summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Black <danielgb@au.ibm.com>2018-02-25 15:25:54 +1100
committerGitHub <noreply@github.com>2018-02-25 15:25:54 +1100
commit0805a9565f09a36104a420d9e229e44b1eea8879 (patch)
tree5c5dbf942479c2b7349f1b4505768ddf5a2f8b8d
parent3188131b15c26509e4df3c4b15972d07a20be8bd (diff)
parent8936b175106a3fdfc560e9d33aa58a6372084c5f (diff)
downloadmariadb-git-0805a9565f09a36104a420d9e229e44b1eea8879.tar.gz
Merge branch '10.3' into 10.2-MDEV-10814-dont-dump-query-cache
-rw-r--r--.gitignore9
-rwxr-xr-x.travis.compiler.sh7
-rw-r--r--.travis.yml44
-rw-r--r--BUILD-CMAKE2
-rw-r--r--BUILD/FINISH.sh10
-rwxr-xr-xBUILD/SETUP.sh3
-rwxr-xr-xBUILD/check-cpu6
-rwxr-xr-xBUILD/compile-pentium-gprof2
-rwxr-xr-xBUILD/compile-pentium64-asan-max24
-rwxr-xr-xBUILD/compile-pentium64-gcov2
-rwxr-xr-xBUILD/compile-pentium64-gprof2
-rw-r--r--CMakeLists.txt8
-rw-r--r--CREDITS3
-rw-r--r--Docs/sp-imp-spec.txt14
-rw-r--r--VERSION3
-rw-r--r--appveyor.yml21
-rw-r--r--client/client_priv.h1
-rw-r--r--client/completion_hash.cc2
-rw-r--r--client/mysql.cc42
-rw-r--r--client/mysql_plugin.c8
-rw-r--r--client/mysql_upgrade.c4
-rw-r--r--client/mysqladmin.cc16
-rw-r--r--client/mysqlbinlog.cc251
-rw-r--r--client/mysqlcheck.c16
-rw-r--r--client/mysqldump.c124
-rw-r--r--client/mysqlimport.c10
-rw-r--r--client/mysqlshow.c14
-rw-r--r--client/mysqlslap.c25
-rw-r--r--client/mysqltest.cc95
-rw-r--r--cmake/bison.cmake11
-rw-r--r--cmake/build_configurations/mysql_release.cmake9
-rw-r--r--cmake/check_compiler_flag.cmake14
-rw-r--r--cmake/cpack_rpm.cmake8
-rw-r--r--cmake/dtrace.cmake3
-rw-r--r--cmake/install_layout.cmake8
-rw-r--r--cmake/maintainer.cmake67
-rw-r--r--cmake/make_dist.cmake.in3
-rw-r--r--cmake/mysql_version.cmake5
-rw-r--r--cmake/os/Windows.cmake82
-rw-r--r--cmake/plugin.cmake2
-rw-r--r--cmake/ssl.cmake7
-rw-r--r--cmake/wsrep.cmake2
-rw-r--r--config.h.cmake2
-rw-r--r--configure.cmake27
-rw-r--r--dbug/dbug.c16
-rwxr-xr-xdebian/additions/debian-start.inc.sh2
-rwxr-xr-xdebian/autobake-deb.sh59
-rw-r--r--debian/control222
-rw-r--r--debian/libmariadb-dev-compat.install4
-rw-r--r--debian/libmariadb-dev-compat.links3
-rw-r--r--debian/libmariadb-dev.install8
-rw-r--r--debian/libmariadb-dev.links1
-rw-r--r--debian/libmariadb-dev.manpages1
-rw-r--r--debian/libmariadb3-compat.install2
-rw-r--r--debian/libmariadb3.install4
-rw-r--r--debian/libmariadbd-dev.install3
-rw-r--r--debian/libmariadbd19.install2
-rw-r--r--debian/mariadb-backup-10.3.install (renamed from debian/mariadb-backup-10.3.files)0
-rw-r--r--debian/mariadb-client-10.3.README.Debian2
-rw-r--r--debian/mariadb-client-10.3.docs2
-rw-r--r--debian/mariadb-client-10.3.install10
-rw-r--r--debian/mariadb-client-10.3.links4
-rw-r--r--debian/mariadb-client-10.3.manpages10
-rw-r--r--debian/mariadb-client-core-10.3.install2
-rw-r--r--debian/mariadb-client-core-10.3.manpages2
-rw-r--r--debian/mariadb-common.install2
-rw-r--r--debian/mariadb-plugin-aws-key-management-10.2.install2
-rw-r--r--debian/mariadb-plugin-aws-key-management.install3
-rw-r--r--debian/mariadb-plugin-connect.install2
-rw-r--r--debian/mariadb-plugin-mroonga.install2
-rw-r--r--debian/mariadb-plugin-rocksdb.install3
-rw-r--r--debian/mariadb-plugin-tokudb.install3
-rw-r--r--debian/mariadb-server-10.3.README.Debian8
-rw-r--r--debian/mariadb-server-10.3.install39
-rw-r--r--debian/mariadb-server-10.3.manpages25
-rw-r--r--debian/mariadb-server-10.3.mysql.init2
-rw-r--r--debian/mariadb-server-core-10.3.install5
-rw-r--r--debian/mariadb-server-core-10.3.manpages3
-rw-r--r--debian/mariadb-test.install8
-rw-r--r--debian/mariadb-test.links2
-rw-r--r--debian/mariadb-test.manpages4
-rw-r--r--debian/mysql-common.install2
-rw-r--r--debian/not-installed127
-rwxr-xr-xdebian/patches/33_scripts__mysql_create_system_tables__no_test.dpatch15
-rwxr-xr-xdebian/patches/38_scripts__mysqld_safe.sh__signals.dpatch10
-rwxr-xr-xdebian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch6
-rwxr-xr-xdebian/patches/50_mysql-test__db_test.dpatch10
-rwxr-xr-xdebian/rules36
-rw-r--r--extra/comp_err.c2
-rw-r--r--extra/innochecksum.cc19
-rw-r--r--extra/mariabackup/backup_copy.cc17
-rw-r--r--extra/mariabackup/backup_mysql.cc28
-rw-r--r--extra/mariabackup/backup_mysql.h2
-rw-r--r--extra/mariabackup/changed_page_bitmap.cc2
-rw-r--r--extra/mariabackup/common.h1
-rw-r--r--extra/mariabackup/crc/crc_glue.c2
-rw-r--r--extra/mariabackup/encryption_plugin.cc1
-rw-r--r--extra/mariabackup/fil_cur.cc19
-rw-r--r--extra/mariabackup/write_filt.cc21
-rw-r--r--extra/mariabackup/write_filt.h2
-rw-r--r--extra/mariabackup/wsrep.cc4
-rw-r--r--extra/mariabackup/xtrabackup.cc246
-rw-r--r--extra/mariabackup/xtrabackup.h4
-rw-r--r--extra/perror.c2
-rw-r--r--extra/resolve_stack_dump.c56
-rw-r--r--extra/yassl/src/cert_wrapper.cpp8
-rw-r--r--extra/yassl/src/socket_wrapper.cpp5
-rw-r--r--extra/yassl/src/yassl_int.cpp4
-rw-r--r--include/atomic/gcc_builtins.h32
-rw-r--r--include/atomic/gcc_sync.h106
-rw-r--r--include/atomic/generic-msvc.h212
-rw-r--r--include/atomic/solaris.h134
-rw-r--r--include/heap.h1
-rw-r--r--include/lf.h1
-rw-r--r--include/m_ctype.h10
-rw-r--r--include/m_string.h11
-rw-r--r--include/ma_dyncol.h9
-rw-r--r--include/my_alloc.h1
-rw-r--r--include/my_atomic.h124
-rw-r--r--include/my_attribute.h4
-rw-r--r--include/my_base.h20
-rw-r--r--include/my_bitmap.h2
-rw-r--r--include/my_compare.h30
-rw-r--r--include/my_cpu.h70
-rw-r--r--include/my_dbug.h7
-rw-r--r--include/my_global.h16
-rw-r--r--include/my_pthread.h6
-rw-r--r--include/my_stacktrace.h2
-rw-r--r--include/my_sys.h27
-rw-r--r--include/my_time.h11
-rw-r--r--include/my_valgrind.h29
-rw-r--r--include/mysql.h1
-rw-r--r--include/mysql.h.pp5
-rw-r--r--include/mysql/plugin.h1
-rw-r--r--include/mysql/plugin_audit.h20
-rw-r--r--include/mysql/plugin_audit.h.pp19
-rw-r--r--include/mysql/plugin_auth.h.pp1
-rw-r--r--include/mysql/plugin_encryption.h.pp1
-rw-r--r--include/mysql/plugin_ftparser.h.pp1
-rw-r--r--include/mysql/plugin_password_validation.h.pp1
-rw-r--r--include/mysql/psi/mysql_socket.h8
-rw-r--r--include/mysql/psi/mysql_statement.h4
-rw-r--r--include/mysql/psi/mysql_thread.h29
-rw-r--r--include/mysql/service_my_print_error.h5
-rw-r--r--include/mysql/service_thd_rnd.h2
-rw-r--r--include/mysql_com.h17
-rw-r--r--include/mysql_version.h.in1
-rw-r--r--include/ssl_compat.h8
-rw-r--r--include/typelib.h2
-rw-r--r--include/violite.h5
-rw-r--r--include/welcome_copyright_notice.h2
m---------libmariadb0
-rw-r--r--libmysqld/CMakeLists.txt14
-rw-r--r--libmysqld/emb_qcache.cc2
-rw-r--r--libmysqld/lib_sql.cc9
-rw-r--r--libmysqld/libmysql.c12
-rw-r--r--libmysqld/libmysqld.c3
-rw-r--r--libservices/my_print_error_service.c2
-rw-r--r--man/mysql-test-run.pl.14
-rw-r--r--man/mysql.12
-rw-r--r--man/mysql_upgrade.13
-rw-r--r--man/mysqladmin.1186
-rw-r--r--mysql-test/CMakeLists.txt1
-rw-r--r--mysql-test/collections/buildbot_suites.bat6
-rw-r--r--mysql-test/extra/rpl_tests/rpl_log.test2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_semi_sync.inc2
-rw-r--r--mysql-test/include/assert_grep.inc5
-rw-r--r--mysql-test/include/check-testcase.test5
-rw-r--r--mysql-test/include/ctype_like_range_mdev14350.inc14
-rw-r--r--mysql-test/include/default_mysqld.cnf2
-rw-r--r--mysql-test/include/filter_file.inc11
-rw-r--r--mysql-test/include/have_debug.inc5
-rw-r--r--mysql-test/include/have_example_plugin.inc14
-rw-r--r--mysql-test/include/have_innodb.combinations2
-rw-r--r--mysql-test/include/have_innodb.inc6
-rw-r--r--mysql-test/include/have_semisync.inc4
-rw-r--r--mysql-test/include/have_semisync.opt4
-rw-r--r--mysql-test/include/have_semisync_plugin.inc15
-rw-r--r--mysql-test/include/innodb_gis_row_format_basic.inc420
-rw-r--r--mysql-test/include/innodb_gis_undo.inc83
-rw-r--r--mysql-test/include/innodb_row_format.combinations8
-rw-r--r--mysql-test/include/innodb_row_format.inc4
-rw-r--r--mysql-test/include/install_semisync.inc39
-rw-r--r--mysql-test/include/kill_and_restart_mysqld.inc15
-rw-r--r--mysql-test/include/mtr_warnings.sql6
-rw-r--r--mysql-test/include/not_embedded.inc6
-rw-r--r--mysql-test/include/not_windows.inc8
-rw-r--r--mysql-test/include/rpl_events.inc159
-rw-r--r--mysql-test/include/show_binlog_events.inc8
-rw-r--r--mysql-test/include/show_events.inc7
-rw-r--r--mysql-test/include/show_gtid_list.inc15
-rw-r--r--mysql-test/include/truncate_file.inc11
-rw-r--r--mysql-test/include/uninstall_semisync.inc29
-rw-r--r--mysql-test/include/wait_innodb_all_purged.inc60
-rw-r--r--mysql-test/lib/My/SafeProcess.pm2
-rw-r--r--mysql-test/lib/My/SafeProcess/Base.pm12
-rw-r--r--mysql-test/lib/My/SafeProcess/CMakeLists.txt22
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_kill_win.cc36
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process_win.cc10
-rw-r--r--mysql-test/lib/My/Tee.pm23
-rwxr-xr-xmysql-test/mysql-test-run.pl102
-rw-r--r--mysql-test/r/1st.result1
-rw-r--r--mysql-test/r/alter_table.result58
-rw-r--r--mysql-test/r/alter_user.result56
-rw-r--r--mysql-test/r/analyze_stmt_privileges2.result6
-rw-r--r--mysql-test/r/binary_to_hex.result4
-rw-r--r--mysql-test/r/cast.result109
-rw-r--r--mysql-test/r/commit_1innodb.result2
-rw-r--r--mysql-test/r/connect.result3
-rw-r--r--mysql-test/r/contributors.result3
-rw-r--r--mysql-test/r/create.result138
-rw-r--r--mysql-test/r/create_drop_binlog.result3
-rw-r--r--mysql-test/r/create_drop_function.result4
-rw-r--r--mysql-test/r/create_drop_view.result2
-rw-r--r--mysql-test/r/create_or_replace.result20
-rw-r--r--mysql-test/r/create_user.result48
-rw-r--r--mysql-test/r/cte_grant.result58
-rw-r--r--mysql-test/r/cte_nonrecursive.result282
-rw-r--r--mysql-test/r/cte_recursive.result414
-rw-r--r--mysql-test/r/ctype_latin1.result25
-rw-r--r--mysql-test/r/ctype_like_range.result45
-rw-r--r--mysql-test/r/ctype_ucs2_uca.result26
-rw-r--r--mysql-test/r/ctype_upgrade.result6
-rw-r--r--mysql-test/r/ctype_utf16_uca.result26
-rw-r--r--mysql-test/r/ctype_utf32_uca.result26
-rw-r--r--mysql-test/r/ctype_utf8.result15
-rw-r--r--mysql-test/r/ctype_utf8_uca.result25
-rw-r--r--mysql-test/r/ctype_utf8mb4.result26
-rw-r--r--mysql-test/r/ctype_utf8mb4_uca.result26
-rw-r--r--mysql-test/r/custom_aggregate_functions.result949
-rw-r--r--mysql-test/r/derived.result97
-rw-r--r--mysql-test/r/derived_cond_pushdown.result5215
-rw-r--r--mysql-test/r/derived_view.result6
-rw-r--r--mysql-test/r/drop.result8
-rw-r--r--mysql-test/r/dyncol.result20
-rw-r--r--mysql-test/r/events_grant.result2
-rw-r--r--mysql-test/r/explain.result8
-rw-r--r--mysql-test/r/explain_json.result62
-rw-r--r--mysql-test/r/features.result1
-rw-r--r--mysql-test/r/frm_bad_row_type-7333.result4
-rw-r--r--mysql-test/r/fulltext.result22
-rw-r--r--mysql-test/r/func_concat.result6
-rw-r--r--mysql-test/r/func_gconcat.result126
-rw-r--r--mysql-test/r/func_group.result2
-rw-r--r--mysql-test/r/func_group_innodb.result4
-rw-r--r--mysql-test/r/func_hybrid_type.result4
-rw-r--r--mysql-test/r/func_in.result13
-rw-r--r--mysql-test/r/func_isnull.result84
-rw-r--r--mysql-test/r/func_json.result11
-rw-r--r--mysql-test/r/func_misc.result15
-rw-r--r--mysql-test/r/func_set.result24
-rw-r--r--mysql-test/r/func_str.result37
-rw-r--r--mysql-test/r/func_time.result51
-rw-r--r--mysql-test/r/get_diagnostics.result2
-rw-r--r--mysql-test/r/gis-json.result15
-rw-r--r--mysql-test/r/gis-rtree.result44
-rw-r--r--mysql-test/r/gis.result6
-rw-r--r--mysql-test/r/grant.result20
-rw-r--r--mysql-test/r/group_by.result25
-rw-r--r--mysql-test/r/having.result15
-rw-r--r--mysql-test/r/information_schema.result37
-rw-r--r--mysql-test/r/information_schema_all_engines.result2
-rw-r--r--mysql-test/r/intersect.result13
-rw-r--r--mysql-test/r/invisible_binlog.result65
-rw-r--r--mysql-test/r/invisible_field.result553
-rw-r--r--mysql-test/r/invisible_field_debug.result371
-rw-r--r--mysql-test/r/join.result1
-rw-r--r--mysql-test/r/join_cache.result58
-rw-r--r--mysql-test/r/join_nested.result2
-rw-r--r--mysql-test/r/join_nested_jcl6.result2
-rw-r--r--mysql-test/r/join_outer.result13
-rw-r--r--mysql-test/r/join_outer_jcl6.result13
-rw-r--r--mysql-test/r/limit_rows_examined.result6
-rw-r--r--mysql-test/r/loadxml.result20
-rw-r--r--mysql-test/r/log_tables_upgrade.result1
-rw-r--r--mysql-test/r/lowercase_table_grant.result8
-rw-r--r--mysql-test/r/mdev_14586.result44
-rw-r--r--mysql-test/r/merge.result11
-rw-r--r--mysql-test/r/myisam.result54
-rw-r--r--mysql-test/r/myisam_explain_non_select_all.result22
-rw-r--r--mysql-test/r/myisam_optimize.result14
-rw-r--r--mysql-test/r/mysql_upgrade-6984.result6
-rw-r--r--mysql-test/r/mysql_upgrade.result31
-rw-r--r--mysql-test/r/mysql_upgrade_no_innodb.result6
-rw-r--r--mysql-test/r/mysql_upgrade_noengine.result3
-rw-r--r--mysql-test/r/mysql_upgrade_ssl.result1
-rw-r--r--mysql-test/r/mysql_upgrade_view.result18
-rw-r--r--mysql-test/r/mysqlbinlog.result3
-rw-r--r--mysql-test/r/mysqlbinlog_row_compressed.result24
-rw-r--r--mysql-test/r/mysqlbinlog_row_minimal.result24
-rw-r--r--mysql-test/r/mysqlcheck.result9
-rw-r--r--mysql-test/r/mysqld--help,win.rdiff30
-rw-r--r--mysql-test/r/mysqld--help.result74
-rw-r--r--mysql-test/r/mysqldump-nl.result43
-rw-r--r--mysql-test/r/mysqldump.result198
-rw-r--r--mysql-test/r/no_password_column-mdev-11170.result1
-rw-r--r--mysql-test/r/not_windows.require2
-rw-r--r--mysql-test/r/openssl_1.result6
-rw-r--r--mysql-test/r/opt_tvc.result58
-rw-r--r--mysql-test/r/order_by.result96
-rw-r--r--mysql-test/r/order_by_innodb.result73
-rw-r--r--mysql-test/r/outfile.resultbin2323 -> 2323 bytes
-rw-r--r--mysql-test/r/partition.result40
-rw-r--r--mysql-test/r/partition_alter.result7
-rw-r--r--mysql-test/r/partition_innodb.result55
-rw-r--r--mysql-test/r/partition_pruning.result88
-rw-r--r--mysql-test/r/partition_range.result4
-rw-r--r--mysql-test/r/partition_windows.result4
-rw-r--r--mysql-test/r/profiling.result2
-rw-r--r--mysql-test/r/ps.result322
-rw-r--r--mysql-test/r/ps_1general.result8
-rw-r--r--mysql-test/r/ps_ddl.result4
-rw-r--r--mysql-test/r/query_cache.result2
-rw-r--r--mysql-test/r/query_cache_debug.result36
-rw-r--r--mysql-test/r/range.result9
-rw-r--r--mysql-test/r/range_mrr_icp.result9
-rw-r--r--mysql-test/r/repair.result25
-rw-r--r--mysql-test/r/select.result16
-rw-r--r--mysql-test/r/select_found.result2
-rw-r--r--mysql-test/r/select_jcl6.result16
-rw-r--r--mysql-test/r/select_pkeycache.result16
-rw-r--r--mysql-test/r/selectivity.result8
-rw-r--r--mysql-test/r/selectivity_innodb.result8
-rw-r--r--mysql-test/r/show_bad_definer-5553.result6
-rw-r--r--mysql-test/r/show_check.result92
-rw-r--r--mysql-test/r/signal.result34
-rw-r--r--mysql-test/r/signal_demo3.result42
-rw-r--r--mysql-test/r/simultaneous_assignment.result222
-rw-r--r--mysql-test/r/sp-big.result29
-rw-r--r--mysql-test/r/sp-code.result303
-rw-r--r--mysql-test/r/sp-cursor.result131
-rw-r--r--mysql-test/r/sp-destruct.result12
-rw-r--r--mysql-test/r/sp-error.result6
-rw-r--r--mysql-test/r/sp-for-loop.result208
-rw-r--r--mysql-test/r/sp-group.result2
-rw-r--r--mysql-test/r/sp-row.result4
-rw-r--r--mysql-test/r/sp.result265
-rw-r--r--mysql-test/r/sql_mode.result8
-rw-r--r--mysql-test/r/status.result17
-rw-r--r--mysql-test/r/subselect.result66
-rw-r--r--mysql-test/r/subselect4.result20
-rw-r--r--mysql-test/r/subselect_mat.result4
-rw-r--r--mysql-test/r/subselect_mat_cost_bugs.result2
-rw-r--r--mysql-test/r/subselect_no_exists_to_in.result66
-rw-r--r--mysql-test/r/subselect_no_mat.result66
-rw-r--r--mysql-test/r/subselect_no_opts.result66
-rw-r--r--mysql-test/r/subselect_no_scache.result66
-rw-r--r--mysql-test/r/subselect_no_semijoin.result66
-rw-r--r--mysql-test/r/system_mysql_db.result10
-rw-r--r--mysql-test/r/system_mysql_db_fix40123.result10
-rw-r--r--mysql-test/r/system_mysql_db_fix50030.result10
-rw-r--r--mysql-test/r/system_mysql_db_fix50117.result10
-rw-r--r--mysql-test/r/thread_id_overflow.result23
-rw-r--r--mysql-test/r/trigger.result19
-rw-r--r--mysql-test/r/type_datetime.result81
-rw-r--r--mysql-test/r/type_set.result6
-rw-r--r--mysql-test/r/type_time.result639
-rw-r--r--mysql-test/r/type_time_6065.result44
-rw-r--r--mysql-test/r/union.result44
-rw-r--r--mysql-test/r/update_innodb.result10
-rw-r--r--mysql-test/r/view.result164
-rw-r--r--mysql-test/r/view_grant.result16
-rw-r--r--mysql-test/r/warnings.result2
-rw-r--r--mysql-test/r/win.result28
-rw-r--r--mysql-test/r/xa.result64
-rw-r--r--mysql-test/r/xml.result12
-rw-r--r--mysql-test/std_data/loaddata/mdev14628a.xml4
-rw-r--r--mysql-test/std_data/loaddata/mdev14628b.xml3
-rw-r--r--mysql-test/std_data/mdev11084.frmbin0 -> 589 bytes
-rw-r--r--mysql-test/std_data/mdev11084.parbin0 -> 36 bytes
-rw-r--r--mysql-test/std_data/mdev11084.part1.MYDbin0 -> 7 bytes
-rw-r--r--mysql-test/std_data/mdev11084.part1.MYIbin0 -> 1024 bytes
-rw-r--r--mysql-test/suite/binlog/r/binlog_base64_flag.result16
-rw-r--r--mysql-test/suite/binlog/r/binlog_flush_binlogs_delete_domain.result78
-rw-r--r--mysql-test/suite/binlog/r/binlog_gtid_delete_domain_debug.result6
-rw-r--r--mysql-test/suite/binlog/r/binlog_killed.result89
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result256
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result20
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result20
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result12
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_annotate.result26
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result8
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result14
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_datetime_ranges_mdev15289.result19
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_ps.result43
-rw-r--r--mysql-test/suite/binlog/r/flashback.result10
-rw-r--r--mysql-test/suite/binlog/r/load_data_stm_view.result1
-rw-r--r--mysql-test/suite/binlog/t/binlog_base64_flag.test9
-rw-r--r--mysql-test/suite/binlog/t/binlog_flush_binlogs_delete_domain.test137
-rw-r--r--mysql-test/suite/binlog/t/binlog_gtid_delete_domain_debug.test11
-rw-r--r--mysql-test/suite/binlog/t/binlog_killed.test95
-rw-r--r--mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test7
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_datetime_ranges_mdev15289.test7
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_ps.test16
-rw-r--r--mysql-test/suite/binlog/t/load_data_stm_view.test4
-rw-r--r--mysql-test/suite/binlog_encryption/binlog_row_annotate.result13
-rw-r--r--mysql-test/suite/binlog_encryption/rpl_semi_sync.result6
-rw-r--r--mysql-test/suite/compat/oracle/r/empty_string_literal.result2
-rw-r--r--mysql-test/suite/compat/oracle/r/ps.result15
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result33
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-param.result16
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-row.result4
-rw-r--r--mysql-test/suite/compat/oracle/r/sp.result95
-rw-r--r--mysql-test/suite/compat/oracle/t/ps.test24
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test36
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-row.test4
-rw-r--r--mysql-test/suite/compat/oracle/t/sp.test114
-rw-r--r--mysql-test/suite/csv/read_only.result2
-rw-r--r--mysql-test/suite/encryption/disabled.def1
-rw-r--r--mysql-test/suite/encryption/r/encrypt_and_grep.result3
-rw-r--r--mysql-test/suite/encryption/r/innodb-bad-key-change.result40
-rw-r--r--mysql-test/suite/encryption/r/innodb-bad-key-change2.result1
-rw-r--r--mysql-test/suite/encryption/r/innodb-bad-key-change4.result1
-rw-r--r--mysql-test/suite/encryption/r/innodb-compressed-blob.result1
-rw-r--r--mysql-test/suite/encryption/r/innodb-encryption-disable.result1
-rw-r--r--mysql-test/suite/encryption/r/innodb-force-corrupt.result1
-rw-r--r--mysql-test/suite/encryption/r/innodb-missing-key.result1
-rw-r--r--mysql-test/suite/encryption/r/innodb-redo-badkey.result1
-rw-r--r--mysql-test/suite/encryption/r/innodb-redo-nokeys.result4
-rw-r--r--mysql-test/suite/encryption/r/innodb-spatial-index.result1
-rw-r--r--mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result40
-rw-r--r--mysql-test/suite/encryption/r/innodb_encryption-page-compression.result28
-rw-r--r--mysql-test/suite/encryption/r/innodb_encryption.result5
-rw-r--r--mysql-test/suite/encryption/r/innodb_encryption_filekeys.result23
-rw-r--r--mysql-test/suite/encryption/r/innodb_lotoftables.result40
-rw-r--r--mysql-test/suite/encryption/r/tempfiles.result69
-rw-r--r--mysql-test/suite/encryption/t/debug_key_management.test5
-rw-r--r--mysql-test/suite/encryption/t/encrypt_and_grep.test3
-rw-r--r--mysql-test/suite/encryption/t/innodb-bad-key-change.test42
-rw-r--r--mysql-test/suite/encryption/t/innodb-bad-key-change2.test1
-rw-r--r--mysql-test/suite/encryption/t/innodb-bad-key-change4.test1
-rw-r--r--mysql-test/suite/encryption/t/innodb-compressed-blob.test1
-rw-r--r--mysql-test/suite/encryption/t/innodb-encryption-disable.test1
-rw-r--r--mysql-test/suite/encryption/t/innodb-force-corrupt.test1
-rw-r--r--mysql-test/suite/encryption/t/innodb-missing-key.test1
-rw-r--r--mysql-test/suite/encryption/t/innodb-redo-badkey.test1
-rw-r--r--mysql-test/suite/encryption/t/innodb-redo-nokeys.test4
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption-page-compression.test41
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption.test6
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption_filekeys.test31
-rw-r--r--mysql-test/suite/encryption/t/tempfiles.combinations5
-rw-r--r--mysql-test/suite/encryption/t/tempfiles.opt1
-rw-r--r--mysql-test/suite/encryption/t/tempfiles.test24
-rw-r--r--mysql-test/suite/federated/assisted_discovery.result8
-rw-r--r--mysql-test/suite/federated/assisted_discovery.test9
-rw-r--r--mysql-test/suite/federated/federated_bug_585688.result8
-rw-r--r--mysql-test/suite/federated/federated_partition.result5
-rw-r--r--mysql-test/suite/federated/federated_partition.test1
-rw-r--r--mysql-test/suite/funcs_1/datadict/tables2.inc2
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_trig_03.result22
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_trig_03e.result6
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_views.result16
-rw-r--r--mysql-test/suite/funcs_1/r/is_column_privileges.result1
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns.result1
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_is.result4
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_is_embedded.result4
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql.result56
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result51
-rw-r--r--mysql-test/suite/funcs_1/r/is_key_column_usage.result2
-rw-r--r--mysql-test/suite/funcs_1/r/is_key_column_usage_embedded.result2
-rw-r--r--mysql-test/suite/funcs_1/r/is_schema_privileges.result2
-rw-r--r--mysql-test/suite/funcs_1/r/is_schema_privileges_is_mysql_test.result1
-rw-r--r--mysql-test/suite/funcs_1/r/is_statistics.result1
-rw-r--r--mysql-test/suite/funcs_1/r/is_statistics_mysql.result5
-rw-r--r--mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result10
-rw-r--r--mysql-test/suite/funcs_1/r/is_table_constraints.result2
-rw-r--r--mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result2
-rw-r--r--mysql-test/suite/funcs_1/r/is_table_constraints_mysql_embedded.result4
-rw-r--r--mysql-test/suite/funcs_1/r/is_table_privileges.result4
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables.result44
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_embedded.result52
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_innodb.result10
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_is.result160
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_is_embedded.result160
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_memory.result10
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_myisam.result10
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_myisam_embedded.result12
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_mysql.result85
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result170
-rw-r--r--mysql-test/suite/funcs_1/r/is_triggers.result2
-rw-r--r--mysql-test/suite/funcs_1/r/is_user_privileges.result33
-rw-r--r--mysql-test/suite/funcs_1/r/memory_trig_03.result22
-rw-r--r--mysql-test/suite/funcs_1/r/memory_trig_03e.result6
-rw-r--r--mysql-test/suite/funcs_1/r/memory_views.result16
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_trig_03.result22
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_trig_03e.result6
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_views-big.result16
-rw-r--r--mysql-test/suite/funcs_1/r/storedproc.result74
-rw-r--r--mysql-test/suite/funcs_2/include/check_charset.inc2
-rw-r--r--mysql-test/suite/funcs_2/r/innodb_charset.result496
-rw-r--r--mysql-test/suite/funcs_2/r/memory_charset.result496
-rw-r--r--mysql-test/suite/funcs_2/r/myisam_charset.result496
-rw-r--r--mysql-test/suite/galera/disabled.def13
-rw-r--r--mysql-test/suite/galera/r/MW-388.result50
-rw-r--r--mysql-test/suite/galera/r/galera_bf_abort.result2
-rw-r--r--mysql-test/suite/galera/r/galera_bf_abort_get_lock.result2
-rw-r--r--mysql-test/suite/galera/r/galera_bf_abort_sleep.result2
-rw-r--r--mysql-test/suite/galera/r/galera_bf_lock_wait.result23
-rw-r--r--mysql-test/suite/galera/r/galera_defaults.result2
-rw-r--r--mysql-test/suite/galera/r/galera_enum.result2
-rw-r--r--mysql-test/suite/galera/r/galera_fk_conflict.result2
-rw-r--r--mysql-test/suite/galera/r/galera_gtid_slave.result36
-rw-r--r--mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result159
-rw-r--r--mysql-test/suite/galera/r/galera_insert_multi.result2
-rw-r--r--mysql-test/suite/galera/r/galera_ist_progress.result9
-rw-r--r--mysql-test/suite/galera/r/galera_many_columns.result2
-rw-r--r--mysql-test/suite/galera/r/galera_many_indexes.result2
-rw-r--r--mysql-test/suite/galera/r/galera_many_rows.result2
-rw-r--r--mysql-test/suite/galera/r/galera_many_tables_nopk.result2
-rw-r--r--mysql-test/suite/galera/r/galera_many_tables_pk.result2
-rw-r--r--mysql-test/suite/galera/r/galera_mdl_race.result2
-rw-r--r--mysql-test/suite/galera/r/galera_nopk_bit.result2
-rw-r--r--mysql-test/suite/galera/r/galera_nopk_blob.result2
-rw-r--r--mysql-test/suite/galera/r/galera_nopk_large_varchar.result2
-rw-r--r--mysql-test/suite/galera/r/galera_nopk_unicode.result2
-rw-r--r--mysql-test/suite/galera/r/galera_parallel_autoinc_largetrx.result2
-rw-r--r--mysql-test/suite/galera/r/galera_pk_bigint_signed.result2
-rw-r--r--mysql-test/suite/galera/r/galera_pk_bigint_unsigned.result2
-rw-r--r--mysql-test/suite/galera/r/galera_serializable.result6
-rw-r--r--mysql-test/suite/galera/r/galera_toi_drop_database.result4
-rw-r--r--mysql-test/suite/galera/r/galera_toi_lock_exclusive.result2
-rw-r--r--mysql-test/suite/galera/r/galera_toi_truncate.result2
-rw-r--r--mysql-test/suite/galera/r/galera_unicode_pk.result4
-rw-r--r--mysql-test/suite/galera/r/galera_var_auto_inc_control_off.result2
-rw-r--r--mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result6
-rw-r--r--mysql-test/suite/galera/r/galera_var_node_address.result1
-rw-r--r--mysql-test/suite/galera/r/galera_wsrep_log_conficts.result2
-rw-r--r--mysql-test/suite/galera/r/query_cache.result130
-rw-r--r--mysql-test/suite/galera/r/sql_log_bin.result1
-rw-r--r--mysql-test/suite/galera/suite.pm6
-rw-r--r--mysql-test/suite/galera/t/MW-388.test76
-rw-r--r--mysql-test/suite/galera/t/galera_bf_lock_wait.test52
-rw-r--r--mysql-test/suite/galera/t/galera_binlog_event_max_size_max-master.opt2
-rw-r--r--mysql-test/suite/galera/t/galera_defaults.test1
-rw-r--r--mysql-test/suite/galera/t/galera_ftwrl.test7
-rw-r--r--mysql-test/suite/galera/t/galera_gtid_slave.cnf18
-rw-r--r--mysql-test/suite/galera/t/galera_gtid_slave.test78
-rw-r--r--mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.cnf18
-rw-r--r--mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test207
-rw-r--r--mysql-test/suite/galera/t/galera_suspend_slave.test4
-rw-r--r--mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test2
-rw-r--r--mysql-test/suite/galera/t/galera_var_node_address.test1
-rw-r--r--mysql-test/suite/galera/t/query_cache.test89
-rw-r--r--mysql-test/suite/galera/t/sql_log_bin.test12
-rw-r--r--mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf122
-rw-r--r--mysql-test/suite/galera_3nodes/include/have_ipv6.inc15
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_gtid_2_cluster.result231
-rw-r--r--mysql-test/suite/galera_3nodes/suite.pm6
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.cnf28
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.test292
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test2
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test2
-rw-r--r--mysql-test/suite/gcol/disabled.def1
-rw-r--r--mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result37
-rw-r--r--mysql-test/suite/gcol/r/innodb_virtual_index.result4
-rw-r--r--mysql-test/suite/gcol/r/innodb_virtual_stats.result127
-rw-r--r--mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test36
-rw-r--r--mysql-test/suite/gcol/t/innodb_virtual_index.test6
-rw-r--r--mysql-test/suite/gcol/t/innodb_virtual_stats.test52
-rw-r--r--mysql-test/suite/heap/heap.result6
-rw-r--r--mysql-test/suite/innodb/include/innodb_bulk_create_index.inc185
-rw-r--r--mysql-test/suite/innodb/include/innodb_bulk_create_index_debug.inc221
-rw-r--r--mysql-test/suite/innodb/r/alter_copy.result213
-rw-r--r--mysql-test/suite/innodb/r/alter_crash.result23
-rw-r--r--mysql-test/suite/innodb/r/ddl_purge.result25
-rw-r--r--mysql-test/suite/innodb/r/deadlock_detect.result6
-rw-r--r--mysql-test/suite/innodb/r/drop_table_background.result15
-rw-r--r--mysql-test/suite/innodb/r/foreign_key.result43
-rw-r--r--mysql-test/suite/innodb/r/innodb-autoinc.result18
-rw-r--r--mysql-test/suite/innodb/r/innodb-fk-warnings.result18
-rw-r--r--mysql-test/suite/innodb/r/innodb-fk.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb-fkcheck.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb-index-debug.result31
-rw-r--r--mysql-test/suite/innodb/r/innodb-index-online-fk.result6
-rw-r--r--mysql-test/suite/innodb/r/innodb-index-online.result25
-rw-r--r--mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result10
-rw-r--r--mysql-test/suite/innodb/r/innodb-on-duplicate-update.result60
-rw-r--r--mysql-test/suite/innodb/r/innodb-replace-debug.result14
-rw-r--r--mysql-test/suite/innodb/r/innodb-table-online.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb-wl5522-debug.result18
-rw-r--r--mysql-test/suite/innodb/r/innodb.result157
-rw-r--r--mysql-test/suite/innodb/r/innodb_buffer_pool_resize.result34
-rw-r--r--mysql-test/suite/innodb/r/innodb_buffer_pool_resize_with_chunks.result26
-rw-r--r--mysql-test/suite/innodb/r/innodb_bulk_create_index.result1037
-rw-r--r--mysql-test/suite/innodb/r/innodb_bulk_create_index_debug.result485
-rw-r--r--mysql-test/suite/innodb/r/innodb_bulk_create_index_flush.result54
-rw-r--r--mysql-test/suite/innodb/r/innodb_bulk_create_index_replication.result222
-rw-r--r--mysql-test/suite/innodb/r/innodb_bulk_create_index_small.result139
-rw-r--r--mysql-test/suite/innodb/r/innodb_corrupt_bit.result9
-rw-r--r--mysql-test/suite/innodb/r/innodb_max_recordsize_32k.result34
-rw-r--r--mysql-test/suite/innodb/r/innodb_max_recordsize_64k.result34
-rw-r--r--mysql-test/suite/innodb/r/innodb_mysql.result6
-rw-r--r--mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result2
-rw-r--r--mysql-test/suite/innodb/r/instant_alter,4k.rdiff52
-rw-r--r--mysql-test/suite/innodb/r/instant_alter,8k.rdiff54
-rw-r--r--mysql-test/suite/innodb/r/instant_alter.resultbin119287 -> 120413 bytes
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_crash.result1
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_debug.result2
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_rollback.result1
-rw-r--r--mysql-test/suite/innodb/r/lock_deleted.result57
-rw-r--r--mysql-test/suite/innodb/r/log_corruption.result38
-rw-r--r--mysql-test/suite/innodb/r/mvcc.result32
-rw-r--r--mysql-test/suite/innodb/r/purge_secondary.result148
-rw-r--r--mysql-test/suite/innodb/r/read_only_recover_committed.result47
-rw-r--r--mysql-test/suite/innodb/r/read_only_recovery.result1
-rw-r--r--mysql-test/suite/innodb/r/recovery_shutdown.result66
-rw-r--r--mysql-test/suite/innodb/r/rename_table_debug.result12
-rw-r--r--mysql-test/suite/innodb/r/restart.result29
-rw-r--r--mysql-test/suite/innodb/r/row_format_redundant.result2
-rw-r--r--mysql-test/suite/innodb/r/table_flags.result13
-rw-r--r--mysql-test/suite/innodb/r/truncate_inject.result114
-rw-r--r--mysql-test/suite/innodb/r/truncate_restart.result12
-rw-r--r--mysql-test/suite/innodb/r/update-cascade.result290
-rw-r--r--mysql-test/suite/innodb/r/update_time.result53
-rw-r--r--mysql-test/suite/innodb/r/update_time_wl6658.result228
-rw-r--r--mysql-test/suite/innodb/t/alter_copy.test91
-rw-r--r--mysql-test/suite/innodb/t/alter_crash.test96
-rw-r--r--mysql-test/suite/innodb/t/ddl_purge.test36
-rw-r--r--mysql-test/suite/innodb/t/deadlock_detect.test14
-rw-r--r--mysql-test/suite/innodb/t/drop_table_background.test14
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test40
-rw-r--r--mysql-test/suite/innodb/t/ibuf_not_empty.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter-tempfile.test14
-rw-r--r--mysql-test/suite/innodb/t/innodb-autoinc.test17
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-debug.test39
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-online.test27
-rw-r--r--mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test24
-rw-r--r--mysql-test/suite/innodb/t/innodb-master.opt2
-rw-r--r--mysql-test/suite/innodb/t/innodb-on-duplicate-update.test63
-rw-r--r--mysql-test/suite/innodb/t/innodb-replace-debug.test16
-rw-r--r--mysql-test/suite/innodb/t/innodb.test160
-rw-r--r--mysql-test/suite/innodb/t/innodb_buffer_pool_resize.opt2
-rw-r--r--mysql-test/suite/innodb/t/innodb_buffer_pool_resize.test74
-rw-r--r--mysql-test/suite/innodb/t/innodb_buffer_pool_resize_with_chunks.opt3
-rw-r--r--mysql-test/suite/innodb/t/innodb_buffer_pool_resize_with_chunks.test63
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug14147491.test10
-rw-r--r--mysql-test/suite/innodb/t/innodb_bulk_create_index.test46
-rw-r--r--mysql-test/suite/innodb/t/innodb_bulk_create_index_debug.test23
-rw-r--r--mysql-test/suite/innodb/t/innodb_bulk_create_index_flush.test75
-rw-r--r--mysql-test/suite/innodb/t/innodb_bulk_create_index_replication.test182
-rw-r--r--mysql-test/suite/innodb/t/innodb_bulk_create_index_small.test148
-rw-r--r--mysql-test/suite/innodb/t/innodb_corrupt_bit.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb_default_row_format.combinations4
-rw-r--r--mysql-test/suite/innodb/t/innodb_default_row_format.inc2
-rw-r--r--mysql-test/suite/innodb/t/innodb_force_recovery.test1
-rw-r--r--mysql-test/suite/innodb/t/innodb_max_recordsize_32k.opt3
-rw-r--r--mysql-test/suite/innodb/t/innodb_max_recordsize_32k.test37
-rw-r--r--mysql-test/suite/innodb/t/innodb_max_recordsize_64k.opt3
-rw-r--r--mysql-test/suite/innodb/t/innodb_max_recordsize_64k.test37
-rw-r--r--mysql-test/suite/innodb/t/instant_alter.test58
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_crash.test2
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_rollback.test3
-rw-r--r--mysql-test/suite/innodb/t/lock_deleted.test72
-rw-r--r--mysql-test/suite/innodb/t/log_corruption.test99
-rw-r--r--mysql-test/suite/innodb/t/log_file_name.test1
-rw-r--r--mysql-test/suite/innodb/t/log_file_size.test3
-rw-r--r--mysql-test/suite/innodb/t/mvcc.test52
-rw-r--r--mysql-test/suite/innodb/t/purge_secondary.opt1
-rw-r--r--mysql-test/suite/innodb/t/purge_secondary.test131
-rw-r--r--mysql-test/suite/innodb/t/read_only_recover_committed.test67
-rw-r--r--mysql-test/suite/innodb/t/read_only_recovery.test3
-rw-r--r--mysql-test/suite/innodb/t/recovery_shutdown.test64
-rw-r--r--mysql-test/suite/innodb/t/rename_table_debug.test21
-rw-r--r--mysql-test/suite/innodb/t/restart.test80
-rw-r--r--mysql-test/suite/innodb/t/row_format_redundant.test6
-rw-r--r--mysql-test/suite/innodb/t/table_definition_cache_debug.opt2
-rw-r--r--mysql-test/suite/innodb/t/table_flags.test5
-rw-r--r--mysql-test/suite/innodb/t/truncate_inject.test97
-rw-r--r--mysql-test/suite/innodb/t/truncate_restart.test16
-rw-r--r--mysql-test/suite/innodb/t/update-cascade.test221
-rw-r--r--mysql-test/suite/innodb/t/update_time-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/update_time.test79
-rw-r--r--mysql-test/suite/innodb/t/update_time_wl6658.test232
-rw-r--r--mysql-test/suite/innodb_fts/r/fulltext.result2
-rw-r--r--mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result14
-rw-r--r--mysql-test/suite/innodb_fts/r/misc_debug.result2
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test13
-rw-r--r--mysql-test/suite/innodb_gis/disabled.def8
-rw-r--r--mysql-test/suite/innodb_gis/r/bug17057168.result6
-rw-r--r--mysql-test/suite/innodb_gis/r/geometry.result35
-rw-r--r--mysql-test/suite/innodb_gis/r/innodb_gis_rtree.result1630
-rw-r--r--mysql-test/suite/innodb_gis/r/kill_server.result1
-rw-r--r--mysql-test/suite/innodb_gis/r/point_basic.result6
-rw-r--r--mysql-test/suite/innodb_gis/r/row_format.result1588
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_compress.result10
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_compress2.result13
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_concurrent_srch.result58
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_crash.result41
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_debug.result9
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_estimate.result96
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_old.result1821
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_purge.result24
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_recovery.result6
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_search.result8
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_split.result15
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_undo.result212
-rw-r--r--mysql-test/suite/innodb_gis/r/types.result4
-rw-r--r--mysql-test/suite/innodb_gis/t/geometry.test37
-rw-r--r--mysql-test/suite/innodb_gis/t/gis_split_inf.test5
-rw-r--r--mysql-test/suite/innodb_gis/t/innodb_gis_rtree.test3
-rw-r--r--mysql-test/suite/innodb_gis/t/kill_server.test3
-rw-r--r--mysql-test/suite/innodb_gis/t/row_format.test34
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_compress.test16
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_compress2.test29
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_concurrent_srch.test26
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_debug.test5
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_old.test1015
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_purge.test58
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_recovery.test5
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_search.test5
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_split.test20
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_undo.test102
-rw-r--r--mysql-test/suite/innodb_gis/t/types.test10
-rw-r--r--mysql-test/suite/innodb_zip/include/innodb_wl6501_error.inc225
-rw-r--r--mysql-test/suite/innodb_zip/r/16k.result4
-rw-r--r--mysql-test/suite/innodb_zip/r/prefix_index_liftedlimit.result1417
-rw-r--r--mysql-test/suite/innodb_zip/t/prefix_index_liftedlimit.test1329
-rw-r--r--mysql-test/suite/maria/dynamic.result4
-rw-r--r--mysql-test/suite/maria/dynamic.test7
-rw-r--r--mysql-test/suite/maria/lock.result69
-rw-r--r--mysql-test/suite/maria/lock.test55
-rw-r--r--mysql-test/suite/maria/maria.result63
-rw-r--r--mysql-test/suite/maria/maria.test43
-rw-r--r--mysql-test/suite/maria/max_length.result118
-rw-r--r--mysql-test/suite/maria/max_length.test77
-rw-r--r--mysql-test/suite/maria/repair.result24
-rw-r--r--mysql-test/suite/maria/repair.test24
-rw-r--r--mysql-test/suite/mariabackup/apply-log-only-incr.result11
-rw-r--r--mysql-test/suite/mariabackup/apply-log-only-incr.test9
-rw-r--r--mysql-test/suite/mariabackup/apply-log-only.result2
-rw-r--r--mysql-test/suite/mariabackup/apply-log-only.test2
-rw-r--r--mysql-test/suite/mariabackup/binlog.result8
-rw-r--r--mysql-test/suite/mariabackup/binlog.test25
-rw-r--r--mysql-test/suite/mariabackup/extra_lsndir.result2
-rw-r--r--mysql-test/suite/mariabackup/extra_lsndir.test9
-rw-r--r--mysql-test/suite/mariabackup/huge_lsn.opt6
-rw-r--r--mysql-test/suite/mariabackup/huge_lsn.result3
-rw-r--r--mysql-test/suite/mariabackup/huge_lsn.test6
-rw-r--r--mysql-test/suite/mariabackup/log_checksum_mismatch.result14
-rw-r--r--mysql-test/suite/mariabackup/log_checksum_mismatch.test32
-rw-r--r--mysql-test/suite/mariabackup/mdev-14447.opt1
-rw-r--r--mysql-test/suite/mariabackup/mdev-14447.result19
-rw-r--r--mysql-test/suite/mariabackup/mdev-14447.test46
-rw-r--r--mysql-test/suite/mariabackup/missing_ibd.result6
-rw-r--r--mysql-test/suite/mariabackup/missing_ibd.test36
-rw-r--r--mysql-test/suite/mariabackup/system_versioning.result49
-rw-r--r--mysql-test/suite/mariabackup/system_versioning.test50
-rw-r--r--mysql-test/suite/mariabackup/xb_aws_key_management.result2
-rw-r--r--mysql-test/suite/mariabackup/xb_aws_key_management.test1
-rw-r--r--mysql-test/suite/parts/inc/part_alter_values.inc37
-rw-r--r--mysql-test/suite/parts/r/cache.result15
-rw-r--r--mysql-test/suite/parts/r/optimizer.result4
-rw-r--r--mysql-test/suite/parts/r/partition_alter_innodb.result44
-rw-r--r--mysql-test/suite/parts/r/partition_alter_maria.result53
-rw-r--r--mysql-test/suite/parts/r/partition_alter_myisam.result57
-rw-r--r--mysql-test/suite/parts/r/partition_basic_symlink_innodb.result193
-rw-r--r--mysql-test/suite/parts/r/partition_open.result8
-rw-r--r--mysql-test/suite/parts/r/print_error.result18
-rw-r--r--mysql-test/suite/parts/t/cache.test22
-rw-r--r--mysql-test/suite/parts/t/partition_alter_innodb.test4
-rw-r--r--mysql-test/suite/parts/t/partition_alter_maria.test10
-rw-r--r--mysql-test/suite/parts/t/partition_alter_myisam.test25
-rw-r--r--mysql-test/suite/parts/t/partition_basic_symlink_innodb.test143
-rw-r--r--mysql-test/suite/parts/t/partition_open.test24
-rw-r--r--mysql-test/suite/parts/t/print_error.test30
-rw-r--r--mysql-test/suite/perfschema/r/dml_setup_instruments.result6
-rw-r--r--mysql-test/suite/perfschema/r/misc.result16
-rw-r--r--mysql-test/suite/perfschema/r/nesting.result14
-rw-r--r--mysql-test/suite/perfschema/r/relaylog.result10
-rw-r--r--mysql-test/suite/perfschema/r/threads_mysql.result4
-rw-r--r--mysql-test/suite/perfschema/t/misc.test15
-rw-r--r--mysql-test/suite/perfschema/t/nesting.test1
-rw-r--r--mysql-test/suite/plugins/r/binlog-simple_plugin_check.result19
-rw-r--r--mysql-test/suite/plugins/t/binlog-simple_plugin_check.test31
-rw-r--r--mysql-test/suite/plugins/t/server_audit.test2
-rw-r--r--mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result4
-rw-r--r--mysql-test/suite/roles/flush_roles-12366.result543
-rw-r--r--mysql-test/suite/roles/flush_roles-12366.test379
-rw-r--r--mysql-test/suite/roles/set_role-13655.result52
-rw-r--r--mysql-test/suite/roles/set_role-13655.test49
-rw-r--r--mysql-test/suite/roles/set_role-recursive.result8
-rw-r--r--mysql-test/suite/roles/set_role-simple.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_create_drop_view.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_ctype_latin1.result34
-rw-r--r--mysql-test/suite/rpl/r/rpl_events.result17
-rw-r--r--mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result82
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result42
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_log.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_log_innodb.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_semi_sync.result6
-rw-r--r--mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result6
-rw-r--r--mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result6
-rw-r--r--mysql-test/suite/rpl/r/rpl_semi_sync_event.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_semi_sync_event_after_sync.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_semi_sync_skip_repl.result30
-rw-r--r--mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result73
-rw-r--r--mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result353
-rw-r--r--mysql-test/suite/rpl/r/rpl_sp.result36
-rw-r--r--mysql-test/suite/rpl/r/rpl_stm_log.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_update.result16
-rw-r--r--mysql-test/suite/rpl/r/rpl_view_debug.result2
-rw-r--r--mysql-test/suite/rpl/t/rpl_ctype_latin1.test44
-rw-r--r--mysql-test/suite/rpl/t/rpl_events.test154
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test98
-rw-r--r--mysql-test/suite/rpl/t/rpl_manual_change_index_file.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_mdev359.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test66
-rw-r--r--mysql-test/suite/rpl/t/rpl_semi_sync_event.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_semi_sync_skip_repl.test61
-rw-r--r--mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test132
-rw-r--r--mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_semisync_ali_issues-master.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_semisync_ali_issues-slave.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_semisync_ali_issues.test410
-rw-r--r--mysql-test/suite/rpl/t/rpl_update.test15
-rw-r--r--mysql-test/suite/rpl/t/semisync_future-7591.test1
-rw-r--r--mysql-test/suite/rpl/t/semisync_memleak_4066.test1
-rw-r--r--mysql-test/suite/sql_sequence/alter.result2
-rw-r--r--mysql-test/suite/sql_sequence/create.result22
-rw-r--r--mysql-test/suite/sql_sequence/create.test9
-rw-r--r--mysql-test/suite/sql_sequence/default.result187
-rw-r--r--mysql-test/suite/sql_sequence/default.test125
-rw-r--r--mysql-test/suite/sql_sequence/grant.result60
-rw-r--r--mysql-test/suite/sql_sequence/grant.test67
-rw-r--r--mysql-test/suite/sql_sequence/mysqldump.result8
-rw-r--r--mysql-test/suite/sql_sequence/mysqldump.test11
-rw-r--r--mysql-test/suite/sql_sequence/other.result22
-rw-r--r--mysql-test/suite/sql_sequence/other.test26
-rw-r--r--mysql-test/suite/sql_sequence/rename.result6
-rw-r--r--mysql-test/suite/sql_sequence/rename.test6
-rw-r--r--mysql-test/suite/sql_sequence/replication.result29
-rw-r--r--mysql-test/suite/sql_sequence/replication.test22
-rw-r--r--mysql-test/suite/storage_engine/autoincrement.result20
-rw-r--r--mysql-test/suite/storage_engine/autoincrement.test10
-rw-r--r--mysql-test/suite/storage_engine/misc.result2
-rw-r--r--mysql-test/suite/storage_engine/show_table_status.result6
-rw-r--r--mysql-test/suite/storage_engine/show_table_status.test2
-rw-r--r--mysql-test/suite/storage_engine/truncate_table.result16
-rw-r--r--mysql-test/suite/storage_engine/truncate_table.test8
-rw-r--r--mysql-test/suite/sys_vars/inc/sysvars_server.inc2
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_abort_loads.result95
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_spin_wait_delay_basic.result16
-rw-r--r--mysql-test/suite/sys_vars/r/optimizer_switch_basic.result36
-rw-r--r--mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result6
-rw-r--r--mysql-test/suite/sys_vars/r/slave_transaction_retry_errors.result21
-rw-r--r--mysql-test/suite/sys_vars/r/slave_transaction_retry_interval_basic.result126
-rw-r--r--mysql-test/suite/sys_vars/r/sql_mode_basic.result16
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_debug.result15
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result13
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result70
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff102
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result226
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_abort_loads.opt5
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_abort_loads.test149
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test30
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_point_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/slave_transaction_retry_errors-master.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/slave_transaction_retry_errors.test19
-rw-r--r--mysql-test/suite/sys_vars/t/slave_transaction_retry_interval_basic.test190
-rw-r--r--mysql-test/suite/sys_vars/t/sql_mode_basic.test4
-rw-r--r--mysql-test/suite/sys_vars/t/sysvars_debug.test1
-rw-r--r--mysql-test/suite/sys_vars/t/sysvars_innodb.test3
-rw-r--r--mysql-test/suite/sys_vars/t/wsrep_on_basic.opt1
-rw-r--r--mysql-test/suite/unit/suite.pm8
-rw-r--r--mysql-test/suite/vcol/r/range.result4
-rw-r--r--mysql-test/suite/versioning/common.inc80
-rw-r--r--mysql-test/suite/versioning/common.opt1
-rw-r--r--mysql-test/suite/versioning/common_finish.inc7
-rw-r--r--mysql-test/suite/versioning/disabled.def (renamed from mysql-test/suite/handler/disabled.def)4
-rw-r--r--mysql-test/suite/versioning/engines.combinations8
-rw-r--r--mysql-test/suite/versioning/engines.inc1
-rw-r--r--mysql-test/suite/versioning/key_type.combinations2
-rw-r--r--mysql-test/suite/versioning/key_type.inc23
-rw-r--r--mysql-test/suite/versioning/r/alter.result521
-rw-r--r--mysql-test/suite/versioning/r/auto_increment.result65
-rw-r--r--mysql-test/suite/versioning/r/commit_id.result100
-rw-r--r--mysql-test/suite/versioning/r/create.result470
-rw-r--r--mysql-test/suite/versioning/r/cte.result118
-rw-r--r--mysql-test/suite/versioning/r/ddl.result211
-rw-r--r--mysql-test/suite/versioning/r/debug.result54
-rw-r--r--mysql-test/suite/versioning/r/delete.result119
-rw-r--r--mysql-test/suite/versioning/r/derived.result295
-rw-r--r--mysql-test/suite/versioning/r/foreign,trx_id.rdiff166
-rw-r--r--mysql-test/suite/versioning/r/foreign.result183
-rw-r--r--mysql-test/suite/versioning/r/insert.result112
-rw-r--r--mysql-test/suite/versioning/r/insert2.result104
-rw-r--r--mysql-test/suite/versioning/r/load_data.result8
-rw-r--r--mysql-test/suite/versioning/r/online.result34
-rw-r--r--mysql-test/suite/versioning/r/optimized.result64
-rw-r--r--mysql-test/suite/versioning/r/partition.result572
-rw-r--r--mysql-test/suite/versioning/r/replace.result10
-rw-r--r--mysql-test/suite/versioning/r/rpl.result167
-rw-r--r--mysql-test/suite/versioning/r/select.result514
-rw-r--r--mysql-test/suite/versioning/r/select2,trx_id.rdiff38
-rw-r--r--mysql-test/suite/versioning/r/select2.result336
-rw-r--r--mysql-test/suite/versioning/r/simple.result73
-rw-r--r--mysql-test/suite/versioning/r/sysvars.result129
-rw-r--r--mysql-test/suite/versioning/r/truncate.result88
-rw-r--r--mysql-test/suite/versioning/r/truncate_privilege.result33
-rw-r--r--mysql-test/suite/versioning/r/trx_id.result131
-rw-r--r--mysql-test/suite/versioning/r/update,trx_id.rdiff13
-rw-r--r--mysql-test/suite/versioning/r/update.result243
-rw-r--r--mysql-test/suite/versioning/r/update2.result21
-rw-r--r--mysql-test/suite/versioning/r/view.result137
-rw-r--r--mysql-test/suite/versioning/r/vtmd.result365
-rw-r--r--mysql-test/suite/versioning/r/vtmd_show.result229
-rw-r--r--mysql-test/suite/versioning/t/alter.test443
-rw-r--r--mysql-test/suite/versioning/t/auto_increment.test50
-rw-r--r--mysql-test/suite/versioning/t/commit_id.test94
-rw-r--r--mysql-test/suite/versioning/t/create.test367
-rw-r--r--mysql-test/suite/versioning/t/cte.test101
-rw-r--r--mysql-test/suite/versioning/t/ddl.test105
-rw-r--r--mysql-test/suite/versioning/t/debug.test35
-rw-r--r--mysql-test/suite/versioning/t/delete.test86
-rw-r--r--mysql-test/suite/versioning/t/derived.test236
-rw-r--r--mysql-test/suite/versioning/t/engines.combinations8
-rw-r--r--mysql-test/suite/versioning/t/foreign.combinations5
-rw-r--r--mysql-test/suite/versioning/t/foreign.test285
-rw-r--r--mysql-test/suite/versioning/t/insert.test82
-rw-r--r--mysql-test/suite/versioning/t/insert2.test104
-rw-r--r--mysql-test/suite/versioning/t/load_data.test12
-rw-r--r--mysql-test/suite/versioning/t/online.test42
-rw-r--r--mysql-test/suite/versioning/t/optimized.test33
-rw-r--r--mysql-test/suite/versioning/t/partition.combinations5
-rw-r--r--mysql-test/suite/versioning/t/partition.test487
-rw-r--r--mysql-test/suite/versioning/t/replace.test13
-rw-r--r--mysql-test/suite/versioning/t/rpl.test136
-rw-r--r--mysql-test/suite/versioning/t/select.test307
-rw-r--r--mysql-test/suite/versioning/t/select2.test208
-rw-r--r--mysql-test/suite/versioning/t/simple.test73
-rw-r--r--mysql-test/suite/versioning/t/sysvars.test87
-rw-r--r--mysql-test/suite/versioning/t/truncate.test90
-rw-r--r--mysql-test/suite/versioning/t/truncate_privilege.test41
-rw-r--r--mysql-test/suite/versioning/t/trx_id.test119
-rw-r--r--mysql-test/suite/versioning/t/update.test150
-rw-r--r--mysql-test/suite/versioning/t/update2.test31
-rw-r--r--mysql-test/suite/versioning/t/view.test116
-rw-r--r--mysql-test/suite/versioning/t/vtmd.test206
-rw-r--r--mysql-test/suite/versioning/t/vtmd_show.test92
-rw-r--r--mysql-test/suite/versioning/wait_system_clock.inc10
-rw-r--r--mysql-test/suite/wsrep/suite.pm6
-rw-r--r--mysql-test/t/alter_table.test34
-rw-r--r--mysql-test/t/binary_to_hex.test20
-rw-r--r--mysql-test/t/bootstrap.test2
-rw-r--r--mysql-test/t/cast.test137
-rw-r--r--mysql-test/t/create.test143
-rw-r--r--mysql-test/t/create_drop_binlog.test2
-rw-r--r--mysql-test/t/create_or_replace.test24
-rw-r--r--mysql-test/t/cte_grant.test53
-rw-r--r--mysql-test/t/cte_nonrecursive.test199
-rw-r--r--mysql-test/t/cte_recursive.test332
-rw-r--r--mysql-test/t/ctype_latin1.test3
-rw-r--r--mysql-test/t/ctype_like_range.test40
-rw-r--r--mysql-test/t/ctype_ucs2_uca.test4
-rw-r--r--mysql-test/t/ctype_utf16_uca.test5
-rw-r--r--mysql-test/t/ctype_utf32_uca.test5
-rw-r--r--mysql-test/t/ctype_utf8.test12
-rw-r--r--mysql-test/t/ctype_utf8_uca.test3
-rw-r--r--mysql-test/t/ctype_utf8mb4.test18
-rw-r--r--mysql-test/t/ctype_utf8mb4_uca.test5
-rw-r--r--mysql-test/t/custom_aggregate_functions.test785
-rw-r--r--mysql-test/t/derived.test38
-rw-r--r--mysql-test/t/derived_cond_pushdown.test833
-rw-r--r--mysql-test/t/dyncol.test17
-rw-r--r--mysql-test/t/explain_json.test11
-rw-r--r--mysql-test/t/frm_bad_row_type-7333.test2
-rw-r--r--mysql-test/t/fulltext.test15
-rw-r--r--mysql-test/t/func_concat.test6
-rw-r--r--mysql-test/t/func_gconcat.test73
-rw-r--r--mysql-test/t/func_in.test14
-rw-r--r--mysql-test/t/func_isnull.test48
-rw-r--r--mysql-test/t/func_json.test14
-rw-r--r--mysql-test/t/func_misc.test21
-rw-r--r--mysql-test/t/func_set.test18
-rw-r--r--mysql-test/t/func_str.test30
-rw-r--r--mysql-test/t/func_time.test53
-rw-r--r--mysql-test/t/gis-json.test4
-rw-r--r--mysql-test/t/gis-rtree.test50
-rw-r--r--mysql-test/t/group_by.test26
-rw-r--r--mysql-test/t/having.test17
-rw-r--r--mysql-test/t/information_schema.test6
-rw-r--r--mysql-test/t/intersect.test15
-rw-r--r--mysql-test/t/invisible_binlog.test32
-rw-r--r--mysql-test/t/invisible_field.test240
-rw-r--r--mysql-test/t/invisible_field_debug.test272
-rw-r--r--mysql-test/t/join_cache.test45
-rw-r--r--mysql-test/t/join_outer.test14
-rw-r--r--mysql-test/t/loadxml.test19
-rw-r--r--mysql-test/t/mdev_14586.test27
-rw-r--r--mysql-test/t/merge.test8
-rw-r--r--mysql-test/t/myisam.test27
-rw-r--r--mysql-test/t/myisam_optimize.test17
-rw-r--r--mysql-test/t/mysql_upgrade.test22
-rw-r--r--mysql-test/t/mysqlbinlog.test6
-rw-r--r--mysql-test/t/mysqlbinlog_row_big.test1
-rw-r--r--mysql-test/t/mysqld--help.test4
-rw-r--r--mysql-test/t/mysqldump-nl.test20
-rw-r--r--mysql-test/t/mysqldump.test45
-rw-r--r--mysql-test/t/openssl_1.test3
-rw-r--r--mysql-test/t/opt_tvc.test63
-rw-r--r--mysql-test/t/order_by.test81
-rw-r--r--mysql-test/t/order_by_innodb.test47
-rw-r--r--mysql-test/t/partition.test17
-rw-r--r--mysql-test/t/partition_alter.test11
-rw-r--r--mysql-test/t/partition_innodb.test28
-rw-r--r--mysql-test/t/ps.test196
-rw-r--r--mysql-test/t/ps_1general.test4
-rw-r--r--mysql-test/t/query_cache_debug.test52
-rw-r--r--mysql-test/t/range.test8
-rw-r--r--mysql-test/t/repair.test23
-rw-r--r--mysql-test/t/select.test2
-rw-r--r--mysql-test/t/show_bad_definer-5553.test2
-rw-r--r--mysql-test/t/show_check.test54
-rw-r--r--mysql-test/t/simultaneous_assignment.test204
-rw-r--r--mysql-test/t/sp-big.test40
-rw-r--r--mysql-test/t/sp-code.test169
-rw-r--r--mysql-test/t/sp-cursor.test133
-rw-r--r--mysql-test/t/sp-destruct.test2
-rw-r--r--mysql-test/t/sp-error.test2
-rw-r--r--mysql-test/t/sp-for-loop.test212
-rw-r--r--mysql-test/t/sp-row.test4
-rw-r--r--mysql-test/t/sp.test327
-rw-r--r--mysql-test/t/sql_mode.test2
-rw-r--r--mysql-test/t/status.test10
-rw-r--r--mysql-test/t/subselect.test39
-rw-r--r--mysql-test/t/system_mysql_db_fix40123.test2
-rw-r--r--mysql-test/t/system_mysql_db_fix50030.test2
-rw-r--r--mysql-test/t/system_mysql_db_fix50117.test2
-rw-r--r--mysql-test/t/thread_id_overflow.test35
-rw-r--r--mysql-test/t/trigger.test27
-rw-r--r--mysql-test/t/type_datetime.test77
-rw-r--r--mysql-test/t/type_set.test8
-rw-r--r--mysql-test/t/type_time.test491
-rw-r--r--mysql-test/t/type_time_6065.test23
-rw-r--r--mysql-test/t/union.test36
-rw-r--r--mysql-test/t/update_innodb.test12
-rw-r--r--mysql-test/t/view.test130
-rw-r--r--mysql-test/t/win.test30
-rw-r--r--mysql-test/t/xa.test65
-rw-r--r--mysql-test/t/xml.test11
-rw-r--r--mysys/CMakeLists.txt3
-rw-r--r--mysys/file_logger.c4
-rw-r--r--mysys/get_password.c1
-rw-r--r--mysys/guess_malloc_library.c65
-rw-r--r--mysys/hash.c2
-rw-r--r--mysys/lf_alloc-pin.c6
-rw-r--r--mysys/lf_hash.c10
-rw-r--r--mysys/ma_dyncol.c61
-rw-r--r--mysys/mf_iocache.c17
-rw-r--r--mysys/mf_iocache2.c27
-rw-r--r--mysys/mf_keycache.c6
-rw-r--r--mysys/my_access.c2
-rw-r--r--mysys/my_addr_resolve.c172
-rw-r--r--mysys/my_alloc.c33
-rw-r--r--mysys/my_atomic_writes.c2
-rw-r--r--mysys/my_bitmap.c3
-rw-r--r--mysys/my_compare.c4
-rw-r--r--mysys/my_conio.c4
-rw-r--r--mysys/my_context.c2
-rw-r--r--mysys/my_default.c17
-rw-r--r--mysys/my_delete.c4
-rw-r--r--mysys/my_getopt.c48
-rw-r--r--mysys/my_init.c4
-rw-r--r--mysys/my_lib.c20
-rw-r--r--mysys/my_lock.c1
-rw-r--r--mysys/my_malloc.c11
-rw-r--r--mysys/my_pthread.c1
-rw-r--r--mysys/my_read.c40
-rw-r--r--mysys/my_sync.c3
-rw-r--r--mysys/my_thr_init.c5
-rw-r--r--mysys/my_wincond.c5
-rw-r--r--mysys/my_windac.c21
-rw-r--r--mysys/my_winerr.c2
-rw-r--r--mysys/my_winthread.c4
-rw-r--r--mysys/mysys_priv.h4
-rw-r--r--mysys/safemalloc.c4
-rw-r--r--mysys/stacktrace.c12
-rw-r--r--mysys/string.c6
-rw-r--r--mysys/thr_alarm.c18
-rw-r--r--mysys/thr_mutex.c4
-rw-r--r--mysys/tree.c3
-rw-r--r--mysys/typelib.c12
-rw-r--r--mysys/waiting_threads.c2
-rw-r--r--mysys_ssl/my_crypt.cc15
-rw-r--r--mysys_ssl/openssl.c2
-rw-r--r--mysys_ssl/yassl.cc1
-rw-r--r--pcre/pcregrep.c4
-rw-r--r--pcre/pcretest.c4
-rw-r--r--plugin/audit_null/audit_null.c4
-rw-r--r--plugin/auth_examples/qa_auth_client.c2
-rw-r--r--plugin/auth_examples/qa_auth_interface.c2
-rw-r--r--plugin/auth_examples/test_plugin.c2
-rw-r--r--plugin/auth_gssapi/mysql-test/auth_gssapi/basic.result8
-rw-r--r--plugin/auth_gssapi/server_plugin.cc4
-rw-r--r--plugin/auth_gssapi/server_plugin.h2
-rw-r--r--plugin/auth_gssapi/sspi_errmsg.cc2
-rw-r--r--plugin/auth_gssapi/sspi_server.cc8
-rw-r--r--plugin/aws_key_management/aws_key_management_plugin.cc4
-rw-r--r--plugin/feedback/feedback.cc2
-rw-r--r--plugin/feedback/sender_thread.cc15
-rw-r--r--plugin/feedback/url_http.cc8
-rw-r--r--plugin/feedback/utils.cc11
-rw-r--r--plugin/fulltext/plugin_example.c2
-rw-r--r--plugin/handler_socket/handlersocket/database.cpp11
-rw-r--r--plugin/semisync/semisync_master.cc1218
-rw-r--r--plugin/semisync/semisync_master_plugin.cc496
-rw-r--r--plugin/semisync/semisync_slave.cc140
-rw-r--r--plugin/semisync/semisync_slave.h97
-rw-r--r--plugin/semisync/semisync_slave_plugin.cc234
-rw-r--r--plugin/server_audit/server_audit.c77
-rw-r--r--plugin/server_audit/test_audit_v4.c6
-rw-r--r--plugin/simple_password_check/simple_password_check.c7
-rw-r--r--plugin/userstat/index_stats.cc25
-rw-r--r--plugin/userstat/table_stats.cc8
-rw-r--r--plugin/versioning/CMakeLists.txt (renamed from plugin/semisync/CMakeLists.txt)17
-rw-r--r--plugin/versioning/versioning.cc204
-rw-r--r--plugin/win_auth_client/common.cc12
-rw-r--r--plugin/win_auth_client/common.h4
-rw-r--r--plugin/win_auth_client/handshake.h4
-rw-r--r--plugin/win_auth_client/handshake_client.cc2
-rw-r--r--plugin/wsrep_info/mysql-test/wsrep_info/suite.pm6
-rw-r--r--scripts/galera_recovery.sh2
-rw-r--r--scripts/mysql_config.sh21
-rw-r--r--scripts/mysql_install_db.sh26
-rw-r--r--scripts/mysql_system_tables.sql30
-rw-r--r--scripts/mysql_system_tables_data.sql14
-rw-r--r--scripts/mysql_system_tables_fix.sql29
-rw-r--r--scripts/mysqld_safe.sh45
-rwxr-xr-xscripts/wsrep_sst_common.sh74
-rw-r--r--scripts/wsrep_sst_mariabackup.sh25
-rw-r--r--scripts/wsrep_sst_mysqldump.sh10
-rw-r--r--scripts/wsrep_sst_rsync.sh23
-rw-r--r--scripts/wsrep_sst_xtrabackup-v2.sh132
-rw-r--r--scripts/wsrep_sst_xtrabackup.sh74
-rw-r--r--sql-common/client.c36
-rw-r--r--sql-common/client_plugin.c2
-rw-r--r--sql-common/my_time.c32
-rw-r--r--sql-common/mysql_async.c4
-rw-r--r--sql/CMakeLists.txt13
-rw-r--r--sql/authors.h2
-rw-r--r--sql/compat56.cc6
-rw-r--r--sql/contributors.h3
-rw-r--r--sql/create_options.cc7
-rw-r--r--sql/create_options.h2
-rw-r--r--sql/debug_sync.cc4
-rw-r--r--sql/derror.cc7
-rw-r--r--sql/des_key_file.cc2
-rw-r--r--sql/discover.cc2
-rw-r--r--sql/event_data_objects.cc26
-rw-r--r--sql/event_data_objects.h2
-rw-r--r--sql/event_db_repository.cc154
-rw-r--r--sql/event_queue.cc4
-rw-r--r--sql/event_scheduler.cc13
-rw-r--r--sql/events.cc10
-rw-r--r--sql/field.cc627
-rw-r--r--sql/field.h320
-rw-r--r--sql/field_conv.cc21
-rw-r--r--sql/filesort.cc60
-rw-r--r--sql/filesort_utils.cc2
-rw-r--r--sql/gcalc_slicescan.cc6
-rw-r--r--sql/gen_lex_token.cc2
-rw-r--r--sql/ha_partition.cc3304
-rw-r--r--sql/ha_partition.h314
-rw-r--r--sql/ha_sequence.cc3
-rw-r--r--sql/handler.cc1015
-rw-r--r--sql/handler.h403
-rw-r--r--sql/hostname.cc53
-rw-r--r--sql/innodb_priv.h6
-rw-r--r--sql/item.cc1247
-rw-r--r--sql/item.h704
-rw-r--r--sql/item_cmpfunc.cc154
-rw-r--r--sql/item_cmpfunc.h230
-rw-r--r--sql/item_create.cc729
-rw-r--r--sql/item_create.h43
-rw-r--r--sql/item_func.cc502
-rw-r--r--sql/item_func.h462
-rw-r--r--sql/item_geofunc.cc3
-rw-r--r--sql/item_geofunc.h146
-rw-r--r--sql/item_inetfunc.h32
-rw-r--r--sql/item_jsonfunc.cc16
-rw-r--r--sql/item_jsonfunc.h88
-rw-r--r--sql/item_row.cc10
-rw-r--r--sql/item_row.h15
-rw-r--r--sql/item_strfunc.cc294
-rw-r--r--sql/item_strfunc.h325
-rw-r--r--sql/item_subselect.cc31
-rw-r--r--sql/item_subselect.h7
-rw-r--r--sql/item_sum.cc636
-rw-r--r--sql/item_sum.h271
-rw-r--r--sql/item_timefunc.cc81
-rw-r--r--sql/item_timefunc.h207
-rw-r--r--sql/item_vers.cc182
-rw-r--r--sql/item_vers.h114
-rw-r--r--sql/item_windowfunc.cc20
-rw-r--r--sql/item_windowfunc.h78
-rw-r--r--sql/item_xmlfunc.cc78
-rw-r--r--sql/item_xmlfunc.h9
-rw-r--r--sql/key.cc44
-rw-r--r--sql/keycaches.cc30
-rw-r--r--sql/keycaches.h14
-rw-r--r--sql/lex.h8
-rw-r--r--sql/lex_string.h52
-rw-r--r--sql/lock.cc17
-rw-r--r--sql/log.cc704
-rw-r--r--sql/log.h165
-rw-r--r--sql/log_event.cc1826
-rw-r--r--sql/log_event.h258
-rw-r--r--sql/log_event_old.cc36
-rw-r--r--sql/log_event_old.h10
-rw-r--r--sql/mdl.cc2
-rw-r--r--sql/mdl.h5
-rw-r--r--sql/mf_iocache_encr.cc13
-rw-r--r--sql/multi_range_read.cc8
-rw-r--r--sql/my_apc.cc24
-rw-r--r--sql/my_apc.h6
-rw-r--r--sql/my_decimal.cc2
-rw-r--r--sql/my_decimal.h6
-rw-r--r--sql/my_json_writer.cc4
-rw-r--r--sql/my_json_writer.h5
-rw-r--r--sql/mysql_install_db.cc26
-rw-r--r--sql/mysql_upgrade_service.cc6
-rw-r--r--sql/mysqld.cc511
-rw-r--r--sql/mysqld.h71
-rw-r--r--sql/net_serv.cc32
-rw-r--r--sql/nt_servc.cc22
-rw-r--r--sql/nt_servc.h8
-rw-r--r--sql/opt_range.cc55
-rw-r--r--sql/opt_range.h49
-rw-r--r--sql/opt_split.cc1137
-rw-r--r--sql/opt_subselect.cc107
-rw-r--r--sql/opt_sum.cc3
-rw-r--r--sql/opt_table_elimination.cc1
-rw-r--r--sql/parse_file.cc4
-rw-r--r--sql/partition_element.h69
-rw-r--r--sql/partition_info.cc720
-rw-r--r--sql/partition_info.h107
-rw-r--r--sql/password.c2
-rw-r--r--sql/procedure.cc2
-rw-r--r--sql/procedure.h6
-rw-r--r--sql/protocol.cc14
-rw-r--r--sql/proxy_protocol.cc21
-rw-r--r--sql/records.cc4
-rw-r--r--sql/repl_failsafe.cc2
-rw-r--r--sql/repl_failsafe.h2
-rw-r--r--sql/replication.h14
-rw-r--r--sql/rpl_filter.cc4
-rw-r--r--sql/rpl_gtid.cc192
-rw-r--r--sql/rpl_gtid.h11
-rw-r--r--sql/rpl_handler.cc553
-rw-r--r--sql/rpl_handler.h216
-rw-r--r--sql/rpl_injector.cc3
-rw-r--r--sql/rpl_injector.h2
-rw-r--r--sql/rpl_mi.cc4
-rw-r--r--sql/rpl_mi.h26
-rw-r--r--sql/rpl_parallel.cc19
-rw-r--r--sql/rpl_rli.cc25
-rw-r--r--sql/rpl_tblmap.cc3
-rw-r--r--sql/rpl_utility.cc18
-rw-r--r--sql/semisync.cc (renamed from plugin/semisync/semisync.cc)16
-rw-r--r--sql/semisync.h (renamed from plugin/semisync/semisync.h)52
-rw-r--r--sql/semisync_master.cc1352
-rw-r--r--sql/semisync_master.h (renamed from plugin/semisync/semisync_master.h)300
-rw-r--r--sql/semisync_master_ack_receiver.cc307
-rw-r--r--sql/semisync_master_ack_receiver.h119
-rw-r--r--sql/semisync_slave.cc251
-rw-r--r--sql/semisync_slave.h115
-rw-r--r--sql/session_tracker.cc10
-rw-r--r--sql/set_var.cc28
-rw-r--r--sql/share/errmsg-utf8.txt261
-rw-r--r--sql/signal_handler.cc6
-rw-r--r--sql/slave.cc464
-rw-r--r--sql/slave.h9
-rw-r--r--sql/sp.cc169
-rw-r--r--sql/sp.h13
-rw-r--r--sql/sp_cache.cc8
-rw-r--r--sql/sp_cache.h1
-rw-r--r--sql/sp_head.cc420
-rw-r--r--sql/sp_head.h62
-rw-r--r--sql/sp_pcontext.cc24
-rw-r--r--sql/sp_pcontext.h2
-rw-r--r--sql/sp_rcontext.cc162
-rw-r--r--sql/sp_rcontext.h42
-rw-r--r--sql/spatial.cc37
-rw-r--r--sql/spatial.h3
-rw-r--r--sql/sql_acl.cc387
-rw-r--r--sql/sql_acl.h35
-rw-r--r--sql/sql_admin.cc30
-rw-r--r--sql/sql_alloc.h17
-rw-r--r--sql/sql_alter.cc59
-rw-r--r--sql/sql_alter.h176
-rw-r--r--sql/sql_array.h13
-rw-r--r--sql/sql_audit.cc1
-rw-r--r--sql/sql_audit.h76
-rw-r--r--sql/sql_base.cc813
-rw-r--r--sql/sql_base.h35
-rw-r--r--sql/sql_binlog.cc2
-rw-r--r--sql/sql_bootstrap.cc6
-rw-r--r--sql/sql_cache.cc318
-rw-r--r--sql/sql_cache.h98
-rw-r--r--sql/sql_class.cc312
-rw-r--r--sql/sql_class.h625
-rw-r--r--sql/sql_connect.cc60
-rw-r--r--sql/sql_const.h1
-rw-r--r--sql/sql_cte.cc77
-rw-r--r--sql/sql_cte.h6
-rw-r--r--sql/sql_cursor.cc6
-rw-r--r--sql/sql_cursor.h1
-rw-r--r--sql/sql_db.cc149
-rw-r--r--sql/sql_db.h8
-rw-r--r--sql/sql_delete.cc178
-rw-r--r--sql/sql_derived.cc104
-rw-r--r--sql/sql_digest.cc4
-rw-r--r--sql/sql_digest.h4
-rw-r--r--sql/sql_do.cc2
-rw-r--r--sql/sql_error.cc27
-rw-r--r--sql/sql_error.h12
-rw-r--r--sql/sql_explain.cc18
-rw-r--r--sql/sql_explain.h7
-rw-r--r--sql/sql_expression_cache.cc3
-rw-r--r--sql/sql_get_diagnostics.cc3
-rw-r--r--sql/sql_handler.cc175
-rw-r--r--sql/sql_handler.h6
-rw-r--r--sql/sql_help.cc26
-rw-r--r--sql/sql_insert.cc225
-rw-r--r--sql/sql_insert.h1
-rw-r--r--sql/sql_join_cache.cc24
-rw-r--r--sql/sql_join_cache.h20
-rw-r--r--sql/sql_lex.cc172
-rw-r--r--sql/sql_lex.h105
-rw-r--r--sql/sql_lifo_buffer.h4
-rw-r--r--sql/sql_list.cc18
-rw-r--r--sql/sql_list.h9
-rw-r--r--sql/sql_load.cc162
-rw-r--r--sql/sql_parse.cc574
-rw-r--r--sql/sql_parse.h22
-rw-r--r--sql/sql_partition.cc1031
-rw-r--r--sql/sql_partition.h51
-rw-r--r--sql/sql_partition_admin.cc38
-rw-r--r--sql/sql_plugin.cc110
-rw-r--r--sql/sql_plugin.h5
-rw-r--r--sql/sql_prepare.cc393
-rw-r--r--sql/sql_prepare.h16
-rw-r--r--sql/sql_priv.h6
-rw-r--r--sql/sql_profile.cc5
-rw-r--r--sql/sql_profile.h4
-rw-r--r--sql/sql_reload.cc19
-rw-r--r--sql/sql_rename.cc95
-rw-r--r--sql/sql_repl.cc208
-rw-r--r--sql/sql_repl.h1
-rw-r--r--sql/sql_select.cc944
-rw-r--r--sql/sql_select.h144
-rw-r--r--sql/sql_sequence.cc30
-rw-r--r--sql/sql_servers.cc23
-rw-r--r--sql/sql_servers.h2
-rw-r--r--sql/sql_show.cc736
-rw-r--r--sql/sql_show.h17
-rw-r--r--sql/sql_signal.cc64
-rw-r--r--sql/sql_statistics.cc169
-rw-r--r--sql/sql_statistics.h18
-rw-r--r--sql/sql_string.cc57
-rw-r--r--sql/sql_string.h122
-rw-r--r--sql/sql_table.cc1286
-rw-r--r--sql/sql_table.h30
-rw-r--r--sql/sql_time.cc161
-rw-r--r--sql/sql_time.h19
-rw-r--r--sql/sql_trigger.cc231
-rw-r--r--sql/sql_trigger.h41
-rw-r--r--sql/sql_truncate.cc44
-rw-r--r--sql/sql_tvc.cc8
-rw-r--r--sql/sql_tvc.h4
-rw-r--r--sql/sql_type.cc400
-rw-r--r--sql/sql_type.h431
-rw-r--r--sql/sql_udf.cc21
-rw-r--r--sql/sql_udf.h2
-rw-r--r--sql/sql_union.cc78
-rw-r--r--sql/sql_update.cc340
-rw-r--r--sql/sql_view.cc203
-rw-r--r--sql/sql_view.h2
-rw-r--r--sql/sql_window.cc9
-rw-r--r--sql/sql_window.h1
-rw-r--r--sql/sql_yacc.yy952
-rw-r--r--sql/sql_yacc_ora.yy271
-rw-r--r--sql/strfunc.cc12
-rw-r--r--sql/strfunc.h10
-rw-r--r--sql/structs.h6
-rw-r--r--sql/sys_vars.cc266
-rw-r--r--sql/sys_vars.ic99
-rw-r--r--sql/sys_vars_shared.h2
-rw-r--r--sql/table.cc873
-rw-r--r--sql/table.h477
-rw-r--r--sql/table_cache.cc11
-rw-r--r--sql/temporary_tables.cc40
-rw-r--r--sql/thr_malloc.cc7
-rw-r--r--sql/thr_malloc.h4
-rw-r--r--sql/threadpool_common.cc24
-rw-r--r--sql/threadpool_generic.cc143
-rw-r--r--sql/threadpool_win.cc5
-rw-r--r--sql/transaction.cc49
-rw-r--r--sql/tztime.cc47
-rw-r--r--sql/tztime.h1
-rw-r--r--sql/udf_example.c9
-rw-r--r--sql/uniques.cc8
-rw-r--r--sql/unireg.cc141
-rw-r--r--sql/unireg.h13
-rw-r--r--sql/vers_string.h148
-rw-r--r--sql/vers_utils.h81
-rw-r--r--sql/vtmd.cc683
-rw-r--r--sql/vtmd.h190
-rw-r--r--sql/wsrep_binlog.cc19
-rw-r--r--sql/wsrep_hton.cc33
-rw-r--r--sql/wsrep_mysqld.cc79
-rw-r--r--sql/wsrep_mysqld.h2
-rw-r--r--sql/wsrep_sst.cc19
-rw-r--r--sql/wsrep_sst.h3
-rw-r--r--sql/wsrep_thd.cc12
-rw-r--r--sql/wsrep_var.cc30
-rw-r--r--sql/wsrep_var.h3
-rw-r--r--storage/archive/azio.c14
-rw-r--r--storage/archive/azlib.h4
-rw-r--r--storage/archive/ha_archive.cc2
-rw-r--r--storage/cassandra/ha_cassandra.cc2
-rw-r--r--storage/connect/CMakeLists.txt16
-rw-r--r--storage/connect/domdoc.cpp2
-rw-r--r--[-rwxr-xr-x]storage/connect/filamvct.cpp0
-rw-r--r--storage/connect/global.h3
-rw-r--r--storage/connect/ha_connect.cc68
-rw-r--r--storage/connect/inihandl.cpp (renamed from storage/connect/inihandl.c)35
-rw-r--r--storage/connect/jsonudf.cpp13
-rw-r--r--storage/connect/myconn.cpp5
-rw-r--r--storage/connect/mysql-test/connect/disabled.def1
-rw-r--r--storage/connect/mysql-test/connect/r/infoschema-9739.result2
-rw-r--r--storage/connect/mysql-test/connect/r/infoschema2-9739.result2
-rw-r--r--storage/connect/odbconn.cpp4
-rw-r--r--storage/connect/plgdbutl.cpp2
-rw-r--r--storage/connect/plugutil.cpp73
-rw-r--r--storage/connect/reldef.cpp14
-rw-r--r--storage/connect/tabtbl.cpp20
-rw-r--r--storage/connect/tabtbl.h50
-rw-r--r--storage/connect/user_connect.cc23
-rw-r--r--[-rwxr-xr-x]storage/connect/xindex.cpp0
-rw-r--r--storage/csv/ha_tina.cc4
-rw-r--r--storage/federated/ha_federated.cc2
-rw-r--r--storage/federated/ha_federated.h1
-rw-r--r--storage/federatedx/federatedx_io_mysql.cc19
-rw-r--r--storage/federatedx/federatedx_io_null.cc4
-rw-r--r--storage/federatedx/ha_federatedx.cc14
-rw-r--r--storage/federatedx/ha_federatedx.h10
-rw-r--r--storage/heap/_check.c2
-rw-r--r--storage/heap/ha_heap.cc2
-rw-r--r--storage/heap/heapdef.h20
-rw-r--r--storage/heap/hp_create.c8
-rw-r--r--storage/heap/hp_delete.c4
-rw-r--r--storage/heap/hp_hash.c108
-rw-r--r--storage/heap/hp_rrnd.c2
-rw-r--r--storage/heap/hp_rsame.c2
-rw-r--r--storage/heap/hp_scan.c2
-rw-r--r--storage/heap/hp_write.c4
-rw-r--r--storage/innobase/CMakeLists.txt21
-rw-r--r--storage/innobase/btr/btr0btr.cc66
-rw-r--r--storage/innobase/btr/btr0cur.cc249
-rw-r--r--storage/innobase/btr/btr0defragment.cc8
-rw-r--r--storage/innobase/btr/btr0pcur.cc9
-rw-r--r--storage/innobase/btr/btr0sea.cc377
-rw-r--r--storage/innobase/buf/buf0buddy.cc3
-rw-r--r--storage/innobase/buf/buf0buf.cc111
-rw-r--r--storage/innobase/buf/buf0dump.cc118
-rw-r--r--storage/innobase/buf/buf0flu.cc336
-rw-r--r--storage/innobase/buf/buf0lru.cc172
-rw-r--r--storage/innobase/data/data0type.cc17
-rw-r--r--storage/innobase/dict/dict0crea.cc3
-rw-r--r--storage/innobase/dict/dict0defrag_bg.cc40
-rw-r--r--storage/innobase/dict/dict0dict.cc47
-rw-r--r--storage/innobase/dict/dict0load.cc22
-rw-r--r--storage/innobase/dict/dict0mem.cc98
-rw-r--r--storage/innobase/dict/dict0stats.cc234
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc4
-rw-r--r--storage/innobase/fil/fil0crypt.cc6
-rw-r--r--storage/innobase/fil/fil0fil.cc204
-rw-r--r--storage/innobase/fsp/fsp0file.cc63
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc6
-rw-r--r--storage/innobase/fsp/fsp0sysspace.cc5
-rw-r--r--storage/innobase/fts/fts0config.cc4
-rw-r--r--storage/innobase/fts/fts0fts.cc256
-rw-r--r--storage/innobase/fts/fts0opt.cc15
-rw-r--r--storage/innobase/fts/fts0que.cc17
-rw-r--r--storage/innobase/fut/fut0lst.cc6
-rw-r--r--storage/innobase/gis/gis0rtree.cc12
-rw-r--r--storage/innobase/gis/gis0sea.cc17
-rw-r--r--storage/innobase/ha/ha0ha.cc58
-rw-r--r--storage/innobase/handler/ha_innodb.cc634
-rw-r--r--storage/innobase/handler/ha_innodb.h10
-rw-r--r--storage/innobase/handler/handler0alter.cc127
-rw-r--r--storage/innobase/handler/i_s.cc102
-rw-r--r--storage/innobase/handler/i_s.h8
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc9
-rw-r--r--storage/innobase/include/btr0btr.h24
-rw-r--r--storage/innobase/include/btr0btr.ic26
-rw-r--r--storage/innobase/include/btr0cur.h29
-rw-r--r--storage/innobase/include/btr0cur.ic16
-rw-r--r--storage/innobase/include/btr0pcur.h27
-rw-r--r--storage/innobase/include/btr0pcur.ic50
-rw-r--r--storage/innobase/include/btr0sea.h57
-rw-r--r--storage/innobase/include/btr0sea.ic51
-rw-r--r--storage/innobase/include/buf0buf.h12
-rw-r--r--storage/innobase/include/buf0flu.h11
-rw-r--r--storage/innobase/include/buf0lru.h16
-rw-r--r--storage/innobase/include/data0data.h16
-rw-r--r--storage/innobase/include/data0type.h73
-rw-r--r--storage/innobase/include/data0type.ic92
-rw-r--r--storage/innobase/include/dict0defrag_bg.h5
-rw-r--r--storage/innobase/include/dict0dict.h20
-rw-r--r--storage/innobase/include/dict0dict.ic42
-rw-r--r--storage/innobase/include/dict0load.h3
-rw-r--r--storage/innobase/include/dict0mem.h111
-rw-r--r--storage/innobase/include/dict0stats.h52
-rw-r--r--storage/innobase/include/dict0stats.ic2
-rw-r--r--storage/innobase/include/dict0types.h7
-rw-r--r--storage/innobase/include/fil0fil.h67
-rw-r--r--storage/innobase/include/fsp0file.h3
-rw-r--r--storage/innobase/include/fts0fts.h22
-rw-r--r--storage/innobase/include/ha0ha.h10
-rw-r--r--storage/innobase/include/ib0mutex.h6
-rw-r--r--storage/innobase/include/lock0lock.h156
-rw-r--r--storage/innobase/include/lock0lock.ic9
-rw-r--r--storage/innobase/include/lock0priv.h23
-rw-r--r--storage/innobase/include/lock0types.h1
-rw-r--r--storage/innobase/include/log0log.h18
-rw-r--r--storage/innobase/include/log0recv.h10
-rw-r--r--storage/innobase/include/mem0mem.ic10
-rw-r--r--storage/innobase/include/mtr0mtr.h22
-rw-r--r--storage/innobase/include/mtr0types.h11
-rw-r--r--storage/innobase/include/os0file.h5
-rw-r--r--storage/innobase/include/os0once.h3
-rw-r--r--storage/innobase/include/os0thread.h6
-rw-r--r--storage/innobase/include/page0page.h48
-rw-r--r--storage/innobase/include/page0page.ic33
-rw-r--r--storage/innobase/include/pars0opt.h3
-rw-r--r--storage/innobase/include/pars0pars.h3
-rw-r--r--storage/innobase/include/pars0sym.h3
-rw-r--r--storage/innobase/include/que0que.h24
-rw-r--r--storage/innobase/include/que0que.ic2
-rw-r--r--storage/innobase/include/read0read.h125
-rw-r--r--storage/innobase/include/read0types.h352
-rw-r--r--storage/innobase/include/rem0rec.h2
-rw-r--r--storage/innobase/include/rem0rec.ic6
-rw-r--r--storage/innobase/include/row0ins.h10
-rw-r--r--storage/innobase/include/row0merge.h7
-rw-r--r--storage/innobase/include/row0mysql.h79
-rw-r--r--storage/innobase/include/row0upd.h89
-rw-r--r--storage/innobase/include/row0upd.ic5
-rw-r--r--storage/innobase/include/row0vers.h23
-rw-r--r--storage/innobase/include/srv0mon.h10
-rw-r--r--storage/innobase/include/srv0srv.h18
-rw-r--r--storage/innobase/include/sync0policy.h11
-rw-r--r--storage/innobase/include/sync0rw.h16
-rw-r--r--storage/innobase/include/sync0rw.ic131
-rw-r--r--storage/innobase/include/sync0sync.h4
-rw-r--r--storage/innobase/include/sync0types.h48
-rw-r--r--storage/innobase/include/trx0i_s.h4
-rw-r--r--storage/innobase/include/trx0purge.h242
-rw-r--r--storage/innobase/include/trx0purge.ic21
-rw-r--r--storage/innobase/include/trx0rec.h50
-rw-r--r--storage/innobase/include/trx0rec.ic5
-rw-r--r--storage/innobase/include/trx0roll.h22
-rw-r--r--storage/innobase/include/trx0rseg.h135
-rw-r--r--storage/innobase/include/trx0rseg.ic24
-rw-r--r--storage/innobase/include/trx0sys.h1220
-rw-r--r--storage/innobase/include/trx0sys.ic448
-rw-r--r--storage/innobase/include/trx0trx.h327
-rw-r--r--storage/innobase/include/trx0trx.ic76
-rw-r--r--storage/innobase/include/trx0types.h57
-rw-r--r--storage/innobase/include/trx0undo.h123
-rw-r--r--storage/innobase/include/trx0undo.ic143
-rw-r--r--storage/innobase/include/univ.i12
-rw-r--r--storage/innobase/include/usr0sess.h69
-rw-r--r--storage/innobase/include/usr0types.h31
-rw-r--r--storage/innobase/include/ut0crc32.h9
-rw-r--r--storage/innobase/include/ut0mutex.h2
-rw-r--r--storage/innobase/include/ut0new.h96
-rw-r--r--storage/innobase/include/ut0rnd.h10
-rw-r--r--storage/innobase/include/ut0rnd.ic24
-rw-r--r--storage/innobase/include/ut0ut.h83
-rw-r--r--storage/innobase/innodb.cmake14
-rw-r--r--storage/innobase/lock/lock0lock.cc2076
-rw-r--r--storage/innobase/lock/lock0prdt.cc27
-rw-r--r--storage/innobase/lock/lock0wait.cc76
-rw-r--r--storage/innobase/log/log0crypt.cc6
-rw-r--r--storage/innobase/log/log0log.cc43
-rw-r--r--storage/innobase/log/log0recv.cc170
-rw-r--r--storage/innobase/mem/mem0mem.cc6
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc3
-rw-r--r--storage/innobase/os/os0event.cc12
-rw-r--r--storage/innobase/os/os0file.cc72
-rw-r--r--storage/innobase/page/page0cur.cc23
-rw-r--r--storage/innobase/page/page0page.cc16
-rw-r--r--storage/innobase/page/page0zip.cc22
-rw-r--r--storage/innobase/pars/pars0pars.cc6
-rw-r--r--storage/innobase/que/que0que.cc13
-rw-r--r--storage/innobase/read/read0read.cc728
-rw-r--r--storage/innobase/rem/rem0rec.cc75
-rw-r--r--storage/innobase/row/row0ext.cc2
-rw-r--r--storage/innobase/row/row0ftsort.cc25
-rw-r--r--storage/innobase/row/row0import.cc111
-rw-r--r--storage/innobase/row/row0ins.cc443
-rw-r--r--storage/innobase/row/row0log.cc70
-rw-r--r--storage/innobase/row/row0merge.cc124
-rw-r--r--storage/innobase/row/row0mysql.cc981
-rw-r--r--storage/innobase/row/row0purge.cc25
-rw-r--r--storage/innobase/row/row0quiesce.cc51
-rw-r--r--storage/innobase/row/row0row.cc27
-rw-r--r--storage/innobase/row/row0sel.cc394
-rw-r--r--storage/innobase/row/row0trunc.cc48
-rw-r--r--storage/innobase/row/row0uins.cc31
-rw-r--r--storage/innobase/row/row0umod.cc38
-rw-r--r--storage/innobase/row/row0undo.cc9
-rw-r--r--storage/innobase/row/row0upd.cc198
-rw-r--r--storage/innobase/row/row0vers.cc323
-rw-r--r--storage/innobase/srv/srv0conc.cc16
-rw-r--r--storage/innobase/srv/srv0mon.cc8
-rw-r--r--storage/innobase/srv/srv0srv.cc232
-rw-r--r--storage/innobase/srv/srv0start.cc141
-rw-r--r--storage/innobase/sync/sync0arr.cc22
-rw-r--r--storage/innobase/sync/sync0debug.cc35
-rw-r--r--storage/innobase/sync/sync0rw.cc107
-rw-r--r--storage/innobase/sync/sync0sync.cc10
-rw-r--r--storage/innobase/trx/trx0i_s.cc192
-rw-r--r--storage/innobase/trx/trx0purge.cc669
-rw-r--r--storage/innobase/trx/trx0rec.cc400
-rw-r--r--storage/innobase/trx/trx0roll.cc352
-rw-r--r--storage/innobase/trx/trx0rseg.cc558
-rw-r--r--storage/innobase/trx/trx0sys.cc520
-rw-r--r--storage/innobase/trx/trx0trx.cc1118
-rw-r--r--storage/innobase/trx/trx0undo.cc794
-rw-r--r--storage/innobase/usr/usr0sess.cc58
-rw-r--r--storage/innobase/ut/ut0crc32.cc200
-rw-r--r--storage/innobase/ut/ut0dbg.cc4
-rw-r--r--storage/innobase/ut/ut0new.cc3
-rw-r--r--storage/innobase/ut/ut0ut.cc73
-rw-r--r--storage/maria/ft_maria.c4
-rw-r--r--storage/maria/ha_maria.cc7
-rw-r--r--storage/maria/lockman.c8
-rw-r--r--storage/maria/ma_bitmap.c241
-rw-r--r--storage/maria/ma_blockrec.c20
-rw-r--r--storage/maria/ma_check.c7
-rw-r--r--storage/maria/ma_checkpoint.c14
-rw-r--r--storage/maria/ma_control_file.c2
-rw-r--r--storage/maria/ma_create.c18
-rw-r--r--storage/maria/ma_delete.c6
-rw-r--r--storage/maria/ma_dynrec.c11
-rw-r--r--storage/maria/ma_ft_boolean_search.c2
-rw-r--r--storage/maria/ma_ft_parser.c3
-rw-r--r--storage/maria/ma_keycache.c2
-rw-r--r--storage/maria/ma_loghandler.c12
-rw-r--r--storage/maria/ma_norec.c4
-rw-r--r--storage/maria/ma_open.c2
-rw-r--r--storage/maria/ma_page.c44
-rw-r--r--storage/maria/ma_pagecache.c8
-rw-r--r--storage/maria/ma_recovery.c2
-rw-r--r--storage/maria/ma_rename.c4
-rw-r--r--storage/maria/ma_search.c16
-rw-r--r--storage/maria/ma_state.c24
-rw-r--r--storage/maria/ma_state.h1
-rw-r--r--storage/maria/ma_test1.c10
-rw-r--r--storage/maria/ma_write.c2
-rw-r--r--storage/maria/maria_chk.c2
-rw-r--r--storage/maria/maria_def.h10
-rw-r--r--storage/maria/unittest/ma_control_file-t.c2
-rw-r--r--storage/maria/unittest/ma_maria_log_cleanup.c2
-rw-r--r--storage/maria/unittest/ma_pagecache_consist.c7
-rw-r--r--storage/maria/unittest/ma_pagecache_rwconsist.c7
-rw-r--r--storage/maria/unittest/ma_pagecache_rwconsist2.c7
-rw-r--r--storage/maria/unittest/ma_pagecache_single.c7
-rw-r--r--storage/maria/unittest/ma_test_loghandler_multigroup-t.c6
-rw-r--r--storage/maria/unittest/ma_test_loghandler_nologs-t.c2
-rw-r--r--storage/maria/unittest/ma_test_loghandler_purge-t.c2
-rw-r--r--storage/maria/unittest/test_file.c2
-rw-r--r--storage/mroonga/CMakeLists.txt154
-rw-r--r--storage/mroonga/Makefile.am48
-rw-r--r--storage/mroonga/appveyor.yml69
-rwxr-xr-xstorage/mroonga/autogen.sh115
-rw-r--r--storage/mroonga/build/makefiles/sphinx-build.am2
-rw-r--r--storage/mroonga/config.sh.in2
-rw-r--r--storage/mroonga/configure.ac38
-rw-r--r--storage/mroonga/data/install.sql.in16
-rw-r--r--storage/mroonga/data/uninstall.sql4
-rw-r--r--storage/mroonga/ha_mroonga.cpp2914
-rw-r--r--storage/mroonga/ha_mroonga.def3
-rw-r--r--storage/mroonga/ha_mroonga.hpp183
-rw-r--r--storage/mroonga/lib/libmrn_need_mysql_sources.am21
-rw-r--r--storage/mroonga/lib/mrn_column_name.cpp69
-rw-r--r--storage/mroonga/lib/mrn_column_name.hpp39
-rw-r--r--storage/mroonga/lib/mrn_condition_converter.cpp53
-rw-r--r--storage/mroonga/lib/mrn_condition_converter.hpp2
-rw-r--r--storage/mroonga/lib/mrn_context_pool.cpp120
-rw-r--r--storage/mroonga/lib/mrn_context_pool.hpp41
-rw-r--r--storage/mroonga/lib/mrn_count_skip_checker.cpp303
-rw-r--r--storage/mroonga/lib/mrn_count_skip_checker.hpp57
-rw-r--r--storage/mroonga/lib/mrn_current_thread.hpp27
-rw-r--r--storage/mroonga/lib/mrn_database.cpp89
-rw-r--r--storage/mroonga/lib/mrn_database.hpp47
-rw-r--r--storage/mroonga/lib/mrn_database_manager.cpp76
-rw-r--r--storage/mroonga/lib/mrn_database_manager.hpp5
-rw-r--r--storage/mroonga/lib/mrn_database_repairer.cpp120
-rw-r--r--storage/mroonga/lib/mrn_database_repairer.hpp17
-rw-r--r--storage/mroonga/lib/mrn_index_table_name.cpp28
-rw-r--r--storage/mroonga/lib/mrn_index_table_name.hpp7
-rw-r--r--storage/mroonga/lib/mrn_multiple_column_key_codec.cpp9
-rw-r--r--storage/mroonga/lib/mrn_multiple_column_key_codec.hpp4
-rw-r--r--storage/mroonga/lib/mrn_operation.cpp51
-rw-r--r--storage/mroonga/lib/mrn_operation.hpp42
-rw-r--r--storage/mroonga/lib/mrn_operations.cpp401
-rw-r--r--storage/mroonga/lib/mrn_operations.hpp60
-rw-r--r--storage/mroonga/lib/mrn_path_mapper.cpp4
-rw-r--r--storage/mroonga/lib/mrn_path_mapper.hpp2
-rw-r--r--storage/mroonga/lib/mrn_query_parser.cpp361
-rw-r--r--storage/mroonga/lib/mrn_query_parser.hpp67
-rw-r--r--storage/mroonga/lib/mrn_smart_bitmap.cpp42
-rw-r--r--storage/mroonga/lib/mrn_smart_bitmap.hpp36
-rw-r--r--storage/mroonga/lib/mrn_table_fields_offset_mover.cpp41
-rw-r--r--storage/mroonga/lib/mrn_table_fields_offset_mover.hpp33
-rw-r--r--storage/mroonga/mrn_err.h3
-rw-r--r--storage/mroonga/mrn_mysql.h19
-rw-r--r--storage/mroonga/mrn_mysql_compat.h258
-rw-r--r--storage/mroonga/mrn_table.cpp70
-rw-r--r--storage/mroonga/mrn_variables.hpp24
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_64bit.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/have_64bit.inc)9
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_freebsd.inc5
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_ha_mroonga_so.inc2
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc2
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_lz4.inc2
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zlib.inc2
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zstd.inc20
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_mariadb.inc2
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_osx.inc16
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_solaris.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_56_or_later.inc)13
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_strict_sql_mode.inc21
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_version.inc23
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_windows.inc2
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_32bit.inc28
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_fractional_seconds.inc6
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_freebsd.inc6
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc4
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb.inc4
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb_10_2_or_later.inc26
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc2
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga_deinit.inc2
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga_helper.inc4
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_mysql.inc4
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_mysql_5_7_or_later.inc26
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_signed_64bit_time_t.inc28
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_solaris.inc21
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_strict_sql_mode.inc21
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0.inc21
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0_or_later.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_100_or_later.inc)8
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_5.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_56.inc)8
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_6.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_55.inc)6
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_6_or_later.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_100.inc)6
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_7.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_57.inc)6
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_7_or_later.inc21
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/load_mroonga_functions.inc8
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/print_groonga_query_log.inc8
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_freebsd.inc6
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_0_or_later.inc24
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_1.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_55.inc)8
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_1_or_earlier.inc24
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_2_or_later.inc24
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_5_5.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_100_or_later.inc)8
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_5_5.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_55.inc)8
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_5_7.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_57.inc)6
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_5_7_or_later.inc24
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_osx.inc4
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_signed_64bit_time_t.inc28
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_solaris.inc21
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_solaris10.inc3
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/skip_strict_sql_mode.inc21
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_lz4.inc4
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zlib.inc4
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zstd.inc22
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/unload_mroonga_functions.inc8
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_lz4.inc4
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zlib.inc4
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zstd.inc22
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_after.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_first.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_comment.result5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multibyte_cp932.result35
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multibyte_utf8.result35
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multiple.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_plain.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_type_comment.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_after.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_first.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_multiple.result24
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_no_order.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_engine_decimal.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/alter_table_engine_decimal.result)25
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_engine_fulltext_index.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_engine.result)30
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result23
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_disable_keys_fulltext_table.result22
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_drop_column_multiple.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_drop_column_one.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_enable_keys_fulltext_table.result22
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_fulltext_add_normal.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_after.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_first.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_no_order.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_recreate_anonymous_index_at_once.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_rename_table.result30
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_spatial.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/check_table_broken.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/check_table_not_broken.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_date_with_index.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_date_without_index.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_2038.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_before_unix_epoch.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_max.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_out_of_range.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_2038.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_before_unix_epoch.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_max.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_strict_sql_mode_out_of_range.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_5_5_out_of_range.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_55_out_of_range.result)8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_5_6_or_later_out_of_range.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_56_or_later_out_of_range.result)12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_with_index.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_without_index.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_freebsd_before_unix_epoch.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mariadb_10_2_or_later_zero_date.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date_strict.result)9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mariadb_10_2_or_later_zero_month_day.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mysql_5_7_or_later_zero_date.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mysql_5_7_or_later_zero_month_day.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_null.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_with_index.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_without_index.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date.result27
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_month_day.result20
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_fractional_seconds_with_index.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_fractional_seconds_without_index.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_with_index.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_without_index.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_add_column.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_delete.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_drop_column.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_insert.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_reindex.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_update.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_add_column.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_delete.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_drop_column.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_insert.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mariadb_10_2_or_later_add_index.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mariadb_10_2_or_later_create_table_with_index.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mysql_5_7_or_later_add_index.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_update.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_vector_other_table.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_int_other_table.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_zstd.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_zstd.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_vector_reference.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_json_insert.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_multibyte_cp932.result32
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_multibyte_utf8.result32
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_time_fractional_seconds_with_index.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_time_with_index.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_timestamp_fractional_seconds_with_index.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_timestamp_with_index.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_year_with_index.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_year_without_index.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/count_star.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_TODO_SPLIT_ME.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_flags_comment.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_comment.result)5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_flags_parameter.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_parameter.result)12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_groonga_type_comment.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_comment.result)11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_groonga_type_nonexistent.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_nonexistent.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_groonga_type_parameter.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_parameter.result)14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_type_comment.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_comment.result)11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_type_nonexistent.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_nonexistent.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_default_tokenizer.result5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_index_medium.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_index_small.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_with_position_and_with_weight.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_fulltext_index_bin.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_index_bin.result22
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_default.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_off.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_multiple_token_filters.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_one_token_filter.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_multiple_token_filters.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_one_token_filter.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/drop_database_no_table.result20
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_add.result24
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_drop.result23
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_create.result147
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_delete_existent.result53
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_delete_nonexistent.result53
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_insert_existent.result51
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_insert_nonexistent.result37
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_rename.result28
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_update_existent.result55
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_update_nonexistent.result53
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_escape.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_leading_not.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_syntax_script_operator.result20
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_syntax_script_selector.result25
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_error.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_error_and_log.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_ignore.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_ignore_and_log.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_charset_utf8mb4.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_found_rows.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_index_recreate.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_insert_values.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_delete.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_insert.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_recreate.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_update.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_index.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_no_primary_key.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_10_0_no_such_key.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_100_no_such_key.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_5_5_no_such_key.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_55_no_such_key.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_5_6_no_such_key.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_56_no_such_key.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_command_auto-escape.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_command_special-database-name.result22
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_error_query_is_not_string.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_all.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/function_escape_success_all.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_custom.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/function_escape_success_custom.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_join.result26
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_match_against.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_named.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_nested.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/function_escape_success_nested.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_decimal.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_integer.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_real.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_string.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_dynamic_keyword.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_japanese.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_multiple_keywords.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_normalizer.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_query.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_query_pragma.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_record.result32
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_default.result3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_normalizer.result3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_record.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_multiple.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_no_index.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_one.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_pragma.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_dynamic_keyword.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_japanese.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_multiple_keywords.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_multiple_snippets.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_query.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_query_pragma.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_record.result30
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/geometry_contains.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/geometry_strict_sql_mode_bulk_insert_null.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/geometry_bulk_insert_null_57.result)7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/geometry_strict_sql_mode_contains.result169
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_hash_id_primary.result22
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_hash_strict_sql_mode_id_primary.result19
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_order_by_where_equal_asc_asc.result40
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_order_by_where_equal_desc_desc.result40
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_primary_strict_sql_mode_update.result26
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_primary_update.result39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_greater_than.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_greater_than.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_greater_than_or_equal.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_greater_than_or_equal.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_less_than.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_less_than.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_less_than_or_equal.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_less_than_or_equal.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_greater_than.result34
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_greater_than_or_equal.result35
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_less_than.result34
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_less_than_or_equal.result35
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_greater_than.result29
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_greater_than_or_equal.result30
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_less_than.result30
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_less_than_or_equal.result31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_select_max.result20
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_select_min.result20
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_64bit_equal.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_index_read.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_order_64bit_asc.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_order_64bit_desc.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_index_read.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_order_asc.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_order_desc.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_index_read.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_order_asc.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_order_desc.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_reinsert.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_primary_date.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_primary_datetime_with_fractional_seconds.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_primary_datetime_without_fractional_seconds.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_primary_decimal_with_fractional_seconds.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_primary_decimal_without_fractional_seconds.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_primary_time_with_fractional_seconds.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_primary_time_without_fractional_seconds.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_primary_timestamp_with_fractional_seconds.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_primary_timestamp_without_fractional_seconds.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_primary_year.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_unique_delete_all.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/information_schema_tables_data_length.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/insert_TODO_SPLIT_ME.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_primary_key.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_unique_key.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/insert_virtual_column.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_TODO_SPLIT_ME.result106
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_after_insert_multithread.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_disabled.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_and.result20
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_between.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_equal.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_full_text_search_in_boolean_mode.result19
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_full_text_search_in_natural_language_mode.result19
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_greater.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_greater_equal.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_less.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_less_equal.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_not_equal.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_multiple_conditions.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_between.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_equal.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_greater.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_greater_equal.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_less.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_less_equal.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_not_equal.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_disabled.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_multiple_match_againsts.result35
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_no_limit.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_cp932.result22
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_between.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_between_over.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_equal.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_greater_than.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_greater_than_or_equal.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_less_than.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_less_than_or_equal.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_enum_name.result25
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_enum_value.result25
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_have_primary_key.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_equal.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_greater_than.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_greater_than_or_equal.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_less_than.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_less_than_or_equal.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_no_primary_key.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_asc.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_desc.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_id.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_match_against.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_select_match_against.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_between.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_between_over.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_equal.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_greater_than.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_greater_than_or_equal.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_less_than.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_less_than_or_equal.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_varchar_equal_with_index.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_varchar_equal_without_index.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/repair_table_no_index_file.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/replace_text.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/replace_varchar.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/select_group_by_with_index.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/select_group_by_without_index.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/sub_query_fulltext.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/temporary_table.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/truncate.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/update_binlog_row.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/update_virtual_column.result27
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_default_tokenizer_new_value.result6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_default_tokenizer_same_value.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_delete.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_insert.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_update.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_enable_operations_recording_insert.result32
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_match_escalation_threshold_global.result29
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_match_escalation_threshold_session.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_global.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_global.result (renamed from storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_global.result)6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_not_found_in_limit.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_session.result22
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_not_found_in_limit.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_disabled_empty_value.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_disabled_null_value.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_enabled_empty_value.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_enabled_null_value.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_new_value.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_same_value.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_after.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_first.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_comment.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multibyte_cp932.test53
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multibyte_utf8.test53
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multiple.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_plain.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_type_comment.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_duplicated.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_multiple_column_duplicated.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_key_multiple_column_with_data.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_primary_key.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_comment_not_for_mroonga.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_have_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_after.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_first.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_multiple.test12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_no_order.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_engine_decimal.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/alter_table_engine_decimal.test)9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_engine_fulltext_index.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_engine.test)10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_create_fulltext.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_table.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_ujis.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_utf8.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_multiple_column.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_normal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_primary.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_truncate.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_updating.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_column_multiple.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_column_one.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_key_multiple_column_with_data.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_primary_key.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_table.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_ujis.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_utf8.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_multiple_column.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_normal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_primary.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_no_primary_key.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_normal.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_table.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_drop_table.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_after.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_first.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_no_order.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_recreate_anonymous_index_at_once.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_rename_table.test10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_spatial.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_TODO_SPLIT_ME.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_table_param.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_text.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/binlog_TODO_SPLIT_ME.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/check_table_broken.test45
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/check_table_not_broken.test38
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_general_ci_french.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_520_ci_french.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_520_ci_japanese.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_ci_french.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_ci_japanese.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_comment_index_not_for_mroonga.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_comment_normal_not_for_mroonga.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_date_with_index.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_date_without_index.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_date_zero_date.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_2038.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_before_unix_epoch.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_max.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_out_of_range.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_2038.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_before_unix_epoch.test9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_max.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_strict_sql_mode_out_of_range.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_56_or_later_out_of_range.test)13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_5_5_out_of_range.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_55_out_of_range.test)7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_5_6_or_later_out_of_range.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_fractional_seconds_with_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_fractional_seconds_without_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_freebsd_before_unix_epoch.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mariadb_10_2_or_later_zero_date.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date_strict.test)8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mariadb_10_2_or_later_zero_month_day.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mysql_5_7_or_later_zero_date.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mysql_5_7_or_later_zero_month_day.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_null.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_with_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_without_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date.test18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_month_day.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_fractional_seconds_with_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_fractional_seconds_without_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_with_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_without_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_enum_less_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_enum_many_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_add_column.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_delete.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_drop_column.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_insert.test40
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_reindex.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_update.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_add_column.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_delete.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_drop_column.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_insert.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mariadb_10_2_or_later_add_index.test35
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mariadb_10_2_or_later_create_table_with_index.test32
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mysql_5_7_or_later_add_index.test35
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_update.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga__id__id.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga__id_invalid_id.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_other_table.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_vector_other_table.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_int_other_table.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_reference.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_lz4.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zlib.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zstd.test37
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_lz4.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zlib.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zstd.test37
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_with_not_for_mroonga_comment.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_vector_order_by_with_function.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_vector_reference.test7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_int_with_index_zero_value.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_json_insert.test37
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_multibyte_cp932.test51
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_multibyte_utf8.test51
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_set_16_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_set_24_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_set_32_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_set_64_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_set_8_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_signed_bigint_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_signed_int_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_signed_mediumint_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_signed_smallint_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_signed_tinyint_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_time_fractional_seconds_with_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_time_with_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_timestamp_fractional_seconds_with_index.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_timestamp_with_index.test9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_tinyint_without_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_bigint_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_bigint_without_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_int_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_mediumint_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_smallint_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_tinyint_with_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_year_with_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_year_without_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/count_star.test35
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_database_name_slash.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_TODO_SPLIT_ME.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_flags_comment.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_comment.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_flags_parameter.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_parameter.test)3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_groonga_type_comment.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_comment.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_groonga_type_nonexistent.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_nonexistent.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_groonga_type_parameter.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_parameter.test)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_type_comment.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_comment.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_type_nonexistent.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_nonexistent.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_comment_normal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_default_tokenizer.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_index_medium.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_index_small.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_with_position_and_with_weight.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_comment.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_fulltext_index_bin.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_index_bin.test37
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_none.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_default.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_off.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_multiple_token_filters.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_one_token_filter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_default.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_hash.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_multiple_token_filters.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_one_token_filter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_stop_word.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/delete_fulltext_column.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/delete_index_btree_many_records.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/delete_index_hash_id_no_unique.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/delete_index_hash_id_unique.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/delete_normal_column.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/delete_unsigned_bigint.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/drop_database_TODO_SPLIT_ME.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/drop_database_no_table.test57
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/drop_table_TODO_SPLIT_ME.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/flush_logs.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_alter_add.test47
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_alter_drop.test48
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_create.test97
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_delete_existent.test53
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_delete_nonexistent.test53
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_insert_existent.test51
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_insert_nonexistent.test51
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_rename.test51
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_update_existent.test53
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_update_nonexistent.test53
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_empty_query.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_escape.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_leading_not.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_all.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_no_operator.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_with_or.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_with_plus.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_no_operator.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_minus.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_or.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_syntax_script_operator.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_syntax_script_selector.test50
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_full_spec.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_no_weight.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_omit_section.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_ten_or_more_sections.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_three_or_more_sections.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_error.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_error_and_log.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_ignore.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_ignore_and_log.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_ascii.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_cp932.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_eucjpms.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_japanese.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_utf8mb4.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_empty_query.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_found_rows.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_groonga_varchar_vector.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_index_recreate.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_insert_select.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_insert_values.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_delete.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_insert.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_recreate.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_update.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_no_primary_key.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_or.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_different_against.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_different_match.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_no_where.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_same_match_against.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_asc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_desc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_different_against.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_different_match.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_no_where.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_same_match_against.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_two_inner_join.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_10_0_no_such_key.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_56_no_such_key.test)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_5_5_no_such_key.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_55_no_such_key.test)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_5_6_no_such_key.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_100_no_such_key.test)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_command_auto-escape.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_command_select.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_command_special-database-name.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_query_is_missing.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_query_is_not_string.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_target_characters_is_not_string.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_all.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/function_escape_success_all.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_custom.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/function_escape_success_custom.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_join.test54
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_match_against.test46
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_named.test26
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_nested.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/function_escape_success_nested.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_decimal.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_integer.test26
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_real.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_string.test26
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_dynamic_keyword.test45
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_japanese.test31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_multiple_keywords.test25
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_normalizer.test25
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_query.test31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_query_pragma.test31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_record.test55
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_grn_id.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_id_reference.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_id_set.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_default.test24
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_normalizer.test24
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_record.test40
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_multiple.test46
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_no_index.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_one.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_pragma.test45
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_ascii.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_cp932.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_eucjpms.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_dynamic_keyword.test45
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_japanese.test31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_multiple_keywords.test25
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_multiple_snippets.test29
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_query.test31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_query_pragma.test31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_record.test55
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_invalid_nonexistent_charset.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_invalid_unsupported_charset.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_japanese.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/geometry_bulk_insert_null.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/geometry_contains.test13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/geometry_strict_sql_mode_bulk_insert_null.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/geometry_bulk_insert_null_57.test)9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/geometry_strict_sql_mode_contains.test152
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_datetime.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_time.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_timestamp.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_btree_normal_column_insert.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_normal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_primary.test29
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_unique.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_hash_normal_column_insert.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_hash_strict_sql_mode_id_primary.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_delete.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_smallint.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_bigint.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_int.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_smallint.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_varchar.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_order_by_where_equal_asc_asc.test49
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_order_by_where_equal_desc_desc.test49
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_delete.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_select_int.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_strict_sql_mode_update.test47
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_update.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_greater_than.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_greater_than.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_greater_than_or_equal.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_greater_than_or_equal.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_less_than.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_less_than.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_less_than_or_equal.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_less_than_or_equal.test)2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_greater_than.test50
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_greater_than_or_equal.test50
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_less_than.test50
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_less_than_or_equal.test50
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_greater_than.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_greater_than_or_equal.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_less_than.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_less_than_or_equal.test45
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_recreate.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_replace.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_double.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_float.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_int.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_max.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_min.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_string.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_varchar.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_32bit_equal.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_64bit_equal.test14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_index_read.test11
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_32bit_asc.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_32bit_desc.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_64bit_asc.test12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_64bit_desc.test12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_reinsert.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_index_read.test12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_order_asc.test12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_order_desc.test12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_reinsert.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_decimal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_index_read.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_order_asc.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_order_desc.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_reinsert.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_index_read.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_order_asc.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_order_desc.test10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_reinsert.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_varchar.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_32bit_equal.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_64bit_equal.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_index_read.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_32bit_asc.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_32bit_desc.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_64bit_asc.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_64bit_desc.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_reinsert.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_update_int.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_update_string.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_exact_length.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_null_character.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_short.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_date.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_datetime_with_fractional_seconds.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_datetime_without_fractional_seconds.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_decimal_with_fractional_seconds.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_decimal_without_fractional_seconds.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_time_with_fractional_seconds.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_time_without_fractional_seconds.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_timestamp_with_fractional_seconds.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_timestamp_without_fractional_seconds.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_varchar_null_character.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_primary_year.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_asc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_desc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_or_equal_asc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_or_equal_desc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_asc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_desc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_or_equal_asc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_or_equal_desc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_asc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_desc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_or_equal_asc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_or_equal_desc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_asc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_desc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_or_equal_asc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_or_equal_desc.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_bigint.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_bigint_unsigned.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_double.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_float.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_int.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_int_unsigned.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_mediumint.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_mediumint_unsigned.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_smallint.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_smallint_unsigned.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_tinyint.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_tinyint_unsigned.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_varchar.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_varchar_collation.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_normal_int.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_normal_varchar.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_primary_int.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_read_primary_varchar.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_unique_delete_all.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_unique_delete_by_primary_key.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_unique_insert_after_error.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_unique_search_after_duplicated.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_unique_varchar.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_update_multiple_column.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_update_single_column.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/information_schema_plugins.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_auto_increment_none.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_auto_increment_use.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_data_length.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/insert_TODO_SPLIT_ME.test18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/insert_delayed.test7
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_no_primary_key_and_unique_key_twice.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_primary_key.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_unique_key.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/insert_virtual_column.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/like_unicode_ci.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/lock_tables_read.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_TODO_SPLIT_ME.test61
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_after_insert_multithread.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_after_insert_single_thread.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_disabled.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_and.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_between.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_equal.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_full_text_search_in_boolean_mode.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_full_text_search_in_natural_language_mode.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_greater.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_greater_equal.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_less.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_less_equal.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_not_equal.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_view.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_multiple_conditions.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_between.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_equal.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_greater.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_greater_equal.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_less.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_less_equal.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_not_equal.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_disabled.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_multiple_match_againsts.test57
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_no_limit.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_cp932.test46
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_between.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_between_over.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_equal.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_greater_than.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_greater_than_or_equal.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_less_than.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_less_than_or_equal.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_duplicated_order_by_columns.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_enum_name.test49
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_enum_value.test49
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_have_primary_key.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_between.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_between_over.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_equal.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_greater_than.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_greater_than_or_equal.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_less_than.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_less_than_or_equal.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_no_primary_key.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_no_where_clause.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_asc.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_desc.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_id.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_match_against.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_select_match_against.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_between.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_between_over.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_equal.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_greater_than.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_greater_than_or_equal.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_less_than.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_less_than_or_equal.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_varchar_equal_with_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_varchar_equal_without_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_between.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_between_over.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_equal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_greater_than.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_greater_than_or_equal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_less_than.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_less_than_or_equal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/partition_insert.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/partition_update.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/repair_table_no_index_file.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/replace_geometry.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/replace_text.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/replace_varchar.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/replace_vector.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/select_all.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/select_empty_key_where_equal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/select_empty_key_where_not_equal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/select_group_by_with_index.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/select_group_by_without_index.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/select_pkey.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/select_secondary_key.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/show_create_table_TODO_SPLIT_ME.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/sub_query_fulltext.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/temporary_table.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/truncate.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/update_binlog_row.test38
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/update_fulltext.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/update_id_hash_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/update_id_unique_hash_index.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/update_int.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/update_last_insert_grn_id.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/update_virtual_column.test34
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_column.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_leading_not.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_update.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_query.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_script.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_database_path_prefix.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_default_parser_new_value.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_default_parser_same_value.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_default_tokenizer_new_value.test25
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_default_tokenizer_same_value.test22
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_delete.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_insert.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_update.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_enable_operations_recording_insert.test50
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_disable.test12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_invalid.test12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_no_retry.test10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_valid.test10
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_new_value.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_nonexistent_path.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_same_value.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_log_level_TODO_SPLIT_ME.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test29
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_global.test9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_global.test60
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_not_found_in_limit.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_session.test47
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_not_found_in_limit.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_session.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_disabled_empty_value.test31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_disabled_null_value.test31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_enabled_empty_value.test33
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_enabled_null_value.test33
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_new_value.test33
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_same_value.test34
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_vector_column_delimiter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_version.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column_multibyte_cp932.result33
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column_multibyte_utf8.result33
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_change_engine.result30
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_comment_change_engine.result23
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_drop_column.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_fulltext.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_rename_table.result20
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/check_table_for_upgrade.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_add_column.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_delete.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_drop_column.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_insert.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_reindex.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_update.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_column.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_fulltext_index.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_index.result19
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_delete.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_drop_column.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_insert.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_update.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_multibyte_cp932.result32
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/column_multibyte_utf8.result32
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/count_star.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/count_star_mysql_5_7_or_later_with_index.result30
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/count_star_with_index.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_TODO_SPLIT_ME.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_comment_combined.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_index_flags_none.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_index_flags_with_position_and_with_weight.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index_bin.result21
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_parser_comment.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_multiple_token_filters.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_one_token_filter.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/drop_table_new_connection.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_leading_not.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_multiple_match_against.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_index_recreate.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result6
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_values.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_delete.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_insert.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_recreate.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_update.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_index.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result12
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_transaction.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_contains.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_delete.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_update.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/insert_bulk.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/insert_on_duplicate_key_update_multiple_column_primary_key_myisam.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/insert_on_duplicate_key_update_multiple_column_unique_index_myisam.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/multi_range_read_mysql_5_7_or_later_disk_sweep.result20
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/repair_table_no_files.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/repair_table_no_index_file.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/temporary_table.result7
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_query_cache.result5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_delete.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_update.result10
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_delete.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_insert.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_update.result8
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/variable_match_escalation_threshold_global.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/variable_match_escalation_threshold_session.result11
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column_multibyte_cp932.test54
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column_multibyte_utf8.test54
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_change_column_comment.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_change_engine.test10
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_comment_change_engine.test7
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_create_fulltext.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_fulltext.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_multiple_column.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_normal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_primary.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_updating.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_drop_column.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_fulltext.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_lock_tables.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_multiple_column.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_normal.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_primary.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_fulltext.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_rename_table.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test6
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/auto_increment_text.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/binlog_TODO_SPLIT_ME.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/check_table_for_upgrade.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_comment_index_not_for_mroonga.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_add_column.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_delete.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_drop_column.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_insert.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_reindex.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_update.test43
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_column.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_fulltext_index.test46
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_index.test47
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_delete.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_drop_column.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_insert.test40
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_update.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_multibyte_cp932.test53
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_multibyte_utf8.test53
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/column_normal_comment.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/count_star.test36
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_mysql_5_7_or_later_with_index.test55
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test7
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_TODO_SPLIT_ME.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_comment_combined.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_index_flags_none.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_index_flags_with_position_and_with_weight.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_fulltext_index_bin.test40
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_parser_comment.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_multiple_token_filters.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_one_token_filter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_comment.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_parameter.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/delete_TODO_SPLIT_ME.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/delete_all.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/drop_table_new_connection.test46
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_leading_not.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_multiple_match_against.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_no_operator.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_with_or.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_with_plus.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_no_operator.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_with_minus.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_with_or.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_full_spec.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_no_weight.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_omit_section.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_ascii.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_cp932.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_eucjpms.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_japanese.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_index_recreate.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test8
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_values.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test19
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_delete.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_insert.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_recreate.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_update.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_index.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_transaction.test13
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/function_last_insert_id_reference.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/function_last_insert_id_set.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_contains.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_delete.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_update.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/index_force_index_not_used.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/insert_TODO_SPLIT_ME.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/insert_bulk.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/insert_on_duplicate_key_update_multiple_column_primary_key_myisam.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/insert_on_duplicate_key_update_multiple_column_unique_index_myisam.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/multi_range_read_disk_sweep.test7
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/multi_range_read_mysql_5_7_or_later_disk_sweep.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_TODO_SPLIT_ME.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_no_direction.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_no_where_clause.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_order_by_primary_key.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/performance_schema.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_files.test12
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_index_file.test11
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/temporary_table.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_query_cache.test12
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_rollback_delete_delete.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_rollback_delete_update.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/update_fulltext.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/update_int.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_delete.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_insert.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_update.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test11
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test5
-rw-r--r--storage/mroonga/packages/apt/Makefile.am50
-rw-r--r--storage/mroonga/packages/apt/Vagrantfile35
-rwxr-xr-xstorage/mroonga/packages/apt/build-deb.sh46
-rw-r--r--storage/mroonga/packages/apt/env.sh.in5
-rwxr-xr-xstorage/mroonga/packages/apt/sign-packages.sh2
-rwxr-xr-xstorage/mroonga/packages/apt/sign-repository.sh2
-rwxr-xr-xstorage/mroonga/packages/apt/update-repository.sh2
-rwxr-xr-xstorage/mroonga/packages/check-utility.sh665
-rw-r--r--storage/mroonga/packages/debian/apparmor/mysql-server-mroonga5
-rw-r--r--storage/mroonga/packages/debian/changelog415
-rw-r--r--storage/mroonga/packages/debian/compat1
-rw-r--r--storage/mroonga/packages/debian/control.in51
-rw-r--r--storage/mroonga/packages/debian/copyright27
-rw-r--r--storage/mroonga/packages/debian/mysql-server-mroonga-doc.install1
-rw-r--r--storage/mroonga/packages/debian/mysql-server-mroonga.install3
-rwxr-xr-xstorage/mroonga/packages/debian/mysql-server-mroonga.postinst72
-rwxr-xr-xstorage/mroonga/packages/debian/mysql-server-mroonga.postrm38
-rwxr-xr-xstorage/mroonga/packages/debian/mysql-server-mroonga.prerm10
-rwxr-xr-xstorage/mroonga/packages/debian/rules39
-rw-r--r--storage/mroonga/packages/rpm/centos/Makefile.am14
-rw-r--r--storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in116
-rw-r--r--storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in131
-rw-r--r--storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in153
-rw-r--r--storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in137
-rw-r--r--storage/mroonga/packages/source/Makefile.am12
-rw-r--r--storage/mroonga/packages/ubuntu/Makefile.am41
-rwxr-xr-xstorage/mroonga/packages/ubuntu/upload.rb135
-rw-r--r--storage/mroonga/packages/windows/Makefile.am12
-rw-r--r--storage/mroonga/packages/windows/README.md12
-rw-r--r--storage/mroonga/packages/windows/build-vc2013-msi-32.bat8
-rw-r--r--storage/mroonga/packages/windows/build-vc2013-msi-64.bat8
-rw-r--r--storage/mroonga/packages/windows/build-vc2013-zip-32.bat8
-rw-r--r--storage/mroonga/packages/windows/build-vc2013-zip-64.bat8
-rw-r--r--storage/mroonga/packages/windows/build-vc2013.bat4
-rw-r--r--storage/mroonga/packages/windows/build-vc2015-msi-32.bat2
-rw-r--r--storage/mroonga/packages/windows/build-vc2015-msi-64.bat2
-rw-r--r--storage/mroonga/packages/windows/build-vc2015-zip-32.bat7
-rw-r--r--storage/mroonga/packages/windows/build-vc2015-zip-64.bat7
-rw-r--r--storage/mroonga/packages/windows/build-vc2015.bat4
-rw-r--r--storage/mroonga/packages/yum/Makefile.am17
-rw-r--r--storage/mroonga/packages/yum/Vagrantfile18
-rwxr-xr-xstorage/mroonga/packages/yum/build-in-vm.sh28
-rwxr-xr-xstorage/mroonga/packages/yum/build-rpm.sh93
-rw-r--r--storage/mroonga/packages/yum/env.sh.in4
-rwxr-xr-xstorage/mroonga/packages/yum/update-repository.sh4
-rw-r--r--storage/mroonga/plugin_version2
-rw-r--r--storage/mroonga/required_groonga_version2
-rwxr-xr-xstorage/mroonga/test/run-sql-test.sh278
-rw-r--r--storage/mroonga/test/unit/test_mrn_path_mapper.cpp2
-rwxr-xr-xstorage/mroonga/tools/prepare-sphinx-html.rb8
-rwxr-xr-xstorage/mroonga/tools/travis/before_script.sh52
-rwxr-xr-xstorage/mroonga/tools/travis/install.sh131
-rwxr-xr-xstorage/mroonga/tools/travis/script.sh24
-rw-r--r--storage/mroonga/udf/mrn_udf_command.cpp194
-rw-r--r--storage/mroonga/udf/mrn_udf_escape.cpp196
-rw-r--r--storage/mroonga/udf/mrn_udf_highlight_html.cpp494
-rw-r--r--storage/mroonga/udf/mrn_udf_last_insert_grn_id.cpp11
-rw-r--r--storage/mroonga/udf/mrn_udf_normalize.cpp212
-rw-r--r--storage/mroonga/udf/mrn_udf_query_expand.cpp282
-rw-r--r--storage/mroonga/udf/mrn_udf_snippet.cpp77
-rw-r--r--storage/mroonga/udf/mrn_udf_snippet_html.cpp444
-rw-r--r--storage/mroonga/udf/sources.am6
-rw-r--r--storage/mroonga/vendor/groonga/CMakeLists.txt219
-rw-r--r--storage/mroonga/vendor/groonga/Makefile.am21
-rw-r--r--storage/mroonga/vendor/groonga/README.md13
-rw-r--r--storage/mroonga/vendor/groonga/appveyor.yml75
-rwxr-xr-xstorage/mroonga/vendor/groonga/autogen.sh19
-rw-r--r--storage/mroonga/vendor/groonga/base_version2
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/Makefile.am83
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c276
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-cache.c155
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c12
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c13
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c13
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c275
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c12
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-range-select.c12
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-result-set.c151
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c13
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am3
-rw-r--r--storage/mroonga/vendor/groonga/build/ac_macros/check_functions.m42
-rw-r--r--storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m44
-rw-r--r--storage/mroonga/vendor/groonga/build/makefiles/gettext.am2
-rw-r--r--storage/mroonga/vendor/groonga/build/makefiles/sphinx-build.am13
-rw-r--r--storage/mroonga/vendor/groonga/build/makefiles/sphinx.am107
-rw-r--r--storage/mroonga/vendor/groonga/bundled_lz4_version1
-rw-r--r--storage/mroonga/vendor/groonga/bundled_mecab_naist_jdic_version1
-rw-r--r--storage/mroonga/vendor/groonga/bundled_mecab_version1
-rw-r--r--storage/mroonga/vendor/groonga/bundled_message_pack_version1
-rw-r--r--storage/mroonga/vendor/groonga/config.h.cmake12
-rw-r--r--storage/mroonga/vendor/groonga/configure.ac338
-rwxr-xr-xstorage/mroonga/vendor/groonga/examples/dictionary/edict/edict-import.sh8
-rw-r--r--storage/mroonga/vendor/groonga/examples/dictionary/html/index.html2
-rw-r--r--storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-ui-1.8.18.custom.min.js356
-rw-r--r--storage/mroonga/vendor/groonga/groonga-arrow.pc.in4
-rw-r--r--storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in6
-rw-r--r--storage/mroonga/vendor/groonga/include/Makefile.am4
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga.h39
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga.hpp21
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/Makefile.am27
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/accessor.h34
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/array.h89
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/arrow.h38
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/arrow.hpp21
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/cache.h49
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/column.h29
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/command.h8
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/config.h65
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/dat.h100
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/db.h68
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/dump.h34
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/error.h29
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/expr.h47
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/file_reader.h37
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/geo.h36
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/groonga.h703
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/hash.h104
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/id.h31
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/ii.h42
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/nfkc.h11
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/normalizer.h8
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/obj.h54
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/operator.h49
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/output.h30
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/pat.h102
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/plugin.h83
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/portability.h59
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/request_canceler.h8
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/request_timer.h53
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/scorer.h14
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/table.h246
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/thread.h39
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/time.h61
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/token.h11
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/token_filter.h8
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/tokenizer.h8
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/type.h40
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/util.h14
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/window_function.h73
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/windows.h31
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/windows_event_logger.h30
-rw-r--r--storage/mroonga/vendor/groonga/lib/CMakeLists.txt81
-rw-r--r--storage/mroonga/vendor/groonga/lib/Makefile.am44
-rw-r--r--storage/mroonga/vendor/groonga/lib/alloc.c961
-rw-r--r--storage/mroonga/vendor/groonga/lib/arrow.cpp849
-rw-r--r--storage/mroonga/vendor/groonga/lib/c_sources.am (renamed from storage/mroonga/vendor/groonga/lib/sources.am)51
-rw-r--r--storage/mroonga/vendor/groonga/lib/cache.c1036
-rw-r--r--storage/mroonga/vendor/groonga/lib/column.c49
-rw-r--r--storage/mroonga/vendor/groonga/lib/com.c49
-rw-r--r--storage/mroonga/vendor/groonga/lib/command.c3
-rw-r--r--storage/mroonga/vendor/groonga/lib/config.c289
-rw-r--r--storage/mroonga/vendor/groonga/lib/cpp_sources.am3
-rw-r--r--storage/mroonga/vendor/groonga/lib/ctx.c1893
-rw-r--r--storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c138
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat.cpp267
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/array.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/base.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/block.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/check.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp1
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/cursor-factory.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/cursor.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/dat.hpp9
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/entry.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp21
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/header.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/id-cursor.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/key-cursor.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/key.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/node.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/string.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/trie.cpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/trie.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/vector.hpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/db.c5509
-rw-r--r--storage/mroonga/vendor/groonga/lib/dump.c112
-rw-r--r--storage/mroonga/vendor/groonga/lib/egn.cpp3245
-rw-r--r--storage/mroonga/vendor/groonga/lib/error.c412
-rw-r--r--storage/mroonga/vendor/groonga/lib/expr.c3726
-rw-r--r--storage/mroonga/vendor/groonga/lib/expr_code.c24
-rw-r--r--storage/mroonga/vendor/groonga/lib/expr_executor.c945
-rw-r--r--storage/mroonga/vendor/groonga/lib/file_lock.c121
-rw-r--r--storage/mroonga/vendor/groonga/lib/file_reader.c109
-rw-r--r--storage/mroonga/vendor/groonga/lib/geo.c136
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn.h141
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_alloc.h163
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_cache.h49
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_com.h14
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_config.h37
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ctx.h312
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h90
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h8
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_dat.h25
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_db.h224
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ecmascript.c2759
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ecmascript.h137
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon212
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_egn.h90
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_egn.hpp318
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_error.h12
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_expr.h17
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_expr_code.h8
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_expr_executor.h39
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_file_lock.h48
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_geo.h15
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_hash.h30
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ii.h68
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_index_column.h34
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_io.h33
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_load.h47
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_logger.h8
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_mrb.h10
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_msgpack.h8
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_nfkc.h39
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_normalizer.h8
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_obj.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_output.h40
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_pat.h50
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_plugin.h9
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_proc.h129
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_raw_string.h62
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_report.h47
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_request_canceler.h7
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_request_timer.h28
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_rset.h9
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_scanner.h40
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_scorer.h8
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_scorers.h8
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_snip.h15
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_store.h79
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_str.h17
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_string.h26
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_time.h40
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_token_cursor.h14
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_tokenizers.h9
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ts.h48
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_util.h23
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_window_function.h40
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_window_functions.h26
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_windows.h33
-rw-r--r--storage/mroonga/vendor/groonga/lib/hash.c552
-rw-r--r--storage/mroonga/vendor/groonga/lib/icudump.c24
-rw-r--r--storage/mroonga/vendor/groonga/lib/id.c36
-rw-r--r--storage/mroonga/vendor/groonga/lib/ii.c6845
-rw-r--r--storage/mroonga/vendor/groonga/lib/index_column.c194
-rw-r--r--storage/mroonga/vendor/groonga/lib/io.c865
-rw-r--r--storage/mroonga/vendor/groonga/lib/libgroonga.c8
-rw-r--r--storage/mroonga/vendor/groonga/lib/load.c1229
-rw-r--r--storage/mroonga/vendor/groonga/lib/logger.c302
-rw-r--r--storage/mroonga/vendor/groonga/lib/metadata.rc.in28
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb.c129
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/Makefile.am3
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c28
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c10
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_array.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c144
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h7
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_cache.c130
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_cache.h33
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c84
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_column.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_command.c24
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_command.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_command_version.c41
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_command_version.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_config.c90
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_config.h31
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c69
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h14
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c130
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_database.c100
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_database.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_error.c8
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_error.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_eval_context.c98
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_eval_context.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c242
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h14
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c8
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_id.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c31
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c35
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_indexable.c170
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_indexable.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.c27
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c134
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c1
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c1
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_pointer.c77
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_pointer.h31
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.c40
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_query_logger.c76
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_query_logger.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_record.c162
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_record.h31
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c176
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c42
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c18
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h7
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.h7
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c4
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_thread.c46
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_thread.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_type.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_void.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_window_definition.c164
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_window_definition.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c21
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.h6
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am5
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/accessor.rb5
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb31
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command_input.rb15
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb433
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line_parser.rb168
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb33
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb24
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb64
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/eval_context.rb5
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb38
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_rewriter.rb22
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_rewriters.rb41
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb168
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree.rb9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/accessor.rb14
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/binary_operation.rb67
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/constant.rb22
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/function_call.rb66
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/index_column.rb14
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/logical_operation.rb33
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/options.rb14
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/procedure.rb18
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/sources.am10
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/variable.rb18
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree_builder.rb111
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/fixed_size_column.rb5
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/id.rb12
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb15
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/level.rb12
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb7
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger.rb9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/flag.rb39
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/record.rb38
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb17
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb3
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb350
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb77
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data_size_estimator.rb185
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am13
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb56
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb2
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/test/empty.rb1
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/variable_size_column.rb5
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/sources.am20
-rw-r--r--storage/mroonga/vendor/groonga/lib/nfkc.c80221
-rwxr-xr-xstorage/mroonga/vendor/groonga/lib/nfkc.rb989
-rw-r--r--storage/mroonga/vendor/groonga/lib/nfkc50.c77784
-rw-r--r--storage/mroonga/vendor/groonga/lib/normalizer.c8
-rw-r--r--storage/mroonga/vendor/groonga/lib/obj.c597
-rw-r--r--storage/mroonga/vendor/groonga/lib/operator.c600
-rw-r--r--storage/mroonga/vendor/groonga/lib/output.c1277
-rw-r--r--storage/mroonga/vendor/groonga/lib/pat.c1044
-rw-r--r--storage/mroonga/vendor/groonga/lib/plugin.c442
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc.c5313
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/Makefile.am17
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_column.c1019
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_config.c139
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_dump.c1138
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_fuzzy_search.c467
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_highlight.c503
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_in_records.c519
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_lock.c172
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_object.c138
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_object_inspect.c614
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_object_list.c413
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_query.c118
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_query_log_flags.c220
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_schema.c1226
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_select.c3808
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_snippet.c319
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_table.c910
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_tokenize.c433
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/sources.am18
-rw-r--r--storage/mroonga/vendor/groonga/lib/raw_string.c38
-rw-r--r--storage/mroonga/vendor/groonga/lib/report.c98
-rw-r--r--storage/mroonga/vendor/groonga/lib/request_canceler.c71
-rw-r--r--storage/mroonga/vendor/groonga/lib/request_timer.c88
-rw-r--r--storage/mroonga/vendor/groonga/lib/scanner.c73
-rw-r--r--storage/mroonga/vendor/groonga/lib/scorer.c14
-rw-r--r--storage/mroonga/vendor/groonga/lib/store.c1245
-rw-r--r--storage/mroonga/vendor/groonga/lib/str.c259
-rw-r--r--storage/mroonga/vendor/groonga/lib/string.c3
-rw-r--r--storage/mroonga/vendor/groonga/lib/table.c122
-rw-r--r--storage/mroonga/vendor/groonga/lib/thread.c59
-rw-r--r--storage/mroonga/vendor/groonga/lib/time.c245
-rw-r--r--storage/mroonga/vendor/groonga/lib/token_cursor.c51
-rw-r--r--storage/mroonga/vendor/groonga/lib/token_filter.c4
-rw-r--r--storage/mroonga/vendor/groonga/lib/tokenizer.c2
-rw-r--r--storage/mroonga/vendor/groonga/lib/tokenizers.c19
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts.c906
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/Makefile.am20
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/sources.am25
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_buf.c244
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_buf.h111
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_cursor.c163
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_cursor.h59
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_expr.c219
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_expr.h87
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_expr_builder.c757
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_expr_builder.h128
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.c5374
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.h128
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_expr_parser.c1329
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_expr_parser.h107
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_log.h46
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_op.c131
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_op.h87
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_plan.c21
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_plan.h87
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_sorter.c2174
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_sorter.h98
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_str.c191
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_str.h106
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_types.h168
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_util.c129
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_util.h61
-rw-r--r--storage/mroonga/vendor/groonga/lib/type.c87
-rw-r--r--storage/mroonga/vendor/groonga/lib/util.c404
-rw-r--r--storage/mroonga/vendor/groonga/lib/window_function.c464
-rw-r--r--storage/mroonga/vendor/groonga/lib/window_functions.c405
-rw-r--r--storage/mroonga/vendor/groonga/lib/windows.c104
-rw-r--r--storage/mroonga/vendor/groonga/lib/windows_event_logger.c203
-rw-r--r--storage/mroonga/vendor/groonga/nginx_version2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/CMakeLists.txt3
-rw-r--r--storage/mroonga/vendor/groonga/plugins/Makefile.am4
-rw-r--r--storage/mroonga/vendor/groonga/plugins/expression_rewriters/CMakeLists.txt (renamed from storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt)23
-rw-r--r--storage/mroonga/vendor/groonga/plugins/expression_rewriters/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/plugins/expression_rewriters/optimizer.rb147
-rw-r--r--storage/mroonga/vendor/groonga/plugins/expression_rewriters/sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt103
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/Makefile.am13
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/index_column.c266
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/index_column_sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/math.c142
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/math_sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/number.c187
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/number_sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/string.c299
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/string_sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/time.c376
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/time_sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/vector.c309
-rw-r--r--storage/mroonga/vendor/groonga/plugins/query_expanders/Makefile.am4
-rw-r--r--storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c55
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt50
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/Makefile.am26
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/eval.c68
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/eval.rb36
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/eval_sources.am3
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/load.c67
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/load_sources.am3
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/ruby_plugin.h76
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding.rb5
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/logical_count.rb53
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb79
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/logical_parameters.rb44
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/logical_range_filter.rb364
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb789
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/logical_shard_list.rb28
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb307
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/parameters.rb10
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/range_expression_builder.rb51
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/sources.am3
-rw-r--r--storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt3
-rw-r--r--storage/mroonga/vendor/groonga/plugins/suggest/suggest.c21
-rw-r--r--storage/mroonga/vendor/groonga/plugins/table/Makefile.am24
-rw-r--r--storage/mroonga/vendor/groonga/plugins/table/sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/table/table.c747
-rw-r--r--storage/mroonga/vendor/groonga/plugins/token_filters/stem.c14
-rw-r--r--storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt11
-rw-r--r--storage/mroonga/vendor/groonga/plugins/tokenizers/Makefile.am6
-rw-r--r--storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c120
-rwxr-xr-xstorage/mroonga/vendor/groonga/ra.rb12
-rw-r--r--storage/mroonga/vendor/groonga/src/CMakeLists.txt14
-rw-r--r--storage/mroonga/vendor/groonga/src/Makefile.am4
-rw-r--r--storage/mroonga/vendor/groonga/src/grndb.c64
-rw-r--r--storage/mroonga/vendor/groonga/src/groonga.c1067
-rw-r--r--storage/mroonga/vendor/groonga/src/groonga_benchmark.c62
-rw-r--r--storage/mroonga/vendor/groonga/src/httpd/Makefile.am2
-rw-r--r--storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c739
-rw-r--r--storage/mroonga/vendor/groonga/src/suggest/CMakeLists.txt3
-rw-r--r--storage/mroonga/vendor/groonga/src/suggest/Makefile.am3
-rw-r--r--storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_create_dataset.c21
-rw-r--r--storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_httpd.c4
-rw-r--r--storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_learner.c4
-rw-r--r--storage/mroonga/vendor/groonga/tools/Makefile.am1
-rwxr-xr-xstorage/mroonga/vendor/groonga/tools/check-small-index-limit.rb123
-rwxr-xr-xstorage/mroonga/vendor/groonga/tools/groonga-benchmark-indexing.rb129
-rwxr-xr-xstorage/mroonga/vendor/groonga/tools/groonga-memory-usage-analyzer.rb127
-rwxr-xr-xstorage/mroonga/vendor/groonga/tools/groonga-object-list-checker.rb104
-rwxr-xr-xstorage/mroonga/vendor/groonga/tools/travis-before-script.sh11
-rwxr-xr-xstorage/mroonga/vendor/groonga/tools/travis-install.sh15
-rwxr-xr-xstorage/mroonga/vendor/groonga/tools/travis-script.sh70
-rw-r--r--storage/mroonga/vendor/groonga/vendor/CMakeLists.txt5
-rw-r--r--storage/mroonga/vendor/groonga/vendor/Makefile.am12
-rwxr-xr-xstorage/mroonga/vendor/groonga/vendor/download_lz4.rb54
-rwxr-xr-xstorage/mroonga/vendor/groonga/vendor/download_mecab.rb59
-rwxr-xr-xstorage/mroonga/vendor/groonga/vendor/download_message_pack.rb54
-rw-r--r--storage/mroonga/vendor/groonga/vendor/lz4/CMakeLists.txt98
-rw-r--r--storage/mroonga/vendor/groonga/vendor/lz4/Makefile.am2
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mecab/CMakeLists.txt219
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mecab/Makefile.am4
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mecab/config.h.cmake1
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mecab/mecabrc.cmake3
-rw-r--r--storage/mroonga/vendor/groonga/vendor/message_pack/CMakeLists.txt53
-rw-r--r--storage/mroonga/vendor/groonga/vendor/message_pack/Makefile.am2
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt40
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am27
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb21
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am5
-rwxr-xr-xstorage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb10
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mruby/version1
-rw-r--r--storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt72
-rw-r--r--storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am2
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt8
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/configure.ac33
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md13
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/Makefile.am2
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/Vagrantfile12
-rwxr-xr-xstorage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/sign-packages.sh2
-rwxr-xr-xstorage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/sign-repository.sh2
-rwxr-xr-xstorage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/update-repository.sh2
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog6
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in3
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in3
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/ubuntu/Makefile.am2
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/yum/Makefile.am3
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/yum/Vagrantfile6
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version2
-rw-r--r--storage/mroonga/version2
-rw-r--r--storage/mroonga/version_in_hex2
-rw-r--r--storage/mroonga/version_major2
-rw-r--r--storage/mroonga/version_micro2
-rw-r--r--storage/myisam/ft_boolean_search.c8
-rw-r--r--storage/myisam/ft_myisam.c4
-rw-r--r--storage/myisam/ft_parser.c5
-rw-r--r--storage/myisam/ft_stopwords.c6
-rw-r--r--storage/myisam/ha_myisam.cc49
-rw-r--r--storage/myisam/mi_cache.c12
-rw-r--r--storage/myisam/mi_check.c8
-rw-r--r--storage/myisam/mi_dynrec.c7
-rw-r--r--storage/myisam/mi_key.c22
-rw-r--r--storage/myisam/mi_locking.c14
-rw-r--r--storage/myisam/mi_open.c6
-rw-r--r--storage/myisam/mi_packrec.c2
-rw-r--r--storage/myisam/mi_preload.c4
-rw-r--r--storage/myisam/mi_search.c14
-rw-r--r--storage/myisam/mi_test1.c10
-rw-r--r--storage/myisam/myisamchk.c2
-rw-r--r--storage/myisam/myisamdef.h6
-rw-r--r--storage/myisam/mysql-test/storage_engine/misc.rdiff17
-rw-r--r--storage/myisammrg/ha_myisammrg.cc52
-rw-r--r--storage/myisammrg/ha_myisammrg.h2
-rw-r--r--storage/myisammrg/myrg_open.c5
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/autoincrement.rdiff30
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/misc.rdiff17
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/truncate_table.rdiff24
-rw-r--r--storage/oqgraph/graphcore.cc80
-rw-r--r--storage/oqgraph/graphcore.h1
-rw-r--r--storage/oqgraph/ha_oqgraph.cc6
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/general-Aria.result164
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/general-MyISAM.result164
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/general-innodb.result164
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/general.inc94
-rw-r--r--storage/perfschema/pfs.cc21
-rw-r--r--storage/perfschema/pfs_digest.cc2
-rw-r--r--storage/perfschema/pfs_digest.h2
-rw-r--r--storage/perfschema/pfs_global.cc2
-rw-r--r--storage/perfschema/pfs_instr.cc2
-rw-r--r--storage/perfschema/pfs_instr_class.cc10
-rw-r--r--storage/perfschema/pfs_server.cc6
-rw-r--r--storage/perfschema/table_events_stages.cc2
-rw-r--r--storage/perfschema/table_events_statements.cc2
-rw-r--r--storage/perfschema/table_events_waits.cc4
-rw-r--r--storage/perfschema/table_host_cache.cc2
-rw-r--r--storage/perfschema/table_setup_consumers.cc2
-rw-r--r--storage/perfschema/table_setup_timers.cc2
-rw-r--r--storage/perfschema/table_threads.cc6
-rw-r--r--storage/perfschema/unittest/pfs-t.cc4
-rw-r--r--storage/rocksdb/CMakeLists.txt39
-rw-r--r--storage/rocksdb/build_rocksdb.cmake6
-rw-r--r--storage/rocksdb/ha_rocksdb.cc151
-rw-r--r--storage/rocksdb/ha_rocksdb.h3
-rwxr-xr-xstorage/rocksdb/myrocks_hotbackup686
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/2pc_group_commit.result30
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result9
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/bulk_load.result16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_cf.result16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_cf_and_data.result16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_data.result16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/bulk_load_unsorted.result16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/information_schema.result14
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/issue255.result12
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/mariadb_ignore_dirs.result9
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result83
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/misc.result1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result15
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rpl_row_triggers.result50
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/show_table_status.result12
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/truncate_table.result16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/suite.opt3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/suite.pm1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/2pc_group_commit.test26
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test9
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/bulk_load.inc2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/bulk_load_unsorted.test1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/compact_deletes_test.inc2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/disabled.def18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/drop_table2.test4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/information_schema-master.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/information_schema.test14
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/mariadb_ignore_dirs.test17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test75
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/optimize_table.inc2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test2
-rwxr-xr-xstorage/rocksdb/mysql-test/rocksdb_hotbackup/include/stream_run.sh4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/my.cnf1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/mdev12179.result265
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_binlog_xid_count.result204
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/singledelete_idempotent_table.result10
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/suite.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def30
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test232
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test20
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf10
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/include/rocksdb_sys_var.inc1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_datadir_basic.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_flush_memtable_on_analyze_basic.result8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_git_hash_basic.result7
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/suite.opt3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_git_hash_basic.test6
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/cleanup_engine.inc4
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/disabled.def1
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/misc.rdiff17
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/parts/suite.opt2
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/suite.opt2
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/trx/suite.opt2
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff20
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff11
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff20
-rw-r--r--storage/rocksdb/patch/port/win/io_win.h446
-rw-r--r--storage/rocksdb/rdb_datadic.cc34
-rw-r--r--storage/rocksdb/rdb_datadic.h7
-rw-r--r--storage/rocksdb/rdb_i_s.cc23
-rw-r--r--storage/rocksdb/rdb_io_watchdog.cc2
-rw-r--r--storage/rocksdb/rdb_io_watchdog.h2
-rw-r--r--storage/rocksdb/rdb_source_revision.h.in1
-rw-r--r--storage/rocksdb/rdb_sst_info.cc3
-rw-r--r--storage/sphinx/CMakeLists.txt10
-rw-r--r--storage/sphinx/ha_sphinx.cc27
-rw-r--r--storage/spider/CMakeLists.txt30
-rw-r--r--storage/spider/ha_spider.cc793
-rw-r--r--storage/spider/ha_spider.h111
-rw-r--r--storage/spider/hs_client/allocator.hpp6
-rw-r--r--storage/spider/hs_client/config.cpp4
-rw-r--r--storage/spider/hs_client/escape.cpp1
-rw-r--r--storage/spider/hs_client/fatal.cpp2
-rw-r--r--storage/spider/hs_client/fatal.hpp2
-rw-r--r--storage/spider/hs_client/hs_compat.h9
-rw-r--r--storage/spider/hs_client/hstcpcli.cpp2
-rw-r--r--storage/spider/hs_client/socket.cpp11
-rw-r--r--storage/spider/hs_client/string_util.cpp2
-rw-r--r--storage/spider/mysql-test/spider/bg/r/direct_aggregate.result8
-rw-r--r--storage/spider/mysql-test/spider/bg/r/direct_aggregate_part.result10
-rw-r--r--storage/spider/mysql-test/spider/bg/r/direct_update.result8
-rw-r--r--storage/spider/mysql-test/spider/bg/r/direct_update_part.result8
-rw-r--r--storage/spider/mysql-test/spider/bg/r/spider_fixes.result1
-rw-r--r--storage/spider/mysql-test/spider/handler/r/direct_update.result8
-rw-r--r--storage/spider/mysql-test/spider/handler/r/direct_update_part.result8
-rw-r--r--storage/spider/mysql-test/spider/handler/r/spider_fixes.result1
-rw-r--r--storage/spider/mysql-test/spider/handler/suite.pm1
-rw-r--r--storage/spider/mysql-test/spider/include/deinit_spider.inc4
-rw-r--r--storage/spider/mysql-test/spider/include/direct_join_deinit.inc9
-rw-r--r--storage/spider/mysql-test/spider/include/direct_join_init.inc13
-rw-r--r--storage/spider/mysql-test/spider/include/init_spider.inc70
-rw-r--r--storage/spider/mysql-test/spider/include/partition_cond_push_deinit.inc20
-rw-r--r--storage/spider/mysql-test/spider/include/partition_cond_push_init.inc58
-rw-r--r--storage/spider/mysql-test/spider/include/partition_fulltext_deinit.inc23
-rw-r--r--storage/spider/mysql-test/spider/include/partition_fulltext_init.inc72
-rw-r--r--storage/spider/mysql-test/spider/include/partition_join_pushdown_for_single_partition_deinit.inc30
-rw-r--r--storage/spider/mysql-test/spider/include/partition_join_pushdown_for_single_partition_init.inc105
-rw-r--r--storage/spider/mysql-test/spider/include/partition_mrr_deinit.inc23
-rw-r--r--storage/spider/mysql-test/spider/include/partition_mrr_init.inc92
-rw-r--r--storage/spider/mysql-test/spider/r/auto_increment.result186
-rw-r--r--storage/spider/mysql-test/spider/r/direct_aggregate.result8
-rw-r--r--storage/spider/mysql-test/spider/r/direct_aggregate_part.result10
-rw-r--r--storage/spider/mysql-test/spider/r/direct_join.result105
-rw-r--r--storage/spider/mysql-test/spider/r/direct_update.result8
-rw-r--r--storage/spider/mysql-test/spider/r/direct_update_part.result8
-rw-r--r--storage/spider/mysql-test/spider/r/partition_cond_push.result168
-rw-r--r--storage/spider/mysql-test/spider/r/partition_fulltext.result126
-rw-r--r--storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result130
-rw-r--r--storage/spider/mysql-test/spider/r/partition_mrr.result223
-rw-r--r--storage/spider/mysql-test/spider/r/spider3_fixes_part.result18
-rw-r--r--storage/spider/mysql-test/spider/r/spider_fixes.result1
-rw-r--r--storage/spider/mysql-test/spider/t/auto_increment.test185
-rw-r--r--storage/spider/mysql-test/spider/t/auto_increment_deinit.inc13
-rw-r--r--storage/spider/mysql-test/spider/t/auto_increment_init.inc38
-rw-r--r--storage/spider/mysql-test/spider/t/direct_join.test197
-rw-r--r--storage/spider/mysql-test/spider/t/partition_cond_push.test219
-rw-r--r--storage/spider/mysql-test/spider/t/partition_fulltext.test223
-rw-r--r--storage/spider/mysql-test/spider/t/partition_join_pushdown_for_single_partition.test222
-rw-r--r--storage/spider/mysql-test/spider/t/partition_mrr.test235
-rw-r--r--storage/spider/scripts/install_spider.sql145
-rw-r--r--storage/spider/spd_conn.cc757
-rw-r--r--storage/spider/spd_conn.h29
-rw-r--r--storage/spider/spd_copy_tables.cc36
-rw-r--r--storage/spider/spd_copy_tables.h2
-rw-r--r--storage/spider/spd_db_conn.cc1195
-rw-r--r--storage/spider/spd_db_conn.h98
-rw-r--r--storage/spider/spd_db_handlersocket.cc547
-rw-r--r--storage/spider/spd_db_handlersocket.h106
-rw-r--r--storage/spider/spd_db_include.h344
-rw-r--r--storage/spider/spd_db_mysql.cc1358
-rw-r--r--storage/spider/spd_db_mysql.h161
-rw-r--r--storage/spider/spd_db_oracle.cc948
-rw-r--r--storage/spider/spd_db_oracle.h130
-rw-r--r--storage/spider/spd_direct_sql.cc120
-rw-r--r--storage/spider/spd_direct_sql.h2
-rw-r--r--storage/spider/spd_environ.h40
-rw-r--r--storage/spider/spd_err.h20
-rw-r--r--storage/spider/spd_group_by_handler.cc2040
-rw-r--r--storage/spider/spd_group_by_handler.h44
-rw-r--r--storage/spider/spd_i_s.cc5
-rw-r--r--storage/spider/spd_include.h152
-rw-r--r--storage/spider/spd_malloc.cc7
-rw-r--r--storage/spider/spd_malloc.h2
-rw-r--r--storage/spider/spd_param.cc311
-rw-r--r--storage/spider/spd_param.h32
-rw-r--r--storage/spider/spd_ping_table.cc394
-rw-r--r--storage/spider/spd_ping_table.h22
-rw-r--r--storage/spider/spd_sys_table.cc911
-rw-r--r--storage/spider/spd_sys_table.h214
-rw-r--r--storage/spider/spd_table.cc2032
-rw-r--r--storage/spider/spd_table.h69
-rw-r--r--storage/spider/spd_trx.cc529
-rw-r--r--storage/spider/spd_trx.h2
-rw-r--r--storage/spider/spd_udf.cc3
-rw-r--r--storage/spider/spd_udf.h2
-rw-r--r--storage/tokudb/CMakeLists.txt12
-rw-r--r--storage/tokudb/PerconaFT/CMakeLists.txt7
-rw-r--r--storage/tokudb/PerconaFT/buildheader/make_tdb.cc13
-rw-r--r--storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake10
-rw-r--r--storage/tokudb/PerconaFT/ft/cachetable/background_job_manager.cc9
-rw-r--r--storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc82
-rw-r--r--storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc36
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-ops.cc304
-rw-r--r--storage/tokudb/PerconaFT/ft/ft.cc17
-rw-r--r--storage/tokudb/PerconaFT/ft/loader/callbacks.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/loader/dbufio.cc163
-rw-r--r--storage/tokudb/PerconaFT/ft/loader/loader-internal.h37
-rw-r--r--storage/tokudb/PerconaFT/ft/loader/loader.cc365
-rw-r--r--storage/tokudb/PerconaFT/ft/loader/loader.h5
-rw-r--r--storage/tokudb/PerconaFT/ft/logger/log-internal.h8
-rw-r--r--storage/tokudb/PerconaFT/ft/logger/logcursor.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/logger/logger.cc79
-rw-r--r--storage/tokudb/PerconaFT/ft/logger/recover.cc14
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/block_allocator.cc1
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/block_table.cc13
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc10
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/sub_block.cc3
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/workset.h14
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-4357.cc31
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-4365.cc42
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-5097.cc11
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-5978-2.cc20
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-5978.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-checkpoint-pending.cc24
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-cleaner-thread-attrs-accumulate.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-clone-checkpoint.cc11
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-pin-checkpoint.cc21
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-put-checkpoint.cc21
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-rwlock-test.cc47
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin-nonblocking.cc30
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin.cc30
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-test.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-unpin-remove-and-checkpoint.cc17
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ftloader-test-extractor-errors.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ftloader-test-merge-files-dbufio.cc12
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ftloader-test-writer-errors.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/log-test4.cc13
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/log-test5.cc16
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/log-test6.cc13
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/recovery-bad-last-entry.cc15
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-bjm.cc14
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test3681.cc34
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/roll.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/rollback_log_node_cache.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/txn.cc119
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/txn_child_manager.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/txn_manager.cc10
-rw-r--r--storage/tokudb/PerconaFT/locktree/lock_request.cc2
-rw-r--r--storage/tokudb/PerconaFT/locktree/locktree.cc8
-rw-r--r--storage/tokudb/PerconaFT/locktree/manager.cc10
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_1big7lt_1small.cc10
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_1lt.cc6
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_2lt.cc6
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_stalls.cc13
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/manager_parallel_locktree_get_release.cc3
-rw-r--r--storage/tokudb/PerconaFT/locktree/treenode.cc8
-rw-r--r--storage/tokudb/PerconaFT/portability/CMakeLists.txt5
-rw-r--r--storage/tokudb/PerconaFT/portability/file.cc498
-rw-r--r--storage/tokudb/PerconaFT/portability/memory.cc8
-rw-r--r--storage/tokudb/PerconaFT/portability/portability.cc60
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/rwlock_condvar.h4
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rdlock.cc2
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rwr.cc14
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/test-stat.cc9
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/test-toku-malloc.cc8
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_assert.h14
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_debug_sync.h3
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc365
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_instr_mysql.h249
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_instrumentation.h339
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_os.h10
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_portability.h330
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_pthread.h450
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_race_tools.h5
-rw-r--r--storage/tokudb/PerconaFT/src/indexer-undo-do.cc2
-rw-r--r--storage/tokudb/PerconaFT/src/indexer.cc19
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-first-empty.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-first.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-last.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-next-prev-deadlock.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-next-prev.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-prelock-range.cc13
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-put-timeout.cc17
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-put-wakeup.cc17
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-put.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-set-range-0.cc11
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-set-range-n.cc11
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-set-range-reverse-0.cc11
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-set.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-table-lock.cc13
-rw-r--r--storage/tokudb/PerconaFT/src/tests/checkpoint_fairness.cc12
-rw-r--r--storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc37
-rw-r--r--storage/tokudb/PerconaFT/src/tests/db-put-simple-deadlock-threads.cc9
-rw-r--r--storage/tokudb/PerconaFT/src/tests/db-put-simple-lockwait.cc7
-rw-r--r--storage/tokudb/PerconaFT/src/tests/db-put-update-deadlock.cc15
-rw-r--r--storage/tokudb/PerconaFT/src/tests/filesize.cc6
-rw-r--r--storage/tokudb/PerconaFT/src/tests/hotindexer-bw.cc26
-rw-r--r--storage/tokudb/PerconaFT/src/tests/hotindexer-multiclient.cc22
-rw-r--r--storage/tokudb/PerconaFT/src/tests/hotindexer-put-abort.cc9
-rw-r--r--storage/tokudb/PerconaFT/src/tests/hotindexer-put-commit.cc14
-rw-r--r--storage/tokudb/PerconaFT/src/tests/hotindexer-with-queries.cc13
-rw-r--r--storage/tokudb/PerconaFT/src/tests/locktree_escalation_stalls.cc13
-rw-r--r--storage/tokudb/PerconaFT/src/tests/recover-test_crash_in_flusher_thread.h19
-rw-r--r--storage/tokudb/PerconaFT/src/tests/recovery_stress.cc15
-rw-r--r--storage/tokudb/PerconaFT/src/tests/stress_openclose.h11
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test3039.cc44
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_1672532.cc210
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_3645.cc46
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_4015.cc14
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_abort1.cc20
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_abort4.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_abort5.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_forkjoin.cc9
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_groupcommit_count.cc14
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_groupcommit_perf.cc14
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_iterate_pending_lock_requests.cc11
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_lock_timeout_callback.cc3
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_log1.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_log1_abort.cc12
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_logmax.cc21
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_multiple_checkpoints_block_commit.cc15
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_stress_hot_indexing.cc7
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_thread_insert.cc9
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_txn_abort7.cc21
-rw-r--r--storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h49
-rw-r--r--storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc4
-rw-r--r--storage/tokudb/PerconaFT/src/ydb.cc31
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_db.cc105
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_db.h3
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_env_func.cc2
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_txn.cc10
-rw-r--r--storage/tokudb/PerconaFT/tools/CMakeLists.txt1
-rw-r--r--storage/tokudb/PerconaFT/util/dbt.cc3
-rw-r--r--storage/tokudb/PerconaFT/util/fmutex.h6
-rw-r--r--storage/tokudb/PerconaFT/util/frwlock.cc510
-rw-r--r--storage/tokudb/PerconaFT/util/frwlock.h142
-rw-r--r--storage/tokudb/PerconaFT/util/kibbutz.cc28
-rw-r--r--storage/tokudb/PerconaFT/util/minicron.cc31
-rw-r--r--storage/tokudb/PerconaFT/util/nb_mutex.h52
-rw-r--r--storage/tokudb/PerconaFT/util/queue.cc13
-rw-r--r--storage/tokudb/PerconaFT/util/rwlock.h88
-rw-r--r--storage/tokudb/PerconaFT/util/tests/marked-omt-test.cc18
-rw-r--r--storage/tokudb/PerconaFT/util/tests/minicron-test.cc9
-rw-r--r--storage/tokudb/PerconaFT/util/tests/queue-test.cc6
-rw-r--r--storage/tokudb/PerconaFT/util/tests/rwlock_condvar.h6
-rw-r--r--storage/tokudb/PerconaFT/util/tests/sm-basic.cc3
-rw-r--r--storage/tokudb/PerconaFT/util/tests/sm-crash-double-free.cc6
-rw-r--r--storage/tokudb/PerconaFT/util/tests/test-frwlock-fair-writers.cc4
-rw-r--r--storage/tokudb/PerconaFT/util/tests/test-rwlock-cheapness.cc11
-rw-r--r--storage/tokudb/PerconaFT/util/tests/test-rwlock.cc39
-rw-r--r--storage/tokudb/PerconaFT/util/tests/threadpool-test.cc7
-rw-r--r--storage/tokudb/PerconaFT/util/threadpool.cc31
-rw-r--r--storage/tokudb/ha_tokudb.cc139
-rw-r--r--storage/tokudb/ha_tokudb.h16
-rw-r--r--storage/tokudb/ha_tokudb_update.cc4
-rw-r--r--storage/tokudb/hatoku_cmp.cc1
-rw-r--r--storage/tokudb/hatoku_defines.h28
-rw-r--r--storage/tokudb/hatoku_hton.cc52
-rw-r--r--storage/tokudb/hatoku_hton.h5
-rw-r--r--storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_crash_safe.result2183
-rw-r--r--storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result2
-rw-r--r--storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result2
-rw-r--r--storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_mixed_crash_safe.result1773
-rw-r--r--storage/tokudb/mysql-test/rpl/t/rpl_tokudb_row_crash_safe.test19
-rw-r--r--storage/tokudb/mysql-test/rpl/t/rpl_tokudb_stm_mixed_crash_safe.test18
-rw-r--r--storage/tokudb/mysql-test/tokudb/disabled.def3
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result11
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-1.result16
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-2.result20
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/nonflushing_analyze_debug.result19
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/row_format.result39
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/tokudb_support_xa.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test6
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-1.test23
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-2.test29
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/nonflushing_analyze_debug.test10
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/row_format.test21
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/tokudb_support_xa.test2
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb_parts/disabled.def1
-rw-r--r--storage/tokudb/mysql-test/tokudb_parts/r/nonflushing_analyze_debug.result50
-rw-r--r--storage/tokudb/mysql-test/tokudb_parts/t/nonflushing_analyze_debug.test29
-rw-r--r--storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_tokudb-master.opt2
-rw-r--r--storage/tokudb/mysql-test/tokudb_perfschema/r/crash_tokudb.result30
-rw-r--r--storage/tokudb/mysql-test/tokudb_perfschema/r/start_server_tokudb.result114
-rw-r--r--storage/tokudb/mysql-test/tokudb_perfschema/t/crash_tokudb.test36
-rw-r--r--storage/tokudb/mysql-test/tokudb_perfschema/t/start_server_tokudb.test10
-rw-r--r--storage/tokudb/mysql-test/tokudb_perfschema/t/suite.opt1
-rw-r--r--storage/tokudb/tokudb_background.cc30
-rw-r--r--storage/tokudb/tokudb_background.h4
-rw-r--r--storage/tokudb/tokudb_information_schema.cc14
-rw-r--r--storage/tokudb/tokudb_thread.cc1
-rw-r--r--storage/tokudb/tokudb_thread.h302
-rw-r--r--strings/CMakeLists.txt5
-rw-r--r--strings/ctype-bin.c8
-rw-r--r--strings/ctype-mb.c14
-rw-r--r--strings/ctype-simple.c14
-rw-r--r--strings/ctype-tis620.c18
-rw-r--r--strings/ctype-uca.c14
-rw-r--r--strings/ctype-ucs2.c4
-rw-r--r--strings/ctype.c12
-rw-r--r--strings/decimal.c6
-rw-r--r--strings/dtoa.c2
-rw-r--r--strings/json_lib.c6
-rw-r--r--strings/my_vsnprintf.c12
-rw-r--r--strings/str_alloc.c41
-rw-r--r--strings/xml.c9
-rw-r--r--support-files/CMakeLists.txt15
-rw-r--r--support-files/compiler_warnings.supp5
-rw-r--r--support-files/mariadb.service.in10
-rw-r--r--support-files/mariadb@.service.in10
-rw-r--r--support-files/mysql.server.sh46
-rw-r--r--support-files/sysusers.conf.in1
-rw-r--r--support-files/tmpfiles.conf.in1
-rw-r--r--tests/mysql_client_fw.c9
-rw-r--r--tests/mysql_client_test.c201
-rw-r--r--unittest/mysys/base64-t.c7
-rw-r--r--unittest/mysys/thr_template.c2
-rw-r--r--unittest/sql/mf_iocache-t.cc4
-rw-r--r--vio/viopipe.c4
-rw-r--r--vio/viosocket.c83
-rw-r--r--vio/viossl.c12
-rw-r--r--win/create_def_file.js5
-rw-r--r--win/packaging/WixUIBannerBmp.jpgbin3703 -> 3856 bytes
-rw-r--r--win/packaging/WixUIDialogBmp.jpgbin12411 -> 9745 bytes
-rw-r--r--win/packaging/ca/CustomAction.cpp78
-rw-r--r--win/upgrade_wizard/CMakeLists.txt6
-rw-r--r--win/upgrade_wizard/stdafx.h2
-rw-r--r--wsrep/CMakeLists.txt4
3935 files changed, 289025 insertions, 155062 deletions
diff --git a/.gitignore b/.gitignore
index 255759e76dd..718befa962d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -193,6 +193,7 @@ storage/myisam/sp_test
storage/rocksdb/ldb
storage/rocksdb/mysql_ldb
storage/rocksdb/sst_dump
+storage/rocksdb/rdb_source_revision.h
storage/tokudb/PerconaFT/buildheader/db.h
storage/tokudb/PerconaFT/buildheader/make_tdb
storage/tokudb/PerconaFT/buildheader/runcat.sh
@@ -494,3 +495,11 @@ UpgradeLog*.htm
# Microsoft Fakes
FakesAssemblies/
+
+compile_commands.json
+.clang-format
+.kscope/
+.vimrc
+.editorconfig
+.kateconfig
+*.kdev4
diff --git a/.travis.compiler.sh b/.travis.compiler.sh
index 13e35fffe87..db5c9ee01ce 100755
--- a/.travis.compiler.sh
+++ b/.travis.compiler.sh
@@ -14,6 +14,10 @@ if [[ "${TRAVIS_OS_NAME}" == 'linux' ]]; then
export CXX CC=${CXX/++/}
elif [[ "${CXX}" == 'g++' ]]; then
CMAKE_OPT=""
+ if [[ "${MYSQL_TEST_SUITES}" == 'rpl' ]]; then
+ CMAKE_OPT="${CMAKE_OPT} -DWITHOUT_TOKUDB_STORAGE_ENGINE=TRUE"
+ CMAKE_OPT="${CMAKE_OPT} -DWITHOUT_MROONGA_STORAGE_ENGINE=TRUE"
+ fi
export CXX=g++-${GCC_VERSION}
export CC=gcc-${GCC_VERSION}
fi
@@ -33,6 +37,9 @@ else
if which ccache ; then
CMAKE_OPT="${CMAKE_OPT} -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
fi
+ if [[ "${MYSQL_TEST_SUITES}" == 'rpl' ]]; then
+ CMAKE_OPT="${CMAKE_OPT} -DWITHOUT_TOKUDB_STORAGE_ENGINE=ON"
+ fi
CMAKE_OPT="${CMAKE_OPT} -DWITHOUT_MROONGA_STORAGE_ENGINE=ON"
if [[ "${TYPE}" == "Debug" ]]; then
CMAKE_OPT="${CMAKE_OPT} -DWITHOUT_TOKUDB_STORAGE_ENGINE=ON"
diff --git a/.travis.yml b/.travis.yml
index f1ffdbb5dfc..444c1c0d790 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,16 +18,12 @@ compiler:
cache:
apt: true
- ccache: true
+ ccache: true # Does not currently work for clang builds: https://github.com/travis-ci/travis-ci/issues/6201
directories:
- - /usr/local/Cellar
+ - /usr/local/Cellar # Fails do to permission error: https://github.com/travis-ci/travis-ci/issues/8092
env:
matrix:
-# - GCC_VERSION=4.8 TYPE=Debug MYSQL_TEST_SUITES=rpl
-# - GCC_VERSION=5 TYPE=Debug MYSQL_TEST_SUITES=main,archive,optimizer_unfixed_bugs,parts,sys_vars,unit,vcol,innodb,innodb_gis,innodb_zip,innodb_fts
-# - GCC_VERSION=6 TYPE=Debug MYSQL_TEST_SUITES=binlog,binlog_encryption,encryption,rocksdb
-# - GCC_VERSION=6 TYPE=Debug MYSQL_TEST_SUITES=csv,federated,funcs_1,funcs_2,gcol,handler,heap,json,maria,perfschema,plugins,multi_source,roles
- GCC_VERSION=4.8 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=rpl
- GCC_VERSION=5 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=main,archive,optimizer_unfixed_bugs,parts,sys_vars,unit,vcol,innodb,innodb_gis,innodb_zip,innodb_fts
- GCC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=binlog,binlog_encryption,encryption,rocksdb
@@ -40,6 +36,8 @@ matrix:
include:
- os: linux
compiler: gcc
+ env:
+ - DebPackages
addons:
apt:
packages: # make sure these match debian/control contents
@@ -80,7 +78,6 @@ matrix:
- fakeroot
script:
- ${CC} --version ; ${CXX} --version
- - source .travis.compiler.sh
# https://github.com/travis-ci/travis-ci/issues/7062 - /run/shm isn't writable or executable
# in trusty containers
- export MTR_MEM=/tmp
@@ -101,44 +98,13 @@ matrix:
compiler: clang
env: GCC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=csv,federated,funcs_1,funcs_2,gcol,handler,heap,json,maria,perfschema,plugins,multi_source,roles
-# Matrix include for coverity
-# - env:
-# - GCC_VERSION=6
-# addon:
-# coverity_scan:
-# # ref: https://scan.coverity.com/travis_ci
-# # GitHub project metadata
-# project:
-# - name: MariaDB/server
-# - description: MariaDB Server
-#
-# # Where email notification of build analysis results will be sent
-# notification_email: security@mariadb.org
-#
-# # Commands to prepare for build_command
-# build_command_prepend:
-# - source .travis.compiler.sh
-# - ${MYSQL_BUILD_CC} --version ; ${MYSQL_BUILD_CXX} --version
-# - cmake .
-# -DCMAKE_BUILD_TYPE=Debug
-# -DWITH_SSL=system -DWITH_ZLIB=system
-# -DWITHOUT_TOKUDB_STORAGE_ENGINE=ON -DWITHOUT_MROONGA_STORAGE_ENGINE=ON
-#
-# # The command that will be added as an argument to "cov-build" to compile your project for analysis,
-# build_command: make -j 4
-#
-# # Pattern to match selecting branches that will run analysis.
-# # Take care in resource usage, and consider the build frequency allowances per
-# # https://scan.coverity.com/faq#frequency - 7 per week is the current limit.
-# branch_pattern: .*coverity.*
-
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main'
- packages: # make sure these match the build requirements
+ packages: # make sure these include all compilers and all build dependencies (see list above)
- gcc-5
- g++-5
- gcc-6
diff --git a/BUILD-CMAKE b/BUILD-CMAKE
index c95482cf619..aedce4400c6 100644
--- a/BUILD-CMAKE
+++ b/BUILD-CMAKE
@@ -97,7 +97,7 @@ shell>cd ../build
shell>cmake ../src
Note: if a directory was used for in-source build, out-of-source will
-not work. To reenable out-of-source build, remove <source-root>/CMakeCache.txt
+not work. To re-enable out-of-source build, remove <source-root>/CMakeCache.txt
file.
diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh
index cae34885145..447eae0a65f 100644
--- a/BUILD/FINISH.sh
+++ b/BUILD/FINISH.sh
@@ -32,15 +32,19 @@ then
configure="$configure --verbose"
fi
+commands=""
# git clean -fdX removes all ignored (build) files
-commands="\
+if test -d .git
+then
+ commands="\
git clean -fdX
cd ./libmariadb
git submodule update
cd ../storage/rocksdb/rocksdb
git submodule update
-cd ../../..
-
+cd ../../.."
+fi
+commands="$commands
path=`dirname $0`
. \"$path/autorun.sh\""
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 2d6548dda0e..721ed3a4c45 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -307,3 +307,6 @@ gprof_compile_flags="-O2 -pg -g"
gprof_link_flags="--disable-shared $static_link"
+disable_gprof_plugins="--with-zlib-dir=bundled --without-plugin-oqgraph --without-plugin-mroonga"
+
+disable_asan_plugins="--without-plugin-rocksdb"
diff --git a/BUILD/check-cpu b/BUILD/check-cpu
index ad8816dc421..c1c85cfd908 100755
--- a/BUILD/check-cpu
+++ b/BUILD/check-cpu
@@ -40,6 +40,12 @@ check_compiler_cpu_flags () {
cc_major=$1
cc_minor=$2
cc_patch=$3
+ if test -z "$cc_minor"; then
+ cc_minor="0";
+ fi
+ if test -z "$cc_patch"; then
+ cc_minor="0";
+ fi
cc_comp=`expr $cc_major '*' 100 '+' $cc_minor`
fi
diff --git a/BUILD/compile-pentium-gprof b/BUILD/compile-pentium-gprof
index de014e3ae8b..498c964df74 100755
--- a/BUILD/compile-pentium-gprof
+++ b/BUILD/compile-pentium-gprof
@@ -19,6 +19,6 @@ path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium_cflags $gprof_compile_flags"
-extra_configs="$pentium_configs $debug_configs $gprof_link_flags $disable_64_bit_plugins"
+extra_configs="$pentium_configs $debug_configs $gprof_link_flags $disable_64_bit_plugins $disable_gprof_plugins"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium64-asan-max b/BUILD/compile-pentium64-asan-max
new file mode 100755
index 00000000000..666a0d89d8c
--- /dev/null
+++ b/BUILD/compile-pentium64-asan-max
@@ -0,0 +1,24 @@
+#! /bin/sh
+# Copyright (c) 2018, MariaDB Corporation.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_flags="$pentium64_cflags $debug_cflags -lasan -O -g -fsanitize=address"
+extra_configs="$pentium_configs $debug_configs $valgrind_configs $max_configs $disable_asan_plugins"
+export LDFLAGS="-ldl"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium64-gcov b/BUILD/compile-pentium64-gcov
index 9587c51b4e0..6e3366c79bd 100755
--- a/BUILD/compile-pentium64-gcov
+++ b/BUILD/compile-pentium64-gcov
@@ -28,6 +28,6 @@ export LDFLAGS="$gcov_link_flags"
extra_flags="$pentium64_cflags $max_cflags $gcov_compile_flags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
-extra_configs="$pentium_configs $debug_configs $gcov_configs $max_configs"
+extra_configs="$pentium_configs $debug_configs $gcov_configs $max_configs --without-oqgraph"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium64-gprof b/BUILD/compile-pentium64-gprof
index b7821e06b6e..346777a4611 100755
--- a/BUILD/compile-pentium64-gprof
+++ b/BUILD/compile-pentium64-gprof
@@ -20,6 +20,6 @@ path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium64_cflags $gprof_compile_flags"
-extra_configs="$pentium_configs $max_configs $gprof_link_flags --with-zlib-dir=bundled"
+extra_configs="$pentium_configs $max_configs $gprof_link_flags $disable_gprof_plugins"
. "$path/FINISH.sh"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b16105a710b..0813cf2288f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,9 +49,9 @@ ENDIF()
SET(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel")
-# MAX_INDEXES - Set the maximum number of indexes per table, default 64U
+# MAX_INDEXES - Set the maximum number of indexes per table, default 64
IF (NOT MAX_INDEXES)
- SET(MAX_INDEXES 64U)
+ SET(MAX_INDEXES 64)
ENDIF(NOT MAX_INDEXES)
IF (${MAX_INDEXES} GREATER 128)
@@ -162,6 +162,7 @@ INCLUDE(plugin)
INCLUDE(install_macros)
INCLUDE(systemd)
INCLUDE(mysql_add_executable)
+INCLUDE(compile_flags)
INCLUDE(crc32-vpmsum)
# Handle options
@@ -182,7 +183,8 @@ OPTION(NOT_FOR_DISTRIBUTION "Allow linking with GPLv2-incompatible system librar
INCLUDE(check_compiler_flag)
OPTION(WITH_ASAN "Enable address sanitizer" OFF)
-IF (WITH_ASAN)
+
+IF (WITH_ASAN AND NOT MSVC)
# gcc 4.8.1 and new versions of clang
MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=address -fPIC"
DEBUG RELWITHDEBINFO)
diff --git a/CREDITS b/CREDITS
index 6288c2cdea4..7572f6f5dd9 100644
--- a/CREDITS
+++ b/CREDITS
@@ -3,8 +3,9 @@ organization registered in the USA.
The current main sponsors of the MariaDB Foundation are:
-Alibaba Cloud https://intl.aliyun.com (2017)
+Alibaba Cloud https://www.alibabacloud.com/ (2017)
Booking.com https://www.booking.com (2013)
+Microsoft https://microsoft.com/ (2017)
Tencent Cloud https://cloud.tencent.com (2017)
Development Bank of Singapore https://dbs.com (2016)
IBM https://www.ibm.com (2017)
diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt
index 259d76ab5bb..0526cc43f81 100644
--- a/Docs/sp-imp-spec.txt
+++ b/Docs/sp-imp-spec.txt
@@ -103,7 +103,7 @@
- Statements:
The Lex in THD is replaced by a new Lex structure and the statement,
is parsed as usual. A sp_instr_stmt is created, containing the new
- Lex, and added to added to the instructions in sphead.
+ Lex, and added to the instructions in sphead.
Afterwards, the procedure's Lex is restored in THD.
- SET var:
Setting a local variable generates a sp_instr_set instruction,
@@ -169,7 +169,7 @@
- Parsing CREATE FUNCTION ...
- Creating a functions is essensially the same thing as for a PROCEDURE,
+ Creating a functions is essentially the same thing as for a PROCEDURE,
with the addition that a FUNCTION has a return type and a RETURN
statement, but no OUT or INOUT parameters.
@@ -189,7 +189,7 @@
additional requirement. They will be called in expressions with the same
syntax as UDFs, so UDFs and stored FUNCTIONs share the namespace. Thus,
we must make sure that we do not have UDFs and FUNCTIONs with the same
- name (even if they are storded in different places).
+ name (even if they are stored in different places).
This means that we can reparse the procedure as many time as we want.
The first time, the resulting Lex is used to store the procedure in
@@ -225,7 +225,7 @@
sql_parse.cc:mysql_execute_command() then uses sp.cc:sp_find() to
get the sp_head for the procedure (which may have been read from the
- database or feetched from the in-memory cache) and calls the sp_head's
+ database or fetched from the in-memory cache) and calls the sp_head's
method execute().
Note: It's important that substatements called by the procedure do not
do send_ok(). Fortunately, there is a flag in THD->net to disable
@@ -323,7 +323,7 @@
One "obvious" solution would be to simply push "mysql.proc" to the list
of tables used by the query, but this implies a "join" with this table
if the query is a select, so it doesn't work (and we can't exclude this
- table easily; since a priviledged used might in fact want to search
+ table easily; since a privileged used might in fact want to search
the proc table).
Another solution would of course be to allow the opening and closing
of the mysql.proc table during a query execution, but this it not
@@ -400,7 +400,7 @@
instruction.
Calling and returning from a CONTINUE handler poses some special
- problems. Since we need to return to the point after its invokation,
+ problems. Since we need to return to the point after its invocation,
we push the return location on a stack in the sp_rcontext (this is
done by the exectution loop). The handler then ends with a special
instruction, sp_instr_hreturn, which returns to this location.
@@ -545,7 +545,7 @@
Cons: Uses more memory, each SP read from table once per thread.
Unfortunately, we cannot use alternative 1 for the time being, as most
- of the datastructures to be cached (lex and items) are not reentrant
+ of the data structures to be cached (lex and items) are not reentrant
and thread-safe. (Things are modifed at execution, we have THD pointers
stored everywhere, etc.)
This leaves us with alternative 2, one cache per thread; or actually
diff --git a/VERSION b/VERSION
index b7885a80b5a..9acf9cc47c0 100644
--- a/VERSION
+++ b/VERSION
@@ -1,3 +1,4 @@
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=3
-MYSQL_VERSION_PATCH=3
+MYSQL_VERSION_PATCH=5
+SERVER_MATURITY=gamma
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000000..22939d496c9
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,21 @@
+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
+
+build:
+ project: win_build\MySQL.sln
+ parallel: true
+ verbosity: minimal
+
+configuration: RelWithDebInfo
+platform: x64
+
+test_script:
+ - set PATH=%PATH%;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
+ - cd %APPVEYOR_BUILD_FOLDER%\win_build\mysql-test
+ - perl mysql-test-run.pl --force --max-test-fail=10 --parallel=auto --testcase-timeout=10 --skip-test-list=unstable-tests --suite=main,innodb,plugins,mariabackup
+
+image: Visual Studio 2017
diff --git a/client/client_priv.h b/client/client_priv.h
index ba1a1fddfae..1d584efeea7 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -98,6 +98,7 @@ enum options_client
OPT_REPORT_PROGRESS,
OPT_SKIP_ANNOTATE_ROWS_EVENTS,
OPT_SSL_CRL, OPT_SSL_CRLPATH,
+ OPT_PRINT_ROW_COUNT, OPT_PRINT_ROW_EVENT_POSITIONS,
OPT_MAX_CLIENT_OPTION /* should be always the last */
};
diff --git a/client/completion_hash.cc b/client/completion_hash.cc
index c170b69de2d..be89dd41441 100644
--- a/client/completion_hash.cc
+++ b/client/completion_hash.cc
@@ -49,7 +49,7 @@ int completion_hash_init(HashTable *ht, uint nSize)
ht->initialized = 0;
return FAILURE;
}
- init_alloc_root(&ht->mem_root, 8192, 0, MYF(0));
+ init_alloc_root(&ht->mem_root, "completion_hash", 8192, 0, MYF(0));
ht->pHashFunction = hashpjw;
ht->nTableSize = nSize;
ht->initialized = 1;
diff --git a/client/mysql.cc b/client/mysql.cc
index fa824d598e6..19c5dd4e6a9 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1065,7 +1065,7 @@ static void fix_history(String *final_command);
static COMMANDS *find_command(char *name);
static COMMANDS *find_command(char cmd_name);
-static bool add_line(String &, char *, ulong, char *, bool *, bool);
+static bool add_line(String &, char *, size_t line_length, char *, bool *, bool);
static void remove_cntrl(String &buffer);
static void print_table_data(MYSQL_RES *result);
static void print_table_data_html(MYSQL_RES *result);
@@ -1138,6 +1138,7 @@ int main(int argc,char *argv[])
current_prompt = my_strdup(default_prompt,MYF(MY_WME));
prompt_counter=0;
aborted= 0;
+ sf_leaking_memory= 1; /* no memory leak reports yet */
outfile[0]=0; // no (default) outfile
strmov(pager, "stdout"); // the default, if --pager wasn't given
@@ -1203,9 +1204,10 @@ int main(int argc,char *argv[])
my_end(0);
exit(1);
}
+ sf_leaking_memory= 0;
glob_buffer.realloc(512);
completion_hash_init(&ht, 128);
- init_alloc_root(&hash_mem_root, 16384, 0, MYF(0));
+ init_alloc_root(&hash_mem_root, "hash", 16384, 0, MYF(0));
if (sql_connect(current_host,current_db,current_user,opt_password,
opt_silent))
{
@@ -1707,13 +1709,12 @@ static struct my_option my_long_options[] =
static void usage(int version)
{
+#ifdef HAVE_READLINE
#if defined(USE_LIBEDIT_INTERFACE)
const char* readline= "";
#else
const char* readline= "readline";
#endif
-
-#ifdef HAVE_READLINE
printf("%s Ver %s Distrib %s, for %s (%s) using %s %s\n",
my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,
readline, rl_library_version);
@@ -1795,8 +1796,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case OPT_MYSQL_PROTOCOL:
#ifndef EMBEDDED_LIBRARY
- opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
- opt->name);
+ if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
+ opt->name)) <= 0)
+ exit(1);
#endif
break;
case OPT_SERVER_ARG:
@@ -1983,7 +1985,7 @@ static int read_and_execute(bool interactive)
ulong line_number=0;
bool ml_comment= 0;
COMMANDS *com;
- ulong line_length= 0;
+ size_t line_length= 0;
status.exit_status=1;
real_binary_mode= !interactive && opt_binary_mode;
@@ -2277,7 +2279,7 @@ static COMMANDS *find_command(char *name)
}
-static bool add_line(String &buffer, char *line, ulong line_length,
+static bool add_line(String &buffer, char *line, size_t line_length,
char *in_string, bool *ml_comment, bool truncated)
{
uchar inchar;
@@ -2985,12 +2987,12 @@ static void get_current_db()
The different commands
***************************************************************************/
-int mysql_real_query_for_lazy(const char *buf, int length)
+int mysql_real_query_for_lazy(const char *buf, size_t length)
{
for (uint retry=0;; retry++)
{
int error;
- if (!mysql_real_query(&mysql,buf,length))
+ if (!mysql_real_query(&mysql,buf,(ulong)length))
return 0;
error= put_error(&mysql);
if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 ||
@@ -3561,10 +3563,10 @@ is_binary_field(MYSQL_FIELD *field)
/* Print binary value as hex literal (0x ...) */
static void
-print_as_hex(FILE *output_file, const char *str, ulong len, ulong total_bytes_to_send)
+print_as_hex(FILE *output_file, const char *str, size_t len, size_t total_bytes_to_send)
{
const char *ptr= str, *end= ptr+len;
- ulong i;
+ size_t i;
fprintf(output_file, "0x");
for(; ptr < end; ptr++)
fprintf(output_file, "%02X", *((uchar*)ptr));
@@ -3614,11 +3616,11 @@ print_table_data(MYSQL_RES *result)
(void) tee_fputs("|", PAGER);
for (uint off=0; (field = mysql_fetch_field(result)) ; off++)
{
- uint name_length= (uint) strlen(field->name);
- uint numcells= charset_info->cset->numcells(charset_info,
+ size_t name_length= (uint) strlen(field->name);
+ size_t numcells= charset_info->cset->numcells(charset_info,
field->name,
field->name + name_length);
- uint display_length= field->max_length + name_length - numcells;
+ size_t display_length= field->max_length + name_length - numcells;
tee_fprintf(PAGER, " %-*s |",(int) MY_MIN(display_length,
MAX_COLUMN_LENGTH),
field->name);
@@ -3639,7 +3641,6 @@ print_table_data(MYSQL_RES *result)
const char *buffer;
uint data_length;
uint field_max_length;
- uint visible_length;
uint extra_padding;
if (off)
@@ -3667,7 +3668,7 @@ print_table_data(MYSQL_RES *result)
We need to find how much screen real-estate we will occupy to know how
many extra padding-characters we should send with the printing function.
*/
- visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
+ size_t visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
extra_padding= (uint) (data_length - visible_length);
if (opt_binhex && is_binary_field(field))
@@ -4592,8 +4593,11 @@ static char *get_arg(char *line, get_arg_mode mode)
}
for (start=ptr ; *ptr; ptr++)
{
- if ((*ptr == '\\' && ptr[1]) || // escaped character
- (!short_cmd && qtype && *ptr == qtype && ptr[1] == qtype)) // quote
+ /* if short_cmd use historical rules (only backslash) otherwise SQL rules */
+ if (short_cmd
+ ? (*ptr == '\\' && ptr[1]) // escaped character
+ : (*ptr == '\\' && ptr[1] && qtype != '`') || // escaped character
+ (qtype && *ptr == qtype && ptr[1] == qtype)) // quote
{
// Remove (or skip) the backslash (or a second quote)
if (mode != CHECK)
diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c
index 9cf4cd957fd..81677ad551f 100644
--- a/client/mysql_plugin.c
+++ b/client/mysql_plugin.c
@@ -262,7 +262,7 @@ static char *convert_path(const char *argument)
/* Convert / to \\ to make Windows paths */
char *winfilename= my_strdup(argument, MYF(MY_FAE));
char *pos, *end;
- int length= strlen(argument);
+ size_t length= strlen(argument);
for (pos= winfilename, end= pos+length ; pos < end ; pos++)
{
@@ -712,11 +712,11 @@ static int check_options(int argc, char **argv, char *operation)
/* Form prefix strings for the options. */
const char *basedir_prefix = "--basedir=";
- int basedir_len= strlen(basedir_prefix);
+ size_t basedir_len= strlen(basedir_prefix);
const char *datadir_prefix = "--datadir=";
- int datadir_len= strlen(datadir_prefix);
+ size_t datadir_len= strlen(datadir_prefix);
const char *plugin_dir_prefix = "--plugin_dir=";
- int plugin_dir_len= strlen(plugin_dir_prefix);
+ size_t plugin_dir_len= strlen(plugin_dir_prefix);
strcpy(plugin_name, "");
for (i = 0; i < argc && num_found < 5; i++)
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index 771fb947e73..c7ef8bfc47a 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -166,8 +166,8 @@ static struct my_option my_long_options[]=
"server with which it was built/distributed.",
&opt_version_check, &opt_version_check, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
- {"write-binlog", OPT_WRITE_BINLOG, "All commands including those, "
- "issued by mysqlcheck, are written to the binary log.",
+ {"write-binlog", OPT_WRITE_BINLOG, "All commands including those "
+ "issued by mysqlcheck are written to the binary log.",
&opt_write_binlog, &opt_write_binlog, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 45b332a6cd6..bd80dd01a1e 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -34,9 +34,9 @@
char *host= NULL, *user= 0, *opt_password= 0,
*default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME;
-char truncated_var_names[MAX_MYSQL_VAR][MAX_TRUNC_LENGTH];
-char ex_var_names[MAX_MYSQL_VAR][FN_REFLEN];
-ulonglong last_values[MAX_MYSQL_VAR];
+char truncated_var_names[MAX_MYSQL_VAR+100][MAX_TRUNC_LENGTH];
+char ex_var_names[MAX_MYSQL_VAR+100][FN_REFLEN];
+ulonglong last_values[MAX_MYSQL_VAR+100];
static int interval=0;
static my_bool option_force=0,interrupted=0,new_line=0,
opt_compress= 0, opt_local= 0, opt_relative= 0, opt_verbose= 0,
@@ -299,8 +299,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#endif
break;
case OPT_MYSQL_PROTOCOL:
- opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
- opt->name);
+ if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
+ opt->name)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
+ exit(1);
+ }
break;
}
return 0;
@@ -885,7 +889,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
return -1;
}
- DBUG_ASSERT(mysql_num_rows(res) < MAX_MYSQL_VAR);
+ DBUG_ASSERT(mysql_num_rows(res) < MAX_MYSQL_VAR+100);
if (!opt_vertical)
print_header(res);
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 30d00706a9f..7e5bb435eb4 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -89,7 +89,8 @@ static char *result_file_name= 0;
static const char *output_prefix= "";
#ifndef DBUG_OFF
-static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace";
+static const char *default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace";
+const char *current_dbug_option= default_dbug_option;
#endif
static const char *load_groups[]=
{ "mysqlbinlog", "client", "client-server", "client-mariadb", 0 };
@@ -109,6 +110,8 @@ static char *opt_base64_output_mode_str= NullS;
static char* database= 0;
static char* table= 0;
static my_bool force_opt= 0, short_form= 0, remote_opt= 0;
+static my_bool print_row_count= 0, print_row_event_positions= 0;
+static my_bool print_row_count_used= 0, print_row_event_positions_used= 0;
static my_bool debug_info_flag, debug_check_flag;
static my_bool force_if_open_opt= 1;
static my_bool opt_raw_mode= 0, opt_stop_never= 0;
@@ -224,14 +227,16 @@ void keep_annotate_event(Annotate_rows_log_event* event)
annotate_event= event;
}
-void print_annotate_event(PRINT_EVENT_INFO *print_event_info)
+bool print_annotate_event(PRINT_EVENT_INFO *print_event_info)
{
+ bool error= 0;
if (annotate_event)
{
- annotate_event->print(result_file, print_event_info);
+ error= annotate_event->print(result_file, print_event_info);
delete annotate_event; // the event should not be printed more than once
annotate_event= 0;
}
+ return error;
}
static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *, const char*);
@@ -434,7 +439,7 @@ File Load_log_processor::prepare_new_file_for_old_format(Load_log_event *le,
return -1;
}
- le->set_fname_outside_temp_buf(filename,len+(uint) strlen(tail));
+ le->set_fname_outside_temp_buf(filename,len+strlen(tail));
return file;
}
@@ -532,7 +537,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname,
uint file_id,
Create_file_log_event *ce)
{
- uint full_len= target_dir_name_len + blen + 9 + 9 + 1;
+ size_t full_len= target_dir_name_len + blen + 9 + 9 + 1;
Exit_status retval= OK_CONTINUE;
char *fname, *ptr;
File file;
@@ -578,7 +583,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname,
}
if (ce)
- ce->set_fname_outside_temp_buf(fname, (uint) strlen(fname));
+ ce->set_fname_outside_temp_buf(fname, strlen(fname));
if (my_write(file, (uchar*)block, block_len, MYF(MY_WME|MY_NABP)))
{
@@ -795,7 +800,7 @@ print_use_stmt(PRINT_EVENT_INFO* pinfo, const Query_log_event *ev)
static void
print_skip_replication_statement(PRINT_EVENT_INFO *pinfo, const Log_event *ev)
{
- int cur_val;
+ bool cur_val;
cur_val= (ev->flags & LOG_EVENT_SKIP_REPLICATION_F) != 0;
if (cur_val == pinfo->skip_replication)
@@ -847,8 +852,9 @@ write_event_header_and_base64(Log_event *ev, FILE *result_file,
DBUG_ENTER("write_event_header_and_base64");
/* Write header and base64 output to cache */
- ev->print_header(head, print_event_info, FALSE);
- ev->print_base64(body, print_event_info, FALSE);
+ if (ev->print_header(head, print_event_info, FALSE) ||
+ ev->print_base64(body, print_event_info, FALSE))
+ DBUG_RETURN(ERROR_STOP);
/* Read data from cache and write to result file */
if (copy_event_cache_to_file_and_reinit(head, result_file) ||
@@ -870,24 +876,20 @@ static bool print_base64(PRINT_EVENT_INFO *print_event_info, Log_event *ev)
passed --short-form, because --short-form disables printing
row events.
*/
+
if (!print_event_info->printed_fd_event && !short_form &&
- opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
+ opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS &&
+ opt_base64_output_mode != BASE64_OUTPUT_NEVER)
{
const char* type_str= ev->get_type_str();
- if (opt_base64_output_mode == BASE64_OUTPUT_NEVER)
- error("--base64-output=never specified, but binlog contains a "
- "%s event which must be printed in base64.",
- type_str);
- else
- error("malformed binlog: it does not contain any "
- "Format_description_log_event. I now found a %s event, which "
+ error("malformed binlog: it does not contain any "
+ "Format_description_log_event. Found a %s event, which "
"is not safe to process without a "
"Format_description_log_event.",
type_str);
return 1;
}
- ev->print(result_file, print_event_info);
- return print_event_info->head_cache.error == -1;
+ return ev->print(result_file, print_event_info);
}
@@ -897,6 +899,8 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
Table_map_log_event *ignored_map=
print_event_info->m_table_map_ignored.get_table(table_id);
bool skip_event= (ignored_map != NULL);
+ char ll_buff[21];
+ bool result= 0;
if (opt_flashback)
{
@@ -969,19 +973,18 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
return 0;
if (!opt_flashback)
- return print_base64(print_event_info, ev);
+ result= print_base64(print_event_info, ev);
else
{
if (is_stmt_end)
{
- bool res= false;
Log_event *e= NULL;
// Print the row_event from the last one to the first one
for (uint i= events_in_stmt.elements; i > 0; --i)
{
e= *(dynamic_element(&events_in_stmt, i - 1, Log_event**));
- res= res || print_base64(print_event_info, e);
+ result= result || print_base64(print_event_info, e);
}
// Copy all output into the Log_event
ev->output_buf.copy(e->output_buf);
@@ -992,12 +995,17 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
delete e;
}
reset_dynamic(&events_in_stmt);
-
- return res;
}
}
- return 0;
+ if (is_stmt_end && !result)
+ {
+ if (print_event_info->print_row_count)
+ fprintf(result_file, "# Number of rows: %s\n",
+ llstr(print_event_info->row_events, ll_buff));
+ print_event_info->row_events= 0;
+ }
+ return result;
}
@@ -1028,7 +1036,6 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
Log_event_type ev_type= ev->get_type_code();
my_bool destroy_evt= TRUE;
DBUG_ENTER("process_event");
- print_event_info->short_form= short_form;
Exit_status retval= OK_CONTINUE;
IO_CACHE *const head= &print_event_info->head_cache;
@@ -1074,7 +1081,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
retval= OK_STOP;
goto end;
}
- if (!short_form && !opt_flashback)
+ if (print_row_event_positions)
fprintf(result_file, "# at %s\n",llstr(pos,ll_buff));
if (!opt_hexdump)
@@ -1115,7 +1122,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
else
{
print_skip_replication_statement(print_event_info, ev);
- ev->print(result_file, print_event_info);
+ if (ev->print(result_file, print_event_info))
+ goto err;
}
if (head->error == -1)
goto err;
@@ -1150,8 +1158,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
else
{
print_skip_replication_statement(print_event_info, ev);
- ce->print(result_file, print_event_info, TRUE);
- if (head->error == -1)
+ if (ce->print(result_file, print_event_info, TRUE))
goto err;
}
// If this binlog is not 3.23 ; why this test??
@@ -1174,8 +1181,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
the subsequent call load_processor.process fails, because the
output of Append_block_log_event::print is only a comment.
*/
- ev->print(result_file, print_event_info);
- if (head->error == -1)
+ if (ev->print(result_file, print_event_info))
goto err;
if ((retval= load_processor.process((Append_block_log_event*) ev)) !=
OK_CONTINUE)
@@ -1184,8 +1190,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
case EXEC_LOAD_EVENT:
{
- ev->print(result_file, print_event_info);
- if (head->error == -1)
+ if (ev->print(result_file, print_event_info))
goto err;
Execute_load_log_event *exv= (Execute_load_log_event*)ev;
Create_file_log_event *ce= load_processor.grab_event(exv->file_id);
@@ -1196,15 +1201,16 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
*/
if (ce)
{
+ bool error;
/*
We must not convert earlier, since the file is used by
my_open() in Load_log_processor::append().
*/
convert_path_to_forward_slashes((char*) ce->fname);
- ce->print(result_file, print_event_info, TRUE);
+ error= ce->print(result_file, print_event_info, TRUE);
my_free((void*)ce->fname);
delete ce;
- if (head->error == -1)
+ if (error)
goto err;
}
else
@@ -1215,10 +1221,10 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
case FORMAT_DESCRIPTION_EVENT:
delete glob_description_event;
glob_description_event= (Format_description_log_event*) ev;
+ destroy_evt= 0;
print_event_info->common_header_len=
glob_description_event->common_header_len;
- ev->print(result_file, print_event_info);
- if (head->error == -1)
+ if (ev->print(result_file, print_event_info))
goto err;
if (!remote_opt)
{
@@ -1248,8 +1254,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
}
break;
case BEGIN_LOAD_QUERY_EVENT:
- ev->print(result_file, print_event_info);
- if (head->error == -1)
+ if (ev->print(result_file, print_event_info))
goto err;
if ((retval= load_processor.process((Begin_load_query_log_event*) ev)) !=
OK_CONTINUE)
@@ -1267,11 +1272,9 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
{
convert_path_to_forward_slashes(fname);
print_skip_replication_statement(print_event_info, ev);
- exlq->print(result_file, print_event_info, fname);
- if (head->error == -1)
+ if (exlq->print(result_file, print_event_info, fname))
{
- if (fname)
- my_free(fname);
+ my_free(fname);
goto err;
}
}
@@ -1279,9 +1282,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
warning("Ignoring Execute_load_query since there is no "
"Begin_load_query event for file_id: %u", exlq->file_id);
}
-
- if (fname)
- my_free(fname);
+ my_free(fname);
break;
}
case ANNOTATE_ROWS_EVENT:
@@ -1427,7 +1428,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
print the kept Annotate event (if there is any).
print_annotate_event() also deletes the kept Annotate event.
*/
- print_annotate_event(print_event_info);
+ if (print_annotate_event(print_event_info))
+ goto err;
size_t len_to= 0;
const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), &len_to);
@@ -1457,10 +1459,18 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
{
Rows_log_event *e= (Rows_log_event*) ev;
bool is_stmt_end= e->get_flags(Rows_log_event::STMT_END_F);
+ if (!print_event_info->found_row_event)
+ {
+ print_event_info->found_row_event= 1;
+ print_event_info->row_events= 0;
+ }
if (print_row_event(print_event_info, ev, e->get_table_id(),
e->get_flags(Rows_log_event::STMT_END_F)))
goto err;
- if (!is_stmt_end)
+ DBUG_PRINT("info", ("is_stmt_end: %d", (int) is_stmt_end));
+ if (is_stmt_end)
+ print_event_info->found_row_event= 0;
+ else if (opt_flashback)
destroy_evt= FALSE;
break;
}
@@ -1473,7 +1483,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
if (print_row_event(print_event_info, ev, e->get_table_id(),
e->get_flags(Old_rows_log_event::STMT_END_F)))
goto err;
- if (!is_stmt_end)
+ DBUG_PRINT("info", ("is_stmt_end: %d", (int) is_stmt_end));
+ if (!is_stmt_end && opt_flashback)
destroy_evt= FALSE;
break;
}
@@ -1482,8 +1493,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
/* fall through */
default:
print_skip_replication_statement(print_event_info, ev);
- ev->print(result_file, print_event_info);
- if (head->error == -1)
+ if (ev->print(result_file, print_event_info))
goto err;
}
}
@@ -1494,7 +1504,8 @@ err:
retval= ERROR_STOP;
end:
rec_count++;
-
+
+ DBUG_PRINT("info", ("end event processing"));
/*
Destroy the log_event object.
MariaDB MWL#36: mainline does this:
@@ -1539,6 +1550,7 @@ end:
if (destroy_evt) /* destroy it later if not set (ignored table map) */
delete ev;
}
+ DBUG_PRINT("exit",("return: %d", retval));
DBUG_RETURN(retval);
}
@@ -1550,14 +1562,15 @@ static struct my_option my_options[] =
{"base64-output", OPT_BASE64_OUTPUT_MODE,
/* 'unspec' is not mentioned because it is just a placeholder. */
"Determine when the output statements should be base64-encoded BINLOG "
- "statements: 'never' disables it and works only for binlogs without "
- "row-based events; 'decode-rows' decodes row events into commented SQL "
- "statements if the --verbose option is also given; 'auto' prints base64 "
- "only when necessary (i.e., for row-based events and format description "
- "events); 'always' prints base64 whenever possible. 'always' is "
- "deprecated, will be removed in a future version, and should not be used "
- "in a production system. --base64-output with no 'name' argument is "
- "equivalent to --base64-output=always and is also deprecated. If no "
+ "statements: 'never' doesn't print binlog row events and should not be "
+ "used when directing output to a MariaDB master; "
+ "'decode-rows' decodes row events into commented SQL statements if the "
+ "--verbose option is also given; "
+ "'auto' prints base64 only when necessary (i.e., for row-based events and "
+ "format description events); "
+ "'always' prints base64 whenever possible. "
+ "--base64-output with no 'name' argument is equivalent to "
+ "--base64-output=always and is also deprecated. If no "
"--base64-output[=name] option is given at all, the default is 'auto'.",
&opt_base64_output_mode_str, &opt_base64_output_mode_str,
0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
@@ -1574,8 +1587,8 @@ static struct my_option my_options[] =
&database, &database, 0, GET_STR_ALLOC, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", '#', "Output debug log.", &default_dbug_option,
- &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log.", &current_dbug_option,
+ &current_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .",
&debug_check_flag, &debug_check_flag, 0,
@@ -1657,6 +1670,14 @@ static struct my_option my_options[] =
&flashback_review_tablename, &flashback_review_tablename,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"print-row-count", OPT_PRINT_ROW_COUNT,
+ "Print row counts for each row events",
+ &print_row_count, &print_row_count, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
+ 0, 0},
+ {"print-row-event-positions", OPT_PRINT_ROW_EVENT_POSITIONS,
+ "Print row event positions",
+ &print_row_event_positions, &print_row_event_positions, 0, GET_BOOL,
+ NO_ARG, 1, 0, 0, 0, 0, 0},
{"server-id", 0,
"Extract only binlog entries created by the server having the given id.",
&server_id, &server_id, 0, GET_ULONG,
@@ -1670,10 +1691,11 @@ static struct my_option my_options[] =
&shared_memory_base_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"short-form", 's', "Just show regular queries: no extra info and no "
- "row-based events. This is for testing only, and should not be used in "
- "production systems. If you want to suppress base64-output, consider "
- "using --base64-output=never instead.",
+ {"short-form", 's', "Just show regular queries: no extra info, no "
+ "row-based events and no row counts. This is mainly for testing only, "
+ "and should not be used to feed to the MariaDB server. "
+ "If you want to just suppress base64-output, you can instead "
+ "use --base64-output=never",
&short_form, &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
{"socket", 'S', "The socket file to use for connection.",
@@ -1775,9 +1797,12 @@ Example: rewrite-db='from->to'.",
*/
static void error_or_warning(const char *format, va_list args, const char *msg)
{
+ if (result_file)
+ fflush(result_file);
fprintf(stderr, "%s: ", msg);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
+ fflush(stderr);
}
/**
@@ -1830,6 +1855,7 @@ static void warning(const char *format,...)
*/
static void cleanup()
{
+ DBUG_ENTER("cleanup");
my_free(pass);
my_free(database);
my_free(table);
@@ -1843,12 +1869,13 @@ static void cleanup()
delete glob_description_event;
if (mysql)
mysql_close(mysql);
+ DBUG_VOID_RETURN;
}
static void print_version()
{
- printf("%s Ver 3.3 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
+ printf("%s Ver 3.4 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
}
@@ -1899,7 +1926,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
switch (optid) {
#ifndef DBUG_OFF
case '#':
- DBUG_PUSH(argument ? argument : default_dbug_option);
+ if (!argument)
+ argument= (char*) default_dbug_option;
+ current_dbug_option= argument;
+ DBUG_PUSH(argument);
break;
#endif
#include <sslopt-case.h>
@@ -1931,8 +1961,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
one_table= 1;
break;
case OPT_MYSQL_PROTOCOL:
- opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
- opt->name);
+ if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
+ opt->name)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
+ exit(1);
+ }
break;
#ifdef WHEN_FLASHBACK_REVIEW_READY
case opt_flashback_review:
@@ -1950,8 +1984,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_base64_output_mode= BASE64_OUTPUT_ALWAYS;
else
{
- opt_base64_output_mode= (enum_base64_output_mode)
- (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1);
+ int val;
+
+ if ((val= find_type_with_warning(argument, &base64_output_mode_typelib,
+ opt->name)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
+ exit(1);
+ }
+ opt_base64_output_mode= (enum_base64_output_mode) (val - 1);
}
break;
case OPT_REWRITE_DB: // db_from->db_to
@@ -2001,6 +2042,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
binlog_filter->add_db_rewrite(key, val);
break;
}
+ case OPT_PRINT_ROW_COUNT:
+ print_row_count_used= 1;
+ break;
+ case OPT_PRINT_ROW_EVENT_POSITIONS:
+ print_row_event_positions_used= 1;
+ break;
case 'v':
if (argument == disabled_my_option)
verbose= 0;
@@ -2133,11 +2180,30 @@ static Exit_status dump_log_entries(const char* logname)
fprintf(result_file, "DELIMITER /*!*/;\n");
strmov(print_event_info.delimiter, "/*!*/;");
- print_event_info.verbose= short_form ? 0 : verbose;
+ if (short_form)
+ {
+ if (!print_row_event_positions_used)
+ print_row_event_positions= 0;
+ if (!print_row_count_used)
+ print_row_count = 0;
+ }
+ if (opt_flashback)
+ {
+ if (!print_row_event_positions_used)
+ print_row_event_positions= 0;
+ }
+ print_event_info.verbose= short_form ? 0 : verbose;
+ print_event_info.short_form= short_form;
+ print_event_info.print_row_count= print_row_count;
+ print_event_info.file= result_file;
+ fflush(result_file);
rc= (remote_opt ? dump_remote_log_entries(&print_event_info, logname) :
dump_local_log_entries(&print_event_info, logname));
+ if (rc == ERROR_STOP)
+ return rc;
+
/* Set delimiter back to semicolon */
if (!opt_raw_mode && !opt_flashback)
fprintf(result_file, "DELIMITER ;\n");
@@ -2208,6 +2274,8 @@ static Exit_status check_master_version()
}
delete glob_description_event;
+ glob_description_event= NULL;
+
switch (version) {
case 3:
glob_description_event= new Format_description_log_event(1);
@@ -2226,7 +2294,6 @@ static Exit_status check_master_version()
glob_description_event= new Format_description_log_event(3);
break;
default:
- glob_description_event= NULL;
error("Could not find server version: "
"Master reported unrecognized MySQL version '%s'.", row[0]);
goto err;
@@ -2467,6 +2534,7 @@ static Exit_status handle_event_raw_mode(PRINT_EVENT_INFO *print_event_info,
error("Could not write into log file '%s'", out_file_name);
DBUG_RETURN(ERROR_STOP);
}
+ print_event_info->file= result_file;
delete glob_description_event;
glob_description_event= (Format_description_log_event*) ev;
@@ -2736,7 +2804,7 @@ static Exit_status check_header(IO_CACHE* file,
Format_description_log_event *new_description_event;
my_b_seek(file, tmp_pos); /* seek back to event's start */
if (!(new_description_event= (Format_description_log_event*)
- Log_event::read_log_event(file, 0, glob_description_event,
+ Log_event::read_log_event(file, glob_description_event,
opt_verify_binlog_checksum)))
/* EOF can't be hit here normally, so it's a real error */
{
@@ -2770,7 +2838,7 @@ static Exit_status check_header(IO_CACHE* file,
{
Log_event *ev;
my_b_seek(file, tmp_pos); /* seek back to event's start */
- if (!(ev= Log_event::read_log_event(file, 0, glob_description_event,
+ if (!(ev= Log_event::read_log_event(file, glob_description_event,
opt_verify_binlog_checksum)))
{
/* EOF can't be hit here normally, so it's a real error */
@@ -2884,7 +2952,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
char llbuff[21];
my_off_t old_off = my_b_tell(file);
- Log_event* ev = Log_event::read_log_event(file, 0, glob_description_event,
+ Log_event* ev = Log_event::read_log_event(file, glob_description_event,
opt_verify_binlog_checksum);
if (!ev)
{
@@ -2955,22 +3023,16 @@ int main(int argc, char** argv)
if (!argc || opt_version)
{
- if (!argc)
- usage();
if (!opt_version)
+ {
+ usage();
retval= ERROR_STOP;
+ }
goto err;
}
if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC)
opt_base64_output_mode= BASE64_OUTPUT_AUTO;
- if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS)
- warning("The --base64-output=always flag and the --base64-output flag "
- "(with '=MODE' omitted), are deprecated. "
- "The output generated when these flags are used cannot be "
- "parsed by mysql 5.6.0 and later. "
- "The flags will be removed in a future version. "
- "Please use --base64-output=auto instead.");
my_set_max_open_files(open_files_limit);
@@ -3083,7 +3145,7 @@ int main(int argc, char** argv)
If enable flashback, need to print the events from the end to the
beginning
*/
- if (opt_flashback)
+ if (opt_flashback && retval != ERROR_STOP)
{
for (uint i= binlog_events.elements; i > 0; --i)
{
@@ -3098,12 +3160,15 @@ int main(int argc, char** argv)
}
/* Set delimiter back to semicolon */
- if (!stop_event_string.is_empty())
- fprintf(result_file, "%s", stop_event_string.ptr());
- if (!opt_raw_mode && opt_flashback)
- fprintf(result_file, "DELIMITER ;\n");
+ if (retval != ERROR_STOP)
+ {
+ if (!stop_event_string.is_empty())
+ fprintf(result_file, "%s", stop_event_string.ptr());
+ if (!opt_raw_mode && opt_flashback)
+ fprintf(result_file, "DELIMITER ;\n");
+ }
- if (!opt_raw_mode)
+ if (retval != ERROR_STOP && !opt_raw_mode)
{
/*
Issue a ROLLBACK in case the last printed binlog was crashed and had half
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index d5938776452..0854c890824 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -367,8 +367,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
print_version(); exit(0);
break;
case OPT_MYSQL_PROTOCOL:
- opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
- opt->name);
+ if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
+ opt->name)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
+ exit(1);
+ }
break;
}
@@ -537,7 +541,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
{
int view;
char *table;
- uint table_len;
+ size_t table_len;
DBUG_ENTER("process_selected_tables");
if (use_db(db))
@@ -665,7 +669,7 @@ static int process_all_tables_in_db(char *database)
size_t tot_length = 0;
char *views, *views_end;
- uint tot_views_length = 0;
+ size_t tot_views_length = 0;
while ((row = mysql_fetch_row(res)))
{
@@ -962,7 +966,7 @@ static int handle_request_for_tables(char *tables, size_t length,
}
if (verbose >= 3)
puts(query);
- if (mysql_real_query(sock, query, query_length))
+ if (mysql_real_query(sock, query, (ulong)query_length))
{
sprintf(message, "when executing '%s%s... %s'", op, tab_view, options);
DBerror(sock, message);
@@ -973,7 +977,7 @@ static int handle_request_for_tables(char *tables, size_t length,
if (opt_flush_tables)
{
query_length= sprintf(query, "FLUSH TABLES %s", table_name);
- if (mysql_real_query(sock, query, query_length))
+ if (mysql_real_query(sock, query, (ulong)query_length))
{
DBerror(sock, query);
my_free(query);
diff --git a/client/mysqldump.c b/client/mysqldump.c
index a260065c64c..2c55fc381b1 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -93,7 +93,7 @@
static void add_load_option(DYNAMIC_STRING *str, const char *option,
const char *option_value);
static ulong find_set(TYPELIB *, const char *, size_t, char **, uint *);
-static char *alloc_query_str(ulong size);
+static char *alloc_query_str(size_t size);
static void field_escape(DYNAMIC_STRING* in, const char *from);
static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_med= 1,
@@ -115,10 +115,11 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_m
opt_events= 0, opt_comments_used= 0,
opt_alltspcs=0, opt_notspcs= 0, opt_logging,
opt_drop_trigger= 0 ;
-static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
+static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0,
+ select_field_names_inited= 0;
static ulong opt_max_allowed_packet, opt_net_buffer_length;
static MYSQL mysql_connection,*mysql=0;
-static DYNAMIC_STRING insert_pat;
+static DYNAMIC_STRING insert_pat, select_field_names;
static char *opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
@@ -170,7 +171,7 @@ wrappers, they will terminate the process if there is
an allocation failure.
*/
static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str,
- uint init_alloc, uint alloc_increment);
+ size_t init_alloc, size_t alloc_increment);
static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src);
static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str);
static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append,
@@ -960,8 +961,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
}
case (int) OPT_MYSQL_PROTOCOL:
- opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
- opt->name);
+ if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
+ opt->name)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
+ exit(1);
+ }
break;
}
return 0;
@@ -991,7 +996,9 @@ static int get_options(int *argc, char ***argv)
my_hash_insert(&ignore_table,
(uchar*) my_strdup("mysql.general_log", MYF(MY_WME))) ||
my_hash_insert(&ignore_table,
- (uchar*) my_strdup("mysql.slow_log", MYF(MY_WME))))
+ (uchar*) my_strdup("mysql.slow_log", MYF(MY_WME))) ||
+ my_hash_insert(&ignore_table,
+ (uchar*) my_strdup("mysql.transaction_registry", MYF(MY_WME))))
return(EX_EOM);
if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
@@ -1276,8 +1283,8 @@ get_binlog_gtid_pos(char *binlog_pos_file, char *binlog_pos_offset,
if (len_pos_file >= FN_REFLEN || len_pos_offset > LONGLONG_LEN)
return 0;
- mysql_real_escape_string(mysql, file_buf, binlog_pos_file, len_pos_file);
- mysql_real_escape_string(mysql, offset_buf, binlog_pos_offset, len_pos_offset);
+ mysql_real_escape_string(mysql, file_buf, binlog_pos_file, (ulong)len_pos_file);
+ mysql_real_escape_string(mysql, offset_buf, binlog_pos_offset, (ulong)len_pos_offset);
init_dynamic_string_checked(&query, "SELECT BINLOG_GTID_POS('", 256, 1024);
dynstr_append_checked(&query, file_buf);
dynstr_append_checked(&query, "', '");
@@ -1524,7 +1531,7 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name)
"SET SESSION character_set_results = '%s'",
(const char *) cs_name);
- return mysql_real_query(mysql, query_buffer, query_length);
+ return mysql_real_query(mysql, query_buffer, (ulong)query_length);
}
/**
@@ -1641,6 +1648,7 @@ static void free_resources()
dynstr_free(&extended_row);
dynstr_free(&dynamic_where);
dynstr_free(&insert_pat);
+ dynstr_free(&select_field_names);
if (defaults_argv)
free_defaults(defaults_argv);
mysql_library_end();
@@ -2668,7 +2676,8 @@ static inline my_bool general_log_or_slow_log_tables(const char *db,
{
return (!my_strcasecmp(charset_info, db, "mysql")) &&
(!my_strcasecmp(charset_info, table, "general_log") ||
- !my_strcasecmp(charset_info, table, "slow_log"));
+ !my_strcasecmp(charset_info, table, "slow_log") ||
+ !my_strcasecmp(charset_info, table, "transaction_registry"));
}
/*
@@ -2706,7 +2715,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
"FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE "
"TABLE_SCHEMA = %s AND TABLE_NAME = %s";
FILE *sql_file= md_result_file;
- int len;
+ size_t len;
my_bool is_log_table;
MYSQL_RES *result;
MYSQL_ROW row;
@@ -2735,7 +2744,13 @@ static uint get_table_structure(char *table, char *db, char *table_type,
else
dynstr_set_checked(&insert_pat, "");
}
-
+ if (!select_field_names_inited)
+ {
+ select_field_names_inited= 1;
+ init_dynamic_string_checked(&select_field_names, "", 1024, 1024);
+ }
+ else
+ dynstr_set_checked(&select_field_names, "");
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
@@ -2971,6 +2986,19 @@ static uint get_table_structure(char *table, char *db, char *table_type,
DBUG_RETURN(0);
}
+ while ((row= mysql_fetch_row(result)))
+ {
+ if (strlen(row[SHOW_EXTRA]) && strstr(row[SHOW_EXTRA],"INVISIBLE"))
+ complete_insert= 1;
+ if (init)
+ {
+ dynstr_append_checked(&select_field_names, ", ");
+ }
+ init=1;
+ dynstr_append_checked(&select_field_names,
+ quote_name(row[SHOW_FIELDNAME], name_buff, 0));
+ }
+ init=0;
/*
If write_data is true, then we build up insert statements for
the table's data. Note: in subsequent lines of code, this test
@@ -2998,19 +3026,8 @@ static uint get_table_structure(char *table, char *db, char *table_type,
}
}
- while ((row= mysql_fetch_row(result)))
- {
- if (complete_insert)
- {
- if (init)
- {
- dynstr_append_checked(&insert_pat, ", ");
- }
- init=1;
- dynstr_append_checked(&insert_pat,
- quote_name(row[SHOW_FIELDNAME], name_buff, 0));
- }
- }
+ if (complete_insert)
+ dynstr_append_checked(&insert_pat, select_field_names.str);
num_fields= mysql_num_rows(result);
mysql_free_result(result);
}
@@ -3070,6 +3087,21 @@ static uint get_table_structure(char *table, char *db, char *table_type,
while ((row= mysql_fetch_row(result)))
{
+ if (strlen(row[SHOW_EXTRA]) && strstr(row[SHOW_EXTRA],"INVISIBLE"))
+ complete_insert= 1;
+ if (init)
+ {
+ dynstr_append_checked(&select_field_names, ", ");
+ }
+ dynstr_append_checked(&select_field_names,
+ quote_name(row[SHOW_FIELDNAME], name_buff, 0));
+ init=1;
+ }
+ init=0;
+ mysql_data_seek(result, 0);
+
+ while ((row= mysql_fetch_row(result)))
+ {
ulong *lengths= mysql_fetch_lengths(result);
if (init)
{
@@ -3586,7 +3618,7 @@ static void field_escape(DYNAMIC_STRING* in, const char *from)
-static char *alloc_query_str(ulong size)
+static char *alloc_query_str(size_t size)
{
char *query;
@@ -3621,8 +3653,10 @@ static void dump_table(char *table, char *db)
char table_type[NAME_LEN];
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
int error= 0;
- ulong rownr, row_break, total_length, init_length;
+ ulong rownr, row_break;
uint num_fields;
+ size_t total_length, init_length;
+
MYSQL_RES *res;
MYSQL_FIELD *field;
MYSQL_ROW row;
@@ -3708,7 +3742,9 @@ static void dump_table(char *table, char *db)
/* now build the query string */
- dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '");
+ dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ ");
+ dynstr_append_checked(&query_string, select_field_names.str);
+ dynstr_append_checked(&query_string, " INTO OUTFILE '");
dynstr_append_checked(&query_string, filename);
dynstr_append_checked(&query_string, "'");
@@ -3744,7 +3780,7 @@ static void dump_table(char *table, char *db)
order_by= 0;
}
- if (mysql_real_query(mysql, query_string.str, query_string.length))
+ if (mysql_real_query(mysql, query_string.str, (ulong)query_string.length))
{
dynstr_free(&query_string);
DB_error(mysql, "when executing 'SELECT INTO OUTFILE'");
@@ -3757,7 +3793,9 @@ static void dump_table(char *table, char *db)
"\n--\n-- Dumping data for table %s\n--\n",
fix_for_comment(result_table));
- dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
+ dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ ");
+ dynstr_append_checked(&query_string, select_field_names.str);
+ dynstr_append_checked(&query_string, " FROM ");
dynstr_append_checked(&query_string, result_table);
if (where)
@@ -4030,7 +4068,7 @@ static void dump_table(char *table, char *db)
if (extended_insert)
{
- ulong row_length;
+ size_t row_length;
dynstr_append_checked(&extended_row,")");
row_length= 2 + extended_row.length;
if (total_length + row_length < opt_net_buffer_length)
@@ -4583,6 +4621,7 @@ static int dump_all_tables_in_db(char *database)
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
char *afterdot;
my_bool general_log_table_exists= 0, slow_log_table_exists=0;
+ my_bool transaction_registry_table_exists= 0;
int using_mysql_db= !my_strcasecmp(charset_info, database, "mysql");
DBUG_ENTER("dump_all_tables_in_db");
@@ -4608,7 +4647,7 @@ static int dump_all_tables_in_db(char *database)
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
}
}
- if (numrows && mysql_real_query(mysql, query.str, query.length-1))
+ if (numrows && mysql_real_query(mysql, query.str, (ulong)query.length-1))
{
dynstr_free(&query);
DB_error(mysql, "when using LOCK TABLES");
@@ -4685,6 +4724,8 @@ static int dump_all_tables_in_db(char *database)
general_log_table_exists= 1;
else if (!my_strcasecmp(charset_info, table, "slow_log"))
slow_log_table_exists= 1;
+ else if (!my_strcasecmp(charset_info, table, "transaction_registry"))
+ transaction_registry_table_exists= 1;
}
}
}
@@ -4731,6 +4772,13 @@ static int dump_all_tables_in_db(char *database)
verbose_msg("-- Warning: get_table_structure() failed with some internal "
"error for 'slow_log' table\n");
}
+ if (transaction_registry_table_exists)
+ {
+ if (!get_table_structure((char *) "transaction_registry",
+ database, table_type, &ignore_flag) )
+ verbose_msg("-- Warning: get_table_structure() failed with some internal "
+ "error for 'transaction_registry' table\n");
+ }
}
if (flush_privileges && using_mysql_db)
{
@@ -4782,7 +4830,7 @@ static my_bool dump_all_views_in_db(char *database)
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
}
}
- if (numrows && mysql_real_query(mysql, query.str, query.length-1))
+ if (numrows && mysql_real_query(mysql, query.str, (ulong)query.length-1))
DB_error(mysql, "when using LOCK TABLES");
/* We shall continue here, if --force was given */
dynstr_free(&query);
@@ -4934,7 +4982,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
if (init_dumping(db, init_dumping_tables))
DBUG_RETURN(1);
- init_alloc_root(&glob_root, 8192, 0, MYF(0));
+ init_alloc_root(&glob_root, "glob_root", 8192, 0, MYF(0));
if (!(dump_tables= pos= (char**) alloc_root(&glob_root,
tables * sizeof(char *))))
die(EX_EOM, "alloc_root failure.");
@@ -4978,7 +5026,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
!my_strcasecmp(&my_charset_latin1, db, PERFORMANCE_SCHEMA_DB_NAME)))
{
if (mysql_real_query(mysql, lock_tables_query.str,
- lock_tables_query.length-1))
+ (ulong)lock_tables_query.length-1))
{
if (!ignore_errors)
{
@@ -5644,7 +5692,7 @@ static char *primary_key_fields(const char *table_name)
MYSQL_ROW row;
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
char show_keys_buff[15 + NAME_LEN * 2 + 3];
- uint result_length= 0;
+ size_t result_length= 0;
char *result= 0;
char buff[NAME_LEN * 2 + 3];
char *quoted_field;
@@ -5962,7 +6010,7 @@ static my_bool get_view_structure(char *table, char* db)
#define DYNAMIC_STR_ERROR_MSG "Couldn't perform DYNAMIC_STRING operation"
static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str,
- uint init_alloc, uint alloc_increment)
+ size_t init_alloc, size_t alloc_increment)
{
if (init_dynamic_string(str, init_str, init_alloc, alloc_increment))
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 38b2eb5f672..84bed92bbd4 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -249,8 +249,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
#endif
case OPT_MYSQL_PROTOCOL:
- opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
- opt->name);
+ if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
+ opt->name)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
+ exit(1);
+ }
break;
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
@@ -409,7 +413,7 @@ static void lock_table(MYSQL *mysql, int tablecount, char **raw_tablename)
dynstr_append(&query, tablename);
dynstr_append(&query, " WRITE,");
}
- if (mysql_real_query(mysql, query.str, query.length-1))
+ if (mysql_real_query(mysql, query.str, (ulong)query.length-1))
db_error(mysql); /* We shall countinue here, if --force was given */
}
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 46494311f7d..f1650a4b26a 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -330,8 +330,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#endif
break;
case OPT_MYSQL_PROTOCOL:
- opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
- opt->name);
+ if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
+ opt->name)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
+ exit(1);
+ }
break;
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
@@ -657,7 +661,7 @@ static int
list_table_status(MYSQL *mysql,const char *db,const char *wild)
{
char query[NAME_LEN + 100];
- int len;
+ size_t len;
MYSQL_RES *result;
MYSQL_ROW row;
@@ -904,7 +908,7 @@ static void print_res_header(MYSQL_RES *result)
static void print_res_top(MYSQL_RES *result)
{
- uint i,length;
+ size_t i,length;
MYSQL_FIELD *field;
putchar('+');
@@ -912,7 +916,7 @@ static void print_res_top(MYSQL_RES *result)
while((field = mysql_fetch_field(result)))
{
if ((length= strlen(field->name)) > field->max_length)
- field->max_length=length;
+ field->max_length=(ulong)length;
else
length=field->max_length;
for (i=length+2 ; i--> 0 ; )
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 60e0939491c..83c5838f739 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -144,7 +144,7 @@ static unsigned long connect_flags= CLIENT_MULTI_RESULTS |
CLIENT_MULTI_STATEMENTS |
CLIENT_REMEMBER_OPTIONS;
-static int verbose, delimiter_length;
+static int verbose;
static uint commit_rate;
static uint detach_rate;
const char *num_int_cols_opt;
@@ -263,7 +263,7 @@ void option_cleanup(option_string *stmt);
void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr);
static int run_statements(MYSQL *mysql, statement *stmt);
int slap_connect(MYSQL *mysql);
-static int run_query(MYSQL *mysql, const char *query, int len);
+static int run_query(MYSQL *mysql, const char *query, size_t len);
static const char ALPHANUMERICS[]=
"0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
@@ -343,9 +343,6 @@ int main(int argc, char **argv)
if (auto_generate_sql)
srandom((uint)time(NULL));
- /* globals? Yes, so we only have to run strlen once */
- delimiter_length= strlen(delimiter);
-
if (argc > 2)
{
fprintf(stderr,"%s: Too many arguments\n",my_progname);
@@ -779,8 +776,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#endif
break;
case OPT_MYSQL_PROTOCOL:
- opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
- opt->name);
+ if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
+ opt->name)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
+ exit(1);
+ }
break;
case '#':
DBUG_PUSH(argument ? argument : default_dbug_option);
@@ -1548,18 +1549,18 @@ get_options(int *argc,char ***argv)
}
-static int run_query(MYSQL *mysql, const char *query, int len)
+static int run_query(MYSQL *mysql, const char *query, size_t len)
{
if (opt_only_print)
{
- printf("%.*s;\n", len, query);
+ printf("%.*s;\n", (int)len, query);
return 0;
}
if (verbose >= 3)
- printf("%.*s;\n", len, query);
+ printf("%.*s;\n", (int)len, query);
- return mysql_real_query(mysql, query, len);
+ return mysql_real_query(mysql, query, (ulong)len);
}
@@ -2127,7 +2128,7 @@ parse_delimiter(const char *script, statement **stmt, char delm)
char *ptr= (char *)script;
statement **sptr= stmt;
statement *tmp;
- uint length= strlen(script);
+ size_t length= strlen(script);
uint count= 0; /* We know that there is always one */
for (tmp= *sptr= (statement *)my_malloc(sizeof(statement),
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 914c0ac8621..92c6f9f8b96 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -184,7 +184,7 @@ static uint opt_connect_timeout= 0;
static uint opt_wait_for_pos_timeout= 0;
static char delimiter[MAX_DELIMITER_LENGTH]= ";";
-static uint delimiter_length= 1;
+static size_t delimiter_length= 1;
static char TMPDIR[FN_REFLEN];
static char global_subst_from[200];
@@ -265,8 +265,8 @@ static void free_re(void);
static char *get_string(char **to_ptr, char **from_ptr,
struct st_command *command);
static int replace(DYNAMIC_STRING *ds_str,
- const char *search_str, ulong search_len,
- const char *replace_str, ulong replace_len);
+ const char *search_str, size_t search_len,
+ const char *replace_str, size_t replace_len);
static uint opt_protocol=0;
@@ -291,11 +291,11 @@ const char *result_file_name= 0;
typedef struct
{
char *name;
- int name_len;
+ size_t name_len;
char *str_val;
- int str_val_len;
+ size_t str_val_len;
int int_val;
- int alloced_len;
+ size_t alloced_len;
bool int_dirty; /* do not update string if int is updated until first read */
bool is_int;
bool alloced;
@@ -572,7 +572,7 @@ struct st_replace_regex *glob_replace_regex= 0;
struct st_replace;
struct st_replace *glob_replace= 0;
void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds,
-const char *from, int len);
+const char *from);
ATTRIBUTE_NORETURN
static void cleanup_and_exit(int exit_code);
@@ -589,20 +589,19 @@ void verbose_msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
void log_msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
VAR* var_from_env(const char *, const char *);
-VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
- int val_len);
+VAR* var_init(VAR* v, const char *name, size_t name_len, const char *val, size_t val_len);
VAR* var_get(const char *var_name, const char** var_name_end,
my_bool raw, my_bool ignore_not_existing);
void eval_expr(VAR* v, const char *p, const char** p_end,
bool open_end=false, bool do_eval=true);
-my_bool match_delimiter(int c, const char *delim, uint length);
+my_bool match_delimiter(int c, const char *delim, size_t length);
void dump_result_to_reject_file(char *buf, int size);
void dump_warning_messages();
void do_eval(DYNAMIC_STRING *query_eval, const char *query,
const char *query_end, my_bool pass_through_escape_chars);
-void str_to_file(const char *fname, char *str, int size);
-void str_to_file2(const char *fname, char *str, int size, my_bool append);
+void str_to_file(const char *fname, char *str, size_t size);
+void str_to_file2(const char *fname, char *str, size_t size, my_bool append);
void fix_win_paths(char *val, size_t len);
const char *get_errname_from_code (uint error_code);
@@ -701,6 +700,8 @@ public:
void write(DYNAMIC_STRING* ds)
{
DBUG_ENTER("LogFile::write");
+ DBUG_PRINT("enter", ("length: %u", (uint) ds->length));
+
DBUG_ASSERT(m_file);
if (ds->length == 0)
@@ -1075,9 +1076,9 @@ static void init_connection_thd(struct st_connection *cn)
#else /* ! EMBEDDED_LIBRARY*/
#define init_connection_thd(X) do { } while(0)
-#define do_send_query(cn,q,q_len) mysql_send_query(cn->mysql, q, q_len)
+#define do_send_query(cn,q,q_len) mysql_send_query(cn->mysql, q, (ulong)q_len)
#define do_read_query_result(cn) mysql_read_query_result(cn->mysql)
-#define do_stmt_prepare(cn, q, q_len) mysql_stmt_prepare(cn->stmt, q, q_len)
+#define do_stmt_prepare(cn, q, q_len) mysql_stmt_prepare(cn->stmt, q, (ulong)q_len)
#define do_stmt_execute(cn) mysql_stmt_execute(cn->stmt)
#define do_stmt_close(cn) mysql_stmt_close(cn->stmt)
@@ -1566,7 +1567,6 @@ static void cleanup_and_exit(int exit_code)
}
}
- sf_leaking_memory= 0; /* all memory should be freed by now */
exit(exit_code);
}
@@ -2137,8 +2137,8 @@ int compare_files2(File fd1, const char* filename2)
trees when Maria is merged into them.
--global-subst should be removed.
*/
- uint global_subst_from_len= strlen(global_subst_from);
- uint global_subst_to_len= strlen(global_subst_to);
+ size_t global_subst_from_len= strlen(global_subst_from);
+ size_t global_subst_to_len= strlen(global_subst_to);
while (replace(&fd1_result,
global_subst_from, global_subst_from_len,
global_subst_to, global_subst_to_len) == 0)
@@ -2420,10 +2420,9 @@ void var_check_int(VAR *v)
}
-VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
- int val_len)
+VAR *var_init(VAR *v, const char *name, size_t name_len, const char *val, size_t val_len)
{
- int val_alloc_len;
+ size_t val_alloc_len;
VAR *tmp_var;
if (!name_len && name)
name_len = strlen(name);
@@ -2724,7 +2723,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
init_dynamic_string(&ds_query, 0, (end - query) + 32, 256);
do_eval(&ds_query, query, end, FALSE);
- if (mysql_real_query(mysql, ds_query.str, ds_query.length))
+ if (mysql_real_query(mysql, ds_query.str, (ulong)ds_query.length))
{
handle_error(curr_command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), &ds_res);
@@ -2761,7 +2760,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
{
/* Add column to tab separated string */
char *val= row[i];
- int len= lengths[i];
+ size_t len= lengths[i];
if (glob_replace_regex)
{
@@ -2774,7 +2773,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
}
if (glob_replace)
- replace_strings_append(glob_replace, &result, val, len);
+ replace_strings_append(glob_replace, &result, val);
else
dynstr_append_mem(&result, val, len);
}
@@ -2912,7 +2911,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var)
die("Mismatched \"'s around query '%s'", ds_query.str);
/* Run the query */
- if (mysql_real_query(mysql, ds_query.str, ds_query.length))
+ if (mysql_real_query(mysql, ds_query.str, (ulong)ds_query.length))
{
handle_error(curr_command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), &ds_res);
@@ -3059,7 +3058,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end,
struct st_command command;
memset(&command, 0, sizeof(command));
command.query= (char*)p;
- command.first_word_len= len;
+ command.first_word_len= (int)len;
command.first_argument= command.query + len;
command.end= (char*)*p_end;
command.abort_on_error= 1; /* avoid uninitialized variables */
@@ -3070,11 +3069,11 @@ void eval_expr(VAR *v, const char *p, const char **p_end,
NO_EVAL:
{
- int new_val_len = (p_end && *p_end) ?
- (int) (*p_end - p) : (int) strlen(p);
+ size_t new_val_len = (p_end && *p_end) ?
+ (size_t)(*p_end - p) : strlen(p);
if (new_val_len + 1 >= v->alloced_len)
{
- static int MIN_VAR_ALLOC= 32;
+ static size_t MIN_VAR_ALLOC= 32;
v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
MIN_VAR_ALLOC : new_val_len + 1;
if (!(v->str_val =
@@ -3330,8 +3329,8 @@ static void init_builtin_echo(void)
*/
static int replace(DYNAMIC_STRING *ds_str,
- const char *search_str, ulong search_len,
- const char *replace_str, ulong replace_len)
+ const char *search_str, size_t search_len,
+ const char *replace_str, size_t replace_len)
{
DYNAMIC_STRING ds_tmp;
const char *start= strstr(ds_str->str, search_str);
@@ -6538,7 +6537,7 @@ void do_delimiter(struct st_command* command)
}
-my_bool match_delimiter(int c, const char *delim, uint length)
+my_bool match_delimiter(int c, const char *delim, size_t length)
{
uint i;
char tmp[MAX_DELIMITER_LENGTH];
@@ -6959,6 +6958,7 @@ int read_command(struct st_command** command_ptr)
if (parser.current_line < parser.read_lines)
{
get_dynamic(&q_lines, command_ptr, parser.current_line) ;
+ DBUG_PRINT("info", ("query: %s", (*command_ptr)->query));
DBUG_RETURN(0);
}
if (!(*command_ptr= command=
@@ -7320,8 +7320,9 @@ get_one_option(int optid, const struct my_option *opt, char *argument)
exit(0);
case OPT_MYSQL_PROTOCOL:
#ifndef EMBEDDED_LIBRARY
- opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
- opt->name);
+ if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
+ opt->name)) <= 0)
+ exit(1);
#endif
break;
case '?':
@@ -7393,7 +7394,7 @@ int parse_args(int argc, char **argv)
append - append to file instead of overwriting old file
*/
-void str_to_file2(const char *fname, char *str, int size, my_bool append)
+void str_to_file2(const char *fname, char *str, size_t size, my_bool append)
{
int fd;
char buff[FN_REFLEN];
@@ -7427,7 +7428,7 @@ void str_to_file2(const char *fname, char *str, int size, my_bool append)
size - size of content witten to file
*/
-void str_to_file(const char *fname, char *str, int size)
+void str_to_file(const char *fname, char *str, size_t size)
{
str_to_file2(fname, str, size, FALSE);
}
@@ -7890,7 +7891,7 @@ static void handle_no_active_connection(struct st_command *command,
*/
void run_query_normal(struct st_connection *cn, struct st_command *command,
- int flags, char *query, int query_len,
+ int flags, char *query, size_t query_len,
DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
{
MYSQL_RES *res= 0;
@@ -8232,7 +8233,7 @@ void handle_no_error(struct st_command *command)
*/
void run_query_stmt(struct st_connection *cn, struct st_command *command,
- char *query, int query_len, DYNAMIC_STRING *ds,
+ char *query, size_t query_len, DYNAMIC_STRING *ds,
DYNAMIC_STRING *ds_warnings)
{
MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */
@@ -8509,7 +8510,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
DYNAMIC_STRING ds_sorted;
DYNAMIC_STRING ds_warnings;
char *query;
- int query_len;
+ size_t query_len;
my_bool view_created= 0, sp_created= 0;
my_bool complete_query= ((flags & QUERY_SEND_FLAG) &&
(flags & QUERY_REAP_FLAG));
@@ -8565,7 +8566,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
if (!disable_query_log && (flags & QUERY_SEND_FLAG))
{
char *print_query= query;
- int print_len= query_len;
+ size_t print_len= query_len;
if (flags & QUERY_PRINT_ORIGINAL_FLAG)
{
print_query= command->query;
@@ -8762,7 +8763,7 @@ void init_re_comp(regex_t *re, const char* str)
if (err)
{
char erbuf[100];
- int len= regerror(err, re, erbuf, sizeof(erbuf));
+ size_t len= regerror(err, re, erbuf, sizeof(erbuf));
die("error %s, %d/%d `%s'\n",
re_eprint(err), (int)len, (int)sizeof(erbuf), erbuf);
}
@@ -8828,7 +8829,7 @@ int match_re(regex_t *re, char *str)
{
char erbuf[100];
- int len= regerror(err, re, erbuf, sizeof(erbuf));
+ size_t len= regerror(err, re, erbuf, sizeof(erbuf));
die("error %s, %d/%d `%s'\n",
re_eprint(err), (int)len, (int)sizeof(erbuf), erbuf);
}
@@ -9139,7 +9140,7 @@ int main(int argc, char **argv)
#endif
init_dynamic_string(&ds_res, "", 2048, 2048);
- init_alloc_root(&require_file_root, 1024, 1024, MYF(0));
+ init_alloc_root(&require_file_root, "require_file", 1024, 1024, MYF(0));
parse_args(argc, argv);
@@ -9963,8 +9964,7 @@ typedef struct st_replace_found {
void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
- const char *str,
- int len __attribute__((unused)))
+ const char *str)
{
REPLACE *rep_pos;
REPLACE_STRING *rep_str;
@@ -10007,7 +10007,6 @@ void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
DBUG_PRINT("exit", ("Found end of from string"));
DBUG_VOID_RETURN;
}
- DBUG_ASSERT(from <= str+len);
start= from;
rep_pos=rep;
}
@@ -10071,7 +10070,7 @@ struct st_replace_regex* init_replace_regex(char* expr)
{
char *expr_end, *buf_p;
struct st_replace_regex* res;
- uint expr_len= strlen(expr);
+ size_t expr_len= strlen(expr);
/* my_malloc() will die on fail with MY_FAE */
res=(struct st_replace_regex*)my_malloc(
@@ -10454,7 +10453,7 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
regfree(&r);
*res_p= 0;
*buf_p= buf;
- *buf_len_p= buf_len;
+ *buf_len_p= (int)buf_len;
return 0;
}
@@ -11097,7 +11096,7 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, size_t len)
if (glob_replace)
{
/* Normal replace */
- replace_strings_append(glob_replace, ds, val, len);
+ replace_strings_append(glob_replace, ds, val);
}
else
dynstr_append_mem(ds, val, len);
diff --git a/cmake/bison.cmake b/cmake/bison.cmake
index 0e4a7b58a13..d825e407b22 100644
--- a/cmake/bison.cmake
+++ b/cmake/bison.cmake
@@ -20,7 +20,16 @@ IF(CMAKE_SYSTEM_NAME MATCHES "SunOS")
SET(BISON_EXECUTABLE /opt/csw/bin/bison)
ENDIF()
ENDIF()
-FIND_PROGRAM(BISON_EXECUTABLE bison DOC "path to the bison executable")
+IF(WIN32)
+ SET(BISON_PATH_HINTS
+ HINTS
+ C:/gnuwin32/bin
+ C:/cygwin64/bin
+ C:/cygwin/bin)
+ENDIF()
+FIND_PROGRAM(BISON_EXECUTABLE bison
+ ${BISON_PATH_HINTS}
+ DOC "path to the bison executable")
MARK_AS_ADVANCED(BISON_EXECUTABLE "")
IF(NOT BISON_EXECUTABLE)
MESSAGE("Warning: Bison executable not found in PATH")
diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake
index 258db0b5a05..105855a0bd1 100644
--- a/cmake/build_configurations/mysql_release.cmake
+++ b/cmake/build_configurations/mysql_release.cmake
@@ -1,4 +1,5 @@
# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -62,7 +63,7 @@ IF(FEATURE_SET)
SET(WITH_NONE ON)
ENDIF()
- IF(num GREATER FEATURE_SET_xsmall)
+ IF(num GREATER FEATURE_SET_xsmall AND NOT WIN32)
SET(WITH_EMBEDDED_SERVER ON CACHE BOOL "")
ENDIF()
IF(num GREATER FEATURE_SET_small)
@@ -88,7 +89,9 @@ ENDIF()
OPTION(ENABLED_LOCAL_INFILE "" ON)
SET(WITH_INNODB_SNAPPY OFF CACHE STRING "")
IF(WIN32)
- SET(WITH_LIBARCHIVE STATIC CACHE STRING "")
+ SET(INSTALL_MYSQLTESTDIR "" CACHE STRING "")
+ SET(INSTALL_SQLBENCHDIR "" CACHE STRING "")
+ SET(INSTALL_SUPPORTFILESDIR "" CACHE STRING "")
ELSEIF(RPM)
SET(WITH_SSL system CACHE STRING "")
SET(WITH_ZLIB system CACHE STRING "")
@@ -128,6 +131,8 @@ IF(UNIX)
CHECK_INCLUDE_FILES(libaio.h HAVE_LIBAIO_H)
CHECK_LIBRARY_EXISTS(aio io_queue_init "" HAVE_LIBAIO)
IF(NOT HAVE_LIBAIO_H OR NOT HAVE_LIBAIO)
+ UNSET(HAVE_LIBAIO_H CACHE)
+ UNSET(HAVE_LIBAIO CACHE)
MESSAGE(FATAL_ERROR "
aio is required on Linux, you need to install the required library:
diff --git a/cmake/check_compiler_flag.cmake b/cmake/check_compiler_flag.cmake
index 6b29ac5ab6b..ab5a15f8457 100644
--- a/cmake/check_compiler_flag.cmake
+++ b/cmake/check_compiler_flag.cmake
@@ -32,25 +32,25 @@ MACRO (MY_CHECK_CXX_COMPILER_FLAG flag)
SET(CMAKE_REQUIRED_FLAGS "${SAVE_CMAKE_REQUIRED_FLAGS}")
ENDMACRO()
-FUNCTION(MY_CHECK_AND_SET_COMPILER_FLAG flag)
+FUNCTION(MY_CHECK_AND_SET_COMPILER_FLAG flag_to_set)
# At the moment this is gcc-only.
# Let's avoid expensive compiler tests on Windows:
IF(WIN32)
RETURN()
ENDIF()
- MY_CHECK_C_COMPILER_FLAG(${flag})
- MY_CHECK_CXX_COMPILER_FLAG(${flag})
- STRING(REGEX REPLACE "[-,= +]" "_" result "${flag}")
+ STRING(REGEX REPLACE "^-Wno-" "-W" flag_to_check ${flag_to_set})
+ MY_CHECK_C_COMPILER_FLAG(${flag_to_check})
+ MY_CHECK_CXX_COMPILER_FLAG(${flag_to_check})
+ STRING(REGEX REPLACE "[-,= +]" "_" result "${flag_to_check}")
FOREACH(lang C CXX)
IF (have_${lang}_${result})
IF(ARGN)
FOREACH(type ${ARGN})
- SET(CMAKE_${lang}_FLAGS_${type} "${CMAKE_${lang}_FLAGS_${type}} ${flag}" PARENT_SCOPE)
+ SET(CMAKE_${lang}_FLAGS_${type} "${CMAKE_${lang}_FLAGS_${type}} ${flag_to_set}" PARENT_SCOPE)
ENDFOREACH()
ELSE()
- SET(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${flag}" PARENT_SCOPE)
+ SET(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${flag_to_set}" PARENT_SCOPE)
ENDIF()
ENDIF()
ENDFOREACH()
ENDFUNCTION()
-
diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake
index 5b8aa36ff0d..e27206fc3b4 100644
--- a/cmake/cpack_rpm.cmake
+++ b/cmake/cpack_rpm.cmake
@@ -168,11 +168,6 @@ IF(WITH_WSREP)
SETA(CPACK_RPM_server_PACKAGE_REQUIRES
"galera" "rsync" "lsof" "grep" "gawk" "iproute"
"coreutils" "findutils" "tar")
- IF (RPM MATCHES "sles11")
- SETA(CPACK_RPM_server_PACKAGE_REQUIRES "util-linux")
- ELSE()
- SETA(CPACK_RPM_server_PACKAGE_REQUIRES "which")
- ENDIF()
ENDIF()
SET(CPACK_RPM_server_PRE_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-prein.sh)
@@ -201,7 +196,7 @@ ALTERNATIVE_NAME("server" "mysql-server")
ALTERNATIVE_NAME("test" "mysql-test")
# Argh! Different distributions call packages differently, to be a drop-in
-# replacement we have to fake distribution-speficic dependencies
+# replacement we have to fake distribution-specificic dependencies
IF(RPM MATCHES "(rhel|centos)6")
ALTERNATIVE_NAME("client" "mysql")
@@ -292,4 +287,3 @@ IF(compat53 AND compat101)
ENDIF()
ENDIF(RPM)
-
diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake
index 3edcdc4c1c5..d7ab0f31991 100644
--- a/cmake/dtrace.cmake
+++ b/cmake/dtrace.cmake
@@ -42,7 +42,8 @@ MACRO(CHECK_DTRACE)
# On FreeBSD, dtrace does not handle userland tracing yet
IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD"
AND NOT BUGGY_GCC_NO_DTRACE_MODULES
- AND NOT BUGGY_LINUX_DTRACE)
+ AND NOT BUGGY_LINUX_DTRACE
+ AND NOT CMAKE_SYSTEM_NAME MATCHES "SunOS")
SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace")
ENDIF()
SET(HAVE_DTRACE ${ENABLE_DTRACE})
diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake
index d1a261f8cef..63e2419951b 100644
--- a/cmake/install_layout.cmake
+++ b/cmake/install_layout.cmake
@@ -162,6 +162,8 @@ SET(INSTALL_MYSQLDATADIR_RPM "/var/lib/mysql")
SET(INSTALL_UNIX_ADDRDIR_RPM "${INSTALL_MYSQLDATADIR_RPM}/mysql.sock")
SET(INSTALL_SYSTEMD_UNITDIR_RPM "/usr/lib/systemd/system")
+SET(INSTALL_SYSTEMD_SYSUSERSDIR_RPM "/usr/lib/sysusers.d")
+SET(INSTALL_SYSTEMD_TMPFILESDIR_RPM "/usr/lib/tmpfiles.d")
#
# DEB layout
@@ -174,7 +176,7 @@ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
SET(INSTALL_LIBDIR_DEB "lib")
SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
#
-SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+SET(INSTALL_INCLUDEDIR_DEB "include/mariadb")
#
SET(INSTALL_DOCDIR_DEB "share/doc")
SET(INSTALL_DOCREADMEDIR_DEB "share/doc")
@@ -191,6 +193,8 @@ SET(INSTALL_MYSQLDATADIR_DEB "/var/lib/mysql")
SET(INSTALL_UNIX_ADDRDIR_DEB "/var/run/mysqld/mysqld.sock")
SET(INSTALL_SYSTEMD_UNITDIR_DEB "/lib/systemd/system")
+SET(INSTALL_SYSTEMD_SYSUSERSDIR_DEB "/usr/lib/sysusers.d")
+SET(INSTALL_SYSTEMD_TMPFILESDIR_DEB "/usr/lib/tmpfiles.d")
#
# SVR4 layout
@@ -232,7 +236,7 @@ SET(OLD_INSTALL_LAYOUT ${INSTALL_LAYOUT} CACHE INTERNAL "")
# layout is chosen)
FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR
- SYSTEMD_UNIT)
+ SYSTEMD_UNIT SYSTEMD_SYSUSERS SYSTEMD_TMPFILES)
SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
CACHE STRING "${var} installation directory" ${FORCE})
MARK_AS_ADVANCED(INSTALL_${var}DIR)
diff --git a/cmake/maintainer.cmake b/cmake/maintainer.cmake
index bd2cfd7097c..4a13edceece 100644
--- a/cmake/maintainer.cmake
+++ b/cmake/maintainer.cmake
@@ -13,55 +13,38 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-# Common warning flags for GCC, G++, Clang and Clang++
-SET(MY_WARNING_FLAGS "-Wall -Wextra -Wformat-security -Wno-init-self")
-MY_CHECK_C_COMPILER_FLAG("-Wvla") # Requires GCC 4.3+ or Clang
-IF(have_C__Wvla)
- SET(MY_WARNING_FLAGS "${MY_WARNING_FLAGS} -Wvla")
-ENDIF()
-
-MY_CHECK_C_COMPILER_FLAG("-Wno-format-truncation")
-IF(HAVE_C__Wno_format_truncation)
- SET(MY_WARNING_FLAGS "${MY_WARNING_FLAGS} -Wno-format-truncation")
-ENDIF()
-
-# Common warning flags for GCC and Clang
-SET(MY_C_WARNING_FLAGS
- "${MY_WARNING_FLAGS} -Wwrite-strings -Wdeclaration-after-statement")
-
-# Common warning flags for G++ and Clang++
-SET(MY_CXX_WARNING_FLAGS
- "${MY_WARNING_FLAGS} -Woverloaded-virtual -Wno-unused-parameter")
-
-# Extra warning flags for Clang++
-IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- SET(MY_CXX_WARNING_FLAGS
- "${MY_CXX_WARNING_FLAGS} -Wno-null-conversion -Wno-unused-private-field")
+IF(MSVC)
+ RETURN()
ENDIF()
-# Turn on Werror (warning => error) when using maintainer mode.
-IF(MYSQL_MAINTAINER_MODE MATCHES "ERR")
- SET(MY_C_WARNING_FLAGS "${MY_C_WARNING_FLAGS} -DFORCE_INIT_OF_VARS -Werror")
- SET(MY_CXX_WARNING_FLAGS "${MY_CXX_WARNING_FLAGS} -DFORCE_INIT_OF_VARS -Werror")
-ENDIF()
-
-# Set warning flags for GCC/Clang
-IF(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
- SET(MY_MAINTAINER_C_WARNINGS "${MY_C_WARNING_FLAGS}")
-ENDIF()
-# Set warning flags for G++/Clang++
-IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
- SET(MY_MAINTAINER_CXX_WARNINGS "${MY_CXX_WARNING_FLAGS}")
-ENDIF()
+# Common warning flags for GCC, G++, Clang and Clang++
+SET(MY_WARNING_FLAGS
+ -Wall
+ -Wdeclaration-after-statement
+ -Wextra
+ -Wformat-security
+ -Wno-format-truncation
+ -Wno-init-self
+ -Wno-nonnull-compare
+ -Wno-null-conversion
+ -Wno-unused-parameter
+ -Wno-unused-private-field
+ -Woverloaded-virtual
+ -Wnon-virtual-dtor
+ -Wvla
+ -Wwrite-strings
+ )
IF(MYSQL_MAINTAINER_MODE MATCHES "ON")
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_MAINTAINER_C_WARNINGS}")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_MAINTAINER_CXX_WARNINGS}")
+ SET(WHERE)
ELSEIF(MYSQL_MAINTAINER_MODE MATCHES "AUTO")
- SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${MY_MAINTAINER_C_WARNINGS}")
- SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${MY_MAINTAINER_CXX_WARNINGS}")
+ SET(WHERE DEBUG)
ENDIF()
+FOREACH(F ${MY_WARNING_FLAGS})
+ MY_CHECK_AND_SET_COMPILER_FLAG(${F} ${WHERE})
+ENDFOREACH()
+
IF(CMAKE_C_COMPILER_ID MATCHES "GNU")
STRING(REPLACE " -E " " -E -dDI " CMAKE_C_CREATE_PREPROCESSED_SOURCE ${CMAKE_C_CREATE_PREPROCESSED_SOURCE})
ENDIF()
diff --git a/cmake/make_dist.cmake.in b/cmake/make_dist.cmake.in
index 6bd71cc7653..885cfa2a706 100644
--- a/cmake/make_dist.cmake.in
+++ b/cmake/make_dist.cmake.in
@@ -55,6 +55,9 @@ ENDIF()
CONFIGURE_FILE(${CMAKE_BINARY_DIR}/include/source_revision.h
${PACKAGE_DIR}/include/source_revision.h COPYONLY)
+CONFIGURE_FILE(${CMAKE_BINARY_DIR}/storage/rocksdb/rdb_source_revision.h
+ ${PACKAGE_DIR}/storage/rocksdb/rdb_source_revision.h COPYONLY)
+
IF(NOT GIT_EXECUTABLE)
MESSAGE(STATUS "git not found or source dir is not a repo, use CPack")
diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake
index 02579c9534e..0694246af18 100644
--- a/cmake/mysql_version.cmake
+++ b/cmake/mysql_version.cmake
@@ -48,6 +48,7 @@ MACRO(GET_MYSQL_VERSION)
MYSQL_GET_CONFIG_VALUE("MYSQL_VERSION_MINOR" MINOR_VERSION)
MYSQL_GET_CONFIG_VALUE("MYSQL_VERSION_PATCH" PATCH_VERSION)
MYSQL_GET_CONFIG_VALUE("MYSQL_VERSION_EXTRA" EXTRA_VERSION)
+ MYSQL_GET_CONFIG_VALUE("SERVER_MATURITY" SERVER_MATURITY)
IF(NOT "${MAJOR_VERSION}" MATCHES "[0-9]+" OR
NOT "${MINOR_VERSION}" MATCHES "[0-9]+" OR
@@ -69,6 +70,10 @@ ENDMACRO()
# Get mysql version and other interesting variables
GET_MYSQL_VERSION()
+# Maturity level
+string(TOUPPER ${SERVER_MATURITY} SERVER_MATURITY)
+SET(SERVER_MATURITY_LEVEL MariaDB_PLUGIN_MATURITY_${SERVER_MATURITY})
+
SET(MYSQL_TCP_PORT_DEFAULT 0)
IF(NOT MYSQL_TCP_PORT)
SET(MYSQL_TCP_PORT 3306)
diff --git a/cmake/os/Windows.cmake b/cmake/os/Windows.cmake
index 021f23a14f2..3935894781e 100644
--- a/cmake/os/Windows.cmake
+++ b/cmake/os/Windows.cmake
@@ -24,9 +24,6 @@ INCLUDE (CheckCSourceRuns)
INCLUDE (CheckSymbolExists)
INCLUDE (CheckTypeSize)
-# Optionally read user configuration, generated by configure.js.
-# This is left for backward compatibility reasons only.
-INCLUDE(${CMAKE_BINARY_DIR}/win/configure.data OPTIONAL)
# avoid running system checks by using pre-cached check results
# system checks are expensive on VS since every tiny program is to be compiled in
@@ -62,7 +59,43 @@ IF(MINGW AND CMAKE_SIZEOF_VOID_P EQUAL 4)
ADD_DEFINITIONS(-march=i486)
ENDIF()
+FUNCTION(ENABLE_ASAN)
+ IF(NOT (MSVC AND CMAKE_CXX_COMPILER_ID MATCHES Clang))
+ MESSAGE(FATAL_ERROR "clang-cl is necessary to enable asan")
+ ENDIF()
+ # currently, asan is broken with static CRT.
+ IF(NOT(MSVC_CRT_TYPE STREQUAL "/MD"))
+ MESSAGE(FATAL_ERROR "-DWITH_ASAN cmake parameter also requires -DMSVC_CRT_TYPE=/MD")
+ ENDIF()
+ IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ MESSAGE(FATAL_ERROR "-DWITH_ASAN on Windows requires 64bit build")
+ ENDIF()
+ # After installation, clang lib directory should be added to PATH
+ # (e.g C:/Program Files/LLVM/lib/clang/5.0.1/lib/windows)
+ FIND_LIBRARY(CLANG_RT_ASAN_DYNAMIC clang_rt.asan_dynamic-x86_64.lib)
+ IF(NOT CLANG_RT_ASAN_DYNAMIC)
+ MESSAGE(FATAL_ERROR "Can't enable ASAN : missing clang_rt.asan_dynamic-x86_64.lib")
+ ENDIF()
+
+ FIND_LIBRARY(CLANG_RT_ASAN_DYNAMIC_THUNK clang_rt.asan_dynamic_runtime_thunk-x86_64.lib)
+ IF(NOT CLANG_RT_ASAN_DYNAMIC_THUNK)
+ MESSAGE(FATAL_ERROR "Can't enable ASAN : missing clang_rt.asan_dynamic_runtime_thunk-x86_64.lib")
+ ENDIF()
+
+ STRING(APPEND CMAKE_C_FLAGS " -fsanitize=address")
+ STRING(APPEND CMAKE_CXX_FLAGS " -fsanitize=address")
+
+ LINK_LIBRARIES(${CLANG_RT_ASAN_DYNAMIC} ${CLANG_RT_ASAN_DYNAMIC_THUNK})
+ENDFUNCTION()
+
+
IF(MSVC)
+ IF(WITH_ASAN)
+ ENABLE_ASAN()
+ ENDIF()
+
+ # Disable mingw based pkg-config found in Strawberry perl
+ SET(PKG_CONFIG_EXECUTABLE 0 CACHE INTERNAL "")
SET(MSVC_CRT_TYPE /MT CACHE STRING
"Runtime library - specify runtime library for linking (/MT,/MTd,/MD,/MDd)"
)
@@ -86,8 +119,10 @@ IF(MSVC)
# Enable debug info also in Release build,
# and create PDB to be able to analyze crashes.
FOREACH(type EXE SHARED MODULE)
- SET(CMAKE_{type}_LINKER_FLAGS_RELEASE
+ SET(CMAKE_${type}_LINKER_FLAGS_RELEASE
"${CMAKE_${type}_LINKER_FLAGS_RELEASE} /debug")
+ SET(CMAKE_${type}_LINKER_FLAGS_MINSIZEREL
+ "${CMAKE_${type}_LINKER_FLAGS_MINSIZEREL} /debug")
ENDFOREACH()
# Force static runtime libraries
@@ -108,13 +143,26 @@ IF(MSVC)
CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT
CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO
- CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG_INIT)
+ CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG_INIT
+ CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL
+ )
STRING(REGEX REPLACE "/M[TD][d]?" "${MSVC_CRT_TYPE}" "${flag}" "${${flag}}" )
STRING(REGEX REPLACE "/D[ ]?_DEBUG" "" "${flag}" "${${flag}}")
STRING(REPLACE "/Zi" "/Z7" "${flag}" "${${flag}}")
+ IF(NOT "${${flag}}" MATCHES "/Z7")
+ STRING(APPEND ${flag} " /Z7")
+ ENDIF()
ENDFOREACH()
-
-
+
+ IF(CMAKE_CXX_COMPILER_ID MATCHES Clang)
+ SET(CLANG_CL_FLAGS
+"-Wno-unused-parameter -Wno-unused-command-line-argument -Wno-pointer-sign -Wno-deprecated-register \
+-Wno-missing-braces -Wno-unused-function -msse4.2 "
+ )
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CLANG_CL_FLAGS}")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CLANG_CL_FLAGS}")
+ ENDIF()
+
# Fix CMake's predefined huge stack size
FOREACH(type EXE SHARED MODULE)
STRING(REGEX REPLACE "/STACK:([^ ]+)" "" CMAKE_${type}_LINKER_FLAGS "${CMAKE_${type}_LINKER_FLAGS}")
@@ -133,15 +181,27 @@ IF(MSVC)
ENDIF()
# Speed up multiprocessor build
- IF (MSVC_VERSION GREATER 1400)
+ IF (MSVC_VERSION GREATER 1400 AND (NOT CMAKE_CXX_COMPILER_ID MATCHES Clang))
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
ENDIF()
#TODO: update the code and remove the disabled warnings
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4800 /wd4805 /wd4996 /we4700 /we4311 /we4477 /we4302 /we4090 /wd4267 ")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800 /wd4805 /wd4996 /wd4291 /wd4577 /we4099 /we4700 /we4311 /we4477 /we4302 /we4090 /wd4267")
-
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /we4700 /we4311 /we4477 /we4302 /we4090")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /we4099 /we4700 /we4311 /we4477 /we4302 /we4090")
+ IF(MSVC_VERSION GREATER 1910 AND (NOT CMAKE_CXX_COMPILER_ID MATCHES Clang))
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-")
+ ENDIF()
+ ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_WARNINGS)
+ IF(MYSQL_MAINTAINER_MODE MATCHES "ERR")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
+ ENDIF()
+ IF(MSVC_VERSION LESS 1910)
+ # Noisy warning C4800: 'type': forcing value to bool 'true' or 'false' (performance warning),
+ # removed in VS2017
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800")
+ ENDIF()
ENDIF()
# Always link with socket library
diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake
index 1c4394d11d2..31291d263f9 100644
--- a/cmake/plugin.cmake
+++ b/cmake/plugin.cmake
@@ -230,7 +230,7 @@ MACRO(MYSQL_ADD_PLUGIN)
SET(CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} PARENT_SCOPE)
IF (NOT ARG_CLIENT)
- SET(CPACK_RPM_${ARG_COMPONENT}_PACKAGE_REQUIRES "MariaDB${ver}" PARENT_SCOPE)
+ SET(CPACK_RPM_${ARG_COMPONENT}_PACKAGE_REQUIRES "MariaDB-server${ver}" PARENT_SCOPE)
ENDIF()
# workarounds for cmake issues #13248 and #12864:
SET(CPACK_RPM_${ARG_COMPONENT}_PACKAGE_PROVIDES "cmake_bug_13248" PARENT_SCOPE)
diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake
index 65abb27923b..634ea03c3c2 100644
--- a/cmake/ssl.cmake
+++ b/cmake/ssl.cmake
@@ -129,10 +129,6 @@ MACRO (MYSQL_CHECK_SSL)
IF(OPENSSL_FOUND)
SET(OPENSSL_LIBRARY ${OPENSSL_SSL_LIBRARY})
INCLUDE(CheckSymbolExists)
- SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
- CHECK_SYMBOL_EXISTS(SHA512_DIGEST_LENGTH "openssl/sha.h"
- HAVE_SHA512_DIGEST_LENGTH)
- SET(CMAKE_REQUIRED_INCLUDES)
SET(SSL_SOURCES "")
SET(SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
IF(CMAKE_SYSTEM_NAME MATCHES "SunOS")
@@ -151,6 +147,7 @@ MACRO (MYSQL_CHECK_SSL)
SET(SSL_INTERNAL_INCLUDE_DIRS "")
SET(SSL_DEFINES "-DHAVE_OPENSSL")
+ SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
SET(CMAKE_REQUIRED_LIBRARIES ${SSL_LIBRARIES})
CHECK_SYMBOL_EXISTS(ERR_remove_thread_state "openssl/err.h"
HAVE_ERR_remove_thread_state)
@@ -158,6 +155,8 @@ MACRO (MYSQL_CHECK_SSL)
HAVE_EncryptAes128Ctr)
CHECK_SYMBOL_EXISTS(EVP_aes_128_gcm "openssl/evp.h"
HAVE_EncryptAes128Gcm)
+ SET(CMAKE_REQUIRED_INCLUDES)
+ SET(CMAKE_REQUIRED_LIBRARIES)
ELSE()
IF(WITH_SSL STREQUAL "system")
MESSAGE(SEND_ERROR "Cannot find appropriate system libraries for SSL. Use WITH_SSL=bundled to enable SSL support")
diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake
index e6d1379aea3..b5dc8b9f157 100644
--- a/cmake/wsrep.cmake
+++ b/cmake/wsrep.cmake
@@ -26,7 +26,7 @@ ENDIF()
OPTION(WITH_WSREP "WSREP replication API (to use, e.g. Galera Replication library)" ${with_wsrep_default})
# Set the patch version
-SET(WSREP_PATCH_VERSION "20")
+SET(WSREP_PATCH_VERSION "21")
# Obtain wsrep API version
FILE(STRINGS "${MySQL_SOURCE_DIR}/wsrep/wsrep_api.h" WSREP_API_VERSION
diff --git a/config.h.cmake b/config.h.cmake
index 139471ef740..4d14b621d91 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -131,6 +131,7 @@
#cmakedefine HAVE_CLOCK_GETTIME 1
#cmakedefine HAVE_CRYPT 1
#cmakedefine HAVE_CUSERID 1
+#cmakedefine HAVE_DLADDR 1
#cmakedefine HAVE_DLERROR 1
#cmakedefine HAVE_DLOPEN 1
#cmakedefine HAVE_FCHMOD 1
@@ -191,7 +192,6 @@
#cmakedefine HAVE_PREAD 1
#cmakedefine HAVE_PAUSE_INSTRUCTION 1
#cmakedefine HAVE_FAKE_PAUSE_INSTRUCTION 1
-#cmakedefine HAVE_HMT_PRIORITY_INSTRUCTION 1
#cmakedefine HAVE_RDTSCLL 1
#cmakedefine HAVE_READ_REAL_TIME 1
#cmakedefine HAVE_PTHREAD_ATTR_CREATE 1
diff --git a/configure.cmake b/configure.cmake
index 40cde3fda45..c5d1d084f0f 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -52,7 +52,7 @@ IF(NOT SYSTEM_TYPE)
ENDIF()
ENDIF()
-IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" AND (NOT MSVC))
# MySQL "canonical" GCC flags. At least -fno-rtti flag affects
# ABI and cannot be simply removed.
SET(CMAKE_CXX_FLAGS
@@ -338,6 +338,7 @@ CHECK_FUNCTION_EXISTS (cuserid HAVE_CUSERID)
CHECK_FUNCTION_EXISTS (ftruncate HAVE_FTRUNCATE)
CHECK_FUNCTION_EXISTS (compress HAVE_COMPRESS)
CHECK_FUNCTION_EXISTS (crypt HAVE_CRYPT)
+CHECK_FUNCTION_EXISTS (dladdr HAVE_DLADDR)
CHECK_FUNCTION_EXISTS (dlerror HAVE_DLERROR)
CHECK_FUNCTION_EXISTS (dlopen HAVE_DLOPEN)
CHECK_FUNCTION_EXISTS (fchmod HAVE_FCHMOD)
@@ -388,7 +389,6 @@ CHECK_FUNCTION_EXISTS (pthread_rwlock_rdlock HAVE_PTHREAD_RWLOCK_RDLOCK)
CHECK_FUNCTION_EXISTS (pthread_sigmask HAVE_PTHREAD_SIGMASK)
CHECK_FUNCTION_EXISTS (pthread_yield_np HAVE_PTHREAD_YIELD_NP)
CHECK_FUNCTION_EXISTS (putenv HAVE_PUTENV)
-CHECK_FUNCTION_EXISTS (readdir_r HAVE_READDIR_R)
CHECK_FUNCTION_EXISTS (readlink HAVE_READLINK)
CHECK_FUNCTION_EXISTS (realpath HAVE_REALPATH)
CHECK_FUNCTION_EXISTS (rename HAVE_RENAME)
@@ -425,6 +425,16 @@ IF(HAVE_SYS_EVENT_H)
CHECK_FUNCTION_EXISTS (kqueue HAVE_KQUEUE)
ENDIF()
+# readdir_r might exist, but be marked deprecated
+SET(CMAKE_REQUIRED_FLAGS -Werror)
+CHECK_CXX_SOURCE_COMPILES(
+"#include <dirent.h>
+int main() {
+ readdir_r(0,0,0);
+ return 0;
+ }" HAVE_READDIR_R)
+SET(CMAKE_REQUIRED_FLAGS)
+
#--------------------------------------------------------------------
# Support for WL#2373 (Use cycle counter for timing)
#--------------------------------------------------------------------
@@ -488,7 +498,7 @@ int main() {
#
-# Test for endianess
+# Test for endianness
#
INCLUDE(TestBigEndian)
IF(APPLE)
@@ -792,17 +802,6 @@ IF(NOT CMAKE_CROSSCOMPILING AND NOT MSVC)
}
" HAVE_FAKE_PAUSE_INSTRUCTION)
ENDIF()
- IF (NOT HAVE_PAUSE_INSTRUCTION)
- CHECK_C_SOURCE_COMPILES("
- #include <sys/platform/ppc.h>
- int main()
- {
- __ppc_set_ppr_low();
- __ppc_set_ppr_med();
- return 0;
- }
- " HAVE_HMT_PRIORITY_INSTRUCTION)
- ENDIF()
ENDIF()
CHECK_SYMBOL_EXISTS(tcgetattr "termios.h" HAVE_TCGETATTR 1)
diff --git a/dbug/dbug.c b/dbug/dbug.c
index e4125a3efea..dedc455147b 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -128,7 +128,6 @@
#define SANITY_CHECK_ON (1U << 12) /* Check memory on every DBUG_ENTER/RETURN */
#define TRACE_ON (1U << 31) /* Trace enabled. MUST be the highest bit!*/
-#define sf_sanity() (0)
#define TRACING (cs->stack->flags & TRACE_ON)
#define DEBUGGING (cs->stack->flags & DEBUG_ON)
@@ -272,6 +271,11 @@ static void PushState(CODE_STATE *cs);
static void FreeState (CODE_STATE *cs, int free_state);
/* Test for tracing enabled */
static int DoTrace(CODE_STATE *cs);
+static int default_my_dbug_sanity(void);
+
+int (*dbug_sanity)(void)= default_my_dbug_sanity;
+
+
/*
return values of DoTrace.
Can also be used as bitmask: ret & DO_TRACE
@@ -1121,7 +1125,7 @@ void _db_enter_(const char *_func_, const char *_file_,
if (!TRACING) break;
/* fall through */
case DO_TRACE:
- if ((cs->stack->flags & SANITY_CHECK_ON) && sf_sanity())
+ if ((cs->stack->flags & SANITY_CHECK_ON) && (*dbug_sanity)())
cs->stack->flags &= ~SANITY_CHECK_ON;
if (TRACING)
{
@@ -1190,7 +1194,7 @@ void _db_return_(struct _db_stack_frame_ *_stack_frame_)
if (DoTrace(cs) & DO_TRACE)
{
int org_cs_locked;
- if ((cs->stack->flags & SANITY_CHECK_ON) && sf_sanity())
+ if ((cs->stack->flags & SANITY_CHECK_ON) && (*dbug_sanity)())
cs->stack->flags &= ~SANITY_CHECK_ON;
if (TRACING)
{
@@ -2248,6 +2252,12 @@ const char* _db_get_func_(void)
return cs->func;
}
+
+static int default_my_dbug_sanity(void)
+{
+ return 0;
+}
+
#else
/*
diff --git a/debian/additions/debian-start.inc.sh b/debian/additions/debian-start.inc.sh
index cfe51936613..0640bf9c2a6 100755
--- a/debian/additions/debian-start.inc.sh
+++ b/debian/additions/debian-start.inc.sh
@@ -72,7 +72,7 @@ function check_root_accounts() {
logger -p daemon.info -i -t$0 "Checking for insecure root accounts."
- ret=$( echo "SELECT count(*) FROM mysql.user WHERE user='root' and password='';" | $MYSQL --skip-column-names )
+ ret=$( echo "SELECT count(*) FROM mysql.user WHERE user='root' and password='' and plugin in ('', 'mysql_native_password', 'mysql_old_password');" | $MYSQL --skip-column-names )
if [ "$ret" -ne "0" ]; then
logger -p daemon.warn -i -t$0 "WARNING: mysql.user contains $ret root accounts without password!"
fi
diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh
index d3c825a02b5..d43f8dbec4a 100755
--- a/debian/autobake-deb.sh
+++ b/debian/autobake-deb.sh
@@ -6,16 +6,11 @@
# Exit immediately on any error
set -e
-# On Buildbot, don't run the mysql-test-run test suite as part of build.
-# It takes a lot of time, and we will do a better test anyway in
-# Buildbot, running the test suite from installed .debs on a clean VM.
-# On Travis-CI we want to simulate the full build, including tests.
-# Also on Travis-CI it is useful not to override the DEB_BUILD_OPTIONS
-# at this stage at all.
-if [[ ! $TRAVIS ]]
-then
- export DEB_BUILD_OPTIONS="nocheck"
-fi
+# This file is invocated from Buildbot and Travis-CI to build deb packages.
+# As both of those CI systems have many parallel jobs that include different
+# parts of the test suite, we don't need to run the mysql-test-run at all when
+# building the deb packages here.
+export DEB_BUILD_OPTIONS="nocheck $DEB_BUILD_OPTIONS"
# Travis-CI optimizations
if [[ $TRAVIS ]]
@@ -26,13 +21,19 @@ then
# Don't include test suite package on Travis-CI to make the build time shorter
sed '/Package: mariadb-test-data/,+28d' -i debian/control
sed '/Package: mariadb-test/,+36d' -i debian/control
+
+ # Don't build the test package at all to save time and disk space
+ sed 's|DINSTALL_MYSQLTESTDIR=share/mysql/mysql-test|DINSTALL_MYSQLTESTDIR=false|' -i debian/rules
+
+ # Also skip building RocksDB and TokuDB to save even more time and disk space
+ sed 's|-DDEB|-DWITHOUT_TOKUDB_STORAGE_ENGINE=true -DWITHOUT_MROONGA_STORAGE_ENGINE=true -DWITHOUT_ROCKSDB_STORAGE_ENGINE=true -DDEB|' -i debian/rules
fi
# Look up distro-version specific stuff
#
# Always keep the actual packaging as up-to-date as possible following the latest
-# Debian policy and targetting Debian Sid. Then case-by-case run in autobake-deb.sh
+# Debian policy and targeting Debian Sid. Then case-by-case run in autobake-deb.sh
# tests for backwards compatibility and strip away parts on older builders.
# If iproute2 is not available (before Debian Jessie and Ubuntu Trusty)
@@ -74,18 +75,30 @@ fi
# Convert gcc version to numberical value. Format is Mmmpp where M is Major
# version, mm is minor version and p is patch.
-GCCVERSION=$(gcc -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$/&00/')
+# -dumpfullversion & -dumpversion to make it uniform across old and new (>=7)
+GCCVERSION=$(gcc -dumpfullversion -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' \
+ -e 's/\.\([0-9]\)/0\1/g' \
+ -e 's/^[0-9]\{3,4\}$/&00/')
# Don't build rocksdb package if gcc version is less than 4.8 or we are running on
# x86 32 bit.
-if [[ $GCCVERSION -lt 40800 ]] || [[ $(arch) =~ i[346]86 ]]
+if [[ $GCCVERSION -lt 40800 ]] || [[ $(arch) =~ i[346]86 ]] || [[ $TRAVIS ]]
then
- sed '/Package: mariadb-plugin-rocksdb/,+11d' -i debian/control
+ sed '/Package: mariadb-plugin-rocksdb/,+14d' -i debian/control
fi
-if [[ $GCCVERSION -lt 40800 ]]
+
+# AWS SDK requires c++11 -capable compiler
+# Minimal supported versions are g++ 4.8 and clang 3.3.
+if [[ $GCCVERSION -lt 40800 ]] || [[ $TRAVIS ]]
then
- sed '/Package: mariadb-plugin-aws-key-management-10.2/,+13d' -i debian/control
+ sed '/Package: mariadb-plugin-aws-key-management/,+14d' -i debian/control
fi
+# Mroonga, TokuDB never built on Travis CI anyway, see build flags above
+if [[ $TRAVIS ]]
+then
+ sed -i -e "/Package: mariadb-plugin-tokudb/,+17d" debian/control
+ sed -i -e "/Package: mariadb-plugin-mroonga/,+16d" debian/control
+fi
# Adjust changelog, add new version
echo "Incrementing changelog and starting build scripts"
@@ -101,12 +114,20 @@ dch -b -D ${CODENAME} -v "${UPSTREAM}${PATCHLEVEL}~${CODENAME}" "Automatic build
echo "Creating package version ${UPSTREAM}${PATCHLEVEL}~${CODENAME} ... "
+# On Travis CI, use -b to build binary only packages as there is no need to
+# waste time on generating the source package.
+if [[ $TRAVIS ]]
+then
+ BUILDPACKAGE_FLAGS="-b"
+fi
+
# Build the package
# Pass -I so that .git and other unnecessary temporary and source control files
# will be ignored by dpkg-source when creating the tar.gz source package.
-# Use -b to build binary only packages as there is no need to waste time on
-# generating the source package.
-fakeroot dpkg-buildpackage -us -uc -I -b
+fakeroot dpkg-buildpackage -us -uc -I $BUILDPACKAGE_FLAGS
+
+# If the step above fails due to missing dependencies, you can manually run
+# sudo mk-build-deps debian/control -r -i
# Don't log package contents on Travis-CI to save time and log size
if [[ ! $TRAVIS ]]
diff --git a/debian/control b/debian/control
index 5f41323bb63..a02a25ccc5f 100644
--- a/debian/control
+++ b/debian/control
@@ -13,17 +13,17 @@ Build-Depends: bison,
libaio-dev [linux-any],
libboost-dev,
libcrack2-dev (>= 2.9.0),
+ libcurl3-dev,
libjemalloc-dev (>= 3.0.0~) [linux-any],
libjudy-dev,
libkrb5-dev,
- libcurl3-dev,
libncurses5-dev (>= 5.0-6~),
libnuma-dev,
libpam0g-dev,
libpcre3-dev (>= 2:8.35-3.2~),
libreadline-gplv2-dev,
- libssl-dev | libssl1.0-dev,
libsnappy-dev,
+ libssl-dev | libssl1.0-dev,
libsystemd-dev,
libxml2-dev,
lsb-release,
@@ -38,86 +38,157 @@ Homepage: http://mariadb.org/
Vcs-Git: https://github.com/MariaDB/server.git
Vcs-Browser: https://github.com/MariaDB/server/
+Package: libmariadb-dev
+Architecture: any
+Section: libdevel
+Depends: libmariadb3 (= ${binary:Version}),
+ zlib1g-dev,
+ ${misc:Depends},
+ ${shlibs:Depends}
+Breaks: libmariadbclient-dev
+Replaces: libmariadbclient-dev
+Conflicts: libmariadbclient16-dev
+Provides: libmariadbclient-dev
+Description: MariaDB database development files
+ MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
+ server. SQL (Structured Query Language) is the most popular database query
+ language in the world. The main goals of MariaDB are speed, robustness and
+ ease of use.
+ .
+ This package includes development libraries and header files. To allow sources
+ expecting the MariaDB Connector/C to build. Sources that expect the MySQL
+ Client libraries should use files from the libmariadb-dev-compat package.
+
+Package: libmariadb-dev-compat
+Architecture: any
+Multi-Arch: same
+Section: libdevel
+Priority: extra
+Depends: libmariadb-dev (= ${binary:Version}),
+ ${misc:Depends}
+Conflicts: libmariadb-client-lgpl-dev-compat,
+ libmariadbclient-dev-compat,
+ libmysqlclient-dev,
+ libmysqlclient10-dev,
+ libmysqlclient12-dev,
+ libmysqlclient14-dev,
+ libmysqlclient15-dev,
+ libmysqlclient16-dev
+Provides: libmariadb-client-lgpl-dev-compat,
+ libmariadbclient-dev-compat,
+ libmysqlclient-dev
+Replaces: libmariadb-client-lgpl-dev-compat,
+ libmariadbclient-dev-compat,
+ libmysqlclient-dev
+Description: MariaDB Connector/C, compatibility symlinks
+ MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
+ server. SQL (Structured Query Language) is the most popular database query
+ language in the world. The main goals of MariaDB are speed, robustness and
+ ease of use.
+ .
+ This package includes compatibility symlinks to allow sources expecting the
+ MySQL client libraries to be built against MariaDB Connector/C.
+
Package: libmariadb3
Architecture: any
Section: libs
-Depends: mariadb-common, ${misc:Depends}, ${shlibs:Depends}
-Conflicts: mariadb-galera-server-10.0 (<< 10.0.5),
+Depends: mariadb-common,
+ ${misc:Depends},
+ ${shlibs:Depends}
+Conflicts: libmariadbclient18 (<< 10.2.0),
+ mariadb-galera-server-10.0 (<< 10.0.5),
mariadb-galera-server-5.5 (<< 5.5.33),
mariadb-server-10.0 (<< 10.0.5),
mariadb-server-5.1,
mariadb-server-5.2,
mariadb-server-5.3,
- mariadb-server-5.5 (<< 5.5.33),
- libmariadbclient18 (<< 10.2.0)
+ mariadb-server-5.5 (<< 5.5.33)
+Description: MariaDB database client library
+ MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
+ server. SQL (Structured Query Language) is the most popular database query
+ language in the world. The main goals of MariaDB are speed, robustness and
+ ease of use.
+ .
+ This package includes the client library.
+
+Package: libmariadb3-compat
+Architecture: any
+Section: libs
+Depends: libmariadb3,
+ mariadb-common,
+ ${misc:Depends},
+ ${shlibs:Depends}
+Breaks: libmysqlclient19,
+ libmysqlclient20
Replaces: libmysqlclient19,
libmysqlclient20
Provides: libmysqlclient19,
libmysqlclient20
-Description: MariaDB database client library
+Description: MariaDB database client library MySQL compat package
MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
server. SQL (Structured Query Language) is the most popular database query
language in the world. The main goals of MariaDB are speed, robustness and
ease of use.
.
- This package includes the client library.
+ This package includes the client runtime libraries that simulate and replace
+ the equivalents found in MySQL 5.6 and 5.7 (mysqlclient19 and 20).
Package: libmariadbclient18
Section: libs
Architecture: any
-Depends: libmariadb3 (= ${binary:Version}), ${misc:Depends}
+Depends: libmariadb3 (= ${binary:Version}),
+ ${misc:Depends}
Replaces: libmariadbclient18
Provides: libmariadbclient18
-Description: Virtual package to satisfy external depends
+Description: Virtual package to satisfy external libmariadbclient18 depends
MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
server. SQL (Structured Query Language) is the most popular database query
language in the world. The main goals of MariaDB are speed, robustness and
ease of use.
.
- This package provides compatibility symlinks for libmariadb3
+ This package provides compatibility symlinks for binaries that expect to find
+ libmariadbclient.so.18 will automatically use libmariadb.so.3 instead.
Package: libmysqlclient18
Section: libs
Architecture: any
-Depends: libmariadb3 (= ${binary:Version}), ${misc:Depends}
+Depends: libmariadb3 (= ${binary:Version}),
+ ${misc:Depends}
Replaces: libmysqlclient18
Provides: libmysqlclient18
-Description: Virtual package to satisfy external depends
+Description: Virtual package to satisfy external libmysqlclient18 depends
MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
server. SQL (Structured Query Language) is the most popular database query
language in the world. The main goals of MariaDB are speed, robustness and
ease of use.
.
- This package provides compatibility symlinks for libmariadb3
+ This package provides compatibility symlinks for binaries that expect to find
+ libmysqlclient.so.18 will automatically use libmariadb.so.3 instead.
-Package: libmariadb-dev
+Package: libmariadbd-dev
Architecture: any
Section: libdevel
-Depends: libmariadb3 (= ${binary:Version}),
- zlib1g-dev,
+Provides: libmysqld-dev
+Pre-Depends: ${misc:Pre-Depends}
+Depends: libmariadb-dev (= ${binary:Version}),
+ libmariadbd19 (= ${binary:Version}),
${misc:Depends},
${shlibs:Depends}
-Breaks: libmariadbclient-dev, libmysqlclient-dev
-Replaces: libmariadbclient-dev, libmysqlclient-dev
-Conflicts: libmariadbclient16-dev,
- libmysqlclient10-dev,
- libmysqlclient12-dev,
- libmysqlclient14-dev,
- libmysqlclient15-dev,
- libmysqlclient16-dev
-Provides: libmariadbclient-dev, libmariadbclient-dev-compat, libmysqlclient-dev
-Description: MariaDB database development files
+Breaks: libmysqld-dev
+Replaces: libmysqld-dev
+Description: MariaDB embedded database, development files
MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
server. SQL (Structured Query Language) is the most popular database query
language in the world. The main goals of MariaDB are speed, robustness and
ease of use.
.
- This package includes development libraries and header files.
+ This package includes the embedded server library development and header files.
Package: libmariadbd19
Architecture: any
Section: libs
-Depends: ${misc:Depends}, ${shlibs:Depends}
+Depends: ${misc:Depends},
+ ${shlibs:Depends}
Multi-Arch: same
Breaks: libmariadbd-dev (<< ${source:Version})
Replaces: libmariadbd-dev (<< ${source:Version})
@@ -129,28 +200,10 @@ Description: MariaDB embedded database, shared library
.
This package includes a shared library for embedded MariaDB applications
-Package: libmariadbd-dev
-Architecture: any
-Section: libdevel
-Provides: libmysqld-dev
-Pre-Depends: ${misc:Pre-Depends}
-Depends: libmariadb-dev (= ${binary:Version}),
- libmariadbd19 (= ${binary:Version}),
- ${misc:Depends},
- ${shlibs:Depends}
-Breaks: libmysqld-dev
-Replaces: libmysqld-dev
-Description: MariaDB embedded database, development files
- MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
- server. SQL (Structured Query Language) is the most popular database query
- language in the world. The main goals of MariaDB are speed, robustness and
- ease of use.
- .
- This package includes the embedded server library development and header files.
-
Package: mysql-common
Architecture: all
-Depends: ${misc:Depends}, ${shlibs:Depends}
+Depends: ${misc:Depends},
+ ${shlibs:Depends}
Description: MariaDB database common files (e.g. /etc/mysql/my.cnf)
MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
server. SQL (Structured Query Language) is the most popular database query
@@ -162,7 +215,9 @@ Description: MariaDB database common files (e.g. /etc/mysql/my.cnf)
Package: mariadb-common
Architecture: all
-Depends: mysql-common, ${misc:Depends}, ${shlibs:Depends}
+Depends: mysql-common,
+ ${misc:Depends},
+ ${shlibs:Depends}
Description: MariaDB database common files (e.g. /etc/mysql/conf.d/mariadb.cnf)
MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
server. SQL (Structured Query Language) is the most popular database query
@@ -284,7 +339,9 @@ Provides: default-mysql-client,
mysql-client-5.6,
mysql-client-5.7,
virtual-mysql-client
-Recommends: libdbd-mysql-perl (>= 1.2202), libdbi-perl, libterm-readkey-perl
+Recommends: libdbd-mysql-perl (>= 1.2202),
+ libdbi-perl,
+ libterm-readkey-perl
Description: MariaDB database client binaries
MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
server. SQL (Structured Query Language) is the most popular database query
@@ -353,9 +410,14 @@ Description: MariaDB database core server files
Package: mariadb-server-10.3
Architecture: any
-Suggests: mailx, mariadb-test, netcat-openbsd, tinyca
+Suggests: mailx,
+ mariadb-test,
+ netcat-openbsd,
+ tinyca
Recommends: libhtml-template-perl
-Pre-Depends: adduser (>= 3.40), debconf, mariadb-common (>= ${source:Version})
+Pre-Depends: adduser (>= 3.40),
+ debconf,
+ mariadb-common (>= ${source:Version})
Depends: bsdutils,
coreutils,
findutils,
@@ -416,7 +478,8 @@ Replaces: libmariadbclient-dev (<< 5.5.0),
mysql-server-5.6,
mysql-server-5.7,
virtual-mysql-server
-Provides: default-mysql-server, virtual-mysql-server
+Provides: default-mysql-server,
+ virtual-mysql-server
Description: MariaDB database server binaries
MariaDB is a fast, stable and true multi-user, multi-threaded SQL database
server. SQL (Structured Query Language) is the most popular database query
@@ -427,7 +490,8 @@ Description: MariaDB database server binaries
Package: mariadb-server
Architecture: all
-Depends: mariadb-server-10.3 (>= ${source:Version}), ${misc:Depends}
+Depends: mariadb-server-10.3 (>= ${source:Version}),
+ ${misc:Depends}
Description: MariaDB database server (metapackage depending on the latest version)
This is an empty package that depends on the current "best" version of
mariadb-server (currently mariadb-server-10.3), as determined by the MariaDB
@@ -442,7 +506,8 @@ Description: MariaDB database server (metapackage depending on the latest versio
Package: mariadb-client
Architecture: all
-Depends: mariadb-client-10.3 (>= ${source:Version}), ${misc:Depends}
+Depends: mariadb-client-10.3 (>= ${source:Version}),
+ ${misc:Depends}
Description: MariaDB database client (metapackage depending on the latest version)
This is an empty package that depends on the current "best" version of
mariadb-client (currently mariadb-client-10.3), as determined by the MariaDB
@@ -452,7 +517,7 @@ Description: MariaDB database client (metapackage depending on the latest versio
Package: mariadb-plugin-connect
Architecture: any
Depends: libxml2,
- mariadb-server-10.3,
+ mariadb-server-10.3 (= ${binary:Version}),
unixodbc,
${misc:Depends},
${shlibs:Depends}
@@ -470,11 +535,14 @@ Description: Connect storage engine for MariaDB
Package: mariadb-plugin-rocksdb
Architecture: any
-Depends: mariadb-server-10.3, ${misc:Depends}, ${shlibs:Depends}
+Depends: mariadb-server-10.3 (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends}
Breaks: mariadb-rocksdb-engine-10.2,
mariadb-rocksdb-engine-10.3
Replaces: mariadb-rocksdb-engine-10.2,
mariadb-rocksdb-engine-10.3
+Recommends: python-mysqldb
Description: RocksDB storage engine for MariaDB
The RocksDB storage engine is a high performance storage engine, aimed
at maximising storage efficiency while maintaining InnoDB-like performance.
@@ -482,7 +550,10 @@ Description: RocksDB storage engine for MariaDB
Package: mariadb-plugin-oqgraph
Architecture: any
-Depends: libjudydebian1, mariadb-server-10.3, ${misc:Depends}, ${shlibs:Depends}
+Depends: libjudydebian1,
+ mariadb-server-10.3 (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends}
Breaks: mariadb-oqgraph-engine-10.1,
mariadb-oqgraph-engine-10.2,
mariadb-oqgraph-engine-10.3
@@ -495,8 +566,10 @@ Description: OQGraph storage engine for MariaDB
This package contains the OQGraph plugin for MariaDB.
Package: mariadb-plugin-tokudb
-Architecture: any
-Depends: mariadb-server-10.3, ${misc:Depends}, ${shlibs:Depends}
+Architecture: amd64
+Depends: mariadb-server-10.3 (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends}
Breaks: mariadb-server-10.0,
mariadb-server-10.1,
mariadb-server-10.2,
@@ -512,8 +585,10 @@ Description: TokuDB storage engine for MariaDB
This package contains the TokuDB plugin for MariaDB.
Package: mariadb-plugin-mroonga
-Architecture: any
-Depends: mariadb-server-10.3, ${misc:Depends}, ${shlibs:Depends}
+Architecture: any-alpha any-amd64 any-arm any-arm64 any-i386 any-ia64 any-mips64el any-mips64r6el any-mipsel any-mipsr6el any-nios2 any-powerpcel any-ppc64el any-sh3 any-sh4 any-tilegx
+Depends: mariadb-server-10.3 (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends}
Breaks: mariadb-server-10.0,
mariadb-server-10.1,
mariadb-server-10.2,
@@ -529,7 +604,9 @@ Description: Mroonga storage engine for MariaDB
Package: mariadb-plugin-spider
Architecture: any
-Depends: mariadb-server-10.3, ${misc:Depends}, ${shlibs:Depends}
+Depends: mariadb-server-10.3 (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends}
Breaks: mariadb-server-10.0,
mariadb-server-10.1,
mariadb-server-10.2,
@@ -546,7 +623,9 @@ Description: Spider storage engine for MariaDB
Package: mariadb-plugin-cassandra
Architecture: any
-Depends: mariadb-server-10.3, ${misc:Depends}, ${shlibs:Depends}
+Depends: mariadb-server-10.3 (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends}
Breaks: mariadb-server-10.0,
mariadb-server-10.1,
mariadb-server-10.2,
@@ -576,6 +655,7 @@ Replaces: mariadb-gssapi-server-10.1,
mariadb-gssapi-server-10.2,
mariadb-gssapi-server-10.3
Description: GSSAPI authentication plugin for MariaDB server
+ This package contains the server components.
Package: mariadb-plugin-gssapi-client
Architecture: any
@@ -590,18 +670,19 @@ Replaces: mariadb-gssapi-client-10.1,
mariadb-gssapi-client-10.2,
mariadb-gssapi-client-10.3
Description: GSSAPI authentication plugin for MariaDB client
+ This package contains the client components.
Package: mariadb-backup-10.3
-Section: database
Architecture: any
Breaks: mariadb-backup-10.1,
mariadb-backup-10.2
Replaces: mariadb-backup-10.1,
- mariadb-backup-10.2
+ mariadb-backup-10.2
Depends: mariadb-server-10.3,
${misc:Depends},
${shlibs:Depends}
Description: Backup tool for MariaDB server
+ This backup tool is guaranteed to be compatible with MariaDB.
Package: mariadb-plugin-cracklib-password-check
Architecture: any
@@ -613,15 +694,14 @@ Description: CrackLib Password Validation Plugin for MariaDB
This password validation plugin uses cracklib to allow only
sufficiently secure (as defined by cracklib) user passwords in MariaDB.
-Package: mariadb-plugin-aws-key-management-10.3
-Section: database
+Package: mariadb-plugin-aws-key-management
Architecture: any
Breaks: mariadb-aws-key-management-10.1,
mariadb-aws-key-management-10.2
Replaces: mariadb-aws-key-management-10.1,
mariadb-aws-key-management-10.2
-Depends: mariadb-server-10.3,
- libcurl3,
+Depends: libcurl3,
+ mariadb-server-10.3,
${misc:Depends},
${shlibs:Depends}
Description: Amazon Web Service Key Management Service Plugin for MariaDB
diff --git a/debian/libmariadb-dev-compat.install b/debian/libmariadb-dev-compat.install
new file mode 100644
index 00000000000..7fe10c50f69
--- /dev/null
+++ b/debian/libmariadb-dev-compat.install
@@ -0,0 +1,4 @@
+usr/lib/*/libmysqlclient.a
+usr/lib/*/libmysqlclient.so
+usr/lib/*/libmysqlclient_r.a
+usr/lib/*/libmysqlclient_r.so
diff --git a/debian/libmariadb-dev-compat.links b/debian/libmariadb-dev-compat.links
new file mode 100644
index 00000000000..11e0dbce225
--- /dev/null
+++ b/debian/libmariadb-dev-compat.links
@@ -0,0 +1,3 @@
+usr/bin/mariadb_config usr/bin/mysql_config
+usr/include/mariadb usr/include/mysql
+usr/share/pkgconfig/mariadb.pc usr/share/pkgconfig/mysqlclient.pc
diff --git a/debian/libmariadb-dev.install b/debian/libmariadb-dev.install
index e62aad1b43f..72798dec379 100644
--- a/debian/libmariadb-dev.install
+++ b/debian/libmariadb-dev.install
@@ -1,9 +1,9 @@
-usr/bin/mysql_config
-usr/include/mysql
+usr/bin/mariadb_config
+usr/include/mariadb
usr/lib/*/libmariadb.so
-usr/lib/*/libmysqlclient.so
-usr/lib/*/libmariadbclient.so
usr/lib/*/libmariadbclient.a
+usr/lib/*/libmariadbclient.so
usr/lib/*/libmysqlservices.a
usr/share/aclocal/mysql.m4
+usr/share/man/man1/mysql_config.1
usr/share/pkgconfig/mariadb.pc
diff --git a/debian/libmariadb-dev.links b/debian/libmariadb-dev.links
new file mode 100644
index 00000000000..6a7bf707ca7
--- /dev/null
+++ b/debian/libmariadb-dev.links
@@ -0,0 +1 @@
+usr/share/man/man1/mysql_config.1.gz usr/share/man/man1/mariadb_config.1.gz
diff --git a/debian/libmariadb-dev.manpages b/debian/libmariadb-dev.manpages
deleted file mode 100644
index 3aac7f4b4a9..00000000000
--- a/debian/libmariadb-dev.manpages
+++ /dev/null
@@ -1 +0,0 @@
-debian/tmp/usr/share/man/man1/mysql_config.1
diff --git a/debian/libmariadb3-compat.install b/debian/libmariadb3-compat.install
new file mode 100644
index 00000000000..4e0d631d6c8
--- /dev/null
+++ b/debian/libmariadb3-compat.install
@@ -0,0 +1,2 @@
+usr/lib/*/libmysqlclient.so.19
+usr/lib/*/libmysqlclient.so.20
diff --git a/debian/libmariadb3.install b/debian/libmariadb3.install
index 58e2bd1dcb2..8636166a493 100644
--- a/debian/libmariadb3.install
+++ b/debian/libmariadb3.install
@@ -1,5 +1,5 @@
-usr/lib/*/libmysqlclient.so.19
-usr/lib/*/libmysqlclient.so.20
usr/lib/*/libmariadb.so.*
+usr/lib/mysql/plugin/client_ed25519.so
usr/lib/mysql/plugin/dialog.so
usr/lib/mysql/plugin/mysql_clear_password.so
+usr/lib/mysql/plugin/sha256_password.so
diff --git a/debian/libmariadbd-dev.install b/debian/libmariadbd-dev.install
index 6fe225b15ba..2c14af5ab31 100644
--- a/debian/libmariadbd-dev.install
+++ b/debian/libmariadbd-dev.install
@@ -1,3 +1,4 @@
-usr/bin/mariadb_config
usr/lib/*/libmysqld.a
+usr/lib/*/libmariadbd.a
usr/lib/*/libmysqld.so
+usr/lib/*/libmariadbd.so
diff --git a/debian/libmariadbd19.install b/debian/libmariadbd19.install
index fb5f4771734..cb627204432 100644
--- a/debian/libmariadbd19.install
+++ b/debian/libmariadbd19.install
@@ -1 +1 @@
-usr/lib/*/libmysqld.so.*
+usr/lib/*/libmariadbd.so.*
diff --git a/debian/mariadb-backup-10.3.files b/debian/mariadb-backup-10.3.install
index 734117c92e2..734117c92e2 100644
--- a/debian/mariadb-backup-10.3.files
+++ b/debian/mariadb-backup-10.3.install
diff --git a/debian/mariadb-client-10.3.README.Debian b/debian/mariadb-client-10.3.README.Debian
index b245638f9c9..64f0f509951 100644
--- a/debian/mariadb-client-10.3.README.Debian
+++ b/debian/mariadb-client-10.3.README.Debian
@@ -1,4 +1,4 @@
FAQ:
-Q: My <tab> completition is gone, why?
+Q: My <tab> completion is gone, why?
A: You have "no-auto-rehash" in the "[mysql]" section of /etc/mysql/my.cnf!
diff --git a/debian/mariadb-client-10.3.docs b/debian/mariadb-client-10.3.docs
index 8117d689011..c09092629c3 100644
--- a/debian/mariadb-client-10.3.docs
+++ b/debian/mariadb-client-10.3.docs
@@ -1,2 +1,2 @@
-debian/additions/innotop/changelog.innotop
README.md
+debian/additions/innotop/changelog.innotop
diff --git a/debian/mariadb-client-10.3.install b/debian/mariadb-client-10.3.install
index 271f2a2f417..945bf77c689 100644
--- a/debian/mariadb-client-10.3.install
+++ b/debian/mariadb-client-10.3.install
@@ -10,3 +10,13 @@ usr/bin/mysqldumpslow
usr/bin/mysqlimport
usr/bin/mysqlshow
usr/bin/mysqlslap
+usr/share/man/man1/mysql_find_rows.1
+usr/share/man/man1/mysql_fix_extensions.1
+usr/share/man/man1/mysql_waitpid.1
+usr/share/man/man1/mysqlaccess.1
+usr/share/man/man1/mysqladmin.1
+usr/share/man/man1/mysqldump.1
+usr/share/man/man1/mysqldumpslow.1
+usr/share/man/man1/mysqlimport.1
+usr/share/man/man1/mysqlshow.1
+usr/share/man/man1/mysqlslap.1
diff --git a/debian/mariadb-client-10.3.links b/debian/mariadb-client-10.3.links
index 0b86e87f2e9..4a504969246 100644
--- a/debian/mariadb-client-10.3.links
+++ b/debian/mariadb-client-10.3.links
@@ -1,6 +1,6 @@
-usr/bin/mysqlcheck usr/bin/mysqlrepair
usr/bin/mysqlcheck usr/bin/mysqlanalyze
usr/bin/mysqlcheck usr/bin/mysqloptimize
-usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mysqlrepair.1.gz
+usr/bin/mysqlcheck usr/bin/mysqlrepair
usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mysqlanalyze.1.gz
usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mysqloptimize.1.gz
+usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mysqlrepair.1.gz
diff --git a/debian/mariadb-client-10.3.manpages b/debian/mariadb-client-10.3.manpages
index 504619785bc..6f3e2bc188c 100644
--- a/debian/mariadb-client-10.3.manpages
+++ b/debian/mariadb-client-10.3.manpages
@@ -1,12 +1,2 @@
debian/additions/innotop/innotop.1
-debian/tmp/usr/share/man/man1/mysqlaccess.1
-debian/tmp/usr/share/man/man1/mysqladmin.1
-debian/tmp/usr/share/man/man1/mysqldump.1
-debian/tmp/usr/share/man/man1/mysqldumpslow.1
-debian/tmp/usr/share/man/man1/mysql_find_rows.1
-debian/tmp/usr/share/man/man1/mysql_fix_extensions.1
-debian/tmp/usr/share/man/man1/mysqlimport.1
debian/additions/mysqlreport.1
-debian/tmp/usr/share/man/man1/mysqlshow.1
-debian/tmp/usr/share/man/man1/mysqlslap.1
-debian/tmp/usr/share/man/man1/mysql_waitpid.1
diff --git a/debian/mariadb-client-core-10.3.install b/debian/mariadb-client-core-10.3.install
index 6308d769930..a2781309439 100644
--- a/debian/mariadb-client-core-10.3.install
+++ b/debian/mariadb-client-core-10.3.install
@@ -1,2 +1,4 @@
usr/bin/mysql
usr/bin/mysqlcheck
+usr/share/man/man1/mysql.1
+usr/share/man/man1/mysqlcheck.1
diff --git a/debian/mariadb-client-core-10.3.manpages b/debian/mariadb-client-core-10.3.manpages
deleted file mode 100644
index 2be91d81f9a..00000000000
--- a/debian/mariadb-client-core-10.3.manpages
+++ /dev/null
@@ -1,2 +0,0 @@
-debian/tmp/usr/share/man/man1/mysql.1
-debian/tmp/usr/share/man/man1/mysqlcheck.1
diff --git a/debian/mariadb-common.install b/debian/mariadb-common.install
index 78dbc22b9f6..611c7d4d36e 100644
--- a/debian/mariadb-common.install
+++ b/debian/mariadb-common.install
@@ -1 +1 @@
-debian/additions/mariadb.cnf etc/mysql/conf.d
+debian/additions/mariadb.cnf etc/mysql/
diff --git a/debian/mariadb-plugin-aws-key-management-10.2.install b/debian/mariadb-plugin-aws-key-management-10.2.install
deleted file mode 100644
index ed966b4115d..00000000000
--- a/debian/mariadb-plugin-aws-key-management-10.2.install
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/lib/mysql/plugin/aws_key_management.so
-debian/additions/enable_encryption.preset etc/mysql/conf.d/
diff --git a/debian/mariadb-plugin-aws-key-management.install b/debian/mariadb-plugin-aws-key-management.install
new file mode 100644
index 00000000000..199d4c87950
--- /dev/null
+++ b/debian/mariadb-plugin-aws-key-management.install
@@ -0,0 +1,3 @@
+debian/additions/enable_encryption.preset etc/mysql/mariadb.conf.d
+etc/mysql/conf.d/aws_key_management.cnf etc/mysql/mariadb.conf.d
+usr/lib/mysql/plugin/aws_key_management.so
diff --git a/debian/mariadb-plugin-connect.install b/debian/mariadb-plugin-connect.install
index 8a7aee412df..22d73c7df05 100644
--- a/debian/mariadb-plugin-connect.install
+++ b/debian/mariadb-plugin-connect.install
@@ -1,2 +1,2 @@
-etc/mysql/conf.d/connect.cnf
+etc/mysql/conf.d/connect.cnf etc/mysql/mariadb.conf.d
usr/lib/mysql/plugin/ha_connect.so
diff --git a/debian/mariadb-plugin-mroonga.install b/debian/mariadb-plugin-mroonga.install
index c28fde2fd18..fedcf62eef0 100644
--- a/debian/mariadb-plugin-mroonga.install
+++ b/debian/mariadb-plugin-mroonga.install
@@ -1,3 +1,5 @@
usr/lib/mysql/plugin/ha_mroonga.so
+usr/share/mysql/mroonga/AUTHORS
+usr/share/mysql/mroonga/COPYING
usr/share/mysql/mroonga/install.sql
usr/share/mysql/mroonga/uninstall.sql
diff --git a/debian/mariadb-plugin-rocksdb.install b/debian/mariadb-plugin-rocksdb.install
index ee45a822e0c..b9a6f7dc432 100644
--- a/debian/mariadb-plugin-rocksdb.install
+++ b/debian/mariadb-plugin-rocksdb.install
@@ -1,4 +1,5 @@
etc/mysql/conf.d/rocksdb.cnf etc/mysql/mariadb.conf.d
-usr/lib/mysql/plugin/ha_rocksdb.so
usr/bin/mysql_ldb
+usr/bin/myrocks_hotbackup
usr/bin/sst_dump
+usr/lib/mysql/plugin/ha_rocksdb.so
diff --git a/debian/mariadb-plugin-tokudb.install b/debian/mariadb-plugin-tokudb.install
index 3c366ee0c44..d15db03b3e5 100644
--- a/debian/mariadb-plugin-tokudb.install
+++ b/debian/mariadb-plugin-tokudb.install
@@ -1,4 +1,7 @@
etc/mysql/conf.d/tokudb.cnf etc/mysql/mariadb.conf.d
+usr/bin/tokuft_logprint
usr/bin/tokuftdump
usr/lib/mysql/plugin/ha_tokudb.so
usr/share/doc/mariadb-server-10.3/README.md usr/share/doc/mariadb-plugin-tokudb/README.md
+usr/share/man/man1/tokuft_logdump.1
+usr/share/man/man1/tokuftdump.1
diff --git a/debian/mariadb-server-10.3.README.Debian b/debian/mariadb-server-10.3.README.Debian
index be2e33d705d..ca81cc357c4 100644
--- a/debian/mariadb-server-10.3.README.Debian
+++ b/debian/mariadb-server-10.3.README.Debian
@@ -42,7 +42,7 @@ https://mariadb.com/kb
It is strongly recommended you create an admin users for your database
adminstration needs.
-If your your local unix account is the one you want to have local super user
+If your local unix account is the one you want to have local super user
access on your database with you can create the following account that will
only work for the local unix user connecting to the database locally.
@@ -57,14 +57,14 @@ the DB server over the network:
sudo /usr/bin/mysql -e "GRANT ALL ON *.* TO 'USERNAME'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION"
-Scripts should run as a user have have the required grants and be identified via unix_socket.
+Scripts should run as a user have the required grants and be identified via unix_socket.
If you are too tired to type the password in every time and unix_socket auth
doesn't suit your needs, you can store it in the file $HOME/.my.cnf. It should
-be chmod 0600 (-rw------- username username .my.cnf) to ensure that nobody else
+be chmod 0600 (-rw------- username usergroup .my.cnf) to ensure that nobody else
can read it. Every other configuration parameter can be stored there, too.
-For more information in the MariaDB manual in/usr/share/doc/mariadb-doc or
+For more information in the MariaDB manual in/usr/share/doc/mariadb-doc or
https://mariadb.com/kb/en/configuring-mariadb-with-mycnf/.
ATTENTION: It is necessary, that a ~/.my.cnf from root always contains a "user"
diff --git a/debian/mariadb-server-10.3.install b/debian/mariadb-server-10.3.install
index 23f8046baaf..d8de5512b05 100644
--- a/debian/mariadb-server-10.3.install
+++ b/debian/mariadb-server-10.3.install
@@ -19,7 +19,6 @@ usr/bin/myisamchk
usr/bin/myisamlog
usr/bin/myisampack
usr/bin/mysql_convert_table_format
-usr/bin/mysql_install_db
usr/bin/mysql_plugin
usr/bin/mysql_secure_installation
usr/bin/mysql_setpermission
@@ -34,11 +33,12 @@ usr/bin/replace
usr/bin/resolve_stack_dump
usr/bin/resolveip
usr/bin/wsrep_sst_common
+usr/bin/wsrep_sst_mariabackup
usr/bin/wsrep_sst_mysqldump
usr/bin/wsrep_sst_rsync
usr/bin/wsrep_sst_xtrabackup
usr/bin/wsrep_sst_xtrabackup-v2
-usr/bin/wsrep_sst_mariabackup
+usr/lib/mysql/plugin/auth_ed25519.so
usr/lib/mysql/plugin/auth_pam.so
usr/lib/mysql/plugin/auth_socket.so
usr/lib/mysql/plugin/file_key_management.so
@@ -52,14 +52,45 @@ usr/lib/mysql/plugin/locales.so
usr/lib/mysql/plugin/metadata_lock_info.so
usr/lib/mysql/plugin/query_cache_info.so
usr/lib/mysql/plugin/query_response_time.so
-usr/lib/mysql/plugin/semisync_master.so
-usr/lib/mysql/plugin/semisync_slave.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/wsrep_info.so
usr/share/apport/package-hooks/source_mariadb-10.3.py
usr/share/doc/mariadb-server-10.3/mysqld.sym.gz
+usr/share/man/man1/aria_chk.1
+usr/share/man/man1/aria_dump_log.1
+usr/share/man/man1/aria_ftdump.1
+usr/share/man/man1/aria_pack.1
+usr/share/man/man1/aria_read_log.1
+usr/share/man/man1/galera_new_cluster.1
+usr/share/man/man1/galera_recovery.1
+usr/share/man/man1/mariadb-service-convert.1
+usr/share/man/man1/msql2mysql.1
+usr/share/man/man1/my_print_defaults.1
+usr/share/man/man1/myisam_ftdump.1
+usr/share/man/man1/myisamchk.1
+usr/share/man/man1/myisamlog.1
+usr/share/man/man1/myisampack.1
+usr/share/man/man1/mysql_convert_table_format.1
+usr/share/man/man1/mysql_plugin.1
+usr/share/man/man1/mysql_secure_installation.1
+usr/share/man/man1/mysql_setpermission.1
+usr/share/man/man1/mysql_tzinfo_to_sql.1
+usr/share/man/man1/mysqlbinlog.1
+usr/share/man/man1/mysqld_multi.1
+usr/share/man/man1/mysqld_safe.1
+usr/share/man/man1/mysqld_safe_helper.1
+usr/share/man/man1/mysqlhotcopy.1
+usr/share/man/man1/perror.1
+usr/share/man/man1/replace.1
+usr/share/man/man1/resolve_stack_dump.1
+usr/share/man/man1/resolveip.1
+usr/share/man/man1/wsrep_sst_common.1
+usr/share/man/man1/wsrep_sst_mysqldump.1
+usr/share/man/man1/wsrep_sst_rsync.1
+usr/share/man/man1/wsrep_sst_xtrabackup-v2.1
+usr/share/man/man1/wsrep_sst_xtrabackup.1
usr/share/mysql/errmsg-utf8.txt
usr/share/mysql/fill_help_tables.sql
usr/share/mysql/maria_add_gis_sp_bootstrap.sql
diff --git a/debian/mariadb-server-10.3.manpages b/debian/mariadb-server-10.3.manpages
deleted file mode 100644
index 1825b7655da..00000000000
--- a/debian/mariadb-server-10.3.manpages
+++ /dev/null
@@ -1,25 +0,0 @@
-debian/tmp/usr/share/man/man1/aria_chk.1
-debian/tmp/usr/share/man/man1/aria_dump_log.1
-debian/tmp/usr/share/man/man1/aria_ftdump.1
-debian/tmp/usr/share/man/man1/aria_pack.1
-debian/tmp/usr/share/man/man1/aria_read_log.1
-debian/tmp/usr/share/man/man1/msql2mysql.1
-debian/tmp/usr/share/man/man1/myisamchk.1
-debian/tmp/usr/share/man/man1/myisam_ftdump.1
-debian/tmp/usr/share/man/man1/myisamlog.1
-debian/tmp/usr/share/man/man1/myisampack.1
-debian/tmp/usr/share/man/man1/my_print_defaults.1
-debian/tmp/usr/share/man/man1/mysqlbinlog.1
-debian/tmp/usr/share/man/man1/mysql_convert_table_format.1
-debian/tmp/usr/share/man/man1/mysqld_multi.1
-debian/tmp/usr/share/man/man1/mysqld_safe.1
-debian/tmp/usr/share/man/man1/mysqlhotcopy.1
-debian/tmp/usr/share/man/man1/mysql_install_db.1
-debian/tmp/usr/share/man/man1/mysql_plugin.1
-debian/tmp/usr/share/man/man1/mysql_secure_installation.1
-debian/tmp/usr/share/man/man1/mysql_setpermission.1
-debian/tmp/usr/share/man/man1/mysql_tzinfo_to_sql.1
-debian/tmp/usr/share/man/man1/perror.1
-debian/tmp/usr/share/man/man1/replace.1
-debian/tmp/usr/share/man/man1/resolveip.1
-debian/tmp/usr/share/man/man1/resolve_stack_dump.1
diff --git a/debian/mariadb-server-10.3.mysql.init b/debian/mariadb-server-10.3.mysql.init
index d7f6d58e8ca..35a52d5d8db 100644
--- a/debian/mariadb-server-10.3.mysql.init
+++ b/debian/mariadb-server-10.3.mysql.init
@@ -25,7 +25,7 @@ SELF=$(cd $(dirname $0); pwd -P)/$(basename $0)
MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf"
-# priority can be overriden and "-s" adds output to stderr
+# priority can be overridden and "-s" adds output to stderr
ERR_LOGGER="logger -p daemon.err -t /etc/init.d/mysql -i"
if [ -f /etc/default/mysql ]; then
diff --git a/debian/mariadb-server-core-10.3.install b/debian/mariadb-server-core-10.3.install
index d882bd53f52..46c116b618d 100644
--- a/debian/mariadb-server-core-10.3.install
+++ b/debian/mariadb-server-core-10.3.install
@@ -1,6 +1,11 @@
usr/bin/innochecksum
+usr/bin/mysql_install_db
usr/bin/mysql_upgrade
usr/sbin/mysqld
+usr/share/man/man1/innochecksum.1
+usr/share/man/man1/mysql_install_db.1
+usr/share/man/man1/mysql_upgrade.1
+usr/share/man/man8/mysqld.8
usr/share/mysql/charsets
usr/share/mysql/czech
usr/share/mysql/danish
diff --git a/debian/mariadb-server-core-10.3.manpages b/debian/mariadb-server-core-10.3.manpages
deleted file mode 100644
index 234108cde50..00000000000
--- a/debian/mariadb-server-core-10.3.manpages
+++ /dev/null
@@ -1,3 +0,0 @@
-debian/tmp/usr/share/man/man8/mysqld.8
-debian/tmp/usr/share/man/man1/innochecksum.1
-debian/tmp/usr/share/man/man1/mysql_upgrade.1
diff --git a/debian/mariadb-test.install b/debian/mariadb-test.install
index 605620dc28c..e1de4074310 100644
--- a/debian/mariadb-test.install
+++ b/debian/mariadb-test.install
@@ -16,9 +16,17 @@ usr/lib/mysql/plugin/mypluglib.so
usr/lib/mysql/plugin/qa_auth_client.so
usr/lib/mysql/plugin/qa_auth_interface.so
usr/lib/mysql/plugin/qa_auth_server.so
+usr/lib/mysql/plugin/test_versioning.so
+usr/share/man/man1/mysql-stress-test.pl.1
+usr/share/man/man1/mysql-test-run.pl.1
+usr/share/man/man1/mysql_client_test.1
+usr/share/man/man1/mysql_client_test_embedded.1
+usr/share/man/man1/mysqltest.1
+usr/share/man/man1/mysqltest_embedded.1
usr/share/mysql/mysql-test/README
usr/share/mysql/mysql-test/README-gcov
usr/share/mysql/mysql-test/README.stress
+usr/share/mysql/mysql-test/dgcov.pl
usr/share/mysql/mysql-test/disabled.def
usr/share/mysql/mysql-test/lib
usr/share/mysql/mysql-test/mysql-stress-test.pl
diff --git a/debian/mariadb-test.links b/debian/mariadb-test.links
index 082680fe5ed..884b25a81da 100644
--- a/debian/mariadb-test.links
+++ b/debian/mariadb-test.links
@@ -1,2 +1,2 @@
-usr/share/mysql/mysql-test/mysql-test-run.pl usr/share/mysql/mysql-test/mysql-test-run
usr/share/mysql/mysql-test/mysql-test-run.pl usr/share/mysql/mysql-test/mtr
+usr/share/mysql/mysql-test/mysql-test-run.pl usr/share/mysql/mysql-test/mysql-test-run
diff --git a/debian/mariadb-test.manpages b/debian/mariadb-test.manpages
deleted file mode 100644
index 33ce8710ea7..00000000000
--- a/debian/mariadb-test.manpages
+++ /dev/null
@@ -1,4 +0,0 @@
-debian/tmp/usr/share/man/man1/mysql_client_test.1
-debian/tmp/usr/share/man/man1/mysql_client_test_embedded.1
-debian/tmp/usr/share/man/man1/mysqltest.1
-debian/tmp/usr/share/man/man1/mysqltest_embedded.1
diff --git a/debian/mysql-common.install b/debian/mysql-common.install
index 5ff685f42ff..264df611822 100644
--- a/debian/mysql-common.install
+++ b/debian/mysql-common.install
@@ -1,2 +1,2 @@
debian/additions/my.cnf etc/mysql
-usr/share/mysql-common/internal-use-only \ No newline at end of file
+usr/share/mysql-common/internal-use-only
diff --git a/debian/not-installed b/debian/not-installed
new file mode 100644
index 00000000000..c151cf753e6
--- /dev/null
+++ b/debian/not-installed
@@ -0,0 +1,127 @@
+lib/systemd/system/mariadb.service # Installed by rules file
+lib/systemd/system/mariadb@.service # Installed by rules file
+usr/bin/mysql_config # We already have the MariaDB variant
+usr/bin/mysql_embedded # Huge 500 MB file. Not intended for distribution via any disto package.
+usr/bin/mytop # Mytop is distributed from a separate source package
+usr/lib/sysusers.d/sysusers.conf
+usr/lib/tmpfiles.d/tmpfiles.conf
+usr/lib/mysql/plugin/JavaWrappers.jar # These are only built if JNI/libjawt.so is installed from e.g. openjdk-8-jre-headless
+usr/lib/mysql/plugin/JdbcInterface.jar # These are only built if JNI/libjawt.so is installed from e.g. openjdk-8-jre-headless
+usr/share/doc/mariadb-server-10.3/COPYING
+usr/share/doc/mariadb-server-10.3/COPYING.AGPLv3
+usr/share/doc/mariadb-server-10.3/COPYING.GPLv2
+usr/share/doc/mariadb-server-10.3/COPYING.thirdparty
+usr/share/doc/mariadb-server-10.3/CREDITS
+usr/share/doc/mariadb-server-10.3/EXCEPTIONS-CLIENT
+usr/share/doc/mariadb-server-10.3/INSTALL-BINARY
+usr/share/doc/mariadb-server-10.3/PATENTS
+usr/share/doc/mariadb-server-10.3/README-wsrep
+usr/share/groonga/COPYING
+usr/share/groonga-normalizer-mysql/lgpl-2.0.txt
+usr/share/groonga-normalizer-mysql/README.md
+usr/share/groonga/README.md
+usr/share/man/man1/my_safe_process.1
+usr/share/man/man1/mysql.server.1
+usr/share/mysql/binary-configure
+usr/share/mysql/magic
+usr/share/mysql/maria_add_gis_sp.sql
+usr/share/mysql/mysqld_multi.server
+usr/share/mysql/mysql-log-rotate
+usr/share/mysql/mysql.server
+usr/share/mysql/mysql-test/mtr # Already created by mariadb-test.links
+usr/share/mysql/mysql-test/mysql-test-run # Already created by mariadb-test.links
+usr/share/mysql/mysql_to_mariadb.sql
+usr/share/mysql/policy/apparmor/README # In MariaDB we don't want to use AppArmor at the moment
+usr/share/mysql/policy/apparmor/usr.sbin.mysqld # In MariaDB we don't want to use AppArmor at the moment
+usr/share/mysql/policy/apparmor/usr.sbin.mysqld.local # In MariaDB we don't want to use AppArmor at the moment
+usr/share/mysql/policy/selinux/mariadb-server.fc # In MariaDB we don't want to use SELinux at the moment
+usr/share/mysql/policy/selinux/mariadb-server.te # In MariaDB we don't want to use SELinux at the moment
+usr/share/mysql/policy/selinux/mariadb.te # In MariaDB we don't want to use SELinux at the moment
+usr/share/mysql/policy/selinux/README # In MariaDB we don't want to use SELinux at the moment
+usr/share/mysql/systemd/mariadb.service # Installed by rules file
+usr/share/mysql/systemd/mariadb@.service # Installed by rules file
+usr/share/mysql/systemd/use_galera_new_cluster.conf
+usr/share/mysql/wsrep.cnf
+usr/sql-bench/bench-count-distinct
+usr/sql-bench/bench-init.pl # SQL-bench is distributed from a separate source package
+usr/sql-bench/compare-results
+usr/sql-bench/copy-db
+usr/sql-bench/crash-me
+usr/sql-bench/Data/ATIS/aircraft.txt
+usr/sql-bench/Data/ATIS/airline.txt
+usr/sql-bench/Data/ATIS/airport_service.txt
+usr/sql-bench/Data/ATIS/airport.txt
+usr/sql-bench/Data/ATIS/city.txt
+usr/sql-bench/Data/ATIS/class_of_service.txt
+usr/sql-bench/Data/ATIS/code_description.txt
+usr/sql-bench/Data/ATIS/compound_class.txt
+usr/sql-bench/Data/ATIS/connect_leg.txt
+usr/sql-bench/Data/ATIS/date_day.txt
+usr/sql-bench/Data/ATIS/day_name.txt
+usr/sql-bench/Data/ATIS/dual_carrier.txt
+usr/sql-bench/Data/ATIS/fare.txt
+usr/sql-bench/Data/ATIS/fconnection.txt
+usr/sql-bench/Data/ATIS/flight_class.txt
+usr/sql-bench/Data/ATIS/flight_day.txt
+usr/sql-bench/Data/ATIS/flight_fare.txt
+usr/sql-bench/Data/ATIS/flight.txt
+usr/sql-bench/Data/ATIS/food_service.txt
+usr/sql-bench/Data/ATIS/ground_service.txt
+usr/sql-bench/Data/ATIS/month_name.txt
+usr/sql-bench/Data/ATIS/restrict_carrier.txt
+usr/sql-bench/Data/ATIS/restrict_class.txt
+usr/sql-bench/Data/ATIS/restriction.txt
+usr/sql-bench/Data/ATIS/state.txt
+usr/sql-bench/Data/ATIS/stop1.txt
+usr/sql-bench/Data/ATIS/stop.txt
+usr/sql-bench/Data/ATIS/time_interval.txt
+usr/sql-bench/Data/ATIS/time_zone.txt
+usr/sql-bench/Data/ATIS/transport.txt
+usr/sql-bench/Data/Wisconsin/onek.data
+usr/sql-bench/Data/Wisconsin/tenk.data
+usr/sql-bench/graph-compare-results
+usr/sql-bench/innotest1
+usr/sql-bench/innotest1a
+usr/sql-bench/innotest1b
+usr/sql-bench/innotest2
+usr/sql-bench/innotest2a
+usr/sql-bench/innotest2b
+usr/sql-bench/limits/access.cfg
+usr/sql-bench/limits/access_odbc.cfg
+usr/sql-bench/limits/Adabas.cfg
+usr/sql-bench/limits/db2.cfg
+usr/sql-bench/limits/empress.cfg
+usr/sql-bench/limits/frontbase.cfg
+usr/sql-bench/limits/Informix.cfg
+usr/sql-bench/limits/interbase.cfg
+usr/sql-bench/limits/interbase-dialect1.cfg
+usr/sql-bench/limits/interbase-dialect3.cfg
+usr/sql-bench/limits/interbase-superserver.cfg
+usr/sql-bench/limits/mimer.cfg
+usr/sql-bench/limits/msql.cfg
+usr/sql-bench/limits/ms-sql65.cfg
+usr/sql-bench/limits/ms-sql.cfg
+usr/sql-bench/limits/mysql-3.22.cfg
+usr/sql-bench/limits/mysql-3.23.cfg
+usr/sql-bench/limits/mysql-4.0.cfg
+usr/sql-bench/limits/mysql-4.1.cfg
+usr/sql-bench/limits/mysql.cfg
+usr/sql-bench/limits/oracle.cfg
+usr/sql-bench/limits/pg.cfg
+usr/sql-bench/limits/solid.cfg
+usr/sql-bench/limits/solid-nt4.cfg
+usr/sql-bench/limits/sybase.cfg
+usr/sql-bench/myisam.cnf
+usr/sql-bench/README
+usr/sql-bench/run-all-tests
+usr/sql-bench/server-cfg
+usr/sql-bench/test-alter-table
+usr/sql-bench/test-ATIS
+usr/sql-bench/test-big-tables
+usr/sql-bench/test-connect
+usr/sql-bench/test-create
+usr/sql-bench/test-insert
+usr/sql-bench/test-select
+usr/sql-bench/test-table-elimination
+usr/sql-bench/test-transactions
+usr/sql-bench/test-wisconsin
diff --git a/debian/patches/33_scripts__mysql_create_system_tables__no_test.dpatch b/debian/patches/33_scripts__mysql_create_system_tables__no_test.dpatch
index 183212ef678..06c984c398c 100755
--- a/debian/patches/33_scripts__mysql_create_system_tables__no_test.dpatch
+++ b/debian/patches/33_scripts__mysql_create_system_tables__no_test.dpatch
@@ -10,16 +10,15 @@
@DPATCH@
--- a/scripts/mysql_system_tables_data.sql
+++ b/scripts/mysql_system_tables_data.sql
-@@ -26,16 +26,6 @@
- -- a plain character
+@@ -27,15 +27,6 @@
SELECT LOWER( REPLACE((SELECT REPLACE(@@hostname,'_','\_')),'%','\%') )INTO @current_hostname;
--
+
--- Fill "db" table with default grants for anyone to
--- access database 'test' and 'test_%' if "db" table didn't exist
-CREATE TEMPORARY TABLE tmp_db LIKE db;
--INSERT INTO tmp_db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y');
--INSERT INTO tmp_db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y');
+-INSERT INTO tmp_db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y','Y');
+-INSERT INTO tmp_db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y','Y');
-INSERT INTO db SELECT * FROM tmp_db WHERE @had_db_table=0;
-DROP TABLE tmp_db;
-
@@ -27,10 +26,10 @@
-- Fill "user" table with default users allowing root access
-- from local machine if "user" table didn't exist before
CREATE TEMPORARY TABLE tmp_user_nopasswd LIKE user;
-@@ -48,9 +38,6 @@ REPLACE INTO tmp_user_nopasswd VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y'
- REPLACE INTO tmp_user_nopasswd VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
+@@ -48,9 +39,6 @@ REPLACE INTO tmp_user_nopasswd VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y'
+ REPLACE INTO tmp_user_nopasswd VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
-- More secure root account using unix sucket auth.
- INSERT INTO tmp_user_socket VALUES ('localhost',IFNULL(@auth_root_socket, 'root'),'','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'unix_socket','','N', 'N','', 0);
+ INSERT INTO tmp_user_socket VALUES ('localhost',IFNULL(@auth_root_socket, 'root'),'','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'unix_socket','','N', 'N','', 0);
--- Anonymous user with no privileges.
-INSERT INTO tmp_user_anonymous (host,user) VALUES ('localhost','');
-INSERT INTO tmp_user_anonymous (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost';
diff --git a/debian/patches/38_scripts__mysqld_safe.sh__signals.dpatch b/debian/patches/38_scripts__mysqld_safe.sh__signals.dpatch
index 5a9c3a59698..5cbc897c272 100755
--- a/debian/patches/38_scripts__mysqld_safe.sh__signals.dpatch
+++ b/debian/patches/38_scripts__mysqld_safe.sh__signals.dpatch
@@ -7,9 +7,9 @@
@DPATCH@
---- a/scripts/mysqld_safe.sh 2013-01-11 16:02:41 +0000
-+++ b/scripts/mysqld_safe.sh 2013-01-11 16:03:14 +0000
-@@ -32,7 +32,6 @@ err_log=
+--- a/scripts/mysqld_safe.sh 2013-01-11 16:02:41 +0000
++++ b/scripts/mysqld_safe.sh 2013-01-11 16:03:14 +0000
+@@ -36,7 +36,6 @@ skip_err_log=0
syslog_tag_mysqld=mysqld
syslog_tag_mysqld_safe=mysqld_safe
@@ -17,7 +17,7 @@
# MySQL-specific environment variable. First off, it's not really a umask,
# it's the desired mode. Second, it follows umask(2), not umask(3) in that
-@@ -163,7 +162,7 @@ eval_log_error () {
+@@ -181,7 +180,7 @@ eval_log_error () {
# sed buffers output (only GNU sed supports a -u (unbuffered) option)
# which means that messages may not get sent to syslog until the
# mysqld process quits.
@@ -26,7 +26,7 @@
;;
*)
echo "Internal program error (non-fatal):" \
-@@ -805,6 +804,13 @@ then
+@@ -895,6 +894,13 @@ then
fi
#
diff --git a/debian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch b/debian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch
index 5ab8ab3d3d7..9a063e408a5 100755
--- a/debian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch
+++ b/debian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch
@@ -7,9 +7,9 @@
@DPATCH@
---- mysql-dfsg-5.1-5.1.23rc.orig/scripts/mysql_install_db.sh 2008-01-29 22:41:20.000000000 +0100
-+++ mysql-dfsg-5.1-5.1.23rc/scripts/mysql_install_db.sh 2008-02-28 10:08:11.000000000 +0100
-@@ -372,7 +372,7 @@ then
+--- mysql-dfsg-5.1-5.1.23rc.orig/scripts/mysql_install_db.sh 2008-01-29 22:41:20.000000000 +0100
++++ mysql-dfsg-5.1-5.1.23rc/scripts/mysql_install_db.sh 2008-02-28 10:08:11.000000000 +0100
+@@ -407,7 +407,7 @@ then
fi
# Create database directories
diff --git a/debian/patches/50_mysql-test__db_test.dpatch b/debian/patches/50_mysql-test__db_test.dpatch
index 14c0fc4acf6..ed2efb95998 100755
--- a/debian/patches/50_mysql-test__db_test.dpatch
+++ b/debian/patches/50_mysql-test__db_test.dpatch
@@ -8,15 +8,15 @@
@DPATCH@
---- old/mysql-test/mysql-test-run.pl 2009-06-16 14:24:09.000000000 +0200
-+++ new/mysql-test/mysql-test-run.pl 2009-07-04 00:03:34.000000000 +0200
-@@ -3578,6 +3578,11 @@ sub mysql_install_db {
+--- old/mysql-test/mysql-test-run.pl 2009-06-16 14:24:09.000000000 +0200
++++ new/mysql-test/mysql-test-run.pl 2009-07-04 00:03:34.000000000 +0200
+@@ -3180,6 +3180,11 @@ sub mysql_install_db {
mtr_appendfile_to_file("$sql_dir/mysql_system_tables_data.sql",
$bootstrap_sql_file);
+ mtr_tofile($bootstrap_sql_file, "-- Debian removed the default privileges on the 'test' database\n");
-+ mtr_tofile($bootstrap_sql_file, "INSERT INTO mysql.db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y');\n");
-+ mtr_tofile($bootstrap_sql_file, "INSERT INTO mysql.db VALUES ('%','test\\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y');\n");
++ mtr_tofile($bootstrap_sql_file, "INSERT INTO mysql.db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y','Y');\n");
++ mtr_tofile($bootstrap_sql_file, "INSERT INTO mysql.db VALUES ('%','test\\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y','Y');\n");
+
+
# Add test data for timezone - this is just a subset, on a real
diff --git a/debian/rules b/debian/rules
index cd910b5cc6d..b4ef2e5da6d 100755
--- a/debian/rules
+++ b/debian/rules
@@ -32,24 +32,19 @@ CXX := $(DEB_HOST_GNU_TYPE)-g++
# at https://www.debian.org/doc/debian-policy/ch-source.html#s-debianrules-options
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
- MAKEFLAGS += -j $(NUMJOBS)
+ MAKEFLAGS += -j$(NUMJOBS)
else
# NUMJOBS cannot be empty as it is used as a parameter to mtr, default to 1.
NUMJOBS = 1
endif
# Ignore test suite exit code on unstable platforms
-ifneq (,$(filter $(ARCH), mips mipsel))
+ifneq (,$(filter $(ARCH),mips mipsel mips64el alpha powerpc sh4 hurd-i386 sparc64 kfreebsd-i386 kfreebsd-amd64))
TESTSUITE_FAIL_CMD:=true
else
TESTSUITE_FAIL_CMD:=exit 1
endif
-# Skip TokuDB if arch is not amd64
-ifneq ($(ARCH), amd64)
- CMAKEFLAGS += -DWITHOUT_TOKUDB=true
-endif
-
# Add support for verbose builds
MAKEFLAGS += VERBOSE=1
@@ -119,19 +114,10 @@ override_dh_auto_install:
dh_testdir
dh_testroot
- # If TokuDB plugin was not built skip the package
- [ -f $(BUILDDIR)/storage/tokudb/ha_tokudb.so ] || sed -i -e "/Package: mariadb-plugin-tokudb/,+16d" debian/control
-
- # If Mroonga plugin was not built skip the package
- [ -f $(BUILDDIR)/storage/mroonga/ha_mroonga.so ] || sed -i -e "/Package: mariadb-plugin-mroonga/,+15d" debian/control
-
# If libthrift-dev was available (manually installed, as it is
# not in Debian) and ha_cassandra.so was thus built, create package,
# otherwise skip it.
- [ -f $(BUILDDIR)/storage/cassandra/ha_cassandra.so ] || sed -i -e "/Package: mariadb-plugin-cassandra/,+18d" debian/control
-
- # If Spider plugin was not built skip the package
- [ -f $(BUILDDIR)/storage/spider/ha_spider.so ] || sed -i -e "/Package: mariadb-plugin-spider/,+16d" debian/control
+ [ -f $(BUILDDIR)/storage/cassandra/ha_cassandra.so ] || sed -i -e "/Package: mariadb-plugin-cassandra/,+20d" debian/control
# Copy systemd files to a location available for dh_installinit
cp $(BUILDDIR)/support-files/mariadb.service debian/mariadb-server-10.3.mariadb.service
@@ -162,13 +148,13 @@ override_dh_auto_install:
install -D -m 644 debian/mariadb-server-10.3.py $(TMP)/usr/share/apport/package-hooks/source_mariadb-10.3.py
# Install libmariadbclient18 compatibility links
- ln -s /usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadbclient.so
- ln -s /usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadbclient.so.18
+ ln -s libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadbclient.so
+ ln -s libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadbclient.so.18
# Install libmysqlclientclientXX compatibility links
- ln -s /usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.18
- ln -s /usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.19
- ln -s /usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.20
+ ln -s libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.18
+ ln -s libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.19
+ ln -s libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.20
touch $@
@@ -191,7 +177,11 @@ override_dh_installcron-arch:
get-orig-source:
uscan --force-download --verbose
+# If a file is not supposed to be included anywhere, add it to the not-installed
+# file and document the reason. Note that dh_install supports the above mentioned
+# white list file only starting from Debian Stretch and Ubuntu Xenial.
+# To find more, grep build logs for 'but is not installed to anywhere'.
%:
- dh $@ --parallel --with dpatch --with systemd
+ dh $@ --parallel --with dpatch --with systemd --list-missing
# vim: ts=8
diff --git a/extra/comp_err.c b/extra/comp_err.c
index 5e3cec676bc..7baa56e130c 100644
--- a/extra/comp_err.c
+++ b/extra/comp_err.c
@@ -969,6 +969,7 @@ static struct errors *generate_empty_message(uint d_code, my_bool skip)
new_error->d_code= d_code;
new_error->sql_code1= empty_string;
new_error->sql_code2= empty_string;
+ new_error->next_error= 0;
message.text= 0; /* If skip set, don't generate a text */
@@ -998,6 +999,7 @@ static struct errors *parse_error_string(char *str, int er_count)
MYF(MY_WME))))
DBUG_RETURN(0);
+ new_error->next_error= 0;
if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0, MYF(0)))
DBUG_RETURN(0); /* OOM: Fatal error */
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc
index b937cc6fa1a..6fb4154c6ca 100644
--- a/extra/innochecksum.cc
+++ b/extra/innochecksum.cc
@@ -95,8 +95,8 @@ static my_bool do_leaf;
static my_bool per_page_details;
static ulint n_merge;
extern ulong srv_checksum_algorithm;
-static ulong physical_page_size; /* Page size in bytes on disk. */
-static ulong logical_page_size; /* Page size when uncompressed. */
+static ulint physical_page_size; /* Page size in bytes on disk. */
+static ulint logical_page_size; /* Page size when uncompressed. */
ulong srv_page_size;
page_size_t univ_page_size(0, 0, false);
/* Current page number (0 based). */
@@ -431,13 +431,13 @@ open_file(
tablespace.
@retval no. of bytes read.
*/
-ulong read_file(
+ulint read_file(
byte* buf,
bool partial_page_read,
- ulong physical_page_size,
+ ulint physical_page_size,
FILE* fil_in)
{
- ulong bytes = 0;
+ ulint bytes = 0;
DBUG_ASSERT(physical_page_size >= UNIV_ZIP_SIZE_MIN);
@@ -447,7 +447,7 @@ ulong read_file(
bytes = UNIV_ZIP_SIZE_MIN;
}
- bytes += ulong(fread(buf, 1, physical_page_size, fil_in));
+ bytes += ulint(fread(buf, 1, physical_page_size, fil_in));
return bytes;
}
@@ -792,7 +792,7 @@ parse_page(
ulint right_page_no;
ulint data_bytes;
bool is_leaf;
- int size_range_id;
+ ulint size_range_id;
/* Check whether page is doublewrite buffer. */
if(skip_page) {
@@ -1703,13 +1703,12 @@ int main(
ulint zip_size = page_size.is_compressed() ? page_size.logical() : 0;
logical_page_size = page_size.is_compressed() ? zip_size : 0;
physical_page_size = page_size.physical();
- srv_page_size = page_size.logical();
+ srv_page_size = (ulong)page_size.logical();
bool is_compressed = FSP_FLAGS_HAS_PAGE_COMPRESSION(flags);
if (page_size.physical() > UNIV_ZIP_SIZE_MIN) {
/* Read rest of the page 0 to determine crypt_data */
- bytes = ulong(read_file(buf, partial_page_read, page_size.physical(), fil_in));
-
+ bytes = read_file(buf, partial_page_read, page_size.physical(), fil_in);
if (bytes != page_size.physical()) {
fprintf(stderr, "Error: Was not able to read the "
"rest of the page ");
diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc
index 0b501970efa..1542e57c84c 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -252,9 +252,8 @@ datadir_iter_next_database(datadir_iter_t *it)
it->dbpath = static_cast<char*>(
malloc(it->dbpath_len));
}
- ut_snprintf(it->dbpath, it->dbpath_len,
- "%s/%s", it->datadir_path,
- it->dbinfo.name);
+ snprintf(it->dbpath, it->dbpath_len, "%s/%s",
+ it->datadir_path, it->dbinfo.name);
os_normalize_path(it->dbpath);
if (it->dbinfo.type == OS_FILE_TYPE_FILE) {
@@ -1034,8 +1033,8 @@ move_file(ds_ctxt_t *datasink,
char dst_dir_abs[FN_REFLEN];
size_t dirname_length;
- ut_snprintf(dst_file_path_abs, sizeof(dst_file_path_abs),
- "%s/%s", dst_dir, dst_file_path);
+ snprintf(dst_file_path_abs, sizeof(dst_file_path_abs),
+ "%s/%s", dst_dir, dst_file_path);
dirname_part(dst_dir_abs, dst_file_path_abs, &dirname_length);
@@ -1252,8 +1251,8 @@ backup_files(const char *from, bool prep_mode)
} else if (!prep_mode) {
/* backup fake file into empty directory */
char path[FN_REFLEN];
- ut_snprintf(path, sizeof(path),
- "%s/db.opt", node.filepath);
+ snprintf(path, sizeof(path),
+ "%s/db.opt", node.filepath);
if (!(ret = backup_file_printf(
trim_dotslash(path), "%s", ""))) {
msg("Failed to create file %s\n", path);
@@ -1465,12 +1464,10 @@ bool backup_finish()
return(false);
}
- if (!write_xtrabackup_info(mysql_connection)) {
+ if (!write_xtrabackup_info(mysql_connection, XTRABACKUP_INFO, opt_history != 0)) {
return(false);
}
-
-
return(true);
}
diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc
index aa683e320fc..0549b0c5e9c 100644
--- a/extra/mariabackup/backup_mysql.cc
+++ b/extra/mariabackup/backup_mysql.cc
@@ -589,7 +589,7 @@ select_incremental_lsn_from_history(lsn_t *incremental_lsn)
mysql_real_escape_string(mysql_connection, buf,
opt_incremental_history_name,
(unsigned long)strlen(opt_incremental_history_name));
- ut_snprintf(query, sizeof(query),
+ snprintf(query, sizeof(query),
"SELECT innodb_to_lsn "
"FROM PERCONA_SCHEMA.xtrabackup_history "
"WHERE name = '%s' "
@@ -602,7 +602,7 @@ select_incremental_lsn_from_history(lsn_t *incremental_lsn)
mysql_real_escape_string(mysql_connection, buf,
opt_incremental_history_uuid,
(unsigned long)strlen(opt_incremental_history_uuid));
- ut_snprintf(query, sizeof(query),
+ snprintf(query, sizeof(query),
"SELECT innodb_to_lsn "
"FROM PERCONA_SCHEMA.xtrabackup_history "
"WHERE uuid = '%s' "
@@ -766,7 +766,7 @@ kill_long_queries(MYSQL *connection, time_t timeout)
is_select_query(info))) {
msg_ts("Killing query %s (duration %d sec): %s\n",
id, (int)duration, info);
- ut_snprintf(kill_stmt, sizeof(kill_stmt),
+ snprintf(kill_stmt, sizeof(kill_stmt),
"KILL %s", id);
xb_mysql_query(connection, kill_stmt, false, false);
}
@@ -800,7 +800,7 @@ wait_for_no_updates(MYSQL *connection, uint timeout, uint threshold)
static
os_thread_ret_t
-kill_query_thread(
+DECLARE_THREAD(kill_query_thread)(
/*===============*/
void *arg __attribute__((unused)))
{
@@ -1288,8 +1288,8 @@ write_current_binlog_file(MYSQL *connection)
goto cleanup;
}
- ut_snprintf(filepath, sizeof(filepath), "%s%c%s",
- log_bin_dir, FN_LIBCHAR, log_bin_file);
+ snprintf(filepath, sizeof(filepath), "%s%c%s",
+ log_bin_dir, FN_LIBCHAR, log_bin_file);
result = copy_file(ds_data, filepath, log_bin_file, 0);
}
@@ -1386,7 +1386,7 @@ operator<<(std::ostream& s, const escape_and_quote& eq)
s << '\'';
size_t len = strlen(eq.str);
char* escaped = (char *)alloca(2 * len + 1);
- len = mysql_real_escape_string(eq.mysql, escaped, eq.str, len);
+ len = mysql_real_escape_string(eq.mysql, escaped, eq.str, (ulong)len);
s << std::string(escaped, len);
s << '\'';
return s;
@@ -1398,7 +1398,7 @@ PERCONA_SCHEMA.xtrabackup_history and writes a new history record to the
table containing all the history info particular to the just completed
backup. */
bool
-write_xtrabackup_info(MYSQL *connection)
+write_xtrabackup_info(MYSQL *connection, const char * filename, bool history)
{
char *uuid = NULL;
@@ -1426,7 +1426,7 @@ write_xtrabackup_info(MYSQL *connection)
|| xtrabackup_databases_exclude
);
- backup_file_printf(XTRABACKUP_INFO,
+ backup_file_printf(filename,
"uuid = %s\n"
"name = %s\n"
"tool_name = %s\n"
@@ -1463,7 +1463,7 @@ write_xtrabackup_info(MYSQL *connection)
xb_stream_name[xtrabackup_stream_fmt], /* format */
xtrabackup_compress ? "compressed" : "N"); /* compressed */
- if (!opt_history) {
+ if (!history) {
goto cleanup;
}
@@ -1574,8 +1574,8 @@ char *make_argv(char *buf, size_t len, int argc, char **argv)
if (strncmp(*argv, "--password", strlen("--password")) == 0) {
arg = "--password=...";
}
- left-= ut_snprintf(buf + len - left, left,
- "%s%c", arg, argc > 1 ? ' ' : 0);
+ left-= snprintf(buf + len - left, left,
+ "%s%c", arg, argc > 1 ? ' ' : 0);
++argv; --argc;
}
@@ -1656,8 +1656,8 @@ static void check_mdl_lock_works(const char *table_name)
MYSQL *test_con= xb_mysql_connect();
char *query;
xb_a(asprintf(&query,
- "SET STATEMENT max_statement_time=1 FOR ALTER TABLE %s"
- " ADD COLUMN mdl_lock_column int", table_name));
+ "SET STATEMENT max_statement_time=1 FOR ALTER TABLE %s FORCE",
+ table_name));
int err = mysql_query(test_con, query);
DBUG_ASSERT(err);
int err_no = mysql_errno(test_con);
diff --git a/extra/mariabackup/backup_mysql.h b/extra/mariabackup/backup_mysql.h
index 3ccd7bdb613..e2c56f88a8c 100644
--- a/extra/mariabackup/backup_mysql.h
+++ b/extra/mariabackup/backup_mysql.h
@@ -68,7 +68,7 @@ bool
write_binlog_info(MYSQL *connection);
bool
-write_xtrabackup_info(MYSQL *connection);
+write_xtrabackup_info(MYSQL *connection, const char * filename, bool history);
bool
write_backup_config_file();
diff --git a/extra/mariabackup/changed_page_bitmap.cc b/extra/mariabackup/changed_page_bitmap.cc
index a430a6cb0af..46bb3a7bcb5 100644
--- a/extra/mariabackup/changed_page_bitmap.cc
+++ b/extra/mariabackup/changed_page_bitmap.cc
@@ -441,7 +441,7 @@ log_online_open_bitmap_file_read_only(
xb_ad(name[0] != '\0');
- ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%s", srv_data_home, name);
+ snprintf(bitmap_file->name, FN_REFLEN, "%s%s", srv_data_home, name);
bitmap_file->file = os_file_create_simple_no_error_handling(
0, bitmap_file->name,
OS_FILE_OPEN, OS_FILE_READ_ONLY, true, &success);
diff --git a/extra/mariabackup/common.h b/extra/mariabackup/common.h
index 7b1dfd7a0db..4d73742af49 100644
--- a/extra/mariabackup/common.h
+++ b/extra/mariabackup/common.h
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include <mysql_version.h>
#include <fcntl.h>
#include <stdarg.h>
+#include <my_sys.h>
# define fil_is_user_tablespace_id(i) ((i) > srv_undo_tablespaces_open)
diff --git a/extra/mariabackup/crc/crc_glue.c b/extra/mariabackup/crc/crc_glue.c
index c301cb01e2e..11d2c21886b 100644
--- a/extra/mariabackup/crc/crc_glue.c
+++ b/extra/mariabackup/crc/crc_glue.c
@@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include <string.h>
#include <zlib.h>
-#if __GNUC__ >= 4 && defined(__x86_64__)
+#if defined(__GNUC__) && defined(__x86_64__)
static int pclmul_enabled = 0;
#endif
diff --git a/extra/mariabackup/encryption_plugin.cc b/extra/mariabackup/encryption_plugin.cc
index b88c149673b..7f230256e7a 100644
--- a/extra/mariabackup/encryption_plugin.cc
+++ b/extra/mariabackup/encryption_plugin.cc
@@ -165,6 +165,7 @@ static void encryption_plugin_init(int argc, char **argv)
{
/* Patch optional and mandatory plugins, we only need to load the one in xb_plugin_load. */
mysql_optional_plugins[0] = mysql_mandatory_plugins[0] = 0;
+ plugin_maturity = MariaDB_PLUGIN_MATURITY_UNKNOWN; /* mariabackup accepts all plugins */
msg("Loading encryption plugin\n");
for (int i= 1; i < argc; i++)
msg("\t Encryption plugin parameter : '%s'\n", argv[i]);
diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc
index 6e6c61e74cc..627ef7a4b72 100644
--- a/extra/mariabackup/fil_cur.cc
+++ b/extra/mariabackup/fil_cur.cc
@@ -212,24 +212,7 @@ xb_fil_cur_open(
posix_fadvise(cursor->file, 0, 0, POSIX_FADV_SEQUENTIAL);
- /* Determine the page size */
- ulint flags = xb_get_space_flags(cursor->file);
- if (flags == ULINT_UNDEFINED) {
- xb_fil_cur_close(cursor);
- return(XB_FIL_CUR_SKIP);
- }
-
- if (!fsp_flags_is_valid(flags, cursor->space_id)) {
- ulint cflags = fsp_flags_convert_from_101(flags);
- if (cflags == ULINT_UNDEFINED) {
- msg("[%02u] mariabackup: Error: Invalid "
- "tablespace flags: %x.\n", thread_n, uint(flags));
- return(XB_FIL_CUR_SKIP);
- }
- flags = cflags;
- }
-
- const page_size_t page_size(flags);
+ const page_size_t page_size(cursor->node->space->flags);
cursor->page_size = page_size;
/* Allocate read buffer */
diff --git a/extra/mariabackup/write_filt.cc b/extra/mariabackup/write_filt.cc
index 254ecdb740d..382a31f859f 100644
--- a/extra/mariabackup/write_filt.cc
+++ b/extra/mariabackup/write_filt.cc
@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include "write_filt.h"
#include "fil_cur.h"
#include "xtrabackup.h"
+#include <os0proc.h>
/************************************************************************
Write-through page write filter. */
@@ -68,19 +69,22 @@ wf_incremental_init(xb_write_filt_ctxt_t *ctxt, char *dst_name,
xb_fil_cur_t *cursor)
{
char meta_name[FN_REFLEN];
- ulint buf_size;
xb_wf_incremental_ctxt_t *cp =
&(ctxt->u.wf_incremental_ctxt);
ctxt->cursor = cursor;
/* allocate buffer for incremental backup (4096 pages) */
- buf_size = (cursor->page_size.physical() / 4 + 1)
- * cursor->page_size.physical();
- cp->delta_buf_base = static_cast<byte *>(malloc(buf_size));
- memset(cp->delta_buf_base, 0, buf_size);
- cp->delta_buf = static_cast<byte *>
- (ut_align(cp->delta_buf_base, cursor->page_size.physical()));
+ cp->delta_buf_size = (cursor->page_size.physical() / 4)
+ * cursor->page_size.physical();
+ cp->delta_buf = (unsigned char *)os_mem_alloc_large(&cp->delta_buf_size);
+
+ if (!cp->delta_buf) {
+ msg("[%02u] mariabackup: Error: "
+ "cannot allocate %zu bytes\n",
+ cursor->thread_n, (size_t) cp->delta_buf_size);
+ return (FALSE);
+ }
/* write delta meta info */
snprintf(meta_name, sizeof(meta_name), "%s%s", dst_name,
@@ -184,8 +188,7 @@ static void
wf_incremental_deinit(xb_write_filt_ctxt_t *ctxt)
{
xb_wf_incremental_ctxt_t *cp = &(ctxt->u.wf_incremental_ctxt);
-
- free(cp->delta_buf_base);
+ os_mem_free_large(cp->delta_buf, cp->delta_buf_size);
}
/************************************************************************
diff --git a/extra/mariabackup/write_filt.h b/extra/mariabackup/write_filt.h
index bcab263f1dd..69655db5b0b 100644
--- a/extra/mariabackup/write_filt.h
+++ b/extra/mariabackup/write_filt.h
@@ -30,7 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
/* Incremental page filter context */
typedef struct {
- byte *delta_buf_base;
+ ulint delta_buf_size;
byte *delta_buf;
ulint npages;
} xb_wf_incremental_ctxt_t;
diff --git a/extra/mariabackup/wsrep.cc b/extra/mariabackup/wsrep.cc
index 6e02bf5ceab..fb66611b3ee 100644
--- a/extra/mariabackup/wsrep.cc
+++ b/extra/mariabackup/wsrep.cc
@@ -43,7 +43,7 @@ permission notice:
#include <my_global.h>
#include <my_base.h>
#include <handler.h>
-#include <trx0sys.h>
+#include <trx0rseg.h>
#include "common.h"
#ifdef WITH_WSREP
@@ -181,7 +181,7 @@ xb_write_galera_info(bool incremental_prepare)
memset(&xid, 0, sizeof(xid));
xid.formatID = -1;
- if (!trx_sys_read_wsrep_checkpoint(&xid)) {
+ if (!trx_rseg_read_wsrep_checkpoint(xid)) {
return;
}
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index af00173a4de..444e932ca1a 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -255,8 +255,9 @@ it every INNOBASE_WAKE_INTERVAL'th step. */
#define INNOBASE_WAKE_INTERVAL 32
ulong innobase_active_counter = 0;
-
+#ifndef _WIN32
static char *xtrabackup_debug_sync = NULL;
+#endif
my_bool xtrabackup_incremental_force_scan = FALSE;
@@ -434,6 +435,22 @@ datafiles_iter_free(datafiles_iter_t *it)
free(it);
}
+void mdl_lock_all()
+{
+ mdl_lock_init();
+ datafiles_iter_t *it = datafiles_iter_new(fil_system);
+ if (!it)
+ return;
+
+ while (fil_node_t *node = datafiles_iter_next(it)){
+ if (fil_is_user_tablespace_id(node->space->id)
+ && check_if_skip_table(node->space->name))
+ continue;
+
+ mdl_lock_table(node->space->id);
+ }
+ datafiles_iter_free(it);
+}
/* ======== Date copying thread context ======== */
typedef struct {
@@ -1061,11 +1078,13 @@ struct my_option xb_server_options[] =
(G_PTR*) &defaults_group, (G_PTR*) &defaults_group,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"plugin-dir", OPT_PLUGIN_DIR, "Server plugin directory",
+ {"plugin-dir", OPT_PLUGIN_DIR,
+ "Server plugin directory. Used to load encryption plugin during 'prepare' phase."
+ "Has no effect in the 'backup' phase (plugin directory during backup is the same as server's)",
&xb_plugin_dir, &xb_plugin_dir,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { "plugin-load", OPT_PLUGIN_LOAD, "encrypton plugin to load",
+ { "plugin-load", OPT_PLUGIN_LOAD, "encrypton plugin to load during 'prepare' phase.",
&xb_plugin_load, &xb_plugin_load,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
@@ -1206,8 +1225,8 @@ static int prepare_export()
if (strncmp(orig_argv1,"--defaults-file=",16) == 0)
{
sprintf(cmdline,
- IF_WIN("\"","") "\"%s\" --mysqld \"%s\" --defaults-group-suffix=%s"
- " --defaults-extra-file=./backup-my.cnf --datadir=."
+ IF_WIN("\"","") "\"%s\" --mysqld \"%s\" "
+ " --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
" --innodb --innodb-fast-shutdown=0"
" --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu"
" --console --skip-log-error --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""),
@@ -1219,11 +1238,12 @@ static int prepare_export()
{
sprintf(cmdline,
IF_WIN("\"","") "\"%s\" --mysqld"
- " --defaults-file=./backup-my.cnf --datadir=."
+ " --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
" --innodb --innodb-fast-shutdown=0"
" --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu"
" --console --log-error= --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""),
mariabackup_exe,
+ (my_defaults_group_suffix?my_defaults_group_suffix:""),
xtrabackup_use_memory);
}
@@ -1246,10 +1266,10 @@ end:
static const char *xb_client_default_groups[]=
- { "xtrabackup", "client", 0, 0, 0 };
+ { "xtrabackup", "mariabackup", "client", 0, 0, 0 };
static const char *xb_server_default_groups[]=
- { "xtrabackup", "mysqld", 0, 0, 0 };
+ { "xtrabackup", "mariabackup", "mysqld", 0, 0, 0 };
static void print_version(void)
{
@@ -1276,7 +1296,7 @@ GNU General Public License for more details.\n\
\n\
You can download full text of the license on http://www.gnu.org/licenses/gpl-2.0.txt\n");
- printf("Usage: [%s [--defaults-file=#] --backup | %s [--defaults-file=#] --prepare] [OPTIONS]\n",my_progname,my_progname);
+ printf("Usage: %s [--defaults-file=#] [--backup | --prepare | --copy-back | --move-back] [OPTIONS]\n",my_progname);
print_defaults("my", xb_server_default_groups);
my_print_help(xb_client_options);
my_print_help(xb_server_options);
@@ -1420,8 +1440,12 @@ xb_get_one_option(int optid,
case OPT_PROTOCOL:
if (argument)
{
- opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
- opt->name);
+ if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
+ opt->name)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
+ exit(1);
+ }
}
break;
#include "sslopt-case.h"
@@ -1455,6 +1479,9 @@ innodb_init_param(void)
srv_page_size = 0;
srv_page_size_shift = 0;
+#ifdef BTR_CUR_HASH_ADAPT
+ btr_ahi_parts = 1;
+#endif /* BTR_CUR_HASH_ADAPT */
if (innobase_page_size != (1LL << 14)) {
int n_shift = (int)get_bit_shift((ulint) innobase_page_size);
@@ -1565,7 +1592,7 @@ innodb_init_param(void)
changes the value so that it becomes the number of database pages. */
srv_buf_pool_size = (ulint) xtrabackup_use_memory;
- srv_buf_pool_chunk_unit = srv_buf_pool_size;
+ srv_buf_pool_chunk_unit = (ulong)srv_buf_pool_size;
srv_buf_pool_instances = 1;
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
@@ -2135,28 +2162,6 @@ check_if_skip_table(
return(FALSE);
}
-/** @return the tablespace flags from a given data file
-@retval ULINT_UNDEFINED if the file is not readable */
-ulint xb_get_space_flags(pfs_os_file_t file)
-{
- byte *buf;
- byte *page;
- ulint flags;
-
- buf = static_cast<byte *>(malloc(2 * UNIV_PAGE_SIZE));
- page = static_cast<byte *>(ut_align(buf, UNIV_PAGE_SIZE));
-
- if (os_file_read(IORequestRead, file, page, 0, UNIV_PAGE_SIZE)) {
- flags = fsp_header_get_flags(page);
- } else {
- flags = ULINT_UNDEFINED;
- }
-
- free(buf);
-
- return(flags);
-}
-
const char*
xb_get_copy_action(const char *dflt)
{
@@ -2213,10 +2218,6 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
return(FALSE);
}
- if (opt_lock_ddl_per_table) {
- mdl_lock_table(node->space->id);
- }
-
if (!changed_page_bitmap) {
read_filter = &rf_pass_through;
}
@@ -2421,8 +2422,15 @@ xtrabackup_copy_logfile(copy_logfile copy)
log_mutex_enter();
- lsn_t lsn = log_group_read_log_seg(log_sys->buf, &log_sys->log,
- start_lsn, end_lsn);
+ lsn_t lsn= start_lsn;
+ for(int retries= 0; retries < 100; retries++) {
+ if (log_group_read_log_seg(log_sys->buf, &log_sys->log,
+ &lsn, end_lsn)){
+ break;
+ }
+ msg("Retrying read of a redo log block");
+ my_sleep(1000);
+ }
start_lsn = xtrabackup_copy_log(copy, start_lsn, lsn);
@@ -2448,7 +2456,7 @@ xtrabackup_copy_logfile(copy_logfile copy)
return(false);
}
-static os_thread_ret_t log_copying_thread(void*)
+static os_thread_ret_t DECLARE_THREAD(log_copying_thread)(void*)
{
/*
Initialize mysys thread-specific memory so we can
@@ -2471,7 +2479,7 @@ static os_thread_ret_t log_copying_thread(void*)
}
/* io throttle watching (rough) */
-static os_thread_ret_t io_watching_thread(void*)
+static os_thread_ret_t DECLARE_THREAD(io_watching_thread)(void*)
{
/* currently, for --backup only */
ut_a(xtrabackup_backup);
@@ -2497,7 +2505,7 @@ static os_thread_ret_t io_watching_thread(void*)
Datafiles copying thread.*/
static
os_thread_ret_t
-data_copy_thread_func(
+DECLARE_THREAD(data_copy_thread_func)(
/*==================*/
void *arg) /* thread context */
{
@@ -2683,10 +2691,10 @@ xb_load_single_table_tablespace(
name = static_cast<char*>(ut_malloc_nokey(pathlen));
if (dirname != NULL) {
- ut_snprintf(name, pathlen, "%s/%s", dirname, filname);
+ snprintf(name, pathlen, "%s/%s", dirname, filname);
name[pathlen - 5] = 0;
} else {
- ut_snprintf(name, pathlen, "%s", filname);
+ snprintf(name, pathlen, "%s", filname);
name[pathlen - 5] = 0;
}
@@ -2804,8 +2812,8 @@ static dberr_t enumerate_ibd_files(process_single_tablespace_func_t callback)
dbpath = static_cast<char*>(ut_malloc_nokey(dbpath_len));
}
- ut_snprintf(dbpath, dbpath_len,
- "%s/%s", fil_path_to_mysql_datadir, dbinfo.name);
+ snprintf(dbpath, dbpath_len,
+ "%s/%s", fil_path_to_mysql_datadir, dbinfo.name);
os_normalize_path(dbpath);
if (check_if_skip_database_by_path(dbpath)) {
@@ -2902,19 +2910,7 @@ xb_load_tablespaces()
&flush_lsn);
if (err != DB_SUCCESS) {
- msg("mariabackup: Could not open or create data files.\n"
- "mariabackup: If you tried to add new data files, and it "
- "failed here,\n"
- "mariabackup: you should now edit innodb_data_file_path in "
- "my.cnf back\n"
- "mariabackup: to what it was, and remove the new ibdata "
- "files InnoDB created\n"
- "mariabackup: in this failed attempt. InnoDB only wrote "
- "those files full of\n"
- "mariabackup: zeros, but did not yet use them in any way. "
- "But be careful: do not\n"
- "mariabackup: remove old data files which contain your "
- "precious data!\n");
+ msg("mariabackup: Could not open data files.\n");
return(err);
}
@@ -3037,7 +3033,7 @@ xb_validate_name(
exit(EXIT_FAILURE);
}
p = strpbrk(name, "/\\~");
- if (p && p - name < NAME_LEN) {
+ if (p && (uint) (p - name) < NAME_LEN) {
msg("mariabackup: name `%s` is not valid.\n", name);
exit(EXIT_FAILURE);
}
@@ -3519,7 +3515,13 @@ xtrabackup_backup_low()
"to '%s'.\n", filename);
return false;
}
-
+ sprintf(filename, "%s/%s", xtrabackup_extra_lsndir,
+ XTRABACKUP_INFO);
+ if (!write_xtrabackup_info(mysql_connection, filename, false)) {
+ msg("mariabackup: Error: failed to write info "
+ "to '%s'.\n", filename);
+ return false;
+ }
}
return true;
@@ -3569,15 +3571,15 @@ xtrabackup_backup_func()
"or RENAME TABLE during the backup, inconsistent backup will be "
"produced.\n");
- if (opt_lock_ddl_per_table) {
- mdl_lock_init();
- }
+
/* initialize components */
if(innodb_init_param()) {
fail:
stop_backup_threads();
- innodb_shutdown();
+ if (fil_system) {
+ innodb_shutdown();
+ }
return(false);
}
@@ -3639,7 +3641,6 @@ fail:
/* Reset the system variables in the recovery module. */
recv_sys_var_init();
trx_pool_init();
- row_mysql_init();
ut_crc32_init();
crc_init();
@@ -3671,8 +3672,6 @@ fail:
"innodb_redo_log", SRV_LOG_SPACE_FIRST_ID, 0,
FIL_TYPE_LOG, NULL);
- lock_sys_create(srv_lock_table_size);
-
for (i = 0; i < srv_n_log_files; i++) {
err = open_or_create_log_file(space, &log_file_created, i);
if (err != DB_SUCCESS) {
@@ -3856,7 +3855,7 @@ reread_log_header:
err = xb_load_tablespaces();
if (err != DB_SUCCESS) {
msg("mariabackup: error: xb_load_tablespaces() failed with"
- "error code %u\n", err);
+ " error code %u\n", err);
goto fail;
}
@@ -3887,6 +3886,10 @@ reread_log_header:
"files transfer\n", xtrabackup_parallel);
}
+ if (opt_lock_ddl_per_table) {
+ mdl_lock_all();
+ }
+
it = datafiles_iter_new(fil_system);
if (it == NULL) {
msg("mariabackup: Error: datafiles_iter_new() failed.\n");
@@ -4311,12 +4314,12 @@ xtrabackup_apply_delta(
page_size = info.page_size.physical();
page_size_shift = get_bit_shift(page_size);
- msg("mariabackup: page size for %s is %lu bytes\n",
+ msg("mariabackup: page size for %s is %zu bytes\n",
src_path, page_size);
if (page_size_shift < 10 ||
page_size_shift > UNIV_PAGE_SIZE_SHIFT_MAX) {
msg("mariabackup: error: invalid value of page_size "
- "(%lu bytes) read from %s\n", page_size, meta_path);
+ "(%zu bytes) read from %s\n", page_size, meta_path);
goto error;
}
@@ -4418,10 +4421,29 @@ xtrabackup_apply_delta(
if (off == 0) {
/* Read tablespace size from page 0,
and extend the file to specified size.*/
- os_offset_t n_pages = mach_read_from_4(buf + FSP_HEADER_OFFSET + FSP_SIZE);
- success = os_file_set_size(dst_path, dst_file, n_pages*page_size);
- if (!success)
- goto error;
+ os_offset_t n_pages = mach_read_from_4(
+ buf + FSP_HEADER_OFFSET + FSP_SIZE);
+ if (mach_read_from_4(buf
+ + FIL_PAGE_SPACE_ID)) {
+ if (!os_file_set_size(
+ dst_path, dst_file,
+ n_pages * page_size))
+ goto error;
+ } else if (fil_space_t* space
+ = fil_space_acquire(0)) {
+ /* The system tablespace can
+ consist of multiple files. The
+ first one has full tablespace
+ size in page 0, but only the last
+ file should be extended. */
+ fil_node_t* n = UT_LIST_GET_FIRST(
+ space->chain);
+ bool fail = !strcmp(n->name, dst_path)
+ && !fil_space_extend(
+ space, (ulint)n_pages);
+ fil_space_release(space);
+ if (fail) goto error;
+ }
}
success = os_file_write(IORequestWrite,
@@ -4511,7 +4533,7 @@ xb_process_datadir(
handle_datadir_entry_func_t func) /*!<in: callback */
{
ulint ret;
- char dbpath[OS_FILE_MAX_PATH];
+ char dbpath[OS_FILE_MAX_PATH+1];
os_file_dir_t dir;
os_file_dir_t dbdir;
os_file_stat_t dbinfo;
@@ -4577,7 +4599,7 @@ next_file_item_1:
goto next_datadir_item;
}
- snprintf(dbpath, sizeof(dbpath), "%s/%s", path, dbinfo.name);
+ snprintf(dbpath, sizeof(dbpath)-1, "%s/%s", path, dbinfo.name);
os_normalize_path(dbpath);
@@ -4820,37 +4842,23 @@ xtrabackup_prepare_func(char** argv)
}
if (ok) {
- mtr_t mtr;
- mtr.start();
- const trx_sysf_t* sys_header = trx_sysf_get(&mtr);
-
- if (mach_read_from_4(TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
- + sys_header)
- == TRX_SYS_MYSQL_LOG_MAGIC_N) {
- ulonglong pos = mach_read_from_8(
- TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET
- + sys_header);
- const char* name = reinterpret_cast<const char*>(
- TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME
- + sys_header);
- msg("Last binlog file %s, position %llu\n", name, pos);
-
- /* output to xtrabackup_binlog_pos_innodb and
- (if backup_safe_binlog_info was available on
- the server) to xtrabackup_binlog_info. In the
- latter case xtrabackup_binlog_pos_innodb
- becomes redundant and is created only for
- compatibility. */
- ok = store_binlog_info(
- "xtrabackup_binlog_pos_innodb", name, pos)
- && (!recover_binlog_info || store_binlog_info(
- XTRABACKUP_BINLOG_INFO,
- name, pos));
- }
-
- mtr.commit();
+ msg("Last binlog file %s, position %lld\n",
+ trx_sys.recovered_binlog_filename,
+ longlong(trx_sys.recovered_binlog_offset));
+
+ /* output to xtrabackup_binlog_pos_innodb and
+ (if backup_safe_binlog_info was available on
+ the server) to xtrabackup_binlog_info. In the
+ latter case xtrabackup_binlog_pos_innodb
+ becomes redundant and is created only for
+ compatibility. */
+ ok = store_binlog_info("xtrabackup_binlog_pos_innodb",
+ trx_sys.recovered_binlog_filename,
+ trx_sys.recovered_binlog_offset)
+ && (!recover_binlog_info
+ || store_binlog_info(XTRABACKUP_BINLOG_INFO,
+ trx_sys.recovered_binlog_filename,
+ trx_sys.recovered_binlog_offset));
}
/* Check whether the log is applied enough or not. */
@@ -4944,9 +4952,19 @@ xb_init()
return(false);
}
- if (opt_rsync && xtrabackup_stream_fmt) {
- msg("Error: --rsync doesn't work with --stream\n");
- return(false);
+ if (xtrabackup_backup && opt_rsync)
+ {
+ if (xtrabackup_stream_fmt)
+ {
+ msg("Error: --rsync doesn't work with --stream\n");
+ return(false);
+ }
+ bool have_rsync = IF_WIN(false, (system("rsync --version > /dev/null 2>&1") == 0));
+ if (!have_rsync)
+ {
+ msg("Error: rsync executable not found, cannot run backup with --rsync\n");
+ return false;
+ }
}
n_mixed_options = 0;
@@ -5044,7 +5062,7 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
setup_error_messages();
sys_var_init();
plugin_mutex_init();
- mysql_rwlock_init(key_rwlock_LOCK_system_variables_hash, &LOCK_system_variables_hash);
+ mysql_prlock_init(key_rwlock_LOCK_system_variables_hash, &LOCK_system_variables_hash);
opt_stack_trace = 1;
test_flags |= TEST_SIGINT;
init_signals();
@@ -5518,7 +5536,7 @@ static int main_low(char** argv)
static int get_exepath(char *buf, size_t size, const char *argv0)
{
#ifdef _WIN32
- DWORD ret = GetModuleFileNameA(NULL, buf, size);
+ DWORD ret = GetModuleFileNameA(NULL, buf, (DWORD)size);
if (ret > 0)
return 0;
#elif defined(__linux__)
diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h
index 045294a2f9e..8eabf8f0e7e 100644
--- a/extra/mariabackup/xtrabackup.h
+++ b/extra/mariabackup/xtrabackup.h
@@ -149,10 +149,6 @@ void xtrabackup_io_throttling(void);
my_bool xb_write_delta_metadata(const char *filename,
const xb_delta_info_t *info);
-/** @return the tablespace flags from a given data file
-@retval ULINT_UNDEFINED if the file is not readable */
-ulint xb_get_space_flags(pfs_os_file_t file);
-
/************************************************************************
Checks if a table specified as a name in the form "database/name" (InnoDB 5.6)
or "./database/name.ibd" (InnoDB 5.5-) should be skipped from backup based on
diff --git a/extra/perror.c b/extra/perror.c
index e96002cbb7b..3bc5120db48 100644
--- a/extra/perror.c
+++ b/extra/perror.c
@@ -204,7 +204,7 @@ static my_bool print_win_error_msg(DWORD error, my_bool verbose)
NULL))
{
if (verbose)
- printf("Win32 error code %d: %s", error, s);
+ printf("Win32 error code %lu: %s", error, s);
else
puts(s);
LocalFree(s);
diff --git a/extra/resolve_stack_dump.c b/extra/resolve_stack_dump.c
index 576710e0bde..dbd9941141d 100644
--- a/extra/resolve_stack_dump.c
+++ b/extra/resolve_stack_dump.c
@@ -192,7 +192,7 @@ static my_long_addr_t read_addr(char** buf)
while((c = hex_val(*p++)) != HEX_INVALID)
addr = (addr << 4) + c;
- *buf = p;
+ *buf= p-1;
return addr;
}
@@ -203,6 +203,7 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
if (!se->addr)
return -1;
+ buf++;
while (my_isspace(&my_charset_latin1,*buf++))
/* empty */;
@@ -281,32 +282,47 @@ static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se)
}
+/*
+ Resolve anything that starts with [0x or (+0x or start of line and 0x
+ Skip '_end' as this is an indication of a wrong symbol (stack?)
+*/
+
static void do_resolve()
{
char buf[1024], *p;
while (fgets(buf, sizeof(buf), fp_dump))
{
- /* skip bracket */
- p= (p= strchr(buf, '[')) ? p+1 : buf;
- /* skip space */
- while (my_isspace(&my_charset_latin1,*p))
- ++p;
-
- if (*p++ == '0' && *p++ == 'x')
+ for (p= buf ; *p ; p++)
{
- SYM_ENTRY se ;
- uchar* addr = (uchar*)read_addr(&p);
- if (resolve_addr(addr, &se))
- fprintf(fp_out, "%p %s + %d\n", addr, se.symbol,
- (int) (addr - se.addr));
+ int found= 0;
+ if (p[0] == '[' && p[1] == '0' && p[2] == 'x')
+ found= 3;
+ if (p[0] == '(' && p[1] == '+' && p[2] == '0' && p[3] == 'x')
+ found= 4;
+
+ /* For stdin */
+ if (p == buf && p[0] == '0' && p[1] == 'x')
+ found= 2;
+
+ if (found)
+ {
+ SYM_ENTRY se ;
+ uchar *addr;
+ char *tmp= p + found;
+ addr= (uchar*)read_addr(&tmp);
+ if (resolve_addr(addr, &se) && strcmp(se.symbol, "_end"))
+ {
+ fprintf(fp_out, "%c%p %s + %d", *p, addr, se.symbol,
+ (int) (addr - se.addr));
+ p= tmp-1;
+ }
+ else
+ {
+ fputc(*p, stdout);
+ }
+ }
else
- fprintf(fp_out, "%p (?)\n", addr);
-
- }
- else
- {
- fputs(buf, fp_out);
- continue;
+ fputc(*p, stdout);
}
}
}
diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp
index 1092e428351..3cfa87b0d80 100644
--- a/extra/yassl/src/cert_wrapper.cpp
+++ b/extra/yassl/src/cert_wrapper.cpp
@@ -299,10 +299,10 @@ int CertManager::Validate()
ASN1_STRING beforeDate, afterDate;
beforeDate.data= (unsigned char *) cert.GetBeforeDate();
beforeDate.type= cert.GetBeforeDateType();
- beforeDate.length= strlen((char *) beforeDate.data) + 1;
+ beforeDate.length= (int)strlen((char *) beforeDate.data) + 1;
afterDate.data= (unsigned char *) cert.GetAfterDate();
afterDate.type= cert.GetAfterDateType();
- afterDate.length= strlen((char *) afterDate.data) + 1;
+ afterDate.length= (int)strlen((char *) afterDate.data) + 1;
peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(),
sSz, &beforeDate, &afterDate,
cert.GetIssuerCnStart(), cert.GetIssuerCnLength(),
@@ -348,10 +348,10 @@ int CertManager::SetPrivateKey(const x509& key)
ASN1_STRING beforeDate, afterDate;
beforeDate.data= (unsigned char *) cd.GetBeforeDate();
beforeDate.type= cd.GetBeforeDateType();
- beforeDate.length= strlen((char *) beforeDate.data) + 1;
+ beforeDate.length= (int)strlen((char *) beforeDate.data) + 1;
afterDate.data= (unsigned char *) cd.GetAfterDate();
afterDate.type= cd.GetAfterDateType();
- afterDate.length= strlen((char *) afterDate.data) + 1;
+ afterDate.length= (int)strlen((char *) afterDate.data) + 1;
selfX509_ = NEW_YS X509(cd.GetIssuer(), iSz, cd.GetCommonName(),
sSz, &beforeDate, &afterDate,
cd.GetIssuerCnStart(), cd.GetIssuerCnLength(),
diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp
index 9b099973578..de8025a8353 100644
--- a/extra/yassl/src/socket_wrapper.cpp
+++ b/extra/yassl/src/socket_wrapper.cpp
@@ -42,7 +42,6 @@
#endif
#ifdef _WIN32
- const int SOCKET_EINVAL = WSAEINVAL;
const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK;
const int SOCKET_EAGAIN = WSAEWOULDBLOCK;
#else
@@ -58,7 +57,7 @@ namespace {
extern "C" long system_recv(void *ptr, void *buf, size_t count, int flags)
{
yaSSL::socket_t *socket = (yaSSL::socket_t *) ptr;
- return ::recv(*socket, reinterpret_cast<char *>(buf), count, flags);
+ return ::recv(*socket, reinterpret_cast<char *>(buf), (int)count, flags);
}
@@ -66,7 +65,7 @@ extern "C" long system_send(void *ptr, const void *buf, size_t count,
int flags)
{
yaSSL::socket_t *socket = (yaSSL::socket_t *) ptr;
- return ::send(*socket, reinterpret_cast<const char *>(buf), count, flags);
+ return ::send(*socket, reinterpret_cast<const char *>(buf), (int)count, flags);
}
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index 1dc89df9d86..a9e41fb997a 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -921,10 +921,6 @@ static bool setPrefix(opaque* sha_input, int i)
return true;
}
-
-const char handshake_order[] = "Out of order HandShake Message!";
-
-
} // namespcae for locals
diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h
index b6d7ec6d28c..e2c3b10c267 100644
--- a/include/atomic/gcc_builtins.h
+++ b/include/atomic/gcc_builtins.h
@@ -1,7 +1,7 @@
#ifndef ATOMIC_GCC_BUILTINS_INCLUDED
#define ATOMIC_GCC_BUILTINS_INCLUDED
-/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2017 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
@@ -16,8 +16,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-#if defined(HAVE_GCC_C11_ATOMICS)
-#define MY_ATOMIC_MODE "gcc-atomics-smp"
#define MY_MEMORY_ORDER_RELAXED __ATOMIC_RELAXED
#define MY_MEMORY_ORDER_CONSUME __ATOMIC_CONSUME
@@ -42,18 +40,18 @@
#define my_atomic_add64_explicit(P, A, O) __atomic_fetch_add((P), (A), (O))
#define my_atomic_cas32_weak_explicit(P, E, D, S, F) \
- __atomic_compare_exchange_n((P), (E), (D), true, (S), (F))
+ __atomic_compare_exchange_n((P), (E), (D), 1, (S), (F))
#define my_atomic_cas64_weak_explicit(P, E, D, S, F) \
- __atomic_compare_exchange_n((P), (E), (D), true, (S), (F))
+ __atomic_compare_exchange_n((P), (E), (D), 1, (S), (F))
#define my_atomic_casptr_weak_explicit(P, E, D, S, F) \
- __atomic_compare_exchange_n((P), (E), (D), true, (S), (F))
+ __atomic_compare_exchange_n((P), (E), (D), 1, (S), (F))
#define my_atomic_cas32_strong_explicit(P, E, D, S, F) \
- __atomic_compare_exchange_n((P), (E), (D), false, (S), (F))
+ __atomic_compare_exchange_n((P), (E), (D), 0, (S), (F))
#define my_atomic_cas64_strong_explicit(P, E, D, S, F) \
- __atomic_compare_exchange_n((P), (E), (D), false, (S), (F))
+ __atomic_compare_exchange_n((P), (E), (D), 0, (S), (F))
#define my_atomic_casptr_strong_explicit(P, E, D, S, F) \
- __atomic_compare_exchange_n((P), (E), (D), false, (S), (F))
+ __atomic_compare_exchange_n((P), (E), (D), 0, (S), (F))
#define my_atomic_store32(P, D) __atomic_store_n((P), (D), __ATOMIC_SEQ_CST)
#define my_atomic_store64(P, D) __atomic_store_n((P), (D), __ATOMIC_SEQ_CST)
@@ -76,21 +74,5 @@
__atomic_compare_exchange_n((P), (E), (D), 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define my_atomic_casptr(P, E, D) \
__atomic_compare_exchange_n((P), (E), (D), 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
-#else
-#define MY_ATOMIC_MODE "gcc-builtins-smp"
-#define make_atomic_load_body(S) \
- ret= __sync_fetch_and_or(a, 0);
-#define make_atomic_store_body(S) \
- (void) __sync_lock_test_and_set(a, v);
-#define make_atomic_add_body(S) \
- v= __sync_fetch_and_add(a, v);
-#define make_atomic_fas_body(S) \
- v= __sync_lock_test_and_set(a, v);
-#define make_atomic_cas_body(S) \
- int ## S sav; \
- int ## S cmp_val= *cmp; \
- sav= __sync_val_compare_and_swap(a, cmp_val, set);\
- if (!(ret= (sav == cmp_val))) *cmp= sav
-#endif
#endif /* ATOMIC_GCC_BUILTINS_INCLUDED */
diff --git a/include/atomic/gcc_sync.h b/include/atomic/gcc_sync.h
new file mode 100644
index 00000000000..82eea35b2ce
--- /dev/null
+++ b/include/atomic/gcc_sync.h
@@ -0,0 +1,106 @@
+#ifndef GCC_SYNC_INCLUDED
+#define GCC_SYNC_INCLUDED
+
+/* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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-1301 USA */
+
+/* Old GCC __sync builtins introduced in GCC 4.1 */
+
+static inline int my_atomic_cas32(int32 volatile *a, int32 *cmp, int32 set)
+{
+ int32 cmp_val= *cmp;
+ int32 sav= __sync_val_compare_and_swap(a, cmp_val, set);
+ int ret= (sav == cmp_val);
+ if (!ret)
+ *cmp = sav;
+ return ret;
+}
+
+static inline int my_atomic_cas64(int64 volatile *a, int64 *cmp, int64 set)
+{
+ int64 cmp_val= *cmp;
+ int64 sav= __sync_val_compare_and_swap(a, cmp_val, set);
+ int ret= (sav == cmp_val);
+ if (!ret)
+ *cmp = sav;
+ return ret;
+}
+
+static inline int my_atomic_casptr(void * volatile *a, void **cmp, void *set)
+{
+ void *cmp_val= *cmp;
+ void *sav= __sync_val_compare_and_swap(a, cmp_val, set);
+ int ret= (sav == cmp_val);
+ if (!ret)
+ *cmp = sav;
+ return ret;
+}
+
+static inline int32 my_atomic_add32(int32 volatile *a, int32 v)
+{
+ return __sync_fetch_and_add(a, v);
+}
+
+static inline int64 my_atomic_add64(int64 volatile *a, int64 v)
+{
+ return __sync_fetch_and_add(a, v);
+}
+
+static inline int32 my_atomic_fas32(int32 volatile *a, int32 v)
+{
+ return __sync_lock_test_and_set(a, v);
+}
+
+static inline int64 my_atomic_fas64(int64 volatile *a, int64 v)
+{
+ return __sync_lock_test_and_set(a, v);
+}
+
+static inline void * my_atomic_fasptr(void * volatile *a, void * v)
+{
+ return __sync_lock_test_and_set(a, v);
+}
+
+static inline int32 my_atomic_load32(int32 volatile *a)
+{
+ return __sync_fetch_and_or(a, 0);
+}
+
+static inline int64 my_atomic_load64(int64 volatile *a)
+{
+ return __sync_fetch_and_or(a, 0);
+}
+
+static inline void* my_atomic_loadptr(void * volatile *a)
+{
+ return __sync_fetch_and_or(a, 0);
+}
+
+static inline void my_atomic_store32(int32 volatile *a, int32 v)
+{
+ (void) __sync_lock_test_and_set(a, v);
+}
+
+static inline void my_atomic_store64(int64 volatile *a, int64 v)
+{
+ (void) __sync_lock_test_and_set(a, v);
+}
+
+static inline void my_atomic_storeptr(void * volatile *a, void *v)
+{
+ (void) __sync_lock_test_and_set(a, v);
+}
+
+#endif /* GCC_SYNC_INCLUDED */
diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h
index d06229ce5ef..d5eaa4738c7 100644
--- a/include/atomic/generic-msvc.h
+++ b/include/atomic/generic-msvc.h
@@ -1,5 +1,7 @@
-/* Copyright (c) 2006-2008 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+#ifndef ATOMIC_MSC_INCLUDED
+#define ATOMIC_MSC_INCLUDED
+
+/* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -14,115 +16,125 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-#ifndef _atomic_h_cleanup_
-#define _atomic_h_cleanup_ "atomic/generic-msvc.h"
-
#include <windows.h>
-/*
- x86 compilers (both VS2003 or VS2005) never use instrinsics, but generate
- function calls to kernel32 instead, even in the optimized build.
- We force intrinsics as described in MSDN documentation for
- _InterlockedCompareExchange.
-*/
-#ifdef _M_IX86
-#if (_MSC_VER >= 1500)
-#include <intrin.h>
-#else
-C_MODE_START
-/*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/
-LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp);
-LONGLONG _InterlockedCompareExchange64 (LONGLONG volatile *Target,
- LONGLONG Value, LONGLONG Comp);
-C_MODE_END
-
-#pragma intrinsic(_InterlockedCompareExchange)
-#pragma intrinsic(_InterlockedCompareExchange64)
-#endif
+static inline int my_atomic_cas32(int32 volatile *a, int32 *cmp, int32 set)
+{
+ int32 initial_cmp= *cmp;
+ int32 initial_a= InterlockedCompareExchange((volatile LONG*)a,
+ set, initial_cmp);
+ int ret= (initial_a == initial_cmp);
+ if (!ret)
+ *cmp= initial_a;
+ return ret;
+}
+
+static inline int my_atomic_cas64(int64 volatile *a, int64 *cmp, int64 set)
+{
+ int64 initial_cmp= *cmp;
+ int64 initial_a= InterlockedCompareExchange64((volatile LONGLONG*)a,
+ (LONGLONG)set,
+ (LONGLONG)initial_cmp);
+ int ret= (initial_a == initial_cmp);
+ if (!ret)
+ *cmp= initial_a;
+ return ret;
+}
+
+static inline int my_atomic_casptr(void * volatile *a, void **cmp, void *set)
+{
+ void *initial_cmp= *cmp;
+ void *initial_a= InterlockedCompareExchangePointer(a, set, initial_cmp);
+ int ret= (initial_a == initial_cmp);
+ if (!ret)
+ *cmp= initial_a;
+ return ret;
+}
+
+static inline int32 my_atomic_add32(int32 volatile *a, int32 v)
+{
+ return (int32)InterlockedExchangeAdd((volatile LONG*)a, v);
+}
+
+static inline int64 my_atomic_add64(int64 volatile *a, int64 v)
+{
+ return (int64)InterlockedExchangeAdd64((volatile LONGLONG*)a, (LONGLONG)v);
+}
+
-#define InterlockedCompareExchange _InterlockedCompareExchange
-#define InterlockedCompareExchange64 _InterlockedCompareExchange64
/*
- No need to do something special for InterlockedCompareExchangePointer
- as it is a #define to InterlockedCompareExchange. The same applies to
- InterlockedExchangePointer.
+ According to MSDN:
+
+ Simple reads and writes to properly-aligned 32-bit variables are atomic
+ operations.
+ ...
+ Simple reads and writes to properly aligned 64-bit variables are atomic on
+ 64-bit Windows. Reads and writes to 64-bit values are not guaranteed to be
+ atomic on 32-bit Windows.
+
+ https://msdn.microsoft.com/en-us/library/windows/desktop/ms684122(v=vs.85).aspx
*/
-#endif /*_M_IX86*/
-
-#define MY_ATOMIC_MODE "msvc-intrinsics"
-/* Implement using CAS on WIN32 */
-#define IL_COMP_EXCHG32(X,Y,Z) \
- InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z))
-#define IL_COMP_EXCHG64(X,Y,Z) \
- InterlockedCompareExchange64((volatile LONGLONG *)(X), \
- (LONGLONG)(Y),(LONGLONG)(Z))
-#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer
-
-#define make_atomic_cas_body(S) \
- int ## S initial_cmp= *cmp; \
- int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \
- if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a;
-
-#ifndef _M_IX86
-/* Use full set of optimised functions on WIN64 */
-#define IL_EXCHG_ADD32(X,Y) \
- InterlockedExchangeAdd((volatile LONG *)(X),(Y))
-#define IL_EXCHG_ADD64(X,Y) \
- InterlockedExchangeAdd64((volatile LONGLONG *)(X),(LONGLONG)(Y))
-#define IL_EXCHG32(X,Y) \
- InterlockedExchange((volatile LONG *)(X),(Y))
-#define IL_EXCHG64(X,Y) \
- InterlockedExchange64((volatile LONGLONG *)(X),(LONGLONG)(Y))
-#define IL_EXCHGptr InterlockedExchangePointer
-
-#define make_atomic_add_body(S) \
- v= IL_EXCHG_ADD ## S (a, v)
-#define make_atomic_swap_body(S) \
- v= IL_EXCHG ## S (a, v)
-#define make_atomic_load_body(S) \
- ret= 0; /* avoid compiler warning */ \
- ret= IL_COMP_EXCHG ## S (a, ret, ret);
-#endif
-/*
- my_yield_processor (equivalent of x86 PAUSE instruction) should be used
- to improve performance on hyperthreaded CPUs. Intel recommends to use it in
- spin loops also on non-HT machines to reduce power consumption (see e.g
- http://softwarecommunity.intel.com/articles/eng/2004.htm)
-
- Running benchmarks for spinlocks implemented with InterlockedCompareExchange
- and YieldProcessor shows that much better performance is achieved by calling
- YieldProcessor in a loop - that is, yielding longer. On Intel boxes setting
- loop count in the range 200-300 brought best results.
- */
-#ifndef YIELD_LOOPS
-#define YIELD_LOOPS 200
-#endif
-static __inline int my_yield_processor()
+static inline int32 my_atomic_load32(int32 volatile *a)
+{
+ int32 value= *a;
+ MemoryBarrier();
+ return value;
+}
+
+static inline int64 my_atomic_load64(int64 volatile *a)
{
- int i;
- for(i=0; i<YIELD_LOOPS; i++)
- {
-#if (_MSC_VER <= 1310)
- /* On older compilers YieldProcessor is not available, use inline assembly*/
- __asm { rep nop }
+#ifdef _M_X64
+ int64 value= *a;
+ MemoryBarrier();
+ return value;
#else
- YieldProcessor();
+ return (int64) InterlockedCompareExchange64((volatile LONGLONG *) a, 0, 0);
#endif
- }
- return 1;
}
-#define LF_BACKOFF my_yield_processor()
-#else /* cleanup */
+static inline void* my_atomic_loadptr(void * volatile *a)
+{
+ void *value= *a;
+ MemoryBarrier();
+ return value;
+}
+
+static inline int32 my_atomic_fas32(int32 volatile *a, int32 v)
+{
+ return (int32)InterlockedExchange((volatile LONG*)a, v);
+}
+
+static inline int64 my_atomic_fas64(int64 volatile *a, int64 v)
+{
+ return (int64)InterlockedExchange64((volatile LONGLONG*)a, v);
+}
+
+static inline void * my_atomic_fasptr(void * volatile *a, void * v)
+{
+ return InterlockedExchangePointer(a, v);
+}
-#undef IL_EXCHG_ADD32
-#undef IL_EXCHG_ADD64
-#undef IL_COMP_EXCHG32
-#undef IL_COMP_EXCHG64
-#undef IL_COMP_EXCHGptr
-#undef IL_EXCHG32
-#undef IL_EXCHG64
-#undef IL_EXCHGptr
+static inline void my_atomic_store32(int32 volatile *a, int32 v)
+{
+ MemoryBarrier();
+ *a= v;
+}
+static inline void my_atomic_store64(int64 volatile *a, int64 v)
+{
+#ifdef _M_X64
+ MemoryBarrier();
+ *a= v;
+#else
+ (void) InterlockedExchange64((volatile LONGLONG *) a, v);
#endif
+}
+
+static inline void my_atomic_storeptr(void * volatile *a, void *v)
+{
+ MemoryBarrier();
+ *a= v;
+}
+
+#endif /* ATOMIC_MSC_INCLUDED */
diff --git a/include/atomic/solaris.h b/include/atomic/solaris.h
index 578e7c46c7c..5be36ec5e77 100644
--- a/include/atomic/solaris.h
+++ b/include/atomic/solaris.h
@@ -1,4 +1,7 @@
-/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#ifndef ATOMIC_SOLARIS_INCLUDED
+#define ATOMIC_SOLARIS_INCLUDED
+
+/* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -13,51 +16,102 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-#ifndef _atomic_h_cleanup_
-#define _atomic_h_cleanup_ "atomic/solaris.h"
-
#include <atomic.h>
-#define MY_ATOMIC_MODE "solaris-atomic"
-
#if defined(__GNUC__)
#define atomic_typeof(T,V) __typeof__(V)
#else
#define atomic_typeof(T,V) T
#endif
-#define uintptr_t void *
-#define atomic_or_ptr_nv(X,Y) (void *)atomic_or_ulong_nv((volatile ulong_t *)X, Y)
-
-#define make_atomic_cas_body(S) \
- atomic_typeof(uint ## S ## _t, *cmp) sav; \
- sav = atomic_cas_ ## S( \
- (volatile uint ## S ## _t *)a, \
- (uint ## S ## _t)*cmp, \
- (uint ## S ## _t)set); \
- if (! (ret= (sav == *cmp))) \
+static inline int my_atomic_cas32(int32 volatile *a, int32 *cmp, int32 set)
+{
+ int ret;
+ atomic_typeof(uint32_t, *cmp) sav;
+ sav= atomic_cas_32((volatile uint32_t *)a, (uint32_t)*cmp, (uint32_t)set);
+ ret= (sav == *cmp);
+ if (!ret)
*cmp= sav;
-
-#define make_atomic_add_body(S) \
- int ## S nv; /* new value */ \
- nv= atomic_add_ ## S ## _nv((volatile uint ## S ## _t *)a, v); \
- v= nv - v
-
-/* ------------------------------------------------------------------------ */
-
-#define make_atomic_load_body(S) \
- ret= atomic_or_ ## S ## _nv((volatile uint ## S ## _t *)a, 0)
-
-#define make_atomic_store_body(S) \
- (void) atomic_swap_ ## S((volatile uint ## S ## _t *)a, (uint ## S ## _t)v)
-
-#define make_atomic_fas_body(S) \
- v= atomic_swap_ ## S((volatile uint ## S ## _t *)a, (uint ## S ## _t)v)
-
-#else /* cleanup */
-
-#undef uintptr_t
-#undef atomic_or_ptr_nv
-
-#endif
-
+ return ret;
+}
+
+static inline int my_atomic_cas64(int64 volatile *a, int64 *cmp, int64 set)
+{
+ int ret;
+ atomic_typeof(uint64_t, *cmp) sav;
+ sav= atomic_cas_64((volatile uint64_t *)a, (uint64_t)*cmp, (uint64_t)set);
+ ret= (sav == *cmp);
+ if (!ret)
+ *cmp= sav;
+ return ret;
+}
+
+static inline int my_atomic_casptr(void * volatile *a, void **cmp, void *set)
+{
+ int ret;
+ atomic_typeof(void *, *cmp) sav;
+ sav= atomic_cas_ptr((volatile void **)a, (void *)*cmp, (void *)set);
+ ret= (sav == *cmp);
+ if (!ret)
+ *cmp= sav;
+ return ret;
+}
+
+static inline int32 my_atomic_add32(int32 volatile *a, int32 v)
+{
+ int32 nv= atomic_add_32_nv((volatile uint32_t *)a, v);
+ return nv - v;
+}
+
+static inline int64 my_atomic_add64(int64 volatile *a, int64 v)
+{
+ int64 nv= atomic_add_64_nv((volatile uint64_t *)a, v);
+ return nv - v;
+}
+
+static inline int32 my_atomic_fas32(int32 volatile *a, int32 v)
+{
+ return atomic_swap_32((volatile uint32_t *)a, (uint32_t)v);
+}
+
+static inline int64 my_atomic_fas64(int64 volatile *a, int64 v)
+{
+ return atomic_swap_64((volatile uint64_t *)a, (uint64_t)v);
+}
+
+static inline void * my_atomic_fasptr(void * volatile *a, void * v)
+{
+ return atomic_swap_ptr(a, v);
+}
+
+static inline int32 my_atomic_load32(int32 volatile *a)
+{
+ return atomic_or_32_nv((volatile uint32_t *)a, 0);
+}
+
+static inline int64 my_atomic_load64(int64 volatile *a)
+{
+ return atomic_or_64_nv((volatile uint64_t *)a, 0);
+}
+
+static inline void* my_atomic_loadptr(void * volatile *a)
+{
+ return atomic_add_ptr_nv(a, 0);
+}
+
+static inline void my_atomic_store32(int32 volatile *a, int32 v)
+{
+ (void) atomic_swap_32((volatile uint32_t *)a, (uint32_t)v);
+}
+
+static inline void my_atomic_store64(int64 volatile *a, int64 v)
+{
+ (void) atomic_swap_64((volatile uint64_t *)a, (uint64_t)v);
+}
+
+static inline void my_atomic_storeptr(void * volatile *a, void *v)
+{
+ (void) atomic_swap_ptr((volatile void **)a, (void *)v);
+}
+
+#endif /* ATOMIC_SOLARIS_INCLUDED */
diff --git a/include/heap.h b/include/heap.h
index 724cf6c5f98..e92f649b87b 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -144,6 +144,7 @@ typedef struct st_heap_share
uint key_version; /* Updated on key change */
uint file_version; /* Update on clear */
uint reclength; /* Length of one record */
+ uint visible; /* Offset to the visible/deleted mark */
uint changed;
uint keys,max_key_length;
uint currently_disabled_keys; /* saved value from "keys" when disabled */
diff --git a/include/lf.h b/include/lf.h
index 1825de62b43..a9d7e9ee688 100644
--- a/include/lf.h
+++ b/include/lf.h
@@ -17,6 +17,7 @@
#define INCLUDE_LF_INCLUDED
#include <my_atomic.h>
+#include <my_cpu.h>
C_MODE_START
diff --git a/include/m_ctype.h b/include/m_ctype.h
index b78443f88f8..565eab9168f 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -376,7 +376,7 @@ typedef size_t (*my_charset_conv_case)(CHARSET_INFO *,
A structure to return the statistics of a native string copying,
when no Unicode conversion is involved.
- The stucture is OK to be unitialized before calling a copying routine.
+ The stucture is OK to be uninitialized before calling a copying routine.
A copying routine must populate the structure as follows:
- m_source_end_pos must be set by to a non-NULL value
in the range of the input string.
@@ -425,7 +425,7 @@ struct my_charset_handler_st
my_charset_conv_case caseup;
my_charset_conv_case casedn;
- /* Charset dependant snprintf() */
+ /* Charset dependent snprintf() */
size_t (*snprintf)(CHARSET_INFO *, char *to, size_t n,
const char *fmt,
...) ATTRIBUTE_FORMAT_FPTR(printf, 4, 5);
@@ -917,7 +917,7 @@ typedef struct
void my_string_metadata_get(MY_STRING_METADATA *metadata,
CHARSET_INFO *cs, const char *str, size_t len);
-uint my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong len);
+uint my_string_repertoire(CHARSET_INFO *cs, const char *str, size_t len);
my_bool my_charset_is_ascii_based(CHARSET_INFO *cs);
uint my_charset_repertoire(CHARSET_INFO *cs);
@@ -953,9 +953,9 @@ uint32 my_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
Protocol::store_warning() uses this to escape control
and non-convertable characters.
*/
-uint32 my_convert_using_func(char *to, uint32 to_length, CHARSET_INFO *to_cs,
+uint32 my_convert_using_func(char *to, size_t to_length, CHARSET_INFO *to_cs,
my_charset_conv_wc_mb mb_wc,
- const char *from, uint32 from_length,
+ const char *from, size_t from_length,
CHARSET_INFO *from_cs,
my_charset_conv_mb_wc wc_mb,
uint *errors);
diff --git a/include/m_string.h b/include/m_string.h
index f06acbea358..d7ee2582c88 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -22,7 +22,6 @@
#ifndef _m_string_h
#define _m_string_h
-#include "my_global.h" /* HAVE_* */
#include "my_decimal_limits.h"
#ifndef __USE_GNU
@@ -65,15 +64,6 @@
extern "C" {
#endif
-/*
- my_str_malloc(), my_str_realloc() and my_str_free() are assigned to
- implementations in strings/alloc.c, but can be overridden in
- the calling program.
- */
-extern void *(*my_str_malloc)(size_t);
-extern void *(*my_str_realloc)(void *, size_t);
-extern void (*my_str_free)(void *);
-
#ifdef DBUG_OFF
#if defined(HAVE_STPCPY) && MY_GNUC_PREREQ(3, 4) && !defined(__INTEL_COMPILER)
#define strmov(A,B) __builtin_stpcpy((A),(B))
@@ -211,6 +201,7 @@ extern ulonglong strtoull(const char *str, char **ptr, int base);
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
#define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
+#define LEX_STRING_WITH_LEN(X) (X).str, (X).length
typedef struct st_mysql_const_lex_string LEX_CSTRING;
diff --git a/include/ma_dyncol.h b/include/ma_dyncol.h
index cb03ccb5382..4f05b425afd 100644
--- a/include/ma_dyncol.h
+++ b/include/ma_dyncol.h
@@ -63,6 +63,15 @@ typedef struct st_mysql_lex_string LEX_STRING;
/* NO and OK is the same used just to show semantics */
#define ER_DYNCOL_NO ER_DYNCOL_OK
+#ifdef HAVE_CHARSET_utf8mb4
+#define DYNCOL_UTF (&my_charset_utf8mb4_general_ci)
+#else
+#define DYNCOL_UTF (&my_charset_utf8_general_ci)
+#endif
+
+/* escape json strings */
+#define DYNCOL_JSON_ESC ((char)1)
+
enum enum_dyncol_func_result
{
ER_DYNCOL_OK= 0,
diff --git a/include/my_alloc.h b/include/my_alloc.h
index b461065eb7c..3ba8a02fc48 100644
--- a/include/my_alloc.h
+++ b/include/my_alloc.h
@@ -52,6 +52,7 @@ typedef struct st_mem_root
unsigned int first_block_usage;
void (*error_handler)(void);
+ const char *name;
} MEM_ROOT;
#ifdef __cplusplus
diff --git a/include/my_atomic.h b/include/my_atomic.h
index bcb6005a8c2..1f5d85fcf12 100644
--- a/include/my_atomic.h
+++ b/include/my_atomic.h
@@ -101,7 +101,7 @@
sequentially-consistent operation ordering.
We choose implementation as follows: on Windows using Visual C++ the native
- implementation should be preferrable. When using gcc we prefer the Solaris
+ implementation should be preferable. When using gcc we prefer the Solaris
implementation before the gcc because of stability preference, we choose gcc
builtins if available.
*/
@@ -110,126 +110,10 @@
#include "atomic/generic-msvc.h"
#elif defined(HAVE_SOLARIS_ATOMIC)
#include "atomic/solaris.h"
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_C11_ATOMICS)
+#elif defined(HAVE_GCC_C11_ATOMICS)
#include "atomic/gcc_builtins.h"
-#endif
-
-
-#ifndef HAVE_GCC_C11_ATOMICS
-#ifndef make_atomic_cas_body
-/* nolock.h was not able to generate even a CAS function, fall back */
-#error atomic ops for this platform are not implemented
-#endif
-
-#define intptr void *
-
-/* define missing functions by using the already generated ones */
-#ifndef make_atomic_add_body
-#define make_atomic_add_body(S) \
- int ## S tmp=*a; \
- while (!my_atomic_cas ## S(a, &tmp, tmp+v)) ; \
- v=tmp;
-#endif
-#ifndef make_atomic_fas_body
-#define make_atomic_fas_body(S) \
- int ## S tmp=*a; \
- while (!my_atomic_cas ## S(a, &tmp, v)) ; \
- v=tmp;
-#endif
-#ifndef make_atomic_load_body
-#define make_atomic_load_body(S) \
- ret= 0; /* avoid compiler warning */ \
- (void)(my_atomic_cas ## S(a, &ret, ret));
-#endif
-#ifndef make_atomic_store_body
-#define make_atomic_store_body(S) \
- (void)(my_atomic_fas ## S (a, v));
-#endif
-
-#define make_atomic_cas(S) \
-static inline int my_atomic_cas ## S(int ## S volatile *a, \
- int ## S *cmp, int ## S set) \
-{ \
- int8 ret; \
- make_atomic_cas_body(S); \
- return ret; \
-}
-
-#define make_atomic_add(S) \
-static inline int ## S my_atomic_add ## S( \
- int ## S volatile *a, int ## S v) \
-{ \
- make_atomic_add_body(S); \
- return v; \
-}
-
-#define make_atomic_fas(S) \
-static inline int ## S my_atomic_fas ## S( \
- int ## S volatile *a, int ## S v) \
-{ \
- make_atomic_fas_body(S); \
- return v; \
-}
-
-#define make_atomic_load(S) \
-static inline int ## S my_atomic_load ## S(int ## S volatile *a)\
-{ \
- int ## S ret; \
- make_atomic_load_body(S); \
- return ret; \
-}
-
-#define make_atomic_store(S) \
-static inline void my_atomic_store ## S( \
- int ## S volatile *a, int ## S v) \
-{ \
- make_atomic_store_body(S); \
-}
-
-make_atomic_cas(32)
-make_atomic_cas(64)
-make_atomic_cas(ptr)
-
-make_atomic_add(32)
-make_atomic_add(64)
-
-make_atomic_load(32)
-make_atomic_load(64)
-make_atomic_load(ptr)
-
-make_atomic_fas(32)
-make_atomic_fas(64)
-make_atomic_fas(ptr)
-
-make_atomic_store(32)
-make_atomic_store(64)
-make_atomic_store(ptr)
-
-#ifdef _atomic_h_cleanup_
-#include _atomic_h_cleanup_
-#undef _atomic_h_cleanup_
-#endif
-
-#undef make_atomic_add
-#undef make_atomic_cas
-#undef make_atomic_load
-#undef make_atomic_store
-#undef make_atomic_fas
-#undef make_atomic_add_body
-#undef make_atomic_cas_body
-#undef make_atomic_load_body
-#undef make_atomic_store_body
-#undef make_atomic_fas_body
-#undef intptr
-#endif
-
-/*
- the macro below defines (as an expression) the code that
- will be run in spin-loops. Intel manuals recummend to have PAUSE there.
- It is expected to be defined in include/atomic/ *.h files
-*/
-#ifndef LF_BACKOFF
-#define LF_BACKOFF (1)
+#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
+#include "atomic/gcc_sync.h"
#endif
#if SIZEOF_LONG == 4
diff --git a/include/my_attribute.h b/include/my_attribute.h
index 14ed35cfe24..9959028bd2e 100644
--- a/include/my_attribute.h
+++ b/include/my_attribute.h
@@ -34,9 +34,9 @@
compilation warnings.
*/
#ifndef __attribute__
-# if !defined(__GNUC__)
+# if !defined(__GNUC__) && !defined(__clang__)
# define __attribute__(A)
-# else
+# elif defined(__GNUC__)
# ifndef GCC_VERSION
# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
# endif
diff --git a/include/my_base.h b/include/my_base.h
index b93300d7562..5472473efa7 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2012, Oracle and/or its affiliates.
- Copyright (c) 1995, 2017, MariaDB Corporation.
+ Copyright (c) 1995, 2018, 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
@@ -204,6 +204,17 @@ enum ha_extra_function {
HA_EXTRA_PREPARE_FOR_FORCED_CLOSE,
/* Inform handler that we will do an alter table */
HA_EXTRA_PREPARE_FOR_ALTER_TABLE,
+ /*
+ Used in ha_partition::handle_ordered_index_scan() to inform engine
+ that we are starting an ordered index scan. Needed by Spider
+ */
+ HA_EXTRA_STARTING_ORDERED_INDEX_SCAN,
+ /** Start writing rows during ALTER TABLE...ALGORITHM=COPY. */
+ HA_EXTRA_BEGIN_ALTER_COPY,
+ /** Finish writing rows during ALTER TABLE...ALGORITHM=COPY. */
+ HA_EXTRA_END_ALTER_COPY,
+ /** Fake the start of a statement after wsrep_load_data_splitting hack */
+ HA_EXTRA_FAKE_START_STMT
};
/* Compatible option, to be deleted in 6.0 */
@@ -277,7 +288,8 @@ enum ha_base_keytype {
This flag can be calculated -- it's based on key lengths comparison.
*/
#define HA_KEY_HAS_PART_KEY_SEG 65536
-
+/* Internal Flag Can be calcaluted */
+#define HA_INVISIBLE_KEY 2<<18
/* Automatic bits in key-flag */
#define HA_SPACE_PACK_USED 4 /* Test for if SPACE_PACK used */
@@ -408,6 +420,10 @@ enum ha_base_keytype {
when only HA_STATUS_VARIABLE but it won't be used.
*/
#define HA_STATUS_VARIABLE_EXTRA 128U
+/*
+ Treat empty table as empty (ignore HA_STATUS_TIME hack).
+*/
+#define HA_STATUS_OPEN 256U
/*
Errorcodes given by handler functions
diff --git a/include/my_bitmap.h b/include/my_bitmap.h
index 3e242280be4..14197955f9a 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -45,6 +45,8 @@ extern "C" {
/* compatibility functions */
#define bitmap_init(A,B,C,D) my_bitmap_init(A,B,C,D)
#define bitmap_free(A) my_bitmap_free(A)
+/* Reset memory. Faster then doing a full bzero */
+#define my_bitmap_clear(A) ((A)->bitmap= 0)
extern void create_last_word_mask(MY_BITMAP *map);
extern my_bool my_bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits,
diff --git a/include/my_compare.h b/include/my_compare.h
index 12f9971d49b..4387105aff8 100644
--- a/include/my_compare.h
+++ b/include/my_compare.h
@@ -84,31 +84,33 @@ typedef struct st_HA_KEYSEG /* Key-portion */
#define store_key_length_inc(key,length) \
{ if ((length) < 255) \
- { *(key)++= (length); } \
+ { *(key)++= (uchar)(length); } \
else \
{ *(key)=255; mi_int2store((key)+1,(length)); (key)+=3; } \
}
#define size_to_store_key_length(length) ((length) < 255 ? 1 : 3)
-#define get_rec_bits(bit_ptr, bit_ofs, bit_len) \
- (((((uint16) (bit_ptr)[1] << 8) | (uint16) (bit_ptr)[0]) >> (bit_ofs)) & \
- ((1 << (bit_len)) - 1))
-
-#define set_rec_bits(bits, bit_ptr, bit_ofs, bit_len) \
-{ \
- (bit_ptr)[0]= ((bit_ptr)[0] & ~(((1 << (bit_len)) - 1) << (bit_ofs))) | \
- ((bits) << (bit_ofs)); \
- if ((bit_ofs) + (bit_len) > 8) \
- (bit_ptr)[1]= ((bit_ptr)[1] & ~((1 << ((bit_len) - 8 + (bit_ofs))) - 1)) | \
- ((bits) >> (8 - (bit_ofs))); \
+static inline uchar get_rec_bits(const uchar *ptr, uchar ofs, uint len)
+{
+ uint16 val= ptr[0];
+ if (ofs + len > 8)
+ val|= (uint16)(ptr[1]) << 8;
+ return (val >> ofs) & ((1 << len) - 1);
+}
+
+static inline void set_rec_bits(uint16 bits, uchar *ptr, uchar ofs, uint len)
+{
+ ptr[0]= (ptr[0] & ~(((1 << len) - 1) << ofs)) | (bits << ofs);
+ if (ofs + len > 8)
+ ptr[1]= (ptr[1] & ~((1 << (len - 8 + ofs)) - 1)) | (bits >> (8 - ofs));
}
#define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \
set_rec_bits(0, bit_ptr, bit_ofs, bit_len)
-extern int ha_compare_text(CHARSET_INFO *, const uchar *, uint,
- const uchar *, uint , my_bool);
+extern int ha_compare_text(CHARSET_INFO *, const uchar *, size_t,
+ const uchar *, size_t , my_bool);
extern int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a,
const uchar *b, uint key_length, uint nextflag,
uint *diff_pos);
diff --git a/include/my_cpu.h b/include/my_cpu.h
index 026b92c1b74..f2e26fca70c 100644
--- a/include/my_cpu.h
+++ b/include/my_cpu.h
@@ -1,3 +1,5 @@
+#ifndef MY_CPU_INCLUDED
+#define MY_CPU_INCLUDED
/* Copyright (c) 2013, MariaDB foundation Ab and SkySQL
This program is free software; you can redistribute it and/or modify
@@ -21,17 +23,18 @@
The defines are the same ones used by the linux kernel
*/
-#if defined(__powerpc__)
+#ifdef _ARCH_PWR8
+#include <sys/platform/ppc.h>
/* Very low priority */
-#define HMT_very_low() asm volatile("or 31,31,31")
+#define HMT_very_low() __ppc_set_ppr_very_low()
/* Low priority */
-#define HMT_low() asm volatile("or 1,1,1")
+#define HMT_low() __ppc_set_ppr_low()
/* Medium low priority */
-#define HMT_medium_low() asm volatile("or 6,6,6")
+#define HMT_medium_low() __ppc_set_ppr_med_low()
/* Medium priority */
-#define HMT_medium() asm volatile("or 2,2,2")
+#define HMT_medium() __ppc_set_ppr_med()
/* Medium high priority */
-#define HMT_medium_high() asm volatile("or 5,5,5")
+#define HMT_medium_high() __ppc_set_ppr_med_high()
/* High priority */
#define HMT_high() asm volatile("or 3,3,3")
#else
@@ -42,3 +45,58 @@
#define HMT_medium_high()
#define HMT_high()
#endif
+
+
+static inline void MY_RELAX_CPU(void)
+{
+#ifdef HAVE_PAUSE_INSTRUCTION
+ /*
+ According to the gcc info page, asm volatile means that the
+ instruction has important side-effects and must not be removed.
+ Also asm volatile may trigger a memory barrier (spilling all registers
+ to memory).
+ */
+#ifdef __SUNPRO_CC
+ asm ("pause" );
+#else
+ __asm__ __volatile__ ("pause");
+#endif
+
+#elif defined(HAVE_FAKE_PAUSE_INSTRUCTION)
+ __asm__ __volatile__ ("rep; nop");
+#elif defined _WIN32
+ /*
+ In the Win32 API, the x86 PAUSE instruction is executed by calling
+ the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
+ independent way by using YieldProcessor.
+ */
+ YieldProcessor();
+#elif defined(_ARCH_PWR8)
+ __ppc_get_timebase();
+#else
+ int32 var, oldval = 0;
+ my_atomic_cas32_strong_explicit(&var, &oldval, 1, MY_MEMORY_ORDER_RELAXED,
+ MY_MEMORY_ORDER_RELAXED);
+#endif
+}
+
+
+/*
+ LF_BACKOFF should be used to improve performance on hyperthreaded CPUs. Intel
+ recommends to use it in spin loops also on non-HT machines to reduce power
+ consumption (see e.g http://softwarecommunity.intel.com/articles/eng/2004.htm)
+
+ Running benchmarks for spinlocks implemented with InterlockedCompareExchange
+ and YieldProcessor shows that much better performance is achieved by calling
+ YieldProcessor in a loop - that is, yielding longer. On Intel boxes setting
+ loop count in the range 200-300 brought best results.
+*/
+
+static inline int LF_BACKOFF(void)
+{
+ int i;
+ for (i= 0; i < 200; i++)
+ MY_RELAX_CPU();
+ return 1;
+}
+#endif
diff --git a/include/my_dbug.h b/include/my_dbug.h
index b9194428f18..f0d4acc358b 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -63,6 +63,7 @@ extern void _db_flush_(void);
extern void dbug_swap_code_state(void **code_state_store);
extern void dbug_free_code_state(void **code_state_store);
extern const char* _db_get_func_(void);
+extern int (*dbug_sanity)(void);
#define DBUG_LEAVE do { \
_db_stack_frame_.line= __LINE__; \
@@ -208,10 +209,14 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
#ifdef __cplusplus
}
+/*
+ DBUG_LOG() was initially intended for InnoDB. To be able to use it elsewhere
+ one should #include <sstream>. We intentially avoid including it here to save
+ compilation time.
+*/
# ifdef DBUG_OFF
# define DBUG_LOG(keyword, v) do {} while (0)
# else
-# include <sstream>
# define DBUG_LOG(keyword, v) do { \
if (_db_pargs_(__LINE__, keyword)) { \
std::ostringstream _db_s; _db_s << v; \
diff --git a/include/my_global.h b/include/my_global.h
index 7986a0e21dd..1b17721ddcc 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -178,7 +178,7 @@
/*
The macros below are borrowed from include/linux/compiler.h in the
- Linux kernel. Use them to indicate the likelyhood of the truthfulness
+ Linux kernel. Use them to indicate the likelihood of the truthfulness
of a condition. This serves two purposes - newer versions of gcc will be
able to optimize for branch predication, which could yield siginficant
performance gains in frequently executed sections of the code, and the
@@ -527,7 +527,7 @@ typedef SOCKET my_socket;
typedef int my_socket; /* File descriptor for sockets */
#define INVALID_SOCKET -1
#endif
-/* Type for fuctions that handles signals */
+/* Type for functions that handles signals */
#define sig_handler RETSIGTYPE
C_MODE_START
#ifdef HAVE_SIGHANDLER_T
@@ -857,7 +857,7 @@ static inline double log2(double x)
/*
Max size that must be added to a so that we know Size to make
- adressable obj.
+ addressable obj.
*/
#if SIZEOF_CHARP == 4
typedef long my_ptrdiff_t;
@@ -869,7 +869,7 @@ typedef long long my_ptrdiff_t;
#define MY_ALIGN_DOWN(A,L) ((A) & ~((L) - 1))
#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
#define ALIGN_MAX_UNIT (sizeof(double))
-/* Size to make adressable obj. */
+/* Size to make addressable obj. */
#define ALIGN_PTR(A, t) ((t*) MY_ALIGN((A), sizeof(double)))
#define ADD_TO_PTR(ptr,size,type) (type) ((uchar*) (ptr)+size)
#define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((uchar*) (A) - (uchar*) (B))
@@ -1100,11 +1100,19 @@ static inline char *dlerror(void)
#ifndef HAVE_DLERROR
#define dlerror() ""
#endif
+#ifndef HAVE_DLADDR
+#define dladdr(A, B) 0
+/* Dummy definition in case we're missing dladdr() */
+typedef struct { const char *dli_fname, dli_fbase; } Dl_info;
+#endif
#else
#define dlerror() "No support for dynamic loading (static build?)"
#define dlopen(A,B) 0
#define dlsym(A,B) 0
#define dlclose(A) 0
+#define dladdr(A, B) 0
+/* Dummy definition in case we're missing dladdr() */
+typedef struct { const char *dli_fname, dli_fbase; } Dl_info;
#endif
/*
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 037ac0a062f..d51951f3904 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -80,7 +80,7 @@ int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_attr_init(pthread_attr_t *connect_att);
-int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
+int pthread_attr_setstacksize(pthread_attr_t *connect_att,size_t stack);
int pthread_attr_destroy(pthread_attr_t *connect_att);
int my_pthread_once(my_pthread_once_t *once_control,void (*init_routine)(void));
@@ -196,7 +196,7 @@ int sigwait(sigset_t *set, int *sig);
#endif
#if !defined(HAVE_SIGWAIT) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(_AIX)
-int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
+int sigwait(sigset_t *setp, int *sigp); /* Use our implementation */
#endif
@@ -393,7 +393,7 @@ typedef struct st_safe_mutex_deadlock_t
#ifdef SAFE_MUTEX_DETECT_DESTROY
/*
- Used to track the destroying of mutexes. This needs to be a seperate
+ Used to track the destroying of mutexes. This needs to be a separate
structure because the safe_mutex_t structure could be freed before
the mutexes are destroyed.
*/
diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h
index cb817fb43a6..da22be202ac 100644
--- a/include/my_stacktrace.h
+++ b/include/my_stacktrace.h
@@ -44,7 +44,7 @@ C_MODE_START
void my_init_stacktrace();
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack,
my_bool silent);
-int my_safe_print_str(const char* val, int max_len);
+int my_safe_print_str(const char* val, size_t max_len);
void my_write_core(int sig);
#if BACKTRACE_DEMANGLE
char *my_demangle(const char *mangled_name, int *status);
diff --git a/include/my_sys.h b/include/my_sys.h
index e8658d34af9..8ebc45bae95 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -152,9 +152,12 @@ typedef struct my_aio_result {
/* Extra length needed for filename if one calls my_create_backup_name */
#define MY_BACKUP_NAME_EXTRA_LENGTH 17
+char *guess_malloc_library();
+
/* If we have our own safemalloc (for debugging) */
#if defined(SAFEMALLOC)
void sf_report_leaked_memory(my_thread_id id);
+int sf_sanity();
extern my_thread_id (*sf_malloc_dbug_id)(void);
#define SAFEMALLOC_REPORT_MEMORY(X) sf_report_leaked_memory(X)
#else
@@ -548,12 +551,13 @@ static inline int my_b_get(IO_CACHE *info)
return _my_b_get(info);
}
-/* my_b_write_byte dosn't have any err-check */
-static inline void my_b_write_byte(IO_CACHE *info, uchar chr)
+static inline my_bool my_b_write_byte(IO_CACHE *info, uchar chr)
{
if (info->write_pos >= info->write_end)
- my_b_flush_io_cache(info, 1);
+ if (my_b_flush_io_cache(info, 1))
+ return 1;
*info->write_pos++= chr;
+ return 0;
}
/**
@@ -821,9 +825,9 @@ extern int end_io_cache(IO_CACHE *info);
extern void my_b_seek(IO_CACHE *info,my_off_t pos);
extern size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length);
extern my_off_t my_b_filelength(IO_CACHE *info);
-extern size_t my_b_write_backtick_quote(IO_CACHE *info, const char *str,
- size_t len);
-extern size_t my_b_printf(IO_CACHE *info, const char* fmt, ...);
+extern my_bool my_b_write_backtick_quote(IO_CACHE *info, const char *str,
+ size_t len);
+extern my_bool my_b_printf(IO_CACHE *info, const char* fmt, ...);
extern size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,
const char *prefix, size_t cache_size,
@@ -889,8 +893,9 @@ extern void my_free_lock(void *ptr);
#define alloc_root_inited(A) ((A)->min_malloc != 0)
#define ALLOC_ROOT_MIN_BLOCK_SIZE (MALLOC_OVERHEAD + sizeof(USED_MEM) + 8)
#define clear_alloc_root(A) do { (A)->free= (A)->used= (A)->pre_alloc= 0; (A)->min_malloc=0;} while(0)
-extern void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
- size_t pre_alloc_size, myf my_flags);
+extern void init_alloc_root(MEM_ROOT *mem_root, const char *name,
+ size_t block_size, size_t pre_alloc_size,
+ myf my_flags);
extern void *alloc_root(MEM_ROOT *mem_root, size_t Size);
extern void *multi_alloc_root(MEM_ROOT *mem_root, ...);
extern void free_root(MEM_ROOT *root, myf MyFLAGS);
@@ -1042,9 +1047,9 @@ extern size_t escape_quotes_for_mysql(CHARSET_INFO *charset_info,
char *to, size_t to_length,
const char *from, size_t length);
-extern void thd_increment_bytes_sent(void *thd, ulong length);
-extern void thd_increment_bytes_received(void *thd, ulong length);
-extern void thd_increment_net_big_packet_count(void *thd, ulong length);
+extern void thd_increment_bytes_sent(void *thd, size_t length);
+extern void thd_increment_bytes_received(void *thd, size_t length);
+extern void thd_increment_net_big_packet_count(void *thd, size_t length);
#ifdef __WIN__
extern my_bool have_tcpip; /* Is set if tcpip is used */
diff --git a/include/my_time.h b/include/my_time.h
index 1e99b14421d..af94288f911 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -109,15 +109,15 @@ static inline void my_time_status_init(MYSQL_TIME_STATUS *status)
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
ulonglong flags, int *was_cut);
-my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
+my_bool str_to_time(const char *str, size_t length, MYSQL_TIME *l_time,
ulonglong flag, MYSQL_TIME_STATUS *status);
-my_bool str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
+my_bool str_to_datetime(const char *str, size_t length, MYSQL_TIME *l_time,
ulonglong flags, MYSQL_TIME_STATUS *status);
longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
ulonglong flags, int *was_cut);
static inline
-longlong double_to_datetime(double nr, MYSQL_TIME *ltime, uint flags, int *cut)
+longlong double_to_datetime(double nr, MYSQL_TIME *ltime, ulonglong flags, int *cut)
{
if (nr < 0 || nr > LONGLONG_MAX)
nr= (double)LONGLONG_MAX;
@@ -134,9 +134,6 @@ ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
ulonglong TIME_to_ulonglong(const MYSQL_TIME *);
double TIME_to_double(const MYSQL_TIME *my_time);
-longlong pack_time(const MYSQL_TIME *my_time);
-MYSQL_TIME *unpack_time(longlong packed, MYSQL_TIME *my_time);
-
int check_time_range(struct st_mysql_time *my_time, uint dec, int *warning);
my_bool check_datetime_range(const MYSQL_TIME *ltime);
@@ -239,7 +236,7 @@ static inline void my_timeval_trunc(struct timeval *tv, uint decimals)
order of elements in 'interval_type_to_name' and 'interval_names'
arrays
- See also interval_type_to_name, get_interval_value, interval_names
+ See also interval_type_to_name, get_interval_value, interval_names, append_interval
*/
enum interval_type
diff --git a/include/my_valgrind.h b/include/my_valgrind.h
index dbbc4fad5ab..c585e3c489a 100644
--- a/include/my_valgrind.h
+++ b/include/my_valgrind.h
@@ -13,6 +13,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
+/* clang -> gcc */
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+#if __has_feature(address_sanitizer)
+# define __SANITIZE_ADDRESS__ 1
+#endif
+
#ifdef HAVE_valgrind
#define IF_VALGRIND(A,B) A
#else
@@ -25,21 +33,24 @@
# define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len)
# define MEM_CHECK_ADDRESSABLE(a,len) VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,len)
# define MEM_CHECK_DEFINED(a,len) VALGRIND_CHECK_MEM_IS_DEFINED(a,len)
-#else /* HAVE_VALGRIND_MEMCHECK_H */
+#elif defined(__SANITIZE_ADDRESS__)
+# include <sanitizer/asan_interface.h>
+# define MEM_UNDEFINED(a,len) ASAN_UNPOISON_MEMORY_REGION(a,len)
+# define MEM_NOACCESS(a,len) ASAN_POISON_MEMORY_REGION(a,len)
+# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0)
+# define MEM_CHECK_DEFINED(a,len) ((void) 0)
+#else
# define MEM_UNDEFINED(a,len) ((void) 0)
# define MEM_NOACCESS(a,len) ((void) 0)
# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0)
# define MEM_CHECK_DEFINED(a,len) ((void) 0)
#endif /* HAVE_VALGRIND_MEMCHECK_H */
-#ifndef DBUG_OFF
-#define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); memset(A, C, trash_tmp); MEM_UNDEFINED(A, trash_tmp); } while (0)
+#if !defined(DBUG_OFF) || defined(TRASH_FREED_MEMORY)
+#define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); MEM_UNDEFINED(A, trash_tmp); memset(A, C, trash_tmp); } while (0)
#else
-#define TRASH_FILL(A,B,C) do{ const size_t trash_tmp __attribute__((unused)) = (B) ; MEM_CHECK_ADDRESSABLE(A,trash_tmp);MEM_UNDEFINED(A,trash_tmp);} while (0)
+#define TRASH_FILL(A,B,C) do { const size_t trash_tmp __attribute__((unused))= (B); MEM_UNDEFINED(A,trash_tmp); } while (0)
#endif
-#define TRASH_ALLOC(A,B) TRASH_FILL(A,B,0xA5)
-#define TRASH_FREE(A,B) TRASH_FILL(A,(size_t) (B),0x8F)
-#define TRASH(A,B) TRASH_FREE(A,B)
-# define DBUG_ASSERT_DEFINED(x) \
- DBUG_ASSERT(!VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x)))
+#define TRASH_ALLOC(A,B) do { TRASH_FILL(A,B,0xA5); MEM_UNDEFINED(A,B); } while(0)
+#define TRASH_FREE(A,B) do { TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0)
diff --git a/include/mysql.h b/include/mysql.h
index 8d8e0589282..a42f90db1ae 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -145,7 +145,6 @@ typedef unsigned long long my_ulonglong;
#define ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
#define ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN ER_PRIMARY_KEY_BASED_ON_GENERATED_COLUMN
#define ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN ER_WRONG_FK_OPTION_FOR_GENERATED_COLUMN
-#define ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
#define ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN
#define ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS ER_UNSUPPORTED_ENGINE_FOR_GENERATED_COLUMNS
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index b87316946a4..e36131b93d2 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -165,7 +165,7 @@ void scramble(char *to, const char *message, const char *password);
my_bool check_scramble(const unsigned char *reply, const char *message,
const unsigned char *hash_stage2);
void get_salt_from_password(unsigned char *res, const char *password);
-char *octet2hex(char *to, const char *str, unsigned int len);
+char *octet2hex(char *to, const char *str, size_t len);
char *get_tty_password(const char *opt_message);
void get_tty_password_buff(const char *opt_message, char *to, size_t length);
const char *mysql_errno_to_sqlstate(unsigned int mysql_errno);
@@ -242,6 +242,7 @@ typedef struct st_mem_root
unsigned int block_num;
unsigned int first_block_usage;
void (*error_handler)(void);
+ const char *name;
} MEM_ROOT;
typedef struct st_typelib {
unsigned int count;
@@ -252,8 +253,6 @@ typedef struct st_typelib {
extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
extern int find_type_with_warning(const char *x, TYPELIB *typelib,
const char *option);
-extern int find_type_or_exit(const char *x, TYPELIB *typelib,
- const char *option);
extern int find_type(const char *x, const TYPELIB *typelib, unsigned int flags);
extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
extern const char *get_type(TYPELIB *typelib,unsigned int nr);
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index ad5a792173a..b122d888c6d 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -649,7 +649,6 @@ void **thd_ha_data(const MYSQL_THD thd, const struct handlerton *hton);
void thd_storage_lock_wait(MYSQL_THD thd, long long value);
int thd_tx_isolation(const MYSQL_THD thd);
int thd_tx_is_read_only(const MYSQL_THD thd);
-int thd_rpl_is_parallel(const MYSQL_THD thd);
/**
Create a temporary file.
diff --git a/include/mysql/plugin_audit.h b/include/mysql/plugin_audit.h
index 10039c4c1fa..7582245945f 100644
--- a/include/mysql/plugin_audit.h
+++ b/include/mysql/plugin_audit.h
@@ -65,8 +65,7 @@ struct mysql_event_general
unsigned long long general_rows;
/* Added in version 0x302 */
unsigned long long query_id;
- const char *database;
- unsigned int database_length;
+ MYSQL_CONST_LEX_STRING database;
};
@@ -101,8 +100,7 @@ struct mysql_event_connection
unsigned int host_length;
const char *ip;
unsigned int ip_length;
- const char *database;
- unsigned int database_length;
+ MYSQL_CONST_LEX_STRING database;
};
/*
@@ -137,17 +135,13 @@ struct mysql_event_table
const char *proxy_user;
const char *host;
const char *ip;
- const char *database;
- unsigned int database_length;
- const char *table;
- unsigned int table_length;
+ MYSQL_CONST_LEX_STRING database;
+ MYSQL_CONST_LEX_STRING table;
+ /* for MYSQL_AUDIT_TABLE_RENAME */
+ MYSQL_CONST_LEX_STRING new_database;
+ MYSQL_CONST_LEX_STRING new_table;
/* for MYSQL_AUDIT_TABLE_LOCK, true if read-only, false if read/write */
int read_only;
- /* for MYSQL_AUDIT_TABLE_RENAME */
- const char *new_database;
- unsigned int new_database_length;
- const char *new_table;
- unsigned int new_table_length;
/* Added in version 0x302 */
unsigned long long query_id;
};
diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp
index 02fe3b75227..89f7dcc36c4 100644
--- a/include/mysql/plugin_audit.h.pp
+++ b/include/mysql/plugin_audit.h.pp
@@ -518,7 +518,6 @@ void **thd_ha_data(const void* thd, const struct handlerton *hton);
void thd_storage_lock_wait(void* thd, long long value);
int thd_tx_isolation(const void* thd);
int thd_tx_is_read_only(const void* thd);
-int thd_rpl_is_parallel(const void* thd);
int mysql_tmpfile(const char *prefix);
unsigned long thd_get_thread_id(const void* thd);
void thd_get_xid(const void* thd, MYSQL_XID *xid);
@@ -544,8 +543,7 @@ struct mysql_event_general
unsigned long long general_time;
unsigned long long general_rows;
unsigned long long query_id;
- const char *database;
- unsigned int database_length;
+ MYSQL_CONST_LEX_STRING database;
};
struct mysql_event_connection
{
@@ -564,8 +562,7 @@ struct mysql_event_connection
unsigned int host_length;
const char *ip;
unsigned int ip_length;
- const char *database;
- unsigned int database_length;
+ MYSQL_CONST_LEX_STRING database;
};
struct mysql_event_table
{
@@ -578,15 +575,11 @@ struct mysql_event_table
const char *proxy_user;
const char *host;
const char *ip;
- const char *database;
- unsigned int database_length;
- const char *table;
- unsigned int table_length;
+ MYSQL_CONST_LEX_STRING database;
+ MYSQL_CONST_LEX_STRING table;
+ MYSQL_CONST_LEX_STRING new_database;
+ MYSQL_CONST_LEX_STRING new_table;
int read_only;
- const char *new_database;
- unsigned int new_database_length;
- const char *new_table;
- unsigned int new_table_length;
unsigned long long query_id;
};
struct st_mysql_audit
diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp
index 6aba0ddb889..e515699cad6 100644
--- a/include/mysql/plugin_auth.h.pp
+++ b/include/mysql/plugin_auth.h.pp
@@ -518,7 +518,6 @@ void **thd_ha_data(const void* thd, const struct handlerton *hton);
void thd_storage_lock_wait(void* thd, long long value);
int thd_tx_isolation(const void* thd);
int thd_tx_is_read_only(const void* thd);
-int thd_rpl_is_parallel(const void* thd);
int mysql_tmpfile(const char *prefix);
unsigned long thd_get_thread_id(const void* thd);
void thd_get_xid(const void* thd, MYSQL_XID *xid);
diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp
index 1f7b4e90908..7defe0aec2c 100644
--- a/include/mysql/plugin_encryption.h.pp
+++ b/include/mysql/plugin_encryption.h.pp
@@ -518,7 +518,6 @@ void **thd_ha_data(const void* thd, const struct handlerton *hton);
void thd_storage_lock_wait(void* thd, long long value);
int thd_tx_isolation(const void* thd);
int thd_tx_is_read_only(const void* thd);
-int thd_rpl_is_parallel(const void* thd);
int mysql_tmpfile(const char *prefix);
unsigned long thd_get_thread_id(const void* thd);
void thd_get_xid(const void* thd, MYSQL_XID *xid);
diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp
index afc4a597b0f..a36f51e74e1 100644
--- a/include/mysql/plugin_ftparser.h.pp
+++ b/include/mysql/plugin_ftparser.h.pp
@@ -472,7 +472,6 @@ void **thd_ha_data(const void* thd, const struct handlerton *hton);
void thd_storage_lock_wait(void* thd, long long value);
int thd_tx_isolation(const void* thd);
int thd_tx_is_read_only(const void* thd);
-int thd_rpl_is_parallel(const void* thd);
int mysql_tmpfile(const char *prefix);
unsigned long thd_get_thread_id(const void* thd);
void thd_get_xid(const void* thd, MYSQL_XID *xid);
diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp
index 0d2c0719b87..9701ad1b92f 100644
--- a/include/mysql/plugin_password_validation.h.pp
+++ b/include/mysql/plugin_password_validation.h.pp
@@ -518,7 +518,6 @@ void **thd_ha_data(const void* thd, const struct handlerton *hton);
void thd_storage_lock_wait(void* thd, long long value);
int thd_tx_isolation(const void* thd);
int thd_tx_is_read_only(const void* thd);
-int thd_rpl_is_parallel(const void* thd);
int mysql_tmpfile(const char *prefix);
unsigned long thd_get_thread_id(const void* thd);
void thd_get_xid(const void* thd, MYSQL_XID *xid);
diff --git a/include/mysql/psi/mysql_socket.h b/include/mysql/psi/mysql_socket.h
index 64531e5c35e..5eee4c1eae6 100644
--- a/include/mysql/psi/mysql_socket.h
+++ b/include/mysql/psi/mysql_socket.h
@@ -572,7 +572,7 @@ inline_mysql_socket_bind
#ifdef HAVE_PSI_SOCKET_INTERFACE
const char *src_file, uint src_line,
#endif
- MYSQL_SOCKET mysql_socket, const struct sockaddr *addr, socklen_t len)
+ MYSQL_SOCKET mysql_socket, const struct sockaddr *addr, size_t len)
{
int result;
@@ -586,11 +586,11 @@ inline_mysql_socket_bind
(&state, mysql_socket.m_psi, PSI_SOCKET_BIND, (size_t)0, src_file, src_line);
/* Instrumented code */
- result= bind(mysql_socket.fd, addr, len);
+ result= bind(mysql_socket.fd, addr, (int)len);
/* Instrumentation end */
if (result == 0)
- PSI_SOCKET_CALL(set_socket_info)(mysql_socket.m_psi, NULL, addr, len);
+ PSI_SOCKET_CALL(set_socket_info)(mysql_socket.m_psi, NULL, addr, (socklen_t)len);
if (locker != NULL)
PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
@@ -600,7 +600,7 @@ inline_mysql_socket_bind
#endif
/* Non instrumented code */
- result= bind(mysql_socket.fd, addr, len);
+ result= bind(mysql_socket.fd, addr, (int)len);
return result;
}
diff --git a/include/mysql/psi/mysql_statement.h b/include/mysql/psi/mysql_statement.h
index 05016130af7..2c59b50aa63 100644
--- a/include/mysql/psi/mysql_statement.h
+++ b/include/mysql/psi/mysql_statement.h
@@ -145,14 +145,14 @@ inline_mysql_digest_end(PSI_digest_locker *locker, const sql_digest_storage *dig
static inline struct PSI_statement_locker *
inline_mysql_start_statement(PSI_statement_locker_state *state,
PSI_statement_key key,
- const char *db, uint db_len,
+ const char *db, size_t db_len,
const CHARSET_INFO *charset,
const char *src_file, uint src_line)
{
PSI_statement_locker *locker;
locker= PSI_STATEMENT_CALL(get_thread_statement_locker)(state, key, charset);
if (likely(locker != NULL))
- PSI_STATEMENT_CALL(start_statement)(locker, db, db_len, src_file, src_line);
+ PSI_STATEMENT_CALL(start_statement)(locker, db, (uint)db_len, src_file, src_line);
return locker;
}
diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h
index 54a0eaabef7..258e283afe6 100644
--- a/include/mysql/psi/mysql_thread.h
+++ b/include/mysql/psi/mysql_thread.h
@@ -62,6 +62,35 @@
@{
*/
+#ifdef HAVE_PSI_THREAD_INTERFACE
+#define PSI_CALL_delete_current_thread PSI_THREAD_CALL(delete_current_thread)
+#define PSI_CALL_get_thread PSI_THREAD_CALL(get_thread)
+#define PSI_CALL_new_thread PSI_THREAD_CALL(new_thread)
+#define PSI_CALL_register_thread PSI_THREAD_CALL(register_thread)
+#define PSI_CALL_set_thread PSI_THREAD_CALL(set_thread)
+#define PSI_CALL_set_thread_connect_attrs PSI_THREAD_CALL(set_thread_connect_attrs)
+#define PSI_CALL_set_thread_db PSI_THREAD_CALL(set_thread_db)
+#define PSI_CALL_set_thread_id PSI_THREAD_CALL(set_thread_id)
+#define PSI_CALL_set_thread_info PSI_THREAD_CALL(set_thread_info)
+#define PSI_CALL_set_thread_start_time PSI_THREAD_CALL(set_thread_start_time)
+#define PSI_CALL_set_thread_user_host PSI_THREAD_CALL(set_thread_user_host)
+#define PSI_CALL_spawn_thread PSI_THREAD_CALL(spawn_thread)
+#else
+#define PSI_CALL_delete_current_thread() do { } while(0)
+#define PSI_CALL_get_thread() NULL
+#define PSI_CALL_new_thread(A1,A2,A3) NULL
+#define PSI_CALL_register_thread(A1,A2,A3) do { } while(0)
+#define PSI_CALL_set_thread(A1) do { } while(0)
+#define PSI_CALL_set_thread_connect_attrs(A1,A2,A3) 0
+#define PSI_CALL_set_thread_db(A1,A2) do { } while(0)
+#define PSI_CALL_set_thread_id(A1,A2) do { } while(0)
+#define PSI_CALL_set_thread_info(A1, A2) do { } while(0)
+#define PSI_CALL_set_thread_start_time(A1) do { } while(0)
+#define PSI_CALL_set_thread_user_host(A1, A2, A3, A4) do { } while(0)
+#define PSI_CALL_spawn_thread(A1, A2, A3, A4, A5) 0
+#endif
+
+
/**
An instrumented mutex structure.
@sa mysql_mutex_t
diff --git a/include/mysql/service_my_print_error.h b/include/mysql/service_my_print_error.h
index 636151655e5..5a71be74fd0 100644
--- a/include/mysql/service_my_print_error.h
+++ b/include/mysql/service_my_print_error.h
@@ -50,11 +50,12 @@ extern struct my_print_error_service_st {
#define my_printv_error(A,B,C,D) my_print_error_service->my_printv_error_func(A,B,C,D)
#else
-
+#ifndef MY_ERROR_DEFINED
extern void my_error(unsigned int nr, unsigned long MyFlags, ...);
extern void my_printf_error(unsigned int my_err, const char *format, unsigned long MyFlags, ...);
extern void my_printv_error(unsigned int error, const char *format, unsigned long MyFlags,va_list ap);
-#endif
+#endif /* MY_ERROR_DEFINED */
+#endif /* MYSQL_DYNAMIC_PLUGIN */
#ifdef __cplusplus
}
diff --git a/include/mysql/service_thd_rnd.h b/include/mysql/service_thd_rnd.h
index 21133c7889f..13fc1c16839 100644
--- a/include/mysql/service_thd_rnd.h
+++ b/include/mysql/service_thd_rnd.h
@@ -18,7 +18,7 @@
@file
This service provides access to the thd-local random number generator.
- It's preferrable over the global one, because concurrent threads
+ It's preferable over the global one, because concurrent threads
can generate random numbers without fighting each other over the access
to the shared rnd state.
*/
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 71858c93046..e8971e7b3cb 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -152,7 +152,7 @@ enum enum_indicator_type
*/
#define SCRAMBLE_LENGTH 20
#define SCRAMBLE_LENGTH_323 8
-/* length of password stored in the db: new passwords are preceeded with '*' */
+/* length of password stored in the db: new passwords are preceded with '*' */
#define SCRAMBLED_PASSWORD_CHAR_LENGTH (SCRAMBLE_LENGTH*2+1)
#define SCRAMBLED_PASSWORD_CHAR_LENGTH_323 (SCRAMBLE_LENGTH_323*2)
@@ -192,6 +192,17 @@ enum enum_indicator_type
#define FIELD_FLAGS_COLUMN_FORMAT_MASK (3U << FIELD_FLAGS_COLUMN_FORMAT)
#define FIELD_IS_DROPPED (1U << 26) /* Intern: Field is being dropped */
+#define VERS_SYS_START_FLAG (1 << 27) /* autogenerated column declared with
+ `generated always as row start`
+ (see II.a SQL Standard) */
+#define VERS_SYS_END_FLAG (1 << 28) /* autogenerated column declared with
+ `generated always as row end`
+ (see II.a SQL Standard).*/
+#define VERS_SYSTEM_FIELD (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG)
+#define VERS_UPDATE_UNVERSIONED_FLAG (1 << 29) /* column that doesn't support
+ system versioning when table
+ itself supports it*/
+
#define REFRESH_GRANT (1ULL << 0) /* Refresh grant tables */
#define REFRESH_LOG (1ULL << 1) /* Start on new log file */
#define REFRESH_TABLES (1ULL << 2) /* close all tables */
@@ -288,7 +299,7 @@ enum enum_indicator_type
#endif
/*
- Gather all possible capabilites (flags) supported by the server
+ Gather all possible capabilities (flags) supported by the server
MARIADB_* flags supported only by MariaDB connector(s).
*/
@@ -698,7 +709,7 @@ void scramble(char *to, const char *message, const char *password);
my_bool check_scramble(const unsigned char *reply, const char *message,
const unsigned char *hash_stage2);
void get_salt_from_password(unsigned char *res, const char *password);
-char *octet2hex(char *to, const char *str, unsigned int len);
+char *octet2hex(char *to, const char *str, size_t len);
/* end of password.c */
diff --git a/include/mysql_version.h.in b/include/mysql_version.h.in
index f22e00dabb9..59df2b7c086 100644
--- a/include/mysql_version.h.in
+++ b/include/mysql_version.h.in
@@ -22,6 +22,7 @@
#define MYSQL_UNIX_ADDR "@MYSQL_UNIX_ADDR@"
#define MYSQL_CONFIG_NAME "my"
#define MYSQL_COMPILATION_COMMENT "@COMPILATION_COMMENT@"
+#define SERVER_MATURITY_LEVEL @SERVER_MATURITY_LEVEL@
#ifdef WITH_WSREP
#define WSREP_PATCH_VERSION "@WSREP_PATCH_VERSION@"
diff --git a/include/ssl_compat.h b/include/ssl_compat.h
index 568af6e1db4..54e80af769d 100644
--- a/include/ssl_compat.h
+++ b/include/ssl_compat.h
@@ -51,14 +51,6 @@
#define HAVE_OPENSSL10 1
#define SSL_LIBRARY SSLeay_version(SSLEAY_VERSION)
-/*
- Unfortunately RAND_bytes manual page does not provide any guarantees
- in relation to blocking behavior. Here we explicitly use SSLeay random
- instead of whatever random engine is currently set in OpenSSL. That way
- we are guaranteed to have a non-blocking random.
-*/
-#define RAND_OpenSSL() RAND_SSLeay()
-
#ifdef HAVE_ERR_remove_thread_state
#define ERR_remove_state(X) ERR_remove_thread_state(NULL)
#endif /* HAVE_ERR_remove_thread_state */
diff --git a/include/typelib.h b/include/typelib.h
index eba32167c4e..0d633e57e5a 100644
--- a/include/typelib.h
+++ b/include/typelib.h
@@ -30,8 +30,6 @@ typedef struct st_typelib { /* Different types saved here */
extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
extern int find_type_with_warning(const char *x, TYPELIB *typelib,
const char *option);
-extern int find_type_or_exit(const char *x, TYPELIB *typelib,
- const char *option);
#define FIND_TYPE_BASIC 0
/** makes @c find_type() require the whole name, no prefix */
#define FIND_TYPE_NO_PREFIX (1U << 0)
diff --git a/include/violite.h b/include/violite.h
index b6d0e130f0d..55f8328df47 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -121,9 +121,9 @@ extern void vio_set_wait_callback(void (*before_wait)(void),
my_bool vio_socket_connect(Vio *vio, struct sockaddr *addr, socklen_t len,
int timeout);
-void vio_get_normalized_ip(const struct sockaddr *src, int src_length, struct sockaddr *dst, int *dst_length);
+void vio_get_normalized_ip(const struct sockaddr *src, size_t src_length, struct sockaddr *dst);
-my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, int addr_length,
+my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, size_t addr_length,
char *ip_string, size_t ip_string_size);
my_bool vio_is_no_name_error(int err_code);
@@ -232,7 +232,6 @@ struct st_vio
int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
struct sockaddr_storage local; /* Local internet address */
struct sockaddr_storage remote; /* Remote internet address */
- int addrLen; /* Length of remote address */
enum enum_vio_type type; /* Type of connection */
const char *desc; /* String description */
char *read_buffer; /* buffer for vio_read_buff */
diff --git a/include/welcome_copyright_notice.h b/include/welcome_copyright_notice.h
index cd7cd6692be..1b4b17cfc0d 100644
--- a/include/welcome_copyright_notice.h
+++ b/include/welcome_copyright_notice.h
@@ -17,7 +17,7 @@
#ifndef _welcome_copyright_notice_h_
#define _welcome_copyright_notice_h_
-#define COPYRIGHT_NOTICE_CURRENT_YEAR "2017"
+#define COPYRIGHT_NOTICE_CURRENT_YEAR "2018"
/*
This define specifies copyright notice which is displayed by every MySQL
diff --git a/libmariadb b/libmariadb
-Subproject 7e53ab369815590ff92913b581d43eb7786f2fe
+Subproject 67cc3438a84df9fa3cc0cfbf9ed81242502702d
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index abb19fd9932..718e832edef 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -90,7 +90,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/scheduler.cc ../sql/sql_audit.cc
../sql/sql_alter.cc ../sql/sql_partition_admin.cc
../sql/event_parse_data.cc
- ../sql/sql_signal.cc ../sql/rpl_handler.cc
+ ../sql/sql_signal.cc
../sql/sys_vars.cc
${CMAKE_BINARY_DIR}/sql/sql_builtin.cc
../sql/mdl.cc ../sql/transaction.cc
@@ -119,6 +119,9 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/session_tracker.cc
../sql/proxy_protocol.cc
../sql/sql_tvc.cc ../sql/sql_tvc.h
+ ../sql/opt_split.cc
+ ../sql/item_vers.cc
+ ../sql/vtmd.cc
${GEN_SOURCES}
${MYSYS_LIBWRAP_SOURCE}
)
@@ -135,7 +138,7 @@ IF(WIN32)
SET(COMPONENT_MYSQLSERVER "Embedded")
SET(COMPONENT_LIBMYSQLD "Embedded")
ELSE()
- SET(MYSQLSERVER_OUTPUT_NAME mysqld)
+ SET(MYSQLSERVER_OUTPUT_NAME mariadbd)
SET(COMPONENT_MYSQLSERVER "Development")
SET(COMPONENT_LIBMYSQLD "Server")
ENDIF()
@@ -163,7 +166,9 @@ ENDFOREACH()
MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER})
-
+IF(UNIX)
+ INSTALL_SYMLINK(libmysqld.a mysqlserver ${INSTALL_LIBDIR} ${COMPONENT_MYSQLSERVER})
+ENDIF()
INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/server/private COMPONENT ${COMPONENT_MYSQLSERVER})
@@ -435,8 +440,9 @@ IF(NOT DISABLE_SHARED)
# Name the shared library, handle versioning (provides same api as client
# library hence the same version)
SET_TARGET_PROPERTIES(libmysqld PROPERTIES
- OUTPUT_NAME mysqld
+ OUTPUT_NAME mariadbd
SOVERSION "${SHARED_LIB_MAJOR_VERSION}")
+ INSTALL_SYMLINK(libmysqld.so libmysqld ${INSTALL_LIBDIR} ${COMPONENT_LIBMYSQLD})
# Clean direct output flags, as 2 targets have the same base name
# libmysqld
SET_TARGET_PROPERTIES(libmysqld PROPERTIES CLEAN_DIRECT_OUTPUT 1)
diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc
index 74a6337912a..4694a94b133 100644
--- a/libmysqld/emb_qcache.cc
+++ b/libmysqld/emb_qcache.cc
@@ -418,7 +418,7 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
if (!data)
goto err;
- init_alloc_root(&data->alloc, 8192,0,MYF(0));
+ init_alloc_root(&data->alloc, "embedded_query_cache", 8192,0,MYF(0));
f_alloc= &data->alloc;
data->fields= src->load_int();
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 25ef6e9b18e..4f78c97e723 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -655,7 +655,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag)
thd->mysql= mysql;
mysql->server_version= server_version;
mysql->client_flag= client_flag;
- init_alloc_root(&mysql->field_alloc, 8192, 0, MYF(0));
+ init_alloc_root(&mysql->field_alloc, "fields", 8192, 0, MYF(0));
}
/**
@@ -692,8 +692,7 @@ void *create_embedded_thd(int client_flag)
thd->client_capabilities= client_flag;
thd->real_id= pthread_self();
- thd->db= NULL;
- thd->db_length= 0;
+ thd->db= null_clex_str;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
thd->security_ctx->db_access= DB_ACLS;
thd->security_ctx->master_access= ~NO_ACCESS;
@@ -731,7 +730,7 @@ emb_transfer_connect_attrs(MYSQL *mysql)
ptr= buf= (uchar *) my_alloca(length + 9);
send_client_connect_attrs(mysql, buf);
net_field_length_ll(&ptr);
- PSI_THREAD_CALL(set_thread_connect_attrs)((char *) ptr, length, thd->charset());
+ PSI_CALL_set_thread_connect_attrs((char *) ptr, length, thd->charset());
my_afree(buf);
}
#endif
@@ -972,7 +971,7 @@ int Protocol::begin_dataset()
return 1;
alloc= &data->alloc;
/* Assume rowlength < 8192 */
- init_alloc_root(alloc, 8192, 0, MYF(0));
+ init_alloc_root(alloc, "protocol", 8192, 0, MYF(0));
alloc->min_malloc= sizeof(MYSQL_ROWS);
return 0;
}
diff --git a/libmysqld/libmysql.c b/libmysqld/libmysql.c
index 4b0b13862eb..b3ef96698ff 100644
--- a/libmysqld/libmysql.c
+++ b/libmysqld/libmysql.c
@@ -1533,8 +1533,9 @@ mysql_stmt_init(MYSQL *mysql)
DBUG_RETURN(NULL);
}
- init_alloc_root(&stmt->mem_root, 2048,2048, MYF(MY_THREAD_SPECIFIC));
- init_alloc_root(&stmt->result.alloc, 4096, 4096, MYF(MY_THREAD_SPECIFIC));
+ init_alloc_root(&stmt->mem_root, "stmt", 2048,2048, MYF(MY_THREAD_SPECIFIC));
+ init_alloc_root(&stmt->result.alloc, "result", 4096, 4096,
+ MYF(MY_THREAD_SPECIFIC));
stmt->result.alloc.min_malloc= sizeof(MYSQL_ROWS);
mysql->stmts= list_add(mysql->stmts, &stmt->list);
stmt->list.data= stmt;
@@ -1545,7 +1546,7 @@ mysql_stmt_init(MYSQL *mysql)
strmov(stmt->sqlstate, not_error_sqlstate);
/* The rest of statement members was bzeroed inside malloc */
- init_alloc_root(&stmt->extension->fields_mem_root, 2048, 0,
+ init_alloc_root(&stmt->extension->fields_mem_root, "extension", 2048, 0,
MYF(MY_THREAD_SPECIFIC));
DBUG_RETURN(stmt);
@@ -3150,8 +3151,7 @@ static void read_binary_date(MYSQL_TIME *tm, uchar **pos)
length data length
*/
-static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
- uint length)
+static void fetch_string_with_conversion(MYSQL_BIND *param, char *value, size_t length)
{
char *buffer= (char *)param->buffer;
int err= 0;
@@ -3263,7 +3263,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
param->length will always contain length of entire column;
number of copied bytes may be way different:
*/
- *param->length= length;
+ *param->length= (ulong)length;
break;
}
}
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
index d1771a09578..e5b6f6b8397 100644
--- a/libmysqld/libmysqld.c
+++ b/libmysqld/libmysqld.c
@@ -121,6 +121,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
my_free(mysql->options.my_cnf_file);
my_free(mysql->options.my_cnf_group);
mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
+
+ if (mysql->options.protocol == UINT_MAX32)
+ goto error;
}
if (!db || !db[0])
diff --git a/libservices/my_print_error_service.c b/libservices/my_print_error_service.c
index 7642668d470..796b554914e 100644
--- a/libservices/my_print_error_service.c
+++ b/libservices/my_print_error_service.c
@@ -14,4 +14,4 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <service_versions.h>
-SERVICE_VERSION my_print_error_service= (void*)VERSION_my_print_error; \ No newline at end of file
+SERVICE_VERSION my_print_error_service= (void*)VERSION_my_print_error;
diff --git a/man/mysql-test-run.pl.1 b/man/mysql-test-run.pl.1
index 93fb42e251a..b928ec66587 100644
--- a/man/mysql-test-run.pl.1
+++ b/man/mysql-test-run.pl.1
@@ -276,7 +276,7 @@ T}:T{
Setting of a timeout in minutes or seconds, corresponding to command
line option
\fB\-\-\fR\fB\fIname\fR\fR\fB\-timeout\fR\&.
- Avaliable timeout names are TESTCASE,
+ Available timeout names are TESTCASE,
SUITE (both in minutes) and
START, SHUTDOWN
(both in seconds)\&. These variables are supported from
@@ -1350,7 +1350,7 @@ for a description\&.
.\" noreorder option: mysql-test-run.pl
\fB\-\-noreorder\fR
.sp
-Do not reorder tests to reduce number of restarts, but run them in exactly the order given\&. If a whole suite is to be run, the tests are run in alphabetical order, though similiar combinations will be grouped together\&. If more than one suite is listed, the tests are run one suite at a time, in the order listed\&.
+Do not reorder tests to reduce number of restarts, but run them in exactly the order given\&. If a whole suite is to be run, the tests are run in alphabetical order, though similar combinations will be grouped together\&. If more than one suite is listed, the tests are run one suite at a time, in the order listed\&.
.RE
.sp
.RS 4
diff --git a/man/mysql.1 b/man/mysql.1
index b7f7a63bff4..f925fee454b 100644
--- a/man/mysql.1
+++ b/man/mysql.1
@@ -698,7 +698,7 @@ the section called \(lqMYSQL COMMANDS\(rq\&. Disabled by default\&.
.\}
.\" mysql: net-buffer-length option
.\" net-buffer-length option: mysql
-\fB\-\-net\-buffer\-lenght=\fR\fB\fIsize\fR\fR
+\fB\-\-net\-buffer\-length=\fR\fB\fIsize\fR\fR
.sp
Set the buffer size for TCP/IP and socket communication\&. (Default value is 16KB\&.)
.RE
diff --git a/man/mysql_upgrade.1 b/man/mysql_upgrade.1
index c1197efe6b9..4ea0f4e054d 100644
--- a/man/mysql_upgrade.1
+++ b/man/mysql_upgrade.1
@@ -691,8 +691,7 @@ it was built/distributed. Defaults to on; use \fB\-\-skip\-version\-check\fR to
.sp
Cause binary logging to be enabled while
\fBmysql_upgrade\fR
-runs\&. This is the default behavior; to disable binary logging during the upgrade, use the inverse of this option (that is, start the program with
-\fB\-\-skip\-write\-binlog\fR)\&.
+runs\&.
.RE
.SH "COPYRIGHT"
.br
diff --git a/man/mysqladmin.1 b/man/mysqladmin.1
index 82c31901e4b..321964e20d6 100644
--- a/man/mysqladmin.1
+++ b/man/mysqladmin.1
@@ -1,6 +1,6 @@
'\" t
.\"
-.TH "\FBMYSQLADMIN\FR" "1" "9 May 2017" "MariaDB 10\&.3" "MariaDB Database System"
+.TH "\FBMYSQLADMIN\FR" "1" "28 December 2017" "MariaDB 10\&.3" "MariaDB Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -106,6 +106,97 @@ Display the server status variables and their values\&.
.sp -1
.IP \(bu 2.3
.\}
+flush\-all\-statistics
+.sp
+Flush all statistics tables\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+flush\-all\-status
+.sp
+Flush all status and statistics\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+flush\-binary\-log
+.sp
+Flush the binary log\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+flush\-client\-statistics
+.sp
+Flush client statistics\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+flush\-engine\-log
+.sp
+Flush engine log\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+flush\-error\-log
+.sp
+Flush error log\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+flush\-general\-log
+.sp
+Flush general query log\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
flush\-hosts
.sp
Flush all information in the host cache\&.
@@ -119,6 +210,19 @@ Flush all information in the host cache\&.
.sp -1
.IP \(bu 2.3
.\}
+flush\-index\-statistics
+.sp
+Flush index statistics\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
flush\-logs
.sp
Flush all logs\&.
@@ -146,6 +250,32 @@ reload)\&.
.sp -1
.IP \(bu 2.3
.\}
+flush\-relay\-log
+.sp
+Flush relay log\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+flush\-slow\-log
+.sp
+Flush slow query log\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
flush\-status
.sp
Clear status variables\&.
@@ -159,6 +289,19 @@ Clear status variables\&.
.sp -1
.IP \(bu 2.3
.\}
+flush\-table\-statistics
+.sp
+Flush table statistics\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
flush\-tables
.sp
Flush all tables\&.
@@ -185,6 +328,19 @@ Flush the thread cache\&.
.sp -1
.IP \(bu 2.3
.\}
+flush\-user\-resources
+.sp
+Flush user resources\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
kill \fIid\fR,\fIid\fR,\&.\&.\&.
.sp
Kill server threads\&. If multiple thread ID values are given, there must be no spaces in the list\&.
@@ -344,6 +500,19 @@ Stop the server\&.
.sp -1
.IP \(bu 2.3
.\}
+start\-all\-slaves
+.sp
+Start all slaves\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
start\-slave
.sp
Start replication on a slave server\&.
@@ -370,6 +539,19 @@ Display a short server status message\&.
.sp -1
.IP \(bu 2.3
.\}
+stop\-all\-slaves
+.sp
+Stop all slaves\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
stop\-slave
.sp
Stop replication on a slave server\&.
@@ -821,7 +1003,7 @@ Connect to the MariaDB server on the given host\&.
\fB\-\-local\fR,
\fB\-l\fR
.sp
-Suppress the SQL command(s) from being written to the binary log by enabling sql_log_bin=0 for the session\&.
+Suppress the SQL command(s) from being written to the binary log by using FLUSH LOCAL or enabling sql_log_bin=0 for the session\&.
.RE
.sp
.RS 4
diff --git a/mysql-test/CMakeLists.txt b/mysql-test/CMakeLists.txt
index 7e5ef3fb8df..a93eb4a5084 100644
--- a/mysql-test/CMakeLists.txt
+++ b/mysql-test/CMakeLists.txt
@@ -1,4 +1,5 @@
# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2018, 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
diff --git a/mysql-test/collections/buildbot_suites.bat b/mysql-test/collections/buildbot_suites.bat
index 89e68919c7f..6228199c793 100644
--- a/mysql-test/collections/buildbot_suites.bat
+++ b/mysql-test/collections/buildbot_suites.bat
@@ -1,6 +1,10 @@
-perl mysql-test-run.pl --verbose-restart --force --testcase-timeout=45 --suite-timeout=600 --max-test-fail=500 --retry=3 --parallel=4 --suite=^
+perl mysql-test-run.pl --verbose-restart --force --suite-timeout=120 --max-test-fail=10 --retry=3 --parallel=4 --suite=^
+vcol,gcol,perfschema,^
main,^
innodb,^
+versioning,^
plugins,^
mariabackup,^
+roles,^
+auth_gssapi,^
rocksdb
diff --git a/mysql-test/extra/rpl_tests/rpl_log.test b/mysql-test/extra/rpl_tests/rpl_log.test
index d2f605e0f96..f885602eaad 100644
--- a/mysql-test/extra/rpl_tests/rpl_log.test
+++ b/mysql-test/extra/rpl_tests/rpl_log.test
@@ -65,6 +65,8 @@ flush logs;
# To make it predictable, we do a useless update now, but which has the
# interest of making the slave catch both rotate events.
+let $skip_checkpoint_events=1;
+
eval create table t3 (a int)ENGINE=$engine_type;
# Sync slave and force it to start on another binary log
diff --git a/mysql-test/extra/rpl_tests/rpl_semi_sync.inc b/mysql-test/extra/rpl_tests/rpl_semi_sync.inc
index 12053c54f4e..393b49372e1 100644
--- a/mysql-test/extra/rpl_tests/rpl_semi_sync.inc
+++ b/mysql-test/extra/rpl_tests/rpl_semi_sync.inc
@@ -4,7 +4,6 @@
# Please check all dependent tests after modifying it
#
-source include/have_semisync.inc;
source include/not_embedded.inc;
source include/have_innodb.inc;
source include/master-slave.inc;
@@ -17,6 +16,7 @@ connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
+call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave;
call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply");
diff --git a/mysql-test/include/assert_grep.inc b/mysql-test/include/assert_grep.inc
index a980a6d73b1..9f2c8505262 100644
--- a/mysql-test/include/assert_grep.inc
+++ b/mysql-test/include/assert_grep.inc
@@ -130,7 +130,10 @@ EOF
--let $_ag_outcome= `SELECT LOAD_FILE('$_AG_OUT')`
if ($_ag_outcome != 'assert_grep.inc ok')
{
- --source include/show_rpl_debug_info.inc
+ if ($rpl_server_count != '')
+ {
+ --source include/show_rpl_debug_info.inc
+ }
--echo include/assert_grep.inc failed!
--echo assert_text: '$assert_text'
--echo assert_file: '$assert_file'
diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test
index a282201857e..4ca53989d06 100644
--- a/mysql-test/include/check-testcase.test
+++ b/mysql-test/include/check-testcase.test
@@ -82,7 +82,10 @@ call mtr.check_testcase();
let $datadir=`select @@datadir`;
list_files $datadir mysql_upgrade_info;
-list_files $datadir/test #sql*;
+list_files_write_file $datadir.tempfiles.txt $datadir/test #sql*;
+--replace_regex /#sql-ib[0-9a-f]+-[0-9a-f]+\.ibd\n//
+cat_file $datadir.tempfiles.txt;
+remove_file $datadir.tempfiles.txt;
list_files $datadir/mysql #sql*;
--enable_query_log
diff --git a/mysql-test/include/ctype_like_range_mdev14350.inc b/mysql-test/include/ctype_like_range_mdev14350.inc
new file mode 100644
index 00000000000..89ecc0201cd
--- /dev/null
+++ b/mysql-test/include/ctype_like_range_mdev14350.inc
@@ -0,0 +1,14 @@
+--echo #
+--echo # MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results
+--echo #
+
+CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b;
+ALTER TABLE t1 ADD KEY(a), ADD KEY(b);
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES ('111', '111');
+INSERT INTO t1 VALUES ('222', '222');
+INSERT INTO t1 VALUES ('333', '333');
+INSERT INTO t1 VALUES ('444', '444');
+SELECT * FROM t1 WHERE a LIKE '111%';
+SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%';
+DROP TABLE t1;
diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf
index 44a7fd12d27..69a2b58288b 100644
--- a/mysql-test/include/default_mysqld.cnf
+++ b/mysql-test/include/default_mysqld.cnf
@@ -17,7 +17,7 @@
# Default values that applies to all MySQL Servers
[mysqld]
disable-getopt-prefix-matching
-
+plugin-maturity=unknown
open-files-limit= 1024
local-infile
character-set-server= latin1
diff --git a/mysql-test/include/filter_file.inc b/mysql-test/include/filter_file.inc
index 17c7c1985d7..bfe53896710 100644
--- a/mysql-test/include/filter_file.inc
+++ b/mysql-test/include/filter_file.inc
@@ -53,6 +53,9 @@
#
# $rpl_debug
# If set, verbose debug info is printed.
+#
+# $filter_script
+# If set, rows matching this regexp will be filtered out
--let $include_filename= filter_file.inc
--source include/begin_include_file.inc
@@ -67,10 +70,12 @@ if ($rpl_debug)
--let _FF_PRE_SCRIPT= $pre_script
--let _FF_SCRIPT= $script
+--let _FF_FILTER_SCRIPT= $filter_script
--let _FF_INPUT_FILE= $input_file
--let _FF_OUTPUT_FILE= $output_file
--let _FF_SELECT_COLUMNS= $select_columns
--let _FF_DEBUG= $rpl_debug
+
if (!$output_file)
{
--let _FF_OUTPUT_FILE= $input_file
@@ -79,6 +84,7 @@ perl;
my $pre_script = $ENV{'_FF_PRE_SCRIPT'};
$pre_script =~ s/DOLLAR/\$/g;
my $script = $ENV{'_FF_SCRIPT'};
+ my $filter_script = $ENV{'_FF_FILTER_SCRIPT'};
$script =~ s/DOLLAR/\$/g;
my $input_file = $ENV{'_FF_INPUT_FILE'};
my $output_file = $ENV{'_FF_OUTPUT_FILE'};
@@ -123,7 +129,10 @@ perl;
{
' . $script . '
}
- $filtered_contents .= $_."\n";
+ if (!$filter_script || ! m/$filter_script/)
+ {
+ $filtered_contents .= $_."\n";
+ }
}
close FILE or die "Error closing $input_file: $!";
open FILE, "> $output_file" or die "Error opening $output_file: $!";
diff --git a/mysql-test/include/have_debug.inc b/mysql-test/include/have_debug.inc
index 5df3080a6ed..a035031e49a 100644
--- a/mysql-test/include/have_debug.inc
+++ b/mysql-test/include/have_debug.inc
@@ -2,8 +2,3 @@
# suite.pm will make sure that all tests including this file
# will be skipped unless this is a debug build.
#
-# The test below is redundant
-
-if (`select version() not like '%debug%'`) {
- --skip Needs a debug build
-}
diff --git a/mysql-test/include/have_example_plugin.inc b/mysql-test/include/have_example_plugin.inc
index 5571c345850..c0da490dde0 100644
--- a/mysql-test/include/have_example_plugin.inc
+++ b/mysql-test/include/have_example_plugin.inc
@@ -1,14 +1,4 @@
#
-# Check if server has support for loading plugins
+# suite.pm will make sure that all tests including this file
+# will be skipped unless dynamic ha_example plugin is available
#
-if (`SELECT @@have_dynamic_loading != 'YES'`) {
- --skip Example plugin requires dynamic loading
-}
-
-#
-# Check if the variable EXAMPLE_PLUGIN is set
-#
-if (!$HA_EXAMPLE_SO) {
- --skip Need example plugin
-}
-
diff --git a/mysql-test/include/have_innodb.combinations b/mysql-test/include/have_innodb.combinations
index ac760f7fcad..f1131c448f3 100644
--- a/mysql-test/include/have_innodb.combinations
+++ b/mysql-test/include/have_innodb.combinations
@@ -6,6 +6,7 @@ innodb-cmpmem
innodb-cmp-per-index
innodb-trx
innodb-locks
+innodb-lock-waits
innodb-buffer-pool-stats
innodb-buffer-page
innodb-buffer-page-lru
@@ -24,6 +25,7 @@ innodb-cmpmem
innodb-cmp-per-index
innodb-trx
innodb-locks
+innodb-lock-waits
innodb-metrics
innodb-buffer-pool-stats
innodb-buffer-page
diff --git a/mysql-test/include/have_innodb.inc b/mysql-test/include/have_innodb.inc
index 5447d935f3c..69ffdb5b284 100644
--- a/mysql-test/include/have_innodb.inc
+++ b/mysql-test/include/have_innodb.inc
@@ -2,9 +2,3 @@
# suite.pm will make sure that all tests including this file
# will be skipped unless innodb is enabled
#
-# The test below is redundant
-
-if (`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED')`)
-{
- --skip Test requires InnoDB.
-}
diff --git a/mysql-test/include/have_semisync.inc b/mysql-test/include/have_semisync.inc
deleted file mode 100644
index 243fad83717..00000000000
--- a/mysql-test/include/have_semisync.inc
+++ /dev/null
@@ -1,4 +0,0 @@
-if (`select count(*) < 2 from information_schema.plugins where plugin_name like 'rpl_semi_sync_%'`)
-{
- --skip Test requires semisync plugins
-}
diff --git a/mysql-test/include/have_semisync.opt b/mysql-test/include/have_semisync.opt
deleted file mode 100644
index 19e29c7e4de..00000000000
--- a/mysql-test/include/have_semisync.opt
+++ /dev/null
@@ -1,4 +0,0 @@
---plugin-load-add=$SEMISYNC_MASTER_SO
---plugin-load-add=$SEMISYNC_SLAVE_SO
---loose-rpl-semi-sync-master
---loose-rpl-semi-sync-slave
diff --git a/mysql-test/include/have_semisync_plugin.inc b/mysql-test/include/have_semisync_plugin.inc
deleted file mode 100644
index 8a1679de636..00000000000
--- a/mysql-test/include/have_semisync_plugin.inc
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# Check if server has support for loading plugins
-#
-if (`SELECT @@have_dynamic_loading != 'YES'`) {
- --skip Requires dynamic loading
-}
-
-#
-# Check if the variable SEMISYNC_MASTER_SO is set
-#
-if (!$SEMISYNC_MASTER_SO)
-{
- skip Need semisync plugins;
-}
-
diff --git a/mysql-test/include/innodb_gis_row_format_basic.inc b/mysql-test/include/innodb_gis_row_format_basic.inc
deleted file mode 100644
index e6d7d3f2783..00000000000
--- a/mysql-test/include/innodb_gis_row_format_basic.inc
+++ /dev/null
@@ -1,420 +0,0 @@
---source include/have_innodb.inc
---source include/not_embedded.inc
-
-eval SET GLOBAL innodb_file_per_table=$file_per_table;
-eval SET GLOBAL innodb_file_format=$file_format;
-
-#
-# This test is the same as innodb_gis_rollback
-#
-
-eval CREATE TABLE t1 (
- id bigint(12) unsigned NOT NULL auto_increment,
- c2 varchar(15) collate utf8_bin DEFAULT NULL,
- c1 varchar(15) collate utf8_bin DEFAULT NULL,
- c3 varchar(10) collate utf8_bin DEFAULT NULL,
- spatial_point point NOT NULL,
- PRIMARY KEY(id),
- SPATIAL KEY (spatial_point)
-) ROW_FORMAT=$row_format ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
- ('y', 's', 'j', ST_GeomFromText('POINT(167 74)')),
- ('r', 'n', 'd', ST_GeomFromText('POINT(215 118)')),
- ('g', 'n', 'e', ST_GeomFromText('POINT(203 98)')),
- ('h', 'd', 'd', ST_GeomFromText('POINT(54 193)')),
- ('r', 'x', 'y', ST_GeomFromText('POINT(47 69)')),
- ('t', 'q', 'r', ST_GeomFromText('POINT(109 42)')),
- ('a', 'z', 'd', ST_GeomFromText('POINT(0 154)')),
- ('x', 'v', 'o', ST_GeomFromText('POINT(174 131)')),
- ('b', 'r', 'a', ST_GeomFromText('POINT(114 253)')),
- ('x', 'z', 'i', ST_GeomFromText('POINT(163 21)')),
- ('w', 'p', 'i', ST_GeomFromText('POINT(42 102)')),
- ('g', 'j', 'j', ST_GeomFromText('POINT(170 133)')),
- ('m', 'g', 'n', ST_GeomFromText('POINT(28 22)')),
- ('b', 'z', 'h', ST_GeomFromText('POINT(174 28)')),
- ('q', 'k', 'f', ST_GeomFromText('POINT(233 73)')),
- ('w', 'w', 'a', ST_GeomFromText('POINT(124 200)')),
- ('t', 'j', 'w', ST_GeomFromText('POINT(252 101)')),
- ('d', 'r', 'd', ST_GeomFromText('POINT(98 18)')),
- ('w', 'o', 'y', ST_GeomFromText('POINT(165 31)')),
- ('y', 'h', 't', ST_GeomFromText('POINT(14 220)')),
- ('d', 'p', 'u', ST_GeomFromText('POINT(223 196)')),
- ('g', 'y', 'g', ST_GeomFromText('POINT(207 96)')),
- ('x', 'm', 'n', ST_GeomFromText('POINT(214 3)')),
- ('g', 'v', 'e', ST_GeomFromText('POINT(140 205)')),
- ('g', 'm', 'm', ST_GeomFromText('POINT(10 236)')),
- ('i', 'r', 'j', ST_GeomFromText('POINT(137 228)')),
- ('w', 's', 'p', ST_GeomFromText('POINT(115 6)')),
- ('o', 'n', 'k', ST_GeomFromText('POINT(158 129)')),
- ('j', 'h', 'l', ST_GeomFromText('POINT(129 72)')),
- ('f', 'x', 'l', ST_GeomFromText('POINT(139 207)')),
- ('u', 'd', 'n', ST_GeomFromText('POINT(125 109)')),
- ('b', 'a', 'z', ST_GeomFromText('POINT(30 32)')),
- ('m', 'h', 'o', ST_GeomFromText('POINT(251 251)')),
- ('f', 'r', 'd', ST_GeomFromText('POINT(243 211)')),
- ('b', 'd', 'r', ST_GeomFromText('POINT(232 80)')),
- ('g', 'k', 'v', ST_GeomFromText('POINT(15 100)')),
- ('i', 'f', 'c', ST_GeomFromText('POINT(109 66)')),
- ('r', 't', 'j', ST_GeomFromText('POINT(178 6)')),
- ('y', 'n', 'f', ST_GeomFromText('POINT(233 211)')),
- ('f', 'y', 'm', ST_GeomFromText('POINT(99 16)')),
- ('z', 'q', 'l', ST_GeomFromText('POINT(39 49)')),
- ('j', 'c', 'r', ST_GeomFromText('POINT(75 187)')),
- ('c', 'y', 'y', ST_GeomFromText('POINT(246 253)')),
- ('w', 'u', 'd', ST_GeomFromText('POINT(56 190)')),
- ('n', 'q', 'm', ST_GeomFromText('POINT(73 149)')),
- ('d', 'y', 'a', ST_GeomFromText('POINT(134 6)')),
- ('z', 's', 'w', ST_GeomFromText('POINT(216 225)')),
- ('d', 'u', 'k', ST_GeomFromText('POINT(132 70)')),
- ('f', 'v', 't', ST_GeomFromText('POINT(187 141)')),
- ('r', 'r', 'a', ST_GeomFromText('POINT(152 39)')),
- ('y', 'p', 'o', ST_GeomFromText('POINT(45 27)')),
- ('p', 'n', 'm', ST_GeomFromText('POINT(228 148)')),
- ('e', 'g', 'e', ST_GeomFromText('POINT(88 81)')),
- ('m', 'a', 'h', ST_GeomFromText('POINT(35 29)')),
- ('m', 'h', 'f', ST_GeomFromText('POINT(30 71)')),
- ('h', 'k', 'i', ST_GeomFromText('POINT(244 78)')),
- ('z', 'v', 'd', ST_GeomFromText('POINT(241 38)')),
- ('q', 'l', 'j', ST_GeomFromText('POINT(13 71)')),
- ('s', 'p', 'g', ST_GeomFromText('POINT(108 38)')),
- ('q', 's', 'j', ST_GeomFromText('POINT(92 101)')),
- ('l', 'h', 'g', ST_GeomFromText('POINT(120 78)')),
- ('w', 't', 'b', ST_GeomFromText('POINT(193 109)')),
- ('b', 's', 's', ST_GeomFromText('POINT(223 211)')),
- ('w', 'w', 'y', ST_GeomFromText('POINT(122 42)')),
- ('q', 'c', 'c', ST_GeomFromText('POINT(104 102)')),
- ('w', 'g', 'n', ST_GeomFromText('POINT(213 120)')),
- ('p', 'q', 'a', ST_GeomFromText('POINT(247 148)')),
- ('c', 'z', 'e', ST_GeomFromText('POINT(18 106)')),
- ('z', 'u', 'n', ST_GeomFromText('POINT(70 133)')),
- ('j', 'n', 'x', ST_GeomFromText('POINT(232 13)')),
- ('e', 'h', 'f', ST_GeomFromText('POINT(22 135)')),
- ('w', 'l', 'f', ST_GeomFromText('POINT(9 180)')),
- ('a', 'v', 'q', ST_GeomFromText('POINT(163 228)')),
- ('i', 'z', 'o', ST_GeomFromText('POINT(180 100)')),
- ('e', 'c', 'l', ST_GeomFromText('POINT(182 231)')),
- ('c', 'k', 'o', ST_GeomFromText('POINT(19 60)')),
- ('q', 'f', 'p', ST_GeomFromText('POINT(79 95)')),
- ('m', 'd', 'r', ST_GeomFromText('POINT(3 127)')),
- ('m', 'e', 't', ST_GeomFromText('POINT(136 154)')),
- ('w', 'w', 'w', ST_GeomFromText('POINT(102 15)')),
- ('l', 'n', 'q', ST_GeomFromText('POINT(71 196)')),
- ('p', 'k', 'c', ST_GeomFromText('POINT(47 139)')),
- ('j', 'o', 'r', ST_GeomFromText('POINT(177 128)')),
- ('j', 'q', 'a', ST_GeomFromText('POINT(170 6)')),
- ('b', 'a', 'o', ST_GeomFromText('POINT(63 211)')),
- ('g', 's', 'o', ST_GeomFromText('POINT(144 251)')),
- ('w', 'u', 'w', ST_GeomFromText('POINT(221 214)')),
- ('g', 'a', 'm', ST_GeomFromText('POINT(14 102)')),
- ('u', 'q', 'z', ST_GeomFromText('POINT(86 200)')),
- ('k', 'a', 'm', ST_GeomFromText('POINT(144 222)')),
- ('j', 'u', 'r', ST_GeomFromText('POINT(216 142)')),
- ('q', 'k', 'v', ST_GeomFromText('POINT(121 236)')),
- ('p', 'o', 'r', ST_GeomFromText('POINT(108 102)')),
- ('b', 'd', 'x', ST_GeomFromText('POINT(127 198)')),
- ('k', 's', 'a', ST_GeomFromText('POINT(2 150)')),
- ('f', 'm', 'f', ST_GeomFromText('POINT(160 191)')),
- ('q', 'y', 'x', ST_GeomFromText('POINT(98 111)')),
- ('o', 'f', 'm', ST_GeomFromText('POINT(232 218)')),
- ('c', 'w', 'j', ST_GeomFromText('POINT(156 165)')),
- ('s', 'q', 'v', ST_GeomFromText('POINT(98 161)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
- ('f', 'y', 'p', ST_GeomFromText('POINT(109 235)')),
- ('b', 'e', 'v', ST_GeomFromText('POINT(20 48)')),
- ('i', 'u', 'f', ST_GeomFromText('POINT(15 55)')),
- ('o', 'r', 'z', ST_GeomFromText('POINT(105 64)')),
- ('a', 'p', 'a', ST_GeomFromText('POINT(142 236)')),
- ('g', 'i', 'k', ST_GeomFromText('POINT(10 49)')),
- ('x', 'z', 'x', ST_GeomFromText('POINT(192 200)')),
- ('c', 'v', 'r', ST_GeomFromText('POINT(94 168)')),
- ('y', 'z', 'e', ST_GeomFromText('POINT(141 51)')),
- ('h', 'm', 'd', ST_GeomFromText('POINT(35 251)')),
- ('v', 'm', 'q', ST_GeomFromText('POINT(44 90)')),
- ('j', 'l', 'z', ST_GeomFromText('POINT(67 237)')),
- ('i', 'v', 'a', ST_GeomFromText('POINT(75 14)')),
- ('b', 'q', 't', ST_GeomFromText('POINT(153 33)')),
- ('e', 'm', 'a', ST_GeomFromText('POINT(247 49)')),
- ('l', 'y', 'g', ST_GeomFromText('POINT(56 203)')),
- ('v', 'o', 'r', ST_GeomFromText('POINT(90 54)')),
- ('r', 'n', 'd', ST_GeomFromText('POINT(135 83)')),
- ('j', 't', 'u', ST_GeomFromText('POINT(174 239)')),
- ('u', 'n', 'g', ST_GeomFromText('POINT(104 191)')),
- ('p', 'q', 'y', ST_GeomFromText('POINT(63 171)')),
- ('o', 'q', 'p', ST_GeomFromText('POINT(192 103)')),
- ('f', 'x', 'e', ST_GeomFromText('POINT(244 30)')),
- ('n', 'x', 'c', ST_GeomFromText('POINT(92 103)')),
- ('r', 'q', 'z', ST_GeomFromText('POINT(166 20)')),
- ('s', 'a', 'j', ST_GeomFromText('POINT(137 205)')),
- ('z', 't', 't', ST_GeomFromText('POINT(99 134)')),
- ('o', 'm', 'j', ST_GeomFromText('POINT(217 3)')),
- ('n', 'h', 'j', ST_GeomFromText('POINT(211 17)')),
- ('v', 'v', 'a', ST_GeomFromText('POINT(41 137)')),
- ('q', 'o', 'j', ST_GeomFromText('POINT(5 92)')),
- ('z', 'y', 'e', ST_GeomFromText('POINT(175 212)')),
- ('j', 'z', 'h', ST_GeomFromText('POINT(224 194)')),
- ('a', 'g', 'm', ST_GeomFromText('POINT(31 119)')),
- ('p', 'c', 'f', ST_GeomFromText('POINT(17 221)')),
- ('t', 'h', 'k', ST_GeomFromText('POINT(26 203)')),
- ('u', 'w', 'p', ST_GeomFromText('POINT(47 185)')),
- ('z', 'a', 'c', ST_GeomFromText('POINT(61 133)')),
- ('u', 'k', 'a', ST_GeomFromText('POINT(210 115)')),
- ('k', 'f', 'h', ST_GeomFromText('POINT(125 113)')),
- ('t', 'v', 'y', ST_GeomFromText('POINT(12 239)')),
- ('u', 'v', 'd', ST_GeomFromText('POINT(90 24)')),
- ('m', 'y', 'w', ST_GeomFromText('POINT(25 243)')),
- ('d', 'n', 'g', ST_GeomFromText('POINT(122 92)')),
- ('z', 'm', 'f', ST_GeomFromText('POINT(235 110)')),
- ('q', 'd', 'f', ST_GeomFromText('POINT(233 217)')),
- ('a', 'v', 'u', ST_GeomFromText('POINT(69 59)')),
- ('x', 'k', 'p', ST_GeomFromText('POINT(240 14)')),
- ('i', 'v', 'r', ST_GeomFromText('POINT(154 42)')),
- ('w', 'h', 'l', ST_GeomFromText('POINT(178 156)')),
- ('d', 'h', 'n', ST_GeomFromText('POINT(65 157)')),
- ('c', 'k', 'z', ST_GeomFromText('POINT(62 33)')),
- ('e', 'l', 'w', ST_GeomFromText('POINT(162 1)')),
- ('r', 'f', 'i', ST_GeomFromText('POINT(127 71)')),
- ('q', 'm', 'c', ST_GeomFromText('POINT(63 118)')),
- ('c', 'h', 'u', ST_GeomFromText('POINT(205 203)')),
- ('d', 't', 'p', ST_GeomFromText('POINT(234 87)')),
- ('s', 'g', 'h', ST_GeomFromText('POINT(149 34)')),
- ('o', 'b', 'q', ST_GeomFromText('POINT(159 179)')),
- ('k', 'u', 'f', ST_GeomFromText('POINT(202 254)')),
- ('u', 'f', 'g', ST_GeomFromText('POINT(70 15)')),
- ('x', 's', 'b', ST_GeomFromText('POINT(25 181)')),
- ('s', 'c', 'g', ST_GeomFromText('POINT(252 17)')),
- ('a', 'c', 'f', ST_GeomFromText('POINT(89 67)')),
- ('r', 'e', 'q', ST_GeomFromText('POINT(55 54)')),
- ('f', 'i', 'k', ST_GeomFromText('POINT(178 230)')),
- ('p', 'e', 'l', ST_GeomFromText('POINT(198 28)')),
- ('w', 'o', 'd', ST_GeomFromText('POINT(204 189)')),
- ('c', 'a', 'g', ST_GeomFromText('POINT(230 178)')),
- ('r', 'o', 'e', ST_GeomFromText('POINT(61 116)')),
- ('w', 'a', 'a', ST_GeomFromText('POINT(178 237)')),
- ('v', 'd', 'e', ST_GeomFromText('POINT(70 85)')),
- ('k', 'c', 'e', ST_GeomFromText('POINT(147 118)')),
- ('d', 'q', 't', ST_GeomFromText('POINT(218 77)')),
- ('k', 'g', 'f', ST_GeomFromText('POINT(192 113)')),
- ('w', 'n', 'e', ST_GeomFromText('POINT(92 124)')),
- ('r', 'm', 'q', ST_GeomFromText('POINT(130 65)')),
- ('o', 'r', 'r', ST_GeomFromText('POINT(174 233)')),
- ('k', 'n', 't', ST_GeomFromText('POINT(175 147)')),
- ('q', 'm', 'r', ST_GeomFromText('POINT(18 208)')),
- ('l', 'd', 'i', ST_GeomFromText('POINT(13 104)')),
- ('w', 'o', 'y', ST_GeomFromText('POINT(207 39)')),
- ('p', 'u', 'o', ST_GeomFromText('POINT(114 31)')),
- ('y', 'a', 'p', ST_GeomFromText('POINT(106 59)')),
- ('a', 'x', 'z', ST_GeomFromText('POINT(17 57)')),
- ('v', 'h', 'x', ST_GeomFromText('POINT(170 13)')),
- ('t', 's', 'u', ST_GeomFromText('POINT(84 18)')),
- ('z', 'z', 'f', ST_GeomFromText('POINT(250 197)')),
- ('l', 'z', 't', ST_GeomFromText('POINT(59 80)')),
- ('j', 'g', 's', ST_GeomFromText('POINT(54 26)')),
- ('g', 'v', 'm', ST_GeomFromText('POINT(89 98)')),
- ('q', 'v', 'b', ST_GeomFromText('POINT(39 240)')),
- ('x', 'k', 'v', ST_GeomFromText('POINT(246 207)')),
- ('k', 'u', 'i', ST_GeomFromText('POINT(105 111)')),
- ('w', 'z', 's', ST_GeomFromText('POINT(235 8)')),
- ('d', 'd', 'd', ST_GeomFromText('POINT(105 4)')),
- ('c', 'z', 'q', ST_GeomFromText('POINT(13 140)')),
- ('m', 'k', 'i', ST_GeomFromText('POINT(208 120)')),
- ('g', 'a', 'g', ST_GeomFromText('POINT(9 182)')),
- ('z', 'j', 'r', ST_GeomFromText('POINT(149 153)')),
- ('h', 'f', 'g', ST_GeomFromText('POINT(81 236)')),
- ('m', 'e', 'q', ST_GeomFromText('POINT(209 215)')),
- ('c', 'h', 'y', ST_GeomFromText('POINT(235 70)')),
- ('i', 'e', 'g', ST_GeomFromText('POINT(138 26)')),
- ('m', 't', 'u', ST_GeomFromText('POINT(119 237)')),
- ('o', 'w', 's', ST_GeomFromText('POINT(193 166)')),
- ('f', 'm', 'q', ST_GeomFromText('POINT(85 96)')),
- ('x', 'l', 'x', ST_GeomFromText('POINT(58 115)')),
- ('x', 'q', 'u', ST_GeomFromText('POINT(108 210)')),
- ('b', 'h', 'i', ST_GeomFromText('POINT(250 139)')),
- ('y', 'd', 'x', ST_GeomFromText('POINT(199 135)')),
- ('w', 'h', 'p', ST_GeomFromText('POINT(247 233)')),
- ('p', 'z', 't', ST_GeomFromText('POINT(148 249)')),
- ('q', 'a', 'u', ST_GeomFromText('POINT(174 78)')),
- ('v', 't', 'm', ST_GeomFromText('POINT(70 228)')),
- ('t', 'n', 'f', ST_GeomFromText('POINT(123 2)')),
- ('x', 't', 'b', ST_GeomFromText('POINT(35 50)')),
- ('r', 'j', 'f', ST_GeomFromText('POINT(200 51)')),
- ('s', 'q', 'o', ST_GeomFromText('POINT(23 184)')),
- ('u', 'v', 'z', ST_GeomFromText('POINT(7 113)')),
- ('v', 'u', 'l', ST_GeomFromText('POINT(145 190)')),
- ('o', 'k', 'i', ST_GeomFromText('POINT(161 122)')),
- ('l', 'y', 'e', ST_GeomFromText('POINT(17 232)')),
- ('t', 'b', 'e', ST_GeomFromText('POINT(120 50)')),
- ('e', 's', 'u', ST_GeomFromText('POINT(254 1)')),
- ('d', 'd', 'u', ST_GeomFromText('POINT(167 140)')),
- ('o', 'b', 'x', ST_GeomFromText('POINT(186 237)')),
- ('m', 's', 's', ST_GeomFromText('POINT(172 149)')),
- ('t', 'y', 'a', ST_GeomFromText('POINT(149 85)')),
- ('x', 't', 'r', ST_GeomFromText('POINT(10 165)')),
- ('g', 'c', 'e', ST_GeomFromText('POINT(95 165)')),
- ('e', 'e', 'z', ST_GeomFromText('POINT(98 65)')),
- ('f', 'v', 'i', ST_GeomFromText('POINT(149 144)')),
- ('o', 'p', 'm', ST_GeomFromText('POINT(233 67)')),
- ('t', 'u', 'b', ST_GeomFromText('POINT(109 215)')),
- ('o', 'o', 'b', ST_GeomFromText('POINT(130 48)')),
- ('e', 'm', 'h', ST_GeomFromText('POINT(88 189)')),
- ('e', 'v', 'y', ST_GeomFromText('POINT(55 29)')),
- ('e', 't', 'm', ST_GeomFromText('POINT(129 55)')),
- ('p', 'p', 'i', ST_GeomFromText('POINT(126 222)')),
- ('c', 'i', 'c', ST_GeomFromText('POINT(19 158)')),
- ('c', 'b', 's', ST_GeomFromText('POINT(13 19)')),
- ('u', 'y', 'a', ST_GeomFromText('POINT(114 5)')),
- ('a', 'o', 'f', ST_GeomFromText('POINT(227 232)')),
- ('t', 'c', 'z', ST_GeomFromText('POINT(63 62)')),
- ('d', 'o', 'k', ST_GeomFromText('POINT(48 228)')),
- ('x', 'c', 'e', ST_GeomFromText('POINT(204 2)')),
- ('e', 'e', 'g', ST_GeomFromText('POINT(125 43)')),
- ('o', 'r', 'f', ST_GeomFromText('POINT(171 140)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
- ('b', 'c', 'e', ST_GeomFromText('POINT(41 137)')),
- ('p', 'y', 'k', ST_GeomFromText('POINT(50 22)')),
- ('s', 'c', 'h', ST_GeomFromText('POINT(208 173)')),
- ('x', 'u', 'l', ST_GeomFromText('POINT(199 175)')),
- ('s', 'r', 'h', ST_GeomFromText('POINT(85 192)')),
- ('j', 'k', 'u', ST_GeomFromText('POINT(18 25)')),
- ('p', 'w', 'h', ST_GeomFromText('POINT(152 197)')),
- ('e', 'd', 'c', ST_GeomFromText('POINT(229 3)')),
- ('o', 'x', 'k', ST_GeomFromText('POINT(187 155)')),
- ('o', 'b', 'k', ST_GeomFromText('POINT(208 150)')),
- ('d', 'a', 'j', ST_GeomFromText('POINT(70 87)')),
- ('f', 'e', 'k', ST_GeomFromText('POINT(156 96)')),
- ('u', 'y', 'p', ST_GeomFromText('POINT(239 193)')),
- ('n', 'v', 'p', ST_GeomFromText('POINT(223 98)')),
- ('z', 'j', 'r', ST_GeomFromText('POINT(87 89)')),
- ('h', 'x', 'x', ST_GeomFromText('POINT(92 0)')),
- ('r', 'v', 'r', ST_GeomFromText('POINT(159 139)')),
- ('v', 'g', 'g', ST_GeomFromText('POINT(16 229)')),
- ('z', 'k', 'u', ST_GeomFromText('POINT(99 52)')),
- ('p', 'p', 'o', ST_GeomFromText('POINT(105 125)')),
- ('w', 'h', 'y', ST_GeomFromText('POINT(105 154)')),
- ('v', 'y', 'z', ST_GeomFromText('POINT(134 238)')),
- ('x', 'o', 'o', ST_GeomFromText('POINT(178 88)')),
- ('z', 'w', 'd', ST_GeomFromText('POINT(123 60)')),
- ('q', 'f', 'u', ST_GeomFromText('POINT(64 90)')),
- ('s', 'n', 't', ST_GeomFromText('POINT(50 138)')),
- ('v', 'p', 't', ST_GeomFromText('POINT(114 91)')),
- ('a', 'o', 'n', ST_GeomFromText('POINT(78 43)')),
- ('k', 'u', 'd', ST_GeomFromText('POINT(185 161)')),
- ('w', 'd', 'n', ST_GeomFromText('POINT(25 92)')),
- ('k', 'w', 'a', ST_GeomFromText('POINT(59 238)')),
- ('t', 'c', 'f', ST_GeomFromText('POINT(65 87)')),
- ('g', 's', 'p', ST_GeomFromText('POINT(238 126)')),
- ('d', 'n', 'y', ST_GeomFromText('POINT(107 173)')),
- ('l', 'a', 'w', ST_GeomFromText('POINT(125 152)')),
- ('m', 'd', 'j', ST_GeomFromText('POINT(146 53)')),
- ('q', 'm', 'c', ST_GeomFromText('POINT(217 187)')),
- ('i', 'r', 'r', ST_GeomFromText('POINT(6 113)')),
- ('e', 'j', 'b', ST_GeomFromText('POINT(37 83)')),
- ('w', 'w', 'h', ST_GeomFromText('POINT(83 199)')),
- ('k', 'b', 's', ST_GeomFromText('POINT(170 64)')),
- ('s', 'b', 'c', ST_GeomFromText('POINT(163 130)')),
- ('c', 'h', 'a', ST_GeomFromText('POINT(141 3)')),
- ('k', 'j', 'u', ST_GeomFromText('POINT(143 76)')),
- ('r', 'h', 'o', ST_GeomFromText('POINT(243 92)')),
- ('i', 'd', 'b', ST_GeomFromText('POINT(205 13)')),
- ('r', 'y', 'q', ST_GeomFromText('POINT(138 8)')),
- ('m', 'o', 'i', ST_GeomFromText('POINT(36 45)')),
- ('v', 'g', 'm', ST_GeomFromText('POINT(0 40)')),
- ('f', 'e', 'i', ST_GeomFromText('POINT(76 6)')),
- ('c', 'q', 'q', ST_GeomFromText('POINT(115 248)')),
- ('x', 'c', 'i', ST_GeomFromText('POINT(29 74)')),
- ('l', 's', 't', ST_GeomFromText('POINT(83 18)')),
- ('t', 't', 'a', ST_GeomFromText('POINT(26 168)')),
- ('u', 'n', 'x', ST_GeomFromText('POINT(200 110)')),
- ('j', 'b', 'd', ST_GeomFromText('POINT(216 136)')),
- ('s', 'p', 'w', ST_GeomFromText('POINT(38 156)')),
- ('f', 'b', 'v', ST_GeomFromText('POINT(29 186)')),
- ('v', 'e', 'r', ST_GeomFromText('POINT(149 40)')),
- ('v', 't', 'm', ST_GeomFromText('POINT(184 24)')),
- ('y', 'g', 'a', ST_GeomFromText('POINT(219 105)')),
- ('s', 'f', 'i', ST_GeomFromText('POINT(114 130)')),
- ('e', 'q', 'h', ST_GeomFromText('POINT(203 135)')),
- ('h', 'g', 'b', ST_GeomFromText('POINT(9 208)')),
- ('o', 'l', 'r', ST_GeomFromText('POINT(245 79)')),
- ('s', 's', 'v', ST_GeomFromText('POINT(238 198)')),
- ('w', 'w', 'z', ST_GeomFromText('POINT(209 232)')),
- ('v', 'd', 'n', ST_GeomFromText('POINT(30 193)')),
- ('q', 'w', 'k', ST_GeomFromText('POINT(133 18)')),
- ('o', 'h', 'o', ST_GeomFromText('POINT(42 140)')),
- ('f', 'f', 'h', ST_GeomFromText('POINT(145 1)')),
- ('u', 's', 'r', ST_GeomFromText('POINT(70 62)')),
- ('x', 'n', 'q', ST_GeomFromText('POINT(33 86)')),
- ('u', 'p', 'v', ST_GeomFromText('POINT(232 220)')),
- ('z', 'e', 'a', ST_GeomFromText('POINT(130 69)')),
- ('r', 'u', 'z', ST_GeomFromText('POINT(243 241)')),
- ('b', 'n', 't', ST_GeomFromText('POINT(120 12)')),
- ('u', 'f', 's', ST_GeomFromText('POINT(190 212)')),
- ('a', 'd', 'q', ST_GeomFromText('POINT(235 191)')),
- ('f', 'q', 'm', ST_GeomFromText('POINT(176 2)')),
- ('n', 'c', 's', ST_GeomFromText('POINT(218 163)')),
- ('e', 'm', 'h', ST_GeomFromText('POINT(163 108)')),
- ('c', 'f', 'l', ST_GeomFromText('POINT(220 115)')),
- ('c', 'v', 'q', ST_GeomFromText('POINT(66 45)')),
- ('w', 'v', 'x', ST_GeomFromText('POINT(251 220)')),
- ('f', 'w', 'z', ST_GeomFromText('POINT(146 149)')),
- ('h', 'n', 'h', ST_GeomFromText('POINT(148 128)')),
- ('y', 'k', 'v', ST_GeomFromText('POINT(28 110)')),
- ('c', 'x', 'q', ST_GeomFromText('POINT(13 13)')),
- ('e', 'd', 's', ST_GeomFromText('POINT(91 190)')),
- ('c', 'w', 'c', ST_GeomFromText('POINT(10 231)')),
- ('u', 'j', 'n', ST_GeomFromText('POINT(250 21)')),
- ('w', 'n', 'x', ST_GeomFromText('POINT(141 69)')),
- ('f', 'p', 'y', ST_GeomFromText('POINT(228 246)')),
- ('d', 'q', 'f', ST_GeomFromText('POINT(194 22)')),
- ('d', 'z', 'l', ST_GeomFromText('POINT(233 181)')),
- ('c', 'a', 'q', ST_GeomFromText('POINT(183 96)')),
- ('m', 'i', 'd', ST_GeomFromText('POINT(117 226)')),
- ('z', 'y', 'y', ST_GeomFromText('POINT(62 81)')),
- ('g', 'v', 'm', ST_GeomFromText('POINT(66 158)'));
-
-START TRANSACTION;
-
-# following INSERTion will result in a node split
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
- ('f', 'x', 'p', ST_GeomFromText('POINT(92 181)'));
-
-# Test rollback, this will result above split being rolled back, btr_compress
-# gets called
-ROLLBACK;
-
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
- ('f', 'x', 'p', ST_GeomFromText('POINT(92 181)'));
-
-# create overlap on the bounding box in parent
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES ('n', 'x', 'p', ST_GeomFromText('POINT(0 1280)'));
-
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES ('n', 'x', 'p', ST_GeomFromText('POINT(45 1280)'));
-
-# Add a row in the cross section of the 2 bounding box
-INSERT INTO t1 VALUES (1280, 'n', 'x', 'p', ST_GeomFromText('POINT(44 253)'));
-
-# Delete this new poINT
-DELETE FROM t1 WHERE id = 1280;
-
-INSERT INTO t1 VALUES (1280, 'n', 'x', 'p', ST_GeomFromText('POINT(44 253)'));
-
-START TRANSACTION;
-DELETE FROM t1 WHERE id = 1280;
-ROLLBACK;
-
-# Test MBR increase
-START TRANSACTION;
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
- ('m', 'u', 'p', ST_GeomFromText('POINT(1192 1181)'));
-ROLLBACK;
-
-SELECT COUNT(*) FROM t1;
-UPDATE t1 SET spatial_point = ST_GeomFromText('POINT(123 456)') WHERE id < 2000;
-SET @g1 = ST_GeomFromText('Polygon((123 456, 123 678, 456 678,456 456,123 456))');
-DELETE FROM t1 WHERE MBRContains(@g1, t1.spatial_point);
-SELECT COUNT(*) FROM t1;
-
-DROP TABLE t1;
-
-SET GLOBAL innodb_file_per_table=default;
-SET GLOBAL innodb_file_format=default;
-
diff --git a/mysql-test/include/innodb_gis_undo.inc b/mysql-test/include/innodb_gis_undo.inc
deleted file mode 100644
index 075c7d1274e..00000000000
--- a/mysql-test/include/innodb_gis_undo.inc
+++ /dev/null
@@ -1,83 +0,0 @@
-
-eval CREATE TABLE t1 (
- p INT NOT NULL AUTO_INCREMENT,
- g LINESTRING NOT NULL,
- PRIMARY KEY(p)
-) ENGINE=InnoDB ROW_FORMAT=$row_format;
-
-if ($index == 'spatial_none') {
- eval ALTER TABLE t1 ADD INDEX prefix_idx (g($prefix_size));
-}
-
-if ($index == 'spatial_only') {
- ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
-}
-
-if ($index == 'spatial_mixed') {
- ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
- eval ALTER TABLE t1 ADD INDEX prefix_idx (g($prefix_size));
-}
-
-INSERT INTO t1(g) VALUES(ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)'));
-INSERT INTO t1(g) VALUES(ST_linefromtext(concat('linestring','(18 106,19 106,24 111,27 108,32 104,37 107,42 107,44 112,44 116,40 118,43 114,46 114,42 118,44 123,45 123,49 123,53 119,50 123,50 124,54 126,58 125,59 126,64 127,65 127,69 131,74 132,75 135,78 139,2078 141,2075 143,2077 143,2079 143,2084 143,2085 147,2090 -1853,2086 -1852,2086 -1856,2089 -1852,2093 -1850,2090 -1851,2090 -1852,2091 -1851,2092 -1850,2097 -1847,2102 -1848,2100 -1852,2100 -1852,7100 -1851,7103 -1850,7104 -1847,7109 -1842,65 127,67 131,66 131,61 132,61 133,62 137,65 1137,2065 1135,2061 1135,2064 1135,5064 1135,5066 1135,5070 1136,5070 1141,5071 1138,5074 1141,5075 1141,5074 1137,5076 1137,5071 1139,5066 1142,5065 2142,5068 2147,5073 2151,5069 2156,5071 2157,5072 2162,5074 2165,5069 2169,5072 2169,5076 2173,5074 2169,5078 2169,5076 2170,76 2175,74 2179,75 2184,80 2188,83 2190,87 2189,84 2193,87 2189,86 2190,87 2195,87 2200,87 1200,85 1202,86 1199,87 1200,87 1201,91 1206,92 1204,94 1204,98 1206,102 1208,105 1211,102 1216,105 1220,109 1224,110 1224,114 1225,117 1224,118 1229,117 1232,122 1237,123 1236,120 1235,124 1237,121 1236,122 1240,126 1244,127 1246,126 1249,125 5249,123 5251,127 5251,131 5251,135 5256,138 5257,135 5257,139 5257,138 5258,141 5260,146 5260,146 5260,143 10260,147 10265,151 10270,156 10266,157 10269,162 10273,166 12273,168 12274,163 12270,168 12275,170 12277,170 12277,-3830 12277,-3825 12277,-3824 12278,-3825 12276,-3825 12278,-3822 12277,-3825 12275,-3829 12278,-3828 12275,-3824 12280,-3827 12280,-3826 12282,-3822 12283,-3822 12286,-3820 12288,-3818 12289,-3816 12294,-3817 12297,-3819 12300,-3816 12297,-3813 12295,-3811 12299,-3811 12297,-3806 12298,-3806 12298,-3804 12301,-3801 12306,-3803 17306,-3803 17306,-3798 17306,-3803 17310,-3801 17314,-3798 17317,-3797 17317,-797 17321,-797 17323,-796 17325,-793 17326,-792 17322,-789 17327,-784 17331,-780 17335,-776 17339,-774 17339,-771 17342,-770 17345,-765 17348,-765 17349,-763 17353,-760 17350,-760 22350,-756 22346,-752 22349,-748 22352,-752 22348,-748 22347,-746 22345,-745 27345,-743 27346,257 27350,260 27349,261 27352,266 27348,266 22348,269 22347,271 22347,272 22347,273 22348,273 22352,278 22348,279 22344,282 22345,282 22342,283 22347,283 22347,288 22349,292 22347,292 22348,293 22348,298 22348,303 22351,306 22352,309 22352,308 22354,310 22356,311 22361,311 22358,311 22360,311 22360,315 22356,320 22358,325 22363,326 22366,321 22371,318 22373,318 22375,314 22375,316 22375,321 22376,321 22376,322 22372,32 104,36 109,40 114,40 113,40 117,44 119,49 123,49 126,49 129,53 133,50 137,50 139,49 137,48 138,43 138,42 139,46 142,46 138,41 139,45 141,4045 5141,4045 5146,4042 5147,4043 10147,4041 10150,4042 10152,4045 10152,4041 10156,4041 10152,4041 10152,4046 10153,4049 10156,4046 10155,4051 10157,4055 10159,4055 10160,4056 10161,4055 10166,4054 10169,4054 10172,4054 15172,4051 15176,4047 15177,4049 15174,4047 15176,4047 15176,4046 15177,4046 15180,4043 15184,4043 15187,4038 15190,4040 15194,4040 15199,4045 15196,4047 15197,4050 15200,4050 15204,4050 15208,4047 15212,4047 15215,4049 15216,4046 15218,4042 15223,4042 15228,4042 15232,4047 15235,4050 15236,4050 15239,4051 15243,4053 15243,4050 17243,4052 17243,4052 18243,4057 18247,4061 18249,4064 18249,4067 20249,4067 20250,4067 20255,4066 20259,4066 20259,4067 20255,4069 20256,4071 20258,4072 20254,4067 20257,4067 20260,4069 20265,4065 20267,4069 20266,4070 20267,4071 20264,4074 20259,4070 20264,4073 20260,4074 20263,4077 20268,4082 20271,4084 20273,4084 20277,4081 18277,4085 18279,4086 18276,4087 18273,4087 18275,4092 18277,4093 18279,4093 18280,4095 18280,4091 18283,4092 18281,4094 18283,4090 18287,4094 18287,138 5257,138 5255,138 5258,-1862 5254,-1860 5256,-1856 5258,-1851 5255,-1850 5260,-1847 5260,-1847 5263,-1847 5258,-1850 5257,-1850 5259,-1851 5257,-1855 5258,-1853 5261,-1849 5261,-1849 5258,-1849 5259,-1845 5264,-1847 5264,-1850 5268,-1852 5266,-1853 5270,-1856 5265,-1852 5262,-1847 5263,-1842 5263,-1842 5260,-1842 5265,-1841 5265,-1844 5265,-1842 5270,-1837 5274,-1838 5279,-1843 5275,-1842 5280,-1838 5281,-1838 5285,-1833 5285,-1828 5288,-1824 5289,-1828 5291,-1831 5291,-1826 5291,-1830 5293,-1826 5296,-1822 5301,-1826 5302,-1826 5302,-1826 5302,-1825 5297,-1820 5299,-1816 5303,-1816 5299,-3811 12299,-3809 12302,-3806 12302,-3806 12302,-3803 12304,-3798 12304,-3797 12304,-3793 12306,-3788 12306,-3783 12309,-3816 12294,-3811 12299,-3809 12297,7100 -1851,7098 -1854,7102 -1854,7107 -1856,7107 -1858,7110 -1854,7110 -1851,7113 -1851,7115 -1851,7120 -1851,7123 -1847,7124 -1852,7125 -1852,7127 -1852,7131 -1852,7129 1148,7129 1145,7133 1150,7137 1148,7138 1147,7143 1149,7147 1154,8147 1155,8152 3155,8147 3157,8143 3158,8144 3160,8144 3164,11144 3167,11146 3167,11148 3163,11152 3161,11148 3159,11149 3163,11150 3161,11151 3166,11154 3171,11154 3170,8144 3160,8144 3163,8144 3166,8145 3166,8146 3171,8146 3174,8144 3174,8144 3174,8145 3176,8141 3180,3141 3182,7141 3183,7141 7183,7136 7185,7136 7185,7133 7187,7136 7187,7131 7190,7136 7194,7137 7197,7141 7196,7139 7199,12139 7200,12143 7200,12143 7199,12144 7203,12145 7200,12141 7200,12136 7195,12136 7191,12137 7191,12137 7196,12139 7197,12140 7197,12137 7201,12140 7204,12140 7209,12143 7209,12145 7210,12147 7214,12148 9214,12152 9218,12149 9218,12149 9221,12149 9220,12150 9222,12153 10222,12153 10226,12156 10227,12159 10223,12160 10220,12161 10225,12161 10227,12163 10224,12163 10223,12158 10224,12158 10227,12158 10231,12155 12231,12157 12226,7136 7185,7139 7189,7139 7189,7139 7188,7137 7191,7139 7191,7140 7189,7143 7191,7144 7189,7144 7190,7149 7193,7152 7194,7154 7198,7153 7203,7148 7207,12148 7209,12146 7209,12145 7213,12140 7217,12139 7219,12141 7219,12138 7218,12143 7218,13143 7220,13140 7224,13142 7228,13137 7231,13142 7235,13146 7239,13149 7243,13148 7247,13150 7248,13155 7249,13155 7253,13155 7253,13155 7258,13157 7260,13162 7255,13159 7255,13163 7258,13164 7258,13164 7263,13167 7264,13167 8264,13165 8265,13169 8265,13171 13265,13175 13261,13176 13259,13176 13259,13180 13262,13181 13262,13183 13262,13188 13265,13191 13267,13191 13265,13194 13267,13191 13269,13192 13264,13196 13269,13198 13272,13200 13272,13202 13270,13207 11270,13211 11270,13211 11273,13213 11274,13217 11275,13222 11276,13222 11272,13226 11274,13231 11277,13233 11282,13236 11284,13238 11284,13236 11286,13236 11288,13236 11283,13236 11284,13238 11289,13241 11292,13244 11292,13245 11289,13241 11294,13244 11298,13249 11301,320 22358,324 24358,328 24358,327 24363,326 24359,327 24361,329 24365,334 24367,-666 24367,-670 24368,49 123,46 127,46 129,49 131,49 136,47 135,45 138,3045 135,3042 138,3044 139,3044 144,3049 144,3053 142,3055 137,3058 136,3053 139,3048 142,7048 138,7048 3138,7048 3139,7048 3140,7050 3145,7053 1145,7050 1146,7053 5146,7048 5150,7047 5146,10047 5147,10043 5147,10047 5147,10050 5152,10052 5155,10054 5156,10056 5157,10056 5159,10058 5162,10062 5164,10062 5169,10066 9169,10068 9168,10063 9164,10063 9169,10061 9171,14061 9172,14061 9174,282 22342,287 22347,288 22347,288 22343,285 22339,280 22338,278 22341,279 25341,284 25343,13241 11294,13246 11296,13243 11296,13244 11291,13245 11291,13244 11291,13246 11295,13251 11300,13253 11305,13253 11306,13258 11305,13255 11306,13256 11309,13256 11311,13261 11307,13265 11303,13267 11305,13270 11301,13275 11298,13271 11300,15271 11302,15276 11306,15279 11303,15284 11305,15286 11305,15289 11307,15290 11302,15292 11305,15296 11309,15297 11313,15298 11316,15300 11317,15304 11320,15306 11324,15306 11320,15307 11320,15312 11320,15313 11319,15317 11317,15315 11321,15317 11323,15317 11328,15319 11333,15322 11336,15322 11337,15322 11337,15324 11341,15324 11345,15325 14345,15328 13345,17328 13346,17333 13349,17337 13354,17338 13358,17342 13358,17346 13353,17348 13353,17345 13353,17348 13354,17347 13354,17347 13354,17347 13355,22347 13358,22349 13355,22351 13355,22356 13354,22358 13354,22361 13355,22362 13355,22358 13355,22359 13359,22364 13364,22369 13369,22372 13373,22376 13371,22377 13371,22377 13369,22381 13374,22386 13379,22387 13376,22387 13380,22392 13378,22390 13374,22392 13378,22391 13378,22391 13375,22392 13378,22390 13380,22393 13382,22398 13387,22398 10387,22402 10391,22399 10392,22400 10392,22400 10394,22404 10391,22403 15391,22405 15392,22407 15392,22412 15387,22412 15390,22412 15394,22408 15396,26408 15398,26407 20398,26411 20402,26415 20406,26417 20411,26420 20407,26422 20407,31422 16407,31421 16405,31421 16410,31423 16410,31426 16414,31426 16410,31430 16415,31430 16418,31435 16419,31437 16420,31438 16422,31438 16425,31438 16425,31441 16427,31439 16431,31441 16436,36441 16436,36443 18436,36442 18437,36440 18440,36440 18436,36440 18440,36442 18445,36443 18446,36447 18451,37447 23451,37452 23456,37456 23455,37458 23459,37456 23461,37458 23463,37460 23466,37464 23469,37460 23474,37462 23476,37461 26476,37466 26479,37470 26483,37471 26488,37474 26489,37474 26485,37474 26483,37474 26488,37470 26492,37474 26497,37474 26499,37478 26495,37483 26499,37483 26501,37488 26496,37491 26499,37495 26495,37500 26496,37500 26497,37500 26501,37497 26499,37497 26499,37495 26504,37498 26504,37494 26509,37497 26514,37495 26515,37498 26514,37503 26514,37508 26512,37510 26516,37511 26519,37509 26523,37506 26528,37507 26532,37512 26536,37513 26538,37510 26542,37512 26544,37517 26543,37522 26546,37527 26551,37525 26555,37529 26558,37524 26563,37524 26562,37527 26562,37522 26562,37522 26559,37526 26561,37522 26559,37523 26561,37523 26556,37524 26558,40524 26560,40524 26563,40521 26567,40525 26566,40527 26568,40532 26572,40534 26569,40533 26565,40531 26565,40535 26569,40535 26570,40539 26572,40544 26575,40543 26575,40544 26579,40548 26584,40549 26581,40553 26585,40556 26590,40552 22590,40557 22594,40556 22595,40561 22592,40561 22593,40565 22593,40568 22593,40573 22588,40570 22590,40570 22591,40570 22588,40573 22590,40573 22593,40568 22593,40567 22597,40567 22599,40571 22599,40574 22600,40574 22604,42574 22607,42577 22607,42577 22612,42579 22616,38579 22619,38580 22617,38580 22614,38575 22619,38579 22619,38579 18619,38582 18614,38582 18617,38586 18622,38590 18625,38590 18622,38594 18621,38596 18616,38597 18614,38597 18618,38600 21618,38601 21618,38605 21620,38607 25620,38611 25620,38608 25617,38608 25621,38608 25625,38611 25623,38615 25623,38615 25620,38616 25622,38619 25624,38620 25625,38620 26625,38623 26627,38623 26627,311 22358,311 22359,-1689 22360,2311 27360,2312 27360,2312 27360,2317 27362,2317 27362,2319 27359,2319 27364,2318 27359,2321 27364,2326 27367,2325 27371,2326 27373,2326 27373,2325 27377,2329 27377,2327 27377,2330 27379,2333 27379,2331 27379,2331 27381,2336 27381,6336 27382,6336 27383,40527 26568,40531 26572,40533 26574,40538 26576,40533 26580,40538 26585,40539 26588,40536 26583,40540 26587,40539 26588,40535 26593,40540 26594,40544 26597,40548 26602,40548 26601,40549 26602,40547 26602,40548 26603,40553 26606,40548 26606,40548 26603,40551 26608,40556 26612,40559 26616,40554 26619,40556 26619,40556 26623,42556 26623,42556 26624,42560 26624,42562 26626,42563 26630,42564 26630,42564 26634,42559 26635,42562 26635,42565 26637,42562 26638,42564 26642,42564 26641,42568 26641,42572 26641,42572 29641,42574 29642,39574 29641,39574 34641,39576 34643,39581 34638,39578 34638,39574 34642,39574 34645,39572 35645,34572 35648,34577 35651,39577 35655,43577 35659,43580 35655,43575 35658,43578 35658,43581 35662,43577 39662,43572 39658,43572 39661,43572 39664,43572 39666,43576 39670,43577 39667,43580 39671,43576 39673,43573 39673,43574 39677,43569 39679,43567 39679,43568 39683,43563 39686,43566 39690,43566 39692,43568 39694,43568 39695,41568 39691,41570 39692,41571 39692,41571 39693,41571 39698,41571 39698,41574 39698,41569 39698,41570 39699,41570 39704,41572 39709,41573 39712,41578 39713,41579 39717,41584 39719,41585 39720,-1850 5268,-1845 5268,-1847 5266,-1842 5268,-1840 5263,-1845 5264,-1843 5264,-1839 8264,-1839 8267,-1839 8272,-1838 8276,-1834 8273,-1834 8273,-1833 8274,-1837 8279,-1836 8283,-1834 8286,-1836 8282,-1834 8279,-1835 8279,-1834 8280,-1836 8283,-1841 8288,-1846 8289,-1843 8286,-1838 8286,-1841 8285,-1838 8285,-1834 8288,-1829 8291,-1825 8286,-1825 8289,-1825 8287,-1824 8291,-1822 8294,-1821 8298,-1818 8300,-1818 8296,-1814 8296,-1811 8295,-1808 8292,1192 8296,1192 8297,1195 11297,1192 11301,1195 11305,1197 11300,1193 11300,1193 11296,1193 11293,1194 11294,1199 11292,1204 11292,1205 11294,1210 11292,1208 11288,1204 11290,1205 11289,1207 8289,1202 8284,1204 8282,1204 8281,1206 8281,1208 8281,1212 8283,1212 13283,1213 13287,1213 13290,1216 13293,1214 13289,1217 13286,1212 13291,1208 13288,1208 13292,1209 13297,1208 13296,1204 13298,1205 13303,1209 13308,1204 13308,1209 13304,1210 13304,1214 13309,1214 13314,1215 13314,1219 13314,1219 13319,1224 13320,1229 13321,1232 13325,1233 13329,1231 13329,1234 13334,-2766 13336,-2769 13337,-2765 13340,-2762 13345,-2760 13342,2240 13342,2238 13342,2242 13342,2246 13345,2246 13346,2244 13348,2239 13348,2240 13351,2240 13352,2245 13357,2248 13357,2243 13362,2247 13362,2248 13362,2252 13363,2256 13363,2256 13363,2260 13367,2255 13372,2251 13369,2251 13369,2252 13372,2249 13376,2254 13378,2255 13382,2259 13379,2262 13379,2267 13381,2262 13381,2262 13383,2265 13383,2269 13385,2270 13386,2271 13389,2267 13391,2271 13386,2275 13391,2273 13392,2275 13387,2277 13390,2274 13390,2275 13394,2280 13395,2280 11395,2281 14395,2279 14400,2277 14403,2273 14406,2274 16406,2274 16410,2279 16410,2284 16411,2280 16409,2280 16409,2282 16409,2282 16411,2282 16412,2280 16413,3280 16418,3284 16418,3285 16423,3289 16423,3292 16427,3294 16429,3296 16431,3297 16436,3298 16435,3303 16435,3305 16434,3305 16436,3305 16436,3309 16437,3309 16438,3308 16439,3308 16439,3306 16444,3302 16441,-1698 16437,-1703 16438,-1699 16438,-1697 16438,-1698 16439,-1695 16436,-1690 16441,-1687 16446,-1683 16450,-1682 16451,-1684 16453,-1682 16457,-1682 16457,-1686 16460,-1681 16459,-1680 16456,-1677 16460,-1681 16461,-1679 16464,-1674 16465,-1673 16469,-1669 16471,-1669 16476,-1665 16474,-1665 16478,-1664 16478,-1664 16479,-1661 16474,-1656 16471,-1655 11471,-1660 11473,-1663 11475,-1666 11480,3334 15480,3338 15476,3342 15471,3345 15471,3345 15470,3350 15469,3347 15474,3351 15476,3352 15473,3353 15476,3350 15477,3350 15479,3351 15482,3352 15484,3351 15487,3353 15487,3358 15487,3353 15486,1217 13286,1222 13291,1222 13291,1225 13286,1229 13286,1231 13281,1235 13280,1236 13281,1241 13282,1245 13285,1247 13285,1247 13287,1250 13287,1247 13290,1247 13295,1247 13298,1252 13301,1249 13304,1252 13304,3252 13304,3247 13304,3249 13308,3254 13308,3257 13308,3261 17308,3261 17309,3261 17306,3259 17305,3262 17310,3263 17308,3262 17311,3259 17314,3259 17314,3257 17309,3254 17309,3253 17309,3255 17310,3253 17312,3255 17312,3255 17312,3256 17307,3257 17307,3256 17311,3256 17313,3255 17317,3251 17317,3248 17321,3253 17325,3256 17326,3258 17324,3258 17327,3263 17322,7263 17325,7265 17328,7263 17330,7265 17333,7270 17333,7273 17333,7278 17336,4278 21336,4278 21340,4279 21340,4281 21340,4286 24340,4290 24343,9290 24347,9294 24349,9296 24347,9298 25347,9301 25348,9301 25348,9304 25353,9303 25357,9303 25352,11303 25355,11304 25358,11307 25358,11312 25358,11312 25361,11310 25365,11313 25365,11314 25369,11319 25371,11321 25371,11325 25366,11329 25365,11330 25366,11329 25370,11330 25365,11334 25367,11338 25366,11343 25363,11348 25359,11345 25356,11348 25357,11349 25358,11349 25358,11352 25360,11356 30360,11360 30365,11360 30365,11362 30365,11367 30367,11368 30369,15368 30370,15373 30371,15376 30373,14376 30378,14377 30383,14381 30378,14386 30380,14388 30382,14391 30385,14393 31385,16393 31389,16396 31394,16396 31397,16392 31400,16395 31405,16398 31409,16398 31413,16397 31415,16396 31417,16401 31418,16401 31422,16402 31419,16407 31420,16411 31419,16406 31423,18406 31427,18411 31432,18415 28432,18417 28437,18418 28441,18414 28438,18417 28435,18416 28439,18420 28442,18423 28447,18427 28444,21427 28445,21428 28450,22428 28455,22432 28457,22436 28458,22441 28458,22445 28463,22448 28468,22451 28465,22456 28468,22453 28468,22458 28471,22463 28473,22460 28475,22459 28472,22463 28476,22464 28472,22468 28468,22468 28471,25468 28466,25471 28468,25473 28464,25473 28464,25475 29464,25476 29466,25479 29461,25476 29462,25476 29464,25478 29464,25483 29461,25484 29460,25486 29458,25486 29462,25490 29460,25495 26460,25498 26463,25495 26468,25495 26472,25495 26472,25499 26474,25504 26476,25504 26478,25509 26476,25513 26479,25514 26481,25519 26477,25519 26480,25518 26481,25519 26484,25524 26483,25527 26484,25522 26484,25526 26487,25528 26492,25533 26496,25535 26498,25535 26498,25539 26503,25542 26504,25543 26505,25547 26510,25552 26510,25551 26508,25550 26512,25553 26510,25557 26510,25554 26511,25552 26508,25556 26505,25556 26506,25560 26506,25560 26507,25560 26506,25565 26501,25567 26504,25569 26504,25568 26508,25571 26508,25571 26511,25576 26511,25581 26516,25581 26519,25582 26521,25585 26522,25588 26527,25588 26526,25584 26530,25587 26534,25589 26529,25593 26533,25598 26538,25599 26540,25599 26540,25599 26540,25604 26543,25603 26543,25603 26538,25606 26538,25609 26540,25611 26542,25612 26547,25612 26547,25612 26548,25617 25548,25612 25548,25613 25547,25616 25545,25616 25549,25618 25551,25620 25555,25620 25551,25622 25550,25625 25551,25622 25555,25619 25557,25617 25556,25622 28556,25625 28551,25630 28546,25634 28548,25639 28553,25643 28553,25638 25553,25634 25553,25634 25557,25639 25557,25643 25558,25644 25553,25646 25556,25647 25560,25650 25562,25650 30562,25650 30562,25650 30564,25650 30566,25652 30570,25656 30571,25661 31571,25662 31575,25663 31579,25662 31579,25665 31581,25666 31584,25671 31582,25674 31581,25674 31584,25676 31584,25673 31587,25678 31586,25679 31581,30679 31584,30675 31589,30680 31590,35680 31590,35675 31589,35677 31591,35680 31590,35681 31587,35684 31588,35685 31589,35689 31592,35689 31593,35692 31597,35696 31597,35700 34597,35699 34599,35703 34604,35703 34606,35702 34601,35705 34603,35705 34606,35708 34603,35713 34604,35717 34603,35719 34608,35715 34608,35711 34608,35713 34609,35714 34605,35714 34610,35714 34614,35718 34616,35719 34617,35722 34618,35722 34621,35725 34625,35725 34626,35725 34629,35725 34631,35725 34635,35730 34636,35727 34638,35731 34640,35735 34642,35739 34645,35741 34645,35742 34649,35738 34649,35738 34645,35741 34647,38741 34650,38741 37650,38742 37646,38746 37651,38749 37652,38753 37653,38753 37657,38757 37656,38756 37660,38761 37660,38765 37660,38760 37660,38759 37660,38760 41660,38760 41660,38762 41665,38757 41667,43757 41669,43752 41674,43752 41677,43757 41672,43758 41677,45758 41680,45758 41679,45762 41683,45765 41683,45769 41683,45770 41684,45768 46684,45773 46688,45776 46692,45774 46694,45775 46697,45778 46695,45776 46698,45774 46702,45779 46702,45784 46704,45787 46706,45791 46711,45786 46707,45790 46711,45793 46715,45796 46719,45799 46724,45797 46728,45802 46726,45797 46729,45801 46733,45802 46733,45803 46732,45804 46732,45805 46732,45808 46735,45810 46740,45810 46744,2326 27373,2322 27377,2323 27379,2325 27383,2325 27382,2322 27382,2323 27382,5323 23382,5325 23385,5329 23386,5330 23390,5335 23392,5330 23392,5330 23395,5329 23395,5333 23399,5333 23402,5338 23405,5339 23405,5334 23406,5329 23401,5332 23403,5330 23407,5333 23409,5328 20409,5324 20411,5324 20414,5329 20416,5328 20421,5325 20421,5329 20424,5330 20424,5335 21424,5331 21427,5333 21431,5334 21433,5329 21434,5330 21437,5333 21440,5338 21437,5338 21440,5334 21441,5333 21438,5329 26438,5332 26435,5335 26439,5337 26440,5338 26444,5342 26439,5342 26442,5345 26440,5349 26438,5352 26442,5349 26445,5348 30445,5350 30447,5350 30444,5354 30444,5359 30443,5363 30445,5367 30446,5367 30448,5367 30453,5371 30455,5371 30453,5373 30458,5375 30461,5380 30463,5384 30463,5383 30459,5384 30459,5383 30459,5385 30460,5390 30459,5392 30464,5394 30464,5389 30465,5393 30469,5391 30469,5391 30469,5395 30474,5396 30470,5399 30470,5401 30467,5401 30468,5404 30470,5400 30465,5401 30462,5403 30467,5404 30467,5409 30469,5412 30473,5412 30477,5407 30481,8407 30486,8408 30489,8410 30490,8410 30489,8413 30490,8414 30493,8414 30496,8419 30501,8420 30502,8415 30507,13415 30509,13411 30506,13414 30507,13412 30511,13412 30515,13417 30518,13419 30523,13418 30527,13422 30529,13418 30531,13413 35531,13409 35531,13413 35532,13417 35537,13419 35533,13423 35529,13424 35529,13423 35524,13428 35525,13433 35526,13438 35530,13443 35531,13448 35531,13452 35532,13455 35536,13457 35536,13452 35536,13455 35539,13452 35535,13457 35540,13457 35544,18457 35546,18460 35547,22460 35546,22465 35550,22466 35554,22468 35552,22473 35555,22471 35559,22470 35564,22472 35564,22470 35569,22474 35569,22474 35571,22477 35573,22482 35576,22487 35580,22488 35583,22489 35585,22493 35585,22496 35585,25496 35586,25493 35582,25494 35585,25498 35585,25496 35585,25498 35587,25503 35591,25503 35593,25499 35590,25499 35591,25495 35591,26495 35595,29495 35591,29495 35593,29498 35597,29498 35601,29500 35606,29501 30606,29502 30603,29505 30603,29510 30606,29511 30606,29514 30607,29516 30610,29518 30608,3259 17305,3263 17304,3267 17303,3271 17308,3269 17312,3269 17313,3274 17315,3277 17315,3282 17311,3285 17313,3283 17309,3278 17310,3275 17315,3275 17317,3276 17322,3280 17324,3280 17324,3276 17325,3277 17325,3276 17328,3278 17324,3273 17329,3277 17331,3280 17326,3281 17328,3276 17324,3277 17324,3277 17322,3277 17321,3277 17321,3281 17323,3282 17327,3282 17332,3287 17335,3288 17335,3288 17338,3290 17337,3294 17340,3294 17341,3299 17341,3299 12341,3299 12342,3304 12339,3301 14339,3305 14340,3307 14341,3311 14343,3313 14343,3314 16343,3310 16341,3310 16346,3312 16348,3311 16349,4311 16346,4316 16348,4321 16344,4324 16348,4322 16349,4323 16346,4323 16346,4326 16350,4322 16354,4323 16356,4325 16361,4325 16358,4322 16362,4325 20362,4325 20366,4322 20367,4326 20372,4326 20374,4331 20373,4333 20373,4338 20376,4339 20379,4341 20382,4338 20384,4339 20386,4340 20383,4340 20383,4335 20388,4336 20390,4341 20390,4346 20391,4348 20391,4349 20393,37497 26499,37494 26496,37496 26500,37496 26501,37499 26506,37497 26502,37498 26502,37500 29502,37500 29507,37505 29508,37506 33508,37508 33513,37513 33518,37517 33522,37516 33520,37521 33521,37521 33525,37516 33530,37519 33528,37520 33528,37524 33530,37527 33530,37525 33527,37528 33530,37533 33533,37534 38533,37536 38536,22358 13355,25358 13360,25361 13358,25362 13362,25362 13362,25365 13365,25363 13367,25359 13369,25357 13374,25360 13374,2247 13362,2252 13366,2254 13363,2257 13363,2261 13358,2264 13354,2264 13356,2269 13361,2272 13363,2274 13363,2275 13363,2273 13362,2274 13365,2278 13365,2280 13370,2284 13366,2284 13365,2289 13368,2290 13366,2293 13368,2298 13373,2298 13372,2295 13375,271 22347,273 22350,4273 22347,4269 22348,4270 22350,4271 22355,4272 22360,4276 22363,4281 22365,4284 24365,4279 24365,4282 24365,4285 24365,4287 24364,4289 24362,4294 24360,4295 24362,4298 24365,4301 24369,1301 24370,1301 24371,1305 24375,1305 24376,1307 24377,1312 24380,1314 24382,1318 24380,1316 24382,1316 24387,1318 24387,1318 29387,1321 29387,1316 29383,1320 29386,1321 29389,1326 29389,1327 29389,2327 29394,2327 29394,2332 29393,-666 24367,-663 24368,-661 24368,-656 24371,-653 24372,-649 24372,-647 24374,-643 24370,-638 24375,-635 24380,-638 24382,-638 24384,-638 24384,-636 24388,-637 24390,-632 24386,-630 24386,-629 24386,371 24389,376 24394,374 24392,377 24397,3377 24400,6377 24405,6378 24408,6373 24406,6370 24406,6375 24403,6370 24403,6375 24403,6379 24406,6374 24409,6378 24411,6380 24412,6378 24415,6378 24419,6383 24423,6385 24425,6387 24428,6390 24433,6386 24430,6386 24435,6387 24436,6388 24440,6387 24444,6383 29444,6383 29447,6386 29451,6382 29446,6387 29447,6390 29452,6393 29452,6397 29455,6400 29459,6400 29463,6397 29467,6393 29467,6395 29470,6397 29473,6399 29468,6394 29467,6397 29470,6396 29473,6396 29470,6393 29465,6389 29469,6390 29470,6389 29465,6389 29468,6392 29470,6388 33470,6390 33466,6391 33466,6392 33467,6394 33467,322 22372,322 22374,323 22377,327 22378,331 22382,330 22383,332 22386,333 22383,331 22383,330 22387,332 22391,332 22396,337 22397,339 22394,340 22399,340 22398,340 22396,343 22396,343 22396,341 22400,342 22404,343 22402,348 22403,345 22407,347 22411,342 22411,345 22413,340 22417,345 22417,348 22422,348 22426,351 22427,352 22432,352 22436,4352 22438,4353 22442,4354 22444,4354 22447,4357 22449,4360 22450,4364 22450,4367 22451,4369 22453,4366 22455,4369 22453,4373 22458,4377 22459,4380 22459,4380 22464,4385 22467,4385 22467,4390 22469,4385 22469,4385 22472,25571 26508,25574 26507,25578 26512,25581 26512,25581 26512,25583 26508,25583 26513,25587 26516,25589 26515,25590 26515,25591 26517,25589 26520,25587 26522,23587 26526,23585 26531,23589 26534,23592 26538,24592 26543,24588 26545,24593 26547,24598 26543,24598 26548,24602 26545,24598 26540,24600 26545,24600 26548,24600 31548,24605 31549,24608 31551,24613 31552,24615 36552,24616 36557,24619 36557,24622 36560,24622 36564,24627 35564,24627 35569,24632 35569,25632 35570,25635 35569,25636 35573,25636 35573,25638 35576,25641 35580,25641 35583,25641 35588,25642 40588,20642 40593,20645 40593,20650 40595,20651 40591,20651 40594,20648 40591,20648 40591,20652 40596,20652 40596,20656 40597,20656 40600,20656 40601,20659 40598,20662 40597,20662 40597,20663 40600,20668 40601,20665 40606,1215 13314,1214 13319,1212 13317,1209 13312,1210 13312,1211 13317,6211 13320,6214 13320,6216 13320,6211 13323,6214 13318,6214 13323,6214 13324,6216 13319,6219 13323,6218 13321,6219 13321,6218 13326,6221 13329,6225 13331,6230 13335,6231 13339,6231 13343,6235 13338,6234 13342,6234 13344,6236 13345,25524 26483,25521 26484,25524 26489,25527 26487,25529 26484,25530 26482,25534 27482,25539 27486,25537 27488,25541 27483,25544 27486,25547 27490,25550 27491,25550 27491,25554 27486,25559 27486,25563 27489,25561 27489,25563 27493,25561 27491,25563 27493,25563 27495,25564 27497,25563 27497,25563 27497,25558 27498,25563 27499,25565 27503,25567 27503,25569 27503,25567 27504,25565 27505,25565 27505,25565 27505,25566 27505,25570 27501,25570 27497,25574 27498,25570 32498,25570 32501,25573 32501,25576 32497,25576 32498,25577 32501,25579 32503,25583 32504,25588 32507,25592 32512,25596 32507,25599 32507,25594 32503,25597 32506,25597 32510,25594 32509,25594 32510,25596 32513,25592 32513,25594 32515,25594 32520,25598 32520,25602 32517,25603 32518,27603 32520,27607 32523,27608 31523,27613 31527,27615 31527,30615 31530,30617 31530,30618 31532,30619 31536,30623 31537,30623 31538,30625 31538,30626 31541,30627 31541,30624 31540,30623 31540,30624 31545,34624 31546,34619 31543,34623 31545,34624 31549,34624 31548,34626 31550,34626 31555,34626 31551,34628 31555,34633 31555,34636 31559,34634 31564,34636 31564,34639 31562,34639 31560,36639 31555,36636 27555,41636 27557,41640 27554,41644 27558,41647 27559,41648 27555,41653 27555,41658 27555,41658 27552,41658 27552,41660 27550,41656 27554,41661 27558,41664 27561,41667 27566,41662 27562,41663 27563,41663 27565,41662 27569,41661 27569,41664 27571,41664 27567,41659 30567,41660 30565,41660 30561,41665 30566,41664 30561,41664 30561,41664 30562,41664 30563,41660 30558,1312 24380,4312 25380,4315 25384,4315 25385,4319 25383,4322 25388,6322 25387,6322 25387,6326 25392,6321 25397,6324 25397,6324 25401,6319 25404,9319 25405,9314 25400,9312 25402,9310 25403,9313 25403,9313 25403,9316 25400,9319 25401,4319 25396,8319 25398,8315 25400,8315 25396,8315 25397,8311 25398,8307 25394,8309 25394,8311 25397,8315 25402,8310 25403,11310 25365,11311 25365,11316 25370,11320 25375,11325 25375,11325 25380,11325 25382,11326 25378,14326 25380,14328 25382,14331 25383,14334 25385,14336 25386,19336 25386,19336 25389,19332 25390,19332 25391,19335 25388,19338 25391,19342 25393,19340 25393,19345 25396,19345 25394,19347 25394,19349 25393,19351 25397,19350 25398,19348 25399,19349 25403,19352 25399,19350 25402,19354 25400,19353 25405,23353 25402,23354 25402,23356 25405,23358 25409,23360 25413,23363 25414,23367 25412,23365 25411,23367 25414,23363 25413,23367 25416,23367 25416,23370 25418,24370 25414,24370 25419,24373 27419,24378 27419,24380 27416,24380 27412,24380 27410,24380 27406,24376 27406,24374 27410,24370 27414,24370 27415,24371 27420,24375 27415,24378 27411,24375 27415,24378 27418,24382 27421,24383 27426,24383 27425,24385 27430,24390 27431,24394 27432,24395 27436,24399 30436,24400 30439,24404 30443,24403 30439,24406 30438,24410 30442,24406 30446,24408 30445,24403 30445,24408 30442,24412 30446,24416 30446,24416 30449,19416 30449,19416 30447,19418 30452,19420 30453,19423 30458,15423 30462,15423 30464,15425 30466,16425 30467,16424 30471,16421 30474,16426 30474,16428 30476,16428 30476,16424 30474,16424 33474,16425 33474,16427 33477,16425 33479,16426 33477,16422 33480,16425 33482,16430 33479,16430 33478,16429 33482,16424 33482,16427 33484,16430 33488,16431 33488,16434 33488,16435 33491,16432 33487,16436 37487,16434 37490,16438 37485,16443 37482,16446 37480,16447 37480,16447 37482,16451 37478,16454 37479,16458 37479,16454 37479,16454 37482,16459 37486,16460 37491,16463 37495,16464 37492,16465 37493,16466 37494,16468 37497,16468 37501,16468 37501,16473 37503,16473 37503,16473 37498,16476 37494,21476 33494,21473 33493,21476 33489,21478 33491,21478 33496,21478 33492,21480 33496,21483 33501,21484 33504,21483 33500,21484 33505,21484 33505,21488 35505,21491 35505,21494 35506,21496 35510,21492 35506,21492 35509,21489 35514,21490 35517,21487 35519,23487 35523,23485 35528,23487 35533,23483 35534,23487 35535,23488 35537,23493 35539,23495 35542,23495 35546,23495 35550,23491 35549,23488 35552,23492 35555,23495 35560,23500 35559,23496 35557,4322 16354,4317 16358,4318 16358,4320 16363,4315 16363,4315 16362,4316 20362,4320 20365,4323 20363,4326 20366,4329 20367,4332 20370,4337 20374,4338 20375,4333 20375,4338 20375,4341 20377,4342 20377,4342 20378,4343 20381,4346 20386,4346 20386,4346 20386,4346 20386,4349 20390,4352 20395,4354 20396,4355 20400,4358 20400,4360 20401,4360 20404,4363 20405,4368 20406,4372 20411,4371 20416,4367 20417,4364 20422,4367 20420,4372 20425,4373 20422,4374 20418,4377 20418,4381 20422,4382 20423,4384 20418,4389 20421,4385 20423,4390 20423,4390 20425,4392 20429,4396 20434,41574 39698,41578 39702,41576 39704,45576 39704,45575 39709,45577 39713,45581 39715,45581 39718,45583 39721,45578 39726,47578 39722,47581 39719,47586 39722,47586 39726,47589 39730,47592 39733,47597 39733,47593 39733,47596 39735,47597 39735,47595 39735,47591 39739,47593 39744,47593 39747,4074 20263,4077 20268,4079 20268,4078 20271,4078 22271,4083 22276,4087 22272,4088 22275,4086 22279,4082 22280,4084 22282,4086 22277,4082 22277,4087 22281,4090 22281,4092 22281,4092 22286,4094 22287,4097 22290,4097 22291,4095 22286,4095 22288,4095 22293,4095 22288,4092 22285,4089 22286,4090 22286,4095 22281,4100 22286,4103 22285,4104 22288,4104 22289,4107 22294,4112 22292,4117 22290,4120 22295,120 22300,121 22303,122 22300,122 22300,121 26300,125 26303,129 26303,127 26305,127 26306,132 26306,132 26307,136 26307,141 26309,140 26311,143 26313,140 26314,145 26318,149 26318,153 26321,153 29321,158 29326,158 29329,162 29324,162 34324,165 34329,168 34328,167 34332,169 34333,173 34334,173 34336,177 34338,178 34340,178 34344,182 34348,177 34348,182 34348,184 34353,184 34358,181 34360,183 34365,187 34365,192 34365,197 34367,199 34366,203 34368,205 34368,202 34363,204 34360,1204 34360,1205 34364,1205 30364,1205 30359,1206 30361,1207 30364,1210 30366,1210 30366,1214 30367,1218 30372,1219 30375,1214 30379,1214 30384,1217 30382,1222 30383,1223 30382,1225 30380,1228 30379,1231 30383,1232 30383,1235 30384,1237 30388,1242 30386,1244 30389,2244 30392,2241 30395,2245 30397,2245 30399,2244 30394,2242 30395,2246 32395,2246 32395,2249 32398,2251 32393,5251 32390,5251 32395,5255 32399,5255 32397,5257 32397,5257 32401,5261 32406,5261 32411,5266 32412,5271 32416,5273 32419,5276 32420,5281 32422,5279 32425,6279 33425,6284 33429,6284 33430,6282 33431,6282 33428,6286 33425,6288 32425,6288 32421,6286 32424,6288 32424,11288 32427,11292 32425,11292 32429,11290 32434,11286 32437,11286 32437,11283 32442,11278 32442,11279 32443,11283 32445,11284 32445,11283 32448,13283 32447,13287 32442,16287 32446,16282 32445,16283 32445,16284 32448,16285 32448,16284 32446,16286 32443,16290 32446,16291 32446,16292 32450,16291 32450,16291 32450,16291 32445,16287 32447,16288 32452,16287 32457,16291 36457,16289 36462,16293 36462,16294 36462,16297 36462,16301 36464,16306 36469,16310 36467,16310 36463,16313 36459,16312 36460,16313 36465,16313 36469,16308 36470,16309 36468,16314 36470,16319 41470,16322 41471,16325 44471,16330 44471,16330 44471,16330 44473,16330 44474,16335 44479,16332 44477,8414 30496,8415 30497,8419 30497,8414 30501,8416 30500,8418 30495,8421 35495,8423 35494,8427 35497,8429 35499,8432 35499,8436 35503,8438 35503,8443 35505,8440 35508,8443 35509,8440 35509,8440 35511,8441 35515,8445 35511,8448 35512,8443 35517,8443 35519,8442 35524,8444 35526,8441 35527,8436 35527,8433 35523,8429 35527,8430 35530,8431 35532,8429 35533,8433 35535,8437 32535,8435 32536,8439 32536,8436 32539,9436 32542,9434 32537,9429 32534,9429 32534,9433 32537,9433 32542,9429 32543,9434 32538,9436 32538,9436 34538,7436 34538,7438 34543,7439 34543,7439 34543,7439 34548,7438 34549,7438 34552,7438 34553,7438 34556,11438 34561,11434 34559,11436 34555,7436 34553,7436 34549,120 1235,124 1239,125 1236,125 1238,129 1235,128 1235,125 1236,123 1239,128 2239,132 2242,131 2242,135 2242,140 2242,145 2247,146 2252,144 2253,146 2248,144 2245,146 2244,150 2249,155 2245,159 2242,160 2243,160 2245,155 2244,156 2245,3156 2246,3159 2248,3159 2250,3164 2254,3165 2257,3166 2255,3169 2257,3171 2262,3169 2263,3174 2268,3177 2273,3174 2276,3178 2275,3173 2279,3177 2276,3180 2279,3182 2284,3185 2289,5185 2286,5185 2288,5181 2286,5185 2288,5184 2293,5187 2293,5187 2297,5190 2299,5187 2299,5185 2300,5181 6300,5182 6297,5187 6300,5189 6298,5191 6296,5193 6296,5193 6296,5195 6297,5195 6300,5197 6297,5195 6300,5190 6302,5191 6306,5192 6308,5195 6312,24395 27436,24391 27437,24393 27433,24398 27436,24398 27437,16286 32443,21286 32443,21286 32444,21282 32448,21283 32446,21283 32448,21285 32451,21281 32456,21282 32458,21282 32463,21282 32468,21284 32470,21289 32471,21287 32471,21287 32469,21287 32474,21284 32477,21288 32482,21291 32482,21291 32486,21296 32485,21299 32486,21301 32487,21303 32484,21301 32482,21305 32487,21310 32491,21312 32495,21313 32491,21315 32495,21312 32495,21314 32498,21316 32501,21311 32506,21311 32508,21312 32513,21317 32516,21319 32516,21324 32516,21327 32521,21328 32526,21332 32527,21328 36527,21331 41527,21336 41527,21334 41531,21337 41533,21335 41535,21339 41540,21340 41540,21343 41536,25343 41539,25340 41542,25337 41542,25337 41545,25335 41542,25335 41543,25335 46543,25339 46548,30339 46551,30340 46556,30343 46557,30342 46553,30337 46556,30341 46561,30337 46565,30336 46563,30338 46564,24373 27419,24373 27421,24375 27424,24377 27425,24377 27430,24374 27435,24379 27437,24384 27432,24385 27434,24382 27437,24381 27442,24381 31442,24381 33442,20381 33439,20383 34439,20382 34440,20378 34444,20381 34446,20381 34442,20384 34443,20388 34446,20392 34447,20393 34442,20393 34447,20396 29447,20395 29443,20399 29443,20400 29439,20399 29436,20404 29439,20409 29440,20410 29440,20410 29444,20408 29445,20413 29448,20413 29451,20412 29455,20413 29458,20418 29461,20413 29463,20415 29464,20416 29464,20416 29463,20416 29463,20418 29464,20414 29465,20418 29463,20413 29460,20413 26460,20418 26458,20421 26459,20421 26461,20421 26460,43578 35658,43578 35654,43578 35658,43578 35660,43583 35661,43583 35659,43583 35662,43579 35663,43583 35661,43587 35666,25625 25551,25629 25551,25630 25554,25630 25559,25632 25560,25627 25561,25623 25557,25623 25559,25624 25561,26624 25566,26627 25566,29627 25571,29626 25574,29625 25575,29622 25579,29625 25583,29630 25588,29632 25589,29635 25591,29635 25594,29637 25598,29642 25596,29643 25597,29644 25597,29649 25598,29654 25602,29656 25602,29661 25603,29661 25601,29664 26601,29666 26604,29665 26604,29668 26607,29672 26607,29669 26611,29671 26616,29674 26613,29679 26616,29680 26616,29681 26615,29682 26619,29679 26617,29684 26622,29686 26624,29689 26624,29690 26628,29691 26630,29693 26625,29694 26620,29698 26617,29703 29617,29707 29616,29706 29620,29709 29623,34709 29626,34710 29628,34710 29627,2282 16411,2283 16412,2283 16412,2287 16417,2292 16421,2297 16421,2298 16426,2303 16426,2304 16429,2309 11429,2313 11432,2308 14432,2308 14431,2311 14433,2310 14437,2308 14438,2309 14440,2311 14440,2309 14443,2312 14443,2314 14447,2314 14452,2314 14450,2309 14451,2309 14451,2309 14456,2313 14461,2313 14461,2309 19461,2309 19461,2311 19462,2315 19465,2318 19465,2321 19462,2317 19464,2321 19467,2322 19467,2322 19469,2322 19469,2320 19464,2321 19462,2322 19461,2327 19466,2327 19461,2322 19461,2322 19463,2317 19467,2318 19471,2102 -1848,2107 -1848,2111 -1846,2114 1154,2114 1156,2115 1157,2114 6157,2116 6162,2121 6165,2124 6170,2121 6175,2124 6179,2124 6183,2128 6178,2126 6179,2125 6178,2126 6181,2122 10181,2127 10186,2128 10189,2130 10188,2130 10191,2127 11191,2127 11195,2131 11196,2132 11192,2131 11197,2135 11201,2135 11203,2139 11199,2142 11203,2143 11204,2147 11208,2142 11210,2142 11211,2147 11212,2150 11217,2150 11219,2151 11219,2152 11222,2152 11222,2148 11224,2150 11220,2150 11223,2146 11218,2143 11219,2140 11221,2143 11218,2140 11219,2140 11223,2145 11225,2147 11226,2152 11226,2155 11224,2157 11229,2157 11229,2153 11233,2153 11238,2149 11239,7149 10239,7154 10241,7157 10241,7162 10243,7164 10248,7164 10251,7169 10253,7171 10253,7172 10257,7177 10260,7182 10256,7187 10260,7191 8260,7195 8256,7200 8258,7204 8258,7203 8261,7203 8262,7205 8266,7209 8270,7209 8273,7214 8273,7214 8276,7210 8276,7211 8276,7213 8279,7218 8278,7222 8283,7223 8279,7220 10279,7221 10283,7223 10284,7228 10286,7230 10290,7231 10290,7231 10293,7232 10294,7232 10297,7234 10299,7229 10295,7226 10294,7221 10293,7223 10295,7228 10299,7229 10303,7232 10307,7232 10311,7233 10316,7234 9316,7239 9318,7244 9321,7241 9326,7241 9328,7238 9331,7235 9330,7237 9335,7236 9335,7236 9337,7236 9338,7231 14338,7230 14333,7232 14338,7237 18338,4082 22280,4081 22280,6081 22283,6076 22285,6076 22289,6078 22286,6080 22287,6084 22292,6084 22293,6085 22293,6086 22291,6091 22294,6092 22293,9092 22290,9095 22294,9096 22295,9096 22297,9091 22292,9096 22295,9098 22290,9094 18290,9097 18290,9096 18294,9099 18292,9098 18297,9103 18299,9103 18302,9103 18305,9100 18301,9102 18302,9106 18305,9102 18310,9101 18306,9103 18308,9103 18312,9107 18310,9107 18315,9107 18320,9111 18322,9111 18326,9113 18329,9111 18329,9116 18329,9121 18329,9121 18332,9123 18331,9124 18332,9125 18328,9127 18325,9125 18328,9128 18329,9133 18329,9136 18333,9141 18337,9142 18342,9143 18340,9148 18344,9152 18341,9150 18346,9149 18341,9149 18341,9154 18343,9158 18345,9161 18346,9161 18347,9163 18352,9164 18352,9162 18349,9165 18352,9165 18351,9165 18352,9165 18356,9163 18352,9167 18353,9167 18349,9168 18351,9168 18347,9173 18347,9175 18347,9179 18348,9182 18349,9187 18352,9186 18357,9189 18360,9192 18360,9196 18362,13196 18367,13196 18369,13196 18371,13199 18374,13194 18374,13197 18375,13200 18377,13205 18380,13210 18384,13209 18379,13209 18374,13213 18375,13216 20375,13212 20375,13215 20375,13211 20375,13211 20372,13208 20373,13204 20373,13204 20369,13205 20369,13207 20366,13212 20367,13216 20367,13221 20372,13222 20377,13225 20381,13226 20386,13230 20383,9230 20388,9228 20384,9228 20386,9223 20389,9223 20392,4223 20397,4223 20396,4225 20399,4222 20404,4220 20408,4220 20411,4223 20416,4227 20421,4230 20418,4234 20421,4232 20422,4236 20423,4238 20423,4239 20423,4235 20427,4231 20427,4230 20426,4228 20428,4232 20427,4232 20431,4236 20433,4241 20431,4241 22431,4236 22436,4239 22437,4239 22439,4236 22443,4232 22439,4236 22444,4236 22446,4239 22447,4239 22452,4241 22454,4245 22457,4245 22460,4250 22462,4251 22465,4253 22465,4249 22465,4251 22460,4251 22464,4255 22469,4257 22473,4256 22478,4259 22479,4260 22480,4257 22485,6257 22489,6260 22490,6260 22493,6262 22496,6262 22500,6267 22495,6271 22495,6276 22491,6276 22489,6281 22487,6286 22490,6289 22490,6294 22490,6294 22489,6292 22485,6292 22489,6288 22489,6288 22494,6288 22496,6286 22497,6288 22501,6292 22500,5292 22503,5292 22503,5296 22508,5295 22510,5300 22510,5305 22513,5302 22514,5306 22510,5309 22513,5313 27513,5313 27513,5317 27513,5322 22513,5326 22517,6326 22516,6323 22518,6323 22523,6320 22523,6321 22526,6323 22531,6323 22531,6324 22532,6324 22532,6325 22529,6321 22531,6323 22534,6328 22534,6329 22530,6324 22527,10324 22522,10319 22524,10315 22520,10314 22525,10311 22525,10307 22526,10304 22531,10306 22527,10306 22528,10309 22530,10312 27530,10312 27534,10312 27534,10307 27536,10307 27532,11307 27531,11307 27533,11308 27535,11303 27531,11298 27532,11294 27534,11294 27534,11299 27538,11297 27542,11302 27547,11306 27547,11311 27549,11313 30549,11317 30551,11313 30546,11316 30541,11316 30540,11319 30545,11318 30546,11323 30550,11326 30554,11326 34554,11330 34558,11331 34558,11333 34558,11332 34561,11328 34561,11331 34562,11336 34562,11336 34567,11340 34570,11342 34569,11345 34568,11344 34569,11345 34571,11349 34574,15349 34574,15354 34569,15359 34566,15362 34571,15363 34576,15367 34577,15368 34577,15371 34581,15374 34576,15379 34574,15383 34579,15384 34584,15387 34583,17387 34578,17392 34578,17391 34578,17396 34573,17397 34578,17397 34580,17397 39580,17402 39584,17397 39587,17402 39587,17406 39582,17403 39587,17407 39589,17409 39592,17406 39592,17409 39595,17409 39599,17412 39603,17416 39608,17417 39608,17417 39608,17421 39607,17422 39609,17424 39608,17427 39604,17425 39605,17426 39609,17423 39611,17422 39610,17425 39613,17428 39618,17428 39619,17429 39616,17432 39616,13432 39615,13432 39617,13432 39617,13432 44617,13434 44621,13434 44623,13439 44627,13442 44632,13442 44635,13440 44631,13442 44631,13445 44635,13447 44639,13445 44637,13445 44638,13450 44639,13454 44644,13457 44644,13459 44642,15459 44639,15457 44644,15461 44644,15462 44642,15459 44645,15459 44647,15463 44650,15458 44651,15459 44653,15461 44657,15463 44661,15463 44661,15463 44663,15467 44666,15472 44668,15474 44664,15470 44668,15471 44670,15473 44674,15475 44675,-3806 12298,-3804 12301,-3805 13301,-3804 13296,-3808 13292,-3809 13295,-3806 13300,-3804 13297,-3801 13301,-3801 13302,-3796 18302,-3801 18306,-3799 18311,-3802 18311,-3799 18312,-3801 18314,-3796 18319,-3795 18322,-3791 18321,-3786 18320,-3786 18321,-3784 18321,-3782 18321,-3781 18324,-3782 18325,-3783 18320,-3788 18324,-1788 18324,-1788 18329,-1784 18333,-1784 18334,-1781 18329,-1777 18334,-6777 18337,-6774 18339,-6776 18341,-6781 18341,-6779 18341,-6779 18343,-6779 18339,-6777 18343,-6782 18338,-6779 18341,-6778 18341,-6776 18336,-6776 18333,-6776 18333,-6780 18338,-6784 18338,-6787 18335,-6786 18336,-6781 22336,-6781 22335,-6778 22331,-6777 22326,-6777 22331,-6777 22335,-6772 22335,-6774 22340,-6769 22341,-6767 22337,-6767 22335,-6767 22335,-6767 22333,-6767 22336,-6762 22331,-6759 22331,-6764 22332,-6765 22334,-6767 22339,-6762 22334,-6760 22334,-6760 22334,-6758 22337,-6754 22341,-6754 22342,-6750 22339,-4750 22343,-4747 22343,-4752 22343,-4751 22344,-4749 22345,-4745 22348,-4740 22353,-4736 22358,-4738 22363,-4740 22358,21336 41527,21334 41527,21330 41526,21330 41526,21333 41529,21328 41529,21329 41530,21326 41532,21328 41532,21324 41537,21328 41532,21330 41535,21334 41532,21336 40532,21334 40536,21339 40534,21341 40534,21344 40534,21346 40532,21350 40532,21353 40535,21357 40539,21359 40542,21360 40546,21355 40546,21360 40547,21359 40550,21356 40551,21356 40550,21357 40550,21361 40554,21358 45554,21362 45556,21366 45553,21370 45557,21374 45556,21377 45553,22377 45549,22382 45549,22382 45552,22386 45557,22387 45557,22388 45553,22392 45557,24392 45561,22392 45558,22397 45561,22399 45558,22398 45561,22400 45564,22400 45569,22404 45573,22406 45577,22406 45581,22404 45581,22407 45582,22409 45579,22409 45575,22409 45579,22407 45579,22402 45582,22402 45582,22404 45587,22406 45587,22406 45589,22411 45589,22413 45590,22417 45591,22417 45592,22422 45587,22425 45583,22428 50583,22428 50585,22428 50585,22430 50588,22435 50590,22435 50585,22435 50590,22439 50595,22440 50590,22445 50587,22442 50584,22442 50586,22443 54586,22443 54590,22446 54595,22448 54597,22448 59597,22444 59593,22449 59596,22449 59599,22452 59600,22457 59600,22458 59605,22457 59602,22462 59603,22463 59604,22461 59605,22458 59602,22457 59601,22457 59601,22455 59605,25455 59606,25457 59611,25462 59613,25464 59614,25467 59617,25472 59612,25476 59613,25478 59610,25482 59615,25482 59616,25486 59612,25483 59614,25487 59619,25492 59623,25497 59625,146 2252,150 2249,150 2249,152 2254,157 2249,158 2253,157 2252,161 2255,159 3255,161 3258,161 3255,163 3255,168 3259,168 3259,172 3263,167 3267,172 3271,172 3272,172 3274,175 3278,179 3282,181 3283,184 3280,185 3282,187 3282,191 3284,192 3286,191 6286,193 6289,198 6285,195 6290,194 6289,195 6289,199 6293,200 6288,198 6290,202 6291,207 6296,212 6301,215 6301,216 6301,211 6304,212 6304,216 6309,216 6304,214 6308,213 6308,211 6305,212 6309,217 6314,220 6317,224 6322,222 6327,220 6323,41573 39712,41572 39709,41576 40709,41580 40714,41576 40717,36576 40717,36577 40719,36582 40716,36585 40721,36590 43721,36585 43721,36582 43724,36585 43729,36590 43731,36590 43730,15289 11307,15285 11312,15286 11315,15289 11315,15294 11315,15295 11316,15296 13316,38742 37646,38743 37650,38745 37655,38744 37658,38739 37659,38737 37662,38742 37662,38745 37657,38748 37662,38748 37662,38752 37667,38753 37667,38748 37669,38748 37668,38752 37673,38754 37674,38756 37676,38758 37674,38760 37679,38760 37675,38758 37675,38763 37675,38767 37674,38772 40674,38767 40679,38772 40683,38774 44683,38778 44686,38780 44690,38780 44690,38779 44695,38782 44700,38780 44695,38775 44696,38775 44696,38775 44696,38779 44699,38783 44696,38784 44696,38786 44692,38786 44692,38786 44696,38791 44698,38793 44699,38795 44703,38800 44708,38803 44708,38807 44709,38802 44706,38806 44708,38809 44709,36809 44709,36814 44704,36813 44705,36814 44705,36816 44709,36811 44712,36812 48712,36811 48717,36815 48721,36816 51721,36818 51717,36822 51720,40822 51715,40827 51712,40830 51716,40829 51719,40832 51723,40835 51724,40840 51721,40841 51721,40836 51725,40841 51730,40846 51734,40848 51738,40849 51740,40851 51743,40854 51745,40855 51746,40857 51750,40857 51746,40861 51748,40866 51751,40862 51750,40866 51750,40869 51752,40865 51752,40863 51755,40858 51757,40855 51753,40855 51758,40852 51758,40853 51760,40857 51761,40855 51757,40852 51760,40853 51761,40855 51762,40858 51757,40859 51756,40863 51757,40863 51759,40860 51764,40859 51764,40854 51768,40850 51765,40852 51767,40852 51767,40848 51772,40852 51776,40854 51778,40852 51778,43852 51778,43854 52778,43856 52781,43859 52781,43859 52776,37512 26536,37517 26531,37520 26535,37520 26540,37522 26544,37527 26544,37532 26549,37537 26544,37540 26549,37545 26544,37549 26547,37549 26550,37548 26551,37549 26553,37546 26553,37546 26553,37549 26556,37549 26559,37552 26559,37556 26564,37560 26559,37561 26561,37565 26565,41565 26565,41569 26568,41571 26573,41571 26573,41576 29573,41571 29573,41573 29576,41573 29578,46573 29578,46569 29582,45569 29583,45572 29583,45568 29583,45573 29581,45575 29578,45571 29581,45572 29584,45572 29585,45576 29585,45578 29588,45581 29591,45582 29593,45582 29598,45584 29597,45589 29600,45585 29605,45589 33605,45593 36605,45594 36607,45599 36609,45600 36604,45604 36604,45604 36608,45604 36607,45608 36610,50608 36613,50611 36609,50614 36609,50619 36605,50624 36605,50625 36606,50625 36605,50629 36606,50624 36608,50625 36610,50626 36610,50629 36608,50627 36610,50628 36614,50632 36618,46632 34618,46632 35618,46636 35622,46636 35617,46637 35620,46639 35619,46643 35620,46645 35625,46643 35630,46648 35635,46648 35640,46649 35643,46651 35647,46655 35650,46652 35655,46657 35656,46658 35657,46662 35660,46659 35663,46662 35664,46665 35663,46667 35667,46667 35663,46670 35666,46672 35671,46674 35671,47674 35668,47676 35672,47677 35673,47677 35678,47677 35677,47677 35677,47677 35682,47672 35683,47671 35683,49671 35685,49674 35689,49677 35692,49675 35692,54675 35697,54678 35699,54674 35699,54670 35701,54670 35700,54675 35703,54676 34703,54676 34703,54679 34706,54683 34708,54688 34706,54688 34707,54685 34702,54687 34702,54692 34707,54687 36707,54687 36706,54682 36707,54685 38707,54680 38710,54680 38714,54677 38714,54679 38719,54682 38720,54687 38716,54688 38717,54692 38722,54697 38726,54699 38727,54700 38724,54702 38720,52702 38719,52702 38719,52702 38721,52702 38725,52704 38726,52706 38728,52707 38729,52711 38728,52711 35728,52713 35733,52712 35737,52712 35739,52713 35742,52713 35745,52708 35745,52710 39745,52713 39749,52716 39748,52721 39749,52720 39753,52716 39756,52716 40756,47716 40757,47717 40761,47722 40761,47722 40761,47722 40766,47726 40769,47728 40772,47733 40777,47731 40773,50731 40777,51731 40779,51733 40782,51734 40786,51737 40784,51741 41784,51739 41783,51739 41785,51739 41785,51736 41789,51731 41789,52731 41790,52735 41791,52738 41790,52742 41789,52746 41785,52747 41785,52745 41785,52750 41782,52753 41786,52753 41787,52758 41792,52754 42792,52749 42793,52752 42794,52756 42791,52757 42790,52762 42793,52766 42797,52766 42797,52769 42802,52774 42806,52774 42805,52771 42807,52774 42807,52770 42808,52771 42811,52767 42811,52766 42812,52767 42817,52771 42817,52771 42817,52775 42815,52779 42811,52779 42812,52780 42815,52776 42818,52774 42818,52777 42822,52780 42823,52781 42827,52776 42829,52780 42832,54780 42835,54780 42840,2135 11201,2140 11203,2137 11204,2140 11209,2142 11213,2147 11211,2145 11213,2145 11213,2150 11218,2150 11221,2153 11225,2157 13225,2162 13228,2167 13231,2171 13232,2167 13229,2168 13233,2171 13237,2173 13239,2168 13234,2168 13235,2173 13235,2175 13234,2177 13235,2177 13234,2179 13229,2179 13226,2180 13226,2177 13226,2177 13231,2180 13231,2181 10231,2176 10233,2177 10232,2180 10235,2185 10237,2182 10240,6182 10240,6184 10244,6182 10242,6183 10243,6185 10246,6190 10244,6194 10244,6194 10247,6192 10247,6192 10252,6195 10256,6194 10260,6195 9260,6195 9260,6195 9264,6199 9269,6204 9272,6199 9268,6201 9268,6203 9265,6208 9268,6204 9270,6204 9275,6201 9279,6201 9281,6201 9286,6206 9281,6206 9277,6202 9281,6200 9285,6202 9288,6198 9290,7198 9293,7200 9297,7201 9297,7205 9298,7209 9298,7209 9299,8209 9302,8214 10302,8218 10306,8222 10308,8226 10313,8231 10313,8235 10318,8237 10318,8237 10323,8233 10326,8233 10327,8237 10325,8238 10328,8238 10330,8234 10330,11234 10332,11236 10333,11241 10337,14241 10338,14240 10338,14237 10339,14238 10337,14237 10339,14242 10339,14246 10339,14250 10339,14250 10339,14251 10337,14254 10337,14256 10334,14256 10332,14252 10336,14255 10340,14259 10342,14262 10347,11148 3159,11153 3163,11154 3162,11154 3165,11158 3167,11161 3172,11162 3175,11162 3176,11166 3179,11166 3181,11171 3185,11176 3180,11178 3179,11176 3181,11179 3183,11174 3182,52776 42818,52778 42822,52777 42822,52782 42817,52783 42822,52784 42823,52789 42826,52789 42823,56789 42828,56786 42829,56786 42832,56789 42836,56789 42835,56785 42838,56786 42843,51786 42844,51788 42846,51790 42847,51794 42842,51796 42842,51801 42846,53801 42849,53806 42849,53809 42852,53812 42850,53817 42846,53817 42848,53818 42853,53822 42856,53823 42854,53826 42858,53825 42860,53826 42860,53826 42864,53830 42868,53835 42873,53839 42873,53841 42872,53841 42876,53841 42879,53841 42884,53836 42888,53836 42889,53836 44889,53833 44889,53835 44893,53838 44897,53842 44897,53844 44900,53844 44904,53845 44905,53850 44903,53853 44904,53858 44906,53856 44907,53861 44909,53856 44913,53858 44916,53863 44916,53868 44918,53867 43918,53869 43921,53869 43919,53867 43919,53862 43918,53860 43923,53864 43928,53869 43930,53874 43933,53874 43932,53874 43932,53875 43930,53877 43928,53878 43924,53883 43927,55883 43929,55883 43925,55879 43929,55881 43929,55884 43928,55881 43928,55882 43929,55883 45929,55883 45933,55883 45936,55884 45941,55884 45941,55886 45946,55882 45948,55883 45952,55888 45956,55890 45957,55894 45953,55892 45954,55897 45950,55893 45954,55896 45956,55892 45955,55897 45959,55899 45961,55899 45961,55894 45962,55898 45957,55893 49957,55896 47957,55894 47956,55898 47960,55901 47964,55901 47967,55901 47970,55896 47973,55898 47969,55894 47974,55895 47975,55891 47976,55896 47979,55899 47984,55902 47983,55897 47987,55899 47989,55904 47992,55904 47993,55905 47997,55902 48001,55902 48003,55907 48000,55910 47998,55915 47999,55911 47994,55906 47998,55910 48003,55914 48000,55918 48000,55914 48000,55919 48000,55921 48003,55921 48007,55924 48007,55919 48010,55922 48005,55927 48009,55928 48008,55928 48008,55930 48012,55925 48012,55925 48016,54925 48014,54922 48018,54922 44018,54926 44013,54929 44012,54932 44016,55932 44017,55935 44017,55936 44020,55937 44022,55936 44020,55939 44015,55944 44018,55945 44022,55947 44023,55950 44024,55953 44020,55956 44023,53867 43919,53871 43921,52871 43921,53871 43923,53876 43923,53881 43923,53880 43927,53882 43931,53886 43936,53884 43937,53879 43934,53879 43937,53877 43939,53878 43938,53879 43942,53880 43947,53881 43948,53884 45948,53884 45949,53882 45953,53883 45954,53878 45956,53880 45953,53885 45958,53885 45958,53886 45957,53886 48957,53886 48962,53891 48962,53892 48964,53897 48965,49897 48962,49902 48965,49906 48967,49902 48967,49904 48971,49901 48967,49904 48970,54904 48971,54904 48971,54904 48975,54909 48979,54907 48975,54910 48975,54906 48971,54909 48973,54911 48975,54915 48978,54920 48978,54923 48981,54918 48984,54921 48984,56921 48984,56926 48986,56924 48981,56929 48980,56932 48979,56932 48977,56936 48979,56937 48981,56937 48982,61937 48984,61937 48980,61934 51980,61935 51981,61935 51984,61935 51984,61931 51986,5329 23395,5331 23395,5333 23390,5337 23392,5340 23395,5345 27395,5345 27397,5350 27398,5355 27399,5356 27402,6356 27405,6360 27407,6361 27406,6364 27402,6366 26402,6371 26402,6371 26402,6372 26405,6370 26405,6375 26406,6380 26411,6385 26413,6387 26414,6388 26419,6390 26419,6391 26424,6393 30424,6390 30429,6390 30432,6390 30430,6394 30434,6394 30437,6394 30441,6396 30442,6398 30439,6399 30436,6404 30435,6405 30435,6400 30435,6405 30440,6404 30443,6405 30447,6409 30447,6411 30447,6412 30448,6417 30446,6421 30450,6418 30448,6417 30444,6418 30449,6420 30451,6425 30456,6426 30456,6425 30458,6426 30458,6426 34458,6427 34459,6432 39459,6434 39462,6434 39467,6439 39470,6443 39467,6444 39468,6449 39473,6451 39476,6452 39481,6452 39479,6452 39476,8452 39476,8456 39478,8460 39480,10460 39482,10455 39482,10456 39484,10460 39484,10463 39484,10468 39486,10473 39482,10475 39484,10475 39486,10476 39488,10477 39492,10475 39494,10480 39499,10476 39501,10479 39506,10480 39510,10475 39508,10480 39513,10481 39516,10481 39516,10485 39521,10487 39522,10490 39523,10490 39520,10493 39520,10496 44520,10491 44519,10491 44524,10492 44520,10497 44525,10499 44525,10502 44527,10500 44531,10502 44535,10506 44535,10511 44532,13511 44536,13513 44533,13510 44535,13507 44540,13511 44543,13515 44548,13517 44549,13522 44550,13525 42550,13520 42551,13522 42553,13525 42552,13529 42557,13529 42558,13524 42559,13525 42559,13525 42562,13520 42564,13523 42567,15523 42569,15523 42572,15524 42577,15529 42577,15530 42582,15532 42584,15532 42588,15531 42587,15531 42592,15530 42587,15530 42583,15533 42583,15536 47583,15532 47583,15535 47587,15534 47590,15536 47594,11536 47590,11533 47590,11529 47590,11533 47592,11533 47592,11533 47593,11537 47598,11538 47603,11538 47603,11538 47605,11541 47609,11544 47613,14544 47614,14539 47610,14537 47610,14537 47614,14535 50614,14537 50619,14539 50619,14540 50623,14538 50623,14537 50619,25599 26540,25599 26541,25599 26544,25594 26542,25599 26543,25596 26544,25597 26543,25598 26543,25593 26544,25588 26542,25593 26545,25595 26544,25596 26544,25599 26541,25594 26544,25592 26549,25593 26548,25597 26549,25596 26550,25594 26551,25590 26550,25594 26554,25597 26550,25598 26552,25593 26555,25598 22555,25599 22557,25604 22559,25605 22558,25606 22562,25605 22559,25605 22564,30605 22569,30610 22571,30610 22575,30609 22575,30609 22576,30609 22581,30605 22581,30610 22583,30610 22584,30613 22579,30613 22581,30616 22577,30619 22577,30621 22580,30621 22585,30626 22590,30628 22593,30629 22598,30626 22603,30628 22606,30629 22607,30629 22604,30627 22606,30632 22608,30633 22608,30636 22612,30641 17612,30642 17614,30647 17614,30651 17615,30654 17610,30655 17607,30658 17611,30653 17610,30654 17606,30654 17607,30659 17606,30660 17611,30658 17616,30659 17616,30664 17619,30665 17621,30665 17620,30667 17621,30671 17624,30673 17624,30673 17624,30678 17627,30675 17632,30675 17635,30678 17640,30681 17643,30686 17639,30691 17641,30696 19641,30699 19640,30700 19640,30696 19645,30698 19643,30699 19645,30702 19646,30703 19649,30699 19651,30704 19648,30706 19652,30709 19653,30709 19655,30709 19655,30712 19657,30708 19658,30705 19660,30700 19662,30701 19663,30706 19664,30711 19663,30707 19667,30704 19670,30708 19672,30709 19673,30711 19673,30711 19674,30713 19678,30718 19682,30723 20682,30721 20686,30725 20691,30726 20693,30729 20695,30728 20690,30730 20692,30733 20694,30736 20692,30736 20691,30740 20694,30741 20695,30741 20697,30746 20700,30747 20702,30750 20701,30751 20698,30753 24698,30749 24701,30748 24703,30746 24704,30747 29704,30747 29705,30749 29707,30752 29712,30757 29712,30760 34712,30760 34716,30763 34716,30759 34713,30759 34717,30763 34717,30758 34717,30757 34721,30760 34726,30758 34726,30763 34727,30763 34727,30764 34727,30759 34729,30759 34732,30762 34734,30757 34735,30761 34736,30759 34736,30762 34738,30757 34733,30760 34735,30762 34737,30760 34736,30765 34733,32765 34737,32768 34737,32765 34740,32765 34742,32768 34747,32772 34751,32772 34752,32777 34749,32782 34751,32783 33751,32783 33746,36783 33749,36783 33754,36786 33756,36787 33755,36787 33758,36791 33754,36796 33754,36801 33756,36801 33758,36801 33762,36802 33765,36802 33765,36806 33770,33806 33772,33806 33777,33809 33777,33814 33780,33814 33785,33818 33782,33821 33784,33826 33781,33822 33781,33824 33783,33822 33784,33826 33787,33823 33792,33827 33795,33828 33798,33829 33799,33833 33801,33833 33801,33836 33805,33839 33809,33842 33805,33847 33810,33845 32810,33847 32808,33849 32812,33851 32815,33849 32818,33849 32822,33847 32822,33847 32826,33850 32831,33854 32836,33857 32833,33856 32828,33859 32829,33860 32832,33857 32834,33857 32830,33855 32830,33857 32830,33855 32834,33859 32829,33859 32833,33862 32836,33864 32837,33864 32839,33866 32837,33869 32835,33872 32840,33874 37840,33879 37845,33881 37850,33881 37855,33886 37856,33891 37860,33896 37860,33893 37863,33894 38863,33896 38859,28896 38864,28899 39864,33899 39869,33896 39871,33898 39875,33902 39873,33902 39875,33907 39879,33912 39884,33908 39887,33908 39888,33905 39890,33909 39895,33911 39896,33908 39900,33912 39901,33915 39902,33915 39902,33915 39902,33910 39907,33910 39904,33914 39903,33912 39906,33916 39909,33920 39909,33922 39912,33923 39916,33928 39916,33931 39918,33932 39919,33935 39915,33936 39912,33934 39909,35934 39914,35931 39915,35935 39917,35939 39920,35939 39915,35940 39911,35944 39916,35944 39911,35944 39908,35945 39904,35945 39908,35945 39912,35950 39915,35955 39917,38955 39916,38960 39921,38962 39920,38962 39920,38967 39922,38967 39924,38970 39928,38975 39928,38973 39928,38977 39931,38980 39934,38984 39936,38982 39939,38983 39942,38985 39943,38987 39945,38992 41945,38988 41950,38989 41954,38992 41958,38992 41962,38992 41965,38993 41970,38997 41970,38997 41970,38994 41974,38994 41979,38997 41979,38999 41982,38994 41980,38998 41985,38998 41984,5334 23406,5330 23406,5325 23403,9325 23404,12325 23408,12325 23408,12322 23406,13322 23411,13325 23416,13326 23412,13322 23414,13327 23419,13328 23422,13329 23425,13333 23422,13337 23424,23491 35549,23490 35544,23494 35546,23499 35548,23495 35549,21495 35553,21490 35556,21492 35558,21492 35556,21494 35559,21494 35564,21494 35566,21499 35566,21502 35562,21502 35567,17502 35568,17506 35573,17507 35574,17511 35578,17512 35583,17513 35588,18513 35591,18514 35592,18515 35594,18513 35596,16513 35601,16513 37601,16513 37602,16511 37604,16513 37609,16514 37611,16518 37616,16522 34616,16524 34613,16528 34615,16528 34620,16533 34624,16535 34627,16538 34628,16539 34630,16539 34631,16542 34628,16542 34633,16544 34638,16547 38638,16547 38640,16543 38645,16543 38640,16540 38640,16543 38640,16542 38641,16546 38646,16541 38649,16541 38645,18541 38648,18544 38648,18544 38653,18544 38656,18549 38651,18547 38651,18550 38656,18547 38658,23547 38663,23544 38664,23548 38668,23548 38670,28548 38672,28549 38669,28549 38673,28545 38669,28549 38670,28554 38670,28557 38674,28560 38669,28562 38674,28562 38669,28561 38669,28564 38671,28569 38671,38779 44699,38780 44695,38778 44698,38783 44700,38785 44700,38781 44701,38782 44696,38786 44691,38789 44692,38794 44692,38799 44688,38799 44693,38803 44697,38808 44697,38806 44697,38806 44700,38803 44702,38803 44706,38802 44707,38807 48707,38808 48707,38806 48707,38810 48712,38810 48709,38810 48711,38810 48711,38806 48707,38802 48710,38803 48706,38805 48711,38810 48711,38805 48709,38809 48710,38809 48710,38814 48707,38815 48703,38816 48703,38816 48704,38820 48704,38822 48709,38820 48710,38818 48714,38822 48716,38822 48719,38827 48722,38828 48727,38832 48725,38830 48730,38831 48726,38832 48724,38829 48728,8431 35532,8431 35537,4431 35532,4434 35537,4438 35537,4439 35533,4443 35535,4442 35530,4445 35527,4449 35527,4453 35530,4458 35530,4459 39530,4460 39531,4461 39531,4464 39531,4468 39531,4470 39534,4465 39534,4465 39532,4469 39532,4471 39537,4466 39538,4470 39539,4473 39540,4476 39540,4480 39543,4485 39548,4483 39546,4484 39547,4484 39549,4484 39551,4486 39553,4486 39554,4487 39551,4483 39553,4486 39554,4490 39556,4493 39557,4498 39561,4494 39562,-4749 22345,-4752 22345,-4748 22348,-4744 22351,-4740 22356,-4741 22358,-4739 22361,-4734 22359,-4730 25359,-4730 25360,-4725 25360,-4727 25360,-4727 25361,-6727 25360,-6729 25365,-6730 25365,-6727 25365,-6731 25364,-6730 27364,-6727 27366,-6723 27367,-3723 27363,-3719 27368,-3720 27371,-3718 27366,-3717 27369,-3716 27369,-3714 27372,-3711 27370,-3712 27371,-3712 27370,-3710 27375,-3708 27377,-3707 27382,-3706 27385,-3706 27389,-3705 32389,-3704 32392,-3704 32392,-3699 32391,-3699 32395,-3694 32399,-3694 32400,-3695 32404,-3695 32408,-3693 32410,-3693 32410,-3697 32410,-3692 32413,-3691 32418,-3686 32420,-3683 32425,-3681 32420,-3678 32424,-3673 32424,-3676 32427,-3673 32426,-3671 32426,-3676 33426,-3678 33428,-3676 33428,-3679 33428,-3679 33433,-3677 33434,-3676 33438,-3681 33440,1319 33444,1321 33441,1325 33444,1329 33439,1326 33444,1326 33439,1327 33439,1327 33440,1332 33444,1333 33449,1338 33453,1338 33450,1343 33450,1347 33454,1346 33457,1346 33455,1342 33459,1341 33462,1346 33462,1347 33463,1343 33463,1344 33462,1348 33457,1347 33460,1352 33464,1356 33468,1361 33469,1363 33468,1365 33469,1368 33472,1369 33475,-2631 33478,-2633 33483,-2629 33486,-2632 34486,-2628 36486,-2625 36488,-2621 36488,-2624 36488,-2622 36492,-2624 36491,-2629 36491,-2627 36496,-2623 36499,-2628 36502,-2631 36506,-2626 36506,-2622 36506,-2622 36509,-2619 36514,-2624 36512,-2621 36510,-2619 36510,-2619 36508,-2617 36512,-2615 36512,-2615 36513,-2615 36511,-2615 36506,-2612 36507,-2609 36511,-2606 37511,-2606 37508,-2610 37505,-2607 37508,-2602 37512,-2599 37512,-2595 37510,-2597 37511,-2592 37515,-2597 37514,-2592 37519,-2592 37524,-2592 37526,-2594 37521,-2594 37516,-2591 36516,-2588 36517,-2589 36513,-2586 36514,-2584 36514,-2583 36516,-2579 36514,-2578 36518,-2578 35518,-2575 35519,-2577 35519,-2578 35524,-2578 35529,-2578 35532,-2578 35534,-2580 35537,-2584 35541,-2586 35542,-2587 35544,-2585 35540,-2585 35544,-2584 35543,-2580 35548,-2576 35550,-2571 35553,-2567 35555,-2565 35560,-2560 35560,-2557 35564,-2553 35564,-5553 36564,-5548 36564,-5544 36565,-5547 36565,-5545 36570,-5542 36565,-5543 36566,-5543 36568,-5543 36570,-5540 36575,-5537 36577,-5535 36581,-5532 36580,-5528 36575,-5526 38575,-5526 38576,-5526 38571,-5522 38571,-5518 38576,-5514 42576,-5510 42581,-5512 42583,-5512 42582,-5507 42582,-5510 42585,-2510 42589,-2511 42592,-2508 42594,-2506 42597,-2503 42598,-2503 42603,-2498 42608,-2501 42611,-2500 42616,-2502 42613,-2502 42616,-4502 42616,-4502 42620,-4502 42622,-4506 42619,-4509 42621,-4511 42624,-4515 42625,-4510 42625,-4507 42628,-4502 42624,-4501 42629,-4505 45629,-4503 45630,-4499 45631,-4496 45630,-4497 45628,-4495 45630,-4494 46630,-4491 46634,-4487 46629,-4483 46631,21336 40532,21341 40533,21346 40534,21346 40536,21345 40536,21346 40536,21345 40536,21344 40538,21347 40543,21348 40543,21351 40540,21351 40542,21348 40545,21351 40546,21352 40546,21353 40546,21358 40546,21359 40545,21359 40550,21357 40555,21362 40560,21364 40555,21363 40555,21364 40560,25364 40564,25365 40566,25368 40566,25371 45566,25372 45567,25372 45562,25376 45564,25381 42564,25385 42560,25389 42564,25389 42568,25393 42572,25390 42572,28390 42569,28389 42570,28385 42574,28386 42576,28389 42577,31389 42578,31385 42582,31387 42582,31390 42578,31391 42579,31392 42576,29392 42580,29396 42582,29398 43582,29402 43584,29406 43585,29407 43587,29411 43592,29413 43594,29414 43595,25414 43600,25412 43595,25415 43599,25420 43602,25418 43604,25423 43599,25426 43599,25429 43602,25434 42602,25429 42604,25432 42600,25435 42605,25436 47605,25440 50605,25441 50610,25439 50614,25444 50617,25447 50621,25444 50624,25444 50626,25445 50627,25450 50632,25450 50628,25451 50630,25451 50632,25454 50633,25458 50637,25462 50641,25463 50640,25463 51640,25467 51644,25469 51649,25473 51650,25474 51653,25475 51654,26475 51658,26475 51662,26474 51665,26476 51665,26481 51661,26483 55661,26485 55664,30485 55667,30485 55670,30489 55671,30489 55668,30491 55670,30492 55670,30493 55675,30497 55675,30501 55671,30503 55676,30500 55677,30498 55672,30494 55675,30499 55676,30500 55676,30505 55681,30501 55684,30496 55685,30500 55685,30502 55687,30506 55692,30507 55693,30506 55692,30511 55693,30516 55694,30514 55699,30514 55701,30512 55701,34512 55705,34516 55708,34520 55704,34518 56704,34519 56704,34520 56706,34517 56706,34515 56701,34519 59701,34522 59706,34522 59708,34522 59713,34526 59715,34528 59717,34533 59712,34538 59715,34538 59717,34541 59717,34546 59720,34548 59721,34552 63721,34547 63726,34549 63728,34554 63726,34556 63726,34557 63721,34556 63725,34561 63730,34558 63730,37558 63725,37561 63729,37565 63724,37569 63720,37573 63718,37578 63722,37577 63718,37579 63720,37579 63722,37580 63719,37580 63720,37579 63724,37574 63725,37574 63727,37576 63725,37581 63729,37583 63732,37586 63732,37590 63737,37592 63734,37597 63731,37600 63730,37596 63731,37596 63733,37600 63733,37601 63735,37596 63735,37591 63732,37596 63733,37601 63738,37602 63733,37599 63738,37594 63740,37598 63744,37603 63745,37605 63747,37607 63752,37607 63756,37603 63757,37603 63761,37604 63761,37608 63758,37609 63762,37604 63764,37604 63764,41604 63765,41600 63761,41599 63761,41600 63766,41596 63766,41599 63766,41601 63770,41604 63768,41608 63768,41611 63772,41614 63767,41609 63763,41612 63765,41615 63760,38615 63764,38615 63768,38618 63768,35618 63769,35618 63774,35617 63775,35618 63776,35613 63775,35615 63780,35612 63782,35613 63779,35614 63775,35618 63774,35619 63776,35624 63778,35624 63780,35629 63785,35629 63780,35626 63781,35624 63782,35629 63784,35634 63787,35638 63782,35634 63783,35634 63778,35633 63777,35638 63782,35641 63786,35644 63791,35648 63793,35647 63793,35649 63797,35653 63801,35654 63804,35654 63804,35656 63804,35655 63806,35658 63810,35658 63805,35662 63805,35657 67805,35658 67808,35660 67811,35664 67808,35660 67803,35658 67803,35661 67803,35663 67808,35666 67810,35670 67814,35669 67813,35669 67816,37669 67820,37664 67820,2275 13363,2278 16363,2274 16363,2275 16362,2279 16362,2282 16362,2287 16366,2284 16366,4284 16366,4286 16371,4290 16375,4294 18375,4295 18377,9295 18381,9296 18381,9299 18382,9303 18379,9305 19379,9308 19375,8308 19380,8312 19380,38746 37651,38749 37652,38754 37653,38757 37656,38753 37661,38753 37661,38758 37663,38763 37664,38763 42664,38768 42666,38765 42668,38770 42664,38767 42659,38768 42659,38773 42654,38771 42659,38775 42661,41775 42663,41778 42665,41781 42669,41782 42667,41779 42669,41784 42672,41781 42672,41783 42672,41780 42672,41783 42675,41784 42675,41788 42676,41792 42677,41792 42675,41793 42680,41793 42676,41796 42681,41801 42685,41804 42684,41806 42685,41804 42690,41802 42692,41805 42696,41800 42697,41802 42698,41804 42700,41809 42704,41813 42705,36813 42708,36813 42704,36810 42703,36811 42705,40811 42706,40815 46706,40816 46708,40820 46708,40818 46712,40822 46717,40825 46720,40829 46724,40827 46727,40831 46727,40833 46731,40829 46733,40830 46733,36830 46738,36830 46741,36834 46744,36831 46749,36826 46748,36822 46748,36824 46751,36819 46755,36823 46758,36823 46762,36824 46766,36822 46769,36826 46772,36831 46774,36828 42774,36833 42776,36833 42777,36838 42782)')));
-INSERT INTO t1(g) VALUES (ST_linefromtext(concat('linestring','(20 110, 21 110, 26 115, 29 112, 34 108, 39 111, 44 111, 46 116, 46 120, 42 122, 45 118, 48 118, 44 122, 46 127, 47 127, 51 127, 55 123, 52 127, 52 128, 56 130, 60 129, 61 130, 66 131, 67 131, 71 135, 76 136, 77 139, 80 143, 2080 145, 2077 147, 2079 147, 2081 147, 2086 147, 2087 151, 2092 -1849, 2088 -1848, 2088 -1852, 2091 -1848, 2095 -1846, 2092 -1847, 2092 -1848, 2093 -1847, 2094 -1846, 2099 -1843, 2104 -1844, 2102 -1848, 2102 -1848, 7102 -1847, 7105 -1846, 7106 -1843, 7111 -1838, 67 131, 69 135, 68 135, 63 136, 63 137, 64 141, 67 1141, 2067 1139, 2063 1139, 2066 1139, 5066 1139, 5068 1139, 5072 1140, 5072 1145, 5073 1142, 5076 1145, 5077 1145, 5076 1141, 5078 1141, 5073 1143, 5068 1146, 5067 2146, 5070 2151, 5075 2155, 5071 2160, 5073 2161, 5074 2166, 5076 2169, 5071 2173, 5074 2173, 5078 2177, 5076 2173, 5080 2173, 5078 2174, 78 2179, 76 2183, 77 2188, 82 2192, 85 2194, 89 2193, 86 2197, 89 2193, 88 2194, 89 2199, 89 2204, 89 1204, 87 1206, 88 1203, 89 1204, 89 1205, 93 1210, 94 1208, 96 1208, 100 1210, 104 1212, 107 1215, 104 1220, 107 1224, 111 1228, 112 1228, 116 1229, 119 1228, 120 1233, 119 1236, 124 1241, 125 1240, 122 1239, 126 1241, 123 1240, 124 1244, 128 1248, 129 1250, 128 1253, 127 5253, 125 5255, 129 5255, 133 5255, 137 5260, 140 5261, 137 5261, 141 5261, 140 5262, 143 5264, 148 5264, 148 5264, 145 10264, 149 10269, 153 10274, 158 10270, 159 10273, 164 10277, 168 12277, 170 12278, 165 12274, 170 12279, 172 12281, 172 12281, -3828 12281, -3823 12281, -3822 12282, -3823 12280, -3823 12282, -3820 12281, -3823 12279, -3827 12282, -3826 12279, -3822 12284, -3825 12284, -3824 12286, -3820 12287, -3820 12290, -3818 12292, -3816 12293, -3814 12298, -3815 12301, -3817 12304, -3814 12301, -3811 12299, -3809 12303, -3809 12301, -3804 12302, -3804 12302, -3802 12305, -3799 12310, -3801 17310, -3801 17310, -3796 17310, -3801 17314, -3799 17318, -3796 17321, -3795 17321, -795 17325, -795 17327, -794 17329, -791 17330, -790 17326, -787 17331, -782 17335, -778 17339, -774 17343, -772 17343, -769 17346, -768 17349, -763 17352, -763 17353, -761 17357, -758 17354, -758 22354, -754 22350, -750 22353, -746 22356, -750 22352, -746 22351, -744 22349, -743 27349, -741 27350, 259 27354, 262 27353, 263 27356, 268 27352, 268 22352, 271 22351, 273 22351, 274 22351, 275 22352, 275 22356, 280 22352, 281 22348, 284 22349, 284 22346, 285 22351, 285 22351, 290 22353, 294 22351, 294 22352, 295 22352, 300 22352, 305 22355, 308 22356, 311 22356, 310 22358, 312 22360, 313 22365, 313 22362, 313 22364, 313 22364, 317 22360, 322 22362, 327 22367, 328 22370, 323 22375, 320 22377, 320 22379, 316 22379, 318 22379, 323 22380, 323 22380, 324 22376, 34 108, 38 113, 42 118, 42 117, 42 121, 46 123, 51 127, 51 130, 51 133, 55 137, 52 141, 52 143, 51 141, 50 142, 45 142, 44 143, 48 146, 48 142, 43 143, 47 145, 4047 5145, 4047 5150, 4044 5151, 4045 10151, 4043 10154, 4044 10156, 4047 10156, 4043 10160, 4043 10156, 4043 10156, 4048 10157, 4051 10160, 4048 10159, 4053 10161, 4057 10163, 4057 10164, 4058 10165, 4057 10170, 4056 10173, 4056 10176, 4056 15176, 4053 15180, 4049 15181, 4051 15178, 4049 15180, 4049 15180, 4048 15181, 4048 15184, 4045 15188, 4045 15191, 4040 15194, 4042 15198, 4042 15203, 4047 15200, 4049 15201, 4052 15204, 4052 15208, 4052 15212, 4049 15216, 4049 15219, 4051 15220, 4048 15222, 4044 15227, 4044 15232, 4044 15236, 4049 15239, 4052 15240, 4052 15243, 4053 15247, 4055 15247, 4052 17247, 4054 17247, 4054 18247, 4059 18251, 4063 18253, 4066 18253, 4069 20253, 4069 20254, 4069 20259, 4068 20263, 4068 20263, 4069 20259, 4071 20260, 4073 20262, 4074 20258, 4069 20261, 4069 20264, 4071 20269, 4067 20271, 4071 20270, 4072 20271, 4073 20268, 4076 20263, 4072 20268, 4075 20264, 4076 20267, 4079 20272, 4084 20275, 4086 20277, 4086 20281, 4083 18281, 4087 18283, 4088 18280, 4089 18277, 4089 18279, 4094 18281, 4095 18283, 4095 18284, 4097 18284, 4093 18287, 4094 18285, 4096 18287, 4092 18291, 4096 18291, 140 5261, 140 5259, 140 5262, -1860 5258, -1858 5260, -1854 5262, -1849 5259, -1848 5264, -1845 5264, -1845 5267, -1845 5262, -1848 5261, -1848 5263, -1849 5261, -1853 5262, -1851 5265, -1847 5265, -1847 5262, -1847 5263, -1843 5268, -1845 5268, -1848 5272, -1850 5270, -1851 5274, -1854 5269, -1850 5266, -1845 5267, -1840 5267, -1840 5264, -1840 5269, -1839 5269, -1842 5269, -1840 5274, -1835 5278, -1836 5283, -1841 5279, -1840 5284, -1836 5285, -1836 5289, -1831 5289, -1826 5292, -1822 5293, -1826 5295, -1829 5295, -1824 5295, -1828 5297, -1824 5300, -1820 5305, -1824 5306, -1824 5306, -1824 5306, -1823 5301, -1818 5303, -1814 5307, -1814 5303, -3809 12303, -3807 12306, -3804 12306, -3804 12306, -3801 12308, -3796 12308, -3795 12308, -3791 12310, -3786 12310, -3781 12313, -3814 12298, -3809 12303, -3807 12301, 7102 -1847, 7100 -1850, 7104 -1850, 7109 -1852, 7109 -1854, 7112 -1850, 7112 -1847, 7115 -1847, 7117 -1847, 7122 -1847, 7125 -1843, 7126 -1848, 7127 -1848, 7129 -1848, 7133 -1848, 7131 1152, 7131 1149, 7135 1154, 7139 1152, 7140 1151, 7145 1153, 7149 1158, 8149 1159, 8154 3159, 8149 3161, 8145 3162, 8146 3164, 8146 3168, 11146 3171, 11148 3171, 11150 3167, 11154 3165, 11150 3163, 11151 3167, 11152 3165, 11153 3170, 11156 3175, 11156 3174, 8146 3164, 8146 3167, 8146 3170, 8147 3170, 8148 3175, 8148 3178, 8146 3178, 8146 3178, 8147 3180, 8143 3184, 3143 3186, 7143 3187, 7143 7187, 7138 7189, 7138 7189, 7135 7191, 7138 7191, 7133 7194, 7138 7198, 7139 7201, 7143 7200, 7141 7203, 12141 7204, 12145 7204, 12145 7203, 12146 7207, 12147 7204, 12143 7204, 12138 7199, 12138 7195, 12139 7195, 12139 7200, 12141 7201, 12142 7201, 12139 7205, 12142 7208, 12142 7213, 12145 7213, 12147 7214, 12149 7218, 12150 9218, 12154 9222, 12151 9222, 12151 9225, 12151 9224, 12152 9226, 12155 10226, 12155 10230, 12158 10231, 12161 10227, 12162 10224, 12163 10229, 12163 10231, 12165 10228, 12165 10227, 12160 10228, 12160 10231, 12160 10235, 12157 12235, 12159 12230, 7138 7189, 7141 7193, 7141 7193, 7141 7192, 7139 7195, 7141 7195, 7142 7193, 7145 7195, 7146 7193, 7146 7194, 7151 7197, 7154 7198, 7156 7202, 7155 7207, 7150 7211, 12150 7213, 12148 7213, 12147 7217, 12142 7221, 12141 7223, 12143 7223, 12140 7222, 12145 7222, 13145 7224, 13142 7228, 13144 7232, 13139 7235, 13144 7239, 13148 7243, 13151 7247, 13150 7251, 13152 7252, 13157 7253, 13157 7257, 13157 7257, 13157 7262, 13159 7264, 13164 7259, 13161 7259, 13165 7262, 13166 7262, 13166 7267, 13169 7268, 13169 8268, 13167 8269, 13171 8269, 13173 13269, 13177 13265, 13178 13263, 13178 13263, 13182 13266, 13183 13266, 13185 13266, 13190 13269, 13193 13271, 13193 13269, 13196 13271, 13193 13273, 13194 13268, 13198 13273, 13200 13276, 13202 13276, 13204 13274, 13209 11274, 13213 11274, 13213 11277, 13215 11278, 13219 11279, 13224 11280, 13224 11276, 13228 11278, 13233 11281, 13235 11286, 13238 11288, 13240 11288, 13238 11290, 13238 11292, 13238 11287, 13238 11288, 13240 11293, 13243 11296, 13246 11296, 13247 11293, 13243 11298, 13246 11302, 13251 11305, 322 22362, 326 24362, 330 24362, 329 24367, 328 24363, 329 24365, 331 24369, 336 24371, -664 24371, -668 24372, 51 127, 48 131, 48 133, 51 135, 51 140, 49 139, 47 142, 3047 139, 3044 142, 3046 143, 3046 148, 3051 148, 3055 146, 3057 141, 3060 140, 3055 143, 3050 146, 7050 142, 7050 3142, 7050 3143, 7050 3144, 7052 3149, 7055 1149, 7052 1150, 7055 5150, 7050 5154, 7049 5150, 10049 5151, 10045 5151, 10049 5151, 10052 5156, 10054 5159, 10056 5160, 10058 5161, 10058 5163, 10060 5166, 10064 5168, 10064 5173, 10068 9173, 10070 9172, 10065 9168, 10065 9173, 10063 9175, 14063 9176, 14063 9178, 284 22346, 289 22351, 290 22351, 290 22347, 287 22343, 282 22342, 280 22345, 281 25345, 286 25347, 13243 11298, 13248 11300, 13245 11300, 13246 11295, 13247 11295, 13246 11295, 13248 11299, 13253 11304, 13255 11309, 13255 11310, 13260 11309, 13257 11310, 13258 11313, 13258 11315, 13263 11311, 13267 11307, 13269 11309, 13272 11305, 13277 11302, 13273 11304, 15273 11306, 15278 11310, 15281 11307, 15286 11309, 15288 11309, 15291 11311, 15292 11306, 15294 11309, 15298 11313, 15299 11317, 15300 11320, 15302 11321, 15306 11324, 15308 11328, 15308 11324, 15309 11324, 15314 11324, 15315 11323, 15319 11321, 15317 11325, 15319 11327, 15319 11332, 15321 11337, 15324 11340, 15324 11341, 15324 11341, 15326 11345, 15326 11349, 15327 14349, 15330 13349, 17330 13350, 17335 13353, 17339 13358, 17340 13362, 17344 13362, 17348 13357, 17350 13357, 17347 13357, 17350 13358, 17349 13358, 17349 13358, 17349 13359, 22349 13362, 22351 13359, 22353 13359, 22358 13358, 22360 13358, 22363 13359, 22364 13359, 22360 13359, 22361 13363, 22366 13368, 22371 13373, 22374 13377, 22378 13375, 22379 13375, 22379 13373, 22383 13378, 22388 13383, 22389 13380, 22389 13384, 22394 13382, 22392 13378, 22394 13382, 22393 13382, 22393 13379, 22394 13382, 22392 13384, 22395 13386, 22400 13391, 22400 10391, 22404 10395, 22401 10396, 22402 10396, 22402 10398, 22406 10395, 22405 15395, 22407 15396, 22409 15396, 22414 15391, 22414 15394, 22414 15398, 22410 15400, 26410 15402, 26409 20402, 26413 20406, 26417 20410, 26419 20415, 26422 20411, 26424 20411, 31424 16411, 31423 16409, 31423 16414, 31425 16414, 31428 16418, 31428 16414, 31432 16419, 31432 16422, 31437 16423, 31439 16424, 31440 16426, 31440 16429, 31440 16429, 31443 16431, 31441 16435, 31443 16440, 36443 16440, 36445 18440, 36444 18441, 36442 18444, 36442 18440, 36442 18444, 36444 18449, 36445 18450, 36449 18455, 37449 23455, 37454 23460, 37458 23459, 37460 23463, 37458 23465, 37460 23467, 37462 23470, 37466 23473, 37462 23478, 37464 23480, 37463 26480, 37468 26483, 37472 26487, 37473 26492, 37476 26493, 37476 26489, 37476 26487, 37476 26492, 37472 26496, 37476 26501, 37476 26503, 37480 26499, 37485 26503, 37485 26505, 37490 26500, 37493 26503, 37497 26499, 37502 26500, 37502 26501, 37502 26505, 37499 26503, 37499 26503, 37497 26508, 37500 26508, 37496 26513, 37499 26518, 37497 26519, 37500 26518, 37505 26518, 37510 26516, 37512 26520, 37513 26523, 37511 26527, 37508 26532, 37509 26536, 37514 26540, 37515 26542, 37512 26546, 37514 26548, 37519 26547, 37524 26550, 37529 26555, 37527 26559, 37531 26562, 37526 26567, 37526 26566, 37529 26566, 37524 26566, 37524 26563, 37528 26565, 37524 26563, 37525 26565, 37525 26560, 37526 26562, 40526 26564, 40526 26567, 40523 26571, 40527 26570, 40529 26572, 40534 26576, 40536 26573, 40535 26569, 40533 26569, 40537 26573, 40537 26574, 40541 26576, 40546 26579, 40545 26579, 40546 26583, 40550 26588, 40551 26585, 40555 26589, 40558 26594, 40554 22594, 40559 22598, 40558 22599, 40563 22596, 40563 22597, 40567 22597, 40570 22597, 40575 22592, 40572 22594, 40572 22595, 40572 22592, 40575 22594, 40575 22597, 40570 22597, 40569 22601, 40569 22603, 40573 22603, 40576 22604, 40576 22608, 42576 22611, 42579 22611, 42579 22616, 42581 22620, 38581 22623, 38582 22621, 38582 22618, 38577 22623, 38581 22623, 38581 18623, 38584 18618, 38584 18621, 38588 18626, 38592 18629, 38592 18626, 38596 18625, 38598 18620, 38599 18618, 38599 18622, 38602 21622, 38603 21622, 38607 21624, 38609 25624, 38613 25624, 38610 25621, 38610 25625, 38610 25629, 38613 25627, 38617 25627, 38617 25624, 38618 25626, 38621 25628, 38622 25629, 38622 26629, 38625 26631, 38625 26631, 313 22362, 313 22363, -1687 22364, 2313 27364, 2314 27364, 2314 27364, 2319 27366, 2319 27366, 2321 27363, 2321 27368, 2320 27363, 2323 27368, 2328 27371, 2327 27375, 2328 27377, 2328 27377, 2327 27381, 2331 27381, 2329 27381, 2332 27383, 2335 27383, 2333 27383, 2333 27385, 2338 27385, 6338 27386, 6338 27387, 40529 26572, 40533 26576, 40535 26578, 40540 26580, 40535 26584, 40540 26589, 40541 26592, 40538 26587, 40542 26591, 40541 26592, 40537 26597, 40542 26598, 40546 26601, 40550 26606, 40550 26605, 40551 26606, 40549 26606, 40550 26607, 40555 26610, 40550 26610, 40550 26607, 40553 26612, 40558 26616, 40561 26620, 40556 26623, 40558 26623, 40558 26627, 42558 26627, 42558 26628, 42562 26628, 42564 26630, 42565 26634, 42566 26634, 42566 26638, 42561 26639, 42564 26639, 42567 26641, 42564 26642, 42566 26646, 42566 26645, 42570 26645, 42574 26645, 42574 29645, 42576 29646, 39576 29645, 39576 34645, 39578 34647, 39583 34642, 39580 34642, 39576 34646, 39576 34649, 39574 35649, 34574 35652, 34579 35655, 39579 35659, 43579 35663, 43582 35659, 43577 35662, 43580 35662, 43583 35666, 43579 39666, 43574 39662, 43574 39665, 43574 39668, 43574 39670, 43578 39674, 43579 39671, 43582 39675, 43578 39677, 43575 39677, 43576 39681, 43571 39683, 43569 39683, 43570 39687, 43565 39690, 43568 39694, 43568 39696, 43570 39698, 43570 39699, 41570 39695, 41572 39696, 41573 39696, 41573 39697, 41573 39702, 41573 39702, 41576 39702, 41571 39702, 41572 39703, 41572 39708, 41574 39713, 41575 39716, 41580 39717, 41581 39721, 41586 39723, 41587 39724, -1848 5272, -1843 5272, -1845 5270, -1840 5272, -1838 5267, -1843 5268, -1841 5268, -1837 8268, -1837 8271, -1837 8276, -1836 8280, -1832 8277, -1832 8277, -1831 8278, -1835 8283, -1834 8287, -1832 8290, -1834 8286, -1832 8283, -1833 8283, -1832 8284, -1834 8287, -1839 8292, -1844 8293, -1841 8290, -1836 8290, -1839 8289, -1836 8289, -1832 8292, -1827 8295, -1823 8290, -1823 8293, -1823 8291, -1822 8295, -1820 8298, -1819 8302, -1816 8304, -1816 8300, -1812 8300, -1809 8299, -1806 8296, 1194 8300, 1194 8301, 1197 11301, 1194 11305, 1197 11309, 1199 11304, 1195 11304, 1195 11300, 1195 11297, 1196 11298, 1201 11296, 1206 11296, 1207 11298, 1212 11296, 1210 11292, 1206 11294, 1207 11293, 1209 8293, 1204 8288, 1206 8286, 1206 8285, 1208 8285, 1210 8285, 1214 8287, 1214 13287, 1215 13291, 1215 13294, 1218 13297, 1216 13293, 1219 13290, 1214 13295, 1210 13292, 1210 13296, 1211 13301, 1210 13300, 1206 13302, 1207 13307, 1211 13312, 1206 13312, 1211 13308, 1212 13308, 1216 13313, 1216 13318, 1217 13318, 1221 13318, 1221 13323, 1226 13324, 1231 13325, 1234 13329, 1235 13333, 1233 13333, 1236 13338, -2764 13340, -2767 13341, -2763 13344, -2760 13349, -2758 13346, 2242 13346, 2240 13346, 2244 13346, 2248 13349, 2248 13350, 2246 13352, 2241 13352, 2242 13355, 2242 13356, 2247 13361, 2250 13361, 2245 13366, 2249 13366, 2250 13366, 2254 13367, 2258 13367, 2258 13367, 2262 13371, 2257 13376, 2253 13373, 2253 13373, 2254 13376, 2251 13380, 2256 13382, 2257 13386, 2261 13383, 2264 13383, 2269 13385, 2264 13385, 2264 13387, 2267 13387, 2271 13389, 2272 13390, 2273 13393, 2269 13395, 2273 13390, 2277 13395, 2275 13396, 2277 13391, 2279 13394, 2276 13394, 2277 13398, 2282 13399, 2282 11399, 2283 14399, 2281 14404, 2279 14407, 2275 14410, 2276 16410, 2276 16414, 2281 16414, 2286 16415, 2282 16413, 2282 16413, 2284 16413, 2284 16415, 2284 16416, 2282 16417, 3282 16422, 3286 16422, 3287 16427, 3291 16427, 3294 16431, 3296 16433, 3298 16435, 3299 16440, 3300 16439, 3305 16439, 3307 16438, 3307 16440, 3307 16440, 3311 16441, 3311 16442, 3310 16443, 3310 16443, 3308 16448, 3304 16445, -1696 16441, -1701 16442, -1697 16442, -1695 16442, -1696 16443, -1693 16440, -1688 16445, -1685 16450, -1681 16454, -1680 16455, -1682 16457, -1680 16461, -1680 16461, -1684 16464, -1679 16463, -1678 16460, -1675 16464, -1679 16465, -1677 16468, -1672 16469, -1671 16473, -1667 16475, -1667 16480, -1663 16478, -1663 16482, -1662 16482, -1662 16483, -1659 16478, -1654 16475, -1653 11475, -1658 11477, -1661 11479, -1664 11484, 3336 15484, 3340 15480, 3344 15475, 3347 15475, 3347 15474, 3352 15473, 3349 15478, 3353 15480, 3354 15477, 3355 15480, 3352 15481, 3352 15483, 3353 15486, 3354 15488, 3353 15491, 3355 15491, 3360 15491, 3355 15490, 1219 13290, 1224 13295, 1224 13295, 1227 13290, 1231 13290, 1233 13285, 1237 13284, 1238 13285, 1243 13286, 1247 13289, 1249 13289, 1249 13291, 1252 13291, 1249 13294, 1249 13299, 1249 13302, 1254 13305, 1251 13308, 1254 13308, 3254 13308, 3249 13308, 3251 13312, 3256 13312, 3259 13312, 3263 17312, 3263 17313, 3263 17310, 3261 17309, 3264 17314, 3265 17312, 3264 17315, 3261 17318, 3261 17318, 3259 17313, 3256 17313, 3255 17313, 3257 17314, 3255 17316, 3257 17316, 3257 17316, 3258 17311, 3259 17311, 3258 17315, 3258 17317, 3257 17321, 3253 17321, 3250 17325, 3255 17329, 3258 17330, 3260 17328, 3260 17331, 3265 17326, 7265 17329, 7267 17332, 7265 17334, 7267 17337, 7272 17337, 7275 17337, 7280 17340, 4280 21340, 4280 21344, 4281 21344, 4283 21344, 4288 24344, 4292 24347, 9292 24351, 9296 24353, 9298 24351, 9300 25351, 9303 25352, 9303 25352, 9306 25357, 9305 25361, 9305 25356, 11305 25359, 11306 25362, 11309 25362, 11314 25362, 11314 25365, 11312 25369, 11315 25369, 11316 25373, 11321 25375, 11323 25375, 11327 25370, 11331 25369, 11332 25370, 11331 25374, 11332 25369, 11336 25371, 11340 25370, 11345 25367, 11350 25363, 11347 25360, 11350 25361, 11351 25362, 11351 25362, 11354 25364, 11358 30364, 11362 30369, 11362 30369, 11364 30369, 11369 30371, 11370 30373, 15370 30374, 15375 30375, 15378 30377, 14378 30382, 14379 30387, 14383 30382, 14388 30384, 14390 30386, 14393 30389, 14395 31389, 16395 31393, 16398 31398, 16398 31401, 16394 31404, 16397 31409, 16400 31413, 16400 31417, 16399 31419, 16398 31421, 16403 31422, 16403 31426, 16404 31423, 16409 31424, 16413 31423, 16408 31427, 18408 31431, 18413 31436, 18417 28436, 18419 28441, 18420 28445, 18416 28442, 18419 28439, 18418 28443, 18422 28446, 18425 28451, 18429 28448, 21429 28449, 21430 28454, 22430 28459, 22434 28461, 22438 28462, 22443 28462, 22447 28467, 22450 28472, 22453 28469, 22458 28472, 22455 28472, 22460 28475, 22465 28477, 22462 28479, 22461 28476, 22465 28480, 22466 28476, 22470 28472, 22470 28475, 25470 28470, 25473 28472, 25475 28468, 25475 28468, 25477 29468, 25478 29470, 25481 29465, 25478 29466, 25478 29468, 25480 29468, 25485 29465, 25486 29464, 25488 29462, 25488 29466, 25492 29464, 25497 26464, 25500 26467, 25497 26472, 25497 26476, 25497 26476, 25501 26478, 25506 26480, 25506 26482, 25511 26480, 25515 26483, 25516 26485, 25521 26481, 25521 26484, 25520 26485, 25521 26488, 25526 26487, 25529 26488, 25524 26488, 25528 26491, 25530 26496, 25535 26500, 25537 26502, 25537 26502, 25541 26507, 25544 26508, 25545 26509, 25549 26514, 25554 26514, 25553 26512, 25552 26516, 25555 26514, 25559 26514, 25556 26515, 25554 26512, 25558 26509, 25558 26510, 25562 26510, 25562 26511, 25562 26510, 25567 26505, 25569 26508, 25571 26508, 25570 26512, 25573 26512, 25573 26515, 25578 26515, 25583 26520, 25583 26523, 25584 26525, 25587 26526, 25590 26531, 25590 26530, 25586 26534, 25589 26538, 25591 26533, 25595 26537, 25600 26542, 25601 26544, 25601 26544, 25601 26544, 25606 26547, 25605 26547, 25605 26542, 25608 26542, 25611 26544, 25613 26546, 25614 26551, 25614 26551, 25614 26552, 25619 25552, 25614 25552, 25615 25551, 25618 25549, 25618 25553, 25620 25555, 25622 25559, 25622 25555, 25624 25554, 25627 25555, 25624 25559, 25621 25561, 25619 25560, 25624 28560, 25627 28555, 25632 28550, 25636 28552, 25641 28557, 25645 28557, 25640 25557, 25636 25557, 25636 25561, 25641 25561, 25645 25562, 25646 25557, 25648 25560, 25649 25564, 25652 25566, 25652 30566, 25652 30566, 25652 30568, 25652 30570, 25654 30574, 25658 30575, 25663 31575, 25664 31579, 25665 31583, 25664 31583, 25667 31585, 25668 31588, 25673 31586, 25676 31585, 25676 31588, 25678 31588, 25675 31591, 25680 31590, 25681 31585, 30681 31588, 30677 31593, 30682 31594, 35682 31594, 35677 31593, 35679 31595, 35682 31594, 35683 31591, 35686 31592, 35687 31593, 35691 31596, 35691 31597, 35694 31601, 35698 31601, 35702 34601, 35701 34603, 35705 34608, 35705 34610, 35704 34605, 35707 34607, 35707 34610, 35710 34607, 35715 34608, 35719 34607, 35721 34612, 35717 34612, 35713 34612, 35715 34613, 35716 34609, 35716 34614, 35716 34618, 35720 34620, 35721 34621, 35724 34622, 35724 34625, 35727 34629, 35727 34630, 35727 34633, 35727 34635, 35727 34639, 35732 34640, 35729 34642, 35733 34644, 35737 34646, 35741 34649, 35743 34649, 35744 34653, 35740 34653, 35740 34649, 35743 34651, 38743 34654, 38743 37654, 38744 37650, 38748 37655, 38751 37656, 38755 37657, 38755 37661, 38759 37660, 38758 37664, 38763 37664, 38767 37664, 38762 37664, 38761 37664, 38762 41664, 38762 41664, 38764 41669, 38759 41671, 43759 41673, 43754 41678, 43754 41681, 43759 41676, 43760 41681, 45760 41684, 45760 41683, 45764 41687, 45767 41687, 45771 41687, 45772 41688, 45770 46688, 45775 46692, 45778 46696, 45776 46698, 45777 46701, 45780 46699, 45778 46702, 45776 46706, 45781 46706, 45786 46708, 45789 46710, 45793 46715, 45788 46711, 45792 46715, 45795 46719, 45798 46723, 45801 46728, 45799 46732, 45804 46730, 45799 46733, 45803 46737, 45804 46737, 45805 46736, 45806 46736, 45807 46736, 45810 46739, 45812 46744, 45812 46748, 2328 27377, 2324 27381, 2325 27383, 2327 27387, 2327 27386, 2324 27386, 2325 27386, 5325 23386, 5327 23389, 5331 23390, 5332 23394, 5337 23396, 5332 23396, 5332 23399, 5331 23399, 5335 23403, 5335 23406, 5340 23409, 5341 23409, 5336 23410, 5331 23405, 5334 23407, 5332 23411, 5335 23413, 5330 20413, 5326 20415, 5326 20418, 5331 20420, 5330 20425, 5327 20425, 5331 20428, 5332 20428, 5337 21428, 5333 21431, 5335 21435, 5336 21437, 5331 21438, 5332 21441, 5335 21444, 5340 21441, 5340 21444, 5336 21445, 5335 21442, 5331 26442, 5334 26439, 5337 26443, 5339 26444, 5340 26448, 5344 26443, 5344 26446, 5347 26444, 5351 26442, 5354 26446, 5351 26449, 5350 30449, 5352 30451, 5352 30448, 5356 30448, 5361 30447, 5365 30449, 5369 30450, 5369 30452, 5369 30457, 5373 30459, 5373 30457, 5375 30462, 5377 30465, 5382 30467, 5386 30467, 5385 30463, 5386 30463, 5385 30463, 5387 30464, 5392 30463, 5394 30468, 5396 30468, 5391 30469, 5395 30473, 5393 30473, 5393 30473, 5397 30478, 5398 30474, 5401 30474, 5403 30471, 5403 30472, 5406 30474, 5402 30469, 5403 30466, 5405 30471, 5406 30471, 5411 30473, 5414 30477, 5414 30481, 5409 30485, 8409 30490, 8410 30493, 8412 30494, 8412 30493, 8415 30494, 8416 30497, 8416 30500, 8421 30505, 8422 30506, 8417 30511, 13417 30513, 13413 30510, 13416 30511, 13414 30515, 13414 30519, 13419 30522, 13421 30527, 13420 30531, 13424 30533, 13420 30535, 13415 35535, 13411 35535, 13415 35536, 13419 35541, 13421 35537, 13425 35533, 13426 35533, 13425 35528, 13430 35529, 13435 35530, 13440 35534, 13445 35535, 13450 35535, 13454 35536, 13457 35540, 13459 35540, 13454 35540, 13457 35543, 13454 35539, 13459 35544, 13459 35548, 18459 35550, 18462 35551, 22462 35550, 22467 35554, 22468 35558, 22470 35556, 22475 35559, 22473 35563, 22472 35568, 22474 35568, 22472 35573, 22476 35573, 22476 35575, 22479 35577, 22484 35580, 22489 35584, 22490 35587, 22491 35589, 22495 35589, 22498 35589, 25498 35590, 25495 35586, 25496 35589, 25500 35589, 25498 35589, 25500 35591, 25505 35595, 25505 35597, 25501 35594, 25501 35595, 25497 35595, 26497 35599, 29497 35595, 29497 35597, 29500 35601, 29500 35605, 29502 35610, 29503 30610, 29504 30607, 29507 30607, 29512 30610, 29513 30610, 29516 30611, 29518 30614, 29520 30612, 3261 17309, 3265 17308, 3269 17307, 3273 17312, 3271 17316, 3271 17317, 3276 17319, 3279 17319, 3284 17315, 3287 17317, 3285 17313, 3280 17314, 3277 17319, 3277 17321, 3278 17326, 3282 17328, 3282 17328, 3278 17329, 3279 17329, 3278 17332, 3280 17328, 3275 17333, 3279 17335, 3282 17330, 3283 17332, 3278 17328, 3279 17328, 3279 17326, 3279 17325, 3279 17325, 3283 17327, 3284 17331, 3284 17336, 3289 17339, 3290 17339, 3290 17342, 3292 17341, 3296 17344, 3296 17345, 3301 17345, 3301 12345, 3301 12346, 3306 12343, 3303 14343, 3307 14344, 3309 14345, 3313 14347, 3315 14347, 3316 16347, 3312 16345, 3312 16350, 3314 16352, 3313 16353, 4313 16350, 4318 16352, 4323 16348, 4326 16352, 4324 16353, 4325 16350, 4325 16350, 4328 16354, 4324 16358, 4325 16360, 4327 16365, 4327 16362, 4324 16366, 4327 20366, 4327 20370, 4324 20371, 4328 20376, 4328 20378, 4333 20377, 4335 20377, 4340 20380, 4341 20383, 4343 20386, 4340 20388, 4341 20390, 4342 20387, 4342 20387, 4337 20392, 4338 20394, 4343 20394, 4348 20395, 4350 20395, 4351 20397, 37499 26503, 37496 26500, 37498 26504, 37498 26505, 37501 26510, 37499 26506, 37500 26506, 37502 29506, 37502 29511, 37507 29512, 37508 33512, 37510 33517, 37515 33522, 37519 33526, 37518 33524, 37523 33525, 37523 33529, 37518 33534, 37521 33532, 37522 33532, 37526 33534, 37529 33534, 37527 33531, 37530 33534, 37535 33537, 37536 38537, 37538 38540, 22360 13359, 25360 13364, 25363 13362, 25364 13366, 25364 13366, 25367 13369, 25365 13371, 25361 13373, 25359 13378, 25362 13378, 2249 13366, 2254 13370, 2256 13367, 2259 13367, 2263 13362, 2266 13358, 2266 13360, 2271 13365, 2274 13367, 2276 13367, 2277 13367, 2275 13366, 2276 13369, 2280 13369, 2282 13374, 2286 13370, 2286 13369, 2291 13372, 2292 13370, 2295 13372, 2300 13377, 2300 13376, 2297 13379, 273 22351, 275 22354, 4275 22351, 4271 22352, 4272 22354, 4273 22359, 4274 22364, 4278 22367, 4283 22369, 4286 24369, 4281 24369, 4284 24369, 4287 24369, 4289 24368, 4291 24366, 4296 24364, 4297 24366, 4300 24369, 4303 24373, 1303 24374, 1303 24375, 1307 24379, 1307 24380, 1309 24381, 1314 24384, 1316 24386, 1320 24384, 1318 24386, 1318 24391, 1320 24391, 1320 29391, 1323 29391, 1318 29387, 1322 29390, 1323 29393, 1328 29393, 1329 29393, 2329 29398, 2329 29398, 2334 29397, -664 24371, -661 24372, -659 24372, -654 24375, -651 24376, -647 24376, -645 24378, -641 24374, -636 24379, -633 24384, -636 24386, -636 24388, -636 24388, -634 24392, -635 24394, -630 24390, -628 24390, -627 24390, 373 24393, 378 24398, 376 24396, 379 24401, 3379 24404, 6379 24409, 6380 24412, 6375 24410, 6372 24410, 6377 24407, 6372 24407, 6377 24407, 6381 24410, 6376 24413, 6380 24415, 6382 24416, 6380 24419, 6380 24423, 6385 24427, 6387 24429, 6389 24432, 6392 24437, 6388 24434, 6388 24439, 6389 24440, 6390 24444, 6389 24448, 6385 29448, 6385 29451, 6388 29455, 6384 29450, 6389 29451, 6392 29456, 6395 29456, 6399 29459, 6402 29463, 6402 29467, 6399 29471, 6395 29471, 6397 29474, 6399 29477, 6401 29472, 6396 29471, 6399 29474, 6398 29477, 6398 29474, 6395 29469, 6391 29473, 6392 29474, 6391 29469, 6391 29472, 6394 29474, 6390 33474, 6392 33470, 6393 33470, 6394 33471, 6396 33471, 324 22376, 324 22378, 325 22381, 329 22382, 333 22386, 332 22387, 334 22390, 335 22387, 333 22387, 332 22391, 334 22395, 334 22400, 339 22401, 341 22398, 342 22403, 342 22402, 342 22400, 345 22400, 345 22400, 343 22404, 344 22408, 345 22406, 350 22407, 347 22411, 349 22415, 344 22415, 347 22417, 342 22421, 347 22421, 350 22426, 350 22430, 353 22431, 354 22436, 354 22440, 4354 22442, 4355 22446, 4356 22448, 4356 22451, 4359 22453, 4362 22454, 4366 22454, 4369 22455, 4371 22457, 4368 22459, 4371 22457, 4375 22462, 4379 22463, 4382 22463, 4382 22468, 4387 22471, 4387 22471, 4392 22473, 4387 22473, 4387 22476, 25573 26512, 25576 26511, 25580 26516, 25583 26516, 25583 26516, 25585 26512, 25585 26517, 25589 26520, 25591 26519, 25592 26519, 25593 26521, 25591 26524, 25589 26526, 23589 26530, 23587 26535, 23591 26538, 23594 26542, 24594 26547, 24590 26549, 24595 26551, 24600 26547, 24600 26552, 24604 26549, 24600 26544, 24602 26549, 24602 26552, 24602 31552, 24607 31553, 24610 31555, 24615 31556, 24617 36556, 24618 36561, 24621 36561, 24624 36564, 24624 36568, 24629 35568, 24629 35573, 24634 35573, 25634 35574, 25637 35573, 25638 35577, 25638 35577, 25640 35580, 25643 35584, 25643 35587, 25643 35592, 25644 40592, 20644 40597, 20647 40597, 20652 40599, 20653 40595, 20653 40598, 20650 40595, 20650 40595, 20654 40600, 20654 40600, 20658 40601, 20658 40604, 20658 40605, 20661 40602, 20664 40601, 20664 40601, 20665 40604, 20670 40605, 20667 40610, 1217 13318, 1216 13323, 1214 13321, 1211 13316, 1212 13316, 1213 13321, 6213 13324, 6216 13324, 6218 13324, 6213 13327, 6216 13322, 6216 13327, 6216 13328, 6218 13323, 6221 13327, 6220 13325, 6221 13325, 6220 13330, 6223 13333, 6227 13335, 6232 13339, 6233 13343, 6233 13347, 6237 13342, 6236 13346, 6236 13348, 6238 13349, 25526 26487, 25523 26488, 25526 26493, 25529 26491, 25531 26488, 25532 26486, 25536 27486, 25541 27490, 25539 27492, 25543 27487, 25546 27490, 25549 27494, 25552 27495, 25552 27495, 25556 27490, 25561 27490, 25565 27493, 25563 27493, 25565 27497, 25563 27495, 25565 27497, 25565 27499, 25566 27501, 25565 27501, 25565 27501, 25560 27502, 25565 27503, 25567 27507, 25569 27507, 25571 27507, 25569 27508, 25567 27509, 25567 27509, 25567 27509, 25568 27509, 25572 27505, 25572 27501, 25576 27502, 25572 32502, 25572 32505, 25575 32505, 25578 32501, 25578 32502, 25579 32505, 25581 32507, 25585 32508, 25590 32511, 25594 32516, 25598 32511, 25601 32511, 25596 32507, 25599 32510, 25599 32514, 25596 32513, 25596 32514, 25598 32517, 25594 32517, 25596 32519, 25596 32524, 25600 32524, 25604 32521, 25605 32522, 27605 32524, 27609 32527, 27610 31527, 27615 31531, 27617 31531, 30617 31534, 30619 31534, 30620 31536, 30621 31540, 30625 31541, 30625 31542, 30627 31542, 30628 31545, 30629 31545, 30626 31544, 30625 31544, 30626 31549, 34626 31550, 34621 31547, 34625 31549, 34626 31553, 34626 31552, 34628 31554, 34628 31559, 34628 31555, 34630 31559, 34635 31559, 34638 31563, 34636 31568, 34638 31568, 34641 31566, 34641 31564, 36641 31559, 36638 27559, 41638 27561, 41642 27558, 41646 27562, 41649 27563, 41650 27559, 41655 27559, 41660 27559, 41660 27556, 41660 27556, 41662 27554, 41658 27558, 41663 27562, 41666 27565, 41669 27570, 41664 27566, 41665 27567, 41665 27569, 41664 27573, 41663 27573, 41666 27575, 41666 27571, 41661 30571, 41662 30569, 41662 30565, 41667 30570, 41666 30565, 41666 30565, 41666 30566, 41666 30567, 41662 30562, 1314 24384, 4314 25384, 4317 25388, 4317 25389, 4321 25387, 4324 25392, 6324 25391, 6324 25391, 6328 25396, 6323 25401, 6326 25401, 6326 25405, 6321 25408, 9321 25409, 9316 25404, 9314 25406, 9312 25407, 9315 25407, 9315 25407, 9318 25404, 9321 25405, 4321 25400, 8321 25402, 8317 25404, 8317 25400, 8317 25401, 8313 25402, 8309 25398, 8311 25398, 8313 25401, 8317 25406, 8312 25407, 11312 25369, 11313 25369, 11318 25374, 11322 25379, 11327 25379, 11327 25384, 11327 25386, 11328 25382, 14328 25384, 14330 25386, 14333 25387, 14336 25389, 14338 25390, 19338 25390, 19338 25393, 19334 25394, 19334 25395, 19337 25392, 19340 25395, 19344 25397, 19342 25397, 19347 25400, 19347 25398, 19349 25398, 19351 25397, 19353 25401, 19352 25402, 19350 25403, 19351 25407, 19354 25403, 19352 25406, 19356 25404, 19355 25409, 23355 25406, 23356 25406, 23358 25409, 23360 25413, 23362 25417, 23365 25418, 23369 25416, 23367 25415, 23369 25418, 23365 25417, 23369 25420, 23369 25420, 23372 25422, 24372 25418, 24372 25423, 24375 27423, 24380 27423, 24382 27420, 24382 27416, 24382 27414, 24382 27410, 24378 27410, 24376 27414, 24372 27418, 24372 27419, 24373 27424, 24377 27419, 24380 27415, 24377 27419, 24380 27422, 24384 27425, 24385 27430, 24385 27429, 24387 27434, 24392 27435, 24396 27436, 24397 27440, 24401 30440, 24402 30443, 24406 30447, 24405 30443, 24408 30442, 24412 30446, 24408 30450, 24410 30449, 24405 30449, 24410 30446, 24414 30450, 24418 30450, 24418 30453, 19418 30453, 19418 30451, 19420 30456, 19422 30457, 19425 30462, 15425 30466, 15425 30468, 15427 30470, 16427 30471, 16426 30475, 16423 30478, 16428 30478, 16430 30480, 16430 30480, 16426 30478, 16426 33478, 16427 33478, 16429 33481, 16427 33483, 16428 33481, 16424 33484, 16427 33486, 16432 33483, 16432 33482, 16431 33486, 16426 33486, 16429 33488, 16432 33492, 16433 33492, 16436 33492, 16437 33495, 16434 33491, 16438 37491, 16436 37494, 16440 37489, 16445 37486, 16448 37484, 16449 37484, 16449 37486, 16453 37482, 16456 37483, 16460 37483, 16456 37483, 16456 37486, 16461 37490, 16462 37495, 16465 37499, 16466 37496, 16467 37497, 16468 37498, 16470 37501, 16470 37505, 16470 37505, 16475 37507, 16475 37507, 16475 37502, 16478 37498, 21478 33498, 21475 33497, 21478 33493, 21480 33495, 21480 33500, 21480 33496, 21482 33500, 21485 33505, 21486 33508, 21485 33504, 21486 33509, 21486 33509, 21490 35509, 21493 35509, 21496 35510, 21498 35514, 21494 35510, 21494 35513, 21491 35518, 21492 35521, 21489 35523, 23489 35527, 23487 35532, 23489 35537, 23485 35538, 23489 35539, 23490 35541, 23495 35543, 23497 35546, 23497 35550, 23497 35554, 23493 35553, 23490 35556, 23494 35559, 23497 35564, 23502 35563, 23498 35561, 4324 16358, 4319 16362, 4320 16362, 4322 16367, 4317 16367, 4317 16366, 4318 20366, 4322 20369, 4325 20367, 4328 20370, 4331 20371, 4334 20374, 4339 20378, 4340 20379, 4335 20379, 4340 20379, 4343 20381, 4344 20381, 4344 20382, 4345 20385, 4348 20390, 4348 20390, 4348 20390, 4348 20390, 4351 20394, 4354 20399, 4356 20400, 4357 20404, 4360 20404, 4362 20405, 4362 20408, 4365 20409, 4370 20410, 4374 20415, 4373 20420, 4369 20421, 4366 20426, 4369 20424, 4374 20429, 4375 20426, 4376 20422, 4379 20422, 4383 20426, 4384 20427, 4386 20422, 4391 20425, 4387 20427, 4392 20427, 4392 20429, 4394 20433, 4398 20438, 41576 39702, 41580 39706, 41578 39708, 45578 39708, 45577 39713, 45579 39717, 45583 39719, 45583 39722, 45585 39725, 45580 39730, 47580 39726, 47583 39723, 47588 39726, 47588 39730, 47591 39734, 47594 39737, 47599 39737, 47595 39737, 47598 39739, 47599 39739, 47597 39739, 47593 39743, 47595 39748, 47595 39751, 4076 20267, 4079 20272, 4081 20272, 4080 20275, 4080 22275, 4085 22280, 4089 22276, 4090 22279, 4088 22283, 4084 22284, 4086 22286, 4088 22281, 4084 22281, 4089 22285, 4092 22285, 4094 22285, 4094 22290, 4096 22291, 4099 22294, 4099 22295, 4097 22290, 4097 22292, 4097 22297, 4097 22292, 4094 22289, 4091 22290, 4092 22290, 4097 22285, 4102 22290, 4105 22289, 4106 22292, 4106 22293, 4109 22298, 4114 22296, 4119 22294, 4122 22299, 122 22304, 123 22307, 124 22304, 124 22304, 123 26304, 127 26307, 131 26307, 129 26309, 129 26310, 134 26310, 134 26311, 138 26311, 143 26313, 142 26315, 145 26317, 142 26318, 147 26322, 151 26322, 155 26325, 155 29325, 160 29330, 160 29333, 164 29328, 164 34328, 167 34333, 170 34332, 169 34336, 171 34337, 175 34338, 175 34340, 179 34342, 180 34344, 180 34348, 184 34352, 179 34352, 184 34352, 186 34357, 186 34362, 183 34364, 185 34369, 189 34369, 194 34369, 199 34371, 201 34370, 205 34372, 207 34372, 204 34367, 206 34364, 1206 34364, 1207 34368, 1207 30368, 1207 30363, 1208 30365, 1209 30368, 1212 30370, 1212 30370, 1216 30371, 1220 30376, 1221 30379, 1216 30383, 1216 30388, 1219 30386, 1224 30387, 1225 30386, 1227 30384, 1230 30383, 1233 30387, 1234 30387, 1237 30388, 1239 30392, 1244 30390, 1246 30393, 2246 30396, 2243 30399, 2247 30401, 2247 30403, 2246 30398, 2244 30399, 2248 32399, 2248 32399, 2251 32402, 2253 32397, 5253 32394, 5253 32399, 5257 32403, 5257 32401, 5259 32401, 5259 32405, 5263 32410, 5263 32415, 5268 32416, 5273 32420, 5275 32423, 5278 32424, 5283 32426, 5281 32429, 6281 33429, 6286 33433, 6286 33434, 6284 33435, 6284 33432, 6288 33429, 6290 32429, 6290 32425, 6288 32428, 6290 32428, 11290 32431, 11294 32429, 11294 32433, 11292 32438, 11288 32441, 11288 32441, 11285 32446, 11280 32446, 11281 32447, 11285 32449, 11286 32449, 11285 32452, 13285 32451, 13289 32446, 16289 32450, 16284 32449, 16285 32449, 16286 32452, 16287 32452, 16286 32450, 16288 32447, 16292 32450, 16293 32450, 16294 32454, 16293 32454, 16293 32454, 16293 32449, 16289 32451, 16290 32456, 16289 32461, 16293 36461, 16291 36466, 16295 36466, 16296 36466, 16299 36466, 16303 36468, 16308 36473, 16312 36471, 16312 36467, 16315 36463, 16314 36464, 16315 36469, 16315 36473, 16310 36474, 16311 36472, 16316 36474, 16321 41474, 16324 41475, 16327 44475, 16332 44475, 16332 44475, 16332 44477, 16332 44478, 16337 44483, 16334 44481, 8416 30500, 8417 30501, 8421 30501, 8416 30505, 8418 30504, 8420 30499, 8423 35499, 8425 35498, 8429 35501, 8431 35503, 8434 35503, 8438 35507, 8440 35507, 8445 35509, 8442 35512, 8445 35513, 8442 35513, 8442 35515, 8443 35519, 8447 35515, 8450 35516, 8445 35521, 8445 35523, 8444 35528, 8446 35530, 8443 35531, 8438 35531, 8435 35527, 8431 35531, 8432 35534, 8433 35536, 8431 35537, 8435 35539, 8439 32539, 8437 32540, 8441 32540, 8438 32543, 9438 32546, 9436 32541, 9431 32538, 9431 32538, 9435 32541, 9435 32546, 9431 32547, 9436 32542, 9438 32542, 9438 34542, 7438 34542, 7440 34547, 7441 34547, 7441 34547, 7441 34552, 7440 34553, 7440 34556, 7440 34557, 7440 34560, 11440 34565, 11436 34563, 11438 34559, 7438 34557, 7438 34553, 122 1239, 126 1243, 127 1240, 127 1242, 131 1239, 130 1239, 127 1240, 125 1243, 130 2243, 134 2246, 133 2246, 137 2246, 142 2246, 147 2251, 148 2256, 146 2257, 148 2252, 146 2249, 148 2248, 152 2253, 157 2249, 161 2246, 162 2247, 162 2249, 157 2248, 158 2249, 3158 2250, 3161 2252, 3161 2254, 3166 2258, 3167 2261, 3168 2259, 3171 2261, 3173 2266, 3171 2267, 3176 2272, 3179 2277, 3176 2280, 3180 2279, 3175 2283, 3179 2280, 3182 2283, 3184 2288, 3187 2293, 5187 2290, 5187 2292, 5183 2290, 5187 2292, 5186 2297, 5189 2297, 5189 2301, 5192 2303, 5189 2303, 5187 2304, 5183 6304, 5184 6301, 5189 6304, 5191 6302, 5193 6300, 5195 6300, 5195 6300, 5197 6301, 5197 6304, 5199 6301, 5197 6304, 5192 6306, 5193 6310, 5194 6312, 5197 6316, 24397 27440, 24393 27441, 24395 27437, 24400 27440, 24400 27441, 16288 32447, 21288 32447, 21288 32448, 21284 32452, 21285 32450, 21285 32452, 21287 32455, 21283 32460, 21284 32462, 21284 32467, 21284 32472, 21286 32474, 21291 32475, 21289 32475, 21289 32473, 21289 32478, 21286 32481, 21290 32486, 21293 32486, 21293 32490, 21298 32489, 21301 32490, 21303 32491, 21305 32488, 21303 32486, 21307 32491, 21312 32495, 21314 32499, 21315 32495, 21317 32499, 21314 32499, 21316 32502, 21318 32505, 21313 32510, 21313 32512, 21314 32517, 21319 32520, 21321 32520, 21326 32520, 21329 32525, 21330 32530, 21334 32531, 21330 36531, 21333 41531, 21338 41531, 21336 41535, 21339 41537, 21337 41539, 21341 41544, 21342 41544, 21345 41540, 25345 41543, 25342 41546, 25339 41546, 25339 41549, 25337 41546, 25337 41547, 25337 46547, 25341 46552, 30341 46555, 30342 46560, 30345 46561, 30344 46557, 30339 46560, 30343 46565, 30339 46569, 30338 46567, 30340 46568, 24375 27423, 24375 27425, 24377 27428, 24379 27429, 24379 27434, 24376 27439, 24381 27441, 24386 27436, 24387 27438, 24384 27441, 24383 27446, 24383 31446, 24383 33446, 20383 33443, 20385 34443, 20384 34444, 20380 34448, 20383 34450, 20383 34446, 20386 34447, 20390 34450, 20394 34451, 20395 34446, 20395 34451, 20398 29451, 20397 29447, 20401 29447, 20402 29443, 20401 29440, 20406 29443, 20411 29444, 20412 29444, 20412 29448, 20410 29449, 20415 29452, 20415 29455, 20414 29459, 20415 29462, 20420 29465, 20415 29467, 20417 29468, 20418 29468, 20418 29467, 20418 29467, 20420 29468, 20416 29469, 20420 29467, 20415 29464, 20415 26464, 20420 26462, 20423 26463, 20423 26465, 20423 26464, 43580 35662, 43580 35658, 43580 35662, 43580 35664, 43585 35665, 43585 35663, 43585 35666, 43581 35667, 43585 35665, 43589 35670, 25627 25555, 25631 25555, 25632 25558, 25632 25563, 25634 25564, 25629 25565, 25625 25561, 25625 25563, 25626 25565, 26626 25570, 26629 25570, 29629 25575, 29628 25578, 29627 25579, 29624 25583, 29627 25587, 29632 25592, 29634 25593, 29637 25595, 29637 25598, 29639 25602, 29644 25600, 29645 25601, 29646 25601, 29651 25602, 29656 25606, 29658 25606, 29663 25607, 29663 25605, 29666 26605, 29668 26608, 29667 26608, 29670 26611, 29674 26611, 29671 26615, 29673 26620, 29676 26617, 29681 26620, 29682 26620, 29683 26619, 29684 26623, 29681 26621, 29686 26626, 29688 26628, 29691 26628, 29692 26632, 29693 26634, 29695 26629, 29696 26624, 29700 26621, 29705 29621, 29709 29620, 29708 29624, 29711 29627, 34711 29630, 34712 29632, 34712 29631, 2284 16415, 2285 16416, 2285 16416, 2289 16421, 2294 16425, 2299 16425, 2300 16430, 2305 16430, 2306 16433, 2311 11433, 2315 11436, 2310 14436, 2310 14435, 2313 14437, 2312 14441, 2310 14442, 2311 14444, 2313 14444, 2311 14447, 2314 14447, 2316 14451, 2316 14456, 2316 14454, 2311 14455, 2311 14455, 2311 14460, 2315 14465, 2315 14465, 2311 19465, 2311 19465, 2313 19466, 2317 19469, 2320 19469, 2323 19466, 2319 19468, 2323 19471, 2324 19471, 2324 19473, 2324 19473, 2322 19468, 2323 19466, 2324 19465, 2329 19470, 2329 19465, 2324 19465, 2324 19467, 2319 19471, 2320 19475, 2104 -1844, 2109 -1844, 2113 -1842, 2116 1158, 2116 1160, 2117 1161, 2116 6161, 2118 6166, 2123 6169, 2126 6174, 2123 6179, 2126 6183, 2126 6187, 2130 6182, 2128 6183, 2127 6182, 2128 6185, 2124 10185, 2129 10190, 2130 10193, 2132 10192, 2132 10195, 2129 11195, 2129 11199, 2133 11200, 2134 11196, 2133 11201, 2137 11205, 2137 11207, 2141 11203, 2144 11207, 2145 11208, 2149 11212, 2144 11214, 2144 11215, 2149 11216, 2152 11221, 2152 11223, 2153 11223, 2154 11226, 2154 11226, 2150 11228, 2152 11224, 2152 11227, 2148 11222, 2145 11223, 2142 11225, 2145 11222, 2142 11223, 2142 11227, 2147 11229, 2149 11230, 2154 11230, 2157 11228, 2159 11233, 2159 11233, 2155 11237, 2155 11242, 2151 11243, 7151 10243, 7156 10245, 7159 10245, 7164 10247, 7166 10252, 7166 10255, 7171 10257, 7173 10257, 7174 10261, 7179 10264, 7184 10260, 7189 10264, 7193 8264, 7197 8260, 7202 8262, 7206 8262, 7205 8265, 7205 8266, 7207 8270, 7211 8274, 7211 8277, 7216 8277, 7216 8280, 7212 8280, 7213 8280, 7215 8283, 7220 8282, 7224 8287, 7225 8283, 7222 10283, 7223 10287, 7225 10288, 7230 10290, 7232 10294, 7233 10294, 7233 10297, 7234 10298, 7234 10301, 7236 10303, 7231 10299, 7228 10298, 7223 10297, 7225 10299, 7230 10303, 7231 10307, 7234 10311, 7234 10315, 7235 10320, 7236 9320, 7241 9322, 7246 9325, 7243 9330, 7243 9332, 7240 9335, 7237 9334, 7239 9339, 7238 9339, 7238 9341, 7238 9342, 7233 14342, 7232 14337, 7234 14342, 7239 18342, 4084 22284, 4083 22284, 6083 22287, 6078 22289, 6078 22293, 6080 22290, 6082 22291, 6086 22296, 6086 22297, 6087 22297, 6088 22295, 6093 22298, 6094 22297, 9094 22294, 9097 22298, 9098 22299, 9098 22301, 9093 22296, 9098 22299, 9100 22294, 9096 18294, 9099 18294, 9098 18298, 9101 18296, 9100 18301, 9105 18303, 9105 18306, 9105 18309, 9102 18305, 9104 18306, 9108 18309, 9104 18314, 9103 18310, 9105 18312, 9105 18316, 9109 18314, 9109 18319, 9109 18324, 9113 18326, 9113 18330, 9115 18333, 9113 18333, 9118 18333, 9123 18333, 9123 18336, 9125 18335, 9126 18336, 9127 18332, 9129 18329, 9127 18332, 9130 18333, 9135 18333, 9138 18337, 9143 18341, 9144 18346, 9145 18344, 9150 18348, 9154 18345, 9152 18350, 9151 18345, 9151 18345, 9156 18347, 9160 18349, 9163 18350, 9163 18351, 9165 18356, 9166 18356, 9164 18353, 9167 18356, 9167 18355, 9167 18356, 9167 18360, 9165 18356, 9169 18357, 9169 18353, 9170 18355, 9170 18351, 9175 18351, 9177 18351, 9181 18352, 9184 18353, 9189 18356, 9188 18361, 9191 18364, 9194 18364, 9198 18366, 13198 18371, 13198 18373, 13198 18375, 13201 18378, 13196 18378, 13199 18379, 13202 18381, 13207 18384, 13212 18388, 13211 18383, 13211 18378, 13215 18379, 13218 20379, 13214 20379, 13217 20379, 13213 20379, 13213 20376, 13210 20377, 13206 20377, 13206 20373, 13207 20373, 13209 20370, 13214 20371, 13218 20371, 13223 20376, 13224 20381, 13227 20385, 13228 20390, 13232 20387, 9232 20392, 9230 20388, 9230 20390, 9225 20393, 9225 20396, 4225 20401, 4225 20400, 4227 20403, 4224 20408, 4222 20412, 4222 20415, 4225 20420, 4229 20425, 4232 20422, 4236 20425, 4234 20426, 4238 20427, 4240 20427, 4241 20427, 4237 20431, 4233 20431, 4232 20430, 4230 20432, 4234 20431, 4234 20435, 4238 20437, 4243 20435, 4243 22435, 4238 22440, 4241 22441, 4241 22443, 4238 22447, 4234 22443, 4238 22448, 4238 22450, 4241 22451, 4241 22456, 4243 22458, 4247 22461, 4247 22464, 4252 22466, 4253 22469, 4255 22469, 4251 22469, 4253 22464, 4253 22468, 4257 22473, 4259 22477, 4258 22482, 4261 22483, 4262 22484, 4259 22489, 6259 22493, 6262 22494, 6262 22497, 6264 22500, 6264 22504, 6269 22499, 6273 22499, 6278 22495, 6278 22493, 6283 22491, 6288 22494, 6291 22494, 6296 22494, 6296 22493, 6294 22489, 6294 22493, 6290 22493, 6290 22498, 6290 22500, 6288 22501, 6290 22505, 6294 22504, 5294 22507, 5294 22507, 5298 22512, 5297 22514, 5302 22514, 5307 22517, 5304 22518, 5308 22514, 5311 22517, 5315 27517, 5315 27517, 5319 27517, 5324 22517, 5328 22521, 6328 22520, 6325 22522, 6325 22527, 6322 22527, 6323 22530, 6325 22535, 6325 22535, 6326 22536, 6326 22536, 6327 22533, 6323 22535, 6325 22538, 6330 22538, 6331 22534, 6326 22531, 10326 22526, 10321 22528, 10317 22524, 10316 22529, 10313 22529, 10309 22530, 10306 22535, 10308 22531, 10308 22532, 10311 22534, 10314 27534, 10314 27538, 10314 27538, 10309 27540, 10309 27536, 11309 27535, 11309 27537, 11310 27539, 11305 27535, 11300 27536, 11296 27538, 11296 27538, 11301 27542, 11299 27546, 11304 27551, 11308 27551, 11313 27553, 11315 30553, 11319 30555, 11315 30550, 11318 30545, 11318 30544, 11321 30549, 11320 30550, 11325 30554, 11328 30558, 11328 34558, 11332 34562, 11333 34562, 11335 34562, 11334 34565, 11330 34565, 11333 34566, 11338 34566, 11338 34571, 11342 34574, 11344 34573, 11347 34572, 11346 34573, 11347 34575, 11351 34578, 15351 34578, 15356 34573, 15361 34570, 15364 34575, 15365 34580, 15369 34581, 15370 34581, 15373 34585, 15376 34580, 15381 34578, 15385 34583, 15386 34588, 15389 34587, 17389 34582, 17394 34582, 17393 34582, 17398 34577, 17399 34582, 17399 34584, 17399 39584, 17404 39588, 17399 39591, 17404 39591, 17408 39586, 17405 39591, 17409 39593, 17411 39596, 17408 39596, 17411 39599, 17411 39603, 17414 39607, 17418 39612, 17419 39612, 17419 39612, 17423 39611, 17424 39613, 17426 39612, 17429 39608, 17427 39609, 17428 39613, 17425 39615, 17424 39614, 17427 39617, 17430 39622, 17430 39623, 17431 39620, 17434 39620, 13434 39619, 13434 39621, 13434 39621, 13434 44621, 13436 44625, 13436 44627, 13441 44631, 13444 44636, 13444 44639, 13442 44635, 13444 44635, 13447 44639, 13449 44643, 13447 44641, 13447 44642, 13452 44643, 13456 44648, 13459 44648, 13461 44646, 15461 44643, 15459 44648, 15463 44648, 15464 44646, 15461 44649, 15461 44651, 15465 44654, 15460 44655, 15461 44657, 15463 44661, 15465 44665, 15465 44665, 15465 44667, 15469 44670, 15474 44672, 15476 44668, 15472 44672, 15473 44674, 15475 44678, 15477 44679, -3804 12302, -3802 12305, -3803 13305, -3802 13300, -3806 13296, -3807 13299, -3804 13304, -3802 13301, -3799 13305, -3799 13306, -3794 18306, -3799 18310, -3797 18315, -3800 18315, -3797 18316, -3799 18318, -3794 18323, -3793 18326, -3789 18325, -3784 18324, -3784 18325, -3782 18325, -3780 18325, -3779 18328, -3780 18329, -3781 18324, -3786 18328, -1786 18328, -1786 18333, -1782 18337, -1782 18338, -1779 18333, -1775 18338, -6775 18341, -6772 18343, -6774 18345, -6779 18345, -6777 18345, -6777 18347, -6777 18343, -6775 18347, -6780 18342, -6777 18345, -6776 18345, -6774 18340, -6774 18337, -6774 18337, -6778 18342, -6782 18342, -6785 18339, -6784 18340, -6779 22340, -6779 22339, -6776 22335, -6775 22330, -6775 22335, -6775 22339, -6770 22339, -6772 22344, -6767 22345, -6765 22341, -6765 22339, -6765 22339, -6765 22337, -6765 22340, -6760 22335, -6757 22335, -6762 22336, -6763 22338, -6765 22343, -6760 22338, -6758 22338, -6758 22338, -6756 22341, -6752 22345, -6752 22346, -6748 22343, -4748 22347, -4745 22347, -4750 22347, -4749 22348, -4747 22349, -4743 22352, -4738 22357, -4734 22362, -4736 22367, -4738 22362, 21338 41531, 21336 41531, 21332 41530, 21332 41530, 21335 41533, 21330 41533, 21331 41534, 21328 41536, 21330 41536, 21326 41541, 21330 41536, 21332 41539, 21336 41536, 21338 40536, 21336 40540, 21341 40538, 21343 40538, 21346 40538, 21348 40536, 21352 40536, 21355 40539, 21359 40543, 21361 40546, 21362 40550, 21357 40550, 21362 40551, 21361 40554, 21358 40555, 21358 40554, 21359 40554, 21363 40558, 21360 45558, 21364 45560, 21368 45557, 21372 45561, 21376 45560, 21379 45557, 22379 45553, 22384 45553, 22384 45556, 22388 45561, 22389 45561, 22390 45557, 22394 45561, 24394 45565, 22394 45562, 22399 45565, 22401 45562, 22400 45565, 22402 45568, 22402 45573, 22406 45577, 22408 45581, 22408 45585, 22406 45585, 22409 45586, 22411 45583, 22411 45579, 22411 45583, 22409 45583, 22404 45586, 22404 45586, 22406 45591, 22408 45591, 22408 45593, 22413 45593, 22415 45594, 22419 45595, 22419 45596, 22424 45591, 22427 45587, 22430 50587, 22430 50589, 22430 50589, 22432 50592, 22437 50594, 22437 50589, 22437 50594, 22441 50599, 22442 50594, 22447 50591, 22444 50588, 22444 50590, 22445 54590, 22445 54594, 22448 54599, 22450 54601, 22450 59601, 22446 59597, 22451 59600, 22451 59603, 22454 59604, 22459 59604, 22460 59609, 22459 59606, 22464 59607, 22465 59608, 22463 59609, 22460 59606, 22459 59605, 22459 59605, 22457 59609, 25457 59610, 25459 59615, 25464 59617, 25466 59618, 25469 59621, 25474 59616, 25478 59617, 25480 59614, 25484 59619, 25484 59620, 25488 59616, 25485 59618, 25489 59623, 25494 59627, 25499 59629, 148 2256, 152 2253, 152 2253, 154 2258, 159 2253, 160 2257, 159 2256, 163 2259, 161 3259, 163 3262, 163 3259, 165 3259, 170 3263, 170 3263, 174 3267, 169 3271, 174 3275, 174 3276, 174 3278, 177 3282, 181 3286, 183 3287, 186 3284, 187 3286, 189 3286, 193 3288, 194 3290, 193 6290, 195 6293, 200 6289, 197 6294, 196 6293, 197 6293, 201 6297, 202 6292, 200 6294, 204 6295, 209 6300, 214 6305, 217 6305, 218 6305, 213 6308, 214 6308, 218 6313, 218 6308, 216 6312, 215 6312, 213 6309, 214 6313, 219 6318, 222 6321, 226 6326, 224 6331, 222 6327, 41575 39716, 41574 39713, 41578 40713, 41582 40718, 41578 40721, 36578 40721, 36579 40723, 36584 40720, 36587 40725, 36592 43725, 36587 43725, 36584 43728, 36587 43733, 36592 43735, 36592 43734, 15291 11311, 15287 11316, 15288 11319, 15291 11319, 15296 11319, 15297 11320, 15298 13320, 38744 37650, 38745 37654, 38747 37659, 38746 37662, 38741 37663, 38739 37666, 38744 37666, 38747 37661, 38750 37666, 38750 37666, 38754 37671, 38755 37671, 38750 37673, 38750 37672, 38754 37677, 38756 37678, 38758 37680, 38760 37678, 38762 37683, 38762 37679, 38760 37679, 38765 37679, 38769 37678, 38774 40678, 38769 40683, 38774 40687, 38776 44687, 38780 44690, 38782 44694, 38782 44694, 38781 44699, 38784 44704, 38782 44699, 38777 44700, 38777 44700, 38777 44700, 38781 44703, 38785 44700, 38786 44700, 38788 44696, 38788 44696, 38788 44700, 38793 44702, 38795 44703, 38797 44707, 38802 44712, 38805 44712, 38809 44713, 38804 44710, 38808 44712, 38811 44713, 36811 44713, 36816 44708, 36815 44709, 36816 44709, 36818 44713, 36813 44716, 36814 48716, 36813 48721, 36817 48725, 36818 51725, 36820 51721, 36824 51724, 40824 51719, 40829 51716, 40832 51720, 40831 51723, 40834 51727, 40837 51728, 40842 51725, 40843 51725, 40838 51729, 40843 51734, 40848 51738, 40850 51742, 40851 51744, 40853 51747, 40856 51749, 40857 51750, 40859 51754, 40859 51750, 40863 51752, 40868 51755, 40864 51754, 40868 51754, 40871 51756, 40867 51756, 40865 51759, 40860 51761, 40857 51757, 40857 51762, 40854 51762, 40855 51764, 40859 51765, 40857 51761, 40854 51764, 40855 51765, 40857 51766, 40860 51761, 40861 51760, 40865 51761, 40865 51763, 40862 51768, 40861 51768, 40856 51772, 40852 51769, 40854 51771, 40854 51771, 40850 51776, 40854 51780, 40856 51782, 40854 51782, 43854 51782, 43856 52782, 43858 52785, 43861 52785, 43861 52780, 37514 26540, 37519 26535, 37522 26539, 37522 26544, 37524 26548, 37529 26548, 37534 26553, 37539 26548, 37542 26553, 37547 26548, 37551 26551, 37551 26554, 37550 26555, 37551 26557, 37548 26557, 37548 26557, 37551 26560, 37551 26563, 37554 26563, 37558 26568, 37562 26563, 37563 26565, 37567 26569, 41567 26569, 41571 26572, 41573 26577, 41573 26577, 41578 29577, 41573 29577, 41575 29580, 41575 29582, 46575 29582, 46571 29586, 45571 29587, 45574 29587, 45570 29587, 45575 29585, 45577 29582, 45573 29585, 45574 29588, 45574 29589, 45578 29589, 45580 29592, 45583 29595, 45584 29597, 45584 29602, 45586 29601, 45591 29604, 45587 29609, 45591 33609, 45595 36609, 45596 36611, 45601 36613, 45602 36608, 45606 36608, 45606 36612, 45606 36611, 45610 36614, 50610 36617, 50613 36613, 50616 36613, 50621 36609, 50626 36609, 50627 36610, 50627 36609, 50631 36610, 50626 36612, 50627 36614, 50628 36614, 50631 36612, 50629 36614, 50630 36618, 50634 36622, 46634 34622, 46634 35622, 46638 35626, 46638 35621, 46639 35624, 46641 35623, 46645 35624, 46647 35629, 46645 35634, 46650 35639, 46650 35644, 46651 35647, 46653 35651, 46657 35654, 46654 35659, 46659 35660, 46660 35661, 46664 35664, 46661 35667, 46664 35668, 46667 35667, 46669 35671, 46669 35667, 46672 35670, 46674 35675, 46676 35675, 47676 35672, 47678 35676, 47679 35677, 47679 35682, 47679 35681, 47679 35681, 47679 35686, 47674 35687, 47673 35687, 49673 35689, 49676 35693, 49679 35696, 49677 35696, 54677 35701, 54680 35703, 54676 35703, 54672 35705, 54672 35704, 54677 35707, 54678 34707, 54678 34707, 54681 34710, 54685 34712, 54690 34710, 54690 34711, 54687 34706, 54689 34706, 54694 34711, 54689 36711, 54689 36710, 54684 36711, 54687 38711, 54682 38714, 54682 38718, 54679 38718, 54681 38723, 54684 38724, 54689 38720, 54690 38721, 54694 38726, 54699 38730, 54701 38731, 54702 38728, 54704 38724, 52704 38723, 52704 38723, 52704 38725, 52704 38729, 52706 38730, 52708 38732, 52709 38733, 52713 38732, 52713 35732, 52715 35737, 52714 35741, 52714 35743, 52715 35746, 52715 35749, 52710 35749, 52712 39749, 52715 39753, 52718 39752, 52723 39753, 52722 39757, 52718 39760, 52718 40760, 47718 40761, 47719 40765, 47724 40765, 47724 40765, 47724 40770, 47728 40773, 47730 40776, 47735 40781, 47733 40777, 50733 40781, 51733 40783, 51735 40786, 51736 40790, 51739 40788, 51743 41788, 51741 41787, 51741 41789, 51741 41789, 51738 41793, 51733 41793, 52733 41794, 52737 41795, 52740 41794, 52744 41793, 52748 41789, 52749 41789, 52747 41789, 52752 41786, 52755 41790, 52755 41791, 52760 41796, 52756 42796, 52751 42797, 52754 42798, 52758 42795, 52759 42794, 52764 42797, 52768 42801, 52768 42801, 52771 42806, 52776 42810, 52776 42809, 52773 42811, 52776 42811, 52772 42812, 52773 42815, 52769 42815, 52768 42816, 52769 42821, 52773 42821, 52773 42821, 52777 42819, 52781 42815, 52781 42816, 52782 42819, 52778 42822, 52776 42822, 52779 42826, 52782 42827, 52783 42831, 52778 42833, 52782 42836, 54782 42839, 54782 42844, 2137 11205, 2142 11207, 2139 11208, 2142 11213, 2144 11217, 2149 11215, 2147 11217, 2147 11217, 2152 11222, 2152 11225, 2155 11229, 2159 13229, 2164 13232, 2169 13235, 2173 13236, 2169 13233, 2170 13237, 2173 13241, 2175 13243, 2170 13238, 2170 13239, 2175 13239, 2177 13238, 2179 13239, 2179 13238, 2181 13233, 2181 13230, 2182 13230, 2179 13230, 2179 13235, 2182 13235, 2183 10235, 2178 10237, 2179 10236, 2182 10239, 2187 10241, 2184 10244, 6184 10244, 6186 10248, 6184 10246, 6185 10247, 6187 10250, 6192 10248, 6196 10248, 6196 10251, 6194 10251, 6194 10256, 6197 10260, 6196 10264, 6197 9264, 6197 9264, 6197 9268, 6201 9273, 6206 9276, 6201 9272, 6203 9272, 6205 9269, 6210 9272, 6206 9274, 6206 9279, 6203 9283, 6203 9285, 6203 9290, 6208 9285, 6208 9281, 6204 9285, 6202 9289, 6204 9292, 6200 9294, 7200 9297, 7202 9301, 7203 9301, 7207 9302, 7211 9302, 7211 9303, 8211 9306, 8216 10306, 8220 10310, 8224 10312, 8228 10317, 8233 10317, 8237 10322, 8239 10322, 8239 10327, 8235 10330, 8235 10331, 8239 10329, 8240 10332, 8240 10334, 8236 10334, 11236 10336, 11238 10337, 11243 10341, 14243 10342, 14242 10342, 14239 10343, 14240 10341, 14239 10343, 14244 10343, 14248 10343, 14252 10343, 14252 10343, 14253 10341, 14256 10341, 14258 10338, 14258 10336, 14254 10340, 14257 10344, 14261 10346, 14264 10351, 11150 3163, 11155 3167, 11156 3166, 11156 3169, 11160 3171, 11163 3176, 11164 3179, 11164 3180, 11168 3183, 11168 3185, 11173 3189, 11178 3184, 11180 3183, 11178 3185, 11181 3187, 11176 3186, 52778 42822, 52780 42826, 52779 42826, 52784 42821, 52785 42826, 52786 42827, 52791 42830, 52791 42827, 56791 42832, 56788 42833, 56788 42836, 56791 42840, 56791 42839, 56787 42842, 56788 42847, 51788 42848, 51790 42850, 51792 42851, 51796 42846, 51798 42846, 51803 42850, 53803 42853, 53808 42853, 53811 42856, 53814 42854, 53819 42850, 53819 42852, 53820 42857, 53824 42860, 53825 42858, 53828 42862, 53827 42864, 53828 42864, 53828 42868, 53832 42872, 53837 42877, 53841 42877, 53843 42876, 53843 42880, 53843 42883, 53843 42888, 53838 42892, 53838 42893, 53838 44893, 53835 44893, 53837 44897, 53840 44901, 53844 44901, 53846 44904, 53846 44908, 53847 44909, 53852 44907, 53855 44908, 53860 44910, 53858 44911, 53863 44913, 53858 44917, 53860 44920, 53865 44920, 53870 44922, 53869 43922, 53871 43925, 53871 43923, 53869 43923, 53864 43922, 53862 43927, 53866 43932, 53871 43934, 53876 43937, 53876 43936, 53876 43936, 53877 43934, 53879 43932, 53880 43928, 53885 43931, 55885 43933, 55885 43929, 55881 43933, 55883 43933, 55886 43932, 55883 43932, 55884 43933, 55885 45933, 55885 45937, 55885 45940, 55886 45945, 55886 45945, 55888 45950, 55884 45952, 55885 45956, 55890 45960, 55892 45961, 55896 45957, 55894 45958, 55899 45954, 55895 45958, 55898 45960, 55894 45959, 55899 45963, 55901 45965, 55901 45965, 55896 45966, 55900 45961, 55895 49961, 55898 47961, 55896 47960, 55900 47964, 55903 47968, 55903 47971, 55903 47974, 55898 47977, 55900 47973, 55896 47978, 55897 47979, 55893 47980, 55898 47983, 55901 47988, 55904 47987, 55899 47991, 55901 47993, 55906 47996, 55906 47997, 55907 48001, 55904 48005, 55904 48007, 55909 48004, 55912 48002, 55917 48003, 55913 47998, 55908 48002, 55912 48007, 55916 48004, 55920 48004, 55916 48004, 55921 48004, 55923 48007, 55923 48011, 55926 48011, 55921 48014, 55924 48009, 55929 48013, 55930 48012, 55930 48012, 55932 48016, 55927 48016, 55927 48020, 54927 48018, 54924 48022, 54924 44022, 54928 44017, 54931 44016, 54934 44020, 55934 44021, 55937 44021, 55938 44024, 55939 44026, 55938 44024, 55941 44019, 55946 44022, 55947 44026, 55949 44027, 55952 44028, 55955 44024, 55958 44027, 53869 43923, 53873 43925, 52873 43925, 53873 43927, 53878 43927, 53883 43927, 53882 43931, 53884 43935, 53888 43940, 53886 43941, 53881 43938, 53881 43941, 53879 43943, 53880 43942, 53881 43946, 53882 43951, 53883 43952, 53886 45952, 53886 45953, 53884 45957, 53885 45958, 53880 45960, 53882 45957, 53887 45962, 53887 45962, 53888 45961, 53888 48961, 53888 48966, 53893 48966, 53894 48968, 53899 48969, 49899 48966, 49904 48969, 49908 48971, 49904 48971, 49906 48975, 49903 48971, 49906 48974, 54906 48975, 54906 48975, 54906 48979, 54911 48983, 54909 48979, 54912 48979, 54908 48975, 54911 48977, 54913 48979, 54917 48982, 54922 48982, 54925 48985, 54920 48988, 54923 48988, 56923 48988, 56928 48990, 56926 48985, 56931 48984, 56934 48983, 56934 48981, 56938 48983, 56939 48985, 56939 48986, 61939 48988, 61939 48984, 61936 51984, 61937 51985, 61937 51988, 61937 51988, 61933 51990, 5331 23399, 5333 23399, 5335 23394, 5339 23396, 5342 23399, 5347 27399, 5347 27401, 5352 27402, 5357 27403, 5358 27406, 6358 27409, 6362 27411, 6363 27410, 6366 27406, 6368 26406, 6373 26406, 6373 26406, 6374 26409, 6372 26409, 6377 26410, 6382 26415, 6387 26417, 6389 26418, 6390 26423, 6392 26423, 6393 26428, 6395 30428, 6392 30433, 6392 30436, 6392 30434, 6396 30438, 6396 30441, 6396 30445, 6398 30446, 6400 30443, 6401 30440, 6406 30439, 6407 30439, 6402 30439, 6407 30444, 6406 30447, 6407 30451, 6411 30451, 6413 30451, 6414 30452, 6419 30450, 6423 30454, 6420 30452, 6419 30448, 6420 30453, 6422 30455, 6427 30460, 6428 30460, 6427 30462, 6428 30462, 6428 34462, 6429 34463, 6434 39463, 6436 39466, 6436 39471, 6441 39474, 6445 39471, 6446 39472, 6451 39477, 6453 39480, 6454 39485, 6454 39483, 6454 39480, 8454 39480, 8458 39482, 8462 39484, 10462 39486, 10457 39486, 10458 39488, 10462 39488, 10465 39488, 10470 39490, 10475 39486, 10477 39488, 10477 39490, 10478 39492, 10479 39496, 10477 39498, 10482 39503, 10478 39505, 10481 39510, 10482 39514, 10477 39512, 10482 39517, 10483 39520, 10483 39520, 10487 39525, 10489 39526, 10492 39527, 10492 39524, 10495 39524, 10498 44524, 10493 44523, 10493 44528, 10494 44524, 10499 44529, 10501 44529, 10504 44531, 10502 44535, 10504 44539, 10508 44539, 10513 44536, 13513 44540, 13515 44537, 13512 44539, 13509 44544, 13513 44547, 13517 44552, 13519 44553, 13524 44554, 13527 42554, 13522 42555, 13524 42557, 13527 42556, 13531 42561, 13531 42562, 13526 42563, 13527 42563, 13527 42566, 13522 42568, 13525 42571, 15525 42573, 15525 42576, 15526 42581, 15531 42581, 15532 42586, 15534 42588, 15534 42592, 15533 42591, 15533 42596, 15532 42591, 15532 42587, 15535 42587, 15538 47587, 15534 47587, 15537 47591, 15536 47594, 15538 47598, 11538 47594, 11535 47594, 11531 47594, 11535 47596, 11535 47596, 11535 47597, 11539 47602, 11540 47607, 11540 47607, 11540 47609, 11543 47613, 11546 47617, 14546 47618, 14541 47614, 14539 47614, 14539 47618, 14537 50618, 14539 50623, 14541 50623, 14542 50627, 14540 50627, 14539 50623, 25601 26544, 25601 26545, 25601 26548, 25596 26546, 25601 26547, 25598 26548, 25599 26547, 25600 26547, 25595 26548, 25590 26546, 25595 26549, 25597 26548, 25598 26548, 25601 26545, 25596 26548, 25594 26553, 25595 26552, 25599 26553, 25598 26554, 25596 26555, 25592 26554, 25596 26558, 25599 26554, 25600 26556, 25595 26559, 25600 22559, 25601 22561, 25606 22563, 25607 22562, 25608 22566, 25607 22563, 25607 22568, 30607 22573, 30612 22575, 30612 22579, 30611 22579, 30611 22580, 30611 22585, 30607 22585, 30612 22587, 30612 22588, 30615 22583, 30615 22585, 30618 22581, 30621 22581, 30623 22584, 30623 22589, 30628 22594, 30630 22597, 30631 22602, 30628 22607, 30630 22610, 30631 22611, 30631 22608, 30629 22610, 30634 22612, 30635 22612, 30638 22616, 30643 17616, 30644 17618, 30649 17618, 30653 17619, 30656 17614, 30657 17611, 30660 17615, 30655 17614, 30656 17610, 30656 17611, 30661 17610, 30662 17615, 30660 17620, 30661 17620, 30666 17623, 30667 17625, 30667 17624, 30669 17625, 30673 17628, 30675 17628, 30675 17628, 30680 17631, 30677 17636, 30677 17639, 30680 17644, 30683 17647, 30688 17643, 30693 17645, 30698 19645, 30701 19644, 30702 19644, 30698 19649, 30700 19647, 30701 19649, 30704 19650, 30705 19653, 30701 19655, 30706 19652, 30708 19656, 30711 19657, 30711 19659, 30711 19659, 30714 19661, 30710 19662, 30707 19664, 30702 19666, 30703 19667, 30708 19668, 30713 19667, 30709 19671, 30706 19674, 30710 19676, 30711 19677, 30713 19677, 30713 19678, 30715 19682, 30720 19686, 30725 20686, 30723 20690, 30727 20695, 30728 20697, 30731 20699, 30730 20694, 30732 20696, 30735 20698, 30738 20696, 30738 20695, 30742 20698, 30743 20699, 30743 20701, 30748 20704, 30749 20706, 30752 20705, 30753 20702, 30755 24702, 30751 24705, 30750 24707, 30748 24708, 30749 29708, 30749 29709, 30751 29711, 30754 29716, 30759 29716, 30762 34716, 30762 34720, 30765 34720, 30761 34717, 30761 34721, 30765 34721, 30760 34721, 30759 34725, 30762 34730, 30760 34730, 30765 34731, 30765 34731, 30766 34731, 30761 34733, 30761 34736, 30764 34738, 30759 34739, 30763 34740, 30761 34740, 30764 34742, 30759 34737, 30762 34739, 30764 34741, 30762 34740, 30767 34737, 32767 34741, 32770 34741, 32767 34744, 32767 34746, 32770 34751, 32774 34755, 32774 34756, 32779 34753, 32784 34755, 32785 33755, 32785 33750, 36785 33753, 36785 33758, 36788 33760, 36789 33759, 36789 33762, 36793 33758, 36798 33758, 36803 33760, 36803 33762, 36803 33766, 36804 33769, 36804 33769, 36808 33774, 33808 33776, 33808 33781, 33811 33781, 33816 33784, 33816 33789, 33820 33786, 33823 33788, 33828 33785, 33824 33785, 33826 33787, 33824 33788, 33828 33791, 33825 33796, 33829 33799, 33830 33802, 33831 33803, 33835 33805, 33835 33805, 33838 33809, 33841 33813, 33844 33809, 33849 33814, 33847 32814, 33849 32812, 33851 32816, 33853 32819, 33851 32822, 33851 32826, 33849 32826, 33849 32830, 33852 32835, 33856 32840, 33859 32837, 33858 32832, 33861 32833, 33862 32836, 33859 32838, 33859 32834, 33857 32834, 33859 32834, 33857 32838, 33861 32833, 33861 32837, 33864 32840, 33866 32841, 33866 32843, 33868 32841, 33871 32839, 33874 32844, 33876 37844, 33881 37849, 33883 37854, 33883 37859, 33888 37860, 33893 37864, 33898 37864, 33895 37867, 33896 38867, 33898 38863, 28898 38868, 28901 39868, 33901 39873, 33898 39875, 33900 39879, 33904 39877, 33904 39879, 33909 39883, 33914 39888, 33910 39891, 33910 39892, 33907 39894, 33911 39899, 33913 39900, 33910 39904, 33914 39905, 33917 39906, 33917 39906, 33917 39906, 33912 39911, 33912 39908, 33916 39907, 33914 39910, 33918 39913, 33922 39913, 33924 39916, 33925 39920, 33930 39920, 33933 39922, 33934 39923, 33937 39919, 33938 39916, 33936 39913, 35936 39918, 35933 39919, 35937 39921, 35941 39924, 35941 39919, 35942 39915, 35946 39920, 35946 39915, 35946 39912, 35947 39908, 35947 39912, 35947 39916, 35952 39919, 35957 39921, 38957 39920, 38962 39925, 38964 39924, 38964 39924, 38969 39926, 38969 39928, 38972 39932, 38977 39932, 38975 39932, 38979 39935, 38982 39938, 38986 39940, 38984 39943, 38985 39946, 38987 39947, 38989 39949, 38994 41949, 38990 41954, 38991 41958, 38994 41962, 38994 41966, 38994 41969, 38995 41974, 38999 41974, 38999 41974, 38996 41978, 38996 41983, 38999 41983, 39001 41986, 38996 41984, 39000 41989, 39000 41988, 5336 23410, 5332 23410, 5327 23407, 9327 23408, 12327 23412, 12327 23412, 12324 23410, 13324 23415, 13327 23420, 13328 23416, 13324 23418, 13329 23423, 13330 23426, 13331 23429, 13335 23426, 13339 23428, 23493 35553, 23492 35548, 23496 35550, 23501 35552, 23497 35553, 21497 35557, 21492 35560, 21494 35562, 21494 35560, 21496 35563, 21496 35568, 21496 35570, 21501 35570, 21504 35566, 21504 35571, 17504 35572, 17508 35577, 17509 35578, 17513 35582, 17514 35587, 17515 35592, 18515 35595, 18516 35596, 18517 35598, 18515 35600, 16515 35605, 16515 37605, 16515 37606, 16513 37608, 16515 37613, 16516 37615, 16520 37620, 16524 34620, 16526 34617, 16530 34619, 16530 34624, 16535 34628, 16537 34631, 16540 34632, 16541 34634, 16541 34635, 16544 34632, 16544 34637, 16546 34642, 16549 38642, 16549 38644, 16545 38649, 16545 38644, 16542 38644, 16545 38644, 16544 38645, 16548 38650, 16543 38653, 16543 38649, 18543 38652, 18546 38652, 18546 38657, 18546 38660, 18551 38655, 18549 38655, 18552 38660, 18549 38662, 23549 38667, 23546 38668, 23550 38672, 23550 38674, 28550 38676, 28551 38673, 28551 38677, 28547 38673, 28551 38674, 28556 38674, 28559 38678, 28562 38673, 28564 38678, 28564 38673, 28563 38673, 28566 38675, 28571 38675, 38781 44703, 38782 44699, 38780 44702, 38785 44704, 38787 44704, 38783 44705, 38784 44700, 38788 44695, 38791 44696, 38796 44696, 38801 44692, 38801 44697, 38805 44701, 38810 44701, 38808 44701, 38808 44704, 38805 44706, 38805 44710, 38804 44711, 38809 48711, 38810 48711, 38808 48711, 38812 48716, 38812 48713, 38812 48715, 38812 48715, 38808 48711, 38804 48714, 38805 48710, 38807 48715, 38812 48715, 38807 48713, 38811 48714, 38811 48714, 38816 48711, 38817 48707, 38818 48707, 38818 48708, 38822 48708, 38824 48713, 38822 48714, 38820 48718, 38824 48720, 38824 48723, 38829 48726, 38830 48731, 38834 48729, 38832 48734, 38833 48730, 38834 48728, 38831 48732, 8433 35536, 8433 35541, 4433 35536, 4436 35541, 4440 35541, 4441 35537, 4445 35539, 4444 35534, 4447 35531, 4451 35531, 4455 35534, 4460 35534, 4461 39534, 4462 39535, 4463 39535, 4466 39535, 4470 39535, 4472 39538, 4467 39538, 4467 39536, 4471 39536, 4473 39541, 4468 39542, 4472 39543, 4475 39544, 4478 39544, 4482 39547, 4487 39552, 4485 39550, 4486 39551, 4486 39553, 4486 39555, 4488 39557, 4488 39558, 4489 39555, 4485 39557, 4488 39558, 4492 39560, 4495 39561, 4500 39565, 4496 39566, -4747 22349, -4750 22349, -4746 22352, -4742 22355, -4738 22360, -4739 22362, -4737 22365, -4732 22363, -4728 25363, -4728 25364, -4723 25364, -4725 25364, -4725 25365, -6725 25364, -6727 25369, -6728 25369, -6725 25369, -6729 25368, -6728 27368, -6725 27370, -6721 27371, -3721 27367, -3717 27372, -3718 27375, -3716 27370, -3715 27373, -3714 27373, -3712 27376, -3709 27374, -3710 27375, -3710 27374, -3708 27379, -3706 27381, -3705 27386, -3704 27389, -3704 27393, -3703 32393, -3702 32396, -3702 32396, -3697 32395, -3697 32399, -3692 32403, -3692 32404, -3693 32408, -3693 32412, -3691 32414, -3691 32414, -3695 32414, -3690 32417, -3689 32422, -3684 32424, -3681 32429, -3679 32424, -3676 32428, -3671 32428, -3674 32431, -3671 32430, -3669 32430, -3674 33430, -3676 33432, -3674 33432, -3677 33432, -3677 33437, -3675 33438, -3674 33442, -3679 33444, 1321 33448, 1323 33445, 1327 33448, 1331 33443, 1328 33448, 1328 33443, 1329 33443, 1329 33444, 1334 33448, 1335 33453, 1340 33457, 1340 33454, 1345 33454, 1349 33458, 1348 33461, 1348 33459, 1344 33463, 1343 33466, 1348 33466, 1349 33467, 1345 33467, 1346 33466, 1350 33461, 1349 33464, 1354 33468, 1358 33472, 1363 33473, 1365 33472, 1367 33473, 1370 33476, 1371 33479, -2629 33482, -2631 33487, -2627 33490, -2630 34490, -2626 36490, -2623 36492, -2619 36492, -2622 36492, -2620 36496, -2622 36495, -2627 36495, -2625 36500, -2621 36503, -2626 36506, -2629 36510, -2624 36510, -2620 36510, -2620 36513, -2617 36518, -2622 36516, -2619 36514, -2617 36514, -2617 36512, -2615 36516, -2613 36516, -2613 36517, -2613 36515, -2613 36510, -2610 36511, -2607 36515, -2604 37515, -2604 37512, -2608 37509, -2605 37512, -2600 37516, -2597 37516, -2593 37514, -2595 37515, -2590 37519, -2595 37518, -2590 37523, -2590 37528, -2590 37530, -2592 37525, -2592 37520, -2589 36520, -2586 36521, -2587 36517, -2584 36518, -2582 36518, -2581 36520, -2577 36518, -2576 36522, -2576 35522, -2573 35523, -2575 35523, -2576 35528, -2576 35533, -2576 35536, -2576 35538, -2578 35541, -2582 35545, -2584 35546, -2585 35548, -2583 35544, -2583 35548, -2582 35547, -2578 35552, -2574 35554, -2569 35557, -2565 35559, -2563 35564, -2558 35564, -2555 35568, -2551 35568, -5551 36568, -5546 36568, -5542 36569, -5545 36569, -5543 36574, -5540 36569, -5541 36570, -5541 36572, -5541 36574, -5538 36579, -5535 36581, -5533 36585, -5530 36584, -5526 36579, -5524 38579, -5524 38580, -5524 38575, -5520 38575, -5516 38580, -5512 42580, -5508 42585, -5510 42587, -5510 42586, -5505 42586, -5508 42589, -2508 42593, -2509 42596, -2506 42598, -2504 42601, -2501 42602, -2501 42607, -2496 42612, -2499 42615, -2498 42620, -2500 42617, -2500 42620, -4500 42620, -4500 42624, -4500 42626, -4504 42623, -4507 42625, -4509 42628, -4513 42629, -4508 42629, -4505 42632, -4500 42628, -4499 42633, -4503 45633, -4501 45634, -4497 45635, -4494 45634, -4495 45632, -4493 45634, -4492 46634, -4489 46638, -4485 46633, -4481 46635, 21338 40536, 21343 40537, 21348 40538, 21348 40540, 21347 40540, 21348 40540, 21347 40540, 21346 40542, 21349 40547, 21350 40547, 21353 40544, 21353 40546, 21350 40549, 21353 40550, 21354 40550, 21355 40550, 21360 40550, 21361 40549, 21361 40554, 21359 40559, 21364 40564, 21366 40559, 21365 40559, 21366 40564, 25366 40568, 25367 40570, 25370 40570, 25373 45570, 25374 45571, 25374 45566, 25378 45568, 25383 42568, 25387 42564, 25391 42568, 25391 42572, 25395 42576, 25392 42576, 28392 42573, 28391 42574, 28387 42578, 28388 42580, 28391 42581, 31391 42582, 31387 42586, 31389 42586, 31392 42582, 31393 42583, 31394 42580, 29394 42584, 29398 42586, 29400 43586, 29404 43588, 29408 43589, 29409 43591, 29413 43596, 29415 43598, 29416 43599, 25416 43604, 25414 43599, 25417 43603, 25422 43606, 25420 43608, 25425 43603, 25428 43603, 25431 43606, 25436 42606, 25431 42608, 25434 42604, 25437 42609, 25438 47609, 25442 50609, 25443 50614, 25441 50618, 25446 50621, 25449 50625, 25446 50628, 25446 50630, 25447 50631, 25452 50636, 25452 50632, 25453 50634, 25453 50636, 25456 50637, 25460 50641, 25464 50645, 25465 50644, 25465 51644, 25469 51648, 25471 51653, 25475 51654, 25476 51657, 25477 51658, 26477 51662, 26477 51666, 26476 51669, 26478 51669, 26483 51665, 26485 55665, 26487 55668, 30487 55671, 30487 55674, 30491 55675, 30491 55672, 30493 55674, 30494 55674, 30495 55679, 30499 55679, 30503 55675, 30505 55680, 30502 55681, 30500 55676, 30496 55679, 30501 55680, 30502 55680, 30507 55685, 30503 55688, 30498 55689, 30502 55689, 30504 55691, 30508 55696, 30509 55697, 30508 55696, 30513 55697, 30518 55698, 30516 55703, 30516 55705, 30514 55705, 34514 55709, 34518 55712, 34522 55708, 34520 56708, 34521 56708, 34522 56710, 34519 56710, 34517 56705, 34521 59705, 34524 59710, 34524 59712, 34524 59717, 34528 59719, 34530 59721, 34535 59716, 34540 59719, 34540 59721, 34543 59721, 34548 59724, 34550 59725, 34554 63725, 34549 63730, 34551 63732, 34556 63730, 34558 63730, 34559 63725, 34558 63729, 34563 63734, 34560 63734, 37560 63729, 37563 63733, 37567 63728, 37571 63724, 37575 63722, 37580 63726, 37579 63722, 37581 63724, 37581 63726, 37582 63723, 37582 63724, 37581 63728, 37576 63729, 37576 63731, 37578 63729, 37583 63733, 37585 63736, 37588 63736, 37592 63741, 37594 63738, 37599 63735, 37602 63734, 37598 63735, 37598 63737, 37602 63737, 37603 63739, 37598 63739, 37593 63736, 37598 63737, 37603 63742, 37604 63737, 37601 63742, 37596 63744, 37600 63748, 37605 63749, 37607 63751, 37609 63756, 37609 63760, 37605 63761, 37605 63765, 37606 63765, 37610 63762, 37611 63766, 37606 63768, 37606 63768, 41606 63769, 41602 63765, 41601 63765, 41602 63770, 41598 63770, 41601 63770, 41603 63774, 41606 63772, 41610 63772, 41613 63776, 41616 63771, 41611 63767, 41614 63769, 41617 63764, 38617 63768, 38617 63772, 38620 63772, 35620 63773, 35620 63778, 35619 63779, 35620 63780, 35615 63779, 35617 63784, 35614 63786, 35615 63783, 35616 63779, 35620 63778, 35621 63780, 35626 63782, 35626 63784, 35631 63789, 35631 63784, 35628 63785, 35626 63786, 35631 63788, 35636 63791, 35640 63786, 35636 63787, 35636 63782, 35635 63781, 35640 63786, 35643 63790, 35646 63795, 35650 63797, 35649 63797, 35651 63801, 35655 63805, 35656 63808, 35656 63808, 35658 63808, 35657 63810, 35660 63814, 35660 63809, 35664 63809, 35659 67809, 35660 67812, 35662 67815, 35666 67812, 35662 67807, 35660 67807, 35663 67807, 35665 67812, 35668 67814, 35672 67818, 35671 67817, 35671 67820, 37671 67824, 37666 67824, 2277 13367, 2280 16367, 2276 16367, 2277 16366, 2281 16366, 2284 16366, 2289 16370, 2286 16370, 4286 16370, 4288 16375, 4292 16379, 4296 18379, 4297 18381, 9297 18385, 9298 18385, 9301 18386, 9305 18383, 9307 19383, 9310 19379, 8310 19384, 8314 19384, 38748 37655, 38751 37656, 38756 37657, 38759 37660, 38755 37665, 38755 37665, 38760 37667, 38765 37668, 38765 42668, 38770 42670, 38767 42672, 38772 42668, 38769 42663, 38770 42663, 38775 42658, 38773 42663, 38777 42665, 41777 42667, 41780 42669, 41783 42673, 41784 42671, 41781 42673, 41786 42676, 41783 42676, 41785 42676, 41782 42676, 41785 42679, 41786 42679, 41790 42680, 41794 42681, 41794 42679, 41795 42684, 41795 42680, 41798 42685, 41803 42689, 41806 42688, 41808 42689, 41806 42694, 41804 42696, 41807 42700, 41802 42701, 41804 42702, 41806 42704, 41811 42708, 41815 42709, 36815 42712, 36815 42708, 36812 42707, 36813 42709, 40813 42710, 40817 46710, 40818 46712, 40822 46712, 40820 46716, 40824 46721, 40827 46724, 40831 46728, 40829 46731, 40833 46731, 40835 46735, 40831 46737, 40832 46737, 36832 46742, 36832 46745, 36836 46748, 36833 46753, 36828 46752, 36824 46752, 36826 46755, 36821 46759, 36825 46762, 36825 46766, 36826 46770, 36824 46773, 36828 46776, 36833 46778, 36830 42778, 36835 42780, 36835 42781, 36840 42786)')));
-BEGIN;
-
-DELETE FROM t1 WHERE p = 3;
-UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
-UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
-
-ROLLBACK;
-
-connection con1;
---echo # disable purge
-CREATE TABLE t0 (a INT) ENGINE=InnoDB;
-BEGIN; SELECT * FROM t0;
-
-connection default;
-DELETE FROM t1 WHERE p = 3;
-
-UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
-UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
-
-if ($index == 'spatial_none') {
- ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
-}
-
-if ($index == 'spatial_only') {
- eval ALTER TABLE t1 ADD INDEX prefix_idx (g($prefix_size));
-}
-
-if ($index == 'spatial_mixed') {
- ALTER TABLE t1 DROP INDEX spatial_idx, DROP INDEX prefix_idx;
-}
-
-connection con1;
---echo # enable purge
-COMMIT;
-
-connection default;
-DELETE FROM t1 WHERE p = 2;
-
---echo # wait for purge to process the update_undo records.
---source include/wait_innodb_all_purged.inc
-
-eval CREATE TABLE t2 (
- p INT PRIMARY KEY,
- g1 POINT NOT NULL,
- g2 POINT NOT NULL,
- g3 LINESTRING NOT NULL,
- g4 LINESTRING NOT NULL,
- g5 GEOMETRY NOT NULL,
- g6 GEOMETRY NOT NULL,
- SPATIAL KEY (g1),
- SPATIAL KEY (g2),
- SPATIAL KEY (g3),
- SPATIAL KEY (g4),
- SPATIAL KEY (g5),
- SPATIAL KEY (g6)
-) ENGINE=InnoDB ROW_FORMAT=$row_format;
-
-DROP TABLE t2;
-DROP TABLE t1;
-DROP TABLE t0;
diff --git a/mysql-test/include/innodb_row_format.combinations b/mysql-test/include/innodb_row_format.combinations
new file mode 100644
index 00000000000..fb94d61dd42
--- /dev/null
+++ b/mysql-test/include/innodb_row_format.combinations
@@ -0,0 +1,8 @@
+[redundant]
+innodb_default_row_format=redundant
+
+[compact]
+innodb_default_row_format=compact
+
+[dynamic]
+innodb_default_row_format=dynamic
diff --git a/mysql-test/include/innodb_row_format.inc b/mysql-test/include/innodb_row_format.inc
new file mode 100644
index 00000000000..8c6357e57d6
--- /dev/null
+++ b/mysql-test/include/innodb_row_format.inc
@@ -0,0 +1,4 @@
+# The goal of including this file is to enable innodb_default_row_format
+# combinations (see include/innodb_row_format.combinations)
+
+--source include/have_innodb.inc
diff --git a/mysql-test/include/install_semisync.inc b/mysql-test/include/install_semisync.inc
deleted file mode 100644
index 9cc6df2072a..00000000000
--- a/mysql-test/include/install_semisync.inc
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
-#
---let $include_filename= install_semisync.inc
---source include/begin_include_file.inc
-
---source include/not_embedded.inc
---source include/have_semisync_plugin.inc
-
---connection master
-
---disable_query_log
---let $value = query_get_value(show variables like 'rpl_semi_sync_master_enabled', Value, 1)
-if ($value == No such row)
-{
- SET sql_log_bin = 0;
- install plugin rpl_semi_sync_master soname 'semisync_master';
- SET GLOBAL rpl_semi_sync_master_enabled = 1;
- SET sql_log_bin = 1;
-}
---enable_query_log
-
---connection slave
---source include/stop_slave_io.inc
-
---disable_query_log
---let $value= query_get_value(show variables like 'rpl_semi_sync_slave_enabled', Value, 1)
-if ($value == No such row)
-{
- SET sql_log_bin = 0;
- install plugin rpl_semi_sync_slave soname 'semisync_slave';
- SET GLOBAL rpl_semi_sync_slave_enabled = 1;
- SET sql_log_bin = 1;
-}
-START SLAVE IO_THREAD;
---source include/wait_for_slave_io_to_start.inc
---enable_query_log
-
---source include/end_include_file.inc
diff --git a/mysql-test/include/kill_and_restart_mysqld.inc b/mysql-test/include/kill_and_restart_mysqld.inc
deleted file mode 100644
index b67fb7350b4..00000000000
--- a/mysql-test/include/kill_and_restart_mysqld.inc
+++ /dev/null
@@ -1,15 +0,0 @@
-if (!$restart_parameters)
-{
- let $restart_parameters = restart;
-}
-
---let $_server_id= `SELECT @@server_id`
---let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
-
---echo # Kill and $restart_parameters
---exec echo "$restart_parameters" > $_expect_file_name
---shutdown_server 0
---source include/wait_until_disconnected.inc
---enable_reconnect
---source include/wait_until_connected_again.inc
---disable_reconnect
diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql
index 71c693961c1..b7b2a316dfb 100644
--- a/mysql-test/include/mtr_warnings.sql
+++ b/mysql-test/include/mtr_warnings.sql
@@ -224,6 +224,12 @@ INSERT INTO global_suppressions VALUES
("Slave I/O: Setting @slave_gtid_ignore_duplicates failed with error.*"),
("Slave I/O: Setting @slave_until_gtid failed with error.*"),
("Slave I/O: Get master GTID position failed with error.*"),
+
+ /*
+ MDEV-12501 -- set --maturity-level by default
+ */
+ ("Plugin .* is of maturity level .* while the server is .*"),
+
("THE_LAST_SUPPRESSION")||
diff --git a/mysql-test/include/not_embedded.inc b/mysql-test/include/not_embedded.inc
index 88185af3b15..4c168f71979 100644
--- a/mysql-test/include/not_embedded.inc
+++ b/mysql-test/include/not_embedded.inc
@@ -2,9 +2,3 @@
# suite.pm will make sure that all tests including this file
# will be skipped unless this is an embedded test run
#
-# The test below is redundant
-
-if (`select version() like '%embedded%'`) {
- This should never happen;
-}
-
diff --git a/mysql-test/include/not_windows.inc b/mysql-test/include/not_windows.inc
index 9240271077a..08373095438 100644
--- a/mysql-test/include/not_windows.inc
+++ b/mysql-test/include/not_windows.inc
@@ -1,4 +1,4 @@
---require r/not_windows.require
-disable_query_log;
-select convert(@@version_compile_os using latin1) NOT IN ("Win32","Win64","Windows") as "TRUE";
-enable_query_log;
+#
+# suite.pm will make sure that all tests including this file
+# will be skipped unless this is on Windows
+#
diff --git a/mysql-test/include/rpl_events.inc b/mysql-test/include/rpl_events.inc
deleted file mode 100644
index 0effa8c4e5c..00000000000
--- a/mysql-test/include/rpl_events.inc
+++ /dev/null
@@ -1,159 +0,0 @@
-##################################################################
-# Author: Giuseppe, Chuck Bell #
-# Date: 17-January-2007 #
-# Purpose: To test that event effects are replicated #
-# in both row based and statement based format #
-##################################################################
-
---disable_warnings
-DROP EVENT IF EXISTS test.justonce;
-drop table if exists t1,t2;
---enable_warnings
-
-# first, we need a table to record something from an event
-
-eval CREATE TABLE `t1` (
- `id` INT(10) UNSIGNED NOT NULL,
- `c` VARCHAR(50) NOT NULL,
- `ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`)
-) ENGINE=$engine_type DEFAULT CHARSET=utf8;
-
-INSERT INTO t1 (id, c) VALUES (1, 'manually');
-
-# We create the event so that it inserts exactly 1 row in the table
-# A recuring event is used so that we can be sure the event will
-# fire regardless of timing delays on the server. Otherwise, it is
-# possible for the event to timeout before it has inserted a row.
---echo "Creating event test.justonce on the master"
-CREATE EVENT test.justonce ON SCHEDULE EVERY 2 SECOND DO
- INSERT IGNORE INTO t1 (id, c) VALUES (2, 'from justonce');
-
-# Show the event is alive and present on master
---echo "Checking event is active on master"
-SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
-
-# Wait until event has fired. We know this because t1 will contain
-# the row from the event.
-let $wait_condition=
- SELECT COUNT(*) = 1 FROM t1 WHERE c = 'from justonce';
---source include/wait_condition.inc
-
-# check that table t1 contains something
---echo "Checking event data on the master"
-let $events_done=`SELECT count(*) FROM t1 id`;
---disable_query_log
-eval SELECT $events_done > 0 as ONE;
---enable_query_log
-
-sync_slave_with_master;
-
---echo "Checking event data on the slave"
---disable_query_log
-eval SELECT count(*) - $events_done as ZERO FROM t1 id;
---enable_query_log
-
---echo "Checking event is inactive on slave"
-SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
-
-# Create an event on the slave and check to see what the originator is.
---echo "Dropping event test.slave_once on the slave"
---disable_warnings
-DROP EVENT IF EXISTS test.slave_once;
---enable_warnings
-
-# Create an event on slave and check its state. An event shouldn't be executed
-# so set start time in 1 hour.
-CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
- INSERT IGNORE INTO t1(id, c) VALUES (3, 'from slave_once');
-
---echo "Checking event status on the slave for originator value = slave's server_id"
-SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_once';
-
---echo "Dropping event test.slave_once on the slave"
---disable_warnings
-DROP EVENT IF EXISTS test.slave_once;
---enable_warnings
-
-connection master;
-
-# BUG#20384 - disable events on slave
---echo "Dropping event test.justonce on the master"
---disable_warnings
-DROP EVENT IF EXISTS test.justonce;
---enable_warnings
-
-# Create an event on master and check its state on slave. An event shouldn't be executed
-# so set start time in 1 hour. Check that changes of event statement replicated to slave
-
---echo "Creating event test.er on the master"
-CREATE EVENT test.er ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
- INSERT IGNORE INTO t1(id, c) VALUES (4, 'from er');
-
---echo "Checking event status on the master"
-SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
-
-sync_slave_with_master;
-
---echo "Checking event status on the slave"
-SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
-
-connection master;
---echo "Altering event test.er on the master"
-ALTER EVENT test.er ON SCHEDULE EVERY 5 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
- INSERT IGNORE INTO t1(id, c) VALUES (5, 'from alter er');
-
---echo "Checking event status on the master"
-SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
-
-sync_slave_with_master;
-
---echo "Checking event status on the slave"
-SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
-
-connection master;
---echo "Dropping event test.er on the master"
-DROP EVENT test.er;
-
---echo "Checking event status on the master"
-SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
-
---disable_info
-
-sync_slave_with_master;
-
---echo "Checking event status on the slave"
-SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
-
-# test the DISABLE ON SLAVE for setting event SLAVESIDE_DISABLED as status
-# on CREATE EVENT
-
-# Create an event on slave and check its status. An event shouldn't be executed
-# so set start time in 1 hour.
-
---echo "Creating event test.slave_terminate on the slave"
-CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
- INSERT IGNORE INTO t1(id, c) VALUES (6, 'from slave_terminate');
-
---echo "Checking event status on the slave"
-SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_terminate';
-
---echo "Dropping event test.slave_terminate on the slave"
-DROP EVENT test.slave_terminate;
-
---echo "Creating event test.slave_terminate with DISABLE ON SLAVE on the slave"
-CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND DISABLE ON SLAVE DO
- INSERT IGNORE INTO t1(c) VALUES (7, 'from slave_terminate');
-
---echo "Checking event status on the slave"
-SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_terminate';
-
---echo "Dropping event test.slave_terminate on the slave"
-DROP EVENT test.slave_terminate;
-
---echo "Cleanup"
-connection master;
-DROP TABLE t1;
-sync_slave_with_master;
-connection master;
-
diff --git a/mysql-test/include/show_binlog_events.inc b/mysql-test/include/show_binlog_events.inc
index b2462e0d1b1..57fe1ffe0e3 100644
--- a/mysql-test/include/show_binlog_events.inc
+++ b/mysql-test/include/show_binlog_events.inc
@@ -7,7 +7,7 @@
# [--let $binlog_file= [<FILENAME> | LAST]]
# [--let $binlog_start= <POSITION> ]
# [--let $binlog_limit= 1, 3 ]
-# [--let $keep_gtid_events= 1]
+# [--let $skip_checkpoint_events= 1]
# --source include/show_binlog_events.inc
#
# Parameters:
@@ -26,12 +26,6 @@
# Limit for the 'LIMIT' clause of SHOW BINLOG EVENTS, i.e.:
# $binlog_limit= 3 -- print three events
# $binlog_limit= 4, 3 -- skip four events, print the three next events
-#
-# $keep_gtid_events
-# By default, Gtid_log_event and Previous_gtid_log_event are
-# filtered out, so that the output is independent of whether GTIDs
-# are enabled or not. If this flag is set, events are kept but
-# the actual GTID values are masked out.
--let $include_filename= show_binlog_events.inc
--source include/begin_include_file.inc
diff --git a/mysql-test/include/show_events.inc b/mysql-test/include/show_events.inc
index 368cfc9e3a7..9ee01f73999 100644
--- a/mysql-test/include/show_events.inc
+++ b/mysql-test/include/show_events.inc
@@ -104,8 +104,15 @@ let $script=
s{DOLLARmysqltest_vardir}{MYSQLTEST_VARDIR}g;
||
--let $pre_script= my DOLLARmysqltest_vardir = DOLLARENV{'MYSQLTEST_VARDIR'};
+
--delimiter ;
+if ($skip_checkpoint_events)
+{
+ let $filter_script=Binlog_checkpoint;
+}
+
+
#--let $select_columns= 1 3 6
--let $input_file= $output_file
--source include/filter_file.inc
diff --git a/mysql-test/include/show_gtid_list.inc b/mysql-test/include/show_gtid_list.inc
new file mode 100644
index 00000000000..96f813f180c
--- /dev/null
+++ b/mysql-test/include/show_gtid_list.inc
@@ -0,0 +1,15 @@
+# ==== Purpose ====
+#
+# Extract Gtid_list info from SHOW BINLOG EVENTS output masking
+# non-deterministic fields.
+#
+# ==== Usage ====
+#
+# [--let $binlog_file=filename
+#
+if ($binlog_file)
+{
+ --let $_in_binlog_file=in '$binlog_file'
+}
+--replace_column 2 # 5 #
+--eval show binlog events $_in_binlog_file limit 1,1
diff --git a/mysql-test/include/truncate_file.inc b/mysql-test/include/truncate_file.inc
index 2326d6c0b94..fe88cb05bd9 100644
--- a/mysql-test/include/truncate_file.inc
+++ b/mysql-test/include/truncate_file.inc
@@ -1,16 +1,11 @@
# truncate a giving file, all contents of the file are be cleared
-if (!$file)
+if (!$TRUNCATE_FILE)
{
- --echo Please assign a file name to $file!!
- exit;
+ die TRUNCATE_FILE is not set;
}
-let TRUNCATE_FILE= $file;
-
perl;
-use Env;
-Env::import('TRUNCATE_FILE');
-open FILE, '>', $TRUNCATE_FILE || die "Can not open file $file";
+open FILE, '>', $ENV{TRUNCATE_FILE} or die "open(>$ENV{TRUNCATE_FILE}): $!";
close FILE;
EOF
diff --git a/mysql-test/include/uninstall_semisync.inc b/mysql-test/include/uninstall_semisync.inc
deleted file mode 100644
index 0a4c55fa4f2..00000000000
--- a/mysql-test/include/uninstall_semisync.inc
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
-#
---let $include_filename= uninstall_semisync.inc
---source include/begin_include_file.inc
-
---disable_query_log
---connection slave
---source include/stop_slave_io.inc
-
-# Uninstall rpl_semi_sync_slave first
---disable_warnings
-UNINSTALL PLUGIN rpl_semi_sync_slave;
-
---connection master
-# After BUG#17638477 fix, uninstallation of rpl_semi_sync_master
-# is not allowed when there are semi sync slaves. Hence kill
-# all dump threads before uninstalling it.
-SET GLOBAL rpl_semi_sync_master_enabled = OFF;
---source include/stop_dump_threads.inc
-UNINSTALL PLUGIN rpl_semi_sync_master;
---enable_warnings
-
---connection slave
-START SLAVE IO_THREAD;
---source include/wait_for_slave_io_to_start.inc
---enable_query_log
-
---source include/end_include_file.inc
diff --git a/mysql-test/include/wait_innodb_all_purged.inc b/mysql-test/include/wait_innodb_all_purged.inc
deleted file mode 100644
index c5edc5937da..00000000000
--- a/mysql-test/include/wait_innodb_all_purged.inc
+++ /dev/null
@@ -1,60 +0,0 @@
-# include/wait_innodb_all_purged.inc
-#
-# SUMMARY
-#
-# Waits until purged all undo records of innodb, or operation times out.
-#
-# USAGE
-#
-# --source include/wait_innodb_all_purged.inc
-#
---source include/have_innodb.inc
---source include/have_debug.inc
-
---disable_query_log
-
-let $wait_counter_init= 300;
-if ($wait_timeout)
-{
- let $wait_counter_init= `SELECT $wait_timeout * 10`;
-}
-# Reset $wait_timeout so that its value won't be used on subsequent
-# calls, and default will be used instead.
-let $wait_timeout= 0;
-
-let $wait_counter= $wait_counter_init;
-
-# Keep track of how many times the wait condition is tested
-let $wait_condition_reps= 0;
-let $prev_trx_age= 0;
-while ($wait_counter)
-{
---disable_warnings
- let $trx_age = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS
-WHERE VARIABLE_NAME = 'INNODB_PURGE_TRX_ID_AGE';`;
---enable_warnings
-
- if ($trx_age != $prev_trx_age)
- {
- let $wait_counter= $wait_counter_init;
- let $prev_trx_age= $trx_age;
- }
-
- let $success= `SELECT $trx_age < 1`;
- inc $wait_condition_reps;
- if ($success)
- {
- let $wait_counter= 0;
- }
- if (!$success)
- {
- real_sleep 0.1;
- dec $wait_counter;
- }
-}
-if (!$success)
-{
- echo Timeout in wait_innodb_all_purged.inc for INNODB_PURGE_TRX_ID_AGE = $trx_age;
-}
-
---enable_query_log
diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm
index 3260a6ed593..0387d09b89c 100644
--- a/mysql-test/lib/My/SafeProcess.pm
+++ b/mysql-test/lib/My/SafeProcess.pm
@@ -84,7 +84,7 @@ sub is_child {
}
-my @safe_process_cmd;
+our @safe_process_cmd;
my $safe_kill;
my $bindir;
diff --git a/mysql-test/lib/My/SafeProcess/Base.pm b/mysql-test/lib/My/SafeProcess/Base.pm
index 1ac0120a735..c5ac2ab51c2 100644
--- a/mysql-test/lib/My/SafeProcess/Base.pm
+++ b/mysql-test/lib/My/SafeProcess/Base.pm
@@ -186,8 +186,10 @@ sub create_process {
# it and any childs(that hasn't changed group themself)
setpgrp(0,0) if $opts{setpgrp};
- if ( $output and !open(STDOUT, $open_mode, $output) ) {
- croak("can't redirect STDOUT to '$output': $!");
+ if ( $output ) {
+ close STDOUT;
+ open(STDOUT, $open_mode, $output)
+ or croak "can't redirect STDOUT to '$output': $!";
}
if ( $error ) {
@@ -196,8 +198,10 @@ sub create_process {
croak("can't dup STDOUT: $!");
}
}
- elsif ( ! open(STDERR, $open_mode, $error) ) {
- croak("can't redirect STDERR to '$error': $!");
+ else {
+ close STDERR;
+ open(STDERR, $open_mode, $error)
+ or croak "can't redirect STDERR to '$error': $!";
}
}
diff --git a/mysql-test/lib/My/SafeProcess/CMakeLists.txt b/mysql-test/lib/My/SafeProcess/CMakeLists.txt
index ff842f3468f..12e3599223e 100644
--- a/mysql-test/lib/My/SafeProcess/CMakeLists.txt
+++ b/mysql-test/lib/My/SafeProcess/CMakeLists.txt
@@ -13,7 +13,16 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-IF (NOT INSTALL_MYSQLTESTDIR)
+
+ IF (WIN32)
+ ADD_EXECUTABLE(my_safe_process safe_process_win.cc)
+ ADD_EXECUTABLE(my_safe_kill safe_kill_win.cc)
+ TARGET_LINK_LIBRARIES(my_safe_kill dbghelp psapi)
+ELSE()
+ ADD_EXECUTABLE(my_safe_process safe_process.cc)
+ENDIF()
+
+IF(NOT INSTALL_MYSQLTESTDIR)
RETURN()
ENDIF()
@@ -22,14 +31,9 @@ SET(INSTALL_ARGS
COMPONENT Test
)
+INSTALL(TARGETS my_safe_process ${INSTALL_ARGS})
IF (WIN32)
- MYSQL_ADD_EXECUTABLE(my_safe_process safe_process_win.cc ${INSTALL_ARGS})
- MYSQL_ADD_EXECUTABLE(my_safe_kill safe_kill_win.cc ${INSTALL_ARGS})
- TARGET_LINK_LIBRARIES(my_safe_kill dbghelp psapi)
-ELSE()
- MYSQL_ADD_EXECUTABLE(my_safe_process safe_process.cc ${INSTALL_ARGS})
+ INSTALL(TARGETS my_safe_kill ${INSTALL_ARGS})
ENDIF()
-INSTALL(FILES Base.pm
- DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" COMPONENT Test
-)
+INSTALL(FILES Base.pm ${INSTALL_ARGS})
diff --git a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
index bb884cba11e..68a069ad319 100644
--- a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
@@ -26,7 +26,20 @@
#include <signal.h>
#include <stdlib.h>
#include <psapi.h>
+
+#ifdef _MSC_VER
+/* Silence warning in OS header dbghelp.h */
+#pragma warning(push)
+#pragma warning(disable : 4091)
+#endif
+
#include <dbghelp.h>
+
+#ifdef _MSC_VER
+/* Silence warning in OS header dbghelp.h */
+#pragma warning(pop)
+#endif
+
#include <tlhelp32.h>
#include <vector>
@@ -59,23 +72,24 @@ void dump_single_process(DWORD pid)
char path[MAX_PATH];
char working_dir[MAX_PATH];
char tmpname[MAX_PATH];
+ char *filename= 0;
process= OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (!process)
{
- fprintf(stderr, "safe_kill : cannot open process pid=%u to create dump, last error %u\n",
+ fprintf(stderr, "safe_kill : cannot open process pid=%lu to create dump, last error %lu\n",
pid, GetLastError());
goto exit;
}
if (QueryFullProcessImageName(process, 0, path, &size) == 0)
{
- fprintf(stderr, "safe_kill : cannot read process path for pid %u, last error %u\n",
+ fprintf(stderr, "safe_kill : cannot read process path for pid %lu, last error %lu\n",
pid, GetLastError());
goto exit;
}
- char *filename= strrchr(path, '\\');
+ filename= strrchr(path, '\\');
if (filename)
{
filename++;
@@ -102,17 +116,17 @@ void dump_single_process(DWORD pid)
{
if (!GetTempFileName(".", filename, 0, tmpname))
{
- fprintf(stderr, "GetTempFileName failed, last error %u", GetLastError());
+ fprintf(stderr, "GetTempFileName failed, last error %lu", GetLastError());
goto exit;
}
- strncat(tmpname, ".dmp", sizeof(tmpname));
+ strncat_s(tmpname, ".dmp", sizeof(tmpname));
filename= tmpname;
}
if (!GetCurrentDirectory(MAX_PATH, working_dir))
{
- fprintf(stderr, "GetCurrentDirectory failed, last error %u", GetLastError());
+ fprintf(stderr, "GetCurrentDirectory failed, last error %lu", GetLastError());
goto exit;
}
@@ -121,14 +135,14 @@ void dump_single_process(DWORD pid)
if (file == INVALID_HANDLE_VALUE)
{
- fprintf(stderr, "safe_kill : CreateFile() failed for file %s, working dir %s, last error = %u\n",
+ fprintf(stderr, "safe_kill : CreateFile() failed for file %s, working dir %s, last error = %lu\n",
filename, working_dir, GetLastError());
goto exit;
}
if (!MiniDumpWriteDump(process, pid, file, MiniDumpNormal, 0, 0, 0))
{
- fprintf(stderr, "Failed to write minidump to %s, working dir %s, last error %u\n",
+ fprintf(stderr, "Failed to write minidump to %s, working dir %s, last error %lu\n",
filename, working_dir, GetLastError());
goto exit;
}
@@ -200,7 +214,7 @@ int main(int argc, const char** argv )
if (!GetExitCodeProcess(process,&exit_code))
{
- fprintf(stderr, "GetExitCodeProcess failed, pid= %d, err= %d\n",
+ fprintf(stderr, "GetExitCodeProcess failed, pid= %lu, err= %lu\n",
pid, GetLastError());
exit(1);
}
@@ -218,7 +232,7 @@ int main(int argc, const char** argv )
Sleep(100);
else
{
- fprintf(stderr, "Failed to open shutdown_event '%s', error: %d\n",
+ fprintf(stderr, "Failed to open shutdown_event '%s', error: %lu\n",
safe_process_name, GetLastError());
exit(3);
}
@@ -226,7 +240,7 @@ int main(int argc, const char** argv )
if(SetEvent(shutdown_event) == 0)
{
- fprintf(stderr, "Failed to signal shutdown_event '%s', error: %d\n",
+ fprintf(stderr, "Failed to signal shutdown_event '%s', error: %lu\n",
safe_process_name, GetLastError());
CloseHandle(shutdown_event);
exit(4);
diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
index dca2faded71..e7fb0d69c91 100644
--- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
@@ -75,7 +75,7 @@ static void message(const char* fmt, ...)
static void die(const char* fmt, ...)
{
- DWORD last_err= GetLastError();
+ int last_err= GetLastError();
va_list args;
fprintf(stderr, "%s: FATAL ERROR, ", safe_process_name);
va_start(args, fmt);
@@ -106,7 +106,7 @@ static void die(const char* fmt, ...)
DWORD get_parent_pid(DWORD pid)
{
HANDLE snapshot;
- DWORD parent_pid= -1;
+ DWORD parent_pid= 0;
PROCESSENTRY32 pe32;
pe32.dwSize= sizeof(PROCESSENTRY32);
@@ -127,7 +127,7 @@ DWORD get_parent_pid(DWORD pid)
} while(Process32Next( snapshot, &pe32));
CloseHandle(snapshot);
- if (parent_pid == -1)
+ if (parent_pid == 0)
die("Could not find parent pid");
return parent_pid;
@@ -163,7 +163,7 @@ int main(int argc, const char** argv )
PROCESS_INFORMATION process_info= {0};
BOOL nocore= FALSE;
- sprintf(safe_process_name, "safe_process[%d]", pid);
+ sprintf(safe_process_name, "safe_process[%lu]", pid);
/* Create an event for the signal handler */
if ((shutdown_event=
@@ -298,7 +298,7 @@ int main(int argc, const char** argv )
BOOL process_created= FALSE;
BOOL jobobject_assigned= FALSE;
- for (int i=0; i < sizeof(create_flags)/sizeof(create_flags[0]); i++)
+ for (size_t i=0; i < sizeof(create_flags)/sizeof(create_flags[0]); i++)
{
process_created= CreateProcess(NULL, (LPSTR)child_args,
NULL,
diff --git a/mysql-test/lib/My/Tee.pm b/mysql-test/lib/My/Tee.pm
new file mode 100644
index 00000000000..ee82e6f45ae
--- /dev/null
+++ b/mysql-test/lib/My/Tee.pm
@@ -0,0 +1,23 @@
+package My::Tee;
+
+# see PerlIO::via
+
+our $copyfh;
+
+sub PUSHED
+{
+ open($copyfh, '>', "$::opt_vardir/log/stdout.log")
+ or die "open(>$::opt_vardir/log/stdout.log): $!"
+ unless $copyfh;
+ bless { }, shift;
+}
+
+sub WRITE
+{
+ my ($obj, $buf, $fh) = @_;
+ print $fh $buf;
+ print $copyfh $buf;
+ return length($buf);
+}
+
+1;
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 9f83d6c9d6e..5ee05f3f606 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -91,6 +91,7 @@ use My::Platform;
use My::SafeProcess;
use My::ConfigFactory;
use My::Options;
+use My::Tee;
use My::Find;
use My::SysInfo;
use My::CoreDump;
@@ -197,6 +198,7 @@ my @DEFAULT_SUITES= qw(
sql_sequence-
unit-
vcol-
+ versioning-
wsrep-
galera-
);
@@ -220,6 +222,7 @@ our @opt_extra_mysqld_opt;
our @opt_mysqld_envs;
my $opt_stress;
+my $opt_tail_lines= 20;
my $opt_dry_run;
@@ -328,6 +331,8 @@ my %mysqld_logs;
my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions.
my $warn_seconds = 60;
+my $rebootstrap_re= '--innodb[-_](?:page[-_]size|checksum[-_]algorithm|undo[-_]tablespaces|log[-_]group[-_]home[-_]dir|data[-_]home[-_]dir)|data[-_]file[-_]path';
+
sub testcase_timeout ($) {
my ($tinfo)= @_;
if (exists $tinfo->{'case-timeout'}) {
@@ -385,6 +390,11 @@ sub main {
initialize_servers();
init_timers();
+ unless (IS_WINDOWS) {
+ binmode(STDOUT,":via(My::Tee)") or die "binmode(STDOUT, :via(My::Tee)):$!";
+ binmode(STDERR,":via(My::Tee)") or die "binmode(STDERR, :via(My::Tee)):$!";
+ }
+
mtr_report("Checking supported features...");
executable_setup();
@@ -432,16 +442,21 @@ sub main {
my $num_tests= @$tests;
if ( $opt_parallel eq "auto" ) {
# Try to find a suitable value for number of workers
- my $sys_info= My::SysInfo->new();
-
- $opt_parallel= $sys_info->num_cpus();
- for my $limit (2000, 1500, 1000, 500){
- $opt_parallel-- if ($sys_info->min_bogomips() < $limit);
+ if (IS_WINDOWS)
+ {
+ $opt_parallel= $ENV{NUMBER_OF_PROCESSORS} || 1;
+ }
+ else
+ {
+ my $sys_info= My::SysInfo->new();
+ $opt_parallel= $sys_info->num_cpus();
+ for my $limit (2000, 1500, 1000, 500){
+ $opt_parallel-- if ($sys_info->min_bogomips() < $limit);
+ }
}
my $max_par= $ENV{MTR_MAX_PARALLEL} || 8;
$opt_parallel= $max_par if ($opt_parallel > $max_par);
$opt_parallel= $num_tests if ($opt_parallel > $num_tests);
- $opt_parallel= 1 if (IS_WINDOWS and $sys_info->isvm());
$opt_parallel= 1 if ($opt_parallel < 1);
mtr_report("Using parallel: $opt_parallel");
}
@@ -1204,6 +1219,7 @@ sub command_line_setup {
'report-times' => \$opt_report_times,
'result-file' => \$opt_resfile,
'stress=s' => \$opt_stress,
+ 'tail-lines=i' => \$opt_tail_lines,
'dry-run' => \$opt_dry_run,
'help|h' => \$opt_usage,
@@ -1585,6 +1601,7 @@ sub command_line_setup {
$opt_manual_debug || $opt_dbx || $opt_client_dbx || $opt_manual_dbx ||
$opt_debugger || $opt_client_debugger )
{
+ $ENV{ASAN_OPTIONS}= 'abort_on_error=1:'.($ENV{ASAN_OPTIONS} || '');
if ( using_extern() )
{
mtr_error("Can't use --extern when using debugger");
@@ -2790,10 +2807,12 @@ sub mysql_server_start($) {
{
# Some InnoDB options are incompatible with the default bootstrap.
# If they are used, re-bootstrap
- if ( $extra_opts and
- "@$extra_opts" =~ /--innodb[-_](?:page[-_]size|checksum[-_]algorithm|undo[-_]tablespaces|log[-_]group[-_]home[-_]dir|data[-_]home[-_]dir)/ )
+ my @rebootstrap_opts;
+ @rebootstrap_opts = grep {/$rebootstrap_re/o} @$extra_opts if $extra_opts;
+ if (@rebootstrap_opts)
{
- mysql_install_db($mysqld, undef, $extra_opts);
+ mtr_verbose("Re-bootstrap with @rebootstrap_opts");
+ mysql_install_db($mysqld, undef, \@rebootstrap_opts);
}
else {
# Copy datadir from installed system db
@@ -3172,6 +3191,9 @@ sub mysql_install_db {
mtr_appendfile_to_file("$sql_dir/mysql_performance_tables.sql",
$bootstrap_sql_file);
+ # Don't install anonymous users
+ mtr_tofile($bootstrap_sql_file, "set \@skip_auth_anonymous=1;\n");
+
# Add the mysql system tables initial data
# for a production system
mtr_appendfile_to_file("$sql_dir/mysql_system_tables_data.sql",
@@ -3206,10 +3228,6 @@ sub mysql_install_db {
sql_to_bootstrap($text));
}
- # Remove anonymous users
- mtr_tofile($bootstrap_sql_file,
- "DELETE FROM mysql.user where user= '';\n");
-
# Create mtr database
mtr_tofile($bootstrap_sql_file,
"CREATE DATABASE mtr CHARSET=latin1;\n");
@@ -3755,14 +3773,32 @@ sub run_testcase ($$) {
$ENV{'MTR_TEST_NAME'} = $tinfo->{name};
resfile_report_test($tinfo) if $opt_resfile;
- # Allow only alpanumerics pluss _ - + . in combination names,
- # or anything beginning with -- (the latter comes from --combination)
- my $combination= $tinfo->{combination};
- if ($combination && $combination !~ /^\w[-\w\.\+]*$/
- && $combination !~ /^--/)
+ for my $key (grep { /^MTR_COMBINATION/ } keys %ENV)
+ {
+ delete $ENV{$key};
+ }
+
+ if (ref $tinfo->{combinations} eq 'ARRAY')
+ {
+ for (my $i = 0; $i < @{$tinfo->{combinations}}; ++$i )
+ {
+ my $combination = $tinfo->{combinations}->[$i];
+ # Allow only alphanumerics plus _ - + . in combination names,
+ # or anything beginning with -- (the latter comes from --combination)
+ if ($combination && $combination !~ /^\w[-\w\.\+]*$/
+ && $combination !~ /^--/)
+ {
+ mtr_error("Combination '$combination' contains illegal characters");
+ }
+ $ENV{"MTR_COMBINATION_". uc(${combination})} = 1;
+ }
+ $ENV{"MTR_COMBINATIONS"} = join(',', @{$tinfo->{combinations}});
+ }
+ elsif (exists $tinfo->{combinations})
{
- mtr_error("Combination '$combination' contains illegal characters");
+ die 'Unexpected type of $tinfo->{combinations}';
}
+
# -------------------------------------------------------
# Init variables that can change between each test case
# -------------------------------------------------------
@@ -4418,7 +4454,7 @@ sub extract_warning_lines ($$) {
qr|feedback plugin: failed to retrieve the MAC address|,
qr|Plugin 'FEEDBACK' init function returned error|,
qr|Plugin 'FEEDBACK' registration as a INFORMATION SCHEMA failed|,
- qr|'log-bin-use-v1-row-events' is MySQL 5.6 compatible option|,
+ qr|'log-bin-use-v1-row-events' is MySQL .* compatible option|,
qr|InnoDB: Setting thread \d+ nice to \d+ failed, current nice \d+, errno 13|, # setpriority() fails under valgrind
qr|Failed to setup SSL|,
qr|SSL error: Failed to set ciphers to use|,
@@ -4870,7 +4906,7 @@ sub report_failure_and_restart ($) {
$tinfo->{comment}.=
"The result from queries just before the failure was:".
"\n< snip >\n".
- mtr_lastlinesfromfile($log_file_name, 20)."\n";
+ mtr_lastlinesfromfile($log_file_name, $opt_tail_lines)."\n";
}
}
}
@@ -5017,7 +5053,7 @@ sub mysqld_start ($$) {
my $args;
mtr_init_args(\$args);
- if ( $opt_valgrind_mysqld )
+ if ( $opt_valgrind_mysqld and not $opt_gdb and not $opt_manual_gdb )
{
valgrind_arguments($args, \$exe);
}
@@ -5543,7 +5579,7 @@ sub start_mysqltest ($) {
mtr_add_arg($args, "--test-file=%s", $tinfo->{'path'});
# Number of lines of resut to include in failure report
- mtr_add_arg($args, "--tail-lines=20");
+ mtr_add_arg($args, "--tail-lines=%d", $opt_tail_lines);
if ( defined $tinfo->{'result_file'} ) {
mtr_add_arg($args, "--result-file=%s", $tinfo->{'result_file'});
@@ -5606,11 +5642,20 @@ sub gdb_arguments {
unlink($gdb_init_file);
# Put $args into a single string
- my $str= join(" ", @$$args);
$input = $input ? "< $input" : "";
- # write init file for mysqld or client
- mtr_tofile($gdb_init_file, "set args $str $input\n");
+ if ($type ne 'client' and $opt_valgrind_mysqld) {
+ my $v = $$exe;
+ my $vargs = [];
+ valgrind_arguments($vargs, \$v);
+ mtr_tofile($gdb_init_file, <<EOF);
+shell @My::SafeProcess::safe_process_cmd --parent-pid=`pgrep -x gdb` -- $v --vgdb-error=0 @$vargs @$$args &
+shell sleep 1
+target remote | /usr/lib64/valgrind/../../bin/vgdb
+EOF
+ } else {
+ mtr_tofile($gdb_init_file, "set args @$$args $input\n");
+ }
if ( $opt_manual_gdb )
{
@@ -6191,6 +6236,8 @@ Misc options
phases of test execution.
stress=ARGS Run stress test, providing options to
mysql-stress-test.pl. Options are separated by comma.
+ tail-lines=N Number of lines of the result to include in a failure
+ report.
Some options that control enabling a feature for normal test runs,
can be turned off by prepending 'no' to the option, e.g. --notimer.
@@ -6229,7 +6276,8 @@ sub xterm_stat {
my $done = $num_tests - $left;
my $spent = time - $^T;
- printf "\e];mtr: spent %s on %d tests. %s (%d tests) left\a",
+ syswrite STDOUT, sprintf
+ "\e];mtr: spent %s on %d tests. %s (%d tests) left\a",
time_format($spent), $done,
time_format($spent/$done * $left), $left;
}
diff --git a/mysql-test/r/1st.result b/mysql-test/r/1st.result
index f9e4b37aa94..cb2da3505f5 100644
--- a/mysql-test/r/1st.result
+++ b/mysql-test/r/1st.result
@@ -36,4 +36,5 @@ time_zone_leap_second
time_zone_name
time_zone_transition
time_zone_transition_type
+transaction_registry
user
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index b8f51ee25ad..9b394926489 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -303,12 +303,12 @@ Warning 1364 Field 'g' doesn't have a default value
Warning 1364 Field 'h' doesn't have a default value
Warning 1364 Field 'i' doesn't have a default value
show table status like 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 37 X X X X X X X X latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 37 X X X X X X X X latin1_swedish_ci NULL X N
alter table t1 modify a int;
show table status like 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 37 X X X X X X X X latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 37 X X X X X X X X latin1_swedish_ci NULL X N
drop table t1;
create table t1 (a int not null, b int not null, c int not null, d int not null, e int not null, f int not null, g int not null, h int not null,i int not null, primary key (a,b,c,d,e,f,g,i,h)) engine=MyISAM;
insert ignore into t1 (a) values(1);
@@ -322,8 +322,8 @@ Warning 1364 Field 'g' doesn't have a default value
Warning 1364 Field 'h' doesn't have a default value
Warning 1364 Field 'i' doesn't have a default value
show table status like 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 37 X X X X X X X X latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 37 X X X X X X X X latin1_swedish_ci NULL X N
drop table t1;
set names koi8r;
create table t1 (a char(10) character set koi8r);
@@ -2275,6 +2275,52 @@ t1 CREATE TABLE `t1` (
`c` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+create table t1 (i int);
+alter table t1 alter column if exists a set default 1;
+Warnings:
+Note 1054 Unknown column 'a' in 't1'
+alter table t1 alter column if exists a drop default;
+Warnings:
+Note 1054 Unknown column 'a' in 't1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+#
+# MDEV-13508 Check that rename of columns changes defaults, virtual
+# columns and constraints
+#
+create table t1 (a int, b int, check(a>b));
+alter table t1 change column a b int, change column b a int;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` int(11) DEFAULT NULL,
+ `a` int(11) DEFAULT NULL,
+ CONSTRAINT `CONSTRAINT_1` CHECK (`b` > `a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int primary key, b int, c int default (a+b) check (a+b>0),
+d int as (a+b),
+key (b),
+constraint test check (a+b > 1));
+alter table t1 change b new_b int not null, add column b char(1), add constraint new check (length(b) > 0);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `new_b` int(11) NOT NULL,
+ `c` int(11) DEFAULT (`a` + `new_b`) CHECK (`a` + `new_b` > 0),
+ `d` int(11) GENERATED ALWAYS AS (`a` + `new_b`) VIRTUAL,
+ `b` char(1) DEFAULT NULL,
+ PRIMARY KEY (`a`),
+ KEY `b` (`new_b`),
+ CONSTRAINT `test` CHECK (`a` + `new_b` > 1),
+ CONSTRAINT `new` CHECK (octet_length(`b`) > 0)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
#
# End of 10.2 tests
#
diff --git a/mysql-test/r/alter_user.result b/mysql-test/r/alter_user.result
index ac668bba8fa..76f811f18c7 100644
--- a/mysql-test/r/alter_user.result
+++ b/mysql-test/r/alter_user.result
@@ -1,25 +1,25 @@
select * from mysql.user where user = 'root' and host = 'localhost';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000
# Test syntax
#
# These 2 selects should have no changes from the first one.
alter user CURRENT_USER;
select * from mysql.user where user = 'root' and host = 'localhost';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000
alter user CURRENT_USER();
select * from mysql.user where user = 'root' and host = 'localhost';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000
create user foo;
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N N 0.000000
alter user foo;
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N N 0.000000
# Test super privilege works correctly with a read only database.
SET @start_read_only = @@global.read_only;
SET GLOBAL read_only=1;
@@ -50,44 +50,44 @@ Note 1396 Operation ALTER USER failed for 'boo'
# Test password related altering.
alter user foo identified by 'something';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N 0 0 0 0 N N 0.000000
alter user foo identified by 'something2';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *9CD58369E930E28C8996A89DB18B63294E6DC10C N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *9CD58369E930E28C8996A89DB18B63294E6DC10C N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N 0 0 0 0 N N 0.000000
alter user foo identified by password '*88C89BE093D4ECF72D039F62EBB7477EA1FD4D63';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N 0 0 0 0 N N 0.000000
alter user foo identified with 'somecoolplugin';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N 0 0 0 0 somecoolplugin N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N 0 0 0 0 somecoolplugin N N 0.000000
alter user foo identified with 'somecoolplugin' using 'somecoolpassphrase';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N 0 0 0 0 somecoolplugin somecoolpassphrase N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N 0 0 0 0 somecoolplugin somecoolpassphrase N N 0.000000
# Test ssl related altering.
alter user foo identified by 'something' require SSL;
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N ANY 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N ANY 0 0 0 0 N N 0.000000
alter user foo identified by 'something' require X509;
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N X509 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N X509 0 0 0 0 N N 0.000000
alter user foo identified by 'something'
require cipher 'text' issuer 'foo_issuer' subject 'foo_subject';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N SPECIFIED text foo_issuer foo_subject 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N SPECIFIED text foo_issuer foo_subject 0 0 0 0 N N 0.000000
# Test resource limits altering.
alter user foo with MAX_QUERIES_PER_HOUR 10
MAX_UPDATES_PER_HOUR 20
MAX_CONNECTIONS_PER_HOUR 30
MAX_USER_CONNECTIONS 40;
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N SPECIFIED text foo_issuer foo_subject 10 20 30 40 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N SPECIFIED text foo_issuer foo_subject 10 20 30 40 N N 0.000000
drop user foo;
diff --git a/mysql-test/r/analyze_stmt_privileges2.result b/mysql-test/r/analyze_stmt_privileges2.result
index 892791dd8f8..cf38810b598 100644
--- a/mysql-test/r/analyze_stmt_privileges2.result
+++ b/mysql-test/r/analyze_stmt_privileges2.result
@@ -1452,7 +1452,7 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f
DELETE FROM t1 USING t1, t2;
EXPLAIN DELETE FROM t1 USING t1, t2;
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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t2 ALL NULL NULL NULL NULL 3
ANALYZE DELETE FROM t1 USING t1, t2;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
@@ -1797,7 +1797,7 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f
DELETE FROM t1 USING t1, t2;
EXPLAIN DELETE FROM t1 USING t1, t2;
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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t2 ALL NULL NULL NULL NULL 3
ANALYZE DELETE FROM t1 USING t1, t2;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
@@ -1813,7 +1813,7 @@ SELECT * FROM t1;
a b
EXPLAIN SELECT * 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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
ANALYZE SELECT * FROM t1;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
diff --git a/mysql-test/r/binary_to_hex.result b/mysql-test/r/binary_to_hex.result
index 345df1de538..51ee5fa1c62 100644
--- a/mysql-test/r/binary_to_hex.result
+++ b/mysql-test/r/binary_to_hex.result
@@ -115,3 +115,7 @@ c9: 0x000000000101000000000000000000F03F000000000000F03F
#Print the table contents in html format
<TABLE BORDER=1><TR><TH>c1</TH><TH>c2</TH><TH>c3</TH><TH>c4</TH><TH>c5</TH><TH>c6</TH><TH>c7</TH><TH>c8</TH><TH>c9</TH></TR><TR><TD>0x74696E79626C6F622D74657874207265616461626C65</TD><TD>0x626C6F622D74657874207265616461626C65</TD><TD>0x6D656469756D626C6F622D74657874207265616461626C65</TD><TD>0x6C6F6E67626C6F622D74657874207265616461626C65</TD><TD>0x74657874207265616461626C65</TD><TD>0x01</TD><TD>0x63</TD><TD>0x7661726961626C65</TD><TD>0x000000000101000000000000000000F03F000000000000F03F</TD></TR></TABLE><TABLE BORDER=1><TR><TH>id</TH><TH>col1</TH><TH>col2</TH></TR><TR><TD>1</TD><TD>0xAB123400000000000000</TD><TD>0x123ABC</TD></TR><TR><TD>2</TD><TD>0xDE123400000000000000</TD><TD>0x123DEF</TD></TR></TABLE>DROP TABLE t1, t2;
+create table t1 (a int);
+formatID gtrid_length bqual_length data
+1 3 2 0x7472316271
+DROP TABLE t1;
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
index 3c9cbb18bcb..ca314573581 100644
--- a/mysql-test/r/cast.result
+++ b/mysql-test/r/cast.result
@@ -1168,3 +1168,112 @@ CAST('-1' AS UNSIGNED)
18446744073709551615
DROP TABLE t1;
SET sql_mode=DEFAULT;
+#
+# MDEV-14376 Explicit CAST(CHAR(N)) erroneously escalates warnings to errors in STRICT_ALL_TABLES
+#
+SET sql_mode=STRICT_ALL_TABLES;
+SELECT CAST('xxx' AS CHAR(1));
+CAST('xxx' AS CHAR(1))
+x
+Warnings:
+Warning 1292 Truncated incorrect CHAR(1) value: 'xxx'
+CREATE OR REPLACE TABLE t1 (a VARCHAR(1));
+INSERT INTO t1 VALUES (CAST('xxx' AS CHAR(1)));
+Warnings:
+Warning 1292 Truncated incorrect CHAR(1) value: 'xxx'
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 (a VARCHAR(3));
+INSERT INTO t1 VALUES ('xxx');
+UPDATE t1 SET a=CAST(a AS CHAR(1));
+Warnings:
+Warning 1292 Truncated incorrect CHAR(1) value: 'xxx'
+DROP TABLE t1;
+BEGIN NOT ATOMIC
+DECLARE a VARCHAR(30) CHARACTER SET latin1;
+SET a=CAST('xxx' AS CHAR(1));
+END;
+$$
+Warnings:
+Warning 1292 Truncated incorrect CHAR(1) value: 'xxx'
+BEGIN NOT ATOMIC
+DECLARE a VARCHAR(30) CHARACTER SET latin1;
+SET a=CAST(_latin1'xxx' AS CHAR(1) CHARACTER SET latin1);
+END;
+$$
+Warnings:
+Warning 1292 Truncated incorrect CHAR(1) value: 'xxx'
+BEGIN NOT ATOMIC
+DECLARE a VARCHAR(30) CHARACTER SET latin1;
+SET a=CAST(_latin1'xxx' AS CHAR(1) CHARACTER SET utf8);
+END;
+$$
+Warnings:
+Warning 1292 Truncated incorrect CHAR(1) value: 'xxx'
+BEGIN NOT ATOMIC
+DECLARE a VARCHAR(30) CHARACTER SET utf8;
+SET a=CAST('xxx' AS CHAR(1));
+END;
+$$
+Warnings:
+Warning 1292 Truncated incorrect CHAR(1) value: 'xxx'
+BEGIN NOT ATOMIC
+DECLARE a VARCHAR(30) CHARACTER SET utf8;
+SET a=CAST(_latin1'xxx' AS CHAR(1) CHARACTER SET latin1);
+END;
+$$
+Warnings:
+Warning 1292 Truncated incorrect CHAR(1) value: 'xxx'
+BEGIN NOT ATOMIC
+DECLARE a VARCHAR(30) CHARACTER SET utf8;
+SET a=CAST(_latin1'xxx' AS CHAR(1) CHARACTER SET utf8);
+END;
+$$
+Warnings:
+Warning 1292 Truncated incorrect CHAR(1) value: 'xxx'
+# Conversion problems still escalate warnings to errors (without right truncation)
+BEGIN NOT ATOMIC
+DECLARE a VARCHAR(30) CHARACTER SET utf8;
+SET a=CAST(_utf8 0xD18F AS CHAR(1) CHARACTER SET latin1);
+END;
+$$
+ERROR HY000: Cannot convert 'utf8' character 0xD18F to 'latin1'
+# Conversion problems still escalate warnings to errors (with right truncation)
+BEGIN NOT ATOMIC
+DECLARE a VARCHAR(30) CHARACTER SET utf8;
+SET a=CAST(_utf8 0xD18FD18F AS CHAR(1) CHARACTER SET latin1);
+END;
+$$
+ERROR HY000: Cannot convert 'utf8' character 0xD18F to 'latin1'
+# CAST(number AS CHAR) escalates warnings to errors on truncation
+CREATE OR REPLACE TABLE t1 (a VARCHAR(10));
+INSERT INTO t1 VALUES (CAST(123 AS CHAR(1)));
+ERROR 22007: Truncated incorrect CHAR(1) value: '123'
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 (a VARCHAR(10));
+INSERT INTO t1 VALUES ('1');
+UPDATE t1 SET a=CAST(123 AS CHAR(1));
+ERROR 22007: Truncated incorrect CHAR(1) value: '123'
+DROP TABLE t1;
+BEGIN NOT ATOMIC
+DECLARE a VARCHAR(10);
+SET a=CAST(123 AS CHAR(1));
+END;
+$$
+ERROR 22007: Truncated incorrect CHAR(1) value: '123'
+# CAST(temporal AS CHAR) escalates warnings to errors on truncation
+CREATE OR REPLACE TABLE t1 (a VARCHAR(10));
+INSERT INTO t1 VALUES (CAST(TIME'10:20:30' AS CHAR(1)));
+ERROR 22007: Truncated incorrect CHAR(1) value: '10:20:30'
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 (a VARCHAR(10));
+INSERT INTO t1 VALUES ('1');
+UPDATE t1 SET a=CAST(TIME'10:20:30' AS CHAR(1));
+ERROR 22007: Truncated incorrect CHAR(1) value: '10:20:30'
+DROP TABLE t1;
+BEGIN NOT ATOMIC
+DECLARE a VARCHAR(10);
+SET a=CAST(TIME'10:20:30' AS CHAR(1));
+END;
+$$
+ERROR 22007: Truncated incorrect CHAR(1) value: '10:20:30'
+SET sql_mode=DEFAULT;
diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result
index ade8a4f7549..7d21540b548 100644
--- a/mysql-test/r/commit_1innodb.result
+++ b/mysql-test/r/commit_1innodb.result
@@ -230,7 +230,7 @@ insert into t2 (a) values (1023);
do (f2(23));
Warnings:
Error 1062 Duplicate entry '23' for key 'a'
-Note 4092 At line 4 in test.f2
+Note 4094 At line 4 in test.f2
select * from t2;
a
1023
diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result
index dfe4406605e..f36483e6d8d 100644
--- a/mysql-test/r/connect.result
+++ b/mysql-test/r/connect.result
@@ -32,6 +32,7 @@ time_zone_leap_second
time_zone_name
time_zone_transition
time_zone_transition_type
+transaction_registry
user
connect con2,localhost,root,,test;
show tables;
@@ -79,6 +80,7 @@ time_zone_leap_second
time_zone_name
time_zone_transition
time_zone_transition_type
+transaction_registry
user
connect con4,localhost,test,gambling,test;
show tables;
@@ -138,6 +140,7 @@ time_zone_leap_second
time_zone_name
time_zone_transition
time_zone_transition_type
+transaction_registry
user
connect con6,localhost,test,gambling3,test;
show tables;
diff --git a/mysql-test/r/contributors.result b/mysql-test/r/contributors.result
index 5d92184f191..927c0bcccbf 100644
--- a/mysql-test/r/contributors.result
+++ b/mysql-test/r/contributors.result
@@ -1,8 +1,9 @@
SHOW CONTRIBUTORS;
Name Location Comment
Booking.com https://www.booking.com Founding member, Platinum Sponsor of the MariaDB Foundation
-Alibaba Cloud https://intl.aliyun.com Platinum Sponsor of the MariaDB Foundation
+Alibaba Cloud https://www.alibabacloud.com/ Platinum Sponsor of the MariaDB Foundation
Tencent Cloud https://cloud.tencent.com Platinum Sponsor of the MariaDB Foundation
+Microsoft https://microsoft.com/ Platinum Sponsor of the MariaDB Foundation
MariaDB Corporation https://mariadb.com Founding member, Gold Sponsor of the MariaDB Foundation
Visma https://visma.com Gold Sponsor of the MariaDB Foundation
DBS https://dbs.com Gold Sponsor of the MariaDB Foundation
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index b4636dca7e2..dc34185ad2e 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1948,6 +1948,144 @@ drop function f1;
create table t1(ID decimal(2,1) unsigned NOT NULL, PRIMARY KEY (ID))engine=memory
select 2.1 ID;
drop table t1;
+create table t1 (
+f01 int, f02 int, f03 int, f04 int, f05 int, f06 int, f07 int, f08 int, f09 int, f10 int, f11 int, f12 int, f13 int, f14 int, f15 int, f16 int, f17 int, f18 int, f19 int, f20 int, f21 int, f22 int, f23 int, f24 int, f25 int, f26 int, f27 int, f28 int, f29 int, f30 int, f31 int, f32 int, f33 int, f34 int, f35 int, f36 int, f37 int, f38 int, f39 int, f40 int, f41 int, f42 int, f43 int, f44 int, f45 int, f46 int, f47 int, f48 int, f49 int, f50 int, f51 int, f52 int, f53 int, f54 int, f55 int, f56 int, f57 int, f58 int, f59 int, f60 int, f61 int, f62 int, f63 int, f64 int,
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0001 (f01) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0002 (f02) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0003 (f03) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0004 (f04) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0005 (f05) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0006 (f06) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0007 (f07) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0008 (f08) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0009 (f09) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0010 (f10) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0011 (f11) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0012 (f12) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0013 (f13) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0014 (f14) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0015 (f15) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0016 (f16) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0017 (f17) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0018 (f18) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0019 (f19) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0020 (f20) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0021 (f21) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0022 (f22) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0023 (f23) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0024 (f24) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0025 (f25) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0026 (f26) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0027 (f27) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0028 (f28) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0029 (f29) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0030 (f30) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0031 (f31) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0032 (f32) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0033 (f33) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0034 (f34) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0035 (f35) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0036 (f36) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0037 (f37) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0038 (f38) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0039 (f39) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0040 (f40) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0041 (f41) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0042 (f42) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0043 (f43) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0044 (f44) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0045 (f45) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0046 (f46) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0047 (f47) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0048 (f48) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0049 (f49) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0050 (f50) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0051 (f51) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0052 (f52) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0053 (f53) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0054 (f54) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0055 (f55) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0056 (f56) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0057 (f57) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0058 (f58) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0059 (f59) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0060 (f60) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0061 (f61) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0062 (f62) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0063 (f63) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0064 (f64) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+fend int);
+ERROR HY000: Cannot create table `t1`: index information is too long. Decrease number of indexes or use shorter index names or shorter comments.
+create table t1 (
+f01 int, f02 int, f03 int, f04 int, f05 int, f06 int, f07 int, f08 int, f09 int, f10 int, f11 int, f12 int, f13 int, f14 int, f15 int, f16 int, f17 int, f18 int, f19 int, f20 int, f21 int, f22 int, f23 int, f24 int, f25 int, f26 int, f27 int, f28 int, f29 int, f30 int, f31 int, f32 int, f33 int, f34 int, f35 int, f36 int, f37 int, f38 int, f39 int, f40 int, f41 int, f42 int, f43 int, f44 int, f45 int, f46 int, f47 int, f48 int, f49 int, f50 int, f51 int, f52 int, f53 int, f54 int, f55 int, f56 int, f57 int, f58 int, f59 int, f60 int, f61 int, f62 int, f63 int, f64 int,
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0001 (f01) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0002 (f02) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0003 (f03) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0004 (f04) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0005 (f05) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0006 (f06) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0007 (f07) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0008 (f08) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0009 (f09) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0010 (f10) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0011 (f11) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0012 (f12) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0013 (f13) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0014 (f14) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0015 (f15) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0016 (f16) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0017 (f17) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0018 (f18) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0019 (f19) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0020 (f20) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0021 (f21) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0022 (f22) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0023 (f23) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0024 (f24) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0025 (f25) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0026 (f26) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0027 (f27) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0028 (f28) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0029 (f29) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0030 (f30) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0031 (f31) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0032 (f32) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0033 (f33) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0034 (f34) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0035 (f35) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0036 (f36) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0037 (f37) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0038 (f38) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0039 (f39) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0040 (f40) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0041 (f41) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0042 (f42) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0043 (f43) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0044 (f44) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0045 (f45) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0046 (f46) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0047 (f47) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0048 (f48) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0049 (f49) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0050 (f50) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0051 (f51) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0052 (f52) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0053 (f53) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0054 (f54) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0055 (f55) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0056 (f56) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0057 (f57) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0058 (f58) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0059 (f59) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0060 (f60) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0061 (f61) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0062 (f62) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0063 (f63) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+fend int);
+alter table t1 add
+key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0064 (f64) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy';
+ERROR HY000: Cannot create table `t1`: index information is too long. Decrease number of indexes or use shorter index names or shorter comments.
+drop table t1;
End of 5.5 tests
create table t1;
ERROR 42000: A table must have at least 1 column
diff --git a/mysql-test/r/create_drop_binlog.result b/mysql-test/r/create_drop_binlog.result
index 79e0bdf5e20..be40fcc140a 100644
--- a/mysql-test/r/create_drop_binlog.result
+++ b/mysql-test/r/create_drop_binlog.result
@@ -1,3 +1,4 @@
+reset master;
CREATE OR REPLACE DATABASE d1;
CREATE OR REPLACE DATABASE d1;
DROP DATABASE d1;
@@ -160,7 +161,7 @@ Note 1050 Table 'v1' already exists
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v1;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
SHOW BINLOG EVENTS;
Log_name Pos Event_type Server_id End_log_pos Info
# # Format_desc 1 # VER
diff --git a/mysql-test/r/create_drop_function.result b/mysql-test/r/create_drop_function.result
index 8e529a587fa..3ba6581d61b 100644
--- a/mysql-test/r/create_drop_function.result
+++ b/mysql-test/r/create_drop_function.result
@@ -3,8 +3,8 @@ CREATE FUNCTION f1(str char(20))
RETURNS CHAR(100)
RETURN CONCAT('Hello, ', str, '!');
SELECT * FROM mysql.proc WHERE name like 'f1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
-test f1 FUNCTION f1 SQL CONTAINS_SQL NO DEFINER str char(20) char(100) CHARSET latin1 RETURN CONCAT('Hello, ', str, '!') root@localhost 2014-09-30 08:00:00 2014-09-30 08:00:00 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci latin1_swedish_ci RETURN CONCAT('Hello, ', str, '!')
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
+test f1 FUNCTION f1 SQL CONTAINS_SQL NO DEFINER str char(20) char(100) CHARSET latin1 RETURN CONCAT('Hello, ', str, '!') root@localhost 2014-09-30 08:00:00 2014-09-30 08:00:00 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci latin1_swedish_ci RETURN CONCAT('Hello, ', str, '!') NONE
SELECT f1('world');
f1('world')
Hello, world!
diff --git a/mysql-test/r/create_drop_view.result b/mysql-test/r/create_drop_view.result
index d23b9b713ad..9d7e42552bf 100644
--- a/mysql-test/r/create_drop_view.result
+++ b/mysql-test/r/create_drop_view.result
@@ -55,5 +55,5 @@ id
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v1;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
DROP TABLE t1;
diff --git a/mysql-test/r/create_or_replace.result b/mysql-test/r/create_or_replace.result
index 3d9b29ffe27..e26884f1cbf 100644
--- a/mysql-test/r/create_or_replace.result
+++ b/mysql-test/r/create_or_replace.result
@@ -458,3 +458,23 @@ CREATE OR REPLACE TABLE t1 AS SELECT f1();
UNLOCK TABLES;
DROP FUNCTION f1;
DROP TABLE t1;
+#
+# MDEV-11071 - Assertion `thd->transaction.stmt.is_empty()' failed in
+# Locked_tables_list::unlock_locked_tables
+#
+CREATE TEMPORARY TABLE t1(a INT) ENGINE=InnoDB;
+CREATE TEMPORARY TABLE t2(a INT);
+CREATE TABLE t3(a INT);
+LOCK TABLE t2 WRITE;
+SELECT * FROM t2;
+a
+CREATE OR REPLACE TEMPORARY TABLE t1(a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+ERROR HY000: CREATE TEMPORARY TABLE is not allowed with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE.
+SELECT * FROM t3;
+ERROR HY000: Table 't3' was not locked with LOCK TABLES
+CREATE OR REPLACE TEMPORARY TABLE t2(a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+ERROR HY000: CREATE TEMPORARY TABLE is not allowed with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE.
+SELECT * FROM t3;
+ERROR HY000: Table 't3' was not locked with LOCK TABLES
+UNLOCK TABLES;
+DROP TABLE t3;
diff --git a/mysql-test/r/create_user.result b/mysql-test/r/create_user.result
index 1411f2e8792..8001b43221b 100644
--- a/mysql-test/r/create_user.result
+++ b/mysql-test/r/create_user.result
@@ -1,57 +1,57 @@
create user foo;
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N N 0.000000
drop user foo;
create user foo identified by 'password';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N N 0.000000
drop user foo;
create user foo identified by 'password' require SSL;
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N ANY 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N ANY 0 0 0 0 N N 0.000000
drop user foo;
create user foo identified by 'password' require X509;
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N X509 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N X509 0 0 0 0 N N 0.000000
drop user foo;
create user foo identified by 'password' require CIPHER 'cipher';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED cipher 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED cipher 0 0 0 0 N N 0.000000
drop user foo;
create user foo identified by 'password' require ISSUER 'issuer';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED issuer 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED issuer 0 0 0 0 N N 0.000000
drop user foo;
create user foo identified by 'password' require SUBJECT 'subject';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED subject 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED subject 0 0 0 0 N N 0.000000
drop user foo;
create user foo identified by 'password' require CIPHER 'cipher'
SUBJECT 'subject';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED cipher subject 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED cipher subject 0 0 0 0 N N 0.000000
drop user foo;
create user foo identified by 'password' require CIPHER 'cipher'
AND SUBJECT 'subject'
AND ISSUER 'issuer';
select * from mysql.user where user = 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED cipher issuer subject 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED cipher issuer subject 0 0 0 0 N N 0.000000
drop user foo;
create user foo, foo2 identified by 'password' require CIPHER 'cipher'
AND SUBJECT 'subject'
AND ISSUER 'issuer';
select * from mysql.user where user like 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED cipher issuer subject 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED cipher issuer subject 0 0 0 0 N N 0.000000
#--warning ER_USER_CREATE_EXISTS
create user if not exists foo, foo2 identified by 'password2'
require CIPHER 'cipher2' AND SUBJECT 'subject2' AND ISSUER 'issuer2';
@@ -59,14 +59,14 @@ Warnings:
Note 1973 Can't create user 'foo'@'%'; it already exists
Note 1973 Can't create user 'foo2'@'%'; it already exists
select * from mysql.user where user like 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED cipher issuer subject 0 0 0 0 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED cipher issuer subject 0 0 0 0 N N 0.000000
drop user foo, foo2;
create user foo with MAX_QUERIES_PER_HOUR 10
MAX_UPDATES_PER_HOUR 20
MAX_CONNECTIONS_PER_HOUR 30
MAX_USER_CONNECTIONS 40;
select * from mysql.user where user like 'foo';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
-% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 40 N N 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+% foo N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 40 N N 0.000000
drop user foo;
diff --git a/mysql-test/r/cte_grant.result b/mysql-test/r/cte_grant.result
index 1282a98fdef..2ee31be3435 100644
--- a/mysql-test/r/cte_grant.result
+++ b/mysql-test/r/cte_grant.result
@@ -63,3 +63,61 @@ connection root;
revoke all privileges on mysqltest.v1 from mysqltest_1@localhost;
drop user mysqltest_1@localhost;
drop database mysqltest;
+#
+# MDEV-13453: privileges checking for CTE
+#
+create database db;
+use db;
+create table t1 (i int);
+insert into t1
+values (3), (7), (1), (4), (2), (3), (1);
+create table t2 (a int, b int);
+insert into t2
+values (3,10), (7,11), (1,17), (4,15), (2,11), (3,10), (1,15);
+create user foo@localhost;
+grant SELECT on db.t1 to foo@localhost;
+grant SELECT(a) on db.t2 to foo@localhost;
+connect con1,localhost,foo,,;
+use db;
+with cte as (select * from t1 where i < 4)
+select * from cte;
+i
+3
+1
+2
+3
+1
+with cte as (select * from t1 where i < 4 group by i)
+select * from cte;
+i
+1
+2
+3
+with cte as (select * from t1 where i < 4)
+select * from cte cte1 where i < 2 union select * from cte cte2 where i > 2;
+i
+1
+3
+with cte as (select * from t1 where i < 4 group by i)
+select * from cte cte1 where i < 2 union select * from cte cte2 where i > 2;
+i
+1
+3
+with cte as (select b from t2 where a < 4)
+select * from cte cte1 where b < 15 union select * from cte cte2 where b > 15;
+ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'b' in table 't2'
+with cte as (select a from t2 where a < 4)
+select * from cte cte1 where a < 2 union select * from cte cte2 where a > 2;
+a
+1
+3
+connection default;
+revoke SELECT on db.t1 from foo@localhost;
+connection con1;
+with cte as (select * from t1 where i < 4)
+select * from cte;
+ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
+disconnect con1;
+connection default;
+drop database db;
+drop user foo@localhost;
diff --git a/mysql-test/r/cte_nonrecursive.result b/mysql-test/r/cte_nonrecursive.result
index d0e42cf4042..53334512b20 100644
--- a/mysql-test/r/cte_nonrecursive.result
+++ b/mysql-test/r/cte_nonrecursive.result
@@ -618,7 +618,7 @@ with t(c) as (select a from t1 where b >= 'c')
select * from t r1, t r2 where r1.c=r2.c and r2.c=4;
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 with t as (select `t1`.`a` AS `c` from `t1` where `t1`.`b` >= 'c')select `r1`.`c` AS `c`,`r2`.`c` AS `d` from (`t` `r1` join `t` `r2`) where `r1`.`c` = `r2`.`c` and `r2`.`c` = 4 latin1 latin1_swedish_ci
+v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS with t as (select `test`.`t1`.`a` AS `c` from `test`.`t1` where `test`.`t1`.`b` >= 'c')select `r1`.`c` AS `c`,`r2`.`c` AS `d` from (`t` `r1` join (select `test`.`t1`.`a` AS `c` from `test`.`t1` where `test`.`t1`.`b` >= 'c') `r2`) where `r1`.`c` = `r2`.`c` and `r2`.`c` = 4 latin1 latin1_swedish_ci
select * from v4;
c d
4 4
@@ -1126,7 +1126,7 @@ NULL UNION RESULT <union2,5> ALL NULL NULL NULL NULL NULL NULL
NULL UNION RESULT <union9,12> ALL NULL NULL NULL NULL NULL NULL
NULL UNION RESULT <union1,6> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 with cte_e as (with cte_o as (with cte_i as (/* select#4 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)/* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union /* select#5 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)/* select#1 */ select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union /* select#6 */ select `cte_e2`.`a` AS `a` from `cte_e` `cte_e2`
+Note 1003 with cte_e as (with cte_o as (with cte_i as (/* select#4 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)/* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union /* select#5 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)/* select#1 */ select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union /* select#6 */ select `cte_e2`.`a` AS `a` from (with cte_o as (with cte_i as (/* select#11 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)/* select#10 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)/* select#9 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 union /* select#12 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7) `cte_e2`
drop table t1;
#
# MDEV-13753: embedded CTE in a VIEW created in prepared statement
@@ -1147,3 +1147,281 @@ SELECT * FROM cte_test;
a
1
DROP VIEW cte_test;
+#
+# mdev-14755 : PS for query using CTE in select with subquery
+#
+create table t1 (a int);
+insert into t1 values
+(7), (2), (8), (1), (3), (2), (7), (5), (4), (7), (9), (8);
+with cte as
+(select a from t1 where a between 4 and 7 group by a)
+(select a from cte where exists( select a from t1 where cte.a=t1.a ))
+union
+(select a from t1 where a < 2);
+a
+7
+5
+4
+1
+prepare stmt from "with cte as
+(select a from t1 where a between 4 and 7 group by a)
+(select a from cte where exists( select a from t1 where cte.a=t1.a ))
+union
+(select a from t1 where a < 2)";
+execute stmt;
+a
+7
+5
+4
+1
+execute stmt;
+a
+7
+5
+4
+1
+deallocate prepare stmt;
+with cte as
+(select a from t1 where a between 4 and 7 group by a)
+(select a from t1 where a < 2)
+union
+(select a from cte where exists( select a from t1 where cte.a=t1.a ));
+a
+1
+7
+5
+4
+prepare stmt from "with cte as
+(select a from t1 where a between 4 and 7 group by a)
+(select a from t1 where a < 2)
+union
+(select a from cte where exists( select a from t1 where cte.a=t1.a ))";
+execute stmt;
+a
+1
+7
+5
+4
+execute stmt;
+a
+1
+7
+5
+4
+deallocate prepare stmt;
+with cte as
+(select a from t1 where a between 4 and 7)
+(select a from t1 where a < 2)
+union
+(select a from cte where exists( select a from t1 where cte.a=t1.a ));
+a
+1
+7
+5
+4
+prepare stmt from "with cte as
+(select a from t1 where a between 4 and 7)
+(select a from t1 where a < 2)
+union
+(select a from cte where exists( select a from t1 where cte.a=t1.a ))";
+execute stmt;
+a
+1
+7
+5
+4
+execute stmt;
+a
+1
+7
+5
+4
+deallocate prepare stmt;
+with cte as
+(select a from t1 where a between 4 and 7)
+(select a from cte
+where exists( select a from t1 where t1.a < 2 and cte.a=t1.a ))
+union
+(select a from cte where exists( select a from t1 where cte.a=t1.a ));
+a
+7
+5
+4
+prepare stmt from "with cte as
+(select a from t1 where a between 4 and 7)
+(select a from cte
+where exists( select a from t1 where t1.a < 2 and cte.a=t1.a ))
+union
+(select a from cte where exists( select a from t1 where cte.a=t1.a ))";
+execute stmt;
+a
+7
+5
+4
+execute stmt;
+a
+7
+5
+4
+deallocate prepare stmt;
+drop table t1;
+#
+# MDEV-14852: CTE using temporary table in query
+# with two references to the CTE
+#
+create temporary table t1 (i int);
+insert into t1 values (5),(4),(1),(2),(3);
+with
+c1 as (select i from t1),
+c2 as (select i from c1 where c1.i=2)
+select i from c1 where i > 3 union select i from c2;
+i
+5
+4
+2
+drop table t1;
+create table t1 (term char(10));
+create temporary table t2 (term char(10));
+insert into t1 values ('TERM01'),('TERM02'),('TERM03');
+insert into t2 values ('TERM02'),('TERM03'),('TERM04');
+with c1 as (select * from t1), c2 as (select * from t2)
+(select * from c1 left outer join c2 on c1.term = c2.term)
+union all
+(select * from c1 right outer join c2 on c1.term = c2.term
+where c1.term is null);
+term term
+TERM02 TERM02
+TERM03 TERM03
+TERM01 NULL
+NULL TERM04
+drop table t1,t2;
+#
+# MDEV-14969: view using subquery with attached CTE
+#
+create table region (
+r_regionkey int,
+r_name char(25),
+primary key (r_regionkey)
+);
+insert into region values
+(0,'AFRICA'), (1,'AMERICA'), (2,'ASIA'), (3,'EUROPE'), (4,'MIDDLE EAST');
+create table nation (
+n_nationkey int,
+n_name char(25),
+n_regionkey int,
+primary key (n_nationkey),
+key i_n_regionkey (n_regionkey)
+);
+insert into nation values
+(0,'ALGERIA',0), (1,'ARGENTINA',1), (2,'BRAZIL',1), (3,'CANADA',1),
+(4,'EGYPT',4), (5,'ETHIOPIA',0), (6,'FRANCE',3), (7,'GERMANY',3),
+(8,'INDIA',2), (9,'INDONESIA',2), (10,'IRAN',4), (11,'IRAQ',4),
+(12,'JAPAN',2), (13,'JORDAN',4), (14,'KENYA',0), (15,'MOROCCO',0),
+(16,'MOZAMBIQUE',0), (17,'PERU',1), (18,'CHINA',2), (19,'ROMANIA',3),
+(20,'SAUDI ARABIA',4), (21,'VIETNAM',2), (22,'RUSSIA',3),
+(23,'UNITED KINGDOM',3), (24,'UNITED STATES',1);
+select * from nation n ,region r
+where n.n_regionkey = r.r_regionkey and
+r.r_regionkey in
+(with t as (select * from region where r_regionkey <= 3 )
+select r_regionkey from t where r_name <> "ASIA");
+n_nationkey n_name n_regionkey r_regionkey r_name
+0 ALGERIA 0 0 AFRICA
+5 ETHIOPIA 0 0 AFRICA
+14 KENYA 0 0 AFRICA
+15 MOROCCO 0 0 AFRICA
+16 MOZAMBIQUE 0 0 AFRICA
+1 ARGENTINA 1 1 AMERICA
+2 BRAZIL 1 1 AMERICA
+3 CANADA 1 1 AMERICA
+17 PERU 1 1 AMERICA
+24 UNITED STATES 1 1 AMERICA
+6 FRANCE 3 3 EUROPE
+7 GERMANY 3 3 EUROPE
+19 ROMANIA 3 3 EUROPE
+22 RUSSIA 3 3 EUROPE
+23 UNITED KINGDOM 3 3 EUROPE
+create view v as
+select * from nation n ,region r
+where n.n_regionkey = r.r_regionkey and
+r.r_regionkey in
+(with t as (select * from region where r_regionkey <= 3)
+select r_regionkey from t where r_name <> "ASIA");
+show create view v;
+View Create View character_set_client collation_connection
+v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `n`.`n_nationkey` AS `n_nationkey`,`n`.`n_name` AS `n_name`,`n`.`n_regionkey` AS `n_regionkey`,`r`.`r_regionkey` AS `r_regionkey`,`r`.`r_name` AS `r_name` from (`nation` `n` join `region` `r`) where `n`.`n_regionkey` = `r`.`r_regionkey` and `r`.`r_regionkey` in (with t as (select `region`.`r_regionkey` AS `r_regionkey`,`region`.`r_name` AS `r_name` from `region` where `region`.`r_regionkey` <= 3)select `t`.`r_regionkey` from `t` where `t`.`r_name` <> 'ASIA') latin1 latin1_swedish_ci
+select * from v;
+n_nationkey n_name n_regionkey r_regionkey r_name
+0 ALGERIA 0 0 AFRICA
+5 ETHIOPIA 0 0 AFRICA
+14 KENYA 0 0 AFRICA
+15 MOROCCO 0 0 AFRICA
+16 MOZAMBIQUE 0 0 AFRICA
+1 ARGENTINA 1 1 AMERICA
+2 BRAZIL 1 1 AMERICA
+3 CANADA 1 1 AMERICA
+17 PERU 1 1 AMERICA
+24 UNITED STATES 1 1 AMERICA
+6 FRANCE 3 3 EUROPE
+7 GERMANY 3 3 EUROPE
+19 ROMANIA 3 3 EUROPE
+22 RUSSIA 3 3 EUROPE
+23 UNITED KINGDOM 3 3 EUROPE
+drop view v;
+drop table region, nation;
+#
+# MDEV-15120: cte name used with database name
+#
+WITH cte AS (SELECT 1 AS a) SELECT test.cte.a FROM test.cte;
+ERROR 42S02: Table 'test.cte' doesn't exist
+CREATE DATABASE db1;
+USE db1;
+WITH cte AS (SELECT 1 AS a) SELECT db1.cte.a FROM db1.cte;
+ERROR 42S02: Table 'db1.cte' doesn't exist
+DROP DATABASE db1;
+USE test;
+#
+# MDEV-15119: CTE c2 specified after CTE c1 and is used in
+# CTE c3 that is embedded into the spec of c1
+#
+CREATE TABLE t1 (i int);
+INSERT INTO t1 VALUES (1),(2),(3);
+WITH c1 AS (WITH c3 AS (SELECT * FROM c2) SELECT * FROM c3),
+c2 AS (SELECT * FROM t1)
+SELECT * FROM c1;
+ERROR 42S02: Table 'test.c2' doesn't exist
+WITH RECURSIVE c1 AS (WITH c3 AS (SELECT * FROM c2) SELECT * FROM c3),
+c2 AS (SELECT * FROM t1)
+SELECT * FROM c1;
+i
+1
+2
+3
+DROP TABLE t1;
+#
+# MDEV-14297: Lost name of a explicitly named CTE column used in
+# the non-recursive CTE via prepared statement
+#
+CREATE TABLE t1 (i int);
+INSERT INTO t1 VALUES (1),(2),(3);
+PREPARE stmt FROM "WITH cte(a) AS (SELECT 1) SELECT * FROM cte";
+EXECUTE stmt;
+a
+1
+DEALLOCATE PREPARE stmt;
+PREPARE stmt FROM "CREATE VIEW v1 AS WITH cte(a) AS (SELECT 1) SELECT * FROM cte";
+EXECUTE stmt;
+SELECT * FROM v1;
+a
+1
+DEALLOCATE PREPARE stmt;
+PREPARE stmt FROM "CREATE VIEW v2 AS WITH cte(a) AS (SELECT * FROM t1) SELECT * FROM cte";
+EXECUTE stmt;
+SELECT * FROM v2;
+a
+1
+2
+3
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+DROP VIEW v1,v2;
diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result
index b902333ddc4..15d4fc1a01f 100644
--- a/mysql-test/r/cte_recursive.result
+++ b/mysql-test/r/cte_recursive.result
@@ -691,13 +691,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
1 PRIMARY <derived3> ref key0 key0 5 c.h_id 2 100.00
1 PRIMARY <derived3> ref key0 key0 5 c.w_id 2 100.00
+2 DERIVED <derived3> ALL NULL NULL NULL NULL 12 100.00 Using where
3 DERIVED folks ALL NULL NULL NULL NULL 12 100.00 Using where
4 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
4 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
5 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
5 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union3,4,5> ALL NULL NULL NULL NULL NULL NULL
-2 DERIVED <derived3> ALL NULL NULL NULL NULL 12 100.00 Using where
Warnings:
Note 1003 with recursive ancestor_couple_ids as (/* select#2 */ select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where `a`.`father` is not null and `a`.`mother` is not null), coupled_ancestors as (/* select#3 */ select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' union all /* select#4 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where `test`.`p`.`id` = `fa`.`h_id` union all /* select#5 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where `test`.`p`.`id` = `ma`.`w_id`)/* select#1 */ select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where `h`.`id` = `c`.`h_id` and `w`.`id` = `c`.`w_id`
# simple mutual recursion
@@ -2904,6 +2904,172 @@ n
2
3
#
+# mdev-14629: a user-defined variable is defined by the recursive CTE
+#
+set @var=
+(
+with recursive cte_tab(a) as (
+select 1
+union
+select a+1 from cte_tab
+where a<3)
+select count(*) from cte_tab
+);
+select @var;
+@var
+3
+create table t1(a int, b int);
+insert into t1 values (3,8),(1,5),(5,7),(7,4),(4,3);
+set @var=
+(
+with recursive summ(a,s) as (
+select 1, 0 union
+select t1.b, t1.b+summ.s from summ, t1
+where summ.a=t1.a)
+select s from summ
+order by a desc
+limit 1
+);
+select @var;
+@var
+27
+set @var=
+(
+with recursive
+cte_1 as (
+select 1
+union
+select * from cte_2),
+cte_2 as (
+select * from cte_1
+union
+select a from t1, cte_2
+where t1.a=cte_2.a)
+select * from cte_2
+limit 1
+);
+ERROR HY000: Unacceptable mutual recursion with anchored table 'cte_1'
+drop table t1;
+#
+# mdev-14777: crash caused by the same as in mdev-14755
+#
+CREATE TABLE t1 (i1 int NOT NULL, i2 int);
+CREATE TABLE t2 (d1 int NOT NULL PRIMARY KEY);
+CREATE TABLE t3 (i int );
+insert into t1 select seq,seq from seq_1_to_100000;
+insert into t2 select seq from seq_1000_to_100000;
+insert into t3 select seq from seq_1_to_1000;
+SELECT *
+FROM
+(
+SELECT *
+FROM
+(
+WITH RECURSIVE rt AS
+(
+SELECT i2 P, i1 C FROM t1 WHERE i1 IN (SELECT d1 FROM t2)
+UNION
+SELECT t1.i2 P, rt.C C FROM t1, rt
+)
+SELECT C,P
+FROM ( SELECT P,C FROM rt WHERE NOT EXISTS (SELECT 1 FROM t1) ) Y
+) X
+WHERE 1 = 1
+) K, t3;
+C P i
+drop table t1,t2,t3;
+#
+# mdev-14879: subquery with recursive reference in WHERE of CTE
+#
+create table flights
+(departure varchar(32),
+arrival varchar(32),
+carrier varchar(20),
+flight_number char(7));
+insert into flights values
+('Seattle', 'Frankfurt', 'Lufthansa', 'LH 491'),
+('Seattle', 'Chicago', 'American', 'AA 2573'),
+('Seattle', 'Los Angeles', 'Alaska Air', 'AS 410'),
+('Chicago', 'New York', 'American', 'AA 375'),
+('Chicago', 'Montreal', 'Air Canada', 'AC 3053'),
+('Los Angeles', 'New York', 'Delta', 'DL 1197'),
+('Moscow', 'Tokyo', 'Aeroflot', 'SU 264'),
+('New York', 'Paris', 'Air France', 'AF 23'),
+('Frankfurt', 'Moscow', 'Lufthansa', 'LH 1444'),
+('Tokyo', 'Seattle', 'ANA', 'NH 178'),
+('Los Angeles', 'Tokyo', 'ANA', 'NH 175'),
+('Moscow', 'Los Angeles', 'Aeroflot', 'SU 106'),
+('Montreal', 'Paris', 'Air Canada', 'AC 870'),
+('Cairo', 'Paris', 'Air France', 'AF 503'),
+('New York', 'Seattle', 'American', 'AA 45'),
+('Paris', 'Chicago', 'Air France', 'AF 6734');
+with recursive destinations (city) as
+( select a.arrival from flights a where a.departure='Cairo'
+ union
+select b.arrival from destinations r, flights b where r.city=b.departure)
+select * from destinations;
+city
+Paris
+Chicago
+New York
+Montreal
+Seattle
+Frankfurt
+Los Angeles
+Moscow
+Tokyo
+set standard_compliant_cte=0;
+with recursive destinations (city, legs) as
+(
+select a.arrival, 1 from flights a where a.departure='Cairo'
+ union
+select b.arrival, r.legs + 1 from destinations r, flights b
+where r.city=b.departure and b.arrival not in (select city from destinations)
+)
+select * from destinations;
+city legs
+Paris 1
+Chicago 2
+New York 3
+Montreal 3
+Seattle 4
+Frankfurt 5
+Los Angeles 5
+Moscow 6
+Tokyo 6
+explain extended with recursive destinations (city, legs) as
+(
+select a.arrival, 1 from flights a where a.departure='Cairo'
+ union
+select b.arrival, r.legs + 1 from destinations r, flights b
+where r.city=b.departure and b.arrival not in (select city from destinations)
+)
+select * from destinations;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 16 100.00
+2 DERIVED a ALL NULL NULL NULL NULL 16 100.00 Using where
+3 RECURSIVE UNION b ALL NULL NULL NULL NULL 16 100.00 Using where
+3 RECURSIVE UNION <derived2> ref key0 key0 35 test.b.departure 2 100.00
+4 DEPENDENT SUBQUERY <derived2> ALL NULL NULL NULL NULL 16 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 with recursive destinations as (/* select#2 */ select `test`.`a`.`arrival` AS `city`,1 AS `legs` from `test`.`flights` `a` where `test`.`a`.`departure` = 'Cairo' union /* select#3 */ select `test`.`b`.`arrival` AS `arrival`,`r`.`legs` + 1 AS `r.legs + 1` from `destinations` `r` join `test`.`flights` `b` where `r`.`city` = `test`.`b`.`departure` and !<in_optimizer>(`test`.`b`.`arrival`,<exists>(/* select#4 */ select `destinations`.`city` from `destinations` where trigcond(`test`.`b`.`arrival` = `destinations`.`city` or `destinations`.`city` is null) having trigcond(`destinations`.`city` is null))))/* select#1 */ select `destinations`.`city` AS `city`,`destinations`.`legs` AS `legs` from `destinations`
+set standard_compliant_cte=default;
+drop table flights;
+#
+# MDEV-15162: Setting user variable in recursive CTE
+#
+SET @c=1;
+WITH RECURSIVE cte AS
+(SELECT 5
+UNION
+SELECT @c:=@c+1 FROM cte WHERE @c<3)
+SELECT * FROM cte;
+5
+5
+2
+3
+#
# MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
#
CREATE TEMPORARY TABLE a_tbl (
@@ -2926,3 +3092,249 @@ ERROR 21000: The used SELECT statements have a different number of columns
DROP TABLE a_tbl;
WITH RECURSIVE x AS (SELECT 1,2 UNION ALL SELECT 1 FROM x) SELECT * FROM x;
ERROR 21000: The used SELECT statements have a different number of columns
+#
+# MDEV-15162: Setting user variable in recursive CTE
+#
+SET @c=1;
+WITH RECURSIVE cte AS
+(SELECT 5
+UNION
+SELECT @c:=@c+1 FROM cte WHERE @c<3)
+SELECT * FROM cte;
+5
+5
+2
+3
+#
+# MDEV-14883: recursive references in operands of INTERSECT / EXCEPT
+#
+create table flights
+(departure varchar(32),
+arrival varchar(32),
+carrier varchar(20),
+flight_number char(7));
+insert into flights values
+('Seattle', 'Frankfurt', 'Lufthansa', 'LH 491'),
+('Seattle', 'Amsterdam', 'KLM', 'KL 6032'),
+('Seattle', 'Chicago', 'American', 'AA 2573'),
+('Seattle', 'Los Angeles', 'Alaska Air', 'AS 410'),
+('Chicago', 'New York', 'American', 'AA 375'),
+('Chicago', 'Montreal', 'Air Canada', 'AC 3053'),
+('Los Angeles', 'New York', 'Delta', 'DL 1197'),
+('New York', 'London', 'British Airways', 'BA 1511'),
+('London', 'Moscow', 'British Airways', 'BA 233'),
+('Moscow', 'Tokyo', 'Aeroflot', 'SU 264'),
+('Moscow', 'Dubai', 'Emirates', 'EK 2421'),
+('Dubai', 'Tokyo', 'Emirates', 'EK 318'),
+('Dubai', 'Bangkok', 'Emirates', 'EK 2142'),
+('Beijing', 'Bangkok', 'Air China', 'CA 757'),
+('Beijing', 'Tokyo', 'Air China', 'CA 6653'),
+('Moscow', 'Bangkok', 'Aeroflot', 'SU 270'),
+('New York', 'Reykjavik', 'Icelandair', 'FL 416'),
+('New York', 'Paris', 'Air France', 'AF 23'),
+('Amsterdam', 'Moscow', 'KLM', 'KL 903'),
+('Frankfurt', 'Dubai', 'Lufthansa', 'LH 630'),
+('Frankfurt', 'Moscow', 'Lufthansa', 'LH 1444'),
+('Reykjavik', 'London', 'British Airways', 'BA 2229'),
+('Frankfurt', 'Beijing', 'Air China', 'CA 966'),
+('Tokyo', 'Seattle', 'ANA', 'NH 178'),
+('Los Angeles', 'Tokyo', 'ANA', 'NH 175'),
+('Moscow', 'Los Angeles', 'Aeroflot', 'SU 106'),
+('Montreal', 'Paris', 'Air Canada', 'AC 870'),
+('London', 'Delhi', 'British Airways', 'BA 143'),
+('Delhi', 'Bangkok', 'Air India', 'AI 306'),
+('Delhi', 'Dubai', 'Air India', 'AI 995'),
+('Dubai', 'Cairo', 'Emirates', 'EK 927'),
+('Cairo', 'Paris', 'Air France', 'AF 503'),
+('Amsterdam', 'New York', 'Delta', 'DL 47'),
+('New York', 'Seattle', 'American', 'AA 45'),
+('Paris', 'Chicago', 'Air France', 'AF 6734');
+create table distances
+(city1 varchar(32),
+city2 varchar(32),
+dist int);
+insert into distances values
+('Seattle', 'Frankfurt', 5080),
+('Seattle', 'Amsterdam', 4859),
+('Seattle', 'Chicago', 1733),
+('Seattle', 'Los Angeles', 960),
+('Chicago', 'New York', 712),
+('Chicago', 'Montreal', 746),
+('Los Angeles', 'New York', 2446),
+('New York', 'London', 3459),
+('London', 'Moscow', 1554),
+('Moscow', 'Tokyo', 4647),
+('Moscow', 'Dubai', 2298),
+('Dubai', 'Tokyo', 4929),
+('Dubai', 'Bangkok', 3050),
+('Beijing', 'Bangkok', 2046),
+('Beijing', 'Tokyo', 1301),
+('Moscow', 'Bangkok', 4390),
+('New York', 'Reykjavik', 2613),
+('New York', 'Paris', 3625),
+('Amsterdam', 'Moscow', 1334),
+('Frankfurt', 'Dubai', 3003),
+('Frankfurt', 'Moscow', 1256),
+('Reykjavik', 'London', 1173),
+('Frankfurt', 'Beijing', 4836),
+('Tokyo', 'Seattle', 4783),
+('Los Angeles', 'Tokyo', 5479),
+('Moscow', 'Los Angeles', 6071),
+('Moscow', 'Reykjavik', 2052),
+('Montreal', 'Paris', 3425),
+('London', 'Delhi', 4159),
+('London', 'Paris', 214),
+('Delhi', 'Bangkok', 1810),
+('Delhi', 'Dubai', 1369),
+('Delhi', 'Beijing', 2350),
+('Dubai', 'Cairo', 1501),
+('Cairo', 'Paris', 1992),
+('Amsterdam', 'New York', 3643),
+('New York', 'Seattle', 2402),
+('Paris', 'Chicago', 4136),
+('Paris', 'Los Angeles', 5647);
+with recursive destinations (city) as
+(
+select a.arrival from flights a where a.departure = 'Seattle'
+ union
+select b.arrival from destinations r, flights b where r.city = b.departure
+)
+select * from destinations;
+city
+Frankfurt
+Amsterdam
+Chicago
+Los Angeles
+New York
+Montreal
+Moscow
+Dubai
+Beijing
+Tokyo
+London
+Bangkok
+Reykjavik
+Paris
+Seattle
+Cairo
+Delhi
+with recursive destinations (city) as
+(
+select a.arrival from flights a, distances d
+where a.departure = 'Seattle' and
+a.departure = d.city1 and a.arrival = d.city2 and
+d.dist < 4000
+union
+select b.arrival from destinations r, flights b, distances d
+where r.city = b.departure and
+b.departure = d.city1 and b.arrival = d.city2 and
+d.dist < 4000
+)
+select * from destinations;
+city
+Chicago
+Los Angeles
+New York
+Montreal
+London
+Reykjavik
+Paris
+Seattle
+Moscow
+Dubai
+Bangkok
+Cairo
+set standard_compliant_cte=0;
+with recursive legs_to_destinations
+(departure, arrival, dist, leg_no, acc_mileage) as
+(
+select a.departure, a.arrival, d.dist, 1, d.dist
+from flights a, distances d
+where a.departure = 'Seattle' and
+a.departure = d.city1 and a.arrival = d.city2 and
+d.dist < 4000
+union all
+select b.departure, b.arrival, d.dist, r.leg_no + 1, r.acc_mileage + d.dist
+from legs_to_destinations r, flights b, distances d
+where r.arrival = b.departure and
+b.departure = d.city1 and b.arrival = d.city2 and
+d.dist < 4000 and
+b.arrival not in (select arrival from legs_to_destinations)
+)
+select * from legs_to_destinations;
+departure arrival dist leg_no acc_mileage
+Seattle Chicago 1733 1 1733
+Seattle Los Angeles 960 1 960
+Chicago New York 712 2 2445
+Chicago Montreal 746 2 2479
+Los Angeles New York 2446 2 3406
+New York London 3459 3 6865
+New York London 3459 3 5904
+New York Reykjavik 2613 3 6019
+New York Reykjavik 2613 3 5058
+New York Paris 3625 3 7031
+New York Paris 3625 3 6070
+Montreal Paris 3425 3 5904
+New York Seattle 2402 3 5808
+New York Seattle 2402 3 4847
+London Moscow 1554 4 7458
+London Moscow 1554 4 8419
+Moscow Dubai 2298 5 10717
+Moscow Dubai 2298 5 9756
+Dubai Bangkok 3050 6 12806
+Dubai Bangkok 3050 6 13767
+Dubai Cairo 1501 6 11257
+Dubai Cairo 1501 6 12218
+set standard_compliant_cte=default;
+with recursive destinations (city) as
+(
+select a.arrival from flights a, distances d
+where a.departure = 'Seattle' and
+a.departure = d.city1 and a.arrival = d.city2 and
+d.dist < 4000
+union
+select b.arrival from destinations r, flights b
+where r.city = b.departure
+intersect
+select city2 from destinations s, distances d
+where s.city = d.city1 and d.dist < 4000
+)
+select * from destinations;
+city
+Chicago
+Los Angeles
+New York
+Montreal
+London
+Reykjavik
+Paris
+Seattle
+Moscow
+Dubai
+Bangkok
+Cairo
+with recursive destinations (city) as
+(
+select a.arrival from flights a where a.departure = 'Seattle'
+ union
+select * from
+(
+select b.arrival from destinations r, flights b
+where r.city = b.departure
+except
+select arrival from flights
+where arrival in
+('New York', 'London', 'Moscow', 'Dubai', 'Cairo', 'Tokyo')
+) t
+)
+select * from destinations;
+city
+Frankfurt
+Amsterdam
+Chicago
+Los Angeles
+Montreal
+Beijing
+Bangkok
+Paris
+drop table flights, distances;
diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result
index f9e0ae5a455..085b8b22f67 100644
--- a/mysql-test/r/ctype_latin1.result
+++ b/mysql-test/r/ctype_latin1.result
@@ -8804,6 +8804,31 @@ DROP TABLE t1;
# End of ctype_pad.inc
#
SET STORAGE_ENGINE=Default;
+SET NAMES latin1;
+#
+# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results
+#
+CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b;
+ALTER TABLE t1 ADD KEY(a), ADD KEY(b);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(50) DEFAULT NULL,
+ `b` varchar(50) DEFAULT NULL,
+ KEY `a` (`a`),
+ KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES ('111', '111');
+INSERT INTO t1 VALUES ('222', '222');
+INSERT INTO t1 VALUES ('333', '333');
+INSERT INTO t1 VALUES ('444', '444');
+SELECT * FROM t1 WHERE a LIKE '111%';
+a b
+111 111
+SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%';
+a b
+111 111
+DROP TABLE t1;
#
# End of 10.2 tests
#
diff --git a/mysql-test/r/ctype_like_range.result b/mysql-test/r/ctype_like_range.result
index f8032d0ae86..d8e621fd056 100644
--- a/mysql-test/r/ctype_like_range.result
+++ b/mysql-test/r/ctype_like_range.result
@@ -4430,5 +4430,50 @@ a_ 6100 61FF
a% 61000000000000000000 61FFFFFFFFFFFFFFFFFF
DROP TABLE t1;
#
+# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results
+#
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_swedish_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+a HEX(LIKE_RANGE_MIN(a,200))
+111% 313131
+DROP TABLE t1;
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_general_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+a HEX(LIKE_RANGE_MIN(a,200))
+111% 313131
+DROP TABLE t1;
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+a HEX(LIKE_RANGE_MIN(a,200))
+111% 313131
+DROP TABLE t1;
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+a HEX(LIKE_RANGE_MIN(a,200))
+111% 313131
+DROP TABLE t1;
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET ucs2 COLLATE ucs2_unicode_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+a HEX(LIKE_RANGE_MIN(a,200))
+111% 003100310031
+DROP TABLE t1;
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf16 COLLATE utf16_unicode_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+a HEX(LIKE_RANGE_MIN(a,200))
+111% 003100310031
+DROP TABLE t1;
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf32 COLLATE utf32_unicode_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+a HEX(LIKE_RANGE_MIN(a,200))
+111% 000000310000003100000031
+DROP TABLE t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/r/ctype_ucs2_uca.result b/mysql-test/r/ctype_ucs2_uca.result
index 48ec25b32e3..44a623842c6 100644
--- a/mysql-test/r/ctype_ucs2_uca.result
+++ b/mysql-test/r/ctype_ucs2_uca.result
@@ -559,6 +559,32 @@ DROP TABLE t1;
# End of ctype_pad.inc
#
SET STORAGE_ENGINE=Default;
+SET NAMES utf8, collation_connection=ucs2_unicode_520_nopad_ci;
+#
+# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results
+#
+CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b;
+ALTER TABLE t1 ADD KEY(a), ADD KEY(b);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(50) CHARACTER SET ucs2 COLLATE ucs2_unicode_520_nopad_ci DEFAULT NULL,
+ `b` varchar(50) CHARACTER SET ucs2 COLLATE ucs2_unicode_520_nopad_ci DEFAULT NULL,
+ KEY `a` (`a`),
+ KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES ('111', '111');
+INSERT INTO t1 VALUES ('222', '222');
+INSERT INTO t1 VALUES ('333', '333');
+INSERT INTO t1 VALUES ('444', '444');
+SELECT * FROM t1 WHERE a LIKE '111%';
+a b
+111 111
+SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%';
+a b
+111 111
+DROP TABLE t1;
+SET NAMES utf8;
#
# End of 10.2 tests
#
diff --git a/mysql-test/r/ctype_upgrade.result b/mysql-test/r/ctype_upgrade.result
index 53cb858035b..5f0be66f8fb 100644
--- a/mysql-test/r/ctype_upgrade.result
+++ b/mysql-test/r/ctype_upgrade.result
@@ -8,7 +8,7 @@ CHECK TABLE maria050313_utf8_croatian_ci FOR UPGRADE;
Table Op Msg_type Msg_text
test.maria050313_utf8_croatian_ci check error Upgrade required. Please do "REPAIR TABLE `maria050313_utf8_croatian_ci`" or dump/reload to fix it!
SHOW CREATE TABLE maria050313_utf8_croatian_ci;
-ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.maria050313_utf8_croatian_c` FORCE" or dump/reload to fix it!
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.maria050313_utf8_croatian_ci` FORCE" or dump/reload to fix it!
REPAIR TABLE maria050313_utf8_croatian_ci;
Table Op Msg_type Msg_text
test.maria050313_utf8_croatian_ci repair status OK
@@ -45,7 +45,7 @@ CHECK TABLE maria050313_ucs2_croatian_ci_def FOR UPGRADE;
Table Op Msg_type Msg_text
test.maria050313_ucs2_croatian_ci_def check error Upgrade required. Please do "REPAIR TABLE `maria050313_ucs2_croatian_ci_def`" or dump/reload to fix it!
SELECT count(*) FROM maria050313_ucs2_croatian_ci_def;
-ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.maria050313_ucs2_croatian_c` FORCE" or dump/reload to fix it!
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.maria050313_ucs2_croatian_ci_def` FORCE" or dump/reload to fix it!
REPAIR TABLE maria050313_ucs2_croatian_ci_def;
Table Op Msg_type Msg_text
test.maria050313_ucs2_croatian_ci_def repair status OK
@@ -257,6 +257,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -315,6 +316,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
diff --git a/mysql-test/r/ctype_utf16_uca.result b/mysql-test/r/ctype_utf16_uca.result
index 1105225ed87..0cb9c4c74c1 100644
--- a/mysql-test/r/ctype_utf16_uca.result
+++ b/mysql-test/r/ctype_utf16_uca.result
@@ -7866,6 +7866,32 @@ DROP TABLE t1;
# End of ctype_pad.inc
#
SET STORAGE_ENGINE=Default;
+SET NAMES utf8, collation_connection=utf16_unicode_520_nopad_ci;
+#
+# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results
+#
+CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b;
+ALTER TABLE t1 ADD KEY(a), ADD KEY(b);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(50) CHARACTER SET utf16 COLLATE utf16_unicode_520_nopad_ci DEFAULT NULL,
+ `b` varchar(50) CHARACTER SET utf16 COLLATE utf16_unicode_520_nopad_ci DEFAULT NULL,
+ KEY `a` (`a`),
+ KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES ('111', '111');
+INSERT INTO t1 VALUES ('222', '222');
+INSERT INTO t1 VALUES ('333', '333');
+INSERT INTO t1 VALUES ('444', '444');
+SELECT * FROM t1 WHERE a LIKE '111%';
+a b
+111 111
+SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%';
+a b
+111 111
+DROP TABLE t1;
+SET NAMES utf8;
#
# End of 10.2 tests
#
diff --git a/mysql-test/r/ctype_utf32_uca.result b/mysql-test/r/ctype_utf32_uca.result
index 097da3d7c16..a112918c0c3 100644
--- a/mysql-test/r/ctype_utf32_uca.result
+++ b/mysql-test/r/ctype_utf32_uca.result
@@ -7886,6 +7886,32 @@ DROP TABLE t1;
# End of ctype_pad.inc
#
SET STORAGE_ENGINE=Default;
+SET NAMES utf8, collation_connection=utf32_unicode_520_nopad_ci;
+#
+# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results
+#
+CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b;
+ALTER TABLE t1 ADD KEY(a), ADD KEY(b);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(50) CHARACTER SET utf32 COLLATE utf32_unicode_520_nopad_ci DEFAULT NULL,
+ `b` varchar(50) CHARACTER SET utf32 COLLATE utf32_unicode_520_nopad_ci DEFAULT NULL,
+ KEY `a` (`a`),
+ KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES ('111', '111');
+INSERT INTO t1 VALUES ('222', '222');
+INSERT INTO t1 VALUES ('333', '333');
+INSERT INTO t1 VALUES ('444', '444');
+SELECT * FROM t1 WHERE a LIKE '111%';
+a b
+111 111
+SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%';
+a b
+111 111
+DROP TABLE t1;
+SET NAMES utf8;
#
# End of 10.2 tests
#
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 7381c1c4004..dfe96d1a904 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -10272,6 +10272,21 @@ DROP TABLE allbytes;
SET sql_mode = DEFAULT;
# End of ctype_backslash.inc
#
+# MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
+#
+SET NAMES utf8;
+SELECT CHAR(0xDF USING latin1);
+CHAR(0xDF USING latin1)
+ß
+CREATE OR REPLACE VIEW v1 AS SELECT CHAR(0xDF USING latin1) AS c;
+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 char(0xdf using latin1) AS `c` utf8 utf8_general_ci
+SELECT * FROM v1;
+c
+ß
+DROP VIEW v1;
+#
# End of 10.0 tests
#
#
diff --git a/mysql-test/r/ctype_utf8_uca.result b/mysql-test/r/ctype_utf8_uca.result
index c8107da3b6f..23e9802b61a 100644
--- a/mysql-test/r/ctype_utf8_uca.result
+++ b/mysql-test/r/ctype_utf8_uca.result
@@ -559,6 +559,31 @@ DROP TABLE t1;
# End of ctype_pad.inc
#
SET STORAGE_ENGINE=Default;
+SET NAMES utf8 COLLATE utf8_unicode_nopad_ci;
+#
+# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results
+#
+CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b;
+ALTER TABLE t1 ADD KEY(a), ADD KEY(b);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
+ `b` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
+ KEY `a` (`a`),
+ KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES ('111', '111');
+INSERT INTO t1 VALUES ('222', '222');
+INSERT INTO t1 VALUES ('333', '333');
+INSERT INTO t1 VALUES ('444', '444');
+SELECT * FROM t1 WHERE a LIKE '111%';
+a b
+111 111
+SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%';
+a b
+111 111
+DROP TABLE t1;
#
# End of 10.2 tests
#
diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result
index cf3000baf6a..fbe95d9f44b 100644
--- a/mysql-test/r/ctype_utf8mb4.result
+++ b/mysql-test/r/ctype_utf8mb4.result
@@ -3430,6 +3430,32 @@ a b
a 😠b a ? b
DROP TABLE t1;
#
+# MDEV-8949: COLUMN_CREATE unicode name breakage
+#
+SET NAMES utf8mb4;
+SELECT COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
+COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1))
+{"😎":1}
+SELECT COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
+COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1))
+`😎`
+SELECT COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E
+as int);
+COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E
+as int)
+1
+CREATE TABLE t1 AS SELECT
+COLUMN_LIST(COLUMN_CREATE('a',1)),
+COLUMN_JSON(COLUMN_CREATE('b',1));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `COLUMN_LIST(COLUMN_CREATE('a',1))` longtext CHARACTER SET utf8mb4 DEFAULT NULL,
+ `COLUMN_JSON(COLUMN_CREATE('b',1))` longtext CHARACTER SET utf8mb4 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SET NAMES default;
+#
# End of 10.0 tests
#
#
diff --git a/mysql-test/r/ctype_utf8mb4_uca.result b/mysql-test/r/ctype_utf8mb4_uca.result
index ca7f1a3d7d4..0712ca63abd 100644
--- a/mysql-test/r/ctype_utf8mb4_uca.result
+++ b/mysql-test/r/ctype_utf8mb4_uca.result
@@ -6576,6 +6576,32 @@ DROP TABLE t1;
# End of ctype_pad.inc
#
SET STORAGE_ENGINE=Default;
+SET NAMES utf8mb4 COLLATE utf8mb4_unicode_520_nopad_ci;
+#
+# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results
+#
+CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b;
+ALTER TABLE t1 ADD KEY(a), ADD KEY(b);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_nopad_ci DEFAULT NULL,
+ `b` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_nopad_ci DEFAULT NULL,
+ KEY `a` (`a`),
+ KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES ('111', '111');
+INSERT INTO t1 VALUES ('222', '222');
+INSERT INTO t1 VALUES ('333', '333');
+INSERT INTO t1 VALUES ('444', '444');
+SELECT * FROM t1 WHERE a LIKE '111%';
+a b
+111 111
+SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%';
+a b
+111 111
+DROP TABLE t1;
+SET NAMES utf8mb4;
#
# End of 10.2 tests
#
diff --git a/mysql-test/r/custom_aggregate_functions.result b/mysql-test/r/custom_aggregate_functions.result
new file mode 100644
index 00000000000..67be44c43f7
--- /dev/null
+++ b/mysql-test/r/custom_aggregate_functions.result
@@ -0,0 +1,949 @@
+create table t2 (sal int(10));
+create aggregate function f1(x INT) returns int
+begin
+declare continue handler for not found return 0;
+loop
+fetch group next row;
+insert into t2 (sal) values (x);
+end loop;
+end|
+create table t1 (sal int(10),id int(10));
+INSERT INTO t1 (sal,id) VALUES (5000,1);
+INSERT INTO t1 (sal,id) VALUES (2000,1);
+INSERT INTO t1 (sal,id) VALUES (1000,1);
+select f1(sal) from t1 where id>= 1;
+f1(sal)
+0
+Warnings:
+Note 4094 At line 5 in test.f1
+Note 4094 At line 5 in test.f1
+Note 4094 At line 5 in test.f1
+select * from t2;
+sal
+5000
+2000
+1000
+drop table t2;
+drop function f1;
+create aggregate function f1(x INT) returns INT
+begin
+insert into t1(sal) values (x);
+return x;
+end|
+ERROR HY000: Aggregate specific instruction(FETCH GROUP NEXT ROW) missing from the aggregate function
+create function f1(x INT) returns INT
+begin
+set x=5;
+fetch group next row;
+return x+1;
+end |
+ERROR HY000: Non-aggregate function contains aggregate specific instructions: (FETCH GROUP NEXT ROW)
+create aggregate function f1(x INT) returns INT
+begin
+declare continue handler for not found return x;
+loop
+fetch group next row;
+end loop;
+end |
+select f1(1);
+f1(1)
+1
+show create function f1;
+Function sql_mode Create Function character_set_client collation_connection Database Collation
+f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` AGGREGATE FUNCTION `f1`(x INT) RETURNS int(11)
+begin
+declare continue handler for not found return x;
+loop
+fetch group next row;
+end loop;
+end latin1 latin1_swedish_ci latin1_swedish_ci
+alter function f1 aggregate none;
+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 'aggregate none' at line 1
+show create function f1;
+Function sql_mode Create Function character_set_client collation_connection Database Collation
+f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` AGGREGATE FUNCTION `f1`(x INT) RETURNS int(11)
+begin
+declare continue handler for not found return x;
+loop
+fetch group next row;
+end loop;
+end latin1 latin1_swedish_ci latin1_swedish_ci
+select f1(1);
+f1(1)
+1
+drop function f1;
+create aggregate function f2(i int) returns int
+begin
+FEtCH GROUP NEXT ROW;
+if i <= 0 then
+return 0;
+elseif i = 1 then
+return (select count(*) from t1 where id = i);
+else
+return (select count(*) + f2( i - 1) from t1 where id = i);
+end if;
+end|
+select f2(1)|
+f2(1)
+3
+select f2(2)|
+ERROR HY000: Recursive stored functions and triggers are not allowed
+select f2(3)|
+ERROR HY000: Recursive stored functions and triggers are not allowed
+drop function f2|
+create aggregate function f1(x int) returns int
+begin
+declare mini int default 0;
+declare continue handler for not found return mini;
+loop
+fetch group next row;
+set mini= mini+x;
+fetch group next row;
+end loop;
+end|
+select f1(10);
+f1(10)
+10
+select f1(sal) from t1;
+f1(sal)
+6000
+select f1(sal) from t1 where 1=0;
+f1(sal)
+NULL
+drop function f1;
+create aggregate function f1(x int) returns int
+begin
+declare mini int default 0;
+LOOP
+FETCH GROUP NEXT ROW;
+set mini = mini + x;
+END LOOP;
+end|
+ERROR 42000: No RETURN found in FUNCTION test.f1
+create aggregate function f1(x int) returns int
+begin
+declare mini int default 0;
+LOOP
+FETCH GROUP NEXT ROW;
+set mini = mini + x;
+END LOOP;
+return -1;
+end|
+select f1(sal) from t1|
+ERROR 02000: No data - zero rows fetched, selected, or processed
+drop function f1|
+create aggregate function f1(x int) returns int
+begin
+declare mini int default 0;
+declare continue handler for not found return mini;
+FETCH GROUP NEXT ROW;
+set mini = mini + x;
+end|
+select f1(sal) from t1|
+ERROR 2F005: FUNCTION f1 ended without RETURN
+drop function f1|
+create aggregate function f1(x int) returns int
+begin
+declare mini int default 0;
+declare continue handler for not found set mini=-1;
+LOOP
+FETCH GROUP NEXT ROW;
+set mini = mini + x;
+END LOOP;
+return 0;
+end|
+select f1(sal) from t1|
+ERROR 2F005: FUNCTION f1 ended without RETURN
+drop function f1|
+drop table t1|
+create table t1 (sal int, id int, val int, counter int, primary key(id));
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 1, 10, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (2000, 2, 16, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 3, 18, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 4, 15, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (3000, 5, 11, 5);
+create aggregate function f1(x INT) returns double
+begin
+declare z double default 0;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+set z= z+x;
+end loop;
+end|
+select id, f1(sal) from t1 where id>= 1 group by counter order by val;
+id f1(sal)
+1 3000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1;
+id f1(sal)
+1 17000
+select id, f1(sal) from t1 where id>= 1;
+id f1(sal)
+1 17000
+select id, f1(sal) from t1 where id>= 1 group by counter;
+id f1(sal)
+1 3000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by id;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by val;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by counter order by counter;
+id f1(sal)
+1 3000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by counter order by val;
+id f1(sal)
+1 3000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by counter order by id;
+id f1(sal)
+1 3000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by val order by counter;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by val order by id;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by val order by val;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+drop table t1;
+create table t1 (sal int, id int, val int, counter int, primary key(id), unique key(val));
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 1, 10, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (2000, 2, NULL, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 3, 18, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 4, 15, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (3000, 5, 11, 5);
+select id, f1(sal) from t1;
+id f1(sal)
+1 17000
+select id, f1(sal) from t1 where id>= 1;
+id f1(sal)
+1 17000
+select id, f1(sal) from t1 where id>= 1 group by counter;
+id f1(sal)
+1 3000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by id;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by val;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by counter order by counter;
+id f1(sal)
+1 3000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by counter order by val;
+id f1(sal)
+1 3000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by counter order by id;
+id f1(sal)
+1 3000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by val order by counter;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by val order by id;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by val order by val;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+drop table t1;
+create table t1 (sal int, id int, val int, counter int, primary key(id), INDEX name (val,counter));
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 1, 10, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (2000, 2, 10, 4);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 3, 18, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 4, 11, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (3000, 5, 11, 5);
+select id, f1(sal) from t1;
+id f1(sal)
+1 17000
+select id, f1(sal) from t1 where id>= 1;
+id f1(sal)
+1 17000
+select id, f1(sal) from t1 where id>= 1 group by counter;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by id;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by val;
+id f1(sal)
+1 3000
+3 6000
+4 8000
+select id, f1(sal) from t1 where id>= 1 group by counter order by counter;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by counter order by val;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by counter order by id;
+id f1(sal)
+1 1000
+2 2000
+3 6000
+4 5000
+5 3000
+select id, f1(sal) from t1 where id>= 1 group by val order by counter;
+id f1(sal)
+1 3000
+3 6000
+4 8000
+select id, f1(sal) from t1 where id>= 1 group by val order by id;
+id f1(sal)
+1 3000
+3 6000
+4 8000
+select id, f1(sal) from t1 where id>= 1 group by val order by val;
+id f1(sal)
+1 3000
+3 6000
+4 8000
+drop table t1;
+drop function f1;
+create aggregate function f1(x INT) returns double
+begin
+declare z double default 0;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+set z= z+x;
+end loop;
+end|
+create aggregate function f2() returns double
+begin
+declare z int default 0;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+set z = z+1;
+end loop;
+end|
+create table t1 (sal int, id int, val int, counter int);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 2, 10, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (2000, 1, 16, 5);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 2, 18, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 3, 15, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (3000, 4, 11, 4);
+prepare test from "select f2() from t1 where id>= ?";
+set @param= 2;
+execute test using @param;
+f2()
+4
+execute test using @param;
+f2()
+4
+execute test using @param;
+f2()
+4
+execute test using @param;
+f2()
+4
+set @param= 1;
+execute test using @param;
+f2()
+5
+set @param= 3;
+execute test using @param;
+f2()
+2
+set @param= 4;
+execute test using @param;
+f2()
+1
+deallocate prepare test;
+prepare test from "select f1(sal) from t1 where id>= ?";
+set @param= 2;
+execute test using @param;
+f1(sal)
+15000
+execute test using @param;
+f1(sal)
+15000
+execute test using @param;
+f1(sal)
+15000
+execute test using @param;
+f1(sal)
+15000
+set @param= 1;
+execute test using @param;
+f1(sal)
+17000
+set @param= 3;
+execute test using @param;
+f1(sal)
+8000
+set @param= 4;
+execute test using @param;
+f1(sal)
+3000
+set @param= 5;
+execute test using @param;
+f1(sal)
+NULL
+deallocate prepare test;
+drop function f2;
+prepare test from "select f1(sal) from t1 where id>= ?";
+set @param= 2;
+execute test using @param;
+f1(sal)
+15000
+drop function f1;
+create function f1(x int) returns int
+return -1;
+execute test using @param;
+f1(sal)
+-1
+-1
+-1
+-1
+drop function f1;
+create aggregate function f1(x INT) returns double
+begin
+declare z double default 0;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+set z= z+x;
+end loop;
+end|
+execute test using @param;
+f1(sal)
+15000
+deallocate prepare test;
+drop table t1;
+drop function f1;
+create table t1 (sal int, id int, val varchar(10), counter int);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 2, 'ab', 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 1, 'cd', 5);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 2, 'ef', 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 3, 'gh', 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 4, 'ij', 4);
+create table t2 (sal int, id int, val int, counter int);
+INSERT INTO t2 (sal, id, val, counter) VALUES (1000, 2, 10, 2);
+INSERT INTO t2 (sal, id, val, counter) VALUES (2000, 1, 16, 5);
+INSERT INTO t2 (sal, id, val, counter) VALUES (6000, 2, 18, 1);
+INSERT INTO t2 (sal, id, val, counter) VALUES (5000, 3, 15, 3);
+INSERT INTO t2 (sal, id, val, counter) VALUES (3000, 4, 11, 4);
+create aggregate function f1(x double) returns double
+begin
+declare z double default 0;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+set z= z+x;
+end loop;
+end|
+create aggregate function f2(x INT) returns CHAR(10)
+begin
+declare mini INT default 0;
+declare continue handler for not found return mini;
+loop
+fetch group next row;
+set mini= mini + x;
+end loop;
+end|
+create aggregate function f3(x INT) returns CHAR(10)
+begin
+declare mini INT default 0;
+declare continue handler for not found return mini;
+loop
+fetch group next row;
+set mini= mini + x;
+fetch group next row;
+set mini= mini - x;
+end loop;
+end|
+create aggregate function f4(x INT, y varchar(10)) returns varchar(1000)
+begin
+declare str varchar(1000) default '';
+declare continue handler for not found return str;
+loop
+fetch group next row;
+set str= concat(str,y);
+end loop;
+end|
+create aggregate function f5(x INT) returns varchar(1000)
+begin
+declare z int default 0;
+DECLARE cur1 CURSOR FOR SELECT sal FROM test.t2;
+declare continue handler for not found return 0;
+loop
+fetch group next row;
+set z = z+x;
+end loop;
+end|
+create function f6(x int) returns int
+return (select f1(sal) from t1)|
+select f1(sal) from t1;
+f1(sal)
+5000
+select f1(sal) from t1 where id>= 1 group by counter;
+f1(sal)
+1000
+1000
+1000
+1000
+1000
+select f3(sal) from t1;
+f3(sal)
+1000
+select f2(val) from t1;
+ERROR 22007: Incorrect integer value: 'ab' for column 'x' at row 1
+select val, id, c from (select f1(sal) as c from t2) as t1, t2;
+val id c
+10 2 17000
+11 4 17000
+15 3 17000
+16 1 17000
+18 2 17000
+select f1(sal),f1(val), f1(id), f1(sal) from t2;
+f1(sal) f1(val) f1(id) f1(sal)
+17000 70 12 17000
+select f4(sal, val) from t1;
+f4(sal, val)
+abcdefghij
+select c from (select f1(sal) as c from t2) as t1;
+c
+17000
+select f1((select val from t2 where 0 > 1)) from t1;
+f1((select val from t2 where 0 > 1))
+NULL
+select f1((select val from t2 where id= 1)) from t1;
+f1((select val from t2 where id= 1))
+80
+select f5(sal) from t1;
+f5(sal)
+0
+SELECT f1(sal)*f1(sal) FROM t1;
+f1(sal)*f1(sal)
+25000000
+SELECT (SELECT f1(sal) FROM t1) FROM t2;
+(SELECT f1(sal) FROM t1)
+5000
+5000
+5000
+5000
+5000
+select id, f1(sal) from t1;
+id f1(sal)
+2 5000
+select id, f1(sal) from t1 where id>= 1;
+id f1(sal)
+2 5000
+select f1(sal), f1(sal) from t1 where id>= 1 group by counter;
+f1(sal) f1(sal)
+1000 1000
+1000 1000
+1000 1000
+1000 1000
+1000 1000
+select f1(sal), f1(sal) from t1 where id>= 1 group by id ;
+f1(sal) f1(sal)
+1000 1000
+1000 1000
+1000 1000
+2000 2000
+select f1(sal) from t1 where id>= 1 group by id ;
+f1(sal)
+1000
+1000
+1000
+2000
+select f1(sal) from t1 where id>= 1 order by counter;
+f1(sal)
+5000
+select f1(sal) from t1 where id>= 1 group by id order by counter;
+f1(sal)
+2000
+1000
+1000
+1000
+select counter, id, f1(sal) from t1 where id>= 1 group by id order by counter;
+counter id f1(sal)
+2 2 2000
+3 3 1000
+4 4 1000
+5 1 1000
+select id, f1(sal) from t1 where id>= 1 group by id order by counter;
+id f1(sal)
+2 2000
+3 1000
+4 1000
+1 1000
+drop table t1;
+drop table t2;
+drop function f1;
+drop function f2;
+drop function f3;
+drop function f4;
+drop function f5;
+drop function f6;
+create aggregate function f1(x INT) returns INT
+begin
+declare z double default 1000;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+set z= (z&x);
+end loop;
+end|
+create table t1 (sal int, id int, val int, counter int);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 2, 10, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (7000, 1, 16, 5);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 2, 18, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 3, 15, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (3000, 4, 11, 4);
+INSERT INTO t1 (sal, id, val, counter) VALUES (2000, 5, 10, 7);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 7, 13, 8);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 6, 19, 9);
+INSERT INTO t1 (sal, id, val, counter) VALUES (7000, 7, 12, 0);
+INSERT INTO t1 (sal, id, val, counter) VALUES (4000, 6, 14, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (8000, 5, 19, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (9000, 4, 11, 4);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 3, 11, 2);
+select f1(sal) from t1 where id>= 1;
+f1(sal)
+768
+drop function f1;
+create aggregate function f1(x INT) returns double
+begin
+declare z double default 0;
+declare count double default 0;
+declare continue handler for not found return z/count;
+loop
+fetch group next row;
+set z= z+x;
+set count= count+1;
+end loop;
+end|
+select f1(sal) from t1 where id>= 1;
+f1(sal)
+4923.076923076923
+drop function f1;
+create aggregate function f1(x INT) returns INT
+begin
+declare maxi INT default -1;
+declare continue handler for not found return maxi;
+loop
+fetch group next row;
+if maxi < x then
+set maxi= x;
+end if;
+end loop;
+end|
+select f1(sal) from t1 where id>= 1;
+f1(sal)
+9000
+drop function f1;
+create aggregate function f1(x INT) returns double
+begin
+declare mini INT default 100000;
+declare continue handler for not found return mini;
+loop
+fetch group next row;
+if mini > x then
+set mini = x;
+end if;
+end loop;
+end|
+select f1(sal) from t1 where id>= 1;
+f1(sal)
+1000
+drop function f1;
+create aggregate function f1(x INT) returns double
+begin
+declare z double default 0;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+set z= z^x;
+end loop;
+end|
+select f1(sal) from t1 where id>= 1;
+f1(sal)
+16288
+drop function f1;
+create aggregate function f1(x INT) returns INT
+begin
+declare z int default 0;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+set z= z+x;
+end loop;
+end|
+select f1(sal) from t1 where id>= 1;
+f1(sal)
+64000
+create aggregate function f2() returns INT
+begin
+declare z double default 0;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+set z= z+1;
+end loop;
+end|
+select f2() from t1;
+f2()
+13
+create table t2 (sal int, id int);
+INSERT INTO t2 (sal, id) VALUES (NULL, 1);
+INSERT INTO t2 (sal, id) VALUES (2000, 1);
+INSERT INTO t2 (sal, id) VALUES (3000, 1);
+select f1(sal) from t2;
+f1(sal)
+NULL
+select f1(1);
+f1(1)
+1
+create function f3() returns int
+return (select f1(sal) from t1);
+select f3();
+f3()
+64000
+create function f4() returns INT
+return 1;
+create aggregate function f5() returns INT
+begin
+declare z double default 0;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+set z= z+f3();
+end loop;
+end|
+select f5() from t2;
+f5()
+192000
+Warnings:
+Note 4094 At line 6 in test.f5
+Note 4094 At line 6 in test.f5
+Note 4094 At line 6 in test.f5
+create aggregate function f6(x INT) returns INT
+begin
+declare z int default 0;
+declare continue handler for not found return z;
+loop
+fetch group next row;
+if x then
+set z= z+(select f1(sal) from t1);
+end if;
+end loop;
+end|
+select f6(sal) from t2;
+f6(sal)
+128000
+Warnings:
+Note 4094 At line 6 in test.f6
+Note 4094 At line 6 in test.f6
+select id, f1(sal) from t1 where id>= 1 group by id;
+id f1(sal)
+1 7000
+2 7000
+3 6000
+4 12000
+5 10000
+6 10000
+7 12000
+select counter, f1(sal) from t1 where id>= 1 group by counter;
+counter f1(sal)
+0 7000
+1 10000
+2 2000
+3 13000
+4 12000
+5 7000
+7 2000
+8 5000
+9 6000
+select val, f1(sal) from t1 where id>= 1 group by val;
+val f1(sal)
+10 3000
+11 13000
+12 7000
+13 5000
+14 4000
+15 5000
+16 7000
+18 6000
+19 14000
+select counter, f1(sal) from t1 where id>= 1 group by id order by counter;
+counter f1(sal)
+0 12000
+2 6000
+2 7000
+4 12000
+5 7000
+7 10000
+9 10000
+select counter, id, f1(sal), f1(sal) from t1 where id>= 1 group by id order by counter;
+counter id f1(sal) f1(sal)
+0 7 12000 12000
+2 2 7000 7000
+2 3 6000 6000
+4 4 12000 12000
+5 1 7000 7000
+7 5 10000 10000
+9 6 10000 10000
+select counter, id, f1(sal), sum(distinct sal) from t1 where id>= 1 group by id order by counter desc;
+counter id f1(sal) sum(distinct sal)
+0 7 12000 12000
+2 2 7000 7000
+2 3 6000 6000
+4 4 12000 12000
+5 1 7000 7000
+7 5 10000 10000
+9 6 10000 10000
+create table t3 (i int);
+INSERT INTO t3 (i) select f1(sal) from t1;
+select * from t3;
+i
+64000
+create aggregate function f7(x INT) returns INT
+begin
+declare z int default 0;
+DECLARE done BOOLEAN DEFAULT FALSE;
+DECLARE a,b,c INT;
+DECLARE cur1 CURSOR FOR SELECT id FROM test.t2;
+declare continue handler for not found return z;
+outer_loop: LOOP
+FETCH GROUP NEXT ROW;
+set z= z+x;
+inner_block: begin
+DECLARE cur2 CURSOR FOR SELECT id FROM test.t2;
+DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
+OPEN cur2;
+read_loop: LOOP
+FETCH cur2 INTO a;
+IF done THEN
+CLOSE cur2;
+LEAVE read_loop;
+END IF;
+END LOOP read_loop;
+end inner_block;
+END LOOP outer_loop;
+end|
+select f7(sal) from t1;
+f7(sal)
+64000
+Warnings:
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+Note 4094 At line 9 in test.f7
+drop table t1;
+drop table t2;
+drop table t3;
+drop function f1;
+drop function f2;
+drop function f3;
+drop function f4;
+drop function f5;
+drop function f6;
+drop function f7;
+create aggregate function f1(x date) returns date
+begin
+declare continue handler for not found return x;
+loop
+fetch group next row;
+end loop;
+end|
+select f1('2001-01-01'),cast(f1('2001-01-01') as time);
+f1('2001-01-01') cast(f1('2001-01-01') as time)
+2001-01-01 00:00:00
+drop function f1;
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index 220fd5a8c74..ebbc08aa958 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -896,34 +896,34 @@ WHERE REF IS NULL AND DIVISION="MIS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_N
A.DIVISION=C1.DIVISION AND A.RECEIVABLE_GROUP=C1.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=C1.CREDIT_LIMIT
ORDER BY TOTAL DESC;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived3> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived4> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived5> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived6> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived7> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived8> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived9> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived10> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived11> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived12> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived13> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived14> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived15> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived16> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived17> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived18> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived19> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived20> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived21> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived22> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived23> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived24> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived25> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived26> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived27> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived28> system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY <derived29> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived3> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived4> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived5> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived6> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived7> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived8> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived9> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived10> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived11> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived12> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived13> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived14> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived15> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived16> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived17> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived18> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived19> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived20> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived21> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived22> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived23> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived24> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived25> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived26> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived27> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived28> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived29> system NULL NULL NULL NULL 0 Const row not found
29 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
28 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
27 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
@@ -1041,6 +1041,47 @@ id id data
2 2 yes
1 NULL NULL
drop table t1;
+#
+# MDEV-14241: Server crash in key_copy / get_matching_chain_by_join_key
+# or valgrind warnings
+#
+CREATE TABLE t1 (a VARCHAR(10)) ENGINE=MyISAM;
+CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES ('foo'),('bar');
+CREATE TABLE t2 (b integer auto_increment primary key) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (NULL),(NULL);
+CREATE TABLE t3 (c VARCHAR(1024) CHARACTER SET utf8, d INT) ENGINE=MyISAM;
+CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3;
+INSERT INTO t3 VALUES ('abc',NULL),('def',4);
+SET join_cache_level= 8;
+explain
+SELECT * FROM v1, t2, v3 WHERE a = c AND b = d;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+1 PRIMARY <derived3> hash_ALL NULL #hash#$hj 3075 func 2 Using where; Using join buffer (flat, BNLH join)
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 v3.d 1 Using index
+3 DERIVED t3 ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 2
+SELECT * FROM v1, t2, v3 WHERE a = c AND b = d;
+a b c d
+DROP VIEW v1, v3;
+DROP TABLE t1, t2, t3;
+#
+# MDEV-14786: Server crashes in Item_cond::transform on 2nd
+# execution of SP querying from a view
+#
+create table t1 (i int, row_start timestamp(6) not null default now(),
+row_end timestamp(6) not null default '2030-01-01 0:0:0');
+create view v1 as select i from t1 where i < 5 and (row_end =
+TIMESTAMP'2030-01-01 0:0:0' or row_end is null);
+create procedure pr(x int) select i from v1;
+call pr(1);
+i
+call pr(2);
+i
+drop procedure pr;
+drop view v1;
+drop table t1;
# end of 5.5
#
# Start of 10.1 tests
diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result
index d8d03d6d062..32d3c88cc8d 100644
--- a/mysql-test/r/derived_cond_pushdown.result
+++ b/mysql-test/r/derived_cond_pushdown.result
@@ -6999,6 +6999,3722 @@ drop view v_union,v2_union,v3_union,v4_union;
drop view v_double,v_char,v_decimal;
drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;
#
+# MDEV-14579: pushdown conditions into materialized views/derived tables
+# that are defined with EXIST or/and INTERSECT
+#
+create table t1 (a int, b int, c int);
+create table t2 (a int, b int, c int);
+insert into t1 values
+(1,21,345), (1,33,7), (8,33,114), (1,21,500), (1,19,117), (5,14,787),
+(8,33,123), (9,10,211), (5,16,207), (1,33,988), (5,27,132), (1,21,104),
+(6,20,309), (6,20,315), (1,21,101), (4,33,404), (9,10,800), (1,21,123);
+insert into t2 values
+(2,3,207), (1,16,909), (5,14,312),
+(5,33,207), (6,20,211), (1,19,132),
+(8,33,117), (3,21,231), (6,23,303);
+create view v1 as
+select a, b, min(c) as c from t1
+where t1.a<9 group by a,b having c < 300
+intersect
+select a, b, min(c) as c from t1
+where t1.b>10 group by a,b having c > 100;
+# using intersect in view definition
+# conjunctive subformulas : pushing into WHERE
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
+a b c a b c
+1 21 101 1 16 909
+1 19 117 1 16 909
+1 21 101 1 19 132
+1 19 117 1 19 132
+select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
+a b c a b c
+1 21 101 1 16 909
+1 19 117 1 16 909
+1 21 101 1 19 132
+1 19 117 1 19 132
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a < 5 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a < 5"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c > 100",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a < 5"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using intersect in view definition
+# conjunctive subformulas : pushing into WHERE
+# pushing equalities
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a=8);
+a b c a b c
+8 33 114 8 33 117
+select * from v1,t2 where (v1.a=t2.a) and (v1.a=8);
+a b c a b c
+8 33 114 8 33 117
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a=8);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a=8);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a = 8"
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "v1.a = 8"
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a = 8"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c > 100",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a = 8 and t1.b > 10"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using intersect in view definition
+# conjunctive subformulas : pushing into WHERE using equalities
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (t2.a=8);
+a b c a b c
+8 33 114 8 33 117
+select * from v1,t2 where (v1.a=t2.a) and (t2.a=8);
+a b c a b c
+8 33 114 8 33 117
+explain select * from v1,t2 where (v1.a=t2.a) and (t2.a=8);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (t2.a=8);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a = 8"
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "v1.a = 8"
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a = 8"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c > 100",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a = 8 and t1.b > 10"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using intersect in view definition
+# conjunctive subformulas : pushing into HAVING
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.c>200);
+a b c a b c
+5 16 207 5 14 312
+5 16 207 5 33 207
+select * from v1,t2 where (v1.a=t2.a) and (v1.c>200);
+a b c a b c
+5 16 207 5 14 312
+5 16 207 5 33 207
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.c>200);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.c>200);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.c > 200",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300 and c > 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c > 100 and c > 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using intersect in view definition
+# conjunctive subformulas : pushing into WHERE
+# conjunctive subformulas : pushing into HAVING
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>110);
+a b c a b c
+1 19 117 1 16 909
+1 19 117 1 19 132
+select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>110);
+a b c a b c
+1 19 117 1 16 909
+1 19 117 1 19 132
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>110);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>110);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a < 5 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.c > 110",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300 and c > 110",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a < 5"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c > 100 and c > 110",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a < 5"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using intersect in view definition
+# extracted or formula : pushing into WHERE
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
+a b c a b c
+5 16 207 5 14 312
+5 16 207 5 33 207
+8 33 114 8 33 117
+select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
+a b c a b c
+5 16 207 5 14 312
+5 16 207 5 33 207
+8 33 114 8 33 117
+explain select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.b > 27 or v1.b < 19",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and (t1.b > 27 or t1.b < 19)"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c > 100",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and (t1.b > 27 or t1.b < 19)"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using intersect in view definition
+# extracted or formula : pushing into HAVING
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where
+(v1.a=t2.a) and ((v1.c>200) or (v1.c<105));
+a b c a b c
+1 21 101 1 16 909
+5 16 207 5 14 312
+5 16 207 5 33 207
+1 21 101 1 19 132
+select * from v1,t2 where
+(v1.a=t2.a) and ((v1.c>200) or (v1.c<105));
+a b c a b c
+1 21 101 1 16 909
+5 16 207 5 14 312
+5 16 207 5 33 207
+1 21 101 1 19 132
+explain select * from v1,t2 where
+(v1.a=t2.a) and ((v1.c>200) or (v1.c<105));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where
+(v1.a=t2.a) and ((v1.c>200) or (v1.c<105));
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.c > 200 or v1.c < 105",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300 and (c > 200 or c < 105)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c > 100 and (c > 200 or c < 105)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using intersect in view definition
+# extracted or formula : pushing into WHERE
+# extracted or formula : pushing into HAVING using equalities
+# pushing equalities
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where
+((v1.a>3) and (t2.c>110) and (v1.c=t2.c)) or
+((v1.a=1) and (v1.c<110));
+a b c a b c
+1 21 101 2 3 207
+1 21 101 1 16 909
+1 21 101 5 14 312
+1 21 101 5 33 207
+1 21 101 6 20 211
+1 21 101 1 19 132
+1 21 101 8 33 117
+1 21 101 3 21 231
+1 21 101 6 23 303
+5 16 207 2 3 207
+5 16 207 5 33 207
+5 27 132 1 19 132
+select * from v1,t2 where
+((v1.a>3) and (t2.c>110) and (v1.c=t2.c)) or
+((v1.a=1) and (v1.c<110));
+a b c a b c
+1 21 101 2 3 207
+1 21 101 1 16 909
+1 21 101 5 14 312
+1 21 101 5 33 207
+1 21 101 6 20 211
+1 21 101 1 19 132
+1 21 101 8 33 117
+1 21 101 3 21 231
+1 21 101 6 23 303
+5 16 207 2 3 207
+5 16 207 5 33 207
+5 27 132 1 19 132
+explain select * from v1,t2 where
+((v1.a>3) and (t2.c>110) and (v1.c=t2.c)) or
+((v1.a=1) and (v1.c<110));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where
+((v1.a>3) and (t2.c>110) and (v1.c=t2.c)) or
+((v1.a=1) and (v1.c<110));
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "v1.a > 3 or v1.a = 1 and v1.c < 110"
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "attached_condition": "v1.c = t2.c and v1.a > 3 and t2.c > 110 or v1.a = 1 and v1.c < 110",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300 and (t1.a > 3 and c > 110 or c < 110 and t1.a = 1)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and (t1.a > 3 or t1.a = 1)"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c > 100 and (t1.a > 3 and c > 110 or c < 110 and t1.a = 1)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and (t1.a > 3 or t1.a = 1)"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using intersect in view definition
+# prepare of a query
+# conjunctive subformulas : pushing into WHERE
+# conjunctive subformulas : pushing into HAVING
+prepare stmt from "select * from v1,t2
+ where (v1.a=t2.a) and (v1.a<5) and (v1.c>110);";
+execute stmt;
+a b c a b c
+1 19 117 1 16 909
+1 19 117 1 19 132
+execute stmt;
+a b c a b c
+1 19 117 1 16 909
+1 19 117 1 19 132
+deallocate prepare stmt;
+# using intersect in derived table definition
+# extracted or formula : pushing into WHERE using equalities
+# extracted or formula : pushing into HAVING
+# pushing equalities
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select *
+from t2,
+(select a, b, min(c) as c from t1
+where t1.a<9 group by a,b having c < 300
+intersect
+select a, b, min(c) as c from t1
+where t1.b>10 group by a,b having c > 100) as d1
+where
+(d1.b=t2.b) and
+(((t2.b>13) and (t2.c=909)) or
+((d1.a<4) and (d1.c<200)));
+a b c a b c
+1 16 909 5 16 207
+1 19 132 1 19 117
+3 21 231 1 21 101
+select *
+from t2,
+(select a, b, min(c) as c from t1
+where t1.a<9 group by a,b having c < 300
+intersect
+select a, b, min(c) as c from t1
+where t1.b>10 group by a,b having c > 100) as d1
+where
+(d1.b=t2.b) and
+(((t2.b>13) and (t2.c=909)) or
+((d1.a<4) and (d1.c<200)));
+a b c a b c
+1 16 909 5 16 207
+1 19 132 1 19 117
+3 21 231 1 21 101
+explain select *
+from t2,
+(select a, b, min(c) as c from t1
+where t1.a<9 group by a,b having c < 300
+intersect
+select a, b, min(c) as c from t1
+where t1.b>10 group by a,b having c > 100) as d1
+where
+(d1.b=t2.b) and
+(((t2.b>13) and (t2.c=909)) or
+((d1.a<4) and (d1.c<200)));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.b 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select *
+from t2,
+(select a, b, min(c) as c from t1
+where t1.a<9 group by a,b having c < 300
+intersect
+select a, b, min(c) as c from t1
+where t1.b>10 group by a,b having c > 100) as d1
+where
+(d1.b=t2.b) and
+(((t2.b>13) and (t2.c=909)) or
+((d1.a<4) and (d1.c<200)));
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.b is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["b"],
+ "ref": ["test.t2.b"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "t2.c = 909 and t2.b > 13 or d1.a < 4 and d1.c < 200",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300 and (t1.b > 13 or t1.a < 4 and c < 200)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and (t1.b > 13 or t1.a < 4)"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c > 100 and (t1.b > 13 or t1.a < 4 and c < 200)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and (t1.b > 13 or t1.a < 4)"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+create view v1 as
+select a, b, max(c) as c from t1
+where t1.a<9 group by a,b having c > 200
+except
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300;
+# using except in view definition
+# conjunctive subformulas : pushing into WHERE
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
+a b c a b c
+1 33 988 1 16 909
+1 21 500 1 16 909
+1 33 988 1 19 132
+1 21 500 1 19 132
+select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
+a b c a b c
+1 33 988 1 16 909
+1 21 500 1 16 909
+1 33 988 1 19 132
+1 21 500 1 19 132
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a < 5 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a < 5"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c < 300",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a < 5"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using except in view definition
+# conjunctive subformulas : pushing into WHERE
+# pushing equalities
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a=6);
+a b c a b c
+6 20 315 6 20 211
+6 20 315 6 23 303
+select * from v1,t2 where (v1.a=t2.a) and (v1.a=6);
+a b c a b c
+6 20 315 6 20 211
+6 20 315 6 23 303
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a=6);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a=6);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a = 6"
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "v1.a = 6"
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a = 6"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c < 300",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a = 6 and t1.b > 10"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using except in view definition
+# conjunctive subformulas : pushing into WHERE using equalities
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (t2.a=6);
+a b c a b c
+6 20 315 6 20 211
+6 20 315 6 23 303
+select * from v1,t2 where (v1.a=t2.a) and (t2.a=6);
+a b c a b c
+6 20 315 6 20 211
+6 20 315 6 23 303
+explain select * from v1,t2 where (v1.a=t2.a) and (t2.a=6);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (t2.a=6);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a = 6"
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "v1.a = 6"
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a = 6"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c < 300",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a = 6 and t1.b > 10"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using except in view definition
+# conjunctive subformulas : pushing into HAVING
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.c>500);
+a b c a b c
+1 33 988 1 16 909
+5 14 787 5 14 312
+5 14 787 5 33 207
+1 33 988 1 19 132
+select * from v1,t2 where (v1.a=t2.a) and (v1.c>500);
+a b c a b c
+1 33 988 1 16 909
+5 14 787 5 14 312
+5 14 787 5 33 207
+1 33 988 1 19 132
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.c>500);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.c>500);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.c > 500",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200 and c > 500",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c < 300 and c > 500",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using except in view definition
+# conjunctive subformulas : pushing into WHERE
+# conjunctive subformulas : pushing into HAVING
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>500);
+a b c a b c
+1 33 988 1 16 909
+1 33 988 1 19 132
+select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>500);
+a b c a b c
+1 33 988 1 16 909
+1 33 988 1 19 132
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>500);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>500);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a < 5 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.c > 500",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200 and c > 500",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a < 5"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c < 300 and c > 500",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a < 5"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using except in view definition
+# extracted or formula : pushing into WHERE
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
+a b c a b c
+1 33 988 1 16 909
+5 14 787 5 14 312
+5 14 787 5 33 207
+1 33 988 1 19 132
+select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
+a b c a b c
+1 33 988 1 16 909
+5 14 787 5 14 312
+5 14 787 5 33 207
+1 33 988 1 19 132
+explain select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.b > 27 or v1.b < 19",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and (t1.b > 27 or t1.b < 19)"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c < 300",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and (t1.b > 27 or t1.b < 19)"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using except in view definition
+# extracted or formula : pushing into HAVING
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where
+(v1.a=t2.a) and ((v1.c<400) or (v1.c>800));
+a b c a b c
+1 33 988 1 16 909
+6 20 315 6 20 211
+1 33 988 1 19 132
+6 20 315 6 23 303
+select * from v1,t2 where
+(v1.a=t2.a) and ((v1.c<400) or (v1.c>800));
+a b c a b c
+1 33 988 1 16 909
+6 20 315 6 20 211
+1 33 988 1 19 132
+6 20 315 6 23 303
+explain select * from v1,t2 where
+(v1.a=t2.a) and ((v1.c<400) or (v1.c>800));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where
+(v1.a=t2.a) and ((v1.c<400) or (v1.c>800));
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.c < 400 or v1.c > 800",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200 and (c < 400 or c > 800)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c < 300 and (c < 400 or c > 800)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using except in view definition
+# extracted or formula : pushing into WHERE
+# extracted or formula : pushing into HAVING using equalities
+# pushing equalities
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where
+(v1.c=t2.c) and
+((v1.a>1) and (t2.c<500)) or
+((v1.a=1) and (v1.c>500));
+a b c a b c
+1 33 988 2 3 207
+1 33 988 1 16 909
+1 33 988 5 14 312
+1 33 988 5 33 207
+1 33 988 6 20 211
+1 33 988 1 19 132
+1 33 988 8 33 117
+1 33 988 3 21 231
+1 33 988 6 23 303
+select * from v1,t2 where
+(v1.c=t2.c) and
+((v1.a>1) and (t2.c<500)) or
+((v1.a=1) and (v1.c>500));
+a b c a b c
+1 33 988 2 3 207
+1 33 988 1 16 909
+1 33 988 5 14 312
+1 33 988 5 33 207
+1 33 988 6 20 211
+1 33 988 1 19 132
+1 33 988 8 33 117
+1 33 988 3 21 231
+1 33 988 6 23 303
+explain select * from v1,t2 where
+(v1.c=t2.c) and
+((v1.a>1) and (t2.c<500)) or
+((v1.a=1) and (v1.c>500));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where
+(v1.c=t2.c) and
+((v1.a>1) and (t2.c<500)) or
+((v1.a=1) and (v1.c>500));
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "v1.a > 1 or v1.a = 1 and v1.c > 500"
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "attached_condition": "v1.c = t2.c and v1.a > 1 and t2.c < 500 or v1.a = 1 and v1.c > 500",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200 and (t1.a > 1 and c < 500 or c > 500 and t1.a = 1)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and (t1.a > 1 or t1.a = 1)"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c < 300 and (t1.a > 1 and c < 500 or c > 500 and t1.a = 1)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and (t1.a > 1 or t1.a = 1)"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+# using except in view definition
+# prepare of a query
+# conjunctive subformulas : pushing into WHERE
+# conjunctive subformulas : pushing into HAVING
+prepare stmt from "select * from v1,t2
+ where (v1.a=t2.a) and (v1.a<5) and (v1.c>500);";
+execute stmt;
+a b c a b c
+1 33 988 1 16 909
+1 33 988 1 19 132
+execute stmt;
+a b c a b c
+1 33 988 1 16 909
+1 33 988 1 19 132
+deallocate prepare stmt;
+# using except in view definition
+# extracted or formula : pushing into WHERE using equalities
+# extracted or formula : pushing into HAVING
+# pushing equalities
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select *
+from t2,
+(select a, b, max(c) as c from t1
+where t1.a<9 group by a,b having c > 200
+except
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300) as d1
+where
+(d1.b=t2.b) and
+(((t2.b>13) and (t2.c=988)) or
+((d1.a>4) and (d1.c>500)));
+a b c a b c
+5 14 312 5 14 787
+select *
+from t2,
+(select a, b, max(c) as c from t1
+where t1.a<9 group by a,b having c > 200
+except
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300) as d1
+where
+(d1.b=t2.b) and
+(((t2.b>13) and (t2.c=988)) or
+((d1.a>4) and (d1.c>500)));
+a b c a b c
+5 14 312 5 14 787
+explain select *
+from t2,
+(select a, b, max(c) as c from t1
+where t1.a<9 group by a,b having c > 200
+except
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300) as d1
+where
+(d1.b=t2.b) and
+(((t2.b>13) and (t2.c=988)) or
+((d1.a>4) and (d1.c>500)));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.b 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select *
+from t2,
+(select a, b, max(c) as c from t1
+where t1.a<9 group by a,b having c > 200
+except
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300) as d1
+where
+(d1.b=t2.b) and
+(((t2.b>13) and (t2.c=988)) or
+((d1.a>4) and (d1.c>500)));
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.b is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["b"],
+ "ref": ["test.t2.b"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "t2.c = 988 and t2.b > 13 or d1.a > 4 and d1.c > 500",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200 and (t1.b > 13 or t1.a > 4 and c > 500)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and (t1.b > 13 or t1.a > 4)"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c < 300 and (t1.b > 13 or t1.a > 4 and c > 500)",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and (t1.b > 13 or t1.a > 4)"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using union and intersect in view definition
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, min(c) as c from t1
+where t1.a<9 group by a,b having c > 200
+union
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300
+intersect
+select a, b, max(c) as c from t1
+where t1.a>3 group by a,b having c < 530;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
+a b c a b c
+6 20 309 6 20 211
+6 20 309 6 23 303
+select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
+a b c a b c
+6 20 309 6 20 211
+6 20 309 6 23 303
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 3 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 UNION <derived4> ALL NULL NULL NULL NULL 18 Using where
+4 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+5 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect4,5> ALL NULL NULL NULL NULL NULL
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 5 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "v1.c > 200",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<union2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200 and c > 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a > 5"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "UNION",
+ "table": {
+ "table_name": "<derived4>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "__3.a > 5 and __3.c > 200",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect4,5>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 4,
+ "having_condition": "c < 300 and c > 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a > 5"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 5,
+ "operation": "INTERSECT",
+ "having_condition": "c < 530 and c > 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a > 3 and t1.a > 5"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using union and intersect in view definition
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, min(c) as c from t1
+where t1.a<9 group by a,b having c > 200
+intersect
+select a, b, max(c) as c from t1
+where t1.a>3 group by a,b having c < 500
+union
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
+a b c a b c
+5 27 132 5 14 312
+5 27 132 5 33 207
+8 33 123 8 33 117
+select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
+a b c a b c
+5 27 132 5 14 312
+5 27 132 5 33 207
+8 33 123 8 33 117
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 3 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+4 UNION t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL UNIT RESULT <unit2,3,4> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 4 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "v1.c < 200",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<unit2,3,4>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200 and c < 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c < 500 and c < 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a > 3 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 4,
+ "operation": "UNION",
+ "having_condition": "c < 300 and c < 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a > 4"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using union and except in view definition
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, min(c) as c from t1
+where t1.a<9 group by a,b having c > 200
+union
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300
+except
+select a, b, max(c) as c from t1
+where t1.a>3 group by a,b having c < 530;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
+a b c a b c
+6 20 309 6 20 211
+6 20 309 6 23 303
+select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
+a b c a b c
+6 20 309 6 20 211
+6 20 309 6 23 303
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 3 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 UNION t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+4 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL UNIT RESULT <unit2,3,4> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 5 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "v1.c > 200",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<unit2,3,4>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200 and c > 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a > 5"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "UNION",
+ "having_condition": "c < 300 and c > 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a > 5"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 4,
+ "operation": "EXCEPT",
+ "having_condition": "c < 530 and c > 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a > 3 and t1.a > 5"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using union and except in view definition
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, min(c) as c from t1
+where t1.a<9 group by a,b having c > 200
+except
+select a, b, max(c) as c from t1
+where t1.a>3 group by a,b having c < 500
+union
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
+a b c a b c
+5 27 132 5 14 312
+5 27 132 5 33 207
+8 33 123 8 33 117
+select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
+a b c a b c
+5 27 132 5 14 312
+5 27 132 5 33 207
+8 33 123 8 33 117
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 3 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+4 UNION t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL UNIT RESULT <unit2,3,4> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 4 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "v1.c < 200",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<unit2,3,4>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 200 and c < 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c < 500 and c < 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a > 3 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 4,
+ "operation": "UNION",
+ "having_condition": "c < 300 and c < 200",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a > 4"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using except and intersect in view definition
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300
+intersect
+select a, b, max(c) as c from t1
+where t1.a<7 group by a,b having c < 500
+except
+select a, b, max(c) as c from t1
+where t1.a<9 group by a,b having c > 150;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<150);
+a b c a b c
+5 27 132 5 14 312
+5 27 132 5 33 207
+select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<150);
+a b c a b c
+5 27 132 5 14 312
+5 27 132 5 33 207
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<150);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+4 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL UNIT RESULT <unit2,3,4> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<150);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 4 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.c < 150",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<unit2,3,4>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300 and c < 150",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c < 500 and c < 150",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 7 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 4,
+ "operation": "EXCEPT",
+ "having_condition": "c > 150 and c < 150",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a > 4"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using except and intersect in view definition
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300
+except
+select a, b, max(c) as c from t1
+where t1.a<9 group by a,b having c > 150
+intersect
+select a, b, max(c) as c from t1
+where t1.a<7 group by a,b having c < 500;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
+a b c a b c
+8 33 123 8 33 117
+select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
+a b c a b c
+8 33 123 8 33 117
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT <derived4> ALL NULL NULL NULL NULL 18 Using where
+4 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+5 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect4,5> ALL NULL NULL NULL NULL NULL
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 4 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.c < 130",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300 and c < 130",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "table": {
+ "table_name": "<derived4>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "__3.a > 4 and __3.c < 130",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect4,5>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 4,
+ "having_condition": "c > 150 and c < 130",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 5,
+ "operation": "INTERSECT",
+ "having_condition": "c < 500 and c < 130",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 7 and t1.a > 4"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using except, intersect and union in view definition
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300
+except
+select a, b, max(c) as c from t1
+where t1.a<9 group by a,b having c > 150
+intersect
+select a, b, max(c) as c from t1
+where t1.a<7 group by a,b having c < 500
+union
+select a, b, max(c) as c from t1
+where t1.a<7 group by a,b having c < 120;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
+a b c a b c
+8 33 123 8 33 117
+select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
+a b c a b c
+8 33 123 8 33 117
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 3 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT <derived4> ALL NULL NULL NULL NULL 18 Using where
+4 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+5 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect4,5> ALL NULL NULL NULL NULL NULL
+6 UNION t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL UNIT RESULT <unit2,3,6> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 4 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "v1.c < 130",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<unit2,3,6>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 300 and c < 130",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "table": {
+ "table_name": "<derived4>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "__3.a > 4 and __3.c < 130",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect4,5>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 4,
+ "having_condition": "c > 150 and c < 130",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 5,
+ "operation": "INTERSECT",
+ "having_condition": "c < 500 and c < 130",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 7 and t1.a > 4"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 6,
+ "operation": "UNION",
+ "having_condition": "c < 120 and c < 130",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 7 and t1.a > 4"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using intersect in view definition
+# using embedded view
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300
+intersect
+select a, b, max(c) as c from t1
+where t1.a<9 group by a,b having c > 120;
+create view v2 as
+select a, b, max(c) as c from v1
+where v1.a<7 group by a,b;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
+a b c a b c
+5 27 132 5 14 312
+5 27 132 5 33 207
+select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
+a b c a b c
+5 27 132 5 14 312
+5 27 132 5 33 207
+explain select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED <derived3> ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+4 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect3,4> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 4 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v2.c < 150",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 150",
+ "filesort": {
+ "sort_key": "v1.a, v1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "v1.a < 7 and v1.a > 4",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect3,4>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "c < 300",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a < 7 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 4,
+ "operation": "INTERSECT",
+ "having_condition": "c > 120",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a < 7 and t1.a > 4"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1,v2;
+# using except in view definition
+# using embedded view
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c < 300
+except
+select a, b, max(c) as c from t1
+where t1.a<9 group by a,b having c > 150;
+create view v2 as
+select a, b, max(c) as c from v1
+where v1.a<7 group by a,b;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
+a b c a b c
+5 27 132 5 14 312
+5 27 132 5 33 207
+select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
+a b c a b c
+5 27 132 5 14 312
+5 27 132 5 33 207
+explain select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED <derived3> ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+4 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except3,4> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 4 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v2.c < 150",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c < 150",
+ "filesort": {
+ "sort_key": "v1.a, v1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "v1.a < 7 and v1.a > 4",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except3,4>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "c < 300",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a < 7 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 4,
+ "operation": "EXCEPT",
+ "having_condition": "c > 150",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a < 7 and t1.a > 4"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1,v2;
+# using intersect in view definition
+# conditions are pushed in different parts of selects
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, max(c) as c from t1
+where t1.a<9 group by a having c > 300
+intersect
+select a, b, max(c) as c from t1
+where t1.b<21 group by b having c > 200;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.b>12) and (v1.c<450);
+a b c a b c
+6 20 315 6 20 211
+6 20 315 6 23 303
+select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.b>12) and (v1.c<450);
+a b c a b c
+6 20 315 6 20 211
+6 20 315 6 23 303
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.b>12) and (v1.c<450);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.b>12) and (v1.c<450);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 4 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.b > 12 and v1.c < 450",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<intersect2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 300 and t1.b > 12 and c < 450",
+ "filesort": {
+ "sort_key": "t1.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a > 4"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c > 200 and t1.a > 4 and c < 450",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b < 21 and t1.b > 12"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using except in view definition
+# conditions are pushed in different parts of selects
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, max(c) as c from t1
+where t1.b>20 group by a having c > 300
+except
+select a, b, max(c) as c from t1
+where t1.a<7 group by b having c > 150;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a<2) and (v1.b<30) and (v1.c>450);
+a b c a b c
+1 21 988 1 16 909
+1 21 988 1 19 132
+select * from v1,t2 where (v1.a=t2.a) and (v1.a<2) and (v1.b<30) and (v1.c>450);
+a b c a b c
+1 21 988 1 16 909
+1 21 988 1 19 132
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a<2) and (v1.b<30) and (v1.c>450);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a<2) and (v1.b<30) and (v1.c>450);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a < 2 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.b < 30 and v1.c > 450",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 300 and t1.b < 30 and c > 450",
+ "filesort": {
+ "sort_key": "t1.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 20 and t1.a < 2"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c > 150 and t1.a < 2 and c > 450",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 7 and t1.b < 30"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using except and union in view definition
+# conditions are pushed in different parts of selects
+# conjunctive subformulas : pushing into HAVING
+# extracted or formula : pushing into WHERE
+# extracted or formula : pushing into HAVING
+create view v1 as
+select a, b, max(c) as c from t1
+where t1.b>20 group by a having c > 300
+except
+select a, b, max(c) as c from t1
+where t1.a<7 group by b having c > 150;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and ((v1.a<2) or (v1.a<5)) and (v1.c>450);
+a b c a b c
+1 21 988 1 16 909
+1 21 988 1 19 132
+select * from v1,t2 where (v1.a=t2.a) and ((v1.a<2) or (v1.a<5)) and (v1.c>450);
+a b c a b c
+1 21 988 1 16 909
+1 21 988 1 19 132
+explain select * from v1,t2 where (v1.a=t2.a) and ((v1.a<2) or (v1.a<5)) and (v1.c>450);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and ((v1.a<2) or (v1.a<5)) and (v1.c>450);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "(t2.a < 2 or t2.a < 5) and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.c > 450",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<except2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 300 and c > 450",
+ "filesort": {
+ "sort_key": "t1.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 20 and (t1.a < 2 or t1.a < 5)"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "EXCEPT",
+ "having_condition": "c > 150 and (t1.a < 2 or t1.a < 5) and c > 450",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 7"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using union and intersect in view definition
+# conditions are pushed in different parts of selects
+# conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+select a, b, max(c) as c from t1
+where t1.a<9 group by a having c > 100
+intersect
+select a, b, max(c) as c from t1
+where t1.a>3 group by b having c < 800
+union
+select a, b, max(c) as c from t1
+where t1.b>10 group by a,b having c > 300;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.a>1) and (v1.b > 12) and (v1.c>400);
+a b c a b c
+5 14 787 5 14 312
+5 14 787 5 33 207
+select * from v1,t2 where (v1.a=t2.a) and (v1.a>1) and (v1.b > 12) and (v1.c>400);
+a b c a b c
+5 14 787 5 14 312
+5 14 787 5 33 207
+explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>1) and (v1.b > 12) and (v1.c>400);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 3 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+4 UNION t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort
+NULL UNIT RESULT <unit2,3,4> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.a>1) and (v1.b > 12) and (v1.c>400);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.a > 1 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "v1.b > 12 and v1.c > 400",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<unit2,3,4>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "c > 100 and t1.b > 12 and c > 400",
+ "filesort": {
+ "sort_key": "t1.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a < 9 and t1.a > 1"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "INTERSECT",
+ "having_condition": "c < 800 and t1.a > 1 and c > 400",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.a > 3 and t1.b > 12"
+ }
+ }
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 4,
+ "operation": "UNION",
+ "having_condition": "c > 300 and c > 400",
+ "filesort": {
+ "sort_key": "t1.a, t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 18,
+ "filtered": 100,
+ "attached_condition": "t1.b > 10 and t1.a > 1 and t1.b > 12"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+create table t3 (a int, b int, c int);
+insert into t3 values
+(1,21,345), (2,33,7), (8,33,114), (3,21,500), (1,19,107), (5,14,787),
+(4,33,123), (9,10,211), (11,16,207), (10,33,988), (5,27,132), (12,21,104),
+(6,20,309), (16,20,315), (16,21,101), (18,33,404), (19,10,800), (10,21,123),
+(17,11,708), (6,20,214);
+create index i1 on t3(a);
+# conjunctive subformulas : pushing into WHERE
+# pushed condition gives range access
+create view v1 as
+select a, b, max(c) as max_c from t3
+where a>0 group by a;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.b=t2.b) and (v1.a<5);
+a b max_c a b c
+4 33 123 5 33 207
+2 33 7 5 33 207
+4 33 123 8 33 117
+2 33 7 8 33 117
+3 21 500 3 21 231
+1 21 345 3 21 231
+select * from v1,t2 where (v1.b=t2.b) and (v1.a<5);
+a b max_c a b c
+1 21 345 3 21 231
+2 33 7 5 33 207
+2 33 7 8 33 117
+3 21 500 3 21 231
+4 33 123 5 33 207
+4 33 123 8 33 117
+explain select * from v1,t2 where (v1.b=t2.b) and (v1.a<5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t3 range i1 i1 5 NULL 5 Using index condition
+explain format=json select * from v1,t2 where (v1.b=t2.b) and (v1.a<5);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 80,
+ "attached_condition": "v1.a < 5"
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "attached_condition": "v1.b = t2.b",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "table_name": "t3",
+ "access_type": "range",
+ "possible_keys": ["i1"],
+ "key": "i1",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "rows": 5,
+ "filtered": 100,
+ "index_condition": "t3.a > 0 and t3.a < 5"
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+# using union in view definition
+# conjunctive subformulas : pushing into WHERE
+# pushed condition gives range access
+create view v1 as
+select a, b, max(c) as c from t3
+where t3.a>1 group by a
+union
+select a, b, max(c) as c from t3
+where t3.a>2 group by a;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.b=t2.b) and (v1.a<4);
+a b c a b c
+2 33 7 5 33 207
+2 33 7 8 33 117
+3 21 500 3 21 231
+select * from v1,t2 where (v1.b=t2.b) and (v1.a<4);
+a b c a b c
+2 33 7 5 33 207
+2 33 7 8 33 117
+3 21 500 3 21 231
+explain select * from v1,t2 where (v1.b=t2.b) and (v1.a<4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t3 range i1 i1 5 NULL 2 Using index condition
+3 UNION t3 range i1 i1 5 NULL 1 Using index condition
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.b=t2.b) and (v1.a<4);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "v1.a < 4",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<union2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "table_name": "t3",
+ "access_type": "range",
+ "possible_keys": ["i1"],
+ "key": "i1",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "rows": 2,
+ "filtered": 100,
+ "index_condition": "t3.a > 1 and t3.a < 4"
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "UNION",
+ "table": {
+ "table_name": "t3",
+ "access_type": "range",
+ "possible_keys": ["i1"],
+ "key": "i1",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "rows": 1,
+ "filtered": 100,
+ "index_condition": "t3.a > 2 and t3.a < 4"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "attached_condition": "t2.b = v1.b"
+ }
+ }
+}
+drop view v1;
+# using union in view definition
+# conjunctive subformulas : pushing into WHERE
+# pushed condition gives range access in one of the selects
+create view v1 as
+select a, b, max(c) as c from t3
+where t3.a>1 group by a
+union
+select a, b, max(c) as c from t3
+where t3.b<21 group by b;
+set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.b=t2.b) and (v1.a<3);
+a b c a b c
+2 33 7 5 33 207
+1 19 107 1 19 132
+2 33 7 8 33 117
+select * from v1,t2 where (v1.b=t2.b) and (v1.a<3);
+a b c a b c
+2 33 7 5 33 207
+1 19 107 1 19 132
+2 33 7 8 33 117
+explain select * from v1,t2 where (v1.b=t2.b) and (v1.a<3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.b 2 Using where
+2 DERIVED t3 range i1 i1 5 NULL 1 Using index condition
+3 UNION t3 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+explain format=json select * from v1,t2 where (v1.b=t2.b) and (v1.a<3);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100,
+ "attached_condition": "t2.b is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["b"],
+ "ref": ["test.t2.b"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "v1.a < 3",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<union2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "table_name": "t3",
+ "access_type": "range",
+ "possible_keys": ["i1"],
+ "key": "i1",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "rows": 1,
+ "filtered": 100,
+ "index_condition": "t3.a > 1 and t3.a < 3"
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "UNION",
+ "having_condition": "t3.a < 3",
+ "filesort": {
+ "sort_key": "t3.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t3",
+ "access_type": "ALL",
+ "rows": 20,
+ "filtered": 100,
+ "attached_condition": "t3.b < 21"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+drop view v1;
+alter table t3 drop index i1;
+drop table t1,t2,t3;
+#
# MDEV-10782: condition extracted from a multiple equality
# pushed into HAVING
#
@@ -8824,10 +12540,74 @@ EXPLAIN
}
drop table t1;
#
+# MDEV-13454: consequence of mdev-14368 fixed for 5.5
+#
+SET sql_mode = 'ONLY_FULL_GROUP_BY';
+create table t1 (id int, id2 int);
+insert into t1 values (1,1),(2,3),(3,4),(7,2);
+create table t2(id2 int);
+insert t2 values (1),(2),(3);
+SELECT * FROM t1
+LEFT OUTER JOIN
+(SELECT id2, COUNT(*) as ct FROM t2 GROUP BY id2) vc USING (id2)
+WHERE (vc.ct>0);
+id2 id ct
+1 1 1
+3 2 1
+2 7 1
+EXPLAIN FORMAT=JSON SELECT * FROM t1
+LEFT OUTER JOIN
+(SELECT id2, COUNT(*) as ct FROM t2 GROUP BY id2) vc USING (id2)
+WHERE (vc.ct>0);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "vc.ct > 0",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "ct > 0",
+ "filesort": {
+ "sort_key": "t2.id2",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 4,
+ "filtered": 100
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "attached_condition": "t1.id2 = vc.id2"
+ }
+ }
+}
+DROP TABLE t1,t2;
+SET sql_mode = DEFAULT;
+#
# MDEV-10855: Pushdown into derived with window functions
#
set @save_optimizer_switch= @@optimizer_switch;
-set optimizer_switch='split_grouping_derived=off';
+set optimizer_switch='split_materialized=off';
create table t1 (a int, c varchar(16));
insert into t1 values
(8,'aa'), (5,'cc'), (1,'bb'), (2,'aa'), (9,'cc'),
@@ -9528,59 +13308,76 @@ set optimizer_switch= @save_optimizer_switch;
# MDEV-13389: Optimization for equi-joins of derived tables with WF
# (Splitting derived tables / views with window functions)
#
-create table t1 (a int);
+create table t1 (a int, b int, index idx_b(b)) engine=myisam;
insert into t1 values
-(8), (5), (1), (2), (9), (7), (2), (7);
-create table t2 (a int, b int, index idx(a));
+(8,3), (5,7), (1,2), (2,1), (9,7), (7,5), (2,2), (7,3),
+(9,3), (8,1), (4,5), (2,3);
+create table t2 (a int, b int, c char(127), index idx_a(a)) engine=myisam;
insert into t2 values
-(7,10), (1,20), (2,23), (7,18), (1,30),
-(4,71), (3,15), (7,82), (8,12), (4,15),
-(11,33), (10,42), (4,53), (10,17), (2,90);
-set statement optimizer_switch='split_grouping_derived=off' for select t1.a,t.max,t.min
+(7,10,'x'), (1,20,'a'), (2,23,'b'), (7,18,'z'), (1,30,'c'),
+(4,71,'d'), (3,15,'x'), (7,82,'y'), (8,12,'t'), (4,15,'b'),
+(11,33,'a'), (10,42,'u'), (4,53,'p'), (10,17,'r'), (2,90,'x'),
+(17,10,'s'), (11,20,'v'), (12,23,'y'), (17,18,'a'), (11,30,'d'),
+(24,71,'h'), (23,15,'i'), (27,82,'k'), (28,12,'p'), (24,15,'q'),
+(31,33,'f'), (30,42,'h'), (40,53,'m'), (30,17,'o'), (21,90,'b'),
+(37,10,'e'), (31,20,'g'), (32,23,'f'), (37,18,'n'), (41,30,'l'),
+(54,71,'j'), (53,15,'w'), (57,82,'z'), (58,12,'k'), (54,15,'p'),
+(61,33,'c'), (60,42,'a'), (62,53,'x'), (67,17,'g'), (64,90,'v');
+insert into t2 select a+10, b+10, concat(c,'f') from t2;
+analyze table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+test.t2 analyze status OK
+set statement optimizer_switch='split_materialized=off' for select t1.a,t.s,t.m
from t1 join
-(select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) t
-on t1.a=t.a;
-a max min
-8 12 12
-1 30 20
-2 90 23
-7 82 10
-2 90 23
-7 82 10
-select t1.a,t.max,t.min
+(select a, sum(t2.b) as s, min(t2.c) as m from t2 group by t2.a) t
+on t1.a=t.a
+where t1.b < 3;
+a s m
+2 113 b
+8 12 t
+1 50 a
+2 113 b
+select t1.a,t.s,t.m
from t1 join
-(select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) t
-on t1.a=t.a;
-a max min
-8 12 12
-1 30 20
-2 90 23
-7 82 10
-2 90 23
-7 82 10
-explain extended select t1.a,t.max,t.min
+(select a, sum(t2.b) as s, min(t2.c) as m from t2 group by t2.a) t
+on t1.a=t.a
+where t1.b < 3;
+a s m
+2 113 b
+8 12 t
+1 50 a
+2 113 b
+explain extended select t1.a,t.s,t.m
from t1 join
-(select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) t
-on t1.a=t.a;
+(select a, sum(t2.b) as s, min(t2.c) as m from t2 group by t2.a) t
+on t1.a=t.a
+where t1.b < 3;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00 Using where
+1 PRIMARY t1 range idx_b idx_b 5 NULL 4 100.00 Using index condition; Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 2 100.00
-2 LATERAL DERIVED t2 ref idx idx 5 test.t1.a 2 100.00
+2 LATERAL DERIVED t2 ref idx_a idx_a 5 test.t1.a 2 100.00
Warnings:
-Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t1` join (/* select#2 */ select `test`.`t2`.`a` AS `a`,max(`test`.`t2`.`b`) AS `max`,min(`test`.`t2`.`b`) AS `min` from `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` group by `test`.`t2`.`a`) `t` where `t`.`a` = `test`.`t1`.`a`
-explain format=json select t1.a,t.max,t.min
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`t`.`s` AS `s`,`t`.`m` AS `m` from `test`.`t1` join (/* select#2 */ select `test`.`t2`.`a` AS `a`,sum(`test`.`t2`.`b`) AS `s`,min(`test`.`t2`.`c`) AS `m` from `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` group by `test`.`t2`.`a`) `t` where `t`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` < 3
+explain format=json select t1.a,t.s,t.m
from t1 join
-(select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) t
-on t1.a=t.a;
+(select a, sum(t2.b) as s, min(t2.c) as m from t2 group by t2.a) t
+on t1.a=t.a
+where t1.b < 3;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t1",
- "access_type": "ALL",
- "rows": 8,
+ "access_type": "range",
+ "possible_keys": ["idx_b"],
+ "key": "idx_b",
+ "key_length": "5",
+ "used_key_parts": ["b"],
+ "rows": 4,
"filtered": 100,
+ "index_condition": "t1.b < 3",
"attached_condition": "t1.a is not null"
},
"table": {
@@ -9600,8 +13397,8 @@ EXPLAIN
"table": {
"table_name": "t2",
"access_type": "ref",
- "possible_keys": ["idx"],
- "key": "idx",
+ "possible_keys": ["idx_a"],
+ "key": "idx_a",
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["test.t1.a"],
@@ -9613,40 +13410,167 @@ EXPLAIN
}
}
}
-set statement optimizer_switch='split_grouping_derived=off' for select t1.a,t.max,t.min
+prepare stmt from "select t1.a,t.s,t.m
+from t1 join
+(select a, sum(t2.b) as s, min(t2.c) as m from t2 group by t2.a) t
+on t1.a=t.a
+where t1.b < 3";
+execute stmt;
+a s m
+2 113 b
+8 12 t
+1 50 a
+2 113 b
+execute stmt;
+a s m
+2 113 b
+8 12 t
+1 50 a
+2 113 b
+deallocate prepare stmt;
+set statement optimizer_switch='split_materialized=off' for select t1.a,t.s,t.m
+from t1 join
+(select a, sum(t2.b) as s, min(t2.b) as m from t2 group by t2.a) t
+on t1.a=t.a
+where t1.b <= 5;
+a s m
+8 12 12
+1 50 20
+2 113 23
+7 110 10
+2 113 23
+7 110 10
+8 12 12
+4 139 15
+2 113 23
+select t1.a,t.s,t.m
+from t1 join
+(select a, sum(t2.b) as s, min(t2.b) as m from t2 group by t2.a) t
+on t1.a=t.a
+where t1.b <= 5;
+a s m
+8 12 12
+1 50 20
+2 113 23
+7 110 10
+2 113 23
+7 110 10
+8 12 12
+4 139 15
+2 113 23
+explain extended select t1.a,t.s,t.m
+from t1 join
+(select a, sum(t2.b) as s, min(t2.b) as m from t2 group by t2.a) t
+on t1.a=t.a
+where t1.b <= 5;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL idx_b NULL NULL NULL 12 75.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 9 100.00
+2 DERIVED t2 ALL idx_a NULL NULL NULL 90 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`t`.`s` AS `s`,`t`.`m` AS `m` from `test`.`t1` join (/* select#2 */ select `test`.`t2`.`a` AS `a`,sum(`test`.`t2`.`b`) AS `s`,min(`test`.`t2`.`b`) AS `m` from `test`.`t2` group by `test`.`t2`.`a`) `t` where `t`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <= 5
+explain format=json select t1.a,t.s,t.m
+from t1 join
+(select a, sum(t2.b) as s, min(t2.b) as m from t2 group by t2.a) t
+on t1.a=t.a
+where t1.b <= 5;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "possible_keys": ["idx_b"],
+ "rows": 12,
+ "filtered": 75,
+ "attached_condition": "t1.b <= 5 and t1.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t1.a"],
+ "rows": 9,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "filesort": {
+ "sort_key": "t2.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "possible_keys": ["idx_a"],
+ "rows": 90,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+prepare stmt from "select t1.a,t.s,t.m
+from t1 join
+(select a, sum(t2.b) as s, min(t2.b) as m from t2 group by t2.a) t
+on t1.a=t.a
+where t1.b <= 5";
+execute stmt;
+a s m
+8 12 12
+1 50 20
+2 113 23
+7 110 10
+2 113 23
+7 110 10
+8 12 12
+4 139 15
+2 113 23
+execute stmt;
+a s m
+8 12 12
+1 50 20
+2 113 23
+7 110 10
+2 113 23
+7 110 10
+8 12 12
+4 139 15
+2 113 23
+deallocate prepare stmt;
+delete from t1 where t1.b between 2 and 5;
+set statement optimizer_switch='split_materialized=off' for select t1.a,t.max,t.min
from t1 left join
(select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) t
on t1.a=t.a;
a max min
-8 12 12
5 NULL NULL
-1 30 20
2 90 23
9 NULL NULL
-7 82 10
-2 90 23
-7 82 10
+8 12 12
select t1.a,t.max,t.min
from t1 left join
(select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) t
on t1.a=t.a;
a max min
-8 12 12
5 NULL NULL
-1 30 20
2 90 23
9 NULL NULL
-7 82 10
-2 90 23
-7 82 10
+8 12 12
explain extended select t1.a,t.max,t.min
from t1 left join
(select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) t
on t1.a=t.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00
1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 2 100.00 Using where
-2 LATERAL DERIVED t2 ref idx idx 5 test.t1.a 2 100.00
+2 LATERAL DERIVED t2 ref idx_a idx_a 5 test.t1.a 2 100.00
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t1` left join (/* select#2 */ select `test`.`t2`.`a` AS `a`,max(`test`.`t2`.`b`) AS `max`,min(`test`.`t2`.`b`) AS `min` from `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` group by `test`.`t2`.`a`) `t` on(`t`.`a` = `test`.`t1`.`a` and `test`.`t1`.`a` is not null) where 1
explain format=json select t1.a,t.max,t.min
@@ -9661,7 +13585,7 @@ EXPLAIN
"table": {
"table_name": "t1",
"access_type": "ALL",
- "rows": 8,
+ "rows": 4,
"filtered": 100
},
"table": {
@@ -9682,8 +13606,8 @@ EXPLAIN
"table": {
"table_name": "t2",
"access_type": "ref",
- "possible_keys": ["idx"],
- "key": "idx",
+ "possible_keys": ["idx_a"],
+ "key": "idx_a",
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["test.t1.a"],
@@ -9695,53 +13619,68 @@ EXPLAIN
}
}
}
-create table t3 (a int, c varchar(16));
+create table t3 (a int, b int, c char(127), index idx_b(b)) engine=myisam;
insert into t3 values
-(8,'aa'), (5,'cc'), (1,'bb'), (2,'aa'), (9,'cc'),
-(7,'aa'), (2,'aa'), (7,'bb');
-create table t4 (a int, b int, c varchar(16), index idx(a,c));
+(8,11,'aa'), (5,15,'cc'), (1,14,'bb'), (2,12,'aa'), (7,17,'cc'),
+(7,18,'aa'), (2,11,'aa'), (7,10,'bb'), (3,11,'dd'), (4,12,'ee'),
+(5,14,'dd'), (9,12,'ee');
+create table t4 (a int, b int, c char(127), index idx(a,c)) engine=myisam;
insert into t4 values
(7,10,'cc'), (1,20,'aa'), (2,23,'bb'), (7,18,'cc'), (1,30,'bb'),
-(4,71,'xx'), (3,15,'aa'), (7,82,'bb'), (8,12,'dd'), (4,15,'aa'),
-(11,33,'yy'), (10,42,'zz'), (4,53,'xx'), (10,17,'yy'), (7,12,'bb'),
+(4,71,'xx'), (3,15,'aa'), (7,82,'aa'), (8,12,'dd'), (4,15,'aa'),
+(11,33,'yy'), (10,42,'zz'), (4,53,'xx'), (10,17,'yy'), (7,12,'cc'),
(8,20,'dd'), (7,32,'bb'), (1,50,'aa'), (3,40,'bb'), (3,77,'aa');
-set statement optimizer_switch='split_grouping_derived=off' for select t3.a,t3.c,t.max,t.min
+insert into t4 select a+10, b+10, concat(c,'f') from t4;
+analyze table t3,t4;
+Table Op Msg_type Msg_text
+test.t3 analyze status OK
+test.t4 analyze status OK
+set statement optimizer_switch='split_materialized=off' for select t3.a,t3.c,t.max,t.min
from t3 join
(select a, c, max(b) max, min(b) min from t4 group by a,c) t
-on t3.a=t.a and t3.c=t.c;
+on t3.a=t.a and t3.c=t.c
+where t3.b > 15;
a c max min
-1 bb 30 30
-7 bb 82 12
+7 cc 18 10
+7 aa 82 82
select t3.a,t3.c,t.max,t.min
from t3 join
(select a, c, max(b) max, min(b) min from t4 group by a,c) t
-on t3.a=t.a and t3.c=t.c;
+on t3.a=t.a and t3.c=t.c
+where t3.b > 15;
a c max min
-1 bb 30 30
-7 bb 82 12
+7 cc 18 10
+7 aa 82 82
explain extended select t3.a,t3.c,t.max,t.min
from t3 join
(select a, c, max(b) max, min(b) min from t4 group by a,c) t
-on t3.a=t.a and t3.c=t.c;
+on t3.a=t.a and t3.c=t.c
+where t3.b > 15;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t3 ALL NULL NULL NULL NULL 8 100.00 Using where
-1 PRIMARY <derived2> ref key0 key0 24 test.t3.a,test.t3.c 2 100.00
-2 LATERAL DERIVED t4 ref idx idx 24 test.t3.a,test.t3.c 2 100.00
+1 PRIMARY t3 range idx_b idx_b 5 NULL 3 100.00 Using index condition; Using where
+1 PRIMARY <derived2> ref key0 key0 133 test.t3.a,test.t3.c 2 100.00
+2 LATERAL DERIVED t4 ref idx idx 133 test.t3.a,test.t3.c 1 100.00
Warnings:
-Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`a` = `test`.`t3`.`a` and `test`.`t4`.`c` = `test`.`t3`.`c` group by `test`.`t4`.`a`,`test`.`t4`.`c`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c`
+Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`a` = `test`.`t3`.`a` and `test`.`t4`.`c` = `test`.`t3`.`c` group by `test`.`t4`.`a`,`test`.`t4`.`c`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t3`.`b` > 15
explain format=json select t3.a,t3.c,t.max,t.min
from t3 join
(select a, c, max(b) max, min(b) min from t4 group by a,c) t
-on t3.a=t.a and t3.c=t.c;
+on t3.a=t.a and t3.c=t.c
+where t3.b > 15;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t3",
- "access_type": "ALL",
- "rows": 8,
+ "access_type": "range",
+ "possible_keys": ["idx_b"],
+ "key": "idx_b",
+ "key_length": "5",
+ "used_key_parts": ["b"],
+ "rows": 3,
"filtered": 100,
+ "index_condition": "t3.b > 15",
"attached_condition": "t3.a is not null and t3.c is not null"
},
"table": {
@@ -9749,7 +13688,7 @@ EXPLAIN
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
- "key_length": "24",
+ "key_length": "133",
"used_key_parts": ["a", "c"],
"ref": ["test.t3.a", "test.t3.c"],
"rows": 2,
@@ -9763,10 +13702,10 @@ EXPLAIN
"access_type": "ref",
"possible_keys": ["idx"],
"key": "idx",
- "key_length": "24",
+ "key_length": "133",
"used_key_parts": ["a", "c"],
"ref": ["test.t3.a", "test.t3.c"],
- "rows": 2,
+ "rows": 1,
"filtered": 100
}
}
@@ -9774,43 +13713,126 @@ EXPLAIN
}
}
}
-set statement optimizer_switch='split_grouping_derived=off' for select t3.a,t3.c,t.max,t.min
+set statement optimizer_switch='split_materialized=off' for select t3.a,t3.c,t.max,t.min
from t3 join
-(select a, c, max(b) max, min(b) min from t4 group by c,a) t
-on t3.a=t.a and t3.c=t.c;
+(select a, c, max(b) max, min(b) min from t4 group by a,c) t
+on t3.a=t.a and t3.c=t.c
+where t3.b <= 15;
a c max min
1 bb 30 30
-7 bb 82 12
+7 bb 32 32
select t3.a,t3.c,t.max,t.min
from t3 join
-(select a, c, max(b) max, min(b) min from t4 group by c,a) t
-on t3.a=t.a and t3.c=t.c;
+(select a, c, max(b) max, min(b) min from t4 group by a,c) t
+on t3.a=t.a and t3.c=t.c
+where t3.b <= 15;
a c max min
1 bb 30 30
-7 bb 82 12
+7 bb 32 32
+explain extended select t3.a,t3.c,t.max,t.min
+from t3 join
+(select a, c, max(b) max, min(b) min from t4 group by a,c) t
+on t3.a=t.a and t3.c=t.c
+where t3.b <= 15;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL idx_b NULL NULL NULL 12 75.00 Using where
+1 PRIMARY <derived2> ref key0 key0 133 test.t3.a,test.t3.c 4 100.00
+2 DERIVED t4 ALL idx NULL NULL NULL 40 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` group by `test`.`t4`.`a`,`test`.`t4`.`c`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t3`.`b` <= 15
+explain format=json select t3.a,t3.c,t.max,t.min
+from t3 join
+(select a, c, max(b) max, min(b) min from t4 group by a,c) t
+on t3.a=t.a and t3.c=t.c
+where t3.b <= 15;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t3",
+ "access_type": "ALL",
+ "possible_keys": ["idx_b"],
+ "rows": 12,
+ "filtered": 75,
+ "attached_condition": "t3.b <= 15 and t3.a is not null and t3.c is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "133",
+ "used_key_parts": ["a", "c"],
+ "ref": ["test.t3.a", "test.t3.c"],
+ "rows": 4,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "filesort": {
+ "sort_key": "t4.a, t4.c",
+ "temporary_table": {
+ "table": {
+ "table_name": "t4",
+ "access_type": "ALL",
+ "possible_keys": ["idx"],
+ "rows": 40,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+set statement optimizer_switch='split_materialized=off' for select t3.a,t3.c,t.max,t.min
+from t3 join
+(select a, c, max(b) max, min(b) min from t4 group by c,a) t
+on t3.a=t.a and t3.c=t.c
+where t3.b > 15;
+a c max min
+7 cc 18 10
+7 aa 82 82
+select t3.a,t3.c,t.max,t.min
+from t3 join
+(select a, c, max(b) max, min(b) min from t4 group by c,a) t
+on t3.a=t.a and t3.c=t.c
+where t3.b > 15;
+a c max min
+7 cc 18 10
+7 aa 82 82
explain extended select t3.a,t3.c,t.max,t.min
from t3 join
(select a, c, max(b) max, min(b) min from t4 group by c,a) t
-on t3.a=t.a and t3.c=t.c;
+on t3.a=t.a and t3.c=t.c
+where t3.b > 15;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t3 ALL NULL NULL NULL NULL 8 100.00 Using where
-1 PRIMARY <derived2> ref key0 key0 24 test.t3.a,test.t3.c 2 100.00
-2 LATERAL DERIVED t4 ref idx idx 24 test.t3.a,test.t3.c 2 100.00
+1 PRIMARY t3 range idx_b idx_b 5 NULL 3 100.00 Using index condition; Using where
+1 PRIMARY <derived2> ref key0 key0 133 test.t3.a,test.t3.c 2 100.00
+2 LATERAL DERIVED t4 ref idx idx 133 test.t3.a,test.t3.c 1 100.00
Warnings:
-Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`c` = `test`.`t3`.`c` and `test`.`t4`.`a` = `test`.`t3`.`a` group by `test`.`t4`.`c`,`test`.`t4`.`a`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c`
+Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`a` = `test`.`t3`.`a` and `test`.`t4`.`c` = `test`.`t3`.`c` group by `test`.`t4`.`c`,`test`.`t4`.`a`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t3`.`b` > 15
explain format=json select t3.a,t3.c,t.max,t.min
from t3 join
(select a, c, max(b) max, min(b) min from t4 group by c,a) t
-on t3.a=t.a and t3.c=t.c;
+on t3.a=t.a and t3.c=t.c
+where t3.b > 15;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t3",
- "access_type": "ALL",
- "rows": 8,
+ "access_type": "range",
+ "possible_keys": ["idx_b"],
+ "key": "idx_b",
+ "key_length": "5",
+ "used_key_parts": ["b"],
+ "rows": 3,
"filtered": 100,
+ "index_condition": "t3.b > 15",
"attached_condition": "t3.a is not null and t3.c is not null"
},
"table": {
@@ -9818,7 +13840,7 @@ EXPLAIN
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
- "key_length": "24",
+ "key_length": "133",
"used_key_parts": ["a", "c"],
"ref": ["test.t3.a", "test.t3.c"],
"rows": 2,
@@ -9832,10 +13854,10 @@ EXPLAIN
"access_type": "ref",
"possible_keys": ["idx"],
"key": "idx",
- "key_length": "24",
+ "key_length": "133",
"used_key_parts": ["a", "c"],
"ref": ["test.t3.a", "test.t3.c"],
- "rows": 2,
+ "rows": 1,
"filtered": 100
}
}
@@ -9843,44 +13865,120 @@ EXPLAIN
}
}
}
-drop index idx on t2;
-create index idx on t2(b);
-create index idx on t3(a);
-create index idx2 on t4(c);
-insert into t3 select a+1, concat(c,'f') from t3;
-insert into t3 select a+1, concat(c,'h') from t3;
-insert into t4 select a+1, b+10, concat(c,'h') from t4;
-set statement optimizer_switch='split_grouping_derived=off' for select t2.a,t2.b,t3.c,t.max,t.min
+set statement optimizer_switch='split_materialized=off' for select t3.a,t3.c,t.max,t.min
+from t3 join
+(select a, c, max(b) max, min(b) min from t4 group by c,a) t
+on t3.a=t.a and t3.c=t.c
+where t3.b <= 15;
+a c max min
+1 bb 30 30
+7 bb 32 32
+select t3.a,t3.c,t.max,t.min
+from t3 join
+(select a, c, max(b) max, min(b) min from t4 group by c,a) t
+on t3.a=t.a and t3.c=t.c
+where t3.b <= 15;
+a c max min
+1 bb 30 30
+7 bb 32 32
+explain extended select t3.a,t3.c,t.max,t.min
+from t3 join
+(select a, c, max(b) max, min(b) min from t4 group by c,a) t
+on t3.a=t.a and t3.c=t.c
+where t3.b <= 15;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL idx_b NULL NULL NULL 12 75.00 Using where
+1 PRIMARY <derived2> ref key0 key0 133 test.t3.a,test.t3.c 4 100.00
+2 DERIVED t4 ALL idx NULL NULL NULL 40 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` group by `test`.`t4`.`c`,`test`.`t4`.`a`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t3`.`b` <= 15
+explain format=json select t3.a,t3.c,t.max,t.min
+from t3 join
+(select a, c, max(b) max, min(b) min from t4 group by c,a) t
+on t3.a=t.a and t3.c=t.c
+where t3.b <= 15;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t3",
+ "access_type": "ALL",
+ "possible_keys": ["idx_b"],
+ "rows": 12,
+ "filtered": 75,
+ "attached_condition": "t3.b <= 15 and t3.a is not null and t3.c is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "133",
+ "used_key_parts": ["a", "c"],
+ "ref": ["test.t3.a", "test.t3.c"],
+ "rows": 4,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "filesort": {
+ "sort_key": "t4.c, t4.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t4",
+ "access_type": "ALL",
+ "possible_keys": ["idx"],
+ "rows": 40,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+drop index idx_a on t2;
+create index idx on t2(c,b);
+create index idx_a on t3(a);
+create index idx_c on t4(c);
+insert into t3 select a+10, b+10, concat(c,'f') from t3;
+insert into t3 select a+100, b+100, concat(c,'g') from t3;
+insert into t4 select a+100, b+100, concat(c,'g') from t4;
+insert into t4 select a+1000, b+1000, concat(c,'h') from t4;
+analyze table t2,t3,t4;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+test.t3 analyze status OK
+test.t4 analyze status OK
+set statement optimizer_switch='split_materialized=off' for select t2.a,t2.b,t2.c,t.c as t_c,t.max,t.min
from t2, t3, (select c, max(b) max, min(b) min from t4 group by c) t
-where t2.b > 50 and t2.a=t3.a and t3.c=t.c;
-a b c max min
-7 82 aa 77 15
-7 82 bb 82 12
-2 90 aa 77 15
-2 90 aa 77 15
-2 90 bbh 92 22
-select t2.a,t2.b,t3.c,t.max,t.min
+where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c;
+a b c t_c max min
+7 82 y cc 18 10
+7 82 y aa 82 15
+7 82 y bb 40 23
+select t2.a,t2.b,t2.c,t.c as t_c,t.max,t.min
from t2, t3, (select c, max(b) max, min(b) min from t4 group by c) t
-where t2.b > 50 and t2.a=t3.a and t3.c=t.c;
-a b c max min
-7 82 aa 77 15
-7 82 bb 82 12
-2 90 aa 77 15
-2 90 aa 77 15
-2 90 bbh 92 22
-explain extended select t2.a,t2.b,t3.c,t.max,t.min
+where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c;
+a b c t_c max min
+7 82 y cc 18 10
+7 82 y aa 82 15
+7 82 y bb 40 23
+explain extended select t2.a,t2.b,t2.c,t.c as t_c,t.max,t.min
from t2, t3, (select c, max(b) max, min(b) min from t4 group by c) t
-where t2.b > 50 and t2.a=t3.a and t3.c=t.c;
+where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 range idx idx 5 NULL 5 100.00 Using index condition; Using where
-1 PRIMARY t3 ref idx idx 5 test.t2.a 3 100.00 Using where
-1 PRIMARY <derived2> ref key0 key0 19 test.t3.c 4 100.00
-2 LATERAL DERIVED t4 ref idx2 idx2 19 test.t3.c 5 100.00
+1 PRIMARY t2 range idx idx 133 NULL 2 100.00 Using index condition; Using where
+1 PRIMARY t3 ref idx_a idx_a 5 test.t2.a 2 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 128 test.t3.c 2 100.00
+2 LATERAL DERIVED t4 ref idx_c idx_c 128 test.t3.c 3 100.00
Warnings:
-Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t2` join `test`.`t3` join (/* select#2 */ select `test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`c` = `test`.`t3`.`c` group by `test`.`t4`.`c`) `t` where `test`.`t3`.`a` = `test`.`t2`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t2`.`b` > 50
-explain format=json select t2.a,t2.b,t3.c,t.max,t.min
+Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`t`.`c` AS `t_c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t2` join `test`.`t3` join (/* select#2 */ select `test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`c` = `test`.`t3`.`c` group by `test`.`t4`.`c`) `t` where `test`.`t3`.`a` = `test`.`t2`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t2`.`b` between 80 and 85 and `test`.`t2`.`c` in ('y','z')
+explain format=json select t2.a,t2.b,t2.c,t.c as t_c,t.max,t.min
from t2, t3, (select c, max(b) max, min(b) min from t4 group by c) t
-where t2.b > 50 and t2.a=t3.a and t3.c=t.c;
+where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c;
EXPLAIN
{
"query_block": {
@@ -9890,22 +13988,22 @@ EXPLAIN
"access_type": "range",
"possible_keys": ["idx"],
"key": "idx",
- "key_length": "5",
- "used_key_parts": ["b"],
- "rows": 5,
+ "key_length": "133",
+ "used_key_parts": ["c", "b"],
+ "rows": 2,
"filtered": 100,
- "index_condition": "t2.b > 50",
+ "index_condition": "t2.b between 80 and 85 and t2.c in ('y','z')",
"attached_condition": "t2.a is not null"
},
"table": {
"table_name": "t3",
"access_type": "ref",
- "possible_keys": ["idx"],
- "key": "idx",
+ "possible_keys": ["idx_a"],
+ "key": "idx_a",
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["test.t2.a"],
- "rows": 3,
+ "rows": 2,
"filtered": 100,
"attached_condition": "t3.c is not null"
},
@@ -9914,10 +14012,10 @@ EXPLAIN
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
- "key_length": "19",
+ "key_length": "128",
"used_key_parts": ["c"],
"ref": ["test.t3.c"],
- "rows": 4,
+ "rows": 2,
"filtered": 100,
"materialized": {
"query_block": {
@@ -9926,12 +14024,12 @@ EXPLAIN
"table": {
"table_name": "t4",
"access_type": "ref",
- "possible_keys": ["idx2"],
- "key": "idx2",
- "key_length": "19",
+ "possible_keys": ["idx_c"],
+ "key": "idx_c",
+ "key_length": "128",
"used_key_parts": ["c"],
"ref": ["test.t3.c"],
- "rows": 5,
+ "rows": 3,
"filtered": 100
}
}
@@ -9939,81 +14037,195 @@ EXPLAIN
}
}
}
-set statement optimizer_switch='split_grouping_derived=off' for select *
+set statement optimizer_switch='split_materialized=off' for select t2.a,t2.b,t2.c,t.c as t_c,t.max,t.min
+from t2, t3, (select c, max(b) max, min(b) min from t4 group by c) t
+where t2.b < 40 and t2.a=t3.a and t3.c=t.c;
+a b c t_c max min
+7 10 x cc 18 10
+7 10 x aa 82 15
+7 10 x bb 40 23
+1 20 a bb 40 23
+2 23 b aa 82 15
+2 23 b aa 82 15
+7 18 z cc 18 10
+7 18 z aa 82 15
+7 18 z bb 40 23
+1 30 c bb 40 23
+3 15 x dd 20 12
+8 12 t aa 82 15
+11 33 a bbf 50 33
+17 10 s ccf 28 20
+17 10 s aaf 92 25
+17 10 s bbf 50 33
+11 20 v bbf 50 33
+12 23 y aaf 92 25
+12 23 y aaf 92 25
+17 18 a ccf 28 20
+17 18 a aaf 92 25
+17 18 a bbf 50 33
+11 30 d bbf 50 33
+17 20 xf ccf 28 20
+17 20 xf aaf 92 25
+17 20 xf bbf 50 33
+11 30 af bbf 50 33
+12 33 bf aaf 92 25
+12 33 bf aaf 92 25
+17 28 zf ccf 28 20
+17 28 zf aaf 92 25
+17 28 zf bbf 50 33
+13 25 xf ddf 30 22
+18 22 tf aaf 92 25
+select t2.a,t2.b,t2.c,t.c as t_c,t.max,t.min
+from t2, t3, (select c, max(b) max, min(b) min from t4 group by c) t
+where t2.b < 40 and t2.a=t3.a and t3.c=t.c;
+a b c t_c max min
+7 10 x cc 18 10
+7 10 x aa 82 15
+7 10 x bb 40 23
+1 20 a bb 40 23
+2 23 b aa 82 15
+2 23 b aa 82 15
+7 18 z cc 18 10
+7 18 z aa 82 15
+7 18 z bb 40 23
+1 30 c bb 40 23
+3 15 x dd 20 12
+8 12 t aa 82 15
+11 33 a bbf 50 33
+17 10 s ccf 28 20
+17 10 s aaf 92 25
+17 10 s bbf 50 33
+11 20 v bbf 50 33
+12 23 y aaf 92 25
+12 23 y aaf 92 25
+17 18 a ccf 28 20
+17 18 a aaf 92 25
+17 18 a bbf 50 33
+11 30 d bbf 50 33
+17 20 xf ccf 28 20
+17 20 xf aaf 92 25
+17 20 xf bbf 50 33
+11 30 af bbf 50 33
+12 33 bf aaf 92 25
+12 33 bf aaf 92 25
+17 28 zf ccf 28 20
+17 28 zf aaf 92 25
+17 28 zf bbf 50 33
+13 25 xf ddf 30 22
+18 22 tf aaf 92 25
+explain extended select t2.a,t2.b,t2.c,t.c as t_c,t.max,t.min
+from t2, t3, (select c, max(b) max, min(b) min from t4 group by c) t
+where t2.b < 40 and t2.a=t3.a and t3.c=t.c;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 90 100.00 Using where
+1 PRIMARY t3 ref idx_a idx_a 5 test.t2.a 2 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 128 test.t3.c 10 100.00
+2 DERIVED t4 ALL idx_c NULL NULL NULL 160 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`t`.`c` AS `t_c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t2` join `test`.`t3` join (/* select#2 */ select `test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` group by `test`.`t4`.`c`) `t` where `test`.`t3`.`a` = `test`.`t2`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t2`.`b` < 40
+explain format=json select t2.a,t2.b,t2.c,t.c as t_c,t.max,t.min
+from t2, t3, (select c, max(b) max, min(b) min from t4 group by c) t
+where t2.b < 40 and t2.a=t3.a and t3.c=t.c;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 90,
+ "filtered": 100,
+ "attached_condition": "t2.b < 40 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "t3",
+ "access_type": "ref",
+ "possible_keys": ["idx_a"],
+ "key": "idx_a",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "t3.c is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "128",
+ "used_key_parts": ["c"],
+ "ref": ["test.t3.c"],
+ "rows": 10,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "filesort": {
+ "sort_key": "t4.c",
+ "temporary_table": {
+ "table": {
+ "table_name": "t4",
+ "access_type": "ALL",
+ "possible_keys": ["idx_c"],
+ "rows": 160,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+set statement optimizer_switch='split_materialized=off' for select *
from t2, t3, (select c, b, sum(b) over (partition by c) from t4 ) t
-where t2.b > 50 and t2.a=t3.a and t3.c=t.c;
-a b a c c b sum(b) over (partition by c)
-7 82 7 aa aa 77 177
-7 82 7 aa aa 50 177
-7 82 7 aa aa 15 177
-7 82 7 aa aa 15 177
-7 82 7 aa aa 20 177
-7 82 7 bb bb 40 219
-7 82 7 bb bb 32 219
-7 82 7 bb bb 12 219
-7 82 7 bb bb 82 219
-7 82 7 bb bb 30 219
-7 82 7 bb bb 23 219
-2 90 2 aa aa 77 177
-2 90 2 aa aa 50 177
-2 90 2 aa aa 15 177
-2 90 2 aa aa 15 177
-2 90 2 aa aa 20 177
-2 90 2 aa aa 77 177
-2 90 2 aa aa 50 177
-2 90 2 aa aa 15 177
-2 90 2 aa aa 15 177
-2 90 2 aa aa 20 177
-2 90 2 bbh bbh 50 279
-2 90 2 bbh bbh 42 279
-2 90 2 bbh bbh 22 279
-2 90 2 bbh bbh 92 279
-2 90 2 bbh bbh 40 279
-2 90 2 bbh bbh 33 279
+where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c;
+a b c a b c c b sum(b) over (partition by c)
+7 82 y 7 17 cc cc 12 40
+7 82 y 7 17 cc cc 18 40
+7 82 y 7 17 cc cc 10 40
+7 82 y 7 18 aa aa 77 259
+7 82 y 7 18 aa aa 50 259
+7 82 y 7 18 aa aa 15 259
+7 82 y 7 18 aa aa 82 259
+7 82 y 7 18 aa aa 15 259
+7 82 y 7 18 aa aa 20 259
+7 82 y 7 10 bb bb 40 125
+7 82 y 7 10 bb bb 32 125
+7 82 y 7 10 bb bb 30 125
+7 82 y 7 10 bb bb 23 125
select *
from t2, t3, (select c, b, sum(b) over (partition by c) from t4 ) t
-where t2.b > 50 and t2.a=t3.a and t3.c=t.c;
-a b a c c b sum(b) over (partition by c)
-7 82 7 aa aa 77 177
-7 82 7 aa aa 50 177
-7 82 7 aa aa 15 177
-7 82 7 aa aa 15 177
-7 82 7 aa aa 20 177
-7 82 7 bb bb 40 219
-7 82 7 bb bb 32 219
-7 82 7 bb bb 12 219
-7 82 7 bb bb 82 219
-7 82 7 bb bb 30 219
-7 82 7 bb bb 23 219
-2 90 2 aa aa 77 177
-2 90 2 aa aa 50 177
-2 90 2 aa aa 15 177
-2 90 2 aa aa 15 177
-2 90 2 aa aa 20 177
-2 90 2 aa aa 77 177
-2 90 2 aa aa 50 177
-2 90 2 aa aa 15 177
-2 90 2 aa aa 15 177
-2 90 2 aa aa 20 177
-2 90 2 bbh bbh 50 279
-2 90 2 bbh bbh 42 279
-2 90 2 bbh bbh 22 279
-2 90 2 bbh bbh 92 279
-2 90 2 bbh bbh 40 279
-2 90 2 bbh bbh 33 279
+where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c;
+a b c a b c c b sum(b) over (partition by c)
+7 82 y 7 17 cc cc 12 40
+7 82 y 7 17 cc cc 18 40
+7 82 y 7 17 cc cc 10 40
+7 82 y 7 18 aa aa 77 259
+7 82 y 7 18 aa aa 50 259
+7 82 y 7 18 aa aa 15 259
+7 82 y 7 18 aa aa 82 259
+7 82 y 7 18 aa aa 15 259
+7 82 y 7 18 aa aa 20 259
+7 82 y 7 10 bb bb 40 125
+7 82 y 7 10 bb bb 32 125
+7 82 y 7 10 bb bb 30 125
+7 82 y 7 10 bb bb 23 125
explain extended select *
from t2, t3, (select c, b, sum(b) over (partition by c) from t4 ) t
-where t2.b > 50 and t2.a=t3.a and t3.c=t.c;
+where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 range idx idx 5 NULL 5 100.00 Using index condition; Using where
-1 PRIMARY t3 ref idx idx 5 test.t2.a 3 100.00 Using where
-1 PRIMARY <derived2> ref key0 key0 19 test.t3.c 4 100.00
-2 LATERAL DERIVED t4 ref idx2 idx2 19 test.t3.c 5 100.00 Using temporary
+1 PRIMARY t2 range idx idx 133 NULL 2 100.00 Using index condition; Using where
+1 PRIMARY t3 ref idx_a idx_a 5 test.t2.a 2 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 128 test.t3.c 2 100.00
+2 LATERAL DERIVED t4 ref idx_c idx_c 128 test.t3.c 3 100.00 Using temporary
Warnings:
-Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`c` AS `c`,`t`.`b` AS `b`,`t`.`sum(b) over (partition by c)` AS `sum(b) over (partition by c)` from `test`.`t2` join `test`.`t3` join (/* select#2 */ select `test`.`t4`.`c` AS `c`,`test`.`t4`.`b` AS `b`,sum(`test`.`t4`.`b`) over ( partition by `test`.`t4`.`c`) AS `sum(b) over (partition by c)` from `test`.`t4` where `test`.`t4`.`c` = `test`.`t3`.`c`) `t` where `test`.`t3`.`a` = `test`.`t2`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t2`.`b` > 50
+Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`t`.`c` AS `c`,`t`.`b` AS `b`,`t`.`sum(b) over (partition by c)` AS `sum(b) over (partition by c)` from `test`.`t2` join `test`.`t3` join (/* select#2 */ select `test`.`t4`.`c` AS `c`,`test`.`t4`.`b` AS `b`,sum(`test`.`t4`.`b`) over ( partition by `test`.`t4`.`c`) AS `sum(b) over (partition by c)` from `test`.`t4` where `test`.`t4`.`c` = `test`.`t3`.`c`) `t` where `test`.`t3`.`a` = `test`.`t2`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t2`.`b` between 80 and 85 and `test`.`t2`.`c` in ('y','z')
explain format=json select *
from t2, t3, (select c, b, sum(b) over (partition by c) from t4 ) t
-where t2.b > 50 and t2.a=t3.a and t3.c=t.c;
+where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c;
EXPLAIN
{
"query_block": {
@@ -10023,22 +14235,22 @@ EXPLAIN
"access_type": "range",
"possible_keys": ["idx"],
"key": "idx",
- "key_length": "5",
- "used_key_parts": ["b"],
- "rows": 5,
+ "key_length": "133",
+ "used_key_parts": ["c", "b"],
+ "rows": 2,
"filtered": 100,
- "index_condition": "t2.b > 50",
+ "index_condition": "t2.b between 80 and 85 and t2.c in ('y','z')",
"attached_condition": "t2.a is not null"
},
"table": {
"table_name": "t3",
"access_type": "ref",
- "possible_keys": ["idx"],
- "key": "idx",
+ "possible_keys": ["idx_a"],
+ "key": "idx_a",
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["test.t2.a"],
- "rows": 3,
+ "rows": 2,
"filtered": 100,
"attached_condition": "t3.c is not null"
},
@@ -10047,10 +14259,10 @@ EXPLAIN
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
- "key_length": "19",
+ "key_length": "128",
"used_key_parts": ["c"],
"ref": ["test.t3.c"],
- "rows": 4,
+ "rows": 2,
"filtered": 100,
"materialized": {
"query_block": {
@@ -10066,12 +14278,398 @@ EXPLAIN
"table": {
"table_name": "t4",
"access_type": "ref",
- "possible_keys": ["idx2"],
- "key": "idx2",
- "key_length": "19",
+ "possible_keys": ["idx_c"],
+ "key": "idx_c",
+ "key_length": "128",
"used_key_parts": ["c"],
"ref": ["test.t3.c"],
- "rows": 5,
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+set statement optimizer_switch='split_materialized=off' for select *
+from t2, t3, (select c, b, sum(b) over (partition by c) from t4 ) t
+where t2.b < 40 and t2.a=t3.a and t3.c=t.c;
+a b c a b c c b sum(b) over (partition by c)
+7 10 x 7 17 cc cc 12 40
+7 10 x 7 17 cc cc 18 40
+7 10 x 7 17 cc cc 10 40
+7 10 x 7 18 aa aa 77 259
+7 10 x 7 18 aa aa 50 259
+7 10 x 7 18 aa aa 15 259
+7 10 x 7 18 aa aa 82 259
+7 10 x 7 18 aa aa 15 259
+7 10 x 7 18 aa aa 20 259
+7 10 x 7 10 bb bb 40 125
+7 10 x 7 10 bb bb 32 125
+7 10 x 7 10 bb bb 30 125
+7 10 x 7 10 bb bb 23 125
+1 20 a 1 14 bb bb 40 125
+1 20 a 1 14 bb bb 32 125
+1 20 a 1 14 bb bb 30 125
+1 20 a 1 14 bb bb 23 125
+2 23 b 2 12 aa aa 77 259
+2 23 b 2 12 aa aa 50 259
+2 23 b 2 12 aa aa 15 259
+2 23 b 2 12 aa aa 82 259
+2 23 b 2 12 aa aa 15 259
+2 23 b 2 12 aa aa 20 259
+2 23 b 2 11 aa aa 77 259
+2 23 b 2 11 aa aa 50 259
+2 23 b 2 11 aa aa 15 259
+2 23 b 2 11 aa aa 82 259
+2 23 b 2 11 aa aa 15 259
+2 23 b 2 11 aa aa 20 259
+7 18 z 7 17 cc cc 12 40
+7 18 z 7 17 cc cc 18 40
+7 18 z 7 17 cc cc 10 40
+7 18 z 7 18 aa aa 77 259
+7 18 z 7 18 aa aa 50 259
+7 18 z 7 18 aa aa 15 259
+7 18 z 7 18 aa aa 82 259
+7 18 z 7 18 aa aa 15 259
+7 18 z 7 18 aa aa 20 259
+7 18 z 7 10 bb bb 40 125
+7 18 z 7 10 bb bb 32 125
+7 18 z 7 10 bb bb 30 125
+7 18 z 7 10 bb bb 23 125
+1 30 c 1 14 bb bb 40 125
+1 30 c 1 14 bb bb 32 125
+1 30 c 1 14 bb bb 30 125
+1 30 c 1 14 bb bb 23 125
+3 15 x 3 11 dd dd 20 32
+3 15 x 3 11 dd dd 12 32
+8 12 t 8 11 aa aa 77 259
+8 12 t 8 11 aa aa 50 259
+8 12 t 8 11 aa aa 15 259
+8 12 t 8 11 aa aa 82 259
+8 12 t 8 11 aa aa 15 259
+8 12 t 8 11 aa aa 20 259
+11 33 a 11 24 bbf bbf 50 165
+11 33 a 11 24 bbf bbf 42 165
+11 33 a 11 24 bbf bbf 40 165
+11 33 a 11 24 bbf bbf 33 165
+17 10 s 17 27 ccf ccf 22 70
+17 10 s 17 27 ccf ccf 28 70
+17 10 s 17 27 ccf ccf 20 70
+17 10 s 17 28 aaf aaf 87 319
+17 10 s 17 28 aaf aaf 60 319
+17 10 s 17 28 aaf aaf 25 319
+17 10 s 17 28 aaf aaf 92 319
+17 10 s 17 28 aaf aaf 25 319
+17 10 s 17 28 aaf aaf 30 319
+17 10 s 17 20 bbf bbf 50 165
+17 10 s 17 20 bbf bbf 42 165
+17 10 s 17 20 bbf bbf 40 165
+17 10 s 17 20 bbf bbf 33 165
+11 20 v 11 24 bbf bbf 50 165
+11 20 v 11 24 bbf bbf 42 165
+11 20 v 11 24 bbf bbf 40 165
+11 20 v 11 24 bbf bbf 33 165
+12 23 y 12 22 aaf aaf 87 319
+12 23 y 12 22 aaf aaf 60 319
+12 23 y 12 22 aaf aaf 25 319
+12 23 y 12 22 aaf aaf 92 319
+12 23 y 12 22 aaf aaf 25 319
+12 23 y 12 22 aaf aaf 30 319
+12 23 y 12 21 aaf aaf 87 319
+12 23 y 12 21 aaf aaf 60 319
+12 23 y 12 21 aaf aaf 25 319
+12 23 y 12 21 aaf aaf 92 319
+12 23 y 12 21 aaf aaf 25 319
+12 23 y 12 21 aaf aaf 30 319
+17 18 a 17 27 ccf ccf 22 70
+17 18 a 17 27 ccf ccf 28 70
+17 18 a 17 27 ccf ccf 20 70
+17 18 a 17 28 aaf aaf 87 319
+17 18 a 17 28 aaf aaf 60 319
+17 18 a 17 28 aaf aaf 25 319
+17 18 a 17 28 aaf aaf 92 319
+17 18 a 17 28 aaf aaf 25 319
+17 18 a 17 28 aaf aaf 30 319
+17 18 a 17 20 bbf bbf 50 165
+17 18 a 17 20 bbf bbf 42 165
+17 18 a 17 20 bbf bbf 40 165
+17 18 a 17 20 bbf bbf 33 165
+11 30 d 11 24 bbf bbf 50 165
+11 30 d 11 24 bbf bbf 42 165
+11 30 d 11 24 bbf bbf 40 165
+11 30 d 11 24 bbf bbf 33 165
+17 20 xf 17 27 ccf ccf 22 70
+17 20 xf 17 27 ccf ccf 28 70
+17 20 xf 17 27 ccf ccf 20 70
+17 20 xf 17 28 aaf aaf 87 319
+17 20 xf 17 28 aaf aaf 60 319
+17 20 xf 17 28 aaf aaf 25 319
+17 20 xf 17 28 aaf aaf 92 319
+17 20 xf 17 28 aaf aaf 25 319
+17 20 xf 17 28 aaf aaf 30 319
+17 20 xf 17 20 bbf bbf 50 165
+17 20 xf 17 20 bbf bbf 42 165
+17 20 xf 17 20 bbf bbf 40 165
+17 20 xf 17 20 bbf bbf 33 165
+11 30 af 11 24 bbf bbf 50 165
+11 30 af 11 24 bbf bbf 42 165
+11 30 af 11 24 bbf bbf 40 165
+11 30 af 11 24 bbf bbf 33 165
+12 33 bf 12 22 aaf aaf 87 319
+12 33 bf 12 22 aaf aaf 60 319
+12 33 bf 12 22 aaf aaf 25 319
+12 33 bf 12 22 aaf aaf 92 319
+12 33 bf 12 22 aaf aaf 25 319
+12 33 bf 12 22 aaf aaf 30 319
+12 33 bf 12 21 aaf aaf 87 319
+12 33 bf 12 21 aaf aaf 60 319
+12 33 bf 12 21 aaf aaf 25 319
+12 33 bf 12 21 aaf aaf 92 319
+12 33 bf 12 21 aaf aaf 25 319
+12 33 bf 12 21 aaf aaf 30 319
+17 28 zf 17 27 ccf ccf 22 70
+17 28 zf 17 27 ccf ccf 28 70
+17 28 zf 17 27 ccf ccf 20 70
+17 28 zf 17 28 aaf aaf 87 319
+17 28 zf 17 28 aaf aaf 60 319
+17 28 zf 17 28 aaf aaf 25 319
+17 28 zf 17 28 aaf aaf 92 319
+17 28 zf 17 28 aaf aaf 25 319
+17 28 zf 17 28 aaf aaf 30 319
+17 28 zf 17 20 bbf bbf 50 165
+17 28 zf 17 20 bbf bbf 42 165
+17 28 zf 17 20 bbf bbf 40 165
+17 28 zf 17 20 bbf bbf 33 165
+13 25 xf 13 21 ddf ddf 30 52
+13 25 xf 13 21 ddf ddf 22 52
+18 22 tf 18 21 aaf aaf 87 319
+18 22 tf 18 21 aaf aaf 60 319
+18 22 tf 18 21 aaf aaf 25 319
+18 22 tf 18 21 aaf aaf 92 319
+18 22 tf 18 21 aaf aaf 25 319
+18 22 tf 18 21 aaf aaf 30 319
+select *
+from t2, t3, (select c, b, sum(b) over (partition by c) from t4 ) t
+where t2.b < 40 and t2.a=t3.a and t3.c=t.c;
+a b c a b c c b sum(b) over (partition by c)
+7 10 x 7 17 cc cc 12 40
+7 10 x 7 17 cc cc 18 40
+7 10 x 7 17 cc cc 10 40
+7 10 x 7 18 aa aa 77 259
+7 10 x 7 18 aa aa 50 259
+7 10 x 7 18 aa aa 15 259
+7 10 x 7 18 aa aa 82 259
+7 10 x 7 18 aa aa 15 259
+7 10 x 7 18 aa aa 20 259
+7 10 x 7 10 bb bb 40 125
+7 10 x 7 10 bb bb 32 125
+7 10 x 7 10 bb bb 30 125
+7 10 x 7 10 bb bb 23 125
+1 20 a 1 14 bb bb 40 125
+1 20 a 1 14 bb bb 32 125
+1 20 a 1 14 bb bb 30 125
+1 20 a 1 14 bb bb 23 125
+2 23 b 2 12 aa aa 77 259
+2 23 b 2 12 aa aa 50 259
+2 23 b 2 12 aa aa 15 259
+2 23 b 2 12 aa aa 82 259
+2 23 b 2 12 aa aa 15 259
+2 23 b 2 12 aa aa 20 259
+2 23 b 2 11 aa aa 77 259
+2 23 b 2 11 aa aa 50 259
+2 23 b 2 11 aa aa 15 259
+2 23 b 2 11 aa aa 82 259
+2 23 b 2 11 aa aa 15 259
+2 23 b 2 11 aa aa 20 259
+7 18 z 7 17 cc cc 12 40
+7 18 z 7 17 cc cc 18 40
+7 18 z 7 17 cc cc 10 40
+7 18 z 7 18 aa aa 77 259
+7 18 z 7 18 aa aa 50 259
+7 18 z 7 18 aa aa 15 259
+7 18 z 7 18 aa aa 82 259
+7 18 z 7 18 aa aa 15 259
+7 18 z 7 18 aa aa 20 259
+7 18 z 7 10 bb bb 40 125
+7 18 z 7 10 bb bb 32 125
+7 18 z 7 10 bb bb 30 125
+7 18 z 7 10 bb bb 23 125
+1 30 c 1 14 bb bb 40 125
+1 30 c 1 14 bb bb 32 125
+1 30 c 1 14 bb bb 30 125
+1 30 c 1 14 bb bb 23 125
+3 15 x 3 11 dd dd 20 32
+3 15 x 3 11 dd dd 12 32
+8 12 t 8 11 aa aa 77 259
+8 12 t 8 11 aa aa 50 259
+8 12 t 8 11 aa aa 15 259
+8 12 t 8 11 aa aa 82 259
+8 12 t 8 11 aa aa 15 259
+8 12 t 8 11 aa aa 20 259
+11 33 a 11 24 bbf bbf 50 165
+11 33 a 11 24 bbf bbf 42 165
+11 33 a 11 24 bbf bbf 40 165
+11 33 a 11 24 bbf bbf 33 165
+17 10 s 17 27 ccf ccf 22 70
+17 10 s 17 27 ccf ccf 28 70
+17 10 s 17 27 ccf ccf 20 70
+17 10 s 17 28 aaf aaf 87 319
+17 10 s 17 28 aaf aaf 60 319
+17 10 s 17 28 aaf aaf 25 319
+17 10 s 17 28 aaf aaf 92 319
+17 10 s 17 28 aaf aaf 25 319
+17 10 s 17 28 aaf aaf 30 319
+17 10 s 17 20 bbf bbf 50 165
+17 10 s 17 20 bbf bbf 42 165
+17 10 s 17 20 bbf bbf 40 165
+17 10 s 17 20 bbf bbf 33 165
+11 20 v 11 24 bbf bbf 50 165
+11 20 v 11 24 bbf bbf 42 165
+11 20 v 11 24 bbf bbf 40 165
+11 20 v 11 24 bbf bbf 33 165
+12 23 y 12 22 aaf aaf 87 319
+12 23 y 12 22 aaf aaf 60 319
+12 23 y 12 22 aaf aaf 25 319
+12 23 y 12 22 aaf aaf 92 319
+12 23 y 12 22 aaf aaf 25 319
+12 23 y 12 22 aaf aaf 30 319
+12 23 y 12 21 aaf aaf 87 319
+12 23 y 12 21 aaf aaf 60 319
+12 23 y 12 21 aaf aaf 25 319
+12 23 y 12 21 aaf aaf 92 319
+12 23 y 12 21 aaf aaf 25 319
+12 23 y 12 21 aaf aaf 30 319
+17 18 a 17 27 ccf ccf 22 70
+17 18 a 17 27 ccf ccf 28 70
+17 18 a 17 27 ccf ccf 20 70
+17 18 a 17 28 aaf aaf 87 319
+17 18 a 17 28 aaf aaf 60 319
+17 18 a 17 28 aaf aaf 25 319
+17 18 a 17 28 aaf aaf 92 319
+17 18 a 17 28 aaf aaf 25 319
+17 18 a 17 28 aaf aaf 30 319
+17 18 a 17 20 bbf bbf 50 165
+17 18 a 17 20 bbf bbf 42 165
+17 18 a 17 20 bbf bbf 40 165
+17 18 a 17 20 bbf bbf 33 165
+11 30 d 11 24 bbf bbf 50 165
+11 30 d 11 24 bbf bbf 42 165
+11 30 d 11 24 bbf bbf 40 165
+11 30 d 11 24 bbf bbf 33 165
+17 20 xf 17 27 ccf ccf 22 70
+17 20 xf 17 27 ccf ccf 28 70
+17 20 xf 17 27 ccf ccf 20 70
+17 20 xf 17 28 aaf aaf 87 319
+17 20 xf 17 28 aaf aaf 60 319
+17 20 xf 17 28 aaf aaf 25 319
+17 20 xf 17 28 aaf aaf 92 319
+17 20 xf 17 28 aaf aaf 25 319
+17 20 xf 17 28 aaf aaf 30 319
+17 20 xf 17 20 bbf bbf 50 165
+17 20 xf 17 20 bbf bbf 42 165
+17 20 xf 17 20 bbf bbf 40 165
+17 20 xf 17 20 bbf bbf 33 165
+11 30 af 11 24 bbf bbf 50 165
+11 30 af 11 24 bbf bbf 42 165
+11 30 af 11 24 bbf bbf 40 165
+11 30 af 11 24 bbf bbf 33 165
+12 33 bf 12 22 aaf aaf 87 319
+12 33 bf 12 22 aaf aaf 60 319
+12 33 bf 12 22 aaf aaf 25 319
+12 33 bf 12 22 aaf aaf 92 319
+12 33 bf 12 22 aaf aaf 25 319
+12 33 bf 12 22 aaf aaf 30 319
+12 33 bf 12 21 aaf aaf 87 319
+12 33 bf 12 21 aaf aaf 60 319
+12 33 bf 12 21 aaf aaf 25 319
+12 33 bf 12 21 aaf aaf 92 319
+12 33 bf 12 21 aaf aaf 25 319
+12 33 bf 12 21 aaf aaf 30 319
+17 28 zf 17 27 ccf ccf 22 70
+17 28 zf 17 27 ccf ccf 28 70
+17 28 zf 17 27 ccf ccf 20 70
+17 28 zf 17 28 aaf aaf 87 319
+17 28 zf 17 28 aaf aaf 60 319
+17 28 zf 17 28 aaf aaf 25 319
+17 28 zf 17 28 aaf aaf 92 319
+17 28 zf 17 28 aaf aaf 25 319
+17 28 zf 17 28 aaf aaf 30 319
+17 28 zf 17 20 bbf bbf 50 165
+17 28 zf 17 20 bbf bbf 42 165
+17 28 zf 17 20 bbf bbf 40 165
+17 28 zf 17 20 bbf bbf 33 165
+13 25 xf 13 21 ddf ddf 30 52
+13 25 xf 13 21 ddf ddf 22 52
+18 22 tf 18 21 aaf aaf 87 319
+18 22 tf 18 21 aaf aaf 60 319
+18 22 tf 18 21 aaf aaf 25 319
+18 22 tf 18 21 aaf aaf 92 319
+18 22 tf 18 21 aaf aaf 25 319
+18 22 tf 18 21 aaf aaf 30 319
+explain extended select *
+from t2, t3, (select c, b, sum(b) over (partition by c) from t4 ) t
+where t2.b < 40 and t2.a=t3.a and t3.c=t.c;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 90 100.00 Using where
+1 PRIMARY t3 ref idx_a idx_a 5 test.t2.a 2 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 128 test.t3.c 10 100.00
+2 DERIVED t4 ALL idx_c NULL NULL NULL 160 100.00 Using temporary
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`t`.`c` AS `c`,`t`.`b` AS `b`,`t`.`sum(b) over (partition by c)` AS `sum(b) over (partition by c)` from `test`.`t2` join `test`.`t3` join (/* select#2 */ select `test`.`t4`.`c` AS `c`,`test`.`t4`.`b` AS `b`,sum(`test`.`t4`.`b`) over ( partition by `test`.`t4`.`c`) AS `sum(b) over (partition by c)` from `test`.`t4`) `t` where `test`.`t3`.`a` = `test`.`t2`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t2`.`b` < 40
+explain format=json select *
+from t2, t3, (select c, b, sum(b) over (partition by c) from t4 ) t
+where t2.b < 40 and t2.a=t3.a and t3.c=t.c;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 90,
+ "filtered": 100,
+ "attached_condition": "t2.b < 40 and t2.a is not null"
+ },
+ "table": {
+ "table_name": "t3",
+ "access_type": "ref",
+ "possible_keys": ["idx_a"],
+ "key": "idx_a",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "t3.c is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "128",
+ "used_key_parts": ["c"],
+ "ref": ["test.t3.c"],
+ "rows": 10,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t4.c"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t4",
+ "access_type": "ALL",
+ "possible_keys": ["idx_c"],
+ "rows": 160,
"filtered": 100
}
}
@@ -10090,39 +14688,53 @@ CREATE TABLE t1 (i int);
INSERT INTO t1 VALUES (1),(9),(3);
CREATE TABLE t2 (a int, i int);
INSERT INTO t2 VALUES (1,9),(2,3),(3,7),(4,1);
-CREATE TABLE t3 (a int, c varchar(8), index(c));
+CREATE TABLE t3 (a int, c char(127), index(c));
INSERT INTO t3 VALUES (1,'foo'),(3,'bar'),(4,'foo'),(2,'bar');
-CREATE TABLE t4 (c varchar(8));
-INSERT INTO t4 VALUES ('abc'),('foo'),('def');
+INSERT INTO t3 SELECT a, concat(c,'a') FROM t3;
+CREATE TABLE t4 (a int, c char(127), index(a));
+INSERT INTO t4 VALUES
+(3,'abc'),(1,'foo'),(4,'def'),(8,'xxx'),(3,'yyy'),
+(5,'zzz'),(9,'xyz'),(2,'yxz'),(5,'zxy'),(7,'zyx') ;
+ANALYZE TABLE t1,t2,t3,t4;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+test.t2 analyze status OK
+test.t3 analyze status OK
+test.t4 analyze status OK
CREATE VIEW v1 AS
SELECT c FROM t3
WHERE a IN ( SELECT t2.a FROM t1 JOIN t2 WHERE t1.i = t2.i ) GROUP BY c ;
-set statement optimizer_switch='split_grouping_derived=off' for SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 );
-c
-foo
-SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 );
-c
-foo
-explain extended SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 );
+set statement optimizer_switch='split_materialized=off' for SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 ) and a < 2;
+a c
+1 foo
+SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 ) and a < 2;
+a c
+1 foo
+explain extended SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 ) and a < 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00 Using where
-1 PRIMARY <derived3> ref key0 key0 11 test.t4.c 4 100.00 FirstMatch(t4)
-3 LATERAL DERIVED t3 ALL c NULL NULL NULL 4 75.00 Using where
+1 PRIMARY t4 range a a 5 NULL 1 100.00 Using index condition; Using where
+1 PRIMARY <derived3> ref key0 key0 128 test.t4.c 2 100.00 FirstMatch(t4)
+3 LATERAL DERIVED t3 ref c c 128 test.t4.c 2 100.00
3 LATERAL DERIVED <subquery4> eq_ref distinct_key distinct_key 4 func 1 100.00
4 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 100.00
4 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 /* select#1 */ select `test`.`t4`.`c` AS `c` from `test`.`t4` semi join (`test`.`v1`) where `v1`.`c` = `test`.`t4`.`c`
-explain format=json SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 );
+Note 1003 /* select#1 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c` from `test`.`t4` semi join (`test`.`v1`) where `v1`.`c` = `test`.`t4`.`c` and `test`.`t4`.`a` < 2
+explain format=json SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 ) and a < 2;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t4",
- "access_type": "ALL",
- "rows": 3,
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "5",
+ "used_key_parts": ["a"],
+ "rows": 1,
"filtered": 100,
+ "index_condition": "t4.a < 2",
"attached_condition": "t4.c is not null"
},
"table": {
@@ -10130,23 +14742,27 @@ EXPLAIN
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
- "key_length": "11",
+ "key_length": "128",
"used_key_parts": ["c"],
"ref": ["test.t4.c"],
- "rows": 4,
+ "rows": 2,
"filtered": 100,
"first_match": "t4",
"materialized": {
"query_block": {
"select_id": 3,
"const_condition": "1",
+ "outer_ref_condition": "t4.c is not null",
"table": {
"table_name": "t3",
- "access_type": "ALL",
+ "access_type": "ref",
"possible_keys": ["c"],
- "rows": 4,
- "filtered": 75,
- "attached_condition": "t3.c = t4.c"
+ "key": "c",
+ "key_length": "128",
+ "used_key_parts": ["c"],
+ "ref": ["test.t4.c"],
+ "rows": 2,
+ "filtered": 100
},
"table": {
"table_name": "<subquery4>",
@@ -10220,3 +14836,112 @@ SELECT * FROM v3 JOIN t1 ON (bmax = b);
a bmax a b
DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
+#
+# MDEV-14845: Impossible where for derived with GROUP BY
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1),(2);
+WITH cte AS ( SELECT pk FROM t1 WHERE pk IS NULL GROUP BY pk )
+SELECT * FROM cte;
+pk
+EXPLAIN EXTENDED WITH cte AS ( SELECT pk FROM t1 WHERE pk IS NULL GROUP BY pk )
+SELECT * FROM cte;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 Const row not found
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1003 with cte as (/* select#2 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` where 0 group by `test`.`t1`.`pk`)/* select#1 */ select NULL AS `pk` from `cte`
+DROP TABLE t1;
+#
+# MDEV-14880: assertion failure in optimizer when splitting is applied
+#
+CREATE TABLE t1 (pk1 INT PRIMARY KEY, f INT) ENGINE=Aria;
+INSERT INTO t1 VALUES (1,0),(2,0);
+CREATE TABLE t2 (pk2 INT PRIMARY KEY) ENGINE=Aria;
+INSERT INTO t2 VALUES (1),(2),(3);
+CREATE VIEW v2 AS SELECT pk2, COUNT(*) AS cnt FROM t2 GROUP BY pk2;
+SELECT * FROM t1 INNER JOIN v2 ON pk1 = pk2 WHERE f <> 5;
+pk1 f pk2 cnt
+1 0 1 1
+2 0 2 1
+EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN v2 ON pk1 = pk2 WHERE f <> 5;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 2 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 4 test.t1.pk1 2 100.00
+2 LATERAL DERIVED t2 eq_ref PRIMARY PRIMARY 4 test.t1.pk1 1 100.00 Using index
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`pk1` AS `pk1`,`test`.`t1`.`f` AS `f`,`v2`.`pk2` AS `pk2`,`v2`.`cnt` AS `cnt` from `test`.`t1` join `test`.`v2` where `v2`.`pk2` = `test`.`t1`.`pk1` and `test`.`t1`.`f` <> 5
+EXPLAIN FORMAT=JSON SELECT * FROM t1 INNER JOIN v2 ON pk1 = pk2 WHERE f <> 5;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "possible_keys": ["PRIMARY"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "t1.f <> 5"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "4",
+ "used_key_parts": ["pk2"],
+ "ref": ["test.t1.pk1"],
+ "rows": 2,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "outer_ref_condition": "t1.pk1 is not null",
+ "table": {
+ "table_name": "t2",
+ "access_type": "eq_ref",
+ "possible_keys": ["PRIMARY"],
+ "key": "PRIMARY",
+ "key_length": "4",
+ "used_key_parts": ["pk2"],
+ "ref": ["test.t1.pk1"],
+ "rows": 1,
+ "filtered": 100,
+ "using_index": true
+ }
+ }
+ }
+ }
+ }
+}
+DROP VIEW v2;
+DROP TABLE t1,t2;
+#
+# MDEV-15017: splittable table is constant table
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+CREATE TABLE t2 (pk INT, b INT, PRIMARY KEY (pk)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,2),(3,4);
+CREATE VIEW v2 AS SELECT pk, MIN(b) FROM t2 GROUP BY pk;
+SELECT * FROM t1 LEFT JOIN v2 ON (a = pk);
+a pk MIN(b)
+DROP VIEW v2;
+DROP TABLE t1,t2;
+#
+# MDEV-14994: splittable table with no rows
+#
+CREATE TABLE t1 (f INT PRIMARY KEY) ENGINE=MyISAM;
+CREATE VIEW v1 AS SELECT a.* FROM t1 AS a STRAIGHT_JOIN t1 AS b;
+CREATE VIEW v2 AS SELECT f FROM v1 GROUP BY f;
+SELECT * FROM v1 JOIN v2 ON v1.f = v2.f;
+f f
+EXPLAIN EXTENDED
+SELECT * FROM v1 JOIN v2 ON v1.f = v2.f;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 LATERAL DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+Warnings:
+Note 1003 /* select#1 */ select NULL AS `f`,`v2`.`f` AS `f` from `test`.`t1` `a` straight_join `test`.`t1` `b` join `test`.`v2` where 0
+DROP VIEW v1,v2;
+DROP TABLE t1;
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index 9221c6240bd..85e56ff176e 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -2014,7 +2014,7 @@ SELECT t.b, t.c, t1.a
FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
WHERE t.b AND t.c = t1.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
@@ -2029,7 +2029,7 @@ SELECT t.b, t.c, t1.a
FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
WHERE t.b <> 0 AND t.c = t1.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
@@ -2310,6 +2310,8 @@ Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
DROP TABLE t1;
SET SESSION optimizer_switch= @save_optimizer_switch;
#
diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result
index 3fd5370f470..88e070af88c 100644
--- a/mysql-test/r/drop.result
+++ b/mysql-test/r/drop.result
@@ -209,10 +209,10 @@ Note 1051 Unknown table 'test.table1'
Note 1051 Unknown table 'test.table2'
DROP VIEW IF EXISTS view1,view2,view3,view4;
Warnings:
-Note 4090 Unknown VIEW: 'test.view1'
-Note 4090 Unknown VIEW: 'test.view2'
-Note 4090 Unknown VIEW: 'test.view3'
-Note 4090 Unknown VIEW: 'test.view4'
+Note 4092 Unknown VIEW: 'test.view1'
+Note 4092 Unknown VIEW: 'test.view2'
+Note 4092 Unknown VIEW: 'test.view3'
+Note 4092 Unknown VIEW: 'test.view4'
# Test error message when trigger does not find table
CREATE TABLE table1(a int);
diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result
index 23d697835b0..7a5eeac67cc 100644
--- a/mysql-test/r/dyncol.result
+++ b/mysql-test/r/dyncol.result
@@ -1873,6 +1873,26 @@ SELECT COLUMN_JSON(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL));
COLUMN_JSON(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL))
{"a":1,"b":1}
#
+# MDEV-7533: COLUMN_JSON() doesn't escape control characters
+# in string values
+#
+SELECT COLUMN_JSON(COLUMN_CREATE('test','"\\\t\n\Z')) AS json;
+json
+{"test":"\"\\\u0009\u000A\u001A"}
+SELECT COLUMN_JSON(COLUMN_CREATE('test','First line\nSecond line')) AS json;
+json
+{"test":"First line\u000ASecond line"}
+#
+# MDEV-15230: column_json breaks cyrillic in 10.1.31
+#
+set names utf8;
+create table t1 (b blob);
+insert into t1 values (column_create('description',column_create('title','ОпиÑание')));
+select column_json(b) from t1;
+column_json(b)
+{"description":{"title":"ОпиÑание"}}
+drop table t1;
+#
# end of 10.0 tests
#
#
diff --git a/mysql-test/r/events_grant.result b/mysql-test/r/events_grant.result
index a054e58494b..51b80742737 100644
--- a/mysql-test/r/events_grant.result
+++ b/mysql-test/r/events_grant.result
@@ -23,7 +23,7 @@ SHOW GRANTS;
Grants for ev_test@localhost
GRANT USAGE ON *.* TO 'ev_test'@'localhost'
GRANT ALL PRIVILEGES ON `events_test`.* TO 'ev_test'@'localhost'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON `events_test2`.* TO 'ev_test'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER, DELETE VERSIONING ROWS ON `events_test2`.* TO 'ev_test'@'localhost'
"Here comes an error:";
SHOW EVENTS;
ERROR 42000: Access denied for user 'ev_test'@'localhost' to database 'events_test2'
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index 97e49af96d4..f593e0dfaba 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -2,7 +2,7 @@ drop table if exists t1;
create table t1 (id int not null, str char(10), unique(str));
explain select * 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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar");
select * from t1 where str is null;
id str
@@ -218,8 +218,8 @@ EXPLAIN EXTENDED SELECT 1 FROM t1
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-2 SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 SUBQUERY t system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 SUBQUERY t system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` where 0
SET SESSION sql_mode=@old_sql_mode;
@@ -387,7 +387,7 @@ set optimizer_switch='derived_merge=off,derived_with_keys=off';
EXPLAIN EXTENDED
SELECT * FROM ( SELECT t1.a FROM t1,t2 WHERE t2.a = t1.a ) AS t;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 Const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
Warnings:
Note 1003 /* select#1 */ select NULL AS `a` from (/* select#2 */ select NULL AS `a` from `test`.`t1` where 0) `t`
diff --git a/mysql-test/r/explain_json.result b/mysql-test/r/explain_json.result
index d7cdeac499e..ef6b70aff71 100644
--- a/mysql-test/r/explain_json.result
+++ b/mysql-test/r/explain_json.result
@@ -1204,7 +1204,7 @@ create table t1 (i int) engine=myisam;
explain
select * 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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
explain format=json
select * from t1;
EXPLAIN
@@ -1584,3 +1584,63 @@ EXPLAIN
}
}
drop table t0,t1;
+#
+# MDEV-10844: EXPLAIN FORMAT=JSON doesn't show order direction for filesort
+#
+create table t1 (a int, b int);
+insert into t1 values (1,2),(3,4),(2,3);
+explain format=json select * from t1 order by a, b desc;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "read_sorted_file": {
+ "filesort": {
+ "sort_key": "t1.a, t1.b desc",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+explain format=json select * from t1 order by a desc, b desc;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "read_sorted_file": {
+ "filesort": {
+ "sort_key": "t1.a desc, t1.b desc",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+explain format=json select * from t1 order by a desc, b ;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "read_sorted_file": {
+ "filesort": {
+ "sort_key": "t1.a desc, t1.b",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+drop table t1;
diff --git a/mysql-test/r/features.result b/mysql-test/r/features.result
index c6d1a6b0bac..fc276e2f885 100644
--- a/mysql-test/r/features.result
+++ b/mysql-test/r/features.result
@@ -8,6 +8,7 @@ Feature_delay_key_write 0
Feature_dynamic_columns 0
Feature_fulltext 0
Feature_gis 0
+Feature_invisible_columns 0
Feature_locale 0
Feature_subquery 0
Feature_timezone 0
diff --git a/mysql-test/r/frm_bad_row_type-7333.result b/mysql-test/r/frm_bad_row_type-7333.result
index 4df3b70fc9f..48404b1ba97 100644
--- a/mysql-test/r/frm_bad_row_type-7333.result
+++ b/mysql-test/r/frm_bad_row_type-7333.result
@@ -9,6 +9,6 @@ bad_row_type CREATE TABLE `bad_row_type` (
PRIMARY KEY (`category_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 /* `compression`='tokudb_zlib' */
show table status like 'bad_row_type';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-bad_row_type MyISAM 10 Dynamic 0 0 0 281474976710655 1024 0 1 x x NULL utf8_general_ci NULL `compression`='tokudb_zlib'
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+bad_row_type MyISAM 10 Dynamic 0 0 0 281474976710655 1024 0 1 x x NULL utf8_general_ci NULL `compression`='tokudb_zlib' x N
drop table bad_row_type;
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 7ee5a68ca90..308d1d7fcb9 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -49,7 +49,7 @@ a b
Full-text indexes are called collections
Only MyISAM tables support collections
select * from t1 where MATCH(a,b) AGAINST ("indexes" IN BOOLEAN MODE WITH QUERY EXPANSION);
-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 'QUERY EXPANSION)' at line 1
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'WITH QUERY EXPANSION)' at line 1
explain select * from t1 where MATCH(a,b) AGAINST ("collections");
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 fulltext a a 0 1 Using where
@@ -743,6 +743,26 @@ txt1 txt2
nnn2 x2 y2 ööö2 mmm2 ùùù2
DROP TABLE t1;
#
+# MDEV-14743: Server crashes in Item_func_match::init_search
+#
+CREATE TABLE t1 (f VARCHAR(8));
+INSERT INTO t1 VALUES ('foo'),('bar');
+SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) );
+'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) )
+1
+SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE )) as f1, MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) as f2 from t1 ;
+f1 f2
+1 0
+1 0
+explain extended
+SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE )) as f1, MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) as f2 from t1 ;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select <expr_cache><'foo'>(<in_optimizer>('foo',<exists>(/* select#2 */ select `test`.`t1`.`f` from `test`.`t1` where <cache>(convert('foo' using latin1)) = `test`.`t1`.`f` or `test`.`t1`.`f` is null having `test`.`t1`.`f` is null))) AS `f1`,(match `test`.`t1`.`f` against ('qux' in boolean mode)) AS `f2` from `test`.`t1`
+drop table t1;
+#
# End of 5.5 tests
#
CREATE TABLE t1 (
diff --git a/mysql-test/r/func_concat.result b/mysql-test/r/func_concat.result
index b87ee7bfc52..9ab6f74653e 100644
--- a/mysql-test/r/func_concat.result
+++ b/mysql-test/r/func_concat.result
@@ -262,3 +262,9 @@ c2
abcdefghi-abcdefghi
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
+#
+# MDEV-13790 UNHEX() of a somewhat complicated CONCAT() returns NULL
+#
+SELECT UNHEX(CONCAT('414C2', HEX(8 + ROUND(RAND()*7)), SUBSTR(SHA(UUID()),6,33),HEX(2+ROUND(RAND()*8)))) IS NULL AS c1;
+c1
+0
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 097e07ac715..723a1952d79 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -1254,3 +1254,129 @@ DROP TABLE t1;
#
# End of 10.2 tests
#
+#
+# Start of 10.3 tests
+#
+drop table if exists t1, t2;
+create table t1 (grp int, a bigint unsigned, c char(10) , d char(10) not null);
+insert into t1 values (1,1,NULL,"a");
+insert into t1 values (1,10,"b","a");
+insert into t1 values (1,11,"c","a");
+insert into t1 values (2,2,"c","a");
+insert into t1 values (2,3,"b","b");
+insert into t1 values (3,4,"E","a");
+insert into t1 values (3,5,"C","b");
+insert into t1 values (3,6,"D","c");
+insert into t1 values (3,7,"E","c");
+select grp,group_concat(c) from t1 group by grp;
+grp group_concat(c)
+1 b,c
+2 c,b
+3 E,C,D,E
+select grp,group_concat(c limit 1 ) from t1 group by grp;
+grp group_concat(c limit 1 )
+1 b
+2 c
+3 E
+select grp,group_concat(c limit 1,1 ) from t1 group by grp;
+grp group_concat(c limit 1,1 )
+1 c
+2 b
+3 C
+select grp,group_concat(c limit 1,10 ) from t1 group by grp;
+grp group_concat(c limit 1,10 )
+1 c
+2 b
+3 C,D,E
+select grp,group_concat(c limit 1000) from t1 group by grp;
+grp group_concat(c limit 1000)
+1 b,c
+2 c,b
+3 E,C,D,E
+select group_concat(grp limit 0) from t1;
+group_concat(grp limit 0)
+
+select group_concat(grp limit "sdjadjs") from t1
+--error ER_PARSE_ERROR
+select grp,group_concat(c limit 5.5) from t1 group by grp ;
+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 '"sdjadjs") from t1
+--error ER_PARSE_ERROR
+select grp,group_concat(c limit 5.5) f' at line 1
+select grp,group_concat(distinct c limit 1,10 ) from t1 group by grp;
+grp group_concat(distinct c limit 1,10 )
+1 c
+2 b
+3 C,D
+select grp,group_concat(c order by a) from t1 group by grp;
+grp group_concat(c order by a)
+1 b,c
+2 c,b
+3 E,C,D,E
+select grp,group_concat(c order by a limit 2 ) from t1 group by grp;
+grp group_concat(c order by a limit 2 )
+1 b,c
+2 c,b
+3 E,C
+select grp,group_concat(c order by a limit 1,1 ) from t1 group by grp;
+grp group_concat(c order by a limit 1,1 )
+1 c
+2 b
+3 C
+select grp,group_concat(c order by c) from t1 group by grp;
+grp group_concat(c order by c)
+1 b,c
+2 b,c
+3 C,D,E,E
+select grp,group_concat(c order by c limit 2) from t1 group by grp;
+grp group_concat(c order by c limit 2)
+1 b,c
+2 b,c
+3 C,D
+select grp,group_concat(c order by c desc) from t1 group by grp;
+grp group_concat(c order by c desc)
+1 c,b
+2 c,b
+3 E,E,D,C
+select grp,group_concat(c order by c desc limit 2) from t1 group by grp;
+grp group_concat(c order by c desc limit 2)
+1 c,b
+2 c,b
+3 E,E
+drop table t1;
+create table t2 (a int, b varchar(10));
+insert into t2 values(1,'a'),(1,'b'),(NULL,'c'),(2,'x'),(2,'y');
+select group_concat(a,b limit 2) from t2;
+group_concat(a,b limit 2)
+1a,1b
+set @x=4;
+prepare STMT from 'select group_concat(b limit ?) from t2';
+execute STMT using @x;
+group_concat(b limit ?)
+a,b,c,x
+set @x=2;
+execute STMT using @x;
+group_concat(b limit ?)
+a,b
+set @x=1000;
+execute STMT using @x;
+group_concat(b limit ?)
+a,b,c,x,y
+set @x=0;
+execute STMT using @x;
+group_concat(b limit ?)
+
+set @x="adasfa";
+execute STMT using @x;
+ERROR HY000: Limit only accepts integer values
+set @x=-1;
+execute STMT using @x;
+ERROR HY000: Incorrect arguments to EXECUTE
+set @x=4;
+prepare STMT from 'select group_concat(a,b limit ?) from t2';
+execute STMT using @x;
+group_concat(a,b limit ?)
+1a,1b,2x,2y
+drop table t2;
+#
+# End of 10.3 tests
+#
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 3340328cad6..9f3928615ec 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -2066,7 +2066,7 @@ HAVING ('m') IN (
SELECT v
FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
set optimizer_switch=@tmp_optimizer_switch;
diff --git a/mysql-test/r/func_group_innodb.result b/mysql-test/r/func_group_innodb.result
index e340c04107d..27493ae710b 100644
--- a/mysql-test/r/func_group_innodb.result
+++ b/mysql-test/r/func_group_innodb.result
@@ -125,14 +125,14 @@ select 1, max(1) from t1i where 1=99;
1 NULL
explain select count(*), min(7), max(7) from t1m, t1i;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1m system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t1m system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t1i ALL NULL NULL NULL NULL 1
select count(*), min(7), max(7) from t1m, t1i;
count(*) min(7) max(7)
0 NULL NULL
explain select count(*), min(7), max(7) from t1m, t2i;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1m system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t1m system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
select count(*), min(7), max(7) from t1m, t2i;
count(*) min(7) max(7)
diff --git a/mysql-test/r/func_hybrid_type.result b/mysql-test/r/func_hybrid_type.result
index fe45338b36f..1bf8231f4dd 100644
--- a/mysql-test/r/func_hybrid_type.result
+++ b/mysql-test/r/func_hybrid_type.result
@@ -3443,8 +3443,8 @@ EXECUTE stmt USING @a,@a;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` varchar(21) DEFAULT NULL,
- `b` varchar(21) DEFAULT NULL
+ `a` varchar(20) DEFAULT NULL,
+ `b` varchar(20) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
#
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index 692806c7cac..65313148bf8 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -896,3 +896,16 @@ EXECUTE stmt;
a b
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
+#
+# MDEV-15340 Wrong result HOUR(case_expression_with_time_and_datetime)
+#
+SELECT
+TIME'00:00:00'='' AS c1_true,
+TIME'00:00:00' IN ('', TIME'10:20:30') AS c2_true,
+TIME'00:00:00' NOT IN ('', TIME'10:20:30') AS c3_false;
+c1_true c2_true c3_false
+1 1 0
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+Warning 1292 Truncated incorrect time value: ''
+Warning 1292 Truncated incorrect time value: ''
diff --git a/mysql-test/r/func_isnull.result b/mysql-test/r/func_isnull.result
index 2dbe3d036f9..15d87997e29 100644
--- a/mysql-test/r/func_isnull.result
+++ b/mysql-test/r/func_isnull.result
@@ -24,3 +24,87 @@ INSERT INTO t1( id ) VALUES ( NULL );
SELECT t1.id FROM t1 WHERE (id is not null and id is null );
id
DROP TABLE t1;
+# End of 5.1 tests
+#
+# MDEV-14911: IS NULL for field from mergeable view
+#
+CREATE TABLE t1 (d1 datetime NOT NULL);
+INSERT INTO t1 VALUES
+('0000-00-00 00:00:00'), ('0000-00-00 00:00:00'), ('1979-09-03 20:49:36');
+SELECT * FROM t1;
+d1
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+1979-09-03 20:49:36
+SELECT * FROM t1 WHERE d1 IS NULL;
+d1
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE d1 IS NULL;
+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`.`d1` AS `d1` from `test`.`t1` where `test`.`t1`.`d1` = 0
+SELECT count(*) FROM t1 WHERE d1 IS NULL;
+count(*)
+2
+CREATE VIEW v1 AS (SELECT * FROM t1);
+SELECT * FROM v1;
+d1
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+1979-09-03 20:49:36
+SELECT * FROM v1 WHERE d1 IS NULL;
+d1
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+EXPLAIN EXTENDED SELECT * FROM v1 WHERE d1 IS NULL;
+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`.`d1` AS `d1` from `test`.`t1` where `test`.`t1`.`d1` = 0
+SELECT count(*) FROM v1 WHERE d1 IS NULL;
+count(*)
+2
+SET @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='derived_merge=off';
+SELECT count(*) FROM ( SELECT * FROM t1 ) AS a1 WHERE d1 IS NULL;
+count(*)
+2
+SET SESSION optimizer_switch='derived_merge=on';
+SELECT count(*) FROM ( SELECT * FROM t1 ) AS a1 WHERE d1 IS NULL;
+count(*)
+2
+SET optimizer_switch=@save_optimizer_switch;
+CREATE TABLE t2 (d1 datetime NOT NULL);
+INSERT INTO t2 VALUES
+('1980-09-03 20:49:36'), ('0000-00-00 00:00:00'), ('1979-09-03 20:49:36');
+SELECT * FROM t2 LEFT JOIN t1 ON t2.d1=t1.d1 WHERE t1.d1 IS NULL;
+d1 d1
+0000-00-00 00:00:00 0000-00-00 00:00:00
+0000-00-00 00:00:00 0000-00-00 00:00:00
+1980-09-03 20:49:36 NULL
+EXPLAIN EXTENDED
+SELECT * FROM t2 LEFT JOIN t1 ON t2.d1=t1.d1 WHERE t1.d1 IS NULL;
+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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`d1` AS `d1`,`test`.`t1`.`d1` AS `d1` from `test`.`t2` left join `test`.`t1` on(`test`.`t1`.`d1` = `test`.`t2`.`d1`) where `test`.`t1`.`d1` = 0 or `test`.`t1`.`d1` is null
+SELECT * FROM t2 LEFT JOIN v1 ON t2.d1=v1.d1 WHERE v1.d1 IS NULL;
+d1 d1
+0000-00-00 00:00:00 0000-00-00 00:00:00
+0000-00-00 00:00:00 0000-00-00 00:00:00
+1980-09-03 20:49:36 NULL
+EXPLAIN EXTENDED
+SELECT * FROM t2 LEFT JOIN v1 ON t2.d1=v1.d1 WHERE v1.d1 IS NULL;
+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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`d1` AS `d1`,`test`.`t1`.`d1` AS `d1` from `test`.`t2` left join (`test`.`t1`) on(`test`.`t1`.`d1` = `test`.`t2`.`d1`) where `test`.`t1`.`d1` = 0 or `test`.`t1`.`d1` is null
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# End of 5.5 tests
+#
diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result
index 15e4fbec605..cb4ba0836d7 100644
--- a/mysql-test/r/func_json.result
+++ b/mysql-test/r/func_json.result
@@ -28,6 +28,9 @@ NULL
select json_value('{"key1": [1,2,3], "key1":123}', '$.key1');
json_value('{"key1": [1,2,3], "key1":123}', '$.key1')
123
+select JSON_VALUE('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }','$.z');
+JSON_VALUE('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }','$.z')
+Mon"t"y
select json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key2');
json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key2')
NULL
@@ -725,6 +728,14 @@ json_contains_path('{"foo":"bar"}', 'one', '$[]')
NULL
Warnings:
Warning 4042 Syntax error in JSON path in argument 3 to function 'json_contains_path' at position 3
+select JSON_VALID(0x36f0c8dccd83c5eac156da);
+JSON_VALID(0x36f0c8dccd83c5eac156da)
+0
+create table t1(a double not null);
+insert into t1 values (2),(1);
+select 1 from t1 where json_extract(a,'$','$[81]');
+1
+drop table t1;
#
# Start of 10.3 tests
#
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 982856e980a..804a563f401 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -1523,6 +1523,21 @@ str str1 b c
::10.0.5.9 ::10.0.5.9 1 0
DROP TABLE t1;
#
+# MDEV-14613: Assertion `fixed == 0' failed in Item_func::fix_fields
+#
+CREATE TABLE `t1` (
+`numgtfmt` char(10) COLLATE utf8_bin NOT NULL
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+create view v1(numgtfmt)
+as
+select 'x' from t1
+union
+select 'x' from t1 ;
+SELECT * FROM v1 WHERE numgtfmt = NAME_CONST('wnumgtfmt',_utf8'QEDITIONS' COLLATE 'utf8_bin');
+numgtfmt
+DROP VIEW v1;
+DROP TABLE t1;
+#
# End of 10.2 tests
#
#
diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result
index 46be54ca6a4..73e121f5f2b 100644
--- a/mysql-test/r/func_set.result
+++ b/mysql-test/r/func_set.result
@@ -221,21 +221,11 @@ NULL
DROP TABLE t1;
#
-# Start of 5.3 tests
-#
-#
-# MDEV-4512 Valgrind warnings in my_long10_to_str_8bit on INTERVAL and DATE_ADD with incorrect types
-#
-CREATE TABLE t1 (pk INT PRIMARY KEY);
-INSERT INTO t1 VALUES (10),(11);
-SELECT INTERVAL( 9, 1, DATE_ADD( pk, INTERVAL pk MINUTE_SECOND ), 9, 8, 3, 5, 2, 1 ) FROM t1;
-INTERVAL( 9, 1, DATE_ADD( pk, INTERVAL pk MINUTE_SECOND ), 9, 8, 3, 5, 2, 1 )
-8
-8
-Warnings:
-Warning 1292 Incorrect datetime value: '10' for column 'pk' at row 1
-Warning 1292 Incorrect datetime value: '11' for column 'pk' at row 2
-DROP TABLE t1;
-#
-# End of 5.3 tests
+# MDEV-14596 Crash in INTERVAL(ROW(..),ROW(..))
#
+SELECT INTERVAL(ROW(1,1),ROW(1,2));
+ERROR 21000: Operand should contain 1 column(s)
+SELECT INTERVAL(1,ROW(1,2));
+ERROR 21000: Operand should contain 1 column(s)
+SELECT INTERVAL(ROW(1,2),1);
+ERROR 21000: Operand should contain 1 column(s)
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index b1862d46613..2b376373f51 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -1340,12 +1340,12 @@ DROP TABLE t1;
create table t1(f1 varchar(4));
explain extended select encode(f1,'zxcv') as 'enc' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select encode(NULL,'zxcv') AS `enc` from `test`.`t1`
explain extended select decode(f1,'zxcv') as 'enc' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select decode(NULL,'zxcv') AS `enc` from `test`.`t1`
drop table t1;
@@ -4734,6 +4734,27 @@ set global max_allowed_packet=default;
# End of 5.6 tests
#
#
+# Start of 10.0 tests
+#
+#
+# MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
+#
+EXPLAIN EXTENDED SELECT CHAR(0xDF USING latin1);
+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 char(0xdf using latin1) AS `CHAR(0xDF USING latin1)`
+EXPLAIN EXTENDED SELECT CHAR(0xDF USING `binary`);
+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 char(0xdf) AS `CHAR(0xDF USING ``binary``)`
+EXPLAIN EXTENDED SELECT CHAR(0xDF);
+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 char(0xdf) AS `CHAR(0xDF)`
+#
# Start of 10.1 tests
#
#
@@ -4843,6 +4864,12 @@ YQ== 61
Yq== 62
DROP TABLE t1;
#
+# End of 10.1 tests
+#
+#
+# Start of 10.3 tests
+#
+#
# MDEV-12685 Oracle-compatible function CHR()
#
select chr(65);
@@ -4859,12 +4886,6 @@ utf8 3 1
drop database mysqltest1;
use test;
#
-# End of 10.1 tests
-#
-#
-# Start of 10.3 tests
-#
-#
# MDEV-12592 Illegal mix of collations with the HEX function
#
SET NAMES utf8;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index e710f3ac438..e03de2ca582 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -3351,3 +3351,54 @@ SELECT CONVERT_TZ(1, ROW(1,1), 1);
ERROR HY000: Illegal parameter data type row for operation 'convert_tz'
SELECT CONVERT_TZ(1, 1, ROW(1,1));
ERROR HY000: Illegal parameter data type row for operation 'convert_tz'
+#
+# MDEV-15340 Wrong result HOUR(case_expression_with_time_and_datetime)
+#
+SET TIMESTAMP=UNIX_TIMESTAMP('2018-02-17 01:02:03');
+SELECT
+COALESCE(TIME'800:00:00', NOW()) AS c,
+HOUR(COALESCE(TIME'800:00:00',NOW())) AS hc;
+c hc
+2018-03-22 08:00:00 8
+SELECT
+CASE WHEN TRUE THEN TIME'800:00:00' ELSE NOW() END AS c,
+HOUR(CASE WHEN TRUE THEN TIME'800:00:00' ELSE NOW() END) AS hc;
+c hc
+2018-03-22 08:00:00 8
+SELECT
+IFNULL(TIME'800:00:00', NOW()) AS c,
+HOUR(IFNULL(TIME'800:00:00', NOW())) AS hc;
+c hc
+2018-03-22 08:00:00 8
+SELECT
+IF(TRUE,TIME'800:00:00', NOW()) AS c,
+HOUR(IF(TRUE,TIME'800:00:00', NOW())) AS hc;
+c hc
+2018-03-22 08:00:00 8
+SELECT
+ADDTIME(TIME'10:20:30', TIMESTAMP'2001-01-01 00:00:00') AS c1,
+ADDTIME(TIME'10:20:30', COALESCE(TIMESTAMP'2001-01-01 00:00:00',TIMESTAMP'2001-01-01 00:00:00')) AS c2,
+ADDTIME(TIME'10:20:30', DATE'2001-01-01') AS c3,
+ADDTIME(TIME'10:20:30', COALESCE(DATE'2001-01-01',TIMESTAMP'2001-01-01 00:00:00')) AS c4;
+c1 c2 c3 c4
+NULL NULL NULL NULL
+SELECT
+HOUR(TIMESTAMP'0000-00-01 10:00:00') AS h0,
+TIME_TO_SEC(TIMESTAMP'0000-00-01 10:00:00') AS tts0,
+TIME_TO_SEC(TIMESTAMP'0000-00-01 10:00:00.1') AS tts1,
+CAST(TIMESTAMP'0000-00-01 10:00:00' AS TIME) AS c0,
+CAST(TIMESTAMP'0000-00-01 10:00:00.1' AS TIME(1)) AS c2;
+h0 tts0 tts1 c0 c2
+10 36000 36000.1 10:00:00 10:00:00.1
+SET TIMESTAMP=DEFAULT;
+#
+# MDEV-15363 Wrong result for CAST(LAST_DAY(TIME'00:00:00') AS TIME)
+#
+SET TIMESTAMP=UNIX_TIMESTAMP('2018-02-17 01:02:03');
+SELECT
+LAST_DAY(TIME'00:00:00') AS c1,
+CAST(CAST(LAST_DAY(TIME'00:00:00') AS DATE) AS TIME) AS c2,
+CAST(LAST_DAY(TIME'00:00:00') AS TIME) AS c3;
+c1 c2 c3
+2018-02-28 00:00:00 00:00:00
+SET TIMESTAMP=DEFAULT;
diff --git a/mysql-test/r/get_diagnostics.result b/mysql-test/r/get_diagnostics.result
index a75b775297c..732be7c0283 100644
--- a/mysql-test/r/get_diagnostics.result
+++ b/mysql-test/r/get_diagnostics.result
@@ -590,7 +590,7 @@ DROP PROCEDURE p1;
SHOW WARNINGS;
Level Code Message
Error 54321 MESSAGE_TEXT text
-Note 4092 At line 16 in test.p1
+Note 4094 At line 16 in test.p1
CREATE PROCEDURE p1()
BEGIN
DECLARE var INT;
diff --git a/mysql-test/r/gis-json.result b/mysql-test/r/gis-json.result
index d888b08351d..1d6e2193fc9 100644
--- a/mysql-test/r/gis-json.result
+++ b/mysql-test/r/gis-json.result
@@ -89,6 +89,21 @@ ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 1)
SELECT ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 5);
ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 5)
{"bbox": [10, 11, 10, 11], "type": "Point", "coordinates": [10, 11]}
+SELECT st_astext(st_geomfromgeojson('{"type": "MultiLineString","coordinates": []}')) as a;
+a
+NULL
+Warnings:
+Warning 4076 Incorrect GeoJSON format - empty 'coordinates' array.
+SELECT st_astext(st_geomfromgeojson('{"type": "Polygon","coordinates": []}')) as a;
+a
+NULL
+Warnings:
+Warning 4076 Incorrect GeoJSON format - empty 'coordinates' array.
+SELECT st_astext(st_geomfromgeojson('{"type": "MultiPolygon","coordinates": []}')) as a;
+a
+NULL
+Warnings:
+Warning 4076 Incorrect GeoJSON format - empty 'coordinates' array.
#
# End of 10.2 tests
#
diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result
index 55f7ab8d0bc..5d4708dd111 100644
--- a/mysql-test/r/gis-rtree.result
+++ b/mysql-test/r/gis-rtree.result
@@ -1,9 +1,8 @@
-DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (
-fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL,
SPATIAL KEY(g)
-) ENGINE=MyISAM;
+);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -183,9 +182,9 @@ fid AsText(g)
2 LINESTRING(149 149,151 151)
DROP TABLE t1;
CREATE TABLE t2 (
-fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL
-) ENGINE=MyISAM;
+);
INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)));
INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10)));
INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10)));
@@ -298,11 +297,11 @@ t2 CREATE TABLE `t2` (
SELECT count(*) FROM t2;
count(*)
100
-EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g,
+EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range g g 34 NULL 4 Using where
-SELECT fid, AsText(g) FROM t2 WHERE Within(g,
+SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
fid AsText(g)
46 LINESTRING(51 41,60 50)
@@ -710,9 +709,6 @@ SELECT count(*) FROM t2;
count(*)
100
DROP TABLE t2;
-drop table if exists t1;
-Warnings:
-Note 1051 Unknown table 'test.t1'
CREATE TABLE t1 (a geometry NOT NULL, SPATIAL (a));
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
@@ -751,10 +747,10 @@ Table Op Msg_type Msg_text
test.t1 analyze status OK
drop table t1;
CREATE TABLE t1 (
-fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL,
SPATIAL KEY(g)
-) ENGINE=MyISAM;
+);
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 2, 2 3)')),(GeomFromText('LineString(1 2, 2 4)'));
drop table t1;
CREATE TABLE t1 (
@@ -762,9 +758,9 @@ line GEOMETRY NOT NULL,
kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
name VARCHAR(32),
SPATIAL KEY (line)
-) engine=myisam;
+);
ALTER TABLE t1 DISABLE KEYS;
-INSERT INTO t1 (name, kind, line) VALUES
+INSERT INTO t1 (name, kind, line) VALUES
("Aadaouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
("Aadassiye", "pp", GeomFromText("POINT(35.816667 36.216667)")),
("Aadbel", "pp", GeomFromText("POINT(34.533333 36.100000)")),
@@ -803,7 +799,7 @@ CREATE TABLE t2 (geom GEOMETRY NOT NULL, SPATIAL KEY gk(geom));
INSERT IGNORE INTO t2 SELECT GeomFromText(st) FROM t1;
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
drop table t1, t2;
-CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`)) DEFAULT CHARSET=latin1;
INSERT INTO t1 (geometry) VALUES
(PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000
-66.8158332999, -18.7186111000 -66.8102777000, -18.7211111000 -66.9269443999,
@@ -819,7 +815,7 @@ drop table t1;
CREATE TABLE t1 (
c1 geometry NOT NULL default '',
SPATIAL KEY i1 (c1)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+) DEFAULT CHARSET=latin1;
INSERT INTO t1 (c1) VALUES (
PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
-18.6055555000 -66.8158332999,
@@ -833,7 +829,7 @@ DROP TABLE t1;
CREATE TABLE t1 (
c1 geometry NOT NULL default '',
SPATIAL KEY i1 (c1)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+) DEFAULT CHARSET=latin1;
INSERT INTO t1 (c1) VALUES (
PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
-18.6055555000 -66.8158332999,
@@ -874,7 +870,7 @@ c3 varchar(10) collate utf8_bin default NULL,
spatial_point point NOT NULL,
PRIMARY KEY(id),
SPATIAL KEY (spatial_point)
-)ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
('y', 's', 'j', GeomFromText('POINT(167 74)')),
('r', 'n', 'd', GeomFromText('POINT(215 118)')),
@@ -1544,11 +1540,11 @@ HANDLER t1 CLOSE;
DROP TABLE t1;
End of 5.0 tests.
#
-# Bug #57323/11764487: myisam corruption with insert ignore
+# Bug #57323/11764487: myisam corruption with insert ignore
# and invalid spatial data
#
CREATE TABLE t1(a POINT NOT NULL, b GEOMETRY NOT NULL,
-SPATIAL KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
+SPATIAL KEY(a), SPATIAL KEY(b));
INSERT INTO t1 VALUES(GEOMFROMTEXT("point (0 0)"), GEOMFROMTEXT("point (1 1)"));
INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=GEOMFROMTEXT("error");
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
@@ -1559,7 +1555,7 @@ ASTEXT(a) ASTEXT(b)
POINT(0 0) POINT(1 1)
DROP TABLE t1;
CREATE TABLE t1(a INT NOT NULL, b GEOMETRY NOT NULL,
-KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
+KEY(a), SPATIAL KEY(b));
INSERT INTO t1 VALUES(0, GEOMFROMTEXT("point (1 1)"));
INSERT IGNORE INTO t1 SET a=0, b=GEOMFROMTEXT("error");
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
@@ -1573,7 +1569,7 @@ End of 5.1 tests
CREATE TABLE t1 (
l LINESTRING NOT NULL,
SPATIAL KEY(l)
-) ENGINE = myisam;
+);
INSERT INTO t1 VALUES(GeomFromText('LINESTRING(0 0, 1 1)'));
INSERT INTO t1 VALUES(GeomFromText('LINESTRING(1 1, 2 2)'));
INSERT INTO t1 VALUES(GeomFromText('LINESTRING(2 2, 3 3)'));
@@ -1596,7 +1592,7 @@ DROP TABLE t1;
#
# MDEV-8239 Reverse spatial operations OP(const, field) do not get optimized
#
-CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a)) ENGINE=MyISAM;
+CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a));
INSERT INTO t1 VALUES (Point(1,2)),(Point(1,3));
EXPLAIN SELECT * FROM t1 WHERE MBRINTERSECTS(a,Point(1,2));
id select_type table type possible_keys key key_len ref rows Extra
@@ -1614,7 +1610,7 @@ DROP TABLE t1;
#
# MDEV-8610 "WHERE CONTAINS(indexed_geometry_column,1)" causes full table scan
#
-CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a)) ENGINE=MyISAM;
+CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a));
INSERT INTO t1 VALUES (Point(1,1)),(Point(2,2)),(Point(3,3));
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1);
ERROR HY000: Illegal parameter data type int for operation 'st_contains'
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index fe67da8001f..3f2e6d39db8 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -4390,7 +4390,7 @@ SELECT ST_BUFFER(Point(1,1), Point(1,1));
ERROR HY000: Illegal parameter data type geometry for operation 'st_buffer'
PREPARE stmt FROM 'CREATE TABLE t1 AS SELECT ST_ENVELOPE(?) AS g';
EXECUTE stmt USING 1;
-ERROR HY000: Illegal parameter data type bigint for operation 'st_envelope'
+ERROR HY000: Illegal parameter data type int for operation 'st_envelope'
EXECUTE stmt USING POINT(1,1);
SHOW CREATE TABLE t1;
Table Create Table
@@ -4404,7 +4404,7 @@ DROP TABLE t1;
DEALLOCATE PREPARE stmt;
PREPARE stmt FROM 'CREATE TABLE t1 AS SELECT ST_BUFFER(?,?) AS g';
EXECUTE stmt USING 1,1;
-ERROR HY000: Illegal parameter data type bigint for operation 'st_buffer'
+ERROR HY000: Illegal parameter data type int for operation 'st_buffer'
EXECUTE stmt USING POINT(1,1),POINT(1,1);
ERROR HY000: Illegal parameter data type geometry for operation 'st_buffer'
EXECUTE stmt USING POINT(1,1),0;
@@ -4455,7 +4455,7 @@ SELECT POINT(1,POINT(1,1));
ERROR HY000: Illegal parameter data type geometry for operation 'point'
PREPARE stmt FROM 'CREATE TABLE t1 AS SELECT ST_GEOMFROMTEXT(?,?) AS g';
EXECUTE stmt USING 1,1;
-ERROR HY000: Illegal parameter data type bigint for operation 'st_geometryfromtext'
+ERROR HY000: Illegal parameter data type int for operation 'st_geometryfromtext'
EXECUTE stmt USING POINT(1,1),POINT(1,1);
ERROR HY000: Illegal parameter data type geometry for operation 'st_geometryfromtext'
EXECUTE stmt USING 'POINT(1 1)',1;
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index 5b239f09172..22add627144 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -49,6 +49,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type SPECIFIED
ssl_cipher EDH-RSA-DES-CBC3-SHA
x509_issuer
@@ -124,6 +125,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -175,6 +177,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -223,7 +226,7 @@ revoke LOCK TABLES, ALTER on mysqltest.* from mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1';
flush privileges;
@@ -609,6 +612,7 @@ Create temporary tables Databases To use CREATE TEMPORARY TABLE
Create view Tables To create new views
Create user Server Admin To create new users
Delete Tables To delete existing rows
+Delete versioning rows Tables To delete versioning table historical rows
Drop Databases,Tables To drop databases, tables, and views
Event Server Admin To create, alter, drop and execute events
Execute Functions,Procedures To execute stored routines
@@ -664,8 +668,8 @@ SELECT TABLE_SCHEMA, TABLE_NAME, GROUP_CONCAT(PRIVILEGE_TYPE ORDER BY
PRIVILEGE_TYPE SEPARATOR ', ') AS PRIVILEGES FROM TABLE_PRIVILEGES WHERE GRANTEE
= '\'dummy\'@\'localhost\'' GROUP BY TABLE_SCHEMA, TABLE_NAME;
TABLE_SCHEMA TABLE_NAME PRIVILEGES
-mysqltest dummytable ALTER, CREATE, CREATE VIEW, DELETE, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
-mysqltest dummyview ALTER, CREATE, CREATE VIEW, DELETE, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
+mysqltest dummytable ALTER, CREATE, CREATE VIEW, DELETE, DELETE VERSIONING ROWS, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
+mysqltest dummyview ALTER, CREATE, CREATE VIEW, DELETE, DELETE VERSIONING ROWS, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
FLUSH PRIVILEGES;
SHOW GRANTS FOR dummy@localhost;
Grants for dummy@localhost
@@ -676,8 +680,8 @@ SELECT TABLE_SCHEMA, TABLE_NAME, GROUP_CONCAT(PRIVILEGE_TYPE ORDER BY
PRIVILEGE_TYPE SEPARATOR ', ') AS PRIVILEGES FROM TABLE_PRIVILEGES WHERE GRANTEE
= '\'dummy\'@\'localhost\'' GROUP BY TABLE_SCHEMA, TABLE_NAME;
TABLE_SCHEMA TABLE_NAME PRIVILEGES
-mysqltest dummytable ALTER, CREATE, CREATE VIEW, DELETE, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
-mysqltest dummyview ALTER, CREATE, CREATE VIEW, DELETE, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
+mysqltest dummytable ALTER, CREATE, CREATE VIEW, DELETE, DELETE VERSIONING ROWS, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
+mysqltest dummyview ALTER, CREATE, CREATE VIEW, DELETE, DELETE VERSIONING ROWS, DROP, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, UPDATE
SHOW FIELDS FROM mysql.tables_priv;
Field Type Null Key Default Extra
Host char(60) NO PRI
@@ -686,7 +690,7 @@ User char(80) NO PRI
Table_name char(64) NO PRI
Grantor char(141) NO MUL
Timestamp timestamp NO current_timestamp() on update current_timestamp()
-Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') NO
+Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows') NO
Column_priv set('Select','Insert','Update','References') NO
use test;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM dummy@localhost;
@@ -769,7 +773,7 @@ flush privileges;
use test;
set @user123="non-existent";
select * from mysql.db where user=@user123;
-Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv
+Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv Delete_history_priv
set names koi8r;
create database ÂÄ;
grant select on ÂÄ.* to root@localhost;
@@ -1428,7 +1432,7 @@ Warnings:
Note 1305 FUNCTION test.test_function does not exist
drop view if exists v1;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
create table test (col1 varchar(30));
create function test_function() returns varchar(30)
begin
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index e025082177a..62c659dd933 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -2667,6 +2667,31 @@ create table t2 (c1 int, c2 int);
select t1.c1 as c1, t2.c2 as c1 from t1, t2 where t1.c1 < 20 and t2.c2 > 5 group by t1.c1, t2.c2 having t1.c1 < 3;
c1 c1
drop table t1, t2;
+SET @old_sort_buff_size = @@sort_buffer_size;
+SET @@sort_buffer_size=256*1024;
+CREATE TABLE t1 (c INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+(2011),(1977),(1982),(2027),(2023),(NULL),(NULL),(2004),(1974),(2032),
+(1993),(NULL),(1995),(2034),(NULL),(2009),(1900),(NULL),(2025),(1900),
+(2033),(1900),(2012),(NULL),(2009),(1992),(1974),(1974),(2012),(2028),
+(2007),(2012),(1900),(1983),(1900),(2010),(1987),(1994),(1981),(2032),
+(2010),(1989),(2014),(1900),(1900),(1976),(1978),(2007),(2030),(NULL),
+(2002),(1997),(1900),(NULL),(2000),(2027),(1975),(2026),(1975),(2026),
+(2029),(1977),(1900),(1900),(2031),(1993),(1986),(2012),(1979),(2013),
+(1994),(2014),(2025),(2006),(1971),(1974),(2021),(2011),(NULL),(1991),
+(2001),(1977),(2023),(2012),(1900),(1978),(1998),(NULL),(1988),(1999),
+(2017),(2008),(1976),(1900),(2005),(2030),(2023),(1900),(1978),(1990),
+(1978),(1987),(2030),(1900),(2034),(2006),(2015),(2001),(2019),(2024),
+(2030),(1989),(1997),(2007),(2023),(1994),(1971),(2011),(2011),(2015),
+(1984),(1978),(1979),(1989),(2008),(2030);
+SELECT ExtractValue('<a></a>','/a') AS f1, SPACE(c) AS f2 FROM t1 GROUP BY f1, f2 WITH ROLLUP;
+f1 f2
+ NULL
+
+ NULL
+NULL NULL
+SET @@sort_buffer_size = @old_sort_buff_size;
+DROP TABLE t1;
#
# Bug #58782
# Missing rows with SELECT .. WHERE .. IN subquery
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index 8a8d6e7b2aa..fe36ef9d442 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -696,6 +696,21 @@ id column_1
expected -- 1 row(s) returned not ER_BAD_FIELD_ERROR
drop table t1;
#
+# mdev-14368: grouping query with alias for aggregate function in HAVING
+# when sql_mode = 'ONLY_FULL_GROUP_BY'
+set @save_sql_mode= @@sql_mode;
+set sql_mode = 'ONLY_FULL_GROUP_BY';
+create table t1(a int);
+insert t1 values (4),(1),(2),(1), (3),(4);
+SELECT a, COUNT(a) as ct FROM t1 GROUP BY a HAVING ct>0;
+a ct
+1 2
+2 1
+3 1
+4 2
+set sql_mode=@save_sql_mode;
+drop table t1;
+#
# Bug mdev-5160: two-way join with HAVING over the second table
#
CREATE TABLE t1 (c1 varchar(6)) ENGINE=MyISAM;
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 23fbfad09d4..d9ed5e7e891 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -121,6 +121,7 @@ time_zone_leap_second
time_zone_name
time_zone_transition
time_zone_transition_type
+transaction_registry
user
v1
select c,table_name from v1
@@ -145,6 +146,7 @@ time_zone_leap_second time_zone_leap_second
time_zone_name time_zone_name
time_zone_transition time_zone_transition
time_zone_transition_type time_zone_transition_type
+transaction_registry transaction_registry
select c,table_name from v1
left join information_schema.TABLES v2 on (v1.c=v2.table_name)
where v1.c like "t%";
@@ -167,6 +169,7 @@ time_zone_leap_second time_zone_leap_second
time_zone_name time_zone_name
time_zone_transition time_zone_transition
time_zone_transition_type time_zone_transition_type
+transaction_registry transaction_registry
select c, v2.table_name from v1
right join information_schema.TABLES v2 on (v1.c=v2.table_name)
where v1.c like "t%";
@@ -189,6 +192,7 @@ time_zone_leap_second time_zone_leap_second
time_zone_name time_zone_name
time_zone_transition time_zone_transition
time_zone_transition_type time_zone_transition_type
+transaction_registry transaction_registry
select table_name from information_schema.TABLES
where table_schema = "mysqltest" and table_name like "t%";
table_name
@@ -206,11 +210,11 @@ t2
t3
t5
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t2 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
-t3 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
-t5 MyISAM 10 Fixed 1 7 7 # 2048 0 11 # # NULL latin1_swedish_ci NULL
-v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL VIEW
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t2 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL # N
+t3 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL # N
+t5 MyISAM 10 Fixed 1 7 7 # 2048 0 11 # # NULL latin1_swedish_ci NULL # N
+v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL VIEW # NULL
show full columns from t3 like "a%";
Field Type Collation Null Key Default Extra Privileges Comment
a int(11) NULL YES MUL NULL select,insert,update,references
@@ -487,6 +491,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
'mysqltest_1'@'localhost' def test ALTER ROUTINE YES
'mysqltest_1'@'localhost' def test EVENT YES
'mysqltest_1'@'localhost' def test TRIGGER YES
+'mysqltest_1'@'localhost' def test DELETE VERSIONING ROWS YES
select * from information_schema.TABLE_PRIVILEGES where grantee like '%mysqltest_1%';
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'mysqltest_1'@'localhost' def test t1 SELECT NO
@@ -659,12 +664,13 @@ proc body longblob
proc definer char(141)
proc created timestamp
proc modified timestamp
-proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL')
+proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')
proc comment text
proc character_set_client char(32)
proc collation_connection char(32)
proc db_collation char(32)
proc body_utf8 longblob
+proc aggregate enum('NONE','GROUP')
drop table t115;
create procedure p108 () begin declare c cursor for select data_type
from information_schema.columns; open c; open c; end;//
@@ -743,6 +749,7 @@ Lock_tables_priv select,insert,update,references
Show_view_priv select,insert,update,references
Create_routine_priv select,insert,update,references
Alter_routine_priv select,insert,update,references
+Delete_history_priv select,insert,update,references
max_questions select,insert,update,references
max_connections select,insert,update,references
max_user_connections select,insert,update,references
@@ -1157,9 +1164,9 @@ CREATE TABLE t2 (b int);
SHOW TABLE STATUS FROM test
WHERE name IN ( SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_TYPE='BASE TABLE');
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
-t2 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL # N
+t2 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL # N
DROP TABLE t1,t2;
create table t1(f1 int);
create view v1 (c) as select f1 from t1;
@@ -1270,7 +1277,7 @@ drop table t1;
use mysql;
INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL',
'NO','DEFINER','','','BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03',
-'2006-03-02 18:40:03','','','utf8','utf8_general_ci','utf8_general_ci','n/a');
+'2006-03-02 18:40:03','','','utf8','utf8_general_ci','utf8_general_ci','n/a', 'NONE');
select routine_name from information_schema.routines where ROUTINE_SCHEMA='test';
routine_name
@@ -1475,7 +1482,7 @@ SELECT *
FROM tables ta
JOIN collations co ON ( co.collation_name = ta.table_catalog )
JOIN character_sets cs ON ( cs.character_set_name = ta.table_catalog );
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN
DROP TABLE test.t1;
SET max_heap_table_size = DEFAULT;
USE test;
@@ -1577,7 +1584,7 @@ AS SELECT *
FROM information_schema.tables;
SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS where TABLE_NAME = 'v1';
VIEW_DEFINITION
-select `information_schema`.`tables`.`TABLE_CATALOG` AS `TABLE_CATALOG`,`information_schema`.`tables`.`TABLE_SCHEMA` AS `TABLE_SCHEMA`,`information_schema`.`tables`.`TABLE_NAME` AS `TABLE_NAME`,`information_schema`.`tables`.`TABLE_TYPE` AS `TABLE_TYPE`,`information_schema`.`tables`.`ENGINE` AS `ENGINE`,`information_schema`.`tables`.`VERSION` AS `VERSION`,`information_schema`.`tables`.`ROW_FORMAT` AS `ROW_FORMAT`,`information_schema`.`tables`.`TABLE_ROWS` AS `TABLE_ROWS`,`information_schema`.`tables`.`AVG_ROW_LENGTH` AS `AVG_ROW_LENGTH`,`information_schema`.`tables`.`DATA_LENGTH` AS `DATA_LENGTH`,`information_schema`.`tables`.`MAX_DATA_LENGTH` AS `MAX_DATA_LENGTH`,`information_schema`.`tables`.`INDEX_LENGTH` AS `INDEX_LENGTH`,`information_schema`.`tables`.`DATA_FREE` AS `DATA_FREE`,`information_schema`.`tables`.`AUTO_INCREMENT` AS `AUTO_INCREMENT`,`information_schema`.`tables`.`CREATE_TIME` AS `CREATE_TIME`,`information_schema`.`tables`.`UPDATE_TIME` AS `UPDATE_TIME`,`information_schema`.`tables`.`CHECK_TIME` AS `CHECK_TIME`,`information_schema`.`tables`.`TABLE_COLLATION` AS `TABLE_COLLATION`,`information_schema`.`tables`.`CHECKSUM` AS `CHECKSUM`,`information_schema`.`tables`.`CREATE_OPTIONS` AS `CREATE_OPTIONS`,`information_schema`.`tables`.`TABLE_COMMENT` AS `TABLE_COMMENT` from `information_schema`.`tables`
+select `information_schema`.`tables`.`TABLE_CATALOG` AS `TABLE_CATALOG`,`information_schema`.`tables`.`TABLE_SCHEMA` AS `TABLE_SCHEMA`,`information_schema`.`tables`.`TABLE_NAME` AS `TABLE_NAME`,`information_schema`.`tables`.`TABLE_TYPE` AS `TABLE_TYPE`,`information_schema`.`tables`.`ENGINE` AS `ENGINE`,`information_schema`.`tables`.`VERSION` AS `VERSION`,`information_schema`.`tables`.`ROW_FORMAT` AS `ROW_FORMAT`,`information_schema`.`tables`.`TABLE_ROWS` AS `TABLE_ROWS`,`information_schema`.`tables`.`AVG_ROW_LENGTH` AS `AVG_ROW_LENGTH`,`information_schema`.`tables`.`DATA_LENGTH` AS `DATA_LENGTH`,`information_schema`.`tables`.`MAX_DATA_LENGTH` AS `MAX_DATA_LENGTH`,`information_schema`.`tables`.`INDEX_LENGTH` AS `INDEX_LENGTH`,`information_schema`.`tables`.`DATA_FREE` AS `DATA_FREE`,`information_schema`.`tables`.`AUTO_INCREMENT` AS `AUTO_INCREMENT`,`information_schema`.`tables`.`CREATE_TIME` AS `CREATE_TIME`,`information_schema`.`tables`.`UPDATE_TIME` AS `UPDATE_TIME`,`information_schema`.`tables`.`CHECK_TIME` AS `CHECK_TIME`,`information_schema`.`tables`.`TABLE_COLLATION` AS `TABLE_COLLATION`,`information_schema`.`tables`.`CHECKSUM` AS `CHECKSUM`,`information_schema`.`tables`.`CREATE_OPTIONS` AS `CREATE_OPTIONS`,`information_schema`.`tables`.`TABLE_COMMENT` AS `TABLE_COMMENT`,`information_schema`.`tables`.`MAX_INDEX_LENGTH` AS `MAX_INDEX_LENGTH`,`information_schema`.`tables`.`TEMPORARY` AS `TEMPORARY` from `information_schema`.`tables`
DROP VIEW v1;
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME ='information_schema';
@@ -1610,11 +1617,11 @@ TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_
select * from `information_schema`.`STATISTICS` where `TABLE_NAME` = NULL;
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT
select * from information_schema.tables where table_schema = NULL;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
select * from information_schema.tables where table_catalog = NULL;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
select * from information_schema.tables where table_name = NULL;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
select * from `information_schema`.`TABLE_CONSTRAINTS` where `TABLE_SCHEMA` = NULL;
CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE
select * from `information_schema`.`TABLE_CONSTRAINTS` where `TABLE_NAME` = NULL;
diff --git a/mysql-test/r/information_schema_all_engines.result b/mysql-test/r/information_schema_all_engines.result
index 126a6f4bccd..8a92f0226ff 100644
--- a/mysql-test/r/information_schema_all_engines.result
+++ b/mysql-test/r/information_schema_all_engines.result
@@ -454,4 +454,4 @@ Wildcard: inf_rmation_schema
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') GROUP BY TABLE_SCHEMA;
table_schema count(*)
information_schema 64
-mysql 30
+mysql 31
diff --git a/mysql-test/r/intersect.result b/mysql-test/r/intersect.result
index 7a0301a23e6..05adaf160ed 100644
--- a/mysql-test/r/intersect.result
+++ b/mysql-test/r/intersect.result
@@ -689,4 +689,17 @@ View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS (select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union select `__3`.`c` AS `c`,`__3`.`d` AS `d` from ((select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__3` union (select 4 AS `4`,4 AS `4`) latin1 latin1_swedish_ci
drop view v1;
drop tables t1,t2,t3;
+#
+# MDEV-14346:incorrect result of intersect with ANY/ALL/IN subquery
+#
+CREATE TABLE t (i INT);
+INSERT INTO t VALUES (1),(2);
+SELECT * FROM t WHERE i != ANY ( SELECT 6 INTERSECT SELECT 3 );
+i
+select i from t where
+exists ((select 6 as r from dual having t.i <> 6)
+intersect
+(select 3 from dual having t.i <> 3));
+i
+drop table t;
# End of 10.3 tests
diff --git a/mysql-test/r/invisible_binlog.result b/mysql-test/r/invisible_binlog.result
new file mode 100644
index 00000000000..088bc858e28
--- /dev/null
+++ b/mysql-test/r/invisible_binlog.result
@@ -0,0 +1,65 @@
+include/master-slave.inc
+[connection master]
+connection master;
+create table t1(a int , b int invisible);
+insert into t1 values(1);
+insert into t1(a,b) values(2,2);
+select a,b from t1;
+a b
+1 NULL
+2 2
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL INVISIBLE
+create table t2(a int , b int invisible default 5);
+insert into t2 values(1);
+insert into t2(a,b) values(2,2);
+select a,b from t2;
+a b
+1 5
+2 2
+desc t2;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES 5 INVISIBLE
+connection slave;
+select * from t1;
+a
+1
+2
+select a,b from t1;
+a b
+1 NULL
+2 2
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL INVISIBLE
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) INVISIBLE DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t2;
+a
+1
+2
+select a,b from t2;
+a b
+1 5
+2 2
+desc t2;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES 5 INVISIBLE
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) INVISIBLE DEFAULT 5
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+connection master;
+drop table t1,t2;
+include/rpl_end.inc
diff --git a/mysql-test/r/invisible_field.result b/mysql-test/r/invisible_field.result
new file mode 100644
index 00000000000..c331f3fca88
--- /dev/null
+++ b/mysql-test/r/invisible_field.result
@@ -0,0 +1,553 @@
+FLUSH STATUS;
+create table t1(abc int primary key, xyz int invisible);
+SHOW STATUS LIKE 'Feature_invisible_columns';
+Variable_name Value
+Feature_invisible_columns 1
+desc t1;
+Field Type Null Key Default Extra
+abc int(11) NO PRI NULL
+xyz int(11) YES NULL INVISIBLE
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `abc` int(11) NOT NULL,
+ `xyz` int(11) INVISIBLE DEFAULT NULL,
+ PRIMARY KEY (`abc`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select TABLE_CATALOG,TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,EXTRA from INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA='test' and TABLE_NAME='t1';
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME EXTRA
+def test t1 abc
+def test t1 xyz INVISIBLE
+drop table t1;
+create table t1(a1 int invisible);
+ERROR 42000: A table must have at least 1 column
+create table t1(a1 blob,invisible(a1));
+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 '(a1))' at line 1
+create table t1(a1 int primary key invisible ,a2 int unique invisible , a3 blob,a4 int not null invisible unique);
+ERROR HY000: Invisible column `a1` must have a default value
+create table t1(abc int not null invisible);
+ERROR 42000: A table must have at least 1 column
+MDEV-14849 CREATE + ALTER with user-invisible columns produce invalid table definition
+create or replace table t1 (pk int auto_increment primary key invisible, i int);
+alter table t1 modify pk int invisible;
+ERROR HY000: Invisible column `pk` must have a default value
+drop table t1;
+create table t1(a int invisible, b int);
+insert into t1 values(1);
+insert into t1(a) values(2);
+insert into t1(b) values(3);
+insert into t1(a,b) values(5,5);
+select * from t1;
+b
+1
+NULL
+3
+5
+select a,b from t1;
+a b
+NULL 1
+2 NULL
+NULL 3
+5 5
+delete from t1;
+insert into t1 values(1),(2),(3),(4);
+select * from t1;
+b
+1
+2
+3
+4
+select a from t1;
+a
+NULL
+NULL
+NULL
+NULL
+drop table t1;
+#more complex case of invisible
+create table t1(a int , b int invisible , c int invisible auto_increment unique, d blob , e int unique, f int);
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL INVISIBLE
+c int(11) NO PRI NULL auto_increment, INVISIBLE
+d blob YES NULL
+e int(11) YES UNI NULL
+f int(11) YES NULL
+insert into t1 values(1,'d blob',1,1),(1,'d blob',11,1),(1,'d blob',2,1),(1,'d blob',3,1),(1,'d blob',41,1);
+select * from t1;
+a d e f
+1 d blob 1 1
+1 d blob 11 1
+1 d blob 2 1
+1 d blob 3 1
+1 d blob 41 1
+select a,b,c,d,e,f from t1;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+drop table t1;
+#more complex case of invisible with sql_mode=NO_AUTO_VALUE_ON_ZERO
+set sql_mode='NO_AUTO_VALUE_ON_ZERO';
+create table t1(a int , b int invisible , c int invisible auto_increment unique, d blob , e int unique, f int);
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL INVISIBLE
+c int(11) NO PRI NULL auto_increment, INVISIBLE
+d blob YES NULL
+e int(11) YES UNI NULL
+f int(11) YES NULL
+insert into t1 values(1,'d blob',1,1),(1,'d blob',11,1),(1,'d blob',2,1),(1,'d blob',3,1),(1,'d blob',41,1);
+select * from t1;
+a d e f
+1 d blob 1 1
+1 d blob 11 1
+1 d blob 2 1
+1 d blob 3 1
+1 d blob 41 1
+select a,b,c,d,e,f from t1;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+drop table t1;
+set sql_mode='';
+create table sdsdsd(a int , b int, invisible(a,b));
+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 '(a,b))' at line 1
+create table t1(a int,abc int as (a mod 3) virtual invisible);
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+abc int(11) YES NULL VIRTUAL GENERATED, INVISIBLE
+insert into t1 values(1,default);
+ERROR 21S01: Column count doesn't match value count at row 1
+insert into t1 values(1),(22),(233);
+select * from t1;
+a
+1
+22
+233
+select a,abc from t1;
+a abc
+1 1
+22 1
+233 2
+drop table t1;
+create table t1(abc int primary key invisible auto_increment, a int);
+desc t1;
+Field Type Null Key Default Extra
+abc int(11) NO PRI NULL auto_increment, INVISIBLE
+a int(11) YES NULL
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `abc` int(11) NOT NULL INVISIBLE AUTO_INCREMENT,
+ `a` int(11) DEFAULT NULL,
+ PRIMARY KEY (`abc`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values(1);
+insert into t1 values(2);
+insert into t1 values(3);
+select * from t1;
+a
+1
+2
+3
+select abc,a from t1;
+abc a
+1 1
+2 2
+3 3
+delete from t1;
+insert into t1 values(1),(2),(3),(4),(6);
+select abc,a from t1;
+abc a
+4 1
+5 2
+6 3
+7 4
+8 6
+drop table t1;
+create table t1(abc int);
+alter table t1 change abc ss int invisible;
+ERROR 42000: A table must have at least 1 column
+alter table t1 add column xyz int;
+alter table t1 modify column abc int ;
+desc t1;
+Field Type Null Key Default Extra
+abc int(11) YES NULL
+xyz int(11) YES NULL
+insert into t1 values(22);
+ERROR 21S01: Column count doesn't match value count at row 1
+alter table t1 modify column abc int invisible;
+desc t1;
+Field Type Null Key Default Extra
+abc int(11) YES NULL INVISIBLE
+xyz int(11) YES NULL
+insert into t1 values(12);
+drop table t1;
+#some test on copy table structure with table data;
+#table with invisible fields and unique keys;
+create table t1(a int , b int invisible , c int invisible auto_increment unique, d blob , e int unique, f int);
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL INVISIBLE
+c int(11) NO PRI NULL auto_increment, INVISIBLE
+d blob YES NULL
+e int(11) YES UNI NULL
+f int(11) YES NULL
+insert into t1 values(1,'d blob',1,1),(1,'d blob',11,1),(1,'d blob',2,1),(1,'d blob',3,1),(1,'d blob',41,1);
+select * from t1;
+a d e f
+1 d blob 1 1
+1 d blob 11 1
+1 d blob 2 1
+1 d blob 3 1
+1 d blob 41 1
+select a,b,c,d,e,f from t1;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+#this won't copy invisible fields and keys;
+create table t2 as select * from t1;
+desc t2;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+d blob YES NULL
+e int(11) YES NULL
+f int(11) YES NULL
+select * from t2;
+a d e f
+1 d blob 1 1
+1 d blob 11 1
+1 d blob 2 1
+1 d blob 3 1
+1 d blob 41 1
+select a,b,c,d,e,f from t2;
+ERROR 42S22: Unknown column 'b' in 'field list'
+drop table t2;
+#now this will copy invisible fields
+create table t2 as select a,b,c,d,e,f from t1;
+desc t2;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL
+c int(11) NO 0
+d blob YES NULL
+e int(11) YES NULL
+f int(11) YES NULL
+select * from t2;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+select a,b,c,d,e,f from t2;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+drop table t2,t1;
+#some test related to copy of data from one table to another;
+create table t1(a int , b int invisible , c int invisible auto_increment unique, d blob , e int unique, f int);
+insert into t1 values(1,'d blob',1,1),(1,'d blob',11,1),(1,'d blob',2,1),(1,'d blob',3,1),(1,'d blob',41,1);
+select a,b,c,d,e,f from t1;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+create table t2(a int , b int invisible , c int invisible , d blob , e int unique, f int);
+insert into t2 select * from t1;
+select a,b,c,d,e,f from t2;
+a b c d e f
+1 NULL NULL d blob 1 1
+1 NULL NULL d blob 11 1
+1 NULL NULL d blob 2 1
+1 NULL NULL d blob 3 1
+1 NULL NULL d blob 41 1
+truncate t2;
+insert into t2 (a,b,c,d,e,f) select a,b,c,d,e,f from t1;
+select a,b,c,d,e,f from t2;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+truncate t2;
+drop table t1,t2;
+#some test related to creating view on table with invisible column;
+create table t1(a int , b int invisible , c int invisible auto_increment unique, d blob , e int unique, f int);
+insert into t1 values(1,'d blob',1,1),(1,'d blob',11,1),(1,'d blob',2,1),(1,'d blob',3,1),(1,'d blob',41,1);
+create view v as select * from t1;
+desc v;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+d blob YES NULL
+e int(11) YES NULL
+f int(11) YES NULL
+select * from v;
+a d e f
+1 d blob 1 1
+1 d blob 11 1
+1 d blob 2 1
+1 d blob 3 1
+1 d blob 41 1
+#v does not have invisible column;
+select a,b,c,d,e,f from v;
+ERROR 42S22: Unknown column 'b' in 'field list'
+insert into v values(1,21,32,4);
+select * from v;
+a d e f
+1 d blob 1 1
+1 d blob 11 1
+1 d blob 2 1
+1 d blob 3 1
+1 d blob 41 1
+1 21 32 4
+insert into v(a,b,c,d,e,f) values(1,12,3,4,5,6);
+ERROR 42S22: Unknown column 'b' in 'field list'
+drop view v;
+create view v as select a,b,c,d,e,f from t1;
+desc v;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL
+c int(11) NO 0
+d blob YES NULL
+e int(11) YES NULL
+f int(11) YES NULL
+select * from v;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+1 NULL 6 21 32 4
+#v does have invisible column but they aren't invisible anymore.
+select a,b,c,d,e,f from v;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+1 NULL 6 21 32 4
+insert into v values(1,26,33,4,45,66);
+select a,b,c,d,e,f from v;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+1 NULL 6 21 32 4
+1 26 33 4 45 66
+insert into v(a,b,c,d,e,f) values(1,32,31,41,5,6);
+select a,b,c,d,e,f from v;
+a b c d e f
+1 NULL 1 d blob 1 1
+1 NULL 2 d blob 11 1
+1 NULL 3 d blob 2 1
+1 NULL 4 d blob 3 1
+1 NULL 5 d blob 41 1
+1 NULL 6 21 32 4
+1 26 33 4 45 66
+1 32 31 41 5 6
+drop view v;
+drop table t1;
+#now invisible column in where and some join query
+create table t1 (a int unique , b int invisible unique, c int unique invisible);
+insert into t1(a,b,c) values(1,1,1);
+insert into t1(a,b,c) values(2,2,2);
+insert into t1(a,b,c) values(3,3,3);
+insert into t1(a,b,c) values(4,4,4);
+insert into t1(a,b,c) values(21,21,26);
+insert into t1(a,b,c) values(31,31,35);
+insert into t1(a,b,c) values(41,41,45);
+insert into t1(a,b,c) values(22,22,24);
+insert into t1(a,b,c) values(32,32,33);
+insert into t1(a,b,c) values(42,42,43);
+explain select * from t1 where b=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const b b 5 const 1
+select * from t1 where b=3;
+a
+3
+explain select * from t1 where c=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const c c 5 const 1
+select * from t1 where c=3;
+a
+3
+create table t2 as select a,b,c from t1;
+desc t2;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL
+c int(11) YES NULL
+explain select * from t1,t2 where t1.b = t2.c and t1.c = t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10
+1 SIMPLE t1 ALL b,c NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
+select * from t1,t2 where t1.b = t2.c and t1.c = t2.b;
+a a b c
+1 1 1 1
+2 2 2 2
+3 3 3 3
+4 4 4 4
+drop table t1,t2;
+#Unhide invisible columns
+create table t1 (a int primary key, b int invisible, c int invisible unique);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `b` int(11) INVISIBLE DEFAULT NULL,
+ `c` int(11) INVISIBLE DEFAULT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `c` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+desc t1;
+Field Type Null Key Default Extra
+a int(11) NO PRI NULL
+b int(11) YES NULL INVISIBLE
+c int(11) YES UNI NULL INVISIBLE
+alter table t1 modify column b int;
+desc t1;
+Field Type Null Key Default Extra
+a int(11) NO PRI NULL
+b int(11) YES NULL
+c int(11) YES UNI NULL INVISIBLE
+alter table t1 change column c d int;
+desc t1;
+Field Type Null Key Default Extra
+a int(11) NO PRI NULL
+b int(11) YES NULL
+d int(11) YES UNI NULL
+drop table t1;
+SHOW STATUS LIKE 'Feature_invisible_columns';
+Variable_name Value
+Feature_invisible_columns 52
+#invisible is non reserved
+create table t1(a int unique , invisible int invisible, c int );
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES UNI NULL
+invisible int(11) YES NULL INVISIBLE
+c int(11) YES NULL
+alter table t1 change column invisible hid int invisible;
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES UNI NULL
+hid int(11) YES NULL INVISIBLE
+c int(11) YES NULL
+drop table t1;
+CREATE TABLE t1 (b int);
+INSERT t1 values(1);
+INSERT t1 values(2);
+INSERT t1 values(3);
+INSERT t1 values(4);
+INSERT t1 values(5);
+CREATE TABLE t2 (a int invisible) SELECT * FROM t1;
+select * from t2 order by b;
+b
+1
+2
+3
+4
+5
+select a,b from t2 order by b;
+a b
+NULL 1
+NULL 2
+NULL 3
+NULL 4
+NULL 5
+CREATE TABLE t3 (b int, a int invisible) SELECT * FROM t1;
+select * from t3 order by b;
+b
+1
+2
+3
+4
+5
+select a,b from t3 order by b;
+a b
+NULL 1
+NULL 2
+NULL 3
+NULL 4
+NULL 5
+CREATE TABLE t4 (b int invisible) SELECT * FROM t1;
+ERROR 42000: A table must have at least 1 column
+CREATE TABLE t5 (a int invisible) SELECT b as a FROM t1;
+ERROR 42000: A table must have at least 1 column
+drop table t1,t2,t3;
+create table t1 (a int , b int invisible default 3, c int , d int invisible default 6);
+CREATE PROCEDURE
+insert_t1(a int, b int)
+MODIFIES SQL DATA
+insert into t1 values(a,b);
+//
+call insert_t1(1,1);
+call insert_t1(2,2);
+select * from t1 order by a;
+a c
+1 1
+2 2
+select a,b,c,d from t1 order by a;
+a b c d
+1 3 1 6
+2 3 2 6
+DROP PROCEDURE insert_t1;
+delete from t1;
+prepare insert_1 from "insert into t1 values(@a,@c)";
+prepare insert_2 from "insert into t1(a,b,c) values(@a,@b,@c)";
+set @a=1, @c=1;
+execute insert_1;
+set @a=2,@b=2, @c=2;
+execute insert_2;
+select a,b,c,d from t1 order by a;
+a b c d
+1 3 1 6
+2 2 2 6
+drop table t1;
+create table t1(a int default 5 invisible, b int);
+create table t2(a int default (b+11) invisible, b int);
+insert into t1 values(1);
+select a,b from t1;
+a b
+5 1
+insert into t2 values(1);
+select a,b from t2;
+a b
+12 1
+drop table t1,t2;
+create table t1 (a int invisible, b int, c int);
+create table t2 (a int, b int, d int);
+insert t1 (a,b,c) values (0,2,3), (10, 20, 30);
+insert t2 (a,b,d) values (1,2,4), (10, 30, 40);
+select * from t1 join t2 using (a);
+b c b d
+20 30 30 40
+select * from t1 natural join t2;
+b c a d
+2 3 1 4
+drop table t1, t2;
diff --git a/mysql-test/r/invisible_field_debug.result b/mysql-test/r/invisible_field_debug.result
new file mode 100644
index 00000000000..4c4ebffbdfc
--- /dev/null
+++ b/mysql-test/r/invisible_field_debug.result
@@ -0,0 +1,371 @@
+set @old_debug= @@debug_dbug;
+create table t_tmp(a int, b int);
+set debug_dbug= "+d,test_pseudo_invisible";
+create table t1(a int);
+set debug_dbug=@old_debug;
+insert into t1 values(1);
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select a , invisible from t1;
+a invisible
+1 9
+insert into t1(a, invisible) values(99,99);
+ERROR 42S22: Unknown column 'invisible' in 'field list'
+insert into t1(invisible) values(99);
+ERROR 42S22: Unknown column 'invisible' in 'field list'
+insert into t_tmp select a, invisible from t1;
+insert into t1 select * from t_tmp;
+ERROR 21S01: Column count doesn't match value count at row 1
+insert into t1(a,invisible) select * from t_tmp;
+ERROR 42S22: Unknown column 'invisible' in 'field list'
+select a , invisible from t1;
+a invisible
+1 9
+insert into t1 values (5), (invisible+1);
+select a , invisible from t1;
+a invisible
+1 9
+5 9
+10 9
+delete from t1 where a > 1;
+update t1 set a = invisible where a=1;
+select a , invisible from t1;
+a invisible
+9 9
+update t1 set a = (select invisible+100 from t1 limit 1) where a=(select a from t1 limit 1);
+select a , invisible from t1;
+a invisible
+109 9
+update t1 set invisible = 23 where a=(select a from t1 limit 1);
+ERROR 42S22: Unknown column 'invisible' in 'field list'
+update t1 set invisible = 101 where a=(select a from t1 limit 1);
+ERROR 42S22: Unknown column 'invisible' in 'field list'
+update t1 set invisible = (select invisible+100 from t1 limit 1) where a=(select invisible from t1 limit 1);
+ERROR 42S22: Unknown column 'invisible' in 'field list'
+select a , invisible from t1;
+a invisible
+109 9
+set @a=12;
+update t1 set invisible = (select @a from dual) where a=(select a from t1 limit 1);
+ERROR 42S22: Unknown column 'invisible' in 'field list'
+select a , invisible from t1;
+a invisible
+109 9
+update t1 set invisible = (select invisible+100 from t1 limit 1) where a=(select a from t1 limit 1);
+ERROR 42S22: Unknown column 'invisible' in 'field list'
+select a , invisible from t1;
+a invisible
+109 9
+set @a=(select invisible from t1 limit 1);
+select @a from dual;
+@a
+9
+alter table t1 add constraint a check (invisible > 2);
+ERROR 42S22: Unknown column 'invisible' in 'CHECK'
+set debug_dbug= "+d,test_pseudo_invisible";
+create table t2(a int, b int as (invisible +2) virtual);
+ERROR 42S22: Unknown column 'invisible' in 'GENERATED ALWAYS AS'
+create table t2(a int , b int);
+insert into t2 values(2,2);
+insert into t2 select a, invisible from t1;
+set debug_dbug=@old_debug;
+select * from t1;
+a
+109
+select invisible ,a from t1;
+invisible a
+9 109
+drop table t1,t2,t_tmp;
+set debug_dbug= "+d,test_completely_invisible";
+create table t1(a int);
+set debug_dbug=@old_debug;
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values(1);
+select * from t1;
+a
+1
+select invisible ,a from t1;
+ERROR 42S22: Unknown column 'invisible' in 'field list'
+set debug_dbug= "+d,test_completely_invisible";
+select invisible ,a from t1;
+invisible a
+9 1
+set debug_dbug=@old_debug;
+create table t2 (invisible int);
+select * from t1 join t2 using (invisible);
+ERROR 42S22: Unknown column 'invisible' in 'from clause'
+select * from t2 join t1 using (invisible);
+ERROR 42S22: Unknown column 'invisible' in 'from clause'
+insert t2 values (8),(9);
+select * from t1 natural join t2;
+a invisible
+1 8
+1 9
+select * from t2 natural join t1;
+invisible a
+8 1
+9 1
+drop table t1, t2;
+set debug_dbug= "+d,test_pseudo_invisible";
+create table t1(a int);
+set debug_dbug=@old_debug;
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+insert into t1 values(1);
+select * from t1;
+a
+1
+select invisible ,a from t1;
+invisible a
+9 1
+ALTER table t1 change invisible b int;
+ERROR 42S22: Unknown column 'invisible' in 't1'
+select * from t1;
+a
+1
+select invisible ,a from t1;
+invisible a
+9 1
+ALTER table t1 modify invisible char;
+ERROR 42S22: Unknown column 'invisible' in 't1'
+select * from t1;
+a
+1
+select invisible ,a from t1;
+invisible a
+9 1
+ALTER table t1 drop invisible;
+ERROR 42000: Can't DROP COLUMN `invisible`; check that it exists
+select * from t1;
+a
+1
+select invisible ,a from t1;
+invisible a
+9 1
+ALTER table t1 add invisible int;
+ERROR 42S21: Duplicate column name 'invisible'
+select * from t1;
+a
+1
+select invisible ,a from t1;
+invisible a
+9 1
+ALTER table t1 add invisible2 int default 2;
+select * from t1;
+a invisible2
+1 2
+select invisible ,a from t1;
+invisible a
+9 1
+create trigger trg before insert on t1 for each row set new.invisible=1;
+ERROR 42S22: Unknown column 'invisible' in 'NEW'
+create trigger trg before insert on t1 for each row set @a:=new.invisible;
+drop table t1;
+set debug_dbug= "+d,test_completely_invisible";
+create table t1(a int);
+set debug_dbug=@old_debug;
+create trigger trg before insert on t1 for each row set new.invisible=1;
+ERROR 42S22: Unknown column 'invisible' in 'NEW'
+create trigger trg before insert on t1 for each row set @a:=new.invisible;
+ERROR 42S22: Unknown column 'invisible' in 'NEW'
+set debug_dbug= "+d,test_completely_invisible";
+desc t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+insert into t1 values(1);
+select * from t1;
+a
+1
+select invisible ,a from t1;
+invisible a
+9 1
+ALTER table t1 change invisible b int;
+ERROR 42S22: Unknown column 'invisible' in 't1'
+select * from t1;
+a
+1
+select invisible ,a from t1;
+invisible a
+9 1
+ALTER table t1 modify invisible char;
+ERROR 42S22: Unknown column 'invisible' in 't1'
+select * from t1;
+a
+1
+select invisible ,a from t1;
+invisible a
+9 1
+ALTER table t1 drop invisible;
+ERROR 42000: Can't DROP COLUMN `invisible`; check that it exists
+select * from t1;
+a
+1
+select invisible ,a from t1;
+invisible a
+9 1
+ALTER table t1 add invisible int;
+select * from t1;
+a invisible
+1 NULL
+select invisible1, invisible ,a from t1;
+invisible1 invisible a
+9 NULL 1
+ALTER table t1 add hid int default 2;
+select * from t1;
+a invisible hid
+1 NULL 2
+select invisible ,a from t1;
+invisible a
+NULL 1
+drop table t1;
+set debug_dbug=@old_debug;
+Create table t1( a int default(99) invisible, b int);
+insert into t1 values(1);
+insert into t1 values(2);
+insert into t1 values(3);
+insert into t1 values(4);
+select * from t1 order by b;
+b
+1
+2
+3
+4
+alter table t1 add index(a);
+alter table t1 add index(a,b);
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+t1 1 a 1 a A NULL NULL NULL YES BTREE
+t1 1 a_2 1 a A NULL NULL NULL YES BTREE
+t1 1 a_2 2 b A NULL NULL NULL YES BTREE
+drop table t1;
+set debug_dbug= "+d,test_pseudo_invisible";
+Create table t1( a int default(99) invisible, b int);
+Create table t2( a int default(99) invisible, b int, unique(invisible));
+ERROR 42000: Key column 'invisible' doesn't exist in table
+set debug_dbug=@old_debug;
+insert into t1 values(1);
+insert into t1 values(2);
+insert into t1 values(3);
+insert into t1 values(4);
+select * from t1 order by b;
+b
+1
+2
+3
+4
+select invisible, a, b from t1 order by b;
+invisible a b
+9 99 1
+9 99 2
+9 99 3
+9 99 4
+alter table t1 add index(invisible);
+ERROR 42000: Key column 'invisible' doesn't exist in table
+alter table t1 add index(b,invisible);
+ERROR 42000: Key column 'invisible' doesn't exist in table
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+drop table t1;
+set debug_dbug= "+d,test_completely_invisible";
+Create table t1( a int default(99) invisible, b int);
+Create table t2( a int default(99) invisible, b int, unique(invisible));
+ERROR 42000: Key column 'invisible' doesn't exist in table
+insert into t1 values(1);
+insert into t1 values(2);
+insert into t1 values(3);
+insert into t1 values(4);
+select * from t1 order by b;
+b
+1
+2
+3
+4
+select invisible, a, b from t1 order by b;
+invisible a b
+9 99 1
+9 99 2
+9 99 3
+9 99 4
+set debug_dbug=@old_debug;
+alter table t1 add index(invisible);
+ERROR 42000: Key column 'invisible' doesn't exist in table
+alter table t1 add index(b,invisible);
+ERROR 42000: Key column 'invisible' doesn't exist in table
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+drop table t1;
+set debug_dbug= "+d,test_completely_invisible,test_invisible_index";
+Create table t1( a int default(99) , b int,c int, index(b));
+set debug_dbug=@old_debug;
+Show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+t1 1 b 1 b A NULL NULL NULL YES BTREE
+select * from INFORMATION_SCHEMA.STATISTICS where TABLE_SCHEMA ='test' and table_name='t1';
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT
+def test t1 1 test b 1 b A NULL NULL NULL YES BTREE
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT 99,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values(1,1,1);
+insert into t1 values(2,2,2);
+insert into t1 values(3,3,3);
+insert into t1 values(4,4,4);
+set debug_dbug= "+d,test_completely_invisible,test_invisible_index";
+select invisible, a ,b from t1 order by b;
+invisible a b
+9 1 1
+9 2 2
+9 3 3
+9 4 4
+explain select * from t1 where invisible =9;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref invisible invisible 5 const 3
+alter table t1 add x int default 3;
+select invisible, a ,b from t1;
+invisible a b
+9 1 1
+9 2 2
+9 3 3
+9 4 4
+set debug_dbug=@old_debug;
+Show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+t1 1 b 1 b A NULL NULL NULL YES BTREE
+create index a1 on t1(invisible);
+ERROR 42000: Key column 'invisible' doesn't exist in table
+set debug_dbug= "+d,test_completely_invisible,test_invisible_index";
+drop index invisible on t1;
+ERROR 42000: Can't DROP INDEX `invisible`; check that it exists
+explain select * from t1 where invisible =9;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref invisible invisible 5 const 3
+create index invisible on t1(c);
+explain select * from t1 where invisible =9;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref invisible_2 invisible_2 5 const 3
+show indexes in t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+t1 1 b 1 b A NULL NULL NULL YES BTREE
+t1 1 invisible 1 c A NULL NULL NULL YES BTREE
+t1 1 invisible_2 1 invisible A NULL NULL NULL YES BTREE
+drop table t1;
+set @old_debug= @@debug_dbug;
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index df48dbba605..046674d5569 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -762,6 +762,7 @@ user User def mysql 0 mysql PRIMARY 2 A NULL NULL BTREE def mysql '' NO char 8
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
drop table t1;
drop table t2;
drop table t3;
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result
index 5a404fe46a6..eea397402ad 100644
--- a/mysql-test/r/join_cache.result
+++ b/mysql-test/r/join_cache.result
@@ -5867,6 +5867,64 @@ set join_buffer_size=default;
set join_cache_level = default;
DROP TABLE t1,t2;
#
+# MDEV-14960: BNLH used for materialized semi-join
+#
+CREATE TABLE t1 (i1 int);
+CREATE TABLE t2 (e1 int);
+CREATE TABLE t4 (e1 int);
+CREATE TABLE t5 (e1 int);
+INSERT INTO t1 VALUES
+(1),(2),(3),(4),(5),(6),(7),(8);
+INSERT INTO t1 SELECT i1+8 FROM t1;
+INSERT INTO t1 SELECT i1+16 FROM t1;
+INSERT INTO t1 SELECT i1+32 FROM t1;
+INSERT INTO t1 SELECT i1+64 FROM t1;
+INSERT INTO t2 SELECT * FROM t1;
+INSERT INTO t4 SELECT * FROM t1;
+INSERT INTO t5 SELECT * FROM t1;
+set @save_optimizer_switch= @@optimizer_switch;
+SET join_cache_level = 6;
+SET join_buffer_size=4096;
+SET join_buffer_space_limit=4096;
+SET optimizer_switch = 'join_cache_hashed=on,optimize_join_buffer_size=on';
+EXPLAIN SELECT * FROM t1
+WHERE
+i1 < 10 AND
+i1 IN
+(SELECT i1 FROM
+(SELECT (t4.e1) i1 FROM t4
+LEFT JOIN t5 ON t4.e1 = t5.e1
+LEFT JOIN (SELECT e1 FROM t2 ) AS d ON t4.e1 = d.e1) a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 128 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t4 ALL NULL NULL NULL NULL 128
+2 MATERIALIZED t5 hash_ALL NULL #hash#$hj 5 test.t4.e1 128 Using where; Using join buffer (flat, BNLH join)
+2 MATERIALIZED t2 hash_ALL NULL #hash#$hj 5 test.t4.e1 128 Using where; Using join buffer (incremental, BNLH join)
+SELECT * FROM t1
+WHERE
+i1 < 10 AND
+i1 IN
+(SELECT i1 FROM
+(SELECT (t4.e1) i1 FROM t4
+LEFT JOIN t5 ON t4.e1 = t5.e1
+LEFT JOIN (SELECT e1 FROM t2 ) AS d ON t4.e1 = d.e1) a);
+i1
+1
+2
+3
+4
+5
+6
+7
+8
+9
+SET join_cache_level = default;
+SET join_buffer_size = default;
+SET join_buffer_space_limit= default;
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t4,t5,t2;
+#
# MDEV-5123 Remove duplicated conditions pushed both to join_tab->select_cond and join_tab->cache_select->cond for blocked joins.
#
set join_cache_level=default;
diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result
index 917a31e2a79..708c72fffb5 100644
--- a/mysql-test/r/join_nested.result
+++ b/mysql-test/r/join_nested.result
@@ -1321,7 +1321,7 @@ c11 c21
5 NULL
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON c11=c21;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21;
c11 c21 c31
diff --git a/mysql-test/r/join_nested_jcl6.result b/mysql-test/r/join_nested_jcl6.result
index 1ffd94547cc..eb59531b7d2 100644
--- a/mysql-test/r/join_nested_jcl6.result
+++ b/mysql-test/r/join_nested_jcl6.result
@@ -1332,7 +1332,7 @@ c11 c21
5 NULL
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON c11=c21;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21;
c11 c21 c31
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index 46e542910a1..d27a136a6c4 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -2431,5 +2431,18 @@ Warnings:
Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`col2` = `test`.`t1`.`col1`) where `f1`(`test`.`t2`.`col3`,0) = 0
DROP FUNCTION f1;
DROP TABLE t1,t2;
+#
+# MDEV-10397: Server crashes in key_copy with join_cache_level > 2 and join on BIT fields
+#
+CREATE TABLE t1 (b1 BIT NOT NULL);
+INSERT INTO t1 VALUES (0),(1);
+CREATE TABLE t2 (b2 BIT NOT NULL);
+INSERT INTO t2 VALUES (0),(1);
+SET SESSION JOIN_CACHE_LEVEL = 3;
+SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2;
+t1.b1+'0' t2.b2 + '0'
+0 0
+1 1
+DROP TABLE t1, t2;
# end of 5.5 tests
SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result
index 65e2dde409e..72527040301 100644
--- a/mysql-test/r/join_outer_jcl6.result
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -2442,6 +2442,19 @@ Warnings:
Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`col2` = `test`.`t1`.`col1`) where `f1`(`test`.`t2`.`col3`,0) = 0
DROP FUNCTION f1;
DROP TABLE t1,t2;
+#
+# MDEV-10397: Server crashes in key_copy with join_cache_level > 2 and join on BIT fields
+#
+CREATE TABLE t1 (b1 BIT NOT NULL);
+INSERT INTO t1 VALUES (0),(1);
+CREATE TABLE t2 (b2 BIT NOT NULL);
+INSERT INTO t2 VALUES (0),(1);
+SET SESSION JOIN_CACHE_LEVEL = 3;
+SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2;
+t1.b1+'0' t2.b2 + '0'
+0 0
+1 1
+DROP TABLE t1, t2;
# end of 5.5 tests
SET optimizer_switch=@save_optimizer_switch;
set join_cache_level=default;
diff --git a/mysql-test/r/limit_rows_examined.result b/mysql-test/r/limit_rows_examined.result
index c94599235b1..7d1ca948c8b 100644
--- a/mysql-test/r/limit_rows_examined.result
+++ b/mysql-test/r/limit_rows_examined.result
@@ -98,11 +98,11 @@ create table t0 (c0 int);
explain
select * from t0 LIMIT ROWS EXAMINED 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t0 system NULL NULL NULL NULL 0 Const row not found
explain
select * from t0 LIMIT ROWS EXAMINED 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t0 system NULL NULL NULL NULL 0 Const row not found
select * from t0 LIMIT ROWS EXAMINED 1;
c0
drop table t0;
@@ -592,7 +592,7 @@ create table t3_empty like t3;
explain
select max(c1) from t3_empty LIMIT ROWS EXAMINED 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3_empty system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t3_empty system NULL NULL NULL NULL 0 Const row not found
select max(c1) from t3_empty LIMIT ROWS EXAMINED 0;
max(c1)
NULL
diff --git a/mysql-test/r/loadxml.result b/mysql-test/r/loadxml.result
index 1d7af4f8b38..b0fb867a676 100644
--- a/mysql-test/r/loadxml.result
+++ b/mysql-test/r/loadxml.result
@@ -134,3 +134,23 @@ LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
ERROR HY000: Column 'c2' is not updatable
DROP VIEW v1;
DROP TABLE t1;
+#
+# MDEV-14628 Wrong autoinc value assigned by LOAD XML in the NO_AUTO_VALUE_ON_ZERO mode
+#
+SET sql_mode=NO_AUTO_VALUE_ON_ZERO;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT);
+LOAD XML INFILE '../../std_data/loaddata/mdev14628a.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+SELECT * FROM t1 ORDER BY b;
+a b
+1 bbb1
+2 bbb2
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+SET sql_mode='';
+CREATE TABLE t1 (id INT, g GEOMETRY NOT NULL);
+LOAD XML INFILE '../../std_data/loaddata/mdev14628b.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+ERROR 22004: Column set to default value; NULL supplied to NOT NULL column 'g' at row 1
+SELECT * FROM t1;
+id g
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
diff --git a/mysql-test/r/log_tables_upgrade.result b/mysql-test/r/log_tables_upgrade.result
index a56d067c2cd..8f822d56020 100644
--- a/mysql-test/r/log_tables_upgrade.result
+++ b/mysql-test/r/log_tables_upgrade.result
@@ -42,6 +42,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
diff --git a/mysql-test/r/lowercase_table_grant.result b/mysql-test/r/lowercase_table_grant.result
index 009965c0c8e..9ba542ec22d 100644
--- a/mysql-test/r/lowercase_table_grant.result
+++ b/mysql-test/r/lowercase_table_grant.result
@@ -7,8 +7,8 @@ Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
select * from db where user = 'mysqltest_1';
-Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv
-localhost mysqltest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y Y Y Y Y Y Y Y
+Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv Delete_history_priv
+localhost mysqltest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y Y Y Y Y Y Y Y Y
update db set db = 'MYSQLtest' where db = 'mysqltest' and user = 'mysqltest_1' and host = 'localhost';
flush privileges;
show grants for mysqltest_1@localhost;
@@ -16,8 +16,8 @@ Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
select * from db where user = 'mysqltest_1';
-Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv
-localhost MYSQLtest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y Y Y Y Y Y Y Y
+Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv Delete_history_priv
+localhost MYSQLtest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y Y Y Y Y Y Y Y Y
delete from db where db = 'MYSQLtest' and user = 'mysqltest_1' and host = 'localhost';
flush privileges;
drop user mysqltest_1@localhost;
diff --git a/mysql-test/r/mdev_14586.result b/mysql-test/r/mdev_14586.result
new file mode 100644
index 00000000000..f6c2095d3cd
--- /dev/null
+++ b/mysql-test/r/mdev_14586.result
@@ -0,0 +1,44 @@
+create table t1(a bit(1), b int auto_increment ,id int, index(a,b));
+insert into t1 values(1,null,1);
+insert into t1 values(1,null,2);
+insert into t1 values(0,null,3);
+insert into t1 values(0,null,4);
+select a+0, b as auto_increment , id from t1 order by id;
+a+0 auto_increment id
+1 1 1
+1 2 2
+0 1 3
+0 2 4
+drop table t1;
+create table t1(a int auto_increment, b bit(5) ,id int, index (b,a));
+insert into t1 values(null,b'1',1);
+insert into t1 values(null,b'1',2);
+insert into t1 values(null,b'11',3);
+insert into t1 values(null,b'11',4);
+select a as auto_increment, b+0, id from t1 order by id;
+auto_increment b+0 id
+1 1 1
+2 1 2
+1 3 3
+2 3 4
+drop table t1;
+create table t1(a bit(1), b int auto_increment , c bit(1) , d bit(1), id int,index(a,c,b,d));
+insert into t1 values(1,null,1,1,1);
+insert into t1 values(1,null,1,1,2);
+insert into t1 values(0,null,1,1,3);
+insert into t1 values(1,null,0,1,4);
+select a+0, b as auto_increment, c+0, d+0, id from t1 order by id;
+a+0 auto_increment c+0 d+0 id
+1 1 1 1 1
+1 2 1 1 2
+0 1 1 1 3
+1 1 0 1 4
+drop table t1;
+CREATE TABLE t1 (b BIT(1), pk INTEGER AUTO_INCREMENT PRIMARY KEY);
+ALTER TABLE t1 ADD INDEX(b,pk);
+INSERT INTO t1 VALUES (1,b'1');
+ALTER TABLE t1 DROP PRIMARY KEY;
+select b+0, pk as auto_increment from t1;
+b+0 auto_increment
+1 1
+DROP TABLE t1;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index afea08593a6..ff6bdf4a07e 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -2092,10 +2092,9 @@ FLUSH TABLES m1, t1;
UNLOCK TABLES;
DROP TABLE t1, m1;
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=FIRST;
-SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE
-TABLE_SCHEMA = 'test' and TABLE_NAME='tm1';
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
-def test tm1 BASE TABLE NULL NULL NULL # # # # # # # # # # NULL # # Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+SELECT table_schema, table_name, table_type, engine, version, row_format, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='tm1';
+table_schema table_name table_type engine version row_format table_comment
+test tm1 BASE TABLE NULL NULL NULL Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
Warnings:
Warning 1168 Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
DROP TABLE tm1;
@@ -2187,7 +2186,7 @@ col1 int(10) NOT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(t1);
insert into m1 (col1) values (1);
insert into m1 (col1) values (1);
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Can't write; duplicate key in table 'm1'
drop table m1, t1;
#
# Bug#45800 crash when replacing into a merge table and there is a duplicate
@@ -2224,7 +2223,7 @@ CREATE TABLE m1 (c1 INT, c2 INT, UNIQUE (c1)) ENGINE=MRG_MyISAM INSERT_METHOD=LA
INSERT INTO m1 VALUES (1,2);
# insert the duplicate value into the merge table
INSERT INTO m1 VALUES (3,2);
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Can't write; duplicate key in table 'm1'
DROP TABLE m1,t1;
# Try to define MERGE and MyISAM with keys on different columns
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE (c1));
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index f20a08d690a..ef7737c6777 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -861,9 +861,9 @@ _id
8
9
DELETE FROM t1 WHERE _id < 8;
-SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic 2 # # # # 140 # # # # # #
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
+table_name engine version row_format Table_rows Data_free create_options table_comment
+t1 MyISAM 10 Dynamic 2 140
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
@@ -873,9 +873,9 @@ test.t1 optimize status OK
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
-SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic 2 # # # # 0 # # # # # #
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
+table_name engine version row_format Table_rows Data_free create_options table_comment
+t1 MyISAM 10 Dynamic 2 0
SELECT _id FROM t1;
_id
8
@@ -920,9 +920,9 @@ _id
8
9
DELETE FROM t1 WHERE _id < 8;
-SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic 2 # # # # 140 # # # # # #
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
+table_name engine version row_format Table_rows Data_free create_options table_comment
+t1 MyISAM 10 Dynamic 2 140
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
@@ -932,9 +932,9 @@ test.t1 repair status OK
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
-SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic 2 # # # # 140 # # # # # #
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
+table_name engine version row_format Table_rows Data_free create_options table_comment
+t1 MyISAM 10 Dynamic 2 140
SELECT _id FROM t1;
_id
8
@@ -961,9 +961,9 @@ a
3
DROP TABLE t1;
CREATE TABLE t1 (c1 TEXT) AVG_ROW_LENGTH=70100 MAX_ROWS=4100100100;
-SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic X X X 72057594037927935 X X X X X X latin1_swedish_ci X max_rows=4100100100 avg_row_length=70100
+SELECT table_name, engine, version, row_format, max_data_length, max_index_length, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
+table_name engine version row_format max_data_length max_index_length create_options table_comment
+t1 MyISAM 10 Dynamic 72057594037927935 17179868160 max_rows=4100100100 avg_row_length=70100
DROP TABLE t1;
CREATE TABLE t1 (c1 TEXT NOT NULL, KEY c1 (c1(10))) ENGINE=MyISAM;
INSERT INTO t1 VALUES
@@ -1845,28 +1845,28 @@ a
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE INDEX (c1), INDEX (c2)) ENGINE=MYISAM;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 0 # # # 1024 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 0 # # # 1024 # # # # # # # # N
INSERT INTO t1 VALUES (1,1);
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # # # N
ALTER TABLE t1 DISABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # # # N
ALTER TABLE t1 ENABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # # # N
ALTER TABLE t1 DISABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # # # N
ALTER TABLE t1 ENABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # # # N
# Enable keys with parallel repair
SET @@myisam_repair_threads=2;
ALTER TABLE t1 DISABLE KEYS;
diff --git a/mysql-test/r/myisam_explain_non_select_all.result b/mysql-test/r/myisam_explain_non_select_all.result
index 12c5e627f7a..09e662f5d6a 100644
--- a/mysql-test/r/myisam_explain_non_select_all.result
+++ b/mysql-test/r/myisam_explain_non_select_all.result
@@ -2184,13 +2184,13 @@ INSERT INTO t1 VALUES (1, 1, 10), (2, 2, 20);
#
EXPLAIN UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c1 SET t2.c2 = 10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c1 SET t2.c2 = 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 0.00 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
# Status of EXPLAIN EXTENDED query
Variable_name Value
@@ -2199,7 +2199,7 @@ FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED SELECT * FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 0.00 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,NULL AS `c1`,NULL AS `c2` from `test`.`t1`
@@ -2219,13 +2219,13 @@ Handler_read_rnd_next 4
#
EXPLAIN UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c1 SET t2.c2 = 10 WHERE t1.c3 = 10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c1 SET t2.c2 = 10 WHERE t1.c3 = 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 0.00 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
# Status of EXPLAIN EXTENDED query
Variable_name Value
@@ -2234,7 +2234,7 @@ FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED SELECT * FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c3 = 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 0.00 Const row not found
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,NULL AS `c1`,NULL AS `c2` from `test`.`t1` where `test`.`t1`.`c3` = 10
@@ -2571,12 +2571,12 @@ CREATE VIEW v1 (x) AS SELECT b FROM t2;
#
EXPLAIN INSERT INTO v1 SELECT * 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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED INSERT INTO v1 SELECT * FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
# Status of EXPLAIN EXTENDED query
Variable_name Value
Handler_read_rnd_next 1
@@ -2584,7 +2584,7 @@ FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED SELECT * FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select NULL AS `a` from `test`.`t1`
# Status of EXPLAIN EXTENDED "equivalent" SELECT query execution
@@ -2781,7 +2781,7 @@ CREATE TABLE t2 (id INT);
INSERT INTO t1 VALUES (1), (2);
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USING(id) GROUP BY t1.id;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found; Using temporary; Using filesort
+1 SIMPLE t2 system NULL NULL NULL NULL 0 Const row not found; Using temporary; Using filesort
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
DROP TABLE t1,t2;
#74
@@ -2879,7 +2879,7 @@ CALL p16();
DROP PROCEDURE p16;
CALL p15();
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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
DROP PROCEDURE p15;
CALL p14();
DROP PROCEDURE p14;
diff --git a/mysql-test/r/myisam_optimize.result b/mysql-test/r/myisam_optimize.result
index b769c4ac3e9..f71d524fadb 100644
--- a/mysql-test/r/myisam_optimize.result
+++ b/mysql-test/r/myisam_optimize.result
@@ -29,3 +29,17 @@ disconnect con2;
connection default;
drop table t1;
set debug_sync='reset';
+# End of 5.5 tests
+CREATE TABLE t1 (i INT) ENGINE=MyISAM;
+INSERT t1 VALUES (1);
+LOCK TABLE t1 WRITE;
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+SELECT * FROM INFORMATION_SCHEMA.TABLES;
+SELECT * FROM t1;
+i
+1
+UNLOCK TABLES;
+DROP TABLE t1;
+# End of 10.0 tests
diff --git a/mysql-test/r/mysql_upgrade-6984.result b/mysql-test/r/mysql_upgrade-6984.result
index 59c9a865b7c..6c711b4847f 100644
--- a/mysql-test/r/mysql_upgrade-6984.result
+++ b/mysql-test/r/mysql_upgrade-6984.result
@@ -33,6 +33,9 @@ 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
+Error : Unknown storage engine 'InnoDB'
+error : Corrupt
mysql.user OK
Repairing tables
@@ -42,6 +45,9 @@ error : Corrupt
mysql.innodb_table_stats
Error : Unknown storage engine 'InnoDB'
error : Corrupt
+mysql.transaction_registry
+Error : Unknown storage engine 'InnoDB'
+error : Corrupt
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
Phase 4/7: Running 'mysql_fix_privilege_tables'
diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result
index a6a5da8f8c8..08efe0e8bc8 100644
--- a/mysql-test/r/mysql_upgrade.result
+++ b/mysql-test/r/mysql_upgrade.result
@@ -30,6 +30,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -78,6 +79,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -126,6 +128,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -179,6 +182,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -233,6 +237,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -290,6 +295,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -342,6 +348,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views... Skipped
@@ -386,6 +393,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -451,6 +459,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -533,6 +542,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -552,7 +562,7 @@ OK
# Should return 2
SELECT count(*) FROM information_schema.tables where ENGINE="InnoDB";
count(*)
-2
+3
SHOW CREATE TABLE test.t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -561,3 +571,22 @@ t1 CREATE TABLE `t1` (
DROP TABLE test.t1;
SET GLOBAL enforce_storage_engine=NULL;
End of 10.1 tests
+Start of 10.3 tests
+#
+# Ensure that mysql_upgrade correctly sets truncate_versioning_priv
+# on upgrade from 10.2
+#
+flush privileges;
+CREATE USER 'user3'@'%';
+GRANT USAGE ON *.* TO 'user3'@'%';
+GRANT ALL PRIVILEGES ON `roelt`.`test2` TO 'user3'@'%';
+alter table mysql.user drop column Delete_history_priv;
+alter table mysql.db drop column Delete_history_priv;
+Run mysql_upgrade with all privileges on a user
+flush privileges;
+SHOW GRANTS FOR 'user3'@'%';
+Grants for user3@%
+GRANT USAGE ON *.* TO 'user3'@'%'
+GRANT ALL PRIVILEGES ON `roelt`.`test2` TO 'user3'@'%'
+DROP USER 'user3'@'%';
+update mysql.db set Delete_history_priv='Y' where db like 'test%';
diff --git a/mysql-test/r/mysql_upgrade_no_innodb.result b/mysql-test/r/mysql_upgrade_no_innodb.result
index 6ad818278f8..8e051bb7c16 100644
--- a/mysql-test/r/mysql_upgrade_no_innodb.result
+++ b/mysql-test/r/mysql_upgrade_no_innodb.result
@@ -33,6 +33,9 @@ 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
+Error : Unknown storage engine 'InnoDB'
+error : Corrupt
mysql.user OK
Repairing tables
@@ -42,6 +45,9 @@ error : Corrupt
mysql.innodb_table_stats
Error : Unknown storage engine 'InnoDB'
error : Corrupt
+mysql.transaction_registry
+Error : Unknown storage engine 'InnoDB'
+error : Corrupt
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views... Skipped
Phase 4/7: Running 'mysql_fix_privilege_tables'
diff --git a/mysql-test/r/mysql_upgrade_noengine.result b/mysql-test/r/mysql_upgrade_noengine.result
index ef6657e0a0c..7b3b1610ee0 100644
--- a/mysql-test/r/mysql_upgrade_noengine.result
+++ b/mysql-test/r/mysql_upgrade_noengine.result
@@ -83,6 +83,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -171,6 +172,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
@@ -259,6 +261,7 @@ 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
diff --git a/mysql-test/r/mysql_upgrade_ssl.result b/mysql-test/r/mysql_upgrade_ssl.result
index 918a24ffc71..172a1401cdb 100644
--- a/mysql-test/r/mysql_upgrade_ssl.result
+++ b/mysql-test/r/mysql_upgrade_ssl.result
@@ -31,6 +31,7 @@ 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
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
diff --git a/mysql-test/r/mysql_upgrade_view.result b/mysql-test/r/mysql_upgrade_view.result
index dc31592566a..813138b57a8 100644
--- a/mysql-test/r/mysql_upgrade_view.result
+++ b/mysql-test/r/mysql_upgrade_view.result
@@ -97,6 +97,9 @@ 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
+Error : Unknown storage engine 'InnoDB'
+error : Corrupt
mysql.user OK
Repairing tables
@@ -106,6 +109,9 @@ error : Corrupt
mysql.innodb_table_stats
Error : Unknown storage engine 'InnoDB'
error : Corrupt
+mysql.transaction_registry
+Error : Unknown storage engine 'InnoDB'
+error : Corrupt
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
test.v1 OK
@@ -241,6 +247,9 @@ 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
+Error : Unknown storage engine 'InnoDB'
+error : Corrupt
mysql.user OK
Repairing tables
@@ -250,6 +259,9 @@ error : Corrupt
mysql.innodb_table_stats
Error : Unknown storage engine 'InnoDB'
error : Corrupt
+mysql.transaction_registry
+Error : Unknown storage engine 'InnoDB'
+error : Corrupt
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views from mysql
test.v1 OK
@@ -360,6 +372,9 @@ 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
+Error : Unknown storage engine 'InnoDB'
+error : Corrupt
mysql.user OK
Repairing tables
@@ -369,6 +384,9 @@ error : Corrupt
mysql.innodb_table_stats
Error : Unknown storage engine 'InnoDB'
error : Corrupt
+mysql.transaction_registry
+Error : Unknown storage engine 'InnoDB'
+error : Corrupt
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views from mysql
test.v1 OK
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index 5ee31bbe227..668952d20d7 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -879,9 +879,7 @@ ROLLBACK /* added by mysqlbinlog */;
End of 5.0 tests
End of 5.1 tests
# Expect deprecation warning.
-WARNING: The --base64-output=always flag and the --base64-output flag (with '=MODE' omitted), are deprecated. The output generated when these flags are used cannot be parsed by mysql 5.6.0 and later. The flags will be removed in a future version. Please use --base64-output=auto instead.
# Expect deprecation warning again.
-WARNING: The --base64-output=always flag and the --base64-output flag (with '=MODE' omitted), are deprecated. The output generated when these flags are used cannot be parsed by mysql 5.6.0 and later. The flags will be removed in a future version. Please use --base64-output=auto instead.
RESET MASTER;
CREATE DATABASE test1;
USE test1;
@@ -1258,3 +1256,4 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
+mysqlbinlog Ver VER for OS at ARCH
diff --git a/mysql-test/r/mysqlbinlog_row_compressed.result b/mysql-test/r/mysqlbinlog_row_compressed.result
index 24fff723ec8..cbea1cf9def 100644
--- a/mysql-test/r/mysqlbinlog_row_compressed.result
+++ b/mysql-test/r/mysqlbinlog_row_compressed.result
@@ -61,7 +61,7 @@ BEGIN
#Q> INSERT INTO t1 VALUES (10, 1, 2, 3, 4, 5, 6, 7, "")
#<date> server id 1 end_log_pos 899 CRC32 XXX Table_map: `test`.`t1` mapped to number num
# at 899
-#<date> server id 1 end_log_pos 967 CRC32 XXX Write_compressed_rows: table id 30 flags: STMT_END_F
+#<date> server id 1 end_log_pos 967 CRC32 XXX Write_compressed_rows: table id 31 flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
### @1=10 /* INT meta=0 nullable=0 is_null=0 */
@@ -73,6 +73,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 1
# at 967
#<date> server id 1 end_log_pos 1040 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -89,7 +90,7 @@ BEGIN
#Q> INSERT INTO t1 VALUES (11, 1, 2, 3, 4, 5, 6, 7, NULL)
#<date> server id 1 end_log_pos 1214 CRC32 XXX Table_map: `test`.`t1` mapped to number num
# at 1214
-#<date> server id 1 end_log_pos 1281 CRC32 XXX Write_compressed_rows: table id 30 flags: STMT_END_F
+#<date> server id 1 end_log_pos 1281 CRC32 XXX Write_compressed_rows: table id 31 flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
### @1=11 /* INT meta=0 nullable=0 is_null=0 */
@@ -101,6 +102,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9=NULL /* STRING(1) meta=65025 nullable=1 is_null=1 */
+# Number of rows: 1
# at 1281
#<date> server id 1 end_log_pos 1354 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -117,7 +119,7 @@ BEGIN
#Q> INSERT INTO t1 VALUES (12, 1, 2, 3, NULL, 5, 6, 7, "A")
#<date> server id 1 end_log_pos 1530 CRC32 XXX Table_map: `test`.`t1` mapped to number num
# at 1530
-#<date> server id 1 end_log_pos 1596 CRC32 XXX Write_compressed_rows: table id 30 flags: STMT_END_F
+#<date> server id 1 end_log_pos 1596 CRC32 XXX Write_compressed_rows: table id 31 flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
### @1=12 /* INT meta=0 nullable=0 is_null=0 */
@@ -129,6 +131,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 1
# at 1596
#<date> server id 1 end_log_pos 1669 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -145,7 +148,7 @@ BEGIN
#Q> INSERT INTO t1 VALUES (13, 1, 2, 3, 0, 5, 6, 7, "A")
#<date> server id 1 end_log_pos 1842 CRC32 XXX Table_map: `test`.`t1` mapped to number num
# at 1842
-#<date> server id 1 end_log_pos 1909 CRC32 XXX Write_compressed_rows: table id 30 flags: STMT_END_F
+#<date> server id 1 end_log_pos 1909 CRC32 XXX Write_compressed_rows: table id 31 flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
### @1=13 /* INT meta=0 nullable=0 is_null=0 */
@@ -157,6 +160,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 1
# at 1909
#<date> server id 1 end_log_pos 1982 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -173,7 +177,7 @@ BEGIN
#Q> INSERT INTO t2 SELECT * FROM t1
#<date> server id 1 end_log_pos 2134 CRC32 XXX Table_map: `test`.`t2` mapped to number num
# at 2134
-#<date> server id 1 end_log_pos 2225 CRC32 XXX Write_compressed_rows: table id 31 flags: STMT_END_F
+#<date> server id 1 end_log_pos 2225 CRC32 XXX Write_compressed_rows: table id 32 flags: STMT_END_F
### INSERT INTO `test`.`t2`
### SET
### @1=10 /* INT meta=0 nullable=0 is_null=0 */
@@ -218,6 +222,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 4
# at 2225
#<date> server id 1 end_log_pos 2298 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -234,7 +239,7 @@ BEGIN
#Q> UPDATE t2 SET f4=5 WHERE f4>0 or f4 is NULL
#<date> server id 1 end_log_pos 2462 CRC32 XXX Table_map: `test`.`t2` mapped to number num
# at 2462
-#<date> server id 1 end_log_pos 2561 CRC32 XXX Update_compressed_rows: table id 31 flags: STMT_END_F
+#<date> server id 1 end_log_pos 2561 CRC32 XXX Update_compressed_rows: table id 32 flags: STMT_END_F
### UPDATE `test`.`t2`
### WHERE
### @1=10 /* INT meta=0 nullable=0 is_null=0 */
@@ -298,6 +303,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 3
# at 2561
#<date> server id 1 end_log_pos 2634 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -314,7 +320,7 @@ BEGIN
#Q> DELETE FROM t1
#<date> server id 1 end_log_pos 2769 CRC32 XXX Table_map: `test`.`t1` mapped to number num
# at 2769
-#<date> server id 1 end_log_pos 2861 CRC32 XXX Delete_compressed_rows: table id 30 flags: STMT_END_F
+#<date> server id 1 end_log_pos 2861 CRC32 XXX Delete_compressed_rows: table id 31 flags: STMT_END_F
### DELETE FROM `test`.`t1`
### WHERE
### @1=10 /* INT meta=0 nullable=0 is_null=0 */
@@ -359,6 +365,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 4
# at 2861
#<date> server id 1 end_log_pos 2934 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -375,7 +382,7 @@ BEGIN
#Q> DELETE FROM t2
#<date> server id 1 end_log_pos 3069 CRC32 XXX Table_map: `test`.`t2` mapped to number num
# at 3069
-#<date> server id 1 end_log_pos 3154 CRC32 XXX Delete_compressed_rows: table id 31 flags: STMT_END_F
+#<date> server id 1 end_log_pos 3154 CRC32 XXX Delete_compressed_rows: table id 32 flags: STMT_END_F
### DELETE FROM `test`.`t2`
### WHERE
### @1=10 /* INT meta=0 nullable=0 is_null=0 */
@@ -420,6 +427,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 4
# at 3154
#<date> server id 1 end_log_pos 3227 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
diff --git a/mysql-test/r/mysqlbinlog_row_minimal.result b/mysql-test/r/mysqlbinlog_row_minimal.result
index ca8e43bfb33..6417a528638 100644
--- a/mysql-test/r/mysqlbinlog_row_minimal.result
+++ b/mysql-test/r/mysqlbinlog_row_minimal.result
@@ -59,7 +59,7 @@ BEGIN
#Q> INSERT INTO t1 VALUES (10, 1, 2, 3, 4, 5, 6, 7, "")
#<date> server id 1 end_log_pos 946 CRC32 XXX Table_map: `test`.`t1` mapped to number num
# at 946
-#<date> server id 1 end_log_pos 1015 CRC32 XXX Write_rows: table id 30 flags: STMT_END_F
+#<date> server id 1 end_log_pos 1015 CRC32 XXX Write_rows: table id 31 flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
### @1=10 /* INT meta=0 nullable=0 is_null=0 */
@@ -71,6 +71,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 1
# at 1015
#<date> server id 1 end_log_pos 1088 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -87,7 +88,7 @@ BEGIN
#Q> INSERT INTO t1 VALUES (11, 1, 2, 3, 4, 5, 6, 7, NULL)
#<date> server id 1 end_log_pos 1262 CRC32 XXX Table_map: `test`.`t1` mapped to number num
# at 1262
-#<date> server id 1 end_log_pos 1330 CRC32 XXX Write_rows: table id 30 flags: STMT_END_F
+#<date> server id 1 end_log_pos 1330 CRC32 XXX Write_rows: table id 31 flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
### @1=11 /* INT meta=0 nullable=0 is_null=0 */
@@ -99,6 +100,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9=NULL /* STRING(1) meta=65025 nullable=1 is_null=1 */
+# Number of rows: 1
# at 1330
#<date> server id 1 end_log_pos 1403 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -115,7 +117,7 @@ BEGIN
#Q> INSERT INTO t1 VALUES (12, 1, 2, 3, NULL, 5, 6, 7, "A")
#<date> server id 1 end_log_pos 1579 CRC32 XXX Table_map: `test`.`t1` mapped to number num
# at 1579
-#<date> server id 1 end_log_pos 1646 CRC32 XXX Write_rows: table id 30 flags: STMT_END_F
+#<date> server id 1 end_log_pos 1646 CRC32 XXX Write_rows: table id 31 flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
### @1=12 /* INT meta=0 nullable=0 is_null=0 */
@@ -127,6 +129,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 1
# at 1646
#<date> server id 1 end_log_pos 1719 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -143,7 +146,7 @@ BEGIN
#Q> INSERT INTO t1 VALUES (13, 1, 2, 3, 0, 5, 6, 7, "A")
#<date> server id 1 end_log_pos 1892 CRC32 XXX Table_map: `test`.`t1` mapped to number num
# at 1892
-#<date> server id 1 end_log_pos 1962 CRC32 XXX Write_rows: table id 30 flags: STMT_END_F
+#<date> server id 1 end_log_pos 1962 CRC32 XXX Write_rows: table id 31 flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
### @1=13 /* INT meta=0 nullable=0 is_null=0 */
@@ -155,6 +158,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 1
# at 1962
#<date> server id 1 end_log_pos 2035 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -171,7 +175,7 @@ BEGIN
#Q> INSERT INTO t2 SELECT * FROM t1
#<date> server id 1 end_log_pos 2187 CRC32 XXX Table_map: `test`.`t2` mapped to number num
# at 2187
-#<date> server id 1 end_log_pos 2354 CRC32 XXX Write_rows: table id 31 flags: STMT_END_F
+#<date> server id 1 end_log_pos 2354 CRC32 XXX Write_rows: table id 32 flags: STMT_END_F
### INSERT INTO `test`.`t2`
### SET
### @1=10 /* INT meta=0 nullable=0 is_null=0 */
@@ -216,6 +220,7 @@ BEGIN
### @7=6 /* INT meta=0 nullable=1 is_null=0 */
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
+# Number of rows: 4
# at 2354
#<date> server id 1 end_log_pos 2427 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -232,7 +237,7 @@ BEGIN
#Q> UPDATE t2 SET f4=5 WHERE f4>0 or f4 is NULL
#<date> server id 1 end_log_pos 2591 CRC32 XXX Table_map: `test`.`t2` mapped to number num
# at 2591
-#<date> server id 1 end_log_pos 2665 CRC32 XXX Update_rows: table id 31 flags: STMT_END_F
+#<date> server id 1 end_log_pos 2665 CRC32 XXX Update_rows: table id 32 flags: STMT_END_F
### UPDATE `test`.`t2`
### WHERE
### @1=10 /* INT meta=0 nullable=0 is_null=0 */
@@ -251,6 +256,7 @@ BEGIN
### @5=NULL /* INT meta=0 nullable=1 is_null=1 */
### SET
### @5=5 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at 2665
#<date> server id 1 end_log_pos 2738 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -267,7 +273,7 @@ BEGIN
#Q> DELETE FROM t1
#<date> server id 1 end_log_pos 2873 CRC32 XXX Table_map: `test`.`t1` mapped to number num
# at 2873
-#<date> server id 1 end_log_pos 2927 CRC32 XXX Delete_rows: table id 30 flags: STMT_END_F
+#<date> server id 1 end_log_pos 2927 CRC32 XXX Delete_rows: table id 31 flags: STMT_END_F
### DELETE FROM `test`.`t1`
### WHERE
### @1=10 /* INT meta=0 nullable=0 is_null=0 */
@@ -280,6 +286,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=13 /* INT meta=0 nullable=0 is_null=0 */
+# Number of rows: 4
# at 2927
#<date> server id 1 end_log_pos 3000 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
@@ -296,7 +303,7 @@ BEGIN
#Q> DELETE FROM t2
#<date> server id 1 end_log_pos 3135 CRC32 XXX Table_map: `test`.`t2` mapped to number num
# at 3135
-#<date> server id 1 end_log_pos 3189 CRC32 XXX Delete_rows: table id 31 flags: STMT_END_F
+#<date> server id 1 end_log_pos 3189 CRC32 XXX Delete_rows: table id 32 flags: STMT_END_F
### DELETE FROM `test`.`t2`
### WHERE
### @1=10 /* INT meta=0 nullable=0 is_null=0 */
@@ -309,6 +316,7 @@ BEGIN
### DELETE FROM `test`.`t2`
### WHERE
### @1=13 /* INT meta=0 nullable=0 is_null=0 */
+# Number of rows: 4
# at 3189
#<date> server id 1 end_log_pos 3262 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result
index ff9cc5d5c81..7259b68be50 100644
--- a/mysql-test/r/mysqlcheck.result
+++ b/mysql-test/r/mysqlcheck.result
@@ -31,6 +31,7 @@ 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
mtr.global_suppressions Table is already up to date
mtr.test_suppressions Table is already up to date
@@ -65,6 +66,9 @@ 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
+note : Table does not support optimize, doing recreate + analyze instead
+status : OK
mysql.user OK
mysql.column_stats OK
mysql.columns_priv OK
@@ -93,6 +97,7 @@ 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
mysql.column_stats Table is already up to date
mysql.columns_priv Table is already up to date
@@ -125,6 +130,9 @@ mysql.time_zone_leap_second Table is already up to date
mysql.time_zone_name Table is already up to date
mysql.time_zone_transition Table is already up to date
mysql.time_zone_transition_type Table is already up to date
+mysql.transaction_registry
+note : Table does not support optimize, doing recreate + analyze instead
+status : OK
mysql.user Table is already up to date
create table t1 (a int) engine=myisam;
create view v1 as select * from t1;
@@ -447,6 +455,7 @@ mysql.time_zone_leap_second Table is already up to date
mysql.time_zone_name Table is already up to date
mysql.time_zone_transition Table is already up to date
mysql.time_zone_transition_type Table is already up to date
+mysql.transaction_registry OK
mysql.user Table is already up to date
mysqltest1.t1
warning : Table is marked as crashed
diff --git a/mysql-test/r/mysqld--help,win.rdiff b/mysql-test/r/mysqld--help,win.rdiff
index b93adcc89d4..367744f6f5d 100644
--- a/mysql-test/r/mysqld--help,win.rdiff
+++ b/mysql-test/r/mysqld--help,win.rdiff
@@ -1,6 +1,6 @@
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
-@@ -381,7 +381,6 @@
+@@ -381,7 +381,6 @@ The following options may be given as the first argument:
The number of segments in a key cache
-L, --language=name Client error messages in given language. May be given as
a full path. Deprecated. Use --lc-messages-dir instead.
@@ -8,7 +8,7 @@
--lc-messages=name Set the language used for the error messages.
-L, --lc-messages-dir=name
Directory where error messages are
-@@ -602,6 +601,7 @@
+@@ -603,6 +602,7 @@ The following options may be given as the first argument:
Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME,
DATETIME, TIMESTAMP columns.
(Defaults to on; use --skip-mysql56-temporal-format to disable.)
@@ -16,7 +16,7 @@
--net-buffer-length=#
Buffer length for TCP/IP and socket communication
--net-read-timeout=#
-@@ -1020,6 +1020,9 @@
+@@ -1048,6 +1048,9 @@ The following options may be given as the first argument:
characteristics (isolation level, read only/read
write,snapshot - but not any work done / data modified
within the transaction).
@@ -26,7 +26,7 @@
--show-slave-auth-info
Show user and password in SHOW SLAVE HOSTS on this
master.
-@@ -1132,6 +1135,10 @@
+@@ -1171,6 +1174,10 @@ The following options may be given as the first argument:
Log slow queries to given log file. Defaults logging to
'hostname'-slow.log. Must be enabled to activate other
slow log options
@@ -37,15 +37,15 @@
--socket=name Socket file to use for connection
--sort-buffer-size=#
Each thread that needs to do a sort allocates a buffer of
-@@ -1151,6 +1158,7 @@
- EMPTY_STRING_IS_NULL
+@@ -1190,6 +1197,7 @@ The following options may be given as the first argument:
+ EMPTY_STRING_IS_NULL, SIMULTANEOUS_ASSIGNMENT
--stack-trace Print a symbolic stack trace on failure
(Defaults to on; use --skip-stack-trace to disable.)
+ --standalone Dummy option to start as a standalone program (NT).
--standard-compliant-cte
Allow only CTEs compliant to SQL standard
(Defaults to on; use --skip-standard-compliant-cte to disable.)
-@@ -1214,6 +1222,11 @@
+@@ -1257,6 +1265,11 @@ The following options may be given as the first argument:
--thread-pool-max-threads=#
Maximum allowed number of worker threads in the thread
pool
@@ -57,7 +57,7 @@
--thread-pool-oversubscribe=#
How many additional active worker threads in a group are
allowed.
-@@ -1252,8 +1265,8 @@
+@@ -1295,8 +1308,8 @@ The following options may be given as the first argument:
automatically convert it to an on-disk MyISAM or Aria
table.
-t, --tmpdir=name Path for temporary files. Several paths may be specified,
@@ -68,7 +68,7 @@
--transaction-alloc-block-size=#
Allocation block size for transactions to be stored in
binary log
-@@ -1387,7 +1400,6 @@
+@@ -1430,7 +1443,6 @@ key-cache-block-size 1024
key-cache-division-limit 100
key-cache-file-hash-size 512
key-cache-segments 0
@@ -76,7 +76,7 @@
lc-messages en_US
lc-messages-dir MYSQL_SHAREDIR/
lc-time-names en_US
-@@ -1459,6 +1471,7 @@
+@@ -1502,6 +1514,7 @@ myisam-sort-buffer-size 134216704
myisam-stats-method NULLS_UNEQUAL
myisam-use-mmap FALSE
mysql56-temporal-format TRUE
@@ -84,7 +84,7 @@
net-buffer-length 16384
net-read-timeout 30
net-retry-count 10
-@@ -1561,6 +1574,8 @@
+@@ -1612,6 +1625,8 @@ session-track-schema TRUE
session-track-state-change FALSE
session-track-system-variables autocommit,character_set_client,character_set_connection,character_set_results,time_zone
session-track-transaction-info OFF
@@ -93,7 +93,7 @@
show-slave-auth-info FALSE
silent-startup FALSE
skip-grant-tables TRUE
-@@ -1585,6 +1600,7 @@
+@@ -1638,6 +1653,7 @@ slave-transaction-retry-interval 0
slave-type-conversions
slow-launch-time 2
slow-query-log FALSE
@@ -101,10 +101,10 @@
sort-buffer-size 2097152
sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
stack-trace TRUE
-@@ -1598,9 +1614,9 @@
- sync-relay-log 10000
+@@ -1652,9 +1668,9 @@ sync-relay-log 10000
sync-relay-log-info 10000
sysdate-is-now FALSE
+ system-versioning-alter-history ERROR
-table-cache 431
+table-cache 2000
table-definition-cache 400
@@ -113,7 +113,7 @@
table-open-cache-instances 8
tc-heuristic-recover OFF
tcp-keepalive-interval 0
-@@ -1609,6 +1625,8 @@
+@@ -1663,6 +1679,8 @@ tcp-keepalive-time 0
thread-cache-size 151
thread-pool-idle-timeout 60
thread-pool-max-threads 65536
diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result
index 266180d7860..add82225739 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -242,7 +242,7 @@ The following options may be given as the first argument:
This option causes CREATE TABLE to create all TIMESTAMP
columns as NULL with DEFAULT NULL attribute, Without this
option, TIMESTAMP columns are NOT NULL and have implicit
- DEFAULT clauses. The old behavior is deprecated.
+ DEFAULT clauses.
--external-locking Use system (external) locking (disabled by default).
With this option enabled you can run myisamchk to test
(not repair) tables while the MySQL server is running.
@@ -336,10 +336,6 @@ The following options may be given as the first argument:
Specifies a directory to add to the ignore list when
collecting database names from the datadir. Put a blank
argument to reset the list accumulated so far.
- --in-subquery-conversion-threshold[=#]
- The minimum number of scalar elements in the value list
- of IN predicate that triggers its conversion to IN
- subquery
--init-connect=name Command(s) that are executed for each new connection
(unless the user has SUPER privilege)
--init-file=name Read SQL commands from this file at startup
@@ -669,7 +665,7 @@ The following options may be given as the first argument:
join_cache_hashed, join_cache_bka,
optimize_join_buffer_size, table_elimination,
extended_keys, exists_to_in, orderby_uses_equalities,
- condition_pushdown_for_derived, split_grouping_derived
+ condition_pushdown_for_derived, split_materialized
--optimizer-use-condition-selectivity=#
Controls selectivity of which conditions the optimizer
takes into account to calculate cardinality of a partial
@@ -998,6 +994,33 @@ The following options may be given as the first argument:
--rowid-merge-buff-size=#
The size of the buffers used [NOT] IN evaluation via
partial matching
+ --rpl-semi-sync-master-enabled
+ Enable semi-synchronous replication master (disabled by
+ default).
+ --rpl-semi-sync-master-timeout=#
+ The timeout value (in ms) for semi-synchronous
+ replication in the master
+ --rpl-semi-sync-master-trace-level=#
+ The tracing level for semi-sync replication.
+ --rpl-semi-sync-master-wait-no-slave
+ Wait until timeout when no semi-synchronous replication
+ slave available (enabled by default).
+ (Defaults to on; use --skip-rpl-semi-sync-master-wait-no-slave to disable.)
+ --rpl-semi-sync-master-wait-point=name
+ Should transaction wait for semi-sync ack after having
+ synced binlog, or after having committed in storage
+ engine.. One of: AFTER_SYNC, AFTER_COMMIT
+ --rpl-semi-sync-slave-delay-master
+ Only write master info file when ack is needed.
+ --rpl-semi-sync-slave-enabled
+ Enable semi-synchronous replication slave (disabled by
+ default).
+ --rpl-semi-sync-slave-kill-conn-timeout[=#]
+ Timeout for the mysql connection used to kill the slave
+ io_thread's connection on master. This timeout comes into
+ play when stop slave is executed.
+ --rpl-semi-sync-slave-trace-level=#
+ The tracing level for semi-sync replication.
--safe-mode Skip some optimize stages (for testing). Deprecated.
--safe-user-create Don't allow new user creation by the user who has no
write privileges to the mysql.user table.
@@ -1118,8 +1141,19 @@ The following options may be given as the first argument:
(Defaults to on; use --skip-slave-sql-verify-checksum to disable.)
--slave-transaction-retries=#
Number of times the slave SQL thread will retry a
- transaction in case it failed with a deadlock or elapsed
- lock wait timeout, before giving up and stopping
+ transaction in case it failed with a deadlock, elapsed
+ lock wait timeout or listed in
+ slave_transaction_retry_errors, before giving up and
+ stopping
+ --slave-transaction-retry-errors=name
+ Tells the slave thread to retry transaction for
+ replication when a query event returns an error from the
+ provided list. Deadlock and elapsed lock wait timeout
+ errors are automatically added to this list
+ --slave-transaction-retry-interval=#
+ Interval of the slave SQL thread will retry a transaction
+ in case it failed with a deadlock or elapsed lock wait
+ timeout or listed in slave_transaction_retry_errors
--slave-type-conversions=name
Set of slave type conversions that are enabled. If the
variable is empty, no conversions are allowed and it is
@@ -1153,7 +1187,7 @@ The following options may be given as the first argument:
ERROR_FOR_DIVISION_BY_ZERO, TRADITIONAL,
NO_AUTO_CREATE_USER, HIGH_NOT_PRECEDENCE,
NO_ENGINE_SUBSTITUTION, PAD_CHAR_TO_FULL_LENGTH,
- EMPTY_STRING_IS_NULL
+ EMPTY_STRING_IS_NULL, SIMULTANEOUS_ASSIGNMENT
--stack-trace Print a symbolic stack trace on failure
(Defaults to on; use --skip-stack-trace to disable.)
--standard-compliant-cte
@@ -1185,6 +1219,10 @@ The following options may be given as the first argument:
safe-replicable. Since 5.0, SYSDATE() returns a `dynamic'
value different for different invocations, even within
the same statement.
+ --system-versioning-alter-history=name
+ Versioning ALTER TABLE mode. ERROR: Fail ALTER with
+ error; KEEP: Keep historical system rows and subject them
+ to ALTER;
--table-cache=# Deprecated; use --table-open-cache instead.
--table-definition-cache=#
The number of cached table definitions
@@ -1377,7 +1415,6 @@ idle-transaction-timeout 0
idle-write-transaction-timeout 0
ignore-builtin-innodb FALSE
ignore-db-dirs
-in-subquery-conversion-threshold 1000
init-connect
init-file (No default value)
init-rpl-role MASTER
@@ -1477,7 +1514,7 @@ old-style-user-limits FALSE
optimizer-prune-level 1
optimizer-search-depth 62
optimizer-selectivity-sampling-limit 100
-optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
optimizer-use-condition-selectivity 1
performance-schema FALSE
performance-schema-accounts-size -1
@@ -1524,7 +1561,6 @@ performance-schema-session-connect-attrs-size -1
performance-schema-setup-actors-size 100
performance-schema-setup-objects-size 100
performance-schema-users-size -1
-plugin-maturity unknown
port 3306
port-open-timeout 0
preload-buffer-size 32768
@@ -1559,6 +1595,15 @@ report-password (No default value)
report-port 0
report-user (No default value)
rowid-merge-buff-size 8388608
+rpl-semi-sync-master-enabled FALSE
+rpl-semi-sync-master-timeout 10000
+rpl-semi-sync-master-trace-level 32
+rpl-semi-sync-master-wait-no-slave TRUE
+rpl-semi-sync-master-wait-point AFTER_COMMIT
+rpl-semi-sync-slave-delay-master FALSE
+rpl-semi-sync-slave-enabled FALSE
+rpl-semi-sync-slave-kill-conn-timeout 5
+rpl-semi-sync-slave-trace-level 32
safe-user-create FALSE
secure-auth TRUE
secure-file-priv (No default value)
@@ -1585,9 +1630,11 @@ slave-parallel-mode conservative
slave-parallel-threads 0
slave-parallel-workers 0
slave-run-triggers-for-rbr NO
-slave-skip-errors (No default value)
+slave-skip-errors OFF
slave-sql-verify-checksum TRUE
slave-transaction-retries 10
+slave-transaction-retry-errors 1213,1205
+slave-transaction-retry-interval 0
slave-type-conversions
slow-launch-time 2
slow-query-log FALSE
@@ -1604,6 +1651,7 @@ sync-master-info 10000
sync-relay-log 10000
sync-relay-log-info 10000
sysdate-is-now FALSE
+system-versioning-alter-history ERROR
table-cache 431
table-definition-cache 400
table-open-cache 431
diff --git a/mysql-test/r/mysqldump-nl.result b/mysql-test/r/mysqldump-nl.result
index db327736551..d2d0e09546b 100644
--- a/mysql-test/r/mysqldump-nl.result
+++ b/mysql-test/r/mysqldump-nl.result
@@ -124,3 +124,46 @@ v1
1v
drop database `mysqltest1
1tsetlqsym`;
+create database `test```;
+create database `test\``
+\! ls
+#`;
+show databases like 'test%';
+Database (test%)
+test
+test\`
+\! ls
+#
+test`
+
+--
+-- Current Database: `test```
+--
+
+/*!40000 DROP DATABASE IF EXISTS `test```*/;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test``` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `test```;
+
+--
+-- Current Database: `test\``
+-- \! ls
+-- #`
+--
+
+/*!40000 DROP DATABASE IF EXISTS `test\``
+\! ls
+#`*/;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test\``
+\! ls
+#` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `test\``
+\! ls
+#`;
+drop database `test```;
+drop database `test\``
+\! ls
+#`;
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 7f6107db5e4..a1e206dffd7 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -1917,7 +1917,7 @@ drop table t1, t2, t3;
# Bug#21288 mysqldump segmentation fault when using --where
#
create table t1 (a int);
-mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ * FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': 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 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064)
+mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ `a` FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': 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 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064)
mysqldump: Got 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 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1" when retrieving data from server
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
@@ -3726,7 +3726,9 @@ CREATE TEMPORARY TABLE `TABLES` (
`TABLE_COLLATION` varchar(32) DEFAULT NULL,
`CHECKSUM` bigint(21) unsigned DEFAULT NULL,
`CREATE_OPTIONS` varchar(2048) DEFAULT NULL,
- `TABLE_COMMENT` varchar(2048) NOT NULL DEFAULT ''
+ `TABLE_COMMENT` varchar(2048) NOT NULL DEFAULT '',
+ `MAX_INDEX_LENGTH` bigint(21) unsigned DEFAULT NULL,
+ `TEMPORARY` varchar(1) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
#
@@ -4780,7 +4782,7 @@ CREATE VIEW v2 AS SELECT * FROM t2;
<table_structure name="t1">
<field Field="c1" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
<field Field="c2" Type="varchar(20)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
- <options Name="t1" Engine="MyISAM" Version="10" Row_format="Dynamic" Rows="3" Avg_row_length="20" Data_length="60" Max_data_length="281474976710655" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
+ <options Name="t1" Engine="MyISAM" Version="10" Row_format="Dynamic" Rows="3" Avg_row_length="20" Data_length="60" Max_data_length="281474976710655" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" Max_index_length="17179868160" Temporary="N" />
</table_structure>
<table_data name="t1">
<row>
@@ -4798,7 +4800,7 @@ CREATE VIEW v2 AS SELECT * FROM t2;
</table_data>
<table_structure name="t2">
<field Field="c1" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
- <options Name="t2" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="3" Avg_row_length="7" Data_length="21" Max_data_length="1970324836974591" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
+ <options Name="t2" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="3" Avg_row_length="7" Data_length="21" Max_data_length="1970324836974591" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" Max_index_length="17179868160" Temporary="N" />
</table_structure>
<table_data name="t2">
<row>
@@ -4903,7 +4905,7 @@ END
<table_structure name="t1">
<field Field="c1" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
<field Field="c2" Type="varchar(20)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
- <options Name="t1" Engine="MyISAM" Version="10" Row_format="Dynamic" Rows="3" Avg_row_length="20" Data_length="60" Max_data_length="281474976710655" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
+ <options Name="t1" Engine="MyISAM" Version="10" Row_format="Dynamic" Rows="3" Avg_row_length="20" Data_length="60" Max_data_length="281474976710655" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" Max_index_length="17179868160" Temporary="N" />
</table_structure>
<!--
-
@@ -4932,7 +4934,7 @@ END
-->
<table_structure name="t2">
<field Field="c1" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
- <options Name="t2" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="3" Avg_row_length="7" Data_length="21" Max_data_length="1970324836974591" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
+ <options Name="t2" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="3" Avg_row_length="7" Data_length="21" Max_data_length="1970324836974591" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" Max_index_length="17179868160" Temporary="N" />
</table_structure>
<!--
-
@@ -5061,7 +5063,7 @@ connection conn_1;
<table_structure name="t1">
<field Field="c1" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
<field Field="c2" Type="varchar(20)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
- <options Name="t1" Engine="MyISAM" Version="10" Row_format="Dynamic" Rows="3" Avg_row_length="20" Data_length="60" Max_data_length="281474976710655" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
+ <options Name="t1" Engine="MyISAM" Version="10" Row_format="Dynamic" Rows="3" Avg_row_length="20" Data_length="60" Max_data_length="281474976710655" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" Max_index_length="17179868160" Temporary="N" />
</table_structure>
<table_data name="t1">
<row>
@@ -5079,7 +5081,7 @@ connection conn_1;
</table_data>
<table_structure name="t2">
<field Field="c1" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
- <options Name="t2" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="3" Avg_row_length="7" Data_length="21" Max_data_length="1970324836974591" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
+ <options Name="t2" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="3" Avg_row_length="7" Data_length="21" Max_data_length="1970324836974591" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" Max_index_length="17179868160" Temporary="N" />
</table_structure>
<table_data name="t2">
<row>
@@ -5646,3 +5648,183 @@ DELIMITER ;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
DROP TABLE t1;
+#
+# Test for Invisible columns
+#
+create database d;
+use d;
+# Invisble field table
+create table t1(a int , b int invisible);
+insert into t1 values(1);
+insert into t1(a,b) values(1,2);
+# not invisible field table --complete-insert wont be used
+create table t2(a int , b int);
+insert into t2(a,b) values(1,2);
+insert into t2(a,b) values(1,2);
+# Invisble field table
+create table t3(invisible int , `a b c & $!@#$%^&*( )` int invisible default 4, `ds=~!@ \# $% ^ & * ( ) _ - = +` int invisible default 5);
+insert into t3 values(1);
+insert into t3 values(5);
+insert into t3 values(2);
+insert into t3(`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +` ) values(1,2,3);
+CREATE TABLE t4(ËÃÃŒÃÎËÃ1 INT);
+insert into t4 values(1);
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) INVISIBLE DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t1` (`a`, `b`) VALUES (1,NULL),(1,2);
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t2` VALUES (1,2),(1,2);
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t3` (
+ `invisible` int(11) DEFAULT NULL,
+ `a b c & $!@#$%^&*( )` int(11) INVISIBLE DEFAULT 4,
+ `ds=~!@ \# $% ^ & * ( ) _ - = +` int(11) INVISIBLE DEFAULT 5
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t3` (`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +`) VALUES (1,4,5),(5,4,5),(2,4,5),(1,2,3);
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t4` (
+ `ËÃÃŒÃÎËÃ1` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t4` VALUES (1);
+#Check side effect on --complete insert
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) INVISIBLE DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t1` (`a`, `b`) VALUES (1,NULL),(1,2);
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t2` (`a`, `b`) VALUES (1,2),(1,2);
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t3` (
+ `invisible` int(11) DEFAULT NULL,
+ `a b c & $!@#$%^&*( )` int(11) INVISIBLE DEFAULT 4,
+ `ds=~!@ \# $% ^ & * ( ) _ - = +` int(11) INVISIBLE DEFAULT 5
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t3` (`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +`) VALUES (1,4,5),(5,4,5),(2,4,5),(1,2,3);
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t4` (
+ `ËÃÃŒÃÎËÃ1` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t4` (`ËÃÃŒÃÎËÃ1`) VALUES (1);
+#Check xml
+<?xml version="1.0"?>
+<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<database name="d">
+ <table_structure name="t1">
+ <field Field="a" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
+ <field Field="b" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="INVISIBLE" Comment="" />
+ </table_structure>
+ <table_data name="t1">
+ <row>
+ <field name="a">1</field>
+ <field name="b" xsi:nil="true" />
+ </row>
+ <row>
+ <field name="a">1</field>
+ <field name="b">2</field>
+ </row>
+ </table_data>
+ <table_structure name="t2">
+ <field Field="a" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
+ <field Field="b" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
+ </table_structure>
+ <table_data name="t2">
+ <row>
+ <field name="a">1</field>
+ <field name="b">2</field>
+ </row>
+ <row>
+ <field name="a">1</field>
+ <field name="b">2</field>
+ </row>
+ </table_data>
+ <table_structure name="t3">
+ <field Field="invisible" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
+ <field Field="a b c &amp; $!@#$%^&amp;*( )" Type="int(11)" Null="YES" Key="" Default="4" Extra="INVISIBLE" Comment="" />
+ <field Field="ds=~!@ \# $% ^ &amp; * ( ) _ - = +" Type="int(11)" Null="YES" Key="" Default="5" Extra="INVISIBLE" Comment="" />
+ </table_structure>
+ <table_data name="t3">
+ <row>
+ <field name="invisible">1</field>
+ <field name="a b c &amp; $!@#$%^&amp;*( )">4</field>
+ <field name="ds=~!@ \# $% ^ &amp; * ( ) _ - = +">5</field>
+ </row>
+ <row>
+ <field name="invisible">5</field>
+ <field name="a b c &amp; $!@#$%^&amp;*( )">4</field>
+ <field name="ds=~!@ \# $% ^ &amp; * ( ) _ - = +">5</field>
+ </row>
+ <row>
+ <field name="invisible">2</field>
+ <field name="a b c &amp; $!@#$%^&amp;*( )">4</field>
+ <field name="ds=~!@ \# $% ^ &amp; * ( ) _ - = +">5</field>
+ </row>
+ <row>
+ <field name="invisible">1</field>
+ <field name="a b c &amp; $!@#$%^&amp;*( )">2</field>
+ <field name="ds=~!@ \# $% ^ &amp; * ( ) _ - = +">3</field>
+ </row>
+ </table_data>
+ <table_structure name="t4">
+ <field Field="ËÃÃŒÃÎËÃ1" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
+ </table_structure>
+ <table_data name="t4">
+ <row>
+ <field name="ËÃÃŒÃÎËÃ1">1</field>
+ </row>
+ </table_data>
+</database>
+</mysqldump>
+DROP table t1,t2,t3;
+select * from t1;
+a
+1
+1
+select a,b from t1;
+a b
+1 NULL
+1 2
+select * from t2;
+a b
+1 2
+1 2
+select * from t3;
+invisible
+1
+5
+2
+1
+desc t3;
+Field Type Null Key Default Extra
+invisible int(11) YES NULL
+a b c & $!@#$%^&*( ) int(11) YES 4 INVISIBLE
+ds=~!@ \# $% ^ & * ( ) _ - = + int(11) YES 5 INVISIBLE
+drop database d;
diff --git a/mysql-test/r/no_password_column-mdev-11170.result b/mysql-test/r/no_password_column-mdev-11170.result
index 81eecc95558..6195100436d 100644
--- a/mysql-test/r/no_password_column-mdev-11170.result
+++ b/mysql-test/r/no_password_column-mdev-11170.result
@@ -42,6 +42,7 @@ Create_user_priv enum('N','Y') NO N
Event_priv enum('N','Y') NO N
Trigger_priv enum('N','Y') NO N
Create_tablespace_priv enum('N','Y') NO N
+Delete_history_priv enum('N','Y') NO N
ssl_type enum('','ANY','X509','SPECIFIED') NO
ssl_cipher blob NO NULL
x509_issuer blob NO NULL
diff --git a/mysql-test/r/not_windows.require b/mysql-test/r/not_windows.require
deleted file mode 100644
index 09aae1ed1d0..00000000000
--- a/mysql-test/r/not_windows.require
+++ /dev/null
@@ -1,2 +0,0 @@
-TRUE
-1
diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result
index 5495f8ffd34..ca8d71895e2 100644
--- a/mysql-test/r/openssl_1.result
+++ b/mysql-test/r/openssl_1.result
@@ -228,8 +228,4 @@ End of 5.1 tests
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
-DELIMITER ;
-# End of log file
-ROLLBACK /* added by mysqlbinlog */;
-/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
-/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
+ERROR: Failed on connect: SSL connection error \ No newline at end of file
diff --git a/mysql-test/r/opt_tvc.result b/mysql-test/r/opt_tvc.result
index 3b03bd4ffaf..0ecae5bf157 100644
--- a/mysql-test/r/opt_tvc.result
+++ b/mysql-test/r/opt_tvc.result
@@ -27,7 +27,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`a` in (1,2)
# set minimum number of values in VALUEs list when optimization works to 2
-set @@in_subquery_conversion_threshold= 2;
+set @@in_predicate_conversion_threshold= 2;
# single IN-predicate in WHERE-part
select * from t1 where a in (1,2);
a b
@@ -485,7 +485,7 @@ a b
2 5
deallocate prepare stmt;
# use inside out access from tvc rows
-set @@in_subquery_conversion_threshold= default;
+set @@in_predicate_conversion_threshold= default;
select * from t3 where a in (1,4,10);
a b
1 abc
@@ -498,7 +498,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 range idx idx 5 NULL 5 100.00 Using index condition
Warnings:
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where `test`.`t3`.`a` in (1,4,10)
-set @@in_subquery_conversion_threshold= 2;
+set @@in_predicate_conversion_threshold= 2;
select * from t3 where a in (1,4,10);
a b
1 abc
@@ -515,7 +515,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` semi join ((values (1),(4),(10)) `tvc_0`) where `test`.`t3`.`a` = `tvc_0`.`1`
# use vectors in IN predeicate
-set @@in_subquery_conversion_threshold= 4;
+set @@in_predicate_conversion_threshold= 4;
select * from t1 where (a,b) in ((1,2),(3,4));
a b
1 2
@@ -527,9 +527,9 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1,2),(3,4)) `tvc_0`) where `test`.`t1`.`a` = `tvc_0`.`1` and `test`.`t1`.`b` = `tvc_0`.`2`
-set @@in_subquery_conversion_threshold= 2;
+set @@in_predicate_conversion_threshold= 2;
# trasformation works for the one IN predicate and doesn't work for the other
-set @@in_subquery_conversion_threshold= 5;
+set @@in_predicate_conversion_threshold= 5;
select * from t2
where (a,b) in ((1,2),(8,9)) and
(a,c) in ((1,3),(8,0),(5,1));
@@ -546,7 +546,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` semi join ((values (1,3),(8,0),(5,1)) `tvc_0`) where `test`.`t2`.`a` = `tvc_0`.`1` and `test`.`t2`.`c` = `tvc_0`.`3` and (`tvc_0`.`1`,`test`.`t2`.`b`) in (<cache>((1,2)),<cache>((8,9)))
-set @@in_subquery_conversion_threshold= 2;
+set @@in_predicate_conversion_threshold= 2;
#
# mdev-14281: conversion of NOT IN predicate into subquery predicate
#
@@ -613,4 +613,46 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where !<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`c`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`c`),(`test`.`t2`.`a`,`test`.`t2`.`c`) in ( <materialize> (/* select#2 */ select `tvc_0`.`1`,`tvc_0`.`2` from (values (1,2),(8,9),(5,1)) `tvc_0` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where `test`.`t2`.`a` = `<subquery2>`.`1` and `test`.`t2`.`c` = `<subquery2>`.`2`))))
drop table t1, t2, t3;
-set @@in_subquery_conversion_threshold= default;
+set @@in_predicate_conversion_threshold= default;
+#
+# MDEV-14947: conversion of TVC with only NULL values
+#
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (3), (2), (7);
+SELECT * FROM t1 WHERE i IN (NULL, NULL, NULL, NULL, NULL);
+i
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE i IN (NULL, NULL, NULL, NULL, NULL);
+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`.`i` AS `i` from `test`.`t1` where `test`.`t1`.`i` in (NULL,NULL,NULL,NULL,NULL)
+SET in_predicate_conversion_threshold= 5;
+SELECT * FROM t1 WHERE i IN (NULL, NULL, NULL, NULL, NULL);
+i
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE i IN (NULL, NULL, NULL, NULL, NULL);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join)
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`i` AS `i` from `test`.`t1` semi join ((values (NULL),(NULL),(NULL),(NULL),(NULL)) `tvc_0`) where `test`.`t1`.`i` = `tvc_0`.`NULL`
+SET in_predicate_conversion_threshold= default;
+DROP TABLE t1;
+#
+# MDEV-14835: conversion of TVC with BIGINT or YEAR values
+#
+SET @@in_predicate_conversion_threshold= 2;
+CREATE TABLE t1 (a BIGINT);
+CREATE TABLE t2 (y YEAR);
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (2009), (2010), (2011);
+SELECT * FROM t1 WHERE a IN ('1','5','3');
+a
+1
+3
+SELECT * FROM t2 WHERE y IN ('2009','2011');
+y
+2009
+2011
+DROP TABLE t1,t2;
+SET @@in_predicate_conversion_threshold= default;
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index f43e6ce18af..e2b05ccec9e 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -2635,7 +2635,7 @@ SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2
LEFT JOIN t3 ON t2.i2 = t3.i3
ORDER BY t1.i1 LIMIT 5;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 Const row not found
1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 5 100.00 Using index
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i1 1 100.00 Using index
Warnings:
@@ -2948,6 +2948,52 @@ ORDER BY NULL, @a0 := 3, @a1 := 3, @a2 := 3, @a3 := 3, @a4 := 3,
1
1
2
+#
+# mdev-6706: semi-join with duplicate weedout + ORDER BY
+#
+CREATE TABLE t1 (f1 VARCHAR(3)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('foo');
+CREATE TABLE t2 (f2 VARCHAR(3)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('bar'),('baz');
+CREATE TABLE t3
+(i3_key INT, f3_key VARCHAR(3), f3 VARCHAR(3), KEY(f3_key,i3_key))
+ENGINE=MyISAM;
+INSERT INTO t3 VALUES (0,'qux','qux'),(8,'bar','bar');
+SELECT CONCAT( f1, f2 ) AS field FROM t1, t2
+WHERE f1 = ANY ( SELECT f1
+FROM t1
+LEFT JOIN ( t3 AS t3a, t3 AS t3b )
+ON ( t3b.f3_key = t3a.f3 )
+WHERE t3a.f3 < f1 OR t3b.f3 != f1 );
+field
+foobar
+foobaz
+SELECT CONCAT( f1, f2 ) AS field FROM t1, t2
+WHERE f1 = ANY ( SELECT f1
+FROM t1
+LEFT JOIN ( t3 AS t3a, t3 AS t3b )
+ON ( t3b.f3_key = t3a.f3 )
+WHERE t3a.f3 < f1 OR t3b.f3 != f1 )
+ORDER BY field;
+field
+foobar
+foobaz
+EXPLAIN EXTENDED SELECT CONCAT( f1, f2 ) AS field FROM t1, t2
+WHERE f1 = ANY ( SELECT f1
+FROM t1
+LEFT JOIN ( t3 AS t3a, t3 AS t3b )
+ON ( t3b.f3_key = t3a.f3 )
+WHERE t3a.f3 < f1 OR t3b.f3 != f1 )
+ORDER BY field;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00 Using temporary; Using filesort
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t3a ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary
+1 PRIMARY t3b ref f3_key f3_key 6 test.t3a.f3 1 100.00 Using where; End temporary
+Warnings:
+Note 1003 select concat('foo',`test`.`t2`.`f2`) AS `field` from `test`.`t2` semi join ((`test`.`t3` `t3a` join `test`.`t3` `t3b`)) where `test`.`t3a`.`f3` < 'foo' or `test`.`t3b`.`f3` <> 'foo' order by concat('foo',`test`.`t2`.`f2`)
+DROP TABLE t1,t2,t3;
End of 5.5 tests
#
# MDEV-5884: EXPLAIN UPDATE ... ORDER BY LIMIT shows wrong #rows
@@ -3159,3 +3205,51 @@ pk
2
3
DROP TABLE t1;
+#
+# MDEV-13994: Bad join results with orderby_uses_equalities=on
+#
+CREATE TABLE books (
+id int(16) NOT NULL AUTO_INCREMENT,
+library_id int(16) NOT NULL DEFAULT 0,
+wings_id int(12) NOT NULL DEFAULT 0,
+scheduled_for_removal int(1) DEFAULT 0,
+PRIMARY KEY (id),
+KEY library_idx (library_id)
+) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+INSERT INTO books VALUES (32625,8663,707,0),(32624,8663,505,1);
+CREATE TABLE wings (
+id int(11) NOT NULL AUTO_INCREMENT,
+department_id int(11) DEFAULT NULL,
+PRIMARY KEY (id)
+) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+INSERT INTO wings VALUES (505,11745),(707,11768);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='orderby_uses_equalities=off';
+SELECT wings.id as wing_id, wings.department_id FROM wings
+WHERE wings.id IN ( SELECT books.wings_id FROM books
+WHERE books.library_id = 8663 AND
+books.scheduled_for_removal=0 )
+ORDER BY wings.id;
+wing_id department_id
+707 11768
+SET optimizer_switch='orderby_uses_equalities=on';
+SELECT wings.id as wing_id, wings.department_id FROM wings
+WHERE wings.id IN ( SELECT books.wings_id FROM books
+WHERE books.library_id = 8663 AND
+books.scheduled_for_removal=0 )
+ORDER BY wings.id;
+wing_id department_id
+707 11768
+explain extended SELECT wings.id as wing_id, wings.department_id FROM wings
+WHERE wings.id IN ( SELECT books.wings_id FROM books
+WHERE books.library_id = 8663 AND
+books.scheduled_for_removal=0 )
+ORDER BY wings.id;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1 100.00 Using temporary; Using filesort
+1 PRIMARY wings eq_ref PRIMARY PRIMARY 4 test.books.wings_id 1 100.00
+2 MATERIALIZED books ref library_idx library_idx 4 const 1 100.00 Using where
+Warnings:
+Note 1003 select `test`.`wings`.`id` AS `wing_id`,`test`.`wings`.`department_id` AS `department_id` from `test`.`wings` semi join (`test`.`books`) where `test`.`books`.`library_id` = 8663 and `test`.`books`.`scheduled_for_removal` = 0 and `test`.`wings`.`id` = `test`.`books`.`wings_id` order by `test`.`wings`.`id`
+set optimizer_switch= @save_optimizer_switch;
+DROP TABLE books, wings;
diff --git a/mysql-test/r/order_by_innodb.result b/mysql-test/r/order_by_innodb.result
index 4f59a2f8c20..3ff1f92e94a 100644
--- a/mysql-test/r/order_by_innodb.result
+++ b/mysql-test/r/order_by_innodb.result
@@ -48,3 +48,76 @@ where key1<3 or key2<3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL # Using sort_union(key1,key2); Using where
drop table t0, t1;
+#
+# MDEV-14071: wrong results with orderby_uses_equalities=on
+# (duplicate of MDEV-13994)
+#
+CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB;
+CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB;
+CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(127,0,1),(188,0,1),(206,0,1),(218,0,1),(292,0,1),(338,0,1),(375,0,1),
+(381,0,1),(409,0,1),(466,0,1),(469,0,1),(498,0,1),(656,0,1);
+INSERT INTO t1 VALUES
+(77,4,0),(86,7,0),(96,6,0),(96,7,0),(99,9,0),(99,10,0),(99,11,0),(104,4,0),
+(106,5,0),(148,6,0),(177,6,0),(181,5,0),(188,8,0),(218,8,0),(253,7,0),
+(268,4,0),(338,4,0),(409,7,0),(466,8,0),(469,8,0),(498,8,0),(656,8,0);
+INSERT INTO t2 VALUES
+(127,7),(188,8),(188,9),(206,6),(218,8),(218,9),(292,7),(338,4),(338,5),
+(375,6),(381,5),(409,7),(409,8),(466,8),(466,9),(469,8),(469,9),(498,8),
+(498,9),(656,8),(656,9);
+INSERT INTO t3 VALUES
+(4,'four'),(5,'five'),(6,'six'),(7,'seven'),(8,'eight'),(9,'nine');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='orderby_uses_equalities=off';
+SELECT i,n
+FROM t1 INNER JOIN t2 USING (i,j) LEFT JOIN t3 USING (j)
+WHERE i IN (SELECT i FROM t1 WHERE z=1) AND z=0 ORDER BY i;
+i n
+188 eight
+218 eight
+338 four
+409 seven
+466 eight
+469 eight
+498 eight
+656 eight
+SELECT i,n
+FROM t1 x INNER JOIN t2 USING (i,j) LEFT JOIN t3 USING (j)
+WHERE EXISTS (SELECT * FROM t1 WHERE i=x.i AND z=1) AND z=0 ORDER BY i;
+i n
+188 eight
+218 eight
+338 four
+409 seven
+466 eight
+469 eight
+498 eight
+656 eight
+SET optimizer_switch='orderby_uses_equalities=on';
+SELECT i,n
+FROM t1 INNER JOIN t2 USING (i,j) LEFT JOIN t3 USING (j)
+WHERE i IN (SELECT i FROM t1 WHERE z=1) AND z=0 ORDER BY i;
+i n
+188 eight
+218 eight
+338 four
+409 seven
+466 eight
+469 eight
+498 eight
+656 eight
+SELECT i,n
+FROM t1 x INNER JOIN t2 USING (i,j) LEFT JOIN t3 USING (j)
+WHERE EXISTS (SELECT * FROM t1 WHERE i=x.i AND z=1) AND z=0 ORDER BY i;
+i n
+188 eight
+218 eight
+338 four
+409 seven
+466 eight
+469 eight
+498 eight
+656 eight
+set optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/r/outfile.result b/mysql-test/r/outfile.result
index cafa9d9db4d..4c439c37e4d 100644
--- a/mysql-test/r/outfile.result
+++ b/mysql-test/r/outfile.result
Binary files differ
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index f398ef07d56..fd76da09d78 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -513,6 +513,9 @@ COUNT(*)
SELECT SUM(c) FROM t1 WHERE b NOT IN ( 1,2,6,7,9,10,11 );
SUM(c)
400
+SELECT SUM(c+0.0) FROM t1 WHERE b NOT IN ( 1,2,6,7,9,10,11 );
+SUM(c+0.0)
+400.0
ALTER TABLE t1 DROP INDEX b;
SELECT COUNT(*) FROM t1 WHERE b NOT IN ( 1,2,6,7,9,10,11 );
COUNT(*)
@@ -1693,8 +1696,8 @@ PARTITION BY RANGE(id)
PARTITION p1 VALUES LESS THAN (20) ENGINE = MyISAM,
PARTITION p2 VALUES LESS THAN (30) ENGINE = MyISAM);
SHOW TABLE STATUS;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic 0 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Dynamic 0 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned 0 N
DROP TABLE t1;
create table t1 (a bigint unsigned)
partition by list (a)
@@ -1790,18 +1793,18 @@ drop table t1;
CREATE TABLE t1 (a int) ENGINE = MYISAM PARTITION BY KEY(a);
INSERT into t1 values (1), (2);
SHOW TABLE STATUS;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 2 7 14 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 2 7 14 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned 0 N
DELETE from t1 where a = 1;
SHOW TABLE STATUS;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 14 14 0 0 7 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 14 14 0 0 7 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned 0 N
ALTER TABLE t1 OPTIMIZE PARTITION p0;
Table Op Msg_type Msg_text
test.t1 optimize status OK
SHOW TABLE STATUS;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 7 7 0 1024 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 7 7 0 1024 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned 0 N
DROP TABLE t1;
CREATE TABLE t1 (a int, index(a)) PARTITION BY KEY(a);
ALTER TABLE t1 DISABLE KEYS;
@@ -1982,15 +1985,15 @@ create table t1(a int auto_increment, b int, primary key (b, a))
partition by hash(b) partitions 2;
insert into t1 values (null, 1);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 9 9 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 9 9 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL partitioned 0 N
drop table t1;
create table t1(a int auto_increment primary key)
partition by key(a) partitions 2;
insert into t1 values (null), (null), (null);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 3 7 21 0 0 0 4 NULL NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 3 7 21 0 0 0 4 NULL NULL NULL latin1_swedish_ci NULL partitioned 0 N
drop table t1;
CREATE TABLE t1(a INT NOT NULL, b TINYBLOB, KEY(a))
PARTITION BY RANGE(a) ( PARTITION p0 VALUES LESS THAN (32));
@@ -2634,8 +2637,19 @@ alter table t1 drop partition if exists p5;
Warnings:
Note 1507 Error in list of partitions to DROP
DROP TABLE t1;
+CREATE TABLE t1 (a INT) ENGINE=MyISAM PARTITION BY RANGE(a) (PARTITION p1 VALUES LESS THAN (0));
+ALTER TABLE t1 ADD PARTITION (PARTITION p2 VALUES LESS THAN (1));
+PREPARE stmt FROM 'ALTER TABLE t1 ADD PARTITION IF NOT EXISTS (PARTITION p2 VALUES LESS THAN (2))';
+EXECUTE stmt;
+Warnings:
+Note 1517 Duplicate partition name p2
+EXECUTE stmt;
+Warnings:
+Note 1517 Duplicate partition name p2
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
#
-# Start of 10.1 tests
+# End of 10.0 tests
#
#
# MDEV-8283 crash in get_mm_leaf with xor on binary col
diff --git a/mysql-test/r/partition_alter.result b/mysql-test/r/partition_alter.result
index 6aa0039c8d2..e42604ba056 100644
--- a/mysql-test/r/partition_alter.result
+++ b/mysql-test/r/partition_alter.result
@@ -120,3 +120,10 @@ t1 CREATE TABLE `t1` (
PARTITION `p02` ENGINE = MyISAM,
PARTITION `p03` ENGINE = MyISAM)
drop table t1;
+create or replace table t1 (x int) partition by hash (x) (partition p1, partition p2);
+lock table t1 write;
+alter table t1 add partition (partition p1);
+ERROR HY000: Duplicate partition name p1
+alter table t1 add partition (partition p1);
+ERROR HY000: Duplicate partition name p1
+drop table t1;
diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result
index 09d8728601f..d27abc07984 100644
--- a/mysql-test/r/partition_innodb.result
+++ b/mysql-test/r/partition_innodb.result
@@ -29,7 +29,7 @@ Table Op Msg_type Msg_text
test.t1 analyze status OK
EXPLAIN SELECT b FROM t1 WHERE b between 'L' and 'N' AND a > -100;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,b b 67 NULL 18 Using where; Using index
+1 SIMPLE t1 range PRIMARY,b b 67 NULL 34 Using where; Using index
DROP TABLE t1;
#
# Bug#13007154: Crash in keys_to_use_for_scanning with ORDER BY
@@ -385,34 +385,34 @@ DROP TABLE t2;
DROP TABLE t1;
create table t1 (a int) engine=innodb partition by hash(a) ;
show table status like 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB 10 Dynamic 2 8192 16384 0 0 # NULL # NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB 10 Dynamic 2 8192 16384 0 0 # NULL # NULL NULL latin1_swedish_ci NULL partitioned 0 N
drop table t1;
create table t1 (a int)
engine = innodb
partition by key (a);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB 10 Dynamic 2 8192 16384 0 0 # NULL # NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB 10 Dynamic 2 8192 16384 0 0 # NULL # NULL NULL latin1_swedish_ci NULL partitioned 0 N
insert into t1 values (0), (1), (2), (3);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB 10 Dynamic 4 4096 16384 0 0 # NULL # NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB 10 Dynamic 4 4096 16384 0 0 # NULL # NULL NULL latin1_swedish_ci NULL partitioned 0 N
drop table t1;
create table t1 (a int auto_increment primary key)
engine = innodb
partition by key (a);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB 10 Dynamic 2 8192 16384 0 0 # 1 # NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB 10 Dynamic 2 8192 16384 0 0 # 1 # NULL NULL latin1_swedish_ci NULL partitioned 0 N
insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB 10 Dynamic 4 4096 16384 0 0 # 5 # NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB 10 Dynamic 4 4096 16384 0 0 # 5 # NULL NULL latin1_swedish_ci NULL partitioned 0 N
insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB 10 Dynamic 8 2048 16384 0 0 # 9 # NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB 10 Dynamic 8 2048 16384 0 0 # 9 # NULL NULL latin1_swedish_ci NULL partitioned 0 N
drop table t1;
create table t1 (a int)
partition by key (a)
@@ -663,7 +663,7 @@ EXPLAIN SELECT * FROM t1 WHERE col1 = 1 AND col2 = 2
AND col3 BETWEEN '2013-03-08 00:00:00' AND '2013-03-12 12:00:00'
GROUP BY 1, 2, 3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge PRIMARY,col1,col2 col1,col2 8,8 NULL # Using intersect(col1,col2); Using where; Using index; Using filesort
+1 SIMPLE t1 range PRIMARY,col1,col2 PRIMARY 5 NULL # Using where; Using filesort
SELECT * FROM t1 USE INDEX () WHERE col1 = 1 AND col2 = 2
AND col3 BETWEEN '2013-03-08 00:00:00' AND '2013-03-12 12:00:00'
GROUP BY 1, 2, 3;
@@ -898,3 +898,30 @@ SELECT b FROM t1 WHERE b = 0;
ERROR HY000: Table definition has changed, please retry transaction
disconnect con1;
DROP TABLE t1;
+#
+# Bug#26390658 RENAMING A PARTITIONED TABLE DOES NOT UPDATE
+# MYSQL.INNODB_TABLE_STATS
+#
+CREATE DATABASE test_jfg;
+CREATE TABLE test_jfg.test_jfg1 (id int(10) unsigned NOT NULL,PRIMARY
+KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=1;
+CREATE TABLE test_jfg.test_jfg2 (id int(10) unsigned NOT NULL,PRIMARY
+KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=1
+PARTITION BY RANGE ( id ) (PARTITION p1000 VALUES LESS THAN (1000)
+ENGINE = InnoDB,PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE =
+InnoDB);
+SELECT database_name, table_name FROM mysql.innodb_table_stats WHERE
+database_name = 'test_jfg';
+database_name table_name
+test_jfg test_jfg1
+test_jfg test_jfg2#P#p1000
+test_jfg test_jfg2#P#pmax
+RENAME TABLE test_jfg.test_jfg1 TO test_jfg.test_jfg11;
+RENAME TABLE test_jfg.test_jfg2 TO test_jfg.test_jfg12;
+SELECT database_name, table_name FROM mysql.innodb_table_stats WHERE
+database_name = 'test_jfg';
+database_name table_name
+test_jfg test_jfg11
+test_jfg test_jfg12#P#p1000
+test_jfg test_jfg12#P#pmax
+DROP DATABASE test_jfg;
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index 0fb24b74218..422132dd1c3 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -18,7 +18,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
# # # # # # # # # 3 #
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7;
id select_type table partitions type possible_keys key key_len ref rows Extra
-# # # # # # # # # 10 #
+# # # # # # # # # 9 #
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
# # # # # # # # # 3 #
@@ -105,7 +105,7 @@ a
6
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index
SELECT * FROM t1 WHERE a <= 1;
a
-1
@@ -168,7 +168,7 @@ a
6
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index
SELECT * FROM t1 WHERE a <= 7;
a
-1
@@ -182,7 +182,7 @@ a
7
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 7;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index
SELECT * FROM t1 WHERE a = 1;
a
1
@@ -424,7 +424,7 @@ a
5
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index
SELECT * FROM t1 WHERE a <= 1;
a
-1
@@ -474,7 +474,7 @@ a
5
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index
SELECT * FROM t1 WHERE a <= 6;
a
-1
@@ -487,7 +487,7 @@ a
6
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index
SELECT * FROM t1 WHERE a = 1;
a
1
@@ -744,13 +744,13 @@ a
1001-01-01
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 Using where; Using index
+1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 4 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 pNULL,p2001-01-01 range a a 4 NULL 3 Using where; Using index
@@ -759,26 +759,26 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1001-01-01 system a NULL NULL NULL 1
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 Using where; Using index
+1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 4 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 Using where; Using index
+1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 4 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 pNULL ref a a 4 const 1 Using index
# Disabling warnings for the invalid date
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 4 Using where; Using index
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 4 Using where; Using index
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 pNULL,p2001-01-01 index a a 4 NULL 4 Using where; Using index
@@ -790,16 +790,16 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 pNULL ref a a 4 const 1 Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 4 Using where; Using index
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 index a a 4 NULL 5 Using where; Using index
+1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 index a a 4 NULL 6 Using where; Using index
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 Using where; Using index
# test without index
ALTER TABLE t1 DROP KEY a;
SELECT * FROM t1 WHERE a < '1001-01-01';
@@ -1076,7 +1076,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 3 Using where; Using index
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index
@@ -1104,10 +1104,10 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
# Disabling warnings for the invalid date
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p2001-01-01,pNULL index a a 4 NULL 4 Using where; Using index
@@ -1119,10 +1119,10 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 pNULL ref a a 4 const 1 Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 3 Using where; Using index
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 pNULL,p1001-01-01 index a a 4 NULL 4 Using where; Using index
@@ -1405,7 +1405,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 3 Using where; Using index
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index
@@ -1433,10 +1433,10 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
# Disabling warnings for the invalid date
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p2001-01-01,pNULL index a a 4 NULL 4 Using where; Using index
@@ -1448,10 +1448,10 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 pNULL ref a a 4 const 1 Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 3 Using where; Using index
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 pNULL,p1001-01-01 index a a 4 NULL 4 Using where; Using index
@@ -2867,18 +2867,18 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 510 Using where
explain partitions select * from t2 where b = 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 96
+1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76
explain extended select * from t2 where b = 6;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 ref b b 5 const 96 100.00
+1 SIMPLE t2 ref b b 5 const 76 100.00
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` = 6
explain partitions select * from t2 where b = 6;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 96
+1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76
explain extended select * from t2 where b in (1,3,5);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 ALL b NULL NULL NULL 910 51.65 Using where
+1 SIMPLE t2 ALL b NULL NULL NULL 910 40.66 Using where
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` in (1,3,5)
explain partitions select * from t2 where b in (1,3,5);
@@ -2886,7 +2886,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL b NULL NULL NULL 910 Using where
explain extended select * from t2 where b in (2,4,6);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 ALL b NULL NULL NULL 910 31.65 Using where
+1 SIMPLE t2 ALL b NULL NULL NULL 910 25.05 Using where
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` in (2,4,6)
explain partitions select * from t2 where b in (2,4,6);
@@ -2894,7 +2894,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL b NULL NULL NULL 910 Using where
explain extended select * from t2 where b in (7,8,9);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 ALL b NULL NULL NULL 910 19.12 Using where
+1 SIMPLE t2 ALL b NULL NULL NULL 910 36.70 Using where
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` in (7,8,9)
explain partitions select * from t2 where b in (7,8,9);
@@ -2902,7 +2902,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL b NULL NULL NULL 910 Using where
explain extended select * from t2 where b > 5;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 ALL b NULL NULL NULL 910 29.23 Using where
+1 SIMPLE t2 ALL b NULL NULL NULL 910 44.84 Using where
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` > 5
explain partitions select * from t2 where b > 5;
@@ -2910,7 +2910,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL b NULL NULL NULL 910 Using where
explain extended select * from t2 where b > 5 and b < 8;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 ALL b NULL NULL NULL 910 28.13 Using where
+1 SIMPLE t2 ALL b NULL NULL NULL 910 22.09 Using where
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` > 5 and `test`.`t2`.`b` < 8
explain partitions select * from t2 where b > 5 and b < 8;
@@ -2918,15 +2918,15 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL b NULL NULL NULL 910 Using where
explain extended select * from t2 where b > 5 and b < 7;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 range b b 5 NULL 96 100.00 Using where
+1 SIMPLE t2 range b b 5 NULL 76 100.00 Using where
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` > 5 and `test`.`t2`.`b` < 7
explain partitions select * from t2 where b > 5 and b < 7;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2,p3,p4 range b b 5 NULL 96 Using where
+1 SIMPLE t2 p0,p1,p2,p3,p4 range b b 5 NULL 76 Using where
explain extended select * from t2 where b > 0 and b < 5;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 ALL b NULL NULL NULL 910 53.19 Using where
+1 SIMPLE t2 ALL b NULL NULL NULL 910 41.65 Using where
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` > 0 and `test`.`t2`.`b` < 5
explain partitions select * from t2 where b > 0 and b < 5;
@@ -2960,10 +2960,10 @@ flush status;
delete from t2 where b = 7;
show status like 'Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 915
+Handler_read_rnd_next 0
show status like 'Handler_read_key';
Variable_name Value
-Handler_read_key 0
+Handler_read_key 5
flush status;
delete from t2 where b > 5;
show status like 'Handler_read_rnd_next';
@@ -3136,7 +3136,7 @@ drop table t2;
create table t1 (s1 int);
explain partitions select 1 from t1 union all select 2;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 NULL system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 NULL system NULL NULL NULL NULL 0 Const row not found
2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
drop table t1;
create table t1 (a bigint unsigned not null) partition by range(a) (
diff --git a/mysql-test/r/partition_range.result b/mysql-test/r/partition_range.result
index dd9e074db0c..7ae029d488c 100644
--- a/mysql-test/r/partition_range.result
+++ b/mysql-test/r/partition_range.result
@@ -961,7 +961,7 @@ INSERT INTO t2 SELECT * FROM t1;
# plans should be identical
EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index for group-by
+1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index
EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by
@@ -972,7 +972,7 @@ a MAX(b)
# Should be no more than 4 reads.
SHOW status LIKE 'handler_read_key';
Variable_name Value
-Handler_read_key 4
+Handler_read_key 2
FLUSH status;
SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a;
a MAX(b)
diff --git a/mysql-test/r/partition_windows.result b/mysql-test/r/partition_windows.result
index dabcedcb3f9..756690925f8 100644
--- a/mysql-test/r/partition_windows.result
+++ b/mysql-test/r/partition_windows.result
@@ -26,9 +26,5 @@ ALTER TABLE t1 ADD PARTITION (PARTITION p3 DATA DIRECTORY = 'G:/mysqltest/p3Data
Warnings:
Warning 1618 <DATA DIRECTORY> option ignored
Warning 1618 <INDEX DIRECTORY> option ignored
-Warning 1618 <DATA DIRECTORY> option ignored
-Warning 1618 <INDEX DIRECTORY> option ignored
-Warning 1618 <DATA DIRECTORY> option ignored
-Warning 1618 <INDEX DIRECTORY> option ignored
INSERT INTO t1 VALUES (NULL, "last", 4);
DROP TABLE t1;
diff --git a/mysql-test/r/profiling.result b/mysql-test/r/profiling.result
index 9644a8afe8d..6590d89bc89 100644
--- a/mysql-test/r/profiling.result
+++ b/mysql-test/r/profiling.result
@@ -415,7 +415,7 @@ select @@profiling;
drop table if exists t1, t2, t3;
drop view if exists v1;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
drop function if exists f1;
set session profiling = OFF;
set global profiling_history_size= @start_value;
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index ba52176e3bd..45e3f60e431 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -218,11 +218,11 @@ drop table t1;
create table t1 ( a int primary key, b varchar(30)) engine = MYISAM ;
prepare stmt1 from ' show table status from test like ''t1%'' ';
execute stmt1;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic 0 0 0 4294967295 1024 0 NULL # # # latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Dynamic 0 0 0 4294967295 1024 0 NULL # # # latin1_swedish_ci NULL 288230376151710720 N
show table status from test like 't1%' ;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic 0 0 0 4294967295 1024 0 NULL # # # latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Dynamic 0 0 0 4294967295 1024 0 NULL # # # latin1_swedish_ci NULL 288230376151710720 N
deallocate prepare stmt1 ;
drop table t1;
create table t1(a varchar(2), b varchar(3));
@@ -1207,22 +1207,25 @@ SET @aux= "SELECT COUNT(*)
prepare my_stmt from @aux;
execute my_stmt;
COUNT(*)
-46
+47
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
execute my_stmt;
COUNT(*)
-46
+47
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
execute my_stmt;
COUNT(*)
-46
+47
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
deallocate prepare my_stmt;
drop procedure if exists p1|
drop table if exists t1|
@@ -1738,7 +1741,7 @@ execute stmt using @a;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `?` decimal(2,1) DEFAULT NULL
+ `?` decimal(2,1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
drop table if exists t1;
@@ -3388,7 +3391,7 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1;
SHOW CREATE TABLE tmp1;
Table Create Table
tmp1 CREATE TEMPORARY TABLE `tmp1` (
- `c1` bigint(20) DEFAULT NULL
+ `c1` bigint(20) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT @a, @a = b'10100100101';
@a @a = b'10100100101'
@@ -3478,7 +3481,7 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1;
SHOW CREATE TABLE tmp1;
Table Create Table
tmp1 CREATE TEMPORARY TABLE `tmp1` (
- `c1` bigint(20) DEFAULT NULL
+ `c1` bigint(20) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT @a, @a = 2010;
@a @a = 2010
@@ -3550,7 +3553,7 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1;
SHOW CREATE TABLE tmp1;
Table Create Table
tmp1 CREATE TEMPORARY TABLE `tmp1` (
- `c1` longblob DEFAULT NULL
+ `c1` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT @a, @a = REPEAT('a', 16);
@a @a = REPEAT('a', 16)
@@ -3568,7 +3571,7 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1;
SHOW CREATE TABLE tmp1;
Table Create Table
tmp1 CREATE TEMPORARY TABLE `tmp1` (
- `c1` longblob DEFAULT NULL
+ `c1` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT @a, @a = REPEAT('b', 16);
@a @a = REPEAT('b', 16)
@@ -3586,7 +3589,7 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1;
SHOW CREATE TABLE tmp1;
Table Create Table
tmp1 CREATE TEMPORARY TABLE `tmp1` (
- `c1` longblob DEFAULT NULL
+ `c1` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT @a, @a = REPEAT('c', 16);
@a @a = REPEAT('c', 16)
@@ -3604,7 +3607,7 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1;
SHOW CREATE TABLE tmp1;
Table Create Table
tmp1 CREATE TEMPORARY TABLE `tmp1` (
- `c1` longblob DEFAULT NULL
+ `c1` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT @a, @a = REPEAT('d', 16);
@a @a = REPEAT('d', 16)
@@ -3622,7 +3625,7 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1;
SHOW CREATE TABLE tmp1;
Table Create Table
tmp1 CREATE TEMPORARY TABLE `tmp1` (
- `c1` longblob DEFAULT NULL
+ `c1` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT @a, @a = REPEAT('e', 16);
@a @a = REPEAT('e', 16)
@@ -3640,7 +3643,7 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1;
SHOW CREATE TABLE tmp1;
Table Create Table
tmp1 CREATE TEMPORARY TABLE `tmp1` (
- `c1` longblob DEFAULT NULL
+ `c1` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT @a, @a = REPEAT('f', 16);
@a @a = REPEAT('f', 16)
@@ -3766,7 +3769,7 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1;
SHOW CREATE TABLE tmp1;
Table Create Table
tmp1 CREATE TEMPORARY TABLE `tmp1` (
- `c1` longblob DEFAULT NULL
+ `c1` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT @a, @a = 'aaa';
@a @a = 'aaa'
@@ -3784,7 +3787,7 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1;
SHOW CREATE TABLE tmp1;
Table Create Table
tmp1 CREATE TEMPORARY TABLE `tmp1` (
- `c1` longblob DEFAULT NULL
+ `c1` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT @a, @a = 'aaa';
@a @a = 'aaa'
@@ -4345,6 +4348,24 @@ set join_cache_level=@join_cache_level_save;
deallocate prepare stmt;
drop view v1,v2,v3;
drop table t1,t2,t3;
+#
+# MDEV-10657: incorrect result returned with binary protocol
+# (prepared statements)
+#
+create table t1 (code varchar(10) primary key);
+INSERT INTO t1(code) VALUES ('LINE1'), ('LINE2'), ('LINE3');
+SELECT X.*
+FROM
+(SELECT CODE, RN
+FROM
+(SELECT A.CODE, @cnt := @cnt + 1 AS RN
+FROM t1 A, (SELECT @cnt := 0) C) T
+) X;
+CODE RN
+LINE1 1
+LINE2 2
+LINE3 3
+drop table t1;
# End of 5.5 tests
#
# Start of 10.2 tests
@@ -4407,14 +4428,14 @@ EXECUTE stmt USING 10;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `c1` bigint(21) NOT NULL
+ `c1` int(2) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
EXECUTE stmt USING 10.123;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `c1` decimal(5,3) DEFAULT NULL
+ `c1` decimal(5,3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
EXECUTE stmt USING 10.123e0;
@@ -4428,49 +4449,49 @@ EXECUTE stmt USING CURRENT_DATE;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `c1` date DEFAULT NULL
+ `c1` date NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
EXECUTE stmt USING CURRENT_TIMESTAMP;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `c1` datetime DEFAULT NULL
+ `c1` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
EXECUTE stmt USING CURRENT_TIMESTAMP(3);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `c1` datetime(3) DEFAULT NULL
+ `c1` datetime(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
EXECUTE stmt USING CURRENT_TIMESTAMP(6);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `c1` datetime(6) DEFAULT NULL
+ `c1` datetime(6) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
EXECUTE stmt USING CURRENT_TIME;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `c1` time DEFAULT NULL
+ `c1` time NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
EXECUTE stmt USING CURRENT_TIME(3);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `c1` time(3) DEFAULT NULL
+ `c1` time(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
EXECUTE stmt USING CURRENT_TIME(6);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `c1` time(6) DEFAULT NULL
+ `c1` time(6) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
DEALLOCATE PREPARE stmt;
@@ -4614,10 +4635,10 @@ EXECUTE IMMEDIATE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(21) NOT NULL,
- `b` decimal(3,1) DEFAULT NULL,
+ `a` bigint(20) NOT NULL,
+ `b` decimal(3,1) NOT NULL,
`c` double NOT NULL,
- `d` varchar(3) NOT NULL
+ `d` tinytext NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
EXECUTE IMMEDIATE
@@ -4626,8 +4647,8 @@ EXECUTE IMMEDIATE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(21) NOT NULL,
- `b` decimal(3,1) DEFAULT NULL,
+ `a` int(2) NOT NULL,
+ `b` decimal(3,1) NOT NULL,
`c` double NOT NULL,
`d` varchar(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
@@ -4642,11 +4663,11 @@ TIMESTAMP'2001-01-01 10:20:30.123';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `t1` time DEFAULT NULL,
- `t2` time(3) DEFAULT NULL,
- `d1` date DEFAULT NULL,
- `dt1` datetime DEFAULT NULL,
- `dt2` datetime(3) DEFAULT NULL
+ `t1` time NOT NULL,
+ `t2` time(3) NOT NULL,
+ `d1` date NOT NULL,
+ `dt1` datetime NOT NULL,
+ `dt2` datetime(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
#
@@ -4992,3 +5013,230 @@ ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NE
EXECUTE IMMEDIATE 'CALL p1(?)' USING IGNORE;
ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
DROP PROCEDURE p1;
+#
+# MDEV-14434 Wrong result for CHARSET(CONCAT(?,const))
+#
+SET NAMES utf8;
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(5,_latin1'a'))";
+CHARSET(CONCAT(5,_latin1'a'))
+latin1
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(?,_latin1'a'))" USING 5;
+CHARSET(CONCAT(?,_latin1'a'))
+latin1
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(?,_latin1'a'))" USING 5.5;
+CHARSET(CONCAT(?,_latin1'a'))
+latin1
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(?,_latin1'a'))" USING 5.5e0;
+CHARSET(CONCAT(?,_latin1'a'))
+latin1
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(?,_latin1'a'))" USING TIME'10:20:30';
+CHARSET(CONCAT(?,_latin1'a'))
+latin1
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(?,_latin1'a'))" USING TIMESTAMP'2001-01-01 10:20:30';
+CHARSET(CONCAT(?,_latin1'a'))
+latin1
+EXECUTE IMMEDIATE "SELECT COERCIBILITY(?)" USING 5;
+COERCIBILITY(?)
+5
+EXECUTE IMMEDIATE "SELECT COERCIBILITY(?)" USING 5.5;
+COERCIBILITY(?)
+5
+EXECUTE IMMEDIATE "SELECT COERCIBILITY(?)" USING 5.5e0;
+COERCIBILITY(?)
+5
+EXECUTE IMMEDIATE "SELECT COERCIBILITY(?)" USING TIME'10:20:30';
+COERCIBILITY(?)
+5
+EXECUTE IMMEDIATE "SELECT COERCIBILITY(?)" USING TIMESTAMP'2001-01-01 10:20:30';
+COERCIBILITY(?)
+5
+#
+# MDEV-14435 Different UNSIGNED flag of out user variable for YEAR parameter for direct vs prepared CALL
+#
+CREATE PROCEDURE p1(OUT v INT UNSIGNED) SET v = 2010;
+CALL p1(@a);
+PREPARE stmt FROM 'CALL p1(?)';
+EXECUTE stmt USING @b;
+DEALLOCATE PREPARE stmt;
+CREATE TABLE t1 AS SELECT @a AS a, @b AS b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) unsigned DEFAULT NULL,
+ `b` bigint(20) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(OUT v YEAR) SET v = 2010;
+CALL p1(@a);
+PREPARE stmt FROM 'CALL p1(?)';
+EXECUTE stmt USING @b;
+DEALLOCATE PREPARE stmt;
+CREATE TABLE t1 AS SELECT @a AS a, @b AS b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) unsigned DEFAULT NULL,
+ `b` bigint(20) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(OUT v BIT(16)) SET v = 2010;
+CALL p1(@a);
+PREPARE stmt FROM 'CALL p1(?)';
+EXECUTE stmt USING @b;
+DEALLOCATE PREPARE stmt;
+CREATE TABLE t1 AS SELECT @a AS a, @b AS b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) unsigned DEFAULT NULL,
+ `b` bigint(20) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+DROP PROCEDURE p1;
+#
+# MDEV-14426 Assertion in Diagnostics_area::set_error_status when using a bad datetime with PS and SP
+#
+CREATE PROCEDURE p1(OUT a VARCHAR(20))
+BEGIN
+SET a=10;
+END;
+$$
+BEGIN NOT ATOMIC
+DECLARE a DATETIME;
+CALL p1(a);
+END;
+$$
+ERROR 22007: Incorrect datetime value: '10' for column 'a' at row 1
+BEGIN NOT ATOMIC
+DECLARE a DATETIME;
+EXECUTE IMMEDIATE 'CALL p1(?)' USING a;
+END;
+$$
+ERROR 22007: Incorrect datetime value: '10' for column 'a' at row 1
+BEGIN NOT ATOMIC
+DECLARE a DATETIME;
+PREPARE stmt FROM 'CALL p1(?)';
+EXECUTE stmt USING a;
+DEALLOCATE PREPARE stmt;
+END;
+$$
+ERROR 22007: Incorrect datetime value: '10' for column 'a' at row 1
+DROP PROCEDURE p1;
+#
+# MDEV-14454 Binary protocol returns wrong collation ID for SP OUT parameters
+#
+CREATE PROCEDURE p1(OUT v CHAR(32) CHARACTER SET utf8) SET v='aaa';
+PREPARE stmt1 FROM 'CALL p1(?)';
+EXECUTE stmt1 USING @a;
+CREATE TABLE t1 AS SELECT @a AS c1;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` longtext CHARACTER SET utf8 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+DROP PROCEDURE p1;
+#
+# MDEV-14467 Item_param: replace {INT|DECIMAL|REAL|STRING|TIME}_VALUE with Type_handler
+#
+EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT 1 FROM DUAL LIMIT ?' USING 10;
+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 1 AS `1` limit 10
+EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT 1 FROM DUAL LIMIT ?' USING 10.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 1 AS `1` limit 10
+EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT 1 FROM DUAL LIMIT ?' USING 10.1e0;
+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 1 AS `1` limit 10
+EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT 1 FROM DUAL LIMIT ?' USING '10';
+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 1 AS `1` limit 10
+EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT 1 FROM DUAL LIMIT ?' USING TIME'10:10:10';
+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 1 AS `1` limit 101010
+EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 AS SELECT 1 AS a,? AS b' USING 1;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL,
+ `b` int(1) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 AS SELECT 10 AS a,? AS b' USING 10;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(2) NOT NULL,
+ `b` int(2) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 AS SELECT 999999999 AS a,? AS b' USING 999999999;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(9) NOT NULL,
+ `b` int(9) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 AS SELECT 2147483647 AS a,? AS b' USING 2147483647;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(10) NOT NULL,
+ `b` bigint(10) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
+# MDEV-14603 signal 11 with short stacktrace
+#
+SET NAMES utf8;
+CREATE TABLE t1(i INT);
+CREATE PROCEDURE p1(tn VARCHAR(32))
+EXECUTE IMMEDIATE CONCAT('ANALYZE TABLE ',tn);
+CALL p1('t1');
+Table Op Msg_type Msg_text
+test.t1 analyze status Table is already up to date
+DROP PROCEDURE p1;
+DROP TABLE t1;
+SET NAMES utf8;
+CREATE PROCEDURE p1()
+EXECUTE IMMEDIATE CONCAT('SELECT ',CONVERT(RAND() USING latin1));
+CALL p1();
+DROP PROCEDURE p1;
+SET NAMES utf8;
+CREATE PROCEDURE p1()
+BEGIN
+PREPARE stmt FROM CONCAT('SELECT ',CONVERT(RAND() USING latin1));
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+END;
+$$
+CALL p1();
+DROP PROCEDURE p1;
+SET NAMES utf8;
+CREATE PROCEDURE p1(a VARCHAR(10) CHARACTER SET utf8)
+EXECUTE IMMEDIATE 'SELECT ?' USING CONCAT(a, CONVERT(RAND() USING latin1));
+CALL p1('x');
+DROP PROCEDURE p1;
+SET NAMES utf8;
+CREATE PROCEDURE p1(a VARCHAR(10) CHARACTER SET utf8)
+BEGIN
+PREPARE stmt FROM 'SELECT ?';
+EXECUTE stmt USING CONCAT(a, CONVERT(RAND() USING latin1));
+DEALLOCATE PREPARE stmt;
+END;
+$$
+CALL p1('x');
+DROP PROCEDURE p1;
diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result
index fef15b89f26..035372a1359 100644
--- a/mysql-test/r/ps_1general.result
+++ b/mysql-test/r/ps_1general.result
@@ -296,12 +296,12 @@ t2 0 PRIMARY 1 a A 0 NULL NULL BTREE
t2 1 t2_idx 1 b A NULL NULL NULL YES BTREE
prepare stmt4 from ' show table status from test like ''t2%'' ';
execute stmt4;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t2 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # # latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t2 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # # latin1_swedish_ci NULL # N
prepare stmt4 from ' show table status from test like ''t9%'' ';
execute stmt4;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t9 MyISAM 10 Dynamic 2 212 424 # 2048 0 NULL # # # latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t9 MyISAM 10 Dynamic 2 212 424 # 2048 0 NULL # # # latin1_swedish_ci NULL # N
prepare stmt4 from ' show status like ''Threads_running'' ';
execute stmt4;
Variable_name Value
diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result
index e69c6e06193..68acf50aee1 100644
--- a/mysql-test/r/ps_ddl.result
+++ b/mysql-test/r/ps_ddl.result
@@ -2370,11 +2370,11 @@ drop table if exists t1;
create table t1 (a int);
prepare stmt from "show table status where (1) in (select * from t1)";
execute stmt;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
drop table t1;
create table t1 (x int);
execute stmt;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
drop table t1;
deallocate prepare stmt;
#
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index eb9b1d16011..bb8703b4185 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -235,7 +235,7 @@ select benchmark(1,1) from t1;
benchmark(1,1)
explain extended select benchmark(1,1) from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select benchmark(1,1) AS `benchmark(1,1)` from `test`.`t1`
show status like "Qcache_queries_in_cache";
diff --git a/mysql-test/r/query_cache_debug.result b/mysql-test/r/query_cache_debug.result
index afc1eb3d135..2a54f073974 100644
--- a/mysql-test/r/query_cache_debug.result
+++ b/mysql-test/r/query_cache_debug.result
@@ -248,3 +248,39 @@ RESET QUERY CACHE;
DROP TABLE t1;
SET GLOBAL query_cache_size= DEFAULT;
SET GLOBAL query_cache_type= DEFAULT;
+#
+# MDEV-14526: MariaDB keeps crashing under load when
+# query_cache_type is changed
+#
+CREATE TABLE t1 (
+`id` int(10) NOT NULL AUTO_INCREMENT,
+`k` int(10) default '0',
+PRIMARY KEY (`id`))
+ENGINE=MyISAM;
+INSERT IGNORE INTO t1 VALUES
+(NULL,1),(NULL,8),(NULL,NULL),(NULL,NULL),(NULL,4),(NULL,9),(NULL,7),
+(NULL,3),(NULL,NULL),(NULL,2),(NULL,3),(NULL,NULL),(NULL,2),(NULL,7),
+(NULL,1),(NULL,2),(NULL,4),(NULL,NULL),(NULL,1),(NULL,1),(NULL,4);
+SET GLOBAL query_cache_size= 1024*1024;
+SET GLOBAL query_cache_type= 1;
+connect con2,localhost,root,,test;
+connect con1,localhost,root,,test;
+set debug_sync="wait_in_query_cache_store_query SIGNAL parked WAIT_FOR go";
+SELECT DISTINCT id FROM t1 WHERE id BETWEEN 5603 AND 16218 ORDER BY k;
+connection default;
+set debug_sync="now WAIT_FOR parked";
+connection con2;
+SET GLOBAL query_cache_type= 0;
+connection default;
+set debug_sync="now SIGNAL go";
+connection con1;
+id
+connection con2;
+disconnect con1;
+disconnect con2;
+connection default;
+set debug_sync= 'RESET';
+DROP TABLE t1;
+SEt GLOBAL query_cache_size= DEFAULT;
+SEt GLOBAL query_cache_type= DEFAULT;
+# End of 5.5 tests
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 80aef096828..e2996b963bc 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1,5 +1,3 @@
-set in_subquery_conversion_threshold=10000;
-drop table if exists t1, t2, t3, t10, t100;
CREATE TABLE t1 (
event_date date DEFAULT '0000-00-00' NOT NULL,
type int(11) DEFAULT '0' NOT NULL,
@@ -1064,7 +1062,9 @@ set @b= concat("explain ", @a);
prepare stmt1 from @b;
execute stmt1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 index a a 5 NULL 1003 Using where; Using index
+1 PRIMARY t2 index NULL a 5 NULL 1003 Using where; Using index
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
prepare stmt1 from @a;
execute stmt1;
a
@@ -2284,7 +2284,7 @@ explain extended select * from t2 where (b > 25 and b < 15) or (a>55 and a<44);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where 0
+Note 1003 select 44 AS `a`,15 AS `b`,NULL AS `c` from `test`.`t2` where 0
drop table t1,t2;
#
# Start of 10.1 tests
@@ -3007,4 +3007,3 @@ drop table t1,t2,t3;
#
# End of 10.2 tests
#
-set in_subquery_conversion_threshold=default;
diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result
index b0672eed54e..629d183bee7 100644
--- a/mysql-test/r/range_mrr_icp.result
+++ b/mysql-test/r/range_mrr_icp.result
@@ -1,7 +1,5 @@
set @mrr_icp_extra_tmp=@@optimizer_switch;
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
-set in_subquery_conversion_threshold=10000;
-drop table if exists t1, t2, t3, t10, t100;
CREATE TABLE t1 (
event_date date DEFAULT '0000-00-00' NOT NULL,
type int(11) DEFAULT '0' NOT NULL,
@@ -1066,7 +1064,9 @@ set @b= concat("explain ", @a);
prepare stmt1 from @b;
execute stmt1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 index a a 5 NULL 1003 Using where; Using index
+1 PRIMARY t2 index NULL a 5 NULL 1003 Using where; Using index
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
prepare stmt1 from @a;
execute stmt1;
a
@@ -2286,7 +2286,7 @@ explain extended select * from t2 where (b > 25 and b < 15) or (a>55 and a<44);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where 0
+Note 1003 select 44 AS `a`,15 AS `b`,NULL AS `c` from `test`.`t2` where 0
drop table t1,t2;
#
# Start of 10.1 tests
@@ -3019,5 +3019,4 @@ drop table t1,t2,t3;
#
# End of 10.2 tests
#
-set in_subquery_conversion_threshold=default;
set optimizer_switch=@mrr_icp_extra_tmp;
diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result
index 79ee0c7a9b8..75d7525ee71 100644
--- a/mysql-test/r/repair.result
+++ b/mysql-test/r/repair.result
@@ -114,11 +114,11 @@ test.t1 repair status OK
SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
DROP TABLE t1;
-End of 4.1 tests
+# End of 4.1 tests
# Test with a saved table from 4.1
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 9 Fixed 2 5 10 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 9 Fixed 2 5 10 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL 17179868160 N
SELECT * FROM t1;
id
1
@@ -137,8 +137,8 @@ REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 1 7 7 1970324836974591 1024 0 NULL # # NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 1 7 7 1970324836974591 1024 0 NULL # # NULL latin1_swedish_ci NULL 17179868160 N
SELECT * FROM t1;
id
1
@@ -150,6 +150,7 @@ SELECT * FROM t1;
id
1
DROP TABLE t1;
+# End of 5.0 tests
DROP TABLE IF EXISTS tt1;
CREATE TEMPORARY TABLE tt1 (c1 INT);
REPAIR TABLE tt1 USE_FRM;
@@ -214,3 +215,17 @@ Table Op Msg_type Msg_text
test.v1 repair status OK
drop view v1;
drop table t1;
+# End of 5.5 tests
+CREATE TABLE t1 (i INT) ENGINE=MyISAM;
+INSERT t1 VALUES (1);
+LOCK TABLE t1 WRITE;
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+SELECT * FROM INFORMATION_SCHEMA.TABLES;
+SELECT * FROM t1;
+i
+1
+UNLOCK TABLES;
+DROP TABLE t1;
+# End of 10.0 tests
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index c7156ddae91..9b6a570717b 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -2330,7 +2330,7 @@ insert into t4 values (1,1);
explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t3 system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t4 const id4 NULL NULL NULL 1
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where
@@ -2655,9 +2655,9 @@ create table t1 (f1 int not null auto_increment primary key, f2 varchar(10));
create table t11 like t1;
insert into t1 values(1,""),(2,"");
show table status like 't1%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic 2 20 X X X X X X X X latin1_swedish_ci NULL
-t11 MyISAM 10 Dynamic 0 0 X X X X X X X X latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Dynamic 2 20 X X X X X X X X latin1_swedish_ci NULL X N
+t11 MyISAM 10 Dynamic 0 0 X X X X X X X X latin1_swedish_ci NULL X N
select 123 as a from t1 where f1 is null;
a
drop table t1,t11;
@@ -4660,17 +4660,17 @@ DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL);
EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND c=c) OR b > 20;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a AND b=b) OR b > 20;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND a=a) OR b > 20;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
DROP TABLE t1;
@@ -5482,7 +5482,7 @@ WHERE i1 = i2 AND ( FALSE OR ( j1 > 27 AND j1 < 100 OR j1 <= 3 ) AND j1 = i2 );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select 1 AS `i1`,8 AS `j1`,`test`.`t2`.`i2` AS `i2` from `test`.`t2` where 0
+Note 1003 select 1 AS `i1`,8 AS `j1`,NULL AS `i2` from `test`.`t2` where 0
SELECT * FROM t1, t2
WHERE i1 = i2 AND ( FALSE OR ( j1 > 27 AND j1 < 100 OR j1 <= 3 ) AND j1 = i2 );
i1 j1 i2
diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result
index 8462e19fda8..2c37c2d28d8 100644
--- a/mysql-test/r/select_found.result
+++ b/mysql-test/r/select_found.result
@@ -83,7 +83,7 @@ UNIQUE KEY e_n (email,name)
);
EXPLAIN SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 system PRIMARY,kid NULL NULL NULL 0 const row not found; Using temporary
+1 SIMPLE t1 system PRIMARY,kid NULL NULL NULL 0 Const row not found; Using temporary
1 SIMPLE t2 ALL NULL NULL NULL NULL 200
SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
email
diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result
index 92be057c62c..d78fad15da1 100644
--- a/mysql-test/r/select_jcl6.result
+++ b/mysql-test/r/select_jcl6.result
@@ -2341,7 +2341,7 @@ insert into t4 values (1,1);
explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t3 system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t4 const id4 NULL NULL NULL 1
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
1 SIMPLE t2 hash_ALL NULL #hash#$hj 4 test.t1.id1 1 Using where; Using join buffer (flat, BNLH join)
@@ -2666,9 +2666,9 @@ create table t1 (f1 int not null auto_increment primary key, f2 varchar(10));
create table t11 like t1;
insert into t1 values(1,""),(2,"");
show table status like 't1%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic 2 20 X X X X X X X X latin1_swedish_ci NULL
-t11 MyISAM 10 Dynamic 0 0 X X X X X X X X latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Dynamic 2 20 X X X X X X X X latin1_swedish_ci NULL X N
+t11 MyISAM 10 Dynamic 0 0 X X X X X X X X latin1_swedish_ci NULL X N
select 123 as a from t1 where f1 is null;
a
drop table t1,t11;
@@ -4671,17 +4671,17 @@ DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL);
EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND c=c) OR b > 20;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a AND b=b) OR b > 20;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND a=a) OR b > 20;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
DROP TABLE t1;
@@ -5493,7 +5493,7 @@ WHERE i1 = i2 AND ( FALSE OR ( j1 > 27 AND j1 < 100 OR j1 <= 3 ) AND j1 = i2 );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select 1 AS `i1`,8 AS `j1`,`test`.`t2`.`i2` AS `i2` from `test`.`t2` where 0
+Note 1003 select 1 AS `i1`,8 AS `j1`,NULL AS `i2` from `test`.`t2` where 0
SELECT * FROM t1, t2
WHERE i1 = i2 AND ( FALSE OR ( j1 > 27 AND j1 < 100 OR j1 <= 3 ) AND j1 = i2 );
i1 j1 i2
diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result
index c7156ddae91..9b6a570717b 100644
--- a/mysql-test/r/select_pkeycache.result
+++ b/mysql-test/r/select_pkeycache.result
@@ -2330,7 +2330,7 @@ insert into t4 values (1,1);
explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t3 system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t4 const id4 NULL NULL NULL 1
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where
@@ -2655,9 +2655,9 @@ create table t1 (f1 int not null auto_increment primary key, f2 varchar(10));
create table t11 like t1;
insert into t1 values(1,""),(2,"");
show table status like 't1%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Dynamic 2 20 X X X X X X X X latin1_swedish_ci NULL
-t11 MyISAM 10 Dynamic 0 0 X X X X X X X X latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Dynamic 2 20 X X X X X X X X latin1_swedish_ci NULL X N
+t11 MyISAM 10 Dynamic 0 0 X X X X X X X X latin1_swedish_ci NULL X N
select 123 as a from t1 where f1 is null;
a
drop table t1,t11;
@@ -4660,17 +4660,17 @@ DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL);
EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND c=c) OR b > 20;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a AND b=b) OR b > 20;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND a=a) OR b > 20;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1
DROP TABLE t1;
@@ -5482,7 +5482,7 @@ WHERE i1 = i2 AND ( FALSE OR ( j1 > 27 AND j1 < 100 OR j1 <= 3 ) AND j1 = i2 );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select 1 AS `i1`,8 AS `j1`,`test`.`t2`.`i2` AS `i2` from `test`.`t2` where 0
+Note 1003 select 1 AS `i1`,8 AS `j1`,NULL AS `i2` from `test`.`t2` where 0
SELECT * FROM t1, t2
WHERE i1 = i2 AND ( FALSE OR ( j1 > 27 AND j1 < 100 OR j1 <= 3 ) AND j1 = i2 );
i1 j1 i2
diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result
index 7400dff3958..9cb6ee3e9bf 100644
--- a/mysql-test/r/selectivity.result
+++ b/mysql-test/r/selectivity.result
@@ -141,7 +141,7 @@ order by s_suppkey;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using filesort
1 PRIMARY <derived3> ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where
-3 LATERAL DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 268 75.00 Using where
+3 DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 268 100.00 Using where; Using temporary; Using filesort
2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 268 100.00
4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 268 100.00 Using where; Using temporary; Using filesort
Warnings:
@@ -162,7 +162,7 @@ order by s_suppkey;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using filesort
1 PRIMARY <derived3> ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where
-3 LATERAL DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 268 100.00 Using where
+3 DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 268 100.00 Using where; Using temporary; Using filesort
2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 268 100.00
4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 268 100.00 Using where; Using temporary; Using filesort
Warnings:
@@ -784,7 +784,7 @@ select * from t1 where a < 1 and a > 7;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0
+Note 1003 select 7 AS `a` from `test`.`t1` where 0
select * from t1 where a < 1 and a > 7;
a
drop table t1;
@@ -1508,7 +1508,7 @@ select * from t2 where col1 < 'b' and col1 > 'd';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select `test`.`t2`.`col1` AS `col1` from `test`.`t2` where 0
+Note 1003 select 'd' AS `col1` from `test`.`t2` where 0
drop table t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result
index 960a873c854..236647c6091 100644
--- a/mysql-test/r/selectivity_innodb.result
+++ b/mysql-test/r/selectivity_innodb.result
@@ -144,7 +144,7 @@ order by s_suppkey;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY supplier index PRIMARY PRIMARY 4 NULL 10 100.00
1 PRIMARY <derived3> ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where
-3 LATERAL DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 229 75.11 Using where
+3 DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 229 100.00 Using where; Using temporary; Using filesort
2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 229 100.00
4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 229 100.00 Using where; Using temporary; Using filesort
Warnings:
@@ -165,7 +165,7 @@ order by s_suppkey;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY supplier index PRIMARY PRIMARY 4 NULL 10 100.00
1 PRIMARY <derived3> ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where
-3 LATERAL DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 229 100.00 Using where
+3 DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 229 100.00 Using where; Using temporary; Using filesort
2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 228 100.00
4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 229 100.00 Using where; Using temporary; Using filesort
Warnings:
@@ -791,7 +791,7 @@ select * from t1 where a < 1 and a > 7;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0
+Note 1003 select 7 AS `a` from `test`.`t1` where 0
select * from t1 where a < 1 and a > 7;
a
drop table t1;
@@ -1518,7 +1518,7 @@ select * from t2 where col1 < 'b' and col1 > 'd';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select `test`.`t2`.`col1` AS `col1` from `test`.`t2` where 0
+Note 1003 select 'd' AS `col1` from `test`.`t2` where 0
drop table t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
diff --git a/mysql-test/r/show_bad_definer-5553.result b/mysql-test/r/show_bad_definer-5553.result
index a1b8c6a7410..173c88bd196 100644
--- a/mysql-test/r/show_bad_definer-5553.result
+++ b/mysql-test/r/show_bad_definer-5553.result
@@ -5,9 +5,9 @@ create definer=unknownuser@'%' sql security definer view v1 as select t1.id from
Warnings:
Note 1449 The user specified as a definer ('unknownuser'@'%') does not exist
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
-v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL VIEW
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL # N
+v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL VIEW # NULL
Warnings:
Note 1449 The user specified as a definer ('unknownuser'@'%') does not exist
drop database mysqltest1;
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index d17469abae5..b86d72acb84 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -135,7 +135,9 @@ def information_schema TABLES TABLES TABLE_COLLATION Collation 253 32 0 Y 0 0 8
def information_schema TABLES TABLES CHECKSUM Checksum 8 21 0 Y 32800 0 63
def information_schema TABLES TABLES CREATE_OPTIONS Create_options 253 2048 0 Y 0 0 8
def information_schema TABLES TABLES TABLE_COMMENT Comment 253 2048 0 N 1 0 8
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+def information_schema TABLES TABLES MAX_INDEX_LENGTH Max_index_length 8 21 0 Y 32800 0 63
+def information_schema TABLES TABLES TEMPORARY Temporary 253 1 0 Y 0 0 8
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
show databases;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def information_schema SCHEMATA SCHEMATA SCHEMA_NAME Database 253 64 18 N 1 0 8
@@ -459,58 +461,58 @@ insert into t1 values (1),(2);
insert into t2 values (1),(2);
insert into t3 values (1,1),(2,2);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 10 Fixed 2 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 10 Fixed 2 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 10 Fixed 2 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY 10 Fixed 2 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t2 MEMORY 10 Fixed 2 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t3 MEMORY 10 Fixed 2 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
insert into t1 values (3),(4);
insert into t2 values (3),(4);
insert into t3 values (3,3),(4,4);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 10 Fixed 4 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 10 Fixed 4 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 10 Fixed 4 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY 10 Fixed 4 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t2 MEMORY 10 Fixed 4 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t3 MEMORY 10 Fixed 4 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 10 Fixed 5 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 10 Fixed 5 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 10 Fixed 5 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY 10 Fixed 5 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t2 MEMORY 10 Fixed 5 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t3 MEMORY 10 Fixed 5 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
delete from t1 where a=3;
delete from t2 where b=3;
delete from t3 where a=3;
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 10 Fixed 4 # # # # # NULL # NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 10 Fixed 4 # # # # # NULL # NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 10 Fixed 4 # # # # # NULL # NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY 10 Fixed 4 # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t2 MEMORY 10 Fixed 4 # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t3 MEMORY 10 Fixed 4 # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N
truncate table t1;
truncate table t2;
truncate table t3;
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 10 Fixed 0 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 10 Fixed 0 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 10 Fixed 0 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY 10 Fixed 0 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t2 MEMORY 10 Fixed 0 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t3 MEMORY 10 Fixed 0 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 10 Fixed 1 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 10 Fixed 1 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 10 Fixed 1 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY 10 Fixed 1 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t2 MEMORY 10 Fixed 1 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t3 MEMORY 10 Fixed 1 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
delete from t1 where a=5;
delete from t2 where b=5;
delete from t3 where a=5;
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 10 Fixed 0 # # # # # NULL # NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 10 Fixed 0 # # # # # NULL # NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 10 Fixed 0 # # # # # NULL # NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY 10 Fixed 0 # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t2 MEMORY 10 Fixed 0 # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t3 MEMORY 10 Fixed 0 # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N
drop table t1, t2, t3;
create database mysqltest;
show create database mysqltest;
@@ -674,8 +676,8 @@ t1 CREATE TABLE `t1` (
DROP TABLE t1;
flush tables;
SHOW TABLE STATUS like 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 NULL NULL NULL NULL # # # # NULL NULL # NULL NULL NULL NULL NULL Incorrect information in file: './test/t1.frm'
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 NULL NULL NULL NULL # # # # NULL NULL # NULL NULL NULL NULL NULL Incorrect information in file: './test/t1.frm' NULL NULL
Warnings:
Warning 1033 Incorrect information in file: './test/t1.frm'
show create table t1;
@@ -1206,26 +1208,6 @@ DROP TABLE t1;
DROP VIEW v1;
DROP PROCEDURE p1;
DROP FUNCTION f1;
-set names koi8r;
-DROP DATABASE IF EXISTS mysqltest1;
-CREATE DATABASE mysqltest1;
-use mysqltest1;
-CREATE TABLE t1(ËÏÌÏÎËÁ1 INT);
-
----> Dumping mysqltest1 to outfile1
-
-
-DROP DATABASE mysqltest1;
-
-
----> Restoring mysqltest1...
-SHOW CREATE TABLE mysqltest1.t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `ËÏÌÏÎËÁ1` int(11) DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-DROP DATABASE mysqltest1;
-use test;
flush status;
show variables like "log_queries_not_using_indexes";
Variable_name Value
@@ -1273,8 +1255,8 @@ PRIMARY KEY (Codigo)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
show create table t1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def Table 253 64 2 N 1 39 7
-def Create Table 253 1024 458 N 1 39 7
+def Table 253 192 2 N 1 39 33
+def Create Table 253 3072 458 N 1 39 33
Table Create Table
t1 CREATE TABLE `t1` (
`Codigo` int(10) unsigned NOT NULL AUTO_INCREMENT,
@@ -1357,8 +1339,8 @@ SET NAMES latin1;
CREATE DATABASE `ä`;
CREATE TABLE `ä`.`ä` (a int) ENGINE=Memory;
SHOW TABLE STATUS FROM `ä` LIKE 'ä';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-ä MEMORY 10 Fixed 0 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+ä MEMORY 10 Fixed 0 # # # # 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
DROP DATABASE `ä`;
show columns from `#mysql50#????????`;
Got one of the listed errors
diff --git a/mysql-test/r/signal.result b/mysql-test/r/signal.result
index 671df4b7f17..905842bfb1c 100644
--- a/mysql-test/r/signal.result
+++ b/mysql-test/r/signal.result
@@ -1715,7 +1715,7 @@ show warnings $$
Level Code Message
Warning 1012 Raising a warning
Error 5555 RESIGNAL to not found
-Note 4092 At line 9 in test.test_resignal
+Note 4094 At line 9 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -1740,7 +1740,7 @@ show warnings $$
Level Code Message
Warning 1012 Raising a warning
Error 5555 RESIGNAL to error
-Note 4092 At line 9 in test.test_resignal
+Note 4094 At line 9 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -1789,7 +1789,7 @@ show warnings $$
Level Code Message
Error 1012 Raising a not found
Error 5555 RESIGNAL to not found
-Note 4092 At line 9 in test.test_resignal
+Note 4094 At line 9 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -1814,7 +1814,7 @@ show warnings $$
Level Code Message
Error 1012 Raising a not found
Error 5555 RESIGNAL to error
-Note 4092 At line 9 in test.test_resignal
+Note 4094 At line 9 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -1863,7 +1863,7 @@ show warnings $$
Level Code Message
Error 1012 Raising an error
Error 5555 RESIGNAL to not found
-Note 4092 At line 9 in test.test_resignal
+Note 4094 At line 9 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -1888,7 +1888,7 @@ show warnings $$
Level Code Message
Error 1012 Raising an error
Error 5555 RESIGNAL to error
-Note 4092 At line 9 in test.test_resignal
+Note 4094 At line 9 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -1931,7 +1931,7 @@ show warnings $$
Level Code Message
Warning 1264 Out of range value for column 'a' at row 1
Error 5555 RESIGNAL to a not found
-Note 4092 At line 8 in test.test_resignal
+Note 4094 At line 8 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -1953,7 +1953,7 @@ show warnings $$
Level Code Message
Warning 1264 Out of range value for column 'a' at row 1
Error 5555 RESIGNAL to an error
-Note 4092 At line 8 in test.test_resignal
+Note 4094 At line 8 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -2004,7 +2004,7 @@ show warnings $$
Level Code Message
Error 1329 No data - zero rows fetched, selected, or processed
Error 5555 RESIGNAL to a not found
-Note 4092 At line 10 in test.test_resignal
+Note 4094 At line 10 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -2030,7 +2030,7 @@ show warnings $$
Level Code Message
Error 1329 No data - zero rows fetched, selected, or processed
Error 5555 RESIGNAL to an error
-Note 4092 At line 10 in test.test_resignal
+Note 4094 At line 10 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -2073,7 +2073,7 @@ show warnings $$
Level Code Message
Error 1051 Unknown table 'test.no_such_table'
Error 5555 RESIGNAL to a not found
-Note 4092 At line 8 in test.test_resignal
+Note 4094 At line 8 in test.test_resignal
drop procedure test_resignal $$
create procedure test_resignal()
begin
@@ -2095,7 +2095,7 @@ show warnings $$
Level Code Message
Error 1051 Unknown table 'test.no_such_table'
Error 5555 RESIGNAL to an error
-Note 4092 At line 8 in test.test_resignal
+Note 4094 At line 8 in test.test_resignal
drop procedure test_resignal $$
#
# More complex cases
@@ -2142,7 +2142,7 @@ ERROR 42000: Hi, I am a useless error message
show warnings $$
Level Code Message
Error 9999 Hi, I am a useless error message
-Note 4092 At line 7 in test.peter_p2
+Note 4094 At line 7 in test.peter_p2
drop procedure peter_p1 $$
drop procedure peter_p2 $$
CREATE PROCEDURE peter_p1 ()
@@ -2198,16 +2198,16 @@ Level Code Message
Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL'
Error 1232 Variable 'sql_mode' can't be set to the value of 'NULL'
Error 9999 Variable 'sql_mode' can't be set to the value of 'NULL'
-Note 4092 At line 8 in test.peter_p1
+Note 4094 At line 8 in test.peter_p1
ERROR 42000: Hi, I am a useless error message
show warnings $$
Level Code Message
Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL'
Error 1232 Variable 'sql_mode' can't be set to the value of 'NULL'
Error 9999 Variable 'sql_mode' can't be set to the value of 'NULL'
-Note 4092 At line 8 in test.peter_p1
+Note 4094 At line 8 in test.peter_p1
Error 9999 Hi, I am a useless error message
-Note 4092 At line 10 in test.peter_p2
+Note 4094 At line 10 in test.peter_p2
drop procedure peter_p1 $$
drop procedure peter_p2 $$
drop procedure if exists peter_p3 $$
@@ -2225,7 +2225,7 @@ show warnings $$
Level Code Message
Error 1 Original
Error 2 Original
-Note 4092 At line 4 in test.peter_p3
+Note 4094 At line 4 in test.peter_p3
drop procedure peter_p3 $$
drop table t_warn;
drop table t_cursor;
diff --git a/mysql-test/r/signal_demo3.result b/mysql-test/r/signal_demo3.result
index a98d587937c..fe425f6412d 100644
--- a/mysql-test/r/signal_demo3.result
+++ b/mysql-test/r/signal_demo3.result
@@ -79,23 +79,23 @@ show warnings;
Level Code Message
Error 1051 Unknown table 'demo.oops_it_is_not_here'
Error 1644 Oops in proc_9
-Note 4092 At line 4 in demo.proc_9
+Note 4094 At line 4 in demo.proc_9
Error 1644 Oops in proc_8
-Note 4092 At line 4 in demo.proc_8
+Note 4094 At line 4 in demo.proc_8
Error 1644 Oops in proc_7
-Note 4092 At line 4 in demo.proc_7
+Note 4094 At line 4 in demo.proc_7
Error 1644 Oops in proc_6
-Note 4092 At line 4 in demo.proc_6
+Note 4094 At line 4 in demo.proc_6
Error 1644 Oops in proc_5
-Note 4092 At line 4 in demo.proc_5
+Note 4094 At line 4 in demo.proc_5
Error 1644 Oops in proc_4
-Note 4092 At line 4 in demo.proc_4
+Note 4094 At line 4 in demo.proc_4
Error 1644 Oops in proc_3
-Note 4092 At line 4 in demo.proc_3
+Note 4094 At line 4 in demo.proc_3
Error 1644 Oops in proc_2
-Note 4092 At line 4 in demo.proc_2
+Note 4094 At line 4 in demo.proc_2
Error 1644 Oops in proc_1
-Note 4092 At line 4 in demo.proc_1
+Note 4094 At line 4 in demo.proc_1
SET @@session.max_error_count = 5;
SELECT @@session.max_error_count;
@@session.max_error_count
@@ -104,11 +104,11 @@ call proc_1();
ERROR 45000: Oops in proc_1
show warnings;
Level Code Message
-Note 4092 At line 4 in demo.proc_3
+Note 4094 At line 4 in demo.proc_3
Error 1644 Oops in proc_2
-Note 4092 At line 4 in demo.proc_2
+Note 4094 At line 4 in demo.proc_2
Error 1644 Oops in proc_1
-Note 4092 At line 4 in demo.proc_1
+Note 4094 At line 4 in demo.proc_1
SET @@session.max_error_count = 7;
SELECT @@session.max_error_count;
@@session.max_error_count
@@ -117,13 +117,13 @@ call proc_1();
ERROR 45000: Oops in proc_1
show warnings;
Level Code Message
-Note 4092 At line 4 in demo.proc_4
+Note 4094 At line 4 in demo.proc_4
Error 1644 Oops in proc_3
-Note 4092 At line 4 in demo.proc_3
+Note 4094 At line 4 in demo.proc_3
Error 1644 Oops in proc_2
-Note 4092 At line 4 in demo.proc_2
+Note 4094 At line 4 in demo.proc_2
Error 1644 Oops in proc_1
-Note 4092 At line 4 in demo.proc_1
+Note 4094 At line 4 in demo.proc_1
SET @@session.max_error_count = 9;
SELECT @@session.max_error_count;
@@session.max_error_count
@@ -132,15 +132,15 @@ call proc_1();
ERROR 45000: Oops in proc_1
show warnings;
Level Code Message
-Note 4092 At line 4 in demo.proc_5
+Note 4094 At line 4 in demo.proc_5
Error 1644 Oops in proc_4
-Note 4092 At line 4 in demo.proc_4
+Note 4094 At line 4 in demo.proc_4
Error 1644 Oops in proc_3
-Note 4092 At line 4 in demo.proc_3
+Note 4094 At line 4 in demo.proc_3
Error 1644 Oops in proc_2
-Note 4092 At line 4 in demo.proc_2
+Note 4094 At line 4 in demo.proc_2
Error 1644 Oops in proc_1
-Note 4092 At line 4 in demo.proc_1
+Note 4094 At line 4 in demo.proc_1
drop database demo;
SET @@global.max_error_count = @start_global_value;
SELECT @@global.max_error_count;
diff --git a/mysql-test/r/simultaneous_assignment.result b/mysql-test/r/simultaneous_assignment.result
new file mode 100644
index 00000000000..67cb58ba6af
--- /dev/null
+++ b/mysql-test/r/simultaneous_assignment.result
@@ -0,0 +1,222 @@
+SET sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,SIMULTANEOUS_ASSIGNMENT';
+#
+# MDEV-13417 UPDATE produces wrong values if an UPDATEd column is later used as an UPDATE source
+#
+CREATE TABLE t1 (c1 INTEGER, c2 INTEGER, c3 INTEGER) ENGINE=InnoDb;
+INSERT INTO t1(c1,c2,c3) VALUES (1,1,1);
+CREATE TABLE t2 (c1 INTEGER, c2 INTEGER, c3 INTEGER) ENGINE=InnoDb;
+INSERT INTO t2(c1,c2,c3) VALUES (1,1,1);
+#
+# Check that a column is only updated once.
+#
+UPDATE t1
+SET c1 = 1,
+c1 = 2;
+ERROR HY000: The column `t1`.`c1` cannot be changed more than once in a single UPDATE statement
+UPDATE t1, t2
+SET t1.c1 = t1.c1 + 1,
+t1.c2 = t1.c1 + 1,
+t2.c2 = t1.c2 + 1,
+t2.c2 = t1.c2 + 1;
+ERROR HY000: The column `t2`.`c2` cannot be changed more than once in a single UPDATE statement
+#
+# Check standard update
+#
+UPDATE t1
+SET c1 = c1+1,
+c2 = c1+1,
+c3 = c2+1
+WHERE c1=10;
+START TRANSACTION;
+UPDATE t1
+SET c1 = c1+1,
+c2 = c1+1,
+c3 = c2+1;
+SELECT * FROM t1;
+c1 c2 c3
+2 2 2
+ROLLBACK;
+#
+# Check update through a single view
+#
+CREATE VIEW v1 (a, b) AS SELECT c1, c2 FROM t1;
+UPDATE v1
+SET a = 10,
+a = b+1;
+ERROR HY000: The column `t1`.`c1` cannot be changed more than once in a single UPDATE statement
+SELECT * FROM t1;
+c1 c2 c3
+1 1 1
+DROP VIEW v1;
+CREATE VIEW v1 (a, b) AS SELECT c2, c2 FROM t1;
+UPDATE v1
+SET a = 10,
+b = 20;
+ERROR HY000: The column `t1`.`c2` cannot be changed more than once in a single UPDATE statement
+SELECT * FROM t1;
+c1 c2 c3
+1 1 1
+DROP VIEW v1;
+#
+# Check update through a multi table view
+#
+CREATE VIEW v1 (a, b) AS SELECT t1.c1, t2.c1 FROM t1, t2 WHERE t1.c1=t2.c1;
+UPDATE v1
+SET a = 10,
+b = 20;
+ERROR HY000: Can not modify more than one base table through a join view 'test.v1'
+START TRANSACTION;
+UPDATE v1
+SET a = 10;
+ROLLBACK;
+UPDATE v1
+SET a = 10,
+a = a + 1;
+ERROR HY000: The column `t1`.`c1` cannot be changed more than once in a single UPDATE statement
+DROP VIEW v1;
+#
+# Check multi update
+#
+START TRANSACTION;
+UPDATE t1, t2
+SET t1.c1 = t1.c1 + 1,
+t1.c2 = t1.c1 + 1,
+t2.c2 = t1.c2 + 1,
+t2.c3 = t2.c2 + 1
+WHERE t1.c1=t2.c1;
+SELECT * FROM t1;
+c1 c2 c3
+2 2 1
+SELECT * FROM t2;
+c1 c2 c3
+1 2 2
+ROLLBACK;
+CREATE TRIGGER tr1 BEFORE UPDATE ON t1 FOR EACH ROW
+BEGIN
+INSERT INTO t2 VALUES(10+old.c1,10+old.c2,10+old.c3);
+INSERT INTO t2 VALUES(20+new.c1,10+new.c2,10+new.c3);
+END;
+/
+START TRANSACTION;
+UPDATE t1
+SET c1 = c1+1,
+c2 = c1+1,
+c3 = c2+1;
+SELECT * FROM t1;
+c1 c2 c3
+2 2 2
+SELECT * FROM t2;
+c1 c2 c3
+1 1 1
+11 11 11
+22 12 12
+ROLLBACK;
+DROP TABLE t1;
+DROP TABLE t2;
+#
+# Check update fired by INSERT ... ON DUPLICATE KEY UPDATE
+#
+CREATE TABLE t1 (
+id INT(11) NOT NULL AUTO_INCREMENT,
+name VARCHAR(60) NOT NULL,
+nb_visits INT NOT NULL,
+nb_visits_prev INT NOT NULL default 0,
+PRIMARY KEY (id),
+UNIQUE KEY name (name)
+) ENGINE=InnoDB AUTO_INCREMENT=1;
+INSERT INTO t1(name, nb_visits) VALUES('nico', 1)
+ON DUPLICATE KEY UPDATE nb_visits = nb_visits + 1;
+SELECT * FROM t1;
+id name nb_visits nb_visits_prev
+1 nico 1 0
+INSERT INTO t1(name, nb_visits) VALUES('nico', 1)
+ON DUPLICATE KEY UPDATE nb_visits = nb_visits + 1, nb_visits_prev=nb_visits;
+SELECT * FROM t1;
+id name nb_visits nb_visits_prev
+1 nico 2 1
+DROP TABLE t1;
+#
+# Update table with virtual column
+#
+CREATE TABLE t1 (c1 INTEGER, c2 INTEGER, c3 INTEGER AS (c1 MOD 10) VIRTUAL, c4 INTEGER AS (c1+c2 MOD 5) PERSISTENT ) ENGINE=InnoDb;
+INSERT INTO t1(c1,c2) VALUES (1,1);
+SELECT * FROM t1;
+c1 c2 c3 c4
+1 1 1 2
+UPDATE t1 SET c2 = 10, c1 = c2;
+SELECT * FROM t1;
+c1 c2 c3 c4
+1 10 1 1
+UPDATE t1 SET c2 = 4, c1 = c2;
+SELECT * FROM t1;
+c1 c2 c3 c4
+10 4 0 14
+DROP TABLE t1;
+#
+# Update dynamic column
+#
+SET @@local.character_set_connection='latin1';
+CREATE TABLE assets (
+item_name VARCHAR(32) PRIMARY KEY,
+dynamic_col1 BLOB,
+dynamic_col2 BLOB
+);
+INSERT INTO assets VALUES ('Thinkpad Laptop', COLUMN_CREATE('color', 'black', 'price', 500),COLUMN_CREATE('CPU', 'Core I7', 'memory', '8Go'));
+INSERT INTO assets VALUES ('Thinkpad Laptop2', COLUMN_CREATE('color', 'yellow', 'price', 700),COLUMN_CREATE('CPU', 'Core I7', 'memory', '16Go'));
+SELECT item_name, COLUMN_GET(dynamic_col1, 'color' as char) AS color1,
+COLUMN_GET(dynamic_col2, 'color' as char) AS color2
+FROM assets;
+item_name color1 color2
+Thinkpad Laptop black NULL
+Thinkpad Laptop2 yellow NULL
+UPDATE assets
+SET dynamic_col1=COLUMN_ADD(dynamic_col1, 'warranty', '3 years'),
+dynamic_col2=dynamic_col1
+WHERE item_name LIKE 'Thinkpad Laptop%';
+SELECT item_name, COLUMN_GET(dynamic_col1, 'warranty' as char) AS waranty1,
+COLUMN_GET(dynamic_col2, 'warranty' as char) AS waranty2,
+COLUMN_GET(dynamic_col2, 'color' as char) AS color2
+FROM assets;
+item_name waranty1 waranty2 color2
+Thinkpad Laptop 3 years NULL black
+Thinkpad Laptop2 3 years NULL yellow
+DROP TABLE assets;
+#
+# Update TEXT column
+#
+CREATE TABLE ft2(copy TEXT,copy2 TEXT,FULLTEXT(copy)) ENGINE=MyISAM;
+INSERT INTO ft2(copy) VALUES
+('MySQL vs MariaDB database'),
+('Oracle vs MariaDB database'),
+('PostgreSQL vs MariaDB database'),
+('MariaDB overview'),
+('Foreign keys'),
+('Primary keys'),
+('Indexes'),
+('Transactions'),
+('Triggers');
+SELECT * FROM ft2;
+copy copy2
+MySQL vs MariaDB database NULL
+Oracle vs MariaDB database NULL
+PostgreSQL vs MariaDB database NULL
+MariaDB overview NULL
+Foreign keys NULL
+Primary keys NULL
+Indexes NULL
+Transactions NULL
+Triggers NULL
+UPDATE ft2 SET copy = UPPER(copy),
+copy2= copy;
+SELECT * FROM ft2;
+copy copy2
+MYSQL VS MARIADB DATABASE MySQL vs MariaDB database
+ORACLE VS MARIADB DATABASE Oracle vs MariaDB database
+POSTGRESQL VS MARIADB DATABASE PostgreSQL vs MariaDB database
+MARIADB OVERVIEW MariaDB overview
+FOREIGN KEYS Foreign keys
+PRIMARY KEYS Primary keys
+INDEXES Indexes
+TRANSACTIONS Transactions
+TRIGGERS Triggers
+DROP TABLE ft2;
diff --git a/mysql-test/r/sp-big.result b/mysql-test/r/sp-big.result
index 9765508859c..e12136eb36d 100644
--- a/mysql-test/r/sp-big.result
+++ b/mysql-test/r/sp-big.result
@@ -1,5 +1,3 @@
-drop procedure if exists test.longprocedure;
-drop table if exists t1;
create table t1 (a int);
insert into t1 values (1),(2),(3);
length
@@ -60,3 +58,30 @@ f1
This is a test case for for Bug#9819
drop procedure p1;
drop table t1, t2;
+create table t1 (
+`id1` int unsigned not null default '0',
+`id2` int unsigned not null default '0',
+`link_type` int unsigned not null default '0',
+`visibility` tinyint not null default '0',
+`data` varchar(255) not null default '',
+`time` int unsigned not null default '0',
+`version` int unsigned not null default '0',
+primary key (id1, link_type, visibility, id2)
+) default collate=latin1_bin;
+create procedure select_test()
+begin
+declare id1_cond int;
+set id1_cond = 1;
+while id1_cond <= 10000 do
+select count(*) as cnt from (select id1 from t1 force index (primary) where id1 = id1_cond and link_type = 1 and visibility = 1 order by id2 desc) as t into @cnt;
+set id1_cond = id1_cond + 1;
+end while;
+end//
+insert t1 select seq, seq, 1, 1, seq, seq, seq from seq_1_to_2000;
+set @before=unix_timestamp();
+call select_test();
+select unix_timestamp() - @before < 60;
+unix_timestamp() - @before < 60
+1
+drop procedure select_test;
+drop table t1;
diff --git a/mysql-test/r/sp-code.result b/mysql-test/r/sp-code.result
index ddb2901b8a4..3a4dc9db6f8 100644
--- a/mysql-test/r/sp-code.result
+++ b/mysql-test/r/sp-code.result
@@ -998,3 +998,306 @@ Pos Instruction
7 set b.a@1["a"] a.a@0["a"]
DROP PROCEDURE p1;
DROP TABLE t1;
+#
+# MDEV-14415 Add Oracle-style FOR loop to sql_mode=DEFAULT
+#
+# Integer range FOR loop
+CREATE PROCEDURE p1()
+BEGIN
+FOR i IN 1..3
+DO
+SELECT i;
+END FOR;
+END;
+$$
+CALL p1;
+i
+1
+i
+2
+i
+3
+SHOW PROCEDURE CODE p1;
+Pos Instruction
+0 set i@0 1
+1 set [upper_bound]@1 3
+2 jump_if_not 6(6) i@0 <= [upper_bound]@1
+3 stmt 0 "SELECT i"
+4 set i@0 i@0 + 1
+5 jump 2
+DROP PROCEDURE p1;
+# Nested integer range FOR loops
+CREATE PROCEDURE p1()
+BEGIN
+fori:
+FOR i IN 1..3
+DO
+forj:
+FOR j IN 1..3
+DO
+IF i = 3 THEN
+LEAVE fori;
+END IF;
+IF j = 3 THEN
+LEAVE forj;
+END IF;
+SELECT i,j;
+END FOR;
+END FOR;
+END;
+$$
+CALL p1;
+i j
+1 1
+i j
+1 2
+i j
+2 1
+i j
+2 2
+SHOW PROCEDURE CODE p1;
+Pos Instruction
+0 set i@0 1
+1 set [upper_bound]@1 3
+2 jump_if_not 17(17) i@0 <= [upper_bound]@1
+3 set j@2 1
+4 set [upper_bound]@3 3
+5 jump_if_not 13(13) j@2 <= [upper_bound]@3
+6 jump_if_not 8(8) i@0 = 3
+7 jump 17
+8 jump_if_not 10(10) j@2 = 3
+9 jump 13
+10 stmt 0 "SELECT i,j"
+11 set j@2 j@2 + 1
+12 jump 5
+13 set i@0 i@0 + 1
+14 jump 2
+DROP PROCEDURE p1;
+# Explicit cursor FOR loops
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE cur0 CURSOR FOR SELECT 10 AS a, 'b0' AS b;
+DECLARE cur1 CURSOR FOR SELECT 10 AS a, 'b0' AS b;
+DECLARE cur2 CURSOR FOR SELECT 10 AS a, 'b0' AS b;
+FOR rec1 IN cur1
+DO
+SELECT rec1.a, rec1.b;
+SET rec1.a= 11;
+SET rec1.b= 'b1';
+SELECT rec1.a, rec1.b;
+END FOR;
+FOR rec0 IN cur0
+DO
+SET rec0.a= 10;
+SET rec0.b='b0';
+END FOR;
+FOR rec2 IN cur2
+DO
+SET rec2.a= 10;
+SET rec2.b='b0';
+END FOR;
+END;
+$$
+SHOW PROCEDURE CODE p1;
+Pos Instruction
+0 cpush cur0@0
+1 cpush cur1@1
+2 cpush cur2@2
+3 cursor_copy_struct cur1 rec1@0
+4 copen cur1@1
+5 cfetch cur1@1 rec1@0
+6 jump_if_not 13(13) `cur1`%FOUND
+7 stmt 0 "SELECT rec1.a, rec1.b"
+8 set rec1.a@0["a"] 11
+9 set rec1.b@0["b"] 'b1'
+10 stmt 0 "SELECT rec1.a, rec1.b"
+11 cfetch cur1@1 rec1@0
+12 jump 6
+13 cursor_copy_struct cur0 rec0@1
+14 copen cur0@0
+15 cfetch cur0@0 rec0@1
+16 jump_if_not 21(21) `cur0`%FOUND
+17 set rec0.a@1["a"] 10
+18 set rec0.b@1["b"] 'b0'
+19 cfetch cur0@0 rec0@1
+20 jump 16
+21 cursor_copy_struct cur2 rec2@2
+22 copen cur2@2
+23 cfetch cur2@2 rec2@2
+24 jump_if_not 29(29) `cur2`%FOUND
+25 set rec2.a@2["a"] 10
+26 set rec2.b@2["b"] 'b0'
+27 cfetch cur2@2 rec2@2
+28 jump 24
+29 cpop 3
+DROP PROCEDURE p1;
+# Nested explicit cursor FOR loops
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE cur0 CURSOR FOR SELECT 10 AS a, 'b0' AS b;
+FOR rec0 IN cur0
+DO
+BEGIN
+DECLARE cur1 CURSOR FOR SELECT 11 AS a, 'b1' AS b;
+SET rec0.a= 11;
+SET rec0.b= 'b0';
+FOR rec1 IN cur1
+DO
+SET rec1.a= 11;
+SET rec1.b= 'b1';
+BEGIN
+DECLARE cur2 CURSOR FOR SELECT 12 AS a, 'b2' AS b;
+FOR rec2 IN cur2
+DO
+SET rec2.a=12;
+SET rec2.b='b2';
+END FOR;
+END;
+END FOR;
+END;
+END FOR;
+END;
+$$
+SHOW PROCEDURE CODE p1;
+Pos Instruction
+0 cpush cur0@0
+1 cursor_copy_struct cur0 rec0@0
+2 copen cur0@0
+3 cfetch cur0@0 rec0@0
+4 jump_if_not 29(29) `cur0`%FOUND
+5 cpush cur1@1
+6 set rec0.a@0["a"] 11
+7 set rec0.b@0["b"] 'b0'
+8 cursor_copy_struct cur1 rec1@1
+9 copen cur1@1
+10 cfetch cur1@1 rec1@1
+11 jump_if_not 26(26) `cur1`%FOUND
+12 set rec1.a@1["a"] 11
+13 set rec1.b@1["b"] 'b1'
+14 cpush cur2@2
+15 cursor_copy_struct cur2 rec2@2
+16 copen cur2@2
+17 cfetch cur2@2 rec2@2
+18 jump_if_not 23(23) `cur2`%FOUND
+19 set rec2.a@2["a"] 12
+20 set rec2.b@2["b"] 'b2'
+21 cfetch cur2@2 rec2@2
+22 jump 18
+23 cpop 1
+24 cfetch cur1@1 rec1@1
+25 jump 11
+26 cpop 1
+27 cfetch cur0@0 rec0@0
+28 jump 4
+29 cpop 1
+DROP PROCEDURE p1;
+# Implicit cursor FOR loops
+CREATE PROCEDURE p1()
+BEGIN
+FOR rec1 IN (SELECT 11 AS a, 'b1' AS b)
+DO
+SELECT rec1.a, rec1.b;
+SET rec1.a= 11;
+SET rec1.b= 'b1';
+SELECT rec1.a, rec1.b;
+END FOR;
+FOR rec0 IN (SELECT 10 AS a, 'b0' AS b)
+DO
+SET rec0.a= 10;
+SET rec0.b='b0';
+END FOR;
+FOR rec2 IN (SELECT 12 AS a, 'b2' AS b)
+DO
+SET rec2.a= 10;
+SET rec2.b='b0';
+END FOR;
+END;
+$$
+SHOW PROCEDURE CODE p1;
+Pos Instruction
+0 cpush [implicit_cursor]@0
+1 cursor_copy_struct [implicit_cursor] rec1@0
+2 copen [implicit_cursor]@0
+3 cfetch [implicit_cursor]@0 rec1@0
+4 jump_if_not 11(11) `[implicit_cursor]`%FOUND
+5 stmt 0 "SELECT rec1.a, rec1.b"
+6 set rec1.a@0["a"] 11
+7 set rec1.b@0["b"] 'b1'
+8 stmt 0 "SELECT rec1.a, rec1.b"
+9 cfetch [implicit_cursor]@0 rec1@0
+10 jump 4
+11 cpop 1
+12 cpush [implicit_cursor]@0
+13 cursor_copy_struct [implicit_cursor] rec0@1
+14 copen [implicit_cursor]@0
+15 cfetch [implicit_cursor]@0 rec0@1
+16 jump_if_not 21(21) `[implicit_cursor]`%FOUND
+17 set rec0.a@1["a"] 10
+18 set rec0.b@1["b"] 'b0'
+19 cfetch [implicit_cursor]@0 rec0@1
+20 jump 16
+21 cpop 1
+22 cpush [implicit_cursor]@0
+23 cursor_copy_struct [implicit_cursor] rec2@2
+24 copen [implicit_cursor]@0
+25 cfetch [implicit_cursor]@0 rec2@2
+26 jump_if_not 31(31) `[implicit_cursor]`%FOUND
+27 set rec2.a@2["a"] 10
+28 set rec2.b@2["b"] 'b0'
+29 cfetch [implicit_cursor]@0 rec2@2
+30 jump 26
+31 cpop 1
+DROP PROCEDURE p1;
+# Nested implicit cursor FOR loops
+CREATE PROCEDURE p1()
+BEGIN
+FOR rec0 IN (SELECT 10 AS a, 'b0' AS b)
+DO
+SET rec0.a= 11;
+SET rec0.b= 'b0';
+FOR rec1 IN (SELECT 11 AS a, 'b1' AS b)
+DO
+SET rec1.a= 11;
+SET rec1.b= 'b1';
+FOR rec2 IN (SELECT 12 AS a, 'b2' AS b)
+DO
+SET rec2.a=12;
+SET rec2.b='b2';
+END FOR;
+END FOR;
+END FOR;
+END;
+$$
+SHOW PROCEDURE CODE p1;
+Pos Instruction
+0 cpush [implicit_cursor]@0
+1 cursor_copy_struct [implicit_cursor] rec0@0
+2 copen [implicit_cursor]@0
+3 cfetch [implicit_cursor]@0 rec0@0
+4 jump_if_not 29(29) `[implicit_cursor]`%FOUND
+5 set rec0.a@0["a"] 11
+6 set rec0.b@0["b"] 'b0'
+7 cpush [implicit_cursor]@1
+8 cursor_copy_struct [implicit_cursor] rec1@1
+9 copen [implicit_cursor]@1
+10 cfetch [implicit_cursor]@1 rec1@1
+11 jump_if_not 26(26) `[implicit_cursor]`%FOUND
+12 set rec1.a@1["a"] 11
+13 set rec1.b@1["b"] 'b1'
+14 cpush [implicit_cursor]@2
+15 cursor_copy_struct [implicit_cursor] rec2@2
+16 copen [implicit_cursor]@2
+17 cfetch [implicit_cursor]@2 rec2@2
+18 jump_if_not 23(23) `[implicit_cursor]`%FOUND
+19 set rec2.a@2["a"] 12
+20 set rec2.b@2["b"] 'b2'
+21 cfetch [implicit_cursor]@2 rec2@2
+22 jump 18
+23 cpop 1
+24 cfetch [implicit_cursor]@1 rec1@1
+25 jump 11
+26 cpop 1
+27 cfetch [implicit_cursor]@0 rec0@0
+28 jump 4
+29 cpop 1
+DROP PROCEDURE p1;
diff --git a/mysql-test/r/sp-cursor.result b/mysql-test/r/sp-cursor.result
index d068c19b22b..1f8cb7f0635 100644
--- a/mysql-test/r/sp-cursor.result
+++ b/mysql-test/r/sp-cursor.result
@@ -480,3 +480,134 @@ DROP PROCEDURE p1;
#
# End of MDEV-12457 Cursors with parameters
#
+#
+# MDEV-14415 Add Oracle-style FOR loop to sql_mode=DEFAULT
+#
+# Explicit cursor
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES (1,'b1'), (2,'b2'), (3,'b3');
+BEGIN NOT ATOMIC
+DECLARE cur CURSOR FOR SELECT * FROM t1;
+FOR rec IN cur
+DO
+SELECT rec.a AS a, rec.b AS b;
+END FOR;
+END;
+$$
+a b
+1 b1
+a b
+2 b2
+a b
+3 b3
+DROP TABLE t1;
+# Explicit cursor with parameters
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES (1,'b1'), (2,'b2'), (3,'b3');
+BEGIN NOT ATOMIC
+DECLARE cur CURSOR(pa INT) FOR SELECT * FROM t1 WHERE a>=pa;
+FOR rec IN cur(2)
+DO
+SELECT rec.a AS a, rec.b AS b;
+END FOR;
+END;
+$$
+a b
+2 b2
+a b
+3 b3
+DROP TABLE t1;
+# Explicit cursor + label
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES ('1','b1'), ('2','b2');
+BEGIN NOT ATOMIC
+DECLARE cur CURSOR FOR SELECT * FROM t1;
+forrec:
+FOR rec IN cur
+DO
+SELECT rec.a AS a, rec.b AS b;
+IF rec.a = 2 THEN
+LEAVE forrec;
+END IF;
+END FOR forrec;
+END;
+$$
+a b
+1 b1
+a b
+2 b2
+DROP TABLE t1;
+# Explicit cursor + FETCH inside the loop body produce an error on "NOT FOUND"
+BEGIN NOT ATOMIC
+DECLARE x INT;
+DECLARE cur CURSOR FOR SELECT 1 AS x;
+FOR rec IN cur
+DO
+FETCH cur INTO x;
+END FOR;
+END;
+$$
+ERROR 02000: No data - zero rows fetched, selected, or processed
+# Explicit cursor + FETCH inside the loop body are normally handled by "HANDLER FOR NOT FOUND"
+BEGIN NOT ATOMIC
+DECLARE done INT DEFAULT 0;
+DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
+SELECT 2,'y2' UNION
+SELECT 3,'y3';
+DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
+forrec:
+FOR rec IN cur
+DO
+SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
+FETCH cur INTO rec;
+IF done THEN
+SELECT 'NO DATA' AS `Explicit FETCH`;
+LEAVE forrec;
+ELSE
+SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
+END IF;
+END FOR;
+END;
+$$
+Implicit FETCH
+1 y1
+Explicit FETCH
+2 y2
+Implicit FETCH
+3 y3
+Explicit FETCH
+NO DATA
+# Implicit cursor
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES ('1','b1'), ('2','b2');
+BEGIN NOT ATOMIC
+FOR rec IN (SELECT * FROM t1)
+DO
+SELECT rec.a AS a, rec.b AS b;
+END FOR;
+END;
+$$
+a b
+1 b1
+a b
+2 b2
+DROP TABLE t1;
+# Implicit cursor + label
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES ('1','b1'), ('2','b2');
+BEGIN NOT ATOMIC
+forrec:
+FOR rec IN (SELECT * FROM t1)
+DO
+SELECT rec.a AS a, rec.b AS b;
+IF rec.a = 2 THEN
+LEAVE forrec;
+END IF;
+END FOR;
+END;
+$$
+a b
+1 b1
+a b
+2 b2
+DROP TABLE t1;
diff --git a/mysql-test/r/sp-destruct.result b/mysql-test/r/sp-destruct.result
index 5bb3b17d4b8..112fdb3978d 100644
--- a/mysql-test/r/sp-destruct.result
+++ b/mysql-test/r/sp-destruct.result
@@ -1,4 +1,4 @@
-call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted");
+call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 21, found 20. The table is probably corrupted");
call mtr.add_suppression("Stored routine .test...bug14233_[123].: invalid value in column mysql.proc");
flush table mysql.proc;
use test;
@@ -14,13 +14,13 @@ create table t1 (id int);
create trigger t1_ai after insert on t1 for each row call bug14233();
alter table mysql.proc drop security_type;
call bug14233();
-ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
+ERROR HY000: Column count of mysql.proc is wrong. Expected 21, found 20. The table is probably corrupted
create view v1 as select bug14233_f();
-ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
+ERROR HY000: Column count of mysql.proc is wrong. Expected 21, found 20. The table is probably corrupted
insert into t1 values (0);
-ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
+ERROR HY000: Column count of mysql.proc is wrong. Expected 21, found 20. The table is probably corrupted
show procedure status;
-ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
+ERROR HY000: Column count of mysql.proc is wrong. Expected 21, found 20. The table is probably corrupted
flush table mysql.proc;
call bug14233();
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
@@ -146,7 +146,7 @@ alter table mysql.proc drop column security_type;
# The below statement should not cause assertion failure.
drop database mysqltest;
Warnings:
-Error 1805 Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
+Error 1805 Column count of mysql.proc is wrong. Expected 21, found 20. The table is probably corrupted
# Restore mysql.proc.
drop table mysql.proc;
#
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index f0bc1874850..fc43bdf17e9 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -1212,7 +1212,7 @@ ERROR 42S02: Unknown table 'c' in field list
drop procedure bug15091;
drop function if exists bug16896;
create aggregate function bug16896() returns int return 1;
-ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '() returns int return 1' at line 1
+ERROR HY000: Aggregate specific instruction(FETCH GROUP NEXT ROW) missing from the aggregate function
DROP PROCEDURE IF EXISTS bug14702;
CREATE IF NOT EXISTS PROCEDURE bug14702()
BEGIN
@@ -1990,8 +1990,8 @@ Warning 1264 Out of range value for column 'a' at row 1
Note 1292 Truncated incorrect INTEGER value: '222222 '
Warning 1264 Out of range value for column 'b' at row 1
Error 1048 Column 'c' cannot be null
-Note 4092 At line 6 in test.t1_bi
-Note 4092 At line 2 in test.p1
+Note 4094 At line 6 in test.t1_bi
+Note 4094 At line 2 in test.p1
DROP TABLE t1;
DROP TABLE t2;
diff --git a/mysql-test/r/sp-for-loop.result b/mysql-test/r/sp-for-loop.result
new file mode 100644
index 00000000000..0da09586df5
--- /dev/null
+++ b/mysql-test/r/sp-for-loop.result
@@ -0,0 +1,208 @@
+#
+# MDEV-14415 Add Oracle-style FOR loop to sql_mode=DEFAULT
+#
+CREATE TABLE t1 (a INT);
+FOR i IN 1..3
+DO
+INSERT INTO t1 VALUES (i);
+END FOR;
+/
+SELECT * FROM t1;
+a
+1
+2
+3
+DROP TABLE t1;
+CREATE FUNCTION f1 (lower_bound INT, upper_bound INT, lim INT) RETURNS INT
+BEGIN
+DECLARE total INT DEFAULT 0;
+FOR i IN lower_bound . . upper_bound
+DO
+NULL
+END FOR;
+RETURN total;
+END;
+/
+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 '. upper_bound
+DO
+NULL
+END FOR;
+RETURN total;
+END' at line 4
+CREATE FUNCTION f1 (lower_bound INT, upper_bound INT, lim INT) RETURNS INT
+BEGIN
+DECLARE total INT DEFAULT 0;
+lab:
+FOR i IN lower_bound .. upper_bound
+DO
+SET total= total + i;
+IF i = lim THEN
+LEAVE lab;
+END IF;
+-- Bounds are calculated only once.
+-- The below assignments have no effect on the loop condition
+SET lower_bound= 900;
+SET upper_bound= 1000;
+END FOR;
+RETURN total;
+END;
+/
+SELECT f1(1, 3, 100) FROM DUAL;
+f1(1, 3, 100)
+6
+SELECT f1(1, 3, 2) FROM DUAL;
+f1(1, 3, 2)
+3
+DROP FUNCTION f1;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+DECLARE total INT DEFAULT 0;
+FOR i IN 1 .. 5
+DO
+SET total= total + 1000;
+forj:
+FOR j IN 1 .. 5
+DO
+SET total= total + 1;
+IF j = 3 THEN
+LEAVE forj; -- End the internal loop
+END IF;
+END FOR;
+END FOR;
+RETURN total;
+END;
+/
+SELECT f1() FROM DUAL;
+f1()
+5015
+DROP FUNCTION f1;
+CREATE FUNCTION f1 (a INT, b INT) RETURNS INT
+BEGIN
+DECLARE total INT DEFAULT 0;
+fori:
+FOR i IN REVERSE a..1
+DO
+SET total= total + i;
+IF i = b THEN
+LEAVE fori;
+END IF;
+END FOR;
+RETURN total;
+END
+/
+SELECT f1(3, 100) FROM DUAL;
+f1(3, 100)
+6
+SELECT f1(3, 2) FROM DUAL;
+f1(3, 2)
+5
+DROP FUNCTION f1;
+# Testing labeled FOR LOOP statement
+CREATE FUNCTION f1 (a INT, limita INT, b INT, limitb INT) RETURNS INT
+BEGIN
+DECLARE total INT DEFAULT 0;
+la:
+FOR ia IN 1 .. a
+DO
+SET total= total + 1000;
+lb:
+FOR ib IN 1 .. b
+DO
+SET total= total + 1;
+IF ib = limitb THEN
+LEAVE lb;
+END IF;
+IF ia = limita THEN
+LEAVE la;
+END IF;
+END FOR lb;
+END FOR la;
+RETURN total;
+END;
+/
+SELECT f1(1, 1, 1, 1) FROM DUAL;
+f1(1, 1, 1, 1)
+1001
+SELECT f1(1, 2, 1, 2) FROM DUAL;
+f1(1, 2, 1, 2)
+1001
+SELECT f1(2, 1, 2, 1) FROM DUAL;
+f1(2, 1, 2, 1)
+2002
+SELECT f1(2, 1, 2, 2) FROM DUAL;
+f1(2, 1, 2, 2)
+1001
+SELECT f1(2, 2, 2, 2) FROM DUAL;
+f1(2, 2, 2, 2)
+2003
+SELECT f1(2, 3, 2, 3) FROM DUAL;
+f1(2, 3, 2, 3)
+2004
+DROP FUNCTION f1;
+# Testing labeled ITERATE in a labeled FOR LOOP statement
+CREATE FUNCTION f1 (a INT, b INT, blim INT) RETURNS INT
+BEGIN
+DECLARE total INT DEFAULT 0;
+la:
+FOR ia IN 1 .. a
+DO
+SET total= total + 1000;
+BEGIN
+DECLARE ib INT DEFAULT 1;
+WHILE ib <= b
+DO
+IF ib > blim THEN
+ITERATE la;
+END IF;
+SET ib= ib + 1;
+SET total= total + 1;
+END WHILE;
+END;
+END FOR la;
+RETURN total;
+END;
+/
+SELECT f1(3,3,0), f1(3,3,1), f1(3,3,2), f1(3,3,3), f1(3,3,4) FROM DUAL;
+f1(3,3,0) f1(3,3,1) f1(3,3,2) f1(3,3,3) f1(3,3,4)
+3000 3003 3006 3009 3009
+DROP FUNCTION f1;
+# Testing INTERATE statement
+CREATE FUNCTION f1(a INT) RETURNS INT
+BEGIN
+DECLARE total INT DEFAULT 0;
+fori:
+FOR i IN 1 .. a
+DO
+IF i=5 THEN
+ITERATE fori;
+END IF;
+SET total= total + 1;
+END FOR;
+RETURN total;
+END;
+/
+SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL;
+f1(3) f1(4) f1(5) f1(6)
+3 4 4 5
+DROP FUNCTION f1;
+CREATE FUNCTION f1(a INT) RETURNS INT
+BEGIN
+DECLARE total INT DEFAULT 0;
+lj:
+FOR j IN 1 .. 2
+DO
+FOR i IN 1 .. a
+DO
+IF i=5 THEN
+ITERATE lj;
+END IF;
+SET total= total + 1;
+END FOR;
+END FOR;
+RETURN total;
+END;
+/
+SELECT f1(3), f1(4), f1(5) FROM DUAL;
+f1(3) f1(4) f1(5)
+6 8 8
+DROP FUNCTION f1;
diff --git a/mysql-test/r/sp-group.result b/mysql-test/r/sp-group.result
index 535e67046d8..ce8dccfa2c9 100644
--- a/mysql-test/r/sp-group.result
+++ b/mysql-test/r/sp-group.result
@@ -3,7 +3,7 @@ Warnings:
Note 1051 Unknown table 'test.t1'
drop view if exists view_t1;
Warnings:
-Note 4090 Unknown VIEW: 'test.view_t1'
+Note 4092 Unknown VIEW: 'test.view_t1'
SET sql_mode=ONLY_FULL_GROUP_BY;
CREATE TABLE t1 (
pk INT,
diff --git a/mysql-test/r/sp-row.result b/mysql-test/r/sp-row.result
index adb67030feb..d3be7c2a9b9 100644
--- a/mysql-test/r/sp-row.result
+++ b/mysql-test/r/sp-row.result
@@ -210,7 +210,7 @@ SELECT a=1;
END;
$$
CALL p1();
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
DROP PROCEDURE p1;
CREATE PROCEDURE p1()
BEGIN
@@ -219,7 +219,7 @@ SELECT 1=a;
END;
$$
CALL p1();
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
DROP PROCEDURE p1;
#
# Passing the entire ROW to a stored function
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index b66faec260f..0aa56291690 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -3211,7 +3211,7 @@ drop procedure bug10961|
DROP PROCEDURE IF EXISTS bug6866|
DROP VIEW IF EXISTS tv|
Warnings:
-Note 4090 Unknown VIEW: 'test.tv'
+Note 4092 Unknown VIEW: 'test.tv'
DROP TABLE IF EXISTS tt1,tt2,tt3|
Warnings:
Note 1051 Unknown table 'test.tt1'
@@ -5324,7 +5324,7 @@ DROP PROCEDURE bug21414|
set names utf8|
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')|
+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)
drop database това_е_дълго_име_за_база_данни_нали|
@@ -7823,7 +7823,7 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show warnings;
Level Code Message
Error 1062 Duplicate entry '2' for key 'PRIMARY'
-Note 4092 At line 5 in test.p1
+Note 4094 At line 5 in test.p1
select * from t1;
id
1
@@ -8116,6 +8116,141 @@ CALL p();
drop procedure p;
drop view v;
drop table t, tmp_t;
+#
+# MDEV-13936: Server crashes in Time_and_counter_tracker::incr_loops
+#
+CREATE TABLE t1 (i INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE RAND() > 0.5;
+CREATE FUNCTION f1() RETURNS INT RETURN ( SELECT MAX(i) FROM v1 );
+REPLACE INTO v1 VALUES (f1());
+ERROR HY000: The target table v1 of the INSERT is not insertable-into
+SET @aux = f1();
+DROP FUNCTION f1;
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# MDEV-14857: problem with 10.2.11 server crashing when
+# executing stored procedure
+#
+SET max_sp_recursion_depth=10;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT);
+CREATE PROCEDURE proc_0()
+BEGIN
+CALL empty_1();
+CALL proc_1();
+END ||
+CREATE PROCEDURE proc_1()
+BEGIN
+CALL proc_2();
+CALL proc_3();
+CALL proc_4();
+CALL proc_5();
+END ||
+CREATE PROCEDURE proc_2()
+CALL proc_6();
+||
+CREATE PROCEDURE proc_3()
+BEGIN
+CALL empty_2();
+CALL empty_3();
+END ||
+CREATE PROCEDURE proc_4()
+CALL proc_7();
+||
+CREATE PROCEDURE proc_5()
+CALL proc_select();
+||
+CREATE PROCEDURE proc_6()
+BEGIN
+CALL empty_4();
+CALL empty_5();
+CALL empty_6();
+CALL empty_7();
+CALL proc_8();
+END ||
+CREATE PROCEDURE proc_7()
+CALL proc_9('foo');
+||
+CREATE PROCEDURE proc_8()
+CALL proc_10();
+||
+CREATE PROCEDURE proc_9(IN opt VARCHAR(40))
+IF LEFT(opt,1) <> '_' THEN
+CALL proc_11();
+END IF;
+||
+CREATE PROCEDURE proc_10()
+CALL proc_12();
+||
+CREATE PROCEDURE proc_11()
+BEGIN
+CALL empty_8();
+CALL empty_9();
+CALL empty_10();
+CALL proc_13();
+END ||
+CREATE PROCEDURE proc_12()
+BEGIN
+CALL empty_11();
+CALL empty_12();
+CALL empty_13();
+END ||
+CREATE PROCEDURE proc_13()
+BEGIN
+CALL proc_9('_bar');
+CALL empty_14();
+END ||
+CREATE PROCEDURE empty_1() BEGIN END ;
+CREATE PROCEDURE empty_2() BEGIN END ;
+CREATE PROCEDURE empty_3() BEGIN END ;
+CREATE PROCEDURE empty_4() BEGIN END ;
+CREATE PROCEDURE empty_5() BEGIN END ;
+CREATE PROCEDURE empty_6() BEGIN END ;
+CREATE PROCEDURE empty_7() BEGIN END ;
+CREATE PROCEDURE empty_8() BEGIN END ;
+CREATE PROCEDURE empty_9() BEGIN END ;
+CREATE PROCEDURE empty_10() BEGIN END ;
+CREATE PROCEDURE empty_11() BEGIN END ;
+CREATE PROCEDURE empty_12() BEGIN END ;
+CREATE PROCEDURE empty_13() BEGIN END ;
+CREATE PROCEDURE empty_14() BEGIN END ;
+CREATE PROCEDURE proc_select()
+SELECT * FROM t1 WHERE NOT EXISTS ( SELECT * FROM t2)
+;
+CALL proc_0();
+a
+DROP PROCEDURE empty_1;
+DROP PROCEDURE empty_2;
+DROP PROCEDURE empty_3;
+DROP PROCEDURE empty_4;
+DROP PROCEDURE empty_5;
+DROP PROCEDURE empty_6;
+DROP PROCEDURE empty_7;
+DROP PROCEDURE empty_8;
+DROP PROCEDURE empty_9;
+DROP PROCEDURE empty_10;
+DROP PROCEDURE empty_11;
+DROP PROCEDURE empty_12;
+DROP PROCEDURE empty_13;
+DROP PROCEDURE empty_14;
+DROP PROCEDURE proc_0;
+DROP PROCEDURE proc_1;
+DROP PROCEDURE proc_2;
+DROP PROCEDURE proc_3;
+DROP PROCEDURE proc_4;
+DROP PROCEDURE proc_5;
+DROP PROCEDURE proc_6;
+DROP PROCEDURE proc_7;
+DROP PROCEDURE proc_8;
+DROP PROCEDURE proc_9;
+DROP PROCEDURE proc_10;
+DROP PROCEDURE proc_11;
+DROP PROCEDURE proc_12;
+DROP PROCEDURE proc_13;
+DROP PROCEDURE proc_select;
+DROP TABLE t1, t2;
+SET max_sp_recursion_depth=default;
#End of 10.1 tests
#
# MDEV-11081: CURSOR for query with GROUP BY
@@ -8174,6 +8309,34 @@ END
CALL p1();
DROP PROCEDURE p1;
#
+# MDEV-15057 Crash when using an unknown identifier as an SP parameter
+#
+CREATE OR REPLACE PROCEDURE p1 (a VARCHAR(10)) SELECT 1;
+CALL p1(a);
+ERROR 42S22: Unknown column 'a' in 'field list'
+drop procedure p1;
+CREATE OR REPLACE PROCEDURE p1 (a VARCHAR(10)) SELECT a|
+CREATE OR REPLACE PROCEDURE p2 ()
+BEGIN
+DECLARE name VARCHAR(10);
+SET name="hello";
+call p1(name);
+END|
+CREATE OR REPLACE PROCEDURE p3 ()
+BEGIN
+DECLARE name VARCHAR(10);
+SET name="hello";
+call p1(name2);
+END|
+call p2();
+a
+hello
+call p3();
+ERROR 42S22: Unknown column 'name2' in 'field list'
+drop procedure p1;
+drop procedure p2;
+drop procedure p3;
+#
# Start of 10.3 tests
#
#
@@ -8279,6 +8442,102 @@ rec=(10)
c
rec=(20)
DROP PROCEDURE p1;
+#
+# MDEV-14228 MariaDB crashes with function
+#
+CREATE TABLE t1 (c VARCHAR(16), KEY(c));
+INSERT INTO t1 VALUES ('foo');
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+DECLARE v VARCHAR(16);
+FOR v IN (SELECT DISTINCT c FROM t1)
+DO
+IF (v = 'bar') THEN
+SELECT 1 INTO @a;
+END IF;
+END FOR;
+RETURN 'qux';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+DECLARE v ROW TYPE OF t1;
+IF v = 'bar' THEN
+RETURN 'eq';
+END IF;
+RETURN 'ne';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+DECLARE v ROW(a INT);
+IF v = 'bar' THEN
+RETURN 'eq';
+END IF;
+RETURN 'ne';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+DROP TABLE t1;
+BEGIN NOT ATOMIC
+DECLARE v ROW(a INT);
+SELECT v IN ('a','b');
+END $$
+ERROR HY000: Illegal parameter data types row and varchar for operation 'in'
+BEGIN NOT ATOMIC
+DECLARE v ROW(a INT);
+SELECT 'a' IN (v,'b');
+END $$
+ERROR HY000: Illegal parameter data types varchar and row for operation 'in'
+BEGIN NOT ATOMIC
+DECLARE v ROW(a INT);
+SELECT 'a' IN ('b',v);
+END $$
+ERROR HY000: Illegal parameter data types varchar and row for operation 'in'
+#
+# MDEV-15112 Inconsistent evaluation of spvariable=0 in strict mode
+#
+SET sql_mode=STRICT_ALL_TABLES;
+CREATE OR REPLACE TABLE t1 (e TIMESTAMP(6));
+INSERT INTO t1 VALUES ('2001-01-01 10:20:30');
+CREATE FUNCTION f1(a VARBINARY(255))
+RETURNS INT
+DETERMINISTIC
+BEGIN
+RETURN a = timestamp'2038-01-19 03:14:07.999999'
+ OR a = 0;
+END
+$$
+CREATE FUNCTION f2(a VARBINARY(255))
+RETURNS INT
+DETERMINISTIC
+BEGIN
+RETURN a = 0;
+END
+$$
+CREATE OR REPLACE FUNCTION f3(a VARBINARY(255))
+RETURNS INT
+DETERMINISTIC
+BEGIN
+RETURN a = timestamp'2038-01-19 03:14:07.999999'
+ OR a = sleep(0);
+END
+$$
+SELECT f1(e) FROM t1;
+ERROR 22007: Truncated incorrect DOUBLE value: '2001-01-01 10:20:30'
+SELECT f2(e) FROM t1;
+ERROR 22007: Truncated incorrect DOUBLE value: '2001-01-01 10:20:30'
+SELECT f3(e) FROM t1;
+ERROR 22007: Truncated incorrect DOUBLE value: '2001-01-01 10:20:30'
+DROP FUNCTION f1;
+DROP FUNCTION f2;
+DROP FUNCTION f3;
+DROP TABLE t1;
# Test affected rows from an sp
create table t1 (a int);
create procedure p1()
diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result
index c6c241413d6..02574c1c545 100644
--- a/mysql-test/r/sql_mode.result
+++ b/mysql-test/r/sql_mode.result
@@ -75,7 +75,7 @@ t1 CREATE TABLE `t1` (
set sql_mode="postgresql,oracle,mssql,db2,maxdb";
select @@sql_mode;
@@sql_mode
-PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
+PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT
show create table t1;
Table Create Table
t1 CREATE TABLE "t1" (
@@ -475,8 +475,8 @@ set sql_mode=16384+(65536*4);
select @@sql_mode;
@@sql_mode
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_TABLE_OPTIONS,ANSI
-set sql_mode=2147483648*2*2;
-ERROR 42000: Variable 'sql_mode' can't be set to the value of '8589934592'
+set sql_mode=2147483648*2*2*2;
+ERROR 42000: Variable 'sql_mode' can't be set to the value of '17179869184'
select @@sql_mode;
@@sql_mode
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_TABLE_OPTIONS,ANSI
@@ -531,7 +531,7 @@ SET SESSION SQL_MODE = @OLD_SQL_MODE;
DROP USER 'user_no_PCTFL'@'localhost';
FLUSH PRIVILEGES;
SELECT * FROM mysql.db WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL';
-Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv
+Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv Delete_history_priv
SELECT * FROM mysql.tables_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL';
Host Db User Table_name Grantor Timestamp Table_priv Column_priv
SELECT * FROM mysql.columns_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL';
diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result
index 9b82c7896cb..18cde57b295 100644
--- a/mysql-test/r/status.result
+++ b/mysql-test/r/status.result
@@ -409,6 +409,23 @@ Table_open_cache_overflows 5
FLUSH TABLES;
FLUSH STATUS;
SET @@global.table_open_cache= @old_table_open_cache;
+#
+# MDEV-14505 - Threads_running becomes scalability bottleneck
+#
+# Session status for Threads_running is currently always 1.
+SHOW STATUS LIKE 'Threads_running';
+Variable_name Value
+Threads_running 1
+SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='THREADS_RUNNING';
+VARIABLE_VALUE
+1
+FLUSH STATUS;
+SHOW STATUS LIKE 'Threads_running';
+Variable_name Value
+Threads_running 1
+SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='THREADS_RUNNING';
+VARIABLE_VALUE
+1
connection default;
set @@global.concurrent_insert= @old_concurrent_insert;
SET GLOBAL log_output = @old_log_output;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 7ba8b545e6a..1c087a3199c 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -384,10 +384,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -1161,20 +1161,20 @@ drop table t1;
CREATE TABLE t1 (a int(1));
EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
drop table t1;
@@ -1644,7 +1644,7 @@ a
explain extended select * from t3 where a >= all (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2);
@@ -1652,7 +1652,7 @@ a
explain extended select * from t3 where a >= some (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= all (select b from t2 group by 1);
@@ -1663,7 +1663,7 @@ a
explain extended select * from t3 where a >= all (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2 group by 1);
@@ -1671,7 +1671,7 @@ a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where NULL >= any (select b from t2);
@@ -2865,13 +2865,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
@@ -3734,7 +3734,7 @@ from t1' at line 1
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
@@ -6120,7 +6120,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 Const row not found
SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
@@ -6134,7 +6134,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3 ) AS alias3;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
@@ -6720,7 +6720,7 @@ CREATE TABLE t2 (b INT);
EXPLAIN
SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t2 system NULL NULL NULL NULL 0 Const row not found
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -7214,6 +7214,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result
index 6126a7ed3f5..d3f46429cf7 100644
--- a/mysql-test/r/subselect4.result
+++ b/mysql-test/r/subselect4.result
@@ -21,7 +21,7 @@ ORDER BY count(*);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL a 5 NULL 2 Using index
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
-3 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 const row not found
+3 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 Const row not found
# should not crash the next statement
SELECT 1 FROM t1
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
@@ -1261,7 +1261,7 @@ SET optimizer_switch='materialization=off';
EXPLAIN
SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
@@ -1269,7 +1269,7 @@ c1 c1
EXPLAIN
SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
@@ -1278,7 +1278,7 @@ SET optimizer_switch='materialization=on';
EXPLAIN
SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
@@ -2191,7 +2191,7 @@ INSERT INTO t2 VALUES (1);
EXPLAIN
SELECT MAX(a), ( SELECT 1 FROM t2 ) AS bb FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY t2 system NULL NULL NULL NULL 1
SELECT MAX(a), ( SELECT 1 FROM t2 ) AS bb FROM t1;
MAX(a) bb
@@ -2199,7 +2199,7 @@ NULL 1
EXPLAIN
SELECT MAX(a), 1 in ( SELECT b FROM t2 ) AS bb FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY t2 system NULL NULL NULL NULL 1
SELECT MAX(a), 1 in ( SELECT b FROM t2 ) AS bb FROM t1;
MAX(a) bb
@@ -2207,7 +2207,7 @@ NULL 1
EXPLAIN
SELECT MAX(a), 1 >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
SELECT MAX(a), 1 >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
MAX(a) bb
@@ -2215,7 +2215,7 @@ NULL 1
EXPLAIN
SELECT MAX(a), ( SELECT 1 FROM t2 where b = a) AS bb FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
SELECT MAX(a), ( SELECT 1 FROM t2 where b = a) AS bb FROM t1;
MAX(a) bb
@@ -2223,7 +2223,7 @@ NULL NULL
EXPLAIN
SELECT MAX(a), a in ( SELECT b FROM t2 ) AS bb FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
SELECT MAX(a), a in ( SELECT b FROM t2 ) AS bb FROM t1;
MAX(a) bb
@@ -2231,7 +2231,7 @@ NULL NULL
EXPLAIN
SELECT MAX(a), a >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
SELECT MAX(a), a >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
MAX(a) bb
diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result
index 350275d2463..6b5db62093e 100644
--- a/mysql-test/r/subselect_mat.result
+++ b/mysql-test/r/subselect_mat.result
@@ -2544,7 +2544,7 @@ SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
-2 MATERIALIZED t3 system NULL NULL NULL NULL 0 const row not found
+2 MATERIALIZED t3 system NULL NULL NULL NULL 0 Const row not found
SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
i
10
@@ -2553,7 +2553,7 @@ SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
-2 MATERIALIZED t3 system NULL NULL NULL NULL 0 const row not found
+2 MATERIALIZED t3 system NULL NULL NULL NULL 0 Const row not found
SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
i
10
diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result
index b4feb8de200..125da8da517 100644
--- a/mysql-test/r/subselect_mat_cost_bugs.result
+++ b/mysql-test/r/subselect_mat_cost_bugs.result
@@ -162,7 +162,7 @@ EXPLAIN
SELECT * FROM (SELECT * FROM t2) AS a2
WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
insert into t2 values (1),(2);
diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result
index c09f3c94710..eb912d9e331 100644
--- a/mysql-test/r/subselect_no_exists_to_in.result
+++ b/mysql-test/r/subselect_no_exists_to_in.result
@@ -388,10 +388,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -1165,20 +1165,20 @@ drop table t1;
CREATE TABLE t1 (a int(1));
EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
drop table t1;
@@ -1648,7 +1648,7 @@ a
explain extended select * from t3 where a >= all (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2);
@@ -1656,7 +1656,7 @@ a
explain extended select * from t3 where a >= some (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= all (select b from t2 group by 1);
@@ -1667,7 +1667,7 @@ a
explain extended select * from t3 where a >= all (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2 group by 1);
@@ -1675,7 +1675,7 @@ a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where NULL >= any (select b from t2);
@@ -2868,13 +2868,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
@@ -3737,7 +3737,7 @@ from t1' at line 1
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
@@ -6120,7 +6120,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 Const row not found
SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
@@ -6134,7 +6134,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3 ) AS alias3;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
@@ -6720,7 +6720,7 @@ CREATE TABLE t2 (b INT);
EXPLAIN
SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t2 system NULL NULL NULL NULL 0 Const row not found
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -7214,6 +7214,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index 0aefeaf44d9..72f30bbd21f 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -391,10 +391,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -1168,20 +1168,20 @@ drop table t1;
CREATE TABLE t1 (a int(1));
EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
drop table t1;
@@ -1651,7 +1651,7 @@ a
explain extended select * from t3 where a >= all (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2);
@@ -1659,7 +1659,7 @@ a
explain extended select * from t3 where a >= some (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= all (select b from t2 group by 1);
@@ -1670,7 +1670,7 @@ a
explain extended select * from t3 where a >= all (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2 group by 1);
@@ -1678,7 +1678,7 @@ a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where NULL >= any (select b from t2);
@@ -2871,13 +2871,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
@@ -3737,7 +3737,7 @@ from t1' at line 1
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
@@ -6115,7 +6115,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 Const row not found
SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
@@ -6129,7 +6129,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3 ) AS alias3;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
@@ -6715,7 +6715,7 @@ CREATE TABLE t2 (b INT);
EXPLAIN
SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t2 system NULL NULL NULL NULL 0 Const row not found
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -7207,6 +7207,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index 92defb3c36d..de075d3245f 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -387,10 +387,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -1164,20 +1164,20 @@ drop table t1;
CREATE TABLE t1 (a int(1));
EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
drop table t1;
@@ -1647,7 +1647,7 @@ a
explain extended select * from t3 where a >= all (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2);
@@ -1655,7 +1655,7 @@ a
explain extended select * from t3 where a >= some (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= all (select b from t2 group by 1);
@@ -1666,7 +1666,7 @@ a
explain extended select * from t3 where a >= all (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2 group by 1);
@@ -1674,7 +1674,7 @@ a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where NULL >= any (select b from t2);
@@ -2867,13 +2867,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
@@ -3733,7 +3733,7 @@ from t1' at line 1
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
@@ -6111,7 +6111,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 Const row not found
SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
@@ -6125,7 +6125,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3 ) AS alias3;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
@@ -6711,7 +6711,7 @@ CREATE TABLE t2 (b INT);
EXPLAIN
SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t2 system NULL NULL NULL NULL 0 Const row not found
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -7205,6 +7205,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
index b47dab2e79e..a594f5f85b9 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -390,10 +390,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -1167,20 +1167,20 @@ drop table t1;
CREATE TABLE t1 (a int(1));
EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
drop table t1;
@@ -1650,7 +1650,7 @@ a
explain extended select * from t3 where a >= all (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2);
@@ -1658,7 +1658,7 @@ a
explain extended select * from t3 where a >= some (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= all (select b from t2 group by 1);
@@ -1669,7 +1669,7 @@ a
explain extended select * from t3 where a >= all (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2 group by 1);
@@ -1677,7 +1677,7 @@ a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where NULL >= any (select b from t2);
@@ -2871,13 +2871,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
@@ -3740,7 +3740,7 @@ from t1' at line 1
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
@@ -6126,7 +6126,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 Const row not found
SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
@@ -6140,7 +6140,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3 ) AS alias3;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
@@ -6726,7 +6726,7 @@ CREATE TABLE t2 (b INT);
EXPLAIN
SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t2 system NULL NULL NULL NULL 0 Const row not found
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -7220,6 +7220,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index 9d04ddd9829..e068b28b017 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -387,10 +387,10 @@ Warnings:
Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types varchar and row for operation '='
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
pseudo
joce
@@ -1164,20 +1164,20 @@ drop table t1;
CREATE TABLE t1 (a int(1));
EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select (/* select#2 */ select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
drop table t1;
@@ -1647,7 +1647,7 @@ a
explain extended select * from t3 where a >= all (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2);
@@ -1655,7 +1655,7 @@ a
explain extended select * from t3 where a >= some (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= all (select b from t2 group by 1);
@@ -1666,7 +1666,7 @@ a
explain extended select * from t3 where a >= all (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`)))
select * from t3 where a >= some (select b from t2 group by 1);
@@ -1674,7 +1674,7 @@ a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(/* select#2 */ select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`)))
select * from t3 where NULL >= any (select b from t2);
@@ -2867,13 +2867,13 @@ drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (select * from t1) = 1;
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (1,2) = (select a from t1);
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
select (select a from t1) = (1,2);
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
@@ -3733,7 +3733,7 @@ from t1' at line 1
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
@@ -6111,7 +6111,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE sq4_alias1 system NULL NULL NULL NULL 0 Const row not found
SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
@@ -6125,7 +6125,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3 ) AS alias3;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
@@ -6711,7 +6711,7 @@ CREATE TABLE t2 (b INT);
EXPLAIN
SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t2 system NULL NULL NULL NULL 0 Const row not found
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -7205,6 +7205,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result
index 7ba77e60e42..1f8946d3de9 100644
--- a/mysql-test/r/system_mysql_db.result
+++ b/mysql-test/r/system_mysql_db.result
@@ -29,6 +29,7 @@ time_zone_leap_second
time_zone_name
time_zone_transition
time_zone_transition_type
+transaction_registry
user
show create table db;
Table Create Table
@@ -55,6 +56,7 @@ db CREATE TABLE `db` (
`Execute_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',
+ `Delete_history_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
PRIMARY KEY (`Host`,`Db`,`User`),
KEY `User` (`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges'
@@ -118,6 +120,7 @@ user CREATE TABLE `user` (
`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',
+ `Delete_history_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,
@@ -152,7 +155,7 @@ tables_priv CREATE TABLE `tables_priv` (
`Table_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
`Grantor` char(141) COLLATE utf8_bin NOT NULL DEFAULT '',
`Timestamp` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
- `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') CHARACTER SET utf8 NOT NULL DEFAULT '',
+ `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows') CHARACTER SET utf8 NOT NULL DEFAULT '',
`Column_priv` set('Select','Insert','Update','References') CHARACTER SET utf8 NOT NULL DEFAULT '',
PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`),
KEY `Grantor` (`Grantor`)
@@ -214,12 +217,13 @@ proc CREATE TABLE `proc` (
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`db_collation` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`body_utf8` longblob DEFAULT NULL,
+ `aggregate` enum('NONE','GROUP') NOT NULL DEFAULT 'NONE',
PRIMARY KEY (`db`,`name`,`type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Stored Procedures'
show create table event;
@@ -239,7 +243,7 @@ event CREATE TABLE `event` (
`ends` datetime DEFAULT NULL,
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`originator` int(10) unsigned NOT NULL,
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
diff --git a/mysql-test/r/system_mysql_db_fix40123.result b/mysql-test/r/system_mysql_db_fix40123.result
index 7ba77e60e42..1f8946d3de9 100644
--- a/mysql-test/r/system_mysql_db_fix40123.result
+++ b/mysql-test/r/system_mysql_db_fix40123.result
@@ -29,6 +29,7 @@ time_zone_leap_second
time_zone_name
time_zone_transition
time_zone_transition_type
+transaction_registry
user
show create table db;
Table Create Table
@@ -55,6 +56,7 @@ db CREATE TABLE `db` (
`Execute_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',
+ `Delete_history_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
PRIMARY KEY (`Host`,`Db`,`User`),
KEY `User` (`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges'
@@ -118,6 +120,7 @@ user CREATE TABLE `user` (
`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',
+ `Delete_history_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,
@@ -152,7 +155,7 @@ tables_priv CREATE TABLE `tables_priv` (
`Table_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
`Grantor` char(141) COLLATE utf8_bin NOT NULL DEFAULT '',
`Timestamp` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
- `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') CHARACTER SET utf8 NOT NULL DEFAULT '',
+ `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows') CHARACTER SET utf8 NOT NULL DEFAULT '',
`Column_priv` set('Select','Insert','Update','References') CHARACTER SET utf8 NOT NULL DEFAULT '',
PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`),
KEY `Grantor` (`Grantor`)
@@ -214,12 +217,13 @@ proc CREATE TABLE `proc` (
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`db_collation` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`body_utf8` longblob DEFAULT NULL,
+ `aggregate` enum('NONE','GROUP') NOT NULL DEFAULT 'NONE',
PRIMARY KEY (`db`,`name`,`type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Stored Procedures'
show create table event;
@@ -239,7 +243,7 @@ event CREATE TABLE `event` (
`ends` datetime DEFAULT NULL,
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`originator` int(10) unsigned NOT NULL,
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
diff --git a/mysql-test/r/system_mysql_db_fix50030.result b/mysql-test/r/system_mysql_db_fix50030.result
index ad74cf6a09d..7e64f004495 100644
--- a/mysql-test/r/system_mysql_db_fix50030.result
+++ b/mysql-test/r/system_mysql_db_fix50030.result
@@ -29,6 +29,7 @@ time_zone_leap_second
time_zone_name
time_zone_transition
time_zone_transition_type
+transaction_registry
user
show create table db;
Table Create Table
@@ -55,6 +56,7 @@ db CREATE TABLE `db` (
`Execute_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',
+ `Delete_history_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
PRIMARY KEY (`Host`,`Db`,`User`),
KEY `User` (`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges'
@@ -118,6 +120,7 @@ user CREATE TABLE `user` (
`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',
+ `Delete_history_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,
@@ -152,7 +155,7 @@ tables_priv CREATE TABLE `tables_priv` (
`Table_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
`Grantor` char(141) COLLATE utf8_bin NOT NULL DEFAULT '',
`Timestamp` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
- `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') CHARACTER SET utf8 NOT NULL DEFAULT '',
+ `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows') CHARACTER SET utf8 NOT NULL DEFAULT '',
`Column_priv` set('Select','Insert','Update','References') CHARACTER SET utf8 NOT NULL DEFAULT '',
PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`),
KEY `Grantor` (`Grantor`)
@@ -214,12 +217,13 @@ proc CREATE TABLE `proc` (
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`db_collation` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`body_utf8` longblob DEFAULT NULL,
+ `aggregate` enum('NONE','GROUP') NOT NULL DEFAULT 'NONE',
PRIMARY KEY (`db`,`name`,`type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Stored Procedures'
show create table event;
@@ -239,7 +243,7 @@ event CREATE TABLE `event` (
`ends` datetime DEFAULT NULL,
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`originator` int(10) unsigned NOT NULL,
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
diff --git a/mysql-test/r/system_mysql_db_fix50117.result b/mysql-test/r/system_mysql_db_fix50117.result
index 7ba77e60e42..1f8946d3de9 100644
--- a/mysql-test/r/system_mysql_db_fix50117.result
+++ b/mysql-test/r/system_mysql_db_fix50117.result
@@ -29,6 +29,7 @@ time_zone_leap_second
time_zone_name
time_zone_transition
time_zone_transition_type
+transaction_registry
user
show create table db;
Table Create Table
@@ -55,6 +56,7 @@ db CREATE TABLE `db` (
`Execute_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',
+ `Delete_history_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
PRIMARY KEY (`Host`,`Db`,`User`),
KEY `User` (`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges'
@@ -118,6 +120,7 @@ user CREATE TABLE `user` (
`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',
+ `Delete_history_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,
@@ -152,7 +155,7 @@ tables_priv CREATE TABLE `tables_priv` (
`Table_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
`Grantor` char(141) COLLATE utf8_bin NOT NULL DEFAULT '',
`Timestamp` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
- `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') CHARACTER SET utf8 NOT NULL DEFAULT '',
+ `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows') CHARACTER SET utf8 NOT NULL DEFAULT '',
`Column_priv` set('Select','Insert','Update','References') CHARACTER SET utf8 NOT NULL DEFAULT '',
PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`),
KEY `Grantor` (`Grantor`)
@@ -214,12 +217,13 @@ proc CREATE TABLE `proc` (
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`db_collation` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`body_utf8` longblob DEFAULT NULL,
+ `aggregate` enum('NONE','GROUP') NOT NULL DEFAULT 'NONE',
PRIMARY KEY (`db`,`name`,`type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Stored Procedures'
show create table event;
@@ -239,7 +243,7 @@ event CREATE TABLE `event` (
`ends` datetime DEFAULT NULL,
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`originator` int(10) unsigned NOT NULL,
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
diff --git a/mysql-test/r/thread_id_overflow.result b/mysql-test/r/thread_id_overflow.result
new file mode 100644
index 00000000000..8303debb246
--- /dev/null
+++ b/mysql-test/r/thread_id_overflow.result
@@ -0,0 +1,23 @@
+connect con1, localhost,root;
+disconnect con1;
+connect con2, localhost,root;
+connection con2;
+connection default;
+SET @orig_debug=@@debug_dbug;
+SET GLOBAL DEBUG_DBUG='+d,thread_id_overflow';
+connect con3, localhost,root;
+connection con3;
+SELECT CONNECTION_ID();
+CONNECTION_ID()
+4294967294
+connection default;
+SET GLOBAL DEBUG_DBUG=@orig_debug;
+connect con4, localhost,root;
+connection con4;
+select IF(connection_id() - max_id = 1,'Good','Bad') as result;
+result
+Good
+disconnect con4;
+disconnect con3;
+disconnect con2;
+connection default;
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 2b843f68499..8473b3bb90d 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -2125,7 +2125,7 @@ SHOW TRIGGERS IN db1;
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
trg1 INSERT t2 CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERTINTOt1 VALUES (1) BEFORE # STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci latin1_swedish_ci
INSERT INTO t2 VALUES (1);
-ERROR 42000: Trigger 'trg1' has an error in its body: '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 '(1)' at line 1'
+ERROR 42000: Trigger 'trg1' has an error in its body: '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 'VALUES (1)' at line 1'
SELECT * FROM t1;
b
# Work around Bug#45235
@@ -2329,6 +2329,23 @@ DROP TRIGGER t1_bi;
DROP TABLE t1;
SET TIMESTAMP=DEFAULT;
set time_zone= @@global.time_zone;
+#
+# MDEV-13936: Server crashes in Time_and_counter_tracker::incr_loops
+#
+CREATE TABLE t1 (i INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE RAND() > 0.5;
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int);
+create trigger trg after insert on t2 for each row
+INSERT INTO t3 SELECT MAX(i) FROM v1 UNION SELECT MAX(i) FROM v1;
+drop table t1;
+insert into t2 value (2);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (i INT);
+insert into t2 value (2);
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+End of 10.1 tests.
create table t1 (i int);
create trigger tr1 after insert on t1 for each row set @a=@a+1;
create trigger tr2 after insert on t1 for each row set @a=@a+1;
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 95e421821c1..74b761a2e8f 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -1218,5 +1218,86 @@ a
DROP TABLE t1;
SET timestamp=DEFAULT;
#
+# MDEV-15310 Range optimizer does not work well for "WHERE temporal_column NOT IN (const_list)"
+#
+#
+# DATETIME(0)
+#
+CREATE TABLE t1 (a DATETIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:02', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:03', 'yes');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01','2001-01-01 23:00:02');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 6 NULL 5 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01','2001-01-01 23:00:02');
+a filler
+2001-01-01 23:00:03 yes
+2001-01-01 23:00:04 yes
+DROP TABLE t1;
+#
+# DATETIME(1)
+#
+CREATE TABLE t1 (a DATETIME(1), filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:02.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:03.1', 'yes');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:04.1', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01.1','2001-01-01 23:00:02.1');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 7 NULL 5 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01.1','2001-01-01 23:00:02.1');
+a filler
+2001-01-01 23:00:03.1 yes
+2001-01-01 23:00:04.1 yes
+DROP TABLE t1;
+#
# End of 10.3 tests
#
diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result
index 1258de317ec..ae72619b5ae 100644
--- a/mysql-test/r/type_set.result
+++ b/mysql-test/r/type_set.result
@@ -352,3 +352,9 @@ EXPLAIN SELECT * FROM t1 WHERE a='1.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
DROP TABLE t1;
+#
+# MDEV-11155 Bad error message when creating a SET column with comma and non-ASCII characters
+#
+SET NAMES utf8;
+CREATE TABLE t1 (a SET('a,bü'));
+ERROR 22007: Illegal set 'a,bü' value found during parsing
diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result
index 89718ea8363..3f34ae6c09b 100644
--- a/mysql-test/r/type_time.result
+++ b/mysql-test/r/type_time.result
@@ -1283,3 +1283,642 @@ a
10:20:32
DROP TABLE t1;
SET timestamp=DEFAULT;
+#
+# MDEV-15176 Storing DATETIME-alike VARCHAR data into TIME produces wrong results
+#
+SET sql_mode='';
+CREATE OR REPLACE TABLE t0 (d VARCHAR(64));
+INSERT INTO t0 VALUES ('0000-00-00 10:20:30');
+INSERT INTO t0 VALUES ('0000-00-01 10:20:30');
+INSERT INTO t0 VALUES ('0000-01-00 10:20:30');
+INSERT INTO t0 VALUES ('0000-01-01 10:20:30');
+INSERT INTO t0 VALUES ('0001-00-00 10:20:30');
+INSERT INTO t0 VALUES ('0001-00-01 10:20:30');
+INSERT INTO t0 VALUES ('0001-01-00 10:20:30');
+INSERT INTO t0 VALUES ('0001-01-01 10:20:30');
+SET @@global.mysql56_temporal_format=false;
+CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1));
+INSERT INTO t1 SELECT d,d,d FROM t0;
+Warnings:
+Note 1265 Data truncated for column 't0' at row 3
+Note 1265 Data truncated for column 't1' at row 3
+Note 1265 Data truncated for column 't0' at row 4
+Note 1265 Data truncated for column 't1' at row 4
+Note 1265 Data truncated for column 't0' at row 5
+Note 1265 Data truncated for column 't1' at row 5
+Note 1265 Data truncated for column 't0' at row 6
+Note 1265 Data truncated for column 't1' at row 6
+Note 1265 Data truncated for column 't0' at row 7
+Note 1265 Data truncated for column 't1' at row 7
+Note 1265 Data truncated for column 't0' at row 8
+Note 1265 Data truncated for column 't1' at row 8
+SELECT * FROM t1 ORDER BY d;
+d t0 t1
+0000-00-00 10:20:30 10:20:30 10:20:30.0
+0000-00-01 10:20:30 34:20:30 34:20:30.0
+0000-01-00 10:20:30 10:20:30 10:20:30.0
+0000-01-01 10:20:30 10:20:30 10:20:30.0
+0001-00-00 10:20:30 10:20:30 10:20:30.0
+0001-00-01 10:20:30 10:20:30 10:20:30.0
+0001-01-00 10:20:30 10:20:30 10:20:30.0
+0001-01-01 10:20:30 10:20:30 10:20:30.0
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1));
+INSERT INTO t1 SELECT CONCAT(d,'x'),CONCAT(d,'x'),CONCAT(d,'x') FROM t0;
+Warnings:
+Warning 1265 Data truncated for column 't0' at row 1
+Warning 1265 Data truncated for column 't1' at row 1
+Warning 1265 Data truncated for column 't0' at row 2
+Warning 1265 Data truncated for column 't1' at row 2
+Warning 1265 Data truncated for column 't0' at row 3
+Warning 1265 Data truncated for column 't1' at row 3
+Warning 1265 Data truncated for column 't0' at row 4
+Warning 1265 Data truncated for column 't1' at row 4
+Warning 1265 Data truncated for column 't0' at row 5
+Warning 1265 Data truncated for column 't1' at row 5
+Warning 1265 Data truncated for column 't0' at row 6
+Warning 1265 Data truncated for column 't1' at row 6
+Warning 1265 Data truncated for column 't0' at row 7
+Warning 1265 Data truncated for column 't1' at row 7
+Warning 1265 Data truncated for column 't0' at row 8
+Warning 1265 Data truncated for column 't1' at row 8
+SELECT * FROM t1;
+d t0 t1
+0000-00-00 10:20:30x 10:20:30 10:20:30.0
+0000-00-01 10:20:30x 34:20:30 34:20:30.0
+0000-01-00 10:20:30x 10:20:30 10:20:30.0
+0000-01-01 10:20:30x 10:20:30 10:20:30.0
+0001-00-00 10:20:30x 10:20:30 10:20:30.0
+0001-00-01 10:20:30x 10:20:30 10:20:30.0
+0001-01-00 10:20:30x 10:20:30 10:20:30.0
+0001-01-01 10:20:30x 10:20:30 10:20:30.0
+DROP TABLE t1;
+SET @@global.mysql56_temporal_format=true;
+CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1));
+INSERT INTO t1 SELECT d,d,d FROM t0;
+Warnings:
+Note 1265 Data truncated for column 't0' at row 3
+Note 1265 Data truncated for column 't1' at row 3
+Note 1265 Data truncated for column 't0' at row 4
+Note 1265 Data truncated for column 't1' at row 4
+Note 1265 Data truncated for column 't0' at row 5
+Note 1265 Data truncated for column 't1' at row 5
+Note 1265 Data truncated for column 't0' at row 6
+Note 1265 Data truncated for column 't1' at row 6
+Note 1265 Data truncated for column 't0' at row 7
+Note 1265 Data truncated for column 't1' at row 7
+Note 1265 Data truncated for column 't0' at row 8
+Note 1265 Data truncated for column 't1' at row 8
+SELECT * FROM t1;
+d t0 t1
+0000-00-00 10:20:30 10:20:30 10:20:30.0
+0000-00-01 10:20:30 34:20:30 34:20:30.0
+0000-01-00 10:20:30 10:20:30 10:20:30.0
+0000-01-01 10:20:30 10:20:30 10:20:30.0
+0001-00-00 10:20:30 10:20:30 10:20:30.0
+0001-00-01 10:20:30 10:20:30 10:20:30.0
+0001-01-00 10:20:30 10:20:30 10:20:30.0
+0001-01-01 10:20:30 10:20:30 10:20:30.0
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1));
+INSERT INTO t1 SELECT CONCAT(d,'x'),CONCAT(d,'x'),CONCAT(d,'x') FROM t0;
+Warnings:
+Warning 1265 Data truncated for column 't0' at row 1
+Warning 1265 Data truncated for column 't1' at row 1
+Warning 1265 Data truncated for column 't0' at row 2
+Warning 1265 Data truncated for column 't1' at row 2
+Warning 1265 Data truncated for column 't0' at row 3
+Warning 1265 Data truncated for column 't1' at row 3
+Warning 1265 Data truncated for column 't0' at row 4
+Warning 1265 Data truncated for column 't1' at row 4
+Warning 1265 Data truncated for column 't0' at row 5
+Warning 1265 Data truncated for column 't1' at row 5
+Warning 1265 Data truncated for column 't0' at row 6
+Warning 1265 Data truncated for column 't1' at row 6
+Warning 1265 Data truncated for column 't0' at row 7
+Warning 1265 Data truncated for column 't1' at row 7
+Warning 1265 Data truncated for column 't0' at row 8
+Warning 1265 Data truncated for column 't1' at row 8
+SELECT * FROM t1 ORDER BY d;
+d t0 t1
+0000-00-00 10:20:30x 10:20:30 10:20:30.0
+0000-00-01 10:20:30x 34:20:30 34:20:30.0
+0000-01-00 10:20:30x 10:20:30 10:20:30.0
+0000-01-01 10:20:30x 10:20:30 10:20:30.0
+0001-00-00 10:20:30x 10:20:30 10:20:30.0
+0001-00-01 10:20:30x 10:20:30 10:20:30.0
+0001-01-00 10:20:30x 10:20:30 10:20:30.0
+0001-01-01 10:20:30x 10:20:30 10:20:30.0
+DROP TABLE t1;
+DROP TABLE t0;
+SET sql_mode=DEFAULT;
+#
+# MDEV-15287 Bad result for LEAST/GREATEST(datetime_alike_string, time)
+#
+SELECT
+GREATEST('2010-01-01 10:10:10',TIME('-20:20:20')) AS gt_minus20_implicit,
+GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-20:20:20')) AS gt_minis20_explicit,
+GREATEST('2010-01-01 10:10:10',TIME('20:20:20')) AS gt_plus20_implicit,
+GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('20:20:20')) AS gt_plus20_explicit;
+gt_minus20_implicit 10:10:10.000000
+gt_minis20_explicit 10:10:10.000000
+gt_plus20_implicit 20:20:20.000000
+gt_plus20_explicit 20:20:20.000000
+SELECT
+HOUR(GREATEST('2010-01-01 10:10:10',TIME('-20:20:20'))) AS gt_minus20_implicit,
+HOUR(GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-20:20:20'))) AS gt_minis20_explicit,
+HOUR(GREATEST('2010-01-01 10:10:10',TIME('20:20:20'))) AS gt_plus20_implicit,
+HOUR(GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('20:20:20'))) AS gt_plus20_explicit;
+gt_minus20_implicit 10
+gt_minis20_explicit 10
+gt_plus20_implicit 20
+gt_plus20_explicit 20
+SELECT
+LEAST('2010-01-01 10:10:10',TIME('-20:20:20')) AS lt_minus20_implicit,
+LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-20:20:20')) AS lt_minus20_explicit,
+LEAST('2010-01-01 10:10:10',TIME('20:20:20')) AS lt_plus20_implicit,
+LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('20:20:20')) AS lt_plus20_explicit;
+lt_minus20_implicit -20:20:20.000000
+lt_minus20_explicit -20:20:20.000000
+lt_plus20_implicit 10:10:10.000000
+lt_plus20_explicit 10:10:10.000000
+SELECT
+HOUR(LEAST('2010-01-01 10:10:10',TIME('-20:20:20'))) AS lt_minus20_implicit,
+HOUR(LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-20:20:20'))) AS lt_minus20_explicit,
+HOUR(LEAST('2010-01-01 10:10:10',TIME('20:20:20'))) AS lt_plus20_implicit,
+HOUR(LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('20:20:20'))) AS lt_plus20_explicit;
+lt_minus20_implicit 20
+lt_minus20_explicit 20
+lt_plus20_implicit 10
+lt_plus20_explicit 10
+SELECT
+GREATEST('2010-01-01 10:10:10',TIME('-200:20:20')) AS gt_minus200_implicit,
+GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-200:20:20')) AS gt_minus200_explictit,
+GREATEST('2010-01-01 10:10:10',TIME('200:20:20')) AS gt_plus200_implicit,
+GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('200:20:20')) AS gt_plus200_explicit;
+gt_minus200_implicit 10:10:10.000000
+gt_minus200_explictit 10:10:10.000000
+gt_plus200_implicit 200:20:20.000000
+gt_plus200_explicit 200:20:20.000000
+SELECT
+HOUR(GREATEST('2010-01-01 10:10:10',TIME('-200:20:20'))) AS gt_minus200_implicit,
+HOUR(GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-200:20:20'))) AS gt_minus200_explictit,
+HOUR(GREATEST('2010-01-01 10:10:10',TIME('200:20:20'))) AS gt_plus200_implicit,
+HOUR(GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('200:20:20'))) AS gt_plus200_explicit;
+gt_minus200_implicit 10
+gt_minus200_explictit 10
+gt_plus200_implicit 200
+gt_plus200_explicit 200
+SELECT
+LEAST('2010-01-01 10:10:10',TIME('-200:20:20')) AS lt_minus200_implicit,
+LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-200:20:20')) AS lt_minus200_explictit,
+LEAST('2010-01-01 10:10:10',TIME('200:20:20')) AS lt_plus200_implicit,
+LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('200:20:20')) AS lt_plus200_explicit;
+lt_minus200_implicit -200:20:20.000000
+lt_minus200_explictit -200:20:20.000000
+lt_plus200_implicit 10:10:10.000000
+lt_plus200_explicit 10:10:10.000000
+SELECT
+HOUR(LEAST('2010-01-01 10:10:10',TIME('-200:20:20'))) AS lt_minus200_implicit,
+HOUR(LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-200:20:20'))) AS lt_minus200_explictit,
+HOUR(LEAST('2010-01-01 10:10:10',TIME('200:20:20'))) AS lt_plus200_implicit,
+HOUR(LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('200:20:20'))) AS lt_plus200_explicit;
+lt_minus200_implicit 200
+lt_minus200_explictit 200
+lt_plus200_implicit 10
+lt_plus200_explicit 10
+#
+# MDEV-15293 CAST(AS TIME) returns bad results for LAST_VALUE(),NAME_CONST(),SP variable
+#
+SELECT CAST(DATE'2001-01-01' AS TIME);
+CAST(DATE'2001-01-01' AS TIME)
+00:00:00
+SELECT CAST(LAST_VALUE(DATE'2001-01-01') AS TIME);
+CAST(LAST_VALUE(DATE'2001-01-01') AS TIME)
+00:00:00
+SELECT CAST(NAME_CONST('name',DATE'2001-01-01') AS TIME);
+CAST(NAME_CONST('name',DATE'2001-01-01') AS TIME)
+00:00:00
+BEGIN NOT ATOMIC
+DECLARE a DATE DEFAULT '2001-01-01';
+SELECT CAST(a AS TIME);
+END;
+$$
+CAST(a AS TIME)
+00:00:00
+CREATE OR REPLACE TABLE t1 (dt DATE,country VARCHAR(10), amount INT);
+INSERT INTO t1 VALUES ('2000-01-01','DE',102);
+SELECT
+dt, country, amount,
+FIRST_VALUE(dt) OVER () AS first,
+MINUTE(FIRST_VALUE(dt) OVER ()) AS m_first,
+LAST_VALUE(dt) OVER () AS last,
+MINUTE(LAST_VALUE(dt) OVER ()) AS m_last
+FROM t1
+ORDER BY country, dt;
+dt country amount first m_first last m_last
+2000-01-01 DE 102 2000-01-01 0 2000-01-01 0
+SELECT
+dt, country, amount,
+FIRST_VALUE(dt) OVER () AS first,
+CAST(FIRST_VALUE(dt) OVER () AS TIME) AS t_first,
+LAST_VALUE(dt) OVER () AS last,
+CAST(LAST_VALUE(dt) OVER () AS TIME) AS t_last
+FROM t1
+ORDER BY country, dt;
+dt country amount first t_first last t_last
+2000-01-01 DE 102 2000-01-01 00:00:00 2000-01-01 00:00:00
+DROP TABLE t1;
+#
+# MDEV-15310 Range optimizer does not work well for "WHERE temporal_column NOT IN (const_list)"
+#
+#
+# TIME(0), positive within 24 hour
+#
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:02', 'no');
+INSERT INTO t1 VALUES ('23:00:03', 'yes');
+INSERT INTO t1 VALUES ('23:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('23:00:01','23:00:02');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 4 NULL 5 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('23:00:01','23:00:02');
+a filler
+23:00:03 yes
+23:00:04 yes
+DROP TABLE t1;
+#
+# TIME(0), negative
+#
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:02', 'no');
+INSERT INTO t1 VALUES ('-23:00:03', 'yes');
+INSERT INTO t1 VALUES ('-23:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('-23:00:01','-23:00:02');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 4 NULL 4 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('-23:00:01','-23:00:02');
+a filler
+-23:00:04 yes
+-23:00:03 yes
+DROP TABLE t1;
+#
+# TIME(0), positive ouside 24 hours
+#
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:02', 'no');
+INSERT INTO t1 VALUES ('24:00:03', 'yes');
+INSERT INTO t1 VALUES ('24:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('24:00:01','24:00:02');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 4 NULL 5 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('24:00:01','24:00:02');
+a filler
+24:00:03 yes
+24:00:04 yes
+DROP TABLE t1;
+#
+# TIME(0), negative, ouside 24 hours
+#
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:02', 'no');
+INSERT INTO t1 VALUES ('-24:00:03', 'yes');
+INSERT INTO t1 VALUES ('-24:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('-24:00:01','-24:00:02');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 4 NULL 4 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('-24:00:01','-24:00:02');
+a filler
+-24:00:04 yes
+-24:00:03 yes
+DROP TABLE t1;
+#
+# TIME(0), positive, huge
+#
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:02', 'no');
+INSERT INTO t1 VALUES ('838:00:03', 'yes');
+INSERT INTO t1 VALUES ('838:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('838:00:01','838:00:02');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 4 NULL 5 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('838:00:01','838:00:02');
+a filler
+838:00:03 yes
+838:00:04 yes
+DROP TABLE t1;
+#
+# TIME(0), negative, huge
+#
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:02', 'no');
+INSERT INTO t1 VALUES ('-838:00:03', 'yes');
+INSERT INTO t1 VALUES ('-838:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('-838:00:01','-838:00:02');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 4 NULL 4 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('-838:00:01','-838:00:02');
+a filler
+-838:00:04 yes
+-838:00:03 yes
+DROP TABLE t1;
+#
+# TIME(1), positive within 24 hours
+#
+CREATE TABLE t1 (a TIME(1), filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:02.1', 'no');
+INSERT INTO t1 VALUES ('23:00:03.1', 'yes');
+INSERT INTO t1 VALUES ('23:00:04.1', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('23:00:01.1','23:00:02.1');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 5 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('23:00:01.1','23:00:02.1');
+a filler
+23:00:03.1 yes
+23:00:04.1 yes
+DROP TABLE t1;
+#
+# TIME(1), negative within 24 hours
+#
+CREATE TABLE t1 (a TIME(1), filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:02.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:03.1', 'yes');
+INSERT INTO t1 VALUES ('-23:00:04.1', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('-23:00:01.1','-23:00:02.1');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 4 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('-23:00:01.1','-23:00:02.1');
+a filler
+-23:00:04.1 yes
+-23:00:03.1 yes
+DROP TABLE t1;
+#
+# TIME(1), positive, huge
+#
+CREATE TABLE t1 (a TIME(1), filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:02.1', 'no');
+INSERT INTO t1 VALUES ('838:00:03.1', 'yes');
+INSERT INTO t1 VALUES ('838:00:04.1', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('838:00:01.1','838:00:02.1');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 5 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('838:00:01.1','838:00:02.1');
+a filler
+838:00:03.1 yes
+838:00:04.1 yes
+DROP TABLE t1;
+#
+# TIME(1), negative, huge
+#
+CREATE TABLE t1 (a TIME(1), filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:02.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:03.1', 'yes');
+INSERT INTO t1 VALUES ('-838:00:04.1', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('-838:00:01.1','-838:00:02.1');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 4 Using index condition
+SELECT * FROM t1 WHERE a NOT IN ('-838:00:01.1','-838:00:02.1');
+a filler
+-838:00:04.1 yes
+-838:00:03.1 yes
+DROP TABLE t1;
diff --git a/mysql-test/r/type_time_6065.result b/mysql-test/r/type_time_6065.result
index 341fc9fe98e..56de96870b6 100644
--- a/mysql-test/r/type_time_6065.result
+++ b/mysql-test/r/type_time_6065.result
@@ -2308,3 +2308,47 @@ col_int_nokey
1
DROP TABLE t1,t2,t3;
SET TIMESTAMP=0;
+#
+# MDEV-15262 Wrong results for SELECT..WHERE non_indexed_datetime_column=indexed_time_column
+#
+SET TIMESTAMP=UNIX_TIMESTAMP('2012-01-31 10:14:35');
+CREATE TABLE t1 (col_time_key TIME, KEY(col_time_key));
+CREATE TABLE t2 (col_datetime_key DATETIME);
+INSERT INTO t1 VALUES ('-760:00:00'),('760:00:00');
+INSERT INTO t1 VALUES ('-770:00:00'),('770:00:00');
+INSERT INTO t2 SELECT * FROM t1;
+SELECT * FROM t2 STRAIGHT_JOIN t1 IGNORE INDEX(col_time_key) WHERE col_time_key = col_datetime_key;
+col_datetime_key col_time_key
+2011-12-30 08:00:00 -760:00:00
+2012-03-02 16:00:00 760:00:00
+2011-12-29 22:00:00 -770:00:00
+2012-03-03 02:00:00 770:00:00
+SELECT * FROM t2 STRAIGHT_JOIN t1 FORCE INDEX (col_time_key) WHERE col_time_key = col_datetime_key;
+col_datetime_key col_time_key
+2011-12-29 22:00:00 -770:00:00
+2011-12-30 08:00:00 -760:00:00
+2012-03-02 16:00:00 760:00:00
+2012-03-03 02:00:00 770:00:00
+INSERT INTO t1 VALUES ('-838:59:59'),('838:59:59');
+INSERT INTO t2 VALUES (DATE_ADD(CURRENT_DATE, INTERVAL '-838:59:59' HOUR_SECOND));
+INSERT INTO t2 VALUES (DATE_ADD(CURRENT_DATE, INTERVAL '838:59:59' HOUR_SECOND));
+INSERT INTO t2 VALUES (DATE_ADD(CURRENT_DATE, INTERVAL '-839:00:00' HOUR_SECOND));
+INSERT INTO t2 VALUES (DATE_ADD(CURRENT_DATE, INTERVAL '839:00:00' HOUR_SECOND));
+SELECT * FROM t2 STRAIGHT_JOIN t1 IGNORE INDEX(col_time_key) WHERE col_time_key = col_datetime_key;
+col_datetime_key col_time_key
+2011-12-30 08:00:00 -760:00:00
+2012-03-02 16:00:00 760:00:00
+2011-12-29 22:00:00 -770:00:00
+2012-03-03 02:00:00 770:00:00
+2011-12-27 01:00:01 -838:59:59
+2012-03-05 22:59:59 838:59:59
+SELECT * FROM t2 STRAIGHT_JOIN t1 FORCE INDEX (col_time_key) WHERE col_time_key = col_datetime_key;
+col_datetime_key col_time_key
+2011-12-29 22:00:00 -770:00:00
+2011-12-30 08:00:00 -760:00:00
+2012-03-02 16:00:00 760:00:00
+2012-03-03 02:00:00 770:00:00
+2011-12-27 01:00:01 -838:59:59
+2012-03-05 22:59:59 838:59:59
+DROP TABLE t1, t2;
+SET TIMESTAMP=DEFAULT;
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index b193f032146..4e5f9312e03 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -1634,8 +1634,8 @@ UNION
SELECT a FROM t1
ORDER BY a;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
-2 UNION t1 system NULL NULL NULL NULL 0 0.00 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
+2 UNION t1 system NULL NULL NULL NULL 0 0.00 Const row not found
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 /* select#1 */ select NULL AS `a` from `test`.`t1` union /* select#2 */ select NULL AS `a` from `test`.`t1` order by `a`
@@ -2094,6 +2094,46 @@ avg(f) sub
31.5000 0
1.5000 1
drop table t1,t2,t3;
+#
+# MDEV-14715 Assertion `!table || (!table->read_set ||
+# bitmap_is_set(table->read_set, field_index))'
+# failed in Field_num::val_decimal
+#
+CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1, NULL),(3, 4);
+(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + sum(a))
+UNION
+(SELECT 2, 2);
+a f
+1 1
+3 3
+2 2
+(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1)
+UNION
+(SELECT 2, 2);
+a f
+1 1
+3 3
+2 2
+SELECT a, b FROM t1
+UNION
+(SELECT a, VAR_POP(a) AS f FROM v1 GROUP BY a ORDER BY b/a );
+a b
+1 NULL
+3 4.0000
+1 0.0000
+3 0.0000
+DROP TABLE t1;
+(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1)
+UNION
+(SELECT 2, 2);
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+DROP VIEW v1;
+(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1)
+UNION
+(SELECT 2, 2);
+ERROR 42S02: Table 'test.v1' doesn't exist
End of 5.5 tests
#
# WL#1763 Avoid creating temporary table in UNION ALL
diff --git a/mysql-test/r/update_innodb.result b/mysql-test/r/update_innodb.result
index 5fcc584035a..0a85c6dab3e 100644
--- a/mysql-test/r/update_innodb.result
+++ b/mysql-test/r/update_innodb.result
@@ -30,6 +30,16 @@ UPDATE t1 a JOIN t2 b ON a.c1 = b.c1 JOIN v1 vw ON b.c2 = vw.c1 JOIN t3 del ON v
drop view v1;
drop table t1,t2,t3,t4;
#
+# MDEV-14862: Server crashes in Bitmap<64u>::merge / add_key_field
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE TABLE t2 (b INT) ENGINE=InnoDB;
+DELETE FROM v1 WHERE a IN ( SELECT a FROM t2 );
+DELETE FROM v1 WHERE (a,a) IN ( SELECT a,a FROM t2 );
+drop view v1;
+drop table t1,t2;
+#
# MDEV-10232 Scalar result of subquery changes after adding an outer select stmt
#
CREATE TABLE t1 (
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 635323a5867..e61e2d2663d 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -152,14 +152,14 @@ v4 VIEW
v5 VIEW
v6 VIEW
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 5 9 45 # 1024 0 NULL # # # latin1_swedish_ci NULL
-v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
-v2 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
-v3 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
-v4 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
-v5 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
-v6 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 5 9 45 # 1024 0 NULL # # # latin1_swedish_ci NULL # N
+v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW # NULL
+v2 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW # NULL
+v3 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW # NULL
+v4 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW # NULL
+v5 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW # NULL
+v6 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW # NULL
drop view v1,v2,v3,v4,v5,v6;
create view v1 (c,d,e,f) as select a,b,
a in (select a+2 from t1), a = all (select a from t1) from t1;
@@ -838,9 +838,9 @@ drop function x1;
select * from v1;
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
-v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL # N
+v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them # NULL
Warnings:
Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
drop view v1;
@@ -851,9 +851,9 @@ alter table t1 change a aa int;
select * from v1;
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
show table status;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
-v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL # N
+v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them # NULL
Warnings:
Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
show create view v1;
@@ -2934,10 +2934,10 @@ CREATE TABLE t1 (s1 int);
CREATE VIEW v1 AS SELECT * FROM t1;
EXPLAIN SELECT * 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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
EXPLAIN SELECT * FROM v1;
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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
INSERT INTO t1 VALUES (1), (3), (2);
EXPLAIN SELECT * FROM t1 t WHERE t.s1+1 < (SELECT MAX(t1.s1) FROM t1);
id select_type table type possible_keys key key_len ref rows Extra
@@ -4609,7 +4609,7 @@ WHERE t4.a >= t1.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
-2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 0.00 const row not found
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 0.00 Const row not found
2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
@@ -4625,7 +4625,7 @@ WHERE t4.a >= v1.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
-2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 0.00 const row not found
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 0.00 Const row not found
2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1276 Field or reference 'v1.a' of SELECT #2 was resolved in SELECT #1
@@ -4657,7 +4657,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00
-2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1276 Field or reference 'test.t4.b' of SELECT #2 was resolved in SELECT #1
Note 1003 /* select#1 */ select 0 AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t4` where `test`.`t4`.`c` <= <expr_cache><`test`.`t4`.`b`>((/* select#2 */ select 0 from dual where 7 > `test`.`t4`.`b`))
@@ -4674,7 +4674,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00
-2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 Const row not found
Warnings:
Note 1276 Field or reference 'v4.b' of SELECT #2 was resolved in SELECT #1
Note 1003 /* select#1 */ select 0 AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t4` where `test`.`t4`.`c` <= <expr_cache><`test`.`t4`.`b`>((/* select#2 */ select 0 from dual where 7 > `test`.`t4`.`b`))
@@ -5166,7 +5166,7 @@ CREATE TABLE t4 (i4 INT);
INSERT INTO t4 VALUES (1),(2);
DROP VIEW IF EXISTS v1;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
CREATE VIEW v1 AS select coalesce(j1,i3) AS v1_field1 from t2 join t3 left join t1 on ( i1 = i2 );
CREATE VIEW v2 AS select v1_field1 from t4 join v1;
prepare my_stmt from "select v1_field1 from v2";
@@ -5227,114 +5227,6 @@ execute stmt1;
deallocate prepare stmt1;
drop view v1,v2;
drop table t1,t2;
-#
-# MDEV-6251: SIGSEGV in query optimizer (in set_check_materialized
-# with MERGE view)
-#
-CREATE TABLE t1 (a1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t2 (b1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t3 (c1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t4 (d1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t5 (e1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t6 (f1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE OR REPLACE view v1 AS
-SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-;
-SELECT 1
-FROM (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t1)
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t2) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t3) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t4) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t5) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t6) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t7) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t8) ON 1=1
-;
-1
-SELECT 1
-FROM (v1 t1)
-LEFT OUTER JOIN (v1 t2) ON 1=1
-LEFT OUTER JOIN (v1 t3) ON 1=1
-LEFT OUTER JOIN (v1 t4) ON 1=1
-LEFT OUTER JOIN (v1 t5) ON 1=1
-LEFT OUTER JOIN (v1 t6) ON 1=1
-LEFT OUTER JOIN (v1 t7) ON 1=1
-LEFT OUTER JOIN (v1 t8) ON 1=1
-;
-1
-drop view v1;
-drop table t1,t2,t3,t4,t5,t6;
# -----------------------------------------------------------------
# -- End of 5.3 tests.
# -----------------------------------------------------------------
@@ -5621,6 +5513,20 @@ PREPARE stmt FROM 'REPLACE INTO v2 SELECT a FROM t3';
ERROR HY000: Can not insert into join view 'test.v2' without fields list
drop view v1,v2;
drop table t3;
+#
+# MDEV-14619: VIEW and GROUP_CONCAT
+#
+CREATE TABLE t1 (str text);
+INSERT INTO t1 VALUES ("My"),("SQL");
+CREATE VIEW v1 AS SELECT GROUP_CONCAT(str SEPARATOR '\\') FROM t1;
+SELECT * FROM v1;
+GROUP_CONCAT(str SEPARATOR '\\')
+My\SQL
+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 group_concat(`t1`.`str` separator '\\') AS `GROUP_CONCAT(str SEPARATOR '\\')` from `t1` latin1 latin1_swedish_ci
+drop view v1;
+drop table t1;
# -----------------------------------------------------------------
# -- End of 5.5 tests.
# -----------------------------------------------------------------
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index 04ad19c5ddc..82594128d85 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -144,7 +144,7 @@ revoke select on mysqltest.v5 from mysqltest_1@localhost;
connection user1;
explain select c from mysqltest.v1;
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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
show create view mysqltest.v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select `mysqltest`.`t1`.`a` + 1 AS `c`,`mysqltest`.`t1`.`b` + 1 AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
@@ -167,13 +167,13 @@ grant show view on mysqltest.* to mysqltest_1@localhost;
connection user1;
explain select c from mysqltest.v1;
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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
show create view mysqltest.v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select `mysqltest`.`t1`.`a` + 1 AS `c`,`mysqltest`.`t1`.`b` + 1 AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
explain select c from mysqltest.v2;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
show create view mysqltest.v2;
View Create View character_set_client collation_connection
@@ -1190,7 +1190,7 @@ select * from v1;
i
explain select * from v1;
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
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
disconnect test11765687;
... as eugene
connect test11765687,localhost,eugene,,mysqltest1;
@@ -1238,12 +1238,12 @@ select k from t3;
k
explain select k from t3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t3 system NULL NULL NULL NULL 0 Const row not found
select * from v3;
k
explain select * from v3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t3 system NULL NULL NULL NULL 0 Const row not found
disconnect test11765687;
... as inga
connect test11765687,localhost,inga,,mysqltest1;
@@ -1284,8 +1284,8 @@ select * from v2;
i j
explain select * from v2;
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
-1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 Const row not found
disconnect test11765687;
... as noam
connect test11765687,localhost,noam,,mysqltest1;
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
index 5d805ac572a..410ea9b28e7 100644
--- a/mysql-test/r/warnings.result
+++ b/mysql-test/r/warnings.result
@@ -353,7 +353,7 @@ ERROR 23000: Duplicate entry '11' for key 'a'
SHOW WARNINGS;
Level Code Message
-Note 4092 At line 4 in test.f1
+Note 4094 At line 4 in test.f1
Error 1062 Duplicate entry '11' for key 'a'
DROP TABLE t1;
diff --git a/mysql-test/r/win.result b/mysql-test/r/win.result
index 6434b26dba1..dd4d09bb1eb 100644
--- a/mysql-test/r/win.result
+++ b/mysql-test/r/win.result
@@ -1779,7 +1779,7 @@ EXPLAIN
"query_block": {
"select_id": 1,
"filesort": {
- "sort_key": "row_number() over ( order by t1.s1,t1.s2)",
+ "sort_key": "row_number() over ( order by t1.s1,t1.s2) desc",
"window_functions_computation": {
"sorts": {
"filesort": {
@@ -3274,5 +3274,31 @@ row_number() over (partition by i order by i) i
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;
+#
# Start of 10.3 tests
#
diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result
index fdcf25f3a12..5d78bb68c8c 100644
--- a/mysql-test/r/xa.result
+++ b/mysql-test/r/xa.result
@@ -60,6 +60,59 @@ a
20
disconnect con1;
connection default;
+xa start 'tr1';
+insert t1 values (40);
+xa end 'tr1';
+xa prepare 'tr1';
+xa recover format='SQL';
+formatID gtrid_length bqual_length data
+1 3 0 'tr1'
+xa rollback 'tr1';
+xa start 'tr1', 'bq';
+insert t1 values (40);
+xa end 'tr1', 'bq';
+xa prepare 'tr1', 'bq';
+xa recover format='SQL';
+formatID gtrid_length bqual_length data
+1 3 2 'tr1','bq'
+xa rollback 'tr1', 'bq';
+xa start 'tr1', 'bq', 3;
+insert t1 values (40);
+xa end 'tr1', 'bq', 3;
+xa prepare 'tr1', 'bq', 3;
+xa recover format='SQL';
+formatID gtrid_length bqual_length data
+3 3 2 'tr1','bq',3
+xa rollback 'tr1', 'bq', 3;
+xa start 'tr1#$';
+insert t1 values (40);
+xa end 'tr1#$';
+xa prepare 'tr1#$';
+xa recover format='SQL';
+formatID gtrid_length bqual_length data
+1 5 0 X'7472312324'
+xa rollback 'tr1#$';
+xa start 'tr1#$', 'bq';
+insert t1 values (40);
+xa end 'tr1#$', 'bq';
+xa prepare 'tr1#$', 'bq';
+xa recover format='SQL';
+formatID gtrid_length bqual_length data
+1 5 2 X'7472312324',X'6271'
+xa rollback 'tr1#$', 'bq';
+xa start 'tr1#$', 'bq', 3;
+insert t1 values (40);
+xa end 'tr1#$', 'bq', 3;
+xa prepare 'tr1#$', 'bq', 3;
+xa recover format='RAW';
+formatID gtrid_length bqual_length data
+3 5 2 tr1#$bq
+xa recover format='PLAIN';
+ERROR HY000: Unknown XA RECOVER format name: 'PLAIN'
+xa recover format='SQL';
+formatID gtrid_length bqual_length data
+3 5 2 X'7472312324',X'6271',3
+xa rollback 'tr1#$', 'bq', 3;
drop table t1;
drop table if exists t1;
create table t1(a int, b int, c varchar(20), primary key(a)) engine = innodb;
@@ -228,6 +281,17 @@ a
1
DROP TABLE t1;
#
+# MDEV-14609 XA Transction unable to ROLLBACK TO SAVEPOINT
+#
+CREATE TABLE t1 (c1 INT) ENGINE=INNODB;
+XA START 'xa1';
+SAVEPOINT savepoint1;
+INSERT INTO t1 (c1) VALUES (1),(2),(3),(4);
+ROLLBACK TO SAVEPOINT savepoint1;
+XA END 'xa1';
+XA ROLLBACK 'xa1';
+DROP TABLE t1;
+#
# Bug#12352846 - TRANS_XA_START(THD*):
# ASSERTION THD->TRANSACTION.XID_STATE.XID.IS_NULL()
# FAILED
diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result
index 23a2f8b62b8..2cd70c08a94 100644
--- a/mysql-test/r/xml.result
+++ b/mysql-test/r/xml.result
@@ -1274,6 +1274,18 @@ c1 c2
2 b2
DROP TABLE t1;
#
+# MDEV-15118 ExtractValue(xml,something_complex) does not work
+#
+CREATE TABLE t1 (a TEXT);
+INSERT INTO t1 VALUES (CONCAT('<a>aaa</a>'));
+SELECT ExtractValue(a, '/a') AS a FROM t1;
+a
+aaa
+SELECT ExtractValue(a, FROM_BASE64(TO_BASE64('/a'))) AS a FROM t1;
+a
+aaa
+DROP TABLE t1;
+#
# End of 10.0 tests
#
#
diff --git a/mysql-test/std_data/loaddata/mdev14628a.xml b/mysql-test/std_data/loaddata/mdev14628a.xml
new file mode 100644
index 00000000000..34ee7336a5a
--- /dev/null
+++ b/mysql-test/std_data/loaddata/mdev14628a.xml
@@ -0,0 +1,4 @@
+<list>
+ <row a="1" b="bbb1"/>
+ <row b="bbb2"/>
+</list>
diff --git a/mysql-test/std_data/loaddata/mdev14628b.xml b/mysql-test/std_data/loaddata/mdev14628b.xml
new file mode 100644
index 00000000000..2ea02d2a35f
--- /dev/null
+++ b/mysql-test/std_data/loaddata/mdev14628b.xml
@@ -0,0 +1,3 @@
+<list>
+ <row id="1"/>
+</list>
diff --git a/mysql-test/std_data/mdev11084.frm b/mysql-test/std_data/mdev11084.frm
new file mode 100644
index 00000000000..21ee498c1ba
--- /dev/null
+++ b/mysql-test/std_data/mdev11084.frm
Binary files differ
diff --git a/mysql-test/std_data/mdev11084.par b/mysql-test/std_data/mdev11084.par
new file mode 100644
index 00000000000..a5eef54fc01
--- /dev/null
+++ b/mysql-test/std_data/mdev11084.par
Binary files differ
diff --git a/mysql-test/std_data/mdev11084.part1.MYD b/mysql-test/std_data/mdev11084.part1.MYD
new file mode 100644
index 00000000000..139d2e06990
--- /dev/null
+++ b/mysql-test/std_data/mdev11084.part1.MYD
Binary files differ
diff --git a/mysql-test/std_data/mdev11084.part1.MYI b/mysql-test/std_data/mdev11084.part1.MYI
new file mode 100644
index 00000000000..a3e532a3a1a
--- /dev/null
+++ b/mysql-test/std_data/mdev11084.part1.MYI
Binary files differ
diff --git a/mysql-test/suite/binlog/r/binlog_base64_flag.result b/mysql-test/suite/binlog/r/binlog_base64_flag.result
index 735a27919ea..66cee19f13f 100644
--- a/mysql-test/suite/binlog/r/binlog_base64_flag.result
+++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result
@@ -9,7 +9,7 @@ BINLOG '
SVtYRxMBAAAAKQAAADQBAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE=
SVtYRxcBAAAAIgAAAFYBAAAQABAAAAAAAAEAAf/+AgAAAA==
';
-ERROR HY000: The BINLOG statement of type `Table_map` was not preceded by a format description BINLOG statement
+ERROR HY000: The BINLOG statement of type Table_map was not preceded by a format description BINLOG statement
select * from t1;
a
1
@@ -33,10 +33,10 @@ a
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
-# at 4
-<#>ROLLBACK/*!*/;
-# at 102
-<#>use `test`/*!*/;
+<#>
+ROLLBACK/*!*/;
+<#>
+use `test`/*!*/;
SET TIMESTAMP=1196959712/*!*/;
<#>SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=0/*!*/;
SET @@session.sql_mode=0/*!*/;
@@ -47,7 +47,11 @@ SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table t1 (a int) engine= myisam
/*!*/;
-# at 203
+<#>
+<#>
+<#>
+<#>
+<#>
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
diff --git a/mysql-test/suite/binlog/r/binlog_flush_binlogs_delete_domain.result b/mysql-test/suite/binlog/r/binlog_flush_binlogs_delete_domain.result
new file mode 100644
index 00000000000..99f2a57835f
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_flush_binlogs_delete_domain.result
@@ -0,0 +1,78 @@
+RESET MASTER;
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = ();
+and the command execution is effective thence rotates binlog as usual
+show binary logs;
+Log_name File_size
+master-bin.000001 #
+master-bin.000002 #
+Non-existed domain is warned, the command completes without rotation
+but with a warning
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (99);
+Warnings:
+Warning 1076 The gtid domain being deleted ('99') is not in the current binlog state
+show binary logs;
+Log_name File_size
+master-bin.000001 #
+master-bin.000002 #
+SET @@SESSION.gtid_domain_id=1;
+SET @@SESSION.server_id=1;
+CREATE TABLE t (a int);
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
+ERROR HY000: Could not delete gtid domain. Reason: binlog files may contain gtids from the domain ('1') being deleted. Make sure to first purge those files.
+FLUSH BINARY LOGS;
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
+ERROR HY000: Could not delete gtid domain. Reason: binlog files may contain gtids from the domain ('1') being deleted. Make sure to first purge those files.
+PURGE BINARY LOGS TO 'master-bin.000003';;
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
+Gtid_list of the current binlog does not contain '1':
+show binlog events in 'master-bin.000004' limit 1,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000004 # Gtid_list 1 # []
+But the previous log's Gtid_list may have it which explains a warning from the following command
+show binlog events in 'master-bin.000003' limit 1,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000003 # Gtid_list 1 # [1-1-1]
+Already deleted domain in Gtid_list of the earliest log is benign
+but may cause a warning
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
+Warnings:
+Warning 1076 The current gtid binlog state is incompatible with a former one missing gtids from the '1-1' domain-server pair which is referred to in the gtid list describing an earlier state. Ignore if the domain ('1') was already explicitly deleted.
+Warning 1076 The gtid domain being deleted ('1') is not in the current binlog state
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0);
+ERROR HY000: Could not delete gtid domain. Reason: binlog files may contain gtids from the domain ('1') being deleted. Make sure to first purge those files.
+FLUSH BINARY LOGS;
+PURGE BINARY LOGS TO 'master-bin.000005';
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0);
+Warnings:
+Warning 1076 The gtid domain being deleted ('0') is not in the current binlog state
+Gtid_list of the current binlog does not contain 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0:
+show binlog events in 'master-bin.000006' limit 1,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000006 # Gtid_list 1 # []
+SET @@SESSION.gtid_domain_id=1;;
+SET @@SESSION.server_id=1;
+SET @@SESSION.gtid_seq_no=1;
+INSERT INTO t SET a=1;
+SET @@SESSION.server_id=2;
+SET @@SESSION.gtid_seq_no=2;
+INSERT INTO t SET a=2;
+SET @@SESSION.gtid_domain_id=11;
+SET @@SESSION.server_id=11;
+SET @@SESSION.gtid_seq_no=11;
+INSERT INTO t SET a=11;
+SET @gtid_binlog_state_saved=@@GLOBAL.gtid_binlog_state;
+FLUSH BINARY LOGS;
+SET @@SESSION.gtid_domain_id=11;
+SET @@SESSION.server_id=11;
+SET @@SESSION.gtid_seq_no=1;
+INSERT INTO t SET a=1;
+SELECT @gtid_binlog_state_saved "as original state", @@GLOBAL.gtid_binlog_state as "out of order for 11 domain state";
+as original state out of order for 11 domain state
+1-1-1,1-2-2,11-11-11 1-1-1,1-2-2,11-11-1
+PURGE BINARY LOGS TO 'master-bin.000007';
+the following command succeeds with warnings
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
+Warnings:
+Warning 1076 The current gtid binlog state is incompatible with a former one having a gtid '11-11-1' which is less than the '11-11-11' of the gtid list describing an earlier state. The state may have been affected by manually injecting a lower sequence number gtid or via replication.
+DROP TABLE t;
+RESET MASTER;
diff --git a/mysql-test/suite/binlog/r/binlog_gtid_delete_domain_debug.result b/mysql-test/suite/binlog/r/binlog_gtid_delete_domain_debug.result
new file mode 100644
index 00000000000..b4627caceb2
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_gtid_delete_domain_debug.result
@@ -0,0 +1,6 @@
+SET @@SESSION.debug_dbug='+d,inject_binlog_delete_domain_init_error';
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (99);
+ERROR HY000: Could not delete gtid domain. Reason: injected error.
+SHOW WARNINGS;
+Level Code Message
+Error 1076 Could not delete gtid domain. Reason: injected error.
diff --git a/mysql-test/suite/binlog/r/binlog_killed.result b/mysql-test/suite/binlog/r/binlog_killed.result
index cda4e8ad6f4..ae851c38e5f 100644
--- a/mysql-test/suite/binlog/r/binlog_killed.result
+++ b/mysql-test/suite/binlog/r/binlog_killed.result
@@ -179,6 +179,95 @@ RELEASE_LOCK("a")
1
drop table t4;
drop function bug27563;
+FLUSH LOGS;
+connect con3, localhost, root,,;
+connection con3;
+MI: MyISAM, INNODB
+BEGIN;
+INSERT INTO t2 VALUES (NULL, 1);
+INSERT INTO t1 VALUES (NULL, 2);
+connection con1;
+KILL ID;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 # Format_desc # # SERVER_VERSION, BINLOG_VERSION
+master-bin.000002 # Gtid_list # # [#-#-#]
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Intvar # # INSERT_ID=3
+master-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (NULL, 1)
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Intvar # # INSERT_ID=4
+master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (NULL, 2)
+master-bin.000002 # Query # # ROLLBACK
+disconnect con3;
+connect con3, localhost, root,,;
+connection con3;
+IM: INNODB, MyISAM
+BEGIN;
+INSERT INTO t1 VALUES (NULL, 3);
+INSERT INTO t2 VALUES (NULL, 4);
+connection con1;
+KILL ID;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Intvar # # INSERT_ID=4
+master-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (NULL, 4)
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Intvar # # INSERT_ID=5
+master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (NULL, 3)
+master-bin.000002 # Query # # ROLLBACK
+disconnect con3;
+connect con3, localhost, root,,;
+connection con3;
+IMI: INNODB, MyISAM, INNODB
+BEGIN;
+INSERT INTO t1 VALUES (NULL, 5);
+INSERT INTO t2 VALUES (NULL, 6);
+INSERT INTO t1 VALUES (NULL, 7);
+connection con1;
+KILL ID;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Intvar # # INSERT_ID=5
+master-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (NULL, 6)
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Intvar # # INSERT_ID=6
+master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (NULL, 5)
+master-bin.000002 # Intvar # # INSERT_ID=7
+master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (NULL, 7)
+master-bin.000002 # Query # # ROLLBACK
+disconnect con3;
+connect con3, localhost, root,,;
+connection con3;
+MI2: MyISAM, INNODB, MyISAM, INNODB
+BEGIN;
+INSERT INTO t2 VALUES (NULL, 8);
+INSERT INTO t1 VALUES (NULL, 9);
+INSERT INTO t2 VALUES (NULL, 10);
+INSERT INTO t1 VALUES (NULL, 11);
+connection con1;
+KILL ID;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Intvar # # INSERT_ID=6
+master-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (NULL, 8)
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Intvar # # INSERT_ID=7
+master-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (NULL, 10)
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Intvar # # INSERT_ID=8
+master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (NULL, 9)
+master-bin.000002 # Intvar # # INSERT_ID=9
+master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (NULL, 11)
+master-bin.000002 # Query # # ROLLBACK
connection default;
disconnect con1;
disconnect con2;
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
index 47069b81a15..4422a00335b 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
@@ -327,6 +327,7 @@ INSERT INTO t2 SET a=1;
INSERT INTO t2 SET b=1;
UPDATE t1, t2 SET t1.a=10, t2.a=20;
DROP TABLE t1,t2;
+flush logs;
INSERT INTO t1dec102 VALUES (-999.99);
INSERT INTO t1dec102 VALUES (0);
INSERT INTO t1dec102 VALUES (999.99);
@@ -386,6 +387,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'0' /* BIT(1) meta=1 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/*!*/;
@@ -406,6 +408,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'1' /* BIT(1) meta=1 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/*!*/;
@@ -442,6 +445,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'0000001' /* BIT(7) meta=7 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/*!*/;
@@ -462,6 +466,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'0000010' /* BIT(7) meta=7 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/*!*/;
@@ -482,6 +487,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'0000100' /* BIT(7) meta=7 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/*!*/;
@@ -502,6 +508,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'0001000' /* BIT(7) meta=7 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/*!*/;
@@ -522,6 +529,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'0010000' /* BIT(7) meta=7 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/*!*/;
@@ -542,6 +550,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'0100000' /* BIT(7) meta=7 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/*!*/;
@@ -562,6 +571,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'1000000' /* BIT(7) meta=7 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/*!*/;
@@ -582,6 +592,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'1111111' /* BIT(7) meta=7 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/*!*/;
@@ -602,6 +613,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=b'1111111' /* BIT(7) meta=7 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/*!*/;
@@ -624,6 +636,7 @@ BEGIN
### @1=b'0010000' /* BIT(7) meta=7 nullable=1 is_null=0 */
### SET
### @1=b'0001111' /* BIT(7) meta=7 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/*!*/;
@@ -661,6 +674,7 @@ BEGIN
### SET
### @1=b'00010010010010001001' /* BIT(20) meta=516 nullable=1 is_null=0 */
### @2='ab' /* STRING(2) meta=65026 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/*!*/;
@@ -697,6 +711,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'0000000000000000000000000000000000000000000000000000000000000001' /* BIT(64) meta=2048 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/*!*/;
@@ -717,6 +732,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'0000000000000000000000000000000000000000000000000000000000000010' /* BIT(64) meta=2048 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/*!*/;
@@ -737,6 +753,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'0000000000000000000000000000000000000000000000000000000010000000' /* BIT(64) meta=2048 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/*!*/;
@@ -757,6 +774,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'1111111111111111111111111111111111111111111111111111111111111111' /* BIT(64) meta=2048 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/*!*/;
@@ -799,6 +817,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=3 /* TINYINT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -819,6 +838,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=-128 (128) /* TINYINT meta=0 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/*!*/;
@@ -841,6 +861,7 @@ BEGIN
### @1=1 /* TINYINT meta=0 nullable=1 is_null=0 */
### SET
### @1=2 /* TINYINT meta=0 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/*!*/;
@@ -861,6 +882,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=-128 (128) /* TINYINT meta=0 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/*!*/;
@@ -900,6 +922,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=-1 (255) /* TINYINT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -920,6 +943,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=-1 (255) /* TINYINT meta=0 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/*!*/;
@@ -956,6 +980,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=1 /* TINYINT meta=0 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/*!*/;
@@ -976,6 +1001,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=1 /* TINYINT meta=0 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/*!*/;
@@ -1012,6 +1038,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=1234 /* SHORTINT meta=0 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/*!*/;
@@ -1032,6 +1059,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=1234 /* SHORTINT meta=0 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/*!*/;
@@ -1071,6 +1099,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=-1 (65535) /* SHORTINT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1093,6 +1122,7 @@ BEGIN
### @1=-32768 (32768) /* SHORTINT meta=0 nullable=1 is_null=0 */
### SET
### @1=2 /* SHORTINT meta=0 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/*!*/;
@@ -1113,6 +1143,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=-1 (65535) /* SHORTINT meta=0 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/*!*/;
@@ -1149,6 +1180,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=12345 /* MEDIUMINT meta=0 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/*!*/;
@@ -1169,6 +1201,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=12345 /* MEDIUMINT meta=0 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/*!*/;
@@ -1208,6 +1241,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=-1 (16777215) /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1230,6 +1264,7 @@ BEGIN
### @1=-8388608 (8388608) /* MEDIUMINT meta=0 nullable=1 is_null=0 */
### SET
### @1=2 /* MEDIUMINT meta=0 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/*!*/;
@@ -1250,6 +1285,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=-1 (16777215) /* MEDIUMINT meta=0 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/*!*/;
@@ -1286,6 +1322,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=123456 /* INT meta=0 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/*!*/;
@@ -1306,6 +1343,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=123456 /* INT meta=0 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/*!*/;
@@ -1345,6 +1383,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=-1 (4294967295) /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1367,6 +1406,7 @@ BEGIN
### @1=-2147483648 (2147483648) /* INT meta=0 nullable=1 is_null=0 */
### SET
### @1=2 /* INT meta=0 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/*!*/;
@@ -1387,6 +1427,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=-1 (4294967295) /* INT meta=0 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/*!*/;
@@ -1423,6 +1464,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=1234567890 /* LONGINT meta=0 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/*!*/;
@@ -1443,6 +1485,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=1234567890 /* LONGINT meta=0 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/*!*/;
@@ -1482,6 +1525,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=-1 (18446744073709551615) /* LONGINT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1504,6 +1548,7 @@ BEGIN
### @1=-9223372036854775808 (9223372036854775808) /* LONGINT meta=0 nullable=1 is_null=0 */
### SET
### @1=2 /* LONGINT meta=0 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/*!*/;
@@ -1524,6 +1569,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=-1 (18446744073709551615) /* LONGINT meta=0 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/*!*/;
@@ -1560,6 +1606,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=123.223... /* FLOAT 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/*!*/;
@@ -1580,6 +1627,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=123.223... /* FLOAT 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/*!*/;
@@ -1616,6 +1664,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=123434.223... /* DOUBLE meta=8 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/*!*/;
@@ -1636,6 +1685,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=123434.223... /* DOUBLE meta=8 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/*!*/;
@@ -1672,6 +1722,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=124.45000 /* DECIMAL(10,5) meta=2565 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/*!*/;
@@ -1692,6 +1743,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=-543.21000 /* DECIMAL(10,5) meta=2565 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/*!*/;
@@ -1712,6 +1764,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=124.45000 /* DECIMAL(10,5) meta=2565 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/*!*/;
@@ -1748,6 +1801,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='2001:02:03' /* DATE meta=0 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/*!*/;
@@ -1768,6 +1822,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='2001:02:03' /* DATE meta=0 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/*!*/;
@@ -1804,6 +1859,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='2001-02-03 10:20:30' /* DATETIME(0) meta=0 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/*!*/;
@@ -1824,6 +1880,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='2001-02-03 10:20:30' /* DATETIME(0) meta=0 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/*!*/;
@@ -1860,6 +1917,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=981184830 /* TIMESTAMP(0) meta=0 nullable=0 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/*!*/;
@@ -1881,6 +1939,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=981184830 /* TIMESTAMP(0) meta=0 nullable=0 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/*!*/;
@@ -1917,6 +1976,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='11:22:33' /* TIME(0) meta=0 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/*!*/;
@@ -1937,6 +1997,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='11:22:33' /* TIME(0) meta=0 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/*!*/;
@@ -1973,6 +2034,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=2001 /* YEAR meta=0 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/*!*/;
@@ -1993,6 +2055,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=2001 /* YEAR meta=0 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/*!*/;
@@ -2029,6 +2092,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='a' /* STRING(1) meta=65025 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/*!*/;
@@ -2049,6 +2113,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='a' /* STRING(1) meta=65025 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/*!*/;
@@ -2085,6 +2150,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* STRING(0) meta=65024 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/*!*/;
@@ -2105,6 +2171,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='' /* STRING(0) meta=65024 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/*!*/;
@@ -2141,6 +2208,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='b' /* STRING(1) meta=65025 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/*!*/;
@@ -2161,6 +2229,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='b' /* STRING(1) meta=65025 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/*!*/;
@@ -2197,6 +2266,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' /* STRING(255) meta=65279 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/*!*/;
@@ -2217,6 +2287,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' /* STRING(255) meta=65279 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/*!*/;
@@ -2253,6 +2324,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='a' /* STRING(3) meta=65027 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/*!*/;
@@ -2273,6 +2345,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='a' /* STRING(3) meta=65027 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/*!*/;
@@ -2309,6 +2382,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* STRING(0) meta=65024 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/*!*/;
@@ -2329,6 +2403,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='' /* STRING(0) meta=65024 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/*!*/;
@@ -2365,6 +2440,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='a' /* STRING(3) meta=65027 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/*!*/;
@@ -2385,6 +2461,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='a' /* STRING(3) meta=65027 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/*!*/;
@@ -2421,6 +2498,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* STRING(765) meta=57085 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/*!*/;
@@ -2441,6 +2519,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß' /* STRING(765) meta=57085 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/*!*/;
@@ -2464,6 +2543,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß' /* STRING(765) meta=57085 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -2500,6 +2580,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00a' /* STRING(2) meta=65026 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/*!*/;
@@ -2520,6 +2601,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x00a' /* STRING(2) meta=65026 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/*!*/;
@@ -2556,6 +2638,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* STRING(0) meta=65024 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/*!*/;
@@ -2576,6 +2659,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='' /* STRING(0) meta=65024 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/*!*/;
@@ -2612,6 +2696,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00a' /* STRING(2) meta=65026 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/*!*/;
@@ -2632,6 +2717,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x00a' /* STRING(2) meta=65026 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/*!*/;
@@ -2668,6 +2754,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a' /* STRING(510) meta=61182 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/*!*/;
@@ -2688,6 +2775,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß' /* STRING(510) meta=61182 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/*!*/;
@@ -2711,6 +2799,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß\x00ß' /* STRING(510) meta=61182 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -2747,6 +2836,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* VARSTRING(0) meta=0 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/*!*/;
@@ -2767,6 +2857,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='' /* VARSTRING(0) meta=0 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/*!*/;
@@ -2803,6 +2894,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='a' /* VARSTRING(1) meta=1 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/*!*/;
@@ -2823,6 +2915,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='a' /* VARSTRING(1) meta=1 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/*!*/;
@@ -2859,6 +2952,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* VARSTRING(255) meta=255 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/*!*/;
@@ -2879,6 +2973,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* VARSTRING(255) meta=255 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/*!*/;
@@ -2915,6 +3010,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* VARSTRING(261) meta=261 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/*!*/;
@@ -2935,6 +3031,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* VARSTRING(261) meta=261 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/*!*/;
@@ -2971,6 +3068,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* VARSTRING(0) meta=0 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/*!*/;
@@ -2991,6 +3089,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='' /* VARSTRING(0) meta=0 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/*!*/;
@@ -3027,6 +3126,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='a' /* VARSTRING(3) meta=3 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/*!*/;
@@ -3047,6 +3147,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='a' /* VARSTRING(3) meta=3 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/*!*/;
@@ -3083,6 +3184,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* VARSTRING(765) meta=765 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/*!*/;
@@ -3103,6 +3205,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß' /* VARSTRING(765) meta=765 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/*!*/;
@@ -3126,6 +3229,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -3162,6 +3266,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* VARSTRING(783) meta=783 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/*!*/;
@@ -3182,6 +3287,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß' /* VARSTRING(783) meta=783 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/*!*/;
@@ -3205,6 +3311,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß' /* VARSTRING(783) meta=783 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -3241,6 +3348,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* VARSTRING(0) meta=0 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/*!*/;
@@ -3261,6 +3369,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='' /* VARSTRING(0) meta=0 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/*!*/;
@@ -3297,6 +3406,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00a' /* VARSTRING(2) meta=2 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/*!*/;
@@ -3317,6 +3427,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x00a' /* VARSTRING(2) meta=2 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/*!*/;
@@ -3353,6 +3464,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b' /* VARSTRING(510) meta=510 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/*!*/;
@@ -3373,6 +3485,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b' /* VARSTRING(510) meta=510 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/*!*/;
@@ -3409,6 +3522,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b' /* VARSTRING(522) meta=522 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/*!*/;
@@ -3429,6 +3543,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b\x00a\x00b' /* VARSTRING(522) meta=522 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/*!*/;
@@ -3465,6 +3580,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* STRING(1) meta=65025 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/*!*/;
@@ -3485,6 +3601,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x02' /* STRING(1) meta=65025 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/*!*/;
@@ -3505,6 +3622,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='a' /* STRING(1) meta=65025 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/*!*/;
@@ -3525,6 +3643,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='a' /* STRING(1) meta=65025 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/*!*/;
@@ -3561,6 +3680,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* STRING(0) meta=65024 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/*!*/;
@@ -3581,6 +3701,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='' /* STRING(0) meta=65024 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/*!*/;
@@ -3617,6 +3738,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* STRING(1) meta=65025 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/*!*/;
@@ -3637,6 +3759,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x02' /* STRING(1) meta=65025 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/*!*/;
@@ -3657,6 +3780,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='a' /* STRING(1) meta=65025 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/*!*/;
@@ -3677,6 +3801,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='a' /* STRING(1) meta=65025 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/*!*/;
@@ -3713,6 +3838,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* STRING(255) meta=65279 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/*!*/;
@@ -3733,6 +3859,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x02' /* STRING(255) meta=65279 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/*!*/;
@@ -3753,6 +3880,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a' /* STRING(255) meta=65279 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/*!*/;
@@ -3773,6 +3901,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='' /* STRING(255) meta=65279 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/*!*/;
@@ -3809,6 +3938,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='' /* VARSTRING(0) meta=0 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/*!*/;
@@ -3829,6 +3959,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='' /* VARSTRING(0) meta=0 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/*!*/;
@@ -3865,6 +3996,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00' /* VARSTRING(1) meta=1 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/*!*/;
@@ -3885,6 +4017,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x02' /* VARSTRING(1) meta=1 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/*!*/;
@@ -3905,6 +4038,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='a' /* VARSTRING(1) meta=1 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/*!*/;
@@ -3925,6 +4059,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x02' /* VARSTRING(1) meta=1 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/*!*/;
@@ -3961,6 +4096,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00' /* VARSTRING(255) meta=255 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/*!*/;
@@ -3981,6 +4117,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x02' /* VARSTRING(255) meta=255 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/*!*/;
@@ -4001,6 +4138,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00a\x00' /* VARSTRING(255) meta=255 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/*!*/;
@@ -4021,6 +4159,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x02' /* VARSTRING(255) meta=255 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/*!*/;
@@ -4057,6 +4196,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='tinyblob1' /* TINYBLOB/TINYTEXT meta=1 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/*!*/;
@@ -4077,6 +4217,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='tinyblob1' /* TINYBLOB/TINYTEXT meta=1 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/*!*/;
@@ -4113,6 +4254,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='blob1' /* BLOB/TEXT meta=2 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/*!*/;
@@ -4133,6 +4275,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='blob1' /* BLOB/TEXT meta=2 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/*!*/;
@@ -4169,6 +4312,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='mediumblob1' /* MEDIUMBLOB/MEDIUMTEXT meta=3 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/*!*/;
@@ -4189,6 +4333,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='mediumblob1' /* MEDIUMBLOB/MEDIUMTEXT meta=3 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/*!*/;
@@ -4225,6 +4370,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='longblob1' /* LONGBLOB/LONGTEXT 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/*!*/;
@@ -4245,6 +4391,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='longblob1' /* LONGBLOB/LONGTEXT 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/*!*/;
@@ -4281,6 +4428,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='tinytext1' /* TINYBLOB/TINYTEXT meta=1 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/*!*/;
@@ -4301,6 +4449,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='tinytext1' /* TINYBLOB/TINYTEXT meta=1 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/*!*/;
@@ -4337,6 +4486,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='text1' /* BLOB/TEXT meta=2 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/*!*/;
@@ -4357,6 +4507,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='text1' /* BLOB/TEXT meta=2 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/*!*/;
@@ -4393,6 +4544,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='mediumtext1' /* MEDIUMBLOB/MEDIUMTEXT meta=3 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/*!*/;
@@ -4413,6 +4565,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='mediumtext1' /* MEDIUMBLOB/MEDIUMTEXT meta=3 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/*!*/;
@@ -4449,6 +4602,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='longtext1' /* LONGBLOB/LONGTEXT 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/*!*/;
@@ -4469,6 +4623,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='longtext1' /* LONGBLOB/LONGTEXT 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/*!*/;
@@ -4505,6 +4660,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00t\x00i\x00n\x00y\x00t\x00e\x00x\x00t\x001' /* TINYBLOB/TINYTEXT meta=1 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/*!*/;
@@ -4525,6 +4681,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x00t\x00i\x00n\x00y\x00t\x00e\x00x\x00t\x001' /* TINYBLOB/TINYTEXT meta=1 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/*!*/;
@@ -4561,6 +4718,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00t\x00e\x00x\x00t\x001' /* BLOB/TEXT meta=2 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/*!*/;
@@ -4581,6 +4739,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x00t\x00e\x00x\x00t\x001' /* BLOB/TEXT meta=2 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/*!*/;
@@ -4617,6 +4776,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00m\x00e\x00d\x00i\x00u\x00m\x00t\x00e\x00x\x00t\x001' /* MEDIUMBLOB/MEDIUMTEXT meta=3 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/*!*/;
@@ -4637,6 +4797,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x00m\x00e\x00d\x00i\x00u\x00m\x00t\x00e\x00x\x00t\x001' /* MEDIUMBLOB/MEDIUMTEXT meta=3 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/*!*/;
@@ -4673,6 +4834,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='\x00l\x00o\x00n\x00g\x00t\x00e\x00x\x00t\x001' /* LONGBLOB/LONGTEXT 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/*!*/;
@@ -4693,6 +4855,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1='\x00l\x00o\x00n\x00g\x00t\x00e\x00x\x00t\x001' /* LONGBLOB/LONGTEXT 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/*!*/;
@@ -4729,6 +4892,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=2 /* ENUM(1 byte) meta=63233 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/*!*/;
@@ -4749,6 +4913,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=2 /* ENUM(1 byte) meta=63233 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/*!*/;
@@ -4785,6 +4950,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'00000011' /* SET(1 bytes) meta=63489 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/*!*/;
@@ -4805,6 +4971,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'00000101' /* SET(1 bytes) meta=63489 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/*!*/;
@@ -4825,6 +4992,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'00000110' /* SET(1 bytes) meta=63489 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/*!*/;
@@ -4845,6 +5013,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'00000111' /* SET(1 bytes) meta=63489 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/*!*/;
@@ -4865,6 +5034,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'00001111' /* SET(1 bytes) meta=63489 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/*!*/;
@@ -4885,6 +5055,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'00011111' /* SET(1 bytes) meta=63489 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/*!*/;
@@ -4905,6 +5076,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1=b'00111111' /* SET(1 bytes) meta=63489 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/*!*/;
@@ -4925,6 +5097,7 @@ BEGIN
### DELETE FROM `test`.`t1`
### WHERE
### @1=b'00000011' /* SET(1 bytes) meta=63489 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/*!*/;
@@ -4970,6 +5143,7 @@ BEGIN
### SET
### @1=1 /* INT meta=0 nullable=0 is_null=0 */
### @2=0 /* INT meta=0 nullable=0 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/*!*/;
@@ -4991,6 +5165,7 @@ BEGIN
### SET
### @1=0 /* INT meta=0 nullable=0 is_null=0 */
### @2=1 /* INT meta=0 nullable=0 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/*!*/;
@@ -5012,6 +5187,7 @@ BEGIN
### SET
### @1=1 /* INT meta=0 nullable=0 is_null=0 */
### @2=0 /* INT meta=0 nullable=0 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/*!*/;
@@ -5033,6 +5209,7 @@ BEGIN
### SET
### @1=0 /* INT meta=0 nullable=0 is_null=0 */
### @2=1 /* INT meta=0 nullable=0 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/*!*/;
@@ -5082,6 +5259,7 @@ BEGIN
### SET
### @1=20 /* INT meta=0 nullable=0 is_null=0 */
### @2=1 /* INT meta=0 nullable=0 is_null=0 */
+# Number of rows: 4
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -5096,74 +5274,40 @@ SET TIMESTAMP=1000000000/*!*/;
DROP TABLE `t1`,`t2` /* generated by server */
/*!*/;
# at #
-#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-317
-/*!100001 SET @@session.gtid_seq_no=317*//*!*/;
-BEGIN
-/*!*/;
-# at #
-# at #
-#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
-#Q> INSERT INTO t1dec102 VALUES (-999.99)
-#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1dec102` 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`.`t1dec102`
-### SET
-### @1=!! Old DECIMAL (mysql-4.1 or earlier). Not enough metadata to display the value. # 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
-/*!*/;
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Rotate to master-bin.000002 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*/;
+/*!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 GTID 0-1-318
-/*!100001 SET @@session.gtid_seq_no=318*//*!*/;
-BEGIN
-/*!*/;
+#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-316]
# at #
-#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
-#Q> INSERT INTO t1dec102 VALUES (0)
-#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1dec102` mapped to number #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Binlog checkpoint master-bin.000001
# at #
-#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
-### INSERT INTO `test`.`t1dec102`
-### SET
-### @1=!! Old DECIMAL (mysql-4.1 or earlier). Not enough metadata to display the value. # 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
-/*!*/;
+#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 GTID 0-1-319
-/*!100001 SET @@session.gtid_seq_no=319*//*!*/;
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-317
+/*!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=317*//*!*/;
BEGIN
/*!*/;
# at #
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
-#Q> INSERT INTO t1dec102 VALUES (999.99)
+#Q> INSERT INTO t1dec102 VALUES (-999.99)
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1dec102` 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`.`t1dec102`
### SET
-### @1=!! Old DECIMAL (mysql-4.1 or earlier). Not enough metadata to display the value. # 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-320 ddl
-/*!100001 SET @@session.gtid_seq_no=320*//*!*/;
-# 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 `t1dec102` /* generated by server */
-/*!*/;
-# at #
-#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Rotate to master-bin.000002 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*/;
+### @1=
+Error: Found Old DECIMAL (mysql-4.1 or earlier). Not enough metadata to display the value.
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result
index 365fcff2a72..3dcaad61897 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result
@@ -2543,6 +2543,7 @@ BEGIN
### @77=1 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000000' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -2724,6 +2725,7 @@ BEGIN
### @77=3 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000111' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=2 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -3071,6 +3073,7 @@ BEGIN
### @77=2 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000110' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=4 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -3410,6 +3413,7 @@ BEGIN
### @77=3 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000111' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -3754,6 +3758,7 @@ BEGIN
### @77=1 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000000' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=2 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -4096,6 +4101,7 @@ BEGIN
### @77=2 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000110' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -4441,6 +4447,7 @@ BEGIN
### @77=NULL /* ENUM(1 byte) meta=63233 nullable=1 is_null=1 */
### @78=NULL /* SET(1 bytes) meta=63489 nullable=1 is_null=1 */
### @79=4 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -4620,6 +4627,7 @@ BEGIN
### @77=3 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000111' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -4796,6 +4804,7 @@ BEGIN
### @77=1 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000000' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=2 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -4975,6 +4984,7 @@ BEGIN
### @77=2 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000110' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -5152,6 +5162,7 @@ BEGIN
### @77=NULL /* ENUM(1 byte) meta=63233 nullable=1 is_null=1 */
### @78=NULL /* SET(1 bytes) meta=63489 nullable=1 is_null=1 */
### @79=4 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -5345,6 +5356,7 @@ BEGIN
### @1='2008:08:09' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-09' /* VARSTRING(24) meta=24 nullable=1 is_null=0 */
### @3=9 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 9
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -5423,6 +5435,7 @@ BEGIN
### @1='2008:08:17' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-07' /* VARSTRING(24) meta=24 nullable=1 is_null=0 */
### @3=7 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 7
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -5473,6 +5486,7 @@ BEGIN
### @1='2008:08:17' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-07' /* VARSTRING(24) meta=24 nullable=1 is_null=0 */
### @3=7 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 7
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -5766,6 +5780,7 @@ BEGIN
### @1='2008:01:09' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-01-09' /* VARSTRING(255) meta=255 nullable=1 is_null=0 */
### @3=19 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 9
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -5835,6 +5850,7 @@ BEGIN
### @1='2008:02:09' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-02-09' /* VARSTRING(255) meta=255 nullable=1 is_null=0 */
### @3=29 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 9
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -5904,6 +5920,7 @@ BEGIN
### @1='2008:03:09' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-03-09' /* VARSTRING(255) meta=255 nullable=1 is_null=0 */
### @3=39 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 9
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -6093,6 +6110,7 @@ BEGIN
### @1='2038:03:07' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-03-07' /* VARSTRING(255) meta=255 nullable=1 is_null=0 */
### @3=7 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 18
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -6207,6 +6225,7 @@ BEGIN
### @1='2038:03:07' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-03-07' /* VARSTRING(255) meta=255 nullable=1 is_null=0 */
### @3=7 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 18
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -6338,6 +6357,7 @@ BEGIN
### @1=5 /* INT meta=0 nullable=1 is_null=0 */
### @2=6 /* INT meta=0 nullable=1 is_null=0 */
### @3='Wow' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result
index 7c6c21625f2..a4d929148e8 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result
@@ -2543,6 +2543,7 @@ BEGIN
### @77=1 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000000' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=1 /* INT meta=0 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/*!*/;
@@ -2727,6 +2728,7 @@ BEGIN
### @77=3 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000111' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=2 /* INT meta=0 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/*!*/;
@@ -3076,6 +3078,7 @@ BEGIN
### @77=2 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000110' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=4 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -3417,6 +3420,7 @@ BEGIN
### @77=3 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000111' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=1 /* INT meta=0 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/*!*/;
@@ -3763,6 +3767,7 @@ BEGIN
### @77=1 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000000' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=2 /* INT meta=0 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/*!*/;
@@ -4107,6 +4112,7 @@ BEGIN
### @77=2 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000110' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=3 /* INT meta=0 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/*!*/;
@@ -4454,6 +4460,7 @@ BEGIN
### @77=NULL /* ENUM(1 byte) meta=63233 nullable=1 is_null=1 */
### @78=NULL /* SET(1 bytes) meta=63489 nullable=1 is_null=1 */
### @79=4 /* INT meta=0 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/*!*/;
@@ -4635,6 +4642,7 @@ BEGIN
### @77=3 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000111' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=1 /* INT meta=0 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/*!*/;
@@ -4813,6 +4821,7 @@ BEGIN
### @77=1 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000000' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=2 /* INT meta=0 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/*!*/;
@@ -4994,6 +5003,7 @@ BEGIN
### @77=2 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
### @78=b'00000110' /* SET(1 bytes) meta=63489 nullable=1 is_null=0 */
### @79=3 /* INT meta=0 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/*!*/;
@@ -5173,6 +5183,7 @@ BEGIN
### @77=NULL /* ENUM(1 byte) meta=63233 nullable=1 is_null=1 */
### @78=NULL /* SET(1 bytes) meta=63489 nullable=1 is_null=1 */
### @79=4 /* INT meta=0 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/*!*/;
@@ -5368,6 +5379,7 @@ BEGIN
### @1='2008:08:09' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-09' /* VARSTRING(24) meta=24 nullable=1 is_null=0 */
### @3=9 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 9
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -5448,6 +5460,7 @@ BEGIN
### @1='2008:08:17' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-07' /* VARSTRING(24) meta=24 nullable=1 is_null=0 */
### @3=7 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 7
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -5500,6 +5513,7 @@ BEGIN
### @1='2008:08:17' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-07' /* VARSTRING(24) meta=24 nullable=1 is_null=0 */
### @3=7 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 7
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -5795,6 +5809,7 @@ BEGIN
### @1='2008:01:09' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-01-09' /* VARSTRING(255) meta=255 nullable=1 is_null=0 */
### @3=19 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 9
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -5866,6 +5881,7 @@ BEGIN
### @1='2008:02:09' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-02-09' /* VARSTRING(255) meta=255 nullable=1 is_null=0 */
### @3=29 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 9
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -5937,6 +5953,7 @@ BEGIN
### @1='2008:03:09' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-03-09' /* VARSTRING(255) meta=255 nullable=1 is_null=0 */
### @3=39 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 9
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -6128,6 +6145,7 @@ BEGIN
### @1='2038:03:07' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-03-07' /* VARSTRING(255) meta=255 nullable=1 is_null=0 */
### @3=7 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 18
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -6244,6 +6262,7 @@ BEGIN
### @1='2038:03:07' /* DATE meta=0 nullable=1 is_null=0 */
### @2='VARCHAR-03-07' /* VARSTRING(255) meta=255 nullable=1 is_null=0 */
### @3=7 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 18
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -6377,6 +6396,7 @@ BEGIN
### @1=5 /* INT meta=0 nullable=1 is_null=0 */
### @2=6 /* INT meta=0 nullable=1 is_null=0 */
### @3='Wow' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result
index c6c7684f4c8..6a0c6b0532f 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result
@@ -193,6 +193,7 @@ BEGIN
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-3' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
@@ -221,6 +222,7 @@ BEGIN
### SET
### @1=13 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-3' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
@@ -232,6 +234,7 @@ BEGIN
### WHERE
### @1=12 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-2' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -275,6 +278,7 @@ BEGIN
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-3' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -313,6 +317,7 @@ BEGIN
### SET
### @1=13 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-3' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -334,6 +339,7 @@ BEGIN
### WHERE
### @1=12 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-2' /* VARSTRING(20) meta=20 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/*!*/;
@@ -363,6 +369,7 @@ BEGIN
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-3' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
@@ -391,6 +398,7 @@ BEGIN
### SET
### @1=13 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-3' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
@@ -402,6 +410,7 @@ BEGIN
### WHERE
### @1=12 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-2' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -445,6 +454,7 @@ BEGIN
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-3' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -483,6 +493,7 @@ BEGIN
### SET
### @1=13 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-3' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -504,6 +515,7 @@ BEGIN
### WHERE
### @1=12 /* INT meta=0 nullable=1 is_null=0 */
### @2='varchar-2' /* VARSTRING(20) meta=20 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/*!*/;
diff --git a/mysql-test/suite/binlog/r/binlog_row_annotate.result b/mysql-test/suite/binlog/r/binlog_row_annotate.result
index 8a37200a2e3..25a9b295301 100644
--- a/mysql-test/suite/binlog/r/binlog_row_annotate.result
+++ b/mysql-test/suite/binlog/r/binlog_row_annotate.result
@@ -162,6 +162,7 @@ BEGIN
### INSERT INTO `test1`.`t1`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -188,6 +189,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -214,6 +216,7 @@ BEGIN
### INSERT INTO `test3`.`t3`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -255,6 +258,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 6
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -281,6 +285,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -309,6 +314,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -386,6 +392,7 @@ BEGIN
### INSERT INTO `test1`.`t1`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -551,6 +558,7 @@ BEGIN
### INSERT INTO `test1`.`t1`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -575,6 +583,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -599,6 +608,7 @@ BEGIN
### INSERT INTO `test3`.`t3`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -636,6 +646,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 6
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -660,6 +671,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -684,6 +696,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -773,6 +786,7 @@ BEGIN
### INSERT INTO `test1`.`t1`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -799,6 +813,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -825,6 +840,7 @@ BEGIN
### INSERT INTO `test3`.`t3`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -866,6 +882,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 6
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -892,6 +909,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -920,6 +938,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -997,6 +1016,7 @@ BEGIN
### INSERT INTO `test1`.`t1`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1161,6 +1181,7 @@ BEGIN
### INSERT INTO `test1`.`t1`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1184,6 +1205,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1207,6 +1229,7 @@ BEGIN
### INSERT INTO `test3`.`t3`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1243,6 +1266,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 6
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1266,6 +1290,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1289,6 +1314,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
diff --git a/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result b/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result
index da51ec1e3b6..343b21160fd 100644
--- a/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result
+++ b/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result
@@ -18,6 +18,8 @@ DELIMITER /*!*/;
ROLLBACK/*!*/;
BEGIN
/*!*/;
+# Annotate_rows:
+#Q> insert into t2 values (@v)
SET TIMESTAMP=10000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
@@ -114,6 +116,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='ä(i1)' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#YYMMDD HH:MM:SS server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=XXX/*!*/;
@@ -134,6 +137,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='ä(i2)' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#YYMMDD HH:MM:SS server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=XXX/*!*/;
@@ -154,6 +158,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='ä(i3)' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#YYMMDD HH:MM:SS server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=XXX/*!*/;
@@ -174,6 +179,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='ä(p1)' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#YYMMDD HH:MM:SS server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=XXX/*!*/;
@@ -194,6 +200,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='ä(p2)' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#YYMMDD HH:MM:SS server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=XXX/*!*/;
@@ -214,6 +221,7 @@ BEGIN
### INSERT INTO `test`.`t1`
### SET
### @1='ä(p3)' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#YYMMDD HH:MM:SS server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=XXX/*!*/;
diff --git a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result
index e48dd2c89b4..1114902bae1 100644
--- a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result
+++ b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result
@@ -79,6 +79,7 @@ BEGIN
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
### @2=2 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -111,6 +112,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -132,6 +134,7 @@ BEGIN
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### @2=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -164,6 +167,7 @@ BEGIN
### INSERT INTO `new_test3`.`t3`
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -185,6 +189,7 @@ BEGIN
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
### @2=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -223,6 +228,7 @@ BEGIN
### SET
### @1=6 /* INT meta=0 nullable=1 is_null=0 */
### @2=6 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 5
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -243,6 +249,7 @@ BEGIN
### DELETE FROM `new_test3`.`t3`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -313,6 +320,7 @@ BEGIN
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
### @2=2 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -345,6 +353,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -366,6 +375,7 @@ BEGIN
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### @2=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -398,6 +408,7 @@ BEGIN
### INSERT INTO `new_test3`.`t3`
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -419,6 +430,7 @@ BEGIN
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
### @2=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -457,6 +469,7 @@ BEGIN
### SET
### @1=6 /* INT meta=0 nullable=1 is_null=0 */
### @2=6 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 5
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -477,6 +490,7 @@ BEGIN
### DELETE FROM `new_test3`.`t3`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_datetime_ranges_mdev15289.result b/mysql-test/suite/binlog/r/binlog_stm_datetime_ranges_mdev15289.result
new file mode 100644
index 00000000000..0c3e72133b8
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_stm_datetime_ranges_mdev15289.result
@@ -0,0 +1,19 @@
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # CREATE DATABASE IF NOT EXISTS client_test_db
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `client_test_db`; create or replace table t1 (t time, d date, dt datetime,ts timestamp)
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Query # # use `client_test_db`; INSERT INTO t1 VALUES (TIMESTAMP'0000-00-00 00:00:00', TIMESTAMP'0000-00-00 00:00:00', TIMESTAMP'0000-00-00 00:00:00', TIMESTAMP'0000-00-00 00:00:00')
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Query # # use `client_test_db`; INSERT INTO t1 VALUES (DATE'0000-00-00', DATE'0000-00-00', DATE'0000-00-00', DATE'0000-00-00')
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Query # # use `client_test_db`; INSERT INTO t1 VALUES (TIME'00:00:00', TIME'00:00:00', TIME'00:00:00', TIME'00:00:00')
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `client_test_db`; DROP TABLE `t1` /* generated by server */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # DROP DATABASE IF EXISTS client_test_db
diff --git a/mysql-test/suite/binlog/r/binlog_stm_ps.result b/mysql-test/suite/binlog/r/binlog_stm_ps.result
index 0b7491e4364..75f64500878 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_ps.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_ps.result
@@ -185,3 +185,46 @@ master-bin.000004 # Gtid # # GTID #-#-#
master-bin.000004 # Query # # use `test`; DROP PROCEDURE p1
master-bin.000004 # Gtid # # GTID #-#-#
master-bin.000004 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
+#
+#MDEV-14467 Item_param: replace {INT|DECIMAL|REAL|STRING|TIME}_VALUE with Type_handler
+#
+FLUSH LOGS;
+CREATE TABLE t1 (a INT);
+EXECUTE IMMEDIATE 'INSERT INTO t1 SELECT 1 LIMIT ?' USING 10;
+Warnings:
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
+EXECUTE IMMEDIATE 'INSERT INTO t1 SELECT 1 LIMIT ?' USING 10.1;
+Warnings:
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
+EXECUTE IMMEDIATE 'INSERT INTO t1 SELECT 1 LIMIT ?' USING 10.1e0;
+Warnings:
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
+EXECUTE IMMEDIATE 'INSERT INTO t1 SELECT 1 LIMIT ?' USING '10';
+Warnings:
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
+EXECUTE IMMEDIATE 'INSERT INTO t1 SELECT 1 LIMIT ?' USING TIME'10:10:10';
+Warnings:
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
+DROP TABLE t1;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000005 # Binlog_checkpoint # # master-bin.000005
+master-bin.000005 # Gtid # # GTID #-#-#
+master-bin.000005 # Query # # use `test`; CREATE TABLE t1 (a INT)
+master-bin.000005 # Gtid # # BEGIN GTID #-#-#
+master-bin.000005 # Query # # use `test`; INSERT INTO t1 SELECT 1 LIMIT 10
+master-bin.000005 # Query # # COMMIT
+master-bin.000005 # Gtid # # BEGIN GTID #-#-#
+master-bin.000005 # Query # # use `test`; INSERT INTO t1 SELECT 1 LIMIT 10
+master-bin.000005 # Query # # COMMIT
+master-bin.000005 # Gtid # # BEGIN GTID #-#-#
+master-bin.000005 # Query # # use `test`; INSERT INTO t1 SELECT 1 LIMIT 10
+master-bin.000005 # Query # # COMMIT
+master-bin.000005 # Gtid # # BEGIN GTID #-#-#
+master-bin.000005 # Query # # use `test`; INSERT INTO t1 SELECT 1 LIMIT 10
+master-bin.000005 # Query # # COMMIT
+master-bin.000005 # Gtid # # BEGIN GTID #-#-#
+master-bin.000005 # Query # # use `test`; INSERT INTO t1 SELECT 1 LIMIT 101010
+master-bin.000005 # Query # # COMMIT
+master-bin.000005 # Gtid # # GTID #-#-#
+master-bin.000005 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
diff --git a/mysql-test/suite/binlog/r/flashback.result b/mysql-test/suite/binlog/r/flashback.result
index c96eaebe838..24c9b735fe5 100644
--- a/mysql-test/suite/binlog/r/flashback.result
+++ b/mysql-test/suite/binlog/r/flashback.result
@@ -100,6 +100,7 @@ BEGIN
### @6='' /* STRING(10) meta=65034 nullable=1 is_null=0 */
### @7='' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
### @8='' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -125,6 +126,7 @@ BEGIN
### @6='abc' /* STRING(10) meta=65034 nullable=1 is_null=0 */
### @7='abcdefg' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
### @8='abcedfghijklmnopqrstuvwxyz' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -150,6 +152,7 @@ BEGIN
### @6='aaaaaaaaaa' /* STRING(10) meta=65034 nullable=1 is_null=0 */
### @7='aaaaaaaaaaaaaaaaaaaa' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
### @8='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+# Number of rows: 1
# at #
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -203,6 +206,7 @@ BEGIN
### @6='abc' /* STRING(10) meta=65034 nullable=1 is_null=0 */
### @7='abcdefg' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
### @8='abcedfghijklmnopqrstuvwxyz' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+# Number of rows: 2
# at #
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -248,6 +252,7 @@ BEGIN
### @6='aaaaaaaaaa' /* STRING(10) meta=65034 nullable=1 is_null=0 */
### @7='aaaaaaaaaaaaaaaaaaaa' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
### @8='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
COMMIT/*!*/;
@@ -272,18 +277,23 @@ ROLLBACK/*!*/;
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
#Q> INSERT INTO t1 VALUES(0,0,0,0,0,'','','')
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# Number of rows: 1
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
#Q> INSERT INTO t1 VALUES(1,2,3,4,5, "abc", "abcdefg", "abcedfghijklmnopqrstuvwxyz")
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# Number of rows: 1
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
#Q> INSERT INTO t1 VALUES(127, 32767, 8388607, 2147483647, 9223372036854775807, repeat('a', 10), repeat('a', 20), repeat('a', 255))
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# Number of rows: 1
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
#Q> UPDATE t1 SET c01=100 WHERE c02=0 OR c03=3
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# Number of rows: 2
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
#Q> DELETE FROM t1
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# Number of rows: 3
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Rotate to master-bin.000002 pos: 4
#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
BEGIN/*!*/;
diff --git a/mysql-test/suite/binlog/r/load_data_stm_view.result b/mysql-test/suite/binlog/r/load_data_stm_view.result
index ddbdb71983f..c21ffb7dcc6 100644
--- a/mysql-test/suite/binlog/r/load_data_stm_view.result
+++ b/mysql-test/suite/binlog/r/load_data_stm_view.result
@@ -1,3 +1,4 @@
+reset master;
create table t1 (i int, j int);
create view v1 as select i from t1;
LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/3940.data' INTO TABLE v1 (i);
diff --git a/mysql-test/suite/binlog/t/binlog_base64_flag.test b/mysql-test/suite/binlog/t/binlog_base64_flag.test
index f8333315088..f17b51166e9 100644
--- a/mysql-test/suite/binlog/t/binlog_base64_flag.test
+++ b/mysql-test/suite/binlog/t/binlog_base64_flag.test
@@ -68,15 +68,12 @@ TFtYRxcBAAAAIgAAAKEBAAAQABAAAAAAAAEAAf/+AwAAAA==
select * from t1;
-# Test that mysqlbinlog stops with an error message when the
-# --base64-output=never flag is used on a binlog with base64 events.
+# New mysqlbinlog supports --base64-output=never
--echo ==== Test --base64-output=never on a binlog with row events ====
# mysqlbinlog should fail
---replace_regex /#[0-9][0-9][0-9][0-9][0-9][0-9] .*/<#>/ /SET \@\@session.pseudo_thread_id.*/<#>/
-error 1;
-exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/bug32407.001;
-# the above line should output the query log event and then stop
+--replace_regex /#[0-9][0-9][0-9][0-9][0-9][0-9] \N*/<#>/ /SET \@\@session.pseudo_thread_id.*/<#>/
+exec $MYSQL_BINLOG --base64-output=never --print-row-count=0 --print-row-event-positions=0 suite/binlog/std_data/bug32407.001;
# Test that the following fails cleanly: "First, read a
diff --git a/mysql-test/suite/binlog/t/binlog_flush_binlogs_delete_domain.test b/mysql-test/suite/binlog/t/binlog_flush_binlogs_delete_domain.test
new file mode 100644
index 00000000000..0faafa35a1b
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_flush_binlogs_delete_domain.test
@@ -0,0 +1,137 @@
+# Prove basic properties of
+#
+# FLUSH BINARY LOGS DELETE_DOMAIN_ID = (...)
+#
+# The command removes the supplied list of domains from the current
+# @@global.gtid_binlog_state provided the binlog files do not contain
+# events from such domains.
+
+# The test is not format specific. One format is chosen to run it.
+--source include/have_binlog_format_mixed.inc
+
+# Reset binlog state
+RESET MASTER;
+
+# Empty list is accepted
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = ();
+--echo and the command execution is effective thence rotates binlog as usual
+--source include/show_binary_logs.inc
+
+--echo Non-existed domain is warned, the command completes without rotation
+--echo but with a warning
+--let $binlog_pre_flush=query_get_value(SHOW MASTER STATUS, Position, 1)
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (99);
+--let $binlog_start=$binlog_pre_flush
+--source include/show_binary_logs.inc
+
+# Log one event in a specified domain and try to delete the domain
+SET @@SESSION.gtid_domain_id=1;
+SET @@SESSION.server_id=1;
+CREATE TABLE t (a int);
+
+--error ER_BINLOG_CANT_DELETE_GTID_DOMAIN
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
+
+# the same error after log rotation
+FLUSH BINARY LOGS;
+--error ER_BINLOG_CANT_DELETE_GTID_DOMAIN
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
+
+# the latest binlog does not really contain any events incl ones from 1-domain
+--let $purge_to_binlog= query_get_value(SHOW MASTER STATUS, File, 1)
+--eval PURGE BINARY LOGS TO '$purge_to_binlog';
+# So now it's safe to delete
+--error 0
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
+--echo Gtid_list of the current binlog does not contain '1':
+--let $binlog_file=query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_gtid_list.inc
+--echo But the previous log's Gtid_list may have it which explains a warning from the following command
+--let $binlog_file=$purge_to_binlog
+--source include/show_gtid_list.inc
+
+--echo Already deleted domain in Gtid_list of the earliest log is benign
+--echo but may cause a warning
+--error 0
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
+
+# Few domains delete. The chosen number verifies among others how
+# expected overrun of the static buffers of underlying dynamic arrays is doing.
+--let $domain_cnt=17
+--let $server_in_domain_cnt=3
+--let $domain_list=
+--disable_query_log
+while ($domain_cnt)
+{
+ --let servers=$server_in_domain_cnt
+ --eval SET @@SESSION.gtid_domain_id=$domain_cnt
+ while ($servers)
+ {
+ --eval SET @@SESSION.server_id=10*$domain_cnt + $servers
+ --eval INSERT INTO t SET a=@@SESSION.server_id
+
+ --dec $servers
+ }
+ --let $domain_list= $domain_cnt, $domain_list
+
+ --dec $domain_cnt
+}
+--enable_query_log
+--let $zero=0
+--let $domain_list= $domain_list$zero
+
+--error ER_BINLOG_CANT_DELETE_GTID_DOMAIN
+--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID = ($domain_list)
+
+# Now satisfy the safety condtion to purge log files containing $domain list
+FLUSH BINARY LOGS;
+--let $purge_to_binlog= query_get_value(SHOW MASTER STATUS, File, 1)
+--eval PURGE BINARY LOGS TO '$purge_to_binlog'
+--error 0
+--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID = ($domain_list)
+--echo Gtid_list of the current binlog does not contain $domain_list:
+--let $binlog_file=query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_gtid_list.inc
+
+# Show reaction on @@global.gtid_binlog_state not succeeding
+# earlier state as described by the 1st binlog' Gtid_list.
+# Now let it be out-order gtid logged to a domain unrelated to deletion.
+
+--let $del_d_id=1
+--eval SET @@SESSION.gtid_domain_id=$del_d_id;
+SET @@SESSION.server_id=1;
+SET @@SESSION.gtid_seq_no=1;
+INSERT INTO t SET a=1;
+SET @@SESSION.server_id=2;
+SET @@SESSION.gtid_seq_no=2;
+INSERT INTO t SET a=2;
+
+SET @@SESSION.gtid_domain_id=11;
+SET @@SESSION.server_id=11;
+SET @@SESSION.gtid_seq_no=11;
+INSERT INTO t SET a=11;
+
+SET @gtid_binlog_state_saved=@@GLOBAL.gtid_binlog_state;
+FLUSH BINARY LOGS;
+
+# Inject out of order for domain '11' before
+SET @@SESSION.gtid_domain_id=11;
+SET @@SESSION.server_id=11;
+SET @@SESSION.gtid_seq_no=1;
+INSERT INTO t SET a=1;
+
+SELECT @gtid_binlog_state_saved "as original state", @@GLOBAL.gtid_binlog_state as "out of order for 11 domain state";
+
+# to delete '1', first to purge logs containing its events
+--let $purge_to_binlog= query_get_value(SHOW MASTER STATUS, File, 1)
+--eval PURGE BINARY LOGS TO '$purge_to_binlog'
+
+--echo the following command succeeds with warnings
+--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID = ($del_d_id)
+
+#
+# Cleanup
+#
+
+DROP TABLE t;
+RESET MASTER;
diff --git a/mysql-test/suite/binlog/t/binlog_gtid_delete_domain_debug.test b/mysql-test/suite/binlog/t/binlog_gtid_delete_domain_debug.test
new file mode 100644
index 00000000000..5de549c45bb
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_gtid_delete_domain_debug.test
@@ -0,0 +1,11 @@
+# Check "internal" error branches of
+# FLUSH BINARY LOGS DELETE_DOMAIN_ID = (...)
+# handler.
+--source include/have_debug.inc
+--source include/have_binlog_format_mixed.inc
+
+SET @@SESSION.debug_dbug='+d,inject_binlog_delete_domain_init_error';
+--error ER_BINLOG_CANT_DELETE_GTID_DOMAIN
+FLUSH BINARY LOGS DELETE_DOMAIN_ID = (99);
+
+SHOW WARNINGS;
diff --git a/mysql-test/suite/binlog/t/binlog_killed.test b/mysql-test/suite/binlog/t/binlog_killed.test
index 73759ee5aa5..7c3a262d2c1 100644
--- a/mysql-test/suite/binlog/t/binlog_killed.test
+++ b/mysql-test/suite/binlog/t/binlog_killed.test
@@ -10,6 +10,13 @@ call mtr.add_suppression("Unsafe statement written to the binary log using state
-- source include/not_embedded.inc
+#
+# Avoid printing binlog checkpoints
+#
+
+--let $skip_checkpoint_events=1
+
+
###
### bug#22725 : incorrect killed error in binlogged query
###
@@ -349,6 +356,94 @@ drop table t4;
drop function bug27563;
+# Prove that killing connection in the middle
+# of mixed engine transactions affect binlogging
+# as specified.
+
+# keep binlogging for this piece of test in a new file
+FLUSH LOGS;
+
+# Connection con3 as transaction generator thoughout the test
+connect (con3, localhost, root,,);
+
+connection con3;
+let $ID= `select connection_id()`;
+
+--let $threads_connected=`select variable_value from information_schema.global_status where variable_name="threads_connected"`
+--let wait_condition=select variable_value < $threads_connected from information_schema.global_status where variable_name="threads_connected"
+
+--echo MI: MyISAM, INNODB
+BEGIN;
+INSERT INTO t2 VALUES (NULL, 1);
+INSERT INTO t1 VALUES (NULL, 2);
+
+#Connection con1 as killer throughout the test
+connection con1;
+--replace_result $ID ID
+--eval KILL $ID
+let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
+--source include/wait_condition.inc
+--let $binlog_start= 4
+--source include/show_binlog_events.inc
+--let $binlog_killed_pos=query_get_value(SHOW MASTER STATUS, Position, 1)
+
+disconnect con3;
+connect (con3, localhost, root,,);
+connection con3;
+let $ID= `select connection_id()`;
+
+--echo IM: INNODB, MyISAM
+BEGIN;
+INSERT INTO t1 VALUES (NULL, 3);
+INSERT INTO t2 VALUES (NULL, 4);
+
+connection con1;
+--replace_result $ID ID
+--eval KILL $ID
+--source include/wait_condition.inc
+--let $binlog_start= $binlog_killed_pos
+--source include/show_binlog_events.inc
+--let $binlog_killed_pos=query_get_value(SHOW MASTER STATUS, Position, 1)
+
+disconnect con3;
+connect (con3, localhost, root,,);
+connection con3;
+let $ID= `select connection_id()`;
+
+--echo IMI: INNODB, MyISAM, INNODB
+BEGIN;
+INSERT INTO t1 VALUES (NULL, 5);
+INSERT INTO t2 VALUES (NULL, 6);
+INSERT INTO t1 VALUES (NULL, 7);
+
+connection con1;
+--replace_result $ID ID
+--eval KILL $ID
+--source include/wait_condition.inc
+--let $binlog_start= $binlog_killed_pos
+--source include/show_binlog_events.inc
+--let $binlog_killed_pos=query_get_value(SHOW MASTER STATUS, Position, 1)
+
+disconnect con3;
+connect (con3, localhost, root,,);
+connection con3;
+let $ID= `select connection_id()`;
+
+--echo MI2: MyISAM, INNODB, MyISAM, INNODB
+BEGIN;
+INSERT INTO t2 VALUES (NULL, 8);
+INSERT INTO t1 VALUES (NULL, 9);
+INSERT INTO t2 VALUES (NULL, 10);
+INSERT INTO t1 VALUES (NULL, 11);
+
+connection con1;
+--replace_result $ID ID
+--eval KILL $ID
+--source include/wait_condition.inc
+--let $binlog_start= $binlog_killed_pos
+--source include/show_binlog_events.inc
+
+
#
# common cleanup
#
diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test
index 750bf10901f..9cc8e3f22a7 100644
--- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test
+++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test
@@ -438,6 +438,8 @@ INSERT INTO t2 SET b=1;
UPDATE t1, t2 SET t1.a=10, t2.a=20;
DROP TABLE t1,t2;
+flush logs;
+
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file std_data/old_decimal/t1dec102.frm $MYSQLD_DATADIR/test/t1dec102.frm
@@ -455,3 +457,8 @@ 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/
--exec $MYSQL_BINLOG --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000001
+
+--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/
+--error 1
+--exec $MYSQL_BINLOG --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000002 2>&1
diff --git a/mysql-test/suite/binlog/t/binlog_stm_datetime_ranges_mdev15289.test b/mysql-test/suite/binlog/t/binlog_stm_datetime_ranges_mdev15289.test
new file mode 100644
index 00000000000..ae4cab62fec
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_stm_datetime_ranges_mdev15289.test
@@ -0,0 +1,7 @@
+--source include/not_embedded.inc
+--source include/have_binlog_format_statement.inc
+
+--exec $MYSQL_CLIENT_TEST test_datetime_ranges_mdev15289 > $MYSQLTEST_VARDIR/log/binlog_stm_datetime_ranges_mysql_client_test.out.log 2>&1
+
+--let $binlog_file = LAST
+source include/show_binlog_events.inc;
diff --git a/mysql-test/suite/binlog/t/binlog_stm_ps.test b/mysql-test/suite/binlog/t/binlog_stm_ps.test
index e6e54985f6f..b83991b1356 100644
--- a/mysql-test/suite/binlog/t/binlog_stm_ps.test
+++ b/mysql-test/suite/binlog/t/binlog_stm_ps.test
@@ -99,3 +99,19 @@ DROP TABLE t1;
--let $binlog_file = LAST
source include/show_binlog_events.inc;
+
+--echo #
+--echo #MDEV-14467 Item_param: replace {INT|DECIMAL|REAL|STRING|TIME}_VALUE with Type_handler
+--echo #
+
+FLUSH LOGS;
+CREATE TABLE t1 (a INT);
+EXECUTE IMMEDIATE 'INSERT INTO t1 SELECT 1 LIMIT ?' USING 10;
+EXECUTE IMMEDIATE 'INSERT INTO t1 SELECT 1 LIMIT ?' USING 10.1;
+EXECUTE IMMEDIATE 'INSERT INTO t1 SELECT 1 LIMIT ?' USING 10.1e0;
+EXECUTE IMMEDIATE 'INSERT INTO t1 SELECT 1 LIMIT ?' USING '10';
+EXECUTE IMMEDIATE 'INSERT INTO t1 SELECT 1 LIMIT ?' USING TIME'10:10:10';
+DROP TABLE t1;
+
+--let $binlog_file = LAST
+source include/show_binlog_events.inc;
diff --git a/mysql-test/suite/binlog/t/load_data_stm_view.test b/mysql-test/suite/binlog/t/load_data_stm_view.test
index b70651b4e2d..9f64b813eec 100644
--- a/mysql-test/suite/binlog/t/load_data_stm_view.test
+++ b/mysql-test/suite/binlog/t/load_data_stm_view.test
@@ -8,6 +8,8 @@
1
EOF
+reset master;
+
create table t1 (i int, j int);
create view v1 as select i from t1;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
@@ -15,6 +17,8 @@ create view v1 as select i from t1;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/3940.data' INTO TABLE v1
select * from v1;
+--let $binlog_file = LAST
--source include/show_binlog_events.inc
drop view v1;
drop table t1;
+--remove_file $MYSQLTEST_VARDIR/3940.data
diff --git a/mysql-test/suite/binlog_encryption/binlog_row_annotate.result b/mysql-test/suite/binlog_encryption/binlog_row_annotate.result
index e72fc9faa6e..790fe225d7a 100644
--- a/mysql-test/suite/binlog_encryption/binlog_row_annotate.result
+++ b/mysql-test/suite/binlog_encryption/binlog_row_annotate.result
@@ -163,6 +163,7 @@ BEGIN
### INSERT INTO `test1`.`t1`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -189,6 +190,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -215,6 +217,7 @@ BEGIN
### INSERT INTO `test3`.`t3`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -256,6 +259,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 6
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -282,6 +286,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -310,6 +315,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -387,6 +393,7 @@ BEGIN
### INSERT INTO `test1`.`t1`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -551,6 +558,7 @@ BEGIN
### INSERT INTO `test1`.`t1`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -574,6 +582,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -597,6 +606,7 @@ BEGIN
### INSERT INTO `test3`.`t3`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -633,6 +643,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 6
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -656,6 +667,7 @@ BEGIN
### INSERT INTO `test2`.`t2`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -679,6 +691,7 @@ BEGIN
### DELETE FROM `test2`.`t2`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# Number of rows: 3
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
diff --git a/mysql-test/suite/binlog_encryption/rpl_semi_sync.result b/mysql-test/suite/binlog_encryption/rpl_semi_sync.result
index 6d574681d73..106efb555d3 100644
--- a/mysql-test/suite/binlog_encryption/rpl_semi_sync.result
+++ b/mysql-test/suite/binlog_encryption/rpl_semi_sync.result
@@ -4,6 +4,7 @@ connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
+call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave;
call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply");
@@ -176,7 +177,7 @@ Variable_name Value
Rpl_semi_sync_master_yes_tx 14
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
-Rpl_semi_sync_master_clients 1
+Rpl_semi_sync_master_clients 0
[ semi-sync replication of these transactions will fail ]
insert into t1 values (500);
[ master status should be OFF ]
@@ -321,7 +322,6 @@ connection slave;
include/stop_slave.inc
reset slave;
connection master;
-kill query _tid;
connection slave;
include/start_slave.inc
connection master;
@@ -353,7 +353,6 @@ include/stop_slave.inc
reset slave;
connection master;
reset master;
-kill query _tid;
set sql_log_bin=0;
grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password';
flush privileges;
@@ -404,7 +403,6 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
Variable_name Value
Rpl_semi_sync_slave_status OFF
connection master;
-kill query _tid;
[ Semi-sync status on master should be ON ]
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
diff --git a/mysql-test/suite/compat/oracle/r/empty_string_literal.result b/mysql-test/suite/compat/oracle/r/empty_string_literal.result
index 6bd268e7138..4fac736367b 100644
--- a/mysql-test/suite/compat/oracle/r/empty_string_literal.result
+++ b/mysql-test/suite/compat/oracle/r/empty_string_literal.result
@@ -11,7 +11,7 @@ SET SESSION character_set_client=cp1250;
SET sql_mode=@mode;
select @@sql_mode;
@@sql_mode
-PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,EMPTY_STRING_IS_NULL
+PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT
SELECT '',CHARSET(''), null, CHARSET(null), CAST(null as char(10)), CHARSET(CAST(null as char(10))), 'x', CHARSET('x');
NULL CHARSET('') NULL CHARSET(null) CAST(null as char(10)) CHARSET(CAST(null as char(10))) x CHARSET('x')
NULL latin2 NULL binary NULL latin2 x latin2
diff --git a/mysql-test/suite/compat/oracle/r/ps.result b/mysql-test/suite/compat/oracle/r/ps.result
index ed7cb4c51d5..158d15e9f90 100644
--- a/mysql-test/suite/compat/oracle/r/ps.result
+++ b/mysql-test/suite/compat/oracle/r/ps.result
@@ -247,3 +247,18 @@ DROP PROCEDURE p1;
#
# End of MDEV-10866 Extend PREPARE and EXECUTE IMMEDIATE to understand expressions
#
+#
+# MDEV-12846 sql_mode=ORACLE: using Oracle-style placeholders in direct query execution makes the server crash
+#
+SELECT ? FROM DUAL;
+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 DUAL' at line 1
+SELECT :a FROM DUAL;
+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 ':a FROM DUAL' at line 1
+SELECT :1 FROM DUAL;
+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 ':1 FROM DUAL' at line 1
+SELECT 1+? FROM DUAL;
+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 DUAL' at line 1
+SELECT 1+:a FROM DUAL;
+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 ':a FROM DUAL' at line 1
+SELECT 1+:1 FROM DUAL;
+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 ':1 FROM DUAL' at line 1
diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result
index 3030a3dc658..a46daf30a8f 100644
--- a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result
+++ b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result
@@ -1359,3 +1359,36 @@ t2 CREATE TABLE "t2" (
"b" varchar(3) DEFAULT NULL,
"c" time DEFAULT NULL
)
+#
+# MDEV-14388 Server crashes in handle_select / val_uint in ORACLE mode
+#
+CREATE TABLE t1 (id INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3);
+CREATE FUNCTION f1() RETURN INT is
+BEGIN
+FOR v1 in (SELECT id FROM t1)
+LOOP
+NULL;
+END LOOP;
+RETURN 1;
+END;
+$$
+SELECT f1();
+f1()
+1
+DROP FUNCTION f1;
+DROP TABLE t1;
+CREATE TABLE t1 (id INT);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+CREATE FUNCTION f1() RETURN INT IS
+CURSOR cur IS SELECT id FROM t1;
+rec cur%ROWTYPE;
+BEGIN
+RETURN 1;
+END;
+$$
+SELECT f1();
+f1()
+1
+DROP FUNCTION f1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/compat/oracle/r/sp-param.result b/mysql-test/suite/compat/oracle/r/sp-param.result
index 93db24709d0..68ecefa5077 100644
--- a/mysql-test/suite/compat/oracle/r/sp-param.result
+++ b/mysql-test/suite/compat/oracle/r/sp-param.result
@@ -5,7 +5,7 @@ SET sql_mode=ORACLE;
CREATE FUNCTION f1(param CHAR) RETURN CHAR AS BEGIN RETURN param; END;;
SHOW CREATE FUNCTION f1;
Function sql_mode Create Function character_set_client collation_connection Database Collation
-f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param CHAR) RETURN varchar(2000) CHARSET latin1
+f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param CHAR) RETURN varchar(2000) CHARSET latin1
AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci
SELECT LENGTH(f1(REPEAT('a',2000)));;
LENGTH(f1(REPEAT('a',2000)))
@@ -21,7 +21,7 @@ DROP FUNCTION f1;
CREATE FUNCTION f1(param NCHAR) RETURN NCHAR AS BEGIN RETURN param; END;;
SHOW CREATE FUNCTION f1;
Function sql_mode Create Function character_set_client collation_connection Database Collation
-f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param NCHAR) RETURN varchar(2000) CHARSET utf8
+f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param NCHAR) RETURN varchar(2000) CHARSET utf8
AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci
SELECT LENGTH(f1(REPEAT('a',2000)));;
LENGTH(f1(REPEAT('a',2000)))
@@ -37,7 +37,7 @@ DROP FUNCTION f1;
CREATE FUNCTION f1(param BINARY) RETURN BINARY AS BEGIN RETURN param; END;;
SHOW CREATE FUNCTION f1;
Function sql_mode Create Function character_set_client collation_connection Database Collation
-f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param BINARY) RETURN varbinary(2000)
+f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param BINARY) RETURN varbinary(2000)
AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci
SELECT LENGTH(f1(REPEAT('a',2000)));;
LENGTH(f1(REPEAT('a',2000)))
@@ -53,7 +53,7 @@ DROP FUNCTION f1;
CREATE FUNCTION f1(param VARCHAR) RETURN VARCHAR AS BEGIN RETURN param; END;;
SHOW CREATE FUNCTION f1;
Function sql_mode Create Function character_set_client collation_connection Database Collation
-f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARCHAR) RETURN varchar(4000) CHARSET latin1
+f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARCHAR) RETURN varchar(4000) CHARSET latin1
AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci
SELECT LENGTH(f1(REPEAT('a',4000)));;
LENGTH(f1(REPEAT('a',4000)))
@@ -69,7 +69,7 @@ DROP FUNCTION f1;
CREATE FUNCTION f1(param VARCHAR2) RETURN VARCHAR2 AS BEGIN RETURN param; END;;
SHOW CREATE FUNCTION f1;
Function sql_mode Create Function character_set_client collation_connection Database Collation
-f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARCHAR2) RETURN varchar(4000) CHARSET latin1
+f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARCHAR2) RETURN varchar(4000) CHARSET latin1
AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci
SELECT LENGTH(f1(REPEAT('a',4000)));;
LENGTH(f1(REPEAT('a',4000)))
@@ -85,7 +85,7 @@ DROP FUNCTION f1;
CREATE FUNCTION f1(param NVARCHAR) RETURN NVARCHAR AS BEGIN RETURN param; END;;
SHOW CREATE FUNCTION f1;
Function sql_mode Create Function character_set_client collation_connection Database Collation
-f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param NVARCHAR) RETURN varchar(4000) CHARSET utf8
+f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param NVARCHAR) RETURN varchar(4000) CHARSET utf8
AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci
SELECT LENGTH(f1(REPEAT('a',4000)));;
LENGTH(f1(REPEAT('a',4000)))
@@ -101,7 +101,7 @@ DROP FUNCTION f1;
CREATE FUNCTION f1(param VARBINARY) RETURN VARBINARY AS BEGIN RETURN param; END;;
SHOW CREATE FUNCTION f1;
Function sql_mode Create Function character_set_client collation_connection Database Collation
-f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARBINARY) RETURN varbinary(4000)
+f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARBINARY) RETURN varbinary(4000)
AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci
SELECT LENGTH(f1(REPEAT('a',4000)));;
LENGTH(f1(REPEAT('a',4000)))
@@ -117,7 +117,7 @@ DROP FUNCTION f1;
CREATE FUNCTION f1(param RAW) RETURN RAW AS BEGIN RETURN param; END;;
SHOW CREATE FUNCTION f1;
Function sql_mode Create Function character_set_client collation_connection Database Collation
-f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param RAW) RETURN varbinary(4000)
+f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param RAW) RETURN varbinary(4000)
AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci
SELECT LENGTH(f1(REPEAT('a',4000)));;
LENGTH(f1(REPEAT('a',4000)))
diff --git a/mysql-test/suite/compat/oracle/r/sp-row.result b/mysql-test/suite/compat/oracle/r/sp-row.result
index f95817420f1..9557a24a1da 100644
--- a/mysql-test/suite/compat/oracle/r/sp-row.result
+++ b/mysql-test/suite/compat/oracle/r/sp-row.result
@@ -232,7 +232,7 @@ SELECT a=1;
END;
$$
CALL p1();
-ERROR 21000: Operand should contain 2 column(s)
+ERROR HY000: Illegal parameter data types row and int for operation '='
DROP PROCEDURE p1;
CREATE PROCEDURE p1()
AS
@@ -242,7 +242,7 @@ SELECT 1=a;
END;
$$
CALL p1();
-ERROR 21000: Operand should contain 1 column(s)
+ERROR HY000: Illegal parameter data types int and row for operation '='
DROP PROCEDURE p1;
#
# Passing the entire ROW to a stored function
diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result
index 53411e80251..f0a7d2808f1 100644
--- a/mysql-test/suite/compat/oracle/r/sp.result
+++ b/mysql-test/suite/compat/oracle/r/sp.result
@@ -8,7 +8,7 @@ END;
/
SHOW CREATE FUNCTION f1;
Function f1
-sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
+sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT
Create Function CREATE DEFINER="root"@"localhost" FUNCTION "f1"() RETURN int(11)
AS
BEGIN
@@ -29,7 +29,7 @@ END;
/
SHOW CREATE PROCEDURE p1;
Procedure p1
-sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
+sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT
Create Procedure CREATE DEFINER="root"@"localhost" PROCEDURE "p1"()
AS
BEGIN
@@ -2404,3 +2404,94 @@ t1 CREATE TABLE "t1" (
"aa_timestamp5" timestamp(5) NULL DEFAULT NULL,
"aa_date0" datetime DEFAULT NULL
)
+#
+# MDEV-11160 "Incorrect column name" when "CREATE TABLE t1 AS SELECT spvar"
+#
+CREATE TABLE t1 (x INT);
+INSERT INTO t1 VALUES (10);
+CREATE VIEW v1 AS SELECT x+1 AS a,x+1 AS b FROM t1;
+CREATE PROCEDURE p1
+AS
+a INT := 1;
+b INT := 2;
+BEGIN
+CREATE TABLE t2 AS SELECT a,b FROM v1;
+SHOW CREATE TABLE t2;
+SELECT * FROM t2;
+DROP TABLE t2;
+END;
+$$
+CALL p1();
+Table Create Table
+t2 CREATE TABLE "t2" (
+ "a" int(11) DEFAULT NULL,
+ "b" int(11) DEFAULT NULL
+)
+a b
+1 2
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# MDEV-14228 MariaDB crashes with function
+#
+CREATE TABLE t1 (c VARCHAR(16), KEY(c));
+INSERT INTO t1 VALUES ('foo');
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+v VARCHAR2(16);
+BEGIN
+FOR v IN (SELECT DISTINCT c FROM t1)
+LOOP
+IF (v = 'bar') THEN
+SELECT 1 INTO @a;
+END IF;
+END LOOP;
+RETURN 'qux';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+v t1%ROWTYPE;
+BEGIN
+IF v = 'bar' THEN
+NULL;
+END IF;
+RETURN 'qux';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+v ROW(a INT);
+BEGIN
+IF v = 'bar' THEN
+NULL;
+END IF;
+RETURN 'qux';
+END $$
+SELECT f1();
+ERROR HY000: Illegal parameter data types row and varchar for operation '='
+DROP FUNCTION f1;
+DROP TABLE t1;
+DECLARE
+v ROW(a INT);
+BEGIN
+SELECT v IN ('a','b');
+END $$
+ERROR HY000: Illegal parameter data types row and varchar for operation 'in'
+DECLARE
+v ROW(a INT);
+BEGIN
+SELECT 'a' IN (v,'b');
+END $$
+ERROR HY000: Illegal parameter data types varchar and row for operation 'in'
+DECLARE
+v ROW(a INT);
+BEGIN
+SELECT 'a' IN ('b',v);
+END $$
+ERROR HY000: Illegal parameter data types varchar and row for operation 'in'
diff --git a/mysql-test/suite/compat/oracle/t/ps.test b/mysql-test/suite/compat/oracle/t/ps.test
index 08bb957c33f..357b50e0eab 100644
--- a/mysql-test/suite/compat/oracle/t/ps.test
+++ b/mysql-test/suite/compat/oracle/t/ps.test
@@ -264,3 +264,27 @@ DROP PROCEDURE p1;
--echo #
--echo # End of MDEV-10866 Extend PREPARE and EXECUTE IMMEDIATE to understand expressions
--echo #
+
+
+--echo #
+--echo # MDEV-12846 sql_mode=ORACLE: using Oracle-style placeholders in direct query execution makes the server crash
+--echo #
+
+# When running with --ps, the below queries return
+# CR_PARAMS_NOT_BOUND instead of ER_PARSE_ERROR
+
+--disable_ps_protocol
+--error ER_PARSE_ERROR
+SELECT ? FROM DUAL;
+--error ER_PARSE_ERROR
+SELECT :a FROM DUAL;
+--error ER_PARSE_ERROR
+SELECT :1 FROM DUAL;
+
+--error ER_PARSE_ERROR
+SELECT 1+? FROM DUAL;
+--error ER_PARSE_ERROR
+SELECT 1+:a FROM DUAL;
+--error ER_PARSE_ERROR
+SELECT 1+:1 FROM DUAL;
+--enable_ps_protocol
diff --git a/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test b/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test
index 19a50eacca1..fd148d1f261 100644
--- a/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test
+++ b/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test
@@ -1444,3 +1444,39 @@ BEGIN
END;
$$
DELIMITER ;$$
+
+--echo #
+--echo # MDEV-14388 Server crashes in handle_select / val_uint in ORACLE mode
+--echo #
+
+CREATE TABLE t1 (id INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3);
+DELIMITER $$;
+CREATE FUNCTION f1() RETURN INT is
+BEGIN
+ FOR v1 in (SELECT id FROM t1)
+ LOOP
+ NULL;
+ END LOOP;
+ RETURN 1;
+END;
+$$
+DELIMITER ;$$
+SELECT f1();
+DROP FUNCTION f1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (id INT);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+DELIMITER $$;
+CREATE FUNCTION f1() RETURN INT IS
+ CURSOR cur IS SELECT id FROM t1;
+ rec cur%ROWTYPE;
+BEGIN
+ RETURN 1;
+END;
+$$
+DELIMITER ;$$
+SELECT f1();
+DROP FUNCTION f1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/compat/oracle/t/sp-row.test b/mysql-test/suite/compat/oracle/t/sp-row.test
index b26cae5a5c6..469494ad228 100644
--- a/mysql-test/suite/compat/oracle/t/sp-row.test
+++ b/mysql-test/suite/compat/oracle/t/sp-row.test
@@ -295,7 +295,7 @@ BEGIN
END;
$$
DELIMITER ;$$
---error ER_OPERAND_COLUMNS
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
@@ -309,7 +309,7 @@ BEGIN
END;
$$
DELIMITER ;$$
---error ER_OPERAND_COLUMNS
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test
index 61a37459483..693569d184c 100644
--- a/mysql-test/suite/compat/oracle/t/sp.test
+++ b/mysql-test/suite/compat/oracle/t/sp.test
@@ -2233,3 +2233,117 @@ BEGIN
END;
$$
DELIMITER ;$$
+
+
+--echo #
+--echo # MDEV-11160 "Incorrect column name" when "CREATE TABLE t1 AS SELECT spvar"
+--echo #
+
+
+CREATE TABLE t1 (x INT);
+INSERT INTO t1 VALUES (10);
+CREATE VIEW v1 AS SELECT x+1 AS a,x+1 AS b FROM t1;
+DELIMITER $$;
+CREATE PROCEDURE p1
+AS
+ a INT := 1;
+ b INT := 2;
+BEGIN
+ CREATE TABLE t2 AS SELECT a,b FROM v1;
+ SHOW CREATE TABLE t2;
+ SELECT * FROM t2;
+ DROP TABLE t2;
+END;
+$$
+DELIMITER ;$$
+CALL p1();
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-14228 MariaDB crashes with function
+--echo #
+
+CREATE TABLE t1 (c VARCHAR(16), KEY(c));
+INSERT INTO t1 VALUES ('foo');
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+ v VARCHAR2(16);
+BEGIN
+ FOR v IN (SELECT DISTINCT c FROM t1)
+ LOOP
+ IF (v = 'bar') THEN
+ SELECT 1 INTO @a;
+ END IF;
+ END LOOP;
+ RETURN 'qux';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+ v t1%ROWTYPE;
+BEGIN
+ IF v = 'bar' THEN
+ NULL;
+ END IF;
+ RETURN 'qux';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURN VARCHAR(16)
+IS
+ v ROW(a INT);
+BEGIN
+ IF v = 'bar' THEN
+ NULL;
+ END IF;
+ RETURN 'qux';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DROP TABLE t1;
+
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+DECLARE
+ v ROW(a INT);
+BEGIN
+ SELECT v IN ('a','b');
+END $$
+DELIMITER ;$$
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+DECLARE
+ v ROW(a INT);
+BEGIN
+ SELECT 'a' IN (v,'b');
+END $$
+DELIMITER ;$$
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+DECLARE
+ v ROW(a INT);
+BEGIN
+ SELECT 'a' IN ('b',v);
+END $$
+DELIMITER ;$$
+
diff --git a/mysql-test/suite/csv/read_only.result b/mysql-test/suite/csv/read_only.result
index d6936681f65..1a98572d6b7 100644
--- a/mysql-test/suite/csv/read_only.result
+++ b/mysql-test/suite/csv/read_only.result
@@ -23,6 +23,8 @@ TABLE_COLLATION NULL
CHECKSUM NULL
CREATE_OPTIONS NULL
TABLE_COMMENT File './test/t1.CSM' not found (Errcode: 13 "Permission denied")
+MAX_INDEX_LENGTH NULL
+TEMPORARY NULL
Warnings:
Level Warning
Code 29
diff --git a/mysql-test/suite/encryption/disabled.def b/mysql-test/suite/encryption/disabled.def
index 9d9d1cd9df9..08f8bd8542b 100644
--- a/mysql-test/suite/encryption/disabled.def
+++ b/mysql-test/suite/encryption/disabled.def
@@ -13,3 +13,4 @@
innodb_scrub : MDEV-8139 scrubbing does not work reliably
innodb_scrub_background : MDEV-8139 scrubbing does not work reliably
innodb-redo-badkey : MDEV-13893 / MDEV-12699 Improve crash recovery of corrupted data pages
+innodb_encryption-page-compression : MDEV-14814 wait condition timeout
diff --git a/mysql-test/suite/encryption/r/encrypt_and_grep.result b/mysql-test/suite/encryption/r/encrypt_and_grep.result
index 05ebefd28b5..cbc05dc7cc6 100644
--- a/mysql-test/suite/encryption/r/encrypt_and_grep.result
+++ b/mysql-test/suite/encryption/r/encrypt_and_grep.result
@@ -15,6 +15,7 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
mysql/innodb_table_stats
mysql/innodb_index_stats
+mysql/transaction_registry
test/t1
test/t2
innodb_system
@@ -33,6 +34,7 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
mysql/innodb_table_stats
mysql/innodb_index_stats
+mysql/transaction_registry
test/t2
test/t3
innodb_system
@@ -57,6 +59,7 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
mysql/innodb_table_stats
mysql/innodb_index_stats
+mysql/transaction_registry
test/t1
test/t2
innodb_system
diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change.result b/mysql-test/suite/encryption/r/innodb-bad-key-change.result
index 71ad4909899..4556ed3e205 100644
--- a/mysql-test/suite/encryption/r/innodb-bad-key-change.result
+++ b/mysql-test/suite/encryption/r/innodb-bad-key-change.result
@@ -2,6 +2,7 @@ call mtr.add_suppression("Plugin 'file_key_management' init function returned er
call mtr.add_suppression("Plugin 'file_key_management' registration.*failed");
call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[12]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found");
# Start server with keys2.txt
SET GLOBAL innodb_file_per_table = ON;
@@ -27,16 +28,9 @@ foobar 2
# Restart server with keysbad3.txt
SELECT * FROM t1;
ERROR 42S02: Table 'test.t1' doesn't exist in engine
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table test/t1 in tablespace is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1932 Table 'test.t1' doesn't exist in engine
DROP TABLE t1;
Warnings:
Warning 192 Table test/t1 in tablespace is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table test/t1 in tablespace is encrypted but encryption service or used key_id is not available. Can't continue reading table.
# Start server with keys3.txt
SET GLOBAL innodb_default_encryption_key_id=5;
CREATE TABLE t2 (c VARCHAR(8), id int not null primary key, b int, key(b)) ENGINE=InnoDB ENCRYPTED=YES;
@@ -45,62 +39,30 @@ INSERT INTO t2 VALUES ('foobar',1,2);
# Restart server with keys2.txt
SELECT * FROM t2;
ERROR 42S02: Table 'test.t2' doesn't exist in engine
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table test/t2 in tablespace is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1932 Table 'test.t2' doesn't exist in engine
SELECT * FROM t2 where id = 1;
ERROR 42S02: Table 'test.t2' doesn't exist in engine
-SHOW WARNINGS;
-Level Code Message
-Error 1932 Table 'test.t2' doesn't exist in engine
SELECT * FROM t2 where b = 1;
ERROR 42S02: Table 'test.t2' doesn't exist in engine
-SHOW WARNINGS;
-Level Code Message
-Error 1932 Table 'test.t2' doesn't exist in engine
INSERT INTO t2 VALUES ('tmp',3,3);
ERROR 42S02: Table 'test.t2' doesn't exist in engine
-SHOW WARNINGS;
-Level Code Message
-Error 1932 Table 'test.t2' doesn't exist in engine
DELETE FROM t2 where b = 3;
ERROR 42S02: Table 'test.t2' doesn't exist in engine
-SHOW WARNINGS;
-Level Code Message
-Error 1932 Table 'test.t2' doesn't exist in engine
DELETE FROM t2 where id = 3;
ERROR 42S02: Table 'test.t2' doesn't exist in engine
-SHOW WARNINGS;
-Level Code Message
-Error 1932 Table 'test.t2' doesn't exist in engine
UPDATE t2 set b = b +1;
ERROR 42S02: Table 'test.t2' doesn't exist in engine
-SHOW WARNINGS;
-Level Code Message
-Error 1932 Table 'test.t2' doesn't exist in engine
OPTIMIZE TABLE t2;
Table Op Msg_type Msg_text
test.t2 optimize Error Table 'test.t2' doesn't exist in engine
test.t2 optimize status Operation failed
-SHOW WARNINGS;
-Level Code Message
ALTER TABLE t2 ADD COLUMN d INT;
ERROR 42S02: Table 'test.t2' doesn't exist in engine
-SHOW WARNINGS;
-Level Code Message
-Error 1932 Table 'test.t2' doesn't exist in engine
ANALYZE TABLE t2;
Table Op Msg_type Msg_text
test.t2 analyze Error Table 'test.t2' doesn't exist in engine
test.t2 analyze status Operation failed
-SHOW WARNINGS;
-Level Code Message
TRUNCATE TABLE t2;
ERROR 42S02: Table 'test.t2' doesn't exist in engine
-SHOW WARNINGS;
-Level Code Message
-Error 1932 Table 'test.t2' doesn't exist in engine
DROP TABLE t2;
# Start server with keys2.txt
diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result
index 087f76eda2d..3cc0de66de9 100644
--- a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result
+++ b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result
@@ -1,5 +1,6 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page|is corrupted|does not exist.*is trying to rename)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t1(new)?\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
call mtr.add_suppression("Couldn't load plugins from 'file_key_management");
call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as discarded\\.");
SET GLOBAL innodb_file_per_table = ON;
diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change4.result b/mysql-test/suite/encryption/r/innodb-bad-key-change4.result
index 514a0aec051..b6300a81be7 100644
--- a/mysql-test/suite/encryption/r/innodb-bad-key-change4.result
+++ b/mysql-test/suite/encryption/r/innodb-bad-key-change4.result
@@ -1,5 +1,6 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t1\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
call mtr.add_suppression("Couldn't load plugins from 'file_key_management");
SET GLOBAL innodb_file_per_table = ON;
CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB
diff --git a/mysql-test/suite/encryption/r/innodb-compressed-blob.result b/mysql-test/suite/encryption/r/innodb-compressed-blob.result
index bf43e1b30d6..e156266edc6 100644
--- a/mysql-test/suite/encryption/r/innodb-compressed-blob.result
+++ b/mysql-test/suite/encryption/r/innodb-compressed-blob.result
@@ -1,4 +1,5 @@
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
call mtr.add_suppression("InnoDB: Unable to decompress ..test.t[1-3]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]");
# Restart mysqld --file-key-management-filename=keys2.txt
SET GLOBAL innodb_file_per_table = ON;
diff --git a/mysql-test/suite/encryption/r/innodb-encryption-disable.result b/mysql-test/suite/encryption/r/innodb-encryption-disable.result
index 74570c92ae0..d8d37ba7493 100644
--- a/mysql-test/suite/encryption/r/innodb-encryption-disable.result
+++ b/mysql-test/suite/encryption/r/innodb-encryption-disable.result
@@ -1,5 +1,6 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[15]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
call mtr.add_suppression("Couldn't load plugins from 'file_key_management");
create table t5 (
`intcol1` int(32) DEFAULT NULL,
diff --git a/mysql-test/suite/encryption/r/innodb-force-corrupt.result b/mysql-test/suite/encryption/r/innodb-force-corrupt.result
index d27136bf430..4c8ee2ef4de 100644
--- a/mysql-test/suite/encryption/r/innodb-force-corrupt.result
+++ b/mysql-test/suite/encryption/r/innodb-force-corrupt.result
@@ -1,5 +1,6 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
SET GLOBAL innodb_file_per_table = ON;
set global innodb_compression_algorithm = 1;
# Create and populate tables to be corrupted
diff --git a/mysql-test/suite/encryption/r/innodb-missing-key.result b/mysql-test/suite/encryption/r/innodb-missing-key.result
index 2c5401ff681..32ae29ca76b 100644
--- a/mysql-test/suite/encryption/r/innodb-missing-key.result
+++ b/mysql-test/suite/encryption/r/innodb-missing-key.result
@@ -1,5 +1,6 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
# Start server with keys2.txt
CREATE TABLE t1(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=19;
CREATE TABLE t2(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=1;
diff --git a/mysql-test/suite/encryption/r/innodb-redo-badkey.result b/mysql-test/suite/encryption/r/innodb-redo-badkey.result
index f600b96f987..9104cac18da 100644
--- a/mysql-test/suite/encryption/r/innodb-redo-badkey.result
+++ b/mysql-test/suite/encryption/r/innodb-redo-badkey.result
@@ -1,6 +1,7 @@
call mtr.add_suppression("Plugin 'file_key_management'");
call mtr.add_suppression("Plugin 'InnoDB' init function returned error.");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[0-9]+\\] in file .*test/t[1-4]\\.ibd cannot be decrypted");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
call mtr.add_suppression("InnoDB: Unable to decompress .*.test.t1\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]");
call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed file read of tablespace test/t1 page \\[page id: space=[1-9][0-9]*, page number=[0-9]*\\]");
call mtr.add_suppression("InnoDB: Plugin initialization aborted");
diff --git a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result
index 530d228cc85..251ea73cd4c 100644
--- a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result
+++ b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result
@@ -1,10 +1,10 @@
-call mtr.add_suppression("InnoDB: Block in space_id .*");
call mtr.add_suppression("mysqld: File .*");
call mtr.add_suppression("Plugin 'file_key_management' .*");
call mtr.add_suppression("InnoDB: cannot enable encryption, encryption plugin is not available");
call mtr.add_suppression("Plugin 'InnoDB' init function returned error.");
call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed.");
-call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[0-9]+\\] in file test/t[1-4] cannot be decrypted");
+call mtr.add_suppression("InnoDB: The page \\[page id: space=[0-9]+, page number=[0-9]+\\] in file '.*test.t[1-4]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
# Restart mysqld --file-key-management-filename=keys2.txt
SET GLOBAL innodb_file_per_table = ON;
create table t1(a int not null primary key auto_increment, c char(200), b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes encryption_key_id=20;
diff --git a/mysql-test/suite/encryption/r/innodb-spatial-index.result b/mysql-test/suite/encryption/r/innodb-spatial-index.result
index d8f76988f9e..e8e133c61a1 100644
--- a/mysql-test/suite/encryption/r/innodb-spatial-index.result
+++ b/mysql-test/suite/encryption/r/innodb-spatial-index.result
@@ -38,6 +38,7 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
mysql/innodb_table_stats
mysql/innodb_index_stats
+mysql/transaction_registry
test/t1
test/t2
innodb_system
diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result b/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result
index 6eb92aedeb7..8b58ff593de 100644
--- a/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result
+++ b/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result
@@ -17,6 +17,13 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /InnoDB: Upgrade after a crash is not supported. This redo log was created before MariaDB 10\.2\.2, and it appears corrupted/ in mysqld.1.err
+# empty redo log from before MariaDB 10.2.2
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+COUNT(*)
+1
+FOUND 1 /InnoDB: Upgrading redo log:/ in mysqld.1.err
# redo log from "after" MariaDB 10.2.2, but with invalid header checksum
SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
@@ -40,14 +47,15 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
-FOUND 1 /InnoDB: Upgrade after a crash is not supported\. The redo log was created with malicious intentions, or perhaps, and it appears corrupted\./ in mysqld.1.err
+FOUND 1 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122/ in mysqld.1.err
+FOUND 1 /InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\./ in mysqld.1.err
# same, but with current-version header
SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
-FOUND 1 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122/ in mysqld.1.err
-FOUND 1 /InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\./ in mysqld.1.err
+FOUND 2 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122/ in mysqld.1.err
+FOUND 2 /InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\./ in mysqld.1.err
# --innodb-force-recovery=6 (skip the entire redo log)
SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
@@ -92,18 +100,38 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /InnoDB: MLOG_FILE_NAME incorrect:bigot/ in mysqld.1.err
FOUND 1 /len 22; hex 38000000000012860cb7809781e800066269676f7400; asc 8 bigot ;/ in mysqld.1.err
-# missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
+# 10.2 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
-NOT FOUND /InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42$/ in mysqld.1.err
+FOUND 1 /InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42/ in mysqld.1.err
+# 10.3 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
+SELECT * FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
+FOUND 2 /InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42/ in mysqld.1.err
+# Empty 10.3 redo log
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+COUNT(*)
+1
+FOUND 1 /InnoDB: .* started; log sequence number 121397[09]/ in mysqld.1.err
+# Empty 10.2 redo log
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+COUNT(*)
+1
+FOUND 2 /InnoDB: Upgrading redo log:/ in mysqld.1.err
# Minimal MariaDB 10.1.21 encrypted redo log
SELECT COUNT(*) `1` FROM INFORMATION_SCHEMA.ENGINES WHERE engine='innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
1
1
-FOUND 1 /InnoDB: Encrypting redo log/ in mysqld.1.err
+FOUND 2 /InnoDB: Encrypting redo log/ in mysqld.1.err
ib_buffer_pool
ib_logfile0
ib_logfile1
diff --git a/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result b/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result
index fd2f03a5d18..bf5698f97fa 100644
--- a/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result
+++ b/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result
@@ -135,18 +135,19 @@ count(*)
select count(*) from innodb_page_compressed9 where c1 < 500000;
count(*)
2000
+flush tables innodb_page_compressed1, innodb_page_compressed2,
+innodb_page_compressed3, innodb_page_compressed4,
+innodb_page_compressed5, innodb_page_compressed6,
+innodb_page_compressed7, innodb_page_compressed8,
+innodb_page_compressed9 for export;
+unlock tables;
+# Wait until dirty pages are compressed and encrypted
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
SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed';
variable_value > 0
1
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed';
-variable_value >= 0
-1
SET GLOBAL innodb_encryption_threads = 4;
SET GLOBAL innodb_encrypt_tables = off;
update innodb_page_compressed1 set c1 = c1 + 1;
@@ -158,17 +159,22 @@ update innodb_page_compressed6 set c1 = c1 + 1;
update innodb_page_compressed7 set c1 = c1 + 1;
update innodb_page_compressed8 set c1 = c1 + 1;
update innodb_page_compressed9 set c1 = c1 + 1;
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted';
-variable_value >= 0
-1
+flush tables innodb_page_compressed1, innodb_page_compressed2,
+innodb_page_compressed3, innodb_page_compressed4,
+innodb_page_compressed5, innodb_page_compressed6,
+innodb_page_compressed7, innodb_page_compressed8,
+innodb_page_compressed9 for export;
+unlock tables;
+# Wait until dirty pages are compressed and encrypted 2
+unlock tables;
SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted';
variable_value > 0
1
SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed';
variable_value > 0
1
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed';
-variable_value >= 0
+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;
diff --git a/mysql-test/suite/encryption/r/innodb_encryption.result b/mysql-test/suite/encryption/r/innodb_encryption.result
index 72f2632ba26..ee3774bcee0 100644
--- a/mysql-test/suite/encryption/r/innodb_encryption.result
+++ b/mysql-test/suite/encryption/r/innodb_encryption.result
@@ -14,6 +14,7 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
mysql/innodb_table_stats
mysql/innodb_index_stats
+mysql/transaction_registry
innodb_system
# Success!
# Now turn off encryption and wait for threads to decrypt everything
@@ -23,6 +24,7 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
mysql/innodb_table_stats
mysql/innodb_index_stats
+mysql/transaction_registry
innodb_system
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
NAME
@@ -37,6 +39,7 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
mysql/innodb_table_stats
mysql/innodb_index_stats
+mysql/transaction_registry
innodb_system
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
NAME
@@ -50,6 +53,7 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
mysql/innodb_table_stats
mysql/innodb_index_stats
+mysql/transaction_registry
innodb_system
# Success!
# Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0
@@ -64,6 +68,7 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
mysql/innodb_table_stats
mysql/innodb_index_stats
+mysql/transaction_registry
innodb_system
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
NAME
diff --git a/mysql-test/suite/encryption/r/innodb_encryption_filekeys.result b/mysql-test/suite/encryption/r/innodb_encryption_filekeys.result
index 54cdf842b20..118da0635d9 100644
--- a/mysql-test/suite/encryption/r/innodb_encryption_filekeys.result
+++ b/mysql-test/suite/encryption/r/innodb_encryption_filekeys.result
@@ -1,4 +1,3 @@
-call mtr.add_suppression("trying to do an operation on a dropped tablespace .*");
SET GLOBAL innodb_encrypt_tables = OFF;
SET GLOBAL innodb_encryption_threads = 4;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB;
@@ -12,24 +11,21 @@ t1 CREATE TABLE `t1` (
CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES;
CREATE TABLE t3 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO;
CREATE TABLE t4 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4;
-INSERT INTO t2 select * from t1;
-INSERT INTO t3 select * from t1;
-INSERT INTO t4 select * from t1;
SET GLOBAL innodb_encrypt_tables = on;
# Wait max 10 min for key encryption threads to encrypt required all spaces
# Success!
SELECT COUNT(1) FROM t1;
COUNT(1)
-400
+10
SELECT COUNT(1) FROM t2;
COUNT(1)
-400
+10
SELECT COUNT(1) FROM t3;
COUNT(1)
-400
+10
SELECT COUNT(1) FROM t4;
COUNT(1)
-400
+10
SET GLOBAL innodb_encrypt_tables = off;
# Wait max 10 min for key encryption threads to decrypt all required spaces
# Success!
@@ -48,18 +44,17 @@ INSERT INTO t5 select * from t1;
# Success!
SELECT COUNT(1) FROM t1;
COUNT(1)
-400
+10
SELECT COUNT(1) FROM t2;
COUNT(1)
-400
+10
SELECT COUNT(1) FROM t3;
COUNT(1)
-400
+10
SELECT COUNT(1) FROM t4;
COUNT(1)
-400
+10
SELECT COUNT(1) FROM t5;
COUNT(1)
-400
+10
drop table t1,t2,t3,t4, t5;
-set GLOBAL innodb_default_encryption_key_id=1;
diff --git a/mysql-test/suite/encryption/r/innodb_lotoftables.result b/mysql-test/suite/encryption/r/innodb_lotoftables.result
index da07a52f8c3..9dadf13f039 100644
--- a/mysql-test/suite/encryption/r/innodb_lotoftables.result
+++ b/mysql-test/suite/encryption/r/innodb_lotoftables.result
@@ -10,13 +10,13 @@ create database innodb_encrypted_1;
use innodb_encrypted_1;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 3
+Innodb_pages0_read 4
set autocommit=0;
set autocommit=1;
commit work;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 3
+Innodb_pages0_read 4
# should be empty
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE NAME LIKE 'innodb_encrypted%';
NAME
@@ -24,13 +24,13 @@ create database innodb_encrypted_2;
use innodb_encrypted_2;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 3
+Innodb_pages0_read 4
set autocommit=0;
commit work;
set autocommit=1;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 3
+Innodb_pages0_read 4
# should contain 100 tables
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
NAME
@@ -141,13 +141,13 @@ create database innodb_encrypted_3;
use innodb_encrypted_3;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 3
+Innodb_pages0_read 4
set autocommit=0;
commit work;
set autocommit=1;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 3
+Innodb_pages0_read 4
# should contain 100 tables
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
NAME
@@ -357,7 +357,7 @@ innodb_encrypted_3/t_99
use test;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 3
+Innodb_pages0_read 4
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
NAME
innodb_encrypted_2/t_1
@@ -770,53 +770,53 @@ innodb_encrypted_3/t_98
innodb_encrypted_3/t_99
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 3
+Innodb_pages0_read 4
# Success!
# Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0
# Restart Success!
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
use test;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
use innodb_encrypted_1;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
use innodb_encrypted_2;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
use innodb_encrypted_3;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
use innodb_encrypted_1;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
use innodb_encrypted_2;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
use innodb_encrypted_3;
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
show status like 'innodb_pages0_read%';
Variable_name Value
-Innodb_pages0_read 303
+Innodb_pages0_read 304
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
NAME
innodb_encrypted_3/t_1
diff --git a/mysql-test/suite/encryption/r/tempfiles.result b/mysql-test/suite/encryption/r/tempfiles.result
index e335e644400..45d9d379473 100644
--- a/mysql-test/suite/encryption/r/tempfiles.result
+++ b/mysql-test/suite/encryption/r/tempfiles.result
@@ -1,3 +1,6 @@
+select @@encrypt_tmp_files;
+@@encrypt_tmp_files
+1
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(1),(2);
DELETE FROM t1 WHERE a=1;
@@ -25,6 +28,7 @@ h 10
i 10
j 10
drop table t1;
+reset master;
set global binlog_cache_size=8192;
connect con1, localhost, root;
create table t1 (a text) engine=innodb;
@@ -34,18 +38,71 @@ commit;
start transaction;
insert t1 select repeat(seq, 1000) from seq_1_to_8;
commit;
-drop table t1;
disconnect con1;
connect con2, localhost, root;
-create table t1 (a text) engine=innodb;
+create table t2 (a text) engine=innodb;
start transaction;
-insert t1 select repeat(seq, 1000) from seq_1_to_15;
+insert t2 select repeat(seq, 1000) from seq_1_to_15;
savepoint foo;
-insert t1 select repeat(seq, 1000) from seq_16_to_30;
+insert t2 select repeat(seq, 1000) from seq_16_to_30;
rollback to savepoint foo;
-insert t1 select repeat(seq, 1000) from seq_31_to_40;
+insert t2 select repeat(seq, 1000) from seq_31_to_40;
commit;
-drop table t1;
disconnect con2;
connection default;
+flush binary logs;
+drop table t1, t2;
set global binlog_cache_size=default;
+select left(a, 10) from t1;
+left(a, 10)
+1111111111
+2222222222
+3333333333
+4444444444
+5555555555
+6666666666
+7777777777
+8888888888
+9999999999
+1010101010
+1111111111
+1212121212
+1313131313
+1414141414
+1515151515
+1111111111
+2222222222
+3333333333
+4444444444
+5555555555
+6666666666
+7777777777
+8888888888
+select left(a, 10) from t2;
+left(a, 10)
+1111111111
+2222222222
+3333333333
+4444444444
+5555555555
+6666666666
+7777777777
+8888888888
+9999999999
+1010101010
+1111111111
+1212121212
+1313131313
+1414141414
+1515151515
+3131313131
+3232323232
+3333333333
+3434343434
+3535353535
+3636363636
+3737373737
+3838383838
+3939393939
+4040404040
+drop table t1, t2;
diff --git a/mysql-test/suite/encryption/t/debug_key_management.test b/mysql-test/suite/encryption/t/debug_key_management.test
index 5001ac6a516..22b213c6135 100644
--- a/mysql-test/suite/encryption/t/debug_key_management.test
+++ b/mysql-test/suite/encryption/t/debug_key_management.test
@@ -8,13 +8,14 @@ if (`select count(*) = 0 from information_schema.plugins
set global innodb_encrypt_tables=ON;
show variables like 'innodb_encrypt%';
-let $wait_condition= select count(*) = 3 from information_schema.innodb_tablespaces_encryption where current_key_version=1;
+--let $tables_count= `select count(*) + 1 from information_schema.tables where engine = 'InnoDB'`
+let $wait_condition= select count(*) = $tables_count from information_schema.innodb_tablespaces_encryption where current_key_version=1;
--source include/wait_condition.inc
select count(*) from information_schema.innodb_tablespaces_encryption where current_key_version <> 1;
set global debug_key_management_version=10;
-let $wait_condition= select count(*) = 3 from information_schema.innodb_tablespaces_encryption where current_key_version=10;
+let $wait_condition= select count(*) = $tables_count from information_schema.innodb_tablespaces_encryption where current_key_version=10;
--source include/wait_condition.inc
select count(*) from information_schema.innodb_tablespaces_encryption where current_key_version <> 10;
diff --git a/mysql-test/suite/encryption/t/encrypt_and_grep.test b/mysql-test/suite/encryption/t/encrypt_and_grep.test
index b0bf41a640d..9f26f0a5b24 100644
--- a/mysql-test/suite/encryption/t/encrypt_and_grep.test
+++ b/mysql-test/suite/encryption/t/encrypt_and_grep.test
@@ -60,7 +60,8 @@ SET GLOBAL innodb_encrypt_tables = off;
--echo # Wait max 10 min for key encryption threads to decrypt all spaces
--let $wait_timeout= 600
---let $wait_condition=SELECT COUNT(*) = 5 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND CURRENT_KEY_VERSION = 0;
+--let $tables_count= `select count(*) from information_schema.tables where engine = 'InnoDB'`
+--let $wait_condition=SELECT COUNT(*) = $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND CURRENT_KEY_VERSION = 0;
--source include/wait_condition.inc
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.test b/mysql-test/suite/encryption/t/innodb-bad-key-change.test
index 8a431cd93ca..8c67d4fa44d 100644
--- a/mysql-test/suite/encryption/t/innodb-bad-key-change.test
+++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.test
@@ -12,6 +12,7 @@ call mtr.add_suppression("Plugin 'file_key_management' init function returned er
call mtr.add_suppression("Plugin 'file_key_management' registration.*failed");
call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[12]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found");
--echo # Start server with keys2.txt
@@ -37,17 +38,16 @@ SELECT * FROM t1;
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keysbad3.txt
-- source include/restart_mysqld.inc
+--disable_warnings
--error ER_NO_SUCH_TABLE_IN_ENGINE
SELECT * FROM t1;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+--enable_warnings
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keysbad3.txt
-- source include/restart_mysqld.inc
+
--replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
DROP TABLE t1;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
#
# MDEV-8591: Database page corruption on disk or a failed space, Assertion failure in file buf0buf.cc
@@ -67,50 +67,40 @@ INSERT INTO t2 VALUES ('foobar',1,2);
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
-- source include/restart_mysqld.inc
+--disable_warnings
--error ER_NO_SUCH_TABLE_IN_ENGINE
SELECT * FROM t2;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+
--error ER_NO_SUCH_TABLE_IN_ENGINE
SELECT * FROM t2 where id = 1;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+
--error ER_NO_SUCH_TABLE_IN_ENGINE
SELECT * FROM t2 where b = 1;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+
--error ER_NO_SUCH_TABLE_IN_ENGINE
INSERT INTO t2 VALUES ('tmp',3,3);
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+
--error ER_NO_SUCH_TABLE_IN_ENGINE
DELETE FROM t2 where b = 3;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+
--error ER_NO_SUCH_TABLE_IN_ENGINE
DELETE FROM t2 where id = 3;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+
--error ER_NO_SUCH_TABLE_IN_ENGINE
UPDATE t2 set b = b +1;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+
OPTIMIZE TABLE t2;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+
--error ER_NO_SUCH_TABLE_IN_ENGINE
ALTER TABLE t2 ADD COLUMN d INT;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+
ANALYZE TABLE t2;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
+
--error ER_NO_SUCH_TABLE_IN_ENGINE
TRUNCATE TABLE t2;
---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 /
-SHOW WARNINGS;
DROP TABLE t2;
+--enable_warnings
--echo
--echo # Start server with keys2.txt
diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change2.test b/mysql-test/suite/encryption/t/innodb-bad-key-change2.test
index 8c1a8277a30..dd5faee6a98 100644
--- a/mysql-test/suite/encryption/t/innodb-bad-key-change2.test
+++ b/mysql-test/suite/encryption/t/innodb-bad-key-change2.test
@@ -10,6 +10,7 @@
#
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page|is corrupted|does not exist.*is trying to rename)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t1(new)?\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
# Suppression for builds where file_key_management plugin is linked statically
call mtr.add_suppression("Couldn't load plugins from 'file_key_management");
call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as discarded\\.");
diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change4.test b/mysql-test/suite/encryption/t/innodb-bad-key-change4.test
index 30d417cfe93..9094ef5ae60 100644
--- a/mysql-test/suite/encryption/t/innodb-bad-key-change4.test
+++ b/mysql-test/suite/encryption/t/innodb-bad-key-change4.test
@@ -9,6 +9,7 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t1\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
# Suppression for builds where file_key_management plugin is linked statically
call mtr.add_suppression("Couldn't load plugins from 'file_key_management");
diff --git a/mysql-test/suite/encryption/t/innodb-compressed-blob.test b/mysql-test/suite/encryption/t/innodb-compressed-blob.test
index 4f28f8e183d..695864db123 100644
--- a/mysql-test/suite/encryption/t/innodb-compressed-blob.test
+++ b/mysql-test/suite/encryption/t/innodb-compressed-blob.test
@@ -5,6 +5,7 @@
-- source include/not_embedded.inc
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
call mtr.add_suppression("InnoDB: Unable to decompress ..test.t[1-3]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]");
--echo # Restart mysqld --file-key-management-filename=keys2.txt
diff --git a/mysql-test/suite/encryption/t/innodb-encryption-disable.test b/mysql-test/suite/encryption/t/innodb-encryption-disable.test
index 0514ce70fb6..0994078788e 100644
--- a/mysql-test/suite/encryption/t/innodb-encryption-disable.test
+++ b/mysql-test/suite/encryption/t/innodb-encryption-disable.test
@@ -9,6 +9,7 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[15]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
# Suppression for builds where file_key_management plugin is linked statically
call mtr.add_suppression("Couldn't load plugins from 'file_key_management");
diff --git a/mysql-test/suite/encryption/t/innodb-force-corrupt.test b/mysql-test/suite/encryption/t/innodb-force-corrupt.test
index c23959801ca..2ec4960af4c 100644
--- a/mysql-test/suite/encryption/t/innodb-force-corrupt.test
+++ b/mysql-test/suite/encryption/t/innodb-force-corrupt.test
@@ -9,6 +9,7 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
SET GLOBAL innodb_file_per_table = ON;
set global innodb_compression_algorithm = 1;
diff --git a/mysql-test/suite/encryption/t/innodb-missing-key.test b/mysql-test/suite/encryption/t/innodb-missing-key.test
index 2a56581601a..17059cc093d 100644
--- a/mysql-test/suite/encryption/t/innodb-missing-key.test
+++ b/mysql-test/suite/encryption/t/innodb-missing-key.test
@@ -9,6 +9,7 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
--echo # Start server with keys2.txt
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
diff --git a/mysql-test/suite/encryption/t/innodb-redo-badkey.test b/mysql-test/suite/encryption/t/innodb-redo-badkey.test
index bc75ca190e7..513e8724586 100644
--- a/mysql-test/suite/encryption/t/innodb-redo-badkey.test
+++ b/mysql-test/suite/encryption/t/innodb-redo-badkey.test
@@ -6,6 +6,7 @@
call mtr.add_suppression("Plugin 'file_key_management'");
call mtr.add_suppression("Plugin 'InnoDB' init function returned error.");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[0-9]+\\] in file .*test/t[1-4]\\.ibd cannot be decrypted");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
call mtr.add_suppression("InnoDB: Unable to decompress .*.test.t1\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]");
call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed file read of tablespace test/t1 page \\[page id: space=[1-9][0-9]*, page number=[0-9]*\\]");
call mtr.add_suppression("InnoDB: Plugin initialization aborted");
diff --git a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test
index 5c344f5beb1..37565ab4827 100644
--- a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test
+++ b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test
@@ -3,13 +3,13 @@
# embedded does not support restart
-- source include/not_embedded.inc
-call mtr.add_suppression("InnoDB: Block in space_id .*");
call mtr.add_suppression("mysqld: File .*");
call mtr.add_suppression("Plugin 'file_key_management' .*");
call mtr.add_suppression("InnoDB: cannot enable encryption, encryption plugin is not available");
call mtr.add_suppression("Plugin 'InnoDB' init function returned error.");
call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed.");
-call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[0-9]+\\] in file test/t[1-4] cannot be decrypted");
+call mtr.add_suppression("InnoDB: The page \\[page id: space=[0-9]+, page number=[0-9]+\\] in file '.*test.t[1-4]\\.ibd' cannot be decrypted\\.");
+call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
--echo # Restart mysqld --file-key-management-filename=keys2.txt
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
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 999ff4ff45a..df52d3f66eb 100644
--- a/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test
+++ b/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test
@@ -1,9 +1,6 @@
-- source include/have_innodb.inc
-- source include/have_example_key_management_plugin.inc
-
-let $innodb_compression_algorithm_orig=`SELECT @@innodb_compression_algorithm`;
-let $innodb_encrypt_tables_orig = `SELECT @@innodb_encrypt_tables`;
-let $innodb_encryption_threads_orig = `SELECT @@innodb_encryption_threads`;
+-- source include/not_embedded.inc
SET GLOBAL innodb_file_per_table = ON;
SET GLOBAL innodb_encryption_threads = 4;
@@ -77,13 +74,24 @@ select count(*) from innodb_page_compressed7 where c1 < 500000;
select count(*) from innodb_page_compressed8 where c1 < 500000;
select count(*) from innodb_page_compressed9 where c1 < 500000;
+flush tables innodb_page_compressed1, innodb_page_compressed2,
+innodb_page_compressed3, innodb_page_compressed4,
+innodb_page_compressed5, innodb_page_compressed6,
+innodb_page_compressed7, innodb_page_compressed8,
+innodb_page_compressed9 for export;
+
+unlock tables;
+
+--echo # Wait until dirty pages are compressed and encrypted
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
+let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED';
+--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';
SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed';
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed';
+
+--source include/restart_mysqld.inc
SET GLOBAL innodb_encryption_threads = 4;
SET GLOBAL innodb_encrypt_tables = off;
@@ -98,13 +106,23 @@ update innodb_page_compressed7 set c1 = c1 + 1;
update innodb_page_compressed8 set c1 = c1 + 1;
update innodb_page_compressed9 set c1 = c1 + 1;
+flush tables innodb_page_compressed1, innodb_page_compressed2,
+innodb_page_compressed3, innodb_page_compressed4,
+innodb_page_compressed5, innodb_page_compressed6,
+innodb_page_compressed7, innodb_page_compressed8,
+innodb_page_compressed9 for export;
+unlock tables;
+
+--echo # Wait until dirty pages are compressed and encrypted 2
+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
+unlock tables;
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';
SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed';
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed';
+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;
@@ -117,10 +135,3 @@ drop table innodb_page_compressed6;
drop table innodb_page_compressed7;
drop table innodb_page_compressed8;
drop table innodb_page_compressed9;
-
-# reset system
---disable_query_log
-EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algorithm_orig;
-EVAL SET GLOBAL innodb_encrypt_tables = $innodb_encrypt_tables_orig;
-EVAL SET GLOBAL innodb_encryption_threads = $innodb_encryption_threads_orig;
---enable_query_log
diff --git a/mysql-test/suite/encryption/t/innodb_encryption.test b/mysql-test/suite/encryption/t/innodb_encryption.test
index 35c2b3695a9..d183a2914bd 100644
--- a/mysql-test/suite/encryption/t/innodb_encryption.test
+++ b/mysql-test/suite/encryption/t/innodb_encryption.test
@@ -14,9 +14,11 @@ SHOW VARIABLES LIKE 'innodb_encrypt%';
SET GLOBAL innodb_encrypt_tables = ON;
+--let $tables_count= `select count(*) + 1 from information_schema.tables where engine = 'InnoDB'`
+
--echo # Wait max 10 min for key encryption threads to encrypt all spaces
--let $wait_timeout= 600
---let $wait_condition=SELECT COUNT(*) >= 3 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
--source include/wait_condition.inc
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
@@ -59,7 +61,7 @@ SET GLOBAL innodb_encryption_threads=@start_global_value;
--echo # Wait max 10 min for key encryption threads to encrypt all spaces
--let $wait_timeout= 600
---let $wait_condition=SELECT COUNT(*) >=3 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
--source include/wait_condition.inc
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
diff --git a/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test b/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test
index 47d546ae698..a087635fc99 100644
--- a/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test
+++ b/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test
@@ -1,12 +1,11 @@
-- source include/have_innodb.inc
-- source include/have_file_key_management_plugin.inc
-# embedded does not support restart
--- source include/not_embedded.inc
-
-call mtr.add_suppression("trying to do an operation on a dropped tablespace .*");
+--disable_query_log
let $encrypt_tables = `SELECT @@innodb_encrypt_tables`;
let $threads = `SELECT @@innodb_encryption_threads`;
+let $key_id = `SELECT @@innodb_default_encryption_key_id`;
+--enable_query_log
SET GLOBAL innodb_encrypt_tables = OFF;
SET GLOBAL innodb_encryption_threads = 4;
@@ -19,21 +18,20 @@ CREATE TABLE t4 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNOD
--disable_warnings
--disable_query_log
-set autocommit=0;
-let $i = 400;
+begin;
+let $i = 10;
while ($i)
{
INSERT INTO t1 values(NULL, substring(MD5(RAND()), -128));
dec $i;
}
-commit;
-set autocommit=1;
---enable_warnings
---enable_query_log
INSERT INTO t2 select * from t1;
INSERT INTO t3 select * from t1;
INSERT INTO t4 select * from t1;
+commit;
+--enable_warnings
+--enable_query_log
SET GLOBAL innodb_encrypt_tables = on;
@@ -54,7 +52,7 @@ while ($cnt)
}
if (!$success)
{
- SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
+ SELECT NAME,ENCRYPTION_SHCEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
SHOW STATUS LIKE 'innodb_encryption%';
-- die Timeout waiting for encryption threads
}
@@ -84,7 +82,7 @@ while ($cnt)
}
if (!$success)
{
- SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
+ SELECT NAME,ENCRYPTION_SHCEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
SHOW STATUS LIKE 'innodb_encryption%';
-- die Timeout waiting for encryption threads
}
@@ -113,7 +111,7 @@ while ($cnt)
}
if (!$success)
{
- SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
+ SELECT NAME,ENCRYPTION_SHCEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
SHOW STATUS LIKE 'innodb_encryption%';
-- die Timeout waiting for encryption threads
}
@@ -125,12 +123,11 @@ SELECT COUNT(1) FROM t3;
SELECT COUNT(1) FROM t4;
SELECT COUNT(1) FROM t5;
+drop table t1,t2,t3,t4, t5;
+
# reset system
--disable_query_log
EVAL SET GLOBAL innodb_encrypt_tables = $encrypt_tables;
EVAL SET GLOBAL innodb_encryption_threads = $threads;
+EVAL set GLOBAL innodb_default_encryption_key_id = $key_id;
--enable_query_log
-
-drop table t1,t2,t3,t4, t5;
-
-set GLOBAL innodb_default_encryption_key_id=1;
diff --git a/mysql-test/suite/encryption/t/tempfiles.combinations b/mysql-test/suite/encryption/t/tempfiles.combinations
new file mode 100644
index 00000000000..7010d2c100d
--- /dev/null
+++ b/mysql-test/suite/encryption/t/tempfiles.combinations
@@ -0,0 +1,5 @@
+[none]
+binlog-checksum=NONE
+
+[crc32]
+binlog-checksum=CRC32
diff --git a/mysql-test/suite/encryption/t/tempfiles.opt b/mysql-test/suite/encryption/t/tempfiles.opt
new file mode 100644
index 00000000000..2b90f474428
--- /dev/null
+++ b/mysql-test/suite/encryption/t/tempfiles.opt
@@ -0,0 +1 @@
+--encrypt-tmp-files
diff --git a/mysql-test/suite/encryption/t/tempfiles.test b/mysql-test/suite/encryption/t/tempfiles.test
index 065d775c182..e2fd356bb82 100644
--- a/mysql-test/suite/encryption/t/tempfiles.test
+++ b/mysql-test/suite/encryption/t/tempfiles.test
@@ -9,6 +9,8 @@ source include/have_binlog_format_row.inc;
source include/have_innodb.inc;
+select @@encrypt_tmp_files;
+
#
# MyISAM messing around with IO_CACHE::file
#
@@ -29,6 +31,7 @@ update t1 set c=v, t=v;
select sql_big_result t,count(t) from t1 group by t limit 10;
drop table t1;
+reset master;
set global binlog_cache_size=8192;
connect con1, localhost, root;
@@ -46,7 +49,6 @@ commit;
start transaction;
insert t1 select repeat(seq, 1000) from seq_1_to_8;
commit;
-drop table t1;
disconnect con1;
connect con2, localhost, root;
@@ -56,17 +58,27 @@ connect con2, localhost, root;
# Start a transaction, write until the cache goes to disk,
# create a savepoint, write more blocks to disk, rollback to savepoint.
#
-create table t1 (a text) engine=innodb;
+create table t2 (a text) engine=innodb;
start transaction;
-insert t1 select repeat(seq, 1000) from seq_1_to_15;
+insert t2 select repeat(seq, 1000) from seq_1_to_15;
savepoint foo;
-insert t1 select repeat(seq, 1000) from seq_16_to_30;
+insert t2 select repeat(seq, 1000) from seq_16_to_30;
rollback to savepoint foo;
-insert t1 select repeat(seq, 1000) from seq_31_to_40;
+insert t2 select repeat(seq, 1000) from seq_31_to_40;
commit;
-drop table t1;
disconnect con2;
connection default;
+flush binary logs;
+
+drop table t1, t2;
+
set global binlog_cache_size=default;
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 | $MYSQL;
+
+select left(a, 10) from t1;
+select left(a, 10) from t2;
+drop table t1, t2;
diff --git a/mysql-test/suite/federated/assisted_discovery.result b/mysql-test/suite/federated/assisted_discovery.result
index 4818ff7bb02..d44f69effcd 100644
--- a/mysql-test/suite/federated/assisted_discovery.result
+++ b/mysql-test/suite/federated/assisted_discovery.result
@@ -72,6 +72,14 @@ t1 CREATE TABLE `t1` (
drop table t1;
connection slave;
drop table t1;
+create or replace table t1 (x int) with system versioning;
+connection master;
+create table t1 engine=federated connection='mysql://root@127.0.0.1:SLAVE_MYPORT/test/t1';
+ERROR HY000: Engine FEDERATED failed to discover table `test`.`t1` with 'CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) WITH SYSTEM VERSIONING CONNECTION='mysql://root@127.0.0.1:SLAVE_MYPORT/test/t1''
+connection slave;
+drop table t1;
connection master;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
diff --git a/mysql-test/suite/federated/assisted_discovery.test b/mysql-test/suite/federated/assisted_discovery.test
index fa83a2a8e19..7099cfedb23 100644
--- a/mysql-test/suite/federated/assisted_discovery.test
+++ b/mysql-test/suite/federated/assisted_discovery.test
@@ -54,5 +54,14 @@ drop table t1;
connection slave;
drop table t1;
+create or replace table t1 (x int) with system versioning;
+connection master;
+--replace_result $SLAVE_MYPORT SLAVE_MYPORT
+--error ER_SQL_DISCOVER_ERROR
+eval create table t1 engine=federated connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
+
+connection slave;
+drop table t1;
+
source include/federated_cleanup.inc;
diff --git a/mysql-test/suite/federated/federated_bug_585688.result b/mysql-test/suite/federated/federated_bug_585688.result
index 84c08944ce0..b317a1eb2a1 100644
--- a/mysql-test/suite/federated/federated_bug_585688.result
+++ b/mysql-test/suite/federated/federated_bug_585688.result
@@ -27,14 +27,14 @@ Field Type Null Key Default Extra
a text YES NULL
connection conn_3;
show table status from federated;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 FEDERATED 10 Dynamic 5 20 X X X X X X X X latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 FEDERATED 10 Dynamic 5 20 X X X X X X X X latin1_swedish_ci NULL 0 N
disconnect conn_2;
connect conn_4,127.0.0.1,root,,,$MASTER_MYPORT;
connection conn_4;
show table status from federated;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 FEDERATED 10 Dynamic 5 20 X X X X X X X X latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 FEDERATED 10 Dynamic 5 20 X X X X X X X X latin1_swedish_ci NULL 0 N
disconnect conn_3;
disconnect conn_4;
connection master;
diff --git a/mysql-test/suite/federated/federated_partition.result b/mysql-test/suite/federated/federated_partition.result
index a2d5fcffd9b..c8a61d825b6 100644
--- a/mysql-test/suite/federated/federated_partition.result
+++ b/mysql-test/suite/federated/federated_partition.result
@@ -10,7 +10,8 @@ create table federated.t1_1 (s1 int primary key) engine=myisam;
create table federated.t1_2 (s1 int primary key) engine=innodb;
connection master;
create table t1 (s1 int primary key) engine=federated
-partition by list (s1)
+CONNECTION="remember_this"
+ partition by list (s1)
(partition p1 values in (1,3)
connection='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1_1',
partition p2 values in (2,4)
@@ -20,7 +21,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`s1` int(11) NOT NULL,
PRIMARY KEY (`s1`)
-) ENGINE=FEDERATED DEFAULT CHARSET=latin1
+) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='remember_this'
PARTITION BY LIST (`s1`)
(PARTITION `p1` VALUES IN (1,3) CONNECTION = 'mysql://root@127.0.0.1:SLAVE_PORT/federated/t1_1' ENGINE = FEDERATED,
PARTITION `p2` VALUES IN (2,4) CONNECTION = 'mysql://root@127.0.0.1:SLAVE_PORT/federated/t1_2' ENGINE = FEDERATED)
diff --git a/mysql-test/suite/federated/federated_partition.test b/mysql-test/suite/federated/federated_partition.test
index ef1e27ec505..47110b5eebf 100644
--- a/mysql-test/suite/federated/federated_partition.test
+++ b/mysql-test/suite/federated/federated_partition.test
@@ -25,6 +25,7 @@ create table federated.t1_2 (s1 int primary key) engine=innodb;
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval create table t1 (s1 int primary key) engine=federated
+ CONNECTION="remember_this"
partition by list (s1)
(partition p1 values in (1,3)
connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1_1',
diff --git a/mysql-test/suite/funcs_1/datadict/tables2.inc b/mysql-test/suite/funcs_1/datadict/tables2.inc
index 1dc00e5b0f7..2d19eb8b3dd 100644
--- a/mysql-test/suite/funcs_1/datadict/tables2.inc
+++ b/mysql-test/suite/funcs_1/datadict/tables2.inc
@@ -30,7 +30,7 @@ let $innodb_pattern = 'InnoDB free';
# We do not unify the engine name here, because the rowformat is
# specific to the engine.
--replace_result Dynamic DYNAMIC_OR_PAGE Page DYNAMIC_OR_PAGE MyISAM MYISAM_OR_MARIA Aria MYISAM_OR_MARIA
---replace_column 8 "#TBLR#" 9 "#ARL#" 10 "#DL#" 11 "#MDL#" 12 "#IL#" 13 "#DF#" 15 "#CRT#" 16 "#UT#" 17 "#CT#" 20 "#CO#" 21 "#TC#"
+--replace_column 8 "#TBLR#" 9 "#ARL#" 10 "#DL#" 11 "#MDL#" 12 "#IL#" 13 "#DF#" 15 "#CRT#" 16 "#UT#" 17 "#CT#" 20 "#CO#" 21 "#TC#" 22 "#MIL#"
eval
SELECT *,
LEFT( table_comment,
diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03.result b/mysql-test/suite/funcs_1/r/innodb_trig_03.result
index 98f599da3e5..7666b86bc94 100644
--- a/mysql-test/suite/funcs_1/r/innodb_trig_03.result
+++ b/mysql-test/suite/funcs_1/r/innodb_trig_03.result
@@ -78,7 +78,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke TRIGGER on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -168,7 +168,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke UPDATE on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -183,7 +183,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
select f1 from t1 order by f1;
f1
insert 3.5.3.2-no
@@ -248,7 +248,7 @@ connection no_privs_424b;
show grants;
Grants for test_noprivs@localhost
GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4b_1 before UPDATE on t1 for each row
set new.f1 = 'trig 3.5.3.7-1b';
@@ -329,7 +329,7 @@ connection no_privs_424c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4c_1 before INSERT on t1 for each row
set new.f1 = 'trig 3.5.3.7-1c';
@@ -441,7 +441,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke SELECT on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, SELECT on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -457,7 +457,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
create trigger trg5a_1 before INSERT on t1 for each row
set @test_var = new.f1;
connection default;
@@ -503,7 +503,7 @@ revoke SELECT on priv_db.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.* to test_yesprivs@localhost;
@@ -518,7 +518,7 @@ connection no_privs_425b;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5b_1 before UPDATE on t1 for each row
set @test_var= new.f1;
@@ -565,7 +565,7 @@ revoke SELECT on priv_db.t1 from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -580,7 +580,7 @@ connection no_privs_425c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5c_1 before INSERT on t1 for each row
set @test_var= new.f1;
diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result
index b29c0271fdc..90dabe044e8 100644
--- a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result
+++ b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result
@@ -603,7 +603,7 @@ trig 1_1-yes
revoke TRIGGER on *.* from test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
disconnect yes_privs;
connect yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK;
select current_user;
@@ -656,7 +656,7 @@ root@localhost
grant TRIGGER on priv_db.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
GRANT TRIGGER ON `priv_db`.* TO 'test_yesprivs'@'localhost'
trigger privilege on db level for create:
@@ -929,7 +929,7 @@ grant TRIGGER on priv1_db.t1 to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
GRANT USAGE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, DELETE VERSIONING ROWS ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
GRANT SELECT, UPDATE ON `priv2_db`.* TO 'test_yesprivs'@'localhost'
GRANT TRIGGER ON `priv1_db`.`t1` TO 'test_yesprivs'@'localhost'
diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result
index 5a27cb65b3d..b00d1a56c90 100644
--- a/mysql-test/suite/funcs_1/r/innodb_views.result
+++ b/mysql-test/suite/funcs_1/r/innodb_views.result
@@ -3551,11 +3551,11 @@ CREATE VIEW v1 or REPLACE AS Select * from tb2 my_table;
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 'or REPLACE AS Select * from tb2 my_table' at line 1
CREATE VIEW v1 WITH CASCADED CHECK OPTION AS Select *
from tb2 my_table limit 50;
-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 'CASCADED CHECK OPTION AS Select *
+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 'WITH CASCADED CHECK OPTION AS Select *
from tb2 my_table limit 50' at line 1
CREATE VIEW v1 WITH LOCAL CHECK OPTION AS Select *
from tb2 my_table limit 50;
-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 'LOCAL CHECK OPTION AS Select *
+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 'WITH LOCAL CHECK OPTION AS Select *
from tb2 my_table limit 50' at line 1
SELECT * FROM tb2 my_table CREATE VIEW As v1;
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 'CREATE VIEW As v1' at line 1
@@ -3585,7 +3585,7 @@ FROM test.tb2 my_table CHECK OPTION WITH CASCADED;
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 'CHECK OPTION WITH CASCADED' at line 2
CREATE OR REPLACE VIEW v1 WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table;
-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 'CASCADED CHECK OPTION
+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 'WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table' at line 1
CREATE OR REPLACE AS SELECT F59, F60
FROM test.tb2 my_table VIEW v1 WITH CASCADED CHECK OPTION;
@@ -3614,7 +3614,7 @@ FROM test.tb2 my_table CHECK OPTION WITH LOCAL;
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 'CHECK OPTION WITH LOCAL' at line 2
CREATE OR REPLACE VIEW v1 WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table;
-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 'CASCADED CHECK OPTION
+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 'WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table' at line 1
CREATE OR REPLACE AS SELECT F59, F60
FROM test.tb2 my_table VIEW v1 WITH LOCAL CHECK OPTION;
@@ -4314,7 +4314,7 @@ CREATE VIEW v2 AS Select * from test.v1;
ERROR 42S02: Table 'test.v1' doesn't exist
DROP VIEW IF EXISTS v2;
Warnings:
-Note 4090 Unknown VIEW: 'test.v2'
+Note 4092 Unknown VIEW: 'test.v2'
Testcase 3.3.1.25
--------------------------------------------------------------------------------
@@ -7566,7 +7566,7 @@ Call sp1() ;
ERROR 42000: PROCEDURE test.sp1 does not exist
Drop view if exists test.v1 ;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
Drop procedure sp1 ;
ERROR 42000: PROCEDURE test.sp1 does not exist
@@ -21312,7 +21312,7 @@ CREATE VIEW v1 AS SELECT f1 FROM t1;
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v1;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
Testcase 3.3.1.68
--------------------------------------------------------------------------------
@@ -21365,7 +21365,7 @@ ERROR 42S02: Table 'test.v1' doesn't exist
SHOW CREATE TABLE v1 ;
ERROR 42S02: Table 'test.v1' doesn't exist
SHOW TABLE STATUS like 'v1' ;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
SHOW TABLES LIKE 'v1';
Tables_in_test (v1)
SHOW COLUMNS FROM v1;
diff --git a/mysql-test/suite/funcs_1/r/is_column_privileges.result b/mysql-test/suite/funcs_1/r/is_column_privileges.result
index a56ef002935..033fb64f689 100644
--- a/mysql-test/suite/funcs_1/r/is_column_privileges.result
+++ b/mysql-test/suite/funcs_1/r/is_column_privileges.result
@@ -140,6 +140,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
'testuser3'@'localhost' def db_datadict CREATE TEMPORARY TABLES NO
'testuser3'@'localhost' def db_datadict CREATE VIEW NO
'testuser3'@'localhost' def db_datadict DELETE NO
+'testuser3'@'localhost' def db_datadict DELETE VERSIONING ROWS NO
'testuser3'@'localhost' def db_datadict DROP NO
'testuser3'@'localhost' def db_datadict EVENT NO
'testuser3'@'localhost' def db_datadict EXECUTE NO
diff --git a/mysql-test/suite/funcs_1/r/is_columns.result b/mysql-test/suite/funcs_1/r/is_columns.result
index 982f4de5116..f1c784e2839 100644
--- a/mysql-test/suite/funcs_1/r/is_columns.result
+++ b/mysql-test/suite/funcs_1/r/is_columns.result
@@ -106,6 +106,7 @@ table_catalog table_schema table_name column_name
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
###############################################################################
# Testcase 3.2.6.2 + 3.2.6.3: INFORMATION_SCHEMA.COLUMNS accessible information
###############################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result
index ba055f2dc58..bf6511e80bf 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result
@@ -373,6 +373,7 @@ def information_schema TABLES DATA_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL
def information_schema TABLES ENGINE 5 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
def information_schema TABLES INDEX_LENGTH 12 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select NEVER NULL
def information_schema TABLES MAX_DATA_LENGTH 11 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select NEVER NULL
+def information_schema TABLES MAX_INDEX_LENGTH 22 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select NEVER NULL
def information_schema TABLES ROW_FORMAT 7 NULL YES varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10) select NEVER NULL
def information_schema TABLES TABLE_CATALOG 1 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select NEVER NULL
def information_schema TABLES TABLE_COLLATION 18 NULL YES varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select NEVER NULL
@@ -381,6 +382,7 @@ def information_schema TABLES TABLE_NAME 3 '' NO varchar 64 192 NULL NULL NULL u
def information_schema TABLES TABLE_ROWS 8 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select NEVER NULL
def information_schema TABLES TABLE_SCHEMA 2 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
def information_schema TABLES TABLE_TYPE 4 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
+def information_schema TABLES TEMPORARY 23 NULL YES varchar 1 3 NULL NULL NULL utf8 utf8_general_ci varchar(1) select NEVER NULL
def information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select NEVER NULL
def information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select NEVER NULL
def information_schema TABLESPACES AUTOEXTEND_SIZE 6 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select NEVER NULL
@@ -914,6 +916,8 @@ NULL information_schema TABLES CHECK_TIME datetime NULL NULL NULL NULL datetime
NULL information_schema TABLES CHECKSUM bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema TABLES CREATE_OPTIONS varchar 2048 6144 utf8 utf8_general_ci varchar(2048)
3.0000 information_schema TABLES TABLE_COMMENT varchar 2048 6144 utf8 utf8_general_ci varchar(2048)
+NULL information_schema TABLES MAX_INDEX_LENGTH bigint NULL NULL NULL NULL bigint(21) unsigned
+3.0000 information_schema TABLES TEMPORARY varchar 1 3 utf8 utf8_general_ci varchar(1)
3.0000 information_schema TABLESPACES TABLESPACE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema TABLESPACES ENGINE varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema TABLESPACES TABLESPACE_TYPE varchar 64 192 utf8 utf8_general_ci varchar(64)
diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
index 3bb5e5e6364..edf11d25f7e 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
@@ -373,6 +373,7 @@ def information_schema TABLES DATA_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL
def information_schema TABLES ENGINE 5 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) NEVER NULL
def information_schema TABLES INDEX_LENGTH 12 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned NEVER NULL
def information_schema TABLES MAX_DATA_LENGTH 11 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned NEVER NULL
+def information_schema TABLES MAX_INDEX_LENGTH 22 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned NEVER NULL
def information_schema TABLES ROW_FORMAT 7 NULL YES varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10) NEVER NULL
def information_schema TABLES TABLE_CATALOG 1 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) NEVER NULL
def information_schema TABLES TABLE_COLLATION 18 NULL YES varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) NEVER NULL
@@ -381,6 +382,7 @@ def information_schema TABLES TABLE_NAME 3 '' NO varchar 64 192 NULL NULL NULL u
def information_schema TABLES TABLE_ROWS 8 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned NEVER NULL
def information_schema TABLES TABLE_SCHEMA 2 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) NEVER NULL
def information_schema TABLES TABLE_TYPE 4 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) NEVER NULL
+def information_schema TABLES TEMPORARY 23 NULL YES varchar 1 3 NULL NULL NULL utf8 utf8_general_ci varchar(1) NEVER NULL
def information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime NEVER NULL
def information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned NEVER NULL
def information_schema TABLESPACES AUTOEXTEND_SIZE 6 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned NEVER NULL
@@ -914,6 +916,8 @@ NULL information_schema TABLES CHECK_TIME datetime NULL NULL NULL NULL datetime
NULL information_schema TABLES CHECKSUM bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema TABLES CREATE_OPTIONS varchar 2048 6144 utf8 utf8_general_ci varchar(2048)
3.0000 information_schema TABLES TABLE_COMMENT varchar 2048 6144 utf8 utf8_general_ci varchar(2048)
+NULL information_schema TABLES MAX_INDEX_LENGTH bigint NULL NULL NULL NULL bigint(21) unsigned
+3.0000 information_schema TABLES TEMPORARY varchar 1 3 utf8 utf8_general_ci varchar(1)
3.0000 information_schema TABLESPACES TABLESPACE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema TABLESPACES ENGINE varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema TABLESPACES TABLESPACE_TYPE varchar 64 192 utf8 utf8_general_ci varchar(64)
diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
index 21ffae902a4..74dff5a46ad 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
@@ -27,6 +27,7 @@ def mysql db Create_routine_priv 18 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_gen
def mysql db Create_tmp_table_priv 14 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql db Create_view_priv 16 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql db Db 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references NEVER NULL
+def mysql db Delete_history_priv 23 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql db Delete_priv 7 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql db Drop_priv 9 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql db Event_priv 21 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
@@ -60,7 +61,7 @@ def mysql event modified 9 '0000-00-00 00:00:00' NO timestamp NULL NULL NULL NUL
def mysql event name 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references NEVER NULL
def mysql event on_completion 14 'DROP' NO enum 8 24 NULL NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') select,insert,update,references NEVER NULL
def mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references NEVER NULL
-def mysql event sql_mode 15 '' NO set 515 1545 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') select,insert,update,references NEVER NULL
+def mysql event sql_mode 15 '' NO set 539 1617 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') select,insert,update,references NEVER NULL
def mysql event starts 11 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references NEVER NULL
def mysql event status 13 'ENABLED' NO enum 18 54 NULL NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') select,insert,update,references NEVER NULL
def mysql event time_zone 18 'SYSTEM' NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references NEVER NULL
@@ -133,6 +134,7 @@ def mysql innodb_table_stats sum_of_other_index_sizes 6 NULL NO bigint NULL NULL
def mysql innodb_table_stats table_name 2 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_bin varchar(64) PRI select,insert,update,references NEVER NULL
def mysql plugin dl 2 '' NO varchar 128 384 NULL NULL NULL utf8 utf8_general_ci varchar(128) select,insert,update,references NEVER NULL
def mysql plugin name 1 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) PRI select,insert,update,references NEVER NULL
+def mysql proc aggregate 21 'NONE' NO enum 5 15 NULL NULL NULL utf8 utf8_general_ci enum('NONE','GROUP') select,insert,update,references NEVER NULL
def mysql proc body 11 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references NEVER NULL
def mysql proc body_utf8 20 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references NEVER NULL
def mysql proc character_set_client 17 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32) select,insert,update,references NEVER NULL
@@ -151,7 +153,7 @@ def mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL
def mysql proc security_type 8 'DEFINER' NO enum 7 21 NULL NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') select,insert,update,references NEVER NULL
def mysql proc specific_name 4 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NEVER NULL
def mysql proc sql_data_access 6 'CONTAINS_SQL' NO enum 17 51 NULL NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') select,insert,update,references NEVER NULL
-def mysql proc sql_mode 15 '' NO set 515 1545 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') select,insert,update,references NEVER NULL
+def mysql proc sql_mode 15 '' NO set 539 1617 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') select,insert,update,references NEVER NULL
def mysql proc type 3 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI select,insert,update,references NEVER NULL
def mysql procs_priv Db 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references NEVER NULL
def mysql procs_priv Grantor 6 '' NO char 141 423 NULL NULL NULL utf8 utf8_bin char(141) MUL select,insert,update,references NEVER NULL
@@ -199,7 +201,7 @@ def mysql tables_priv Db 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_bin char(6
def mysql tables_priv Grantor 5 '' NO char 141 423 NULL NULL NULL utf8 utf8_bin char(141) MUL select,insert,update,references NEVER NULL
def mysql tables_priv Host 1 '' NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references NEVER NULL
def mysql tables_priv Table_name 4 '' NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references NEVER NULL
-def mysql tables_priv Table_priv 7 '' NO set 98 294 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') select,insert,update,references NEVER NULL
+def mysql tables_priv Table_priv 7 '' NO set 121 363 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows') select,insert,update,references NEVER NULL
def mysql tables_priv Timestamp 6 current_timestamp() NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update current_timestamp() select,insert,update,references NEVER NULL
def mysql tables_priv User 3 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) PRI select,insert,update,references NEVER NULL
def mysql table_stats cardinality 3 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select,insert,update,references NEVER NULL
@@ -219,16 +221,22 @@ def mysql time_zone_transition_type Is_DST 4 0 NO tinyint NULL NULL 3 0 NULL NUL
def mysql time_zone_transition_type Offset 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references NEVER NULL
def mysql time_zone_transition_type Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI select,insert,update,references NEVER NULL
def mysql time_zone_transition_type Transition_type_id 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI select,insert,update,references NEVER NULL
+def mysql transaction_registry begin_timestamp 3 '0000-00-00 00:00:00.000000' NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) MUL select,insert,update,references NEVER NULL
+def mysql transaction_registry commit_id 2 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned UNI select,insert,update,references NEVER NULL
+def mysql transaction_registry commit_timestamp 4 '0000-00-00 00:00:00.000000' NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) MUL select,insert,update,references NEVER NULL
+def mysql transaction_registry isolation_level 5 NULL NO enum 16 48 NULL NULL NULL utf8 utf8_bin enum('READ-UNCOMMITTED','READ-COMMITTED','REPEATABLE-READ','SERIALIZABLE') select,insert,update,references NEVER NULL
+def mysql transaction_registry transaction_id 1 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned PRI select,insert,update,references NEVER NULL
def mysql user Alter_priv 17 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Alter_routine_priv 28 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
-def mysql user authentication_string 42 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_bin text select,insert,update,references NEVER NULL
+def mysql user authentication_string 43 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_bin text select,insert,update,references NEVER NULL
def mysql user Create_priv 8 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Create_routine_priv 27 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Create_tablespace_priv 32 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Create_tmp_table_priv 20 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Create_user_priv 29 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Create_view_priv 25 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
-def mysql user default_role 45 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) select,insert,update,references NEVER NULL
+def mysql user default_role 46 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) select,insert,update,references NEVER NULL
+def mysql user Delete_history_priv 33 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Delete_priv 7 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Drop_priv 9 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Event_priv 30 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
@@ -238,16 +246,16 @@ def mysql user Grant_priv 14 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci
def mysql user Host 1 '' NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references NEVER NULL
def mysql user Index_priv 16 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Insert_priv 5 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
-def mysql user is_role 44 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
+def mysql user is_role 45 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Lock_tables_priv 21 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
-def mysql user max_connections 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references NEVER NULL
-def mysql user max_questions 37 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references NEVER NULL
-def mysql user max_statement_time 46 0.000000 NO decimal NULL NULL 12 6 NULL NULL NULL decimal(12,6) select,insert,update,references NEVER NULL
-def mysql user max_updates 38 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references NEVER NULL
-def mysql user max_user_connections 40 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references NEVER NULL
+def mysql user max_connections 40 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references NEVER NULL
+def mysql user max_questions 38 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references NEVER NULL
+def mysql user max_statement_time 47 0.000000 NO decimal NULL NULL 12 6 NULL NULL NULL decimal(12,6) select,insert,update,references NEVER NULL
+def mysql user max_updates 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references NEVER NULL
+def mysql user max_user_connections 41 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references NEVER NULL
def mysql user Password 3 '' NO char 41 41 NULL NULL NULL latin1 latin1_bin char(41) select,insert,update,references NEVER NULL
-def mysql user password_expired 43 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
-def mysql user plugin 41 '' NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references NEVER NULL
+def mysql user password_expired 44 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
+def mysql user plugin 42 '' NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references NEVER NULL
def mysql user Process_priv 12 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user References_priv 15 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Reload_priv 10 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
@@ -257,14 +265,14 @@ def mysql user Select_priv 4 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci
def mysql user Show_db_priv 18 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Show_view_priv 26 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Shutdown_priv 11 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
-def mysql user ssl_cipher 34 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references NEVER NULL
-def mysql user ssl_type 33 '' NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED') select,insert,update,references NEVER NULL
+def mysql user ssl_cipher 35 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references NEVER NULL
+def mysql user ssl_type 34 '' NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED') select,insert,update,references NEVER NULL
def mysql user Super_priv 19 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Trigger_priv 31 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user Update_priv 6 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NEVER NULL
def mysql user User 2 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) PRI select,insert,update,references NEVER NULL
-def mysql user x509_issuer 35 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references NEVER NULL
-def mysql user x509_subject 36 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references NEVER NULL
+def mysql user x509_issuer 36 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references NEVER NULL
+def mysql user x509_subject 37 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references NEVER NULL
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
@@ -377,6 +385,7 @@ NULL mysql column_stats hist_size tinyint NULL NULL NULL NULL tinyint(3) unsigne
3.0000 mysql db Execute_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql db Event_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql db Trigger_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
+3.0000 mysql db Delete_history_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql event db char 64 192 utf8 utf8_bin char(64)
3.0000 mysql event name char 64 192 utf8 utf8_general_ci char(64)
1.0000 mysql event body longblob 4294967295 4294967295 NULL NULL longblob
@@ -391,7 +400,7 @@ NULL mysql event starts datetime NULL NULL NULL NULL datetime
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
-3.0000 mysql event sql_mode set 515 1545 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL')
+3.0000 mysql event sql_mode set 539 1617 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@@ -482,12 +491,13 @@ NULL mysql innodb_table_stats sum_of_other_index_sizes bigint NULL NULL NULL NUL
3.0000 mysql proc definer char 141 423 utf8 utf8_bin char(141)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql proc sql_mode set 515 1545 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL')
+3.0000 mysql proc sql_mode set 539 1617 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')
1.0000 mysql proc comment text 65535 65535 utf8 utf8_bin text
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc db_collation char 32 96 utf8 utf8_bin char(32)
1.0000 mysql proc body_utf8 longblob 4294967295 4294967295 NULL NULL longblob
+3.0000 mysql proc aggregate enum 5 15 utf8 utf8_general_ci enum('NONE','GROUP')
3.0000 mysql procs_priv Host char 60 180 utf8 utf8_bin char(60)
3.0000 mysql procs_priv Db char 64 192 utf8 utf8_bin char(64)
3.0000 mysql procs_priv User char 80 240 utf8 utf8_bin char(80)
@@ -535,7 +545,7 @@ NULL mysql slow_log rows_affected int NULL NULL NULL NULL int(11)
3.0000 mysql tables_priv Table_name char 64 192 utf8 utf8_bin char(64)
3.0000 mysql tables_priv Grantor char 141 423 utf8 utf8_bin char(141)
NULL mysql tables_priv Timestamp timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql tables_priv Table_priv set 98 294 utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger')
+3.0000 mysql tables_priv Table_priv set 121 363 utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows')
3.0000 mysql tables_priv Column_priv set 31 93 utf8 utf8_general_ci set('Select','Insert','Update','References')
3.0000 mysql table_stats db_name varchar 64 192 utf8 utf8_bin varchar(64)
3.0000 mysql table_stats table_name varchar 64 192 utf8 utf8_bin varchar(64)
@@ -554,6 +564,11 @@ NULL mysql time_zone_transition_type Transition_type_id int NULL NULL NULL NULL
NULL mysql time_zone_transition_type Offset int NULL NULL NULL NULL int(11)
NULL mysql time_zone_transition_type Is_DST tinyint NULL NULL NULL NULL tinyint(3) unsigned
3.0000 mysql time_zone_transition_type Abbreviation char 8 24 utf8 utf8_general_ci char(8)
+NULL mysql transaction_registry transaction_id bigint NULL NULL NULL NULL bigint(20) unsigned
+NULL mysql transaction_registry commit_id bigint NULL NULL NULL NULL bigint(20) unsigned
+NULL mysql transaction_registry begin_timestamp timestamp NULL NULL NULL NULL timestamp(6)
+NULL mysql transaction_registry commit_timestamp timestamp NULL NULL NULL NULL timestamp(6)
+3.0000 mysql transaction_registry isolation_level enum 16 48 utf8 utf8_bin enum('READ-UNCOMMITTED','READ-COMMITTED','REPEATABLE-READ','SERIALIZABLE')
3.0000 mysql user Host char 60 180 utf8 utf8_bin char(60)
3.0000 mysql user User char 80 240 utf8 utf8_bin char(80)
1.0000 mysql user Password char 41 41 latin1 latin1_bin char(41)
@@ -586,6 +601,7 @@ NULL mysql time_zone_transition_type Is_DST tinyint NULL NULL NULL NULL tinyint(
3.0000 mysql user Event_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql user Trigger_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql user Create_tablespace_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
+3.0000 mysql user Delete_history_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql user ssl_type enum 9 27 utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED')
1.0000 mysql user ssl_cipher blob 65535 65535 NULL NULL blob
1.0000 mysql user x509_issuer blob 65535 65535 NULL NULL blob
diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
index c7d10790325..435a28728fe 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
@@ -27,6 +27,7 @@ def mysql db Create_routine_priv 18 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_gen
def mysql db Create_tmp_table_priv 14 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql db Create_view_priv 16 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql db Db 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI NEVER NULL
+def mysql db Delete_history_priv 23 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql db Delete_priv 7 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql db Drop_priv 9 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql db Event_priv 21 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
@@ -60,7 +61,7 @@ def mysql event modified 9 '0000-00-00 00:00:00' NO timestamp NULL NULL NULL NUL
def mysql event name 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI NEVER NULL
def mysql event on_completion 14 'DROP' NO enum 8 24 NULL NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') NEVER NULL
def mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned NEVER NULL
-def mysql event sql_mode 15 '' NO set 515 1545 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') NEVER NULL
+def mysql event sql_mode 15 '' NO set 539 1617 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NEVER NULL
def mysql event starts 11 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime NEVER NULL
def mysql event status 13 'ENABLED' NO enum 18 54 NULL NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NEVER NULL
def mysql event time_zone 18 'SYSTEM' NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64) NEVER NULL
@@ -119,6 +120,7 @@ def mysql index_stats prefix_arity 4 NULL NO int NULL NULL 10 0 NULL NULL NULL i
def mysql index_stats table_name 2 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_bin varchar(64) PRI NEVER NULL
def mysql plugin dl 2 '' NO varchar 128 384 NULL NULL NULL utf8 utf8_general_ci varchar(128) NEVER NULL
def mysql plugin name 1 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) PRI NEVER NULL
+def mysql proc aggregate 21 'NONE' NO enum 5 15 NULL NULL NULL utf8 utf8_general_ci enum('NONE','GROUP') NEVER NULL
def mysql proc body 11 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob NEVER NULL
def mysql proc body_utf8 20 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob NEVER NULL
def mysql proc character_set_client 17 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32) NEVER NULL
@@ -137,7 +139,7 @@ def mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL
def mysql proc security_type 8 'DEFINER' NO enum 7 21 NULL NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') NEVER NULL
def mysql proc specific_name 4 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) NEVER NULL
def mysql proc sql_data_access 6 'CONTAINS_SQL' NO enum 17 51 NULL NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') NEVER NULL
-def mysql proc sql_mode 15 '' NO set 515 1545 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') NEVER NULL
+def mysql proc sql_mode 15 '' NO set 539 1617 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NEVER NULL
def mysql proc type 3 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI NEVER NULL
def mysql procs_priv Db 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI NEVER NULL
def mysql procs_priv Grantor 6 '' NO char 141 423 NULL NULL NULL utf8 utf8_bin char(141) MUL NEVER NULL
@@ -185,7 +187,7 @@ def mysql tables_priv Db 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_bin char(6
def mysql tables_priv Grantor 5 '' NO char 141 423 NULL NULL NULL utf8 utf8_bin char(141) MUL NEVER NULL
def mysql tables_priv Host 1 '' NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI NEVER NULL
def mysql tables_priv Table_name 4 '' NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI NEVER NULL
-def mysql tables_priv Table_priv 7 '' NO set 98 294 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') NEVER NULL
+def mysql tables_priv Table_priv 7 '' NO set 121 363 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows') NEVER NULL
def mysql tables_priv Timestamp 6 current_timestamp() NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update current_timestamp() NEVER NULL
def mysql tables_priv User 3 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) PRI NEVER NULL
def mysql table_stats cardinality 3 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned NEVER NULL
@@ -207,14 +209,15 @@ def mysql time_zone_transition_type Time_zone_id 1 NULL NO int NULL NULL 10 0 NU
def mysql time_zone_transition_type Transition_type_id 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI NEVER NULL
def mysql user Alter_priv 17 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Alter_routine_priv 28 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
-def mysql user authentication_string 42 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_bin text NEVER NULL
+def mysql user authentication_string 43 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_bin text NEVER NULL
def mysql user Create_priv 8 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Create_routine_priv 27 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Create_tablespace_priv 32 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Create_tmp_table_priv 20 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Create_user_priv 29 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Create_view_priv 25 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
-def mysql user default_role 45 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) NEVER NULL
+def mysql user default_role 46 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) NEVER NULL
+def mysql user Delete_history_priv 33 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Delete_priv 7 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Drop_priv 9 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Event_priv 30 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
@@ -224,16 +227,16 @@ def mysql user Grant_priv 14 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci
def mysql user Host 1 '' NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI NEVER NULL
def mysql user Index_priv 16 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Insert_priv 5 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
-def mysql user is_role 44 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
+def mysql user is_role 45 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Lock_tables_priv 21 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
-def mysql user max_connections 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned NEVER NULL
-def mysql user max_questions 37 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned NEVER NULL
-def mysql user max_statement_time 46 0.000000 NO decimal NULL NULL 12 6 NULL NULL NULL decimal(12,6) NEVER NULL
-def mysql user max_updates 38 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned NEVER NULL
-def mysql user max_user_connections 40 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) NEVER NULL
+def mysql user max_connections 40 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned NEVER NULL
+def mysql user max_questions 38 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned NEVER NULL
+def mysql user max_statement_time 47 0.000000 NO decimal NULL NULL 12 6 NULL NULL NULL decimal(12,6) NEVER NULL
+def mysql user max_updates 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned NEVER NULL
+def mysql user max_user_connections 41 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) NEVER NULL
def mysql user Password 3 '' NO char 41 41 NULL NULL NULL latin1 latin1_bin char(41) NEVER NULL
-def mysql user password_expired 43 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
-def mysql user plugin 41 '' NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64) NEVER NULL
+def mysql user password_expired 44 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
+def mysql user plugin 42 '' NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64) NEVER NULL
def mysql user Process_priv 12 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user References_priv 15 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Reload_priv 10 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
@@ -243,17 +246,18 @@ def mysql user Select_priv 4 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci
def mysql user Show_db_priv 18 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Show_view_priv 26 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Shutdown_priv 11 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
-def mysql user ssl_cipher 34 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob NEVER NULL
-def mysql user ssl_type 33 '' NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED') NEVER NULL
+def mysql user ssl_cipher 35 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob NEVER NULL
+def mysql user ssl_type 34 '' NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED') NEVER NULL
def mysql user Super_priv 19 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Trigger_priv 31 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user Update_priv 6 'N' NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') NEVER NULL
def mysql user User 2 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) PRI NEVER NULL
-def mysql user x509_issuer 35 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob NEVER NULL
-def mysql user x509_subject 36 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob NEVER NULL
+def mysql user x509_issuer 36 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob NEVER NULL
+def mysql user x509_subject 37 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob NEVER NULL
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
@@ -278,6 +282,7 @@ COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
SELECT DISTINCT
CHARACTER_OCTET_LENGTH / CHARACTER_MAXIMUM_LENGTH AS COL_CML,
DATA_TYPE,
@@ -298,6 +303,7 @@ COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
SELECT DISTINCT
CHARACTER_OCTET_LENGTH / CHARACTER_MAXIMUM_LENGTH AS COL_CML,
DATA_TYPE,
@@ -319,6 +325,7 @@ NULL tinyint NULL NULL
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
--> CHAR(0) is allowed (see manual), and here both CHARACHTER_* values
--> are 0, which is intended behavior, and the result of 0 / 0 IS NULL
SELECT CHARACTER_OCTET_LENGTH / CHARACTER_MAXIMUM_LENGTH AS COL_CML,
@@ -375,6 +382,7 @@ NULL mysql column_stats hist_size tinyint NULL NULL NULL NULL tinyint(3) unsigne
3.0000 mysql db Execute_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql db Event_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql db Trigger_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
+3.0000 mysql db Delete_history_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql event db char 64 192 utf8 utf8_bin char(64)
3.0000 mysql event name char 64 192 utf8 utf8_general_ci char(64)
1.0000 mysql event body longblob 4294967295 4294967295 NULL NULL longblob
@@ -389,7 +397,7 @@ NULL mysql event starts datetime NULL NULL NULL NULL datetime
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
-3.0000 mysql event sql_mode set 515 1545 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL')
+3.0000 mysql event sql_mode set 539 1617 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@@ -466,12 +474,13 @@ NULL mysql index_stats avg_frequency decimal NULL NULL NULL NULL decimal(12,4)
3.0000 mysql proc definer char 141 423 utf8 utf8_bin char(141)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql proc sql_mode set 515 1545 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL')
+3.0000 mysql proc sql_mode set 539 1617 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')
1.0000 mysql proc comment text 65535 65535 utf8 utf8_bin text
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc db_collation char 32 96 utf8 utf8_bin char(32)
1.0000 mysql proc body_utf8 longblob 4294967295 4294967295 NULL NULL longblob
+3.0000 mysql proc aggregate enum 5 15 utf8 utf8_general_ci enum('NONE','GROUP')
3.0000 mysql procs_priv Host char 60 180 utf8 utf8_bin char(60)
3.0000 mysql procs_priv Db char 64 192 utf8 utf8_bin char(64)
3.0000 mysql procs_priv User char 80 240 utf8 utf8_bin char(80)
@@ -519,7 +528,7 @@ NULL mysql slow_log rows_affected int NULL NULL NULL NULL int(11)
3.0000 mysql tables_priv Table_name char 64 192 utf8 utf8_bin char(64)
3.0000 mysql tables_priv Grantor char 141 423 utf8 utf8_bin char(141)
NULL mysql tables_priv Timestamp timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql tables_priv Table_priv set 98 294 utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger')
+3.0000 mysql tables_priv Table_priv set 121 363 utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows')
3.0000 mysql tables_priv Column_priv set 31 93 utf8 utf8_general_ci set('Select','Insert','Update','References')
3.0000 mysql table_stats db_name varchar 64 192 utf8 utf8_bin varchar(64)
3.0000 mysql table_stats table_name varchar 64 192 utf8 utf8_bin varchar(64)
@@ -570,6 +579,7 @@ NULL mysql time_zone_transition_type Is_DST tinyint NULL NULL NULL NULL tinyint(
3.0000 mysql user Event_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql user Trigger_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql user Create_tablespace_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
+3.0000 mysql user Delete_history_priv enum 1 3 utf8 utf8_general_ci enum('N','Y')
3.0000 mysql user ssl_type enum 9 27 utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED')
1.0000 mysql user ssl_cipher blob 65535 65535 NULL NULL blob
1.0000 mysql user x509_issuer blob 65535 65535 NULL NULL blob
@@ -587,3 +597,4 @@ NULL mysql user max_statement_time decimal NULL NULL NULL NULL decimal(12,6)
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
diff --git a/mysql-test/suite/funcs_1/r/is_key_column_usage.result b/mysql-test/suite/funcs_1/r/is_key_column_usage.result
index 933a8e537f2..5c126a48419 100644
--- a/mysql-test/suite/funcs_1/r/is_key_column_usage.result
+++ b/mysql-test/suite/funcs_1/r/is_key_column_usage.result
@@ -142,6 +142,8 @@ def mysql PRIMARY def mysql time_zone_transition Time_zone_id
def mysql PRIMARY def mysql time_zone_transition Transition_time
def mysql PRIMARY def mysql time_zone_transition_type Time_zone_id
def mysql PRIMARY def mysql time_zone_transition_type Transition_type_id
+def mysql commit_id def mysql transaction_registry commit_id
+def mysql PRIMARY def mysql transaction_registry transaction_id
def mysql PRIMARY def mysql user Host
def mysql PRIMARY def mysql user User
########################################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_key_column_usage_embedded.result b/mysql-test/suite/funcs_1/r/is_key_column_usage_embedded.result
index 62e566ca89f..d41f7395483 100644
--- a/mysql-test/suite/funcs_1/r/is_key_column_usage_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_key_column_usage_embedded.result
@@ -142,6 +142,8 @@ def mysql PRIMARY def mysql time_zone_transition Time_zone_id
def mysql PRIMARY def mysql time_zone_transition Transition_time
def mysql PRIMARY def mysql time_zone_transition_type Time_zone_id
def mysql PRIMARY def mysql time_zone_transition_type Transition_type_id
+def mysql commit_id def mysql transaction_registry commit_id
+def mysql PRIMARY def mysql transaction_registry transaction_id
def mysql PRIMARY def mysql user Host
def mysql PRIMARY def mysql user User
########################################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_schema_privileges.result b/mysql-test/suite/funcs_1/r/is_schema_privileges.result
index cf9b70308de..1339639106f 100644
--- a/mysql-test/suite/funcs_1/r/is_schema_privileges.result
+++ b/mysql-test/suite/funcs_1/r/is_schema_privileges.result
@@ -68,6 +68,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE
''@'%' def test CREATE ROUTINE
''@'%' def test EVENT
''@'%' def test TRIGGER
+''@'%' def test DELETE VERSIONING ROWS
''@'%' def test\_% SELECT
''@'%' def test\_% INSERT
''@'%' def test\_% UPDATE
@@ -84,6 +85,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE
''@'%' def test\_% CREATE ROUTINE
''@'%' def test\_% EVENT
''@'%' def test\_% TRIGGER
+''@'%' def test\_% DELETE VERSIONING ROWS
###############################################################################
# Testcase 3.2.15.2-3.2.15.4 INFORMATION_SCHEMA.SCHEMA_PRIVILEGES accessibility
###############################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_schema_privileges_is_mysql_test.result b/mysql-test/suite/funcs_1/r/is_schema_privileges_is_mysql_test.result
index 38257899a4b..528a770e0eb 100644
--- a/mysql-test/suite/funcs_1/r/is_schema_privileges_is_mysql_test.result
+++ b/mysql-test/suite/funcs_1/r/is_schema_privileges_is_mysql_test.result
@@ -16,6 +16,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
''@'%' def test CREATE TEMPORARY TABLES NO
''@'%' def test CREATE VIEW NO
''@'%' def test DELETE NO
+''@'%' def test DELETE VERSIONING ROWS NO
''@'%' def test DROP NO
''@'%' def test EVENT NO
''@'%' def test INDEX NO
diff --git a/mysql-test/suite/funcs_1/r/is_statistics.result b/mysql-test/suite/funcs_1/r/is_statistics.result
index a07d9d8d3c3..419eb0b4b4c 100644
--- a/mysql-test/suite/funcs_1/r/is_statistics.result
+++ b/mysql-test/suite/funcs_1/r/is_statistics.result
@@ -155,6 +155,7 @@ def mysql user mysql PRIMARY
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
####################################################################################
# Testcase 3.2.14.2 + 3.2.14.3: INFORMATION_SCHEMA.STATISTICS accessible information
####################################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_statistics_mysql.result b/mysql-test/suite/funcs_1/r/is_statistics_mysql.result
index dc3ed5f9839..31fb460f9aa 100644
--- a/mysql-test/suite/funcs_1/r/is_statistics_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_statistics_mysql.result
@@ -77,6 +77,11 @@ def mysql time_zone_transition 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL
def mysql time_zone_transition 0 mysql PRIMARY 2 Transition_time A #CARD# NULL NULL BTREE
def mysql time_zone_transition_type 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
def mysql time_zone_transition_type 0 mysql PRIMARY 2 Transition_type_id A #CARD# NULL NULL BTREE
+def mysql transaction_registry 1 mysql begin_timestamp 1 begin_timestamp A #CARD# NULL NULL BTREE
+def mysql transaction_registry 0 mysql commit_id 1 commit_id A #CARD# NULL NULL BTREE
+def mysql transaction_registry 1 mysql commit_timestamp 1 commit_timestamp A #CARD# NULL NULL BTREE
+def mysql transaction_registry 1 mysql commit_timestamp 2 transaction_id A #CARD# NULL NULL BTREE
+def mysql transaction_registry 0 mysql PRIMARY 1 transaction_id A #CARD# NULL NULL BTREE
def mysql user 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
def mysql user 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE
connect testuser1,localhost,testuser1,,db_datadict;
diff --git a/mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result
index cbc9a8f17ce..c81052321f8 100644
--- a/mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result
@@ -77,6 +77,11 @@ def mysql time_zone_transition 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL
def mysql time_zone_transition 0 mysql PRIMARY 2 Transition_time A #CARD# NULL NULL BTREE
def mysql time_zone_transition_type 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
def mysql time_zone_transition_type 0 mysql PRIMARY 2 Transition_type_id A #CARD# NULL NULL BTREE
+def mysql transaction_registry 1 mysql begin_timestamp 1 begin_timestamp A #CARD# NULL NULL BTREE
+def mysql transaction_registry 0 mysql commit_id 1 commit_id A #CARD# NULL NULL BTREE
+def mysql transaction_registry 1 mysql commit_timestamp 1 commit_timestamp A #CARD# NULL NULL BTREE
+def mysql transaction_registry 1 mysql commit_timestamp 2 transaction_id A #CARD# NULL NULL BTREE
+def mysql transaction_registry 0 mysql PRIMARY 1 transaction_id A #CARD# NULL NULL BTREE
def mysql user 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
def mysql user 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE
connect testuser1,localhost,testuser1,,db_datadict;
@@ -154,6 +159,11 @@ def mysql time_zone_transition 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL
def mysql time_zone_transition 0 mysql PRIMARY 2 Transition_time A #CARD# NULL NULL BTREE
def mysql time_zone_transition_type 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
def mysql time_zone_transition_type 0 mysql PRIMARY 2 Transition_type_id A #CARD# NULL NULL BTREE
+def mysql transaction_registry 1 mysql begin_timestamp 1 begin_timestamp A #CARD# NULL NULL BTREE
+def mysql transaction_registry 0 mysql commit_id 1 commit_id A #CARD# NULL NULL BTREE
+def mysql transaction_registry 1 mysql commit_timestamp 1 commit_timestamp A #CARD# NULL NULL BTREE
+def mysql transaction_registry 1 mysql commit_timestamp 2 transaction_id A #CARD# NULL NULL BTREE
+def mysql transaction_registry 0 mysql PRIMARY 1 transaction_id A #CARD# NULL NULL BTREE
def mysql user 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
def mysql user 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE
connection default;
diff --git a/mysql-test/suite/funcs_1/r/is_table_constraints.result b/mysql-test/suite/funcs_1/r/is_table_constraints.result
index 2f3afaaa0ad..d968d3b65de 100644
--- a/mysql-test/suite/funcs_1/r/is_table_constraints.result
+++ b/mysql-test/suite/funcs_1/r/is_table_constraints.result
@@ -88,6 +88,8 @@ def mysql PRIMARY mysql time_zone_leap_second
def mysql PRIMARY mysql time_zone_name
def mysql PRIMARY mysql time_zone_transition
def mysql PRIMARY mysql time_zone_transition_type
+def mysql commit_id mysql transaction_registry
+def mysql PRIMARY mysql transaction_registry
def mysql PRIMARY mysql user
#########################################################################################
# Testcase 3.2.7.2 + 3.2.7.3: INFORMATION_SCHEMA.TABLE_CONSTRAINTS accessible information
diff --git a/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result b/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result
index e54de0671a2..b56c5115f16 100644
--- a/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result
@@ -37,6 +37,8 @@ def mysql PRIMARY mysql time_zone_leap_second PRIMARY KEY
def mysql PRIMARY mysql time_zone_name PRIMARY KEY
def mysql PRIMARY mysql time_zone_transition PRIMARY KEY
def mysql PRIMARY mysql time_zone_transition_type PRIMARY KEY
+def mysql commit_id mysql transaction_registry UNIQUE
+def mysql PRIMARY mysql transaction_registry PRIMARY KEY
def mysql PRIMARY mysql user PRIMARY KEY
connect testuser1,localhost,testuser1,,db_datadict;
SELECT * FROM information_schema.table_constraints
diff --git a/mysql-test/suite/funcs_1/r/is_table_constraints_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_table_constraints_mysql_embedded.result
index 58a2373b66d..b40bc0ea0c7 100644
--- a/mysql-test/suite/funcs_1/r/is_table_constraints_mysql_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_table_constraints_mysql_embedded.result
@@ -37,6 +37,8 @@ def mysql PRIMARY mysql time_zone_leap_second PRIMARY KEY
def mysql PRIMARY mysql time_zone_name PRIMARY KEY
def mysql PRIMARY mysql time_zone_transition PRIMARY KEY
def mysql PRIMARY mysql time_zone_transition_type PRIMARY KEY
+def mysql commit_id mysql transaction_registry UNIQUE
+def mysql PRIMARY mysql transaction_registry PRIMARY KEY
def mysql PRIMARY mysql user PRIMARY KEY
connect testuser1,localhost,testuser1,,db_datadict;
SELECT * FROM information_schema.table_constraints
@@ -73,6 +75,8 @@ def mysql PRIMARY mysql time_zone_leap_second PRIMARY KEY
def mysql PRIMARY mysql time_zone_name PRIMARY KEY
def mysql PRIMARY mysql time_zone_transition PRIMARY KEY
def mysql PRIMARY mysql time_zone_transition_type PRIMARY KEY
+def mysql commit_id mysql transaction_registry UNIQUE
+def mysql PRIMARY mysql transaction_registry PRIMARY KEY
def mysql PRIMARY mysql user PRIMARY KEY
connection default;
disconnect testuser1;
diff --git a/mysql-test/suite/funcs_1/r/is_table_privileges.result b/mysql-test/suite/funcs_1/r/is_table_privileges.result
index 340aead9aba..c448241e14e 100644
--- a/mysql-test/suite/funcs_1/r/is_table_privileges.result
+++ b/mysql-test/suite/funcs_1/r/is_table_privileges.result
@@ -96,6 +96,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'testuser2'@'localhost' def db_datadict tb1 CREATE YES
'testuser2'@'localhost' def db_datadict tb1 CREATE VIEW YES
'testuser2'@'localhost' def db_datadict tb1 DELETE YES
+'testuser2'@'localhost' def db_datadict tb1 DELETE VERSIONING ROWS YES
'testuser2'@'localhost' def db_datadict tb1 DROP YES
'testuser2'@'localhost' def db_datadict tb1 INDEX YES
'testuser2'@'localhost' def db_datadict tb1 INSERT YES
@@ -131,6 +132,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'testuser2'@'localhost' def db_datadict tb1 CREATE YES
'testuser2'@'localhost' def db_datadict tb1 CREATE VIEW YES
'testuser2'@'localhost' def db_datadict tb1 DELETE YES
+'testuser2'@'localhost' def db_datadict tb1 DELETE VERSIONING ROWS YES
'testuser2'@'localhost' def db_datadict tb1 DROP YES
'testuser2'@'localhost' def db_datadict tb1 INDEX YES
'testuser2'@'localhost' def db_datadict tb1 INSERT YES
@@ -184,6 +186,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'testuser1'@'localhost' def test t1_table CREATE NO
'testuser1'@'localhost' def test t1_table CREATE VIEW NO
'testuser1'@'localhost' def test t1_table DELETE NO
+'testuser1'@'localhost' def test t1_table DELETE VERSIONING ROWS NO
'testuser1'@'localhost' def test t1_table DROP NO
'testuser1'@'localhost' def test t1_table INDEX NO
'testuser1'@'localhost' def test t1_table INSERT NO
@@ -196,6 +199,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'testuser1'@'localhost' def test t1_view CREATE NO
'testuser1'@'localhost' def test t1_view CREATE VIEW NO
'testuser1'@'localhost' def test t1_view DELETE NO
+'testuser1'@'localhost' def test t1_view DELETE VERSIONING ROWS NO
'testuser1'@'localhost' def test t1_view DROP NO
'testuser1'@'localhost' def test t1_view INDEX NO
'testuser1'@'localhost' def test t1_view INSERT NO
diff --git a/mysql-test/suite/funcs_1/r/is_tables.result b/mysql-test/suite/funcs_1/r/is_tables.result
index 75809a3b77a..739d00eacb9 100644
--- a/mysql-test/suite/funcs_1/r/is_tables.result
+++ b/mysql-test/suite/funcs_1/r/is_tables.result
@@ -49,6 +49,8 @@ TABLE_COLLATION varchar(32) YES NULL
CHECKSUM bigint(21) unsigned YES NULL
CREATE_OPTIONS varchar(2048) YES NULL
TABLE_COMMENT varchar(2048) NO
+MAX_INDEX_LENGTH bigint(21) unsigned YES NULL
+TEMPORARY varchar(1) YES NULL
SHOW CREATE TABLE information_schema.TABLES;
Table Create Table
TABLES CREATE TEMPORARY TABLE `TABLES` (
@@ -72,7 +74,9 @@ TABLES CREATE TEMPORARY TABLE `TABLES` (
`TABLE_COLLATION` varchar(32) DEFAULT NULL,
`CHECKSUM` bigint(21) unsigned DEFAULT NULL,
`CREATE_OPTIONS` varchar(2048) DEFAULT NULL,
- `TABLE_COMMENT` varchar(2048) NOT NULL DEFAULT ''
+ `TABLE_COMMENT` varchar(2048) NOT NULL DEFAULT '',
+ `MAX_INDEX_LENGTH` bigint(21) unsigned DEFAULT NULL,
+ `TEMPORARY` varchar(1) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=utf8
SHOW COLUMNS FROM information_schema.TABLES;
Field Type Null Key Default Extra
@@ -97,6 +101,8 @@ TABLE_COLLATION varchar(32) YES NULL
CHECKSUM bigint(21) unsigned YES NULL
CREATE_OPTIONS varchar(2048) YES NULL
TABLE_COMMENT varchar(2048) NO
+MAX_INDEX_LENGTH bigint(21) unsigned YES NULL
+TEMPORARY varchar(1) YES NULL
SELECT table_catalog, table_schema, table_name
FROM information_schema.tables WHERE table_catalog IS NULL OR table_catalog <> 'def';
table_catalog table_schema table_name
@@ -128,11 +134,11 @@ CREATE VIEW v3 AS SELECT * FROM tb3;
GRANT SELECT ON db_datadict.v3 to 'testuser3'@'localhost';
SELECT * FROM information_schema.tables
WHERE table_schema = 'db_datadict' ORDER BY table_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
-def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
+def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW NULL NULL
SHOW TABLES FROM db_datadict;
Tables_in_db_datadict
tb1
@@ -142,9 +148,9 @@ v3
connect testuser2, localhost, testuser2, , db_datadict;
SELECT * FROM information_schema.tables
WHERE table_schema = 'db_datadict' ORDER BY table_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
-def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
+def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
SHOW TABLES FROM db_datadict;
Tables_in_db_datadict
tb1
@@ -152,9 +158,9 @@ tb3
connect testuser3, localhost, testuser3, , db_datadict;
SELECT * FROM information_schema.tables
WHERE table_schema = 'db_datadict' ORDER BY table_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
-def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
+def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW NULL NULL
SHOW TABLES FROM db_datadict;
Tables_in_db_datadict
tb3
@@ -162,11 +168,11 @@ v3
connection default;
SELECT * FROM information_schema.tables
WHERE table_schema = 'db_datadict' ORDER BY table_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
-def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
+def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW NULL NULL
SHOW TABLES FROM db_datadict;
Tables_in_db_datadict
tb1
@@ -215,6 +221,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM #CS#
CREATE_OPTIONS
TABLE_COMMENT Initial Comment
+MAX_INDEX_LENGTH 0
+TEMPORARY N
SELECT table_name FROM information_schema.tables
WHERE table_name LIKE 't1_my_table%';
table_name
@@ -368,6 +376,8 @@ TABLE_COLLATION NULL
CHECKSUM NULL
CREATE_OPTIONS NULL
TABLE_COMMENT VIEW
+MAX_INDEX_LENGTH NULL
+TEMPORARY NULL
DROP VIEW test.t1_my_tablex;
SELECT table_name FROM information_schema.tables
WHERE table_name = 't1_my_tablex';
diff --git a/mysql-test/suite/funcs_1/r/is_tables_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_embedded.result
index c42645f3536..4d54128e5b0 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_embedded.result
@@ -49,6 +49,8 @@ TABLE_COLLATION varchar(32) YES NULL
CHECKSUM bigint(21) unsigned YES NULL
CREATE_OPTIONS varchar(2048) YES NULL
TABLE_COMMENT varchar(2048) NO
+MAX_INDEX_LENGTH bigint(21) unsigned YES NULL
+TEMPORARY varchar(1) YES NULL
SHOW CREATE TABLE information_schema.TABLES;
Table Create Table
TABLES CREATE TEMPORARY TABLE `TABLES` (
@@ -72,7 +74,9 @@ TABLES CREATE TEMPORARY TABLE `TABLES` (
`TABLE_COLLATION` varchar(32) DEFAULT NULL,
`CHECKSUM` bigint(21) unsigned DEFAULT NULL,
`CREATE_OPTIONS` varchar(2048) DEFAULT NULL,
- `TABLE_COMMENT` varchar(2048) NOT NULL DEFAULT ''
+ `TABLE_COMMENT` varchar(2048) NOT NULL DEFAULT '',
+ `MAX_INDEX_LENGTH` bigint(21) unsigned DEFAULT NULL,
+ `TEMPORARY` varchar(1) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=utf8
SHOW COLUMNS FROM information_schema.TABLES;
Field Type Null Key Default Extra
@@ -97,6 +101,8 @@ TABLE_COLLATION varchar(32) YES NULL
CHECKSUM bigint(21) unsigned YES NULL
CREATE_OPTIONS varchar(2048) YES NULL
TABLE_COMMENT varchar(2048) NO
+MAX_INDEX_LENGTH bigint(21) unsigned YES NULL
+TEMPORARY varchar(1) YES NULL
SELECT table_catalog, table_schema, table_name
FROM information_schema.tables WHERE table_catalog IS NULL OR table_catalog <> 'def';
table_catalog table_schema table_name
@@ -128,11 +134,11 @@ CREATE VIEW v3 AS SELECT * FROM tb3;
GRANT SELECT ON db_datadict.v3 to 'testuser3'@'localhost';
SELECT * FROM information_schema.tables
WHERE table_schema = 'db_datadict' ORDER BY table_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
-def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
+def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW NULL NULL
SHOW TABLES FROM db_datadict;
Tables_in_db_datadict
tb1
@@ -142,11 +148,11 @@ v3
connect testuser2, localhost, testuser2, , db_datadict;
SELECT * FROM information_schema.tables
WHERE table_schema = 'db_datadict' ORDER BY table_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
-def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
+def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW NULL NULL
SHOW TABLES FROM db_datadict;
Tables_in_db_datadict
tb1
@@ -156,11 +162,11 @@ v3
connect testuser3, localhost, testuser3, , db_datadict;
SELECT * FROM information_schema.tables
WHERE table_schema = 'db_datadict' ORDER BY table_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
-def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
+def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW NULL NULL
SHOW TABLES FROM db_datadict;
Tables_in_db_datadict
tb1
@@ -170,11 +176,11 @@ v3
connection default;
SELECT * FROM information_schema.tables
WHERE table_schema = 'db_datadict' ORDER BY table_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
-def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS#
-def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
+def db_datadict tb1 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb2 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict tb3 BASE TABLE #ENG# 10 #RF# 0 #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# latin1_swedish_ci #CS# 0 N
+def db_datadict v3 VIEW #ENG# NULL #RF# NULL #ARL# #DL# #MDL# #IL# #DF# NULL #CRT #UT# #CT# NULL #CS# NULL VIEW NULL NULL
SHOW TABLES FROM db_datadict;
Tables_in_db_datadict
tb1
@@ -223,6 +229,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM #CS#
CREATE_OPTIONS
TABLE_COMMENT Initial Comment
+MAX_INDEX_LENGTH 0
+TEMPORARY N
SELECT table_name FROM information_schema.tables
WHERE table_name LIKE 't1_my_table%';
table_name
@@ -376,6 +384,8 @@ TABLE_COLLATION NULL
CHECKSUM NULL
CREATE_OPTIONS NULL
TABLE_COMMENT VIEW
+MAX_INDEX_LENGTH NULL
+TEMPORARY NULL
DROP VIEW test.t1_my_tablex;
SELECT table_name FROM information_schema.tables
WHERE table_name = 't1_my_tablex';
diff --git a/mysql-test/suite/funcs_1/r/is_tables_innodb.result b/mysql-test/suite/funcs_1/r/is_tables_innodb.result
index 0e2389771b2..5274f58a8ef 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_innodb.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_innodb.result
@@ -36,6 +36,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -59,6 +61,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -82,6 +86,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
SHOW TABLES FROM test1;
@@ -126,6 +132,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -149,6 +157,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
SHOW TABLES FROM test1;
diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result
index 54bc727fb74..e0e5a82a265 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_is.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_is.result
@@ -33,6 +33,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -56,6 +58,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -79,6 +83,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -102,6 +108,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -125,6 +133,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -148,6 +158,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -171,6 +183,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -194,6 +208,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -217,6 +233,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -240,6 +258,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -263,6 +283,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -286,6 +308,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -309,6 +333,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -332,6 +358,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -355,6 +383,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -378,6 +408,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -401,6 +433,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -424,6 +458,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -447,6 +483,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -470,6 +508,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -493,6 +533,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -516,6 +558,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -539,6 +583,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -562,6 +608,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -585,6 +633,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -608,6 +658,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -631,6 +683,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -654,6 +708,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -677,6 +733,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -700,6 +758,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -723,6 +783,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -746,6 +808,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -769,6 +833,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -792,6 +858,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -815,6 +883,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -838,6 +908,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -861,6 +933,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -884,6 +958,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -907,6 +983,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -930,6 +1008,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
DROP USER testuser1@localhost;
@@ -969,6 +1049,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -992,6 +1074,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1015,6 +1099,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1038,6 +1124,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1061,6 +1149,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1084,6 +1174,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1107,6 +1199,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1130,6 +1224,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1153,6 +1249,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1176,6 +1274,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1199,6 +1299,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1222,6 +1324,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1245,6 +1349,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1268,6 +1374,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1291,6 +1399,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1314,6 +1424,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1337,6 +1449,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1360,6 +1474,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1383,6 +1499,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1406,6 +1524,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1429,6 +1549,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1452,6 +1574,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1475,6 +1599,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1498,6 +1624,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1521,6 +1649,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1544,6 +1674,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1567,6 +1699,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1590,6 +1724,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1613,6 +1749,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1636,6 +1774,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1659,6 +1799,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1682,6 +1824,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1705,6 +1849,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1728,6 +1874,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1751,6 +1899,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1774,6 +1924,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1797,6 +1949,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1820,6 +1974,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1843,6 +1999,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1866,6 +2024,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
connection default;
diff --git a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
index 54bc727fb74..e0e5a82a265 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
@@ -33,6 +33,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -56,6 +58,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -79,6 +83,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -102,6 +108,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -125,6 +133,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -148,6 +158,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -171,6 +183,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -194,6 +208,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -217,6 +233,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -240,6 +258,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -263,6 +283,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -286,6 +308,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -309,6 +333,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -332,6 +358,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -355,6 +383,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -378,6 +408,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -401,6 +433,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -424,6 +458,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -447,6 +483,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -470,6 +508,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -493,6 +533,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -516,6 +558,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -539,6 +583,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -562,6 +608,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -585,6 +633,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -608,6 +658,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -631,6 +683,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -654,6 +708,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -677,6 +733,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -700,6 +758,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -723,6 +783,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -746,6 +808,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -769,6 +833,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -792,6 +858,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -815,6 +883,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -838,6 +908,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -861,6 +933,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -884,6 +958,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -907,6 +983,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -930,6 +1008,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
DROP USER testuser1@localhost;
@@ -969,6 +1049,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -992,6 +1074,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1015,6 +1099,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1038,6 +1124,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1061,6 +1149,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1084,6 +1174,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1107,6 +1199,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1130,6 +1224,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1153,6 +1249,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1176,6 +1274,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1199,6 +1299,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1222,6 +1324,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1245,6 +1349,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1268,6 +1374,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1291,6 +1399,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1314,6 +1424,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1337,6 +1449,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1360,6 +1474,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1383,6 +1499,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1406,6 +1524,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1429,6 +1549,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1452,6 +1574,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1475,6 +1599,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1498,6 +1624,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1521,6 +1649,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1544,6 +1674,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1567,6 +1699,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1590,6 +1724,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1613,6 +1749,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1636,6 +1774,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1659,6 +1799,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1682,6 +1824,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1705,6 +1849,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1728,6 +1874,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1751,6 +1899,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1774,6 +1924,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1797,6 +1949,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1820,6 +1974,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1843,6 +1999,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1866,6 +2024,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
user_comment
Separator -----------------------------------------------------
connection default;
diff --git a/mysql-test/suite/funcs_1/r/is_tables_memory.result b/mysql-test/suite/funcs_1/r/is_tables_memory.result
index 2ee21898085..73beadf644c 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_memory.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_memory.result
@@ -37,6 +37,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -60,6 +62,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -83,6 +87,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
SHOW TABLES FROM test1;
@@ -127,6 +133,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -150,6 +158,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
SHOW TABLES FROM test1;
diff --git a/mysql-test/suite/funcs_1/r/is_tables_myisam.result b/mysql-test/suite/funcs_1/r/is_tables_myisam.result
index 5ccd8377cb1..6c2e9307d78 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_myisam.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_myisam.result
@@ -37,6 +37,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -60,6 +62,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -83,6 +87,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
SHOW TABLES FROM test1;
@@ -127,6 +133,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -150,6 +158,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
SHOW TABLES FROM test1;
diff --git a/mysql-test/suite/funcs_1/r/is_tables_myisam_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_myisam_embedded.result
index 5a1b6df84cb..9b2cb07f391 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_myisam_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_myisam_embedded.result
@@ -37,6 +37,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -60,6 +62,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -83,6 +87,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
SHOW TABLES FROM test1;
@@ -127,6 +133,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -150,6 +158,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -173,6 +183,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
SHOW TABLES FROM test1;
diff --git a/mysql-test/suite/funcs_1/r/is_tables_mysql.result b/mysql-test/suite/funcs_1/r/is_tables_mysql.result
index 8e0c9b64dab..2ceed585699 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_mysql.result
@@ -31,6 +31,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Column privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -54,6 +56,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Statistics on Columns
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -77,6 +81,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Database privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -100,6 +106,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Events
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -123,6 +131,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment User defined functions
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -146,6 +156,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment General log
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -169,6 +181,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Replication slave GTID position
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -192,6 +206,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment help categories
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -215,6 +231,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment help keywords
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -238,6 +256,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment keyword-topic relation
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -261,6 +281,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment help topics
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -284,6 +306,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Host privileges; Merged with database privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -307,6 +331,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Statistics on Indexes
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -330,6 +356,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -353,6 +381,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -376,6 +406,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment MySQL plugins
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -399,6 +431,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Stored Procedures
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -422,6 +456,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Procedure privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -445,6 +481,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment User proxy privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -468,6 +506,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Granted roles
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -491,6 +531,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment MySQL Foreign Servers table
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -514,6 +556,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Slow log
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -537,6 +581,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Table privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -560,6 +606,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Statistics on Tables
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -583,6 +631,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zones
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -606,6 +656,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Leap seconds information for time zones
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -629,6 +681,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zone names
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -652,6 +706,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zone transitions
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -675,10 +731,37 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zone transition types
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA mysql
+TABLE_NAME transaction_registry
+TABLE_TYPE BASE TABLE
+ENGINE InnoDB
+VERSION 10
+ROW_FORMAT DYNAMIC_OR_PAGE
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_bin
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG def
+TABLE_SCHEMA mysql
TABLE_NAME user
TABLE_TYPE BASE TABLE
ENGINE MYISAM_OR_MARIA
@@ -698,6 +781,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Users and global privileges
Separator -----------------------------------------------------
DROP USER testuser1@localhost;
diff --git a/mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result
index f40294491cc..77fa6ddae1e 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result
@@ -31,6 +31,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Column privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -54,6 +56,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Statistics on Columns
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -77,6 +81,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Database privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -100,6 +106,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Events
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -123,6 +131,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment User defined functions
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -146,6 +156,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment General log
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -169,6 +181,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Replication slave GTID position
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -192,6 +206,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment help categories
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -215,6 +231,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment help keywords
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -238,6 +256,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment keyword-topic relation
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -261,6 +281,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment help topics
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -284,6 +306,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Host privileges; Merged with database privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -307,6 +331,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Statistics on Indexes
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -330,6 +356,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -353,6 +381,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -376,6 +406,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment MySQL plugins
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -399,6 +431,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Stored Procedures
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -422,6 +456,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Procedure privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -445,6 +481,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment User proxy privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -468,6 +506,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Granted roles
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -491,6 +531,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment MySQL Foreign Servers table
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -514,6 +556,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Slow log
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -537,6 +581,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Table privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -560,6 +606,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Statistics on Tables
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -583,6 +631,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zones
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -606,6 +656,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Leap seconds information for time zones
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -629,6 +681,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zone names
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -652,6 +706,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zone transitions
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -675,10 +731,37 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zone transition types
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA mysql
+TABLE_NAME transaction_registry
+TABLE_TYPE BASE TABLE
+ENGINE InnoDB
+VERSION 10
+ROW_FORMAT DYNAMIC_OR_PAGE
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_bin
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG def
+TABLE_SCHEMA mysql
TABLE_NAME user
TABLE_TYPE BASE TABLE
ENGINE MYISAM_OR_MARIA
@@ -698,6 +781,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Users and global privileges
Separator -----------------------------------------------------
DROP USER testuser1@localhost;
@@ -735,6 +820,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Column privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -758,6 +845,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Statistics on Columns
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -781,6 +870,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Database privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -804,6 +895,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Events
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -827,6 +920,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment User defined functions
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -850,6 +945,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment General log
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -873,6 +970,8 @@ TABLE_COLLATION latin1_swedish_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Replication slave GTID position
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -896,6 +995,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment help categories
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -919,6 +1020,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment help keywords
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -942,6 +1045,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment keyword-topic relation
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -965,6 +1070,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment help topics
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -988,6 +1095,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Host privileges; Merged with database privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1011,6 +1120,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Statistics on Indexes
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1034,6 +1145,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1057,6 +1170,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1080,6 +1195,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment MySQL plugins
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1103,6 +1220,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Stored Procedures
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1126,6 +1245,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Procedure privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1149,6 +1270,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment User proxy privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1172,6 +1295,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Granted roles
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1195,6 +1320,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment MySQL Foreign Servers table
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1218,6 +1345,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Slow log
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1241,6 +1370,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Table privileges
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1264,6 +1395,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Statistics on Tables
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1287,6 +1420,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zones
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1310,6 +1445,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Leap seconds information for time zones
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1333,6 +1470,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zone names
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1356,6 +1495,8 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zone transitions
Separator -----------------------------------------------------
TABLE_CATALOG def
@@ -1379,10 +1520,37 @@ TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Time zone transition types
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA mysql
+TABLE_NAME transaction_registry
+TABLE_TYPE BASE TABLE
+ENGINE InnoDB
+VERSION 10
+ROW_FORMAT DYNAMIC_OR_PAGE
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_bin
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG def
+TABLE_SCHEMA mysql
TABLE_NAME user
TABLE_TYPE BASE TABLE
ENGINE MYISAM_OR_MARIA
@@ -1402,6 +1570,8 @@ TABLE_COLLATION utf8_bin
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY N
user_comment Users and global privileges
Separator -----------------------------------------------------
connection default;
diff --git a/mysql-test/suite/funcs_1/r/is_triggers.result b/mysql-test/suite/funcs_1/r/is_triggers.result
index 347bf02238a..1ea7263eb8f 100644
--- a/mysql-test/suite/funcs_1/r/is_triggers.result
+++ b/mysql-test/suite/funcs_1/r/is_triggers.result
@@ -145,7 +145,7 @@ connect testuser2, localhost, testuser2, , db_datadict;
SHOW GRANTS FOR 'testuser2'@'localhost';
Grants for testuser2@localhost
GRANT USAGE ON *.* TO 'testuser2'@'localhost'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW ON `db_datadict`.`t1` TO 'testuser2'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, DELETE VERSIONING ROWS ON `db_datadict`.`t1` TO 'testuser2'@'localhost'
# No TRIGGER Privilege --> no result for query
SELECT * FROM information_schema.triggers
WHERE trigger_name = 'trg1';
diff --git a/mysql-test/suite/funcs_1/r/is_user_privileges.result b/mysql-test/suite/funcs_1/r/is_user_privileges.result
index a300a1f73e7..cb619831baa 100644
--- a/mysql-test/suite/funcs_1/r/is_user_privileges.result
+++ b/mysql-test/suite/funcs_1/r/is_user_privileges.result
@@ -119,6 +119,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -165,6 +166,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -211,6 +213,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -281,6 +284,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -327,6 +331,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -373,6 +378,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -429,6 +435,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -475,6 +482,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -521,6 +529,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -599,6 +608,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -645,6 +655,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -691,6 +702,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -761,6 +773,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -807,6 +820,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -853,6 +867,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -909,6 +924,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -955,6 +971,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1001,6 +1018,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1109,6 +1127,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1155,6 +1174,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1201,6 +1221,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1304,6 +1325,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1350,6 +1372,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1396,6 +1419,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1452,6 +1476,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1498,6 +1523,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1544,6 +1570,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1607,6 +1634,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1653,6 +1681,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1699,6 +1728,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1777,6 +1807,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1823,6 +1854,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
@@ -1869,6 +1901,7 @@ Create_user_priv N
Event_priv N
Trigger_priv N
Create_tablespace_priv N
+Delete_history_priv N
ssl_type
ssl_cipher
x509_issuer
diff --git a/mysql-test/suite/funcs_1/r/memory_trig_03.result b/mysql-test/suite/funcs_1/r/memory_trig_03.result
index 8fd3e034735..b86315a1a7d 100644
--- a/mysql-test/suite/funcs_1/r/memory_trig_03.result
+++ b/mysql-test/suite/funcs_1/r/memory_trig_03.result
@@ -78,7 +78,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke TRIGGER on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -168,7 +168,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke UPDATE on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -183,7 +183,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
select f1 from t1 order by f1;
f1
insert 3.5.3.2-no
@@ -248,7 +248,7 @@ connection no_privs_424b;
show grants;
Grants for test_noprivs@localhost
GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4b_1 before UPDATE on t1 for each row
set new.f1 = 'trig 3.5.3.7-1b';
@@ -329,7 +329,7 @@ connection no_privs_424c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4c_1 before INSERT on t1 for each row
set new.f1 = 'trig 3.5.3.7-1c';
@@ -441,7 +441,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke SELECT on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, SELECT on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -457,7 +457,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
create trigger trg5a_1 before INSERT on t1 for each row
set @test_var = new.f1;
connection default;
@@ -503,7 +503,7 @@ revoke SELECT on priv_db.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.* to test_yesprivs@localhost;
@@ -518,7 +518,7 @@ connection no_privs_425b;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5b_1 before UPDATE on t1 for each row
set @test_var= new.f1;
@@ -565,7 +565,7 @@ revoke SELECT on priv_db.t1 from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -580,7 +580,7 @@ connection no_privs_425c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5c_1 before INSERT on t1 for each row
set @test_var= new.f1;
diff --git a/mysql-test/suite/funcs_1/r/memory_trig_03e.result b/mysql-test/suite/funcs_1/r/memory_trig_03e.result
index 83c36c6294f..ea0aaf0c86f 100644
--- a/mysql-test/suite/funcs_1/r/memory_trig_03e.result
+++ b/mysql-test/suite/funcs_1/r/memory_trig_03e.result
@@ -604,7 +604,7 @@ trig 1_1-yes
revoke TRIGGER on *.* from test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
disconnect yes_privs;
connect yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK;
select current_user;
@@ -657,7 +657,7 @@ root@localhost
grant TRIGGER on priv_db.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
GRANT TRIGGER ON `priv_db`.* TO 'test_yesprivs'@'localhost'
trigger privilege on db level for create:
@@ -930,7 +930,7 @@ grant TRIGGER on priv1_db.t1 to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
GRANT USAGE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, DELETE VERSIONING ROWS ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
GRANT SELECT, UPDATE ON `priv2_db`.* TO 'test_yesprivs'@'localhost'
GRANT TRIGGER ON `priv1_db`.`t1` TO 'test_yesprivs'@'localhost'
diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result
index a2af9082c72..5ac5c838fb5 100644
--- a/mysql-test/suite/funcs_1/r/memory_views.result
+++ b/mysql-test/suite/funcs_1/r/memory_views.result
@@ -3552,11 +3552,11 @@ CREATE VIEW v1 or REPLACE AS Select * from tb2 my_table;
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 'or REPLACE AS Select * from tb2 my_table' at line 1
CREATE VIEW v1 WITH CASCADED CHECK OPTION AS Select *
from tb2 my_table limit 50;
-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 'CASCADED CHECK OPTION AS Select *
+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 'WITH CASCADED CHECK OPTION AS Select *
from tb2 my_table limit 50' at line 1
CREATE VIEW v1 WITH LOCAL CHECK OPTION AS Select *
from tb2 my_table limit 50;
-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 'LOCAL CHECK OPTION AS Select *
+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 'WITH LOCAL CHECK OPTION AS Select *
from tb2 my_table limit 50' at line 1
SELECT * FROM tb2 my_table CREATE VIEW As v1;
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 'CREATE VIEW As v1' at line 1
@@ -3586,7 +3586,7 @@ FROM test.tb2 my_table CHECK OPTION WITH CASCADED;
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 'CHECK OPTION WITH CASCADED' at line 2
CREATE OR REPLACE VIEW v1 WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table;
-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 'CASCADED CHECK OPTION
+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 'WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table' at line 1
CREATE OR REPLACE AS SELECT F59, F60
FROM test.tb2 my_table VIEW v1 WITH CASCADED CHECK OPTION;
@@ -3615,7 +3615,7 @@ FROM test.tb2 my_table CHECK OPTION WITH LOCAL;
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 'CHECK OPTION WITH LOCAL' at line 2
CREATE OR REPLACE VIEW v1 WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table;
-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 'CASCADED CHECK OPTION
+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 'WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table' at line 1
CREATE OR REPLACE AS SELECT F59, F60
FROM test.tb2 my_table VIEW v1 WITH LOCAL CHECK OPTION;
@@ -4315,7 +4315,7 @@ CREATE VIEW v2 AS Select * from test.v1;
ERROR 42S02: Table 'test.v1' doesn't exist
DROP VIEW IF EXISTS v2;
Warnings:
-Note 4090 Unknown VIEW: 'test.v2'
+Note 4092 Unknown VIEW: 'test.v2'
Testcase 3.3.1.25
--------------------------------------------------------------------------------
@@ -7567,7 +7567,7 @@ Call sp1() ;
ERROR 42000: PROCEDURE test.sp1 does not exist
Drop view if exists test.v1 ;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
Drop procedure sp1 ;
ERROR 42000: PROCEDURE test.sp1 does not exist
@@ -21314,7 +21314,7 @@ CREATE VIEW v1 AS SELECT f1 FROM t1;
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v1;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
Testcase 3.3.1.68
--------------------------------------------------------------------------------
@@ -21367,7 +21367,7 @@ ERROR 42S02: Table 'test.v1' doesn't exist
SHOW CREATE TABLE v1 ;
ERROR 42S02: Table 'test.v1' doesn't exist
SHOW TABLE STATUS like 'v1' ;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
SHOW TABLES LIKE 'v1';
Tables_in_test (v1)
SHOW COLUMNS FROM v1;
diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_03.result b/mysql-test/suite/funcs_1/r/myisam_trig_03.result
index 8fd3e034735..b86315a1a7d 100644
--- a/mysql-test/suite/funcs_1/r/myisam_trig_03.result
+++ b/mysql-test/suite/funcs_1/r/myisam_trig_03.result
@@ -78,7 +78,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke TRIGGER on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -168,7 +168,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke UPDATE on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -183,7 +183,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
select f1 from t1 order by f1;
f1
insert 3.5.3.2-no
@@ -248,7 +248,7 @@ connection no_privs_424b;
show grants;
Grants for test_noprivs@localhost
GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4b_1 before UPDATE on t1 for each row
set new.f1 = 'trig 3.5.3.7-1b';
@@ -329,7 +329,7 @@ connection no_privs_424c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg4c_1 before INSERT on t1 for each row
set new.f1 = 'trig 3.5.3.7-1c';
@@ -441,7 +441,7 @@ grant ALL on *.* to test_noprivs@localhost;
revoke SELECT on *.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER, SELECT on *.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
@@ -457,7 +457,7 @@ test_noprivs@localhost
use priv_db;
show grants;
Grants for test_noprivs@localhost
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
create trigger trg5a_1 before INSERT on t1 for each row
set @test_var = new.f1;
connection default;
@@ -503,7 +503,7 @@ revoke SELECT on priv_db.* from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.* to test_yesprivs@localhost;
@@ -518,7 +518,7 @@ connection no_privs_425b;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `priv_db`.* TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.* TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5b_1 before UPDATE on t1 for each row
set @test_var= new.f1;
@@ -565,7 +565,7 @@ revoke SELECT on priv_db.t1 from test_noprivs@localhost;
show grants for test_noprivs@localhost;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost;
grant TRIGGER on *.* to test_yesprivs@localhost;
grant SELECT on priv_db.t1 to test_yesprivs@localhost;
@@ -580,7 +580,7 @@ connection no_privs_425c;
show grants;
Grants for test_noprivs@localhost
GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
+GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER, DELETE VERSIONING ROWS ON `priv_db`.`t1` TO 'test_noprivs'@'localhost'
use priv_db;
create trigger trg5c_1 before INSERT on t1 for each row
set @test_var= new.f1;
diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result
index a4db9050c86..60e6031f0e2 100644
--- a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result
+++ b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result
@@ -604,7 +604,7 @@ trig 1_1-yes
revoke TRIGGER on *.* from test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
disconnect yes_privs;
connect yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK;
select current_user;
@@ -657,7 +657,7 @@ root@localhost
grant TRIGGER on priv_db.* to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE, DELETE VERSIONING ROWS ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
GRANT TRIGGER ON `priv_db`.* TO 'test_yesprivs'@'localhost'
trigger privilege on db level for create:
@@ -930,7 +930,7 @@ grant TRIGGER on priv1_db.t1 to test_yesprivs@localhost;
show grants for test_yesprivs@localhost;
Grants for test_yesprivs@localhost
GRANT USAGE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, DELETE VERSIONING ROWS ON `priv1_db`.* TO 'test_yesprivs'@'localhost'
GRANT SELECT, UPDATE ON `priv2_db`.* TO 'test_yesprivs'@'localhost'
GRANT TRIGGER ON `priv1_db`.`t1` TO 'test_yesprivs'@'localhost'
diff --git a/mysql-test/suite/funcs_1/r/myisam_views-big.result b/mysql-test/suite/funcs_1/r/myisam_views-big.result
index 3290b3dd36a..5021cbd5324 100644
--- a/mysql-test/suite/funcs_1/r/myisam_views-big.result
+++ b/mysql-test/suite/funcs_1/r/myisam_views-big.result
@@ -4054,11 +4054,11 @@ CREATE VIEW v1 or REPLACE AS Select * from tb2 my_table;
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 'or REPLACE AS Select * from tb2 my_table' at line 1
CREATE VIEW v1 WITH CASCADED CHECK OPTION AS Select *
from tb2 my_table limit 50;
-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 'CASCADED CHECK OPTION AS Select *
+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 'WITH CASCADED CHECK OPTION AS Select *
from tb2 my_table limit 50' at line 1
CREATE VIEW v1 WITH LOCAL CHECK OPTION AS Select *
from tb2 my_table limit 50;
-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 'LOCAL CHECK OPTION AS Select *
+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 'WITH LOCAL CHECK OPTION AS Select *
from tb2 my_table limit 50' at line 1
SELECT * FROM tb2 my_table CREATE VIEW As v1;
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 'CREATE VIEW As v1' at line 1
@@ -4088,7 +4088,7 @@ FROM test.tb2 my_table CHECK OPTION WITH CASCADED;
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 'CHECK OPTION WITH CASCADED' at line 2
CREATE OR REPLACE VIEW v1 WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table;
-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 'CASCADED CHECK OPTION
+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 'WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table' at line 1
CREATE OR REPLACE AS SELECT F59, F60
FROM test.tb2 my_table VIEW v1 WITH CASCADED CHECK OPTION;
@@ -4117,7 +4117,7 @@ FROM test.tb2 my_table CHECK OPTION WITH LOCAL;
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 'CHECK OPTION WITH LOCAL' at line 2
CREATE OR REPLACE VIEW v1 WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table;
-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 'CASCADED CHECK OPTION
+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 'WITH CASCADED CHECK OPTION
AS SELECT F59, F60 FROM test.tb2 my_table' at line 1
CREATE OR REPLACE AS SELECT F59, F60
FROM test.tb2 my_table VIEW v1 WITH LOCAL CHECK OPTION;
@@ -4784,7 +4784,7 @@ CREATE VIEW v2 AS Select * from test.v1;
ERROR 42S02: Table 'test.v1' doesn't exist
DROP VIEW IF EXISTS v2;
Warnings:
-Note 4090 Unknown VIEW: 'test.v2'
+Note 4092 Unknown VIEW: 'test.v2'
Testcase 3.3.1.25
--------------------------------------------------------------------------------
@@ -8387,7 +8387,7 @@ Call sp1() ;
ERROR 42000: PROCEDURE test.sp1 does not exist
Drop view if exists test.v1 ;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
Drop procedure sp1 ;
ERROR 42000: PROCEDURE test.sp1 does not exist
@@ -22989,7 +22989,7 @@ CREATE VIEW v1 AS SELECT f1 FROM t1;
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v1;
Warnings:
-Note 4090 Unknown VIEW: 'test.v1'
+Note 4092 Unknown VIEW: 'test.v1'
Testcase 3.3.1.68
--------------------------------------------------------------------------------
@@ -23042,7 +23042,7 @@ ERROR 42S02: Table 'test.v1' doesn't exist
SHOW CREATE TABLE v1 ;
ERROR 42S02: Table 'test.v1' doesn't exist
SHOW TABLE STATUS like 'v1' ;
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
SHOW TABLES LIKE 'v1';
Tables_in_test (v1)
SHOW COLUMNS FROM v1;
diff --git a/mysql-test/suite/funcs_1/r/storedproc.result b/mysql-test/suite/funcs_1/r/storedproc.result
index b36f995d32f..e5e009a86de 100644
--- a/mysql-test/suite/funcs_1/r/storedproc.result
+++ b/mysql-test/suite/funcs_1/r/storedproc.result
@@ -1771,48 +1771,48 @@ Testcase 4.1.9:
drop procedure
--------------------------------------------------------------------------------
SELECT * from mysql.proc where specific_name='sp9';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
DROP PROCEDURE IF EXISTS sp9;
SELECT * from mysql.proc where specific_name='sp9';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
CREATE PROCEDURE sp9()SELECT * from t1;
SELECT * from mysql.proc where specific_name='sp9';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
-db_storedproc sp9 PROCEDURE sp9 SQL CONTAINS_SQL NO DEFINER SELECT * from t1 root@localhost created modified latin1 latin1_swedish_ci latin1_swedish_ci SELECT * from t1
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
+db_storedproc sp9 PROCEDURE sp9 SQL CONTAINS_SQL NO DEFINER SELECT * from t1 root@localhost created modified latin1 latin1_swedish_ci latin1_swedish_ci SELECT * from t1 NONE
DROP PROCEDURE sp9;
SELECT * from mysql.proc where specific_name='sp9';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
CREATE PROCEDURE sp9()SELECT * from t1;
SELECT * from mysql.proc where specific_name='sp9';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
-db_storedproc sp9 PROCEDURE sp9 SQL CONTAINS_SQL NO DEFINER SELECT * from t1 root@localhost created modified latin1 latin1_swedish_ci latin1_swedish_ci SELECT * from t1
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
+db_storedproc sp9 PROCEDURE sp9 SQL CONTAINS_SQL NO DEFINER SELECT * from t1 root@localhost created modified latin1 latin1_swedish_ci latin1_swedish_ci SELECT * from t1 NONE
DROP PROCEDURE IF EXISTS sp9;
SELECT * from mysql.proc where specific_name='sp9';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
Testcase 4.1.10:
----------------
DROP FUNCTION
--------------------------------------------------------------------------------
SELECT * from mysql.proc where specific_name='fn10' and type='function';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
DROP FUNCTION IF EXISTS fn10;
SELECT * from mysql.proc where specific_name='fn10' and type='function';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
CREATE FUNCTION fn10() returns int return 100;
SELECT * from mysql.proc where specific_name='fn10' and type='function';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
-db_storedproc fn10 FUNCTION fn10 SQL CONTAINS_SQL NO DEFINER int(11) return 100 root@localhost created modified latin1 latin1_swedish_ci latin1_swedish_ci return 100
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
+db_storedproc fn10 FUNCTION fn10 SQL CONTAINS_SQL NO DEFINER int(11) return 100 root@localhost created modified latin1 latin1_swedish_ci latin1_swedish_ci return 100 NONE
DROP FUNCTION fn10;
SELECT * from mysql.proc where specific_name='fn10' and type='function';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
CREATE FUNCTION fn10() returns int return 100;
SELECT * from mysql.proc where specific_name='fn10' and type='function';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
-db_storedproc fn10 FUNCTION fn10 SQL CONTAINS_SQL NO DEFINER int(11) return 100 root@localhost created modified latin1 latin1_swedish_ci latin1_swedish_ci return 100
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
+db_storedproc fn10 FUNCTION fn10 SQL CONTAINS_SQL NO DEFINER int(11) return 100 root@localhost created modified latin1 latin1_swedish_ci latin1_swedish_ci return 100 NONE
DROP FUNCTION IF EXISTS fn10;
SELECT * from mysql.proc where specific_name='fn10' and type='function';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
Testcase 4.1.11:
----------------
@@ -2775,7 +2775,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
SELECT * from t1 where f2=f1' at line 1
CREATE PROCEDURE values()
SELECT * from t1 where f2=f1;
-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 '()
+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 'values()
SELECT * from t1 where f2=f1' at line 1
CREATE PROCEDURE varbinary()
SELECT * from t1 where f2=f1;
@@ -2807,7 +2807,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
SELECT * from t1 where f2=f1' at line 1
CREATE PROCEDURE with()
SELECT * from t1 where f2=f1;
-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 '()
+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 'with()
SELECT * from t1 where f2=f1' at line 1
CREATE PROCEDURE write()
SELECT * from t1 where f2=f1;
@@ -4477,7 +4477,7 @@ CREATE PROCEDURE sp1()
for:BEGIN
SELECT @x;
END//
-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 'for:BEGIN
+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 ':BEGIN
SELECT @x;
END' at line 2
DROP PROCEDURE IF EXISTS sp1;
@@ -9150,7 +9150,7 @@ CREATE PROCEDURE sp1()
BEGIN
declare values char;
END//
-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 'char;
+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 'values char;
END' at line 3
DROP PROCEDURE IF EXISTS sp1;
Warnings:
@@ -9222,7 +9222,7 @@ CREATE PROCEDURE sp1()
BEGIN
declare with char;
END//
-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 'char;
+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 'with char;
END' at line 3
DROP PROCEDURE IF EXISTS sp1;
Warnings:
@@ -11494,9 +11494,8 @@ BEGIN
declare values condition for sqlstate '02000';
declare exit handler for values set @var2 = 1;
END//
-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 'condition for sqlstate '02000';
-declare exit handler for values set @var2 = 1;
-E' at line 3
+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 'values condition for sqlstate '02000';
+declare exit handler for values set @var2' at line 3
DROP PROCEDURE IF EXISTS sp1;
Warnings:
Note 1305 PROCEDURE db_storedproc.sp1 does not exist
@@ -11575,9 +11574,8 @@ BEGIN
declare with condition for sqlstate '02000';
declare exit handler for with set @var2 = 1;
END//
-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 'condition for sqlstate '02000';
-declare exit handler for with set @var2 = 1;
-END' at line 3
+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 'with condition for sqlstate '02000';
+declare exit handler for with set @var2 = 1' at line 3
DROP PROCEDURE IF EXISTS sp1;
Warnings:
Note 1305 PROCEDURE db_storedproc.sp1 does not exist
@@ -13609,7 +13607,7 @@ CREATE PROCEDURE sp1( )
BEGIN
declare values handler for sqlstate '02000' set @var2 = 1;
END//
-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 'handler for sqlstate '02000' set @var2 = 1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'values handler for sqlstate '02000' set @var2 = 1;
END' at line 3
DROP PROCEDURE IF EXISTS sp1;
Warnings:
@@ -13681,7 +13679,7 @@ CREATE PROCEDURE sp1( )
BEGIN
declare with handler for sqlstate '02000' set @var2 = 1;
END//
-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 'handler for sqlstate '02000' set @var2 = 1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'with handler for sqlstate '02000' set @var2 = 1;
END' at line 3
DROP PROCEDURE IF EXISTS sp1;
Warnings:
@@ -16172,15 +16170,15 @@ insert into t43 values('abcde', 'a!@#$%^&*(');
CREATE PROCEDURE d1.sp4()
SELECT * from d1.t43;
SELECT * from mysql.proc where specific_name = 'sp4';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
-d1 sp4 PROCEDURE sp4 SQL CONTAINS_SQL NO DEFINER SELECT * from d1.t43 root@localhost modified created latin1 latin1_swedish_ci latin1_swedish_ci SELECT * from d1.t43
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
+d1 sp4 PROCEDURE sp4 SQL CONTAINS_SQL NO DEFINER SELECT * from d1.t43 root@localhost modified created latin1 latin1_swedish_ci latin1_swedish_ci SELECT * from d1.t43 NONE
USE db_storedproc;
DROP DATABASE d1;
CREATE DATABASE d1;
USE d1;
create table t44(a char(5), b char(10));
SELECT * from mysql.proc where specific_name = 'sp4';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
USE db_storedproc;
DROP DATABASE d1;
@@ -16222,8 +16220,8 @@ CREATE PROCEDURE sp8 ( n char(20) ) sql security DEFINER comment 'initial'
USE d2;
alter procedure d1.sp8 sql security DEFINER comment 'updated';
SELECT * from mysql.proc where specific_name='sp8' and db='d1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
-d1 sp8 PROCEDURE sp8 SQL CONTAINS_SQL NO DEFINER n char(20) SELECT * from t1 where t1.f1 = n root@localhost modified created updated latin1 latin1_swedish_ci latin1_swedish_ci SELECT * from t1 where t1.f1 = n
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
+d1 sp8 PROCEDURE sp8 SQL CONTAINS_SQL NO DEFINER n char(20) SELECT * from t1 where t1.f1 = n root@localhost modified created updated latin1 latin1_swedish_ci latin1_swedish_ci SELECT * from t1 where t1.f1 = n NONE
Testcase 4.4.9:
--------------------------------------------------------------------------------
@@ -16239,7 +16237,7 @@ END//
USE d2;
alter function d1.fn2 sql security DEFINER comment 'updated';
SELECT * from mysql.proc where specific_name='fn2' and db='d1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
d1 fn2 FUNCTION fn2 SQL CONTAINS_SQL NO DEFINER n int int(11) BEGIN
declare a int;
set a = 0.9 * n;
@@ -16248,7 +16246,7 @@ END root@localhost modified created updated latin1 latin1_swedish_ci latin1_swe
declare a int;
set a = 0.9 * n;
return a;
-END
+END NONE
Testcase 4.4.10:
--------------------------------------------------------------------------------
@@ -16258,7 +16256,7 @@ SELECT * from t1 where t1.f1 = n;
USE d2;
DROP PROCEDURE d1.sp9;
SELECT * from mysql.proc where specific_name='sp9' and db='d1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
Testcase 4.4.11:
--------------------------------------------------------------------------------
@@ -16272,7 +16270,7 @@ END//
USE d2;
DROP FUNCTION d1.fn3;
SELECT * from mysql.proc where specific_name='fn3' and db='d1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
USE db_storedproc;
DROP DATABASE d1;
DROP DATABASE d2;
diff --git a/mysql-test/suite/funcs_2/include/check_charset.inc b/mysql-test/suite/funcs_2/include/check_charset.inc
index bf2f2db610b..a6f827e14cc 100644
--- a/mysql-test/suite/funcs_2/include/check_charset.inc
+++ b/mysql-test/suite/funcs_2/include/check_charset.inc
@@ -17,7 +17,7 @@ if ($std_cset)
eval CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET $cset COLLATE $coll) ENGINE=$engine_type CHARACTER SET $cset COLLATE $coll;
}
---replace_column 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 11 # 12 # 13 # 14 # 16 # 17 # 18 #
+--replace_column 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 11 # 12 # 13 # 14 # 16 # 17 # 18 # 19 #
SHOW TABLE STATUS LIKE 't1';
--disable_warnings
diff --git a/mysql-test/suite/funcs_2/r/innodb_charset.result b/mysql-test/suite/funcs_2/r/innodb_charset.result
index 60785d09430..814adbcd112 100644
--- a/mysql-test/suite/funcs_2/r/innodb_charset.result
+++ b/mysql-test/suite/funcs_2/r/innodb_charset.result
@@ -2,8 +2,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES armscii8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET armscii8 COLLATE armscii8_bin) ENGINE=InnoDB CHARACTER SET armscii8 COLLATE armscii8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # armscii8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # armscii8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -232,8 +232,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES armscii8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET armscii8 COLLATE armscii8_general_ci) ENGINE=InnoDB CHARACTER SET armscii8 COLLATE armscii8_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # armscii8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # armscii8_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -462,8 +462,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ascii;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ascii COLLATE ascii_bin) ENGINE=InnoDB CHARACTER SET ascii COLLATE ascii_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # ascii_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # ascii_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -692,8 +692,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ascii;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ascii COLLATE ascii_general_ci) ENGINE=InnoDB CHARACTER SET ascii COLLATE ascii_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # ascii_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # ascii_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -922,8 +922,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES big5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET big5 COLLATE big5_bin) ENGINE=InnoDB CHARACTER SET big5 COLLATE big5_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # big5_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # big5_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1026,8 +1026,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES big5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET big5 COLLATE big5_chinese_ci) ENGINE=InnoDB CHARACTER SET big5 COLLATE big5_chinese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # big5_chinese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # big5_chinese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1130,8 +1130,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES binary;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET binary) ENGINE=InnoDB CHARACTER SET binary;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # binary # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # binary # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1360,8 +1360,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_bin) ENGINE=InnoDB CHARACTER SET cp1250 COLLATE cp1250_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1250_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1250_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1590,8 +1590,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_croatian_ci) ENGINE=InnoDB CHARACTER SET cp1250 COLLATE cp1250_croatian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1250_croatian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1250_croatian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1820,8 +1820,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_czech_cs) ENGINE=InnoDB CHARACTER SET cp1250 COLLATE cp1250_czech_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1250_czech_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1250_czech_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -2050,8 +2050,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_general_ci) ENGINE=InnoDB CHARACTER SET cp1250 COLLATE cp1250_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1250_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1250_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
A0 1
@@ -2280,8 +2280,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_bin) ENGINE=InnoDB CHARACTER SET cp1251 COLLATE cp1251_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1251_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1251_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -2510,8 +2510,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_bulgarian_ci) ENGINE=InnoDB CHARACTER SET cp1251 COLLATE cp1251_bulgarian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1251_bulgarian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1251_bulgarian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -2740,8 +2740,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_general_ci) ENGINE=InnoDB CHARACTER SET cp1251 COLLATE cp1251_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1251_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1251_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -2970,8 +2970,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_general_cs) ENGINE=InnoDB CHARACTER SET cp1251 COLLATE cp1251_general_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1251_general_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1251_general_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -3200,8 +3200,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_ukrainian_ci) ENGINE=InnoDB CHARACTER SET cp1251 COLLATE cp1251_ukrainian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1251_ukrainian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1251_ukrainian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
60 1
@@ -3430,8 +3430,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1256;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1256 COLLATE cp1256_bin) ENGINE=InnoDB CHARACTER SET cp1256 COLLATE cp1256_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1256_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1256_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -3660,8 +3660,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1256;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1256 COLLATE cp1256_general_ci) ENGINE=InnoDB CHARACTER SET cp1256 COLLATE cp1256_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1256_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1256_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -3890,8 +3890,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1257;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1257 COLLATE cp1257_bin) ENGINE=InnoDB CHARACTER SET cp1257 COLLATE cp1257_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1257_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1257_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4120,8 +4120,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1257;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1257 COLLATE cp1257_general_ci) ENGINE=InnoDB CHARACTER SET cp1257 COLLATE cp1257_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1257_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1257_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4350,8 +4350,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1257;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1257 COLLATE cp1257_lithuanian_ci) ENGINE=InnoDB CHARACTER SET cp1257 COLLATE cp1257_lithuanian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp1257_lithuanian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp1257_lithuanian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4580,8 +4580,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp850;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp850 COLLATE cp850_bin) ENGINE=InnoDB CHARACTER SET cp850 COLLATE cp850_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp850_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp850_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4810,8 +4810,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp850;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp850 COLLATE cp850_general_ci) ENGINE=InnoDB CHARACTER SET cp850 COLLATE cp850_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp850_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp850_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5040,8 +5040,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp852;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp852 COLLATE cp852_bin) ENGINE=InnoDB CHARACTER SET cp852 COLLATE cp852_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp852_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp852_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5270,8 +5270,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp852;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp852 COLLATE cp852_general_ci) ENGINE=InnoDB CHARACTER SET cp852 COLLATE cp852_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp852_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp852_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5500,8 +5500,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp866;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp866 COLLATE cp866_bin) ENGINE=InnoDB CHARACTER SET cp866 COLLATE cp866_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp866_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp866_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5730,8 +5730,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp866;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp866 COLLATE cp866_general_ci) ENGINE=InnoDB CHARACTER SET cp866 COLLATE cp866_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp866_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp866_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5960,8 +5960,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp932;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp932 COLLATE cp932_bin) ENGINE=InnoDB CHARACTER SET cp932 COLLATE cp932_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp932_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp932_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6127,8 +6127,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp932;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp932 COLLATE cp932_japanese_ci) ENGINE=InnoDB CHARACTER SET cp932 COLLATE cp932_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # cp932_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # cp932_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6294,8 +6294,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES dec8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET dec8 COLLATE dec8_bin) ENGINE=InnoDB CHARACTER SET dec8 COLLATE dec8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # dec8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # dec8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6524,8 +6524,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES dec8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET dec8 COLLATE dec8_swedish_ci) ENGINE=InnoDB CHARACTER SET dec8 COLLATE dec8_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # dec8_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # dec8_swedish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6754,8 +6754,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES eucjpms;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET eucjpms COLLATE eucjpms_bin) ENGINE=InnoDB CHARACTER SET eucjpms COLLATE eucjpms_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # eucjpms_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # eucjpms_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6858,8 +6858,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES eucjpms;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET eucjpms COLLATE eucjpms_japanese_ci) ENGINE=InnoDB CHARACTER SET eucjpms COLLATE eucjpms_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # eucjpms_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # eucjpms_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6962,8 +6962,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES euckr;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET euckr COLLATE euckr_bin) ENGINE=InnoDB CHARACTER SET euckr COLLATE euckr_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # euckr_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # euckr_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7066,8 +7066,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES euckr;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET euckr COLLATE euckr_korean_ci) ENGINE=InnoDB CHARACTER SET euckr COLLATE euckr_korean_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # euckr_korean_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # euckr_korean_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7170,8 +7170,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gb2312;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gb2312 COLLATE gb2312_bin) ENGINE=InnoDB CHARACTER SET gb2312 COLLATE gb2312_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # gb2312_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # gb2312_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7274,8 +7274,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gb2312;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gb2312 COLLATE gb2312_chinese_ci) ENGINE=InnoDB CHARACTER SET gb2312 COLLATE gb2312_chinese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # gb2312_chinese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # gb2312_chinese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7378,8 +7378,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gbk;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gbk COLLATE gbk_bin) ENGINE=InnoDB CHARACTER SET gbk COLLATE gbk_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # gbk_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # gbk_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7482,8 +7482,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gbk;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gbk COLLATE gbk_chinese_ci) ENGINE=InnoDB CHARACTER SET gbk COLLATE gbk_chinese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # gbk_chinese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # gbk_chinese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7586,8 +7586,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES geostd8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET geostd8 COLLATE geostd8_bin) ENGINE=InnoDB CHARACTER SET geostd8 COLLATE geostd8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # geostd8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # geostd8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7816,8 +7816,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES geostd8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET geostd8 COLLATE geostd8_general_ci) ENGINE=InnoDB CHARACTER SET geostd8 COLLATE geostd8_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # geostd8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # geostd8_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8046,8 +8046,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES greek;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET greek COLLATE greek_bin) ENGINE=InnoDB CHARACTER SET greek COLLATE greek_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # greek_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # greek_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8276,8 +8276,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES greek;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET greek COLLATE greek_general_ci) ENGINE=InnoDB CHARACTER SET greek COLLATE greek_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # greek_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # greek_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8506,8 +8506,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hebrew;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hebrew COLLATE hebrew_bin) ENGINE=InnoDB CHARACTER SET hebrew COLLATE hebrew_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # hebrew_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # hebrew_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8736,8 +8736,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hebrew;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hebrew COLLATE hebrew_general_ci) ENGINE=InnoDB CHARACTER SET hebrew COLLATE hebrew_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # hebrew_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # hebrew_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8966,8 +8966,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hp8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hp8 COLLATE hp8_bin) ENGINE=InnoDB CHARACTER SET hp8 COLLATE hp8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # hp8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # hp8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9196,8 +9196,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hp8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hp8 COLLATE hp8_english_ci) ENGINE=InnoDB CHARACTER SET hp8 COLLATE hp8_english_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # hp8_english_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # hp8_english_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9426,8 +9426,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES keybcs2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET keybcs2 COLLATE keybcs2_bin) ENGINE=InnoDB CHARACTER SET keybcs2 COLLATE keybcs2_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # keybcs2_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # keybcs2_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9656,8 +9656,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES keybcs2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET keybcs2 COLLATE keybcs2_general_ci) ENGINE=InnoDB CHARACTER SET keybcs2 COLLATE keybcs2_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # keybcs2_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # keybcs2_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9886,8 +9886,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8r;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8r COLLATE koi8r_bin) ENGINE=InnoDB CHARACTER SET koi8r COLLATE koi8r_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # koi8r_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # koi8r_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -10116,8 +10116,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8r;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8r COLLATE koi8r_general_ci) ENGINE=InnoDB CHARACTER SET koi8r COLLATE koi8r_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # koi8r_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # koi8r_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -10346,8 +10346,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8u;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8u COLLATE koi8u_bin) ENGINE=InnoDB CHARACTER SET koi8u COLLATE koi8u_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # koi8u_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # koi8u_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -10576,8 +10576,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8u;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8u COLLATE koi8u_general_ci) ENGINE=InnoDB CHARACTER SET koi8u COLLATE koi8u_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # koi8u_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # koi8u_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
60 1
@@ -10806,8 +10806,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_bin) ENGINE=InnoDB CHARACTER SET latin1 COLLATE latin1_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin1_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin1_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11036,8 +11036,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_danish_ci) ENGINE=InnoDB CHARACTER SET latin1 COLLATE latin1_danish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin1_danish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin1_danish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11266,8 +11266,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_general_ci) ENGINE=InnoDB CHARACTER SET latin1 COLLATE latin1_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin1_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin1_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11496,8 +11496,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_general_cs) ENGINE=InnoDB CHARACTER SET latin1 COLLATE latin1_general_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin1_general_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin1_general_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11726,8 +11726,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_german1_ci) ENGINE=InnoDB CHARACTER SET latin1 COLLATE latin1_german1_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin1_german1_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin1_german1_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11956,8 +11956,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_german2_ci) ENGINE=InnoDB CHARACTER SET latin1 COLLATE latin1_german2_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin1_german2_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin1_german2_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12186,8 +12186,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_spanish_ci) ENGINE=InnoDB CHARACTER SET latin1 COLLATE latin1_spanish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin1_spanish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin1_spanish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12416,8 +12416,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_swedish_ci) ENGINE=InnoDB CHARACTER SET latin1 COLLATE latin1_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin1_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin1_swedish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12646,8 +12646,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_bin) ENGINE=InnoDB CHARACTER SET latin2 COLLATE latin2_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin2_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin2_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12876,8 +12876,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_croatian_ci) ENGINE=InnoDB CHARACTER SET latin2 COLLATE latin2_croatian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin2_croatian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin2_croatian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -13106,8 +13106,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_czech_cs) ENGINE=InnoDB CHARACTER SET latin2 COLLATE latin2_czech_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin2_czech_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin2_czech_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
2E 1
@@ -13336,8 +13336,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_general_ci) ENGINE=InnoDB CHARACTER SET latin2 COLLATE latin2_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin2_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin2_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -13566,8 +13566,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_hungarian_ci) ENGINE=InnoDB CHARACTER SET latin2 COLLATE latin2_hungarian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin2_hungarian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin2_hungarian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -13796,8 +13796,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin5 COLLATE latin5_bin) ENGINE=InnoDB CHARACTER SET latin5 COLLATE latin5_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin5_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin5_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -14026,8 +14026,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin5 COLLATE latin5_turkish_ci) ENGINE=InnoDB CHARACTER SET latin5 COLLATE latin5_turkish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin5_turkish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin5_turkish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -14256,8 +14256,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_bin) ENGINE=InnoDB CHARACTER SET latin7 COLLATE latin7_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin7_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin7_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -14486,8 +14486,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_estonian_cs) ENGINE=InnoDB CHARACTER SET latin7 COLLATE latin7_estonian_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin7_estonian_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin7_estonian_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
80 1
@@ -14716,8 +14716,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_general_ci) ENGINE=InnoDB CHARACTER SET latin7 COLLATE latin7_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin7_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin7_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -14946,8 +14946,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_general_cs) ENGINE=InnoDB CHARACTER SET latin7 COLLATE latin7_general_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # latin7_general_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # latin7_general_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -15176,8 +15176,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macce;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macce COLLATE macce_bin) ENGINE=InnoDB CHARACTER SET macce COLLATE macce_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # macce_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # macce_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -15406,8 +15406,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macce;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macce COLLATE macce_general_ci) ENGINE=InnoDB CHARACTER SET macce COLLATE macce_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # macce_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # macce_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -15636,8 +15636,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macroman;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macroman COLLATE macroman_bin) ENGINE=InnoDB CHARACTER SET macroman COLLATE macroman_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # macroman_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # macroman_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -15866,8 +15866,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macroman;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macroman COLLATE macroman_general_ci) ENGINE=InnoDB CHARACTER SET macroman COLLATE macroman_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # macroman_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # macroman_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16096,8 +16096,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES sjis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET sjis COLLATE sjis_bin) ENGINE=InnoDB CHARACTER SET sjis COLLATE sjis_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # sjis_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # sjis_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16263,8 +16263,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES sjis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET sjis COLLATE sjis_japanese_ci) ENGINE=InnoDB CHARACTER SET sjis COLLATE sjis_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # sjis_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # sjis_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16430,8 +16430,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES swe7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET swe7 COLLATE swe7_bin) ENGINE=InnoDB CHARACTER SET swe7 COLLATE swe7_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # swe7_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # swe7_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16660,8 +16660,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES swe7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET swe7 COLLATE swe7_swedish_ci) ENGINE=InnoDB CHARACTER SET swe7 COLLATE swe7_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # swe7_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # swe7_swedish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16890,8 +16890,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES tis620;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET tis620 COLLATE tis620_bin) ENGINE=InnoDB CHARACTER SET tis620 COLLATE tis620_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # tis620_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # tis620_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17120,8 +17120,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES tis620;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET tis620 COLLATE tis620_thai_ci) ENGINE=InnoDB CHARACTER SET tis620 COLLATE tis620_thai_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # tis620_thai_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # tis620_thai_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17350,8 +17350,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ujis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ujis COLLATE ujis_bin) ENGINE=InnoDB CHARACTER SET ujis COLLATE ujis_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # ujis_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # ujis_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17454,8 +17454,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ujis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ujis COLLATE ujis_japanese_ci) ENGINE=InnoDB CHARACTER SET ujis COLLATE ujis_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # ujis_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # ujis_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17561,8 +17561,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_bin;
@@ -20102,8 +20102,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_czech_ci;
@@ -22643,8 +22643,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_danish_ci;
@@ -25184,8 +25184,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_estonian_ci;
@@ -27725,8 +27725,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_general_ci;
@@ -30266,8 +30266,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_hungarian_ci;
@@ -32807,8 +32807,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_icelandic_ci;
@@ -35348,8 +35348,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_latvian_ci;
@@ -37889,8 +37889,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_lithuanian_ci;
@@ -40430,8 +40430,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_persian_ci;
@@ -42971,8 +42971,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_polish_ci;
@@ -45512,8 +45512,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_roman_ci;
@@ -48053,8 +48053,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_romanian_ci;
@@ -50594,8 +50594,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovak_ci;
@@ -53135,8 +53135,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovenian_ci;
@@ -55676,8 +55676,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish2_ci;
@@ -58217,8 +58217,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish_ci;
@@ -60758,8 +60758,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_swedish_ci;
@@ -63299,8 +63299,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_turkish_ci;
@@ -65840,8 +65840,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci;
@@ -68380,8 +68380,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_bin) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_bin # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -70919,8 +70919,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_czech_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_czech_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_czech_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_czech_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -73458,8 +73458,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_danish_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_danish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_danish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_danish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -75997,8 +75997,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_estonian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_estonian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_estonian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_estonian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -78536,8 +78536,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_general_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -81075,8 +81075,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_hungarian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_hungarian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_hungarian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_hungarian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -83614,8 +83614,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_icelandic_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_icelandic_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_icelandic_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_icelandic_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -86153,8 +86153,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_latvian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_latvian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_latvian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_latvian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -88692,8 +88692,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_lithuanian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_lithuanian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_lithuanian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_lithuanian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -91231,8 +91231,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_persian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_persian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_persian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_persian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -93770,8 +93770,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_polish_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_polish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_polish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_polish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -96309,8 +96309,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_roman_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_roman_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_roman_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_roman_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -98848,8 +98848,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_romanian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_romanian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_romanian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_romanian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -101387,8 +101387,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovak_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_slovak_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_slovak_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_slovak_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -103926,8 +103926,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovenian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_slovenian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_slovenian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_slovenian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -106465,8 +106465,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish2_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_spanish2_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_spanish2_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_spanish2_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -109004,8 +109004,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_spanish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_spanish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_spanish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -111543,8 +111543,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_swedish_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_swedish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -114082,8 +114082,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_turkish_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_turkish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_turkish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_turkish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -116621,8 +116621,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 InnoDB # # # # # # # # # # # # utf8_unicode_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 InnoDB # # # # # # # # # # # # utf8_unicode_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
diff --git a/mysql-test/suite/funcs_2/r/memory_charset.result b/mysql-test/suite/funcs_2/r/memory_charset.result
index 55951e4443e..c4562d3b5df 100644
--- a/mysql-test/suite/funcs_2/r/memory_charset.result
+++ b/mysql-test/suite/funcs_2/r/memory_charset.result
@@ -2,8 +2,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES armscii8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET armscii8 COLLATE armscii8_bin) ENGINE=Memory CHARACTER SET armscii8 COLLATE armscii8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # armscii8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # armscii8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -232,8 +232,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES armscii8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET armscii8 COLLATE armscii8_general_ci) ENGINE=Memory CHARACTER SET armscii8 COLLATE armscii8_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # armscii8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # armscii8_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -462,8 +462,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ascii;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ascii COLLATE ascii_bin) ENGINE=Memory CHARACTER SET ascii COLLATE ascii_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # ascii_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # ascii_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -692,8 +692,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ascii;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ascii COLLATE ascii_general_ci) ENGINE=Memory CHARACTER SET ascii COLLATE ascii_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # ascii_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # ascii_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -922,8 +922,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES big5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET big5 COLLATE big5_bin) ENGINE=Memory CHARACTER SET big5 COLLATE big5_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # big5_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # big5_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1026,8 +1026,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES big5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET big5 COLLATE big5_chinese_ci) ENGINE=Memory CHARACTER SET big5 COLLATE big5_chinese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # big5_chinese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # big5_chinese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1130,8 +1130,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES binary;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET binary) ENGINE=Memory CHARACTER SET binary;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # binary # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # binary # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1360,8 +1360,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_bin) ENGINE=Memory CHARACTER SET cp1250 COLLATE cp1250_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1250_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1250_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1590,8 +1590,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_croatian_ci) ENGINE=Memory CHARACTER SET cp1250 COLLATE cp1250_croatian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1250_croatian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1250_croatian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1820,8 +1820,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_czech_cs) ENGINE=Memory CHARACTER SET cp1250 COLLATE cp1250_czech_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1250_czech_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1250_czech_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -2050,8 +2050,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_general_ci) ENGINE=Memory CHARACTER SET cp1250 COLLATE cp1250_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1250_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1250_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
A0 1
@@ -2280,8 +2280,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_bin) ENGINE=Memory CHARACTER SET cp1251 COLLATE cp1251_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1251_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1251_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -2510,8 +2510,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_bulgarian_ci) ENGINE=Memory CHARACTER SET cp1251 COLLATE cp1251_bulgarian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1251_bulgarian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1251_bulgarian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -2740,8 +2740,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_general_ci) ENGINE=Memory CHARACTER SET cp1251 COLLATE cp1251_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1251_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1251_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -2970,8 +2970,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_general_cs) ENGINE=Memory CHARACTER SET cp1251 COLLATE cp1251_general_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1251_general_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1251_general_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -3200,8 +3200,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_ukrainian_ci) ENGINE=Memory CHARACTER SET cp1251 COLLATE cp1251_ukrainian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1251_ukrainian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1251_ukrainian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
60 1
@@ -3430,8 +3430,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1256;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1256 COLLATE cp1256_bin) ENGINE=Memory CHARACTER SET cp1256 COLLATE cp1256_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1256_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1256_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -3660,8 +3660,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1256;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1256 COLLATE cp1256_general_ci) ENGINE=Memory CHARACTER SET cp1256 COLLATE cp1256_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1256_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1256_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -3890,8 +3890,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1257;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1257 COLLATE cp1257_bin) ENGINE=Memory CHARACTER SET cp1257 COLLATE cp1257_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1257_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1257_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4120,8 +4120,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1257;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1257 COLLATE cp1257_general_ci) ENGINE=Memory CHARACTER SET cp1257 COLLATE cp1257_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1257_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1257_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4350,8 +4350,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1257;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1257 COLLATE cp1257_lithuanian_ci) ENGINE=Memory CHARACTER SET cp1257 COLLATE cp1257_lithuanian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp1257_lithuanian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp1257_lithuanian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4580,8 +4580,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp850;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp850 COLLATE cp850_bin) ENGINE=Memory CHARACTER SET cp850 COLLATE cp850_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp850_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp850_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4810,8 +4810,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp850;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp850 COLLATE cp850_general_ci) ENGINE=Memory CHARACTER SET cp850 COLLATE cp850_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp850_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp850_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5040,8 +5040,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp852;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp852 COLLATE cp852_bin) ENGINE=Memory CHARACTER SET cp852 COLLATE cp852_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp852_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp852_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5270,8 +5270,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp852;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp852 COLLATE cp852_general_ci) ENGINE=Memory CHARACTER SET cp852 COLLATE cp852_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp852_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp852_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5500,8 +5500,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp866;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp866 COLLATE cp866_bin) ENGINE=Memory CHARACTER SET cp866 COLLATE cp866_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp866_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp866_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5730,8 +5730,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp866;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp866 COLLATE cp866_general_ci) ENGINE=Memory CHARACTER SET cp866 COLLATE cp866_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp866_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp866_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5960,8 +5960,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp932;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp932 COLLATE cp932_bin) ENGINE=Memory CHARACTER SET cp932 COLLATE cp932_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp932_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp932_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6127,8 +6127,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp932;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp932 COLLATE cp932_japanese_ci) ENGINE=Memory CHARACTER SET cp932 COLLATE cp932_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # cp932_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # cp932_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6294,8 +6294,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES dec8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET dec8 COLLATE dec8_bin) ENGINE=Memory CHARACTER SET dec8 COLLATE dec8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # dec8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # dec8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6524,8 +6524,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES dec8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET dec8 COLLATE dec8_swedish_ci) ENGINE=Memory CHARACTER SET dec8 COLLATE dec8_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # dec8_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # dec8_swedish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6754,8 +6754,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES eucjpms;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET eucjpms COLLATE eucjpms_bin) ENGINE=Memory CHARACTER SET eucjpms COLLATE eucjpms_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # eucjpms_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # eucjpms_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6858,8 +6858,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES eucjpms;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET eucjpms COLLATE eucjpms_japanese_ci) ENGINE=Memory CHARACTER SET eucjpms COLLATE eucjpms_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # eucjpms_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # eucjpms_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6962,8 +6962,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES euckr;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET euckr COLLATE euckr_bin) ENGINE=Memory CHARACTER SET euckr COLLATE euckr_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # euckr_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # euckr_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7066,8 +7066,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES euckr;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET euckr COLLATE euckr_korean_ci) ENGINE=Memory CHARACTER SET euckr COLLATE euckr_korean_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # euckr_korean_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # euckr_korean_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7170,8 +7170,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gb2312;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gb2312 COLLATE gb2312_bin) ENGINE=Memory CHARACTER SET gb2312 COLLATE gb2312_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # gb2312_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # gb2312_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7274,8 +7274,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gb2312;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gb2312 COLLATE gb2312_chinese_ci) ENGINE=Memory CHARACTER SET gb2312 COLLATE gb2312_chinese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # gb2312_chinese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # gb2312_chinese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7378,8 +7378,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gbk;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gbk COLLATE gbk_bin) ENGINE=Memory CHARACTER SET gbk COLLATE gbk_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # gbk_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # gbk_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7482,8 +7482,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gbk;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gbk COLLATE gbk_chinese_ci) ENGINE=Memory CHARACTER SET gbk COLLATE gbk_chinese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # gbk_chinese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # gbk_chinese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7586,8 +7586,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES geostd8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET geostd8 COLLATE geostd8_bin) ENGINE=Memory CHARACTER SET geostd8 COLLATE geostd8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # geostd8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # geostd8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7816,8 +7816,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES geostd8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET geostd8 COLLATE geostd8_general_ci) ENGINE=Memory CHARACTER SET geostd8 COLLATE geostd8_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # geostd8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # geostd8_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8046,8 +8046,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES greek;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET greek COLLATE greek_bin) ENGINE=Memory CHARACTER SET greek COLLATE greek_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # greek_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # greek_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8276,8 +8276,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES greek;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET greek COLLATE greek_general_ci) ENGINE=Memory CHARACTER SET greek COLLATE greek_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # greek_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # greek_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8506,8 +8506,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hebrew;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hebrew COLLATE hebrew_bin) ENGINE=Memory CHARACTER SET hebrew COLLATE hebrew_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # hebrew_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # hebrew_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8736,8 +8736,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hebrew;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hebrew COLLATE hebrew_general_ci) ENGINE=Memory CHARACTER SET hebrew COLLATE hebrew_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # hebrew_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # hebrew_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8966,8 +8966,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hp8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hp8 COLLATE hp8_bin) ENGINE=Memory CHARACTER SET hp8 COLLATE hp8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # hp8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # hp8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9196,8 +9196,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hp8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hp8 COLLATE hp8_english_ci) ENGINE=Memory CHARACTER SET hp8 COLLATE hp8_english_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # hp8_english_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # hp8_english_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9426,8 +9426,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES keybcs2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET keybcs2 COLLATE keybcs2_bin) ENGINE=Memory CHARACTER SET keybcs2 COLLATE keybcs2_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # keybcs2_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # keybcs2_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9656,8 +9656,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES keybcs2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET keybcs2 COLLATE keybcs2_general_ci) ENGINE=Memory CHARACTER SET keybcs2 COLLATE keybcs2_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # keybcs2_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # keybcs2_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9886,8 +9886,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8r;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8r COLLATE koi8r_bin) ENGINE=Memory CHARACTER SET koi8r COLLATE koi8r_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # koi8r_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # koi8r_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -10116,8 +10116,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8r;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8r COLLATE koi8r_general_ci) ENGINE=Memory CHARACTER SET koi8r COLLATE koi8r_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # koi8r_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # koi8r_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -10346,8 +10346,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8u;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8u COLLATE koi8u_bin) ENGINE=Memory CHARACTER SET koi8u COLLATE koi8u_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # koi8u_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # koi8u_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -10576,8 +10576,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8u;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8u COLLATE koi8u_general_ci) ENGINE=Memory CHARACTER SET koi8u COLLATE koi8u_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # koi8u_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # koi8u_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
60 1
@@ -10806,8 +10806,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_bin) ENGINE=Memory CHARACTER SET latin1 COLLATE latin1_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin1_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin1_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11036,8 +11036,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_danish_ci) ENGINE=Memory CHARACTER SET latin1 COLLATE latin1_danish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin1_danish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin1_danish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11266,8 +11266,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_general_ci) ENGINE=Memory CHARACTER SET latin1 COLLATE latin1_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin1_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin1_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11496,8 +11496,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_general_cs) ENGINE=Memory CHARACTER SET latin1 COLLATE latin1_general_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin1_general_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin1_general_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11726,8 +11726,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_german1_ci) ENGINE=Memory CHARACTER SET latin1 COLLATE latin1_german1_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin1_german1_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin1_german1_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11956,8 +11956,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_german2_ci) ENGINE=Memory CHARACTER SET latin1 COLLATE latin1_german2_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin1_german2_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin1_german2_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12186,8 +12186,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_spanish_ci) ENGINE=Memory CHARACTER SET latin1 COLLATE latin1_spanish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin1_spanish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin1_spanish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12416,8 +12416,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_swedish_ci) ENGINE=Memory CHARACTER SET latin1 COLLATE latin1_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin1_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin1_swedish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12646,8 +12646,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_bin) ENGINE=Memory CHARACTER SET latin2 COLLATE latin2_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin2_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin2_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12876,8 +12876,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_croatian_ci) ENGINE=Memory CHARACTER SET latin2 COLLATE latin2_croatian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin2_croatian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin2_croatian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -13106,8 +13106,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_czech_cs) ENGINE=Memory CHARACTER SET latin2 COLLATE latin2_czech_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin2_czech_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin2_czech_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
2E 1
@@ -13336,8 +13336,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_general_ci) ENGINE=Memory CHARACTER SET latin2 COLLATE latin2_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin2_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin2_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -13566,8 +13566,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_hungarian_ci) ENGINE=Memory CHARACTER SET latin2 COLLATE latin2_hungarian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin2_hungarian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin2_hungarian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -13796,8 +13796,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin5 COLLATE latin5_bin) ENGINE=Memory CHARACTER SET latin5 COLLATE latin5_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin5_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin5_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -14026,8 +14026,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin5 COLLATE latin5_turkish_ci) ENGINE=Memory CHARACTER SET latin5 COLLATE latin5_turkish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin5_turkish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin5_turkish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -14256,8 +14256,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_bin) ENGINE=Memory CHARACTER SET latin7 COLLATE latin7_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin7_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin7_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -14486,8 +14486,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_estonian_cs) ENGINE=Memory CHARACTER SET latin7 COLLATE latin7_estonian_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin7_estonian_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin7_estonian_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
80 1
@@ -14716,8 +14716,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_general_ci) ENGINE=Memory CHARACTER SET latin7 COLLATE latin7_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin7_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin7_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -14946,8 +14946,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_general_cs) ENGINE=Memory CHARACTER SET latin7 COLLATE latin7_general_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # latin7_general_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # latin7_general_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -15176,8 +15176,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macce;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macce COLLATE macce_bin) ENGINE=Memory CHARACTER SET macce COLLATE macce_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # macce_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # macce_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -15406,8 +15406,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macce;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macce COLLATE macce_general_ci) ENGINE=Memory CHARACTER SET macce COLLATE macce_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # macce_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # macce_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -15636,8 +15636,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macroman;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macroman COLLATE macroman_bin) ENGINE=Memory CHARACTER SET macroman COLLATE macroman_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # macroman_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # macroman_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -15866,8 +15866,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macroman;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macroman COLLATE macroman_general_ci) ENGINE=Memory CHARACTER SET macroman COLLATE macroman_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # macroman_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # macroman_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16096,8 +16096,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES sjis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET sjis COLLATE sjis_bin) ENGINE=Memory CHARACTER SET sjis COLLATE sjis_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # sjis_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # sjis_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16263,8 +16263,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES sjis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET sjis COLLATE sjis_japanese_ci) ENGINE=Memory CHARACTER SET sjis COLLATE sjis_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # sjis_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # sjis_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16430,8 +16430,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES swe7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET swe7 COLLATE swe7_bin) ENGINE=Memory CHARACTER SET swe7 COLLATE swe7_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # swe7_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # swe7_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16660,8 +16660,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES swe7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET swe7 COLLATE swe7_swedish_ci) ENGINE=Memory CHARACTER SET swe7 COLLATE swe7_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # swe7_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # swe7_swedish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16890,8 +16890,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES tis620;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET tis620 COLLATE tis620_bin) ENGINE=Memory CHARACTER SET tis620 COLLATE tis620_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # tis620_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # tis620_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17120,8 +17120,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES tis620;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET tis620 COLLATE tis620_thai_ci) ENGINE=Memory CHARACTER SET tis620 COLLATE tis620_thai_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # tis620_thai_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # tis620_thai_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17350,8 +17350,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ujis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ujis COLLATE ujis_bin) ENGINE=Memory CHARACTER SET ujis COLLATE ujis_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # ujis_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # ujis_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17454,8 +17454,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ujis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ujis COLLATE ujis_japanese_ci) ENGINE=Memory CHARACTER SET ujis COLLATE ujis_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # ujis_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # ujis_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17561,8 +17561,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_bin;
@@ -20102,8 +20102,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_czech_ci;
@@ -22643,8 +22643,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_danish_ci;
@@ -25184,8 +25184,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_estonian_ci;
@@ -27725,8 +27725,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_general_ci;
@@ -30266,8 +30266,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_hungarian_ci;
@@ -32807,8 +32807,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_icelandic_ci;
@@ -35348,8 +35348,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_latvian_ci;
@@ -37889,8 +37889,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_lithuanian_ci;
@@ -40430,8 +40430,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_persian_ci;
@@ -42971,8 +42971,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_polish_ci;
@@ -45512,8 +45512,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_roman_ci;
@@ -48053,8 +48053,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_romanian_ci;
@@ -50594,8 +50594,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovak_ci;
@@ -53135,8 +53135,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovenian_ci;
@@ -55676,8 +55676,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish2_ci;
@@ -58217,8 +58217,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish_ci;
@@ -60758,8 +60758,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_swedish_ci;
@@ -63299,8 +63299,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_turkish_ci;
@@ -65840,8 +65840,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci;
@@ -68380,8 +68380,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_bin) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_bin # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -70919,8 +70919,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_czech_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_czech_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_czech_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_czech_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -73458,8 +73458,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_danish_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_danish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_danish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_danish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -75997,8 +75997,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_estonian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_estonian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_estonian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_estonian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -78536,8 +78536,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_general_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -81075,8 +81075,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_hungarian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_hungarian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_hungarian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_hungarian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -83614,8 +83614,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_icelandic_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_icelandic_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_icelandic_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_icelandic_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -86153,8 +86153,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_latvian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_latvian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_latvian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_latvian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -88692,8 +88692,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_lithuanian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_lithuanian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_lithuanian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_lithuanian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -91231,8 +91231,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_persian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_persian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_persian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_persian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -93770,8 +93770,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_polish_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_polish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_polish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_polish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -96309,8 +96309,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_roman_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_roman_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_roman_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_roman_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -98848,8 +98848,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_romanian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_romanian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_romanian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_romanian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -101387,8 +101387,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovak_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_slovak_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_slovak_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_slovak_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -103926,8 +103926,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovenian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_slovenian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_slovenian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_slovenian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -106465,8 +106465,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish2_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_spanish2_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_spanish2_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_spanish2_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -109004,8 +109004,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_spanish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_spanish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_spanish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -111543,8 +111543,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_swedish_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_swedish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -114082,8 +114082,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_turkish_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_turkish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_turkish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_turkish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -116621,8 +116621,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_unicode_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY # # # # # # # # # # # # utf8_unicode_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY # # # # # # # # # # # # utf8_unicode_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
diff --git a/mysql-test/suite/funcs_2/r/myisam_charset.result b/mysql-test/suite/funcs_2/r/myisam_charset.result
index c4630637177..cf2b798de09 100644
--- a/mysql-test/suite/funcs_2/r/myisam_charset.result
+++ b/mysql-test/suite/funcs_2/r/myisam_charset.result
@@ -2,8 +2,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES armscii8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET armscii8 COLLATE armscii8_bin) ENGINE=MyISAM CHARACTER SET armscii8 COLLATE armscii8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # armscii8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # armscii8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -232,8 +232,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES armscii8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET armscii8 COLLATE armscii8_general_ci) ENGINE=MyISAM CHARACTER SET armscii8 COLLATE armscii8_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # armscii8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # armscii8_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -462,8 +462,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ascii;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ascii COLLATE ascii_bin) ENGINE=MyISAM CHARACTER SET ascii COLLATE ascii_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # ascii_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # ascii_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -692,8 +692,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ascii;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ascii COLLATE ascii_general_ci) ENGINE=MyISAM CHARACTER SET ascii COLLATE ascii_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # ascii_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # ascii_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -922,8 +922,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES big5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET big5 COLLATE big5_bin) ENGINE=MyISAM CHARACTER SET big5 COLLATE big5_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # big5_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # big5_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1026,8 +1026,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES big5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET big5 COLLATE big5_chinese_ci) ENGINE=MyISAM CHARACTER SET big5 COLLATE big5_chinese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # big5_chinese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # big5_chinese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1130,8 +1130,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES binary;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET binary) ENGINE=MyISAM CHARACTER SET binary;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # binary # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # binary # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1360,8 +1360,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_bin) ENGINE=MyISAM CHARACTER SET cp1250 COLLATE cp1250_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1250_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1250_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1590,8 +1590,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_croatian_ci) ENGINE=MyISAM CHARACTER SET cp1250 COLLATE cp1250_croatian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1250_croatian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1250_croatian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -1820,8 +1820,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_czech_cs) ENGINE=MyISAM CHARACTER SET cp1250 COLLATE cp1250_czech_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1250_czech_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1250_czech_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -2050,8 +2050,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1250;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1250 COLLATE cp1250_general_ci) ENGINE=MyISAM CHARACTER SET cp1250 COLLATE cp1250_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1250_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1250_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
A0 1
@@ -2280,8 +2280,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_bin) ENGINE=MyISAM CHARACTER SET cp1251 COLLATE cp1251_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1251_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1251_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -2510,8 +2510,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_bulgarian_ci) ENGINE=MyISAM CHARACTER SET cp1251 COLLATE cp1251_bulgarian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1251_bulgarian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1251_bulgarian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -2740,8 +2740,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_general_ci) ENGINE=MyISAM CHARACTER SET cp1251 COLLATE cp1251_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1251_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1251_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -2970,8 +2970,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_general_cs) ENGINE=MyISAM CHARACTER SET cp1251 COLLATE cp1251_general_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1251_general_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1251_general_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -3200,8 +3200,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1251;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1251 COLLATE cp1251_ukrainian_ci) ENGINE=MyISAM CHARACTER SET cp1251 COLLATE cp1251_ukrainian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1251_ukrainian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1251_ukrainian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
60 1
@@ -3430,8 +3430,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1256;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1256 COLLATE cp1256_bin) ENGINE=MyISAM CHARACTER SET cp1256 COLLATE cp1256_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1256_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1256_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -3660,8 +3660,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1256;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1256 COLLATE cp1256_general_ci) ENGINE=MyISAM CHARACTER SET cp1256 COLLATE cp1256_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1256_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1256_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -3890,8 +3890,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1257;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1257 COLLATE cp1257_bin) ENGINE=MyISAM CHARACTER SET cp1257 COLLATE cp1257_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1257_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1257_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4120,8 +4120,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1257;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1257 COLLATE cp1257_general_ci) ENGINE=MyISAM CHARACTER SET cp1257 COLLATE cp1257_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1257_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1257_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4350,8 +4350,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp1257;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp1257 COLLATE cp1257_lithuanian_ci) ENGINE=MyISAM CHARACTER SET cp1257 COLLATE cp1257_lithuanian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp1257_lithuanian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp1257_lithuanian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4580,8 +4580,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp850;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp850 COLLATE cp850_bin) ENGINE=MyISAM CHARACTER SET cp850 COLLATE cp850_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp850_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp850_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -4810,8 +4810,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp850;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp850 COLLATE cp850_general_ci) ENGINE=MyISAM CHARACTER SET cp850 COLLATE cp850_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp850_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp850_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5040,8 +5040,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp852;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp852 COLLATE cp852_bin) ENGINE=MyISAM CHARACTER SET cp852 COLLATE cp852_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp852_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp852_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5270,8 +5270,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp852;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp852 COLLATE cp852_general_ci) ENGINE=MyISAM CHARACTER SET cp852 COLLATE cp852_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp852_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp852_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5500,8 +5500,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp866;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp866 COLLATE cp866_bin) ENGINE=MyISAM CHARACTER SET cp866 COLLATE cp866_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp866_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp866_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5730,8 +5730,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp866;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp866 COLLATE cp866_general_ci) ENGINE=MyISAM CHARACTER SET cp866 COLLATE cp866_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp866_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp866_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -5960,8 +5960,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp932;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp932 COLLATE cp932_bin) ENGINE=MyISAM CHARACTER SET cp932 COLLATE cp932_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp932_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp932_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6127,8 +6127,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES cp932;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET cp932 COLLATE cp932_japanese_ci) ENGINE=MyISAM CHARACTER SET cp932 COLLATE cp932_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # cp932_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # cp932_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6294,8 +6294,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES dec8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET dec8 COLLATE dec8_bin) ENGINE=MyISAM CHARACTER SET dec8 COLLATE dec8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # dec8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # dec8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6524,8 +6524,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES dec8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET dec8 COLLATE dec8_swedish_ci) ENGINE=MyISAM CHARACTER SET dec8 COLLATE dec8_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # dec8_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # dec8_swedish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6754,8 +6754,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES eucjpms;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET eucjpms COLLATE eucjpms_bin) ENGINE=MyISAM CHARACTER SET eucjpms COLLATE eucjpms_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # eucjpms_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # eucjpms_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6858,8 +6858,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES eucjpms;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET eucjpms COLLATE eucjpms_japanese_ci) ENGINE=MyISAM CHARACTER SET eucjpms COLLATE eucjpms_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # eucjpms_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # eucjpms_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -6962,8 +6962,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES euckr;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET euckr COLLATE euckr_bin) ENGINE=MyISAM CHARACTER SET euckr COLLATE euckr_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # euckr_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # euckr_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7066,8 +7066,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES euckr;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET euckr COLLATE euckr_korean_ci) ENGINE=MyISAM CHARACTER SET euckr COLLATE euckr_korean_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # euckr_korean_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # euckr_korean_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7170,8 +7170,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gb2312;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gb2312 COLLATE gb2312_bin) ENGINE=MyISAM CHARACTER SET gb2312 COLLATE gb2312_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # gb2312_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # gb2312_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7274,8 +7274,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gb2312;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gb2312 COLLATE gb2312_chinese_ci) ENGINE=MyISAM CHARACTER SET gb2312 COLLATE gb2312_chinese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # gb2312_chinese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # gb2312_chinese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7378,8 +7378,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gbk;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gbk COLLATE gbk_bin) ENGINE=MyISAM CHARACTER SET gbk COLLATE gbk_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # gbk_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # gbk_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7482,8 +7482,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES gbk;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET gbk COLLATE gbk_chinese_ci) ENGINE=MyISAM CHARACTER SET gbk COLLATE gbk_chinese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # gbk_chinese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # gbk_chinese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7586,8 +7586,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES geostd8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET geostd8 COLLATE geostd8_bin) ENGINE=MyISAM CHARACTER SET geostd8 COLLATE geostd8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # geostd8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # geostd8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -7816,8 +7816,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES geostd8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET geostd8 COLLATE geostd8_general_ci) ENGINE=MyISAM CHARACTER SET geostd8 COLLATE geostd8_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # geostd8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # geostd8_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8046,8 +8046,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES greek;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET greek COLLATE greek_bin) ENGINE=MyISAM CHARACTER SET greek COLLATE greek_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # greek_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # greek_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8276,8 +8276,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES greek;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET greek COLLATE greek_general_ci) ENGINE=MyISAM CHARACTER SET greek COLLATE greek_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # greek_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # greek_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8506,8 +8506,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hebrew;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hebrew COLLATE hebrew_bin) ENGINE=MyISAM CHARACTER SET hebrew COLLATE hebrew_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # hebrew_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # hebrew_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8736,8 +8736,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hebrew;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hebrew COLLATE hebrew_general_ci) ENGINE=MyISAM CHARACTER SET hebrew COLLATE hebrew_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # hebrew_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # hebrew_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -8966,8 +8966,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hp8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hp8 COLLATE hp8_bin) ENGINE=MyISAM CHARACTER SET hp8 COLLATE hp8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # hp8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # hp8_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9196,8 +9196,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES hp8;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET hp8 COLLATE hp8_english_ci) ENGINE=MyISAM CHARACTER SET hp8 COLLATE hp8_english_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # hp8_english_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # hp8_english_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9426,8 +9426,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES keybcs2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET keybcs2 COLLATE keybcs2_bin) ENGINE=MyISAM CHARACTER SET keybcs2 COLLATE keybcs2_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # keybcs2_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # keybcs2_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9656,8 +9656,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES keybcs2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET keybcs2 COLLATE keybcs2_general_ci) ENGINE=MyISAM CHARACTER SET keybcs2 COLLATE keybcs2_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # keybcs2_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # keybcs2_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -9886,8 +9886,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8r;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8r COLLATE koi8r_bin) ENGINE=MyISAM CHARACTER SET koi8r COLLATE koi8r_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # koi8r_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # koi8r_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -10116,8 +10116,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8r;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8r COLLATE koi8r_general_ci) ENGINE=MyISAM CHARACTER SET koi8r COLLATE koi8r_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # koi8r_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # koi8r_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -10346,8 +10346,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8u;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8u COLLATE koi8u_bin) ENGINE=MyISAM CHARACTER SET koi8u COLLATE koi8u_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # koi8u_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # koi8u_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -10576,8 +10576,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES koi8u;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET koi8u COLLATE koi8u_general_ci) ENGINE=MyISAM CHARACTER SET koi8u COLLATE koi8u_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # koi8u_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # koi8u_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
60 1
@@ -10806,8 +10806,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_bin) ENGINE=MyISAM CHARACTER SET latin1 COLLATE latin1_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin1_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin1_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11036,8 +11036,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_danish_ci) ENGINE=MyISAM CHARACTER SET latin1 COLLATE latin1_danish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin1_danish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin1_danish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11266,8 +11266,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_general_ci) ENGINE=MyISAM CHARACTER SET latin1 COLLATE latin1_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin1_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin1_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11496,8 +11496,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_general_cs) ENGINE=MyISAM CHARACTER SET latin1 COLLATE latin1_general_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin1_general_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin1_general_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11726,8 +11726,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_german1_ci) ENGINE=MyISAM CHARACTER SET latin1 COLLATE latin1_german1_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin1_german1_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin1_german1_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -11956,8 +11956,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_german2_ci) ENGINE=MyISAM CHARACTER SET latin1 COLLATE latin1_german2_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin1_german2_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin1_german2_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12186,8 +12186,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_spanish_ci) ENGINE=MyISAM CHARACTER SET latin1 COLLATE latin1_spanish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin1_spanish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin1_spanish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12416,8 +12416,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin1;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin1 COLLATE latin1_swedish_ci) ENGINE=MyISAM CHARACTER SET latin1 COLLATE latin1_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin1_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin1_swedish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12646,8 +12646,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_bin) ENGINE=MyISAM CHARACTER SET latin2 COLLATE latin2_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin2_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin2_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -12876,8 +12876,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_croatian_ci) ENGINE=MyISAM CHARACTER SET latin2 COLLATE latin2_croatian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin2_croatian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin2_croatian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -13106,8 +13106,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_czech_cs) ENGINE=MyISAM CHARACTER SET latin2 COLLATE latin2_czech_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin2_czech_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin2_czech_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
2E 1
@@ -13336,8 +13336,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_general_ci) ENGINE=MyISAM CHARACTER SET latin2 COLLATE latin2_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin2_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin2_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -13566,8 +13566,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin2;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin2 COLLATE latin2_hungarian_ci) ENGINE=MyISAM CHARACTER SET latin2 COLLATE latin2_hungarian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin2_hungarian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin2_hungarian_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -13796,8 +13796,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin5 COLLATE latin5_bin) ENGINE=MyISAM CHARACTER SET latin5 COLLATE latin5_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin5_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin5_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -14026,8 +14026,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin5;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin5 COLLATE latin5_turkish_ci) ENGINE=MyISAM CHARACTER SET latin5 COLLATE latin5_turkish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin5_turkish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin5_turkish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -14256,8 +14256,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_bin) ENGINE=MyISAM CHARACTER SET latin7 COLLATE latin7_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin7_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin7_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -14486,8 +14486,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_estonian_cs) ENGINE=MyISAM CHARACTER SET latin7 COLLATE latin7_estonian_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin7_estonian_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin7_estonian_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
80 1
@@ -14716,8 +14716,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_general_ci) ENGINE=MyISAM CHARACTER SET latin7 COLLATE latin7_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin7_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin7_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -14946,8 +14946,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES latin7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET latin7 COLLATE latin7_general_cs) ENGINE=MyISAM CHARACTER SET latin7 COLLATE latin7_general_cs;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # latin7_general_cs # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # latin7_general_cs # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
7F 1
@@ -15176,8 +15176,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macce;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macce COLLATE macce_bin) ENGINE=MyISAM CHARACTER SET macce COLLATE macce_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # macce_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # macce_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -15406,8 +15406,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macce;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macce COLLATE macce_general_ci) ENGINE=MyISAM CHARACTER SET macce COLLATE macce_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # macce_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # macce_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -15636,8 +15636,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macroman;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macroman COLLATE macroman_bin) ENGINE=MyISAM CHARACTER SET macroman COLLATE macroman_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # macroman_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # macroman_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -15866,8 +15866,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES macroman;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET macroman COLLATE macroman_general_ci) ENGINE=MyISAM CHARACTER SET macroman COLLATE macroman_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # macroman_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # macroman_general_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16096,8 +16096,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES sjis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET sjis COLLATE sjis_bin) ENGINE=MyISAM CHARACTER SET sjis COLLATE sjis_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # sjis_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # sjis_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16263,8 +16263,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES sjis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET sjis COLLATE sjis_japanese_ci) ENGINE=MyISAM CHARACTER SET sjis COLLATE sjis_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # sjis_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # sjis_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16430,8 +16430,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES swe7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET swe7 COLLATE swe7_bin) ENGINE=MyISAM CHARACTER SET swe7 COLLATE swe7_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # swe7_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # swe7_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16660,8 +16660,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES swe7;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET swe7 COLLATE swe7_swedish_ci) ENGINE=MyISAM CHARACTER SET swe7 COLLATE swe7_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # swe7_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # swe7_swedish_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -16890,8 +16890,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES tis620;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET tis620 COLLATE tis620_bin) ENGINE=MyISAM CHARACTER SET tis620 COLLATE tis620_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # tis620_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # tis620_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17120,8 +17120,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES tis620;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET tis620 COLLATE tis620_thai_ci) ENGINE=MyISAM CHARACTER SET tis620 COLLATE tis620_thai_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # tis620_thai_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # tis620_thai_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17350,8 +17350,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ujis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ujis COLLATE ujis_bin) ENGINE=MyISAM CHARACTER SET ujis COLLATE ujis_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # ujis_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # ujis_bin # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17454,8 +17454,8 @@ DROP TABLE IF EXISTS test.t1;
SET NAMES ujis;
CREATE TABLE test.t1 (a VARCHAR(3) CHARACTER SET ujis COLLATE ujis_japanese_ci) ENGINE=MyISAM CHARACTER SET ujis COLLATE ujis_japanese_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # ujis_japanese_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # ujis_japanese_ci # # # # N
SELECT HEX(ASCII(a)) AS a_ascii, CHAR_LENGTH(a) AS a_len FROM test.t1 ORDER BY a, ORD(a);
a_ascii a_len
21 1
@@ -17561,8 +17561,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_bin;
@@ -20102,8 +20102,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_czech_ci;
@@ -22643,8 +22643,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_danish_ci;
@@ -25184,8 +25184,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_estonian_ci;
@@ -27725,8 +27725,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_general_ci;
@@ -30266,8 +30266,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_hungarian_ci;
@@ -32807,8 +32807,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_icelandic_ci;
@@ -35348,8 +35348,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_latvian_ci;
@@ -37889,8 +37889,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_lithuanian_ci;
@@ -40430,8 +40430,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_persian_ci;
@@ -42971,8 +42971,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_polish_ci;
@@ -45512,8 +45512,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_roman_ci;
@@ -48053,8 +48053,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_romanian_ci;
@@ -50594,8 +50594,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovak_ci;
@@ -53135,8 +53135,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovenian_ci;
@@ -55676,8 +55676,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish2_ci;
@@ -58217,8 +58217,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish_ci;
@@ -60758,8 +60758,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_swedish_ci;
@@ -63299,8 +63299,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_turkish_ci;
@@ -65840,8 +65840,8 @@ USE test;
SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci;
@@ -68380,8 +68380,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_bin) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_bin;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_bin # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_bin # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -70919,8 +70919,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_czech_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_czech_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_czech_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_czech_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -73458,8 +73458,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_danish_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_danish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_danish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_danish_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -75997,8 +75997,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_estonian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_estonian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_estonian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_estonian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -78536,8 +78536,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_general_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -81075,8 +81075,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_hungarian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_hungarian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_hungarian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_hungarian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -83614,8 +83614,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_icelandic_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_icelandic_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_icelandic_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_icelandic_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -86153,8 +86153,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_latvian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_latvian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_latvian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_latvian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -88692,8 +88692,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_lithuanian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_lithuanian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_lithuanian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_lithuanian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -91231,8 +91231,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_persian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_persian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_persian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_persian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -93770,8 +93770,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_polish_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_polish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_polish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_polish_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -96309,8 +96309,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_roman_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_roman_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_roman_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_roman_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -98848,8 +98848,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_romanian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_romanian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_romanian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_romanian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -101387,8 +101387,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovak_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_slovak_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_slovak_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_slovak_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -103926,8 +103926,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovenian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_slovenian_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_slovenian_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_slovenian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -106465,8 +106465,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish2_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_spanish2_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_spanish2_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_spanish2_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -109004,8 +109004,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_spanish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_spanish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_spanish_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -111543,8 +111543,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_swedish_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_swedish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_swedish_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -114082,8 +114082,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_turkish_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_turkish_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_turkish_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_turkish_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -116621,8 +116621,8 @@ CREATE DATABASE test CHARACTER SET utf8;
USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_unicode_ci;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM # # # # # # # # # # # # utf8_unicode_ci # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MyISAM # # # # # # # # # # # # utf8_unicode_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index 193b9f87d56..8db0073d268 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -54,9 +54,14 @@ galera_pc_ignore_sb : MDEV-13549 Galera test failures 10.1
galera_lock_table : MDEV-13549 Galera test failures 10.1
MW-284 : MDEV-13549 Galera test failures 10.1
galera_as_slave : MDEV-13549 Galera test failures 10.1
-galera_var_innodb_disallow_writes : MDEV-10949
galera_kill_applier : race condition at the start of the test
GAL-480 : "Lost connection to MySQL"
-MW-328A : "Found wrong usage of mutex"
-MW-328B : "Found wrong usage of mutex"
-MW-328C : "Found wrong usage of mutex"
+MW-328C: MDEV-13549 Galera test failures 10.1
+MW-328A: MDEV-13549 Galera test failures 10.1
+MW-328B: MDEV-13549 Galera test failures 10.1
+MW-328: MDEV-13549 Galera test failures 10.1
+galera_suspend_slave: MDEV-13549 Galera test failures 10.1
+galera_ist_progress: MDEV-15236 galera_ist_progress fails when trying to read transfer status
+galera_gtid : MDEV-13549 Galera test failures 10.1
+galera_gtid_slave : MDEV-13549 Galera test failures 10.1
+galera_unicode_identifiers : MDEV-13549 Galera test failures 10.1
diff --git a/mysql-test/suite/galera/r/MW-388.result b/mysql-test/suite/galera/r/MW-388.result
new file mode 100644
index 00000000000..a2cf02712bb
--- /dev/null
+++ b/mysql-test/suite/galera/r/MW-388.result
@@ -0,0 +1,50 @@
+connection node_1;
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(255)) Engine=InnoDB;
+CREATE PROCEDURE insert_proc ()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;
+END;
+INSERT INTO t1 VALUES (1, 'node 1'),(2, 'node 1');
+INSERT INTO t1 VALUES (3, 'node 1');
+END|
+SET GLOBAL wsrep_slave_threads = 2;
+SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb";
+connection node_2;
+INSERT INTO t1 VALUES (1, 'node 2');;
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+connection node_1a;
+SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+connection node_1;
+SET SESSION wsrep_sync_wait = 0;
+SET SESSION DEBUG_SYNC = 'wsrep_after_replication SIGNAL wsrep_after_replication_reached WAIT_FOR wsrep_after_replication_continue';
+CALL insert_proc ();;
+connection node_1a;
+SET SESSION DEBUG_SYNC = "now WAIT_FOR wsrep_after_replication_reached";
+SET GLOBAL DEBUG_DBUG = "";
+SET DEBUG_SYNC = "now SIGNAL wsrep_after_replication_continue";
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+connection node_2;
+connection node_1;
+SELECT @errno = 1213;
+@errno = 1213
+0
+SELECT * FROM t1;
+f1 f2
+1 node 2
+3 node 1
+connection node_2;
+SELECT * FROM t1;
+f1 f2
+1 node 2
+3 node 1
+connection node_1;
+SET GLOBAL wsrep_slave_threads = DEFAULT;
+DROP TABLE t1;
+DROP PROCEDURE insert_proc;
+SET GLOBAL debug_dbug = NULL;
+SET debug_sync='RESET';
+SELECT @@debug_sync;
+@@debug_sync
+ON - current signal: ''
diff --git a/mysql-test/suite/galera/r/galera_bf_abort.result b/mysql-test/suite/galera/r/galera_bf_abort.result
index f7af382d8e2..c2e89965fce 100644
--- a/mysql-test/suite/galera/r/galera_bf_abort.result
+++ b/mysql-test/suite/galera/r/galera_bf_abort.result
@@ -9,7 +9,7 @@ INSERT INTO t1 VALUES (1,'node_1');
connection node_2a;
connection node_2;
INSERT INTO t1 VALUES (2, 'node_2');
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
wsrep_local_aborts_increment
1
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_bf_abort_get_lock.result b/mysql-test/suite/galera/r/galera_bf_abort_get_lock.result
index 2a4a786cca4..8c6c7b7d7a4 100644
--- a/mysql-test/suite/galera/r/galera_bf_abort_get_lock.result
+++ b/mysql-test/suite/galera/r/galera_bf_abort_get_lock.result
@@ -10,7 +10,7 @@ SELECT GET_LOCK("foo", 1000);;
connection node_1;
INSERT INTO t1 VALUES (1);
connection node_2;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
wsrep_local_aborts_increment
1
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_bf_abort_sleep.result b/mysql-test/suite/galera/r/galera_bf_abort_sleep.result
index 2982e40f9ae..9cd6abad5a1 100644
--- a/mysql-test/suite/galera/r/galera_bf_abort_sleep.result
+++ b/mysql-test/suite/galera/r/galera_bf_abort_sleep.result
@@ -6,7 +6,7 @@ SELECT SLEEP(1000);;
connection node_1;
INSERT INTO t1 VALUES (1);
connection node_2;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
wsrep_local_aborts_increment
1
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_bf_lock_wait.result b/mysql-test/suite/galera/r/galera_bf_lock_wait.result
new file mode 100644
index 00000000000..7ec524da888
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_bf_lock_wait.result
@@ -0,0 +1,23 @@
+CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2;
+ALTER TABLE t1 add primary key(a);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION rollback;
+WHILE 1 DO
+start transaction;
+update t1 set b=connection_id() where a=1;
+commit;
+END WHILE;
+END|
+connect node_1_p1, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+call p1;
+connect node_1_p2, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+call p1;
+connect node_2_p1, 127.0.0.1, root, , test, $NODE_MYPORT_2;
+call p1;
+connect node_2_p2, 127.0.0.1, root, , test, $NODE_MYPORT_2;
+call p1;
+connection default;
+checking error log for 'BF lock wait long' message for 10 times every 10 seconds ...
+drop table t1;
+drop procedure p1;
diff --git a/mysql-test/suite/galera/r/galera_defaults.result b/mysql-test/suite/galera/r/galera_defaults.result
index 28c3f4dd104..d3004735a0a 100644
--- a/mysql-test/suite/galera/r/galera_defaults.result
+++ b/mysql-test/suite/galera/r/galera_defaults.result
@@ -51,7 +51,7 @@ WSREP_SST_DONOR
WSREP_SST_DONOR_REJECTS_QUERIES OFF
WSREP_SST_METHOD rsync
WSREP_SYNC_WAIT 15
-<BASE_DIR>; <BASE_HOST>; <BASE_PORT>; cert.log_conflicts = no; debug = no; evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask = 0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S; evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT30S; evs.info_log_mask = 0; evs.install_timeout = PT15S; evs.join_retrans_period = PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window = 4; evs.stats_report_period = PT1M; evs.suspect_timeout = PT10S; evs.use_aggregate = true; evs.user_send_window = 2; evs.version = 0; evs.view_forget_timeout = P1D; <GCACHE_DIR>; gcache.keep_pages_size = 0; gcache.mem_size = 0; <GCACHE_NAME>; gcache.page_size = 128M; gcache.recover = no; gcache.size = 10M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1.0; gcs.fc_limit = 16; gcs.fc_master_slave = no; gcs.max_packet_size = 64500; gcs.max_throttle = 0.25; <GCS_RECV_Q_HARD_LIMIT>; gcs.recv_q_soft_limit = 0.25; gcs.sync_donor = no; <GMCAST_LISTEN_ADDR>; gmcast.mcast_addr = ; gmcast.mcast_ttl = 1; gmcast.peer_timeout = PT3S; gmcast.segment = 0; gmcast.time_wait = PT5S; gmcast.version = 0; <IST_RECV_ADDR>; pc.announce_timeout = PT3S; pc.checksum = false; pc.ignore_quorum = false; pc.ignore_sb = false; pc.linger = PT20S; pc.npvo = false; pc.recovery = true; pc.version = 0; pc.wait_prim = true; pc.wait_prim_timeout = PT30S; pc.weight = 1; protonet.backend = asio; protonet.version = 0; repl.causal_read_timeout = PT90S; repl.commit_order = 3; repl.key_format = FLAT8; repl.max_ws_size = 2147483647; repl.proto_max = 7; socket.checksum = 2; socket.recv_buf_size = 212992;
+<BASE_DIR>; <BASE_HOST>; <BASE_PORT>; cert.log_conflicts = no; debug = no; evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask = 0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S; evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT30S; evs.info_log_mask = 0; evs.install_timeout = PT15S; evs.join_retrans_period = PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window = 4; evs.stats_report_period = PT1M; evs.suspect_timeout = PT10S; evs.use_aggregate = true; evs.user_send_window = 2; evs.version = 0; evs.view_forget_timeout = P1D; <GCACHE_DIR>; gcache.keep_pages_size = 0; gcache.mem_size = 0; <GCACHE_NAME>; gcache.page_size = 128M; gcache.recover = no; gcache.size = 10M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1.0; gcs.fc_limit = 16; gcs.fc_master_slave = no; gcs.max_packet_size = 64500; gcs.max_throttle = 0.25; <GCS_RECV_Q_HARD_LIMIT>; gcs.recv_q_soft_limit = 0.25; gcs.sync_donor = no; <GMCAST_LISTEN_ADDR>; gmcast.mcast_addr = ; gmcast.mcast_ttl = 1; gmcast.peer_timeout = PT3S; gmcast.segment = 0; gmcast.time_wait = PT5S; gmcast.version = 0; <IST_RECV_ADDR>; pc.announce_timeout = PT3S; pc.checksum = false; pc.ignore_quorum = false; pc.ignore_sb = false; pc.linger = PT20S; pc.npvo = false; pc.recovery = true; pc.version = 0; pc.wait_prim = true; pc.wait_prim_timeout = PT30S; pc.weight = 1; protonet.backend = asio; protonet.version = 0; repl.causal_read_timeout = PT90S; repl.commit_order = 3; repl.key_format = FLAT8; repl.max_ws_size = 2147483647; <REPL_PROTO_MAX>;socket.checksum = 2; socket.recv_buf_size = 212992;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_STATUS
WHERE VARIABLE_NAME LIKE 'wsrep_%'
AND VARIABLE_NAME != 'wsrep_debug_sync_waiters';
diff --git a/mysql-test/suite/galera/r/galera_enum.result b/mysql-test/suite/galera/r/galera_enum.result
index ad0ee92a8e5..dcf31aa5948 100644
--- a/mysql-test/suite/galera/r/galera_enum.result
+++ b/mysql-test/suite/galera/r/galera_enum.result
@@ -38,7 +38,7 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
connection node_1;
SELECT COUNT(*) = 1 FROM t1 WHERE f1 = 'three';
COUNT(*) = 1
diff --git a/mysql-test/suite/galera/r/galera_fk_conflict.result b/mysql-test/suite/galera/r/galera_fk_conflict.result
index 97e8a47fa6c..a08aa30a82e 100644
--- a/mysql-test/suite/galera/r/galera_fk_conflict.result
+++ b/mysql-test/suite/galera/r/galera_fk_conflict.result
@@ -22,6 +22,6 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
DROP TABLE child;
DROP TABLE parent;
diff --git a/mysql-test/suite/galera/r/galera_gtid_slave.result b/mysql-test/suite/galera/r/galera_gtid_slave.result
new file mode 100644
index 00000000000..0b6306bdc6a
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_gtid_slave.result
@@ -0,0 +1,36 @@
+connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
+connection node_2;
+START SLAVE;
+connection node_1;
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1);
+begin;
+insert into t2 values(21);
+insert into t2 values(22);
+commit;
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4
+connection node_2;
+INSERT INTO t1 VALUES(2);
+INSERT INTO t1 VALUES(3);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4,2-2-2
+connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3;
+INSERT INTO t1 VALUES(4);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4,2-2-2,2-3-3
+connection node_1;
+DROP TABLE t1,t2;
+reset master;
+connection node_2;
+connection node_3;
+connection node_2;
+STOP SLAVE;
+RESET SLAVE ALL;
+reset master;
+connection node_3;
+reset master;
diff --git a/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result b/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result
new file mode 100644
index 00000000000..cdf330643c2
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result
@@ -0,0 +1,159 @@
+connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
+#Connection 2
+connection node_2;
+START SLAVE;
+#Connection 1
+connection node_1;
+CREATE TABLE t2 (f1 INTEGER PRIMARY KEY, f2 int unique) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(1,11);
+INSERT INTO t2 VALUES(2,22);
+INSERT INTO t2 VALUES(3,33);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4
+include/save_master_gtid.inc
+#Connection 2
+connection node_2;
+include/sync_with_master_gtid.inc
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4
+INSERT INTO t2 VALUES(4,44);
+INSERT INTO t2 VALUES(5,55);
+INSERT INTO t2 VALUES(6,66);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4,2-2-3
+#Connection 3
+connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3;
+INSERT INTO t2 VALUES(7,77);
+INSERT INTO t2 VALUES(8,88);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4,2-2-3,2-3-5
+#Connection 1
+connection node_1;
+CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+COMMIT;
+include/save_master_gtid.inc
+#Connection 2
+connection node_2;
+include/sync_with_master_gtid.inc
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+COMMIT;
+#Connection 3
+connection node_3;
+connection node_2;
+connection node_3;
+Shutting down server ...
+#Connection 2
+connection node_2;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+COMMIT;
+#Connection 3
+connection node_3;
+Starting server ...
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node3_committed_after');
+INSERT INTO t1 VALUES ('node3_committed_after');
+COMMIT;
+#Connection 2
+connection node_2;
+Select * from t1 order by f1;
+f1
+node1_committed_before
+node1_committed_before
+node1_committed_during
+node1_committed_during
+node2_committed_before
+node2_committed_before
+node3_committed_after
+node3_committed_after
+#Connection 3
+connection node_3;
+Select * from t1 order by f1;
+f1
+node1_committed_before
+node1_committed_before
+node1_committed_during
+node1_committed_during
+node2_committed_before
+node2_committed_before
+node3_committed_after
+node3_committed_after
+#Connection 2
+connection node_2;
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-6,2-2-7,2-3-8
+#Connection 3
+connection node_3;
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-6,2-2-7,2-3-8
+#Connection 1
+connection node_1;
+SET AUTOCOMMIT=ON;
+#Connection 2
+connection node_2;
+SET AUTOCOMMIT=ON;
+#Connection 3
+connection node_3;
+SET AUTOCOMMIT=ON;
+#Connection 2
+connection node_2;
+STOP slave;
+INSERT INTO t1 VALUES ('node2_slave_stoped');
+#Connection 1
+connection node_1;
+INSERT INTO t1 VALUES ('node1_normal_entry');
+include/save_master_gtid.inc
+#Connection 2
+connection node_2;
+INSERT INTO t1 VALUES ('node2_slave_stoped_inserted');
+start slave;
+include/sync_with_master_gtid.inc
+INSERT INTO t1 VALUES ('node2_slave_started');
+SELECT count(*) from t1;
+count(*)
+12
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-7,2-3-8,2-2-11
+#Connection 3
+connection node_3;
+SELECT count(*) from t1;
+count(*)
+12
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-7,2-3-8,2-2-11
+#Connection 1
+connection node_1;
+DROP TABLE t2,t1;
+#Connection 2
+connection node_2;
+#Connection 3
+connection node_3;
+#Connection 2
+connection node_2;
+STOP SLAVE;
+RESET SLAVE ALL;
+reset master;
+#Connection 3
+connection node_3;
+reset master;
+#Connection 1
+connection node_1;
+reset master;
diff --git a/mysql-test/suite/galera/r/galera_insert_multi.result b/mysql-test/suite/galera/r/galera_insert_multi.result
index 71921134b03..913dd42403a 100644
--- a/mysql-test/suite/galera/r/galera_insert_multi.result
+++ b/mysql-test/suite/galera/r/galera_insert_multi.result
@@ -51,7 +51,7 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
ROLLBACK;
INSERT INTO t1 VALUES (1), (2);
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
diff --git a/mysql-test/suite/galera/r/galera_ist_progress.result b/mysql-test/suite/galera/r/galera_ist_progress.result
index 9fc7febbea5..ed36a217624 100644
--- a/mysql-test/suite/galera/r/galera_ist_progress.result
+++ b/mysql-test/suite/galera/r/galera_ist_progress.result
@@ -1,6 +1,10 @@
+connection node_2;
SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1';
+connection node_1;
+connection node_2;
SET SESSION wsrep_on = OFF;
SET SESSION wsrep_on = ON;
+connection node_1;
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (2);
@@ -12,8 +16,13 @@ INSERT INTO t1 VALUES (7);
INSERT INTO t1 VALUES (8);
INSERT INTO t1 VALUES (9);
INSERT INTO t1 VALUES (10);
+connection node_2;
SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0';
+connection node_1;
+connection node_2;
+connection node_1;
include/assert_grep.inc [Receiving IST: 11 writesets, seqnos]
include/assert_grep.inc [Receiving IST\.\.\. 0\.0% \( 0/11 events\) complete]
include/assert_grep.inc [Receiving IST\.\.\.100\.0% \(11/11 events\) complete]
+connection node_1;
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_many_columns.result b/mysql-test/suite/galera/r/galera_many_columns.result
index 527e1a0b519..db8a8f5ec9d 100644
--- a/mysql-test/suite/galera/r/galera_many_columns.result
+++ b/mysql-test/suite/galera/r/galera_many_columns.result
@@ -19,7 +19,7 @@ UPDATE t1 SET f2 = 'CDE' WHERE f1 = 'XYZ' AND f1017 = 'XYZ';
COMMIT;
connection node_1;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
ROLLBACK;
connection node_2;
ROLLBACK;
diff --git a/mysql-test/suite/galera/r/galera_many_indexes.result b/mysql-test/suite/galera/r/galera_many_indexes.result
index 7b935eb66ba..5691eef4c00 100644
--- a/mysql-test/suite/galera/r/galera_many_indexes.result
+++ b/mysql-test/suite/galera/r/galera_many_indexes.result
@@ -129,5 +129,5 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_many_rows.result b/mysql-test/suite/galera/r/galera_many_rows.result
index 612ecc6a188..b06925fea60 100644
--- a/mysql-test/suite/galera/r/galera_many_rows.result
+++ b/mysql-test/suite/galera/r/galera_many_rows.result
@@ -35,6 +35,6 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
DROP TABLE t1;
DROP TABLE ten;
diff --git a/mysql-test/suite/galera/r/galera_many_tables_nopk.result b/mysql-test/suite/galera/r/galera_many_tables_nopk.result
index b0983fe8289..573ce758a13 100644
--- a/mysql-test/suite/galera/r/galera_many_tables_nopk.result
+++ b/mysql-test/suite/galera/r/galera_many_tables_nopk.result
@@ -18,6 +18,6 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
DROP SCHEMA test;
CREATE SCHEMA test;
diff --git a/mysql-test/suite/galera/r/galera_many_tables_pk.result b/mysql-test/suite/galera/r/galera_many_tables_pk.result
index 31345a4b10e..67624d5edb0 100644
--- a/mysql-test/suite/galera/r/galera_many_tables_pk.result
+++ b/mysql-test/suite/galera/r/galera_many_tables_pk.result
@@ -23,7 +23,7 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
include/diff_servers.inc [servers=1 2]
DROP SCHEMA test;
CREATE SCHEMA test;
diff --git a/mysql-test/suite/galera/r/galera_mdl_race.result b/mysql-test/suite/galera/r/galera_mdl_race.result
index 79f1ccead0a..048b2c46a67 100644
--- a/mysql-test/suite/galera/r/galera_mdl_race.result
+++ b/mysql-test/suite/galera/r/galera_mdl_race.result
@@ -28,7 +28,7 @@ SET DEBUG_SYNC = "now SIGNAL signal.wsrep_before_mdl_wait";
SET DEBUG_SYNC = "now SIGNAL signal.wsrep_after_BF_victim_lock";
UNLOCK TABLES;
connection node_1;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'a';
COUNT(*) = 1
1
diff --git a/mysql-test/suite/galera/r/galera_nopk_bit.result b/mysql-test/suite/galera/r/galera_nopk_bit.result
index b670781c9be..21da039df09 100644
--- a/mysql-test/suite/galera/r/galera_nopk_bit.result
+++ b/mysql-test/suite/galera/r/galera_nopk_bit.result
@@ -28,6 +28,6 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
DROP TABLE t1;
DROP TABLE t2;
diff --git a/mysql-test/suite/galera/r/galera_nopk_blob.result b/mysql-test/suite/galera/r/galera_nopk_blob.result
index 55d369e3077..53e04f72d1e 100644
--- a/mysql-test/suite/galera/r/galera_nopk_blob.result
+++ b/mysql-test/suite/galera/r/galera_nopk_blob.result
@@ -28,6 +28,6 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
DROP TABLE t1;
DROP TABLE t2;
diff --git a/mysql-test/suite/galera/r/galera_nopk_large_varchar.result b/mysql-test/suite/galera/r/galera_nopk_large_varchar.result
index 720e93fc42c..a83cf7f2d91 100644
--- a/mysql-test/suite/galera/r/galera_nopk_large_varchar.result
+++ b/mysql-test/suite/galera/r/galera_nopk_large_varchar.result
@@ -31,6 +31,6 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
DROP TABLE t1;
DROP TABLE t2;
diff --git a/mysql-test/suite/galera/r/galera_nopk_unicode.result b/mysql-test/suite/galera/r/galera_nopk_unicode.result
index 8b7a094edf2..b2a8bb63df9 100644
--- a/mysql-test/suite/galera/r/galera_nopk_unicode.result
+++ b/mysql-test/suite/galera/r/galera_nopk_unicode.result
@@ -19,7 +19,7 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
SELECT f1 = 'текÑÑ‚2' FROM t1;
f1 = 'текÑÑ‚2'
1
diff --git a/mysql-test/suite/galera/r/galera_parallel_autoinc_largetrx.result b/mysql-test/suite/galera/r/galera_parallel_autoinc_largetrx.result
index 22f16a29796..827b2aa9dac 100644
--- a/mysql-test/suite/galera/r/galera_parallel_autoinc_largetrx.result
+++ b/mysql-test/suite/galera/r/galera_parallel_autoinc_largetrx.result
@@ -22,7 +22,7 @@ COUNT(DISTINCT f1)
SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE
USER = 'system user' AND STATE NOT LIKE 'InnoDB%';
COUNT(*)
-5
+3
connection default;
DROP TABLE t1;
DROP TABLE ten;
diff --git a/mysql-test/suite/galera/r/galera_pk_bigint_signed.result b/mysql-test/suite/galera/r/galera_pk_bigint_signed.result
index f0d8586b27b..807ab62c548 100644
--- a/mysql-test/suite/galera/r/galera_pk_bigint_signed.result
+++ b/mysql-test/suite/galera/r/galera_pk_bigint_signed.result
@@ -27,6 +27,6 @@ COMMIT;
SET AUTOCOMMIT=ON;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
SET AUTOCOMMIT=ON;
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_pk_bigint_unsigned.result b/mysql-test/suite/galera/r/galera_pk_bigint_unsigned.result
index 9c878c1a1a1..c94b7e2314a 100644
--- a/mysql-test/suite/galera/r/galera_pk_bigint_unsigned.result
+++ b/mysql-test/suite/galera/r/galera_pk_bigint_unsigned.result
@@ -24,6 +24,6 @@ COMMIT;
SET AUTOCOMMIT=ON;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
SET AUTOCOMMIT=ON;
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_serializable.result b/mysql-test/suite/galera/r/galera_serializable.result
index f82adbbd1db..be3f93a081f 100644
--- a/mysql-test/suite/galera/r/galera_serializable.result
+++ b/mysql-test/suite/galera/r/galera_serializable.result
@@ -9,7 +9,7 @@ connection node_2;
INSERT INTO t1 VALUES (1,1);
connection node_1;
SELECT * FROM t1;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
ROLLBACK;
DELETE FROM t1;
connection node_1;
@@ -22,7 +22,7 @@ connection node_2;
UPDATE t1 SET f2 = 2;
connection node_1;
UPDATE t1 SET f2 = 3;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
ROLLBACK;
DELETE FROM t1;
connection node_1;
@@ -33,5 +33,5 @@ connection node_2;
INSERT INTO t1 VALUES (1,2);
connection node_1;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_toi_drop_database.result b/mysql-test/suite/galera/r/galera_toi_drop_database.result
index e61e73806e2..6d88c8ea230 100644
--- a/mysql-test/suite/galera/r/galera_toi_drop_database.result
+++ b/mysql-test/suite/galera/r/galera_toi_drop_database.result
@@ -14,9 +14,9 @@ INSERT INTO t2 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, te
connection node_2;
DROP DATABASE database1;;
connection node_1;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
connection node_1a;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
connection node_2;
connection node_1;
SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'database1';
diff --git a/mysql-test/suite/galera/r/galera_toi_lock_exclusive.result b/mysql-test/suite/galera/r/galera_toi_lock_exclusive.result
index 5aba1eae2e8..f5cc14ed0f1 100644
--- a/mysql-test/suite/galera/r/galera_toi_lock_exclusive.result
+++ b/mysql-test/suite/galera/r/galera_toi_lock_exclusive.result
@@ -8,7 +8,7 @@ connection node_2a;
ALTER TABLE t1 ADD COLUMN f2 INTEGER, LOCK=EXCLUSIVE;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
connection node_1;
INSERT INTO t1 VALUES (2, 2);
SELECT COUNT(*) = 2 FROM t1;
diff --git a/mysql-test/suite/galera/r/galera_toi_truncate.result b/mysql-test/suite/galera/r/galera_toi_truncate.result
index a53261eafd5..933379cade5 100644
--- a/mysql-test/suite/galera/r/galera_toi_truncate.result
+++ b/mysql-test/suite/galera/r/galera_toi_truncate.result
@@ -9,7 +9,7 @@ connection node_1;
TRUNCATE TABLE t1;;
connection node_1;
connection node_2;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
connection node_2;
SELECT COUNT(*) = 0 FROM t1;
COUNT(*) = 0
diff --git a/mysql-test/suite/galera/r/galera_unicode_pk.result b/mysql-test/suite/galera/r/galera_unicode_pk.result
index 20e903c7778..0e8965a76e3 100644
--- a/mysql-test/suite/galera/r/galera_unicode_pk.result
+++ b/mysql-test/suite/galera/r/galera_unicode_pk.result
@@ -18,7 +18,7 @@ connection node_1;
COMMIT;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
SELECT f1 = 'текÑÑ‚2' FROM t1;
f1 = 'текÑÑ‚2'
1
@@ -35,6 +35,6 @@ connection node_2;
COMMIT;
connection node_1;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
COMMIT;
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_var_auto_inc_control_off.result b/mysql-test/suite/galera/r/galera_var_auto_inc_control_off.result
index bdc4ecb0225..ba117b4c2d5 100644
--- a/mysql-test/suite/galera/r/galera_var_auto_inc_control_off.result
+++ b/mysql-test/suite/galera/r/galera_var_auto_inc_control_off.result
@@ -59,7 +59,7 @@ connection node_1a;
COMMIT;
connection node_2a;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
connection node_1a;
SELECT * FROM t1;
f1 node
diff --git a/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result b/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result
index 5377a0af1b6..4db4e539c50 100644
--- a/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result
+++ b/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result
@@ -5,6 +5,12 @@ CREATE TABLE t1 (f1 INTEGER) Engine=InnoDB;
SET GLOBAL innodb_disallow_writes=ON;
INSERT INTO t1 VALUES (1);;
connection node_1a;
+SELECT COUNT(*) = 1 FROM t1;
+COUNT(*) = 1
+0
+SELECT COUNT(*) = 1 FROM t1;
+COUNT(*) = 1
+0
SET GLOBAL innodb_disallow_writes=OFF;
connection node_1;
SELECT COUNT(*) = 1 FROM t1;
diff --git a/mysql-test/suite/galera/r/galera_var_node_address.result b/mysql-test/suite/galera/r/galera_var_node_address.result
index 8ce6a5e01a1..b8076958532 100644
--- a/mysql-test/suite/galera/r/galera_var_node_address.result
+++ b/mysql-test/suite/galera/r/galera_var_node_address.result
@@ -1,5 +1,6 @@
call mtr.add_suppression("WSREP: Stray state UUID msg: .* current group state WAIT_STATE_UUID .*");
call mtr.add_suppression("WSREP: Protocol violation. JOIN message sender .* is not in state transfer (.*). Message ignored.");
+call mtr.add_suppression("WSREP: Sending JOIN failed: -[0-9]+ (Transport endpoint is not connected). Will retry in new primary component.");
SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
VARIABLE_VALUE = 4
1
diff --git a/mysql-test/suite/galera/r/galera_wsrep_log_conficts.result b/mysql-test/suite/galera/r/galera_wsrep_log_conficts.result
index 4c33d9ac6ce..fa49d8c57c2 100644
--- a/mysql-test/suite/galera/r/galera_wsrep_log_conficts.result
+++ b/mysql-test/suite/galera/r/galera_wsrep_log_conficts.result
@@ -20,6 +20,6 @@ connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
connection node_2a;
connection node_2;
COMMIT;
-ERROR 40001: wsrep aborted transaction
+ERROR 40001: Deadlock: wsrep aborted transaction
include/assert_grep.inc [cluster conflict due to high priority abort for threads]
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/query_cache.result b/mysql-test/suite/galera/r/query_cache.result
index 4aaae2997f3..d497fc87544 100644
--- a/mysql-test/suite/galera/r/query_cache.result
+++ b/mysql-test/suite/galera/r/query_cache.result
@@ -820,6 +820,9 @@ Qcache_queries_in_cache 1
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 9
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 21
insert delayed into t1 values (4);
select a from t1;
a
@@ -870,6 +873,9 @@ Qcache_queries_in_cache 0
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 9
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 22
# On node-2
connection node_2;
show global variables like "query_cache_min_res_unit";
@@ -916,12 +922,15 @@ a
1
2
3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 11
-show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
Variable_name Value
-Qcache_queries_in_cache 2
+Qcache_inserts 24
# On node-2
connection node_2;
select * from t1;
@@ -944,12 +953,12 @@ a
1
2
3
-show status like "Qcache_hits";
-Variable_name Value
-Qcache_hits 10
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 2
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 10
drop table t1;
select a from t2;
a
@@ -961,12 +970,15 @@ a
1
2
3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 11
-show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
Variable_name Value
-Qcache_queries_in_cache 2
+Qcache_inserts 18
set GLOBAL query_cache_min_res_unit=default;
show global variables like "query_cache_min_res_unit";
Variable_name Value
@@ -983,12 +995,15 @@ a
1
2
3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
-show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
Variable_name Value
-Qcache_queries_in_cache 2
+Qcache_inserts 25
drop table t2;
set GLOBAL query_cache_min_res_unit=default;
show global variables like "query_cache_min_res_unit";
@@ -1010,6 +1025,9 @@ Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 27
# On node-2
connection node_2;
select "aaa" from t1;
@@ -1024,6 +1042,9 @@ Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 11
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 20
drop table t1;
# On node-1
connection node_1;
@@ -1322,6 +1343,9 @@ select count(*) from t1;
count(*)
140
drop table t1;
+#
+# INTO OUTFILE/DUMPFILE test
+#
# On node-1
connection node_1;
create table t1 (a int) engine=innodb;
@@ -1342,7 +1366,13 @@ Qcache_queries_in_cache 0
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 36
drop table t1;
+#
+# Test of SQL_SELECT_LIMIT
+#
# On node-1
connection node_1;
create table t1 (a int) engine=innodb;
@@ -1367,6 +1397,9 @@ Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 38
SET SQL_SELECT_LIMIT=DEFAULT;
# On node-2
connection node_2;
@@ -1392,6 +1425,9 @@ Variable_name Value
Qcache_hits 11
SET SQL_SELECT_LIMIT=DEFAULT;
drop table t1;
+#
+# WRITE LOCK & QC
+#
# On node-1
connection node_1;
create table t1 (a int not null) engine=innodb;
@@ -1408,6 +1444,9 @@ Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 40
lock table t1 write, t2 read;
show status like "Qcache_queries_in_cache";
Variable_name Value
@@ -1431,6 +1470,9 @@ Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 41
unlock table;
drop view v1;
set query_cache_wlock_invalidate=default;
@@ -1471,10 +1513,16 @@ Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 11
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 34
unlock table;
drop view v1;
set query_cache_wlock_invalidate=default;
drop table t1,t2;
+#
+# Hiding real table stored in query cache by temporary table
+#
# On node-1
connection node_1;
create table t1 (id int primary key) engine=innodb;
@@ -1498,92 +1546,119 @@ SELECT a,'Â','â'='Â' FROM t1;
a  'â'='Â'
à Â 0
à Â 0
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
-show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
Variable_name Value
-Qcache_queries_in_cache 1
+Qcache_inserts 43
set collation_connection=koi8r_bin;
SELECT a,'Â','â'='Â' FROM t1;
a  'â'='Â'
à Â 0
à Â 0
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
-show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
Variable_name Value
-Qcache_queries_in_cache 2
+Qcache_inserts 44
set character_set_client=cp1251;
SELECT a,'Â','â'='Â' FROM t1;
a ç? 'ç?'='ç?'
à ç? 1
à ç? 1
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
-show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
Variable_name Value
-Qcache_queries_in_cache 3
+Qcache_inserts 45
set character_set_results=cp1251;
SELECT a,'Â','â'='Â' FROM t1;
a � 'â'='Â'
ö Ã? 1
ö Ã? 1
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 4
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
-show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
Variable_name Value
-Qcache_queries_in_cache 4
+Qcache_inserts 46
SET NAMES default;
# On node-2
connection node_2;
+#
+# Run select
+#
SELECT a,'Â','â'='Â' FROM t1;
a  'â'='Â'
? Â 0
? Â 0
-show status like "Qcache_hits";
-Variable_name Value
-Qcache_hits 11
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 11
set collation_connection=koi8r_bin;
SELECT a,'Â','â'='Â' FROM t1;
a ?? 'â'='Â'
? ?? 1
? ?? 1
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 11
-show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
Variable_name Value
-Qcache_queries_in_cache 2
+Qcache_inserts 36
set character_set_client=cp1251;
SELECT a,'Â','â'='Â' FROM t1;
a ?? '??'='?‚'
? ?? 1
? ?? 1
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 11
-show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
Variable_name Value
-Qcache_queries_in_cache 3
+Qcache_inserts 37
set character_set_results=cp1251;
SELECT a,'Â','â'='Â' FROM t1;
a � 'â'='Â'
ö Ã? 1
ö Ã? 1
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 4
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 11
-show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
Variable_name Value
-Qcache_queries_in_cache 4
+Qcache_inserts 38
drop table t1;
+#
+# Comments before command
+#
# On node-1
connection node_1;
create table t1 (a int) engine=innodb;
@@ -1634,6 +1709,9 @@ show status like "Qcache_hits";
Variable_name Value
Qcache_hits 12
drop table t1;
+#
+# Information schema & query cache test
+#
# On node-1
connection node_1;
set session query_cache_type = 2;
diff --git a/mysql-test/suite/galera/r/sql_log_bin.result b/mysql-test/suite/galera/r/sql_log_bin.result
index 8b208ff82d5..c175a0a0e7a 100644
--- a/mysql-test/suite/galera/r/sql_log_bin.result
+++ b/mysql-test/suite/galera/r/sql_log_bin.result
@@ -7,6 +7,7 @@ INSERT INTO t1 VALUES (1);
# Disable binary logging for current session
SET SQL_LOG_BIN=OFF;
INSERT INTO t1 VALUES (2);
+FLUSH BINARY LOGS;
CREATE TABLE t2(c1 INT PRIMARY KEY) ENGINE=INNODB;
INSERT INTO t2 VALUES (1);
CREATE TABLE test.t3 AS SELECT * from t1;
diff --git a/mysql-test/suite/galera/suite.pm b/mysql-test/suite/galera/suite.pm
index 361743f1243..bad0484be16 100644
--- a/mysql-test/suite/galera/suite.pm
+++ b/mysql-test/suite/galera/suite.pm
@@ -9,8 +9,10 @@ return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" unless defined $::mysqld_variables{'wsrep-on'};
my ($provider) = grep { -f $_ } $ENV{WSREP_PROVIDER},
- "/usr/lib/galera/libgalera_smm.so",
- "/usr/lib64/galera/libgalera_smm.so";
+ "/usr/lib64/galera-3/libgalera_smm.so",
+ "/usr/lib64/galera/libgalera_smm.so",
+ "/usr/lib/galera-3/libgalera_smm.so",
+ "/usr/lib/galera/libgalera_smm.so";
return "No wsrep provider library" unless -f $provider;
diff --git a/mysql-test/suite/galera/t/MW-388.test b/mysql-test/suite/galera/t/MW-388.test
new file mode 100644
index 00000000000..de1ac52bf3e
--- /dev/null
+++ b/mysql-test/suite/galera/t/MW-388.test
@@ -0,0 +1,76 @@
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+--connection node_1
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(255)) Engine=InnoDB;
+
+DELIMITER |;
+CREATE PROCEDURE insert_proc ()
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+ BEGIN
+ GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;
+ END;
+ INSERT INTO t1 VALUES (1, 'node 1'),(2, 'node 1');
+ INSERT INTO t1 VALUES (3, 'node 1');
+END|
+DELIMITER ;|
+
+# We need two slave threads here to guarantee progress.
+# If we use only one thread the following could happen
+# in node_1:
+# We block the only slave thread in wsrep_apply_cb and we
+# issue an INSERT (by calling the stored procedure) that will
+# try to acquire galera's local monitor in pre_commit().
+# This usually works fine, except for when a commit cut event
+# sneaks in the slave queue and gets a local seqno smaller than
+# that of the INSERT. Because there is only one slave thread,
+# commit cut is not processed and therefore does not advance
+# local monitor, and our INSERT remains stuck there.
+SET GLOBAL wsrep_slave_threads = 2;
+SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb";
+
+--connection node_2
+--send INSERT INTO t1 VALUES (1, 'node 2');
+
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+--connection node_1a
+SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+
+--connection node_1
+SET SESSION wsrep_sync_wait = 0;
+SET SESSION DEBUG_SYNC = 'wsrep_after_replication SIGNAL wsrep_after_replication_reached WAIT_FOR wsrep_after_replication_continue';
+--send CALL insert_proc ();
+
+--connection node_1a
+SET SESSION DEBUG_SYNC = "now WAIT_FOR wsrep_after_replication_reached";
+
+
+SET GLOBAL DEBUG_DBUG = "";
+SET DEBUG_SYNC = "now SIGNAL wsrep_after_replication_continue";
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+
+--connection node_2
+--reap
+
+--connection node_1
+# We expect no errors here, because the handler in insert_proc() caught the deadlock error
+--reap
+SELECT @errno = 1213;
+SELECT * FROM t1;
+
+--connection node_2
+SELECT * FROM t1;
+
+--connection node_1
+SET GLOBAL wsrep_slave_threads = DEFAULT;
+DROP TABLE t1;
+DROP PROCEDURE insert_proc;
+
+SET GLOBAL debug_dbug = NULL;
+SET debug_sync='RESET';
+
+# Make sure no pending signals are leftover to surprise subsequent tests.
+SELECT @@debug_sync;
diff --git a/mysql-test/suite/galera/t/galera_bf_lock_wait.test b/mysql-test/suite/galera/t/galera_bf_lock_wait.test
new file mode 100644
index 00000000000..e3a9077a888
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_bf_lock_wait.test
@@ -0,0 +1,52 @@
+--source include/galera_cluster.inc
+--source include/big_test.inc
+
+CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2;
+ALTER TABLE t1 add primary key(a);
+
+DELIMITER |;
+
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLEXCEPTION rollback;
+ WHILE 1 DO
+ start transaction;
+ update t1 set b=connection_id() where a=1;
+ commit;
+ END WHILE;
+END|
+
+
+DELIMITER ;|
+
+--connect node_1_p1, 127.0.0.1, root, , test, $NODE_MYPORT_1
+send call p1;
+--connect node_1_p2, 127.0.0.1, root, , test, $NODE_MYPORT_1
+send call p1;
+--connect node_2_p1, 127.0.0.1, root, , test, $NODE_MYPORT_2
+send call p1;
+--connect node_2_p2, 127.0.0.1, root, , test, $NODE_MYPORT_2
+send call p1;
+
+connection default;
+let $counter=10;
+let $sleep_period=10;
+
+echo checking error log for 'BF lock wait long' message for $counter times every $sleep_period seconds ...;
+while($counter > 0)
+{
+--disable_query_log
+--disable_result_log
+ eval do sleep($sleep_period);
+--enable_query_log
+--enable_result_log
+
+# use error 0,1 instead if want test to continue
+ --error 1
+ exec grep 'BF lock wait long' $MYSQLTEST_VARDIR/log/mysqld.*.err;
+ dec $counter;
+}
+
+drop table t1;
+drop procedure p1;
+
diff --git a/mysql-test/suite/galera/t/galera_binlog_event_max_size_max-master.opt b/mysql-test/suite/galera/t/galera_binlog_event_max_size_max-master.opt
index a36d21315a6..576829cfef8 100644
--- a/mysql-test/suite/galera/t/galera_binlog_event_max_size_max-master.opt
+++ b/mysql-test/suite/galera/t/galera_binlog_event_max_size_max-master.opt
@@ -1 +1 @@
---binlog-row-event-max-size=4294967295
+--binlog-row-event-max-size=4294967040
diff --git a/mysql-test/suite/galera/t/galera_defaults.test b/mysql-test/suite/galera/t/galera_defaults.test
index 32fc24097d2..facc5180f2f 100644
--- a/mysql-test/suite/galera/t/galera_defaults.test
+++ b/mysql-test/suite/galera/t/galera_defaults.test
@@ -56,6 +56,7 @@ ORDER BY VARIABLE_NAME;
$wsrep_provider_options =~ s/evs\.evict = .*?;/<EVS_EVICT>;/sgio;
$wsrep_provider_options =~ s/signal = .*?;\s*//sgio;
$wsrep_provider_options =~ s/dbug = .*?;\s*//sgio;
+ $wsrep_provider_options =~ s/repl.proto_max = .*?;\s*/<REPL_PROTO_MAX>;/sgio;
print $wsrep_provider_options."\n";
EOF
diff --git a/mysql-test/suite/galera/t/galera_ftwrl.test b/mysql-test/suite/galera/t/galera_ftwrl.test
index de8310e52d2..739255609ee 100644
--- a/mysql-test/suite/galera/t/galera_ftwrl.test
+++ b/mysql-test/suite/galera/t/galera_ftwrl.test
@@ -29,12 +29,11 @@ SELECT * FROM t1;
UNLOCK TABLES;
-SHOW TABLES;
-SELECT COUNT(*) = 1 FROM t1;
-
--disable_query_log
--eval SET GLOBAL wsrep_provider_options = "$wsrep_provider_options_orig";
--enable_query_log
-DROP TABLE t1;
+SHOW TABLES;
+SELECT COUNT(*) = 1 FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/galera_gtid_slave.cnf b/mysql-test/suite/galera/t/galera_gtid_slave.cnf
new file mode 100644
index 00000000000..409d0d1609a
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_gtid_slave.cnf
@@ -0,0 +1,18 @@
+!include ../galera_2nodes_as_slave.cnf
+
+[mysqld]
+log-bin=mysqld-bin
+log-slave-updates
+binlog-format=ROW
+
+[mysqld.1]
+gtid-domain-id=1
+[mysqld.2]
+gtid-domain-id=2
+wsrep_gtid_mode=1
+wsrep_gtid_domain_id=2
+[mysqld.3]
+gtid-domain-id=2
+wsrep_gtid_mode=1
+wsrep_gtid_domain_id=2
+
diff --git a/mysql-test/suite/galera/t/galera_gtid_slave.test b/mysql-test/suite/galera/t/galera_gtid_slave.test
new file mode 100644
index 00000000000..8ef87452a5b
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_gtid_slave.test
@@ -0,0 +1,78 @@
+#
+# Test Galera as a slave to a MariaDB master using GTIDs
+#
+# suite/galera/galera_2nodes_as_slave.cnf describes the setup of the nodes
+# suite/galera/t/galera_as_slave_gtid.cnf has the GTID options
+#
+# In addition to performing DDL and DML, we check that the gtid of the master is preserved inside the cluster
+#
+
+--source include/have_innodb.inc
+
+# As node #1 is not a Galera node, we connect to node #2 in order to run include/galera_cluster.inc
+--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
+--source include/galera_cluster.inc
+
+--connection node_2
+--disable_query_log
+--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_1;
+--enable_query_log
+START SLAVE;
+
+--connection node_1
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1);
+
+#multi stmt trans
+begin;
+insert into t2 values(21);
+insert into t2 values(22);
+commit;
+
+SELECT @@global.gtid_binlog_state;
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+--source include/wait_condition.inc
+
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
+--source include/wait_condition.inc
+--sleep 1
+INSERT INTO t1 VALUES(2);
+INSERT INTO t1 VALUES(3);
+SELECT @@global.gtid_binlog_state;
+
+--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES(4);
+SELECT @@global.gtid_binlog_state;
+
+--connection node_1
+DROP TABLE t1,t2;
+reset master;
+#
+# Unfortunately without the sleep below the following statement fails with "query returned no rows", which
+# is difficult to understand given that it is an aggregate query. A "query execution was interrupted"
+# warning is also reported by MTR, which is also weird.
+#
+
+--sleep 1
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+--source include/wait_condition.inc
+
+--connection node_2
+STOP SLAVE;
+RESET SLAVE ALL;
+reset master;
+
+--connection node_3
+reset master;
diff --git a/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.cnf b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.cnf
new file mode 100644
index 00000000000..bb9c8e84f1b
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.cnf
@@ -0,0 +1,18 @@
+!include ../galera_2nodes_as_slave.cnf
+
+[mysqld]
+log-bin=mysqld-bin
+log-slave-updates
+binlog-format=ROW
+wsrep_sst_method=rsync
+[mysqld.1]
+gtid-domain-id=1
+[mysqld.2]
+gtid-domain-id=2
+wsrep_gtid_mode=1
+wsrep_gtid_domain_id=2
+[mysqld.3]
+gtid-domain-id=2
+wsrep_gtid_mode=1
+wsrep_gtid_domain_id=2
+
diff --git a/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test
new file mode 100644
index 00000000000..3fe94ad16b7
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test
@@ -0,0 +1,207 @@
+#
+# Test Galera as a slave to a MariaDB master using GTIDs
+#
+# suite/galera/galera_2nodes_as_slave.cnf describes the setup of the nodes
+#
+# In addition to performing DDL and DML, we check that the gtid of the master is preserved inside the cluster
+#
+
+--source include/big_test.inc
+--source include/have_innodb.inc
+# As node #1 is not a Galera node, we connect to node #2 in order to run include/galera_cluster.inc
+--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
+--source include/galera_cluster.inc
+
+--echo #Connection 2
+--connection node_2
+--disable_query_log
+--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_1,master_use_gtid=slave_pos;
+--enable_query_log
+START SLAVE;
+--sleep 1
+
+
+--echo #Connection 1
+--connection node_1
+CREATE TABLE t2 (f1 INTEGER PRIMARY KEY, f2 int unique) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(1,11);
+INSERT INTO t2 VALUES(2,22);
+INSERT INTO t2 VALUES(3,33);
+
+SELECT @@global.gtid_binlog_state;
+--source include/save_master_gtid.inc
+
+--echo #Connection 2
+--connection node_2
+--source include/sync_with_master_gtid.inc
+SELECT @@global.gtid_binlog_state;
+
+INSERT INTO t2 VALUES(4,44);
+INSERT INTO t2 VALUES(5,55);
+INSERT INTO t2 VALUES(6,66);
+SELECT @@global.gtid_binlog_state;
+
+--echo #Connection 3
+--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME= 't2';
+--source include/wait_condition.inc
+--let $wait_condition = SELECT COUNT(*) = 6 FROM t2;
+--source include/wait_condition.inc
+
+INSERT INTO t2 VALUES(7,77);
+INSERT INTO t2 VALUES(8,88);
+SELECT @@global.gtid_binlog_state;
+
+#Perform SST
+--echo #Connection 1
+--connection node_1
+CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+COMMIT;
+--source include/save_master_gtid.inc
+
+--echo #Connection 2
+--connection node_2
+--source include/sync_with_master_gtid.inc
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+COMMIT;
+
+--echo #Connection 3
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME= 't1';
+--source include/wait_condition.inc
+--let $wait_condition = SELECT COUNT(*) = 4 FROM t1;
+--source include/wait_condition.inc
+--let $node_1= node_2
+--let $node_2= node_3
+--source include/auto_increment_offset_save.inc
+--echo Shutting down server ...
+--source include/shutdown_mysqld.inc
+
+
+--echo #Connection 2
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
+--source include/wait_condition.inc
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+COMMIT;
+
+--echo #Connection 3
+--connection node_3
+--echo Starting server ...
+--source include/start_mysqld.inc
+--source include/wait_until_ready.inc
+--source include/auto_increment_offset_restore.inc
+
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node3_committed_after');
+INSERT INTO t1 VALUES ('node3_committed_after');
+COMMIT;
+
+--echo #Connection 2
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+Select * from t1 order by f1;
+
+--echo #Connection 3
+--connection node_3
+Select * from t1 order by f1;
+
+#SST Done
+--sleep 1
+--echo #Connection 2
+--connection node_2
+SELECT @@global.gtid_binlog_state;
+
+--echo #Connection 3
+--connection node_3
+SELECT @@global.gtid_binlog_state;
+
+--echo #Connection 1
+--connection node_1
+SET AUTOCOMMIT=ON;
+#drop table t1;
+#CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
+
+--echo #Connection 2
+--connection node_2
+SET AUTOCOMMIT=ON;
+--echo #Connection 3
+--connection node_3
+SET AUTOCOMMIT=ON;
+
+#
+#stop slave on node 2
+--echo #Connection 2
+--connection node_2
+STOP slave;
+--sleep 1
+INSERT INTO t1 VALUES ('node2_slave_stoped');
+
+--echo #Connection 1
+--connection node_1
+INSERT INTO t1 VALUES ('node1_normal_entry');
+--source include/save_master_gtid.inc
+
+#start slave
+--echo #Connection 2
+--connection node_2
+INSERT INTO t1 VALUES ('node2_slave_stoped_inserted');
+start slave;
+--source include/sync_with_master_gtid.inc
+INSERT INTO t1 VALUES ('node2_slave_started');
+SELECT count(*) from t1;
+SELECT @@global.gtid_binlog_state;
+
+--echo #Connection 3
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 12 FROM t1;
+--source include/wait_condition.inc
+SELECT count(*) from t1;
+SELECT @@global.gtid_binlog_state;
+
+--echo #Connection 1
+--connection node_1
+DROP TABLE t2,t1;
+
+# Unfortunately without the sleep below the following statement fails with "query returned no rows", which
+# is difficult to understand given that it is an aggregate query. A "query execution was interrupted"
+# warning is also reported by MTR, which is also weird.
+#
+
+--sleep 3
+
+--echo #Connection 2
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2';
+--source include/wait_condition.inc
+
+--echo #Connection 3
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+--source include/wait_condition.inc
+
+--echo #Connection 2
+--connection node_2
+STOP SLAVE;
+RESET SLAVE ALL;
+reset master;
+
+--echo #Connection 3
+--connection node_3
+reset master;
+
+--echo #Connection 1
+--connection node_1
+reset master;
diff --git a/mysql-test/suite/galera/t/galera_suspend_slave.test b/mysql-test/suite/galera/t/galera_suspend_slave.test
index dcc4a8d14c3..aa4543cf81c 100644
--- a/mysql-test/suite/galera/t/galera_suspend_slave.test
+++ b/mysql-test/suite/galera/t/galera_suspend_slave.test
@@ -25,7 +25,7 @@ CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
my $pid_filename = $ENV{'NODE_2_PIDFILE'};
my $mysqld_pid = `cat $pid_filename`;
chomp($mysqld_pid);
- system("kill -19 $mysqld_pid");
+ system("kill -SIGSTOP $mysqld_pid");
exit(0);
EOF
@@ -37,7 +37,7 @@ INSERT INTO t1 VALUES (1);
my $pid_filename = $ENV{'NODE_2_PIDFILE'};
my $mysqld_pid = `cat $pid_filename`;
chomp($mysqld_pid);
- system("kill -18 $mysqld_pid");
+ system("kill -SIGCONT $mysqld_pid");
exit(0);
EOF
diff --git a/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test b/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test
index 3606075e7a8..65b55435a9e 100644
--- a/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test
+++ b/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test
@@ -18,8 +18,10 @@ SET GLOBAL innodb_disallow_writes=ON;
--send INSERT INTO t1 VALUES (1);
--connection node_1a
+SELECT COUNT(*) = 1 FROM t1;
let $wait_condition = SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO = 'INSERT INTO t1 VALUES (1)' AND State = 'Commit';
--source include/wait_condition.inc
+SELECT COUNT(*) = 1 FROM t1;
SET GLOBAL innodb_disallow_writes=OFF;
diff --git a/mysql-test/suite/galera/t/galera_var_node_address.test b/mysql-test/suite/galera/t/galera_var_node_address.test
index 3353652d8b9..22e98e3aa82 100644
--- a/mysql-test/suite/galera/t/galera_var_node_address.test
+++ b/mysql-test/suite/galera/t/galera_var_node_address.test
@@ -8,6 +8,7 @@
call mtr.add_suppression("WSREP: Stray state UUID msg: .* current group state WAIT_STATE_UUID .*");
call mtr.add_suppression("WSREP: Protocol violation. JOIN message sender .* is not in state transfer (.*). Message ignored.");
+call mtr.add_suppression("WSREP: Sending JOIN failed: -[0-9]+ (Transport endpoint is not connected). Will retry in new primary component.");
SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
diff --git a/mysql-test/suite/galera/t/query_cache.test b/mysql-test/suite/galera/t/query_cache.test
index e024b308fab..13b21eca6e7 100644
--- a/mysql-test/suite/galera/t/query_cache.test
+++ b/mysql-test/suite/galera/t/query_cache.test
@@ -448,6 +448,7 @@ select * from t1;
select * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+show status like "Qcache_inserts";
insert delayed into t1 values (4);
--sleep 5 # Wait for insert delayed to be executed.
select a from t1;
@@ -474,6 +475,7 @@ show status like "Qcache_hits";
--connection node_1
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+show status like "Qcache_inserts";
#
# Test of min result data unit size changing
@@ -497,8 +499,9 @@ select * from t1;
select * from t1;
select * from t2;
select * from t2;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_inserts";
--echo # On node-2
--connection node_2
@@ -506,13 +509,14 @@ select * from t1;
select * from t1;
select * from t2;
select * from t2;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
drop table t1;
select a from t2;
select a from t2;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_inserts";
set GLOBAL query_cache_min_res_unit=default;
show global variables like "query_cache_min_res_unit";
@@ -520,8 +524,9 @@ show global variables like "query_cache_min_res_unit";
--connection node_1
select a from t2;
select a from t2;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_inserts";
drop table t2;
set GLOBAL query_cache_min_res_unit=default;
show global variables like "query_cache_min_res_unit";
@@ -537,6 +542,7 @@ select "aaa" from t1;
select "AAA" from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+show status like "Qcache_inserts";
--echo # On node-2
--connection node_2
@@ -544,6 +550,7 @@ select "aaa" from t1;
select "AAA" from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+show status like "Qcache_inserts";
drop table t1;
#
@@ -728,9 +735,9 @@ select count(*) from t1;
drop table t1;
-#
-# INTO OUTFILE/DUMPFILE test
-#
+--echo #
+--echo # INTO OUTFILE/DUMPFILE test
+--echo #
--echo # On node-1
--connection node_1
create table t1 (a int) engine=innodb;
@@ -743,14 +750,15 @@ select * from t1 into outfile "query_cache.out.file";
select * from t1 limit 1 into dumpfile "query_cache.dump.file";
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+show status like "Qcache_inserts";
drop table t1;
let $datadir=`select @@datadir`;
--remove_file $datadir/test/query_cache.dump.file
--remove_file $datadir/test/query_cache.out.file
-#
-# Test of SQL_SELECT_LIMIT
-#
+--echo #
+--echo # Test of SQL_SELECT_LIMIT
+--echo #
--echo # On node-1
--connection node_1
create table t1 (a int) engine=innodb;
@@ -762,6 +770,7 @@ SET SQL_SELECT_LIMIT=1;
select * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+show status like "Qcache_inserts";
SET SQL_SELECT_LIMIT=DEFAULT;
--echo # On node-2
@@ -777,9 +786,9 @@ SET SQL_SELECT_LIMIT=DEFAULT;
drop table t1;
-#
-# WRITE LOCK & QC
-#
+--echo #
+--echo # WRITE LOCK & QC
+--echo #
--echo # On node-1
--connection node_1
create table t1 (a int not null) engine=innodb;
@@ -791,6 +800,7 @@ select * from t1;
select * from t2;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+show status like "Qcache_inserts";
lock table t1 write, t2 read;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
@@ -802,6 +812,7 @@ show status like "Qcache_hits";
lock table v1 write;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+show status like "Qcache_inserts";
unlock table;
drop view v1;
set query_cache_wlock_invalidate=default;
@@ -825,15 +836,16 @@ show status like "Qcache_hits";
lock table v1 write;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+show status like "Qcache_inserts";
unlock table;
drop view v1;
set query_cache_wlock_invalidate=default;
drop table t1,t2;
-#
-# Hiding real table stored in query cache by temporary table
-#
+--echo #
+--echo # Hiding real table stored in query cache by temporary table
+--echo #
--echo # On node-1
--connection node_1
create table t1 (id int primary key) engine=innodb;
@@ -866,66 +878,76 @@ INSERT INTO t1 VALUES (_koi8r 0xc3),(_koi8r 0xc3);
# Run select
#
SELECT a,'Â','â'='Â' FROM t1;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_inserts";
#
# Change collation_connection and run the same query again
#
set collation_connection=koi8r_bin;
SELECT a,'Â','â'='Â' FROM t1;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_inserts";
#
# Now change character_set_client and run the same query again
#
set character_set_client=cp1251;
SELECT a,'Â','â'='Â' FROM t1;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_inserts";
#
# And finally change character_set_results and run the same query again
#
set character_set_results=cp1251;
SELECT a,'Â','â'='Â' FROM t1;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_inserts";
SET NAMES default;
--echo # On node-2
--connection node_2
-#
-# Run select
-#
+
+--echo #
+--echo # Run select
+--echo #
+
SELECT a,'Â','â'='Â' FROM t1;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
#
# Change collation_connection and run the same query again
#
set collation_connection=koi8r_bin;
SELECT a,'Â','â'='Â' FROM t1;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_inserts";
#
# Now change character_set_client and run the same query again
#
set character_set_client=cp1251;
SELECT a,'Â','â'='Â' FROM t1;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_inserts";
#
# And finally change character_set_results and run the same query again
#
set character_set_results=cp1251;
SELECT a,'Â','â'='Â' FROM t1;
-show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_inserts";
drop table t1;
-#
-# Comments before command
-#
+--echo #
+--echo # Comments before command
+--echo #
+
--echo # On node-1
--connection node_1
create table t1 (a int) engine=innodb;
@@ -951,9 +973,10 @@ show status like "Qcache_hits";
drop table t1;
-#
-# Information schema & query cache test
-#
+--echo #
+--echo # Information schema & query cache test
+--echo #
+
--echo # On node-1
--connection node_1
set session query_cache_type = 2;
diff --git a/mysql-test/suite/galera/t/sql_log_bin.test b/mysql-test/suite/galera/t/sql_log_bin.test
index 615bc4c30af..9f8f7c84486 100644
--- a/mysql-test/suite/galera/t/sql_log_bin.test
+++ b/mysql-test/suite/galera/t/sql_log_bin.test
@@ -1,5 +1,13 @@
# Test to check the behavior of galera cluster with sql_log_bin=ON|OFF & binary
# logging is disabled. sql_bin_log should not affect galera replication.
+#
+# The following bugfixes are tested:
+#
+# MDEV-9510: Segmentation fault in binlog thread.
+# A scenario otherwise causing a similar segfault is replayed.
+# The test must pass having no crashes.
+# The sequence of sql statements is provided by original
+# sql_log_bin.test augmented with a FLUSH BINLOG LOGS, below.
--source include/galera_cluster.inc
--source include/have_innodb.inc
@@ -15,6 +23,10 @@ INSERT INTO t1 VALUES (1);
--echo # Disable binary logging for current session
SET SQL_LOG_BIN=OFF;
INSERT INTO t1 VALUES (2);
+
+# MDEV-9510: the following binlog rotation due to FLUSH segfaults wo/ the fixes
+FLUSH BINARY LOGS;
+
CREATE TABLE t2(c1 INT PRIMARY KEY) ENGINE=INNODB;
INSERT INTO t2 VALUES (1);
CREATE TABLE test.t3 AS SELECT * from t1;
diff --git a/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf b/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf
new file mode 100644
index 00000000000..3f39b82f7b7
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf
@@ -0,0 +1,122 @@
+# Use default setting for mysqld processes
+!include include/default_mysqld.cnf
+
+[mysqld]
+log-bin
+log-slave-updates
+binlog-format=row
+innodb-autoinc-lock-mode=2
+default-storage-engine=innodb
+wsrep_gtid_mode=1
+gtid_ignore_duplicates
+
+wsrep-on=1
+wsrep-provider=@ENV.WSREP_PROVIDER
+wsrep_node_address=127.0.0.1
+# enforce read-committed characteristics across the cluster
+# wsrep-causal-reads=ON
+# wsrep-sync-wait=15
+
+[mysqld.1]
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+wsrep-cluster-address='gcomm://'
+wsrep_provider_options='base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.1.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.1.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.1.#sst_port'
+
+[mysqld.2]
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port'
+wsrep_provider_options='base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.2.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port'
+
+[mysqld.3]
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port'
+wsrep_provider_options='base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.3.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.3.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.3.#sst_port'
+
+
+[mysqld.4]
+wsrep_cluster_name=cluster2
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+
+wsrep-cluster-address='gcomm://'
+wsrep_provider_options='base_port=@mysqld.4.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.4.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.4.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.4.#sst_port'
+
+[mysqld.5]
+wsrep_cluster_name=cluster2
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.4.#galera_port'
+wsrep_provider_options='base_port=@mysqld.5.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.5.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.5.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.5.#sst_port'
+
+[mysqld.6]
+wsrep_cluster_name=cluster2
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.4.#galera_port'
+wsrep_provider_options='base_port=@mysqld.6.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.6.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.6.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.6.#sst_port'
+
+[ENV]
+NODE_MYPORT_1= @mysqld.1.port
+NODE_MYSOCK_1= @mysqld.1.socket
+
+NODE_MYPORT_2= @mysqld.2.port
+NODE_MYSOCK_2= @mysqld.2.socket
+
+NODE_MYPORT_3= @mysqld.3.port
+NODE_MYSOCK_3= @mysqld.3.socket
+
+NODE_MYPORT_4= @mysqld.4.port
+NODE_MYSOCK_4= @mysqld.4.socket
+
+NODE_MYPORT_5= @mysqld.5.port
+NODE_MYSOCK_5= @mysqld.5.socket
+
+NODE_MYPORT_6= @mysqld.6.port
+NODE_MYSOCK_6= @mysqld.6.socket
+
+NODE_GALERAPORT_1= @mysqld.1.#galera_port
+NODE_GALERAPORT_2= @mysqld.2.#galera_port
+NODE_GALERAPORT_3= @mysqld.3.#galera_port
+NODE_GALERAPORT_4= @mysqld.4.#galera_port
+NODE_GALERAPORT_5= @mysqld.5.#galera_port
+NODE_GALERAPORT_6= @mysqld.6.#galera_port
+
+NODE_SSTPORT_1= @mysqld.1.#sst_port
+NODE_SSTPORT_2= @mysqld.2.#sst_port
+NODE_SSTPORT_3= @mysqld.3.#sst_port
+NODE_SSTPORT_4= @mysqld.4.#sst_port
+NODE_SSTPORT_5= @mysqld.5.#sst_port
+NODE_SSTPORT_6= @mysqld.6.#sst_port
diff --git a/mysql-test/suite/galera_3nodes/include/have_ipv6.inc b/mysql-test/suite/galera_3nodes/include/have_ipv6.inc
new file mode 100644
index 00000000000..560cad03350
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/include/have_ipv6.inc
@@ -0,0 +1,15 @@
+# Check if ipv6 is available.
+#
+--disable_query_log
+--disable_result_log
+connect (checkcon123456789,::1,root,,test);
+if($mysql_errno)
+{
+ skip No IPv6 support;
+}
+connection default;
+disconnect checkcon123456789;
+--enable_result_log
+--enable_query_log
+# end check
+
diff --git a/mysql-test/suite/galera_3nodes/r/galera_gtid_2_cluster.result b/mysql-test/suite/galera_3nodes/r/galera_gtid_2_cluster.result
new file mode 100644
index 00000000000..35ca84119e7
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_gtid_2_cluster.result
@@ -0,0 +1,231 @@
+cluster 1 node 1
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+cluster 1 node 2
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+cluster 1 node 3
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+cluster 2 node 1
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+cluster 2 node 2
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+cluster 2 node 3
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+change master to master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_4, master_use_gtid=current_pos, ignore_server_ids=(12,13);;
+start slave;
+include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+
+select @@gtid_slave_pos;
+@@gtid_slave_pos
+
+change master to master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_1, master_use_gtid=current_pos, ignore_server_ids=(22,23);;
+start slave;
+include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+
+select @@gtid_slave_pos;
+@@gtid_slave_pos
+
+cluster 1 node 1
+create table t1 (cluster_domain_id int ,node_server_id int, seq_no int);
+insert into t1 values (1, 11, 2);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 1
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2
+insert into t1 values (2, 21, 1);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,2-21-1
+select * from t1;
+cluster_domain_id node_server_id seq_no
+1 11 2
+2 21 1
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 node 2
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,2-21-1
+insert into t1 values (1, 12, 3);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,1-12-3,2-21-1
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 node 3
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,1-12-3,2-21-1
+insert into t1 values (1, 13, 4);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 2
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1
+insert into t1 values (2, 22, 2);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1,2-22-2
+#wait for sync cluster 2 and 1
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 3
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1,2-22-2
+insert into t1 values (2, 23, 3);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1,2-22-2,2-23-3
+#wait for sync cluster 2 and 1
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 node 1
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1,2-22-2,2-23-3
+drop table t1;
+stop slave;
+reset slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+cluster 2 node 1
+stop slave;
+reset slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+reset master;
+reset master;
+reset master;
+reset master;
+change master to master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_6, master_use_gtid=current_pos, ignore_server_ids=(12,13);;
+start slave;
+include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+
+select @@gtid_slave_pos;
+@@gtid_slave_pos
+
+change master to master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_3, master_use_gtid=current_pos, ignore_server_ids=(22,23);;
+start slave;
+include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+
+select @@gtid_slave_pos;
+@@gtid_slave_pos
+
+cluster 1 node 1
+create table t1 (cluster_domain_id int ,node_server_id int, seq_no int);
+insert into t1 values (1, 11, 2);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 1
+insert into t1 values (2, 21, 1);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,2-21-1
+select * from t1;
+cluster_domain_id node_server_id seq_no
+1 11 2
+2 21 1
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 node 2
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,2-21-1
+insert into t1 values (1, 12, 3);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,1-12-3,2-21-1
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 node 3
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,1-12-3,2-21-1
+insert into t1 values (1, 13, 4);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 2
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1
+insert into t1 values (2, 22, 2);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1,2-22-2
+#wait for sync cluster 2 and 1
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 3
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1,2-22-2
+insert into t1 values (2, 23, 3);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1,2-22-2,2-23-3
+#wait for sync cluster 2 and 1
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 node 1
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1,2-22-2,2-23-3
+drop table t1;
+stop slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+cluster 2 node 1
+stop slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+reset master;
+reset master;
+reset master;
+reset master;
diff --git a/mysql-test/suite/galera_3nodes/suite.pm b/mysql-test/suite/galera_3nodes/suite.pm
index c91e6e07d76..3a1237ecf75 100644
--- a/mysql-test/suite/galera_3nodes/suite.pm
+++ b/mysql-test/suite/galera_3nodes/suite.pm
@@ -9,8 +9,10 @@ return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" unless defined $::mysqld_variables{'wsrep-on'};
my ($provider) = grep { -f $_ } $ENV{WSREP_PROVIDER},
- "/usr/lib/galera/libgalera_smm.so",
- "/usr/lib64/galera/libgalera_smm.so";
+ "/usr/lib64/galera-3/libgalera_smm.so",
+ "/usr/lib64/galera/libgalera_smm.so",
+ "/usr/lib/galera-3/libgalera_smm.so",
+ "/usr/lib/galera/libgalera_smm.so";
return "No wsrep provider library" unless -f $provider;
diff --git a/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.cnf b/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.cnf
new file mode 100644
index 00000000000..dc5535ef34a
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.cnf
@@ -0,0 +1,28 @@
+# We need a dedicated .cnf file, even if empty, in order to force this test to run
+# alone on a freshly started cluster. Otherwise there are adverse interactions with
+# following tests such as galera_3nodes.galera_var_dirty_reads2
+
+!include ../galera_2x3nodes.cnf
+[mysqld.1]
+wsrep_gtid_domain_id=1
+server-id=11
+
+[mysqld.2]
+wsrep_gtid_domain_id=1
+server-id=12
+
+[mysqld.3]
+wsrep_gtid_domain_id=1
+server-id=13
+
+[mysqld.4]
+wsrep_gtid_domain_id=2
+server-id=21
+
+[mysqld.5]
+wsrep_gtid_domain_id=2
+server-id=22
+
+[mysqld.6]
+wsrep_gtid_domain_id=2
+server-id=23
diff --git a/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.test b/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.test
new file mode 100644
index 00000000000..c679db1305d
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.test
@@ -0,0 +1,292 @@
+#
+# This test creates 2x 3 nodes galera cluster.
+# The whole test case
+# A <-> B <-> C {Galera cluster 1}
+# | {Circular Async replication}
+# D <-> E <-> F {Galera cluster 2}
+# We will write on any random node to see if gtid is consitent or not
+# Then we will kill node D and set up the replication between A and E
+# To see whether fail over works or not.
+
+--source include/big_test.inc
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+--connection node_1
+--echo cluster 1 node 1
+SHOW STATUS LIKE 'wsrep_cluster_size';
+
+--connection node_2
+--echo cluster 1 node 2
+SHOW STATUS LIKE 'wsrep_cluster_size';
+
+--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
+--connection node_3
+--echo cluster 1 node 3
+SHOW STATUS LIKE 'wsrep_cluster_size';
+
+--connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4
+--connection node_4
+--echo cluster 2 node 1
+SHOW STATUS LIKE 'wsrep_cluster_size';
+
+--connect node_5, 127.0.0.1, root, , test, $NODE_MYPORT_5
+--connection node_5
+--echo cluster 2 node 2
+SHOW STATUS LIKE 'wsrep_cluster_size';
+
+--connect node_6, 127.0.0.1, root, , test, $NODE_MYPORT_6
+--connection node_6
+--echo cluster 2 node 3
+SHOW STATUS LIKE 'wsrep_cluster_size';
+#--disable_parsing
+--connection node_1
+--replace_result $NODE_MYPORT_4 NODE_MYPORT_4
+--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_4, master_use_gtid=current_pos, ignore_server_ids=(12,13);
+start slave;
+--source include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+select @@gtid_slave_pos;
+#--query_vertical SHOW SLAVE STATUS;
+
+--connection node_4
+--replace_result $NODE_MYPORT_1 NODE_MYPORT_1
+--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_1, master_use_gtid=current_pos, ignore_server_ids=(22,23);
+start slave;
+--source include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+select @@gtid_slave_pos;
+#--query_vertical SHOW SLAVE STATUS;
+
+--echo cluster 1 node 1
+--connection node_1
+create table t1 (cluster_domain_id int ,node_server_id int, seq_no int);
+insert into t1 values (1, 11, 2);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 2 node 1
+--connection node_4
+select @@gtid_binlog_state;
+insert into t1 values (2, 21, 1);
+select @@gtid_binlog_state;
+select * from t1;
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+
+--echo cluster 1 node 2
+--connection node_2
+select @@gtid_binlog_state;
+insert into t1 values (1, 12, 3);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 1 node 3
+--connection node_3
+select @@gtid_binlog_state;
+insert into t1 values (1, 13, 4);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 2 node 2
+--connection node_5
+select @@gtid_binlog_state;
+insert into t1 values (2, 22, 2);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 2 and 1
+--connection node_4
+--source include/save_master_gtid.inc
+--connection node_1
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 2 node 3
+--connection node_6
+select @@gtid_binlog_state;
+insert into t1 values (2, 23, 3);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 2 and 1
+--connection node_4
+--source include/save_master_gtid.inc
+--connection node_1
+--source include/sync_with_master_gtid.inc
+
+
+--echo cluster 1 node 1
+--connection node_1
+select @@gtid_binlog_state;
+drop table t1;
+stop slave;
+reset slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+--sleep 2
+
+--echo cluster 2 node 1
+--connection node_4
+stop slave;
+reset slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+
+--connection node_2
+reset master;
+--connection node_3
+reset master;
+--connection node_5
+reset master;
+--connection node_6
+reset master;
+#--enable_parsing
+#
+# This test creates 2x 3 nodes galera cluster.
+# The whole test case
+# A <-> B <-> C {Galera cluster 1}
+# \ /
+# \ /
+# / {C->D, F->A , Async normal slave repl}
+# / \
+# | \
+# D <-> E <-> F {Galera cluster 2}
+# We will write on any random node to see if gtid is consitent or not
+# Then we will kill node D and set up the replication between A and E
+# To see whether fail over works or not.
+--connection node_1
+--replace_result $NODE_MYPORT_6 NODE_MYPORT_6
+--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_6, master_use_gtid=current_pos, ignore_server_ids=(12,13);
+start slave;
+--source include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+select @@gtid_slave_pos;
+#--query_vertical SHOW SLAVE STATUS;
+
+--connection node_4
+--replace_result $NODE_MYPORT_3 NODE_MYPORT_3
+--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_3, master_use_gtid=current_pos, ignore_server_ids=(22,23);
+start slave;
+--source include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+select @@gtid_slave_pos;
+#--query_vertical SHOW SLAVE STATUS;
+
+--echo cluster 1 node 1
+--connection node_1
+create table t1 (cluster_domain_id int ,node_server_id int, seq_no int);
+insert into t1 values (1, 11, 2);
+
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+--sleep 2
+--echo cluster 2 node 1
+--connection node_4
+insert into t1 values (2, 21, 1);
+select @@gtid_binlog_state;
+select * from t1;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+
+--echo cluster 1 node 2
+--connection node_2
+select @@gtid_binlog_state;
+insert into t1 values (1, 12, 3);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 1 node 3
+--connection node_3
+select @@gtid_binlog_state;
+insert into t1 values (1, 13, 4);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 2 node 2
+--connection node_5
+select @@gtid_binlog_state;
+insert into t1 values (2, 22, 2);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 2 and 1
+--connection node_4
+--source include/save_master_gtid.inc
+--connection node_1
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 2 node 3
+--connection node_6
+select @@gtid_binlog_state;
+insert into t1 values (2, 23, 3);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 2 and 1
+--connection node_4
+--source include/save_master_gtid.inc
+--connection node_1
+--source include/sync_with_master_gtid.inc
+
+
+--echo cluster 1 node 1
+--connection node_1
+select @@gtid_binlog_state;
+drop table t1;
+stop slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+
+--echo cluster 2 node 1
+--connection node_4
+stop slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+
+--connection node_2
+reset master;
+--connection node_3
+reset master;
+--connection node_5
+reset master;
+--connection node_6
+reset master;
diff --git a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test
index a6660bd08d1..cc3f42c7290 100644
--- a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test
+++ b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test
@@ -16,7 +16,7 @@ SELECT COUNT(*) = 10 FROM t1;
--exec innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 $MYSQL_TMP_DIR/innobackupex_backup --galera-info --port=$NODE_MYPORT_2 --host=127.0.0.1 --no-timestamp > $MYSQL_TMP_DIR/innobackupex-backup.log
--exec innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 $MYSQL_TMP_DIR/innobackupex_backup --apply-log --galera-info --port=$NODE_MYPORT_2 --host=127.0.0.1 --no-timestamp > $MYSQL_TMP_DIR/innobackupex-apply.log
---source include/kill_galera.inc
+--source ../galera/include/kill_galera.inc
--sleep 1
--connection node_1
diff --git a/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test b/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test
index 7c9991e68c4..88d0cfba4f4 100644
--- a/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test
+++ b/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test
@@ -108,7 +108,7 @@ SET SESSION wsrep_on = OFF;
--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc
---source include/kill_galera.inc
+--source ../galera/include/kill_galera.inc
#
# Only node #1 should have safe_to_bootstrap: 1
diff --git a/mysql-test/suite/gcol/disabled.def b/mysql-test/suite/gcol/disabled.def
deleted file mode 100644
index 37209a4c353..00000000000
--- a/mysql-test/suite/gcol/disabled.def
+++ /dev/null
@@ -1 +0,0 @@
-innodb_virtual_debug_purge : MDEV-13568 should purge yield to LOCK TABLES?
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result
index 65a2f5c844f..e2d503cf134 100644
--- a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result
+++ b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result
@@ -143,21 +143,40 @@ connect prevent_purge, localhost, root;
start transaction with consistent snapshot;
connection default;
update t set a = repeat('m', 16000) where a like "aaa%";
-connect con1, localhost, root;
+connect lock_table, localhost, root;
lock table t write;
-disconnect prevent_purge;
+connection prevent_purge;
+commit;
connection default;
-select variable_value>1 from information_schema.global_status where variable_name='innodb_purge_trx_id_age';
-variable_value>1
-0
-disconnect con1;
+InnoDB 0 transactions not purged
+disconnect lock_table;
start transaction with consistent snapshot;
commit;
InnoDB 0 transactions not purged
-select variable_value>1 from information_schema.global_status where variable_name='innodb_purge_trx_id_age';
-variable_value>1
-0
set global debug_dbug=@old_dbug;
drop table t;
+#
+# MDEV-15165 InnoDB purge for index on virtual column
+# is trying to access an incomplete record
+#
+CREATE TABLE t1(
+u INT PRIMARY KEY, b BLOB, ug INT GENERATED ALWAYS AS (u) VIRTUAL,
+INDEX bug(b(100),ug)
+) ENGINE=InnoDB;
+INSERT INTO t1 (u,b) VALUES(1,REPEAT('a',16384));
+connection prevent_purge;
+start transaction with consistent snapshot;
+connection default;
+DELETE FROM t1;
+SET DEBUG_SYNC='blob_write_middle SIGNAL halfway WAIT_FOR purged';
+INSERT INTO t1 (u,b) VALUES(1,REPEAT('a',16384));
+connection prevent_purge;
+SET DEBUG_SYNC='now WAIT_FOR halfway';
+COMMIT;
+InnoDB 0 transactions not purged
+SET DEBUG_SYNC='now SIGNAL purged';
+disconnect prevent_purge;
+connection default;
+DROP TABLE t1;
set debug_sync=reset;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_index.result b/mysql-test/suite/gcol/r/innodb_virtual_index.result
index 375c62bd173..b1f7976c6c0 100644
--- a/mysql-test/suite/gcol/r/innodb_virtual_index.result
+++ b/mysql-test/suite/gcol/r/innodb_virtual_index.result
@@ -1,3 +1,5 @@
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
#
# Bug 21922176 - PREBUILT->SEARCH_TUPLE CREATED WITHOUT INCLUDING
# THE NUMBER OF VIRTUAL COLUMNS
@@ -86,6 +88,7 @@ DISTINCT I1.c14 AS y
FROM t1 AS I1
ORDER BY I1.c14);
SET @@SESSION.sql_mode=default;
+InnoDB 0 transactions not purged
DROP TABLE t1, t2, t3;
#
# Bug 22650296 - ASSERTION IN INNOBASE_BUILD_COL_MAP, ALTER
@@ -194,3 +197,4 @@ ALTER TABLE t1 ADD COLUMN col7a INT GENERATED ALWAYS AS (col1 % col2)
VIRTUAL, ADD UNIQUE index idx (col1), algorithm=inplace;
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try ALGORITHM=COPY
DROP TABLE t1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_stats.result b/mysql-test/suite/gcol/r/innodb_virtual_stats.result
new file mode 100644
index 00000000000..4ef499f932f
--- /dev/null
+++ b/mysql-test/suite/gcol/r/innodb_virtual_stats.result
@@ -0,0 +1,127 @@
+CREATE TABLE t (
+a INT,
+b INT,
+c INT GENERATED ALWAYS AS(a+b),
+d INT GENERATED ALWAYS AS(a+b+b),
+KEY idxa (a),
+KEY vidxcd (c, d)
+) ENGINE=INNODB STATS_PERSISTENT=1 STATS_AUTO_RECALC=1;
+INSERT INTO t (a,b) VALUES (1, 2);
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+index_name stat_name stat_description
+GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
+GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
+GEN_CLUST_INDEX size Number of pages in the index
+idxa n_diff_pfx01 a
+idxa n_diff_pfx02 a,DB_ROW_ID
+idxa n_leaf_pages Number of leaf pages in the index
+idxa size Number of pages in the index
+vidxcd n_diff_pfx01 c
+vidxcd n_diff_pfx02 c,d
+vidxcd n_diff_pfx03 c,d,DB_ROW_ID
+vidxcd n_leaf_pages Number of leaf pages in the index
+vidxcd size Number of pages in the index
+ALTER TABLE t ADD COLUMN e INT GENERATED ALWAYS AS(a+a+b), ADD INDEX idxb (b), ALGORITHM=INPLACE;
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+index_name stat_name stat_description
+GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
+GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
+GEN_CLUST_INDEX size Number of pages in the index
+idxa n_diff_pfx01 a
+idxa n_diff_pfx02 a,DB_ROW_ID
+idxa n_leaf_pages Number of leaf pages in the index
+idxa size Number of pages in the index
+idxb n_diff_pfx01 b
+idxb n_diff_pfx02 b,DB_ROW_ID
+idxb n_leaf_pages Number of leaf pages in the index
+idxb size Number of pages in the index
+vidxcd n_diff_pfx01 c
+vidxcd n_diff_pfx02 c,d
+vidxcd n_diff_pfx03 c,d,DB_ROW_ID
+vidxcd n_leaf_pages Number of leaf pages in the index
+vidxcd size Number of pages in the index
+ALTER TABLE t DROP COLUMN c, DROP INDEX idxa, ALGORITHM=INPLACE;
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+index_name stat_name stat_description
+GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
+GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
+GEN_CLUST_INDEX size Number of pages in the index
+idxb n_diff_pfx01 b
+idxb n_diff_pfx02 b,DB_ROW_ID
+idxb n_leaf_pages Number of leaf pages in the index
+idxb size Number of pages in the index
+vidxcd n_diff_pfx01 d
+vidxcd n_diff_pfx02 d,DB_ROW_ID
+vidxcd n_leaf_pages Number of leaf pages in the index
+vidxcd size Number of pages in the index
+ALTER TABLE t ADD INDEX vidxe (e), ALGORITHM=INPLACE;
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+index_name stat_name stat_description
+GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
+GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
+GEN_CLUST_INDEX size Number of pages in the index
+idxb n_diff_pfx01 b
+idxb n_diff_pfx02 b,DB_ROW_ID
+idxb n_leaf_pages Number of leaf pages in the index
+idxb size Number of pages in the index
+vidxcd n_diff_pfx01 d
+vidxcd n_diff_pfx02 d,DB_ROW_ID
+vidxcd n_leaf_pages Number of leaf pages in the index
+vidxcd size Number of pages in the index
+vidxe n_diff_pfx01 e
+vidxe n_diff_pfx02 e,DB_ROW_ID
+vidxe n_leaf_pages Number of leaf pages in the index
+vidxe size Number of pages in the index
+ALTER TABLE t ADD COLUMN f INT GENERATED ALWAYS AS(a + a), ADD INDEX vidxf (f), ALGORITHM=INPLACE;
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+index_name stat_name stat_description
+GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
+GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
+GEN_CLUST_INDEX size Number of pages in the index
+idxb n_diff_pfx01 b
+idxb n_diff_pfx02 b,DB_ROW_ID
+idxb n_leaf_pages Number of leaf pages in the index
+idxb size Number of pages in the index
+vidxcd n_diff_pfx01 d
+vidxcd n_diff_pfx02 d,DB_ROW_ID
+vidxcd n_leaf_pages Number of leaf pages in the index
+vidxcd size Number of pages in the index
+vidxe n_diff_pfx01 e
+vidxe n_diff_pfx02 e,DB_ROW_ID
+vidxe n_leaf_pages Number of leaf pages in the index
+vidxe size Number of pages in the index
+vidxf n_diff_pfx01 f
+vidxf n_diff_pfx02 f,DB_ROW_ID
+vidxf n_leaf_pages Number of leaf pages in the index
+vidxf size Number of pages in the index
+ALTER TABLE t DROP INDEX vidxcd;
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+index_name stat_name stat_description
+GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
+GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
+GEN_CLUST_INDEX size Number of pages in the index
+idxb n_diff_pfx01 b
+idxb n_diff_pfx02 b,DB_ROW_ID
+idxb n_leaf_pages Number of leaf pages in the index
+idxb size Number of pages in the index
+vidxe n_diff_pfx01 e
+vidxe n_diff_pfx02 e,DB_ROW_ID
+vidxe n_leaf_pages Number of leaf pages in the index
+vidxe size Number of pages in the index
+vidxf n_diff_pfx01 f
+vidxf n_diff_pfx02 f,DB_ROW_ID
+vidxf n_leaf_pages Number of leaf pages in the index
+vidxf size Number of pages in the index
+DROP TABLE t;
diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test
index 2668e26c976..ad733eee3a7 100644
--- a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test
+++ b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test
@@ -182,19 +182,45 @@ connect(prevent_purge, localhost, root);
start transaction with consistent snapshot;
connection default;
update t set a = repeat('m', 16000) where a like "aaa%";
-connect(con1, localhost, root);
+connect(lock_table, localhost, root);
lock table t write;
-disconnect prevent_purge;
+connection prevent_purge;
+commit;
connection default;
-select variable_value>1 from information_schema.global_status where variable_name='innodb_purge_trx_id_age';
-disconnect con1;
+--source ../../innodb/include/wait_all_purged.inc
+disconnect lock_table;
start transaction with consistent snapshot;
commit;
--source ../../innodb/include/wait_all_purged.inc
-select variable_value>1 from information_schema.global_status where variable_name='innodb_purge_trx_id_age';
set global debug_dbug=@old_dbug;
drop table t;
+--echo #
+--echo # MDEV-15165 InnoDB purge for index on virtual column
+--echo # is trying to access an incomplete record
+--echo #
+CREATE TABLE t1(
+ u INT PRIMARY KEY, b BLOB, ug INT GENERATED ALWAYS AS (u) VIRTUAL,
+ INDEX bug(b(100),ug)
+) ENGINE=InnoDB;
+INSERT INTO t1 (u,b) VALUES(1,REPEAT('a',16384));
+connection prevent_purge;
+start transaction with consistent snapshot;
+connection default;
+DELETE FROM t1;
+SET DEBUG_SYNC='blob_write_middle SIGNAL halfway WAIT_FOR purged';
+send INSERT INTO t1 (u,b) VALUES(1,REPEAT('a',16384));
+connection prevent_purge;
+SET DEBUG_SYNC='now WAIT_FOR halfway';
+COMMIT;
+--source ../../innodb/include/wait_all_purged.inc
+SET DEBUG_SYNC='now SIGNAL purged';
+disconnect prevent_purge;
+
+connection default;
+reap;
+DROP TABLE t1;
+
--source include/wait_until_count_sessions.inc
set debug_sync=reset;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/gcol/t/innodb_virtual_index.test b/mysql-test/suite/gcol/t/innodb_virtual_index.test
index 4c4cb2a2d05..432faeb65ae 100644
--- a/mysql-test/suite/gcol/t/innodb_virtual_index.test
+++ b/mysql-test/suite/gcol/t/innodb_virtual_index.test
@@ -1,5 +1,9 @@
--source include/have_innodb.inc
+# Ensure that the history list length will actually be decremented by purge.
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
+
--echo #
--echo # Bug 21922176 - PREBUILT->SEARCH_TUPLE CREATED WITHOUT INCLUDING
--echo # THE NUMBER OF VIRTUAL COLUMNS
@@ -96,6 +100,7 @@ FROM t1 AS I1
ORDER BY I1.c14);
SET @@SESSION.sql_mode=default;
+--source ../../innodb/include/wait_all_purged.inc
DROP TABLE t1, t2, t3;
@@ -218,3 +223,4 @@ ALTER TABLE t1 ADD COLUMN col7a INT GENERATED ALWAYS AS (col1 % col2)
VIRTUAL, ADD UNIQUE index idx (col1), algorithm=inplace;
DROP TABLE t1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/gcol/t/innodb_virtual_stats.test b/mysql-test/suite/gcol/t/innodb_virtual_stats.test
new file mode 100644
index 00000000000..7e3c8f4e00e
--- /dev/null
+++ b/mysql-test/suite/gcol/t/innodb_virtual_stats.test
@@ -0,0 +1,52 @@
+--source include/have_innodb.inc
+
+#
+# BUG#22469660 INNODB DOESN'T UPDATE INDEX STATS WHEN ADDING OR DROPPING VIRTUAL COLUMN
+#
+
+CREATE TABLE t (
+ a INT,
+ b INT,
+ c INT GENERATED ALWAYS AS(a+b),
+ d INT GENERATED ALWAYS AS(a+b+b),
+ KEY idxa (a),
+ KEY vidxcd (c, d)
+) ENGINE=INNODB STATS_PERSISTENT=1 STATS_AUTO_RECALC=1;
+
+INSERT INTO t (a,b) VALUES (1, 2);
+
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+
+ALTER TABLE t ADD COLUMN e INT GENERATED ALWAYS AS(a+a+b), ADD INDEX idxb (b), ALGORITHM=INPLACE;
+
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+
+ALTER TABLE t DROP COLUMN c, DROP INDEX idxa, ALGORITHM=INPLACE;
+
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+
+ALTER TABLE t ADD INDEX vidxe (e), ALGORITHM=INPLACE;
+
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+
+ALTER TABLE t ADD COLUMN f INT GENERATED ALWAYS AS(a + a), ADD INDEX vidxf (f), ALGORITHM=INPLACE;
+
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+
+ALTER TABLE t DROP INDEX vidxcd;
+
+SELECT index_name, stat_name, stat_description
+FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't';
+
+DROP TABLE t;
diff --git a/mysql-test/suite/heap/heap.result b/mysql-test/suite/heap/heap.result
index 9e97d5a17fb..320966dd571 100644
--- a/mysql-test/suite/heap/heap.result
+++ b/mysql-test/suite/heap/heap.result
@@ -715,9 +715,9 @@ drop table t1;
create table t1 (c char(10)) engine=memory;
create table t2 (c varchar(10)) engine=memory;
show table status like 't_';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 10 Fixed 0 11 0 # 0 0 NULL # NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 10 Fixed 0 12 0 # 0 0 NULL # NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 MEMORY 10 Fixed 0 11 0 # 0 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
+t2 MEMORY 10 Fixed 0 12 0 # 0 0 NULL # NULL NULL latin1_swedish_ci NULL 0 N
drop table t1, t2;
CREATE TABLE t1(a VARCHAR(1), b VARCHAR(2), c VARCHAR(256),
KEY(a), KEY(b), KEY(c)) ENGINE=MEMORY;
diff --git a/mysql-test/suite/innodb/include/innodb_bulk_create_index.inc b/mysql-test/suite/innodb/include/innodb_bulk_create_index.inc
new file mode 100644
index 00000000000..3c10517933f
--- /dev/null
+++ b/mysql-test/suite/innodb/include/innodb_bulk_create_index.inc
@@ -0,0 +1,185 @@
+#
+# wl#7277: InnoDB: Bulk Load for Create Index
+#
+
+# Create Insert Procedure
+DELIMITER |;
+CREATE PROCEDURE populate_t1(load_even INT)
+BEGIN
+ DECLARE i int DEFAULT 1;
+
+ START TRANSACTION;
+ WHILE (i <= 10000) DO
+ IF i%2 = 0 AND load_even = 1 THEN
+ INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+ END IF;
+ IF i%2 != 0 AND load_even != 1 THEN
+ INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+ END IF;
+ SET i = i + 1;
+ END WHILE;
+ COMMIT;
+END|
+DELIMITER ;|
+
+SELECT @@innodb_fill_factor;
+
+if ($row_format != 'COMPRESSED')
+{
+ eval CREATE TABLE t1(
+ class INT,
+ id INT,
+ title VARCHAR(100)
+ ) ENGINE=InnoDB ROW_FORMAT=$row_format;
+}
+
+if ($row_format == 'COMPRESSED')
+{
+ SET GLOBAL innodb_file_per_table=1;
+
+ eval CREATE TABLE t1(
+ class INT,
+ id INT,
+ title VARCHAR(100)
+ ) ENGINE=InnoDB ROW_FORMAT=$row_format KEY_BLOCK_SIZE=4;
+}
+
+-- disable_query_log
+# Load half records
+CALL populate_t1(1);
+-- enable_query_log
+
+SELECT COUNT(*) FROM t1;
+
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+
+CREATE INDEX idx_title ON t1(title);
+
+/* Check table. */
+CHECK TABLE t1;
+
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 10;
+SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 5000;
+SELECT * FROM t1 WHERE title = 'a5000';
+
+SELECT * FROM t1 WHERE id = 10000;
+SELECT * FROM t1 WHERE title = 'a10000';
+
+SELECT * FROM t1 WHERE id = 10010;
+SELECT * FROM t1 WHERE title = 'a10010';
+
+/*Insert/Update/Delete. */
+DELETE FROM t1 WHERE id < 4010 AND id > 3990;
+INSERT INTO t1 VALUES(4000, 4000, 'b4000');
+UPDATE t1 SET title = CONCAT('b', id) WHERE id < 3010 AND id > 2990;
+
+SELECT * FROM t1 WHERE id = 3000;
+SELECT * FROM t1 WHERE title = 'a3000';
+SELECT * FROM t1 WHERE title = 'b3000';
+
+SELECT * FROM t1 WHERE id = 4000;
+SELECT * FROM t1 WHERE title = 'a4000';
+SELECT * FROM t1 WHERE title = 'b4000';
+
+SELECT * FROM t1 WHERE id = 4001;
+SELECT * FROM t1 WHERE title = 'a4001';
+
+-- disable_query_log
+# Load half records (follow up load)
+CALL populate_t1(0);
+-- enable_query_log
+SELECT COUNT(*) FROM t1;
+
+
+/* Add column. */
+ALTER TABLE t1 ADD COLUMN content TEXT;
+
+CHECK TABLE t1;
+
+SELECT * FROM t1 WHERE id = 10;
+SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 5000;
+SELECT * FROM t1 WHERE title = 'a5000';
+
+SELECT * FROM t1 WHERE id = 10000;
+SELECT * FROM t1 WHERE title = 'a10000';
+
+SELECT * FROM t1 WHERE id = 10010;
+SELECT * FROM t1 WHERE title = 'a10010';
+
+/* Drop column. */
+ALTER TABLE t1 DROP COLUMN content;
+
+CHECK TABLE t1;
+
+SELECT * FROM t1 WHERE id = 10;
+SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 5000;
+SELECT * FROM t1 WHERE title = 'a5000';
+
+SELECT * FROM t1 WHERE id = 10000;
+SELECT * FROM t1 WHERE title = 'a10000';
+
+SELECT * FROM t1 WHERE id = 10010;
+SELECT * FROM t1 WHERE title = 'a10010';
+
+DROP TABLE t1;
+
+# Test Blob
+if ($row_format != 'COMPRESSED') {
+ eval CREATE TABLE t1(
+ a INT PRIMARY KEY,
+ b TEXT,
+ c TEXT) ENGINE=InnoDB ROW_FORMAT=$row_format;
+}
+
+if ($row_format == 'COMPRESSED') {
+ eval CREATE TABLE t1(
+ a INT PRIMARY KEY,
+ b BLOB,
+ c TEXT) ENGINE=InnoDB ROW_FORMAT=$row_format KEY_BLOCK_SIZE=4;
+}
+
+let $cnt= 5000;
+-- disable_query_log
+WHILE ($cnt>=4950)
+{
+EVAL INSERT INTO t1 VALUES
+ ($cnt, REPEAT(CONCAT('a', $cnt),2000), CONCAT('a', $cnt));
+dec $cnt;
+}
+-- enable_query_log
+ALTER TABLE t1 ADD INDEX `idx` (a,b(5));
+
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+UPDATE t1 SET b = REPEAT(CONCAT('b',4975),2000) WHERE a=4975 AND b like 'a4975%';
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+DELETE FROM t1 WHERE a=4975 AND b like 'b4975%';
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+
+ALTER TABLE t1 DROP COLUMN c;
+
+CHECK TABLE t1;
+
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+
+DROP TABLE t1;
+
+# Restore global variables
+if ($row_format == 'COMPRESSED')
+{
+ SET GLOBAL innodb_file_per_table=default;
+}
+
+DROP PROCEDURE populate_t1;
diff --git a/mysql-test/suite/innodb/include/innodb_bulk_create_index_debug.inc b/mysql-test/suite/innodb/include/innodb_bulk_create_index_debug.inc
new file mode 100644
index 00000000000..48de3a1962d
--- /dev/null
+++ b/mysql-test/suite/innodb/include/innodb_bulk_create_index_debug.inc
@@ -0,0 +1,221 @@
+#
+# wl#7277: InnoDB: Bulk Load for Create Index
+#
+
+# Not supported in embedded
+-- source include/not_embedded.inc
+
+# This test case needs to crash the server. Needs a debug server.
+-- source include/have_debug.inc
+
+# Don't test this under valgrind, memory leaks will occur.
+-- source include/not_valgrind.inc
+
+# Avoid CrashReporter popup on Mac
+-- source include/not_crashrep.inc
+
+-- source include/have_innodb.inc
+
+# Create Insert Procedure
+DELIMITER |;
+CREATE PROCEDURE populate_t1()
+BEGIN
+ DECLARE i int DEFAULT 1;
+
+ START TRANSACTION;
+ WHILE (i <= 10000) DO
+ INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+ SET i = i + 1;
+ END WHILE;
+ COMMIT;
+END|
+DELIMITER ;|
+
+# Test scenarios:
+# 1. Test restart;
+# 2. Test crash recovery.
+
+# Test Restart
+if ($row_format != 'COMPRESSED')
+{
+ eval CREATE TABLE t1(
+ class INT,
+ id INT,
+ title VARCHAR(100)
+ ) ENGINE=InnoDB ROW_FORMAT=$row_format;
+}
+
+if ($row_format == 'COMPRESSED')
+{
+ SET GLOBAL innodb_file_per_table=1;
+
+ eval CREATE TABLE t1(
+ class INT,
+ id INT,
+ title VARCHAR(100)
+ ) ENGINE=InnoDB ROW_FORMAT=$row_format KEY_BLOCK_SIZE=4;
+}
+
+-- disable_query_log
+CALL populate_t1();
+-- enable_query_log
+
+SELECT COUNT(*) FROM t1;
+
+CREATE INDEX idx_title ON t1(title);
+
+--source include/restart_mysqld.inc
+
+CHECK TABLE t1;
+
+SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE title = 'a5000';
+
+SELECT * FROM t1 WHERE title = 'a10000';
+
+SELECT * FROM t1 WHERE title = 'a10010';
+
+DROP TABLE t1;
+
+-- echo # Test Blob
+
+if ($row_format != 'COMPRESSED') {
+ eval CREATE TABLE t1(
+ a INT PRIMARY KEY,
+ b TEXT,
+ c TEXT) ENGINE=InnoDB ROW_FORMAT=$row_format;
+}
+
+if ($row_format == 'COMPRESSED') {
+ SET GLOBAL innodb_file_per_table=1;
+
+ eval CREATE TABLE t1(
+ a INT PRIMARY KEY,
+ b TEXT,
+ c TEXT) ENGINE=InnoDB ROW_FORMAT=$row_format KEY_BLOCK_SIZE=4;
+}
+
+INSERT INTO t1 VALUES
+ (1, REPEAT('a',10000), 'a'),
+ (2, REPEAT('b',20000), 'b'),
+ (3, REPEAT('c',40000), 'c'),
+ (4, REPEAT('d',60000), 'd');
+
+SELECT CHAR_LENGTH(b) FROM t1;
+
+ALTER TABLE t1 DROP COLUMN c;
+
+--source include/restart_mysqld.inc
+
+CHECK TABLE t1;
+
+SELECT CHAR_LENGTH(b) FROM t1;
+
+DROP TABLE t1;
+
+# Test Crash Recovery
+
+if ($row_format != 'COMPRESSED')
+{
+ eval CREATE TABLE t1(
+ class INT,
+ id INT,
+ title VARCHAR(100)
+ ) ENGINE=InnoDB ROW_FORMAT=$row_format;
+}
+
+if ($row_format == 'COMPRESSED')
+{
+ SET GLOBAL innodb_file_per_table=1;
+
+ eval CREATE TABLE t1(
+ class INT,
+ id INT,
+ title VARCHAR(100)
+ ) ENGINE=InnoDB ROW_FORMAT=$row_format KEY_BLOCK_SIZE=4;
+}
+
+-- disable_query_log
+CALL populate_t1();
+-- enable_query_log
+
+SET debug_dbug='+d,crash_commit_before';
+
+# Write file to make mysql-test-run.pl start up the server again
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+--error 2013
+CREATE INDEX idx_title ON t1(title);
+
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+
+SELECT COUNT(*) FROM t1;
+
+CHECK TABLE t1;
+
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE title = 'a5000';
+
+SELECT * FROM t1 WHERE title = 'a10000';
+
+SELECT * FROM t1 WHERE title = 'a10010';
+
+DROP TABLE t1;
+
+-- echo # Test Blob
+
+if ($row_format != 'COMPRESSED') {
+ eval CREATE TABLE t1(
+ a INT PRIMARY KEY,
+ b TEXT,
+ c TEXT) ENGINE=InnoDB ROW_FORMAT=$row_format;
+}
+
+if ($row_format == 'COMPRESSED') {
+ SET GLOBAL innodb_file_per_table=1;
+
+ eval CREATE TABLE t1(
+ a INT PRIMARY KEY,
+ b TEXT,
+ c TEXT) ENGINE=InnoDB ROW_FORMAT=$row_format KEY_BLOCK_SIZE=4;
+}
+
+INSERT INTO t1 VALUES
+ (1, REPEAT('a',10000), 'a'),
+ (2, REPEAT('b',20000), 'b'),
+ (3, REPEAT('c',40000), 'c'),
+ (4, REPEAT('d',60000), 'd');
+
+SELECT CHAR_LENGTH(b) FROM t1;
+
+SET debug_dbug='+d,crash_commit_before';
+
+# Write file to make mysql-test-run.pl start up the server again
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+--error 2013
+ALTER TABLE t1 DROP COLUMN c;
+
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+
+CHECK TABLE t1;
+
+SELECT CHAR_LENGTH(b) FROM t1;
+
+DROP TABLE t1;
+
+# Restore global variables
+if ($row_format == 'COMPRESSED')
+{
+ SET GLOBAL innodb_file_per_table=default;
+}
+
+DROP PROCEDURE populate_t1;
diff --git a/mysql-test/suite/innodb/r/alter_copy.result b/mysql-test/suite/innodb/r/alter_copy.result
new file mode 100644
index 00000000000..286c5152ded
--- /dev/null
+++ b/mysql-test/suite/innodb/r/alter_copy.result
@@ -0,0 +1,213 @@
+#
+# MDEV-11415 AVOID INTERMEDIATE COMMIT WHILE DOING
+# ALTER TABLE...ALGORITHM=COPY
+#
+CREATE TABLE t(a SERIAL, b INT, c INT, d INT) ENGINE=InnoDB;
+CREATE TABLE t1(a INT, b TEXT, c TEXT,
+FULLTEXT(b), FULLTEXT(c(3)), FULLTEXT(b,c)) ENGINE=InnoDB;
+BEGIN;
+COMMIT;
+SELECT COUNT(*) FROM t;
+COUNT(*)
+999
+UPDATE t SET b=a%7, c=a%11, d=a%13;
+INSERT INTO t1 VALUES(1, 'This is a first b column', 'This is a first c column');
+INSERT INTO t1 VALUES(2, 'This is a second b column', 'This is a second c column');
+INSERT INTO t1(a) VALUES(3);
+INSERT INTO t1 VALUES(4, 'This is a third b column', 'This is a third c column');
+DELETE FROM t1 WHERE a = 2;
+SELECT * FROM t1 WHERE MATCH(b) AGAINST ('first');
+a b c
+1 This is a first b column This is a first c column
+SELECT * FROM t1 WHERE MATCH(c) AGAINST ('first');
+a b c
+1 This is a first b column This is a first c column
+SELECT * FROM t1 WHERE MATCH(b,c) AGAINST ('column');
+a b c
+1 This is a first b column This is a first c column
+4 This is a third b column This is a third c column
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` text DEFAULT NULL,
+ `c` text DEFAULT NULL,
+ FULLTEXT KEY `b` (`b`),
+ FULLTEXT KEY `c` (`c`),
+ FULLTEXT KEY `b_2` (`b`,`c`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 FORCE, ALGORITHM=COPY;
+SET DEBUG_DBUG='+d,crash_commit_before';
+ALTER TABLE t ADD INDEX(b,c,d,a),ADD INDEX(b,c,a,d),ADD INDEX(b,a,c,d),ADD INDEX(b,a,d,c),
+ADD INDEX(b,d,a,c),ADD INDEX(b,d,c,a),ADD INDEX(a,b,c,d),ADD INDEX(a,b,d,c),
+ADD INDEX(a,c,b,d),ADD INDEX(a,c,d,b),ADD INDEX(a,d,b,c),ADD INDEX(a,d,c,b),
+ADD INDEX(c,a,b,d),ADD INDEX(c,a,d,b),ADD INDEX(c,b,a,d),ADD INDEX(c,b,d,a),
+ADD INDEX(c,d,a,b),ADD INDEX(c,d,b,a),ADD INDEX(d,a,b,c),ADD INDEX(d,a,c,b),
+ADD INDEX(d,b,a,c),ADD INDEX(d,b,c,a),ADD INDEX(d,c,a,b),ADD INDEX(d,c,b,a),
+ADD INDEX(a,b,c), ADD INDEX(a,c,b), ADD INDEX(a,c,d), ADD INDEX(a,d,c),
+ADD INDEX(a,b,d), ADD INDEX(a,d,b), ADD INDEX(b,c,d), ADD INDEX(b,d,c),
+ALGORITHM=COPY;
+ERROR HY000: Lost connection to MySQL server during query
+#sql-temporary.frm
+#sql-temporary.ibd
+FTS_INDEX_1.ibd
+FTS_INDEX_2.ibd
+FTS_INDEX_3.ibd
+FTS_INDEX_4.ibd
+FTS_INDEX_5.ibd
+FTS_INDEX_6.ibd
+FTS_INDEX_1.ibd
+FTS_INDEX_2.ibd
+FTS_INDEX_3.ibd
+FTS_INDEX_4.ibd
+FTS_INDEX_5.ibd
+FTS_INDEX_6.ibd
+FTS_INDEX_1.ibd
+FTS_INDEX_2.ibd
+FTS_INDEX_3.ibd
+FTS_INDEX_4.ibd
+FTS_INDEX_5.ibd
+FTS_INDEX_6.ibd
+FTSBEING_DELETED.ibd
+FTSBEING_DELETED_CACHE.ibd
+FTSCONFIG.ibd
+FTSDELETED.ibd
+FTSDELETED_CACHE.ibd
+t.frm
+t.ibd
+t1.frm
+t1.ibd
+SHOW CREATE TABLE t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ UNIQUE KEY `a` (`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=latin1
+SELECT COUNT(*) FROM t;
+COUNT(*)
+999
+CHECK TABLE t;
+Table Op Msg_type Msg_text
+test.t check status OK
+SELECT * FROM t1 WHERE MATCH(b) AGAINST ('first');
+a b c
+1 This is a first b column This is a first c column
+SELECT * FROM t1 WHERE MATCH(c) AGAINST ('first');
+a b c
+1 This is a first b column This is a first c column
+SELECT * FROM t1 WHERE MATCH(b,c) AGAINST ('column');
+a b c
+1 This is a first b column This is a first c column
+4 This is a third b column This is a third c column
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` text DEFAULT NULL,
+ `c` text DEFAULT NULL,
+ FULLTEXT KEY `b` (`b`),
+ FULLTEXT KEY `c` (`c`),
+ FULLTEXT KEY `b_2` (`b`,`c`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+#sql-temporary.frm
+#sql-temporary.ibd
+FTS_INDEX_1.ibd
+FTS_INDEX_2.ibd
+FTS_INDEX_3.ibd
+FTS_INDEX_4.ibd
+FTS_INDEX_5.ibd
+FTS_INDEX_6.ibd
+FTS_INDEX_1.ibd
+FTS_INDEX_2.ibd
+FTS_INDEX_3.ibd
+FTS_INDEX_4.ibd
+FTS_INDEX_5.ibd
+FTS_INDEX_6.ibd
+FTS_INDEX_1.ibd
+FTS_INDEX_2.ibd
+FTS_INDEX_3.ibd
+FTS_INDEX_4.ibd
+FTS_INDEX_5.ibd
+FTS_INDEX_6.ibd
+FTSBEING_DELETED.ibd
+FTSBEING_DELETED_CACHE.ibd
+FTSCONFIG.ibd
+FTSDELETED.ibd
+FTSDELETED_CACHE.ibd
+t.frm
+t.ibd
+t1.frm
+t1.ibd
+SHOW CREATE TABLE t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ UNIQUE KEY `a` (`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=latin1
+SELECT COUNT(*) FROM t;
+COUNT(*)
+999
+CHECK TABLE t;
+Table Op Msg_type Msg_text
+test.t check status OK
+SELECT * FROM t1 WHERE MATCH(b) AGAINST ('first');
+a b c
+1 This is a first b column This is a first c column
+SELECT * FROM t1 WHERE MATCH(c) AGAINST ('first');
+a b c
+1 This is a first b column This is a first c column
+SELECT * FROM t1 WHERE MATCH(b,c) AGAINST ('column');
+a b c
+1 This is a first b column This is a first c column
+4 This is a third b column This is a third c column
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` text DEFAULT NULL,
+ `c` text DEFAULT NULL,
+ FULLTEXT KEY `b` (`b`),
+ FULLTEXT KEY `c` (`c`),
+ FULLTEXT KEY `b_2` (`b`,`c`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+#sql-temporary.frm
+FTS_INDEX_1.ibd
+FTS_INDEX_2.ibd
+FTS_INDEX_3.ibd
+FTS_INDEX_4.ibd
+FTS_INDEX_5.ibd
+FTS_INDEX_6.ibd
+FTS_INDEX_1.ibd
+FTS_INDEX_2.ibd
+FTS_INDEX_3.ibd
+FTS_INDEX_4.ibd
+FTS_INDEX_5.ibd
+FTS_INDEX_6.ibd
+FTS_INDEX_1.ibd
+FTS_INDEX_2.ibd
+FTS_INDEX_3.ibd
+FTS_INDEX_4.ibd
+FTS_INDEX_5.ibd
+FTS_INDEX_6.ibd
+FTSBEING_DELETED.ibd
+FTSBEING_DELETED_CACHE.ibd
+FTSCONFIG.ibd
+FTSDELETED.ibd
+FTSDELETED_CACHE.ibd
+t.frm
+t.ibd
+t1.frm
+t1.ibd
+DROP TABLE t1,t;
diff --git a/mysql-test/suite/innodb/r/alter_crash.result b/mysql-test/suite/innodb/r/alter_crash.result
index 8de02cc5fbd..5bf25cf8592 100644
--- a/mysql-test/suite/innodb/r/alter_crash.result
+++ b/mysql-test/suite/innodb/r/alter_crash.result
@@ -44,10 +44,9 @@ SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit';
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
ERROR HY000: Lost connection to MySQL server during query
# Restart mysqld after the crash and reconnect.
-# Manual *.frm recovery begin.
-# Manual recovery end
-FLUSH TABLES;
-# Drop the orphaned original table.
+SELECT * FROM information_schema.innodb_sys_tables
+WHERE table_id = ID;
+TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
# Files in datadir after manual recovery.
t1.frm
t1.ibd
@@ -83,12 +82,9 @@ SET DEBUG_DBUG='+d,innodb_alter_commit_crash_before_commit';
ALTER TABLE t2 ADD PRIMARY KEY (f2, f1);
ERROR HY000: Lost connection to MySQL server during query
# Startup the server after the crash
-# Read and remember the temporary table name
-# Manual *.frm recovery begin. The dictionary was not updated
-# and the files were not renamed. The rebuilt table
-# was left behind on purpose, to faciliate data recovery.
-# Manual recovery end
-# Drop the orphaned rebuilt table.
+SELECT * FROM information_schema.innodb_sys_tables
+WHERE name LIKE 'test/#sql-%';
+TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
SHOW TABLES;
Tables_in_test
t2
@@ -123,10 +119,9 @@ SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit';
ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE;
ERROR HY000: Lost connection to MySQL server during query
# Restart mysqld after the crash and reconnect.
-# Manual *.frm recovery begin.
-# Manual recovery end
-FLUSH TABLES;
-# Drop the orphaned original table.
+SELECT * FROM information_schema.innodb_sys_tables
+WHERE table_id = ID;
+TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
# Files in datadir after manual recovery.
t1.frm
t1.ibd
diff --git a/mysql-test/suite/innodb/r/ddl_purge.result b/mysql-test/suite/innodb/r/ddl_purge.result
new file mode 100644
index 00000000000..45f4c99e97b
--- /dev/null
+++ b/mysql-test/suite/innodb/r/ddl_purge.result
@@ -0,0 +1,25 @@
+CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=InnoDB;
+connect con1,localhost,root,,test;
+BEGIN;
+INSERT INTO t0 SET pk=1;
+connect con2,localhost,root,,test;
+BEGIN;
+INSERT INTO t0 SET pk=2;
+connection default;
+SET DEBUG_SYNC='alter_table_inplace_after_lock_downgrade SIGNAL prepared WAIT_FOR logged';
+ALTER TABLE t1 FORCE;
+connection con1;
+SET DEBUG_SYNC='now WAIT_FOR prepared';
+INSERT INTO t1 SET pk=1;
+COMMIT;
+disconnect con1;
+connection con2;
+UPDATE t1 SET b=1;
+DELETE FROM t1;
+ROLLBACK;
+SET DEBUG_SYNC='now SIGNAL logged';
+disconnect con2;
+connection default;
+SET DEBUG_SYNC='RESET';
+DROP TABLE t0,t1;
diff --git a/mysql-test/suite/innodb/r/deadlock_detect.result b/mysql-test/suite/innodb/r/deadlock_detect.result
index c3e3794ed21..4e14eff34b2 100644
--- a/mysql-test/suite/innodb/r/deadlock_detect.result
+++ b/mysql-test/suite/innodb/r/deadlock_detect.result
@@ -8,21 +8,15 @@ PRIMARY KEY(id)
INSERT INTO t1 VALUES(1), (2), (3);
BEGIN;
SELECT * FROM t1 WHERE id = 1 FOR UPDATE;
-id
-1
connect con1,localhost,root,,;
BEGIN;
SELECT * FROM t1 WHERE id = 2 FOR UPDATE;
-id
-2
SELECT * FROM t1 WHERE id = 1 FOR UPDATE;
connection default;
SELECT * FROM t1 WHERE id = 2 FOR UPDATE;
connection con1;
-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ROLLBACK;
connection default;
-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ROLLBACK;
DROP TABLE t1;
disconnect con1;
diff --git a/mysql-test/suite/innodb/r/drop_table_background.result b/mysql-test/suite/innodb/r/drop_table_background.result
index a6f5672ba7f..e74bcd5e780 100644
--- a/mysql-test/suite/innodb/r/drop_table_background.result
+++ b/mysql-test/suite/innodb/r/drop_table_background.result
@@ -3,7 +3,22 @@ KEY(c1), KEY(c2), KEY(c2,c1),
KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1),
KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1),
KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB;
+CREATE TABLE `#mysql50##sql-ib-foo`(a SERIAL) ENGINE=InnoDB;
+INSERT INTO t (c1) VALUES (1),(2),(1);
SET DEBUG_DBUG='+d,row_drop_table_add_to_background';
+CREATE TABLE target (PRIMARY KEY(c1)) ENGINE=InnoDB SELECT * FROM t;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+SELECT * from target;
+ERROR 42S02: Table 'test.target' doesn't exist
DROP TABLE t;
CREATE TABLE t (a INT) ENGINE=InnoDB;
DROP TABLE t;
+DROP TABLE target;
+ERROR 42S02: Unknown table 'test.target'
+CREATE TABLE target (a INT) ENGINE=InnoDB;
+DROP TABLE target;
+SELECT * FROM `#mysql50##sql-ib-foo`;
+ERROR 42S02: Table 'test.#mysql50##sql-ib-foo' doesn't exist in engine
+DROP TABLE `#mysql50##sql-ib-foo`;
+Warnings:
+Warning 1932 Table 'test.#mysql50##sql-ib-foo' doesn't exist in engine
diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result
index da0e16b86ac..e569fc7dba7 100644
--- a/mysql-test/suite/innodb/r/foreign_key.result
+++ b/mysql-test/suite/innodb/r/foreign_key.result
@@ -263,3 +263,46 @@ SELECT * FROM t2;
id ref_id f
2 2 20
DROP TABLE t2, t1;
+#
+# MDEV-15199 Referential integrity broken in ON DELETE CASCADE
+#
+CREATE TABLE member (id int AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO member VALUES (1);
+CREATE TABLE address (
+id int AUTO_INCREMENT PRIMARY KEY,
+member_id int NOT NULL,
+KEY address_FI_1 (member_id),
+CONSTRAINT address_FK_1 FOREIGN KEY (member_id) REFERENCES member (id)
+ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT INTO address VALUES (2,1);
+CREATE TABLE payment_method (
+id int AUTO_INCREMENT PRIMARY KEY,
+member_id int NOT NULL,
+cardholder_address_id int DEFAULT NULL,
+KEY payment_method_FI_1 (member_id),
+KEY payment_method_FI_2 (cardholder_address_id),
+CONSTRAINT payment_method_FK_1 FOREIGN KEY (member_id) REFERENCES member (id) ON DELETE CASCADE ON UPDATE CASCADE,
+CONSTRAINT payment_method_FK_2 FOREIGN KEY (cardholder_address_id) REFERENCES address (id) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT INTO payment_method VALUES (3,1,2);
+BEGIN;
+UPDATE member SET id=42;
+SELECT * FROM member;
+id
+42
+SELECT * FROM address;
+id member_id
+2 42
+SELECT * FROM payment_method;
+id member_id cardholder_address_id
+3 42 2
+DELETE FROM member;
+COMMIT;
+SELECT * FROM member;
+id
+SELECT * FROM address;
+id member_id
+SELECT * FROM payment_method;
+id member_id cardholder_address_id
+DROP TABLE payment_method,address,member;
diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result
index e276303557e..ee1adc07661 100644
--- a/mysql-test/suite/innodb/r/innodb-autoinc.result
+++ b/mysql-test/suite/innodb/r/innodb-autoinc.result
@@ -1351,3 +1351,21 @@ t CREATE TABLE `t` (
KEY `i` (`i`)
) ENGINE=InnoDB AUTO_INCREMENT=401 DEFAULT CHARSET=latin1
DROP TABLE t;
+#
+# MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())
+#
+SET sql_mode=STRICT_ALL_TABLES;
+CREATE TABLE t1 (
+c1 DOUBLE NOT NULL PRIMARY KEY AUTO_INCREMENT
+) ENGINE=InnoDB AUTO_INCREMENT=10000000000000000000;
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1;
+c1
+1e19
+DROP TABLE t1;
+CREATE TABLE t1 (a DOUBLE PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (-1);
+SELECT * FROM t1;
+a
+-1
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb-fk-warnings.result b/mysql-test/suite/innodb/r/innodb-fk-warnings.result
index 792cae85b55..fc3f45f3d0a 100644
--- a/mysql-test/suite/innodb/r/innodb-fk-warnings.result
+++ b/mysql-test/suite/innodb/r/innodb-fk-warnings.result
@@ -27,7 +27,7 @@ show warnings;
Level Code Message
Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key a (a) references t1(a)) engine=innodb'.
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `t2`
drop table t1;
create table t1(a int not null primary key, b int) engine=innodb;
create table t2(a int, b int, constraint a foreign key a (a) references t1(a),
@@ -36,7 +36,7 @@ ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint
show warnings;
Level Code Message
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `t2`
create table t2(a int, b int, constraint a foreign key a (a) references t1(a)) engine=innodb;
alter table t2 add constraint b foreign key (b) references t2(b);
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
@@ -44,7 +44,7 @@ show warnings;
Level Code Message
Warning 150 Alter table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key (b) references t2(b)'.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `#sql-temporary`
drop table t2, t1;
create table t1 (f1 integer primary key) engine=innodb;
alter table t1 add constraint c1 foreign key (f1) references t11(f1);
@@ -53,7 +53,7 @@ show warnings;
Level Code Message
Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t11` not found in the data dictionary near ' foreign key (f1) references t11(f1)'.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `#sql-temporary`
drop table t1;
create temporary table t1(a int not null primary key, b int, key(b)) engine=innodb;
create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb;
@@ -76,14 +76,14 @@ show warnings;
Level Code Message
Warning 150 Create table `mysqld.1`.`t2` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary near 'foreign key(a) references t1(a)) engine=innodb'.
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `t2`
alter table t1 add foreign key(b) references t1(a);
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary near 'foreign key(b) references t1(a)'.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `#sql-temporary`
drop table t1;
create table t1(a int not null primary key, b int, key(b)) engine=innodb;
alter table t1 add foreign key(a,b) references t1(a);
@@ -106,14 +106,14 @@ show warnings;
Level Code Message
Warning 150 Alter table `test`.`t1` with foreign key constraint failed. You have defined a SET NULL condition but column 'f1' is defined as NOT NULL in ' foreign key (f1) references t1(f1) on update set null' near ' on update set null'.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `#sql-temporary`
create table t2(a int not null, foreign key(a) references t1(f1) on delete set null) engine=innodb;
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Create table `test`.`t2` with foreign key constraint failed. You have defined a SET NULL condition but column 'a' is defined as NOT NULL in 'foreign key(a) references t1(f1) on delete set null) engine=innodb' near ' on delete set null) engine=innodb'.
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `t2`
drop table t1;
create table t1 (id int not null primary key, f1 int, f2 int, key(f1)) engine=innodb;
create table t2(a char(20), key(a), foreign key(a) references t1(f1)) engine=innodb;
@@ -122,5 +122,5 @@ show warnings;
Level Code Message
Warning 150 Create table `test`.`t2` with foreign key constraint failed. Field type or character set for column 'a' does not mach referenced column 'f1' near 'foreign key(a) references t1(f1)) engine=innodb'.
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `t2`
drop table t1;
diff --git a/mysql-test/suite/innodb/r/innodb-fk.result b/mysql-test/suite/innodb/r/innodb-fk.result
index 2eb19764769..4efa0214999 100644
--- a/mysql-test/suite/innodb/r/innodb-fk.result
+++ b/mysql-test/suite/innodb/r/innodb-fk.result
@@ -53,7 +53,7 @@ Level Code Message
Warning 150 Create table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary near ' FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE
) ENGINE=InnoDB'.
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `t2`
CREATE TABLE t2 (
id int(11) NOT NULL AUTO_INCREMENT,
f2 int(11) NOT NULL,
@@ -67,7 +67,7 @@ show warnings;
Level Code Message
Warning 150 Alter table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary near ' FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE'.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `#sql-temporary`
drop table t2;
drop table t1;
CREATE DATABASE kg_test1;
diff --git a/mysql-test/suite/innodb/r/innodb-fkcheck.result b/mysql-test/suite/innodb/r/innodb-fkcheck.result
index c6beabb0f50..efa227e4035 100644
--- a/mysql-test/suite/innodb/r/innodb-fkcheck.result
+++ b/mysql-test/suite/innodb/r/innodb-fkcheck.result
@@ -37,7 +37,7 @@ ERROR HY000: Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint
show warnings;
Level Code Message
Error 1005 Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `b`
DROP TABLE IF EXISTS d;
Warnings:
Note 1051 Unknown table 'bug_fk.d'
@@ -76,7 +76,7 @@ ERROR HY000: Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint
show warnings;
Level Code Message
Error 1005 Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `b`
set foreign_key_checks=0;
drop table c;
drop table d;
diff --git a/mysql-test/suite/innodb/r/innodb-index-debug.result b/mysql-test/suite/innodb/r/innodb-index-debug.result
index beab075f3c8..5d161e5e6ca 100644
--- a/mysql-test/suite/innodb/r/innodb-index-debug.result
+++ b/mysql-test/suite/innodb/r/innodb-index-debug.result
@@ -95,7 +95,7 @@ SET DEBUG_SYNC= 'now SIGNAL flushed';
SET DEBUG_DBUG = @saved_debug_dbug;
connection con1;
/*con1 reap*/ ALTER TABLE t1 ADD COLUMN k4 int;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SELECT COUNT(k1),k2,k3 FROM t1 GROUP BY k2,k3;
COUNT(k1) k2 k3
480 aaa bbb
@@ -112,6 +112,35 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB AUTO_INCREMENT=1023 DEFAULT CHARSET=latin1
drop table t1;
drop table t480;
+#
+# MDEV-12827 Assertion failure when reporting duplicate key error
+# in online table rebuild
+#
+CREATE TABLE t1 (j INT UNIQUE, i INT UNIQUE) ENGINE=InnoDB;
+connect con1,localhost,root,,test;
+SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built WAIT_FOR log';
+ALTER TABLE t1 DROP j, FORCE;
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR built';
+INSERT INTO t1 (i) VALUES (0),(0);
+ERROR 23000: Duplicate entry '0' for key 'i'
+SET DEBUG_SYNC='now SIGNAL log';
+connection con1;
+ERROR 23000: Duplicate entry '0' for key 'i'
+SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built2 WAIT_FOR log2';
+ALTER TABLE t1 DROP j, FORCE;
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR built2';
+INSERT INTO t1 (i) VALUES (0),(1);
+UPDATE t1 SET i=0;
+ERROR 23000: Duplicate entry '0' for key 'i'
+SET DEBUG_SYNC='now SIGNAL log2';
+connection con1;
+ERROR 23000: Duplicate entry '0' for key 'i'
+disconnect con1;
+connection default;
+SET DEBUG_SYNC='RESET';
+DROP TABLE t1;
SET DEBUG_SYNC='RESET';
#
# BUG#21612714 ALTER TABLE SORTING SKIPPED WHEN CHANGE PK AND DROP
diff --git a/mysql-test/suite/innodb/r/innodb-index-online-fk.result b/mysql-test/suite/innodb/r/innodb-index-online-fk.result
index 359ce4a717c..47fc8e8b840 100644
--- a/mysql-test/suite/innodb/r/innodb-index-online-fk.result
+++ b/mysql-test/suite/innodb/r/innodb-index-online-fk.result
@@ -86,6 +86,7 @@ child CREATE TABLE `child` (
DELETE FROM parent where a = 1;
SELECT * FROM child;
a1 a2
+1 NULL
2 3
10 20
SET foreign_key_checks = 0;
@@ -126,6 +127,7 @@ SYS_TABLESPACES
SYS_VIRTUAL
mysql/innodb_index_stats
mysql/innodb_table_stats
+mysql/transaction_registry
test/child
test/parent
INSERT INTO child VALUES(5,4);
@@ -317,6 +319,7 @@ SYS_TABLESPACES
SYS_VIRTUAL
mysql/innodb_index_stats
mysql/innodb_table_stats
+mysql/transaction_registry
test/child
test/parent
ALTER TABLE child ADD PRIMARY KEY idx (a3), CHANGE a1 a3 INT,
@@ -342,6 +345,7 @@ SYS_TABLESPACES
SYS_VIRTUAL
mysql/innodb_index_stats
mysql/innodb_table_stats
+mysql/transaction_registry
test/child
test/parent
SHOW CREATE TABLE child;
@@ -378,6 +382,7 @@ SYS_TABLESPACES
SYS_VIRTUAL
mysql/innodb_index_stats
mysql/innodb_table_stats
+mysql/transaction_registry
test/child
test/parent
SHOW CREATE TABLE child;
@@ -414,6 +419,7 @@ SYS_TABLESPACES
SYS_VIRTUAL
mysql/innodb_index_stats
mysql/innodb_table_stats
+mysql/transaction_registry
test/child
test/parent
SHOW CREATE TABLE child;
diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result
index 5427f13043d..c646645ba7a 100644
--- a/mysql-test/suite/innodb/r/innodb-index-online.result
+++ b/mysql-test/suite/innodb/r/innodb-index-online.result
@@ -37,11 +37,11 @@ connection con1;
SET @saved_debug_dbug = @@SESSION.debug_dbug;
SET DEBUG_DBUG = '+d,innodb_OOM_prepare_inplace_alter';
ALTER TABLE t1 ADD UNIQUE INDEX(c2);
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET DEBUG_DBUG = @saved_debug_dbug;
SET DEBUG_DBUG = '+d,innodb_OOM_inplace_alter';
CREATE UNIQUE INDEX c2 ON t1(c2);
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET DEBUG_DBUG = @saved_debug_dbug;
CREATE UNIQUE INDEX c2 ON t1(c2);
DROP INDEX c2 ON t1;
@@ -470,8 +470,6 @@ ddl_online_create_index 0
ddl_pending_alter_table 0
ddl_sort_file_alter_table 0
ddl_log_file_alter_table 2
-connection con1;
-disconnect con1;
connection default;
SHOW CREATE TABLE t1;
Table Create Table
@@ -498,6 +496,25 @@ ERROR 42000: Duplicate key name 'c2h'
SET DEBUG_SYNC = 'RESET';
SET GLOBAL innodb_monitor_disable = module_ddl;
DROP TABLE t1;
+#
+# MDEV-13205 assertion !dict_index_is_online_ddl(index) upon ALTER TABLE
+#
+CREATE TABLE t1 (c VARCHAR(64)) ENGINE=InnoDB;
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL t1u_created WAIT_FOR dup_done';
+ALTER TABLE t1 ADD UNIQUE(c);
+connection con1;
+SET DEBUG_SYNC = 'now WAIT_FOR t1u_created';
+BEGIN;
+INSERT INTO t1 VALUES('bar'),('bar');
+SET DEBUG_SYNC = 'now SIGNAL dup_done';
+connection default;
+ERROR 23000: Duplicate entry 'bar' for key 'c'
+SET DEBUG_SYNC = 'RESET';
+disconnect con1;
+CREATE TABLE t2 (c VARCHAR(64)) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (c) REFERENCES t1 (c);
+ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
+DROP TABLE t2,t1;
SET GLOBAL innodb_file_per_table = @global_innodb_file_per_table_orig;
SET GLOBAL innodb_monitor_enable = default;
SET GLOBAL innodb_monitor_disable = default;
diff --git a/mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result b/mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result
new file mode 100644
index 00000000000..09e53b59d9d
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result
@@ -0,0 +1,10 @@
+call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool");
+SET @saved_debug = @@SESSION.debug_dbug;
+SET SESSION debug_dbug="+d,ib_lru_force_no_free_page";
+CREATE TABLE t1 (j LONGBLOB) ENGINE = InnoDB;
+BEGIN;
+INSERT INTO t1 VALUES (repeat('abcdefghijklmnopqrstuvwxyz',200));
+COMMIT;
+SET debug_dbug = @saved_debug;
+DROP TABLE t1;
+FOUND 1 /InnoDB: Difficult to find free blocks / in mysqld.1.err
diff --git a/mysql-test/suite/innodb/r/innodb-on-duplicate-update.result b/mysql-test/suite/innodb/r/innodb-on-duplicate-update.result
new file mode 100644
index 00000000000..474ebf33bbd
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-on-duplicate-update.result
@@ -0,0 +1,60 @@
+set sql_mode='';
+set innodb_strict_mode=0;
+CREATE TABLE `v` (
+`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+INSERT v values (1);
+CREATE TABLE `vp` (
+`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+`v_id` int(10) unsigned NOT NULL,
+`p_id` int(10) unsigned NOT NULL,
+`ppp` varchar(255) NOT NULL,
+PRIMARY KEY (`id`),
+UNIQUE KEY `IDX_vp_uniq` (`v_id`,`p_id`),
+KEY `FK_vp_v` (`v_id`),
+CONSTRAINT `FK_vp_v` FOREIGN KEY (`v_id`) REFERENCES `v` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+INSERT vp VALUES (12, 1, 100, 'text12');
+INSERT INTO `vp` (`id`,`ppp`) VALUES (12, 'test12-2') ON DUPLICATE KEY UPDATE `ppp` = VALUES(`ppp`);
+Warnings:
+Warning 1364 Field 'v_id' doesn't have a default value
+Warning 1364 Field 'p_id' doesn't have a default value
+SELECT * FROM vp;
+id v_id p_id ppp
+12 1 100 test12-2
+DROP TABLE vp, v;
+CREATE TABLE t1 (i int PRIMARY KEY) ENGINE=InnoDB;
+INSERT into t1 values (1);
+CREATE TABLE t2 (
+i int not null primary key,
+vi int not null,
+m int,
+UNIQUE KEY (vi),
+CONSTRAINT `cc` FOREIGN KEY (vi) REFERENCES t1 (i) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT into t2 VALUES (1, 1, 100);
+INSERT INTO t2 (i,m) VALUES (1, 2) ON DUPLICATE KEY UPDATE m=3;
+Warnings:
+Warning 1364 Field 'vi' doesn't have a default value
+SELECT * FROM t2;
+i vi m
+1 1 3
+DROP TABLE t2,t1;
+CREATE TABLE t1 (i int PRIMARY KEY) ENGINE=InnoDB;
+INSERT into t1 values (1);
+CREATE TABLE t2 (
+i int not null primary key,
+vi int not null,
+m int,
+KEY (vi),
+CONSTRAINT `cc` FOREIGN KEY (vi) REFERENCES t1 (i) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT into t2 VALUES (1, 1, 100);
+INSERT INTO t2 (i,m) VALUES (1, 2) ON DUPLICATE KEY UPDATE m=3;
+Warnings:
+Warning 1364 Field 'vi' doesn't have a default value
+SELECT * FROM t2;
+i vi m
+1 1 3
+DROP TABLE t2, t1;
diff --git a/mysql-test/suite/innodb/r/innodb-replace-debug.result b/mysql-test/suite/innodb/r/innodb-replace-debug.result
new file mode 100644
index 00000000000..989fb055cbc
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-replace-debug.result
@@ -0,0 +1,14 @@
+#
+# Bug#17604730 ASSERTION: *CURSOR->INDEX->NAME == TEMP_INDEX_PREFIX
+#
+create table t1 (f1 int primary key, f2 int, f3 int, unique key k1(f2),
+key k2(f3)) engine=innodb;
+insert into t1 values (14, 24, 34);
+set @old_dbug= @@session.debug_dbug;
+set debug_dbug = '+d,row_ins_sec_index_entry_timeout';
+replace into t1 values (14, 25, 34);
+select * from t1;
+f1 f2 f3
+14 25 34
+drop table t1;
+set debug_dbug = @old_dbug;
diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result
index 09ec3bbc252..3ac00436e07 100644
--- a/mysql-test/suite/innodb/r/innodb-table-online.result
+++ b/mysql-test/suite/innodb/r/innodb-table-online.result
@@ -42,7 +42,7 @@ connection con1;
SET @saved_debug_dbug = @@SESSION.debug_dbug;
SET DEBUG_DBUG = '+d,innodb_OOM_prepare_inplace_alter';
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION DEBUG = @saved_debug_dbug;
Warnings:
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
@@ -50,7 +50,7 @@ SET SESSION DEBUG = '+d,innodb_OOM_inplace_alter';
Warnings:
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION DEBUG = @saved_debug_dbug;
Warnings:
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result
index 99e9c49eee9..ec3856c20b8 100644
--- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result
+++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result
@@ -323,7 +323,7 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,ib_import_OOM_1";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
@@ -336,7 +336,7 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,ib_import_OOM_2";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
@@ -349,7 +349,7 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,ib_import_OOM_4";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
@@ -362,7 +362,7 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,ib_import_OOM_5";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
@@ -375,7 +375,7 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,ib_import_OOM_6";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
@@ -388,7 +388,7 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,ib_import_OOM_7";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
@@ -401,7 +401,7 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,ib_import_OOM_8";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
@@ -414,7 +414,7 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,ib_import_OOM_9";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
@@ -427,7 +427,7 @@ ERROR HY000: Tablespace has been discarded for table `t1`
restore: t1 .ibd and .cfg files
SET SESSION debug_dbug="+d,ib_import_OOM_10";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index edac0d0ab69..aafd31ae6f1 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -1,3 +1,5 @@
+create temporary table t (a char(1) character set filename) engine=innodb;
+drop temporary table t;
set optimizer_switch = 'mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
drop table if exists t1,t2,t3,t4;
drop database if exists mysqltest;
@@ -1318,80 +1320,17 @@ INSERT INTO t2 VALUES (10, 'old'), (20, 'other');
UPDATE t1 SET c1 = 'other' WHERE c1 = 'old';
ERROR 23000: Foreign key constraint for table 't1', record 'other-somevalu' would lead to a duplicate entry in table 't2', key 'c1'
DROP TABLE t2,t1;
-call mtr.add_suppression("Cannot delete/update rows with cascading foreign key constraints that exceed max depth of 255. Please drop excessive foreign constraints and try again");
+call mtr.add_suppression("Cannot delete/update rows with cascading foreign key constraints that exceed max depth of 15\\. Please drop excessive foreign constraints and try again");
create table t1(
id int primary key,
pid int,
index(pid),
foreign key(pid) references t1(id) on delete cascade) engine=innodb;
-insert into t1 values
-( 0, 0), ( 1, 0), ( 2, 1), ( 3, 2),
-( 4, 3), ( 5, 4), ( 6, 5), ( 7, 6),
-( 8, 7), ( 9, 8), ( 10, 9), ( 11, 10),
-( 12, 11), ( 13, 12), ( 14, 13), ( 15, 14),
-( 16, 15), ( 17, 16), ( 18, 17), ( 19, 18),
-( 20, 19), ( 21, 20), ( 22, 21), ( 23, 22),
-( 24, 23), ( 25, 24), ( 26, 25), ( 27, 26),
-( 28, 27), ( 29, 28), ( 30, 29), ( 31, 30),
-( 32, 31), ( 33, 32), ( 34, 33), ( 35, 34),
-( 36, 35), ( 37, 36), ( 38, 37), ( 39, 38),
-( 40, 39), ( 41, 40), ( 42, 41), ( 43, 42),
-( 44, 43), ( 45, 44), ( 46, 45), ( 47, 46),
-( 48, 47), ( 49, 48), ( 50, 49), ( 51, 50),
-( 52, 51), ( 53, 52), ( 54, 53), ( 55, 54),
-( 56, 55), ( 57, 56), ( 58, 57), ( 59, 58),
-( 60, 59), ( 61, 60), ( 62, 61), ( 63, 62),
-( 64, 63), ( 65, 64), ( 66, 65), ( 67, 66),
-( 68, 67), ( 69, 68), ( 70, 69), ( 71, 70),
-( 72, 71), ( 73, 72), ( 74, 73), ( 75, 74),
-( 76, 75), ( 77, 76), ( 78, 77), ( 79, 78),
-( 80, 79), ( 81, 80), ( 82, 81), ( 83, 82),
-( 84, 83), ( 85, 84), ( 86, 85), ( 87, 86),
-( 88, 87), ( 89, 88), ( 90, 89), ( 91, 90),
-( 92, 91), ( 93, 92), ( 94, 93), ( 95, 94),
-( 96, 95), ( 97, 96), ( 98, 97), ( 99, 98),
-(100, 99), (101, 100), (102, 101), (103, 102),
-(104, 103), (105, 104), (106, 105), (107, 106),
-(108, 107), (109, 108), (110, 109), (111, 110),
-(112, 111), (113, 112), (114, 113), (115, 114),
-(116, 115), (117, 116), (118, 117), (119, 118),
-(120, 119), (121, 120), (122, 121), (123, 122),
-(124, 123), (125, 124), (126, 125), (127, 126),
-(128, 127), (129, 128), (130, 129), (131, 130),
-(132, 131), (133, 132), (134, 133), (135, 134),
-(136, 135), (137, 136), (138, 137), (139, 138),
-(140, 139), (141, 140), (142, 141), (143, 142),
-(144, 143), (145, 144), (146, 145), (147, 146),
-(148, 147), (149, 148), (150, 149), (151, 150),
-(152, 151), (153, 152), (154, 153), (155, 154),
-(156, 155), (157, 156), (158, 157), (159, 158),
-(160, 159), (161, 160), (162, 161), (163, 162),
-(164, 163), (165, 164), (166, 165), (167, 166),
-(168, 167), (169, 168), (170, 169), (171, 170),
-(172, 171), (173, 172), (174, 173), (175, 174),
-(176, 175), (177, 176), (178, 177), (179, 178),
-(180, 179), (181, 180), (182, 181), (183, 182),
-(184, 183), (185, 184), (186, 185), (187, 186),
-(188, 187), (189, 188), (190, 189), (191, 190),
-(192, 191), (193, 192), (194, 193), (195, 194),
-(196, 195), (197, 196), (198, 197), (199, 198),
-(200, 199), (201, 200), (202, 201), (203, 202),
-(204, 203), (205, 204), (206, 205), (207, 206),
-(208, 207), (209, 208), (210, 209), (211, 210),
-(212, 211), (213, 212), (214, 213), (215, 214),
-(216, 215), (217, 216), (218, 217), (219, 218),
-(220, 219), (221, 220), (222, 221), (223, 222),
-(224, 223), (225, 224), (226, 225), (227, 226),
-(228, 227), (229, 228), (230, 229), (231, 230),
-(232, 231), (233, 232), (234, 233), (235, 234),
-(236, 235), (237, 236), (238, 237), (239, 238),
-(240, 239), (241, 240), (242, 241), (243, 242),
-(244, 243), (245, 244), (246, 245), (247, 246),
-(248, 247), (249, 248), (250, 249), (251, 250),
-(252, 251), (253, 252), (254, 253), (255, 254);
+insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
+(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
delete from t1 where id=0;
Got one of the listed errors
-delete from t1 where id=255;
+delete from t1 where id=15;
delete from t1 where id=0;
drop table t1;
CREATE TABLE t1 (col1 int(1))ENGINE=InnoDB;
@@ -1756,10 +1695,10 @@ variable_value
16384
SELECT variable_value - @innodb_rows_deleted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted';
variable_value - @innodb_rows_deleted_orig
-311
+71
SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted';
variable_value - @innodb_rows_inserted_orig
-1204
+964
SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated';
variable_value - @innodb_rows_updated_orig
866
@@ -3299,3 +3238,83 @@ show status like "handler_read_key";
Variable_name Value
Handler_read_key 0
drop table t1;
+CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
+CREATE TEMPORARY TABLE t2 (c1 INT) ENGINE=InnoDB;
+START TRANSACTION READ ONLY;
+INSERT INTO t2 VALUES(0);
+INSERT INTO t1 VALUES(0);
+ERROR 25006: Cannot execute statement in a READ ONLY transaction
+ROLLBACK;
+SELECT * FROM t1;
+c1
+SELECT * FROM t2;
+c1
+START TRANSACTION READ ONLY;
+INSERT INTO t1 VALUES(0);
+ERROR 25006: Cannot execute statement in a READ ONLY transaction
+INSERT INTO t2 VALUES(1);
+COMMIT;
+SET TRANSACTION READ ONLY;
+START TRANSACTION;
+INSERT INTO t2 VALUES(3);
+INSERT INTO t1 VALUES(0);
+ERROR 25006: Cannot execute statement in a READ ONLY transaction
+COMMIT;
+SELECT * FROM t1;
+c1
+SELECT * FROM t2;
+c1
+1
+3
+DROP TABLE t2;
+CREATE TEMPORARY TABLE t2 (
+c1 INT AUTO_INCREMENT PRIMARY KEY,
+c2 INT, INDEX idx(c2)) ENGINE=InnoDB;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TEMPORARY TABLE `t2` (
+ `c1` int(11) NOT NULL AUTO_INCREMENT,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `idx` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+START TRANSACTION READ ONLY;
+INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3);
+INSERT INTO t1 VALUES(0);
+ERROR 25006: Cannot execute statement in a READ ONLY transaction
+ROLLBACK;
+SELECT * FROM t1;
+c1
+SELECT * FROM t2;
+c1 c2
+START TRANSACTION READ ONLY;
+INSERT INTO t1 VALUES(0);
+ERROR 25006: Cannot execute statement in a READ ONLY transaction
+INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3);
+COMMIT;
+SET TRANSACTION READ ONLY;
+START TRANSACTION;
+INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3);
+INSERT INTO t1 VALUES(0);
+ERROR 25006: Cannot execute statement in a READ ONLY transaction
+COMMIT;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TEMPORARY TABLE `t2` (
+ `c1` int(11) NOT NULL AUTO_INCREMENT,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `idx` (`c2`)
+) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1
+SELECT * FROM t2;
+c1 c2
+4 1
+7 1
+5 2
+8 2
+6 3
+9 3
+DROP TABLE t1;
+DROP TABLE t2;
diff --git a/mysql-test/suite/innodb/r/innodb_buffer_pool_resize.result b/mysql-test/suite/innodb/r/innodb_buffer_pool_resize.result
new file mode 100644
index 00000000000..667d31a0b69
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_buffer_pool_resize.result
@@ -0,0 +1,34 @@
+set global innodb_adaptive_hash_index=ON;
+select @@innodb_buffer_pool_size;
+@@innodb_buffer_pool_size
+8388608
+set global innodb_buffer_pool_size = 10485760;
+Warnings:
+Warning 1292 Truncated incorrect innodb_buffer_pool_size value: '10485760'
+select @@innodb_buffer_pool_size;
+@@innodb_buffer_pool_size
+16777216
+create table t1 (id int not null, val int not null default '0', primary key (id)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+create or replace view view0 as select 1 union all select 1;
+set @`v_id` := 0;
+set @`v_val` := 0;
+replace into t1 select (@`v_id` := (@`v_id` + 4) mod 4294967296) as id, (@`v_val` := (@`v_val` + 4) mod 4294967296) as val from view0 v0, view0 v1, view0 v2, view0 v3, view0 v4, view0 v5, view0 v6, view0 v7, view0 v8, view0 v9, view0 v10, view0 v11, view0 v12, view0 v13, view0 v14, view0 v15, view0 v16, view0 v17;
+set global innodb_buffer_pool_size = 7340032;
+Warnings:
+Warning 1292 Truncated incorrect innodb_buffer_pool_size value: '7340032'
+select @@innodb_buffer_pool_size;
+@@innodb_buffer_pool_size
+8388608
+select count(val) from t1;
+count(val)
+262144
+set global innodb_adaptive_hash_index=OFF;
+set global innodb_buffer_pool_size = 25165824;
+select @@innodb_buffer_pool_size;
+@@innodb_buffer_pool_size
+25165824
+select count(val) from t1;
+count(val)
+262144
+drop table t1;
+drop view view0;
diff --git a/mysql-test/suite/innodb/r/innodb_buffer_pool_resize_with_chunks.result b/mysql-test/suite/innodb/r/innodb_buffer_pool_resize_with_chunks.result
new file mode 100644
index 00000000000..4bf244c9588
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_buffer_pool_resize_with_chunks.result
@@ -0,0 +1,26 @@
+select @@innodb_buffer_pool_chunk_size;
+@@innodb_buffer_pool_chunk_size
+2097152
+create table t1 (id int not null, val int not null default '0', primary key (id)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+create or replace view view0 as select 1 union all select 1;
+set @`v_id` := 0;
+set @`v_val` := 0;
+replace into t1 select (@`v_id` := (@`v_id` + 4) mod 4294967296) as id, (@`v_val` := (@`v_val` + 4) mod 4294967296) as val from view0 v0, view0 v1, view0 v2, view0 v3, view0 v4, view0 v5, view0 v6, view0 v7, view0 v8, view0 v9, view0 v10, view0 v11, view0 v12, view0 v13, view0 v14, view0 v15, view0 v16, view0 v17;
+set global innodb_buffer_pool_size = 7340032;
+Warnings:
+Warning 1292 Truncated incorrect innodb_buffer_pool_size value: '7340032'
+select count(val) from t1;
+count(val)
+262144
+set global innodb_buffer_pool_size = 16777216;
+select count(val) from t1;
+count(val)
+262144
+drop table t1;
+drop view view0;
+set global innodb_buffer_pool_size = 1048576;
+Warnings:
+Warning 1292 Truncated incorrect innodb_buffer_pool_size value: '1048576'
+select @@innodb_buffer_pool_size;
+@@innodb_buffer_pool_size
+6291456
diff --git a/mysql-test/suite/innodb/r/innodb_bulk_create_index.result b/mysql-test/suite/innodb/r/innodb_bulk_create_index.result
new file mode 100644
index 00000000000..ec7ce044cb7
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bulk_create_index.result
@@ -0,0 +1,1037 @@
+CREATE PROCEDURE populate_t1(load_even INT)
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+IF i%2 = 0 AND load_even = 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+IF i%2 != 0 AND load_even != 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+SELECT @@innodb_fill_factor;
+@@innodb_fill_factor
+100
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+5000
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+CREATE INDEX idx_title ON t1(title);
+/* Check table. */
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_id idx_id 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+/*Insert/Update/Delete. */
+DELETE FROM t1 WHERE id < 4010 AND id > 3990;
+INSERT INTO t1 VALUES(4000, 4000, 'b4000');
+UPDATE t1 SET title = CONCAT('b', id) WHERE id < 3010 AND id > 2990;
+SELECT * FROM t1 WHERE id = 3000;
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE title = 'a3000';
+class id title
+SELECT * FROM t1 WHERE title = 'b3000';
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE id = 4000;
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE title = 'a4000';
+class id title
+SELECT * FROM t1 WHERE title = 'b4000';
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE id = 4001;
+class id title
+SELECT * FROM t1 WHERE title = 'a4001';
+class id title
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+9992
+/* Add column. */
+ALTER TABLE t1 ADD COLUMN content TEXT;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE title = 'a10';
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE id = 5000;
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE id = 10000;
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE id = 10010;
+class id title content
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title content
+/* Drop column. */
+ALTER TABLE t1 DROP COLUMN content;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+ALTER TABLE t1 ADD INDEX `idx` (a,b(5));
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+10000
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+1
+UPDATE t1 SET b = REPEAT(CONCAT('b',4975),2000) WHERE a=4975 AND b like 'a4975%';
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+1
+DELETE FROM t1 WHERE a=4975 AND b like 'b4975%';
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+DROP TABLE t1;
+DROP PROCEDURE populate_t1;
+CREATE PROCEDURE populate_t1(load_even INT)
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+IF i%2 = 0 AND load_even = 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+IF i%2 != 0 AND load_even != 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+SELECT @@innodb_fill_factor;
+@@innodb_fill_factor
+100
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+5000
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+CREATE INDEX idx_title ON t1(title);
+/* Check table. */
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_id idx_id 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+/*Insert/Update/Delete. */
+DELETE FROM t1 WHERE id < 4010 AND id > 3990;
+INSERT INTO t1 VALUES(4000, 4000, 'b4000');
+UPDATE t1 SET title = CONCAT('b', id) WHERE id < 3010 AND id > 2990;
+SELECT * FROM t1 WHERE id = 3000;
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE title = 'a3000';
+class id title
+SELECT * FROM t1 WHERE title = 'b3000';
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE id = 4000;
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE title = 'a4000';
+class id title
+SELECT * FROM t1 WHERE title = 'b4000';
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE id = 4001;
+class id title
+SELECT * FROM t1 WHERE title = 'a4001';
+class id title
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+9992
+/* Add column. */
+ALTER TABLE t1 ADD COLUMN content TEXT;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE title = 'a10';
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE id = 5000;
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE id = 10000;
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE id = 10010;
+class id title content
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title content
+/* Drop column. */
+ALTER TABLE t1 DROP COLUMN content;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+ALTER TABLE t1 ADD INDEX `idx` (a,b(5));
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+10000
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+1
+UPDATE t1 SET b = REPEAT(CONCAT('b',4975),2000) WHERE a=4975 AND b like 'a4975%';
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+1
+DELETE FROM t1 WHERE a=4975 AND b like 'b4975%';
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+DROP TABLE t1;
+DROP PROCEDURE populate_t1;
+CREATE PROCEDURE populate_t1(load_even INT)
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+IF i%2 = 0 AND load_even = 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+IF i%2 != 0 AND load_even != 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+SELECT @@innodb_fill_factor;
+@@innodb_fill_factor
+100
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+5000
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+CREATE INDEX idx_title ON t1(title);
+/* Check table. */
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_id idx_id 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+/*Insert/Update/Delete. */
+DELETE FROM t1 WHERE id < 4010 AND id > 3990;
+INSERT INTO t1 VALUES(4000, 4000, 'b4000');
+UPDATE t1 SET title = CONCAT('b', id) WHERE id < 3010 AND id > 2990;
+SELECT * FROM t1 WHERE id = 3000;
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE title = 'a3000';
+class id title
+SELECT * FROM t1 WHERE title = 'b3000';
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE id = 4000;
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE title = 'a4000';
+class id title
+SELECT * FROM t1 WHERE title = 'b4000';
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE id = 4001;
+class id title
+SELECT * FROM t1 WHERE title = 'a4001';
+class id title
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+9992
+/* Add column. */
+ALTER TABLE t1 ADD COLUMN content TEXT;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE title = 'a10';
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE id = 5000;
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE id = 10000;
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE id = 10010;
+class id title content
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title content
+/* Drop column. */
+ALTER TABLE t1 DROP COLUMN content;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+ALTER TABLE t1 ADD INDEX `idx` (a,b(5));
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+10000
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+1
+UPDATE t1 SET b = REPEAT(CONCAT('b',4975),2000) WHERE a=4975 AND b like 'a4975%';
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+1
+DELETE FROM t1 WHERE a=4975 AND b like 'b4975%';
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+DROP TABLE t1;
+DROP PROCEDURE populate_t1;
+CREATE PROCEDURE populate_t1(load_even INT)
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+IF i%2 = 0 AND load_even = 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+IF i%2 != 0 AND load_even != 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+SELECT @@innodb_fill_factor;
+@@innodb_fill_factor
+100
+SET GLOBAL innodb_file_per_table=1;
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+5000
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+CREATE INDEX idx_title ON t1(title);
+/* Check table. */
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_id idx_id 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+/*Insert/Update/Delete. */
+DELETE FROM t1 WHERE id < 4010 AND id > 3990;
+INSERT INTO t1 VALUES(4000, 4000, 'b4000');
+UPDATE t1 SET title = CONCAT('b', id) WHERE id < 3010 AND id > 2990;
+SELECT * FROM t1 WHERE id = 3000;
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE title = 'a3000';
+class id title
+SELECT * FROM t1 WHERE title = 'b3000';
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE id = 4000;
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE title = 'a4000';
+class id title
+SELECT * FROM t1 WHERE title = 'b4000';
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE id = 4001;
+class id title
+SELECT * FROM t1 WHERE title = 'a4001';
+class id title
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+9992
+/* Add column. */
+ALTER TABLE t1 ADD COLUMN content TEXT;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE title = 'a10';
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE id = 5000;
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE id = 10000;
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE id = 10010;
+class id title content
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title content
+/* Drop column. */
+ALTER TABLE t1 DROP COLUMN content;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b BLOB,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+ALTER TABLE t1 ADD INDEX `idx` (a,b(5));
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+10000
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+1
+UPDATE t1 SET b = REPEAT(CONCAT('b',4975),2000) WHERE a=4975 AND b like 'a4975%';
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+1
+DELETE FROM t1 WHERE a=4975 AND b like 'b4975%';
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+DROP TABLE t1;
+SET GLOBAL innodb_file_per_table=default;
+DROP PROCEDURE populate_t1;
+SET GLOBAL innodb_fill_factor=10;
+CREATE PROCEDURE populate_t1(load_even INT)
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+IF i%2 = 0 AND load_even = 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+IF i%2 != 0 AND load_even != 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+SELECT @@innodb_fill_factor;
+@@innodb_fill_factor
+10
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+5000
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+CREATE INDEX idx_title ON t1(title);
+/* Check table. */
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_id idx_id 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+/*Insert/Update/Delete. */
+DELETE FROM t1 WHERE id < 4010 AND id > 3990;
+INSERT INTO t1 VALUES(4000, 4000, 'b4000');
+UPDATE t1 SET title = CONCAT('b', id) WHERE id < 3010 AND id > 2990;
+SELECT * FROM t1 WHERE id = 3000;
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE title = 'a3000';
+class id title
+SELECT * FROM t1 WHERE title = 'b3000';
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE id = 4000;
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE title = 'a4000';
+class id title
+SELECT * FROM t1 WHERE title = 'b4000';
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE id = 4001;
+class id title
+SELECT * FROM t1 WHERE title = 'a4001';
+class id title
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+9992
+/* Add column. */
+ALTER TABLE t1 ADD COLUMN content TEXT;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE title = 'a10';
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE id = 5000;
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE id = 10000;
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE id = 10010;
+class id title content
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title content
+/* Drop column. */
+ALTER TABLE t1 DROP COLUMN content;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+ALTER TABLE t1 ADD INDEX `idx` (a,b(5));
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+10000
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+1
+UPDATE t1 SET b = REPEAT(CONCAT('b',4975),2000) WHERE a=4975 AND b like 'a4975%';
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+1
+DELETE FROM t1 WHERE a=4975 AND b like 'b4975%';
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+DROP TABLE t1;
+DROP PROCEDURE populate_t1;
+SET GLOBAL innodb_fill_factor=50;
+CREATE PROCEDURE populate_t1(load_even INT)
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+IF i%2 = 0 AND load_even = 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+IF i%2 != 0 AND load_even != 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+SELECT @@innodb_fill_factor;
+@@innodb_fill_factor
+50
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+5000
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+CREATE INDEX idx_title ON t1(title);
+/* Check table. */
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_id idx_id 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+/*Insert/Update/Delete. */
+DELETE FROM t1 WHERE id < 4010 AND id > 3990;
+INSERT INTO t1 VALUES(4000, 4000, 'b4000');
+UPDATE t1 SET title = CONCAT('b', id) WHERE id < 3010 AND id > 2990;
+SELECT * FROM t1 WHERE id = 3000;
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE title = 'a3000';
+class id title
+SELECT * FROM t1 WHERE title = 'b3000';
+class id title
+3000 3000 b3000
+SELECT * FROM t1 WHERE id = 4000;
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE title = 'a4000';
+class id title
+SELECT * FROM t1 WHERE title = 'b4000';
+class id title
+4000 4000 b4000
+SELECT * FROM t1 WHERE id = 4001;
+class id title
+SELECT * FROM t1 WHERE title = 'a4001';
+class id title
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+9992
+/* Add column. */
+ALTER TABLE t1 ADD COLUMN content TEXT;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE title = 'a10';
+class id title content
+10 10 a10 NULL
+SELECT * FROM t1 WHERE id = 5000;
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title content
+5000 5000 a5000 NULL
+SELECT * FROM t1 WHERE id = 10000;
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title content
+10000 10000 a10000 NULL
+SELECT * FROM t1 WHERE id = 10010;
+class id title content
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title content
+/* Drop column. */
+ALTER TABLE t1 DROP COLUMN content;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 5000;
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE id = 10000;
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE id = 10010;
+class id title
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+ALTER TABLE t1 ADD INDEX `idx` (a,b(5));
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+10000
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+1
+UPDATE t1 SET b = REPEAT(CONCAT('b',4975),2000) WHERE a=4975 AND b like 'a4975%';
+SELECT b=REPEAT(CONCAT('a',4975),2000) FROM t1 WHERE a=4975 AND b like 'a4975%';
+b=REPEAT(CONCAT('a',4975),2000)
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+1
+DELETE FROM t1 WHERE a=4975 AND b like 'b4975%';
+SELECT b=REPEAT(CONCAT('b',4975),2000) FROM t1 WHERE a=4975 AND b like 'b4975%';
+b=REPEAT(CONCAT('b',4975),2000)
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+DROP TABLE t1;
+DROP PROCEDURE populate_t1;
+SET GLOBAL innodb_fill_factor=default;
diff --git a/mysql-test/suite/innodb/r/innodb_bulk_create_index_debug.result b/mysql-test/suite/innodb/r/innodb_bulk_create_index_debug.result
new file mode 100644
index 00000000000..cd5a3c340da
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bulk_create_index_debug.result
@@ -0,0 +1,485 @@
+CREATE PROCEDURE populate_t1()
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+10000
+CREATE INDEX idx_title ON t1(title);
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+# Test Blob
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+INSERT INTO t1 VALUES
+(1, REPEAT('a',10000), 'a'),
+(2, REPEAT('b',20000), 'b'),
+(3, REPEAT('c',40000), 'c'),
+(4, REPEAT('d',60000), 'd');
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+DROP TABLE t1;
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+SET debug_dbug='+d,crash_commit_before';
+CREATE INDEX idx_title ON t1(title);
+ERROR HY000: Lost connection to MySQL server during query
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+10000
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+# Test Blob
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+INSERT INTO t1 VALUES
+(1, REPEAT('a',10000), 'a'),
+(2, REPEAT('b',20000), 'b'),
+(3, REPEAT('c',40000), 'c'),
+(4, REPEAT('d',60000), 'd');
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+SET debug_dbug='+d,crash_commit_before';
+ALTER TABLE t1 DROP COLUMN c;
+ERROR HY000: Lost connection to MySQL server during query
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+DROP TABLE t1;
+DROP PROCEDURE populate_t1;
+CREATE PROCEDURE populate_t1()
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+10000
+CREATE INDEX idx_title ON t1(title);
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+# Test Blob
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+INSERT INTO t1 VALUES
+(1, REPEAT('a',10000), 'a'),
+(2, REPEAT('b',20000), 'b'),
+(3, REPEAT('c',40000), 'c'),
+(4, REPEAT('d',60000), 'd');
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+DROP TABLE t1;
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+SET debug_dbug='+d,crash_commit_before';
+CREATE INDEX idx_title ON t1(title);
+ERROR HY000: Lost connection to MySQL server during query
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+10000
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+# Test Blob
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+INSERT INTO t1 VALUES
+(1, REPEAT('a',10000), 'a'),
+(2, REPEAT('b',20000), 'b'),
+(3, REPEAT('c',40000), 'c'),
+(4, REPEAT('d',60000), 'd');
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+SET debug_dbug='+d,crash_commit_before';
+ALTER TABLE t1 DROP COLUMN c;
+ERROR HY000: Lost connection to MySQL server during query
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+DROP TABLE t1;
+DROP PROCEDURE populate_t1;
+CREATE PROCEDURE populate_t1()
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+10000
+CREATE INDEX idx_title ON t1(title);
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+# Test Blob
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES
+(1, REPEAT('a',10000), 'a'),
+(2, REPEAT('b',20000), 'b'),
+(3, REPEAT('c',40000), 'c'),
+(4, REPEAT('d',60000), 'd');
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+DROP TABLE t1;
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+SET debug_dbug='+d,crash_commit_before';
+CREATE INDEX idx_title ON t1(title);
+ERROR HY000: Lost connection to MySQL server during query
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+10000
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+# Test Blob
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES
+(1, REPEAT('a',10000), 'a'),
+(2, REPEAT('b',20000), 'b'),
+(3, REPEAT('c',40000), 'c'),
+(4, REPEAT('d',60000), 'd');
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+SET debug_dbug='+d,crash_commit_before';
+ALTER TABLE t1 DROP COLUMN c;
+ERROR HY000: Lost connection to MySQL server during query
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+DROP TABLE t1;
+DROP PROCEDURE populate_t1;
+CREATE PROCEDURE populate_t1()
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+SET GLOBAL innodb_file_per_table=1;
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+10000
+CREATE INDEX idx_title ON t1(title);
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+# Test Blob
+SET GLOBAL innodb_file_per_table=1;
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+INSERT INTO t1 VALUES
+(1, REPEAT('a',10000), 'a'),
+(2, REPEAT('b',20000), 'b'),
+(3, REPEAT('c',40000), 'c'),
+(4, REPEAT('d',60000), 'd');
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+DROP TABLE t1;
+SET GLOBAL innodb_file_per_table=1;
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+SET debug_dbug='+d,crash_commit_before';
+CREATE INDEX idx_title ON t1(title);
+ERROR HY000: Lost connection to MySQL server during query
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+10000
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a5000';
+class id title
+5000 5000 a5000
+SELECT * FROM t1 WHERE title = 'a10000';
+class id title
+10000 10000 a10000
+SELECT * FROM t1 WHERE title = 'a10010';
+class id title
+DROP TABLE t1;
+# Test Blob
+SET GLOBAL innodb_file_per_table=1;
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+INSERT INTO t1 VALUES
+(1, REPEAT('a',10000), 'a'),
+(2, REPEAT('b',20000), 'b'),
+(3, REPEAT('c',40000), 'c'),
+(4, REPEAT('d',60000), 'd');
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+SET debug_dbug='+d,crash_commit_before';
+ALTER TABLE t1 DROP COLUMN c;
+ERROR HY000: Lost connection to MySQL server during query
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1;
+CHAR_LENGTH(b)
+10000
+20000
+40000
+60000
+DROP TABLE t1;
+SET GLOBAL innodb_file_per_table=default;
+DROP PROCEDURE populate_t1;
diff --git a/mysql-test/suite/innodb/r/innodb_bulk_create_index_flush.result b/mysql-test/suite/innodb/r/innodb_bulk_create_index_flush.result
new file mode 100644
index 00000000000..d2b812642f6
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bulk_create_index_flush.result
@@ -0,0 +1,54 @@
+CREATE PROCEDURE populate_t1()
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 10000) DO
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+10000
+SET @saved_dbug= @@SESSION.debug_dbug;
+SET debug_dbug='+d,ib_index_build_fail_before_flush';
+CREATE INDEX idx_id ON t1(id);
+ERROR 70100: Query execution was interrupted
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+CREATE INDEX idx_title ON t1(title);
+ERROR 70100: Query execution was interrupted
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+CREATE FULLTEXT INDEX fidx_title ON t1(title);
+ERROR 70100: Query execution was interrupted
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+ALTER TABLE t1 ADD COLUMN content TEXT, FORCE;
+ERROR 70100: Query execution was interrupted
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SET debug_dbug= @saved_dbug;
+INSERT INTO t1 VALUES(10001, 10001, 'a10000');
+ALTER TABLE t1 ADD UNIQUE INDEX idx_title(title);
+ERROR 23000: Duplicate entry 'a10000' for key 'idx_title'
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+ALTER TABLE t1 ADD UNIQUE INDEX idx_id(id), ADD UNIQUE INDEX idx_title(title);
+ERROR 23000: Duplicate entry 'a10000' for key 'idx_title'
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
+DROP PROCEDURE populate_t1;
diff --git a/mysql-test/suite/innodb/r/innodb_bulk_create_index_replication.result b/mysql-test/suite/innodb/r/innodb_bulk_create_index_replication.result
new file mode 100644
index 00000000000..ae050170b4f
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bulk_create_index_replication.result
@@ -0,0 +1,222 @@
+include/master-slave.inc
+[connection master]
+connection master;
+CREATE PROCEDURE populate_t1(load_even INT)
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 100) DO
+IF i%2 = 0 AND load_even = 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+IF i%2 != 0 AND load_even != 1 THEN
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+END IF;
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+50
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+CREATE INDEX idx_title ON t1(title);
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_id idx_id 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 20;
+class id title
+20 20 a20
+SELECT * FROM t1 WHERE title = 'a20';
+class id title
+20 20 a20
+SELECT * FROM t1 WHERE id = 30;
+class id title
+30 30 a30
+SELECT * FROM t1 WHERE title = 'a30';
+class id title
+30 30 a30
+SELECT * FROM t1 WHERE id = 101;
+class id title
+SELECT * FROM t1 WHERE title = 'a101';
+class id title
+/*Insert/Update/Delete. */
+DELETE FROM t1 WHERE id < 40 AND id > 30;
+INSERT INTO t1 VALUES(38, 38, 'b38');
+UPDATE t1 SET title = CONCAT('b', id) WHERE id < 30 AND id > 20;
+SELECT * FROM t1 WHERE id = 28;
+class id title
+28 28 b28
+SELECT * FROM t1 WHERE title = 'a28';
+class id title
+SELECT * FROM t1 WHERE title = 'b28';
+class id title
+28 28 b28
+SELECT * FROM t1 WHERE id = 38;
+class id title
+38 38 b38
+SELECT * FROM t1 WHERE title = 'a38';
+class id title
+SELECT * FROM t1 WHERE title = 'b38';
+class id title
+38 38 b38
+SELECT * FROM t1 WHERE id = 101;
+class id title
+SELECT * FROM t1 WHERE title = 'a101';
+class id title
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+97
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 20;
+class id title
+20 20 a20
+SELECT * FROM t1 WHERE title = 'a20';
+class id title
+20 20 a20
+SELECT * FROM t1 WHERE id = 30;
+class id title
+30 30 a30
+SELECT * FROM t1 WHERE title = 'a30';
+class id title
+30 30 a30
+SELECT * FROM t1 WHERE id = 101;
+class id title
+SELECT * FROM t1 WHERE title = 'a101';
+class id title
+CREATE TABLE t_part (
+class INT ,
+id INT ,
+title VARCHAR(30)
+) ENGINE=InnoDB
+PARTITION BY RANGE(id)
+SUBPARTITION BY KEY(id)
+SUBPARTITIONS 4
+(
+PARTITION p0 VALUES LESS THAN (5000),
+PARTITION p1 VALUES LESS THAN (MAXVALUE)
+);
+INSERT INTO t_part SELECT * FROM t1;
+ALTER TABLE t_part ADD INDEX `idx` (class,id,title(10));
+SELECT * FROM t_part WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t_part WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t_part WHERE id = 20;
+class id title
+20 20 a20
+SELECT * FROM t_part WHERE title = 'a20';
+class id title
+20 20 a20
+SELECT * FROM t_part WHERE id = 30;
+class id title
+30 30 a30
+SELECT * FROM t_part WHERE title = 'a30';
+class id title
+30 30 a30
+SELECT * FROM t_part WHERE id = 101;
+class id title
+SELECT * FROM t_part WHERE title = 'a101';
+class id title
+include/sync_slave_sql_with_master.inc
+connection slave;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `class` int(11) DEFAULT NULL,
+ `id` int(11) DEFAULT NULL,
+ `title` varchar(100) DEFAULT NULL,
+ KEY `idx_id` (`id`),
+ KEY `idx_title` (`title`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t_part;
+Table Create Table
+t_part CREATE TABLE `t_part` (
+ `class` int(11) DEFAULT NULL,
+ `id` int(11) DEFAULT NULL,
+ `title` varchar(30) DEFAULT NULL,
+ KEY `idx` (`class`,`id`,`title`(10))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (`id`)
+SUBPARTITION BY KEY (`id`)
+SUBPARTITIONS 4
+(PARTITION `p0` VALUES LESS THAN (5000) ENGINE = InnoDB,
+ PARTITION `p1` VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+97
+SELECT COUNT(*) FROM t_part;
+COUNT(*)
+97
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 20;
+class id title
+20 20 a20
+SELECT * FROM t1 WHERE title = 'a20';
+class id title
+20 20 a20
+SELECT * FROM t1 WHERE id = 30;
+class id title
+30 30 a30
+SELECT * FROM t1 WHERE title = 'a30';
+class id title
+30 30 a30
+SELECT * FROM t1 WHERE id = 101;
+class id title
+SELECT * FROM t1 WHERE title = 'a101';
+class id title
+SELECT * FROM t_part WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t_part WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t_part WHERE id = 20;
+class id title
+20 20 a20
+SELECT * FROM t_part WHERE title = 'a20';
+class id title
+20 20 a20
+SELECT * FROM t_part WHERE id = 30;
+class id title
+30 30 a30
+SELECT * FROM t_part WHERE title = 'a30';
+class id title
+30 30 a30
+SELECT * FROM t_part WHERE id = 101;
+class id title
+SELECT * FROM t_part WHERE title = 'a101';
+class id title
+connection master;
+DROP PROCEDURE populate_t1;
+DROP TABLE t1;
+DROP TABLE t_part;
+include/rpl_end.inc
diff --git a/mysql-test/suite/innodb/r/innodb_bulk_create_index_small.result b/mysql-test/suite/innodb/r/innodb_bulk_create_index_small.result
new file mode 100644
index 00000000000..b48207d4497
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bulk_create_index_small.result
@@ -0,0 +1,139 @@
+CREATE PROCEDURE populate_t1()
+BEGIN
+DECLARE i int DEFAULT 1;
+START TRANSACTION;
+WHILE (i <= 1000) DO
+INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END|
+SELECT @@innodb_fill_factor;
+@@innodb_fill_factor
+100
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+1000
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+CREATE INDEX idx_title ON t1(title);
+/* Check table. */
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_id idx_id 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 500;
+class id title
+500 500 a500
+SELECT * FROM t1 WHERE title = 'a500';
+class id title
+500 500 a500
+SELECT * FROM t1 WHERE id = 1000;
+class id title
+1000 1000 a1000
+SELECT * FROM t1 WHERE title = 'a1000';
+class id title
+1000 1000 a1000
+SELECT * FROM t1 WHERE id = 1010;
+class id title
+SELECT * FROM t1 WHERE title = 'a1010';
+class id title
+DROP TABLE t1;
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+INSERT INTO t1 VALUES
+(1, REPEAT('a',10000), 'a'),
+(2, REPEAT('b',20000), 'b'),
+(3, REPEAT('c',40000), 'c'),
+(4, REPEAT('d',60000), 'd');
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+DROP TABLE t1;
+SET GLOBAL innodb_file_per_table=default;
+SET GLOBAL innodb_file_per_table=1;
+CREATE TABLE t1(
+class INT,
+id INT,
+title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+1000
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+CREATE INDEX idx_title ON t1(title);
+/* Check table. */
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_id idx_id 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx_title idx_title 103 const 1 Using index condition
+SELECT * FROM t1 WHERE id = 10;
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE title = 'a10';
+class id title
+10 10 a10
+SELECT * FROM t1 WHERE id = 500;
+class id title
+500 500 a500
+SELECT * FROM t1 WHERE title = 'a500';
+class id title
+500 500 a500
+SELECT * FROM t1 WHERE id = 1000;
+class id title
+1000 1000 a1000
+SELECT * FROM t1 WHERE title = 'a1000';
+class id title
+1000 1000 a1000
+SELECT * FROM t1 WHERE id = 1010;
+class id title
+SELECT * FROM t1 WHERE title = 'a1010';
+class id title
+DROP TABLE t1;
+CREATE TABLE t1(
+a INT PRIMARY KEY,
+b TEXT,
+c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+INSERT INTO t1 VALUES
+(1, REPEAT('a',10000), 'a'),
+(2, REPEAT('b',20000), 'b'),
+(3, REPEAT('c',40000), 'c'),
+(4, REPEAT('d',60000), 'd');
+ALTER TABLE t1 DROP COLUMN c;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+CHAR_LENGTH(b)
+DROP TABLE t1;
+SET GLOBAL innodb_file_per_table=default;
+DROP PROCEDURE populate_t1;
diff --git a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result
index d614ebff751..2000db03efa 100644
--- a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result
+++ b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result
@@ -16,18 +16,15 @@ INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+1,z+1 FROM corrupt_bit_test_Ä;
select count(*) from corrupt_bit_test_Ä;
count(*)
2
-SET SESSION debug="+d,dict_set_index_corrupted";
-Warnings:
-Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+SET @save_dbug = @@SESSION.debug_dbug;
+SET debug_dbug = '+d,dict_set_index_corrupted';
check table corrupt_bit_test_Ä;
Table Op Msg_type Msg_text
test.corrupt_bit_test_Ä check Warning InnoDB: Index idx is marked as corrupted
test.corrupt_bit_test_Ä check Warning InnoDB: Index idxÄ is marked as corrupted
test.corrupt_bit_test_Ä check Warning InnoDB: Index idxÄ“ is marked as corrupted
test.corrupt_bit_test_Ä check error Corrupt
-SET SESSION debug="-d,dict_set_index_corrupted";
-Warnings:
-Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+SET debug_dbug = @save_dbug;
CREATE INDEX idx3 ON corrupt_bit_test_Ä(b, c);
ERROR HY000: Index idx is corrupted
CREATE INDEX idx4 ON corrupt_bit_test_Ä(b, z);
diff --git a/mysql-test/suite/innodb/r/innodb_max_recordsize_32k.result b/mysql-test/suite/innodb/r/innodb_max_recordsize_32k.result
index c2bb0ba0aa8..117b7e4418e 100644
--- a/mysql-test/suite/innodb/r/innodb_max_recordsize_32k.result
+++ b/mysql-test/suite/innodb/r/innodb_max_recordsize_32k.result
@@ -2,14 +2,7 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the
SELECT @@innodb_page_size;
@@innodb_page_size
32768
-SET GLOBAL innodb_file_per_table=ON;
-SET @@innodb_strict_mode=ON;
-SELECT @@innodb_file_per_table;
-@@innodb_file_per_table
-1
-SELECT @@innodb_strict_mode;
-@@innodb_strict_mode
-1
+SET innodb_strict_mode=ON;
CREATE TABLE tab5(col1 CHAR (255), col2 CHAR (255), col3 CHAR(255),col4 CHAR(255), col5 CHAR(255),
col6 CHAR(255), col7 CHAR(255), col8 CHAR(255), col9 CHAR(255),col10 CHAR(255), col11 CHAR(255),
col12 CHAR(255), col13 CHAR(255),col14 CHAR(255),col15 CHAR(255),col16 CHAR(255), col17 CHAR(255),
@@ -333,11 +326,9 @@ FLUSH TABLE t;
ANALYZE TABLE t;
Table Op Msg_type Msg_text
test.t analyze status OK
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-stat_value
-6
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
-clustered_index_size
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
+clust_index_size
7
DROP TABLE t;
CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
@@ -355,11 +346,9 @@ FLUSH TABLE t;
ANALYZE TABLE t;
Table Op Msg_type Msg_text
test.t analyze status OK
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-stat_value
-4
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
-clustered_index_size
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
+clust_index_size
5
DROP TABLE t;
CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=COMPACT;
@@ -377,11 +366,8 @@ FLUSH TABLE t;
ANALYZE TABLE t;
Table Op Msg_type Msg_text
test.t analyze status OK
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-stat_value
-4
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
-clustered_index_size
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
+clust_index_size
5
DROP TABLE t;
-# Success
diff --git a/mysql-test/suite/innodb/r/innodb_max_recordsize_64k.result b/mysql-test/suite/innodb/r/innodb_max_recordsize_64k.result
index 31dcae834bf..de957023ff8 100644
--- a/mysql-test/suite/innodb/r/innodb_max_recordsize_64k.result
+++ b/mysql-test/suite/innodb/r/innodb_max_recordsize_64k.result
@@ -2,14 +2,7 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the
SELECT @@innodb_page_size;
@@innodb_page_size
65536
-SET GLOBAL innodb_file_per_table=ON;
-SET @@innodb_strict_mode=ON;
-SELECT @@innodb_file_per_table;
-@@innodb_file_per_table
-1
-SELECT @@innodb_strict_mode;
-@@innodb_strict_mode
-1
+SET innodb_strict_mode=ON;
CREATE TABLE tab5(col1 CHAR (255), col2 CHAR (255), col3 CHAR(255),col4 CHAR(255), col5 CHAR(255),
col6 CHAR(255), col7 CHAR(255), col8 CHAR(255), col9 CHAR(255),col10 CHAR(255), col11 CHAR(255),
col12 CHAR(255), col13 CHAR(255),col14 CHAR(255),col15 CHAR(255),col16 CHAR(255), col17 CHAR(255),
@@ -536,11 +529,9 @@ FLUSH TABLE t;
ANALYZE TABLE t;
Table Op Msg_type Msg_text
test.t analyze status OK
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-stat_value
-4
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
-clustered_index_size
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
+clust_index_size
5
DROP TABLE t;
CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
@@ -558,11 +549,9 @@ FLUSH TABLE t;
ANALYZE TABLE t;
Table Op Msg_type Msg_text
test.t analyze status OK
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-stat_value
-3
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
-clustered_index_size
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
+clust_index_size
4
DROP TABLE t;
CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=COMPACT;
@@ -580,11 +569,8 @@ FLUSH TABLE t;
ANALYZE TABLE t;
Table Op Msg_type Msg_text
test.t analyze status OK
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-stat_value
-3
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
-clustered_index_size
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
+clust_index_size
4
DROP TABLE t;
-# Success
diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result
index cdfdbad9e20..3663c18ea44 100644
--- a/mysql-test/suite/innodb/r/innodb_mysql.result
+++ b/mysql-test/suite/innodb/r/innodb_mysql.result
@@ -238,14 +238,14 @@ select 1, max(1) from t1i where 1=99;
1 NULL
explain select count(*), min(7), max(7) from t1m, t1i;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1m system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t1m system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t1i ALL NULL NULL NULL NULL 1
select count(*), min(7), max(7) from t1m, t1i;
count(*) min(7) max(7)
0 NULL NULL
explain select count(*), min(7), max(7) from t1m, t2i;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1m system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t1m system NULL NULL NULL NULL 0 Const row not found
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
select count(*), min(7), max(7) from t1m, t2i;
count(*) min(7) max(7)
@@ -1853,7 +1853,7 @@ explain
select b from t1 where a not in (select max(b) from t1,t2 group by a) group by a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 Const row not found
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 1
set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2;
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 103937fa408..79f0e73e745 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
@@ -395,6 +395,6 @@ NAME CREATE_FILE CREATE_LINE OS_WAITS
Warnings:
Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_mutexes but the InnoDB storage engine is not installed
select * from information_schema.innodb_sys_semaphore_waits;
-THREAD_ID OBJECT_NAME FILE LINE WAIT_TIME WAIT_OBJECT WAIT_TYPE HOLDER_THREAD_ID HOLDER_FILE HOLDER_LINE CREATED_FILE CREATED_LINE WRITER_THREAD RESERVATION_MODE READERS WAITERS_FLAG LOCK_WORD LAST_READER_FILE LAST_READER_LINE LAST_WRITER_FILE LAST_WRITER_LINE OS_WAIT_COUNT
+THREAD_ID OBJECT_NAME FILE LINE WAIT_TIME WAIT_OBJECT WAIT_TYPE HOLDER_THREAD_ID HOLDER_FILE HOLDER_LINE CREATED_FILE CREATED_LINE WRITER_THREAD RESERVATION_MODE READERS WAITERS_FLAG LOCK_WORD LAST_WRITER_FILE LAST_WRITER_LINE OS_WAIT_COUNT
Warnings:
Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_sys_semaphore_waits but the InnoDB storage engine is not installed
diff --git a/mysql-test/suite/innodb/r/instant_alter,4k.rdiff b/mysql-test/suite/innodb/r/instant_alter,4k.rdiff
index 098d9fa3b5d..d274d834faa 100644
--- a/mysql-test/suite/innodb/r/instant_alter,4k.rdiff
+++ b/mysql-test/suite/innodb/r/instant_alter,4k.rdiff
@@ -9,7 +9,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -191,7 +191,7 @@
+@@ -250,7 +250,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -18,7 +18,7 @@
connection default;
BEGIN;
UPDATE t2 SET d1 = repeat(id, 200);
-@@ -202,7 +202,7 @@
+@@ -261,7 +261,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -27,7 +27,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -212,7 +212,7 @@
+@@ -271,7 +271,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -36,7 +36,7 @@
connection default;
ALTER TABLE t2 DROP p;
affected rows: 0
-@@ -317,7 +317,7 @@
+@@ -374,7 +374,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -45,7 +45,7 @@
connection default;
ALTER TABLE big ADD COLUMN
(d1 INT DEFAULT 0, d2 VARCHAR(20) DEFAULT 'abcde',
-@@ -340,7 +340,7 @@
+@@ -397,7 +397,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -54,16 +54,16 @@
connection default;
ROLLBACK;
CHECKSUM TABLE big;
-@@ -353,7 +353,7 @@
+@@ -410,7 +410,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
-3
+8
connection default;
- DROP TABLE big;
- CREATE TABLE t1
-@@ -532,7 +532,7 @@
+ InnoDB 0 transactions not purged
+ DROP TABLE t1,t2,t3,big;
+@@ -600,7 +600,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -72,7 +72,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -542,7 +542,7 @@
+@@ -610,7 +610,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -81,7 +81,7 @@
connection default;
BEGIN;
UPDATE t2 SET d1 = repeat(id, 200);
-@@ -553,7 +553,7 @@
+@@ -621,7 +621,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -90,7 +90,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -563,7 +563,7 @@
+@@ -631,7 +631,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -99,7 +99,7 @@
connection default;
ALTER TABLE t2 DROP p;
affected rows: 0
-@@ -668,7 +668,7 @@
+@@ -734,7 +734,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -108,7 +108,7 @@
connection default;
ALTER TABLE big ADD COLUMN
(d1 INT DEFAULT 0, d2 VARCHAR(20) DEFAULT 'abcde',
-@@ -691,7 +691,7 @@
+@@ -757,7 +757,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -117,16 +117,16 @@
connection default;
ROLLBACK;
CHECKSUM TABLE big;
-@@ -704,7 +704,7 @@
+@@ -770,7 +770,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
-3
+7
connection default;
- DROP TABLE big;
- CREATE TABLE t1
-@@ -883,7 +883,7 @@
+ InnoDB 0 transactions not purged
+ DROP TABLE t1,t2,t3,big;
+@@ -960,7 +960,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -135,7 +135,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -893,7 +893,7 @@
+@@ -970,7 +970,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -144,7 +144,7 @@
connection default;
BEGIN;
UPDATE t2 SET d1 = repeat(id, 200);
-@@ -904,7 +904,7 @@
+@@ -981,7 +981,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -153,7 +153,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -914,7 +914,7 @@
+@@ -991,7 +991,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -162,7 +162,7 @@
connection default;
ALTER TABLE t2 DROP p;
affected rows: 0
-@@ -1019,7 +1019,7 @@
+@@ -1094,7 +1094,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -171,7 +171,7 @@
connection default;
ALTER TABLE big ADD COLUMN
(d1 INT DEFAULT 0, d2 VARCHAR(20) DEFAULT 'abcde',
-@@ -1042,7 +1042,7 @@
+@@ -1117,7 +1117,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -180,12 +180,12 @@
connection default;
ROLLBACK;
CHECKSUM TABLE big;
-@@ -1055,7 +1055,7 @@
+@@ -1130,7 +1130,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
-3
+7
connection default;
- DROP TABLE big;
- disconnect analyze;
+ InnoDB 0 transactions not purged
+ DROP TABLE t1,t2,t3,big;
diff --git a/mysql-test/suite/innodb/r/instant_alter,8k.rdiff b/mysql-test/suite/innodb/r/instant_alter,8k.rdiff
index a313765df3a..b96262866e5 100644
--- a/mysql-test/suite/innodb/r/instant_alter,8k.rdiff
+++ b/mysql-test/suite/innodb/r/instant_alter,8k.rdiff
@@ -1,6 +1,6 @@
--- instant_alter.result
+++ instant_alter,8k.result
-@@ -181,7 +181,7 @@
+@@ -240,7 +240,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -9,7 +9,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -191,7 +191,7 @@
+@@ -250,7 +250,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -18,7 +18,7 @@
connection default;
BEGIN;
UPDATE t2 SET d1 = repeat(id, 200);
-@@ -202,7 +202,7 @@
+@@ -261,7 +261,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -27,7 +27,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -212,7 +212,7 @@
+@@ -271,7 +271,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -36,7 +36,7 @@
connection default;
ALTER TABLE t2 DROP p;
affected rows: 0
-@@ -317,7 +317,7 @@
+@@ -374,7 +374,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -45,7 +45,7 @@
connection default;
ALTER TABLE big ADD COLUMN
(d1 INT DEFAULT 0, d2 VARCHAR(20) DEFAULT 'abcde',
-@@ -340,7 +340,7 @@
+@@ -397,7 +397,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -54,16 +54,16 @@
connection default;
ROLLBACK;
CHECKSUM TABLE big;
-@@ -353,7 +353,7 @@
+@@ -410,7 +410,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
-3
+5
connection default;
- DROP TABLE big;
- CREATE TABLE t1
-@@ -532,7 +532,7 @@
+ InnoDB 0 transactions not purged
+ DROP TABLE t1,t2,t3,big;
+@@ -600,7 +600,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -72,7 +72,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -542,7 +542,7 @@
+@@ -610,7 +610,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -81,7 +81,7 @@
connection default;
BEGIN;
UPDATE t2 SET d1 = repeat(id, 200);
-@@ -553,7 +553,7 @@
+@@ -621,7 +621,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -90,7 +90,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -563,7 +563,7 @@
+@@ -631,7 +631,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -99,7 +99,7 @@
connection default;
ALTER TABLE t2 DROP p;
affected rows: 0
-@@ -668,7 +668,7 @@
+@@ -734,7 +734,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -108,7 +108,7 @@
connection default;
ALTER TABLE big ADD COLUMN
(d1 INT DEFAULT 0, d2 VARCHAR(20) DEFAULT 'abcde',
-@@ -691,7 +691,7 @@
+@@ -757,7 +757,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -117,16 +117,16 @@
connection default;
ROLLBACK;
CHECKSUM TABLE big;
-@@ -704,7 +704,7 @@
+@@ -770,7 +770,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
-3
+5
connection default;
- DROP TABLE big;
- CREATE TABLE t1
-@@ -883,7 +883,7 @@
+ InnoDB 0 transactions not purged
+ DROP TABLE t1,t2,t3,big;
+@@ -960,7 +960,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -135,7 +135,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -893,7 +893,7 @@
+@@ -970,7 +970,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -144,7 +144,7 @@
connection default;
BEGIN;
UPDATE t2 SET d1 = repeat(id, 200);
-@@ -904,7 +904,7 @@
+@@ -981,7 +981,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -153,7 +153,7 @@
connection default;
ROLLBACK;
connection analyze;
-@@ -914,7 +914,7 @@
+@@ -991,7 +991,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/t2';
clust_index_size
@@ -162,7 +162,7 @@
connection default;
ALTER TABLE t2 DROP p;
affected rows: 0
-@@ -1019,7 +1019,7 @@
+@@ -1094,7 +1094,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -171,7 +171,7 @@
connection default;
ALTER TABLE big ADD COLUMN
(d1 INT DEFAULT 0, d2 VARCHAR(20) DEFAULT 'abcde',
-@@ -1042,7 +1042,7 @@
+@@ -1117,7 +1117,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
@@ -180,12 +180,12 @@
connection default;
ROLLBACK;
CHECKSUM TABLE big;
-@@ -1055,7 +1055,7 @@
+@@ -1130,7 +1130,7 @@
SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
WHERE name = 'test/big';
clust_index_size
-3
+5
connection default;
- DROP TABLE big;
- disconnect analyze;
+ InnoDB 0 transactions not purged
+ DROP TABLE t1,t2,t3,big;
diff --git a/mysql-test/suite/innodb/r/instant_alter.result b/mysql-test/suite/innodb/r/instant_alter.result
index 1bf2d1025a0..1580ba29717 100644
--- a/mysql-test/suite/innodb/r/instant_alter.result
+++ b/mysql-test/suite/innodb/r/instant_alter.result
Binary files differ
diff --git a/mysql-test/suite/innodb/r/instant_alter_crash.result b/mysql-test/suite/innodb/r/instant_alter_crash.result
index 1c967e538aa..2daaf10fa67 100644
--- a/mysql-test/suite/innodb/r/instant_alter_crash.result
+++ b/mysql-test/suite/innodb/r/instant_alter_crash.result
@@ -1,3 +1,4 @@
+FLUSH TABLES;
#
# MDEV-11369: Instant ADD COLUMN for InnoDB
#
diff --git a/mysql-test/suite/innodb/r/instant_alter_debug.result b/mysql-test/suite/innodb/r/instant_alter_debug.result
index b1407aad1f3..3aec7553ff0 100644
--- a/mysql-test/suite/innodb/r/instant_alter_debug.result
+++ b/mysql-test/suite/innodb/r/instant_alter_debug.result
@@ -35,7 +35,7 @@ ALTER TABLE t4 ADD COLUMN b INT;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
LEFT JOIN t4 ON (NUMERIC_SCALE = pk);
COUNT(*)
-1734
+1748
SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL enter WAIT_FOR delete';
ALTER TABLE t4 ADD COLUMN c INT;
connect dml,localhost,root,,;
diff --git a/mysql-test/suite/innodb/r/instant_alter_rollback.result b/mysql-test/suite/innodb/r/instant_alter_rollback.result
index 786bfa81336..ce49cea2343 100644
--- a/mysql-test/suite/innodb/r/instant_alter_rollback.result
+++ b/mysql-test/suite/innodb/r/instant_alter_rollback.result
@@ -1,3 +1,4 @@
+FLUSH TABLES;
#
# MDEV-11369: Instant ADD COLUMN for InnoDB
#
diff --git a/mysql-test/suite/innodb/r/lock_deleted.result b/mysql-test/suite/innodb/r/lock_deleted.result
new file mode 100644
index 00000000000..0fcb8bd5aa8
--- /dev/null
+++ b/mysql-test/suite/innodb/r/lock_deleted.result
@@ -0,0 +1,57 @@
+connect stop_purge, localhost, root,,;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connect delete, localhost, root,,;
+connection default;
+CREATE TABLE t1(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1,1);
+DELETE FROM t1;
+SET DEBUG_SYNC='row_ins_sec_index_unique SIGNAL inserted WAIT_FOR locked';
+BEGIN;
+INSERT INTO t1 VALUES(1,1);
+connection delete;
+SET DEBUG_SYNC='now WAIT_FOR inserted';
+SET DEBUG_SYNC='innodb_row_search_for_mysql_exit SIGNAL locked';
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+BEGIN;
+DELETE FROM t1 WHERE b=1;
+connection default;
+connection delete;
+COMMIT;
+connection default;
+SET DEBUG_SYNC='RESET';
+ROLLBACK;
+SET DEBUG_SYNC='row_ins_sec_index_unique SIGNAL inserted WAIT_FOR locked';
+BEGIN;
+INSERT INTO t1 VALUES(1,1);
+connection delete;
+SET DEBUG_SYNC='now WAIT_FOR inserted';
+SET DEBUG_SYNC='innodb_row_search_for_mysql_exit SIGNAL locked';
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+BEGIN;
+DELETE FROM t1 WHERE b=1;
+connection default;
+connection delete;
+COMMIT;
+connection default;
+SET DEBUG_SYNC='RESET';
+ROLLBACK;
+SET DEBUG_SYNC='row_ins_sec_index_unique SIGNAL inserted WAIT_FOR locked';
+BEGIN;
+SET innodb_lock_wait_timeout=1;
+INSERT INTO t1 VALUES(1,1);
+connection delete;
+SET DEBUG_SYNC='now WAIT_FOR inserted';
+SET DEBUG_SYNC='innodb_row_search_for_mysql_exit SIGNAL locked';
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+BEGIN;
+DELETE FROM t1 WHERE b=1;
+connection default;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+COMMIT;
+SET DEBUG_SYNC='RESET';
+connection delete;
+COMMIT;
+disconnect delete;
+disconnect stop_purge;
+connection default;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/log_corruption.result b/mysql-test/suite/innodb/r/log_corruption.result
index 35b7b00ead6..6bc10c970fc 100644
--- a/mysql-test/suite/innodb/r/log_corruption.result
+++ b/mysql-test/suite/innodb/r/log_corruption.result
@@ -17,6 +17,13 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /InnoDB: Upgrade after a crash is not supported. This redo log was created before MariaDB 10\.2\.2, and it appears corrupted/ in mysqld.1.err
+# empty redo log from before MariaDB 10.2.2
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+COUNT(*)
+1
+FOUND 1 /InnoDB: Upgrading redo log:/ in mysqld.1.err
# redo log from "after" MariaDB 10.2.2, but with invalid header checksum
SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
@@ -40,14 +47,15 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
-FOUND 1 /InnoDB: Upgrade after a crash is not supported\. The redo log was created with malicious intentions, or perhaps, and it appears corrupted\./ in mysqld.1.err
+FOUND 1 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122/ in mysqld.1.err
+FOUND 1 /InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\./ in mysqld.1.err
# same, but with current-version header
SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
-FOUND 1 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122/ in mysqld.1.err
-FOUND 1 /InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\./ in mysqld.1.err
+FOUND 2 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122/ in mysqld.1.err
+FOUND 2 /InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\./ in mysqld.1.err
# --innodb-force-recovery=6 (skip the entire redo log)
SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
@@ -92,12 +100,32 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /InnoDB: MLOG_FILE_NAME incorrect:bigot/ in mysqld.1.err
FOUND 1 /len 22; hex 38000000000012860cb7809781e800066269676f7400; asc 8 bigot ;/ in mysqld.1.err
-# missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
+# 10.2 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
+SELECT * FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
+FOUND 1 /InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42/ in mysqld.1.err
+# 10.3 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
-NOT FOUND /InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42$/ in mysqld.1.err
+FOUND 2 /InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42/ in mysqld.1.err
+# Empty 10.3 redo log
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+COUNT(*)
+1
+FOUND 1 /InnoDB: .* started; log sequence number 121397[09]/ in mysqld.1.err
+# Empty 10.2 redo log
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+COUNT(*)
+1
+FOUND 2 /InnoDB: Upgrading redo log:/ in mysqld.1.err
# Minimal MariaDB 10.1.21 encrypted redo log
SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
diff --git a/mysql-test/suite/innodb/r/mvcc.result b/mysql-test/suite/innodb/r/mvcc.result
new file mode 100644
index 00000000000..fc2d403fa63
--- /dev/null
+++ b/mysql-test/suite/innodb/r/mvcc.result
@@ -0,0 +1,32 @@
+SET @save_per_table= @@GLOBAL.innodb_file_per_table;
+SET GLOBAL innodb_file_per_table= 1;
+#
+# MDEV-15249 Crash in MVCC read after IMPORT TABLESPACE
+#
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(0);
+FLUSH TABLES t1 WITH READ LOCK;
+UNLOCK TABLES;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connect con1,localhost,root,,;
+ALTER TABLE t1 FORCE, ALGORITHM=COPY;
+connection default;
+SELECT * FROM t1;
+ERROR HY000: Table definition has changed, please retry transaction
+COMMIT;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection con1;
+ALTER TABLE t1 DISCARD TABLESPACE;
+ALTER TABLE t1 IMPORT TABLESPACE;
+disconnect con1;
+connection default;
+# FIXME: Block this with ER_TABLE_DEF_CHANGED
+SELECT * FROM t1;
+a
+0
+COMMIT;
+SELECT * FROM t1;
+a
+0
+DROP TABLE t1;
+SET GLOBAL innodb_file_per_table= @save_per_table;
diff --git a/mysql-test/suite/innodb/r/purge_secondary.result b/mysql-test/suite/innodb/r/purge_secondary.result
new file mode 100644
index 00000000000..2312434a2bd
--- /dev/null
+++ b/mysql-test/suite/innodb/r/purge_secondary.result
@@ -0,0 +1,148 @@
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
+CREATE TABLE t1 (
+a SERIAL, b CHAR(255) NOT NULL DEFAULT '', c BOOLEAN DEFAULT false,
+l LINESTRING NOT NULL DEFAULT ST_linefromtext('linestring(448 -689,
+ 453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,
+ 468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,
+ 479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,
+ 501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,
+ 518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,
+ 522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,
+ 536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,
+ 554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,
+ 549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,
+ 554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,
+ 470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,
+ 486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,
+ 495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,
+ 498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,
+ 511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,
+ 515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,
+ 529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,
+ 4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,
+ 4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,
+ 4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,
+ 4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,
+ 4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,
+ 4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,
+ 4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,
+ 4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,
+ 6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,
+ 7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,
+ 7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,
+ 7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,
+ 7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,
+ 482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,
+ 483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,
+ 493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,
+ 507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,
+ 503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,
+ 505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,
+ 497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,
+ 498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,
+ 503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,
+ 496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,
+ 497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,
+ 515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,
+ 527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,
+ 532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,
+ 541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,
+ 561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,
+ 561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,
+ 4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,
+ 9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,
+ 9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,
+ 9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,
+ 9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,
+ 9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,
+ 9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,
+ 9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,
+ 9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,
+ 9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,
+ 9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,
+ 9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,
+ 9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,
+ 502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,
+ 3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,
+ 3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,
+ 7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,
+ 7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,
+ 7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,
+ 7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,
+ 7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,
+ 12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,
+ 12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,
+ 12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,
+ 12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,
+ 9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,
+ 9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,
+ 9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,
+ 9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,
+ 9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,
+ 9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,
+ 9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,
+ 9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,
+ 9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,
+ 9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,
+ 9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,
+ 9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,
+ 9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,
+ 9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,
+ 9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,
+ 9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,
+ 9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,
+ 9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,
+ 9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,
+ 9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,
+ 9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,
+ 9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,
+ 12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,
+ 12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677)'),
+INDEX(b,c), SPATIAL INDEX(l)
+) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+INSERT INTO t1 () VALUES (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
+SELECT LENGTH(l) FROM t1;
+LENGTH(l)
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+11197
+INSERT INTO t1 (a) SELECT NULL FROM t1;
+INSERT INTO t1 (a) SELECT NULL FROM t1;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+UPDATE t1 SET c=true, l=ST_linefromtext('linestring(0 0,1 1,2 2)');
+DELETE FROM t1;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+InnoDB 0 transactions not purged
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+SELECT OTHER_INDEX_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE NAME='test/t1';
+OTHER_INDEX_SIZE
+1
+# 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:
+# FLUSH TABLES t1 FOR EXPORT;
+# UNLOCK TABLES;
+DROP TABLE t1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb/r/read_only_recover_committed.result b/mysql-test/suite/innodb/r/read_only_recover_committed.result
new file mode 100644
index 00000000000..34b33f60f1b
--- /dev/null
+++ b/mysql-test/suite/innodb/r/read_only_recover_committed.result
@@ -0,0 +1,47 @@
+connect con1, localhost, root;
+CREATE TABLE t(a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t VALUES(1);
+BEGIN;
+INSERT INTO t VALUES(2);
+DELETE FROM t WHERE a=2;
+connect con2, localhost, root;
+# Normal MariaDB shutdown would roll back the above transaction.
+# We want the transaction to remain open, so we will kill the server
+# after ensuring that any non-transactional files are clean.
+FLUSH TABLES;
+# Create another transaction that will be recovered as COMMITTED.
+BEGIN;
+SET DEBUG_SYNC='after_trx_committed_in_memory SIGNAL committed WAIT_FOR ever';
+COMMIT;
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR committed';
+# Ensure that the above incomplete transactions become durable.
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+BEGIN;
+INSERT INTO t VALUES(-10000);
+ROLLBACK;
+disconnect con1;
+disconnect con2;
+SELECT * FROM t;
+a
+1
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT * FROM t;
+a
+1
+UPDATE t SET a=3 WHERE a=1;
+# Starting with MariaDB 10.2, innodb_read_only implies READ UNCOMMITTED.
+# In earlier versions, this would return the last committed version
+# (empty table)!
+SELECT * FROM t;
+a
+3
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT * FROM t;
+a
+3
+SELECT * FROM t;
+a
+3
+DROP TABLE t;
+FOUND 1 /Rolled back recovered transaction [^0]/ in mysqld.1.err
diff --git a/mysql-test/suite/innodb/r/read_only_recovery.result b/mysql-test/suite/innodb/r/read_only_recovery.result
index 97ec938fb2a..e639e8abacc 100644
--- a/mysql-test/suite/innodb/r/read_only_recovery.result
+++ b/mysql-test/suite/innodb/r/read_only_recovery.result
@@ -37,3 +37,4 @@ SELECT * FROM t;
a
3
DROP TABLE t;
+FOUND 1 /Rolled back recovered transaction [^0]/ in mysqld.1.err
diff --git a/mysql-test/suite/innodb/r/recovery_shutdown.result b/mysql-test/suite/innodb/r/recovery_shutdown.result
new file mode 100644
index 00000000000..d26163a0c4a
--- /dev/null
+++ b/mysql-test/suite/innodb/r/recovery_shutdown.result
@@ -0,0 +1,66 @@
+FLUSH TABLES;
+#
+# MDEV-13797 InnoDB may hang if shutdown is initiated soon after startup
+# while rolling back recovered incomplete transactions
+#
+CREATE TABLE t (a INT) ENGINE=InnoDB;
+BEGIN;
+COMMIT;
+connect con$c,localhost,root,,;
+CREATE TABLE t8 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t8 (a) SELECT NULL FROM t;
+UPDATE t8 SET a=a+100, b=a;
+DELETE FROM t8;
+connect con$c,localhost,root,,;
+CREATE TABLE t7 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t7 (a) SELECT NULL FROM t;
+UPDATE t7 SET a=a+100, b=a;
+DELETE FROM t7;
+connect con$c,localhost,root,,;
+CREATE TABLE t6 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t6 (a) SELECT NULL FROM t;
+UPDATE t6 SET a=a+100, b=a;
+DELETE FROM t6;
+connect con$c,localhost,root,,;
+CREATE TABLE t5 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t5 (a) SELECT NULL FROM t;
+UPDATE t5 SET a=a+100, b=a;
+DELETE FROM t5;
+connect con$c,localhost,root,,;
+CREATE TABLE t4 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t4 (a) SELECT NULL FROM t;
+UPDATE t4 SET a=a+100, b=a;
+DELETE FROM t4;
+connect con$c,localhost,root,,;
+CREATE TABLE t3 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t3 (a) SELECT NULL FROM t;
+UPDATE t3 SET a=a+100, b=a;
+DELETE FROM t3;
+connect con$c,localhost,root,,;
+CREATE TABLE t2 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t2 (a) SELECT NULL FROM t;
+UPDATE t2 SET a=a+100, b=a;
+DELETE FROM t2;
+connect con$c,localhost,root,,;
+CREATE TABLE t1 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t1 (a) SELECT NULL FROM t;
+UPDATE t1 SET a=a+100, b=a;
+DELETE FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+connection default;
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+CREATE TABLE u(a SERIAL) ENGINE=INNODB;
+FLUSH TABLES;
+DROP TABLE t,u;
diff --git a/mysql-test/suite/innodb/r/rename_table_debug.result b/mysql-test/suite/innodb/r/rename_table_debug.result
new file mode 100644
index 00000000000..976b609bdd5
--- /dev/null
+++ b/mysql-test/suite/innodb/r/rename_table_debug.result
@@ -0,0 +1,12 @@
+CREATE TABLE t1 (a SERIAL, b INT, c INT, d INT) ENGINE=InnoDB;
+INSERT INTO t1 () VALUES ();
+connect con1,localhost,root,,test;
+SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever';
+RENAME TABLE t1 TO t2;
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR renamed';
+disconnect con1;
+SELECT * FROM t1;
+a b c d
+1 NULL NULL NULL
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/restart.result b/mysql-test/suite/innodb/r/restart.result
new file mode 100644
index 00000000000..c70adac3a55
--- /dev/null
+++ b/mysql-test/suite/innodb/r/restart.result
@@ -0,0 +1,29 @@
+#
+# MDEV-15333 MariaDB (still) slow start
+#
+# FIXME: Unlike MySQL, maybe MariaDB should not read the .ibd files
+# of tables with .isl file or DATA DIRECTORY attribute.
+call mtr.add_suppression("\\[ERROR\\] InnoDB: Invalid flags 0x7a207879 in .*td\\.ibd");
+# FIXME: This is much more noisy than MariaDB 10.1!
+call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot read first page in datafile: .*td\\.ibd, Space ID:2048948345, Flags: 2048948345");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\.");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\.");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them\\.");
+call mtr.add_suppression("\\[Warning\\] InnoDB: Ignoring tablespace for `test`\\.`td` because it could not be opened\\.");
+CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT
+PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9;
+CREATE TABLE td(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC
+STATS_PERSISTENT=0 DATA DIRECTORY='MYSQL_TMP_DIR';
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+COUNT(*)
+1
+SELECT * FROM tr;
+a
+SELECT * FROM tc;
+a
+SELECT * FROM td;
+a
+DROP TABLE tr,tc,td;
diff --git a/mysql-test/suite/innodb/r/row_format_redundant.result b/mysql-test/suite/innodb/r/row_format_redundant.result
index a2d5bbef8df..6deecd10ada 100644
--- a/mysql-test/suite/innodb/r/row_format_redundant.result
+++ b/mysql-test/suite/innodb/r/row_format_redundant.result
@@ -72,7 +72,7 @@ DROP TABLE t1;
Warnings:
Warning 1932 Table 'test.t1' doesn't exist in engine
DROP TABLE t2,t3;
-FOUND 49 /\[ERROR\] InnoDB: Table `test`\.`t1` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=255\b/ in mysqld.1.err
+FOUND 49 /\[ERROR\] InnoDB: Table `test`\.`t1` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err
ib_buffer_pool
ib_logfile0
ib_logfile1
diff --git a/mysql-test/suite/innodb/r/table_flags.result b/mysql-test/suite/innodb/r/table_flags.result
index 0d636d84529..c82cd6ceccb 100644
--- a/mysql-test/suite/innodb/r/table_flags.result
+++ b/mysql-test/suite/innodb/r/table_flags.result
@@ -116,8 +116,16 @@ SHOW CREATE TABLE tr;
ERROR 42S02: Table 'test.tr' doesn't exist in engine
SHOW CREATE TABLE tc;
ERROR 42S02: Table 'test.tc' doesn't exist in engine
+SELECT * FROM tc;
+ERROR 42S02: Table 'test.tc' doesn't exist in engine
SHOW CREATE TABLE td;
-ERROR 42S02: Table 'test.td' doesn't exist in engine
+Table Create Table
+td CREATE TABLE `td` (
+ `a` int(11) NOT NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+SELECT * FROM td;
+a
SHOW CREATE TABLE tz;
Table Create Table
tz CREATE TABLE `tz` (
@@ -132,8 +140,7 @@ a
42
SHOW CREATE TABLE tp;
ERROR 42S02: Table 'test.tp' doesn't exist in engine
-FOUND 4 /InnoDB: Table `test`.`t[cp]` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649/ in mysqld.1.err
-FOUND 2 /InnoDB: Refusing to load '\..test.td\.ibd' \(id=3, flags=0x1?[2ae]1\); dictionary contains id=3, flags=0x10[01][2ae]1\b/ in mysqld.1.err
+FOUND 5 /InnoDB: Table `test`.`t[cp]` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649/ in mysqld.1.err
FOUND 2 /InnoDB: Table `test`\.`tr` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b/ in mysqld.1.err
Restoring SYS_TABLES clustered index root page (8)
SHOW CREATE TABLE tr;
diff --git a/mysql-test/suite/innodb/r/truncate_inject.result b/mysql-test/suite/innodb/r/truncate_inject.result
new file mode 100644
index 00000000000..5ec532a0f83
--- /dev/null
+++ b/mysql-test/suite/innodb/r/truncate_inject.result
@@ -0,0 +1,114 @@
+SET @save_dbug = @@SESSION.debug_dbug;
+call mtr.add_suppression("InnoDB: Flagged corruption of .* in table `test`\\.`t` in TRUNCATE TABLE");
+# 1. Error in assigning undo logs for truncate action
+CREATE TABLE t (i int PRIMARY KEY, f float UNIQUE, c char(100), INDEX ck(c))
+ENGINE = InnoDB;
+insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+SET debug_dbug = '+d,ib_err_trunc_assigning_undo_log';
+truncate table t;
+ERROR HY000: Got error 168 "Unknown (generic) error from engine" from storage engine InnoDB
+SET debug_dbug = @save_dbug;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+i f c
+1 1.1 a
+2 2.2 b
+3 3.3 c
+# 2. Error while preparing for truncate
+SET debug_dbug = '+d,ib_err_trunc_preparing_for_truncate';
+truncate table t;
+ERROR HY000: Got error 168 "Unknown (generic) error from engine" from storage engine InnoDB
+SET debug_dbug = @save_dbug;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+i f c
+1 1.1 a
+2 2.2 b
+3 3.3 c
+# 3. Error while dropping/creating indexes
+SET debug_dbug = '+d,ib_err_trunc_drop_index';
+truncate table t;
+ERROR HY000: Got error 168 "Unknown (generic) error from engine" from storage engine InnoDB
+SET debug_dbug = @save_dbug;
+check table t;
+Table Op Msg_type Msg_text
+test.t check Warning InnoDB: Index PRIMARY is marked as corrupted
+test.t check error Corrupt
+select * from t;
+Got one of the listed errors
+drop table t;
+CREATE TABLE t (i int PRIMARY KEY, f float UNIQUE, c char(100), INDEX ck(c))
+ENGINE = InnoDB;
+insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+SET debug_dbug = '+d,ib_err_trunc_create_index';
+truncate table t;
+ERROR HY000: Got error 168 "Unknown (generic) error from engine" from storage engine InnoDB
+SET debug_dbug = @save_dbug;
+check table t;
+Table Op Msg_type Msg_text
+test.t check Warning InnoDB: Index PRIMARY is marked as corrupted
+test.t check error Corrupt
+select * from t;
+Got one of the listed errors
+drop table t;
+CREATE TABLE t (i int PRIMARY KEY, f float UNIQUE, c char(100), INDEX ck(c))
+ENGINE = InnoDB;
+insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+SET debug_dbug = '+d,ib_err_trunc_temp_recreate_index';
+truncate table t;
+SET debug_dbug = @save_dbug;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+i f c
+drop table t;
+# 4. Error while completing truncate of table involving FTS
+CREATE TABLE t (i int PRIMARY KEY, f float UNIQUE, c char(100),
+FULLTEXT INDEX(c)) ENGINE = InnoDB;
+insert into t values (1, 1.1, 'mysql is now oracle company'),
+(2, 2.2, 'innodb is part of mysql'),
+(3, 3.3, 'innodb is default storage engine of mysql');
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+SET debug_dbug = '+d,ib_err_trunc_temp_recreate_index';
+truncate table t;
+SET debug_dbug = @save_dbug;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+i f c
+drop table t;
+# 5. Error while updating sys-tables
+CREATE TABLE t (i int PRIMARY KEY, f float UNIQUE, c char(100),
+FULLTEXT INDEX(c)) ENGINE = InnoDB;
+insert into t values (1, 1.1, 'mysql is now oracle company'),
+(2, 2.2, 'innodb is part of mysql'),
+(3, 3.3, 'innodb is default storage engine of mysql');
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+SET debug_dbug = '+d,ib_err_trunc_temp_recreate_index';
+truncate table t;
+SET debug_dbug = @save_dbug;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t order by i;
+i f c
+drop table t;
diff --git a/mysql-test/suite/innodb/r/truncate_restart.result b/mysql-test/suite/innodb/r/truncate_restart.result
new file mode 100644
index 00000000000..b6d14124371
--- /dev/null
+++ b/mysql-test/suite/innodb/r/truncate_restart.result
@@ -0,0 +1,12 @@
+SET GLOBAL innodb_stats_persistent= ON;
+CREATE TABLE t1 (t TEXT) ENGINE=InnoDB STATS_PERSISTENT=1;
+connect con1,localhost,root,,test;
+SET DEBUG_SYNC='ib_trunc_table_trunc_completing SIGNAL committed WAIT_FOR ever';
+TRUNCATE TABLE t1;
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR committed';
+disconnect con1;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/update-cascade.result b/mysql-test/suite/innodb/r/update-cascade.result
new file mode 100644
index 00000000000..a3c8fed931e
--- /dev/null
+++ b/mysql-test/suite/innodb/r/update-cascade.result
@@ -0,0 +1,290 @@
+#
+# Bug #18451287 REDUNDANT DELETE MARKING AFTER DB_LOCK_WAIT
+#
+create table t1 (f1 int primary key, f2 blob) engine=innodb;
+create table t2 (f1 int primary key, f2 int,
+foreign key (f2) references t1(f1) on update cascade) engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` int(11) NOT NULL,
+ `f2` blob DEFAULT NULL,
+ PRIMARY KEY (`f1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `f1` int(11) NOT NULL,
+ `f2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`f1`),
+ KEY `f2` (`f2`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`) ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1, repeat('+', 20000));
+insert into t1 values (2, repeat('-', 20000));
+insert into t1 values (3, repeat('=', 20000));
+insert into t2 values (1, 2);
+select f1, right(f2, 20) as p2 from t1;
+f1 p2
+1 ++++++++++++++++++++
+2 --------------------
+3 ====================
+select f1, f2 from t2;
+f1 f2
+1 2
+connect con1,localhost,root,,test;
+start transaction;
+select f1, f2 from t2 for update;
+f1 f2
+1 2
+connection default;
+set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
+update t1 set f1 = 10 where f1 = 2;
+connection con1;
+set debug_sync='now WAIT_FOR upd_waiting';
+rollback;
+set debug_sync='now SIGNAL go_upd';
+connection default;
+# reap: update t1 set f1 = 10 where f1 = 2;
+select f1, right(f2, 20) as p2 from t1;
+f1 p2
+1 ++++++++++++++++++++
+3 ====================
+10 --------------------
+select f1, f2 from t2;
+f1 f2
+1 10
+drop table t2, t1;
+set debug_sync = reset;
+#
+# Test Scenario: Two tables t1 -> t2 are involved in update cascade.
+# If DB_LOCK_WAIT happens when t1 is being updated and FK constraints
+# are being checked in t2, then retry must happen on t1. The update
+# cascade happens in secondary index. For secondary index testing,
+# blobs are not needed.
+#
+create table t1 (f1 int primary key, f2 int, key k1(f2)) engine=innodb;
+create table t2 (f1 int primary key, f2 int,
+foreign key (f2) references t1(f2) on update cascade) engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` int(11) NOT NULL,
+ `f2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`f1`),
+ KEY `k1` (`f2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `f1` int(11) NOT NULL,
+ `f2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`f1`),
+ KEY `f2` (`f2`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f2`) ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1, 91);
+insert into t2 values (1, 91);
+select f1, f2 from t1;
+f1 f2
+1 91
+select f1, f2 from t2;
+f1 f2
+1 91
+connection con1;
+start transaction;
+select f1, f2 from t2 for update;
+f1 f2
+1 91
+connection default;
+set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
+update t1 set f2 = 28 where f2 = 91;
+connection con1;
+set debug_sync='now WAIT_FOR upd_waiting';
+rollback;
+set debug_sync='now SIGNAL go_upd';
+connection default;
+# reap: update t1 set f1 = 10 where f1 = 2;
+select f1, f2 from t1;
+f1 f2
+1 28
+select f1, f2 from t2;
+f1 f2
+1 28
+drop table t2, t1;
+set debug_sync = reset;
+#
+# Test Scenario: Three tables t1 -> t2 -> t3 are involved in update cascade.
+# If DB_LOCK_WAIT happens when t2 is being updated, then retry must happen
+# on t2.
+#
+create table t1 (f1 int primary key, f2 blob) engine=innodb;
+create table t2 (f1 int primary key, f2 blob,
+foreign key (f1) references t1(f1) on update cascade) engine=innodb;
+create table t3 (f1 int primary key, f2 blob,
+foreign key (f1) references t2(f1) on update cascade) engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` int(11) NOT NULL,
+ `f2` blob DEFAULT NULL,
+ PRIMARY KEY (`f1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `f1` int(11) NOT NULL,
+ `f2` blob DEFAULT NULL,
+ PRIMARY KEY (`f1`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `f1` int(11) NOT NULL,
+ `f2` blob DEFAULT NULL,
+ PRIMARY KEY (`f1`),
+ CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t2` (`f1`) ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2, repeat('-', 20000));
+insert into t2 values (2, repeat('%', 20000));
+insert into t3 values (2, repeat('+', 20000));
+select f1, right(f2, 20) as p2 from t1;
+f1 p2
+2 --------------------
+select f1, right(f2, 20) as p2 from t2;
+f1 p2
+2 %%%%%%%%%%%%%%%%%%%%
+select f1, right(f2, 20) as p2 from t3;
+f1 p2
+2 ++++++++++++++++++++
+connection con1;
+start transaction;
+select f1 from t3 for update;
+f1
+2
+connection default;
+set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
+update t1 set f1 = 10 where f1 = 2;
+connection con1;
+set debug_sync='now WAIT_FOR upd_waiting';
+rollback;
+# The table t1 is updated.
+# In t2 delete-mark happened. Retry will happen on t2.
+# In t3 yet to be updated.
+set session transaction isolation level read uncommitted;
+start transaction;
+select f1, right(f2, 20) as p2 from t1;
+f1 p2
+select f1, right(f2, 20) as p2 from t2;
+f1 p2
+select f1, right(f2, 20) as p2 from t3;
+f1 p2
+2 ++++++++++++++++++++
+commit;
+set debug_sync='now SIGNAL go_upd';
+connection default;
+# reap: update t1 set f1 = 10 where f1 = 2;
+start transaction;
+select f1, right(f2, 20) as p2 from t1;
+f1 p2
+10 --------------------
+select f1, right(f2, 20) as p2 from t2;
+f1 p2
+10 %%%%%%%%%%%%%%%%%%%%
+select f1, right(f2, 20) as p2 from t3;
+f1 p2
+10 ++++++++++++++++++++
+commit;
+drop table t3, t2, t1;
+set debug_sync = reset;
+#
+# Test Scenario: Three tables t1 -> t2 -> t3 are involved in update
+# cascade. If DB_LOCK_WAIT happens when t2 is being updated, then
+# retry must happen on t2. The update cascade is happening via
+# secondary index (hence blobs are not needed).
+#
+create table t1 (f1 int primary key, f2 int, key k1(f2)) engine=innodb;
+create table t2 (f1 int primary key, f2 int,
+foreign key (f2) references t1(f2) on update cascade) engine=innodb;
+create table t3 (f1 int primary key, f2 int,
+foreign key (f2) references t2(f2) on update cascade) engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` int(11) NOT NULL,
+ `f2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`f1`),
+ KEY `k1` (`f2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `f1` int(11) NOT NULL,
+ `f2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`f1`),
+ KEY `f2` (`f2`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f2`) ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `f1` int(11) NOT NULL,
+ `f2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`f1`),
+ KEY `f2` (`f2`),
+ CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t2` (`f2`) ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2, 91);
+insert into t2 values (2, 91);
+insert into t3 values (2, 91);
+select f1, f2 from t1;
+f1 f2
+2 91
+select f1, f2 from t2;
+f1 f2
+2 91
+select f1, f2 from t3;
+f1 f2
+2 91
+connection con1;
+start transaction;
+select f1 from t3 for update;
+f1
+2
+connection default;
+set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
+update t1 set f2 = 28 where f2 = 91;
+connection con1;
+set debug_sync='now WAIT_FOR upd_waiting';
+rollback;
+# The table t1 is updated.
+# In t2 delete-mark happened. Retry will happen on t2.
+# In t3 yet to be updated.
+set session transaction isolation level read uncommitted;
+start transaction;
+select f1, f2 from t1;
+f1 f2
+select f1, f2 from t2;
+f1 f2
+select f1, f2 from t3;
+f1 f2
+2 91
+commit;
+set debug_sync='now SIGNAL go_upd';
+disconnect con1;
+connection default;
+# reap: update t1 set f2 = 28 where f2 = 91;
+start transaction;
+select f1, f2 from t1;
+f1 f2
+2 28
+select f1, f2 from t2;
+f1 f2
+2 28
+select f1, f2 from t3;
+f1 f2
+2 28
+commit;
+drop table t3, t2, t1;
+set debug_sync = reset;
diff --git a/mysql-test/suite/innodb/r/update_time.result b/mysql-test/suite/innodb/r/update_time.result
new file mode 100644
index 00000000000..d8b9069b1ae
--- /dev/null
+++ b/mysql-test/suite/innodb/r/update_time.result
@@ -0,0 +1,53 @@
+#
+# Test that INFORMATION_SCHEMA.TABLES.UPDATE_TIME is filled
+# correctly for InnoDB tables.
+#
+CREATE TABLE t (a INT) ENGINE=INNODB;
+SELECT update_time FROM information_schema.tables WHERE table_name = 't';
+update_time
+NULL
+INSERT INTO t VALUES (1);
+SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 't'
+AND update_time IS NOT NULL;
+COUNT(*)
+1
+# We cant deterministically check that the saved value is correct, but
+# at least we check that it is a timestamp not older than 2 minutes.
+# Usually update_time and NOW() are equal below, but on heavily loaded
+# machines NOW() could be younger.
+SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 't'
+AND TIMESTAMPDIFF(SECOND, update_time, NOW()) < 120;
+COUNT(*)
+1
+CREATE TEMPORARY TABLE big (a TEXT) ENGINE=INNODB;
+SELECT COUNT(*) FROM information_schema.innodb_buffer_page
+WHERE table_name = '`test`.`t`';
+COUNT(*)
+1
+# INSERT lots of data in table 'big': begin
+# INSERT lots of data in table 'big': end
+SELECT COUNT(*) FROM information_schema.innodb_buffer_page
+WHERE table_name = '`test`.`t`';
+COUNT(*)
+0
+SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 't'
+AND update_time IS NOT NULL;
+COUNT(*)
+1
+DROP TEMPORARY TABLE big;
+# Test the behavior after restart with a prepared XA transaction
+XA START 'xatrx';
+INSERT INTO t VALUES (5);
+XA END 'xatrx';
+XA PREPARE 'xatrx';
+CONNECT con1,localhost,root,,;
+call mtr.add_suppression("Found 1 prepared XA transactions");
+FLUSH TABLES;
+SELECT update_time FROM information_schema.tables WHERE table_name = 't';
+update_time
+NULL
+XA COMMIT 'xatrx';
+SELECT COUNT(update_time) FROM information_schema.tables WHERE table_name='t';
+COUNT(update_time)
+1
+DROP TABLE t;
diff --git a/mysql-test/suite/innodb/r/update_time_wl6658.result b/mysql-test/suite/innodb/r/update_time_wl6658.result
new file mode 100644
index 00000000000..fcd7a53351a
--- /dev/null
+++ b/mysql-test/suite/innodb/r/update_time_wl6658.result
@@ -0,0 +1,228 @@
+CREATE TABLE tab1(c1 int,c2 varchar(30), c3 BLOB) ENGINE=InnoDB;
+CREATE TABLE tab1u LIKE tab1;
+CREATE TABLE tab1d LIKE tab1;
+CREATE TABLE tab1i LIKE tab1;
+CREATE TABLE tab3(c1 int,c2 varchar(30)) ENGINE=InnoDB;
+CREATE TABLE tab4(c1 int,c2 varchar(30)) ENGINE=InnoDB;
+CREATE TABLE tab5(c1 int,c2 varchar(30)) ENGINE=InnoDB;
+INSERT INTO tab1u VALUES(1,'Testing the wl6658','Testing the wl6658');
+INSERT INTO tab1d VALUES(1,'Updated','Updated');
+INSERT INTO tab4 VALUES(1,'Test for Update');
+INSERT INTO tab5 VALUES(1,'Test for Delete');
+CREATE TRIGGER test_trig BEFORE INSERT ON tab1
+FOR EACH ROW BEGIN
+INSERT INTO tab3 VALUES(1,'Inserted From Trigger');
+UPDATE tab4 SET c2='Updated from Trigger' WHERE c1=1;
+DELETE FROM tab5;
+END |
+CREATE TABLE tab2(
+id INT NOT NULL,
+store_name VARCHAR(30),
+parts VARCHAR(30),
+store_id INT
+) ENGINE=InnoDB
+PARTITION BY LIST(store_id) (
+PARTITION pNorth VALUES IN (10,20,30),
+PARTITION pEast VALUES IN (40,50,60),
+PARTITION pWest VALUES IN (70,80,100)
+);
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab2';
+update_time
+NULL
+CREATE PROCEDURE proc_wl6658()
+BEGIN
+INSERT INTO tab2 VALUES(1,'ORACLE','NUTT',10);
+INSERT INTO tab2 VALUES(2,'HUAWEI','BOLT',40);
+COMMIT;
+END |
+CALL proc_wl6658;
+SELECT * FROM tab2 ORDER BY id,store_id;
+id store_name parts store_id
+1 ORACLE NUTT 10
+2 HUAWEI BOLT 40
+SELECT COUNT(update_time)
+FROM information_schema.tables WHERE table_name='tab2';
+COUNT(update_time)
+1
+TRUNCATE TABLE tab2;
+SELECT COUNT(update_time)
+FROM information_schema.tables WHERE table_name='tab2';
+COUNT(update_time)
+1
+CREATE TABLE tab7(c1 INT NOT NULL, PRIMARY KEY (c1)) ENGINE=INNODB;
+CREATE TABLE tab8(c1 INT PRIMARY KEY,c2 INT,
+FOREIGN KEY (c2) REFERENCES tab7(c1) ON DELETE CASCADE )
+ENGINE=INNODB;
+SELECT table_name,update_time
+FROM information_schema.tables WHERE table_name IN ('tab7','tab8')
+GROUP BY table_name ORDER BY table_name;
+table_name update_time
+tab7 NULL
+tab8 NULL
+INSERT INTO tab7 VALUES(1);
+INSERT INTO tab8 VALUES(1,1);
+SELECT table_name,COUNT(update_time)
+FROM information_schema.tables WHERE table_name IN ('tab7','tab8')
+GROUP BY table_name ORDER BY table_name;
+table_name COUNT(update_time)
+tab7 1
+tab8 1
+#restart the server
+SELECT table_name,update_time
+FROM information_schema.tables
+WHERE table_name IN ('tab1','tab2','tab3','tab4','tab5','tab7','tab8')
+ORDER BY table_name;
+table_name update_time
+tab1 NULL
+tab2 NULL
+tab3 NULL
+tab4 NULL
+tab5 NULL
+tab7 NULL
+tab8 NULL
+#case1:
+BEGIN WORK;
+INSERT INTO tab1
+VALUES(1,'Testing the wl6658', 'Testing the wl6658');
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1';
+update_time
+NULL
+COMMIT;
+SELECT * FROM tab1;
+c1 c2 c3
+1 Testing the wl6658 Testing the wl6658
+SELECT * FROM tab3;
+c1 c2
+1 Inserted From Trigger
+SELECT * FROM tab4;
+c1 c2
+1 Updated from Trigger
+SELECT * FROM tab5;
+c1 c2
+SELECT table_name,COUNT(update_time)
+FROM information_schema.tables
+WHERE table_name IN ('tab1','tab3','tab4','tab5')
+GROUP BY table_name ORDER BY table_name;
+table_name COUNT(update_time)
+tab1 1
+tab3 1
+tab4 1
+tab5 1
+Testcase with UPDATE stmt and transaction
+SELECT * FROM tab1u;
+c1 c2 c3
+1 Testing the wl6658 Testing the wl6658
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1u';
+update_time
+NULL
+#case2:
+START TRANSACTION;
+UPDATE tab1u SET c2='Updated',c3='Updated' WHERE c1=1;
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1u';
+update_time
+NULL
+COMMIT;
+SELECT * FROM tab1u;
+c1 c2 c3
+1 Updated Updated
+SELECT COUNT(update_time)
+FROM information_schema.tables WHERE table_name='tab1u';
+COUNT(update_time)
+1
+SELECT * FROM tab1d;
+c1 c2 c3
+1 Updated Updated
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1d';
+update_time
+NULL
+#case3:
+START TRANSACTION;
+DELETE FROM tab1d;
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1d';
+update_time
+NULL
+COMMIT;
+SELECT * FROM tab1d;
+c1 c2 c3
+SELECT COUNT(update_time)
+FROM information_schema.tables WHERE table_name='tab1d';
+COUNT(update_time)
+1
+SELECT * FROM tab1i;
+c1 c2 c3
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1i';
+update_time
+NULL
+#case4:
+START TRANSACTION;
+INSERT INTO tab1i
+VALUES(1,'Testing the wl6658', 'Testing the wl6658');
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1i';
+update_time
+NULL
+ROLLBACK;
+SELECT * FROM tab1i;
+c1 c2 c3
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1i';
+update_time
+NULL
+BEGIN WORK;
+DELETE FROM tab1i;
+SAVEPOINT A;
+INSERT INTO tab2 VALUES(1,'Oracle','NUTT',10);
+INSERT INTO tab2 VALUES(2,'HUAWEI','BOLT',40);
+SAVEPOINT B;
+INSERT INTO tab2 VALUES(3,'IBM','NAIL',70);
+SAVEPOINT C;
+ROLLBACK to A;
+SELECT * FROM tab2;
+id store_name parts store_id
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab2';
+update_time
+NULL
+#execute DDL instead of commit
+create table tab6(c1 int);
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab2';
+update_time
+NULL
+START TRANSACTION;
+DELETE FROM tab7;
+ROLLBACK;
+SELECT * FROM tab7;
+c1
+1
+SELECT * FROM tab8;
+c1 c2
+1 1
+SELECT table_name,update_time
+FROM information_schema.tables WHERE table_name IN ('tab7','tab8')
+GROUP BY table_name ORDER BY table_name;
+table_name update_time
+tab7 NULL
+tab8 NULL
+DELETE FROM tab7;
+SELECT * FROM tab7;
+c1
+SELECT * FROM tab8;
+c1 c2
+SELECT table_name,COUNT(update_time)
+FROM information_schema.tables WHERE table_name IN ('tab7','tab8')
+GROUP BY table_name ORDER BY table_name;
+table_name COUNT(update_time)
+tab7 1
+tab8 1
+#cleanup
+DROP TRIGGER test_trig;
+DROP TABLE tab1,tab1u,tab1d,tab1i,tab2,tab3,tab4,tab5,tab6,tab8,tab7;
+DROP PROCEDURE proc_wl6658;
diff --git a/mysql-test/suite/innodb/t/alter_copy.test b/mysql-test/suite/innodb/t/alter_copy.test
new file mode 100644
index 00000000000..0dce61994b5
--- /dev/null
+++ b/mysql-test/suite/innodb/t/alter_copy.test
@@ -0,0 +1,91 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+--echo #
+--echo # MDEV-11415 AVOID INTERMEDIATE COMMIT WHILE DOING
+--echo # ALTER TABLE...ALGORITHM=COPY
+--echo #
+
+CREATE TABLE t(a SERIAL, b INT, c INT, d INT) ENGINE=InnoDB;
+CREATE TABLE t1(a INT, b TEXT, c TEXT,
+ FULLTEXT(b), FULLTEXT(c(3)), FULLTEXT(b,c)) ENGINE=InnoDB;
+
+let $c = 999;
+BEGIN;
+--disable_query_log
+while ($c) {
+INSERT INTO t() VALUES();
+dec $c;
+}
+--enable_query_log
+COMMIT;
+
+SELECT COUNT(*) FROM t;
+# try to make the to-be-created secondary index keys randomly distributed
+UPDATE t SET b=a%7, c=a%11, d=a%13;
+
+INSERT INTO t1 VALUES(1, 'This is a first b column', 'This is a first c column');
+INSERT INTO t1 VALUES(2, 'This is a second b column', 'This is a second c column');
+INSERT INTO t1(a) VALUES(3);
+INSERT INTO t1 VALUES(4, 'This is a third b column', 'This is a third c column');
+DELETE FROM t1 WHERE a = 2;
+SELECT * FROM t1 WHERE MATCH(b) AGAINST ('first');
+SELECT * FROM t1 WHERE MATCH(c) AGAINST ('first');
+SELECT * FROM t1 WHERE MATCH(b,c) AGAINST ('column');
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 FORCE, ALGORITHM=COPY;
+
+# crash right after the last write_row(), before the first commit of ALTER TABLE
+--source include/expect_crash.inc
+
+SET DEBUG_DBUG='+d,crash_commit_before';
+--error 2013
+# create 32 secondary indexes
+ALTER TABLE t ADD INDEX(b,c,d,a),ADD INDEX(b,c,a,d),ADD INDEX(b,a,c,d),ADD INDEX(b,a,d,c),
+ ADD INDEX(b,d,a,c),ADD INDEX(b,d,c,a),ADD INDEX(a,b,c,d),ADD INDEX(a,b,d,c),
+ ADD INDEX(a,c,b,d),ADD INDEX(a,c,d,b),ADD INDEX(a,d,b,c),ADD INDEX(a,d,c,b),
+ ADD INDEX(c,a,b,d),ADD INDEX(c,a,d,b),ADD INDEX(c,b,a,d),ADD INDEX(c,b,d,a),
+ ADD INDEX(c,d,a,b),ADD INDEX(c,d,b,a),ADD INDEX(d,a,b,c),ADD INDEX(d,a,c,b),
+ ADD INDEX(d,b,a,c),ADD INDEX(d,b,c,a),ADD INDEX(d,c,a,b),ADD INDEX(d,c,b,a),
+ ADD INDEX(a,b,c), ADD INDEX(a,c,b), ADD INDEX(a,c,d), ADD INDEX(a,d,c),
+ ADD INDEX(a,b,d), ADD INDEX(a,d,b), ADD INDEX(b,c,d), ADD INDEX(b,d,c),
+ ALGORITHM=COPY;
+
+--let $restart_parameters= --innodb-force-recovery=3
+--source include/start_mysqld.inc
+let $datadir=`select @@datadir`;
+--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ /FTS_[0-9a-f]*_[0-9a-f]*/FTS/
+--list_files $datadir/test
+SHOW CREATE TABLE t;
+SELECT COUNT(*) FROM t;
+CHECK TABLE t;
+SELECT * FROM t1 WHERE MATCH(b) AGAINST ('first');
+SELECT * FROM t1 WHERE MATCH(c) AGAINST ('first');
+SELECT * FROM t1 WHERE MATCH(b,c) AGAINST ('column');
+SHOW CREATE TABLE t1;
+CHECK TABLE t1;
+
+--let $restart_parameters= --innodb-read-only
+--source include/restart_mysqld.inc
+--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ /FTS_[0-9a-f]*_[0-9a-f]*/FTS/
+
+--list_files $datadir/test
+SHOW CREATE TABLE t;
+SELECT COUNT(*) FROM t;
+CHECK TABLE t;
+SELECT * FROM t1 WHERE MATCH(b) AGAINST ('first');
+SELECT * FROM t1 WHERE MATCH(c) AGAINST ('first');
+SELECT * FROM t1 WHERE MATCH(b,c) AGAINST ('column');
+SHOW CREATE TABLE t1;
+CHECK TABLE t1;
+
+--let $restart_parameters=
+--source include/restart_mysqld.inc
+--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ /FTS_[0-9a-f]*_[0-9a-f]*/FTS/
+--list_files $datadir/test
+DROP TABLE t1,t;
+
+# Work around missing crash recovery at the SQL layer.
+--remove_files_wildcard $datadir/test #sql-*.frm
diff --git a/mysql-test/suite/innodb/t/alter_crash.test b/mysql-test/suite/innodb/t/alter_crash.test
index 1751e2d6c8b..101e0fa44c2 100644
--- a/mysql-test/suite/innodb/t/alter_crash.test
+++ b/mysql-test/suite/innodb/t/alter_crash.test
@@ -72,31 +72,25 @@ let $orig_table_id = `SELECT table_id
--error 2013
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
---echo # Restart mysqld after the crash and reconnect.
---source include/start_mysqld.inc
-
-let $temp_table_name = `SELECT SUBSTR(name, 6)
- FROM information_schema.innodb_sys_tables
- WHERE table_id = $orig_table_id`;
-
---echo # Manual *.frm recovery begin.
-
---move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/$temp_table_name.frm
-
+let TABLENAME_INC= $MYSQLTEST_VARDIR/tmp/tablename.inc;
perl;
-my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm";
-my $t1_frm = "$ENV{'datadir'}/test/t1.frm";
-rename($frm_file[0], $t1_frm);
+die unless open OUT, ">$ENV{TABLENAME_INC}";
+chdir "$ENV{'datadir'}/test";
+my @frm_file = map { substr($_, 0, -4) } glob "#sql-*.frm";
+print OUT 'let $tablename=', $frm_file[0], ';';
+close OUT or die;
EOF
+source $TABLENAME_INC;
+remove_file $TABLENAME_INC;
---echo # Manual recovery end
+move_file $datadir/test/$tablename.frm $datadir/test/t1.frm;
-FLUSH TABLES;
+--echo # Restart mysqld after the crash and reconnect.
+--source include/start_mysqld.inc
---echo # Drop the orphaned original table.
---disable_query_log
-eval DROP TABLE `$temp_table_name`;
---enable_query_log
+--replace_result $orig_table_id ID
+eval SELECT * FROM information_schema.innodb_sys_tables
+WHERE table_id = $orig_table_id;
--echo # Files in datadir after manual recovery.
--list_files $MYSQLD_DATADIR/test
@@ -131,35 +125,13 @@ let $orig_table_id = `SELECT table_id
--error 2013
ALTER TABLE t2 ADD PRIMARY KEY (f2, f1);
+remove_files_wildcard $datadir/test #sql-*.frm;
+
--echo # Startup the server after the crash
--source include/start_mysqld.inc
---echo # Read and remember the temporary table name
-let $temp_table_name = `SELECT SUBSTRING(name,6)
- FROM information_schema.innodb_sys_tables
- WHERE name LIKE "test/#sql-ib$orig_table_id%"`;
-
---echo # Manual *.frm recovery begin. The dictionary was not updated
---echo # and the files were not renamed. The rebuilt table
---echo # was left behind on purpose, to faciliate data recovery.
-
-let TABLENAME_INC= $MYSQLTEST_VARDIR/tmp/tablename.inc;
-perl;
-die unless open OUT, ">$ENV{TABLENAME_INC}";
-chdir "$ENV{'datadir'}/test";
-my @frm_file = map { substr($_, 0, -4) } glob "#sql-*.frm";
-print OUT 'let $tablename=', $frm_file[0], ';';
-close OUT or die;
-EOF
-source $TABLENAME_INC;
-remove_file $TABLENAME_INC;
-
---echo # Manual recovery end
-
---echo # Drop the orphaned rebuilt table.
---disable_query_log
-eval DROP TABLE `#mysql50#$tablename`;
---enable_query_log
+SELECT * FROM information_schema.innodb_sys_tables
+WHERE name LIKE 'test/#sql-%';
SHOW TABLES;
INSERT INTO t2 VALUES (5,6),(7,8);
@@ -195,30 +167,24 @@ let $orig_table_id = `select table_id from
--error 2013
ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE;
---echo # Restart mysqld after the crash and reconnect.
---source include/start_mysqld.inc
-
-let $temp_table_name = `SELECT SUBSTR(name, 6)
- FROM information_schema.innodb_sys_tables
- WHERE table_id = $orig_table_id`;
-
---echo # Manual *.frm recovery begin.
---move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/$temp_table_name.frm
-
perl;
-my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm";
-my $t1_frm = "$ENV{'datadir'}/test/t1.frm";
-rename($frm_file[0], $t1_frm);
+die unless open OUT, ">$ENV{TABLENAME_INC}";
+chdir "$ENV{'datadir'}/test";
+my @frm_file = map { substr($_, 0, -4) } glob "#sql-*.frm";
+print OUT 'let $tablename=', $frm_file[0], ';';
+close OUT or die;
EOF
+source $TABLENAME_INC;
+remove_file $TABLENAME_INC;
---echo # Manual recovery end
+move_file $datadir/test/$tablename.frm $datadir/test/t1.frm;
-FLUSH TABLES;
+--echo # Restart mysqld after the crash and reconnect.
+--source include/start_mysqld.inc
---echo # Drop the orphaned original table.
---disable_query_log
-eval DROP TABLE `#mysql50#$temp_table_name`;
---enable_query_log
+--replace_result $orig_table_id ID
+eval SELECT * FROM information_schema.innodb_sys_tables
+WHERE table_id = $orig_table_id;
--echo # Files in datadir after manual recovery.
--list_files $MYSQLD_DATADIR/test
diff --git a/mysql-test/suite/innodb/t/ddl_purge.test b/mysql-test/suite/innodb/t/ddl_purge.test
new file mode 100644
index 00000000000..60d17acead8
--- /dev/null
+++ b/mysql-test/suite/innodb/t/ddl_purge.test
@@ -0,0 +1,36 @@
+--source innodb_default_row_format.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=InnoDB;
+
+--connect (con1,localhost,root,,test)
+BEGIN;
+INSERT INTO t0 SET pk=1;
+
+--connect (con2,localhost,root,,test)
+BEGIN;
+INSERT INTO t0 SET pk=2;
+
+--connection default
+SET DEBUG_SYNC='alter_table_inplace_after_lock_downgrade SIGNAL prepared WAIT_FOR logged';
+send ALTER TABLE t1 FORCE;
+
+--connection con1
+SET DEBUG_SYNC='now WAIT_FOR prepared';
+INSERT INTO t1 SET pk=1;
+COMMIT;
+--disconnect con1
+
+--connection con2
+UPDATE t1 SET b=1;
+DELETE FROM t1;
+ROLLBACK;
+SET DEBUG_SYNC='now SIGNAL logged';
+--disconnect con2
+
+--connection default
+reap;
+SET DEBUG_SYNC='RESET';
+DROP TABLE t0,t1;
diff --git a/mysql-test/suite/innodb/t/deadlock_detect.test b/mysql-test/suite/innodb/t/deadlock_detect.test
index 85d8c1f67f2..babdb54719f 100644
--- a/mysql-test/suite/innodb/t/deadlock_detect.test
+++ b/mysql-test/suite/innodb/t/deadlock_detect.test
@@ -18,6 +18,8 @@ CREATE TABLE t1(
INSERT INTO t1 VALUES(1), (2), (3);
+# We are not interested query results, only errors
+--disable_result_log
BEGIN;
SELECT * FROM t1 WHERE id = 1 FOR UPDATE;
@@ -39,12 +41,22 @@ reap;
ROLLBACK;
+#
+# Note here that con1 is the older transaction as it
+# query started wait first. Thus, con1 gets lock
+# wait timeout first. There is possibility that
+# default connection gets lock timeout also or
+# as con1 is rolled back it gets the locks it waited
+# and does the update.
+#
connection default;
---error ER_LOCK_WAIT_TIMEOUT
+--error 0,ER_LOCK_WAIT_TIMEOUT
reap;
ROLLBACK;
+--enable_result_log
+
DROP TABLE t1;
disconnect con1;
diff --git a/mysql-test/suite/innodb/t/drop_table_background.test b/mysql-test/suite/innodb/t/drop_table_background.test
index 0f596dec574..8d82bea9675 100644
--- a/mysql-test/suite/innodb/t/drop_table_background.test
+++ b/mysql-test/suite/innodb/t/drop_table_background.test
@@ -9,6 +9,9 @@ KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1),
KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1),
KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB;
+CREATE TABLE `#mysql50##sql-ib-foo`(a SERIAL) ENGINE=InnoDB;
+INSERT INTO t (c1) VALUES (1),(2),(1);
+
let $n= 10;
SET DEBUG_DBUG='+d,row_drop_table_add_to_background';
@@ -24,7 +27,18 @@ while ($i) {
dec $i;
}
--enable_query_log
+--error ER_DUP_ENTRY
+CREATE TABLE target (PRIMARY KEY(c1)) ENGINE=InnoDB SELECT * FROM t;
+--error ER_NO_SUCH_TABLE
+SELECT * from target;
DROP TABLE t;
--source include/restart_mysqld.inc
CREATE TABLE t (a INT) ENGINE=InnoDB;
DROP TABLE t;
+--error ER_BAD_TABLE_ERROR
+DROP TABLE target;
+CREATE TABLE target (a INT) ENGINE=InnoDB;
+DROP TABLE target;
+--error ER_NO_SUCH_TABLE_IN_ENGINE
+SELECT * FROM `#mysql50##sql-ib-foo`;
+DROP TABLE `#mysql50##sql-ib-foo`;
diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test
index 3d3466c90f0..862717647b5 100644
--- a/mysql-test/suite/innodb/t/foreign_key.test
+++ b/mysql-test/suite/innodb/t/foreign_key.test
@@ -236,4 +236,44 @@ DELETE FROM t1 WHERE id = 1;
SELECT * FROM t2;
DROP TABLE t2, t1;
+--echo #
+--echo # MDEV-15199 Referential integrity broken in ON DELETE CASCADE
+--echo #
+
+CREATE TABLE member (id int AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO member VALUES (1);
+CREATE TABLE address (
+ id int AUTO_INCREMENT PRIMARY KEY,
+ member_id int NOT NULL,
+ KEY address_FI_1 (member_id),
+ CONSTRAINT address_FK_1 FOREIGN KEY (member_id) REFERENCES member (id)
+ ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+
+INSERT INTO address VALUES (2,1);
+CREATE TABLE payment_method (
+ id int AUTO_INCREMENT PRIMARY KEY,
+ member_id int NOT NULL,
+ cardholder_address_id int DEFAULT NULL,
+ KEY payment_method_FI_1 (member_id),
+ KEY payment_method_FI_2 (cardholder_address_id),
+ CONSTRAINT payment_method_FK_1 FOREIGN KEY (member_id) REFERENCES member (id) ON DELETE CASCADE ON UPDATE CASCADE,
+ CONSTRAINT payment_method_FK_2 FOREIGN KEY (cardholder_address_id) REFERENCES address (id) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB;
+
+INSERT INTO payment_method VALUES (3,1,2);
+
+BEGIN;
+UPDATE member SET id=42;
+SELECT * FROM member;
+SELECT * FROM address;
+SELECT * FROM payment_method;
+DELETE FROM member;
+COMMIT;
+SELECT * FROM member;
+SELECT * FROM address;
+SELECT * FROM payment_method;
+
+DROP TABLE payment_method,address,member;
+
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/ibuf_not_empty.test b/mysql-test/suite/innodb/t/ibuf_not_empty.test
index a1a2da1f903..5adbfb72550 100644
--- a/mysql-test/suite/innodb/t/ibuf_not_empty.test
+++ b/mysql-test/suite/innodb/t/ibuf_not_empty.test
@@ -9,6 +9,8 @@
--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");
+call mtr.add_suppression("InnoDB: Failed to find tablespace for table `mysql`\\.`transaction_registry` in the cache\\. Attempting to load the tablespace with space id");
+call mtr.add_suppression("InnoDB: Allocated tablespace ID \\d+ for mysql.transaction_registry, old maximum was");
--enable_query_log
CREATE TABLE t1(
diff --git a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test
index f2038da8c4c..f7635e96d50 100644
--- a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test
+++ b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test
@@ -32,24 +32,12 @@ SET debug_dbug='+d,innodb_alter_commit_crash_before_commit';
--error 2013
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
-let TABLENAME_INC= $MYSQLTEST_VARDIR/tmp/tablename.inc;
-perl;
-die unless open OUT, ">$ENV{TABLENAME_INC}";
-chdir "$ENV{'datadir'}/test";
-my @frm_file = map { substr($_, 0, -4) } glob "#sql-*.frm";
-print OUT 'let $temp_table_name=', $frm_file[0], ';';
-close OUT or die;
-EOF
-source $TABLENAME_INC;
-remove_file $TABLENAME_INC;
+remove_files_wildcard $datadir/test #sql-*.frm;
--source include/start_mysqld.inc
show create table t1;
--echo # Consecutive Alter table does not create same temporary file name
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
---disable_query_log
-eval DROP TABLE `#mysql50#$temp_table_name`;
---enable_query_log
show create table t1;
drop table t1;
diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test
index 9b526c7c433..db265ff8f67 100644
--- a/mysql-test/suite/innodb/t/innodb-autoinc.test
+++ b/mysql-test/suite/innodb/t/innodb-autoinc.test
@@ -683,3 +683,20 @@ INSERT INTO t VALUES (NULL);
SELECT * FROM t;
SHOW CREATE TABLE t;
DROP TABLE t;
+
+--echo #
+--echo # MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())
+--echo #
+
+SET sql_mode=STRICT_ALL_TABLES;
+CREATE TABLE t1 (
+ c1 DOUBLE NOT NULL PRIMARY KEY AUTO_INCREMENT
+) ENGINE=InnoDB AUTO_INCREMENT=10000000000000000000;
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a DOUBLE PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (-1);
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-index-debug.test b/mysql-test/suite/innodb/t/innodb-index-debug.test
index de598740e6a..e680fb719cc 100644
--- a/mysql-test/suite/innodb/t/innodb-index-debug.test
+++ b/mysql-test/suite/innodb/t/innodb-index-debug.test
@@ -114,6 +114,45 @@ connection default;
show create table t1;
drop table t1;
drop table t480;
+--echo #
+--echo # MDEV-12827 Assertion failure when reporting duplicate key error
+--echo # in online table rebuild
+--echo #
+
+CREATE TABLE t1 (j INT UNIQUE, i INT UNIQUE) ENGINE=InnoDB;
+--connect (con1,localhost,root,,test)
+SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built WAIT_FOR log';
+--send
+ALTER TABLE t1 DROP j, FORCE;
+
+--connection default
+SET DEBUG_SYNC='now WAIT_FOR built';
+--error ER_DUP_ENTRY
+INSERT INTO t1 (i) VALUES (0),(0);
+SET DEBUG_SYNC='now SIGNAL log';
+
+--connection con1
+--error ER_DUP_ENTRY
+reap;
+SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built2 WAIT_FOR log2';
+--send
+ALTER TABLE t1 DROP j, FORCE;
+
+--connection default
+SET DEBUG_SYNC='now WAIT_FOR built2';
+INSERT INTO t1 (i) VALUES (0),(1);
+--error ER_DUP_ENTRY
+UPDATE t1 SET i=0;
+SET DEBUG_SYNC='now SIGNAL log2';
+
+--connection con1
+--error ER_DUP_ENTRY
+reap;
+--disconnect con1
+--connection default
+SET DEBUG_SYNC='RESET';
+DROP TABLE t1;
+
SET DEBUG_SYNC='RESET';
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/innodb-index-online.test b/mysql-test/suite/innodb/t/innodb-index-online.test
index 5509d985edc..efe1c796cf1 100644
--- a/mysql-test/suite/innodb/t/innodb-index-online.test
+++ b/mysql-test/suite/innodb/t/innodb-index-online.test
@@ -457,8 +457,6 @@ connection default;
reap;
--enable_parsing
#remove below con1 disconnect if above test case is enabled
-connection con1;
-disconnect con1;
connection default;
SHOW CREATE TABLE t1;
@@ -474,6 +472,31 @@ SET GLOBAL innodb_monitor_disable = module_ddl;
DROP TABLE t1;
+--echo #
+--echo # MDEV-13205 assertion !dict_index_is_online_ddl(index) upon ALTER TABLE
+--echo #
+CREATE TABLE t1 (c VARCHAR(64)) ENGINE=InnoDB;
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL t1u_created WAIT_FOR dup_done';
+send ALTER TABLE t1 ADD UNIQUE(c);
+
+connection con1;
+SET DEBUG_SYNC = 'now WAIT_FOR t1u_created';
+BEGIN;
+INSERT INTO t1 VALUES('bar'),('bar');
+SET DEBUG_SYNC = 'now SIGNAL dup_done';
+
+connection default;
+--error ER_DUP_ENTRY
+reap;
+
+SET DEBUG_SYNC = 'RESET';
+disconnect con1;
+CREATE TABLE t2 (c VARCHAR(64)) ENGINE=InnoDB;
+--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
+--error ER_CANT_CREATE_TABLE
+ALTER TABLE t2 ADD FOREIGN KEY (c) REFERENCES t1 (c);
+DROP TABLE t2,t1;
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test b/mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test
new file mode 100644
index 00000000000..d4f08b5afe6
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test
@@ -0,0 +1,24 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/not_embedded.inc
+
+call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool");
+
+SET @saved_debug = @@SESSION.debug_dbug;
+SET SESSION debug_dbug="+d,ib_lru_force_no_free_page";
+
+CREATE TABLE t1 (j LONGBLOB) ENGINE = InnoDB;
+BEGIN;
+INSERT INTO t1 VALUES (repeat('abcdefghijklmnopqrstuvwxyz',200));
+COMMIT;
+
+SET debug_dbug = @saved_debug;
+
+DROP TABLE t1;
+
+#
+# There should be only one message
+#
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
+--let SEARCH_PATTERN=InnoDB: Difficult to find free blocks
+--source include/search_pattern_in_file.inc
diff --git a/mysql-test/suite/innodb/t/innodb-master.opt b/mysql-test/suite/innodb/t/innodb-master.opt
index 5266978e4f0..2e71d62206d 100644
--- a/mysql-test/suite/innodb/t/innodb-master.opt
+++ b/mysql-test/suite/innodb/t/innodb-master.opt
@@ -2,3 +2,5 @@
--default-storage-engine=MyISAM
--innodb-strict-mode=0
--innodb-file-per-table=0
+--loose-innodb-track-changed-pages
+--loose-innodb-log-archive
diff --git a/mysql-test/suite/innodb/t/innodb-on-duplicate-update.test b/mysql-test/suite/innodb/t/innodb-on-duplicate-update.test
new file mode 100644
index 00000000000..cc80198d24a
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-on-duplicate-update.test
@@ -0,0 +1,63 @@
+--source include/have_innodb.inc
+
+#
+# MDEV-13206: INSERT ON DUPLICATE KEY UPDATE foreign key fail
+#
+set sql_mode='';
+set innodb_strict_mode=0;
+
+CREATE TABLE `v` (
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+
+INSERT v values (1);
+
+CREATE TABLE `vp` (
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+ `v_id` int(10) unsigned NOT NULL,
+ `p_id` int(10) unsigned NOT NULL,
+ `ppp` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `IDX_vp_uniq` (`v_id`,`p_id`),
+ KEY `FK_vp_v` (`v_id`),
+ CONSTRAINT `FK_vp_v` FOREIGN KEY (`v_id`) REFERENCES `v` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+
+INSERT vp VALUES (12, 1, 100, 'text12');
+INSERT INTO `vp` (`id`,`ppp`) VALUES (12, 'test12-2') ON DUPLICATE KEY UPDATE `ppp` = VALUES(`ppp`);
+SELECT * FROM vp;
+DROP TABLE vp, v;
+
+CREATE TABLE t1 (i int PRIMARY KEY) ENGINE=InnoDB;
+INSERT into t1 values (1);
+
+CREATE TABLE t2 (
+ i int not null primary key,
+ vi int not null,
+ m int,
+ UNIQUE KEY (vi),
+ CONSTRAINT `cc` FOREIGN KEY (vi) REFERENCES t1 (i) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+
+INSERT into t2 VALUES (1, 1, 100);
+INSERT INTO t2 (i,m) VALUES (1, 2) ON DUPLICATE KEY UPDATE m=3;
+SELECT * FROM t2;
+
+DROP TABLE t2,t1;
+
+CREATE TABLE t1 (i int PRIMARY KEY) ENGINE=InnoDB;
+INSERT into t1 values (1);
+
+CREATE TABLE t2 (
+ i int not null primary key,
+ vi int not null,
+ m int,
+ KEY (vi),
+ CONSTRAINT `cc` FOREIGN KEY (vi) REFERENCES t1 (i) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+
+INSERT into t2 VALUES (1, 1, 100);
+INSERT INTO t2 (i,m) VALUES (1, 2) ON DUPLICATE KEY UPDATE m=3;
+SELECT * FROM t2;
+DROP TABLE t2, t1;
diff --git a/mysql-test/suite/innodb/t/innodb-replace-debug.test b/mysql-test/suite/innodb/t/innodb-replace-debug.test
new file mode 100644
index 00000000000..7e710ae154c
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-replace-debug.test
@@ -0,0 +1,16 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+--echo #
+--echo # Bug#17604730 ASSERTION: *CURSOR->INDEX->NAME == TEMP_INDEX_PREFIX
+--echo #
+
+create table t1 (f1 int primary key, f2 int, f3 int, unique key k1(f2),
+ key k2(f3)) engine=innodb;
+insert into t1 values (14, 24, 34);
+set @old_dbug= @@session.debug_dbug;
+set debug_dbug = '+d,row_ins_sec_index_entry_timeout';
+replace into t1 values (14, 25, 34);
+select * from t1;
+drop table t1;
+set debug_dbug = @old_dbug;
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index a4ba60ec94c..472b47899db 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -5,6 +5,10 @@ let $MYSQLD_DATADIR= `select @@datadir`;
let collation=utf8_unicode_ci;
--source include/have_collation.inc
+
+create temporary table t (a char(1) character set filename) engine=innodb;
+drop temporary table t;
+
set optimizer_switch = 'mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
# Save the original values of some variables in order to be able to
@@ -1054,82 +1058,18 @@ DROP TABLE t2,t1;
#
# test for FK cascade depth limit
#
-call mtr.add_suppression("Cannot delete/update rows with cascading foreign key constraints that exceed max depth of 255. Please drop excessive foreign constraints and try again");
+call mtr.add_suppression("Cannot delete/update rows with cascading foreign key constraints that exceed max depth of 15\\. Please drop excessive foreign constraints and try again");
create table t1(
id int primary key,
pid int,
index(pid),
foreign key(pid) references t1(id) on delete cascade) engine=innodb;
-insert into t1 values
-( 0, 0), ( 1, 0), ( 2, 1), ( 3, 2),
-( 4, 3), ( 5, 4), ( 6, 5), ( 7, 6),
-( 8, 7), ( 9, 8), ( 10, 9), ( 11, 10),
-( 12, 11), ( 13, 12), ( 14, 13), ( 15, 14),
-( 16, 15), ( 17, 16), ( 18, 17), ( 19, 18),
-( 20, 19), ( 21, 20), ( 22, 21), ( 23, 22),
-( 24, 23), ( 25, 24), ( 26, 25), ( 27, 26),
-( 28, 27), ( 29, 28), ( 30, 29), ( 31, 30),
-( 32, 31), ( 33, 32), ( 34, 33), ( 35, 34),
-( 36, 35), ( 37, 36), ( 38, 37), ( 39, 38),
-( 40, 39), ( 41, 40), ( 42, 41), ( 43, 42),
-( 44, 43), ( 45, 44), ( 46, 45), ( 47, 46),
-( 48, 47), ( 49, 48), ( 50, 49), ( 51, 50),
-( 52, 51), ( 53, 52), ( 54, 53), ( 55, 54),
-( 56, 55), ( 57, 56), ( 58, 57), ( 59, 58),
-( 60, 59), ( 61, 60), ( 62, 61), ( 63, 62),
-( 64, 63), ( 65, 64), ( 66, 65), ( 67, 66),
-( 68, 67), ( 69, 68), ( 70, 69), ( 71, 70),
-( 72, 71), ( 73, 72), ( 74, 73), ( 75, 74),
-( 76, 75), ( 77, 76), ( 78, 77), ( 79, 78),
-( 80, 79), ( 81, 80), ( 82, 81), ( 83, 82),
-( 84, 83), ( 85, 84), ( 86, 85), ( 87, 86),
-( 88, 87), ( 89, 88), ( 90, 89), ( 91, 90),
-( 92, 91), ( 93, 92), ( 94, 93), ( 95, 94),
-( 96, 95), ( 97, 96), ( 98, 97), ( 99, 98),
-(100, 99), (101, 100), (102, 101), (103, 102),
-(104, 103), (105, 104), (106, 105), (107, 106),
-(108, 107), (109, 108), (110, 109), (111, 110),
-(112, 111), (113, 112), (114, 113), (115, 114),
-(116, 115), (117, 116), (118, 117), (119, 118),
-(120, 119), (121, 120), (122, 121), (123, 122),
-(124, 123), (125, 124), (126, 125), (127, 126),
-(128, 127), (129, 128), (130, 129), (131, 130),
-(132, 131), (133, 132), (134, 133), (135, 134),
-(136, 135), (137, 136), (138, 137), (139, 138),
-(140, 139), (141, 140), (142, 141), (143, 142),
-(144, 143), (145, 144), (146, 145), (147, 146),
-(148, 147), (149, 148), (150, 149), (151, 150),
-(152, 151), (153, 152), (154, 153), (155, 154),
-(156, 155), (157, 156), (158, 157), (159, 158),
-(160, 159), (161, 160), (162, 161), (163, 162),
-(164, 163), (165, 164), (166, 165), (167, 166),
-(168, 167), (169, 168), (170, 169), (171, 170),
-(172, 171), (173, 172), (174, 173), (175, 174),
-(176, 175), (177, 176), (178, 177), (179, 178),
-(180, 179), (181, 180), (182, 181), (183, 182),
-(184, 183), (185, 184), (186, 185), (187, 186),
-(188, 187), (189, 188), (190, 189), (191, 190),
-(192, 191), (193, 192), (194, 193), (195, 194),
-(196, 195), (197, 196), (198, 197), (199, 198),
-(200, 199), (201, 200), (202, 201), (203, 202),
-(204, 203), (205, 204), (206, 205), (207, 206),
-(208, 207), (209, 208), (210, 209), (211, 210),
-(212, 211), (213, 212), (214, 213), (215, 214),
-(216, 215), (217, 216), (218, 217), (219, 218),
-(220, 219), (221, 220), (222, 221), (223, 222),
-(224, 223), (225, 224), (226, 225), (227, 226),
-(228, 227), (229, 228), (230, 229), (231, 230),
-(232, 231), (233, 232), (234, 233), (235, 234),
-(236, 235), (237, 236), (238, 237), (239, 238),
-(240, 239), (241, 240), (242, 241), (243, 242),
-(244, 243), (245, 244), (246, 245), (247, 246),
-(248, 247), (249, 248), (250, 249), (251, 250),
-(252, 251), (253, 252), (254, 253), (255, 254);
+insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
+(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
--error ER_GET_ERRMSG,ER_ROW_IS_REFERENCED_2
delete from t1 where id=0;
-delete from t1 where id=255;
---error 0,ER_ROW_IS_REFERENCED_2
+delete from t1 where id=15;
delete from t1 where id=0;
drop table t1;
@@ -2583,17 +2523,73 @@ select f1 from t1;
show status like "handler_read_key";
drop table t1;
-#######################################################################
-# #
-# Please, DO NOT TOUCH this file as well as the innodb.result file. #
-# These files are to be modified ONLY BY INNOBASE guys. #
-# #
-# Use innodb_mysql.[test|result] files instead. #
-# #
-# If nevertheless you need to make some changes here, please, forward #
-# your commit message #
-# To: innodb_dev_ww@oracle.com #
-# Cc: dev-innodb@mysql.com #
-# (otherwise your changes may be erased). #
-# #
-#######################################################################
+#
+# Test handling of writes to TEMPORARY tables for read-only transactions
+#
+CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
+CREATE TEMPORARY TABLE t2 (c1 INT) ENGINE=InnoDB;
+
+# Check that the rollback works
+START TRANSACTION READ ONLY;
+INSERT INTO t2 VALUES(0);
+--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
+INSERT INTO t1 VALUES(0);
+ROLLBACK;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+START TRANSACTION READ ONLY;
+--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
+INSERT INTO t1 VALUES(0);
+INSERT INTO t2 VALUES(1);
+COMMIT;
+
+SET TRANSACTION READ ONLY;
+START TRANSACTION;
+INSERT INTO t2 VALUES(3);
+--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
+INSERT INTO t1 VALUES(0);
+COMMIT;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+DROP TABLE t2;
+
+# This time with some indexes
+CREATE TEMPORARY TABLE t2 (
+ c1 INT AUTO_INCREMENT PRIMARY KEY,
+ c2 INT, INDEX idx(c2)) ENGINE=InnoDB;
+
+SHOW CREATE TABLE t2;
+
+# Check that the rollback works
+START TRANSACTION READ ONLY;
+INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3);
+--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
+INSERT INTO t1 VALUES(0);
+ROLLBACK;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+START TRANSACTION READ ONLY;
+--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
+INSERT INTO t1 VALUES(0);
+INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3);
+COMMIT;
+
+SET TRANSACTION READ ONLY;
+START TRANSACTION;
+INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3);
+--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
+INSERT INTO t1 VALUES(0);
+COMMIT;
+
+SHOW CREATE TABLE t2;
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+DROP TABLE t1;
+DROP TABLE t2;
diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_resize.opt b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize.opt
new file mode 100644
index 00000000000..39543543a53
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize.opt
@@ -0,0 +1,2 @@
+--innodb-buffer-pool-size=8M
+--innodb-page-size=4k
diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_resize.test b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize.test
new file mode 100644
index 00000000000..77fdb49a57d
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize.test
@@ -0,0 +1,74 @@
+#
+# WL6117 : Resize the InnoDB Buffer Pool Online
+#
+
+--source include/have_innodb.inc
+--source include/big_test.inc
+
+let $wait_timeout = 180;
+let $wait_condition =
+ SELECT SUBSTR(variable_value, 1, 34) = 'Completed resizing buffer pool at '
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_resize_status';
+
+--disable_query_log
+set @old_innodb_buffer_pool_size = @@innodb_buffer_pool_size;
+set @old_innodb_adaptive_hash_index = @@innodb_adaptive_hash_index;
+if (`select (version() like '%debug%') > 0`)
+{
+ set @old_innodb_disable_resize = @@innodb_disable_resize_buffer_pool_debug;
+ set global innodb_disable_resize_buffer_pool_debug = OFF;
+}
+--enable_query_log
+
+set global innodb_adaptive_hash_index=ON;
+
+select @@innodb_buffer_pool_size;
+
+# Expand buffer pool
+set global innodb_buffer_pool_size = 10485760;
+
+--source include/wait_condition.inc
+
+select @@innodb_buffer_pool_size;
+
+# fill buffer pool
+create table t1 (id int not null, val int not null default '0', primary key (id)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+create or replace view view0 as select 1 union all select 1;
+
+set @`v_id` := 0;
+set @`v_val` := 0;
+
+# 2^18 == 262144 records
+replace into t1 select (@`v_id` := (@`v_id` + 4) mod 4294967296) as id, (@`v_val` := (@`v_val` + 4) mod 4294967296) as val from view0 v0, view0 v1, view0 v2, view0 v3, view0 v4, view0 v5, view0 v6, view0 v7, view0 v8, view0 v9, view0 v10, view0 v11, view0 v12, view0 v13, view0 v14, view0 v15, view0 v16, view0 v17;
+
+# Shrink buffer pool
+set global innodb_buffer_pool_size = 7340032;
+--source include/wait_condition.inc
+
+select @@innodb_buffer_pool_size;
+
+select count(val) from t1;
+
+set global innodb_adaptive_hash_index=OFF;
+
+# Expand buffer pool to 24MB
+set global innodb_buffer_pool_size = 25165824;
+--source include/wait_condition.inc
+
+select @@innodb_buffer_pool_size;
+
+select count(val) from t1;
+
+drop table t1;
+drop view view0;
+
+--disable_query_log
+set global innodb_adaptive_hash_index = @old_innodb_adaptive_hash_index;
+set global innodb_buffer_pool_size = @old_innodb_buffer_pool_size;
+if (`select (version() like '%debug%') > 0`)
+{
+ set global innodb_disable_resize_buffer_pool_debug = @old_innodb_disable_resize;
+}
+--enable_query_log
+--source include/wait_condition.inc
diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_with_chunks.opt b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_with_chunks.opt
new file mode 100644
index 00000000000..b97a3995457
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_with_chunks.opt
@@ -0,0 +1,3 @@
+--innodb-buffer-pool-size=16M
+--innodb-buffer-pool-chunk-size=2M
+--innodb-page-size=4k
diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_with_chunks.test b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_with_chunks.test
new file mode 100644
index 00000000000..b04b0306bf1
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_with_chunks.test
@@ -0,0 +1,63 @@
+#
+# WL6117 : Resize the InnoDB Buffer Pool Online
+# (innodb_buffer_pool_chunk_size used case)
+#
+
+--source include/have_innodb.inc
+--source include/big_test.inc
+
+let $wait_timeout = 180;
+let $wait_condition =
+ SELECT SUBSTR(variable_value, 1, 34) = 'Completed resizing buffer pool at '
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_resize_status';
+
+--disable_query_log
+set @old_innodb_buffer_pool_size = @@innodb_buffer_pool_size;
+if (`select (version() like '%debug%') > 0`)
+{
+ set @old_innodb_disable_resize = @@innodb_disable_resize_buffer_pool_debug;
+ set global innodb_disable_resize_buffer_pool_debug = OFF;
+}
+--enable_query_log
+
+select @@innodb_buffer_pool_chunk_size;
+
+# fill buffer pool
+create table t1 (id int not null, val int not null default '0', primary key (id)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+create or replace view view0 as select 1 union all select 1;
+
+set @`v_id` := 0;
+set @`v_val` := 0;
+
+# 2^18 == 262144 records
+replace into t1 select (@`v_id` := (@`v_id` + 4) mod 4294967296) as id, (@`v_val` := (@`v_val` + 4) mod 4294967296) as val from view0 v0, view0 v1, view0 v2, view0 v3, view0 v4, view0 v5, view0 v6, view0 v7, view0 v8, view0 v9, view0 v10, view0 v11, view0 v12, view0 v13, view0 v14, view0 v15, view0 v16, view0 v17;
+
+# Shrink buffer pool to 7MB
+set global innodb_buffer_pool_size = 7340032;
+--source include/wait_condition.inc
+
+select count(val) from t1;
+
+# Expand buffer pool to 16MB
+set global innodb_buffer_pool_size = 16777216;
+--source include/wait_condition.inc
+
+select count(val) from t1;
+
+drop table t1;
+drop view view0;
+
+# Try to shrink buffer pool to smaller than chunk size
+set global innodb_buffer_pool_size = 1048576;
+--source include/wait_condition.inc
+select @@innodb_buffer_pool_size;
+
+--disable_query_log
+set global innodb_buffer_pool_size = @old_innodb_buffer_pool_size;
+if (`select (version() like '%debug%') > 0`)
+{
+ set global innodb_disable_resize_buffer_pool_debug = @old_innodb_disable_resize;
+}
+--enable_query_log
+--source include/wait_condition.inc
diff --git a/mysql-test/suite/innodb/t/innodb_bug14147491.test b/mysql-test/suite/innodb/t/innodb_bug14147491.test
index 620b93aae04..44b9d16ca78 100644
--- a/mysql-test/suite/innodb/t/innodb_bug14147491.test
+++ b/mysql-test/suite/innodb/t/innodb_bug14147491.test
@@ -8,12 +8,10 @@
-- source include/not_encrypted.inc
--disable_query_log
-call mtr.add_suppression("InnoDB: Table `test`.`t1` is corrupted. Please drop the table and recreate.");
-call mtr.add_suppression("InnoDB: Cannot open table test/t1 from the internal data dictionary of InnoDB though the .frm file for the table exists. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html for how to resolve the issue.");
-call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed file read of tablespace test/t1 page \[page id: space=[0-9]+, page number=[0-9]+\]. You may have to recover from a backup.");
-call mtr.add_suppression("InnoDB: We detected index corruption in an InnoDB type table.*");
-call mtr.add_suppression("mysqld: Index for table 't1' is corrupt; try to repair it");
-call mtr.add_suppression("mysqld.exe: Index for table 't1' is corrupt; try to repair it");
+call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted\\. Please drop the table and recreate\\.");
+call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed file read of tablespace test/t1 page");
+call mtr.add_suppression("InnoDB: We detected index corruption in an InnoDB type table");
+call mtr.add_suppression("Index for table 't1' is corrupt; try to repair it");
--enable_query_log
--echo # Ensure that purge will not crash on the table after we corrupt it.
diff --git a/mysql-test/suite/innodb/t/innodb_bulk_create_index.test b/mysql-test/suite/innodb/t/innodb_bulk_create_index.test
new file mode 100644
index 00000000000..534b4de87f7
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bulk_create_index.test
@@ -0,0 +1,46 @@
+######## suite/innodb/t/innodb_bulk_create_index.test #####
+# #
+# Testcase for worklog WL#7277: InnoDB: Bulk Load for Create Index #
+# The basic idea of bulk load is to build an index from bottom up #
+# (also known as sorted index build). #
+# Earlier index was create by repeatedly inserting records #
+# Test scenario : #
+# - Run bulk create index on 10K rows #
+# - Run bulk create index on table with various row types #
+# - Run DML and SELECT after bulk index creation #
+# Creation: #
+# 2014-06-19 Implemented this test as part of WL#7277 #
+# #
+######################################################################
+
+-- source include/not_embedded.inc
+-- source include/innodb_page_size_small.inc
+-- source include/big_test.inc
+
+# Test Row Format: REDUNDANT.
+let $row_format = REDUNDANT;
+-- source suite/innodb/include/innodb_bulk_create_index.inc
+
+# Test Row Format: COMPACT.
+let $row_format = COMPACT;
+-- source suite/innodb/include/innodb_bulk_create_index.inc
+
+# Test Row Format: DYNAMIC.
+let $row_format = DYNAMIC;
+-- source suite/innodb/include/innodb_bulk_create_index.inc
+
+# Test Row Format: COMPRESSED.
+let $row_format = COMPRESSED;
+-- source suite/innodb/include/innodb_bulk_create_index.inc
+
+# Test Fill Factor: 10
+let $row_format = COMPACT;
+SET GLOBAL innodb_fill_factor=10;
+-- source suite/innodb/include/innodb_bulk_create_index.inc
+
+# Test Fill Factor: 50
+let $row_format = COMPACT;
+SET GLOBAL innodb_fill_factor=50;
+-- source suite/innodb/include/innodb_bulk_create_index.inc
+
+SET GLOBAL innodb_fill_factor=default;
diff --git a/mysql-test/suite/innodb/t/innodb_bulk_create_index_debug.test b/mysql-test/suite/innodb/t/innodb_bulk_create_index_debug.test
new file mode 100644
index 00000000000..83a12431802
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bulk_create_index_debug.test
@@ -0,0 +1,23 @@
+#
+# wl#7277: InnoDB: Bulk Load for Create Index
+#
+
+# Test Restart & Crash Recovery.
+-- source include/big_test.inc
+-- source include/innodb_page_size_small.inc
+
+# Test Row Format: REDUNDANT.
+let $row_format = REDUNDANT;
+-- source suite/innodb/include/innodb_bulk_create_index_debug.inc
+
+# Test Row Format: COMPACT.
+let $row_format = COMPACT;
+-- source suite/innodb/include/innodb_bulk_create_index_debug.inc
+
+# Test Row Format: DYNAMIC.
+let $row_format = DYNAMIC;
+-- source suite/innodb/include/innodb_bulk_create_index_debug.inc
+
+# Test Row Format: COMPRESSED.
+let $row_format = COMPRESSED;
+-- source suite/innodb/include/innodb_bulk_create_index_debug.inc
diff --git a/mysql-test/suite/innodb/t/innodb_bulk_create_index_flush.test b/mysql-test/suite/innodb/t/innodb_bulk_create_index_flush.test
new file mode 100644
index 00000000000..cffca0cc773
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bulk_create_index_flush.test
@@ -0,0 +1,75 @@
+#
+# Test flush on error in bulk load to make sure we do a proper cleanup.
+# Note: We flush all dirty pages before applying any online log in bulk load.
+#
+
+-- source include/have_innodb.inc
+-- source include/have_debug.inc
+
+# Create Insert Procedure
+DELIMITER |;
+CREATE PROCEDURE populate_t1()
+BEGIN
+ DECLARE i int DEFAULT 1;
+
+ START TRANSACTION;
+ WHILE (i <= 10000) DO
+ INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+ SET i = i + 1;
+ END WHILE;
+ COMMIT;
+END|
+DELIMITER ;|
+
+CREATE TABLE t1(
+ class INT,
+ id INT,
+ title VARCHAR(100)
+) ENGINE=InnoDB;
+
+-- disable_query_log
+CALL populate_t1();
+-- enable_query_log
+
+SELECT COUNT(*) FROM t1;
+
+SET @saved_dbug= @@SESSION.debug_dbug;
+SET debug_dbug='+d,ib_index_build_fail_before_flush';
+
+-- error ER_QUERY_INTERRUPTED
+CREATE INDEX idx_id ON t1(id);
+
+CHECK TABLE t1;
+
+-- error ER_QUERY_INTERRUPTED
+CREATE INDEX idx_title ON t1(title);
+
+CHECK TABLE t1;
+
+-- error ER_QUERY_INTERRUPTED
+CREATE FULLTEXT INDEX fidx_title ON t1(title);
+
+CHECK TABLE t1;
+
+-- error ER_QUERY_INTERRUPTED
+ALTER TABLE t1 ADD COLUMN content TEXT, FORCE;
+
+CHECK TABLE t1;
+
+SET debug_dbug= @saved_dbug;
+
+INSERT INTO t1 VALUES(10001, 10001, 'a10000');
+
+-- error ER_DUP_ENTRY
+ALTER TABLE t1 ADD UNIQUE INDEX idx_title(title);
+
+CHECK TABLE t1;
+
+-- error ER_DUP_ENTRY
+ALTER TABLE t1 ADD UNIQUE INDEX idx_id(id), ADD UNIQUE INDEX idx_title(title);
+
+CHECK TABLE t1;
+
+DROP TABLE t1;
+
+DROP PROCEDURE populate_t1;
diff --git a/mysql-test/suite/innodb/t/innodb_bulk_create_index_replication.test b/mysql-test/suite/innodb/t/innodb_bulk_create_index_replication.test
new file mode 100644
index 00000000000..5b4eaae7557
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bulk_create_index_replication.test
@@ -0,0 +1,182 @@
+######## suite/innodb/t/innodb_wl7277_1.test #####
+# #
+# Testcase for worklog WL#7277: InnoDB: Bulk Load for Create Index #
+# The basic idea of bulk load is to build an index from bottom up #
+# (also known as sorted index build). #
+# Earlier index was create by repeatedly inserting records #
+# Test scenario : #
+# - Run bulk create index on replication setup #
+# - Run bulk create on partitioned table and see its replictaed #
+# to slave #
+# Creation: #
+# 2014-06-19 Implemented this test as part of WL#7277 #
+# #
+######################################################################
+
+--source include/not_embedded.inc
+-- source include/have_innodb.inc
+-- source include/have_partition.inc
+-- source include/master-slave.inc
+
+-- connection master
+# Create Insert Procedure
+DELIMITER |;
+CREATE PROCEDURE populate_t1(load_even INT)
+BEGIN
+ DECLARE i int DEFAULT 1;
+
+ START TRANSACTION;
+ WHILE (i <= 100) DO
+ IF i%2 = 0 AND load_even = 1 THEN
+ INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+ END IF;
+ IF i%2 != 0 AND load_even != 1 THEN
+ INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+ END IF;
+ SET i = i + 1;
+ END WHILE;
+ COMMIT;
+END|
+DELIMITER ;|
+
+CREATE TABLE t1(
+ class INT,
+ id INT,
+ title VARCHAR(100)
+) ENGINE=InnoDB ;
+
+
+
+
+-- disable_query_log
+# Load half records
+CALL populate_t1(1);
+-- enable_query_log
+
+SELECT COUNT(*) FROM t1;
+
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+
+CREATE INDEX idx_title ON t1(title);
+
+
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 10;
+SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 20;
+SELECT * FROM t1 WHERE title = 'a20';
+
+SELECT * FROM t1 WHERE id = 30;
+SELECT * FROM t1 WHERE title = 'a30';
+
+SELECT * FROM t1 WHERE id = 101;
+SELECT * FROM t1 WHERE title = 'a101';
+
+/*Insert/Update/Delete. */
+DELETE FROM t1 WHERE id < 40 AND id > 30;
+INSERT INTO t1 VALUES(38, 38, 'b38');
+UPDATE t1 SET title = CONCAT('b', id) WHERE id < 30 AND id > 20;
+
+SELECT * FROM t1 WHERE id = 28;
+SELECT * FROM t1 WHERE title = 'a28';
+SELECT * FROM t1 WHERE title = 'b28';
+
+SELECT * FROM t1 WHERE id = 38;
+SELECT * FROM t1 WHERE title = 'a38';
+SELECT * FROM t1 WHERE title = 'b38';
+
+SELECT * FROM t1 WHERE id = 101;
+SELECT * FROM t1 WHERE title = 'a101';
+
+-- disable_query_log
+# Load half records (follow up load)
+CALL populate_t1(0);
+-- enable_query_log
+SELECT COUNT(*) FROM t1;
+
+
+SELECT * FROM t1 WHERE id = 10;
+SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 20;
+SELECT * FROM t1 WHERE title = 'a20';
+
+SELECT * FROM t1 WHERE id = 30;
+SELECT * FROM t1 WHERE title = 'a30';
+
+SELECT * FROM t1 WHERE id = 101;
+SELECT * FROM t1 WHERE title = 'a101';
+
+# Create partition table
+CREATE TABLE t_part (
+ class INT ,
+ id INT ,
+ title VARCHAR(30)
+ ) ENGINE=InnoDB
+ PARTITION BY RANGE(id)
+ SUBPARTITION BY KEY(id)
+ SUBPARTITIONS 4
+ (
+ PARTITION p0 VALUES LESS THAN (5000),
+ PARTITION p1 VALUES LESS THAN (MAXVALUE)
+ );
+INSERT INTO t_part SELECT * FROM t1;
+ALTER TABLE t_part ADD INDEX `idx` (class,id,title(10));
+
+SELECT * FROM t_part WHERE id = 10;
+SELECT * FROM t_part WHERE title = 'a10';
+
+SELECT * FROM t_part WHERE id = 20;
+SELECT * FROM t_part WHERE title = 'a20';
+
+SELECT * FROM t_part WHERE id = 30;
+SELECT * FROM t_part WHERE title = 'a30';
+
+SELECT * FROM t_part WHERE id = 101;
+SELECT * FROM t_part WHERE title = 'a101';
+
+
+--source include/sync_slave_sql_with_master.inc
+-- connection slave
+SHOW CREATE TABLE t1;
+SHOW CREATE TABLE t_part;
+SELECT COUNT(*) FROM t1;
+SELECT COUNT(*) FROM t_part;
+
+SELECT * FROM t1 WHERE id = 10;
+SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 20;
+SELECT * FROM t1 WHERE title = 'a20';
+
+SELECT * FROM t1 WHERE id = 30;
+SELECT * FROM t1 WHERE title = 'a30';
+
+SELECT * FROM t1 WHERE id = 101;
+SELECT * FROM t1 WHERE title = 'a101';
+
+
+
+SELECT * FROM t_part WHERE id = 10;
+SELECT * FROM t_part WHERE title = 'a10';
+
+SELECT * FROM t_part WHERE id = 20;
+SELECT * FROM t_part WHERE title = 'a20';
+
+SELECT * FROM t_part WHERE id = 30;
+SELECT * FROM t_part WHERE title = 'a30';
+
+SELECT * FROM t_part WHERE id = 101;
+SELECT * FROM t_part WHERE title = 'a101';
+
+
+-- connection master
+DROP PROCEDURE populate_t1;
+DROP TABLE t1;
+DROP TABLE t_part;
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/innodb/t/innodb_bulk_create_index_small.test b/mysql-test/suite/innodb/t/innodb_bulk_create_index_small.test
new file mode 100644
index 00000000000..d04dd59f7e7
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bulk_create_index_small.test
@@ -0,0 +1,148 @@
+#
+# wl#7277: InnoDB: Bulk Load for Create Index
+#
+
+-- source include/innodb_page_size_small.inc
+
+# Create Insert Procedure
+DELIMITER |;
+CREATE PROCEDURE populate_t1()
+BEGIN
+ DECLARE i int DEFAULT 1;
+
+ START TRANSACTION;
+ WHILE (i <= 1000) DO
+ INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
+ SET i = i + 1;
+ END WHILE;
+ COMMIT;
+END|
+DELIMITER ;|
+
+SELECT @@innodb_fill_factor;
+
+# Test Compact Table
+CREATE TABLE t1(
+ class INT,
+ id INT,
+ title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+
+-- disable_query_log
+CALL populate_t1();
+-- enable_query_log
+
+SELECT COUNT(*) FROM t1;
+
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+
+CREATE INDEX idx_title ON t1(title);
+
+/* Check table. */
+CHECK TABLE t1;
+
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 10;
+SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 500;
+SELECT * FROM t1 WHERE title = 'a500';
+
+SELECT * FROM t1 WHERE id = 1000;
+SELECT * FROM t1 WHERE title = 'a1000';
+
+SELECT * FROM t1 WHERE id = 1010;
+SELECT * FROM t1 WHERE title = 'a1010';
+
+DROP TABLE t1;
+
+# Test Blob
+CREATE TABLE t1(
+ a INT PRIMARY KEY,
+ b TEXT,
+ c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+
+INSERT INTO t1 VALUES
+ (1, REPEAT('a',10000), 'a'),
+ (2, REPEAT('b',20000), 'b'),
+ (3, REPEAT('c',40000), 'c'),
+ (4, REPEAT('d',60000), 'd');
+
+ALTER TABLE t1 DROP COLUMN c;
+
+CHECK TABLE t1;
+
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+
+DROP TABLE t1;
+
+SET GLOBAL innodb_file_per_table=default;
+
+# Test Compressed Table
+SET GLOBAL innodb_file_per_table=1;
+
+CREATE TABLE t1(
+ class INT,
+ id INT,
+ title VARCHAR(100)
+) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+
+-- disable_query_log
+CALL populate_t1();
+-- enable_query_log
+
+SELECT COUNT(*) FROM t1;
+
+/* Create index. */
+CREATE INDEX idx_id ON t1(id);
+
+CREATE INDEX idx_title ON t1(title);
+
+/* Check table. */
+CHECK TABLE t1;
+
+/* Select by index. */
+EXPLAIN SELECT * FROM t1 WHERE id = 10;
+EXPLAIN SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 10;
+SELECT * FROM t1 WHERE title = 'a10';
+
+SELECT * FROM t1 WHERE id = 500;
+SELECT * FROM t1 WHERE title = 'a500';
+
+SELECT * FROM t1 WHERE id = 1000;
+SELECT * FROM t1 WHERE title = 'a1000';
+
+SELECT * FROM t1 WHERE id = 1010;
+SELECT * FROM t1 WHERE title = 'a1010';
+
+DROP TABLE t1;
+
+# Test Compression & Blob
+CREATE TABLE t1(
+ a INT PRIMARY KEY,
+ b TEXT,
+ c TEXT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+
+INSERT INTO t1 VALUES
+ (1, REPEAT('a',10000), 'a'),
+ (2, REPEAT('b',20000), 'b'),
+ (3, REPEAT('c',40000), 'c'),
+ (4, REPEAT('d',60000), 'd');
+
+ALTER TABLE t1 DROP COLUMN c;
+
+CHECK TABLE t1;
+
+SELECT CHAR_LENGTH(b) FROM t1 WHERE a=4975;
+
+DROP TABLE t1;
+
+SET GLOBAL innodb_file_per_table=default;
+
+DROP PROCEDURE populate_t1;
diff --git a/mysql-test/suite/innodb/t/innodb_corrupt_bit.test b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test
index 52a318f0fa8..1d723c0bbc3 100644
--- a/mysql-test/suite/innodb/t/innodb_corrupt_bit.test
+++ b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test
@@ -33,9 +33,10 @@ INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+1,z+1 FROM corrupt_bit_test_Ä;
select count(*) from corrupt_bit_test_Ä;
# This will flag all secondary indexes corrupted
-SET SESSION debug="+d,dict_set_index_corrupted";
+SET @save_dbug = @@SESSION.debug_dbug;
+SET debug_dbug = '+d,dict_set_index_corrupted';
check table corrupt_bit_test_Ä;
-SET SESSION debug="-d,dict_set_index_corrupted";
+SET debug_dbug = @save_dbug;
# Cannot create new indexes while corrupted indexes exist
--error ER_INDEX_CORRUPT
diff --git a/mysql-test/suite/innodb/t/innodb_default_row_format.combinations b/mysql-test/suite/innodb/t/innodb_default_row_format.combinations
new file mode 100644
index 00000000000..f3bc2cc0c25
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_default_row_format.combinations
@@ -0,0 +1,4 @@
+[redundant]
+innodb_default_row_format=redundant
+[dynamic]
+innodb_default_row_format=dynamic
diff --git a/mysql-test/suite/innodb/t/innodb_default_row_format.inc b/mysql-test/suite/innodb/t/innodb_default_row_format.inc
new file mode 100644
index 00000000000..15c61dc6342
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_default_row_format.inc
@@ -0,0 +1,2 @@
+# See also innodb_default_row_format.combinations
+--source include/have_innodb.inc
diff --git a/mysql-test/suite/innodb/t/innodb_force_recovery.test b/mysql-test/suite/innodb/t/innodb_force_recovery.test
index f9af16f6609..9dae9f8e7c9 100644
--- a/mysql-test/suite/innodb/t/innodb_force_recovery.test
+++ b/mysql-test/suite/innodb/t/innodb_force_recovery.test
@@ -7,6 +7,7 @@
--disable_query_log
call mtr.add_suppression("InnoDB: Failed to find tablespace for table .* in the cache. Attempting to load the tablespace with space id");
call mtr.add_suppression("InnoDB: Allocated tablespace ID \\d+ for test.t[12], old maximum was");
+call mtr.add_suppression("InnoDB: Allocated tablespace ID \\d+ for mysql.transaction_registry, old maximum was");
--enable_query_log
create table t1(f1 int not null, f2 int not null, index idx(f2))engine=innodb;
diff --git a/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.opt b/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.opt
index f543bd0da39..587a2d7e6c1 100644
--- a/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.opt
+++ b/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.opt
@@ -1,3 +1,4 @@
--innodb-page-size=32K
--innodb_buffer_pool_size=32M
---innodb-stats-persistent=ON
+--skip-innodb-stats-persistent
+--innodb-sys-tablestats
diff --git a/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.test b/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.test
index 138917593da..aa816a9b0e8 100644
--- a/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.test
+++ b/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.test
@@ -6,16 +6,7 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the
# Check page size 32k
SELECT @@innodb_page_size;
-let $innodb_file_per_table = `SELECT @@innodb_file_per_table`;
-let $innodb_strict_mode = `SELECT @@innodb_strict_mode`;
-
---disable_warnings
-SET GLOBAL innodb_file_per_table=ON;
-SET @@innodb_strict_mode=ON;
---enable_warnings
-
-SELECT @@innodb_file_per_table;
-SELECT @@innodb_strict_mode;
+SET innodb_strict_mode=ON;
# Check the error when the max record length > 16K for innodb_page_size=32k
--error ER_TOO_BIG_ROWSIZE
@@ -356,9 +347,8 @@ INSERT INTO t VALUES (REPEAT('a',65535));
SELECT LENGTH(col) FROM t;
FLUSH TABLE t;
ANALYZE TABLE t;
-# retrieve the number of leaf pages
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
DROP TABLE t;
CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
@@ -369,9 +359,8 @@ INSERT INTO t VALUES (REPEAT('a',65535));
SELECT LENGTH(col) FROM t;
FLUSH TABLE t;
ANALYZE TABLE t;
-# retrieve the number of leaf pages
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
DROP TABLE t;
CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=COMPACT;
@@ -382,18 +371,6 @@ INSERT INTO t VALUES (REPEAT('a',65535));
SELECT LENGTH(col) FROM t;
FLUSH TABLE t;
ANALYZE TABLE t;
-# retrieve the number of leaf pages
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
DROP TABLE t;
-
-# cleanup
---disable_query_log
---disable_warnings
-eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table;
-eval SET GLOBAL INNODB_STRICT_MODE=$innodb_strict_mode;
---enable_warnings
---enable_query_log
-
---echo # Success
-
diff --git a/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.opt b/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.opt
index 8c9b8ae1e48..1a8442b841f 100644
--- a/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.opt
+++ b/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.opt
@@ -1,3 +1,4 @@
--innodb-page-size=64K
--innodb_buffer_pool_size=32M
---innodb-stats-persistent=ON
+--skip-innodb-stats-persistent
+--innodb-sys-tablestats
diff --git a/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.test b/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.test
index 7b830096afa..598cc3d77bf 100644
--- a/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.test
+++ b/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.test
@@ -6,16 +6,7 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the
# Check page size 64k
SELECT @@innodb_page_size;
-let $innodb_file_per_table = `SELECT @@innodb_file_per_table`;
-let $innodb_strict_mode = `SELECT @@innodb_strict_mode`;
-
---disable_warnings
-SET GLOBAL innodb_file_per_table=ON;
-SET @@innodb_strict_mode=ON;
---enable_warnings
-
-SELECT @@innodb_file_per_table;
-SELECT @@innodb_strict_mode;
+SET innodb_strict_mode=ON;
# Check the error when the max record length > 32K for innodb_page_size=64k
--error ER_TOO_BIG_ROWSIZE
@@ -560,9 +551,8 @@ INSERT INTO t VALUES (REPEAT('a',65535));
SELECT LENGTH(col) FROM t;
FLUSH TABLE t;
ANALYZE TABLE t;
-# retrieve the number of leaf pages
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
DROP TABLE t;
CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
@@ -573,9 +563,8 @@ INSERT INTO t VALUES (REPEAT('a',65535));
SELECT LENGTH(col) FROM t;
FLUSH TABLE t;
ANALYZE TABLE t;
-# retrieve the number of leaf pages
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
DROP TABLE t;
CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=COMPACT;
@@ -586,18 +575,6 @@ INSERT INTO t VALUES (REPEAT('a',65535));
SELECT LENGTH(col) FROM t;
FLUSH TABLE t;
ANALYZE TABLE t;
-# retrieve the number of leaf pages
-SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages';
-SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't';
+SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE name = 'test/t';
DROP TABLE t;
-
-# cleanup
---disable_query_log
---disable_warnings
-eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table;
-eval SET GLOBAL INNODB_STRICT_MODE=$innodb_strict_mode;
---enable_warnings
---enable_query_log
-
---echo # Success
-
diff --git a/mysql-test/suite/innodb/t/instant_alter.test b/mysql-test/suite/innodb/t/instant_alter.test
index 4045ce282e8..d95f412fb37 100644
--- a/mysql-test/suite/innodb/t/instant_alter.test
+++ b/mysql-test/suite/innodb/t/instant_alter.test
@@ -56,7 +56,7 @@ eval CREATE TABLE t1
SPATIAL INDEX(c3)) $engine;
INSERT INTO t1 (id, c2) values(1,1);
-SELECT * FROM t1;
+SELECT id,c2,ST_AsText(c3) c3 FROM t1;
--enable_info
ALTER TABLE t1 ADD COLUMN (
@@ -68,7 +68,7 @@ ALTER TABLE t1 ADD INDEX(d3);
BEGIN;
UPDATE t1 SET d3='';
ROLLBACK;
-SELECT * FROM t1;
+SELECT id,c2,ST_AsText(c3) c3, d1, d2, d3, d4 FROM t1;
INSERT INTO t1 (id) VALUES(2),(3),(4),(5),(6);
--enable_info
@@ -80,7 +80,7 @@ CHANGE d4 dfour TIMESTAMP NOT NULL DEFAULT now();
UPDATE t1 SET d3='foo' WHERE id = 2;
UPDATE t1 SET d3=DEFAULT WHERE id = 4;
INSERT INTO t1 SET id = 7;
-SELECT * FROM t1;
+SELECT id,c2,ST_AsText(c3) c3, d1, d2, d3, dfour FROM t1;
CHECK TABLE t1;
# add virtual columns
@@ -106,9 +106,9 @@ UPDATE t1 SET d3 = 'xxxxx' WHERE id = 2;
# transaction rollback
BEGIN;
UPDATE t1 SET d3 = 'xxxxx' WHERE id = 3;
-SELECT * FROM t1 WHERE id = 3;
+SELECT id, c2, ST_AsText(c3) c3, d1, d2, d3, dfour, e1, e2, e3, d5, d6, d7 FROM t1 WHERE id = 3;
ROLLBACK;
-SELECT * FROM t1 WHERE id = 3;
+SELECT id, c2, ST_AsText(c3) c3, d1, d2, d3, dfour, e1, e2, e3, d5, d6, d7 FROM t1 WHERE id = 3;
# NULL to NULL, no change
BEGIN;
@@ -116,9 +116,9 @@ UPDATE t1 SET d7 = NULL WHERE ID = 5;
ROLLBACK;
BEGIN;
UPDATE t1 SET d7 = NULL, d6 = 10 WHERE id = 5;
-SELECT * FROM t1 WHERE id = 5;
+SELECT id, c2, ST_AsText(c3) c3, d1, d2, d3, dfour, e1, e2, e3, d5, d6, d7 FROM t1 WHERE id = 5;
ROLLBACK;
-SELECT * FROM t1 WHERE id = 5;
+SELECT id, c2, ST_AsText(c3) c3, d1, d2, d3, dfour, e1, e2, e3, d5, d6, d7 FROM t1 WHERE id = 5;
# add virtual stored columns; not instant
--enable_info
@@ -128,7 +128,7 @@ ALTER TABLE t1 ADD COLUMN (f1 VARCHAR(20) AS (concat('x', e2)) STORED);
ALTER TABLE t1 ADD COLUMN (d8 VARCHAR(20) DEFAULT 'omnopq');
--disable_info
-SELECT * FROM t1;
+SELECT id, c2, ST_AsText(c3) c3, d1, d2, d3, dfour, e1, e2, e3, d5, d6, d7, f1, d8 FROM t1;
SHOW CREATE TABLE t1;
--enable_info
@@ -160,7 +160,7 @@ COMMIT;
--enable_info
ALTER TABLE t2 ADD COLUMN d1 VARCHAR(2000) DEFAULT REPEAT('asdf',500);
--disable_info
-SELECT * FROM t2;
+SELECT id, c1, ST_AsText(p) p, d1 FROM t2;
# inplace update, rollback
BEGIN;
@@ -206,17 +206,17 @@ eval CREATE TABLE t3
SPATIAL INDEX(c3))
$engine;
INSERT INTO t3(id,c2) VALUES(1,1),(2,2),(3,3);
-SELECT * FROM t3;
+SELECT id, c2, ST_AsText(c3) c3 FROM t3;
--enable_info
ALTER TABLE t3 ADD COLUMN
(c4 DATETIME DEFAULT current_timestamp(),
c5 TIMESTAMP NOT NULL DEFAULT current_timestamp(),
c6 POINT);
-SELECT * FROM t3;
+SELECT id, c2, ST_AsText(c3) c3, c4, c5, c6 FROM t3;
ALTER TABLE t3 ADD COLUMN c7 TIME NOT NULL DEFAULT current_timestamp();
ALTER TABLE t3 ADD COLUMN c8 DATE NOT NULL DEFAULT current_timestamp();
--disable_info
-SELECT * FROM t3;
+SELECT id, c2, ST_AsText(c3) c3, c4, c5, c6, c7, c8 FROM t3;
--enable_info
ALTER TABLE t3 ADD COLUMN t TEXT CHARSET utf8
@@ -230,12 +230,32 @@ ALTER TABLE t3 CHANGE t phrase TEXT DEFAULT 0xc3a4c3a448,
CHANGE b b BLOB NOT NULL DEFAULT 'binary line of business';
--disable_info
INSERT INTO t3 SET id=5, c2=9;
-SELECT * FROM t3;
+SELECT id, c2, ST_AsText(c3) c3, c4, c5, c6, c7, c8, phrase, b FROM t3;
--enable_info
ALTER TABLE t3 DROP c3, DROP c7;
--disable_info
SELECT * FROM t3;
+eval CREATE TABLE t4
+(id INT, foo INT DEFAULT 0, c1 VARCHAR(4000),
+ p GEOMETRY NOT NULL DEFAULT ST_GeomFromText('LINESTRING(0 0,0 1,1 1)'),
+ PRIMARY KEY(id,foo))
+$engine;
+
+INSERT INTO t4 (id,c1) VALUES (1, REPEAT('a', 4000)), (2, REPEAT('a', 4000));
+ALTER TABLE t4 ADD COLUMN d1 INT;
+
+BEGIN;
+UPDATE t4 SET c1 = repeat('1', 4000), foo=1 WHERE id=1;
+INSERT INTO t4 (id,c1) VALUES (1, REPEAT('a', 4000));
+UPDATE t4 SET c1 = repeat('2', 4000), foo=1 WHERE id=2;
+ROLLBACK;
+
+BEGIN;
+UPDATE t4 SET d1 = 1,foo=2 WHERE id=1;
+INSERT INTO t4 (id,foo,c1) VALUES (1, 1, REPEAT('1', 4000));
+COMMIT;
+
eval CREATE TABLE big
(id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000),
p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p))
@@ -279,7 +299,17 @@ WHERE name = 'test/big';
connection default;
--source include/wait_all_purged.inc
-DROP TABLE t1,t2,t3,big;
+DROP TABLE t1,t2,t3,t4,big;
+
+# MDEV-14837 Duplicate primary keys are allowed after ADD COLUMN / UPDATE
+eval CREATE TABLE t1 (a VARCHAR(1) PRIMARY KEY) $engine;
+INSERT INTO t1 SET a='a';
+ALTER TABLE t1 ADD COLUMN b INT NOT NULL DEFAULT 0;
+UPDATE t1 SET b = 1;
+--error ER_DUP_ENTRY
+INSERT INTO t1 SET a='a';
+SELECT * FROM t1;
+DROP TABLE t1;
dec $format;
}
diff --git a/mysql-test/suite/innodb/t/instant_alter_crash.test b/mysql-test/suite/innodb/t/instant_alter_crash.test
index 1bdde904fc2..fe7301b4f78 100644
--- a/mysql-test/suite/innodb/t/instant_alter_crash.test
+++ b/mysql-test/suite/innodb/t/instant_alter_crash.test
@@ -4,6 +4,8 @@
--source include/have_debug.inc
--source include/have_debug_sync.inc
+FLUSH TABLES;
+
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
let MYSQLD_DATADIR=`select @@datadir`;
diff --git a/mysql-test/suite/innodb/t/instant_alter_rollback.test b/mysql-test/suite/innodb/t/instant_alter_rollback.test
index c27f198b4c6..487a60dcbe1 100644
--- a/mysql-test/suite/innodb/t/instant_alter_rollback.test
+++ b/mysql-test/suite/innodb/t/instant_alter_rollback.test
@@ -2,6 +2,9 @@
# The embedded server tests do not support restarting.
--source include/not_embedded.inc
+# Flush any open myisam tables from previous tests
+FLUSH TABLES;
+
--echo #
--echo # MDEV-11369: Instant ADD COLUMN for InnoDB
--echo #
diff --git a/mysql-test/suite/innodb/t/lock_deleted.test b/mysql-test/suite/innodb/t/lock_deleted.test
new file mode 100644
index 00000000000..8dbad90d354
--- /dev/null
+++ b/mysql-test/suite/innodb/t/lock_deleted.test
@@ -0,0 +1,72 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+--source include/count_sessions.inc
+
+connect(stop_purge, localhost, root,,);
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connect(delete, localhost, root,,);
+connection default;
+
+CREATE TABLE t1(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1,1);
+DELETE FROM t1;
+
+let $i=2;
+while ($i) {
+let $iso= `SELECT CASE $i WHEN 1 THEN 'UNCOMMITTED' ELSE 'COMMITTED' END`;
+
+SET DEBUG_SYNC='row_ins_sec_index_unique SIGNAL inserted WAIT_FOR locked';
+BEGIN;
+send INSERT INTO t1 VALUES(1,1);
+
+connection delete;
+SET DEBUG_SYNC='now WAIT_FOR inserted';
+SET DEBUG_SYNC='innodb_row_search_for_mysql_exit SIGNAL locked';
+eval SET SESSION TRANSACTION ISOLATION LEVEL READ $iso;
+BEGIN;
+send DELETE FROM t1 WHERE b=1;
+
+connection default;
+reap;
+connection delete;
+reap;
+COMMIT;
+
+connection default;
+SET DEBUG_SYNC='RESET';
+ROLLBACK;
+
+dec $i;
+}
+
+SET DEBUG_SYNC='row_ins_sec_index_unique SIGNAL inserted WAIT_FOR locked';
+BEGIN;
+SET innodb_lock_wait_timeout=1;
+send INSERT INTO t1 VALUES(1,1);
+
+connection delete;
+SET DEBUG_SYNC='now WAIT_FOR inserted';
+SET DEBUG_SYNC='innodb_row_search_for_mysql_exit SIGNAL locked';
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+BEGIN;
+send DELETE FROM t1 WHERE b=1;
+
+connection default;
+--error ER_LOCK_WAIT_TIMEOUT
+reap;
+COMMIT;
+SET DEBUG_SYNC='RESET';
+
+connection delete;
+reap;
+COMMIT;
+
+disconnect delete;
+disconnect stop_purge;
+
+connection default;
+DROP TABLE t1;
+
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/log_corruption.test b/mysql-test/suite/innodb/t/log_corruption.test
index 3bf68cab4cc..e9b081cff76 100644
--- a/mysql-test/suite/innodb/t/log_corruption.test
+++ b/mysql-test/suite/innodb/t/log_corruption.test
@@ -16,6 +16,7 @@ call mtr.add_suppression("InnoDB: Log scan aborted at LSN");
call mtr.add_suppression("InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42\\r?$");
call mtr.add_suppression("InnoDB: Obtaining redo log encryption key version 1 failed");
call mtr.add_suppression("InnoDB: Decrypting checkpoint failed");
+call mtr.add_suppression("InnoDB: Are you sure you are using the right ib_logfiles to start up the database\\? Log sequence number in the ib_logfiles is 1213964,");
--enable_query_log
let bugdir= $MYSQLTEST_VARDIR/tmp/log_corruption;
@@ -140,6 +141,24 @@ eval $check_no_innodb;
let SEARCH_PATTERN=InnoDB: Upgrade after a crash is not supported. This redo log was created before MariaDB 10\\.2\\.2, and it appears corrupted;
--source include/search_pattern_in_file.inc
+--echo # empty redo log from before MariaDB 10.2.2
+perl;
+die unless open OUT, "+<", "$ENV{bugdir}/ib_logfile0";
+binmode OUT;
+die unless seek(OUT, 0x800, 0);
+print OUT pack("NnnNx[496]N", 0x80000944, 12, 12, 0, 0xb2a);
+close OUT or die;
+EOF
+--let $restart_parameters= $dirs --innodb-force-recovery=5 --innodb-log-file-size=1m
+--source include/start_mysqld.inc
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+--source include/shutdown_mysqld.inc
+--let SEARCH_PATTERN= InnoDB: Upgrading redo log:
+--source include/search_pattern_in_file.inc
+--let $restart_parameters= $dirs
+
--echo # redo log from "after" MariaDB 10.2.2, but with invalid header checksum
perl;
die unless open OUT, "+<", "$ENV{bugdir}/ib_logfile0";
@@ -204,7 +223,9 @@ EOF
--source include/start_mysqld.inc
eval $check_no_innodb;
--source include/shutdown_mysqld.inc
-let SEARCH_PATTERN=InnoDB: Upgrade after a crash is not supported\. The redo log was created with malicious intentions, or perhaps, and it appears corrupted\.;
+let SEARCH_PATTERN=InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122;
+--source include/search_pattern_in_file.inc
+let SEARCH_PATTERN=InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\.;
--source include/search_pattern_in_file.inc
--echo # same, but with current-version header
@@ -334,13 +355,14 @@ let SEARCH_PATTERN=InnoDB: MLOG_FILE_NAME incorrect:bigot;
--let SEARCH_PATTERN= len 22; hex 38000000000012860cb7809781e800066269676f7400; asc 8 bigot ;
--source include/search_pattern_in_file.inc
---echo # missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
+--echo # 10.2 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
perl;
die unless open OUT, "+<", "$ENV{bugdir}/ib_logfile0";
binmode OUT;
# header block
-print OUT pack("Nx[5]nx[5]", 103, 0x1286), "MariaDB 10.3.1";
-print OUT pack("x[478]N", 0x85021a0f);
+print OUT pack("Nx[5]nx[5]", 1, 0x1286);
+print OUT "ibbackup was here!!!1!";
+print OUT pack("x[470]N", 0x52b54540);
# invalid (all-zero) checkpoint page 1 and an empty log page
print OUT chr(0) x 1024;
# valid checkpoint block 2
@@ -361,7 +383,74 @@ EOF
--source include/start_mysqld.inc
eval $check_no_innodb;
--source include/shutdown_mysqld.inc
---let SEARCH_PATTERN= InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42\$
+--let SEARCH_PATTERN= InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42
+--source include/search_pattern_in_file.inc
+
+--echo # 10.3 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
+perl;
+die unless open OUT, "+<", "$ENV{bugdir}/ib_logfile0";
+binmode OUT;
+print OUT pack("Nx[5]nx[5]", 103, 0x1286), "MariaDB 10.3.1";
+print OUT pack("x[478]N", 0x85021a0f);
+close OUT or die;
+EOF
+
+--source include/start_mysqld.inc
+eval $check_no_innodb;
+--source include/shutdown_mysqld.inc
+--let SEARCH_PATTERN= InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42
+--source include/search_pattern_in_file.inc
+
+--echo # Empty 10.3 redo log
+perl;
+die unless open OUT, "+<", "$ENV{bugdir}/ib_logfile0";
+binmode OUT;
+die unless seek(OUT, 0x800, 0);
+print OUT pack("NnnNx[496]N", 0x80000944, 12, 12, 1, 0x46c8a2a2);
+close OUT or die;
+EOF
+
+--let $restart_parameters= $dirs --innodb-force-recovery=5 --innodb-log-file-size=1m
+--source include/start_mysqld.inc
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+--source include/shutdown_mysqld.inc
+# In encryption.innodb_encrypt_log_corruption, we would convert the
+# log to encrypted format. Writing an extra log checkpoint before the
+# redo log conversion would advance the LSN by the size of a
+# MLOG_CHECKPOINT record (9 bytes).
+--let SEARCH_PATTERN= InnoDB: .* started; log sequence number 121397[09]
+--source include/search_pattern_in_file.inc
+
+--echo # Empty 10.2 redo log
+perl;
+die unless open OUT, "+<", "$ENV{bugdir}/ib_logfile0";
+binmode OUT;
+# header block
+print OUT pack("Nx[5]nx[5]", 1, 0x1286);
+print OUT "ibbackup was here!!!1!";
+print OUT pack("x[470]N", 0x52b54540);
+# In encryption.innodb_log_corruption the previous step would
+# replace the block with an encrypted one and update the checkpoint.
+# Restore them.
+# invalid (all-zero) checkpoint page 1 and an empty log page
+print OUT chr(0) x 1024;
+# valid checkpoint block 2
+print OUT pack("x[12]NNNx[264]", 0x12860c, 0, 0x80c);
+# pointer to the MLOG_CHECKPOINT record, and checkpoint page checksum
+print OUT pack("H*x[204]NNN", "590DBAACFE922582", 0x128612, 0, 0x101741b);
+# log page
+print OUT pack("NnnNx[496]N", 0x80000944, 12, 12, 1, 0x46c8a2a2);
+close OUT or die;
+EOF
+
+--source include/start_mysqld.inc
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+--source include/shutdown_mysqld.inc
+--let SEARCH_PATTERN= InnoDB: Upgrading redo log:
--source include/search_pattern_in_file.inc
--echo # Minimal MariaDB 10.1.21 encrypted redo log
diff --git a/mysql-test/suite/innodb/t/log_file_name.test b/mysql-test/suite/innodb/t/log_file_name.test
index 2ee8c49aa7c..87c1681d443 100644
--- a/mysql-test/suite/innodb/t/log_file_name.test
+++ b/mysql-test/suite/innodb/t/log_file_name.test
@@ -163,6 +163,7 @@ call mtr.add_suppression("InnoDB: Cannot rename.*because the target file exists"
call mtr.add_suppression("InnoDB: Log scan aborted at LSN");
# The following are for the --innodb-force-recovery=1 with broken u* tables:
call mtr.add_suppression("InnoDB: Header page consists of zero bytes in datafile: .*u1.ibd");
+call mtr.add_suppression("InnoDB: The size of the file .*u1\\.ibd is only 16384 bytes, should be at least 65536");
call mtr.add_suppression("InnoDB: The error means the system cannot find the path specified");
call mtr.add_suppression("InnoDB: .*you must create directories");
call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: '.*u[1-5]\.ibd'");
diff --git a/mysql-test/suite/innodb/t/log_file_size.test b/mysql-test/suite/innodb/t/log_file_size.test
index 140198de4ab..44cb155c7d9 100644
--- a/mysql-test/suite/innodb/t/log_file_size.test
+++ b/mysql-test/suite/innodb/t/log_file_size.test
@@ -17,7 +17,8 @@ call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE faile
call mtr.add_suppression("InnoDB: Plugin initialization aborted");
call mtr.add_suppression("InnoDB: innodb_read_only prevents crash recovery");
call mtr.add_suppression("InnoDB: Are you sure you are using the right ib_logfiles");
-call mtr.add_suppression("InnoDB: Cannot create log files in read-only mode");
+call mtr.add_suppression("InnoDB: Cannot (create|resize) log files in read-only mode");
+call mtr.add_suppression("InnoDB: Can't initiate database recovery, running in read-only-mode");
call mtr.add_suppression("InnoDB: Only one log file found");
call mtr.add_suppression("InnoDB: Log file .*ib_logfile[01].* size");
call mtr.add_suppression("InnoDB: Unable to open .*ib_logfile0. to check native AIO read support");
diff --git a/mysql-test/suite/innodb/t/mvcc.test b/mysql-test/suite/innodb/t/mvcc.test
new file mode 100644
index 00000000000..bf76a5de798
--- /dev/null
+++ b/mysql-test/suite/innodb/t/mvcc.test
@@ -0,0 +1,52 @@
+--source include/have_innodb.inc
+
+SET @save_per_table= @@GLOBAL.innodb_file_per_table;
+SET GLOBAL innodb_file_per_table= 1;
+
+let MYSQLD_DATADIR =`SELECT @@datadir`;
+
+--echo #
+--echo # MDEV-15249 Crash in MVCC read after IMPORT TABLESPACE
+--echo #
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(0);
+FLUSH TABLES t1 WITH READ LOCK;
+perl;
+do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+ib_backup_tablespace("test", "t1");
+EOF
+UNLOCK TABLES;
+
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+
+connect (con1,localhost,root,,);
+ALTER TABLE t1 FORCE, ALGORITHM=COPY;
+
+connection default;
+--error ER_TABLE_DEF_CHANGED
+SELECT * FROM t1;
+COMMIT;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+
+connection con1;
+
+ALTER TABLE t1 DISCARD TABLESPACE;
+
+perl;
+do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+ib_restore_tablespace("test", "t1");
+EOF
+
+ALTER TABLE t1 IMPORT TABLESPACE;
+disconnect con1;
+
+connection default;
+--echo # FIXME: Block this with ER_TABLE_DEF_CHANGED
+SELECT * FROM t1;
+COMMIT;
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+SET GLOBAL innodb_file_per_table= @save_per_table;
diff --git a/mysql-test/suite/innodb/t/purge_secondary.opt b/mysql-test/suite/innodb/t/purge_secondary.opt
new file mode 100644
index 00000000000..99bf0e5a28b
--- /dev/null
+++ b/mysql-test/suite/innodb/t/purge_secondary.opt
@@ -0,0 +1 @@
+--innodb-sys-tablestats
diff --git a/mysql-test/suite/innodb/t/purge_secondary.test b/mysql-test/suite/innodb/t/purge_secondary.test
new file mode 100644
index 00000000000..47cfaec41ca
--- /dev/null
+++ b/mysql-test/suite/innodb/t/purge_secondary.test
@@ -0,0 +1,131 @@
+--source include/have_innodb.inc
+
+# Ensure that the history list length will actually be decremented by purge.
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
+
+CREATE TABLE t1 (
+ a SERIAL, b CHAR(255) NOT NULL DEFAULT '', c BOOLEAN DEFAULT false,
+ l LINESTRING NOT NULL DEFAULT ST_linefromtext('linestring(448 -689,
+ 453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,
+ 468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,
+ 479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,
+ 501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,
+ 518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,
+ 522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,
+ 536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,
+ 554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,
+ 549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,
+ 554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,
+ 470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,
+ 486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,
+ 495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,
+ 498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,
+ 511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,
+ 515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,
+ 529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,
+ 4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,
+ 4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,
+ 4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,
+ 4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,
+ 4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,
+ 4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,
+ 4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,
+ 4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,
+ 6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,
+ 7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,
+ 7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,
+ 7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,
+ 7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,
+ 482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,
+ 483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,
+ 493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,
+ 507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,
+ 503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,
+ 505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,
+ 497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,
+ 498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,
+ 503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,
+ 496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,
+ 497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,
+ 515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,
+ 527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,
+ 532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,
+ 541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,
+ 561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,
+ 561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,
+ 4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,
+ 9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,
+ 9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,
+ 9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,
+ 9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,
+ 9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,
+ 9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,
+ 9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,
+ 9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,
+ 9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,
+ 9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,
+ 9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,
+ 9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,
+ 502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,
+ 3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,
+ 3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,
+ 7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,
+ 7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,
+ 7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,
+ 7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,
+ 7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,
+ 12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,
+ 12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,
+ 12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,
+ 12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,
+ 9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,
+ 9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,
+ 9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,
+ 9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,
+ 9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,
+ 9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,
+ 9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,
+ 9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,
+ 9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,
+ 9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,
+ 9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,
+ 9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,
+ 9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,
+ 9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,
+ 9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,
+ 9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,
+ 9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,
+ 9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,
+ 9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,
+ 9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,
+ 9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,
+ 9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,
+ 12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,
+ 12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677)'),
+ INDEX(b,c), SPATIAL INDEX(l)
+) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+INSERT INTO t1 () VALUES (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
+SELECT LENGTH(l) FROM t1;
+INSERT INTO t1 (a) SELECT NULL FROM t1;
+INSERT INTO t1 (a) SELECT NULL FROM t1;
+CHECK TABLE t1;
+UPDATE t1 SET c=true, l=ST_linefromtext('linestring(0 0,1 1,2 2)');
+DELETE FROM t1;
+CHECK TABLE t1;
+
+source include/wait_all_purged.inc;
+
+ANALYZE TABLE t1;
+SELECT OTHER_INDEX_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
+WHERE NAME='test/t1';
+
+--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:
+--echo # FLUSH TABLES t1 FOR EXPORT;
+--echo # UNLOCK TABLES;
+
+DROP TABLE t1;
+
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb/t/read_only_recover_committed.test b/mysql-test/suite/innodb/t/read_only_recover_committed.test
new file mode 100644
index 00000000000..c75b91d05db
--- /dev/null
+++ b/mysql-test/suite/innodb/t/read_only_recover_committed.test
@@ -0,0 +1,67 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+# need to restart server
+--source include/not_embedded.inc
+
+--connect(con1, localhost, root)
+CREATE TABLE t(a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t VALUES(1);
+BEGIN;
+# Generate insert_undo log.
+INSERT INTO t VALUES(2);
+# Generate update_undo log.
+DELETE FROM t WHERE a=2;
+--connect(con2, localhost, root)
+--echo # Normal MariaDB shutdown would roll back the above transaction.
+--echo # We want the transaction to remain open, so we will kill the server
+--echo # after ensuring that any non-transactional files are clean.
+FLUSH TABLES;
+--echo # Create another transaction that will be recovered as COMMITTED.
+BEGIN;
+# Generate multiple pages of both insert_undo and update_undo, so that
+# the state TRX_UNDO_CACHE will not be chosen.
+--disable_query_log
+let $n= 10000;
+while ($n) {
+dec $n;
+eval INSERT INTO t VALUES(-$n);
+eval DELETE FROM t WHERE a=-$n;
+}
+--enable_query_log
+SET DEBUG_SYNC='after_trx_committed_in_memory SIGNAL committed WAIT_FOR ever';
+send COMMIT;
+
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR committed';
+--echo # Ensure that the above incomplete transactions become durable.
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+BEGIN;
+INSERT INTO t VALUES(-10000);
+ROLLBACK;
+--let $restart_parameters= --innodb-force-recovery=3
+--let $shutdown_timeout= 0
+--source include/restart_mysqld.inc
+--let $shutdown_timeout= 30
+--disconnect con1
+--disconnect con2
+SELECT * FROM t;
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT * FROM t;
+# refused on MySQL 5.6, MariaDB 10.0, 10.1, but not MariaDB 10.2+
+UPDATE t SET a=3 WHERE a=1;
+--let $restart_parameters= --innodb-read-only
+--source include/restart_mysqld.inc
+--echo # Starting with MariaDB 10.2, innodb_read_only implies READ UNCOMMITTED.
+--echo # In earlier versions, this would return the last committed version
+--echo # (empty table)!
+SELECT * FROM t;
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT * FROM t;
+--let $restart_parameters=
+--source include/restart_mysqld.inc
+SELECT * FROM t;
+DROP TABLE t;
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
+--let SEARCH_PATTERN= Rolled back recovered transaction [^0]
+--source include/search_pattern_in_file.inc
diff --git a/mysql-test/suite/innodb/t/read_only_recovery.test b/mysql-test/suite/innodb/t/read_only_recovery.test
index aea676d3644..7da012efb74 100644
--- a/mysql-test/suite/innodb/t/read_only_recovery.test
+++ b/mysql-test/suite/innodb/t/read_only_recovery.test
@@ -41,3 +41,6 @@ SELECT * FROM t;
--source include/restart_mysqld.inc
SELECT * FROM t;
DROP TABLE t;
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
+--let SEARCH_PATTERN= Rolled back recovered transaction [^0]
+--source include/search_pattern_in_file.inc
diff --git a/mysql-test/suite/innodb/t/recovery_shutdown.test b/mysql-test/suite/innodb/t/recovery_shutdown.test
new file mode 100644
index 00000000000..d796189c724
--- /dev/null
+++ b/mysql-test/suite/innodb/t/recovery_shutdown.test
@@ -0,0 +1,64 @@
+--source include/have_innodb.inc
+--source include/not_embedded.inc
+
+# Flush any open myisam tables from previous tests
+FLUSH TABLES;
+
+--echo #
+--echo # MDEV-13797 InnoDB may hang if shutdown is initiated soon after startup
+--echo # while rolling back recovered incomplete transactions
+--echo #
+
+CREATE TABLE t (a INT) ENGINE=InnoDB;
+let $size = 100;
+let $trx = 8;
+let $c = $size;
+BEGIN;
+--disable_query_log
+while ($c) {
+INSERT INTO t VALUES();
+dec $c;
+}
+--enable_query_log
+COMMIT;
+
+let $c = $trx;
+while ($c)
+{
+connect (con$c,localhost,root,,);
+eval CREATE TABLE t$c (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+eval INSERT INTO t$c (a) SELECT NULL FROM t;
+eval UPDATE t$c SET a=a+$size, b=a;
+eval DELETE FROM t$c;
+dec $c;
+}
+
+INSERT INTO t1(a) SELECT NULL FROM t;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+
+--connection default
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+CREATE TABLE u(a SERIAL) ENGINE=INNODB;
+
+FLUSH TABLES;
+
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
+--let $shutdown_timeout=60
+--source include/restart_mysqld.inc
+
+--disable_query_log
+let $c = $trx;
+while ($c)
+{
+disconnect con$c;
+eval DROP TABLE t$c;
+dec $c;
+}
+--enable_query_log
+
+DROP TABLE t,u;
diff --git a/mysql-test/suite/innodb/t/rename_table_debug.test b/mysql-test/suite/innodb/t/rename_table_debug.test
new file mode 100644
index 00000000000..df4331cf8bb
--- /dev/null
+++ b/mysql-test/suite/innodb/t/rename_table_debug.test
@@ -0,0 +1,21 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+LET $datadir= `SELECT @@datadir`;
+
+CREATE TABLE t1 (a SERIAL, b INT, c INT, d INT) ENGINE=InnoDB;
+INSERT INTO t1 () VALUES ();
+
+--connect (con1,localhost,root,,test)
+SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever';
+--send
+RENAME TABLE t1 TO t2;
+--connection default
+SET DEBUG_SYNC='now WAIT_FOR renamed';
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
+--disconnect con1
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/restart.test b/mysql-test/suite/innodb/t/restart.test
new file mode 100644
index 00000000000..2fd7ca244e5
--- /dev/null
+++ b/mysql-test/suite/innodb/t/restart.test
@@ -0,0 +1,80 @@
+--source include/innodb_page_size.inc
+--source include/not_embedded.inc
+
+let datadir= `select @@datadir`;
+let page_size= `select @@innodb_page_size`;
+
+--echo #
+--echo # MDEV-15333 MariaDB (still) slow start
+--echo #
+
+# Ensure that on normal startup, no data files are read.
+# Note: just like in MySQL, all .ibd files will still be
+# opened at least once.
+
+--echo # FIXME: Unlike MySQL, maybe MariaDB should not read the .ibd files
+--echo # of tables with .isl file or DATA DIRECTORY attribute.
+call mtr.add_suppression("\\[ERROR\\] InnoDB: Invalid flags 0x7a207879 in .*td\\.ibd");
+--echo # FIXME: This is much more noisy than MariaDB 10.1!
+call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot read first page in datafile: .*td\\.ibd, Space ID:2048948345, Flags: 2048948345");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\.");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\.");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them\\.");
+call mtr.add_suppression("\\[Warning\\] InnoDB: Ignoring tablespace for `test`\\.`td` because it could not be opened\\.");
+
+CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT
+PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9;
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+eval CREATE TABLE td(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC
+STATS_PERSISTENT=0 DATA DIRECTORY='$MYSQL_TMP_DIR';
+
+--source include/shutdown_mysqld.inc
+
+--move_file $datadir/test/tr.ibd $datadir/test/tr0.ibd
+--move_file $datadir/test/tc.ibd $datadir/test/tc0.ibd
+--move_file $MYSQL_TMP_DIR/test/td.ibd $datadir/test/td0.ibd
+# TODO: test that MariaDB does not even attempt to open the files
+#--mkdir $datadir/test/tr.ibd
+#--mkdir $datadir/test/tc.ibd
+#--mkdir $MYSQL_TMP_DIR/test/td.ibd
+
+perl;
+die unless open OUT, ">", "$ENV{datadir}/test/tr.ibd";
+print OUT "foo " x $ENV{page_size};
+close OUT or die;
+die unless open OUT, ">", "$ENV{datadir}/test/tc.ibd";
+print OUT "bar " x $ENV{page_size};
+close OUT or die;
+die unless open OUT, ">", "$ENV{MYSQL_TMP_DIR}/test/td.ibd";
+print OUT "xyz " x $ENV{page_size};
+close OUT or die;
+EOF
+
+--let $restart_parameters= --skip-innodb-buffer-pool-load-at-startup
+--source include/start_mysqld.inc
+--let $restart_parameters=
+
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+
+--source include/shutdown_mysqld.inc
+
+# TODO: test that MariaDB does not even attempt to open the files
+#--rmdir $datadir/test/tr.ibd
+#--rmdir $datadir/test/tc.ibd
+#--rmdir $MYSQL_TMP_DIR/test/td.ibd
+--remove_file $datadir/test/tr.ibd
+--remove_file $datadir/test/tc.ibd
+--remove_file $MYSQL_TMP_DIR/test/td.ibd
+
+--move_file $datadir/test/tr0.ibd $datadir/test/tr.ibd
+--move_file $datadir/test/tc0.ibd $datadir/test/tc.ibd
+--move_file $datadir/test/td0.ibd $MYSQL_TMP_DIR/test/td.ibd
+
+--source include/start_mysqld.inc
+SELECT * FROM tr;
+SELECT * FROM tc;
+SELECT * FROM td;
+DROP TABLE tr,tc,td;
diff --git a/mysql-test/suite/innodb/t/row_format_redundant.test b/mysql-test/suite/innodb/t/row_format_redundant.test
index af3fe3b52cf..81541fb0582 100644
--- a/mysql-test/suite/innodb/t/row_format_redundant.test
+++ b/mysql-test/suite/innodb/t/row_format_redundant.test
@@ -4,7 +4,7 @@
--disable_query_log
call mtr.add_suppression("InnoDB: Table `mysql`\\.`innodb_table_stats` not found");
-call mtr.add_suppression("InnoDB: Table `test`.`t1` in InnoDB data dictionary contains invalid flags. SYS_TABLES\\.TYPE=1 SYS_TABLES\\.MIX_LEN=255\\r?$");
+call mtr.add_suppression("InnoDB: Table `test`.`t1` in InnoDB data dictionary contains invalid flags. SYS_TABLES\\.TYPE=1 SYS_TABLES\\.MIX_LEN=511\\r?$");
call mtr.add_suppression("InnoDB: Parent table of FTS auxiliary table test/FTS_.* not found");
call mtr.add_suppression("InnoDB: Cannot open table test/t1 from the internal data dictionary");
call mtr.add_suppression("InnoDB: Table `test`.`t1` does not exist in the InnoDB internal data dictionary though MariaDB is trying to (rename|drop)");
@@ -115,7 +115,7 @@ for (my $offset= 0x65; $offset;
if ($i == 7 && $name =~ '^test/t[123]')
{
print "corrupted SYS_TABLES.MIX_LEN for $name\n";
- substr($page,$offset+$start,$end-$start)= pack("N", 255);
+ substr($page,$offset+$start,$end-$start)= pack("N", 511);
}
$start= $end & 0x7f;
}
@@ -141,7 +141,7 @@ RENAME TABLE t1 TO tee_one;
DROP TABLE t1;
DROP TABLE t2,t3;
---let SEARCH_PATTERN= \[ERROR\] InnoDB: Table `test`\.`t1` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=255\b
+--let SEARCH_PATTERN= \[ERROR\] InnoDB: Table `test`\.`t1` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b
--source include/search_pattern_in_file.inc
--let $restart_parameters=
diff --git a/mysql-test/suite/innodb/t/table_definition_cache_debug.opt b/mysql-test/suite/innodb/t/table_definition_cache_debug.opt
index 6195e055dc8..c2db7e1df6e 100644
--- a/mysql-test/suite/innodb/t/table_definition_cache_debug.opt
+++ b/mysql-test/suite/innodb/t/table_definition_cache_debug.opt
@@ -1 +1 @@
---innodb-open-files=13
+--innodb-open-files=30
diff --git a/mysql-test/suite/innodb/t/table_flags.test b/mysql-test/suite/innodb/t/table_flags.test
index 2c0b55bcaae..2d2a32e9547 100644
--- a/mysql-test/suite/innodb/t/table_flags.test
+++ b/mysql-test/suite/innodb/t/table_flags.test
@@ -14,6 +14,7 @@ call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`.`td` because it
call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation");
call mtr.add_suppression("InnoDB: The error means the system cannot find the path specified");
call mtr.add_suppression("InnoDB: If you are installing InnoDB, remember that you must create directories yourself");
+call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS of tablespace");
FLUSH TABLES;
--enable_query_log
@@ -136,7 +137,9 @@ SHOW CREATE TABLE tr;
--error ER_NO_SUCH_TABLE_IN_ENGINE
SHOW CREATE TABLE tc;
--error ER_NO_SUCH_TABLE_IN_ENGINE
+SELECT * FROM tc;
SHOW CREATE TABLE td;
+SELECT * FROM td;
# This table was converted to NO_ROLLBACK due to the SYS_TABLES.TYPE change.
SHOW CREATE TABLE tz;
BEGIN;
@@ -151,8 +154,6 @@ SHOW CREATE TABLE tp;
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
--let SEARCH_PATTERN= InnoDB: Table `test`.`t[cp]` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649
--source include/search_pattern_in_file.inc
---let SEARCH_PATTERN= InnoDB: Refusing to load '\..test.td\.ibd' \(id=3, flags=0x1?[2ae]1\); dictionary contains id=3, flags=0x10[01][2ae]1\b
---source include/search_pattern_in_file.inc
--let SEARCH_PATTERN= InnoDB: Table `test`\.`tr` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b
--source include/search_pattern_in_file.inc
diff --git a/mysql-test/suite/innodb/t/truncate_inject.test b/mysql-test/suite/innodb/t/truncate_inject.test
new file mode 100644
index 00000000000..35e516324bb
--- /dev/null
+++ b/mysql-test/suite/innodb/t/truncate_inject.test
@@ -0,0 +1,97 @@
+# This test is based on innodb_zip.wl6501_error_1 in MySQL 5.7.
+
+--source include/have_innodb.inc
+--source include/innodb_row_format.inc
+--source include/have_debug.inc
+
+SET @save_dbug = @@SESSION.debug_dbug;
+
+call mtr.add_suppression("InnoDB: Flagged corruption of .* in table `test`\\.`t` in TRUNCATE TABLE");
+
+--echo # 1. Error in assigning undo logs for truncate action
+CREATE TABLE t (i int PRIMARY KEY, f float UNIQUE, c char(100), INDEX ck(c))
+ENGINE = InnoDB;
+insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
+check table t;
+#
+SET debug_dbug = '+d,ib_err_trunc_assigning_undo_log';
+--error ER_GET_ERRNO
+truncate table t;
+SET debug_dbug = @save_dbug;
+check table t;
+select * from t;
+
+--echo # 2. Error while preparing for truncate
+SET debug_dbug = '+d,ib_err_trunc_preparing_for_truncate';
+--error ER_GET_ERRNO
+truncate table t;
+SET debug_dbug = @save_dbug;
+check table t;
+select * from t;
+
+--echo # 3. Error while dropping/creating indexes
+SET debug_dbug = '+d,ib_err_trunc_drop_index';
+--error ER_GET_ERRNO
+truncate table t;
+SET debug_dbug = @save_dbug;
+check table t;
+--error ER_TABLE_CORRUPT,ER_GET_ERRNO
+select * from t;
+drop table t;
+
+CREATE TABLE t (i int PRIMARY KEY, f float UNIQUE, c char(100), INDEX ck(c))
+ENGINE = InnoDB;
+insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
+check table t;
+
+SET debug_dbug = '+d,ib_err_trunc_create_index';
+--error ER_GET_ERRNO
+truncate table t;
+SET debug_dbug = @save_dbug;
+check table t;
+--error ER_TABLE_CORRUPT,ER_GET_ERRNO
+select * from t;
+drop table t;
+
+CREATE TABLE t (i int PRIMARY KEY, f float UNIQUE, c char(100), INDEX ck(c))
+ENGINE = InnoDB;
+insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
+check table t;
+
+SET debug_dbug = '+d,ib_err_trunc_temp_recreate_index';
+truncate table t;
+SET debug_dbug = @save_dbug;
+
+check table t;
+select * from t;
+drop table t;
+
+--echo # 4. Error while completing truncate of table involving FTS
+CREATE TABLE t (i int PRIMARY KEY, f float UNIQUE, c char(100),
+FULLTEXT INDEX(c)) ENGINE = InnoDB;
+insert into t values (1, 1.1, 'mysql is now oracle company'),
+ (2, 2.2, 'innodb is part of mysql'),
+ (3, 3.3, 'innodb is default storage engine of mysql');
+check table t;
+SET debug_dbug = '+d,ib_err_trunc_temp_recreate_index';
+truncate table t;
+SET debug_dbug = @save_dbug;
+
+check table t;
+select * from t;
+drop table t;
+
+--echo # 5. Error while updating sys-tables
+CREATE TABLE t (i int PRIMARY KEY, f float UNIQUE, c char(100),
+FULLTEXT INDEX(c)) ENGINE = InnoDB;
+insert into t values (1, 1.1, 'mysql is now oracle company'),
+ (2, 2.2, 'innodb is part of mysql'),
+ (3, 3.3, 'innodb is default storage engine of mysql');
+check table t;
+SET debug_dbug = '+d,ib_err_trunc_temp_recreate_index';
+truncate table t;
+SET debug_dbug = @save_dbug;
+
+check table t;
+select * from t order by i;
+drop table t;
diff --git a/mysql-test/suite/innodb/t/truncate_restart.test b/mysql-test/suite/innodb/t/truncate_restart.test
new file mode 100644
index 00000000000..60a3d83cd81
--- /dev/null
+++ b/mysql-test/suite/innodb/t/truncate_restart.test
@@ -0,0 +1,16 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+SET GLOBAL innodb_stats_persistent= ON;
+CREATE TABLE t1 (t TEXT) ENGINE=InnoDB STATS_PERSISTENT=1;
+--connect (con1,localhost,root,,test)
+SET DEBUG_SYNC='ib_trunc_table_trunc_completing SIGNAL committed WAIT_FOR ever';
+--send
+TRUNCATE TABLE t1;
+--connection default
+SET DEBUG_SYNC='now WAIT_FOR committed';
+--source include/restart_mysqld.inc
+--disconnect con1
+SELECT COUNT(*) FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/update-cascade.test b/mysql-test/suite/innodb/t/update-cascade.test
new file mode 100644
index 00000000000..de8294703b4
--- /dev/null
+++ b/mysql-test/suite/innodb/t/update-cascade.test
@@ -0,0 +1,221 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+# Save the initial number of concurrent sessions
+--source include/count_sessions.inc
+
+--echo #
+--echo # Bug #18451287 REDUNDANT DELETE MARKING AFTER DB_LOCK_WAIT
+--echo #
+
+create table t1 (f1 int primary key, f2 blob) engine=innodb;
+create table t2 (f1 int primary key, f2 int,
+ foreign key (f2) references t1(f1) on update cascade) engine=innodb;
+
+show create table t1;
+show create table t2;
+insert into t1 values (1, repeat('+', 20000));
+insert into t1 values (2, repeat('-', 20000));
+insert into t1 values (3, repeat('=', 20000));
+insert into t2 values (1, 2);
+
+select f1, right(f2, 20) as p2 from t1;
+select f1, f2 from t2;
+
+connect(con1,localhost,root,,test);
+start transaction;
+select f1, f2 from t2 for update;
+
+connection default;
+set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
+send update t1 set f1 = 10 where f1 = 2;
+
+connection con1;
+set debug_sync='now WAIT_FOR upd_waiting';
+rollback;
+set debug_sync='now SIGNAL go_upd';
+
+connection default;
+--echo # reap: update t1 set f1 = 10 where f1 = 2;
+reap;
+
+select f1, right(f2, 20) as p2 from t1;
+select f1, f2 from t2;
+
+drop table t2, t1;
+
+set debug_sync = reset;
+
+--echo #
+--echo # Test Scenario: Two tables t1 -> t2 are involved in update cascade.
+--echo # If DB_LOCK_WAIT happens when t1 is being updated and FK constraints
+--echo # are being checked in t2, then retry must happen on t1. The update
+--echo # cascade happens in secondary index. For secondary index testing,
+--echo # blobs are not needed.
+--echo #
+
+create table t1 (f1 int primary key, f2 int, key k1(f2)) engine=innodb;
+create table t2 (f1 int primary key, f2 int,
+ foreign key (f2) references t1(f2) on update cascade) engine=innodb;
+
+show create table t1;
+show create table t2;
+insert into t1 values (1, 91);
+insert into t2 values (1, 91);
+
+select f1, f2 from t1;
+select f1, f2 from t2;
+
+connection con1;
+start transaction;
+select f1, f2 from t2 for update;
+
+connection default;
+set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
+send update t1 set f2 = 28 where f2 = 91;
+
+connection con1;
+set debug_sync='now WAIT_FOR upd_waiting';
+rollback;
+set debug_sync='now SIGNAL go_upd';
+
+connection default;
+--echo # reap: update t1 set f1 = 10 where f1 = 2;
+--reap
+
+select f1, f2 from t1;
+select f1, f2 from t2;
+
+drop table t2, t1;
+
+set debug_sync = reset;
+
+--echo #
+--echo # Test Scenario: Three tables t1 -> t2 -> t3 are involved in update cascade.
+--echo # If DB_LOCK_WAIT happens when t2 is being updated, then retry must happen
+--echo # on t2.
+--echo #
+
+create table t1 (f1 int primary key, f2 blob) engine=innodb;
+create table t2 (f1 int primary key, f2 blob,
+ foreign key (f1) references t1(f1) on update cascade) engine=innodb;
+create table t3 (f1 int primary key, f2 blob,
+ foreign key (f1) references t2(f1) on update cascade) engine=innodb;
+
+show create table t1;
+show create table t2;
+show create table t3;
+
+insert into t1 values (2, repeat('-', 20000));
+insert into t2 values (2, repeat('%', 20000));
+insert into t3 values (2, repeat('+', 20000));
+
+select f1, right(f2, 20) as p2 from t1;
+select f1, right(f2, 20) as p2 from t2;
+select f1, right(f2, 20) as p2 from t3;
+
+connection con1;
+start transaction;
+select f1 from t3 for update;
+
+connection default;
+set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
+send update t1 set f1 = 10 where f1 = 2;
+
+connection con1;
+set debug_sync='now WAIT_FOR upd_waiting';
+rollback;
+
+--echo # The table t1 is updated.
+--echo # In t2 delete-mark happened. Retry will happen on t2.
+--echo # In t3 yet to be updated.
+set session transaction isolation level read uncommitted;
+start transaction;
+select f1, right(f2, 20) as p2 from t1;
+select f1, right(f2, 20) as p2 from t2;
+select f1, right(f2, 20) as p2 from t3;
+commit;
+
+set debug_sync='now SIGNAL go_upd';
+
+connection default;
+--echo # reap: update t1 set f1 = 10 where f1 = 2;
+--reap;
+
+start transaction;
+select f1, right(f2, 20) as p2 from t1;
+select f1, right(f2, 20) as p2 from t2;
+select f1, right(f2, 20) as p2 from t3;
+commit;
+
+drop table t3, t2, t1;
+
+set debug_sync = reset;
+
+--echo #
+--echo # Test Scenario: Three tables t1 -> t2 -> t3 are involved in update
+--echo # cascade. If DB_LOCK_WAIT happens when t2 is being updated, then
+--echo # retry must happen on t2. The update cascade is happening via
+--echo # secondary index (hence blobs are not needed).
+--echo #
+
+create table t1 (f1 int primary key, f2 int, key k1(f2)) engine=innodb;
+create table t2 (f1 int primary key, f2 int,
+ foreign key (f2) references t1(f2) on update cascade) engine=innodb;
+create table t3 (f1 int primary key, f2 int,
+ foreign key (f2) references t2(f2) on update cascade) engine=innodb;
+
+show create table t1;
+show create table t2;
+show create table t3;
+
+insert into t1 values (2, 91);
+insert into t2 values (2, 91);
+insert into t3 values (2, 91);
+
+select f1, f2 from t1;
+select f1, f2 from t2;
+select f1, f2 from t3;
+
+connection con1;
+start transaction;
+select f1 from t3 for update;
+
+connection default;
+set debug_sync='lock_wait_suspend_thread_enter SIGNAL upd_waiting WAIT_FOR go_upd';
+send update t1 set f2 = 28 where f2 = 91;
+
+connection con1;
+set debug_sync='now WAIT_FOR upd_waiting';
+rollback;
+
+--echo # The table t1 is updated.
+--echo # In t2 delete-mark happened. Retry will happen on t2.
+--echo # In t3 yet to be updated.
+set session transaction isolation level read uncommitted;
+start transaction;
+select f1, f2 from t1;
+select f1, f2 from t2;
+select f1, f2 from t3;
+commit;
+
+set debug_sync='now SIGNAL go_upd';
+disconnect con1;
+
+connection default;
+--echo # reap: update t1 set f2 = 28 where f2 = 91;
+--reap;
+
+start transaction;
+select f1, f2 from t1;
+select f1, f2 from t2;
+select f1, f2 from t3;
+commit;
+
+drop table t3, t2, t1;
+
+set debug_sync = reset;
+
+# Wait till all disconnects are completed
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/update_time-master.opt b/mysql-test/suite/innodb/t/update_time-master.opt
new file mode 100644
index 00000000000..9f283a9503f
--- /dev/null
+++ b/mysql-test/suite/innodb/t/update_time-master.opt
@@ -0,0 +1 @@
+--innodb-buffer-pool-size=10M
diff --git a/mysql-test/suite/innodb/t/update_time.test b/mysql-test/suite/innodb/t/update_time.test
new file mode 100644
index 00000000000..1a00e3b9f73
--- /dev/null
+++ b/mysql-test/suite/innodb/t/update_time.test
@@ -0,0 +1,79 @@
+###################################################################
+-- echo #
+-- echo # Test that INFORMATION_SCHEMA.TABLES.UPDATE_TIME is filled
+-- echo # correctly for InnoDB tables.
+-- echo #
+
+-- source include/have_innodb.inc
+-- source include/have_innodb_max_16k.inc
+# restart does not work with embedded
+-- source include/not_embedded.inc
+
+CREATE TABLE t (a INT) ENGINE=INNODB;
+
+SELECT update_time FROM information_schema.tables WHERE table_name = 't';
+
+INSERT INTO t VALUES (1);
+
+SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 't'
+AND update_time IS NOT NULL;
+
+-- echo # We cant deterministically check that the saved value is correct, but
+-- echo # at least we check that it is a timestamp not older than 2 minutes.
+-- echo # Usually update_time and NOW() are equal below, but on heavily loaded
+-- echo # machines NOW() could be younger.
+SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 't'
+AND TIMESTAMPDIFF(SECOND, update_time, NOW()) < 120;
+
+CREATE TEMPORARY TABLE big (a TEXT) ENGINE=INNODB;
+
+SELECT COUNT(*) FROM information_schema.innodb_buffer_page
+WHERE table_name = '`test`.`t`';
+
+# evict table 't' by inserting as much data as the BP size itself
+-- echo # INSERT lots of data in table 'big': begin
+-- disable_query_log
+BEGIN;
+-- let $i = 10240
+while ($i)
+{
+ INSERT INTO big VALUES (REPEAT('a', 1024));
+ dec $i;
+}
+COMMIT;
+-- enable_query_log
+-- echo # INSERT lots of data in table 'big': end
+
+# confirm that all pages for table 't' have been evicted
+SELECT COUNT(*) FROM information_schema.innodb_buffer_page
+WHERE table_name = '`test`.`t`';
+
+# The result from this query will change once update_time becomes persistent
+# (WL#6917).
+SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 't'
+AND update_time IS NOT NULL;
+
+DROP TEMPORARY TABLE big;
+
+-- echo # Test the behavior after restart with a prepared XA transaction
+
+XA START 'xatrx';
+INSERT INTO t VALUES (5);
+XA END 'xatrx';
+XA PREPARE 'xatrx';
+
+CONNECT (con1,localhost,root,,);
+
+call mtr.add_suppression("Found 1 prepared XA transactions");
+FLUSH TABLES;
+
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
+
+SELECT update_time FROM information_schema.tables WHERE table_name = 't';
+
+XA COMMIT 'xatrx';
+
+SELECT COUNT(update_time) FROM information_schema.tables WHERE table_name='t';
+
+DROP TABLE t;
diff --git a/mysql-test/suite/innodb/t/update_time_wl6658.test b/mysql-test/suite/innodb/t/update_time_wl6658.test
new file mode 100644
index 00000000000..0adc6a867fe
--- /dev/null
+++ b/mysql-test/suite/innodb/t/update_time_wl6658.test
@@ -0,0 +1,232 @@
+###################################################################
+#Testing functionality of the WL6658
+#case1: begin work with INSERT with Triggers
+#case2: (tab1u) begin transaction with UPDATE
+#case3: (tab1d) begin transaction with DELETE
+#case4: (tab1i) Rollback & INSERT
+#case5: (tab2) partitioned table and procedures
+#case6: (tab2) SAVEPOINT
+#case7: (tab7,tab8) pk-fk with ON DELETE CASCADE
+###################################################################
+--source include/no_valgrind_without_big.inc
+--source include/have_innodb.inc
+--source include/have_partition.inc
+--source include/not_embedded.inc
+
+CREATE TABLE tab1(c1 int,c2 varchar(30), c3 BLOB) ENGINE=InnoDB;
+CREATE TABLE tab1u LIKE tab1;
+CREATE TABLE tab1d LIKE tab1;
+CREATE TABLE tab1i LIKE tab1;
+CREATE TABLE tab3(c1 int,c2 varchar(30)) ENGINE=InnoDB;
+CREATE TABLE tab4(c1 int,c2 varchar(30)) ENGINE=InnoDB;
+CREATE TABLE tab5(c1 int,c2 varchar(30)) ENGINE=InnoDB;
+
+INSERT INTO tab1u VALUES(1,'Testing the wl6658','Testing the wl6658');
+INSERT INTO tab1d VALUES(1,'Updated','Updated');
+INSERT INTO tab4 VALUES(1,'Test for Update');
+INSERT INTO tab5 VALUES(1,'Test for Delete');
+
+delimiter |;
+
+CREATE TRIGGER test_trig BEFORE INSERT ON tab1
+FOR EACH ROW BEGIN
+ INSERT INTO tab3 VALUES(1,'Inserted From Trigger');
+ UPDATE tab4 SET c2='Updated from Trigger' WHERE c1=1;
+ DELETE FROM tab5;
+END |
+
+delimiter ;|
+
+CREATE TABLE tab2(
+ id INT NOT NULL,
+ store_name VARCHAR(30),
+ parts VARCHAR(30),
+ store_id INT
+) ENGINE=InnoDB
+PARTITION BY LIST(store_id) (
+ PARTITION pNorth VALUES IN (10,20,30),
+ PARTITION pEast VALUES IN (40,50,60),
+ PARTITION pWest VALUES IN (70,80,100)
+);
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab2';
+
+delimiter |;
+
+CREATE PROCEDURE proc_wl6658()
+BEGIN
+INSERT INTO tab2 VALUES(1,'ORACLE','NUTT',10);
+INSERT INTO tab2 VALUES(2,'HUAWEI','BOLT',40);
+COMMIT;
+END |
+
+delimiter ;|
+
+CALL proc_wl6658;
+
+SELECT * FROM tab2 ORDER BY id,store_id;
+
+SELECT COUNT(update_time)
+FROM information_schema.tables WHERE table_name='tab2';
+
+TRUNCATE TABLE tab2;
+
+SELECT COUNT(update_time)
+FROM information_schema.tables WHERE table_name='tab2';
+
+CREATE TABLE tab7(c1 INT NOT NULL, PRIMARY KEY (c1)) ENGINE=INNODB;
+
+CREATE TABLE tab8(c1 INT PRIMARY KEY,c2 INT,
+FOREIGN KEY (c2) REFERENCES tab7(c1) ON DELETE CASCADE )
+ENGINE=INNODB;
+
+SELECT table_name,update_time
+FROM information_schema.tables WHERE table_name IN ('tab7','tab8')
+GROUP BY table_name ORDER BY table_name;
+
+INSERT INTO tab7 VALUES(1);
+
+INSERT INTO tab8 VALUES(1,1);
+
+SELECT table_name,COUNT(update_time)
+FROM information_schema.tables WHERE table_name IN ('tab7','tab8')
+GROUP BY table_name ORDER BY table_name;
+
+--echo #restart the server
+--source include/restart_mysqld.inc
+
+SELECT table_name,update_time
+FROM information_schema.tables
+WHERE table_name IN ('tab1','tab2','tab3','tab4','tab5','tab7','tab8')
+ORDER BY table_name;
+
+--echo #case1:
+
+BEGIN WORK;
+
+INSERT INTO tab1
+VALUES(1,'Testing the wl6658', 'Testing the wl6658');
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1';
+
+COMMIT;
+
+SELECT * FROM tab1;
+SELECT * FROM tab3;
+SELECT * FROM tab4;
+SELECT * FROM tab5;
+
+SELECT table_name,COUNT(update_time)
+FROM information_schema.tables
+WHERE table_name IN ('tab1','tab3','tab4','tab5')
+GROUP BY table_name ORDER BY table_name;
+
+--echo Testcase with UPDATE stmt and transaction
+
+SELECT * FROM tab1u;
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1u';
+
+--echo #case2:
+START TRANSACTION;
+
+UPDATE tab1u SET c2='Updated',c3='Updated' WHERE c1=1;
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1u';
+
+COMMIT;
+
+SELECT * FROM tab1u;
+
+SELECT COUNT(update_time)
+FROM information_schema.tables WHERE table_name='tab1u';
+
+SELECT * FROM tab1d;
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1d';
+
+--echo #case3:
+START TRANSACTION;
+
+DELETE FROM tab1d;
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1d';
+
+COMMIT;
+
+SELECT * FROM tab1d;
+
+SELECT COUNT(update_time)
+FROM information_schema.tables WHERE table_name='tab1d';
+
+SELECT * FROM tab1i;
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1i';
+
+--echo #case4:
+START TRANSACTION;
+
+INSERT INTO tab1i
+VALUES(1,'Testing the wl6658', 'Testing the wl6658');
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1i';
+
+ROLLBACK;
+
+SELECT * FROM tab1i;
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab1i';
+
+BEGIN WORK;
+DELETE FROM tab1i;
+SAVEPOINT A;
+INSERT INTO tab2 VALUES(1,'Oracle','NUTT',10);
+INSERT INTO tab2 VALUES(2,'HUAWEI','BOLT',40);
+SAVEPOINT B;
+INSERT INTO tab2 VALUES(3,'IBM','NAIL',70);
+SAVEPOINT C;
+ROLLBACK to A;
+
+SELECT * FROM tab2;
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab2';
+
+--echo #execute DDL instead of commit
+create table tab6(c1 int);
+
+SELECT update_time
+FROM information_schema.tables WHERE table_name='tab2';
+
+START TRANSACTION;
+DELETE FROM tab7;
+ROLLBACK;
+
+SELECT * FROM tab7;
+SELECT * FROM tab8;
+
+SELECT table_name,update_time
+FROM information_schema.tables WHERE table_name IN ('tab7','tab8')
+GROUP BY table_name ORDER BY table_name;
+
+DELETE FROM tab7;
+SELECT * FROM tab7;
+SELECT * FROM tab8;
+
+SELECT table_name,COUNT(update_time)
+FROM information_schema.tables WHERE table_name IN ('tab7','tab8')
+GROUP BY table_name ORDER BY table_name;
+
+--echo #cleanup
+DROP TRIGGER test_trig;
+DROP TABLE tab1,tab1u,tab1d,tab1i,tab2,tab3,tab4,tab5,tab6,tab8,tab7;
+DROP PROCEDURE proc_wl6658;
diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result
index 42e294b3293..fcf196a0631 100644
--- a/mysql-test/suite/innodb_fts/r/fulltext.result
+++ b/mysql-test/suite/innodb_fts/r/fulltext.result
@@ -56,7 +56,7 @@ Only MyISAM tables support collections
MySQL has now support for full-text search
Full-text search in MySQL implements vector space model
select * from t1 where MATCH(a,b) AGAINST ("indexes" IN BOOLEAN MODE WITH QUERY EXPANSION);
-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 'QUERY EXPANSION)' at line 1
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'WITH QUERY EXPANSION)' at line 1
explain select * from t1 where MATCH(a,b) AGAINST ("collections");
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 fulltext a a 0 1 Using where
diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
index 983f254cf90..cd7d8f03923 100644
--- a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
+++ b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
@@ -162,11 +162,15 @@ INSERT INTO articles (FTS_DOC_ID, title, body) VALUES
(14,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
(19, 'MySQL vs. YourSQL','In the following database comparison ...'),
(20, 'MySQL Security','When configured properly, MySQL ...');
-ALTER TABLE articles ADD FULLTEXT INDEX idx3 (title),
-ADD FULLTEXT INDEX idx5 (title);
-ERROR HY000: InnoDB presently supports one FULLTEXT index creation at a time
-CREATE FULLTEXT INDEX idx on articles (title);
-ALTER TABLE articles ADD FULLTEXT INDEX idx3 (title);
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title),
+ADD FULLTEXT INDEX idx3 (title), ALGORITHM=INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try ALGORITHM=COPY
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title),
+ADD FULLTEXT INDEX idx3 (title);
+affected rows: 6
+info: Records: 6 Duplicates: 0 Warnings: 1
+Warnings:
+Note 1831 Duplicate index `idx3`. This is deprecated and will be disallowed in a future release
ALTER TABLE articles ADD INDEX t20 (title(20)), LOCK=NONE;
ALTER TABLE articles DROP INDEX t20;
INSERT INTO articles (FTS_DOC_ID, title, body) VALUES
diff --git a/mysql-test/suite/innodb_fts/r/misc_debug.result b/mysql-test/suite/innodb_fts/r/misc_debug.result
index 1fcc89b165b..3a156049fe2 100644
--- a/mysql-test/suite/innodb_fts/r/misc_debug.result
+++ b/mysql-test/suite/innodb_fts/r/misc_debug.result
@@ -7,7 +7,7 @@ FULLTEXT (title,body)
SET @saved_debug_dbug = @@SESSION.debug_dbug;
SET SESSION debug_dbug="+d,ib_dict_create_index_tree_fail";
CREATE FULLTEXT INDEX idx ON articles(body);
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
SET SESSION debug_dbug=@saved_debug_dbug;
ALTER TABLE articles STATS_PERSISTENT=DEFAULT;
DROP TABLE articles;
diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
index 10dc1462c98..23065a97002 100644
--- a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
+++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
@@ -195,12 +195,13 @@ INSERT INTO articles (FTS_DOC_ID, title, body) VALUES
(19, 'MySQL vs. YourSQL','In the following database comparison ...'),
(20, 'MySQL Security','When configured properly, MySQL ...');
---error ER_INNODB_FT_LIMIT
-ALTER TABLE articles ADD FULLTEXT INDEX idx3 (title),
- ADD FULLTEXT INDEX idx5 (title);
-
-CREATE FULLTEXT INDEX idx on articles (title);
-ALTER TABLE articles ADD FULLTEXT INDEX idx3 (title);
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title),
+ ADD FULLTEXT INDEX idx3 (title), ALGORITHM=INPLACE;
+--enable_info
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title),
+ ADD FULLTEXT INDEX idx3 (title);
+--disable_info
ALTER TABLE articles ADD INDEX t20 (title(20)), LOCK=NONE;
ALTER TABLE articles DROP INDEX t20;
diff --git a/mysql-test/suite/innodb_gis/disabled.def b/mysql-test/suite/innodb_gis/disabled.def
index 4ffc0607a90..e486a70a0c6 100644
--- a/mysql-test/suite/innodb_gis/disabled.def
+++ b/mysql-test/suite/innodb_gis/disabled.def
@@ -11,16 +11,8 @@
##############################################################################
gis_split_inf : MDEV-14057 InnoDB GIS tests fail
-row_format : MDEV-14057 InnoDB GIS tests fail
-rtree_estimate : MDEV-14057 InnoDB GIS tests fail
rtree_multi_pk : MDEV-14057 InnoDB GIS tests fail
-rtree_recovery : MDEV-14058 InnoDB Assertion failure !leaf on rem0rec.cc line 566 on test innodb_gis.rtree_recovery
-tree_search : MDEV-14057 InnoDB GIS tests fail
-rtree_concurrent_srch: MDEV-14059 InnoDB assertion failure offset >= ((38U + 36 + 2 * 10) + 5) at page0page.h line 318
point_big : MDEV-14057 InnoDB GIS tests fail
geometry : MDEV-14057 InnoDB GIS tests fail
-bug17057168 : MDEV-14057 InnoDB GIS tests fail
bug16236208 : MDEV-14057 InnoDB GIS tests fail
bug16266012 : MDEV-14057 InnoDB GIS tests fail
-rtree_search : MDEV-14057 InnoDB GIS tests fail
-rtree_old : MDEV-14057 InnoDB GIS tests fail
diff --git a/mysql-test/suite/innodb_gis/r/bug17057168.result b/mysql-test/suite/innodb_gis/r/bug17057168.result
index 885989f12e3..0002acaf8a1 100644
--- a/mysql-test/suite/innodb_gis/r/bug17057168.result
+++ b/mysql-test/suite/innodb_gis/r/bug17057168.result
@@ -12,10 +12,8 @@ INSERT INTO t1 (location) SELECT POINT(tmp1.id, tmp2.id) FROM tmp tmp1,
tmp tmp2 ORDER BY tmp1.id, tmp2.id;
EXPLAIN SELECT id, ST_AsText(location) FROM t1 WHERE location = POINT(1,
2);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL ref location location 28 const 1 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select `geotest`.`t1`.`id` AS `id`,st_astext(`geotest`.`t1`.`location`) AS `ST_AsText(location)` from `geotest`.`t1` where (`geotest`.`t1`.`location` = <cache>(point(1,2)))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref location location 28 const 1 Using where
SELECT id, ST_AsText(location) FROM t1 WHERE location = POINT(1, 2);
id ST_AsText(location)
163 POINT(1 2)
diff --git a/mysql-test/suite/innodb_gis/r/geometry.result b/mysql-test/suite/innodb_gis/r/geometry.result
index 60c5f80f69b..780efc11bce 100644
--- a/mysql-test/suite/innodb_gis/r/geometry.result
+++ b/mysql-test/suite/innodb_gis/r/geometry.result
@@ -1,21 +1,5 @@
SET default_storage_engine=InnoDB;
SET innodb_strict_mode=OFF;
-SET SESSION debug="+d,row_print_geometry_data";
-SHOW VARIABLES LIKE '%engine%';
-Variable_name Value
-default_storage_engine InnoDB
-default_tmp_storage_engine InnoDB
-disabled_storage_engines
-internal_tmp_disk_storage_engine InnoDB
-USE test;
-DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon;
-DROP TABLE IF EXISTS gis_multi_point, gis_multi_line, gis_multi_polygon;
-DROP TABLE IF EXISTS gis_geometrycollection, gis_geometry;
-DROP TABLE IF EXISTS tab,tab2,tab3,parent,emp2;
-DROP PROCEDURE IF EXISTS geominout;
-DROP PROCEDURE IF EXISTS geom_insert;
-DROP TRIGGER IF EXISTS geom_trigger;
-DROP PROCEDURE IF EXISTS geom_cursor;
CREATE TABLE gis_point (fid INTEGER NOT NULL PRIMARY KEY, g POINT) ENGINE=InnoDB;
CREATE TABLE gis_line (fid INTEGER NOT NULL PRIMARY KEY, g LINESTRING) ENGINE=InnoDB;
CREATE TABLE gis_polygon (fid INTEGER NOT NULL PRIMARY KEY, g POLYGON) ENGINE=InnoDB;
@@ -1136,15 +1120,10 @@ COMMIT;
SELECT COUNT(*) FROM tab3;
COUNT(*)
0
-DROP TABLE IF EXISTS gis_point, gis_line, gis_polygon, gis_multi_point;
-DROP TABLE IF EXISTS gis_multi_line, gis_multi_polygon;
-DROP TABLE IF EXISTS gis_geometrycollection, gis_geometry;
-DROP TABLE IF EXISTS tab,tab2,tab3,parent,emp2;
-Warnings:
-Note 1051 Unknown table 'test.emp2'
-DROP PROCEDURE IF EXISTS geominout;
-DROP PROCEDURE IF EXISTS geom_insert;
-DROP TRIGGER IF EXISTS geom_trigger;
-Warnings:
-Note 1360 Trigger does not exist
-DROP PROCEDURE IF EXISTS geom_cursor;
+DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point;
+DROP TABLE gis_multi_line, gis_multi_polygon;
+DROP TABLE gis_geometrycollection, gis_geometry;
+DROP TABLE tab,tab2,tab3,parent;
+DROP PROCEDURE geominout;
+DROP PROCEDURE geom_insert;
+DROP PROCEDURE geom_cursor;
diff --git a/mysql-test/suite/innodb_gis/r/innodb_gis_rtree.result b/mysql-test/suite/innodb_gis/r/innodb_gis_rtree.result
new file mode 100644
index 00000000000..5d4708dd111
--- /dev/null
+++ b/mysql-test/suite/innodb_gis/r/innodb_gis_rtree.result
@@ -0,0 +1,1630 @@
+CREATE TABLE t1 (
+fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+g GEOMETRY NOT NULL,
+SPATIAL KEY(g)
+);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `fid` int(11) NOT NULL AUTO_INCREMENT,
+ `g` geometry NOT NULL,
+ PRIMARY KEY (`fid`),
+ SPATIAL KEY `g` (`g`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(150 150, 150 150)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(149 149, 151 151)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(148 148, 152 152)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(147 147, 153 153)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(146 146, 154 154)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(145 145, 155 155)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(144 144, 156 156)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(143 143, 157 157)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(142 142, 158 158)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(141 141, 159 159)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(140 140, 160 160)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(139 139, 161 161)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(138 138, 162 162)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(137 137, 163 163)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(136 136, 164 164)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(135 135, 165 165)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(134 134, 166 166)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(133 133, 167 167)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(132 132, 168 168)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(131 131, 169 169)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(130 130, 170 170)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(129 129, 171 171)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(128 128, 172 172)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(127 127, 173 173)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(126 126, 174 174)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(125 125, 175 175)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(124 124, 176 176)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(123 123, 177 177)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(122 122, 178 178)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(121 121, 179 179)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(120 120, 180 180)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(119 119, 181 181)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(118 118, 182 182)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(117 117, 183 183)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(116 116, 184 184)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(115 115, 185 185)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(114 114, 186 186)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(113 113, 187 187)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(112 112, 188 188)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(111 111, 189 189)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(110 110, 190 190)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(109 109, 191 191)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(108 108, 192 192)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(107 107, 193 193)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(106 106, 194 194)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(105 105, 195 195)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(104 104, 196 196)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(103 103, 197 197)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(102 102, 198 198)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(101 101, 199 199)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(100 100, 200 200)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(99 99, 201 201)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(98 98, 202 202)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(97 97, 203 203)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(96 96, 204 204)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(95 95, 205 205)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(94 94, 206 206)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(93 93, 207 207)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(92 92, 208 208)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(91 91, 209 209)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(90 90, 210 210)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(89 89, 211 211)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(88 88, 212 212)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(87 87, 213 213)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(86 86, 214 214)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(85 85, 215 215)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(84 84, 216 216)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(83 83, 217 217)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(82 82, 218 218)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(81 81, 219 219)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(80 80, 220 220)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(79 79, 221 221)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(78 78, 222 222)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(77 77, 223 223)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(76 76, 224 224)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(75 75, 225 225)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(74 74, 226 226)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(73 73, 227 227)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(72 72, 228 228)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(71 71, 229 229)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(70 70, 230 230)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(69 69, 231 231)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(68 68, 232 232)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(67 67, 233 233)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(66 66, 234 234)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(65 65, 235 235)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(64 64, 236 236)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(63 63, 237 237)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(62 62, 238 238)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(61 61, 239 239)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(60 60, 240 240)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(59 59, 241 241)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(58 58, 242 242)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(57 57, 243 243)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(56 56, 244 244)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(55 55, 245 245)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(54 54, 246 246)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(53 53, 247 247)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(52 52, 248 248)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(51 51, 249 249)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(50 50, 250 250)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(49 49, 251 251)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(48 48, 252 252)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(47 47, 253 253)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(46 46, 254 254)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(45 45, 255 255)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(44 44, 256 256)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(43 43, 257 257)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(42 42, 258 258)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(41 41, 259 259)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(40 40, 260 260)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(39 39, 261 261)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(38 38, 262 262)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(37 37, 263 263)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(36 36, 264 264)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(35 35, 265 265)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(34 34, 266 266)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(33 33, 267 267)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(32 32, 268 268)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(31 31, 269 269)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(30 30, 270 270)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(29 29, 271 271)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(28 28, 272 272)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(27 27, 273 273)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(26 26, 274 274)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(25 25, 275 275)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(24 24, 276 276)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(23 23, 277 277)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(22 22, 278 278)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(21 21, 279 279)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(20 20, 280 280)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(19 19, 281 281)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(18 18, 282 282)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(17 17, 283 283)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(16 16, 284 284)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(15 15, 285 285)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(14 14, 286 286)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(13 13, 287 287)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(12 12, 288 288)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(11 11, 289 289)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(10 10, 290 290)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(9 9, 291 291)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(8 8, 292 292)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(7 7, 293 293)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(6 6, 294 294)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(5 5, 295 295)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(4 4, 296 296)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(3 3, 297 297)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(2 2, 298 298)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 1, 299 299)'));
+SELECT count(*) FROM t1;
+count(*)
+150
+EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 8 Using where
+SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
+fid AsText(g)
+1 LINESTRING(150 150,150 150)
+3 LINESTRING(148 148,152 152)
+4 LINESTRING(147 147,153 153)
+5 LINESTRING(146 146,154 154)
+6 LINESTRING(145 145,155 155)
+7 LINESTRING(144 144,156 156)
+8 LINESTRING(143 143,157 157)
+9 LINESTRING(142 142,158 158)
+10 LINESTRING(141 141,159 159)
+11 LINESTRING(140 140,160 160)
+2 LINESTRING(149 149,151 151)
+DROP TABLE t1;
+CREATE TABLE t2 (
+fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+g GEOMETRY NOT NULL
+);
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10)));
+ALTER TABLE t2 ADD SPATIAL KEY(g);
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `fid` int(11) NOT NULL AUTO_INCREMENT,
+ `g` geometry NOT NULL,
+ PRIMARY KEY (`fid`),
+ SPATIAL KEY `g` (`g`)
+) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1
+SELECT count(*) FROM t2;
+count(*)
+100
+EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g,
+GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range g g 34 NULL 4 Using where
+SELECT fid, AsText(g) FROM t2 WHERE Within(g,
+GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
+fid AsText(g)
+46 LINESTRING(51 41,60 50)
+56 LINESTRING(41 41,50 50)
+45 LINESTRING(51 51,60 60)
+55 LINESTRING(41 51,50 60)
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 10 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 9 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 8 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 7 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 6 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 5 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 4 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 3 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 2 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 1 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 10 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 9 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 8 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 7 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 6 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 5 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 4 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 3 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 2 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 1 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 10 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 9 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 8 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 7 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 6 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 5 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 4 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 3 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 2 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 1 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 10 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 9 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 8 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 7 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 6 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 5 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 4 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 3 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 2 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 1 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 10 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 9 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 8 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 7 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 6 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 5 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 4 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 3 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 2 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 1 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 10 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 9 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 8 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 7 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 6 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 5 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 4 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 3 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 2 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 1 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 10 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 9 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 8 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 7 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 6 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 5 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 4 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 3 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 2 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 1 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 10 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 9 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 8 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 7 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 6 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 5 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 4 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 3 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 2 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 1 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 10 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 9 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 8 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 7 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 6 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 5 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 4 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 3 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 2 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 1 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 10 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 9 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 8 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 7 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 6 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 5 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 4 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 3 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 2 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 1 * 10 - 9), 0)));
+SELECT count(*) FROM t2;
+count(*)
+100
+DROP TABLE t2;
+CREATE TABLE t1 (a geometry NOT NULL, SPATIAL (a));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+drop table t1;
+CREATE TABLE t1 (
+fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+g GEOMETRY NOT NULL,
+SPATIAL KEY(g)
+);
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 2, 2 3)')),(GeomFromText('LineString(1 2, 2 4)'));
+drop table t1;
+CREATE TABLE t1 (
+line GEOMETRY NOT NULL,
+kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
+name VARCHAR(32),
+SPATIAL KEY (line)
+);
+ALTER TABLE t1 DISABLE KEYS;
+INSERT INTO t1 (name, kind, line) VALUES
+("Aadaouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
+("Aadassiye", "pp", GeomFromText("POINT(35.816667 36.216667)")),
+("Aadbel", "pp", GeomFromText("POINT(34.533333 36.100000)")),
+("Aadchit", "pp", GeomFromText("POINT(33.347222 35.423611)")),
+("Aadchite", "pp", GeomFromText("POINT(33.347222 35.423611)")),
+("Aadchit el Qoussair", "pp", GeomFromText("POINT(33.283333 35.483333)")),
+("Aaddaye", "pp", GeomFromText("POINT(36.716667 40.833333)")),
+("'Aadeissa", "pp", GeomFromText("POINT(32.823889 35.698889)")),
+("Aaderup", "pp", GeomFromText("POINT(55.216667 11.766667)")),
+("Qalaat Aades", "pp", GeomFromText("POINT(33.503333 35.377500)")),
+("A ad'ino", "pp", GeomFromText("POINT(54.812222 38.209167)")),
+("Aadi Noia", "pp", GeomFromText("POINT(13.800000 39.833333)")),
+("Aad La Macta", "pp", GeomFromText("POINT(35.779444 -0.129167)")),
+("Aadland", "pp", GeomFromText("POINT(60.366667 5.483333)")),
+("Aadliye", "pp", GeomFromText("POINT(33.366667 36.333333)")),
+("Aadloun", "pp", GeomFromText("POINT(33.403889 35.273889)")),
+("Aadma", "pp", GeomFromText("POINT(58.798333 22.663889)")),
+("Aadma Asundus", "pp", GeomFromText("POINT(58.798333 22.663889)")),
+("Aadmoun", "pp", GeomFromText("POINT(34.150000 35.650000)")),
+("Aadneram", "pp", GeomFromText("POINT(59.016667 6.933333)")),
+("Aadneskaar", "pp", GeomFromText("POINT(58.083333 6.983333)")),
+("Aadorf", "pp", GeomFromText("POINT(47.483333 8.900000)")),
+("Aadorp", "pp", GeomFromText("POINT(52.366667 6.633333)")),
+("Aadouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
+("Aadoui", "pp", GeomFromText("POINT(34.450000 35.983333)")),
+("Aadouiye", "pp", GeomFromText("POINT(34.583333 36.183333)")),
+("Aadouss", "pp", GeomFromText("POINT(33.512500 35.601389)")),
+("Aadra", "pp", GeomFromText("POINT(33.616667 36.500000)")),
+("Aadzi", "pp", GeomFromText("POINT(38.100000 64.850000)"));
+ALTER TABLE t1 ENABLE KEYS;
+INSERT INTO t1 (name, kind, line) VALUES ("austria", "pp", GeomFromText('LINESTRING(14.9906 48.9887,14.9946 48.9904,14.9947 48.9916)'));
+drop table t1;
+CREATE TABLE t1 (st varchar(100));
+INSERT INTO t1 VALUES ("Fake string");
+CREATE TABLE t2 (geom GEOMETRY NOT NULL, SPATIAL KEY gk(geom));
+INSERT IGNORE INTO t2 SELECT GeomFromText(st) FROM t1;
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+drop table t1, t2;
+CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`)) DEFAULT CHARSET=latin1;
+INSERT INTO t1 (geometry) VALUES
+(PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000
+-66.8158332999, -18.7186111000 -66.8102777000, -18.7211111000 -66.9269443999,
+-18.6086111000 -66.9327777000))'));
+INSERT INTO t1 (geometry) VALUES
+(PolygonFromText('POLYGON((-65.7402776999 -96.6686111000, -65.7372222000
+-96.5516666000, -65.8502777000 -96.5461111000, -65.8527777000 -96.6627777000,
+-65.7402776999 -96.6686111000))'));
+check table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+CREATE TABLE t1 (
+c1 geometry NOT NULL default '',
+SPATIAL KEY i1 (c1)
+) DEFAULT CHARSET=latin1;
+INSERT INTO t1 (c1) VALUES (
+PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
+ -18.6055555000 -66.8158332999,
+ -18.7186111000 -66.8102777000,
+ -18.7211111000 -66.9269443999,
+ -18.6086111000 -66.9327777000))'));
+CHECK TABLE t1 EXTENDED;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
+CREATE TABLE t1 (
+c1 geometry NOT NULL default '',
+SPATIAL KEY i1 (c1)
+) DEFAULT CHARSET=latin1;
+INSERT INTO t1 (c1) VALUES (
+PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
+ -18.6055555000 -66.8158332999,
+ -18.7186111000 -66.8102777000,
+ -18.7211111000 -66.9269443999,
+ -18.6086111000 -66.9327777000))'));
+INSERT INTO t1 (c1) VALUES (
+PolygonFromText('POLYGON((-65.7402776999 -96.6686111000,
+ -65.7372222000 -96.5516666000,
+ -65.8502777000 -96.5461111000,
+ -65.8527777000 -96.6627777000,
+ -65.7402776999 -96.6686111000))'));
+INSERT INTO t1 (c1) VALUES (
+PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
+ -18.6055555000 -66.8158332999,
+ -18.7186111000 -66.8102777000,
+ -18.7211111000 -66.9269443999,
+ -18.6086111000 -66.9327777000))'));
+CHECK TABLE t1 EXTENDED;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
+CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
+INSERT INTO t1 (foo) VALUES (POINT(1,1));
+INSERT INTO t1 (foo) VALUES (POINT(1,0));
+INSERT INTO t1 (foo) VALUES (POINT(0,1));
+INSERT INTO t1 (foo) VALUES (POINT(0,0));
+SELECT 1 FROM t1 WHERE foo != POINT(0,0);
+1
+1
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (id bigint(12) unsigned NOT NULL auto_increment,
+c2 varchar(15) collate utf8_bin default NULL,
+c1 varchar(15) collate utf8_bin default NULL,
+c3 varchar(10) collate utf8_bin default NULL,
+spatial_point point NOT NULL,
+PRIMARY KEY(id),
+SPATIAL KEY (spatial_point)
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
+('y', 's', 'j', GeomFromText('POINT(167 74)')),
+('r', 'n', 'd', GeomFromText('POINT(215 118)')),
+('g', 'n', 'e', GeomFromText('POINT(203 98)')),
+('h', 'd', 'd', GeomFromText('POINT(54 193)')),
+('r', 'x', 'y', GeomFromText('POINT(47 69)')),
+('t', 'q', 'r', GeomFromText('POINT(109 42)')),
+('a', 'z', 'd', GeomFromText('POINT(0 154)')),
+('x', 'v', 'o', GeomFromText('POINT(174 131)')),
+('b', 'r', 'a', GeomFromText('POINT(114 253)')),
+('x', 'z', 'i', GeomFromText('POINT(163 21)')),
+('w', 'p', 'i', GeomFromText('POINT(42 102)')),
+('g', 'j', 'j', GeomFromText('POINT(170 133)')),
+('m', 'g', 'n', GeomFromText('POINT(28 22)')),
+('b', 'z', 'h', GeomFromText('POINT(174 28)')),
+('q', 'k', 'f', GeomFromText('POINT(233 73)')),
+('w', 'w', 'a', GeomFromText('POINT(124 200)')),
+('t', 'j', 'w', GeomFromText('POINT(252 101)')),
+('d', 'r', 'd', GeomFromText('POINT(98 18)')),
+('w', 'o', 'y', GeomFromText('POINT(165 31)')),
+('y', 'h', 't', GeomFromText('POINT(14 220)')),
+('d', 'p', 'u', GeomFromText('POINT(223 196)')),
+('g', 'y', 'g', GeomFromText('POINT(207 96)')),
+('x', 'm', 'n', GeomFromText('POINT(214 3)')),
+('g', 'v', 'e', GeomFromText('POINT(140 205)')),
+('g', 'm', 'm', GeomFromText('POINT(10 236)')),
+('i', 'r', 'j', GeomFromText('POINT(137 228)')),
+('w', 's', 'p', GeomFromText('POINT(115 6)')),
+('o', 'n', 'k', GeomFromText('POINT(158 129)')),
+('j', 'h', 'l', GeomFromText('POINT(129 72)')),
+('f', 'x', 'l', GeomFromText('POINT(139 207)')),
+('u', 'd', 'n', GeomFromText('POINT(125 109)')),
+('b', 'a', 'z', GeomFromText('POINT(30 32)')),
+('m', 'h', 'o', GeomFromText('POINT(251 251)')),
+('f', 'r', 'd', GeomFromText('POINT(243 211)')),
+('b', 'd', 'r', GeomFromText('POINT(232 80)')),
+('g', 'k', 'v', GeomFromText('POINT(15 100)')),
+('i', 'f', 'c', GeomFromText('POINT(109 66)')),
+('r', 't', 'j', GeomFromText('POINT(178 6)')),
+('y', 'n', 'f', GeomFromText('POINT(233 211)')),
+('f', 'y', 'm', GeomFromText('POINT(99 16)')),
+('z', 'q', 'l', GeomFromText('POINT(39 49)')),
+('j', 'c', 'r', GeomFromText('POINT(75 187)')),
+('c', 'y', 'y', GeomFromText('POINT(246 253)')),
+('w', 'u', 'd', GeomFromText('POINT(56 190)')),
+('n', 'q', 'm', GeomFromText('POINT(73 149)')),
+('d', 'y', 'a', GeomFromText('POINT(134 6)')),
+('z', 's', 'w', GeomFromText('POINT(216 225)')),
+('d', 'u', 'k', GeomFromText('POINT(132 70)')),
+('f', 'v', 't', GeomFromText('POINT(187 141)')),
+('r', 'r', 'a', GeomFromText('POINT(152 39)')),
+('y', 'p', 'o', GeomFromText('POINT(45 27)')),
+('p', 'n', 'm', GeomFromText('POINT(228 148)')),
+('e', 'g', 'e', GeomFromText('POINT(88 81)')),
+('m', 'a', 'h', GeomFromText('POINT(35 29)')),
+('m', 'h', 'f', GeomFromText('POINT(30 71)')),
+('h', 'k', 'i', GeomFromText('POINT(244 78)')),
+('z', 'v', 'd', GeomFromText('POINT(241 38)')),
+('q', 'l', 'j', GeomFromText('POINT(13 71)')),
+('s', 'p', 'g', GeomFromText('POINT(108 38)')),
+('q', 's', 'j', GeomFromText('POINT(92 101)')),
+('l', 'h', 'g', GeomFromText('POINT(120 78)')),
+('w', 't', 'b', GeomFromText('POINT(193 109)')),
+('b', 's', 's', GeomFromText('POINT(223 211)')),
+('w', 'w', 'y', GeomFromText('POINT(122 42)')),
+('q', 'c', 'c', GeomFromText('POINT(104 102)')),
+('w', 'g', 'n', GeomFromText('POINT(213 120)')),
+('p', 'q', 'a', GeomFromText('POINT(247 148)')),
+('c', 'z', 'e', GeomFromText('POINT(18 106)')),
+('z', 'u', 'n', GeomFromText('POINT(70 133)')),
+('j', 'n', 'x', GeomFromText('POINT(232 13)')),
+('e', 'h', 'f', GeomFromText('POINT(22 135)')),
+('w', 'l', 'f', GeomFromText('POINT(9 180)')),
+('a', 'v', 'q', GeomFromText('POINT(163 228)')),
+('i', 'z', 'o', GeomFromText('POINT(180 100)')),
+('e', 'c', 'l', GeomFromText('POINT(182 231)')),
+('c', 'k', 'o', GeomFromText('POINT(19 60)')),
+('q', 'f', 'p', GeomFromText('POINT(79 95)')),
+('m', 'd', 'r', GeomFromText('POINT(3 127)')),
+('m', 'e', 't', GeomFromText('POINT(136 154)')),
+('w', 'w', 'w', GeomFromText('POINT(102 15)')),
+('l', 'n', 'q', GeomFromText('POINT(71 196)')),
+('p', 'k', 'c', GeomFromText('POINT(47 139)')),
+('j', 'o', 'r', GeomFromText('POINT(177 128)')),
+('j', 'q', 'a', GeomFromText('POINT(170 6)')),
+('b', 'a', 'o', GeomFromText('POINT(63 211)')),
+('g', 's', 'o', GeomFromText('POINT(144 251)')),
+('w', 'u', 'w', GeomFromText('POINT(221 214)')),
+('g', 'a', 'm', GeomFromText('POINT(14 102)')),
+('u', 'q', 'z', GeomFromText('POINT(86 200)')),
+('k', 'a', 'm', GeomFromText('POINT(144 222)')),
+('j', 'u', 'r', GeomFromText('POINT(216 142)')),
+('q', 'k', 'v', GeomFromText('POINT(121 236)')),
+('p', 'o', 'r', GeomFromText('POINT(108 102)')),
+('b', 'd', 'x', GeomFromText('POINT(127 198)')),
+('k', 's', 'a', GeomFromText('POINT(2 150)')),
+('f', 'm', 'f', GeomFromText('POINT(160 191)')),
+('q', 'y', 'x', GeomFromText('POINT(98 111)')),
+('o', 'f', 'm', GeomFromText('POINT(232 218)')),
+('c', 'w', 'j', GeomFromText('POINT(156 165)')),
+('s', 'q', 'v', GeomFromText('POINT(98 161)'));
+SET @@RAND_SEED1=692635050, @@RAND_SEED2=297339954;
+DELETE FROM t1 ORDER BY RAND() LIMIT 10;
+SET @@RAND_SEED1=159925977, @@RAND_SEED2=942570618;
+DELETE FROM t1 ORDER BY RAND() LIMIT 10;
+SET @@RAND_SEED1=328169745, @@RAND_SEED2=410451954;
+DELETE FROM t1 ORDER BY RAND() LIMIT 10;
+SET @@RAND_SEED1=178507359, @@RAND_SEED2=332493072;
+DELETE FROM t1 ORDER BY RAND() LIMIT 10;
+SET @@RAND_SEED1=1034033013, @@RAND_SEED2=558966507;
+DELETE FROM t1 ORDER BY RAND() LIMIT 10;
+UPDATE t1 set spatial_point=GeomFromText('POINT(230 9)') where c1 like 'y%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(95 35)') where c1 like 'j%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(93 99)') where c1 like 'a%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(19 81)') where c1 like 'r%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(20 177)') where c1 like 'h%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(221 193)') where c1 like 'u%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(195 205)') where c1 like 'd%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(15 213)') where c1 like 'u%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(214 63)') where c1 like 'n%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(243 171)') where c1 like 'c%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(198 82)') where c1 like 'y%';
+INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
+('f', 'y', 'p', GeomFromText('POINT(109 235)')),
+('b', 'e', 'v', GeomFromText('POINT(20 48)')),
+('i', 'u', 'f', GeomFromText('POINT(15 55)')),
+('o', 'r', 'z', GeomFromText('POINT(105 64)')),
+('a', 'p', 'a', GeomFromText('POINT(142 236)')),
+('g', 'i', 'k', GeomFromText('POINT(10 49)')),
+('x', 'z', 'x', GeomFromText('POINT(192 200)')),
+('c', 'v', 'r', GeomFromText('POINT(94 168)')),
+('y', 'z', 'e', GeomFromText('POINT(141 51)')),
+('h', 'm', 'd', GeomFromText('POINT(35 251)')),
+('v', 'm', 'q', GeomFromText('POINT(44 90)')),
+('j', 'l', 'z', GeomFromText('POINT(67 237)')),
+('i', 'v', 'a', GeomFromText('POINT(75 14)')),
+('b', 'q', 't', GeomFromText('POINT(153 33)')),
+('e', 'm', 'a', GeomFromText('POINT(247 49)')),
+('l', 'y', 'g', GeomFromText('POINT(56 203)')),
+('v', 'o', 'r', GeomFromText('POINT(90 54)')),
+('r', 'n', 'd', GeomFromText('POINT(135 83)')),
+('j', 't', 'u', GeomFromText('POINT(174 239)')),
+('u', 'n', 'g', GeomFromText('POINT(104 191)')),
+('p', 'q', 'y', GeomFromText('POINT(63 171)')),
+('o', 'q', 'p', GeomFromText('POINT(192 103)')),
+('f', 'x', 'e', GeomFromText('POINT(244 30)')),
+('n', 'x', 'c', GeomFromText('POINT(92 103)')),
+('r', 'q', 'z', GeomFromText('POINT(166 20)')),
+('s', 'a', 'j', GeomFromText('POINT(137 205)')),
+('z', 't', 't', GeomFromText('POINT(99 134)')),
+('o', 'm', 'j', GeomFromText('POINT(217 3)')),
+('n', 'h', 'j', GeomFromText('POINT(211 17)')),
+('v', 'v', 'a', GeomFromText('POINT(41 137)')),
+('q', 'o', 'j', GeomFromText('POINT(5 92)')),
+('z', 'y', 'e', GeomFromText('POINT(175 212)')),
+('j', 'z', 'h', GeomFromText('POINT(224 194)')),
+('a', 'g', 'm', GeomFromText('POINT(31 119)')),
+('p', 'c', 'f', GeomFromText('POINT(17 221)')),
+('t', 'h', 'k', GeomFromText('POINT(26 203)')),
+('u', 'w', 'p', GeomFromText('POINT(47 185)')),
+('z', 'a', 'c', GeomFromText('POINT(61 133)')),
+('u', 'k', 'a', GeomFromText('POINT(210 115)')),
+('k', 'f', 'h', GeomFromText('POINT(125 113)')),
+('t', 'v', 'y', GeomFromText('POINT(12 239)')),
+('u', 'v', 'd', GeomFromText('POINT(90 24)')),
+('m', 'y', 'w', GeomFromText('POINT(25 243)')),
+('d', 'n', 'g', GeomFromText('POINT(122 92)')),
+('z', 'm', 'f', GeomFromText('POINT(235 110)')),
+('q', 'd', 'f', GeomFromText('POINT(233 217)')),
+('a', 'v', 'u', GeomFromText('POINT(69 59)')),
+('x', 'k', 'p', GeomFromText('POINT(240 14)')),
+('i', 'v', 'r', GeomFromText('POINT(154 42)')),
+('w', 'h', 'l', GeomFromText('POINT(178 156)')),
+('d', 'h', 'n', GeomFromText('POINT(65 157)')),
+('c', 'k', 'z', GeomFromText('POINT(62 33)')),
+('e', 'l', 'w', GeomFromText('POINT(162 1)')),
+('r', 'f', 'i', GeomFromText('POINT(127 71)')),
+('q', 'm', 'c', GeomFromText('POINT(63 118)')),
+('c', 'h', 'u', GeomFromText('POINT(205 203)')),
+('d', 't', 'p', GeomFromText('POINT(234 87)')),
+('s', 'g', 'h', GeomFromText('POINT(149 34)')),
+('o', 'b', 'q', GeomFromText('POINT(159 179)')),
+('k', 'u', 'f', GeomFromText('POINT(202 254)')),
+('u', 'f', 'g', GeomFromText('POINT(70 15)')),
+('x', 's', 'b', GeomFromText('POINT(25 181)')),
+('s', 'c', 'g', GeomFromText('POINT(252 17)')),
+('a', 'c', 'f', GeomFromText('POINT(89 67)')),
+('r', 'e', 'q', GeomFromText('POINT(55 54)')),
+('f', 'i', 'k', GeomFromText('POINT(178 230)')),
+('p', 'e', 'l', GeomFromText('POINT(198 28)')),
+('w', 'o', 'd', GeomFromText('POINT(204 189)')),
+('c', 'a', 'g', GeomFromText('POINT(230 178)')),
+('r', 'o', 'e', GeomFromText('POINT(61 116)')),
+('w', 'a', 'a', GeomFromText('POINT(178 237)')),
+('v', 'd', 'e', GeomFromText('POINT(70 85)')),
+('k', 'c', 'e', GeomFromText('POINT(147 118)')),
+('d', 'q', 't', GeomFromText('POINT(218 77)')),
+('k', 'g', 'f', GeomFromText('POINT(192 113)')),
+('w', 'n', 'e', GeomFromText('POINT(92 124)')),
+('r', 'm', 'q', GeomFromText('POINT(130 65)')),
+('o', 'r', 'r', GeomFromText('POINT(174 233)')),
+('k', 'n', 't', GeomFromText('POINT(175 147)')),
+('q', 'm', 'r', GeomFromText('POINT(18 208)')),
+('l', 'd', 'i', GeomFromText('POINT(13 104)')),
+('w', 'o', 'y', GeomFromText('POINT(207 39)')),
+('p', 'u', 'o', GeomFromText('POINT(114 31)')),
+('y', 'a', 'p', GeomFromText('POINT(106 59)')),
+('a', 'x', 'z', GeomFromText('POINT(17 57)')),
+('v', 'h', 'x', GeomFromText('POINT(170 13)')),
+('t', 's', 'u', GeomFromText('POINT(84 18)')),
+('z', 'z', 'f', GeomFromText('POINT(250 197)')),
+('l', 'z', 't', GeomFromText('POINT(59 80)')),
+('j', 'g', 's', GeomFromText('POINT(54 26)')),
+('g', 'v', 'm', GeomFromText('POINT(89 98)')),
+('q', 'v', 'b', GeomFromText('POINT(39 240)')),
+('x', 'k', 'v', GeomFromText('POINT(246 207)')),
+('k', 'u', 'i', GeomFromText('POINT(105 111)')),
+('w', 'z', 's', GeomFromText('POINT(235 8)')),
+('d', 'd', 'd', GeomFromText('POINT(105 4)')),
+('c', 'z', 'q', GeomFromText('POINT(13 140)')),
+('m', 'k', 'i', GeomFromText('POINT(208 120)')),
+('g', 'a', 'g', GeomFromText('POINT(9 182)')),
+('z', 'j', 'r', GeomFromText('POINT(149 153)')),
+('h', 'f', 'g', GeomFromText('POINT(81 236)')),
+('m', 'e', 'q', GeomFromText('POINT(209 215)')),
+('c', 'h', 'y', GeomFromText('POINT(235 70)')),
+('i', 'e', 'g', GeomFromText('POINT(138 26)')),
+('m', 't', 'u', GeomFromText('POINT(119 237)')),
+('o', 'w', 's', GeomFromText('POINT(193 166)')),
+('f', 'm', 'q', GeomFromText('POINT(85 96)')),
+('x', 'l', 'x', GeomFromText('POINT(58 115)')),
+('x', 'q', 'u', GeomFromText('POINT(108 210)')),
+('b', 'h', 'i', GeomFromText('POINT(250 139)')),
+('y', 'd', 'x', GeomFromText('POINT(199 135)')),
+('w', 'h', 'p', GeomFromText('POINT(247 233)')),
+('p', 'z', 't', GeomFromText('POINT(148 249)')),
+('q', 'a', 'u', GeomFromText('POINT(174 78)')),
+('v', 't', 'm', GeomFromText('POINT(70 228)')),
+('t', 'n', 'f', GeomFromText('POINT(123 2)')),
+('x', 't', 'b', GeomFromText('POINT(35 50)')),
+('r', 'j', 'f', GeomFromText('POINT(200 51)')),
+('s', 'q', 'o', GeomFromText('POINT(23 184)')),
+('u', 'v', 'z', GeomFromText('POINT(7 113)')),
+('v', 'u', 'l', GeomFromText('POINT(145 190)')),
+('o', 'k', 'i', GeomFromText('POINT(161 122)')),
+('l', 'y', 'e', GeomFromText('POINT(17 232)')),
+('t', 'b', 'e', GeomFromText('POINT(120 50)')),
+('e', 's', 'u', GeomFromText('POINT(254 1)')),
+('d', 'd', 'u', GeomFromText('POINT(167 140)')),
+('o', 'b', 'x', GeomFromText('POINT(186 237)')),
+('m', 's', 's', GeomFromText('POINT(172 149)')),
+('t', 'y', 'a', GeomFromText('POINT(149 85)')),
+('x', 't', 'r', GeomFromText('POINT(10 165)')),
+('g', 'c', 'e', GeomFromText('POINT(95 165)')),
+('e', 'e', 'z', GeomFromText('POINT(98 65)')),
+('f', 'v', 'i', GeomFromText('POINT(149 144)')),
+('o', 'p', 'm', GeomFromText('POINT(233 67)')),
+('t', 'u', 'b', GeomFromText('POINT(109 215)')),
+('o', 'o', 'b', GeomFromText('POINT(130 48)')),
+('e', 'm', 'h', GeomFromText('POINT(88 189)')),
+('e', 'v', 'y', GeomFromText('POINT(55 29)')),
+('e', 't', 'm', GeomFromText('POINT(129 55)')),
+('p', 'p', 'i', GeomFromText('POINT(126 222)')),
+('c', 'i', 'c', GeomFromText('POINT(19 158)')),
+('c', 'b', 's', GeomFromText('POINT(13 19)')),
+('u', 'y', 'a', GeomFromText('POINT(114 5)')),
+('a', 'o', 'f', GeomFromText('POINT(227 232)')),
+('t', 'c', 'z', GeomFromText('POINT(63 62)')),
+('d', 'o', 'k', GeomFromText('POINT(48 228)')),
+('x', 'c', 'e', GeomFromText('POINT(204 2)')),
+('e', 'e', 'g', GeomFromText('POINT(125 43)')),
+('o', 'r', 'f', GeomFromText('POINT(171 140)'));
+UPDATE t1 set spatial_point=GeomFromText('POINT(163 157)') where c1 like 'w%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(53 151)') where c1 like 'd%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(96 183)') where c1 like 'r%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(57 91)') where c1 like 'q%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(202 110)') where c1 like 'c%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(120 137)') where c1 like 'w%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(207 147)') where c1 like 'c%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(31 125)') where c1 like 'e%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(27 36)') where c1 like 'r%';
+INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
+('b', 'c', 'e', GeomFromText('POINT(41 137)')),
+('p', 'y', 'k', GeomFromText('POINT(50 22)')),
+('s', 'c', 'h', GeomFromText('POINT(208 173)')),
+('x', 'u', 'l', GeomFromText('POINT(199 175)')),
+('s', 'r', 'h', GeomFromText('POINT(85 192)')),
+('j', 'k', 'u', GeomFromText('POINT(18 25)')),
+('p', 'w', 'h', GeomFromText('POINT(152 197)')),
+('e', 'd', 'c', GeomFromText('POINT(229 3)')),
+('o', 'x', 'k', GeomFromText('POINT(187 155)')),
+('o', 'b', 'k', GeomFromText('POINT(208 150)')),
+('d', 'a', 'j', GeomFromText('POINT(70 87)')),
+('f', 'e', 'k', GeomFromText('POINT(156 96)')),
+('u', 'y', 'p', GeomFromText('POINT(239 193)')),
+('n', 'v', 'p', GeomFromText('POINT(223 98)')),
+('z', 'j', 'r', GeomFromText('POINT(87 89)')),
+('h', 'x', 'x', GeomFromText('POINT(92 0)')),
+('r', 'v', 'r', GeomFromText('POINT(159 139)')),
+('v', 'g', 'g', GeomFromText('POINT(16 229)')),
+('z', 'k', 'u', GeomFromText('POINT(99 52)')),
+('p', 'p', 'o', GeomFromText('POINT(105 125)')),
+('w', 'h', 'y', GeomFromText('POINT(105 154)')),
+('v', 'y', 'z', GeomFromText('POINT(134 238)')),
+('x', 'o', 'o', GeomFromText('POINT(178 88)')),
+('z', 'w', 'd', GeomFromText('POINT(123 60)')),
+('q', 'f', 'u', GeomFromText('POINT(64 90)')),
+('s', 'n', 't', GeomFromText('POINT(50 138)')),
+('v', 'p', 't', GeomFromText('POINT(114 91)')),
+('a', 'o', 'n', GeomFromText('POINT(78 43)')),
+('k', 'u', 'd', GeomFromText('POINT(185 161)')),
+('w', 'd', 'n', GeomFromText('POINT(25 92)')),
+('k', 'w', 'a', GeomFromText('POINT(59 238)')),
+('t', 'c', 'f', GeomFromText('POINT(65 87)')),
+('g', 's', 'p', GeomFromText('POINT(238 126)')),
+('d', 'n', 'y', GeomFromText('POINT(107 173)')),
+('l', 'a', 'w', GeomFromText('POINT(125 152)')),
+('m', 'd', 'j', GeomFromText('POINT(146 53)')),
+('q', 'm', 'c', GeomFromText('POINT(217 187)')),
+('i', 'r', 'r', GeomFromText('POINT(6 113)')),
+('e', 'j', 'b', GeomFromText('POINT(37 83)')),
+('w', 'w', 'h', GeomFromText('POINT(83 199)')),
+('k', 'b', 's', GeomFromText('POINT(170 64)')),
+('s', 'b', 'c', GeomFromText('POINT(163 130)')),
+('c', 'h', 'a', GeomFromText('POINT(141 3)')),
+('k', 'j', 'u', GeomFromText('POINT(143 76)')),
+('r', 'h', 'o', GeomFromText('POINT(243 92)')),
+('i', 'd', 'b', GeomFromText('POINT(205 13)')),
+('r', 'y', 'q', GeomFromText('POINT(138 8)')),
+('m', 'o', 'i', GeomFromText('POINT(36 45)')),
+('v', 'g', 'm', GeomFromText('POINT(0 40)')),
+('f', 'e', 'i', GeomFromText('POINT(76 6)')),
+('c', 'q', 'q', GeomFromText('POINT(115 248)')),
+('x', 'c', 'i', GeomFromText('POINT(29 74)')),
+('l', 's', 't', GeomFromText('POINT(83 18)')),
+('t', 't', 'a', GeomFromText('POINT(26 168)')),
+('u', 'n', 'x', GeomFromText('POINT(200 110)')),
+('j', 'b', 'd', GeomFromText('POINT(216 136)')),
+('s', 'p', 'w', GeomFromText('POINT(38 156)')),
+('f', 'b', 'v', GeomFromText('POINT(29 186)')),
+('v', 'e', 'r', GeomFromText('POINT(149 40)')),
+('v', 't', 'm', GeomFromText('POINT(184 24)')),
+('y', 'g', 'a', GeomFromText('POINT(219 105)')),
+('s', 'f', 'i', GeomFromText('POINT(114 130)')),
+('e', 'q', 'h', GeomFromText('POINT(203 135)')),
+('h', 'g', 'b', GeomFromText('POINT(9 208)')),
+('o', 'l', 'r', GeomFromText('POINT(245 79)')),
+('s', 's', 'v', GeomFromText('POINT(238 198)')),
+('w', 'w', 'z', GeomFromText('POINT(209 232)')),
+('v', 'd', 'n', GeomFromText('POINT(30 193)')),
+('q', 'w', 'k', GeomFromText('POINT(133 18)')),
+('o', 'h', 'o', GeomFromText('POINT(42 140)')),
+('f', 'f', 'h', GeomFromText('POINT(145 1)')),
+('u', 's', 'r', GeomFromText('POINT(70 62)')),
+('x', 'n', 'q', GeomFromText('POINT(33 86)')),
+('u', 'p', 'v', GeomFromText('POINT(232 220)')),
+('z', 'e', 'a', GeomFromText('POINT(130 69)')),
+('r', 'u', 'z', GeomFromText('POINT(243 241)')),
+('b', 'n', 't', GeomFromText('POINT(120 12)')),
+('u', 'f', 's', GeomFromText('POINT(190 212)')),
+('a', 'd', 'q', GeomFromText('POINT(235 191)')),
+('f', 'q', 'm', GeomFromText('POINT(176 2)')),
+('n', 'c', 's', GeomFromText('POINT(218 163)')),
+('e', 'm', 'h', GeomFromText('POINT(163 108)')),
+('c', 'f', 'l', GeomFromText('POINT(220 115)')),
+('c', 'v', 'q', GeomFromText('POINT(66 45)')),
+('w', 'v', 'x', GeomFromText('POINT(251 220)')),
+('f', 'w', 'z', GeomFromText('POINT(146 149)')),
+('h', 'n', 'h', GeomFromText('POINT(148 128)')),
+('y', 'k', 'v', GeomFromText('POINT(28 110)')),
+('c', 'x', 'q', GeomFromText('POINT(13 13)')),
+('e', 'd', 's', GeomFromText('POINT(91 190)')),
+('c', 'w', 'c', GeomFromText('POINT(10 231)')),
+('u', 'j', 'n', GeomFromText('POINT(250 21)')),
+('w', 'n', 'x', GeomFromText('POINT(141 69)')),
+('f', 'p', 'y', GeomFromText('POINT(228 246)')),
+('d', 'q', 'f', GeomFromText('POINT(194 22)')),
+('d', 'z', 'l', GeomFromText('POINT(233 181)')),
+('c', 'a', 'q', GeomFromText('POINT(183 96)')),
+('m', 'i', 'd', GeomFromText('POINT(117 226)')),
+('z', 'y', 'y', GeomFromText('POINT(62 81)')),
+('g', 'v', 'm', GeomFromText('POINT(66 158)'));
+SET @@RAND_SEED1=481064922, @@RAND_SEED2=438133497;
+DELETE FROM t1 ORDER BY RAND() LIMIT 10;
+SET @@RAND_SEED1=280535103, @@RAND_SEED2=444518646;
+DELETE FROM t1 ORDER BY RAND() LIMIT 10;
+SET @@RAND_SEED1=1072017234, @@RAND_SEED2=484203885;
+DELETE FROM t1 ORDER BY RAND() LIMIT 10;
+SET @@RAND_SEED1=358851897, @@RAND_SEED2=358495224;
+DELETE FROM t1 ORDER BY RAND() LIMIT 10;
+SET @@RAND_SEED1=509031459, @@RAND_SEED2=675962925;
+DELETE FROM t1 ORDER BY RAND() LIMIT 10;
+UPDATE t1 set spatial_point=GeomFromText('POINT(61 203)') where c1 like 'y%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(202 194)') where c1 like 'f%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(228 18)') where c1 like 'h%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(88 18)') where c1 like 'l%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(176 94)') where c1 like 'e%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(44 47)') where c1 like 'g%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(95 191)') where c1 like 'b%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(179 218)') where c1 like 'y%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(239 40)') where c1 like 'g%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(248 41)') where c1 like 'q%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(167 82)') where c1 like 't%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(13 104)') where c1 like 'u%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(139 84)') where c1 like 'a%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(145 108)') where c1 like 'p%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(147 57)') where c1 like 't%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(217 144)') where c1 like 'n%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(160 224)') where c1 like 'w%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(38 28)') where c1 like 'j%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(104 114)') where c1 like 'q%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(88 19)') where c1 like 'c%';
+INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
+('f', 'x', 'p', GeomFromText('POINT(92 181)')),
+('s', 'i', 'c', GeomFromText('POINT(49 60)')),
+('c', 'c', 'i', GeomFromText('POINT(7 57)')),
+('n', 'g', 'k', GeomFromText('POINT(252 105)')),
+('g', 'b', 'm', GeomFromText('POINT(180 11)')),
+('u', 'l', 'r', GeomFromText('POINT(32 90)')),
+('c', 'x', 'e', GeomFromText('POINT(143 24)')),
+('x', 'u', 'a', GeomFromText('POINT(123 92)')),
+('s', 'b', 'h', GeomFromText('POINT(190 108)')),
+('c', 'x', 'b', GeomFromText('POINT(104 100)')),
+('i', 'd', 't', GeomFromText('POINT(214 104)')),
+('r', 'w', 'g', GeomFromText('POINT(29 67)')),
+('b', 'f', 'g', GeomFromText('POINT(149 46)')),
+('r', 'r', 'd', GeomFromText('POINT(242 196)')),
+('j', 'l', 'a', GeomFromText('POINT(90 196)')),
+('e', 't', 'b', GeomFromText('POINT(190 64)')),
+('l', 'x', 'w', GeomFromText('POINT(250 73)')),
+('q', 'y', 'r', GeomFromText('POINT(120 182)')),
+('s', 'j', 'a', GeomFromText('POINT(180 175)')),
+('n', 'i', 'y', GeomFromText('POINT(124 136)')),
+('s', 'x', 's', GeomFromText('POINT(176 209)')),
+('u', 'f', 's', GeomFromText('POINT(215 173)')),
+('m', 'j', 'x', GeomFromText('POINT(44 140)')),
+('v', 'g', 'x', GeomFromText('POINT(177 233)')),
+('u', 't', 'b', GeomFromText('POINT(136 197)')),
+('f', 'g', 'b', GeomFromText('POINT(10 8)')),
+('v', 'c', 'j', GeomFromText('POINT(13 81)')),
+('d', 's', 'q', GeomFromText('POINT(200 100)')),
+('a', 'p', 'j', GeomFromText('POINT(33 40)')),
+('i', 'c', 'g', GeomFromText('POINT(168 204)')),
+('k', 'h', 'i', GeomFromText('POINT(93 243)')),
+('s', 'b', 's', GeomFromText('POINT(157 13)')),
+('v', 'l', 'l', GeomFromText('POINT(103 6)')),
+('r', 'b', 'k', GeomFromText('POINT(244 137)')),
+('l', 'd', 'r', GeomFromText('POINT(162 254)')),
+('q', 'b', 'z', GeomFromText('POINT(136 246)')),
+('x', 'x', 'p', GeomFromText('POINT(120 37)')),
+('m', 'e', 'z', GeomFromText('POINT(203 167)')),
+('q', 'n', 'p', GeomFromText('POINT(94 119)')),
+('b', 'g', 'u', GeomFromText('POINT(93 248)')),
+('r', 'v', 'v', GeomFromText('POINT(53 88)')),
+('y', 'a', 'i', GeomFromText('POINT(98 219)')),
+('a', 's', 'g', GeomFromText('POINT(173 138)')),
+('c', 'a', 't', GeomFromText('POINT(235 135)')),
+('q', 'm', 'd', GeomFromText('POINT(224 208)')),
+('e', 'p', 'k', GeomFromText('POINT(161 238)')),
+('n', 'g', 'q', GeomFromText('POINT(35 204)')),
+('t', 't', 'x', GeomFromText('POINT(230 178)')),
+('w', 'f', 'a', GeomFromText('POINT(150 221)')),
+('z', 'm', 'z', GeomFromText('POINT(119 42)')),
+('l', 'j', 's', GeomFromText('POINT(97 96)')),
+('f', 'z', 'x', GeomFromText('POINT(208 65)')),
+('i', 'v', 'c', GeomFromText('POINT(145 79)')),
+('l', 'f', 'k', GeomFromText('POINT(83 234)')),
+('u', 'a', 's', GeomFromText('POINT(250 49)')),
+('o', 'k', 'p', GeomFromText('POINT(46 50)')),
+('d', 'e', 'z', GeomFromText('POINT(30 198)')),
+('r', 'r', 'l', GeomFromText('POINT(78 189)')),
+('y', 'l', 'f', GeomFromText('POINT(188 132)')),
+('d', 'q', 'm', GeomFromText('POINT(247 107)')),
+('p', 'j', 'n', GeomFromText('POINT(148 227)')),
+('b', 'o', 'i', GeomFromText('POINT(172 25)')),
+('e', 'v', 'd', GeomFromText('POINT(94 248)')),
+('q', 'd', 'f', GeomFromText('POINT(15 29)')),
+('w', 'b', 'b', GeomFromText('POINT(74 111)')),
+('g', 'q', 'f', GeomFromText('POINT(107 215)')),
+('o', 'h', 'r', GeomFromText('POINT(25 168)')),
+('u', 't', 'w', GeomFromText('POINT(251 188)')),
+('h', 's', 'w', GeomFromText('POINT(254 247)')),
+('f', 'f', 'b', GeomFromText('POINT(166 103)'));
+SET @@RAND_SEED1=866613816, @@RAND_SEED2=92289615;
+INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
+('l', 'c', 'l', GeomFromText('POINT(202 98)')),
+('k', 'c', 'b', GeomFromText('POINT(46 206)')),
+('r', 'y', 'm', GeomFromText('POINT(74 140)')),
+('y', 'z', 'd', GeomFromText('POINT(200 160)')),
+('s', 'y', 's', GeomFromText('POINT(156 205)')),
+('u', 'v', 'p', GeomFromText('POINT(86 82)')),
+('j', 's', 's', GeomFromText('POINT(91 233)')),
+('x', 'j', 'f', GeomFromText('POINT(3 14)')),
+('l', 'z', 'v', GeomFromText('POINT(123 156)')),
+('h', 'i', 'o', GeomFromText('POINT(145 229)')),
+('o', 'r', 'd', GeomFromText('POINT(15 22)')),
+('f', 'x', 't', GeomFromText('POINT(21 60)')),
+('t', 'g', 'h', GeomFromText('POINT(50 153)')),
+('g', 'u', 'b', GeomFromText('POINT(82 85)')),
+('v', 'a', 'p', GeomFromText('POINT(231 178)')),
+('n', 'v', 'o', GeomFromText('POINT(183 25)')),
+('j', 'n', 'm', GeomFromText('POINT(50 144)')),
+('e', 'f', 'i', GeomFromText('POINT(46 16)')),
+('d', 'w', 'a', GeomFromText('POINT(66 6)')),
+('f', 'x', 'a', GeomFromText('POINT(107 197)')),
+('m', 'o', 'a', GeomFromText('POINT(142 80)')),
+('q', 'l', 'g', GeomFromText('POINT(251 23)')),
+('c', 's', 's', GeomFromText('POINT(158 43)')),
+('y', 'd', 'o', GeomFromText('POINT(196 228)')),
+('d', 'p', 'l', GeomFromText('POINT(107 5)')),
+('h', 'a', 'b', GeomFromText('POINT(183 166)')),
+('m', 'w', 'p', GeomFromText('POINT(19 59)')),
+('b', 'y', 'o', GeomFromText('POINT(178 30)')),
+('x', 'w', 'i', GeomFromText('POINT(168 94)')),
+('t', 'k', 'z', GeomFromText('POINT(171 5)')),
+('r', 'm', 'a', GeomFromText('POINT(222 19)')),
+('u', 'v', 'e', GeomFromText('POINT(224 80)')),
+('q', 'r', 'k', GeomFromText('POINT(212 218)')),
+('d', 'p', 'j', GeomFromText('POINT(169 7)')),
+('d', 'r', 'v', GeomFromText('POINT(193 23)')),
+('n', 'y', 'y', GeomFromText('POINT(130 178)')),
+('m', 'z', 'r', GeomFromText('POINT(81 200)')),
+('j', 'e', 'w', GeomFromText('POINT(145 239)')),
+('v', 'h', 'x', GeomFromText('POINT(24 105)')),
+('z', 'm', 'a', GeomFromText('POINT(175 129)')),
+('b', 'c', 'v', GeomFromText('POINT(213 10)')),
+('t', 't', 'u', GeomFromText('POINT(2 129)')),
+('r', 's', 'v', GeomFromText('POINT(209 192)')),
+('x', 'p', 'g', GeomFromText('POINT(43 63)')),
+('t', 'e', 'u', GeomFromText('POINT(139 210)')),
+('l', 'e', 't', GeomFromText('POINT(245 148)')),
+('a', 'i', 'k', GeomFromText('POINT(167 195)')),
+('m', 'o', 'h', GeomFromText('POINT(206 120)')),
+('g', 'z', 's', GeomFromText('POINT(169 240)')),
+('z', 'u', 's', GeomFromText('POINT(202 120)')),
+('i', 'b', 'a', GeomFromText('POINT(216 18)')),
+('w', 'y', 'g', GeomFromText('POINT(119 236)')),
+('h', 'y', 'p', GeomFromText('POINT(161 24)'));
+UPDATE t1 set spatial_point=GeomFromText('POINT(33 100)') where c1 like 't%';
+UPDATE t1 set spatial_point=GeomFromText('POINT(41 46)') where c1 like 'f%';
+CHECK TABLE t1 EXTENDED;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
+create table t1 (a geometry not null, spatial index(a));
+insert into t1 values (POINT(1.1517219314031e+164, 131072));
+insert into t1 values (POINT(9.1248812352444e+192, 2.9740338169556e+284));
+insert into t1 values (POINT(4.7783097267365e-299, -0));
+insert into t1 values (POINT(1.49166814624e-154, 2.0880974297595e-53));
+insert into t1 values (POINT(4.0917382598702e+149, 1.2024538023802e+111));
+insert into t1 values (POINT(2.0349165139404e+236, 2.9993936277913e-241));
+insert into t1 values (POINT(2.5243548967072e-29, 1.2024538023802e+111));
+insert into t1 values (POINT(0, 6.9835074892995e-251));
+insert into t1 values (POINT(2.0880974297595e-53, 3.1050361846014e+231));
+insert into t1 values (POINT(2.8728483499323e-188, 2.4600631144627e+260));
+insert into t1 values (POINT(3.0517578125e-05, 2.0349165139404e+236));
+insert into t1 values (POINT(1.1517219314031e+164, 1.1818212630766e-125));
+insert into t1 values (POINT(2.481040258324e-265, 5.7766220027675e-275));
+insert into t1 values (POINT(2.0880974297595e-53, 2.5243548967072e-29));
+insert into t1 values (POINT(5.7766220027675e-275, 9.9464647281957e+86));
+insert into t1 values (POINT(2.2181357552967e+130, 3.7857669957337e-270));
+insert into t1 values (POINT(4.5767114681874e-246, 3.6893488147419e+19));
+insert into t1 values (POINT(4.5767114681874e-246, 3.7537584144024e+255));
+insert into t1 values (POINT(3.7857669957337e-270, 1.8033161362863e-130));
+insert into t1 values (POINT(0, 5.8774717541114e-39));
+insert into t1 values (POINT(1.1517219314031e+164, 2.2761049594727e-159));
+insert into t1 values (POINT(6.243497100632e+144, 3.7857669957337e-270));
+insert into t1 values (POINT(3.7857669957337e-270, 2.6355494858076e-82));
+insert into t1 values (POINT(2.0349165139404e+236, 3.8518598887745e-34));
+insert into t1 values (POINT(4.6566128730774e-10, 2.0880974297595e-53));
+insert into t1 values (POINT(2.0880974297595e-53, 1.8827498946116e-183));
+insert into t1 values (POINT(1.8033161362863e-130, 9.1248812352444e+192));
+insert into t1 values (POINT(4.7783097267365e-299, 2.2761049594727e-159));
+insert into t1 values (POINT(1.94906280228e+289, 1.2338789709327e-178));
+drop table t1;
+CREATE TABLE t1(foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
+INSERT INTO t1(foo) VALUES (NULL);
+ERROR 23000: Column 'foo' cannot be null
+INSERT IGNORE INTO t1() VALUES ();
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+INSERT INTO t1(foo) VALUES ('');
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+DROP TABLE t1;
+CREATE TABLE t1 (a INT AUTO_INCREMENT, b POINT NOT NULL, KEY (a), SPATIAL KEY (b));
+INSERT INTO t1 (b) VALUES (GeomFromText('POINT(1 2)'));
+INSERT INTO t1 (b) SELECT b FROM t1;
+INSERT INTO t1 (b) SELECT b FROM t1;
+INSERT INTO t1 (b) SELECT b FROM t1;
+INSERT INTO t1 (b) SELECT b FROM t1;
+INSERT INTO t1 (b) SELECT b FROM t1;
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b GEOMETRY NOT NULL, SPATIAL KEY b(b));
+INSERT INTO t1 VALUES (1, GEOMFROMTEXT('LINESTRING(1102218.456 1,2000000 2)'));
+INSERT INTO t1 VALUES (2, GEOMFROMTEXT('LINESTRING(1102218.456 1,2000000 2)'));
+SELECT COUNT(*) FROM t1 WHERE
+MBRINTERSECTS(b, GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') );
+COUNT(*)
+2
+SELECT COUNT(*) FROM t1 IGNORE INDEX (b) WHERE
+MBRINTERSECTS(b, GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') );
+COUNT(*)
+2
+DROP TABLE t1;
+#
+# Bug #48258: Assertion failed when using a spatial index
+#
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+1
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+1
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+1
+1
+DROP TABLE t1;
+#
+# Bug #51357: crash when using handler commands on spatial indexes
+#
+CREATE TABLE t1(a GEOMETRY NOT NULL,SPATIAL INDEX a(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a FIRST;
+a
+HANDLER t1 READ a NEXT;
+a
+HANDLER t1 READ a PREV;
+a
+HANDLER t1 READ a LAST;
+a
+HANDLER t1 CLOSE;
+HANDLER t1 OPEN;
+HANDLER t1 READ a FIRST;
+a
+INSERT INTO t1 VALUES (GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
+# should not crash
+HANDLER t1 READ a NEXT;
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+End of 5.0 tests.
+#
+# Bug #57323/11764487: myisam corruption with insert ignore
+# and invalid spatial data
+#
+CREATE TABLE t1(a POINT NOT NULL, b GEOMETRY NOT NULL,
+SPATIAL KEY(a), SPATIAL KEY(b));
+INSERT INTO t1 VALUES(GEOMFROMTEXT("point (0 0)"), GEOMFROMTEXT("point (1 1)"));
+INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=GEOMFROMTEXT("error");
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=NULL;
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+SELECT ASTEXT(a), ASTEXT(b) FROM t1;
+ASTEXT(a) ASTEXT(b)
+POINT(0 0) POINT(1 1)
+DROP TABLE t1;
+CREATE TABLE t1(a INT NOT NULL, b GEOMETRY NOT NULL,
+KEY(a), SPATIAL KEY(b));
+INSERT INTO t1 VALUES(0, GEOMFROMTEXT("point (1 1)"));
+INSERT IGNORE INTO t1 SET a=0, b=GEOMFROMTEXT("error");
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+INSERT IGNORE INTO t1 SET a=1, b=NULL;
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+SELECT a, ASTEXT(b) FROM t1;
+a ASTEXT(b)
+0 POINT(1 1)
+DROP TABLE t1;
+End of 5.1 tests
+CREATE TABLE t1 (
+l LINESTRING NOT NULL,
+SPATIAL KEY(l)
+);
+INSERT INTO t1 VALUES(GeomFromText('LINESTRING(0 0, 1 1)'));
+INSERT INTO t1 VALUES(GeomFromText('LINESTRING(1 1, 2 2)'));
+INSERT INTO t1 VALUES(GeomFromText('LINESTRING(2 2, 3 3)'));
+SELECT COUNT(*) FROM t1 IGNORE INDEX(l) WHERE MBRContains(l, GEOMFROMTEXT('POINT(0 0)'));
+COUNT(*)
+1
+SELECT COUNT(*) FROM t1 IGNORE INDEX(l) WHERE MBRWithin(GEOMFROMTEXT('POINT(0 0)'), l);
+COUNT(*)
+1
+SELECT COUNT(*) FROM t1 FORCE INDEX(l) WHERE MBRContains(l, GEOMFROMTEXT('POINT(0 0)'));
+COUNT(*)
+1
+SELECT COUNT(*) FROM t1 FORCE INDEX(l) WHERE MBRWithin(GEOMFROMTEXT('POINT(0 0)'), l);
+COUNT(*)
+1
+DROP TABLE t1;
+#
+# Start of 10.1 tests
+#
+#
+# MDEV-8239 Reverse spatial operations OP(const, field) do not get optimized
+#
+CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES (Point(1,2)),(Point(1,3));
+EXPLAIN SELECT * FROM t1 WHERE MBRINTERSECTS(a,Point(1,2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 34 NULL 1 Using where
+EXPLAIN SELECT * FROM t1 WHERE ST_INTERSECTS(a,Point(1,2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 34 NULL 1 Using where
+EXPLAIN SELECT * FROM t1 WHERE MBRINTERSECTS(Point(1,2),a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 34 NULL 1 Using where
+EXPLAIN SELECT * FROM t1 WHERE ST_INTERSECTS(Point(1,2),a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 34 NULL 1 Using where
+DROP TABLE t1;
+#
+# MDEV-8610 "WHERE CONTAINS(indexed_geometry_column,1)" causes full table scan
+#
+CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES (Point(1,1)),(Point(2,2)),(Point(3,3));
+EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1);
+ERROR HY000: Illegal parameter data type int for operation 'st_contains'
+EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1.0);
+ERROR HY000: Illegal parameter data type decimal for operation 'st_contains'
+EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1e0);
+ERROR HY000: Illegal parameter data type double for operation 'st_contains'
+EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,TIME'00:00:00');
+ERROR HY000: Illegal parameter data type time for operation 'st_contains'
+EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,DATE'2001-01-01');
+ERROR HY000: Illegal parameter data type date for operation 'st_contains'
+EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,TIMESTAMP'2001-01-01 00:00:00');
+ERROR HY000: Illegal parameter data type datetime for operation 'st_contains'
+DROP TABLE t1;
+#
+# End of 10.1 tests
+#
diff --git a/mysql-test/suite/innodb_gis/r/kill_server.result b/mysql-test/suite/innodb_gis/r/kill_server.result
index 579317872b4..eac4feb442f 100644
--- a/mysql-test/suite/innodb_gis/r/kill_server.result
+++ b/mysql-test/suite/innodb_gis/r/kill_server.result
@@ -36,6 +36,5 @@ call mtr.add_suppression("InnoDB: A copy of page \[page id: space=[0-9]+, page n
START TRANSACTION;
CALL insert_t1(5000);
COMMIT;
-# Kill and restart
drop procedure insert_t1;
drop table t1;
diff --git a/mysql-test/suite/innodb_gis/r/point_basic.result b/mysql-test/suite/innodb_gis/r/point_basic.result
index faaef07c112..0fa5021dab9 100644
--- a/mysql-test/suite/innodb_gis/r/point_basic.result
+++ b/mysql-test/suite/innodb_gis/r/point_basic.result
@@ -1526,7 +1526,7 @@ show warnings;
Level Code Message
Warning 150 Alter table '`test`.`child`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `#sql-temporary`
ALTER TABLE parent DROP INDEX idx1;
ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p);
Got one of the listed errors
@@ -1534,7 +1534,7 @@ show warnings;
Level Code Message
Warning 150 Alter table '`test`.`child`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `#sql-temporary`
ALTER TABLE child DROP INDEX idx2;
ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p);
Got one of the listed errors
@@ -1542,7 +1542,7 @@ show warnings;
Level Code Message
Warning 150 Alter table '`test`.`child`' with foreign key constraint failed. There is only prefix index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
-Warning 1215 Cannot add foreign key constraint
+Warning 1215 Cannot add foreign key constraint for `#sql-temporary`
DROP TABLE child, parent;
#
# Bug#28763: Selecting geometry fields in UNION caused server crash.
diff --git a/mysql-test/suite/innodb_gis/r/row_format.result b/mysql-test/suite/innodb_gis/r/row_format.result
deleted file mode 100644
index 1fd19371bcd..00000000000
--- a/mysql-test/suite/innodb_gis/r/row_format.result
+++ /dev/null
@@ -1,1588 +0,0 @@
-SET GLOBAL innodb_file_per_table='off';
-SET GLOBAL innodb_file_format='Antelope';
-Warnings:
-Warning 131 Using innodb_file_format is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html
-CREATE TABLE t1 (
-id bigint(12) unsigned NOT NULL auto_increment,
-c2 varchar(15) collate utf8_bin DEFAULT NULL,
-c1 varchar(15) collate utf8_bin DEFAULT NULL,
-c3 varchar(10) collate utf8_bin DEFAULT NULL,
-spatial_point point NOT NULL,
-PRIMARY KEY(id),
-SPATIAL KEY (spatial_point)
-) ROW_FORMAT=REDUNDANT ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('y', 's', 'j', ST_GeomFromText('POINT(167 74)')),
-('r', 'n', 'd', ST_GeomFromText('POINT(215 118)')),
-('g', 'n', 'e', ST_GeomFromText('POINT(203 98)')),
-('h', 'd', 'd', ST_GeomFromText('POINT(54 193)')),
-('r', 'x', 'y', ST_GeomFromText('POINT(47 69)')),
-('t', 'q', 'r', ST_GeomFromText('POINT(109 42)')),
-('a', 'z', 'd', ST_GeomFromText('POINT(0 154)')),
-('x', 'v', 'o', ST_GeomFromText('POINT(174 131)')),
-('b', 'r', 'a', ST_GeomFromText('POINT(114 253)')),
-('x', 'z', 'i', ST_GeomFromText('POINT(163 21)')),
-('w', 'p', 'i', ST_GeomFromText('POINT(42 102)')),
-('g', 'j', 'j', ST_GeomFromText('POINT(170 133)')),
-('m', 'g', 'n', ST_GeomFromText('POINT(28 22)')),
-('b', 'z', 'h', ST_GeomFromText('POINT(174 28)')),
-('q', 'k', 'f', ST_GeomFromText('POINT(233 73)')),
-('w', 'w', 'a', ST_GeomFromText('POINT(124 200)')),
-('t', 'j', 'w', ST_GeomFromText('POINT(252 101)')),
-('d', 'r', 'd', ST_GeomFromText('POINT(98 18)')),
-('w', 'o', 'y', ST_GeomFromText('POINT(165 31)')),
-('y', 'h', 't', ST_GeomFromText('POINT(14 220)')),
-('d', 'p', 'u', ST_GeomFromText('POINT(223 196)')),
-('g', 'y', 'g', ST_GeomFromText('POINT(207 96)')),
-('x', 'm', 'n', ST_GeomFromText('POINT(214 3)')),
-('g', 'v', 'e', ST_GeomFromText('POINT(140 205)')),
-('g', 'm', 'm', ST_GeomFromText('POINT(10 236)')),
-('i', 'r', 'j', ST_GeomFromText('POINT(137 228)')),
-('w', 's', 'p', ST_GeomFromText('POINT(115 6)')),
-('o', 'n', 'k', ST_GeomFromText('POINT(158 129)')),
-('j', 'h', 'l', ST_GeomFromText('POINT(129 72)')),
-('f', 'x', 'l', ST_GeomFromText('POINT(139 207)')),
-('u', 'd', 'n', ST_GeomFromText('POINT(125 109)')),
-('b', 'a', 'z', ST_GeomFromText('POINT(30 32)')),
-('m', 'h', 'o', ST_GeomFromText('POINT(251 251)')),
-('f', 'r', 'd', ST_GeomFromText('POINT(243 211)')),
-('b', 'd', 'r', ST_GeomFromText('POINT(232 80)')),
-('g', 'k', 'v', ST_GeomFromText('POINT(15 100)')),
-('i', 'f', 'c', ST_GeomFromText('POINT(109 66)')),
-('r', 't', 'j', ST_GeomFromText('POINT(178 6)')),
-('y', 'n', 'f', ST_GeomFromText('POINT(233 211)')),
-('f', 'y', 'm', ST_GeomFromText('POINT(99 16)')),
-('z', 'q', 'l', ST_GeomFromText('POINT(39 49)')),
-('j', 'c', 'r', ST_GeomFromText('POINT(75 187)')),
-('c', 'y', 'y', ST_GeomFromText('POINT(246 253)')),
-('w', 'u', 'd', ST_GeomFromText('POINT(56 190)')),
-('n', 'q', 'm', ST_GeomFromText('POINT(73 149)')),
-('d', 'y', 'a', ST_GeomFromText('POINT(134 6)')),
-('z', 's', 'w', ST_GeomFromText('POINT(216 225)')),
-('d', 'u', 'k', ST_GeomFromText('POINT(132 70)')),
-('f', 'v', 't', ST_GeomFromText('POINT(187 141)')),
-('r', 'r', 'a', ST_GeomFromText('POINT(152 39)')),
-('y', 'p', 'o', ST_GeomFromText('POINT(45 27)')),
-('p', 'n', 'm', ST_GeomFromText('POINT(228 148)')),
-('e', 'g', 'e', ST_GeomFromText('POINT(88 81)')),
-('m', 'a', 'h', ST_GeomFromText('POINT(35 29)')),
-('m', 'h', 'f', ST_GeomFromText('POINT(30 71)')),
-('h', 'k', 'i', ST_GeomFromText('POINT(244 78)')),
-('z', 'v', 'd', ST_GeomFromText('POINT(241 38)')),
-('q', 'l', 'j', ST_GeomFromText('POINT(13 71)')),
-('s', 'p', 'g', ST_GeomFromText('POINT(108 38)')),
-('q', 's', 'j', ST_GeomFromText('POINT(92 101)')),
-('l', 'h', 'g', ST_GeomFromText('POINT(120 78)')),
-('w', 't', 'b', ST_GeomFromText('POINT(193 109)')),
-('b', 's', 's', ST_GeomFromText('POINT(223 211)')),
-('w', 'w', 'y', ST_GeomFromText('POINT(122 42)')),
-('q', 'c', 'c', ST_GeomFromText('POINT(104 102)')),
-('w', 'g', 'n', ST_GeomFromText('POINT(213 120)')),
-('p', 'q', 'a', ST_GeomFromText('POINT(247 148)')),
-('c', 'z', 'e', ST_GeomFromText('POINT(18 106)')),
-('z', 'u', 'n', ST_GeomFromText('POINT(70 133)')),
-('j', 'n', 'x', ST_GeomFromText('POINT(232 13)')),
-('e', 'h', 'f', ST_GeomFromText('POINT(22 135)')),
-('w', 'l', 'f', ST_GeomFromText('POINT(9 180)')),
-('a', 'v', 'q', ST_GeomFromText('POINT(163 228)')),
-('i', 'z', 'o', ST_GeomFromText('POINT(180 100)')),
-('e', 'c', 'l', ST_GeomFromText('POINT(182 231)')),
-('c', 'k', 'o', ST_GeomFromText('POINT(19 60)')),
-('q', 'f', 'p', ST_GeomFromText('POINT(79 95)')),
-('m', 'd', 'r', ST_GeomFromText('POINT(3 127)')),
-('m', 'e', 't', ST_GeomFromText('POINT(136 154)')),
-('w', 'w', 'w', ST_GeomFromText('POINT(102 15)')),
-('l', 'n', 'q', ST_GeomFromText('POINT(71 196)')),
-('p', 'k', 'c', ST_GeomFromText('POINT(47 139)')),
-('j', 'o', 'r', ST_GeomFromText('POINT(177 128)')),
-('j', 'q', 'a', ST_GeomFromText('POINT(170 6)')),
-('b', 'a', 'o', ST_GeomFromText('POINT(63 211)')),
-('g', 's', 'o', ST_GeomFromText('POINT(144 251)')),
-('w', 'u', 'w', ST_GeomFromText('POINT(221 214)')),
-('g', 'a', 'm', ST_GeomFromText('POINT(14 102)')),
-('u', 'q', 'z', ST_GeomFromText('POINT(86 200)')),
-('k', 'a', 'm', ST_GeomFromText('POINT(144 222)')),
-('j', 'u', 'r', ST_GeomFromText('POINT(216 142)')),
-('q', 'k', 'v', ST_GeomFromText('POINT(121 236)')),
-('p', 'o', 'r', ST_GeomFromText('POINT(108 102)')),
-('b', 'd', 'x', ST_GeomFromText('POINT(127 198)')),
-('k', 's', 'a', ST_GeomFromText('POINT(2 150)')),
-('f', 'm', 'f', ST_GeomFromText('POINT(160 191)')),
-('q', 'y', 'x', ST_GeomFromText('POINT(98 111)')),
-('o', 'f', 'm', ST_GeomFromText('POINT(232 218)')),
-('c', 'w', 'j', ST_GeomFromText('POINT(156 165)')),
-('s', 'q', 'v', ST_GeomFromText('POINT(98 161)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'y', 'p', ST_GeomFromText('POINT(109 235)')),
-('b', 'e', 'v', ST_GeomFromText('POINT(20 48)')),
-('i', 'u', 'f', ST_GeomFromText('POINT(15 55)')),
-('o', 'r', 'z', ST_GeomFromText('POINT(105 64)')),
-('a', 'p', 'a', ST_GeomFromText('POINT(142 236)')),
-('g', 'i', 'k', ST_GeomFromText('POINT(10 49)')),
-('x', 'z', 'x', ST_GeomFromText('POINT(192 200)')),
-('c', 'v', 'r', ST_GeomFromText('POINT(94 168)')),
-('y', 'z', 'e', ST_GeomFromText('POINT(141 51)')),
-('h', 'm', 'd', ST_GeomFromText('POINT(35 251)')),
-('v', 'm', 'q', ST_GeomFromText('POINT(44 90)')),
-('j', 'l', 'z', ST_GeomFromText('POINT(67 237)')),
-('i', 'v', 'a', ST_GeomFromText('POINT(75 14)')),
-('b', 'q', 't', ST_GeomFromText('POINT(153 33)')),
-('e', 'm', 'a', ST_GeomFromText('POINT(247 49)')),
-('l', 'y', 'g', ST_GeomFromText('POINT(56 203)')),
-('v', 'o', 'r', ST_GeomFromText('POINT(90 54)')),
-('r', 'n', 'd', ST_GeomFromText('POINT(135 83)')),
-('j', 't', 'u', ST_GeomFromText('POINT(174 239)')),
-('u', 'n', 'g', ST_GeomFromText('POINT(104 191)')),
-('p', 'q', 'y', ST_GeomFromText('POINT(63 171)')),
-('o', 'q', 'p', ST_GeomFromText('POINT(192 103)')),
-('f', 'x', 'e', ST_GeomFromText('POINT(244 30)')),
-('n', 'x', 'c', ST_GeomFromText('POINT(92 103)')),
-('r', 'q', 'z', ST_GeomFromText('POINT(166 20)')),
-('s', 'a', 'j', ST_GeomFromText('POINT(137 205)')),
-('z', 't', 't', ST_GeomFromText('POINT(99 134)')),
-('o', 'm', 'j', ST_GeomFromText('POINT(217 3)')),
-('n', 'h', 'j', ST_GeomFromText('POINT(211 17)')),
-('v', 'v', 'a', ST_GeomFromText('POINT(41 137)')),
-('q', 'o', 'j', ST_GeomFromText('POINT(5 92)')),
-('z', 'y', 'e', ST_GeomFromText('POINT(175 212)')),
-('j', 'z', 'h', ST_GeomFromText('POINT(224 194)')),
-('a', 'g', 'm', ST_GeomFromText('POINT(31 119)')),
-('p', 'c', 'f', ST_GeomFromText('POINT(17 221)')),
-('t', 'h', 'k', ST_GeomFromText('POINT(26 203)')),
-('u', 'w', 'p', ST_GeomFromText('POINT(47 185)')),
-('z', 'a', 'c', ST_GeomFromText('POINT(61 133)')),
-('u', 'k', 'a', ST_GeomFromText('POINT(210 115)')),
-('k', 'f', 'h', ST_GeomFromText('POINT(125 113)')),
-('t', 'v', 'y', ST_GeomFromText('POINT(12 239)')),
-('u', 'v', 'd', ST_GeomFromText('POINT(90 24)')),
-('m', 'y', 'w', ST_GeomFromText('POINT(25 243)')),
-('d', 'n', 'g', ST_GeomFromText('POINT(122 92)')),
-('z', 'm', 'f', ST_GeomFromText('POINT(235 110)')),
-('q', 'd', 'f', ST_GeomFromText('POINT(233 217)')),
-('a', 'v', 'u', ST_GeomFromText('POINT(69 59)')),
-('x', 'k', 'p', ST_GeomFromText('POINT(240 14)')),
-('i', 'v', 'r', ST_GeomFromText('POINT(154 42)')),
-('w', 'h', 'l', ST_GeomFromText('POINT(178 156)')),
-('d', 'h', 'n', ST_GeomFromText('POINT(65 157)')),
-('c', 'k', 'z', ST_GeomFromText('POINT(62 33)')),
-('e', 'l', 'w', ST_GeomFromText('POINT(162 1)')),
-('r', 'f', 'i', ST_GeomFromText('POINT(127 71)')),
-('q', 'm', 'c', ST_GeomFromText('POINT(63 118)')),
-('c', 'h', 'u', ST_GeomFromText('POINT(205 203)')),
-('d', 't', 'p', ST_GeomFromText('POINT(234 87)')),
-('s', 'g', 'h', ST_GeomFromText('POINT(149 34)')),
-('o', 'b', 'q', ST_GeomFromText('POINT(159 179)')),
-('k', 'u', 'f', ST_GeomFromText('POINT(202 254)')),
-('u', 'f', 'g', ST_GeomFromText('POINT(70 15)')),
-('x', 's', 'b', ST_GeomFromText('POINT(25 181)')),
-('s', 'c', 'g', ST_GeomFromText('POINT(252 17)')),
-('a', 'c', 'f', ST_GeomFromText('POINT(89 67)')),
-('r', 'e', 'q', ST_GeomFromText('POINT(55 54)')),
-('f', 'i', 'k', ST_GeomFromText('POINT(178 230)')),
-('p', 'e', 'l', ST_GeomFromText('POINT(198 28)')),
-('w', 'o', 'd', ST_GeomFromText('POINT(204 189)')),
-('c', 'a', 'g', ST_GeomFromText('POINT(230 178)')),
-('r', 'o', 'e', ST_GeomFromText('POINT(61 116)')),
-('w', 'a', 'a', ST_GeomFromText('POINT(178 237)')),
-('v', 'd', 'e', ST_GeomFromText('POINT(70 85)')),
-('k', 'c', 'e', ST_GeomFromText('POINT(147 118)')),
-('d', 'q', 't', ST_GeomFromText('POINT(218 77)')),
-('k', 'g', 'f', ST_GeomFromText('POINT(192 113)')),
-('w', 'n', 'e', ST_GeomFromText('POINT(92 124)')),
-('r', 'm', 'q', ST_GeomFromText('POINT(130 65)')),
-('o', 'r', 'r', ST_GeomFromText('POINT(174 233)')),
-('k', 'n', 't', ST_GeomFromText('POINT(175 147)')),
-('q', 'm', 'r', ST_GeomFromText('POINT(18 208)')),
-('l', 'd', 'i', ST_GeomFromText('POINT(13 104)')),
-('w', 'o', 'y', ST_GeomFromText('POINT(207 39)')),
-('p', 'u', 'o', ST_GeomFromText('POINT(114 31)')),
-('y', 'a', 'p', ST_GeomFromText('POINT(106 59)')),
-('a', 'x', 'z', ST_GeomFromText('POINT(17 57)')),
-('v', 'h', 'x', ST_GeomFromText('POINT(170 13)')),
-('t', 's', 'u', ST_GeomFromText('POINT(84 18)')),
-('z', 'z', 'f', ST_GeomFromText('POINT(250 197)')),
-('l', 'z', 't', ST_GeomFromText('POINT(59 80)')),
-('j', 'g', 's', ST_GeomFromText('POINT(54 26)')),
-('g', 'v', 'm', ST_GeomFromText('POINT(89 98)')),
-('q', 'v', 'b', ST_GeomFromText('POINT(39 240)')),
-('x', 'k', 'v', ST_GeomFromText('POINT(246 207)')),
-('k', 'u', 'i', ST_GeomFromText('POINT(105 111)')),
-('w', 'z', 's', ST_GeomFromText('POINT(235 8)')),
-('d', 'd', 'd', ST_GeomFromText('POINT(105 4)')),
-('c', 'z', 'q', ST_GeomFromText('POINT(13 140)')),
-('m', 'k', 'i', ST_GeomFromText('POINT(208 120)')),
-('g', 'a', 'g', ST_GeomFromText('POINT(9 182)')),
-('z', 'j', 'r', ST_GeomFromText('POINT(149 153)')),
-('h', 'f', 'g', ST_GeomFromText('POINT(81 236)')),
-('m', 'e', 'q', ST_GeomFromText('POINT(209 215)')),
-('c', 'h', 'y', ST_GeomFromText('POINT(235 70)')),
-('i', 'e', 'g', ST_GeomFromText('POINT(138 26)')),
-('m', 't', 'u', ST_GeomFromText('POINT(119 237)')),
-('o', 'w', 's', ST_GeomFromText('POINT(193 166)')),
-('f', 'm', 'q', ST_GeomFromText('POINT(85 96)')),
-('x', 'l', 'x', ST_GeomFromText('POINT(58 115)')),
-('x', 'q', 'u', ST_GeomFromText('POINT(108 210)')),
-('b', 'h', 'i', ST_GeomFromText('POINT(250 139)')),
-('y', 'd', 'x', ST_GeomFromText('POINT(199 135)')),
-('w', 'h', 'p', ST_GeomFromText('POINT(247 233)')),
-('p', 'z', 't', ST_GeomFromText('POINT(148 249)')),
-('q', 'a', 'u', ST_GeomFromText('POINT(174 78)')),
-('v', 't', 'm', ST_GeomFromText('POINT(70 228)')),
-('t', 'n', 'f', ST_GeomFromText('POINT(123 2)')),
-('x', 't', 'b', ST_GeomFromText('POINT(35 50)')),
-('r', 'j', 'f', ST_GeomFromText('POINT(200 51)')),
-('s', 'q', 'o', ST_GeomFromText('POINT(23 184)')),
-('u', 'v', 'z', ST_GeomFromText('POINT(7 113)')),
-('v', 'u', 'l', ST_GeomFromText('POINT(145 190)')),
-('o', 'k', 'i', ST_GeomFromText('POINT(161 122)')),
-('l', 'y', 'e', ST_GeomFromText('POINT(17 232)')),
-('t', 'b', 'e', ST_GeomFromText('POINT(120 50)')),
-('e', 's', 'u', ST_GeomFromText('POINT(254 1)')),
-('d', 'd', 'u', ST_GeomFromText('POINT(167 140)')),
-('o', 'b', 'x', ST_GeomFromText('POINT(186 237)')),
-('m', 's', 's', ST_GeomFromText('POINT(172 149)')),
-('t', 'y', 'a', ST_GeomFromText('POINT(149 85)')),
-('x', 't', 'r', ST_GeomFromText('POINT(10 165)')),
-('g', 'c', 'e', ST_GeomFromText('POINT(95 165)')),
-('e', 'e', 'z', ST_GeomFromText('POINT(98 65)')),
-('f', 'v', 'i', ST_GeomFromText('POINT(149 144)')),
-('o', 'p', 'm', ST_GeomFromText('POINT(233 67)')),
-('t', 'u', 'b', ST_GeomFromText('POINT(109 215)')),
-('o', 'o', 'b', ST_GeomFromText('POINT(130 48)')),
-('e', 'm', 'h', ST_GeomFromText('POINT(88 189)')),
-('e', 'v', 'y', ST_GeomFromText('POINT(55 29)')),
-('e', 't', 'm', ST_GeomFromText('POINT(129 55)')),
-('p', 'p', 'i', ST_GeomFromText('POINT(126 222)')),
-('c', 'i', 'c', ST_GeomFromText('POINT(19 158)')),
-('c', 'b', 's', ST_GeomFromText('POINT(13 19)')),
-('u', 'y', 'a', ST_GeomFromText('POINT(114 5)')),
-('a', 'o', 'f', ST_GeomFromText('POINT(227 232)')),
-('t', 'c', 'z', ST_GeomFromText('POINT(63 62)')),
-('d', 'o', 'k', ST_GeomFromText('POINT(48 228)')),
-('x', 'c', 'e', ST_GeomFromText('POINT(204 2)')),
-('e', 'e', 'g', ST_GeomFromText('POINT(125 43)')),
-('o', 'r', 'f', ST_GeomFromText('POINT(171 140)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('b', 'c', 'e', ST_GeomFromText('POINT(41 137)')),
-('p', 'y', 'k', ST_GeomFromText('POINT(50 22)')),
-('s', 'c', 'h', ST_GeomFromText('POINT(208 173)')),
-('x', 'u', 'l', ST_GeomFromText('POINT(199 175)')),
-('s', 'r', 'h', ST_GeomFromText('POINT(85 192)')),
-('j', 'k', 'u', ST_GeomFromText('POINT(18 25)')),
-('p', 'w', 'h', ST_GeomFromText('POINT(152 197)')),
-('e', 'd', 'c', ST_GeomFromText('POINT(229 3)')),
-('o', 'x', 'k', ST_GeomFromText('POINT(187 155)')),
-('o', 'b', 'k', ST_GeomFromText('POINT(208 150)')),
-('d', 'a', 'j', ST_GeomFromText('POINT(70 87)')),
-('f', 'e', 'k', ST_GeomFromText('POINT(156 96)')),
-('u', 'y', 'p', ST_GeomFromText('POINT(239 193)')),
-('n', 'v', 'p', ST_GeomFromText('POINT(223 98)')),
-('z', 'j', 'r', ST_GeomFromText('POINT(87 89)')),
-('h', 'x', 'x', ST_GeomFromText('POINT(92 0)')),
-('r', 'v', 'r', ST_GeomFromText('POINT(159 139)')),
-('v', 'g', 'g', ST_GeomFromText('POINT(16 229)')),
-('z', 'k', 'u', ST_GeomFromText('POINT(99 52)')),
-('p', 'p', 'o', ST_GeomFromText('POINT(105 125)')),
-('w', 'h', 'y', ST_GeomFromText('POINT(105 154)')),
-('v', 'y', 'z', ST_GeomFromText('POINT(134 238)')),
-('x', 'o', 'o', ST_GeomFromText('POINT(178 88)')),
-('z', 'w', 'd', ST_GeomFromText('POINT(123 60)')),
-('q', 'f', 'u', ST_GeomFromText('POINT(64 90)')),
-('s', 'n', 't', ST_GeomFromText('POINT(50 138)')),
-('v', 'p', 't', ST_GeomFromText('POINT(114 91)')),
-('a', 'o', 'n', ST_GeomFromText('POINT(78 43)')),
-('k', 'u', 'd', ST_GeomFromText('POINT(185 161)')),
-('w', 'd', 'n', ST_GeomFromText('POINT(25 92)')),
-('k', 'w', 'a', ST_GeomFromText('POINT(59 238)')),
-('t', 'c', 'f', ST_GeomFromText('POINT(65 87)')),
-('g', 's', 'p', ST_GeomFromText('POINT(238 126)')),
-('d', 'n', 'y', ST_GeomFromText('POINT(107 173)')),
-('l', 'a', 'w', ST_GeomFromText('POINT(125 152)')),
-('m', 'd', 'j', ST_GeomFromText('POINT(146 53)')),
-('q', 'm', 'c', ST_GeomFromText('POINT(217 187)')),
-('i', 'r', 'r', ST_GeomFromText('POINT(6 113)')),
-('e', 'j', 'b', ST_GeomFromText('POINT(37 83)')),
-('w', 'w', 'h', ST_GeomFromText('POINT(83 199)')),
-('k', 'b', 's', ST_GeomFromText('POINT(170 64)')),
-('s', 'b', 'c', ST_GeomFromText('POINT(163 130)')),
-('c', 'h', 'a', ST_GeomFromText('POINT(141 3)')),
-('k', 'j', 'u', ST_GeomFromText('POINT(143 76)')),
-('r', 'h', 'o', ST_GeomFromText('POINT(243 92)')),
-('i', 'd', 'b', ST_GeomFromText('POINT(205 13)')),
-('r', 'y', 'q', ST_GeomFromText('POINT(138 8)')),
-('m', 'o', 'i', ST_GeomFromText('POINT(36 45)')),
-('v', 'g', 'm', ST_GeomFromText('POINT(0 40)')),
-('f', 'e', 'i', ST_GeomFromText('POINT(76 6)')),
-('c', 'q', 'q', ST_GeomFromText('POINT(115 248)')),
-('x', 'c', 'i', ST_GeomFromText('POINT(29 74)')),
-('l', 's', 't', ST_GeomFromText('POINT(83 18)')),
-('t', 't', 'a', ST_GeomFromText('POINT(26 168)')),
-('u', 'n', 'x', ST_GeomFromText('POINT(200 110)')),
-('j', 'b', 'd', ST_GeomFromText('POINT(216 136)')),
-('s', 'p', 'w', ST_GeomFromText('POINT(38 156)')),
-('f', 'b', 'v', ST_GeomFromText('POINT(29 186)')),
-('v', 'e', 'r', ST_GeomFromText('POINT(149 40)')),
-('v', 't', 'm', ST_GeomFromText('POINT(184 24)')),
-('y', 'g', 'a', ST_GeomFromText('POINT(219 105)')),
-('s', 'f', 'i', ST_GeomFromText('POINT(114 130)')),
-('e', 'q', 'h', ST_GeomFromText('POINT(203 135)')),
-('h', 'g', 'b', ST_GeomFromText('POINT(9 208)')),
-('o', 'l', 'r', ST_GeomFromText('POINT(245 79)')),
-('s', 's', 'v', ST_GeomFromText('POINT(238 198)')),
-('w', 'w', 'z', ST_GeomFromText('POINT(209 232)')),
-('v', 'd', 'n', ST_GeomFromText('POINT(30 193)')),
-('q', 'w', 'k', ST_GeomFromText('POINT(133 18)')),
-('o', 'h', 'o', ST_GeomFromText('POINT(42 140)')),
-('f', 'f', 'h', ST_GeomFromText('POINT(145 1)')),
-('u', 's', 'r', ST_GeomFromText('POINT(70 62)')),
-('x', 'n', 'q', ST_GeomFromText('POINT(33 86)')),
-('u', 'p', 'v', ST_GeomFromText('POINT(232 220)')),
-('z', 'e', 'a', ST_GeomFromText('POINT(130 69)')),
-('r', 'u', 'z', ST_GeomFromText('POINT(243 241)')),
-('b', 'n', 't', ST_GeomFromText('POINT(120 12)')),
-('u', 'f', 's', ST_GeomFromText('POINT(190 212)')),
-('a', 'd', 'q', ST_GeomFromText('POINT(235 191)')),
-('f', 'q', 'm', ST_GeomFromText('POINT(176 2)')),
-('n', 'c', 's', ST_GeomFromText('POINT(218 163)')),
-('e', 'm', 'h', ST_GeomFromText('POINT(163 108)')),
-('c', 'f', 'l', ST_GeomFromText('POINT(220 115)')),
-('c', 'v', 'q', ST_GeomFromText('POINT(66 45)')),
-('w', 'v', 'x', ST_GeomFromText('POINT(251 220)')),
-('f', 'w', 'z', ST_GeomFromText('POINT(146 149)')),
-('h', 'n', 'h', ST_GeomFromText('POINT(148 128)')),
-('y', 'k', 'v', ST_GeomFromText('POINT(28 110)')),
-('c', 'x', 'q', ST_GeomFromText('POINT(13 13)')),
-('e', 'd', 's', ST_GeomFromText('POINT(91 190)')),
-('c', 'w', 'c', ST_GeomFromText('POINT(10 231)')),
-('u', 'j', 'n', ST_GeomFromText('POINT(250 21)')),
-('w', 'n', 'x', ST_GeomFromText('POINT(141 69)')),
-('f', 'p', 'y', ST_GeomFromText('POINT(228 246)')),
-('d', 'q', 'f', ST_GeomFromText('POINT(194 22)')),
-('d', 'z', 'l', ST_GeomFromText('POINT(233 181)')),
-('c', 'a', 'q', ST_GeomFromText('POINT(183 96)')),
-('m', 'i', 'd', ST_GeomFromText('POINT(117 226)')),
-('z', 'y', 'y', ST_GeomFromText('POINT(62 81)')),
-('g', 'v', 'm', ST_GeomFromText('POINT(66 158)'));
-START TRANSACTION;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'x', 'p', ST_GeomFromText('POINT(92 181)'));
-ROLLBACK;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'x', 'p', ST_GeomFromText('POINT(92 181)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES ('n', 'x', 'p', ST_GeomFromText('POINT(0 1280)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES ('n', 'x', 'p', ST_GeomFromText('POINT(45 1280)'));
-INSERT INTO t1 VALUES (1280, 'n', 'x', 'p', ST_GeomFromText('POINT(44 253)'));
-DELETE FROM t1 WHERE id = 1280;
-INSERT INTO t1 VALUES (1280, 'n', 'x', 'p', ST_GeomFromText('POINT(44 253)'));
-START TRANSACTION;
-DELETE FROM t1 WHERE id = 1280;
-ROLLBACK;
-START TRANSACTION;
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
-('m', 'u', 'p', ST_GeomFromText('POINT(1192 1181)'));
-ROLLBACK;
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-353
-UPDATE t1 SET spatial_point = ST_GeomFromText('POINT(123 456)') WHERE id < 2000;
-SET @g1 = ST_GeomFromText('Polygon((123 456, 123 678, 456 678,456 456,123 456))');
-DELETE FROM t1 WHERE MBRContains(@g1, t1.spatial_point);
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-353
-DROP TABLE t1;
-SET GLOBAL innodb_file_per_table=default;
-SET GLOBAL innodb_file_format=default;
-Warnings:
-Warning 131 Using innodb_file_format is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html
-SET GLOBAL innodb_file_per_table='on';
-SET GLOBAL innodb_file_format='Barracuda';
-Warnings:
-Warning 131 Using innodb_file_format is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html
-CREATE TABLE t1 (
-id bigint(12) unsigned NOT NULL auto_increment,
-c2 varchar(15) collate utf8_bin DEFAULT NULL,
-c1 varchar(15) collate utf8_bin DEFAULT NULL,
-c3 varchar(10) collate utf8_bin DEFAULT NULL,
-spatial_point point NOT NULL,
-PRIMARY KEY(id),
-SPATIAL KEY (spatial_point)
-) ROW_FORMAT=COMPRESSED ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('y', 's', 'j', ST_GeomFromText('POINT(167 74)')),
-('r', 'n', 'd', ST_GeomFromText('POINT(215 118)')),
-('g', 'n', 'e', ST_GeomFromText('POINT(203 98)')),
-('h', 'd', 'd', ST_GeomFromText('POINT(54 193)')),
-('r', 'x', 'y', ST_GeomFromText('POINT(47 69)')),
-('t', 'q', 'r', ST_GeomFromText('POINT(109 42)')),
-('a', 'z', 'd', ST_GeomFromText('POINT(0 154)')),
-('x', 'v', 'o', ST_GeomFromText('POINT(174 131)')),
-('b', 'r', 'a', ST_GeomFromText('POINT(114 253)')),
-('x', 'z', 'i', ST_GeomFromText('POINT(163 21)')),
-('w', 'p', 'i', ST_GeomFromText('POINT(42 102)')),
-('g', 'j', 'j', ST_GeomFromText('POINT(170 133)')),
-('m', 'g', 'n', ST_GeomFromText('POINT(28 22)')),
-('b', 'z', 'h', ST_GeomFromText('POINT(174 28)')),
-('q', 'k', 'f', ST_GeomFromText('POINT(233 73)')),
-('w', 'w', 'a', ST_GeomFromText('POINT(124 200)')),
-('t', 'j', 'w', ST_GeomFromText('POINT(252 101)')),
-('d', 'r', 'd', ST_GeomFromText('POINT(98 18)')),
-('w', 'o', 'y', ST_GeomFromText('POINT(165 31)')),
-('y', 'h', 't', ST_GeomFromText('POINT(14 220)')),
-('d', 'p', 'u', ST_GeomFromText('POINT(223 196)')),
-('g', 'y', 'g', ST_GeomFromText('POINT(207 96)')),
-('x', 'm', 'n', ST_GeomFromText('POINT(214 3)')),
-('g', 'v', 'e', ST_GeomFromText('POINT(140 205)')),
-('g', 'm', 'm', ST_GeomFromText('POINT(10 236)')),
-('i', 'r', 'j', ST_GeomFromText('POINT(137 228)')),
-('w', 's', 'p', ST_GeomFromText('POINT(115 6)')),
-('o', 'n', 'k', ST_GeomFromText('POINT(158 129)')),
-('j', 'h', 'l', ST_GeomFromText('POINT(129 72)')),
-('f', 'x', 'l', ST_GeomFromText('POINT(139 207)')),
-('u', 'd', 'n', ST_GeomFromText('POINT(125 109)')),
-('b', 'a', 'z', ST_GeomFromText('POINT(30 32)')),
-('m', 'h', 'o', ST_GeomFromText('POINT(251 251)')),
-('f', 'r', 'd', ST_GeomFromText('POINT(243 211)')),
-('b', 'd', 'r', ST_GeomFromText('POINT(232 80)')),
-('g', 'k', 'v', ST_GeomFromText('POINT(15 100)')),
-('i', 'f', 'c', ST_GeomFromText('POINT(109 66)')),
-('r', 't', 'j', ST_GeomFromText('POINT(178 6)')),
-('y', 'n', 'f', ST_GeomFromText('POINT(233 211)')),
-('f', 'y', 'm', ST_GeomFromText('POINT(99 16)')),
-('z', 'q', 'l', ST_GeomFromText('POINT(39 49)')),
-('j', 'c', 'r', ST_GeomFromText('POINT(75 187)')),
-('c', 'y', 'y', ST_GeomFromText('POINT(246 253)')),
-('w', 'u', 'd', ST_GeomFromText('POINT(56 190)')),
-('n', 'q', 'm', ST_GeomFromText('POINT(73 149)')),
-('d', 'y', 'a', ST_GeomFromText('POINT(134 6)')),
-('z', 's', 'w', ST_GeomFromText('POINT(216 225)')),
-('d', 'u', 'k', ST_GeomFromText('POINT(132 70)')),
-('f', 'v', 't', ST_GeomFromText('POINT(187 141)')),
-('r', 'r', 'a', ST_GeomFromText('POINT(152 39)')),
-('y', 'p', 'o', ST_GeomFromText('POINT(45 27)')),
-('p', 'n', 'm', ST_GeomFromText('POINT(228 148)')),
-('e', 'g', 'e', ST_GeomFromText('POINT(88 81)')),
-('m', 'a', 'h', ST_GeomFromText('POINT(35 29)')),
-('m', 'h', 'f', ST_GeomFromText('POINT(30 71)')),
-('h', 'k', 'i', ST_GeomFromText('POINT(244 78)')),
-('z', 'v', 'd', ST_GeomFromText('POINT(241 38)')),
-('q', 'l', 'j', ST_GeomFromText('POINT(13 71)')),
-('s', 'p', 'g', ST_GeomFromText('POINT(108 38)')),
-('q', 's', 'j', ST_GeomFromText('POINT(92 101)')),
-('l', 'h', 'g', ST_GeomFromText('POINT(120 78)')),
-('w', 't', 'b', ST_GeomFromText('POINT(193 109)')),
-('b', 's', 's', ST_GeomFromText('POINT(223 211)')),
-('w', 'w', 'y', ST_GeomFromText('POINT(122 42)')),
-('q', 'c', 'c', ST_GeomFromText('POINT(104 102)')),
-('w', 'g', 'n', ST_GeomFromText('POINT(213 120)')),
-('p', 'q', 'a', ST_GeomFromText('POINT(247 148)')),
-('c', 'z', 'e', ST_GeomFromText('POINT(18 106)')),
-('z', 'u', 'n', ST_GeomFromText('POINT(70 133)')),
-('j', 'n', 'x', ST_GeomFromText('POINT(232 13)')),
-('e', 'h', 'f', ST_GeomFromText('POINT(22 135)')),
-('w', 'l', 'f', ST_GeomFromText('POINT(9 180)')),
-('a', 'v', 'q', ST_GeomFromText('POINT(163 228)')),
-('i', 'z', 'o', ST_GeomFromText('POINT(180 100)')),
-('e', 'c', 'l', ST_GeomFromText('POINT(182 231)')),
-('c', 'k', 'o', ST_GeomFromText('POINT(19 60)')),
-('q', 'f', 'p', ST_GeomFromText('POINT(79 95)')),
-('m', 'd', 'r', ST_GeomFromText('POINT(3 127)')),
-('m', 'e', 't', ST_GeomFromText('POINT(136 154)')),
-('w', 'w', 'w', ST_GeomFromText('POINT(102 15)')),
-('l', 'n', 'q', ST_GeomFromText('POINT(71 196)')),
-('p', 'k', 'c', ST_GeomFromText('POINT(47 139)')),
-('j', 'o', 'r', ST_GeomFromText('POINT(177 128)')),
-('j', 'q', 'a', ST_GeomFromText('POINT(170 6)')),
-('b', 'a', 'o', ST_GeomFromText('POINT(63 211)')),
-('g', 's', 'o', ST_GeomFromText('POINT(144 251)')),
-('w', 'u', 'w', ST_GeomFromText('POINT(221 214)')),
-('g', 'a', 'm', ST_GeomFromText('POINT(14 102)')),
-('u', 'q', 'z', ST_GeomFromText('POINT(86 200)')),
-('k', 'a', 'm', ST_GeomFromText('POINT(144 222)')),
-('j', 'u', 'r', ST_GeomFromText('POINT(216 142)')),
-('q', 'k', 'v', ST_GeomFromText('POINT(121 236)')),
-('p', 'o', 'r', ST_GeomFromText('POINT(108 102)')),
-('b', 'd', 'x', ST_GeomFromText('POINT(127 198)')),
-('k', 's', 'a', ST_GeomFromText('POINT(2 150)')),
-('f', 'm', 'f', ST_GeomFromText('POINT(160 191)')),
-('q', 'y', 'x', ST_GeomFromText('POINT(98 111)')),
-('o', 'f', 'm', ST_GeomFromText('POINT(232 218)')),
-('c', 'w', 'j', ST_GeomFromText('POINT(156 165)')),
-('s', 'q', 'v', ST_GeomFromText('POINT(98 161)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'y', 'p', ST_GeomFromText('POINT(109 235)')),
-('b', 'e', 'v', ST_GeomFromText('POINT(20 48)')),
-('i', 'u', 'f', ST_GeomFromText('POINT(15 55)')),
-('o', 'r', 'z', ST_GeomFromText('POINT(105 64)')),
-('a', 'p', 'a', ST_GeomFromText('POINT(142 236)')),
-('g', 'i', 'k', ST_GeomFromText('POINT(10 49)')),
-('x', 'z', 'x', ST_GeomFromText('POINT(192 200)')),
-('c', 'v', 'r', ST_GeomFromText('POINT(94 168)')),
-('y', 'z', 'e', ST_GeomFromText('POINT(141 51)')),
-('h', 'm', 'd', ST_GeomFromText('POINT(35 251)')),
-('v', 'm', 'q', ST_GeomFromText('POINT(44 90)')),
-('j', 'l', 'z', ST_GeomFromText('POINT(67 237)')),
-('i', 'v', 'a', ST_GeomFromText('POINT(75 14)')),
-('b', 'q', 't', ST_GeomFromText('POINT(153 33)')),
-('e', 'm', 'a', ST_GeomFromText('POINT(247 49)')),
-('l', 'y', 'g', ST_GeomFromText('POINT(56 203)')),
-('v', 'o', 'r', ST_GeomFromText('POINT(90 54)')),
-('r', 'n', 'd', ST_GeomFromText('POINT(135 83)')),
-('j', 't', 'u', ST_GeomFromText('POINT(174 239)')),
-('u', 'n', 'g', ST_GeomFromText('POINT(104 191)')),
-('p', 'q', 'y', ST_GeomFromText('POINT(63 171)')),
-('o', 'q', 'p', ST_GeomFromText('POINT(192 103)')),
-('f', 'x', 'e', ST_GeomFromText('POINT(244 30)')),
-('n', 'x', 'c', ST_GeomFromText('POINT(92 103)')),
-('r', 'q', 'z', ST_GeomFromText('POINT(166 20)')),
-('s', 'a', 'j', ST_GeomFromText('POINT(137 205)')),
-('z', 't', 't', ST_GeomFromText('POINT(99 134)')),
-('o', 'm', 'j', ST_GeomFromText('POINT(217 3)')),
-('n', 'h', 'j', ST_GeomFromText('POINT(211 17)')),
-('v', 'v', 'a', ST_GeomFromText('POINT(41 137)')),
-('q', 'o', 'j', ST_GeomFromText('POINT(5 92)')),
-('z', 'y', 'e', ST_GeomFromText('POINT(175 212)')),
-('j', 'z', 'h', ST_GeomFromText('POINT(224 194)')),
-('a', 'g', 'm', ST_GeomFromText('POINT(31 119)')),
-('p', 'c', 'f', ST_GeomFromText('POINT(17 221)')),
-('t', 'h', 'k', ST_GeomFromText('POINT(26 203)')),
-('u', 'w', 'p', ST_GeomFromText('POINT(47 185)')),
-('z', 'a', 'c', ST_GeomFromText('POINT(61 133)')),
-('u', 'k', 'a', ST_GeomFromText('POINT(210 115)')),
-('k', 'f', 'h', ST_GeomFromText('POINT(125 113)')),
-('t', 'v', 'y', ST_GeomFromText('POINT(12 239)')),
-('u', 'v', 'd', ST_GeomFromText('POINT(90 24)')),
-('m', 'y', 'w', ST_GeomFromText('POINT(25 243)')),
-('d', 'n', 'g', ST_GeomFromText('POINT(122 92)')),
-('z', 'm', 'f', ST_GeomFromText('POINT(235 110)')),
-('q', 'd', 'f', ST_GeomFromText('POINT(233 217)')),
-('a', 'v', 'u', ST_GeomFromText('POINT(69 59)')),
-('x', 'k', 'p', ST_GeomFromText('POINT(240 14)')),
-('i', 'v', 'r', ST_GeomFromText('POINT(154 42)')),
-('w', 'h', 'l', ST_GeomFromText('POINT(178 156)')),
-('d', 'h', 'n', ST_GeomFromText('POINT(65 157)')),
-('c', 'k', 'z', ST_GeomFromText('POINT(62 33)')),
-('e', 'l', 'w', ST_GeomFromText('POINT(162 1)')),
-('r', 'f', 'i', ST_GeomFromText('POINT(127 71)')),
-('q', 'm', 'c', ST_GeomFromText('POINT(63 118)')),
-('c', 'h', 'u', ST_GeomFromText('POINT(205 203)')),
-('d', 't', 'p', ST_GeomFromText('POINT(234 87)')),
-('s', 'g', 'h', ST_GeomFromText('POINT(149 34)')),
-('o', 'b', 'q', ST_GeomFromText('POINT(159 179)')),
-('k', 'u', 'f', ST_GeomFromText('POINT(202 254)')),
-('u', 'f', 'g', ST_GeomFromText('POINT(70 15)')),
-('x', 's', 'b', ST_GeomFromText('POINT(25 181)')),
-('s', 'c', 'g', ST_GeomFromText('POINT(252 17)')),
-('a', 'c', 'f', ST_GeomFromText('POINT(89 67)')),
-('r', 'e', 'q', ST_GeomFromText('POINT(55 54)')),
-('f', 'i', 'k', ST_GeomFromText('POINT(178 230)')),
-('p', 'e', 'l', ST_GeomFromText('POINT(198 28)')),
-('w', 'o', 'd', ST_GeomFromText('POINT(204 189)')),
-('c', 'a', 'g', ST_GeomFromText('POINT(230 178)')),
-('r', 'o', 'e', ST_GeomFromText('POINT(61 116)')),
-('w', 'a', 'a', ST_GeomFromText('POINT(178 237)')),
-('v', 'd', 'e', ST_GeomFromText('POINT(70 85)')),
-('k', 'c', 'e', ST_GeomFromText('POINT(147 118)')),
-('d', 'q', 't', ST_GeomFromText('POINT(218 77)')),
-('k', 'g', 'f', ST_GeomFromText('POINT(192 113)')),
-('w', 'n', 'e', ST_GeomFromText('POINT(92 124)')),
-('r', 'm', 'q', ST_GeomFromText('POINT(130 65)')),
-('o', 'r', 'r', ST_GeomFromText('POINT(174 233)')),
-('k', 'n', 't', ST_GeomFromText('POINT(175 147)')),
-('q', 'm', 'r', ST_GeomFromText('POINT(18 208)')),
-('l', 'd', 'i', ST_GeomFromText('POINT(13 104)')),
-('w', 'o', 'y', ST_GeomFromText('POINT(207 39)')),
-('p', 'u', 'o', ST_GeomFromText('POINT(114 31)')),
-('y', 'a', 'p', ST_GeomFromText('POINT(106 59)')),
-('a', 'x', 'z', ST_GeomFromText('POINT(17 57)')),
-('v', 'h', 'x', ST_GeomFromText('POINT(170 13)')),
-('t', 's', 'u', ST_GeomFromText('POINT(84 18)')),
-('z', 'z', 'f', ST_GeomFromText('POINT(250 197)')),
-('l', 'z', 't', ST_GeomFromText('POINT(59 80)')),
-('j', 'g', 's', ST_GeomFromText('POINT(54 26)')),
-('g', 'v', 'm', ST_GeomFromText('POINT(89 98)')),
-('q', 'v', 'b', ST_GeomFromText('POINT(39 240)')),
-('x', 'k', 'v', ST_GeomFromText('POINT(246 207)')),
-('k', 'u', 'i', ST_GeomFromText('POINT(105 111)')),
-('w', 'z', 's', ST_GeomFromText('POINT(235 8)')),
-('d', 'd', 'd', ST_GeomFromText('POINT(105 4)')),
-('c', 'z', 'q', ST_GeomFromText('POINT(13 140)')),
-('m', 'k', 'i', ST_GeomFromText('POINT(208 120)')),
-('g', 'a', 'g', ST_GeomFromText('POINT(9 182)')),
-('z', 'j', 'r', ST_GeomFromText('POINT(149 153)')),
-('h', 'f', 'g', ST_GeomFromText('POINT(81 236)')),
-('m', 'e', 'q', ST_GeomFromText('POINT(209 215)')),
-('c', 'h', 'y', ST_GeomFromText('POINT(235 70)')),
-('i', 'e', 'g', ST_GeomFromText('POINT(138 26)')),
-('m', 't', 'u', ST_GeomFromText('POINT(119 237)')),
-('o', 'w', 's', ST_GeomFromText('POINT(193 166)')),
-('f', 'm', 'q', ST_GeomFromText('POINT(85 96)')),
-('x', 'l', 'x', ST_GeomFromText('POINT(58 115)')),
-('x', 'q', 'u', ST_GeomFromText('POINT(108 210)')),
-('b', 'h', 'i', ST_GeomFromText('POINT(250 139)')),
-('y', 'd', 'x', ST_GeomFromText('POINT(199 135)')),
-('w', 'h', 'p', ST_GeomFromText('POINT(247 233)')),
-('p', 'z', 't', ST_GeomFromText('POINT(148 249)')),
-('q', 'a', 'u', ST_GeomFromText('POINT(174 78)')),
-('v', 't', 'm', ST_GeomFromText('POINT(70 228)')),
-('t', 'n', 'f', ST_GeomFromText('POINT(123 2)')),
-('x', 't', 'b', ST_GeomFromText('POINT(35 50)')),
-('r', 'j', 'f', ST_GeomFromText('POINT(200 51)')),
-('s', 'q', 'o', ST_GeomFromText('POINT(23 184)')),
-('u', 'v', 'z', ST_GeomFromText('POINT(7 113)')),
-('v', 'u', 'l', ST_GeomFromText('POINT(145 190)')),
-('o', 'k', 'i', ST_GeomFromText('POINT(161 122)')),
-('l', 'y', 'e', ST_GeomFromText('POINT(17 232)')),
-('t', 'b', 'e', ST_GeomFromText('POINT(120 50)')),
-('e', 's', 'u', ST_GeomFromText('POINT(254 1)')),
-('d', 'd', 'u', ST_GeomFromText('POINT(167 140)')),
-('o', 'b', 'x', ST_GeomFromText('POINT(186 237)')),
-('m', 's', 's', ST_GeomFromText('POINT(172 149)')),
-('t', 'y', 'a', ST_GeomFromText('POINT(149 85)')),
-('x', 't', 'r', ST_GeomFromText('POINT(10 165)')),
-('g', 'c', 'e', ST_GeomFromText('POINT(95 165)')),
-('e', 'e', 'z', ST_GeomFromText('POINT(98 65)')),
-('f', 'v', 'i', ST_GeomFromText('POINT(149 144)')),
-('o', 'p', 'm', ST_GeomFromText('POINT(233 67)')),
-('t', 'u', 'b', ST_GeomFromText('POINT(109 215)')),
-('o', 'o', 'b', ST_GeomFromText('POINT(130 48)')),
-('e', 'm', 'h', ST_GeomFromText('POINT(88 189)')),
-('e', 'v', 'y', ST_GeomFromText('POINT(55 29)')),
-('e', 't', 'm', ST_GeomFromText('POINT(129 55)')),
-('p', 'p', 'i', ST_GeomFromText('POINT(126 222)')),
-('c', 'i', 'c', ST_GeomFromText('POINT(19 158)')),
-('c', 'b', 's', ST_GeomFromText('POINT(13 19)')),
-('u', 'y', 'a', ST_GeomFromText('POINT(114 5)')),
-('a', 'o', 'f', ST_GeomFromText('POINT(227 232)')),
-('t', 'c', 'z', ST_GeomFromText('POINT(63 62)')),
-('d', 'o', 'k', ST_GeomFromText('POINT(48 228)')),
-('x', 'c', 'e', ST_GeomFromText('POINT(204 2)')),
-('e', 'e', 'g', ST_GeomFromText('POINT(125 43)')),
-('o', 'r', 'f', ST_GeomFromText('POINT(171 140)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('b', 'c', 'e', ST_GeomFromText('POINT(41 137)')),
-('p', 'y', 'k', ST_GeomFromText('POINT(50 22)')),
-('s', 'c', 'h', ST_GeomFromText('POINT(208 173)')),
-('x', 'u', 'l', ST_GeomFromText('POINT(199 175)')),
-('s', 'r', 'h', ST_GeomFromText('POINT(85 192)')),
-('j', 'k', 'u', ST_GeomFromText('POINT(18 25)')),
-('p', 'w', 'h', ST_GeomFromText('POINT(152 197)')),
-('e', 'd', 'c', ST_GeomFromText('POINT(229 3)')),
-('o', 'x', 'k', ST_GeomFromText('POINT(187 155)')),
-('o', 'b', 'k', ST_GeomFromText('POINT(208 150)')),
-('d', 'a', 'j', ST_GeomFromText('POINT(70 87)')),
-('f', 'e', 'k', ST_GeomFromText('POINT(156 96)')),
-('u', 'y', 'p', ST_GeomFromText('POINT(239 193)')),
-('n', 'v', 'p', ST_GeomFromText('POINT(223 98)')),
-('z', 'j', 'r', ST_GeomFromText('POINT(87 89)')),
-('h', 'x', 'x', ST_GeomFromText('POINT(92 0)')),
-('r', 'v', 'r', ST_GeomFromText('POINT(159 139)')),
-('v', 'g', 'g', ST_GeomFromText('POINT(16 229)')),
-('z', 'k', 'u', ST_GeomFromText('POINT(99 52)')),
-('p', 'p', 'o', ST_GeomFromText('POINT(105 125)')),
-('w', 'h', 'y', ST_GeomFromText('POINT(105 154)')),
-('v', 'y', 'z', ST_GeomFromText('POINT(134 238)')),
-('x', 'o', 'o', ST_GeomFromText('POINT(178 88)')),
-('z', 'w', 'd', ST_GeomFromText('POINT(123 60)')),
-('q', 'f', 'u', ST_GeomFromText('POINT(64 90)')),
-('s', 'n', 't', ST_GeomFromText('POINT(50 138)')),
-('v', 'p', 't', ST_GeomFromText('POINT(114 91)')),
-('a', 'o', 'n', ST_GeomFromText('POINT(78 43)')),
-('k', 'u', 'd', ST_GeomFromText('POINT(185 161)')),
-('w', 'd', 'n', ST_GeomFromText('POINT(25 92)')),
-('k', 'w', 'a', ST_GeomFromText('POINT(59 238)')),
-('t', 'c', 'f', ST_GeomFromText('POINT(65 87)')),
-('g', 's', 'p', ST_GeomFromText('POINT(238 126)')),
-('d', 'n', 'y', ST_GeomFromText('POINT(107 173)')),
-('l', 'a', 'w', ST_GeomFromText('POINT(125 152)')),
-('m', 'd', 'j', ST_GeomFromText('POINT(146 53)')),
-('q', 'm', 'c', ST_GeomFromText('POINT(217 187)')),
-('i', 'r', 'r', ST_GeomFromText('POINT(6 113)')),
-('e', 'j', 'b', ST_GeomFromText('POINT(37 83)')),
-('w', 'w', 'h', ST_GeomFromText('POINT(83 199)')),
-('k', 'b', 's', ST_GeomFromText('POINT(170 64)')),
-('s', 'b', 'c', ST_GeomFromText('POINT(163 130)')),
-('c', 'h', 'a', ST_GeomFromText('POINT(141 3)')),
-('k', 'j', 'u', ST_GeomFromText('POINT(143 76)')),
-('r', 'h', 'o', ST_GeomFromText('POINT(243 92)')),
-('i', 'd', 'b', ST_GeomFromText('POINT(205 13)')),
-('r', 'y', 'q', ST_GeomFromText('POINT(138 8)')),
-('m', 'o', 'i', ST_GeomFromText('POINT(36 45)')),
-('v', 'g', 'm', ST_GeomFromText('POINT(0 40)')),
-('f', 'e', 'i', ST_GeomFromText('POINT(76 6)')),
-('c', 'q', 'q', ST_GeomFromText('POINT(115 248)')),
-('x', 'c', 'i', ST_GeomFromText('POINT(29 74)')),
-('l', 's', 't', ST_GeomFromText('POINT(83 18)')),
-('t', 't', 'a', ST_GeomFromText('POINT(26 168)')),
-('u', 'n', 'x', ST_GeomFromText('POINT(200 110)')),
-('j', 'b', 'd', ST_GeomFromText('POINT(216 136)')),
-('s', 'p', 'w', ST_GeomFromText('POINT(38 156)')),
-('f', 'b', 'v', ST_GeomFromText('POINT(29 186)')),
-('v', 'e', 'r', ST_GeomFromText('POINT(149 40)')),
-('v', 't', 'm', ST_GeomFromText('POINT(184 24)')),
-('y', 'g', 'a', ST_GeomFromText('POINT(219 105)')),
-('s', 'f', 'i', ST_GeomFromText('POINT(114 130)')),
-('e', 'q', 'h', ST_GeomFromText('POINT(203 135)')),
-('h', 'g', 'b', ST_GeomFromText('POINT(9 208)')),
-('o', 'l', 'r', ST_GeomFromText('POINT(245 79)')),
-('s', 's', 'v', ST_GeomFromText('POINT(238 198)')),
-('w', 'w', 'z', ST_GeomFromText('POINT(209 232)')),
-('v', 'd', 'n', ST_GeomFromText('POINT(30 193)')),
-('q', 'w', 'k', ST_GeomFromText('POINT(133 18)')),
-('o', 'h', 'o', ST_GeomFromText('POINT(42 140)')),
-('f', 'f', 'h', ST_GeomFromText('POINT(145 1)')),
-('u', 's', 'r', ST_GeomFromText('POINT(70 62)')),
-('x', 'n', 'q', ST_GeomFromText('POINT(33 86)')),
-('u', 'p', 'v', ST_GeomFromText('POINT(232 220)')),
-('z', 'e', 'a', ST_GeomFromText('POINT(130 69)')),
-('r', 'u', 'z', ST_GeomFromText('POINT(243 241)')),
-('b', 'n', 't', ST_GeomFromText('POINT(120 12)')),
-('u', 'f', 's', ST_GeomFromText('POINT(190 212)')),
-('a', 'd', 'q', ST_GeomFromText('POINT(235 191)')),
-('f', 'q', 'm', ST_GeomFromText('POINT(176 2)')),
-('n', 'c', 's', ST_GeomFromText('POINT(218 163)')),
-('e', 'm', 'h', ST_GeomFromText('POINT(163 108)')),
-('c', 'f', 'l', ST_GeomFromText('POINT(220 115)')),
-('c', 'v', 'q', ST_GeomFromText('POINT(66 45)')),
-('w', 'v', 'x', ST_GeomFromText('POINT(251 220)')),
-('f', 'w', 'z', ST_GeomFromText('POINT(146 149)')),
-('h', 'n', 'h', ST_GeomFromText('POINT(148 128)')),
-('y', 'k', 'v', ST_GeomFromText('POINT(28 110)')),
-('c', 'x', 'q', ST_GeomFromText('POINT(13 13)')),
-('e', 'd', 's', ST_GeomFromText('POINT(91 190)')),
-('c', 'w', 'c', ST_GeomFromText('POINT(10 231)')),
-('u', 'j', 'n', ST_GeomFromText('POINT(250 21)')),
-('w', 'n', 'x', ST_GeomFromText('POINT(141 69)')),
-('f', 'p', 'y', ST_GeomFromText('POINT(228 246)')),
-('d', 'q', 'f', ST_GeomFromText('POINT(194 22)')),
-('d', 'z', 'l', ST_GeomFromText('POINT(233 181)')),
-('c', 'a', 'q', ST_GeomFromText('POINT(183 96)')),
-('m', 'i', 'd', ST_GeomFromText('POINT(117 226)')),
-('z', 'y', 'y', ST_GeomFromText('POINT(62 81)')),
-('g', 'v', 'm', ST_GeomFromText('POINT(66 158)'));
-START TRANSACTION;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'x', 'p', ST_GeomFromText('POINT(92 181)'));
-ROLLBACK;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'x', 'p', ST_GeomFromText('POINT(92 181)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES ('n', 'x', 'p', ST_GeomFromText('POINT(0 1280)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES ('n', 'x', 'p', ST_GeomFromText('POINT(45 1280)'));
-INSERT INTO t1 VALUES (1280, 'n', 'x', 'p', ST_GeomFromText('POINT(44 253)'));
-DELETE FROM t1 WHERE id = 1280;
-INSERT INTO t1 VALUES (1280, 'n', 'x', 'p', ST_GeomFromText('POINT(44 253)'));
-START TRANSACTION;
-DELETE FROM t1 WHERE id = 1280;
-ROLLBACK;
-START TRANSACTION;
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
-('m', 'u', 'p', ST_GeomFromText('POINT(1192 1181)'));
-ROLLBACK;
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-353
-UPDATE t1 SET spatial_point = ST_GeomFromText('POINT(123 456)') WHERE id < 2000;
-SET @g1 = ST_GeomFromText('Polygon((123 456, 123 678, 456 678,456 456,123 456))');
-DELETE FROM t1 WHERE MBRContains(@g1, t1.spatial_point);
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-353
-DROP TABLE t1;
-SET GLOBAL innodb_file_per_table=default;
-SET GLOBAL innodb_file_format=default;
-Warnings:
-Warning 131 Using innodb_file_format is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html
-SET GLOBAL innodb_file_per_table='on';
-SET GLOBAL innodb_file_format='Barracuda';
-Warnings:
-Warning 131 Using innodb_file_format is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html
-CREATE TABLE t1 (
-id bigint(12) unsigned NOT NULL auto_increment,
-c2 varchar(15) collate utf8_bin DEFAULT NULL,
-c1 varchar(15) collate utf8_bin DEFAULT NULL,
-c3 varchar(10) collate utf8_bin DEFAULT NULL,
-spatial_point point NOT NULL,
-PRIMARY KEY(id),
-SPATIAL KEY (spatial_point)
-) ROW_FORMAT=DYNAMIC ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('y', 's', 'j', ST_GeomFromText('POINT(167 74)')),
-('r', 'n', 'd', ST_GeomFromText('POINT(215 118)')),
-('g', 'n', 'e', ST_GeomFromText('POINT(203 98)')),
-('h', 'd', 'd', ST_GeomFromText('POINT(54 193)')),
-('r', 'x', 'y', ST_GeomFromText('POINT(47 69)')),
-('t', 'q', 'r', ST_GeomFromText('POINT(109 42)')),
-('a', 'z', 'd', ST_GeomFromText('POINT(0 154)')),
-('x', 'v', 'o', ST_GeomFromText('POINT(174 131)')),
-('b', 'r', 'a', ST_GeomFromText('POINT(114 253)')),
-('x', 'z', 'i', ST_GeomFromText('POINT(163 21)')),
-('w', 'p', 'i', ST_GeomFromText('POINT(42 102)')),
-('g', 'j', 'j', ST_GeomFromText('POINT(170 133)')),
-('m', 'g', 'n', ST_GeomFromText('POINT(28 22)')),
-('b', 'z', 'h', ST_GeomFromText('POINT(174 28)')),
-('q', 'k', 'f', ST_GeomFromText('POINT(233 73)')),
-('w', 'w', 'a', ST_GeomFromText('POINT(124 200)')),
-('t', 'j', 'w', ST_GeomFromText('POINT(252 101)')),
-('d', 'r', 'd', ST_GeomFromText('POINT(98 18)')),
-('w', 'o', 'y', ST_GeomFromText('POINT(165 31)')),
-('y', 'h', 't', ST_GeomFromText('POINT(14 220)')),
-('d', 'p', 'u', ST_GeomFromText('POINT(223 196)')),
-('g', 'y', 'g', ST_GeomFromText('POINT(207 96)')),
-('x', 'm', 'n', ST_GeomFromText('POINT(214 3)')),
-('g', 'v', 'e', ST_GeomFromText('POINT(140 205)')),
-('g', 'm', 'm', ST_GeomFromText('POINT(10 236)')),
-('i', 'r', 'j', ST_GeomFromText('POINT(137 228)')),
-('w', 's', 'p', ST_GeomFromText('POINT(115 6)')),
-('o', 'n', 'k', ST_GeomFromText('POINT(158 129)')),
-('j', 'h', 'l', ST_GeomFromText('POINT(129 72)')),
-('f', 'x', 'l', ST_GeomFromText('POINT(139 207)')),
-('u', 'd', 'n', ST_GeomFromText('POINT(125 109)')),
-('b', 'a', 'z', ST_GeomFromText('POINT(30 32)')),
-('m', 'h', 'o', ST_GeomFromText('POINT(251 251)')),
-('f', 'r', 'd', ST_GeomFromText('POINT(243 211)')),
-('b', 'd', 'r', ST_GeomFromText('POINT(232 80)')),
-('g', 'k', 'v', ST_GeomFromText('POINT(15 100)')),
-('i', 'f', 'c', ST_GeomFromText('POINT(109 66)')),
-('r', 't', 'j', ST_GeomFromText('POINT(178 6)')),
-('y', 'n', 'f', ST_GeomFromText('POINT(233 211)')),
-('f', 'y', 'm', ST_GeomFromText('POINT(99 16)')),
-('z', 'q', 'l', ST_GeomFromText('POINT(39 49)')),
-('j', 'c', 'r', ST_GeomFromText('POINT(75 187)')),
-('c', 'y', 'y', ST_GeomFromText('POINT(246 253)')),
-('w', 'u', 'd', ST_GeomFromText('POINT(56 190)')),
-('n', 'q', 'm', ST_GeomFromText('POINT(73 149)')),
-('d', 'y', 'a', ST_GeomFromText('POINT(134 6)')),
-('z', 's', 'w', ST_GeomFromText('POINT(216 225)')),
-('d', 'u', 'k', ST_GeomFromText('POINT(132 70)')),
-('f', 'v', 't', ST_GeomFromText('POINT(187 141)')),
-('r', 'r', 'a', ST_GeomFromText('POINT(152 39)')),
-('y', 'p', 'o', ST_GeomFromText('POINT(45 27)')),
-('p', 'n', 'm', ST_GeomFromText('POINT(228 148)')),
-('e', 'g', 'e', ST_GeomFromText('POINT(88 81)')),
-('m', 'a', 'h', ST_GeomFromText('POINT(35 29)')),
-('m', 'h', 'f', ST_GeomFromText('POINT(30 71)')),
-('h', 'k', 'i', ST_GeomFromText('POINT(244 78)')),
-('z', 'v', 'd', ST_GeomFromText('POINT(241 38)')),
-('q', 'l', 'j', ST_GeomFromText('POINT(13 71)')),
-('s', 'p', 'g', ST_GeomFromText('POINT(108 38)')),
-('q', 's', 'j', ST_GeomFromText('POINT(92 101)')),
-('l', 'h', 'g', ST_GeomFromText('POINT(120 78)')),
-('w', 't', 'b', ST_GeomFromText('POINT(193 109)')),
-('b', 's', 's', ST_GeomFromText('POINT(223 211)')),
-('w', 'w', 'y', ST_GeomFromText('POINT(122 42)')),
-('q', 'c', 'c', ST_GeomFromText('POINT(104 102)')),
-('w', 'g', 'n', ST_GeomFromText('POINT(213 120)')),
-('p', 'q', 'a', ST_GeomFromText('POINT(247 148)')),
-('c', 'z', 'e', ST_GeomFromText('POINT(18 106)')),
-('z', 'u', 'n', ST_GeomFromText('POINT(70 133)')),
-('j', 'n', 'x', ST_GeomFromText('POINT(232 13)')),
-('e', 'h', 'f', ST_GeomFromText('POINT(22 135)')),
-('w', 'l', 'f', ST_GeomFromText('POINT(9 180)')),
-('a', 'v', 'q', ST_GeomFromText('POINT(163 228)')),
-('i', 'z', 'o', ST_GeomFromText('POINT(180 100)')),
-('e', 'c', 'l', ST_GeomFromText('POINT(182 231)')),
-('c', 'k', 'o', ST_GeomFromText('POINT(19 60)')),
-('q', 'f', 'p', ST_GeomFromText('POINT(79 95)')),
-('m', 'd', 'r', ST_GeomFromText('POINT(3 127)')),
-('m', 'e', 't', ST_GeomFromText('POINT(136 154)')),
-('w', 'w', 'w', ST_GeomFromText('POINT(102 15)')),
-('l', 'n', 'q', ST_GeomFromText('POINT(71 196)')),
-('p', 'k', 'c', ST_GeomFromText('POINT(47 139)')),
-('j', 'o', 'r', ST_GeomFromText('POINT(177 128)')),
-('j', 'q', 'a', ST_GeomFromText('POINT(170 6)')),
-('b', 'a', 'o', ST_GeomFromText('POINT(63 211)')),
-('g', 's', 'o', ST_GeomFromText('POINT(144 251)')),
-('w', 'u', 'w', ST_GeomFromText('POINT(221 214)')),
-('g', 'a', 'm', ST_GeomFromText('POINT(14 102)')),
-('u', 'q', 'z', ST_GeomFromText('POINT(86 200)')),
-('k', 'a', 'm', ST_GeomFromText('POINT(144 222)')),
-('j', 'u', 'r', ST_GeomFromText('POINT(216 142)')),
-('q', 'k', 'v', ST_GeomFromText('POINT(121 236)')),
-('p', 'o', 'r', ST_GeomFromText('POINT(108 102)')),
-('b', 'd', 'x', ST_GeomFromText('POINT(127 198)')),
-('k', 's', 'a', ST_GeomFromText('POINT(2 150)')),
-('f', 'm', 'f', ST_GeomFromText('POINT(160 191)')),
-('q', 'y', 'x', ST_GeomFromText('POINT(98 111)')),
-('o', 'f', 'm', ST_GeomFromText('POINT(232 218)')),
-('c', 'w', 'j', ST_GeomFromText('POINT(156 165)')),
-('s', 'q', 'v', ST_GeomFromText('POINT(98 161)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'y', 'p', ST_GeomFromText('POINT(109 235)')),
-('b', 'e', 'v', ST_GeomFromText('POINT(20 48)')),
-('i', 'u', 'f', ST_GeomFromText('POINT(15 55)')),
-('o', 'r', 'z', ST_GeomFromText('POINT(105 64)')),
-('a', 'p', 'a', ST_GeomFromText('POINT(142 236)')),
-('g', 'i', 'k', ST_GeomFromText('POINT(10 49)')),
-('x', 'z', 'x', ST_GeomFromText('POINT(192 200)')),
-('c', 'v', 'r', ST_GeomFromText('POINT(94 168)')),
-('y', 'z', 'e', ST_GeomFromText('POINT(141 51)')),
-('h', 'm', 'd', ST_GeomFromText('POINT(35 251)')),
-('v', 'm', 'q', ST_GeomFromText('POINT(44 90)')),
-('j', 'l', 'z', ST_GeomFromText('POINT(67 237)')),
-('i', 'v', 'a', ST_GeomFromText('POINT(75 14)')),
-('b', 'q', 't', ST_GeomFromText('POINT(153 33)')),
-('e', 'm', 'a', ST_GeomFromText('POINT(247 49)')),
-('l', 'y', 'g', ST_GeomFromText('POINT(56 203)')),
-('v', 'o', 'r', ST_GeomFromText('POINT(90 54)')),
-('r', 'n', 'd', ST_GeomFromText('POINT(135 83)')),
-('j', 't', 'u', ST_GeomFromText('POINT(174 239)')),
-('u', 'n', 'g', ST_GeomFromText('POINT(104 191)')),
-('p', 'q', 'y', ST_GeomFromText('POINT(63 171)')),
-('o', 'q', 'p', ST_GeomFromText('POINT(192 103)')),
-('f', 'x', 'e', ST_GeomFromText('POINT(244 30)')),
-('n', 'x', 'c', ST_GeomFromText('POINT(92 103)')),
-('r', 'q', 'z', ST_GeomFromText('POINT(166 20)')),
-('s', 'a', 'j', ST_GeomFromText('POINT(137 205)')),
-('z', 't', 't', ST_GeomFromText('POINT(99 134)')),
-('o', 'm', 'j', ST_GeomFromText('POINT(217 3)')),
-('n', 'h', 'j', ST_GeomFromText('POINT(211 17)')),
-('v', 'v', 'a', ST_GeomFromText('POINT(41 137)')),
-('q', 'o', 'j', ST_GeomFromText('POINT(5 92)')),
-('z', 'y', 'e', ST_GeomFromText('POINT(175 212)')),
-('j', 'z', 'h', ST_GeomFromText('POINT(224 194)')),
-('a', 'g', 'm', ST_GeomFromText('POINT(31 119)')),
-('p', 'c', 'f', ST_GeomFromText('POINT(17 221)')),
-('t', 'h', 'k', ST_GeomFromText('POINT(26 203)')),
-('u', 'w', 'p', ST_GeomFromText('POINT(47 185)')),
-('z', 'a', 'c', ST_GeomFromText('POINT(61 133)')),
-('u', 'k', 'a', ST_GeomFromText('POINT(210 115)')),
-('k', 'f', 'h', ST_GeomFromText('POINT(125 113)')),
-('t', 'v', 'y', ST_GeomFromText('POINT(12 239)')),
-('u', 'v', 'd', ST_GeomFromText('POINT(90 24)')),
-('m', 'y', 'w', ST_GeomFromText('POINT(25 243)')),
-('d', 'n', 'g', ST_GeomFromText('POINT(122 92)')),
-('z', 'm', 'f', ST_GeomFromText('POINT(235 110)')),
-('q', 'd', 'f', ST_GeomFromText('POINT(233 217)')),
-('a', 'v', 'u', ST_GeomFromText('POINT(69 59)')),
-('x', 'k', 'p', ST_GeomFromText('POINT(240 14)')),
-('i', 'v', 'r', ST_GeomFromText('POINT(154 42)')),
-('w', 'h', 'l', ST_GeomFromText('POINT(178 156)')),
-('d', 'h', 'n', ST_GeomFromText('POINT(65 157)')),
-('c', 'k', 'z', ST_GeomFromText('POINT(62 33)')),
-('e', 'l', 'w', ST_GeomFromText('POINT(162 1)')),
-('r', 'f', 'i', ST_GeomFromText('POINT(127 71)')),
-('q', 'm', 'c', ST_GeomFromText('POINT(63 118)')),
-('c', 'h', 'u', ST_GeomFromText('POINT(205 203)')),
-('d', 't', 'p', ST_GeomFromText('POINT(234 87)')),
-('s', 'g', 'h', ST_GeomFromText('POINT(149 34)')),
-('o', 'b', 'q', ST_GeomFromText('POINT(159 179)')),
-('k', 'u', 'f', ST_GeomFromText('POINT(202 254)')),
-('u', 'f', 'g', ST_GeomFromText('POINT(70 15)')),
-('x', 's', 'b', ST_GeomFromText('POINT(25 181)')),
-('s', 'c', 'g', ST_GeomFromText('POINT(252 17)')),
-('a', 'c', 'f', ST_GeomFromText('POINT(89 67)')),
-('r', 'e', 'q', ST_GeomFromText('POINT(55 54)')),
-('f', 'i', 'k', ST_GeomFromText('POINT(178 230)')),
-('p', 'e', 'l', ST_GeomFromText('POINT(198 28)')),
-('w', 'o', 'd', ST_GeomFromText('POINT(204 189)')),
-('c', 'a', 'g', ST_GeomFromText('POINT(230 178)')),
-('r', 'o', 'e', ST_GeomFromText('POINT(61 116)')),
-('w', 'a', 'a', ST_GeomFromText('POINT(178 237)')),
-('v', 'd', 'e', ST_GeomFromText('POINT(70 85)')),
-('k', 'c', 'e', ST_GeomFromText('POINT(147 118)')),
-('d', 'q', 't', ST_GeomFromText('POINT(218 77)')),
-('k', 'g', 'f', ST_GeomFromText('POINT(192 113)')),
-('w', 'n', 'e', ST_GeomFromText('POINT(92 124)')),
-('r', 'm', 'q', ST_GeomFromText('POINT(130 65)')),
-('o', 'r', 'r', ST_GeomFromText('POINT(174 233)')),
-('k', 'n', 't', ST_GeomFromText('POINT(175 147)')),
-('q', 'm', 'r', ST_GeomFromText('POINT(18 208)')),
-('l', 'd', 'i', ST_GeomFromText('POINT(13 104)')),
-('w', 'o', 'y', ST_GeomFromText('POINT(207 39)')),
-('p', 'u', 'o', ST_GeomFromText('POINT(114 31)')),
-('y', 'a', 'p', ST_GeomFromText('POINT(106 59)')),
-('a', 'x', 'z', ST_GeomFromText('POINT(17 57)')),
-('v', 'h', 'x', ST_GeomFromText('POINT(170 13)')),
-('t', 's', 'u', ST_GeomFromText('POINT(84 18)')),
-('z', 'z', 'f', ST_GeomFromText('POINT(250 197)')),
-('l', 'z', 't', ST_GeomFromText('POINT(59 80)')),
-('j', 'g', 's', ST_GeomFromText('POINT(54 26)')),
-('g', 'v', 'm', ST_GeomFromText('POINT(89 98)')),
-('q', 'v', 'b', ST_GeomFromText('POINT(39 240)')),
-('x', 'k', 'v', ST_GeomFromText('POINT(246 207)')),
-('k', 'u', 'i', ST_GeomFromText('POINT(105 111)')),
-('w', 'z', 's', ST_GeomFromText('POINT(235 8)')),
-('d', 'd', 'd', ST_GeomFromText('POINT(105 4)')),
-('c', 'z', 'q', ST_GeomFromText('POINT(13 140)')),
-('m', 'k', 'i', ST_GeomFromText('POINT(208 120)')),
-('g', 'a', 'g', ST_GeomFromText('POINT(9 182)')),
-('z', 'j', 'r', ST_GeomFromText('POINT(149 153)')),
-('h', 'f', 'g', ST_GeomFromText('POINT(81 236)')),
-('m', 'e', 'q', ST_GeomFromText('POINT(209 215)')),
-('c', 'h', 'y', ST_GeomFromText('POINT(235 70)')),
-('i', 'e', 'g', ST_GeomFromText('POINT(138 26)')),
-('m', 't', 'u', ST_GeomFromText('POINT(119 237)')),
-('o', 'w', 's', ST_GeomFromText('POINT(193 166)')),
-('f', 'm', 'q', ST_GeomFromText('POINT(85 96)')),
-('x', 'l', 'x', ST_GeomFromText('POINT(58 115)')),
-('x', 'q', 'u', ST_GeomFromText('POINT(108 210)')),
-('b', 'h', 'i', ST_GeomFromText('POINT(250 139)')),
-('y', 'd', 'x', ST_GeomFromText('POINT(199 135)')),
-('w', 'h', 'p', ST_GeomFromText('POINT(247 233)')),
-('p', 'z', 't', ST_GeomFromText('POINT(148 249)')),
-('q', 'a', 'u', ST_GeomFromText('POINT(174 78)')),
-('v', 't', 'm', ST_GeomFromText('POINT(70 228)')),
-('t', 'n', 'f', ST_GeomFromText('POINT(123 2)')),
-('x', 't', 'b', ST_GeomFromText('POINT(35 50)')),
-('r', 'j', 'f', ST_GeomFromText('POINT(200 51)')),
-('s', 'q', 'o', ST_GeomFromText('POINT(23 184)')),
-('u', 'v', 'z', ST_GeomFromText('POINT(7 113)')),
-('v', 'u', 'l', ST_GeomFromText('POINT(145 190)')),
-('o', 'k', 'i', ST_GeomFromText('POINT(161 122)')),
-('l', 'y', 'e', ST_GeomFromText('POINT(17 232)')),
-('t', 'b', 'e', ST_GeomFromText('POINT(120 50)')),
-('e', 's', 'u', ST_GeomFromText('POINT(254 1)')),
-('d', 'd', 'u', ST_GeomFromText('POINT(167 140)')),
-('o', 'b', 'x', ST_GeomFromText('POINT(186 237)')),
-('m', 's', 's', ST_GeomFromText('POINT(172 149)')),
-('t', 'y', 'a', ST_GeomFromText('POINT(149 85)')),
-('x', 't', 'r', ST_GeomFromText('POINT(10 165)')),
-('g', 'c', 'e', ST_GeomFromText('POINT(95 165)')),
-('e', 'e', 'z', ST_GeomFromText('POINT(98 65)')),
-('f', 'v', 'i', ST_GeomFromText('POINT(149 144)')),
-('o', 'p', 'm', ST_GeomFromText('POINT(233 67)')),
-('t', 'u', 'b', ST_GeomFromText('POINT(109 215)')),
-('o', 'o', 'b', ST_GeomFromText('POINT(130 48)')),
-('e', 'm', 'h', ST_GeomFromText('POINT(88 189)')),
-('e', 'v', 'y', ST_GeomFromText('POINT(55 29)')),
-('e', 't', 'm', ST_GeomFromText('POINT(129 55)')),
-('p', 'p', 'i', ST_GeomFromText('POINT(126 222)')),
-('c', 'i', 'c', ST_GeomFromText('POINT(19 158)')),
-('c', 'b', 's', ST_GeomFromText('POINT(13 19)')),
-('u', 'y', 'a', ST_GeomFromText('POINT(114 5)')),
-('a', 'o', 'f', ST_GeomFromText('POINT(227 232)')),
-('t', 'c', 'z', ST_GeomFromText('POINT(63 62)')),
-('d', 'o', 'k', ST_GeomFromText('POINT(48 228)')),
-('x', 'c', 'e', ST_GeomFromText('POINT(204 2)')),
-('e', 'e', 'g', ST_GeomFromText('POINT(125 43)')),
-('o', 'r', 'f', ST_GeomFromText('POINT(171 140)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('b', 'c', 'e', ST_GeomFromText('POINT(41 137)')),
-('p', 'y', 'k', ST_GeomFromText('POINT(50 22)')),
-('s', 'c', 'h', ST_GeomFromText('POINT(208 173)')),
-('x', 'u', 'l', ST_GeomFromText('POINT(199 175)')),
-('s', 'r', 'h', ST_GeomFromText('POINT(85 192)')),
-('j', 'k', 'u', ST_GeomFromText('POINT(18 25)')),
-('p', 'w', 'h', ST_GeomFromText('POINT(152 197)')),
-('e', 'd', 'c', ST_GeomFromText('POINT(229 3)')),
-('o', 'x', 'k', ST_GeomFromText('POINT(187 155)')),
-('o', 'b', 'k', ST_GeomFromText('POINT(208 150)')),
-('d', 'a', 'j', ST_GeomFromText('POINT(70 87)')),
-('f', 'e', 'k', ST_GeomFromText('POINT(156 96)')),
-('u', 'y', 'p', ST_GeomFromText('POINT(239 193)')),
-('n', 'v', 'p', ST_GeomFromText('POINT(223 98)')),
-('z', 'j', 'r', ST_GeomFromText('POINT(87 89)')),
-('h', 'x', 'x', ST_GeomFromText('POINT(92 0)')),
-('r', 'v', 'r', ST_GeomFromText('POINT(159 139)')),
-('v', 'g', 'g', ST_GeomFromText('POINT(16 229)')),
-('z', 'k', 'u', ST_GeomFromText('POINT(99 52)')),
-('p', 'p', 'o', ST_GeomFromText('POINT(105 125)')),
-('w', 'h', 'y', ST_GeomFromText('POINT(105 154)')),
-('v', 'y', 'z', ST_GeomFromText('POINT(134 238)')),
-('x', 'o', 'o', ST_GeomFromText('POINT(178 88)')),
-('z', 'w', 'd', ST_GeomFromText('POINT(123 60)')),
-('q', 'f', 'u', ST_GeomFromText('POINT(64 90)')),
-('s', 'n', 't', ST_GeomFromText('POINT(50 138)')),
-('v', 'p', 't', ST_GeomFromText('POINT(114 91)')),
-('a', 'o', 'n', ST_GeomFromText('POINT(78 43)')),
-('k', 'u', 'd', ST_GeomFromText('POINT(185 161)')),
-('w', 'd', 'n', ST_GeomFromText('POINT(25 92)')),
-('k', 'w', 'a', ST_GeomFromText('POINT(59 238)')),
-('t', 'c', 'f', ST_GeomFromText('POINT(65 87)')),
-('g', 's', 'p', ST_GeomFromText('POINT(238 126)')),
-('d', 'n', 'y', ST_GeomFromText('POINT(107 173)')),
-('l', 'a', 'w', ST_GeomFromText('POINT(125 152)')),
-('m', 'd', 'j', ST_GeomFromText('POINT(146 53)')),
-('q', 'm', 'c', ST_GeomFromText('POINT(217 187)')),
-('i', 'r', 'r', ST_GeomFromText('POINT(6 113)')),
-('e', 'j', 'b', ST_GeomFromText('POINT(37 83)')),
-('w', 'w', 'h', ST_GeomFromText('POINT(83 199)')),
-('k', 'b', 's', ST_GeomFromText('POINT(170 64)')),
-('s', 'b', 'c', ST_GeomFromText('POINT(163 130)')),
-('c', 'h', 'a', ST_GeomFromText('POINT(141 3)')),
-('k', 'j', 'u', ST_GeomFromText('POINT(143 76)')),
-('r', 'h', 'o', ST_GeomFromText('POINT(243 92)')),
-('i', 'd', 'b', ST_GeomFromText('POINT(205 13)')),
-('r', 'y', 'q', ST_GeomFromText('POINT(138 8)')),
-('m', 'o', 'i', ST_GeomFromText('POINT(36 45)')),
-('v', 'g', 'm', ST_GeomFromText('POINT(0 40)')),
-('f', 'e', 'i', ST_GeomFromText('POINT(76 6)')),
-('c', 'q', 'q', ST_GeomFromText('POINT(115 248)')),
-('x', 'c', 'i', ST_GeomFromText('POINT(29 74)')),
-('l', 's', 't', ST_GeomFromText('POINT(83 18)')),
-('t', 't', 'a', ST_GeomFromText('POINT(26 168)')),
-('u', 'n', 'x', ST_GeomFromText('POINT(200 110)')),
-('j', 'b', 'd', ST_GeomFromText('POINT(216 136)')),
-('s', 'p', 'w', ST_GeomFromText('POINT(38 156)')),
-('f', 'b', 'v', ST_GeomFromText('POINT(29 186)')),
-('v', 'e', 'r', ST_GeomFromText('POINT(149 40)')),
-('v', 't', 'm', ST_GeomFromText('POINT(184 24)')),
-('y', 'g', 'a', ST_GeomFromText('POINT(219 105)')),
-('s', 'f', 'i', ST_GeomFromText('POINT(114 130)')),
-('e', 'q', 'h', ST_GeomFromText('POINT(203 135)')),
-('h', 'g', 'b', ST_GeomFromText('POINT(9 208)')),
-('o', 'l', 'r', ST_GeomFromText('POINT(245 79)')),
-('s', 's', 'v', ST_GeomFromText('POINT(238 198)')),
-('w', 'w', 'z', ST_GeomFromText('POINT(209 232)')),
-('v', 'd', 'n', ST_GeomFromText('POINT(30 193)')),
-('q', 'w', 'k', ST_GeomFromText('POINT(133 18)')),
-('o', 'h', 'o', ST_GeomFromText('POINT(42 140)')),
-('f', 'f', 'h', ST_GeomFromText('POINT(145 1)')),
-('u', 's', 'r', ST_GeomFromText('POINT(70 62)')),
-('x', 'n', 'q', ST_GeomFromText('POINT(33 86)')),
-('u', 'p', 'v', ST_GeomFromText('POINT(232 220)')),
-('z', 'e', 'a', ST_GeomFromText('POINT(130 69)')),
-('r', 'u', 'z', ST_GeomFromText('POINT(243 241)')),
-('b', 'n', 't', ST_GeomFromText('POINT(120 12)')),
-('u', 'f', 's', ST_GeomFromText('POINT(190 212)')),
-('a', 'd', 'q', ST_GeomFromText('POINT(235 191)')),
-('f', 'q', 'm', ST_GeomFromText('POINT(176 2)')),
-('n', 'c', 's', ST_GeomFromText('POINT(218 163)')),
-('e', 'm', 'h', ST_GeomFromText('POINT(163 108)')),
-('c', 'f', 'l', ST_GeomFromText('POINT(220 115)')),
-('c', 'v', 'q', ST_GeomFromText('POINT(66 45)')),
-('w', 'v', 'x', ST_GeomFromText('POINT(251 220)')),
-('f', 'w', 'z', ST_GeomFromText('POINT(146 149)')),
-('h', 'n', 'h', ST_GeomFromText('POINT(148 128)')),
-('y', 'k', 'v', ST_GeomFromText('POINT(28 110)')),
-('c', 'x', 'q', ST_GeomFromText('POINT(13 13)')),
-('e', 'd', 's', ST_GeomFromText('POINT(91 190)')),
-('c', 'w', 'c', ST_GeomFromText('POINT(10 231)')),
-('u', 'j', 'n', ST_GeomFromText('POINT(250 21)')),
-('w', 'n', 'x', ST_GeomFromText('POINT(141 69)')),
-('f', 'p', 'y', ST_GeomFromText('POINT(228 246)')),
-('d', 'q', 'f', ST_GeomFromText('POINT(194 22)')),
-('d', 'z', 'l', ST_GeomFromText('POINT(233 181)')),
-('c', 'a', 'q', ST_GeomFromText('POINT(183 96)')),
-('m', 'i', 'd', ST_GeomFromText('POINT(117 226)')),
-('z', 'y', 'y', ST_GeomFromText('POINT(62 81)')),
-('g', 'v', 'm', ST_GeomFromText('POINT(66 158)'));
-START TRANSACTION;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'x', 'p', ST_GeomFromText('POINT(92 181)'));
-ROLLBACK;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'x', 'p', ST_GeomFromText('POINT(92 181)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES ('n', 'x', 'p', ST_GeomFromText('POINT(0 1280)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES ('n', 'x', 'p', ST_GeomFromText('POINT(45 1280)'));
-INSERT INTO t1 VALUES (1280, 'n', 'x', 'p', ST_GeomFromText('POINT(44 253)'));
-DELETE FROM t1 WHERE id = 1280;
-INSERT INTO t1 VALUES (1280, 'n', 'x', 'p', ST_GeomFromText('POINT(44 253)'));
-START TRANSACTION;
-DELETE FROM t1 WHERE id = 1280;
-ROLLBACK;
-START TRANSACTION;
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
-('m', 'u', 'p', ST_GeomFromText('POINT(1192 1181)'));
-ROLLBACK;
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-353
-UPDATE t1 SET spatial_point = ST_GeomFromText('POINT(123 456)') WHERE id < 2000;
-SET @g1 = ST_GeomFromText('Polygon((123 456, 123 678, 456 678,456 456,123 456))');
-DELETE FROM t1 WHERE MBRContains(@g1, t1.spatial_point);
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-353
-DROP TABLE t1;
-SET GLOBAL innodb_file_per_table=default;
-SET GLOBAL innodb_file_format=default;
-Warnings:
-Warning 131 Using innodb_file_format is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html
-SET GLOBAL innodb_file_per_table='off';
-SET GLOBAL innodb_file_format='Antelope';
-Warnings:
-Warning 131 Using innodb_file_format is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html
-CREATE TABLE t1 (
-id bigint(12) unsigned NOT NULL auto_increment,
-c2 varchar(15) collate utf8_bin DEFAULT NULL,
-c1 varchar(15) collate utf8_bin DEFAULT NULL,
-c3 varchar(10) collate utf8_bin DEFAULT NULL,
-spatial_point point NOT NULL,
-PRIMARY KEY(id),
-SPATIAL KEY (spatial_point)
-) ROW_FORMAT=COMPACT ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('y', 's', 'j', ST_GeomFromText('POINT(167 74)')),
-('r', 'n', 'd', ST_GeomFromText('POINT(215 118)')),
-('g', 'n', 'e', ST_GeomFromText('POINT(203 98)')),
-('h', 'd', 'd', ST_GeomFromText('POINT(54 193)')),
-('r', 'x', 'y', ST_GeomFromText('POINT(47 69)')),
-('t', 'q', 'r', ST_GeomFromText('POINT(109 42)')),
-('a', 'z', 'd', ST_GeomFromText('POINT(0 154)')),
-('x', 'v', 'o', ST_GeomFromText('POINT(174 131)')),
-('b', 'r', 'a', ST_GeomFromText('POINT(114 253)')),
-('x', 'z', 'i', ST_GeomFromText('POINT(163 21)')),
-('w', 'p', 'i', ST_GeomFromText('POINT(42 102)')),
-('g', 'j', 'j', ST_GeomFromText('POINT(170 133)')),
-('m', 'g', 'n', ST_GeomFromText('POINT(28 22)')),
-('b', 'z', 'h', ST_GeomFromText('POINT(174 28)')),
-('q', 'k', 'f', ST_GeomFromText('POINT(233 73)')),
-('w', 'w', 'a', ST_GeomFromText('POINT(124 200)')),
-('t', 'j', 'w', ST_GeomFromText('POINT(252 101)')),
-('d', 'r', 'd', ST_GeomFromText('POINT(98 18)')),
-('w', 'o', 'y', ST_GeomFromText('POINT(165 31)')),
-('y', 'h', 't', ST_GeomFromText('POINT(14 220)')),
-('d', 'p', 'u', ST_GeomFromText('POINT(223 196)')),
-('g', 'y', 'g', ST_GeomFromText('POINT(207 96)')),
-('x', 'm', 'n', ST_GeomFromText('POINT(214 3)')),
-('g', 'v', 'e', ST_GeomFromText('POINT(140 205)')),
-('g', 'm', 'm', ST_GeomFromText('POINT(10 236)')),
-('i', 'r', 'j', ST_GeomFromText('POINT(137 228)')),
-('w', 's', 'p', ST_GeomFromText('POINT(115 6)')),
-('o', 'n', 'k', ST_GeomFromText('POINT(158 129)')),
-('j', 'h', 'l', ST_GeomFromText('POINT(129 72)')),
-('f', 'x', 'l', ST_GeomFromText('POINT(139 207)')),
-('u', 'd', 'n', ST_GeomFromText('POINT(125 109)')),
-('b', 'a', 'z', ST_GeomFromText('POINT(30 32)')),
-('m', 'h', 'o', ST_GeomFromText('POINT(251 251)')),
-('f', 'r', 'd', ST_GeomFromText('POINT(243 211)')),
-('b', 'd', 'r', ST_GeomFromText('POINT(232 80)')),
-('g', 'k', 'v', ST_GeomFromText('POINT(15 100)')),
-('i', 'f', 'c', ST_GeomFromText('POINT(109 66)')),
-('r', 't', 'j', ST_GeomFromText('POINT(178 6)')),
-('y', 'n', 'f', ST_GeomFromText('POINT(233 211)')),
-('f', 'y', 'm', ST_GeomFromText('POINT(99 16)')),
-('z', 'q', 'l', ST_GeomFromText('POINT(39 49)')),
-('j', 'c', 'r', ST_GeomFromText('POINT(75 187)')),
-('c', 'y', 'y', ST_GeomFromText('POINT(246 253)')),
-('w', 'u', 'd', ST_GeomFromText('POINT(56 190)')),
-('n', 'q', 'm', ST_GeomFromText('POINT(73 149)')),
-('d', 'y', 'a', ST_GeomFromText('POINT(134 6)')),
-('z', 's', 'w', ST_GeomFromText('POINT(216 225)')),
-('d', 'u', 'k', ST_GeomFromText('POINT(132 70)')),
-('f', 'v', 't', ST_GeomFromText('POINT(187 141)')),
-('r', 'r', 'a', ST_GeomFromText('POINT(152 39)')),
-('y', 'p', 'o', ST_GeomFromText('POINT(45 27)')),
-('p', 'n', 'm', ST_GeomFromText('POINT(228 148)')),
-('e', 'g', 'e', ST_GeomFromText('POINT(88 81)')),
-('m', 'a', 'h', ST_GeomFromText('POINT(35 29)')),
-('m', 'h', 'f', ST_GeomFromText('POINT(30 71)')),
-('h', 'k', 'i', ST_GeomFromText('POINT(244 78)')),
-('z', 'v', 'd', ST_GeomFromText('POINT(241 38)')),
-('q', 'l', 'j', ST_GeomFromText('POINT(13 71)')),
-('s', 'p', 'g', ST_GeomFromText('POINT(108 38)')),
-('q', 's', 'j', ST_GeomFromText('POINT(92 101)')),
-('l', 'h', 'g', ST_GeomFromText('POINT(120 78)')),
-('w', 't', 'b', ST_GeomFromText('POINT(193 109)')),
-('b', 's', 's', ST_GeomFromText('POINT(223 211)')),
-('w', 'w', 'y', ST_GeomFromText('POINT(122 42)')),
-('q', 'c', 'c', ST_GeomFromText('POINT(104 102)')),
-('w', 'g', 'n', ST_GeomFromText('POINT(213 120)')),
-('p', 'q', 'a', ST_GeomFromText('POINT(247 148)')),
-('c', 'z', 'e', ST_GeomFromText('POINT(18 106)')),
-('z', 'u', 'n', ST_GeomFromText('POINT(70 133)')),
-('j', 'n', 'x', ST_GeomFromText('POINT(232 13)')),
-('e', 'h', 'f', ST_GeomFromText('POINT(22 135)')),
-('w', 'l', 'f', ST_GeomFromText('POINT(9 180)')),
-('a', 'v', 'q', ST_GeomFromText('POINT(163 228)')),
-('i', 'z', 'o', ST_GeomFromText('POINT(180 100)')),
-('e', 'c', 'l', ST_GeomFromText('POINT(182 231)')),
-('c', 'k', 'o', ST_GeomFromText('POINT(19 60)')),
-('q', 'f', 'p', ST_GeomFromText('POINT(79 95)')),
-('m', 'd', 'r', ST_GeomFromText('POINT(3 127)')),
-('m', 'e', 't', ST_GeomFromText('POINT(136 154)')),
-('w', 'w', 'w', ST_GeomFromText('POINT(102 15)')),
-('l', 'n', 'q', ST_GeomFromText('POINT(71 196)')),
-('p', 'k', 'c', ST_GeomFromText('POINT(47 139)')),
-('j', 'o', 'r', ST_GeomFromText('POINT(177 128)')),
-('j', 'q', 'a', ST_GeomFromText('POINT(170 6)')),
-('b', 'a', 'o', ST_GeomFromText('POINT(63 211)')),
-('g', 's', 'o', ST_GeomFromText('POINT(144 251)')),
-('w', 'u', 'w', ST_GeomFromText('POINT(221 214)')),
-('g', 'a', 'm', ST_GeomFromText('POINT(14 102)')),
-('u', 'q', 'z', ST_GeomFromText('POINT(86 200)')),
-('k', 'a', 'm', ST_GeomFromText('POINT(144 222)')),
-('j', 'u', 'r', ST_GeomFromText('POINT(216 142)')),
-('q', 'k', 'v', ST_GeomFromText('POINT(121 236)')),
-('p', 'o', 'r', ST_GeomFromText('POINT(108 102)')),
-('b', 'd', 'x', ST_GeomFromText('POINT(127 198)')),
-('k', 's', 'a', ST_GeomFromText('POINT(2 150)')),
-('f', 'm', 'f', ST_GeomFromText('POINT(160 191)')),
-('q', 'y', 'x', ST_GeomFromText('POINT(98 111)')),
-('o', 'f', 'm', ST_GeomFromText('POINT(232 218)')),
-('c', 'w', 'j', ST_GeomFromText('POINT(156 165)')),
-('s', 'q', 'v', ST_GeomFromText('POINT(98 161)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'y', 'p', ST_GeomFromText('POINT(109 235)')),
-('b', 'e', 'v', ST_GeomFromText('POINT(20 48)')),
-('i', 'u', 'f', ST_GeomFromText('POINT(15 55)')),
-('o', 'r', 'z', ST_GeomFromText('POINT(105 64)')),
-('a', 'p', 'a', ST_GeomFromText('POINT(142 236)')),
-('g', 'i', 'k', ST_GeomFromText('POINT(10 49)')),
-('x', 'z', 'x', ST_GeomFromText('POINT(192 200)')),
-('c', 'v', 'r', ST_GeomFromText('POINT(94 168)')),
-('y', 'z', 'e', ST_GeomFromText('POINT(141 51)')),
-('h', 'm', 'd', ST_GeomFromText('POINT(35 251)')),
-('v', 'm', 'q', ST_GeomFromText('POINT(44 90)')),
-('j', 'l', 'z', ST_GeomFromText('POINT(67 237)')),
-('i', 'v', 'a', ST_GeomFromText('POINT(75 14)')),
-('b', 'q', 't', ST_GeomFromText('POINT(153 33)')),
-('e', 'm', 'a', ST_GeomFromText('POINT(247 49)')),
-('l', 'y', 'g', ST_GeomFromText('POINT(56 203)')),
-('v', 'o', 'r', ST_GeomFromText('POINT(90 54)')),
-('r', 'n', 'd', ST_GeomFromText('POINT(135 83)')),
-('j', 't', 'u', ST_GeomFromText('POINT(174 239)')),
-('u', 'n', 'g', ST_GeomFromText('POINT(104 191)')),
-('p', 'q', 'y', ST_GeomFromText('POINT(63 171)')),
-('o', 'q', 'p', ST_GeomFromText('POINT(192 103)')),
-('f', 'x', 'e', ST_GeomFromText('POINT(244 30)')),
-('n', 'x', 'c', ST_GeomFromText('POINT(92 103)')),
-('r', 'q', 'z', ST_GeomFromText('POINT(166 20)')),
-('s', 'a', 'j', ST_GeomFromText('POINT(137 205)')),
-('z', 't', 't', ST_GeomFromText('POINT(99 134)')),
-('o', 'm', 'j', ST_GeomFromText('POINT(217 3)')),
-('n', 'h', 'j', ST_GeomFromText('POINT(211 17)')),
-('v', 'v', 'a', ST_GeomFromText('POINT(41 137)')),
-('q', 'o', 'j', ST_GeomFromText('POINT(5 92)')),
-('z', 'y', 'e', ST_GeomFromText('POINT(175 212)')),
-('j', 'z', 'h', ST_GeomFromText('POINT(224 194)')),
-('a', 'g', 'm', ST_GeomFromText('POINT(31 119)')),
-('p', 'c', 'f', ST_GeomFromText('POINT(17 221)')),
-('t', 'h', 'k', ST_GeomFromText('POINT(26 203)')),
-('u', 'w', 'p', ST_GeomFromText('POINT(47 185)')),
-('z', 'a', 'c', ST_GeomFromText('POINT(61 133)')),
-('u', 'k', 'a', ST_GeomFromText('POINT(210 115)')),
-('k', 'f', 'h', ST_GeomFromText('POINT(125 113)')),
-('t', 'v', 'y', ST_GeomFromText('POINT(12 239)')),
-('u', 'v', 'd', ST_GeomFromText('POINT(90 24)')),
-('m', 'y', 'w', ST_GeomFromText('POINT(25 243)')),
-('d', 'n', 'g', ST_GeomFromText('POINT(122 92)')),
-('z', 'm', 'f', ST_GeomFromText('POINT(235 110)')),
-('q', 'd', 'f', ST_GeomFromText('POINT(233 217)')),
-('a', 'v', 'u', ST_GeomFromText('POINT(69 59)')),
-('x', 'k', 'p', ST_GeomFromText('POINT(240 14)')),
-('i', 'v', 'r', ST_GeomFromText('POINT(154 42)')),
-('w', 'h', 'l', ST_GeomFromText('POINT(178 156)')),
-('d', 'h', 'n', ST_GeomFromText('POINT(65 157)')),
-('c', 'k', 'z', ST_GeomFromText('POINT(62 33)')),
-('e', 'l', 'w', ST_GeomFromText('POINT(162 1)')),
-('r', 'f', 'i', ST_GeomFromText('POINT(127 71)')),
-('q', 'm', 'c', ST_GeomFromText('POINT(63 118)')),
-('c', 'h', 'u', ST_GeomFromText('POINT(205 203)')),
-('d', 't', 'p', ST_GeomFromText('POINT(234 87)')),
-('s', 'g', 'h', ST_GeomFromText('POINT(149 34)')),
-('o', 'b', 'q', ST_GeomFromText('POINT(159 179)')),
-('k', 'u', 'f', ST_GeomFromText('POINT(202 254)')),
-('u', 'f', 'g', ST_GeomFromText('POINT(70 15)')),
-('x', 's', 'b', ST_GeomFromText('POINT(25 181)')),
-('s', 'c', 'g', ST_GeomFromText('POINT(252 17)')),
-('a', 'c', 'f', ST_GeomFromText('POINT(89 67)')),
-('r', 'e', 'q', ST_GeomFromText('POINT(55 54)')),
-('f', 'i', 'k', ST_GeomFromText('POINT(178 230)')),
-('p', 'e', 'l', ST_GeomFromText('POINT(198 28)')),
-('w', 'o', 'd', ST_GeomFromText('POINT(204 189)')),
-('c', 'a', 'g', ST_GeomFromText('POINT(230 178)')),
-('r', 'o', 'e', ST_GeomFromText('POINT(61 116)')),
-('w', 'a', 'a', ST_GeomFromText('POINT(178 237)')),
-('v', 'd', 'e', ST_GeomFromText('POINT(70 85)')),
-('k', 'c', 'e', ST_GeomFromText('POINT(147 118)')),
-('d', 'q', 't', ST_GeomFromText('POINT(218 77)')),
-('k', 'g', 'f', ST_GeomFromText('POINT(192 113)')),
-('w', 'n', 'e', ST_GeomFromText('POINT(92 124)')),
-('r', 'm', 'q', ST_GeomFromText('POINT(130 65)')),
-('o', 'r', 'r', ST_GeomFromText('POINT(174 233)')),
-('k', 'n', 't', ST_GeomFromText('POINT(175 147)')),
-('q', 'm', 'r', ST_GeomFromText('POINT(18 208)')),
-('l', 'd', 'i', ST_GeomFromText('POINT(13 104)')),
-('w', 'o', 'y', ST_GeomFromText('POINT(207 39)')),
-('p', 'u', 'o', ST_GeomFromText('POINT(114 31)')),
-('y', 'a', 'p', ST_GeomFromText('POINT(106 59)')),
-('a', 'x', 'z', ST_GeomFromText('POINT(17 57)')),
-('v', 'h', 'x', ST_GeomFromText('POINT(170 13)')),
-('t', 's', 'u', ST_GeomFromText('POINT(84 18)')),
-('z', 'z', 'f', ST_GeomFromText('POINT(250 197)')),
-('l', 'z', 't', ST_GeomFromText('POINT(59 80)')),
-('j', 'g', 's', ST_GeomFromText('POINT(54 26)')),
-('g', 'v', 'm', ST_GeomFromText('POINT(89 98)')),
-('q', 'v', 'b', ST_GeomFromText('POINT(39 240)')),
-('x', 'k', 'v', ST_GeomFromText('POINT(246 207)')),
-('k', 'u', 'i', ST_GeomFromText('POINT(105 111)')),
-('w', 'z', 's', ST_GeomFromText('POINT(235 8)')),
-('d', 'd', 'd', ST_GeomFromText('POINT(105 4)')),
-('c', 'z', 'q', ST_GeomFromText('POINT(13 140)')),
-('m', 'k', 'i', ST_GeomFromText('POINT(208 120)')),
-('g', 'a', 'g', ST_GeomFromText('POINT(9 182)')),
-('z', 'j', 'r', ST_GeomFromText('POINT(149 153)')),
-('h', 'f', 'g', ST_GeomFromText('POINT(81 236)')),
-('m', 'e', 'q', ST_GeomFromText('POINT(209 215)')),
-('c', 'h', 'y', ST_GeomFromText('POINT(235 70)')),
-('i', 'e', 'g', ST_GeomFromText('POINT(138 26)')),
-('m', 't', 'u', ST_GeomFromText('POINT(119 237)')),
-('o', 'w', 's', ST_GeomFromText('POINT(193 166)')),
-('f', 'm', 'q', ST_GeomFromText('POINT(85 96)')),
-('x', 'l', 'x', ST_GeomFromText('POINT(58 115)')),
-('x', 'q', 'u', ST_GeomFromText('POINT(108 210)')),
-('b', 'h', 'i', ST_GeomFromText('POINT(250 139)')),
-('y', 'd', 'x', ST_GeomFromText('POINT(199 135)')),
-('w', 'h', 'p', ST_GeomFromText('POINT(247 233)')),
-('p', 'z', 't', ST_GeomFromText('POINT(148 249)')),
-('q', 'a', 'u', ST_GeomFromText('POINT(174 78)')),
-('v', 't', 'm', ST_GeomFromText('POINT(70 228)')),
-('t', 'n', 'f', ST_GeomFromText('POINT(123 2)')),
-('x', 't', 'b', ST_GeomFromText('POINT(35 50)')),
-('r', 'j', 'f', ST_GeomFromText('POINT(200 51)')),
-('s', 'q', 'o', ST_GeomFromText('POINT(23 184)')),
-('u', 'v', 'z', ST_GeomFromText('POINT(7 113)')),
-('v', 'u', 'l', ST_GeomFromText('POINT(145 190)')),
-('o', 'k', 'i', ST_GeomFromText('POINT(161 122)')),
-('l', 'y', 'e', ST_GeomFromText('POINT(17 232)')),
-('t', 'b', 'e', ST_GeomFromText('POINT(120 50)')),
-('e', 's', 'u', ST_GeomFromText('POINT(254 1)')),
-('d', 'd', 'u', ST_GeomFromText('POINT(167 140)')),
-('o', 'b', 'x', ST_GeomFromText('POINT(186 237)')),
-('m', 's', 's', ST_GeomFromText('POINT(172 149)')),
-('t', 'y', 'a', ST_GeomFromText('POINT(149 85)')),
-('x', 't', 'r', ST_GeomFromText('POINT(10 165)')),
-('g', 'c', 'e', ST_GeomFromText('POINT(95 165)')),
-('e', 'e', 'z', ST_GeomFromText('POINT(98 65)')),
-('f', 'v', 'i', ST_GeomFromText('POINT(149 144)')),
-('o', 'p', 'm', ST_GeomFromText('POINT(233 67)')),
-('t', 'u', 'b', ST_GeomFromText('POINT(109 215)')),
-('o', 'o', 'b', ST_GeomFromText('POINT(130 48)')),
-('e', 'm', 'h', ST_GeomFromText('POINT(88 189)')),
-('e', 'v', 'y', ST_GeomFromText('POINT(55 29)')),
-('e', 't', 'm', ST_GeomFromText('POINT(129 55)')),
-('p', 'p', 'i', ST_GeomFromText('POINT(126 222)')),
-('c', 'i', 'c', ST_GeomFromText('POINT(19 158)')),
-('c', 'b', 's', ST_GeomFromText('POINT(13 19)')),
-('u', 'y', 'a', ST_GeomFromText('POINT(114 5)')),
-('a', 'o', 'f', ST_GeomFromText('POINT(227 232)')),
-('t', 'c', 'z', ST_GeomFromText('POINT(63 62)')),
-('d', 'o', 'k', ST_GeomFromText('POINT(48 228)')),
-('x', 'c', 'e', ST_GeomFromText('POINT(204 2)')),
-('e', 'e', 'g', ST_GeomFromText('POINT(125 43)')),
-('o', 'r', 'f', ST_GeomFromText('POINT(171 140)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('b', 'c', 'e', ST_GeomFromText('POINT(41 137)')),
-('p', 'y', 'k', ST_GeomFromText('POINT(50 22)')),
-('s', 'c', 'h', ST_GeomFromText('POINT(208 173)')),
-('x', 'u', 'l', ST_GeomFromText('POINT(199 175)')),
-('s', 'r', 'h', ST_GeomFromText('POINT(85 192)')),
-('j', 'k', 'u', ST_GeomFromText('POINT(18 25)')),
-('p', 'w', 'h', ST_GeomFromText('POINT(152 197)')),
-('e', 'd', 'c', ST_GeomFromText('POINT(229 3)')),
-('o', 'x', 'k', ST_GeomFromText('POINT(187 155)')),
-('o', 'b', 'k', ST_GeomFromText('POINT(208 150)')),
-('d', 'a', 'j', ST_GeomFromText('POINT(70 87)')),
-('f', 'e', 'k', ST_GeomFromText('POINT(156 96)')),
-('u', 'y', 'p', ST_GeomFromText('POINT(239 193)')),
-('n', 'v', 'p', ST_GeomFromText('POINT(223 98)')),
-('z', 'j', 'r', ST_GeomFromText('POINT(87 89)')),
-('h', 'x', 'x', ST_GeomFromText('POINT(92 0)')),
-('r', 'v', 'r', ST_GeomFromText('POINT(159 139)')),
-('v', 'g', 'g', ST_GeomFromText('POINT(16 229)')),
-('z', 'k', 'u', ST_GeomFromText('POINT(99 52)')),
-('p', 'p', 'o', ST_GeomFromText('POINT(105 125)')),
-('w', 'h', 'y', ST_GeomFromText('POINT(105 154)')),
-('v', 'y', 'z', ST_GeomFromText('POINT(134 238)')),
-('x', 'o', 'o', ST_GeomFromText('POINT(178 88)')),
-('z', 'w', 'd', ST_GeomFromText('POINT(123 60)')),
-('q', 'f', 'u', ST_GeomFromText('POINT(64 90)')),
-('s', 'n', 't', ST_GeomFromText('POINT(50 138)')),
-('v', 'p', 't', ST_GeomFromText('POINT(114 91)')),
-('a', 'o', 'n', ST_GeomFromText('POINT(78 43)')),
-('k', 'u', 'd', ST_GeomFromText('POINT(185 161)')),
-('w', 'd', 'n', ST_GeomFromText('POINT(25 92)')),
-('k', 'w', 'a', ST_GeomFromText('POINT(59 238)')),
-('t', 'c', 'f', ST_GeomFromText('POINT(65 87)')),
-('g', 's', 'p', ST_GeomFromText('POINT(238 126)')),
-('d', 'n', 'y', ST_GeomFromText('POINT(107 173)')),
-('l', 'a', 'w', ST_GeomFromText('POINT(125 152)')),
-('m', 'd', 'j', ST_GeomFromText('POINT(146 53)')),
-('q', 'm', 'c', ST_GeomFromText('POINT(217 187)')),
-('i', 'r', 'r', ST_GeomFromText('POINT(6 113)')),
-('e', 'j', 'b', ST_GeomFromText('POINT(37 83)')),
-('w', 'w', 'h', ST_GeomFromText('POINT(83 199)')),
-('k', 'b', 's', ST_GeomFromText('POINT(170 64)')),
-('s', 'b', 'c', ST_GeomFromText('POINT(163 130)')),
-('c', 'h', 'a', ST_GeomFromText('POINT(141 3)')),
-('k', 'j', 'u', ST_GeomFromText('POINT(143 76)')),
-('r', 'h', 'o', ST_GeomFromText('POINT(243 92)')),
-('i', 'd', 'b', ST_GeomFromText('POINT(205 13)')),
-('r', 'y', 'q', ST_GeomFromText('POINT(138 8)')),
-('m', 'o', 'i', ST_GeomFromText('POINT(36 45)')),
-('v', 'g', 'm', ST_GeomFromText('POINT(0 40)')),
-('f', 'e', 'i', ST_GeomFromText('POINT(76 6)')),
-('c', 'q', 'q', ST_GeomFromText('POINT(115 248)')),
-('x', 'c', 'i', ST_GeomFromText('POINT(29 74)')),
-('l', 's', 't', ST_GeomFromText('POINT(83 18)')),
-('t', 't', 'a', ST_GeomFromText('POINT(26 168)')),
-('u', 'n', 'x', ST_GeomFromText('POINT(200 110)')),
-('j', 'b', 'd', ST_GeomFromText('POINT(216 136)')),
-('s', 'p', 'w', ST_GeomFromText('POINT(38 156)')),
-('f', 'b', 'v', ST_GeomFromText('POINT(29 186)')),
-('v', 'e', 'r', ST_GeomFromText('POINT(149 40)')),
-('v', 't', 'm', ST_GeomFromText('POINT(184 24)')),
-('y', 'g', 'a', ST_GeomFromText('POINT(219 105)')),
-('s', 'f', 'i', ST_GeomFromText('POINT(114 130)')),
-('e', 'q', 'h', ST_GeomFromText('POINT(203 135)')),
-('h', 'g', 'b', ST_GeomFromText('POINT(9 208)')),
-('o', 'l', 'r', ST_GeomFromText('POINT(245 79)')),
-('s', 's', 'v', ST_GeomFromText('POINT(238 198)')),
-('w', 'w', 'z', ST_GeomFromText('POINT(209 232)')),
-('v', 'd', 'n', ST_GeomFromText('POINT(30 193)')),
-('q', 'w', 'k', ST_GeomFromText('POINT(133 18)')),
-('o', 'h', 'o', ST_GeomFromText('POINT(42 140)')),
-('f', 'f', 'h', ST_GeomFromText('POINT(145 1)')),
-('u', 's', 'r', ST_GeomFromText('POINT(70 62)')),
-('x', 'n', 'q', ST_GeomFromText('POINT(33 86)')),
-('u', 'p', 'v', ST_GeomFromText('POINT(232 220)')),
-('z', 'e', 'a', ST_GeomFromText('POINT(130 69)')),
-('r', 'u', 'z', ST_GeomFromText('POINT(243 241)')),
-('b', 'n', 't', ST_GeomFromText('POINT(120 12)')),
-('u', 'f', 's', ST_GeomFromText('POINT(190 212)')),
-('a', 'd', 'q', ST_GeomFromText('POINT(235 191)')),
-('f', 'q', 'm', ST_GeomFromText('POINT(176 2)')),
-('n', 'c', 's', ST_GeomFromText('POINT(218 163)')),
-('e', 'm', 'h', ST_GeomFromText('POINT(163 108)')),
-('c', 'f', 'l', ST_GeomFromText('POINT(220 115)')),
-('c', 'v', 'q', ST_GeomFromText('POINT(66 45)')),
-('w', 'v', 'x', ST_GeomFromText('POINT(251 220)')),
-('f', 'w', 'z', ST_GeomFromText('POINT(146 149)')),
-('h', 'n', 'h', ST_GeomFromText('POINT(148 128)')),
-('y', 'k', 'v', ST_GeomFromText('POINT(28 110)')),
-('c', 'x', 'q', ST_GeomFromText('POINT(13 13)')),
-('e', 'd', 's', ST_GeomFromText('POINT(91 190)')),
-('c', 'w', 'c', ST_GeomFromText('POINT(10 231)')),
-('u', 'j', 'n', ST_GeomFromText('POINT(250 21)')),
-('w', 'n', 'x', ST_GeomFromText('POINT(141 69)')),
-('f', 'p', 'y', ST_GeomFromText('POINT(228 246)')),
-('d', 'q', 'f', ST_GeomFromText('POINT(194 22)')),
-('d', 'z', 'l', ST_GeomFromText('POINT(233 181)')),
-('c', 'a', 'q', ST_GeomFromText('POINT(183 96)')),
-('m', 'i', 'd', ST_GeomFromText('POINT(117 226)')),
-('z', 'y', 'y', ST_GeomFromText('POINT(62 81)')),
-('g', 'v', 'm', ST_GeomFromText('POINT(66 158)'));
-START TRANSACTION;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'x', 'p', ST_GeomFromText('POINT(92 181)'));
-ROLLBACK;
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES
-('f', 'x', 'p', ST_GeomFromText('POINT(92 181)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES ('n', 'x', 'p', ST_GeomFromText('POINT(0 1280)'));
-INSERT INTO t1 (c2, c1, c3, spatial_poINT) VALUES ('n', 'x', 'p', ST_GeomFromText('POINT(45 1280)'));
-INSERT INTO t1 VALUES (1280, 'n', 'x', 'p', ST_GeomFromText('POINT(44 253)'));
-DELETE FROM t1 WHERE id = 1280;
-INSERT INTO t1 VALUES (1280, 'n', 'x', 'p', ST_GeomFromText('POINT(44 253)'));
-START TRANSACTION;
-DELETE FROM t1 WHERE id = 1280;
-ROLLBACK;
-START TRANSACTION;
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
-('m', 'u', 'p', ST_GeomFromText('POINT(1192 1181)'));
-ROLLBACK;
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-353
-UPDATE t1 SET spatial_point = ST_GeomFromText('POINT(123 456)') WHERE id < 2000;
-SET @g1 = ST_GeomFromText('Polygon((123 456, 123 678, 456 678,456 456,123 456))');
-DELETE FROM t1 WHERE MBRContains(@g1, t1.spatial_point);
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-353
-DROP TABLE t1;
-SET GLOBAL innodb_file_per_table=default;
-SET GLOBAL innodb_file_format=default;
-Warnings:
-Warning 131 Using innodb_file_format is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html
diff --git a/mysql-test/suite/innodb_gis/r/rtree_compress.result b/mysql-test/suite/innodb_gis/r/rtree_compress.result
index 50f0367af5e..a88f8b9fa9b 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_compress.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_compress.result
@@ -1,4 +1,5 @@
-SET GLOBAL innodb_file_per_table=1;
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb ROW_FORMAT=COMPRESSED;
insert into t1 values(1, Point(1,1));
insert into t1 values(2, Point(2,2));
@@ -39,14 +40,15 @@ set @g1 = ST_GeomFromText('Polygon((10 10,10 800,800 800,800 10,10 10))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
0
+SET @saved_dbug = @@SESSION.debug_dbug;
SET DEBUG='+d,page_copy_rec_list_start_compress_fail';
Warnings:
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
delete from t1;
-SET DEBUG='-d,page_copy_rec_list_start_compress_fail';
-Warnings:
-Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
0
+SET debug_dbug = @saved_dbug;
+InnoDB 0 transactions not purged
drop table t1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb_gis/r/rtree_compress2.result b/mysql-test/suite/innodb_gis/r/rtree_compress2.result
index 3522a1097aa..3fa6b5e8c01 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_compress2.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_compress2.result
@@ -9,17 +9,12 @@ set i = i + 1;
end while;
end|
CALL insert_t1(70000);
-select count(*) from t1;
-count(*)
-70000
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
-truncate table t1;
-call mtr.add_suppression("InnoDB: A copy of page \[page id: space=[0-9]+, page number=[0-9]+\] in the doublewrite buffer slot [0-9]+ is not within space bounds");
-START TRANSACTION;
-CALL insert_t1(5000);
-COMMIT;
-# Kill and restart
+select count(*) from t1;
+count(*)
+70000
+delete from t1;
drop procedure insert_t1;
drop table t1;
diff --git a/mysql-test/suite/innodb_gis/r/rtree_concurrent_srch.result b/mysql-test/suite/innodb_gis/r/rtree_concurrent_srch.result
index 232d6fa296d..1b52059fff9 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_concurrent_srch.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_concurrent_srch.result
@@ -14,22 +14,25 @@ insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
-SET SESSION debug="+d,rtr_pcur_move_to_next_return";
+connect a,localhost,root,,;
+SET debug_dbug='+d,rtr_pcur_move_to_next_return';
set session transaction isolation level serializable;
set @g1 = ST_GeomFromText('Polygon((0 0,0 100,100 100,100 0,0 0))');
SET DEBUG_SYNC = 'RESET';
SET DEBUG_SYNC = 'row_search_for_mysql_before_return SIGNAL started WAIT_FOR go_ahead';
select count(*) from t1 where MBRWithin(t1.c2, @g1);;
-# Establish session con1 (user=root)
+connect con1,localhost,root,,;
set session transaction isolation level serializable;
SET DEBUG_SYNC = 'now WAIT_FOR started';
insert into t1 select * from t1;
SET DEBUG_SYNC = 'now SIGNAL go_ahead';
+connection a;
count(*)
576
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
1152
+connection default;
insert into t1 select * from t1;
insert into t1 select * from t1;
set @g1 = ST_GeomFromText('Polygon((0 0,0 100,100 100,100 0,0 0))');
@@ -53,6 +56,7 @@ insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
+connection a;
set session transaction isolation level serializable;
select @@tx_isolation;
@@tx_isolation
@@ -62,6 +66,7 @@ set @g1 = ST_GeomFromText('Polygon((100 100, 100 110, 110 110, 110 100, 100 100)
select count(*) from t1 where MBRwithin(t1.c2, @g1);
count(*)
0
+connect b,localhost,root,,;
set session transaction isolation level serializable;
set session innodb_lock_wait_timeout = 1;
select @@tx_isolation;
@@ -70,16 +75,20 @@ SERIALIZABLE
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
+connection a;
commit;
+connection default;
select count(*) from t1;
count(*)
896
insert into t1 values (105, Point(105, 105));
+connection a;
start transaction;
set @g1 = ST_GeomFromText('Polygon((100 100, 100 110, 110 110, 110 100, 100 100))');
select count(*) from t1 where MBRwithin(t1.c2, @g1);
count(*)
1
+connection b;
select @@innodb_lock_wait_timeout;
@@innodb_lock_wait_timeout
1
@@ -91,10 +100,12 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction
select count(*) from t1;
count(*)
897
+connection a;
select sleep(2);
sleep(2)
0
commit;
+connection default;
truncate t1;
INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(2 2, 150 150)'));
INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(3 3, 160 160)'));
@@ -107,6 +118,7 @@ insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
+connection a;
set session transaction isolation level serializable;
select @@tx_isolation;
@@tx_isolation
@@ -116,6 +128,7 @@ set @g1 = ST_GeomFromText('Polygon((100 100, 100 110, 110 110, 110 100, 100 100)
select count(*) from t1 where MBRwithin(t1.c2, @g1);
count(*)
0
+connection b;
set session transaction isolation level serializable;
set session innodb_lock_wait_timeout = 1;
select @@tx_isolation;
@@ -125,11 +138,14 @@ insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
+connection a;
commit;
+connection default;
select count(*) from t1;
count(*)
1792
insert into t1 values (105, Point(105, 105));
+connection a;
start transaction;
set @g1 = ST_GeomFromText('Polygon((100 100, 100 110, 110 110, 110 100, 100 100))');
select count(*) from t1 where MBRwithin(t1.c2, @g1);
@@ -138,6 +154,7 @@ count(*)
select count(*) from t1 where MBRIntersects(t1.c2, @g1);
count(*)
1793
+connection b;
select @@innodb_lock_wait_timeout;
@@innodb_lock_wait_timeout
1
@@ -149,10 +166,12 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction
select count(*) from t1;
count(*)
1793
+connection a;
select sleep(2);
sleep(2)
0
commit;
+connection default;
truncate t1;
INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(2 2, 150 150)'));
INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(3 3, 160 160)'));
@@ -163,13 +182,16 @@ INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(8 8, 210 210)'));
set @g1 = ST_GeomFromText('Polygon((3 3, 3 5, 5 5, 5 3, 3 3))');
start transaction;
delete from t1 where MBRWithin(t1.c2, @g1);
+connection a;
set session innodb_lock_wait_timeout = 1;
select @@innodb_lock_wait_timeout;
@@innodb_lock_wait_timeout
1
insert into t1 values(4, Point(4,4));
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection default;
rollback;
+connection default;
truncate t1;
INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(2 2, 150 150)'));
INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(3 3, 160 160)'));
@@ -182,13 +204,16 @@ start transaction;
select count(*) from t1 where MBRWithin(t1.c2, @g1) for update;
count(*)
0
+connection a;
set session innodb_lock_wait_timeout = 1;
select @@innodb_lock_wait_timeout;
@@innodb_lock_wait_timeout
1
insert into t1 values(4, Point(4,4));
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection default;
rollback;
+connection default;
truncate t1;
create procedure insert_t1(IN start int, IN total int)
begin
@@ -200,6 +225,7 @@ set i = i + 1;
end while;
end|
CALL insert_t1(0, 1000);
+connection a;
set session transaction isolation level serializable;
select @@tx_isolation;
@@tx_isolation
@@ -208,17 +234,21 @@ start transaction;
set @g1 = ST_GeomFromText('Polygon((800 800, 800 1000, 1000 1000, 1000 800, 800 800))');
select count(*) from t1 where MBRwithin(t1.c2, @g1);
count(*)
-199
+201
+connection b;
CALL insert_t1(1001, 2000);
set session transaction isolation level serializable;
set session innodb_lock_wait_timeout = 1;
insert into t1 values (1200, Point(950, 950));
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection a;
select sleep(2);
sleep(2)
0
commit;
-SET SESSION debug="-d,rtr_pcur_move_to_next_return";
+disconnect a;
+disconnect b;
+connection default;
drop table t1;
drop procedure insert_t1;
create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
@@ -229,14 +259,19 @@ INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(5 5, 180 180)'));
INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(6 6, 190 190)'));
INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(7 7, 200 200)'));
INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(8 8, 210 210)'));
+connect a,localhost,root,,;
SET SESSION debug="+d,rtr_pcur_move_to_next_return";
+Warnings:
+Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
set transaction isolation level serializable;
start transaction;
set @g1 = ST_GeomFromText('Polygon((100 100, 100 110, 110 110, 110 100, 100 100))');
select count(*) from t1 where MBRwithin(t1.c2, @g1);
count(*)
0
+connect b,localhost,root,,;
delete from t1 where c1 = 1;
+connection a;
commit;
set transaction isolation level serializable;
start transaction;
@@ -244,10 +279,13 @@ set @g1 = ST_GeomFromText('Polygon((0 0, 0 300, 300 300, 300 0, 0 0))');
select count(*) from t1 where MBRwithin(t1.c2, @g1);
count(*)
2
+connection b;
set session innodb_lock_wait_timeout = 1;
delete from t1 where c1 = 2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection a;
commit;
+connection default;
drop table t1;
SET DEBUG_SYNC= 'RESET';
create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
@@ -273,18 +311,22 @@ insert into t1 select * from t1;
select count(*) from t1;
count(*)
4608
+connection b;
set @g1 = ST_GeomFromText('Polygon((0 0,0 100,100 100,100 0,0 0))');
set transaction isolation level read uncommitted;
SET DEBUG_SYNC= 'row_search_for_mysql_before_return SIGNAL siga WAIT_FOR sigb';
select count(*) from t1 where MBRWithin(t1.c2, @g1);
+connection default;
SET DEBUG_SYNC= 'now WAIT_FOR siga';
rollback;
SET DEBUG_SYNC= 'now SIGNAL sigb';
+connection b;
count(*)
1
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
0
+connection default;
DROP TABLE t1;
SET DEBUG_SYNC = 'RESET';
create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
@@ -298,15 +340,21 @@ end while;
end|
start transaction;
CALL insert_t1(100);
+connection a;
set @g1 = ST_GeomFromText('Polygon((0 0,0 1000,1000 1000,1000 0,0 0))');
SET DEBUG_SYNC= 'rtr_pcur_move_to_next_return SIGNAL siga WAIT_FOR sigb';
select count(*) from t1 where MBRWithin(t1.c2, @g1);;
+connection default;
SET DEBUG_SYNC= 'now WAIT_FOR siga';
rollback;
SET DEBUG_SYNC= 'now SIGNAL sigb';
+connection a;
count(*)
0
+connection default;
drop procedure insert_t1;
DROP TABLE t1;
-SET SESSION debug="-d,rtr_pcur_move_to_next_return";
+disconnect a;
+disconnect b;
+connection default;
SET DEBUG_SYNC = 'RESET';
diff --git a/mysql-test/suite/innodb_gis/r/rtree_crash.result b/mysql-test/suite/innodb_gis/r/rtree_crash.result
deleted file mode 100644
index 12ca15a420d..00000000000
--- a/mysql-test/suite/innodb_gis/r/rtree_crash.result
+++ /dev/null
@@ -1,41 +0,0 @@
-create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
-create procedure insert_t1(IN total int)
-begin
-declare i int default 1;
-while (i <= total) DO
-insert into t1 values (i, Point(i, i));
-set i = i + 1;
-end while;
-end|
-CALL insert_t1(5000);
-select count(*) from t1;
-count(*)
-5000
-check table t1;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-truncate table t1;
-CALL insert_t1(10000);
-select count(*) from t1;
-count(*)
-10000
-drop index c2 on t1;
-create spatial index idx on t1(c2);
-show create table t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `c1` int(11) DEFAULT NULL,
- `c2` geometry NOT NULL,
- SPATIAL KEY `idx` (`c2`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-check table t1;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-truncate table t1;
-call mtr.add_suppression("InnoDB: page [0-9]+ in the doublewrite buffer is not within space bounds.*");
-START TRANSACTION;
-CALL insert_t1(5000);
-COMMIT;
-# Kill and restart
-drop procedure insert_t1;
-drop table t1;
diff --git a/mysql-test/suite/innodb_gis/r/rtree_debug.result b/mysql-test/suite/innodb_gis/r/rtree_debug.result
index e3877880387..11e2cd40e25 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_debug.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_debug.result
@@ -38,14 +38,11 @@ t1 CREATE TABLE `t1` (
`c2` geometry NOT NULL,
SPATIAL KEY `idx` (`c2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
-SET DEBUG='+d,row_merge_ins_spatial_fail';
-Warnings:
-Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+SET @save_dbug = @@SESSION.debug_dbug;
+SET debug_dbug='+d,row_merge_ins_spatial_fail';
create spatial index idx2 on t1(c2);
ERROR HY000: Got error 1000 "Unknown error 1000" from storage engine InnoDB
-SET DEBUG='-d,row_merge_ins_spatial_fail';
-Warnings:
-Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+SET debug_dbug = @save_dbug;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/suite/innodb_gis/r/rtree_estimate.result b/mysql-test/suite/innodb_gis/r/rtree_estimate.result
index 24f0f5ff41a..251685df018 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_estimate.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_estimate.result
@@ -6,10 +6,8 @@ SET @g1 = ST_GeomFromText('POINT(10 10)');
SET @g2 = ST_GeomFromText('POLYGON((5 5, 20 5, 20 21, 5 21, 5 5))');
SET @g3 = ST_GeomFromText('POLYGON((1.79769e+308 1.79769e+308, 20 5, -1.79769e+308 -1.79769e+308, 1.79769e+308 1.79769e+308))');
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRContains(g, @g1);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL ALL g NULL NULL NULL 1 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrcontains(`test`.`t1`.`g`,(@`g1`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL g NULL NULL NULL 1 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g1);
ST_AsText(g)
INSERT INTO t1 VALUES(@g1);
@@ -24,135 +22,105 @@ ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRContains(g, @g1);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL range g g 34 NULL 1 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrcontains(`test`.`t1`.`g`,(@`g1`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 1 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g1);
ST_AsText(g)
POINT(10 10)
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRDisjoint(g, @g1);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL range g g 34 NULL 2 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrdisjoint(`test`.`t1`.`g`,(@`g1`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 2 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g1);
ST_AsText(g)
POINT(10 10)
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBREquals(g, @g1);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL range g g 34 NULL 1 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrequals(`test`.`t1`.`g`,(@`g1`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 1 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g1);
ST_AsText(g)
POINT(10 10)
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRIntersects(g, @g1);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL range g g 34 NULL 1 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrintersects(`test`.`t1`.`g`,(@`g1`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 1 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g1);
ST_AsText(g)
POINT(10 10)
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g1);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL range g g 34 NULL 1 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrwithin(`test`.`t1`.`g`,(@`g1`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 1 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g1);
ST_AsText(g)
POINT(10 10)
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRContains(g, @g2);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL range g g 34 NULL 1 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrcontains(`test`.`t1`.`g`,(@`g2`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 1 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g2);
ST_AsText(g)
POINT(10 10)
POLYGON((5 5,20 5,20 21,5 21,5 5))
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRDisjoint(g, @g2);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL range g g 34 NULL 1 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrdisjoint(`test`.`t1`.`g`,(@`g2`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 1 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g2);
ST_AsText(g)
POINT(10 10)
POLYGON((5 5,20 5,20 21,5 21,5 5))
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBREquals(g, @g2);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL range g g 34 NULL 1 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrequals(`test`.`t1`.`g`,(@`g2`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 1 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g2);
ST_AsText(g)
POINT(10 10)
POLYGON((5 5,20 5,20 21,5 21,5 5))
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRIntersects(g, @g2);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL range g g 34 NULL 2 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrintersects(`test`.`t1`.`g`,(@`g2`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 2 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g2);
ST_AsText(g)
POINT(10 10)
POLYGON((5 5,20 5,20 21,5 21,5 5))
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g2);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL range g g 34 NULL 2 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrwithin(`test`.`t1`.`g`,(@`g2`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 2 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g2);
ST_AsText(g)
POINT(10 10)
POLYGON((5 5,20 5,20 21,5 21,5 5))
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRContains(g, @g3);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL ALL g NULL NULL NULL 3 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrcontains(`test`.`t1`.`g`,(@`g3`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL g NULL NULL NULL 3 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g3);
ST_AsText(g)
POINT(10 10)
POLYGON((5 5,20 5,20 21,5 21,5 5))
POLYGON((1.79769e308 1.79769e308,20 5,-1.79769e308 -1.79769e308,1.79769e308 1.79769e308))
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRDisjoint(g, @g3);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL ALL g NULL NULL NULL 3 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrdisjoint(`test`.`t1`.`g`,(@`g3`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL g NULL NULL NULL 3 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g3);
ST_AsText(g)
POINT(10 10)
POLYGON((5 5,20 5,20 21,5 21,5 5))
POLYGON((1.79769e308 1.79769e308,20 5,-1.79769e308 -1.79769e308,1.79769e308 1.79769e308))
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBREquals(g, @g3);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL ALL g NULL NULL NULL 3 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrequals(`test`.`t1`.`g`,(@`g3`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL g NULL NULL NULL 3 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g3);
ST_AsText(g)
POINT(10 10)
POLYGON((5 5,20 5,20 21,5 21,5 5))
POLYGON((1.79769e308 1.79769e308,20 5,-1.79769e308 -1.79769e308,1.79769e308 1.79769e308))
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRIntersects(g, @g3);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL ALL g NULL NULL NULL 3 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrintersects(`test`.`t1`.`g`,(@`g3`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL g NULL NULL NULL 3 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g3);
ST_AsText(g)
POINT(10 10)
POLYGON((5 5,20 5,20 21,5 21,5 5))
POLYGON((1.79769e308 1.79769e308,20 5,-1.79769e308 -1.79769e308,1.79769e308 1.79769e308))
EXPLAIN SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g3);
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL ALL g NULL NULL NULL 3 100.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select st_astext(`test`.`t1`.`g`) AS `ST_AsText(g)` from `test`.`t1` where mbrwithin(`test`.`t1`.`g`,(@`g3`))
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL g NULL NULL NULL 3 Using where
SELECT ST_AsText(g) FROM t1 WHERE MBRWithin(g, @g3);
ST_AsText(g)
POINT(10 10)
diff --git a/mysql-test/suite/innodb_gis/r/rtree_old.result b/mysql-test/suite/innodb_gis/r/rtree_old.result
deleted file mode 100644
index 30a1bdcc375..00000000000
--- a/mysql-test/suite/innodb_gis/r/rtree_old.result
+++ /dev/null
@@ -1,1821 +0,0 @@
-DROP TABLE IF EXISTS t1, t2;
-CREATE TABLE t1 (
-fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-g GEOMETRY NOT NULL,
-SPATIAL KEY(g)
-) ENGINE=InnoDB;
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `fid` int(11) NOT NULL AUTO_INCREMENT,
- `g` geometry NOT NULL,
- PRIMARY KEY (`fid`),
- SPATIAL KEY `g` (`g`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(150 150, 150 150)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(149 149, 151 151)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(148 148, 152 152)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(147 147, 153 153)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(146 146, 154 154)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(145 145, 155 155)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(144 144, 156 156)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(143 143, 157 157)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(142 142, 158 158)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(141 141, 159 159)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(140 140, 160 160)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(139 139, 161 161)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(138 138, 162 162)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(137 137, 163 163)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(136 136, 164 164)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(135 135, 165 165)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(134 134, 166 166)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(133 133, 167 167)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(132 132, 168 168)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(131 131, 169 169)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(130 130, 170 170)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(129 129, 171 171)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(128 128, 172 172)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(127 127, 173 173)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(126 126, 174 174)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(125 125, 175 175)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(124 124, 176 176)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(123 123, 177 177)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(122 122, 178 178)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(121 121, 179 179)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(120 120, 180 180)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(119 119, 181 181)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(118 118, 182 182)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(117 117, 183 183)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(116 116, 184 184)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(115 115, 185 185)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(114 114, 186 186)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(113 113, 187 187)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(112 112, 188 188)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(111 111, 189 189)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(110 110, 190 190)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(109 109, 191 191)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(108 108, 192 192)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(107 107, 193 193)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(106 106, 194 194)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(105 105, 195 195)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(104 104, 196 196)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(103 103, 197 197)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(102 102, 198 198)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(101 101, 199 199)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(100 100, 200 200)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(99 99, 201 201)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(98 98, 202 202)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(97 97, 203 203)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(96 96, 204 204)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(95 95, 205 205)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(94 94, 206 206)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(93 93, 207 207)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(92 92, 208 208)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(91 91, 209 209)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(90 90, 210 210)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(89 89, 211 211)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(88 88, 212 212)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(87 87, 213 213)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(86 86, 214 214)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(85 85, 215 215)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(84 84, 216 216)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(83 83, 217 217)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(82 82, 218 218)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(81 81, 219 219)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(80 80, 220 220)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(79 79, 221 221)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(78 78, 222 222)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(77 77, 223 223)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(76 76, 224 224)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(75 75, 225 225)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(74 74, 226 226)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(73 73, 227 227)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(72 72, 228 228)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(71 71, 229 229)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(70 70, 230 230)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(69 69, 231 231)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(68 68, 232 232)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(67 67, 233 233)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(66 66, 234 234)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(65 65, 235 235)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(64 64, 236 236)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(63 63, 237 237)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(62 62, 238 238)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(61 61, 239 239)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(60 60, 240 240)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(59 59, 241 241)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(58 58, 242 242)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(57 57, 243 243)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(56 56, 244 244)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(55 55, 245 245)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(54 54, 246 246)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(53 53, 247 247)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(52 52, 248 248)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(51 51, 249 249)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(50 50, 250 250)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(49 49, 251 251)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(48 48, 252 252)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(47 47, 253 253)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(46 46, 254 254)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(45 45, 255 255)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(44 44, 256 256)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(43 43, 257 257)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(42 42, 258 258)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(41 41, 259 259)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(40 40, 260 260)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(39 39, 261 261)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(38 38, 262 262)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(37 37, 263 263)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(36 36, 264 264)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(35 35, 265 265)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(34 34, 266 266)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(33 33, 267 267)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(32 32, 268 268)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(31 31, 269 269)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(30 30, 270 270)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(29 29, 271 271)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(28 28, 272 272)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(27 27, 273 273)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(26 26, 274 274)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(25 25, 275 275)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(24 24, 276 276)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(23 23, 277 277)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(22 22, 278 278)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(21 21, 279 279)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(20 20, 280 280)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(19 19, 281 281)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(18 18, 282 282)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(17 17, 283 283)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(16 16, 284 284)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(15 15, 285 285)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(14 14, 286 286)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(13 13, 287 287)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(12 12, 288 288)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(11 11, 289 289)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(10 10, 290 290)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(9 9, 291 291)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(8 8, 292 292)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(7 7, 293 293)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(6 6, 294 294)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(5 5, 295 295)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(4 4, 296 296)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(3 3, 297 297)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(2 2, 298 298)'));
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(1 1, 299 299)'));
-SELECT count(*) FROM t1;
-count(*)
-150
-SELECT fid, ST_AsText(g) FROM t1 WHERE MBRWithin(g, ST_GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))')) ORDER BY fid;
-fid ST_AsText(g)
-1 LINESTRING(150 150,150 150)
-2 LINESTRING(149 149,151 151)
-3 LINESTRING(148 148,152 152)
-4 LINESTRING(147 147,153 153)
-5 LINESTRING(146 146,154 154)
-6 LINESTRING(145 145,155 155)
-7 LINESTRING(144 144,156 156)
-8 LINESTRING(143 143,157 157)
-9 LINESTRING(142 142,158 158)
-10 LINESTRING(141 141,159 159)
-11 LINESTRING(140 140,160 160)
-DROP TABLE t1;
-CREATE TABLE t2 (
-fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-g GEOMETRY NOT NULL
-) ENGINE=InnoDB;
-INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10)));
-INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10)));
-ALTER TABLE t2 ADD SPATIAL KEY(g);
-SHOW CREATE TABLE t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `fid` int(11) NOT NULL AUTO_INCREMENT,
- `g` geometry NOT NULL,
- PRIMARY KEY (`fid`),
- SPATIAL KEY `g` (`g`)
-) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=latin1
-SELECT count(*) FROM t2;
-count(*)
-100
-SELECT fid, ST_AsText(g) FROM t2 WHERE MBRWithin(g,
-ST_GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))')) ORDER BY fid;
-fid ST_AsText(g)
-45 LINESTRING(51 51,60 60)
-46 LINESTRING(51 41,60 50)
-55 LINESTRING(41 51,50 60)
-56 LINESTRING(41 41,50 50)
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10))));
-Warnings:
-Warning 3196 st_geometryfromwkb(geometry, srid) is deprecated and will be replaced by st_srid(geometry, srid) in a future version. Use st_geometryfromwkb(st_aswkb(geometry), srid) instead.
-SELECT count(*) FROM t2;
-count(*)
-100
-DROP TABLE t2;
-drop table if exists t1;
-Warnings:
-Note 1051 Unknown table 'test.t1'
-CREATE TABLE t1 (a geometry NOT NULL, SPATIAL (a));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-check table t1;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-analyze table t1;
-Table Op Msg_type Msg_text
-test.t1 analyze status OK
-drop table t1;
-CREATE TABLE t1 (
-fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-g GEOMETRY NOT NULL,
-SPATIAL KEY(g)
-) ENGINE=InnoDB;
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(1 2, 2 3)')),(ST_GeomFromText('LineString(1 2, 2 4)'));
-drop table t1;
-CREATE TABLE t1 (
-line LINESTRING NOT NULL,
-kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
-name VARCHAR(32),
-SPATIAL KEY (line)
-) engine=InnoDB;
-ALTER TABLE t1 DISABLE KEYS;
-Warnings:
-Note 1031 Table storage engine for 't1' doesn't have this option
-INSERT INTO t1 (name, kind, line) VALUES
-("Aadaouane", "pp", ST_GeomFromText("POINT(32.816667 35.983333)")),
-("Aadassiye", "pp", ST_GeomFromText("POINT(35.816667 36.216667)")),
-("Aadbel", "pp", ST_GeomFromText("POINT(34.533333 36.100000)")),
-("Aadchit", "pp", ST_GeomFromText("POINT(33.347222 35.423611)")),
-("Aadchite", "pp", ST_GeomFromText("POINT(33.347222 35.423611)")),
-("Aadchit el Qoussair", "pp", ST_GeomFromText("POINT(33.283333 35.483333)")),
-("Aaddaye", "pp", ST_GeomFromText("POINT(36.716667 40.833333)")),
-("'Aadeissa", "pp", ST_GeomFromText("POINT(32.823889 35.698889)")),
-("Aaderup", "pp", ST_GeomFromText("POINT(55.216667 11.766667)")),
-("Qalaat Aades", "pp", ST_GeomFromText("POINT(33.503333 35.377500)")),
-("A ad'ino", "pp", ST_GeomFromText("POINT(54.812222 38.209167)")),
-("Aadi Noia", "pp", ST_GeomFromText("POINT(13.800000 39.833333)")),
-("Aad La Macta", "pp", ST_GeomFromText("POINT(35.779444 -0.129167)")),
-("Aadland", "pp", ST_GeomFromText("POINT(60.366667 5.483333)")),
-("Aadliye", "pp", ST_GeomFromText("POINT(33.366667 36.333333)")),
-("Aadloun", "pp", ST_GeomFromText("POINT(33.403889 35.273889)")),
-("Aadma", "pp", ST_GeomFromText("POINT(58.798333 22.663889)")),
-("Aadma Asundus", "pp", ST_GeomFromText("POINT(58.798333 22.663889)")),
-("Aadmoun", "pp", ST_GeomFromText("POINT(34.150000 35.650000)")),
-("Aadneram", "pp", ST_GeomFromText("POINT(59.016667 6.933333)")),
-("Aadneskaar", "pp", ST_GeomFromText("POINT(58.083333 6.983333)")),
-("Aadorf", "pp", ST_GeomFromText("POINT(47.483333 8.900000)")),
-("Aadorp", "pp", ST_GeomFromText("POINT(52.366667 6.633333)")),
-("Aadouane", "pp", ST_GeomFromText("POINT(32.816667 35.983333)")),
-("Aadoui", "pp", ST_GeomFromText("POINT(34.450000 35.983333)")),
-("Aadouiye", "pp", ST_GeomFromText("POINT(34.583333 36.183333)")),
-("Aadouss", "pp", ST_GeomFromText("POINT(33.512500 35.601389)")),
-("Aadra", "pp", ST_GeomFromText("POINT(33.616667 36.500000)")),
-("Aadzi", "pp", ST_GeomFromText("POINT(38.100000 64.850000)"));
-ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
-ALTER TABLE t1 ENABLE KEYS;
-Warnings:
-Note 1031 Table storage engine for 't1' doesn't have this option
-INSERT INTO t1 (name, kind, line) VALUES ("austria", "pp", ST_GeomFromText('LINESTRING(14.9906 48.9887,14.9946 48.9904,14.9947 48.9916)'));
-drop table t1;
-CREATE TABLE t1 (st varchar(100));
-INSERT INTO t1 VALUES ("Fake string");
-CREATE TABLE t2 (geom GEOMETRY NOT NULL, SPATIAL KEY gk(geom));
-INSERT INTO t2 SELECT ST_GeomFromText(st) FROM t1;
-ERROR 22023: Invalid GIS data provided to function st_geometryfromtext.
-drop table t1, t2;
-SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
-Warnings:
-Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
-CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-Warnings:
-Warning 1101 BLOB, TEXT, GEOMETRY or JSON column 'geometry' can't have a default value
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000
--66.8158332999, -18.7186111000 -66.8102777000, -18.7211111000 -66.9269443999,
--18.6086111000 -66.9327777000))'));
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((-65.7402776999 -96.6686111000, -65.7372222000
--96.5516666000, -65.8502777000 -96.5461111000, -65.8527777000 -96.6627777000,
--65.7402776999 -96.6686111000))'));
-check table t1 extended;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-drop table t1;
-CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-Warnings:
-Warning 1101 BLOB, TEXT, GEOMETRY or JSON column 'geometry' can't have a default value
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((2 2, 2 8, 10 8, 10 2, 2 2))'));
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((2 12, 15 12, 15 18, 2 18, 2 12))'));
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((3 5, 3 18, 10 18, 10 5, 3 5))'));
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((4 6, 4 8, 10 8, 10 4, 4 6))'));
-set @g1 = ST_GeomFromText('Polygon((0 0,0 1000,1000 1000,1000 0,0 0))');
-select count(*) from t1 where MBRWithin(t1.geometry, @g1);
-count(*)
-4
-start transaction;
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((4 6, 4 8, 10 8, 10 4, 4 6))'));
-select count(*) from t1 where MBRWithin(t1.geometry, @g1);
-count(*)
-5
-rollback;
-select count(*) from t1 where MBRWithin(t1.geometry, @g1);
-count(*)
-4
-set @g2 = ST_GeomFromText('POINT(2 2)');
-select count(*) from t1 where MBRcontains(t1.geometry, @g2);
-count(*)
-0
-select count(*) from t1 where MBRintersects(t1.geometry, @g2);
-count(*)
-1
-set @g3 = ST_GeomFromText('LINESTRING(2 2, 2 12)');
-select count(*) from t1 where MBRintersects(t1.geometry, @g3);
-count(*)
-2
-DROP TABLE t1;
-CREATE TABLE t1 (
-c1 geometry NOT NULL default '',
-SPATIAL KEY i1 (c1)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-Warnings:
-Warning 1101 BLOB, TEXT, GEOMETRY or JSON column 'c1' can't have a default value
-INSERT INTO t1 (c1) VALUES (
-ST_PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
- -18.6055555000 -66.8158332999,
- -18.7186111000 -66.8102777000,
- -18.7211111000 -66.9269443999,
- -18.6086111000 -66.9327777000))'));
-CHECK TABLE t1 EXTENDED;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-DROP TABLE t1;
-CREATE TABLE t1 (
-c1 geometry NOT NULL default '',
-SPATIAL KEY i1 (c1)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-Warnings:
-Warning 1101 BLOB, TEXT, GEOMETRY or JSON column 'c1' can't have a default value
-INSERT INTO t1 (c1) VALUES (
-ST_PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
- -18.6055555000 -66.8158332999,
- -18.7186111000 -66.8102777000,
- -18.7211111000 -66.9269443999,
- -18.6086111000 -66.9327777000))'));
-INSERT INTO t1 (c1) VALUES (
-ST_PolygonFromText('POLYGON((-65.7402776999 -96.6686111000,
- -65.7372222000 -96.5516666000,
- -65.8502777000 -96.5461111000,
- -65.8527777000 -96.6627777000,
- -65.7402776999 -96.6686111000))'));
-INSERT INTO t1 (c1) VALUES (
-ST_PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
- -18.6055555000 -66.8158332999,
- -18.7186111000 -66.8102777000,
- -18.7211111000 -66.9269443999,
- -18.6086111000 -66.9327777000))'));
-CHECK TABLE t1 EXTENDED;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-DROP TABLE t1;
-SET sql_mode = default;
-CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
-INSERT INTO t1 (foo) VALUES (POINT(1,1));
-INSERT INTO t1 (foo) VALUES (POINT(1,0));
-INSERT INTO t1 (foo) VALUES (POINT(0,1));
-INSERT INTO t1 (foo) VALUES (POINT(0,0));
-SELECT 1 FROM t1 WHERE foo != POINT(0,0);
-1
-1
-1
-1
-DROP TABLE t1;
-CREATE TABLE t1 (id bigint(12) unsigned NOT NULL auto_increment,
-c2 varchar(15) collate utf8_bin default NULL,
-c1 varchar(15) collate utf8_bin default NULL,
-c3 varchar(10) collate utf8_bin default NULL,
-spatial_point point NOT NULL,
-PRIMARY KEY(id),
-SPATIAL KEY (spatial_point)
-)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
-('y', 's', 'j', ST_GeomFromText('POINT(167 74)')),
-('r', 'n', 'd', ST_GeomFromText('POINT(215 118)')),
-('g', 'n', 'e', ST_GeomFromText('POINT(203 98)')),
-('h', 'd', 'd', ST_GeomFromText('POINT(54 193)')),
-('r', 'x', 'y', ST_GeomFromText('POINT(47 69)')),
-('t', 'q', 'r', ST_GeomFromText('POINT(109 42)')),
-('a', 'z', 'd', ST_GeomFromText('POINT(0 154)')),
-('x', 'v', 'o', ST_GeomFromText('POINT(174 131)')),
-('b', 'r', 'a', ST_GeomFromText('POINT(114 253)')),
-('x', 'z', 'i', ST_GeomFromText('POINT(163 21)')),
-('w', 'p', 'i', ST_GeomFromText('POINT(42 102)')),
-('g', 'j', 'j', ST_GeomFromText('POINT(170 133)')),
-('m', 'g', 'n', ST_GeomFromText('POINT(28 22)')),
-('b', 'z', 'h', ST_GeomFromText('POINT(174 28)')),
-('q', 'k', 'f', ST_GeomFromText('POINT(233 73)')),
-('w', 'w', 'a', ST_GeomFromText('POINT(124 200)')),
-('t', 'j', 'w', ST_GeomFromText('POINT(252 101)')),
-('d', 'r', 'd', ST_GeomFromText('POINT(98 18)')),
-('w', 'o', 'y', ST_GeomFromText('POINT(165 31)')),
-('y', 'h', 't', ST_GeomFromText('POINT(14 220)')),
-('d', 'p', 'u', ST_GeomFromText('POINT(223 196)')),
-('g', 'y', 'g', ST_GeomFromText('POINT(207 96)')),
-('x', 'm', 'n', ST_GeomFromText('POINT(214 3)')),
-('g', 'v', 'e', ST_GeomFromText('POINT(140 205)')),
-('g', 'm', 'm', ST_GeomFromText('POINT(10 236)')),
-('i', 'r', 'j', ST_GeomFromText('POINT(137 228)')),
-('w', 's', 'p', ST_GeomFromText('POINT(115 6)')),
-('o', 'n', 'k', ST_GeomFromText('POINT(158 129)')),
-('j', 'h', 'l', ST_GeomFromText('POINT(129 72)')),
-('f', 'x', 'l', ST_GeomFromText('POINT(139 207)')),
-('u', 'd', 'n', ST_GeomFromText('POINT(125 109)')),
-('b', 'a', 'z', ST_GeomFromText('POINT(30 32)')),
-('m', 'h', 'o', ST_GeomFromText('POINT(251 251)')),
-('f', 'r', 'd', ST_GeomFromText('POINT(243 211)')),
-('b', 'd', 'r', ST_GeomFromText('POINT(232 80)')),
-('g', 'k', 'v', ST_GeomFromText('POINT(15 100)')),
-('i', 'f', 'c', ST_GeomFromText('POINT(109 66)')),
-('r', 't', 'j', ST_GeomFromText('POINT(178 6)')),
-('y', 'n', 'f', ST_GeomFromText('POINT(233 211)')),
-('f', 'y', 'm', ST_GeomFromText('POINT(99 16)')),
-('z', 'q', 'l', ST_GeomFromText('POINT(39 49)')),
-('j', 'c', 'r', ST_GeomFromText('POINT(75 187)')),
-('c', 'y', 'y', ST_GeomFromText('POINT(246 253)')),
-('w', 'u', 'd', ST_GeomFromText('POINT(56 190)')),
-('n', 'q', 'm', ST_GeomFromText('POINT(73 149)')),
-('d', 'y', 'a', ST_GeomFromText('POINT(134 6)')),
-('z', 's', 'w', ST_GeomFromText('POINT(216 225)')),
-('d', 'u', 'k', ST_GeomFromText('POINT(132 70)')),
-('f', 'v', 't', ST_GeomFromText('POINT(187 141)')),
-('r', 'r', 'a', ST_GeomFromText('POINT(152 39)')),
-('y', 'p', 'o', ST_GeomFromText('POINT(45 27)')),
-('p', 'n', 'm', ST_GeomFromText('POINT(228 148)')),
-('e', 'g', 'e', ST_GeomFromText('POINT(88 81)')),
-('m', 'a', 'h', ST_GeomFromText('POINT(35 29)')),
-('m', 'h', 'f', ST_GeomFromText('POINT(30 71)')),
-('h', 'k', 'i', ST_GeomFromText('POINT(244 78)')),
-('z', 'v', 'd', ST_GeomFromText('POINT(241 38)')),
-('q', 'l', 'j', ST_GeomFromText('POINT(13 71)')),
-('s', 'p', 'g', ST_GeomFromText('POINT(108 38)')),
-('q', 's', 'j', ST_GeomFromText('POINT(92 101)')),
-('l', 'h', 'g', ST_GeomFromText('POINT(120 78)')),
-('w', 't', 'b', ST_GeomFromText('POINT(193 109)')),
-('b', 's', 's', ST_GeomFromText('POINT(223 211)')),
-('w', 'w', 'y', ST_GeomFromText('POINT(122 42)')),
-('q', 'c', 'c', ST_GeomFromText('POINT(104 102)')),
-('w', 'g', 'n', ST_GeomFromText('POINT(213 120)')),
-('p', 'q', 'a', ST_GeomFromText('POINT(247 148)')),
-('c', 'z', 'e', ST_GeomFromText('POINT(18 106)')),
-('z', 'u', 'n', ST_GeomFromText('POINT(70 133)')),
-('j', 'n', 'x', ST_GeomFromText('POINT(232 13)')),
-('e', 'h', 'f', ST_GeomFromText('POINT(22 135)')),
-('w', 'l', 'f', ST_GeomFromText('POINT(9 180)')),
-('a', 'v', 'q', ST_GeomFromText('POINT(163 228)')),
-('i', 'z', 'o', ST_GeomFromText('POINT(180 100)')),
-('e', 'c', 'l', ST_GeomFromText('POINT(182 231)')),
-('c', 'k', 'o', ST_GeomFromText('POINT(19 60)')),
-('q', 'f', 'p', ST_GeomFromText('POINT(79 95)')),
-('m', 'd', 'r', ST_GeomFromText('POINT(3 127)')),
-('m', 'e', 't', ST_GeomFromText('POINT(136 154)')),
-('w', 'w', 'w', ST_GeomFromText('POINT(102 15)')),
-('l', 'n', 'q', ST_GeomFromText('POINT(71 196)')),
-('p', 'k', 'c', ST_GeomFromText('POINT(47 139)')),
-('j', 'o', 'r', ST_GeomFromText('POINT(177 128)')),
-('j', 'q', 'a', ST_GeomFromText('POINT(170 6)')),
-('b', 'a', 'o', ST_GeomFromText('POINT(63 211)')),
-('g', 's', 'o', ST_GeomFromText('POINT(144 251)')),
-('w', 'u', 'w', ST_GeomFromText('POINT(221 214)')),
-('g', 'a', 'm', ST_GeomFromText('POINT(14 102)')),
-('u', 'q', 'z', ST_GeomFromText('POINT(86 200)')),
-('k', 'a', 'm', ST_GeomFromText('POINT(144 222)')),
-('j', 'u', 'r', ST_GeomFromText('POINT(216 142)')),
-('q', 'k', 'v', ST_GeomFromText('POINT(121 236)')),
-('p', 'o', 'r', ST_GeomFromText('POINT(108 102)')),
-('b', 'd', 'x', ST_GeomFromText('POINT(127 198)')),
-('k', 's', 'a', ST_GeomFromText('POINT(2 150)')),
-('f', 'm', 'f', ST_GeomFromText('POINT(160 191)')),
-('q', 'y', 'x', ST_GeomFromText('POINT(98 111)')),
-('o', 'f', 'm', ST_GeomFromText('POINT(232 218)')),
-('c', 'w', 'j', ST_GeomFromText('POINT(156 165)')),
-('s', 'q', 'v', ST_GeomFromText('POINT(98 161)'));
-SET @@RAND_SEED1=692635050, @@RAND_SEED2=297339954;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=159925977, @@RAND_SEED2=942570618;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=328169745, @@RAND_SEED2=410451954;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=178507359, @@RAND_SEED2=332493072;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=1034033013, @@RAND_SEED2=558966507;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(230 9)') where c1 like 'y%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(95 35)') where c1 like 'j%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(93 99)') where c1 like 'a%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(19 81)') where c1 like 'r%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(20 177)') where c1 like 'h%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(221 193)') where c1 like 'u%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(195 205)') where c1 like 'd%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(15 213)') where c1 like 'u%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(214 63)') where c1 like 'n%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(243 171)') where c1 like 'c%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(198 82)') where c1 like 'y%';
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
-('f', 'y', 'p', ST_GeomFromText('POINT(109 235)')),
-('b', 'e', 'v', ST_GeomFromText('POINT(20 48)')),
-('i', 'u', 'f', ST_GeomFromText('POINT(15 55)')),
-('o', 'r', 'z', ST_GeomFromText('POINT(105 64)')),
-('a', 'p', 'a', ST_GeomFromText('POINT(142 236)')),
-('g', 'i', 'k', ST_GeomFromText('POINT(10 49)')),
-('x', 'z', 'x', ST_GeomFromText('POINT(192 200)')),
-('c', 'v', 'r', ST_GeomFromText('POINT(94 168)')),
-('y', 'z', 'e', ST_GeomFromText('POINT(141 51)')),
-('h', 'm', 'd', ST_GeomFromText('POINT(35 251)')),
-('v', 'm', 'q', ST_GeomFromText('POINT(44 90)')),
-('j', 'l', 'z', ST_GeomFromText('POINT(67 237)')),
-('i', 'v', 'a', ST_GeomFromText('POINT(75 14)')),
-('b', 'q', 't', ST_GeomFromText('POINT(153 33)')),
-('e', 'm', 'a', ST_GeomFromText('POINT(247 49)')),
-('l', 'y', 'g', ST_GeomFromText('POINT(56 203)')),
-('v', 'o', 'r', ST_GeomFromText('POINT(90 54)')),
-('r', 'n', 'd', ST_GeomFromText('POINT(135 83)')),
-('j', 't', 'u', ST_GeomFromText('POINT(174 239)')),
-('u', 'n', 'g', ST_GeomFromText('POINT(104 191)')),
-('p', 'q', 'y', ST_GeomFromText('POINT(63 171)')),
-('o', 'q', 'p', ST_GeomFromText('POINT(192 103)')),
-('f', 'x', 'e', ST_GeomFromText('POINT(244 30)')),
-('n', 'x', 'c', ST_GeomFromText('POINT(92 103)')),
-('r', 'q', 'z', ST_GeomFromText('POINT(166 20)')),
-('s', 'a', 'j', ST_GeomFromText('POINT(137 205)')),
-('z', 't', 't', ST_GeomFromText('POINT(99 134)')),
-('o', 'm', 'j', ST_GeomFromText('POINT(217 3)')),
-('n', 'h', 'j', ST_GeomFromText('POINT(211 17)')),
-('v', 'v', 'a', ST_GeomFromText('POINT(41 137)')),
-('q', 'o', 'j', ST_GeomFromText('POINT(5 92)')),
-('z', 'y', 'e', ST_GeomFromText('POINT(175 212)')),
-('j', 'z', 'h', ST_GeomFromText('POINT(224 194)')),
-('a', 'g', 'm', ST_GeomFromText('POINT(31 119)')),
-('p', 'c', 'f', ST_GeomFromText('POINT(17 221)')),
-('t', 'h', 'k', ST_GeomFromText('POINT(26 203)')),
-('u', 'w', 'p', ST_GeomFromText('POINT(47 185)')),
-('z', 'a', 'c', ST_GeomFromText('POINT(61 133)')),
-('u', 'k', 'a', ST_GeomFromText('POINT(210 115)')),
-('k', 'f', 'h', ST_GeomFromText('POINT(125 113)')),
-('t', 'v', 'y', ST_GeomFromText('POINT(12 239)')),
-('u', 'v', 'd', ST_GeomFromText('POINT(90 24)')),
-('m', 'y', 'w', ST_GeomFromText('POINT(25 243)')),
-('d', 'n', 'g', ST_GeomFromText('POINT(122 92)')),
-('z', 'm', 'f', ST_GeomFromText('POINT(235 110)')),
-('q', 'd', 'f', ST_GeomFromText('POINT(233 217)')),
-('a', 'v', 'u', ST_GeomFromText('POINT(69 59)')),
-('x', 'k', 'p', ST_GeomFromText('POINT(240 14)')),
-('i', 'v', 'r', ST_GeomFromText('POINT(154 42)')),
-('w', 'h', 'l', ST_GeomFromText('POINT(178 156)')),
-('d', 'h', 'n', ST_GeomFromText('POINT(65 157)')),
-('c', 'k', 'z', ST_GeomFromText('POINT(62 33)')),
-('e', 'l', 'w', ST_GeomFromText('POINT(162 1)')),
-('r', 'f', 'i', ST_GeomFromText('POINT(127 71)')),
-('q', 'm', 'c', ST_GeomFromText('POINT(63 118)')),
-('c', 'h', 'u', ST_GeomFromText('POINT(205 203)')),
-('d', 't', 'p', ST_GeomFromText('POINT(234 87)')),
-('s', 'g', 'h', ST_GeomFromText('POINT(149 34)')),
-('o', 'b', 'q', ST_GeomFromText('POINT(159 179)')),
-('k', 'u', 'f', ST_GeomFromText('POINT(202 254)')),
-('u', 'f', 'g', ST_GeomFromText('POINT(70 15)')),
-('x', 's', 'b', ST_GeomFromText('POINT(25 181)')),
-('s', 'c', 'g', ST_GeomFromText('POINT(252 17)')),
-('a', 'c', 'f', ST_GeomFromText('POINT(89 67)')),
-('r', 'e', 'q', ST_GeomFromText('POINT(55 54)')),
-('f', 'i', 'k', ST_GeomFromText('POINT(178 230)')),
-('p', 'e', 'l', ST_GeomFromText('POINT(198 28)')),
-('w', 'o', 'd', ST_GeomFromText('POINT(204 189)')),
-('c', 'a', 'g', ST_GeomFromText('POINT(230 178)')),
-('r', 'o', 'e', ST_GeomFromText('POINT(61 116)')),
-('w', 'a', 'a', ST_GeomFromText('POINT(178 237)')),
-('v', 'd', 'e', ST_GeomFromText('POINT(70 85)')),
-('k', 'c', 'e', ST_GeomFromText('POINT(147 118)')),
-('d', 'q', 't', ST_GeomFromText('POINT(218 77)')),
-('k', 'g', 'f', ST_GeomFromText('POINT(192 113)')),
-('w', 'n', 'e', ST_GeomFromText('POINT(92 124)')),
-('r', 'm', 'q', ST_GeomFromText('POINT(130 65)')),
-('o', 'r', 'r', ST_GeomFromText('POINT(174 233)')),
-('k', 'n', 't', ST_GeomFromText('POINT(175 147)')),
-('q', 'm', 'r', ST_GeomFromText('POINT(18 208)')),
-('l', 'd', 'i', ST_GeomFromText('POINT(13 104)')),
-('w', 'o', 'y', ST_GeomFromText('POINT(207 39)')),
-('p', 'u', 'o', ST_GeomFromText('POINT(114 31)')),
-('y', 'a', 'p', ST_GeomFromText('POINT(106 59)')),
-('a', 'x', 'z', ST_GeomFromText('POINT(17 57)')),
-('v', 'h', 'x', ST_GeomFromText('POINT(170 13)')),
-('t', 's', 'u', ST_GeomFromText('POINT(84 18)')),
-('z', 'z', 'f', ST_GeomFromText('POINT(250 197)')),
-('l', 'z', 't', ST_GeomFromText('POINT(59 80)')),
-('j', 'g', 's', ST_GeomFromText('POINT(54 26)')),
-('g', 'v', 'm', ST_GeomFromText('POINT(89 98)')),
-('q', 'v', 'b', ST_GeomFromText('POINT(39 240)')),
-('x', 'k', 'v', ST_GeomFromText('POINT(246 207)')),
-('k', 'u', 'i', ST_GeomFromText('POINT(105 111)')),
-('w', 'z', 's', ST_GeomFromText('POINT(235 8)')),
-('d', 'd', 'd', ST_GeomFromText('POINT(105 4)')),
-('c', 'z', 'q', ST_GeomFromText('POINT(13 140)')),
-('m', 'k', 'i', ST_GeomFromText('POINT(208 120)')),
-('g', 'a', 'g', ST_GeomFromText('POINT(9 182)')),
-('z', 'j', 'r', ST_GeomFromText('POINT(149 153)')),
-('h', 'f', 'g', ST_GeomFromText('POINT(81 236)')),
-('m', 'e', 'q', ST_GeomFromText('POINT(209 215)')),
-('c', 'h', 'y', ST_GeomFromText('POINT(235 70)')),
-('i', 'e', 'g', ST_GeomFromText('POINT(138 26)')),
-('m', 't', 'u', ST_GeomFromText('POINT(119 237)')),
-('o', 'w', 's', ST_GeomFromText('POINT(193 166)')),
-('f', 'm', 'q', ST_GeomFromText('POINT(85 96)')),
-('x', 'l', 'x', ST_GeomFromText('POINT(58 115)')),
-('x', 'q', 'u', ST_GeomFromText('POINT(108 210)')),
-('b', 'h', 'i', ST_GeomFromText('POINT(250 139)')),
-('y', 'd', 'x', ST_GeomFromText('POINT(199 135)')),
-('w', 'h', 'p', ST_GeomFromText('POINT(247 233)')),
-('p', 'z', 't', ST_GeomFromText('POINT(148 249)')),
-('q', 'a', 'u', ST_GeomFromText('POINT(174 78)')),
-('v', 't', 'm', ST_GeomFromText('POINT(70 228)')),
-('t', 'n', 'f', ST_GeomFromText('POINT(123 2)')),
-('x', 't', 'b', ST_GeomFromText('POINT(35 50)')),
-('r', 'j', 'f', ST_GeomFromText('POINT(200 51)')),
-('s', 'q', 'o', ST_GeomFromText('POINT(23 184)')),
-('u', 'v', 'z', ST_GeomFromText('POINT(7 113)')),
-('v', 'u', 'l', ST_GeomFromText('POINT(145 190)')),
-('o', 'k', 'i', ST_GeomFromText('POINT(161 122)')),
-('l', 'y', 'e', ST_GeomFromText('POINT(17 232)')),
-('t', 'b', 'e', ST_GeomFromText('POINT(120 50)')),
-('e', 's', 'u', ST_GeomFromText('POINT(254 1)')),
-('d', 'd', 'u', ST_GeomFromText('POINT(167 140)')),
-('o', 'b', 'x', ST_GeomFromText('POINT(186 237)')),
-('m', 's', 's', ST_GeomFromText('POINT(172 149)')),
-('t', 'y', 'a', ST_GeomFromText('POINT(149 85)')),
-('x', 't', 'r', ST_GeomFromText('POINT(10 165)')),
-('g', 'c', 'e', ST_GeomFromText('POINT(95 165)')),
-('e', 'e', 'z', ST_GeomFromText('POINT(98 65)')),
-('f', 'v', 'i', ST_GeomFromText('POINT(149 144)')),
-('o', 'p', 'm', ST_GeomFromText('POINT(233 67)')),
-('t', 'u', 'b', ST_GeomFromText('POINT(109 215)')),
-('o', 'o', 'b', ST_GeomFromText('POINT(130 48)')),
-('e', 'm', 'h', ST_GeomFromText('POINT(88 189)')),
-('e', 'v', 'y', ST_GeomFromText('POINT(55 29)')),
-('e', 't', 'm', ST_GeomFromText('POINT(129 55)')),
-('p', 'p', 'i', ST_GeomFromText('POINT(126 222)')),
-('c', 'i', 'c', ST_GeomFromText('POINT(19 158)')),
-('c', 'b', 's', ST_GeomFromText('POINT(13 19)')),
-('u', 'y', 'a', ST_GeomFromText('POINT(114 5)')),
-('a', 'o', 'f', ST_GeomFromText('POINT(227 232)')),
-('t', 'c', 'z', ST_GeomFromText('POINT(63 62)')),
-('d', 'o', 'k', ST_GeomFromText('POINT(48 228)')),
-('x', 'c', 'e', ST_GeomFromText('POINT(204 2)')),
-('e', 'e', 'g', ST_GeomFromText('POINT(125 43)')),
-('o', 'r', 'f', ST_GeomFromText('POINT(171 140)'));
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(163 157)') where c1 like 'w%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(53 151)') where c1 like 'd%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(96 183)') where c1 like 'r%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(57 91)') where c1 like 'q%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(202 110)') where c1 like 'c%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(120 137)') where c1 like 'w%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(207 147)') where c1 like 'c%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(31 125)') where c1 like 'e%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(27 36)') where c1 like 'r%';
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
-('b', 'c', 'e', ST_GeomFromText('POINT(41 137)')),
-('p', 'y', 'k', ST_GeomFromText('POINT(50 22)')),
-('s', 'c', 'h', ST_GeomFromText('POINT(208 173)')),
-('x', 'u', 'l', ST_GeomFromText('POINT(199 175)')),
-('s', 'r', 'h', ST_GeomFromText('POINT(85 192)')),
-('j', 'k', 'u', ST_GeomFromText('POINT(18 25)')),
-('p', 'w', 'h', ST_GeomFromText('POINT(152 197)')),
-('e', 'd', 'c', ST_GeomFromText('POINT(229 3)')),
-('o', 'x', 'k', ST_GeomFromText('POINT(187 155)')),
-('o', 'b', 'k', ST_GeomFromText('POINT(208 150)')),
-('d', 'a', 'j', ST_GeomFromText('POINT(70 87)')),
-('f', 'e', 'k', ST_GeomFromText('POINT(156 96)')),
-('u', 'y', 'p', ST_GeomFromText('POINT(239 193)')),
-('n', 'v', 'p', ST_GeomFromText('POINT(223 98)')),
-('z', 'j', 'r', ST_GeomFromText('POINT(87 89)')),
-('h', 'x', 'x', ST_GeomFromText('POINT(92 0)')),
-('r', 'v', 'r', ST_GeomFromText('POINT(159 139)')),
-('v', 'g', 'g', ST_GeomFromText('POINT(16 229)')),
-('z', 'k', 'u', ST_GeomFromText('POINT(99 52)')),
-('p', 'p', 'o', ST_GeomFromText('POINT(105 125)')),
-('w', 'h', 'y', ST_GeomFromText('POINT(105 154)')),
-('v', 'y', 'z', ST_GeomFromText('POINT(134 238)')),
-('x', 'o', 'o', ST_GeomFromText('POINT(178 88)')),
-('z', 'w', 'd', ST_GeomFromText('POINT(123 60)')),
-('q', 'f', 'u', ST_GeomFromText('POINT(64 90)')),
-('s', 'n', 't', ST_GeomFromText('POINT(50 138)')),
-('v', 'p', 't', ST_GeomFromText('POINT(114 91)')),
-('a', 'o', 'n', ST_GeomFromText('POINT(78 43)')),
-('k', 'u', 'd', ST_GeomFromText('POINT(185 161)')),
-('w', 'd', 'n', ST_GeomFromText('POINT(25 92)')),
-('k', 'w', 'a', ST_GeomFromText('POINT(59 238)')),
-('t', 'c', 'f', ST_GeomFromText('POINT(65 87)')),
-('g', 's', 'p', ST_GeomFromText('POINT(238 126)')),
-('d', 'n', 'y', ST_GeomFromText('POINT(107 173)')),
-('l', 'a', 'w', ST_GeomFromText('POINT(125 152)')),
-('m', 'd', 'j', ST_GeomFromText('POINT(146 53)')),
-('q', 'm', 'c', ST_GeomFromText('POINT(217 187)')),
-('i', 'r', 'r', ST_GeomFromText('POINT(6 113)')),
-('e', 'j', 'b', ST_GeomFromText('POINT(37 83)')),
-('w', 'w', 'h', ST_GeomFromText('POINT(83 199)')),
-('k', 'b', 's', ST_GeomFromText('POINT(170 64)')),
-('s', 'b', 'c', ST_GeomFromText('POINT(163 130)')),
-('c', 'h', 'a', ST_GeomFromText('POINT(141 3)')),
-('k', 'j', 'u', ST_GeomFromText('POINT(143 76)')),
-('r', 'h', 'o', ST_GeomFromText('POINT(243 92)')),
-('i', 'd', 'b', ST_GeomFromText('POINT(205 13)')),
-('r', 'y', 'q', ST_GeomFromText('POINT(138 8)')),
-('m', 'o', 'i', ST_GeomFromText('POINT(36 45)')),
-('v', 'g', 'm', ST_GeomFromText('POINT(0 40)')),
-('f', 'e', 'i', ST_GeomFromText('POINT(76 6)')),
-('c', 'q', 'q', ST_GeomFromText('POINT(115 248)')),
-('x', 'c', 'i', ST_GeomFromText('POINT(29 74)')),
-('l', 's', 't', ST_GeomFromText('POINT(83 18)')),
-('t', 't', 'a', ST_GeomFromText('POINT(26 168)')),
-('u', 'n', 'x', ST_GeomFromText('POINT(200 110)')),
-('j', 'b', 'd', ST_GeomFromText('POINT(216 136)')),
-('s', 'p', 'w', ST_GeomFromText('POINT(38 156)')),
-('f', 'b', 'v', ST_GeomFromText('POINT(29 186)')),
-('v', 'e', 'r', ST_GeomFromText('POINT(149 40)')),
-('v', 't', 'm', ST_GeomFromText('POINT(184 24)')),
-('y', 'g', 'a', ST_GeomFromText('POINT(219 105)')),
-('s', 'f', 'i', ST_GeomFromText('POINT(114 130)')),
-('e', 'q', 'h', ST_GeomFromText('POINT(203 135)')),
-('h', 'g', 'b', ST_GeomFromText('POINT(9 208)')),
-('o', 'l', 'r', ST_GeomFromText('POINT(245 79)')),
-('s', 's', 'v', ST_GeomFromText('POINT(238 198)')),
-('w', 'w', 'z', ST_GeomFromText('POINT(209 232)')),
-('v', 'd', 'n', ST_GeomFromText('POINT(30 193)')),
-('q', 'w', 'k', ST_GeomFromText('POINT(133 18)')),
-('o', 'h', 'o', ST_GeomFromText('POINT(42 140)')),
-('f', 'f', 'h', ST_GeomFromText('POINT(145 1)')),
-('u', 's', 'r', ST_GeomFromText('POINT(70 62)')),
-('x', 'n', 'q', ST_GeomFromText('POINT(33 86)')),
-('u', 'p', 'v', ST_GeomFromText('POINT(232 220)')),
-('z', 'e', 'a', ST_GeomFromText('POINT(130 69)')),
-('r', 'u', 'z', ST_GeomFromText('POINT(243 241)')),
-('b', 'n', 't', ST_GeomFromText('POINT(120 12)')),
-('u', 'f', 's', ST_GeomFromText('POINT(190 212)')),
-('a', 'd', 'q', ST_GeomFromText('POINT(235 191)')),
-('f', 'q', 'm', ST_GeomFromText('POINT(176 2)')),
-('n', 'c', 's', ST_GeomFromText('POINT(218 163)')),
-('e', 'm', 'h', ST_GeomFromText('POINT(163 108)')),
-('c', 'f', 'l', ST_GeomFromText('POINT(220 115)')),
-('c', 'v', 'q', ST_GeomFromText('POINT(66 45)')),
-('w', 'v', 'x', ST_GeomFromText('POINT(251 220)')),
-('f', 'w', 'z', ST_GeomFromText('POINT(146 149)')),
-('h', 'n', 'h', ST_GeomFromText('POINT(148 128)')),
-('y', 'k', 'v', ST_GeomFromText('POINT(28 110)')),
-('c', 'x', 'q', ST_GeomFromText('POINT(13 13)')),
-('e', 'd', 's', ST_GeomFromText('POINT(91 190)')),
-('c', 'w', 'c', ST_GeomFromText('POINT(10 231)')),
-('u', 'j', 'n', ST_GeomFromText('POINT(250 21)')),
-('w', 'n', 'x', ST_GeomFromText('POINT(141 69)')),
-('f', 'p', 'y', ST_GeomFromText('POINT(228 246)')),
-('d', 'q', 'f', ST_GeomFromText('POINT(194 22)')),
-('d', 'z', 'l', ST_GeomFromText('POINT(233 181)')),
-('c', 'a', 'q', ST_GeomFromText('POINT(183 96)')),
-('m', 'i', 'd', ST_GeomFromText('POINT(117 226)')),
-('z', 'y', 'y', ST_GeomFromText('POINT(62 81)')),
-('g', 'v', 'm', ST_GeomFromText('POINT(66 158)'));
-SET @@RAND_SEED1=481064922, @@RAND_SEED2=438133497;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=280535103, @@RAND_SEED2=444518646;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=1072017234, @@RAND_SEED2=484203885;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=358851897, @@RAND_SEED2=358495224;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=509031459, @@RAND_SEED2=675962925;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(202 194)') where c1 like 'f%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(228 18)') where c1 like 'h%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(88 18)') where c1 like 'l%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(176 94)') where c1 like 'e%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(44 47)') where c1 like 'g%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(95 191)') where c1 like 'b%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(179 218)') where c1 like 'y%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(239 40)') where c1 like 'g%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(248 41)') where c1 like 'q%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(167 82)') where c1 like 't%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(13 104)') where c1 like 'u%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(139 84)') where c1 like 'a%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(145 108)') where c1 like 'p%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(147 57)') where c1 like 't%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(217 144)') where c1 like 'n%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(160 224)') where c1 like 'w%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(38 28)') where c1 like 'j%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(104 114)') where c1 like 'q%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(88 19)') where c1 like 'c%';
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
-('f', 'x', 'p', ST_GeomFromText('POINT(92 181)')),
-('s', 'i', 'c', ST_GeomFromText('POINT(49 60)')),
-('c', 'c', 'i', ST_GeomFromText('POINT(7 57)')),
-('n', 'g', 'k', ST_GeomFromText('POINT(252 105)')),
-('g', 'b', 'm', ST_GeomFromText('POINT(180 11)')),
-('u', 'l', 'r', ST_GeomFromText('POINT(32 90)')),
-('c', 'x', 'e', ST_GeomFromText('POINT(143 24)')),
-('x', 'u', 'a', ST_GeomFromText('POINT(123 92)')),
-('s', 'b', 'h', ST_GeomFromText('POINT(190 108)')),
-('c', 'x', 'b', ST_GeomFromText('POINT(104 100)')),
-('i', 'd', 't', ST_GeomFromText('POINT(214 104)')),
-('r', 'w', 'g', ST_GeomFromText('POINT(29 67)')),
-('b', 'f', 'g', ST_GeomFromText('POINT(149 46)')),
-('r', 'r', 'd', ST_GeomFromText('POINT(242 196)')),
-('j', 'l', 'a', ST_GeomFromText('POINT(90 196)')),
-('e', 't', 'b', ST_GeomFromText('POINT(190 64)')),
-('l', 'x', 'w', ST_GeomFromText('POINT(250 73)')),
-('q', 'y', 'r', ST_GeomFromText('POINT(120 182)')),
-('s', 'j', 'a', ST_GeomFromText('POINT(180 175)')),
-('n', 'i', 'y', ST_GeomFromText('POINT(124 136)')),
-('s', 'x', 's', ST_GeomFromText('POINT(176 209)')),
-('u', 'f', 's', ST_GeomFromText('POINT(215 173)')),
-('m', 'j', 'x', ST_GeomFromText('POINT(44 140)')),
-('v', 'g', 'x', ST_GeomFromText('POINT(177 233)')),
-('u', 't', 'b', ST_GeomFromText('POINT(136 197)')),
-('f', 'g', 'b', ST_GeomFromText('POINT(10 8)')),
-('v', 'c', 'j', ST_GeomFromText('POINT(13 81)')),
-('d', 's', 'q', ST_GeomFromText('POINT(200 100)')),
-('a', 'p', 'j', ST_GeomFromText('POINT(33 40)')),
-('i', 'c', 'g', ST_GeomFromText('POINT(168 204)')),
-('k', 'h', 'i', ST_GeomFromText('POINT(93 243)')),
-('s', 'b', 's', ST_GeomFromText('POINT(157 13)')),
-('v', 'l', 'l', ST_GeomFromText('POINT(103 6)')),
-('r', 'b', 'k', ST_GeomFromText('POINT(244 137)')),
-('l', 'd', 'r', ST_GeomFromText('POINT(162 254)')),
-('q', 'b', 'z', ST_GeomFromText('POINT(136 246)')),
-('x', 'x', 'p', ST_GeomFromText('POINT(120 37)')),
-('m', 'e', 'z', ST_GeomFromText('POINT(203 167)')),
-('q', 'n', 'p', ST_GeomFromText('POINT(94 119)')),
-('b', 'g', 'u', ST_GeomFromText('POINT(93 248)')),
-('r', 'v', 'v', ST_GeomFromText('POINT(53 88)')),
-('y', 'a', 'i', ST_GeomFromText('POINT(98 219)')),
-('a', 's', 'g', ST_GeomFromText('POINT(173 138)')),
-('c', 'a', 't', ST_GeomFromText('POINT(235 135)')),
-('q', 'm', 'd', ST_GeomFromText('POINT(224 208)')),
-('e', 'p', 'k', ST_GeomFromText('POINT(161 238)')),
-('n', 'g', 'q', ST_GeomFromText('POINT(35 204)')),
-('t', 't', 'x', ST_GeomFromText('POINT(230 178)')),
-('w', 'f', 'a', ST_GeomFromText('POINT(150 221)')),
-('z', 'm', 'z', ST_GeomFromText('POINT(119 42)')),
-('l', 'j', 's', ST_GeomFromText('POINT(97 96)')),
-('f', 'z', 'x', ST_GeomFromText('POINT(208 65)')),
-('i', 'v', 'c', ST_GeomFromText('POINT(145 79)')),
-('l', 'f', 'k', ST_GeomFromText('POINT(83 234)')),
-('u', 'a', 's', ST_GeomFromText('POINT(250 49)')),
-('o', 'k', 'p', ST_GeomFromText('POINT(46 50)')),
-('d', 'e', 'z', ST_GeomFromText('POINT(30 198)')),
-('r', 'r', 'l', ST_GeomFromText('POINT(78 189)')),
-('y', 'l', 'f', ST_GeomFromText('POINT(188 132)')),
-('d', 'q', 'm', ST_GeomFromText('POINT(247 107)')),
-('p', 'j', 'n', ST_GeomFromText('POINT(148 227)')),
-('b', 'o', 'i', ST_GeomFromText('POINT(172 25)')),
-('e', 'v', 'd', ST_GeomFromText('POINT(94 248)')),
-('q', 'd', 'f', ST_GeomFromText('POINT(15 29)')),
-('w', 'b', 'b', ST_GeomFromText('POINT(74 111)')),
-('g', 'q', 'f', ST_GeomFromText('POINT(107 215)')),
-('o', 'h', 'r', ST_GeomFromText('POINT(25 168)')),
-('u', 't', 'w', ST_GeomFromText('POINT(251 188)')),
-('h', 's', 'w', ST_GeomFromText('POINT(254 247)')),
-('f', 'f', 'b', ST_GeomFromText('POINT(166 103)'));
-SET @@RAND_SEED1=866613816, @@RAND_SEED2=92289615;
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
-('l', 'c', 'l', ST_GeomFromText('POINT(202 98)')),
-('k', 'c', 'b', ST_GeomFromText('POINT(46 206)')),
-('r', 'y', 'm', ST_GeomFromText('POINT(74 140)')),
-('y', 'z', 'd', ST_GeomFromText('POINT(200 160)')),
-('s', 'y', 's', ST_GeomFromText('POINT(156 205)')),
-('u', 'v', 'p', ST_GeomFromText('POINT(86 82)')),
-('j', 's', 's', ST_GeomFromText('POINT(91 233)')),
-('x', 'j', 'f', ST_GeomFromText('POINT(3 14)')),
-('l', 'z', 'v', ST_GeomFromText('POINT(123 156)')),
-('h', 'i', 'o', ST_GeomFromText('POINT(145 229)')),
-('o', 'r', 'd', ST_GeomFromText('POINT(15 22)')),
-('f', 'x', 't', ST_GeomFromText('POINT(21 60)')),
-('t', 'g', 'h', ST_GeomFromText('POINT(50 153)')),
-('g', 'u', 'b', ST_GeomFromText('POINT(82 85)')),
-('v', 'a', 'p', ST_GeomFromText('POINT(231 178)')),
-('n', 'v', 'o', ST_GeomFromText('POINT(183 25)')),
-('j', 'n', 'm', ST_GeomFromText('POINT(50 144)')),
-('e', 'f', 'i', ST_GeomFromText('POINT(46 16)')),
-('d', 'w', 'a', ST_GeomFromText('POINT(66 6)')),
-('f', 'x', 'a', ST_GeomFromText('POINT(107 197)')),
-('m', 'o', 'a', ST_GeomFromText('POINT(142 80)')),
-('q', 'l', 'g', ST_GeomFromText('POINT(251 23)')),
-('c', 's', 's', ST_GeomFromText('POINT(158 43)')),
-('y', 'd', 'o', ST_GeomFromText('POINT(196 228)')),
-('d', 'p', 'l', ST_GeomFromText('POINT(107 5)')),
-('h', 'a', 'b', ST_GeomFromText('POINT(183 166)')),
-('m', 'w', 'p', ST_GeomFromText('POINT(19 59)')),
-('b', 'y', 'o', ST_GeomFromText('POINT(178 30)')),
-('x', 'w', 'i', ST_GeomFromText('POINT(168 94)')),
-('t', 'k', 'z', ST_GeomFromText('POINT(171 5)')),
-('r', 'm', 'a', ST_GeomFromText('POINT(222 19)')),
-('u', 'v', 'e', ST_GeomFromText('POINT(224 80)')),
-('q', 'r', 'k', ST_GeomFromText('POINT(212 218)')),
-('d', 'p', 'j', ST_GeomFromText('POINT(169 7)')),
-('d', 'r', 'v', ST_GeomFromText('POINT(193 23)')),
-('n', 'y', 'y', ST_GeomFromText('POINT(130 178)')),
-('m', 'z', 'r', ST_GeomFromText('POINT(81 200)')),
-('j', 'e', 'w', ST_GeomFromText('POINT(145 239)')),
-('v', 'h', 'x', ST_GeomFromText('POINT(24 105)')),
-('z', 'm', 'a', ST_GeomFromText('POINT(175 129)')),
-('b', 'c', 'v', ST_GeomFromText('POINT(213 10)')),
-('t', 't', 'u', ST_GeomFromText('POINT(2 129)')),
-('r', 's', 'v', ST_GeomFromText('POINT(209 192)')),
-('x', 'p', 'g', ST_GeomFromText('POINT(43 63)')),
-('t', 'e', 'u', ST_GeomFromText('POINT(139 210)')),
-('l', 'e', 't', ST_GeomFromText('POINT(245 148)')),
-('a', 'i', 'k', ST_GeomFromText('POINT(167 195)')),
-('m', 'o', 'h', ST_GeomFromText('POINT(206 120)')),
-('g', 'z', 's', ST_GeomFromText('POINT(169 240)')),
-('z', 'u', 's', ST_GeomFromText('POINT(202 120)')),
-('i', 'b', 'a', ST_GeomFromText('POINT(216 18)')),
-('w', 'y', 'g', ST_GeomFromText('POINT(119 236)')),
-('h', 'y', 'p', ST_GeomFromText('POINT(161 24)'));
-CHECK TABLE t1 EXTENDED;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(33 100)') where c1 like 't%';
-CHECK TABLE t1 EXTENDED;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(41 46)') where c1 like 'f%';
-CHECK TABLE t1 EXTENDED;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-DROP TABLE t1;
-create table t1 (a geometry not null, spatial index(a));
-insert into t1 values (POINT(1.1517219314031e+164, 131072));
-insert into t1 values (POINT(9.1248812352444e+192, 2.9740338169556e+284));
-insert into t1 values (POINT(4.7783097267365e-299, -0));
-insert into t1 values (POINT(1.49166814624e-154, 2.0880974297595e-53));
-insert into t1 values (POINT(4.0917382598702e+149, 1.2024538023802e+111));
-insert into t1 values (POINT(2.0349165139404e+236, 2.9993936277913e-241));
-insert into t1 values (POINT(2.5243548967072e-29, 1.2024538023802e+111));
-insert into t1 values (POINT(0, 6.9835074892995e-251));
-insert into t1 values (POINT(2.0880974297595e-53, 3.1050361846014e+231));
-insert into t1 values (POINT(2.8728483499323e-188, 2.4600631144627e+260));
-insert into t1 values (POINT(3.0517578125e-05, 2.0349165139404e+236));
-insert into t1 values (POINT(1.1517219314031e+164, 1.1818212630766e-125));
-insert into t1 values (POINT(2.481040258324e-265, 5.7766220027675e-275));
-insert into t1 values (POINT(2.0880974297595e-53, 2.5243548967072e-29));
-insert into t1 values (POINT(5.7766220027675e-275, 9.9464647281957e+86));
-insert into t1 values (POINT(2.2181357552967e+130, 3.7857669957337e-270));
-insert into t1 values (POINT(4.5767114681874e-246, 3.6893488147419e+19));
-insert into t1 values (POINT(4.5767114681874e-246, 3.7537584144024e+255));
-insert into t1 values (POINT(3.7857669957337e-270, 1.8033161362863e-130));
-insert into t1 values (POINT(0, 5.8774717541114e-39));
-insert into t1 values (POINT(1.1517219314031e+164, 2.2761049594727e-159));
-insert into t1 values (POINT(6.243497100632e+144, 3.7857669957337e-270));
-insert into t1 values (POINT(3.7857669957337e-270, 2.6355494858076e-82));
-insert into t1 values (POINT(2.0349165139404e+236, 3.8518598887745e-34));
-insert into t1 values (POINT(4.6566128730774e-10, 2.0880974297595e-53));
-insert into t1 values (POINT(2.0880974297595e-53, 1.8827498946116e-183));
-insert into t1 values (POINT(1.8033161362863e-130, 9.1248812352444e+192));
-insert into t1 values (POINT(4.7783097267365e-299, 2.2761049594727e-159));
-insert into t1 values (POINT(1.94906280228e+289, 1.2338789709327e-178));
-drop table t1;
-CREATE TABLE t1(foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
-INSERT INTO t1(foo) VALUES (NULL);
-ERROR 23000: Column 'foo' cannot be null
-SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
-Warnings:
-Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
-INSERT INTO t1() VALUES ();
-ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
-SET sql_mode = default;
-INSERT INTO t1(foo) VALUES ('');
-ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
-DROP TABLE t1;
-CREATE TABLE t1 (a INT AUTO_INCREMENT, b POINT NOT NULL, KEY (a), SPATIAL KEY (b));
-INSERT INTO t1 (b) VALUES (ST_GeomFromText('POINT(1 2)'));
-INSERT INTO t1 (b) SELECT b FROM t1;
-INSERT INTO t1 (b) SELECT b FROM t1;
-INSERT INTO t1 (b) SELECT b FROM t1;
-INSERT INTO t1 (b) SELECT b FROM t1;
-INSERT INTO t1 (b) SELECT b FROM t1;
-OPTIMIZE TABLE t1;
-Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
-test.t1 optimize status OK
-DROP TABLE t1;
-CREATE TABLE t1 (a INT, b GEOMETRY NOT NULL, SPATIAL KEY b(b));
-INSERT INTO t1 VALUES (1, ST_GEOMFROMTEXT('LINESTRING(1102218.456 1,2000000 2)'));
-INSERT INTO t1 VALUES (2, ST_GEOMFROMTEXT('LINESTRING(1102218.456 1,2000000 2)'));
-SELECT COUNT(*) FROM t1 WHERE
-MBRINTERSECTS(b, ST_GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') );
-COUNT(*)
-2
-SELECT COUNT(*) FROM t1 IGNORE INDEX (b) WHERE
-MBRINTERSECTS(b, ST_GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') );
-COUNT(*)
-2
-DROP TABLE t1;
-#
-# Bug #48258: Assertion failed when using a spatial index
-#
-CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
-INSERT INTO t1 VALUES
-(ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
-(ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
-EXPLAIN SELECT 1 FROM t1 WHERE a = ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-id select_type table partitions type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 NULL ALL a NULL NULL NULL 2 50.00 Using where
-Warnings:
-Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` = <cache>(st_geometryfromtext('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')))
-SELECT 1 FROM t1 WHERE a = ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-1
-1
-1
-EXPLAIN SELECT 1 FROM t1 WHERE a < ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-ERROR HY000: Incorrect arguments to <
-SELECT 1 FROM t1 WHERE a < ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-ERROR HY000: Incorrect arguments to <
-EXPLAIN SELECT 1 FROM t1 WHERE a <= ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-ERROR HY000: Incorrect arguments to <=
-SELECT 1 FROM t1 WHERE a <= ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-ERROR HY000: Incorrect arguments to <=
-EXPLAIN SELECT 1 FROM t1 WHERE a > ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-ERROR HY000: Incorrect arguments to >
-SELECT 1 FROM t1 WHERE a > ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-ERROR HY000: Incorrect arguments to >
-EXPLAIN SELECT 1 FROM t1 WHERE a >= ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-ERROR HY000: Incorrect arguments to >=
-SELECT 1 FROM t1 WHERE a >= ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-ERROR HY000: Incorrect arguments to >=
-DROP TABLE t1;
-#
-# Bug #51357: crash when using handler commands on spatial indexes
-#
-CREATE TABLE t1(a GEOMETRY NOT NULL,SPATIAL INDEX a(a));
-HANDLER t1 OPEN;
-HANDLER t1 READ a FIRST;
-a
-HANDLER t1 READ a NEXT;
-a
-HANDLER t1 READ a PREV;
-a
-HANDLER t1 READ a LAST;
-a
-HANDLER t1 CLOSE;
-HANDLER t1 OPEN;
-HANDLER t1 READ a FIRST;
-a
-INSERT INTO t1 VALUES (ST_GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
-# should not crash
-HANDLER t1 READ a NEXT;
-HANDLER t1 CLOSE;
-DROP TABLE t1;
-End of 5.0 tests.
-#
-# Bug #57323/11764487: myisam corruption with insert ignore
-# and invalid spatial data
-#
-CREATE TABLE t1(a LINESTRING NOT NULL, b GEOMETRY NOT NULL,
-SPATIAL KEY(a), SPATIAL KEY(b)) ENGINE=InnoDB;
-INSERT INTO t1 VALUES(ST_GEOMFROMTEXT("point (0 0)"), ST_GEOMFROMTEXT("point (1 1)"));
-ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
-INSERT IGNORE INTO t1 SET a=ST_GEOMFROMTEXT("point (-6 0)"), b=ST_GEOMFROMTEXT("error");
-ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
-INSERT IGNORE INTO t1 SET a=ST_GEOMFROMTEXT("point (-6 0)"), b=NULL;
-ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
-SELECT ST_ASTEXT(a), ST_ASTEXT(b) FROM t1;
-ST_ASTEXT(a) ST_ASTEXT(b)
-DROP TABLE t1;
-CREATE TABLE t1(a INT NOT NULL, b GEOMETRY NOT NULL,
-KEY(a), SPATIAL KEY(b)) ENGINE=InnoDB;
-INSERT INTO t1 VALUES(0, ST_GEOMFROMTEXT("point (1 1)"));
-INSERT IGNORE INTO t1 SET a=0, b=ST_GEOMFROMTEXT("error");
-ERROR 22023: Invalid GIS data provided to function st_geometryfromtext.
-INSERT IGNORE INTO t1 SET a=1, b=NULL;
-ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
-SELECT a, ST_ASTEXT(b) FROM t1;
-a ST_ASTEXT(b)
-0 POINT(1 1)
-DROP TABLE t1;
-End of 5.1 tests
diff --git a/mysql-test/suite/innodb_gis/r/rtree_purge.result b/mysql-test/suite/innodb_gis/r/rtree_purge.result
index c3e879674dd..38c4f484504 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_purge.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_purge.result
@@ -1,24 +1,8 @@
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
create table t (
-a point not null,b point not null,c point,
-d point not null,e point,f point,
-spatial key (d),spatial key (b)
+b point not null,d point not null, spatial key (d),spatial key (b)
) engine=innodb;
-create procedure p(i int)
-begin
-declare n int default 0;
-declare continue handler for sqlexception begin end;
-delete from t;
-repeat
-set @p=point(1,1);
-insert into t values(@p,@p,@p,@p,@p,@p);
-insert into t values(@p,@p,@p,@p,@p,@p);
-insert into t select @p,@p,@p,@p,@p,@p
-from t a,t b,t c,t d,t e,t f,t g,t h,t i,t j;
-delete from t;
-set n:=n+1;
-until n >= i end repeat;
-end|
-call p(200);
InnoDB 0 transactions not purged
-drop procedure p;
drop table t;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb_gis/r/rtree_recovery.result b/mysql-test/suite/innodb_gis/r/rtree_recovery.result
index d2f4409f38c..4fee60caf85 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_recovery.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_recovery.result
@@ -1,4 +1,3 @@
-# restart
create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
create procedure insert_t1(IN total int)
begin
@@ -18,7 +17,6 @@ end while;
end|
CALL insert_t1(367);
COMMIT;
-# Kill and restart
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
@@ -29,16 +27,14 @@ CALL update_t1(367);
SET @poly1 = ST_GeomFromText('POLYGON((10000 10000, 10000 10350, 10350 10350, 10350 10000, 10000 10000))');
delete from t1 where ST_Contains(@poly1, c2);
COMMIT;
-# Kill and restart
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
select count(*) from t1;
count(*)
-18
+17
select c1, ST_astext(c2) from t1;
c1 ST_astext(c2)
-350 POINT(10350 10350)
351 POINT(10351 10351)
352 POINT(10352 10352)
353 POINT(10353 10353)
diff --git a/mysql-test/suite/innodb_gis/r/rtree_search.result b/mysql-test/suite/innodb_gis/r/rtree_search.result
index d8a8d209cd3..d186986156e 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_search.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_search.result
@@ -14,19 +14,19 @@ count(*)
set @g1 = ST_GeomFromText('Polygon((0 0,0 1000,1000 1000,1000 0,0 0))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
-999
+1000
set @g1 = ST_GeomFromText('Polygon((0 0,0 100,100 100,100 0,0 0))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
-99
+100
set @g1 = ST_GeomFromText('Polygon((10 10,10 800,800 800,800 10,10 10))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
-789
+791
set @g1 = ST_GeomFromText('Polygon((100 100,100 800,800 800,800 100,100 100))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
-699
+701
set @g1 = ST_GeomFromText('Point(1 1)');
select count(*) from t1 where MBRequals(t1.c2, @g1);
count(*)
diff --git a/mysql-test/suite/innodb_gis/r/rtree_split.result b/mysql-test/suite/innodb_gis/r/rtree_split.result
index 37ce67a9f2c..65a9ff3499f 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_split.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_split.result
@@ -14,9 +14,10 @@ insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
-SET SESSION debug="+d, rtr_page_need_second_split";
+SET @saved_dbug = @@SESSION.debug_dbug;
+SET debug_dbug = '+d, rtr_page_need_second_split';
insert into t1 select * from t1;
-SET SESSION debug="-d, rtr_page_need_second_split";
+SET debug_dbug = @saved_dbug;
delete from t1;
insert into t1 values(1, Point(1,1));
insert into t1 values(2, Point(2,2));
@@ -62,6 +63,8 @@ count(*)
0
drop index c2 on t1;
create spatial index idx2 on t1(c2);
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -73,7 +76,10 @@ set @g1 = ST_GeomFromText('Polygon((0 0,0 100,100 100,100 0,0 0))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
73728
-# restart: --innodb-read-only
+set @g1 = ST_GeomFromText('Polygon((2 2,2 800,800 800,800 2,2 2))');
+select count(*) from t1 where MBRWithin(t1.c2, @g1);
+count(*)
+65536
set @g1 = ST_GeomFromText('Polygon((0 0,0 100,100 100,100 0,0 0))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
@@ -81,6 +87,5 @@ count(*)
set @g1 = ST_GeomFromText('Polygon((2 2,2 800,800 800,800 2,2 2))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
count(*)
-57344
-# restart
+65536
drop table t1;
diff --git a/mysql-test/suite/innodb_gis/r/rtree_undo.result b/mysql-test/suite/innodb_gis/r/rtree_undo.result
index 12e052ccb9a..589ccc3ff9a 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_undo.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_undo.result
@@ -1,10 +1,12 @@
-connect con1,localhost,root,,;
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
+connect control_purge,localhost,root,,;
connection default;
CREATE TABLE t1 (
p INT NOT NULL AUTO_INCREMENT,
g LINESTRING NOT NULL,
PRIMARY KEY(p)
-) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+) ENGINE=InnoDB;
ALTER TABLE t1 ADD INDEX prefix_idx (g(767));
INSERT INTO t1(g) VALUES(ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)'));
INSERT INTO t1(g) VALUES(ST_linefromtext(concat('linestring','(18 106,19 106,24 111,27 108,32 104,37 107,42 107,44 112,44 116,40 118,43 114,46 114,42 118,44 123,45 123,49 123,53 119,50 123,50 124,54 126,58 125,59 126,64 127,65 127,69 131,74 132,75 135,78 139,2078 141,2075 143,2077 143,2079 143,2084 143,2085 147,2090 -1853,2086 -1852,2086 -1856,2089 -1852,2093 -1850,2090 -1851,2090 -1852,2091 -1851,2092 -1850,2097 -1847,2102 -1848,2100 -1852,2100 -1852,7100 -1851,7103 -1850,7104 -1847,7109 -1842,65 127,67 131,66 131,61 132,61 133,62 137,65 1137,2065 1135,2061 1135,2064 1135,5064 1135,5066 1135,5070 1136,5070 1141,5071 1138,5074 1141,5075 1141,5074 1137,5076 1137,5071 1139,5066 1142,5065 2142,5068 2147,5073 2151,5069 2156,5071 2157,5072 2162,5074 2165,5069 2169,5072 2169,5076 2173,5074 2169,5078 2169,5076 2170,76 2175,74 2179,75 2184,80 2188,83 2190,87 2189,84 2193,87 2189,86 2190,87 2195,87 2200,87 1200,85 1202,86 1199,87 1200,87 1201,91 1206,92 1204,94 1204,98 1206,102 1208,105 1211,102 1216,105 1220,109 1224,110 1224,114 1225,117 1224,118 1229,117 1232,122 1237,123 1236,120 1235,124 1237,121 1236,122 1240,126 1244,127 1246,126 1249,125 5249,123 5251,127 5251,131 5251,135 5256,138 5257,135 5257,139 5257,138 5258,141 5260,146 5260,146 5260,143 10260,147 10265,151 10270,156 10266,157 10269,162 10273,166 12273,168 12274,163 12270,168 12275,170 12277,170 12277,-3830 12277,-3825 12277,-3824 12278,-3825 12276,-3825 12278,-3822 12277,-3825 12275,-3829 12278,-3828 12275,-3824 12280,-3827 12280,-3826 12282,-3822 12283,-3822 12286,-3820 12288,-3818 12289,-3816 12294,-3817 12297,-3819 12300,-3816 12297,-3813 12295,-3811 12299,-3811 12297,-3806 12298,-3806 12298,-3804 12301,-3801 12306,-3803 17306,-3803 17306,-3798 17306,-3803 17310,-3801 17314,-3798 17317,-3797 17317,-797 17321,-797 17323,-796 17325,-793 17326,-792 17322,-789 17327,-784 17331,-780 17335,-776 17339,-774 17339,-771 17342,-770 17345,-765 17348,-765 17349,-763 17353,-760 17350,-760 22350,-756 22346,-752 22349,-748 22352,-752 22348,-748 22347,-746 22345,-745 27345,-743 27346,257 27350,260 27349,261 27352,266 27348,266 22348,269 22347,271 22347,272 22347,273 22348,273 22352,278 22348,279 22344,282 22345,282 22342,283 22347,283 22347,288 22349,292 22347,292 22348,293 22348,298 22348,303 22351,306 22352,309 22352,308 22354,310 22356,311 22361,311 22358,311 22360,311 22360,315 22356,320 22358,325 22363,326 22366,321 22371,318 22373,318 22375,314 22375,316 22375,321 22376,321 22376,322 22372,32 104,36 109,40 114,40 113,40 117,44 119,49 123,49 126,49 129,53 133,50 137,50 139,49 137,48 138,43 138,42 139,46 142,46 138,41 139,45 141,4045 5141,4045 5146,4042 5147,4043 10147,4041 10150,4042 10152,4045 10152,4041 10156,4041 10152,4041 10152,4046 10153,4049 10156,4046 10155,4051 10157,4055 10159,4055 10160,4056 10161,4055 10166,4054 10169,4054 10172,4054 15172,4051 15176,4047 15177,4049 15174,4047 15176,4047 15176,4046 15177,4046 15180,4043 15184,4043 15187,4038 15190,4040 15194,4040 15199,4045 15196,4047 15197,4050 15200,4050 15204,4050 15208,4047 15212,4047 15215,4049 15216,4046 15218,4042 15223,4042 15228,4042 15232,4047 15235,4050 15236,4050 15239,4051 15243,4053 15243,4050 17243,4052 17243,4052 18243,4057 18247,4061 18249,4064 18249,4067 20249,4067 20250,4067 20255,4066 20259,4066 20259,4067 20255,4069 20256,4071 20258,4072 20254,4067 20257,4067 20260,4069 20265,4065 20267,4069 20266,4070 20267,4071 20264,4074 20259,4070 20264,4073 20260,4074 20263,4077 20268,4082 20271,4084 20273,4084 20277,4081 18277,4085 18279,4086 18276,4087 18273,4087 18275,4092 18277,4093 18279,4093 18280,4095 18280,4091 18283,4092 18281,4094 18283,4090 18287,4094 18287,138 5257,138 5255,138 5258,-1862 5254,-1860 5256,-1856 5258,-1851 5255,-1850 5260,-1847 5260,-1847 5263,-1847 5258,-1850 5257,-1850 5259,-1851 5257,-1855 5258,-1853 5261,-1849 5261,-1849 5258,-1849 5259,-1845 5264,-1847 5264,-1850 5268,-1852 5266,-1853 5270,-1856 5265,-1852 5262,-1847 5263,-1842 5263,-1842 5260,-1842 5265,-1841 5265,-1844 5265,-1842 5270,-1837 5274,-1838 5279,-1843 5275,-1842 5280,-1838 5281,-1838 5285,-1833 5285,-1828 5288,-1824 5289,-1828 5291,-1831 5291,-1826 5291,-1830 5293,-1826 5296,-1822 5301,-1826 5302,-1826 5302,-1826 5302,-1825 5297,-1820 5299,-1816 5303,-1816 5299,-3811 12299,-3809 12302,-3806 12302,-3806 12302,-3803 12304,-3798 12304,-3797 12304,-3793 12306,-3788 12306,-3783 12309,-3816 12294,-3811 12299,-3809 12297,7100 -1851,7098 -1854,7102 -1854,7107 -1856,7107 -1858,7110 -1854,7110 -1851,7113 -1851,7115 -1851,7120 -1851,7123 -1847,7124 -1852,7125 -1852,7127 -1852,7131 -1852,7129 1148,7129 1145,7133 1150,7137 1148,7138 1147,7143 1149,7147 1154,8147 1155,8152 3155,8147 3157,8143 3158,8144 3160,8144 3164,11144 3167,11146 3167,11148 3163,11152 3161,11148 3159,11149 3163,11150 3161,11151 3166,11154 3171,11154 3170,8144 3160,8144 3163,8144 3166,8145 3166,8146 3171,8146 3174,8144 3174,8144 3174,8145 3176,8141 3180,3141 3182,7141 3183,7141 7183,7136 7185,7136 7185,7133 7187,7136 7187,7131 7190,7136 7194,7137 7197,7141 7196,7139 7199,12139 7200,12143 7200,12143 7199,12144 7203,12145 7200,12141 7200,12136 7195,12136 7191,12137 7191,12137 7196,12139 7197,12140 7197,12137 7201,12140 7204,12140 7209,12143 7209,12145 7210,12147 7214,12148 9214,12152 9218,12149 9218,12149 9221,12149 9220,12150 9222,12153 10222,12153 10226,12156 10227,12159 10223,12160 10220,12161 10225,12161 10227,12163 10224,12163 10223,12158 10224,12158 10227,12158 10231,12155 12231,12157 12226,7136 7185,7139 7189,7139 7189,7139 7188,7137 7191,7139 7191,7140 7189,7143 7191,7144 7189,7144 7190,7149 7193,7152 7194,7154 7198,7153 7203,7148 7207,12148 7209,12146 7209,12145 7213,12140 7217,12139 7219,12141 7219,12138 7218,12143 7218,13143 7220,13140 7224,13142 7228,13137 7231,13142 7235,13146 7239,13149 7243,13148 7247,13150 7248,13155 7249,13155 7253,13155 7253,13155 7258,13157 7260,13162 7255,13159 7255,13163 7258,13164 7258,13164 7263,13167 7264,13167 8264,13165 8265,13169 8265,13171 13265,13175 13261,13176 13259,13176 13259,13180 13262,13181 13262,13183 13262,13188 13265,13191 13267,13191 13265,13194 13267,13191 13269,13192 13264,13196 13269,13198 13272,13200 13272,13202 13270,13207 11270,13211 11270,13211 11273,13213 11274,13217 11275,13222 11276,13222 11272,13226 11274,13231 11277,13233 11282,13236 11284,13238 11284,13236 11286,13236 11288,13236 11283,13236 11284,13238 11289,13241 11292,13244 11292,13245 11289,13241 11294,13244 11298,13249 11301,320 22358,324 24358,328 24358,327 24363,326 24359,327 24361,329 24365,334 24367,-666 24367,-670 24368,49 123,46 127,46 129,49 131,49 136,47 135,45 138,3045 135,3042 138,3044 139,3044 144,3049 144,3053 142,3055 137,3058 136,3053 139,3048 142,7048 138,7048 3138,7048 3139,7048 3140,7050 3145,7053 1145,7050 1146,7053 5146,7048 5150,7047 5146,10047 5147,10043 5147,10047 5147,10050 5152,10052 5155,10054 5156,10056 5157,10056 5159,10058 5162,10062 5164,10062 5169,10066 9169,10068 9168,10063 9164,10063 9169,10061 9171,14061 9172,14061 9174,282 22342,287 22347,288 22347,288 22343,285 22339,280 22338,278 22341,279 25341,284 25343,13241 11294,13246 11296,13243 11296,13244 11291,13245 11291,13244 11291,13246 11295,13251 11300,13253 11305,13253 11306,13258 11305,13255 11306,13256 11309,13256 11311,13261 11307,13265 11303,13267 11305,13270 11301,13275 11298,13271 11300,15271 11302,15276 11306,15279 11303,15284 11305,15286 11305,15289 11307,15290 11302,15292 11305,15296 11309,15297 11313,15298 11316,15300 11317,15304 11320,15306 11324,15306 11320,15307 11320,15312 11320,15313 11319,15317 11317,15315 11321,15317 11323,15317 11328,15319 11333,15322 11336,15322 11337,15322 11337,15324 11341,15324 11345,15325 14345,15328 13345,17328 13346,17333 13349,17337 13354,17338 13358,17342 13358,17346 13353,17348 13353,17345 13353,17348 13354,17347 13354,17347 13354,17347 13355,22347 13358,22349 13355,22351 13355,22356 13354,22358 13354,22361 13355,22362 13355,22358 13355,22359 13359,22364 13364,22369 13369,22372 13373,22376 13371,22377 13371,22377 13369,22381 13374,22386 13379,22387 13376,22387 13380,22392 13378,22390 13374,22392 13378,22391 13378,22391 13375,22392 13378,22390 13380,22393 13382,22398 13387,22398 10387,22402 10391,22399 10392,22400 10392,22400 10394,22404 10391,22403 15391,22405 15392,22407 15392,22412 15387,22412 15390,22412 15394,22408 15396,26408 15398,26407 20398,26411 20402,26415 20406,26417 20411,26420 20407,26422 20407,31422 16407,31421 16405,31421 16410,31423 16410,31426 16414,31426 16410,31430 16415,31430 16418,31435 16419,31437 16420,31438 16422,31438 16425,31438 16425,31441 16427,31439 16431,31441 16436,36441 16436,36443 18436,36442 18437,36440 18440,36440 18436,36440 18440,36442 18445,36443 18446,36447 18451,37447 23451,37452 23456,37456 23455,37458 23459,37456 23461,37458 23463,37460 23466,37464 23469,37460 23474,37462 23476,37461 26476,37466 26479,37470 26483,37471 26488,37474 26489,37474 26485,37474 26483,37474 26488,37470 26492,37474 26497,37474 26499,37478 26495,37483 26499,37483 26501,37488 26496,37491 26499,37495 26495,37500 26496,37500 26497,37500 26501,37497 26499,37497 26499,37495 26504,37498 26504,37494 26509,37497 26514,37495 26515,37498 26514,37503 26514,37508 26512,37510 26516,37511 26519,37509 26523,37506 26528,37507 26532,37512 26536,37513 26538,37510 26542,37512 26544,37517 26543,37522 26546,37527 26551,37525 26555,37529 26558,37524 26563,37524 26562,37527 26562,37522 26562,37522 26559,37526 26561,37522 26559,37523 26561,37523 26556,37524 26558,40524 26560,40524 26563,40521 26567,40525 26566,40527 26568,40532 26572,40534 26569,40533 26565,40531 26565,40535 26569,40535 26570,40539 26572,40544 26575,40543 26575,40544 26579,40548 26584,40549 26581,40553 26585,40556 26590,40552 22590,40557 22594,40556 22595,40561 22592,40561 22593,40565 22593,40568 22593,40573 22588,40570 22590,40570 22591,40570 22588,40573 22590,40573 22593,40568 22593,40567 22597,40567 22599,40571 22599,40574 22600,40574 22604,42574 22607,42577 22607,42577 22612,42579 22616,38579 22619,38580 22617,38580 22614,38575 22619,38579 22619,38579 18619,38582 18614,38582 18617,38586 18622,38590 18625,38590 18622,38594 18621,38596 18616,38597 18614,38597 18618,38600 21618,38601 21618,38605 21620,38607 25620,38611 25620,38608 25617,38608 25621,38608 25625,38611 25623,38615 25623,38615 25620,38616 25622,38619 25624,38620 25625,38620 26625,38623 26627,38623 26627,311 22358,311 22359,-1689 22360,2311 27360,2312 27360,2312 27360,2317 27362,2317 27362,2319 27359,2319 27364,2318 27359,2321 27364,2326 27367,2325 27371,2326 27373,2326 27373,2325 27377,2329 27377,2327 27377,2330 27379,2333 27379,2331 27379,2331 27381,2336 27381,6336 27382,6336 27383,40527 26568,40531 26572,40533 26574,40538 26576,40533 26580,40538 26585,40539 26588,40536 26583,40540 26587,40539 26588,40535 26593,40540 26594,40544 26597,40548 26602,40548 26601,40549 26602,40547 26602,40548 26603,40553 26606,40548 26606,40548 26603,40551 26608,40556 26612,40559 26616,40554 26619,40556 26619,40556 26623,42556 26623,42556 26624,42560 26624,42562 26626,42563 26630,42564 26630,42564 26634,42559 26635,42562 26635,42565 26637,42562 26638,42564 26642,42564 26641,42568 26641,42572 26641,42572 29641,42574 29642,39574 29641,39574 34641,39576 34643,39581 34638,39578 34638,39574 34642,39574 34645,39572 35645,34572 35648,34577 35651,39577 35655,43577 35659,43580 35655,43575 35658,43578 35658,43581 35662,43577 39662,43572 39658,43572 39661,43572 39664,43572 39666,43576 39670,43577 39667,43580 39671,43576 39673,43573 39673,43574 39677,43569 39679,43567 39679,43568 39683,43563 39686,43566 39690,43566 39692,43568 39694,43568 39695,41568 39691,41570 39692,41571 39692,41571 39693,41571 39698,41571 39698,41574 39698,41569 39698,41570 39699,41570 39704,41572 39709,41573 39712,41578 39713,41579 39717,41584 39719,41585 39720,-1850 5268,-1845 5268,-1847 5266,-1842 5268,-1840 5263,-1845 5264,-1843 5264,-1839 8264,-1839 8267,-1839 8272,-1838 8276,-1834 8273,-1834 8273,-1833 8274,-1837 8279,-1836 8283,-1834 8286,-1836 8282,-1834 8279,-1835 8279,-1834 8280,-1836 8283,-1841 8288,-1846 8289,-1843 8286,-1838 8286,-1841 8285,-1838 8285,-1834 8288,-1829 8291,-1825 8286,-1825 8289,-1825 8287,-1824 8291,-1822 8294,-1821 8298,-1818 8300,-1818 8296,-1814 8296,-1811 8295,-1808 8292,1192 8296,1192 8297,1195 11297,1192 11301,1195 11305,1197 11300,1193 11300,1193 11296,1193 11293,1194 11294,1199 11292,1204 11292,1205 11294,1210 11292,1208 11288,1204 11290,1205 11289,1207 8289,1202 8284,1204 8282,1204 8281,1206 8281,1208 8281,1212 8283,1212 13283,1213 13287,1213 13290,1216 13293,1214 13289,1217 13286,1212 13291,1208 13288,1208 13292,1209 13297,1208 13296,1204 13298,1205 13303,1209 13308,1204 13308,1209 13304,1210 13304,1214 13309,1214 13314,1215 13314,1219 13314,1219 13319,1224 13320,1229 13321,1232 13325,1233 13329,1231 13329,1234 13334,-2766 13336,-2769 13337,-2765 13340,-2762 13345,-2760 13342,2240 13342,2238 13342,2242 13342,2246 13345,2246 13346,2244 13348,2239 13348,2240 13351,2240 13352,2245 13357,2248 13357,2243 13362,2247 13362,2248 13362,2252 13363,2256 13363,2256 13363,2260 13367,2255 13372,2251 13369,2251 13369,2252 13372,2249 13376,2254 13378,2255 13382,2259 13379,2262 13379,2267 13381,2262 13381,2262 13383,2265 13383,2269 13385,2270 13386,2271 13389,2267 13391,2271 13386,2275 13391,2273 13392,2275 13387,2277 13390,2274 13390,2275 13394,2280 13395,2280 11395,2281 14395,2279 14400,2277 14403,2273 14406,2274 16406,2274 16410,2279 16410,2284 16411,2280 16409,2280 16409,2282 16409,2282 16411,2282 16412,2280 16413,3280 16418,3284 16418,3285 16423,3289 16423,3292 16427,3294 16429,3296 16431,3297 16436,3298 16435,3303 16435,3305 16434,3305 16436,3305 16436,3309 16437,3309 16438,3308 16439,3308 16439,3306 16444,3302 16441,-1698 16437,-1703 16438,-1699 16438,-1697 16438,-1698 16439,-1695 16436,-1690 16441,-1687 16446,-1683 16450,-1682 16451,-1684 16453,-1682 16457,-1682 16457,-1686 16460,-1681 16459,-1680 16456,-1677 16460,-1681 16461,-1679 16464,-1674 16465,-1673 16469,-1669 16471,-1669 16476,-1665 16474,-1665 16478,-1664 16478,-1664 16479,-1661 16474,-1656 16471,-1655 11471,-1660 11473,-1663 11475,-1666 11480,3334 15480,3338 15476,3342 15471,3345 15471,3345 15470,3350 15469,3347 15474,3351 15476,3352 15473,3353 15476,3350 15477,3350 15479,3351 15482,3352 15484,3351 15487,3353 15487,3358 15487,3353 15486,1217 13286,1222 13291,1222 13291,1225 13286,1229 13286,1231 13281,1235 13280,1236 13281,1241 13282,1245 13285,1247 13285,1247 13287,1250 13287,1247 13290,1247 13295,1247 13298,1252 13301,1249 13304,1252 13304,3252 13304,3247 13304,3249 13308,3254 13308,3257 13308,3261 17308,3261 17309,3261 17306,3259 17305,3262 17310,3263 17308,3262 17311,3259 17314,3259 17314,3257 17309,3254 17309,3253 17309,3255 17310,3253 17312,3255 17312,3255 17312,3256 17307,3257 17307,3256 17311,3256 17313,3255 17317,3251 17317,3248 17321,3253 17325,3256 17326,3258 17324,3258 17327,3263 17322,7263 17325,7265 17328,7263 17330,7265 17333,7270 17333,7273 17333,7278 17336,4278 21336,4278 21340,4279 21340,4281 21340,4286 24340,4290 24343,9290 24347,9294 24349,9296 24347,9298 25347,9301 25348,9301 25348,9304 25353,9303 25357,9303 25352,11303 25355,11304 25358,11307 25358,11312 25358,11312 25361,11310 25365,11313 25365,11314 25369,11319 25371,11321 25371,11325 25366,11329 25365,11330 25366,11329 25370,11330 25365,11334 25367,11338 25366,11343 25363,11348 25359,11345 25356,11348 25357,11349 25358,11349 25358,11352 25360,11356 30360,11360 30365,11360 30365,11362 30365,11367 30367,11368 30369,15368 30370,15373 30371,15376 30373,14376 30378,14377 30383,14381 30378,14386 30380,14388 30382,14391 30385,14393 31385,16393 31389,16396 31394,16396 31397,16392 31400,16395 31405,16398 31409,16398 31413,16397 31415,16396 31417,16401 31418,16401 31422,16402 31419,16407 31420,16411 31419,16406 31423,18406 31427,18411 31432,18415 28432,18417 28437,18418 28441,18414 28438,18417 28435,18416 28439,18420 28442,18423 28447,18427 28444,21427 28445,21428 28450,22428 28455,22432 28457,22436 28458,22441 28458,22445 28463,22448 28468,22451 28465,22456 28468,22453 28468,22458 28471,22463 28473,22460 28475,22459 28472,22463 28476,22464 28472,22468 28468,22468 28471,25468 28466,25471 28468,25473 28464,25473 28464,25475 29464,25476 29466,25479 29461,25476 29462,25476 29464,25478 29464,25483 29461,25484 29460,25486 29458,25486 29462,25490 29460,25495 26460,25498 26463,25495 26468,25495 26472,25495 26472,25499 26474,25504 26476,25504 26478,25509 26476,25513 26479,25514 26481,25519 26477,25519 26480,25518 26481,25519 26484,25524 26483,25527 26484,25522 26484,25526 26487,25528 26492,25533 26496,25535 26498,25535 26498,25539 26503,25542 26504,25543 26505,25547 26510,25552 26510,25551 26508,25550 26512,25553 26510,25557 26510,25554 26511,25552 26508,25556 26505,25556 26506,25560 26506,25560 26507,25560 26506,25565 26501,25567 26504,25569 26504,25568 26508,25571 26508,25571 26511,25576 26511,25581 26516,25581 26519,25582 26521,25585 26522,25588 26527,25588 26526,25584 26530,25587 26534,25589 26529,25593 26533,25598 26538,25599 26540,25599 26540,25599 26540,25604 26543,25603 26543,25603 26538,25606 26538,25609 26540,25611 26542,25612 26547,25612 26547,25612 26548,25617 25548,25612 25548,25613 25547,25616 25545,25616 25549,25618 25551,25620 25555,25620 25551,25622 25550,25625 25551,25622 25555,25619 25557,25617 25556,25622 28556,25625 28551,25630 28546,25634 28548,25639 28553,25643 28553,25638 25553,25634 25553,25634 25557,25639 25557,25643 25558,25644 25553,25646 25556,25647 25560,25650 25562,25650 30562,25650 30562,25650 30564,25650 30566,25652 30570,25656 30571,25661 31571,25662 31575,25663 31579,25662 31579,25665 31581,25666 31584,25671 31582,25674 31581,25674 31584,25676 31584,25673 31587,25678 31586,25679 31581,30679 31584,30675 31589,30680 31590,35680 31590,35675 31589,35677 31591,35680 31590,35681 31587,35684 31588,35685 31589,35689 31592,35689 31593,35692 31597,35696 31597,35700 34597,35699 34599,35703 34604,35703 34606,35702 34601,35705 34603,35705 34606,35708 34603,35713 34604,35717 34603,35719 34608,35715 34608,35711 34608,35713 34609,35714 34605,35714 34610,35714 34614,35718 34616,35719 34617,35722 34618,35722 34621,35725 34625,35725 34626,35725 34629,35725 34631,35725 34635,35730 34636,35727 34638,35731 34640,35735 34642,35739 34645,35741 34645,35742 34649,35738 34649,35738 34645,35741 34647,38741 34650,38741 37650,38742 37646,38746 37651,38749 37652,38753 37653,38753 37657,38757 37656,38756 37660,38761 37660,38765 37660,38760 37660,38759 37660,38760 41660,38760 41660,38762 41665,38757 41667,43757 41669,43752 41674,43752 41677,43757 41672,43758 41677,45758 41680,45758 41679,45762 41683,45765 41683,45769 41683,45770 41684,45768 46684,45773 46688,45776 46692,45774 46694,45775 46697,45778 46695,45776 46698,45774 46702,45779 46702,45784 46704,45787 46706,45791 46711,45786 46707,45790 46711,45793 46715,45796 46719,45799 46724,45797 46728,45802 46726,45797 46729,45801 46733,45802 46733,45803 46732,45804 46732,45805 46732,45808 46735,45810 46740,45810 46744,2326 27373,2322 27377,2323 27379,2325 27383,2325 27382,2322 27382,2323 27382,5323 23382,5325 23385,5329 23386,5330 23390,5335 23392,5330 23392,5330 23395,5329 23395,5333 23399,5333 23402,5338 23405,5339 23405,5334 23406,5329 23401,5332 23403,5330 23407,5333 23409,5328 20409,5324 20411,5324 20414,5329 20416,5328 20421,5325 20421,5329 20424,5330 20424,5335 21424,5331 21427,5333 21431,5334 21433,5329 21434,5330 21437,5333 21440,5338 21437,5338 21440,5334 21441,5333 21438,5329 26438,5332 26435,5335 26439,5337 26440,5338 26444,5342 26439,5342 26442,5345 26440,5349 26438,5352 26442,5349 26445,5348 30445,5350 30447,5350 30444,5354 30444,5359 30443,5363 30445,5367 30446,5367 30448,5367 30453,5371 30455,5371 30453,5373 30458,5375 30461,5380 30463,5384 30463,5383 30459,5384 30459,5383 30459,5385 30460,5390 30459,5392 30464,5394 30464,5389 30465,5393 30469,5391 30469,5391 30469,5395 30474,5396 30470,5399 30470,5401 30467,5401 30468,5404 30470,5400 30465,5401 30462,5403 30467,5404 30467,5409 30469,5412 30473,5412 30477,5407 30481,8407 30486,8408 30489,8410 30490,8410 30489,8413 30490,8414 30493,8414 30496,8419 30501,8420 30502,8415 30507,13415 30509,13411 30506,13414 30507,13412 30511,13412 30515,13417 30518,13419 30523,13418 30527,13422 30529,13418 30531,13413 35531,13409 35531,13413 35532,13417 35537,13419 35533,13423 35529,13424 35529,13423 35524,13428 35525,13433 35526,13438 35530,13443 35531,13448 35531,13452 35532,13455 35536,13457 35536,13452 35536,13455 35539,13452 35535,13457 35540,13457 35544,18457 35546,18460 35547,22460 35546,22465 35550,22466 35554,22468 35552,22473 35555,22471 35559,22470 35564,22472 35564,22470 35569,22474 35569,22474 35571,22477 35573,22482 35576,22487 35580,22488 35583,22489 35585,22493 35585,22496 35585,25496 35586,25493 35582,25494 35585,25498 35585,25496 35585,25498 35587,25503 35591,25503 35593,25499 35590,25499 35591,25495 35591,26495 35595,29495 35591,29495 35593,29498 35597,29498 35601,29500 35606,29501 30606,29502 30603,29505 30603,29510 30606,29511 30606,29514 30607,29516 30610,29518 30608,3259 17305,3263 17304,3267 17303,3271 17308,3269 17312,3269 17313,3274 17315,3277 17315,3282 17311,3285 17313,3283 17309,3278 17310,3275 17315,3275 17317,3276 17322,3280 17324,3280 17324,3276 17325,3277 17325,3276 17328,3278 17324,3273 17329,3277 17331,3280 17326,3281 17328,3276 17324,3277 17324,3277 17322,3277 17321,3277 17321,3281 17323,3282 17327,3282 17332,3287 17335,3288 17335,3288 17338,3290 17337,3294 17340,3294 17341,3299 17341,3299 12341,3299 12342,3304 12339,3301 14339,3305 14340,3307 14341,3311 14343,3313 14343,3314 16343,3310 16341,3310 16346,3312 16348,3311 16349,4311 16346,4316 16348,4321 16344,4324 16348,4322 16349,4323 16346,4323 16346,4326 16350,4322 16354,4323 16356,4325 16361,4325 16358,4322 16362,4325 20362,4325 20366,4322 20367,4326 20372,4326 20374,4331 20373,4333 20373,4338 20376,4339 20379,4341 20382,4338 20384,4339 20386,4340 20383,4340 20383,4335 20388,4336 20390,4341 20390,4346 20391,4348 20391,4349 20393,37497 26499,37494 26496,37496 26500,37496 26501,37499 26506,37497 26502,37498 26502,37500 29502,37500 29507,37505 29508,37506 33508,37508 33513,37513 33518,37517 33522,37516 33520,37521 33521,37521 33525,37516 33530,37519 33528,37520 33528,37524 33530,37527 33530,37525 33527,37528 33530,37533 33533,37534 38533,37536 38536,22358 13355,25358 13360,25361 13358,25362 13362,25362 13362,25365 13365,25363 13367,25359 13369,25357 13374,25360 13374,2247 13362,2252 13366,2254 13363,2257 13363,2261 13358,2264 13354,2264 13356,2269 13361,2272 13363,2274 13363,2275 13363,2273 13362,2274 13365,2278 13365,2280 13370,2284 13366,2284 13365,2289 13368,2290 13366,2293 13368,2298 13373,2298 13372,2295 13375,271 22347,273 22350,4273 22347,4269 22348,4270 22350,4271 22355,4272 22360,4276 22363,4281 22365,4284 24365,4279 24365,4282 24365,4285 24365,4287 24364,4289 24362,4294 24360,4295 24362,4298 24365,4301 24369,1301 24370,1301 24371,1305 24375,1305 24376,1307 24377,1312 24380,1314 24382,1318 24380,1316 24382,1316 24387,1318 24387,1318 29387,1321 29387,1316 29383,1320 29386,1321 29389,1326 29389,1327 29389,2327 29394,2327 29394,2332 29393,-666 24367,-663 24368,-661 24368,-656 24371,-653 24372,-649 24372,-647 24374,-643 24370,-638 24375,-635 24380,-638 24382,-638 24384,-638 24384,-636 24388,-637 24390,-632 24386,-630 24386,-629 24386,371 24389,376 24394,374 24392,377 24397,3377 24400,6377 24405,6378 24408,6373 24406,6370 24406,6375 24403,6370 24403,6375 24403,6379 24406,6374 24409,6378 24411,6380 24412,6378 24415,6378 24419,6383 24423,6385 24425,6387 24428,6390 24433,6386 24430,6386 24435,6387 24436,6388 24440,6387 24444,6383 29444,6383 29447,6386 29451,6382 29446,6387 29447,6390 29452,6393 29452,6397 29455,6400 29459,6400 29463,6397 29467,6393 29467,6395 29470,6397 29473,6399 29468,6394 29467,6397 29470,6396 29473,6396 29470,6393 29465,6389 29469,6390 29470,6389 29465,6389 29468,6392 29470,6388 33470,6390 33466,6391 33466,6392 33467,6394 33467,322 22372,322 22374,323 22377,327 22378,331 22382,330 22383,332 22386,333 22383,331 22383,330 22387,332 22391,332 22396,337 22397,339 22394,340 22399,340 22398,340 22396,343 22396,343 22396,341 22400,342 22404,343 22402,348 22403,345 22407,347 22411,342 22411,345 22413,340 22417,345 22417,348 22422,348 22426,351 22427,352 22432,352 22436,4352 22438,4353 22442,4354 22444,4354 22447,4357 22449,4360 22450,4364 22450,4367 22451,4369 22453,4366 22455,4369 22453,4373 22458,4377 22459,4380 22459,4380 22464,4385 22467,4385 22467,4390 22469,4385 22469,4385 22472,25571 26508,25574 26507,25578 26512,25581 26512,25581 26512,25583 26508,25583 26513,25587 26516,25589 26515,25590 26515,25591 26517,25589 26520,25587 26522,23587 26526,23585 26531,23589 26534,23592 26538,24592 26543,24588 26545,24593 26547,24598 26543,24598 26548,24602 26545,24598 26540,24600 26545,24600 26548,24600 31548,24605 31549,24608 31551,24613 31552,24615 36552,24616 36557,24619 36557,24622 36560,24622 36564,24627 35564,24627 35569,24632 35569,25632 35570,25635 35569,25636 35573,25636 35573,25638 35576,25641 35580,25641 35583,25641 35588,25642 40588,20642 40593,20645 40593,20650 40595,20651 40591,20651 40594,20648 40591,20648 40591,20652 40596,20652 40596,20656 40597,20656 40600,20656 40601,20659 40598,20662 40597,20662 40597,20663 40600,20668 40601,20665 40606,1215 13314,1214 13319,1212 13317,1209 13312,1210 13312,1211 13317,6211 13320,6214 13320,6216 13320,6211 13323,6214 13318,6214 13323,6214 13324,6216 13319,6219 13323,6218 13321,6219 13321,6218 13326,6221 13329,6225 13331,6230 13335,6231 13339,6231 13343,6235 13338,6234 13342,6234 13344,6236 13345,25524 26483,25521 26484,25524 26489,25527 26487,25529 26484,25530 26482,25534 27482,25539 27486,25537 27488,25541 27483,25544 27486,25547 27490,25550 27491,25550 27491,25554 27486,25559 27486,25563 27489,25561 27489,25563 27493,25561 27491,25563 27493,25563 27495,25564 27497,25563 27497,25563 27497,25558 27498,25563 27499,25565 27503,25567 27503,25569 27503,25567 27504,25565 27505,25565 27505,25565 27505,25566 27505,25570 27501,25570 27497,25574 27498,25570 32498,25570 32501,25573 32501,25576 32497,25576 32498,25577 32501,25579 32503,25583 32504,25588 32507,25592 32512,25596 32507,25599 32507,25594 32503,25597 32506,25597 32510,25594 32509,25594 32510,25596 32513,25592 32513,25594 32515,25594 32520,25598 32520,25602 32517,25603 32518,27603 32520,27607 32523,27608 31523,27613 31527,27615 31527,30615 31530,30617 31530,30618 31532,30619 31536,30623 31537,30623 31538,30625 31538,30626 31541,30627 31541,30624 31540,30623 31540,30624 31545,34624 31546,34619 31543,34623 31545,34624 31549,34624 31548,34626 31550,34626 31555,34626 31551,34628 31555,34633 31555,34636 31559,34634 31564,34636 31564,34639 31562,34639 31560,36639 31555,36636 27555,41636 27557,41640 27554,41644 27558,41647 27559,41648 27555,41653 27555,41658 27555,41658 27552,41658 27552,41660 27550,41656 27554,41661 27558,41664 27561,41667 27566,41662 27562,41663 27563,41663 27565,41662 27569,41661 27569,41664 27571,41664 27567,41659 30567,41660 30565,41660 30561,41665 30566,41664 30561,41664 30561,41664 30562,41664 30563,41660 30558,1312 24380,4312 25380,4315 25384,4315 25385,4319 25383,4322 25388,6322 25387,6322 25387,6326 25392,6321 25397,6324 25397,6324 25401,6319 25404,9319 25405,9314 25400,9312 25402,9310 25403,9313 25403,9313 25403,9316 25400,9319 25401,4319 25396,8319 25398,8315 25400,8315 25396,8315 25397,8311 25398,8307 25394,8309 25394,8311 25397,8315 25402,8310 25403,11310 25365,11311 25365,11316 25370,11320 25375,11325 25375,11325 25380,11325 25382,11326 25378,14326 25380,14328 25382,14331 25383,14334 25385,14336 25386,19336 25386,19336 25389,19332 25390,19332 25391,19335 25388,19338 25391,19342 25393,19340 25393,19345 25396,19345 25394,19347 25394,19349 25393,19351 25397,19350 25398,19348 25399,19349 25403,19352 25399,19350 25402,19354 25400,19353 25405,23353 25402,23354 25402,23356 25405,23358 25409,23360 25413,23363 25414,23367 25412,23365 25411,23367 25414,23363 25413,23367 25416,23367 25416,23370 25418,24370 25414,24370 25419,24373 27419,24378 27419,24380 27416,24380 27412,24380 27410,24380 27406,24376 27406,24374 27410,24370 27414,24370 27415,24371 27420,24375 27415,24378 27411,24375 27415,24378 27418,24382 27421,24383 27426,24383 27425,24385 27430,24390 27431,24394 27432,24395 27436,24399 30436,24400 30439,24404 30443,24403 30439,24406 30438,24410 30442,24406 30446,24408 30445,24403 30445,24408 30442,24412 30446,24416 30446,24416 30449,19416 30449,19416 30447,19418 30452,19420 30453,19423 30458,15423 30462,15423 30464,15425 30466,16425 30467,16424 30471,16421 30474,16426 30474,16428 30476,16428 30476,16424 30474,16424 33474,16425 33474,16427 33477,16425 33479,16426 33477,16422 33480,16425 33482,16430 33479,16430 33478,16429 33482,16424 33482,16427 33484,16430 33488,16431 33488,16434 33488,16435 33491,16432 33487,16436 37487,16434 37490,16438 37485,16443 37482,16446 37480,16447 37480,16447 37482,16451 37478,16454 37479,16458 37479,16454 37479,16454 37482,16459 37486,16460 37491,16463 37495,16464 37492,16465 37493,16466 37494,16468 37497,16468 37501,16468 37501,16473 37503,16473 37503,16473 37498,16476 37494,21476 33494,21473 33493,21476 33489,21478 33491,21478 33496,21478 33492,21480 33496,21483 33501,21484 33504,21483 33500,21484 33505,21484 33505,21488 35505,21491 35505,21494 35506,21496 35510,21492 35506,21492 35509,21489 35514,21490 35517,21487 35519,23487 35523,23485 35528,23487 35533,23483 35534,23487 35535,23488 35537,23493 35539,23495 35542,23495 35546,23495 35550,23491 35549,23488 35552,23492 35555,23495 35560,23500 35559,23496 35557,4322 16354,4317 16358,4318 16358,4320 16363,4315 16363,4315 16362,4316 20362,4320 20365,4323 20363,4326 20366,4329 20367,4332 20370,4337 20374,4338 20375,4333 20375,4338 20375,4341 20377,4342 20377,4342 20378,4343 20381,4346 20386,4346 20386,4346 20386,4346 20386,4349 20390,4352 20395,4354 20396,4355 20400,4358 20400,4360 20401,4360 20404,4363 20405,4368 20406,4372 20411,4371 20416,4367 20417,4364 20422,4367 20420,4372 20425,4373 20422,4374 20418,4377 20418,4381 20422,4382 20423,4384 20418,4389 20421,4385 20423,4390 20423,4390 20425,4392 20429,4396 20434,41574 39698,41578 39702,41576 39704,45576 39704,45575 39709,45577 39713,45581 39715,45581 39718,45583 39721,45578 39726,47578 39722,47581 39719,47586 39722,47586 39726,47589 39730,47592 39733,47597 39733,47593 39733,47596 39735,47597 39735,47595 39735,47591 39739,47593 39744,47593 39747,4074 20263,4077 20268,4079 20268,4078 20271,4078 22271,4083 22276,4087 22272,4088 22275,4086 22279,4082 22280,4084 22282,4086 22277,4082 22277,4087 22281,4090 22281,4092 22281,4092 22286,4094 22287,4097 22290,4097 22291,4095 22286,4095 22288,4095 22293,4095 22288,4092 22285,4089 22286,4090 22286,4095 22281,4100 22286,4103 22285,4104 22288,4104 22289,4107 22294,4112 22292,4117 22290,4120 22295,120 22300,121 22303,122 22300,122 22300,121 26300,125 26303,129 26303,127 26305,127 26306,132 26306,132 26307,136 26307,141 26309,140 26311,143 26313,140 26314,145 26318,149 26318,153 26321,153 29321,158 29326,158 29329,162 29324,162 34324,165 34329,168 34328,167 34332,169 34333,173 34334,173 34336,177 34338,178 34340,178 34344,182 34348,177 34348,182 34348,184 34353,184 34358,181 34360,183 34365,187 34365,192 34365,197 34367,199 34366,203 34368,205 34368,202 34363,204 34360,1204 34360,1205 34364,1205 30364,1205 30359,1206 30361,1207 30364,1210 30366,1210 30366,1214 30367,1218 30372,1219 30375,1214 30379,1214 30384,1217 30382,1222 30383,1223 30382,1225 30380,1228 30379,1231 30383,1232 30383,1235 30384,1237 30388,1242 30386,1244 30389,2244 30392,2241 30395,2245 30397,2245 30399,2244 30394,2242 30395,2246 32395,2246 32395,2249 32398,2251 32393,5251 32390,5251 32395,5255 32399,5255 32397,5257 32397,5257 32401,5261 32406,5261 32411,5266 32412,5271 32416,5273 32419,5276 32420,5281 32422,5279 32425,6279 33425,6284 33429,6284 33430,6282 33431,6282 33428,6286 33425,6288 32425,6288 32421,6286 32424,6288 32424,11288 32427,11292 32425,11292 32429,11290 32434,11286 32437,11286 32437,11283 32442,11278 32442,11279 32443,11283 32445,11284 32445,11283 32448,13283 32447,13287 32442,16287 32446,16282 32445,16283 32445,16284 32448,16285 32448,16284 32446,16286 32443,16290 32446,16291 32446,16292 32450,16291 32450,16291 32450,16291 32445,16287 32447,16288 32452,16287 32457,16291 36457,16289 36462,16293 36462,16294 36462,16297 36462,16301 36464,16306 36469,16310 36467,16310 36463,16313 36459,16312 36460,16313 36465,16313 36469,16308 36470,16309 36468,16314 36470,16319 41470,16322 41471,16325 44471,16330 44471,16330 44471,16330 44473,16330 44474,16335 44479,16332 44477,8414 30496,8415 30497,8419 30497,8414 30501,8416 30500,8418 30495,8421 35495,8423 35494,8427 35497,8429 35499,8432 35499,8436 35503,8438 35503,8443 35505,8440 35508,8443 35509,8440 35509,8440 35511,8441 35515,8445 35511,8448 35512,8443 35517,8443 35519,8442 35524,8444 35526,8441 35527,8436 35527,8433 35523,8429 35527,8430 35530,8431 35532,8429 35533,8433 35535,8437 32535,8435 32536,8439 32536,8436 32539,9436 32542,9434 32537,9429 32534,9429 32534,9433 32537,9433 32542,9429 32543,9434 32538,9436 32538,9436 34538,7436 34538,7438 34543,7439 34543,7439 34543,7439 34548,7438 34549,7438 34552,7438 34553,7438 34556,11438 34561,11434 34559,11436 34555,7436 34553,7436 34549,120 1235,124 1239,125 1236,125 1238,129 1235,128 1235,125 1236,123 1239,128 2239,132 2242,131 2242,135 2242,140 2242,145 2247,146 2252,144 2253,146 2248,144 2245,146 2244,150 2249,155 2245,159 2242,160 2243,160 2245,155 2244,156 2245,3156 2246,3159 2248,3159 2250,3164 2254,3165 2257,3166 2255,3169 2257,3171 2262,3169 2263,3174 2268,3177 2273,3174 2276,3178 2275,3173 2279,3177 2276,3180 2279,3182 2284,3185 2289,5185 2286,5185 2288,5181 2286,5185 2288,5184 2293,5187 2293,5187 2297,5190 2299,5187 2299,5185 2300,5181 6300,5182 6297,5187 6300,5189 6298,5191 6296,5193 6296,5193 6296,5195 6297,5195 6300,5197 6297,5195 6300,5190 6302,5191 6306,5192 6308,5195 6312,24395 27436,24391 27437,24393 27433,24398 27436,24398 27437,16286 32443,21286 32443,21286 32444,21282 32448,21283 32446,21283 32448,21285 32451,21281 32456,21282 32458,21282 32463,21282 32468,21284 32470,21289 32471,21287 32471,21287 32469,21287 32474,21284 32477,21288 32482,21291 32482,21291 32486,21296 32485,21299 32486,21301 32487,21303 32484,21301 32482,21305 32487,21310 32491,21312 32495,21313 32491,21315 32495,21312 32495,21314 32498,21316 32501,21311 32506,21311 32508,21312 32513,21317 32516,21319 32516,21324 32516,21327 32521,21328 32526,21332 32527,21328 36527,21331 41527,21336 41527,21334 41531,21337 41533,21335 41535,21339 41540,21340 41540,21343 41536,25343 41539,25340 41542,25337 41542,25337 41545,25335 41542,25335 41543,25335 46543,25339 46548,30339 46551,30340 46556,30343 46557,30342 46553,30337 46556,30341 46561,30337 46565,30336 46563,30338 46564,24373 27419,24373 27421,24375 27424,24377 27425,24377 27430,24374 27435,24379 27437,24384 27432,24385 27434,24382 27437,24381 27442,24381 31442,24381 33442,20381 33439,20383 34439,20382 34440,20378 34444,20381 34446,20381 34442,20384 34443,20388 34446,20392 34447,20393 34442,20393 34447,20396 29447,20395 29443,20399 29443,20400 29439,20399 29436,20404 29439,20409 29440,20410 29440,20410 29444,20408 29445,20413 29448,20413 29451,20412 29455,20413 29458,20418 29461,20413 29463,20415 29464,20416 29464,20416 29463,20416 29463,20418 29464,20414 29465,20418 29463,20413 29460,20413 26460,20418 26458,20421 26459,20421 26461,20421 26460,43578 35658,43578 35654,43578 35658,43578 35660,43583 35661,43583 35659,43583 35662,43579 35663,43583 35661,43587 35666,25625 25551,25629 25551,25630 25554,25630 25559,25632 25560,25627 25561,25623 25557,25623 25559,25624 25561,26624 25566,26627 25566,29627 25571,29626 25574,29625 25575,29622 25579,29625 25583,29630 25588,29632 25589,29635 25591,29635 25594,29637 25598,29642 25596,29643 25597,29644 25597,29649 25598,29654 25602,29656 25602,29661 25603,29661 25601,29664 26601,29666 26604,29665 26604,29668 26607,29672 26607,29669 26611,29671 26616,29674 26613,29679 26616,29680 26616,29681 26615,29682 26619,29679 26617,29684 26622,29686 26624,29689 26624,29690 26628,29691 26630,29693 26625,29694 26620,29698 26617,29703 29617,29707 29616,29706 29620,29709 29623,34709 29626,34710 29628,34710 29627,2282 16411,2283 16412,2283 16412,2287 16417,2292 16421,2297 16421,2298 16426,2303 16426,2304 16429,2309 11429,2313 11432,2308 14432,2308 14431,2311 14433,2310 14437,2308 14438,2309 14440,2311 14440,2309 14443,2312 14443,2314 14447,2314 14452,2314 14450,2309 14451,2309 14451,2309 14456,2313 14461,2313 14461,2309 19461,2309 19461,2311 19462,2315 19465,2318 19465,2321 19462,2317 19464,2321 19467,2322 19467,2322 19469,2322 19469,2320 19464,2321 19462,2322 19461,2327 19466,2327 19461,2322 19461,2322 19463,2317 19467,2318 19471,2102 -1848,2107 -1848,2111 -1846,2114 1154,2114 1156,2115 1157,2114 6157,2116 6162,2121 6165,2124 6170,2121 6175,2124 6179,2124 6183,2128 6178,2126 6179,2125 6178,2126 6181,2122 10181,2127 10186,2128 10189,2130 10188,2130 10191,2127 11191,2127 11195,2131 11196,2132 11192,2131 11197,2135 11201,2135 11203,2139 11199,2142 11203,2143 11204,2147 11208,2142 11210,2142 11211,2147 11212,2150 11217,2150 11219,2151 11219,2152 11222,2152 11222,2148 11224,2150 11220,2150 11223,2146 11218,2143 11219,2140 11221,2143 11218,2140 11219,2140 11223,2145 11225,2147 11226,2152 11226,2155 11224,2157 11229,2157 11229,2153 11233,2153 11238,2149 11239,7149 10239,7154 10241,7157 10241,7162 10243,7164 10248,7164 10251,7169 10253,7171 10253,7172 10257,7177 10260,7182 10256,7187 10260,7191 8260,7195 8256,7200 8258,7204 8258,7203 8261,7203 8262,7205 8266,7209 8270,7209 8273,7214 8273,7214 8276,7210 8276,7211 8276,7213 8279,7218 8278,7222 8283,7223 8279,7220 10279,7221 10283,7223 10284,7228 10286,7230 10290,7231 10290,7231 10293,7232 10294,7232 10297,7234 10299,7229 10295,7226 10294,7221 10293,7223 10295,7228 10299,7229 10303,7232 10307,7232 10311,7233 10316,7234 9316,7239 9318,7244 9321,7241 9326,7241 9328,7238 9331,7235 9330,7237 9335,7236 9335,7236 9337,7236 9338,7231 14338,7230 14333,7232 14338,7237 18338,4082 22280,4081 22280,6081 22283,6076 22285,6076 22289,6078 22286,6080 22287,6084 22292,6084 22293,6085 22293,6086 22291,6091 22294,6092 22293,9092 22290,9095 22294,9096 22295,9096 22297,9091 22292,9096 22295,9098 22290,9094 18290,9097 18290,9096 18294,9099 18292,9098 18297,9103 18299,9103 18302,9103 18305,9100 18301,9102 18302,9106 18305,9102 18310,9101 18306,9103 18308,9103 18312,9107 18310,9107 18315,9107 18320,9111 18322,9111 18326,9113 18329,9111 18329,9116 18329,9121 18329,9121 18332,9123 18331,9124 18332,9125 18328,9127 18325,9125 18328,9128 18329,9133 18329,9136 18333,9141 18337,9142 18342,9143 18340,9148 18344,9152 18341,9150 18346,9149 18341,9149 18341,9154 18343,9158 18345,9161 18346,9161 18347,9163 18352,9164 18352,9162 18349,9165 18352,9165 18351,9165 18352,9165 18356,9163 18352,9167 18353,9167 18349,9168 18351,9168 18347,9173 18347,9175 18347,9179 18348,9182 18349,9187 18352,9186 18357,9189 18360,9192 18360,9196 18362,13196 18367,13196 18369,13196 18371,13199 18374,13194 18374,13197 18375,13200 18377,13205 18380,13210 18384,13209 18379,13209 18374,13213 18375,13216 20375,13212 20375,13215 20375,13211 20375,13211 20372,13208 20373,13204 20373,13204 20369,13205 20369,13207 20366,13212 20367,13216 20367,13221 20372,13222 20377,13225 20381,13226 20386,13230 20383,9230 20388,9228 20384,9228 20386,9223 20389,9223 20392,4223 20397,4223 20396,4225 20399,4222 20404,4220 20408,4220 20411,4223 20416,4227 20421,4230 20418,4234 20421,4232 20422,4236 20423,4238 20423,4239 20423,4235 20427,4231 20427,4230 20426,4228 20428,4232 20427,4232 20431,4236 20433,4241 20431,4241 22431,4236 22436,4239 22437,4239 22439,4236 22443,4232 22439,4236 22444,4236 22446,4239 22447,4239 22452,4241 22454,4245 22457,4245 22460,4250 22462,4251 22465,4253 22465,4249 22465,4251 22460,4251 22464,4255 22469,4257 22473,4256 22478,4259 22479,4260 22480,4257 22485,6257 22489,6260 22490,6260 22493,6262 22496,6262 22500,6267 22495,6271 22495,6276 22491,6276 22489,6281 22487,6286 22490,6289 22490,6294 22490,6294 22489,6292 22485,6292 22489,6288 22489,6288 22494,6288 22496,6286 22497,6288 22501,6292 22500,5292 22503,5292 22503,5296 22508,5295 22510,5300 22510,5305 22513,5302 22514,5306 22510,5309 22513,5313 27513,5313 27513,5317 27513,5322 22513,5326 22517,6326 22516,6323 22518,6323 22523,6320 22523,6321 22526,6323 22531,6323 22531,6324 22532,6324 22532,6325 22529,6321 22531,6323 22534,6328 22534,6329 22530,6324 22527,10324 22522,10319 22524,10315 22520,10314 22525,10311 22525,10307 22526,10304 22531,10306 22527,10306 22528,10309 22530,10312 27530,10312 27534,10312 27534,10307 27536,10307 27532,11307 27531,11307 27533,11308 27535,11303 27531,11298 27532,11294 27534,11294 27534,11299 27538,11297 27542,11302 27547,11306 27547,11311 27549,11313 30549,11317 30551,11313 30546,11316 30541,11316 30540,11319 30545,11318 30546,11323 30550,11326 30554,11326 34554,11330 34558,11331 34558,11333 34558,11332 34561,11328 34561,11331 34562,11336 34562,11336 34567,11340 34570,11342 34569,11345 34568,11344 34569,11345 34571,11349 34574,15349 34574,15354 34569,15359 34566,15362 34571,15363 34576,15367 34577,15368 34577,15371 34581,15374 34576,15379 34574,15383 34579,15384 34584,15387 34583,17387 34578,17392 34578,17391 34578,17396 34573,17397 34578,17397 34580,17397 39580,17402 39584,17397 39587,17402 39587,17406 39582,17403 39587,17407 39589,17409 39592,17406 39592,17409 39595,17409 39599,17412 39603,17416 39608,17417 39608,17417 39608,17421 39607,17422 39609,17424 39608,17427 39604,17425 39605,17426 39609,17423 39611,17422 39610,17425 39613,17428 39618,17428 39619,17429 39616,17432 39616,13432 39615,13432 39617,13432 39617,13432 44617,13434 44621,13434 44623,13439 44627,13442 44632,13442 44635,13440 44631,13442 44631,13445 44635,13447 44639,13445 44637,13445 44638,13450 44639,13454 44644,13457 44644,13459 44642,15459 44639,15457 44644,15461 44644,15462 44642,15459 44645,15459 44647,15463 44650,15458 44651,15459 44653,15461 44657,15463 44661,15463 44661,15463 44663,15467 44666,15472 44668,15474 44664,15470 44668,15471 44670,15473 44674,15475 44675,-3806 12298,-3804 12301,-3805 13301,-3804 13296,-3808 13292,-3809 13295,-3806 13300,-3804 13297,-3801 13301,-3801 13302,-3796 18302,-3801 18306,-3799 18311,-3802 18311,-3799 18312,-3801 18314,-3796 18319,-3795 18322,-3791 18321,-3786 18320,-3786 18321,-3784 18321,-3782 18321,-3781 18324,-3782 18325,-3783 18320,-3788 18324,-1788 18324,-1788 18329,-1784 18333,-1784 18334,-1781 18329,-1777 18334,-6777 18337,-6774 18339,-6776 18341,-6781 18341,-6779 18341,-6779 18343,-6779 18339,-6777 18343,-6782 18338,-6779 18341,-6778 18341,-6776 18336,-6776 18333,-6776 18333,-6780 18338,-6784 18338,-6787 18335,-6786 18336,-6781 22336,-6781 22335,-6778 22331,-6777 22326,-6777 22331,-6777 22335,-6772 22335,-6774 22340,-6769 22341,-6767 22337,-6767 22335,-6767 22335,-6767 22333,-6767 22336,-6762 22331,-6759 22331,-6764 22332,-6765 22334,-6767 22339,-6762 22334,-6760 22334,-6760 22334,-6758 22337,-6754 22341,-6754 22342,-6750 22339,-4750 22343,-4747 22343,-4752 22343,-4751 22344,-4749 22345,-4745 22348,-4740 22353,-4736 22358,-4738 22363,-4740 22358,21336 41527,21334 41527,21330 41526,21330 41526,21333 41529,21328 41529,21329 41530,21326 41532,21328 41532,21324 41537,21328 41532,21330 41535,21334 41532,21336 40532,21334 40536,21339 40534,21341 40534,21344 40534,21346 40532,21350 40532,21353 40535,21357 40539,21359 40542,21360 40546,21355 40546,21360 40547,21359 40550,21356 40551,21356 40550,21357 40550,21361 40554,21358 45554,21362 45556,21366 45553,21370 45557,21374 45556,21377 45553,22377 45549,22382 45549,22382 45552,22386 45557,22387 45557,22388 45553,22392 45557,24392 45561,22392 45558,22397 45561,22399 45558,22398 45561,22400 45564,22400 45569,22404 45573,22406 45577,22406 45581,22404 45581,22407 45582,22409 45579,22409 45575,22409 45579,22407 45579,22402 45582,22402 45582,22404 45587,22406 45587,22406 45589,22411 45589,22413 45590,22417 45591,22417 45592,22422 45587,22425 45583,22428 50583,22428 50585,22428 50585,22430 50588,22435 50590,22435 50585,22435 50590,22439 50595,22440 50590,22445 50587,22442 50584,22442 50586,22443 54586,22443 54590,22446 54595,22448 54597,22448 59597,22444 59593,22449 59596,22449 59599,22452 59600,22457 59600,22458 59605,22457 59602,22462 59603,22463 59604,22461 59605,22458 59602,22457 59601,22457 59601,22455 59605,25455 59606,25457 59611,25462 59613,25464 59614,25467 59617,25472 59612,25476 59613,25478 59610,25482 59615,25482 59616,25486 59612,25483 59614,25487 59619,25492 59623,25497 59625,146 2252,150 2249,150 2249,152 2254,157 2249,158 2253,157 2252,161 2255,159 3255,161 3258,161 3255,163 3255,168 3259,168 3259,172 3263,167 3267,172 3271,172 3272,172 3274,175 3278,179 3282,181 3283,184 3280,185 3282,187 3282,191 3284,192 3286,191 6286,193 6289,198 6285,195 6290,194 6289,195 6289,199 6293,200 6288,198 6290,202 6291,207 6296,212 6301,215 6301,216 6301,211 6304,212 6304,216 6309,216 6304,214 6308,213 6308,211 6305,212 6309,217 6314,220 6317,224 6322,222 6327,220 6323,41573 39712,41572 39709,41576 40709,41580 40714,41576 40717,36576 40717,36577 40719,36582 40716,36585 40721,36590 43721,36585 43721,36582 43724,36585 43729,36590 43731,36590 43730,15289 11307,15285 11312,15286 11315,15289 11315,15294 11315,15295 11316,15296 13316,38742 37646,38743 37650,38745 37655,38744 37658,38739 37659,38737 37662,38742 37662,38745 37657,38748 37662,38748 37662,38752 37667,38753 37667,38748 37669,38748 37668,38752 37673,38754 37674,38756 37676,38758 37674,38760 37679,38760 37675,38758 37675,38763 37675,38767 37674,38772 40674,38767 40679,38772 40683,38774 44683,38778 44686,38780 44690,38780 44690,38779 44695,38782 44700,38780 44695,38775 44696,38775 44696,38775 44696,38779 44699,38783 44696,38784 44696,38786 44692,38786 44692,38786 44696,38791 44698,38793 44699,38795 44703,38800 44708,38803 44708,38807 44709,38802 44706,38806 44708,38809 44709,36809 44709,36814 44704,36813 44705,36814 44705,36816 44709,36811 44712,36812 48712,36811 48717,36815 48721,36816 51721,36818 51717,36822 51720,40822 51715,40827 51712,40830 51716,40829 51719,40832 51723,40835 51724,40840 51721,40841 51721,40836 51725,40841 51730,40846 51734,40848 51738,40849 51740,40851 51743,40854 51745,40855 51746,40857 51750,40857 51746,40861 51748,40866 51751,40862 51750,40866 51750,40869 51752,40865 51752,40863 51755,40858 51757,40855 51753,40855 51758,40852 51758,40853 51760,40857 51761,40855 51757,40852 51760,40853 51761,40855 51762,40858 51757,40859 51756,40863 51757,40863 51759,40860 51764,40859 51764,40854 51768,40850 51765,40852 51767,40852 51767,40848 51772,40852 51776,40854 51778,40852 51778,43852 51778,43854 52778,43856 52781,43859 52781,43859 52776,37512 26536,37517 26531,37520 26535,37520 26540,37522 26544,37527 26544,37532 26549,37537 26544,37540 26549,37545 26544,37549 26547,37549 26550,37548 26551,37549 26553,37546 26553,37546 26553,37549 26556,37549 26559,37552 26559,37556 26564,37560 26559,37561 26561,37565 26565,41565 26565,41569 26568,41571 26573,41571 26573,41576 29573,41571 29573,41573 29576,41573 29578,46573 29578,46569 29582,45569 29583,45572 29583,45568 29583,45573 29581,45575 29578,45571 29581,45572 29584,45572 29585,45576 29585,45578 29588,45581 29591,45582 29593,45582 29598,45584 29597,45589 29600,45585 29605,45589 33605,45593 36605,45594 36607,45599 36609,45600 36604,45604 36604,45604 36608,45604 36607,45608 36610,50608 36613,50611 36609,50614 36609,50619 36605,50624 36605,50625 36606,50625 36605,50629 36606,50624 36608,50625 36610,50626 36610,50629 36608,50627 36610,50628 36614,50632 36618,46632 34618,46632 35618,46636 35622,46636 35617,46637 35620,46639 35619,46643 35620,46645 35625,46643 35630,46648 35635,46648 35640,46649 35643,46651 35647,46655 35650,46652 35655,46657 35656,46658 35657,46662 35660,46659 35663,46662 35664,46665 35663,46667 35667,46667 35663,46670 35666,46672 35671,46674 35671,47674 35668,47676 35672,47677 35673,47677 35678,47677 35677,47677 35677,47677 35682,47672 35683,47671 35683,49671 35685,49674 35689,49677 35692,49675 35692,54675 35697,54678 35699,54674 35699,54670 35701,54670 35700,54675 35703,54676 34703,54676 34703,54679 34706,54683 34708,54688 34706,54688 34707,54685 34702,54687 34702,54692 34707,54687 36707,54687 36706,54682 36707,54685 38707,54680 38710,54680 38714,54677 38714,54679 38719,54682 38720,54687 38716,54688 38717,54692 38722,54697 38726,54699 38727,54700 38724,54702 38720,52702 38719,52702 38719,52702 38721,52702 38725,52704 38726,52706 38728,52707 38729,52711 38728,52711 35728,52713 35733,52712 35737,52712 35739,52713 35742,52713 35745,52708 35745,52710 39745,52713 39749,52716 39748,52721 39749,52720 39753,52716 39756,52716 40756,47716 40757,47717 40761,47722 40761,47722 40761,47722 40766,47726 40769,47728 40772,47733 40777,47731 40773,50731 40777,51731 40779,51733 40782,51734 40786,51737 40784,51741 41784,51739 41783,51739 41785,51739 41785,51736 41789,51731 41789,52731 41790,52735 41791,52738 41790,52742 41789,52746 41785,52747 41785,52745 41785,52750 41782,52753 41786,52753 41787,52758 41792,52754 42792,52749 42793,52752 42794,52756 42791,52757 42790,52762 42793,52766 42797,52766 42797,52769 42802,52774 42806,52774 42805,52771 42807,52774 42807,52770 42808,52771 42811,52767 42811,52766 42812,52767 42817,52771 42817,52771 42817,52775 42815,52779 42811,52779 42812,52780 42815,52776 42818,52774 42818,52777 42822,52780 42823,52781 42827,52776 42829,52780 42832,54780 42835,54780 42840,2135 11201,2140 11203,2137 11204,2140 11209,2142 11213,2147 11211,2145 11213,2145 11213,2150 11218,2150 11221,2153 11225,2157 13225,2162 13228,2167 13231,2171 13232,2167 13229,2168 13233,2171 13237,2173 13239,2168 13234,2168 13235,2173 13235,2175 13234,2177 13235,2177 13234,2179 13229,2179 13226,2180 13226,2177 13226,2177 13231,2180 13231,2181 10231,2176 10233,2177 10232,2180 10235,2185 10237,2182 10240,6182 10240,6184 10244,6182 10242,6183 10243,6185 10246,6190 10244,6194 10244,6194 10247,6192 10247,6192 10252,6195 10256,6194 10260,6195 9260,6195 9260,6195 9264,6199 9269,6204 9272,6199 9268,6201 9268,6203 9265,6208 9268,6204 9270,6204 9275,6201 9279,6201 9281,6201 9286,6206 9281,6206 9277,6202 9281,6200 9285,6202 9288,6198 9290,7198 9293,7200 9297,7201 9297,7205 9298,7209 9298,7209 9299,8209 9302,8214 10302,8218 10306,8222 10308,8226 10313,8231 10313,8235 10318,8237 10318,8237 10323,8233 10326,8233 10327,8237 10325,8238 10328,8238 10330,8234 10330,11234 10332,11236 10333,11241 10337,14241 10338,14240 10338,14237 10339,14238 10337,14237 10339,14242 10339,14246 10339,14250 10339,14250 10339,14251 10337,14254 10337,14256 10334,14256 10332,14252 10336,14255 10340,14259 10342,14262 10347,11148 3159,11153 3163,11154 3162,11154 3165,11158 3167,11161 3172,11162 3175,11162 3176,11166 3179,11166 3181,11171 3185,11176 3180,11178 3179,11176 3181,11179 3183,11174 3182,52776 42818,52778 42822,52777 42822,52782 42817,52783 42822,52784 42823,52789 42826,52789 42823,56789 42828,56786 42829,56786 42832,56789 42836,56789 42835,56785 42838,56786 42843,51786 42844,51788 42846,51790 42847,51794 42842,51796 42842,51801 42846,53801 42849,53806 42849,53809 42852,53812 42850,53817 42846,53817 42848,53818 42853,53822 42856,53823 42854,53826 42858,53825 42860,53826 42860,53826 42864,53830 42868,53835 42873,53839 42873,53841 42872,53841 42876,53841 42879,53841 42884,53836 42888,53836 42889,53836 44889,53833 44889,53835 44893,53838 44897,53842 44897,53844 44900,53844 44904,53845 44905,53850 44903,53853 44904,53858 44906,53856 44907,53861 44909,53856 44913,53858 44916,53863 44916,53868 44918,53867 43918,53869 43921,53869 43919,53867 43919,53862 43918,53860 43923,53864 43928,53869 43930,53874 43933,53874 43932,53874 43932,53875 43930,53877 43928,53878 43924,53883 43927,55883 43929,55883 43925,55879 43929,55881 43929,55884 43928,55881 43928,55882 43929,55883 45929,55883 45933,55883 45936,55884 45941,55884 45941,55886 45946,55882 45948,55883 45952,55888 45956,55890 45957,55894 45953,55892 45954,55897 45950,55893 45954,55896 45956,55892 45955,55897 45959,55899 45961,55899 45961,55894 45962,55898 45957,55893 49957,55896 47957,55894 47956,55898 47960,55901 47964,55901 47967,55901 47970,55896 47973,55898 47969,55894 47974,55895 47975,55891 47976,55896 47979,55899 47984,55902 47983,55897 47987,55899 47989,55904 47992,55904 47993,55905 47997,55902 48001,55902 48003,55907 48000,55910 47998,55915 47999,55911 47994,55906 47998,55910 48003,55914 48000,55918 48000,55914 48000,55919 48000,55921 48003,55921 48007,55924 48007,55919 48010,55922 48005,55927 48009,55928 48008,55928 48008,55930 48012,55925 48012,55925 48016,54925 48014,54922 48018,54922 44018,54926 44013,54929 44012,54932 44016,55932 44017,55935 44017,55936 44020,55937 44022,55936 44020,55939 44015,55944 44018,55945 44022,55947 44023,55950 44024,55953 44020,55956 44023,53867 43919,53871 43921,52871 43921,53871 43923,53876 43923,53881 43923,53880 43927,53882 43931,53886 43936,53884 43937,53879 43934,53879 43937,53877 43939,53878 43938,53879 43942,53880 43947,53881 43948,53884 45948,53884 45949,53882 45953,53883 45954,53878 45956,53880 45953,53885 45958,53885 45958,53886 45957,53886 48957,53886 48962,53891 48962,53892 48964,53897 48965,49897 48962,49902 48965,49906 48967,49902 48967,49904 48971,49901 48967,49904 48970,54904 48971,54904 48971,54904 48975,54909 48979,54907 48975,54910 48975,54906 48971,54909 48973,54911 48975,54915 48978,54920 48978,54923 48981,54918 48984,54921 48984,56921 48984,56926 48986,56924 48981,56929 48980,56932 48979,56932 48977,56936 48979,56937 48981,56937 48982,61937 48984,61937 48980,61934 51980,61935 51981,61935 51984,61935 51984,61931 51986,5329 23395,5331 23395,5333 23390,5337 23392,5340 23395,5345 27395,5345 27397,5350 27398,5355 27399,5356 27402,6356 27405,6360 27407,6361 27406,6364 27402,6366 26402,6371 26402,6371 26402,6372 26405,6370 26405,6375 26406,6380 26411,6385 26413,6387 26414,6388 26419,6390 26419,6391 26424,6393 30424,6390 30429,6390 30432,6390 30430,6394 30434,6394 30437,6394 30441,6396 30442,6398 30439,6399 30436,6404 30435,6405 30435,6400 30435,6405 30440,6404 30443,6405 30447,6409 30447,6411 30447,6412 30448,6417 30446,6421 30450,6418 30448,6417 30444,6418 30449,6420 30451,6425 30456,6426 30456,6425 30458,6426 30458,6426 34458,6427 34459,6432 39459,6434 39462,6434 39467,6439 39470,6443 39467,6444 39468,6449 39473,6451 39476,6452 39481,6452 39479,6452 39476,8452 39476,8456 39478,8460 39480,10460 39482,10455 39482,10456 39484,10460 39484,10463 39484,10468 39486,10473 39482,10475 39484,10475 39486,10476 39488,10477 39492,10475 39494,10480 39499,10476 39501,10479 39506,10480 39510,10475 39508,10480 39513,10481 39516,10481 39516,10485 39521,10487 39522,10490 39523,10490 39520,10493 39520,10496 44520,10491 44519,10491 44524,10492 44520,10497 44525,10499 44525,10502 44527,10500 44531,10502 44535,10506 44535,10511 44532,13511 44536,13513 44533,13510 44535,13507 44540,13511 44543,13515 44548,13517 44549,13522 44550,13525 42550,13520 42551,13522 42553,13525 42552,13529 42557,13529 42558,13524 42559,13525 42559,13525 42562,13520 42564,13523 42567,15523 42569,15523 42572,15524 42577,15529 42577,15530 42582,15532 42584,15532 42588,15531 42587,15531 42592,15530 42587,15530 42583,15533 42583,15536 47583,15532 47583,15535 47587,15534 47590,15536 47594,11536 47590,11533 47590,11529 47590,11533 47592,11533 47592,11533 47593,11537 47598,11538 47603,11538 47603,11538 47605,11541 47609,11544 47613,14544 47614,14539 47610,14537 47610,14537 47614,14535 50614,14537 50619,14539 50619,14540 50623,14538 50623,14537 50619,25599 26540,25599 26541,25599 26544,25594 26542,25599 26543,25596 26544,25597 26543,25598 26543,25593 26544,25588 26542,25593 26545,25595 26544,25596 26544,25599 26541,25594 26544,25592 26549,25593 26548,25597 26549,25596 26550,25594 26551,25590 26550,25594 26554,25597 26550,25598 26552,25593 26555,25598 22555,25599 22557,25604 22559,25605 22558,25606 22562,25605 22559,25605 22564,30605 22569,30610 22571,30610 22575,30609 22575,30609 22576,30609 22581,30605 22581,30610 22583,30610 22584,30613 22579,30613 22581,30616 22577,30619 22577,30621 22580,30621 22585,30626 22590,30628 22593,30629 22598,30626 22603,30628 22606,30629 22607,30629 22604,30627 22606,30632 22608,30633 22608,30636 22612,30641 17612,30642 17614,30647 17614,30651 17615,30654 17610,30655 17607,30658 17611,30653 17610,30654 17606,30654 17607,30659 17606,30660 17611,30658 17616,30659 17616,30664 17619,30665 17621,30665 17620,30667 17621,30671 17624,30673 17624,30673 17624,30678 17627,30675 17632,30675 17635,30678 17640,30681 17643,30686 17639,30691 17641,30696 19641,30699 19640,30700 19640,30696 19645,30698 19643,30699 19645,30702 19646,30703 19649,30699 19651,30704 19648,30706 19652,30709 19653,30709 19655,30709 19655,30712 19657,30708 19658,30705 19660,30700 19662,30701 19663,30706 19664,30711 19663,30707 19667,30704 19670,30708 19672,30709 19673,30711 19673,30711 19674,30713 19678,30718 19682,30723 20682,30721 20686,30725 20691,30726 20693,30729 20695,30728 20690,30730 20692,30733 20694,30736 20692,30736 20691,30740 20694,30741 20695,30741 20697,30746 20700,30747 20702,30750 20701,30751 20698,30753 24698,30749 24701,30748 24703,30746 24704,30747 29704,30747 29705,30749 29707,30752 29712,30757 29712,30760 34712,30760 34716,30763 34716,30759 34713,30759 34717,30763 34717,30758 34717,30757 34721,30760 34726,30758 34726,30763 34727,30763 34727,30764 34727,30759 34729,30759 34732,30762 34734,30757 34735,30761 34736,30759 34736,30762 34738,30757 34733,30760 34735,30762 34737,30760 34736,30765 34733,32765 34737,32768 34737,32765 34740,32765 34742,32768 34747,32772 34751,32772 34752,32777 34749,32782 34751,32783 33751,32783 33746,36783 33749,36783 33754,36786 33756,36787 33755,36787 33758,36791 33754,36796 33754,36801 33756,36801 33758,36801 33762,36802 33765,36802 33765,36806 33770,33806 33772,33806 33777,33809 33777,33814 33780,33814 33785,33818 33782,33821 33784,33826 33781,33822 33781,33824 33783,33822 33784,33826 33787,33823 33792,33827 33795,33828 33798,33829 33799,33833 33801,33833 33801,33836 33805,33839 33809,33842 33805,33847 33810,33845 32810,33847 32808,33849 32812,33851 32815,33849 32818,33849 32822,33847 32822,33847 32826,33850 32831,33854 32836,33857 32833,33856 32828,33859 32829,33860 32832,33857 32834,33857 32830,33855 32830,33857 32830,33855 32834,33859 32829,33859 32833,33862 32836,33864 32837,33864 32839,33866 32837,33869 32835,33872 32840,33874 37840,33879 37845,33881 37850,33881 37855,33886 37856,33891 37860,33896 37860,33893 37863,33894 38863,33896 38859,28896 38864,28899 39864,33899 39869,33896 39871,33898 39875,33902 39873,33902 39875,33907 39879,33912 39884,33908 39887,33908 39888,33905 39890,33909 39895,33911 39896,33908 39900,33912 39901,33915 39902,33915 39902,33915 39902,33910 39907,33910 39904,33914 39903,33912 39906,33916 39909,33920 39909,33922 39912,33923 39916,33928 39916,33931 39918,33932 39919,33935 39915,33936 39912,33934 39909,35934 39914,35931 39915,35935 39917,35939 39920,35939 39915,35940 39911,35944 39916,35944 39911,35944 39908,35945 39904,35945 39908,35945 39912,35950 39915,35955 39917,38955 39916,38960 39921,38962 39920,38962 39920,38967 39922,38967 39924,38970 39928,38975 39928,38973 39928,38977 39931,38980 39934,38984 39936,38982 39939,38983 39942,38985 39943,38987 39945,38992 41945,38988 41950,38989 41954,38992 41958,38992 41962,38992 41965,38993 41970,38997 41970,38997 41970,38994 41974,38994 41979,38997 41979,38999 41982,38994 41980,38998 41985,38998 41984,5334 23406,5330 23406,5325 23403,9325 23404,12325 23408,12325 23408,12322 23406,13322 23411,13325 23416,13326 23412,13322 23414,13327 23419,13328 23422,13329 23425,13333 23422,13337 23424,23491 35549,23490 35544,23494 35546,23499 35548,23495 35549,21495 35553,21490 35556,21492 35558,21492 35556,21494 35559,21494 35564,21494 35566,21499 35566,21502 35562,21502 35567,17502 35568,17506 35573,17507 35574,17511 35578,17512 35583,17513 35588,18513 35591,18514 35592,18515 35594,18513 35596,16513 35601,16513 37601,16513 37602,16511 37604,16513 37609,16514 37611,16518 37616,16522 34616,16524 34613,16528 34615,16528 34620,16533 34624,16535 34627,16538 34628,16539 34630,16539 34631,16542 34628,16542 34633,16544 34638,16547 38638,16547 38640,16543 38645,16543 38640,16540 38640,16543 38640,16542 38641,16546 38646,16541 38649,16541 38645,18541 38648,18544 38648,18544 38653,18544 38656,18549 38651,18547 38651,18550 38656,18547 38658,23547 38663,23544 38664,23548 38668,23548 38670,28548 38672,28549 38669,28549 38673,28545 38669,28549 38670,28554 38670,28557 38674,28560 38669,28562 38674,28562 38669,28561 38669,28564 38671,28569 38671,38779 44699,38780 44695,38778 44698,38783 44700,38785 44700,38781 44701,38782 44696,38786 44691,38789 44692,38794 44692,38799 44688,38799 44693,38803 44697,38808 44697,38806 44697,38806 44700,38803 44702,38803 44706,38802 44707,38807 48707,38808 48707,38806 48707,38810 48712,38810 48709,38810 48711,38810 48711,38806 48707,38802 48710,38803 48706,38805 48711,38810 48711,38805 48709,38809 48710,38809 48710,38814 48707,38815 48703,38816 48703,38816 48704,38820 48704,38822 48709,38820 48710,38818 48714,38822 48716,38822 48719,38827 48722,38828 48727,38832 48725,38830 48730,38831 48726,38832 48724,38829 48728,8431 35532,8431 35537,4431 35532,4434 35537,4438 35537,4439 35533,4443 35535,4442 35530,4445 35527,4449 35527,4453 35530,4458 35530,4459 39530,4460 39531,4461 39531,4464 39531,4468 39531,4470 39534,4465 39534,4465 39532,4469 39532,4471 39537,4466 39538,4470 39539,4473 39540,4476 39540,4480 39543,4485 39548,4483 39546,4484 39547,4484 39549,4484 39551,4486 39553,4486 39554,4487 39551,4483 39553,4486 39554,4490 39556,4493 39557,4498 39561,4494 39562,-4749 22345,-4752 22345,-4748 22348,-4744 22351,-4740 22356,-4741 22358,-4739 22361,-4734 22359,-4730 25359,-4730 25360,-4725 25360,-4727 25360,-4727 25361,-6727 25360,-6729 25365,-6730 25365,-6727 25365,-6731 25364,-6730 27364,-6727 27366,-6723 27367,-3723 27363,-3719 27368,-3720 27371,-3718 27366,-3717 27369,-3716 27369,-3714 27372,-3711 27370,-3712 27371,-3712 27370,-3710 27375,-3708 27377,-3707 27382,-3706 27385,-3706 27389,-3705 32389,-3704 32392,-3704 32392,-3699 32391,-3699 32395,-3694 32399,-3694 32400,-3695 32404,-3695 32408,-3693 32410,-3693 32410,-3697 32410,-3692 32413,-3691 32418,-3686 32420,-3683 32425,-3681 32420,-3678 32424,-3673 32424,-3676 32427,-3673 32426,-3671 32426,-3676 33426,-3678 33428,-3676 33428,-3679 33428,-3679 33433,-3677 33434,-3676 33438,-3681 33440,1319 33444,1321 33441,1325 33444,1329 33439,1326 33444,1326 33439,1327 33439,1327 33440,1332 33444,1333 33449,1338 33453,1338 33450,1343 33450,1347 33454,1346 33457,1346 33455,1342 33459,1341 33462,1346 33462,1347 33463,1343 33463,1344 33462,1348 33457,1347 33460,1352 33464,1356 33468,1361 33469,1363 33468,1365 33469,1368 33472,1369 33475,-2631 33478,-2633 33483,-2629 33486,-2632 34486,-2628 36486,-2625 36488,-2621 36488,-2624 36488,-2622 36492,-2624 36491,-2629 36491,-2627 36496,-2623 36499,-2628 36502,-2631 36506,-2626 36506,-2622 36506,-2622 36509,-2619 36514,-2624 36512,-2621 36510,-2619 36510,-2619 36508,-2617 36512,-2615 36512,-2615 36513,-2615 36511,-2615 36506,-2612 36507,-2609 36511,-2606 37511,-2606 37508,-2610 37505,-2607 37508,-2602 37512,-2599 37512,-2595 37510,-2597 37511,-2592 37515,-2597 37514,-2592 37519,-2592 37524,-2592 37526,-2594 37521,-2594 37516,-2591 36516,-2588 36517,-2589 36513,-2586 36514,-2584 36514,-2583 36516,-2579 36514,-2578 36518,-2578 35518,-2575 35519,-2577 35519,-2578 35524,-2578 35529,-2578 35532,-2578 35534,-2580 35537,-2584 35541,-2586 35542,-2587 35544,-2585 35540,-2585 35544,-2584 35543,-2580 35548,-2576 35550,-2571 35553,-2567 35555,-2565 35560,-2560 35560,-2557 35564,-2553 35564,-5553 36564,-5548 36564,-5544 36565,-5547 36565,-5545 36570,-5542 36565,-5543 36566,-5543 36568,-5543 36570,-5540 36575,-5537 36577,-5535 36581,-5532 36580,-5528 36575,-5526 38575,-5526 38576,-5526 38571,-5522 38571,-5518 38576,-5514 42576,-5510 42581,-5512 42583,-5512 42582,-5507 42582,-5510 42585,-2510 42589,-2511 42592,-2508 42594,-2506 42597,-2503 42598,-2503 42603,-2498 42608,-2501 42611,-2500 42616,-2502 42613,-2502 42616,-4502 42616,-4502 42620,-4502 42622,-4506 42619,-4509 42621,-4511 42624,-4515 42625,-4510 42625,-4507 42628,-4502 42624,-4501 42629,-4505 45629,-4503 45630,-4499 45631,-4496 45630,-4497 45628,-4495 45630,-4494 46630,-4491 46634,-4487 46629,-4483 46631,21336 40532,21341 40533,21346 40534,21346 40536,21345 40536,21346 40536,21345 40536,21344 40538,21347 40543,21348 40543,21351 40540,21351 40542,21348 40545,21351 40546,21352 40546,21353 40546,21358 40546,21359 40545,21359 40550,21357 40555,21362 40560,21364 40555,21363 40555,21364 40560,25364 40564,25365 40566,25368 40566,25371 45566,25372 45567,25372 45562,25376 45564,25381 42564,25385 42560,25389 42564,25389 42568,25393 42572,25390 42572,28390 42569,28389 42570,28385 42574,28386 42576,28389 42577,31389 42578,31385 42582,31387 42582,31390 42578,31391 42579,31392 42576,29392 42580,29396 42582,29398 43582,29402 43584,29406 43585,29407 43587,29411 43592,29413 43594,29414 43595,25414 43600,25412 43595,25415 43599,25420 43602,25418 43604,25423 43599,25426 43599,25429 43602,25434 42602,25429 42604,25432 42600,25435 42605,25436 47605,25440 50605,25441 50610,25439 50614,25444 50617,25447 50621,25444 50624,25444 50626,25445 50627,25450 50632,25450 50628,25451 50630,25451 50632,25454 50633,25458 50637,25462 50641,25463 50640,25463 51640,25467 51644,25469 51649,25473 51650,25474 51653,25475 51654,26475 51658,26475 51662,26474 51665,26476 51665,26481 51661,26483 55661,26485 55664,30485 55667,30485 55670,30489 55671,30489 55668,30491 55670,30492 55670,30493 55675,30497 55675,30501 55671,30503 55676,30500 55677,30498 55672,30494 55675,30499 55676,30500 55676,30505 55681,30501 55684,30496 55685,30500 55685,30502 55687,30506 55692,30507 55693,30506 55692,30511 55693,30516 55694,30514 55699,30514 55701,30512 55701,34512 55705,34516 55708,34520 55704,34518 56704,34519 56704,34520 56706,34517 56706,34515 56701,34519 59701,34522 59706,34522 59708,34522 59713,34526 59715,34528 59717,34533 59712,34538 59715,34538 59717,34541 59717,34546 59720,34548 59721,34552 63721,34547 63726,34549 63728,34554 63726,34556 63726,34557 63721,34556 63725,34561 63730,34558 63730,37558 63725,37561 63729,37565 63724,37569 63720,37573 63718,37578 63722,37577 63718,37579 63720,37579 63722,37580 63719,37580 63720,37579 63724,37574 63725,37574 63727,37576 63725,37581 63729,37583 63732,37586 63732,37590 63737,37592 63734,37597 63731,37600 63730,37596 63731,37596 63733,37600 63733,37601 63735,37596 63735,37591 63732,37596 63733,37601 63738,37602 63733,37599 63738,37594 63740,37598 63744,37603 63745,37605 63747,37607 63752,37607 63756,37603 63757,37603 63761,37604 63761,37608 63758,37609 63762,37604 63764,37604 63764,41604 63765,41600 63761,41599 63761,41600 63766,41596 63766,41599 63766,41601 63770,41604 63768,41608 63768,41611 63772,41614 63767,41609 63763,41612 63765,41615 63760,38615 63764,38615 63768,38618 63768,35618 63769,35618 63774,35617 63775,35618 63776,35613 63775,35615 63780,35612 63782,35613 63779,35614 63775,35618 63774,35619 63776,35624 63778,35624 63780,35629 63785,35629 63780,35626 63781,35624 63782,35629 63784,35634 63787,35638 63782,35634 63783,35634 63778,35633 63777,35638 63782,35641 63786,35644 63791,35648 63793,35647 63793,35649 63797,35653 63801,35654 63804,35654 63804,35656 63804,35655 63806,35658 63810,35658 63805,35662 63805,35657 67805,35658 67808,35660 67811,35664 67808,35660 67803,35658 67803,35661 67803,35663 67808,35666 67810,35670 67814,35669 67813,35669 67816,37669 67820,37664 67820,2275 13363,2278 16363,2274 16363,2275 16362,2279 16362,2282 16362,2287 16366,2284 16366,4284 16366,4286 16371,4290 16375,4294 18375,4295 18377,9295 18381,9296 18381,9299 18382,9303 18379,9305 19379,9308 19375,8308 19380,8312 19380,38746 37651,38749 37652,38754 37653,38757 37656,38753 37661,38753 37661,38758 37663,38763 37664,38763 42664,38768 42666,38765 42668,38770 42664,38767 42659,38768 42659,38773 42654,38771 42659,38775 42661,41775 42663,41778 42665,41781 42669,41782 42667,41779 42669,41784 42672,41781 42672,41783 42672,41780 42672,41783 42675,41784 42675,41788 42676,41792 42677,41792 42675,41793 42680,41793 42676,41796 42681,41801 42685,41804 42684,41806 42685,41804 42690,41802 42692,41805 42696,41800 42697,41802 42698,41804 42700,41809 42704,41813 42705,36813 42708,36813 42704,36810 42703,36811 42705,40811 42706,40815 46706,40816 46708,40820 46708,40818 46712,40822 46717,40825 46720,40829 46724,40827 46727,40831 46727,40833 46731,40829 46733,40830 46733,36830 46738,36830 46741,36834 46744,36831 46749,36826 46748,36822 46748,36824 46751,36819 46755,36823 46758,36823 46762,36824 46766,36822 46769,36826 46772,36831 46774,36828 42774,36833 42776,36833 42777,36838 42782)')));
@@ -14,171 +16,20 @@ DELETE FROM t1 WHERE p = 3;
UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
ROLLBACK;
-connection con1;
+connection control_purge;
# disable purge
-CREATE TABLE t0 (a INT) ENGINE=InnoDB;
-BEGIN;
-SELECT * FROM t0;
-a
-connection default;
-DELETE FROM t1 WHERE p = 3;
-UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
-UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
-ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
-connection con1;
-# enable purge
-COMMIT;
-connection default;
-DELETE FROM t1 WHERE p = 2;
-# wait for purge to process the update_undo records.
-CREATE TABLE t2 (
-p INT PRIMARY KEY,
-g1 POINT NOT NULL,
-g2 POINT NOT NULL,
-g3 LINESTRING NOT NULL,
-g4 LINESTRING NOT NULL,
-g5 GEOMETRY NOT NULL,
-g6 GEOMETRY NOT NULL,
-SPATIAL KEY (g1),
-SPATIAL KEY (g2),
-SPATIAL KEY (g3),
-SPATIAL KEY (g4),
-SPATIAL KEY (g5),
-SPATIAL KEY (g6)
-) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
-DROP TABLE t2;
-DROP TABLE t1;
-DROP TABLE t0;
-CREATE TABLE t1 (
-p INT NOT NULL AUTO_INCREMENT,
-g LINESTRING NOT NULL,
-PRIMARY KEY(p)
-) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
-ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
-INSERT INTO t1(g) VALUES(ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)'));
-INSERT INTO t1(g) VALUES(ST_linefromtext(concat('linestring','(18 106,19 106,24 111,27 108,32 104,37 107,42 107,44 112,44 116,40 118,43 114,46 114,42 118,44 123,45 123,49 123,53 119,50 123,50 124,54 126,58 125,59 126,64 127,65 127,69 131,74 132,75 135,78 139,2078 141,2075 143,2077 143,2079 143,2084 143,2085 147,2090 -1853,2086 -1852,2086 -1856,2089 -1852,2093 -1850,2090 -1851,2090 -1852,2091 -1851,2092 -1850,2097 -1847,2102 -1848,2100 -1852,2100 -1852,7100 -1851,7103 -1850,7104 -1847,7109 -1842,65 127,67 131,66 131,61 132,61 133,62 137,65 1137,2065 1135,2061 1135,2064 1135,5064 1135,5066 1135,5070 1136,5070 1141,5071 1138,5074 1141,5075 1141,5074 1137,5076 1137,5071 1139,5066 1142,5065 2142,5068 2147,5073 2151,5069 2156,5071 2157,5072 2162,5074 2165,5069 2169,5072 2169,5076 2173,5074 2169,5078 2169,5076 2170,76 2175,74 2179,75 2184,80 2188,83 2190,87 2189,84 2193,87 2189,86 2190,87 2195,87 2200,87 1200,85 1202,86 1199,87 1200,87 1201,91 1206,92 1204,94 1204,98 1206,102 1208,105 1211,102 1216,105 1220,109 1224,110 1224,114 1225,117 1224,118 1229,117 1232,122 1237,123 1236,120 1235,124 1237,121 1236,122 1240,126 1244,127 1246,126 1249,125 5249,123 5251,127 5251,131 5251,135 5256,138 5257,135 5257,139 5257,138 5258,141 5260,146 5260,146 5260,143 10260,147 10265,151 10270,156 10266,157 10269,162 10273,166 12273,168 12274,163 12270,168 12275,170 12277,170 12277,-3830 12277,-3825 12277,-3824 12278,-3825 12276,-3825 12278,-3822 12277,-3825 12275,-3829 12278,-3828 12275,-3824 12280,-3827 12280,-3826 12282,-3822 12283,-3822 12286,-3820 12288,-3818 12289,-3816 12294,-3817 12297,-3819 12300,-3816 12297,-3813 12295,-3811 12299,-3811 12297,-3806 12298,-3806 12298,-3804 12301,-3801 12306,-3803 17306,-3803 17306,-3798 17306,-3803 17310,-3801 17314,-3798 17317,-3797 17317,-797 17321,-797 17323,-796 17325,-793 17326,-792 17322,-789 17327,-784 17331,-780 17335,-776 17339,-774 17339,-771 17342,-770 17345,-765 17348,-765 17349,-763 17353,-760 17350,-760 22350,-756 22346,-752 22349,-748 22352,-752 22348,-748 22347,-746 22345,-745 27345,-743 27346,257 27350,260 27349,261 27352,266 27348,266 22348,269 22347,271 22347,272 22347,273 22348,273 22352,278 22348,279 22344,282 22345,282 22342,283 22347,283 22347,288 22349,292 22347,292 22348,293 22348,298 22348,303 22351,306 22352,309 22352,308 22354,310 22356,311 22361,311 22358,311 22360,311 22360,315 22356,320 22358,325 22363,326 22366,321 22371,318 22373,318 22375,314 22375,316 22375,321 22376,321 22376,322 22372,32 104,36 109,40 114,40 113,40 117,44 119,49 123,49 126,49 129,53 133,50 137,50 139,49 137,48 138,43 138,42 139,46 142,46 138,41 139,45 141,4045 5141,4045 5146,4042 5147,4043 10147,4041 10150,4042 10152,4045 10152,4041 10156,4041 10152,4041 10152,4046 10153,4049 10156,4046 10155,4051 10157,4055 10159,4055 10160,4056 10161,4055 10166,4054 10169,4054 10172,4054 15172,4051 15176,4047 15177,4049 15174,4047 15176,4047 15176,4046 15177,4046 15180,4043 15184,4043 15187,4038 15190,4040 15194,4040 15199,4045 15196,4047 15197,4050 15200,4050 15204,4050 15208,4047 15212,4047 15215,4049 15216,4046 15218,4042 15223,4042 15228,4042 15232,4047 15235,4050 15236,4050 15239,4051 15243,4053 15243,4050 17243,4052 17243,4052 18243,4057 18247,4061 18249,4064 18249,4067 20249,4067 20250,4067 20255,4066 20259,4066 20259,4067 20255,4069 20256,4071 20258,4072 20254,4067 20257,4067 20260,4069 20265,4065 20267,4069 20266,4070 20267,4071 20264,4074 20259,4070 20264,4073 20260,4074 20263,4077 20268,4082 20271,4084 20273,4084 20277,4081 18277,4085 18279,4086 18276,4087 18273,4087 18275,4092 18277,4093 18279,4093 18280,4095 18280,4091 18283,4092 18281,4094 18283,4090 18287,4094 18287,138 5257,138 5255,138 5258,-1862 5254,-1860 5256,-1856 5258,-1851 5255,-1850 5260,-1847 5260,-1847 5263,-1847 5258,-1850 5257,-1850 5259,-1851 5257,-1855 5258,-1853 5261,-1849 5261,-1849 5258,-1849 5259,-1845 5264,-1847 5264,-1850 5268,-1852 5266,-1853 5270,-1856 5265,-1852 5262,-1847 5263,-1842 5263,-1842 5260,-1842 5265,-1841 5265,-1844 5265,-1842 5270,-1837 5274,-1838 5279,-1843 5275,-1842 5280,-1838 5281,-1838 5285,-1833 5285,-1828 5288,-1824 5289,-1828 5291,-1831 5291,-1826 5291,-1830 5293,-1826 5296,-1822 5301,-1826 5302,-1826 5302,-1826 5302,-1825 5297,-1820 5299,-1816 5303,-1816 5299,-3811 12299,-3809 12302,-3806 12302,-3806 12302,-3803 12304,-3798 12304,-3797 12304,-3793 12306,-3788 12306,-3783 12309,-3816 12294,-3811 12299,-3809 12297,7100 -1851,7098 -1854,7102 -1854,7107 -1856,7107 -1858,7110 -1854,7110 -1851,7113 -1851,7115 -1851,7120 -1851,7123 -1847,7124 -1852,7125 -1852,7127 -1852,7131 -1852,7129 1148,7129 1145,7133 1150,7137 1148,7138 1147,7143 1149,7147 1154,8147 1155,8152 3155,8147 3157,8143 3158,8144 3160,8144 3164,11144 3167,11146 3167,11148 3163,11152 3161,11148 3159,11149 3163,11150 3161,11151 3166,11154 3171,11154 3170,8144 3160,8144 3163,8144 3166,8145 3166,8146 3171,8146 3174,8144 3174,8144 3174,8145 3176,8141 3180,3141 3182,7141 3183,7141 7183,7136 7185,7136 7185,7133 7187,7136 7187,7131 7190,7136 7194,7137 7197,7141 7196,7139 7199,12139 7200,12143 7200,12143 7199,12144 7203,12145 7200,12141 7200,12136 7195,12136 7191,12137 7191,12137 7196,12139 7197,12140 7197,12137 7201,12140 7204,12140 7209,12143 7209,12145 7210,12147 7214,12148 9214,12152 9218,12149 9218,12149 9221,12149 9220,12150 9222,12153 10222,12153 10226,12156 10227,12159 10223,12160 10220,12161 10225,12161 10227,12163 10224,12163 10223,12158 10224,12158 10227,12158 10231,12155 12231,12157 12226,7136 7185,7139 7189,7139 7189,7139 7188,7137 7191,7139 7191,7140 7189,7143 7191,7144 7189,7144 7190,7149 7193,7152 7194,7154 7198,7153 7203,7148 7207,12148 7209,12146 7209,12145 7213,12140 7217,12139 7219,12141 7219,12138 7218,12143 7218,13143 7220,13140 7224,13142 7228,13137 7231,13142 7235,13146 7239,13149 7243,13148 7247,13150 7248,13155 7249,13155 7253,13155 7253,13155 7258,13157 7260,13162 7255,13159 7255,13163 7258,13164 7258,13164 7263,13167 7264,13167 8264,13165 8265,13169 8265,13171 13265,13175 13261,13176 13259,13176 13259,13180 13262,13181 13262,13183 13262,13188 13265,13191 13267,13191 13265,13194 13267,13191 13269,13192 13264,13196 13269,13198 13272,13200 13272,13202 13270,13207 11270,13211 11270,13211 11273,13213 11274,13217 11275,13222 11276,13222 11272,13226 11274,13231 11277,13233 11282,13236 11284,13238 11284,13236 11286,13236 11288,13236 11283,13236 11284,13238 11289,13241 11292,13244 11292,13245 11289,13241 11294,13244 11298,13249 11301,320 22358,324 24358,328 24358,327 24363,326 24359,327 24361,329 24365,334 24367,-666 24367,-670 24368,49 123,46 127,46 129,49 131,49 136,47 135,45 138,3045 135,3042 138,3044 139,3044 144,3049 144,3053 142,3055 137,3058 136,3053 139,3048 142,7048 138,7048 3138,7048 3139,7048 3140,7050 3145,7053 1145,7050 1146,7053 5146,7048 5150,7047 5146,10047 5147,10043 5147,10047 5147,10050 5152,10052 5155,10054 5156,10056 5157,10056 5159,10058 5162,10062 5164,10062 5169,10066 9169,10068 9168,10063 9164,10063 9169,10061 9171,14061 9172,14061 9174,282 22342,287 22347,288 22347,288 22343,285 22339,280 22338,278 22341,279 25341,284 25343,13241 11294,13246 11296,13243 11296,13244 11291,13245 11291,13244 11291,13246 11295,13251 11300,13253 11305,13253 11306,13258 11305,13255 11306,13256 11309,13256 11311,13261 11307,13265 11303,13267 11305,13270 11301,13275 11298,13271 11300,15271 11302,15276 11306,15279 11303,15284 11305,15286 11305,15289 11307,15290 11302,15292 11305,15296 11309,15297 11313,15298 11316,15300 11317,15304 11320,15306 11324,15306 11320,15307 11320,15312 11320,15313 11319,15317 11317,15315 11321,15317 11323,15317 11328,15319 11333,15322 11336,15322 11337,15322 11337,15324 11341,15324 11345,15325 14345,15328 13345,17328 13346,17333 13349,17337 13354,17338 13358,17342 13358,17346 13353,17348 13353,17345 13353,17348 13354,17347 13354,17347 13354,17347 13355,22347 13358,22349 13355,22351 13355,22356 13354,22358 13354,22361 13355,22362 13355,22358 13355,22359 13359,22364 13364,22369 13369,22372 13373,22376 13371,22377 13371,22377 13369,22381 13374,22386 13379,22387 13376,22387 13380,22392 13378,22390 13374,22392 13378,22391 13378,22391 13375,22392 13378,22390 13380,22393 13382,22398 13387,22398 10387,22402 10391,22399 10392,22400 10392,22400 10394,22404 10391,22403 15391,22405 15392,22407 15392,22412 15387,22412 15390,22412 15394,22408 15396,26408 15398,26407 20398,26411 20402,26415 20406,26417 20411,26420 20407,26422 20407,31422 16407,31421 16405,31421 16410,31423 16410,31426 16414,31426 16410,31430 16415,31430 16418,31435 16419,31437 16420,31438 16422,31438 16425,31438 16425,31441 16427,31439 16431,31441 16436,36441 16436,36443 18436,36442 18437,36440 18440,36440 18436,36440 18440,36442 18445,36443 18446,36447 18451,37447 23451,37452 23456,37456 23455,37458 23459,37456 23461,37458 23463,37460 23466,37464 23469,37460 23474,37462 23476,37461 26476,37466 26479,37470 26483,37471 26488,37474 26489,37474 26485,37474 26483,37474 26488,37470 26492,37474 26497,37474 26499,37478 26495,37483 26499,37483 26501,37488 26496,37491 26499,37495 26495,37500 26496,37500 26497,37500 26501,37497 26499,37497 26499,37495 26504,37498 26504,37494 26509,37497 26514,37495 26515,37498 26514,37503 26514,37508 26512,37510 26516,37511 26519,37509 26523,37506 26528,37507 26532,37512 26536,37513 26538,37510 26542,37512 26544,37517 26543,37522 26546,37527 26551,37525 26555,37529 26558,37524 26563,37524 26562,37527 26562,37522 26562,37522 26559,37526 26561,37522 26559,37523 26561,37523 26556,37524 26558,40524 26560,40524 26563,40521 26567,40525 26566,40527 26568,40532 26572,40534 26569,40533 26565,40531 26565,40535 26569,40535 26570,40539 26572,40544 26575,40543 26575,40544 26579,40548 26584,40549 26581,40553 26585,40556 26590,40552 22590,40557 22594,40556 22595,40561 22592,40561 22593,40565 22593,40568 22593,40573 22588,40570 22590,40570 22591,40570 22588,40573 22590,40573 22593,40568 22593,40567 22597,40567 22599,40571 22599,40574 22600,40574 22604,42574 22607,42577 22607,42577 22612,42579 22616,38579 22619,38580 22617,38580 22614,38575 22619,38579 22619,38579 18619,38582 18614,38582 18617,38586 18622,38590 18625,38590 18622,38594 18621,38596 18616,38597 18614,38597 18618,38600 21618,38601 21618,38605 21620,38607 25620,38611 25620,38608 25617,38608 25621,38608 25625,38611 25623,38615 25623,38615 25620,38616 25622,38619 25624,38620 25625,38620 26625,38623 26627,38623 26627,311 22358,311 22359,-1689 22360,2311 27360,2312 27360,2312 27360,2317 27362,2317 27362,2319 27359,2319 27364,2318 27359,2321 27364,2326 27367,2325 27371,2326 27373,2326 27373,2325 27377,2329 27377,2327 27377,2330 27379,2333 27379,2331 27379,2331 27381,2336 27381,6336 27382,6336 27383,40527 26568,40531 26572,40533 26574,40538 26576,40533 26580,40538 26585,40539 26588,40536 26583,40540 26587,40539 26588,40535 26593,40540 26594,40544 26597,40548 26602,40548 26601,40549 26602,40547 26602,40548 26603,40553 26606,40548 26606,40548 26603,40551 26608,40556 26612,40559 26616,40554 26619,40556 26619,40556 26623,42556 26623,42556 26624,42560 26624,42562 26626,42563 26630,42564 26630,42564 26634,42559 26635,42562 26635,42565 26637,42562 26638,42564 26642,42564 26641,42568 26641,42572 26641,42572 29641,42574 29642,39574 29641,39574 34641,39576 34643,39581 34638,39578 34638,39574 34642,39574 34645,39572 35645,34572 35648,34577 35651,39577 35655,43577 35659,43580 35655,43575 35658,43578 35658,43581 35662,43577 39662,43572 39658,43572 39661,43572 39664,43572 39666,43576 39670,43577 39667,43580 39671,43576 39673,43573 39673,43574 39677,43569 39679,43567 39679,43568 39683,43563 39686,43566 39690,43566 39692,43568 39694,43568 39695,41568 39691,41570 39692,41571 39692,41571 39693,41571 39698,41571 39698,41574 39698,41569 39698,41570 39699,41570 39704,41572 39709,41573 39712,41578 39713,41579 39717,41584 39719,41585 39720,-1850 5268,-1845 5268,-1847 5266,-1842 5268,-1840 5263,-1845 5264,-1843 5264,-1839 8264,-1839 8267,-1839 8272,-1838 8276,-1834 8273,-1834 8273,-1833 8274,-1837 8279,-1836 8283,-1834 8286,-1836 8282,-1834 8279,-1835 8279,-1834 8280,-1836 8283,-1841 8288,-1846 8289,-1843 8286,-1838 8286,-1841 8285,-1838 8285,-1834 8288,-1829 8291,-1825 8286,-1825 8289,-1825 8287,-1824 8291,-1822 8294,-1821 8298,-1818 8300,-1818 8296,-1814 8296,-1811 8295,-1808 8292,1192 8296,1192 8297,1195 11297,1192 11301,1195 11305,1197 11300,1193 11300,1193 11296,1193 11293,1194 11294,1199 11292,1204 11292,1205 11294,1210 11292,1208 11288,1204 11290,1205 11289,1207 8289,1202 8284,1204 8282,1204 8281,1206 8281,1208 8281,1212 8283,1212 13283,1213 13287,1213 13290,1216 13293,1214 13289,1217 13286,1212 13291,1208 13288,1208 13292,1209 13297,1208 13296,1204 13298,1205 13303,1209 13308,1204 13308,1209 13304,1210 13304,1214 13309,1214 13314,1215 13314,1219 13314,1219 13319,1224 13320,1229 13321,1232 13325,1233 13329,1231 13329,1234 13334,-2766 13336,-2769 13337,-2765 13340,-2762 13345,-2760 13342,2240 13342,2238 13342,2242 13342,2246 13345,2246 13346,2244 13348,2239 13348,2240 13351,2240 13352,2245 13357,2248 13357,2243 13362,2247 13362,2248 13362,2252 13363,2256 13363,2256 13363,2260 13367,2255 13372,2251 13369,2251 13369,2252 13372,2249 13376,2254 13378,2255 13382,2259 13379,2262 13379,2267 13381,2262 13381,2262 13383,2265 13383,2269 13385,2270 13386,2271 13389,2267 13391,2271 13386,2275 13391,2273 13392,2275 13387,2277 13390,2274 13390,2275 13394,2280 13395,2280 11395,2281 14395,2279 14400,2277 14403,2273 14406,2274 16406,2274 16410,2279 16410,2284 16411,2280 16409,2280 16409,2282 16409,2282 16411,2282 16412,2280 16413,3280 16418,3284 16418,3285 16423,3289 16423,3292 16427,3294 16429,3296 16431,3297 16436,3298 16435,3303 16435,3305 16434,3305 16436,3305 16436,3309 16437,3309 16438,3308 16439,3308 16439,3306 16444,3302 16441,-1698 16437,-1703 16438,-1699 16438,-1697 16438,-1698 16439,-1695 16436,-1690 16441,-1687 16446,-1683 16450,-1682 16451,-1684 16453,-1682 16457,-1682 16457,-1686 16460,-1681 16459,-1680 16456,-1677 16460,-1681 16461,-1679 16464,-1674 16465,-1673 16469,-1669 16471,-1669 16476,-1665 16474,-1665 16478,-1664 16478,-1664 16479,-1661 16474,-1656 16471,-1655 11471,-1660 11473,-1663 11475,-1666 11480,3334 15480,3338 15476,3342 15471,3345 15471,3345 15470,3350 15469,3347 15474,3351 15476,3352 15473,3353 15476,3350 15477,3350 15479,3351 15482,3352 15484,3351 15487,3353 15487,3358 15487,3353 15486,1217 13286,1222 13291,1222 13291,1225 13286,1229 13286,1231 13281,1235 13280,1236 13281,1241 13282,1245 13285,1247 13285,1247 13287,1250 13287,1247 13290,1247 13295,1247 13298,1252 13301,1249 13304,1252 13304,3252 13304,3247 13304,3249 13308,3254 13308,3257 13308,3261 17308,3261 17309,3261 17306,3259 17305,3262 17310,3263 17308,3262 17311,3259 17314,3259 17314,3257 17309,3254 17309,3253 17309,3255 17310,3253 17312,3255 17312,3255 17312,3256 17307,3257 17307,3256 17311,3256 17313,3255 17317,3251 17317,3248 17321,3253 17325,3256 17326,3258 17324,3258 17327,3263 17322,7263 17325,7265 17328,7263 17330,7265 17333,7270 17333,7273 17333,7278 17336,4278 21336,4278 21340,4279 21340,4281 21340,4286 24340,4290 24343,9290 24347,9294 24349,9296 24347,9298 25347,9301 25348,9301 25348,9304 25353,9303 25357,9303 25352,11303 25355,11304 25358,11307 25358,11312 25358,11312 25361,11310 25365,11313 25365,11314 25369,11319 25371,11321 25371,11325 25366,11329 25365,11330 25366,11329 25370,11330 25365,11334 25367,11338 25366,11343 25363,11348 25359,11345 25356,11348 25357,11349 25358,11349 25358,11352 25360,11356 30360,11360 30365,11360 30365,11362 30365,11367 30367,11368 30369,15368 30370,15373 30371,15376 30373,14376 30378,14377 30383,14381 30378,14386 30380,14388 30382,14391 30385,14393 31385,16393 31389,16396 31394,16396 31397,16392 31400,16395 31405,16398 31409,16398 31413,16397 31415,16396 31417,16401 31418,16401 31422,16402 31419,16407 31420,16411 31419,16406 31423,18406 31427,18411 31432,18415 28432,18417 28437,18418 28441,18414 28438,18417 28435,18416 28439,18420 28442,18423 28447,18427 28444,21427 28445,21428 28450,22428 28455,22432 28457,22436 28458,22441 28458,22445 28463,22448 28468,22451 28465,22456 28468,22453 28468,22458 28471,22463 28473,22460 28475,22459 28472,22463 28476,22464 28472,22468 28468,22468 28471,25468 28466,25471 28468,25473 28464,25473 28464,25475 29464,25476 29466,25479 29461,25476 29462,25476 29464,25478 29464,25483 29461,25484 29460,25486 29458,25486 29462,25490 29460,25495 26460,25498 26463,25495 26468,25495 26472,25495 26472,25499 26474,25504 26476,25504 26478,25509 26476,25513 26479,25514 26481,25519 26477,25519 26480,25518 26481,25519 26484,25524 26483,25527 26484,25522 26484,25526 26487,25528 26492,25533 26496,25535 26498,25535 26498,25539 26503,25542 26504,25543 26505,25547 26510,25552 26510,25551 26508,25550 26512,25553 26510,25557 26510,25554 26511,25552 26508,25556 26505,25556 26506,25560 26506,25560 26507,25560 26506,25565 26501,25567 26504,25569 26504,25568 26508,25571 26508,25571 26511,25576 26511,25581 26516,25581 26519,25582 26521,25585 26522,25588 26527,25588 26526,25584 26530,25587 26534,25589 26529,25593 26533,25598 26538,25599 26540,25599 26540,25599 26540,25604 26543,25603 26543,25603 26538,25606 26538,25609 26540,25611 26542,25612 26547,25612 26547,25612 26548,25617 25548,25612 25548,25613 25547,25616 25545,25616 25549,25618 25551,25620 25555,25620 25551,25622 25550,25625 25551,25622 25555,25619 25557,25617 25556,25622 28556,25625 28551,25630 28546,25634 28548,25639 28553,25643 28553,25638 25553,25634 25553,25634 25557,25639 25557,25643 25558,25644 25553,25646 25556,25647 25560,25650 25562,25650 30562,25650 30562,25650 30564,25650 30566,25652 30570,25656 30571,25661 31571,25662 31575,25663 31579,25662 31579,25665 31581,25666 31584,25671 31582,25674 31581,25674 31584,25676 31584,25673 31587,25678 31586,25679 31581,30679 31584,30675 31589,30680 31590,35680 31590,35675 31589,35677 31591,35680 31590,35681 31587,35684 31588,35685 31589,35689 31592,35689 31593,35692 31597,35696 31597,35700 34597,35699 34599,35703 34604,35703 34606,35702 34601,35705 34603,35705 34606,35708 34603,35713 34604,35717 34603,35719 34608,35715 34608,35711 34608,35713 34609,35714 34605,35714 34610,35714 34614,35718 34616,35719 34617,35722 34618,35722 34621,35725 34625,35725 34626,35725 34629,35725 34631,35725 34635,35730 34636,35727 34638,35731 34640,35735 34642,35739 34645,35741 34645,35742 34649,35738 34649,35738 34645,35741 34647,38741 34650,38741 37650,38742 37646,38746 37651,38749 37652,38753 37653,38753 37657,38757 37656,38756 37660,38761 37660,38765 37660,38760 37660,38759 37660,38760 41660,38760 41660,38762 41665,38757 41667,43757 41669,43752 41674,43752 41677,43757 41672,43758 41677,45758 41680,45758 41679,45762 41683,45765 41683,45769 41683,45770 41684,45768 46684,45773 46688,45776 46692,45774 46694,45775 46697,45778 46695,45776 46698,45774 46702,45779 46702,45784 46704,45787 46706,45791 46711,45786 46707,45790 46711,45793 46715,45796 46719,45799 46724,45797 46728,45802 46726,45797 46729,45801 46733,45802 46733,45803 46732,45804 46732,45805 46732,45808 46735,45810 46740,45810 46744,2326 27373,2322 27377,2323 27379,2325 27383,2325 27382,2322 27382,2323 27382,5323 23382,5325 23385,5329 23386,5330 23390,5335 23392,5330 23392,5330 23395,5329 23395,5333 23399,5333 23402,5338 23405,5339 23405,5334 23406,5329 23401,5332 23403,5330 23407,5333 23409,5328 20409,5324 20411,5324 20414,5329 20416,5328 20421,5325 20421,5329 20424,5330 20424,5335 21424,5331 21427,5333 21431,5334 21433,5329 21434,5330 21437,5333 21440,5338 21437,5338 21440,5334 21441,5333 21438,5329 26438,5332 26435,5335 26439,5337 26440,5338 26444,5342 26439,5342 26442,5345 26440,5349 26438,5352 26442,5349 26445,5348 30445,5350 30447,5350 30444,5354 30444,5359 30443,5363 30445,5367 30446,5367 30448,5367 30453,5371 30455,5371 30453,5373 30458,5375 30461,5380 30463,5384 30463,5383 30459,5384 30459,5383 30459,5385 30460,5390 30459,5392 30464,5394 30464,5389 30465,5393 30469,5391 30469,5391 30469,5395 30474,5396 30470,5399 30470,5401 30467,5401 30468,5404 30470,5400 30465,5401 30462,5403 30467,5404 30467,5409 30469,5412 30473,5412 30477,5407 30481,8407 30486,8408 30489,8410 30490,8410 30489,8413 30490,8414 30493,8414 30496,8419 30501,8420 30502,8415 30507,13415 30509,13411 30506,13414 30507,13412 30511,13412 30515,13417 30518,13419 30523,13418 30527,13422 30529,13418 30531,13413 35531,13409 35531,13413 35532,13417 35537,13419 35533,13423 35529,13424 35529,13423 35524,13428 35525,13433 35526,13438 35530,13443 35531,13448 35531,13452 35532,13455 35536,13457 35536,13452 35536,13455 35539,13452 35535,13457 35540,13457 35544,18457 35546,18460 35547,22460 35546,22465 35550,22466 35554,22468 35552,22473 35555,22471 35559,22470 35564,22472 35564,22470 35569,22474 35569,22474 35571,22477 35573,22482 35576,22487 35580,22488 35583,22489 35585,22493 35585,22496 35585,25496 35586,25493 35582,25494 35585,25498 35585,25496 35585,25498 35587,25503 35591,25503 35593,25499 35590,25499 35591,25495 35591,26495 35595,29495 35591,29495 35593,29498 35597,29498 35601,29500 35606,29501 30606,29502 30603,29505 30603,29510 30606,29511 30606,29514 30607,29516 30610,29518 30608,3259 17305,3263 17304,3267 17303,3271 17308,3269 17312,3269 17313,3274 17315,3277 17315,3282 17311,3285 17313,3283 17309,3278 17310,3275 17315,3275 17317,3276 17322,3280 17324,3280 17324,3276 17325,3277 17325,3276 17328,3278 17324,3273 17329,3277 17331,3280 17326,3281 17328,3276 17324,3277 17324,3277 17322,3277 17321,3277 17321,3281 17323,3282 17327,3282 17332,3287 17335,3288 17335,3288 17338,3290 17337,3294 17340,3294 17341,3299 17341,3299 12341,3299 12342,3304 12339,3301 14339,3305 14340,3307 14341,3311 14343,3313 14343,3314 16343,3310 16341,3310 16346,3312 16348,3311 16349,4311 16346,4316 16348,4321 16344,4324 16348,4322 16349,4323 16346,4323 16346,4326 16350,4322 16354,4323 16356,4325 16361,4325 16358,4322 16362,4325 20362,4325 20366,4322 20367,4326 20372,4326 20374,4331 20373,4333 20373,4338 20376,4339 20379,4341 20382,4338 20384,4339 20386,4340 20383,4340 20383,4335 20388,4336 20390,4341 20390,4346 20391,4348 20391,4349 20393,37497 26499,37494 26496,37496 26500,37496 26501,37499 26506,37497 26502,37498 26502,37500 29502,37500 29507,37505 29508,37506 33508,37508 33513,37513 33518,37517 33522,37516 33520,37521 33521,37521 33525,37516 33530,37519 33528,37520 33528,37524 33530,37527 33530,37525 33527,37528 33530,37533 33533,37534 38533,37536 38536,22358 13355,25358 13360,25361 13358,25362 13362,25362 13362,25365 13365,25363 13367,25359 13369,25357 13374,25360 13374,2247 13362,2252 13366,2254 13363,2257 13363,2261 13358,2264 13354,2264 13356,2269 13361,2272 13363,2274 13363,2275 13363,2273 13362,2274 13365,2278 13365,2280 13370,2284 13366,2284 13365,2289 13368,2290 13366,2293 13368,2298 13373,2298 13372,2295 13375,271 22347,273 22350,4273 22347,4269 22348,4270 22350,4271 22355,4272 22360,4276 22363,4281 22365,4284 24365,4279 24365,4282 24365,4285 24365,4287 24364,4289 24362,4294 24360,4295 24362,4298 24365,4301 24369,1301 24370,1301 24371,1305 24375,1305 24376,1307 24377,1312 24380,1314 24382,1318 24380,1316 24382,1316 24387,1318 24387,1318 29387,1321 29387,1316 29383,1320 29386,1321 29389,1326 29389,1327 29389,2327 29394,2327 29394,2332 29393,-666 24367,-663 24368,-661 24368,-656 24371,-653 24372,-649 24372,-647 24374,-643 24370,-638 24375,-635 24380,-638 24382,-638 24384,-638 24384,-636 24388,-637 24390,-632 24386,-630 24386,-629 24386,371 24389,376 24394,374 24392,377 24397,3377 24400,6377 24405,6378 24408,6373 24406,6370 24406,6375 24403,6370 24403,6375 24403,6379 24406,6374 24409,6378 24411,6380 24412,6378 24415,6378 24419,6383 24423,6385 24425,6387 24428,6390 24433,6386 24430,6386 24435,6387 24436,6388 24440,6387 24444,6383 29444,6383 29447,6386 29451,6382 29446,6387 29447,6390 29452,6393 29452,6397 29455,6400 29459,6400 29463,6397 29467,6393 29467,6395 29470,6397 29473,6399 29468,6394 29467,6397 29470,6396 29473,6396 29470,6393 29465,6389 29469,6390 29470,6389 29465,6389 29468,6392 29470,6388 33470,6390 33466,6391 33466,6392 33467,6394 33467,322 22372,322 22374,323 22377,327 22378,331 22382,330 22383,332 22386,333 22383,331 22383,330 22387,332 22391,332 22396,337 22397,339 22394,340 22399,340 22398,340 22396,343 22396,343 22396,341 22400,342 22404,343 22402,348 22403,345 22407,347 22411,342 22411,345 22413,340 22417,345 22417,348 22422,348 22426,351 22427,352 22432,352 22436,4352 22438,4353 22442,4354 22444,4354 22447,4357 22449,4360 22450,4364 22450,4367 22451,4369 22453,4366 22455,4369 22453,4373 22458,4377 22459,4380 22459,4380 22464,4385 22467,4385 22467,4390 22469,4385 22469,4385 22472,25571 26508,25574 26507,25578 26512,25581 26512,25581 26512,25583 26508,25583 26513,25587 26516,25589 26515,25590 26515,25591 26517,25589 26520,25587 26522,23587 26526,23585 26531,23589 26534,23592 26538,24592 26543,24588 26545,24593 26547,24598 26543,24598 26548,24602 26545,24598 26540,24600 26545,24600 26548,24600 31548,24605 31549,24608 31551,24613 31552,24615 36552,24616 36557,24619 36557,24622 36560,24622 36564,24627 35564,24627 35569,24632 35569,25632 35570,25635 35569,25636 35573,25636 35573,25638 35576,25641 35580,25641 35583,25641 35588,25642 40588,20642 40593,20645 40593,20650 40595,20651 40591,20651 40594,20648 40591,20648 40591,20652 40596,20652 40596,20656 40597,20656 40600,20656 40601,20659 40598,20662 40597,20662 40597,20663 40600,20668 40601,20665 40606,1215 13314,1214 13319,1212 13317,1209 13312,1210 13312,1211 13317,6211 13320,6214 13320,6216 13320,6211 13323,6214 13318,6214 13323,6214 13324,6216 13319,6219 13323,6218 13321,6219 13321,6218 13326,6221 13329,6225 13331,6230 13335,6231 13339,6231 13343,6235 13338,6234 13342,6234 13344,6236 13345,25524 26483,25521 26484,25524 26489,25527 26487,25529 26484,25530 26482,25534 27482,25539 27486,25537 27488,25541 27483,25544 27486,25547 27490,25550 27491,25550 27491,25554 27486,25559 27486,25563 27489,25561 27489,25563 27493,25561 27491,25563 27493,25563 27495,25564 27497,25563 27497,25563 27497,25558 27498,25563 27499,25565 27503,25567 27503,25569 27503,25567 27504,25565 27505,25565 27505,25565 27505,25566 27505,25570 27501,25570 27497,25574 27498,25570 32498,25570 32501,25573 32501,25576 32497,25576 32498,25577 32501,25579 32503,25583 32504,25588 32507,25592 32512,25596 32507,25599 32507,25594 32503,25597 32506,25597 32510,25594 32509,25594 32510,25596 32513,25592 32513,25594 32515,25594 32520,25598 32520,25602 32517,25603 32518,27603 32520,27607 32523,27608 31523,27613 31527,27615 31527,30615 31530,30617 31530,30618 31532,30619 31536,30623 31537,30623 31538,30625 31538,30626 31541,30627 31541,30624 31540,30623 31540,30624 31545,34624 31546,34619 31543,34623 31545,34624 31549,34624 31548,34626 31550,34626 31555,34626 31551,34628 31555,34633 31555,34636 31559,34634 31564,34636 31564,34639 31562,34639 31560,36639 31555,36636 27555,41636 27557,41640 27554,41644 27558,41647 27559,41648 27555,41653 27555,41658 27555,41658 27552,41658 27552,41660 27550,41656 27554,41661 27558,41664 27561,41667 27566,41662 27562,41663 27563,41663 27565,41662 27569,41661 27569,41664 27571,41664 27567,41659 30567,41660 30565,41660 30561,41665 30566,41664 30561,41664 30561,41664 30562,41664 30563,41660 30558,1312 24380,4312 25380,4315 25384,4315 25385,4319 25383,4322 25388,6322 25387,6322 25387,6326 25392,6321 25397,6324 25397,6324 25401,6319 25404,9319 25405,9314 25400,9312 25402,9310 25403,9313 25403,9313 25403,9316 25400,9319 25401,4319 25396,8319 25398,8315 25400,8315 25396,8315 25397,8311 25398,8307 25394,8309 25394,8311 25397,8315 25402,8310 25403,11310 25365,11311 25365,11316 25370,11320 25375,11325 25375,11325 25380,11325 25382,11326 25378,14326 25380,14328 25382,14331 25383,14334 25385,14336 25386,19336 25386,19336 25389,19332 25390,19332 25391,19335 25388,19338 25391,19342 25393,19340 25393,19345 25396,19345 25394,19347 25394,19349 25393,19351 25397,19350 25398,19348 25399,19349 25403,19352 25399,19350 25402,19354 25400,19353 25405,23353 25402,23354 25402,23356 25405,23358 25409,23360 25413,23363 25414,23367 25412,23365 25411,23367 25414,23363 25413,23367 25416,23367 25416,23370 25418,24370 25414,24370 25419,24373 27419,24378 27419,24380 27416,24380 27412,24380 27410,24380 27406,24376 27406,24374 27410,24370 27414,24370 27415,24371 27420,24375 27415,24378 27411,24375 27415,24378 27418,24382 27421,24383 27426,24383 27425,24385 27430,24390 27431,24394 27432,24395 27436,24399 30436,24400 30439,24404 30443,24403 30439,24406 30438,24410 30442,24406 30446,24408 30445,24403 30445,24408 30442,24412 30446,24416 30446,24416 30449,19416 30449,19416 30447,19418 30452,19420 30453,19423 30458,15423 30462,15423 30464,15425 30466,16425 30467,16424 30471,16421 30474,16426 30474,16428 30476,16428 30476,16424 30474,16424 33474,16425 33474,16427 33477,16425 33479,16426 33477,16422 33480,16425 33482,16430 33479,16430 33478,16429 33482,16424 33482,16427 33484,16430 33488,16431 33488,16434 33488,16435 33491,16432 33487,16436 37487,16434 37490,16438 37485,16443 37482,16446 37480,16447 37480,16447 37482,16451 37478,16454 37479,16458 37479,16454 37479,16454 37482,16459 37486,16460 37491,16463 37495,16464 37492,16465 37493,16466 37494,16468 37497,16468 37501,16468 37501,16473 37503,16473 37503,16473 37498,16476 37494,21476 33494,21473 33493,21476 33489,21478 33491,21478 33496,21478 33492,21480 33496,21483 33501,21484 33504,21483 33500,21484 33505,21484 33505,21488 35505,21491 35505,21494 35506,21496 35510,21492 35506,21492 35509,21489 35514,21490 35517,21487 35519,23487 35523,23485 35528,23487 35533,23483 35534,23487 35535,23488 35537,23493 35539,23495 35542,23495 35546,23495 35550,23491 35549,23488 35552,23492 35555,23495 35560,23500 35559,23496 35557,4322 16354,4317 16358,4318 16358,4320 16363,4315 16363,4315 16362,4316 20362,4320 20365,4323 20363,4326 20366,4329 20367,4332 20370,4337 20374,4338 20375,4333 20375,4338 20375,4341 20377,4342 20377,4342 20378,4343 20381,4346 20386,4346 20386,4346 20386,4346 20386,4349 20390,4352 20395,4354 20396,4355 20400,4358 20400,4360 20401,4360 20404,4363 20405,4368 20406,4372 20411,4371 20416,4367 20417,4364 20422,4367 20420,4372 20425,4373 20422,4374 20418,4377 20418,4381 20422,4382 20423,4384 20418,4389 20421,4385 20423,4390 20423,4390 20425,4392 20429,4396 20434,41574 39698,41578 39702,41576 39704,45576 39704,45575 39709,45577 39713,45581 39715,45581 39718,45583 39721,45578 39726,47578 39722,47581 39719,47586 39722,47586 39726,47589 39730,47592 39733,47597 39733,47593 39733,47596 39735,47597 39735,47595 39735,47591 39739,47593 39744,47593 39747,4074 20263,4077 20268,4079 20268,4078 20271,4078 22271,4083 22276,4087 22272,4088 22275,4086 22279,4082 22280,4084 22282,4086 22277,4082 22277,4087 22281,4090 22281,4092 22281,4092 22286,4094 22287,4097 22290,4097 22291,4095 22286,4095 22288,4095 22293,4095 22288,4092 22285,4089 22286,4090 22286,4095 22281,4100 22286,4103 22285,4104 22288,4104 22289,4107 22294,4112 22292,4117 22290,4120 22295,120 22300,121 22303,122 22300,122 22300,121 26300,125 26303,129 26303,127 26305,127 26306,132 26306,132 26307,136 26307,141 26309,140 26311,143 26313,140 26314,145 26318,149 26318,153 26321,153 29321,158 29326,158 29329,162 29324,162 34324,165 34329,168 34328,167 34332,169 34333,173 34334,173 34336,177 34338,178 34340,178 34344,182 34348,177 34348,182 34348,184 34353,184 34358,181 34360,183 34365,187 34365,192 34365,197 34367,199 34366,203 34368,205 34368,202 34363,204 34360,1204 34360,1205 34364,1205 30364,1205 30359,1206 30361,1207 30364,1210 30366,1210 30366,1214 30367,1218 30372,1219 30375,1214 30379,1214 30384,1217 30382,1222 30383,1223 30382,1225 30380,1228 30379,1231 30383,1232 30383,1235 30384,1237 30388,1242 30386,1244 30389,2244 30392,2241 30395,2245 30397,2245 30399,2244 30394,2242 30395,2246 32395,2246 32395,2249 32398,2251 32393,5251 32390,5251 32395,5255 32399,5255 32397,5257 32397,5257 32401,5261 32406,5261 32411,5266 32412,5271 32416,5273 32419,5276 32420,5281 32422,5279 32425,6279 33425,6284 33429,6284 33430,6282 33431,6282 33428,6286 33425,6288 32425,6288 32421,6286 32424,6288 32424,11288 32427,11292 32425,11292 32429,11290 32434,11286 32437,11286 32437,11283 32442,11278 32442,11279 32443,11283 32445,11284 32445,11283 32448,13283 32447,13287 32442,16287 32446,16282 32445,16283 32445,16284 32448,16285 32448,16284 32446,16286 32443,16290 32446,16291 32446,16292 32450,16291 32450,16291 32450,16291 32445,16287 32447,16288 32452,16287 32457,16291 36457,16289 36462,16293 36462,16294 36462,16297 36462,16301 36464,16306 36469,16310 36467,16310 36463,16313 36459,16312 36460,16313 36465,16313 36469,16308 36470,16309 36468,16314 36470,16319 41470,16322 41471,16325 44471,16330 44471,16330 44471,16330 44473,16330 44474,16335 44479,16332 44477,8414 30496,8415 30497,8419 30497,8414 30501,8416 30500,8418 30495,8421 35495,8423 35494,8427 35497,8429 35499,8432 35499,8436 35503,8438 35503,8443 35505,8440 35508,8443 35509,8440 35509,8440 35511,8441 35515,8445 35511,8448 35512,8443 35517,8443 35519,8442 35524,8444 35526,8441 35527,8436 35527,8433 35523,8429 35527,8430 35530,8431 35532,8429 35533,8433 35535,8437 32535,8435 32536,8439 32536,8436 32539,9436 32542,9434 32537,9429 32534,9429 32534,9433 32537,9433 32542,9429 32543,9434 32538,9436 32538,9436 34538,7436 34538,7438 34543,7439 34543,7439 34543,7439 34548,7438 34549,7438 34552,7438 34553,7438 34556,11438 34561,11434 34559,11436 34555,7436 34553,7436 34549,120 1235,124 1239,125 1236,125 1238,129 1235,128 1235,125 1236,123 1239,128 2239,132 2242,131 2242,135 2242,140 2242,145 2247,146 2252,144 2253,146 2248,144 2245,146 2244,150 2249,155 2245,159 2242,160 2243,160 2245,155 2244,156 2245,3156 2246,3159 2248,3159 2250,3164 2254,3165 2257,3166 2255,3169 2257,3171 2262,3169 2263,3174 2268,3177 2273,3174 2276,3178 2275,3173 2279,3177 2276,3180 2279,3182 2284,3185 2289,5185 2286,5185 2288,5181 2286,5185 2288,5184 2293,5187 2293,5187 2297,5190 2299,5187 2299,5185 2300,5181 6300,5182 6297,5187 6300,5189 6298,5191 6296,5193 6296,5193 6296,5195 6297,5195 6300,5197 6297,5195 6300,5190 6302,5191 6306,5192 6308,5195 6312,24395 27436,24391 27437,24393 27433,24398 27436,24398 27437,16286 32443,21286 32443,21286 32444,21282 32448,21283 32446,21283 32448,21285 32451,21281 32456,21282 32458,21282 32463,21282 32468,21284 32470,21289 32471,21287 32471,21287 32469,21287 32474,21284 32477,21288 32482,21291 32482,21291 32486,21296 32485,21299 32486,21301 32487,21303 32484,21301 32482,21305 32487,21310 32491,21312 32495,21313 32491,21315 32495,21312 32495,21314 32498,21316 32501,21311 32506,21311 32508,21312 32513,21317 32516,21319 32516,21324 32516,21327 32521,21328 32526,21332 32527,21328 36527,21331 41527,21336 41527,21334 41531,21337 41533,21335 41535,21339 41540,21340 41540,21343 41536,25343 41539,25340 41542,25337 41542,25337 41545,25335 41542,25335 41543,25335 46543,25339 46548,30339 46551,30340 46556,30343 46557,30342 46553,30337 46556,30341 46561,30337 46565,30336 46563,30338 46564,24373 27419,24373 27421,24375 27424,24377 27425,24377 27430,24374 27435,24379 27437,24384 27432,24385 27434,24382 27437,24381 27442,24381 31442,24381 33442,20381 33439,20383 34439,20382 34440,20378 34444,20381 34446,20381 34442,20384 34443,20388 34446,20392 34447,20393 34442,20393 34447,20396 29447,20395 29443,20399 29443,20400 29439,20399 29436,20404 29439,20409 29440,20410 29440,20410 29444,20408 29445,20413 29448,20413 29451,20412 29455,20413 29458,20418 29461,20413 29463,20415 29464,20416 29464,20416 29463,20416 29463,20418 29464,20414 29465,20418 29463,20413 29460,20413 26460,20418 26458,20421 26459,20421 26461,20421 26460,43578 35658,43578 35654,43578 35658,43578 35660,43583 35661,43583 35659,43583 35662,43579 35663,43583 35661,43587 35666,25625 25551,25629 25551,25630 25554,25630 25559,25632 25560,25627 25561,25623 25557,25623 25559,25624 25561,26624 25566,26627 25566,29627 25571,29626 25574,29625 25575,29622 25579,29625 25583,29630 25588,29632 25589,29635 25591,29635 25594,29637 25598,29642 25596,29643 25597,29644 25597,29649 25598,29654 25602,29656 25602,29661 25603,29661 25601,29664 26601,29666 26604,29665 26604,29668 26607,29672 26607,29669 26611,29671 26616,29674 26613,29679 26616,29680 26616,29681 26615,29682 26619,29679 26617,29684 26622,29686 26624,29689 26624,29690 26628,29691 26630,29693 26625,29694 26620,29698 26617,29703 29617,29707 29616,29706 29620,29709 29623,34709 29626,34710 29628,34710 29627,2282 16411,2283 16412,2283 16412,2287 16417,2292 16421,2297 16421,2298 16426,2303 16426,2304 16429,2309 11429,2313 11432,2308 14432,2308 14431,2311 14433,2310 14437,2308 14438,2309 14440,2311 14440,2309 14443,2312 14443,2314 14447,2314 14452,2314 14450,2309 14451,2309 14451,2309 14456,2313 14461,2313 14461,2309 19461,2309 19461,2311 19462,2315 19465,2318 19465,2321 19462,2317 19464,2321 19467,2322 19467,2322 19469,2322 19469,2320 19464,2321 19462,2322 19461,2327 19466,2327 19461,2322 19461,2322 19463,2317 19467,2318 19471,2102 -1848,2107 -1848,2111 -1846,2114 1154,2114 1156,2115 1157,2114 6157,2116 6162,2121 6165,2124 6170,2121 6175,2124 6179,2124 6183,2128 6178,2126 6179,2125 6178,2126 6181,2122 10181,2127 10186,2128 10189,2130 10188,2130 10191,2127 11191,2127 11195,2131 11196,2132 11192,2131 11197,2135 11201,2135 11203,2139 11199,2142 11203,2143 11204,2147 11208,2142 11210,2142 11211,2147 11212,2150 11217,2150 11219,2151 11219,2152 11222,2152 11222,2148 11224,2150 11220,2150 11223,2146 11218,2143 11219,2140 11221,2143 11218,2140 11219,2140 11223,2145 11225,2147 11226,2152 11226,2155 11224,2157 11229,2157 11229,2153 11233,2153 11238,2149 11239,7149 10239,7154 10241,7157 10241,7162 10243,7164 10248,7164 10251,7169 10253,7171 10253,7172 10257,7177 10260,7182 10256,7187 10260,7191 8260,7195 8256,7200 8258,7204 8258,7203 8261,7203 8262,7205 8266,7209 8270,7209 8273,7214 8273,7214 8276,7210 8276,7211 8276,7213 8279,7218 8278,7222 8283,7223 8279,7220 10279,7221 10283,7223 10284,7228 10286,7230 10290,7231 10290,7231 10293,7232 10294,7232 10297,7234 10299,7229 10295,7226 10294,7221 10293,7223 10295,7228 10299,7229 10303,7232 10307,7232 10311,7233 10316,7234 9316,7239 9318,7244 9321,7241 9326,7241 9328,7238 9331,7235 9330,7237 9335,7236 9335,7236 9337,7236 9338,7231 14338,7230 14333,7232 14338,7237 18338,4082 22280,4081 22280,6081 22283,6076 22285,6076 22289,6078 22286,6080 22287,6084 22292,6084 22293,6085 22293,6086 22291,6091 22294,6092 22293,9092 22290,9095 22294,9096 22295,9096 22297,9091 22292,9096 22295,9098 22290,9094 18290,9097 18290,9096 18294,9099 18292,9098 18297,9103 18299,9103 18302,9103 18305,9100 18301,9102 18302,9106 18305,9102 18310,9101 18306,9103 18308,9103 18312,9107 18310,9107 18315,9107 18320,9111 18322,9111 18326,9113 18329,9111 18329,9116 18329,9121 18329,9121 18332,9123 18331,9124 18332,9125 18328,9127 18325,9125 18328,9128 18329,9133 18329,9136 18333,9141 18337,9142 18342,9143 18340,9148 18344,9152 18341,9150 18346,9149 18341,9149 18341,9154 18343,9158 18345,9161 18346,9161 18347,9163 18352,9164 18352,9162 18349,9165 18352,9165 18351,9165 18352,9165 18356,9163 18352,9167 18353,9167 18349,9168 18351,9168 18347,9173 18347,9175 18347,9179 18348,9182 18349,9187 18352,9186 18357,9189 18360,9192 18360,9196 18362,13196 18367,13196 18369,13196 18371,13199 18374,13194 18374,13197 18375,13200 18377,13205 18380,13210 18384,13209 18379,13209 18374,13213 18375,13216 20375,13212 20375,13215 20375,13211 20375,13211 20372,13208 20373,13204 20373,13204 20369,13205 20369,13207 20366,13212 20367,13216 20367,13221 20372,13222 20377,13225 20381,13226 20386,13230 20383,9230 20388,9228 20384,9228 20386,9223 20389,9223 20392,4223 20397,4223 20396,4225 20399,4222 20404,4220 20408,4220 20411,4223 20416,4227 20421,4230 20418,4234 20421,4232 20422,4236 20423,4238 20423,4239 20423,4235 20427,4231 20427,4230 20426,4228 20428,4232 20427,4232 20431,4236 20433,4241 20431,4241 22431,4236 22436,4239 22437,4239 22439,4236 22443,4232 22439,4236 22444,4236 22446,4239 22447,4239 22452,4241 22454,4245 22457,4245 22460,4250 22462,4251 22465,4253 22465,4249 22465,4251 22460,4251 22464,4255 22469,4257 22473,4256 22478,4259 22479,4260 22480,4257 22485,6257 22489,6260 22490,6260 22493,6262 22496,6262 22500,6267 22495,6271 22495,6276 22491,6276 22489,6281 22487,6286 22490,6289 22490,6294 22490,6294 22489,6292 22485,6292 22489,6288 22489,6288 22494,6288 22496,6286 22497,6288 22501,6292 22500,5292 22503,5292 22503,5296 22508,5295 22510,5300 22510,5305 22513,5302 22514,5306 22510,5309 22513,5313 27513,5313 27513,5317 27513,5322 22513,5326 22517,6326 22516,6323 22518,6323 22523,6320 22523,6321 22526,6323 22531,6323 22531,6324 22532,6324 22532,6325 22529,6321 22531,6323 22534,6328 22534,6329 22530,6324 22527,10324 22522,10319 22524,10315 22520,10314 22525,10311 22525,10307 22526,10304 22531,10306 22527,10306 22528,10309 22530,10312 27530,10312 27534,10312 27534,10307 27536,10307 27532,11307 27531,11307 27533,11308 27535,11303 27531,11298 27532,11294 27534,11294 27534,11299 27538,11297 27542,11302 27547,11306 27547,11311 27549,11313 30549,11317 30551,11313 30546,11316 30541,11316 30540,11319 30545,11318 30546,11323 30550,11326 30554,11326 34554,11330 34558,11331 34558,11333 34558,11332 34561,11328 34561,11331 34562,11336 34562,11336 34567,11340 34570,11342 34569,11345 34568,11344 34569,11345 34571,11349 34574,15349 34574,15354 34569,15359 34566,15362 34571,15363 34576,15367 34577,15368 34577,15371 34581,15374 34576,15379 34574,15383 34579,15384 34584,15387 34583,17387 34578,17392 34578,17391 34578,17396 34573,17397 34578,17397 34580,17397 39580,17402 39584,17397 39587,17402 39587,17406 39582,17403 39587,17407 39589,17409 39592,17406 39592,17409 39595,17409 39599,17412 39603,17416 39608,17417 39608,17417 39608,17421 39607,17422 39609,17424 39608,17427 39604,17425 39605,17426 39609,17423 39611,17422 39610,17425 39613,17428 39618,17428 39619,17429 39616,17432 39616,13432 39615,13432 39617,13432 39617,13432 44617,13434 44621,13434 44623,13439 44627,13442 44632,13442 44635,13440 44631,13442 44631,13445 44635,13447 44639,13445 44637,13445 44638,13450 44639,13454 44644,13457 44644,13459 44642,15459 44639,15457 44644,15461 44644,15462 44642,15459 44645,15459 44647,15463 44650,15458 44651,15459 44653,15461 44657,15463 44661,15463 44661,15463 44663,15467 44666,15472 44668,15474 44664,15470 44668,15471 44670,15473 44674,15475 44675,-3806 12298,-3804 12301,-3805 13301,-3804 13296,-3808 13292,-3809 13295,-3806 13300,-3804 13297,-3801 13301,-3801 13302,-3796 18302,-3801 18306,-3799 18311,-3802 18311,-3799 18312,-3801 18314,-3796 18319,-3795 18322,-3791 18321,-3786 18320,-3786 18321,-3784 18321,-3782 18321,-3781 18324,-3782 18325,-3783 18320,-3788 18324,-1788 18324,-1788 18329,-1784 18333,-1784 18334,-1781 18329,-1777 18334,-6777 18337,-6774 18339,-6776 18341,-6781 18341,-6779 18341,-6779 18343,-6779 18339,-6777 18343,-6782 18338,-6779 18341,-6778 18341,-6776 18336,-6776 18333,-6776 18333,-6780 18338,-6784 18338,-6787 18335,-6786 18336,-6781 22336,-6781 22335,-6778 22331,-6777 22326,-6777 22331,-6777 22335,-6772 22335,-6774 22340,-6769 22341,-6767 22337,-6767 22335,-6767 22335,-6767 22333,-6767 22336,-6762 22331,-6759 22331,-6764 22332,-6765 22334,-6767 22339,-6762 22334,-6760 22334,-6760 22334,-6758 22337,-6754 22341,-6754 22342,-6750 22339,-4750 22343,-4747 22343,-4752 22343,-4751 22344,-4749 22345,-4745 22348,-4740 22353,-4736 22358,-4738 22363,-4740 22358,21336 41527,21334 41527,21330 41526,21330 41526,21333 41529,21328 41529,21329 41530,21326 41532,21328 41532,21324 41537,21328 41532,21330 41535,21334 41532,21336 40532,21334 40536,21339 40534,21341 40534,21344 40534,21346 40532,21350 40532,21353 40535,21357 40539,21359 40542,21360 40546,21355 40546,21360 40547,21359 40550,21356 40551,21356 40550,21357 40550,21361 40554,21358 45554,21362 45556,21366 45553,21370 45557,21374 45556,21377 45553,22377 45549,22382 45549,22382 45552,22386 45557,22387 45557,22388 45553,22392 45557,24392 45561,22392 45558,22397 45561,22399 45558,22398 45561,22400 45564,22400 45569,22404 45573,22406 45577,22406 45581,22404 45581,22407 45582,22409 45579,22409 45575,22409 45579,22407 45579,22402 45582,22402 45582,22404 45587,22406 45587,22406 45589,22411 45589,22413 45590,22417 45591,22417 45592,22422 45587,22425 45583,22428 50583,22428 50585,22428 50585,22430 50588,22435 50590,22435 50585,22435 50590,22439 50595,22440 50590,22445 50587,22442 50584,22442 50586,22443 54586,22443 54590,22446 54595,22448 54597,22448 59597,22444 59593,22449 59596,22449 59599,22452 59600,22457 59600,22458 59605,22457 59602,22462 59603,22463 59604,22461 59605,22458 59602,22457 59601,22457 59601,22455 59605,25455 59606,25457 59611,25462 59613,25464 59614,25467 59617,25472 59612,25476 59613,25478 59610,25482 59615,25482 59616,25486 59612,25483 59614,25487 59619,25492 59623,25497 59625,146 2252,150 2249,150 2249,152 2254,157 2249,158 2253,157 2252,161 2255,159 3255,161 3258,161 3255,163 3255,168 3259,168 3259,172 3263,167 3267,172 3271,172 3272,172 3274,175 3278,179 3282,181 3283,184 3280,185 3282,187 3282,191 3284,192 3286,191 6286,193 6289,198 6285,195 6290,194 6289,195 6289,199 6293,200 6288,198 6290,202 6291,207 6296,212 6301,215 6301,216 6301,211 6304,212 6304,216 6309,216 6304,214 6308,213 6308,211 6305,212 6309,217 6314,220 6317,224 6322,222 6327,220 6323,41573 39712,41572 39709,41576 40709,41580 40714,41576 40717,36576 40717,36577 40719,36582 40716,36585 40721,36590 43721,36585 43721,36582 43724,36585 43729,36590 43731,36590 43730,15289 11307,15285 11312,15286 11315,15289 11315,15294 11315,15295 11316,15296 13316,38742 37646,38743 37650,38745 37655,38744 37658,38739 37659,38737 37662,38742 37662,38745 37657,38748 37662,38748 37662,38752 37667,38753 37667,38748 37669,38748 37668,38752 37673,38754 37674,38756 37676,38758 37674,38760 37679,38760 37675,38758 37675,38763 37675,38767 37674,38772 40674,38767 40679,38772 40683,38774 44683,38778 44686,38780 44690,38780 44690,38779 44695,38782 44700,38780 44695,38775 44696,38775 44696,38775 44696,38779 44699,38783 44696,38784 44696,38786 44692,38786 44692,38786 44696,38791 44698,38793 44699,38795 44703,38800 44708,38803 44708,38807 44709,38802 44706,38806 44708,38809 44709,36809 44709,36814 44704,36813 44705,36814 44705,36816 44709,36811 44712,36812 48712,36811 48717,36815 48721,36816 51721,36818 51717,36822 51720,40822 51715,40827 51712,40830 51716,40829 51719,40832 51723,40835 51724,40840 51721,40841 51721,40836 51725,40841 51730,40846 51734,40848 51738,40849 51740,40851 51743,40854 51745,40855 51746,40857 51750,40857 51746,40861 51748,40866 51751,40862 51750,40866 51750,40869 51752,40865 51752,40863 51755,40858 51757,40855 51753,40855 51758,40852 51758,40853 51760,40857 51761,40855 51757,40852 51760,40853 51761,40855 51762,40858 51757,40859 51756,40863 51757,40863 51759,40860 51764,40859 51764,40854 51768,40850 51765,40852 51767,40852 51767,40848 51772,40852 51776,40854 51778,40852 51778,43852 51778,43854 52778,43856 52781,43859 52781,43859 52776,37512 26536,37517 26531,37520 26535,37520 26540,37522 26544,37527 26544,37532 26549,37537 26544,37540 26549,37545 26544,37549 26547,37549 26550,37548 26551,37549 26553,37546 26553,37546 26553,37549 26556,37549 26559,37552 26559,37556 26564,37560 26559,37561 26561,37565 26565,41565 26565,41569 26568,41571 26573,41571 26573,41576 29573,41571 29573,41573 29576,41573 29578,46573 29578,46569 29582,45569 29583,45572 29583,45568 29583,45573 29581,45575 29578,45571 29581,45572 29584,45572 29585,45576 29585,45578 29588,45581 29591,45582 29593,45582 29598,45584 29597,45589 29600,45585 29605,45589 33605,45593 36605,45594 36607,45599 36609,45600 36604,45604 36604,45604 36608,45604 36607,45608 36610,50608 36613,50611 36609,50614 36609,50619 36605,50624 36605,50625 36606,50625 36605,50629 36606,50624 36608,50625 36610,50626 36610,50629 36608,50627 36610,50628 36614,50632 36618,46632 34618,46632 35618,46636 35622,46636 35617,46637 35620,46639 35619,46643 35620,46645 35625,46643 35630,46648 35635,46648 35640,46649 35643,46651 35647,46655 35650,46652 35655,46657 35656,46658 35657,46662 35660,46659 35663,46662 35664,46665 35663,46667 35667,46667 35663,46670 35666,46672 35671,46674 35671,47674 35668,47676 35672,47677 35673,47677 35678,47677 35677,47677 35677,47677 35682,47672 35683,47671 35683,49671 35685,49674 35689,49677 35692,49675 35692,54675 35697,54678 35699,54674 35699,54670 35701,54670 35700,54675 35703,54676 34703,54676 34703,54679 34706,54683 34708,54688 34706,54688 34707,54685 34702,54687 34702,54692 34707,54687 36707,54687 36706,54682 36707,54685 38707,54680 38710,54680 38714,54677 38714,54679 38719,54682 38720,54687 38716,54688 38717,54692 38722,54697 38726,54699 38727,54700 38724,54702 38720,52702 38719,52702 38719,52702 38721,52702 38725,52704 38726,52706 38728,52707 38729,52711 38728,52711 35728,52713 35733,52712 35737,52712 35739,52713 35742,52713 35745,52708 35745,52710 39745,52713 39749,52716 39748,52721 39749,52720 39753,52716 39756,52716 40756,47716 40757,47717 40761,47722 40761,47722 40761,47722 40766,47726 40769,47728 40772,47733 40777,47731 40773,50731 40777,51731 40779,51733 40782,51734 40786,51737 40784,51741 41784,51739 41783,51739 41785,51739 41785,51736 41789,51731 41789,52731 41790,52735 41791,52738 41790,52742 41789,52746 41785,52747 41785,52745 41785,52750 41782,52753 41786,52753 41787,52758 41792,52754 42792,52749 42793,52752 42794,52756 42791,52757 42790,52762 42793,52766 42797,52766 42797,52769 42802,52774 42806,52774 42805,52771 42807,52774 42807,52770 42808,52771 42811,52767 42811,52766 42812,52767 42817,52771 42817,52771 42817,52775 42815,52779 42811,52779 42812,52780 42815,52776 42818,52774 42818,52777 42822,52780 42823,52781 42827,52776 42829,52780 42832,54780 42835,54780 42840,2135 11201,2140 11203,2137 11204,2140 11209,2142 11213,2147 11211,2145 11213,2145 11213,2150 11218,2150 11221,2153 11225,2157 13225,2162 13228,2167 13231,2171 13232,2167 13229,2168 13233,2171 13237,2173 13239,2168 13234,2168 13235,2173 13235,2175 13234,2177 13235,2177 13234,2179 13229,2179 13226,2180 13226,2177 13226,2177 13231,2180 13231,2181 10231,2176 10233,2177 10232,2180 10235,2185 10237,2182 10240,6182 10240,6184 10244,6182 10242,6183 10243,6185 10246,6190 10244,6194 10244,6194 10247,6192 10247,6192 10252,6195 10256,6194 10260,6195 9260,6195 9260,6195 9264,6199 9269,6204 9272,6199 9268,6201 9268,6203 9265,6208 9268,6204 9270,6204 9275,6201 9279,6201 9281,6201 9286,6206 9281,6206 9277,6202 9281,6200 9285,6202 9288,6198 9290,7198 9293,7200 9297,7201 9297,7205 9298,7209 9298,7209 9299,8209 9302,8214 10302,8218 10306,8222 10308,8226 10313,8231 10313,8235 10318,8237 10318,8237 10323,8233 10326,8233 10327,8237 10325,8238 10328,8238 10330,8234 10330,11234 10332,11236 10333,11241 10337,14241 10338,14240 10338,14237 10339,14238 10337,14237 10339,14242 10339,14246 10339,14250 10339,14250 10339,14251 10337,14254 10337,14256 10334,14256 10332,14252 10336,14255 10340,14259 10342,14262 10347,11148 3159,11153 3163,11154 3162,11154 3165,11158 3167,11161 3172,11162 3175,11162 3176,11166 3179,11166 3181,11171 3185,11176 3180,11178 3179,11176 3181,11179 3183,11174 3182,52776 42818,52778 42822,52777 42822,52782 42817,52783 42822,52784 42823,52789 42826,52789 42823,56789 42828,56786 42829,56786 42832,56789 42836,56789 42835,56785 42838,56786 42843,51786 42844,51788 42846,51790 42847,51794 42842,51796 42842,51801 42846,53801 42849,53806 42849,53809 42852,53812 42850,53817 42846,53817 42848,53818 42853,53822 42856,53823 42854,53826 42858,53825 42860,53826 42860,53826 42864,53830 42868,53835 42873,53839 42873,53841 42872,53841 42876,53841 42879,53841 42884,53836 42888,53836 42889,53836 44889,53833 44889,53835 44893,53838 44897,53842 44897,53844 44900,53844 44904,53845 44905,53850 44903,53853 44904,53858 44906,53856 44907,53861 44909,53856 44913,53858 44916,53863 44916,53868 44918,53867 43918,53869 43921,53869 43919,53867 43919,53862 43918,53860 43923,53864 43928,53869 43930,53874 43933,53874 43932,53874 43932,53875 43930,53877 43928,53878 43924,53883 43927,55883 43929,55883 43925,55879 43929,55881 43929,55884 43928,55881 43928,55882 43929,55883 45929,55883 45933,55883 45936,55884 45941,55884 45941,55886 45946,55882 45948,55883 45952,55888 45956,55890 45957,55894 45953,55892 45954,55897 45950,55893 45954,55896 45956,55892 45955,55897 45959,55899 45961,55899 45961,55894 45962,55898 45957,55893 49957,55896 47957,55894 47956,55898 47960,55901 47964,55901 47967,55901 47970,55896 47973,55898 47969,55894 47974,55895 47975,55891 47976,55896 47979,55899 47984,55902 47983,55897 47987,55899 47989,55904 47992,55904 47993,55905 47997,55902 48001,55902 48003,55907 48000,55910 47998,55915 47999,55911 47994,55906 47998,55910 48003,55914 48000,55918 48000,55914 48000,55919 48000,55921 48003,55921 48007,55924 48007,55919 48010,55922 48005,55927 48009,55928 48008,55928 48008,55930 48012,55925 48012,55925 48016,54925 48014,54922 48018,54922 44018,54926 44013,54929 44012,54932 44016,55932 44017,55935 44017,55936 44020,55937 44022,55936 44020,55939 44015,55944 44018,55945 44022,55947 44023,55950 44024,55953 44020,55956 44023,53867 43919,53871 43921,52871 43921,53871 43923,53876 43923,53881 43923,53880 43927,53882 43931,53886 43936,53884 43937,53879 43934,53879 43937,53877 43939,53878 43938,53879 43942,53880 43947,53881 43948,53884 45948,53884 45949,53882 45953,53883 45954,53878 45956,53880 45953,53885 45958,53885 45958,53886 45957,53886 48957,53886 48962,53891 48962,53892 48964,53897 48965,49897 48962,49902 48965,49906 48967,49902 48967,49904 48971,49901 48967,49904 48970,54904 48971,54904 48971,54904 48975,54909 48979,54907 48975,54910 48975,54906 48971,54909 48973,54911 48975,54915 48978,54920 48978,54923 48981,54918 48984,54921 48984,56921 48984,56926 48986,56924 48981,56929 48980,56932 48979,56932 48977,56936 48979,56937 48981,56937 48982,61937 48984,61937 48980,61934 51980,61935 51981,61935 51984,61935 51984,61931 51986,5329 23395,5331 23395,5333 23390,5337 23392,5340 23395,5345 27395,5345 27397,5350 27398,5355 27399,5356 27402,6356 27405,6360 27407,6361 27406,6364 27402,6366 26402,6371 26402,6371 26402,6372 26405,6370 26405,6375 26406,6380 26411,6385 26413,6387 26414,6388 26419,6390 26419,6391 26424,6393 30424,6390 30429,6390 30432,6390 30430,6394 30434,6394 30437,6394 30441,6396 30442,6398 30439,6399 30436,6404 30435,6405 30435,6400 30435,6405 30440,6404 30443,6405 30447,6409 30447,6411 30447,6412 30448,6417 30446,6421 30450,6418 30448,6417 30444,6418 30449,6420 30451,6425 30456,6426 30456,6425 30458,6426 30458,6426 34458,6427 34459,6432 39459,6434 39462,6434 39467,6439 39470,6443 39467,6444 39468,6449 39473,6451 39476,6452 39481,6452 39479,6452 39476,8452 39476,8456 39478,8460 39480,10460 39482,10455 39482,10456 39484,10460 39484,10463 39484,10468 39486,10473 39482,10475 39484,10475 39486,10476 39488,10477 39492,10475 39494,10480 39499,10476 39501,10479 39506,10480 39510,10475 39508,10480 39513,10481 39516,10481 39516,10485 39521,10487 39522,10490 39523,10490 39520,10493 39520,10496 44520,10491 44519,10491 44524,10492 44520,10497 44525,10499 44525,10502 44527,10500 44531,10502 44535,10506 44535,10511 44532,13511 44536,13513 44533,13510 44535,13507 44540,13511 44543,13515 44548,13517 44549,13522 44550,13525 42550,13520 42551,13522 42553,13525 42552,13529 42557,13529 42558,13524 42559,13525 42559,13525 42562,13520 42564,13523 42567,15523 42569,15523 42572,15524 42577,15529 42577,15530 42582,15532 42584,15532 42588,15531 42587,15531 42592,15530 42587,15530 42583,15533 42583,15536 47583,15532 47583,15535 47587,15534 47590,15536 47594,11536 47590,11533 47590,11529 47590,11533 47592,11533 47592,11533 47593,11537 47598,11538 47603,11538 47603,11538 47605,11541 47609,11544 47613,14544 47614,14539 47610,14537 47610,14537 47614,14535 50614,14537 50619,14539 50619,14540 50623,14538 50623,14537 50619,25599 26540,25599 26541,25599 26544,25594 26542,25599 26543,25596 26544,25597 26543,25598 26543,25593 26544,25588 26542,25593 26545,25595 26544,25596 26544,25599 26541,25594 26544,25592 26549,25593 26548,25597 26549,25596 26550,25594 26551,25590 26550,25594 26554,25597 26550,25598 26552,25593 26555,25598 22555,25599 22557,25604 22559,25605 22558,25606 22562,25605 22559,25605 22564,30605 22569,30610 22571,30610 22575,30609 22575,30609 22576,30609 22581,30605 22581,30610 22583,30610 22584,30613 22579,30613 22581,30616 22577,30619 22577,30621 22580,30621 22585,30626 22590,30628 22593,30629 22598,30626 22603,30628 22606,30629 22607,30629 22604,30627 22606,30632 22608,30633 22608,30636 22612,30641 17612,30642 17614,30647 17614,30651 17615,30654 17610,30655 17607,30658 17611,30653 17610,30654 17606,30654 17607,30659 17606,30660 17611,30658 17616,30659 17616,30664 17619,30665 17621,30665 17620,30667 17621,30671 17624,30673 17624,30673 17624,30678 17627,30675 17632,30675 17635,30678 17640,30681 17643,30686 17639,30691 17641,30696 19641,30699 19640,30700 19640,30696 19645,30698 19643,30699 19645,30702 19646,30703 19649,30699 19651,30704 19648,30706 19652,30709 19653,30709 19655,30709 19655,30712 19657,30708 19658,30705 19660,30700 19662,30701 19663,30706 19664,30711 19663,30707 19667,30704 19670,30708 19672,30709 19673,30711 19673,30711 19674,30713 19678,30718 19682,30723 20682,30721 20686,30725 20691,30726 20693,30729 20695,30728 20690,30730 20692,30733 20694,30736 20692,30736 20691,30740 20694,30741 20695,30741 20697,30746 20700,30747 20702,30750 20701,30751 20698,30753 24698,30749 24701,30748 24703,30746 24704,30747 29704,30747 29705,30749 29707,30752 29712,30757 29712,30760 34712,30760 34716,30763 34716,30759 34713,30759 34717,30763 34717,30758 34717,30757 34721,30760 34726,30758 34726,30763 34727,30763 34727,30764 34727,30759 34729,30759 34732,30762 34734,30757 34735,30761 34736,30759 34736,30762 34738,30757 34733,30760 34735,30762 34737,30760 34736,30765 34733,32765 34737,32768 34737,32765 34740,32765 34742,32768 34747,32772 34751,32772 34752,32777 34749,32782 34751,32783 33751,32783 33746,36783 33749,36783 33754,36786 33756,36787 33755,36787 33758,36791 33754,36796 33754,36801 33756,36801 33758,36801 33762,36802 33765,36802 33765,36806 33770,33806 33772,33806 33777,33809 33777,33814 33780,33814 33785,33818 33782,33821 33784,33826 33781,33822 33781,33824 33783,33822 33784,33826 33787,33823 33792,33827 33795,33828 33798,33829 33799,33833 33801,33833 33801,33836 33805,33839 33809,33842 33805,33847 33810,33845 32810,33847 32808,33849 32812,33851 32815,33849 32818,33849 32822,33847 32822,33847 32826,33850 32831,33854 32836,33857 32833,33856 32828,33859 32829,33860 32832,33857 32834,33857 32830,33855 32830,33857 32830,33855 32834,33859 32829,33859 32833,33862 32836,33864 32837,33864 32839,33866 32837,33869 32835,33872 32840,33874 37840,33879 37845,33881 37850,33881 37855,33886 37856,33891 37860,33896 37860,33893 37863,33894 38863,33896 38859,28896 38864,28899 39864,33899 39869,33896 39871,33898 39875,33902 39873,33902 39875,33907 39879,33912 39884,33908 39887,33908 39888,33905 39890,33909 39895,33911 39896,33908 39900,33912 39901,33915 39902,33915 39902,33915 39902,33910 39907,33910 39904,33914 39903,33912 39906,33916 39909,33920 39909,33922 39912,33923 39916,33928 39916,33931 39918,33932 39919,33935 39915,33936 39912,33934 39909,35934 39914,35931 39915,35935 39917,35939 39920,35939 39915,35940 39911,35944 39916,35944 39911,35944 39908,35945 39904,35945 39908,35945 39912,35950 39915,35955 39917,38955 39916,38960 39921,38962 39920,38962 39920,38967 39922,38967 39924,38970 39928,38975 39928,38973 39928,38977 39931,38980 39934,38984 39936,38982 39939,38983 39942,38985 39943,38987 39945,38992 41945,38988 41950,38989 41954,38992 41958,38992 41962,38992 41965,38993 41970,38997 41970,38997 41970,38994 41974,38994 41979,38997 41979,38999 41982,38994 41980,38998 41985,38998 41984,5334 23406,5330 23406,5325 23403,9325 23404,12325 23408,12325 23408,12322 23406,13322 23411,13325 23416,13326 23412,13322 23414,13327 23419,13328 23422,13329 23425,13333 23422,13337 23424,23491 35549,23490 35544,23494 35546,23499 35548,23495 35549,21495 35553,21490 35556,21492 35558,21492 35556,21494 35559,21494 35564,21494 35566,21499 35566,21502 35562,21502 35567,17502 35568,17506 35573,17507 35574,17511 35578,17512 35583,17513 35588,18513 35591,18514 35592,18515 35594,18513 35596,16513 35601,16513 37601,16513 37602,16511 37604,16513 37609,16514 37611,16518 37616,16522 34616,16524 34613,16528 34615,16528 34620,16533 34624,16535 34627,16538 34628,16539 34630,16539 34631,16542 34628,16542 34633,16544 34638,16547 38638,16547 38640,16543 38645,16543 38640,16540 38640,16543 38640,16542 38641,16546 38646,16541 38649,16541 38645,18541 38648,18544 38648,18544 38653,18544 38656,18549 38651,18547 38651,18550 38656,18547 38658,23547 38663,23544 38664,23548 38668,23548 38670,28548 38672,28549 38669,28549 38673,28545 38669,28549 38670,28554 38670,28557 38674,28560 38669,28562 38674,28562 38669,28561 38669,28564 38671,28569 38671,38779 44699,38780 44695,38778 44698,38783 44700,38785 44700,38781 44701,38782 44696,38786 44691,38789 44692,38794 44692,38799 44688,38799 44693,38803 44697,38808 44697,38806 44697,38806 44700,38803 44702,38803 44706,38802 44707,38807 48707,38808 48707,38806 48707,38810 48712,38810 48709,38810 48711,38810 48711,38806 48707,38802 48710,38803 48706,38805 48711,38810 48711,38805 48709,38809 48710,38809 48710,38814 48707,38815 48703,38816 48703,38816 48704,38820 48704,38822 48709,38820 48710,38818 48714,38822 48716,38822 48719,38827 48722,38828 48727,38832 48725,38830 48730,38831 48726,38832 48724,38829 48728,8431 35532,8431 35537,4431 35532,4434 35537,4438 35537,4439 35533,4443 35535,4442 35530,4445 35527,4449 35527,4453 35530,4458 35530,4459 39530,4460 39531,4461 39531,4464 39531,4468 39531,4470 39534,4465 39534,4465 39532,4469 39532,4471 39537,4466 39538,4470 39539,4473 39540,4476 39540,4480 39543,4485 39548,4483 39546,4484 39547,4484 39549,4484 39551,4486 39553,4486 39554,4487 39551,4483 39553,4486 39554,4490 39556,4493 39557,4498 39561,4494 39562,-4749 22345,-4752 22345,-4748 22348,-4744 22351,-4740 22356,-4741 22358,-4739 22361,-4734 22359,-4730 25359,-4730 25360,-4725 25360,-4727 25360,-4727 25361,-6727 25360,-6729 25365,-6730 25365,-6727 25365,-6731 25364,-6730 27364,-6727 27366,-6723 27367,-3723 27363,-3719 27368,-3720 27371,-3718 27366,-3717 27369,-3716 27369,-3714 27372,-3711 27370,-3712 27371,-3712 27370,-3710 27375,-3708 27377,-3707 27382,-3706 27385,-3706 27389,-3705 32389,-3704 32392,-3704 32392,-3699 32391,-3699 32395,-3694 32399,-3694 32400,-3695 32404,-3695 32408,-3693 32410,-3693 32410,-3697 32410,-3692 32413,-3691 32418,-3686 32420,-3683 32425,-3681 32420,-3678 32424,-3673 32424,-3676 32427,-3673 32426,-3671 32426,-3676 33426,-3678 33428,-3676 33428,-3679 33428,-3679 33433,-3677 33434,-3676 33438,-3681 33440,1319 33444,1321 33441,1325 33444,1329 33439,1326 33444,1326 33439,1327 33439,1327 33440,1332 33444,1333 33449,1338 33453,1338 33450,1343 33450,1347 33454,1346 33457,1346 33455,1342 33459,1341 33462,1346 33462,1347 33463,1343 33463,1344 33462,1348 33457,1347 33460,1352 33464,1356 33468,1361 33469,1363 33468,1365 33469,1368 33472,1369 33475,-2631 33478,-2633 33483,-2629 33486,-2632 34486,-2628 36486,-2625 36488,-2621 36488,-2624 36488,-2622 36492,-2624 36491,-2629 36491,-2627 36496,-2623 36499,-2628 36502,-2631 36506,-2626 36506,-2622 36506,-2622 36509,-2619 36514,-2624 36512,-2621 36510,-2619 36510,-2619 36508,-2617 36512,-2615 36512,-2615 36513,-2615 36511,-2615 36506,-2612 36507,-2609 36511,-2606 37511,-2606 37508,-2610 37505,-2607 37508,-2602 37512,-2599 37512,-2595 37510,-2597 37511,-2592 37515,-2597 37514,-2592 37519,-2592 37524,-2592 37526,-2594 37521,-2594 37516,-2591 36516,-2588 36517,-2589 36513,-2586 36514,-2584 36514,-2583 36516,-2579 36514,-2578 36518,-2578 35518,-2575 35519,-2577 35519,-2578 35524,-2578 35529,-2578 35532,-2578 35534,-2580 35537,-2584 35541,-2586 35542,-2587 35544,-2585 35540,-2585 35544,-2584 35543,-2580 35548,-2576 35550,-2571 35553,-2567 35555,-2565 35560,-2560 35560,-2557 35564,-2553 35564,-5553 36564,-5548 36564,-5544 36565,-5547 36565,-5545 36570,-5542 36565,-5543 36566,-5543 36568,-5543 36570,-5540 36575,-5537 36577,-5535 36581,-5532 36580,-5528 36575,-5526 38575,-5526 38576,-5526 38571,-5522 38571,-5518 38576,-5514 42576,-5510 42581,-5512 42583,-5512 42582,-5507 42582,-5510 42585,-2510 42589,-2511 42592,-2508 42594,-2506 42597,-2503 42598,-2503 42603,-2498 42608,-2501 42611,-2500 42616,-2502 42613,-2502 42616,-4502 42616,-4502 42620,-4502 42622,-4506 42619,-4509 42621,-4511 42624,-4515 42625,-4510 42625,-4507 42628,-4502 42624,-4501 42629,-4505 45629,-4503 45630,-4499 45631,-4496 45630,-4497 45628,-4495 45630,-4494 46630,-4491 46634,-4487 46629,-4483 46631,21336 40532,21341 40533,21346 40534,21346 40536,21345 40536,21346 40536,21345 40536,21344 40538,21347 40543,21348 40543,21351 40540,21351 40542,21348 40545,21351 40546,21352 40546,21353 40546,21358 40546,21359 40545,21359 40550,21357 40555,21362 40560,21364 40555,21363 40555,21364 40560,25364 40564,25365 40566,25368 40566,25371 45566,25372 45567,25372 45562,25376 45564,25381 42564,25385 42560,25389 42564,25389 42568,25393 42572,25390 42572,28390 42569,28389 42570,28385 42574,28386 42576,28389 42577,31389 42578,31385 42582,31387 42582,31390 42578,31391 42579,31392 42576,29392 42580,29396 42582,29398 43582,29402 43584,29406 43585,29407 43587,29411 43592,29413 43594,29414 43595,25414 43600,25412 43595,25415 43599,25420 43602,25418 43604,25423 43599,25426 43599,25429 43602,25434 42602,25429 42604,25432 42600,25435 42605,25436 47605,25440 50605,25441 50610,25439 50614,25444 50617,25447 50621,25444 50624,25444 50626,25445 50627,25450 50632,25450 50628,25451 50630,25451 50632,25454 50633,25458 50637,25462 50641,25463 50640,25463 51640,25467 51644,25469 51649,25473 51650,25474 51653,25475 51654,26475 51658,26475 51662,26474 51665,26476 51665,26481 51661,26483 55661,26485 55664,30485 55667,30485 55670,30489 55671,30489 55668,30491 55670,30492 55670,30493 55675,30497 55675,30501 55671,30503 55676,30500 55677,30498 55672,30494 55675,30499 55676,30500 55676,30505 55681,30501 55684,30496 55685,30500 55685,30502 55687,30506 55692,30507 55693,30506 55692,30511 55693,30516 55694,30514 55699,30514 55701,30512 55701,34512 55705,34516 55708,34520 55704,34518 56704,34519 56704,34520 56706,34517 56706,34515 56701,34519 59701,34522 59706,34522 59708,34522 59713,34526 59715,34528 59717,34533 59712,34538 59715,34538 59717,34541 59717,34546 59720,34548 59721,34552 63721,34547 63726,34549 63728,34554 63726,34556 63726,34557 63721,34556 63725,34561 63730,34558 63730,37558 63725,37561 63729,37565 63724,37569 63720,37573 63718,37578 63722,37577 63718,37579 63720,37579 63722,37580 63719,37580 63720,37579 63724,37574 63725,37574 63727,37576 63725,37581 63729,37583 63732,37586 63732,37590 63737,37592 63734,37597 63731,37600 63730,37596 63731,37596 63733,37600 63733,37601 63735,37596 63735,37591 63732,37596 63733,37601 63738,37602 63733,37599 63738,37594 63740,37598 63744,37603 63745,37605 63747,37607 63752,37607 63756,37603 63757,37603 63761,37604 63761,37608 63758,37609 63762,37604 63764,37604 63764,41604 63765,41600 63761,41599 63761,41600 63766,41596 63766,41599 63766,41601 63770,41604 63768,41608 63768,41611 63772,41614 63767,41609 63763,41612 63765,41615 63760,38615 63764,38615 63768,38618 63768,35618 63769,35618 63774,35617 63775,35618 63776,35613 63775,35615 63780,35612 63782,35613 63779,35614 63775,35618 63774,35619 63776,35624 63778,35624 63780,35629 63785,35629 63780,35626 63781,35624 63782,35629 63784,35634 63787,35638 63782,35634 63783,35634 63778,35633 63777,35638 63782,35641 63786,35644 63791,35648 63793,35647 63793,35649 63797,35653 63801,35654 63804,35654 63804,35656 63804,35655 63806,35658 63810,35658 63805,35662 63805,35657 67805,35658 67808,35660 67811,35664 67808,35660 67803,35658 67803,35661 67803,35663 67808,35666 67810,35670 67814,35669 67813,35669 67816,37669 67820,37664 67820,2275 13363,2278 16363,2274 16363,2275 16362,2279 16362,2282 16362,2287 16366,2284 16366,4284 16366,4286 16371,4290 16375,4294 18375,4295 18377,9295 18381,9296 18381,9299 18382,9303 18379,9305 19379,9308 19375,8308 19380,8312 19380,38746 37651,38749 37652,38754 37653,38757 37656,38753 37661,38753 37661,38758 37663,38763 37664,38763 42664,38768 42666,38765 42668,38770 42664,38767 42659,38768 42659,38773 42654,38771 42659,38775 42661,41775 42663,41778 42665,41781 42669,41782 42667,41779 42669,41784 42672,41781 42672,41783 42672,41780 42672,41783 42675,41784 42675,41788 42676,41792 42677,41792 42675,41793 42680,41793 42676,41796 42681,41801 42685,41804 42684,41806 42685,41804 42690,41802 42692,41805 42696,41800 42697,41802 42698,41804 42700,41809 42704,41813 42705,36813 42708,36813 42704,36810 42703,36811 42705,40811 42706,40815 46706,40816 46708,40820 46708,40818 46712,40822 46717,40825 46720,40829 46724,40827 46727,40831 46727,40833 46731,40829 46733,40830 46733,36830 46738,36830 46741,36834 46744,36831 46749,36826 46748,36822 46748,36824 46751,36819 46755,36823 46758,36823 46762,36824 46766,36822 46769,36826 46772,36831 46774,36828 42774,36833 42776,36833 42777,36838 42782)')));
-INSERT INTO t1(g) VALUES (ST_linefromtext(concat('linestring','(20 110, 21 110, 26 115, 29 112, 34 108, 39 111, 44 111, 46 116, 46 120, 42 122, 45 118, 48 118, 44 122, 46 127, 47 127, 51 127, 55 123, 52 127, 52 128, 56 130, 60 129, 61 130, 66 131, 67 131, 71 135, 76 136, 77 139, 80 143, 2080 145, 2077 147, 2079 147, 2081 147, 2086 147, 2087 151, 2092 -1849, 2088 -1848, 2088 -1852, 2091 -1848, 2095 -1846, 2092 -1847, 2092 -1848, 2093 -1847, 2094 -1846, 2099 -1843, 2104 -1844, 2102 -1848, 2102 -1848, 7102 -1847, 7105 -1846, 7106 -1843, 7111 -1838, 67 131, 69 135, 68 135, 63 136, 63 137, 64 141, 67 1141, 2067 1139, 2063 1139, 2066 1139, 5066 1139, 5068 1139, 5072 1140, 5072 1145, 5073 1142, 5076 1145, 5077 1145, 5076 1141, 5078 1141, 5073 1143, 5068 1146, 5067 2146, 5070 2151, 5075 2155, 5071 2160, 5073 2161, 5074 2166, 5076 2169, 5071 2173, 5074 2173, 5078 2177, 5076 2173, 5080 2173, 5078 2174, 78 2179, 76 2183, 77 2188, 82 2192, 85 2194, 89 2193, 86 2197, 89 2193, 88 2194, 89 2199, 89 2204, 89 1204, 87 1206, 88 1203, 89 1204, 89 1205, 93 1210, 94 1208, 96 1208, 100 1210, 104 1212, 107 1215, 104 1220, 107 1224, 111 1228, 112 1228, 116 1229, 119 1228, 120 1233, 119 1236, 124 1241, 125 1240, 122 1239, 126 1241, 123 1240, 124 1244, 128 1248, 129 1250, 128 1253, 127 5253, 125 5255, 129 5255, 133 5255, 137 5260, 140 5261, 137 5261, 141 5261, 140 5262, 143 5264, 148 5264, 148 5264, 145 10264, 149 10269, 153 10274, 158 10270, 159 10273, 164 10277, 168 12277, 170 12278, 165 12274, 170 12279, 172 12281, 172 12281, -3828 12281, -3823 12281, -3822 12282, -3823 12280, -3823 12282, -3820 12281, -3823 12279, -3827 12282, -3826 12279, -3822 12284, -3825 12284, -3824 12286, -3820 12287, -3820 12290, -3818 12292, -3816 12293, -3814 12298, -3815 12301, -3817 12304, -3814 12301, -3811 12299, -3809 12303, -3809 12301, -3804 12302, -3804 12302, -3802 12305, -3799 12310, -3801 17310, -3801 17310, -3796 17310, -3801 17314, -3799 17318, -3796 17321, -3795 17321, -795 17325, -795 17327, -794 17329, -791 17330, -790 17326, -787 17331, -782 17335, -778 17339, -774 17343, -772 17343, -769 17346, -768 17349, -763 17352, -763 17353, -761 17357, -758 17354, -758 22354, -754 22350, -750 22353, -746 22356, -750 22352, -746 22351, -744 22349, -743 27349, -741 27350, 259 27354, 262 27353, 263 27356, 268 27352, 268 22352, 271 22351, 273 22351, 274 22351, 275 22352, 275 22356, 280 22352, 281 22348, 284 22349, 284 22346, 285 22351, 285 22351, 290 22353, 294 22351, 294 22352, 295 22352, 300 22352, 305 22355, 308 22356, 311 22356, 310 22358, 312 22360, 313 22365, 313 22362, 313 22364, 313 22364, 317 22360, 322 22362, 327 22367, 328 22370, 323 22375, 320 22377, 320 22379, 316 22379, 318 22379, 323 22380, 323 22380, 324 22376, 34 108, 38 113, 42 118, 42 117, 42 121, 46 123, 51 127, 51 130, 51 133, 55 137, 52 141, 52 143, 51 141, 50 142, 45 142, 44 143, 48 146, 48 142, 43 143, 47 145, 4047 5145, 4047 5150, 4044 5151, 4045 10151, 4043 10154, 4044 10156, 4047 10156, 4043 10160, 4043 10156, 4043 10156, 4048 10157, 4051 10160, 4048 10159, 4053 10161, 4057 10163, 4057 10164, 4058 10165, 4057 10170, 4056 10173, 4056 10176, 4056 15176, 4053 15180, 4049 15181, 4051 15178, 4049 15180, 4049 15180, 4048 15181, 4048 15184, 4045 15188, 4045 15191, 4040 15194, 4042 15198, 4042 15203, 4047 15200, 4049 15201, 4052 15204, 4052 15208, 4052 15212, 4049 15216, 4049 15219, 4051 15220, 4048 15222, 4044 15227, 4044 15232, 4044 15236, 4049 15239, 4052 15240, 4052 15243, 4053 15247, 4055 15247, 4052 17247, 4054 17247, 4054 18247, 4059 18251, 4063 18253, 4066 18253, 4069 20253, 4069 20254, 4069 20259, 4068 20263, 4068 20263, 4069 20259, 4071 20260, 4073 20262, 4074 20258, 4069 20261, 4069 20264, 4071 20269, 4067 20271, 4071 20270, 4072 20271, 4073 20268, 4076 20263, 4072 20268, 4075 20264, 4076 20267, 4079 20272, 4084 20275, 4086 20277, 4086 20281, 4083 18281, 4087 18283, 4088 18280, 4089 18277, 4089 18279, 4094 18281, 4095 18283, 4095 18284, 4097 18284, 4093 18287, 4094 18285, 4096 18287, 4092 18291, 4096 18291, 140 5261, 140 5259, 140 5262, -1860 5258, -1858 5260, -1854 5262, -1849 5259, -1848 5264, -1845 5264, -1845 5267, -1845 5262, -1848 5261, -1848 5263, -1849 5261, -1853 5262, -1851 5265, -1847 5265, -1847 5262, -1847 5263, -1843 5268, -1845 5268, -1848 5272, -1850 5270, -1851 5274, -1854 5269, -1850 5266, -1845 5267, -1840 5267, -1840 5264, -1840 5269, -1839 5269, -1842 5269, -1840 5274, -1835 5278, -1836 5283, -1841 5279, -1840 5284, -1836 5285, -1836 5289, -1831 5289, -1826 5292, -1822 5293, -1826 5295, -1829 5295, -1824 5295, -1828 5297, -1824 5300, -1820 5305, -1824 5306, -1824 5306, -1824 5306, -1823 5301, -1818 5303, -1814 5307, -1814 5303, -3809 12303, -3807 12306, -3804 12306, -3804 12306, -3801 12308, -3796 12308, -3795 12308, -3791 12310, -3786 12310, -3781 12313, -3814 12298, -3809 12303, -3807 12301, 7102 -1847, 7100 -1850, 7104 -1850, 7109 -1852, 7109 -1854, 7112 -1850, 7112 -1847, 7115 -1847, 7117 -1847, 7122 -1847, 7125 -1843, 7126 -1848, 7127 -1848, 7129 -1848, 7133 -1848, 7131 1152, 7131 1149, 7135 1154, 7139 1152, 7140 1151, 7145 1153, 7149 1158, 8149 1159, 8154 3159, 8149 3161, 8145 3162, 8146 3164, 8146 3168, 11146 3171, 11148 3171, 11150 3167, 11154 3165, 11150 3163, 11151 3167, 11152 3165, 11153 3170, 11156 3175, 11156 3174, 8146 3164, 8146 3167, 8146 3170, 8147 3170, 8148 3175, 8148 3178, 8146 3178, 8146 3178, 8147 3180, 8143 3184, 3143 3186, 7143 3187, 7143 7187, 7138 7189, 7138 7189, 7135 7191, 7138 7191, 7133 7194, 7138 7198, 7139 7201, 7143 7200, 7141 7203, 12141 7204, 12145 7204, 12145 7203, 12146 7207, 12147 7204, 12143 7204, 12138 7199, 12138 7195, 12139 7195, 12139 7200, 12141 7201, 12142 7201, 12139 7205, 12142 7208, 12142 7213, 12145 7213, 12147 7214, 12149 7218, 12150 9218, 12154 9222, 12151 9222, 12151 9225, 12151 9224, 12152 9226, 12155 10226, 12155 10230, 12158 10231, 12161 10227, 12162 10224, 12163 10229, 12163 10231, 12165 10228, 12165 10227, 12160 10228, 12160 10231, 12160 10235, 12157 12235, 12159 12230, 7138 7189, 7141 7193, 7141 7193, 7141 7192, 7139 7195, 7141 7195, 7142 7193, 7145 7195, 7146 7193, 7146 7194, 7151 7197, 7154 7198, 7156 7202, 7155 7207, 7150 7211, 12150 7213, 12148 7213, 12147 7217, 12142 7221, 12141 7223, 12143 7223, 12140 7222, 12145 7222, 13145 7224, 13142 7228, 13144 7232, 13139 7235, 13144 7239, 13148 7243, 13151 7247, 13150 7251, 13152 7252, 13157 7253, 13157 7257, 13157 7257, 13157 7262, 13159 7264, 13164 7259, 13161 7259, 13165 7262, 13166 7262, 13166 7267, 13169 7268, 13169 8268, 13167 8269, 13171 8269, 13173 13269, 13177 13265, 13178 13263, 13178 13263, 13182 13266, 13183 13266, 13185 13266, 13190 13269, 13193 13271, 13193 13269, 13196 13271, 13193 13273, 13194 13268, 13198 13273, 13200 13276, 13202 13276, 13204 13274, 13209 11274, 13213 11274, 13213 11277, 13215 11278, 13219 11279, 13224 11280, 13224 11276, 13228 11278, 13233 11281, 13235 11286, 13238 11288, 13240 11288, 13238 11290, 13238 11292, 13238 11287, 13238 11288, 13240 11293, 13243 11296, 13246 11296, 13247 11293, 13243 11298, 13246 11302, 13251 11305, 322 22362, 326 24362, 330 24362, 329 24367, 328 24363, 329 24365, 331 24369, 336 24371, -664 24371, -668 24372, 51 127, 48 131, 48 133, 51 135, 51 140, 49 139, 47 142, 3047 139, 3044 142, 3046 143, 3046 148, 3051 148, 3055 146, 3057 141, 3060 140, 3055 143, 3050 146, 7050 142, 7050 3142, 7050 3143, 7050 3144, 7052 3149, 7055 1149, 7052 1150, 7055 5150, 7050 5154, 7049 5150, 10049 5151, 10045 5151, 10049 5151, 10052 5156, 10054 5159, 10056 5160, 10058 5161, 10058 5163, 10060 5166, 10064 5168, 10064 5173, 10068 9173, 10070 9172, 10065 9168, 10065 9173, 10063 9175, 14063 9176, 14063 9178, 284 22346, 289 22351, 290 22351, 290 22347, 287 22343, 282 22342, 280 22345, 281 25345, 286 25347, 13243 11298, 13248 11300, 13245 11300, 13246 11295, 13247 11295, 13246 11295, 13248 11299, 13253 11304, 13255 11309, 13255 11310, 13260 11309, 13257 11310, 13258 11313, 13258 11315, 13263 11311, 13267 11307, 13269 11309, 13272 11305, 13277 11302, 13273 11304, 15273 11306, 15278 11310, 15281 11307, 15286 11309, 15288 11309, 15291 11311, 15292 11306, 15294 11309, 15298 11313, 15299 11317, 15300 11320, 15302 11321, 15306 11324, 15308 11328, 15308 11324, 15309 11324, 15314 11324, 15315 11323, 15319 11321, 15317 11325, 15319 11327, 15319 11332, 15321 11337, 15324 11340, 15324 11341, 15324 11341, 15326 11345, 15326 11349, 15327 14349, 15330 13349, 17330 13350, 17335 13353, 17339 13358, 17340 13362, 17344 13362, 17348 13357, 17350 13357, 17347 13357, 17350 13358, 17349 13358, 17349 13358, 17349 13359, 22349 13362, 22351 13359, 22353 13359, 22358 13358, 22360 13358, 22363 13359, 22364 13359, 22360 13359, 22361 13363, 22366 13368, 22371 13373, 22374 13377, 22378 13375, 22379 13375, 22379 13373, 22383 13378, 22388 13383, 22389 13380, 22389 13384, 22394 13382, 22392 13378, 22394 13382, 22393 13382, 22393 13379, 22394 13382, 22392 13384, 22395 13386, 22400 13391, 22400 10391, 22404 10395, 22401 10396, 22402 10396, 22402 10398, 22406 10395, 22405 15395, 22407 15396, 22409 15396, 22414 15391, 22414 15394, 22414 15398, 22410 15400, 26410 15402, 26409 20402, 26413 20406, 26417 20410, 26419 20415, 26422 20411, 26424 20411, 31424 16411, 31423 16409, 31423 16414, 31425 16414, 31428 16418, 31428 16414, 31432 16419, 31432 16422, 31437 16423, 31439 16424, 31440 16426, 31440 16429, 31440 16429, 31443 16431, 31441 16435, 31443 16440, 36443 16440, 36445 18440, 36444 18441, 36442 18444, 36442 18440, 36442 18444, 36444 18449, 36445 18450, 36449 18455, 37449 23455, 37454 23460, 37458 23459, 37460 23463, 37458 23465, 37460 23467, 37462 23470, 37466 23473, 37462 23478, 37464 23480, 37463 26480, 37468 26483, 37472 26487, 37473 26492, 37476 26493, 37476 26489, 37476 26487, 37476 26492, 37472 26496, 37476 26501, 37476 26503, 37480 26499, 37485 26503, 37485 26505, 37490 26500, 37493 26503, 37497 26499, 37502 26500, 37502 26501, 37502 26505, 37499 26503, 37499 26503, 37497 26508, 37500 26508, 37496 26513, 37499 26518, 37497 26519, 37500 26518, 37505 26518, 37510 26516, 37512 26520, 37513 26523, 37511 26527, 37508 26532, 37509 26536, 37514 26540, 37515 26542, 37512 26546, 37514 26548, 37519 26547, 37524 26550, 37529 26555, 37527 26559, 37531 26562, 37526 26567, 37526 26566, 37529 26566, 37524 26566, 37524 26563, 37528 26565, 37524 26563, 37525 26565, 37525 26560, 37526 26562, 40526 26564, 40526 26567, 40523 26571, 40527 26570, 40529 26572, 40534 26576, 40536 26573, 40535 26569, 40533 26569, 40537 26573, 40537 26574, 40541 26576, 40546 26579, 40545 26579, 40546 26583, 40550 26588, 40551 26585, 40555 26589, 40558 26594, 40554 22594, 40559 22598, 40558 22599, 40563 22596, 40563 22597, 40567 22597, 40570 22597, 40575 22592, 40572 22594, 40572 22595, 40572 22592, 40575 22594, 40575 22597, 40570 22597, 40569 22601, 40569 22603, 40573 22603, 40576 22604, 40576 22608, 42576 22611, 42579 22611, 42579 22616, 42581 22620, 38581 22623, 38582 22621, 38582 22618, 38577 22623, 38581 22623, 38581 18623, 38584 18618, 38584 18621, 38588 18626, 38592 18629, 38592 18626, 38596 18625, 38598 18620, 38599 18618, 38599 18622, 38602 21622, 38603 21622, 38607 21624, 38609 25624, 38613 25624, 38610 25621, 38610 25625, 38610 25629, 38613 25627, 38617 25627, 38617 25624, 38618 25626, 38621 25628, 38622 25629, 38622 26629, 38625 26631, 38625 26631, 313 22362, 313 22363, -1687 22364, 2313 27364, 2314 27364, 2314 27364, 2319 27366, 2319 27366, 2321 27363, 2321 27368, 2320 27363, 2323 27368, 2328 27371, 2327 27375, 2328 27377, 2328 27377, 2327 27381, 2331 27381, 2329 27381, 2332 27383, 2335 27383, 2333 27383, 2333 27385, 2338 27385, 6338 27386, 6338 27387, 40529 26572, 40533 26576, 40535 26578, 40540 26580, 40535 26584, 40540 26589, 40541 26592, 40538 26587, 40542 26591, 40541 26592, 40537 26597, 40542 26598, 40546 26601, 40550 26606, 40550 26605, 40551 26606, 40549 26606, 40550 26607, 40555 26610, 40550 26610, 40550 26607, 40553 26612, 40558 26616, 40561 26620, 40556 26623, 40558 26623, 40558 26627, 42558 26627, 42558 26628, 42562 26628, 42564 26630, 42565 26634, 42566 26634, 42566 26638, 42561 26639, 42564 26639, 42567 26641, 42564 26642, 42566 26646, 42566 26645, 42570 26645, 42574 26645, 42574 29645, 42576 29646, 39576 29645, 39576 34645, 39578 34647, 39583 34642, 39580 34642, 39576 34646, 39576 34649, 39574 35649, 34574 35652, 34579 35655, 39579 35659, 43579 35663, 43582 35659, 43577 35662, 43580 35662, 43583 35666, 43579 39666, 43574 39662, 43574 39665, 43574 39668, 43574 39670, 43578 39674, 43579 39671, 43582 39675, 43578 39677, 43575 39677, 43576 39681, 43571 39683, 43569 39683, 43570 39687, 43565 39690, 43568 39694, 43568 39696, 43570 39698, 43570 39699, 41570 39695, 41572 39696, 41573 39696, 41573 39697, 41573 39702, 41573 39702, 41576 39702, 41571 39702, 41572 39703, 41572 39708, 41574 39713, 41575 39716, 41580 39717, 41581 39721, 41586 39723, 41587 39724, -1848 5272, -1843 5272, -1845 5270, -1840 5272, -1838 5267, -1843 5268, -1841 5268, -1837 8268, -1837 8271, -1837 8276, -1836 8280, -1832 8277, -1832 8277, -1831 8278, -1835 8283, -1834 8287, -1832 8290, -1834 8286, -1832 8283, -1833 8283, -1832 8284, -1834 8287, -1839 8292, -1844 8293, -1841 8290, -1836 8290, -1839 8289, -1836 8289, -1832 8292, -1827 8295, -1823 8290, -1823 8293, -1823 8291, -1822 8295, -1820 8298, -1819 8302, -1816 8304, -1816 8300, -1812 8300, -1809 8299, -1806 8296, 1194 8300, 1194 8301, 1197 11301, 1194 11305, 1197 11309, 1199 11304, 1195 11304, 1195 11300, 1195 11297, 1196 11298, 1201 11296, 1206 11296, 1207 11298, 1212 11296, 1210 11292, 1206 11294, 1207 11293, 1209 8293, 1204 8288, 1206 8286, 1206 8285, 1208 8285, 1210 8285, 1214 8287, 1214 13287, 1215 13291, 1215 13294, 1218 13297, 1216 13293, 1219 13290, 1214 13295, 1210 13292, 1210 13296, 1211 13301, 1210 13300, 1206 13302, 1207 13307, 1211 13312, 1206 13312, 1211 13308, 1212 13308, 1216 13313, 1216 13318, 1217 13318, 1221 13318, 1221 13323, 1226 13324, 1231 13325, 1234 13329, 1235 13333, 1233 13333, 1236 13338, -2764 13340, -2767 13341, -2763 13344, -2760 13349, -2758 13346, 2242 13346, 2240 13346, 2244 13346, 2248 13349, 2248 13350, 2246 13352, 2241 13352, 2242 13355, 2242 13356, 2247 13361, 2250 13361, 2245 13366, 2249 13366, 2250 13366, 2254 13367, 2258 13367, 2258 13367, 2262 13371, 2257 13376, 2253 13373, 2253 13373, 2254 13376, 2251 13380, 2256 13382, 2257 13386, 2261 13383, 2264 13383, 2269 13385, 2264 13385, 2264 13387, 2267 13387, 2271 13389, 2272 13390, 2273 13393, 2269 13395, 2273 13390, 2277 13395, 2275 13396, 2277 13391, 2279 13394, 2276 13394, 2277 13398, 2282 13399, 2282 11399, 2283 14399, 2281 14404, 2279 14407, 2275 14410, 2276 16410, 2276 16414, 2281 16414, 2286 16415, 2282 16413, 2282 16413, 2284 16413, 2284 16415, 2284 16416, 2282 16417, 3282 16422, 3286 16422, 3287 16427, 3291 16427, 3294 16431, 3296 16433, 3298 16435, 3299 16440, 3300 16439, 3305 16439, 3307 16438, 3307 16440, 3307 16440, 3311 16441, 3311 16442, 3310 16443, 3310 16443, 3308 16448, 3304 16445, -1696 16441, -1701 16442, -1697 16442, -1695 16442, -1696 16443, -1693 16440, -1688 16445, -1685 16450, -1681 16454, -1680 16455, -1682 16457, -1680 16461, -1680 16461, -1684 16464, -1679 16463, -1678 16460, -1675 16464, -1679 16465, -1677 16468, -1672 16469, -1671 16473, -1667 16475, -1667 16480, -1663 16478, -1663 16482, -1662 16482, -1662 16483, -1659 16478, -1654 16475, -1653 11475, -1658 11477, -1661 11479, -1664 11484, 3336 15484, 3340 15480, 3344 15475, 3347 15475, 3347 15474, 3352 15473, 3349 15478, 3353 15480, 3354 15477, 3355 15480, 3352 15481, 3352 15483, 3353 15486, 3354 15488, 3353 15491, 3355 15491, 3360 15491, 3355 15490, 1219 13290, 1224 13295, 1224 13295, 1227 13290, 1231 13290, 1233 13285, 1237 13284, 1238 13285, 1243 13286, 1247 13289, 1249 13289, 1249 13291, 1252 13291, 1249 13294, 1249 13299, 1249 13302, 1254 13305, 1251 13308, 1254 13308, 3254 13308, 3249 13308, 3251 13312, 3256 13312, 3259 13312, 3263 17312, 3263 17313, 3263 17310, 3261 17309, 3264 17314, 3265 17312, 3264 17315, 3261 17318, 3261 17318, 3259 17313, 3256 17313, 3255 17313, 3257 17314, 3255 17316, 3257 17316, 3257 17316, 3258 17311, 3259 17311, 3258 17315, 3258 17317, 3257 17321, 3253 17321, 3250 17325, 3255 17329, 3258 17330, 3260 17328, 3260 17331, 3265 17326, 7265 17329, 7267 17332, 7265 17334, 7267 17337, 7272 17337, 7275 17337, 7280 17340, 4280 21340, 4280 21344, 4281 21344, 4283 21344, 4288 24344, 4292 24347, 9292 24351, 9296 24353, 9298 24351, 9300 25351, 9303 25352, 9303 25352, 9306 25357, 9305 25361, 9305 25356, 11305 25359, 11306 25362, 11309 25362, 11314 25362, 11314 25365, 11312 25369, 11315 25369, 11316 25373, 11321 25375, 11323 25375, 11327 25370, 11331 25369, 11332 25370, 11331 25374, 11332 25369, 11336 25371, 11340 25370, 11345 25367, 11350 25363, 11347 25360, 11350 25361, 11351 25362, 11351 25362, 11354 25364, 11358 30364, 11362 30369, 11362 30369, 11364 30369, 11369 30371, 11370 30373, 15370 30374, 15375 30375, 15378 30377, 14378 30382, 14379 30387, 14383 30382, 14388 30384, 14390 30386, 14393 30389, 14395 31389, 16395 31393, 16398 31398, 16398 31401, 16394 31404, 16397 31409, 16400 31413, 16400 31417, 16399 31419, 16398 31421, 16403 31422, 16403 31426, 16404 31423, 16409 31424, 16413 31423, 16408 31427, 18408 31431, 18413 31436, 18417 28436, 18419 28441, 18420 28445, 18416 28442, 18419 28439, 18418 28443, 18422 28446, 18425 28451, 18429 28448, 21429 28449, 21430 28454, 22430 28459, 22434 28461, 22438 28462, 22443 28462, 22447 28467, 22450 28472, 22453 28469, 22458 28472, 22455 28472, 22460 28475, 22465 28477, 22462 28479, 22461 28476, 22465 28480, 22466 28476, 22470 28472, 22470 28475, 25470 28470, 25473 28472, 25475 28468, 25475 28468, 25477 29468, 25478 29470, 25481 29465, 25478 29466, 25478 29468, 25480 29468, 25485 29465, 25486 29464, 25488 29462, 25488 29466, 25492 29464, 25497 26464, 25500 26467, 25497 26472, 25497 26476, 25497 26476, 25501 26478, 25506 26480, 25506 26482, 25511 26480, 25515 26483, 25516 26485, 25521 26481, 25521 26484, 25520 26485, 25521 26488, 25526 26487, 25529 26488, 25524 26488, 25528 26491, 25530 26496, 25535 26500, 25537 26502, 25537 26502, 25541 26507, 25544 26508, 25545 26509, 25549 26514, 25554 26514, 25553 26512, 25552 26516, 25555 26514, 25559 26514, 25556 26515, 25554 26512, 25558 26509, 25558 26510, 25562 26510, 25562 26511, 25562 26510, 25567 26505, 25569 26508, 25571 26508, 25570 26512, 25573 26512, 25573 26515, 25578 26515, 25583 26520, 25583 26523, 25584 26525, 25587 26526, 25590 26531, 25590 26530, 25586 26534, 25589 26538, 25591 26533, 25595 26537, 25600 26542, 25601 26544, 25601 26544, 25601 26544, 25606 26547, 25605 26547, 25605 26542, 25608 26542, 25611 26544, 25613 26546, 25614 26551, 25614 26551, 25614 26552, 25619 25552, 25614 25552, 25615 25551, 25618 25549, 25618 25553, 25620 25555, 25622 25559, 25622 25555, 25624 25554, 25627 25555, 25624 25559, 25621 25561, 25619 25560, 25624 28560, 25627 28555, 25632 28550, 25636 28552, 25641 28557, 25645 28557, 25640 25557, 25636 25557, 25636 25561, 25641 25561, 25645 25562, 25646 25557, 25648 25560, 25649 25564, 25652 25566, 25652 30566, 25652 30566, 25652 30568, 25652 30570, 25654 30574, 25658 30575, 25663 31575, 25664 31579, 25665 31583, 25664 31583, 25667 31585, 25668 31588, 25673 31586, 25676 31585, 25676 31588, 25678 31588, 25675 31591, 25680 31590, 25681 31585, 30681 31588, 30677 31593, 30682 31594, 35682 31594, 35677 31593, 35679 31595, 35682 31594, 35683 31591, 35686 31592, 35687 31593, 35691 31596, 35691 31597, 35694 31601, 35698 31601, 35702 34601, 35701 34603, 35705 34608, 35705 34610, 35704 34605, 35707 34607, 35707 34610, 35710 34607, 35715 34608, 35719 34607, 35721 34612, 35717 34612, 35713 34612, 35715 34613, 35716 34609, 35716 34614, 35716 34618, 35720 34620, 35721 34621, 35724 34622, 35724 34625, 35727 34629, 35727 34630, 35727 34633, 35727 34635, 35727 34639, 35732 34640, 35729 34642, 35733 34644, 35737 34646, 35741 34649, 35743 34649, 35744 34653, 35740 34653, 35740 34649, 35743 34651, 38743 34654, 38743 37654, 38744 37650, 38748 37655, 38751 37656, 38755 37657, 38755 37661, 38759 37660, 38758 37664, 38763 37664, 38767 37664, 38762 37664, 38761 37664, 38762 41664, 38762 41664, 38764 41669, 38759 41671, 43759 41673, 43754 41678, 43754 41681, 43759 41676, 43760 41681, 45760 41684, 45760 41683, 45764 41687, 45767 41687, 45771 41687, 45772 41688, 45770 46688, 45775 46692, 45778 46696, 45776 46698, 45777 46701, 45780 46699, 45778 46702, 45776 46706, 45781 46706, 45786 46708, 45789 46710, 45793 46715, 45788 46711, 45792 46715, 45795 46719, 45798 46723, 45801 46728, 45799 46732, 45804 46730, 45799 46733, 45803 46737, 45804 46737, 45805 46736, 45806 46736, 45807 46736, 45810 46739, 45812 46744, 45812 46748, 2328 27377, 2324 27381, 2325 27383, 2327 27387, 2327 27386, 2324 27386, 2325 27386, 5325 23386, 5327 23389, 5331 23390, 5332 23394, 5337 23396, 5332 23396, 5332 23399, 5331 23399, 5335 23403, 5335 23406, 5340 23409, 5341 23409, 5336 23410, 5331 23405, 5334 23407, 5332 23411, 5335 23413, 5330 20413, 5326 20415, 5326 20418, 5331 20420, 5330 20425, 5327 20425, 5331 20428, 5332 20428, 5337 21428, 5333 21431, 5335 21435, 5336 21437, 5331 21438, 5332 21441, 5335 21444, 5340 21441, 5340 21444, 5336 21445, 5335 21442, 5331 26442, 5334 26439, 5337 26443, 5339 26444, 5340 26448, 5344 26443, 5344 26446, 5347 26444, 5351 26442, 5354 26446, 5351 26449, 5350 30449, 5352 30451, 5352 30448, 5356 30448, 5361 30447, 5365 30449, 5369 30450, 5369 30452, 5369 30457, 5373 30459, 5373 30457, 5375 30462, 5377 30465, 5382 30467, 5386 30467, 5385 30463, 5386 30463, 5385 30463, 5387 30464, 5392 30463, 5394 30468, 5396 30468, 5391 30469, 5395 30473, 5393 30473, 5393 30473, 5397 30478, 5398 30474, 5401 30474, 5403 30471, 5403 30472, 5406 30474, 5402 30469, 5403 30466, 5405 30471, 5406 30471, 5411 30473, 5414 30477, 5414 30481, 5409 30485, 8409 30490, 8410 30493, 8412 30494, 8412 30493, 8415 30494, 8416 30497, 8416 30500, 8421 30505, 8422 30506, 8417 30511, 13417 30513, 13413 30510, 13416 30511, 13414 30515, 13414 30519, 13419 30522, 13421 30527, 13420 30531, 13424 30533, 13420 30535, 13415 35535, 13411 35535, 13415 35536, 13419 35541, 13421 35537, 13425 35533, 13426 35533, 13425 35528, 13430 35529, 13435 35530, 13440 35534, 13445 35535, 13450 35535, 13454 35536, 13457 35540, 13459 35540, 13454 35540, 13457 35543, 13454 35539, 13459 35544, 13459 35548, 18459 35550, 18462 35551, 22462 35550, 22467 35554, 22468 35558, 22470 35556, 22475 35559, 22473 35563, 22472 35568, 22474 35568, 22472 35573, 22476 35573, 22476 35575, 22479 35577, 22484 35580, 22489 35584, 22490 35587, 22491 35589, 22495 35589, 22498 35589, 25498 35590, 25495 35586, 25496 35589, 25500 35589, 25498 35589, 25500 35591, 25505 35595, 25505 35597, 25501 35594, 25501 35595, 25497 35595, 26497 35599, 29497 35595, 29497 35597, 29500 35601, 29500 35605, 29502 35610, 29503 30610, 29504 30607, 29507 30607, 29512 30610, 29513 30610, 29516 30611, 29518 30614, 29520 30612, 3261 17309, 3265 17308, 3269 17307, 3273 17312, 3271 17316, 3271 17317, 3276 17319, 3279 17319, 3284 17315, 3287 17317, 3285 17313, 3280 17314, 3277 17319, 3277 17321, 3278 17326, 3282 17328, 3282 17328, 3278 17329, 3279 17329, 3278 17332, 3280 17328, 3275 17333, 3279 17335, 3282 17330, 3283 17332, 3278 17328, 3279 17328, 3279 17326, 3279 17325, 3279 17325, 3283 17327, 3284 17331, 3284 17336, 3289 17339, 3290 17339, 3290 17342, 3292 17341, 3296 17344, 3296 17345, 3301 17345, 3301 12345, 3301 12346, 3306 12343, 3303 14343, 3307 14344, 3309 14345, 3313 14347, 3315 14347, 3316 16347, 3312 16345, 3312 16350, 3314 16352, 3313 16353, 4313 16350, 4318 16352, 4323 16348, 4326 16352, 4324 16353, 4325 16350, 4325 16350, 4328 16354, 4324 16358, 4325 16360, 4327 16365, 4327 16362, 4324 16366, 4327 20366, 4327 20370, 4324 20371, 4328 20376, 4328 20378, 4333 20377, 4335 20377, 4340 20380, 4341 20383, 4343 20386, 4340 20388, 4341 20390, 4342 20387, 4342 20387, 4337 20392, 4338 20394, 4343 20394, 4348 20395, 4350 20395, 4351 20397, 37499 26503, 37496 26500, 37498 26504, 37498 26505, 37501 26510, 37499 26506, 37500 26506, 37502 29506, 37502 29511, 37507 29512, 37508 33512, 37510 33517, 37515 33522, 37519 33526, 37518 33524, 37523 33525, 37523 33529, 37518 33534, 37521 33532, 37522 33532, 37526 33534, 37529 33534, 37527 33531, 37530 33534, 37535 33537, 37536 38537, 37538 38540, 22360 13359, 25360 13364, 25363 13362, 25364 13366, 25364 13366, 25367 13369, 25365 13371, 25361 13373, 25359 13378, 25362 13378, 2249 13366, 2254 13370, 2256 13367, 2259 13367, 2263 13362, 2266 13358, 2266 13360, 2271 13365, 2274 13367, 2276 13367, 2277 13367, 2275 13366, 2276 13369, 2280 13369, 2282 13374, 2286 13370, 2286 13369, 2291 13372, 2292 13370, 2295 13372, 2300 13377, 2300 13376, 2297 13379, 273 22351, 275 22354, 4275 22351, 4271 22352, 4272 22354, 4273 22359, 4274 22364, 4278 22367, 4283 22369, 4286 24369, 4281 24369, 4284 24369, 4287 24369, 4289 24368, 4291 24366, 4296 24364, 4297 24366, 4300 24369, 4303 24373, 1303 24374, 1303 24375, 1307 24379, 1307 24380, 1309 24381, 1314 24384, 1316 24386, 1320 24384, 1318 24386, 1318 24391, 1320 24391, 1320 29391, 1323 29391, 1318 29387, 1322 29390, 1323 29393, 1328 29393, 1329 29393, 2329 29398, 2329 29398, 2334 29397, -664 24371, -661 24372, -659 24372, -654 24375, -651 24376, -647 24376, -645 24378, -641 24374, -636 24379, -633 24384, -636 24386, -636 24388, -636 24388, -634 24392, -635 24394, -630 24390, -628 24390, -627 24390, 373 24393, 378 24398, 376 24396, 379 24401, 3379 24404, 6379 24409, 6380 24412, 6375 24410, 6372 24410, 6377 24407, 6372 24407, 6377 24407, 6381 24410, 6376 24413, 6380 24415, 6382 24416, 6380 24419, 6380 24423, 6385 24427, 6387 24429, 6389 24432, 6392 24437, 6388 24434, 6388 24439, 6389 24440, 6390 24444, 6389 24448, 6385 29448, 6385 29451, 6388 29455, 6384 29450, 6389 29451, 6392 29456, 6395 29456, 6399 29459, 6402 29463, 6402 29467, 6399 29471, 6395 29471, 6397 29474, 6399 29477, 6401 29472, 6396 29471, 6399 29474, 6398 29477, 6398 29474, 6395 29469, 6391 29473, 6392 29474, 6391 29469, 6391 29472, 6394 29474, 6390 33474, 6392 33470, 6393 33470, 6394 33471, 6396 33471, 324 22376, 324 22378, 325 22381, 329 22382, 333 22386, 332 22387, 334 22390, 335 22387, 333 22387, 332 22391, 334 22395, 334 22400, 339 22401, 341 22398, 342 22403, 342 22402, 342 22400, 345 22400, 345 22400, 343 22404, 344 22408, 345 22406, 350 22407, 347 22411, 349 22415, 344 22415, 347 22417, 342 22421, 347 22421, 350 22426, 350 22430, 353 22431, 354 22436, 354 22440, 4354 22442, 4355 22446, 4356 22448, 4356 22451, 4359 22453, 4362 22454, 4366 22454, 4369 22455, 4371 22457, 4368 22459, 4371 22457, 4375 22462, 4379 22463, 4382 22463, 4382 22468, 4387 22471, 4387 22471, 4392 22473, 4387 22473, 4387 22476, 25573 26512, 25576 26511, 25580 26516, 25583 26516, 25583 26516, 25585 26512, 25585 26517, 25589 26520, 25591 26519, 25592 26519, 25593 26521, 25591 26524, 25589 26526, 23589 26530, 23587 26535, 23591 26538, 23594 26542, 24594 26547, 24590 26549, 24595 26551, 24600 26547, 24600 26552, 24604 26549, 24600 26544, 24602 26549, 24602 26552, 24602 31552, 24607 31553, 24610 31555, 24615 31556, 24617 36556, 24618 36561, 24621 36561, 24624 36564, 24624 36568, 24629 35568, 24629 35573, 24634 35573, 25634 35574, 25637 35573, 25638 35577, 25638 35577, 25640 35580, 25643 35584, 25643 35587, 25643 35592, 25644 40592, 20644 40597, 20647 40597, 20652 40599, 20653 40595, 20653 40598, 20650 40595, 20650 40595, 20654 40600, 20654 40600, 20658 40601, 20658 40604, 20658 40605, 20661 40602, 20664 40601, 20664 40601, 20665 40604, 20670 40605, 20667 40610, 1217 13318, 1216 13323, 1214 13321, 1211 13316, 1212 13316, 1213 13321, 6213 13324, 6216 13324, 6218 13324, 6213 13327, 6216 13322, 6216 13327, 6216 13328, 6218 13323, 6221 13327, 6220 13325, 6221 13325, 6220 13330, 6223 13333, 6227 13335, 6232 13339, 6233 13343, 6233 13347, 6237 13342, 6236 13346, 6236 13348, 6238 13349, 25526 26487, 25523 26488, 25526 26493, 25529 26491, 25531 26488, 25532 26486, 25536 27486, 25541 27490, 25539 27492, 25543 27487, 25546 27490, 25549 27494, 25552 27495, 25552 27495, 25556 27490, 25561 27490, 25565 27493, 25563 27493, 25565 27497, 25563 27495, 25565 27497, 25565 27499, 25566 27501, 25565 27501, 25565 27501, 25560 27502, 25565 27503, 25567 27507, 25569 27507, 25571 27507, 25569 27508, 25567 27509, 25567 27509, 25567 27509, 25568 27509, 25572 27505, 25572 27501, 25576 27502, 25572 32502, 25572 32505, 25575 32505, 25578 32501, 25578 32502, 25579 32505, 25581 32507, 25585 32508, 25590 32511, 25594 32516, 25598 32511, 25601 32511, 25596 32507, 25599 32510, 25599 32514, 25596 32513, 25596 32514, 25598 32517, 25594 32517, 25596 32519, 25596 32524, 25600 32524, 25604 32521, 25605 32522, 27605 32524, 27609 32527, 27610 31527, 27615 31531, 27617 31531, 30617 31534, 30619 31534, 30620 31536, 30621 31540, 30625 31541, 30625 31542, 30627 31542, 30628 31545, 30629 31545, 30626 31544, 30625 31544, 30626 31549, 34626 31550, 34621 31547, 34625 31549, 34626 31553, 34626 31552, 34628 31554, 34628 31559, 34628 31555, 34630 31559, 34635 31559, 34638 31563, 34636 31568, 34638 31568, 34641 31566, 34641 31564, 36641 31559, 36638 27559, 41638 27561, 41642 27558, 41646 27562, 41649 27563, 41650 27559, 41655 27559, 41660 27559, 41660 27556, 41660 27556, 41662 27554, 41658 27558, 41663 27562, 41666 27565, 41669 27570, 41664 27566, 41665 27567, 41665 27569, 41664 27573, 41663 27573, 41666 27575, 41666 27571, 41661 30571, 41662 30569, 41662 30565, 41667 30570, 41666 30565, 41666 30565, 41666 30566, 41666 30567, 41662 30562, 1314 24384, 4314 25384, 4317 25388, 4317 25389, 4321 25387, 4324 25392, 6324 25391, 6324 25391, 6328 25396, 6323 25401, 6326 25401, 6326 25405, 6321 25408, 9321 25409, 9316 25404, 9314 25406, 9312 25407, 9315 25407, 9315 25407, 9318 25404, 9321 25405, 4321 25400, 8321 25402, 8317 25404, 8317 25400, 8317 25401, 8313 25402, 8309 25398, 8311 25398, 8313 25401, 8317 25406, 8312 25407, 11312 25369, 11313 25369, 11318 25374, 11322 25379, 11327 25379, 11327 25384, 11327 25386, 11328 25382, 14328 25384, 14330 25386, 14333 25387, 14336 25389, 14338 25390, 19338 25390, 19338 25393, 19334 25394, 19334 25395, 19337 25392, 19340 25395, 19344 25397, 19342 25397, 19347 25400, 19347 25398, 19349 25398, 19351 25397, 19353 25401, 19352 25402, 19350 25403, 19351 25407, 19354 25403, 19352 25406, 19356 25404, 19355 25409, 23355 25406, 23356 25406, 23358 25409, 23360 25413, 23362 25417, 23365 25418, 23369 25416, 23367 25415, 23369 25418, 23365 25417, 23369 25420, 23369 25420, 23372 25422, 24372 25418, 24372 25423, 24375 27423, 24380 27423, 24382 27420, 24382 27416, 24382 27414, 24382 27410, 24378 27410, 24376 27414, 24372 27418, 24372 27419, 24373 27424, 24377 27419, 24380 27415, 24377 27419, 24380 27422, 24384 27425, 24385 27430, 24385 27429, 24387 27434, 24392 27435, 24396 27436, 24397 27440, 24401 30440, 24402 30443, 24406 30447, 24405 30443, 24408 30442, 24412 30446, 24408 30450, 24410 30449, 24405 30449, 24410 30446, 24414 30450, 24418 30450, 24418 30453, 19418 30453, 19418 30451, 19420 30456, 19422 30457, 19425 30462, 15425 30466, 15425 30468, 15427 30470, 16427 30471, 16426 30475, 16423 30478, 16428 30478, 16430 30480, 16430 30480, 16426 30478, 16426 33478, 16427 33478, 16429 33481, 16427 33483, 16428 33481, 16424 33484, 16427 33486, 16432 33483, 16432 33482, 16431 33486, 16426 33486, 16429 33488, 16432 33492, 16433 33492, 16436 33492, 16437 33495, 16434 33491, 16438 37491, 16436 37494, 16440 37489, 16445 37486, 16448 37484, 16449 37484, 16449 37486, 16453 37482, 16456 37483, 16460 37483, 16456 37483, 16456 37486, 16461 37490, 16462 37495, 16465 37499, 16466 37496, 16467 37497, 16468 37498, 16470 37501, 16470 37505, 16470 37505, 16475 37507, 16475 37507, 16475 37502, 16478 37498, 21478 33498, 21475 33497, 21478 33493, 21480 33495, 21480 33500, 21480 33496, 21482 33500, 21485 33505, 21486 33508, 21485 33504, 21486 33509, 21486 33509, 21490 35509, 21493 35509, 21496 35510, 21498 35514, 21494 35510, 21494 35513, 21491 35518, 21492 35521, 21489 35523, 23489 35527, 23487 35532, 23489 35537, 23485 35538, 23489 35539, 23490 35541, 23495 35543, 23497 35546, 23497 35550, 23497 35554, 23493 35553, 23490 35556, 23494 35559, 23497 35564, 23502 35563, 23498 35561, 4324 16358, 4319 16362, 4320 16362, 4322 16367, 4317 16367, 4317 16366, 4318 20366, 4322 20369, 4325 20367, 4328 20370, 4331 20371, 4334 20374, 4339 20378, 4340 20379, 4335 20379, 4340 20379, 4343 20381, 4344 20381, 4344 20382, 4345 20385, 4348 20390, 4348 20390, 4348 20390, 4348 20390, 4351 20394, 4354 20399, 4356 20400, 4357 20404, 4360 20404, 4362 20405, 4362 20408, 4365 20409, 4370 20410, 4374 20415, 4373 20420, 4369 20421, 4366 20426, 4369 20424, 4374 20429, 4375 20426, 4376 20422, 4379 20422, 4383 20426, 4384 20427, 4386 20422, 4391 20425, 4387 20427, 4392 20427, 4392 20429, 4394 20433, 4398 20438, 41576 39702, 41580 39706, 41578 39708, 45578 39708, 45577 39713, 45579 39717, 45583 39719, 45583 39722, 45585 39725, 45580 39730, 47580 39726, 47583 39723, 47588 39726, 47588 39730, 47591 39734, 47594 39737, 47599 39737, 47595 39737, 47598 39739, 47599 39739, 47597 39739, 47593 39743, 47595 39748, 47595 39751, 4076 20267, 4079 20272, 4081 20272, 4080 20275, 4080 22275, 4085 22280, 4089 22276, 4090 22279, 4088 22283, 4084 22284, 4086 22286, 4088 22281, 4084 22281, 4089 22285, 4092 22285, 4094 22285, 4094 22290, 4096 22291, 4099 22294, 4099 22295, 4097 22290, 4097 22292, 4097 22297, 4097 22292, 4094 22289, 4091 22290, 4092 22290, 4097 22285, 4102 22290, 4105 22289, 4106 22292, 4106 22293, 4109 22298, 4114 22296, 4119 22294, 4122 22299, 122 22304, 123 22307, 124 22304, 124 22304, 123 26304, 127 26307, 131 26307, 129 26309, 129 26310, 134 26310, 134 26311, 138 26311, 143 26313, 142 26315, 145 26317, 142 26318, 147 26322, 151 26322, 155 26325, 155 29325, 160 29330, 160 29333, 164 29328, 164 34328, 167 34333, 170 34332, 169 34336, 171 34337, 175 34338, 175 34340, 179 34342, 180 34344, 180 34348, 184 34352, 179 34352, 184 34352, 186 34357, 186 34362, 183 34364, 185 34369, 189 34369, 194 34369, 199 34371, 201 34370, 205 34372, 207 34372, 204 34367, 206 34364, 1206 34364, 1207 34368, 1207 30368, 1207 30363, 1208 30365, 1209 30368, 1212 30370, 1212 30370, 1216 30371, 1220 30376, 1221 30379, 1216 30383, 1216 30388, 1219 30386, 1224 30387, 1225 30386, 1227 30384, 1230 30383, 1233 30387, 1234 30387, 1237 30388, 1239 30392, 1244 30390, 1246 30393, 2246 30396, 2243 30399, 2247 30401, 2247 30403, 2246 30398, 2244 30399, 2248 32399, 2248 32399, 2251 32402, 2253 32397, 5253 32394, 5253 32399, 5257 32403, 5257 32401, 5259 32401, 5259 32405, 5263 32410, 5263 32415, 5268 32416, 5273 32420, 5275 32423, 5278 32424, 5283 32426, 5281 32429, 6281 33429, 6286 33433, 6286 33434, 6284 33435, 6284 33432, 6288 33429, 6290 32429, 6290 32425, 6288 32428, 6290 32428, 11290 32431, 11294 32429, 11294 32433, 11292 32438, 11288 32441, 11288 32441, 11285 32446, 11280 32446, 11281 32447, 11285 32449, 11286 32449, 11285 32452, 13285 32451, 13289 32446, 16289 32450, 16284 32449, 16285 32449, 16286 32452, 16287 32452, 16286 32450, 16288 32447, 16292 32450, 16293 32450, 16294 32454, 16293 32454, 16293 32454, 16293 32449, 16289 32451, 16290 32456, 16289 32461, 16293 36461, 16291 36466, 16295 36466, 16296 36466, 16299 36466, 16303 36468, 16308 36473, 16312 36471, 16312 36467, 16315 36463, 16314 36464, 16315 36469, 16315 36473, 16310 36474, 16311 36472, 16316 36474, 16321 41474, 16324 41475, 16327 44475, 16332 44475, 16332 44475, 16332 44477, 16332 44478, 16337 44483, 16334 44481, 8416 30500, 8417 30501, 8421 30501, 8416 30505, 8418 30504, 8420 30499, 8423 35499, 8425 35498, 8429 35501, 8431 35503, 8434 35503, 8438 35507, 8440 35507, 8445 35509, 8442 35512, 8445 35513, 8442 35513, 8442 35515, 8443 35519, 8447 35515, 8450 35516, 8445 35521, 8445 35523, 8444 35528, 8446 35530, 8443 35531, 8438 35531, 8435 35527, 8431 35531, 8432 35534, 8433 35536, 8431 35537, 8435 35539, 8439 32539, 8437 32540, 8441 32540, 8438 32543, 9438 32546, 9436 32541, 9431 32538, 9431 32538, 9435 32541, 9435 32546, 9431 32547, 9436 32542, 9438 32542, 9438 34542, 7438 34542, 7440 34547, 7441 34547, 7441 34547, 7441 34552, 7440 34553, 7440 34556, 7440 34557, 7440 34560, 11440 34565, 11436 34563, 11438 34559, 7438 34557, 7438 34553, 122 1239, 126 1243, 127 1240, 127 1242, 131 1239, 130 1239, 127 1240, 125 1243, 130 2243, 134 2246, 133 2246, 137 2246, 142 2246, 147 2251, 148 2256, 146 2257, 148 2252, 146 2249, 148 2248, 152 2253, 157 2249, 161 2246, 162 2247, 162 2249, 157 2248, 158 2249, 3158 2250, 3161 2252, 3161 2254, 3166 2258, 3167 2261, 3168 2259, 3171 2261, 3173 2266, 3171 2267, 3176 2272, 3179 2277, 3176 2280, 3180 2279, 3175 2283, 3179 2280, 3182 2283, 3184 2288, 3187 2293, 5187 2290, 5187 2292, 5183 2290, 5187 2292, 5186 2297, 5189 2297, 5189 2301, 5192 2303, 5189 2303, 5187 2304, 5183 6304, 5184 6301, 5189 6304, 5191 6302, 5193 6300, 5195 6300, 5195 6300, 5197 6301, 5197 6304, 5199 6301, 5197 6304, 5192 6306, 5193 6310, 5194 6312, 5197 6316, 24397 27440, 24393 27441, 24395 27437, 24400 27440, 24400 27441, 16288 32447, 21288 32447, 21288 32448, 21284 32452, 21285 32450, 21285 32452, 21287 32455, 21283 32460, 21284 32462, 21284 32467, 21284 32472, 21286 32474, 21291 32475, 21289 32475, 21289 32473, 21289 32478, 21286 32481, 21290 32486, 21293 32486, 21293 32490, 21298 32489, 21301 32490, 21303 32491, 21305 32488, 21303 32486, 21307 32491, 21312 32495, 21314 32499, 21315 32495, 21317 32499, 21314 32499, 21316 32502, 21318 32505, 21313 32510, 21313 32512, 21314 32517, 21319 32520, 21321 32520, 21326 32520, 21329 32525, 21330 32530, 21334 32531, 21330 36531, 21333 41531, 21338 41531, 21336 41535, 21339 41537, 21337 41539, 21341 41544, 21342 41544, 21345 41540, 25345 41543, 25342 41546, 25339 41546, 25339 41549, 25337 41546, 25337 41547, 25337 46547, 25341 46552, 30341 46555, 30342 46560, 30345 46561, 30344 46557, 30339 46560, 30343 46565, 30339 46569, 30338 46567, 30340 46568, 24375 27423, 24375 27425, 24377 27428, 24379 27429, 24379 27434, 24376 27439, 24381 27441, 24386 27436, 24387 27438, 24384 27441, 24383 27446, 24383 31446, 24383 33446, 20383 33443, 20385 34443, 20384 34444, 20380 34448, 20383 34450, 20383 34446, 20386 34447, 20390 34450, 20394 34451, 20395 34446, 20395 34451, 20398 29451, 20397 29447, 20401 29447, 20402 29443, 20401 29440, 20406 29443, 20411 29444, 20412 29444, 20412 29448, 20410 29449, 20415 29452, 20415 29455, 20414 29459, 20415 29462, 20420 29465, 20415 29467, 20417 29468, 20418 29468, 20418 29467, 20418 29467, 20420 29468, 20416 29469, 20420 29467, 20415 29464, 20415 26464, 20420 26462, 20423 26463, 20423 26465, 20423 26464, 43580 35662, 43580 35658, 43580 35662, 43580 35664, 43585 35665, 43585 35663, 43585 35666, 43581 35667, 43585 35665, 43589 35670, 25627 25555, 25631 25555, 25632 25558, 25632 25563, 25634 25564, 25629 25565, 25625 25561, 25625 25563, 25626 25565, 26626 25570, 26629 25570, 29629 25575, 29628 25578, 29627 25579, 29624 25583, 29627 25587, 29632 25592, 29634 25593, 29637 25595, 29637 25598, 29639 25602, 29644 25600, 29645 25601, 29646 25601, 29651 25602, 29656 25606, 29658 25606, 29663 25607, 29663 25605, 29666 26605, 29668 26608, 29667 26608, 29670 26611, 29674 26611, 29671 26615, 29673 26620, 29676 26617, 29681 26620, 29682 26620, 29683 26619, 29684 26623, 29681 26621, 29686 26626, 29688 26628, 29691 26628, 29692 26632, 29693 26634, 29695 26629, 29696 26624, 29700 26621, 29705 29621, 29709 29620, 29708 29624, 29711 29627, 34711 29630, 34712 29632, 34712 29631, 2284 16415, 2285 16416, 2285 16416, 2289 16421, 2294 16425, 2299 16425, 2300 16430, 2305 16430, 2306 16433, 2311 11433, 2315 11436, 2310 14436, 2310 14435, 2313 14437, 2312 14441, 2310 14442, 2311 14444, 2313 14444, 2311 14447, 2314 14447, 2316 14451, 2316 14456, 2316 14454, 2311 14455, 2311 14455, 2311 14460, 2315 14465, 2315 14465, 2311 19465, 2311 19465, 2313 19466, 2317 19469, 2320 19469, 2323 19466, 2319 19468, 2323 19471, 2324 19471, 2324 19473, 2324 19473, 2322 19468, 2323 19466, 2324 19465, 2329 19470, 2329 19465, 2324 19465, 2324 19467, 2319 19471, 2320 19475, 2104 -1844, 2109 -1844, 2113 -1842, 2116 1158, 2116 1160, 2117 1161, 2116 6161, 2118 6166, 2123 6169, 2126 6174, 2123 6179, 2126 6183, 2126 6187, 2130 6182, 2128 6183, 2127 6182, 2128 6185, 2124 10185, 2129 10190, 2130 10193, 2132 10192, 2132 10195, 2129 11195, 2129 11199, 2133 11200, 2134 11196, 2133 11201, 2137 11205, 2137 11207, 2141 11203, 2144 11207, 2145 11208, 2149 11212, 2144 11214, 2144 11215, 2149 11216, 2152 11221, 2152 11223, 2153 11223, 2154 11226, 2154 11226, 2150 11228, 2152 11224, 2152 11227, 2148 11222, 2145 11223, 2142 11225, 2145 11222, 2142 11223, 2142 11227, 2147 11229, 2149 11230, 2154 11230, 2157 11228, 2159 11233, 2159 11233, 2155 11237, 2155 11242, 2151 11243, 7151 10243, 7156 10245, 7159 10245, 7164 10247, 7166 10252, 7166 10255, 7171 10257, 7173 10257, 7174 10261, 7179 10264, 7184 10260, 7189 10264, 7193 8264, 7197 8260, 7202 8262, 7206 8262, 7205 8265, 7205 8266, 7207 8270, 7211 8274, 7211 8277, 7216 8277, 7216 8280, 7212 8280, 7213 8280, 7215 8283, 7220 8282, 7224 8287, 7225 8283, 7222 10283, 7223 10287, 7225 10288, 7230 10290, 7232 10294, 7233 10294, 7233 10297, 7234 10298, 7234 10301, 7236 10303, 7231 10299, 7228 10298, 7223 10297, 7225 10299, 7230 10303, 7231 10307, 7234 10311, 7234 10315, 7235 10320, 7236 9320, 7241 9322, 7246 9325, 7243 9330, 7243 9332, 7240 9335, 7237 9334, 7239 9339, 7238 9339, 7238 9341, 7238 9342, 7233 14342, 7232 14337, 7234 14342, 7239 18342, 4084 22284, 4083 22284, 6083 22287, 6078 22289, 6078 22293, 6080 22290, 6082 22291, 6086 22296, 6086 22297, 6087 22297, 6088 22295, 6093 22298, 6094 22297, 9094 22294, 9097 22298, 9098 22299, 9098 22301, 9093 22296, 9098 22299, 9100 22294, 9096 18294, 9099 18294, 9098 18298, 9101 18296, 9100 18301, 9105 18303, 9105 18306, 9105 18309, 9102 18305, 9104 18306, 9108 18309, 9104 18314, 9103 18310, 9105 18312, 9105 18316, 9109 18314, 9109 18319, 9109 18324, 9113 18326, 9113 18330, 9115 18333, 9113 18333, 9118 18333, 9123 18333, 9123 18336, 9125 18335, 9126 18336, 9127 18332, 9129 18329, 9127 18332, 9130 18333, 9135 18333, 9138 18337, 9143 18341, 9144 18346, 9145 18344, 9150 18348, 9154 18345, 9152 18350, 9151 18345, 9151 18345, 9156 18347, 9160 18349, 9163 18350, 9163 18351, 9165 18356, 9166 18356, 9164 18353, 9167 18356, 9167 18355, 9167 18356, 9167 18360, 9165 18356, 9169 18357, 9169 18353, 9170 18355, 9170 18351, 9175 18351, 9177 18351, 9181 18352, 9184 18353, 9189 18356, 9188 18361, 9191 18364, 9194 18364, 9198 18366, 13198 18371, 13198 18373, 13198 18375, 13201 18378, 13196 18378, 13199 18379, 13202 18381, 13207 18384, 13212 18388, 13211 18383, 13211 18378, 13215 18379, 13218 20379, 13214 20379, 13217 20379, 13213 20379, 13213 20376, 13210 20377, 13206 20377, 13206 20373, 13207 20373, 13209 20370, 13214 20371, 13218 20371, 13223 20376, 13224 20381, 13227 20385, 13228 20390, 13232 20387, 9232 20392, 9230 20388, 9230 20390, 9225 20393, 9225 20396, 4225 20401, 4225 20400, 4227 20403, 4224 20408, 4222 20412, 4222 20415, 4225 20420, 4229 20425, 4232 20422, 4236 20425, 4234 20426, 4238 20427, 4240 20427, 4241 20427, 4237 20431, 4233 20431, 4232 20430, 4230 20432, 4234 20431, 4234 20435, 4238 20437, 4243 20435, 4243 22435, 4238 22440, 4241 22441, 4241 22443, 4238 22447, 4234 22443, 4238 22448, 4238 22450, 4241 22451, 4241 22456, 4243 22458, 4247 22461, 4247 22464, 4252 22466, 4253 22469, 4255 22469, 4251 22469, 4253 22464, 4253 22468, 4257 22473, 4259 22477, 4258 22482, 4261 22483, 4262 22484, 4259 22489, 6259 22493, 6262 22494, 6262 22497, 6264 22500, 6264 22504, 6269 22499, 6273 22499, 6278 22495, 6278 22493, 6283 22491, 6288 22494, 6291 22494, 6296 22494, 6296 22493, 6294 22489, 6294 22493, 6290 22493, 6290 22498, 6290 22500, 6288 22501, 6290 22505, 6294 22504, 5294 22507, 5294 22507, 5298 22512, 5297 22514, 5302 22514, 5307 22517, 5304 22518, 5308 22514, 5311 22517, 5315 27517, 5315 27517, 5319 27517, 5324 22517, 5328 22521, 6328 22520, 6325 22522, 6325 22527, 6322 22527, 6323 22530, 6325 22535, 6325 22535, 6326 22536, 6326 22536, 6327 22533, 6323 22535, 6325 22538, 6330 22538, 6331 22534, 6326 22531, 10326 22526, 10321 22528, 10317 22524, 10316 22529, 10313 22529, 10309 22530, 10306 22535, 10308 22531, 10308 22532, 10311 22534, 10314 27534, 10314 27538, 10314 27538, 10309 27540, 10309 27536, 11309 27535, 11309 27537, 11310 27539, 11305 27535, 11300 27536, 11296 27538, 11296 27538, 11301 27542, 11299 27546, 11304 27551, 11308 27551, 11313 27553, 11315 30553, 11319 30555, 11315 30550, 11318 30545, 11318 30544, 11321 30549, 11320 30550, 11325 30554, 11328 30558, 11328 34558, 11332 34562, 11333 34562, 11335 34562, 11334 34565, 11330 34565, 11333 34566, 11338 34566, 11338 34571, 11342 34574, 11344 34573, 11347 34572, 11346 34573, 11347 34575, 11351 34578, 15351 34578, 15356 34573, 15361 34570, 15364 34575, 15365 34580, 15369 34581, 15370 34581, 15373 34585, 15376 34580, 15381 34578, 15385 34583, 15386 34588, 15389 34587, 17389 34582, 17394 34582, 17393 34582, 17398 34577, 17399 34582, 17399 34584, 17399 39584, 17404 39588, 17399 39591, 17404 39591, 17408 39586, 17405 39591, 17409 39593, 17411 39596, 17408 39596, 17411 39599, 17411 39603, 17414 39607, 17418 39612, 17419 39612, 17419 39612, 17423 39611, 17424 39613, 17426 39612, 17429 39608, 17427 39609, 17428 39613, 17425 39615, 17424 39614, 17427 39617, 17430 39622, 17430 39623, 17431 39620, 17434 39620, 13434 39619, 13434 39621, 13434 39621, 13434 44621, 13436 44625, 13436 44627, 13441 44631, 13444 44636, 13444 44639, 13442 44635, 13444 44635, 13447 44639, 13449 44643, 13447 44641, 13447 44642, 13452 44643, 13456 44648, 13459 44648, 13461 44646, 15461 44643, 15459 44648, 15463 44648, 15464 44646, 15461 44649, 15461 44651, 15465 44654, 15460 44655, 15461 44657, 15463 44661, 15465 44665, 15465 44665, 15465 44667, 15469 44670, 15474 44672, 15476 44668, 15472 44672, 15473 44674, 15475 44678, 15477 44679, -3804 12302, -3802 12305, -3803 13305, -3802 13300, -3806 13296, -3807 13299, -3804 13304, -3802 13301, -3799 13305, -3799 13306, -3794 18306, -3799 18310, -3797 18315, -3800 18315, -3797 18316, -3799 18318, -3794 18323, -3793 18326, -3789 18325, -3784 18324, -3784 18325, -3782 18325, -3780 18325, -3779 18328, -3780 18329, -3781 18324, -3786 18328, -1786 18328, -1786 18333, -1782 18337, -1782 18338, -1779 18333, -1775 18338, -6775 18341, -6772 18343, -6774 18345, -6779 18345, -6777 18345, -6777 18347, -6777 18343, -6775 18347, -6780 18342, -6777 18345, -6776 18345, -6774 18340, -6774 18337, -6774 18337, -6778 18342, -6782 18342, -6785 18339, -6784 18340, -6779 22340, -6779 22339, -6776 22335, -6775 22330, -6775 22335, -6775 22339, -6770 22339, -6772 22344, -6767 22345, -6765 22341, -6765 22339, -6765 22339, -6765 22337, -6765 22340, -6760 22335, -6757 22335, -6762 22336, -6763 22338, -6765 22343, -6760 22338, -6758 22338, -6758 22338, -6756 22341, -6752 22345, -6752 22346, -6748 22343, -4748 22347, -4745 22347, -4750 22347, -4749 22348, -4747 22349, -4743 22352, -4738 22357, -4734 22362, -4736 22367, -4738 22362, 21338 41531, 21336 41531, 21332 41530, 21332 41530, 21335 41533, 21330 41533, 21331 41534, 21328 41536, 21330 41536, 21326 41541, 21330 41536, 21332 41539, 21336 41536, 21338 40536, 21336 40540, 21341 40538, 21343 40538, 21346 40538, 21348 40536, 21352 40536, 21355 40539, 21359 40543, 21361 40546, 21362 40550, 21357 40550, 21362 40551, 21361 40554, 21358 40555, 21358 40554, 21359 40554, 21363 40558, 21360 45558, 21364 45560, 21368 45557, 21372 45561, 21376 45560, 21379 45557, 22379 45553, 22384 45553, 22384 45556, 22388 45561, 22389 45561, 22390 45557, 22394 45561, 24394 45565, 22394 45562, 22399 45565, 22401 45562, 22400 45565, 22402 45568, 22402 45573, 22406 45577, 22408 45581, 22408 45585, 22406 45585, 22409 45586, 22411 45583, 22411 45579, 22411 45583, 22409 45583, 22404 45586, 22404 45586, 22406 45591, 22408 45591, 22408 45593, 22413 45593, 22415 45594, 22419 45595, 22419 45596, 22424 45591, 22427 45587, 22430 50587, 22430 50589, 22430 50589, 22432 50592, 22437 50594, 22437 50589, 22437 50594, 22441 50599, 22442 50594, 22447 50591, 22444 50588, 22444 50590, 22445 54590, 22445 54594, 22448 54599, 22450 54601, 22450 59601, 22446 59597, 22451 59600, 22451 59603, 22454 59604, 22459 59604, 22460 59609, 22459 59606, 22464 59607, 22465 59608, 22463 59609, 22460 59606, 22459 59605, 22459 59605, 22457 59609, 25457 59610, 25459 59615, 25464 59617, 25466 59618, 25469 59621, 25474 59616, 25478 59617, 25480 59614, 25484 59619, 25484 59620, 25488 59616, 25485 59618, 25489 59623, 25494 59627, 25499 59629, 148 2256, 152 2253, 152 2253, 154 2258, 159 2253, 160 2257, 159 2256, 163 2259, 161 3259, 163 3262, 163 3259, 165 3259, 170 3263, 170 3263, 174 3267, 169 3271, 174 3275, 174 3276, 174 3278, 177 3282, 181 3286, 183 3287, 186 3284, 187 3286, 189 3286, 193 3288, 194 3290, 193 6290, 195 6293, 200 6289, 197 6294, 196 6293, 197 6293, 201 6297, 202 6292, 200 6294, 204 6295, 209 6300, 214 6305, 217 6305, 218 6305, 213 6308, 214 6308, 218 6313, 218 6308, 216 6312, 215 6312, 213 6309, 214 6313, 219 6318, 222 6321, 226 6326, 224 6331, 222 6327, 41575 39716, 41574 39713, 41578 40713, 41582 40718, 41578 40721, 36578 40721, 36579 40723, 36584 40720, 36587 40725, 36592 43725, 36587 43725, 36584 43728, 36587 43733, 36592 43735, 36592 43734, 15291 11311, 15287 11316, 15288 11319, 15291 11319, 15296 11319, 15297 11320, 15298 13320, 38744 37650, 38745 37654, 38747 37659, 38746 37662, 38741 37663, 38739 37666, 38744 37666, 38747 37661, 38750 37666, 38750 37666, 38754 37671, 38755 37671, 38750 37673, 38750 37672, 38754 37677, 38756 37678, 38758 37680, 38760 37678, 38762 37683, 38762 37679, 38760 37679, 38765 37679, 38769 37678, 38774 40678, 38769 40683, 38774 40687, 38776 44687, 38780 44690, 38782 44694, 38782 44694, 38781 44699, 38784 44704, 38782 44699, 38777 44700, 38777 44700, 38777 44700, 38781 44703, 38785 44700, 38786 44700, 38788 44696, 38788 44696, 38788 44700, 38793 44702, 38795 44703, 38797 44707, 38802 44712, 38805 44712, 38809 44713, 38804 44710, 38808 44712, 38811 44713, 36811 44713, 36816 44708, 36815 44709, 36816 44709, 36818 44713, 36813 44716, 36814 48716, 36813 48721, 36817 48725, 36818 51725, 36820 51721, 36824 51724, 40824 51719, 40829 51716, 40832 51720, 40831 51723, 40834 51727, 40837 51728, 40842 51725, 40843 51725, 40838 51729, 40843 51734, 40848 51738, 40850 51742, 40851 51744, 40853 51747, 40856 51749, 40857 51750, 40859 51754, 40859 51750, 40863 51752, 40868 51755, 40864 51754, 40868 51754, 40871 51756, 40867 51756, 40865 51759, 40860 51761, 40857 51757, 40857 51762, 40854 51762, 40855 51764, 40859 51765, 40857 51761, 40854 51764, 40855 51765, 40857 51766, 40860 51761, 40861 51760, 40865 51761, 40865 51763, 40862 51768, 40861 51768, 40856 51772, 40852 51769, 40854 51771, 40854 51771, 40850 51776, 40854 51780, 40856 51782, 40854 51782, 43854 51782, 43856 52782, 43858 52785, 43861 52785, 43861 52780, 37514 26540, 37519 26535, 37522 26539, 37522 26544, 37524 26548, 37529 26548, 37534 26553, 37539 26548, 37542 26553, 37547 26548, 37551 26551, 37551 26554, 37550 26555, 37551 26557, 37548 26557, 37548 26557, 37551 26560, 37551 26563, 37554 26563, 37558 26568, 37562 26563, 37563 26565, 37567 26569, 41567 26569, 41571 26572, 41573 26577, 41573 26577, 41578 29577, 41573 29577, 41575 29580, 41575 29582, 46575 29582, 46571 29586, 45571 29587, 45574 29587, 45570 29587, 45575 29585, 45577 29582, 45573 29585, 45574 29588, 45574 29589, 45578 29589, 45580 29592, 45583 29595, 45584 29597, 45584 29602, 45586 29601, 45591 29604, 45587 29609, 45591 33609, 45595 36609, 45596 36611, 45601 36613, 45602 36608, 45606 36608, 45606 36612, 45606 36611, 45610 36614, 50610 36617, 50613 36613, 50616 36613, 50621 36609, 50626 36609, 50627 36610, 50627 36609, 50631 36610, 50626 36612, 50627 36614, 50628 36614, 50631 36612, 50629 36614, 50630 36618, 50634 36622, 46634 34622, 46634 35622, 46638 35626, 46638 35621, 46639 35624, 46641 35623, 46645 35624, 46647 35629, 46645 35634, 46650 35639, 46650 35644, 46651 35647, 46653 35651, 46657 35654, 46654 35659, 46659 35660, 46660 35661, 46664 35664, 46661 35667, 46664 35668, 46667 35667, 46669 35671, 46669 35667, 46672 35670, 46674 35675, 46676 35675, 47676 35672, 47678 35676, 47679 35677, 47679 35682, 47679 35681, 47679 35681, 47679 35686, 47674 35687, 47673 35687, 49673 35689, 49676 35693, 49679 35696, 49677 35696, 54677 35701, 54680 35703, 54676 35703, 54672 35705, 54672 35704, 54677 35707, 54678 34707, 54678 34707, 54681 34710, 54685 34712, 54690 34710, 54690 34711, 54687 34706, 54689 34706, 54694 34711, 54689 36711, 54689 36710, 54684 36711, 54687 38711, 54682 38714, 54682 38718, 54679 38718, 54681 38723, 54684 38724, 54689 38720, 54690 38721, 54694 38726, 54699 38730, 54701 38731, 54702 38728, 54704 38724, 52704 38723, 52704 38723, 52704 38725, 52704 38729, 52706 38730, 52708 38732, 52709 38733, 52713 38732, 52713 35732, 52715 35737, 52714 35741, 52714 35743, 52715 35746, 52715 35749, 52710 35749, 52712 39749, 52715 39753, 52718 39752, 52723 39753, 52722 39757, 52718 39760, 52718 40760, 47718 40761, 47719 40765, 47724 40765, 47724 40765, 47724 40770, 47728 40773, 47730 40776, 47735 40781, 47733 40777, 50733 40781, 51733 40783, 51735 40786, 51736 40790, 51739 40788, 51743 41788, 51741 41787, 51741 41789, 51741 41789, 51738 41793, 51733 41793, 52733 41794, 52737 41795, 52740 41794, 52744 41793, 52748 41789, 52749 41789, 52747 41789, 52752 41786, 52755 41790, 52755 41791, 52760 41796, 52756 42796, 52751 42797, 52754 42798, 52758 42795, 52759 42794, 52764 42797, 52768 42801, 52768 42801, 52771 42806, 52776 42810, 52776 42809, 52773 42811, 52776 42811, 52772 42812, 52773 42815, 52769 42815, 52768 42816, 52769 42821, 52773 42821, 52773 42821, 52777 42819, 52781 42815, 52781 42816, 52782 42819, 52778 42822, 52776 42822, 52779 42826, 52782 42827, 52783 42831, 52778 42833, 52782 42836, 54782 42839, 54782 42844, 2137 11205, 2142 11207, 2139 11208, 2142 11213, 2144 11217, 2149 11215, 2147 11217, 2147 11217, 2152 11222, 2152 11225, 2155 11229, 2159 13229, 2164 13232, 2169 13235, 2173 13236, 2169 13233, 2170 13237, 2173 13241, 2175 13243, 2170 13238, 2170 13239, 2175 13239, 2177 13238, 2179 13239, 2179 13238, 2181 13233, 2181 13230, 2182 13230, 2179 13230, 2179 13235, 2182 13235, 2183 10235, 2178 10237, 2179 10236, 2182 10239, 2187 10241, 2184 10244, 6184 10244, 6186 10248, 6184 10246, 6185 10247, 6187 10250, 6192 10248, 6196 10248, 6196 10251, 6194 10251, 6194 10256, 6197 10260, 6196 10264, 6197 9264, 6197 9264, 6197 9268, 6201 9273, 6206 9276, 6201 9272, 6203 9272, 6205 9269, 6210 9272, 6206 9274, 6206 9279, 6203 9283, 6203 9285, 6203 9290, 6208 9285, 6208 9281, 6204 9285, 6202 9289, 6204 9292, 6200 9294, 7200 9297, 7202 9301, 7203 9301, 7207 9302, 7211 9302, 7211 9303, 8211 9306, 8216 10306, 8220 10310, 8224 10312, 8228 10317, 8233 10317, 8237 10322, 8239 10322, 8239 10327, 8235 10330, 8235 10331, 8239 10329, 8240 10332, 8240 10334, 8236 10334, 11236 10336, 11238 10337, 11243 10341, 14243 10342, 14242 10342, 14239 10343, 14240 10341, 14239 10343, 14244 10343, 14248 10343, 14252 10343, 14252 10343, 14253 10341, 14256 10341, 14258 10338, 14258 10336, 14254 10340, 14257 10344, 14261 10346, 14264 10351, 11150 3163, 11155 3167, 11156 3166, 11156 3169, 11160 3171, 11163 3176, 11164 3179, 11164 3180, 11168 3183, 11168 3185, 11173 3189, 11178 3184, 11180 3183, 11178 3185, 11181 3187, 11176 3186, 52778 42822, 52780 42826, 52779 42826, 52784 42821, 52785 42826, 52786 42827, 52791 42830, 52791 42827, 56791 42832, 56788 42833, 56788 42836, 56791 42840, 56791 42839, 56787 42842, 56788 42847, 51788 42848, 51790 42850, 51792 42851, 51796 42846, 51798 42846, 51803 42850, 53803 42853, 53808 42853, 53811 42856, 53814 42854, 53819 42850, 53819 42852, 53820 42857, 53824 42860, 53825 42858, 53828 42862, 53827 42864, 53828 42864, 53828 42868, 53832 42872, 53837 42877, 53841 42877, 53843 42876, 53843 42880, 53843 42883, 53843 42888, 53838 42892, 53838 42893, 53838 44893, 53835 44893, 53837 44897, 53840 44901, 53844 44901, 53846 44904, 53846 44908, 53847 44909, 53852 44907, 53855 44908, 53860 44910, 53858 44911, 53863 44913, 53858 44917, 53860 44920, 53865 44920, 53870 44922, 53869 43922, 53871 43925, 53871 43923, 53869 43923, 53864 43922, 53862 43927, 53866 43932, 53871 43934, 53876 43937, 53876 43936, 53876 43936, 53877 43934, 53879 43932, 53880 43928, 53885 43931, 55885 43933, 55885 43929, 55881 43933, 55883 43933, 55886 43932, 55883 43932, 55884 43933, 55885 45933, 55885 45937, 55885 45940, 55886 45945, 55886 45945, 55888 45950, 55884 45952, 55885 45956, 55890 45960, 55892 45961, 55896 45957, 55894 45958, 55899 45954, 55895 45958, 55898 45960, 55894 45959, 55899 45963, 55901 45965, 55901 45965, 55896 45966, 55900 45961, 55895 49961, 55898 47961, 55896 47960, 55900 47964, 55903 47968, 55903 47971, 55903 47974, 55898 47977, 55900 47973, 55896 47978, 55897 47979, 55893 47980, 55898 47983, 55901 47988, 55904 47987, 55899 47991, 55901 47993, 55906 47996, 55906 47997, 55907 48001, 55904 48005, 55904 48007, 55909 48004, 55912 48002, 55917 48003, 55913 47998, 55908 48002, 55912 48007, 55916 48004, 55920 48004, 55916 48004, 55921 48004, 55923 48007, 55923 48011, 55926 48011, 55921 48014, 55924 48009, 55929 48013, 55930 48012, 55930 48012, 55932 48016, 55927 48016, 55927 48020, 54927 48018, 54924 48022, 54924 44022, 54928 44017, 54931 44016, 54934 44020, 55934 44021, 55937 44021, 55938 44024, 55939 44026, 55938 44024, 55941 44019, 55946 44022, 55947 44026, 55949 44027, 55952 44028, 55955 44024, 55958 44027, 53869 43923, 53873 43925, 52873 43925, 53873 43927, 53878 43927, 53883 43927, 53882 43931, 53884 43935, 53888 43940, 53886 43941, 53881 43938, 53881 43941, 53879 43943, 53880 43942, 53881 43946, 53882 43951, 53883 43952, 53886 45952, 53886 45953, 53884 45957, 53885 45958, 53880 45960, 53882 45957, 53887 45962, 53887 45962, 53888 45961, 53888 48961, 53888 48966, 53893 48966, 53894 48968, 53899 48969, 49899 48966, 49904 48969, 49908 48971, 49904 48971, 49906 48975, 49903 48971, 49906 48974, 54906 48975, 54906 48975, 54906 48979, 54911 48983, 54909 48979, 54912 48979, 54908 48975, 54911 48977, 54913 48979, 54917 48982, 54922 48982, 54925 48985, 54920 48988, 54923 48988, 56923 48988, 56928 48990, 56926 48985, 56931 48984, 56934 48983, 56934 48981, 56938 48983, 56939 48985, 56939 48986, 61939 48988, 61939 48984, 61936 51984, 61937 51985, 61937 51988, 61937 51988, 61933 51990, 5331 23399, 5333 23399, 5335 23394, 5339 23396, 5342 23399, 5347 27399, 5347 27401, 5352 27402, 5357 27403, 5358 27406, 6358 27409, 6362 27411, 6363 27410, 6366 27406, 6368 26406, 6373 26406, 6373 26406, 6374 26409, 6372 26409, 6377 26410, 6382 26415, 6387 26417, 6389 26418, 6390 26423, 6392 26423, 6393 26428, 6395 30428, 6392 30433, 6392 30436, 6392 30434, 6396 30438, 6396 30441, 6396 30445, 6398 30446, 6400 30443, 6401 30440, 6406 30439, 6407 30439, 6402 30439, 6407 30444, 6406 30447, 6407 30451, 6411 30451, 6413 30451, 6414 30452, 6419 30450, 6423 30454, 6420 30452, 6419 30448, 6420 30453, 6422 30455, 6427 30460, 6428 30460, 6427 30462, 6428 30462, 6428 34462, 6429 34463, 6434 39463, 6436 39466, 6436 39471, 6441 39474, 6445 39471, 6446 39472, 6451 39477, 6453 39480, 6454 39485, 6454 39483, 6454 39480, 8454 39480, 8458 39482, 8462 39484, 10462 39486, 10457 39486, 10458 39488, 10462 39488, 10465 39488, 10470 39490, 10475 39486, 10477 39488, 10477 39490, 10478 39492, 10479 39496, 10477 39498, 10482 39503, 10478 39505, 10481 39510, 10482 39514, 10477 39512, 10482 39517, 10483 39520, 10483 39520, 10487 39525, 10489 39526, 10492 39527, 10492 39524, 10495 39524, 10498 44524, 10493 44523, 10493 44528, 10494 44524, 10499 44529, 10501 44529, 10504 44531, 10502 44535, 10504 44539, 10508 44539, 10513 44536, 13513 44540, 13515 44537, 13512 44539, 13509 44544, 13513 44547, 13517 44552, 13519 44553, 13524 44554, 13527 42554, 13522 42555, 13524 42557, 13527 42556, 13531 42561, 13531 42562, 13526 42563, 13527 42563, 13527 42566, 13522 42568, 13525 42571, 15525 42573, 15525 42576, 15526 42581, 15531 42581, 15532 42586, 15534 42588, 15534 42592, 15533 42591, 15533 42596, 15532 42591, 15532 42587, 15535 42587, 15538 47587, 15534 47587, 15537 47591, 15536 47594, 15538 47598, 11538 47594, 11535 47594, 11531 47594, 11535 47596, 11535 47596, 11535 47597, 11539 47602, 11540 47607, 11540 47607, 11540 47609, 11543 47613, 11546 47617, 14546 47618, 14541 47614, 14539 47614, 14539 47618, 14537 50618, 14539 50623, 14541 50623, 14542 50627, 14540 50627, 14539 50623, 25601 26544, 25601 26545, 25601 26548, 25596 26546, 25601 26547, 25598 26548, 25599 26547, 25600 26547, 25595 26548, 25590 26546, 25595 26549, 25597 26548, 25598 26548, 25601 26545, 25596 26548, 25594 26553, 25595 26552, 25599 26553, 25598 26554, 25596 26555, 25592 26554, 25596 26558, 25599 26554, 25600 26556, 25595 26559, 25600 22559, 25601 22561, 25606 22563, 25607 22562, 25608 22566, 25607 22563, 25607 22568, 30607 22573, 30612 22575, 30612 22579, 30611 22579, 30611 22580, 30611 22585, 30607 22585, 30612 22587, 30612 22588, 30615 22583, 30615 22585, 30618 22581, 30621 22581, 30623 22584, 30623 22589, 30628 22594, 30630 22597, 30631 22602, 30628 22607, 30630 22610, 30631 22611, 30631 22608, 30629 22610, 30634 22612, 30635 22612, 30638 22616, 30643 17616, 30644 17618, 30649 17618, 30653 17619, 30656 17614, 30657 17611, 30660 17615, 30655 17614, 30656 17610, 30656 17611, 30661 17610, 30662 17615, 30660 17620, 30661 17620, 30666 17623, 30667 17625, 30667 17624, 30669 17625, 30673 17628, 30675 17628, 30675 17628, 30680 17631, 30677 17636, 30677 17639, 30680 17644, 30683 17647, 30688 17643, 30693 17645, 30698 19645, 30701 19644, 30702 19644, 30698 19649, 30700 19647, 30701 19649, 30704 19650, 30705 19653, 30701 19655, 30706 19652, 30708 19656, 30711 19657, 30711 19659, 30711 19659, 30714 19661, 30710 19662, 30707 19664, 30702 19666, 30703 19667, 30708 19668, 30713 19667, 30709 19671, 30706 19674, 30710 19676, 30711 19677, 30713 19677, 30713 19678, 30715 19682, 30720 19686, 30725 20686, 30723 20690, 30727 20695, 30728 20697, 30731 20699, 30730 20694, 30732 20696, 30735 20698, 30738 20696, 30738 20695, 30742 20698, 30743 20699, 30743 20701, 30748 20704, 30749 20706, 30752 20705, 30753 20702, 30755 24702, 30751 24705, 30750 24707, 30748 24708, 30749 29708, 30749 29709, 30751 29711, 30754 29716, 30759 29716, 30762 34716, 30762 34720, 30765 34720, 30761 34717, 30761 34721, 30765 34721, 30760 34721, 30759 34725, 30762 34730, 30760 34730, 30765 34731, 30765 34731, 30766 34731, 30761 34733, 30761 34736, 30764 34738, 30759 34739, 30763 34740, 30761 34740, 30764 34742, 30759 34737, 30762 34739, 30764 34741, 30762 34740, 30767 34737, 32767 34741, 32770 34741, 32767 34744, 32767 34746, 32770 34751, 32774 34755, 32774 34756, 32779 34753, 32784 34755, 32785 33755, 32785 33750, 36785 33753, 36785 33758, 36788 33760, 36789 33759, 36789 33762, 36793 33758, 36798 33758, 36803 33760, 36803 33762, 36803 33766, 36804 33769, 36804 33769, 36808 33774, 33808 33776, 33808 33781, 33811 33781, 33816 33784, 33816 33789, 33820 33786, 33823 33788, 33828 33785, 33824 33785, 33826 33787, 33824 33788, 33828 33791, 33825 33796, 33829 33799, 33830 33802, 33831 33803, 33835 33805, 33835 33805, 33838 33809, 33841 33813, 33844 33809, 33849 33814, 33847 32814, 33849 32812, 33851 32816, 33853 32819, 33851 32822, 33851 32826, 33849 32826, 33849 32830, 33852 32835, 33856 32840, 33859 32837, 33858 32832, 33861 32833, 33862 32836, 33859 32838, 33859 32834, 33857 32834, 33859 32834, 33857 32838, 33861 32833, 33861 32837, 33864 32840, 33866 32841, 33866 32843, 33868 32841, 33871 32839, 33874 32844, 33876 37844, 33881 37849, 33883 37854, 33883 37859, 33888 37860, 33893 37864, 33898 37864, 33895 37867, 33896 38867, 33898 38863, 28898 38868, 28901 39868, 33901 39873, 33898 39875, 33900 39879, 33904 39877, 33904 39879, 33909 39883, 33914 39888, 33910 39891, 33910 39892, 33907 39894, 33911 39899, 33913 39900, 33910 39904, 33914 39905, 33917 39906, 33917 39906, 33917 39906, 33912 39911, 33912 39908, 33916 39907, 33914 39910, 33918 39913, 33922 39913, 33924 39916, 33925 39920, 33930 39920, 33933 39922, 33934 39923, 33937 39919, 33938 39916, 33936 39913, 35936 39918, 35933 39919, 35937 39921, 35941 39924, 35941 39919, 35942 39915, 35946 39920, 35946 39915, 35946 39912, 35947 39908, 35947 39912, 35947 39916, 35952 39919, 35957 39921, 38957 39920, 38962 39925, 38964 39924, 38964 39924, 38969 39926, 38969 39928, 38972 39932, 38977 39932, 38975 39932, 38979 39935, 38982 39938, 38986 39940, 38984 39943, 38985 39946, 38987 39947, 38989 39949, 38994 41949, 38990 41954, 38991 41958, 38994 41962, 38994 41966, 38994 41969, 38995 41974, 38999 41974, 38999 41974, 38996 41978, 38996 41983, 38999 41983, 39001 41986, 38996 41984, 39000 41989, 39000 41988, 5336 23410, 5332 23410, 5327 23407, 9327 23408, 12327 23412, 12327 23412, 12324 23410, 13324 23415, 13327 23420, 13328 23416, 13324 23418, 13329 23423, 13330 23426, 13331 23429, 13335 23426, 13339 23428, 23493 35553, 23492 35548, 23496 35550, 23501 35552, 23497 35553, 21497 35557, 21492 35560, 21494 35562, 21494 35560, 21496 35563, 21496 35568, 21496 35570, 21501 35570, 21504 35566, 21504 35571, 17504 35572, 17508 35577, 17509 35578, 17513 35582, 17514 35587, 17515 35592, 18515 35595, 18516 35596, 18517 35598, 18515 35600, 16515 35605, 16515 37605, 16515 37606, 16513 37608, 16515 37613, 16516 37615, 16520 37620, 16524 34620, 16526 34617, 16530 34619, 16530 34624, 16535 34628, 16537 34631, 16540 34632, 16541 34634, 16541 34635, 16544 34632, 16544 34637, 16546 34642, 16549 38642, 16549 38644, 16545 38649, 16545 38644, 16542 38644, 16545 38644, 16544 38645, 16548 38650, 16543 38653, 16543 38649, 18543 38652, 18546 38652, 18546 38657, 18546 38660, 18551 38655, 18549 38655, 18552 38660, 18549 38662, 23549 38667, 23546 38668, 23550 38672, 23550 38674, 28550 38676, 28551 38673, 28551 38677, 28547 38673, 28551 38674, 28556 38674, 28559 38678, 28562 38673, 28564 38678, 28564 38673, 28563 38673, 28566 38675, 28571 38675, 38781 44703, 38782 44699, 38780 44702, 38785 44704, 38787 44704, 38783 44705, 38784 44700, 38788 44695, 38791 44696, 38796 44696, 38801 44692, 38801 44697, 38805 44701, 38810 44701, 38808 44701, 38808 44704, 38805 44706, 38805 44710, 38804 44711, 38809 48711, 38810 48711, 38808 48711, 38812 48716, 38812 48713, 38812 48715, 38812 48715, 38808 48711, 38804 48714, 38805 48710, 38807 48715, 38812 48715, 38807 48713, 38811 48714, 38811 48714, 38816 48711, 38817 48707, 38818 48707, 38818 48708, 38822 48708, 38824 48713, 38822 48714, 38820 48718, 38824 48720, 38824 48723, 38829 48726, 38830 48731, 38834 48729, 38832 48734, 38833 48730, 38834 48728, 38831 48732, 8433 35536, 8433 35541, 4433 35536, 4436 35541, 4440 35541, 4441 35537, 4445 35539, 4444 35534, 4447 35531, 4451 35531, 4455 35534, 4460 35534, 4461 39534, 4462 39535, 4463 39535, 4466 39535, 4470 39535, 4472 39538, 4467 39538, 4467 39536, 4471 39536, 4473 39541, 4468 39542, 4472 39543, 4475 39544, 4478 39544, 4482 39547, 4487 39552, 4485 39550, 4486 39551, 4486 39553, 4486 39555, 4488 39557, 4488 39558, 4489 39555, 4485 39557, 4488 39558, 4492 39560, 4495 39561, 4500 39565, 4496 39566, -4747 22349, -4750 22349, -4746 22352, -4742 22355, -4738 22360, -4739 22362, -4737 22365, -4732 22363, -4728 25363, -4728 25364, -4723 25364, -4725 25364, -4725 25365, -6725 25364, -6727 25369, -6728 25369, -6725 25369, -6729 25368, -6728 27368, -6725 27370, -6721 27371, -3721 27367, -3717 27372, -3718 27375, -3716 27370, -3715 27373, -3714 27373, -3712 27376, -3709 27374, -3710 27375, -3710 27374, -3708 27379, -3706 27381, -3705 27386, -3704 27389, -3704 27393, -3703 32393, -3702 32396, -3702 32396, -3697 32395, -3697 32399, -3692 32403, -3692 32404, -3693 32408, -3693 32412, -3691 32414, -3691 32414, -3695 32414, -3690 32417, -3689 32422, -3684 32424, -3681 32429, -3679 32424, -3676 32428, -3671 32428, -3674 32431, -3671 32430, -3669 32430, -3674 33430, -3676 33432, -3674 33432, -3677 33432, -3677 33437, -3675 33438, -3674 33442, -3679 33444, 1321 33448, 1323 33445, 1327 33448, 1331 33443, 1328 33448, 1328 33443, 1329 33443, 1329 33444, 1334 33448, 1335 33453, 1340 33457, 1340 33454, 1345 33454, 1349 33458, 1348 33461, 1348 33459, 1344 33463, 1343 33466, 1348 33466, 1349 33467, 1345 33467, 1346 33466, 1350 33461, 1349 33464, 1354 33468, 1358 33472, 1363 33473, 1365 33472, 1367 33473, 1370 33476, 1371 33479, -2629 33482, -2631 33487, -2627 33490, -2630 34490, -2626 36490, -2623 36492, -2619 36492, -2622 36492, -2620 36496, -2622 36495, -2627 36495, -2625 36500, -2621 36503, -2626 36506, -2629 36510, -2624 36510, -2620 36510, -2620 36513, -2617 36518, -2622 36516, -2619 36514, -2617 36514, -2617 36512, -2615 36516, -2613 36516, -2613 36517, -2613 36515, -2613 36510, -2610 36511, -2607 36515, -2604 37515, -2604 37512, -2608 37509, -2605 37512, -2600 37516, -2597 37516, -2593 37514, -2595 37515, -2590 37519, -2595 37518, -2590 37523, -2590 37528, -2590 37530, -2592 37525, -2592 37520, -2589 36520, -2586 36521, -2587 36517, -2584 36518, -2582 36518, -2581 36520, -2577 36518, -2576 36522, -2576 35522, -2573 35523, -2575 35523, -2576 35528, -2576 35533, -2576 35536, -2576 35538, -2578 35541, -2582 35545, -2584 35546, -2585 35548, -2583 35544, -2583 35548, -2582 35547, -2578 35552, -2574 35554, -2569 35557, -2565 35559, -2563 35564, -2558 35564, -2555 35568, -2551 35568, -5551 36568, -5546 36568, -5542 36569, -5545 36569, -5543 36574, -5540 36569, -5541 36570, -5541 36572, -5541 36574, -5538 36579, -5535 36581, -5533 36585, -5530 36584, -5526 36579, -5524 38579, -5524 38580, -5524 38575, -5520 38575, -5516 38580, -5512 42580, -5508 42585, -5510 42587, -5510 42586, -5505 42586, -5508 42589, -2508 42593, -2509 42596, -2506 42598, -2504 42601, -2501 42602, -2501 42607, -2496 42612, -2499 42615, -2498 42620, -2500 42617, -2500 42620, -4500 42620, -4500 42624, -4500 42626, -4504 42623, -4507 42625, -4509 42628, -4513 42629, -4508 42629, -4505 42632, -4500 42628, -4499 42633, -4503 45633, -4501 45634, -4497 45635, -4494 45634, -4495 45632, -4493 45634, -4492 46634, -4489 46638, -4485 46633, -4481 46635, 21338 40536, 21343 40537, 21348 40538, 21348 40540, 21347 40540, 21348 40540, 21347 40540, 21346 40542, 21349 40547, 21350 40547, 21353 40544, 21353 40546, 21350 40549, 21353 40550, 21354 40550, 21355 40550, 21360 40550, 21361 40549, 21361 40554, 21359 40559, 21364 40564, 21366 40559, 21365 40559, 21366 40564, 25366 40568, 25367 40570, 25370 40570, 25373 45570, 25374 45571, 25374 45566, 25378 45568, 25383 42568, 25387 42564, 25391 42568, 25391 42572, 25395 42576, 25392 42576, 28392 42573, 28391 42574, 28387 42578, 28388 42580, 28391 42581, 31391 42582, 31387 42586, 31389 42586, 31392 42582, 31393 42583, 31394 42580, 29394 42584, 29398 42586, 29400 43586, 29404 43588, 29408 43589, 29409 43591, 29413 43596, 29415 43598, 29416 43599, 25416 43604, 25414 43599, 25417 43603, 25422 43606, 25420 43608, 25425 43603, 25428 43603, 25431 43606, 25436 42606, 25431 42608, 25434 42604, 25437 42609, 25438 47609, 25442 50609, 25443 50614, 25441 50618, 25446 50621, 25449 50625, 25446 50628, 25446 50630, 25447 50631, 25452 50636, 25452 50632, 25453 50634, 25453 50636, 25456 50637, 25460 50641, 25464 50645, 25465 50644, 25465 51644, 25469 51648, 25471 51653, 25475 51654, 25476 51657, 25477 51658, 26477 51662, 26477 51666, 26476 51669, 26478 51669, 26483 51665, 26485 55665, 26487 55668, 30487 55671, 30487 55674, 30491 55675, 30491 55672, 30493 55674, 30494 55674, 30495 55679, 30499 55679, 30503 55675, 30505 55680, 30502 55681, 30500 55676, 30496 55679, 30501 55680, 30502 55680, 30507 55685, 30503 55688, 30498 55689, 30502 55689, 30504 55691, 30508 55696, 30509 55697, 30508 55696, 30513 55697, 30518 55698, 30516 55703, 30516 55705, 30514 55705, 34514 55709, 34518 55712, 34522 55708, 34520 56708, 34521 56708, 34522 56710, 34519 56710, 34517 56705, 34521 59705, 34524 59710, 34524 59712, 34524 59717, 34528 59719, 34530 59721, 34535 59716, 34540 59719, 34540 59721, 34543 59721, 34548 59724, 34550 59725, 34554 63725, 34549 63730, 34551 63732, 34556 63730, 34558 63730, 34559 63725, 34558 63729, 34563 63734, 34560 63734, 37560 63729, 37563 63733, 37567 63728, 37571 63724, 37575 63722, 37580 63726, 37579 63722, 37581 63724, 37581 63726, 37582 63723, 37582 63724, 37581 63728, 37576 63729, 37576 63731, 37578 63729, 37583 63733, 37585 63736, 37588 63736, 37592 63741, 37594 63738, 37599 63735, 37602 63734, 37598 63735, 37598 63737, 37602 63737, 37603 63739, 37598 63739, 37593 63736, 37598 63737, 37603 63742, 37604 63737, 37601 63742, 37596 63744, 37600 63748, 37605 63749, 37607 63751, 37609 63756, 37609 63760, 37605 63761, 37605 63765, 37606 63765, 37610 63762, 37611 63766, 37606 63768, 37606 63768, 41606 63769, 41602 63765, 41601 63765, 41602 63770, 41598 63770, 41601 63770, 41603 63774, 41606 63772, 41610 63772, 41613 63776, 41616 63771, 41611 63767, 41614 63769, 41617 63764, 38617 63768, 38617 63772, 38620 63772, 35620 63773, 35620 63778, 35619 63779, 35620 63780, 35615 63779, 35617 63784, 35614 63786, 35615 63783, 35616 63779, 35620 63778, 35621 63780, 35626 63782, 35626 63784, 35631 63789, 35631 63784, 35628 63785, 35626 63786, 35631 63788, 35636 63791, 35640 63786, 35636 63787, 35636 63782, 35635 63781, 35640 63786, 35643 63790, 35646 63795, 35650 63797, 35649 63797, 35651 63801, 35655 63805, 35656 63808, 35656 63808, 35658 63808, 35657 63810, 35660 63814, 35660 63809, 35664 63809, 35659 67809, 35660 67812, 35662 67815, 35666 67812, 35662 67807, 35660 67807, 35663 67807, 35665 67812, 35668 67814, 35672 67818, 35671 67817, 35671 67820, 37671 67824, 37666 67824, 2277 13367, 2280 16367, 2276 16367, 2277 16366, 2281 16366, 2284 16366, 2289 16370, 2286 16370, 4286 16370, 4288 16375, 4292 16379, 4296 18379, 4297 18381, 9297 18385, 9298 18385, 9301 18386, 9305 18383, 9307 19383, 9310 19379, 8310 19384, 8314 19384, 38748 37655, 38751 37656, 38756 37657, 38759 37660, 38755 37665, 38755 37665, 38760 37667, 38765 37668, 38765 42668, 38770 42670, 38767 42672, 38772 42668, 38769 42663, 38770 42663, 38775 42658, 38773 42663, 38777 42665, 41777 42667, 41780 42669, 41783 42673, 41784 42671, 41781 42673, 41786 42676, 41783 42676, 41785 42676, 41782 42676, 41785 42679, 41786 42679, 41790 42680, 41794 42681, 41794 42679, 41795 42684, 41795 42680, 41798 42685, 41803 42689, 41806 42688, 41808 42689, 41806 42694, 41804 42696, 41807 42700, 41802 42701, 41804 42702, 41806 42704, 41811 42708, 41815 42709, 36815 42712, 36815 42708, 36812 42707, 36813 42709, 40813 42710, 40817 46710, 40818 46712, 40822 46712, 40820 46716, 40824 46721, 40827 46724, 40831 46728, 40829 46731, 40833 46731, 40835 46735, 40831 46737, 40832 46737, 36832 46742, 36832 46745, 36836 46748, 36833 46753, 36828 46752, 36824 46752, 36826 46755, 36821 46759, 36825 46762, 36825 46766, 36826 46770, 36824 46773, 36828 46776, 36833 46778, 36830 42778, 36835 42780, 36835 42781, 36840 42786)')));
-BEGIN;
-DELETE FROM t1 WHERE p = 3;
-UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
-UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
-ROLLBACK;
-connection con1;
-# disable purge
-CREATE TABLE t0 (a INT) ENGINE=InnoDB;
-BEGIN;
-SELECT * FROM t0;
-a
-connection default;
-DELETE FROM t1 WHERE p = 3;
-UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
-UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
-ALTER TABLE t1 ADD INDEX prefix_idx (g(767));
-connection con1;
-# enable purge
-COMMIT;
-connection default;
-DELETE FROM t1 WHERE p = 2;
-# wait for purge to process the update_undo records.
-CREATE TABLE t2 (
-p INT PRIMARY KEY,
-g1 POINT NOT NULL,
-g2 POINT NOT NULL,
-g3 LINESTRING NOT NULL,
-g4 LINESTRING NOT NULL,
-g5 GEOMETRY NOT NULL,
-g6 GEOMETRY NOT NULL,
-SPATIAL KEY (g1),
-SPATIAL KEY (g2),
-SPATIAL KEY (g3),
-SPATIAL KEY (g4),
-SPATIAL KEY (g5),
-SPATIAL KEY (g6)
-) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
-DROP TABLE t2;
-DROP TABLE t1;
-DROP TABLE t0;
-CREATE TABLE t1 (
-p INT NOT NULL AUTO_INCREMENT,
-g LINESTRING NOT NULL,
-PRIMARY KEY(p)
-) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
-ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
-ALTER TABLE t1 ADD INDEX prefix_idx (g(767));
-INSERT INTO t1(g) VALUES(ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)'));
-INSERT INTO t1(g) VALUES(ST_linefromtext(concat('linestring','(18 106,19 106,24 111,27 108,32 104,37 107,42 107,44 112,44 116,40 118,43 114,46 114,42 118,44 123,45 123,49 123,53 119,50 123,50 124,54 126,58 125,59 126,64 127,65 127,69 131,74 132,75 135,78 139,2078 141,2075 143,2077 143,2079 143,2084 143,2085 147,2090 -1853,2086 -1852,2086 -1856,2089 -1852,2093 -1850,2090 -1851,2090 -1852,2091 -1851,2092 -1850,2097 -1847,2102 -1848,2100 -1852,2100 -1852,7100 -1851,7103 -1850,7104 -1847,7109 -1842,65 127,67 131,66 131,61 132,61 133,62 137,65 1137,2065 1135,2061 1135,2064 1135,5064 1135,5066 1135,5070 1136,5070 1141,5071 1138,5074 1141,5075 1141,5074 1137,5076 1137,5071 1139,5066 1142,5065 2142,5068 2147,5073 2151,5069 2156,5071 2157,5072 2162,5074 2165,5069 2169,5072 2169,5076 2173,5074 2169,5078 2169,5076 2170,76 2175,74 2179,75 2184,80 2188,83 2190,87 2189,84 2193,87 2189,86 2190,87 2195,87 2200,87 1200,85 1202,86 1199,87 1200,87 1201,91 1206,92 1204,94 1204,98 1206,102 1208,105 1211,102 1216,105 1220,109 1224,110 1224,114 1225,117 1224,118 1229,117 1232,122 1237,123 1236,120 1235,124 1237,121 1236,122 1240,126 1244,127 1246,126 1249,125 5249,123 5251,127 5251,131 5251,135 5256,138 5257,135 5257,139 5257,138 5258,141 5260,146 5260,146 5260,143 10260,147 10265,151 10270,156 10266,157 10269,162 10273,166 12273,168 12274,163 12270,168 12275,170 12277,170 12277,-3830 12277,-3825 12277,-3824 12278,-3825 12276,-3825 12278,-3822 12277,-3825 12275,-3829 12278,-3828 12275,-3824 12280,-3827 12280,-3826 12282,-3822 12283,-3822 12286,-3820 12288,-3818 12289,-3816 12294,-3817 12297,-3819 12300,-3816 12297,-3813 12295,-3811 12299,-3811 12297,-3806 12298,-3806 12298,-3804 12301,-3801 12306,-3803 17306,-3803 17306,-3798 17306,-3803 17310,-3801 17314,-3798 17317,-3797 17317,-797 17321,-797 17323,-796 17325,-793 17326,-792 17322,-789 17327,-784 17331,-780 17335,-776 17339,-774 17339,-771 17342,-770 17345,-765 17348,-765 17349,-763 17353,-760 17350,-760 22350,-756 22346,-752 22349,-748 22352,-752 22348,-748 22347,-746 22345,-745 27345,-743 27346,257 27350,260 27349,261 27352,266 27348,266 22348,269 22347,271 22347,272 22347,273 22348,273 22352,278 22348,279 22344,282 22345,282 22342,283 22347,283 22347,288 22349,292 22347,292 22348,293 22348,298 22348,303 22351,306 22352,309 22352,308 22354,310 22356,311 22361,311 22358,311 22360,311 22360,315 22356,320 22358,325 22363,326 22366,321 22371,318 22373,318 22375,314 22375,316 22375,321 22376,321 22376,322 22372,32 104,36 109,40 114,40 113,40 117,44 119,49 123,49 126,49 129,53 133,50 137,50 139,49 137,48 138,43 138,42 139,46 142,46 138,41 139,45 141,4045 5141,4045 5146,4042 5147,4043 10147,4041 10150,4042 10152,4045 10152,4041 10156,4041 10152,4041 10152,4046 10153,4049 10156,4046 10155,4051 10157,4055 10159,4055 10160,4056 10161,4055 10166,4054 10169,4054 10172,4054 15172,4051 15176,4047 15177,4049 15174,4047 15176,4047 15176,4046 15177,4046 15180,4043 15184,4043 15187,4038 15190,4040 15194,4040 15199,4045 15196,4047 15197,4050 15200,4050 15204,4050 15208,4047 15212,4047 15215,4049 15216,4046 15218,4042 15223,4042 15228,4042 15232,4047 15235,4050 15236,4050 15239,4051 15243,4053 15243,4050 17243,4052 17243,4052 18243,4057 18247,4061 18249,4064 18249,4067 20249,4067 20250,4067 20255,4066 20259,4066 20259,4067 20255,4069 20256,4071 20258,4072 20254,4067 20257,4067 20260,4069 20265,4065 20267,4069 20266,4070 20267,4071 20264,4074 20259,4070 20264,4073 20260,4074 20263,4077 20268,4082 20271,4084 20273,4084 20277,4081 18277,4085 18279,4086 18276,4087 18273,4087 18275,4092 18277,4093 18279,4093 18280,4095 18280,4091 18283,4092 18281,4094 18283,4090 18287,4094 18287,138 5257,138 5255,138 5258,-1862 5254,-1860 5256,-1856 5258,-1851 5255,-1850 5260,-1847 5260,-1847 5263,-1847 5258,-1850 5257,-1850 5259,-1851 5257,-1855 5258,-1853 5261,-1849 5261,-1849 5258,-1849 5259,-1845 5264,-1847 5264,-1850 5268,-1852 5266,-1853 5270,-1856 5265,-1852 5262,-1847 5263,-1842 5263,-1842 5260,-1842 5265,-1841 5265,-1844 5265,-1842 5270,-1837 5274,-1838 5279,-1843 5275,-1842 5280,-1838 5281,-1838 5285,-1833 5285,-1828 5288,-1824 5289,-1828 5291,-1831 5291,-1826 5291,-1830 5293,-1826 5296,-1822 5301,-1826 5302,-1826 5302,-1826 5302,-1825 5297,-1820 5299,-1816 5303,-1816 5299,-3811 12299,-3809 12302,-3806 12302,-3806 12302,-3803 12304,-3798 12304,-3797 12304,-3793 12306,-3788 12306,-3783 12309,-3816 12294,-3811 12299,-3809 12297,7100 -1851,7098 -1854,7102 -1854,7107 -1856,7107 -1858,7110 -1854,7110 -1851,7113 -1851,7115 -1851,7120 -1851,7123 -1847,7124 -1852,7125 -1852,7127 -1852,7131 -1852,7129 1148,7129 1145,7133 1150,7137 1148,7138 1147,7143 1149,7147 1154,8147 1155,8152 3155,8147 3157,8143 3158,8144 3160,8144 3164,11144 3167,11146 3167,11148 3163,11152 3161,11148 3159,11149 3163,11150 3161,11151 3166,11154 3171,11154 3170,8144 3160,8144 3163,8144 3166,8145 3166,8146 3171,8146 3174,8144 3174,8144 3174,8145 3176,8141 3180,3141 3182,7141 3183,7141 7183,7136 7185,7136 7185,7133 7187,7136 7187,7131 7190,7136 7194,7137 7197,7141 7196,7139 7199,12139 7200,12143 7200,12143 7199,12144 7203,12145 7200,12141 7200,12136 7195,12136 7191,12137 7191,12137 7196,12139 7197,12140 7197,12137 7201,12140 7204,12140 7209,12143 7209,12145 7210,12147 7214,12148 9214,12152 9218,12149 9218,12149 9221,12149 9220,12150 9222,12153 10222,12153 10226,12156 10227,12159 10223,12160 10220,12161 10225,12161 10227,12163 10224,12163 10223,12158 10224,12158 10227,12158 10231,12155 12231,12157 12226,7136 7185,7139 7189,7139 7189,7139 7188,7137 7191,7139 7191,7140 7189,7143 7191,7144 7189,7144 7190,7149 7193,7152 7194,7154 7198,7153 7203,7148 7207,12148 7209,12146 7209,12145 7213,12140 7217,12139 7219,12141 7219,12138 7218,12143 7218,13143 7220,13140 7224,13142 7228,13137 7231,13142 7235,13146 7239,13149 7243,13148 7247,13150 7248,13155 7249,13155 7253,13155 7253,13155 7258,13157 7260,13162 7255,13159 7255,13163 7258,13164 7258,13164 7263,13167 7264,13167 8264,13165 8265,13169 8265,13171 13265,13175 13261,13176 13259,13176 13259,13180 13262,13181 13262,13183 13262,13188 13265,13191 13267,13191 13265,13194 13267,13191 13269,13192 13264,13196 13269,13198 13272,13200 13272,13202 13270,13207 11270,13211 11270,13211 11273,13213 11274,13217 11275,13222 11276,13222 11272,13226 11274,13231 11277,13233 11282,13236 11284,13238 11284,13236 11286,13236 11288,13236 11283,13236 11284,13238 11289,13241 11292,13244 11292,13245 11289,13241 11294,13244 11298,13249 11301,320 22358,324 24358,328 24358,327 24363,326 24359,327 24361,329 24365,334 24367,-666 24367,-670 24368,49 123,46 127,46 129,49 131,49 136,47 135,45 138,3045 135,3042 138,3044 139,3044 144,3049 144,3053 142,3055 137,3058 136,3053 139,3048 142,7048 138,7048 3138,7048 3139,7048 3140,7050 3145,7053 1145,7050 1146,7053 5146,7048 5150,7047 5146,10047 5147,10043 5147,10047 5147,10050 5152,10052 5155,10054 5156,10056 5157,10056 5159,10058 5162,10062 5164,10062 5169,10066 9169,10068 9168,10063 9164,10063 9169,10061 9171,14061 9172,14061 9174,282 22342,287 22347,288 22347,288 22343,285 22339,280 22338,278 22341,279 25341,284 25343,13241 11294,13246 11296,13243 11296,13244 11291,13245 11291,13244 11291,13246 11295,13251 11300,13253 11305,13253 11306,13258 11305,13255 11306,13256 11309,13256 11311,13261 11307,13265 11303,13267 11305,13270 11301,13275 11298,13271 11300,15271 11302,15276 11306,15279 11303,15284 11305,15286 11305,15289 11307,15290 11302,15292 11305,15296 11309,15297 11313,15298 11316,15300 11317,15304 11320,15306 11324,15306 11320,15307 11320,15312 11320,15313 11319,15317 11317,15315 11321,15317 11323,15317 11328,15319 11333,15322 11336,15322 11337,15322 11337,15324 11341,15324 11345,15325 14345,15328 13345,17328 13346,17333 13349,17337 13354,17338 13358,17342 13358,17346 13353,17348 13353,17345 13353,17348 13354,17347 13354,17347 13354,17347 13355,22347 13358,22349 13355,22351 13355,22356 13354,22358 13354,22361 13355,22362 13355,22358 13355,22359 13359,22364 13364,22369 13369,22372 13373,22376 13371,22377 13371,22377 13369,22381 13374,22386 13379,22387 13376,22387 13380,22392 13378,22390 13374,22392 13378,22391 13378,22391 13375,22392 13378,22390 13380,22393 13382,22398 13387,22398 10387,22402 10391,22399 10392,22400 10392,22400 10394,22404 10391,22403 15391,22405 15392,22407 15392,22412 15387,22412 15390,22412 15394,22408 15396,26408 15398,26407 20398,26411 20402,26415 20406,26417 20411,26420 20407,26422 20407,31422 16407,31421 16405,31421 16410,31423 16410,31426 16414,31426 16410,31430 16415,31430 16418,31435 16419,31437 16420,31438 16422,31438 16425,31438 16425,31441 16427,31439 16431,31441 16436,36441 16436,36443 18436,36442 18437,36440 18440,36440 18436,36440 18440,36442 18445,36443 18446,36447 18451,37447 23451,37452 23456,37456 23455,37458 23459,37456 23461,37458 23463,37460 23466,37464 23469,37460 23474,37462 23476,37461 26476,37466 26479,37470 26483,37471 26488,37474 26489,37474 26485,37474 26483,37474 26488,37470 26492,37474 26497,37474 26499,37478 26495,37483 26499,37483 26501,37488 26496,37491 26499,37495 26495,37500 26496,37500 26497,37500 26501,37497 26499,37497 26499,37495 26504,37498 26504,37494 26509,37497 26514,37495 26515,37498 26514,37503 26514,37508 26512,37510 26516,37511 26519,37509 26523,37506 26528,37507 26532,37512 26536,37513 26538,37510 26542,37512 26544,37517 26543,37522 26546,37527 26551,37525 26555,37529 26558,37524 26563,37524 26562,37527 26562,37522 26562,37522 26559,37526 26561,37522 26559,37523 26561,37523 26556,37524 26558,40524 26560,40524 26563,40521 26567,40525 26566,40527 26568,40532 26572,40534 26569,40533 26565,40531 26565,40535 26569,40535 26570,40539 26572,40544 26575,40543 26575,40544 26579,40548 26584,40549 26581,40553 26585,40556 26590,40552 22590,40557 22594,40556 22595,40561 22592,40561 22593,40565 22593,40568 22593,40573 22588,40570 22590,40570 22591,40570 22588,40573 22590,40573 22593,40568 22593,40567 22597,40567 22599,40571 22599,40574 22600,40574 22604,42574 22607,42577 22607,42577 22612,42579 22616,38579 22619,38580 22617,38580 22614,38575 22619,38579 22619,38579 18619,38582 18614,38582 18617,38586 18622,38590 18625,38590 18622,38594 18621,38596 18616,38597 18614,38597 18618,38600 21618,38601 21618,38605 21620,38607 25620,38611 25620,38608 25617,38608 25621,38608 25625,38611 25623,38615 25623,38615 25620,38616 25622,38619 25624,38620 25625,38620 26625,38623 26627,38623 26627,311 22358,311 22359,-1689 22360,2311 27360,2312 27360,2312 27360,2317 27362,2317 27362,2319 27359,2319 27364,2318 27359,2321 27364,2326 27367,2325 27371,2326 27373,2326 27373,2325 27377,2329 27377,2327 27377,2330 27379,2333 27379,2331 27379,2331 27381,2336 27381,6336 27382,6336 27383,40527 26568,40531 26572,40533 26574,40538 26576,40533 26580,40538 26585,40539 26588,40536 26583,40540 26587,40539 26588,40535 26593,40540 26594,40544 26597,40548 26602,40548 26601,40549 26602,40547 26602,40548 26603,40553 26606,40548 26606,40548 26603,40551 26608,40556 26612,40559 26616,40554 26619,40556 26619,40556 26623,42556 26623,42556 26624,42560 26624,42562 26626,42563 26630,42564 26630,42564 26634,42559 26635,42562 26635,42565 26637,42562 26638,42564 26642,42564 26641,42568 26641,42572 26641,42572 29641,42574 29642,39574 29641,39574 34641,39576 34643,39581 34638,39578 34638,39574 34642,39574 34645,39572 35645,34572 35648,34577 35651,39577 35655,43577 35659,43580 35655,43575 35658,43578 35658,43581 35662,43577 39662,43572 39658,43572 39661,43572 39664,43572 39666,43576 39670,43577 39667,43580 39671,43576 39673,43573 39673,43574 39677,43569 39679,43567 39679,43568 39683,43563 39686,43566 39690,43566 39692,43568 39694,43568 39695,41568 39691,41570 39692,41571 39692,41571 39693,41571 39698,41571 39698,41574 39698,41569 39698,41570 39699,41570 39704,41572 39709,41573 39712,41578 39713,41579 39717,41584 39719,41585 39720,-1850 5268,-1845 5268,-1847 5266,-1842 5268,-1840 5263,-1845 5264,-1843 5264,-1839 8264,-1839 8267,-1839 8272,-1838 8276,-1834 8273,-1834 8273,-1833 8274,-1837 8279,-1836 8283,-1834 8286,-1836 8282,-1834 8279,-1835 8279,-1834 8280,-1836 8283,-1841 8288,-1846 8289,-1843 8286,-1838 8286,-1841 8285,-1838 8285,-1834 8288,-1829 8291,-1825 8286,-1825 8289,-1825 8287,-1824 8291,-1822 8294,-1821 8298,-1818 8300,-1818 8296,-1814 8296,-1811 8295,-1808 8292,1192 8296,1192 8297,1195 11297,1192 11301,1195 11305,1197 11300,1193 11300,1193 11296,1193 11293,1194 11294,1199 11292,1204 11292,1205 11294,1210 11292,1208 11288,1204 11290,1205 11289,1207 8289,1202 8284,1204 8282,1204 8281,1206 8281,1208 8281,1212 8283,1212 13283,1213 13287,1213 13290,1216 13293,1214 13289,1217 13286,1212 13291,1208 13288,1208 13292,1209 13297,1208 13296,1204 13298,1205 13303,1209 13308,1204 13308,1209 13304,1210 13304,1214 13309,1214 13314,1215 13314,1219 13314,1219 13319,1224 13320,1229 13321,1232 13325,1233 13329,1231 13329,1234 13334,-2766 13336,-2769 13337,-2765 13340,-2762 13345,-2760 13342,2240 13342,2238 13342,2242 13342,2246 13345,2246 13346,2244 13348,2239 13348,2240 13351,2240 13352,2245 13357,2248 13357,2243 13362,2247 13362,2248 13362,2252 13363,2256 13363,2256 13363,2260 13367,2255 13372,2251 13369,2251 13369,2252 13372,2249 13376,2254 13378,2255 13382,2259 13379,2262 13379,2267 13381,2262 13381,2262 13383,2265 13383,2269 13385,2270 13386,2271 13389,2267 13391,2271 13386,2275 13391,2273 13392,2275 13387,2277 13390,2274 13390,2275 13394,2280 13395,2280 11395,2281 14395,2279 14400,2277 14403,2273 14406,2274 16406,2274 16410,2279 16410,2284 16411,2280 16409,2280 16409,2282 16409,2282 16411,2282 16412,2280 16413,3280 16418,3284 16418,3285 16423,3289 16423,3292 16427,3294 16429,3296 16431,3297 16436,3298 16435,3303 16435,3305 16434,3305 16436,3305 16436,3309 16437,3309 16438,3308 16439,3308 16439,3306 16444,3302 16441,-1698 16437,-1703 16438,-1699 16438,-1697 16438,-1698 16439,-1695 16436,-1690 16441,-1687 16446,-1683 16450,-1682 16451,-1684 16453,-1682 16457,-1682 16457,-1686 16460,-1681 16459,-1680 16456,-1677 16460,-1681 16461,-1679 16464,-1674 16465,-1673 16469,-1669 16471,-1669 16476,-1665 16474,-1665 16478,-1664 16478,-1664 16479,-1661 16474,-1656 16471,-1655 11471,-1660 11473,-1663 11475,-1666 11480,3334 15480,3338 15476,3342 15471,3345 15471,3345 15470,3350 15469,3347 15474,3351 15476,3352 15473,3353 15476,3350 15477,3350 15479,3351 15482,3352 15484,3351 15487,3353 15487,3358 15487,3353 15486,1217 13286,1222 13291,1222 13291,1225 13286,1229 13286,1231 13281,1235 13280,1236 13281,1241 13282,1245 13285,1247 13285,1247 13287,1250 13287,1247 13290,1247 13295,1247 13298,1252 13301,1249 13304,1252 13304,3252 13304,3247 13304,3249 13308,3254 13308,3257 13308,3261 17308,3261 17309,3261 17306,3259 17305,3262 17310,3263 17308,3262 17311,3259 17314,3259 17314,3257 17309,3254 17309,3253 17309,3255 17310,3253 17312,3255 17312,3255 17312,3256 17307,3257 17307,3256 17311,3256 17313,3255 17317,3251 17317,3248 17321,3253 17325,3256 17326,3258 17324,3258 17327,3263 17322,7263 17325,7265 17328,7263 17330,7265 17333,7270 17333,7273 17333,7278 17336,4278 21336,4278 21340,4279 21340,4281 21340,4286 24340,4290 24343,9290 24347,9294 24349,9296 24347,9298 25347,9301 25348,9301 25348,9304 25353,9303 25357,9303 25352,11303 25355,11304 25358,11307 25358,11312 25358,11312 25361,11310 25365,11313 25365,11314 25369,11319 25371,11321 25371,11325 25366,11329 25365,11330 25366,11329 25370,11330 25365,11334 25367,11338 25366,11343 25363,11348 25359,11345 25356,11348 25357,11349 25358,11349 25358,11352 25360,11356 30360,11360 30365,11360 30365,11362 30365,11367 30367,11368 30369,15368 30370,15373 30371,15376 30373,14376 30378,14377 30383,14381 30378,14386 30380,14388 30382,14391 30385,14393 31385,16393 31389,16396 31394,16396 31397,16392 31400,16395 31405,16398 31409,16398 31413,16397 31415,16396 31417,16401 31418,16401 31422,16402 31419,16407 31420,16411 31419,16406 31423,18406 31427,18411 31432,18415 28432,18417 28437,18418 28441,18414 28438,18417 28435,18416 28439,18420 28442,18423 28447,18427 28444,21427 28445,21428 28450,22428 28455,22432 28457,22436 28458,22441 28458,22445 28463,22448 28468,22451 28465,22456 28468,22453 28468,22458 28471,22463 28473,22460 28475,22459 28472,22463 28476,22464 28472,22468 28468,22468 28471,25468 28466,25471 28468,25473 28464,25473 28464,25475 29464,25476 29466,25479 29461,25476 29462,25476 29464,25478 29464,25483 29461,25484 29460,25486 29458,25486 29462,25490 29460,25495 26460,25498 26463,25495 26468,25495 26472,25495 26472,25499 26474,25504 26476,25504 26478,25509 26476,25513 26479,25514 26481,25519 26477,25519 26480,25518 26481,25519 26484,25524 26483,25527 26484,25522 26484,25526 26487,25528 26492,25533 26496,25535 26498,25535 26498,25539 26503,25542 26504,25543 26505,25547 26510,25552 26510,25551 26508,25550 26512,25553 26510,25557 26510,25554 26511,25552 26508,25556 26505,25556 26506,25560 26506,25560 26507,25560 26506,25565 26501,25567 26504,25569 26504,25568 26508,25571 26508,25571 26511,25576 26511,25581 26516,25581 26519,25582 26521,25585 26522,25588 26527,25588 26526,25584 26530,25587 26534,25589 26529,25593 26533,25598 26538,25599 26540,25599 26540,25599 26540,25604 26543,25603 26543,25603 26538,25606 26538,25609 26540,25611 26542,25612 26547,25612 26547,25612 26548,25617 25548,25612 25548,25613 25547,25616 25545,25616 25549,25618 25551,25620 25555,25620 25551,25622 25550,25625 25551,25622 25555,25619 25557,25617 25556,25622 28556,25625 28551,25630 28546,25634 28548,25639 28553,25643 28553,25638 25553,25634 25553,25634 25557,25639 25557,25643 25558,25644 25553,25646 25556,25647 25560,25650 25562,25650 30562,25650 30562,25650 30564,25650 30566,25652 30570,25656 30571,25661 31571,25662 31575,25663 31579,25662 31579,25665 31581,25666 31584,25671 31582,25674 31581,25674 31584,25676 31584,25673 31587,25678 31586,25679 31581,30679 31584,30675 31589,30680 31590,35680 31590,35675 31589,35677 31591,35680 31590,35681 31587,35684 31588,35685 31589,35689 31592,35689 31593,35692 31597,35696 31597,35700 34597,35699 34599,35703 34604,35703 34606,35702 34601,35705 34603,35705 34606,35708 34603,35713 34604,35717 34603,35719 34608,35715 34608,35711 34608,35713 34609,35714 34605,35714 34610,35714 34614,35718 34616,35719 34617,35722 34618,35722 34621,35725 34625,35725 34626,35725 34629,35725 34631,35725 34635,35730 34636,35727 34638,35731 34640,35735 34642,35739 34645,35741 34645,35742 34649,35738 34649,35738 34645,35741 34647,38741 34650,38741 37650,38742 37646,38746 37651,38749 37652,38753 37653,38753 37657,38757 37656,38756 37660,38761 37660,38765 37660,38760 37660,38759 37660,38760 41660,38760 41660,38762 41665,38757 41667,43757 41669,43752 41674,43752 41677,43757 41672,43758 41677,45758 41680,45758 41679,45762 41683,45765 41683,45769 41683,45770 41684,45768 46684,45773 46688,45776 46692,45774 46694,45775 46697,45778 46695,45776 46698,45774 46702,45779 46702,45784 46704,45787 46706,45791 46711,45786 46707,45790 46711,45793 46715,45796 46719,45799 46724,45797 46728,45802 46726,45797 46729,45801 46733,45802 46733,45803 46732,45804 46732,45805 46732,45808 46735,45810 46740,45810 46744,2326 27373,2322 27377,2323 27379,2325 27383,2325 27382,2322 27382,2323 27382,5323 23382,5325 23385,5329 23386,5330 23390,5335 23392,5330 23392,5330 23395,5329 23395,5333 23399,5333 23402,5338 23405,5339 23405,5334 23406,5329 23401,5332 23403,5330 23407,5333 23409,5328 20409,5324 20411,5324 20414,5329 20416,5328 20421,5325 20421,5329 20424,5330 20424,5335 21424,5331 21427,5333 21431,5334 21433,5329 21434,5330 21437,5333 21440,5338 21437,5338 21440,5334 21441,5333 21438,5329 26438,5332 26435,5335 26439,5337 26440,5338 26444,5342 26439,5342 26442,5345 26440,5349 26438,5352 26442,5349 26445,5348 30445,5350 30447,5350 30444,5354 30444,5359 30443,5363 30445,5367 30446,5367 30448,5367 30453,5371 30455,5371 30453,5373 30458,5375 30461,5380 30463,5384 30463,5383 30459,5384 30459,5383 30459,5385 30460,5390 30459,5392 30464,5394 30464,5389 30465,5393 30469,5391 30469,5391 30469,5395 30474,5396 30470,5399 30470,5401 30467,5401 30468,5404 30470,5400 30465,5401 30462,5403 30467,5404 30467,5409 30469,5412 30473,5412 30477,5407 30481,8407 30486,8408 30489,8410 30490,8410 30489,8413 30490,8414 30493,8414 30496,8419 30501,8420 30502,8415 30507,13415 30509,13411 30506,13414 30507,13412 30511,13412 30515,13417 30518,13419 30523,13418 30527,13422 30529,13418 30531,13413 35531,13409 35531,13413 35532,13417 35537,13419 35533,13423 35529,13424 35529,13423 35524,13428 35525,13433 35526,13438 35530,13443 35531,13448 35531,13452 35532,13455 35536,13457 35536,13452 35536,13455 35539,13452 35535,13457 35540,13457 35544,18457 35546,18460 35547,22460 35546,22465 35550,22466 35554,22468 35552,22473 35555,22471 35559,22470 35564,22472 35564,22470 35569,22474 35569,22474 35571,22477 35573,22482 35576,22487 35580,22488 35583,22489 35585,22493 35585,22496 35585,25496 35586,25493 35582,25494 35585,25498 35585,25496 35585,25498 35587,25503 35591,25503 35593,25499 35590,25499 35591,25495 35591,26495 35595,29495 35591,29495 35593,29498 35597,29498 35601,29500 35606,29501 30606,29502 30603,29505 30603,29510 30606,29511 30606,29514 30607,29516 30610,29518 30608,3259 17305,3263 17304,3267 17303,3271 17308,3269 17312,3269 17313,3274 17315,3277 17315,3282 17311,3285 17313,3283 17309,3278 17310,3275 17315,3275 17317,3276 17322,3280 17324,3280 17324,3276 17325,3277 17325,3276 17328,3278 17324,3273 17329,3277 17331,3280 17326,3281 17328,3276 17324,3277 17324,3277 17322,3277 17321,3277 17321,3281 17323,3282 17327,3282 17332,3287 17335,3288 17335,3288 17338,3290 17337,3294 17340,3294 17341,3299 17341,3299 12341,3299 12342,3304 12339,3301 14339,3305 14340,3307 14341,3311 14343,3313 14343,3314 16343,3310 16341,3310 16346,3312 16348,3311 16349,4311 16346,4316 16348,4321 16344,4324 16348,4322 16349,4323 16346,4323 16346,4326 16350,4322 16354,4323 16356,4325 16361,4325 16358,4322 16362,4325 20362,4325 20366,4322 20367,4326 20372,4326 20374,4331 20373,4333 20373,4338 20376,4339 20379,4341 20382,4338 20384,4339 20386,4340 20383,4340 20383,4335 20388,4336 20390,4341 20390,4346 20391,4348 20391,4349 20393,37497 26499,37494 26496,37496 26500,37496 26501,37499 26506,37497 26502,37498 26502,37500 29502,37500 29507,37505 29508,37506 33508,37508 33513,37513 33518,37517 33522,37516 33520,37521 33521,37521 33525,37516 33530,37519 33528,37520 33528,37524 33530,37527 33530,37525 33527,37528 33530,37533 33533,37534 38533,37536 38536,22358 13355,25358 13360,25361 13358,25362 13362,25362 13362,25365 13365,25363 13367,25359 13369,25357 13374,25360 13374,2247 13362,2252 13366,2254 13363,2257 13363,2261 13358,2264 13354,2264 13356,2269 13361,2272 13363,2274 13363,2275 13363,2273 13362,2274 13365,2278 13365,2280 13370,2284 13366,2284 13365,2289 13368,2290 13366,2293 13368,2298 13373,2298 13372,2295 13375,271 22347,273 22350,4273 22347,4269 22348,4270 22350,4271 22355,4272 22360,4276 22363,4281 22365,4284 24365,4279 24365,4282 24365,4285 24365,4287 24364,4289 24362,4294 24360,4295 24362,4298 24365,4301 24369,1301 24370,1301 24371,1305 24375,1305 24376,1307 24377,1312 24380,1314 24382,1318 24380,1316 24382,1316 24387,1318 24387,1318 29387,1321 29387,1316 29383,1320 29386,1321 29389,1326 29389,1327 29389,2327 29394,2327 29394,2332 29393,-666 24367,-663 24368,-661 24368,-656 24371,-653 24372,-649 24372,-647 24374,-643 24370,-638 24375,-635 24380,-638 24382,-638 24384,-638 24384,-636 24388,-637 24390,-632 24386,-630 24386,-629 24386,371 24389,376 24394,374 24392,377 24397,3377 24400,6377 24405,6378 24408,6373 24406,6370 24406,6375 24403,6370 24403,6375 24403,6379 24406,6374 24409,6378 24411,6380 24412,6378 24415,6378 24419,6383 24423,6385 24425,6387 24428,6390 24433,6386 24430,6386 24435,6387 24436,6388 24440,6387 24444,6383 29444,6383 29447,6386 29451,6382 29446,6387 29447,6390 29452,6393 29452,6397 29455,6400 29459,6400 29463,6397 29467,6393 29467,6395 29470,6397 29473,6399 29468,6394 29467,6397 29470,6396 29473,6396 29470,6393 29465,6389 29469,6390 29470,6389 29465,6389 29468,6392 29470,6388 33470,6390 33466,6391 33466,6392 33467,6394 33467,322 22372,322 22374,323 22377,327 22378,331 22382,330 22383,332 22386,333 22383,331 22383,330 22387,332 22391,332 22396,337 22397,339 22394,340 22399,340 22398,340 22396,343 22396,343 22396,341 22400,342 22404,343 22402,348 22403,345 22407,347 22411,342 22411,345 22413,340 22417,345 22417,348 22422,348 22426,351 22427,352 22432,352 22436,4352 22438,4353 22442,4354 22444,4354 22447,4357 22449,4360 22450,4364 22450,4367 22451,4369 22453,4366 22455,4369 22453,4373 22458,4377 22459,4380 22459,4380 22464,4385 22467,4385 22467,4390 22469,4385 22469,4385 22472,25571 26508,25574 26507,25578 26512,25581 26512,25581 26512,25583 26508,25583 26513,25587 26516,25589 26515,25590 26515,25591 26517,25589 26520,25587 26522,23587 26526,23585 26531,23589 26534,23592 26538,24592 26543,24588 26545,24593 26547,24598 26543,24598 26548,24602 26545,24598 26540,24600 26545,24600 26548,24600 31548,24605 31549,24608 31551,24613 31552,24615 36552,24616 36557,24619 36557,24622 36560,24622 36564,24627 35564,24627 35569,24632 35569,25632 35570,25635 35569,25636 35573,25636 35573,25638 35576,25641 35580,25641 35583,25641 35588,25642 40588,20642 40593,20645 40593,20650 40595,20651 40591,20651 40594,20648 40591,20648 40591,20652 40596,20652 40596,20656 40597,20656 40600,20656 40601,20659 40598,20662 40597,20662 40597,20663 40600,20668 40601,20665 40606,1215 13314,1214 13319,1212 13317,1209 13312,1210 13312,1211 13317,6211 13320,6214 13320,6216 13320,6211 13323,6214 13318,6214 13323,6214 13324,6216 13319,6219 13323,6218 13321,6219 13321,6218 13326,6221 13329,6225 13331,6230 13335,6231 13339,6231 13343,6235 13338,6234 13342,6234 13344,6236 13345,25524 26483,25521 26484,25524 26489,25527 26487,25529 26484,25530 26482,25534 27482,25539 27486,25537 27488,25541 27483,25544 27486,25547 27490,25550 27491,25550 27491,25554 27486,25559 27486,25563 27489,25561 27489,25563 27493,25561 27491,25563 27493,25563 27495,25564 27497,25563 27497,25563 27497,25558 27498,25563 27499,25565 27503,25567 27503,25569 27503,25567 27504,25565 27505,25565 27505,25565 27505,25566 27505,25570 27501,25570 27497,25574 27498,25570 32498,25570 32501,25573 32501,25576 32497,25576 32498,25577 32501,25579 32503,25583 32504,25588 32507,25592 32512,25596 32507,25599 32507,25594 32503,25597 32506,25597 32510,25594 32509,25594 32510,25596 32513,25592 32513,25594 32515,25594 32520,25598 32520,25602 32517,25603 32518,27603 32520,27607 32523,27608 31523,27613 31527,27615 31527,30615 31530,30617 31530,30618 31532,30619 31536,30623 31537,30623 31538,30625 31538,30626 31541,30627 31541,30624 31540,30623 31540,30624 31545,34624 31546,34619 31543,34623 31545,34624 31549,34624 31548,34626 31550,34626 31555,34626 31551,34628 31555,34633 31555,34636 31559,34634 31564,34636 31564,34639 31562,34639 31560,36639 31555,36636 27555,41636 27557,41640 27554,41644 27558,41647 27559,41648 27555,41653 27555,41658 27555,41658 27552,41658 27552,41660 27550,41656 27554,41661 27558,41664 27561,41667 27566,41662 27562,41663 27563,41663 27565,41662 27569,41661 27569,41664 27571,41664 27567,41659 30567,41660 30565,41660 30561,41665 30566,41664 30561,41664 30561,41664 30562,41664 30563,41660 30558,1312 24380,4312 25380,4315 25384,4315 25385,4319 25383,4322 25388,6322 25387,6322 25387,6326 25392,6321 25397,6324 25397,6324 25401,6319 25404,9319 25405,9314 25400,9312 25402,9310 25403,9313 25403,9313 25403,9316 25400,9319 25401,4319 25396,8319 25398,8315 25400,8315 25396,8315 25397,8311 25398,8307 25394,8309 25394,8311 25397,8315 25402,8310 25403,11310 25365,11311 25365,11316 25370,11320 25375,11325 25375,11325 25380,11325 25382,11326 25378,14326 25380,14328 25382,14331 25383,14334 25385,14336 25386,19336 25386,19336 25389,19332 25390,19332 25391,19335 25388,19338 25391,19342 25393,19340 25393,19345 25396,19345 25394,19347 25394,19349 25393,19351 25397,19350 25398,19348 25399,19349 25403,19352 25399,19350 25402,19354 25400,19353 25405,23353 25402,23354 25402,23356 25405,23358 25409,23360 25413,23363 25414,23367 25412,23365 25411,23367 25414,23363 25413,23367 25416,23367 25416,23370 25418,24370 25414,24370 25419,24373 27419,24378 27419,24380 27416,24380 27412,24380 27410,24380 27406,24376 27406,24374 27410,24370 27414,24370 27415,24371 27420,24375 27415,24378 27411,24375 27415,24378 27418,24382 27421,24383 27426,24383 27425,24385 27430,24390 27431,24394 27432,24395 27436,24399 30436,24400 30439,24404 30443,24403 30439,24406 30438,24410 30442,24406 30446,24408 30445,24403 30445,24408 30442,24412 30446,24416 30446,24416 30449,19416 30449,19416 30447,19418 30452,19420 30453,19423 30458,15423 30462,15423 30464,15425 30466,16425 30467,16424 30471,16421 30474,16426 30474,16428 30476,16428 30476,16424 30474,16424 33474,16425 33474,16427 33477,16425 33479,16426 33477,16422 33480,16425 33482,16430 33479,16430 33478,16429 33482,16424 33482,16427 33484,16430 33488,16431 33488,16434 33488,16435 33491,16432 33487,16436 37487,16434 37490,16438 37485,16443 37482,16446 37480,16447 37480,16447 37482,16451 37478,16454 37479,16458 37479,16454 37479,16454 37482,16459 37486,16460 37491,16463 37495,16464 37492,16465 37493,16466 37494,16468 37497,16468 37501,16468 37501,16473 37503,16473 37503,16473 37498,16476 37494,21476 33494,21473 33493,21476 33489,21478 33491,21478 33496,21478 33492,21480 33496,21483 33501,21484 33504,21483 33500,21484 33505,21484 33505,21488 35505,21491 35505,21494 35506,21496 35510,21492 35506,21492 35509,21489 35514,21490 35517,21487 35519,23487 35523,23485 35528,23487 35533,23483 35534,23487 35535,23488 35537,23493 35539,23495 35542,23495 35546,23495 35550,23491 35549,23488 35552,23492 35555,23495 35560,23500 35559,23496 35557,4322 16354,4317 16358,4318 16358,4320 16363,4315 16363,4315 16362,4316 20362,4320 20365,4323 20363,4326 20366,4329 20367,4332 20370,4337 20374,4338 20375,4333 20375,4338 20375,4341 20377,4342 20377,4342 20378,4343 20381,4346 20386,4346 20386,4346 20386,4346 20386,4349 20390,4352 20395,4354 20396,4355 20400,4358 20400,4360 20401,4360 20404,4363 20405,4368 20406,4372 20411,4371 20416,4367 20417,4364 20422,4367 20420,4372 20425,4373 20422,4374 20418,4377 20418,4381 20422,4382 20423,4384 20418,4389 20421,4385 20423,4390 20423,4390 20425,4392 20429,4396 20434,41574 39698,41578 39702,41576 39704,45576 39704,45575 39709,45577 39713,45581 39715,45581 39718,45583 39721,45578 39726,47578 39722,47581 39719,47586 39722,47586 39726,47589 39730,47592 39733,47597 39733,47593 39733,47596 39735,47597 39735,47595 39735,47591 39739,47593 39744,47593 39747,4074 20263,4077 20268,4079 20268,4078 20271,4078 22271,4083 22276,4087 22272,4088 22275,4086 22279,4082 22280,4084 22282,4086 22277,4082 22277,4087 22281,4090 22281,4092 22281,4092 22286,4094 22287,4097 22290,4097 22291,4095 22286,4095 22288,4095 22293,4095 22288,4092 22285,4089 22286,4090 22286,4095 22281,4100 22286,4103 22285,4104 22288,4104 22289,4107 22294,4112 22292,4117 22290,4120 22295,120 22300,121 22303,122 22300,122 22300,121 26300,125 26303,129 26303,127 26305,127 26306,132 26306,132 26307,136 26307,141 26309,140 26311,143 26313,140 26314,145 26318,149 26318,153 26321,153 29321,158 29326,158 29329,162 29324,162 34324,165 34329,168 34328,167 34332,169 34333,173 34334,173 34336,177 34338,178 34340,178 34344,182 34348,177 34348,182 34348,184 34353,184 34358,181 34360,183 34365,187 34365,192 34365,197 34367,199 34366,203 34368,205 34368,202 34363,204 34360,1204 34360,1205 34364,1205 30364,1205 30359,1206 30361,1207 30364,1210 30366,1210 30366,1214 30367,1218 30372,1219 30375,1214 30379,1214 30384,1217 30382,1222 30383,1223 30382,1225 30380,1228 30379,1231 30383,1232 30383,1235 30384,1237 30388,1242 30386,1244 30389,2244 30392,2241 30395,2245 30397,2245 30399,2244 30394,2242 30395,2246 32395,2246 32395,2249 32398,2251 32393,5251 32390,5251 32395,5255 32399,5255 32397,5257 32397,5257 32401,5261 32406,5261 32411,5266 32412,5271 32416,5273 32419,5276 32420,5281 32422,5279 32425,6279 33425,6284 33429,6284 33430,6282 33431,6282 33428,6286 33425,6288 32425,6288 32421,6286 32424,6288 32424,11288 32427,11292 32425,11292 32429,11290 32434,11286 32437,11286 32437,11283 32442,11278 32442,11279 32443,11283 32445,11284 32445,11283 32448,13283 32447,13287 32442,16287 32446,16282 32445,16283 32445,16284 32448,16285 32448,16284 32446,16286 32443,16290 32446,16291 32446,16292 32450,16291 32450,16291 32450,16291 32445,16287 32447,16288 32452,16287 32457,16291 36457,16289 36462,16293 36462,16294 36462,16297 36462,16301 36464,16306 36469,16310 36467,16310 36463,16313 36459,16312 36460,16313 36465,16313 36469,16308 36470,16309 36468,16314 36470,16319 41470,16322 41471,16325 44471,16330 44471,16330 44471,16330 44473,16330 44474,16335 44479,16332 44477,8414 30496,8415 30497,8419 30497,8414 30501,8416 30500,8418 30495,8421 35495,8423 35494,8427 35497,8429 35499,8432 35499,8436 35503,8438 35503,8443 35505,8440 35508,8443 35509,8440 35509,8440 35511,8441 35515,8445 35511,8448 35512,8443 35517,8443 35519,8442 35524,8444 35526,8441 35527,8436 35527,8433 35523,8429 35527,8430 35530,8431 35532,8429 35533,8433 35535,8437 32535,8435 32536,8439 32536,8436 32539,9436 32542,9434 32537,9429 32534,9429 32534,9433 32537,9433 32542,9429 32543,9434 32538,9436 32538,9436 34538,7436 34538,7438 34543,7439 34543,7439 34543,7439 34548,7438 34549,7438 34552,7438 34553,7438 34556,11438 34561,11434 34559,11436 34555,7436 34553,7436 34549,120 1235,124 1239,125 1236,125 1238,129 1235,128 1235,125 1236,123 1239,128 2239,132 2242,131 2242,135 2242,140 2242,145 2247,146 2252,144 2253,146 2248,144 2245,146 2244,150 2249,155 2245,159 2242,160 2243,160 2245,155 2244,156 2245,3156 2246,3159 2248,3159 2250,3164 2254,3165 2257,3166 2255,3169 2257,3171 2262,3169 2263,3174 2268,3177 2273,3174 2276,3178 2275,3173 2279,3177 2276,3180 2279,3182 2284,3185 2289,5185 2286,5185 2288,5181 2286,5185 2288,5184 2293,5187 2293,5187 2297,5190 2299,5187 2299,5185 2300,5181 6300,5182 6297,5187 6300,5189 6298,5191 6296,5193 6296,5193 6296,5195 6297,5195 6300,5197 6297,5195 6300,5190 6302,5191 6306,5192 6308,5195 6312,24395 27436,24391 27437,24393 27433,24398 27436,24398 27437,16286 32443,21286 32443,21286 32444,21282 32448,21283 32446,21283 32448,21285 32451,21281 32456,21282 32458,21282 32463,21282 32468,21284 32470,21289 32471,21287 32471,21287 32469,21287 32474,21284 32477,21288 32482,21291 32482,21291 32486,21296 32485,21299 32486,21301 32487,21303 32484,21301 32482,21305 32487,21310 32491,21312 32495,21313 32491,21315 32495,21312 32495,21314 32498,21316 32501,21311 32506,21311 32508,21312 32513,21317 32516,21319 32516,21324 32516,21327 32521,21328 32526,21332 32527,21328 36527,21331 41527,21336 41527,21334 41531,21337 41533,21335 41535,21339 41540,21340 41540,21343 41536,25343 41539,25340 41542,25337 41542,25337 41545,25335 41542,25335 41543,25335 46543,25339 46548,30339 46551,30340 46556,30343 46557,30342 46553,30337 46556,30341 46561,30337 46565,30336 46563,30338 46564,24373 27419,24373 27421,24375 27424,24377 27425,24377 27430,24374 27435,24379 27437,24384 27432,24385 27434,24382 27437,24381 27442,24381 31442,24381 33442,20381 33439,20383 34439,20382 34440,20378 34444,20381 34446,20381 34442,20384 34443,20388 34446,20392 34447,20393 34442,20393 34447,20396 29447,20395 29443,20399 29443,20400 29439,20399 29436,20404 29439,20409 29440,20410 29440,20410 29444,20408 29445,20413 29448,20413 29451,20412 29455,20413 29458,20418 29461,20413 29463,20415 29464,20416 29464,20416 29463,20416 29463,20418 29464,20414 29465,20418 29463,20413 29460,20413 26460,20418 26458,20421 26459,20421 26461,20421 26460,43578 35658,43578 35654,43578 35658,43578 35660,43583 35661,43583 35659,43583 35662,43579 35663,43583 35661,43587 35666,25625 25551,25629 25551,25630 25554,25630 25559,25632 25560,25627 25561,25623 25557,25623 25559,25624 25561,26624 25566,26627 25566,29627 25571,29626 25574,29625 25575,29622 25579,29625 25583,29630 25588,29632 25589,29635 25591,29635 25594,29637 25598,29642 25596,29643 25597,29644 25597,29649 25598,29654 25602,29656 25602,29661 25603,29661 25601,29664 26601,29666 26604,29665 26604,29668 26607,29672 26607,29669 26611,29671 26616,29674 26613,29679 26616,29680 26616,29681 26615,29682 26619,29679 26617,29684 26622,29686 26624,29689 26624,29690 26628,29691 26630,29693 26625,29694 26620,29698 26617,29703 29617,29707 29616,29706 29620,29709 29623,34709 29626,34710 29628,34710 29627,2282 16411,2283 16412,2283 16412,2287 16417,2292 16421,2297 16421,2298 16426,2303 16426,2304 16429,2309 11429,2313 11432,2308 14432,2308 14431,2311 14433,2310 14437,2308 14438,2309 14440,2311 14440,2309 14443,2312 14443,2314 14447,2314 14452,2314 14450,2309 14451,2309 14451,2309 14456,2313 14461,2313 14461,2309 19461,2309 19461,2311 19462,2315 19465,2318 19465,2321 19462,2317 19464,2321 19467,2322 19467,2322 19469,2322 19469,2320 19464,2321 19462,2322 19461,2327 19466,2327 19461,2322 19461,2322 19463,2317 19467,2318 19471,2102 -1848,2107 -1848,2111 -1846,2114 1154,2114 1156,2115 1157,2114 6157,2116 6162,2121 6165,2124 6170,2121 6175,2124 6179,2124 6183,2128 6178,2126 6179,2125 6178,2126 6181,2122 10181,2127 10186,2128 10189,2130 10188,2130 10191,2127 11191,2127 11195,2131 11196,2132 11192,2131 11197,2135 11201,2135 11203,2139 11199,2142 11203,2143 11204,2147 11208,2142 11210,2142 11211,2147 11212,2150 11217,2150 11219,2151 11219,2152 11222,2152 11222,2148 11224,2150 11220,2150 11223,2146 11218,2143 11219,2140 11221,2143 11218,2140 11219,2140 11223,2145 11225,2147 11226,2152 11226,2155 11224,2157 11229,2157 11229,2153 11233,2153 11238,2149 11239,7149 10239,7154 10241,7157 10241,7162 10243,7164 10248,7164 10251,7169 10253,7171 10253,7172 10257,7177 10260,7182 10256,7187 10260,7191 8260,7195 8256,7200 8258,7204 8258,7203 8261,7203 8262,7205 8266,7209 8270,7209 8273,7214 8273,7214 8276,7210 8276,7211 8276,7213 8279,7218 8278,7222 8283,7223 8279,7220 10279,7221 10283,7223 10284,7228 10286,7230 10290,7231 10290,7231 10293,7232 10294,7232 10297,7234 10299,7229 10295,7226 10294,7221 10293,7223 10295,7228 10299,7229 10303,7232 10307,7232 10311,7233 10316,7234 9316,7239 9318,7244 9321,7241 9326,7241 9328,7238 9331,7235 9330,7237 9335,7236 9335,7236 9337,7236 9338,7231 14338,7230 14333,7232 14338,7237 18338,4082 22280,4081 22280,6081 22283,6076 22285,6076 22289,6078 22286,6080 22287,6084 22292,6084 22293,6085 22293,6086 22291,6091 22294,6092 22293,9092 22290,9095 22294,9096 22295,9096 22297,9091 22292,9096 22295,9098 22290,9094 18290,9097 18290,9096 18294,9099 18292,9098 18297,9103 18299,9103 18302,9103 18305,9100 18301,9102 18302,9106 18305,9102 18310,9101 18306,9103 18308,9103 18312,9107 18310,9107 18315,9107 18320,9111 18322,9111 18326,9113 18329,9111 18329,9116 18329,9121 18329,9121 18332,9123 18331,9124 18332,9125 18328,9127 18325,9125 18328,9128 18329,9133 18329,9136 18333,9141 18337,9142 18342,9143 18340,9148 18344,9152 18341,9150 18346,9149 18341,9149 18341,9154 18343,9158 18345,9161 18346,9161 18347,9163 18352,9164 18352,9162 18349,9165 18352,9165 18351,9165 18352,9165 18356,9163 18352,9167 18353,9167 18349,9168 18351,9168 18347,9173 18347,9175 18347,9179 18348,9182 18349,9187 18352,9186 18357,9189 18360,9192 18360,9196 18362,13196 18367,13196 18369,13196 18371,13199 18374,13194 18374,13197 18375,13200 18377,13205 18380,13210 18384,13209 18379,13209 18374,13213 18375,13216 20375,13212 20375,13215 20375,13211 20375,13211 20372,13208 20373,13204 20373,13204 20369,13205 20369,13207 20366,13212 20367,13216 20367,13221 20372,13222 20377,13225 20381,13226 20386,13230 20383,9230 20388,9228 20384,9228 20386,9223 20389,9223 20392,4223 20397,4223 20396,4225 20399,4222 20404,4220 20408,4220 20411,4223 20416,4227 20421,4230 20418,4234 20421,4232 20422,4236 20423,4238 20423,4239 20423,4235 20427,4231 20427,4230 20426,4228 20428,4232 20427,4232 20431,4236 20433,4241 20431,4241 22431,4236 22436,4239 22437,4239 22439,4236 22443,4232 22439,4236 22444,4236 22446,4239 22447,4239 22452,4241 22454,4245 22457,4245 22460,4250 22462,4251 22465,4253 22465,4249 22465,4251 22460,4251 22464,4255 22469,4257 22473,4256 22478,4259 22479,4260 22480,4257 22485,6257 22489,6260 22490,6260 22493,6262 22496,6262 22500,6267 22495,6271 22495,6276 22491,6276 22489,6281 22487,6286 22490,6289 22490,6294 22490,6294 22489,6292 22485,6292 22489,6288 22489,6288 22494,6288 22496,6286 22497,6288 22501,6292 22500,5292 22503,5292 22503,5296 22508,5295 22510,5300 22510,5305 22513,5302 22514,5306 22510,5309 22513,5313 27513,5313 27513,5317 27513,5322 22513,5326 22517,6326 22516,6323 22518,6323 22523,6320 22523,6321 22526,6323 22531,6323 22531,6324 22532,6324 22532,6325 22529,6321 22531,6323 22534,6328 22534,6329 22530,6324 22527,10324 22522,10319 22524,10315 22520,10314 22525,10311 22525,10307 22526,10304 22531,10306 22527,10306 22528,10309 22530,10312 27530,10312 27534,10312 27534,10307 27536,10307 27532,11307 27531,11307 27533,11308 27535,11303 27531,11298 27532,11294 27534,11294 27534,11299 27538,11297 27542,11302 27547,11306 27547,11311 27549,11313 30549,11317 30551,11313 30546,11316 30541,11316 30540,11319 30545,11318 30546,11323 30550,11326 30554,11326 34554,11330 34558,11331 34558,11333 34558,11332 34561,11328 34561,11331 34562,11336 34562,11336 34567,11340 34570,11342 34569,11345 34568,11344 34569,11345 34571,11349 34574,15349 34574,15354 34569,15359 34566,15362 34571,15363 34576,15367 34577,15368 34577,15371 34581,15374 34576,15379 34574,15383 34579,15384 34584,15387 34583,17387 34578,17392 34578,17391 34578,17396 34573,17397 34578,17397 34580,17397 39580,17402 39584,17397 39587,17402 39587,17406 39582,17403 39587,17407 39589,17409 39592,17406 39592,17409 39595,17409 39599,17412 39603,17416 39608,17417 39608,17417 39608,17421 39607,17422 39609,17424 39608,17427 39604,17425 39605,17426 39609,17423 39611,17422 39610,17425 39613,17428 39618,17428 39619,17429 39616,17432 39616,13432 39615,13432 39617,13432 39617,13432 44617,13434 44621,13434 44623,13439 44627,13442 44632,13442 44635,13440 44631,13442 44631,13445 44635,13447 44639,13445 44637,13445 44638,13450 44639,13454 44644,13457 44644,13459 44642,15459 44639,15457 44644,15461 44644,15462 44642,15459 44645,15459 44647,15463 44650,15458 44651,15459 44653,15461 44657,15463 44661,15463 44661,15463 44663,15467 44666,15472 44668,15474 44664,15470 44668,15471 44670,15473 44674,15475 44675,-3806 12298,-3804 12301,-3805 13301,-3804 13296,-3808 13292,-3809 13295,-3806 13300,-3804 13297,-3801 13301,-3801 13302,-3796 18302,-3801 18306,-3799 18311,-3802 18311,-3799 18312,-3801 18314,-3796 18319,-3795 18322,-3791 18321,-3786 18320,-3786 18321,-3784 18321,-3782 18321,-3781 18324,-3782 18325,-3783 18320,-3788 18324,-1788 18324,-1788 18329,-1784 18333,-1784 18334,-1781 18329,-1777 18334,-6777 18337,-6774 18339,-6776 18341,-6781 18341,-6779 18341,-6779 18343,-6779 18339,-6777 18343,-6782 18338,-6779 18341,-6778 18341,-6776 18336,-6776 18333,-6776 18333,-6780 18338,-6784 18338,-6787 18335,-6786 18336,-6781 22336,-6781 22335,-6778 22331,-6777 22326,-6777 22331,-6777 22335,-6772 22335,-6774 22340,-6769 22341,-6767 22337,-6767 22335,-6767 22335,-6767 22333,-6767 22336,-6762 22331,-6759 22331,-6764 22332,-6765 22334,-6767 22339,-6762 22334,-6760 22334,-6760 22334,-6758 22337,-6754 22341,-6754 22342,-6750 22339,-4750 22343,-4747 22343,-4752 22343,-4751 22344,-4749 22345,-4745 22348,-4740 22353,-4736 22358,-4738 22363,-4740 22358,21336 41527,21334 41527,21330 41526,21330 41526,21333 41529,21328 41529,21329 41530,21326 41532,21328 41532,21324 41537,21328 41532,21330 41535,21334 41532,21336 40532,21334 40536,21339 40534,21341 40534,21344 40534,21346 40532,21350 40532,21353 40535,21357 40539,21359 40542,21360 40546,21355 40546,21360 40547,21359 40550,21356 40551,21356 40550,21357 40550,21361 40554,21358 45554,21362 45556,21366 45553,21370 45557,21374 45556,21377 45553,22377 45549,22382 45549,22382 45552,22386 45557,22387 45557,22388 45553,22392 45557,24392 45561,22392 45558,22397 45561,22399 45558,22398 45561,22400 45564,22400 45569,22404 45573,22406 45577,22406 45581,22404 45581,22407 45582,22409 45579,22409 45575,22409 45579,22407 45579,22402 45582,22402 45582,22404 45587,22406 45587,22406 45589,22411 45589,22413 45590,22417 45591,22417 45592,22422 45587,22425 45583,22428 50583,22428 50585,22428 50585,22430 50588,22435 50590,22435 50585,22435 50590,22439 50595,22440 50590,22445 50587,22442 50584,22442 50586,22443 54586,22443 54590,22446 54595,22448 54597,22448 59597,22444 59593,22449 59596,22449 59599,22452 59600,22457 59600,22458 59605,22457 59602,22462 59603,22463 59604,22461 59605,22458 59602,22457 59601,22457 59601,22455 59605,25455 59606,25457 59611,25462 59613,25464 59614,25467 59617,25472 59612,25476 59613,25478 59610,25482 59615,25482 59616,25486 59612,25483 59614,25487 59619,25492 59623,25497 59625,146 2252,150 2249,150 2249,152 2254,157 2249,158 2253,157 2252,161 2255,159 3255,161 3258,161 3255,163 3255,168 3259,168 3259,172 3263,167 3267,172 3271,172 3272,172 3274,175 3278,179 3282,181 3283,184 3280,185 3282,187 3282,191 3284,192 3286,191 6286,193 6289,198 6285,195 6290,194 6289,195 6289,199 6293,200 6288,198 6290,202 6291,207 6296,212 6301,215 6301,216 6301,211 6304,212 6304,216 6309,216 6304,214 6308,213 6308,211 6305,212 6309,217 6314,220 6317,224 6322,222 6327,220 6323,41573 39712,41572 39709,41576 40709,41580 40714,41576 40717,36576 40717,36577 40719,36582 40716,36585 40721,36590 43721,36585 43721,36582 43724,36585 43729,36590 43731,36590 43730,15289 11307,15285 11312,15286 11315,15289 11315,15294 11315,15295 11316,15296 13316,38742 37646,38743 37650,38745 37655,38744 37658,38739 37659,38737 37662,38742 37662,38745 37657,38748 37662,38748 37662,38752 37667,38753 37667,38748 37669,38748 37668,38752 37673,38754 37674,38756 37676,38758 37674,38760 37679,38760 37675,38758 37675,38763 37675,38767 37674,38772 40674,38767 40679,38772 40683,38774 44683,38778 44686,38780 44690,38780 44690,38779 44695,38782 44700,38780 44695,38775 44696,38775 44696,38775 44696,38779 44699,38783 44696,38784 44696,38786 44692,38786 44692,38786 44696,38791 44698,38793 44699,38795 44703,38800 44708,38803 44708,38807 44709,38802 44706,38806 44708,38809 44709,36809 44709,36814 44704,36813 44705,36814 44705,36816 44709,36811 44712,36812 48712,36811 48717,36815 48721,36816 51721,36818 51717,36822 51720,40822 51715,40827 51712,40830 51716,40829 51719,40832 51723,40835 51724,40840 51721,40841 51721,40836 51725,40841 51730,40846 51734,40848 51738,40849 51740,40851 51743,40854 51745,40855 51746,40857 51750,40857 51746,40861 51748,40866 51751,40862 51750,40866 51750,40869 51752,40865 51752,40863 51755,40858 51757,40855 51753,40855 51758,40852 51758,40853 51760,40857 51761,40855 51757,40852 51760,40853 51761,40855 51762,40858 51757,40859 51756,40863 51757,40863 51759,40860 51764,40859 51764,40854 51768,40850 51765,40852 51767,40852 51767,40848 51772,40852 51776,40854 51778,40852 51778,43852 51778,43854 52778,43856 52781,43859 52781,43859 52776,37512 26536,37517 26531,37520 26535,37520 26540,37522 26544,37527 26544,37532 26549,37537 26544,37540 26549,37545 26544,37549 26547,37549 26550,37548 26551,37549 26553,37546 26553,37546 26553,37549 26556,37549 26559,37552 26559,37556 26564,37560 26559,37561 26561,37565 26565,41565 26565,41569 26568,41571 26573,41571 26573,41576 29573,41571 29573,41573 29576,41573 29578,46573 29578,46569 29582,45569 29583,45572 29583,45568 29583,45573 29581,45575 29578,45571 29581,45572 29584,45572 29585,45576 29585,45578 29588,45581 29591,45582 29593,45582 29598,45584 29597,45589 29600,45585 29605,45589 33605,45593 36605,45594 36607,45599 36609,45600 36604,45604 36604,45604 36608,45604 36607,45608 36610,50608 36613,50611 36609,50614 36609,50619 36605,50624 36605,50625 36606,50625 36605,50629 36606,50624 36608,50625 36610,50626 36610,50629 36608,50627 36610,50628 36614,50632 36618,46632 34618,46632 35618,46636 35622,46636 35617,46637 35620,46639 35619,46643 35620,46645 35625,46643 35630,46648 35635,46648 35640,46649 35643,46651 35647,46655 35650,46652 35655,46657 35656,46658 35657,46662 35660,46659 35663,46662 35664,46665 35663,46667 35667,46667 35663,46670 35666,46672 35671,46674 35671,47674 35668,47676 35672,47677 35673,47677 35678,47677 35677,47677 35677,47677 35682,47672 35683,47671 35683,49671 35685,49674 35689,49677 35692,49675 35692,54675 35697,54678 35699,54674 35699,54670 35701,54670 35700,54675 35703,54676 34703,54676 34703,54679 34706,54683 34708,54688 34706,54688 34707,54685 34702,54687 34702,54692 34707,54687 36707,54687 36706,54682 36707,54685 38707,54680 38710,54680 38714,54677 38714,54679 38719,54682 38720,54687 38716,54688 38717,54692 38722,54697 38726,54699 38727,54700 38724,54702 38720,52702 38719,52702 38719,52702 38721,52702 38725,52704 38726,52706 38728,52707 38729,52711 38728,52711 35728,52713 35733,52712 35737,52712 35739,52713 35742,52713 35745,52708 35745,52710 39745,52713 39749,52716 39748,52721 39749,52720 39753,52716 39756,52716 40756,47716 40757,47717 40761,47722 40761,47722 40761,47722 40766,47726 40769,47728 40772,47733 40777,47731 40773,50731 40777,51731 40779,51733 40782,51734 40786,51737 40784,51741 41784,51739 41783,51739 41785,51739 41785,51736 41789,51731 41789,52731 41790,52735 41791,52738 41790,52742 41789,52746 41785,52747 41785,52745 41785,52750 41782,52753 41786,52753 41787,52758 41792,52754 42792,52749 42793,52752 42794,52756 42791,52757 42790,52762 42793,52766 42797,52766 42797,52769 42802,52774 42806,52774 42805,52771 42807,52774 42807,52770 42808,52771 42811,52767 42811,52766 42812,52767 42817,52771 42817,52771 42817,52775 42815,52779 42811,52779 42812,52780 42815,52776 42818,52774 42818,52777 42822,52780 42823,52781 42827,52776 42829,52780 42832,54780 42835,54780 42840,2135 11201,2140 11203,2137 11204,2140 11209,2142 11213,2147 11211,2145 11213,2145 11213,2150 11218,2150 11221,2153 11225,2157 13225,2162 13228,2167 13231,2171 13232,2167 13229,2168 13233,2171 13237,2173 13239,2168 13234,2168 13235,2173 13235,2175 13234,2177 13235,2177 13234,2179 13229,2179 13226,2180 13226,2177 13226,2177 13231,2180 13231,2181 10231,2176 10233,2177 10232,2180 10235,2185 10237,2182 10240,6182 10240,6184 10244,6182 10242,6183 10243,6185 10246,6190 10244,6194 10244,6194 10247,6192 10247,6192 10252,6195 10256,6194 10260,6195 9260,6195 9260,6195 9264,6199 9269,6204 9272,6199 9268,6201 9268,6203 9265,6208 9268,6204 9270,6204 9275,6201 9279,6201 9281,6201 9286,6206 9281,6206 9277,6202 9281,6200 9285,6202 9288,6198 9290,7198 9293,7200 9297,7201 9297,7205 9298,7209 9298,7209 9299,8209 9302,8214 10302,8218 10306,8222 10308,8226 10313,8231 10313,8235 10318,8237 10318,8237 10323,8233 10326,8233 10327,8237 10325,8238 10328,8238 10330,8234 10330,11234 10332,11236 10333,11241 10337,14241 10338,14240 10338,14237 10339,14238 10337,14237 10339,14242 10339,14246 10339,14250 10339,14250 10339,14251 10337,14254 10337,14256 10334,14256 10332,14252 10336,14255 10340,14259 10342,14262 10347,11148 3159,11153 3163,11154 3162,11154 3165,11158 3167,11161 3172,11162 3175,11162 3176,11166 3179,11166 3181,11171 3185,11176 3180,11178 3179,11176 3181,11179 3183,11174 3182,52776 42818,52778 42822,52777 42822,52782 42817,52783 42822,52784 42823,52789 42826,52789 42823,56789 42828,56786 42829,56786 42832,56789 42836,56789 42835,56785 42838,56786 42843,51786 42844,51788 42846,51790 42847,51794 42842,51796 42842,51801 42846,53801 42849,53806 42849,53809 42852,53812 42850,53817 42846,53817 42848,53818 42853,53822 42856,53823 42854,53826 42858,53825 42860,53826 42860,53826 42864,53830 42868,53835 42873,53839 42873,53841 42872,53841 42876,53841 42879,53841 42884,53836 42888,53836 42889,53836 44889,53833 44889,53835 44893,53838 44897,53842 44897,53844 44900,53844 44904,53845 44905,53850 44903,53853 44904,53858 44906,53856 44907,53861 44909,53856 44913,53858 44916,53863 44916,53868 44918,53867 43918,53869 43921,53869 43919,53867 43919,53862 43918,53860 43923,53864 43928,53869 43930,53874 43933,53874 43932,53874 43932,53875 43930,53877 43928,53878 43924,53883 43927,55883 43929,55883 43925,55879 43929,55881 43929,55884 43928,55881 43928,55882 43929,55883 45929,55883 45933,55883 45936,55884 45941,55884 45941,55886 45946,55882 45948,55883 45952,55888 45956,55890 45957,55894 45953,55892 45954,55897 45950,55893 45954,55896 45956,55892 45955,55897 45959,55899 45961,55899 45961,55894 45962,55898 45957,55893 49957,55896 47957,55894 47956,55898 47960,55901 47964,55901 47967,55901 47970,55896 47973,55898 47969,55894 47974,55895 47975,55891 47976,55896 47979,55899 47984,55902 47983,55897 47987,55899 47989,55904 47992,55904 47993,55905 47997,55902 48001,55902 48003,55907 48000,55910 47998,55915 47999,55911 47994,55906 47998,55910 48003,55914 48000,55918 48000,55914 48000,55919 48000,55921 48003,55921 48007,55924 48007,55919 48010,55922 48005,55927 48009,55928 48008,55928 48008,55930 48012,55925 48012,55925 48016,54925 48014,54922 48018,54922 44018,54926 44013,54929 44012,54932 44016,55932 44017,55935 44017,55936 44020,55937 44022,55936 44020,55939 44015,55944 44018,55945 44022,55947 44023,55950 44024,55953 44020,55956 44023,53867 43919,53871 43921,52871 43921,53871 43923,53876 43923,53881 43923,53880 43927,53882 43931,53886 43936,53884 43937,53879 43934,53879 43937,53877 43939,53878 43938,53879 43942,53880 43947,53881 43948,53884 45948,53884 45949,53882 45953,53883 45954,53878 45956,53880 45953,53885 45958,53885 45958,53886 45957,53886 48957,53886 48962,53891 48962,53892 48964,53897 48965,49897 48962,49902 48965,49906 48967,49902 48967,49904 48971,49901 48967,49904 48970,54904 48971,54904 48971,54904 48975,54909 48979,54907 48975,54910 48975,54906 48971,54909 48973,54911 48975,54915 48978,54920 48978,54923 48981,54918 48984,54921 48984,56921 48984,56926 48986,56924 48981,56929 48980,56932 48979,56932 48977,56936 48979,56937 48981,56937 48982,61937 48984,61937 48980,61934 51980,61935 51981,61935 51984,61935 51984,61931 51986,5329 23395,5331 23395,5333 23390,5337 23392,5340 23395,5345 27395,5345 27397,5350 27398,5355 27399,5356 27402,6356 27405,6360 27407,6361 27406,6364 27402,6366 26402,6371 26402,6371 26402,6372 26405,6370 26405,6375 26406,6380 26411,6385 26413,6387 26414,6388 26419,6390 26419,6391 26424,6393 30424,6390 30429,6390 30432,6390 30430,6394 30434,6394 30437,6394 30441,6396 30442,6398 30439,6399 30436,6404 30435,6405 30435,6400 30435,6405 30440,6404 30443,6405 30447,6409 30447,6411 30447,6412 30448,6417 30446,6421 30450,6418 30448,6417 30444,6418 30449,6420 30451,6425 30456,6426 30456,6425 30458,6426 30458,6426 34458,6427 34459,6432 39459,6434 39462,6434 39467,6439 39470,6443 39467,6444 39468,6449 39473,6451 39476,6452 39481,6452 39479,6452 39476,8452 39476,8456 39478,8460 39480,10460 39482,10455 39482,10456 39484,10460 39484,10463 39484,10468 39486,10473 39482,10475 39484,10475 39486,10476 39488,10477 39492,10475 39494,10480 39499,10476 39501,10479 39506,10480 39510,10475 39508,10480 39513,10481 39516,10481 39516,10485 39521,10487 39522,10490 39523,10490 39520,10493 39520,10496 44520,10491 44519,10491 44524,10492 44520,10497 44525,10499 44525,10502 44527,10500 44531,10502 44535,10506 44535,10511 44532,13511 44536,13513 44533,13510 44535,13507 44540,13511 44543,13515 44548,13517 44549,13522 44550,13525 42550,13520 42551,13522 42553,13525 42552,13529 42557,13529 42558,13524 42559,13525 42559,13525 42562,13520 42564,13523 42567,15523 42569,15523 42572,15524 42577,15529 42577,15530 42582,15532 42584,15532 42588,15531 42587,15531 42592,15530 42587,15530 42583,15533 42583,15536 47583,15532 47583,15535 47587,15534 47590,15536 47594,11536 47590,11533 47590,11529 47590,11533 47592,11533 47592,11533 47593,11537 47598,11538 47603,11538 47603,11538 47605,11541 47609,11544 47613,14544 47614,14539 47610,14537 47610,14537 47614,14535 50614,14537 50619,14539 50619,14540 50623,14538 50623,14537 50619,25599 26540,25599 26541,25599 26544,25594 26542,25599 26543,25596 26544,25597 26543,25598 26543,25593 26544,25588 26542,25593 26545,25595 26544,25596 26544,25599 26541,25594 26544,25592 26549,25593 26548,25597 26549,25596 26550,25594 26551,25590 26550,25594 26554,25597 26550,25598 26552,25593 26555,25598 22555,25599 22557,25604 22559,25605 22558,25606 22562,25605 22559,25605 22564,30605 22569,30610 22571,30610 22575,30609 22575,30609 22576,30609 22581,30605 22581,30610 22583,30610 22584,30613 22579,30613 22581,30616 22577,30619 22577,30621 22580,30621 22585,30626 22590,30628 22593,30629 22598,30626 22603,30628 22606,30629 22607,30629 22604,30627 22606,30632 22608,30633 22608,30636 22612,30641 17612,30642 17614,30647 17614,30651 17615,30654 17610,30655 17607,30658 17611,30653 17610,30654 17606,30654 17607,30659 17606,30660 17611,30658 17616,30659 17616,30664 17619,30665 17621,30665 17620,30667 17621,30671 17624,30673 17624,30673 17624,30678 17627,30675 17632,30675 17635,30678 17640,30681 17643,30686 17639,30691 17641,30696 19641,30699 19640,30700 19640,30696 19645,30698 19643,30699 19645,30702 19646,30703 19649,30699 19651,30704 19648,30706 19652,30709 19653,30709 19655,30709 19655,30712 19657,30708 19658,30705 19660,30700 19662,30701 19663,30706 19664,30711 19663,30707 19667,30704 19670,30708 19672,30709 19673,30711 19673,30711 19674,30713 19678,30718 19682,30723 20682,30721 20686,30725 20691,30726 20693,30729 20695,30728 20690,30730 20692,30733 20694,30736 20692,30736 20691,30740 20694,30741 20695,30741 20697,30746 20700,30747 20702,30750 20701,30751 20698,30753 24698,30749 24701,30748 24703,30746 24704,30747 29704,30747 29705,30749 29707,30752 29712,30757 29712,30760 34712,30760 34716,30763 34716,30759 34713,30759 34717,30763 34717,30758 34717,30757 34721,30760 34726,30758 34726,30763 34727,30763 34727,30764 34727,30759 34729,30759 34732,30762 34734,30757 34735,30761 34736,30759 34736,30762 34738,30757 34733,30760 34735,30762 34737,30760 34736,30765 34733,32765 34737,32768 34737,32765 34740,32765 34742,32768 34747,32772 34751,32772 34752,32777 34749,32782 34751,32783 33751,32783 33746,36783 33749,36783 33754,36786 33756,36787 33755,36787 33758,36791 33754,36796 33754,36801 33756,36801 33758,36801 33762,36802 33765,36802 33765,36806 33770,33806 33772,33806 33777,33809 33777,33814 33780,33814 33785,33818 33782,33821 33784,33826 33781,33822 33781,33824 33783,33822 33784,33826 33787,33823 33792,33827 33795,33828 33798,33829 33799,33833 33801,33833 33801,33836 33805,33839 33809,33842 33805,33847 33810,33845 32810,33847 32808,33849 32812,33851 32815,33849 32818,33849 32822,33847 32822,33847 32826,33850 32831,33854 32836,33857 32833,33856 32828,33859 32829,33860 32832,33857 32834,33857 32830,33855 32830,33857 32830,33855 32834,33859 32829,33859 32833,33862 32836,33864 32837,33864 32839,33866 32837,33869 32835,33872 32840,33874 37840,33879 37845,33881 37850,33881 37855,33886 37856,33891 37860,33896 37860,33893 37863,33894 38863,33896 38859,28896 38864,28899 39864,33899 39869,33896 39871,33898 39875,33902 39873,33902 39875,33907 39879,33912 39884,33908 39887,33908 39888,33905 39890,33909 39895,33911 39896,33908 39900,33912 39901,33915 39902,33915 39902,33915 39902,33910 39907,33910 39904,33914 39903,33912 39906,33916 39909,33920 39909,33922 39912,33923 39916,33928 39916,33931 39918,33932 39919,33935 39915,33936 39912,33934 39909,35934 39914,35931 39915,35935 39917,35939 39920,35939 39915,35940 39911,35944 39916,35944 39911,35944 39908,35945 39904,35945 39908,35945 39912,35950 39915,35955 39917,38955 39916,38960 39921,38962 39920,38962 39920,38967 39922,38967 39924,38970 39928,38975 39928,38973 39928,38977 39931,38980 39934,38984 39936,38982 39939,38983 39942,38985 39943,38987 39945,38992 41945,38988 41950,38989 41954,38992 41958,38992 41962,38992 41965,38993 41970,38997 41970,38997 41970,38994 41974,38994 41979,38997 41979,38999 41982,38994 41980,38998 41985,38998 41984,5334 23406,5330 23406,5325 23403,9325 23404,12325 23408,12325 23408,12322 23406,13322 23411,13325 23416,13326 23412,13322 23414,13327 23419,13328 23422,13329 23425,13333 23422,13337 23424,23491 35549,23490 35544,23494 35546,23499 35548,23495 35549,21495 35553,21490 35556,21492 35558,21492 35556,21494 35559,21494 35564,21494 35566,21499 35566,21502 35562,21502 35567,17502 35568,17506 35573,17507 35574,17511 35578,17512 35583,17513 35588,18513 35591,18514 35592,18515 35594,18513 35596,16513 35601,16513 37601,16513 37602,16511 37604,16513 37609,16514 37611,16518 37616,16522 34616,16524 34613,16528 34615,16528 34620,16533 34624,16535 34627,16538 34628,16539 34630,16539 34631,16542 34628,16542 34633,16544 34638,16547 38638,16547 38640,16543 38645,16543 38640,16540 38640,16543 38640,16542 38641,16546 38646,16541 38649,16541 38645,18541 38648,18544 38648,18544 38653,18544 38656,18549 38651,18547 38651,18550 38656,18547 38658,23547 38663,23544 38664,23548 38668,23548 38670,28548 38672,28549 38669,28549 38673,28545 38669,28549 38670,28554 38670,28557 38674,28560 38669,28562 38674,28562 38669,28561 38669,28564 38671,28569 38671,38779 44699,38780 44695,38778 44698,38783 44700,38785 44700,38781 44701,38782 44696,38786 44691,38789 44692,38794 44692,38799 44688,38799 44693,38803 44697,38808 44697,38806 44697,38806 44700,38803 44702,38803 44706,38802 44707,38807 48707,38808 48707,38806 48707,38810 48712,38810 48709,38810 48711,38810 48711,38806 48707,38802 48710,38803 48706,38805 48711,38810 48711,38805 48709,38809 48710,38809 48710,38814 48707,38815 48703,38816 48703,38816 48704,38820 48704,38822 48709,38820 48710,38818 48714,38822 48716,38822 48719,38827 48722,38828 48727,38832 48725,38830 48730,38831 48726,38832 48724,38829 48728,8431 35532,8431 35537,4431 35532,4434 35537,4438 35537,4439 35533,4443 35535,4442 35530,4445 35527,4449 35527,4453 35530,4458 35530,4459 39530,4460 39531,4461 39531,4464 39531,4468 39531,4470 39534,4465 39534,4465 39532,4469 39532,4471 39537,4466 39538,4470 39539,4473 39540,4476 39540,4480 39543,4485 39548,4483 39546,4484 39547,4484 39549,4484 39551,4486 39553,4486 39554,4487 39551,4483 39553,4486 39554,4490 39556,4493 39557,4498 39561,4494 39562,-4749 22345,-4752 22345,-4748 22348,-4744 22351,-4740 22356,-4741 22358,-4739 22361,-4734 22359,-4730 25359,-4730 25360,-4725 25360,-4727 25360,-4727 25361,-6727 25360,-6729 25365,-6730 25365,-6727 25365,-6731 25364,-6730 27364,-6727 27366,-6723 27367,-3723 27363,-3719 27368,-3720 27371,-3718 27366,-3717 27369,-3716 27369,-3714 27372,-3711 27370,-3712 27371,-3712 27370,-3710 27375,-3708 27377,-3707 27382,-3706 27385,-3706 27389,-3705 32389,-3704 32392,-3704 32392,-3699 32391,-3699 32395,-3694 32399,-3694 32400,-3695 32404,-3695 32408,-3693 32410,-3693 32410,-3697 32410,-3692 32413,-3691 32418,-3686 32420,-3683 32425,-3681 32420,-3678 32424,-3673 32424,-3676 32427,-3673 32426,-3671 32426,-3676 33426,-3678 33428,-3676 33428,-3679 33428,-3679 33433,-3677 33434,-3676 33438,-3681 33440,1319 33444,1321 33441,1325 33444,1329 33439,1326 33444,1326 33439,1327 33439,1327 33440,1332 33444,1333 33449,1338 33453,1338 33450,1343 33450,1347 33454,1346 33457,1346 33455,1342 33459,1341 33462,1346 33462,1347 33463,1343 33463,1344 33462,1348 33457,1347 33460,1352 33464,1356 33468,1361 33469,1363 33468,1365 33469,1368 33472,1369 33475,-2631 33478,-2633 33483,-2629 33486,-2632 34486,-2628 36486,-2625 36488,-2621 36488,-2624 36488,-2622 36492,-2624 36491,-2629 36491,-2627 36496,-2623 36499,-2628 36502,-2631 36506,-2626 36506,-2622 36506,-2622 36509,-2619 36514,-2624 36512,-2621 36510,-2619 36510,-2619 36508,-2617 36512,-2615 36512,-2615 36513,-2615 36511,-2615 36506,-2612 36507,-2609 36511,-2606 37511,-2606 37508,-2610 37505,-2607 37508,-2602 37512,-2599 37512,-2595 37510,-2597 37511,-2592 37515,-2597 37514,-2592 37519,-2592 37524,-2592 37526,-2594 37521,-2594 37516,-2591 36516,-2588 36517,-2589 36513,-2586 36514,-2584 36514,-2583 36516,-2579 36514,-2578 36518,-2578 35518,-2575 35519,-2577 35519,-2578 35524,-2578 35529,-2578 35532,-2578 35534,-2580 35537,-2584 35541,-2586 35542,-2587 35544,-2585 35540,-2585 35544,-2584 35543,-2580 35548,-2576 35550,-2571 35553,-2567 35555,-2565 35560,-2560 35560,-2557 35564,-2553 35564,-5553 36564,-5548 36564,-5544 36565,-5547 36565,-5545 36570,-5542 36565,-5543 36566,-5543 36568,-5543 36570,-5540 36575,-5537 36577,-5535 36581,-5532 36580,-5528 36575,-5526 38575,-5526 38576,-5526 38571,-5522 38571,-5518 38576,-5514 42576,-5510 42581,-5512 42583,-5512 42582,-5507 42582,-5510 42585,-2510 42589,-2511 42592,-2508 42594,-2506 42597,-2503 42598,-2503 42603,-2498 42608,-2501 42611,-2500 42616,-2502 42613,-2502 42616,-4502 42616,-4502 42620,-4502 42622,-4506 42619,-4509 42621,-4511 42624,-4515 42625,-4510 42625,-4507 42628,-4502 42624,-4501 42629,-4505 45629,-4503 45630,-4499 45631,-4496 45630,-4497 45628,-4495 45630,-4494 46630,-4491 46634,-4487 46629,-4483 46631,21336 40532,21341 40533,21346 40534,21346 40536,21345 40536,21346 40536,21345 40536,21344 40538,21347 40543,21348 40543,21351 40540,21351 40542,21348 40545,21351 40546,21352 40546,21353 40546,21358 40546,21359 40545,21359 40550,21357 40555,21362 40560,21364 40555,21363 40555,21364 40560,25364 40564,25365 40566,25368 40566,25371 45566,25372 45567,25372 45562,25376 45564,25381 42564,25385 42560,25389 42564,25389 42568,25393 42572,25390 42572,28390 42569,28389 42570,28385 42574,28386 42576,28389 42577,31389 42578,31385 42582,31387 42582,31390 42578,31391 42579,31392 42576,29392 42580,29396 42582,29398 43582,29402 43584,29406 43585,29407 43587,29411 43592,29413 43594,29414 43595,25414 43600,25412 43595,25415 43599,25420 43602,25418 43604,25423 43599,25426 43599,25429 43602,25434 42602,25429 42604,25432 42600,25435 42605,25436 47605,25440 50605,25441 50610,25439 50614,25444 50617,25447 50621,25444 50624,25444 50626,25445 50627,25450 50632,25450 50628,25451 50630,25451 50632,25454 50633,25458 50637,25462 50641,25463 50640,25463 51640,25467 51644,25469 51649,25473 51650,25474 51653,25475 51654,26475 51658,26475 51662,26474 51665,26476 51665,26481 51661,26483 55661,26485 55664,30485 55667,30485 55670,30489 55671,30489 55668,30491 55670,30492 55670,30493 55675,30497 55675,30501 55671,30503 55676,30500 55677,30498 55672,30494 55675,30499 55676,30500 55676,30505 55681,30501 55684,30496 55685,30500 55685,30502 55687,30506 55692,30507 55693,30506 55692,30511 55693,30516 55694,30514 55699,30514 55701,30512 55701,34512 55705,34516 55708,34520 55704,34518 56704,34519 56704,34520 56706,34517 56706,34515 56701,34519 59701,34522 59706,34522 59708,34522 59713,34526 59715,34528 59717,34533 59712,34538 59715,34538 59717,34541 59717,34546 59720,34548 59721,34552 63721,34547 63726,34549 63728,34554 63726,34556 63726,34557 63721,34556 63725,34561 63730,34558 63730,37558 63725,37561 63729,37565 63724,37569 63720,37573 63718,37578 63722,37577 63718,37579 63720,37579 63722,37580 63719,37580 63720,37579 63724,37574 63725,37574 63727,37576 63725,37581 63729,37583 63732,37586 63732,37590 63737,37592 63734,37597 63731,37600 63730,37596 63731,37596 63733,37600 63733,37601 63735,37596 63735,37591 63732,37596 63733,37601 63738,37602 63733,37599 63738,37594 63740,37598 63744,37603 63745,37605 63747,37607 63752,37607 63756,37603 63757,37603 63761,37604 63761,37608 63758,37609 63762,37604 63764,37604 63764,41604 63765,41600 63761,41599 63761,41600 63766,41596 63766,41599 63766,41601 63770,41604 63768,41608 63768,41611 63772,41614 63767,41609 63763,41612 63765,41615 63760,38615 63764,38615 63768,38618 63768,35618 63769,35618 63774,35617 63775,35618 63776,35613 63775,35615 63780,35612 63782,35613 63779,35614 63775,35618 63774,35619 63776,35624 63778,35624 63780,35629 63785,35629 63780,35626 63781,35624 63782,35629 63784,35634 63787,35638 63782,35634 63783,35634 63778,35633 63777,35638 63782,35641 63786,35644 63791,35648 63793,35647 63793,35649 63797,35653 63801,35654 63804,35654 63804,35656 63804,35655 63806,35658 63810,35658 63805,35662 63805,35657 67805,35658 67808,35660 67811,35664 67808,35660 67803,35658 67803,35661 67803,35663 67808,35666 67810,35670 67814,35669 67813,35669 67816,37669 67820,37664 67820,2275 13363,2278 16363,2274 16363,2275 16362,2279 16362,2282 16362,2287 16366,2284 16366,4284 16366,4286 16371,4290 16375,4294 18375,4295 18377,9295 18381,9296 18381,9299 18382,9303 18379,9305 19379,9308 19375,8308 19380,8312 19380,38746 37651,38749 37652,38754 37653,38757 37656,38753 37661,38753 37661,38758 37663,38763 37664,38763 42664,38768 42666,38765 42668,38770 42664,38767 42659,38768 42659,38773 42654,38771 42659,38775 42661,41775 42663,41778 42665,41781 42669,41782 42667,41779 42669,41784 42672,41781 42672,41783 42672,41780 42672,41783 42675,41784 42675,41788 42676,41792 42677,41792 42675,41793 42680,41793 42676,41796 42681,41801 42685,41804 42684,41806 42685,41804 42690,41802 42692,41805 42696,41800 42697,41802 42698,41804 42700,41809 42704,41813 42705,36813 42708,36813 42704,36810 42703,36811 42705,40811 42706,40815 46706,40816 46708,40820 46708,40818 46712,40822 46717,40825 46720,40829 46724,40827 46727,40831 46727,40833 46731,40829 46733,40830 46733,36830 46738,36830 46741,36834 46744,36831 46749,36826 46748,36822 46748,36824 46751,36819 46755,36823 46758,36823 46762,36824 46766,36822 46769,36826 46772,36831 46774,36828 42774,36833 42776,36833 42777,36838 42782)')));
-INSERT INTO t1(g) VALUES (ST_linefromtext(concat('linestring','(20 110, 21 110, 26 115, 29 112, 34 108, 39 111, 44 111, 46 116, 46 120, 42 122, 45 118, 48 118, 44 122, 46 127, 47 127, 51 127, 55 123, 52 127, 52 128, 56 130, 60 129, 61 130, 66 131, 67 131, 71 135, 76 136, 77 139, 80 143, 2080 145, 2077 147, 2079 147, 2081 147, 2086 147, 2087 151, 2092 -1849, 2088 -1848, 2088 -1852, 2091 -1848, 2095 -1846, 2092 -1847, 2092 -1848, 2093 -1847, 2094 -1846, 2099 -1843, 2104 -1844, 2102 -1848, 2102 -1848, 7102 -1847, 7105 -1846, 7106 -1843, 7111 -1838, 67 131, 69 135, 68 135, 63 136, 63 137, 64 141, 67 1141, 2067 1139, 2063 1139, 2066 1139, 5066 1139, 5068 1139, 5072 1140, 5072 1145, 5073 1142, 5076 1145, 5077 1145, 5076 1141, 5078 1141, 5073 1143, 5068 1146, 5067 2146, 5070 2151, 5075 2155, 5071 2160, 5073 2161, 5074 2166, 5076 2169, 5071 2173, 5074 2173, 5078 2177, 5076 2173, 5080 2173, 5078 2174, 78 2179, 76 2183, 77 2188, 82 2192, 85 2194, 89 2193, 86 2197, 89 2193, 88 2194, 89 2199, 89 2204, 89 1204, 87 1206, 88 1203, 89 1204, 89 1205, 93 1210, 94 1208, 96 1208, 100 1210, 104 1212, 107 1215, 104 1220, 107 1224, 111 1228, 112 1228, 116 1229, 119 1228, 120 1233, 119 1236, 124 1241, 125 1240, 122 1239, 126 1241, 123 1240, 124 1244, 128 1248, 129 1250, 128 1253, 127 5253, 125 5255, 129 5255, 133 5255, 137 5260, 140 5261, 137 5261, 141 5261, 140 5262, 143 5264, 148 5264, 148 5264, 145 10264, 149 10269, 153 10274, 158 10270, 159 10273, 164 10277, 168 12277, 170 12278, 165 12274, 170 12279, 172 12281, 172 12281, -3828 12281, -3823 12281, -3822 12282, -3823 12280, -3823 12282, -3820 12281, -3823 12279, -3827 12282, -3826 12279, -3822 12284, -3825 12284, -3824 12286, -3820 12287, -3820 12290, -3818 12292, -3816 12293, -3814 12298, -3815 12301, -3817 12304, -3814 12301, -3811 12299, -3809 12303, -3809 12301, -3804 12302, -3804 12302, -3802 12305, -3799 12310, -3801 17310, -3801 17310, -3796 17310, -3801 17314, -3799 17318, -3796 17321, -3795 17321, -795 17325, -795 17327, -794 17329, -791 17330, -790 17326, -787 17331, -782 17335, -778 17339, -774 17343, -772 17343, -769 17346, -768 17349, -763 17352, -763 17353, -761 17357, -758 17354, -758 22354, -754 22350, -750 22353, -746 22356, -750 22352, -746 22351, -744 22349, -743 27349, -741 27350, 259 27354, 262 27353, 263 27356, 268 27352, 268 22352, 271 22351, 273 22351, 274 22351, 275 22352, 275 22356, 280 22352, 281 22348, 284 22349, 284 22346, 285 22351, 285 22351, 290 22353, 294 22351, 294 22352, 295 22352, 300 22352, 305 22355, 308 22356, 311 22356, 310 22358, 312 22360, 313 22365, 313 22362, 313 22364, 313 22364, 317 22360, 322 22362, 327 22367, 328 22370, 323 22375, 320 22377, 320 22379, 316 22379, 318 22379, 323 22380, 323 22380, 324 22376, 34 108, 38 113, 42 118, 42 117, 42 121, 46 123, 51 127, 51 130, 51 133, 55 137, 52 141, 52 143, 51 141, 50 142, 45 142, 44 143, 48 146, 48 142, 43 143, 47 145, 4047 5145, 4047 5150, 4044 5151, 4045 10151, 4043 10154, 4044 10156, 4047 10156, 4043 10160, 4043 10156, 4043 10156, 4048 10157, 4051 10160, 4048 10159, 4053 10161, 4057 10163, 4057 10164, 4058 10165, 4057 10170, 4056 10173, 4056 10176, 4056 15176, 4053 15180, 4049 15181, 4051 15178, 4049 15180, 4049 15180, 4048 15181, 4048 15184, 4045 15188, 4045 15191, 4040 15194, 4042 15198, 4042 15203, 4047 15200, 4049 15201, 4052 15204, 4052 15208, 4052 15212, 4049 15216, 4049 15219, 4051 15220, 4048 15222, 4044 15227, 4044 15232, 4044 15236, 4049 15239, 4052 15240, 4052 15243, 4053 15247, 4055 15247, 4052 17247, 4054 17247, 4054 18247, 4059 18251, 4063 18253, 4066 18253, 4069 20253, 4069 20254, 4069 20259, 4068 20263, 4068 20263, 4069 20259, 4071 20260, 4073 20262, 4074 20258, 4069 20261, 4069 20264, 4071 20269, 4067 20271, 4071 20270, 4072 20271, 4073 20268, 4076 20263, 4072 20268, 4075 20264, 4076 20267, 4079 20272, 4084 20275, 4086 20277, 4086 20281, 4083 18281, 4087 18283, 4088 18280, 4089 18277, 4089 18279, 4094 18281, 4095 18283, 4095 18284, 4097 18284, 4093 18287, 4094 18285, 4096 18287, 4092 18291, 4096 18291, 140 5261, 140 5259, 140 5262, -1860 5258, -1858 5260, -1854 5262, -1849 5259, -1848 5264, -1845 5264, -1845 5267, -1845 5262, -1848 5261, -1848 5263, -1849 5261, -1853 5262, -1851 5265, -1847 5265, -1847 5262, -1847 5263, -1843 5268, -1845 5268, -1848 5272, -1850 5270, -1851 5274, -1854 5269, -1850 5266, -1845 5267, -1840 5267, -1840 5264, -1840 5269, -1839 5269, -1842 5269, -1840 5274, -1835 5278, -1836 5283, -1841 5279, -1840 5284, -1836 5285, -1836 5289, -1831 5289, -1826 5292, -1822 5293, -1826 5295, -1829 5295, -1824 5295, -1828 5297, -1824 5300, -1820 5305, -1824 5306, -1824 5306, -1824 5306, -1823 5301, -1818 5303, -1814 5307, -1814 5303, -3809 12303, -3807 12306, -3804 12306, -3804 12306, -3801 12308, -3796 12308, -3795 12308, -3791 12310, -3786 12310, -3781 12313, -3814 12298, -3809 12303, -3807 12301, 7102 -1847, 7100 -1850, 7104 -1850, 7109 -1852, 7109 -1854, 7112 -1850, 7112 -1847, 7115 -1847, 7117 -1847, 7122 -1847, 7125 -1843, 7126 -1848, 7127 -1848, 7129 -1848, 7133 -1848, 7131 1152, 7131 1149, 7135 1154, 7139 1152, 7140 1151, 7145 1153, 7149 1158, 8149 1159, 8154 3159, 8149 3161, 8145 3162, 8146 3164, 8146 3168, 11146 3171, 11148 3171, 11150 3167, 11154 3165, 11150 3163, 11151 3167, 11152 3165, 11153 3170, 11156 3175, 11156 3174, 8146 3164, 8146 3167, 8146 3170, 8147 3170, 8148 3175, 8148 3178, 8146 3178, 8146 3178, 8147 3180, 8143 3184, 3143 3186, 7143 3187, 7143 7187, 7138 7189, 7138 7189, 7135 7191, 7138 7191, 7133 7194, 7138 7198, 7139 7201, 7143 7200, 7141 7203, 12141 7204, 12145 7204, 12145 7203, 12146 7207, 12147 7204, 12143 7204, 12138 7199, 12138 7195, 12139 7195, 12139 7200, 12141 7201, 12142 7201, 12139 7205, 12142 7208, 12142 7213, 12145 7213, 12147 7214, 12149 7218, 12150 9218, 12154 9222, 12151 9222, 12151 9225, 12151 9224, 12152 9226, 12155 10226, 12155 10230, 12158 10231, 12161 10227, 12162 10224, 12163 10229, 12163 10231, 12165 10228, 12165 10227, 12160 10228, 12160 10231, 12160 10235, 12157 12235, 12159 12230, 7138 7189, 7141 7193, 7141 7193, 7141 7192, 7139 7195, 7141 7195, 7142 7193, 7145 7195, 7146 7193, 7146 7194, 7151 7197, 7154 7198, 7156 7202, 7155 7207, 7150 7211, 12150 7213, 12148 7213, 12147 7217, 12142 7221, 12141 7223, 12143 7223, 12140 7222, 12145 7222, 13145 7224, 13142 7228, 13144 7232, 13139 7235, 13144 7239, 13148 7243, 13151 7247, 13150 7251, 13152 7252, 13157 7253, 13157 7257, 13157 7257, 13157 7262, 13159 7264, 13164 7259, 13161 7259, 13165 7262, 13166 7262, 13166 7267, 13169 7268, 13169 8268, 13167 8269, 13171 8269, 13173 13269, 13177 13265, 13178 13263, 13178 13263, 13182 13266, 13183 13266, 13185 13266, 13190 13269, 13193 13271, 13193 13269, 13196 13271, 13193 13273, 13194 13268, 13198 13273, 13200 13276, 13202 13276, 13204 13274, 13209 11274, 13213 11274, 13213 11277, 13215 11278, 13219 11279, 13224 11280, 13224 11276, 13228 11278, 13233 11281, 13235 11286, 13238 11288, 13240 11288, 13238 11290, 13238 11292, 13238 11287, 13238 11288, 13240 11293, 13243 11296, 13246 11296, 13247 11293, 13243 11298, 13246 11302, 13251 11305, 322 22362, 326 24362, 330 24362, 329 24367, 328 24363, 329 24365, 331 24369, 336 24371, -664 24371, -668 24372, 51 127, 48 131, 48 133, 51 135, 51 140, 49 139, 47 142, 3047 139, 3044 142, 3046 143, 3046 148, 3051 148, 3055 146, 3057 141, 3060 140, 3055 143, 3050 146, 7050 142, 7050 3142, 7050 3143, 7050 3144, 7052 3149, 7055 1149, 7052 1150, 7055 5150, 7050 5154, 7049 5150, 10049 5151, 10045 5151, 10049 5151, 10052 5156, 10054 5159, 10056 5160, 10058 5161, 10058 5163, 10060 5166, 10064 5168, 10064 5173, 10068 9173, 10070 9172, 10065 9168, 10065 9173, 10063 9175, 14063 9176, 14063 9178, 284 22346, 289 22351, 290 22351, 290 22347, 287 22343, 282 22342, 280 22345, 281 25345, 286 25347, 13243 11298, 13248 11300, 13245 11300, 13246 11295, 13247 11295, 13246 11295, 13248 11299, 13253 11304, 13255 11309, 13255 11310, 13260 11309, 13257 11310, 13258 11313, 13258 11315, 13263 11311, 13267 11307, 13269 11309, 13272 11305, 13277 11302, 13273 11304, 15273 11306, 15278 11310, 15281 11307, 15286 11309, 15288 11309, 15291 11311, 15292 11306, 15294 11309, 15298 11313, 15299 11317, 15300 11320, 15302 11321, 15306 11324, 15308 11328, 15308 11324, 15309 11324, 15314 11324, 15315 11323, 15319 11321, 15317 11325, 15319 11327, 15319 11332, 15321 11337, 15324 11340, 15324 11341, 15324 11341, 15326 11345, 15326 11349, 15327 14349, 15330 13349, 17330 13350, 17335 13353, 17339 13358, 17340 13362, 17344 13362, 17348 13357, 17350 13357, 17347 13357, 17350 13358, 17349 13358, 17349 13358, 17349 13359, 22349 13362, 22351 13359, 22353 13359, 22358 13358, 22360 13358, 22363 13359, 22364 13359, 22360 13359, 22361 13363, 22366 13368, 22371 13373, 22374 13377, 22378 13375, 22379 13375, 22379 13373, 22383 13378, 22388 13383, 22389 13380, 22389 13384, 22394 13382, 22392 13378, 22394 13382, 22393 13382, 22393 13379, 22394 13382, 22392 13384, 22395 13386, 22400 13391, 22400 10391, 22404 10395, 22401 10396, 22402 10396, 22402 10398, 22406 10395, 22405 15395, 22407 15396, 22409 15396, 22414 15391, 22414 15394, 22414 15398, 22410 15400, 26410 15402, 26409 20402, 26413 20406, 26417 20410, 26419 20415, 26422 20411, 26424 20411, 31424 16411, 31423 16409, 31423 16414, 31425 16414, 31428 16418, 31428 16414, 31432 16419, 31432 16422, 31437 16423, 31439 16424, 31440 16426, 31440 16429, 31440 16429, 31443 16431, 31441 16435, 31443 16440, 36443 16440, 36445 18440, 36444 18441, 36442 18444, 36442 18440, 36442 18444, 36444 18449, 36445 18450, 36449 18455, 37449 23455, 37454 23460, 37458 23459, 37460 23463, 37458 23465, 37460 23467, 37462 23470, 37466 23473, 37462 23478, 37464 23480, 37463 26480, 37468 26483, 37472 26487, 37473 26492, 37476 26493, 37476 26489, 37476 26487, 37476 26492, 37472 26496, 37476 26501, 37476 26503, 37480 26499, 37485 26503, 37485 26505, 37490 26500, 37493 26503, 37497 26499, 37502 26500, 37502 26501, 37502 26505, 37499 26503, 37499 26503, 37497 26508, 37500 26508, 37496 26513, 37499 26518, 37497 26519, 37500 26518, 37505 26518, 37510 26516, 37512 26520, 37513 26523, 37511 26527, 37508 26532, 37509 26536, 37514 26540, 37515 26542, 37512 26546, 37514 26548, 37519 26547, 37524 26550, 37529 26555, 37527 26559, 37531 26562, 37526 26567, 37526 26566, 37529 26566, 37524 26566, 37524 26563, 37528 26565, 37524 26563, 37525 26565, 37525 26560, 37526 26562, 40526 26564, 40526 26567, 40523 26571, 40527 26570, 40529 26572, 40534 26576, 40536 26573, 40535 26569, 40533 26569, 40537 26573, 40537 26574, 40541 26576, 40546 26579, 40545 26579, 40546 26583, 40550 26588, 40551 26585, 40555 26589, 40558 26594, 40554 22594, 40559 22598, 40558 22599, 40563 22596, 40563 22597, 40567 22597, 40570 22597, 40575 22592, 40572 22594, 40572 22595, 40572 22592, 40575 22594, 40575 22597, 40570 22597, 40569 22601, 40569 22603, 40573 22603, 40576 22604, 40576 22608, 42576 22611, 42579 22611, 42579 22616, 42581 22620, 38581 22623, 38582 22621, 38582 22618, 38577 22623, 38581 22623, 38581 18623, 38584 18618, 38584 18621, 38588 18626, 38592 18629, 38592 18626, 38596 18625, 38598 18620, 38599 18618, 38599 18622, 38602 21622, 38603 21622, 38607 21624, 38609 25624, 38613 25624, 38610 25621, 38610 25625, 38610 25629, 38613 25627, 38617 25627, 38617 25624, 38618 25626, 38621 25628, 38622 25629, 38622 26629, 38625 26631, 38625 26631, 313 22362, 313 22363, -1687 22364, 2313 27364, 2314 27364, 2314 27364, 2319 27366, 2319 27366, 2321 27363, 2321 27368, 2320 27363, 2323 27368, 2328 27371, 2327 27375, 2328 27377, 2328 27377, 2327 27381, 2331 27381, 2329 27381, 2332 27383, 2335 27383, 2333 27383, 2333 27385, 2338 27385, 6338 27386, 6338 27387, 40529 26572, 40533 26576, 40535 26578, 40540 26580, 40535 26584, 40540 26589, 40541 26592, 40538 26587, 40542 26591, 40541 26592, 40537 26597, 40542 26598, 40546 26601, 40550 26606, 40550 26605, 40551 26606, 40549 26606, 40550 26607, 40555 26610, 40550 26610, 40550 26607, 40553 26612, 40558 26616, 40561 26620, 40556 26623, 40558 26623, 40558 26627, 42558 26627, 42558 26628, 42562 26628, 42564 26630, 42565 26634, 42566 26634, 42566 26638, 42561 26639, 42564 26639, 42567 26641, 42564 26642, 42566 26646, 42566 26645, 42570 26645, 42574 26645, 42574 29645, 42576 29646, 39576 29645, 39576 34645, 39578 34647, 39583 34642, 39580 34642, 39576 34646, 39576 34649, 39574 35649, 34574 35652, 34579 35655, 39579 35659, 43579 35663, 43582 35659, 43577 35662, 43580 35662, 43583 35666, 43579 39666, 43574 39662, 43574 39665, 43574 39668, 43574 39670, 43578 39674, 43579 39671, 43582 39675, 43578 39677, 43575 39677, 43576 39681, 43571 39683, 43569 39683, 43570 39687, 43565 39690, 43568 39694, 43568 39696, 43570 39698, 43570 39699, 41570 39695, 41572 39696, 41573 39696, 41573 39697, 41573 39702, 41573 39702, 41576 39702, 41571 39702, 41572 39703, 41572 39708, 41574 39713, 41575 39716, 41580 39717, 41581 39721, 41586 39723, 41587 39724, -1848 5272, -1843 5272, -1845 5270, -1840 5272, -1838 5267, -1843 5268, -1841 5268, -1837 8268, -1837 8271, -1837 8276, -1836 8280, -1832 8277, -1832 8277, -1831 8278, -1835 8283, -1834 8287, -1832 8290, -1834 8286, -1832 8283, -1833 8283, -1832 8284, -1834 8287, -1839 8292, -1844 8293, -1841 8290, -1836 8290, -1839 8289, -1836 8289, -1832 8292, -1827 8295, -1823 8290, -1823 8293, -1823 8291, -1822 8295, -1820 8298, -1819 8302, -1816 8304, -1816 8300, -1812 8300, -1809 8299, -1806 8296, 1194 8300, 1194 8301, 1197 11301, 1194 11305, 1197 11309, 1199 11304, 1195 11304, 1195 11300, 1195 11297, 1196 11298, 1201 11296, 1206 11296, 1207 11298, 1212 11296, 1210 11292, 1206 11294, 1207 11293, 1209 8293, 1204 8288, 1206 8286, 1206 8285, 1208 8285, 1210 8285, 1214 8287, 1214 13287, 1215 13291, 1215 13294, 1218 13297, 1216 13293, 1219 13290, 1214 13295, 1210 13292, 1210 13296, 1211 13301, 1210 13300, 1206 13302, 1207 13307, 1211 13312, 1206 13312, 1211 13308, 1212 13308, 1216 13313, 1216 13318, 1217 13318, 1221 13318, 1221 13323, 1226 13324, 1231 13325, 1234 13329, 1235 13333, 1233 13333, 1236 13338, -2764 13340, -2767 13341, -2763 13344, -2760 13349, -2758 13346, 2242 13346, 2240 13346, 2244 13346, 2248 13349, 2248 13350, 2246 13352, 2241 13352, 2242 13355, 2242 13356, 2247 13361, 2250 13361, 2245 13366, 2249 13366, 2250 13366, 2254 13367, 2258 13367, 2258 13367, 2262 13371, 2257 13376, 2253 13373, 2253 13373, 2254 13376, 2251 13380, 2256 13382, 2257 13386, 2261 13383, 2264 13383, 2269 13385, 2264 13385, 2264 13387, 2267 13387, 2271 13389, 2272 13390, 2273 13393, 2269 13395, 2273 13390, 2277 13395, 2275 13396, 2277 13391, 2279 13394, 2276 13394, 2277 13398, 2282 13399, 2282 11399, 2283 14399, 2281 14404, 2279 14407, 2275 14410, 2276 16410, 2276 16414, 2281 16414, 2286 16415, 2282 16413, 2282 16413, 2284 16413, 2284 16415, 2284 16416, 2282 16417, 3282 16422, 3286 16422, 3287 16427, 3291 16427, 3294 16431, 3296 16433, 3298 16435, 3299 16440, 3300 16439, 3305 16439, 3307 16438, 3307 16440, 3307 16440, 3311 16441, 3311 16442, 3310 16443, 3310 16443, 3308 16448, 3304 16445, -1696 16441, -1701 16442, -1697 16442, -1695 16442, -1696 16443, -1693 16440, -1688 16445, -1685 16450, -1681 16454, -1680 16455, -1682 16457, -1680 16461, -1680 16461, -1684 16464, -1679 16463, -1678 16460, -1675 16464, -1679 16465, -1677 16468, -1672 16469, -1671 16473, -1667 16475, -1667 16480, -1663 16478, -1663 16482, -1662 16482, -1662 16483, -1659 16478, -1654 16475, -1653 11475, -1658 11477, -1661 11479, -1664 11484, 3336 15484, 3340 15480, 3344 15475, 3347 15475, 3347 15474, 3352 15473, 3349 15478, 3353 15480, 3354 15477, 3355 15480, 3352 15481, 3352 15483, 3353 15486, 3354 15488, 3353 15491, 3355 15491, 3360 15491, 3355 15490, 1219 13290, 1224 13295, 1224 13295, 1227 13290, 1231 13290, 1233 13285, 1237 13284, 1238 13285, 1243 13286, 1247 13289, 1249 13289, 1249 13291, 1252 13291, 1249 13294, 1249 13299, 1249 13302, 1254 13305, 1251 13308, 1254 13308, 3254 13308, 3249 13308, 3251 13312, 3256 13312, 3259 13312, 3263 17312, 3263 17313, 3263 17310, 3261 17309, 3264 17314, 3265 17312, 3264 17315, 3261 17318, 3261 17318, 3259 17313, 3256 17313, 3255 17313, 3257 17314, 3255 17316, 3257 17316, 3257 17316, 3258 17311, 3259 17311, 3258 17315, 3258 17317, 3257 17321, 3253 17321, 3250 17325, 3255 17329, 3258 17330, 3260 17328, 3260 17331, 3265 17326, 7265 17329, 7267 17332, 7265 17334, 7267 17337, 7272 17337, 7275 17337, 7280 17340, 4280 21340, 4280 21344, 4281 21344, 4283 21344, 4288 24344, 4292 24347, 9292 24351, 9296 24353, 9298 24351, 9300 25351, 9303 25352, 9303 25352, 9306 25357, 9305 25361, 9305 25356, 11305 25359, 11306 25362, 11309 25362, 11314 25362, 11314 25365, 11312 25369, 11315 25369, 11316 25373, 11321 25375, 11323 25375, 11327 25370, 11331 25369, 11332 25370, 11331 25374, 11332 25369, 11336 25371, 11340 25370, 11345 25367, 11350 25363, 11347 25360, 11350 25361, 11351 25362, 11351 25362, 11354 25364, 11358 30364, 11362 30369, 11362 30369, 11364 30369, 11369 30371, 11370 30373, 15370 30374, 15375 30375, 15378 30377, 14378 30382, 14379 30387, 14383 30382, 14388 30384, 14390 30386, 14393 30389, 14395 31389, 16395 31393, 16398 31398, 16398 31401, 16394 31404, 16397 31409, 16400 31413, 16400 31417, 16399 31419, 16398 31421, 16403 31422, 16403 31426, 16404 31423, 16409 31424, 16413 31423, 16408 31427, 18408 31431, 18413 31436, 18417 28436, 18419 28441, 18420 28445, 18416 28442, 18419 28439, 18418 28443, 18422 28446, 18425 28451, 18429 28448, 21429 28449, 21430 28454, 22430 28459, 22434 28461, 22438 28462, 22443 28462, 22447 28467, 22450 28472, 22453 28469, 22458 28472, 22455 28472, 22460 28475, 22465 28477, 22462 28479, 22461 28476, 22465 28480, 22466 28476, 22470 28472, 22470 28475, 25470 28470, 25473 28472, 25475 28468, 25475 28468, 25477 29468, 25478 29470, 25481 29465, 25478 29466, 25478 29468, 25480 29468, 25485 29465, 25486 29464, 25488 29462, 25488 29466, 25492 29464, 25497 26464, 25500 26467, 25497 26472, 25497 26476, 25497 26476, 25501 26478, 25506 26480, 25506 26482, 25511 26480, 25515 26483, 25516 26485, 25521 26481, 25521 26484, 25520 26485, 25521 26488, 25526 26487, 25529 26488, 25524 26488, 25528 26491, 25530 26496, 25535 26500, 25537 26502, 25537 26502, 25541 26507, 25544 26508, 25545 26509, 25549 26514, 25554 26514, 25553 26512, 25552 26516, 25555 26514, 25559 26514, 25556 26515, 25554 26512, 25558 26509, 25558 26510, 25562 26510, 25562 26511, 25562 26510, 25567 26505, 25569 26508, 25571 26508, 25570 26512, 25573 26512, 25573 26515, 25578 26515, 25583 26520, 25583 26523, 25584 26525, 25587 26526, 25590 26531, 25590 26530, 25586 26534, 25589 26538, 25591 26533, 25595 26537, 25600 26542, 25601 26544, 25601 26544, 25601 26544, 25606 26547, 25605 26547, 25605 26542, 25608 26542, 25611 26544, 25613 26546, 25614 26551, 25614 26551, 25614 26552, 25619 25552, 25614 25552, 25615 25551, 25618 25549, 25618 25553, 25620 25555, 25622 25559, 25622 25555, 25624 25554, 25627 25555, 25624 25559, 25621 25561, 25619 25560, 25624 28560, 25627 28555, 25632 28550, 25636 28552, 25641 28557, 25645 28557, 25640 25557, 25636 25557, 25636 25561, 25641 25561, 25645 25562, 25646 25557, 25648 25560, 25649 25564, 25652 25566, 25652 30566, 25652 30566, 25652 30568, 25652 30570, 25654 30574, 25658 30575, 25663 31575, 25664 31579, 25665 31583, 25664 31583, 25667 31585, 25668 31588, 25673 31586, 25676 31585, 25676 31588, 25678 31588, 25675 31591, 25680 31590, 25681 31585, 30681 31588, 30677 31593, 30682 31594, 35682 31594, 35677 31593, 35679 31595, 35682 31594, 35683 31591, 35686 31592, 35687 31593, 35691 31596, 35691 31597, 35694 31601, 35698 31601, 35702 34601, 35701 34603, 35705 34608, 35705 34610, 35704 34605, 35707 34607, 35707 34610, 35710 34607, 35715 34608, 35719 34607, 35721 34612, 35717 34612, 35713 34612, 35715 34613, 35716 34609, 35716 34614, 35716 34618, 35720 34620, 35721 34621, 35724 34622, 35724 34625, 35727 34629, 35727 34630, 35727 34633, 35727 34635, 35727 34639, 35732 34640, 35729 34642, 35733 34644, 35737 34646, 35741 34649, 35743 34649, 35744 34653, 35740 34653, 35740 34649, 35743 34651, 38743 34654, 38743 37654, 38744 37650, 38748 37655, 38751 37656, 38755 37657, 38755 37661, 38759 37660, 38758 37664, 38763 37664, 38767 37664, 38762 37664, 38761 37664, 38762 41664, 38762 41664, 38764 41669, 38759 41671, 43759 41673, 43754 41678, 43754 41681, 43759 41676, 43760 41681, 45760 41684, 45760 41683, 45764 41687, 45767 41687, 45771 41687, 45772 41688, 45770 46688, 45775 46692, 45778 46696, 45776 46698, 45777 46701, 45780 46699, 45778 46702, 45776 46706, 45781 46706, 45786 46708, 45789 46710, 45793 46715, 45788 46711, 45792 46715, 45795 46719, 45798 46723, 45801 46728, 45799 46732, 45804 46730, 45799 46733, 45803 46737, 45804 46737, 45805 46736, 45806 46736, 45807 46736, 45810 46739, 45812 46744, 45812 46748, 2328 27377, 2324 27381, 2325 27383, 2327 27387, 2327 27386, 2324 27386, 2325 27386, 5325 23386, 5327 23389, 5331 23390, 5332 23394, 5337 23396, 5332 23396, 5332 23399, 5331 23399, 5335 23403, 5335 23406, 5340 23409, 5341 23409, 5336 23410, 5331 23405, 5334 23407, 5332 23411, 5335 23413, 5330 20413, 5326 20415, 5326 20418, 5331 20420, 5330 20425, 5327 20425, 5331 20428, 5332 20428, 5337 21428, 5333 21431, 5335 21435, 5336 21437, 5331 21438, 5332 21441, 5335 21444, 5340 21441, 5340 21444, 5336 21445, 5335 21442, 5331 26442, 5334 26439, 5337 26443, 5339 26444, 5340 26448, 5344 26443, 5344 26446, 5347 26444, 5351 26442, 5354 26446, 5351 26449, 5350 30449, 5352 30451, 5352 30448, 5356 30448, 5361 30447, 5365 30449, 5369 30450, 5369 30452, 5369 30457, 5373 30459, 5373 30457, 5375 30462, 5377 30465, 5382 30467, 5386 30467, 5385 30463, 5386 30463, 5385 30463, 5387 30464, 5392 30463, 5394 30468, 5396 30468, 5391 30469, 5395 30473, 5393 30473, 5393 30473, 5397 30478, 5398 30474, 5401 30474, 5403 30471, 5403 30472, 5406 30474, 5402 30469, 5403 30466, 5405 30471, 5406 30471, 5411 30473, 5414 30477, 5414 30481, 5409 30485, 8409 30490, 8410 30493, 8412 30494, 8412 30493, 8415 30494, 8416 30497, 8416 30500, 8421 30505, 8422 30506, 8417 30511, 13417 30513, 13413 30510, 13416 30511, 13414 30515, 13414 30519, 13419 30522, 13421 30527, 13420 30531, 13424 30533, 13420 30535, 13415 35535, 13411 35535, 13415 35536, 13419 35541, 13421 35537, 13425 35533, 13426 35533, 13425 35528, 13430 35529, 13435 35530, 13440 35534, 13445 35535, 13450 35535, 13454 35536, 13457 35540, 13459 35540, 13454 35540, 13457 35543, 13454 35539, 13459 35544, 13459 35548, 18459 35550, 18462 35551, 22462 35550, 22467 35554, 22468 35558, 22470 35556, 22475 35559, 22473 35563, 22472 35568, 22474 35568, 22472 35573, 22476 35573, 22476 35575, 22479 35577, 22484 35580, 22489 35584, 22490 35587, 22491 35589, 22495 35589, 22498 35589, 25498 35590, 25495 35586, 25496 35589, 25500 35589, 25498 35589, 25500 35591, 25505 35595, 25505 35597, 25501 35594, 25501 35595, 25497 35595, 26497 35599, 29497 35595, 29497 35597, 29500 35601, 29500 35605, 29502 35610, 29503 30610, 29504 30607, 29507 30607, 29512 30610, 29513 30610, 29516 30611, 29518 30614, 29520 30612, 3261 17309, 3265 17308, 3269 17307, 3273 17312, 3271 17316, 3271 17317, 3276 17319, 3279 17319, 3284 17315, 3287 17317, 3285 17313, 3280 17314, 3277 17319, 3277 17321, 3278 17326, 3282 17328, 3282 17328, 3278 17329, 3279 17329, 3278 17332, 3280 17328, 3275 17333, 3279 17335, 3282 17330, 3283 17332, 3278 17328, 3279 17328, 3279 17326, 3279 17325, 3279 17325, 3283 17327, 3284 17331, 3284 17336, 3289 17339, 3290 17339, 3290 17342, 3292 17341, 3296 17344, 3296 17345, 3301 17345, 3301 12345, 3301 12346, 3306 12343, 3303 14343, 3307 14344, 3309 14345, 3313 14347, 3315 14347, 3316 16347, 3312 16345, 3312 16350, 3314 16352, 3313 16353, 4313 16350, 4318 16352, 4323 16348, 4326 16352, 4324 16353, 4325 16350, 4325 16350, 4328 16354, 4324 16358, 4325 16360, 4327 16365, 4327 16362, 4324 16366, 4327 20366, 4327 20370, 4324 20371, 4328 20376, 4328 20378, 4333 20377, 4335 20377, 4340 20380, 4341 20383, 4343 20386, 4340 20388, 4341 20390, 4342 20387, 4342 20387, 4337 20392, 4338 20394, 4343 20394, 4348 20395, 4350 20395, 4351 20397, 37499 26503, 37496 26500, 37498 26504, 37498 26505, 37501 26510, 37499 26506, 37500 26506, 37502 29506, 37502 29511, 37507 29512, 37508 33512, 37510 33517, 37515 33522, 37519 33526, 37518 33524, 37523 33525, 37523 33529, 37518 33534, 37521 33532, 37522 33532, 37526 33534, 37529 33534, 37527 33531, 37530 33534, 37535 33537, 37536 38537, 37538 38540, 22360 13359, 25360 13364, 25363 13362, 25364 13366, 25364 13366, 25367 13369, 25365 13371, 25361 13373, 25359 13378, 25362 13378, 2249 13366, 2254 13370, 2256 13367, 2259 13367, 2263 13362, 2266 13358, 2266 13360, 2271 13365, 2274 13367, 2276 13367, 2277 13367, 2275 13366, 2276 13369, 2280 13369, 2282 13374, 2286 13370, 2286 13369, 2291 13372, 2292 13370, 2295 13372, 2300 13377, 2300 13376, 2297 13379, 273 22351, 275 22354, 4275 22351, 4271 22352, 4272 22354, 4273 22359, 4274 22364, 4278 22367, 4283 22369, 4286 24369, 4281 24369, 4284 24369, 4287 24369, 4289 24368, 4291 24366, 4296 24364, 4297 24366, 4300 24369, 4303 24373, 1303 24374, 1303 24375, 1307 24379, 1307 24380, 1309 24381, 1314 24384, 1316 24386, 1320 24384, 1318 24386, 1318 24391, 1320 24391, 1320 29391, 1323 29391, 1318 29387, 1322 29390, 1323 29393, 1328 29393, 1329 29393, 2329 29398, 2329 29398, 2334 29397, -664 24371, -661 24372, -659 24372, -654 24375, -651 24376, -647 24376, -645 24378, -641 24374, -636 24379, -633 24384, -636 24386, -636 24388, -636 24388, -634 24392, -635 24394, -630 24390, -628 24390, -627 24390, 373 24393, 378 24398, 376 24396, 379 24401, 3379 24404, 6379 24409, 6380 24412, 6375 24410, 6372 24410, 6377 24407, 6372 24407, 6377 24407, 6381 24410, 6376 24413, 6380 24415, 6382 24416, 6380 24419, 6380 24423, 6385 24427, 6387 24429, 6389 24432, 6392 24437, 6388 24434, 6388 24439, 6389 24440, 6390 24444, 6389 24448, 6385 29448, 6385 29451, 6388 29455, 6384 29450, 6389 29451, 6392 29456, 6395 29456, 6399 29459, 6402 29463, 6402 29467, 6399 29471, 6395 29471, 6397 29474, 6399 29477, 6401 29472, 6396 29471, 6399 29474, 6398 29477, 6398 29474, 6395 29469, 6391 29473, 6392 29474, 6391 29469, 6391 29472, 6394 29474, 6390 33474, 6392 33470, 6393 33470, 6394 33471, 6396 33471, 324 22376, 324 22378, 325 22381, 329 22382, 333 22386, 332 22387, 334 22390, 335 22387, 333 22387, 332 22391, 334 22395, 334 22400, 339 22401, 341 22398, 342 22403, 342 22402, 342 22400, 345 22400, 345 22400, 343 22404, 344 22408, 345 22406, 350 22407, 347 22411, 349 22415, 344 22415, 347 22417, 342 22421, 347 22421, 350 22426, 350 22430, 353 22431, 354 22436, 354 22440, 4354 22442, 4355 22446, 4356 22448, 4356 22451, 4359 22453, 4362 22454, 4366 22454, 4369 22455, 4371 22457, 4368 22459, 4371 22457, 4375 22462, 4379 22463, 4382 22463, 4382 22468, 4387 22471, 4387 22471, 4392 22473, 4387 22473, 4387 22476, 25573 26512, 25576 26511, 25580 26516, 25583 26516, 25583 26516, 25585 26512, 25585 26517, 25589 26520, 25591 26519, 25592 26519, 25593 26521, 25591 26524, 25589 26526, 23589 26530, 23587 26535, 23591 26538, 23594 26542, 24594 26547, 24590 26549, 24595 26551, 24600 26547, 24600 26552, 24604 26549, 24600 26544, 24602 26549, 24602 26552, 24602 31552, 24607 31553, 24610 31555, 24615 31556, 24617 36556, 24618 36561, 24621 36561, 24624 36564, 24624 36568, 24629 35568, 24629 35573, 24634 35573, 25634 35574, 25637 35573, 25638 35577, 25638 35577, 25640 35580, 25643 35584, 25643 35587, 25643 35592, 25644 40592, 20644 40597, 20647 40597, 20652 40599, 20653 40595, 20653 40598, 20650 40595, 20650 40595, 20654 40600, 20654 40600, 20658 40601, 20658 40604, 20658 40605, 20661 40602, 20664 40601, 20664 40601, 20665 40604, 20670 40605, 20667 40610, 1217 13318, 1216 13323, 1214 13321, 1211 13316, 1212 13316, 1213 13321, 6213 13324, 6216 13324, 6218 13324, 6213 13327, 6216 13322, 6216 13327, 6216 13328, 6218 13323, 6221 13327, 6220 13325, 6221 13325, 6220 13330, 6223 13333, 6227 13335, 6232 13339, 6233 13343, 6233 13347, 6237 13342, 6236 13346, 6236 13348, 6238 13349, 25526 26487, 25523 26488, 25526 26493, 25529 26491, 25531 26488, 25532 26486, 25536 27486, 25541 27490, 25539 27492, 25543 27487, 25546 27490, 25549 27494, 25552 27495, 25552 27495, 25556 27490, 25561 27490, 25565 27493, 25563 27493, 25565 27497, 25563 27495, 25565 27497, 25565 27499, 25566 27501, 25565 27501, 25565 27501, 25560 27502, 25565 27503, 25567 27507, 25569 27507, 25571 27507, 25569 27508, 25567 27509, 25567 27509, 25567 27509, 25568 27509, 25572 27505, 25572 27501, 25576 27502, 25572 32502, 25572 32505, 25575 32505, 25578 32501, 25578 32502, 25579 32505, 25581 32507, 25585 32508, 25590 32511, 25594 32516, 25598 32511, 25601 32511, 25596 32507, 25599 32510, 25599 32514, 25596 32513, 25596 32514, 25598 32517, 25594 32517, 25596 32519, 25596 32524, 25600 32524, 25604 32521, 25605 32522, 27605 32524, 27609 32527, 27610 31527, 27615 31531, 27617 31531, 30617 31534, 30619 31534, 30620 31536, 30621 31540, 30625 31541, 30625 31542, 30627 31542, 30628 31545, 30629 31545, 30626 31544, 30625 31544, 30626 31549, 34626 31550, 34621 31547, 34625 31549, 34626 31553, 34626 31552, 34628 31554, 34628 31559, 34628 31555, 34630 31559, 34635 31559, 34638 31563, 34636 31568, 34638 31568, 34641 31566, 34641 31564, 36641 31559, 36638 27559, 41638 27561, 41642 27558, 41646 27562, 41649 27563, 41650 27559, 41655 27559, 41660 27559, 41660 27556, 41660 27556, 41662 27554, 41658 27558, 41663 27562, 41666 27565, 41669 27570, 41664 27566, 41665 27567, 41665 27569, 41664 27573, 41663 27573, 41666 27575, 41666 27571, 41661 30571, 41662 30569, 41662 30565, 41667 30570, 41666 30565, 41666 30565, 41666 30566, 41666 30567, 41662 30562, 1314 24384, 4314 25384, 4317 25388, 4317 25389, 4321 25387, 4324 25392, 6324 25391, 6324 25391, 6328 25396, 6323 25401, 6326 25401, 6326 25405, 6321 25408, 9321 25409, 9316 25404, 9314 25406, 9312 25407, 9315 25407, 9315 25407, 9318 25404, 9321 25405, 4321 25400, 8321 25402, 8317 25404, 8317 25400, 8317 25401, 8313 25402, 8309 25398, 8311 25398, 8313 25401, 8317 25406, 8312 25407, 11312 25369, 11313 25369, 11318 25374, 11322 25379, 11327 25379, 11327 25384, 11327 25386, 11328 25382, 14328 25384, 14330 25386, 14333 25387, 14336 25389, 14338 25390, 19338 25390, 19338 25393, 19334 25394, 19334 25395, 19337 25392, 19340 25395, 19344 25397, 19342 25397, 19347 25400, 19347 25398, 19349 25398, 19351 25397, 19353 25401, 19352 25402, 19350 25403, 19351 25407, 19354 25403, 19352 25406, 19356 25404, 19355 25409, 23355 25406, 23356 25406, 23358 25409, 23360 25413, 23362 25417, 23365 25418, 23369 25416, 23367 25415, 23369 25418, 23365 25417, 23369 25420, 23369 25420, 23372 25422, 24372 25418, 24372 25423, 24375 27423, 24380 27423, 24382 27420, 24382 27416, 24382 27414, 24382 27410, 24378 27410, 24376 27414, 24372 27418, 24372 27419, 24373 27424, 24377 27419, 24380 27415, 24377 27419, 24380 27422, 24384 27425, 24385 27430, 24385 27429, 24387 27434, 24392 27435, 24396 27436, 24397 27440, 24401 30440, 24402 30443, 24406 30447, 24405 30443, 24408 30442, 24412 30446, 24408 30450, 24410 30449, 24405 30449, 24410 30446, 24414 30450, 24418 30450, 24418 30453, 19418 30453, 19418 30451, 19420 30456, 19422 30457, 19425 30462, 15425 30466, 15425 30468, 15427 30470, 16427 30471, 16426 30475, 16423 30478, 16428 30478, 16430 30480, 16430 30480, 16426 30478, 16426 33478, 16427 33478, 16429 33481, 16427 33483, 16428 33481, 16424 33484, 16427 33486, 16432 33483, 16432 33482, 16431 33486, 16426 33486, 16429 33488, 16432 33492, 16433 33492, 16436 33492, 16437 33495, 16434 33491, 16438 37491, 16436 37494, 16440 37489, 16445 37486, 16448 37484, 16449 37484, 16449 37486, 16453 37482, 16456 37483, 16460 37483, 16456 37483, 16456 37486, 16461 37490, 16462 37495, 16465 37499, 16466 37496, 16467 37497, 16468 37498, 16470 37501, 16470 37505, 16470 37505, 16475 37507, 16475 37507, 16475 37502, 16478 37498, 21478 33498, 21475 33497, 21478 33493, 21480 33495, 21480 33500, 21480 33496, 21482 33500, 21485 33505, 21486 33508, 21485 33504, 21486 33509, 21486 33509, 21490 35509, 21493 35509, 21496 35510, 21498 35514, 21494 35510, 21494 35513, 21491 35518, 21492 35521, 21489 35523, 23489 35527, 23487 35532, 23489 35537, 23485 35538, 23489 35539, 23490 35541, 23495 35543, 23497 35546, 23497 35550, 23497 35554, 23493 35553, 23490 35556, 23494 35559, 23497 35564, 23502 35563, 23498 35561, 4324 16358, 4319 16362, 4320 16362, 4322 16367, 4317 16367, 4317 16366, 4318 20366, 4322 20369, 4325 20367, 4328 20370, 4331 20371, 4334 20374, 4339 20378, 4340 20379, 4335 20379, 4340 20379, 4343 20381, 4344 20381, 4344 20382, 4345 20385, 4348 20390, 4348 20390, 4348 20390, 4348 20390, 4351 20394, 4354 20399, 4356 20400, 4357 20404, 4360 20404, 4362 20405, 4362 20408, 4365 20409, 4370 20410, 4374 20415, 4373 20420, 4369 20421, 4366 20426, 4369 20424, 4374 20429, 4375 20426, 4376 20422, 4379 20422, 4383 20426, 4384 20427, 4386 20422, 4391 20425, 4387 20427, 4392 20427, 4392 20429, 4394 20433, 4398 20438, 41576 39702, 41580 39706, 41578 39708, 45578 39708, 45577 39713, 45579 39717, 45583 39719, 45583 39722, 45585 39725, 45580 39730, 47580 39726, 47583 39723, 47588 39726, 47588 39730, 47591 39734, 47594 39737, 47599 39737, 47595 39737, 47598 39739, 47599 39739, 47597 39739, 47593 39743, 47595 39748, 47595 39751, 4076 20267, 4079 20272, 4081 20272, 4080 20275, 4080 22275, 4085 22280, 4089 22276, 4090 22279, 4088 22283, 4084 22284, 4086 22286, 4088 22281, 4084 22281, 4089 22285, 4092 22285, 4094 22285, 4094 22290, 4096 22291, 4099 22294, 4099 22295, 4097 22290, 4097 22292, 4097 22297, 4097 22292, 4094 22289, 4091 22290, 4092 22290, 4097 22285, 4102 22290, 4105 22289, 4106 22292, 4106 22293, 4109 22298, 4114 22296, 4119 22294, 4122 22299, 122 22304, 123 22307, 124 22304, 124 22304, 123 26304, 127 26307, 131 26307, 129 26309, 129 26310, 134 26310, 134 26311, 138 26311, 143 26313, 142 26315, 145 26317, 142 26318, 147 26322, 151 26322, 155 26325, 155 29325, 160 29330, 160 29333, 164 29328, 164 34328, 167 34333, 170 34332, 169 34336, 171 34337, 175 34338, 175 34340, 179 34342, 180 34344, 180 34348, 184 34352, 179 34352, 184 34352, 186 34357, 186 34362, 183 34364, 185 34369, 189 34369, 194 34369, 199 34371, 201 34370, 205 34372, 207 34372, 204 34367, 206 34364, 1206 34364, 1207 34368, 1207 30368, 1207 30363, 1208 30365, 1209 30368, 1212 30370, 1212 30370, 1216 30371, 1220 30376, 1221 30379, 1216 30383, 1216 30388, 1219 30386, 1224 30387, 1225 30386, 1227 30384, 1230 30383, 1233 30387, 1234 30387, 1237 30388, 1239 30392, 1244 30390, 1246 30393, 2246 30396, 2243 30399, 2247 30401, 2247 30403, 2246 30398, 2244 30399, 2248 32399, 2248 32399, 2251 32402, 2253 32397, 5253 32394, 5253 32399, 5257 32403, 5257 32401, 5259 32401, 5259 32405, 5263 32410, 5263 32415, 5268 32416, 5273 32420, 5275 32423, 5278 32424, 5283 32426, 5281 32429, 6281 33429, 6286 33433, 6286 33434, 6284 33435, 6284 33432, 6288 33429, 6290 32429, 6290 32425, 6288 32428, 6290 32428, 11290 32431, 11294 32429, 11294 32433, 11292 32438, 11288 32441, 11288 32441, 11285 32446, 11280 32446, 11281 32447, 11285 32449, 11286 32449, 11285 32452, 13285 32451, 13289 32446, 16289 32450, 16284 32449, 16285 32449, 16286 32452, 16287 32452, 16286 32450, 16288 32447, 16292 32450, 16293 32450, 16294 32454, 16293 32454, 16293 32454, 16293 32449, 16289 32451, 16290 32456, 16289 32461, 16293 36461, 16291 36466, 16295 36466, 16296 36466, 16299 36466, 16303 36468, 16308 36473, 16312 36471, 16312 36467, 16315 36463, 16314 36464, 16315 36469, 16315 36473, 16310 36474, 16311 36472, 16316 36474, 16321 41474, 16324 41475, 16327 44475, 16332 44475, 16332 44475, 16332 44477, 16332 44478, 16337 44483, 16334 44481, 8416 30500, 8417 30501, 8421 30501, 8416 30505, 8418 30504, 8420 30499, 8423 35499, 8425 35498, 8429 35501, 8431 35503, 8434 35503, 8438 35507, 8440 35507, 8445 35509, 8442 35512, 8445 35513, 8442 35513, 8442 35515, 8443 35519, 8447 35515, 8450 35516, 8445 35521, 8445 35523, 8444 35528, 8446 35530, 8443 35531, 8438 35531, 8435 35527, 8431 35531, 8432 35534, 8433 35536, 8431 35537, 8435 35539, 8439 32539, 8437 32540, 8441 32540, 8438 32543, 9438 32546, 9436 32541, 9431 32538, 9431 32538, 9435 32541, 9435 32546, 9431 32547, 9436 32542, 9438 32542, 9438 34542, 7438 34542, 7440 34547, 7441 34547, 7441 34547, 7441 34552, 7440 34553, 7440 34556, 7440 34557, 7440 34560, 11440 34565, 11436 34563, 11438 34559, 7438 34557, 7438 34553, 122 1239, 126 1243, 127 1240, 127 1242, 131 1239, 130 1239, 127 1240, 125 1243, 130 2243, 134 2246, 133 2246, 137 2246, 142 2246, 147 2251, 148 2256, 146 2257, 148 2252, 146 2249, 148 2248, 152 2253, 157 2249, 161 2246, 162 2247, 162 2249, 157 2248, 158 2249, 3158 2250, 3161 2252, 3161 2254, 3166 2258, 3167 2261, 3168 2259, 3171 2261, 3173 2266, 3171 2267, 3176 2272, 3179 2277, 3176 2280, 3180 2279, 3175 2283, 3179 2280, 3182 2283, 3184 2288, 3187 2293, 5187 2290, 5187 2292, 5183 2290, 5187 2292, 5186 2297, 5189 2297, 5189 2301, 5192 2303, 5189 2303, 5187 2304, 5183 6304, 5184 6301, 5189 6304, 5191 6302, 5193 6300, 5195 6300, 5195 6300, 5197 6301, 5197 6304, 5199 6301, 5197 6304, 5192 6306, 5193 6310, 5194 6312, 5197 6316, 24397 27440, 24393 27441, 24395 27437, 24400 27440, 24400 27441, 16288 32447, 21288 32447, 21288 32448, 21284 32452, 21285 32450, 21285 32452, 21287 32455, 21283 32460, 21284 32462, 21284 32467, 21284 32472, 21286 32474, 21291 32475, 21289 32475, 21289 32473, 21289 32478, 21286 32481, 21290 32486, 21293 32486, 21293 32490, 21298 32489, 21301 32490, 21303 32491, 21305 32488, 21303 32486, 21307 32491, 21312 32495, 21314 32499, 21315 32495, 21317 32499, 21314 32499, 21316 32502, 21318 32505, 21313 32510, 21313 32512, 21314 32517, 21319 32520, 21321 32520, 21326 32520, 21329 32525, 21330 32530, 21334 32531, 21330 36531, 21333 41531, 21338 41531, 21336 41535, 21339 41537, 21337 41539, 21341 41544, 21342 41544, 21345 41540, 25345 41543, 25342 41546, 25339 41546, 25339 41549, 25337 41546, 25337 41547, 25337 46547, 25341 46552, 30341 46555, 30342 46560, 30345 46561, 30344 46557, 30339 46560, 30343 46565, 30339 46569, 30338 46567, 30340 46568, 24375 27423, 24375 27425, 24377 27428, 24379 27429, 24379 27434, 24376 27439, 24381 27441, 24386 27436, 24387 27438, 24384 27441, 24383 27446, 24383 31446, 24383 33446, 20383 33443, 20385 34443, 20384 34444, 20380 34448, 20383 34450, 20383 34446, 20386 34447, 20390 34450, 20394 34451, 20395 34446, 20395 34451, 20398 29451, 20397 29447, 20401 29447, 20402 29443, 20401 29440, 20406 29443, 20411 29444, 20412 29444, 20412 29448, 20410 29449, 20415 29452, 20415 29455, 20414 29459, 20415 29462, 20420 29465, 20415 29467, 20417 29468, 20418 29468, 20418 29467, 20418 29467, 20420 29468, 20416 29469, 20420 29467, 20415 29464, 20415 26464, 20420 26462, 20423 26463, 20423 26465, 20423 26464, 43580 35662, 43580 35658, 43580 35662, 43580 35664, 43585 35665, 43585 35663, 43585 35666, 43581 35667, 43585 35665, 43589 35670, 25627 25555, 25631 25555, 25632 25558, 25632 25563, 25634 25564, 25629 25565, 25625 25561, 25625 25563, 25626 25565, 26626 25570, 26629 25570, 29629 25575, 29628 25578, 29627 25579, 29624 25583, 29627 25587, 29632 25592, 29634 25593, 29637 25595, 29637 25598, 29639 25602, 29644 25600, 29645 25601, 29646 25601, 29651 25602, 29656 25606, 29658 25606, 29663 25607, 29663 25605, 29666 26605, 29668 26608, 29667 26608, 29670 26611, 29674 26611, 29671 26615, 29673 26620, 29676 26617, 29681 26620, 29682 26620, 29683 26619, 29684 26623, 29681 26621, 29686 26626, 29688 26628, 29691 26628, 29692 26632, 29693 26634, 29695 26629, 29696 26624, 29700 26621, 29705 29621, 29709 29620, 29708 29624, 29711 29627, 34711 29630, 34712 29632, 34712 29631, 2284 16415, 2285 16416, 2285 16416, 2289 16421, 2294 16425, 2299 16425, 2300 16430, 2305 16430, 2306 16433, 2311 11433, 2315 11436, 2310 14436, 2310 14435, 2313 14437, 2312 14441, 2310 14442, 2311 14444, 2313 14444, 2311 14447, 2314 14447, 2316 14451, 2316 14456, 2316 14454, 2311 14455, 2311 14455, 2311 14460, 2315 14465, 2315 14465, 2311 19465, 2311 19465, 2313 19466, 2317 19469, 2320 19469, 2323 19466, 2319 19468, 2323 19471, 2324 19471, 2324 19473, 2324 19473, 2322 19468, 2323 19466, 2324 19465, 2329 19470, 2329 19465, 2324 19465, 2324 19467, 2319 19471, 2320 19475, 2104 -1844, 2109 -1844, 2113 -1842, 2116 1158, 2116 1160, 2117 1161, 2116 6161, 2118 6166, 2123 6169, 2126 6174, 2123 6179, 2126 6183, 2126 6187, 2130 6182, 2128 6183, 2127 6182, 2128 6185, 2124 10185, 2129 10190, 2130 10193, 2132 10192, 2132 10195, 2129 11195, 2129 11199, 2133 11200, 2134 11196, 2133 11201, 2137 11205, 2137 11207, 2141 11203, 2144 11207, 2145 11208, 2149 11212, 2144 11214, 2144 11215, 2149 11216, 2152 11221, 2152 11223, 2153 11223, 2154 11226, 2154 11226, 2150 11228, 2152 11224, 2152 11227, 2148 11222, 2145 11223, 2142 11225, 2145 11222, 2142 11223, 2142 11227, 2147 11229, 2149 11230, 2154 11230, 2157 11228, 2159 11233, 2159 11233, 2155 11237, 2155 11242, 2151 11243, 7151 10243, 7156 10245, 7159 10245, 7164 10247, 7166 10252, 7166 10255, 7171 10257, 7173 10257, 7174 10261, 7179 10264, 7184 10260, 7189 10264, 7193 8264, 7197 8260, 7202 8262, 7206 8262, 7205 8265, 7205 8266, 7207 8270, 7211 8274, 7211 8277, 7216 8277, 7216 8280, 7212 8280, 7213 8280, 7215 8283, 7220 8282, 7224 8287, 7225 8283, 7222 10283, 7223 10287, 7225 10288, 7230 10290, 7232 10294, 7233 10294, 7233 10297, 7234 10298, 7234 10301, 7236 10303, 7231 10299, 7228 10298, 7223 10297, 7225 10299, 7230 10303, 7231 10307, 7234 10311, 7234 10315, 7235 10320, 7236 9320, 7241 9322, 7246 9325, 7243 9330, 7243 9332, 7240 9335, 7237 9334, 7239 9339, 7238 9339, 7238 9341, 7238 9342, 7233 14342, 7232 14337, 7234 14342, 7239 18342, 4084 22284, 4083 22284, 6083 22287, 6078 22289, 6078 22293, 6080 22290, 6082 22291, 6086 22296, 6086 22297, 6087 22297, 6088 22295, 6093 22298, 6094 22297, 9094 22294, 9097 22298, 9098 22299, 9098 22301, 9093 22296, 9098 22299, 9100 22294, 9096 18294, 9099 18294, 9098 18298, 9101 18296, 9100 18301, 9105 18303, 9105 18306, 9105 18309, 9102 18305, 9104 18306, 9108 18309, 9104 18314, 9103 18310, 9105 18312, 9105 18316, 9109 18314, 9109 18319, 9109 18324, 9113 18326, 9113 18330, 9115 18333, 9113 18333, 9118 18333, 9123 18333, 9123 18336, 9125 18335, 9126 18336, 9127 18332, 9129 18329, 9127 18332, 9130 18333, 9135 18333, 9138 18337, 9143 18341, 9144 18346, 9145 18344, 9150 18348, 9154 18345, 9152 18350, 9151 18345, 9151 18345, 9156 18347, 9160 18349, 9163 18350, 9163 18351, 9165 18356, 9166 18356, 9164 18353, 9167 18356, 9167 18355, 9167 18356, 9167 18360, 9165 18356, 9169 18357, 9169 18353, 9170 18355, 9170 18351, 9175 18351, 9177 18351, 9181 18352, 9184 18353, 9189 18356, 9188 18361, 9191 18364, 9194 18364, 9198 18366, 13198 18371, 13198 18373, 13198 18375, 13201 18378, 13196 18378, 13199 18379, 13202 18381, 13207 18384, 13212 18388, 13211 18383, 13211 18378, 13215 18379, 13218 20379, 13214 20379, 13217 20379, 13213 20379, 13213 20376, 13210 20377, 13206 20377, 13206 20373, 13207 20373, 13209 20370, 13214 20371, 13218 20371, 13223 20376, 13224 20381, 13227 20385, 13228 20390, 13232 20387, 9232 20392, 9230 20388, 9230 20390, 9225 20393, 9225 20396, 4225 20401, 4225 20400, 4227 20403, 4224 20408, 4222 20412, 4222 20415, 4225 20420, 4229 20425, 4232 20422, 4236 20425, 4234 20426, 4238 20427, 4240 20427, 4241 20427, 4237 20431, 4233 20431, 4232 20430, 4230 20432, 4234 20431, 4234 20435, 4238 20437, 4243 20435, 4243 22435, 4238 22440, 4241 22441, 4241 22443, 4238 22447, 4234 22443, 4238 22448, 4238 22450, 4241 22451, 4241 22456, 4243 22458, 4247 22461, 4247 22464, 4252 22466, 4253 22469, 4255 22469, 4251 22469, 4253 22464, 4253 22468, 4257 22473, 4259 22477, 4258 22482, 4261 22483, 4262 22484, 4259 22489, 6259 22493, 6262 22494, 6262 22497, 6264 22500, 6264 22504, 6269 22499, 6273 22499, 6278 22495, 6278 22493, 6283 22491, 6288 22494, 6291 22494, 6296 22494, 6296 22493, 6294 22489, 6294 22493, 6290 22493, 6290 22498, 6290 22500, 6288 22501, 6290 22505, 6294 22504, 5294 22507, 5294 22507, 5298 22512, 5297 22514, 5302 22514, 5307 22517, 5304 22518, 5308 22514, 5311 22517, 5315 27517, 5315 27517, 5319 27517, 5324 22517, 5328 22521, 6328 22520, 6325 22522, 6325 22527, 6322 22527, 6323 22530, 6325 22535, 6325 22535, 6326 22536, 6326 22536, 6327 22533, 6323 22535, 6325 22538, 6330 22538, 6331 22534, 6326 22531, 10326 22526, 10321 22528, 10317 22524, 10316 22529, 10313 22529, 10309 22530, 10306 22535, 10308 22531, 10308 22532, 10311 22534, 10314 27534, 10314 27538, 10314 27538, 10309 27540, 10309 27536, 11309 27535, 11309 27537, 11310 27539, 11305 27535, 11300 27536, 11296 27538, 11296 27538, 11301 27542, 11299 27546, 11304 27551, 11308 27551, 11313 27553, 11315 30553, 11319 30555, 11315 30550, 11318 30545, 11318 30544, 11321 30549, 11320 30550, 11325 30554, 11328 30558, 11328 34558, 11332 34562, 11333 34562, 11335 34562, 11334 34565, 11330 34565, 11333 34566, 11338 34566, 11338 34571, 11342 34574, 11344 34573, 11347 34572, 11346 34573, 11347 34575, 11351 34578, 15351 34578, 15356 34573, 15361 34570, 15364 34575, 15365 34580, 15369 34581, 15370 34581, 15373 34585, 15376 34580, 15381 34578, 15385 34583, 15386 34588, 15389 34587, 17389 34582, 17394 34582, 17393 34582, 17398 34577, 17399 34582, 17399 34584, 17399 39584, 17404 39588, 17399 39591, 17404 39591, 17408 39586, 17405 39591, 17409 39593, 17411 39596, 17408 39596, 17411 39599, 17411 39603, 17414 39607, 17418 39612, 17419 39612, 17419 39612, 17423 39611, 17424 39613, 17426 39612, 17429 39608, 17427 39609, 17428 39613, 17425 39615, 17424 39614, 17427 39617, 17430 39622, 17430 39623, 17431 39620, 17434 39620, 13434 39619, 13434 39621, 13434 39621, 13434 44621, 13436 44625, 13436 44627, 13441 44631, 13444 44636, 13444 44639, 13442 44635, 13444 44635, 13447 44639, 13449 44643, 13447 44641, 13447 44642, 13452 44643, 13456 44648, 13459 44648, 13461 44646, 15461 44643, 15459 44648, 15463 44648, 15464 44646, 15461 44649, 15461 44651, 15465 44654, 15460 44655, 15461 44657, 15463 44661, 15465 44665, 15465 44665, 15465 44667, 15469 44670, 15474 44672, 15476 44668, 15472 44672, 15473 44674, 15475 44678, 15477 44679, -3804 12302, -3802 12305, -3803 13305, -3802 13300, -3806 13296, -3807 13299, -3804 13304, -3802 13301, -3799 13305, -3799 13306, -3794 18306, -3799 18310, -3797 18315, -3800 18315, -3797 18316, -3799 18318, -3794 18323, -3793 18326, -3789 18325, -3784 18324, -3784 18325, -3782 18325, -3780 18325, -3779 18328, -3780 18329, -3781 18324, -3786 18328, -1786 18328, -1786 18333, -1782 18337, -1782 18338, -1779 18333, -1775 18338, -6775 18341, -6772 18343, -6774 18345, -6779 18345, -6777 18345, -6777 18347, -6777 18343, -6775 18347, -6780 18342, -6777 18345, -6776 18345, -6774 18340, -6774 18337, -6774 18337, -6778 18342, -6782 18342, -6785 18339, -6784 18340, -6779 22340, -6779 22339, -6776 22335, -6775 22330, -6775 22335, -6775 22339, -6770 22339, -6772 22344, -6767 22345, -6765 22341, -6765 22339, -6765 22339, -6765 22337, -6765 22340, -6760 22335, -6757 22335, -6762 22336, -6763 22338, -6765 22343, -6760 22338, -6758 22338, -6758 22338, -6756 22341, -6752 22345, -6752 22346, -6748 22343, -4748 22347, -4745 22347, -4750 22347, -4749 22348, -4747 22349, -4743 22352, -4738 22357, -4734 22362, -4736 22367, -4738 22362, 21338 41531, 21336 41531, 21332 41530, 21332 41530, 21335 41533, 21330 41533, 21331 41534, 21328 41536, 21330 41536, 21326 41541, 21330 41536, 21332 41539, 21336 41536, 21338 40536, 21336 40540, 21341 40538, 21343 40538, 21346 40538, 21348 40536, 21352 40536, 21355 40539, 21359 40543, 21361 40546, 21362 40550, 21357 40550, 21362 40551, 21361 40554, 21358 40555, 21358 40554, 21359 40554, 21363 40558, 21360 45558, 21364 45560, 21368 45557, 21372 45561, 21376 45560, 21379 45557, 22379 45553, 22384 45553, 22384 45556, 22388 45561, 22389 45561, 22390 45557, 22394 45561, 24394 45565, 22394 45562, 22399 45565, 22401 45562, 22400 45565, 22402 45568, 22402 45573, 22406 45577, 22408 45581, 22408 45585, 22406 45585, 22409 45586, 22411 45583, 22411 45579, 22411 45583, 22409 45583, 22404 45586, 22404 45586, 22406 45591, 22408 45591, 22408 45593, 22413 45593, 22415 45594, 22419 45595, 22419 45596, 22424 45591, 22427 45587, 22430 50587, 22430 50589, 22430 50589, 22432 50592, 22437 50594, 22437 50589, 22437 50594, 22441 50599, 22442 50594, 22447 50591, 22444 50588, 22444 50590, 22445 54590, 22445 54594, 22448 54599, 22450 54601, 22450 59601, 22446 59597, 22451 59600, 22451 59603, 22454 59604, 22459 59604, 22460 59609, 22459 59606, 22464 59607, 22465 59608, 22463 59609, 22460 59606, 22459 59605, 22459 59605, 22457 59609, 25457 59610, 25459 59615, 25464 59617, 25466 59618, 25469 59621, 25474 59616, 25478 59617, 25480 59614, 25484 59619, 25484 59620, 25488 59616, 25485 59618, 25489 59623, 25494 59627, 25499 59629, 148 2256, 152 2253, 152 2253, 154 2258, 159 2253, 160 2257, 159 2256, 163 2259, 161 3259, 163 3262, 163 3259, 165 3259, 170 3263, 170 3263, 174 3267, 169 3271, 174 3275, 174 3276, 174 3278, 177 3282, 181 3286, 183 3287, 186 3284, 187 3286, 189 3286, 193 3288, 194 3290, 193 6290, 195 6293, 200 6289, 197 6294, 196 6293, 197 6293, 201 6297, 202 6292, 200 6294, 204 6295, 209 6300, 214 6305, 217 6305, 218 6305, 213 6308, 214 6308, 218 6313, 218 6308, 216 6312, 215 6312, 213 6309, 214 6313, 219 6318, 222 6321, 226 6326, 224 6331, 222 6327, 41575 39716, 41574 39713, 41578 40713, 41582 40718, 41578 40721, 36578 40721, 36579 40723, 36584 40720, 36587 40725, 36592 43725, 36587 43725, 36584 43728, 36587 43733, 36592 43735, 36592 43734, 15291 11311, 15287 11316, 15288 11319, 15291 11319, 15296 11319, 15297 11320, 15298 13320, 38744 37650, 38745 37654, 38747 37659, 38746 37662, 38741 37663, 38739 37666, 38744 37666, 38747 37661, 38750 37666, 38750 37666, 38754 37671, 38755 37671, 38750 37673, 38750 37672, 38754 37677, 38756 37678, 38758 37680, 38760 37678, 38762 37683, 38762 37679, 38760 37679, 38765 37679, 38769 37678, 38774 40678, 38769 40683, 38774 40687, 38776 44687, 38780 44690, 38782 44694, 38782 44694, 38781 44699, 38784 44704, 38782 44699, 38777 44700, 38777 44700, 38777 44700, 38781 44703, 38785 44700, 38786 44700, 38788 44696, 38788 44696, 38788 44700, 38793 44702, 38795 44703, 38797 44707, 38802 44712, 38805 44712, 38809 44713, 38804 44710, 38808 44712, 38811 44713, 36811 44713, 36816 44708, 36815 44709, 36816 44709, 36818 44713, 36813 44716, 36814 48716, 36813 48721, 36817 48725, 36818 51725, 36820 51721, 36824 51724, 40824 51719, 40829 51716, 40832 51720, 40831 51723, 40834 51727, 40837 51728, 40842 51725, 40843 51725, 40838 51729, 40843 51734, 40848 51738, 40850 51742, 40851 51744, 40853 51747, 40856 51749, 40857 51750, 40859 51754, 40859 51750, 40863 51752, 40868 51755, 40864 51754, 40868 51754, 40871 51756, 40867 51756, 40865 51759, 40860 51761, 40857 51757, 40857 51762, 40854 51762, 40855 51764, 40859 51765, 40857 51761, 40854 51764, 40855 51765, 40857 51766, 40860 51761, 40861 51760, 40865 51761, 40865 51763, 40862 51768, 40861 51768, 40856 51772, 40852 51769, 40854 51771, 40854 51771, 40850 51776, 40854 51780, 40856 51782, 40854 51782, 43854 51782, 43856 52782, 43858 52785, 43861 52785, 43861 52780, 37514 26540, 37519 26535, 37522 26539, 37522 26544, 37524 26548, 37529 26548, 37534 26553, 37539 26548, 37542 26553, 37547 26548, 37551 26551, 37551 26554, 37550 26555, 37551 26557, 37548 26557, 37548 26557, 37551 26560, 37551 26563, 37554 26563, 37558 26568, 37562 26563, 37563 26565, 37567 26569, 41567 26569, 41571 26572, 41573 26577, 41573 26577, 41578 29577, 41573 29577, 41575 29580, 41575 29582, 46575 29582, 46571 29586, 45571 29587, 45574 29587, 45570 29587, 45575 29585, 45577 29582, 45573 29585, 45574 29588, 45574 29589, 45578 29589, 45580 29592, 45583 29595, 45584 29597, 45584 29602, 45586 29601, 45591 29604, 45587 29609, 45591 33609, 45595 36609, 45596 36611, 45601 36613, 45602 36608, 45606 36608, 45606 36612, 45606 36611, 45610 36614, 50610 36617, 50613 36613, 50616 36613, 50621 36609, 50626 36609, 50627 36610, 50627 36609, 50631 36610, 50626 36612, 50627 36614, 50628 36614, 50631 36612, 50629 36614, 50630 36618, 50634 36622, 46634 34622, 46634 35622, 46638 35626, 46638 35621, 46639 35624, 46641 35623, 46645 35624, 46647 35629, 46645 35634, 46650 35639, 46650 35644, 46651 35647, 46653 35651, 46657 35654, 46654 35659, 46659 35660, 46660 35661, 46664 35664, 46661 35667, 46664 35668, 46667 35667, 46669 35671, 46669 35667, 46672 35670, 46674 35675, 46676 35675, 47676 35672, 47678 35676, 47679 35677, 47679 35682, 47679 35681, 47679 35681, 47679 35686, 47674 35687, 47673 35687, 49673 35689, 49676 35693, 49679 35696, 49677 35696, 54677 35701, 54680 35703, 54676 35703, 54672 35705, 54672 35704, 54677 35707, 54678 34707, 54678 34707, 54681 34710, 54685 34712, 54690 34710, 54690 34711, 54687 34706, 54689 34706, 54694 34711, 54689 36711, 54689 36710, 54684 36711, 54687 38711, 54682 38714, 54682 38718, 54679 38718, 54681 38723, 54684 38724, 54689 38720, 54690 38721, 54694 38726, 54699 38730, 54701 38731, 54702 38728, 54704 38724, 52704 38723, 52704 38723, 52704 38725, 52704 38729, 52706 38730, 52708 38732, 52709 38733, 52713 38732, 52713 35732, 52715 35737, 52714 35741, 52714 35743, 52715 35746, 52715 35749, 52710 35749, 52712 39749, 52715 39753, 52718 39752, 52723 39753, 52722 39757, 52718 39760, 52718 40760, 47718 40761, 47719 40765, 47724 40765, 47724 40765, 47724 40770, 47728 40773, 47730 40776, 47735 40781, 47733 40777, 50733 40781, 51733 40783, 51735 40786, 51736 40790, 51739 40788, 51743 41788, 51741 41787, 51741 41789, 51741 41789, 51738 41793, 51733 41793, 52733 41794, 52737 41795, 52740 41794, 52744 41793, 52748 41789, 52749 41789, 52747 41789, 52752 41786, 52755 41790, 52755 41791, 52760 41796, 52756 42796, 52751 42797, 52754 42798, 52758 42795, 52759 42794, 52764 42797, 52768 42801, 52768 42801, 52771 42806, 52776 42810, 52776 42809, 52773 42811, 52776 42811, 52772 42812, 52773 42815, 52769 42815, 52768 42816, 52769 42821, 52773 42821, 52773 42821, 52777 42819, 52781 42815, 52781 42816, 52782 42819, 52778 42822, 52776 42822, 52779 42826, 52782 42827, 52783 42831, 52778 42833, 52782 42836, 54782 42839, 54782 42844, 2137 11205, 2142 11207, 2139 11208, 2142 11213, 2144 11217, 2149 11215, 2147 11217, 2147 11217, 2152 11222, 2152 11225, 2155 11229, 2159 13229, 2164 13232, 2169 13235, 2173 13236, 2169 13233, 2170 13237, 2173 13241, 2175 13243, 2170 13238, 2170 13239, 2175 13239, 2177 13238, 2179 13239, 2179 13238, 2181 13233, 2181 13230, 2182 13230, 2179 13230, 2179 13235, 2182 13235, 2183 10235, 2178 10237, 2179 10236, 2182 10239, 2187 10241, 2184 10244, 6184 10244, 6186 10248, 6184 10246, 6185 10247, 6187 10250, 6192 10248, 6196 10248, 6196 10251, 6194 10251, 6194 10256, 6197 10260, 6196 10264, 6197 9264, 6197 9264, 6197 9268, 6201 9273, 6206 9276, 6201 9272, 6203 9272, 6205 9269, 6210 9272, 6206 9274, 6206 9279, 6203 9283, 6203 9285, 6203 9290, 6208 9285, 6208 9281, 6204 9285, 6202 9289, 6204 9292, 6200 9294, 7200 9297, 7202 9301, 7203 9301, 7207 9302, 7211 9302, 7211 9303, 8211 9306, 8216 10306, 8220 10310, 8224 10312, 8228 10317, 8233 10317, 8237 10322, 8239 10322, 8239 10327, 8235 10330, 8235 10331, 8239 10329, 8240 10332, 8240 10334, 8236 10334, 11236 10336, 11238 10337, 11243 10341, 14243 10342, 14242 10342, 14239 10343, 14240 10341, 14239 10343, 14244 10343, 14248 10343, 14252 10343, 14252 10343, 14253 10341, 14256 10341, 14258 10338, 14258 10336, 14254 10340, 14257 10344, 14261 10346, 14264 10351, 11150 3163, 11155 3167, 11156 3166, 11156 3169, 11160 3171, 11163 3176, 11164 3179, 11164 3180, 11168 3183, 11168 3185, 11173 3189, 11178 3184, 11180 3183, 11178 3185, 11181 3187, 11176 3186, 52778 42822, 52780 42826, 52779 42826, 52784 42821, 52785 42826, 52786 42827, 52791 42830, 52791 42827, 56791 42832, 56788 42833, 56788 42836, 56791 42840, 56791 42839, 56787 42842, 56788 42847, 51788 42848, 51790 42850, 51792 42851, 51796 42846, 51798 42846, 51803 42850, 53803 42853, 53808 42853, 53811 42856, 53814 42854, 53819 42850, 53819 42852, 53820 42857, 53824 42860, 53825 42858, 53828 42862, 53827 42864, 53828 42864, 53828 42868, 53832 42872, 53837 42877, 53841 42877, 53843 42876, 53843 42880, 53843 42883, 53843 42888, 53838 42892, 53838 42893, 53838 44893, 53835 44893, 53837 44897, 53840 44901, 53844 44901, 53846 44904, 53846 44908, 53847 44909, 53852 44907, 53855 44908, 53860 44910, 53858 44911, 53863 44913, 53858 44917, 53860 44920, 53865 44920, 53870 44922, 53869 43922, 53871 43925, 53871 43923, 53869 43923, 53864 43922, 53862 43927, 53866 43932, 53871 43934, 53876 43937, 53876 43936, 53876 43936, 53877 43934, 53879 43932, 53880 43928, 53885 43931, 55885 43933, 55885 43929, 55881 43933, 55883 43933, 55886 43932, 55883 43932, 55884 43933, 55885 45933, 55885 45937, 55885 45940, 55886 45945, 55886 45945, 55888 45950, 55884 45952, 55885 45956, 55890 45960, 55892 45961, 55896 45957, 55894 45958, 55899 45954, 55895 45958, 55898 45960, 55894 45959, 55899 45963, 55901 45965, 55901 45965, 55896 45966, 55900 45961, 55895 49961, 55898 47961, 55896 47960, 55900 47964, 55903 47968, 55903 47971, 55903 47974, 55898 47977, 55900 47973, 55896 47978, 55897 47979, 55893 47980, 55898 47983, 55901 47988, 55904 47987, 55899 47991, 55901 47993, 55906 47996, 55906 47997, 55907 48001, 55904 48005, 55904 48007, 55909 48004, 55912 48002, 55917 48003, 55913 47998, 55908 48002, 55912 48007, 55916 48004, 55920 48004, 55916 48004, 55921 48004, 55923 48007, 55923 48011, 55926 48011, 55921 48014, 55924 48009, 55929 48013, 55930 48012, 55930 48012, 55932 48016, 55927 48016, 55927 48020, 54927 48018, 54924 48022, 54924 44022, 54928 44017, 54931 44016, 54934 44020, 55934 44021, 55937 44021, 55938 44024, 55939 44026, 55938 44024, 55941 44019, 55946 44022, 55947 44026, 55949 44027, 55952 44028, 55955 44024, 55958 44027, 53869 43923, 53873 43925, 52873 43925, 53873 43927, 53878 43927, 53883 43927, 53882 43931, 53884 43935, 53888 43940, 53886 43941, 53881 43938, 53881 43941, 53879 43943, 53880 43942, 53881 43946, 53882 43951, 53883 43952, 53886 45952, 53886 45953, 53884 45957, 53885 45958, 53880 45960, 53882 45957, 53887 45962, 53887 45962, 53888 45961, 53888 48961, 53888 48966, 53893 48966, 53894 48968, 53899 48969, 49899 48966, 49904 48969, 49908 48971, 49904 48971, 49906 48975, 49903 48971, 49906 48974, 54906 48975, 54906 48975, 54906 48979, 54911 48983, 54909 48979, 54912 48979, 54908 48975, 54911 48977, 54913 48979, 54917 48982, 54922 48982, 54925 48985, 54920 48988, 54923 48988, 56923 48988, 56928 48990, 56926 48985, 56931 48984, 56934 48983, 56934 48981, 56938 48983, 56939 48985, 56939 48986, 61939 48988, 61939 48984, 61936 51984, 61937 51985, 61937 51988, 61937 51988, 61933 51990, 5331 23399, 5333 23399, 5335 23394, 5339 23396, 5342 23399, 5347 27399, 5347 27401, 5352 27402, 5357 27403, 5358 27406, 6358 27409, 6362 27411, 6363 27410, 6366 27406, 6368 26406, 6373 26406, 6373 26406, 6374 26409, 6372 26409, 6377 26410, 6382 26415, 6387 26417, 6389 26418, 6390 26423, 6392 26423, 6393 26428, 6395 30428, 6392 30433, 6392 30436, 6392 30434, 6396 30438, 6396 30441, 6396 30445, 6398 30446, 6400 30443, 6401 30440, 6406 30439, 6407 30439, 6402 30439, 6407 30444, 6406 30447, 6407 30451, 6411 30451, 6413 30451, 6414 30452, 6419 30450, 6423 30454, 6420 30452, 6419 30448, 6420 30453, 6422 30455, 6427 30460, 6428 30460, 6427 30462, 6428 30462, 6428 34462, 6429 34463, 6434 39463, 6436 39466, 6436 39471, 6441 39474, 6445 39471, 6446 39472, 6451 39477, 6453 39480, 6454 39485, 6454 39483, 6454 39480, 8454 39480, 8458 39482, 8462 39484, 10462 39486, 10457 39486, 10458 39488, 10462 39488, 10465 39488, 10470 39490, 10475 39486, 10477 39488, 10477 39490, 10478 39492, 10479 39496, 10477 39498, 10482 39503, 10478 39505, 10481 39510, 10482 39514, 10477 39512, 10482 39517, 10483 39520, 10483 39520, 10487 39525, 10489 39526, 10492 39527, 10492 39524, 10495 39524, 10498 44524, 10493 44523, 10493 44528, 10494 44524, 10499 44529, 10501 44529, 10504 44531, 10502 44535, 10504 44539, 10508 44539, 10513 44536, 13513 44540, 13515 44537, 13512 44539, 13509 44544, 13513 44547, 13517 44552, 13519 44553, 13524 44554, 13527 42554, 13522 42555, 13524 42557, 13527 42556, 13531 42561, 13531 42562, 13526 42563, 13527 42563, 13527 42566, 13522 42568, 13525 42571, 15525 42573, 15525 42576, 15526 42581, 15531 42581, 15532 42586, 15534 42588, 15534 42592, 15533 42591, 15533 42596, 15532 42591, 15532 42587, 15535 42587, 15538 47587, 15534 47587, 15537 47591, 15536 47594, 15538 47598, 11538 47594, 11535 47594, 11531 47594, 11535 47596, 11535 47596, 11535 47597, 11539 47602, 11540 47607, 11540 47607, 11540 47609, 11543 47613, 11546 47617, 14546 47618, 14541 47614, 14539 47614, 14539 47618, 14537 50618, 14539 50623, 14541 50623, 14542 50627, 14540 50627, 14539 50623, 25601 26544, 25601 26545, 25601 26548, 25596 26546, 25601 26547, 25598 26548, 25599 26547, 25600 26547, 25595 26548, 25590 26546, 25595 26549, 25597 26548, 25598 26548, 25601 26545, 25596 26548, 25594 26553, 25595 26552, 25599 26553, 25598 26554, 25596 26555, 25592 26554, 25596 26558, 25599 26554, 25600 26556, 25595 26559, 25600 22559, 25601 22561, 25606 22563, 25607 22562, 25608 22566, 25607 22563, 25607 22568, 30607 22573, 30612 22575, 30612 22579, 30611 22579, 30611 22580, 30611 22585, 30607 22585, 30612 22587, 30612 22588, 30615 22583, 30615 22585, 30618 22581, 30621 22581, 30623 22584, 30623 22589, 30628 22594, 30630 22597, 30631 22602, 30628 22607, 30630 22610, 30631 22611, 30631 22608, 30629 22610, 30634 22612, 30635 22612, 30638 22616, 30643 17616, 30644 17618, 30649 17618, 30653 17619, 30656 17614, 30657 17611, 30660 17615, 30655 17614, 30656 17610, 30656 17611, 30661 17610, 30662 17615, 30660 17620, 30661 17620, 30666 17623, 30667 17625, 30667 17624, 30669 17625, 30673 17628, 30675 17628, 30675 17628, 30680 17631, 30677 17636, 30677 17639, 30680 17644, 30683 17647, 30688 17643, 30693 17645, 30698 19645, 30701 19644, 30702 19644, 30698 19649, 30700 19647, 30701 19649, 30704 19650, 30705 19653, 30701 19655, 30706 19652, 30708 19656, 30711 19657, 30711 19659, 30711 19659, 30714 19661, 30710 19662, 30707 19664, 30702 19666, 30703 19667, 30708 19668, 30713 19667, 30709 19671, 30706 19674, 30710 19676, 30711 19677, 30713 19677, 30713 19678, 30715 19682, 30720 19686, 30725 20686, 30723 20690, 30727 20695, 30728 20697, 30731 20699, 30730 20694, 30732 20696, 30735 20698, 30738 20696, 30738 20695, 30742 20698, 30743 20699, 30743 20701, 30748 20704, 30749 20706, 30752 20705, 30753 20702, 30755 24702, 30751 24705, 30750 24707, 30748 24708, 30749 29708, 30749 29709, 30751 29711, 30754 29716, 30759 29716, 30762 34716, 30762 34720, 30765 34720, 30761 34717, 30761 34721, 30765 34721, 30760 34721, 30759 34725, 30762 34730, 30760 34730, 30765 34731, 30765 34731, 30766 34731, 30761 34733, 30761 34736, 30764 34738, 30759 34739, 30763 34740, 30761 34740, 30764 34742, 30759 34737, 30762 34739, 30764 34741, 30762 34740, 30767 34737, 32767 34741, 32770 34741, 32767 34744, 32767 34746, 32770 34751, 32774 34755, 32774 34756, 32779 34753, 32784 34755, 32785 33755, 32785 33750, 36785 33753, 36785 33758, 36788 33760, 36789 33759, 36789 33762, 36793 33758, 36798 33758, 36803 33760, 36803 33762, 36803 33766, 36804 33769, 36804 33769, 36808 33774, 33808 33776, 33808 33781, 33811 33781, 33816 33784, 33816 33789, 33820 33786, 33823 33788, 33828 33785, 33824 33785, 33826 33787, 33824 33788, 33828 33791, 33825 33796, 33829 33799, 33830 33802, 33831 33803, 33835 33805, 33835 33805, 33838 33809, 33841 33813, 33844 33809, 33849 33814, 33847 32814, 33849 32812, 33851 32816, 33853 32819, 33851 32822, 33851 32826, 33849 32826, 33849 32830, 33852 32835, 33856 32840, 33859 32837, 33858 32832, 33861 32833, 33862 32836, 33859 32838, 33859 32834, 33857 32834, 33859 32834, 33857 32838, 33861 32833, 33861 32837, 33864 32840, 33866 32841, 33866 32843, 33868 32841, 33871 32839, 33874 32844, 33876 37844, 33881 37849, 33883 37854, 33883 37859, 33888 37860, 33893 37864, 33898 37864, 33895 37867, 33896 38867, 33898 38863, 28898 38868, 28901 39868, 33901 39873, 33898 39875, 33900 39879, 33904 39877, 33904 39879, 33909 39883, 33914 39888, 33910 39891, 33910 39892, 33907 39894, 33911 39899, 33913 39900, 33910 39904, 33914 39905, 33917 39906, 33917 39906, 33917 39906, 33912 39911, 33912 39908, 33916 39907, 33914 39910, 33918 39913, 33922 39913, 33924 39916, 33925 39920, 33930 39920, 33933 39922, 33934 39923, 33937 39919, 33938 39916, 33936 39913, 35936 39918, 35933 39919, 35937 39921, 35941 39924, 35941 39919, 35942 39915, 35946 39920, 35946 39915, 35946 39912, 35947 39908, 35947 39912, 35947 39916, 35952 39919, 35957 39921, 38957 39920, 38962 39925, 38964 39924, 38964 39924, 38969 39926, 38969 39928, 38972 39932, 38977 39932, 38975 39932, 38979 39935, 38982 39938, 38986 39940, 38984 39943, 38985 39946, 38987 39947, 38989 39949, 38994 41949, 38990 41954, 38991 41958, 38994 41962, 38994 41966, 38994 41969, 38995 41974, 38999 41974, 38999 41974, 38996 41978, 38996 41983, 38999 41983, 39001 41986, 38996 41984, 39000 41989, 39000 41988, 5336 23410, 5332 23410, 5327 23407, 9327 23408, 12327 23412, 12327 23412, 12324 23410, 13324 23415, 13327 23420, 13328 23416, 13324 23418, 13329 23423, 13330 23426, 13331 23429, 13335 23426, 13339 23428, 23493 35553, 23492 35548, 23496 35550, 23501 35552, 23497 35553, 21497 35557, 21492 35560, 21494 35562, 21494 35560, 21496 35563, 21496 35568, 21496 35570, 21501 35570, 21504 35566, 21504 35571, 17504 35572, 17508 35577, 17509 35578, 17513 35582, 17514 35587, 17515 35592, 18515 35595, 18516 35596, 18517 35598, 18515 35600, 16515 35605, 16515 37605, 16515 37606, 16513 37608, 16515 37613, 16516 37615, 16520 37620, 16524 34620, 16526 34617, 16530 34619, 16530 34624, 16535 34628, 16537 34631, 16540 34632, 16541 34634, 16541 34635, 16544 34632, 16544 34637, 16546 34642, 16549 38642, 16549 38644, 16545 38649, 16545 38644, 16542 38644, 16545 38644, 16544 38645, 16548 38650, 16543 38653, 16543 38649, 18543 38652, 18546 38652, 18546 38657, 18546 38660, 18551 38655, 18549 38655, 18552 38660, 18549 38662, 23549 38667, 23546 38668, 23550 38672, 23550 38674, 28550 38676, 28551 38673, 28551 38677, 28547 38673, 28551 38674, 28556 38674, 28559 38678, 28562 38673, 28564 38678, 28564 38673, 28563 38673, 28566 38675, 28571 38675, 38781 44703, 38782 44699, 38780 44702, 38785 44704, 38787 44704, 38783 44705, 38784 44700, 38788 44695, 38791 44696, 38796 44696, 38801 44692, 38801 44697, 38805 44701, 38810 44701, 38808 44701, 38808 44704, 38805 44706, 38805 44710, 38804 44711, 38809 48711, 38810 48711, 38808 48711, 38812 48716, 38812 48713, 38812 48715, 38812 48715, 38808 48711, 38804 48714, 38805 48710, 38807 48715, 38812 48715, 38807 48713, 38811 48714, 38811 48714, 38816 48711, 38817 48707, 38818 48707, 38818 48708, 38822 48708, 38824 48713, 38822 48714, 38820 48718, 38824 48720, 38824 48723, 38829 48726, 38830 48731, 38834 48729, 38832 48734, 38833 48730, 38834 48728, 38831 48732, 8433 35536, 8433 35541, 4433 35536, 4436 35541, 4440 35541, 4441 35537, 4445 35539, 4444 35534, 4447 35531, 4451 35531, 4455 35534, 4460 35534, 4461 39534, 4462 39535, 4463 39535, 4466 39535, 4470 39535, 4472 39538, 4467 39538, 4467 39536, 4471 39536, 4473 39541, 4468 39542, 4472 39543, 4475 39544, 4478 39544, 4482 39547, 4487 39552, 4485 39550, 4486 39551, 4486 39553, 4486 39555, 4488 39557, 4488 39558, 4489 39555, 4485 39557, 4488 39558, 4492 39560, 4495 39561, 4500 39565, 4496 39566, -4747 22349, -4750 22349, -4746 22352, -4742 22355, -4738 22360, -4739 22362, -4737 22365, -4732 22363, -4728 25363, -4728 25364, -4723 25364, -4725 25364, -4725 25365, -6725 25364, -6727 25369, -6728 25369, -6725 25369, -6729 25368, -6728 27368, -6725 27370, -6721 27371, -3721 27367, -3717 27372, -3718 27375, -3716 27370, -3715 27373, -3714 27373, -3712 27376, -3709 27374, -3710 27375, -3710 27374, -3708 27379, -3706 27381, -3705 27386, -3704 27389, -3704 27393, -3703 32393, -3702 32396, -3702 32396, -3697 32395, -3697 32399, -3692 32403, -3692 32404, -3693 32408, -3693 32412, -3691 32414, -3691 32414, -3695 32414, -3690 32417, -3689 32422, -3684 32424, -3681 32429, -3679 32424, -3676 32428, -3671 32428, -3674 32431, -3671 32430, -3669 32430, -3674 33430, -3676 33432, -3674 33432, -3677 33432, -3677 33437, -3675 33438, -3674 33442, -3679 33444, 1321 33448, 1323 33445, 1327 33448, 1331 33443, 1328 33448, 1328 33443, 1329 33443, 1329 33444, 1334 33448, 1335 33453, 1340 33457, 1340 33454, 1345 33454, 1349 33458, 1348 33461, 1348 33459, 1344 33463, 1343 33466, 1348 33466, 1349 33467, 1345 33467, 1346 33466, 1350 33461, 1349 33464, 1354 33468, 1358 33472, 1363 33473, 1365 33472, 1367 33473, 1370 33476, 1371 33479, -2629 33482, -2631 33487, -2627 33490, -2630 34490, -2626 36490, -2623 36492, -2619 36492, -2622 36492, -2620 36496, -2622 36495, -2627 36495, -2625 36500, -2621 36503, -2626 36506, -2629 36510, -2624 36510, -2620 36510, -2620 36513, -2617 36518, -2622 36516, -2619 36514, -2617 36514, -2617 36512, -2615 36516, -2613 36516, -2613 36517, -2613 36515, -2613 36510, -2610 36511, -2607 36515, -2604 37515, -2604 37512, -2608 37509, -2605 37512, -2600 37516, -2597 37516, -2593 37514, -2595 37515, -2590 37519, -2595 37518, -2590 37523, -2590 37528, -2590 37530, -2592 37525, -2592 37520, -2589 36520, -2586 36521, -2587 36517, -2584 36518, -2582 36518, -2581 36520, -2577 36518, -2576 36522, -2576 35522, -2573 35523, -2575 35523, -2576 35528, -2576 35533, -2576 35536, -2576 35538, -2578 35541, -2582 35545, -2584 35546, -2585 35548, -2583 35544, -2583 35548, -2582 35547, -2578 35552, -2574 35554, -2569 35557, -2565 35559, -2563 35564, -2558 35564, -2555 35568, -2551 35568, -5551 36568, -5546 36568, -5542 36569, -5545 36569, -5543 36574, -5540 36569, -5541 36570, -5541 36572, -5541 36574, -5538 36579, -5535 36581, -5533 36585, -5530 36584, -5526 36579, -5524 38579, -5524 38580, -5524 38575, -5520 38575, -5516 38580, -5512 42580, -5508 42585, -5510 42587, -5510 42586, -5505 42586, -5508 42589, -2508 42593, -2509 42596, -2506 42598, -2504 42601, -2501 42602, -2501 42607, -2496 42612, -2499 42615, -2498 42620, -2500 42617, -2500 42620, -4500 42620, -4500 42624, -4500 42626, -4504 42623, -4507 42625, -4509 42628, -4513 42629, -4508 42629, -4505 42632, -4500 42628, -4499 42633, -4503 45633, -4501 45634, -4497 45635, -4494 45634, -4495 45632, -4493 45634, -4492 46634, -4489 46638, -4485 46633, -4481 46635, 21338 40536, 21343 40537, 21348 40538, 21348 40540, 21347 40540, 21348 40540, 21347 40540, 21346 40542, 21349 40547, 21350 40547, 21353 40544, 21353 40546, 21350 40549, 21353 40550, 21354 40550, 21355 40550, 21360 40550, 21361 40549, 21361 40554, 21359 40559, 21364 40564, 21366 40559, 21365 40559, 21366 40564, 25366 40568, 25367 40570, 25370 40570, 25373 45570, 25374 45571, 25374 45566, 25378 45568, 25383 42568, 25387 42564, 25391 42568, 25391 42572, 25395 42576, 25392 42576, 28392 42573, 28391 42574, 28387 42578, 28388 42580, 28391 42581, 31391 42582, 31387 42586, 31389 42586, 31392 42582, 31393 42583, 31394 42580, 29394 42584, 29398 42586, 29400 43586, 29404 43588, 29408 43589, 29409 43591, 29413 43596, 29415 43598, 29416 43599, 25416 43604, 25414 43599, 25417 43603, 25422 43606, 25420 43608, 25425 43603, 25428 43603, 25431 43606, 25436 42606, 25431 42608, 25434 42604, 25437 42609, 25438 47609, 25442 50609, 25443 50614, 25441 50618, 25446 50621, 25449 50625, 25446 50628, 25446 50630, 25447 50631, 25452 50636, 25452 50632, 25453 50634, 25453 50636, 25456 50637, 25460 50641, 25464 50645, 25465 50644, 25465 51644, 25469 51648, 25471 51653, 25475 51654, 25476 51657, 25477 51658, 26477 51662, 26477 51666, 26476 51669, 26478 51669, 26483 51665, 26485 55665, 26487 55668, 30487 55671, 30487 55674, 30491 55675, 30491 55672, 30493 55674, 30494 55674, 30495 55679, 30499 55679, 30503 55675, 30505 55680, 30502 55681, 30500 55676, 30496 55679, 30501 55680, 30502 55680, 30507 55685, 30503 55688, 30498 55689, 30502 55689, 30504 55691, 30508 55696, 30509 55697, 30508 55696, 30513 55697, 30518 55698, 30516 55703, 30516 55705, 30514 55705, 34514 55709, 34518 55712, 34522 55708, 34520 56708, 34521 56708, 34522 56710, 34519 56710, 34517 56705, 34521 59705, 34524 59710, 34524 59712, 34524 59717, 34528 59719, 34530 59721, 34535 59716, 34540 59719, 34540 59721, 34543 59721, 34548 59724, 34550 59725, 34554 63725, 34549 63730, 34551 63732, 34556 63730, 34558 63730, 34559 63725, 34558 63729, 34563 63734, 34560 63734, 37560 63729, 37563 63733, 37567 63728, 37571 63724, 37575 63722, 37580 63726, 37579 63722, 37581 63724, 37581 63726, 37582 63723, 37582 63724, 37581 63728, 37576 63729, 37576 63731, 37578 63729, 37583 63733, 37585 63736, 37588 63736, 37592 63741, 37594 63738, 37599 63735, 37602 63734, 37598 63735, 37598 63737, 37602 63737, 37603 63739, 37598 63739, 37593 63736, 37598 63737, 37603 63742, 37604 63737, 37601 63742, 37596 63744, 37600 63748, 37605 63749, 37607 63751, 37609 63756, 37609 63760, 37605 63761, 37605 63765, 37606 63765, 37610 63762, 37611 63766, 37606 63768, 37606 63768, 41606 63769, 41602 63765, 41601 63765, 41602 63770, 41598 63770, 41601 63770, 41603 63774, 41606 63772, 41610 63772, 41613 63776, 41616 63771, 41611 63767, 41614 63769, 41617 63764, 38617 63768, 38617 63772, 38620 63772, 35620 63773, 35620 63778, 35619 63779, 35620 63780, 35615 63779, 35617 63784, 35614 63786, 35615 63783, 35616 63779, 35620 63778, 35621 63780, 35626 63782, 35626 63784, 35631 63789, 35631 63784, 35628 63785, 35626 63786, 35631 63788, 35636 63791, 35640 63786, 35636 63787, 35636 63782, 35635 63781, 35640 63786, 35643 63790, 35646 63795, 35650 63797, 35649 63797, 35651 63801, 35655 63805, 35656 63808, 35656 63808, 35658 63808, 35657 63810, 35660 63814, 35660 63809, 35664 63809, 35659 67809, 35660 67812, 35662 67815, 35666 67812, 35662 67807, 35660 67807, 35663 67807, 35665 67812, 35668 67814, 35672 67818, 35671 67817, 35671 67820, 37671 67824, 37666 67824, 2277 13367, 2280 16367, 2276 16367, 2277 16366, 2281 16366, 2284 16366, 2289 16370, 2286 16370, 4286 16370, 4288 16375, 4292 16379, 4296 18379, 4297 18381, 9297 18385, 9298 18385, 9301 18386, 9305 18383, 9307 19383, 9310 19379, 8310 19384, 8314 19384, 38748 37655, 38751 37656, 38756 37657, 38759 37660, 38755 37665, 38755 37665, 38760 37667, 38765 37668, 38765 42668, 38770 42670, 38767 42672, 38772 42668, 38769 42663, 38770 42663, 38775 42658, 38773 42663, 38777 42665, 41777 42667, 41780 42669, 41783 42673, 41784 42671, 41781 42673, 41786 42676, 41783 42676, 41785 42676, 41782 42676, 41785 42679, 41786 42679, 41790 42680, 41794 42681, 41794 42679, 41795 42684, 41795 42680, 41798 42685, 41803 42689, 41806 42688, 41808 42689, 41806 42694, 41804 42696, 41807 42700, 41802 42701, 41804 42702, 41806 42704, 41811 42708, 41815 42709, 36815 42712, 36815 42708, 36812 42707, 36813 42709, 40813 42710, 40817 46710, 40818 46712, 40822 46712, 40820 46716, 40824 46721, 40827 46724, 40831 46728, 40829 46731, 40833 46731, 40835 46735, 40831 46737, 40832 46737, 36832 46742, 36832 46745, 36836 46748, 36833 46753, 36828 46752, 36824 46752, 36826 46755, 36821 46759, 36825 46762, 36825 46766, 36826 46770, 36824 46773, 36828 46776, 36833 46778, 36830 42778, 36835 42780, 36835 42781, 36840 42786)')));
-BEGIN;
-DELETE FROM t1 WHERE p = 3;
-UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
-UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
-ROLLBACK;
-connection con1;
-# disable purge
-CREATE TABLE t0 (a INT) ENGINE=InnoDB;
-BEGIN;
-SELECT * FROM t0;
-a
-connection default;
-DELETE FROM t1 WHERE p = 3;
-UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
-UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
-ALTER TABLE t1 DROP INDEX spatial_idx, DROP INDEX prefix_idx;
-connection con1;
-# enable purge
-COMMIT;
-connection default;
-DELETE FROM t1 WHERE p = 2;
-# wait for purge to process the update_undo records.
-CREATE TABLE t2 (
-p INT PRIMARY KEY,
-g1 POINT NOT NULL,
-g2 POINT NOT NULL,
-g3 LINESTRING NOT NULL,
-g4 LINESTRING NOT NULL,
-g5 GEOMETRY NOT NULL,
-g6 GEOMETRY NOT NULL,
-SPATIAL KEY (g1),
-SPATIAL KEY (g2),
-SPATIAL KEY (g3),
-SPATIAL KEY (g4),
-SPATIAL KEY (g5),
-SPATIAL KEY (g6)
-) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
-DROP TABLE t2;
-DROP TABLE t1;
-DROP TABLE t0;
-CREATE TABLE t1 (
-p INT NOT NULL AUTO_INCREMENT,
-g LINESTRING NOT NULL,
-PRIMARY KEY(p)
-) ENGINE=InnoDB ROW_FORMAT=COMPACT;
-ALTER TABLE t1 ADD INDEX prefix_idx (g(767));
-INSERT INTO t1(g) VALUES(ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)'));
-INSERT INTO t1(g) VALUES(ST_linefromtext(concat('linestring','(18 106,19 106,24 111,27 108,32 104,37 107,42 107,44 112,44 116,40 118,43 114,46 114,42 118,44 123,45 123,49 123,53 119,50 123,50 124,54 126,58 125,59 126,64 127,65 127,69 131,74 132,75 135,78 139,2078 141,2075 143,2077 143,2079 143,2084 143,2085 147,2090 -1853,2086 -1852,2086 -1856,2089 -1852,2093 -1850,2090 -1851,2090 -1852,2091 -1851,2092 -1850,2097 -1847,2102 -1848,2100 -1852,2100 -1852,7100 -1851,7103 -1850,7104 -1847,7109 -1842,65 127,67 131,66 131,61 132,61 133,62 137,65 1137,2065 1135,2061 1135,2064 1135,5064 1135,5066 1135,5070 1136,5070 1141,5071 1138,5074 1141,5075 1141,5074 1137,5076 1137,5071 1139,5066 1142,5065 2142,5068 2147,5073 2151,5069 2156,5071 2157,5072 2162,5074 2165,5069 2169,5072 2169,5076 2173,5074 2169,5078 2169,5076 2170,76 2175,74 2179,75 2184,80 2188,83 2190,87 2189,84 2193,87 2189,86 2190,87 2195,87 2200,87 1200,85 1202,86 1199,87 1200,87 1201,91 1206,92 1204,94 1204,98 1206,102 1208,105 1211,102 1216,105 1220,109 1224,110 1224,114 1225,117 1224,118 1229,117 1232,122 1237,123 1236,120 1235,124 1237,121 1236,122 1240,126 1244,127 1246,126 1249,125 5249,123 5251,127 5251,131 5251,135 5256,138 5257,135 5257,139 5257,138 5258,141 5260,146 5260,146 5260,143 10260,147 10265,151 10270,156 10266,157 10269,162 10273,166 12273,168 12274,163 12270,168 12275,170 12277,170 12277,-3830 12277,-3825 12277,-3824 12278,-3825 12276,-3825 12278,-3822 12277,-3825 12275,-3829 12278,-3828 12275,-3824 12280,-3827 12280,-3826 12282,-3822 12283,-3822 12286,-3820 12288,-3818 12289,-3816 12294,-3817 12297,-3819 12300,-3816 12297,-3813 12295,-3811 12299,-3811 12297,-3806 12298,-3806 12298,-3804 12301,-3801 12306,-3803 17306,-3803 17306,-3798 17306,-3803 17310,-3801 17314,-3798 17317,-3797 17317,-797 17321,-797 17323,-796 17325,-793 17326,-792 17322,-789 17327,-784 17331,-780 17335,-776 17339,-774 17339,-771 17342,-770 17345,-765 17348,-765 17349,-763 17353,-760 17350,-760 22350,-756 22346,-752 22349,-748 22352,-752 22348,-748 22347,-746 22345,-745 27345,-743 27346,257 27350,260 27349,261 27352,266 27348,266 22348,269 22347,271 22347,272 22347,273 22348,273 22352,278 22348,279 22344,282 22345,282 22342,283 22347,283 22347,288 22349,292 22347,292 22348,293 22348,298 22348,303 22351,306 22352,309 22352,308 22354,310 22356,311 22361,311 22358,311 22360,311 22360,315 22356,320 22358,325 22363,326 22366,321 22371,318 22373,318 22375,314 22375,316 22375,321 22376,321 22376,322 22372,32 104,36 109,40 114,40 113,40 117,44 119,49 123,49 126,49 129,53 133,50 137,50 139,49 137,48 138,43 138,42 139,46 142,46 138,41 139,45 141,4045 5141,4045 5146,4042 5147,4043 10147,4041 10150,4042 10152,4045 10152,4041 10156,4041 10152,4041 10152,4046 10153,4049 10156,4046 10155,4051 10157,4055 10159,4055 10160,4056 10161,4055 10166,4054 10169,4054 10172,4054 15172,4051 15176,4047 15177,4049 15174,4047 15176,4047 15176,4046 15177,4046 15180,4043 15184,4043 15187,4038 15190,4040 15194,4040 15199,4045 15196,4047 15197,4050 15200,4050 15204,4050 15208,4047 15212,4047 15215,4049 15216,4046 15218,4042 15223,4042 15228,4042 15232,4047 15235,4050 15236,4050 15239,4051 15243,4053 15243,4050 17243,4052 17243,4052 18243,4057 18247,4061 18249,4064 18249,4067 20249,4067 20250,4067 20255,4066 20259,4066 20259,4067 20255,4069 20256,4071 20258,4072 20254,4067 20257,4067 20260,4069 20265,4065 20267,4069 20266,4070 20267,4071 20264,4074 20259,4070 20264,4073 20260,4074 20263,4077 20268,4082 20271,4084 20273,4084 20277,4081 18277,4085 18279,4086 18276,4087 18273,4087 18275,4092 18277,4093 18279,4093 18280,4095 18280,4091 18283,4092 18281,4094 18283,4090 18287,4094 18287,138 5257,138 5255,138 5258,-1862 5254,-1860 5256,-1856 5258,-1851 5255,-1850 5260,-1847 5260,-1847 5263,-1847 5258,-1850 5257,-1850 5259,-1851 5257,-1855 5258,-1853 5261,-1849 5261,-1849 5258,-1849 5259,-1845 5264,-1847 5264,-1850 5268,-1852 5266,-1853 5270,-1856 5265,-1852 5262,-1847 5263,-1842 5263,-1842 5260,-1842 5265,-1841 5265,-1844 5265,-1842 5270,-1837 5274,-1838 5279,-1843 5275,-1842 5280,-1838 5281,-1838 5285,-1833 5285,-1828 5288,-1824 5289,-1828 5291,-1831 5291,-1826 5291,-1830 5293,-1826 5296,-1822 5301,-1826 5302,-1826 5302,-1826 5302,-1825 5297,-1820 5299,-1816 5303,-1816 5299,-3811 12299,-3809 12302,-3806 12302,-3806 12302,-3803 12304,-3798 12304,-3797 12304,-3793 12306,-3788 12306,-3783 12309,-3816 12294,-3811 12299,-3809 12297,7100 -1851,7098 -1854,7102 -1854,7107 -1856,7107 -1858,7110 -1854,7110 -1851,7113 -1851,7115 -1851,7120 -1851,7123 -1847,7124 -1852,7125 -1852,7127 -1852,7131 -1852,7129 1148,7129 1145,7133 1150,7137 1148,7138 1147,7143 1149,7147 1154,8147 1155,8152 3155,8147 3157,8143 3158,8144 3160,8144 3164,11144 3167,11146 3167,11148 3163,11152 3161,11148 3159,11149 3163,11150 3161,11151 3166,11154 3171,11154 3170,8144 3160,8144 3163,8144 3166,8145 3166,8146 3171,8146 3174,8144 3174,8144 3174,8145 3176,8141 3180,3141 3182,7141 3183,7141 7183,7136 7185,7136 7185,7133 7187,7136 7187,7131 7190,7136 7194,7137 7197,7141 7196,7139 7199,12139 7200,12143 7200,12143 7199,12144 7203,12145 7200,12141 7200,12136 7195,12136 7191,12137 7191,12137 7196,12139 7197,12140 7197,12137 7201,12140 7204,12140 7209,12143 7209,12145 7210,12147 7214,12148 9214,12152 9218,12149 9218,12149 9221,12149 9220,12150 9222,12153 10222,12153 10226,12156 10227,12159 10223,12160 10220,12161 10225,12161 10227,12163 10224,12163 10223,12158 10224,12158 10227,12158 10231,12155 12231,12157 12226,7136 7185,7139 7189,7139 7189,7139 7188,7137 7191,7139 7191,7140 7189,7143 7191,7144 7189,7144 7190,7149 7193,7152 7194,7154 7198,7153 7203,7148 7207,12148 7209,12146 7209,12145 7213,12140 7217,12139 7219,12141 7219,12138 7218,12143 7218,13143 7220,13140 7224,13142 7228,13137 7231,13142 7235,13146 7239,13149 7243,13148 7247,13150 7248,13155 7249,13155 7253,13155 7253,13155 7258,13157 7260,13162 7255,13159 7255,13163 7258,13164 7258,13164 7263,13167 7264,13167 8264,13165 8265,13169 8265,13171 13265,13175 13261,13176 13259,13176 13259,13180 13262,13181 13262,13183 13262,13188 13265,13191 13267,13191 13265,13194 13267,13191 13269,13192 13264,13196 13269,13198 13272,13200 13272,13202 13270,13207 11270,13211 11270,13211 11273,13213 11274,13217 11275,13222 11276,13222 11272,13226 11274,13231 11277,13233 11282,13236 11284,13238 11284,13236 11286,13236 11288,13236 11283,13236 11284,13238 11289,13241 11292,13244 11292,13245 11289,13241 11294,13244 11298,13249 11301,320 22358,324 24358,328 24358,327 24363,326 24359,327 24361,329 24365,334 24367,-666 24367,-670 24368,49 123,46 127,46 129,49 131,49 136,47 135,45 138,3045 135,3042 138,3044 139,3044 144,3049 144,3053 142,3055 137,3058 136,3053 139,3048 142,7048 138,7048 3138,7048 3139,7048 3140,7050 3145,7053 1145,7050 1146,7053 5146,7048 5150,7047 5146,10047 5147,10043 5147,10047 5147,10050 5152,10052 5155,10054 5156,10056 5157,10056 5159,10058 5162,10062 5164,10062 5169,10066 9169,10068 9168,10063 9164,10063 9169,10061 9171,14061 9172,14061 9174,282 22342,287 22347,288 22347,288 22343,285 22339,280 22338,278 22341,279 25341,284 25343,13241 11294,13246 11296,13243 11296,13244 11291,13245 11291,13244 11291,13246 11295,13251 11300,13253 11305,13253 11306,13258 11305,13255 11306,13256 11309,13256 11311,13261 11307,13265 11303,13267 11305,13270 11301,13275 11298,13271 11300,15271 11302,15276 11306,15279 11303,15284 11305,15286 11305,15289 11307,15290 11302,15292 11305,15296 11309,15297 11313,15298 11316,15300 11317,15304 11320,15306 11324,15306 11320,15307 11320,15312 11320,15313 11319,15317 11317,15315 11321,15317 11323,15317 11328,15319 11333,15322 11336,15322 11337,15322 11337,15324 11341,15324 11345,15325 14345,15328 13345,17328 13346,17333 13349,17337 13354,17338 13358,17342 13358,17346 13353,17348 13353,17345 13353,17348 13354,17347 13354,17347 13354,17347 13355,22347 13358,22349 13355,22351 13355,22356 13354,22358 13354,22361 13355,22362 13355,22358 13355,22359 13359,22364 13364,22369 13369,22372 13373,22376 13371,22377 13371,22377 13369,22381 13374,22386 13379,22387 13376,22387 13380,22392 13378,22390 13374,22392 13378,22391 13378,22391 13375,22392 13378,22390 13380,22393 13382,22398 13387,22398 10387,22402 10391,22399 10392,22400 10392,22400 10394,22404 10391,22403 15391,22405 15392,22407 15392,22412 15387,22412 15390,22412 15394,22408 15396,26408 15398,26407 20398,26411 20402,26415 20406,26417 20411,26420 20407,26422 20407,31422 16407,31421 16405,31421 16410,31423 16410,31426 16414,31426 16410,31430 16415,31430 16418,31435 16419,31437 16420,31438 16422,31438 16425,31438 16425,31441 16427,31439 16431,31441 16436,36441 16436,36443 18436,36442 18437,36440 18440,36440 18436,36440 18440,36442 18445,36443 18446,36447 18451,37447 23451,37452 23456,37456 23455,37458 23459,37456 23461,37458 23463,37460 23466,37464 23469,37460 23474,37462 23476,37461 26476,37466 26479,37470 26483,37471 26488,37474 26489,37474 26485,37474 26483,37474 26488,37470 26492,37474 26497,37474 26499,37478 26495,37483 26499,37483 26501,37488 26496,37491 26499,37495 26495,37500 26496,37500 26497,37500 26501,37497 26499,37497 26499,37495 26504,37498 26504,37494 26509,37497 26514,37495 26515,37498 26514,37503 26514,37508 26512,37510 26516,37511 26519,37509 26523,37506 26528,37507 26532,37512 26536,37513 26538,37510 26542,37512 26544,37517 26543,37522 26546,37527 26551,37525 26555,37529 26558,37524 26563,37524 26562,37527 26562,37522 26562,37522 26559,37526 26561,37522 26559,37523 26561,37523 26556,37524 26558,40524 26560,40524 26563,40521 26567,40525 26566,40527 26568,40532 26572,40534 26569,40533 26565,40531 26565,40535 26569,40535 26570,40539 26572,40544 26575,40543 26575,40544 26579,40548 26584,40549 26581,40553 26585,40556 26590,40552 22590,40557 22594,40556 22595,40561 22592,40561 22593,40565 22593,40568 22593,40573 22588,40570 22590,40570 22591,40570 22588,40573 22590,40573 22593,40568 22593,40567 22597,40567 22599,40571 22599,40574 22600,40574 22604,42574 22607,42577 22607,42577 22612,42579 22616,38579 22619,38580 22617,38580 22614,38575 22619,38579 22619,38579 18619,38582 18614,38582 18617,38586 18622,38590 18625,38590 18622,38594 18621,38596 18616,38597 18614,38597 18618,38600 21618,38601 21618,38605 21620,38607 25620,38611 25620,38608 25617,38608 25621,38608 25625,38611 25623,38615 25623,38615 25620,38616 25622,38619 25624,38620 25625,38620 26625,38623 26627,38623 26627,311 22358,311 22359,-1689 22360,2311 27360,2312 27360,2312 27360,2317 27362,2317 27362,2319 27359,2319 27364,2318 27359,2321 27364,2326 27367,2325 27371,2326 27373,2326 27373,2325 27377,2329 27377,2327 27377,2330 27379,2333 27379,2331 27379,2331 27381,2336 27381,6336 27382,6336 27383,40527 26568,40531 26572,40533 26574,40538 26576,40533 26580,40538 26585,40539 26588,40536 26583,40540 26587,40539 26588,40535 26593,40540 26594,40544 26597,40548 26602,40548 26601,40549 26602,40547 26602,40548 26603,40553 26606,40548 26606,40548 26603,40551 26608,40556 26612,40559 26616,40554 26619,40556 26619,40556 26623,42556 26623,42556 26624,42560 26624,42562 26626,42563 26630,42564 26630,42564 26634,42559 26635,42562 26635,42565 26637,42562 26638,42564 26642,42564 26641,42568 26641,42572 26641,42572 29641,42574 29642,39574 29641,39574 34641,39576 34643,39581 34638,39578 34638,39574 34642,39574 34645,39572 35645,34572 35648,34577 35651,39577 35655,43577 35659,43580 35655,43575 35658,43578 35658,43581 35662,43577 39662,43572 39658,43572 39661,43572 39664,43572 39666,43576 39670,43577 39667,43580 39671,43576 39673,43573 39673,43574 39677,43569 39679,43567 39679,43568 39683,43563 39686,43566 39690,43566 39692,43568 39694,43568 39695,41568 39691,41570 39692,41571 39692,41571 39693,41571 39698,41571 39698,41574 39698,41569 39698,41570 39699,41570 39704,41572 39709,41573 39712,41578 39713,41579 39717,41584 39719,41585 39720,-1850 5268,-1845 5268,-1847 5266,-1842 5268,-1840 5263,-1845 5264,-1843 5264,-1839 8264,-1839 8267,-1839 8272,-1838 8276,-1834 8273,-1834 8273,-1833 8274,-1837 8279,-1836 8283,-1834 8286,-1836 8282,-1834 8279,-1835 8279,-1834 8280,-1836 8283,-1841 8288,-1846 8289,-1843 8286,-1838 8286,-1841 8285,-1838 8285,-1834 8288,-1829 8291,-1825 8286,-1825 8289,-1825 8287,-1824 8291,-1822 8294,-1821 8298,-1818 8300,-1818 8296,-1814 8296,-1811 8295,-1808 8292,1192 8296,1192 8297,1195 11297,1192 11301,1195 11305,1197 11300,1193 11300,1193 11296,1193 11293,1194 11294,1199 11292,1204 11292,1205 11294,1210 11292,1208 11288,1204 11290,1205 11289,1207 8289,1202 8284,1204 8282,1204 8281,1206 8281,1208 8281,1212 8283,1212 13283,1213 13287,1213 13290,1216 13293,1214 13289,1217 13286,1212 13291,1208 13288,1208 13292,1209 13297,1208 13296,1204 13298,1205 13303,1209 13308,1204 13308,1209 13304,1210 13304,1214 13309,1214 13314,1215 13314,1219 13314,1219 13319,1224 13320,1229 13321,1232 13325,1233 13329,1231 13329,1234 13334,-2766 13336,-2769 13337,-2765 13340,-2762 13345,-2760 13342,2240 13342,2238 13342,2242 13342,2246 13345,2246 13346,2244 13348,2239 13348,2240 13351,2240 13352,2245 13357,2248 13357,2243 13362,2247 13362,2248 13362,2252 13363,2256 13363,2256 13363,2260 13367,2255 13372,2251 13369,2251 13369,2252 13372,2249 13376,2254 13378,2255 13382,2259 13379,2262 13379,2267 13381,2262 13381,2262 13383,2265 13383,2269 13385,2270 13386,2271 13389,2267 13391,2271 13386,2275 13391,2273 13392,2275 13387,2277 13390,2274 13390,2275 13394,2280 13395,2280 11395,2281 14395,2279 14400,2277 14403,2273 14406,2274 16406,2274 16410,2279 16410,2284 16411,2280 16409,2280 16409,2282 16409,2282 16411,2282 16412,2280 16413,3280 16418,3284 16418,3285 16423,3289 16423,3292 16427,3294 16429,3296 16431,3297 16436,3298 16435,3303 16435,3305 16434,3305 16436,3305 16436,3309 16437,3309 16438,3308 16439,3308 16439,3306 16444,3302 16441,-1698 16437,-1703 16438,-1699 16438,-1697 16438,-1698 16439,-1695 16436,-1690 16441,-1687 16446,-1683 16450,-1682 16451,-1684 16453,-1682 16457,-1682 16457,-1686 16460,-1681 16459,-1680 16456,-1677 16460,-1681 16461,-1679 16464,-1674 16465,-1673 16469,-1669 16471,-1669 16476,-1665 16474,-1665 16478,-1664 16478,-1664 16479,-1661 16474,-1656 16471,-1655 11471,-1660 11473,-1663 11475,-1666 11480,3334 15480,3338 15476,3342 15471,3345 15471,3345 15470,3350 15469,3347 15474,3351 15476,3352 15473,3353 15476,3350 15477,3350 15479,3351 15482,3352 15484,3351 15487,3353 15487,3358 15487,3353 15486,1217 13286,1222 13291,1222 13291,1225 13286,1229 13286,1231 13281,1235 13280,1236 13281,1241 13282,1245 13285,1247 13285,1247 13287,1250 13287,1247 13290,1247 13295,1247 13298,1252 13301,1249 13304,1252 13304,3252 13304,3247 13304,3249 13308,3254 13308,3257 13308,3261 17308,3261 17309,3261 17306,3259 17305,3262 17310,3263 17308,3262 17311,3259 17314,3259 17314,3257 17309,3254 17309,3253 17309,3255 17310,3253 17312,3255 17312,3255 17312,3256 17307,3257 17307,3256 17311,3256 17313,3255 17317,3251 17317,3248 17321,3253 17325,3256 17326,3258 17324,3258 17327,3263 17322,7263 17325,7265 17328,7263 17330,7265 17333,7270 17333,7273 17333,7278 17336,4278 21336,4278 21340,4279 21340,4281 21340,4286 24340,4290 24343,9290 24347,9294 24349,9296 24347,9298 25347,9301 25348,9301 25348,9304 25353,9303 25357,9303 25352,11303 25355,11304 25358,11307 25358,11312 25358,11312 25361,11310 25365,11313 25365,11314 25369,11319 25371,11321 25371,11325 25366,11329 25365,11330 25366,11329 25370,11330 25365,11334 25367,11338 25366,11343 25363,11348 25359,11345 25356,11348 25357,11349 25358,11349 25358,11352 25360,11356 30360,11360 30365,11360 30365,11362 30365,11367 30367,11368 30369,15368 30370,15373 30371,15376 30373,14376 30378,14377 30383,14381 30378,14386 30380,14388 30382,14391 30385,14393 31385,16393 31389,16396 31394,16396 31397,16392 31400,16395 31405,16398 31409,16398 31413,16397 31415,16396 31417,16401 31418,16401 31422,16402 31419,16407 31420,16411 31419,16406 31423,18406 31427,18411 31432,18415 28432,18417 28437,18418 28441,18414 28438,18417 28435,18416 28439,18420 28442,18423 28447,18427 28444,21427 28445,21428 28450,22428 28455,22432 28457,22436 28458,22441 28458,22445 28463,22448 28468,22451 28465,22456 28468,22453 28468,22458 28471,22463 28473,22460 28475,22459 28472,22463 28476,22464 28472,22468 28468,22468 28471,25468 28466,25471 28468,25473 28464,25473 28464,25475 29464,25476 29466,25479 29461,25476 29462,25476 29464,25478 29464,25483 29461,25484 29460,25486 29458,25486 29462,25490 29460,25495 26460,25498 26463,25495 26468,25495 26472,25495 26472,25499 26474,25504 26476,25504 26478,25509 26476,25513 26479,25514 26481,25519 26477,25519 26480,25518 26481,25519 26484,25524 26483,25527 26484,25522 26484,25526 26487,25528 26492,25533 26496,25535 26498,25535 26498,25539 26503,25542 26504,25543 26505,25547 26510,25552 26510,25551 26508,25550 26512,25553 26510,25557 26510,25554 26511,25552 26508,25556 26505,25556 26506,25560 26506,25560 26507,25560 26506,25565 26501,25567 26504,25569 26504,25568 26508,25571 26508,25571 26511,25576 26511,25581 26516,25581 26519,25582 26521,25585 26522,25588 26527,25588 26526,25584 26530,25587 26534,25589 26529,25593 26533,25598 26538,25599 26540,25599 26540,25599 26540,25604 26543,25603 26543,25603 26538,25606 26538,25609 26540,25611 26542,25612 26547,25612 26547,25612 26548,25617 25548,25612 25548,25613 25547,25616 25545,25616 25549,25618 25551,25620 25555,25620 25551,25622 25550,25625 25551,25622 25555,25619 25557,25617 25556,25622 28556,25625 28551,25630 28546,25634 28548,25639 28553,25643 28553,25638 25553,25634 25553,25634 25557,25639 25557,25643 25558,25644 25553,25646 25556,25647 25560,25650 25562,25650 30562,25650 30562,25650 30564,25650 30566,25652 30570,25656 30571,25661 31571,25662 31575,25663 31579,25662 31579,25665 31581,25666 31584,25671 31582,25674 31581,25674 31584,25676 31584,25673 31587,25678 31586,25679 31581,30679 31584,30675 31589,30680 31590,35680 31590,35675 31589,35677 31591,35680 31590,35681 31587,35684 31588,35685 31589,35689 31592,35689 31593,35692 31597,35696 31597,35700 34597,35699 34599,35703 34604,35703 34606,35702 34601,35705 34603,35705 34606,35708 34603,35713 34604,35717 34603,35719 34608,35715 34608,35711 34608,35713 34609,35714 34605,35714 34610,35714 34614,35718 34616,35719 34617,35722 34618,35722 34621,35725 34625,35725 34626,35725 34629,35725 34631,35725 34635,35730 34636,35727 34638,35731 34640,35735 34642,35739 34645,35741 34645,35742 34649,35738 34649,35738 34645,35741 34647,38741 34650,38741 37650,38742 37646,38746 37651,38749 37652,38753 37653,38753 37657,38757 37656,38756 37660,38761 37660,38765 37660,38760 37660,38759 37660,38760 41660,38760 41660,38762 41665,38757 41667,43757 41669,43752 41674,43752 41677,43757 41672,43758 41677,45758 41680,45758 41679,45762 41683,45765 41683,45769 41683,45770 41684,45768 46684,45773 46688,45776 46692,45774 46694,45775 46697,45778 46695,45776 46698,45774 46702,45779 46702,45784 46704,45787 46706,45791 46711,45786 46707,45790 46711,45793 46715,45796 46719,45799 46724,45797 46728,45802 46726,45797 46729,45801 46733,45802 46733,45803 46732,45804 46732,45805 46732,45808 46735,45810 46740,45810 46744,2326 27373,2322 27377,2323 27379,2325 27383,2325 27382,2322 27382,2323 27382,5323 23382,5325 23385,5329 23386,5330 23390,5335 23392,5330 23392,5330 23395,5329 23395,5333 23399,5333 23402,5338 23405,5339 23405,5334 23406,5329 23401,5332 23403,5330 23407,5333 23409,5328 20409,5324 20411,5324 20414,5329 20416,5328 20421,5325 20421,5329 20424,5330 20424,5335 21424,5331 21427,5333 21431,5334 21433,5329 21434,5330 21437,5333 21440,5338 21437,5338 21440,5334 21441,5333 21438,5329 26438,5332 26435,5335 26439,5337 26440,5338 26444,5342 26439,5342 26442,5345 26440,5349 26438,5352 26442,5349 26445,5348 30445,5350 30447,5350 30444,5354 30444,5359 30443,5363 30445,5367 30446,5367 30448,5367 30453,5371 30455,5371 30453,5373 30458,5375 30461,5380 30463,5384 30463,5383 30459,5384 30459,5383 30459,5385 30460,5390 30459,5392 30464,5394 30464,5389 30465,5393 30469,5391 30469,5391 30469,5395 30474,5396 30470,5399 30470,5401 30467,5401 30468,5404 30470,5400 30465,5401 30462,5403 30467,5404 30467,5409 30469,5412 30473,5412 30477,5407 30481,8407 30486,8408 30489,8410 30490,8410 30489,8413 30490,8414 30493,8414 30496,8419 30501,8420 30502,8415 30507,13415 30509,13411 30506,13414 30507,13412 30511,13412 30515,13417 30518,13419 30523,13418 30527,13422 30529,13418 30531,13413 35531,13409 35531,13413 35532,13417 35537,13419 35533,13423 35529,13424 35529,13423 35524,13428 35525,13433 35526,13438 35530,13443 35531,13448 35531,13452 35532,13455 35536,13457 35536,13452 35536,13455 35539,13452 35535,13457 35540,13457 35544,18457 35546,18460 35547,22460 35546,22465 35550,22466 35554,22468 35552,22473 35555,22471 35559,22470 35564,22472 35564,22470 35569,22474 35569,22474 35571,22477 35573,22482 35576,22487 35580,22488 35583,22489 35585,22493 35585,22496 35585,25496 35586,25493 35582,25494 35585,25498 35585,25496 35585,25498 35587,25503 35591,25503 35593,25499 35590,25499 35591,25495 35591,26495 35595,29495 35591,29495 35593,29498 35597,29498 35601,29500 35606,29501 30606,29502 30603,29505 30603,29510 30606,29511 30606,29514 30607,29516 30610,29518 30608,3259 17305,3263 17304,3267 17303,3271 17308,3269 17312,3269 17313,3274 17315,3277 17315,3282 17311,3285 17313,3283 17309,3278 17310,3275 17315,3275 17317,3276 17322,3280 17324,3280 17324,3276 17325,3277 17325,3276 17328,3278 17324,3273 17329,3277 17331,3280 17326,3281 17328,3276 17324,3277 17324,3277 17322,3277 17321,3277 17321,3281 17323,3282 17327,3282 17332,3287 17335,3288 17335,3288 17338,3290 17337,3294 17340,3294 17341,3299 17341,3299 12341,3299 12342,3304 12339,3301 14339,3305 14340,3307 14341,3311 14343,3313 14343,3314 16343,3310 16341,3310 16346,3312 16348,3311 16349,4311 16346,4316 16348,4321 16344,4324 16348,4322 16349,4323 16346,4323 16346,4326 16350,4322 16354,4323 16356,4325 16361,4325 16358,4322 16362,4325 20362,4325 20366,4322 20367,4326 20372,4326 20374,4331 20373,4333 20373,4338 20376,4339 20379,4341 20382,4338 20384,4339 20386,4340 20383,4340 20383,4335 20388,4336 20390,4341 20390,4346 20391,4348 20391,4349 20393,37497 26499,37494 26496,37496 26500,37496 26501,37499 26506,37497 26502,37498 26502,37500 29502,37500 29507,37505 29508,37506 33508,37508 33513,37513 33518,37517 33522,37516 33520,37521 33521,37521 33525,37516 33530,37519 33528,37520 33528,37524 33530,37527 33530,37525 33527,37528 33530,37533 33533,37534 38533,37536 38536,22358 13355,25358 13360,25361 13358,25362 13362,25362 13362,25365 13365,25363 13367,25359 13369,25357 13374,25360 13374,2247 13362,2252 13366,2254 13363,2257 13363,2261 13358,2264 13354,2264 13356,2269 13361,2272 13363,2274 13363,2275 13363,2273 13362,2274 13365,2278 13365,2280 13370,2284 13366,2284 13365,2289 13368,2290 13366,2293 13368,2298 13373,2298 13372,2295 13375,271 22347,273 22350,4273 22347,4269 22348,4270 22350,4271 22355,4272 22360,4276 22363,4281 22365,4284 24365,4279 24365,4282 24365,4285 24365,4287 24364,4289 24362,4294 24360,4295 24362,4298 24365,4301 24369,1301 24370,1301 24371,1305 24375,1305 24376,1307 24377,1312 24380,1314 24382,1318 24380,1316 24382,1316 24387,1318 24387,1318 29387,1321 29387,1316 29383,1320 29386,1321 29389,1326 29389,1327 29389,2327 29394,2327 29394,2332 29393,-666 24367,-663 24368,-661 24368,-656 24371,-653 24372,-649 24372,-647 24374,-643 24370,-638 24375,-635 24380,-638 24382,-638 24384,-638 24384,-636 24388,-637 24390,-632 24386,-630 24386,-629 24386,371 24389,376 24394,374 24392,377 24397,3377 24400,6377 24405,6378 24408,6373 24406,6370 24406,6375 24403,6370 24403,6375 24403,6379 24406,6374 24409,6378 24411,6380 24412,6378 24415,6378 24419,6383 24423,6385 24425,6387 24428,6390 24433,6386 24430,6386 24435,6387 24436,6388 24440,6387 24444,6383 29444,6383 29447,6386 29451,6382 29446,6387 29447,6390 29452,6393 29452,6397 29455,6400 29459,6400 29463,6397 29467,6393 29467,6395 29470,6397 29473,6399 29468,6394 29467,6397 29470,6396 29473,6396 29470,6393 29465,6389 29469,6390 29470,6389 29465,6389 29468,6392 29470,6388 33470,6390 33466,6391 33466,6392 33467,6394 33467,322 22372,322 22374,323 22377,327 22378,331 22382,330 22383,332 22386,333 22383,331 22383,330 22387,332 22391,332 22396,337 22397,339 22394,340 22399,340 22398,340 22396,343 22396,343 22396,341 22400,342 22404,343 22402,348 22403,345 22407,347 22411,342 22411,345 22413,340 22417,345 22417,348 22422,348 22426,351 22427,352 22432,352 22436,4352 22438,4353 22442,4354 22444,4354 22447,4357 22449,4360 22450,4364 22450,4367 22451,4369 22453,4366 22455,4369 22453,4373 22458,4377 22459,4380 22459,4380 22464,4385 22467,4385 22467,4390 22469,4385 22469,4385 22472,25571 26508,25574 26507,25578 26512,25581 26512,25581 26512,25583 26508,25583 26513,25587 26516,25589 26515,25590 26515,25591 26517,25589 26520,25587 26522,23587 26526,23585 26531,23589 26534,23592 26538,24592 26543,24588 26545,24593 26547,24598 26543,24598 26548,24602 26545,24598 26540,24600 26545,24600 26548,24600 31548,24605 31549,24608 31551,24613 31552,24615 36552,24616 36557,24619 36557,24622 36560,24622 36564,24627 35564,24627 35569,24632 35569,25632 35570,25635 35569,25636 35573,25636 35573,25638 35576,25641 35580,25641 35583,25641 35588,25642 40588,20642 40593,20645 40593,20650 40595,20651 40591,20651 40594,20648 40591,20648 40591,20652 40596,20652 40596,20656 40597,20656 40600,20656 40601,20659 40598,20662 40597,20662 40597,20663 40600,20668 40601,20665 40606,1215 13314,1214 13319,1212 13317,1209 13312,1210 13312,1211 13317,6211 13320,6214 13320,6216 13320,6211 13323,6214 13318,6214 13323,6214 13324,6216 13319,6219 13323,6218 13321,6219 13321,6218 13326,6221 13329,6225 13331,6230 13335,6231 13339,6231 13343,6235 13338,6234 13342,6234 13344,6236 13345,25524 26483,25521 26484,25524 26489,25527 26487,25529 26484,25530 26482,25534 27482,25539 27486,25537 27488,25541 27483,25544 27486,25547 27490,25550 27491,25550 27491,25554 27486,25559 27486,25563 27489,25561 27489,25563 27493,25561 27491,25563 27493,25563 27495,25564 27497,25563 27497,25563 27497,25558 27498,25563 27499,25565 27503,25567 27503,25569 27503,25567 27504,25565 27505,25565 27505,25565 27505,25566 27505,25570 27501,25570 27497,25574 27498,25570 32498,25570 32501,25573 32501,25576 32497,25576 32498,25577 32501,25579 32503,25583 32504,25588 32507,25592 32512,25596 32507,25599 32507,25594 32503,25597 32506,25597 32510,25594 32509,25594 32510,25596 32513,25592 32513,25594 32515,25594 32520,25598 32520,25602 32517,25603 32518,27603 32520,27607 32523,27608 31523,27613 31527,27615 31527,30615 31530,30617 31530,30618 31532,30619 31536,30623 31537,30623 31538,30625 31538,30626 31541,30627 31541,30624 31540,30623 31540,30624 31545,34624 31546,34619 31543,34623 31545,34624 31549,34624 31548,34626 31550,34626 31555,34626 31551,34628 31555,34633 31555,34636 31559,34634 31564,34636 31564,34639 31562,34639 31560,36639 31555,36636 27555,41636 27557,41640 27554,41644 27558,41647 27559,41648 27555,41653 27555,41658 27555,41658 27552,41658 27552,41660 27550,41656 27554,41661 27558,41664 27561,41667 27566,41662 27562,41663 27563,41663 27565,41662 27569,41661 27569,41664 27571,41664 27567,41659 30567,41660 30565,41660 30561,41665 30566,41664 30561,41664 30561,41664 30562,41664 30563,41660 30558,1312 24380,4312 25380,4315 25384,4315 25385,4319 25383,4322 25388,6322 25387,6322 25387,6326 25392,6321 25397,6324 25397,6324 25401,6319 25404,9319 25405,9314 25400,9312 25402,9310 25403,9313 25403,9313 25403,9316 25400,9319 25401,4319 25396,8319 25398,8315 25400,8315 25396,8315 25397,8311 25398,8307 25394,8309 25394,8311 25397,8315 25402,8310 25403,11310 25365,11311 25365,11316 25370,11320 25375,11325 25375,11325 25380,11325 25382,11326 25378,14326 25380,14328 25382,14331 25383,14334 25385,14336 25386,19336 25386,19336 25389,19332 25390,19332 25391,19335 25388,19338 25391,19342 25393,19340 25393,19345 25396,19345 25394,19347 25394,19349 25393,19351 25397,19350 25398,19348 25399,19349 25403,19352 25399,19350 25402,19354 25400,19353 25405,23353 25402,23354 25402,23356 25405,23358 25409,23360 25413,23363 25414,23367 25412,23365 25411,23367 25414,23363 25413,23367 25416,23367 25416,23370 25418,24370 25414,24370 25419,24373 27419,24378 27419,24380 27416,24380 27412,24380 27410,24380 27406,24376 27406,24374 27410,24370 27414,24370 27415,24371 27420,24375 27415,24378 27411,24375 27415,24378 27418,24382 27421,24383 27426,24383 27425,24385 27430,24390 27431,24394 27432,24395 27436,24399 30436,24400 30439,24404 30443,24403 30439,24406 30438,24410 30442,24406 30446,24408 30445,24403 30445,24408 30442,24412 30446,24416 30446,24416 30449,19416 30449,19416 30447,19418 30452,19420 30453,19423 30458,15423 30462,15423 30464,15425 30466,16425 30467,16424 30471,16421 30474,16426 30474,16428 30476,16428 30476,16424 30474,16424 33474,16425 33474,16427 33477,16425 33479,16426 33477,16422 33480,16425 33482,16430 33479,16430 33478,16429 33482,16424 33482,16427 33484,16430 33488,16431 33488,16434 33488,16435 33491,16432 33487,16436 37487,16434 37490,16438 37485,16443 37482,16446 37480,16447 37480,16447 37482,16451 37478,16454 37479,16458 37479,16454 37479,16454 37482,16459 37486,16460 37491,16463 37495,16464 37492,16465 37493,16466 37494,16468 37497,16468 37501,16468 37501,16473 37503,16473 37503,16473 37498,16476 37494,21476 33494,21473 33493,21476 33489,21478 33491,21478 33496,21478 33492,21480 33496,21483 33501,21484 33504,21483 33500,21484 33505,21484 33505,21488 35505,21491 35505,21494 35506,21496 35510,21492 35506,21492 35509,21489 35514,21490 35517,21487 35519,23487 35523,23485 35528,23487 35533,23483 35534,23487 35535,23488 35537,23493 35539,23495 35542,23495 35546,23495 35550,23491 35549,23488 35552,23492 35555,23495 35560,23500 35559,23496 35557,4322 16354,4317 16358,4318 16358,4320 16363,4315 16363,4315 16362,4316 20362,4320 20365,4323 20363,4326 20366,4329 20367,4332 20370,4337 20374,4338 20375,4333 20375,4338 20375,4341 20377,4342 20377,4342 20378,4343 20381,4346 20386,4346 20386,4346 20386,4346 20386,4349 20390,4352 20395,4354 20396,4355 20400,4358 20400,4360 20401,4360 20404,4363 20405,4368 20406,4372 20411,4371 20416,4367 20417,4364 20422,4367 20420,4372 20425,4373 20422,4374 20418,4377 20418,4381 20422,4382 20423,4384 20418,4389 20421,4385 20423,4390 20423,4390 20425,4392 20429,4396 20434,41574 39698,41578 39702,41576 39704,45576 39704,45575 39709,45577 39713,45581 39715,45581 39718,45583 39721,45578 39726,47578 39722,47581 39719,47586 39722,47586 39726,47589 39730,47592 39733,47597 39733,47593 39733,47596 39735,47597 39735,47595 39735,47591 39739,47593 39744,47593 39747,4074 20263,4077 20268,4079 20268,4078 20271,4078 22271,4083 22276,4087 22272,4088 22275,4086 22279,4082 22280,4084 22282,4086 22277,4082 22277,4087 22281,4090 22281,4092 22281,4092 22286,4094 22287,4097 22290,4097 22291,4095 22286,4095 22288,4095 22293,4095 22288,4092 22285,4089 22286,4090 22286,4095 22281,4100 22286,4103 22285,4104 22288,4104 22289,4107 22294,4112 22292,4117 22290,4120 22295,120 22300,121 22303,122 22300,122 22300,121 26300,125 26303,129 26303,127 26305,127 26306,132 26306,132 26307,136 26307,141 26309,140 26311,143 26313,140 26314,145 26318,149 26318,153 26321,153 29321,158 29326,158 29329,162 29324,162 34324,165 34329,168 34328,167 34332,169 34333,173 34334,173 34336,177 34338,178 34340,178 34344,182 34348,177 34348,182 34348,184 34353,184 34358,181 34360,183 34365,187 34365,192 34365,197 34367,199 34366,203 34368,205 34368,202 34363,204 34360,1204 34360,1205 34364,1205 30364,1205 30359,1206 30361,1207 30364,1210 30366,1210 30366,1214 30367,1218 30372,1219 30375,1214 30379,1214 30384,1217 30382,1222 30383,1223 30382,1225 30380,1228 30379,1231 30383,1232 30383,1235 30384,1237 30388,1242 30386,1244 30389,2244 30392,2241 30395,2245 30397,2245 30399,2244 30394,2242 30395,2246 32395,2246 32395,2249 32398,2251 32393,5251 32390,5251 32395,5255 32399,5255 32397,5257 32397,5257 32401,5261 32406,5261 32411,5266 32412,5271 32416,5273 32419,5276 32420,5281 32422,5279 32425,6279 33425,6284 33429,6284 33430,6282 33431,6282 33428,6286 33425,6288 32425,6288 32421,6286 32424,6288 32424,11288 32427,11292 32425,11292 32429,11290 32434,11286 32437,11286 32437,11283 32442,11278 32442,11279 32443,11283 32445,11284 32445,11283 32448,13283 32447,13287 32442,16287 32446,16282 32445,16283 32445,16284 32448,16285 32448,16284 32446,16286 32443,16290 32446,16291 32446,16292 32450,16291 32450,16291 32450,16291 32445,16287 32447,16288 32452,16287 32457,16291 36457,16289 36462,16293 36462,16294 36462,16297 36462,16301 36464,16306 36469,16310 36467,16310 36463,16313 36459,16312 36460,16313 36465,16313 36469,16308 36470,16309 36468,16314 36470,16319 41470,16322 41471,16325 44471,16330 44471,16330 44471,16330 44473,16330 44474,16335 44479,16332 44477,8414 30496,8415 30497,8419 30497,8414 30501,8416 30500,8418 30495,8421 35495,8423 35494,8427 35497,8429 35499,8432 35499,8436 35503,8438 35503,8443 35505,8440 35508,8443 35509,8440 35509,8440 35511,8441 35515,8445 35511,8448 35512,8443 35517,8443 35519,8442 35524,8444 35526,8441 35527,8436 35527,8433 35523,8429 35527,8430 35530,8431 35532,8429 35533,8433 35535,8437 32535,8435 32536,8439 32536,8436 32539,9436 32542,9434 32537,9429 32534,9429 32534,9433 32537,9433 32542,9429 32543,9434 32538,9436 32538,9436 34538,7436 34538,7438 34543,7439 34543,7439 34543,7439 34548,7438 34549,7438 34552,7438 34553,7438 34556,11438 34561,11434 34559,11436 34555,7436 34553,7436 34549,120 1235,124 1239,125 1236,125 1238,129 1235,128 1235,125 1236,123 1239,128 2239,132 2242,131 2242,135 2242,140 2242,145 2247,146 2252,144 2253,146 2248,144 2245,146 2244,150 2249,155 2245,159 2242,160 2243,160 2245,155 2244,156 2245,3156 2246,3159 2248,3159 2250,3164 2254,3165 2257,3166 2255,3169 2257,3171 2262,3169 2263,3174 2268,3177 2273,3174 2276,3178 2275,3173 2279,3177 2276,3180 2279,3182 2284,3185 2289,5185 2286,5185 2288,5181 2286,5185 2288,5184 2293,5187 2293,5187 2297,5190 2299,5187 2299,5185 2300,5181 6300,5182 6297,5187 6300,5189 6298,5191 6296,5193 6296,5193 6296,5195 6297,5195 6300,5197 6297,5195 6300,5190 6302,5191 6306,5192 6308,5195 6312,24395 27436,24391 27437,24393 27433,24398 27436,24398 27437,16286 32443,21286 32443,21286 32444,21282 32448,21283 32446,21283 32448,21285 32451,21281 32456,21282 32458,21282 32463,21282 32468,21284 32470,21289 32471,21287 32471,21287 32469,21287 32474,21284 32477,21288 32482,21291 32482,21291 32486,21296 32485,21299 32486,21301 32487,21303 32484,21301 32482,21305 32487,21310 32491,21312 32495,21313 32491,21315 32495,21312 32495,21314 32498,21316 32501,21311 32506,21311 32508,21312 32513,21317 32516,21319 32516,21324 32516,21327 32521,21328 32526,21332 32527,21328 36527,21331 41527,21336 41527,21334 41531,21337 41533,21335 41535,21339 41540,21340 41540,21343 41536,25343 41539,25340 41542,25337 41542,25337 41545,25335 41542,25335 41543,25335 46543,25339 46548,30339 46551,30340 46556,30343 46557,30342 46553,30337 46556,30341 46561,30337 46565,30336 46563,30338 46564,24373 27419,24373 27421,24375 27424,24377 27425,24377 27430,24374 27435,24379 27437,24384 27432,24385 27434,24382 27437,24381 27442,24381 31442,24381 33442,20381 33439,20383 34439,20382 34440,20378 34444,20381 34446,20381 34442,20384 34443,20388 34446,20392 34447,20393 34442,20393 34447,20396 29447,20395 29443,20399 29443,20400 29439,20399 29436,20404 29439,20409 29440,20410 29440,20410 29444,20408 29445,20413 29448,20413 29451,20412 29455,20413 29458,20418 29461,20413 29463,20415 29464,20416 29464,20416 29463,20416 29463,20418 29464,20414 29465,20418 29463,20413 29460,20413 26460,20418 26458,20421 26459,20421 26461,20421 26460,43578 35658,43578 35654,43578 35658,43578 35660,43583 35661,43583 35659,43583 35662,43579 35663,43583 35661,43587 35666,25625 25551,25629 25551,25630 25554,25630 25559,25632 25560,25627 25561,25623 25557,25623 25559,25624 25561,26624 25566,26627 25566,29627 25571,29626 25574,29625 25575,29622 25579,29625 25583,29630 25588,29632 25589,29635 25591,29635 25594,29637 25598,29642 25596,29643 25597,29644 25597,29649 25598,29654 25602,29656 25602,29661 25603,29661 25601,29664 26601,29666 26604,29665 26604,29668 26607,29672 26607,29669 26611,29671 26616,29674 26613,29679 26616,29680 26616,29681 26615,29682 26619,29679 26617,29684 26622,29686 26624,29689 26624,29690 26628,29691 26630,29693 26625,29694 26620,29698 26617,29703 29617,29707 29616,29706 29620,29709 29623,34709 29626,34710 29628,34710 29627,2282 16411,2283 16412,2283 16412,2287 16417,2292 16421,2297 16421,2298 16426,2303 16426,2304 16429,2309 11429,2313 11432,2308 14432,2308 14431,2311 14433,2310 14437,2308 14438,2309 14440,2311 14440,2309 14443,2312 14443,2314 14447,2314 14452,2314 14450,2309 14451,2309 14451,2309 14456,2313 14461,2313 14461,2309 19461,2309 19461,2311 19462,2315 19465,2318 19465,2321 19462,2317 19464,2321 19467,2322 19467,2322 19469,2322 19469,2320 19464,2321 19462,2322 19461,2327 19466,2327 19461,2322 19461,2322 19463,2317 19467,2318 19471,2102 -1848,2107 -1848,2111 -1846,2114 1154,2114 1156,2115 1157,2114 6157,2116 6162,2121 6165,2124 6170,2121 6175,2124 6179,2124 6183,2128 6178,2126 6179,2125 6178,2126 6181,2122 10181,2127 10186,2128 10189,2130 10188,2130 10191,2127 11191,2127 11195,2131 11196,2132 11192,2131 11197,2135 11201,2135 11203,2139 11199,2142 11203,2143 11204,2147 11208,2142 11210,2142 11211,2147 11212,2150 11217,2150 11219,2151 11219,2152 11222,2152 11222,2148 11224,2150 11220,2150 11223,2146 11218,2143 11219,2140 11221,2143 11218,2140 11219,2140 11223,2145 11225,2147 11226,2152 11226,2155 11224,2157 11229,2157 11229,2153 11233,2153 11238,2149 11239,7149 10239,7154 10241,7157 10241,7162 10243,7164 10248,7164 10251,7169 10253,7171 10253,7172 10257,7177 10260,7182 10256,7187 10260,7191 8260,7195 8256,7200 8258,7204 8258,7203 8261,7203 8262,7205 8266,7209 8270,7209 8273,7214 8273,7214 8276,7210 8276,7211 8276,7213 8279,7218 8278,7222 8283,7223 8279,7220 10279,7221 10283,7223 10284,7228 10286,7230 10290,7231 10290,7231 10293,7232 10294,7232 10297,7234 10299,7229 10295,7226 10294,7221 10293,7223 10295,7228 10299,7229 10303,7232 10307,7232 10311,7233 10316,7234 9316,7239 9318,7244 9321,7241 9326,7241 9328,7238 9331,7235 9330,7237 9335,7236 9335,7236 9337,7236 9338,7231 14338,7230 14333,7232 14338,7237 18338,4082 22280,4081 22280,6081 22283,6076 22285,6076 22289,6078 22286,6080 22287,6084 22292,6084 22293,6085 22293,6086 22291,6091 22294,6092 22293,9092 22290,9095 22294,9096 22295,9096 22297,9091 22292,9096 22295,9098 22290,9094 18290,9097 18290,9096 18294,9099 18292,9098 18297,9103 18299,9103 18302,9103 18305,9100 18301,9102 18302,9106 18305,9102 18310,9101 18306,9103 18308,9103 18312,9107 18310,9107 18315,9107 18320,9111 18322,9111 18326,9113 18329,9111 18329,9116 18329,9121 18329,9121 18332,9123 18331,9124 18332,9125 18328,9127 18325,9125 18328,9128 18329,9133 18329,9136 18333,9141 18337,9142 18342,9143 18340,9148 18344,9152 18341,9150 18346,9149 18341,9149 18341,9154 18343,9158 18345,9161 18346,9161 18347,9163 18352,9164 18352,9162 18349,9165 18352,9165 18351,9165 18352,9165 18356,9163 18352,9167 18353,9167 18349,9168 18351,9168 18347,9173 18347,9175 18347,9179 18348,9182 18349,9187 18352,9186 18357,9189 18360,9192 18360,9196 18362,13196 18367,13196 18369,13196 18371,13199 18374,13194 18374,13197 18375,13200 18377,13205 18380,13210 18384,13209 18379,13209 18374,13213 18375,13216 20375,13212 20375,13215 20375,13211 20375,13211 20372,13208 20373,13204 20373,13204 20369,13205 20369,13207 20366,13212 20367,13216 20367,13221 20372,13222 20377,13225 20381,13226 20386,13230 20383,9230 20388,9228 20384,9228 20386,9223 20389,9223 20392,4223 20397,4223 20396,4225 20399,4222 20404,4220 20408,4220 20411,4223 20416,4227 20421,4230 20418,4234 20421,4232 20422,4236 20423,4238 20423,4239 20423,4235 20427,4231 20427,4230 20426,4228 20428,4232 20427,4232 20431,4236 20433,4241 20431,4241 22431,4236 22436,4239 22437,4239 22439,4236 22443,4232 22439,4236 22444,4236 22446,4239 22447,4239 22452,4241 22454,4245 22457,4245 22460,4250 22462,4251 22465,4253 22465,4249 22465,4251 22460,4251 22464,4255 22469,4257 22473,4256 22478,4259 22479,4260 22480,4257 22485,6257 22489,6260 22490,6260 22493,6262 22496,6262 22500,6267 22495,6271 22495,6276 22491,6276 22489,6281 22487,6286 22490,6289 22490,6294 22490,6294 22489,6292 22485,6292 22489,6288 22489,6288 22494,6288 22496,6286 22497,6288 22501,6292 22500,5292 22503,5292 22503,5296 22508,5295 22510,5300 22510,5305 22513,5302 22514,5306 22510,5309 22513,5313 27513,5313 27513,5317 27513,5322 22513,5326 22517,6326 22516,6323 22518,6323 22523,6320 22523,6321 22526,6323 22531,6323 22531,6324 22532,6324 22532,6325 22529,6321 22531,6323 22534,6328 22534,6329 22530,6324 22527,10324 22522,10319 22524,10315 22520,10314 22525,10311 22525,10307 22526,10304 22531,10306 22527,10306 22528,10309 22530,10312 27530,10312 27534,10312 27534,10307 27536,10307 27532,11307 27531,11307 27533,11308 27535,11303 27531,11298 27532,11294 27534,11294 27534,11299 27538,11297 27542,11302 27547,11306 27547,11311 27549,11313 30549,11317 30551,11313 30546,11316 30541,11316 30540,11319 30545,11318 30546,11323 30550,11326 30554,11326 34554,11330 34558,11331 34558,11333 34558,11332 34561,11328 34561,11331 34562,11336 34562,11336 34567,11340 34570,11342 34569,11345 34568,11344 34569,11345 34571,11349 34574,15349 34574,15354 34569,15359 34566,15362 34571,15363 34576,15367 34577,15368 34577,15371 34581,15374 34576,15379 34574,15383 34579,15384 34584,15387 34583,17387 34578,17392 34578,17391 34578,17396 34573,17397 34578,17397 34580,17397 39580,17402 39584,17397 39587,17402 39587,17406 39582,17403 39587,17407 39589,17409 39592,17406 39592,17409 39595,17409 39599,17412 39603,17416 39608,17417 39608,17417 39608,17421 39607,17422 39609,17424 39608,17427 39604,17425 39605,17426 39609,17423 39611,17422 39610,17425 39613,17428 39618,17428 39619,17429 39616,17432 39616,13432 39615,13432 39617,13432 39617,13432 44617,13434 44621,13434 44623,13439 44627,13442 44632,13442 44635,13440 44631,13442 44631,13445 44635,13447 44639,13445 44637,13445 44638,13450 44639,13454 44644,13457 44644,13459 44642,15459 44639,15457 44644,15461 44644,15462 44642,15459 44645,15459 44647,15463 44650,15458 44651,15459 44653,15461 44657,15463 44661,15463 44661,15463 44663,15467 44666,15472 44668,15474 44664,15470 44668,15471 44670,15473 44674,15475 44675,-3806 12298,-3804 12301,-3805 13301,-3804 13296,-3808 13292,-3809 13295,-3806 13300,-3804 13297,-3801 13301,-3801 13302,-3796 18302,-3801 18306,-3799 18311,-3802 18311,-3799 18312,-3801 18314,-3796 18319,-3795 18322,-3791 18321,-3786 18320,-3786 18321,-3784 18321,-3782 18321,-3781 18324,-3782 18325,-3783 18320,-3788 18324,-1788 18324,-1788 18329,-1784 18333,-1784 18334,-1781 18329,-1777 18334,-6777 18337,-6774 18339,-6776 18341,-6781 18341,-6779 18341,-6779 18343,-6779 18339,-6777 18343,-6782 18338,-6779 18341,-6778 18341,-6776 18336,-6776 18333,-6776 18333,-6780 18338,-6784 18338,-6787 18335,-6786 18336,-6781 22336,-6781 22335,-6778 22331,-6777 22326,-6777 22331,-6777 22335,-6772 22335,-6774 22340,-6769 22341,-6767 22337,-6767 22335,-6767 22335,-6767 22333,-6767 22336,-6762 22331,-6759 22331,-6764 22332,-6765 22334,-6767 22339,-6762 22334,-6760 22334,-6760 22334,-6758 22337,-6754 22341,-6754 22342,-6750 22339,-4750 22343,-4747 22343,-4752 22343,-4751 22344,-4749 22345,-4745 22348,-4740 22353,-4736 22358,-4738 22363,-4740 22358,21336 41527,21334 41527,21330 41526,21330 41526,21333 41529,21328 41529,21329 41530,21326 41532,21328 41532,21324 41537,21328 41532,21330 41535,21334 41532,21336 40532,21334 40536,21339 40534,21341 40534,21344 40534,21346 40532,21350 40532,21353 40535,21357 40539,21359 40542,21360 40546,21355 40546,21360 40547,21359 40550,21356 40551,21356 40550,21357 40550,21361 40554,21358 45554,21362 45556,21366 45553,21370 45557,21374 45556,21377 45553,22377 45549,22382 45549,22382 45552,22386 45557,22387 45557,22388 45553,22392 45557,24392 45561,22392 45558,22397 45561,22399 45558,22398 45561,22400 45564,22400 45569,22404 45573,22406 45577,22406 45581,22404 45581,22407 45582,22409 45579,22409 45575,22409 45579,22407 45579,22402 45582,22402 45582,22404 45587,22406 45587,22406 45589,22411 45589,22413 45590,22417 45591,22417 45592,22422 45587,22425 45583,22428 50583,22428 50585,22428 50585,22430 50588,22435 50590,22435 50585,22435 50590,22439 50595,22440 50590,22445 50587,22442 50584,22442 50586,22443 54586,22443 54590,22446 54595,22448 54597,22448 59597,22444 59593,22449 59596,22449 59599,22452 59600,22457 59600,22458 59605,22457 59602,22462 59603,22463 59604,22461 59605,22458 59602,22457 59601,22457 59601,22455 59605,25455 59606,25457 59611,25462 59613,25464 59614,25467 59617,25472 59612,25476 59613,25478 59610,25482 59615,25482 59616,25486 59612,25483 59614,25487 59619,25492 59623,25497 59625,146 2252,150 2249,150 2249,152 2254,157 2249,158 2253,157 2252,161 2255,159 3255,161 3258,161 3255,163 3255,168 3259,168 3259,172 3263,167 3267,172 3271,172 3272,172 3274,175 3278,179 3282,181 3283,184 3280,185 3282,187 3282,191 3284,192 3286,191 6286,193 6289,198 6285,195 6290,194 6289,195 6289,199 6293,200 6288,198 6290,202 6291,207 6296,212 6301,215 6301,216 6301,211 6304,212 6304,216 6309,216 6304,214 6308,213 6308,211 6305,212 6309,217 6314,220 6317,224 6322,222 6327,220 6323,41573 39712,41572 39709,41576 40709,41580 40714,41576 40717,36576 40717,36577 40719,36582 40716,36585 40721,36590 43721,36585 43721,36582 43724,36585 43729,36590 43731,36590 43730,15289 11307,15285 11312,15286 11315,15289 11315,15294 11315,15295 11316,15296 13316,38742 37646,38743 37650,38745 37655,38744 37658,38739 37659,38737 37662,38742 37662,38745 37657,38748 37662,38748 37662,38752 37667,38753 37667,38748 37669,38748 37668,38752 37673,38754 37674,38756 37676,38758 37674,38760 37679,38760 37675,38758 37675,38763 37675,38767 37674,38772 40674,38767 40679,38772 40683,38774 44683,38778 44686,38780 44690,38780 44690,38779 44695,38782 44700,38780 44695,38775 44696,38775 44696,38775 44696,38779 44699,38783 44696,38784 44696,38786 44692,38786 44692,38786 44696,38791 44698,38793 44699,38795 44703,38800 44708,38803 44708,38807 44709,38802 44706,38806 44708,38809 44709,36809 44709,36814 44704,36813 44705,36814 44705,36816 44709,36811 44712,36812 48712,36811 48717,36815 48721,36816 51721,36818 51717,36822 51720,40822 51715,40827 51712,40830 51716,40829 51719,40832 51723,40835 51724,40840 51721,40841 51721,40836 51725,40841 51730,40846 51734,40848 51738,40849 51740,40851 51743,40854 51745,40855 51746,40857 51750,40857 51746,40861 51748,40866 51751,40862 51750,40866 51750,40869 51752,40865 51752,40863 51755,40858 51757,40855 51753,40855 51758,40852 51758,40853 51760,40857 51761,40855 51757,40852 51760,40853 51761,40855 51762,40858 51757,40859 51756,40863 51757,40863 51759,40860 51764,40859 51764,40854 51768,40850 51765,40852 51767,40852 51767,40848 51772,40852 51776,40854 51778,40852 51778,43852 51778,43854 52778,43856 52781,43859 52781,43859 52776,37512 26536,37517 26531,37520 26535,37520 26540,37522 26544,37527 26544,37532 26549,37537 26544,37540 26549,37545 26544,37549 26547,37549 26550,37548 26551,37549 26553,37546 26553,37546 26553,37549 26556,37549 26559,37552 26559,37556 26564,37560 26559,37561 26561,37565 26565,41565 26565,41569 26568,41571 26573,41571 26573,41576 29573,41571 29573,41573 29576,41573 29578,46573 29578,46569 29582,45569 29583,45572 29583,45568 29583,45573 29581,45575 29578,45571 29581,45572 29584,45572 29585,45576 29585,45578 29588,45581 29591,45582 29593,45582 29598,45584 29597,45589 29600,45585 29605,45589 33605,45593 36605,45594 36607,45599 36609,45600 36604,45604 36604,45604 36608,45604 36607,45608 36610,50608 36613,50611 36609,50614 36609,50619 36605,50624 36605,50625 36606,50625 36605,50629 36606,50624 36608,50625 36610,50626 36610,50629 36608,50627 36610,50628 36614,50632 36618,46632 34618,46632 35618,46636 35622,46636 35617,46637 35620,46639 35619,46643 35620,46645 35625,46643 35630,46648 35635,46648 35640,46649 35643,46651 35647,46655 35650,46652 35655,46657 35656,46658 35657,46662 35660,46659 35663,46662 35664,46665 35663,46667 35667,46667 35663,46670 35666,46672 35671,46674 35671,47674 35668,47676 35672,47677 35673,47677 35678,47677 35677,47677 35677,47677 35682,47672 35683,47671 35683,49671 35685,49674 35689,49677 35692,49675 35692,54675 35697,54678 35699,54674 35699,54670 35701,54670 35700,54675 35703,54676 34703,54676 34703,54679 34706,54683 34708,54688 34706,54688 34707,54685 34702,54687 34702,54692 34707,54687 36707,54687 36706,54682 36707,54685 38707,54680 38710,54680 38714,54677 38714,54679 38719,54682 38720,54687 38716,54688 38717,54692 38722,54697 38726,54699 38727,54700 38724,54702 38720,52702 38719,52702 38719,52702 38721,52702 38725,52704 38726,52706 38728,52707 38729,52711 38728,52711 35728,52713 35733,52712 35737,52712 35739,52713 35742,52713 35745,52708 35745,52710 39745,52713 39749,52716 39748,52721 39749,52720 39753,52716 39756,52716 40756,47716 40757,47717 40761,47722 40761,47722 40761,47722 40766,47726 40769,47728 40772,47733 40777,47731 40773,50731 40777,51731 40779,51733 40782,51734 40786,51737 40784,51741 41784,51739 41783,51739 41785,51739 41785,51736 41789,51731 41789,52731 41790,52735 41791,52738 41790,52742 41789,52746 41785,52747 41785,52745 41785,52750 41782,52753 41786,52753 41787,52758 41792,52754 42792,52749 42793,52752 42794,52756 42791,52757 42790,52762 42793,52766 42797,52766 42797,52769 42802,52774 42806,52774 42805,52771 42807,52774 42807,52770 42808,52771 42811,52767 42811,52766 42812,52767 42817,52771 42817,52771 42817,52775 42815,52779 42811,52779 42812,52780 42815,52776 42818,52774 42818,52777 42822,52780 42823,52781 42827,52776 42829,52780 42832,54780 42835,54780 42840,2135 11201,2140 11203,2137 11204,2140 11209,2142 11213,2147 11211,2145 11213,2145 11213,2150 11218,2150 11221,2153 11225,2157 13225,2162 13228,2167 13231,2171 13232,2167 13229,2168 13233,2171 13237,2173 13239,2168 13234,2168 13235,2173 13235,2175 13234,2177 13235,2177 13234,2179 13229,2179 13226,2180 13226,2177 13226,2177 13231,2180 13231,2181 10231,2176 10233,2177 10232,2180 10235,2185 10237,2182 10240,6182 10240,6184 10244,6182 10242,6183 10243,6185 10246,6190 10244,6194 10244,6194 10247,6192 10247,6192 10252,6195 10256,6194 10260,6195 9260,6195 9260,6195 9264,6199 9269,6204 9272,6199 9268,6201 9268,6203 9265,6208 9268,6204 9270,6204 9275,6201 9279,6201 9281,6201 9286,6206 9281,6206 9277,6202 9281,6200 9285,6202 9288,6198 9290,7198 9293,7200 9297,7201 9297,7205 9298,7209 9298,7209 9299,8209 9302,8214 10302,8218 10306,8222 10308,8226 10313,8231 10313,8235 10318,8237 10318,8237 10323,8233 10326,8233 10327,8237 10325,8238 10328,8238 10330,8234 10330,11234 10332,11236 10333,11241 10337,14241 10338,14240 10338,14237 10339,14238 10337,14237 10339,14242 10339,14246 10339,14250 10339,14250 10339,14251 10337,14254 10337,14256 10334,14256 10332,14252 10336,14255 10340,14259 10342,14262 10347,11148 3159,11153 3163,11154 3162,11154 3165,11158 3167,11161 3172,11162 3175,11162 3176,11166 3179,11166 3181,11171 3185,11176 3180,11178 3179,11176 3181,11179 3183,11174 3182,52776 42818,52778 42822,52777 42822,52782 42817,52783 42822,52784 42823,52789 42826,52789 42823,56789 42828,56786 42829,56786 42832,56789 42836,56789 42835,56785 42838,56786 42843,51786 42844,51788 42846,51790 42847,51794 42842,51796 42842,51801 42846,53801 42849,53806 42849,53809 42852,53812 42850,53817 42846,53817 42848,53818 42853,53822 42856,53823 42854,53826 42858,53825 42860,53826 42860,53826 42864,53830 42868,53835 42873,53839 42873,53841 42872,53841 42876,53841 42879,53841 42884,53836 42888,53836 42889,53836 44889,53833 44889,53835 44893,53838 44897,53842 44897,53844 44900,53844 44904,53845 44905,53850 44903,53853 44904,53858 44906,53856 44907,53861 44909,53856 44913,53858 44916,53863 44916,53868 44918,53867 43918,53869 43921,53869 43919,53867 43919,53862 43918,53860 43923,53864 43928,53869 43930,53874 43933,53874 43932,53874 43932,53875 43930,53877 43928,53878 43924,53883 43927,55883 43929,55883 43925,55879 43929,55881 43929,55884 43928,55881 43928,55882 43929,55883 45929,55883 45933,55883 45936,55884 45941,55884 45941,55886 45946,55882 45948,55883 45952,55888 45956,55890 45957,55894 45953,55892 45954,55897 45950,55893 45954,55896 45956,55892 45955,55897 45959,55899 45961,55899 45961,55894 45962,55898 45957,55893 49957,55896 47957,55894 47956,55898 47960,55901 47964,55901 47967,55901 47970,55896 47973,55898 47969,55894 47974,55895 47975,55891 47976,55896 47979,55899 47984,55902 47983,55897 47987,55899 47989,55904 47992,55904 47993,55905 47997,55902 48001,55902 48003,55907 48000,55910 47998,55915 47999,55911 47994,55906 47998,55910 48003,55914 48000,55918 48000,55914 48000,55919 48000,55921 48003,55921 48007,55924 48007,55919 48010,55922 48005,55927 48009,55928 48008,55928 48008,55930 48012,55925 48012,55925 48016,54925 48014,54922 48018,54922 44018,54926 44013,54929 44012,54932 44016,55932 44017,55935 44017,55936 44020,55937 44022,55936 44020,55939 44015,55944 44018,55945 44022,55947 44023,55950 44024,55953 44020,55956 44023,53867 43919,53871 43921,52871 43921,53871 43923,53876 43923,53881 43923,53880 43927,53882 43931,53886 43936,53884 43937,53879 43934,53879 43937,53877 43939,53878 43938,53879 43942,53880 43947,53881 43948,53884 45948,53884 45949,53882 45953,53883 45954,53878 45956,53880 45953,53885 45958,53885 45958,53886 45957,53886 48957,53886 48962,53891 48962,53892 48964,53897 48965,49897 48962,49902 48965,49906 48967,49902 48967,49904 48971,49901 48967,49904 48970,54904 48971,54904 48971,54904 48975,54909 48979,54907 48975,54910 48975,54906 48971,54909 48973,54911 48975,54915 48978,54920 48978,54923 48981,54918 48984,54921 48984,56921 48984,56926 48986,56924 48981,56929 48980,56932 48979,56932 48977,56936 48979,56937 48981,56937 48982,61937 48984,61937 48980,61934 51980,61935 51981,61935 51984,61935 51984,61931 51986,5329 23395,5331 23395,5333 23390,5337 23392,5340 23395,5345 27395,5345 27397,5350 27398,5355 27399,5356 27402,6356 27405,6360 27407,6361 27406,6364 27402,6366 26402,6371 26402,6371 26402,6372 26405,6370 26405,6375 26406,6380 26411,6385 26413,6387 26414,6388 26419,6390 26419,6391 26424,6393 30424,6390 30429,6390 30432,6390 30430,6394 30434,6394 30437,6394 30441,6396 30442,6398 30439,6399 30436,6404 30435,6405 30435,6400 30435,6405 30440,6404 30443,6405 30447,6409 30447,6411 30447,6412 30448,6417 30446,6421 30450,6418 30448,6417 30444,6418 30449,6420 30451,6425 30456,6426 30456,6425 30458,6426 30458,6426 34458,6427 34459,6432 39459,6434 39462,6434 39467,6439 39470,6443 39467,6444 39468,6449 39473,6451 39476,6452 39481,6452 39479,6452 39476,8452 39476,8456 39478,8460 39480,10460 39482,10455 39482,10456 39484,10460 39484,10463 39484,10468 39486,10473 39482,10475 39484,10475 39486,10476 39488,10477 39492,10475 39494,10480 39499,10476 39501,10479 39506,10480 39510,10475 39508,10480 39513,10481 39516,10481 39516,10485 39521,10487 39522,10490 39523,10490 39520,10493 39520,10496 44520,10491 44519,10491 44524,10492 44520,10497 44525,10499 44525,10502 44527,10500 44531,10502 44535,10506 44535,10511 44532,13511 44536,13513 44533,13510 44535,13507 44540,13511 44543,13515 44548,13517 44549,13522 44550,13525 42550,13520 42551,13522 42553,13525 42552,13529 42557,13529 42558,13524 42559,13525 42559,13525 42562,13520 42564,13523 42567,15523 42569,15523 42572,15524 42577,15529 42577,15530 42582,15532 42584,15532 42588,15531 42587,15531 42592,15530 42587,15530 42583,15533 42583,15536 47583,15532 47583,15535 47587,15534 47590,15536 47594,11536 47590,11533 47590,11529 47590,11533 47592,11533 47592,11533 47593,11537 47598,11538 47603,11538 47603,11538 47605,11541 47609,11544 47613,14544 47614,14539 47610,14537 47610,14537 47614,14535 50614,14537 50619,14539 50619,14540 50623,14538 50623,14537 50619,25599 26540,25599 26541,25599 26544,25594 26542,25599 26543,25596 26544,25597 26543,25598 26543,25593 26544,25588 26542,25593 26545,25595 26544,25596 26544,25599 26541,25594 26544,25592 26549,25593 26548,25597 26549,25596 26550,25594 26551,25590 26550,25594 26554,25597 26550,25598 26552,25593 26555,25598 22555,25599 22557,25604 22559,25605 22558,25606 22562,25605 22559,25605 22564,30605 22569,30610 22571,30610 22575,30609 22575,30609 22576,30609 22581,30605 22581,30610 22583,30610 22584,30613 22579,30613 22581,30616 22577,30619 22577,30621 22580,30621 22585,30626 22590,30628 22593,30629 22598,30626 22603,30628 22606,30629 22607,30629 22604,30627 22606,30632 22608,30633 22608,30636 22612,30641 17612,30642 17614,30647 17614,30651 17615,30654 17610,30655 17607,30658 17611,30653 17610,30654 17606,30654 17607,30659 17606,30660 17611,30658 17616,30659 17616,30664 17619,30665 17621,30665 17620,30667 17621,30671 17624,30673 17624,30673 17624,30678 17627,30675 17632,30675 17635,30678 17640,30681 17643,30686 17639,30691 17641,30696 19641,30699 19640,30700 19640,30696 19645,30698 19643,30699 19645,30702 19646,30703 19649,30699 19651,30704 19648,30706 19652,30709 19653,30709 19655,30709 19655,30712 19657,30708 19658,30705 19660,30700 19662,30701 19663,30706 19664,30711 19663,30707 19667,30704 19670,30708 19672,30709 19673,30711 19673,30711 19674,30713 19678,30718 19682,30723 20682,30721 20686,30725 20691,30726 20693,30729 20695,30728 20690,30730 20692,30733 20694,30736 20692,30736 20691,30740 20694,30741 20695,30741 20697,30746 20700,30747 20702,30750 20701,30751 20698,30753 24698,30749 24701,30748 24703,30746 24704,30747 29704,30747 29705,30749 29707,30752 29712,30757 29712,30760 34712,30760 34716,30763 34716,30759 34713,30759 34717,30763 34717,30758 34717,30757 34721,30760 34726,30758 34726,30763 34727,30763 34727,30764 34727,30759 34729,30759 34732,30762 34734,30757 34735,30761 34736,30759 34736,30762 34738,30757 34733,30760 34735,30762 34737,30760 34736,30765 34733,32765 34737,32768 34737,32765 34740,32765 34742,32768 34747,32772 34751,32772 34752,32777 34749,32782 34751,32783 33751,32783 33746,36783 33749,36783 33754,36786 33756,36787 33755,36787 33758,36791 33754,36796 33754,36801 33756,36801 33758,36801 33762,36802 33765,36802 33765,36806 33770,33806 33772,33806 33777,33809 33777,33814 33780,33814 33785,33818 33782,33821 33784,33826 33781,33822 33781,33824 33783,33822 33784,33826 33787,33823 33792,33827 33795,33828 33798,33829 33799,33833 33801,33833 33801,33836 33805,33839 33809,33842 33805,33847 33810,33845 32810,33847 32808,33849 32812,33851 32815,33849 32818,33849 32822,33847 32822,33847 32826,33850 32831,33854 32836,33857 32833,33856 32828,33859 32829,33860 32832,33857 32834,33857 32830,33855 32830,33857 32830,33855 32834,33859 32829,33859 32833,33862 32836,33864 32837,33864 32839,33866 32837,33869 32835,33872 32840,33874 37840,33879 37845,33881 37850,33881 37855,33886 37856,33891 37860,33896 37860,33893 37863,33894 38863,33896 38859,28896 38864,28899 39864,33899 39869,33896 39871,33898 39875,33902 39873,33902 39875,33907 39879,33912 39884,33908 39887,33908 39888,33905 39890,33909 39895,33911 39896,33908 39900,33912 39901,33915 39902,33915 39902,33915 39902,33910 39907,33910 39904,33914 39903,33912 39906,33916 39909,33920 39909,33922 39912,33923 39916,33928 39916,33931 39918,33932 39919,33935 39915,33936 39912,33934 39909,35934 39914,35931 39915,35935 39917,35939 39920,35939 39915,35940 39911,35944 39916,35944 39911,35944 39908,35945 39904,35945 39908,35945 39912,35950 39915,35955 39917,38955 39916,38960 39921,38962 39920,38962 39920,38967 39922,38967 39924,38970 39928,38975 39928,38973 39928,38977 39931,38980 39934,38984 39936,38982 39939,38983 39942,38985 39943,38987 39945,38992 41945,38988 41950,38989 41954,38992 41958,38992 41962,38992 41965,38993 41970,38997 41970,38997 41970,38994 41974,38994 41979,38997 41979,38999 41982,38994 41980,38998 41985,38998 41984,5334 23406,5330 23406,5325 23403,9325 23404,12325 23408,12325 23408,12322 23406,13322 23411,13325 23416,13326 23412,13322 23414,13327 23419,13328 23422,13329 23425,13333 23422,13337 23424,23491 35549,23490 35544,23494 35546,23499 35548,23495 35549,21495 35553,21490 35556,21492 35558,21492 35556,21494 35559,21494 35564,21494 35566,21499 35566,21502 35562,21502 35567,17502 35568,17506 35573,17507 35574,17511 35578,17512 35583,17513 35588,18513 35591,18514 35592,18515 35594,18513 35596,16513 35601,16513 37601,16513 37602,16511 37604,16513 37609,16514 37611,16518 37616,16522 34616,16524 34613,16528 34615,16528 34620,16533 34624,16535 34627,16538 34628,16539 34630,16539 34631,16542 34628,16542 34633,16544 34638,16547 38638,16547 38640,16543 38645,16543 38640,16540 38640,16543 38640,16542 38641,16546 38646,16541 38649,16541 38645,18541 38648,18544 38648,18544 38653,18544 38656,18549 38651,18547 38651,18550 38656,18547 38658,23547 38663,23544 38664,23548 38668,23548 38670,28548 38672,28549 38669,28549 38673,28545 38669,28549 38670,28554 38670,28557 38674,28560 38669,28562 38674,28562 38669,28561 38669,28564 38671,28569 38671,38779 44699,38780 44695,38778 44698,38783 44700,38785 44700,38781 44701,38782 44696,38786 44691,38789 44692,38794 44692,38799 44688,38799 44693,38803 44697,38808 44697,38806 44697,38806 44700,38803 44702,38803 44706,38802 44707,38807 48707,38808 48707,38806 48707,38810 48712,38810 48709,38810 48711,38810 48711,38806 48707,38802 48710,38803 48706,38805 48711,38810 48711,38805 48709,38809 48710,38809 48710,38814 48707,38815 48703,38816 48703,38816 48704,38820 48704,38822 48709,38820 48710,38818 48714,38822 48716,38822 48719,38827 48722,38828 48727,38832 48725,38830 48730,38831 48726,38832 48724,38829 48728,8431 35532,8431 35537,4431 35532,4434 35537,4438 35537,4439 35533,4443 35535,4442 35530,4445 35527,4449 35527,4453 35530,4458 35530,4459 39530,4460 39531,4461 39531,4464 39531,4468 39531,4470 39534,4465 39534,4465 39532,4469 39532,4471 39537,4466 39538,4470 39539,4473 39540,4476 39540,4480 39543,4485 39548,4483 39546,4484 39547,4484 39549,4484 39551,4486 39553,4486 39554,4487 39551,4483 39553,4486 39554,4490 39556,4493 39557,4498 39561,4494 39562,-4749 22345,-4752 22345,-4748 22348,-4744 22351,-4740 22356,-4741 22358,-4739 22361,-4734 22359,-4730 25359,-4730 25360,-4725 25360,-4727 25360,-4727 25361,-6727 25360,-6729 25365,-6730 25365,-6727 25365,-6731 25364,-6730 27364,-6727 27366,-6723 27367,-3723 27363,-3719 27368,-3720 27371,-3718 27366,-3717 27369,-3716 27369,-3714 27372,-3711 27370,-3712 27371,-3712 27370,-3710 27375,-3708 27377,-3707 27382,-3706 27385,-3706 27389,-3705 32389,-3704 32392,-3704 32392,-3699 32391,-3699 32395,-3694 32399,-3694 32400,-3695 32404,-3695 32408,-3693 32410,-3693 32410,-3697 32410,-3692 32413,-3691 32418,-3686 32420,-3683 32425,-3681 32420,-3678 32424,-3673 32424,-3676 32427,-3673 32426,-3671 32426,-3676 33426,-3678 33428,-3676 33428,-3679 33428,-3679 33433,-3677 33434,-3676 33438,-3681 33440,1319 33444,1321 33441,1325 33444,1329 33439,1326 33444,1326 33439,1327 33439,1327 33440,1332 33444,1333 33449,1338 33453,1338 33450,1343 33450,1347 33454,1346 33457,1346 33455,1342 33459,1341 33462,1346 33462,1347 33463,1343 33463,1344 33462,1348 33457,1347 33460,1352 33464,1356 33468,1361 33469,1363 33468,1365 33469,1368 33472,1369 33475,-2631 33478,-2633 33483,-2629 33486,-2632 34486,-2628 36486,-2625 36488,-2621 36488,-2624 36488,-2622 36492,-2624 36491,-2629 36491,-2627 36496,-2623 36499,-2628 36502,-2631 36506,-2626 36506,-2622 36506,-2622 36509,-2619 36514,-2624 36512,-2621 36510,-2619 36510,-2619 36508,-2617 36512,-2615 36512,-2615 36513,-2615 36511,-2615 36506,-2612 36507,-2609 36511,-2606 37511,-2606 37508,-2610 37505,-2607 37508,-2602 37512,-2599 37512,-2595 37510,-2597 37511,-2592 37515,-2597 37514,-2592 37519,-2592 37524,-2592 37526,-2594 37521,-2594 37516,-2591 36516,-2588 36517,-2589 36513,-2586 36514,-2584 36514,-2583 36516,-2579 36514,-2578 36518,-2578 35518,-2575 35519,-2577 35519,-2578 35524,-2578 35529,-2578 35532,-2578 35534,-2580 35537,-2584 35541,-2586 35542,-2587 35544,-2585 35540,-2585 35544,-2584 35543,-2580 35548,-2576 35550,-2571 35553,-2567 35555,-2565 35560,-2560 35560,-2557 35564,-2553 35564,-5553 36564,-5548 36564,-5544 36565,-5547 36565,-5545 36570,-5542 36565,-5543 36566,-5543 36568,-5543 36570,-5540 36575,-5537 36577,-5535 36581,-5532 36580,-5528 36575,-5526 38575,-5526 38576,-5526 38571,-5522 38571,-5518 38576,-5514 42576,-5510 42581,-5512 42583,-5512 42582,-5507 42582,-5510 42585,-2510 42589,-2511 42592,-2508 42594,-2506 42597,-2503 42598,-2503 42603,-2498 42608,-2501 42611,-2500 42616,-2502 42613,-2502 42616,-4502 42616,-4502 42620,-4502 42622,-4506 42619,-4509 42621,-4511 42624,-4515 42625,-4510 42625,-4507 42628,-4502 42624,-4501 42629,-4505 45629,-4503 45630,-4499 45631,-4496 45630,-4497 45628,-4495 45630,-4494 46630,-4491 46634,-4487 46629,-4483 46631,21336 40532,21341 40533,21346 40534,21346 40536,21345 40536,21346 40536,21345 40536,21344 40538,21347 40543,21348 40543,21351 40540,21351 40542,21348 40545,21351 40546,21352 40546,21353 40546,21358 40546,21359 40545,21359 40550,21357 40555,21362 40560,21364 40555,21363 40555,21364 40560,25364 40564,25365 40566,25368 40566,25371 45566,25372 45567,25372 45562,25376 45564,25381 42564,25385 42560,25389 42564,25389 42568,25393 42572,25390 42572,28390 42569,28389 42570,28385 42574,28386 42576,28389 42577,31389 42578,31385 42582,31387 42582,31390 42578,31391 42579,31392 42576,29392 42580,29396 42582,29398 43582,29402 43584,29406 43585,29407 43587,29411 43592,29413 43594,29414 43595,25414 43600,25412 43595,25415 43599,25420 43602,25418 43604,25423 43599,25426 43599,25429 43602,25434 42602,25429 42604,25432 42600,25435 42605,25436 47605,25440 50605,25441 50610,25439 50614,25444 50617,25447 50621,25444 50624,25444 50626,25445 50627,25450 50632,25450 50628,25451 50630,25451 50632,25454 50633,25458 50637,25462 50641,25463 50640,25463 51640,25467 51644,25469 51649,25473 51650,25474 51653,25475 51654,26475 51658,26475 51662,26474 51665,26476 51665,26481 51661,26483 55661,26485 55664,30485 55667,30485 55670,30489 55671,30489 55668,30491 55670,30492 55670,30493 55675,30497 55675,30501 55671,30503 55676,30500 55677,30498 55672,30494 55675,30499 55676,30500 55676,30505 55681,30501 55684,30496 55685,30500 55685,30502 55687,30506 55692,30507 55693,30506 55692,30511 55693,30516 55694,30514 55699,30514 55701,30512 55701,34512 55705,34516 55708,34520 55704,34518 56704,34519 56704,34520 56706,34517 56706,34515 56701,34519 59701,34522 59706,34522 59708,34522 59713,34526 59715,34528 59717,34533 59712,34538 59715,34538 59717,34541 59717,34546 59720,34548 59721,34552 63721,34547 63726,34549 63728,34554 63726,34556 63726,34557 63721,34556 63725,34561 63730,34558 63730,37558 63725,37561 63729,37565 63724,37569 63720,37573 63718,37578 63722,37577 63718,37579 63720,37579 63722,37580 63719,37580 63720,37579 63724,37574 63725,37574 63727,37576 63725,37581 63729,37583 63732,37586 63732,37590 63737,37592 63734,37597 63731,37600 63730,37596 63731,37596 63733,37600 63733,37601 63735,37596 63735,37591 63732,37596 63733,37601 63738,37602 63733,37599 63738,37594 63740,37598 63744,37603 63745,37605 63747,37607 63752,37607 63756,37603 63757,37603 63761,37604 63761,37608 63758,37609 63762,37604 63764,37604 63764,41604 63765,41600 63761,41599 63761,41600 63766,41596 63766,41599 63766,41601 63770,41604 63768,41608 63768,41611 63772,41614 63767,41609 63763,41612 63765,41615 63760,38615 63764,38615 63768,38618 63768,35618 63769,35618 63774,35617 63775,35618 63776,35613 63775,35615 63780,35612 63782,35613 63779,35614 63775,35618 63774,35619 63776,35624 63778,35624 63780,35629 63785,35629 63780,35626 63781,35624 63782,35629 63784,35634 63787,35638 63782,35634 63783,35634 63778,35633 63777,35638 63782,35641 63786,35644 63791,35648 63793,35647 63793,35649 63797,35653 63801,35654 63804,35654 63804,35656 63804,35655 63806,35658 63810,35658 63805,35662 63805,35657 67805,35658 67808,35660 67811,35664 67808,35660 67803,35658 67803,35661 67803,35663 67808,35666 67810,35670 67814,35669 67813,35669 67816,37669 67820,37664 67820,2275 13363,2278 16363,2274 16363,2275 16362,2279 16362,2282 16362,2287 16366,2284 16366,4284 16366,4286 16371,4290 16375,4294 18375,4295 18377,9295 18381,9296 18381,9299 18382,9303 18379,9305 19379,9308 19375,8308 19380,8312 19380,38746 37651,38749 37652,38754 37653,38757 37656,38753 37661,38753 37661,38758 37663,38763 37664,38763 42664,38768 42666,38765 42668,38770 42664,38767 42659,38768 42659,38773 42654,38771 42659,38775 42661,41775 42663,41778 42665,41781 42669,41782 42667,41779 42669,41784 42672,41781 42672,41783 42672,41780 42672,41783 42675,41784 42675,41788 42676,41792 42677,41792 42675,41793 42680,41793 42676,41796 42681,41801 42685,41804 42684,41806 42685,41804 42690,41802 42692,41805 42696,41800 42697,41802 42698,41804 42700,41809 42704,41813 42705,36813 42708,36813 42704,36810 42703,36811 42705,40811 42706,40815 46706,40816 46708,40820 46708,40818 46712,40822 46717,40825 46720,40829 46724,40827 46727,40831 46727,40833 46731,40829 46733,40830 46733,36830 46738,36830 46741,36834 46744,36831 46749,36826 46748,36822 46748,36824 46751,36819 46755,36823 46758,36823 46762,36824 46766,36822 46769,36826 46772,36831 46774,36828 42774,36833 42776,36833 42777,36838 42782)')));
-INSERT INTO t1(g) VALUES (ST_linefromtext(concat('linestring','(20 110, 21 110, 26 115, 29 112, 34 108, 39 111, 44 111, 46 116, 46 120, 42 122, 45 118, 48 118, 44 122, 46 127, 47 127, 51 127, 55 123, 52 127, 52 128, 56 130, 60 129, 61 130, 66 131, 67 131, 71 135, 76 136, 77 139, 80 143, 2080 145, 2077 147, 2079 147, 2081 147, 2086 147, 2087 151, 2092 -1849, 2088 -1848, 2088 -1852, 2091 -1848, 2095 -1846, 2092 -1847, 2092 -1848, 2093 -1847, 2094 -1846, 2099 -1843, 2104 -1844, 2102 -1848, 2102 -1848, 7102 -1847, 7105 -1846, 7106 -1843, 7111 -1838, 67 131, 69 135, 68 135, 63 136, 63 137, 64 141, 67 1141, 2067 1139, 2063 1139, 2066 1139, 5066 1139, 5068 1139, 5072 1140, 5072 1145, 5073 1142, 5076 1145, 5077 1145, 5076 1141, 5078 1141, 5073 1143, 5068 1146, 5067 2146, 5070 2151, 5075 2155, 5071 2160, 5073 2161, 5074 2166, 5076 2169, 5071 2173, 5074 2173, 5078 2177, 5076 2173, 5080 2173, 5078 2174, 78 2179, 76 2183, 77 2188, 82 2192, 85 2194, 89 2193, 86 2197, 89 2193, 88 2194, 89 2199, 89 2204, 89 1204, 87 1206, 88 1203, 89 1204, 89 1205, 93 1210, 94 1208, 96 1208, 100 1210, 104 1212, 107 1215, 104 1220, 107 1224, 111 1228, 112 1228, 116 1229, 119 1228, 120 1233, 119 1236, 124 1241, 125 1240, 122 1239, 126 1241, 123 1240, 124 1244, 128 1248, 129 1250, 128 1253, 127 5253, 125 5255, 129 5255, 133 5255, 137 5260, 140 5261, 137 5261, 141 5261, 140 5262, 143 5264, 148 5264, 148 5264, 145 10264, 149 10269, 153 10274, 158 10270, 159 10273, 164 10277, 168 12277, 170 12278, 165 12274, 170 12279, 172 12281, 172 12281, -3828 12281, -3823 12281, -3822 12282, -3823 12280, -3823 12282, -3820 12281, -3823 12279, -3827 12282, -3826 12279, -3822 12284, -3825 12284, -3824 12286, -3820 12287, -3820 12290, -3818 12292, -3816 12293, -3814 12298, -3815 12301, -3817 12304, -3814 12301, -3811 12299, -3809 12303, -3809 12301, -3804 12302, -3804 12302, -3802 12305, -3799 12310, -3801 17310, -3801 17310, -3796 17310, -3801 17314, -3799 17318, -3796 17321, -3795 17321, -795 17325, -795 17327, -794 17329, -791 17330, -790 17326, -787 17331, -782 17335, -778 17339, -774 17343, -772 17343, -769 17346, -768 17349, -763 17352, -763 17353, -761 17357, -758 17354, -758 22354, -754 22350, -750 22353, -746 22356, -750 22352, -746 22351, -744 22349, -743 27349, -741 27350, 259 27354, 262 27353, 263 27356, 268 27352, 268 22352, 271 22351, 273 22351, 274 22351, 275 22352, 275 22356, 280 22352, 281 22348, 284 22349, 284 22346, 285 22351, 285 22351, 290 22353, 294 22351, 294 22352, 295 22352, 300 22352, 305 22355, 308 22356, 311 22356, 310 22358, 312 22360, 313 22365, 313 22362, 313 22364, 313 22364, 317 22360, 322 22362, 327 22367, 328 22370, 323 22375, 320 22377, 320 22379, 316 22379, 318 22379, 323 22380, 323 22380, 324 22376, 34 108, 38 113, 42 118, 42 117, 42 121, 46 123, 51 127, 51 130, 51 133, 55 137, 52 141, 52 143, 51 141, 50 142, 45 142, 44 143, 48 146, 48 142, 43 143, 47 145, 4047 5145, 4047 5150, 4044 5151, 4045 10151, 4043 10154, 4044 10156, 4047 10156, 4043 10160, 4043 10156, 4043 10156, 4048 10157, 4051 10160, 4048 10159, 4053 10161, 4057 10163, 4057 10164, 4058 10165, 4057 10170, 4056 10173, 4056 10176, 4056 15176, 4053 15180, 4049 15181, 4051 15178, 4049 15180, 4049 15180, 4048 15181, 4048 15184, 4045 15188, 4045 15191, 4040 15194, 4042 15198, 4042 15203, 4047 15200, 4049 15201, 4052 15204, 4052 15208, 4052 15212, 4049 15216, 4049 15219, 4051 15220, 4048 15222, 4044 15227, 4044 15232, 4044 15236, 4049 15239, 4052 15240, 4052 15243, 4053 15247, 4055 15247, 4052 17247, 4054 17247, 4054 18247, 4059 18251, 4063 18253, 4066 18253, 4069 20253, 4069 20254, 4069 20259, 4068 20263, 4068 20263, 4069 20259, 4071 20260, 4073 20262, 4074 20258, 4069 20261, 4069 20264, 4071 20269, 4067 20271, 4071 20270, 4072 20271, 4073 20268, 4076 20263, 4072 20268, 4075 20264, 4076 20267, 4079 20272, 4084 20275, 4086 20277, 4086 20281, 4083 18281, 4087 18283, 4088 18280, 4089 18277, 4089 18279, 4094 18281, 4095 18283, 4095 18284, 4097 18284, 4093 18287, 4094 18285, 4096 18287, 4092 18291, 4096 18291, 140 5261, 140 5259, 140 5262, -1860 5258, -1858 5260, -1854 5262, -1849 5259, -1848 5264, -1845 5264, -1845 5267, -1845 5262, -1848 5261, -1848 5263, -1849 5261, -1853 5262, -1851 5265, -1847 5265, -1847 5262, -1847 5263, -1843 5268, -1845 5268, -1848 5272, -1850 5270, -1851 5274, -1854 5269, -1850 5266, -1845 5267, -1840 5267, -1840 5264, -1840 5269, -1839 5269, -1842 5269, -1840 5274, -1835 5278, -1836 5283, -1841 5279, -1840 5284, -1836 5285, -1836 5289, -1831 5289, -1826 5292, -1822 5293, -1826 5295, -1829 5295, -1824 5295, -1828 5297, -1824 5300, -1820 5305, -1824 5306, -1824 5306, -1824 5306, -1823 5301, -1818 5303, -1814 5307, -1814 5303, -3809 12303, -3807 12306, -3804 12306, -3804 12306, -3801 12308, -3796 12308, -3795 12308, -3791 12310, -3786 12310, -3781 12313, -3814 12298, -3809 12303, -3807 12301, 7102 -1847, 7100 -1850, 7104 -1850, 7109 -1852, 7109 -1854, 7112 -1850, 7112 -1847, 7115 -1847, 7117 -1847, 7122 -1847, 7125 -1843, 7126 -1848, 7127 -1848, 7129 -1848, 7133 -1848, 7131 1152, 7131 1149, 7135 1154, 7139 1152, 7140 1151, 7145 1153, 7149 1158, 8149 1159, 8154 3159, 8149 3161, 8145 3162, 8146 3164, 8146 3168, 11146 3171, 11148 3171, 11150 3167, 11154 3165, 11150 3163, 11151 3167, 11152 3165, 11153 3170, 11156 3175, 11156 3174, 8146 3164, 8146 3167, 8146 3170, 8147 3170, 8148 3175, 8148 3178, 8146 3178, 8146 3178, 8147 3180, 8143 3184, 3143 3186, 7143 3187, 7143 7187, 7138 7189, 7138 7189, 7135 7191, 7138 7191, 7133 7194, 7138 7198, 7139 7201, 7143 7200, 7141 7203, 12141 7204, 12145 7204, 12145 7203, 12146 7207, 12147 7204, 12143 7204, 12138 7199, 12138 7195, 12139 7195, 12139 7200, 12141 7201, 12142 7201, 12139 7205, 12142 7208, 12142 7213, 12145 7213, 12147 7214, 12149 7218, 12150 9218, 12154 9222, 12151 9222, 12151 9225, 12151 9224, 12152 9226, 12155 10226, 12155 10230, 12158 10231, 12161 10227, 12162 10224, 12163 10229, 12163 10231, 12165 10228, 12165 10227, 12160 10228, 12160 10231, 12160 10235, 12157 12235, 12159 12230, 7138 7189, 7141 7193, 7141 7193, 7141 7192, 7139 7195, 7141 7195, 7142 7193, 7145 7195, 7146 7193, 7146 7194, 7151 7197, 7154 7198, 7156 7202, 7155 7207, 7150 7211, 12150 7213, 12148 7213, 12147 7217, 12142 7221, 12141 7223, 12143 7223, 12140 7222, 12145 7222, 13145 7224, 13142 7228, 13144 7232, 13139 7235, 13144 7239, 13148 7243, 13151 7247, 13150 7251, 13152 7252, 13157 7253, 13157 7257, 13157 7257, 13157 7262, 13159 7264, 13164 7259, 13161 7259, 13165 7262, 13166 7262, 13166 7267, 13169 7268, 13169 8268, 13167 8269, 13171 8269, 13173 13269, 13177 13265, 13178 13263, 13178 13263, 13182 13266, 13183 13266, 13185 13266, 13190 13269, 13193 13271, 13193 13269, 13196 13271, 13193 13273, 13194 13268, 13198 13273, 13200 13276, 13202 13276, 13204 13274, 13209 11274, 13213 11274, 13213 11277, 13215 11278, 13219 11279, 13224 11280, 13224 11276, 13228 11278, 13233 11281, 13235 11286, 13238 11288, 13240 11288, 13238 11290, 13238 11292, 13238 11287, 13238 11288, 13240 11293, 13243 11296, 13246 11296, 13247 11293, 13243 11298, 13246 11302, 13251 11305, 322 22362, 326 24362, 330 24362, 329 24367, 328 24363, 329 24365, 331 24369, 336 24371, -664 24371, -668 24372, 51 127, 48 131, 48 133, 51 135, 51 140, 49 139, 47 142, 3047 139, 3044 142, 3046 143, 3046 148, 3051 148, 3055 146, 3057 141, 3060 140, 3055 143, 3050 146, 7050 142, 7050 3142, 7050 3143, 7050 3144, 7052 3149, 7055 1149, 7052 1150, 7055 5150, 7050 5154, 7049 5150, 10049 5151, 10045 5151, 10049 5151, 10052 5156, 10054 5159, 10056 5160, 10058 5161, 10058 5163, 10060 5166, 10064 5168, 10064 5173, 10068 9173, 10070 9172, 10065 9168, 10065 9173, 10063 9175, 14063 9176, 14063 9178, 284 22346, 289 22351, 290 22351, 290 22347, 287 22343, 282 22342, 280 22345, 281 25345, 286 25347, 13243 11298, 13248 11300, 13245 11300, 13246 11295, 13247 11295, 13246 11295, 13248 11299, 13253 11304, 13255 11309, 13255 11310, 13260 11309, 13257 11310, 13258 11313, 13258 11315, 13263 11311, 13267 11307, 13269 11309, 13272 11305, 13277 11302, 13273 11304, 15273 11306, 15278 11310, 15281 11307, 15286 11309, 15288 11309, 15291 11311, 15292 11306, 15294 11309, 15298 11313, 15299 11317, 15300 11320, 15302 11321, 15306 11324, 15308 11328, 15308 11324, 15309 11324, 15314 11324, 15315 11323, 15319 11321, 15317 11325, 15319 11327, 15319 11332, 15321 11337, 15324 11340, 15324 11341, 15324 11341, 15326 11345, 15326 11349, 15327 14349, 15330 13349, 17330 13350, 17335 13353, 17339 13358, 17340 13362, 17344 13362, 17348 13357, 17350 13357, 17347 13357, 17350 13358, 17349 13358, 17349 13358, 17349 13359, 22349 13362, 22351 13359, 22353 13359, 22358 13358, 22360 13358, 22363 13359, 22364 13359, 22360 13359, 22361 13363, 22366 13368, 22371 13373, 22374 13377, 22378 13375, 22379 13375, 22379 13373, 22383 13378, 22388 13383, 22389 13380, 22389 13384, 22394 13382, 22392 13378, 22394 13382, 22393 13382, 22393 13379, 22394 13382, 22392 13384, 22395 13386, 22400 13391, 22400 10391, 22404 10395, 22401 10396, 22402 10396, 22402 10398, 22406 10395, 22405 15395, 22407 15396, 22409 15396, 22414 15391, 22414 15394, 22414 15398, 22410 15400, 26410 15402, 26409 20402, 26413 20406, 26417 20410, 26419 20415, 26422 20411, 26424 20411, 31424 16411, 31423 16409, 31423 16414, 31425 16414, 31428 16418, 31428 16414, 31432 16419, 31432 16422, 31437 16423, 31439 16424, 31440 16426, 31440 16429, 31440 16429, 31443 16431, 31441 16435, 31443 16440, 36443 16440, 36445 18440, 36444 18441, 36442 18444, 36442 18440, 36442 18444, 36444 18449, 36445 18450, 36449 18455, 37449 23455, 37454 23460, 37458 23459, 37460 23463, 37458 23465, 37460 23467, 37462 23470, 37466 23473, 37462 23478, 37464 23480, 37463 26480, 37468 26483, 37472 26487, 37473 26492, 37476 26493, 37476 26489, 37476 26487, 37476 26492, 37472 26496, 37476 26501, 37476 26503, 37480 26499, 37485 26503, 37485 26505, 37490 26500, 37493 26503, 37497 26499, 37502 26500, 37502 26501, 37502 26505, 37499 26503, 37499 26503, 37497 26508, 37500 26508, 37496 26513, 37499 26518, 37497 26519, 37500 26518, 37505 26518, 37510 26516, 37512 26520, 37513 26523, 37511 26527, 37508 26532, 37509 26536, 37514 26540, 37515 26542, 37512 26546, 37514 26548, 37519 26547, 37524 26550, 37529 26555, 37527 26559, 37531 26562, 37526 26567, 37526 26566, 37529 26566, 37524 26566, 37524 26563, 37528 26565, 37524 26563, 37525 26565, 37525 26560, 37526 26562, 40526 26564, 40526 26567, 40523 26571, 40527 26570, 40529 26572, 40534 26576, 40536 26573, 40535 26569, 40533 26569, 40537 26573, 40537 26574, 40541 26576, 40546 26579, 40545 26579, 40546 26583, 40550 26588, 40551 26585, 40555 26589, 40558 26594, 40554 22594, 40559 22598, 40558 22599, 40563 22596, 40563 22597, 40567 22597, 40570 22597, 40575 22592, 40572 22594, 40572 22595, 40572 22592, 40575 22594, 40575 22597, 40570 22597, 40569 22601, 40569 22603, 40573 22603, 40576 22604, 40576 22608, 42576 22611, 42579 22611, 42579 22616, 42581 22620, 38581 22623, 38582 22621, 38582 22618, 38577 22623, 38581 22623, 38581 18623, 38584 18618, 38584 18621, 38588 18626, 38592 18629, 38592 18626, 38596 18625, 38598 18620, 38599 18618, 38599 18622, 38602 21622, 38603 21622, 38607 21624, 38609 25624, 38613 25624, 38610 25621, 38610 25625, 38610 25629, 38613 25627, 38617 25627, 38617 25624, 38618 25626, 38621 25628, 38622 25629, 38622 26629, 38625 26631, 38625 26631, 313 22362, 313 22363, -1687 22364, 2313 27364, 2314 27364, 2314 27364, 2319 27366, 2319 27366, 2321 27363, 2321 27368, 2320 27363, 2323 27368, 2328 27371, 2327 27375, 2328 27377, 2328 27377, 2327 27381, 2331 27381, 2329 27381, 2332 27383, 2335 27383, 2333 27383, 2333 27385, 2338 27385, 6338 27386, 6338 27387, 40529 26572, 40533 26576, 40535 26578, 40540 26580, 40535 26584, 40540 26589, 40541 26592, 40538 26587, 40542 26591, 40541 26592, 40537 26597, 40542 26598, 40546 26601, 40550 26606, 40550 26605, 40551 26606, 40549 26606, 40550 26607, 40555 26610, 40550 26610, 40550 26607, 40553 26612, 40558 26616, 40561 26620, 40556 26623, 40558 26623, 40558 26627, 42558 26627, 42558 26628, 42562 26628, 42564 26630, 42565 26634, 42566 26634, 42566 26638, 42561 26639, 42564 26639, 42567 26641, 42564 26642, 42566 26646, 42566 26645, 42570 26645, 42574 26645, 42574 29645, 42576 29646, 39576 29645, 39576 34645, 39578 34647, 39583 34642, 39580 34642, 39576 34646, 39576 34649, 39574 35649, 34574 35652, 34579 35655, 39579 35659, 43579 35663, 43582 35659, 43577 35662, 43580 35662, 43583 35666, 43579 39666, 43574 39662, 43574 39665, 43574 39668, 43574 39670, 43578 39674, 43579 39671, 43582 39675, 43578 39677, 43575 39677, 43576 39681, 43571 39683, 43569 39683, 43570 39687, 43565 39690, 43568 39694, 43568 39696, 43570 39698, 43570 39699, 41570 39695, 41572 39696, 41573 39696, 41573 39697, 41573 39702, 41573 39702, 41576 39702, 41571 39702, 41572 39703, 41572 39708, 41574 39713, 41575 39716, 41580 39717, 41581 39721, 41586 39723, 41587 39724, -1848 5272, -1843 5272, -1845 5270, -1840 5272, -1838 5267, -1843 5268, -1841 5268, -1837 8268, -1837 8271, -1837 8276, -1836 8280, -1832 8277, -1832 8277, -1831 8278, -1835 8283, -1834 8287, -1832 8290, -1834 8286, -1832 8283, -1833 8283, -1832 8284, -1834 8287, -1839 8292, -1844 8293, -1841 8290, -1836 8290, -1839 8289, -1836 8289, -1832 8292, -1827 8295, -1823 8290, -1823 8293, -1823 8291, -1822 8295, -1820 8298, -1819 8302, -1816 8304, -1816 8300, -1812 8300, -1809 8299, -1806 8296, 1194 8300, 1194 8301, 1197 11301, 1194 11305, 1197 11309, 1199 11304, 1195 11304, 1195 11300, 1195 11297, 1196 11298, 1201 11296, 1206 11296, 1207 11298, 1212 11296, 1210 11292, 1206 11294, 1207 11293, 1209 8293, 1204 8288, 1206 8286, 1206 8285, 1208 8285, 1210 8285, 1214 8287, 1214 13287, 1215 13291, 1215 13294, 1218 13297, 1216 13293, 1219 13290, 1214 13295, 1210 13292, 1210 13296, 1211 13301, 1210 13300, 1206 13302, 1207 13307, 1211 13312, 1206 13312, 1211 13308, 1212 13308, 1216 13313, 1216 13318, 1217 13318, 1221 13318, 1221 13323, 1226 13324, 1231 13325, 1234 13329, 1235 13333, 1233 13333, 1236 13338, -2764 13340, -2767 13341, -2763 13344, -2760 13349, -2758 13346, 2242 13346, 2240 13346, 2244 13346, 2248 13349, 2248 13350, 2246 13352, 2241 13352, 2242 13355, 2242 13356, 2247 13361, 2250 13361, 2245 13366, 2249 13366, 2250 13366, 2254 13367, 2258 13367, 2258 13367, 2262 13371, 2257 13376, 2253 13373, 2253 13373, 2254 13376, 2251 13380, 2256 13382, 2257 13386, 2261 13383, 2264 13383, 2269 13385, 2264 13385, 2264 13387, 2267 13387, 2271 13389, 2272 13390, 2273 13393, 2269 13395, 2273 13390, 2277 13395, 2275 13396, 2277 13391, 2279 13394, 2276 13394, 2277 13398, 2282 13399, 2282 11399, 2283 14399, 2281 14404, 2279 14407, 2275 14410, 2276 16410, 2276 16414, 2281 16414, 2286 16415, 2282 16413, 2282 16413, 2284 16413, 2284 16415, 2284 16416, 2282 16417, 3282 16422, 3286 16422, 3287 16427, 3291 16427, 3294 16431, 3296 16433, 3298 16435, 3299 16440, 3300 16439, 3305 16439, 3307 16438, 3307 16440, 3307 16440, 3311 16441, 3311 16442, 3310 16443, 3310 16443, 3308 16448, 3304 16445, -1696 16441, -1701 16442, -1697 16442, -1695 16442, -1696 16443, -1693 16440, -1688 16445, -1685 16450, -1681 16454, -1680 16455, -1682 16457, -1680 16461, -1680 16461, -1684 16464, -1679 16463, -1678 16460, -1675 16464, -1679 16465, -1677 16468, -1672 16469, -1671 16473, -1667 16475, -1667 16480, -1663 16478, -1663 16482, -1662 16482, -1662 16483, -1659 16478, -1654 16475, -1653 11475, -1658 11477, -1661 11479, -1664 11484, 3336 15484, 3340 15480, 3344 15475, 3347 15475, 3347 15474, 3352 15473, 3349 15478, 3353 15480, 3354 15477, 3355 15480, 3352 15481, 3352 15483, 3353 15486, 3354 15488, 3353 15491, 3355 15491, 3360 15491, 3355 15490, 1219 13290, 1224 13295, 1224 13295, 1227 13290, 1231 13290, 1233 13285, 1237 13284, 1238 13285, 1243 13286, 1247 13289, 1249 13289, 1249 13291, 1252 13291, 1249 13294, 1249 13299, 1249 13302, 1254 13305, 1251 13308, 1254 13308, 3254 13308, 3249 13308, 3251 13312, 3256 13312, 3259 13312, 3263 17312, 3263 17313, 3263 17310, 3261 17309, 3264 17314, 3265 17312, 3264 17315, 3261 17318, 3261 17318, 3259 17313, 3256 17313, 3255 17313, 3257 17314, 3255 17316, 3257 17316, 3257 17316, 3258 17311, 3259 17311, 3258 17315, 3258 17317, 3257 17321, 3253 17321, 3250 17325, 3255 17329, 3258 17330, 3260 17328, 3260 17331, 3265 17326, 7265 17329, 7267 17332, 7265 17334, 7267 17337, 7272 17337, 7275 17337, 7280 17340, 4280 21340, 4280 21344, 4281 21344, 4283 21344, 4288 24344, 4292 24347, 9292 24351, 9296 24353, 9298 24351, 9300 25351, 9303 25352, 9303 25352, 9306 25357, 9305 25361, 9305 25356, 11305 25359, 11306 25362, 11309 25362, 11314 25362, 11314 25365, 11312 25369, 11315 25369, 11316 25373, 11321 25375, 11323 25375, 11327 25370, 11331 25369, 11332 25370, 11331 25374, 11332 25369, 11336 25371, 11340 25370, 11345 25367, 11350 25363, 11347 25360, 11350 25361, 11351 25362, 11351 25362, 11354 25364, 11358 30364, 11362 30369, 11362 30369, 11364 30369, 11369 30371, 11370 30373, 15370 30374, 15375 30375, 15378 30377, 14378 30382, 14379 30387, 14383 30382, 14388 30384, 14390 30386, 14393 30389, 14395 31389, 16395 31393, 16398 31398, 16398 31401, 16394 31404, 16397 31409, 16400 31413, 16400 31417, 16399 31419, 16398 31421, 16403 31422, 16403 31426, 16404 31423, 16409 31424, 16413 31423, 16408 31427, 18408 31431, 18413 31436, 18417 28436, 18419 28441, 18420 28445, 18416 28442, 18419 28439, 18418 28443, 18422 28446, 18425 28451, 18429 28448, 21429 28449, 21430 28454, 22430 28459, 22434 28461, 22438 28462, 22443 28462, 22447 28467, 22450 28472, 22453 28469, 22458 28472, 22455 28472, 22460 28475, 22465 28477, 22462 28479, 22461 28476, 22465 28480, 22466 28476, 22470 28472, 22470 28475, 25470 28470, 25473 28472, 25475 28468, 25475 28468, 25477 29468, 25478 29470, 25481 29465, 25478 29466, 25478 29468, 25480 29468, 25485 29465, 25486 29464, 25488 29462, 25488 29466, 25492 29464, 25497 26464, 25500 26467, 25497 26472, 25497 26476, 25497 26476, 25501 26478, 25506 26480, 25506 26482, 25511 26480, 25515 26483, 25516 26485, 25521 26481, 25521 26484, 25520 26485, 25521 26488, 25526 26487, 25529 26488, 25524 26488, 25528 26491, 25530 26496, 25535 26500, 25537 26502, 25537 26502, 25541 26507, 25544 26508, 25545 26509, 25549 26514, 25554 26514, 25553 26512, 25552 26516, 25555 26514, 25559 26514, 25556 26515, 25554 26512, 25558 26509, 25558 26510, 25562 26510, 25562 26511, 25562 26510, 25567 26505, 25569 26508, 25571 26508, 25570 26512, 25573 26512, 25573 26515, 25578 26515, 25583 26520, 25583 26523, 25584 26525, 25587 26526, 25590 26531, 25590 26530, 25586 26534, 25589 26538, 25591 26533, 25595 26537, 25600 26542, 25601 26544, 25601 26544, 25601 26544, 25606 26547, 25605 26547, 25605 26542, 25608 26542, 25611 26544, 25613 26546, 25614 26551, 25614 26551, 25614 26552, 25619 25552, 25614 25552, 25615 25551, 25618 25549, 25618 25553, 25620 25555, 25622 25559, 25622 25555, 25624 25554, 25627 25555, 25624 25559, 25621 25561, 25619 25560, 25624 28560, 25627 28555, 25632 28550, 25636 28552, 25641 28557, 25645 28557, 25640 25557, 25636 25557, 25636 25561, 25641 25561, 25645 25562, 25646 25557, 25648 25560, 25649 25564, 25652 25566, 25652 30566, 25652 30566, 25652 30568, 25652 30570, 25654 30574, 25658 30575, 25663 31575, 25664 31579, 25665 31583, 25664 31583, 25667 31585, 25668 31588, 25673 31586, 25676 31585, 25676 31588, 25678 31588, 25675 31591, 25680 31590, 25681 31585, 30681 31588, 30677 31593, 30682 31594, 35682 31594, 35677 31593, 35679 31595, 35682 31594, 35683 31591, 35686 31592, 35687 31593, 35691 31596, 35691 31597, 35694 31601, 35698 31601, 35702 34601, 35701 34603, 35705 34608, 35705 34610, 35704 34605, 35707 34607, 35707 34610, 35710 34607, 35715 34608, 35719 34607, 35721 34612, 35717 34612, 35713 34612, 35715 34613, 35716 34609, 35716 34614, 35716 34618, 35720 34620, 35721 34621, 35724 34622, 35724 34625, 35727 34629, 35727 34630, 35727 34633, 35727 34635, 35727 34639, 35732 34640, 35729 34642, 35733 34644, 35737 34646, 35741 34649, 35743 34649, 35744 34653, 35740 34653, 35740 34649, 35743 34651, 38743 34654, 38743 37654, 38744 37650, 38748 37655, 38751 37656, 38755 37657, 38755 37661, 38759 37660, 38758 37664, 38763 37664, 38767 37664, 38762 37664, 38761 37664, 38762 41664, 38762 41664, 38764 41669, 38759 41671, 43759 41673, 43754 41678, 43754 41681, 43759 41676, 43760 41681, 45760 41684, 45760 41683, 45764 41687, 45767 41687, 45771 41687, 45772 41688, 45770 46688, 45775 46692, 45778 46696, 45776 46698, 45777 46701, 45780 46699, 45778 46702, 45776 46706, 45781 46706, 45786 46708, 45789 46710, 45793 46715, 45788 46711, 45792 46715, 45795 46719, 45798 46723, 45801 46728, 45799 46732, 45804 46730, 45799 46733, 45803 46737, 45804 46737, 45805 46736, 45806 46736, 45807 46736, 45810 46739, 45812 46744, 45812 46748, 2328 27377, 2324 27381, 2325 27383, 2327 27387, 2327 27386, 2324 27386, 2325 27386, 5325 23386, 5327 23389, 5331 23390, 5332 23394, 5337 23396, 5332 23396, 5332 23399, 5331 23399, 5335 23403, 5335 23406, 5340 23409, 5341 23409, 5336 23410, 5331 23405, 5334 23407, 5332 23411, 5335 23413, 5330 20413, 5326 20415, 5326 20418, 5331 20420, 5330 20425, 5327 20425, 5331 20428, 5332 20428, 5337 21428, 5333 21431, 5335 21435, 5336 21437, 5331 21438, 5332 21441, 5335 21444, 5340 21441, 5340 21444, 5336 21445, 5335 21442, 5331 26442, 5334 26439, 5337 26443, 5339 26444, 5340 26448, 5344 26443, 5344 26446, 5347 26444, 5351 26442, 5354 26446, 5351 26449, 5350 30449, 5352 30451, 5352 30448, 5356 30448, 5361 30447, 5365 30449, 5369 30450, 5369 30452, 5369 30457, 5373 30459, 5373 30457, 5375 30462, 5377 30465, 5382 30467, 5386 30467, 5385 30463, 5386 30463, 5385 30463, 5387 30464, 5392 30463, 5394 30468, 5396 30468, 5391 30469, 5395 30473, 5393 30473, 5393 30473, 5397 30478, 5398 30474, 5401 30474, 5403 30471, 5403 30472, 5406 30474, 5402 30469, 5403 30466, 5405 30471, 5406 30471, 5411 30473, 5414 30477, 5414 30481, 5409 30485, 8409 30490, 8410 30493, 8412 30494, 8412 30493, 8415 30494, 8416 30497, 8416 30500, 8421 30505, 8422 30506, 8417 30511, 13417 30513, 13413 30510, 13416 30511, 13414 30515, 13414 30519, 13419 30522, 13421 30527, 13420 30531, 13424 30533, 13420 30535, 13415 35535, 13411 35535, 13415 35536, 13419 35541, 13421 35537, 13425 35533, 13426 35533, 13425 35528, 13430 35529, 13435 35530, 13440 35534, 13445 35535, 13450 35535, 13454 35536, 13457 35540, 13459 35540, 13454 35540, 13457 35543, 13454 35539, 13459 35544, 13459 35548, 18459 35550, 18462 35551, 22462 35550, 22467 35554, 22468 35558, 22470 35556, 22475 35559, 22473 35563, 22472 35568, 22474 35568, 22472 35573, 22476 35573, 22476 35575, 22479 35577, 22484 35580, 22489 35584, 22490 35587, 22491 35589, 22495 35589, 22498 35589, 25498 35590, 25495 35586, 25496 35589, 25500 35589, 25498 35589, 25500 35591, 25505 35595, 25505 35597, 25501 35594, 25501 35595, 25497 35595, 26497 35599, 29497 35595, 29497 35597, 29500 35601, 29500 35605, 29502 35610, 29503 30610, 29504 30607, 29507 30607, 29512 30610, 29513 30610, 29516 30611, 29518 30614, 29520 30612, 3261 17309, 3265 17308, 3269 17307, 3273 17312, 3271 17316, 3271 17317, 3276 17319, 3279 17319, 3284 17315, 3287 17317, 3285 17313, 3280 17314, 3277 17319, 3277 17321, 3278 17326, 3282 17328, 3282 17328, 3278 17329, 3279 17329, 3278 17332, 3280 17328, 3275 17333, 3279 17335, 3282 17330, 3283 17332, 3278 17328, 3279 17328, 3279 17326, 3279 17325, 3279 17325, 3283 17327, 3284 17331, 3284 17336, 3289 17339, 3290 17339, 3290 17342, 3292 17341, 3296 17344, 3296 17345, 3301 17345, 3301 12345, 3301 12346, 3306 12343, 3303 14343, 3307 14344, 3309 14345, 3313 14347, 3315 14347, 3316 16347, 3312 16345, 3312 16350, 3314 16352, 3313 16353, 4313 16350, 4318 16352, 4323 16348, 4326 16352, 4324 16353, 4325 16350, 4325 16350, 4328 16354, 4324 16358, 4325 16360, 4327 16365, 4327 16362, 4324 16366, 4327 20366, 4327 20370, 4324 20371, 4328 20376, 4328 20378, 4333 20377, 4335 20377, 4340 20380, 4341 20383, 4343 20386, 4340 20388, 4341 20390, 4342 20387, 4342 20387, 4337 20392, 4338 20394, 4343 20394, 4348 20395, 4350 20395, 4351 20397, 37499 26503, 37496 26500, 37498 26504, 37498 26505, 37501 26510, 37499 26506, 37500 26506, 37502 29506, 37502 29511, 37507 29512, 37508 33512, 37510 33517, 37515 33522, 37519 33526, 37518 33524, 37523 33525, 37523 33529, 37518 33534, 37521 33532, 37522 33532, 37526 33534, 37529 33534, 37527 33531, 37530 33534, 37535 33537, 37536 38537, 37538 38540, 22360 13359, 25360 13364, 25363 13362, 25364 13366, 25364 13366, 25367 13369, 25365 13371, 25361 13373, 25359 13378, 25362 13378, 2249 13366, 2254 13370, 2256 13367, 2259 13367, 2263 13362, 2266 13358, 2266 13360, 2271 13365, 2274 13367, 2276 13367, 2277 13367, 2275 13366, 2276 13369, 2280 13369, 2282 13374, 2286 13370, 2286 13369, 2291 13372, 2292 13370, 2295 13372, 2300 13377, 2300 13376, 2297 13379, 273 22351, 275 22354, 4275 22351, 4271 22352, 4272 22354, 4273 22359, 4274 22364, 4278 22367, 4283 22369, 4286 24369, 4281 24369, 4284 24369, 4287 24369, 4289 24368, 4291 24366, 4296 24364, 4297 24366, 4300 24369, 4303 24373, 1303 24374, 1303 24375, 1307 24379, 1307 24380, 1309 24381, 1314 24384, 1316 24386, 1320 24384, 1318 24386, 1318 24391, 1320 24391, 1320 29391, 1323 29391, 1318 29387, 1322 29390, 1323 29393, 1328 29393, 1329 29393, 2329 29398, 2329 29398, 2334 29397, -664 24371, -661 24372, -659 24372, -654 24375, -651 24376, -647 24376, -645 24378, -641 24374, -636 24379, -633 24384, -636 24386, -636 24388, -636 24388, -634 24392, -635 24394, -630 24390, -628 24390, -627 24390, 373 24393, 378 24398, 376 24396, 379 24401, 3379 24404, 6379 24409, 6380 24412, 6375 24410, 6372 24410, 6377 24407, 6372 24407, 6377 24407, 6381 24410, 6376 24413, 6380 24415, 6382 24416, 6380 24419, 6380 24423, 6385 24427, 6387 24429, 6389 24432, 6392 24437, 6388 24434, 6388 24439, 6389 24440, 6390 24444, 6389 24448, 6385 29448, 6385 29451, 6388 29455, 6384 29450, 6389 29451, 6392 29456, 6395 29456, 6399 29459, 6402 29463, 6402 29467, 6399 29471, 6395 29471, 6397 29474, 6399 29477, 6401 29472, 6396 29471, 6399 29474, 6398 29477, 6398 29474, 6395 29469, 6391 29473, 6392 29474, 6391 29469, 6391 29472, 6394 29474, 6390 33474, 6392 33470, 6393 33470, 6394 33471, 6396 33471, 324 22376, 324 22378, 325 22381, 329 22382, 333 22386, 332 22387, 334 22390, 335 22387, 333 22387, 332 22391, 334 22395, 334 22400, 339 22401, 341 22398, 342 22403, 342 22402, 342 22400, 345 22400, 345 22400, 343 22404, 344 22408, 345 22406, 350 22407, 347 22411, 349 22415, 344 22415, 347 22417, 342 22421, 347 22421, 350 22426, 350 22430, 353 22431, 354 22436, 354 22440, 4354 22442, 4355 22446, 4356 22448, 4356 22451, 4359 22453, 4362 22454, 4366 22454, 4369 22455, 4371 22457, 4368 22459, 4371 22457, 4375 22462, 4379 22463, 4382 22463, 4382 22468, 4387 22471, 4387 22471, 4392 22473, 4387 22473, 4387 22476, 25573 26512, 25576 26511, 25580 26516, 25583 26516, 25583 26516, 25585 26512, 25585 26517, 25589 26520, 25591 26519, 25592 26519, 25593 26521, 25591 26524, 25589 26526, 23589 26530, 23587 26535, 23591 26538, 23594 26542, 24594 26547, 24590 26549, 24595 26551, 24600 26547, 24600 26552, 24604 26549, 24600 26544, 24602 26549, 24602 26552, 24602 31552, 24607 31553, 24610 31555, 24615 31556, 24617 36556, 24618 36561, 24621 36561, 24624 36564, 24624 36568, 24629 35568, 24629 35573, 24634 35573, 25634 35574, 25637 35573, 25638 35577, 25638 35577, 25640 35580, 25643 35584, 25643 35587, 25643 35592, 25644 40592, 20644 40597, 20647 40597, 20652 40599, 20653 40595, 20653 40598, 20650 40595, 20650 40595, 20654 40600, 20654 40600, 20658 40601, 20658 40604, 20658 40605, 20661 40602, 20664 40601, 20664 40601, 20665 40604, 20670 40605, 20667 40610, 1217 13318, 1216 13323, 1214 13321, 1211 13316, 1212 13316, 1213 13321, 6213 13324, 6216 13324, 6218 13324, 6213 13327, 6216 13322, 6216 13327, 6216 13328, 6218 13323, 6221 13327, 6220 13325, 6221 13325, 6220 13330, 6223 13333, 6227 13335, 6232 13339, 6233 13343, 6233 13347, 6237 13342, 6236 13346, 6236 13348, 6238 13349, 25526 26487, 25523 26488, 25526 26493, 25529 26491, 25531 26488, 25532 26486, 25536 27486, 25541 27490, 25539 27492, 25543 27487, 25546 27490, 25549 27494, 25552 27495, 25552 27495, 25556 27490, 25561 27490, 25565 27493, 25563 27493, 25565 27497, 25563 27495, 25565 27497, 25565 27499, 25566 27501, 25565 27501, 25565 27501, 25560 27502, 25565 27503, 25567 27507, 25569 27507, 25571 27507, 25569 27508, 25567 27509, 25567 27509, 25567 27509, 25568 27509, 25572 27505, 25572 27501, 25576 27502, 25572 32502, 25572 32505, 25575 32505, 25578 32501, 25578 32502, 25579 32505, 25581 32507, 25585 32508, 25590 32511, 25594 32516, 25598 32511, 25601 32511, 25596 32507, 25599 32510, 25599 32514, 25596 32513, 25596 32514, 25598 32517, 25594 32517, 25596 32519, 25596 32524, 25600 32524, 25604 32521, 25605 32522, 27605 32524, 27609 32527, 27610 31527, 27615 31531, 27617 31531, 30617 31534, 30619 31534, 30620 31536, 30621 31540, 30625 31541, 30625 31542, 30627 31542, 30628 31545, 30629 31545, 30626 31544, 30625 31544, 30626 31549, 34626 31550, 34621 31547, 34625 31549, 34626 31553, 34626 31552, 34628 31554, 34628 31559, 34628 31555, 34630 31559, 34635 31559, 34638 31563, 34636 31568, 34638 31568, 34641 31566, 34641 31564, 36641 31559, 36638 27559, 41638 27561, 41642 27558, 41646 27562, 41649 27563, 41650 27559, 41655 27559, 41660 27559, 41660 27556, 41660 27556, 41662 27554, 41658 27558, 41663 27562, 41666 27565, 41669 27570, 41664 27566, 41665 27567, 41665 27569, 41664 27573, 41663 27573, 41666 27575, 41666 27571, 41661 30571, 41662 30569, 41662 30565, 41667 30570, 41666 30565, 41666 30565, 41666 30566, 41666 30567, 41662 30562, 1314 24384, 4314 25384, 4317 25388, 4317 25389, 4321 25387, 4324 25392, 6324 25391, 6324 25391, 6328 25396, 6323 25401, 6326 25401, 6326 25405, 6321 25408, 9321 25409, 9316 25404, 9314 25406, 9312 25407, 9315 25407, 9315 25407, 9318 25404, 9321 25405, 4321 25400, 8321 25402, 8317 25404, 8317 25400, 8317 25401, 8313 25402, 8309 25398, 8311 25398, 8313 25401, 8317 25406, 8312 25407, 11312 25369, 11313 25369, 11318 25374, 11322 25379, 11327 25379, 11327 25384, 11327 25386, 11328 25382, 14328 25384, 14330 25386, 14333 25387, 14336 25389, 14338 25390, 19338 25390, 19338 25393, 19334 25394, 19334 25395, 19337 25392, 19340 25395, 19344 25397, 19342 25397, 19347 25400, 19347 25398, 19349 25398, 19351 25397, 19353 25401, 19352 25402, 19350 25403, 19351 25407, 19354 25403, 19352 25406, 19356 25404, 19355 25409, 23355 25406, 23356 25406, 23358 25409, 23360 25413, 23362 25417, 23365 25418, 23369 25416, 23367 25415, 23369 25418, 23365 25417, 23369 25420, 23369 25420, 23372 25422, 24372 25418, 24372 25423, 24375 27423, 24380 27423, 24382 27420, 24382 27416, 24382 27414, 24382 27410, 24378 27410, 24376 27414, 24372 27418, 24372 27419, 24373 27424, 24377 27419, 24380 27415, 24377 27419, 24380 27422, 24384 27425, 24385 27430, 24385 27429, 24387 27434, 24392 27435, 24396 27436, 24397 27440, 24401 30440, 24402 30443, 24406 30447, 24405 30443, 24408 30442, 24412 30446, 24408 30450, 24410 30449, 24405 30449, 24410 30446, 24414 30450, 24418 30450, 24418 30453, 19418 30453, 19418 30451, 19420 30456, 19422 30457, 19425 30462, 15425 30466, 15425 30468, 15427 30470, 16427 30471, 16426 30475, 16423 30478, 16428 30478, 16430 30480, 16430 30480, 16426 30478, 16426 33478, 16427 33478, 16429 33481, 16427 33483, 16428 33481, 16424 33484, 16427 33486, 16432 33483, 16432 33482, 16431 33486, 16426 33486, 16429 33488, 16432 33492, 16433 33492, 16436 33492, 16437 33495, 16434 33491, 16438 37491, 16436 37494, 16440 37489, 16445 37486, 16448 37484, 16449 37484, 16449 37486, 16453 37482, 16456 37483, 16460 37483, 16456 37483, 16456 37486, 16461 37490, 16462 37495, 16465 37499, 16466 37496, 16467 37497, 16468 37498, 16470 37501, 16470 37505, 16470 37505, 16475 37507, 16475 37507, 16475 37502, 16478 37498, 21478 33498, 21475 33497, 21478 33493, 21480 33495, 21480 33500, 21480 33496, 21482 33500, 21485 33505, 21486 33508, 21485 33504, 21486 33509, 21486 33509, 21490 35509, 21493 35509, 21496 35510, 21498 35514, 21494 35510, 21494 35513, 21491 35518, 21492 35521, 21489 35523, 23489 35527, 23487 35532, 23489 35537, 23485 35538, 23489 35539, 23490 35541, 23495 35543, 23497 35546, 23497 35550, 23497 35554, 23493 35553, 23490 35556, 23494 35559, 23497 35564, 23502 35563, 23498 35561, 4324 16358, 4319 16362, 4320 16362, 4322 16367, 4317 16367, 4317 16366, 4318 20366, 4322 20369, 4325 20367, 4328 20370, 4331 20371, 4334 20374, 4339 20378, 4340 20379, 4335 20379, 4340 20379, 4343 20381, 4344 20381, 4344 20382, 4345 20385, 4348 20390, 4348 20390, 4348 20390, 4348 20390, 4351 20394, 4354 20399, 4356 20400, 4357 20404, 4360 20404, 4362 20405, 4362 20408, 4365 20409, 4370 20410, 4374 20415, 4373 20420, 4369 20421, 4366 20426, 4369 20424, 4374 20429, 4375 20426, 4376 20422, 4379 20422, 4383 20426, 4384 20427, 4386 20422, 4391 20425, 4387 20427, 4392 20427, 4392 20429, 4394 20433, 4398 20438, 41576 39702, 41580 39706, 41578 39708, 45578 39708, 45577 39713, 45579 39717, 45583 39719, 45583 39722, 45585 39725, 45580 39730, 47580 39726, 47583 39723, 47588 39726, 47588 39730, 47591 39734, 47594 39737, 47599 39737, 47595 39737, 47598 39739, 47599 39739, 47597 39739, 47593 39743, 47595 39748, 47595 39751, 4076 20267, 4079 20272, 4081 20272, 4080 20275, 4080 22275, 4085 22280, 4089 22276, 4090 22279, 4088 22283, 4084 22284, 4086 22286, 4088 22281, 4084 22281, 4089 22285, 4092 22285, 4094 22285, 4094 22290, 4096 22291, 4099 22294, 4099 22295, 4097 22290, 4097 22292, 4097 22297, 4097 22292, 4094 22289, 4091 22290, 4092 22290, 4097 22285, 4102 22290, 4105 22289, 4106 22292, 4106 22293, 4109 22298, 4114 22296, 4119 22294, 4122 22299, 122 22304, 123 22307, 124 22304, 124 22304, 123 26304, 127 26307, 131 26307, 129 26309, 129 26310, 134 26310, 134 26311, 138 26311, 143 26313, 142 26315, 145 26317, 142 26318, 147 26322, 151 26322, 155 26325, 155 29325, 160 29330, 160 29333, 164 29328, 164 34328, 167 34333, 170 34332, 169 34336, 171 34337, 175 34338, 175 34340, 179 34342, 180 34344, 180 34348, 184 34352, 179 34352, 184 34352, 186 34357, 186 34362, 183 34364, 185 34369, 189 34369, 194 34369, 199 34371, 201 34370, 205 34372, 207 34372, 204 34367, 206 34364, 1206 34364, 1207 34368, 1207 30368, 1207 30363, 1208 30365, 1209 30368, 1212 30370, 1212 30370, 1216 30371, 1220 30376, 1221 30379, 1216 30383, 1216 30388, 1219 30386, 1224 30387, 1225 30386, 1227 30384, 1230 30383, 1233 30387, 1234 30387, 1237 30388, 1239 30392, 1244 30390, 1246 30393, 2246 30396, 2243 30399, 2247 30401, 2247 30403, 2246 30398, 2244 30399, 2248 32399, 2248 32399, 2251 32402, 2253 32397, 5253 32394, 5253 32399, 5257 32403, 5257 32401, 5259 32401, 5259 32405, 5263 32410, 5263 32415, 5268 32416, 5273 32420, 5275 32423, 5278 32424, 5283 32426, 5281 32429, 6281 33429, 6286 33433, 6286 33434, 6284 33435, 6284 33432, 6288 33429, 6290 32429, 6290 32425, 6288 32428, 6290 32428, 11290 32431, 11294 32429, 11294 32433, 11292 32438, 11288 32441, 11288 32441, 11285 32446, 11280 32446, 11281 32447, 11285 32449, 11286 32449, 11285 32452, 13285 32451, 13289 32446, 16289 32450, 16284 32449, 16285 32449, 16286 32452, 16287 32452, 16286 32450, 16288 32447, 16292 32450, 16293 32450, 16294 32454, 16293 32454, 16293 32454, 16293 32449, 16289 32451, 16290 32456, 16289 32461, 16293 36461, 16291 36466, 16295 36466, 16296 36466, 16299 36466, 16303 36468, 16308 36473, 16312 36471, 16312 36467, 16315 36463, 16314 36464, 16315 36469, 16315 36473, 16310 36474, 16311 36472, 16316 36474, 16321 41474, 16324 41475, 16327 44475, 16332 44475, 16332 44475, 16332 44477, 16332 44478, 16337 44483, 16334 44481, 8416 30500, 8417 30501, 8421 30501, 8416 30505, 8418 30504, 8420 30499, 8423 35499, 8425 35498, 8429 35501, 8431 35503, 8434 35503, 8438 35507, 8440 35507, 8445 35509, 8442 35512, 8445 35513, 8442 35513, 8442 35515, 8443 35519, 8447 35515, 8450 35516, 8445 35521, 8445 35523, 8444 35528, 8446 35530, 8443 35531, 8438 35531, 8435 35527, 8431 35531, 8432 35534, 8433 35536, 8431 35537, 8435 35539, 8439 32539, 8437 32540, 8441 32540, 8438 32543, 9438 32546, 9436 32541, 9431 32538, 9431 32538, 9435 32541, 9435 32546, 9431 32547, 9436 32542, 9438 32542, 9438 34542, 7438 34542, 7440 34547, 7441 34547, 7441 34547, 7441 34552, 7440 34553, 7440 34556, 7440 34557, 7440 34560, 11440 34565, 11436 34563, 11438 34559, 7438 34557, 7438 34553, 122 1239, 126 1243, 127 1240, 127 1242, 131 1239, 130 1239, 127 1240, 125 1243, 130 2243, 134 2246, 133 2246, 137 2246, 142 2246, 147 2251, 148 2256, 146 2257, 148 2252, 146 2249, 148 2248, 152 2253, 157 2249, 161 2246, 162 2247, 162 2249, 157 2248, 158 2249, 3158 2250, 3161 2252, 3161 2254, 3166 2258, 3167 2261, 3168 2259, 3171 2261, 3173 2266, 3171 2267, 3176 2272, 3179 2277, 3176 2280, 3180 2279, 3175 2283, 3179 2280, 3182 2283, 3184 2288, 3187 2293, 5187 2290, 5187 2292, 5183 2290, 5187 2292, 5186 2297, 5189 2297, 5189 2301, 5192 2303, 5189 2303, 5187 2304, 5183 6304, 5184 6301, 5189 6304, 5191 6302, 5193 6300, 5195 6300, 5195 6300, 5197 6301, 5197 6304, 5199 6301, 5197 6304, 5192 6306, 5193 6310, 5194 6312, 5197 6316, 24397 27440, 24393 27441, 24395 27437, 24400 27440, 24400 27441, 16288 32447, 21288 32447, 21288 32448, 21284 32452, 21285 32450, 21285 32452, 21287 32455, 21283 32460, 21284 32462, 21284 32467, 21284 32472, 21286 32474, 21291 32475, 21289 32475, 21289 32473, 21289 32478, 21286 32481, 21290 32486, 21293 32486, 21293 32490, 21298 32489, 21301 32490, 21303 32491, 21305 32488, 21303 32486, 21307 32491, 21312 32495, 21314 32499, 21315 32495, 21317 32499, 21314 32499, 21316 32502, 21318 32505, 21313 32510, 21313 32512, 21314 32517, 21319 32520, 21321 32520, 21326 32520, 21329 32525, 21330 32530, 21334 32531, 21330 36531, 21333 41531, 21338 41531, 21336 41535, 21339 41537, 21337 41539, 21341 41544, 21342 41544, 21345 41540, 25345 41543, 25342 41546, 25339 41546, 25339 41549, 25337 41546, 25337 41547, 25337 46547, 25341 46552, 30341 46555, 30342 46560, 30345 46561, 30344 46557, 30339 46560, 30343 46565, 30339 46569, 30338 46567, 30340 46568, 24375 27423, 24375 27425, 24377 27428, 24379 27429, 24379 27434, 24376 27439, 24381 27441, 24386 27436, 24387 27438, 24384 27441, 24383 27446, 24383 31446, 24383 33446, 20383 33443, 20385 34443, 20384 34444, 20380 34448, 20383 34450, 20383 34446, 20386 34447, 20390 34450, 20394 34451, 20395 34446, 20395 34451, 20398 29451, 20397 29447, 20401 29447, 20402 29443, 20401 29440, 20406 29443, 20411 29444, 20412 29444, 20412 29448, 20410 29449, 20415 29452, 20415 29455, 20414 29459, 20415 29462, 20420 29465, 20415 29467, 20417 29468, 20418 29468, 20418 29467, 20418 29467, 20420 29468, 20416 29469, 20420 29467, 20415 29464, 20415 26464, 20420 26462, 20423 26463, 20423 26465, 20423 26464, 43580 35662, 43580 35658, 43580 35662, 43580 35664, 43585 35665, 43585 35663, 43585 35666, 43581 35667, 43585 35665, 43589 35670, 25627 25555, 25631 25555, 25632 25558, 25632 25563, 25634 25564, 25629 25565, 25625 25561, 25625 25563, 25626 25565, 26626 25570, 26629 25570, 29629 25575, 29628 25578, 29627 25579, 29624 25583, 29627 25587, 29632 25592, 29634 25593, 29637 25595, 29637 25598, 29639 25602, 29644 25600, 29645 25601, 29646 25601, 29651 25602, 29656 25606, 29658 25606, 29663 25607, 29663 25605, 29666 26605, 29668 26608, 29667 26608, 29670 26611, 29674 26611, 29671 26615, 29673 26620, 29676 26617, 29681 26620, 29682 26620, 29683 26619, 29684 26623, 29681 26621, 29686 26626, 29688 26628, 29691 26628, 29692 26632, 29693 26634, 29695 26629, 29696 26624, 29700 26621, 29705 29621, 29709 29620, 29708 29624, 29711 29627, 34711 29630, 34712 29632, 34712 29631, 2284 16415, 2285 16416, 2285 16416, 2289 16421, 2294 16425, 2299 16425, 2300 16430, 2305 16430, 2306 16433, 2311 11433, 2315 11436, 2310 14436, 2310 14435, 2313 14437, 2312 14441, 2310 14442, 2311 14444, 2313 14444, 2311 14447, 2314 14447, 2316 14451, 2316 14456, 2316 14454, 2311 14455, 2311 14455, 2311 14460, 2315 14465, 2315 14465, 2311 19465, 2311 19465, 2313 19466, 2317 19469, 2320 19469, 2323 19466, 2319 19468, 2323 19471, 2324 19471, 2324 19473, 2324 19473, 2322 19468, 2323 19466, 2324 19465, 2329 19470, 2329 19465, 2324 19465, 2324 19467, 2319 19471, 2320 19475, 2104 -1844, 2109 -1844, 2113 -1842, 2116 1158, 2116 1160, 2117 1161, 2116 6161, 2118 6166, 2123 6169, 2126 6174, 2123 6179, 2126 6183, 2126 6187, 2130 6182, 2128 6183, 2127 6182, 2128 6185, 2124 10185, 2129 10190, 2130 10193, 2132 10192, 2132 10195, 2129 11195, 2129 11199, 2133 11200, 2134 11196, 2133 11201, 2137 11205, 2137 11207, 2141 11203, 2144 11207, 2145 11208, 2149 11212, 2144 11214, 2144 11215, 2149 11216, 2152 11221, 2152 11223, 2153 11223, 2154 11226, 2154 11226, 2150 11228, 2152 11224, 2152 11227, 2148 11222, 2145 11223, 2142 11225, 2145 11222, 2142 11223, 2142 11227, 2147 11229, 2149 11230, 2154 11230, 2157 11228, 2159 11233, 2159 11233, 2155 11237, 2155 11242, 2151 11243, 7151 10243, 7156 10245, 7159 10245, 7164 10247, 7166 10252, 7166 10255, 7171 10257, 7173 10257, 7174 10261, 7179 10264, 7184 10260, 7189 10264, 7193 8264, 7197 8260, 7202 8262, 7206 8262, 7205 8265, 7205 8266, 7207 8270, 7211 8274, 7211 8277, 7216 8277, 7216 8280, 7212 8280, 7213 8280, 7215 8283, 7220 8282, 7224 8287, 7225 8283, 7222 10283, 7223 10287, 7225 10288, 7230 10290, 7232 10294, 7233 10294, 7233 10297, 7234 10298, 7234 10301, 7236 10303, 7231 10299, 7228 10298, 7223 10297, 7225 10299, 7230 10303, 7231 10307, 7234 10311, 7234 10315, 7235 10320, 7236 9320, 7241 9322, 7246 9325, 7243 9330, 7243 9332, 7240 9335, 7237 9334, 7239 9339, 7238 9339, 7238 9341, 7238 9342, 7233 14342, 7232 14337, 7234 14342, 7239 18342, 4084 22284, 4083 22284, 6083 22287, 6078 22289, 6078 22293, 6080 22290, 6082 22291, 6086 22296, 6086 22297, 6087 22297, 6088 22295, 6093 22298, 6094 22297, 9094 22294, 9097 22298, 9098 22299, 9098 22301, 9093 22296, 9098 22299, 9100 22294, 9096 18294, 9099 18294, 9098 18298, 9101 18296, 9100 18301, 9105 18303, 9105 18306, 9105 18309, 9102 18305, 9104 18306, 9108 18309, 9104 18314, 9103 18310, 9105 18312, 9105 18316, 9109 18314, 9109 18319, 9109 18324, 9113 18326, 9113 18330, 9115 18333, 9113 18333, 9118 18333, 9123 18333, 9123 18336, 9125 18335, 9126 18336, 9127 18332, 9129 18329, 9127 18332, 9130 18333, 9135 18333, 9138 18337, 9143 18341, 9144 18346, 9145 18344, 9150 18348, 9154 18345, 9152 18350, 9151 18345, 9151 18345, 9156 18347, 9160 18349, 9163 18350, 9163 18351, 9165 18356, 9166 18356, 9164 18353, 9167 18356, 9167 18355, 9167 18356, 9167 18360, 9165 18356, 9169 18357, 9169 18353, 9170 18355, 9170 18351, 9175 18351, 9177 18351, 9181 18352, 9184 18353, 9189 18356, 9188 18361, 9191 18364, 9194 18364, 9198 18366, 13198 18371, 13198 18373, 13198 18375, 13201 18378, 13196 18378, 13199 18379, 13202 18381, 13207 18384, 13212 18388, 13211 18383, 13211 18378, 13215 18379, 13218 20379, 13214 20379, 13217 20379, 13213 20379, 13213 20376, 13210 20377, 13206 20377, 13206 20373, 13207 20373, 13209 20370, 13214 20371, 13218 20371, 13223 20376, 13224 20381, 13227 20385, 13228 20390, 13232 20387, 9232 20392, 9230 20388, 9230 20390, 9225 20393, 9225 20396, 4225 20401, 4225 20400, 4227 20403, 4224 20408, 4222 20412, 4222 20415, 4225 20420, 4229 20425, 4232 20422, 4236 20425, 4234 20426, 4238 20427, 4240 20427, 4241 20427, 4237 20431, 4233 20431, 4232 20430, 4230 20432, 4234 20431, 4234 20435, 4238 20437, 4243 20435, 4243 22435, 4238 22440, 4241 22441, 4241 22443, 4238 22447, 4234 22443, 4238 22448, 4238 22450, 4241 22451, 4241 22456, 4243 22458, 4247 22461, 4247 22464, 4252 22466, 4253 22469, 4255 22469, 4251 22469, 4253 22464, 4253 22468, 4257 22473, 4259 22477, 4258 22482, 4261 22483, 4262 22484, 4259 22489, 6259 22493, 6262 22494, 6262 22497, 6264 22500, 6264 22504, 6269 22499, 6273 22499, 6278 22495, 6278 22493, 6283 22491, 6288 22494, 6291 22494, 6296 22494, 6296 22493, 6294 22489, 6294 22493, 6290 22493, 6290 22498, 6290 22500, 6288 22501, 6290 22505, 6294 22504, 5294 22507, 5294 22507, 5298 22512, 5297 22514, 5302 22514, 5307 22517, 5304 22518, 5308 22514, 5311 22517, 5315 27517, 5315 27517, 5319 27517, 5324 22517, 5328 22521, 6328 22520, 6325 22522, 6325 22527, 6322 22527, 6323 22530, 6325 22535, 6325 22535, 6326 22536, 6326 22536, 6327 22533, 6323 22535, 6325 22538, 6330 22538, 6331 22534, 6326 22531, 10326 22526, 10321 22528, 10317 22524, 10316 22529, 10313 22529, 10309 22530, 10306 22535, 10308 22531, 10308 22532, 10311 22534, 10314 27534, 10314 27538, 10314 27538, 10309 27540, 10309 27536, 11309 27535, 11309 27537, 11310 27539, 11305 27535, 11300 27536, 11296 27538, 11296 27538, 11301 27542, 11299 27546, 11304 27551, 11308 27551, 11313 27553, 11315 30553, 11319 30555, 11315 30550, 11318 30545, 11318 30544, 11321 30549, 11320 30550, 11325 30554, 11328 30558, 11328 34558, 11332 34562, 11333 34562, 11335 34562, 11334 34565, 11330 34565, 11333 34566, 11338 34566, 11338 34571, 11342 34574, 11344 34573, 11347 34572, 11346 34573, 11347 34575, 11351 34578, 15351 34578, 15356 34573, 15361 34570, 15364 34575, 15365 34580, 15369 34581, 15370 34581, 15373 34585, 15376 34580, 15381 34578, 15385 34583, 15386 34588, 15389 34587, 17389 34582, 17394 34582, 17393 34582, 17398 34577, 17399 34582, 17399 34584, 17399 39584, 17404 39588, 17399 39591, 17404 39591, 17408 39586, 17405 39591, 17409 39593, 17411 39596, 17408 39596, 17411 39599, 17411 39603, 17414 39607, 17418 39612, 17419 39612, 17419 39612, 17423 39611, 17424 39613, 17426 39612, 17429 39608, 17427 39609, 17428 39613, 17425 39615, 17424 39614, 17427 39617, 17430 39622, 17430 39623, 17431 39620, 17434 39620, 13434 39619, 13434 39621, 13434 39621, 13434 44621, 13436 44625, 13436 44627, 13441 44631, 13444 44636, 13444 44639, 13442 44635, 13444 44635, 13447 44639, 13449 44643, 13447 44641, 13447 44642, 13452 44643, 13456 44648, 13459 44648, 13461 44646, 15461 44643, 15459 44648, 15463 44648, 15464 44646, 15461 44649, 15461 44651, 15465 44654, 15460 44655, 15461 44657, 15463 44661, 15465 44665, 15465 44665, 15465 44667, 15469 44670, 15474 44672, 15476 44668, 15472 44672, 15473 44674, 15475 44678, 15477 44679, -3804 12302, -3802 12305, -3803 13305, -3802 13300, -3806 13296, -3807 13299, -3804 13304, -3802 13301, -3799 13305, -3799 13306, -3794 18306, -3799 18310, -3797 18315, -3800 18315, -3797 18316, -3799 18318, -3794 18323, -3793 18326, -3789 18325, -3784 18324, -3784 18325, -3782 18325, -3780 18325, -3779 18328, -3780 18329, -3781 18324, -3786 18328, -1786 18328, -1786 18333, -1782 18337, -1782 18338, -1779 18333, -1775 18338, -6775 18341, -6772 18343, -6774 18345, -6779 18345, -6777 18345, -6777 18347, -6777 18343, -6775 18347, -6780 18342, -6777 18345, -6776 18345, -6774 18340, -6774 18337, -6774 18337, -6778 18342, -6782 18342, -6785 18339, -6784 18340, -6779 22340, -6779 22339, -6776 22335, -6775 22330, -6775 22335, -6775 22339, -6770 22339, -6772 22344, -6767 22345, -6765 22341, -6765 22339, -6765 22339, -6765 22337, -6765 22340, -6760 22335, -6757 22335, -6762 22336, -6763 22338, -6765 22343, -6760 22338, -6758 22338, -6758 22338, -6756 22341, -6752 22345, -6752 22346, -6748 22343, -4748 22347, -4745 22347, -4750 22347, -4749 22348, -4747 22349, -4743 22352, -4738 22357, -4734 22362, -4736 22367, -4738 22362, 21338 41531, 21336 41531, 21332 41530, 21332 41530, 21335 41533, 21330 41533, 21331 41534, 21328 41536, 21330 41536, 21326 41541, 21330 41536, 21332 41539, 21336 41536, 21338 40536, 21336 40540, 21341 40538, 21343 40538, 21346 40538, 21348 40536, 21352 40536, 21355 40539, 21359 40543, 21361 40546, 21362 40550, 21357 40550, 21362 40551, 21361 40554, 21358 40555, 21358 40554, 21359 40554, 21363 40558, 21360 45558, 21364 45560, 21368 45557, 21372 45561, 21376 45560, 21379 45557, 22379 45553, 22384 45553, 22384 45556, 22388 45561, 22389 45561, 22390 45557, 22394 45561, 24394 45565, 22394 45562, 22399 45565, 22401 45562, 22400 45565, 22402 45568, 22402 45573, 22406 45577, 22408 45581, 22408 45585, 22406 45585, 22409 45586, 22411 45583, 22411 45579, 22411 45583, 22409 45583, 22404 45586, 22404 45586, 22406 45591, 22408 45591, 22408 45593, 22413 45593, 22415 45594, 22419 45595, 22419 45596, 22424 45591, 22427 45587, 22430 50587, 22430 50589, 22430 50589, 22432 50592, 22437 50594, 22437 50589, 22437 50594, 22441 50599, 22442 50594, 22447 50591, 22444 50588, 22444 50590, 22445 54590, 22445 54594, 22448 54599, 22450 54601, 22450 59601, 22446 59597, 22451 59600, 22451 59603, 22454 59604, 22459 59604, 22460 59609, 22459 59606, 22464 59607, 22465 59608, 22463 59609, 22460 59606, 22459 59605, 22459 59605, 22457 59609, 25457 59610, 25459 59615, 25464 59617, 25466 59618, 25469 59621, 25474 59616, 25478 59617, 25480 59614, 25484 59619, 25484 59620, 25488 59616, 25485 59618, 25489 59623, 25494 59627, 25499 59629, 148 2256, 152 2253, 152 2253, 154 2258, 159 2253, 160 2257, 159 2256, 163 2259, 161 3259, 163 3262, 163 3259, 165 3259, 170 3263, 170 3263, 174 3267, 169 3271, 174 3275, 174 3276, 174 3278, 177 3282, 181 3286, 183 3287, 186 3284, 187 3286, 189 3286, 193 3288, 194 3290, 193 6290, 195 6293, 200 6289, 197 6294, 196 6293, 197 6293, 201 6297, 202 6292, 200 6294, 204 6295, 209 6300, 214 6305, 217 6305, 218 6305, 213 6308, 214 6308, 218 6313, 218 6308, 216 6312, 215 6312, 213 6309, 214 6313, 219 6318, 222 6321, 226 6326, 224 6331, 222 6327, 41575 39716, 41574 39713, 41578 40713, 41582 40718, 41578 40721, 36578 40721, 36579 40723, 36584 40720, 36587 40725, 36592 43725, 36587 43725, 36584 43728, 36587 43733, 36592 43735, 36592 43734, 15291 11311, 15287 11316, 15288 11319, 15291 11319, 15296 11319, 15297 11320, 15298 13320, 38744 37650, 38745 37654, 38747 37659, 38746 37662, 38741 37663, 38739 37666, 38744 37666, 38747 37661, 38750 37666, 38750 37666, 38754 37671, 38755 37671, 38750 37673, 38750 37672, 38754 37677, 38756 37678, 38758 37680, 38760 37678, 38762 37683, 38762 37679, 38760 37679, 38765 37679, 38769 37678, 38774 40678, 38769 40683, 38774 40687, 38776 44687, 38780 44690, 38782 44694, 38782 44694, 38781 44699, 38784 44704, 38782 44699, 38777 44700, 38777 44700, 38777 44700, 38781 44703, 38785 44700, 38786 44700, 38788 44696, 38788 44696, 38788 44700, 38793 44702, 38795 44703, 38797 44707, 38802 44712, 38805 44712, 38809 44713, 38804 44710, 38808 44712, 38811 44713, 36811 44713, 36816 44708, 36815 44709, 36816 44709, 36818 44713, 36813 44716, 36814 48716, 36813 48721, 36817 48725, 36818 51725, 36820 51721, 36824 51724, 40824 51719, 40829 51716, 40832 51720, 40831 51723, 40834 51727, 40837 51728, 40842 51725, 40843 51725, 40838 51729, 40843 51734, 40848 51738, 40850 51742, 40851 51744, 40853 51747, 40856 51749, 40857 51750, 40859 51754, 40859 51750, 40863 51752, 40868 51755, 40864 51754, 40868 51754, 40871 51756, 40867 51756, 40865 51759, 40860 51761, 40857 51757, 40857 51762, 40854 51762, 40855 51764, 40859 51765, 40857 51761, 40854 51764, 40855 51765, 40857 51766, 40860 51761, 40861 51760, 40865 51761, 40865 51763, 40862 51768, 40861 51768, 40856 51772, 40852 51769, 40854 51771, 40854 51771, 40850 51776, 40854 51780, 40856 51782, 40854 51782, 43854 51782, 43856 52782, 43858 52785, 43861 52785, 43861 52780, 37514 26540, 37519 26535, 37522 26539, 37522 26544, 37524 26548, 37529 26548, 37534 26553, 37539 26548, 37542 26553, 37547 26548, 37551 26551, 37551 26554, 37550 26555, 37551 26557, 37548 26557, 37548 26557, 37551 26560, 37551 26563, 37554 26563, 37558 26568, 37562 26563, 37563 26565, 37567 26569, 41567 26569, 41571 26572, 41573 26577, 41573 26577, 41578 29577, 41573 29577, 41575 29580, 41575 29582, 46575 29582, 46571 29586, 45571 29587, 45574 29587, 45570 29587, 45575 29585, 45577 29582, 45573 29585, 45574 29588, 45574 29589, 45578 29589, 45580 29592, 45583 29595, 45584 29597, 45584 29602, 45586 29601, 45591 29604, 45587 29609, 45591 33609, 45595 36609, 45596 36611, 45601 36613, 45602 36608, 45606 36608, 45606 36612, 45606 36611, 45610 36614, 50610 36617, 50613 36613, 50616 36613, 50621 36609, 50626 36609, 50627 36610, 50627 36609, 50631 36610, 50626 36612, 50627 36614, 50628 36614, 50631 36612, 50629 36614, 50630 36618, 50634 36622, 46634 34622, 46634 35622, 46638 35626, 46638 35621, 46639 35624, 46641 35623, 46645 35624, 46647 35629, 46645 35634, 46650 35639, 46650 35644, 46651 35647, 46653 35651, 46657 35654, 46654 35659, 46659 35660, 46660 35661, 46664 35664, 46661 35667, 46664 35668, 46667 35667, 46669 35671, 46669 35667, 46672 35670, 46674 35675, 46676 35675, 47676 35672, 47678 35676, 47679 35677, 47679 35682, 47679 35681, 47679 35681, 47679 35686, 47674 35687, 47673 35687, 49673 35689, 49676 35693, 49679 35696, 49677 35696, 54677 35701, 54680 35703, 54676 35703, 54672 35705, 54672 35704, 54677 35707, 54678 34707, 54678 34707, 54681 34710, 54685 34712, 54690 34710, 54690 34711, 54687 34706, 54689 34706, 54694 34711, 54689 36711, 54689 36710, 54684 36711, 54687 38711, 54682 38714, 54682 38718, 54679 38718, 54681 38723, 54684 38724, 54689 38720, 54690 38721, 54694 38726, 54699 38730, 54701 38731, 54702 38728, 54704 38724, 52704 38723, 52704 38723, 52704 38725, 52704 38729, 52706 38730, 52708 38732, 52709 38733, 52713 38732, 52713 35732, 52715 35737, 52714 35741, 52714 35743, 52715 35746, 52715 35749, 52710 35749, 52712 39749, 52715 39753, 52718 39752, 52723 39753, 52722 39757, 52718 39760, 52718 40760, 47718 40761, 47719 40765, 47724 40765, 47724 40765, 47724 40770, 47728 40773, 47730 40776, 47735 40781, 47733 40777, 50733 40781, 51733 40783, 51735 40786, 51736 40790, 51739 40788, 51743 41788, 51741 41787, 51741 41789, 51741 41789, 51738 41793, 51733 41793, 52733 41794, 52737 41795, 52740 41794, 52744 41793, 52748 41789, 52749 41789, 52747 41789, 52752 41786, 52755 41790, 52755 41791, 52760 41796, 52756 42796, 52751 42797, 52754 42798, 52758 42795, 52759 42794, 52764 42797, 52768 42801, 52768 42801, 52771 42806, 52776 42810, 52776 42809, 52773 42811, 52776 42811, 52772 42812, 52773 42815, 52769 42815, 52768 42816, 52769 42821, 52773 42821, 52773 42821, 52777 42819, 52781 42815, 52781 42816, 52782 42819, 52778 42822, 52776 42822, 52779 42826, 52782 42827, 52783 42831, 52778 42833, 52782 42836, 54782 42839, 54782 42844, 2137 11205, 2142 11207, 2139 11208, 2142 11213, 2144 11217, 2149 11215, 2147 11217, 2147 11217, 2152 11222, 2152 11225, 2155 11229, 2159 13229, 2164 13232, 2169 13235, 2173 13236, 2169 13233, 2170 13237, 2173 13241, 2175 13243, 2170 13238, 2170 13239, 2175 13239, 2177 13238, 2179 13239, 2179 13238, 2181 13233, 2181 13230, 2182 13230, 2179 13230, 2179 13235, 2182 13235, 2183 10235, 2178 10237, 2179 10236, 2182 10239, 2187 10241, 2184 10244, 6184 10244, 6186 10248, 6184 10246, 6185 10247, 6187 10250, 6192 10248, 6196 10248, 6196 10251, 6194 10251, 6194 10256, 6197 10260, 6196 10264, 6197 9264, 6197 9264, 6197 9268, 6201 9273, 6206 9276, 6201 9272, 6203 9272, 6205 9269, 6210 9272, 6206 9274, 6206 9279, 6203 9283, 6203 9285, 6203 9290, 6208 9285, 6208 9281, 6204 9285, 6202 9289, 6204 9292, 6200 9294, 7200 9297, 7202 9301, 7203 9301, 7207 9302, 7211 9302, 7211 9303, 8211 9306, 8216 10306, 8220 10310, 8224 10312, 8228 10317, 8233 10317, 8237 10322, 8239 10322, 8239 10327, 8235 10330, 8235 10331, 8239 10329, 8240 10332, 8240 10334, 8236 10334, 11236 10336, 11238 10337, 11243 10341, 14243 10342, 14242 10342, 14239 10343, 14240 10341, 14239 10343, 14244 10343, 14248 10343, 14252 10343, 14252 10343, 14253 10341, 14256 10341, 14258 10338, 14258 10336, 14254 10340, 14257 10344, 14261 10346, 14264 10351, 11150 3163, 11155 3167, 11156 3166, 11156 3169, 11160 3171, 11163 3176, 11164 3179, 11164 3180, 11168 3183, 11168 3185, 11173 3189, 11178 3184, 11180 3183, 11178 3185, 11181 3187, 11176 3186, 52778 42822, 52780 42826, 52779 42826, 52784 42821, 52785 42826, 52786 42827, 52791 42830, 52791 42827, 56791 42832, 56788 42833, 56788 42836, 56791 42840, 56791 42839, 56787 42842, 56788 42847, 51788 42848, 51790 42850, 51792 42851, 51796 42846, 51798 42846, 51803 42850, 53803 42853, 53808 42853, 53811 42856, 53814 42854, 53819 42850, 53819 42852, 53820 42857, 53824 42860, 53825 42858, 53828 42862, 53827 42864, 53828 42864, 53828 42868, 53832 42872, 53837 42877, 53841 42877, 53843 42876, 53843 42880, 53843 42883, 53843 42888, 53838 42892, 53838 42893, 53838 44893, 53835 44893, 53837 44897, 53840 44901, 53844 44901, 53846 44904, 53846 44908, 53847 44909, 53852 44907, 53855 44908, 53860 44910, 53858 44911, 53863 44913, 53858 44917, 53860 44920, 53865 44920, 53870 44922, 53869 43922, 53871 43925, 53871 43923, 53869 43923, 53864 43922, 53862 43927, 53866 43932, 53871 43934, 53876 43937, 53876 43936, 53876 43936, 53877 43934, 53879 43932, 53880 43928, 53885 43931, 55885 43933, 55885 43929, 55881 43933, 55883 43933, 55886 43932, 55883 43932, 55884 43933, 55885 45933, 55885 45937, 55885 45940, 55886 45945, 55886 45945, 55888 45950, 55884 45952, 55885 45956, 55890 45960, 55892 45961, 55896 45957, 55894 45958, 55899 45954, 55895 45958, 55898 45960, 55894 45959, 55899 45963, 55901 45965, 55901 45965, 55896 45966, 55900 45961, 55895 49961, 55898 47961, 55896 47960, 55900 47964, 55903 47968, 55903 47971, 55903 47974, 55898 47977, 55900 47973, 55896 47978, 55897 47979, 55893 47980, 55898 47983, 55901 47988, 55904 47987, 55899 47991, 55901 47993, 55906 47996, 55906 47997, 55907 48001, 55904 48005, 55904 48007, 55909 48004, 55912 48002, 55917 48003, 55913 47998, 55908 48002, 55912 48007, 55916 48004, 55920 48004, 55916 48004, 55921 48004, 55923 48007, 55923 48011, 55926 48011, 55921 48014, 55924 48009, 55929 48013, 55930 48012, 55930 48012, 55932 48016, 55927 48016, 55927 48020, 54927 48018, 54924 48022, 54924 44022, 54928 44017, 54931 44016, 54934 44020, 55934 44021, 55937 44021, 55938 44024, 55939 44026, 55938 44024, 55941 44019, 55946 44022, 55947 44026, 55949 44027, 55952 44028, 55955 44024, 55958 44027, 53869 43923, 53873 43925, 52873 43925, 53873 43927, 53878 43927, 53883 43927, 53882 43931, 53884 43935, 53888 43940, 53886 43941, 53881 43938, 53881 43941, 53879 43943, 53880 43942, 53881 43946, 53882 43951, 53883 43952, 53886 45952, 53886 45953, 53884 45957, 53885 45958, 53880 45960, 53882 45957, 53887 45962, 53887 45962, 53888 45961, 53888 48961, 53888 48966, 53893 48966, 53894 48968, 53899 48969, 49899 48966, 49904 48969, 49908 48971, 49904 48971, 49906 48975, 49903 48971, 49906 48974, 54906 48975, 54906 48975, 54906 48979, 54911 48983, 54909 48979, 54912 48979, 54908 48975, 54911 48977, 54913 48979, 54917 48982, 54922 48982, 54925 48985, 54920 48988, 54923 48988, 56923 48988, 56928 48990, 56926 48985, 56931 48984, 56934 48983, 56934 48981, 56938 48983, 56939 48985, 56939 48986, 61939 48988, 61939 48984, 61936 51984, 61937 51985, 61937 51988, 61937 51988, 61933 51990, 5331 23399, 5333 23399, 5335 23394, 5339 23396, 5342 23399, 5347 27399, 5347 27401, 5352 27402, 5357 27403, 5358 27406, 6358 27409, 6362 27411, 6363 27410, 6366 27406, 6368 26406, 6373 26406, 6373 26406, 6374 26409, 6372 26409, 6377 26410, 6382 26415, 6387 26417, 6389 26418, 6390 26423, 6392 26423, 6393 26428, 6395 30428, 6392 30433, 6392 30436, 6392 30434, 6396 30438, 6396 30441, 6396 30445, 6398 30446, 6400 30443, 6401 30440, 6406 30439, 6407 30439, 6402 30439, 6407 30444, 6406 30447, 6407 30451, 6411 30451, 6413 30451, 6414 30452, 6419 30450, 6423 30454, 6420 30452, 6419 30448, 6420 30453, 6422 30455, 6427 30460, 6428 30460, 6427 30462, 6428 30462, 6428 34462, 6429 34463, 6434 39463, 6436 39466, 6436 39471, 6441 39474, 6445 39471, 6446 39472, 6451 39477, 6453 39480, 6454 39485, 6454 39483, 6454 39480, 8454 39480, 8458 39482, 8462 39484, 10462 39486, 10457 39486, 10458 39488, 10462 39488, 10465 39488, 10470 39490, 10475 39486, 10477 39488, 10477 39490, 10478 39492, 10479 39496, 10477 39498, 10482 39503, 10478 39505, 10481 39510, 10482 39514, 10477 39512, 10482 39517, 10483 39520, 10483 39520, 10487 39525, 10489 39526, 10492 39527, 10492 39524, 10495 39524, 10498 44524, 10493 44523, 10493 44528, 10494 44524, 10499 44529, 10501 44529, 10504 44531, 10502 44535, 10504 44539, 10508 44539, 10513 44536, 13513 44540, 13515 44537, 13512 44539, 13509 44544, 13513 44547, 13517 44552, 13519 44553, 13524 44554, 13527 42554, 13522 42555, 13524 42557, 13527 42556, 13531 42561, 13531 42562, 13526 42563, 13527 42563, 13527 42566, 13522 42568, 13525 42571, 15525 42573, 15525 42576, 15526 42581, 15531 42581, 15532 42586, 15534 42588, 15534 42592, 15533 42591, 15533 42596, 15532 42591, 15532 42587, 15535 42587, 15538 47587, 15534 47587, 15537 47591, 15536 47594, 15538 47598, 11538 47594, 11535 47594, 11531 47594, 11535 47596, 11535 47596, 11535 47597, 11539 47602, 11540 47607, 11540 47607, 11540 47609, 11543 47613, 11546 47617, 14546 47618, 14541 47614, 14539 47614, 14539 47618, 14537 50618, 14539 50623, 14541 50623, 14542 50627, 14540 50627, 14539 50623, 25601 26544, 25601 26545, 25601 26548, 25596 26546, 25601 26547, 25598 26548, 25599 26547, 25600 26547, 25595 26548, 25590 26546, 25595 26549, 25597 26548, 25598 26548, 25601 26545, 25596 26548, 25594 26553, 25595 26552, 25599 26553, 25598 26554, 25596 26555, 25592 26554, 25596 26558, 25599 26554, 25600 26556, 25595 26559, 25600 22559, 25601 22561, 25606 22563, 25607 22562, 25608 22566, 25607 22563, 25607 22568, 30607 22573, 30612 22575, 30612 22579, 30611 22579, 30611 22580, 30611 22585, 30607 22585, 30612 22587, 30612 22588, 30615 22583, 30615 22585, 30618 22581, 30621 22581, 30623 22584, 30623 22589, 30628 22594, 30630 22597, 30631 22602, 30628 22607, 30630 22610, 30631 22611, 30631 22608, 30629 22610, 30634 22612, 30635 22612, 30638 22616, 30643 17616, 30644 17618, 30649 17618, 30653 17619, 30656 17614, 30657 17611, 30660 17615, 30655 17614, 30656 17610, 30656 17611, 30661 17610, 30662 17615, 30660 17620, 30661 17620, 30666 17623, 30667 17625, 30667 17624, 30669 17625, 30673 17628, 30675 17628, 30675 17628, 30680 17631, 30677 17636, 30677 17639, 30680 17644, 30683 17647, 30688 17643, 30693 17645, 30698 19645, 30701 19644, 30702 19644, 30698 19649, 30700 19647, 30701 19649, 30704 19650, 30705 19653, 30701 19655, 30706 19652, 30708 19656, 30711 19657, 30711 19659, 30711 19659, 30714 19661, 30710 19662, 30707 19664, 30702 19666, 30703 19667, 30708 19668, 30713 19667, 30709 19671, 30706 19674, 30710 19676, 30711 19677, 30713 19677, 30713 19678, 30715 19682, 30720 19686, 30725 20686, 30723 20690, 30727 20695, 30728 20697, 30731 20699, 30730 20694, 30732 20696, 30735 20698, 30738 20696, 30738 20695, 30742 20698, 30743 20699, 30743 20701, 30748 20704, 30749 20706, 30752 20705, 30753 20702, 30755 24702, 30751 24705, 30750 24707, 30748 24708, 30749 29708, 30749 29709, 30751 29711, 30754 29716, 30759 29716, 30762 34716, 30762 34720, 30765 34720, 30761 34717, 30761 34721, 30765 34721, 30760 34721, 30759 34725, 30762 34730, 30760 34730, 30765 34731, 30765 34731, 30766 34731, 30761 34733, 30761 34736, 30764 34738, 30759 34739, 30763 34740, 30761 34740, 30764 34742, 30759 34737, 30762 34739, 30764 34741, 30762 34740, 30767 34737, 32767 34741, 32770 34741, 32767 34744, 32767 34746, 32770 34751, 32774 34755, 32774 34756, 32779 34753, 32784 34755, 32785 33755, 32785 33750, 36785 33753, 36785 33758, 36788 33760, 36789 33759, 36789 33762, 36793 33758, 36798 33758, 36803 33760, 36803 33762, 36803 33766, 36804 33769, 36804 33769, 36808 33774, 33808 33776, 33808 33781, 33811 33781, 33816 33784, 33816 33789, 33820 33786, 33823 33788, 33828 33785, 33824 33785, 33826 33787, 33824 33788, 33828 33791, 33825 33796, 33829 33799, 33830 33802, 33831 33803, 33835 33805, 33835 33805, 33838 33809, 33841 33813, 33844 33809, 33849 33814, 33847 32814, 33849 32812, 33851 32816, 33853 32819, 33851 32822, 33851 32826, 33849 32826, 33849 32830, 33852 32835, 33856 32840, 33859 32837, 33858 32832, 33861 32833, 33862 32836, 33859 32838, 33859 32834, 33857 32834, 33859 32834, 33857 32838, 33861 32833, 33861 32837, 33864 32840, 33866 32841, 33866 32843, 33868 32841, 33871 32839, 33874 32844, 33876 37844, 33881 37849, 33883 37854, 33883 37859, 33888 37860, 33893 37864, 33898 37864, 33895 37867, 33896 38867, 33898 38863, 28898 38868, 28901 39868, 33901 39873, 33898 39875, 33900 39879, 33904 39877, 33904 39879, 33909 39883, 33914 39888, 33910 39891, 33910 39892, 33907 39894, 33911 39899, 33913 39900, 33910 39904, 33914 39905, 33917 39906, 33917 39906, 33917 39906, 33912 39911, 33912 39908, 33916 39907, 33914 39910, 33918 39913, 33922 39913, 33924 39916, 33925 39920, 33930 39920, 33933 39922, 33934 39923, 33937 39919, 33938 39916, 33936 39913, 35936 39918, 35933 39919, 35937 39921, 35941 39924, 35941 39919, 35942 39915, 35946 39920, 35946 39915, 35946 39912, 35947 39908, 35947 39912, 35947 39916, 35952 39919, 35957 39921, 38957 39920, 38962 39925, 38964 39924, 38964 39924, 38969 39926, 38969 39928, 38972 39932, 38977 39932, 38975 39932, 38979 39935, 38982 39938, 38986 39940, 38984 39943, 38985 39946, 38987 39947, 38989 39949, 38994 41949, 38990 41954, 38991 41958, 38994 41962, 38994 41966, 38994 41969, 38995 41974, 38999 41974, 38999 41974, 38996 41978, 38996 41983, 38999 41983, 39001 41986, 38996 41984, 39000 41989, 39000 41988, 5336 23410, 5332 23410, 5327 23407, 9327 23408, 12327 23412, 12327 23412, 12324 23410, 13324 23415, 13327 23420, 13328 23416, 13324 23418, 13329 23423, 13330 23426, 13331 23429, 13335 23426, 13339 23428, 23493 35553, 23492 35548, 23496 35550, 23501 35552, 23497 35553, 21497 35557, 21492 35560, 21494 35562, 21494 35560, 21496 35563, 21496 35568, 21496 35570, 21501 35570, 21504 35566, 21504 35571, 17504 35572, 17508 35577, 17509 35578, 17513 35582, 17514 35587, 17515 35592, 18515 35595, 18516 35596, 18517 35598, 18515 35600, 16515 35605, 16515 37605, 16515 37606, 16513 37608, 16515 37613, 16516 37615, 16520 37620, 16524 34620, 16526 34617, 16530 34619, 16530 34624, 16535 34628, 16537 34631, 16540 34632, 16541 34634, 16541 34635, 16544 34632, 16544 34637, 16546 34642, 16549 38642, 16549 38644, 16545 38649, 16545 38644, 16542 38644, 16545 38644, 16544 38645, 16548 38650, 16543 38653, 16543 38649, 18543 38652, 18546 38652, 18546 38657, 18546 38660, 18551 38655, 18549 38655, 18552 38660, 18549 38662, 23549 38667, 23546 38668, 23550 38672, 23550 38674, 28550 38676, 28551 38673, 28551 38677, 28547 38673, 28551 38674, 28556 38674, 28559 38678, 28562 38673, 28564 38678, 28564 38673, 28563 38673, 28566 38675, 28571 38675, 38781 44703, 38782 44699, 38780 44702, 38785 44704, 38787 44704, 38783 44705, 38784 44700, 38788 44695, 38791 44696, 38796 44696, 38801 44692, 38801 44697, 38805 44701, 38810 44701, 38808 44701, 38808 44704, 38805 44706, 38805 44710, 38804 44711, 38809 48711, 38810 48711, 38808 48711, 38812 48716, 38812 48713, 38812 48715, 38812 48715, 38808 48711, 38804 48714, 38805 48710, 38807 48715, 38812 48715, 38807 48713, 38811 48714, 38811 48714, 38816 48711, 38817 48707, 38818 48707, 38818 48708, 38822 48708, 38824 48713, 38822 48714, 38820 48718, 38824 48720, 38824 48723, 38829 48726, 38830 48731, 38834 48729, 38832 48734, 38833 48730, 38834 48728, 38831 48732, 8433 35536, 8433 35541, 4433 35536, 4436 35541, 4440 35541, 4441 35537, 4445 35539, 4444 35534, 4447 35531, 4451 35531, 4455 35534, 4460 35534, 4461 39534, 4462 39535, 4463 39535, 4466 39535, 4470 39535, 4472 39538, 4467 39538, 4467 39536, 4471 39536, 4473 39541, 4468 39542, 4472 39543, 4475 39544, 4478 39544, 4482 39547, 4487 39552, 4485 39550, 4486 39551, 4486 39553, 4486 39555, 4488 39557, 4488 39558, 4489 39555, 4485 39557, 4488 39558, 4492 39560, 4495 39561, 4500 39565, 4496 39566, -4747 22349, -4750 22349, -4746 22352, -4742 22355, -4738 22360, -4739 22362, -4737 22365, -4732 22363, -4728 25363, -4728 25364, -4723 25364, -4725 25364, -4725 25365, -6725 25364, -6727 25369, -6728 25369, -6725 25369, -6729 25368, -6728 27368, -6725 27370, -6721 27371, -3721 27367, -3717 27372, -3718 27375, -3716 27370, -3715 27373, -3714 27373, -3712 27376, -3709 27374, -3710 27375, -3710 27374, -3708 27379, -3706 27381, -3705 27386, -3704 27389, -3704 27393, -3703 32393, -3702 32396, -3702 32396, -3697 32395, -3697 32399, -3692 32403, -3692 32404, -3693 32408, -3693 32412, -3691 32414, -3691 32414, -3695 32414, -3690 32417, -3689 32422, -3684 32424, -3681 32429, -3679 32424, -3676 32428, -3671 32428, -3674 32431, -3671 32430, -3669 32430, -3674 33430, -3676 33432, -3674 33432, -3677 33432, -3677 33437, -3675 33438, -3674 33442, -3679 33444, 1321 33448, 1323 33445, 1327 33448, 1331 33443, 1328 33448, 1328 33443, 1329 33443, 1329 33444, 1334 33448, 1335 33453, 1340 33457, 1340 33454, 1345 33454, 1349 33458, 1348 33461, 1348 33459, 1344 33463, 1343 33466, 1348 33466, 1349 33467, 1345 33467, 1346 33466, 1350 33461, 1349 33464, 1354 33468, 1358 33472, 1363 33473, 1365 33472, 1367 33473, 1370 33476, 1371 33479, -2629 33482, -2631 33487, -2627 33490, -2630 34490, -2626 36490, -2623 36492, -2619 36492, -2622 36492, -2620 36496, -2622 36495, -2627 36495, -2625 36500, -2621 36503, -2626 36506, -2629 36510, -2624 36510, -2620 36510, -2620 36513, -2617 36518, -2622 36516, -2619 36514, -2617 36514, -2617 36512, -2615 36516, -2613 36516, -2613 36517, -2613 36515, -2613 36510, -2610 36511, -2607 36515, -2604 37515, -2604 37512, -2608 37509, -2605 37512, -2600 37516, -2597 37516, -2593 37514, -2595 37515, -2590 37519, -2595 37518, -2590 37523, -2590 37528, -2590 37530, -2592 37525, -2592 37520, -2589 36520, -2586 36521, -2587 36517, -2584 36518, -2582 36518, -2581 36520, -2577 36518, -2576 36522, -2576 35522, -2573 35523, -2575 35523, -2576 35528, -2576 35533, -2576 35536, -2576 35538, -2578 35541, -2582 35545, -2584 35546, -2585 35548, -2583 35544, -2583 35548, -2582 35547, -2578 35552, -2574 35554, -2569 35557, -2565 35559, -2563 35564, -2558 35564, -2555 35568, -2551 35568, -5551 36568, -5546 36568, -5542 36569, -5545 36569, -5543 36574, -5540 36569, -5541 36570, -5541 36572, -5541 36574, -5538 36579, -5535 36581, -5533 36585, -5530 36584, -5526 36579, -5524 38579, -5524 38580, -5524 38575, -5520 38575, -5516 38580, -5512 42580, -5508 42585, -5510 42587, -5510 42586, -5505 42586, -5508 42589, -2508 42593, -2509 42596, -2506 42598, -2504 42601, -2501 42602, -2501 42607, -2496 42612, -2499 42615, -2498 42620, -2500 42617, -2500 42620, -4500 42620, -4500 42624, -4500 42626, -4504 42623, -4507 42625, -4509 42628, -4513 42629, -4508 42629, -4505 42632, -4500 42628, -4499 42633, -4503 45633, -4501 45634, -4497 45635, -4494 45634, -4495 45632, -4493 45634, -4492 46634, -4489 46638, -4485 46633, -4481 46635, 21338 40536, 21343 40537, 21348 40538, 21348 40540, 21347 40540, 21348 40540, 21347 40540, 21346 40542, 21349 40547, 21350 40547, 21353 40544, 21353 40546, 21350 40549, 21353 40550, 21354 40550, 21355 40550, 21360 40550, 21361 40549, 21361 40554, 21359 40559, 21364 40564, 21366 40559, 21365 40559, 21366 40564, 25366 40568, 25367 40570, 25370 40570, 25373 45570, 25374 45571, 25374 45566, 25378 45568, 25383 42568, 25387 42564, 25391 42568, 25391 42572, 25395 42576, 25392 42576, 28392 42573, 28391 42574, 28387 42578, 28388 42580, 28391 42581, 31391 42582, 31387 42586, 31389 42586, 31392 42582, 31393 42583, 31394 42580, 29394 42584, 29398 42586, 29400 43586, 29404 43588, 29408 43589, 29409 43591, 29413 43596, 29415 43598, 29416 43599, 25416 43604, 25414 43599, 25417 43603, 25422 43606, 25420 43608, 25425 43603, 25428 43603, 25431 43606, 25436 42606, 25431 42608, 25434 42604, 25437 42609, 25438 47609, 25442 50609, 25443 50614, 25441 50618, 25446 50621, 25449 50625, 25446 50628, 25446 50630, 25447 50631, 25452 50636, 25452 50632, 25453 50634, 25453 50636, 25456 50637, 25460 50641, 25464 50645, 25465 50644, 25465 51644, 25469 51648, 25471 51653, 25475 51654, 25476 51657, 25477 51658, 26477 51662, 26477 51666, 26476 51669, 26478 51669, 26483 51665, 26485 55665, 26487 55668, 30487 55671, 30487 55674, 30491 55675, 30491 55672, 30493 55674, 30494 55674, 30495 55679, 30499 55679, 30503 55675, 30505 55680, 30502 55681, 30500 55676, 30496 55679, 30501 55680, 30502 55680, 30507 55685, 30503 55688, 30498 55689, 30502 55689, 30504 55691, 30508 55696, 30509 55697, 30508 55696, 30513 55697, 30518 55698, 30516 55703, 30516 55705, 30514 55705, 34514 55709, 34518 55712, 34522 55708, 34520 56708, 34521 56708, 34522 56710, 34519 56710, 34517 56705, 34521 59705, 34524 59710, 34524 59712, 34524 59717, 34528 59719, 34530 59721, 34535 59716, 34540 59719, 34540 59721, 34543 59721, 34548 59724, 34550 59725, 34554 63725, 34549 63730, 34551 63732, 34556 63730, 34558 63730, 34559 63725, 34558 63729, 34563 63734, 34560 63734, 37560 63729, 37563 63733, 37567 63728, 37571 63724, 37575 63722, 37580 63726, 37579 63722, 37581 63724, 37581 63726, 37582 63723, 37582 63724, 37581 63728, 37576 63729, 37576 63731, 37578 63729, 37583 63733, 37585 63736, 37588 63736, 37592 63741, 37594 63738, 37599 63735, 37602 63734, 37598 63735, 37598 63737, 37602 63737, 37603 63739, 37598 63739, 37593 63736, 37598 63737, 37603 63742, 37604 63737, 37601 63742, 37596 63744, 37600 63748, 37605 63749, 37607 63751, 37609 63756, 37609 63760, 37605 63761, 37605 63765, 37606 63765, 37610 63762, 37611 63766, 37606 63768, 37606 63768, 41606 63769, 41602 63765, 41601 63765, 41602 63770, 41598 63770, 41601 63770, 41603 63774, 41606 63772, 41610 63772, 41613 63776, 41616 63771, 41611 63767, 41614 63769, 41617 63764, 38617 63768, 38617 63772, 38620 63772, 35620 63773, 35620 63778, 35619 63779, 35620 63780, 35615 63779, 35617 63784, 35614 63786, 35615 63783, 35616 63779, 35620 63778, 35621 63780, 35626 63782, 35626 63784, 35631 63789, 35631 63784, 35628 63785, 35626 63786, 35631 63788, 35636 63791, 35640 63786, 35636 63787, 35636 63782, 35635 63781, 35640 63786, 35643 63790, 35646 63795, 35650 63797, 35649 63797, 35651 63801, 35655 63805, 35656 63808, 35656 63808, 35658 63808, 35657 63810, 35660 63814, 35660 63809, 35664 63809, 35659 67809, 35660 67812, 35662 67815, 35666 67812, 35662 67807, 35660 67807, 35663 67807, 35665 67812, 35668 67814, 35672 67818, 35671 67817, 35671 67820, 37671 67824, 37666 67824, 2277 13367, 2280 16367, 2276 16367, 2277 16366, 2281 16366, 2284 16366, 2289 16370, 2286 16370, 4286 16370, 4288 16375, 4292 16379, 4296 18379, 4297 18381, 9297 18385, 9298 18385, 9301 18386, 9305 18383, 9307 19383, 9310 19379, 8310 19384, 8314 19384, 38748 37655, 38751 37656, 38756 37657, 38759 37660, 38755 37665, 38755 37665, 38760 37667, 38765 37668, 38765 42668, 38770 42670, 38767 42672, 38772 42668, 38769 42663, 38770 42663, 38775 42658, 38773 42663, 38777 42665, 41777 42667, 41780 42669, 41783 42673, 41784 42671, 41781 42673, 41786 42676, 41783 42676, 41785 42676, 41782 42676, 41785 42679, 41786 42679, 41790 42680, 41794 42681, 41794 42679, 41795 42684, 41795 42680, 41798 42685, 41803 42689, 41806 42688, 41808 42689, 41806 42694, 41804 42696, 41807 42700, 41802 42701, 41804 42702, 41806 42704, 41811 42708, 41815 42709, 36815 42712, 36815 42708, 36812 42707, 36813 42709, 40813 42710, 40817 46710, 40818 46712, 40822 46712, 40820 46716, 40824 46721, 40827 46724, 40831 46728, 40829 46731, 40833 46731, 40835 46735, 40831 46737, 40832 46737, 36832 46742, 36832 46745, 36836 46748, 36833 46753, 36828 46752, 36824 46752, 36826 46755, 36821 46759, 36825 46762, 36825 46766, 36826 46770, 36824 46773, 36828 46776, 36833 46778, 36830 42778, 36835 42780, 36835 42781, 36840 42786)')));
-BEGIN;
-DELETE FROM t1 WHERE p = 3;
-UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
-UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
-ROLLBACK;
-connection con1;
-# disable purge
-CREATE TABLE t0 (a INT) ENGINE=InnoDB;
-BEGIN;
-SELECT * FROM t0;
-a
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
DELETE FROM t1 WHERE p = 3;
UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
-connection con1;
+connection control_purge;
# enable purge
COMMIT;
connection default;
DELETE FROM t1 WHERE p = 2;
-# wait for purge to process the update_undo records.
+InnoDB 0 transactions not purged
CREATE TABLE t2 (
p INT PRIMARY KEY,
g1 POINT NOT NULL,
@@ -193,15 +44,13 @@ SPATIAL KEY (g3),
SPATIAL KEY (g4),
SPATIAL KEY (g5),
SPATIAL KEY (g6)
-) ENGINE=InnoDB ROW_FORMAT=COMPACT;
-DROP TABLE t2;
-DROP TABLE t1;
-DROP TABLE t0;
+) ENGINE=InnoDB;
+DROP TABLE t1,t2;
CREATE TABLE t1 (
p INT NOT NULL AUTO_INCREMENT,
g LINESTRING NOT NULL,
PRIMARY KEY(p)
-) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+) ENGINE=InnoDB;
ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
INSERT INTO t1(g) VALUES(ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)'));
INSERT INTO t1(g) VALUES(ST_linefromtext(concat('linestring','(18 106,19 106,24 111,27 108,32 104,37 107,42 107,44 112,44 116,40 118,43 114,46 114,42 118,44 123,45 123,49 123,53 119,50 123,50 124,54 126,58 125,59 126,64 127,65 127,69 131,74 132,75 135,78 139,2078 141,2075 143,2077 143,2079 143,2084 143,2085 147,2090 -1853,2086 -1852,2086 -1856,2089 -1852,2093 -1850,2090 -1851,2090 -1852,2091 -1851,2092 -1850,2097 -1847,2102 -1848,2100 -1852,2100 -1852,7100 -1851,7103 -1850,7104 -1847,7109 -1842,65 127,67 131,66 131,61 132,61 133,62 137,65 1137,2065 1135,2061 1135,2064 1135,5064 1135,5066 1135,5070 1136,5070 1141,5071 1138,5074 1141,5075 1141,5074 1137,5076 1137,5071 1139,5066 1142,5065 2142,5068 2147,5073 2151,5069 2156,5071 2157,5072 2162,5074 2165,5069 2169,5072 2169,5076 2173,5074 2169,5078 2169,5076 2170,76 2175,74 2179,75 2184,80 2188,83 2190,87 2189,84 2193,87 2189,86 2190,87 2195,87 2200,87 1200,85 1202,86 1199,87 1200,87 1201,91 1206,92 1204,94 1204,98 1206,102 1208,105 1211,102 1216,105 1220,109 1224,110 1224,114 1225,117 1224,118 1229,117 1232,122 1237,123 1236,120 1235,124 1237,121 1236,122 1240,126 1244,127 1246,126 1249,125 5249,123 5251,127 5251,131 5251,135 5256,138 5257,135 5257,139 5257,138 5258,141 5260,146 5260,146 5260,143 10260,147 10265,151 10270,156 10266,157 10269,162 10273,166 12273,168 12274,163 12270,168 12275,170 12277,170 12277,-3830 12277,-3825 12277,-3824 12278,-3825 12276,-3825 12278,-3822 12277,-3825 12275,-3829 12278,-3828 12275,-3824 12280,-3827 12280,-3826 12282,-3822 12283,-3822 12286,-3820 12288,-3818 12289,-3816 12294,-3817 12297,-3819 12300,-3816 12297,-3813 12295,-3811 12299,-3811 12297,-3806 12298,-3806 12298,-3804 12301,-3801 12306,-3803 17306,-3803 17306,-3798 17306,-3803 17310,-3801 17314,-3798 17317,-3797 17317,-797 17321,-797 17323,-796 17325,-793 17326,-792 17322,-789 17327,-784 17331,-780 17335,-776 17339,-774 17339,-771 17342,-770 17345,-765 17348,-765 17349,-763 17353,-760 17350,-760 22350,-756 22346,-752 22349,-748 22352,-752 22348,-748 22347,-746 22345,-745 27345,-743 27346,257 27350,260 27349,261 27352,266 27348,266 22348,269 22347,271 22347,272 22347,273 22348,273 22352,278 22348,279 22344,282 22345,282 22342,283 22347,283 22347,288 22349,292 22347,292 22348,293 22348,298 22348,303 22351,306 22352,309 22352,308 22354,310 22356,311 22361,311 22358,311 22360,311 22360,315 22356,320 22358,325 22363,326 22366,321 22371,318 22373,318 22375,314 22375,316 22375,321 22376,321 22376,322 22372,32 104,36 109,40 114,40 113,40 117,44 119,49 123,49 126,49 129,53 133,50 137,50 139,49 137,48 138,43 138,42 139,46 142,46 138,41 139,45 141,4045 5141,4045 5146,4042 5147,4043 10147,4041 10150,4042 10152,4045 10152,4041 10156,4041 10152,4041 10152,4046 10153,4049 10156,4046 10155,4051 10157,4055 10159,4055 10160,4056 10161,4055 10166,4054 10169,4054 10172,4054 15172,4051 15176,4047 15177,4049 15174,4047 15176,4047 15176,4046 15177,4046 15180,4043 15184,4043 15187,4038 15190,4040 15194,4040 15199,4045 15196,4047 15197,4050 15200,4050 15204,4050 15208,4047 15212,4047 15215,4049 15216,4046 15218,4042 15223,4042 15228,4042 15232,4047 15235,4050 15236,4050 15239,4051 15243,4053 15243,4050 17243,4052 17243,4052 18243,4057 18247,4061 18249,4064 18249,4067 20249,4067 20250,4067 20255,4066 20259,4066 20259,4067 20255,4069 20256,4071 20258,4072 20254,4067 20257,4067 20260,4069 20265,4065 20267,4069 20266,4070 20267,4071 20264,4074 20259,4070 20264,4073 20260,4074 20263,4077 20268,4082 20271,4084 20273,4084 20277,4081 18277,4085 18279,4086 18276,4087 18273,4087 18275,4092 18277,4093 18279,4093 18280,4095 18280,4091 18283,4092 18281,4094 18283,4090 18287,4094 18287,138 5257,138 5255,138 5258,-1862 5254,-1860 5256,-1856 5258,-1851 5255,-1850 5260,-1847 5260,-1847 5263,-1847 5258,-1850 5257,-1850 5259,-1851 5257,-1855 5258,-1853 5261,-1849 5261,-1849 5258,-1849 5259,-1845 5264,-1847 5264,-1850 5268,-1852 5266,-1853 5270,-1856 5265,-1852 5262,-1847 5263,-1842 5263,-1842 5260,-1842 5265,-1841 5265,-1844 5265,-1842 5270,-1837 5274,-1838 5279,-1843 5275,-1842 5280,-1838 5281,-1838 5285,-1833 5285,-1828 5288,-1824 5289,-1828 5291,-1831 5291,-1826 5291,-1830 5293,-1826 5296,-1822 5301,-1826 5302,-1826 5302,-1826 5302,-1825 5297,-1820 5299,-1816 5303,-1816 5299,-3811 12299,-3809 12302,-3806 12302,-3806 12302,-3803 12304,-3798 12304,-3797 12304,-3793 12306,-3788 12306,-3783 12309,-3816 12294,-3811 12299,-3809 12297,7100 -1851,7098 -1854,7102 -1854,7107 -1856,7107 -1858,7110 -1854,7110 -1851,7113 -1851,7115 -1851,7120 -1851,7123 -1847,7124 -1852,7125 -1852,7127 -1852,7131 -1852,7129 1148,7129 1145,7133 1150,7137 1148,7138 1147,7143 1149,7147 1154,8147 1155,8152 3155,8147 3157,8143 3158,8144 3160,8144 3164,11144 3167,11146 3167,11148 3163,11152 3161,11148 3159,11149 3163,11150 3161,11151 3166,11154 3171,11154 3170,8144 3160,8144 3163,8144 3166,8145 3166,8146 3171,8146 3174,8144 3174,8144 3174,8145 3176,8141 3180,3141 3182,7141 3183,7141 7183,7136 7185,7136 7185,7133 7187,7136 7187,7131 7190,7136 7194,7137 7197,7141 7196,7139 7199,12139 7200,12143 7200,12143 7199,12144 7203,12145 7200,12141 7200,12136 7195,12136 7191,12137 7191,12137 7196,12139 7197,12140 7197,12137 7201,12140 7204,12140 7209,12143 7209,12145 7210,12147 7214,12148 9214,12152 9218,12149 9218,12149 9221,12149 9220,12150 9222,12153 10222,12153 10226,12156 10227,12159 10223,12160 10220,12161 10225,12161 10227,12163 10224,12163 10223,12158 10224,12158 10227,12158 10231,12155 12231,12157 12226,7136 7185,7139 7189,7139 7189,7139 7188,7137 7191,7139 7191,7140 7189,7143 7191,7144 7189,7144 7190,7149 7193,7152 7194,7154 7198,7153 7203,7148 7207,12148 7209,12146 7209,12145 7213,12140 7217,12139 7219,12141 7219,12138 7218,12143 7218,13143 7220,13140 7224,13142 7228,13137 7231,13142 7235,13146 7239,13149 7243,13148 7247,13150 7248,13155 7249,13155 7253,13155 7253,13155 7258,13157 7260,13162 7255,13159 7255,13163 7258,13164 7258,13164 7263,13167 7264,13167 8264,13165 8265,13169 8265,13171 13265,13175 13261,13176 13259,13176 13259,13180 13262,13181 13262,13183 13262,13188 13265,13191 13267,13191 13265,13194 13267,13191 13269,13192 13264,13196 13269,13198 13272,13200 13272,13202 13270,13207 11270,13211 11270,13211 11273,13213 11274,13217 11275,13222 11276,13222 11272,13226 11274,13231 11277,13233 11282,13236 11284,13238 11284,13236 11286,13236 11288,13236 11283,13236 11284,13238 11289,13241 11292,13244 11292,13245 11289,13241 11294,13244 11298,13249 11301,320 22358,324 24358,328 24358,327 24363,326 24359,327 24361,329 24365,334 24367,-666 24367,-670 24368,49 123,46 127,46 129,49 131,49 136,47 135,45 138,3045 135,3042 138,3044 139,3044 144,3049 144,3053 142,3055 137,3058 136,3053 139,3048 142,7048 138,7048 3138,7048 3139,7048 3140,7050 3145,7053 1145,7050 1146,7053 5146,7048 5150,7047 5146,10047 5147,10043 5147,10047 5147,10050 5152,10052 5155,10054 5156,10056 5157,10056 5159,10058 5162,10062 5164,10062 5169,10066 9169,10068 9168,10063 9164,10063 9169,10061 9171,14061 9172,14061 9174,282 22342,287 22347,288 22347,288 22343,285 22339,280 22338,278 22341,279 25341,284 25343,13241 11294,13246 11296,13243 11296,13244 11291,13245 11291,13244 11291,13246 11295,13251 11300,13253 11305,13253 11306,13258 11305,13255 11306,13256 11309,13256 11311,13261 11307,13265 11303,13267 11305,13270 11301,13275 11298,13271 11300,15271 11302,15276 11306,15279 11303,15284 11305,15286 11305,15289 11307,15290 11302,15292 11305,15296 11309,15297 11313,15298 11316,15300 11317,15304 11320,15306 11324,15306 11320,15307 11320,15312 11320,15313 11319,15317 11317,15315 11321,15317 11323,15317 11328,15319 11333,15322 11336,15322 11337,15322 11337,15324 11341,15324 11345,15325 14345,15328 13345,17328 13346,17333 13349,17337 13354,17338 13358,17342 13358,17346 13353,17348 13353,17345 13353,17348 13354,17347 13354,17347 13354,17347 13355,22347 13358,22349 13355,22351 13355,22356 13354,22358 13354,22361 13355,22362 13355,22358 13355,22359 13359,22364 13364,22369 13369,22372 13373,22376 13371,22377 13371,22377 13369,22381 13374,22386 13379,22387 13376,22387 13380,22392 13378,22390 13374,22392 13378,22391 13378,22391 13375,22392 13378,22390 13380,22393 13382,22398 13387,22398 10387,22402 10391,22399 10392,22400 10392,22400 10394,22404 10391,22403 15391,22405 15392,22407 15392,22412 15387,22412 15390,22412 15394,22408 15396,26408 15398,26407 20398,26411 20402,26415 20406,26417 20411,26420 20407,26422 20407,31422 16407,31421 16405,31421 16410,31423 16410,31426 16414,31426 16410,31430 16415,31430 16418,31435 16419,31437 16420,31438 16422,31438 16425,31438 16425,31441 16427,31439 16431,31441 16436,36441 16436,36443 18436,36442 18437,36440 18440,36440 18436,36440 18440,36442 18445,36443 18446,36447 18451,37447 23451,37452 23456,37456 23455,37458 23459,37456 23461,37458 23463,37460 23466,37464 23469,37460 23474,37462 23476,37461 26476,37466 26479,37470 26483,37471 26488,37474 26489,37474 26485,37474 26483,37474 26488,37470 26492,37474 26497,37474 26499,37478 26495,37483 26499,37483 26501,37488 26496,37491 26499,37495 26495,37500 26496,37500 26497,37500 26501,37497 26499,37497 26499,37495 26504,37498 26504,37494 26509,37497 26514,37495 26515,37498 26514,37503 26514,37508 26512,37510 26516,37511 26519,37509 26523,37506 26528,37507 26532,37512 26536,37513 26538,37510 26542,37512 26544,37517 26543,37522 26546,37527 26551,37525 26555,37529 26558,37524 26563,37524 26562,37527 26562,37522 26562,37522 26559,37526 26561,37522 26559,37523 26561,37523 26556,37524 26558,40524 26560,40524 26563,40521 26567,40525 26566,40527 26568,40532 26572,40534 26569,40533 26565,40531 26565,40535 26569,40535 26570,40539 26572,40544 26575,40543 26575,40544 26579,40548 26584,40549 26581,40553 26585,40556 26590,40552 22590,40557 22594,40556 22595,40561 22592,40561 22593,40565 22593,40568 22593,40573 22588,40570 22590,40570 22591,40570 22588,40573 22590,40573 22593,40568 22593,40567 22597,40567 22599,40571 22599,40574 22600,40574 22604,42574 22607,42577 22607,42577 22612,42579 22616,38579 22619,38580 22617,38580 22614,38575 22619,38579 22619,38579 18619,38582 18614,38582 18617,38586 18622,38590 18625,38590 18622,38594 18621,38596 18616,38597 18614,38597 18618,38600 21618,38601 21618,38605 21620,38607 25620,38611 25620,38608 25617,38608 25621,38608 25625,38611 25623,38615 25623,38615 25620,38616 25622,38619 25624,38620 25625,38620 26625,38623 26627,38623 26627,311 22358,311 22359,-1689 22360,2311 27360,2312 27360,2312 27360,2317 27362,2317 27362,2319 27359,2319 27364,2318 27359,2321 27364,2326 27367,2325 27371,2326 27373,2326 27373,2325 27377,2329 27377,2327 27377,2330 27379,2333 27379,2331 27379,2331 27381,2336 27381,6336 27382,6336 27383,40527 26568,40531 26572,40533 26574,40538 26576,40533 26580,40538 26585,40539 26588,40536 26583,40540 26587,40539 26588,40535 26593,40540 26594,40544 26597,40548 26602,40548 26601,40549 26602,40547 26602,40548 26603,40553 26606,40548 26606,40548 26603,40551 26608,40556 26612,40559 26616,40554 26619,40556 26619,40556 26623,42556 26623,42556 26624,42560 26624,42562 26626,42563 26630,42564 26630,42564 26634,42559 26635,42562 26635,42565 26637,42562 26638,42564 26642,42564 26641,42568 26641,42572 26641,42572 29641,42574 29642,39574 29641,39574 34641,39576 34643,39581 34638,39578 34638,39574 34642,39574 34645,39572 35645,34572 35648,34577 35651,39577 35655,43577 35659,43580 35655,43575 35658,43578 35658,43581 35662,43577 39662,43572 39658,43572 39661,43572 39664,43572 39666,43576 39670,43577 39667,43580 39671,43576 39673,43573 39673,43574 39677,43569 39679,43567 39679,43568 39683,43563 39686,43566 39690,43566 39692,43568 39694,43568 39695,41568 39691,41570 39692,41571 39692,41571 39693,41571 39698,41571 39698,41574 39698,41569 39698,41570 39699,41570 39704,41572 39709,41573 39712,41578 39713,41579 39717,41584 39719,41585 39720,-1850 5268,-1845 5268,-1847 5266,-1842 5268,-1840 5263,-1845 5264,-1843 5264,-1839 8264,-1839 8267,-1839 8272,-1838 8276,-1834 8273,-1834 8273,-1833 8274,-1837 8279,-1836 8283,-1834 8286,-1836 8282,-1834 8279,-1835 8279,-1834 8280,-1836 8283,-1841 8288,-1846 8289,-1843 8286,-1838 8286,-1841 8285,-1838 8285,-1834 8288,-1829 8291,-1825 8286,-1825 8289,-1825 8287,-1824 8291,-1822 8294,-1821 8298,-1818 8300,-1818 8296,-1814 8296,-1811 8295,-1808 8292,1192 8296,1192 8297,1195 11297,1192 11301,1195 11305,1197 11300,1193 11300,1193 11296,1193 11293,1194 11294,1199 11292,1204 11292,1205 11294,1210 11292,1208 11288,1204 11290,1205 11289,1207 8289,1202 8284,1204 8282,1204 8281,1206 8281,1208 8281,1212 8283,1212 13283,1213 13287,1213 13290,1216 13293,1214 13289,1217 13286,1212 13291,1208 13288,1208 13292,1209 13297,1208 13296,1204 13298,1205 13303,1209 13308,1204 13308,1209 13304,1210 13304,1214 13309,1214 13314,1215 13314,1219 13314,1219 13319,1224 13320,1229 13321,1232 13325,1233 13329,1231 13329,1234 13334,-2766 13336,-2769 13337,-2765 13340,-2762 13345,-2760 13342,2240 13342,2238 13342,2242 13342,2246 13345,2246 13346,2244 13348,2239 13348,2240 13351,2240 13352,2245 13357,2248 13357,2243 13362,2247 13362,2248 13362,2252 13363,2256 13363,2256 13363,2260 13367,2255 13372,2251 13369,2251 13369,2252 13372,2249 13376,2254 13378,2255 13382,2259 13379,2262 13379,2267 13381,2262 13381,2262 13383,2265 13383,2269 13385,2270 13386,2271 13389,2267 13391,2271 13386,2275 13391,2273 13392,2275 13387,2277 13390,2274 13390,2275 13394,2280 13395,2280 11395,2281 14395,2279 14400,2277 14403,2273 14406,2274 16406,2274 16410,2279 16410,2284 16411,2280 16409,2280 16409,2282 16409,2282 16411,2282 16412,2280 16413,3280 16418,3284 16418,3285 16423,3289 16423,3292 16427,3294 16429,3296 16431,3297 16436,3298 16435,3303 16435,3305 16434,3305 16436,3305 16436,3309 16437,3309 16438,3308 16439,3308 16439,3306 16444,3302 16441,-1698 16437,-1703 16438,-1699 16438,-1697 16438,-1698 16439,-1695 16436,-1690 16441,-1687 16446,-1683 16450,-1682 16451,-1684 16453,-1682 16457,-1682 16457,-1686 16460,-1681 16459,-1680 16456,-1677 16460,-1681 16461,-1679 16464,-1674 16465,-1673 16469,-1669 16471,-1669 16476,-1665 16474,-1665 16478,-1664 16478,-1664 16479,-1661 16474,-1656 16471,-1655 11471,-1660 11473,-1663 11475,-1666 11480,3334 15480,3338 15476,3342 15471,3345 15471,3345 15470,3350 15469,3347 15474,3351 15476,3352 15473,3353 15476,3350 15477,3350 15479,3351 15482,3352 15484,3351 15487,3353 15487,3358 15487,3353 15486,1217 13286,1222 13291,1222 13291,1225 13286,1229 13286,1231 13281,1235 13280,1236 13281,1241 13282,1245 13285,1247 13285,1247 13287,1250 13287,1247 13290,1247 13295,1247 13298,1252 13301,1249 13304,1252 13304,3252 13304,3247 13304,3249 13308,3254 13308,3257 13308,3261 17308,3261 17309,3261 17306,3259 17305,3262 17310,3263 17308,3262 17311,3259 17314,3259 17314,3257 17309,3254 17309,3253 17309,3255 17310,3253 17312,3255 17312,3255 17312,3256 17307,3257 17307,3256 17311,3256 17313,3255 17317,3251 17317,3248 17321,3253 17325,3256 17326,3258 17324,3258 17327,3263 17322,7263 17325,7265 17328,7263 17330,7265 17333,7270 17333,7273 17333,7278 17336,4278 21336,4278 21340,4279 21340,4281 21340,4286 24340,4290 24343,9290 24347,9294 24349,9296 24347,9298 25347,9301 25348,9301 25348,9304 25353,9303 25357,9303 25352,11303 25355,11304 25358,11307 25358,11312 25358,11312 25361,11310 25365,11313 25365,11314 25369,11319 25371,11321 25371,11325 25366,11329 25365,11330 25366,11329 25370,11330 25365,11334 25367,11338 25366,11343 25363,11348 25359,11345 25356,11348 25357,11349 25358,11349 25358,11352 25360,11356 30360,11360 30365,11360 30365,11362 30365,11367 30367,11368 30369,15368 30370,15373 30371,15376 30373,14376 30378,14377 30383,14381 30378,14386 30380,14388 30382,14391 30385,14393 31385,16393 31389,16396 31394,16396 31397,16392 31400,16395 31405,16398 31409,16398 31413,16397 31415,16396 31417,16401 31418,16401 31422,16402 31419,16407 31420,16411 31419,16406 31423,18406 31427,18411 31432,18415 28432,18417 28437,18418 28441,18414 28438,18417 28435,18416 28439,18420 28442,18423 28447,18427 28444,21427 28445,21428 28450,22428 28455,22432 28457,22436 28458,22441 28458,22445 28463,22448 28468,22451 28465,22456 28468,22453 28468,22458 28471,22463 28473,22460 28475,22459 28472,22463 28476,22464 28472,22468 28468,22468 28471,25468 28466,25471 28468,25473 28464,25473 28464,25475 29464,25476 29466,25479 29461,25476 29462,25476 29464,25478 29464,25483 29461,25484 29460,25486 29458,25486 29462,25490 29460,25495 26460,25498 26463,25495 26468,25495 26472,25495 26472,25499 26474,25504 26476,25504 26478,25509 26476,25513 26479,25514 26481,25519 26477,25519 26480,25518 26481,25519 26484,25524 26483,25527 26484,25522 26484,25526 26487,25528 26492,25533 26496,25535 26498,25535 26498,25539 26503,25542 26504,25543 26505,25547 26510,25552 26510,25551 26508,25550 26512,25553 26510,25557 26510,25554 26511,25552 26508,25556 26505,25556 26506,25560 26506,25560 26507,25560 26506,25565 26501,25567 26504,25569 26504,25568 26508,25571 26508,25571 26511,25576 26511,25581 26516,25581 26519,25582 26521,25585 26522,25588 26527,25588 26526,25584 26530,25587 26534,25589 26529,25593 26533,25598 26538,25599 26540,25599 26540,25599 26540,25604 26543,25603 26543,25603 26538,25606 26538,25609 26540,25611 26542,25612 26547,25612 26547,25612 26548,25617 25548,25612 25548,25613 25547,25616 25545,25616 25549,25618 25551,25620 25555,25620 25551,25622 25550,25625 25551,25622 25555,25619 25557,25617 25556,25622 28556,25625 28551,25630 28546,25634 28548,25639 28553,25643 28553,25638 25553,25634 25553,25634 25557,25639 25557,25643 25558,25644 25553,25646 25556,25647 25560,25650 25562,25650 30562,25650 30562,25650 30564,25650 30566,25652 30570,25656 30571,25661 31571,25662 31575,25663 31579,25662 31579,25665 31581,25666 31584,25671 31582,25674 31581,25674 31584,25676 31584,25673 31587,25678 31586,25679 31581,30679 31584,30675 31589,30680 31590,35680 31590,35675 31589,35677 31591,35680 31590,35681 31587,35684 31588,35685 31589,35689 31592,35689 31593,35692 31597,35696 31597,35700 34597,35699 34599,35703 34604,35703 34606,35702 34601,35705 34603,35705 34606,35708 34603,35713 34604,35717 34603,35719 34608,35715 34608,35711 34608,35713 34609,35714 34605,35714 34610,35714 34614,35718 34616,35719 34617,35722 34618,35722 34621,35725 34625,35725 34626,35725 34629,35725 34631,35725 34635,35730 34636,35727 34638,35731 34640,35735 34642,35739 34645,35741 34645,35742 34649,35738 34649,35738 34645,35741 34647,38741 34650,38741 37650,38742 37646,38746 37651,38749 37652,38753 37653,38753 37657,38757 37656,38756 37660,38761 37660,38765 37660,38760 37660,38759 37660,38760 41660,38760 41660,38762 41665,38757 41667,43757 41669,43752 41674,43752 41677,43757 41672,43758 41677,45758 41680,45758 41679,45762 41683,45765 41683,45769 41683,45770 41684,45768 46684,45773 46688,45776 46692,45774 46694,45775 46697,45778 46695,45776 46698,45774 46702,45779 46702,45784 46704,45787 46706,45791 46711,45786 46707,45790 46711,45793 46715,45796 46719,45799 46724,45797 46728,45802 46726,45797 46729,45801 46733,45802 46733,45803 46732,45804 46732,45805 46732,45808 46735,45810 46740,45810 46744,2326 27373,2322 27377,2323 27379,2325 27383,2325 27382,2322 27382,2323 27382,5323 23382,5325 23385,5329 23386,5330 23390,5335 23392,5330 23392,5330 23395,5329 23395,5333 23399,5333 23402,5338 23405,5339 23405,5334 23406,5329 23401,5332 23403,5330 23407,5333 23409,5328 20409,5324 20411,5324 20414,5329 20416,5328 20421,5325 20421,5329 20424,5330 20424,5335 21424,5331 21427,5333 21431,5334 21433,5329 21434,5330 21437,5333 21440,5338 21437,5338 21440,5334 21441,5333 21438,5329 26438,5332 26435,5335 26439,5337 26440,5338 26444,5342 26439,5342 26442,5345 26440,5349 26438,5352 26442,5349 26445,5348 30445,5350 30447,5350 30444,5354 30444,5359 30443,5363 30445,5367 30446,5367 30448,5367 30453,5371 30455,5371 30453,5373 30458,5375 30461,5380 30463,5384 30463,5383 30459,5384 30459,5383 30459,5385 30460,5390 30459,5392 30464,5394 30464,5389 30465,5393 30469,5391 30469,5391 30469,5395 30474,5396 30470,5399 30470,5401 30467,5401 30468,5404 30470,5400 30465,5401 30462,5403 30467,5404 30467,5409 30469,5412 30473,5412 30477,5407 30481,8407 30486,8408 30489,8410 30490,8410 30489,8413 30490,8414 30493,8414 30496,8419 30501,8420 30502,8415 30507,13415 30509,13411 30506,13414 30507,13412 30511,13412 30515,13417 30518,13419 30523,13418 30527,13422 30529,13418 30531,13413 35531,13409 35531,13413 35532,13417 35537,13419 35533,13423 35529,13424 35529,13423 35524,13428 35525,13433 35526,13438 35530,13443 35531,13448 35531,13452 35532,13455 35536,13457 35536,13452 35536,13455 35539,13452 35535,13457 35540,13457 35544,18457 35546,18460 35547,22460 35546,22465 35550,22466 35554,22468 35552,22473 35555,22471 35559,22470 35564,22472 35564,22470 35569,22474 35569,22474 35571,22477 35573,22482 35576,22487 35580,22488 35583,22489 35585,22493 35585,22496 35585,25496 35586,25493 35582,25494 35585,25498 35585,25496 35585,25498 35587,25503 35591,25503 35593,25499 35590,25499 35591,25495 35591,26495 35595,29495 35591,29495 35593,29498 35597,29498 35601,29500 35606,29501 30606,29502 30603,29505 30603,29510 30606,29511 30606,29514 30607,29516 30610,29518 30608,3259 17305,3263 17304,3267 17303,3271 17308,3269 17312,3269 17313,3274 17315,3277 17315,3282 17311,3285 17313,3283 17309,3278 17310,3275 17315,3275 17317,3276 17322,3280 17324,3280 17324,3276 17325,3277 17325,3276 17328,3278 17324,3273 17329,3277 17331,3280 17326,3281 17328,3276 17324,3277 17324,3277 17322,3277 17321,3277 17321,3281 17323,3282 17327,3282 17332,3287 17335,3288 17335,3288 17338,3290 17337,3294 17340,3294 17341,3299 17341,3299 12341,3299 12342,3304 12339,3301 14339,3305 14340,3307 14341,3311 14343,3313 14343,3314 16343,3310 16341,3310 16346,3312 16348,3311 16349,4311 16346,4316 16348,4321 16344,4324 16348,4322 16349,4323 16346,4323 16346,4326 16350,4322 16354,4323 16356,4325 16361,4325 16358,4322 16362,4325 20362,4325 20366,4322 20367,4326 20372,4326 20374,4331 20373,4333 20373,4338 20376,4339 20379,4341 20382,4338 20384,4339 20386,4340 20383,4340 20383,4335 20388,4336 20390,4341 20390,4346 20391,4348 20391,4349 20393,37497 26499,37494 26496,37496 26500,37496 26501,37499 26506,37497 26502,37498 26502,37500 29502,37500 29507,37505 29508,37506 33508,37508 33513,37513 33518,37517 33522,37516 33520,37521 33521,37521 33525,37516 33530,37519 33528,37520 33528,37524 33530,37527 33530,37525 33527,37528 33530,37533 33533,37534 38533,37536 38536,22358 13355,25358 13360,25361 13358,25362 13362,25362 13362,25365 13365,25363 13367,25359 13369,25357 13374,25360 13374,2247 13362,2252 13366,2254 13363,2257 13363,2261 13358,2264 13354,2264 13356,2269 13361,2272 13363,2274 13363,2275 13363,2273 13362,2274 13365,2278 13365,2280 13370,2284 13366,2284 13365,2289 13368,2290 13366,2293 13368,2298 13373,2298 13372,2295 13375,271 22347,273 22350,4273 22347,4269 22348,4270 22350,4271 22355,4272 22360,4276 22363,4281 22365,4284 24365,4279 24365,4282 24365,4285 24365,4287 24364,4289 24362,4294 24360,4295 24362,4298 24365,4301 24369,1301 24370,1301 24371,1305 24375,1305 24376,1307 24377,1312 24380,1314 24382,1318 24380,1316 24382,1316 24387,1318 24387,1318 29387,1321 29387,1316 29383,1320 29386,1321 29389,1326 29389,1327 29389,2327 29394,2327 29394,2332 29393,-666 24367,-663 24368,-661 24368,-656 24371,-653 24372,-649 24372,-647 24374,-643 24370,-638 24375,-635 24380,-638 24382,-638 24384,-638 24384,-636 24388,-637 24390,-632 24386,-630 24386,-629 24386,371 24389,376 24394,374 24392,377 24397,3377 24400,6377 24405,6378 24408,6373 24406,6370 24406,6375 24403,6370 24403,6375 24403,6379 24406,6374 24409,6378 24411,6380 24412,6378 24415,6378 24419,6383 24423,6385 24425,6387 24428,6390 24433,6386 24430,6386 24435,6387 24436,6388 24440,6387 24444,6383 29444,6383 29447,6386 29451,6382 29446,6387 29447,6390 29452,6393 29452,6397 29455,6400 29459,6400 29463,6397 29467,6393 29467,6395 29470,6397 29473,6399 29468,6394 29467,6397 29470,6396 29473,6396 29470,6393 29465,6389 29469,6390 29470,6389 29465,6389 29468,6392 29470,6388 33470,6390 33466,6391 33466,6392 33467,6394 33467,322 22372,322 22374,323 22377,327 22378,331 22382,330 22383,332 22386,333 22383,331 22383,330 22387,332 22391,332 22396,337 22397,339 22394,340 22399,340 22398,340 22396,343 22396,343 22396,341 22400,342 22404,343 22402,348 22403,345 22407,347 22411,342 22411,345 22413,340 22417,345 22417,348 22422,348 22426,351 22427,352 22432,352 22436,4352 22438,4353 22442,4354 22444,4354 22447,4357 22449,4360 22450,4364 22450,4367 22451,4369 22453,4366 22455,4369 22453,4373 22458,4377 22459,4380 22459,4380 22464,4385 22467,4385 22467,4390 22469,4385 22469,4385 22472,25571 26508,25574 26507,25578 26512,25581 26512,25581 26512,25583 26508,25583 26513,25587 26516,25589 26515,25590 26515,25591 26517,25589 26520,25587 26522,23587 26526,23585 26531,23589 26534,23592 26538,24592 26543,24588 26545,24593 26547,24598 26543,24598 26548,24602 26545,24598 26540,24600 26545,24600 26548,24600 31548,24605 31549,24608 31551,24613 31552,24615 36552,24616 36557,24619 36557,24622 36560,24622 36564,24627 35564,24627 35569,24632 35569,25632 35570,25635 35569,25636 35573,25636 35573,25638 35576,25641 35580,25641 35583,25641 35588,25642 40588,20642 40593,20645 40593,20650 40595,20651 40591,20651 40594,20648 40591,20648 40591,20652 40596,20652 40596,20656 40597,20656 40600,20656 40601,20659 40598,20662 40597,20662 40597,20663 40600,20668 40601,20665 40606,1215 13314,1214 13319,1212 13317,1209 13312,1210 13312,1211 13317,6211 13320,6214 13320,6216 13320,6211 13323,6214 13318,6214 13323,6214 13324,6216 13319,6219 13323,6218 13321,6219 13321,6218 13326,6221 13329,6225 13331,6230 13335,6231 13339,6231 13343,6235 13338,6234 13342,6234 13344,6236 13345,25524 26483,25521 26484,25524 26489,25527 26487,25529 26484,25530 26482,25534 27482,25539 27486,25537 27488,25541 27483,25544 27486,25547 27490,25550 27491,25550 27491,25554 27486,25559 27486,25563 27489,25561 27489,25563 27493,25561 27491,25563 27493,25563 27495,25564 27497,25563 27497,25563 27497,25558 27498,25563 27499,25565 27503,25567 27503,25569 27503,25567 27504,25565 27505,25565 27505,25565 27505,25566 27505,25570 27501,25570 27497,25574 27498,25570 32498,25570 32501,25573 32501,25576 32497,25576 32498,25577 32501,25579 32503,25583 32504,25588 32507,25592 32512,25596 32507,25599 32507,25594 32503,25597 32506,25597 32510,25594 32509,25594 32510,25596 32513,25592 32513,25594 32515,25594 32520,25598 32520,25602 32517,25603 32518,27603 32520,27607 32523,27608 31523,27613 31527,27615 31527,30615 31530,30617 31530,30618 31532,30619 31536,30623 31537,30623 31538,30625 31538,30626 31541,30627 31541,30624 31540,30623 31540,30624 31545,34624 31546,34619 31543,34623 31545,34624 31549,34624 31548,34626 31550,34626 31555,34626 31551,34628 31555,34633 31555,34636 31559,34634 31564,34636 31564,34639 31562,34639 31560,36639 31555,36636 27555,41636 27557,41640 27554,41644 27558,41647 27559,41648 27555,41653 27555,41658 27555,41658 27552,41658 27552,41660 27550,41656 27554,41661 27558,41664 27561,41667 27566,41662 27562,41663 27563,41663 27565,41662 27569,41661 27569,41664 27571,41664 27567,41659 30567,41660 30565,41660 30561,41665 30566,41664 30561,41664 30561,41664 30562,41664 30563,41660 30558,1312 24380,4312 25380,4315 25384,4315 25385,4319 25383,4322 25388,6322 25387,6322 25387,6326 25392,6321 25397,6324 25397,6324 25401,6319 25404,9319 25405,9314 25400,9312 25402,9310 25403,9313 25403,9313 25403,9316 25400,9319 25401,4319 25396,8319 25398,8315 25400,8315 25396,8315 25397,8311 25398,8307 25394,8309 25394,8311 25397,8315 25402,8310 25403,11310 25365,11311 25365,11316 25370,11320 25375,11325 25375,11325 25380,11325 25382,11326 25378,14326 25380,14328 25382,14331 25383,14334 25385,14336 25386,19336 25386,19336 25389,19332 25390,19332 25391,19335 25388,19338 25391,19342 25393,19340 25393,19345 25396,19345 25394,19347 25394,19349 25393,19351 25397,19350 25398,19348 25399,19349 25403,19352 25399,19350 25402,19354 25400,19353 25405,23353 25402,23354 25402,23356 25405,23358 25409,23360 25413,23363 25414,23367 25412,23365 25411,23367 25414,23363 25413,23367 25416,23367 25416,23370 25418,24370 25414,24370 25419,24373 27419,24378 27419,24380 27416,24380 27412,24380 27410,24380 27406,24376 27406,24374 27410,24370 27414,24370 27415,24371 27420,24375 27415,24378 27411,24375 27415,24378 27418,24382 27421,24383 27426,24383 27425,24385 27430,24390 27431,24394 27432,24395 27436,24399 30436,24400 30439,24404 30443,24403 30439,24406 30438,24410 30442,24406 30446,24408 30445,24403 30445,24408 30442,24412 30446,24416 30446,24416 30449,19416 30449,19416 30447,19418 30452,19420 30453,19423 30458,15423 30462,15423 30464,15425 30466,16425 30467,16424 30471,16421 30474,16426 30474,16428 30476,16428 30476,16424 30474,16424 33474,16425 33474,16427 33477,16425 33479,16426 33477,16422 33480,16425 33482,16430 33479,16430 33478,16429 33482,16424 33482,16427 33484,16430 33488,16431 33488,16434 33488,16435 33491,16432 33487,16436 37487,16434 37490,16438 37485,16443 37482,16446 37480,16447 37480,16447 37482,16451 37478,16454 37479,16458 37479,16454 37479,16454 37482,16459 37486,16460 37491,16463 37495,16464 37492,16465 37493,16466 37494,16468 37497,16468 37501,16468 37501,16473 37503,16473 37503,16473 37498,16476 37494,21476 33494,21473 33493,21476 33489,21478 33491,21478 33496,21478 33492,21480 33496,21483 33501,21484 33504,21483 33500,21484 33505,21484 33505,21488 35505,21491 35505,21494 35506,21496 35510,21492 35506,21492 35509,21489 35514,21490 35517,21487 35519,23487 35523,23485 35528,23487 35533,23483 35534,23487 35535,23488 35537,23493 35539,23495 35542,23495 35546,23495 35550,23491 35549,23488 35552,23492 35555,23495 35560,23500 35559,23496 35557,4322 16354,4317 16358,4318 16358,4320 16363,4315 16363,4315 16362,4316 20362,4320 20365,4323 20363,4326 20366,4329 20367,4332 20370,4337 20374,4338 20375,4333 20375,4338 20375,4341 20377,4342 20377,4342 20378,4343 20381,4346 20386,4346 20386,4346 20386,4346 20386,4349 20390,4352 20395,4354 20396,4355 20400,4358 20400,4360 20401,4360 20404,4363 20405,4368 20406,4372 20411,4371 20416,4367 20417,4364 20422,4367 20420,4372 20425,4373 20422,4374 20418,4377 20418,4381 20422,4382 20423,4384 20418,4389 20421,4385 20423,4390 20423,4390 20425,4392 20429,4396 20434,41574 39698,41578 39702,41576 39704,45576 39704,45575 39709,45577 39713,45581 39715,45581 39718,45583 39721,45578 39726,47578 39722,47581 39719,47586 39722,47586 39726,47589 39730,47592 39733,47597 39733,47593 39733,47596 39735,47597 39735,47595 39735,47591 39739,47593 39744,47593 39747,4074 20263,4077 20268,4079 20268,4078 20271,4078 22271,4083 22276,4087 22272,4088 22275,4086 22279,4082 22280,4084 22282,4086 22277,4082 22277,4087 22281,4090 22281,4092 22281,4092 22286,4094 22287,4097 22290,4097 22291,4095 22286,4095 22288,4095 22293,4095 22288,4092 22285,4089 22286,4090 22286,4095 22281,4100 22286,4103 22285,4104 22288,4104 22289,4107 22294,4112 22292,4117 22290,4120 22295,120 22300,121 22303,122 22300,122 22300,121 26300,125 26303,129 26303,127 26305,127 26306,132 26306,132 26307,136 26307,141 26309,140 26311,143 26313,140 26314,145 26318,149 26318,153 26321,153 29321,158 29326,158 29329,162 29324,162 34324,165 34329,168 34328,167 34332,169 34333,173 34334,173 34336,177 34338,178 34340,178 34344,182 34348,177 34348,182 34348,184 34353,184 34358,181 34360,183 34365,187 34365,192 34365,197 34367,199 34366,203 34368,205 34368,202 34363,204 34360,1204 34360,1205 34364,1205 30364,1205 30359,1206 30361,1207 30364,1210 30366,1210 30366,1214 30367,1218 30372,1219 30375,1214 30379,1214 30384,1217 30382,1222 30383,1223 30382,1225 30380,1228 30379,1231 30383,1232 30383,1235 30384,1237 30388,1242 30386,1244 30389,2244 30392,2241 30395,2245 30397,2245 30399,2244 30394,2242 30395,2246 32395,2246 32395,2249 32398,2251 32393,5251 32390,5251 32395,5255 32399,5255 32397,5257 32397,5257 32401,5261 32406,5261 32411,5266 32412,5271 32416,5273 32419,5276 32420,5281 32422,5279 32425,6279 33425,6284 33429,6284 33430,6282 33431,6282 33428,6286 33425,6288 32425,6288 32421,6286 32424,6288 32424,11288 32427,11292 32425,11292 32429,11290 32434,11286 32437,11286 32437,11283 32442,11278 32442,11279 32443,11283 32445,11284 32445,11283 32448,13283 32447,13287 32442,16287 32446,16282 32445,16283 32445,16284 32448,16285 32448,16284 32446,16286 32443,16290 32446,16291 32446,16292 32450,16291 32450,16291 32450,16291 32445,16287 32447,16288 32452,16287 32457,16291 36457,16289 36462,16293 36462,16294 36462,16297 36462,16301 36464,16306 36469,16310 36467,16310 36463,16313 36459,16312 36460,16313 36465,16313 36469,16308 36470,16309 36468,16314 36470,16319 41470,16322 41471,16325 44471,16330 44471,16330 44471,16330 44473,16330 44474,16335 44479,16332 44477,8414 30496,8415 30497,8419 30497,8414 30501,8416 30500,8418 30495,8421 35495,8423 35494,8427 35497,8429 35499,8432 35499,8436 35503,8438 35503,8443 35505,8440 35508,8443 35509,8440 35509,8440 35511,8441 35515,8445 35511,8448 35512,8443 35517,8443 35519,8442 35524,8444 35526,8441 35527,8436 35527,8433 35523,8429 35527,8430 35530,8431 35532,8429 35533,8433 35535,8437 32535,8435 32536,8439 32536,8436 32539,9436 32542,9434 32537,9429 32534,9429 32534,9433 32537,9433 32542,9429 32543,9434 32538,9436 32538,9436 34538,7436 34538,7438 34543,7439 34543,7439 34543,7439 34548,7438 34549,7438 34552,7438 34553,7438 34556,11438 34561,11434 34559,11436 34555,7436 34553,7436 34549,120 1235,124 1239,125 1236,125 1238,129 1235,128 1235,125 1236,123 1239,128 2239,132 2242,131 2242,135 2242,140 2242,145 2247,146 2252,144 2253,146 2248,144 2245,146 2244,150 2249,155 2245,159 2242,160 2243,160 2245,155 2244,156 2245,3156 2246,3159 2248,3159 2250,3164 2254,3165 2257,3166 2255,3169 2257,3171 2262,3169 2263,3174 2268,3177 2273,3174 2276,3178 2275,3173 2279,3177 2276,3180 2279,3182 2284,3185 2289,5185 2286,5185 2288,5181 2286,5185 2288,5184 2293,5187 2293,5187 2297,5190 2299,5187 2299,5185 2300,5181 6300,5182 6297,5187 6300,5189 6298,5191 6296,5193 6296,5193 6296,5195 6297,5195 6300,5197 6297,5195 6300,5190 6302,5191 6306,5192 6308,5195 6312,24395 27436,24391 27437,24393 27433,24398 27436,24398 27437,16286 32443,21286 32443,21286 32444,21282 32448,21283 32446,21283 32448,21285 32451,21281 32456,21282 32458,21282 32463,21282 32468,21284 32470,21289 32471,21287 32471,21287 32469,21287 32474,21284 32477,21288 32482,21291 32482,21291 32486,21296 32485,21299 32486,21301 32487,21303 32484,21301 32482,21305 32487,21310 32491,21312 32495,21313 32491,21315 32495,21312 32495,21314 32498,21316 32501,21311 32506,21311 32508,21312 32513,21317 32516,21319 32516,21324 32516,21327 32521,21328 32526,21332 32527,21328 36527,21331 41527,21336 41527,21334 41531,21337 41533,21335 41535,21339 41540,21340 41540,21343 41536,25343 41539,25340 41542,25337 41542,25337 41545,25335 41542,25335 41543,25335 46543,25339 46548,30339 46551,30340 46556,30343 46557,30342 46553,30337 46556,30341 46561,30337 46565,30336 46563,30338 46564,24373 27419,24373 27421,24375 27424,24377 27425,24377 27430,24374 27435,24379 27437,24384 27432,24385 27434,24382 27437,24381 27442,24381 31442,24381 33442,20381 33439,20383 34439,20382 34440,20378 34444,20381 34446,20381 34442,20384 34443,20388 34446,20392 34447,20393 34442,20393 34447,20396 29447,20395 29443,20399 29443,20400 29439,20399 29436,20404 29439,20409 29440,20410 29440,20410 29444,20408 29445,20413 29448,20413 29451,20412 29455,20413 29458,20418 29461,20413 29463,20415 29464,20416 29464,20416 29463,20416 29463,20418 29464,20414 29465,20418 29463,20413 29460,20413 26460,20418 26458,20421 26459,20421 26461,20421 26460,43578 35658,43578 35654,43578 35658,43578 35660,43583 35661,43583 35659,43583 35662,43579 35663,43583 35661,43587 35666,25625 25551,25629 25551,25630 25554,25630 25559,25632 25560,25627 25561,25623 25557,25623 25559,25624 25561,26624 25566,26627 25566,29627 25571,29626 25574,29625 25575,29622 25579,29625 25583,29630 25588,29632 25589,29635 25591,29635 25594,29637 25598,29642 25596,29643 25597,29644 25597,29649 25598,29654 25602,29656 25602,29661 25603,29661 25601,29664 26601,29666 26604,29665 26604,29668 26607,29672 26607,29669 26611,29671 26616,29674 26613,29679 26616,29680 26616,29681 26615,29682 26619,29679 26617,29684 26622,29686 26624,29689 26624,29690 26628,29691 26630,29693 26625,29694 26620,29698 26617,29703 29617,29707 29616,29706 29620,29709 29623,34709 29626,34710 29628,34710 29627,2282 16411,2283 16412,2283 16412,2287 16417,2292 16421,2297 16421,2298 16426,2303 16426,2304 16429,2309 11429,2313 11432,2308 14432,2308 14431,2311 14433,2310 14437,2308 14438,2309 14440,2311 14440,2309 14443,2312 14443,2314 14447,2314 14452,2314 14450,2309 14451,2309 14451,2309 14456,2313 14461,2313 14461,2309 19461,2309 19461,2311 19462,2315 19465,2318 19465,2321 19462,2317 19464,2321 19467,2322 19467,2322 19469,2322 19469,2320 19464,2321 19462,2322 19461,2327 19466,2327 19461,2322 19461,2322 19463,2317 19467,2318 19471,2102 -1848,2107 -1848,2111 -1846,2114 1154,2114 1156,2115 1157,2114 6157,2116 6162,2121 6165,2124 6170,2121 6175,2124 6179,2124 6183,2128 6178,2126 6179,2125 6178,2126 6181,2122 10181,2127 10186,2128 10189,2130 10188,2130 10191,2127 11191,2127 11195,2131 11196,2132 11192,2131 11197,2135 11201,2135 11203,2139 11199,2142 11203,2143 11204,2147 11208,2142 11210,2142 11211,2147 11212,2150 11217,2150 11219,2151 11219,2152 11222,2152 11222,2148 11224,2150 11220,2150 11223,2146 11218,2143 11219,2140 11221,2143 11218,2140 11219,2140 11223,2145 11225,2147 11226,2152 11226,2155 11224,2157 11229,2157 11229,2153 11233,2153 11238,2149 11239,7149 10239,7154 10241,7157 10241,7162 10243,7164 10248,7164 10251,7169 10253,7171 10253,7172 10257,7177 10260,7182 10256,7187 10260,7191 8260,7195 8256,7200 8258,7204 8258,7203 8261,7203 8262,7205 8266,7209 8270,7209 8273,7214 8273,7214 8276,7210 8276,7211 8276,7213 8279,7218 8278,7222 8283,7223 8279,7220 10279,7221 10283,7223 10284,7228 10286,7230 10290,7231 10290,7231 10293,7232 10294,7232 10297,7234 10299,7229 10295,7226 10294,7221 10293,7223 10295,7228 10299,7229 10303,7232 10307,7232 10311,7233 10316,7234 9316,7239 9318,7244 9321,7241 9326,7241 9328,7238 9331,7235 9330,7237 9335,7236 9335,7236 9337,7236 9338,7231 14338,7230 14333,7232 14338,7237 18338,4082 22280,4081 22280,6081 22283,6076 22285,6076 22289,6078 22286,6080 22287,6084 22292,6084 22293,6085 22293,6086 22291,6091 22294,6092 22293,9092 22290,9095 22294,9096 22295,9096 22297,9091 22292,9096 22295,9098 22290,9094 18290,9097 18290,9096 18294,9099 18292,9098 18297,9103 18299,9103 18302,9103 18305,9100 18301,9102 18302,9106 18305,9102 18310,9101 18306,9103 18308,9103 18312,9107 18310,9107 18315,9107 18320,9111 18322,9111 18326,9113 18329,9111 18329,9116 18329,9121 18329,9121 18332,9123 18331,9124 18332,9125 18328,9127 18325,9125 18328,9128 18329,9133 18329,9136 18333,9141 18337,9142 18342,9143 18340,9148 18344,9152 18341,9150 18346,9149 18341,9149 18341,9154 18343,9158 18345,9161 18346,9161 18347,9163 18352,9164 18352,9162 18349,9165 18352,9165 18351,9165 18352,9165 18356,9163 18352,9167 18353,9167 18349,9168 18351,9168 18347,9173 18347,9175 18347,9179 18348,9182 18349,9187 18352,9186 18357,9189 18360,9192 18360,9196 18362,13196 18367,13196 18369,13196 18371,13199 18374,13194 18374,13197 18375,13200 18377,13205 18380,13210 18384,13209 18379,13209 18374,13213 18375,13216 20375,13212 20375,13215 20375,13211 20375,13211 20372,13208 20373,13204 20373,13204 20369,13205 20369,13207 20366,13212 20367,13216 20367,13221 20372,13222 20377,13225 20381,13226 20386,13230 20383,9230 20388,9228 20384,9228 20386,9223 20389,9223 20392,4223 20397,4223 20396,4225 20399,4222 20404,4220 20408,4220 20411,4223 20416,4227 20421,4230 20418,4234 20421,4232 20422,4236 20423,4238 20423,4239 20423,4235 20427,4231 20427,4230 20426,4228 20428,4232 20427,4232 20431,4236 20433,4241 20431,4241 22431,4236 22436,4239 22437,4239 22439,4236 22443,4232 22439,4236 22444,4236 22446,4239 22447,4239 22452,4241 22454,4245 22457,4245 22460,4250 22462,4251 22465,4253 22465,4249 22465,4251 22460,4251 22464,4255 22469,4257 22473,4256 22478,4259 22479,4260 22480,4257 22485,6257 22489,6260 22490,6260 22493,6262 22496,6262 22500,6267 22495,6271 22495,6276 22491,6276 22489,6281 22487,6286 22490,6289 22490,6294 22490,6294 22489,6292 22485,6292 22489,6288 22489,6288 22494,6288 22496,6286 22497,6288 22501,6292 22500,5292 22503,5292 22503,5296 22508,5295 22510,5300 22510,5305 22513,5302 22514,5306 22510,5309 22513,5313 27513,5313 27513,5317 27513,5322 22513,5326 22517,6326 22516,6323 22518,6323 22523,6320 22523,6321 22526,6323 22531,6323 22531,6324 22532,6324 22532,6325 22529,6321 22531,6323 22534,6328 22534,6329 22530,6324 22527,10324 22522,10319 22524,10315 22520,10314 22525,10311 22525,10307 22526,10304 22531,10306 22527,10306 22528,10309 22530,10312 27530,10312 27534,10312 27534,10307 27536,10307 27532,11307 27531,11307 27533,11308 27535,11303 27531,11298 27532,11294 27534,11294 27534,11299 27538,11297 27542,11302 27547,11306 27547,11311 27549,11313 30549,11317 30551,11313 30546,11316 30541,11316 30540,11319 30545,11318 30546,11323 30550,11326 30554,11326 34554,11330 34558,11331 34558,11333 34558,11332 34561,11328 34561,11331 34562,11336 34562,11336 34567,11340 34570,11342 34569,11345 34568,11344 34569,11345 34571,11349 34574,15349 34574,15354 34569,15359 34566,15362 34571,15363 34576,15367 34577,15368 34577,15371 34581,15374 34576,15379 34574,15383 34579,15384 34584,15387 34583,17387 34578,17392 34578,17391 34578,17396 34573,17397 34578,17397 34580,17397 39580,17402 39584,17397 39587,17402 39587,17406 39582,17403 39587,17407 39589,17409 39592,17406 39592,17409 39595,17409 39599,17412 39603,17416 39608,17417 39608,17417 39608,17421 39607,17422 39609,17424 39608,17427 39604,17425 39605,17426 39609,17423 39611,17422 39610,17425 39613,17428 39618,17428 39619,17429 39616,17432 39616,13432 39615,13432 39617,13432 39617,13432 44617,13434 44621,13434 44623,13439 44627,13442 44632,13442 44635,13440 44631,13442 44631,13445 44635,13447 44639,13445 44637,13445 44638,13450 44639,13454 44644,13457 44644,13459 44642,15459 44639,15457 44644,15461 44644,15462 44642,15459 44645,15459 44647,15463 44650,15458 44651,15459 44653,15461 44657,15463 44661,15463 44661,15463 44663,15467 44666,15472 44668,15474 44664,15470 44668,15471 44670,15473 44674,15475 44675,-3806 12298,-3804 12301,-3805 13301,-3804 13296,-3808 13292,-3809 13295,-3806 13300,-3804 13297,-3801 13301,-3801 13302,-3796 18302,-3801 18306,-3799 18311,-3802 18311,-3799 18312,-3801 18314,-3796 18319,-3795 18322,-3791 18321,-3786 18320,-3786 18321,-3784 18321,-3782 18321,-3781 18324,-3782 18325,-3783 18320,-3788 18324,-1788 18324,-1788 18329,-1784 18333,-1784 18334,-1781 18329,-1777 18334,-6777 18337,-6774 18339,-6776 18341,-6781 18341,-6779 18341,-6779 18343,-6779 18339,-6777 18343,-6782 18338,-6779 18341,-6778 18341,-6776 18336,-6776 18333,-6776 18333,-6780 18338,-6784 18338,-6787 18335,-6786 18336,-6781 22336,-6781 22335,-6778 22331,-6777 22326,-6777 22331,-6777 22335,-6772 22335,-6774 22340,-6769 22341,-6767 22337,-6767 22335,-6767 22335,-6767 22333,-6767 22336,-6762 22331,-6759 22331,-6764 22332,-6765 22334,-6767 22339,-6762 22334,-6760 22334,-6760 22334,-6758 22337,-6754 22341,-6754 22342,-6750 22339,-4750 22343,-4747 22343,-4752 22343,-4751 22344,-4749 22345,-4745 22348,-4740 22353,-4736 22358,-4738 22363,-4740 22358,21336 41527,21334 41527,21330 41526,21330 41526,21333 41529,21328 41529,21329 41530,21326 41532,21328 41532,21324 41537,21328 41532,21330 41535,21334 41532,21336 40532,21334 40536,21339 40534,21341 40534,21344 40534,21346 40532,21350 40532,21353 40535,21357 40539,21359 40542,21360 40546,21355 40546,21360 40547,21359 40550,21356 40551,21356 40550,21357 40550,21361 40554,21358 45554,21362 45556,21366 45553,21370 45557,21374 45556,21377 45553,22377 45549,22382 45549,22382 45552,22386 45557,22387 45557,22388 45553,22392 45557,24392 45561,22392 45558,22397 45561,22399 45558,22398 45561,22400 45564,22400 45569,22404 45573,22406 45577,22406 45581,22404 45581,22407 45582,22409 45579,22409 45575,22409 45579,22407 45579,22402 45582,22402 45582,22404 45587,22406 45587,22406 45589,22411 45589,22413 45590,22417 45591,22417 45592,22422 45587,22425 45583,22428 50583,22428 50585,22428 50585,22430 50588,22435 50590,22435 50585,22435 50590,22439 50595,22440 50590,22445 50587,22442 50584,22442 50586,22443 54586,22443 54590,22446 54595,22448 54597,22448 59597,22444 59593,22449 59596,22449 59599,22452 59600,22457 59600,22458 59605,22457 59602,22462 59603,22463 59604,22461 59605,22458 59602,22457 59601,22457 59601,22455 59605,25455 59606,25457 59611,25462 59613,25464 59614,25467 59617,25472 59612,25476 59613,25478 59610,25482 59615,25482 59616,25486 59612,25483 59614,25487 59619,25492 59623,25497 59625,146 2252,150 2249,150 2249,152 2254,157 2249,158 2253,157 2252,161 2255,159 3255,161 3258,161 3255,163 3255,168 3259,168 3259,172 3263,167 3267,172 3271,172 3272,172 3274,175 3278,179 3282,181 3283,184 3280,185 3282,187 3282,191 3284,192 3286,191 6286,193 6289,198 6285,195 6290,194 6289,195 6289,199 6293,200 6288,198 6290,202 6291,207 6296,212 6301,215 6301,216 6301,211 6304,212 6304,216 6309,216 6304,214 6308,213 6308,211 6305,212 6309,217 6314,220 6317,224 6322,222 6327,220 6323,41573 39712,41572 39709,41576 40709,41580 40714,41576 40717,36576 40717,36577 40719,36582 40716,36585 40721,36590 43721,36585 43721,36582 43724,36585 43729,36590 43731,36590 43730,15289 11307,15285 11312,15286 11315,15289 11315,15294 11315,15295 11316,15296 13316,38742 37646,38743 37650,38745 37655,38744 37658,38739 37659,38737 37662,38742 37662,38745 37657,38748 37662,38748 37662,38752 37667,38753 37667,38748 37669,38748 37668,38752 37673,38754 37674,38756 37676,38758 37674,38760 37679,38760 37675,38758 37675,38763 37675,38767 37674,38772 40674,38767 40679,38772 40683,38774 44683,38778 44686,38780 44690,38780 44690,38779 44695,38782 44700,38780 44695,38775 44696,38775 44696,38775 44696,38779 44699,38783 44696,38784 44696,38786 44692,38786 44692,38786 44696,38791 44698,38793 44699,38795 44703,38800 44708,38803 44708,38807 44709,38802 44706,38806 44708,38809 44709,36809 44709,36814 44704,36813 44705,36814 44705,36816 44709,36811 44712,36812 48712,36811 48717,36815 48721,36816 51721,36818 51717,36822 51720,40822 51715,40827 51712,40830 51716,40829 51719,40832 51723,40835 51724,40840 51721,40841 51721,40836 51725,40841 51730,40846 51734,40848 51738,40849 51740,40851 51743,40854 51745,40855 51746,40857 51750,40857 51746,40861 51748,40866 51751,40862 51750,40866 51750,40869 51752,40865 51752,40863 51755,40858 51757,40855 51753,40855 51758,40852 51758,40853 51760,40857 51761,40855 51757,40852 51760,40853 51761,40855 51762,40858 51757,40859 51756,40863 51757,40863 51759,40860 51764,40859 51764,40854 51768,40850 51765,40852 51767,40852 51767,40848 51772,40852 51776,40854 51778,40852 51778,43852 51778,43854 52778,43856 52781,43859 52781,43859 52776,37512 26536,37517 26531,37520 26535,37520 26540,37522 26544,37527 26544,37532 26549,37537 26544,37540 26549,37545 26544,37549 26547,37549 26550,37548 26551,37549 26553,37546 26553,37546 26553,37549 26556,37549 26559,37552 26559,37556 26564,37560 26559,37561 26561,37565 26565,41565 26565,41569 26568,41571 26573,41571 26573,41576 29573,41571 29573,41573 29576,41573 29578,46573 29578,46569 29582,45569 29583,45572 29583,45568 29583,45573 29581,45575 29578,45571 29581,45572 29584,45572 29585,45576 29585,45578 29588,45581 29591,45582 29593,45582 29598,45584 29597,45589 29600,45585 29605,45589 33605,45593 36605,45594 36607,45599 36609,45600 36604,45604 36604,45604 36608,45604 36607,45608 36610,50608 36613,50611 36609,50614 36609,50619 36605,50624 36605,50625 36606,50625 36605,50629 36606,50624 36608,50625 36610,50626 36610,50629 36608,50627 36610,50628 36614,50632 36618,46632 34618,46632 35618,46636 35622,46636 35617,46637 35620,46639 35619,46643 35620,46645 35625,46643 35630,46648 35635,46648 35640,46649 35643,46651 35647,46655 35650,46652 35655,46657 35656,46658 35657,46662 35660,46659 35663,46662 35664,46665 35663,46667 35667,46667 35663,46670 35666,46672 35671,46674 35671,47674 35668,47676 35672,47677 35673,47677 35678,47677 35677,47677 35677,47677 35682,47672 35683,47671 35683,49671 35685,49674 35689,49677 35692,49675 35692,54675 35697,54678 35699,54674 35699,54670 35701,54670 35700,54675 35703,54676 34703,54676 34703,54679 34706,54683 34708,54688 34706,54688 34707,54685 34702,54687 34702,54692 34707,54687 36707,54687 36706,54682 36707,54685 38707,54680 38710,54680 38714,54677 38714,54679 38719,54682 38720,54687 38716,54688 38717,54692 38722,54697 38726,54699 38727,54700 38724,54702 38720,52702 38719,52702 38719,52702 38721,52702 38725,52704 38726,52706 38728,52707 38729,52711 38728,52711 35728,52713 35733,52712 35737,52712 35739,52713 35742,52713 35745,52708 35745,52710 39745,52713 39749,52716 39748,52721 39749,52720 39753,52716 39756,52716 40756,47716 40757,47717 40761,47722 40761,47722 40761,47722 40766,47726 40769,47728 40772,47733 40777,47731 40773,50731 40777,51731 40779,51733 40782,51734 40786,51737 40784,51741 41784,51739 41783,51739 41785,51739 41785,51736 41789,51731 41789,52731 41790,52735 41791,52738 41790,52742 41789,52746 41785,52747 41785,52745 41785,52750 41782,52753 41786,52753 41787,52758 41792,52754 42792,52749 42793,52752 42794,52756 42791,52757 42790,52762 42793,52766 42797,52766 42797,52769 42802,52774 42806,52774 42805,52771 42807,52774 42807,52770 42808,52771 42811,52767 42811,52766 42812,52767 42817,52771 42817,52771 42817,52775 42815,52779 42811,52779 42812,52780 42815,52776 42818,52774 42818,52777 42822,52780 42823,52781 42827,52776 42829,52780 42832,54780 42835,54780 42840,2135 11201,2140 11203,2137 11204,2140 11209,2142 11213,2147 11211,2145 11213,2145 11213,2150 11218,2150 11221,2153 11225,2157 13225,2162 13228,2167 13231,2171 13232,2167 13229,2168 13233,2171 13237,2173 13239,2168 13234,2168 13235,2173 13235,2175 13234,2177 13235,2177 13234,2179 13229,2179 13226,2180 13226,2177 13226,2177 13231,2180 13231,2181 10231,2176 10233,2177 10232,2180 10235,2185 10237,2182 10240,6182 10240,6184 10244,6182 10242,6183 10243,6185 10246,6190 10244,6194 10244,6194 10247,6192 10247,6192 10252,6195 10256,6194 10260,6195 9260,6195 9260,6195 9264,6199 9269,6204 9272,6199 9268,6201 9268,6203 9265,6208 9268,6204 9270,6204 9275,6201 9279,6201 9281,6201 9286,6206 9281,6206 9277,6202 9281,6200 9285,6202 9288,6198 9290,7198 9293,7200 9297,7201 9297,7205 9298,7209 9298,7209 9299,8209 9302,8214 10302,8218 10306,8222 10308,8226 10313,8231 10313,8235 10318,8237 10318,8237 10323,8233 10326,8233 10327,8237 10325,8238 10328,8238 10330,8234 10330,11234 10332,11236 10333,11241 10337,14241 10338,14240 10338,14237 10339,14238 10337,14237 10339,14242 10339,14246 10339,14250 10339,14250 10339,14251 10337,14254 10337,14256 10334,14256 10332,14252 10336,14255 10340,14259 10342,14262 10347,11148 3159,11153 3163,11154 3162,11154 3165,11158 3167,11161 3172,11162 3175,11162 3176,11166 3179,11166 3181,11171 3185,11176 3180,11178 3179,11176 3181,11179 3183,11174 3182,52776 42818,52778 42822,52777 42822,52782 42817,52783 42822,52784 42823,52789 42826,52789 42823,56789 42828,56786 42829,56786 42832,56789 42836,56789 42835,56785 42838,56786 42843,51786 42844,51788 42846,51790 42847,51794 42842,51796 42842,51801 42846,53801 42849,53806 42849,53809 42852,53812 42850,53817 42846,53817 42848,53818 42853,53822 42856,53823 42854,53826 42858,53825 42860,53826 42860,53826 42864,53830 42868,53835 42873,53839 42873,53841 42872,53841 42876,53841 42879,53841 42884,53836 42888,53836 42889,53836 44889,53833 44889,53835 44893,53838 44897,53842 44897,53844 44900,53844 44904,53845 44905,53850 44903,53853 44904,53858 44906,53856 44907,53861 44909,53856 44913,53858 44916,53863 44916,53868 44918,53867 43918,53869 43921,53869 43919,53867 43919,53862 43918,53860 43923,53864 43928,53869 43930,53874 43933,53874 43932,53874 43932,53875 43930,53877 43928,53878 43924,53883 43927,55883 43929,55883 43925,55879 43929,55881 43929,55884 43928,55881 43928,55882 43929,55883 45929,55883 45933,55883 45936,55884 45941,55884 45941,55886 45946,55882 45948,55883 45952,55888 45956,55890 45957,55894 45953,55892 45954,55897 45950,55893 45954,55896 45956,55892 45955,55897 45959,55899 45961,55899 45961,55894 45962,55898 45957,55893 49957,55896 47957,55894 47956,55898 47960,55901 47964,55901 47967,55901 47970,55896 47973,55898 47969,55894 47974,55895 47975,55891 47976,55896 47979,55899 47984,55902 47983,55897 47987,55899 47989,55904 47992,55904 47993,55905 47997,55902 48001,55902 48003,55907 48000,55910 47998,55915 47999,55911 47994,55906 47998,55910 48003,55914 48000,55918 48000,55914 48000,55919 48000,55921 48003,55921 48007,55924 48007,55919 48010,55922 48005,55927 48009,55928 48008,55928 48008,55930 48012,55925 48012,55925 48016,54925 48014,54922 48018,54922 44018,54926 44013,54929 44012,54932 44016,55932 44017,55935 44017,55936 44020,55937 44022,55936 44020,55939 44015,55944 44018,55945 44022,55947 44023,55950 44024,55953 44020,55956 44023,53867 43919,53871 43921,52871 43921,53871 43923,53876 43923,53881 43923,53880 43927,53882 43931,53886 43936,53884 43937,53879 43934,53879 43937,53877 43939,53878 43938,53879 43942,53880 43947,53881 43948,53884 45948,53884 45949,53882 45953,53883 45954,53878 45956,53880 45953,53885 45958,53885 45958,53886 45957,53886 48957,53886 48962,53891 48962,53892 48964,53897 48965,49897 48962,49902 48965,49906 48967,49902 48967,49904 48971,49901 48967,49904 48970,54904 48971,54904 48971,54904 48975,54909 48979,54907 48975,54910 48975,54906 48971,54909 48973,54911 48975,54915 48978,54920 48978,54923 48981,54918 48984,54921 48984,56921 48984,56926 48986,56924 48981,56929 48980,56932 48979,56932 48977,56936 48979,56937 48981,56937 48982,61937 48984,61937 48980,61934 51980,61935 51981,61935 51984,61935 51984,61931 51986,5329 23395,5331 23395,5333 23390,5337 23392,5340 23395,5345 27395,5345 27397,5350 27398,5355 27399,5356 27402,6356 27405,6360 27407,6361 27406,6364 27402,6366 26402,6371 26402,6371 26402,6372 26405,6370 26405,6375 26406,6380 26411,6385 26413,6387 26414,6388 26419,6390 26419,6391 26424,6393 30424,6390 30429,6390 30432,6390 30430,6394 30434,6394 30437,6394 30441,6396 30442,6398 30439,6399 30436,6404 30435,6405 30435,6400 30435,6405 30440,6404 30443,6405 30447,6409 30447,6411 30447,6412 30448,6417 30446,6421 30450,6418 30448,6417 30444,6418 30449,6420 30451,6425 30456,6426 30456,6425 30458,6426 30458,6426 34458,6427 34459,6432 39459,6434 39462,6434 39467,6439 39470,6443 39467,6444 39468,6449 39473,6451 39476,6452 39481,6452 39479,6452 39476,8452 39476,8456 39478,8460 39480,10460 39482,10455 39482,10456 39484,10460 39484,10463 39484,10468 39486,10473 39482,10475 39484,10475 39486,10476 39488,10477 39492,10475 39494,10480 39499,10476 39501,10479 39506,10480 39510,10475 39508,10480 39513,10481 39516,10481 39516,10485 39521,10487 39522,10490 39523,10490 39520,10493 39520,10496 44520,10491 44519,10491 44524,10492 44520,10497 44525,10499 44525,10502 44527,10500 44531,10502 44535,10506 44535,10511 44532,13511 44536,13513 44533,13510 44535,13507 44540,13511 44543,13515 44548,13517 44549,13522 44550,13525 42550,13520 42551,13522 42553,13525 42552,13529 42557,13529 42558,13524 42559,13525 42559,13525 42562,13520 42564,13523 42567,15523 42569,15523 42572,15524 42577,15529 42577,15530 42582,15532 42584,15532 42588,15531 42587,15531 42592,15530 42587,15530 42583,15533 42583,15536 47583,15532 47583,15535 47587,15534 47590,15536 47594,11536 47590,11533 47590,11529 47590,11533 47592,11533 47592,11533 47593,11537 47598,11538 47603,11538 47603,11538 47605,11541 47609,11544 47613,14544 47614,14539 47610,14537 47610,14537 47614,14535 50614,14537 50619,14539 50619,14540 50623,14538 50623,14537 50619,25599 26540,25599 26541,25599 26544,25594 26542,25599 26543,25596 26544,25597 26543,25598 26543,25593 26544,25588 26542,25593 26545,25595 26544,25596 26544,25599 26541,25594 26544,25592 26549,25593 26548,25597 26549,25596 26550,25594 26551,25590 26550,25594 26554,25597 26550,25598 26552,25593 26555,25598 22555,25599 22557,25604 22559,25605 22558,25606 22562,25605 22559,25605 22564,30605 22569,30610 22571,30610 22575,30609 22575,30609 22576,30609 22581,30605 22581,30610 22583,30610 22584,30613 22579,30613 22581,30616 22577,30619 22577,30621 22580,30621 22585,30626 22590,30628 22593,30629 22598,30626 22603,30628 22606,30629 22607,30629 22604,30627 22606,30632 22608,30633 22608,30636 22612,30641 17612,30642 17614,30647 17614,30651 17615,30654 17610,30655 17607,30658 17611,30653 17610,30654 17606,30654 17607,30659 17606,30660 17611,30658 17616,30659 17616,30664 17619,30665 17621,30665 17620,30667 17621,30671 17624,30673 17624,30673 17624,30678 17627,30675 17632,30675 17635,30678 17640,30681 17643,30686 17639,30691 17641,30696 19641,30699 19640,30700 19640,30696 19645,30698 19643,30699 19645,30702 19646,30703 19649,30699 19651,30704 19648,30706 19652,30709 19653,30709 19655,30709 19655,30712 19657,30708 19658,30705 19660,30700 19662,30701 19663,30706 19664,30711 19663,30707 19667,30704 19670,30708 19672,30709 19673,30711 19673,30711 19674,30713 19678,30718 19682,30723 20682,30721 20686,30725 20691,30726 20693,30729 20695,30728 20690,30730 20692,30733 20694,30736 20692,30736 20691,30740 20694,30741 20695,30741 20697,30746 20700,30747 20702,30750 20701,30751 20698,30753 24698,30749 24701,30748 24703,30746 24704,30747 29704,30747 29705,30749 29707,30752 29712,30757 29712,30760 34712,30760 34716,30763 34716,30759 34713,30759 34717,30763 34717,30758 34717,30757 34721,30760 34726,30758 34726,30763 34727,30763 34727,30764 34727,30759 34729,30759 34732,30762 34734,30757 34735,30761 34736,30759 34736,30762 34738,30757 34733,30760 34735,30762 34737,30760 34736,30765 34733,32765 34737,32768 34737,32765 34740,32765 34742,32768 34747,32772 34751,32772 34752,32777 34749,32782 34751,32783 33751,32783 33746,36783 33749,36783 33754,36786 33756,36787 33755,36787 33758,36791 33754,36796 33754,36801 33756,36801 33758,36801 33762,36802 33765,36802 33765,36806 33770,33806 33772,33806 33777,33809 33777,33814 33780,33814 33785,33818 33782,33821 33784,33826 33781,33822 33781,33824 33783,33822 33784,33826 33787,33823 33792,33827 33795,33828 33798,33829 33799,33833 33801,33833 33801,33836 33805,33839 33809,33842 33805,33847 33810,33845 32810,33847 32808,33849 32812,33851 32815,33849 32818,33849 32822,33847 32822,33847 32826,33850 32831,33854 32836,33857 32833,33856 32828,33859 32829,33860 32832,33857 32834,33857 32830,33855 32830,33857 32830,33855 32834,33859 32829,33859 32833,33862 32836,33864 32837,33864 32839,33866 32837,33869 32835,33872 32840,33874 37840,33879 37845,33881 37850,33881 37855,33886 37856,33891 37860,33896 37860,33893 37863,33894 38863,33896 38859,28896 38864,28899 39864,33899 39869,33896 39871,33898 39875,33902 39873,33902 39875,33907 39879,33912 39884,33908 39887,33908 39888,33905 39890,33909 39895,33911 39896,33908 39900,33912 39901,33915 39902,33915 39902,33915 39902,33910 39907,33910 39904,33914 39903,33912 39906,33916 39909,33920 39909,33922 39912,33923 39916,33928 39916,33931 39918,33932 39919,33935 39915,33936 39912,33934 39909,35934 39914,35931 39915,35935 39917,35939 39920,35939 39915,35940 39911,35944 39916,35944 39911,35944 39908,35945 39904,35945 39908,35945 39912,35950 39915,35955 39917,38955 39916,38960 39921,38962 39920,38962 39920,38967 39922,38967 39924,38970 39928,38975 39928,38973 39928,38977 39931,38980 39934,38984 39936,38982 39939,38983 39942,38985 39943,38987 39945,38992 41945,38988 41950,38989 41954,38992 41958,38992 41962,38992 41965,38993 41970,38997 41970,38997 41970,38994 41974,38994 41979,38997 41979,38999 41982,38994 41980,38998 41985,38998 41984,5334 23406,5330 23406,5325 23403,9325 23404,12325 23408,12325 23408,12322 23406,13322 23411,13325 23416,13326 23412,13322 23414,13327 23419,13328 23422,13329 23425,13333 23422,13337 23424,23491 35549,23490 35544,23494 35546,23499 35548,23495 35549,21495 35553,21490 35556,21492 35558,21492 35556,21494 35559,21494 35564,21494 35566,21499 35566,21502 35562,21502 35567,17502 35568,17506 35573,17507 35574,17511 35578,17512 35583,17513 35588,18513 35591,18514 35592,18515 35594,18513 35596,16513 35601,16513 37601,16513 37602,16511 37604,16513 37609,16514 37611,16518 37616,16522 34616,16524 34613,16528 34615,16528 34620,16533 34624,16535 34627,16538 34628,16539 34630,16539 34631,16542 34628,16542 34633,16544 34638,16547 38638,16547 38640,16543 38645,16543 38640,16540 38640,16543 38640,16542 38641,16546 38646,16541 38649,16541 38645,18541 38648,18544 38648,18544 38653,18544 38656,18549 38651,18547 38651,18550 38656,18547 38658,23547 38663,23544 38664,23548 38668,23548 38670,28548 38672,28549 38669,28549 38673,28545 38669,28549 38670,28554 38670,28557 38674,28560 38669,28562 38674,28562 38669,28561 38669,28564 38671,28569 38671,38779 44699,38780 44695,38778 44698,38783 44700,38785 44700,38781 44701,38782 44696,38786 44691,38789 44692,38794 44692,38799 44688,38799 44693,38803 44697,38808 44697,38806 44697,38806 44700,38803 44702,38803 44706,38802 44707,38807 48707,38808 48707,38806 48707,38810 48712,38810 48709,38810 48711,38810 48711,38806 48707,38802 48710,38803 48706,38805 48711,38810 48711,38805 48709,38809 48710,38809 48710,38814 48707,38815 48703,38816 48703,38816 48704,38820 48704,38822 48709,38820 48710,38818 48714,38822 48716,38822 48719,38827 48722,38828 48727,38832 48725,38830 48730,38831 48726,38832 48724,38829 48728,8431 35532,8431 35537,4431 35532,4434 35537,4438 35537,4439 35533,4443 35535,4442 35530,4445 35527,4449 35527,4453 35530,4458 35530,4459 39530,4460 39531,4461 39531,4464 39531,4468 39531,4470 39534,4465 39534,4465 39532,4469 39532,4471 39537,4466 39538,4470 39539,4473 39540,4476 39540,4480 39543,4485 39548,4483 39546,4484 39547,4484 39549,4484 39551,4486 39553,4486 39554,4487 39551,4483 39553,4486 39554,4490 39556,4493 39557,4498 39561,4494 39562,-4749 22345,-4752 22345,-4748 22348,-4744 22351,-4740 22356,-4741 22358,-4739 22361,-4734 22359,-4730 25359,-4730 25360,-4725 25360,-4727 25360,-4727 25361,-6727 25360,-6729 25365,-6730 25365,-6727 25365,-6731 25364,-6730 27364,-6727 27366,-6723 27367,-3723 27363,-3719 27368,-3720 27371,-3718 27366,-3717 27369,-3716 27369,-3714 27372,-3711 27370,-3712 27371,-3712 27370,-3710 27375,-3708 27377,-3707 27382,-3706 27385,-3706 27389,-3705 32389,-3704 32392,-3704 32392,-3699 32391,-3699 32395,-3694 32399,-3694 32400,-3695 32404,-3695 32408,-3693 32410,-3693 32410,-3697 32410,-3692 32413,-3691 32418,-3686 32420,-3683 32425,-3681 32420,-3678 32424,-3673 32424,-3676 32427,-3673 32426,-3671 32426,-3676 33426,-3678 33428,-3676 33428,-3679 33428,-3679 33433,-3677 33434,-3676 33438,-3681 33440,1319 33444,1321 33441,1325 33444,1329 33439,1326 33444,1326 33439,1327 33439,1327 33440,1332 33444,1333 33449,1338 33453,1338 33450,1343 33450,1347 33454,1346 33457,1346 33455,1342 33459,1341 33462,1346 33462,1347 33463,1343 33463,1344 33462,1348 33457,1347 33460,1352 33464,1356 33468,1361 33469,1363 33468,1365 33469,1368 33472,1369 33475,-2631 33478,-2633 33483,-2629 33486,-2632 34486,-2628 36486,-2625 36488,-2621 36488,-2624 36488,-2622 36492,-2624 36491,-2629 36491,-2627 36496,-2623 36499,-2628 36502,-2631 36506,-2626 36506,-2622 36506,-2622 36509,-2619 36514,-2624 36512,-2621 36510,-2619 36510,-2619 36508,-2617 36512,-2615 36512,-2615 36513,-2615 36511,-2615 36506,-2612 36507,-2609 36511,-2606 37511,-2606 37508,-2610 37505,-2607 37508,-2602 37512,-2599 37512,-2595 37510,-2597 37511,-2592 37515,-2597 37514,-2592 37519,-2592 37524,-2592 37526,-2594 37521,-2594 37516,-2591 36516,-2588 36517,-2589 36513,-2586 36514,-2584 36514,-2583 36516,-2579 36514,-2578 36518,-2578 35518,-2575 35519,-2577 35519,-2578 35524,-2578 35529,-2578 35532,-2578 35534,-2580 35537,-2584 35541,-2586 35542,-2587 35544,-2585 35540,-2585 35544,-2584 35543,-2580 35548,-2576 35550,-2571 35553,-2567 35555,-2565 35560,-2560 35560,-2557 35564,-2553 35564,-5553 36564,-5548 36564,-5544 36565,-5547 36565,-5545 36570,-5542 36565,-5543 36566,-5543 36568,-5543 36570,-5540 36575,-5537 36577,-5535 36581,-5532 36580,-5528 36575,-5526 38575,-5526 38576,-5526 38571,-5522 38571,-5518 38576,-5514 42576,-5510 42581,-5512 42583,-5512 42582,-5507 42582,-5510 42585,-2510 42589,-2511 42592,-2508 42594,-2506 42597,-2503 42598,-2503 42603,-2498 42608,-2501 42611,-2500 42616,-2502 42613,-2502 42616,-4502 42616,-4502 42620,-4502 42622,-4506 42619,-4509 42621,-4511 42624,-4515 42625,-4510 42625,-4507 42628,-4502 42624,-4501 42629,-4505 45629,-4503 45630,-4499 45631,-4496 45630,-4497 45628,-4495 45630,-4494 46630,-4491 46634,-4487 46629,-4483 46631,21336 40532,21341 40533,21346 40534,21346 40536,21345 40536,21346 40536,21345 40536,21344 40538,21347 40543,21348 40543,21351 40540,21351 40542,21348 40545,21351 40546,21352 40546,21353 40546,21358 40546,21359 40545,21359 40550,21357 40555,21362 40560,21364 40555,21363 40555,21364 40560,25364 40564,25365 40566,25368 40566,25371 45566,25372 45567,25372 45562,25376 45564,25381 42564,25385 42560,25389 42564,25389 42568,25393 42572,25390 42572,28390 42569,28389 42570,28385 42574,28386 42576,28389 42577,31389 42578,31385 42582,31387 42582,31390 42578,31391 42579,31392 42576,29392 42580,29396 42582,29398 43582,29402 43584,29406 43585,29407 43587,29411 43592,29413 43594,29414 43595,25414 43600,25412 43595,25415 43599,25420 43602,25418 43604,25423 43599,25426 43599,25429 43602,25434 42602,25429 42604,25432 42600,25435 42605,25436 47605,25440 50605,25441 50610,25439 50614,25444 50617,25447 50621,25444 50624,25444 50626,25445 50627,25450 50632,25450 50628,25451 50630,25451 50632,25454 50633,25458 50637,25462 50641,25463 50640,25463 51640,25467 51644,25469 51649,25473 51650,25474 51653,25475 51654,26475 51658,26475 51662,26474 51665,26476 51665,26481 51661,26483 55661,26485 55664,30485 55667,30485 55670,30489 55671,30489 55668,30491 55670,30492 55670,30493 55675,30497 55675,30501 55671,30503 55676,30500 55677,30498 55672,30494 55675,30499 55676,30500 55676,30505 55681,30501 55684,30496 55685,30500 55685,30502 55687,30506 55692,30507 55693,30506 55692,30511 55693,30516 55694,30514 55699,30514 55701,30512 55701,34512 55705,34516 55708,34520 55704,34518 56704,34519 56704,34520 56706,34517 56706,34515 56701,34519 59701,34522 59706,34522 59708,34522 59713,34526 59715,34528 59717,34533 59712,34538 59715,34538 59717,34541 59717,34546 59720,34548 59721,34552 63721,34547 63726,34549 63728,34554 63726,34556 63726,34557 63721,34556 63725,34561 63730,34558 63730,37558 63725,37561 63729,37565 63724,37569 63720,37573 63718,37578 63722,37577 63718,37579 63720,37579 63722,37580 63719,37580 63720,37579 63724,37574 63725,37574 63727,37576 63725,37581 63729,37583 63732,37586 63732,37590 63737,37592 63734,37597 63731,37600 63730,37596 63731,37596 63733,37600 63733,37601 63735,37596 63735,37591 63732,37596 63733,37601 63738,37602 63733,37599 63738,37594 63740,37598 63744,37603 63745,37605 63747,37607 63752,37607 63756,37603 63757,37603 63761,37604 63761,37608 63758,37609 63762,37604 63764,37604 63764,41604 63765,41600 63761,41599 63761,41600 63766,41596 63766,41599 63766,41601 63770,41604 63768,41608 63768,41611 63772,41614 63767,41609 63763,41612 63765,41615 63760,38615 63764,38615 63768,38618 63768,35618 63769,35618 63774,35617 63775,35618 63776,35613 63775,35615 63780,35612 63782,35613 63779,35614 63775,35618 63774,35619 63776,35624 63778,35624 63780,35629 63785,35629 63780,35626 63781,35624 63782,35629 63784,35634 63787,35638 63782,35634 63783,35634 63778,35633 63777,35638 63782,35641 63786,35644 63791,35648 63793,35647 63793,35649 63797,35653 63801,35654 63804,35654 63804,35656 63804,35655 63806,35658 63810,35658 63805,35662 63805,35657 67805,35658 67808,35660 67811,35664 67808,35660 67803,35658 67803,35661 67803,35663 67808,35666 67810,35670 67814,35669 67813,35669 67816,37669 67820,37664 67820,2275 13363,2278 16363,2274 16363,2275 16362,2279 16362,2282 16362,2287 16366,2284 16366,4284 16366,4286 16371,4290 16375,4294 18375,4295 18377,9295 18381,9296 18381,9299 18382,9303 18379,9305 19379,9308 19375,8308 19380,8312 19380,38746 37651,38749 37652,38754 37653,38757 37656,38753 37661,38753 37661,38758 37663,38763 37664,38763 42664,38768 42666,38765 42668,38770 42664,38767 42659,38768 42659,38773 42654,38771 42659,38775 42661,41775 42663,41778 42665,41781 42669,41782 42667,41779 42669,41784 42672,41781 42672,41783 42672,41780 42672,41783 42675,41784 42675,41788 42676,41792 42677,41792 42675,41793 42680,41793 42676,41796 42681,41801 42685,41804 42684,41806 42685,41804 42690,41802 42692,41805 42696,41800 42697,41802 42698,41804 42700,41809 42704,41813 42705,36813 42708,36813 42704,36810 42703,36811 42705,40811 42706,40815 46706,40816 46708,40820 46708,40818 46712,40822 46717,40825 46720,40829 46724,40827 46727,40831 46727,40833 46731,40829 46733,40830 46733,36830 46738,36830 46741,36834 46744,36831 46749,36826 46748,36822 46748,36824 46751,36819 46755,36823 46758,36823 46762,36824 46766,36822 46769,36826 46772,36831 46774,36828 42774,36833 42776,36833 42777,36838 42782)')));
@@ -211,23 +60,20 @@ DELETE FROM t1 WHERE p = 3;
UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
ROLLBACK;
-connection con1;
+connection control_purge;
# disable purge
-CREATE TABLE t0 (a INT) ENGINE=InnoDB;
-BEGIN;
-SELECT * FROM t0;
-a
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
DELETE FROM t1 WHERE p = 3;
UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
ALTER TABLE t1 ADD INDEX prefix_idx (g(767));
-connection con1;
+connection control_purge;
# enable purge
COMMIT;
connection default;
DELETE FROM t1 WHERE p = 2;
-# wait for purge to process the update_undo records.
+InnoDB 0 transactions not purged
CREATE TABLE t2 (
p INT PRIMARY KEY,
g1 POINT NOT NULL,
@@ -242,15 +88,13 @@ SPATIAL KEY (g3),
SPATIAL KEY (g4),
SPATIAL KEY (g5),
SPATIAL KEY (g6)
-) ENGINE=InnoDB ROW_FORMAT=COMPACT;
-DROP TABLE t2;
-DROP TABLE t1;
-DROP TABLE t0;
+) ENGINE=InnoDB;
+DROP TABLE t1,t2;
CREATE TABLE t1 (
p INT NOT NULL AUTO_INCREMENT,
g LINESTRING NOT NULL,
PRIMARY KEY(p)
-) ENGINE=InnoDB ROW_FORMAT=COMPACT;
+) ENGINE=InnoDB;
ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
ALTER TABLE t1 ADD INDEX prefix_idx (g(767));
INSERT INTO t1(g) VALUES(ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)'));
@@ -261,23 +105,20 @@ DELETE FROM t1 WHERE p = 3;
UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
ROLLBACK;
-connection con1;
+connection control_purge;
# disable purge
-CREATE TABLE t0 (a INT) ENGINE=InnoDB;
-BEGIN;
-SELECT * FROM t0;
-a
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
DELETE FROM t1 WHERE p = 3;
UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
ALTER TABLE t1 DROP INDEX spatial_idx, DROP INDEX prefix_idx;
-connection con1;
+connection control_purge;
# enable purge
COMMIT;
connection default;
DELETE FROM t1 WHERE p = 2;
-# wait for purge to process the update_undo records.
+InnoDB 0 transactions not purged
CREATE TABLE t2 (
p INT PRIMARY KEY,
g1 POINT NOT NULL,
@@ -292,8 +133,7 @@ SPATIAL KEY (g3),
SPATIAL KEY (g4),
SPATIAL KEY (g5),
SPATIAL KEY (g6)
-) ENGINE=InnoDB ROW_FORMAT=COMPACT;
-DROP TABLE t2;
-DROP TABLE t1;
-DROP TABLE t0;
-disconnect con1;
+) ENGINE=InnoDB;
+DROP TABLE t1,t2;
+disconnect control_purge;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb_gis/r/types.result b/mysql-test/suite/innodb_gis/r/types.result
index ac1802085d6..12e1eb44cd7 100644
--- a/mysql-test/suite/innodb_gis/r/types.result
+++ b/mysql-test/suite/innodb_gis/r/types.result
@@ -1,6 +1,3 @@
-SET SESSION debug="+d,row_print_geometry_data";
-Warnings:
-Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
CREATE TABLE t_wl6455 ( i INT, g GEOMETRY NOT NULL) ENGINE=InnoDB;
SHOW CREATE TABLE t_wl6455;
Table Create Table
@@ -53,7 +50,6 @@ COMMIT;
INSERT INTO t_wl6455 VALUES(11, POINT(11,11));
BEGIN;
INSERT INTO t_wl6455 VALUES(1, POINT(1,1));
-# Kill and restart
CHECK TABLE t_wl6455;
Table Op Msg_type Msg_text
test.t_wl6455 check status OK
diff --git a/mysql-test/suite/innodb_gis/t/geometry.test b/mysql-test/suite/innodb_gis/t/geometry.test
index 6450e82e2e4..2d030f90dc9 100644
--- a/mysql-test/suite/innodb_gis/t/geometry.test
+++ b/mysql-test/suite/innodb_gis/t/geometry.test
@@ -9,37 +9,15 @@
# All Geometric functions.
#********************************************************
--source include/have_geometry.inc
---source include/not_embedded.inc
---source include/have_debug.inc
--source include/have_innodb.inc
SET default_storage_engine=InnoDB;
SET innodb_strict_mode=OFF;
-# Turn on the geometry data print.
-SET SESSION debug="+d,row_print_geometry_data";
-
-SHOW VARIABLES LIKE '%engine%';
-
#
# Spatial objects
#
-USE test;
-
---disable_warnings
-DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon;
-DROP TABLE IF EXISTS gis_multi_point, gis_multi_line, gis_multi_polygon;
-DROP TABLE IF EXISTS gis_geometrycollection, gis_geometry;
-DROP TABLE IF EXISTS tab,tab2,tab3,parent,emp2;
-DROP PROCEDURE IF EXISTS geominout;
-DROP PROCEDURE IF EXISTS geom_insert;
-DROP TRIGGER IF EXISTS geom_trigger;
-DROP PROCEDURE IF EXISTS geom_cursor;
-
-
---enable_warnings
-
CREATE TABLE gis_point (fid INTEGER NOT NULL PRIMARY KEY, g POINT) ENGINE=InnoDB;
CREATE TABLE gis_line (fid INTEGER NOT NULL PRIMARY KEY, g LINESTRING) ENGINE=InnoDB;
CREATE TABLE gis_polygon (fid INTEGER NOT NULL PRIMARY KEY, g POLYGON) ENGINE=InnoDB;
@@ -694,11 +672,10 @@ COMMIT;
SELECT COUNT(*) FROM tab3;
-DROP TABLE IF EXISTS gis_point, gis_line, gis_polygon, gis_multi_point;
-DROP TABLE IF EXISTS gis_multi_line, gis_multi_polygon;
-DROP TABLE IF EXISTS gis_geometrycollection, gis_geometry;
-DROP TABLE IF EXISTS tab,tab2,tab3,parent,emp2;
-DROP PROCEDURE IF EXISTS geominout;
-DROP PROCEDURE IF EXISTS geom_insert;
-DROP TRIGGER IF EXISTS geom_trigger;
-DROP PROCEDURE IF EXISTS geom_cursor;
+DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point;
+DROP TABLE gis_multi_line, gis_multi_polygon;
+DROP TABLE gis_geometrycollection, gis_geometry;
+DROP TABLE tab,tab2,tab3,parent,emp2;
+DROP PROCEDURE geominout;
+DROP PROCEDURE geom_insert;
+DROP PROCEDURE geom_cursor;
diff --git a/mysql-test/suite/innodb_gis/t/gis_split_inf.test b/mysql-test/suite/innodb_gis/t/gis_split_inf.test
index 7988ce58f4f..e1b2d4e5947 100644
--- a/mysql-test/suite/innodb_gis/t/gis_split_inf.test
+++ b/mysql-test/suite/innodb_gis/t/gis_split_inf.test
@@ -1,6 +1,4 @@
-
--source include/have_innodb.inc
---source include/have_debug.inc
create table t1(a geometrycollection not null,spatial key(a))engine=innodb;
@@ -24,8 +22,5 @@ insert into t1(a) values( geometrycollection(linestring(point(-33,99), point(
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
drop table t1;
diff --git a/mysql-test/suite/innodb_gis/t/innodb_gis_rtree.test b/mysql-test/suite/innodb_gis/t/innodb_gis_rtree.test
new file mode 100644
index 00000000000..85d6948c8aa
--- /dev/null
+++ b/mysql-test/suite/innodb_gis/t/innodb_gis_rtree.test
@@ -0,0 +1,3 @@
+-- source include/innodb_page_size.inc
+-- source include/innodb_row_format.inc
+-- source ../../../t/gis-rtree.test
diff --git a/mysql-test/suite/innodb_gis/t/kill_server.test b/mysql-test/suite/innodb_gis/t/kill_server.test
index 9b6469606ca..028bbbdd40d 100644
--- a/mysql-test/suite/innodb_gis/t/kill_server.test
+++ b/mysql-test/suite/innodb_gis/t/kill_server.test
@@ -58,7 +58,8 @@ CALL insert_t1(5000);
COMMIT;
---source include/kill_and_restart_mysqld.inc
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
# Clean up.
drop procedure insert_t1;
diff --git a/mysql-test/suite/innodb_gis/t/row_format.test b/mysql-test/suite/innodb_gis/t/row_format.test
deleted file mode 100644
index 23c08dae5e6..00000000000
--- a/mysql-test/suite/innodb_gis/t/row_format.test
+++ /dev/null
@@ -1,34 +0,0 @@
---source include/not_embedded.inc
---source include/have_innodb.inc
---source include/innodb_page_size_small.inc
-
-# Test the redundant format
-LET $file_per_table='off';
-LET $file_format='Antelope';
-LET $row_format=REDUNDANT;
-
---source include/innodb_gis_row_format_basic.inc
-
-
-# Test the compressed format
-LET $file_per_table='on';
-LET $file_format='Barracuda';
-LET $row_format=COMPRESSED;
-
---source include/innodb_gis_row_format_basic.inc
-
-
-# Test the dynamic format
-LET $file_per_table='on';
-LET $file_format='Barracuda';
-LET $row_format=DYNAMIC;
-
---source include/innodb_gis_row_format_basic.inc
-
-# Test the compact format
-LET $file_per_table='off';
-LET $file_format='Antelope';
-LET $row_format=COMPACT;
-
---source include/innodb_gis_row_format_basic.inc
-
diff --git a/mysql-test/suite/innodb_gis/t/rtree_compress.test b/mysql-test/suite/innodb_gis/t/rtree_compress.test
index 946a336a4d0..a3d1e883a45 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_compress.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_compress.test
@@ -4,17 +4,15 @@
# Not supported in embedded
--source include/not_embedded.inc
---source include/have_innodb.inc
---source include/have_innodb_zip.inc
+--source include/innodb_page_size_small.inc
--source include/have_debug.inc
--source include/big_test.inc
# Valgrind takes too much time on PB2 even in the --big-test runs.
--source include/not_valgrind.inc
-# Create table with R-tree index.
-SET GLOBAL innodb_file_per_table=1;
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
-#Create table with R-tree index.
create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb ROW_FORMAT=COMPRESSED;
# Insert enough values to let R-tree split.
@@ -53,12 +51,14 @@ select count(*) from t1 where MBRWithin(t1.c2, @g1);
set @g1 = ST_GeomFromText('Polygon((10 10,10 800,800 800,800 10,10 10))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
+SET @saved_dbug = @@SESSION.debug_dbug;
SET DEBUG='+d,page_copy_rec_list_start_compress_fail';
delete from t1;
-SET DEBUG='-d,page_copy_rec_list_start_compress_fail';
-
-
select count(*) from t1 where MBRWithin(t1.c2, @g1);
+SET debug_dbug = @saved_dbug;
+
+--source ../../innodb/include/wait_all_purged.inc
# Clean up.
drop table t1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb_gis/t/rtree_compress2.test b/mysql-test/suite/innodb_gis/t/rtree_compress2.test
index 5956fc9a774..c02a6ff0ed4 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_compress2.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_compress2.test
@@ -4,8 +4,7 @@
# Restarting is not supported in embedded
--source include/not_embedded.inc
---source include/have_innodb.inc
---source include/have_innodb_zip.inc
+--source include/innodb_page_size_small.inc
--source include/big_test.inc
# Valgrind takes too much time on PB2 even in the --big-test runs.
--source include/not_valgrind.inc
@@ -29,29 +28,13 @@ delimiter ;|
# Test level 3 rtree.
CALL insert_t1(70000);
-select count(*) from t1;
-
-# Check table.
-check table t1;
-
-truncate table t1;
-
-# Test crash recovery.
-#
-#
-call mtr.add_suppression("InnoDB: A copy of page \[page id: space=[0-9]+, page number=[0-9]+\] in the doublewrite buffer slot [0-9]+ is not within space bounds");
-# Test rtree enlarge recovery.
-START TRANSACTION;
-CALL insert_t1(5000);
-#select count(*) from t1;
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
-# Check table.
-#check table t1;
-
-COMMIT;
-
---source include/kill_and_restart_mysqld.inc
+check table t1;
+select count(*) from t1;
+delete from t1;
# Clean up.
drop procedure insert_t1;
diff --git a/mysql-test/suite/innodb_gis/t/rtree_concurrent_srch.test b/mysql-test/suite/innodb_gis/t/rtree_concurrent_srch.test
index ec6f496b5cc..c10ce368b11 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_concurrent_srch.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_concurrent_srch.test
@@ -1,9 +1,6 @@
# WL#6745 InnoDB R-tree support
# This test case will test R-tree split.
-# Not supported in embedded
---source include/not_embedded.inc
-
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
@@ -32,8 +29,7 @@ insert into t1 select * from t1;
insert into t1 select * from t1;
connect (a,localhost,root,,);
-connection a;
-SET SESSION debug="+d,rtr_pcur_move_to_next_return";
+SET debug_dbug='+d,rtr_pcur_move_to_next_return';
set session transaction isolation level serializable;
set @g1 = ST_GeomFromText('Polygon((0 0,0 100,100 100,100 0,0 0))');
@@ -41,9 +37,7 @@ SET DEBUG_SYNC = 'RESET';
SET DEBUG_SYNC = 'row_search_for_mysql_before_return SIGNAL started WAIT_FOR go_ahead';
--send select count(*) from t1 where MBRWithin(t1.c2, @g1);
---echo # Establish session con1 (user=root)
connect (con1,localhost,root,,);
-connection con1;
set session transaction isolation level serializable;
SET DEBUG_SYNC = 'now WAIT_FOR started';
@@ -92,7 +86,6 @@ select count(*) from t1 where MBRwithin(t1.c2, @g1);
# The split will replicate locks across pages
connect (b,localhost,root,,);
-connection b;
set session transaction isolation level serializable;
set session innodb_lock_wait_timeout = 1;
@@ -292,15 +285,8 @@ insert into t1 values (1200, Point(950, 950));
connection a;
select sleep(2);
commit;
-
-connection a;
-SET SESSION debug="-d,rtr_pcur_move_to_next_return";
disconnect a;
---source include/wait_until_disconnected.inc
-
-connection b;
disconnect b;
---source include/wait_until_disconnected.inc
# Clean up.
connection default;
@@ -321,7 +307,6 @@ INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(7 7, 200 200)'));
INSERT INTO t1 VALUES (1, ST_GeomFromText('LineString(8 8, 210 210)'));
connect (a,localhost,root,,);
-connection a;
SET SESSION debug="+d,rtr_pcur_move_to_next_return";
set transaction isolation level serializable;
@@ -330,7 +315,6 @@ set @g1 = ST_GeomFromText('Polygon((100 100, 100 110, 110 110, 110 100, 100 100)
select count(*) from t1 where MBRwithin(t1.c2, @g1);
connect (b,localhost,root,,);
-connection b;
# This should be successful
delete from t1 where c1 = 1;
@@ -432,20 +416,14 @@ rollback;
SET DEBUG_SYNC= 'now SIGNAL sigb';
connection a;
---reap;
+reap;
connection default;
drop procedure insert_t1;
DROP TABLE t1;
-connection a;
-SET SESSION debug="-d,rtr_pcur_move_to_next_return";
disconnect a;
---source include/wait_until_disconnected.inc
-
-connection b;
disconnect b;
---source include/wait_until_disconnected.inc
connection default;
SET DEBUG_SYNC = 'RESET';
diff --git a/mysql-test/suite/innodb_gis/t/rtree_debug.test b/mysql-test/suite/innodb_gis/t/rtree_debug.test
index 3ba8ecc0655..2f7c2806c68 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_debug.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_debug.test
@@ -49,10 +49,11 @@ create spatial index idx on t1(c2);
show create table t1;
-SET DEBUG='+d,row_merge_ins_spatial_fail';
+SET @save_dbug = @@SESSION.debug_dbug;
+SET debug_dbug='+d,row_merge_ins_spatial_fail';
--error ER_GET_ERRNO
create spatial index idx2 on t1(c2);
-SET DEBUG='-d,row_merge_ins_spatial_fail';
+SET debug_dbug = @save_dbug;
show create table t1;
# Check table.
diff --git a/mysql-test/suite/innodb_gis/t/rtree_old.test b/mysql-test/suite/innodb_gis/t/rtree_old.test
deleted file mode 100644
index 0c793488bf3..00000000000
--- a/mysql-test/suite/innodb_gis/t/rtree_old.test
+++ /dev/null
@@ -1,1015 +0,0 @@
-# This is a testcase ported from mysql-test/t/gis-rtree.test
-
--- source include/have_geometry.inc
--- source include/have_innodb.inc
-
-#
-# test of rtree (using with spatial data)
-#
---disable_warnings
-DROP TABLE IF EXISTS t1, t2;
---enable_warnings
-
-CREATE TABLE t1 (
- fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
- g GEOMETRY NOT NULL,
- SPATIAL KEY(g)
-) ENGINE=InnoDB;
-
-SHOW CREATE TABLE t1;
-
-let $1=150;
-let $2=150;
-while ($1)
-{
- eval INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString($1 $1, $2 $2)'));
- dec $1;
- inc $2;
-}
-
-SELECT count(*) FROM t1;
-SELECT fid, ST_AsText(g) FROM t1 WHERE MBRWithin(g, ST_GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))')) ORDER BY fid;
-
-DROP TABLE t1;
-
-CREATE TABLE t2 (
- fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
- g GEOMETRY NOT NULL
-) ENGINE=InnoDB;
-
-let $1=10;
-while ($1)
-{
- let $2=10;
- while ($2)
- {
- eval INSERT INTO t2 (g) VALUES (LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10)));
- dec $2;
- }
- dec $1;
-}
-
-ALTER TABLE t2 ADD SPATIAL KEY(g);
-SHOW CREATE TABLE t2;
-SELECT count(*) FROM t2;
-SELECT fid, ST_AsText(g) FROM t2 WHERE MBRWithin(g,
- ST_GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))')) ORDER BY fid;
-
-let $1=10;
-while ($1)
-{
- let $2=10;
- while ($2)
- {
- eval DELETE FROM t2 WHERE MBRWithin(g, ST_Envelope(ST_GeometryFromWKB(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10))));
- SELECT count(*) FROM t2;
- dec $2;
- }
- dec $1;
-}
-
-DROP TABLE t2;
-
-drop table if exists t1;
-CREATE TABLE t1 (a geometry NOT NULL, SPATIAL (a));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-INSERT INTO t1 VALUES (ST_GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
-check table t1;
-analyze table t1;
-drop table t1;
-
-#
-# The following crashed gis
-#
-
-CREATE TABLE t1 (
- fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
- g GEOMETRY NOT NULL,
- SPATIAL KEY(g)
-) ENGINE=InnoDB;
-
-INSERT INTO t1 (g) VALUES (ST_GeomFromText('LineString(1 2, 2 3)')),(ST_GeomFromText('LineString(1 2, 2 4)'));
-#select * from t1 where g<ST_GeomFromText('LineString(1 2, 2 3)');
-drop table t1;
-
-CREATE TABLE t1 (
- line LINESTRING NOT NULL,
- kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
- name VARCHAR(32),
-
- SPATIAL KEY (line)
-
-
-) engine=InnoDB;
-
-ALTER TABLE t1 DISABLE KEYS;
---error ER_CANT_CREATE_GEOMETRY_OBJECT
-INSERT INTO t1 (name, kind, line) VALUES
- ("Aadaouane", "pp", ST_GeomFromText("POINT(32.816667 35.983333)")),
- ("Aadassiye", "pp", ST_GeomFromText("POINT(35.816667 36.216667)")),
- ("Aadbel", "pp", ST_GeomFromText("POINT(34.533333 36.100000)")),
- ("Aadchit", "pp", ST_GeomFromText("POINT(33.347222 35.423611)")),
- ("Aadchite", "pp", ST_GeomFromText("POINT(33.347222 35.423611)")),
- ("Aadchit el Qoussair", "pp", ST_GeomFromText("POINT(33.283333 35.483333)")),
- ("Aaddaye", "pp", ST_GeomFromText("POINT(36.716667 40.833333)")),
- ("'Aadeissa", "pp", ST_GeomFromText("POINT(32.823889 35.698889)")),
- ("Aaderup", "pp", ST_GeomFromText("POINT(55.216667 11.766667)")),
- ("Qalaat Aades", "pp", ST_GeomFromText("POINT(33.503333 35.377500)")),
- ("A ad'ino", "pp", ST_GeomFromText("POINT(54.812222 38.209167)")),
- ("Aadi Noia", "pp", ST_GeomFromText("POINT(13.800000 39.833333)")),
- ("Aad La Macta", "pp", ST_GeomFromText("POINT(35.779444 -0.129167)")),
- ("Aadland", "pp", ST_GeomFromText("POINT(60.366667 5.483333)")),
- ("Aadliye", "pp", ST_GeomFromText("POINT(33.366667 36.333333)")),
- ("Aadloun", "pp", ST_GeomFromText("POINT(33.403889 35.273889)")),
- ("Aadma", "pp", ST_GeomFromText("POINT(58.798333 22.663889)")),
- ("Aadma Asundus", "pp", ST_GeomFromText("POINT(58.798333 22.663889)")),
- ("Aadmoun", "pp", ST_GeomFromText("POINT(34.150000 35.650000)")),
- ("Aadneram", "pp", ST_GeomFromText("POINT(59.016667 6.933333)")),
- ("Aadneskaar", "pp", ST_GeomFromText("POINT(58.083333 6.983333)")),
- ("Aadorf", "pp", ST_GeomFromText("POINT(47.483333 8.900000)")),
- ("Aadorp", "pp", ST_GeomFromText("POINT(52.366667 6.633333)")),
- ("Aadouane", "pp", ST_GeomFromText("POINT(32.816667 35.983333)")),
- ("Aadoui", "pp", ST_GeomFromText("POINT(34.450000 35.983333)")),
- ("Aadouiye", "pp", ST_GeomFromText("POINT(34.583333 36.183333)")),
- ("Aadouss", "pp", ST_GeomFromText("POINT(33.512500 35.601389)")),
- ("Aadra", "pp", ST_GeomFromText("POINT(33.616667 36.500000)")),
- ("Aadzi", "pp", ST_GeomFromText("POINT(38.100000 64.850000)"));
-
-ALTER TABLE t1 ENABLE KEYS;
-INSERT INTO t1 (name, kind, line) VALUES ("austria", "pp", ST_GeomFromText('LINESTRING(14.9906 48.9887,14.9946 48.9904,14.9947 48.9916)'));
-drop table t1;
-
-CREATE TABLE t1 (st varchar(100));
-INSERT INTO t1 VALUES ("Fake string");
-CREATE TABLE t2 (geom GEOMETRY NOT NULL, SPATIAL KEY gk(geom));
---error ER_GIS_INVALID_DATA
-INSERT INTO t2 SELECT ST_GeomFromText(st) FROM t1;
-drop table t1, t2;
-
-SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
-CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000
--66.8158332999, -18.7186111000 -66.8102777000, -18.7211111000 -66.9269443999,
--18.6086111000 -66.9327777000))'));
-
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((-65.7402776999 -96.6686111000, -65.7372222000
--96.5516666000, -65.8502777000 -96.5461111000, -65.8527777000 -96.6627777000,
--65.7402776999 -96.6686111000))'));
-check table t1 extended;
-
-drop table t1;
-
-CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((2 2, 2 8, 10 8, 10 2, 2 2))'));
-
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((2 12, 15 12, 15 18, 2 18, 2 12))'));
-
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((3 5, 3 18, 10 18, 10 5, 3 5))'));
-
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((4 6, 4 8, 10 8, 10 4, 4 6))'));
-
-set @g1 = ST_GeomFromText('Polygon((0 0,0 1000,1000 1000,1000 0,0 0))');
-
-select count(*) from t1 where MBRWithin(t1.geometry, @g1);
-
-start transaction;
-
-INSERT INTO t1 (geometry) VALUES
-(ST_PolygonFromText('POLYGON((4 6, 4 8, 10 8, 10 4, 4 6))'));
-
-select count(*) from t1 where MBRWithin(t1.geometry, @g1);
-
-rollback;
-
-select count(*) from t1 where MBRWithin(t1.geometry, @g1);
-
-set @g2 = ST_GeomFromText('POINT(2 2)');
-
-select count(*) from t1 where MBRcontains(t1.geometry, @g2);
-
-select count(*) from t1 where MBRintersects(t1.geometry, @g2);
-
-set @g3 = ST_GeomFromText('LINESTRING(2 2, 2 12)');
-
-select count(*) from t1 where MBRintersects(t1.geometry, @g3);
-
-DROP TABLE t1;
-
-#
-# Bug#17877 - Corrupted spatial index
-#
-CREATE TABLE t1 (
- c1 geometry NOT NULL default '',
- SPATIAL KEY i1 (c1)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-INSERT INTO t1 (c1) VALUES (
- ST_PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
- -18.6055555000 -66.8158332999,
- -18.7186111000 -66.8102777000,
- -18.7211111000 -66.9269443999,
- -18.6086111000 -66.9327777000))'));
-# This showed a missing key.
-CHECK TABLE t1 EXTENDED;
-DROP TABLE t1;
-#
-CREATE TABLE t1 (
- c1 geometry NOT NULL default '',
- SPATIAL KEY i1 (c1)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-INSERT INTO t1 (c1) VALUES (
- ST_PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
- -18.6055555000 -66.8158332999,
- -18.7186111000 -66.8102777000,
- -18.7211111000 -66.9269443999,
- -18.6086111000 -66.9327777000))'));
-INSERT INTO t1 (c1) VALUES (
- ST_PolygonFromText('POLYGON((-65.7402776999 -96.6686111000,
- -65.7372222000 -96.5516666000,
- -65.8502777000 -96.5461111000,
- -65.8527777000 -96.6627777000,
- -65.7402776999 -96.6686111000))'));
-# This is the same as the first insert to get a non-unique key.
-INSERT INTO t1 (c1) VALUES (
- ST_PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
- -18.6055555000 -66.8158332999,
- -18.7186111000 -66.8102777000,
- -18.7211111000 -66.9269443999,
- -18.6086111000 -66.9327777000))'));
-# This showed (and still shows) OK.
-CHECK TABLE t1 EXTENDED;
-DROP TABLE t1;
-SET sql_mode = default;
-
-#
-# Bug #21888: Query on GEOMETRY field using PointFromWKB() results in lost connection
-#
-CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
-INSERT INTO t1 (foo) VALUES (POINT(1,1));
-INSERT INTO t1 (foo) VALUES (POINT(1,0));
-INSERT INTO t1 (foo) VALUES (POINT(0,1));
-INSERT INTO t1 (foo) VALUES (POINT(0,0));
-SELECT 1 FROM t1 WHERE foo != POINT(0,0);
-DROP TABLE t1;
-
-#
-# Bug#25673 - spatial index corruption, error 126 incorrect key file for table
-#
-CREATE TABLE t1 (id bigint(12) unsigned NOT NULL auto_increment,
- c2 varchar(15) collate utf8_bin default NULL,
- c1 varchar(15) collate utf8_bin default NULL,
- c3 varchar(10) collate utf8_bin default NULL,
- spatial_point point NOT NULL,
- PRIMARY KEY(id),
- SPATIAL KEY (spatial_point)
- )ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-#
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
- ('y', 's', 'j', ST_GeomFromText('POINT(167 74)')),
- ('r', 'n', 'd', ST_GeomFromText('POINT(215 118)')),
- ('g', 'n', 'e', ST_GeomFromText('POINT(203 98)')),
- ('h', 'd', 'd', ST_GeomFromText('POINT(54 193)')),
- ('r', 'x', 'y', ST_GeomFromText('POINT(47 69)')),
- ('t', 'q', 'r', ST_GeomFromText('POINT(109 42)')),
- ('a', 'z', 'd', ST_GeomFromText('POINT(0 154)')),
- ('x', 'v', 'o', ST_GeomFromText('POINT(174 131)')),
- ('b', 'r', 'a', ST_GeomFromText('POINT(114 253)')),
- ('x', 'z', 'i', ST_GeomFromText('POINT(163 21)')),
- ('w', 'p', 'i', ST_GeomFromText('POINT(42 102)')),
- ('g', 'j', 'j', ST_GeomFromText('POINT(170 133)')),
- ('m', 'g', 'n', ST_GeomFromText('POINT(28 22)')),
- ('b', 'z', 'h', ST_GeomFromText('POINT(174 28)')),
- ('q', 'k', 'f', ST_GeomFromText('POINT(233 73)')),
- ('w', 'w', 'a', ST_GeomFromText('POINT(124 200)')),
- ('t', 'j', 'w', ST_GeomFromText('POINT(252 101)')),
- ('d', 'r', 'd', ST_GeomFromText('POINT(98 18)')),
- ('w', 'o', 'y', ST_GeomFromText('POINT(165 31)')),
- ('y', 'h', 't', ST_GeomFromText('POINT(14 220)')),
- ('d', 'p', 'u', ST_GeomFromText('POINT(223 196)')),
- ('g', 'y', 'g', ST_GeomFromText('POINT(207 96)')),
- ('x', 'm', 'n', ST_GeomFromText('POINT(214 3)')),
- ('g', 'v', 'e', ST_GeomFromText('POINT(140 205)')),
- ('g', 'm', 'm', ST_GeomFromText('POINT(10 236)')),
- ('i', 'r', 'j', ST_GeomFromText('POINT(137 228)')),
- ('w', 's', 'p', ST_GeomFromText('POINT(115 6)')),
- ('o', 'n', 'k', ST_GeomFromText('POINT(158 129)')),
- ('j', 'h', 'l', ST_GeomFromText('POINT(129 72)')),
- ('f', 'x', 'l', ST_GeomFromText('POINT(139 207)')),
- ('u', 'd', 'n', ST_GeomFromText('POINT(125 109)')),
- ('b', 'a', 'z', ST_GeomFromText('POINT(30 32)')),
- ('m', 'h', 'o', ST_GeomFromText('POINT(251 251)')),
- ('f', 'r', 'd', ST_GeomFromText('POINT(243 211)')),
- ('b', 'd', 'r', ST_GeomFromText('POINT(232 80)')),
- ('g', 'k', 'v', ST_GeomFromText('POINT(15 100)')),
- ('i', 'f', 'c', ST_GeomFromText('POINT(109 66)')),
- ('r', 't', 'j', ST_GeomFromText('POINT(178 6)')),
- ('y', 'n', 'f', ST_GeomFromText('POINT(233 211)')),
- ('f', 'y', 'm', ST_GeomFromText('POINT(99 16)')),
- ('z', 'q', 'l', ST_GeomFromText('POINT(39 49)')),
- ('j', 'c', 'r', ST_GeomFromText('POINT(75 187)')),
- ('c', 'y', 'y', ST_GeomFromText('POINT(246 253)')),
- ('w', 'u', 'd', ST_GeomFromText('POINT(56 190)')),
- ('n', 'q', 'm', ST_GeomFromText('POINT(73 149)')),
- ('d', 'y', 'a', ST_GeomFromText('POINT(134 6)')),
- ('z', 's', 'w', ST_GeomFromText('POINT(216 225)')),
- ('d', 'u', 'k', ST_GeomFromText('POINT(132 70)')),
- ('f', 'v', 't', ST_GeomFromText('POINT(187 141)')),
- ('r', 'r', 'a', ST_GeomFromText('POINT(152 39)')),
- ('y', 'p', 'o', ST_GeomFromText('POINT(45 27)')),
- ('p', 'n', 'm', ST_GeomFromText('POINT(228 148)')),
- ('e', 'g', 'e', ST_GeomFromText('POINT(88 81)')),
- ('m', 'a', 'h', ST_GeomFromText('POINT(35 29)')),
- ('m', 'h', 'f', ST_GeomFromText('POINT(30 71)')),
- ('h', 'k', 'i', ST_GeomFromText('POINT(244 78)')),
- ('z', 'v', 'd', ST_GeomFromText('POINT(241 38)')),
- ('q', 'l', 'j', ST_GeomFromText('POINT(13 71)')),
- ('s', 'p', 'g', ST_GeomFromText('POINT(108 38)')),
- ('q', 's', 'j', ST_GeomFromText('POINT(92 101)')),
- ('l', 'h', 'g', ST_GeomFromText('POINT(120 78)')),
- ('w', 't', 'b', ST_GeomFromText('POINT(193 109)')),
- ('b', 's', 's', ST_GeomFromText('POINT(223 211)')),
- ('w', 'w', 'y', ST_GeomFromText('POINT(122 42)')),
- ('q', 'c', 'c', ST_GeomFromText('POINT(104 102)')),
- ('w', 'g', 'n', ST_GeomFromText('POINT(213 120)')),
- ('p', 'q', 'a', ST_GeomFromText('POINT(247 148)')),
- ('c', 'z', 'e', ST_GeomFromText('POINT(18 106)')),
- ('z', 'u', 'n', ST_GeomFromText('POINT(70 133)')),
- ('j', 'n', 'x', ST_GeomFromText('POINT(232 13)')),
- ('e', 'h', 'f', ST_GeomFromText('POINT(22 135)')),
- ('w', 'l', 'f', ST_GeomFromText('POINT(9 180)')),
- ('a', 'v', 'q', ST_GeomFromText('POINT(163 228)')),
- ('i', 'z', 'o', ST_GeomFromText('POINT(180 100)')),
- ('e', 'c', 'l', ST_GeomFromText('POINT(182 231)')),
- ('c', 'k', 'o', ST_GeomFromText('POINT(19 60)')),
- ('q', 'f', 'p', ST_GeomFromText('POINT(79 95)')),
- ('m', 'd', 'r', ST_GeomFromText('POINT(3 127)')),
- ('m', 'e', 't', ST_GeomFromText('POINT(136 154)')),
- ('w', 'w', 'w', ST_GeomFromText('POINT(102 15)')),
- ('l', 'n', 'q', ST_GeomFromText('POINT(71 196)')),
- ('p', 'k', 'c', ST_GeomFromText('POINT(47 139)')),
- ('j', 'o', 'r', ST_GeomFromText('POINT(177 128)')),
- ('j', 'q', 'a', ST_GeomFromText('POINT(170 6)')),
- ('b', 'a', 'o', ST_GeomFromText('POINT(63 211)')),
- ('g', 's', 'o', ST_GeomFromText('POINT(144 251)')),
- ('w', 'u', 'w', ST_GeomFromText('POINT(221 214)')),
- ('g', 'a', 'm', ST_GeomFromText('POINT(14 102)')),
- ('u', 'q', 'z', ST_GeomFromText('POINT(86 200)')),
- ('k', 'a', 'm', ST_GeomFromText('POINT(144 222)')),
- ('j', 'u', 'r', ST_GeomFromText('POINT(216 142)')),
- ('q', 'k', 'v', ST_GeomFromText('POINT(121 236)')),
- ('p', 'o', 'r', ST_GeomFromText('POINT(108 102)')),
- ('b', 'd', 'x', ST_GeomFromText('POINT(127 198)')),
- ('k', 's', 'a', ST_GeomFromText('POINT(2 150)')),
- ('f', 'm', 'f', ST_GeomFromText('POINT(160 191)')),
- ('q', 'y', 'x', ST_GeomFromText('POINT(98 111)')),
- ('o', 'f', 'm', ST_GeomFromText('POINT(232 218)')),
- ('c', 'w', 'j', ST_GeomFromText('POINT(156 165)')),
- ('s', 'q', 'v', ST_GeomFromText('POINT(98 161)'));
-SET @@RAND_SEED1=692635050, @@RAND_SEED2=297339954;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=159925977, @@RAND_SEED2=942570618;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=328169745, @@RAND_SEED2=410451954;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=178507359, @@RAND_SEED2=332493072;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=1034033013, @@RAND_SEED2=558966507;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(230 9)') where c1 like 'y%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(95 35)') where c1 like 'j%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(93 99)') where c1 like 'a%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(19 81)') where c1 like 'r%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(20 177)') where c1 like 'h%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(221 193)') where c1 like 'u%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(195 205)') where c1 like 'd%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(15 213)') where c1 like 'u%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(214 63)') where c1 like 'n%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(243 171)') where c1 like 'c%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(198 82)') where c1 like 'y%';
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
- ('f', 'y', 'p', ST_GeomFromText('POINT(109 235)')),
- ('b', 'e', 'v', ST_GeomFromText('POINT(20 48)')),
- ('i', 'u', 'f', ST_GeomFromText('POINT(15 55)')),
- ('o', 'r', 'z', ST_GeomFromText('POINT(105 64)')),
- ('a', 'p', 'a', ST_GeomFromText('POINT(142 236)')),
- ('g', 'i', 'k', ST_GeomFromText('POINT(10 49)')),
- ('x', 'z', 'x', ST_GeomFromText('POINT(192 200)')),
- ('c', 'v', 'r', ST_GeomFromText('POINT(94 168)')),
- ('y', 'z', 'e', ST_GeomFromText('POINT(141 51)')),
- ('h', 'm', 'd', ST_GeomFromText('POINT(35 251)')),
- ('v', 'm', 'q', ST_GeomFromText('POINT(44 90)')),
- ('j', 'l', 'z', ST_GeomFromText('POINT(67 237)')),
- ('i', 'v', 'a', ST_GeomFromText('POINT(75 14)')),
- ('b', 'q', 't', ST_GeomFromText('POINT(153 33)')),
- ('e', 'm', 'a', ST_GeomFromText('POINT(247 49)')),
- ('l', 'y', 'g', ST_GeomFromText('POINT(56 203)')),
- ('v', 'o', 'r', ST_GeomFromText('POINT(90 54)')),
- ('r', 'n', 'd', ST_GeomFromText('POINT(135 83)')),
- ('j', 't', 'u', ST_GeomFromText('POINT(174 239)')),
- ('u', 'n', 'g', ST_GeomFromText('POINT(104 191)')),
- ('p', 'q', 'y', ST_GeomFromText('POINT(63 171)')),
- ('o', 'q', 'p', ST_GeomFromText('POINT(192 103)')),
- ('f', 'x', 'e', ST_GeomFromText('POINT(244 30)')),
- ('n', 'x', 'c', ST_GeomFromText('POINT(92 103)')),
- ('r', 'q', 'z', ST_GeomFromText('POINT(166 20)')),
- ('s', 'a', 'j', ST_GeomFromText('POINT(137 205)')),
- ('z', 't', 't', ST_GeomFromText('POINT(99 134)')),
- ('o', 'm', 'j', ST_GeomFromText('POINT(217 3)')),
- ('n', 'h', 'j', ST_GeomFromText('POINT(211 17)')),
- ('v', 'v', 'a', ST_GeomFromText('POINT(41 137)')),
- ('q', 'o', 'j', ST_GeomFromText('POINT(5 92)')),
- ('z', 'y', 'e', ST_GeomFromText('POINT(175 212)')),
- ('j', 'z', 'h', ST_GeomFromText('POINT(224 194)')),
- ('a', 'g', 'm', ST_GeomFromText('POINT(31 119)')),
- ('p', 'c', 'f', ST_GeomFromText('POINT(17 221)')),
- ('t', 'h', 'k', ST_GeomFromText('POINT(26 203)')),
- ('u', 'w', 'p', ST_GeomFromText('POINT(47 185)')),
- ('z', 'a', 'c', ST_GeomFromText('POINT(61 133)')),
- ('u', 'k', 'a', ST_GeomFromText('POINT(210 115)')),
- ('k', 'f', 'h', ST_GeomFromText('POINT(125 113)')),
- ('t', 'v', 'y', ST_GeomFromText('POINT(12 239)')),
- ('u', 'v', 'd', ST_GeomFromText('POINT(90 24)')),
- ('m', 'y', 'w', ST_GeomFromText('POINT(25 243)')),
- ('d', 'n', 'g', ST_GeomFromText('POINT(122 92)')),
- ('z', 'm', 'f', ST_GeomFromText('POINT(235 110)')),
- ('q', 'd', 'f', ST_GeomFromText('POINT(233 217)')),
- ('a', 'v', 'u', ST_GeomFromText('POINT(69 59)')),
- ('x', 'k', 'p', ST_GeomFromText('POINT(240 14)')),
- ('i', 'v', 'r', ST_GeomFromText('POINT(154 42)')),
- ('w', 'h', 'l', ST_GeomFromText('POINT(178 156)')),
- ('d', 'h', 'n', ST_GeomFromText('POINT(65 157)')),
- ('c', 'k', 'z', ST_GeomFromText('POINT(62 33)')),
- ('e', 'l', 'w', ST_GeomFromText('POINT(162 1)')),
- ('r', 'f', 'i', ST_GeomFromText('POINT(127 71)')),
- ('q', 'm', 'c', ST_GeomFromText('POINT(63 118)')),
- ('c', 'h', 'u', ST_GeomFromText('POINT(205 203)')),
- ('d', 't', 'p', ST_GeomFromText('POINT(234 87)')),
- ('s', 'g', 'h', ST_GeomFromText('POINT(149 34)')),
- ('o', 'b', 'q', ST_GeomFromText('POINT(159 179)')),
- ('k', 'u', 'f', ST_GeomFromText('POINT(202 254)')),
- ('u', 'f', 'g', ST_GeomFromText('POINT(70 15)')),
- ('x', 's', 'b', ST_GeomFromText('POINT(25 181)')),
- ('s', 'c', 'g', ST_GeomFromText('POINT(252 17)')),
- ('a', 'c', 'f', ST_GeomFromText('POINT(89 67)')),
- ('r', 'e', 'q', ST_GeomFromText('POINT(55 54)')),
- ('f', 'i', 'k', ST_GeomFromText('POINT(178 230)')),
- ('p', 'e', 'l', ST_GeomFromText('POINT(198 28)')),
- ('w', 'o', 'd', ST_GeomFromText('POINT(204 189)')),
- ('c', 'a', 'g', ST_GeomFromText('POINT(230 178)')),
- ('r', 'o', 'e', ST_GeomFromText('POINT(61 116)')),
- ('w', 'a', 'a', ST_GeomFromText('POINT(178 237)')),
- ('v', 'd', 'e', ST_GeomFromText('POINT(70 85)')),
- ('k', 'c', 'e', ST_GeomFromText('POINT(147 118)')),
- ('d', 'q', 't', ST_GeomFromText('POINT(218 77)')),
- ('k', 'g', 'f', ST_GeomFromText('POINT(192 113)')),
- ('w', 'n', 'e', ST_GeomFromText('POINT(92 124)')),
- ('r', 'm', 'q', ST_GeomFromText('POINT(130 65)')),
- ('o', 'r', 'r', ST_GeomFromText('POINT(174 233)')),
- ('k', 'n', 't', ST_GeomFromText('POINT(175 147)')),
- ('q', 'm', 'r', ST_GeomFromText('POINT(18 208)')),
- ('l', 'd', 'i', ST_GeomFromText('POINT(13 104)')),
- ('w', 'o', 'y', ST_GeomFromText('POINT(207 39)')),
- ('p', 'u', 'o', ST_GeomFromText('POINT(114 31)')),
- ('y', 'a', 'p', ST_GeomFromText('POINT(106 59)')),
- ('a', 'x', 'z', ST_GeomFromText('POINT(17 57)')),
- ('v', 'h', 'x', ST_GeomFromText('POINT(170 13)')),
- ('t', 's', 'u', ST_GeomFromText('POINT(84 18)')),
- ('z', 'z', 'f', ST_GeomFromText('POINT(250 197)')),
- ('l', 'z', 't', ST_GeomFromText('POINT(59 80)')),
- ('j', 'g', 's', ST_GeomFromText('POINT(54 26)')),
- ('g', 'v', 'm', ST_GeomFromText('POINT(89 98)')),
- ('q', 'v', 'b', ST_GeomFromText('POINT(39 240)')),
- ('x', 'k', 'v', ST_GeomFromText('POINT(246 207)')),
- ('k', 'u', 'i', ST_GeomFromText('POINT(105 111)')),
- ('w', 'z', 's', ST_GeomFromText('POINT(235 8)')),
- ('d', 'd', 'd', ST_GeomFromText('POINT(105 4)')),
- ('c', 'z', 'q', ST_GeomFromText('POINT(13 140)')),
- ('m', 'k', 'i', ST_GeomFromText('POINT(208 120)')),
- ('g', 'a', 'g', ST_GeomFromText('POINT(9 182)')),
- ('z', 'j', 'r', ST_GeomFromText('POINT(149 153)')),
- ('h', 'f', 'g', ST_GeomFromText('POINT(81 236)')),
- ('m', 'e', 'q', ST_GeomFromText('POINT(209 215)')),
- ('c', 'h', 'y', ST_GeomFromText('POINT(235 70)')),
- ('i', 'e', 'g', ST_GeomFromText('POINT(138 26)')),
- ('m', 't', 'u', ST_GeomFromText('POINT(119 237)')),
- ('o', 'w', 's', ST_GeomFromText('POINT(193 166)')),
- ('f', 'm', 'q', ST_GeomFromText('POINT(85 96)')),
- ('x', 'l', 'x', ST_GeomFromText('POINT(58 115)')),
- ('x', 'q', 'u', ST_GeomFromText('POINT(108 210)')),
- ('b', 'h', 'i', ST_GeomFromText('POINT(250 139)')),
- ('y', 'd', 'x', ST_GeomFromText('POINT(199 135)')),
- ('w', 'h', 'p', ST_GeomFromText('POINT(247 233)')),
- ('p', 'z', 't', ST_GeomFromText('POINT(148 249)')),
- ('q', 'a', 'u', ST_GeomFromText('POINT(174 78)')),
- ('v', 't', 'm', ST_GeomFromText('POINT(70 228)')),
- ('t', 'n', 'f', ST_GeomFromText('POINT(123 2)')),
- ('x', 't', 'b', ST_GeomFromText('POINT(35 50)')),
- ('r', 'j', 'f', ST_GeomFromText('POINT(200 51)')),
- ('s', 'q', 'o', ST_GeomFromText('POINT(23 184)')),
- ('u', 'v', 'z', ST_GeomFromText('POINT(7 113)')),
- ('v', 'u', 'l', ST_GeomFromText('POINT(145 190)')),
- ('o', 'k', 'i', ST_GeomFromText('POINT(161 122)')),
- ('l', 'y', 'e', ST_GeomFromText('POINT(17 232)')),
- ('t', 'b', 'e', ST_GeomFromText('POINT(120 50)')),
- ('e', 's', 'u', ST_GeomFromText('POINT(254 1)')),
- ('d', 'd', 'u', ST_GeomFromText('POINT(167 140)')),
- ('o', 'b', 'x', ST_GeomFromText('POINT(186 237)')),
- ('m', 's', 's', ST_GeomFromText('POINT(172 149)')),
- ('t', 'y', 'a', ST_GeomFromText('POINT(149 85)')),
- ('x', 't', 'r', ST_GeomFromText('POINT(10 165)')),
- ('g', 'c', 'e', ST_GeomFromText('POINT(95 165)')),
- ('e', 'e', 'z', ST_GeomFromText('POINT(98 65)')),
- ('f', 'v', 'i', ST_GeomFromText('POINT(149 144)')),
- ('o', 'p', 'm', ST_GeomFromText('POINT(233 67)')),
- ('t', 'u', 'b', ST_GeomFromText('POINT(109 215)')),
- ('o', 'o', 'b', ST_GeomFromText('POINT(130 48)')),
- ('e', 'm', 'h', ST_GeomFromText('POINT(88 189)')),
- ('e', 'v', 'y', ST_GeomFromText('POINT(55 29)')),
- ('e', 't', 'm', ST_GeomFromText('POINT(129 55)')),
- ('p', 'p', 'i', ST_GeomFromText('POINT(126 222)')),
- ('c', 'i', 'c', ST_GeomFromText('POINT(19 158)')),
- ('c', 'b', 's', ST_GeomFromText('POINT(13 19)')),
- ('u', 'y', 'a', ST_GeomFromText('POINT(114 5)')),
- ('a', 'o', 'f', ST_GeomFromText('POINT(227 232)')),
- ('t', 'c', 'z', ST_GeomFromText('POINT(63 62)')),
- ('d', 'o', 'k', ST_GeomFromText('POINT(48 228)')),
- ('x', 'c', 'e', ST_GeomFromText('POINT(204 2)')),
- ('e', 'e', 'g', ST_GeomFromText('POINT(125 43)')),
- ('o', 'r', 'f', ST_GeomFromText('POINT(171 140)'));
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(163 157)') where c1 like 'w%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(53 151)') where c1 like 'd%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(96 183)') where c1 like 'r%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(57 91)') where c1 like 'q%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(202 110)') where c1 like 'c%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(120 137)') where c1 like 'w%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(207 147)') where c1 like 'c%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(31 125)') where c1 like 'e%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(27 36)') where c1 like 'r%';
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
- ('b', 'c', 'e', ST_GeomFromText('POINT(41 137)')),
- ('p', 'y', 'k', ST_GeomFromText('POINT(50 22)')),
- ('s', 'c', 'h', ST_GeomFromText('POINT(208 173)')),
- ('x', 'u', 'l', ST_GeomFromText('POINT(199 175)')),
- ('s', 'r', 'h', ST_GeomFromText('POINT(85 192)')),
- ('j', 'k', 'u', ST_GeomFromText('POINT(18 25)')),
- ('p', 'w', 'h', ST_GeomFromText('POINT(152 197)')),
- ('e', 'd', 'c', ST_GeomFromText('POINT(229 3)')),
- ('o', 'x', 'k', ST_GeomFromText('POINT(187 155)')),
- ('o', 'b', 'k', ST_GeomFromText('POINT(208 150)')),
- ('d', 'a', 'j', ST_GeomFromText('POINT(70 87)')),
- ('f', 'e', 'k', ST_GeomFromText('POINT(156 96)')),
- ('u', 'y', 'p', ST_GeomFromText('POINT(239 193)')),
- ('n', 'v', 'p', ST_GeomFromText('POINT(223 98)')),
- ('z', 'j', 'r', ST_GeomFromText('POINT(87 89)')),
- ('h', 'x', 'x', ST_GeomFromText('POINT(92 0)')),
- ('r', 'v', 'r', ST_GeomFromText('POINT(159 139)')),
- ('v', 'g', 'g', ST_GeomFromText('POINT(16 229)')),
- ('z', 'k', 'u', ST_GeomFromText('POINT(99 52)')),
- ('p', 'p', 'o', ST_GeomFromText('POINT(105 125)')),
- ('w', 'h', 'y', ST_GeomFromText('POINT(105 154)')),
- ('v', 'y', 'z', ST_GeomFromText('POINT(134 238)')),
- ('x', 'o', 'o', ST_GeomFromText('POINT(178 88)')),
- ('z', 'w', 'd', ST_GeomFromText('POINT(123 60)')),
- ('q', 'f', 'u', ST_GeomFromText('POINT(64 90)')),
- ('s', 'n', 't', ST_GeomFromText('POINT(50 138)')),
- ('v', 'p', 't', ST_GeomFromText('POINT(114 91)')),
- ('a', 'o', 'n', ST_GeomFromText('POINT(78 43)')),
- ('k', 'u', 'd', ST_GeomFromText('POINT(185 161)')),
- ('w', 'd', 'n', ST_GeomFromText('POINT(25 92)')),
- ('k', 'w', 'a', ST_GeomFromText('POINT(59 238)')),
- ('t', 'c', 'f', ST_GeomFromText('POINT(65 87)')),
- ('g', 's', 'p', ST_GeomFromText('POINT(238 126)')),
- ('d', 'n', 'y', ST_GeomFromText('POINT(107 173)')),
- ('l', 'a', 'w', ST_GeomFromText('POINT(125 152)')),
- ('m', 'd', 'j', ST_GeomFromText('POINT(146 53)')),
- ('q', 'm', 'c', ST_GeomFromText('POINT(217 187)')),
- ('i', 'r', 'r', ST_GeomFromText('POINT(6 113)')),
- ('e', 'j', 'b', ST_GeomFromText('POINT(37 83)')),
- ('w', 'w', 'h', ST_GeomFromText('POINT(83 199)')),
- ('k', 'b', 's', ST_GeomFromText('POINT(170 64)')),
- ('s', 'b', 'c', ST_GeomFromText('POINT(163 130)')),
- ('c', 'h', 'a', ST_GeomFromText('POINT(141 3)')),
- ('k', 'j', 'u', ST_GeomFromText('POINT(143 76)')),
- ('r', 'h', 'o', ST_GeomFromText('POINT(243 92)')),
- ('i', 'd', 'b', ST_GeomFromText('POINT(205 13)')),
- ('r', 'y', 'q', ST_GeomFromText('POINT(138 8)')),
- ('m', 'o', 'i', ST_GeomFromText('POINT(36 45)')),
- ('v', 'g', 'm', ST_GeomFromText('POINT(0 40)')),
- ('f', 'e', 'i', ST_GeomFromText('POINT(76 6)')),
- ('c', 'q', 'q', ST_GeomFromText('POINT(115 248)')),
- ('x', 'c', 'i', ST_GeomFromText('POINT(29 74)')),
- ('l', 's', 't', ST_GeomFromText('POINT(83 18)')),
- ('t', 't', 'a', ST_GeomFromText('POINT(26 168)')),
- ('u', 'n', 'x', ST_GeomFromText('POINT(200 110)')),
- ('j', 'b', 'd', ST_GeomFromText('POINT(216 136)')),
- ('s', 'p', 'w', ST_GeomFromText('POINT(38 156)')),
- ('f', 'b', 'v', ST_GeomFromText('POINT(29 186)')),
- ('v', 'e', 'r', ST_GeomFromText('POINT(149 40)')),
- ('v', 't', 'm', ST_GeomFromText('POINT(184 24)')),
- ('y', 'g', 'a', ST_GeomFromText('POINT(219 105)')),
- ('s', 'f', 'i', ST_GeomFromText('POINT(114 130)')),
- ('e', 'q', 'h', ST_GeomFromText('POINT(203 135)')),
- ('h', 'g', 'b', ST_GeomFromText('POINT(9 208)')),
- ('o', 'l', 'r', ST_GeomFromText('POINT(245 79)')),
- ('s', 's', 'v', ST_GeomFromText('POINT(238 198)')),
- ('w', 'w', 'z', ST_GeomFromText('POINT(209 232)')),
- ('v', 'd', 'n', ST_GeomFromText('POINT(30 193)')),
- ('q', 'w', 'k', ST_GeomFromText('POINT(133 18)')),
- ('o', 'h', 'o', ST_GeomFromText('POINT(42 140)')),
- ('f', 'f', 'h', ST_GeomFromText('POINT(145 1)')),
- ('u', 's', 'r', ST_GeomFromText('POINT(70 62)')),
- ('x', 'n', 'q', ST_GeomFromText('POINT(33 86)')),
- ('u', 'p', 'v', ST_GeomFromText('POINT(232 220)')),
- ('z', 'e', 'a', ST_GeomFromText('POINT(130 69)')),
- ('r', 'u', 'z', ST_GeomFromText('POINT(243 241)')),
- ('b', 'n', 't', ST_GeomFromText('POINT(120 12)')),
- ('u', 'f', 's', ST_GeomFromText('POINT(190 212)')),
- ('a', 'd', 'q', ST_GeomFromText('POINT(235 191)')),
- ('f', 'q', 'm', ST_GeomFromText('POINT(176 2)')),
- ('n', 'c', 's', ST_GeomFromText('POINT(218 163)')),
- ('e', 'm', 'h', ST_GeomFromText('POINT(163 108)')),
- ('c', 'f', 'l', ST_GeomFromText('POINT(220 115)')),
- ('c', 'v', 'q', ST_GeomFromText('POINT(66 45)')),
- ('w', 'v', 'x', ST_GeomFromText('POINT(251 220)')),
- ('f', 'w', 'z', ST_GeomFromText('POINT(146 149)')),
- ('h', 'n', 'h', ST_GeomFromText('POINT(148 128)')),
- ('y', 'k', 'v', ST_GeomFromText('POINT(28 110)')),
- ('c', 'x', 'q', ST_GeomFromText('POINT(13 13)')),
- ('e', 'd', 's', ST_GeomFromText('POINT(91 190)')),
- ('c', 'w', 'c', ST_GeomFromText('POINT(10 231)')),
- ('u', 'j', 'n', ST_GeomFromText('POINT(250 21)')),
- ('w', 'n', 'x', ST_GeomFromText('POINT(141 69)')),
- ('f', 'p', 'y', ST_GeomFromText('POINT(228 246)')),
- ('d', 'q', 'f', ST_GeomFromText('POINT(194 22)')),
- ('d', 'z', 'l', ST_GeomFromText('POINT(233 181)')),
- ('c', 'a', 'q', ST_GeomFromText('POINT(183 96)')),
- ('m', 'i', 'd', ST_GeomFromText('POINT(117 226)')),
- ('z', 'y', 'y', ST_GeomFromText('POINT(62 81)')),
- ('g', 'v', 'm', ST_GeomFromText('POINT(66 158)'));
-SET @@RAND_SEED1=481064922, @@RAND_SEED2=438133497;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=280535103, @@RAND_SEED2=444518646;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=1072017234, @@RAND_SEED2=484203885;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=358851897, @@RAND_SEED2=358495224;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-SET @@RAND_SEED1=509031459, @@RAND_SEED2=675962925;
-DELETE FROM t1 ORDER BY RAND() LIMIT 10;
-#UPDATE t1 set spatial_point=ST_GeomFromText('POINT(61 203)') where c1 like 'y%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(202 194)') where c1 like 'f%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(228 18)') where c1 like 'h%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(88 18)') where c1 like 'l%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(176 94)') where c1 like 'e%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(44 47)') where c1 like 'g%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(95 191)') where c1 like 'b%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(179 218)') where c1 like 'y%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(239 40)') where c1 like 'g%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(248 41)') where c1 like 'q%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(167 82)') where c1 like 't%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(13 104)') where c1 like 'u%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(139 84)') where c1 like 'a%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(145 108)') where c1 like 'p%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(147 57)') where c1 like 't%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(217 144)') where c1 like 'n%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(160 224)') where c1 like 'w%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(38 28)') where c1 like 'j%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(104 114)') where c1 like 'q%';
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(88 19)') where c1 like 'c%';
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
- ('f', 'x', 'p', ST_GeomFromText('POINT(92 181)')),
- ('s', 'i', 'c', ST_GeomFromText('POINT(49 60)')),
- ('c', 'c', 'i', ST_GeomFromText('POINT(7 57)')),
- ('n', 'g', 'k', ST_GeomFromText('POINT(252 105)')),
- ('g', 'b', 'm', ST_GeomFromText('POINT(180 11)')),
- ('u', 'l', 'r', ST_GeomFromText('POINT(32 90)')),
- ('c', 'x', 'e', ST_GeomFromText('POINT(143 24)')),
- ('x', 'u', 'a', ST_GeomFromText('POINT(123 92)')),
- ('s', 'b', 'h', ST_GeomFromText('POINT(190 108)')),
- ('c', 'x', 'b', ST_GeomFromText('POINT(104 100)')),
- ('i', 'd', 't', ST_GeomFromText('POINT(214 104)')),
- ('r', 'w', 'g', ST_GeomFromText('POINT(29 67)')),
- ('b', 'f', 'g', ST_GeomFromText('POINT(149 46)')),
- ('r', 'r', 'd', ST_GeomFromText('POINT(242 196)')),
- ('j', 'l', 'a', ST_GeomFromText('POINT(90 196)')),
- ('e', 't', 'b', ST_GeomFromText('POINT(190 64)')),
- ('l', 'x', 'w', ST_GeomFromText('POINT(250 73)')),
- ('q', 'y', 'r', ST_GeomFromText('POINT(120 182)')),
- ('s', 'j', 'a', ST_GeomFromText('POINT(180 175)')),
- ('n', 'i', 'y', ST_GeomFromText('POINT(124 136)')),
- ('s', 'x', 's', ST_GeomFromText('POINT(176 209)')),
- ('u', 'f', 's', ST_GeomFromText('POINT(215 173)')),
- ('m', 'j', 'x', ST_GeomFromText('POINT(44 140)')),
- ('v', 'g', 'x', ST_GeomFromText('POINT(177 233)')),
- ('u', 't', 'b', ST_GeomFromText('POINT(136 197)')),
- ('f', 'g', 'b', ST_GeomFromText('POINT(10 8)')),
- ('v', 'c', 'j', ST_GeomFromText('POINT(13 81)')),
- ('d', 's', 'q', ST_GeomFromText('POINT(200 100)')),
- ('a', 'p', 'j', ST_GeomFromText('POINT(33 40)')),
- ('i', 'c', 'g', ST_GeomFromText('POINT(168 204)')),
- ('k', 'h', 'i', ST_GeomFromText('POINT(93 243)')),
- ('s', 'b', 's', ST_GeomFromText('POINT(157 13)')),
- ('v', 'l', 'l', ST_GeomFromText('POINT(103 6)')),
- ('r', 'b', 'k', ST_GeomFromText('POINT(244 137)')),
- ('l', 'd', 'r', ST_GeomFromText('POINT(162 254)')),
- ('q', 'b', 'z', ST_GeomFromText('POINT(136 246)')),
- ('x', 'x', 'p', ST_GeomFromText('POINT(120 37)')),
- ('m', 'e', 'z', ST_GeomFromText('POINT(203 167)')),
- ('q', 'n', 'p', ST_GeomFromText('POINT(94 119)')),
- ('b', 'g', 'u', ST_GeomFromText('POINT(93 248)')),
- ('r', 'v', 'v', ST_GeomFromText('POINT(53 88)')),
- ('y', 'a', 'i', ST_GeomFromText('POINT(98 219)')),
- ('a', 's', 'g', ST_GeomFromText('POINT(173 138)')),
- ('c', 'a', 't', ST_GeomFromText('POINT(235 135)')),
- ('q', 'm', 'd', ST_GeomFromText('POINT(224 208)')),
- ('e', 'p', 'k', ST_GeomFromText('POINT(161 238)')),
- ('n', 'g', 'q', ST_GeomFromText('POINT(35 204)')),
- ('t', 't', 'x', ST_GeomFromText('POINT(230 178)')),
- ('w', 'f', 'a', ST_GeomFromText('POINT(150 221)')),
- ('z', 'm', 'z', ST_GeomFromText('POINT(119 42)')),
- ('l', 'j', 's', ST_GeomFromText('POINT(97 96)')),
- ('f', 'z', 'x', ST_GeomFromText('POINT(208 65)')),
- ('i', 'v', 'c', ST_GeomFromText('POINT(145 79)')),
- ('l', 'f', 'k', ST_GeomFromText('POINT(83 234)')),
- ('u', 'a', 's', ST_GeomFromText('POINT(250 49)')),
- ('o', 'k', 'p', ST_GeomFromText('POINT(46 50)')),
- ('d', 'e', 'z', ST_GeomFromText('POINT(30 198)')),
- ('r', 'r', 'l', ST_GeomFromText('POINT(78 189)')),
- ('y', 'l', 'f', ST_GeomFromText('POINT(188 132)')),
- ('d', 'q', 'm', ST_GeomFromText('POINT(247 107)')),
- ('p', 'j', 'n', ST_GeomFromText('POINT(148 227)')),
- ('b', 'o', 'i', ST_GeomFromText('POINT(172 25)')),
- ('e', 'v', 'd', ST_GeomFromText('POINT(94 248)')),
- ('q', 'd', 'f', ST_GeomFromText('POINT(15 29)')),
- ('w', 'b', 'b', ST_GeomFromText('POINT(74 111)')),
- ('g', 'q', 'f', ST_GeomFromText('POINT(107 215)')),
- ('o', 'h', 'r', ST_GeomFromText('POINT(25 168)')),
- ('u', 't', 'w', ST_GeomFromText('POINT(251 188)')),
- ('h', 's', 'w', ST_GeomFromText('POINT(254 247)')),
- ('f', 'f', 'b', ST_GeomFromText('POINT(166 103)'));
-SET @@RAND_SEED1=866613816, @@RAND_SEED2=92289615;
-INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
- ('l', 'c', 'l', ST_GeomFromText('POINT(202 98)')),
- ('k', 'c', 'b', ST_GeomFromText('POINT(46 206)')),
- ('r', 'y', 'm', ST_GeomFromText('POINT(74 140)')),
- ('y', 'z', 'd', ST_GeomFromText('POINT(200 160)')),
- ('s', 'y', 's', ST_GeomFromText('POINT(156 205)')),
- ('u', 'v', 'p', ST_GeomFromText('POINT(86 82)')),
- ('j', 's', 's', ST_GeomFromText('POINT(91 233)')),
- ('x', 'j', 'f', ST_GeomFromText('POINT(3 14)')),
- ('l', 'z', 'v', ST_GeomFromText('POINT(123 156)')),
- ('h', 'i', 'o', ST_GeomFromText('POINT(145 229)')),
- ('o', 'r', 'd', ST_GeomFromText('POINT(15 22)')),
- ('f', 'x', 't', ST_GeomFromText('POINT(21 60)')),
- ('t', 'g', 'h', ST_GeomFromText('POINT(50 153)')),
- ('g', 'u', 'b', ST_GeomFromText('POINT(82 85)')),
- ('v', 'a', 'p', ST_GeomFromText('POINT(231 178)')),
- ('n', 'v', 'o', ST_GeomFromText('POINT(183 25)')),
- ('j', 'n', 'm', ST_GeomFromText('POINT(50 144)')),
- ('e', 'f', 'i', ST_GeomFromText('POINT(46 16)')),
- ('d', 'w', 'a', ST_GeomFromText('POINT(66 6)')),
- ('f', 'x', 'a', ST_GeomFromText('POINT(107 197)')),
- ('m', 'o', 'a', ST_GeomFromText('POINT(142 80)')),
- ('q', 'l', 'g', ST_GeomFromText('POINT(251 23)')),
- ('c', 's', 's', ST_GeomFromText('POINT(158 43)')),
- ('y', 'd', 'o', ST_GeomFromText('POINT(196 228)')),
- ('d', 'p', 'l', ST_GeomFromText('POINT(107 5)')),
- ('h', 'a', 'b', ST_GeomFromText('POINT(183 166)')),
- ('m', 'w', 'p', ST_GeomFromText('POINT(19 59)')),
- ('b', 'y', 'o', ST_GeomFromText('POINT(178 30)')),
- ('x', 'w', 'i', ST_GeomFromText('POINT(168 94)')),
- ('t', 'k', 'z', ST_GeomFromText('POINT(171 5)')),
- ('r', 'm', 'a', ST_GeomFromText('POINT(222 19)')),
- ('u', 'v', 'e', ST_GeomFromText('POINT(224 80)')),
- ('q', 'r', 'k', ST_GeomFromText('POINT(212 218)')),
- ('d', 'p', 'j', ST_GeomFromText('POINT(169 7)')),
- ('d', 'r', 'v', ST_GeomFromText('POINT(193 23)')),
- ('n', 'y', 'y', ST_GeomFromText('POINT(130 178)')),
- ('m', 'z', 'r', ST_GeomFromText('POINT(81 200)')),
- ('j', 'e', 'w', ST_GeomFromText('POINT(145 239)')),
- ('v', 'h', 'x', ST_GeomFromText('POINT(24 105)')),
- ('z', 'm', 'a', ST_GeomFromText('POINT(175 129)')),
- ('b', 'c', 'v', ST_GeomFromText('POINT(213 10)')),
- ('t', 't', 'u', ST_GeomFromText('POINT(2 129)')),
- ('r', 's', 'v', ST_GeomFromText('POINT(209 192)')),
- ('x', 'p', 'g', ST_GeomFromText('POINT(43 63)')),
- ('t', 'e', 'u', ST_GeomFromText('POINT(139 210)')),
- ('l', 'e', 't', ST_GeomFromText('POINT(245 148)')),
- ('a', 'i', 'k', ST_GeomFromText('POINT(167 195)')),
- ('m', 'o', 'h', ST_GeomFromText('POINT(206 120)')),
- ('g', 'z', 's', ST_GeomFromText('POINT(169 240)')),
- ('z', 'u', 's', ST_GeomFromText('POINT(202 120)')),
- ('i', 'b', 'a', ST_GeomFromText('POINT(216 18)')),
- ('w', 'y', 'g', ST_GeomFromText('POINT(119 236)')),
- ('h', 'y', 'p', ST_GeomFromText('POINT(161 24)'));
-CHECK TABLE t1 EXTENDED;
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(33 100)') where c1 like 't%';
-CHECK TABLE t1 EXTENDED;
-UPDATE t1 set spatial_point=ST_GeomFromText('POINT(41 46)') where c1 like 'f%';
-CHECK TABLE t1 EXTENDED;
-DROP TABLE t1;
-
-#
-# Bug #30286 spatial index cause corruption and server crash!
-#
-
-create table t1 (a geometry not null, spatial index(a));
-insert into t1 values (POINT(1.1517219314031e+164, 131072));
-insert into t1 values (POINT(9.1248812352444e+192, 2.9740338169556e+284));
-insert into t1 values (POINT(4.7783097267365e-299, -0));
-insert into t1 values (POINT(1.49166814624e-154, 2.0880974297595e-53));
-insert into t1 values (POINT(4.0917382598702e+149, 1.2024538023802e+111));
-insert into t1 values (POINT(2.0349165139404e+236, 2.9993936277913e-241));
-insert into t1 values (POINT(2.5243548967072e-29, 1.2024538023802e+111));
-insert into t1 values (POINT(0, 6.9835074892995e-251));
-insert into t1 values (POINT(2.0880974297595e-53, 3.1050361846014e+231));
-insert into t1 values (POINT(2.8728483499323e-188, 2.4600631144627e+260));
-insert into t1 values (POINT(3.0517578125e-05, 2.0349165139404e+236));
-insert into t1 values (POINT(1.1517219314031e+164, 1.1818212630766e-125));
-insert into t1 values (POINT(2.481040258324e-265, 5.7766220027675e-275));
-insert into t1 values (POINT(2.0880974297595e-53, 2.5243548967072e-29));
-insert into t1 values (POINT(5.7766220027675e-275, 9.9464647281957e+86));
-insert into t1 values (POINT(2.2181357552967e+130, 3.7857669957337e-270));
-insert into t1 values (POINT(4.5767114681874e-246, 3.6893488147419e+19));
-insert into t1 values (POINT(4.5767114681874e-246, 3.7537584144024e+255));
-insert into t1 values (POINT(3.7857669957337e-270, 1.8033161362863e-130));
-insert into t1 values (POINT(0, 5.8774717541114e-39));
-insert into t1 values (POINT(1.1517219314031e+164, 2.2761049594727e-159));
-insert into t1 values (POINT(6.243497100632e+144, 3.7857669957337e-270));
-insert into t1 values (POINT(3.7857669957337e-270, 2.6355494858076e-82));
-insert into t1 values (POINT(2.0349165139404e+236, 3.8518598887745e-34));
-insert into t1 values (POINT(4.6566128730774e-10, 2.0880974297595e-53));
-insert into t1 values (POINT(2.0880974297595e-53, 1.8827498946116e-183));
-insert into t1 values (POINT(1.8033161362863e-130, 9.1248812352444e+192));
-insert into t1 values (POINT(4.7783097267365e-299, 2.2761049594727e-159));
-insert into t1 values (POINT(1.94906280228e+289, 1.2338789709327e-178));
-drop table t1;
-
-# End of 4.1 tests
-
-#
-# bug #21790 (UNKNOWN ERROR on NULLs in RTree)
-#
-CREATE TABLE t1(foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
---error 1048
-INSERT INTO t1(foo) VALUES (NULL);
-SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
---error 1416
-INSERT INTO t1() VALUES ();
-SET sql_mode = default;
---error 1416
-INSERT INTO t1(foo) VALUES ('');
-DROP TABLE t1;
-
-#
-# Bug #23578: Corruption prevents Optimize table from working properly with a
-# spatial index
-#
-
-CREATE TABLE t1 (a INT AUTO_INCREMENT, b POINT NOT NULL, KEY (a), SPATIAL KEY (b));
-
-INSERT INTO t1 (b) VALUES (ST_GeomFromText('POINT(1 2)'));
-INSERT INTO t1 (b) SELECT b FROM t1;
-INSERT INTO t1 (b) SELECT b FROM t1;
-INSERT INTO t1 (b) SELECT b FROM t1;
-INSERT INTO t1 (b) SELECT b FROM t1;
-INSERT INTO t1 (b) SELECT b FROM t1;
-
-OPTIMIZE TABLE t1;
-DROP TABLE t1;
-
-
-#
-# Bug #29070: Error in spatial index
-#
-
-CREATE TABLE t1 (a INT, b GEOMETRY NOT NULL, SPATIAL KEY b(b));
-INSERT INTO t1 VALUES (1, ST_GEOMFROMTEXT('LINESTRING(1102218.456 1,2000000 2)'));
-INSERT INTO t1 VALUES (2, ST_GEOMFROMTEXT('LINESTRING(1102218.456 1,2000000 2)'));
-
-# must return the same number as the next select
-SELECT COUNT(*) FROM t1 WHERE
- MBRINTERSECTS(b, ST_GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') );
-SELECT COUNT(*) FROM t1 IGNORE INDEX (b) WHERE
- MBRINTERSECTS(b, ST_GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') );
-
-DROP TABLE t1;
-
-
---echo #
---echo # Bug #48258: Assertion failed when using a spatial index
---echo #
-CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
-INSERT INTO t1 VALUES
- (ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
- (ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
-EXPLAIN SELECT 1 FROM t1 WHERE a = ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-SELECT 1 FROM t1 WHERE a = ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
---error ER_WRONG_ARGUMENTS
-EXPLAIN SELECT 1 FROM t1 WHERE a < ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
---error ER_WRONG_ARGUMENTS
-SELECT 1 FROM t1 WHERE a < ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
---error ER_WRONG_ARGUMENTS
-EXPLAIN SELECT 1 FROM t1 WHERE a <= ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
---error ER_WRONG_ARGUMENTS
-SELECT 1 FROM t1 WHERE a <= ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
---error ER_WRONG_ARGUMENTS
-EXPLAIN SELECT 1 FROM t1 WHERE a > ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
---error ER_WRONG_ARGUMENTS
-SELECT 1 FROM t1 WHERE a > ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
---error ER_WRONG_ARGUMENTS
-EXPLAIN SELECT 1 FROM t1 WHERE a >= ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
---error ER_WRONG_ARGUMENTS
-SELECT 1 FROM t1 WHERE a >= ST_GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
-DROP TABLE t1;
-
-
---echo #
---echo # Bug #51357: crash when using handler commands on spatial indexes
---echo #
-
-CREATE TABLE t1(a GEOMETRY NOT NULL,SPATIAL INDEX a(a));
-HANDLER t1 OPEN;
-HANDLER t1 READ a FIRST;
-HANDLER t1 READ a NEXT;
-HANDLER t1 READ a PREV;
-HANDLER t1 READ a LAST;
-HANDLER t1 CLOSE;
-
-# second crash fixed when the tree has changed since the last search.
-HANDLER t1 OPEN;
-HANDLER t1 READ a FIRST;
-INSERT INTO t1 VALUES (ST_GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
---echo # should not crash
---disable_result_log
-HANDLER t1 READ a NEXT;
---enable_result_log
-HANDLER t1 CLOSE;
-
-DROP TABLE t1;
-
-
---echo End of 5.0 tests.
-
-
---echo #
---echo # Bug #57323/11764487: myisam corruption with insert ignore
---echo # and invalid spatial data
---echo #
-
-CREATE TABLE t1(a LINESTRING NOT NULL, b GEOMETRY NOT NULL,
- SPATIAL KEY(a), SPATIAL KEY(b)) ENGINE=InnoDB;
---error ER_CANT_CREATE_GEOMETRY_OBJECT
-INSERT INTO t1 VALUES(ST_GEOMFROMTEXT("point (0 0)"), ST_GEOMFROMTEXT("point (1 1)"));
---error ER_CANT_CREATE_GEOMETRY_OBJECT
-INSERT IGNORE INTO t1 SET a=ST_GEOMFROMTEXT("point (-6 0)"), b=ST_GEOMFROMTEXT("error");
---error ER_CANT_CREATE_GEOMETRY_OBJECT
-INSERT IGNORE INTO t1 SET a=ST_GEOMFROMTEXT("point (-6 0)"), b=NULL;
-SELECT ST_ASTEXT(a), ST_ASTEXT(b) FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1(a INT NOT NULL, b GEOMETRY NOT NULL,
- KEY(a), SPATIAL KEY(b)) ENGINE=InnoDB;
-INSERT INTO t1 VALUES(0, ST_GEOMFROMTEXT("point (1 1)"));
---error ER_GIS_INVALID_DATA
-INSERT IGNORE INTO t1 SET a=0, b=ST_GEOMFROMTEXT("error");
---error ER_CANT_CREATE_GEOMETRY_OBJECT
-INSERT IGNORE INTO t1 SET a=1, b=NULL;
-SELECT a, ST_ASTEXT(b) FROM t1;
-DROP TABLE t1;
-
---echo End of 5.1 tests
diff --git a/mysql-test/suite/innodb_gis/t/rtree_purge.test b/mysql-test/suite/innodb_gis/t/rtree_purge.test
index 86a1ecb88da..42f00428b88 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_purge.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_purge.test
@@ -1,52 +1,32 @@
# This test case will test R-tree purge.
-# Not supported in embedded
---source include/not_embedded.inc
-
---source include/have_innodb.inc
---source include/have_innodb_zip.inc
---source include/have_debug.inc
---source include/big_test.inc
+--source include/innodb_page_size.inc
# Valgrind takes too much time on PB2 even in the --big-test runs.
--source include/not_valgrind.inc
-# Temporarily disable it for 4k page size. Since it'll take too long
-# time.
---disable_warnings
-if (`SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE LOWER(variable_name) = 'innodb_page_size' AND variable_value = 4096`)
-{
- --skip Test requires InnoDB with not 4k Page size.
-}
---enable_warnings
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
create table t (
- a point not null,b point not null,c point,
- d point not null,e point,f point,
- spatial key (d),spatial key (b)
+ b point not null,d point not null, spatial key (d),spatial key (b)
) engine=innodb;
-delimiter |;
-create procedure p(i int)
-begin
- declare n int default 0;
- declare continue handler for sqlexception begin end;
- delete from t;
- repeat
- set @p=point(1,1);
- insert into t values(@p,@p,@p,@p,@p,@p);
- insert into t values(@p,@p,@p,@p,@p,@p);
- insert into t select @p,@p,@p,@p,@p,@p
- from t a,t b,t c,t d,t e,t f,t g,t h,t i,t j;
- delete from t;
- set n:=n+1;
- until n >= i end repeat;
-end|
-delimiter ;|
-
-call p(200);
+--disable_query_log
+set @p=point(1,1);
+let $n=200;
+while ($n) {
+begin;
+insert into t values(@p,@p),(@p,@p);
+insert into t select @p,@p
+from t a,t b,t c,t d,t e,t f,t g;
+delete from t;
+commit;
+dec $n;
+}
+--enable_query_log
---source include/wait_all_purged.inc
+--source ../../innodb/include/wait_all_purged.inc
# Clean up.
-drop procedure p;
drop table t;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb_gis/t/rtree_recovery.test b/mysql-test/suite/innodb_gis/t/rtree_recovery.test
index 9e332c089f2..d995048ceac 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_recovery.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_recovery.test
@@ -44,7 +44,8 @@ delimiter ;|
CALL insert_t1(367);
COMMIT;
---source include/kill_and_restart_mysqld.inc
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
# Check table.
check table t1;
@@ -63,7 +64,7 @@ SET @poly1 = ST_GeomFromText('POLYGON((10000 10000, 10000 10350, 10350 10350, 10
delete from t1 where ST_Contains(@poly1, c2);
COMMIT;
---source include/kill_and_restart_mysqld.inc
+--source include/restart_mysqld.inc
# Check table.
check table t1;
diff --git a/mysql-test/suite/innodb_gis/t/rtree_search.test b/mysql-test/suite/innodb_gis/t/rtree_search.test
index 3c591004042..6bbd84a25cf 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_search.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_search.test
@@ -38,9 +38,10 @@ select count(*) from t1 where MBRWithin(t1.c2, @g1);
set @g1 = ST_GeomFromText('Polygon((100 100,100 800,800 800,800 100,100 100))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
-#SET DEBUG='+d, rtr_pessimistic_position';
+#SET @save_dbug= @@session.debug_dbug;
+#SET debug_dbug = '+d,rtr_pessimistic_position';
#select count(*) from t1 where MBRWithin(t1.c2, @g1);
-#SET DEBUG='-d, rtr_pessimistic_position';
+#SET debug_dbug = @save_dbug;
# Equality search
set @g1 = ST_GeomFromText('Point(1 1)');
diff --git a/mysql-test/suite/innodb_gis/t/rtree_split.test b/mysql-test/suite/innodb_gis/t/rtree_split.test
index e6925940fcd..caf79becbd0 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_split.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_split.test
@@ -31,9 +31,10 @@ insert into t1 select * from t1;
insert into t1 select * from t1;
#Check second round spliting.
-SET SESSION debug="+d, rtr_page_need_second_split";
+SET @saved_dbug = @@SESSION.debug_dbug;
+SET debug_dbug = '+d, rtr_page_need_second_split';
insert into t1 select * from t1;
-SET SESSION debug="-d, rtr_page_need_second_split";
+SET debug_dbug = @saved_dbug;
delete from t1;
@@ -79,24 +80,27 @@ select count(*) from t1 where MBRWithin(t1.c2, @g1);
drop index c2 on t1;
# Test create index with algorithm=inplace
+--enable_info
create spatial index idx2 on t1(c2);
+--disable_info
show create table t1;
-set @g1 = ST_GeomFromText('Polygon((0 0,0 100,100 100,100 0,0 0))');
-select count(*) from t1 where MBRWithin(t1.c2, @g1);
-
# test read only case
-let $restart_parameters = restart: --innodb-read-only;
+let $restart_parameters = --innodb-read-only;
--source include/restart_mysqld.inc
set @g1 = ST_GeomFromText('Polygon((0 0,0 100,100 100,100 0,0 0))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
-
set @g1 = ST_GeomFromText('Polygon((2 2,2 800,800 800,800 2,2 2))');
select count(*) from t1 where MBRWithin(t1.c2, @g1);
-let $restart_parameters = restart;
+let $restart_parameters =;
--source include/restart_mysqld.inc
+set @g1 = ST_GeomFromText('Polygon((0 0,0 100,100 100,100 0,0 0))');
+select count(*) from t1 where MBRWithin(t1.c2, @g1);
+set @g1 = ST_GeomFromText('Polygon((2 2,2 800,800 800,800 2,2 2))');
+select count(*) from t1 where MBRWithin(t1.c2, @g1);
+
# Clean up.
drop table t1;
diff --git a/mysql-test/suite/innodb_gis/t/rtree_undo.test b/mysql-test/suite/innodb_gis/t/rtree_undo.test
index 5ed11f6165d..2ae309a8f7e 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_undo.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_undo.test
@@ -3,36 +3,102 @@
# BUG#21508582 UNDO LOG DOES NOT CONTAIN ENOUGH INFORMATION ON SPATIAL COLUMNS
#
---source include/have_innodb.inc
+--source include/innodb_row_format.inc
--source include/count_sessions.inc
-connect (con1,localhost,root,,);
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
+
+connect (control_purge,localhost,root,,);
connection default;
-let $row_format = DYNAMIC;
let $prefix_size = 767;
+let $index = 3;
-let $index = spatial_none;
---source include/innodb_gis_undo.inc
+while ($index) {
+CREATE TABLE t1 (
+ p INT NOT NULL AUTO_INCREMENT,
+ g LINESTRING NOT NULL,
+ PRIMARY KEY(p)
+) ENGINE=InnoDB;
-let $index = spatial_only;
---source include/innodb_gis_undo.inc
+if ($index == 3) {
+ eval ALTER TABLE t1 ADD INDEX prefix_idx (g($prefix_size));
+}
-let $index = spatial_mixed;
---source include/innodb_gis_undo.inc
+if ($index == 2) {
+ ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
+}
+if ($index == 1) {
+ ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
+ eval ALTER TABLE t1 ADD INDEX prefix_idx (g($prefix_size));
+}
-let $row_format = COMPACT;
-let $prefix_size = 767;
+INSERT INTO t1(g) VALUES(ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)'));
+INSERT INTO t1(g) VALUES(ST_linefromtext(concat('linestring','(18 106,19 106,24 111,27 108,32 104,37 107,42 107,44 112,44 116,40 118,43 114,46 114,42 118,44 123,45 123,49 123,53 119,50 123,50 124,54 126,58 125,59 126,64 127,65 127,69 131,74 132,75 135,78 139,2078 141,2075 143,2077 143,2079 143,2084 143,2085 147,2090 -1853,2086 -1852,2086 -1856,2089 -1852,2093 -1850,2090 -1851,2090 -1852,2091 -1851,2092 -1850,2097 -1847,2102 -1848,2100 -1852,2100 -1852,7100 -1851,7103 -1850,7104 -1847,7109 -1842,65 127,67 131,66 131,61 132,61 133,62 137,65 1137,2065 1135,2061 1135,2064 1135,5064 1135,5066 1135,5070 1136,5070 1141,5071 1138,5074 1141,5075 1141,5074 1137,5076 1137,5071 1139,5066 1142,5065 2142,5068 2147,5073 2151,5069 2156,5071 2157,5072 2162,5074 2165,5069 2169,5072 2169,5076 2173,5074 2169,5078 2169,5076 2170,76 2175,74 2179,75 2184,80 2188,83 2190,87 2189,84 2193,87 2189,86 2190,87 2195,87 2200,87 1200,85 1202,86 1199,87 1200,87 1201,91 1206,92 1204,94 1204,98 1206,102 1208,105 1211,102 1216,105 1220,109 1224,110 1224,114 1225,117 1224,118 1229,117 1232,122 1237,123 1236,120 1235,124 1237,121 1236,122 1240,126 1244,127 1246,126 1249,125 5249,123 5251,127 5251,131 5251,135 5256,138 5257,135 5257,139 5257,138 5258,141 5260,146 5260,146 5260,143 10260,147 10265,151 10270,156 10266,157 10269,162 10273,166 12273,168 12274,163 12270,168 12275,170 12277,170 12277,-3830 12277,-3825 12277,-3824 12278,-3825 12276,-3825 12278,-3822 12277,-3825 12275,-3829 12278,-3828 12275,-3824 12280,-3827 12280,-3826 12282,-3822 12283,-3822 12286,-3820 12288,-3818 12289,-3816 12294,-3817 12297,-3819 12300,-3816 12297,-3813 12295,-3811 12299,-3811 12297,-3806 12298,-3806 12298,-3804 12301,-3801 12306,-3803 17306,-3803 17306,-3798 17306,-3803 17310,-3801 17314,-3798 17317,-3797 17317,-797 17321,-797 17323,-796 17325,-793 17326,-792 17322,-789 17327,-784 17331,-780 17335,-776 17339,-774 17339,-771 17342,-770 17345,-765 17348,-765 17349,-763 17353,-760 17350,-760 22350,-756 22346,-752 22349,-748 22352,-752 22348,-748 22347,-746 22345,-745 27345,-743 27346,257 27350,260 27349,261 27352,266 27348,266 22348,269 22347,271 22347,272 22347,273 22348,273 22352,278 22348,279 22344,282 22345,282 22342,283 22347,283 22347,288 22349,292 22347,292 22348,293 22348,298 22348,303 22351,306 22352,309 22352,308 22354,310 22356,311 22361,311 22358,311 22360,311 22360,315 22356,320 22358,325 22363,326 22366,321 22371,318 22373,318 22375,314 22375,316 22375,321 22376,321 22376,322 22372,32 104,36 109,40 114,40 113,40 117,44 119,49 123,49 126,49 129,53 133,50 137,50 139,49 137,48 138,43 138,42 139,46 142,46 138,41 139,45 141,4045 5141,4045 5146,4042 5147,4043 10147,4041 10150,4042 10152,4045 10152,4041 10156,4041 10152,4041 10152,4046 10153,4049 10156,4046 10155,4051 10157,4055 10159,4055 10160,4056 10161,4055 10166,4054 10169,4054 10172,4054 15172,4051 15176,4047 15177,4049 15174,4047 15176,4047 15176,4046 15177,4046 15180,4043 15184,4043 15187,4038 15190,4040 15194,4040 15199,4045 15196,4047 15197,4050 15200,4050 15204,4050 15208,4047 15212,4047 15215,4049 15216,4046 15218,4042 15223,4042 15228,4042 15232,4047 15235,4050 15236,4050 15239,4051 15243,4053 15243,4050 17243,4052 17243,4052 18243,4057 18247,4061 18249,4064 18249,4067 20249,4067 20250,4067 20255,4066 20259,4066 20259,4067 20255,4069 20256,4071 20258,4072 20254,4067 20257,4067 20260,4069 20265,4065 20267,4069 20266,4070 20267,4071 20264,4074 20259,4070 20264,4073 20260,4074 20263,4077 20268,4082 20271,4084 20273,4084 20277,4081 18277,4085 18279,4086 18276,4087 18273,4087 18275,4092 18277,4093 18279,4093 18280,4095 18280,4091 18283,4092 18281,4094 18283,4090 18287,4094 18287,138 5257,138 5255,138 5258,-1862 5254,-1860 5256,-1856 5258,-1851 5255,-1850 5260,-1847 5260,-1847 5263,-1847 5258,-1850 5257,-1850 5259,-1851 5257,-1855 5258,-1853 5261,-1849 5261,-1849 5258,-1849 5259,-1845 5264,-1847 5264,-1850 5268,-1852 5266,-1853 5270,-1856 5265,-1852 5262,-1847 5263,-1842 5263,-1842 5260,-1842 5265,-1841 5265,-1844 5265,-1842 5270,-1837 5274,-1838 5279,-1843 5275,-1842 5280,-1838 5281,-1838 5285,-1833 5285,-1828 5288,-1824 5289,-1828 5291,-1831 5291,-1826 5291,-1830 5293,-1826 5296,-1822 5301,-1826 5302,-1826 5302,-1826 5302,-1825 5297,-1820 5299,-1816 5303,-1816 5299,-3811 12299,-3809 12302,-3806 12302,-3806 12302,-3803 12304,-3798 12304,-3797 12304,-3793 12306,-3788 12306,-3783 12309,-3816 12294,-3811 12299,-3809 12297,7100 -1851,7098 -1854,7102 -1854,7107 -1856,7107 -1858,7110 -1854,7110 -1851,7113 -1851,7115 -1851,7120 -1851,7123 -1847,7124 -1852,7125 -1852,7127 -1852,7131 -1852,7129 1148,7129 1145,7133 1150,7137 1148,7138 1147,7143 1149,7147 1154,8147 1155,8152 3155,8147 3157,8143 3158,8144 3160,8144 3164,11144 3167,11146 3167,11148 3163,11152 3161,11148 3159,11149 3163,11150 3161,11151 3166,11154 3171,11154 3170,8144 3160,8144 3163,8144 3166,8145 3166,8146 3171,8146 3174,8144 3174,8144 3174,8145 3176,8141 3180,3141 3182,7141 3183,7141 7183,7136 7185,7136 7185,7133 7187,7136 7187,7131 7190,7136 7194,7137 7197,7141 7196,7139 7199,12139 7200,12143 7200,12143 7199,12144 7203,12145 7200,12141 7200,12136 7195,12136 7191,12137 7191,12137 7196,12139 7197,12140 7197,12137 7201,12140 7204,12140 7209,12143 7209,12145 7210,12147 7214,12148 9214,12152 9218,12149 9218,12149 9221,12149 9220,12150 9222,12153 10222,12153 10226,12156 10227,12159 10223,12160 10220,12161 10225,12161 10227,12163 10224,12163 10223,12158 10224,12158 10227,12158 10231,12155 12231,12157 12226,7136 7185,7139 7189,7139 7189,7139 7188,7137 7191,7139 7191,7140 7189,7143 7191,7144 7189,7144 7190,7149 7193,7152 7194,7154 7198,7153 7203,7148 7207,12148 7209,12146 7209,12145 7213,12140 7217,12139 7219,12141 7219,12138 7218,12143 7218,13143 7220,13140 7224,13142 7228,13137 7231,13142 7235,13146 7239,13149 7243,13148 7247,13150 7248,13155 7249,13155 7253,13155 7253,13155 7258,13157 7260,13162 7255,13159 7255,13163 7258,13164 7258,13164 7263,13167 7264,13167 8264,13165 8265,13169 8265,13171 13265,13175 13261,13176 13259,13176 13259,13180 13262,13181 13262,13183 13262,13188 13265,13191 13267,13191 13265,13194 13267,13191 13269,13192 13264,13196 13269,13198 13272,13200 13272,13202 13270,13207 11270,13211 11270,13211 11273,13213 11274,13217 11275,13222 11276,13222 11272,13226 11274,13231 11277,13233 11282,13236 11284,13238 11284,13236 11286,13236 11288,13236 11283,13236 11284,13238 11289,13241 11292,13244 11292,13245 11289,13241 11294,13244 11298,13249 11301,320 22358,324 24358,328 24358,327 24363,326 24359,327 24361,329 24365,334 24367,-666 24367,-670 24368,49 123,46 127,46 129,49 131,49 136,47 135,45 138,3045 135,3042 138,3044 139,3044 144,3049 144,3053 142,3055 137,3058 136,3053 139,3048 142,7048 138,7048 3138,7048 3139,7048 3140,7050 3145,7053 1145,7050 1146,7053 5146,7048 5150,7047 5146,10047 5147,10043 5147,10047 5147,10050 5152,10052 5155,10054 5156,10056 5157,10056 5159,10058 5162,10062 5164,10062 5169,10066 9169,10068 9168,10063 9164,10063 9169,10061 9171,14061 9172,14061 9174,282 22342,287 22347,288 22347,288 22343,285 22339,280 22338,278 22341,279 25341,284 25343,13241 11294,13246 11296,13243 11296,13244 11291,13245 11291,13244 11291,13246 11295,13251 11300,13253 11305,13253 11306,13258 11305,13255 11306,13256 11309,13256 11311,13261 11307,13265 11303,13267 11305,13270 11301,13275 11298,13271 11300,15271 11302,15276 11306,15279 11303,15284 11305,15286 11305,15289 11307,15290 11302,15292 11305,15296 11309,15297 11313,15298 11316,15300 11317,15304 11320,15306 11324,15306 11320,15307 11320,15312 11320,15313 11319,15317 11317,15315 11321,15317 11323,15317 11328,15319 11333,15322 11336,15322 11337,15322 11337,15324 11341,15324 11345,15325 14345,15328 13345,17328 13346,17333 13349,17337 13354,17338 13358,17342 13358,17346 13353,17348 13353,17345 13353,17348 13354,17347 13354,17347 13354,17347 13355,22347 13358,22349 13355,22351 13355,22356 13354,22358 13354,22361 13355,22362 13355,22358 13355,22359 13359,22364 13364,22369 13369,22372 13373,22376 13371,22377 13371,22377 13369,22381 13374,22386 13379,22387 13376,22387 13380,22392 13378,22390 13374,22392 13378,22391 13378,22391 13375,22392 13378,22390 13380,22393 13382,22398 13387,22398 10387,22402 10391,22399 10392,22400 10392,22400 10394,22404 10391,22403 15391,22405 15392,22407 15392,22412 15387,22412 15390,22412 15394,22408 15396,26408 15398,26407 20398,26411 20402,26415 20406,26417 20411,26420 20407,26422 20407,31422 16407,31421 16405,31421 16410,31423 16410,31426 16414,31426 16410,31430 16415,31430 16418,31435 16419,31437 16420,31438 16422,31438 16425,31438 16425,31441 16427,31439 16431,31441 16436,36441 16436,36443 18436,36442 18437,36440 18440,36440 18436,36440 18440,36442 18445,36443 18446,36447 18451,37447 23451,37452 23456,37456 23455,37458 23459,37456 23461,37458 23463,37460 23466,37464 23469,37460 23474,37462 23476,37461 26476,37466 26479,37470 26483,37471 26488,37474 26489,37474 26485,37474 26483,37474 26488,37470 26492,37474 26497,37474 26499,37478 26495,37483 26499,37483 26501,37488 26496,37491 26499,37495 26495,37500 26496,37500 26497,37500 26501,37497 26499,37497 26499,37495 26504,37498 26504,37494 26509,37497 26514,37495 26515,37498 26514,37503 26514,37508 26512,37510 26516,37511 26519,37509 26523,37506 26528,37507 26532,37512 26536,37513 26538,37510 26542,37512 26544,37517 26543,37522 26546,37527 26551,37525 26555,37529 26558,37524 26563,37524 26562,37527 26562,37522 26562,37522 26559,37526 26561,37522 26559,37523 26561,37523 26556,37524 26558,40524 26560,40524 26563,40521 26567,40525 26566,40527 26568,40532 26572,40534 26569,40533 26565,40531 26565,40535 26569,40535 26570,40539 26572,40544 26575,40543 26575,40544 26579,40548 26584,40549 26581,40553 26585,40556 26590,40552 22590,40557 22594,40556 22595,40561 22592,40561 22593,40565 22593,40568 22593,40573 22588,40570 22590,40570 22591,40570 22588,40573 22590,40573 22593,40568 22593,40567 22597,40567 22599,40571 22599,40574 22600,40574 22604,42574 22607,42577 22607,42577 22612,42579 22616,38579 22619,38580 22617,38580 22614,38575 22619,38579 22619,38579 18619,38582 18614,38582 18617,38586 18622,38590 18625,38590 18622,38594 18621,38596 18616,38597 18614,38597 18618,38600 21618,38601 21618,38605 21620,38607 25620,38611 25620,38608 25617,38608 25621,38608 25625,38611 25623,38615 25623,38615 25620,38616 25622,38619 25624,38620 25625,38620 26625,38623 26627,38623 26627,311 22358,311 22359,-1689 22360,2311 27360,2312 27360,2312 27360,2317 27362,2317 27362,2319 27359,2319 27364,2318 27359,2321 27364,2326 27367,2325 27371,2326 27373,2326 27373,2325 27377,2329 27377,2327 27377,2330 27379,2333 27379,2331 27379,2331 27381,2336 27381,6336 27382,6336 27383,40527 26568,40531 26572,40533 26574,40538 26576,40533 26580,40538 26585,40539 26588,40536 26583,40540 26587,40539 26588,40535 26593,40540 26594,40544 26597,40548 26602,40548 26601,40549 26602,40547 26602,40548 26603,40553 26606,40548 26606,40548 26603,40551 26608,40556 26612,40559 26616,40554 26619,40556 26619,40556 26623,42556 26623,42556 26624,42560 26624,42562 26626,42563 26630,42564 26630,42564 26634,42559 26635,42562 26635,42565 26637,42562 26638,42564 26642,42564 26641,42568 26641,42572 26641,42572 29641,42574 29642,39574 29641,39574 34641,39576 34643,39581 34638,39578 34638,39574 34642,39574 34645,39572 35645,34572 35648,34577 35651,39577 35655,43577 35659,43580 35655,43575 35658,43578 35658,43581 35662,43577 39662,43572 39658,43572 39661,43572 39664,43572 39666,43576 39670,43577 39667,43580 39671,43576 39673,43573 39673,43574 39677,43569 39679,43567 39679,43568 39683,43563 39686,43566 39690,43566 39692,43568 39694,43568 39695,41568 39691,41570 39692,41571 39692,41571 39693,41571 39698,41571 39698,41574 39698,41569 39698,41570 39699,41570 39704,41572 39709,41573 39712,41578 39713,41579 39717,41584 39719,41585 39720,-1850 5268,-1845 5268,-1847 5266,-1842 5268,-1840 5263,-1845 5264,-1843 5264,-1839 8264,-1839 8267,-1839 8272,-1838 8276,-1834 8273,-1834 8273,-1833 8274,-1837 8279,-1836 8283,-1834 8286,-1836 8282,-1834 8279,-1835 8279,-1834 8280,-1836 8283,-1841 8288,-1846 8289,-1843 8286,-1838 8286,-1841 8285,-1838 8285,-1834 8288,-1829 8291,-1825 8286,-1825 8289,-1825 8287,-1824 8291,-1822 8294,-1821 8298,-1818 8300,-1818 8296,-1814 8296,-1811 8295,-1808 8292,1192 8296,1192 8297,1195 11297,1192 11301,1195 11305,1197 11300,1193 11300,1193 11296,1193 11293,1194 11294,1199 11292,1204 11292,1205 11294,1210 11292,1208 11288,1204 11290,1205 11289,1207 8289,1202 8284,1204 8282,1204 8281,1206 8281,1208 8281,1212 8283,1212 13283,1213 13287,1213 13290,1216 13293,1214 13289,1217 13286,1212 13291,1208 13288,1208 13292,1209 13297,1208 13296,1204 13298,1205 13303,1209 13308,1204 13308,1209 13304,1210 13304,1214 13309,1214 13314,1215 13314,1219 13314,1219 13319,1224 13320,1229 13321,1232 13325,1233 13329,1231 13329,1234 13334,-2766 13336,-2769 13337,-2765 13340,-2762 13345,-2760 13342,2240 13342,2238 13342,2242 13342,2246 13345,2246 13346,2244 13348,2239 13348,2240 13351,2240 13352,2245 13357,2248 13357,2243 13362,2247 13362,2248 13362,2252 13363,2256 13363,2256 13363,2260 13367,2255 13372,2251 13369,2251 13369,2252 13372,2249 13376,2254 13378,2255 13382,2259 13379,2262 13379,2267 13381,2262 13381,2262 13383,2265 13383,2269 13385,2270 13386,2271 13389,2267 13391,2271 13386,2275 13391,2273 13392,2275 13387,2277 13390,2274 13390,2275 13394,2280 13395,2280 11395,2281 14395,2279 14400,2277 14403,2273 14406,2274 16406,2274 16410,2279 16410,2284 16411,2280 16409,2280 16409,2282 16409,2282 16411,2282 16412,2280 16413,3280 16418,3284 16418,3285 16423,3289 16423,3292 16427,3294 16429,3296 16431,3297 16436,3298 16435,3303 16435,3305 16434,3305 16436,3305 16436,3309 16437,3309 16438,3308 16439,3308 16439,3306 16444,3302 16441,-1698 16437,-1703 16438,-1699 16438,-1697 16438,-1698 16439,-1695 16436,-1690 16441,-1687 16446,-1683 16450,-1682 16451,-1684 16453,-1682 16457,-1682 16457,-1686 16460,-1681 16459,-1680 16456,-1677 16460,-1681 16461,-1679 16464,-1674 16465,-1673 16469,-1669 16471,-1669 16476,-1665 16474,-1665 16478,-1664 16478,-1664 16479,-1661 16474,-1656 16471,-1655 11471,-1660 11473,-1663 11475,-1666 11480,3334 15480,3338 15476,3342 15471,3345 15471,3345 15470,3350 15469,3347 15474,3351 15476,3352 15473,3353 15476,3350 15477,3350 15479,3351 15482,3352 15484,3351 15487,3353 15487,3358 15487,3353 15486,1217 13286,1222 13291,1222 13291,1225 13286,1229 13286,1231 13281,1235 13280,1236 13281,1241 13282,1245 13285,1247 13285,1247 13287,1250 13287,1247 13290,1247 13295,1247 13298,1252 13301,1249 13304,1252 13304,3252 13304,3247 13304,3249 13308,3254 13308,3257 13308,3261 17308,3261 17309,3261 17306,3259 17305,3262 17310,3263 17308,3262 17311,3259 17314,3259 17314,3257 17309,3254 17309,3253 17309,3255 17310,3253 17312,3255 17312,3255 17312,3256 17307,3257 17307,3256 17311,3256 17313,3255 17317,3251 17317,3248 17321,3253 17325,3256 17326,3258 17324,3258 17327,3263 17322,7263 17325,7265 17328,7263 17330,7265 17333,7270 17333,7273 17333,7278 17336,4278 21336,4278 21340,4279 21340,4281 21340,4286 24340,4290 24343,9290 24347,9294 24349,9296 24347,9298 25347,9301 25348,9301 25348,9304 25353,9303 25357,9303 25352,11303 25355,11304 25358,11307 25358,11312 25358,11312 25361,11310 25365,11313 25365,11314 25369,11319 25371,11321 25371,11325 25366,11329 25365,11330 25366,11329 25370,11330 25365,11334 25367,11338 25366,11343 25363,11348 25359,11345 25356,11348 25357,11349 25358,11349 25358,11352 25360,11356 30360,11360 30365,11360 30365,11362 30365,11367 30367,11368 30369,15368 30370,15373 30371,15376 30373,14376 30378,14377 30383,14381 30378,14386 30380,14388 30382,14391 30385,14393 31385,16393 31389,16396 31394,16396 31397,16392 31400,16395 31405,16398 31409,16398 31413,16397 31415,16396 31417,16401 31418,16401 31422,16402 31419,16407 31420,16411 31419,16406 31423,18406 31427,18411 31432,18415 28432,18417 28437,18418 28441,18414 28438,18417 28435,18416 28439,18420 28442,18423 28447,18427 28444,21427 28445,21428 28450,22428 28455,22432 28457,22436 28458,22441 28458,22445 28463,22448 28468,22451 28465,22456 28468,22453 28468,22458 28471,22463 28473,22460 28475,22459 28472,22463 28476,22464 28472,22468 28468,22468 28471,25468 28466,25471 28468,25473 28464,25473 28464,25475 29464,25476 29466,25479 29461,25476 29462,25476 29464,25478 29464,25483 29461,25484 29460,25486 29458,25486 29462,25490 29460,25495 26460,25498 26463,25495 26468,25495 26472,25495 26472,25499 26474,25504 26476,25504 26478,25509 26476,25513 26479,25514 26481,25519 26477,25519 26480,25518 26481,25519 26484,25524 26483,25527 26484,25522 26484,25526 26487,25528 26492,25533 26496,25535 26498,25535 26498,25539 26503,25542 26504,25543 26505,25547 26510,25552 26510,25551 26508,25550 26512,25553 26510,25557 26510,25554 26511,25552 26508,25556 26505,25556 26506,25560 26506,25560 26507,25560 26506,25565 26501,25567 26504,25569 26504,25568 26508,25571 26508,25571 26511,25576 26511,25581 26516,25581 26519,25582 26521,25585 26522,25588 26527,25588 26526,25584 26530,25587 26534,25589 26529,25593 26533,25598 26538,25599 26540,25599 26540,25599 26540,25604 26543,25603 26543,25603 26538,25606 26538,25609 26540,25611 26542,25612 26547,25612 26547,25612 26548,25617 25548,25612 25548,25613 25547,25616 25545,25616 25549,25618 25551,25620 25555,25620 25551,25622 25550,25625 25551,25622 25555,25619 25557,25617 25556,25622 28556,25625 28551,25630 28546,25634 28548,25639 28553,25643 28553,25638 25553,25634 25553,25634 25557,25639 25557,25643 25558,25644 25553,25646 25556,25647 25560,25650 25562,25650 30562,25650 30562,25650 30564,25650 30566,25652 30570,25656 30571,25661 31571,25662 31575,25663 31579,25662 31579,25665 31581,25666 31584,25671 31582,25674 31581,25674 31584,25676 31584,25673 31587,25678 31586,25679 31581,30679 31584,30675 31589,30680 31590,35680 31590,35675 31589,35677 31591,35680 31590,35681 31587,35684 31588,35685 31589,35689 31592,35689 31593,35692 31597,35696 31597,35700 34597,35699 34599,35703 34604,35703 34606,35702 34601,35705 34603,35705 34606,35708 34603,35713 34604,35717 34603,35719 34608,35715 34608,35711 34608,35713 34609,35714 34605,35714 34610,35714 34614,35718 34616,35719 34617,35722 34618,35722 34621,35725 34625,35725 34626,35725 34629,35725 34631,35725 34635,35730 34636,35727 34638,35731 34640,35735 34642,35739 34645,35741 34645,35742 34649,35738 34649,35738 34645,35741 34647,38741 34650,38741 37650,38742 37646,38746 37651,38749 37652,38753 37653,38753 37657,38757 37656,38756 37660,38761 37660,38765 37660,38760 37660,38759 37660,38760 41660,38760 41660,38762 41665,38757 41667,43757 41669,43752 41674,43752 41677,43757 41672,43758 41677,45758 41680,45758 41679,45762 41683,45765 41683,45769 41683,45770 41684,45768 46684,45773 46688,45776 46692,45774 46694,45775 46697,45778 46695,45776 46698,45774 46702,45779 46702,45784 46704,45787 46706,45791 46711,45786 46707,45790 46711,45793 46715,45796 46719,45799 46724,45797 46728,45802 46726,45797 46729,45801 46733,45802 46733,45803 46732,45804 46732,45805 46732,45808 46735,45810 46740,45810 46744,2326 27373,2322 27377,2323 27379,2325 27383,2325 27382,2322 27382,2323 27382,5323 23382,5325 23385,5329 23386,5330 23390,5335 23392,5330 23392,5330 23395,5329 23395,5333 23399,5333 23402,5338 23405,5339 23405,5334 23406,5329 23401,5332 23403,5330 23407,5333 23409,5328 20409,5324 20411,5324 20414,5329 20416,5328 20421,5325 20421,5329 20424,5330 20424,5335 21424,5331 21427,5333 21431,5334 21433,5329 21434,5330 21437,5333 21440,5338 21437,5338 21440,5334 21441,5333 21438,5329 26438,5332 26435,5335 26439,5337 26440,5338 26444,5342 26439,5342 26442,5345 26440,5349 26438,5352 26442,5349 26445,5348 30445,5350 30447,5350 30444,5354 30444,5359 30443,5363 30445,5367 30446,5367 30448,5367 30453,5371 30455,5371 30453,5373 30458,5375 30461,5380 30463,5384 30463,5383 30459,5384 30459,5383 30459,5385 30460,5390 30459,5392 30464,5394 30464,5389 30465,5393 30469,5391 30469,5391 30469,5395 30474,5396 30470,5399 30470,5401 30467,5401 30468,5404 30470,5400 30465,5401 30462,5403 30467,5404 30467,5409 30469,5412 30473,5412 30477,5407 30481,8407 30486,8408 30489,8410 30490,8410 30489,8413 30490,8414 30493,8414 30496,8419 30501,8420 30502,8415 30507,13415 30509,13411 30506,13414 30507,13412 30511,13412 30515,13417 30518,13419 30523,13418 30527,13422 30529,13418 30531,13413 35531,13409 35531,13413 35532,13417 35537,13419 35533,13423 35529,13424 35529,13423 35524,13428 35525,13433 35526,13438 35530,13443 35531,13448 35531,13452 35532,13455 35536,13457 35536,13452 35536,13455 35539,13452 35535,13457 35540,13457 35544,18457 35546,18460 35547,22460 35546,22465 35550,22466 35554,22468 35552,22473 35555,22471 35559,22470 35564,22472 35564,22470 35569,22474 35569,22474 35571,22477 35573,22482 35576,22487 35580,22488 35583,22489 35585,22493 35585,22496 35585,25496 35586,25493 35582,25494 35585,25498 35585,25496 35585,25498 35587,25503 35591,25503 35593,25499 35590,25499 35591,25495 35591,26495 35595,29495 35591,29495 35593,29498 35597,29498 35601,29500 35606,29501 30606,29502 30603,29505 30603,29510 30606,29511 30606,29514 30607,29516 30610,29518 30608,3259 17305,3263 17304,3267 17303,3271 17308,3269 17312,3269 17313,3274 17315,3277 17315,3282 17311,3285 17313,3283 17309,3278 17310,3275 17315,3275 17317,3276 17322,3280 17324,3280 17324,3276 17325,3277 17325,3276 17328,3278 17324,3273 17329,3277 17331,3280 17326,3281 17328,3276 17324,3277 17324,3277 17322,3277 17321,3277 17321,3281 17323,3282 17327,3282 17332,3287 17335,3288 17335,3288 17338,3290 17337,3294 17340,3294 17341,3299 17341,3299 12341,3299 12342,3304 12339,3301 14339,3305 14340,3307 14341,3311 14343,3313 14343,3314 16343,3310 16341,3310 16346,3312 16348,3311 16349,4311 16346,4316 16348,4321 16344,4324 16348,4322 16349,4323 16346,4323 16346,4326 16350,4322 16354,4323 16356,4325 16361,4325 16358,4322 16362,4325 20362,4325 20366,4322 20367,4326 20372,4326 20374,4331 20373,4333 20373,4338 20376,4339 20379,4341 20382,4338 20384,4339 20386,4340 20383,4340 20383,4335 20388,4336 20390,4341 20390,4346 20391,4348 20391,4349 20393,37497 26499,37494 26496,37496 26500,37496 26501,37499 26506,37497 26502,37498 26502,37500 29502,37500 29507,37505 29508,37506 33508,37508 33513,37513 33518,37517 33522,37516 33520,37521 33521,37521 33525,37516 33530,37519 33528,37520 33528,37524 33530,37527 33530,37525 33527,37528 33530,37533 33533,37534 38533,37536 38536,22358 13355,25358 13360,25361 13358,25362 13362,25362 13362,25365 13365,25363 13367,25359 13369,25357 13374,25360 13374,2247 13362,2252 13366,2254 13363,2257 13363,2261 13358,2264 13354,2264 13356,2269 13361,2272 13363,2274 13363,2275 13363,2273 13362,2274 13365,2278 13365,2280 13370,2284 13366,2284 13365,2289 13368,2290 13366,2293 13368,2298 13373,2298 13372,2295 13375,271 22347,273 22350,4273 22347,4269 22348,4270 22350,4271 22355,4272 22360,4276 22363,4281 22365,4284 24365,4279 24365,4282 24365,4285 24365,4287 24364,4289 24362,4294 24360,4295 24362,4298 24365,4301 24369,1301 24370,1301 24371,1305 24375,1305 24376,1307 24377,1312 24380,1314 24382,1318 24380,1316 24382,1316 24387,1318 24387,1318 29387,1321 29387,1316 29383,1320 29386,1321 29389,1326 29389,1327 29389,2327 29394,2327 29394,2332 29393,-666 24367,-663 24368,-661 24368,-656 24371,-653 24372,-649 24372,-647 24374,-643 24370,-638 24375,-635 24380,-638 24382,-638 24384,-638 24384,-636 24388,-637 24390,-632 24386,-630 24386,-629 24386,371 24389,376 24394,374 24392,377 24397,3377 24400,6377 24405,6378 24408,6373 24406,6370 24406,6375 24403,6370 24403,6375 24403,6379 24406,6374 24409,6378 24411,6380 24412,6378 24415,6378 24419,6383 24423,6385 24425,6387 24428,6390 24433,6386 24430,6386 24435,6387 24436,6388 24440,6387 24444,6383 29444,6383 29447,6386 29451,6382 29446,6387 29447,6390 29452,6393 29452,6397 29455,6400 29459,6400 29463,6397 29467,6393 29467,6395 29470,6397 29473,6399 29468,6394 29467,6397 29470,6396 29473,6396 29470,6393 29465,6389 29469,6390 29470,6389 29465,6389 29468,6392 29470,6388 33470,6390 33466,6391 33466,6392 33467,6394 33467,322 22372,322 22374,323 22377,327 22378,331 22382,330 22383,332 22386,333 22383,331 22383,330 22387,332 22391,332 22396,337 22397,339 22394,340 22399,340 22398,340 22396,343 22396,343 22396,341 22400,342 22404,343 22402,348 22403,345 22407,347 22411,342 22411,345 22413,340 22417,345 22417,348 22422,348 22426,351 22427,352 22432,352 22436,4352 22438,4353 22442,4354 22444,4354 22447,4357 22449,4360 22450,4364 22450,4367 22451,4369 22453,4366 22455,4369 22453,4373 22458,4377 22459,4380 22459,4380 22464,4385 22467,4385 22467,4390 22469,4385 22469,4385 22472,25571 26508,25574 26507,25578 26512,25581 26512,25581 26512,25583 26508,25583 26513,25587 26516,25589 26515,25590 26515,25591 26517,25589 26520,25587 26522,23587 26526,23585 26531,23589 26534,23592 26538,24592 26543,24588 26545,24593 26547,24598 26543,24598 26548,24602 26545,24598 26540,24600 26545,24600 26548,24600 31548,24605 31549,24608 31551,24613 31552,24615 36552,24616 36557,24619 36557,24622 36560,24622 36564,24627 35564,24627 35569,24632 35569,25632 35570,25635 35569,25636 35573,25636 35573,25638 35576,25641 35580,25641 35583,25641 35588,25642 40588,20642 40593,20645 40593,20650 40595,20651 40591,20651 40594,20648 40591,20648 40591,20652 40596,20652 40596,20656 40597,20656 40600,20656 40601,20659 40598,20662 40597,20662 40597,20663 40600,20668 40601,20665 40606,1215 13314,1214 13319,1212 13317,1209 13312,1210 13312,1211 13317,6211 13320,6214 13320,6216 13320,6211 13323,6214 13318,6214 13323,6214 13324,6216 13319,6219 13323,6218 13321,6219 13321,6218 13326,6221 13329,6225 13331,6230 13335,6231 13339,6231 13343,6235 13338,6234 13342,6234 13344,6236 13345,25524 26483,25521 26484,25524 26489,25527 26487,25529 26484,25530 26482,25534 27482,25539 27486,25537 27488,25541 27483,25544 27486,25547 27490,25550 27491,25550 27491,25554 27486,25559 27486,25563 27489,25561 27489,25563 27493,25561 27491,25563 27493,25563 27495,25564 27497,25563 27497,25563 27497,25558 27498,25563 27499,25565 27503,25567 27503,25569 27503,25567 27504,25565 27505,25565 27505,25565 27505,25566 27505,25570 27501,25570 27497,25574 27498,25570 32498,25570 32501,25573 32501,25576 32497,25576 32498,25577 32501,25579 32503,25583 32504,25588 32507,25592 32512,25596 32507,25599 32507,25594 32503,25597 32506,25597 32510,25594 32509,25594 32510,25596 32513,25592 32513,25594 32515,25594 32520,25598 32520,25602 32517,25603 32518,27603 32520,27607 32523,27608 31523,27613 31527,27615 31527,30615 31530,30617 31530,30618 31532,30619 31536,30623 31537,30623 31538,30625 31538,30626 31541,30627 31541,30624 31540,30623 31540,30624 31545,34624 31546,34619 31543,34623 31545,34624 31549,34624 31548,34626 31550,34626 31555,34626 31551,34628 31555,34633 31555,34636 31559,34634 31564,34636 31564,34639 31562,34639 31560,36639 31555,36636 27555,41636 27557,41640 27554,41644 27558,41647 27559,41648 27555,41653 27555,41658 27555,41658 27552,41658 27552,41660 27550,41656 27554,41661 27558,41664 27561,41667 27566,41662 27562,41663 27563,41663 27565,41662 27569,41661 27569,41664 27571,41664 27567,41659 30567,41660 30565,41660 30561,41665 30566,41664 30561,41664 30561,41664 30562,41664 30563,41660 30558,1312 24380,4312 25380,4315 25384,4315 25385,4319 25383,4322 25388,6322 25387,6322 25387,6326 25392,6321 25397,6324 25397,6324 25401,6319 25404,9319 25405,9314 25400,9312 25402,9310 25403,9313 25403,9313 25403,9316 25400,9319 25401,4319 25396,8319 25398,8315 25400,8315 25396,8315 25397,8311 25398,8307 25394,8309 25394,8311 25397,8315 25402,8310 25403,11310 25365,11311 25365,11316 25370,11320 25375,11325 25375,11325 25380,11325 25382,11326 25378,14326 25380,14328 25382,14331 25383,14334 25385,14336 25386,19336 25386,19336 25389,19332 25390,19332 25391,19335 25388,19338 25391,19342 25393,19340 25393,19345 25396,19345 25394,19347 25394,19349 25393,19351 25397,19350 25398,19348 25399,19349 25403,19352 25399,19350 25402,19354 25400,19353 25405,23353 25402,23354 25402,23356 25405,23358 25409,23360 25413,23363 25414,23367 25412,23365 25411,23367 25414,23363 25413,23367 25416,23367 25416,23370 25418,24370 25414,24370 25419,24373 27419,24378 27419,24380 27416,24380 27412,24380 27410,24380 27406,24376 27406,24374 27410,24370 27414,24370 27415,24371 27420,24375 27415,24378 27411,24375 27415,24378 27418,24382 27421,24383 27426,24383 27425,24385 27430,24390 27431,24394 27432,24395 27436,24399 30436,24400 30439,24404 30443,24403 30439,24406 30438,24410 30442,24406 30446,24408 30445,24403 30445,24408 30442,24412 30446,24416 30446,24416 30449,19416 30449,19416 30447,19418 30452,19420 30453,19423 30458,15423 30462,15423 30464,15425 30466,16425 30467,16424 30471,16421 30474,16426 30474,16428 30476,16428 30476,16424 30474,16424 33474,16425 33474,16427 33477,16425 33479,16426 33477,16422 33480,16425 33482,16430 33479,16430 33478,16429 33482,16424 33482,16427 33484,16430 33488,16431 33488,16434 33488,16435 33491,16432 33487,16436 37487,16434 37490,16438 37485,16443 37482,16446 37480,16447 37480,16447 37482,16451 37478,16454 37479,16458 37479,16454 37479,16454 37482,16459 37486,16460 37491,16463 37495,16464 37492,16465 37493,16466 37494,16468 37497,16468 37501,16468 37501,16473 37503,16473 37503,16473 37498,16476 37494,21476 33494,21473 33493,21476 33489,21478 33491,21478 33496,21478 33492,21480 33496,21483 33501,21484 33504,21483 33500,21484 33505,21484 33505,21488 35505,21491 35505,21494 35506,21496 35510,21492 35506,21492 35509,21489 35514,21490 35517,21487 35519,23487 35523,23485 35528,23487 35533,23483 35534,23487 35535,23488 35537,23493 35539,23495 35542,23495 35546,23495 35550,23491 35549,23488 35552,23492 35555,23495 35560,23500 35559,23496 35557,4322 16354,4317 16358,4318 16358,4320 16363,4315 16363,4315 16362,4316 20362,4320 20365,4323 20363,4326 20366,4329 20367,4332 20370,4337 20374,4338 20375,4333 20375,4338 20375,4341 20377,4342 20377,4342 20378,4343 20381,4346 20386,4346 20386,4346 20386,4346 20386,4349 20390,4352 20395,4354 20396,4355 20400,4358 20400,4360 20401,4360 20404,4363 20405,4368 20406,4372 20411,4371 20416,4367 20417,4364 20422,4367 20420,4372 20425,4373 20422,4374 20418,4377 20418,4381 20422,4382 20423,4384 20418,4389 20421,4385 20423,4390 20423,4390 20425,4392 20429,4396 20434,41574 39698,41578 39702,41576 39704,45576 39704,45575 39709,45577 39713,45581 39715,45581 39718,45583 39721,45578 39726,47578 39722,47581 39719,47586 39722,47586 39726,47589 39730,47592 39733,47597 39733,47593 39733,47596 39735,47597 39735,47595 39735,47591 39739,47593 39744,47593 39747,4074 20263,4077 20268,4079 20268,4078 20271,4078 22271,4083 22276,4087 22272,4088 22275,4086 22279,4082 22280,4084 22282,4086 22277,4082 22277,4087 22281,4090 22281,4092 22281,4092 22286,4094 22287,4097 22290,4097 22291,4095 22286,4095 22288,4095 22293,4095 22288,4092 22285,4089 22286,4090 22286,4095 22281,4100 22286,4103 22285,4104 22288,4104 22289,4107 22294,4112 22292,4117 22290,4120 22295,120 22300,121 22303,122 22300,122 22300,121 26300,125 26303,129 26303,127 26305,127 26306,132 26306,132 26307,136 26307,141 26309,140 26311,143 26313,140 26314,145 26318,149 26318,153 26321,153 29321,158 29326,158 29329,162 29324,162 34324,165 34329,168 34328,167 34332,169 34333,173 34334,173 34336,177 34338,178 34340,178 34344,182 34348,177 34348,182 34348,184 34353,184 34358,181 34360,183 34365,187 34365,192 34365,197 34367,199 34366,203 34368,205 34368,202 34363,204 34360,1204 34360,1205 34364,1205 30364,1205 30359,1206 30361,1207 30364,1210 30366,1210 30366,1214 30367,1218 30372,1219 30375,1214 30379,1214 30384,1217 30382,1222 30383,1223 30382,1225 30380,1228 30379,1231 30383,1232 30383,1235 30384,1237 30388,1242 30386,1244 30389,2244 30392,2241 30395,2245 30397,2245 30399,2244 30394,2242 30395,2246 32395,2246 32395,2249 32398,2251 32393,5251 32390,5251 32395,5255 32399,5255 32397,5257 32397,5257 32401,5261 32406,5261 32411,5266 32412,5271 32416,5273 32419,5276 32420,5281 32422,5279 32425,6279 33425,6284 33429,6284 33430,6282 33431,6282 33428,6286 33425,6288 32425,6288 32421,6286 32424,6288 32424,11288 32427,11292 32425,11292 32429,11290 32434,11286 32437,11286 32437,11283 32442,11278 32442,11279 32443,11283 32445,11284 32445,11283 32448,13283 32447,13287 32442,16287 32446,16282 32445,16283 32445,16284 32448,16285 32448,16284 32446,16286 32443,16290 32446,16291 32446,16292 32450,16291 32450,16291 32450,16291 32445,16287 32447,16288 32452,16287 32457,16291 36457,16289 36462,16293 36462,16294 36462,16297 36462,16301 36464,16306 36469,16310 36467,16310 36463,16313 36459,16312 36460,16313 36465,16313 36469,16308 36470,16309 36468,16314 36470,16319 41470,16322 41471,16325 44471,16330 44471,16330 44471,16330 44473,16330 44474,16335 44479,16332 44477,8414 30496,8415 30497,8419 30497,8414 30501,8416 30500,8418 30495,8421 35495,8423 35494,8427 35497,8429 35499,8432 35499,8436 35503,8438 35503,8443 35505,8440 35508,8443 35509,8440 35509,8440 35511,8441 35515,8445 35511,8448 35512,8443 35517,8443 35519,8442 35524,8444 35526,8441 35527,8436 35527,8433 35523,8429 35527,8430 35530,8431 35532,8429 35533,8433 35535,8437 32535,8435 32536,8439 32536,8436 32539,9436 32542,9434 32537,9429 32534,9429 32534,9433 32537,9433 32542,9429 32543,9434 32538,9436 32538,9436 34538,7436 34538,7438 34543,7439 34543,7439 34543,7439 34548,7438 34549,7438 34552,7438 34553,7438 34556,11438 34561,11434 34559,11436 34555,7436 34553,7436 34549,120 1235,124 1239,125 1236,125 1238,129 1235,128 1235,125 1236,123 1239,128 2239,132 2242,131 2242,135 2242,140 2242,145 2247,146 2252,144 2253,146 2248,144 2245,146 2244,150 2249,155 2245,159 2242,160 2243,160 2245,155 2244,156 2245,3156 2246,3159 2248,3159 2250,3164 2254,3165 2257,3166 2255,3169 2257,3171 2262,3169 2263,3174 2268,3177 2273,3174 2276,3178 2275,3173 2279,3177 2276,3180 2279,3182 2284,3185 2289,5185 2286,5185 2288,5181 2286,5185 2288,5184 2293,5187 2293,5187 2297,5190 2299,5187 2299,5185 2300,5181 6300,5182 6297,5187 6300,5189 6298,5191 6296,5193 6296,5193 6296,5195 6297,5195 6300,5197 6297,5195 6300,5190 6302,5191 6306,5192 6308,5195 6312,24395 27436,24391 27437,24393 27433,24398 27436,24398 27437,16286 32443,21286 32443,21286 32444,21282 32448,21283 32446,21283 32448,21285 32451,21281 32456,21282 32458,21282 32463,21282 32468,21284 32470,21289 32471,21287 32471,21287 32469,21287 32474,21284 32477,21288 32482,21291 32482,21291 32486,21296 32485,21299 32486,21301 32487,21303 32484,21301 32482,21305 32487,21310 32491,21312 32495,21313 32491,21315 32495,21312 32495,21314 32498,21316 32501,21311 32506,21311 32508,21312 32513,21317 32516,21319 32516,21324 32516,21327 32521,21328 32526,21332 32527,21328 36527,21331 41527,21336 41527,21334 41531,21337 41533,21335 41535,21339 41540,21340 41540,21343 41536,25343 41539,25340 41542,25337 41542,25337 41545,25335 41542,25335 41543,25335 46543,25339 46548,30339 46551,30340 46556,30343 46557,30342 46553,30337 46556,30341 46561,30337 46565,30336 46563,30338 46564,24373 27419,24373 27421,24375 27424,24377 27425,24377 27430,24374 27435,24379 27437,24384 27432,24385 27434,24382 27437,24381 27442,24381 31442,24381 33442,20381 33439,20383 34439,20382 34440,20378 34444,20381 34446,20381 34442,20384 34443,20388 34446,20392 34447,20393 34442,20393 34447,20396 29447,20395 29443,20399 29443,20400 29439,20399 29436,20404 29439,20409 29440,20410 29440,20410 29444,20408 29445,20413 29448,20413 29451,20412 29455,20413 29458,20418 29461,20413 29463,20415 29464,20416 29464,20416 29463,20416 29463,20418 29464,20414 29465,20418 29463,20413 29460,20413 26460,20418 26458,20421 26459,20421 26461,20421 26460,43578 35658,43578 35654,43578 35658,43578 35660,43583 35661,43583 35659,43583 35662,43579 35663,43583 35661,43587 35666,25625 25551,25629 25551,25630 25554,25630 25559,25632 25560,25627 25561,25623 25557,25623 25559,25624 25561,26624 25566,26627 25566,29627 25571,29626 25574,29625 25575,29622 25579,29625 25583,29630 25588,29632 25589,29635 25591,29635 25594,29637 25598,29642 25596,29643 25597,29644 25597,29649 25598,29654 25602,29656 25602,29661 25603,29661 25601,29664 26601,29666 26604,29665 26604,29668 26607,29672 26607,29669 26611,29671 26616,29674 26613,29679 26616,29680 26616,29681 26615,29682 26619,29679 26617,29684 26622,29686 26624,29689 26624,29690 26628,29691 26630,29693 26625,29694 26620,29698 26617,29703 29617,29707 29616,29706 29620,29709 29623,34709 29626,34710 29628,34710 29627,2282 16411,2283 16412,2283 16412,2287 16417,2292 16421,2297 16421,2298 16426,2303 16426,2304 16429,2309 11429,2313 11432,2308 14432,2308 14431,2311 14433,2310 14437,2308 14438,2309 14440,2311 14440,2309 14443,2312 14443,2314 14447,2314 14452,2314 14450,2309 14451,2309 14451,2309 14456,2313 14461,2313 14461,2309 19461,2309 19461,2311 19462,2315 19465,2318 19465,2321 19462,2317 19464,2321 19467,2322 19467,2322 19469,2322 19469,2320 19464,2321 19462,2322 19461,2327 19466,2327 19461,2322 19461,2322 19463,2317 19467,2318 19471,2102 -1848,2107 -1848,2111 -1846,2114 1154,2114 1156,2115 1157,2114 6157,2116 6162,2121 6165,2124 6170,2121 6175,2124 6179,2124 6183,2128 6178,2126 6179,2125 6178,2126 6181,2122 10181,2127 10186,2128 10189,2130 10188,2130 10191,2127 11191,2127 11195,2131 11196,2132 11192,2131 11197,2135 11201,2135 11203,2139 11199,2142 11203,2143 11204,2147 11208,2142 11210,2142 11211,2147 11212,2150 11217,2150 11219,2151 11219,2152 11222,2152 11222,2148 11224,2150 11220,2150 11223,2146 11218,2143 11219,2140 11221,2143 11218,2140 11219,2140 11223,2145 11225,2147 11226,2152 11226,2155 11224,2157 11229,2157 11229,2153 11233,2153 11238,2149 11239,7149 10239,7154 10241,7157 10241,7162 10243,7164 10248,7164 10251,7169 10253,7171 10253,7172 10257,7177 10260,7182 10256,7187 10260,7191 8260,7195 8256,7200 8258,7204 8258,7203 8261,7203 8262,7205 8266,7209 8270,7209 8273,7214 8273,7214 8276,7210 8276,7211 8276,7213 8279,7218 8278,7222 8283,7223 8279,7220 10279,7221 10283,7223 10284,7228 10286,7230 10290,7231 10290,7231 10293,7232 10294,7232 10297,7234 10299,7229 10295,7226 10294,7221 10293,7223 10295,7228 10299,7229 10303,7232 10307,7232 10311,7233 10316,7234 9316,7239 9318,7244 9321,7241 9326,7241 9328,7238 9331,7235 9330,7237 9335,7236 9335,7236 9337,7236 9338,7231 14338,7230 14333,7232 14338,7237 18338,4082 22280,4081 22280,6081 22283,6076 22285,6076 22289,6078 22286,6080 22287,6084 22292,6084 22293,6085 22293,6086 22291,6091 22294,6092 22293,9092 22290,9095 22294,9096 22295,9096 22297,9091 22292,9096 22295,9098 22290,9094 18290,9097 18290,9096 18294,9099 18292,9098 18297,9103 18299,9103 18302,9103 18305,9100 18301,9102 18302,9106 18305,9102 18310,9101 18306,9103 18308,9103 18312,9107 18310,9107 18315,9107 18320,9111 18322,9111 18326,9113 18329,9111 18329,9116 18329,9121 18329,9121 18332,9123 18331,9124 18332,9125 18328,9127 18325,9125 18328,9128 18329,9133 18329,9136 18333,9141 18337,9142 18342,9143 18340,9148 18344,9152 18341,9150 18346,9149 18341,9149 18341,9154 18343,9158 18345,9161 18346,9161 18347,9163 18352,9164 18352,9162 18349,9165 18352,9165 18351,9165 18352,9165 18356,9163 18352,9167 18353,9167 18349,9168 18351,9168 18347,9173 18347,9175 18347,9179 18348,9182 18349,9187 18352,9186 18357,9189 18360,9192 18360,9196 18362,13196 18367,13196 18369,13196 18371,13199 18374,13194 18374,13197 18375,13200 18377,13205 18380,13210 18384,13209 18379,13209 18374,13213 18375,13216 20375,13212 20375,13215 20375,13211 20375,13211 20372,13208 20373,13204 20373,13204 20369,13205 20369,13207 20366,13212 20367,13216 20367,13221 20372,13222 20377,13225 20381,13226 20386,13230 20383,9230 20388,9228 20384,9228 20386,9223 20389,9223 20392,4223 20397,4223 20396,4225 20399,4222 20404,4220 20408,4220 20411,4223 20416,4227 20421,4230 20418,4234 20421,4232 20422,4236 20423,4238 20423,4239 20423,4235 20427,4231 20427,4230 20426,4228 20428,4232 20427,4232 20431,4236 20433,4241 20431,4241 22431,4236 22436,4239 22437,4239 22439,4236 22443,4232 22439,4236 22444,4236 22446,4239 22447,4239 22452,4241 22454,4245 22457,4245 22460,4250 22462,4251 22465,4253 22465,4249 22465,4251 22460,4251 22464,4255 22469,4257 22473,4256 22478,4259 22479,4260 22480,4257 22485,6257 22489,6260 22490,6260 22493,6262 22496,6262 22500,6267 22495,6271 22495,6276 22491,6276 22489,6281 22487,6286 22490,6289 22490,6294 22490,6294 22489,6292 22485,6292 22489,6288 22489,6288 22494,6288 22496,6286 22497,6288 22501,6292 22500,5292 22503,5292 22503,5296 22508,5295 22510,5300 22510,5305 22513,5302 22514,5306 22510,5309 22513,5313 27513,5313 27513,5317 27513,5322 22513,5326 22517,6326 22516,6323 22518,6323 22523,6320 22523,6321 22526,6323 22531,6323 22531,6324 22532,6324 22532,6325 22529,6321 22531,6323 22534,6328 22534,6329 22530,6324 22527,10324 22522,10319 22524,10315 22520,10314 22525,10311 22525,10307 22526,10304 22531,10306 22527,10306 22528,10309 22530,10312 27530,10312 27534,10312 27534,10307 27536,10307 27532,11307 27531,11307 27533,11308 27535,11303 27531,11298 27532,11294 27534,11294 27534,11299 27538,11297 27542,11302 27547,11306 27547,11311 27549,11313 30549,11317 30551,11313 30546,11316 30541,11316 30540,11319 30545,11318 30546,11323 30550,11326 30554,11326 34554,11330 34558,11331 34558,11333 34558,11332 34561,11328 34561,11331 34562,11336 34562,11336 34567,11340 34570,11342 34569,11345 34568,11344 34569,11345 34571,11349 34574,15349 34574,15354 34569,15359 34566,15362 34571,15363 34576,15367 34577,15368 34577,15371 34581,15374 34576,15379 34574,15383 34579,15384 34584,15387 34583,17387 34578,17392 34578,17391 34578,17396 34573,17397 34578,17397 34580,17397 39580,17402 39584,17397 39587,17402 39587,17406 39582,17403 39587,17407 39589,17409 39592,17406 39592,17409 39595,17409 39599,17412 39603,17416 39608,17417 39608,17417 39608,17421 39607,17422 39609,17424 39608,17427 39604,17425 39605,17426 39609,17423 39611,17422 39610,17425 39613,17428 39618,17428 39619,17429 39616,17432 39616,13432 39615,13432 39617,13432 39617,13432 44617,13434 44621,13434 44623,13439 44627,13442 44632,13442 44635,13440 44631,13442 44631,13445 44635,13447 44639,13445 44637,13445 44638,13450 44639,13454 44644,13457 44644,13459 44642,15459 44639,15457 44644,15461 44644,15462 44642,15459 44645,15459 44647,15463 44650,15458 44651,15459 44653,15461 44657,15463 44661,15463 44661,15463 44663,15467 44666,15472 44668,15474 44664,15470 44668,15471 44670,15473 44674,15475 44675,-3806 12298,-3804 12301,-3805 13301,-3804 13296,-3808 13292,-3809 13295,-3806 13300,-3804 13297,-3801 13301,-3801 13302,-3796 18302,-3801 18306,-3799 18311,-3802 18311,-3799 18312,-3801 18314,-3796 18319,-3795 18322,-3791 18321,-3786 18320,-3786 18321,-3784 18321,-3782 18321,-3781 18324,-3782 18325,-3783 18320,-3788 18324,-1788 18324,-1788 18329,-1784 18333,-1784 18334,-1781 18329,-1777 18334,-6777 18337,-6774 18339,-6776 18341,-6781 18341,-6779 18341,-6779 18343,-6779 18339,-6777 18343,-6782 18338,-6779 18341,-6778 18341,-6776 18336,-6776 18333,-6776 18333,-6780 18338,-6784 18338,-6787 18335,-6786 18336,-6781 22336,-6781 22335,-6778 22331,-6777 22326,-6777 22331,-6777 22335,-6772 22335,-6774 22340,-6769 22341,-6767 22337,-6767 22335,-6767 22335,-6767 22333,-6767 22336,-6762 22331,-6759 22331,-6764 22332,-6765 22334,-6767 22339,-6762 22334,-6760 22334,-6760 22334,-6758 22337,-6754 22341,-6754 22342,-6750 22339,-4750 22343,-4747 22343,-4752 22343,-4751 22344,-4749 22345,-4745 22348,-4740 22353,-4736 22358,-4738 22363,-4740 22358,21336 41527,21334 41527,21330 41526,21330 41526,21333 41529,21328 41529,21329 41530,21326 41532,21328 41532,21324 41537,21328 41532,21330 41535,21334 41532,21336 40532,21334 40536,21339 40534,21341 40534,21344 40534,21346 40532,21350 40532,21353 40535,21357 40539,21359 40542,21360 40546,21355 40546,21360 40547,21359 40550,21356 40551,21356 40550,21357 40550,21361 40554,21358 45554,21362 45556,21366 45553,21370 45557,21374 45556,21377 45553,22377 45549,22382 45549,22382 45552,22386 45557,22387 45557,22388 45553,22392 45557,24392 45561,22392 45558,22397 45561,22399 45558,22398 45561,22400 45564,22400 45569,22404 45573,22406 45577,22406 45581,22404 45581,22407 45582,22409 45579,22409 45575,22409 45579,22407 45579,22402 45582,22402 45582,22404 45587,22406 45587,22406 45589,22411 45589,22413 45590,22417 45591,22417 45592,22422 45587,22425 45583,22428 50583,22428 50585,22428 50585,22430 50588,22435 50590,22435 50585,22435 50590,22439 50595,22440 50590,22445 50587,22442 50584,22442 50586,22443 54586,22443 54590,22446 54595,22448 54597,22448 59597,22444 59593,22449 59596,22449 59599,22452 59600,22457 59600,22458 59605,22457 59602,22462 59603,22463 59604,22461 59605,22458 59602,22457 59601,22457 59601,22455 59605,25455 59606,25457 59611,25462 59613,25464 59614,25467 59617,25472 59612,25476 59613,25478 59610,25482 59615,25482 59616,25486 59612,25483 59614,25487 59619,25492 59623,25497 59625,146 2252,150 2249,150 2249,152 2254,157 2249,158 2253,157 2252,161 2255,159 3255,161 3258,161 3255,163 3255,168 3259,168 3259,172 3263,167 3267,172 3271,172 3272,172 3274,175 3278,179 3282,181 3283,184 3280,185 3282,187 3282,191 3284,192 3286,191 6286,193 6289,198 6285,195 6290,194 6289,195 6289,199 6293,200 6288,198 6290,202 6291,207 6296,212 6301,215 6301,216 6301,211 6304,212 6304,216 6309,216 6304,214 6308,213 6308,211 6305,212 6309,217 6314,220 6317,224 6322,222 6327,220 6323,41573 39712,41572 39709,41576 40709,41580 40714,41576 40717,36576 40717,36577 40719,36582 40716,36585 40721,36590 43721,36585 43721,36582 43724,36585 43729,36590 43731,36590 43730,15289 11307,15285 11312,15286 11315,15289 11315,15294 11315,15295 11316,15296 13316,38742 37646,38743 37650,38745 37655,38744 37658,38739 37659,38737 37662,38742 37662,38745 37657,38748 37662,38748 37662,38752 37667,38753 37667,38748 37669,38748 37668,38752 37673,38754 37674,38756 37676,38758 37674,38760 37679,38760 37675,38758 37675,38763 37675,38767 37674,38772 40674,38767 40679,38772 40683,38774 44683,38778 44686,38780 44690,38780 44690,38779 44695,38782 44700,38780 44695,38775 44696,38775 44696,38775 44696,38779 44699,38783 44696,38784 44696,38786 44692,38786 44692,38786 44696,38791 44698,38793 44699,38795 44703,38800 44708,38803 44708,38807 44709,38802 44706,38806 44708,38809 44709,36809 44709,36814 44704,36813 44705,36814 44705,36816 44709,36811 44712,36812 48712,36811 48717,36815 48721,36816 51721,36818 51717,36822 51720,40822 51715,40827 51712,40830 51716,40829 51719,40832 51723,40835 51724,40840 51721,40841 51721,40836 51725,40841 51730,40846 51734,40848 51738,40849 51740,40851 51743,40854 51745,40855 51746,40857 51750,40857 51746,40861 51748,40866 51751,40862 51750,40866 51750,40869 51752,40865 51752,40863 51755,40858 51757,40855 51753,40855 51758,40852 51758,40853 51760,40857 51761,40855 51757,40852 51760,40853 51761,40855 51762,40858 51757,40859 51756,40863 51757,40863 51759,40860 51764,40859 51764,40854 51768,40850 51765,40852 51767,40852 51767,40848 51772,40852 51776,40854 51778,40852 51778,43852 51778,43854 52778,43856 52781,43859 52781,43859 52776,37512 26536,37517 26531,37520 26535,37520 26540,37522 26544,37527 26544,37532 26549,37537 26544,37540 26549,37545 26544,37549 26547,37549 26550,37548 26551,37549 26553,37546 26553,37546 26553,37549 26556,37549 26559,37552 26559,37556 26564,37560 26559,37561 26561,37565 26565,41565 26565,41569 26568,41571 26573,41571 26573,41576 29573,41571 29573,41573 29576,41573 29578,46573 29578,46569 29582,45569 29583,45572 29583,45568 29583,45573 29581,45575 29578,45571 29581,45572 29584,45572 29585,45576 29585,45578 29588,45581 29591,45582 29593,45582 29598,45584 29597,45589 29600,45585 29605,45589 33605,45593 36605,45594 36607,45599 36609,45600 36604,45604 36604,45604 36608,45604 36607,45608 36610,50608 36613,50611 36609,50614 36609,50619 36605,50624 36605,50625 36606,50625 36605,50629 36606,50624 36608,50625 36610,50626 36610,50629 36608,50627 36610,50628 36614,50632 36618,46632 34618,46632 35618,46636 35622,46636 35617,46637 35620,46639 35619,46643 35620,46645 35625,46643 35630,46648 35635,46648 35640,46649 35643,46651 35647,46655 35650,46652 35655,46657 35656,46658 35657,46662 35660,46659 35663,46662 35664,46665 35663,46667 35667,46667 35663,46670 35666,46672 35671,46674 35671,47674 35668,47676 35672,47677 35673,47677 35678,47677 35677,47677 35677,47677 35682,47672 35683,47671 35683,49671 35685,49674 35689,49677 35692,49675 35692,54675 35697,54678 35699,54674 35699,54670 35701,54670 35700,54675 35703,54676 34703,54676 34703,54679 34706,54683 34708,54688 34706,54688 34707,54685 34702,54687 34702,54692 34707,54687 36707,54687 36706,54682 36707,54685 38707,54680 38710,54680 38714,54677 38714,54679 38719,54682 38720,54687 38716,54688 38717,54692 38722,54697 38726,54699 38727,54700 38724,54702 38720,52702 38719,52702 38719,52702 38721,52702 38725,52704 38726,52706 38728,52707 38729,52711 38728,52711 35728,52713 35733,52712 35737,52712 35739,52713 35742,52713 35745,52708 35745,52710 39745,52713 39749,52716 39748,52721 39749,52720 39753,52716 39756,52716 40756,47716 40757,47717 40761,47722 40761,47722 40761,47722 40766,47726 40769,47728 40772,47733 40777,47731 40773,50731 40777,51731 40779,51733 40782,51734 40786,51737 40784,51741 41784,51739 41783,51739 41785,51739 41785,51736 41789,51731 41789,52731 41790,52735 41791,52738 41790,52742 41789,52746 41785,52747 41785,52745 41785,52750 41782,52753 41786,52753 41787,52758 41792,52754 42792,52749 42793,52752 42794,52756 42791,52757 42790,52762 42793,52766 42797,52766 42797,52769 42802,52774 42806,52774 42805,52771 42807,52774 42807,52770 42808,52771 42811,52767 42811,52766 42812,52767 42817,52771 42817,52771 42817,52775 42815,52779 42811,52779 42812,52780 42815,52776 42818,52774 42818,52777 42822,52780 42823,52781 42827,52776 42829,52780 42832,54780 42835,54780 42840,2135 11201,2140 11203,2137 11204,2140 11209,2142 11213,2147 11211,2145 11213,2145 11213,2150 11218,2150 11221,2153 11225,2157 13225,2162 13228,2167 13231,2171 13232,2167 13229,2168 13233,2171 13237,2173 13239,2168 13234,2168 13235,2173 13235,2175 13234,2177 13235,2177 13234,2179 13229,2179 13226,2180 13226,2177 13226,2177 13231,2180 13231,2181 10231,2176 10233,2177 10232,2180 10235,2185 10237,2182 10240,6182 10240,6184 10244,6182 10242,6183 10243,6185 10246,6190 10244,6194 10244,6194 10247,6192 10247,6192 10252,6195 10256,6194 10260,6195 9260,6195 9260,6195 9264,6199 9269,6204 9272,6199 9268,6201 9268,6203 9265,6208 9268,6204 9270,6204 9275,6201 9279,6201 9281,6201 9286,6206 9281,6206 9277,6202 9281,6200 9285,6202 9288,6198 9290,7198 9293,7200 9297,7201 9297,7205 9298,7209 9298,7209 9299,8209 9302,8214 10302,8218 10306,8222 10308,8226 10313,8231 10313,8235 10318,8237 10318,8237 10323,8233 10326,8233 10327,8237 10325,8238 10328,8238 10330,8234 10330,11234 10332,11236 10333,11241 10337,14241 10338,14240 10338,14237 10339,14238 10337,14237 10339,14242 10339,14246 10339,14250 10339,14250 10339,14251 10337,14254 10337,14256 10334,14256 10332,14252 10336,14255 10340,14259 10342,14262 10347,11148 3159,11153 3163,11154 3162,11154 3165,11158 3167,11161 3172,11162 3175,11162 3176,11166 3179,11166 3181,11171 3185,11176 3180,11178 3179,11176 3181,11179 3183,11174 3182,52776 42818,52778 42822,52777 42822,52782 42817,52783 42822,52784 42823,52789 42826,52789 42823,56789 42828,56786 42829,56786 42832,56789 42836,56789 42835,56785 42838,56786 42843,51786 42844,51788 42846,51790 42847,51794 42842,51796 42842,51801 42846,53801 42849,53806 42849,53809 42852,53812 42850,53817 42846,53817 42848,53818 42853,53822 42856,53823 42854,53826 42858,53825 42860,53826 42860,53826 42864,53830 42868,53835 42873,53839 42873,53841 42872,53841 42876,53841 42879,53841 42884,53836 42888,53836 42889,53836 44889,53833 44889,53835 44893,53838 44897,53842 44897,53844 44900,53844 44904,53845 44905,53850 44903,53853 44904,53858 44906,53856 44907,53861 44909,53856 44913,53858 44916,53863 44916,53868 44918,53867 43918,53869 43921,53869 43919,53867 43919,53862 43918,53860 43923,53864 43928,53869 43930,53874 43933,53874 43932,53874 43932,53875 43930,53877 43928,53878 43924,53883 43927,55883 43929,55883 43925,55879 43929,55881 43929,55884 43928,55881 43928,55882 43929,55883 45929,55883 45933,55883 45936,55884 45941,55884 45941,55886 45946,55882 45948,55883 45952,55888 45956,55890 45957,55894 45953,55892 45954,55897 45950,55893 45954,55896 45956,55892 45955,55897 45959,55899 45961,55899 45961,55894 45962,55898 45957,55893 49957,55896 47957,55894 47956,55898 47960,55901 47964,55901 47967,55901 47970,55896 47973,55898 47969,55894 47974,55895 47975,55891 47976,55896 47979,55899 47984,55902 47983,55897 47987,55899 47989,55904 47992,55904 47993,55905 47997,55902 48001,55902 48003,55907 48000,55910 47998,55915 47999,55911 47994,55906 47998,55910 48003,55914 48000,55918 48000,55914 48000,55919 48000,55921 48003,55921 48007,55924 48007,55919 48010,55922 48005,55927 48009,55928 48008,55928 48008,55930 48012,55925 48012,55925 48016,54925 48014,54922 48018,54922 44018,54926 44013,54929 44012,54932 44016,55932 44017,55935 44017,55936 44020,55937 44022,55936 44020,55939 44015,55944 44018,55945 44022,55947 44023,55950 44024,55953 44020,55956 44023,53867 43919,53871 43921,52871 43921,53871 43923,53876 43923,53881 43923,53880 43927,53882 43931,53886 43936,53884 43937,53879 43934,53879 43937,53877 43939,53878 43938,53879 43942,53880 43947,53881 43948,53884 45948,53884 45949,53882 45953,53883 45954,53878 45956,53880 45953,53885 45958,53885 45958,53886 45957,53886 48957,53886 48962,53891 48962,53892 48964,53897 48965,49897 48962,49902 48965,49906 48967,49902 48967,49904 48971,49901 48967,49904 48970,54904 48971,54904 48971,54904 48975,54909 48979,54907 48975,54910 48975,54906 48971,54909 48973,54911 48975,54915 48978,54920 48978,54923 48981,54918 48984,54921 48984,56921 48984,56926 48986,56924 48981,56929 48980,56932 48979,56932 48977,56936 48979,56937 48981,56937 48982,61937 48984,61937 48980,61934 51980,61935 51981,61935 51984,61935 51984,61931 51986,5329 23395,5331 23395,5333 23390,5337 23392,5340 23395,5345 27395,5345 27397,5350 27398,5355 27399,5356 27402,6356 27405,6360 27407,6361 27406,6364 27402,6366 26402,6371 26402,6371 26402,6372 26405,6370 26405,6375 26406,6380 26411,6385 26413,6387 26414,6388 26419,6390 26419,6391 26424,6393 30424,6390 30429,6390 30432,6390 30430,6394 30434,6394 30437,6394 30441,6396 30442,6398 30439,6399 30436,6404 30435,6405 30435,6400 30435,6405 30440,6404 30443,6405 30447,6409 30447,6411 30447,6412 30448,6417 30446,6421 30450,6418 30448,6417 30444,6418 30449,6420 30451,6425 30456,6426 30456,6425 30458,6426 30458,6426 34458,6427 34459,6432 39459,6434 39462,6434 39467,6439 39470,6443 39467,6444 39468,6449 39473,6451 39476,6452 39481,6452 39479,6452 39476,8452 39476,8456 39478,8460 39480,10460 39482,10455 39482,10456 39484,10460 39484,10463 39484,10468 39486,10473 39482,10475 39484,10475 39486,10476 39488,10477 39492,10475 39494,10480 39499,10476 39501,10479 39506,10480 39510,10475 39508,10480 39513,10481 39516,10481 39516,10485 39521,10487 39522,10490 39523,10490 39520,10493 39520,10496 44520,10491 44519,10491 44524,10492 44520,10497 44525,10499 44525,10502 44527,10500 44531,10502 44535,10506 44535,10511 44532,13511 44536,13513 44533,13510 44535,13507 44540,13511 44543,13515 44548,13517 44549,13522 44550,13525 42550,13520 42551,13522 42553,13525 42552,13529 42557,13529 42558,13524 42559,13525 42559,13525 42562,13520 42564,13523 42567,15523 42569,15523 42572,15524 42577,15529 42577,15530 42582,15532 42584,15532 42588,15531 42587,15531 42592,15530 42587,15530 42583,15533 42583,15536 47583,15532 47583,15535 47587,15534 47590,15536 47594,11536 47590,11533 47590,11529 47590,11533 47592,11533 47592,11533 47593,11537 47598,11538 47603,11538 47603,11538 47605,11541 47609,11544 47613,14544 47614,14539 47610,14537 47610,14537 47614,14535 50614,14537 50619,14539 50619,14540 50623,14538 50623,14537 50619,25599 26540,25599 26541,25599 26544,25594 26542,25599 26543,25596 26544,25597 26543,25598 26543,25593 26544,25588 26542,25593 26545,25595 26544,25596 26544,25599 26541,25594 26544,25592 26549,25593 26548,25597 26549,25596 26550,25594 26551,25590 26550,25594 26554,25597 26550,25598 26552,25593 26555,25598 22555,25599 22557,25604 22559,25605 22558,25606 22562,25605 22559,25605 22564,30605 22569,30610 22571,30610 22575,30609 22575,30609 22576,30609 22581,30605 22581,30610 22583,30610 22584,30613 22579,30613 22581,30616 22577,30619 22577,30621 22580,30621 22585,30626 22590,30628 22593,30629 22598,30626 22603,30628 22606,30629 22607,30629 22604,30627 22606,30632 22608,30633 22608,30636 22612,30641 17612,30642 17614,30647 17614,30651 17615,30654 17610,30655 17607,30658 17611,30653 17610,30654 17606,30654 17607,30659 17606,30660 17611,30658 17616,30659 17616,30664 17619,30665 17621,30665 17620,30667 17621,30671 17624,30673 17624,30673 17624,30678 17627,30675 17632,30675 17635,30678 17640,30681 17643,30686 17639,30691 17641,30696 19641,30699 19640,30700 19640,30696 19645,30698 19643,30699 19645,30702 19646,30703 19649,30699 19651,30704 19648,30706 19652,30709 19653,30709 19655,30709 19655,30712 19657,30708 19658,30705 19660,30700 19662,30701 19663,30706 19664,30711 19663,30707 19667,30704 19670,30708 19672,30709 19673,30711 19673,30711 19674,30713 19678,30718 19682,30723 20682,30721 20686,30725 20691,30726 20693,30729 20695,30728 20690,30730 20692,30733 20694,30736 20692,30736 20691,30740 20694,30741 20695,30741 20697,30746 20700,30747 20702,30750 20701,30751 20698,30753 24698,30749 24701,30748 24703,30746 24704,30747 29704,30747 29705,30749 29707,30752 29712,30757 29712,30760 34712,30760 34716,30763 34716,30759 34713,30759 34717,30763 34717,30758 34717,30757 34721,30760 34726,30758 34726,30763 34727,30763 34727,30764 34727,30759 34729,30759 34732,30762 34734,30757 34735,30761 34736,30759 34736,30762 34738,30757 34733,30760 34735,30762 34737,30760 34736,30765 34733,32765 34737,32768 34737,32765 34740,32765 34742,32768 34747,32772 34751,32772 34752,32777 34749,32782 34751,32783 33751,32783 33746,36783 33749,36783 33754,36786 33756,36787 33755,36787 33758,36791 33754,36796 33754,36801 33756,36801 33758,36801 33762,36802 33765,36802 33765,36806 33770,33806 33772,33806 33777,33809 33777,33814 33780,33814 33785,33818 33782,33821 33784,33826 33781,33822 33781,33824 33783,33822 33784,33826 33787,33823 33792,33827 33795,33828 33798,33829 33799,33833 33801,33833 33801,33836 33805,33839 33809,33842 33805,33847 33810,33845 32810,33847 32808,33849 32812,33851 32815,33849 32818,33849 32822,33847 32822,33847 32826,33850 32831,33854 32836,33857 32833,33856 32828,33859 32829,33860 32832,33857 32834,33857 32830,33855 32830,33857 32830,33855 32834,33859 32829,33859 32833,33862 32836,33864 32837,33864 32839,33866 32837,33869 32835,33872 32840,33874 37840,33879 37845,33881 37850,33881 37855,33886 37856,33891 37860,33896 37860,33893 37863,33894 38863,33896 38859,28896 38864,28899 39864,33899 39869,33896 39871,33898 39875,33902 39873,33902 39875,33907 39879,33912 39884,33908 39887,33908 39888,33905 39890,33909 39895,33911 39896,33908 39900,33912 39901,33915 39902,33915 39902,33915 39902,33910 39907,33910 39904,33914 39903,33912 39906,33916 39909,33920 39909,33922 39912,33923 39916,33928 39916,33931 39918,33932 39919,33935 39915,33936 39912,33934 39909,35934 39914,35931 39915,35935 39917,35939 39920,35939 39915,35940 39911,35944 39916,35944 39911,35944 39908,35945 39904,35945 39908,35945 39912,35950 39915,35955 39917,38955 39916,38960 39921,38962 39920,38962 39920,38967 39922,38967 39924,38970 39928,38975 39928,38973 39928,38977 39931,38980 39934,38984 39936,38982 39939,38983 39942,38985 39943,38987 39945,38992 41945,38988 41950,38989 41954,38992 41958,38992 41962,38992 41965,38993 41970,38997 41970,38997 41970,38994 41974,38994 41979,38997 41979,38999 41982,38994 41980,38998 41985,38998 41984,5334 23406,5330 23406,5325 23403,9325 23404,12325 23408,12325 23408,12322 23406,13322 23411,13325 23416,13326 23412,13322 23414,13327 23419,13328 23422,13329 23425,13333 23422,13337 23424,23491 35549,23490 35544,23494 35546,23499 35548,23495 35549,21495 35553,21490 35556,21492 35558,21492 35556,21494 35559,21494 35564,21494 35566,21499 35566,21502 35562,21502 35567,17502 35568,17506 35573,17507 35574,17511 35578,17512 35583,17513 35588,18513 35591,18514 35592,18515 35594,18513 35596,16513 35601,16513 37601,16513 37602,16511 37604,16513 37609,16514 37611,16518 37616,16522 34616,16524 34613,16528 34615,16528 34620,16533 34624,16535 34627,16538 34628,16539 34630,16539 34631,16542 34628,16542 34633,16544 34638,16547 38638,16547 38640,16543 38645,16543 38640,16540 38640,16543 38640,16542 38641,16546 38646,16541 38649,16541 38645,18541 38648,18544 38648,18544 38653,18544 38656,18549 38651,18547 38651,18550 38656,18547 38658,23547 38663,23544 38664,23548 38668,23548 38670,28548 38672,28549 38669,28549 38673,28545 38669,28549 38670,28554 38670,28557 38674,28560 38669,28562 38674,28562 38669,28561 38669,28564 38671,28569 38671,38779 44699,38780 44695,38778 44698,38783 44700,38785 44700,38781 44701,38782 44696,38786 44691,38789 44692,38794 44692,38799 44688,38799 44693,38803 44697,38808 44697,38806 44697,38806 44700,38803 44702,38803 44706,38802 44707,38807 48707,38808 48707,38806 48707,38810 48712,38810 48709,38810 48711,38810 48711,38806 48707,38802 48710,38803 48706,38805 48711,38810 48711,38805 48709,38809 48710,38809 48710,38814 48707,38815 48703,38816 48703,38816 48704,38820 48704,38822 48709,38820 48710,38818 48714,38822 48716,38822 48719,38827 48722,38828 48727,38832 48725,38830 48730,38831 48726,38832 48724,38829 48728,8431 35532,8431 35537,4431 35532,4434 35537,4438 35537,4439 35533,4443 35535,4442 35530,4445 35527,4449 35527,4453 35530,4458 35530,4459 39530,4460 39531,4461 39531,4464 39531,4468 39531,4470 39534,4465 39534,4465 39532,4469 39532,4471 39537,4466 39538,4470 39539,4473 39540,4476 39540,4480 39543,4485 39548,4483 39546,4484 39547,4484 39549,4484 39551,4486 39553,4486 39554,4487 39551,4483 39553,4486 39554,4490 39556,4493 39557,4498 39561,4494 39562,-4749 22345,-4752 22345,-4748 22348,-4744 22351,-4740 22356,-4741 22358,-4739 22361,-4734 22359,-4730 25359,-4730 25360,-4725 25360,-4727 25360,-4727 25361,-6727 25360,-6729 25365,-6730 25365,-6727 25365,-6731 25364,-6730 27364,-6727 27366,-6723 27367,-3723 27363,-3719 27368,-3720 27371,-3718 27366,-3717 27369,-3716 27369,-3714 27372,-3711 27370,-3712 27371,-3712 27370,-3710 27375,-3708 27377,-3707 27382,-3706 27385,-3706 27389,-3705 32389,-3704 32392,-3704 32392,-3699 32391,-3699 32395,-3694 32399,-3694 32400,-3695 32404,-3695 32408,-3693 32410,-3693 32410,-3697 32410,-3692 32413,-3691 32418,-3686 32420,-3683 32425,-3681 32420,-3678 32424,-3673 32424,-3676 32427,-3673 32426,-3671 32426,-3676 33426,-3678 33428,-3676 33428,-3679 33428,-3679 33433,-3677 33434,-3676 33438,-3681 33440,1319 33444,1321 33441,1325 33444,1329 33439,1326 33444,1326 33439,1327 33439,1327 33440,1332 33444,1333 33449,1338 33453,1338 33450,1343 33450,1347 33454,1346 33457,1346 33455,1342 33459,1341 33462,1346 33462,1347 33463,1343 33463,1344 33462,1348 33457,1347 33460,1352 33464,1356 33468,1361 33469,1363 33468,1365 33469,1368 33472,1369 33475,-2631 33478,-2633 33483,-2629 33486,-2632 34486,-2628 36486,-2625 36488,-2621 36488,-2624 36488,-2622 36492,-2624 36491,-2629 36491,-2627 36496,-2623 36499,-2628 36502,-2631 36506,-2626 36506,-2622 36506,-2622 36509,-2619 36514,-2624 36512,-2621 36510,-2619 36510,-2619 36508,-2617 36512,-2615 36512,-2615 36513,-2615 36511,-2615 36506,-2612 36507,-2609 36511,-2606 37511,-2606 37508,-2610 37505,-2607 37508,-2602 37512,-2599 37512,-2595 37510,-2597 37511,-2592 37515,-2597 37514,-2592 37519,-2592 37524,-2592 37526,-2594 37521,-2594 37516,-2591 36516,-2588 36517,-2589 36513,-2586 36514,-2584 36514,-2583 36516,-2579 36514,-2578 36518,-2578 35518,-2575 35519,-2577 35519,-2578 35524,-2578 35529,-2578 35532,-2578 35534,-2580 35537,-2584 35541,-2586 35542,-2587 35544,-2585 35540,-2585 35544,-2584 35543,-2580 35548,-2576 35550,-2571 35553,-2567 35555,-2565 35560,-2560 35560,-2557 35564,-2553 35564,-5553 36564,-5548 36564,-5544 36565,-5547 36565,-5545 36570,-5542 36565,-5543 36566,-5543 36568,-5543 36570,-5540 36575,-5537 36577,-5535 36581,-5532 36580,-5528 36575,-5526 38575,-5526 38576,-5526 38571,-5522 38571,-5518 38576,-5514 42576,-5510 42581,-5512 42583,-5512 42582,-5507 42582,-5510 42585,-2510 42589,-2511 42592,-2508 42594,-2506 42597,-2503 42598,-2503 42603,-2498 42608,-2501 42611,-2500 42616,-2502 42613,-2502 42616,-4502 42616,-4502 42620,-4502 42622,-4506 42619,-4509 42621,-4511 42624,-4515 42625,-4510 42625,-4507 42628,-4502 42624,-4501 42629,-4505 45629,-4503 45630,-4499 45631,-4496 45630,-4497 45628,-4495 45630,-4494 46630,-4491 46634,-4487 46629,-4483 46631,21336 40532,21341 40533,21346 40534,21346 40536,21345 40536,21346 40536,21345 40536,21344 40538,21347 40543,21348 40543,21351 40540,21351 40542,21348 40545,21351 40546,21352 40546,21353 40546,21358 40546,21359 40545,21359 40550,21357 40555,21362 40560,21364 40555,21363 40555,21364 40560,25364 40564,25365 40566,25368 40566,25371 45566,25372 45567,25372 45562,25376 45564,25381 42564,25385 42560,25389 42564,25389 42568,25393 42572,25390 42572,28390 42569,28389 42570,28385 42574,28386 42576,28389 42577,31389 42578,31385 42582,31387 42582,31390 42578,31391 42579,31392 42576,29392 42580,29396 42582,29398 43582,29402 43584,29406 43585,29407 43587,29411 43592,29413 43594,29414 43595,25414 43600,25412 43595,25415 43599,25420 43602,25418 43604,25423 43599,25426 43599,25429 43602,25434 42602,25429 42604,25432 42600,25435 42605,25436 47605,25440 50605,25441 50610,25439 50614,25444 50617,25447 50621,25444 50624,25444 50626,25445 50627,25450 50632,25450 50628,25451 50630,25451 50632,25454 50633,25458 50637,25462 50641,25463 50640,25463 51640,25467 51644,25469 51649,25473 51650,25474 51653,25475 51654,26475 51658,26475 51662,26474 51665,26476 51665,26481 51661,26483 55661,26485 55664,30485 55667,30485 55670,30489 55671,30489 55668,30491 55670,30492 55670,30493 55675,30497 55675,30501 55671,30503 55676,30500 55677,30498 55672,30494 55675,30499 55676,30500 55676,30505 55681,30501 55684,30496 55685,30500 55685,30502 55687,30506 55692,30507 55693,30506 55692,30511 55693,30516 55694,30514 55699,30514 55701,30512 55701,34512 55705,34516 55708,34520 55704,34518 56704,34519 56704,34520 56706,34517 56706,34515 56701,34519 59701,34522 59706,34522 59708,34522 59713,34526 59715,34528 59717,34533 59712,34538 59715,34538 59717,34541 59717,34546 59720,34548 59721,34552 63721,34547 63726,34549 63728,34554 63726,34556 63726,34557 63721,34556 63725,34561 63730,34558 63730,37558 63725,37561 63729,37565 63724,37569 63720,37573 63718,37578 63722,37577 63718,37579 63720,37579 63722,37580 63719,37580 63720,37579 63724,37574 63725,37574 63727,37576 63725,37581 63729,37583 63732,37586 63732,37590 63737,37592 63734,37597 63731,37600 63730,37596 63731,37596 63733,37600 63733,37601 63735,37596 63735,37591 63732,37596 63733,37601 63738,37602 63733,37599 63738,37594 63740,37598 63744,37603 63745,37605 63747,37607 63752,37607 63756,37603 63757,37603 63761,37604 63761,37608 63758,37609 63762,37604 63764,37604 63764,41604 63765,41600 63761,41599 63761,41600 63766,41596 63766,41599 63766,41601 63770,41604 63768,41608 63768,41611 63772,41614 63767,41609 63763,41612 63765,41615 63760,38615 63764,38615 63768,38618 63768,35618 63769,35618 63774,35617 63775,35618 63776,35613 63775,35615 63780,35612 63782,35613 63779,35614 63775,35618 63774,35619 63776,35624 63778,35624 63780,35629 63785,35629 63780,35626 63781,35624 63782,35629 63784,35634 63787,35638 63782,35634 63783,35634 63778,35633 63777,35638 63782,35641 63786,35644 63791,35648 63793,35647 63793,35649 63797,35653 63801,35654 63804,35654 63804,35656 63804,35655 63806,35658 63810,35658 63805,35662 63805,35657 67805,35658 67808,35660 67811,35664 67808,35660 67803,35658 67803,35661 67803,35663 67808,35666 67810,35670 67814,35669 67813,35669 67816,37669 67820,37664 67820,2275 13363,2278 16363,2274 16363,2275 16362,2279 16362,2282 16362,2287 16366,2284 16366,4284 16366,4286 16371,4290 16375,4294 18375,4295 18377,9295 18381,9296 18381,9299 18382,9303 18379,9305 19379,9308 19375,8308 19380,8312 19380,38746 37651,38749 37652,38754 37653,38757 37656,38753 37661,38753 37661,38758 37663,38763 37664,38763 42664,38768 42666,38765 42668,38770 42664,38767 42659,38768 42659,38773 42654,38771 42659,38775 42661,41775 42663,41778 42665,41781 42669,41782 42667,41779 42669,41784 42672,41781 42672,41783 42672,41780 42672,41783 42675,41784 42675,41788 42676,41792 42677,41792 42675,41793 42680,41793 42676,41796 42681,41801 42685,41804 42684,41806 42685,41804 42690,41802 42692,41805 42696,41800 42697,41802 42698,41804 42700,41809 42704,41813 42705,36813 42708,36813 42704,36810 42703,36811 42705,40811 42706,40815 46706,40816 46708,40820 46708,40818 46712,40822 46717,40825 46720,40829 46724,40827 46727,40831 46727,40833 46731,40829 46733,40830 46733,36830 46738,36830 46741,36834 46744,36831 46749,36826 46748,36822 46748,36824 46751,36819 46755,36823 46758,36823 46762,36824 46766,36822 46769,36826 46772,36831 46774,36828 42774,36833 42776,36833 42777,36838 42782)')));
+INSERT INTO t1(g) VALUES (ST_linefromtext(concat('linestring','(20 110, 21 110, 26 115, 29 112, 34 108, 39 111, 44 111, 46 116, 46 120, 42 122, 45 118, 48 118, 44 122, 46 127, 47 127, 51 127, 55 123, 52 127, 52 128, 56 130, 60 129, 61 130, 66 131, 67 131, 71 135, 76 136, 77 139, 80 143, 2080 145, 2077 147, 2079 147, 2081 147, 2086 147, 2087 151, 2092 -1849, 2088 -1848, 2088 -1852, 2091 -1848, 2095 -1846, 2092 -1847, 2092 -1848, 2093 -1847, 2094 -1846, 2099 -1843, 2104 -1844, 2102 -1848, 2102 -1848, 7102 -1847, 7105 -1846, 7106 -1843, 7111 -1838, 67 131, 69 135, 68 135, 63 136, 63 137, 64 141, 67 1141, 2067 1139, 2063 1139, 2066 1139, 5066 1139, 5068 1139, 5072 1140, 5072 1145, 5073 1142, 5076 1145, 5077 1145, 5076 1141, 5078 1141, 5073 1143, 5068 1146, 5067 2146, 5070 2151, 5075 2155, 5071 2160, 5073 2161, 5074 2166, 5076 2169, 5071 2173, 5074 2173, 5078 2177, 5076 2173, 5080 2173, 5078 2174, 78 2179, 76 2183, 77 2188, 82 2192, 85 2194, 89 2193, 86 2197, 89 2193, 88 2194, 89 2199, 89 2204, 89 1204, 87 1206, 88 1203, 89 1204, 89 1205, 93 1210, 94 1208, 96 1208, 100 1210, 104 1212, 107 1215, 104 1220, 107 1224, 111 1228, 112 1228, 116 1229, 119 1228, 120 1233, 119 1236, 124 1241, 125 1240, 122 1239, 126 1241, 123 1240, 124 1244, 128 1248, 129 1250, 128 1253, 127 5253, 125 5255, 129 5255, 133 5255, 137 5260, 140 5261, 137 5261, 141 5261, 140 5262, 143 5264, 148 5264, 148 5264, 145 10264, 149 10269, 153 10274, 158 10270, 159 10273, 164 10277, 168 12277, 170 12278, 165 12274, 170 12279, 172 12281, 172 12281, -3828 12281, -3823 12281, -3822 12282, -3823 12280, -3823 12282, -3820 12281, -3823 12279, -3827 12282, -3826 12279, -3822 12284, -3825 12284, -3824 12286, -3820 12287, -3820 12290, -3818 12292, -3816 12293, -3814 12298, -3815 12301, -3817 12304, -3814 12301, -3811 12299, -3809 12303, -3809 12301, -3804 12302, -3804 12302, -3802 12305, -3799 12310, -3801 17310, -3801 17310, -3796 17310, -3801 17314, -3799 17318, -3796 17321, -3795 17321, -795 17325, -795 17327, -794 17329, -791 17330, -790 17326, -787 17331, -782 17335, -778 17339, -774 17343, -772 17343, -769 17346, -768 17349, -763 17352, -763 17353, -761 17357, -758 17354, -758 22354, -754 22350, -750 22353, -746 22356, -750 22352, -746 22351, -744 22349, -743 27349, -741 27350, 259 27354, 262 27353, 263 27356, 268 27352, 268 22352, 271 22351, 273 22351, 274 22351, 275 22352, 275 22356, 280 22352, 281 22348, 284 22349, 284 22346, 285 22351, 285 22351, 290 22353, 294 22351, 294 22352, 295 22352, 300 22352, 305 22355, 308 22356, 311 22356, 310 22358, 312 22360, 313 22365, 313 22362, 313 22364, 313 22364, 317 22360, 322 22362, 327 22367, 328 22370, 323 22375, 320 22377, 320 22379, 316 22379, 318 22379, 323 22380, 323 22380, 324 22376, 34 108, 38 113, 42 118, 42 117, 42 121, 46 123, 51 127, 51 130, 51 133, 55 137, 52 141, 52 143, 51 141, 50 142, 45 142, 44 143, 48 146, 48 142, 43 143, 47 145, 4047 5145, 4047 5150, 4044 5151, 4045 10151, 4043 10154, 4044 10156, 4047 10156, 4043 10160, 4043 10156, 4043 10156, 4048 10157, 4051 10160, 4048 10159, 4053 10161, 4057 10163, 4057 10164, 4058 10165, 4057 10170, 4056 10173, 4056 10176, 4056 15176, 4053 15180, 4049 15181, 4051 15178, 4049 15180, 4049 15180, 4048 15181, 4048 15184, 4045 15188, 4045 15191, 4040 15194, 4042 15198, 4042 15203, 4047 15200, 4049 15201, 4052 15204, 4052 15208, 4052 15212, 4049 15216, 4049 15219, 4051 15220, 4048 15222, 4044 15227, 4044 15232, 4044 15236, 4049 15239, 4052 15240, 4052 15243, 4053 15247, 4055 15247, 4052 17247, 4054 17247, 4054 18247, 4059 18251, 4063 18253, 4066 18253, 4069 20253, 4069 20254, 4069 20259, 4068 20263, 4068 20263, 4069 20259, 4071 20260, 4073 20262, 4074 20258, 4069 20261, 4069 20264, 4071 20269, 4067 20271, 4071 20270, 4072 20271, 4073 20268, 4076 20263, 4072 20268, 4075 20264, 4076 20267, 4079 20272, 4084 20275, 4086 20277, 4086 20281, 4083 18281, 4087 18283, 4088 18280, 4089 18277, 4089 18279, 4094 18281, 4095 18283, 4095 18284, 4097 18284, 4093 18287, 4094 18285, 4096 18287, 4092 18291, 4096 18291, 140 5261, 140 5259, 140 5262, -1860 5258, -1858 5260, -1854 5262, -1849 5259, -1848 5264, -1845 5264, -1845 5267, -1845 5262, -1848 5261, -1848 5263, -1849 5261, -1853 5262, -1851 5265, -1847 5265, -1847 5262, -1847 5263, -1843 5268, -1845 5268, -1848 5272, -1850 5270, -1851 5274, -1854 5269, -1850 5266, -1845 5267, -1840 5267, -1840 5264, -1840 5269, -1839 5269, -1842 5269, -1840 5274, -1835 5278, -1836 5283, -1841 5279, -1840 5284, -1836 5285, -1836 5289, -1831 5289, -1826 5292, -1822 5293, -1826 5295, -1829 5295, -1824 5295, -1828 5297, -1824 5300, -1820 5305, -1824 5306, -1824 5306, -1824 5306, -1823 5301, -1818 5303, -1814 5307, -1814 5303, -3809 12303, -3807 12306, -3804 12306, -3804 12306, -3801 12308, -3796 12308, -3795 12308, -3791 12310, -3786 12310, -3781 12313, -3814 12298, -3809 12303, -3807 12301, 7102 -1847, 7100 -1850, 7104 -1850, 7109 -1852, 7109 -1854, 7112 -1850, 7112 -1847, 7115 -1847, 7117 -1847, 7122 -1847, 7125 -1843, 7126 -1848, 7127 -1848, 7129 -1848, 7133 -1848, 7131 1152, 7131 1149, 7135 1154, 7139 1152, 7140 1151, 7145 1153, 7149 1158, 8149 1159, 8154 3159, 8149 3161, 8145 3162, 8146 3164, 8146 3168, 11146 3171, 11148 3171, 11150 3167, 11154 3165, 11150 3163, 11151 3167, 11152 3165, 11153 3170, 11156 3175, 11156 3174, 8146 3164, 8146 3167, 8146 3170, 8147 3170, 8148 3175, 8148 3178, 8146 3178, 8146 3178, 8147 3180, 8143 3184, 3143 3186, 7143 3187, 7143 7187, 7138 7189, 7138 7189, 7135 7191, 7138 7191, 7133 7194, 7138 7198, 7139 7201, 7143 7200, 7141 7203, 12141 7204, 12145 7204, 12145 7203, 12146 7207, 12147 7204, 12143 7204, 12138 7199, 12138 7195, 12139 7195, 12139 7200, 12141 7201, 12142 7201, 12139 7205, 12142 7208, 12142 7213, 12145 7213, 12147 7214, 12149 7218, 12150 9218, 12154 9222, 12151 9222, 12151 9225, 12151 9224, 12152 9226, 12155 10226, 12155 10230, 12158 10231, 12161 10227, 12162 10224, 12163 10229, 12163 10231, 12165 10228, 12165 10227, 12160 10228, 12160 10231, 12160 10235, 12157 12235, 12159 12230, 7138 7189, 7141 7193, 7141 7193, 7141 7192, 7139 7195, 7141 7195, 7142 7193, 7145 7195, 7146 7193, 7146 7194, 7151 7197, 7154 7198, 7156 7202, 7155 7207, 7150 7211, 12150 7213, 12148 7213, 12147 7217, 12142 7221, 12141 7223, 12143 7223, 12140 7222, 12145 7222, 13145 7224, 13142 7228, 13144 7232, 13139 7235, 13144 7239, 13148 7243, 13151 7247, 13150 7251, 13152 7252, 13157 7253, 13157 7257, 13157 7257, 13157 7262, 13159 7264, 13164 7259, 13161 7259, 13165 7262, 13166 7262, 13166 7267, 13169 7268, 13169 8268, 13167 8269, 13171 8269, 13173 13269, 13177 13265, 13178 13263, 13178 13263, 13182 13266, 13183 13266, 13185 13266, 13190 13269, 13193 13271, 13193 13269, 13196 13271, 13193 13273, 13194 13268, 13198 13273, 13200 13276, 13202 13276, 13204 13274, 13209 11274, 13213 11274, 13213 11277, 13215 11278, 13219 11279, 13224 11280, 13224 11276, 13228 11278, 13233 11281, 13235 11286, 13238 11288, 13240 11288, 13238 11290, 13238 11292, 13238 11287, 13238 11288, 13240 11293, 13243 11296, 13246 11296, 13247 11293, 13243 11298, 13246 11302, 13251 11305, 322 22362, 326 24362, 330 24362, 329 24367, 328 24363, 329 24365, 331 24369, 336 24371, -664 24371, -668 24372, 51 127, 48 131, 48 133, 51 135, 51 140, 49 139, 47 142, 3047 139, 3044 142, 3046 143, 3046 148, 3051 148, 3055 146, 3057 141, 3060 140, 3055 143, 3050 146, 7050 142, 7050 3142, 7050 3143, 7050 3144, 7052 3149, 7055 1149, 7052 1150, 7055 5150, 7050 5154, 7049 5150, 10049 5151, 10045 5151, 10049 5151, 10052 5156, 10054 5159, 10056 5160, 10058 5161, 10058 5163, 10060 5166, 10064 5168, 10064 5173, 10068 9173, 10070 9172, 10065 9168, 10065 9173, 10063 9175, 14063 9176, 14063 9178, 284 22346, 289 22351, 290 22351, 290 22347, 287 22343, 282 22342, 280 22345, 281 25345, 286 25347, 13243 11298, 13248 11300, 13245 11300, 13246 11295, 13247 11295, 13246 11295, 13248 11299, 13253 11304, 13255 11309, 13255 11310, 13260 11309, 13257 11310, 13258 11313, 13258 11315, 13263 11311, 13267 11307, 13269 11309, 13272 11305, 13277 11302, 13273 11304, 15273 11306, 15278 11310, 15281 11307, 15286 11309, 15288 11309, 15291 11311, 15292 11306, 15294 11309, 15298 11313, 15299 11317, 15300 11320, 15302 11321, 15306 11324, 15308 11328, 15308 11324, 15309 11324, 15314 11324, 15315 11323, 15319 11321, 15317 11325, 15319 11327, 15319 11332, 15321 11337, 15324 11340, 15324 11341, 15324 11341, 15326 11345, 15326 11349, 15327 14349, 15330 13349, 17330 13350, 17335 13353, 17339 13358, 17340 13362, 17344 13362, 17348 13357, 17350 13357, 17347 13357, 17350 13358, 17349 13358, 17349 13358, 17349 13359, 22349 13362, 22351 13359, 22353 13359, 22358 13358, 22360 13358, 22363 13359, 22364 13359, 22360 13359, 22361 13363, 22366 13368, 22371 13373, 22374 13377, 22378 13375, 22379 13375, 22379 13373, 22383 13378, 22388 13383, 22389 13380, 22389 13384, 22394 13382, 22392 13378, 22394 13382, 22393 13382, 22393 13379, 22394 13382, 22392 13384, 22395 13386, 22400 13391, 22400 10391, 22404 10395, 22401 10396, 22402 10396, 22402 10398, 22406 10395, 22405 15395, 22407 15396, 22409 15396, 22414 15391, 22414 15394, 22414 15398, 22410 15400, 26410 15402, 26409 20402, 26413 20406, 26417 20410, 26419 20415, 26422 20411, 26424 20411, 31424 16411, 31423 16409, 31423 16414, 31425 16414, 31428 16418, 31428 16414, 31432 16419, 31432 16422, 31437 16423, 31439 16424, 31440 16426, 31440 16429, 31440 16429, 31443 16431, 31441 16435, 31443 16440, 36443 16440, 36445 18440, 36444 18441, 36442 18444, 36442 18440, 36442 18444, 36444 18449, 36445 18450, 36449 18455, 37449 23455, 37454 23460, 37458 23459, 37460 23463, 37458 23465, 37460 23467, 37462 23470, 37466 23473, 37462 23478, 37464 23480, 37463 26480, 37468 26483, 37472 26487, 37473 26492, 37476 26493, 37476 26489, 37476 26487, 37476 26492, 37472 26496, 37476 26501, 37476 26503, 37480 26499, 37485 26503, 37485 26505, 37490 26500, 37493 26503, 37497 26499, 37502 26500, 37502 26501, 37502 26505, 37499 26503, 37499 26503, 37497 26508, 37500 26508, 37496 26513, 37499 26518, 37497 26519, 37500 26518, 37505 26518, 37510 26516, 37512 26520, 37513 26523, 37511 26527, 37508 26532, 37509 26536, 37514 26540, 37515 26542, 37512 26546, 37514 26548, 37519 26547, 37524 26550, 37529 26555, 37527 26559, 37531 26562, 37526 26567, 37526 26566, 37529 26566, 37524 26566, 37524 26563, 37528 26565, 37524 26563, 37525 26565, 37525 26560, 37526 26562, 40526 26564, 40526 26567, 40523 26571, 40527 26570, 40529 26572, 40534 26576, 40536 26573, 40535 26569, 40533 26569, 40537 26573, 40537 26574, 40541 26576, 40546 26579, 40545 26579, 40546 26583, 40550 26588, 40551 26585, 40555 26589, 40558 26594, 40554 22594, 40559 22598, 40558 22599, 40563 22596, 40563 22597, 40567 22597, 40570 22597, 40575 22592, 40572 22594, 40572 22595, 40572 22592, 40575 22594, 40575 22597, 40570 22597, 40569 22601, 40569 22603, 40573 22603, 40576 22604, 40576 22608, 42576 22611, 42579 22611, 42579 22616, 42581 22620, 38581 22623, 38582 22621, 38582 22618, 38577 22623, 38581 22623, 38581 18623, 38584 18618, 38584 18621, 38588 18626, 38592 18629, 38592 18626, 38596 18625, 38598 18620, 38599 18618, 38599 18622, 38602 21622, 38603 21622, 38607 21624, 38609 25624, 38613 25624, 38610 25621, 38610 25625, 38610 25629, 38613 25627, 38617 25627, 38617 25624, 38618 25626, 38621 25628, 38622 25629, 38622 26629, 38625 26631, 38625 26631, 313 22362, 313 22363, -1687 22364, 2313 27364, 2314 27364, 2314 27364, 2319 27366, 2319 27366, 2321 27363, 2321 27368, 2320 27363, 2323 27368, 2328 27371, 2327 27375, 2328 27377, 2328 27377, 2327 27381, 2331 27381, 2329 27381, 2332 27383, 2335 27383, 2333 27383, 2333 27385, 2338 27385, 6338 27386, 6338 27387, 40529 26572, 40533 26576, 40535 26578, 40540 26580, 40535 26584, 40540 26589, 40541 26592, 40538 26587, 40542 26591, 40541 26592, 40537 26597, 40542 26598, 40546 26601, 40550 26606, 40550 26605, 40551 26606, 40549 26606, 40550 26607, 40555 26610, 40550 26610, 40550 26607, 40553 26612, 40558 26616, 40561 26620, 40556 26623, 40558 26623, 40558 26627, 42558 26627, 42558 26628, 42562 26628, 42564 26630, 42565 26634, 42566 26634, 42566 26638, 42561 26639, 42564 26639, 42567 26641, 42564 26642, 42566 26646, 42566 26645, 42570 26645, 42574 26645, 42574 29645, 42576 29646, 39576 29645, 39576 34645, 39578 34647, 39583 34642, 39580 34642, 39576 34646, 39576 34649, 39574 35649, 34574 35652, 34579 35655, 39579 35659, 43579 35663, 43582 35659, 43577 35662, 43580 35662, 43583 35666, 43579 39666, 43574 39662, 43574 39665, 43574 39668, 43574 39670, 43578 39674, 43579 39671, 43582 39675, 43578 39677, 43575 39677, 43576 39681, 43571 39683, 43569 39683, 43570 39687, 43565 39690, 43568 39694, 43568 39696, 43570 39698, 43570 39699, 41570 39695, 41572 39696, 41573 39696, 41573 39697, 41573 39702, 41573 39702, 41576 39702, 41571 39702, 41572 39703, 41572 39708, 41574 39713, 41575 39716, 41580 39717, 41581 39721, 41586 39723, 41587 39724, -1848 5272, -1843 5272, -1845 5270, -1840 5272, -1838 5267, -1843 5268, -1841 5268, -1837 8268, -1837 8271, -1837 8276, -1836 8280, -1832 8277, -1832 8277, -1831 8278, -1835 8283, -1834 8287, -1832 8290, -1834 8286, -1832 8283, -1833 8283, -1832 8284, -1834 8287, -1839 8292, -1844 8293, -1841 8290, -1836 8290, -1839 8289, -1836 8289, -1832 8292, -1827 8295, -1823 8290, -1823 8293, -1823 8291, -1822 8295, -1820 8298, -1819 8302, -1816 8304, -1816 8300, -1812 8300, -1809 8299, -1806 8296, 1194 8300, 1194 8301, 1197 11301, 1194 11305, 1197 11309, 1199 11304, 1195 11304, 1195 11300, 1195 11297, 1196 11298, 1201 11296, 1206 11296, 1207 11298, 1212 11296, 1210 11292, 1206 11294, 1207 11293, 1209 8293, 1204 8288, 1206 8286, 1206 8285, 1208 8285, 1210 8285, 1214 8287, 1214 13287, 1215 13291, 1215 13294, 1218 13297, 1216 13293, 1219 13290, 1214 13295, 1210 13292, 1210 13296, 1211 13301, 1210 13300, 1206 13302, 1207 13307, 1211 13312, 1206 13312, 1211 13308, 1212 13308, 1216 13313, 1216 13318, 1217 13318, 1221 13318, 1221 13323, 1226 13324, 1231 13325, 1234 13329, 1235 13333, 1233 13333, 1236 13338, -2764 13340, -2767 13341, -2763 13344, -2760 13349, -2758 13346, 2242 13346, 2240 13346, 2244 13346, 2248 13349, 2248 13350, 2246 13352, 2241 13352, 2242 13355, 2242 13356, 2247 13361, 2250 13361, 2245 13366, 2249 13366, 2250 13366, 2254 13367, 2258 13367, 2258 13367, 2262 13371, 2257 13376, 2253 13373, 2253 13373, 2254 13376, 2251 13380, 2256 13382, 2257 13386, 2261 13383, 2264 13383, 2269 13385, 2264 13385, 2264 13387, 2267 13387, 2271 13389, 2272 13390, 2273 13393, 2269 13395, 2273 13390, 2277 13395, 2275 13396, 2277 13391, 2279 13394, 2276 13394, 2277 13398, 2282 13399, 2282 11399, 2283 14399, 2281 14404, 2279 14407, 2275 14410, 2276 16410, 2276 16414, 2281 16414, 2286 16415, 2282 16413, 2282 16413, 2284 16413, 2284 16415, 2284 16416, 2282 16417, 3282 16422, 3286 16422, 3287 16427, 3291 16427, 3294 16431, 3296 16433, 3298 16435, 3299 16440, 3300 16439, 3305 16439, 3307 16438, 3307 16440, 3307 16440, 3311 16441, 3311 16442, 3310 16443, 3310 16443, 3308 16448, 3304 16445, -1696 16441, -1701 16442, -1697 16442, -1695 16442, -1696 16443, -1693 16440, -1688 16445, -1685 16450, -1681 16454, -1680 16455, -1682 16457, -1680 16461, -1680 16461, -1684 16464, -1679 16463, -1678 16460, -1675 16464, -1679 16465, -1677 16468, -1672 16469, -1671 16473, -1667 16475, -1667 16480, -1663 16478, -1663 16482, -1662 16482, -1662 16483, -1659 16478, -1654 16475, -1653 11475, -1658 11477, -1661 11479, -1664 11484, 3336 15484, 3340 15480, 3344 15475, 3347 15475, 3347 15474, 3352 15473, 3349 15478, 3353 15480, 3354 15477, 3355 15480, 3352 15481, 3352 15483, 3353 15486, 3354 15488, 3353 15491, 3355 15491, 3360 15491, 3355 15490, 1219 13290, 1224 13295, 1224 13295, 1227 13290, 1231 13290, 1233 13285, 1237 13284, 1238 13285, 1243 13286, 1247 13289, 1249 13289, 1249 13291, 1252 13291, 1249 13294, 1249 13299, 1249 13302, 1254 13305, 1251 13308, 1254 13308, 3254 13308, 3249 13308, 3251 13312, 3256 13312, 3259 13312, 3263 17312, 3263 17313, 3263 17310, 3261 17309, 3264 17314, 3265 17312, 3264 17315, 3261 17318, 3261 17318, 3259 17313, 3256 17313, 3255 17313, 3257 17314, 3255 17316, 3257 17316, 3257 17316, 3258 17311, 3259 17311, 3258 17315, 3258 17317, 3257 17321, 3253 17321, 3250 17325, 3255 17329, 3258 17330, 3260 17328, 3260 17331, 3265 17326, 7265 17329, 7267 17332, 7265 17334, 7267 17337, 7272 17337, 7275 17337, 7280 17340, 4280 21340, 4280 21344, 4281 21344, 4283 21344, 4288 24344, 4292 24347, 9292 24351, 9296 24353, 9298 24351, 9300 25351, 9303 25352, 9303 25352, 9306 25357, 9305 25361, 9305 25356, 11305 25359, 11306 25362, 11309 25362, 11314 25362, 11314 25365, 11312 25369, 11315 25369, 11316 25373, 11321 25375, 11323 25375, 11327 25370, 11331 25369, 11332 25370, 11331 25374, 11332 25369, 11336 25371, 11340 25370, 11345 25367, 11350 25363, 11347 25360, 11350 25361, 11351 25362, 11351 25362, 11354 25364, 11358 30364, 11362 30369, 11362 30369, 11364 30369, 11369 30371, 11370 30373, 15370 30374, 15375 30375, 15378 30377, 14378 30382, 14379 30387, 14383 30382, 14388 30384, 14390 30386, 14393 30389, 14395 31389, 16395 31393, 16398 31398, 16398 31401, 16394 31404, 16397 31409, 16400 31413, 16400 31417, 16399 31419, 16398 31421, 16403 31422, 16403 31426, 16404 31423, 16409 31424, 16413 31423, 16408 31427, 18408 31431, 18413 31436, 18417 28436, 18419 28441, 18420 28445, 18416 28442, 18419 28439, 18418 28443, 18422 28446, 18425 28451, 18429 28448, 21429 28449, 21430 28454, 22430 28459, 22434 28461, 22438 28462, 22443 28462, 22447 28467, 22450 28472, 22453 28469, 22458 28472, 22455 28472, 22460 28475, 22465 28477, 22462 28479, 22461 28476, 22465 28480, 22466 28476, 22470 28472, 22470 28475, 25470 28470, 25473 28472, 25475 28468, 25475 28468, 25477 29468, 25478 29470, 25481 29465, 25478 29466, 25478 29468, 25480 29468, 25485 29465, 25486 29464, 25488 29462, 25488 29466, 25492 29464, 25497 26464, 25500 26467, 25497 26472, 25497 26476, 25497 26476, 25501 26478, 25506 26480, 25506 26482, 25511 26480, 25515 26483, 25516 26485, 25521 26481, 25521 26484, 25520 26485, 25521 26488, 25526 26487, 25529 26488, 25524 26488, 25528 26491, 25530 26496, 25535 26500, 25537 26502, 25537 26502, 25541 26507, 25544 26508, 25545 26509, 25549 26514, 25554 26514, 25553 26512, 25552 26516, 25555 26514, 25559 26514, 25556 26515, 25554 26512, 25558 26509, 25558 26510, 25562 26510, 25562 26511, 25562 26510, 25567 26505, 25569 26508, 25571 26508, 25570 26512, 25573 26512, 25573 26515, 25578 26515, 25583 26520, 25583 26523, 25584 26525, 25587 26526, 25590 26531, 25590 26530, 25586 26534, 25589 26538, 25591 26533, 25595 26537, 25600 26542, 25601 26544, 25601 26544, 25601 26544, 25606 26547, 25605 26547, 25605 26542, 25608 26542, 25611 26544, 25613 26546, 25614 26551, 25614 26551, 25614 26552, 25619 25552, 25614 25552, 25615 25551, 25618 25549, 25618 25553, 25620 25555, 25622 25559, 25622 25555, 25624 25554, 25627 25555, 25624 25559, 25621 25561, 25619 25560, 25624 28560, 25627 28555, 25632 28550, 25636 28552, 25641 28557, 25645 28557, 25640 25557, 25636 25557, 25636 25561, 25641 25561, 25645 25562, 25646 25557, 25648 25560, 25649 25564, 25652 25566, 25652 30566, 25652 30566, 25652 30568, 25652 30570, 25654 30574, 25658 30575, 25663 31575, 25664 31579, 25665 31583, 25664 31583, 25667 31585, 25668 31588, 25673 31586, 25676 31585, 25676 31588, 25678 31588, 25675 31591, 25680 31590, 25681 31585, 30681 31588, 30677 31593, 30682 31594, 35682 31594, 35677 31593, 35679 31595, 35682 31594, 35683 31591, 35686 31592, 35687 31593, 35691 31596, 35691 31597, 35694 31601, 35698 31601, 35702 34601, 35701 34603, 35705 34608, 35705 34610, 35704 34605, 35707 34607, 35707 34610, 35710 34607, 35715 34608, 35719 34607, 35721 34612, 35717 34612, 35713 34612, 35715 34613, 35716 34609, 35716 34614, 35716 34618, 35720 34620, 35721 34621, 35724 34622, 35724 34625, 35727 34629, 35727 34630, 35727 34633, 35727 34635, 35727 34639, 35732 34640, 35729 34642, 35733 34644, 35737 34646, 35741 34649, 35743 34649, 35744 34653, 35740 34653, 35740 34649, 35743 34651, 38743 34654, 38743 37654, 38744 37650, 38748 37655, 38751 37656, 38755 37657, 38755 37661, 38759 37660, 38758 37664, 38763 37664, 38767 37664, 38762 37664, 38761 37664, 38762 41664, 38762 41664, 38764 41669, 38759 41671, 43759 41673, 43754 41678, 43754 41681, 43759 41676, 43760 41681, 45760 41684, 45760 41683, 45764 41687, 45767 41687, 45771 41687, 45772 41688, 45770 46688, 45775 46692, 45778 46696, 45776 46698, 45777 46701, 45780 46699, 45778 46702, 45776 46706, 45781 46706, 45786 46708, 45789 46710, 45793 46715, 45788 46711, 45792 46715, 45795 46719, 45798 46723, 45801 46728, 45799 46732, 45804 46730, 45799 46733, 45803 46737, 45804 46737, 45805 46736, 45806 46736, 45807 46736, 45810 46739, 45812 46744, 45812 46748, 2328 27377, 2324 27381, 2325 27383, 2327 27387, 2327 27386, 2324 27386, 2325 27386, 5325 23386, 5327 23389, 5331 23390, 5332 23394, 5337 23396, 5332 23396, 5332 23399, 5331 23399, 5335 23403, 5335 23406, 5340 23409, 5341 23409, 5336 23410, 5331 23405, 5334 23407, 5332 23411, 5335 23413, 5330 20413, 5326 20415, 5326 20418, 5331 20420, 5330 20425, 5327 20425, 5331 20428, 5332 20428, 5337 21428, 5333 21431, 5335 21435, 5336 21437, 5331 21438, 5332 21441, 5335 21444, 5340 21441, 5340 21444, 5336 21445, 5335 21442, 5331 26442, 5334 26439, 5337 26443, 5339 26444, 5340 26448, 5344 26443, 5344 26446, 5347 26444, 5351 26442, 5354 26446, 5351 26449, 5350 30449, 5352 30451, 5352 30448, 5356 30448, 5361 30447, 5365 30449, 5369 30450, 5369 30452, 5369 30457, 5373 30459, 5373 30457, 5375 30462, 5377 30465, 5382 30467, 5386 30467, 5385 30463, 5386 30463, 5385 30463, 5387 30464, 5392 30463, 5394 30468, 5396 30468, 5391 30469, 5395 30473, 5393 30473, 5393 30473, 5397 30478, 5398 30474, 5401 30474, 5403 30471, 5403 30472, 5406 30474, 5402 30469, 5403 30466, 5405 30471, 5406 30471, 5411 30473, 5414 30477, 5414 30481, 5409 30485, 8409 30490, 8410 30493, 8412 30494, 8412 30493, 8415 30494, 8416 30497, 8416 30500, 8421 30505, 8422 30506, 8417 30511, 13417 30513, 13413 30510, 13416 30511, 13414 30515, 13414 30519, 13419 30522, 13421 30527, 13420 30531, 13424 30533, 13420 30535, 13415 35535, 13411 35535, 13415 35536, 13419 35541, 13421 35537, 13425 35533, 13426 35533, 13425 35528, 13430 35529, 13435 35530, 13440 35534, 13445 35535, 13450 35535, 13454 35536, 13457 35540, 13459 35540, 13454 35540, 13457 35543, 13454 35539, 13459 35544, 13459 35548, 18459 35550, 18462 35551, 22462 35550, 22467 35554, 22468 35558, 22470 35556, 22475 35559, 22473 35563, 22472 35568, 22474 35568, 22472 35573, 22476 35573, 22476 35575, 22479 35577, 22484 35580, 22489 35584, 22490 35587, 22491 35589, 22495 35589, 22498 35589, 25498 35590, 25495 35586, 25496 35589, 25500 35589, 25498 35589, 25500 35591, 25505 35595, 25505 35597, 25501 35594, 25501 35595, 25497 35595, 26497 35599, 29497 35595, 29497 35597, 29500 35601, 29500 35605, 29502 35610, 29503 30610, 29504 30607, 29507 30607, 29512 30610, 29513 30610, 29516 30611, 29518 30614, 29520 30612, 3261 17309, 3265 17308, 3269 17307, 3273 17312, 3271 17316, 3271 17317, 3276 17319, 3279 17319, 3284 17315, 3287 17317, 3285 17313, 3280 17314, 3277 17319, 3277 17321, 3278 17326, 3282 17328, 3282 17328, 3278 17329, 3279 17329, 3278 17332, 3280 17328, 3275 17333, 3279 17335, 3282 17330, 3283 17332, 3278 17328, 3279 17328, 3279 17326, 3279 17325, 3279 17325, 3283 17327, 3284 17331, 3284 17336, 3289 17339, 3290 17339, 3290 17342, 3292 17341, 3296 17344, 3296 17345, 3301 17345, 3301 12345, 3301 12346, 3306 12343, 3303 14343, 3307 14344, 3309 14345, 3313 14347, 3315 14347, 3316 16347, 3312 16345, 3312 16350, 3314 16352, 3313 16353, 4313 16350, 4318 16352, 4323 16348, 4326 16352, 4324 16353, 4325 16350, 4325 16350, 4328 16354, 4324 16358, 4325 16360, 4327 16365, 4327 16362, 4324 16366, 4327 20366, 4327 20370, 4324 20371, 4328 20376, 4328 20378, 4333 20377, 4335 20377, 4340 20380, 4341 20383, 4343 20386, 4340 20388, 4341 20390, 4342 20387, 4342 20387, 4337 20392, 4338 20394, 4343 20394, 4348 20395, 4350 20395, 4351 20397, 37499 26503, 37496 26500, 37498 26504, 37498 26505, 37501 26510, 37499 26506, 37500 26506, 37502 29506, 37502 29511, 37507 29512, 37508 33512, 37510 33517, 37515 33522, 37519 33526, 37518 33524, 37523 33525, 37523 33529, 37518 33534, 37521 33532, 37522 33532, 37526 33534, 37529 33534, 37527 33531, 37530 33534, 37535 33537, 37536 38537, 37538 38540, 22360 13359, 25360 13364, 25363 13362, 25364 13366, 25364 13366, 25367 13369, 25365 13371, 25361 13373, 25359 13378, 25362 13378, 2249 13366, 2254 13370, 2256 13367, 2259 13367, 2263 13362, 2266 13358, 2266 13360, 2271 13365, 2274 13367, 2276 13367, 2277 13367, 2275 13366, 2276 13369, 2280 13369, 2282 13374, 2286 13370, 2286 13369, 2291 13372, 2292 13370, 2295 13372, 2300 13377, 2300 13376, 2297 13379, 273 22351, 275 22354, 4275 22351, 4271 22352, 4272 22354, 4273 22359, 4274 22364, 4278 22367, 4283 22369, 4286 24369, 4281 24369, 4284 24369, 4287 24369, 4289 24368, 4291 24366, 4296 24364, 4297 24366, 4300 24369, 4303 24373, 1303 24374, 1303 24375, 1307 24379, 1307 24380, 1309 24381, 1314 24384, 1316 24386, 1320 24384, 1318 24386, 1318 24391, 1320 24391, 1320 29391, 1323 29391, 1318 29387, 1322 29390, 1323 29393, 1328 29393, 1329 29393, 2329 29398, 2329 29398, 2334 29397, -664 24371, -661 24372, -659 24372, -654 24375, -651 24376, -647 24376, -645 24378, -641 24374, -636 24379, -633 24384, -636 24386, -636 24388, -636 24388, -634 24392, -635 24394, -630 24390, -628 24390, -627 24390, 373 24393, 378 24398, 376 24396, 379 24401, 3379 24404, 6379 24409, 6380 24412, 6375 24410, 6372 24410, 6377 24407, 6372 24407, 6377 24407, 6381 24410, 6376 24413, 6380 24415, 6382 24416, 6380 24419, 6380 24423, 6385 24427, 6387 24429, 6389 24432, 6392 24437, 6388 24434, 6388 24439, 6389 24440, 6390 24444, 6389 24448, 6385 29448, 6385 29451, 6388 29455, 6384 29450, 6389 29451, 6392 29456, 6395 29456, 6399 29459, 6402 29463, 6402 29467, 6399 29471, 6395 29471, 6397 29474, 6399 29477, 6401 29472, 6396 29471, 6399 29474, 6398 29477, 6398 29474, 6395 29469, 6391 29473, 6392 29474, 6391 29469, 6391 29472, 6394 29474, 6390 33474, 6392 33470, 6393 33470, 6394 33471, 6396 33471, 324 22376, 324 22378, 325 22381, 329 22382, 333 22386, 332 22387, 334 22390, 335 22387, 333 22387, 332 22391, 334 22395, 334 22400, 339 22401, 341 22398, 342 22403, 342 22402, 342 22400, 345 22400, 345 22400, 343 22404, 344 22408, 345 22406, 350 22407, 347 22411, 349 22415, 344 22415, 347 22417, 342 22421, 347 22421, 350 22426, 350 22430, 353 22431, 354 22436, 354 22440, 4354 22442, 4355 22446, 4356 22448, 4356 22451, 4359 22453, 4362 22454, 4366 22454, 4369 22455, 4371 22457, 4368 22459, 4371 22457, 4375 22462, 4379 22463, 4382 22463, 4382 22468, 4387 22471, 4387 22471, 4392 22473, 4387 22473, 4387 22476, 25573 26512, 25576 26511, 25580 26516, 25583 26516, 25583 26516, 25585 26512, 25585 26517, 25589 26520, 25591 26519, 25592 26519, 25593 26521, 25591 26524, 25589 26526, 23589 26530, 23587 26535, 23591 26538, 23594 26542, 24594 26547, 24590 26549, 24595 26551, 24600 26547, 24600 26552, 24604 26549, 24600 26544, 24602 26549, 24602 26552, 24602 31552, 24607 31553, 24610 31555, 24615 31556, 24617 36556, 24618 36561, 24621 36561, 24624 36564, 24624 36568, 24629 35568, 24629 35573, 24634 35573, 25634 35574, 25637 35573, 25638 35577, 25638 35577, 25640 35580, 25643 35584, 25643 35587, 25643 35592, 25644 40592, 20644 40597, 20647 40597, 20652 40599, 20653 40595, 20653 40598, 20650 40595, 20650 40595, 20654 40600, 20654 40600, 20658 40601, 20658 40604, 20658 40605, 20661 40602, 20664 40601, 20664 40601, 20665 40604, 20670 40605, 20667 40610, 1217 13318, 1216 13323, 1214 13321, 1211 13316, 1212 13316, 1213 13321, 6213 13324, 6216 13324, 6218 13324, 6213 13327, 6216 13322, 6216 13327, 6216 13328, 6218 13323, 6221 13327, 6220 13325, 6221 13325, 6220 13330, 6223 13333, 6227 13335, 6232 13339, 6233 13343, 6233 13347, 6237 13342, 6236 13346, 6236 13348, 6238 13349, 25526 26487, 25523 26488, 25526 26493, 25529 26491, 25531 26488, 25532 26486, 25536 27486, 25541 27490, 25539 27492, 25543 27487, 25546 27490, 25549 27494, 25552 27495, 25552 27495, 25556 27490, 25561 27490, 25565 27493, 25563 27493, 25565 27497, 25563 27495, 25565 27497, 25565 27499, 25566 27501, 25565 27501, 25565 27501, 25560 27502, 25565 27503, 25567 27507, 25569 27507, 25571 27507, 25569 27508, 25567 27509, 25567 27509, 25567 27509, 25568 27509, 25572 27505, 25572 27501, 25576 27502, 25572 32502, 25572 32505, 25575 32505, 25578 32501, 25578 32502, 25579 32505, 25581 32507, 25585 32508, 25590 32511, 25594 32516, 25598 32511, 25601 32511, 25596 32507, 25599 32510, 25599 32514, 25596 32513, 25596 32514, 25598 32517, 25594 32517, 25596 32519, 25596 32524, 25600 32524, 25604 32521, 25605 32522, 27605 32524, 27609 32527, 27610 31527, 27615 31531, 27617 31531, 30617 31534, 30619 31534, 30620 31536, 30621 31540, 30625 31541, 30625 31542, 30627 31542, 30628 31545, 30629 31545, 30626 31544, 30625 31544, 30626 31549, 34626 31550, 34621 31547, 34625 31549, 34626 31553, 34626 31552, 34628 31554, 34628 31559, 34628 31555, 34630 31559, 34635 31559, 34638 31563, 34636 31568, 34638 31568, 34641 31566, 34641 31564, 36641 31559, 36638 27559, 41638 27561, 41642 27558, 41646 27562, 41649 27563, 41650 27559, 41655 27559, 41660 27559, 41660 27556, 41660 27556, 41662 27554, 41658 27558, 41663 27562, 41666 27565, 41669 27570, 41664 27566, 41665 27567, 41665 27569, 41664 27573, 41663 27573, 41666 27575, 41666 27571, 41661 30571, 41662 30569, 41662 30565, 41667 30570, 41666 30565, 41666 30565, 41666 30566, 41666 30567, 41662 30562, 1314 24384, 4314 25384, 4317 25388, 4317 25389, 4321 25387, 4324 25392, 6324 25391, 6324 25391, 6328 25396, 6323 25401, 6326 25401, 6326 25405, 6321 25408, 9321 25409, 9316 25404, 9314 25406, 9312 25407, 9315 25407, 9315 25407, 9318 25404, 9321 25405, 4321 25400, 8321 25402, 8317 25404, 8317 25400, 8317 25401, 8313 25402, 8309 25398, 8311 25398, 8313 25401, 8317 25406, 8312 25407, 11312 25369, 11313 25369, 11318 25374, 11322 25379, 11327 25379, 11327 25384, 11327 25386, 11328 25382, 14328 25384, 14330 25386, 14333 25387, 14336 25389, 14338 25390, 19338 25390, 19338 25393, 19334 25394, 19334 25395, 19337 25392, 19340 25395, 19344 25397, 19342 25397, 19347 25400, 19347 25398, 19349 25398, 19351 25397, 19353 25401, 19352 25402, 19350 25403, 19351 25407, 19354 25403, 19352 25406, 19356 25404, 19355 25409, 23355 25406, 23356 25406, 23358 25409, 23360 25413, 23362 25417, 23365 25418, 23369 25416, 23367 25415, 23369 25418, 23365 25417, 23369 25420, 23369 25420, 23372 25422, 24372 25418, 24372 25423, 24375 27423, 24380 27423, 24382 27420, 24382 27416, 24382 27414, 24382 27410, 24378 27410, 24376 27414, 24372 27418, 24372 27419, 24373 27424, 24377 27419, 24380 27415, 24377 27419, 24380 27422, 24384 27425, 24385 27430, 24385 27429, 24387 27434, 24392 27435, 24396 27436, 24397 27440, 24401 30440, 24402 30443, 24406 30447, 24405 30443, 24408 30442, 24412 30446, 24408 30450, 24410 30449, 24405 30449, 24410 30446, 24414 30450, 24418 30450, 24418 30453, 19418 30453, 19418 30451, 19420 30456, 19422 30457, 19425 30462, 15425 30466, 15425 30468, 15427 30470, 16427 30471, 16426 30475, 16423 30478, 16428 30478, 16430 30480, 16430 30480, 16426 30478, 16426 33478, 16427 33478, 16429 33481, 16427 33483, 16428 33481, 16424 33484, 16427 33486, 16432 33483, 16432 33482, 16431 33486, 16426 33486, 16429 33488, 16432 33492, 16433 33492, 16436 33492, 16437 33495, 16434 33491, 16438 37491, 16436 37494, 16440 37489, 16445 37486, 16448 37484, 16449 37484, 16449 37486, 16453 37482, 16456 37483, 16460 37483, 16456 37483, 16456 37486, 16461 37490, 16462 37495, 16465 37499, 16466 37496, 16467 37497, 16468 37498, 16470 37501, 16470 37505, 16470 37505, 16475 37507, 16475 37507, 16475 37502, 16478 37498, 21478 33498, 21475 33497, 21478 33493, 21480 33495, 21480 33500, 21480 33496, 21482 33500, 21485 33505, 21486 33508, 21485 33504, 21486 33509, 21486 33509, 21490 35509, 21493 35509, 21496 35510, 21498 35514, 21494 35510, 21494 35513, 21491 35518, 21492 35521, 21489 35523, 23489 35527, 23487 35532, 23489 35537, 23485 35538, 23489 35539, 23490 35541, 23495 35543, 23497 35546, 23497 35550, 23497 35554, 23493 35553, 23490 35556, 23494 35559, 23497 35564, 23502 35563, 23498 35561, 4324 16358, 4319 16362, 4320 16362, 4322 16367, 4317 16367, 4317 16366, 4318 20366, 4322 20369, 4325 20367, 4328 20370, 4331 20371, 4334 20374, 4339 20378, 4340 20379, 4335 20379, 4340 20379, 4343 20381, 4344 20381, 4344 20382, 4345 20385, 4348 20390, 4348 20390, 4348 20390, 4348 20390, 4351 20394, 4354 20399, 4356 20400, 4357 20404, 4360 20404, 4362 20405, 4362 20408, 4365 20409, 4370 20410, 4374 20415, 4373 20420, 4369 20421, 4366 20426, 4369 20424, 4374 20429, 4375 20426, 4376 20422, 4379 20422, 4383 20426, 4384 20427, 4386 20422, 4391 20425, 4387 20427, 4392 20427, 4392 20429, 4394 20433, 4398 20438, 41576 39702, 41580 39706, 41578 39708, 45578 39708, 45577 39713, 45579 39717, 45583 39719, 45583 39722, 45585 39725, 45580 39730, 47580 39726, 47583 39723, 47588 39726, 47588 39730, 47591 39734, 47594 39737, 47599 39737, 47595 39737, 47598 39739, 47599 39739, 47597 39739, 47593 39743, 47595 39748, 47595 39751, 4076 20267, 4079 20272, 4081 20272, 4080 20275, 4080 22275, 4085 22280, 4089 22276, 4090 22279, 4088 22283, 4084 22284, 4086 22286, 4088 22281, 4084 22281, 4089 22285, 4092 22285, 4094 22285, 4094 22290, 4096 22291, 4099 22294, 4099 22295, 4097 22290, 4097 22292, 4097 22297, 4097 22292, 4094 22289, 4091 22290, 4092 22290, 4097 22285, 4102 22290, 4105 22289, 4106 22292, 4106 22293, 4109 22298, 4114 22296, 4119 22294, 4122 22299, 122 22304, 123 22307, 124 22304, 124 22304, 123 26304, 127 26307, 131 26307, 129 26309, 129 26310, 134 26310, 134 26311, 138 26311, 143 26313, 142 26315, 145 26317, 142 26318, 147 26322, 151 26322, 155 26325, 155 29325, 160 29330, 160 29333, 164 29328, 164 34328, 167 34333, 170 34332, 169 34336, 171 34337, 175 34338, 175 34340, 179 34342, 180 34344, 180 34348, 184 34352, 179 34352, 184 34352, 186 34357, 186 34362, 183 34364, 185 34369, 189 34369, 194 34369, 199 34371, 201 34370, 205 34372, 207 34372, 204 34367, 206 34364, 1206 34364, 1207 34368, 1207 30368, 1207 30363, 1208 30365, 1209 30368, 1212 30370, 1212 30370, 1216 30371, 1220 30376, 1221 30379, 1216 30383, 1216 30388, 1219 30386, 1224 30387, 1225 30386, 1227 30384, 1230 30383, 1233 30387, 1234 30387, 1237 30388, 1239 30392, 1244 30390, 1246 30393, 2246 30396, 2243 30399, 2247 30401, 2247 30403, 2246 30398, 2244 30399, 2248 32399, 2248 32399, 2251 32402, 2253 32397, 5253 32394, 5253 32399, 5257 32403, 5257 32401, 5259 32401, 5259 32405, 5263 32410, 5263 32415, 5268 32416, 5273 32420, 5275 32423, 5278 32424, 5283 32426, 5281 32429, 6281 33429, 6286 33433, 6286 33434, 6284 33435, 6284 33432, 6288 33429, 6290 32429, 6290 32425, 6288 32428, 6290 32428, 11290 32431, 11294 32429, 11294 32433, 11292 32438, 11288 32441, 11288 32441, 11285 32446, 11280 32446, 11281 32447, 11285 32449, 11286 32449, 11285 32452, 13285 32451, 13289 32446, 16289 32450, 16284 32449, 16285 32449, 16286 32452, 16287 32452, 16286 32450, 16288 32447, 16292 32450, 16293 32450, 16294 32454, 16293 32454, 16293 32454, 16293 32449, 16289 32451, 16290 32456, 16289 32461, 16293 36461, 16291 36466, 16295 36466, 16296 36466, 16299 36466, 16303 36468, 16308 36473, 16312 36471, 16312 36467, 16315 36463, 16314 36464, 16315 36469, 16315 36473, 16310 36474, 16311 36472, 16316 36474, 16321 41474, 16324 41475, 16327 44475, 16332 44475, 16332 44475, 16332 44477, 16332 44478, 16337 44483, 16334 44481, 8416 30500, 8417 30501, 8421 30501, 8416 30505, 8418 30504, 8420 30499, 8423 35499, 8425 35498, 8429 35501, 8431 35503, 8434 35503, 8438 35507, 8440 35507, 8445 35509, 8442 35512, 8445 35513, 8442 35513, 8442 35515, 8443 35519, 8447 35515, 8450 35516, 8445 35521, 8445 35523, 8444 35528, 8446 35530, 8443 35531, 8438 35531, 8435 35527, 8431 35531, 8432 35534, 8433 35536, 8431 35537, 8435 35539, 8439 32539, 8437 32540, 8441 32540, 8438 32543, 9438 32546, 9436 32541, 9431 32538, 9431 32538, 9435 32541, 9435 32546, 9431 32547, 9436 32542, 9438 32542, 9438 34542, 7438 34542, 7440 34547, 7441 34547, 7441 34547, 7441 34552, 7440 34553, 7440 34556, 7440 34557, 7440 34560, 11440 34565, 11436 34563, 11438 34559, 7438 34557, 7438 34553, 122 1239, 126 1243, 127 1240, 127 1242, 131 1239, 130 1239, 127 1240, 125 1243, 130 2243, 134 2246, 133 2246, 137 2246, 142 2246, 147 2251, 148 2256, 146 2257, 148 2252, 146 2249, 148 2248, 152 2253, 157 2249, 161 2246, 162 2247, 162 2249, 157 2248, 158 2249, 3158 2250, 3161 2252, 3161 2254, 3166 2258, 3167 2261, 3168 2259, 3171 2261, 3173 2266, 3171 2267, 3176 2272, 3179 2277, 3176 2280, 3180 2279, 3175 2283, 3179 2280, 3182 2283, 3184 2288, 3187 2293, 5187 2290, 5187 2292, 5183 2290, 5187 2292, 5186 2297, 5189 2297, 5189 2301, 5192 2303, 5189 2303, 5187 2304, 5183 6304, 5184 6301, 5189 6304, 5191 6302, 5193 6300, 5195 6300, 5195 6300, 5197 6301, 5197 6304, 5199 6301, 5197 6304, 5192 6306, 5193 6310, 5194 6312, 5197 6316, 24397 27440, 24393 27441, 24395 27437, 24400 27440, 24400 27441, 16288 32447, 21288 32447, 21288 32448, 21284 32452, 21285 32450, 21285 32452, 21287 32455, 21283 32460, 21284 32462, 21284 32467, 21284 32472, 21286 32474, 21291 32475, 21289 32475, 21289 32473, 21289 32478, 21286 32481, 21290 32486, 21293 32486, 21293 32490, 21298 32489, 21301 32490, 21303 32491, 21305 32488, 21303 32486, 21307 32491, 21312 32495, 21314 32499, 21315 32495, 21317 32499, 21314 32499, 21316 32502, 21318 32505, 21313 32510, 21313 32512, 21314 32517, 21319 32520, 21321 32520, 21326 32520, 21329 32525, 21330 32530, 21334 32531, 21330 36531, 21333 41531, 21338 41531, 21336 41535, 21339 41537, 21337 41539, 21341 41544, 21342 41544, 21345 41540, 25345 41543, 25342 41546, 25339 41546, 25339 41549, 25337 41546, 25337 41547, 25337 46547, 25341 46552, 30341 46555, 30342 46560, 30345 46561, 30344 46557, 30339 46560, 30343 46565, 30339 46569, 30338 46567, 30340 46568, 24375 27423, 24375 27425, 24377 27428, 24379 27429, 24379 27434, 24376 27439, 24381 27441, 24386 27436, 24387 27438, 24384 27441, 24383 27446, 24383 31446, 24383 33446, 20383 33443, 20385 34443, 20384 34444, 20380 34448, 20383 34450, 20383 34446, 20386 34447, 20390 34450, 20394 34451, 20395 34446, 20395 34451, 20398 29451, 20397 29447, 20401 29447, 20402 29443, 20401 29440, 20406 29443, 20411 29444, 20412 29444, 20412 29448, 20410 29449, 20415 29452, 20415 29455, 20414 29459, 20415 29462, 20420 29465, 20415 29467, 20417 29468, 20418 29468, 20418 29467, 20418 29467, 20420 29468, 20416 29469, 20420 29467, 20415 29464, 20415 26464, 20420 26462, 20423 26463, 20423 26465, 20423 26464, 43580 35662, 43580 35658, 43580 35662, 43580 35664, 43585 35665, 43585 35663, 43585 35666, 43581 35667, 43585 35665, 43589 35670, 25627 25555, 25631 25555, 25632 25558, 25632 25563, 25634 25564, 25629 25565, 25625 25561, 25625 25563, 25626 25565, 26626 25570, 26629 25570, 29629 25575, 29628 25578, 29627 25579, 29624 25583, 29627 25587, 29632 25592, 29634 25593, 29637 25595, 29637 25598, 29639 25602, 29644 25600, 29645 25601, 29646 25601, 29651 25602, 29656 25606, 29658 25606, 29663 25607, 29663 25605, 29666 26605, 29668 26608, 29667 26608, 29670 26611, 29674 26611, 29671 26615, 29673 26620, 29676 26617, 29681 26620, 29682 26620, 29683 26619, 29684 26623, 29681 26621, 29686 26626, 29688 26628, 29691 26628, 29692 26632, 29693 26634, 29695 26629, 29696 26624, 29700 26621, 29705 29621, 29709 29620, 29708 29624, 29711 29627, 34711 29630, 34712 29632, 34712 29631, 2284 16415, 2285 16416, 2285 16416, 2289 16421, 2294 16425, 2299 16425, 2300 16430, 2305 16430, 2306 16433, 2311 11433, 2315 11436, 2310 14436, 2310 14435, 2313 14437, 2312 14441, 2310 14442, 2311 14444, 2313 14444, 2311 14447, 2314 14447, 2316 14451, 2316 14456, 2316 14454, 2311 14455, 2311 14455, 2311 14460, 2315 14465, 2315 14465, 2311 19465, 2311 19465, 2313 19466, 2317 19469, 2320 19469, 2323 19466, 2319 19468, 2323 19471, 2324 19471, 2324 19473, 2324 19473, 2322 19468, 2323 19466, 2324 19465, 2329 19470, 2329 19465, 2324 19465, 2324 19467, 2319 19471, 2320 19475, 2104 -1844, 2109 -1844, 2113 -1842, 2116 1158, 2116 1160, 2117 1161, 2116 6161, 2118 6166, 2123 6169, 2126 6174, 2123 6179, 2126 6183, 2126 6187, 2130 6182, 2128 6183, 2127 6182, 2128 6185, 2124 10185, 2129 10190, 2130 10193, 2132 10192, 2132 10195, 2129 11195, 2129 11199, 2133 11200, 2134 11196, 2133 11201, 2137 11205, 2137 11207, 2141 11203, 2144 11207, 2145 11208, 2149 11212, 2144 11214, 2144 11215, 2149 11216, 2152 11221, 2152 11223, 2153 11223, 2154 11226, 2154 11226, 2150 11228, 2152 11224, 2152 11227, 2148 11222, 2145 11223, 2142 11225, 2145 11222, 2142 11223, 2142 11227, 2147 11229, 2149 11230, 2154 11230, 2157 11228, 2159 11233, 2159 11233, 2155 11237, 2155 11242, 2151 11243, 7151 10243, 7156 10245, 7159 10245, 7164 10247, 7166 10252, 7166 10255, 7171 10257, 7173 10257, 7174 10261, 7179 10264, 7184 10260, 7189 10264, 7193 8264, 7197 8260, 7202 8262, 7206 8262, 7205 8265, 7205 8266, 7207 8270, 7211 8274, 7211 8277, 7216 8277, 7216 8280, 7212 8280, 7213 8280, 7215 8283, 7220 8282, 7224 8287, 7225 8283, 7222 10283, 7223 10287, 7225 10288, 7230 10290, 7232 10294, 7233 10294, 7233 10297, 7234 10298, 7234 10301, 7236 10303, 7231 10299, 7228 10298, 7223 10297, 7225 10299, 7230 10303, 7231 10307, 7234 10311, 7234 10315, 7235 10320, 7236 9320, 7241 9322, 7246 9325, 7243 9330, 7243 9332, 7240 9335, 7237 9334, 7239 9339, 7238 9339, 7238 9341, 7238 9342, 7233 14342, 7232 14337, 7234 14342, 7239 18342, 4084 22284, 4083 22284, 6083 22287, 6078 22289, 6078 22293, 6080 22290, 6082 22291, 6086 22296, 6086 22297, 6087 22297, 6088 22295, 6093 22298, 6094 22297, 9094 22294, 9097 22298, 9098 22299, 9098 22301, 9093 22296, 9098 22299, 9100 22294, 9096 18294, 9099 18294, 9098 18298, 9101 18296, 9100 18301, 9105 18303, 9105 18306, 9105 18309, 9102 18305, 9104 18306, 9108 18309, 9104 18314, 9103 18310, 9105 18312, 9105 18316, 9109 18314, 9109 18319, 9109 18324, 9113 18326, 9113 18330, 9115 18333, 9113 18333, 9118 18333, 9123 18333, 9123 18336, 9125 18335, 9126 18336, 9127 18332, 9129 18329, 9127 18332, 9130 18333, 9135 18333, 9138 18337, 9143 18341, 9144 18346, 9145 18344, 9150 18348, 9154 18345, 9152 18350, 9151 18345, 9151 18345, 9156 18347, 9160 18349, 9163 18350, 9163 18351, 9165 18356, 9166 18356, 9164 18353, 9167 18356, 9167 18355, 9167 18356, 9167 18360, 9165 18356, 9169 18357, 9169 18353, 9170 18355, 9170 18351, 9175 18351, 9177 18351, 9181 18352, 9184 18353, 9189 18356, 9188 18361, 9191 18364, 9194 18364, 9198 18366, 13198 18371, 13198 18373, 13198 18375, 13201 18378, 13196 18378, 13199 18379, 13202 18381, 13207 18384, 13212 18388, 13211 18383, 13211 18378, 13215 18379, 13218 20379, 13214 20379, 13217 20379, 13213 20379, 13213 20376, 13210 20377, 13206 20377, 13206 20373, 13207 20373, 13209 20370, 13214 20371, 13218 20371, 13223 20376, 13224 20381, 13227 20385, 13228 20390, 13232 20387, 9232 20392, 9230 20388, 9230 20390, 9225 20393, 9225 20396, 4225 20401, 4225 20400, 4227 20403, 4224 20408, 4222 20412, 4222 20415, 4225 20420, 4229 20425, 4232 20422, 4236 20425, 4234 20426, 4238 20427, 4240 20427, 4241 20427, 4237 20431, 4233 20431, 4232 20430, 4230 20432, 4234 20431, 4234 20435, 4238 20437, 4243 20435, 4243 22435, 4238 22440, 4241 22441, 4241 22443, 4238 22447, 4234 22443, 4238 22448, 4238 22450, 4241 22451, 4241 22456, 4243 22458, 4247 22461, 4247 22464, 4252 22466, 4253 22469, 4255 22469, 4251 22469, 4253 22464, 4253 22468, 4257 22473, 4259 22477, 4258 22482, 4261 22483, 4262 22484, 4259 22489, 6259 22493, 6262 22494, 6262 22497, 6264 22500, 6264 22504, 6269 22499, 6273 22499, 6278 22495, 6278 22493, 6283 22491, 6288 22494, 6291 22494, 6296 22494, 6296 22493, 6294 22489, 6294 22493, 6290 22493, 6290 22498, 6290 22500, 6288 22501, 6290 22505, 6294 22504, 5294 22507, 5294 22507, 5298 22512, 5297 22514, 5302 22514, 5307 22517, 5304 22518, 5308 22514, 5311 22517, 5315 27517, 5315 27517, 5319 27517, 5324 22517, 5328 22521, 6328 22520, 6325 22522, 6325 22527, 6322 22527, 6323 22530, 6325 22535, 6325 22535, 6326 22536, 6326 22536, 6327 22533, 6323 22535, 6325 22538, 6330 22538, 6331 22534, 6326 22531, 10326 22526, 10321 22528, 10317 22524, 10316 22529, 10313 22529, 10309 22530, 10306 22535, 10308 22531, 10308 22532, 10311 22534, 10314 27534, 10314 27538, 10314 27538, 10309 27540, 10309 27536, 11309 27535, 11309 27537, 11310 27539, 11305 27535, 11300 27536, 11296 27538, 11296 27538, 11301 27542, 11299 27546, 11304 27551, 11308 27551, 11313 27553, 11315 30553, 11319 30555, 11315 30550, 11318 30545, 11318 30544, 11321 30549, 11320 30550, 11325 30554, 11328 30558, 11328 34558, 11332 34562, 11333 34562, 11335 34562, 11334 34565, 11330 34565, 11333 34566, 11338 34566, 11338 34571, 11342 34574, 11344 34573, 11347 34572, 11346 34573, 11347 34575, 11351 34578, 15351 34578, 15356 34573, 15361 34570, 15364 34575, 15365 34580, 15369 34581, 15370 34581, 15373 34585, 15376 34580, 15381 34578, 15385 34583, 15386 34588, 15389 34587, 17389 34582, 17394 34582, 17393 34582, 17398 34577, 17399 34582, 17399 34584, 17399 39584, 17404 39588, 17399 39591, 17404 39591, 17408 39586, 17405 39591, 17409 39593, 17411 39596, 17408 39596, 17411 39599, 17411 39603, 17414 39607, 17418 39612, 17419 39612, 17419 39612, 17423 39611, 17424 39613, 17426 39612, 17429 39608, 17427 39609, 17428 39613, 17425 39615, 17424 39614, 17427 39617, 17430 39622, 17430 39623, 17431 39620, 17434 39620, 13434 39619, 13434 39621, 13434 39621, 13434 44621, 13436 44625, 13436 44627, 13441 44631, 13444 44636, 13444 44639, 13442 44635, 13444 44635, 13447 44639, 13449 44643, 13447 44641, 13447 44642, 13452 44643, 13456 44648, 13459 44648, 13461 44646, 15461 44643, 15459 44648, 15463 44648, 15464 44646, 15461 44649, 15461 44651, 15465 44654, 15460 44655, 15461 44657, 15463 44661, 15465 44665, 15465 44665, 15465 44667, 15469 44670, 15474 44672, 15476 44668, 15472 44672, 15473 44674, 15475 44678, 15477 44679, -3804 12302, -3802 12305, -3803 13305, -3802 13300, -3806 13296, -3807 13299, -3804 13304, -3802 13301, -3799 13305, -3799 13306, -3794 18306, -3799 18310, -3797 18315, -3800 18315, -3797 18316, -3799 18318, -3794 18323, -3793 18326, -3789 18325, -3784 18324, -3784 18325, -3782 18325, -3780 18325, -3779 18328, -3780 18329, -3781 18324, -3786 18328, -1786 18328, -1786 18333, -1782 18337, -1782 18338, -1779 18333, -1775 18338, -6775 18341, -6772 18343, -6774 18345, -6779 18345, -6777 18345, -6777 18347, -6777 18343, -6775 18347, -6780 18342, -6777 18345, -6776 18345, -6774 18340, -6774 18337, -6774 18337, -6778 18342, -6782 18342, -6785 18339, -6784 18340, -6779 22340, -6779 22339, -6776 22335, -6775 22330, -6775 22335, -6775 22339, -6770 22339, -6772 22344, -6767 22345, -6765 22341, -6765 22339, -6765 22339, -6765 22337, -6765 22340, -6760 22335, -6757 22335, -6762 22336, -6763 22338, -6765 22343, -6760 22338, -6758 22338, -6758 22338, -6756 22341, -6752 22345, -6752 22346, -6748 22343, -4748 22347, -4745 22347, -4750 22347, -4749 22348, -4747 22349, -4743 22352, -4738 22357, -4734 22362, -4736 22367, -4738 22362, 21338 41531, 21336 41531, 21332 41530, 21332 41530, 21335 41533, 21330 41533, 21331 41534, 21328 41536, 21330 41536, 21326 41541, 21330 41536, 21332 41539, 21336 41536, 21338 40536, 21336 40540, 21341 40538, 21343 40538, 21346 40538, 21348 40536, 21352 40536, 21355 40539, 21359 40543, 21361 40546, 21362 40550, 21357 40550, 21362 40551, 21361 40554, 21358 40555, 21358 40554, 21359 40554, 21363 40558, 21360 45558, 21364 45560, 21368 45557, 21372 45561, 21376 45560, 21379 45557, 22379 45553, 22384 45553, 22384 45556, 22388 45561, 22389 45561, 22390 45557, 22394 45561, 24394 45565, 22394 45562, 22399 45565, 22401 45562, 22400 45565, 22402 45568, 22402 45573, 22406 45577, 22408 45581, 22408 45585, 22406 45585, 22409 45586, 22411 45583, 22411 45579, 22411 45583, 22409 45583, 22404 45586, 22404 45586, 22406 45591, 22408 45591, 22408 45593, 22413 45593, 22415 45594, 22419 45595, 22419 45596, 22424 45591, 22427 45587, 22430 50587, 22430 50589, 22430 50589, 22432 50592, 22437 50594, 22437 50589, 22437 50594, 22441 50599, 22442 50594, 22447 50591, 22444 50588, 22444 50590, 22445 54590, 22445 54594, 22448 54599, 22450 54601, 22450 59601, 22446 59597, 22451 59600, 22451 59603, 22454 59604, 22459 59604, 22460 59609, 22459 59606, 22464 59607, 22465 59608, 22463 59609, 22460 59606, 22459 59605, 22459 59605, 22457 59609, 25457 59610, 25459 59615, 25464 59617, 25466 59618, 25469 59621, 25474 59616, 25478 59617, 25480 59614, 25484 59619, 25484 59620, 25488 59616, 25485 59618, 25489 59623, 25494 59627, 25499 59629, 148 2256, 152 2253, 152 2253, 154 2258, 159 2253, 160 2257, 159 2256, 163 2259, 161 3259, 163 3262, 163 3259, 165 3259, 170 3263, 170 3263, 174 3267, 169 3271, 174 3275, 174 3276, 174 3278, 177 3282, 181 3286, 183 3287, 186 3284, 187 3286, 189 3286, 193 3288, 194 3290, 193 6290, 195 6293, 200 6289, 197 6294, 196 6293, 197 6293, 201 6297, 202 6292, 200 6294, 204 6295, 209 6300, 214 6305, 217 6305, 218 6305, 213 6308, 214 6308, 218 6313, 218 6308, 216 6312, 215 6312, 213 6309, 214 6313, 219 6318, 222 6321, 226 6326, 224 6331, 222 6327, 41575 39716, 41574 39713, 41578 40713, 41582 40718, 41578 40721, 36578 40721, 36579 40723, 36584 40720, 36587 40725, 36592 43725, 36587 43725, 36584 43728, 36587 43733, 36592 43735, 36592 43734, 15291 11311, 15287 11316, 15288 11319, 15291 11319, 15296 11319, 15297 11320, 15298 13320, 38744 37650, 38745 37654, 38747 37659, 38746 37662, 38741 37663, 38739 37666, 38744 37666, 38747 37661, 38750 37666, 38750 37666, 38754 37671, 38755 37671, 38750 37673, 38750 37672, 38754 37677, 38756 37678, 38758 37680, 38760 37678, 38762 37683, 38762 37679, 38760 37679, 38765 37679, 38769 37678, 38774 40678, 38769 40683, 38774 40687, 38776 44687, 38780 44690, 38782 44694, 38782 44694, 38781 44699, 38784 44704, 38782 44699, 38777 44700, 38777 44700, 38777 44700, 38781 44703, 38785 44700, 38786 44700, 38788 44696, 38788 44696, 38788 44700, 38793 44702, 38795 44703, 38797 44707, 38802 44712, 38805 44712, 38809 44713, 38804 44710, 38808 44712, 38811 44713, 36811 44713, 36816 44708, 36815 44709, 36816 44709, 36818 44713, 36813 44716, 36814 48716, 36813 48721, 36817 48725, 36818 51725, 36820 51721, 36824 51724, 40824 51719, 40829 51716, 40832 51720, 40831 51723, 40834 51727, 40837 51728, 40842 51725, 40843 51725, 40838 51729, 40843 51734, 40848 51738, 40850 51742, 40851 51744, 40853 51747, 40856 51749, 40857 51750, 40859 51754, 40859 51750, 40863 51752, 40868 51755, 40864 51754, 40868 51754, 40871 51756, 40867 51756, 40865 51759, 40860 51761, 40857 51757, 40857 51762, 40854 51762, 40855 51764, 40859 51765, 40857 51761, 40854 51764, 40855 51765, 40857 51766, 40860 51761, 40861 51760, 40865 51761, 40865 51763, 40862 51768, 40861 51768, 40856 51772, 40852 51769, 40854 51771, 40854 51771, 40850 51776, 40854 51780, 40856 51782, 40854 51782, 43854 51782, 43856 52782, 43858 52785, 43861 52785, 43861 52780, 37514 26540, 37519 26535, 37522 26539, 37522 26544, 37524 26548, 37529 26548, 37534 26553, 37539 26548, 37542 26553, 37547 26548, 37551 26551, 37551 26554, 37550 26555, 37551 26557, 37548 26557, 37548 26557, 37551 26560, 37551 26563, 37554 26563, 37558 26568, 37562 26563, 37563 26565, 37567 26569, 41567 26569, 41571 26572, 41573 26577, 41573 26577, 41578 29577, 41573 29577, 41575 29580, 41575 29582, 46575 29582, 46571 29586, 45571 29587, 45574 29587, 45570 29587, 45575 29585, 45577 29582, 45573 29585, 45574 29588, 45574 29589, 45578 29589, 45580 29592, 45583 29595, 45584 29597, 45584 29602, 45586 29601, 45591 29604, 45587 29609, 45591 33609, 45595 36609, 45596 36611, 45601 36613, 45602 36608, 45606 36608, 45606 36612, 45606 36611, 45610 36614, 50610 36617, 50613 36613, 50616 36613, 50621 36609, 50626 36609, 50627 36610, 50627 36609, 50631 36610, 50626 36612, 50627 36614, 50628 36614, 50631 36612, 50629 36614, 50630 36618, 50634 36622, 46634 34622, 46634 35622, 46638 35626, 46638 35621, 46639 35624, 46641 35623, 46645 35624, 46647 35629, 46645 35634, 46650 35639, 46650 35644, 46651 35647, 46653 35651, 46657 35654, 46654 35659, 46659 35660, 46660 35661, 46664 35664, 46661 35667, 46664 35668, 46667 35667, 46669 35671, 46669 35667, 46672 35670, 46674 35675, 46676 35675, 47676 35672, 47678 35676, 47679 35677, 47679 35682, 47679 35681, 47679 35681, 47679 35686, 47674 35687, 47673 35687, 49673 35689, 49676 35693, 49679 35696, 49677 35696, 54677 35701, 54680 35703, 54676 35703, 54672 35705, 54672 35704, 54677 35707, 54678 34707, 54678 34707, 54681 34710, 54685 34712, 54690 34710, 54690 34711, 54687 34706, 54689 34706, 54694 34711, 54689 36711, 54689 36710, 54684 36711, 54687 38711, 54682 38714, 54682 38718, 54679 38718, 54681 38723, 54684 38724, 54689 38720, 54690 38721, 54694 38726, 54699 38730, 54701 38731, 54702 38728, 54704 38724, 52704 38723, 52704 38723, 52704 38725, 52704 38729, 52706 38730, 52708 38732, 52709 38733, 52713 38732, 52713 35732, 52715 35737, 52714 35741, 52714 35743, 52715 35746, 52715 35749, 52710 35749, 52712 39749, 52715 39753, 52718 39752, 52723 39753, 52722 39757, 52718 39760, 52718 40760, 47718 40761, 47719 40765, 47724 40765, 47724 40765, 47724 40770, 47728 40773, 47730 40776, 47735 40781, 47733 40777, 50733 40781, 51733 40783, 51735 40786, 51736 40790, 51739 40788, 51743 41788, 51741 41787, 51741 41789, 51741 41789, 51738 41793, 51733 41793, 52733 41794, 52737 41795, 52740 41794, 52744 41793, 52748 41789, 52749 41789, 52747 41789, 52752 41786, 52755 41790, 52755 41791, 52760 41796, 52756 42796, 52751 42797, 52754 42798, 52758 42795, 52759 42794, 52764 42797, 52768 42801, 52768 42801, 52771 42806, 52776 42810, 52776 42809, 52773 42811, 52776 42811, 52772 42812, 52773 42815, 52769 42815, 52768 42816, 52769 42821, 52773 42821, 52773 42821, 52777 42819, 52781 42815, 52781 42816, 52782 42819, 52778 42822, 52776 42822, 52779 42826, 52782 42827, 52783 42831, 52778 42833, 52782 42836, 54782 42839, 54782 42844, 2137 11205, 2142 11207, 2139 11208, 2142 11213, 2144 11217, 2149 11215, 2147 11217, 2147 11217, 2152 11222, 2152 11225, 2155 11229, 2159 13229, 2164 13232, 2169 13235, 2173 13236, 2169 13233, 2170 13237, 2173 13241, 2175 13243, 2170 13238, 2170 13239, 2175 13239, 2177 13238, 2179 13239, 2179 13238, 2181 13233, 2181 13230, 2182 13230, 2179 13230, 2179 13235, 2182 13235, 2183 10235, 2178 10237, 2179 10236, 2182 10239, 2187 10241, 2184 10244, 6184 10244, 6186 10248, 6184 10246, 6185 10247, 6187 10250, 6192 10248, 6196 10248, 6196 10251, 6194 10251, 6194 10256, 6197 10260, 6196 10264, 6197 9264, 6197 9264, 6197 9268, 6201 9273, 6206 9276, 6201 9272, 6203 9272, 6205 9269, 6210 9272, 6206 9274, 6206 9279, 6203 9283, 6203 9285, 6203 9290, 6208 9285, 6208 9281, 6204 9285, 6202 9289, 6204 9292, 6200 9294, 7200 9297, 7202 9301, 7203 9301, 7207 9302, 7211 9302, 7211 9303, 8211 9306, 8216 10306, 8220 10310, 8224 10312, 8228 10317, 8233 10317, 8237 10322, 8239 10322, 8239 10327, 8235 10330, 8235 10331, 8239 10329, 8240 10332, 8240 10334, 8236 10334, 11236 10336, 11238 10337, 11243 10341, 14243 10342, 14242 10342, 14239 10343, 14240 10341, 14239 10343, 14244 10343, 14248 10343, 14252 10343, 14252 10343, 14253 10341, 14256 10341, 14258 10338, 14258 10336, 14254 10340, 14257 10344, 14261 10346, 14264 10351, 11150 3163, 11155 3167, 11156 3166, 11156 3169, 11160 3171, 11163 3176, 11164 3179, 11164 3180, 11168 3183, 11168 3185, 11173 3189, 11178 3184, 11180 3183, 11178 3185, 11181 3187, 11176 3186, 52778 42822, 52780 42826, 52779 42826, 52784 42821, 52785 42826, 52786 42827, 52791 42830, 52791 42827, 56791 42832, 56788 42833, 56788 42836, 56791 42840, 56791 42839, 56787 42842, 56788 42847, 51788 42848, 51790 42850, 51792 42851, 51796 42846, 51798 42846, 51803 42850, 53803 42853, 53808 42853, 53811 42856, 53814 42854, 53819 42850, 53819 42852, 53820 42857, 53824 42860, 53825 42858, 53828 42862, 53827 42864, 53828 42864, 53828 42868, 53832 42872, 53837 42877, 53841 42877, 53843 42876, 53843 42880, 53843 42883, 53843 42888, 53838 42892, 53838 42893, 53838 44893, 53835 44893, 53837 44897, 53840 44901, 53844 44901, 53846 44904, 53846 44908, 53847 44909, 53852 44907, 53855 44908, 53860 44910, 53858 44911, 53863 44913, 53858 44917, 53860 44920, 53865 44920, 53870 44922, 53869 43922, 53871 43925, 53871 43923, 53869 43923, 53864 43922, 53862 43927, 53866 43932, 53871 43934, 53876 43937, 53876 43936, 53876 43936, 53877 43934, 53879 43932, 53880 43928, 53885 43931, 55885 43933, 55885 43929, 55881 43933, 55883 43933, 55886 43932, 55883 43932, 55884 43933, 55885 45933, 55885 45937, 55885 45940, 55886 45945, 55886 45945, 55888 45950, 55884 45952, 55885 45956, 55890 45960, 55892 45961, 55896 45957, 55894 45958, 55899 45954, 55895 45958, 55898 45960, 55894 45959, 55899 45963, 55901 45965, 55901 45965, 55896 45966, 55900 45961, 55895 49961, 55898 47961, 55896 47960, 55900 47964, 55903 47968, 55903 47971, 55903 47974, 55898 47977, 55900 47973, 55896 47978, 55897 47979, 55893 47980, 55898 47983, 55901 47988, 55904 47987, 55899 47991, 55901 47993, 55906 47996, 55906 47997, 55907 48001, 55904 48005, 55904 48007, 55909 48004, 55912 48002, 55917 48003, 55913 47998, 55908 48002, 55912 48007, 55916 48004, 55920 48004, 55916 48004, 55921 48004, 55923 48007, 55923 48011, 55926 48011, 55921 48014, 55924 48009, 55929 48013, 55930 48012, 55930 48012, 55932 48016, 55927 48016, 55927 48020, 54927 48018, 54924 48022, 54924 44022, 54928 44017, 54931 44016, 54934 44020, 55934 44021, 55937 44021, 55938 44024, 55939 44026, 55938 44024, 55941 44019, 55946 44022, 55947 44026, 55949 44027, 55952 44028, 55955 44024, 55958 44027, 53869 43923, 53873 43925, 52873 43925, 53873 43927, 53878 43927, 53883 43927, 53882 43931, 53884 43935, 53888 43940, 53886 43941, 53881 43938, 53881 43941, 53879 43943, 53880 43942, 53881 43946, 53882 43951, 53883 43952, 53886 45952, 53886 45953, 53884 45957, 53885 45958, 53880 45960, 53882 45957, 53887 45962, 53887 45962, 53888 45961, 53888 48961, 53888 48966, 53893 48966, 53894 48968, 53899 48969, 49899 48966, 49904 48969, 49908 48971, 49904 48971, 49906 48975, 49903 48971, 49906 48974, 54906 48975, 54906 48975, 54906 48979, 54911 48983, 54909 48979, 54912 48979, 54908 48975, 54911 48977, 54913 48979, 54917 48982, 54922 48982, 54925 48985, 54920 48988, 54923 48988, 56923 48988, 56928 48990, 56926 48985, 56931 48984, 56934 48983, 56934 48981, 56938 48983, 56939 48985, 56939 48986, 61939 48988, 61939 48984, 61936 51984, 61937 51985, 61937 51988, 61937 51988, 61933 51990, 5331 23399, 5333 23399, 5335 23394, 5339 23396, 5342 23399, 5347 27399, 5347 27401, 5352 27402, 5357 27403, 5358 27406, 6358 27409, 6362 27411, 6363 27410, 6366 27406, 6368 26406, 6373 26406, 6373 26406, 6374 26409, 6372 26409, 6377 26410, 6382 26415, 6387 26417, 6389 26418, 6390 26423, 6392 26423, 6393 26428, 6395 30428, 6392 30433, 6392 30436, 6392 30434, 6396 30438, 6396 30441, 6396 30445, 6398 30446, 6400 30443, 6401 30440, 6406 30439, 6407 30439, 6402 30439, 6407 30444, 6406 30447, 6407 30451, 6411 30451, 6413 30451, 6414 30452, 6419 30450, 6423 30454, 6420 30452, 6419 30448, 6420 30453, 6422 30455, 6427 30460, 6428 30460, 6427 30462, 6428 30462, 6428 34462, 6429 34463, 6434 39463, 6436 39466, 6436 39471, 6441 39474, 6445 39471, 6446 39472, 6451 39477, 6453 39480, 6454 39485, 6454 39483, 6454 39480, 8454 39480, 8458 39482, 8462 39484, 10462 39486, 10457 39486, 10458 39488, 10462 39488, 10465 39488, 10470 39490, 10475 39486, 10477 39488, 10477 39490, 10478 39492, 10479 39496, 10477 39498, 10482 39503, 10478 39505, 10481 39510, 10482 39514, 10477 39512, 10482 39517, 10483 39520, 10483 39520, 10487 39525, 10489 39526, 10492 39527, 10492 39524, 10495 39524, 10498 44524, 10493 44523, 10493 44528, 10494 44524, 10499 44529, 10501 44529, 10504 44531, 10502 44535, 10504 44539, 10508 44539, 10513 44536, 13513 44540, 13515 44537, 13512 44539, 13509 44544, 13513 44547, 13517 44552, 13519 44553, 13524 44554, 13527 42554, 13522 42555, 13524 42557, 13527 42556, 13531 42561, 13531 42562, 13526 42563, 13527 42563, 13527 42566, 13522 42568, 13525 42571, 15525 42573, 15525 42576, 15526 42581, 15531 42581, 15532 42586, 15534 42588, 15534 42592, 15533 42591, 15533 42596, 15532 42591, 15532 42587, 15535 42587, 15538 47587, 15534 47587, 15537 47591, 15536 47594, 15538 47598, 11538 47594, 11535 47594, 11531 47594, 11535 47596, 11535 47596, 11535 47597, 11539 47602, 11540 47607, 11540 47607, 11540 47609, 11543 47613, 11546 47617, 14546 47618, 14541 47614, 14539 47614, 14539 47618, 14537 50618, 14539 50623, 14541 50623, 14542 50627, 14540 50627, 14539 50623, 25601 26544, 25601 26545, 25601 26548, 25596 26546, 25601 26547, 25598 26548, 25599 26547, 25600 26547, 25595 26548, 25590 26546, 25595 26549, 25597 26548, 25598 26548, 25601 26545, 25596 26548, 25594 26553, 25595 26552, 25599 26553, 25598 26554, 25596 26555, 25592 26554, 25596 26558, 25599 26554, 25600 26556, 25595 26559, 25600 22559, 25601 22561, 25606 22563, 25607 22562, 25608 22566, 25607 22563, 25607 22568, 30607 22573, 30612 22575, 30612 22579, 30611 22579, 30611 22580, 30611 22585, 30607 22585, 30612 22587, 30612 22588, 30615 22583, 30615 22585, 30618 22581, 30621 22581, 30623 22584, 30623 22589, 30628 22594, 30630 22597, 30631 22602, 30628 22607, 30630 22610, 30631 22611, 30631 22608, 30629 22610, 30634 22612, 30635 22612, 30638 22616, 30643 17616, 30644 17618, 30649 17618, 30653 17619, 30656 17614, 30657 17611, 30660 17615, 30655 17614, 30656 17610, 30656 17611, 30661 17610, 30662 17615, 30660 17620, 30661 17620, 30666 17623, 30667 17625, 30667 17624, 30669 17625, 30673 17628, 30675 17628, 30675 17628, 30680 17631, 30677 17636, 30677 17639, 30680 17644, 30683 17647, 30688 17643, 30693 17645, 30698 19645, 30701 19644, 30702 19644, 30698 19649, 30700 19647, 30701 19649, 30704 19650, 30705 19653, 30701 19655, 30706 19652, 30708 19656, 30711 19657, 30711 19659, 30711 19659, 30714 19661, 30710 19662, 30707 19664, 30702 19666, 30703 19667, 30708 19668, 30713 19667, 30709 19671, 30706 19674, 30710 19676, 30711 19677, 30713 19677, 30713 19678, 30715 19682, 30720 19686, 30725 20686, 30723 20690, 30727 20695, 30728 20697, 30731 20699, 30730 20694, 30732 20696, 30735 20698, 30738 20696, 30738 20695, 30742 20698, 30743 20699, 30743 20701, 30748 20704, 30749 20706, 30752 20705, 30753 20702, 30755 24702, 30751 24705, 30750 24707, 30748 24708, 30749 29708, 30749 29709, 30751 29711, 30754 29716, 30759 29716, 30762 34716, 30762 34720, 30765 34720, 30761 34717, 30761 34721, 30765 34721, 30760 34721, 30759 34725, 30762 34730, 30760 34730, 30765 34731, 30765 34731, 30766 34731, 30761 34733, 30761 34736, 30764 34738, 30759 34739, 30763 34740, 30761 34740, 30764 34742, 30759 34737, 30762 34739, 30764 34741, 30762 34740, 30767 34737, 32767 34741, 32770 34741, 32767 34744, 32767 34746, 32770 34751, 32774 34755, 32774 34756, 32779 34753, 32784 34755, 32785 33755, 32785 33750, 36785 33753, 36785 33758, 36788 33760, 36789 33759, 36789 33762, 36793 33758, 36798 33758, 36803 33760, 36803 33762, 36803 33766, 36804 33769, 36804 33769, 36808 33774, 33808 33776, 33808 33781, 33811 33781, 33816 33784, 33816 33789, 33820 33786, 33823 33788, 33828 33785, 33824 33785, 33826 33787, 33824 33788, 33828 33791, 33825 33796, 33829 33799, 33830 33802, 33831 33803, 33835 33805, 33835 33805, 33838 33809, 33841 33813, 33844 33809, 33849 33814, 33847 32814, 33849 32812, 33851 32816, 33853 32819, 33851 32822, 33851 32826, 33849 32826, 33849 32830, 33852 32835, 33856 32840, 33859 32837, 33858 32832, 33861 32833, 33862 32836, 33859 32838, 33859 32834, 33857 32834, 33859 32834, 33857 32838, 33861 32833, 33861 32837, 33864 32840, 33866 32841, 33866 32843, 33868 32841, 33871 32839, 33874 32844, 33876 37844, 33881 37849, 33883 37854, 33883 37859, 33888 37860, 33893 37864, 33898 37864, 33895 37867, 33896 38867, 33898 38863, 28898 38868, 28901 39868, 33901 39873, 33898 39875, 33900 39879, 33904 39877, 33904 39879, 33909 39883, 33914 39888, 33910 39891, 33910 39892, 33907 39894, 33911 39899, 33913 39900, 33910 39904, 33914 39905, 33917 39906, 33917 39906, 33917 39906, 33912 39911, 33912 39908, 33916 39907, 33914 39910, 33918 39913, 33922 39913, 33924 39916, 33925 39920, 33930 39920, 33933 39922, 33934 39923, 33937 39919, 33938 39916, 33936 39913, 35936 39918, 35933 39919, 35937 39921, 35941 39924, 35941 39919, 35942 39915, 35946 39920, 35946 39915, 35946 39912, 35947 39908, 35947 39912, 35947 39916, 35952 39919, 35957 39921, 38957 39920, 38962 39925, 38964 39924, 38964 39924, 38969 39926, 38969 39928, 38972 39932, 38977 39932, 38975 39932, 38979 39935, 38982 39938, 38986 39940, 38984 39943, 38985 39946, 38987 39947, 38989 39949, 38994 41949, 38990 41954, 38991 41958, 38994 41962, 38994 41966, 38994 41969, 38995 41974, 38999 41974, 38999 41974, 38996 41978, 38996 41983, 38999 41983, 39001 41986, 38996 41984, 39000 41989, 39000 41988, 5336 23410, 5332 23410, 5327 23407, 9327 23408, 12327 23412, 12327 23412, 12324 23410, 13324 23415, 13327 23420, 13328 23416, 13324 23418, 13329 23423, 13330 23426, 13331 23429, 13335 23426, 13339 23428, 23493 35553, 23492 35548, 23496 35550, 23501 35552, 23497 35553, 21497 35557, 21492 35560, 21494 35562, 21494 35560, 21496 35563, 21496 35568, 21496 35570, 21501 35570, 21504 35566, 21504 35571, 17504 35572, 17508 35577, 17509 35578, 17513 35582, 17514 35587, 17515 35592, 18515 35595, 18516 35596, 18517 35598, 18515 35600, 16515 35605, 16515 37605, 16515 37606, 16513 37608, 16515 37613, 16516 37615, 16520 37620, 16524 34620, 16526 34617, 16530 34619, 16530 34624, 16535 34628, 16537 34631, 16540 34632, 16541 34634, 16541 34635, 16544 34632, 16544 34637, 16546 34642, 16549 38642, 16549 38644, 16545 38649, 16545 38644, 16542 38644, 16545 38644, 16544 38645, 16548 38650, 16543 38653, 16543 38649, 18543 38652, 18546 38652, 18546 38657, 18546 38660, 18551 38655, 18549 38655, 18552 38660, 18549 38662, 23549 38667, 23546 38668, 23550 38672, 23550 38674, 28550 38676, 28551 38673, 28551 38677, 28547 38673, 28551 38674, 28556 38674, 28559 38678, 28562 38673, 28564 38678, 28564 38673, 28563 38673, 28566 38675, 28571 38675, 38781 44703, 38782 44699, 38780 44702, 38785 44704, 38787 44704, 38783 44705, 38784 44700, 38788 44695, 38791 44696, 38796 44696, 38801 44692, 38801 44697, 38805 44701, 38810 44701, 38808 44701, 38808 44704, 38805 44706, 38805 44710, 38804 44711, 38809 48711, 38810 48711, 38808 48711, 38812 48716, 38812 48713, 38812 48715, 38812 48715, 38808 48711, 38804 48714, 38805 48710, 38807 48715, 38812 48715, 38807 48713, 38811 48714, 38811 48714, 38816 48711, 38817 48707, 38818 48707, 38818 48708, 38822 48708, 38824 48713, 38822 48714, 38820 48718, 38824 48720, 38824 48723, 38829 48726, 38830 48731, 38834 48729, 38832 48734, 38833 48730, 38834 48728, 38831 48732, 8433 35536, 8433 35541, 4433 35536, 4436 35541, 4440 35541, 4441 35537, 4445 35539, 4444 35534, 4447 35531, 4451 35531, 4455 35534, 4460 35534, 4461 39534, 4462 39535, 4463 39535, 4466 39535, 4470 39535, 4472 39538, 4467 39538, 4467 39536, 4471 39536, 4473 39541, 4468 39542, 4472 39543, 4475 39544, 4478 39544, 4482 39547, 4487 39552, 4485 39550, 4486 39551, 4486 39553, 4486 39555, 4488 39557, 4488 39558, 4489 39555, 4485 39557, 4488 39558, 4492 39560, 4495 39561, 4500 39565, 4496 39566, -4747 22349, -4750 22349, -4746 22352, -4742 22355, -4738 22360, -4739 22362, -4737 22365, -4732 22363, -4728 25363, -4728 25364, -4723 25364, -4725 25364, -4725 25365, -6725 25364, -6727 25369, -6728 25369, -6725 25369, -6729 25368, -6728 27368, -6725 27370, -6721 27371, -3721 27367, -3717 27372, -3718 27375, -3716 27370, -3715 27373, -3714 27373, -3712 27376, -3709 27374, -3710 27375, -3710 27374, -3708 27379, -3706 27381, -3705 27386, -3704 27389, -3704 27393, -3703 32393, -3702 32396, -3702 32396, -3697 32395, -3697 32399, -3692 32403, -3692 32404, -3693 32408, -3693 32412, -3691 32414, -3691 32414, -3695 32414, -3690 32417, -3689 32422, -3684 32424, -3681 32429, -3679 32424, -3676 32428, -3671 32428, -3674 32431, -3671 32430, -3669 32430, -3674 33430, -3676 33432, -3674 33432, -3677 33432, -3677 33437, -3675 33438, -3674 33442, -3679 33444, 1321 33448, 1323 33445, 1327 33448, 1331 33443, 1328 33448, 1328 33443, 1329 33443, 1329 33444, 1334 33448, 1335 33453, 1340 33457, 1340 33454, 1345 33454, 1349 33458, 1348 33461, 1348 33459, 1344 33463, 1343 33466, 1348 33466, 1349 33467, 1345 33467, 1346 33466, 1350 33461, 1349 33464, 1354 33468, 1358 33472, 1363 33473, 1365 33472, 1367 33473, 1370 33476, 1371 33479, -2629 33482, -2631 33487, -2627 33490, -2630 34490, -2626 36490, -2623 36492, -2619 36492, -2622 36492, -2620 36496, -2622 36495, -2627 36495, -2625 36500, -2621 36503, -2626 36506, -2629 36510, -2624 36510, -2620 36510, -2620 36513, -2617 36518, -2622 36516, -2619 36514, -2617 36514, -2617 36512, -2615 36516, -2613 36516, -2613 36517, -2613 36515, -2613 36510, -2610 36511, -2607 36515, -2604 37515, -2604 37512, -2608 37509, -2605 37512, -2600 37516, -2597 37516, -2593 37514, -2595 37515, -2590 37519, -2595 37518, -2590 37523, -2590 37528, -2590 37530, -2592 37525, -2592 37520, -2589 36520, -2586 36521, -2587 36517, -2584 36518, -2582 36518, -2581 36520, -2577 36518, -2576 36522, -2576 35522, -2573 35523, -2575 35523, -2576 35528, -2576 35533, -2576 35536, -2576 35538, -2578 35541, -2582 35545, -2584 35546, -2585 35548, -2583 35544, -2583 35548, -2582 35547, -2578 35552, -2574 35554, -2569 35557, -2565 35559, -2563 35564, -2558 35564, -2555 35568, -2551 35568, -5551 36568, -5546 36568, -5542 36569, -5545 36569, -5543 36574, -5540 36569, -5541 36570, -5541 36572, -5541 36574, -5538 36579, -5535 36581, -5533 36585, -5530 36584, -5526 36579, -5524 38579, -5524 38580, -5524 38575, -5520 38575, -5516 38580, -5512 42580, -5508 42585, -5510 42587, -5510 42586, -5505 42586, -5508 42589, -2508 42593, -2509 42596, -2506 42598, -2504 42601, -2501 42602, -2501 42607, -2496 42612, -2499 42615, -2498 42620, -2500 42617, -2500 42620, -4500 42620, -4500 42624, -4500 42626, -4504 42623, -4507 42625, -4509 42628, -4513 42629, -4508 42629, -4505 42632, -4500 42628, -4499 42633, -4503 45633, -4501 45634, -4497 45635, -4494 45634, -4495 45632, -4493 45634, -4492 46634, -4489 46638, -4485 46633, -4481 46635, 21338 40536, 21343 40537, 21348 40538, 21348 40540, 21347 40540, 21348 40540, 21347 40540, 21346 40542, 21349 40547, 21350 40547, 21353 40544, 21353 40546, 21350 40549, 21353 40550, 21354 40550, 21355 40550, 21360 40550, 21361 40549, 21361 40554, 21359 40559, 21364 40564, 21366 40559, 21365 40559, 21366 40564, 25366 40568, 25367 40570, 25370 40570, 25373 45570, 25374 45571, 25374 45566, 25378 45568, 25383 42568, 25387 42564, 25391 42568, 25391 42572, 25395 42576, 25392 42576, 28392 42573, 28391 42574, 28387 42578, 28388 42580, 28391 42581, 31391 42582, 31387 42586, 31389 42586, 31392 42582, 31393 42583, 31394 42580, 29394 42584, 29398 42586, 29400 43586, 29404 43588, 29408 43589, 29409 43591, 29413 43596, 29415 43598, 29416 43599, 25416 43604, 25414 43599, 25417 43603, 25422 43606, 25420 43608, 25425 43603, 25428 43603, 25431 43606, 25436 42606, 25431 42608, 25434 42604, 25437 42609, 25438 47609, 25442 50609, 25443 50614, 25441 50618, 25446 50621, 25449 50625, 25446 50628, 25446 50630, 25447 50631, 25452 50636, 25452 50632, 25453 50634, 25453 50636, 25456 50637, 25460 50641, 25464 50645, 25465 50644, 25465 51644, 25469 51648, 25471 51653, 25475 51654, 25476 51657, 25477 51658, 26477 51662, 26477 51666, 26476 51669, 26478 51669, 26483 51665, 26485 55665, 26487 55668, 30487 55671, 30487 55674, 30491 55675, 30491 55672, 30493 55674, 30494 55674, 30495 55679, 30499 55679, 30503 55675, 30505 55680, 30502 55681, 30500 55676, 30496 55679, 30501 55680, 30502 55680, 30507 55685, 30503 55688, 30498 55689, 30502 55689, 30504 55691, 30508 55696, 30509 55697, 30508 55696, 30513 55697, 30518 55698, 30516 55703, 30516 55705, 30514 55705, 34514 55709, 34518 55712, 34522 55708, 34520 56708, 34521 56708, 34522 56710, 34519 56710, 34517 56705, 34521 59705, 34524 59710, 34524 59712, 34524 59717, 34528 59719, 34530 59721, 34535 59716, 34540 59719, 34540 59721, 34543 59721, 34548 59724, 34550 59725, 34554 63725, 34549 63730, 34551 63732, 34556 63730, 34558 63730, 34559 63725, 34558 63729, 34563 63734, 34560 63734, 37560 63729, 37563 63733, 37567 63728, 37571 63724, 37575 63722, 37580 63726, 37579 63722, 37581 63724, 37581 63726, 37582 63723, 37582 63724, 37581 63728, 37576 63729, 37576 63731, 37578 63729, 37583 63733, 37585 63736, 37588 63736, 37592 63741, 37594 63738, 37599 63735, 37602 63734, 37598 63735, 37598 63737, 37602 63737, 37603 63739, 37598 63739, 37593 63736, 37598 63737, 37603 63742, 37604 63737, 37601 63742, 37596 63744, 37600 63748, 37605 63749, 37607 63751, 37609 63756, 37609 63760, 37605 63761, 37605 63765, 37606 63765, 37610 63762, 37611 63766, 37606 63768, 37606 63768, 41606 63769, 41602 63765, 41601 63765, 41602 63770, 41598 63770, 41601 63770, 41603 63774, 41606 63772, 41610 63772, 41613 63776, 41616 63771, 41611 63767, 41614 63769, 41617 63764, 38617 63768, 38617 63772, 38620 63772, 35620 63773, 35620 63778, 35619 63779, 35620 63780, 35615 63779, 35617 63784, 35614 63786, 35615 63783, 35616 63779, 35620 63778, 35621 63780, 35626 63782, 35626 63784, 35631 63789, 35631 63784, 35628 63785, 35626 63786, 35631 63788, 35636 63791, 35640 63786, 35636 63787, 35636 63782, 35635 63781, 35640 63786, 35643 63790, 35646 63795, 35650 63797, 35649 63797, 35651 63801, 35655 63805, 35656 63808, 35656 63808, 35658 63808, 35657 63810, 35660 63814, 35660 63809, 35664 63809, 35659 67809, 35660 67812, 35662 67815, 35666 67812, 35662 67807, 35660 67807, 35663 67807, 35665 67812, 35668 67814, 35672 67818, 35671 67817, 35671 67820, 37671 67824, 37666 67824, 2277 13367, 2280 16367, 2276 16367, 2277 16366, 2281 16366, 2284 16366, 2289 16370, 2286 16370, 4286 16370, 4288 16375, 4292 16379, 4296 18379, 4297 18381, 9297 18385, 9298 18385, 9301 18386, 9305 18383, 9307 19383, 9310 19379, 8310 19384, 8314 19384, 38748 37655, 38751 37656, 38756 37657, 38759 37660, 38755 37665, 38755 37665, 38760 37667, 38765 37668, 38765 42668, 38770 42670, 38767 42672, 38772 42668, 38769 42663, 38770 42663, 38775 42658, 38773 42663, 38777 42665, 41777 42667, 41780 42669, 41783 42673, 41784 42671, 41781 42673, 41786 42676, 41783 42676, 41785 42676, 41782 42676, 41785 42679, 41786 42679, 41790 42680, 41794 42681, 41794 42679, 41795 42684, 41795 42680, 41798 42685, 41803 42689, 41806 42688, 41808 42689, 41806 42694, 41804 42696, 41807 42700, 41802 42701, 41804 42702, 41806 42704, 41811 42708, 41815 42709, 36815 42712, 36815 42708, 36812 42707, 36813 42709, 40813 42710, 40817 46710, 40818 46712, 40822 46712, 40820 46716, 40824 46721, 40827 46724, 40831 46728, 40829 46731, 40833 46731, 40835 46735, 40831 46737, 40832 46737, 36832 46742, 36832 46745, 36836 46748, 36833 46753, 36828 46752, 36824 46752, 36826 46755, 36821 46759, 36825 46762, 36825 46766, 36826 46770, 36824 46773, 36828 46776, 36833 46778, 36830 42778, 36835 42780, 36835 42781, 36840 42786)')));
+BEGIN;
+
+DELETE FROM t1 WHERE p = 3;
+UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
+UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
+
+ROLLBACK;
+
+connection control_purge;
+--echo # disable purge
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+
+connection default;
+DELETE FROM t1 WHERE p = 3;
+
+UPDATE t1 SET g = ST_linefromtext('linestring(448 -689,453 -684,451 -679,453 -677,458 -681,463 -681,468 -678,470 -676,470 -678,468 -675,472 -675,472 -675,474 -674,479 -676,477 -675,473 -676,475 1324,479 1319,484 1322,483 1323,486 1323,491 1328,492 1325,496 1325,498 1325,501 1330,498 1331,500 1331,504 1330,508 1329,512 1332,513 1337,518 1339,518 1339,513 1344,513 1344,512 1346,514 1351,515 1353,519 1358,518 1362,522 1365,525 1360,526 1362,527 1362,528 1367,525 1371,528 1366,532 1369,536 1374,539 1377,543 1379,539 1381,541 1382,543 1383,546 1388,549 1393,554 1393,554 1395,554 1392,550 1394,550 1392,546 1394,549 1397,550 1393,549 1394,554 1390,554 1391,549 1396,551 1396,547 1400,547 1402,551 1407,554 1412,554 1415,558 1418,463 -681,465 -677,465 -675,470 -670,470 -665,470 -660,470 -659,473 -656,476 -656,481 -655,482 -652,486 -654,486 -652,486 -648,491 -646,490 -651,494 -646,493 -644,493 -644,490 -644,491 2356,495 2359,495 2364,500 2359,503 5359,504 5364,509 5368,504 5367,499 5368,498 5371,498 5369,500 5370,504 5370,508 5370,511 5370,507 5374,508 5378,511 5382,507 5387,509 5389,512 5388,515 5393,520 5396,517 5397,517 5402,515 5404,520 5402,521 5405,525 5405,526 5408,530 7408,535 7413,533 7415,529 7412,532 7416,4532 7416,4534 7421,4533 7417,4536 7413,4536 7418,4540 3418,4545 3418,4549 3415,4551 3419,4554 3421,4559 3423,4559 3426,4557 3424,4561 3428,4558 3428,4563 3431,4565 3435,4569 3439,4569 3439,4569 3444,4567 3444,4572 3446,4577 3447,4581 3444,4581 3448,4584 3448,4579 3447,4580 3450,4583 3449,4583 3453,4587 3455,4588 3458,4593 3463,4598 3465,4601 3468,4598 3464,4598 3460,4593 5460,4595 5461,4600 5464,4600 5465,4601 5466,4606 5466,4608 5466,4605 5464,4608 5467,4607 5468,4609 5465,4614 5461,4618 5463,4621 5467,4623 5470,4622 5470,4622 5470,4625 6470,4627 6471,4627 6472,4627 6473,6627 6474,6625 6474,6628 6477,6633 6481,6633 6480,6637 6475,7637 6479,7638 6482,7643 6487,7644 6492,7647 6492,7648 6495,7646 6498,7650 6499,7646 6494,7644 6499,7644 6497,7644 6499,7647 6502,7649 6504,7650 6501,7647 6503,7649 6504,7650 6508,7651 6503,7652 6508,7655 6508,7650 6511,7655 6515,7658 6513,7663 6513,7665 6514,7669 6512,7667 6510,7664 6510,472 -675,477 -670,479 -666,482 -663,484 -668,484 -666,485 -664,481 -664,479 -659,482 -659,484 -658,483 -659,488 2341,493 2339,489 2338,491 2342,491 2346,494 2346,490 2348,493 2348,498 2349,498 2350,499 2349,502 2350,503 2348,506 2348,506 2348,507 2353,507 2355,504 2359,504 2364,504 2361,499 2365,502 2360,502 2358,503 2357,504 2353,504 2357,500 2356,497 2355,498 2355,500 2359,502 2361,505 2364,508 2364,506 2368,506 2370,504 2373,499 2373,496 2372,493 2377,497 2380,495 2383,496 7383,493 7386,497 7391,494 7387,495 7389,498 7392,498 7392,495 7395,493 7398,498 7401,498 7403,503 7400,498 8400,501 8401,503 8401,503 8401,501 10401,496 10396,491 10401,492 10399,493 10403,496 10403,491 10403,493 10407,489 10410,493 10407,489 10403,498 7403,497 7399,496 7403,500 7405,500 7407,503 7411,508 7415,511 7415,511 7420,515 7420,520 7423,523 7423,520 7427,523 7427,523 7427,522 7432,525 4432,527 4434,530 4437,534 4441,529 4446,529 4441,534 4436,537 4436,535 4437,532 4437,534 4432,535 4429,538 4430,542 4427,542 4431,538 4431,541 4431,541 4433,543 4433,545 4432,549 4428,552 4426,556 4427,557 4423,560 4427,561 4428,558 4430,559 4434,559 4432,561 4434,561 4437,563 4435,559 4430,561 4435,4561 4437,4566 4441,4568 4446,4568 4450,4569 4455,4565 4458,4561 4463,4561 9463,4564 9463,4565 9461,9565 9463,9560 9467,9560 9466,9555 9469,9555 9471,9559 9469,9557 9473,9553 9478,9555 9480,9557 9481,9557 9481,9557 9483,9562 9487,9558 9487,9558 9490,9561 9493,9562 9493,9557 9493,9560 9496,9555 9501,9553 9503,9553 9506,9557 9510,9558 9511,9561 9514,9563 9512,9568 9514,9567 9514,9567 13514,9570 13517,9566 13521,9571 13521,9571 13526,9573 13521,9571 13521,9576 10521,9580 10526,9582 10525,9584 10528,9584 10531,9584 10533,9589 10533,9588 10537,9588 10541,9589 10542,9593 10544,9595 10540,9597 10541,9600 10545,9601 15545,9603 15549,9605 15553,9601 15558,9601 15553,9605 15551,9605 15550,9605 15554,9607 15556,9605 15556,9604 15561,9607 15559,9603 15559,9603 15562,9604 15563,9608 15566,9612 15570,9617 15565,9622 15568,9627 15566,9628 15564,9629 15564,9633 15569,9636 15569,9634 15571,9634 15572,9636 15574,9634 15570,9629 15570,9631 15567,9629 15570,9626 15574,9626 15575,498 7401,502 7401,506 7397,506 7395,502 7398,497 7401,502 7402,505 7397,508 7400,504 7404,3504 7409,3505 7405,3508 7410,3511 7413,3511 7416,3511 7419,3511 7419,3513 7421,3517 7424,3519 7426,3520 11426,3523 11421,3527 11418,3530 11415,3530 11416,3533 11418,7533 11415,7531 11415,7531 11417,7536 11420,7541 11424,7543 11425,7543 11427,7543 11429,7540 11429,7542 11425,7541 11420,7542 11421,7542 11422,7540 11424,7540 11423,7543 11422,7546 11426,7550 11431,7553 11436,7555 16436,7553 16438,7558 16438,7559 16438,7560 16439,7565 16437,7560 16435,7563 16435,7566 16440,7566 16444,7564 16447,7559 16443,7561 16443,7566 16448,7570 16451,7574 16456,7578 16459,12578 16459,12578 20459,12577 20456,12581 20454,12585 20456,12585 20456,12585 20456,12583 20456,12579 20459,12580 20461,12580 20462,12580 20460,12585 20465,12586 20467,12590 20470,12590 20470,12589 20471,12584 20471,12589 20471,9589 20472,9594 20472,9595 20472,9596 20477,9598 20482,9603 20480,9608 20484,9613 20484,9610 20486,9608 20488,9608 20489,9610 20489,9614 20486,9619 20481,9620 20481,9618 21481,9621 21483,9626 21483,9628 21485,9623 21487,9622 21490,9626 21493,9621 21495,9626 21498,9622 21499,9624 21504,9625 21499,9629 21501,9633 21498,9637 21495,9639 21498,9644 21501,9557 9481,9560 9485,9561 9490,9563 9488,9560 9486,9558 9488,9561 9492,9563 9495,9567 9492,9567 9488,9564 9490,9559 9495,9559 9498,9557 9502,9562 9506,9564 9509,9569 9512,9569 9516,9569 9518,9569 9515,9571 9513,9571 9512,9573 9513,9578 9516,9581 9516,9585 11516,9585 11521,9590 10521,9586 10524,9589 10529,9589 10527,9589 10527,9594 10532,9594 10534,9598 10536,9598 10540,9600 10542,9604 10538,9607 10538,9609 10543,9613 10538,9613 10533,9613 10537,9610 10537,9614 10542,9609 10542,9610 10543,9610 10548,9611 10553,9616 7553,9620 7553,9621 7557,9618 7559,9618 7554,9622 7557,9622 7561,9622 7556,9622 7560,9619 7560,9620 7565,9622 7563,9627 7566,9630 7570,9630 7571,9632 7573,9637 7576,9639 7578,9640 7576,9640 7579,9640 7575,9642 7570,9646 7570,9651 7574,9653 7577,9652 7572,9653 7576,9653 7576,9651 7581,9656 7585,9660 7586,9659 7591,9657 7594,9661 7598,9664 7602,9668 12602,9673 12604,9676 12606,9679 12602,9682 12605,9677 12610,9674 12606,9674 12601,9674 12603,9672 9603,9668 9605,9671 9606,9668 9611,9668 9606,9671 9611,9675 9615,9677 9620,9678 9622,9679 9624,9684 9626,9685 9627,9685 9622,9685 9626,9689 9628,9694 9633,9699 9637,9699 9637,9704 9636,9708 9637,9709 9638,9707 9639,9705 9642,9707 9647,9710 9649,9711 9653,9716 9649,9716 9648,9720 9650,9721 9648,9723 9648,9726 4648,12726 4653,12731 4655,12734 4660,12730 4661,12733 4664,12733 4665,12735 4670,12737 4674,12741 4674,12738 4675,12740 4675,12737 4675,12742 4678,12743 4681,12746 4677,12751 4675,559 4430,563 4430,565 4435,566 4440,561 4445,562 4447,564 4450,561 4453,563 4453,561 4458,561 4458,562 4453,566 4454,571 4458,571 4460,574 4461,574 4464,579 4466,579 4470,582 4468,586 4470,590 4468,593 4468,594 4470,596 4474,591 4475,591 4480,594 4482,597 4486,593 4486,595 4486,598 4490,600 4492,3600 4497,3598 4497,3598 4494,3599 4493,3600 4497,3600 4494,3604 4498,3604 5498,3600 5497,3602 5493,3602 10493,8602 10498,8606 10494,8605 10495,8606 10496,8605 10500,8605 10500,8603 10499,8601 10502,8602 10505,8603 10501,8608 10503,8608 10508,8609 10503,8610 10505,8613 10504,8615 10506,8616 10508,8612 10513,8613 10517,8615 10520,8617 10521,8621 10524,8624 10524,8624 10524,8624 10519,8625 10514,8626 10519,502 7402,503 7399,506 7404,543 1379,548 1379,550 1380,553 1379,558 1376,556 1376,558 1372,559 1372,560 1377,565 1374,568 1375,568 1379,572 1382,570 1384,575 1386,576 1389,576 1394,579 1398,583 1403,586 1401,586 1401,591 1400,593 1402,598 1407,601 1412,546 1394,550 1396,553 1396,555 1394,4584 3448,4585 3450,4583 3450,4588 3451,4590 3449,4595 3449,4599 3454,4603 454,5603 458,5604 458,5605 453,5610 457,5614 459,5619 463,5621 466,5618 466,5623 465,5627 466,5625 471,5626 476,5630 479,5635 484,9635 488,9639 488,9641 483,9644 484,9649 484,5649 488,5649 492,5651 497,5656 497,5661 499,5665 504,5666 500,5666 497,5666 499,5666 499,5666 501,5670 502,5670 504,5670 507,5673 502,5677 506,4677 507,4682 509,4682 511,3682 510,3679 514,3683 510,3686 515,3684 518,3686 522,3689 527,3690 527,3688 529,3690 533,3692 530,3691 532,3695 529,3696 529,3701 533,3701 535,3699 540,9610 10543,9612 10545,9615 10548,9617 10548,9619 10550,9624 10548,9627 10549,9625 10553,10625 10553,10626 10555,500 7407,500 7407,500 7411,505 7413,505 7411,502 7415,504 7415,508 7411,511 7411,506 7412,506 7410,3506 7411,3507 7415,3509 7417,3511 7417,3513 7418,3516 7422,3518 7422,3518 7426,3513 7430,3515 7435,3520 7435,3521 7437,3526 9437,3526 9434,6526 9437,6526 9438,6526 9438,6527 9441,6528 9439,6523 9441,6518 9445,6522 9446,6526 9447,6529 9451,6529 9455,6530 9459,6532 9457,3532 9460,3536 9461,3537 9466,3541 9466,3544 9466,3546 9468,3549 9467,3553 9470,3551 9470,3551 9474,3552 9473,3547 9473,3547 9473,3547 9476,3552 9481,3553 9486,3555 9490,3556 9491,3559 9495,3560 9493,3563 9494,3563 9494,3565 9495,3565 10495,3568 10496,3573 10501,3574 10501,3576 10502,3578 10503,3578 10504,3580 10508,7580 10505,7578 10508,7578 10511,7578 10508,7581 10508,7582 10511,7577 10510,7577 10514,7573 10516,7578 10520,7580 10525,7581 10530,7585 10532,7590 10535,7594 10540,12594 10540,12591 10545,12595 10548,12595 10543,12597 10547,12597 10542,12595 10545,12595 10546,12600 10550,12605 10550,12606 10546,12604 10548,12605 12548,12605 12546,12607 12548,7607 12552,7611 12557,7608 12557,7608 12553,7611 12553,7610 15553,7608 15550,7610 15551,7607 14551,7607 14556,7606 14561,7602 14561,7602 14566,7601 14565,7606 14565,7605 14570,7608 14568,7609 14571,7613 14572,7614 14572,7616 14574,7613 14573,7615 14570,7618 14570,7615 14574,7617 14575,7614 14578,7616 14582,7617 14584,7617 14584,7618 14589,7622 14590,7619 14592,7624 14593,7628 14596,7632 14601,7627 14601,7629 14603,7629 14603,7630 14608,7631 14611,7626 14611,7628 14611,7628 14616,7624 14617,7619 14618,7624 14618,7626 16618,10626 16620,10624 16620,10629 16619,10633 16624,10636 16624,10638 16624,10643 16624,7643 16625,7643 16630,7643 16625,7647 16629,7648 16628,7649 16633,7650 16633,7650 16634,7645 16635,7646 16632,7642 16635,7643 16635,7643 16630,7638 16634,7640 21634,7645 21633,7650 21634,7651 21639,7652 21641,7655 21636,7651 21640,7654 21635,7655 21637,7660 21640,7656 21643,7661 21644,7663 21645,7667 21642,7669 21644,7674 21645,7674 21649,7677 21647,7672 22647,7672 22650,7667 22650,7667 22647,7671 22646,7672 22648,7673 22651,11673 22653,11672 22654,11670 22652,11671 22656,11673 22656,11674 22654,11678 22658,11678 22656,11675 22659,11680 22659,11685 22664,11687 22659,11687 22664,11687 22664,11692 22669,11696 22673,11701 22678,11696 22683,11696 22687,11691 22688,11695 22683,11691 22688,11696 22691,11695 22691,11700 22695,11702 22693,11705 22696,11710 22699,15710 22700,15712 22704,15707 22708,15712 22708,15715 22708,15720 22709,15725 22712,15723 22714,15724 22719,15727 22718,15727 22718,15731 22713,15730 22715,15734 22717,18734 22722,18729 22724,18725 22728,18729 22732,18733 22734,18736 22730,18740 22733,18740 22735,18742 22731,18741 22732,18744 22736,18749 22735,18754 22739,18754 22741,18756 22745,18758 22746,18760 22750,18764 22751,18764 22753,18764 22754,18767 22750,18767 22753,18767 22756,18772 22761,18777 22757,22777 22757,22780 22760,22776 22758,22776 22760,22772 22760,22775 22760,22777 22762,22774 22759,22775 22764,22772 22764,22767 22766,22768 22771,22771 22771,9589 10527,9593 10528,9598 10533,9600 10534,9597 10534,11597 10535,11602 10539,11603 10544,11598 10543,11601 10543,11605 10544,11609 10545,11611 10542,11615 10540,11615 10542,11616 10544,11619 10544,11621 10544,11623 10542,11619 10544,11620 10549,11616 10549,11618 10550,11619 10552,11622 10555,11622 10556,11623 10556,11621 10556,11625 10561,11625 10564,11625 10566,11628 10563,11630 10567,11628 10572,11626 10575,11628 10575,11632 11575,11636 11576,11638 11577,11638 11578,11638 11581,11639 11579,11643 11574,11646 11573,11650 11574,11647 11579,11648 11580,11653 11581,9571 9513,9571 9516,9571 9516,9574 9521,9572 9525,9573 9528,9573 9529,9578 9531,9583 9526,9581 9531,9576 9535,9578 9533,9583 9535,9583 9539,9587 9544,9590 14544,9595 14544,9598 14545,6598 14549,6598 14551,6599 14552,11599 14556,11602 14558,11598 14558,11598 14561,11602 14565,11603 14565,11603 14564,11603 14568,11604 14573,11605 14568,11607 14568,11607 14570,11607 14572,11607 14567,11611 14572,11611 14571,11607 14571,11609 14569,11605 14569,11606 14570,11606 14573,11607 14577,11610 14578,11609 16578,11609 16582,11607 16579,11605 16581,11606 16576,11605 11576,11608 11578,11610 11583,13610 11583,13614 11578,13616 11582,13617 11587,13617 11583,13621 11585,13626 11589,13621 11589,13621 11591,15621 11591,15625 11591,15630 11595,15631 11596,15634 11598,15638 11603,15642 11608,15643 11612,15642 11614,15646 16614,15648 16610,15648 16614,15648 16614,15647 16614,15652 16611,15654 16616,15655 16611,15651 16612,15655 16615,15659 16617,18659 16616,18660 16611,18660 16616,18664 16621,18668 16626,9673 12604,9674 12605,9676 12605,9679 12605,9682 12606,9680 12606,9680 12609,9681 12612,9684 12616,9688 12620,9691 12624,9686 12621,9686 12625,9686 12630,9684 12634,9686 12634,9687 12639,9686 12637,9683 12634,9685 12632,9689 12632,9689 12629,9692 12629,9692 12632,9695 12636,9693 12641,9692 12645,9692 16645,9694 16646,9698 16650,9698 16651,9693 16651,9693 16652,9693 16655,9692 16652,9693 16655,9689 16658,9689 16658,9692 16661,9696 16665,9698 14665,9701 14668,9702 14664,9703 14663,9702 14667,9707 14667,9711 14672,9716 14673,9719 14677,11719 14673,11720 14674,11721 14672,11725 14672,11729 14667,10729 18667,10732 18667,10727 18669,10730 18665,10732 18670,10737 18665,10737 18670,10742 18674,9742 18674,9741 18675,9742 18676,9746 18678,9751 18677,11751 18679,11751 18684,11753 18687,11757 18692,11757 18690,11761 18691,11761 18692,11766 18697,11769 18701,11771 18696,11774 18697,11774 18701,8613 10517,8611 10522,8611 10522,8616 10521,8619 10523,8622 10521,8623 10518,8623 10518,8624 10518,8624 10521,8629 10523,8633 10518,8635 10514,8640 10514,8642 10514,8646 10514,8647 10517,8644 13517,8649 13518,8653 13522,12653 13522,12653 13526,12657 18526,12653 18527,12657 18532,12660 18535,12656 18537,12660 18539,12658 18537,13658 18541,13657 18545,13657 18547,13660 18551,13665 18554,13665 18556,13665 18559,13665 18556,13668 18560,13672 18564,13672 18566,13676 18568,13676 18568,16676 18568,16681 18568,16678 18568,16682 18573,16681 18577,16686 18575,16686 18571,16686 18576,16684 18578,16684 18578,16681 18581,16684 18584,16683 18586,16687 18581,16682 18583,16677 18582,16676 18583,16681 18585,16679 14585,16677 14590,16682 14591,16686 14587,16691 14587,16696 14585,16696 14583,16697 14587,16702 14589,16704 14594,16699 14594,16704 14594,16704 14599,16705 14604,16708 14608,16713 15608,16717 15613,16721 15618,16721 15623,16724 15628,19724 15630,19726 15627,19729 15628,19725 15626,19720 15631,19724 15635,19728 15634,19729 15632,19730 15630,19733 15633,19734 15634,19736 15636,19741 15634,19739 15634,19744 15634,19749 15630,21749 15633,21747 15637,21749 15641,21749 15641,21745 15645,21748 15650,21749 15655,21751 15660,21753 15660,21755 15656,21752 15658,21751 15658,21753 15658,21754 15661,21754 15665,21754 15667,21757 15668,21753 16668,21753 16670,21757 16673,21759 16670,21756 16670,21760 16673,21757 16676,21761 16680,21765 16685,21768 16686,21769 16690,21769 16688,21769 16686,21766 16686,21768 16688,21773 16687,21778 16690,21781 16690,21780 16694,21780 16693,24780 16695,24777 16700,24782 16702,24787 16701,24787 16697,24787 16700,24792 16704,24787 16701,24788 16701,24789 16706,24792 16706,24797 16706,24800 16710,24805 16711,24805 16715,24810 16710,24809 16714,24813 16717,24817 16718,24817 16720,24819 16722,24815 16725,24812 16727,24811 16727,24814 16730,24819 16726,24821 16729,24826 16731,24830 16736,23830 16741,23826 16746,23827 16747,23829 16749,23833 16752,23835 11752,27835 11757,27837 11756,27834 11756,27835 11757,27838 11759,27833 11763,27834 11766,27839 11770,27844 11770,27849 11772,27849 11773,27849 11773,27854 11777,7581 10530,7582 10533,7581 10529,7583 10530,7584 10529,7584 10533,7582 10535,7586 10535,7589 10530,7592 10526,7592 10529,7589 10525,7592 10528,7596 10524,7600 10529,7602 10530,7599 10530,7594 10531,7598 10526,7601 10531,7605 10535,7609 10539,7612 10544,7610 10544,7612 10540,7608 10541,7610 15541,7613 15546,7617 15548,7618 15547,7620 15544,7620 15546,7621 15547,7624 15551,7628 15554,7631 15558,7631 15553,7636 15556,7637 15558,7637 15554,7641 15556,7644 15556,7648 15559,7651 15560,7647 15563,7650 15564,7650 15559,7652 15561,7650 15562,7651 15562,7651 15567,7655 15568,7653 15569,2653 15573,2657 15577,2662 15579,2663 15582,2663 15587,2665 15589,2669 15589,2669 15587,2673 15591,2673 15595,2677 15597,2677 15599,2680 15601,2683 15606,2687 15606,2683 15609,2688 15606,2692 15607,2693 15607,2698 15610,2698 15611,7698 15613,7702 15616,7704 15618,7699 19618,7703 19620,7698 19624,7698 19624,7701 19627,7699 19628,7704 19624,7708 19622,7712 19617,7714 19615,7710 19612,7715 20612,3715 24612,3720 28612,3724 28610,3727 28610,3728 28608,3725 28603,3729 28605,3733 28604,3734 28603,3737 32603,3739 32606,3740 32609,3739 32613,3738 32613,3735 32615,3739 31615,3739 31610,3743 31606,6743 31601,6743 31603,8743 31601,8743 31605,8748 35605,8748 35610,8752 35615,8751 35615,8752 35620,8755 35620,8760 35620,8765 35624,8760 35627,8764 35626,8761 35631,8763 35635,8767 35636,8767 35632,8767 35635,8771 35630,8775 35631,8778 35632,8775 35632,3775 35633,3775 35637,3774 35639,3772 35641,8772 35645,8772 35645,8773 35648,8768 35651,8764 35651,8769 40651,8764 40653,8767 40653,8770 40654,8771 40657,8775 40658,8777 40663,8779 40666,8783 40670,8783 40674,8787 40675,8789 40670,8789 40674,8792 40672,8795 40675,8796 40672,8800 40676,8800 40676,8800 40679,498 7392,503 7390,504 7390,507 7395,509 7395,509 7397,514 7400,6529 9451,6529 9451,6524 9451,6527 9452,6527 11452,6527 11456,6528 11457,6529 11458,6531 11461,6535 11463,6535 11467,6530 11472,6532 11472,10532 11473,10533 11473,10537 11476,10540 11473,10540 11473,10544 11474,10544 11474,10544 11472,10544 11470,10539 11475,10539 11478,10542 12478,10545 12483,10546 12488,10547 12492,10552 12493,10552 12490,10556 12490,10558 12493,10560 12495,10555 12496,10557 12491,10556 12491,10556 12490,10553 12494,10558 12497,10559 12502,10564 12505,21753 16670,21754 16672,26754 16674,26757 16676,26761 16679,26756 16682,26761 16683,26763 16684,26766 16689,26771 16692,28771 16687,28774 16687,28776 16692,28777 16695,28781 16695,28785 16690,28789 16691,28786 16688,28789 16690,28792 16688,28793 16687,28795 16690,28793 16695,28791 16692,28793 16695,28790 16696,28790 16700,28792 16700,28793 16701,28794 16701,28794 13701,28796 12701,28799 12701,28799 12706,28800 12701,28801 12705,28803 12708,28807 12708,28808 15708,28810 15712,28811 15709,28813 15709,28813 11709,28817 11709,7618 14589,7620 14587,7625 14589,7626 14584,7631 14586,7632 14588,7637 14589,7642 14592,536 1374,540 5374,542 5378,542 5383,-2458 5388,-2457 5388,-2455 5393,-2452 5393,-2452 5391,-2448 5389,-2448 5390,-2449 5393,-2445 5388,-2441 5392,-2436 5397,-2432 5397,-2430 5397,-3430 5399,-3429 5404,-3430 5405,-3427 5407,-3422 5409,-3421 5411,-3421 5411,-3421 5407,-3417 5410,-3418 5410,-3422 2410,-3417 2414,-3416 2418,-3412 3418,-3407 3422,-3407 3426,-3406 3429,-3404 3433,-3403 3435,-3398 3439,-2398 3441,-2399 3442,-2397 3446,-2395 3447,-2394 3443,-2398 3445,-2398 3443,-2393 3446,-2391 3450,-2387 3451,-2390 3455,-2385 3457,-2383 3457,-2382 3462,-2379 3467,-2384 3467,-2383 3467,-2381 3470,-2383 3471,-2385 3474,-2383 3479,-2383 3481,-2383 3479,-2382 3484,-2380 3489,-2385 3487,-2384 3490,-2384 3490,-2383 3492,-2383 3495,-2378 3499,-2377 3495,-2378 3498,-2375 3500,-2375 3505,-2373 3503,-2373 3505,-2374 3505,-2374 3506,-2369 3511,-2364 3516,-2361 3516,-2356 3520,-2354 3524,-2353 3529,-2356 3533,-2351 3538,-2354 3542,-2349 3545,-2349 3547,-2347 3550,-2352 3547,-2355 3551,-2353 3556,-2353 3556,-2349 3554,-2352 3553,-2351 3558,-2348 3554,-2346 3556,-2344 3559,-2347 -441,-2352 -437,-2348 -440,-2345 -435,-2343 -440,-2343 -436,-2339 -432,-2339 -431,-2337 -429,-2337 -434,-2341 -431,-2345 -427,-2349 -426,-2350 -422,-2348 -418,-2344 -415,-2349 -415,-2345 -413,-2345 3587,-2344 3583,-2344 3580,-2339 5580,-2335 5583,-2336 5582,-2331 5587,-2330 5582,-2329 5582,-2337 -434,-2333 -433,-2330 -2433,-2327 -2435,-2331 -2433,-2328 -2433,-2328 -2429,-2325 -2429,-2320 -2428,2680 -2428,2684 -2424,2685 576,2685 579,2682 582,2684 584,2679 584,2674 585,2671 587,2673 583,2673 581,2677 581,2680 580,2681 584,2684 580,2681 582,2685 585,2690 583,690 587,691 584,694 584,694 585,692 583,694 584,693 588,28793 16695,28791 16694,28793 16698,28797 16703,28798 16707,28797 16712,28797 16715,28795 16717,28799 16712,28795 16710,28800 16707,28805 16705,28807 16702,28802 16705,28803 16701,28805 16703,28803 16698,28803 16700,28805 16704,28809 16699,28812 16702,28808 16703,28813 16700,28817 16703,28819 16704,28816 16709,28812 16708,28809 16708,28809 16707,28814 16709,28812 16712,28807 16717,28807 16717,28809 16717,28807 16717,28811 16717,28814 16722,28815 16719,28819 16719,28819 16724,28819 16726,28814 16727,28814 16722,28817 16726,28820 16730,28821 16730,28816 16733,28821 16737,28823 16741,28818 16741,28822 16744,28819 16747,28815 16748,31815 16748,31819 16748,31817 16746,31818 16749,31819 16747,31817 16748,31820 16746,31816 18746,31820 18746,31815 18742,31815 18744,31818 18740,31819 18735,31824 18735,31829 18738,31834 18742,31837 18745,31837 18748,31842 18749,31847 18749,31851 18749,31854 18750,31854 18749,31852 18752,31847 18754,31850 18758,31855 22758,31857 22760,31861 22759,31859 22761,31856 22764,31856 22768,31856 22768,31856 22770,31858 22765,31863 22766,31862 22770,31860 22772,31856 22776,31861 22775,31866 22780,31870 22780,31871 22782,31871 22779,31866 22781,31870 22781,31870 22786,31873 22786,31877 25786,31877 25791,31877 25796,31880 25800,31882 25804,31885 25809,31885 25812,31886 25815,31888 25815,31890 25820,31890 25821,31889 25821,31885 25817,31889 25814,31887 25815,31890 25819,31892 25820,31896 25816,31897 25817,31902 25818,31904 25823,31908 25825,31910 25828,31914 25825,31909 25825,31912 25829,31907 25829,31911 25834,31912 25838,31911 25837,31914 25837,31918 25836,31918 25831,31914 25831,31912 25826,32912 25830,32915 25833,32911 26833,32912 26834,32915 26839,32913 26839,32915 26835,32917 26837,32922 26832,32924 26834,32926 26835,32921 26840,33921 26835,33923 26836,33927 26837,33925 26833,33926 26836,33931 26837,33929 26837,33932 26842,33934 26842,33935 26847,33940 26850,33935 26848,33931 28848,33929 28852,33925 28849,33927 28849,33929 28852,33927 28850,33929 28854,33931 28854,33935 28854,28935 28854,28935 28849,28938 28854,28942 28855,28944 28860,28942 28861,28941 28863,28942 28860,28942 28856,28947 28858,28951 28857,28953 28861,28953 28860,28956 28863,28957 31863,28957 31867,28960 31869,28962 31869,28964 31872,28965 31877,28969 31881,28965 31882,28967 31886,28969 31888,28964 31892,28960 31895,28961 31893,28966 31896,28967 31901,28963 31903,28961 31908,28964 31908,28964 31904,28960 31904,28961 31905,28960 31905,28965 31906,28966 31909,28967 28909,28967 28909,28970 28910,28966 28914,28965 28918,28966 28918,9626 21498,9621 21498,9622 21501,9618 21504,9621 21505,9624 24505,9622 24505,9625 24508,9626 24511,9631 24516,7631 24512,7631 24507,7632 24506,7635 24504,7638 24507,7636 24502,7639 24507,7644 24508,7648 24512,7648 24512,7650 24512,7651 24514,7655 24517,7659 27517,10659 27520,10661 27524,10664 27523,10666 27528,10666 27523,10665 27524,10667 27529,9667 27534,9670 27534,9668 27534,9667 27533,9670 27533,9670 27538,9670 27540,9675 27538,9679 27538,9683 27543,9680 27538,9682 27540,9685 27545,9683 27546,9683 27547,9678 27548,9680 27548,9684 27549,9685 27545,9690 27546,9690 27548,9692 27550,9697 27553,9698 27557,9702 27553,9702 27548,9702 27549,9706 27551,9701 27551,9701 27551,9697 27546,9696 27549,9697 27553,9699 27557,9698 27558,9696 27560,9701 27556,9705 27552,32912 25830,32913 25829,32916 25830,36916 25828,36916 25831,36916 25835,39916 25837,39911 25842,39913 30842,39910 30844,39910 30845,39908 30848,39911 30852,39913 30856,39918 30857,493 10403,498 10406,498 10406,493 10406,497 10404,493 10409,493 10414,497 10416,496 10418,499 10423,500 10427,505 10429,510 10429,515 10431,515 10433,515 10433,512 10434,5666 500,5666 500,5668 505,5669 509,8669 2509,9669 2505,9672 2505,9675 2509,9670 2510,14670 2513,14675 2512,14671 2512,14673 2513,14671 2517,14674 2515,14679 2520,14676 2524,17676 2519,17677 2520,17678 2523,10558 12497,13558 12492,13558 12490,13560 12494,13561 12499,13563 12503,13568 12508,13572 12512,13572 15512,13573 15515,13569 15518,13566 15522,13571 15522,13572 15522,13575 15527,13576 15532,13573 15534,13575 15535,13572 15538,13574 15541,13571 15546,13571 15541,13568 15541,11605 16581,11608 16576,11613 16575,11612 16577,7612 16581,7614 16582,7617 16587,7616 16591,7617 19591,7619 19595,7620 19598,7624 19598,7625 19599,7624 19595,7625 14595,7627 14597,7626 14599,7628 14604,7628 14605,7633 14610,7632 14615,7632 14620,7631 14621,7631 14621,7631 14621,7627 14621,7632 15621,7635 15626,7636 15627,7637 15631,7633 15636,7635 15636,7631 15631,7631 15631,7634 18631,7630 18632,7629 18633,7632 18630,7633 18631,7638 18632,7638 18632,7638 18633,7633 18638,7637 18642,7639 18639,7639 18641,7643 18643,7647 20643,7648 20647,7643 20643,7648 20640,7649 20645,7650 20641,7650 20642,7650 20645,5650 20646,5654 20646,5654 20643,5651 20645,5648 20645,5653 20650,5653 20650,5654 20653,5655 20655,5659 20660,5664 20664,5668 20669,5668 20672,5670 20677,5675 20677,5678 20677,5680 20678,5680 20680,5679 20680,5682 20683,5681 20681,5682 20682,5685 20682,5685 20687,5685 20691,5685 20694,5685 20696,5685 20698,5686 20697,5688 20698,5688 20697,5688 20696,5689 20696,5694 20701,5695 20700,5697 20704,5697 20708,5694 20708,5694 20708,5694 20713,5691 20713,1691 20713,1689 23713,1694 23714,1696 23714,593 1402,593 1406,595 1410,598 1413,603 1418,602 1422,601 1422,602 1418,606 1423,607 1424,603 1429,605 1433,609 1429,614 1429,610 1429,610 1429,614 1429,610 3429,612 3425,616 3429,620 3429,624 3432,628 3436,628 3436,628 3441,632 3441,628 3445,626 445,631 449,631 453,630 455,626 -1545,630 -1542,630 -1538,630 -1542,630 -1541,633 -1536,631 -1534,626 -1536,630 -1535,630 -1532,635 1468,637 1471,642 1476,642 1477,642 1478,643 1481,643 4481,638 7481,638 7483,643 7486,645 7484,9668 27534,9669 27537,9671 27538,9672 27539,9673 27544,9674 27544,9673 27546,9671 27546,9667 27542,9666 27546,9667 27543,9672 27544,9675 27548,9676 27546,9676 27541,9681 27538,9681 27540,9686 27544,9686 27547,9690 27544,9687 27545,9691 27549,9693 24549,9694 24546,9692 24548,9697 24553,9694 24555,9695 24560,9696 24555,9700 24551,9704 24547,9703 24549,9705 24551,9705 24554,9705 24554,9705 24557,9707 24561,9706 24557,9711 24562,9715 24566,9720 24568,9717 24569,9720 24573,9725 24573,9726 24575,9729 24577,9734 24575,9735 24578,9735 24582,9731 24583,9726 24586,9727 24586,9728 24589,9733 24592,9734 28592,9734 28592,13734 28594,13737 28595,13740 28595,13744 28598,13739 28600,13742 28601,13744 28597,13742 28602,13744 28602,13744 28598,13745 28603,13744 28608,13749 28609,13749 28609,13754 28606,13758 28610,13759 28609,13760 23609,13761 23611,13763 23616,13768 23618,13769 24618,13768 24617,13773 24613,13773 24613,13778 24617,13776 24620,13778 24619,13779 24620,13781 24625,13785 24625,13785 24622,16785 24617,16786 24617,16790 24617,16794 24622,16795 24626,16798 24630,16796 24631,16796 24636,16799 24638,16804 24637,16808 24637,16809 24632,16814 24627,16809 24627,16814 24632,16818 24628,16816 24627,16820 24622,16820 24627,16824 24632,16823 24637,16824 24642,16826 24644,16824 24648,16826 24648,16826 24652,16829 24652,16829 24656,16828 24651,16832 24653,16827 24648,16828 24645,16828 24647,16831 24645,16832 24649,16835 24653,16839 24656,16839 24654,16840 24659,16841 24658,16845 27658,16845 27658,16840 27659,16837 27659,19837 27654,19841 27654,19836 27657,19839 27659,19839 32659,19839 32659,19839 32664,19840 32668,19842 32671,19847 32671,19851 32673,19856 29673,19856 29670,19858 29675,19860 29676,19865 29677,19868 29677,19868 29674,19872 29675,19872 29674,19874 29669,19876 29667,19876 29670,19878 29675,19883 29675,19883 29675,19879 29676,19879 29673,19880 29674,19880 29679,19876 29676,19876 29677,19879 29673,19880 29677,19879 29678,19881 29681,19882 29683,19882 29681,19887 29681,19888 29681,19891 29684,19896 29688,14896 29689,14896 29693,14899 30693,14903 30698,14908 25698,14910 25698,14911 25698,14914 25699,14910 25695,14910 25696,14914 25697,14917 25692,14921 27692,14925 28692,14920 28694,14924 28698,14924 28699,11924 28697,11928 28692,11932 28687,11937 28691,11941 28694,11940 28699,11944 28701,11940 28701,11940 28701,11943 28699,11945 28703,11947 28706,11951 28711,11953 28714,11956 28709,11961 28708,11966 28703,11969 28705,11967 28709,11967 28714,11964 28719,11969 28719,14969 28720,14970 28717,14973 28714,14976 32714,14976 32711,14977 32711,14980 32709,14984 32709,14987 32711,14988 32715,14993 32719,14994 34719,14994 34721,12994 34724,12994 34726,12998 34727,13000 34729,13002 34729,17002 34732,16998 34736,16999 34735,17000 34740,16999 32740,17001 32745,17001 32741,17005 32746,17006 32751,17010 33751,17008 33754,17013 33758,17013 33760,17010 33759,17010 33759,17009 33762,17013 33766,17017 33766,17020 33762,17015 33766,17019 33762,17022 33762,17017 33766,17014 33762,17018 33767,17019 33764,17021 33764,17023 33764,17019 33764,17022 33760,17024 33758,17029 33759,17033 33760,17028 33764,17023 33764,17028 33769,17031 33774,17034 33778,17029 33780,17034 33783,17030 33785,17032 33781,17035 33776,17038 33775,17040 33775,17041 33778,17045 33778,17049 31778,17050 31782,17052 31780,17054 31781,17051 31783,17053 31783,17049 31779,17050 31779,21050 31782,21053 31783,21054 31778,21056 31781,22056 31786,22052 31783,22050 31786,31882 25804,31887 25800,31887 25801,9610 10543,9612 10548,9614 10553,9614 10558,9614 10553,9616 10556,9620 8556,9623 8554,9628 8559,9630 8564,9630 8568,9628 8566,9628 8570,9630 8574,9634 8574,9634 8570,9635 8569,9635 8566,9632 8568,9637 8571,9638 8572,9639 8568,9643 8568,9646 8572,9646 8570,9651 8575,9650 8578,9653 8581,9654 8583,9653 8586,9655 13586,7655 13586,7660 13591,4660 13590,4663 13590,4666 13592,4671 13597,4673 13596,4678 13599,4682 13600,4685 13601,4683 13603,4685 18603,4683 18604,4685 18606,4690 18608,4690 23608,4693 23606,4693 23606,4697 23603,4702 23608,4704 23613,4704 23615,4709 23614,4708 23615,4711 23619,4711 23619,4713 23622,4713 23626,4711 23630,4715 23631,4712 23635,4714 23640,4718 23640,4719 23642,4721 23640,4721 23639,4726 23644,4730 23648,4725 27648,4723 27648,4727 27651,4731 27654,4733 27656,4737 27657,4742 27660,4745 27661,4750 27660,4751 27664,4754 27659,4759 27659,4755 27664,4757 27665,4752 27665,4754 27667,4750 27670,4750 27674,4753 27678,4753 27682,4758 27682,4758 27683,4760 27679,4762 27679,4764 27682,4769 27678,4773 32678,4773 32675,4771 32675,4767 32679,4772 32684,4775 32684,4778 32684,4775 35684,4775 35679,4775 35680,4779 35683,4779 35683,4784 35683,4789 35680,4790 35685,4791 35687,4791 35688,4792 35683,4792 35688,4792 35688,4797 35690,4799 35693,4803 35692,4803 35694,4803 35695,4808 35695,4812 35698,4816 35702,4815 35706,4811 35711,4811 35708,4813 35710,4813 35710,4814 35714,4815 35718,4820 35722,4816 35719,4819 35719,4824 35722,4826 35719,4830 35724,4832 35728,4835 35725,4840 35726,4840 35729,4840 35733,4840 35733,4841 35732,4844 35728,4848 35730,4849 35733,4849 35734,4849 35736,4847 35737,4847 35738,4843 34738,4846 34739,9846 37739,9850 37743,9853 37745,9857 37749,9852 37752,9852 37751,9852 37748,9852 37751,9851 37753,9848 37756,9843 37759,9841 37759,9840 37764,9837 37767,9842 37764,9845 37764,9840 37765,9842 37770,9842 37774,9846 37775,9851 37778,9854 37783,9854 37779,8854 37783,8851 37787,8856 37791,8859 37794,8860 37793,8855 37794,8857 37798,8859 37797,8860 37797,8860 37802,8861 37804,8863 37804,8863 37805,8865 37808,8866 37811,8866 37811,8862 37811,8859 37811,8864 37816,8864 37816,8867 37817,8872 37819,8867 37822,8871 37819,8875 37817,8876 37819,8876 37822,8871 37818,8873 37823,8877 37822,8879 37820,8880 37824,8881 37826,8884 37825,8887 37827,8884 37829,6637 6475,6637 6471,6635 6469,6640 6474,6641 6478,11641 6476,11644 6471,11639 6467,11638 6464,11642 6464,11646 6459,11647 6462,550 1394,551 1395,552 1399,548 1401,552 1400,547 1405,551 1406,556 1407,558 1410,558 1411,560 1413,565 1418,561 1423,-2378 3499,-2378 3502,-2378 3504,-2374 3501,-2371 3505,-2367 3507,4607 5468,4611 5471,4614 5472,4619 8472,4621 8473,4624 8477,4629 8474,4633 8476,4635 8478,4638 8475,4640 3475,4642 3479,4645 5479,4645 5482,4644 5486,4641 5486,4639 5488,4635 5491,4631 5488,8631 5485,8635 4485,8630 4488,8628 4488,8630 4486,8635 7486,8640 7482,8641 8482,8642 8483,8643 8483,8643 8483,8640 8488,8641 8489,8638 8487,8641 8491,500 5370,502 5368,504 5369,504 5371,506 5375,505 5376,509 5381,509 5381,504 5380,505 5375,509 5379,513 5382,513 5382,515 5382,517 5379,3517 5381,3519 5381,3520 5384,3523 5387,3521 5388,3521 5390,3520 5385,3519 5380,4519 5383,4524 5387,4523 5392,4525 5389,4530 5384,4525 5384,4526 5386,4531 5390,4531 5387,4530 5389,4534 5388,4538 5391,4541 5386,4542 5390,7542 5393,7547 5398,7548 5399,7547 5397,7543 5401,7544 5405,7545 5403,7545 5408,7546 5409,7550 5414,3550 5416,3550 5417,3548 5417,3543 5417,3543 5412,3548 5412,548 5412,552 10412,555 10414,557 10410,560 10411,563 10416,2563 10418,2564 10422,2559 10426,2555 10423,2560 10421,2563 10418,2565 10419,2569 10421,2573 10421,2573 12421,2572 12425,2571 12428,2576 12428,2581 12433,2583 12435,2581 12434,2576 12439,2581 12442,2581 12443,2581 12438,2579 12442,2575 12447,2573 12445,2577 12445,2582 12441,2587 12436,2589 16436,2590 16433,2586 16437,2586 16439,2588 16434,2589 16436,2590 16433,2593 16434,2590 16432,2593 16432,2590 16437,2594 16439,2599 16442,2600 16447,2605 16450,2605 16454,2604 16451,2608 16447,2612 16442,2613 16446,2618 16451,2623 16455,2626 16457,2629 16457,2630 16460,2630 16460,2632 16464,2636 16464,2639 16467,2638 16471,2643 16476,2643 16479,2645 16484,2645 16481,2649 16482,2652 16480,2648 16476,2649 16476,2649 16481,2644 16485,6644 16488,6647 16488,6647 20488,6647 20493,6652 20497,6656 20498,6661 20503,6656 20507,6656 20511,6656 20512,7540 11429,9674 12603,11674 12599,11675 12594,11674 12599,11678 12601,11681 12603,13681 12603,13684 12603,13684 12603,13686 12603,13689 12603,13693 12605,13695 12601,13695 12603,13697 12602,13701 15602,13703 15603,13704 15601,13706 15597,13711 15598,13711 15603,13715 15603,13714 15600,13713 15598,13717 15603,13722 15605,13726 15607,13727 15612,13727 15612,13731 15614,13733 15616,13728 15616,13730 15617,13734 15614,13736 15617,13739 15614,13739 15617,13739 15617,13741 15619,13746 15624,13742 15624,13742 15626,13746 15626,13750 15623,13749 15621,13754 15626,12754 15627,12750 15627,12753 15624,12754 15624,12758 15629,12759 15624,12761 15627,12764 15632,12765 15637,12768 15635,12772 15640,12769 15636,12772 15634,12773 15634,12772 15634,12775 15635,12772 15640,12774 15641,12777 15641,12779 15646,12780 15642,12776 15640,12780 15640,12779 15638,12784 15642,12789 15643,12787 15644,12788 15649,12791 15649,12789 15648,12787 15648,12791 15650,7791 15655,7795 15655,7798 15658,7802 15659,7803 15655,7804 15654,2804 15652,2808 15648,2806 15652,2805 15652,2806 15657,2801 15657,2801 15658,2801 15655,2803 15654,2808 15658,2804 15653,2803 15656,2807 15656,2812 15658,2814 15657,2818 15658,2818 15660,2822 18660,2825 18664,2829 18668,2833 18663,2832 18668,2832 18668,2834 18671,2836 18672,2839 18677,2843 18680,2848 18675,2851 18677,2854 18681,2859 18685,2864 18690,2868 18694,2873 21694,2877 21694,2879 21693,2881 21693,2882 21696,2885 21697,2883 21701,2887 21702,2887 21702,2887 21697,6887 21701,6892 21702,6888 21707,3576 10502,3578 10506,3582 10508,3585 10508,3590 10512,3592 11512,3593 11514,3598 11514,3602 11514,3599 11515,3599 11516,3601 11520,3601 11519,3599 11522,3599 11519,3601 11517,3600 11515,3600 11517,3596 11519,3600 11521,3603 11525,3606 11528,3607 11532,3608 11536,3606 11541,3605 11541,3605 11542,3609 11537,3613 11538,3609 11538,3605 11538,3605 11542,3609 11546,3613 11541,3613 11546,3612 11547,3611 11551,3614 11548,3610 11550,3611 11555,3611 11559,3615 11559,3618 11563,3621 11564,3618 11567,3620 6567,3624 6567,3627 6570,3623 6572,3619 6576,3616 6577,3611 6578,3612 6579,3609 6578,3610 6582,3613 6586,3614 6586,3619 6584,3622 8584,3617 8582,3622 8587,3622 8592,3624 8592,3627 8587,3628 13587,3629 13589,3631 13594,3636 13589,3636 13590,3637 13587,3637 13591,3641 13596,3641 13597,3645 13602,3640 13601,3640 13602,3640 13606,3644 13606,3644 13609,3639 13612,3639 13612,3644 13610,3649 13615,3654 13618,3659 13618,3662 13618,3666 13620,3661 13625,3660 13630,3660 13634,3662 13635,3659 13637,3663 13638,3666 13638,3669 13635,6669 13635,6671 13631,6672 13631,6669 13631,6667 13629,6663 13629,6663 13627,6663 13627,6667 13630,6671 13630,6671 13630,6673 15630,6674 15631,6679 15632,6682 15629,6685 15629,6686 15631,6691 15633,11691 15630,11689 15629,11693 15632,11693 15627,11698 15627,11695 15626,11697 15629,14697 15628,14701 15631,14705 15632,14700 15632,17700 15635,17705 15640,17700 15642,17701 15638,17703 15640,17708 15641,17712 16641,17716 21641,17716 21645,17721 21645,17720 21650,17720 21653,17720 21653,17722 21653,17718 21654,17721 21657,17723 21657,17724 21657,17720 21659,17723 21663,17725 21660,17725 21661,17723 21661,17727 21665,17727 21665,17731 21669,17729 21671,17731 21671,17727 21671,17727 21667,17726 21670,17722 21671,17727 21671,17732 21671,17737 21671,17739 21674,17741 21676,17746 21680,17750 21683,17745 21681,17745 21678,17750 21679,17753 21681,17758 21677,17760 21682,17764 21681,17763 21681,17763 21684,17766 21680,17768 21684,17764 21688,17769 21691,17771 21695,17773 21691,17776 21690,17777 21695,17781 21695,17784 21695,17784 21695,17786 21699,14786 21695,14786 21692,14786 21690,14788 21691,14788 21696,14793 21698,14798 21701,14796 21699,14800 21702,14796 21704,14800 26704,14805 26699,14810 26700,14810 26698,14814 24698,14814 24702,14814 24705,14815 24700,14819 24703,14822 24705,14826 24710,14831 24709,14833 28709,14835 28710,14838 28708,14839 28708,14842 28709,14847 28713,14843 28714,14847 28712,14850 28717,14847 28713,14851 28711,14854 28706,14853 28702,14848 28697,14852 28702,14857 28706,14857 28710,14858 27710,14861 27711,14864 27714,17864 27715,17864 27716,17864 27713,17869 27715,17870 27719,17871 27720,17869 27720,17872 27724,17871 27729,17873 27729,17875 27733,17877 28733,17881 28730,17881 28727,17884 28728,17886 28733,17886 28734,17891 28735,19891 28735,19892 28731,19896 28732,19891 28736,19895 28740,19898 28737,22898 28738,22898 26738,22898 26733,22899 26738,22900 26738,22901 26742,22901 26744,22896 26744,22899 26746,22901 26751,22899 26754,22904 26756,22906 26761,22909 26761,22914 26766,22915 26765,22918 26768,22913 26768,22915 26763,22920 26763,22917 26764,22921 26765,22922 26769,22918 26764,22920 26765,22919 26768,26919 26771,26922 26774,26927 26779,26924 26778,26924 26780,26920 26782,26924 26787,26922 26788,26925 26792,26927 26787,26928 26790,26933 26794,26933 26795,26936 26795,26939 26800,26939 26798,26936 26798,26939 26795,26937 26795,26937 26793,26937 28793,26939 28791,26940 28793,26937 28796,26937 28797,26935 28798,26930 28798,26934 28802,26934 28807,26936 28811,26940 28812,26937 28815,26939 28814,26934 28812,26938 28817,26942 28822,26943 28822,26948 28822,26952 28824,26953 28824,26953 28829,26950 28834,26954 28839,26954 28839,26949 29839,21949 32839,21951 32838,21951 32843,21951 32844,21951 32849,21951 32854,21953 32854,24953 32852,24953 32851,24957 32853,24962 32854,24963 32849,24967 32847,24970 32849,24966 32849,24967 32852,24963 32856,24965 32860,24968 32861,24971 32860,24974 32860,24978 32863,24980 32859,24981 32864,24981 32868,24983 32866,24988 32866,24988 32869,24991 32874,24992 32878,24992 32881,24992 32877,24988 32880,24991 36880,24991 36883,24991 36885,24992 36889,24996 36894,24995 36894,24998 36894,24999 41894,25004 41899,25006 41900,25010 41905,25005 41909,25007 41912,25008 41916,25009 41919,25011 41917,25016 41919,25017 41916,25014 41919,25015 41919,25017 41919,25018 41924,25023 41927,25026 41928,25026 41929,25021 41926,25020 41926,25023 41928,25019 41933,25018 41932,638 7483,639 7484,640 7482,644 7484,646 7486,651 7486,554 1390,549 1391,547 1392,551 1397,3551 1394,3553 6394,3550 6399,3554 6399,3553 6403,3553 6400,3550 6403,3554 6398,3555 6402,3559 6403,3564 6405,3564 6410,3560 6412,3565 6412,3564 6407,3567 6407,3572 6410,3576 6412,3578 6413,3580 6414,11674 22654,11679 22654,11679 22654,11679 22656,11684 22658,11689 22661,11694 23661,11697 23658,11697 23661,11698 23664,11700 23667,11695 28667,11698 28671,11699 28672,11704 28675,12704 28671,12708 28669,12710 28673,12707 28678,12708 28678,12710 28677,12710 28677,12712 28675,12713 28679,12715 28676,12715 28680,12719 28681,12724 28678,12728 28673,12733 28676,12733 28673,12734 28673,12739 28677,12743 28679,12744 27679,12741 27680,12741 27680,12740 27682,12741 27678,12740 27680,7740 27684,7743 27686,7738 27683,7740 27683,7740 27686,7736 27690,7736 27693,7739 27691,7735 27686,7739 27686,7737 27686,7737 27688,7732 27689,7732 27689,7731 27684,7736 27689,7741 27692,7739 27697,7740 27702,7738 27703,7741 27706,7746 27704,2626 16457,2627 16460,2623 16461,2618 16461,2620 20461,2622 20457,2623 20457,2628 20457,2632 20462,2629 20462,2630 20462,2628 20457,2633 20460,2632 20460,2637 20460,2639 20457,2639 20457,2639 20461,2641 20460,2646 20460,2651 20461,2650 20461,2651 20464,2656 20460,2660 20463,2665 20464,2667 20464,2668 21464,2671 21468,2676 21471,2673 21476,2590 16437,2591 16434,2596 16436,4596 16438,4600 16439,4600 16439,4601 16439,4599 16435,4599 16440,4597 16441,4598 16446,4598 16447,4595 16445,4590 16447,4594 16447,4595 16447,4598 16447,4598 16449,4596 16451,4598 14451,4596 14456,4598 14457,4594 14452,4598 14457,5598 14457,5598 14458,2598 14463,2600 14463,2603 14464,2598 14465,2595 14470,2590 14467,2594 14470,2595 14471,2598 14473,2598 14473,2599 14473,1599 14474,1599 14472,1600 14467,1599 14470,1601 14468,1599 14463,1601 14461,1601 14461,1601 14466,1602 14468,1606 14473,1602 14473,1600 14475,1595 14478,1599 14479,1596 14479,1596 14484,1596 14488,1601 14489,1604 18489,1606 18492,1604 18492,1605 18496,1605 18496,1608 18501,1603 18498,1608 18500,1612 18497,1608 18492,1604 18494,1609 18497,1609 18499,1606 18499,1608 18501,1610 18503,1606 18499,1610 18500,1614 18501,1617 18497,1620 18498,1616 18501,1614 18496,1615 18500,1617 18497,1619 18498,1617 18501,1622 18506,1622 20506,1625 20506,1625 20509,1627 20513,1631 20514,1633 20519,1637 20520,1639 20525,1643 24525,1638 24520,1642 24520,1647 24525,1650 24529,1654 24530,1657 24533,1656 24538,1659 24542,1659 24545,1662 24550,1666 24551,1666 24552,1666 24557,1666 24562,1666 24565,1669 24568,1672 24569,1672 24569,1676 24566,1676 24570,1678 24565,1676 24567,1673 24567,1674 24572,1679 24577,1679 24578,1683 24581,1684 24586,1688 24590,1690 27590,1685 27594,1688 27594,1683 27594,1686 27597,1688 27600,1692 27599,1696 27600,1695 27604,1695 27609,1698 27610,1701 27610,1705 27609,1706 27605,1709 27600,1714 27600,1716 27602,1717 27601,1712 27597,1714 30597,1711 30600,1713 30600,1713 30604,1714 30604,1716 30602,1713 30605,1710 30606,1713 30609,1709 30607,1713 30604,1714 30609,1717 30609,1717 30613,1721 30615,2721 30620,2718 30623,4718 30628,4723 30624,4727 30619,4728 30618,4728 30615,4728 30619,4729 30618,4731 30622,4731 30625,4734 30625,4734 30630,4735 30627,4736 30631,4735 30636,4730 30641,4727 30641,4729 30646,4731 30650,4736 30651,4740 30648,4737 30648,4738 30647,4741 30649,5741 30646,5744 30648,5745 30651,10745 30651,13745 30653,13749 30651,13754 30652,13754 30657,13754 30657,13758 30653,13761 30656,13766 30655,13768 30659,13769 30662,13771 30659,13771 30661,13771 30665,13768 30670,13768 30667,13772 30670,13776 30672,13775 30672,13777 30675,13780 30679,13783 30677,13784 30678,13784 30674,13788 30674,13788 30678,13784 30678,13787 30683,13792 30683,13791 30679,13794 30679,13795 30682,13795 30686,13798 30691,13803 30692,13807 30694,13810 30694,13810 30692,13813 30694,13813 30689,13816 30689,13820 30689,13822 30692,13826 30696,13822 30701,13827 30704,13832 30707,13832 30707,13828 30707,13831 30712,13831 30709,13834 30706,12834 30707,12839 30703,12843 30707,12843 30703,12843 30706,12848 30710,12849 30715,12853 30713,12853 30716,12852 30718,12849 30721,12849 30719,12852 30719,12853 30714,12856 30712,12856 30714,12857 30719,12862 30720,12865 25720,12863 25723,12864 25724,12868 25729,12869 25731,12868 25736,12869 25739,12865 25737,12863 25739,12866 25743,12862 25747,12867 25747,12867 25748,12867 25748,12870 25748,12866 25748,12869 25749,12869 25751,12874 25754,12875 25758,12877 25761,12878 25763,21745 15645,21749 15645,21753 15646,21753 15648,21758 15652,21754 15654,21759 15654,21762 15658,21766 15663,21761 15663,21761 15665,21758 15666,21761 15668,21763 15666,21765 15662,21770 15666,21773 15671,12742 4678,12743 4682,12740 4687,12745 4692,12745 4688,12748 4689,12748 4692,12752 4696,12754 4697,12754 4700,12758 4703,12758 4703,12762 4704,12762 4709,12762 4711,12760 4713,12760 4717,12764 4713,12767 4712,12767 4712,12768 4715,12767 4720,12770 4716,12770 4712,2569 10421,2572 10423,2576 10424,2579 10428,2580 10423,2582 10424,2578 10422,2577 10426,2577 10428,2580 10433,2580 10433,2581 10432,2580 10435,2584 10435,2588 10439,2587 10444,2592 10445,2589 10446,2591 10447,2594 10446,2597 10445,2599 10440,2602 10443,2603 10443,2605 10444,2605 10449,2607 10449,2602 7449,2605 7449,2608 12449,2605 16449,2605 17449,2605 17450,2608 17454,2612 17459,2607 17459,2608 17456,2613 17457,2617 17459,6617 17462,6621 17467,6621 17468,6626 17464,6622 17465,6622 17465,6623 17469,6623 17466,6623 17467,6627 17466,6623 17466,6626 17463,6622 17468,6625 17464,6627 17468,6625 17463,6626 18463,6624 18463,6625 18464,6623 18468,6623 18469,6626 18470,6621 18466,6621 18467,6622 18467,6625 18464,6630 18468,6628 18469,6631 18472,6627 18477,6628 21477,6631 21481,6627 21486,6628 21490,6632 21494,6637 21496,6640 21491,6643 21491,6648 21490,1648 21492,1650 21489,1650 21487,1654 21488,1653 21489,1653 21492,1650 21493,1655 21493,1650 21493,1651 21490,1651 21490,1649 21493,1645 21498,1649 21494,1652 21495,1654 21500,1655 21495,1658 21492,1663 21496,1666 21500,1666 19500,1664 19504,1668 19508,1668 19512,1666 19516,1669 19518,1669 19518,1674 19520,1674 19525,1676 19525,1679 19526,1679 19526,1681 19526,1686 19526,1691 19529,1689 19529,1688 19529,1685 19524,1690 19528,1693 19531,1693 19531,1698 20531,1699 20536,1703 20538,1703 20538,1706 20541,1701 20545,1702 20550,1704 20547,1705 20544,1710 20548,1710 20551,1713 20555,1712 20559,1714 20562,1714 20563,1714 20565,1712 20567,1711 20570,1706 20571,1708 20571,1708 22571,6708 18571,6712 18571,6715 18573,6710 18577,6711 18579,6711 18579,6716 18578,6721 18580,6721 18582,6726 18587,6731 18588,6736 18587,6734 18587,6736 18590,6739 18594,6744 18597,6744 18602,6746 18606,6749 18606,6750 18609,6750 18610,6753 18605,6755 18610,6759 18613,6759 18613,6759 18617,6763 20617,6767 20621,6771 20625,6773 20628,6769 20629,4769 20633,5769 20635,5769 20637,5770 20640,5772 20643,5772 20646,5772 20644,5776 20641,5779 20643,5784 20642,5786 25642,5786 25645,5791 25647,3791 25651,3791 25652,3794 25648,3793 25644,3791 30644,3796 30649,3796 30654,3800 30655,3800 30657,3797 30657,3797 30659,3800 30661,3803 30661,3803 30657,3800 30652,3801 30652,3802 30653,3807 30654,3809 30657,3804 30656,3801 30657,3803 30657,3803 30658,3804 30663,4804 30663,4809 30665,9809 30665,9809 30669,9812 30673,9816 30676,9816 30676,9816 30677,9818 30682,9818 30683,9817 30687,9813 30692,9817 30692,9814 30693,9816 30693,9818 30697,9818 30699,9818 30696,9816 30694,9811 30694,9812 30694,9816 30697,9821 30700,9824 30702,9827 30707,9827 25707,9827 25711,9828 25709,9823 25713,9827 25712,9830 25714,9827 25712,9832 25717,9836 25719,9836 25722,11836 25725,11838 25727,14838 29727,14835 29728,14838 29724,14843 29724,19843 29724,19846 29728,19847 29732,19851 29737,19855 29738,19858 29735,19853 29735,19853 29737,19852 29739,19850 29744,19850 29744,19854 29747,19859 29752,19861 29750,19864 29751,19869 29752,19864 29756,19865 29757,19868 29758,19868 29758,19871 29763,19874 29764,19877 29766,19879 29763,19880 29763,19881 29765,19886 29765,19881 29765,19881 29768,19880 29773,19875 29775,19879 29776,19883 29776,19887 29781,19890 29784,19890 29789,19892 29784,19897 29785,19893 29785,22893 29787,22895 29792,22895 29788,22895 29789,22895 29793,22900 29793,25900 29790,25901 29794,25902 29794,25905 29794,25907 29798,25912 29799,25910 29804,25915 29809,25918 29807,25917 29808,25921 29808,25925 29812,25926 29816,25926 29819,25921 29821,25926 30821,25929 30823,25933 30822,25935 30823,25937 30818,25937 30818,25939 30819,25939 30824,25941 30819,25943 30823,25946 30824,25946 30829,25947 30829,25947 30830,25952 30833,25953 30831,25954 30836,25959 30836,25964 30836,25961 30836,25965 30837,25964 30835,29964 30839,29968 30842,31968 30847,31967 30844,31972 30844,31972 30840,31977 30839,31982 30842,31987 30844,31987 25844,31984 25848,31987 25848,31992 25845,31993 25846,31997 25846,31997 25849,31996 25851,31995 25855,32000 25858,31995 25859,31996 25856,31997 25858,31999 25858,31998 25858,32001 25859,32003 25863,32002 25866,32003 25867,32008 25867,32011 25870,32014 25875,32013 25874,34013 25873,34013 25876,34011 25878,34011 25880,34012 25885,34016 27885,34011 27884,39011 27888,39008 27884,39011 27879,39011 27876,39011 27880,39014 27879,39013 27879,39014 27879,39015 27882,39019 27886,39020 27888,39020 27893,39025 27895,39030 27896,39030 27896,39031 27892,39036 22892,39039 22894,39038 27894,39043 27895,39048 27900,39044 27905,39046 27907,39041 27910,39044 27910,39043 27915,-2382 3462,-2377 3465,-2373 3468,-2371 3469,1629 3470,1632 3472,1630 3469,5630 3473,5635 3474,5638 3474,5639 3469,5643 3473,5643 3473,5639 3477,5639 3477,5639 3480,5642 3479,5644 3481,5649 3480,2649 3485,2649 3485,2650 3489,2653 3491,506 5375,510 5380,513 5382,518 5384,522 5387,521 5384,524 5385,525 5382,523 5384,527 5384,527 5386,4527 5391,4528 5393,4533 2393,4534 2389,4537 2393,4538 2395,4541 2400,4543 2404,4544 2405,4548 3405,4553 3410,4556 3406,4561 3406,4558 3410,4559 3410,4558 3408,4558 3413,4563 3413,4561 3418,4563 3423,4565 3426,4565 3428,4570 3432,4570 3433,4574 3437,4579 3439,4583 3443,4578 3444,4582 3447,4583 3447,4585 3443,4590 3448,4586 3448,4588 3449,5588 3449,5589 3454,5593 3456,5591 3457,5591 3458,7591 3461,7594 3457,7596 3459,7591 3458,7590 3460,7593 3460,7593 3463,7590 3464,7586 3466,7581 3467,7580 3466,7580 3466,7585 3470,7585 3472,7589 3468,7589 3471,7594 3474,7599 3474,7600 3471,7603 3471,7606 3471,7606 3472,7606 3474,7606 3479,7609 3482,7612 6482,7614 6485,11614 6481,11619 6486,11624 6486,11621 6489,11623 6491,11628 6491,8628 6496,8632 6498,8629 6502,8632 6502,8627 6505,8631 6506,8633 6502,8633 6507,8631 6512,8631 6512,8626 6514,8621 6515,8620 6513,8615 6514,8611 6519,8612 6522,8613 6522,8616 6522,8611 6519,8614 6519,8615 6521,8618 6525,8623 6526,8628 6521,8631 6517,8634 6520,8634 6525,8637 6526,8636 6528,8640 6533,8643 6534,8643 6531,8642 6532,8643 6535,8643 6535,8640 6531,8641 6531,8641 6534,8644 6537,8647 6541,8648 6536,8649 6537,8649 6542,8644 6546,8644 6546,13644 6548,13642 6549,13638 6548,13636 6549,11636 6549,11636 6554,11633 6554,11636 6554,11641 7554,11642 7558,11641 7553,11643 7556,11644 7556,11639 7556,11641 7558,11641 7559,11641 7563,11638 7560,11639 7564,11642 7569,12642 7574,7642 7576,7642 7574,7643 7577,7645 7577,7650 7576,7645 7576,7648 7576,7650 7581,7651 7576,7654 7581,7658 7581,7661 7583,7662 7584,7664 7586,7661 7586,7662 7589,7666 7585,7669 7585,7670 7585,7670 7587,7670 7587,7670 7591,7667 7595,7672 7595,7677 7600,7679 7597,7684 5597,7682 5600,7685 5601,7688 5601,7691 5604,7696 5605,7700 5607,7703 5602,7704 5602,7701 5606,7702 5607,7706 5609,7710 5614,7713 5610,7716 5615,7717 5616,7719 5621,7724 5621,7724 5618,3724 5623,3722 5625,3725 5626,3730 5628,3727 5633,3727 5636,3729 5638,6729 5639,6732 5642,8732 5644,8732 5649,8729 5650,8734 5645,8736 5644,8739 5644,8741 5645,8745 5650,8743 5652,8739 5651,8744 5652,8744 5653,8745 5649,8748 5651,8749 5652,8750 5655,8753 5660,8753 5662,8755 5660,8757 5657,8758 5654,8762 5659,8760 5660,8761 5664,8765 5669,8768 5669,8768 5669,8769 5673,8769 5678,8772 5678,8769 5683,8774 5683,8776 5687,8777 7687,8779 7691,10779 7686,10779 7686,10780 7686,15780 7690,15781 7695,15779 7699,15783 7702,15788 7705,15791 7705,15786 7709,15788 7707,15793 7710,17793 7711,17794 7712,17799 7713,17800 10713,17802 10713,17802 10715,17803 10715,17808 10716,17811 10717,17811 14717,17811 14722,17811 14722,17815 14725,17819 14726,17820 14727,17822 14727,17817 14731,17818 14731,17818 14729,17820 19729,17818 19725,17822 19728,17818 19723,17821 19720,17821 19725,17824 19725,17821 19728,17821 19725,17825 19725,17830 19725,17834 19729,17836 19730,17837 19730,17841 19725,17844 19730,17849 19734,17853 19734,17856 19737,17858 19732,17858 19732,17863 19732,17868 19733,17873 19735,17874 19740,17878 19742,17883 19742,17879 19747,551 1397,551 1398,552 1401,553 1401,553 1398,552 1398,555 1402,556 1406,557 1409,558 1413,558 1416,558 1418,558 1420,563 1421,566 3421,568 3421,570 3426,572 3429,5572 3433,5576 3433,5579 3436,5579 3441,5583 3444,5580 3445,5585 3450,5589 3453,5593 3454,5597 3459,610 1429,612 1431,607 1430,607 1430,609 1426,605 1425,607 1425,602 1420,604 1423,-2378 3502,-2377 3503,-2378 3507,-2373 3508,-2375 3512,-2370 3516,-2373 3517,-2369 3514,-2370 3517,-2367 3519,-2366 3524,-2366 3529,-2362 3534,-2365 3536,-2370 3534,-2370 3531,-2366 3528,-2370 3532,-2366 3535,-2361 3533,-2361 3537,-2361 3540,-2358 3541,-3358 3543,-3355 3544,-3355 3542,-3355 3541,-3352 3546,-3348 3548,-3350 3551,-3346 3553,-3347 3553,-3342 3548,-3337 3548,-3338 3547,-3338 3547,-3334 3552,-3333 3552,-3332 3550,-3331 3550,-3329 3550,-3326 3552,-3325 3554,-3320 3556,-3315 3560,-3313 3565,-3312 3560,-3315 3563,-3315 3559,-3318 3564,-3321 4564,-3321 4569,-3317 4568,-3312 4573,-3311 4576,-3311 4575,-3308 4571,-3304 4572,-3299 4576,701 4580,703 4582,708 4582,711 4583,715 4587,716 4591,721 4587,717 4590,715 4594,715 4594,719 4598,719 4600,720 4604,717 4606,718 8606,722 8604,726 8600,727 8605,731 8609,731 8609,733 8611,738 8611,739 8612,734 12612,734 12617,730 12622,729 12622,732 12625,-268 12627,-263 12627,-264 12625,-261 12622,-260 12622,-265 12625,-264 12622,-264 12624,736 12622,733 12623,734 12626,730 12628,731 12632,732 12637,730 12637,733 12634,732 12635,732 12635,734 12635,733 12636,731 12639,734 12639,733 12642,734 14642,736 14646,739 14651,743 14654,-2257 14651,-2252 14651,-2252 19651,-2249 19656,-2249 19653,-2245 19650,-2248 19651,-2243 19656,-2241 19661,-2238 19664,-7238 19668,-7236 19666,-7231 19661,-7231 19666,-7227 19671,-9227 19672,-9223 19676,-7223 19675,-7223 19677,-7218 19677,-7219 19677,-7216 19673,-7214 19677,-7210 19674,-7206 19671,-7205 19673,-7203 19677,-7206 19680,-7202 19680,-7197 19685,-7197 19686,-7196 16686,-7201 16687,-7201 12687,-7198 12682,-7198 12682,-7193 12682,2673 15591,2673 15594,2673 15597,2671 15599,2666 15601,2670 15606,2669 15607,2670 15607,2673 15602,2670 15604,2671 15601,2672 15602,2667 15600,2672 15602,2675 15598,2675 15600,2678 15600,2677 15602,2673 17602,2678 17602,2677 18602,2681 18606,2682 18611,2685 18616,2686 18612,2688 18611,2686 18615,2686 18612,2687 18609,2688 18608,2688 18609,2688 18613,2693 18615,2693 18620,2691 18620,2696 18620,2698 18619,2695 18622,2700 18625,2704 22625,2709 25625,2709 25626,2710 25628,2710 25629,2714 25625,2715 25625,2713 25627,2714 25630,2718 25635,2723 30635,2723 30639,2726 30634,2727 30637,2728 30639,2732 30639,-1268 30642,-1266 30646,-1269 30643,-1269 30642,-1271 30642,-1269 30643,-1269 30645,-1269 30648,-1267 30647,-1265 30644,-1269 30648,-1268 30644,-1269 30644,-1269 30642,-1266 30641,3734 30637,3739 30640,3743 30641,3748 30646,3753 30650,3751 30653,3751 30652,3756 30647,3757 30648,3759 30653,3761 30656,3762 30655,3762 30653,3763 30650,3766 30652,3770 30657,3770 30657,3770 30653,3773 30650,3776 30650,3778 30650,3774 30655,3775 30657,3776 30660,3781 30662,3785 30665,3790 30670,5790 30672,5794 30675,5798 30680,5803 30675,5802 30673,5801 30677,5803 30679,5808 30677,5805 34677,5810 34677,5811 34682,5812 34684,5816 39684,5816 39687,5814 39690,5810 39695,5811 39696,5816 39700,5821 39705,5824 39707,5826 39711,5828 39708,5829 39709,5834 39712,5838 39715,5839 39718,5840 39720,5839 39722,5839 39722,5835 42722,5833 44722,5829 44722,5828 44722,5833 44724,5835 44727,5835 44731,2835 44729,3835 44731,3836 44736,3841 44739,3839 44736,3839 44736,3836 44736,3837 44737,3841 44737,3842 44733,3840 44735,3843 44730,3842 44732,6842 44734,6841 44735,6846 44737,6848 44737,6851 44740,6850 45740,6853 45741,6853 45741,6848 45743,6852 45744,6857 45746,6855 45747,6853 45750,6857 45754,6859 45752,6863 45751,6861 45751,6861 45748,6858 45752,6861 45750,6858 45750,6862 45750,6862 45753,6864 45757,6861 45762,6864 45762,6867 45761,6872 45763,6877 45758,6882 45761,6883 47761,6886 47761,6888 47762,6893 47767,6897 48767,6897 48772,6902 48771,6903 48773,6904 48773,6904 48777,6899 52777,6899 52777,6903 52773,6903 52773,7903 52773,7908 52771,7903 52772,7904 52774,7899 52776,7895 52776,7895 52781,7894 52778,7898 52783,7902 52785,7906 52790,7907 52792,11907 52797,11908 52801,11911 52800,11916 52804,11911 52806,11913 52808,11913 52805,11913 52809,11909 52812,11911 52812,11908 52815,11913 52817,11917 52820,11918 52820,11922 52825,11926 52823,11931 52827,11931 52826,11934 52823,11936 52818,11938 52819,11940 52823,11943 52828,11938 52833,11940 52835,11944 52832,11941 52831,11936 52831,11936 52833,11934 52836,11938 52839,11940 52840,11943 52840,11943 52841,11945 52844,16945 52844,16942 52839,18942 52838,18945 49838,18950 49841,18950 49844,18951 49845,21951 49847,21956 49848,21961 49846,21961 49851,23961 49852,23961 49856,23966 49860,23969 49865,23965 49866,23970 49862,23975 49859,23975 49859,23978 44859,23979 44862,23981 44862,23984 44867,23980 44871,23983 44875,23988 44875,23992 44877,27992 44878,27989 44881,27985 44886,27986 44888,27984 44888,29984 44889,29984 44889,29985 44893,29990 44888,29994 44892,29997 44896,30001 44895,30002 44900,30003 44904,30004 44907,30008 44904,30009 44904,30010 44905,30010 44908,30007 44908,30011 44905,30014 44908,30016 44909,30021 44912,30023 44913,30025 44912,30024 44910,30022 44914,30026 44912,30025 44912,30029 44912,30029 44915,30033 44920,30038 44924,30043 44926,30047 44928,30043 44930,30047 44932,30050 44934,30050 48934,30046 48935,30051 48935,30051 48935,30055 51935,30054 51931,1610 18503,1614 18504,1616 18504,1619 20504,1619 20504,1619 20505,1620 20509,1620 20511,1618 20511,1619 20508,2619 20511,2615 20516,2612 20515,2612 20515,2617 20512,2622 20515,2617 22515,2620 22516,2622 22519,2626 22522,2624 22522,2619 22524,2623 22519,2621 22519,2622 22516,2620 22512,2622 22517,2622 22522,2626 22522,2630 22522,-370 22526,-1370 22531,-1375 22531,-1371 22527,-1366 22527,-1362 22531,-1361 22528,-1362 22524,-1367 22528,-1367 22530,-1367 22533,-1367 22535,-1363 22540,-1363 22536,-1363 22539,-1358 22541,-1358 22541,-1355 22543,-1355 22538,-1355 22541,-1356 22544,-1357 22548,-1354 22553,-1353 22557,-1353 22561,-1355 22562,-1352 22566,-1351 22568,-1349 22569,-1347 22568,-1346 22566,-1351 22565,-1347 22566,-1348 22567,-1351 22569,-1346 22565,-5346 22567,-3313 3565,-3311 4565,-3308 4568,-3304 4571,-3307 4572,-3307 4573,-3303 4573,-3304 4578,-3300 4578,-3301 4578,-3301 4583,-3301 4581,-3297 4585,-3295 4580,-3295 4575,-3295 4573,-3293 4575,-3290 4580,-3285 4580,-3284 4582,-3284 4581,-3280 4580,-3285 4579,-3285 4579,-3284 4584,-3288 4588,-3286 4588,-3283 4584,-3279 4584,-3278 4588,-3279 4588,-3274 4586,-3270 4589,-3270 4590,-3268 4587,-3270 4591,-3267 5591,-3265 5591,-3261 5592,-3259 5593,-3259 5590,-3258 5595,-3256 5599,-3253 5601,-3252 5600,-3252 5603,-3252 5603,-3255 5601,-3250 5600,-3247 5605,-3242 5606,-3241 5608,-3243 5612,-3242 5612,-3245 5614,-3242 5619,-3243 5623,-2243 10623,-2242 10626,-2247 10626,-2247 10630,-2244 10634,-2248 10639,-2248 10636,-2248 10641,-2244 10646,11598 14558,11594 14563,11596 14568,11597 14569,11600 18569,11601 18570,11599 18566,11602 18568,11607 18567,11611 18572,11614 18573,11612 18569,11615 18570,11614 18573,11617 18577,11621 18577,11617 18574,11615 18579,11619 18583,11615 18587,11615 18587,11620 18588,11621 18589,11617 18593,11620 18597,11622 18599,11626 18603,11621 18603,11625 18607,11628 18611,11630 18614,11630 18619,11633 18616,11633 18616,11635 18614,11634 18613,11636 18609,11638 18607,11642 18612,11641 18615,11646 18615,11648 18619,11652 18621,11654 18622,11653 18617,11648 18619,11650 18614,11646 18617,11648 18613,11648 18618,11650 18615,11647 18617,11649 18621,11653 18621,11656 18624,11656 18628,11659 18628,11660 18624,11662 18624,11662 18620,11663 18620,14663 18621,14665 18616,14662 18611,14662 18607,14665 18607,14670 18607,14674 17607,14676 17610,19676 17608,19681 17613,19681 17613,19686 17611,19687 17612,22687 17612,22684 17608,22682 17607,22686 17610,22690 17611,22692 17612,22690 17617,22693 17622,22696 17622,22698 17625,22703 17627,22699 17629,22698 17629,22702 17634,22705 17630,22707 17634,22708 17634,22710 17639,22712 17639,22713 17635,22712 17639,22715 17644,22720 17644,22720 17646,22723 17644,22723 17644,22728 17643,22729 17646,22725 17651,22725 17652,22725 17647,22730 17647,22733 17647,22734 17647,22733 17651,22737 17653,22737 17657,22735 17660,22738 17658,22742 17662,22747 17667,22752 17671,22751 17672,22749 17677,22751 17677,22753 17681,22754 17677,22759 17674,22763 17674,22768 17677,22773 17673,22774 17676,22774 17679,17774 16679,17772 16679,17770 16675,17772 16676,17771 16676,17770 16679,17775 16684,17774 16685,17776 16685,17780 16687,17781 16688,17786 16689,17790 16689,17793 16688,17797 16684,17800 16684,17799 16689,21799 16691,21799 16688,21804 16689,21804 16687,21804 16687,21808 16685,21809 16689,21813 16693,21813 16696,21817 16698,21817 16699,21819 16694,21824 16699,21824 16701,21827 16705,21823 16702,21825 16702,21827 16702,21827 16702,21828 16705,21832 16707,21835 16710,21838 16712,21841 16712,21839 19712,24839 19714,24838 19719,24838 19722,24833 19722,24831 21722,24832 21727,24829 21729,24832 21730,24837 21732,24838 21736,24842 21740,24842 21740,24844 21740,24846 21740,24848 21741,24851 21736,24851 21732,24852 21737,24849 21741,24847 21742,24845 21743,24849 21744,24852 21742,24856 21744,24860 21745,24860 21745,24864 21749,24864 21754,24865 21759,24865 21760,24870 21764,24871 21762,24871 21762,24876 21767,24881 21769,24883 21768,24883 21769,24886 21766,24886 21767,24891 21770,24894 21772,24894 21772,24899 21777,24902 21781,24897 21786,24894 21787,24895 21790,24899 21791,24899 21795,24903 21798,24903 21801,24905 21804,24906 21806,24910 21808,25910 17808,25905 17812,25906 17813,28906 17813,28906 17813,28911 17817,28912 17812,28916 17813,33916 17818,33916 17818,33916 17820,33912 17820,33915 17823,33915 17826,33910 17826,33914 17829,33910 17833,33910 17836,33913 17837,33918 17841,33923 17840,33920 17840,33919 17842,33922 17838,33925 17835,33923 17836,33920 17838,33916 17840,33917 17845,33912 17850,33912 21850,33916 21846,33917 21841,33918 21844,33922 21844,33923 21844,33927 21844,33928 21849,33933 21850,33937 21851,33937 21853,33940 21855,33939 21858,33944 21855,33945 24855,33946 24858,33950 24860,33951 24864,33952 24861,33957 24864,33959 24867,33954 24865,33959 24867,33963 24867,33961 24867,33963 24871,34963 24874,34967 24874,34967 24874,34969 24870,34965 24875,34965 25875,34969 25880,34974 25883,34972 25883,34973 25885,34976 25889,34979 25890,34981 25894,34984 25897,34989 25899,34986 25900,34990 25901,34990 25901,34993 25902,34996 25902,35000 25903,35001 25906,35006 25909,35007 29909,35009 29905,35008 29906,35008 29908,35012 29908,31012 29911,31017 29906,31017 29908,21054 31778,21054 31775,21059 31780,21057 31780,21059 31783,21059 31781,21064 29781,21065 29786,21070 29787,21074 29787,21079 29792,21082 29792,21083 29791,21085 29793,21086 29794,21086 29794,21088 29797,21085 29797,21085 29800,21083 29804,21088 29808,21088 29804,552 1401,554 1401,555 1404,555 1404,559 1409,561 1410,561 1412,561 1413,557 1414,561 1419,564 1417,565 1420,568 1421,573 1425,578 1426,583 1430,584 1432,587 1433,588 1433,592 1437,592 1438,592 1442,591 1444,596 1444,597 1449,592 1449,502 2350,503 2352,505 2349,508 2349,508 2350,506 2350,506 2353,511 2357,511 2359,511 2361,508 2362,512 3362,517 3365,4517 3366,4518 3366,4513 3367,4512 3370,4509 3365,4510 3370,4510 3371,4513 3371,4513 3374,4517 3373,4517 3375,4514 3375,4515 3374,4516 3378,4516 3383,4516 3387,516 3392,516 3393,521 3394,521 -1606,522 -1601,518 -1601,519 -1603,521 -1598,526 -1603,528 -1603,527 -1601,527 -1600,523 -1603,526 -1601,529 -1598,532 -1594,531 -1590,531 -1594,527 -1595,532 -1591,536 -1586,539 3414,541 3419,546 3419,551 3422,551 3427,553 3429,558 3432,557 3433,558 3438,559 3442,560 3445,556 3448,555 3446,559 3446,560 3442,560 3439,561 3442,563 3443,564 3448,562 3448,5562 3453,5560 3454,5563 3454,5565 3456,5562 3457,5557 3456,5557 -544,5558 -543,5561 -538,5562 -535,5563 -533,5563 -530,5568 -525,5568 -523,5572 -518,5567 -514,5571 -516,5571 -514,5571 -514,5572 -510,5575 -512,5578 -512,5579 -508,5581 -506,5584 -503,5579 -502,5581 -505,10581 -505,10583 -500,12583 -499,12587 -498,12587 -499,12588 -497,12589 -502,12589 -500,12594 -498,12592 -498,12595 -498,12600 -496,12604 -494,12609 2506,12611 5506,12614 5511,12615 5516,12617 5518,12620 5522,12620 5519,12623 5521,12621 5524,12626 5526,12625 5531,12625 5531,12627 5532,12632 5531,12635 5536,12636 7536,12641 7540,12642 7540,12647 7543,11909 52812,11911 52817,11912 52817,11917 52814,11918 52819,11920 52819,11923 52823,11928 52818,11924 52813,11928 52812,11929 54812,11931 54813,11927 54813,11929 54818,11929 54822,11931 54823,11935 54824,11931 54828,11931 54833,11930 54830,11931 54832,11935 54835,11939 54830,11942 54827,11942 54828,11943 54828,11946 54825,11943 54826,11948 54829,11952 54824,11952 54828,11954 54830,11955 54830,11953 54835,11958 59835,11959 59838,11960 59836,11965 59840,11965 59843,11970 59840,11974 59840,11971 59842,11975 59847,11976 59848,11981 59848,11986 59853,11987 63853,11992 63854,11993 65854,11995 65850,11998 65852,12003 65856,12000 65859,12002 65859,12006 65854,12011 65855,12013 65856,12017 65861,12022 65861,12022 65856,12022 65857,8022 65859,8026 65862,8030 65863,8026 65865,8030 65866,8026 65871,8026 65871,3026 65869,3021 65870,3023 65875,3028 65876,3033 65878,3038 65874,3039 65878,3039 65882,3043 65880,3044 65880,3043 65884,3043 65888,3047 65889,3047 65890,3047 65890,3047 63890,3043 63892,3046 63896,3041 63895,3039 63898,3034 63900,3035 63901,3032 63903,3034 63906,3036 63906,3034 63908,3034 63913,3036 63911,3037 63916,3039 63911,3041 63913,3045 63915,3047 63915,3045 63917,3046 63921,3046 63921,3049 63920,3053 63923,3050 63927,3055 63930,3058 63933,3058 63932,3058 63934,3053 63931,3054 63933,3058 63936,3063 63940,3063 63939,-937 63940,-940 63944,-938 63945,-938 63946,-934 63948,-935 63945,-932 63948,-928 63950,-927 63954,-922 67954,-918 67951,-917 67956,-915 67960,-914 67965,-912 67967,-914 67971,-914 67971,-918 67976,-916 67973,-911 67973,-909 67978,-906 67981,-903 67982,-900 67982,-899 67978,-895 67981,-892 67985,-890 67987,-885 67982,-884 67984,-883 67984,-880 67985,-879 67985,-874 67981,-871 67981,-871 67986,-868 67986,-868 67981,-865 67979,-864 70979,-859 70984,-856 70985,-856 70990,-855 70991,-857 70989,-859 70991,-856 70986,-854 70991,-849 70994,-849 70997,-852 71002,-851 71007,-851 71009,-850 71009,-846 71011,-843 71011,-842 71011,-839 71011,-837 71016,-837 71016,-833 71018,-835 71022,2165 71022,2166 71018,7166 71017,7163 71017,7164 71018,7162 71016,7166 71013,7166 71013,7171 71010,7175 71010,7173 71012,7176 71017,7174 71021,11174 71021,11171 66021,11176 66021,11181 66018,11181 66023,11186 66022,11182 66027,11184 63027,11186 63031,11187 63033,11191 63034,11188 63031,11189 63036,11184 63037,11185 63038,11187 66038,11187 66038,11189 66038,11191 66038,11189 66034,11192 66036,11197 66037,12197 66041,12200 66044,12203 66042,12206 66046,12204 66046,12205 66048,12209 66048,12212 66043,12216 66040,12213 66043,12218 63043,12223 63038,12227 63033,12227 63038,12231 63040,12233 63040,12235 63045,12235 63045,12230 63044,12235 68044,12237 68044,12235 68049,12231 68045,12226 68050,12229 68052,12234 68052,12231 68056,12236 68059,12236 68062,12241 70062,12241 70063,12244 70063,12245 70068,12247 70068,12248 70071,12251 70071,12252 70071,12251 70073,12248 70075,12253 70080,12256 70084,12257 70088,12256 70088,12256 70089,12251 70089,17251 70090,17247 70090,17249 70091,17249 70088,17252 70084,17256 70085,17260 70086,16260 70084,16261 70083,16256 70079,16257 70076,16258 70072,16258 70077,16262 70081,16260 70084,16263 70087,16263 70088,16267 70090,16267 70093,16267 70097,16267 70100,16267 70101,16270 70103,16270 70105,16270 70108,16274 70110,16274 70113,16275 70115,16277 70115,16273 70115,16274 70120,16279 70117,16284 70117,16288 69117,16287 69121,16287 69123,16288 69119,16288 69122,16292 69125,16292 69122,16290 69125,16288 69125,16290 69126,16295 69122,3037 63916,3042 63920,3047 63925,3048 63928,3053 63928,3056 63931,3056 63930,3052 63932,3051 63935,3056 63938,3055 63935,3059 63932,3059 63937,3061 63942,3065 63945,3069 63942,6069 63940,6064 63945,6067 63948,6067 63947,6068 63951,10068 63953,10072 63953,10071 63951,10071 63956,10071 63958,10075 63958,10079 63953,10082 63958,10084 63959,10086 63959,10090 63960,10094 63955,10099 63955,10101 63956,10099 63952,10099 63949,10103 63953,10106 63956,10108 63956,10109 63956,10114 63959,10118 63959,10120 63960,10122 63963,10122 63968,10125 63969,10125 64969,10130 64971,10130 64973,10134 64974,10134 64979,10139 64984,10139 64987,10142 64988,10137 64992,10140 64995,10141 65995,10142 65999,10145 66000,10142 66002,10145 66002,10144 66004,10149 66002,10153 66007,8153 66007,8155 66011,8155 66011,8155 66011,8156 66011,9156 66013,9158 66014,9160 66014,9165 66017,9169 66022,9170 66023,9170 66023,9170 66028,9171 66031,9175 66033,9175 66033,9173 66035,9177 66034,9177 66039,9177 66044,9177 66044,9173 66044,9171 66044,9174 66046,9177 66050,9177 66047,9180 66051,9180 66055,9184 66055,9184 66051,9187 66056,9184 66057,9187 66053,9187 66055,9192 66056,9195 66061,9195 66066,9195 66071,9200 66076,9195 66075,9200 66080,9200 66080,9202 66076,9204 66079,9202 66079,9198 66079,11198 66083,11199 66087,11199 66088,11204 66088,11206 66089,11206 66093,11211 66088,11211 66091,11206 71091,11205 71090,11207 71094,11207 71098,11211 71102,11210 71103,11211 71107,11212 71107,11216 71105,11216 71108,11216 71113,11217 71108,11220 71113,11217 71113,11217 72113,11218 72115,11220 72117,11220 72121,11221 72124,11225 72120,11229 72117,11226 72118,11230 72122,11230 72123,11232 72127,11236 72132,11241 72133,11246 72135,11250 72139,11247 72141,11252 72141,11256 72143,11259 75143,11258 75146,11261 75151,11265 75149,11269 75153,11270 75158,11273 75160,11274 75165,11270 75166,11270 75166,11274 75165,11279 75167,11283 75170,11286 75166,11285 75168,11282 75165,6282 75163,6283 75167,6288 75170,6293 75175,6290 75178,6292 75179,6292 75182,6293 75181,31996 25856,31998 25856,32003 25857,32007 25862,32007 25857,32009 25857,32010 25858,32015 25854,32014 25857,32019 25857,32021 25852,32024 25852,32024 25854,32026 25851,32028 25855,32032 25855,32028 25858,32031 25860,32031 25863,32026 25867,32029 25868,32029 25869,32034 25872,32035 25875,32040 25878,32042 25883,32043 25881,32045 25885,32048 25884,32052 25881,32056 25878,32056 25874,32059 25878,32063 25882,32066 25885,32067 25885,32070 25885,37070 25885,37072 25889,37075 25890,37075 25885,37080 25890,37080 25892,37084 25888,37086 25893,37090 25898,37091 25895,37096 25897,37101 25902,37096 25905,37101 25906,37101 25909,37102 25914,37100 25914,37104 25914,37109 25917,37111 25919,37111 25924,37113 25925,37118 25923,37122 25927,37123 25929,17800 10713,17805 10708,17808 10711,17813 10715,17813 13715,17808 13719,17804 13714,17807 13717,17808 13722,17810 13724,17811 13728,17816 13730,17820 13733,17822 13736,17823 13736,17824 13740,17824 13745,18767 22750,18768 22754,18773 22754,18775 22757,18779 22760,18784 22763,18781 22767,18776 22767,18776 22769,18778 22772,18774 22773,18770 22774,18774 22776,18774 22777,18770 22781,18771 26781,18768 26785,18770 26787,18775 26787,18770 26789,18773 26793,18778 26795,18783 26796,18785 26799,18785 26801,18789 26798,18794 26799,18794 26801,18789 26803,18793 26806,18795 31806,18791 31810,18794 31814,18797 31817,18802 31813,18806 31815,18806 31819,18810 31824,18807 31828,18812 31830,18813 31826,18815 31828,18816 31829,18821 31831,18821 31833,18822 31836,18822 31838,18826 31841,18828 31846,5666 501,5668 506,5669 1506,5672 1508,5674 1512,7674 1512,7679 1513,7679 1512,7684 1513,7689 1511,7686 1515,7691 1520,7689 520,7689 521,7690 524,7695 520,4695 521,4696 526,4698 526,4699 531,4702 531,4699 535,4702 538,4698 540,4699 4540,4702 4537,4707 4540,4707 4537,4709 4537,4711 4542,4713 4542,4718 4544,4720 4549,4716 4553,4717 4556,4722 4561,4726 4562,4726 4563,4731 4564,4735 4565,4735 4570,4733 4572,9733 4574,9736 4577,9736 577,9737 572,9737 569,9742 570,9747 575,9747 580,9748 1580,9747 1585,9747 1588,9747 1588,9747 1592,9747 1592,9751 1592,9754 1593,9751 1595,9756 1599,11756 1603,11759 1607,11756 1610,11754 1613,11749 1613,11750 4613,11749 2613,11746 2610,11749 2608,11752 2611,11754 2607,11759 2612,11762 2612,11763 2612,11764 2613,11765 2613,11760 2615,11757 2620,11752 2623,11748 2627,11748 2631,11751 2632,11751 2633,11754 2635,11758 2639,11758 2643,11760 2646,11763 2646,11767 2649,11762 2652,11760 2652,11756 2656,11752 4656,11749 4659,11754 4662,11759 4666,11764 4670,11761 4666,11756 4669,11756 4670,11761 4671,11762 4673,11765 4678,11768 4680,11768 7680,12768 7677,12771 7680,12771 7683,12776 7683,12777 7688,12779 7688,12779 7684,12781 7679,13781 7682,13781 7684,13776 7684,13779 7685,13784 7685,13787 7689,13784 7689,13787 7689,13791 7685,13791 7686,13787 7691,13788 7696,13790 7693,13790 7696,13791 6696,13796 6698,13798 6695,13797 6698,13799 6701,13799 6704,13803 6709,13804 6705,13799 6708,13804 6703,13807 6705,13807 6708,13809 6710,13812 6714,13814 6716,13817 6718,13819 6722,13821 6717,13826 6718,13828 6717,13828 6721,13831 6721,13831 6720,13834 6715,13837 6712,13837 6713,13842 6715,13847 6715,13847 6714,13847 6709,13848 6712,13852 6714,13854 6719,13857 6723,13859 6726,13861 6730,13859 6731,13855 6731,13855 6731,13856 6728,13857 6730,13862 6731,13865 6731,13863 6729,13868 6729,13866 11729,13867 11732,13871 11732,13873 11737,13872 11741,13870 11745,13874 11744,13871 11748,13870 11753,13871 11757,13871 14757,13875 14759,13878 14760,13881 14760,13879 10760,13875 10765,13879 10767,13880 10770,13876 10775,13880 10776,13880 10776,13882 10776,13883 14776,13888 14779,13888 14779,13893 14779,13898 17779,13903 17784,13898 17788,13894 17788,13896 17788,13900 21788,13903 21784,18903 21789,18899 21789,18900 21793,18901 21794,18905 21795,18908 21792,18913 21794,13913 21796,13911 21798,13916 21799,13916 21799,13918 21804,13916 21800,13912 21799,13915 21794,13916 21797,13921 21799,13916 21802,13918 21806,13919 21810,13921 21813,13924 21817,13927 21814,13932 21816,13934 21811,13936 21811,13934 21814,18934 21816,18929 21816,18934 21815,18933 21817,18932 21822,18936 21819,18938 16819,18933 16822,18933 16822,18937 16822,18937 16827,18940 16827,18945 16830,18947 16829,18950 19829,18949 19829,18949 19829,18946 19825,18947 19828,18946 19829,18943 19829,18943 19824,14943 19829,14939 19830,14942 19831,14946 19835,14946 22835,14942 22836,14946 22831,14950 22832,14952 22835,14947 22840,14951 22844,14951 22845,14947 22850,14948 22851,14951 22849,14956 22852,14957 22852,14957 22857,14962 22857,14965 22859,14970 22860,14968 22862,14972 22864,14977 22866,14974 22870,14975 20870,14976 20870,14979 20873,14984 20869,14989 20871,14993 20874,14993 20877,14994 20878,14995 20878,14997 20883,14998 20879,15001 20884,15001 20884,15003 20889,15006 20884,15009 20885,15009 20883,15007 20880,15011 20876,15008 20877,15009 20873,15010 20875,15009 20875,10009 20876,10012 20871,10013 21871,10017 21872,10012 21873,10010 21874,10008 21871,10012 21870,10013 21874,11607 14571,11608 14575,11612 15575,11613 15576,11613 15577,11618 15578,11622 15581,11624 15585,11627 18585,11631 18587,11634 18590,11634 18586,11634 18586,11636 18591,11635 18591,11636 18596,11636 18592,13636 18593,13640 18595,13642 18600,13641 18600,13641 18604,13642 18607,13643 18611,13648 18611,13651 18613,13655 18615,13656 18620,13651 18618,13651 18616,13654 18611,13651 18616,18651 18620,18656 18620,18661 18621,18657 18625,18661 18627,18663 18628,18666 18633,18661 18637,18665 18639,18665 18639,18667 18641,18669 18641,22669 18642,22673 18644,22676 18648,22681 18649,22682 18649,22682 18646,19682 18646,19684 18646,19685 20646,19690 20646,19690 20643,19686 20643,19686 20643,19690 20647,19690 20647,19689 20652,19692 20653,19692 20656,19697 20661,19698 20662,19703 20666,19707 20669,19707 20673,19708 20674,19709 20675,19709 20677,19710 20674,19715 20675,19717 20673,19721 20673,19720 20677,19718 20677,19716 20680,19718 20681,19718 20685,19722 20688,19725 20688,19729 20685,19728 20687,19728 20690,19732 20691,19735 20691,19739 20691,19744 20696,16744 20693,16746 20695,16748 20695,16748 20691,16746 20696,16750 20699,16755 20704,16755 20709,16760 20710,16763 20711,16763 20711,16765 20707,16767 20705,16771 20706,16771 20708,16775 20706,9653 7576,9654 7577,9659 7576,9659 7572,9655 7575,9660 7579,9660 7579,9660 7583,9661 7588,9663 7591,9666 7590,9662 7592,9665 7593,9669 7594,9668 80000)') WHERE p = 1;
+UPDATE t1 SET g = ST_linefromtext('linestring(-5 -576,0 -576,0 -571,0 -571,5 -568,6 -564,6 -565,6 -563)') WHERE p = 2;
-let $index = spatial_none;
---source include/innodb_gis_undo.inc
+if ($index == 3) {
+ ALTER TABLE t1 ADD SPATIAL INDEX spatial_idx (g);
+}
-let $index = spatial_only;
---source include/innodb_gis_undo.inc
+if ($index == 2) {
+ eval ALTER TABLE t1 ADD INDEX prefix_idx (g($prefix_size));
+}
-let $index = spatial_mixed;
---source include/innodb_gis_undo.inc
+if ($index == 1) {
+ ALTER TABLE t1 DROP INDEX spatial_idx, DROP INDEX prefix_idx;
+}
-disconnect con1;
+connection control_purge;
+--echo # enable purge
+COMMIT;
+
+connection default;
+DELETE FROM t1 WHERE p = 2;
+
+--source ../../innodb/include/wait_all_purged.inc
+
+CREATE TABLE t2 (
+ p INT PRIMARY KEY,
+ g1 POINT NOT NULL,
+ g2 POINT NOT NULL,
+ g3 LINESTRING NOT NULL,
+ g4 LINESTRING NOT NULL,
+ g5 GEOMETRY NOT NULL,
+ g6 GEOMETRY NOT NULL,
+ SPATIAL KEY (g1),
+ SPATIAL KEY (g2),
+ SPATIAL KEY (g3),
+ SPATIAL KEY (g4),
+ SPATIAL KEY (g5),
+ SPATIAL KEY (g6)
+) ENGINE=InnoDB;
+
+DROP TABLE t1,t2;
+
+dec $index;
+}
+
+disconnect control_purge;
--source include/wait_until_count_sessions.inc
+
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb_gis/t/types.test b/mysql-test/suite/innodb_gis/t/types.test
index bd03e7b1dbe..fab0db5f755 100644
--- a/mysql-test/suite/innodb_gis/t/types.test
+++ b/mysql-test/suite/innodb_gis/t/types.test
@@ -6,13 +6,6 @@
# Restarting is not supported in embedded
--source include/not_embedded.inc
--source include/have_innodb.inc
---source include/have_debug.inc
-
-# Avoid CrashReporter popup on Mac
---source include/not_crashrep.inc
-
-# Turn on the geometry data print.
-SET SESSION debug="+d,row_print_geometry_data";
# Test GEOMETRY datatype.
CREATE TABLE t_wl6455 ( i INT, g GEOMETRY NOT NULL) ENGINE=InnoDB;
@@ -73,7 +66,8 @@ INSERT INTO t_wl6455 VALUES(11, POINT(11,11));
BEGIN;
INSERT INTO t_wl6455 VALUES(1, POINT(1,1));
---source include/kill_and_restart_mysqld.inc
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
CHECK TABLE t_wl6455;
SELECT ST_AsText(g) FROM t_wl6455;
diff --git a/mysql-test/suite/innodb_zip/include/innodb_wl6501_error.inc b/mysql-test/suite/innodb_zip/include/innodb_wl6501_error.inc
deleted file mode 100644
index 03400c79bef..00000000000
--- a/mysql-test/suite/innodb_zip/include/innodb_wl6501_error.inc
+++ /dev/null
@@ -1,225 +0,0 @@
-#
-# WL#6501: make truncate table atomic
-#
-
---source include/have_innodb.inc
---source include/have_debug.inc
-
---disable_query_log
-# suppress expected warnings
-call mtr.add_suppression("Unable to truncate FTS index for table");
-call mtr.add_suppression("Unable to assign a new identifier to table "
- "`.*`\.`.*` after truncating it");
-call mtr.add_suppression("Flagged corruption of .* in table "
- "`.*`\.`.*` in TRUNCATE TABLE");
-call mtr.add_suppression("Parent table of FTS auxiliary table "
- ".*\/.* not found");
---enable_query_log
-################################################################################
-#
-# Will test following scenarios:
-# 1. Error in assigning undo logs for truncate action.
-# 2. Error while preparing for truncate.
-# 3. Error while dropping/creating indexes.
-# 4. Error while completing truncate of table involving FTS.
-# 5. Error while updating sys-tables.
-#
-################################################################################
-
-#-----------------------------------------------------------------------------
-#
-# create test-bed
-#
-let $per_table = `select @@innodb_file_per_table`;
-
-eval set global innodb_file_per_table = on;
-let $WL6501_TMP_DIR = `select @@tmpdir`;
-let $WL6501_DATA_DIR = `select @@datadir`;
-set innodb_strict_mode=off;
-
-#-----------------------------------------------------------------------------
-#
-# 1. Error in assigning undo logs for truncate action.
-#
---echo "1. Error in assigning undo logs for truncate action."
-eval set global innodb_file_per_table = $wl6501_file_per_table;
---disable_warnings
-eval create $wl6501_temp table t (
- i int, f float, c char,
- primary key pk(i), unique findex(f), index ck(c))
- engine = innodb row_format = $wl6501_row_fmt
- key_block_size = $wl6501_kbs;
---enable_warnings
-insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
-select * from t;
-#check table t;
-#
-set session debug = "+d,ib_err_trunc_assigning_undo_log";
---error ER_GET_ERRNO
-truncate table t;
-set session debug = "-d,ib_err_trunc_assigning_undo_log";
-#
-#check table t;
-select * from t;
-drop table t;
-
-#-----------------------------------------------------------------------------
-#
-# 2. Error while preparing for truncate.
-#
---echo "2. Error while preparing for truncate."
-eval set global innodb_file_per_table = $wl6501_file_per_table;
---disable_warnings
-eval create $wl6501_temp table t (
- i int, f float, c char,
- primary key pk(i), unique findex(f), index ck(c))
- engine = innodb row_format = $wl6501_row_fmt
- key_block_size = $wl6501_kbs;
---enable_warnings
-insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
-select * from t;
-#check table t;
-#
-set session debug = "+d,ib_err_trunc_preparing_for_truncate";
---error ER_GET_ERRNO
-truncate table t;
-set session debug = "-d,ib_err_trunc_preparing_for_truncate";
-#
-#check table t;
-select * from t;
-drop table t;
-
-#-----------------------------------------------------------------------------
-#
-# 3. Error while dropping/creating indexes
-#
---echo "3. Error while dropping/creating indexes"
-eval set global innodb_file_per_table = $wl6501_file_per_table;
---disable_warnings
-eval create $wl6501_temp table t (
- i int, f float, c char,
- primary key pk(i), unique findex(f), index ck(c))
- engine = innodb row_format = $wl6501_row_fmt
- key_block_size = $wl6501_kbs;
---enable_warnings
-insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
-select * from t;
-#check table t;
-#
-set session debug = "+d,ib_err_trunc_drop_index";
---error ER_GET_ERRNO
-truncate table t;
-set session debug = "-d,ib_err_trunc_drop_index";
-#
-#check table t;
---error ER_TABLE_CORRUPT, 1030
-select * from t;
-drop table t;
-#
-#
-eval set global innodb_file_per_table = $wl6501_file_per_table;
---disable_warnings
-eval create $wl6501_temp table t (
- i int, f float, c char,
- primary key pk(i), unique findex(f), index ck(c))
- engine = innodb row_format = $wl6501_row_fmt
- key_block_size = $wl6501_kbs;
---enable_warnings
-insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
-select * from t;
-#check table t;
-#
-set session debug = "+d,ib_err_trunc_create_index";
---error ER_GET_ERRNO
-truncate table t;
-set session debug = "-d,ib_err_trunc_create_index";
-#
-#check table t;
---error ER_TABLE_CORRUPT, 1030
-select * from t;
-drop table t;
-#
-#
-eval set global innodb_file_per_table = $wl6501_file_per_table;
---disable_warnings
-eval create temporary table t (
- i int, f float, c char,
- primary key pk(i), unique findex(f), index ck(c))
- engine = innodb row_format = $wl6501_row_fmt
- key_block_size = $wl6501_kbs;
---enable_warnings
-insert into t values (1, 1.1, 'a'), (2, 2.2, 'b'), (3, 3.3, 'c');
-select * from t;
-#check table t;
-#
-set session debug = "+d,ib_err_trunc_temp_recreate_index";
---error ER_GET_ERRNO
-truncate table t;
-set session debug = "-d,ib_err_trunc_temp_recreate_index";
-#
-#check table t;
---error ER_TABLE_CORRUPT, 1030
-select * from t;
-drop table t;
-
-#-----------------------------------------------------------------------------
-#
-# 4. Error while completing truncate of table involving FTS.
-#
---echo "4. Error while completing truncate of table involving FTS."
-eval set global innodb_file_per_table = $wl6501_file_per_table;
---disable_warnings
-eval create $wl6501_temp table t (i int, f float, c char(100),
- primary key pk(i), index fk(f), fulltext index ck(c))
- engine=innodb row_format=$wl6501_row_fmt
- key_block_size=$wl6501_kbs;
---enable_warnings
-insert into t values (1, 1.1, 'mysql is now oracle company'),
- (2, 2.2, 'innodb is part of mysql'),
- (3, 3.3, 'innodb is default storage engine of mysql');
-select * from t;
-#check table t;
-#
-set session debug = "+d,ib_err_trunc_during_fts_trunc";
---error ER_GET_ERRNO
-truncate table t;
-set session debug = "-d,ib_err_trunc_during_fts_trunc";
-#
-#check table t;
---error ER_TABLE_CORRUPT, 1030
-select * from t;
-drop table t;
-
-#-----------------------------------------------------------------------------
-#
-# 5. Error while updating sys-tables.
-#
---echo "5. Error while updating sys-tables."
-eval set global innodb_file_per_table = $wl6501_file_per_table;
---disable_warnings
-eval create $wl6501_temp table t (i int, f float, c char(100),
- primary key pk(i), index fk(f), fulltext index ck(c))
- engine=innodb row_format=$wl6501_row_fmt
- key_block_size=$wl6501_kbs;
---enable_warnings
-insert into t values (1, 1.1, 'mysql is now oracle company'),
- (2, 2.2, 'innodb is part of mysql'),
- (3, 3.3, 'innodb is default storage engine of mysql');
-select * from t order by i;
-#check table t;
-#
-set session debug = "+d,ib_err_trunc_during_sys_table_update";
---error ER_GET_ERRNO
-truncate table t;
-set session debug = "-d,ib_err_trunc_during_sys_table_update";
-#
-#check table t;
---error ER_TABLE_CORRUPT, 1030
-select * from t order by i;
-drop table t;
-
-#-----------------------------------------------------------------------------
-#
-# remove test-bed
-#
-eval set global innodb_file_per_table = $per_table;
diff --git a/mysql-test/suite/innodb_zip/r/16k.result b/mysql-test/suite/innodb_zip/r/16k.result
index c1efeea329b..e7def759e87 100644
--- a/mysql-test/suite/innodb_zip/r/16k.result
+++ b/mysql-test/suite/innodb_zip/r/16k.result
@@ -18,6 +18,10 @@ AND t.name LIKE 'mysql%'
table_name n_cols table_flags index_name root_page type n_fields merge_threshold
mysql/innodb_index_stats 11 33 PRIMARY 3 3 4 50
mysql/innodb_table_stats 9 33 PRIMARY 3 3 2 50
+mysql/transaction_registry 8 33 PRIMARY 3 3 1 50
+mysql/transaction_registry 8 33 commit_id 4 2 1 50
+mysql/transaction_registry 8 33 begin_timestamp 5 0 1 50
+mysql/transaction_registry 8 33 commit_timestamp 6 0 2 50
CREATE TABLE t1 (a INT KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=innodb;
CREATE TABLE t2 (a INT KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=innodb;
CREATE TABLE t3 (a INT KEY, b TEXT) ROW_FORMAT=COMPRESSED ENGINE=innodb;
diff --git a/mysql-test/suite/innodb_zip/r/prefix_index_liftedlimit.result b/mysql-test/suite/innodb_zip/r/prefix_index_liftedlimit.result
new file mode 100644
index 00000000000..7a73dae473e
--- /dev/null
+++ b/mysql-test/suite/innodb_zip/r/prefix_index_liftedlimit.result
@@ -0,0 +1,1417 @@
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM
+INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ;
+COLUMN_NAME INDEX_NAME SUB_PART INDEX_TYPE
+col_1_varchar PRIMARY 3072 BTREE
+col_1_varchar prefix_idx 3072 BTREE
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+col_1_varchar = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+col_1_varchar = REPEAT("c", 4000)
+0
+1
+ALTER TABLE worklog5743 ROW_FORMAT=REDUNDANT;
+ERROR HY000: Index column size too large. The maximum column size is 767 bytes
+ALTER TABLE worklog5743 ROW_FORMAT=COMPACT;
+ERROR HY000: Index column size too large. The maximum column size is 767 bytes
+ALTER TABLE worklog5743 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16;
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (3072));
+SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM
+INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ;
+COLUMN_NAME INDEX_NAME SUB_PART INDEX_TYPE
+col_1_text PRIMARY 3072 BTREE
+col_1_text prefix_idx 3072 BTREE
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743;
+col_1_text = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_mediumtext MEDIUMTEXT , col_2_mediumtext MEDIUMTEXT ,
+PRIMARY KEY (col_1_mediumtext(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_mediumtext (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_mediumtext = REPEAT("a", 4000),col_2_mediumtext = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_mediumtext = REPEAT("a", 4000) col_2_mediumtext = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_mediumtext = REPEAT("c", 4000)
+WHERE col_1_mediumtext = REPEAT("a", 4000)
+AND col_2_mediumtext = REPEAT("o", 4000);
+SELECT col_1_mediumtext = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_mediumtext = REPEAT("c", 4000)
+AND col_2_mediumtext = REPEAT("o", 4000);
+col_1_mediumtext = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_mediumtext = REPEAT("b", 4000);
+SELECT col_1_mediumtext = REPEAT("c", 4000) FROM worklog5743;
+col_1_mediumtext = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_longtext LONGTEXT , col_2_longtext LONGTEXT ,
+PRIMARY KEY (col_1_longtext(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_longtext (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_longtext = REPEAT("a", 4000) , col_2_longtext = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_longtext = REPEAT("a", 4000) col_2_longtext = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_longtext = REPEAT("c", 4000)
+WHERE col_1_longtext = REPEAT("a", 4000)
+AND col_2_longtext = REPEAT("o", 4000);
+SELECT col_1_longtext = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_longtext = REPEAT("c", 4000)
+AND col_2_longtext = REPEAT("o", 4000);
+col_1_longtext = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_longtext = REPEAT("b", 4000);
+SELECT col_1_longtext = REPEAT("c", 4000) FROM worklog5743;
+col_1_longtext = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_blob BLOB (4000) , col_2_blob BLOB (4000) ,
+PRIMARY KEY (col_1_blob(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_blob (3072));
+SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM
+INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ;
+COLUMN_NAME INDEX_NAME SUB_PART INDEX_TYPE
+col_1_blob PRIMARY 3072 BTREE
+col_1_blob prefix_idx 3072 BTREE
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_blob = REPEAT("a", 4000) col_2_blob = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_blob = REPEAT("c", 4000)
+WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000);
+SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000);
+col_1_blob = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_blob = REPEAT("b", 4000);
+SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743;
+col_1_blob = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_mediumblob MEDIUMBLOB , col_2_mediumblob MEDIUMBLOB ,
+PRIMARY KEY (col_1_mediumblob(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_mediumblob (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_mediumblob = REPEAT("a", 4000),col_2_mediumblob = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_mediumblob = REPEAT("a", 4000) col_2_mediumblob = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_mediumblob = REPEAT("c", 4000)
+WHERE col_1_mediumblob = REPEAT("a", 4000)
+AND col_2_mediumblob = REPEAT("o", 4000);
+SELECT col_1_mediumblob = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_mediumblob = REPEAT("c", 4000)
+AND col_2_mediumblob = REPEAT("o", 4000);
+col_1_mediumblob = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_mediumblob = REPEAT("b", 4000);
+SELECT col_1_mediumblob = REPEAT("c", 4000) FROM worklog5743;
+col_1_mediumblob = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_longblob LONGBLOB , col_2_longblob LONGBLOB ,
+PRIMARY KEY (col_1_longblob(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_longblob (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_longblob = REPEAT("a", 4000) , col_2_longblob = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_longblob = REPEAT("a", 4000) col_2_longblob = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_longblob = REPEAT("c", 4000)
+WHERE col_1_longblob = REPEAT("a", 4000)
+AND col_2_longblob = REPEAT("o", 4000);
+SELECT col_1_longblob = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_longblob = REPEAT("c", 4000)
+AND col_2_longblob = REPEAT("o", 4000);
+col_1_longblob = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_longblob = REPEAT("b", 4000);
+SELECT col_1_longblob = REPEAT("c", 4000) FROM worklog5743;
+col_1_longblob = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varbinary VARBINARY (4000) , col_2_varbinary VARBINARY (4000) ,
+PRIMARY KEY (col_1_varbinary(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varbinary = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varbinary = REPEAT("a", 4000) col_2_varbinary = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+col_1_varbinary = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743;
+col_1_varbinary = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (col_1_char CHAR (255) , col_2_char CHAR (255),
+col_3_char CHAR (255), col_4_char CHAR (255),col_5_char CHAR (255),
+col_6_char CHAR (255), col_7_char CHAR (255),col_8_char CHAR (255),
+col_9_char CHAR (255), col_10_char CHAR (255),col_11_char CHAR (255),
+col_12_char CHAR (255), col_13_char CHAR (255),col_14_char CHAR (255)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255)
+);
+CREATE INDEX prefix_idx ON worklog5743(col_1_char(250),col_2_char(250),
+col_3_char(250),col_4_char(250),col_5_char(250),col_6_char(250),
+col_7_char(250),col_8_char(250),col_9_char(250),col_10_char(250),
+col_11_char(250),col_12_char(250),col_13_char(72)
+);
+INSERT INTO worklog5743 VALUES(REPEAT("b", 255) , REPEAT("p", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255)
+);
+SELECT col_1_char = REPEAT("a", 255) , col_2_char = REPEAT("o", 255) FROM worklog5743;
+col_1_char = REPEAT("a", 255) col_2_char = REPEAT("o", 255)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_char = REPEAT("c", 255)
+WHERE col_1_char = REPEAT("a", 255) AND col_2_char = REPEAT("o", 255);
+SELECT col_1_char = REPEAT("c", 255) FROM worklog5743
+WHERE col_1_char = REPEAT("c", 255) AND col_2_char = REPEAT("o", 255);
+col_1_char = REPEAT("c", 255)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255)
+);
+DELETE FROM worklog5743 WHERE col_1_char = REPEAT("b", 255);
+SELECT col_1_char = REPEAT("c", 255) FROM worklog5743;
+col_1_char = REPEAT("c", 255)
+1
+0
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (col_1_binary BINARY (255) , col_2_binary BINARY (255),
+col_3_binary BINARY(255),col_4_binary BINARY (255),col_5_binary BINARY (255),
+col_6_binary BINARY(255),col_7_binary BINARY (255),col_8_binary BINARY (255),
+col_9_binary BINARY(255),col_10_binary BINARY (255),col_11_binary BINARY (255),
+col_12_binary BINARY(255),col_13_binary BINARY (255),col_14_binary BINARY (255)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255)
+);
+CREATE INDEX prefix_idx ON worklog5743(col_1_binary (250),col_2_binary (250),
+col_3_binary (250),col_4_binary (250),col_5_binary (250),
+col_6_binary (250),col_7_binary (250),col_8_binary (250),
+col_9_binary (250),col_10_binary (250),col_11_binary (250),
+col_12_binary (250),col_13_binary (72)
+);
+INSERT INTO worklog5743 VALUES(REPEAT("b", 255) , REPEAT("p", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255)
+);
+SELECT col_1_binary = REPEAT("a", 255) , col_2_binary = REPEAT("o", 255) FROM worklog5743;
+col_1_binary = REPEAT("a", 255) col_2_binary = REPEAT("o", 255)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_binary = REPEAT("c", 255)
+WHERE col_1_binary = REPEAT("a", 255)
+AND col_2_binary = REPEAT("o", 255);
+SELECT col_1_binary = REPEAT("c", 255) FROM worklog5743
+WHERE col_1_binary = REPEAT("c", 255)
+AND col_2_binary = REPEAT("o", 255);
+col_1_binary = REPEAT("c", 255)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255)
+);
+DELETE FROM worklog5743 WHERE col_1_binary = REPEAT("b", 255);
+SELECT col_1_binary = REPEAT("c", 255) FROM worklog5743;
+col_1_binary = REPEAT("c", 255)
+1
+0
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743_key2 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(948))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb;
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743_key2;
+col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743_key2 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key2
+WHERE col_2_varchar = REPEAT("o", 4000);
+col_1_varchar = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key2 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key2;
+col_1_varchar = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743_key2;
+CREATE TABLE worklog5743_key4 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(1964))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb;
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743_key4;
+col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743_key4 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743_key4
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+col_1_varchar = REPEAT("b", 3500)
+0
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key4 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key4;
+col_1_varchar = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743_key4;
+CREATE TABLE worklog5743_key8 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(3072))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb;
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743_key8;
+col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743_key8 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743_key8
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+col_1_varchar = REPEAT("b", 3500)
+0
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key8 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key8;
+col_1_varchar = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743_key8;
+CREATE TABLE worklog5743_key2 (
+col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(948))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb;
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743_key2;
+col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743_key2 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key2
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("b", 3500)
+0
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key2 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key2;
+col_1_text = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743_key2;
+CREATE TABLE worklog5743_key4 (
+col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(1964))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb;
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743_key4;
+col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743_key4 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key4
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("b", 3500)
+0
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key4 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key4;
+col_1_text = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743_key4;
+CREATE TABLE worklog5743_key8 (
+col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb;
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743_key8;
+col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743_key8 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key8
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("b", 3500)
+0
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key8 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key8;
+col_1_text = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743_key8;
+CREATE TABLE worklog5743_key2 (
+col_1_blob BLOB (4000) , col_2_blob BLOB (4000) ,
+PRIMARY KEY (col_1_blob(948))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb;
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000)
+FROM worklog5743_key2;
+col_1_blob = REPEAT("a", 4000) col_2_blob = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743_key2 SET col_1_blob = REPEAT("c", 4000)
+WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000);
+SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key2
+WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000);
+col_1_blob = REPEAT("b", 3500)
+0
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key2 WHERE col_1_blob = REPEAT("b", 4000);
+SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key2;
+col_1_blob = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743_key2;
+CREATE TABLE worklog5743_key4 (
+col_1_blob BLOB (4000) , col_2_blob BLOB (4000) ,
+PRIMARY KEY (col_1_blob(1964))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb;
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000)
+FROM worklog5743_key4;
+col_1_blob = REPEAT("a", 4000) col_2_blob = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743_key4 SET col_1_blob = REPEAT("c", 4000)
+WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000);
+SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key4
+WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000);
+col_1_blob = REPEAT("b", 3500)
+0
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key4 WHERE col_1_blob = REPEAT("b", 4000);
+SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key4;
+col_1_blob = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743_key4;
+CREATE TABLE worklog5743_key8 (
+col_1_blob BLOB (4000) , col_2_blob BLOB (4000) ,
+PRIMARY KEY (col_1_blob(3072))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb;
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000)
+FROM worklog5743_key8;
+col_1_blob = REPEAT("a", 4000) col_2_blob = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743_key8 SET col_1_blob = REPEAT("c", 4000)
+WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000);
+SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key8
+WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000);
+col_1_blob = REPEAT("b", 3500)
+0
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key8 WHERE col_1_blob = REPEAT("b", 4000);
+SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key8;
+col_1_blob = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743_key8;
+CREATE TABLE worklog5743 (
+col_1_varbinary VARBINARY (4000) , col_2_varchar VARCHAR (4000) ,
+col_3_text TEXT (4000), col_4_blob BLOB (4000), col_5_text TEXT (4000),
+col_6_varchar VARCHAR (4000), col_7_binary BINARY (255)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+CREATE INDEX prefix_idx1 ON worklog5743(col_1_varbinary (3072));
+CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varbinary = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+col_1_varbinary = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743;
+col_1_varbinary = REPEAT("c", 4000)
+1
+0
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (3072));
+CREATE INDEX prefix_idx4 ON worklog5743(col_4_blob (3072));
+CREATE INDEX prefix_idx5 ON worklog5743(col_5_text (3072));
+BEGIN;
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SHOW WARNINGS;
+Level Code Message
+ROLLBACK;
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varbinary VARBINARY (4000) , col_2_varchar VARCHAR (4000) ,
+col_3_text TEXT (4000), col_4_blob BLOB (4000),col_5_text TEXT (4000),
+col_6_varchar VARCHAR (4000), col_7_binary BINARY (255)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+CREATE INDEX prefix_idx1 ON worklog5743(col_1_varbinary (3072));
+CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (3072));
+CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (3072));
+CREATE INDEX prefix_idx4 ON worklog5743(col_4_blob (3072));
+CREATE INDEX prefix_idx5 ON worklog5743(col_5_text (3072));
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varbinary = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+ROLLBACK;
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+COMMIT;
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varbinary = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+ROLLBACK;
+BEGIN;
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+SHOW WARNINGS;
+Level Code Message
+ROLLBACK;
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+col_1_varbinary = REPEAT("c", 4000)
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743;
+col_1_varbinary = REPEAT("c", 4000)
+0
+0
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_text TEXT (4000) CHARACTER SET 'utf8',
+col_2_text TEXT (4000) CHARACTER SET 'utf8',
+PRIMARY KEY (col_1_text(1024))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (1024));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) FROM worklog5743;
+col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743;
+col_1_text = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (col_1_varchar VARCHAR (4000) CHARACTER SET 'utf8',
+col_2_varchar VARCHAR (4000) CHARACTER SET 'utf8' ,
+PRIMARY KEY (col_1_varchar(1024))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (1024));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) FROM worklog5743;
+col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+col_1_varchar = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+col_1_varchar = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varbinary VARBINARY (4000) ,
+col_2_varchar VARCHAR (4000) CHARACTER SET 'utf8',
+col_3_text TEXT (4000) CHARACTER SET 'utf8',
+col_4_blob BLOB (4000),col_5_text TEXT (4000),
+col_6_varchar VARCHAR (4000), col_7_binary BINARY (255)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (500));
+CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (500));
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varbinary = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+ROLLBACK;
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+COMMIT;
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varbinary = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+ROLLBACK;
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+col_1_varbinary = REPEAT("c", 4000)
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743;
+col_1_varbinary = REPEAT("c", 4000)
+0
+0
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_text TEXT (4000) CHARACTER SET 'utf8',
+col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(1024))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("स", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (1024));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("स", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_text = REPEAT("स", 4000) col_2_text = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_text = REPEAT("क", 4000)
+WHERE col_1_text = REPEAT("स", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("क", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("क", 4000)
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("क", 4000) FROM worklog5743;
+col_1_text = REPEAT("क", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_text TEXT(4000) , col_2_text TEXT(4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200));
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+1 1
+connect con1,localhost,root,,;
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+1 1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+connect con2,localhost,root,,;
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200));
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+1 1
+0 1
+connection con1;
+select @@session.tx_isolation;
+@@session.tx_isolation
+REPEATABLE-READ
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200)
+0 1
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+select @@session.tx_isolation;
+@@session.tx_isolation
+READ-UNCOMMITTED
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200)
+0 1
+1 1
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+START TRANSACTION;
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+1 1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+connection con2;
+COMMIT;
+connection con1;
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200)
+0 1
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+1 1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+COMMIT;
+connection default;
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_text TEXT(4000) , col_2_text TEXT(4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200));
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+1 1
+connection con1;
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+1 1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+START TRANSACTION;
+connection con2;
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("a", 200);
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+0 1
+COMMIT;
+connection con1;
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+select @@session.tx_isolation;
+@@session.tx_isolation
+READ-UNCOMMITTED
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200)
+1 1
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200)
+1 1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+COMMIT;
+connection default;
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_text TEXT(4000) , col_2_text TEXT(4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200));
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+1 1
+connection con1;
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+1 1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+START TRANSACTION;
+connection con2;
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("a", 200);
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200)
+0 1
+ROLLBACK;
+disconnect con2;
+connection con1;
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200)
+0 1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+COMMIT;
+connection default;
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+col_1_varchar = REPEAT("c", 4000)
+1
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+col_1_varchar = REPEAT("c", 4000)
+0
+0
+1
+SELECT tbl1.col_1_varchar = tbl2.col_1_varchar
+FROM worklog5743 tbl1 , worklog5743 tbl2
+WHERE tbl1.col_1_varchar = tbl2.col_1_varchar ;
+tbl1.col_1_varchar = tbl2.col_1_varchar
+1
+1
+1
+SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1
+WHERE col_1_varchar IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2) ;
+tbl1.col_1_varchar = REPEAT("c", 4000)
+0
+0
+1
+SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1
+WHERE col_1_varchar NOT IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2) ;
+tbl1.col_1_varchar = REPEAT("c", 4000)
+SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 WHERE
+col_1_varchar IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2)
+AND col_1_varchar = REPEAT("c", 4000);
+tbl1.col_1_varchar = REPEAT("c", 4000)
+1
+SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1
+WHERE col_1_varchar in (
+SELECT tbl2.col_1_varchar FROM worklog5743 tbl2
+WHERE tbl1.col_1_varchar != tbl2.col_1_varchar
+) ;
+tbl1.col_1_varchar = REPEAT("c", 4000)
+SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1
+WHERE col_1_varchar in (
+SELECT tbl2.col_1_varchar FROM worklog5743 tbl2
+WHERE tbl1.col_1_varchar = tbl2.col_1_varchar
+) ;
+tbl1.col_1_varchar = REPEAT("c", 4000)
+0
+0
+1
+SELECT
+REVERSE(col_1_varchar) = REPEAT("c", 4000) ,
+REVERSE(REVERSE(col_1_varchar)) = REPEAT("c", 4000)
+FROM worklog5743;
+REVERSE(col_1_varchar) = REPEAT("c", 4000) REVERSE(REVERSE(col_1_varchar)) = REPEAT("c", 4000)
+0 0
+0 0
+1 1
+SELECT
+UPPER(col_1_varchar) = REPEAT("c", 4000) ,
+UPPER(col_1_varchar) = REPEAT("C", 4000) ,
+LOWER(UPPER(col_1_varchar)) = REPEAT("c", 4000)
+FROM worklog5743;
+UPPER(col_1_varchar) = REPEAT("c", 4000) UPPER(col_1_varchar) = REPEAT("C", 4000) LOWER(UPPER(col_1_varchar)) = REPEAT("c", 4000)
+0 0 0
+0 0 0
+1 1 1
+SELECT
+col_1_varchar = REPEAT("c", 4000)
+FROM worklog5743 WHERE col_1_varchar like '%c__%';
+col_1_varchar = REPEAT("c", 4000)
+1
+SELECT SUBSTRING(INSERT(col_1_varchar, 1, 4, 'kkkk'),1,10) FROM worklog5743 ;
+SUBSTRING(INSERT(col_1_varchar, 1, 4, 'kkkk'),1,10)
+kkkkaaaaaa
+kkkkbbbbbb
+kkkkcccccc
+SELECT CONCAT(SUBSTRING(col_1_varchar,-5,3),'append') FROM worklog5743 ;
+CONCAT(SUBSTRING(col_1_varchar,-5,3),'append')
+aaaappend
+bbbappend
+cccappend
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) ,
+col_2_varchar VARCHAR (4000) ,
+UNIQUE INDEX (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743
+VALUES(concat(REPEAT("a", 2000),REPEAT("b", 1000),REPEAT("c", 1000)), REPEAT("o", 4000));
+INSERT INTO worklog5743
+VALUES(concat(REPEAT("a", 2000),REPEAT("b", 2000)), REPEAT("o", 4000));
+INSERT INTO worklog5743 VALUES(NULL,NULL);
+INSERT INTO worklog5743 VALUES(NULL,NULL);
+SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE
+FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ;
+COLUMN_NAME INDEX_NAME SUB_PART INDEX_TYPE
+col_1_varchar col_1_varchar 3072 BTREE
+SELECT col_1_varchar FROM worklog5743 WHERE col_1_varchar IS NULL;
+col_1_varchar
+NULL
+NULL
+SELECT col_1_varchar = concat(REPEAT("a", 2000),REPEAT("b", 2000))
+FROM worklog5743 WHERE col_1_varchar IS NOT NULL ORDER BY 1;
+col_1_varchar = concat(REPEAT("a", 2000),REPEAT("b", 2000))
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(3072))) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+DROP INDEX prefix_idx ON worklog5743;
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+col_1_varchar = REPEAT("c", 4000)
+1
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+col_1_varchar = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY `prefix_primary` (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+col_1_varchar = REPEAT("c", 4000)
+1
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar(3072));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+ERROR 23000: Duplicate entry 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' for key 'PRIMARY'
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+col_1_varchar = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY `prefix_primary` (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+DROP INDEX prefix_idx ON worklog5743;
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+col_1_varchar = REPEAT("c", 4000)
+1
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar(3072));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+ERROR 23000: Duplicate entry 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' for key 'PRIMARY'
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+col_1_varchar = REPEAT("c", 4000)
+0
+1
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR(4000) , col_2_varchar VARCHAR(4000) ,
+PRIMARY KEY (col_1_varchar (3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("c", 3500) , REPEAT("o", 3500));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+connection con1;
+SELECT col_1_varchar = REPEAT("c", 3500) , col_2_varchar = REPEAT("o", 3500)
+FROM worklog5743;
+col_1_varchar = REPEAT("c", 3500) col_2_varchar = REPEAT("o", 3500)
+1 1
+connection default;
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 3500) , REPEAT("o", 3500));
+SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743
+WHERE col_2_varchar = REPEAT("o", 3500);
+col_1_varchar = REPEAT("b", 3500)
+0
+0
+COMMIT;
+connection con1;
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("k", 3500),REPEAT("p", 3500));
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+UPDATE worklog5743 SET col_1_varchar = REPEAT("b", 3500)
+WHERE col_1_varchar = REPEAT("a", 3500)
+AND col_2_varchar = REPEAT("o", 3500);
+SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743
+WHERE col_2_varchar = REPEAT("o", 3500);
+col_1_varchar = REPEAT("b", 3500)
+1
+0
+connection default;
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 3500);
+SELECT col_1_varchar = REPEAT("a", 3500) FROM worklog5743
+WHERE col_2_varchar = REPEAT("p", 3500);
+col_1_varchar = REPEAT("a", 3500)
+0
+connection con1;
+COMMIT;
+disconnect con1;
+connection default;
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varbinary VARBINARY (4000) , col_2_varbinary VARBINARY (4000) ,
+PRIMARY KEY (col_1_varbinary(3072))) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varbinary = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_varbinary = REPEAT("a", 4000) col_2_varbinary = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+col_1_varbinary = REPEAT("c", 4000)
+1
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+col_1_varbinary = REPEAT("c", 4000)
+DROP INDEX prefix_idx ON worklog5743;
+SELECT col_1_varbinary = REPEAT("b", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("b", 4000)
+AND col_2_varbinary = REPEAT("p", 4000);
+col_1_varbinary = REPEAT("b", 4000)
+1
+CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (2000));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_varbinary = REPEAT("a", 4000) FROM worklog5743;
+col_1_varbinary = REPEAT("a", 4000)
+1
+0
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+col_1_varbinary = REPEAT("c", 4000)
+DROP INDEX prefix_idx ON worklog5743;
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (4000));
+Warnings:
+Warning 1071 Specified key was too long; max key length is 3072 bytes
+SET sql_mode = default;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_varbinary = REPEAT("a", 4000) FROM worklog5743;
+col_1_varbinary = REPEAT("a", 4000)
+1
+0
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+col_1_varbinary = REPEAT("c", 4000)
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(500))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743;
+col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000)
+AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("c", 4000)
+1
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("c", 4000)
+DROP INDEX prefix_idx ON worklog5743;
+SELECT col_1_text = REPEAT("b", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("b", 4000) AND col_2_text = REPEAT("p", 4000);
+col_1_text = REPEAT("b", 4000)
+1
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (1000));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743;
+col_1_text = REPEAT("a", 4000)
+1
+0
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("c", 4000)
+DROP INDEX prefix_idx ON worklog5743;
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (4000));
+Warnings:
+Note 1071 Specified key was too long; max key length is 3072 bytes
+SHOW CREATE TABLE worklog5743;
+Table Create Table
+worklog5743 CREATE TABLE `worklog5743` (
+ `col_1_text` text NOT NULL,
+ `col_2_text` text DEFAULT NULL,
+ PRIMARY KEY (`col_1_text`(500)),
+ KEY `prefix_idx` (`col_1_text`(3072))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743;
+col_1_text = REPEAT("a", 4000)
+1
+0
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("c", 4000)
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(948))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) FROM worklog5743;
+col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000)
+1 1
+0 0
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000)
+AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000)
+AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("c", 4000)
+1
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000)
+AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("c", 4000)
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+SELECT col_1_text = REPEAT("b", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("b", 4000)
+AND col_2_text = REPEAT("p", 4000);
+col_1_text = REPEAT("b", 4000)
+1
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_text (700));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743;
+col_1_text = REPEAT("a", 4000)
+1
+0
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000)
+AND col_2_text = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000)
+AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("c", 4000)
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_text (950));
+ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743;
+col_1_text = REPEAT("a", 4000)
+0
+1
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000)
+AND col_2_text = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000)
+AND col_2_text = REPEAT("o", 4000);
+col_1_text = REPEAT("c", 4000)
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , PRIMARY KEY (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar (900));
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar (3073));
+ERROR 42000: Specified key was too long; max key length is 3072 bytes
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_BLOB BLOB (4000) , PRIMARY KEY (col_1_BLOB(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_BLOB (500));
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_BLOB (3073));
+ERROR 42000: Specified key was too long; max key length is 3072 bytes
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743
+VALUES(concat(REPEAT("a", 2000),REPEAT("b", 1000),REPEAT("c", 1000)),
+REPEAT("o", 4000));
+INSERT INTO worklog5743
+VALUES(concat(REPEAT("a", 2000),REPEAT("b", 2000)), REPEAT("o", 4000));
+ALTER TABLE worklog5743 ADD PRIMARY KEY `pk_idx` (col_1_varchar(3000));
+ERROR 23000: Duplicate entry 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' for key 'PRIMARY'
+DROP TABLE worklog5743;
+set global innodb_large_prefix=0;
+ERROR HY000: Unknown system variable 'innodb_large_prefix'
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+DROP TABLE worklog5743;
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(767))
+) engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT('a',4000),REPEAT('b',4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (1000));
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+ALTER TABLE worklog5743 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE;
+ERROR HY000: Index column size too large. The maximum column size is 767 bytes
+ALTER TABLE worklog5743 ROW_FORMAT=REDUNDANT, ALGORITHM=COPY;
+ERROR HY000: Index column size too large. The maximum column size is 767 bytes
+SHOW CREATE TABLE worklog5743;
+Table Create Table
+worklog5743 CREATE TABLE `worklog5743` (
+ `col_1_varchar` varchar(4000) NOT NULL,
+ `col_2_varchar` varchar(4000) DEFAULT NULL,
+ PRIMARY KEY (`col_1_varchar`(767)),
+ KEY `prefix_idx` (`col_1_varchar`(1000))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE worklog5743;
diff --git a/mysql-test/suite/innodb_zip/t/prefix_index_liftedlimit.test b/mysql-test/suite/innodb_zip/t/prefix_index_liftedlimit.test
new file mode 100644
index 00000000000..5a944f0ae8b
--- /dev/null
+++ b/mysql-test/suite/innodb_zip/t/prefix_index_liftedlimit.test
@@ -0,0 +1,1329 @@
+######## suite/innodb/t/innodb_prefix_index_liftedlimit.test ##########
+# #
+# Testcase for worklog WL#5743: Lift the limit of index key prefixes #
+# According to WL#5743 - prefix index limit is increased from 767 #
+# to 3072 for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPRESSED. #
+# All sub-test in this file focus on prefix index along with other #
+# operations #
+# #
+# #
+# Creation: #
+# 2011-05-19 Implemented this test as part of WL#5743 #
+# #
+######################################################################
+
+--source include/have_innodb.inc
+--source include/have_innodb_16k.inc
+
+# Prefix index with VARCHAR data type , primary/secondary index and DML ops
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+# check IS
+SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM
+INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+--error ER_INDEX_COLUMN_TOO_LONG
+ALTER TABLE worklog5743 ROW_FORMAT=REDUNDANT;
+--error ER_INDEX_COLUMN_TOO_LONG
+ALTER TABLE worklog5743 ROW_FORMAT=COMPACT;
+ALTER TABLE worklog5743 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16;
+DROP TABLE worklog5743;
+
+
+#------------------------------------------------------------------------------
+# Prefix index with TEXT data type , primary/secondary index and DML ops
+CREATE TABLE worklog5743 (
+col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (3072));
+# check IS
+SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM
+INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# Prefix index with MEDIUMTEXT data type , primary/secondary index and DML ops
+CREATE TABLE worklog5743 (
+col_1_mediumtext MEDIUMTEXT , col_2_mediumtext MEDIUMTEXT ,
+PRIMARY KEY (col_1_mediumtext(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_mediumtext (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_mediumtext = REPEAT("a", 4000),col_2_mediumtext = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_mediumtext = REPEAT("c", 4000)
+WHERE col_1_mediumtext = REPEAT("a", 4000)
+AND col_2_mediumtext = REPEAT("o", 4000);
+SELECT col_1_mediumtext = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_mediumtext = REPEAT("c", 4000)
+AND col_2_mediumtext = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_mediumtext = REPEAT("b", 4000);
+SELECT col_1_mediumtext = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+
+#------------------------------------------------------------------------------
+# Prefix index with LONGTEXT data type , primary/secondary index and DML ops
+CREATE TABLE worklog5743 (
+col_1_longtext LONGTEXT , col_2_longtext LONGTEXT ,
+PRIMARY KEY (col_1_longtext(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_longtext (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_longtext = REPEAT("a", 4000) , col_2_longtext = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_longtext = REPEAT("c", 4000)
+WHERE col_1_longtext = REPEAT("a", 4000)
+AND col_2_longtext = REPEAT("o", 4000);
+SELECT col_1_longtext = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_longtext = REPEAT("c", 4000)
+AND col_2_longtext = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_longtext = REPEAT("b", 4000);
+SELECT col_1_longtext = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+
+#------------------------------------------------------------------------------
+# Prefix index with BLOB data type , primary/secondary index and DML ops
+CREATE TABLE worklog5743 (
+col_1_blob BLOB (4000) , col_2_blob BLOB (4000) ,
+PRIMARY KEY (col_1_blob(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_blob (3072));
+# check IS
+SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM
+INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_blob = REPEAT("c", 4000)
+WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000);
+SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_blob = REPEAT("b", 4000);
+SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+
+#------------------------------------------------------------------------------
+# Prefix index with MEDIUMBLOB data type , primary/secondary index and DML ops
+CREATE TABLE worklog5743 (
+col_1_mediumblob MEDIUMBLOB , col_2_mediumblob MEDIUMBLOB ,
+PRIMARY KEY (col_1_mediumblob(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_mediumblob (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_mediumblob = REPEAT("a", 4000),col_2_mediumblob = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_mediumblob = REPEAT("c", 4000)
+WHERE col_1_mediumblob = REPEAT("a", 4000)
+AND col_2_mediumblob = REPEAT("o", 4000);
+SELECT col_1_mediumblob = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_mediumblob = REPEAT("c", 4000)
+AND col_2_mediumblob = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_mediumblob = REPEAT("b", 4000);
+SELECT col_1_mediumblob = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# Prefix index with LONGBLOB data type , primary/secondary index and DML ops
+CREATE TABLE worklog5743 (
+col_1_longblob LONGBLOB , col_2_longblob LONGBLOB ,
+PRIMARY KEY (col_1_longblob(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_longblob (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_longblob = REPEAT("a", 4000) , col_2_longblob = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_longblob = REPEAT("c", 4000)
+WHERE col_1_longblob = REPEAT("a", 4000)
+AND col_2_longblob = REPEAT("o", 4000);
+SELECT col_1_longblob = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_longblob = REPEAT("c", 4000)
+AND col_2_longblob = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_longblob = REPEAT("b", 4000);
+SELECT col_1_longblob = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# Prefix index with VARBINARY data type , primary/secondary index and DML ops
+CREATE TABLE worklog5743 (
+col_1_varbinary VARBINARY (4000) , col_2_varbinary VARBINARY (4000) ,
+PRIMARY KEY (col_1_varbinary(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varbinary = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# Prefix index with CHAR data type , composite index and DML ops
+CREATE TABLE worklog5743 (col_1_char CHAR (255) , col_2_char CHAR (255),
+col_3_char CHAR (255), col_4_char CHAR (255),col_5_char CHAR (255),
+col_6_char CHAR (255), col_7_char CHAR (255),col_8_char CHAR (255),
+col_9_char CHAR (255), col_10_char CHAR (255),col_11_char CHAR (255),
+col_12_char CHAR (255), col_13_char CHAR (255),col_14_char CHAR (255)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255)
+);
+# Create index with total prefix index length = 3072
+CREATE INDEX prefix_idx ON worklog5743(col_1_char(250),col_2_char(250),
+col_3_char(250),col_4_char(250),col_5_char(250),col_6_char(250),
+col_7_char(250),col_8_char(250),col_9_char(250),col_10_char(250),
+col_11_char(250),col_12_char(250),col_13_char(72)
+);
+INSERT INTO worklog5743 VALUES(REPEAT("b", 255) , REPEAT("p", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255)
+);
+SELECT col_1_char = REPEAT("a", 255) , col_2_char = REPEAT("o", 255) FROM worklog5743;
+UPDATE worklog5743 SET col_1_char = REPEAT("c", 255)
+WHERE col_1_char = REPEAT("a", 255) AND col_2_char = REPEAT("o", 255);
+SELECT col_1_char = REPEAT("c", 255) FROM worklog5743
+WHERE col_1_char = REPEAT("c", 255) AND col_2_char = REPEAT("o", 255);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255)
+);
+DELETE FROM worklog5743 WHERE col_1_char = REPEAT("b", 255);
+SELECT col_1_char = REPEAT("c", 255) FROM worklog5743;
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# Prefix index with BINARY data type , composite index and DML ops
+CREATE TABLE worklog5743 (col_1_binary BINARY (255) , col_2_binary BINARY (255),
+col_3_binary BINARY(255),col_4_binary BINARY (255),col_5_binary BINARY (255),
+col_6_binary BINARY(255),col_7_binary BINARY (255),col_8_binary BINARY (255),
+col_9_binary BINARY(255),col_10_binary BINARY (255),col_11_binary BINARY (255),
+col_12_binary BINARY(255),col_13_binary BINARY (255),col_14_binary BINARY (255)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255)
+);
+# Create index with total prefix index length = 3072
+CREATE INDEX prefix_idx ON worklog5743(col_1_binary (250),col_2_binary (250),
+col_3_binary (250),col_4_binary (250),col_5_binary (250),
+col_6_binary (250),col_7_binary (250),col_8_binary (250),
+col_9_binary (250),col_10_binary (250),col_11_binary (250),
+col_12_binary (250),col_13_binary (72)
+);
+INSERT INTO worklog5743 VALUES(REPEAT("b", 255) , REPEAT("p", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255)
+);
+SELECT col_1_binary = REPEAT("a", 255) , col_2_binary = REPEAT("o", 255) FROM worklog5743;
+UPDATE worklog5743 SET col_1_binary = REPEAT("c", 255)
+WHERE col_1_binary = REPEAT("a", 255)
+AND col_2_binary = REPEAT("o", 255);
+SELECT col_1_binary = REPEAT("c", 255) FROM worklog5743
+WHERE col_1_binary = REPEAT("c", 255)
+AND col_2_binary = REPEAT("o", 255);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255),
+REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255)
+);
+DELETE FROM worklog5743 WHERE col_1_binary = REPEAT("b", 255);
+SELECT col_1_binary = REPEAT("c", 255) FROM worklog5743;
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# Prefix index with VARCHAR data type , primary/seconday index , DML ops
+# and COMPRESSED row format. KEY_BLOCK_SIZE is varied as 2 , 4 , 8.
+
+# With KEY_BLOCK_SIZE = 2,prefix index limit comes around ~948 for following
+CREATE TABLE worklog5743_key2 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(948))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb;
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+#CREATE INDEX prefix_idx ON worklog5743_key2 (col_1_varchar (767));
+INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743_key2;
+UPDATE worklog5743_key2 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key2
+WHERE col_2_varchar = REPEAT("o", 4000);
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key2 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key2;
+DROP TABLE worklog5743_key2;
+
+# With KEY_BLOCK_SIZE = 4,prefix index limit comes around ~1964 for following
+CREATE TABLE worklog5743_key4 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(1964))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb;
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+#CREATE INDEX prefix_idx ON worklog5743_key4 (col_1_varchar (767));
+INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743_key4;
+UPDATE worklog5743_key4 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743_key4
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key4 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key4;
+DROP TABLE worklog5743_key4;
+
+# With KEY_BLOCK_SIZE = 8,prefix index limit comes around ~3072 for following
+CREATE TABLE worklog5743_key8 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(3072))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb;
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+#CREATE INDEX prefix_idx ON worklog5743_key8 (col_1_varchar (767));
+INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743_key8;
+UPDATE worklog5743_key8 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743_key8
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key8 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key8;
+DROP TABLE worklog5743_key8;
+
+# Prefix index with TEXT data type , primary/seconday index , DML ops
+# and COMPRESSED row format. KEY_BLOCK_SIZE is varied as 2 , 4 , 8.
+
+# With KEY_BLOCK_SIZE = 2,prefix index limit comes around ~948 for following
+CREATE TABLE worklog5743_key2 (
+col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(948))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb;
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+#CREATE INDEX prefix_idx ON worklog5743_key2 (col_1_text (767));
+INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743_key2;
+UPDATE worklog5743_key2 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key2
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key2 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key2;
+DROP TABLE worklog5743_key2;
+
+# With KEY_BLOCK_SIZE = 4,prefix index limit comes around ~1964 for following
+CREATE TABLE worklog5743_key4 (
+col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(1964))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb;
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+#CREATE INDEX prefix_idx ON worklog5743_key4 (col_1_text (767));
+INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743_key4;
+UPDATE worklog5743_key4 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key4
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key4 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key4;
+DROP TABLE worklog5743_key4;
+
+# With KEY_BLOCK_SIZE = 8,prefix index limit comes around ~3072 for following
+CREATE TABLE worklog5743_key8 (
+col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb;
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+#CREATE INDEX prefix_idx ON worklog5743_key8 (col_1_text (767));
+INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743_key8;
+UPDATE worklog5743_key8 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key8
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key8 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key8;
+DROP TABLE worklog5743_key8;
+
+# Prefix index with BLOB data type , primary/seconday index , DML ops
+# and COMPRESSED row format. KEY_BLOCK_SIZE is varied as 2 , 4 , 8.
+
+# With KEY_BLOCK_SIZE = 2,prefix index limit comes around ~948 for following
+CREATE TABLE worklog5743_key2 (
+col_1_blob BLOB (4000) , col_2_blob BLOB (4000) ,
+PRIMARY KEY (col_1_blob(948))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb;
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+#CREATE INDEX prefix_idx ON worklog5743_key2 (col_1_blob (767));
+INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000)
+FROM worklog5743_key2;
+UPDATE worklog5743_key2 SET col_1_blob = REPEAT("c", 4000)
+WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000);
+SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key2
+WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000);
+INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key2 WHERE col_1_blob = REPEAT("b", 4000);
+SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key2;
+DROP TABLE worklog5743_key2;
+
+# With KEY_BLOCK_SIZE = 4,prefix index limit comes around ~1964 for following
+CREATE TABLE worklog5743_key4 (
+col_1_blob BLOB (4000) , col_2_blob BLOB (4000) ,
+PRIMARY KEY (col_1_blob(1964))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb;
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+#CREATE INDEX prefix_idx ON worklog5743_key4 (col_1_blob (767));
+INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000)
+FROM worklog5743_key4;
+UPDATE worklog5743_key4 SET col_1_blob = REPEAT("c", 4000)
+WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000);
+SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key4
+WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000);
+INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key4 WHERE col_1_blob = REPEAT("b", 4000);
+SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key4;
+DROP TABLE worklog5743_key4;
+
+# With KEY_BLOCK_SIZE = 8,prefix index limit comes around ~3072 for following
+CREATE TABLE worklog5743_key8 (
+col_1_blob BLOB (4000) , col_2_blob BLOB (4000) ,
+PRIMARY KEY (col_1_blob(3072))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb;
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+#CREATE INDEX prefix_idx ON worklog5743_key8 (col_1_blob (767));
+INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000)
+FROM worklog5743_key8;
+UPDATE worklog5743_key8 SET col_1_blob = REPEAT("c", 4000)
+WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000);
+SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key8
+WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000);
+INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743_key8 WHERE col_1_blob = REPEAT("b", 4000);
+SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key8;
+DROP TABLE worklog5743_key8;
+
+
+#------------------------------------------------------------------------------
+# Create multiple prefix index. We can not create prefix index length > 16K
+# as index is written in undo log page which of 16K size.
+# So we can create max 2 prefix index of length 3072 on table
+CREATE TABLE worklog5743 (
+col_1_varbinary VARBINARY (4000) , col_2_varchar VARCHAR (4000) ,
+col_3_text TEXT (4000), col_4_blob BLOB (4000), col_5_text TEXT (4000),
+col_6_varchar VARCHAR (4000), col_7_binary BINARY (255)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+
+# Update reports ER_UNDO_RECORD_TOO_BIG if we create more than 2 indexes.
+# Bug#12547647 - UPDATE LOGGING COULD EXCEED LOG PAGE SIZE
+CREATE INDEX prefix_idx1 ON worklog5743(col_1_varbinary (3072));
+CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (3072));
+
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743;
+
+# Add 3 more indexes.
+# Update used to hang but now ER_UNDO_RECORD_TOO_BIG is reported;
+# Bug#12547647 - UPDATE LOGGING COULD EXCEED UNDO LOG PAGE SIZE
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (3072));
+CREATE INDEX prefix_idx4 ON worklog5743(col_4_blob (3072));
+CREATE INDEX prefix_idx5 ON worklog5743(col_5_text (3072));
+BEGIN;
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SHOW WARNINGS;
+ROLLBACK;
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# Create multiple prefix index. We can not create prefix index length > 16K as
+# we write in undo log page which of 16K size.
+# so we can create max 5 prefix index of length 3072 on table.
+# Similar to above case but with transactions
+CREATE TABLE worklog5743 (
+col_1_varbinary VARBINARY (4000) , col_2_varchar VARCHAR (4000) ,
+col_3_text TEXT (4000), col_4_blob BLOB (4000),col_5_text TEXT (4000),
+col_6_varchar VARCHAR (4000), col_7_binary BINARY (255)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+
+
+# Update used to hang if we create following 5 indexes. Fixed in;
+# Bug#12547647 - UPDATE LOGGING COULD EXCEED UNDO LOG PAGE SIZE
+CREATE INDEX prefix_idx1 ON worklog5743(col_1_varbinary (3072));
+CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (3072));
+CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (3072));
+CREATE INDEX prefix_idx4 ON worklog5743(col_4_blob (3072));
+CREATE INDEX prefix_idx5 ON worklog5743(col_5_text (3072));
+
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+ROLLBACK;
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+COMMIT;
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+ROLLBACK;
+BEGIN;
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+SHOW WARNINGS;
+ROLLBACK;
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# Prefix index with utf8 charset
+# utf8 charcter takes 3 bytes in mysql so prefix index limit is 3072/3 = 1024
+CREATE TABLE worklog5743 (
+col_1_text TEXT (4000) CHARACTER SET 'utf8',
+col_2_text TEXT (4000) CHARACTER SET 'utf8',
+PRIMARY KEY (col_1_text(1024))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (1024));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) FROM worklog5743;
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+# Prefix index with utf8 charset + varchar.
+CREATE TABLE worklog5743 (col_1_varchar VARCHAR (4000) CHARACTER SET 'utf8',
+col_2_varchar VARCHAR (4000) CHARACTER SET 'utf8' ,
+PRIMARY KEY (col_1_varchar(1024))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (1024));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) FROM worklog5743;
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# prefinx index on utf8 charset with transaction
+CREATE TABLE worklog5743 (
+col_1_varbinary VARBINARY (4000) ,
+col_2_varchar VARCHAR (4000) CHARACTER SET 'utf8',
+col_3_text TEXT (4000) CHARACTER SET 'utf8',
+col_4_blob BLOB (4000),col_5_text TEXT (4000),
+col_6_varchar VARCHAR (4000), col_7_binary BINARY (255)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+
+
+CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (500));
+CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (500));
+
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+ROLLBACK;
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+COMMIT;
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+ROLLBACK;
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000),
+REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
+REPEAT("a", 4000) , REPEAT("a", 255)
+);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+
+#------------------------------------------------------------------------------
+# Prefix index with utf8 charset on TEXT data type with actual utf8 character
+# like "स" and "क"
+CREATE TABLE worklog5743 (
+col_1_text TEXT (4000) CHARACTER SET 'utf8',
+col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(1024))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("स", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (1024));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("स", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_text = REPEAT("क", 4000)
+WHERE col_1_text = REPEAT("स", 4000) AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("क", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000);
+SELECT col_1_text = REPEAT("क", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+
+#------------------------------------------------------------------------------
+# Prefix index with transaction when 2 client are ruuning there transaction
+# in different sessions.With ISOLATION LEVEL as REPEATABLE READ and
+# READ UNCOMMITTED.
+CREATE TABLE worklog5743 (
+col_1_text TEXT(4000) , col_2_text TEXT(4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200));
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+
+--connect (con1,localhost,root,,)
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+
+--connect (con2,localhost,root,,)
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200));
+# Uncomment after Bug#12552164 - TRANSACTION CAN NOT SEE OLD VERSION ROWS THAT
+# BEING UPDATED
+#UPDATE worklog5743 SET col_1_varchar = REPEAT("d", 200) WHERE col_1_varchar =
+#REPEAT("a", 200) AND col_2_varchar = REPEAT("o", 200);
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+
+--connection con1
+select @@session.tx_isolation;
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+select @@session.tx_isolation;
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+
+START TRANSACTION;
+
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+
+--connection con2
+COMMIT;
+# Wait for commit
+let $wait_condition=SELECT COUNT(*)=0 FROM information_schema.processlist
+WHERE info='COMMIT';
+--source include/wait_condition.inc
+
+--connection con1
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+COMMIT;
+
+--connection default
+DROP TABLE worklog5743;
+
+
+#------------------------------------------------------------------------------
+# Prefix index with transaction when 2 client are ruuning there transaction
+# in different sessions.With ISOLATION LEVEL as REPEATABLE READ and
+# READ UNCOMMITTED. Same as above case but con2 starts tnx before con1
+
+CREATE TABLE worklog5743 (
+col_1_text TEXT(4000) , col_2_text TEXT(4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200));
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+
+--connection con1
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+START TRANSACTION;
+
+--connection con2
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("a", 200);
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+COMMIT;
+# Wait for commit
+let $wait_condition=SELECT COUNT(*)=0 FROM information_schema.processlist
+WHERE info='COMMIT';
+--source include/wait_condition.inc
+
+--connection con1
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+select @@session.tx_isolation;
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+COMMIT;
+
+--connection default
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+
+# Prefix index with transaction when 2 client are ruuning there transaction
+# in different sessions.With ISOLATION LEVEL as REPEATABLE READ and
+# READ UNCOMMITTED. Same as above cases but with ROLLBACK
+
+CREATE TABLE worklog5743 (
+col_1_text TEXT(4000) , col_2_text TEXT(4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200));
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+
+--connection con1
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+START TRANSACTION;
+
+--connection con2
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("a", 200);
+SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+ROLLBACK;
+# Wait for rollback
+let $wait_condition=SELECT COUNT(*)=0 FROM information_schema.processlist
+WHERE info='COMMIT';
+--source include/wait_condition.inc
+--disconnect con2
+
+--connection con1
+SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+COMMIT;
+
+--connection default
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# Select queries on prefix index column as index will be used in queries.
+# Use few select functions , join condition , subqueries.
+
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+
+# Select with Join
+SELECT tbl1.col_1_varchar = tbl2.col_1_varchar
+FROM worklog5743 tbl1 , worklog5743 tbl2
+WHERE tbl1.col_1_varchar = tbl2.col_1_varchar ;
+
+# Select in subquey
+SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1
+WHERE col_1_varchar IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2) ;
+SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1
+WHERE col_1_varchar NOT IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2) ;
+SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 WHERE
+col_1_varchar IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2)
+AND col_1_varchar = REPEAT("c", 4000);
+SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1
+WHERE col_1_varchar in (
+SELECT tbl2.col_1_varchar FROM worklog5743 tbl2
+WHERE tbl1.col_1_varchar != tbl2.col_1_varchar
+) ;
+SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1
+WHERE col_1_varchar in (
+SELECT tbl2.col_1_varchar FROM worklog5743 tbl2
+WHERE tbl1.col_1_varchar = tbl2.col_1_varchar
+) ;
+
+# function
+SELECT
+REVERSE(col_1_varchar) = REPEAT("c", 4000) ,
+REVERSE(REVERSE(col_1_varchar)) = REPEAT("c", 4000)
+FROM worklog5743;
+SELECT
+UPPER(col_1_varchar) = REPEAT("c", 4000) ,
+UPPER(col_1_varchar) = REPEAT("C", 4000) ,
+LOWER(UPPER(col_1_varchar)) = REPEAT("c", 4000)
+FROM worklog5743;
+SELECT
+col_1_varchar = REPEAT("c", 4000)
+FROM worklog5743 WHERE col_1_varchar like '%c__%';
+SELECT SUBSTRING(INSERT(col_1_varchar, 1, 4, 'kkkk'),1,10) FROM worklog5743 ;
+SELECT CONCAT(SUBSTRING(col_1_varchar,-5,3),'append') FROM worklog5743 ;
+
+
+DROP TABLE worklog5743;
+
+#------------------------------------------------------------------------------
+# Prefix index with NULL values
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) ,
+col_2_varchar VARCHAR (4000) ,
+UNIQUE INDEX (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743
+VALUES(concat(REPEAT("a", 2000),REPEAT("b", 1000),REPEAT("c", 1000)), REPEAT("o", 4000));
+INSERT INTO worklog5743
+VALUES(concat(REPEAT("a", 2000),REPEAT("b", 2000)), REPEAT("o", 4000));
+INSERT INTO worklog5743 VALUES(NULL,NULL);
+INSERT INTO worklog5743 VALUES(NULL,NULL);
+# check IS
+SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE
+FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ;
+SELECT col_1_varchar FROM worklog5743 WHERE col_1_varchar IS NULL;
+SELECT col_1_varchar = concat(REPEAT("a", 2000),REPEAT("b", 2000))
+FROM worklog5743 WHERE col_1_varchar IS NOT NULL ORDER BY 1;
+
+
+DROP TABLE worklog5743;
+
+# -----------------------------------------------------------------------------
+# Try drop and add secondary prefix index
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(3072))) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+# Create index
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+# Drop index
+DROP INDEX prefix_idx ON worklog5743;
+
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+# Again add index
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+# -----------------------------------------------------------------------------
+
+# Try drop and add primary prefix index
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY `prefix_primary` (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+# Create index
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+# Drop index
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000)
+AND col_2_varchar = REPEAT("o", 4000);
+# Again add index
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar(3072));
+
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+--error ER_DUP_ENTRY
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+
+# -----------------------------------------------------------------------------
+
+# Try drop and add both (primary/secondary) prefix index
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY `prefix_primary` (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+# Create index
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+# Drop primary index
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+# Drop secondary index
+DROP INDEX prefix_idx ON worklog5743;
+
+SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000)
+WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000);
+# Again add index
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar(3072));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+--error ER_DUP_ENTRY
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000);
+SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743;
+DROP TABLE worklog5743;
+
+
+# -----------------------------------------------------------------------------
+# Drop index from differnt session
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR(4000) , col_2_varchar VARCHAR(4000) ,
+PRIMARY KEY (col_1_varchar (3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("c", 3500) , REPEAT("o", 3500));
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072));
+
+--connection con1
+SELECT col_1_varchar = REPEAT("c", 3500) , col_2_varchar = REPEAT("o", 3500)
+FROM worklog5743;
+
+--connection default
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 3500) , REPEAT("o", 3500));
+SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743
+WHERE col_2_varchar = REPEAT("o", 3500);
+COMMIT;
+
+--connection con1
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("k", 3500),REPEAT("p", 3500));
+# Drop primary index
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+UPDATE worklog5743 SET col_1_varchar = REPEAT("b", 3500)
+WHERE col_1_varchar = REPEAT("a", 3500)
+AND col_2_varchar = REPEAT("o", 3500);
+SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743
+WHERE col_2_varchar = REPEAT("o", 3500);
+
+--connection default
+DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 3500);
+SELECT col_1_varchar = REPEAT("a", 3500) FROM worklog5743
+WHERE col_2_varchar = REPEAT("p", 3500);
+
+--connection con1
+COMMIT;
+--disconnect con1
+
+--connection default
+DROP TABLE worklog5743;
+
+
+
+# -----------------------------------------------------------------------------
+# Create prefix index with length < 3072 , length = 3072 , length > 3072
+# - varbinary data type + secondary index
+CREATE TABLE worklog5743 (
+col_1_varbinary VARBINARY (4000) , col_2_varbinary VARBINARY (4000) ,
+PRIMARY KEY (col_1_varbinary(3072))) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+# Create index of 3072
+CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varbinary = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+# Drop index
+DROP INDEX prefix_idx ON worklog5743;
+SELECT col_1_varbinary = REPEAT("b", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("b", 4000)
+AND col_2_varbinary = REPEAT("p", 4000);
+
+
+# Again add index length < 3072
+CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (2000));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_varbinary = REPEAT("a", 4000) FROM worklog5743;
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+# Drop index
+DROP INDEX prefix_idx ON worklog5743;
+
+# Again add index length > 3072.
+# index prefix larger than 3072 will be truncated to 3072
+# For the ROW_FORMAT of REDUNDANT or COMPACT, which do
+# not support prefix > 767, the create index will be rejected.
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (4000));
+SET sql_mode = default;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_varbinary = REPEAT("a", 4000) FROM worklog5743;
+UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000)
+WHERE col_1_varbinary = REPEAT("a", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000);
+SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_varbinary = REPEAT("c", 4000)
+AND col_2_varbinary = REPEAT("o", 4000);
+
+
+DROP TABLE worklog5743;
+
+# -----------------------------------------------------------------------------
+# Create prefix index with length < 3072 , length = 3072 , length > 3072
+# text data type + secondary index
+CREATE TABLE worklog5743 (col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(500))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+# Create index of 3072
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (3072));
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000)
+FROM worklog5743;
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000)
+AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+# Drop index
+DROP INDEX prefix_idx ON worklog5743;
+SELECT col_1_text = REPEAT("b", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("b", 4000) AND col_2_text = REPEAT("p", 4000);
+
+# Again add index length < 3072
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (1000));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743;
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+# Drop index
+DROP INDEX prefix_idx ON worklog5743;
+
+# Again add index length > 3072.
+# index prefix larger than 3072 will be truncated to 3072
+# In STRICT mode, the statement will fail with error.
+# For ROW_FORMAT of REDUNDANT or COMPACT, which does not support prefix > 767,
+# the create index will be rejected.
+# --error ER_TOO_LONG_KEY
+CREATE INDEX prefix_idx ON worklog5743(col_1_text (4000));
+#CREATE INDEX prefix_idx ON worklog5743(col_1_text (3072));
+SHOW CREATE TABLE worklog5743;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743;
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000);
+
+DROP TABLE worklog5743;
+
+
+# -----------------------------------------------------------------------------
+# Create prefix index with length < 948 , length = 948 , length > 948
+# For compressed row type + primary key
+CREATE TABLE worklog5743 (
+col_1_text TEXT (4000) , col_2_text TEXT (4000) ,
+PRIMARY KEY (col_1_text(948))
+) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000));
+# Create index of 767
+INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000));
+SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) FROM worklog5743;
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000)
+AND col_2_text = REPEAT("o", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000)
+AND col_2_text = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000)
+AND col_2_text = REPEAT("o", 4000);
+# Drop index
+#DROP INDEX prefix_idx ON worklog5743;
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+SELECT col_1_text = REPEAT("b", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("b", 4000)
+AND col_2_text = REPEAT("p", 4000);
+
+# Again add index length < 767
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_text (700));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743;
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000)
+AND col_2_text = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000)
+AND col_2_text = REPEAT("o", 4000);
+# Drop index
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+
+# Again add index length > 948. Expect error 'to big row ' due to exceed
+# in key length.
+-- error ER_TOO_BIG_ROWSIZE
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_text (950));
+INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000));
+SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743;
+UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000)
+WHERE col_1_text = REPEAT("a", 4000)
+AND col_2_text = REPEAT("o", 4000);
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000);
+SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743
+WHERE col_1_text = REPEAT("c", 4000)
+AND col_2_text = REPEAT("o", 4000);
+
+DROP TABLE worklog5743;
+
+# -----------------------------------------------------------------------------
+# Create prefix index with length < 3072 , length = 3072 , length > 3072
+# data types VARCHAR
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , PRIMARY KEY (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar (900));
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+# Again add index length > 3072. Expect error.Length exceeds maximum supported
+# key length
+# Again add index length > 3072.
+# index prefix larger than 3072 will be truncated to 3072.
+# For ROW_FORMAT of REDUNDANT or COMPACT, which do
+# not support prefix > 767, the create index will be rejected.
+# Index length is truncated only for 'create index' , but error if we add
+# prefix index with length > 3072
+--error ER_TOO_LONG_KEY
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar (3073));
+DROP TABLE worklog5743;
+
+
+CREATE TABLE worklog5743 (
+col_1_BLOB BLOB (4000) , PRIMARY KEY (col_1_BLOB(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_BLOB (500));
+ALTER TABLE worklog5743 DROP PRIMARY KEY;
+# Negative case
+# Again add index length > 3072. Expect error.Length exceeds maximum supported
+# key length
+# Index length is truncated only for 'create index' , but error if we add
+# prefix index with length > 3072
+--error ER_TOO_LONG_KEY
+ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_BLOB (3073));
+
+DROP TABLE worklog5743;
+
+# -----------------------------------------------------------------------------
+# Error on adding larger prefix if violates unique index.
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000)
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743
+VALUES(concat(REPEAT("a", 2000),REPEAT("b", 1000),REPEAT("c", 1000)),
+REPEAT("o", 4000));
+INSERT INTO worklog5743
+VALUES(concat(REPEAT("a", 2000),REPEAT("b", 2000)), REPEAT("o", 4000));
+--error ER_DUP_ENTRY
+ALTER TABLE worklog5743 ADD PRIMARY KEY `pk_idx` (col_1_varchar(3000));
+DROP TABLE worklog5743;
+
+# -----------------------------------------------------------------------------
+--error ER_UNKNOWN_SYSTEM_VARIABLE
+set global innodb_large_prefix=0;
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+DROP TABLE worklog5743;
+
+
+# -----------------------------------------------------------------------------
+# Backward compatibility test - Index length > 767 is truncated for REDUNDANT
+# and COMPACT
+CREATE TABLE worklog5743 (
+col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
+PRIMARY KEY (col_1_varchar(767))
+) engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT('a',4000),REPEAT('b',4000));
+# Prefix index > 767 is truncated with REDUNDANT and COMPACT
+--enable_info
+CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (1000));
+--error ER_INDEX_COLUMN_TOO_LONG
+ALTER TABLE worklog5743 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE;
+--error ER_INDEX_COLUMN_TOO_LONG
+ALTER TABLE worklog5743 ROW_FORMAT=REDUNDANT, ALGORITHM=COPY;
+--disable_info
+SHOW CREATE TABLE worklog5743;
+DROP TABLE worklog5743;
diff --git a/mysql-test/suite/maria/dynamic.result b/mysql-test/suite/maria/dynamic.result
new file mode 100644
index 00000000000..1e87010e9ca
--- /dev/null
+++ b/mysql-test/suite/maria/dynamic.result
@@ -0,0 +1,4 @@
+create table t1 (a blob, b varchar(20000)) engine=aria row_format=dynamic;
+insert t1 (b) values (repeat('a', 20000));
+update t1 set b='b';
+drop table t1;
diff --git a/mysql-test/suite/maria/dynamic.test b/mysql-test/suite/maria/dynamic.test
new file mode 100644
index 00000000000..f8a1e98cd41
--- /dev/null
+++ b/mysql-test/suite/maria/dynamic.test
@@ -0,0 +1,7 @@
+#
+# MDEV-13748 Assertion `status_var.local_memory_used == 0 || !debug_assert_on_not_freed_memory' failed in virtual THD::~THD after query with INTERSECT
+#
+create table t1 (a blob, b varchar(20000)) engine=aria row_format=dynamic;
+insert t1 (b) values (repeat('a', 20000));
+update t1 set b='b';
+drop table t1;
diff --git a/mysql-test/suite/maria/lock.result b/mysql-test/suite/maria/lock.result
index 52e83eb111d..90250568ef5 100644
--- a/mysql-test/suite/maria/lock.result
+++ b/mysql-test/suite/maria/lock.result
@@ -30,3 +30,72 @@ drop table t1;
CREATE TABLE t1 (i INT) ENGINE=Aria;
LOCK TABLES t1 WRITE, t1 AS t1a WRITE;
DROP TABLE t1;
+#
+# MDEV-8200 aria bug with insert select when select is a aria table
+# (wrong result or assertion failure:
+# `table->file->stats.records > 0 || error')
+#
+CREATE TABLE t1 (f1 INT) ENGINE=Aria;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (f2 INT) ENGINE=MyISAM;
+CREATE TABLE tmp (f3 INT) engine=Aria;
+LOCK TABLE t2 WRITE, tmp WRITE, tmp AS tmp_alias WRITE, t1 WRITE;
+INSERT INTO tmp SELECT f1 FROM t1;
+INSERT INTO t2 SELECT f3 FROM tmp AS tmp_alias;
+select * from t2;
+f2
+1
+unlock tables;
+DROP TABLE t1,t2,tmp;
+#
+# Same without transactional
+#
+CREATE TABLE t1 (f1 INT) transactional=0 ENGINE=Aria;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0
+INSERT INTO t1 VALUES (2);
+CREATE TABLE t2 (f2 INT) ENGINE=MyISAM;
+CREATE TABLE tmp (f3 INT) transactional=0 engine=Aria;
+LOCK TABLE t2 WRITE, tmp WRITE, tmp AS tmp_alias WRITE, t1 WRITE;
+INSERT INTO tmp SELECT f1 FROM t1;
+INSERT INTO t2 SELECT f3 FROM tmp AS tmp_alias;
+select * from t2;
+f2
+2
+unlock tables;
+DROP TABLE t1,t2,tmp;
+#
+# Using spatical keys (disables versioning)
+#
+CREATE TABLE t1 (f1 INT, c1 geometry NOT NULL, SPATIAL KEY i1 (c1)) transactional=1 ENGINE=Aria;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` int(11) DEFAULT NULL,
+ `c1` geometry NOT NULL,
+ SPATIAL KEY `i1` (`c1`)
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1
+INSERT INTO t1 VALUES (3,
+PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
+ -18.6055555000 -66.8158332999,
+ -18.7186111000 -66.8102777000,
+ -18.7211111000 -66.9269443999,
+ -18.6086111000 -66.9327777000))'));
+CREATE TABLE t2 (f2 INT) ENGINE=MyISAM;
+CREATE TABLE tmp (f3 INT, c1 geometry NOT NULL, SPATIAL KEY i1 (c1)) transactional=1 ENGINE=Aria;
+LOCK TABLE t2 WRITE, tmp WRITE, tmp AS tmp_alias WRITE, t1 WRITE;
+INSERT INTO tmp SELECT f1,c1 FROM t1;
+INSERT INTO t2 (f2) SELECT f3 FROM tmp AS tmp_alias;
+select * from t2;
+f2
+3
+unlock tables;
+DROP TABLE t1,t2,tmp;
diff --git a/mysql-test/suite/maria/lock.test b/mysql-test/suite/maria/lock.test
index 5b6d17069e7..57447a18c55 100644
--- a/mysql-test/suite/maria/lock.test
+++ b/mysql-test/suite/maria/lock.test
@@ -50,3 +50,58 @@ drop table t1;
CREATE TABLE t1 (i INT) ENGINE=Aria;
LOCK TABLES t1 WRITE, t1 AS t1a WRITE;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-8200 aria bug with insert select when select is a aria table
+--echo # (wrong result or assertion failure:
+--echo # `table->file->stats.records > 0 || error')
+--echo #
+
+CREATE TABLE t1 (f1 INT) ENGINE=Aria;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (f2 INT) ENGINE=MyISAM;
+CREATE TABLE tmp (f3 INT) engine=Aria;
+LOCK TABLE t2 WRITE, tmp WRITE, tmp AS tmp_alias WRITE, t1 WRITE;
+INSERT INTO tmp SELECT f1 FROM t1;
+INSERT INTO t2 SELECT f3 FROM tmp AS tmp_alias;
+select * from t2;
+unlock tables;
+DROP TABLE t1,t2,tmp;
+
+--echo #
+--echo # Same without transactional
+--echo #
+
+CREATE TABLE t1 (f1 INT) transactional=0 ENGINE=Aria;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (2);
+CREATE TABLE t2 (f2 INT) ENGINE=MyISAM;
+CREATE TABLE tmp (f3 INT) transactional=0 engine=Aria;
+LOCK TABLE t2 WRITE, tmp WRITE, tmp AS tmp_alias WRITE, t1 WRITE;
+INSERT INTO tmp SELECT f1 FROM t1;
+INSERT INTO t2 SELECT f3 FROM tmp AS tmp_alias;
+select * from t2;
+unlock tables;
+DROP TABLE t1,t2,tmp;
+
+--echo #
+--echo # Using spatical keys (disables versioning)
+--echo #
+
+CREATE TABLE t1 (f1 INT, c1 geometry NOT NULL, SPATIAL KEY i1 (c1)) transactional=1 ENGINE=Aria;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (3,
+PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
+ -18.6055555000 -66.8158332999,
+ -18.7186111000 -66.8102777000,
+ -18.7211111000 -66.9269443999,
+ -18.6086111000 -66.9327777000))'));
+CREATE TABLE t2 (f2 INT) ENGINE=MyISAM;
+CREATE TABLE tmp (f3 INT, c1 geometry NOT NULL, SPATIAL KEY i1 (c1)) transactional=1 ENGINE=Aria;
+LOCK TABLE t2 WRITE, tmp WRITE, tmp AS tmp_alias WRITE, t1 WRITE;
+INSERT INTO tmp SELECT f1,c1 FROM t1;
+INSERT INTO t2 (f2) SELECT f3 FROM tmp AS tmp_alias;
+select * from t2;
+unlock tables;
+DROP TABLE t1,t2,tmp;
diff --git a/mysql-test/suite/maria/maria.result b/mysql-test/suite/maria/maria.result
index c7a08c4d95e..805fb536848 100644
--- a/mysql-test/suite/maria/maria.result
+++ b/mysql-test/suite/maria/maria.result
@@ -901,7 +901,7 @@ CREATE TABLE t1 (
PRIMARY KEY (`_id`),
UNIQUE KEY `sequence_name_index` (`name`(50)),
KEY (`length_`)
-) DEFAULT CHARSET=latin1;
+) DEFAULT CHARSET=latin1 row_format=dynamic;
INSERT INTO t1 VALUES
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
@@ -924,9 +924,9 @@ _id
8
9
DELETE FROM t1 WHERE _id < 8;
-SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 2 # # # # 0 # # # # # #
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
+table_name engine version row_format Table_rows Data_free create_options table_comment
+t1 Aria 10 Dynamic 2 140 row_format=DYNAMIC
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
@@ -936,9 +936,9 @@ test.t1 optimize status OK
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
-SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 2 # # # # 0 # # # # # #
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
+table_name engine version row_format Table_rows Data_free create_options table_comment
+t1 Aria 10 Dynamic 2 0 row_format=DYNAMIC
SELECT _id FROM t1;
_id
8
@@ -960,7 +960,7 @@ CREATE TABLE t1 (
PRIMARY KEY (`_id`),
UNIQUE KEY `sequence_name_index` (`name`(50)),
KEY (`length_`)
-) DEFAULT CHARSET=latin1;
+) DEFAULT CHARSET=latin1 row_format=dynamic;
INSERT INTO t1 VALUES
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
@@ -983,9 +983,9 @@ _id
8
9
DELETE FROM t1 WHERE _id < 8;
-SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 2 # # # # 0 # # # # # #
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
+table_name engine version row_format Table_rows Data_free create_options table_comment
+t1 Aria 10 Dynamic 2 140 row_format=DYNAMIC
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
@@ -995,9 +995,9 @@ test.t1 repair status OK
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
-SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 2 # # # # 0 # # # # # #
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
+table_name engine version row_format Table_rows Data_free create_options table_comment
+t1 Aria 10 Dynamic 2 140 row_format=DYNAMIC
SELECT _id FROM t1;
_id
8
@@ -1761,28 +1761,28 @@ a
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE INDEX (c1), INDEX (c2));
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 0 # # # 8192 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 Aria 10 Page 0 # # # 8192 # # # # # # # # N
INSERT INTO t1 VALUES (1,1);
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 1 # # # 24576 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 Aria 10 Page 1 # # # 24576 # # # # # # # # N
ALTER TABLE t1 DISABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 1 # # # 24576 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 Aria 10 Page 1 # # # 24576 # # # # # # # # N
ALTER TABLE t1 ENABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 1 # # # 24576 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 Aria 10 Page 1 # # # 24576 # # # # # # # # N
ALTER TABLE t1 DISABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 1 # # # 24576 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 Aria 10 Page 1 # # # 24576 # # # # # # # # N
ALTER TABLE t1 ENABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 1 # # # 24576 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 Aria 10 Page 1 # # # 24576 # # # # # # # # N
# Enable keys with parallel repair
SET @@aria_repair_threads=2;
ALTER TABLE t1 DISABLE KEYS;
@@ -2734,6 +2734,17 @@ count(*)
13
drop table t1;
#
+# MDEV-14690: Assertion `page_link == &fake_link' failed in
+# pagecache_write_part
+#
+CREATE TABLE t1 (a CHAR(8), b CHAR(8), c CHAR(8) NOT NULL DEFAULT '', f FLOAT, KEY(f)) ENGINE=Aria;
+INSERT INTO t1 (a) VALUES ('foo');
+DELETE FROM t1 WHERE c < 'bar';
+ALTER TABLE t1 DISABLE KEYS;
+INSERT INTO t1 (b) VALUES ('');
+ALTER TABLE t1 ENABLE KEYS;
+DROP TABLE t1;
+#
# BUG#47444 - --myisam_repair_threads > 1 can result in all index
# cardinalities=1
#
diff --git a/mysql-test/suite/maria/maria.test b/mysql-test/suite/maria/maria.test
index 24b97577d5e..34bd4a638bb 100644
--- a/mysql-test/suite/maria/maria.test
+++ b/mysql-test/suite/maria/maria.test
@@ -839,7 +839,7 @@ CREATE TABLE t1 (
PRIMARY KEY (`_id`),
UNIQUE KEY `sequence_name_index` (`name`(50)),
KEY (`length_`)
-) DEFAULT CHARSET=latin1;
+) DEFAULT CHARSET=latin1 row_format=dynamic;
#
INSERT INTO t1 VALUES
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
@@ -854,13 +854,11 @@ INSERT INTO t1 VALUES
#
SELECT _id FROM t1;
DELETE FROM t1 WHERE _id < 8;
---replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
-SHOW TABLE STATUS LIKE 't1';
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
CHECK TABLE t1 EXTENDED;
OPTIMIZE TABLE t1;
CHECK TABLE t1 EXTENDED;
---replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
-SHOW TABLE STATUS LIKE 't1';
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
SELECT _id FROM t1;
DROP TABLE t1;
#
@@ -881,7 +879,7 @@ CREATE TABLE t1 (
PRIMARY KEY (`_id`),
UNIQUE KEY `sequence_name_index` (`name`(50)),
KEY (`length_`)
-) DEFAULT CHARSET=latin1;
+) DEFAULT CHARSET=latin1 row_format=dynamic;
#
INSERT INTO t1 VALUES
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
@@ -896,13 +894,11 @@ INSERT INTO t1 VALUES
#
SELECT _id FROM t1;
DELETE FROM t1 WHERE _id < 8;
---replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
-SHOW TABLE STATUS LIKE 't1';
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
CHECK TABLE t1 EXTENDED;
REPAIR TABLE t1 QUICK;
CHECK TABLE t1 EXTENDED;
---replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
-SHOW TABLE STATUS LIKE 't1';
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
SELECT _id FROM t1;
DROP TABLE t1;
#
@@ -1082,22 +1078,22 @@ DROP TABLE t1;
# Bug#4692 - DISABLE/ENABLE KEYS waste a space
#
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE INDEX (c1), INDEX (c2));
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
INSERT INTO t1 VALUES (1,1);
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 DISABLE KEYS;
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 ENABLE KEYS;
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 DISABLE KEYS;
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 ENABLE KEYS;
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
#--exec ls -log var/mysqld.1/data/test/t1
#--exec aria_chk -dvv var/mysqld.1/data/test/t1
@@ -1975,6 +1971,21 @@ select count(*) from t1;
drop table t1;
--echo #
+--echo # MDEV-14690: Assertion `page_link == &fake_link' failed in
+--echo # pagecache_write_part
+--echo #
+
+CREATE TABLE t1 (a CHAR(8), b CHAR(8), c CHAR(8) NOT NULL DEFAULT '', f FLOAT, KEY(f)) ENGINE=Aria;
+INSERT INTO t1 (a) VALUES ('foo');
+DELETE FROM t1 WHERE c < 'bar';
+ALTER TABLE t1 DISABLE KEYS;
+INSERT INTO t1 (b) VALUES ('');
+ALTER TABLE t1 ENABLE KEYS;
+
+# Cleanup
+DROP TABLE t1;
+
+--echo #
--echo # BUG#47444 - --myisam_repair_threads > 1 can result in all index
--echo # cardinalities=1
--echo #
diff --git a/mysql-test/suite/maria/max_length.result b/mysql-test/suite/maria/max_length.result
index 049b92eafe5..93478e033f4 100644
--- a/mysql-test/suite/maria/max_length.result
+++ b/mysql-test/suite/maria/max_length.result
@@ -6,9 +6,9 @@ create table t1 (id int(10) unsigned not null auto_increment primary key, v varc
create table t2 (id int(10) unsigned not null auto_increment primary key, v varchar(1000), b blob) row_format=page max_rows=20000000 engine=aria;
lock tables t1 write,t2 write;
show table status like "t_";
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 Aria 10 Page 0 0 8192 268320768 8192 0 1 # # # latin1_swedish_ci NULL max_rows=2 row_format=PAGE
-t2 Aria 10 Page 0 0 8192 17592186011648 8192 0 1 # # # latin1_swedish_ci NULL max_rows=20000000 row_format=PAGE
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 Aria 10 Page 0 0 8192 268320768 8192 0 1 # # # latin1_swedish_ci NULL max_rows=2 row_format=PAGE 536862720 N
+t2 Aria 10 Page 0 0 8192 17592186011648 8192 0 1 # # # latin1_swedish_ci NULL max_rows=20000000 row_format=PAGE 536862720 N
insert into t1 values(null, repeat("ab",100),repeat("def",1000));
insert into t1 values(null, repeat("de",200),repeat("ghi",2000));
insert into t1 values(null, repeat("fe",300),repeat("ghi",3000));
@@ -54,3 +54,115 @@ Table Op Msg_type Msg_text
test.t1 check warning Datafile is almost full, 268230656 of 268320768 used
test.t1 check status OK
drop table t1,t2;
+create table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=FIXED min_rows=1000000;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(10) unsigned DEFAULT NULL,
+ `c2` char(80) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 MIN_ROWS=1000000 PAGE_CHECKSUM=1 ROW_FORMAT=FIXED
+insert into t1 select seq,seq from seq_1_to_100000;
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=FIXED;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(10) unsigned DEFAULT NULL,
+ `c2` char(80) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=FIXED
+insert into t1 select seq,seq from seq_1_to_100000;
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=PAGE TRANSACTIONAL=0;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(10) unsigned DEFAULT NULL,
+ `c2` char(80) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE TRANSACTIONAL=0
+insert into t1 select seq,seq from seq_1_to_100000;
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=FIXED MAX_ROWS=10;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(10) unsigned DEFAULT NULL,
+ `c2` char(80) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 MAX_ROWS=10 PAGE_CHECKSUM=1 ROW_FORMAT=FIXED
+insert into t1 select seq,seq from seq_1_to_100000;
+ERROR HY000: The table 't1' is full
+select count(*) from t1;
+count(*)
+65535
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=DYNAMIC MAX_ROWS=10;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(10) unsigned DEFAULT NULL,
+ `c2` char(80) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 MAX_ROWS=10 PAGE_CHECKSUM=1 ROW_FORMAT=DYNAMIC
+insert into t1 select seq,seq from seq_1_to_100000;
+ERROR HY000: The table 't1' is full
+select count(*) from t1;
+count(*)
+3276
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Datafile is almost full, 65520 of 65535 used
+test.t1 check status OK
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=PAGE MAX_ROWS=10;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(10) unsigned DEFAULT NULL,
+ `c2` char(80) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 MAX_ROWS=10 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE
+insert into t1 select seq,seq from seq_1_to_100000;
+select count(*) from t1;
+count(*)
+100000
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=PAGE MAX_ROWS=10;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(10) unsigned DEFAULT NULL,
+ `c2` char(80) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 MAX_ROWS=10 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE
+insert into t1 select seq,seq from seq_1_to_10000000;
+ERROR HY000: The table 't1' is full
+select count(*) from t1;
+count(*)
+6189940
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Datafile is almost full, 268320768 of 268320768 used
+test.t1 check status OK
+show table status like "t1";
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 Aria 10 Page 6189940 43 268320768 268320768 8192 0 NULL # # # latin1_swedish_ci NULL max_rows=10 row_format=PAGE 137438945280 N
+create index seq on t1(c1);
+show table status like "t1";
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 Aria 10 Page 6189940 43 268320768 268320768 49750016 0 NULL # # # latin1_swedish_ci NULL max_rows=10 page_checksum=1 row_format=PAGE 536862720 N
+drop table t1;
diff --git a/mysql-test/suite/maria/max_length.test b/mysql-test/suite/maria/max_length.test
index 68ad1e22aa9..fdfe2aae4ac 100644
--- a/mysql-test/suite/maria/max_length.test
+++ b/mysql-test/suite/maria/max_length.test
@@ -2,6 +2,7 @@
# This test will use around 1.3G of disk space!
--source include/have_maria.inc
+--source include/have_sequence.inc
--source include/big_test.inc
drop table if exists t1,t2;
@@ -50,3 +51,79 @@ insert into t1 (v,b) select v,b from t2;
check table t1;
drop table t1,t2;
+
+#
+# Check that we don't get table-is-full
+#
+
+create table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=FIXED min_rows=1000000;
+show create table t1;
+insert into t1 select seq,seq from seq_1_to_100000;
+
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=FIXED;
+show create table t1;
+insert into t1 select seq,seq from seq_1_to_100000;
+
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=PAGE TRANSACTIONAL=0;
+show create table t1;
+insert into t1 select seq,seq from seq_1_to_100000;
+
+#
+# For these we should get table is full error
+#
+
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=FIXED MAX_ROWS=10;
+show create table t1;
+--error ER_RECORD_FILE_FULL
+insert into t1 select seq,seq from seq_1_to_100000;
+select count(*) from t1;
+
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=DYNAMIC MAX_ROWS=10;
+show create table t1;
+--error ER_RECORD_FILE_FULL
+insert into t1 select seq,seq from seq_1_to_100000;
+select count(*) from t1;
+check table t1;
+
+# PAGE uses 3 byte pointers as minimum, which can handle up to 200M files
+
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=PAGE MAX_ROWS=10;
+show create table t1;
+insert into t1 select seq,seq from seq_1_to_100000;
+select count(*) from t1;
+check table t1;
+drop table t1;
+
+create or replace table t1 (
+c1 int unsigned,
+c2 char(80)
+) Engine=ARIA ROW_FORMAT=PAGE MAX_ROWS=10;
+show create table t1;
+--error ER_RECORD_FILE_FULL
+insert into t1 select seq,seq from seq_1_to_10000000;
+select count(*) from t1;
+check table t1;
+--replace_column 12 # 13 # 14 #
+show table status like "t1";
+create index seq on t1(c1);
+--replace_column 12 # 13 # 14 #
+show table status like "t1";
+drop table t1;
diff --git a/mysql-test/suite/maria/repair.result b/mysql-test/suite/maria/repair.result
new file mode 100644
index 00000000000..6bb9e1b5b9e
--- /dev/null
+++ b/mysql-test/suite/maria/repair.result
@@ -0,0 +1,24 @@
+CREATE TABLE t1 (i INT) ENGINE=Aria TRANSACTIONAL=1;
+INSERT t1 VALUES (1);
+LOCK TABLE t1 WRITE;
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+SELECT * FROM INFORMATION_SCHEMA.TABLES;
+SELECT * FROM t1;
+i
+1
+UNLOCK TABLES;
+DROP TABLE t1;
+CREATE TABLE t1 (i INT) ENGINE=Aria TRANSACTIONAL=1;
+INSERT t1 VALUES (1);
+LOCK TABLE t1 WRITE;
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+SELECT * FROM INFORMATION_SCHEMA.TABLES;
+SELECT * FROM t1;
+i
+1
+UNLOCK TABLES;
+DROP TABLE t1;
diff --git a/mysql-test/suite/maria/repair.test b/mysql-test/suite/maria/repair.test
new file mode 100644
index 00000000000..2f713950d3e
--- /dev/null
+++ b/mysql-test/suite/maria/repair.test
@@ -0,0 +1,24 @@
+#
+# MDEV-11539 test_if_reopen: Assertion `strcmp(share->unique_file_name,filename) || share->last_version' failed upon select from I_S
+#
+CREATE TABLE t1 (i INT) ENGINE=Aria TRANSACTIONAL=1;
+INSERT t1 VALUES (1);
+LOCK TABLE t1 WRITE;
+REPAIR TABLE t1;
+--disable_result_log
+SELECT * FROM INFORMATION_SCHEMA.TABLES;
+--enable_result_log
+SELECT * FROM t1;
+UNLOCK TABLES;
+DROP TABLE t1;
+
+CREATE TABLE t1 (i INT) ENGINE=Aria TRANSACTIONAL=1;
+INSERT t1 VALUES (1);
+LOCK TABLE t1 WRITE;
+OPTIMIZE TABLE t1;
+--disable_result_log
+SELECT * FROM INFORMATION_SCHEMA.TABLES;
+--enable_result_log
+SELECT * FROM t1;
+UNLOCK TABLES;
+DROP TABLE t1;
diff --git a/mysql-test/suite/mariabackup/apply-log-only-incr.result b/mysql-test/suite/mariabackup/apply-log-only-incr.result
index 2baed8c1db9..917a9647511 100644
--- a/mysql-test/suite/mariabackup/apply-log-only-incr.result
+++ b/mysql-test/suite/mariabackup/apply-log-only-incr.result
@@ -3,9 +3,16 @@ CREATE TABLE t(a INT UNSIGNED PRIMARY KEY) ENGINE INNODB;
INSERT INTO t VALUES(0);
COMMIT;
start transaction;
-NOT FOUND /Rollback of trx with id/ in current_test
+connect flush_log,localhost,root,,;
+BEGIN;
+DELETE FROM t LIMIT 1;
+SET GLOBAL innodb_flush_log_at_trx_commit = 1;
+ROLLBACK;
+disconnect flush_log;
+connection default;
+NOT FOUND /Rolled back recovered transaction/ in current_test
# expect NOT FOUND
-NOT FOUND /Rollback of trx with id/ in current_test
+NOT FOUND /Rolled back recovered transaction/ in current_test
# expect NOT FOUND
commit;
SELECT count(*) FROM t;
diff --git a/mysql-test/suite/mariabackup/apply-log-only-incr.test b/mysql-test/suite/mariabackup/apply-log-only-incr.test
index aa5110cc51e..25cb3a82023 100644
--- a/mysql-test/suite/mariabackup/apply-log-only-incr.test
+++ b/mysql-test/suite/mariabackup/apply-log-only-incr.test
@@ -26,6 +26,13 @@ eval INSERT t VALUES(201-$n);
dec $n;
}
--enable_query_log
+connect (flush_log,localhost,root,,);
+BEGIN;
+DELETE FROM t LIMIT 1;
+SET GLOBAL innodb_flush_log_at_trx_commit = 1;
+ROLLBACK;
+disconnect flush_log;
+connection default;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --ftwrl-wait-timeout=5 --ftwrl-wait-threshold=300 --ftwrl-wait-query-type=all --target-dir=$incremental_dir --incremental-basedir=$basedir ;
@@ -33,7 +40,7 @@ exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir ;
--enable_result_log
let SEARCH_FILE=$MYSQLTEST_VARDIR/log/current_test;
---let SEARCH_PATTERN= Rollback of trx with id
+--let SEARCH_PATTERN= Rolled back recovered transaction
--source include/search_pattern_in_file.inc
--echo # expect NOT FOUND
diff --git a/mysql-test/suite/mariabackup/apply-log-only.result b/mysql-test/suite/mariabackup/apply-log-only.result
index 04b9c0d8ee2..d618a7bbeb5 100644
--- a/mysql-test/suite/mariabackup/apply-log-only.result
+++ b/mysql-test/suite/mariabackup/apply-log-only.result
@@ -2,7 +2,7 @@ call mtr.add_suppression("InnoDB: New log files created");
CREATE TABLE t(a varchar(60)) ENGINE INNODB;
start transaction;
INSERT INTO t VALUES(1);
-NOT FOUND /Rollback of trx with id/ in current_test
+NOT FOUND /Rolled back recovered transaction/ in current_test
# expect NOT FOUND
SELECT count(*) FROM t;
count(*)
diff --git a/mysql-test/suite/mariabackup/apply-log-only.test b/mysql-test/suite/mariabackup/apply-log-only.test
index 96a251fc03b..5a3c45f2914 100644
--- a/mysql-test/suite/mariabackup/apply-log-only.test
+++ b/mysql-test/suite/mariabackup/apply-log-only.test
@@ -14,7 +14,7 @@ exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir
exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir ;
let SEARCH_FILE=$MYSQLTEST_VARDIR/log/current_test;
---let SEARCH_PATTERN= Rollback of trx with id
+--let SEARCH_PATTERN= Rolled back recovered transaction
--source include/search_pattern_in_file.inc
--echo # expect NOT FOUND
diff --git a/mysql-test/suite/mariabackup/binlog.result b/mysql-test/suite/mariabackup/binlog.result
new file mode 100644
index 00000000000..4f8ed4185ce
--- /dev/null
+++ b/mysql-test/suite/mariabackup/binlog.result
@@ -0,0 +1,8 @@
+CREATE TABLE t(a varchar(60)) ENGINE INNODB;
+INSERT INTO t VALUES(1);
+SHOW VARIABLES like 'log_bin';
+Variable_name Value
+log_bin ON
+FOUND 1 /Last binlog file .*, position .*/ in current_test
+# expect FOUND
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/binlog.test b/mysql-test/suite/mariabackup/binlog.test
new file mode 100644
index 00000000000..998397bb495
--- /dev/null
+++ b/mysql-test/suite/mariabackup/binlog.test
@@ -0,0 +1,25 @@
+--source include/have_innodb.inc
+--source include/have_log_bin.inc
+
+let $basedir=$MYSQLTEST_VARDIR/tmp/backup;
+
+CREATE TABLE t(a varchar(60)) ENGINE INNODB;
+INSERT INTO t VALUES(1);
+
+SHOW VARIABLES like 'log_bin';
+
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir;
+--enable_result_log
+
+exec $XTRABACKUP --prepare --binlog-info=1 --apply-log-only --target-dir=$basedir ;
+
+let SEARCH_FILE=$MYSQLTEST_VARDIR/log/current_test;
+--let SEARCH_PATTERN= Last binlog file .*, position .*
+--source include/search_pattern_in_file.inc
+--echo # expect FOUND
+
+DROP TABLE t;
+
+# Cleanup
+rmdir $basedir;
diff --git a/mysql-test/suite/mariabackup/extra_lsndir.result b/mysql-test/suite/mariabackup/extra_lsndir.result
new file mode 100644
index 00000000000..a25c45a13d1
--- /dev/null
+++ b/mysql-test/suite/mariabackup/extra_lsndir.result
@@ -0,0 +1,2 @@
+xtrabackup_checkpoints
+xtrabackup_info
diff --git a/mysql-test/suite/mariabackup/extra_lsndir.test b/mysql-test/suite/mariabackup/extra_lsndir.test
new file mode 100644
index 00000000000..092ee34c6cc
--- /dev/null
+++ b/mysql-test/suite/mariabackup/extra_lsndir.test
@@ -0,0 +1,9 @@
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+let $extra_lsndir=$MYSQLTEST_VARDIR/tmp/extra_lsndir;
+mkdir $extra_lsndir;
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --extra-lsndir=$extra_lsndir;
+--enable_result_log
+list_files $extra_lsndir;
+rmdir $extra_lsndir;
+rmdir $targetdir;
diff --git a/mysql-test/suite/mariabackup/huge_lsn.opt b/mysql-test/suite/mariabackup/huge_lsn.opt
new file mode 100644
index 00000000000..74a6450a1ef
--- /dev/null
+++ b/mysql-test/suite/mariabackup/huge_lsn.opt
@@ -0,0 +1,6 @@
+--innodb-encrypt-log=ON
+--plugin-load-add=$FILE_KEY_MANAGEMENT_SO
+--loose-file-key-management
+--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/filekeys-data.key
+--loose-file-key-management-filename=$MTR_SUITE_DIR/filekeys-data.enc
+--loose-file-key-management-encryption-algorithm=aes_cbc
diff --git a/mysql-test/suite/mariabackup/huge_lsn.result b/mysql-test/suite/mariabackup/huge_lsn.result
index f8c4d3b5fb3..e7c4cc9471d 100644
--- a/mysql-test/suite/mariabackup/huge_lsn.result
+++ b/mysql-test/suite/mariabackup/huge_lsn.result
@@ -1,10 +1,11 @@
#
# MDEV-13416 mariabackup fails with EFAULT "Bad Address"
#
-FOUND 1 /InnoDB: 5\.7\.\d+ started; log sequence number 17592186044428/ in mysqld.1.err
+FOUND 1 /InnoDB: New log files created, LSN=175964\d{8}/ in mysqld.1.err
CREATE TABLE t(i INT) ENGINE INNODB;
INSERT INTO t VALUES(1);
# xtrabackup backup
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
INSERT INTO t VALUES(2);
# xtrabackup prepare
# shutdown server
diff --git a/mysql-test/suite/mariabackup/huge_lsn.test b/mysql-test/suite/mariabackup/huge_lsn.test
index 8b1ae338274..9e72f0ad8d0 100644
--- a/mysql-test/suite/mariabackup/huge_lsn.test
+++ b/mysql-test/suite/mariabackup/huge_lsn.test
@@ -1,4 +1,5 @@
--source include/not_embedded.inc
+--source include/have_file_key_management.inc
--echo #
--echo # MDEV-13416 mariabackup fails with EFAULT "Bad Address"
@@ -16,7 +17,7 @@ binmode FILE;
my $ps= $ENV{INNODB_PAGE_SIZE};
my $page;
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
-substr($page,26,8) = pack("NN", 4096, 0);
+substr($page,26,8) = pack("NN", 4096, ~1024);
substr($page,0,4)=pack("N",0xdeadbeef);
substr($page,$ps-8,4)=pack("N",0xdeadbeef);
sysseek(FILE, 0, 0) || die "Unable to rewind $file\n";
@@ -28,7 +29,7 @@ EOF
--source include/start_mysqld.inc
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
---let SEARCH_PATTERN= InnoDB: 5\.7\.\d+ started; log sequence number 17592186044428
+--let SEARCH_PATTERN= InnoDB: New log files created, LSN=175964\d{8}
--source include/search_pattern_in_file.inc
CREATE TABLE t(i INT) ENGINE INNODB;
@@ -39,6 +40,7 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir;
--enable_result_log
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
INSERT INTO t VALUES(2);
echo # xtrabackup prepare;
--disable_result_log
diff --git a/mysql-test/suite/mariabackup/log_checksum_mismatch.result b/mysql-test/suite/mariabackup/log_checksum_mismatch.result
new file mode 100644
index 00000000000..806a5e62cb6
--- /dev/null
+++ b/mysql-test/suite/mariabackup/log_checksum_mismatch.result
@@ -0,0 +1,14 @@
+CREATE TABLE t(i INT) ENGINE INNODB;
+INSERT INTO t VALUES(1);
+# xtrabackup backup
+FOUND 1 /Invalid log block checksum/ in backup.log
+INSERT INTO t VALUES(2);
+# xtrabackup prepare
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT * FROM t;
+i
+1
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/log_checksum_mismatch.test b/mysql-test/suite/mariabackup/log_checksum_mismatch.test
new file mode 100644
index 00000000000..f041b0aeedd
--- /dev/null
+++ b/mysql-test/suite/mariabackup/log_checksum_mismatch.test
@@ -0,0 +1,32 @@
+--source include/have_debug.inc
+
+CREATE TABLE t(i INT) ENGINE INNODB;
+INSERT INTO t VALUES(1);
+echo # xtrabackup backup;
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+let $backuplog=$MYSQLTEST_VARDIR/tmp/backup.log;
+
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,log_intermittent_checksum_mismatch > $backuplog;
+--enable_result_log
+
+--let SEARCH_RANGE = 10000000
+--let SEARCH_PATTERN=Invalid log block checksum
+--let SEARCH_FILE=$backuplog
+--source include/search_pattern_in_file.inc
+remove_file $backuplog;
+
+
+INSERT INTO t VALUES(2);
+
+
+echo # xtrabackup prepare;
+--disable_result_log
+exec $XTRABACKUP --prepare --target-dir=$targetdir;
+-- source include/restart_and_restore.inc
+--enable_result_log
+
+SELECT * FROM t;
+DROP TABLE t;
+rmdir $targetdir;
+
diff --git a/mysql-test/suite/mariabackup/mdev-14447.opt b/mysql-test/suite/mariabackup/mdev-14447.opt
new file mode 100644
index 00000000000..5ac67e950c4
--- /dev/null
+++ b/mysql-test/suite/mariabackup/mdev-14447.opt
@@ -0,0 +1 @@
+--sequence --innodb-data-file-path=ibdata_first:3M;ibdata_second:1M:autoextend \ No newline at end of file
diff --git a/mysql-test/suite/mariabackup/mdev-14447.result b/mysql-test/suite/mariabackup/mdev-14447.result
new file mode 100644
index 00000000000..3bca7eb5701
--- /dev/null
+++ b/mysql-test/suite/mariabackup/mdev-14447.result
@@ -0,0 +1,19 @@
+call mtr.add_suppression("InnoDB: New log files created");
+CREATE TABLE t(a varchar(40) PRIMARY KEY, b varchar(40), c varchar(40), d varchar(40), index(b,c,d)) ENGINE INNODB;
+# Create full backup , modify table, then create incremental/differential backup
+BEGIN;
+INSERT INTO t select uuid(), uuid(), uuid(), uuid() from seq_1_to_100000;
+COMMIT;
+SELECT count(*) FROM t;
+count(*)
+100000
+# Prepare full backup, apply incremental one
+# Restore and check results
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT count(*) FROM t;
+count(*)
+100000
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/mdev-14447.test b/mysql-test/suite/mariabackup/mdev-14447.test
new file mode 100644
index 00000000000..48f37646231
--- /dev/null
+++ b/mysql-test/suite/mariabackup/mdev-14447.test
@@ -0,0 +1,46 @@
+call mtr.add_suppression("InnoDB: New log files created");
+
+let $basedir=$MYSQLTEST_VARDIR/tmp/backup;
+let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1;
+
+CREATE TABLE t(a varchar(40) PRIMARY KEY, b varchar(40), c varchar(40), d varchar(40), index(b,c,d)) ENGINE INNODB;
+
+echo # Create full backup , modify table, then create incremental/differential backup;
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir;
+--enable_result_log
+BEGIN;
+INSERT INTO t select uuid(), uuid(), uuid(), uuid() from seq_1_to_100000;
+COMMIT;
+SELECT count(*) FROM t;
+
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir;
+
+--disable_result_log
+echo # Prepare full backup, apply incremental one;
+exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir;
+exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir --incremental-dir=$incremental_dir ;
+
+echo # Restore and check results;
+let $targetdir=$basedir;
+#-- source include/restart_and_restore.inc
+
+let $_datadir= `SELECT @@datadir`;
+let $innodb_data_file_path=`SELECT @@innodb_data_file_path`;
+echo # shutdown server;
+--source include/shutdown_mysqld.inc
+echo # remove datadir;
+rmdir $_datadir;
+echo # xtrabackup move back;
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --copy-back --datadir=$_datadir "--innodb_data_file_path=$innodb_data_file_path" --target-dir=$targetdir;
+echo # restart server;
+--source include/start_mysqld.inc
+
+
+--enable_result_log
+SELECT count(*) FROM t;
+DROP TABLE t;
+
+# Cleanup
+rmdir $basedir;
+rmdir $incremental_dir;
diff --git a/mysql-test/suite/mariabackup/missing_ibd.result b/mysql-test/suite/mariabackup/missing_ibd.result
new file mode 100644
index 00000000000..53989be7c14
--- /dev/null
+++ b/mysql-test/suite/mariabackup/missing_ibd.result
@@ -0,0 +1,6 @@
+create table t1(c1 int) engine=InnoDB;
+INSERT INTO t1 VALUES(1);
+# xtrabackup backup
+select * from t1;
+ERROR 42S02: Table 'test.t1' doesn't exist in engine
+drop table t1;
diff --git a/mysql-test/suite/mariabackup/missing_ibd.test b/mysql-test/suite/mariabackup/missing_ibd.test
new file mode 100644
index 00000000000..22044e59841
--- /dev/null
+++ b/mysql-test/suite/mariabackup/missing_ibd.test
@@ -0,0 +1,36 @@
+--source include/have_innodb.inc
+
+#
+# MDEV-13499: Backing up table that "doesn't exist in engine" cause crash in mariabackup when using encryption
+#
+create table t1(c1 int) engine=InnoDB;
+INSERT INTO t1 VALUES(1);
+let MYSQLD_DATADIR=`select @@datadir`;
+
+--disable_query_log
+call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: '.*test.t1\.ibd'");
+call mtr.add_suppression('InnoDB: Operating system error number');
+call mtr.add_suppression('InnoDB: The error means the system cannot find the path specified\.');
+call mtr.add_suppression('InnoDB: If you are installing InnoDB');
+call mtr.add_suppression('InnoDB: Table test/t1 in the InnoDB data dictionary has tablespace id .*, but tablespace with that id or name does not exist');
+call mtr.add_suppression('InnoDB: Ignoring tablespace for `test`\.`t1` because it could not be opened\.');
+--enable_query_log
+
+--source include/shutdown_mysqld.inc
+
+--remove_file $MYSQLD_DATADIR/test/t1.ibd
+
+--source include/start_mysqld.inc
+
+echo # xtrabackup backup;
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir;
+--enable_result_log
+
+rmdir $targetdir;
+
+--error ER_NO_SUCH_TABLE_IN_ENGINE
+select * from t1;
+drop table t1;
+
diff --git a/mysql-test/suite/mariabackup/system_versioning.result b/mysql-test/suite/mariabackup/system_versioning.result
new file mode 100644
index 00000000000..0e1e9253dd0
--- /dev/null
+++ b/mysql-test/suite/mariabackup/system_versioning.result
@@ -0,0 +1,49 @@
+create table t (a int) with system versioning;
+insert into t values (1);
+update t set a=2;
+insert into t values (3);
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=INNODB_OR_MYISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+select * from t;
+a
+2
+select a from t for system_time all;
+a
+2
+1
+create or replace table t (
+a int,
+s bigint unsigned as row start invisible,
+e bigint unsigned as row end invisible,
+period for system_time(s, e)
+) with system versioning engine=innodb;
+insert into t values (1);
+update t set a=2;
+insert into t values (3);
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `s` bigint(20) unsigned GENERATED ALWAYS AS ROW START INVISIBLE,
+ `e` bigint(20) unsigned GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`s`, `e`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+select * from t;
+a
+2
+select a from t for system_time all;
+a
+2
+1
+drop table t;
diff --git a/mysql-test/suite/mariabackup/system_versioning.test b/mysql-test/suite/mariabackup/system_versioning.test
new file mode 100644
index 00000000000..1ced00b4588
--- /dev/null
+++ b/mysql-test/suite/mariabackup/system_versioning.test
@@ -0,0 +1,50 @@
+create table t (a int) with system versioning;
+insert into t values (1);
+update t set a=2;
+
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir;
+--enable_result_log
+
+insert into t values (3);
+
+--disable_result_log
+exec $XTRABACKUP --prepare --target-dir=$targetdir;
+-- source include/restart_and_restore.inc
+--enable_result_log
+
+--replace_result InnoDB INNODB_OR_MYISAM MyISAM INNODB_OR_MYISAM
+show create table t;
+select * from t;
+select a from t for system_time all;
+
+rmdir $targetdir;
+
+create or replace table t (
+ a int,
+ s bigint unsigned as row start invisible,
+ e bigint unsigned as row end invisible,
+ period for system_time(s, e)
+) with system versioning engine=innodb;
+insert into t values (1);
+update t set a=2;
+
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir;
+--enable_result_log
+
+insert into t values (3);
+
+--disable_result_log
+exec $XTRABACKUP --prepare --target-dir=$targetdir;
+-- source include/restart_and_restore.inc
+--enable_result_log
+
+show create table t;
+select * from t;
+select a from t for system_time all;
+
+drop table t;
+rmdir $targetdir;
diff --git a/mysql-test/suite/mariabackup/xb_aws_key_management.result b/mysql-test/suite/mariabackup/xb_aws_key_management.result
index 6efc76a8be3..fd12344dfa0 100644
--- a/mysql-test/suite/mariabackup/xb_aws_key_management.result
+++ b/mysql-test/suite/mariabackup/xb_aws_key_management.result
@@ -11,6 +11,4 @@ INSERT INTO t VALUES('foobar1');
SELECT * from t;
c
foobar1
-Warnings:
-Note 1105 AWS KMS plugin: loaded key 1, version 1, key length 128 bit
DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/xb_aws_key_management.test b/mysql-test/suite/mariabackup/xb_aws_key_management.test
index 9f69cbec8b8..c8a12f6ed08 100644
--- a/mysql-test/suite/mariabackup/xb_aws_key_management.test
+++ b/mysql-test/suite/mariabackup/xb_aws_key_management.test
@@ -1,4 +1,3 @@
---source include/innodb_page_size.inc
--source include/have_debug.inc
if (`SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'aws_key_management' AND PLUGIN_STATUS='ACTIVE'`)
diff --git a/mysql-test/suite/parts/inc/part_alter_values.inc b/mysql-test/suite/parts/inc/part_alter_values.inc
new file mode 100644
index 00000000000..0d4929d9820
--- /dev/null
+++ b/mysql-test/suite/parts/inc/part_alter_values.inc
@@ -0,0 +1,37 @@
+--echo #
+--echo # MDEV-14641 Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine
+--echo #
+
+--eval CREATE TABLE t1 (i INT) ENGINE=$engine PARTITION BY LIST(i) (PARTITION p0 VALUES IN (1), PARTITION p1 VALUES IN (2));
+ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
+ALTER TABLE t1 DROP PARTITION p1;
+SELECT * FROM t1;
+
+# Cleanup
+DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-13788 Server crash when issuing bad SQL partition syntax
+--echo #
+
+--eval CREATE TABLE t1 (id int, d date) ENGINE=$engine PARTITION BY RANGE COLUMNS(d) (PARTITION p1 VALUES LESS THAN (MAXVALUE))
+SHOW CREATE TABLE t1;
+--error ER_PARTITION_REQUIRES_VALUES_ERROR
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
+(
+ PARTITION p2, /* Notice no values */
+ PARTITION p3 VALUES LESS THAN (MAXVALUE)
+);
+DROP TABLE t1;
+
+
+--eval CREATE TABLE t1 (id int, d date) ENGINE=$engine PARTITION BY LIST (id) (PARTITION p1 VALUES IN (1,2,3))
+SHOW CREATE TABLE t1;
+--error ER_PARTITION_REQUIRES_VALUES_ERROR
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
+(
+ PARTITION p2, /* Notice no values */
+ PARTITION p3 VALUES IN (4,5,6)
+);
+DROP TABLE t1;
diff --git a/mysql-test/suite/parts/r/cache.result b/mysql-test/suite/parts/r/cache.result
new file mode 100644
index 00000000000..fb40526f379
--- /dev/null
+++ b/mysql-test/suite/parts/r/cache.result
@@ -0,0 +1,15 @@
+CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, f4 INT, KEY (f4),
+KEY (f1,f4,f3,f2)
+) PARTITION BY RANGE(f1) ( PARTITION p VALUES LESS THAN MAXVALUE );
+INSERT IGNORE INTO t1 VALUES
+(140,0,0,7),(143,92,NULL,0),(0,0,NULL,154),(NULL,255,117,197),(0,0,NULL,0),(60,0,0,1);
+CREATE TABLE t2 (f INT);
+INSERT INTO t2 VALUES (NULL),(35),(NULL),(2);
+SELECT * FROM t1, t2 WHERE f4 >= f;
+f1 f2 f3 f4 f
+0 0 NULL 154 2
+0 0 NULL 154 35
+140 0 0 7 2
+NULL 255 117 197 2
+NULL 255 117 197 35
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/parts/r/optimizer.result b/mysql-test/suite/parts/r/optimizer.result
index cdf0b2b83dc..465c6c7d762 100644
--- a/mysql-test/suite/parts/r/optimizer.result
+++ b/mysql-test/suite/parts/r/optimizer.result
@@ -22,7 +22,7 @@ INSERT INTO t2 SELECT * FROM t1;
# plans should be identical
EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index for group-by
+1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index
EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by
@@ -33,7 +33,7 @@ a MAX(b)
# Should be no more than 4 reads.
SHOW status LIKE 'handler_read_key';
Variable_name Value
-Handler_read_key 4
+Handler_read_key 2
FLUSH status;
SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a;
a MAX(b)
diff --git a/mysql-test/suite/parts/r/partition_alter_innodb.result b/mysql-test/suite/parts/r/partition_alter_innodb.result
new file mode 100644
index 00000000000..99697086170
--- /dev/null
+++ b/mysql-test/suite/parts/r/partition_alter_innodb.result
@@ -0,0 +1,44 @@
+#
+# MDEV-14641 Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine
+#
+CREATE TABLE t1 (i INT) ENGINE=InnoDB PARTITION BY LIST(i) (PARTITION p0 VALUES IN (1), PARTITION p1 VALUES IN (2));;
+ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
+ALTER TABLE t1 DROP PARTITION p1;
+SELECT * FROM t1;
+i
+DROP TABLE t1;
+#
+# MDEV-13788 Server crash when issuing bad SQL partition syntax
+#
+CREATE TABLE t1 (id int, d date) ENGINE=InnoDB PARTITION BY RANGE COLUMNS(d) (PARTITION p1 VALUES LESS THAN (MAXVALUE));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL,
+ `d` date DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ PARTITION BY RANGE COLUMNS(`d`)
+(PARTITION `p1` VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB)
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
+(
+PARTITION p2, /* Notice no values */
+PARTITION p3 VALUES LESS THAN (MAXVALUE)
+);
+ERROR HY000: Syntax error: RANGE PARTITIONING requires definition of VALUES LESS THAN for each partition
+DROP TABLE t1;
+CREATE TABLE t1 (id int, d date) ENGINE=InnoDB PARTITION BY LIST (id) (PARTITION p1 VALUES IN (1,2,3));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL,
+ `d` date DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ PARTITION BY LIST (`id`)
+(PARTITION `p1` VALUES IN (1,2,3) ENGINE = InnoDB)
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
+(
+PARTITION p2, /* Notice no values */
+PARTITION p3 VALUES IN (4,5,6)
+);
+ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
+DROP TABLE t1;
diff --git a/mysql-test/suite/parts/r/partition_alter_maria.result b/mysql-test/suite/parts/r/partition_alter_maria.result
index 6343566e408..c7e9028a29c 100644
--- a/mysql-test/suite/parts/r/partition_alter_maria.result
+++ b/mysql-test/suite/parts/r/partition_alter_maria.result
@@ -16,3 +16,56 @@ select * from t1;
pk dt
1 2017-09-28 15:12:00
drop table t1;
+create table t1 (a int) engine=Aria transactional=1 partition by hash(a) partitions 2;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 TRANSACTIONAL=1
+ PARTITION BY HASH (`a`)
+PARTITIONS 2
+drop table t1;
+#
+# MDEV-14641 Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine
+#
+CREATE TABLE t1 (i INT) ENGINE=Aria PARTITION BY LIST(i) (PARTITION p0 VALUES IN (1), PARTITION p1 VALUES IN (2));;
+ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
+ALTER TABLE t1 DROP PARTITION p1;
+SELECT * FROM t1;
+i
+DROP TABLE t1;
+#
+# MDEV-13788 Server crash when issuing bad SQL partition syntax
+#
+CREATE TABLE t1 (id int, d date) ENGINE=Aria PARTITION BY RANGE COLUMNS(d) (PARTITION p1 VALUES LESS THAN (MAXVALUE));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL,
+ `d` date DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1
+ PARTITION BY RANGE COLUMNS(`d`)
+(PARTITION `p1` VALUES LESS THAN (MAXVALUE) ENGINE = Aria)
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
+(
+PARTITION p2, /* Notice no values */
+PARTITION p3 VALUES LESS THAN (MAXVALUE)
+);
+ERROR HY000: Syntax error: RANGE PARTITIONING requires definition of VALUES LESS THAN for each partition
+DROP TABLE t1;
+CREATE TABLE t1 (id int, d date) ENGINE=Aria PARTITION BY LIST (id) (PARTITION p1 VALUES IN (1,2,3));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL,
+ `d` date DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1
+ PARTITION BY LIST (`id`)
+(PARTITION `p1` VALUES IN (1,2,3) ENGINE = Aria)
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
+(
+PARTITION p2, /* Notice no values */
+PARTITION p3 VALUES IN (4,5,6)
+);
+ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
+DROP TABLE t1;
diff --git a/mysql-test/suite/parts/r/partition_alter_myisam.result b/mysql-test/suite/parts/r/partition_alter_myisam.result
new file mode 100644
index 00000000000..50b8b802ad4
--- /dev/null
+++ b/mysql-test/suite/parts/r/partition_alter_myisam.result
@@ -0,0 +1,57 @@
+#
+# MDEV-14641 Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine
+#
+CREATE TABLE t1 (i INT) ENGINE=MyISAM PARTITION BY LIST(i) (PARTITION p0 VALUES IN (1), PARTITION p1 VALUES IN (2));;
+ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
+ALTER TABLE t1 DROP PARTITION p1;
+SELECT * FROM t1;
+i
+DROP TABLE t1;
+#
+# MDEV-13788 Server crash when issuing bad SQL partition syntax
+#
+CREATE TABLE t1 (id int, d date) ENGINE=MyISAM PARTITION BY RANGE COLUMNS(d) (PARTITION p1 VALUES LESS THAN (MAXVALUE));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL,
+ `d` date DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ PARTITION BY RANGE COLUMNS(`d`)
+(PARTITION `p1` VALUES LESS THAN (MAXVALUE) ENGINE = MyISAM)
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
+(
+PARTITION p2, /* Notice no values */
+PARTITION p3 VALUES LESS THAN (MAXVALUE)
+);
+ERROR HY000: Syntax error: RANGE PARTITIONING requires definition of VALUES LESS THAN for each partition
+DROP TABLE t1;
+CREATE TABLE t1 (id int, d date) ENGINE=MyISAM PARTITION BY LIST (id) (PARTITION p1 VALUES IN (1,2,3));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL,
+ `d` date DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ PARTITION BY LIST (`id`)
+(PARTITION `p1` VALUES IN (1,2,3) ENGINE = MyISAM)
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
+(
+PARTITION p2, /* Notice no values */
+PARTITION p3 VALUES IN (4,5,6)
+);
+ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
+DROP TABLE t1;
+create table t1 ( c1 int, c2 int, c3 varchar(100)) delay_key_write=1
+partition by key(c1) (
+partition p01 data directory = 'MYSQL_TMP_DIR'
+ index directory = 'MYSQL_TMP_DIR',
+partition p02 data directory = 'MYSQL_TMP_DIR'
+ index directory = 'MYSQL_TMP_DIR');
+insert into t1 values (1, 1, repeat('a', 100));
+insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1;
+insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1;
+insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1;
+alter online table t1 delay_key_write=0;
+alter online table t1 delay_key_write=1;
+drop table t1;
diff --git a/mysql-test/suite/parts/r/partition_basic_symlink_innodb.result b/mysql-test/suite/parts/r/partition_basic_symlink_innodb.result
index 4d3fae27422..c86b057433a 100644
--- a/mysql-test/suite/parts/r/partition_basic_symlink_innodb.result
+++ b/mysql-test/suite/parts/r/partition_basic_symlink_innodb.result
@@ -127,5 +127,198 @@ t1#P#p0.ibd
t1#P#p1.ibd
DROP TABLE t1;
#
+# MDEV-14611 ALTER TABLE EXCHANGE PARTITION does not work
+# properly when used with DATA DIRECTORY
+#
+SET GLOBAL innodb_file_per_table = ON;
+CREATE TABLE t1
+(
+myid INT(11) NOT NULL,
+myval VARCHAR(10),
+PRIMARY KEY (myid)
+) ENGINE=INNODB PARTITION BY KEY (myid)
+(
+PARTITION p0001 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB,
+PARTITION p0002 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB,
+PARTITION p0003 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB,
+PARTITION p0004 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB
+);
+CREATE TABLE t2
+(
+myid INT(11) NOT NULL,
+myval VARCHAR(10),
+PRIMARY KEY (myid)
+) ENGINE=INNODB DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir';
+ALTER TABLE t1 EXCHANGE PARTITION p0001 WITH TABLE t2;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `myid` int(11) NOT NULL,
+ `myval` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`myid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ PARTITION BY KEY (`myid`)
+(PARTITION `p0001` DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = InnoDB,
+ PARTITION `p0002` DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = InnoDB,
+ PARTITION `p0003` DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = InnoDB,
+ PARTITION `p0004` DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = InnoDB)
+DROP TABLE t1, t2;
+CREATE TABLE t1
+(
+myid INT(11) NOT NULL,
+myval VARCHAR(10),
+PRIMARY KEY (myid)
+) ENGINE=INNODB PARTITION BY RANGE (myid)
+(
+PARTITION p0001 VALUES LESS THAN (50) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB,
+PARTITION p0002 VALUES LESS THAN (150) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB,
+PARTITION p0003 VALUES LESS THAN (1050) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB,
+PARTITION p0004 VALUES LESS THAN (10050) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB
+);
+CREATE TABLE t2
+(
+myid INT(11) NOT NULL,
+myval VARCHAR(10),
+PRIMARY KEY (myid)
+) ENGINE=INNODB DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir';
+insert into t1 values (1, 'one');
+insert into t2 values (2, 'two'), (3, 'threee'), (4, 'four');
+select * from t1;
+myid myval
+1 one
+ALTER TABLE t1 EXCHANGE PARTITION p0001 WITH TABLE t2;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `myid` int(11) NOT NULL,
+ `myval` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`myid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (`myid`)
+(PARTITION `p0001` VALUES LESS THAN (50) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = InnoDB,
+ PARTITION `p0002` VALUES LESS THAN (150) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = InnoDB,
+ PARTITION `p0003` VALUES LESS THAN (1050) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = InnoDB,
+ PARTITION `p0004` VALUES LESS THAN (10050) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = InnoDB)
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `myid` int(11) NOT NULL,
+ `myval` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`myid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/mysql-test-data-dir/'
+select * from t1;
+myid myval
+2 two
+3 threee
+4 four
+select * from t2;
+myid myval
+1 one
+DROP TABLE t1, t2;
+CREATE TABLE t1
+(
+myid INT(11) NOT NULL,
+myval VARCHAR(10),
+PRIMARY KEY (myid)
+) ENGINE=INNODB PARTITION BY RANGE (myid)
+(
+PARTITION p0001 VALUES LESS THAN (50) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB,
+PARTITION p0002 VALUES LESS THAN (150) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB,
+PARTITION p0003 VALUES LESS THAN (1050) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB,
+PARTITION p0004 VALUES LESS THAN (10050) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = INNODB
+);
+CREATE TABLE t2
+(
+myid INT(11) NOT NULL,
+myval VARCHAR(10),
+PRIMARY KEY (myid)
+) ENGINE=INNODB;
+insert into t1 values (1, 'one');
+insert into t2 values (2, 'two'), (3, 'threee'), (4, 'four');
+select * from t1;
+myid myval
+1 one
+ALTER TABLE t1 EXCHANGE PARTITION p0001 WITH TABLE t2;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `myid` int(11) NOT NULL,
+ `myval` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`myid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (`myid`)
+(PARTITION `p0001` VALUES LESS THAN (50) ENGINE = InnoDB,
+ PARTITION `p0002` VALUES LESS THAN (150) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = InnoDB,
+ PARTITION `p0003` VALUES LESS THAN (1050) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = InnoDB,
+ PARTITION `p0004` VALUES LESS THAN (10050) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' ENGINE = InnoDB)
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `myid` int(11) NOT NULL,
+ `myval` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`myid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/mysql-test-data-dir/'
+select * from t1;
+myid myval
+2 two
+3 threee
+4 four
+select * from t2;
+myid myval
+1 one
+DROP TABLE t1, t2;
+CREATE TABLE t1
+(
+myid INT(11) NOT NULL,
+myval VARCHAR(10),
+PRIMARY KEY (myid)
+) ENGINE=INNODB PARTITION BY RANGE (myid)
+(
+PARTITION p0001 VALUES LESS THAN (50) ENGINE = INNODB,
+PARTITION p0002 VALUES LESS THAN (150) ENGINE = INNODB,
+PARTITION p0003 VALUES LESS THAN (1050) ENGINE = INNODB,
+PARTITION p0004 VALUES LESS THAN (10050) ENGINE = INNODB
+);
+CREATE TABLE t2
+(
+myid INT(11) NOT NULL,
+myval VARCHAR(10),
+PRIMARY KEY (myid)
+) ENGINE=INNODB DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir';
+insert into t1 values (1, 'one');
+insert into t2 values (2, 'two'), (3, 'threee'), (4, 'four');
+select * from t1;
+myid myval
+1 one
+ALTER TABLE t1 EXCHANGE PARTITION p0001 WITH TABLE t2;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `myid` int(11) NOT NULL,
+ `myval` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`myid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (`myid`)
+(PARTITION `p0001` VALUES LESS THAN (50) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = InnoDB,
+ PARTITION `p0002` VALUES LESS THAN (150) ENGINE = InnoDB,
+ PARTITION `p0003` VALUES LESS THAN (1050) ENGINE = InnoDB,
+ PARTITION `p0004` VALUES LESS THAN (10050) ENGINE = InnoDB)
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `myid` int(11) NOT NULL,
+ `myval` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`myid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select * from t1;
+myid myval
+2 two
+3 threee
+4 four
+select * from t2;
+myid myval
+1 one
+DROP TABLE t1, t2;
+#
# Cleanup
#
diff --git a/mysql-test/suite/parts/r/partition_open.result b/mysql-test/suite/parts/r/partition_open.result
new file mode 100644
index 00000000000..98600d98ce3
--- /dev/null
+++ b/mysql-test/suite/parts/r/partition_open.result
@@ -0,0 +1,8 @@
+select * from t1 partition (p1);
+x
+300
+select * from t1 partition (p0);
+ERROR HY000: Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory")
+drop table t1;
+Warnings:
+Warning 1017 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory")
diff --git a/mysql-test/suite/parts/r/print_error.result b/mysql-test/suite/parts/r/print_error.result
new file mode 100644
index 00000000000..74a13afeb46
--- /dev/null
+++ b/mysql-test/suite/parts/r/print_error.result
@@ -0,0 +1,18 @@
+CREATE TABLE t1 (i INT) ENGINE=InnoDB PARTITION BY HASH (i) PARTITIONS 2;
+XA START 'xid';
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+connect con1,localhost,root,,test;
+CREATE TABLE t2 SELECT * FROM t1;;
+connect con2,localhost,root,,test;
+SET max_statement_time= 1;
+DELETE FROM t1 PARTITION (p1) ORDER BY i LIMIT 2;
+ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
+disconnect con2;
+connection default;
+XA END 'xid';
+XA ROLLBACK 'xid';
+connection con1;
+disconnect con1;
+connection default;
+call mtr.add_suppression('Sort aborted');
+DROP TABLE IF EXISTS t2, t1;
diff --git a/mysql-test/suite/parts/t/cache.test b/mysql-test/suite/parts/t/cache.test
new file mode 100644
index 00000000000..fcf2ba5d6b6
--- /dev/null
+++ b/mysql-test/suite/parts/t/cache.test
@@ -0,0 +1,22 @@
+#
+# Test cases related to row cache
+#
+
+# The server must support partitioning.
+--source include/have_partition.inc
+
+CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, f4 INT, KEY (f4),
+ KEY (f1,f4,f3,f2)
+) PARTITION BY RANGE(f1) ( PARTITION p VALUES LESS THAN MAXVALUE );
+
+INSERT IGNORE INTO t1 VALUES
+(140,0,0,7),(143,92,NULL,0),(0,0,NULL,154),(NULL,255,117,197),(0,0,NULL,0),(60,0,0,1);
+
+CREATE TABLE t2 (f INT);
+INSERT INTO t2 VALUES (NULL),(35),(NULL),(2);
+
+--sorted_result
+SELECT * FROM t1, t2 WHERE f4 >= f;
+
+# Cleanup
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/parts/t/partition_alter_innodb.test b/mysql-test/suite/parts/t/partition_alter_innodb.test
new file mode 100644
index 00000000000..451bec05adc
--- /dev/null
+++ b/mysql-test/suite/parts/t/partition_alter_innodb.test
@@ -0,0 +1,4 @@
+--source include/have_innodb.inc
+--source include/have_partition.inc
+--let $engine=InnoDB
+--source inc/part_alter_values.inc
diff --git a/mysql-test/suite/parts/t/partition_alter_maria.test b/mysql-test/suite/parts/t/partition_alter_maria.test
index db249591158..e0b9256391d 100644
--- a/mysql-test/suite/parts/t/partition_alter_maria.test
+++ b/mysql-test/suite/parts/t/partition_alter_maria.test
@@ -16,3 +16,13 @@ select * from t1;
alter table t1 drop partition p20181231;
select * from t1;
drop table t1;
+
+#
+# MDEV-13982 Server crashes in in ha_partition::engine_name
+#
+create table t1 (a int) engine=Aria transactional=1 partition by hash(a) partitions 2;
+show create table t1;
+drop table t1;
+
+--let $engine=Aria
+--source inc/part_alter_values.inc
diff --git a/mysql-test/suite/parts/t/partition_alter_myisam.test b/mysql-test/suite/parts/t/partition_alter_myisam.test
new file mode 100644
index 00000000000..326cf52b018
--- /dev/null
+++ b/mysql-test/suite/parts/t/partition_alter_myisam.test
@@ -0,0 +1,25 @@
+--source include/have_partition.inc
+--source include/have_symlink.inc
+--let $engine=MyISAM
+--source inc/part_alter_values.inc
+
+#
+# MDEV-14026 ALTER TABLE ... DELAY_KEY_WRITE=1 creates table copy for partitioned MyISAM table with DATA DIRECTORY/INDEX DIRECTORY options
+#
+
+replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR;
+--disable_warnings
+eval create table t1 ( c1 int, c2 int, c3 varchar(100)) delay_key_write=1
+ partition by key(c1) (
+ partition p01 data directory = '$MYSQL_TMP_DIR'
+ index directory = '$MYSQL_TMP_DIR',
+ partition p02 data directory = '$MYSQL_TMP_DIR'
+ index directory = '$MYSQL_TMP_DIR');
+--enable_warnings
+insert into t1 values (1, 1, repeat('a', 100));
+insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1;
+insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1;
+insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1;
+alter online table t1 delay_key_write=0;
+alter online table t1 delay_key_write=1;
+drop table t1;
diff --git a/mysql-test/suite/parts/t/partition_basic_symlink_innodb.test b/mysql-test/suite/parts/t/partition_basic_symlink_innodb.test
index 35dc2d5e004..31448c7a9fe 100644
--- a/mysql-test/suite/parts/t/partition_basic_symlink_innodb.test
+++ b/mysql-test/suite/parts/t/partition_basic_symlink_innodb.test
@@ -148,6 +148,147 @@ SHOW CREATE TABLE t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-14611 ALTER TABLE EXCHANGE PARTITION does not work
+--echo # properly when used with DATA DIRECTORY
+--echo #
+let $data_dir_path= $MYSQLTEST_VARDIR/mysql-test-data-dir;
+let $alt_data_dir_path= $MYSQLTEST_VARDIR/mysql-test-idx-dir;
+SET GLOBAL innodb_file_per_table = ON;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval CREATE TABLE t1
+(
+ myid INT(11) NOT NULL,
+ myval VARCHAR(10),
+ PRIMARY KEY (myid)
+) ENGINE=INNODB PARTITION BY KEY (myid)
+ (
+ PARTITION p0001 DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB,
+ PARTITION p0002 DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB,
+ PARTITION p0003 DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB,
+ PARTITION p0004 DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB
+ );
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval CREATE TABLE t2
+(
+ myid INT(11) NOT NULL,
+ myval VARCHAR(10),
+ PRIMARY KEY (myid)
+) ENGINE=INNODB DATA DIRECTORY = '$data_dir_path';
+
+ALTER TABLE t1 EXCHANGE PARTITION p0001 WITH TABLE t2;
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW CREATE TABLE t1;
+DROP TABLE t1, t2;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval CREATE TABLE t1
+(
+ myid INT(11) NOT NULL,
+ myval VARCHAR(10),
+ PRIMARY KEY (myid)
+) ENGINE=INNODB PARTITION BY RANGE (myid)
+ (
+ PARTITION p0001 VALUES LESS THAN (50) DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB,
+ PARTITION p0002 VALUES LESS THAN (150) DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB,
+ PARTITION p0003 VALUES LESS THAN (1050) DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB,
+ PARTITION p0004 VALUES LESS THAN (10050) DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB
+ );
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval CREATE TABLE t2
+(
+ myid INT(11) NOT NULL,
+ myval VARCHAR(10),
+ PRIMARY KEY (myid)
+) ENGINE=INNODB DATA DIRECTORY = '$alt_data_dir_path';
+
+insert into t1 values (1, 'one');
+insert into t2 values (2, 'two'), (3, 'threee'), (4, 'four');
+
+select * from t1;
+ALTER TABLE t1 EXCHANGE PARTITION p0001 WITH TABLE t2;
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW CREATE TABLE t1;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW CREATE TABLE t2;
+select * from t1;
+select * from t2;
+DROP TABLE t1, t2;
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval CREATE TABLE t1
+(
+ myid INT(11) NOT NULL,
+ myval VARCHAR(10),
+ PRIMARY KEY (myid)
+) ENGINE=INNODB PARTITION BY RANGE (myid)
+ (
+ PARTITION p0001 VALUES LESS THAN (50) DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB,
+ PARTITION p0002 VALUES LESS THAN (150) DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB,
+ PARTITION p0003 VALUES LESS THAN (1050) DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB,
+ PARTITION p0004 VALUES LESS THAN (10050) DATA DIRECTORY = '$data_dir_path' ENGINE = INNODB
+ );
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval CREATE TABLE t2
+(
+ myid INT(11) NOT NULL,
+ myval VARCHAR(10),
+ PRIMARY KEY (myid)
+) ENGINE=INNODB;
+
+insert into t1 values (1, 'one');
+insert into t2 values (2, 'two'), (3, 'threee'), (4, 'four');
+
+select * from t1;
+ALTER TABLE t1 EXCHANGE PARTITION p0001 WITH TABLE t2;
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW CREATE TABLE t1;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW CREATE TABLE t2;
+select * from t1;
+select * from t2;
+DROP TABLE t1, t2;
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval CREATE TABLE t1
+(
+ myid INT(11) NOT NULL,
+ myval VARCHAR(10),
+ PRIMARY KEY (myid)
+) ENGINE=INNODB PARTITION BY RANGE (myid)
+ (
+ PARTITION p0001 VALUES LESS THAN (50) ENGINE = INNODB,
+ PARTITION p0002 VALUES LESS THAN (150) ENGINE = INNODB,
+ PARTITION p0003 VALUES LESS THAN (1050) ENGINE = INNODB,
+ PARTITION p0004 VALUES LESS THAN (10050) ENGINE = INNODB
+ );
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval CREATE TABLE t2
+(
+ myid INT(11) NOT NULL,
+ myval VARCHAR(10),
+ PRIMARY KEY (myid)
+) ENGINE=INNODB DATA DIRECTORY = '$alt_data_dir_path';
+
+insert into t1 values (1, 'one');
+insert into t2 values (2, 'two'), (3, 'threee'), (4, 'four');
+
+select * from t1;
+ALTER TABLE t1 EXCHANGE PARTITION p0001 WITH TABLE t2;
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW CREATE TABLE t1;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW CREATE TABLE t2;
+select * from t1;
+select * from t2;
+DROP TABLE t1, t2;
+--echo #
--echo # Cleanup
--echo #
@@ -160,5 +301,3 @@ EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig;
EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig;
--enable_query_log
-
-
diff --git a/mysql-test/suite/parts/t/partition_open.test b/mysql-test/suite/parts/t/partition_open.test
new file mode 100644
index 00000000000..de6873aacec
--- /dev/null
+++ b/mysql-test/suite/parts/t/partition_open.test
@@ -0,0 +1,24 @@
+#
+# MDEV-11084 Select statement with partition selection against MyISAM table opens all partitions.
+#
+--source include/have_partition.inc
+
+let $datadir=`select @@datadir`;
+
+# Table declared as having 2 partitions
+# create table t1 (x int) egine=myisam
+# partition by range columns (x)
+# ( partition p0 values less than (100), partition p1 values less than (1000));
+#
+# But we copy only second partition. So the 'p0' can't be opened.
+
+copy_file std_data/mdev11084.frm $datadir/test/t1.frm;
+copy_file std_data/mdev11084.par $datadir/test/t1.par;
+copy_file std_data/mdev11084.part1.MYD $datadir/test/t1#P#p1.MYD;
+copy_file std_data/mdev11084.part1.MYI $datadir/test/t1#P#p1.MYI;
+select * from t1 partition (p1);
+--replace_result $datadir ./
+--error ER_FILE_NOT_FOUND
+select * from t1 partition (p0);
+--replace_result $datadir ./
+drop table t1;
diff --git a/mysql-test/suite/parts/t/print_error.test b/mysql-test/suite/parts/t/print_error.test
new file mode 100644
index 00000000000..79da0d87f4b
--- /dev/null
+++ b/mysql-test/suite/parts/t/print_error.test
@@ -0,0 +1,30 @@
+#
+# MDEV-15336 Server crashes in handler::print_error / ha_partition::print_error upon query timeout
+#
+--source include/have_innodb.inc
+--source include/not_embedded.inc
+--source include/have_partition.inc
+
+CREATE TABLE t1 (i INT) ENGINE=InnoDB PARTITION BY HASH (i) PARTITIONS 2;
+XA START 'xid';
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+
+--connect (con1,localhost,root,,test)
+--send CREATE TABLE t2 SELECT * FROM t1;
+
+--connect (con2,localhost,root,,test)
+SET max_statement_time= 1;
+--error ER_STATEMENT_TIMEOUT
+DELETE FROM t1 PARTITION (p1) ORDER BY i LIMIT 2;
+
+# Cleanup
+--disconnect con2
+--connection default
+XA END 'xid';
+XA ROLLBACK 'xid';
+--connection con1
+--reap
+--disconnect con1
+--connection default
+call mtr.add_suppression('Sort aborted');
+DROP TABLE IF EXISTS t2, t1;
diff --git a/mysql-test/suite/perfschema/r/dml_setup_instruments.result b/mysql-test/suite/perfschema/r/dml_setup_instruments.result
index 83510e5827e..ff184806e2e 100644
--- a/mysql-test/suite/perfschema/r/dml_setup_instruments.result
+++ b/mysql-test/suite/perfschema/r/dml_setup_instruments.result
@@ -4,6 +4,7 @@ where name like 'Wait/Synch/Mutex/sql/%'
and name not in ('wait/synch/mutex/sql/DEBUG_SYNC::mutex')
order by name limit 10;
NAME ENABLED TIMED
+wait/synch/mutex/sql/Ack_receiver::mutex YES YES
wait/synch/mutex/sql/Cversion_lock YES YES
wait/synch/mutex/sql/Delayed_insert::mutex YES YES
wait/synch/mutex/sql/Event_scheduler::LOCK_scheduler_state YES YES
@@ -13,7 +14,6 @@ wait/synch/mutex/sql/HA_DATA_PARTITION::LOCK_auto_inc YES YES
wait/synch/mutex/sql/LOCK_active_mi YES YES
wait/synch/mutex/sql/LOCK_after_binlog_sync YES YES
wait/synch/mutex/sql/LOCK_audit_mask YES YES
-wait/synch/mutex/sql/LOCK_binlog_state YES YES
select * from performance_schema.setup_instruments
where name like 'Wait/Synch/Rwlock/sql/%'
and name not in ('wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock')
@@ -36,6 +36,8 @@ where name like 'Wait/Synch/Cond/sql/%'
'wait/synch/cond/sql/DEBUG_SYNC::cond')
order by name limit 10;
NAME ENABLED TIMED
+wait/synch/cond/sql/Ack_receiver::cond YES YES
+wait/synch/cond/sql/COND_binlog_send YES YES
wait/synch/cond/sql/COND_flush_thread_cache YES YES
wait/synch/cond/sql/COND_group_commit_orderer YES YES
wait/synch/cond/sql/COND_gtid_ignore_duplicates YES YES
@@ -44,8 +46,6 @@ wait/synch/cond/sql/COND_parallel_entry YES YES
wait/synch/cond/sql/COND_prepare_ordered YES YES
wait/synch/cond/sql/COND_queue_state YES YES
wait/synch/cond/sql/COND_rpl_thread YES YES
-wait/synch/cond/sql/COND_rpl_thread_pool YES YES
-wait/synch/cond/sql/COND_rpl_thread_queue YES YES
select * from performance_schema.setup_instruments
where name='Wait';
select * from performance_schema.setup_instruments
diff --git a/mysql-test/suite/perfschema/r/misc.result b/mysql-test/suite/perfschema/r/misc.result
index f2d40fe90b5..4c8fdca8e68 100644
--- a/mysql-test/suite/perfschema/r/misc.result
+++ b/mysql-test/suite/perfschema/r/misc.result
@@ -118,3 +118,19 @@ B
select count(*) from events_statements_history where sql_text like "%...";
count(*)
2
+use test;
+create table t1 (id int);
+insert into t1 values (1), (2), (3);
+truncate performance_schema.events_statements_history;
+select * from t1;
+id
+1
+2
+3
+insert into t1 select RAND()*10000 from t1;
+select sql_text, rows_examined from performance_schema.events_statements_history;
+sql_text rows_examined
+truncate performance_schema.events_statements_history 0
+select * from t1 3
+insert into t1 select RAND()*10000 from t1 6
+drop table t1;
diff --git a/mysql-test/suite/perfschema/r/nesting.result b/mysql-test/suite/perfschema/r/nesting.result
index 78126d93cc7..37681757973 100644
--- a/mysql-test/suite/perfschema/r/nesting.result
+++ b/mysql-test/suite/perfschema/r/nesting.result
@@ -125,7 +125,7 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re
15 15 stage/sql/Starting cleanup (stage) STATEMENT 0
16 16 stage/sql/Freeing items (stage) STATEMENT 0
17 17 wait/io/socket/sql/client_connection send STATEMENT 0
-18 18 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 0
+18 18 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 0
19 20 stage/sql/Reset for next command (stage) STATEMENT 0
20 20 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 19
21 21 idle idle NULL NULL
@@ -147,7 +147,7 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re
37 37 stage/sql/Starting cleanup (stage) STATEMENT 22
38 38 stage/sql/Freeing items (stage) STATEMENT 22
39 39 wait/io/socket/sql/client_connection send STATEMENT 22
-40 40 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 22
+40 40 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 22
41 42 stage/sql/Reset for next command (stage) STATEMENT 22
42 42 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 41
43 43 idle idle NULL NULL
@@ -169,7 +169,7 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re
59 59 stage/sql/Starting cleanup (stage) STATEMENT 44
60 60 stage/sql/Freeing items (stage) STATEMENT 44
61 61 wait/io/socket/sql/client_connection send STATEMENT 44
-62 62 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 44
+62 62 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 44
63 64 stage/sql/Reset for next command (stage) STATEMENT 44
64 64 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 63
65 65 idle idle NULL NULL
@@ -194,7 +194,7 @@ select "With a third part to make things complete" as payload NULL NULL
82 82 stage/sql/Starting cleanup (stage) STATEMENT 66
83 85 stage/sql/Freeing items (stage) STATEMENT 66
84 84 wait/io/socket/sql/client_connection send STAGE 83
-85 85 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 83
+85 85 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 83
86 103 statement/sql/select select "And this is the second part of a multi query" as payload;
select "With a third part to make things complete" as payload NULL NULL
87 89 stage/sql/Init (stage) STATEMENT 86
@@ -213,7 +213,7 @@ select "With a third part to make things complete" as payload NULL NULL
100 100 stage/sql/Starting cleanup (stage) STATEMENT 86
101 103 stage/sql/Freeing items (stage) STATEMENT 86
102 102 wait/io/socket/sql/client_connection send STAGE 101
-103 103 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 101
+103 103 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 101
104 122 statement/sql/select select "With a third part to make things complete" as payload NULL NULL
105 106 stage/sql/Init (stage) STATEMENT 104
106 106 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 105
@@ -230,7 +230,7 @@ select "With a third part to make things complete" as payload NULL NULL
117 117 stage/sql/Starting cleanup (stage) STATEMENT 104
118 118 stage/sql/Freeing items (stage) STATEMENT 104
119 119 wait/io/socket/sql/client_connection send STATEMENT 104
-120 120 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 104
+120 120 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 104
121 122 stage/sql/Reset for next command (stage) STATEMENT 104
122 122 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 121
123 123 idle idle NULL NULL
@@ -252,7 +252,7 @@ select "With a third part to make things complete" as payload NULL NULL
139 139 stage/sql/Starting cleanup (stage) STATEMENT 124
140 140 stage/sql/Freeing items (stage) STATEMENT 124
141 141 wait/io/socket/sql/client_connection send STATEMENT 124
-142 142 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 124
+142 142 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 124
143 144 stage/sql/Reset for next command (stage) STATEMENT 124
144 144 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 143
disconnect con1;
diff --git a/mysql-test/suite/perfschema/r/relaylog.result b/mysql-test/suite/perfschema/r/relaylog.result
index 8dcecf0dc9c..3fcf7367b53 100644
--- a/mysql-test/suite/perfschema/r/relaylog.result
+++ b/mysql-test/suite/perfschema/r/relaylog.result
@@ -62,7 +62,9 @@ where event_name like "%MYSQL_BIN_LOG%"
and event_name not like "%MYSQL_BIN_LOG::COND_xid_list"
order by event_name;
EVENT_NAME COUNT_STAR
+wait/synch/cond/sql/MYSQL_BIN_LOG::COND_bin_log_updated MANY
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_queue_busy NONE
+wait/synch/cond/sql/MYSQL_BIN_LOG::COND_relay_log_updated NONE
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_background_thread MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_end_pos MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index MANY
@@ -81,7 +83,10 @@ where event_name like "%MYSQL_RELAY_LOG%"
and event_name not like "%MYSQL_RELAY_LOG::update_cond"
order by event_name;
EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT
+wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_bin_log_updated 0 0 0 0 0
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_queue_busy 0 0 0 0 0
+wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_relay_log_updated 0 0 0 0 0
+wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_binlog_end_pos 0 0 0 0 0
wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index 0 0 0 0 0
connection slave;
"============ Performance schema on slave ============"
@@ -142,7 +147,9 @@ where event_name like "%MYSQL_BIN_LOG%"
and event_name not like "%MYSQL_BIN_LOG::COND_xid_list"
order by event_name;
EVENT_NAME COUNT_STAR
+wait/synch/cond/sql/MYSQL_BIN_LOG::COND_bin_log_updated NONE
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_queue_busy NONE
+wait/synch/cond/sql/MYSQL_BIN_LOG::COND_relay_log_updated NONE
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_background_thread MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_end_pos MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index MANY
@@ -184,6 +191,9 @@ where event_name like "%MYSQL_RELAY_LOG%"
and event_name not like "%MYSQL_RELAY_LOG::update_cond"
order by event_name;
EVENT_NAME COUNT_STAR
+wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_bin_log_updated NONE
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_queue_busy NONE
+wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_relay_log_updated MANY
+wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_binlog_end_pos NONE
wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index MANY
include/stop_slave.inc
diff --git a/mysql-test/suite/perfschema/r/threads_mysql.result b/mysql-test/suite/perfschema/r/threads_mysql.result
index 9f9c46fe6a6..31f91fc6464 100644
--- a/mysql-test/suite/perfschema/r/threads_mysql.result
+++ b/mysql-test/suite/perfschema/r/threads_mysql.result
@@ -11,7 +11,7 @@ name thread/sql/main
type BACKGROUND
processlist_user NULL
processlist_host NULL
-processlist_db NULL
+processlist_db mysql
processlist_command NULL
processlist_info NULL
unified_parent_thread_id NULL
@@ -99,7 +99,7 @@ name thread/sql/event_worker
type FOREGROUND
processlist_user root
processlist_host localhost
-processlist_db NULL
+processlist_db test
processlist_command Sleep
processlist_info SELECT SLEEP(3)
unified_parent_thread_id unified parent_thread_id
diff --git a/mysql-test/suite/perfschema/t/misc.test b/mysql-test/suite/perfschema/t/misc.test
index bf3e8afffdc..c9f7dc6bfc0 100644
--- a/mysql-test/suite/perfschema/t/misc.test
+++ b/mysql-test/suite/perfschema/t/misc.test
@@ -207,3 +207,18 @@ select 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
select _utf8mb4 'òðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑòðÑÂÑ' as B;
select count(*) from events_statements_history where sql_text like "%...";
+
+
+#
+# MDEV-10486 MariaDB 10.x does not update rows_examined in performance_schema tables
+# Verify that the rows_examined counter is set properly.
+
+use test;
+create table t1 (id int);
+insert into t1 values (1), (2), (3);
+truncate performance_schema.events_statements_history;
+select * from t1;
+insert into t1 select RAND()*10000 from t1;
+select sql_text, rows_examined from performance_schema.events_statements_history;
+drop table t1;
+
diff --git a/mysql-test/suite/perfschema/t/nesting.test b/mysql-test/suite/perfschema/t/nesting.test
index 9ab59157f50..d0547d8a932 100644
--- a/mysql-test/suite/perfschema/t/nesting.test
+++ b/mysql-test/suite/perfschema/t/nesting.test
@@ -39,6 +39,7 @@ update performance_schema.setup_instruments set enabled='YES', timed='YES'
'wait/io/socket/sql/client_connection',
'wait/synch/rwlock/sql/LOCK_grant',
'wait/synch/mutex/sql/THD::LOCK_thd_data',
+ 'wait/synch/mutex/sql/THD::LOCK_thd_kill',
'wait/io/file/sql/query_log');
update performance_schema.setup_instruments set enabled='YES', timed='YES'
diff --git a/mysql-test/suite/plugins/r/binlog-simple_plugin_check.result b/mysql-test/suite/plugins/r/binlog-simple_plugin_check.result
new file mode 100644
index 00000000000..6c960ee325c
--- /dev/null
+++ b/mysql-test/suite/plugins/r/binlog-simple_plugin_check.result
@@ -0,0 +1,19 @@
+INSTALL SONAME "simple_password_check";
+SELECT PLUGIN_NAME FROM INFORMATION_SCHEMA.PLUGINS
+WHERE PLUGIN_NAME='simple_password_check';
+PLUGIN_NAME
+simple_password_check
+#
+# MDEV-14031 Password policy causes replication failure
+#
+CREATE USER user1@localhost IDENTIFIED BY 'BsG9#9.cem#!85';
+CREATE USER user2@localhost IDENTIFIED BY 'bsg9#d.cem#!85';
+ERROR HY000: Your password does not satisfy the current policy requirements
+DROP USER user1@localhost;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE USER user1@localhost IDENTIFIED BY 'BsG9#9.cem#!85'
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP USER user1@localhost
+UNINSTALL PLUGIN simple_password_check;
diff --git a/mysql-test/suite/plugins/t/binlog-simple_plugin_check.test b/mysql-test/suite/plugins/t/binlog-simple_plugin_check.test
new file mode 100644
index 00000000000..773dafe8a81
--- /dev/null
+++ b/mysql-test/suite/plugins/t/binlog-simple_plugin_check.test
@@ -0,0 +1,31 @@
+--source include/not_embedded.inc
+--source include/have_binlog_format_statement.inc
+
+if (!$SIMPLE_PASSWORD_CHECK_SO) {
+ skip No SIMPLE_PASSWORD_CHECK plugin;
+}
+
+INSTALL SONAME "simple_password_check";
+SELECT PLUGIN_NAME FROM INFORMATION_SCHEMA.PLUGINS
+WHERE PLUGIN_NAME='simple_password_check';
+
+
+--echo #
+--echo # MDEV-14031 Password policy causes replication failure
+--echo #
+
+--disable_query_log
+RESET MASTER; # get rid of previous tests binlog
+--enable_query_log
+
+CREATE USER user1@localhost IDENTIFIED BY 'BsG9#9.cem#!85';
+
+--error ER_NOT_VALID_PASSWORD
+CREATE USER user2@localhost IDENTIFIED BY 'bsg9#d.cem#!85';
+
+DROP USER user1@localhost;
+
+--let $binlog_file = LAST
+source include/show_binlog_events.inc;
+
+UNINSTALL PLUGIN simple_password_check;
diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test
index 9be0d5556f0..6c5eaffd9a2 100644
--- a/mysql-test/suite/plugins/t/server_audit.test
+++ b/mysql-test/suite/plugins/t/server_audit.test
@@ -42,8 +42,10 @@ select 1,
3;
insert into t2 values (1), (2);
select * from t2;
+--disable_ps_protocol
--error ER_NO_SUCH_TABLE
select * from t_doesnt_exist;
+--enable_ps_protocol
--error 1064
syntax_error_query;
drop table renamed_t1, t2;
diff --git a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result
index 1a269d72eb7..afe00ed7729 100644
--- a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result
+++ b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result
@@ -5,7 +5,7 @@ alter table user drop column default_role;
alter table user drop column max_statement_time;
flush privileges;
create role test_role;
-ERROR HY000: Column count of mysql.user is wrong. Expected 44, found 43. Created with MariaDB MYSQL_VERSION_ID, now running MYSQL_VERSION_ID. Please use mysql_upgrade to fix this error
+ERROR HY000: Column count of mysql.user is wrong. Expected 45, found 44. Created with MariaDB MYSQL_VERSION_ID, now running MYSQL_VERSION_ID. Please use mysql_upgrade to fix this error
drop role test_role;
ERROR HY000: Operation DROP ROLE failed for 'test_role'
alter table user add column is_role enum('N', 'Y') default 'N' not null
@@ -15,7 +15,7 @@ create role test_role;
create user test_user@localhost;
grant test_role to test_user@localhost;
set default role test_role for root@localhost;
-ERROR HY000: Column count of mysql.user is wrong. Expected 45, found 44. Created with MariaDB MYSQL_VERSION_ID, now running MYSQL_VERSION_ID. Please use mysql_upgrade to fix this error
+ERROR HY000: Column count of mysql.user is wrong. Expected 46, found 45. Created with MariaDB MYSQL_VERSION_ID, now running MYSQL_VERSION_ID. Please use mysql_upgrade to fix this error
drop role test_role;
drop user test_user@localhost;
alter table user add column default_role char(80) binary default '' not null
diff --git a/mysql-test/suite/roles/flush_roles-12366.result b/mysql-test/suite/roles/flush_roles-12366.result
new file mode 100644
index 00000000000..f65c97e0ee3
--- /dev/null
+++ b/mysql-test/suite/roles/flush_roles-12366.result
@@ -0,0 +1,543 @@
+#
+# MDEV-12366: FLUSH PRIVILEGES can break hierarchy of roles
+#
+# This testcase contains a user, who is granted a master role
+# operations_cluster. operations_cluster is granted 8 different roles
+# who in turn each have 4 different roles granted to them.
+#
+# Only the leaf roles contain privileges to access databases.
+# Make sure the user has access to all databases if the master role
+# is granted to him.
+#
+CREATE USER u;
+CREATE ROLE operations_cluster;
+GRANT operations_cluster TO u;
+CREATE DATABASE bob_live_sg;
+CREATE TABLE bob_live_sg.a (i INT(10));
+CREATE TABLE bob_live_sg.b (i INT(10));
+CREATE TABLE bob_live_sg.c (i INT(10));
+CREATE TABLE bob_live_sg.d (i INT(10));
+CREATE DATABASE oms_live_sg;
+CREATE TABLE oms_live_sg.a (i INT(10));
+CREATE TABLE oms_live_sg.b (i INT(10));
+CREATE TABLE oms_live_sg.c (i INT(10));
+CREATE TABLE oms_live_sg.d (i INT(10));
+CREATE DATABASE bob_live_ph;
+CREATE TABLE bob_live_ph.a (i INT(10));
+CREATE TABLE bob_live_ph.b (i INT(10));
+CREATE TABLE bob_live_ph.c (i INT(10));
+CREATE TABLE bob_live_ph.d (i INT(10));
+CREATE DATABASE oms_live_ph;
+CREATE TABLE oms_live_ph.a (i INT(10));
+CREATE TABLE oms_live_ph.b (i INT(10));
+CREATE TABLE oms_live_ph.c (i INT(10));
+CREATE TABLE oms_live_ph.d (i INT(10));
+CREATE DATABASE bob_live_id;
+CREATE TABLE bob_live_id.a (i INT(10));
+CREATE TABLE bob_live_id.b (i INT(10));
+CREATE TABLE bob_live_id.c (i INT(10));
+CREATE TABLE bob_live_id.d (i INT(10));
+CREATE DATABASE oms_live_id;
+CREATE TABLE oms_live_id.a (i INT(10));
+CREATE TABLE oms_live_id.b (i INT(10));
+CREATE TABLE oms_live_id.c (i INT(10));
+CREATE TABLE oms_live_id.d (i INT(10));
+CREATE DATABASE bob_live_hk;
+CREATE TABLE bob_live_hk.a (i INT(10));
+CREATE TABLE bob_live_hk.b (i INT(10));
+CREATE TABLE bob_live_hk.c (i INT(10));
+CREATE TABLE bob_live_hk.d (i INT(10));
+CREATE DATABASE oms_live_hk;
+CREATE TABLE oms_live_hk.a (i INT(10));
+CREATE TABLE oms_live_hk.b (i INT(10));
+CREATE TABLE oms_live_hk.c (i INT(10));
+CREATE TABLE oms_live_hk.d (i INT(10));
+CREATE DATABASE bob_live_vn;
+CREATE TABLE bob_live_vn.a (i INT(10));
+CREATE TABLE bob_live_vn.b (i INT(10));
+CREATE TABLE bob_live_vn.c (i INT(10));
+CREATE TABLE bob_live_vn.d (i INT(10));
+CREATE DATABASE oms_live_vn;
+CREATE TABLE oms_live_vn.a (i INT(10));
+CREATE TABLE oms_live_vn.b (i INT(10));
+CREATE TABLE oms_live_vn.c (i INT(10));
+CREATE TABLE oms_live_vn.d (i INT(10));
+CREATE DATABASE bob_live_tw;
+CREATE TABLE bob_live_tw.a (i INT(10));
+CREATE TABLE bob_live_tw.b (i INT(10));
+CREATE TABLE bob_live_tw.c (i INT(10));
+CREATE TABLE bob_live_tw.d (i INT(10));
+CREATE DATABASE oms_live_tw;
+CREATE TABLE oms_live_tw.a (i INT(10));
+CREATE TABLE oms_live_tw.b (i INT(10));
+CREATE TABLE oms_live_tw.c (i INT(10));
+CREATE TABLE oms_live_tw.d (i INT(10));
+CREATE DATABASE bob_live_my;
+CREATE TABLE bob_live_my.a (i INT(10));
+CREATE TABLE bob_live_my.b (i INT(10));
+CREATE TABLE bob_live_my.c (i INT(10));
+CREATE TABLE bob_live_my.d (i INT(10));
+CREATE DATABASE oms_live_my;
+CREATE TABLE oms_live_my.a (i INT(10));
+CREATE TABLE oms_live_my.b (i INT(10));
+CREATE TABLE oms_live_my.c (i INT(10));
+CREATE TABLE oms_live_my.d (i INT(10));
+CREATE DATABASE bob_live_th;
+CREATE TABLE bob_live_th.a (i INT(10));
+CREATE TABLE bob_live_th.b (i INT(10));
+CREATE TABLE bob_live_th.c (i INT(10));
+CREATE TABLE bob_live_th.d (i INT(10));
+CREATE DATABASE oms_live_th;
+CREATE TABLE oms_live_th.a (i INT(10));
+CREATE TABLE oms_live_th.b (i INT(10));
+CREATE TABLE oms_live_th.c (i INT(10));
+CREATE TABLE oms_live_th.d (i INT(10));
+CREATE ROLE a_sg;
+CREATE ROLE b_sg;
+CREATE ROLE c_sg;
+CREATE ROLE d_sg;
+CREATE ROLE operations_sg;
+GRANT a_sg TO operations_sg;
+GRANT b_sg TO operations_sg;
+GRANT c_sg TO operations_sg;
+GRANT d_sg TO operations_sg;
+GRANT SELECT ON bob_live_sg.a TO a_sg;
+GRANT SELECT ON bob_live_sg.b TO b_sg;
+GRANT SELECT ON bob_live_sg.c TO c_sg;
+GRANT SELECT ON bob_live_sg.d TO d_sg;
+GRANT SELECT ON oms_live_sg.a TO a_sg;
+GRANT SELECT ON oms_live_sg.b TO b_sg;
+GRANT SELECT ON oms_live_sg.c TO c_sg;
+GRANT SELECT ON oms_live_sg.d TO d_sg;
+CREATE ROLE a_ph;
+CREATE ROLE b_ph;
+CREATE ROLE c_ph;
+CREATE ROLE d_ph;
+CREATE ROLE operations_ph;
+GRANT a_ph TO operations_ph;
+GRANT b_ph TO operations_ph;
+GRANT c_ph TO operations_ph;
+GRANT d_ph TO operations_ph;
+GRANT SELECT ON bob_live_ph.a TO a_ph;
+GRANT SELECT ON bob_live_ph.b TO b_ph;
+GRANT SELECT ON bob_live_ph.c TO c_ph;
+GRANT SELECT ON bob_live_ph.d TO d_ph;
+GRANT SELECT ON oms_live_ph.a TO a_ph;
+GRANT SELECT ON oms_live_ph.b TO b_ph;
+GRANT SELECT ON oms_live_ph.c TO c_ph;
+GRANT SELECT ON oms_live_ph.d TO d_ph;
+CREATE ROLE a_id;
+CREATE ROLE b_id;
+CREATE ROLE c_id;
+CREATE ROLE d_id;
+CREATE ROLE operations_id;
+GRANT a_id TO operations_id;
+GRANT b_id TO operations_id;
+GRANT c_id TO operations_id;
+GRANT d_id TO operations_id;
+GRANT SELECT ON bob_live_id.a TO a_id;
+GRANT SELECT ON bob_live_id.b TO b_id;
+GRANT SELECT ON bob_live_id.c TO c_id;
+GRANT SELECT ON bob_live_id.d TO d_id;
+GRANT SELECT ON oms_live_id.a TO a_id;
+GRANT SELECT ON oms_live_id.b TO b_id;
+GRANT SELECT ON oms_live_id.c TO c_id;
+GRANT SELECT ON oms_live_id.d TO d_id;
+CREATE ROLE a_hk;
+CREATE ROLE b_hk;
+CREATE ROLE c_hk;
+CREATE ROLE d_hk;
+CREATE ROLE operations_hk;
+GRANT a_hk TO operations_hk;
+GRANT b_hk TO operations_hk;
+GRANT c_hk TO operations_hk;
+GRANT d_hk TO operations_hk;
+GRANT SELECT ON bob_live_hk.a TO a_hk;
+GRANT SELECT ON bob_live_hk.b TO b_hk;
+GRANT SELECT ON bob_live_hk.c TO c_hk;
+GRANT SELECT ON bob_live_hk.d TO d_hk;
+GRANT SELECT ON oms_live_hk.a TO a_hk;
+GRANT SELECT ON oms_live_hk.b TO b_hk;
+GRANT SELECT ON oms_live_hk.c TO c_hk;
+GRANT SELECT ON oms_live_hk.d TO d_hk;
+CREATE ROLE a_vn;
+CREATE ROLE b_vn;
+CREATE ROLE c_vn;
+CREATE ROLE d_vn;
+CREATE ROLE operations_vn;
+GRANT a_vn TO operations_vn;
+GRANT b_vn TO operations_vn;
+GRANT c_vn TO operations_vn;
+GRANT d_vn TO operations_vn;
+GRANT SELECT ON bob_live_vn.a TO a_vn;
+GRANT SELECT ON bob_live_vn.b TO b_vn;
+GRANT SELECT ON bob_live_vn.c TO c_vn;
+GRANT SELECT ON bob_live_vn.d TO d_vn;
+GRANT SELECT ON oms_live_vn.a TO a_vn;
+GRANT SELECT ON oms_live_vn.b TO b_vn;
+GRANT SELECT ON oms_live_vn.c TO c_vn;
+GRANT SELECT ON oms_live_vn.d TO d_vn;
+CREATE ROLE a_tw;
+CREATE ROLE b_tw;
+CREATE ROLE c_tw;
+CREATE ROLE d_tw;
+CREATE ROLE operations_tw;
+GRANT a_tw TO operations_tw;
+GRANT b_tw TO operations_tw;
+GRANT c_tw TO operations_tw;
+GRANT d_tw TO operations_tw;
+GRANT SELECT ON bob_live_tw.a TO a_tw;
+GRANT SELECT ON bob_live_tw.b TO b_tw;
+GRANT SELECT ON bob_live_tw.c TO c_tw;
+GRANT SELECT ON bob_live_tw.d TO d_tw;
+GRANT SELECT ON oms_live_tw.a TO a_tw;
+GRANT SELECT ON oms_live_tw.b TO b_tw;
+GRANT SELECT ON oms_live_tw.c TO c_tw;
+GRANT SELECT ON oms_live_tw.d TO d_tw;
+CREATE ROLE a_my;
+CREATE ROLE b_my;
+CREATE ROLE c_my;
+CREATE ROLE d_my;
+CREATE ROLE operations_my;
+GRANT a_my TO operations_my;
+GRANT b_my TO operations_my;
+GRANT c_my TO operations_my;
+GRANT d_my TO operations_my;
+GRANT SELECT ON bob_live_my.a TO a_my;
+GRANT SELECT ON bob_live_my.b TO b_my;
+GRANT SELECT ON bob_live_my.c TO c_my;
+GRANT SELECT ON bob_live_my.d TO d_my;
+GRANT SELECT ON oms_live_my.a TO a_my;
+GRANT SELECT ON oms_live_my.b TO b_my;
+GRANT SELECT ON oms_live_my.c TO c_my;
+GRANT SELECT ON oms_live_my.d TO d_my;
+CREATE ROLE a_th;
+CREATE ROLE b_th;
+CREATE ROLE c_th;
+CREATE ROLE d_th;
+CREATE ROLE operations_th;
+GRANT a_th TO operations_th;
+GRANT b_th TO operations_th;
+GRANT c_th TO operations_th;
+GRANT d_th TO operations_th;
+GRANT SELECT ON bob_live_th.a TO a_th;
+GRANT SELECT ON bob_live_th.b TO b_th;
+GRANT SELECT ON bob_live_th.c TO c_th;
+GRANT SELECT ON bob_live_th.d TO d_th;
+GRANT SELECT ON oms_live_th.a TO a_th;
+GRANT SELECT ON oms_live_th.b TO b_th;
+GRANT SELECT ON oms_live_th.c TO c_th;
+GRANT SELECT ON oms_live_th.d TO d_th;
+GRANT operations_sg TO operations_cluster;
+GRANT operations_ph TO operations_cluster;
+GRANT operations_id TO operations_cluster;
+GRANT operations_hk TO operations_cluster;
+GRANT operations_vn TO operations_cluster;
+GRANT operations_tw TO operations_cluster;
+GRANT operations_my TO operations_cluster;
+GRANT operations_th TO operations_cluster;
+connect con1,localhost,u,,;
+SHOW DATABASES;
+Database
+information_schema
+test
+SET ROLE operations_cluster;
+SHOW DATABASES;
+Database
+bob_live_hk
+bob_live_id
+bob_live_my
+bob_live_ph
+bob_live_sg
+bob_live_th
+bob_live_tw
+bob_live_vn
+information_schema
+oms_live_hk
+oms_live_id
+oms_live_my
+oms_live_ph
+oms_live_sg
+oms_live_th
+oms_live_tw
+oms_live_vn
+test
+SELECT COUNT(1) FROM oms_live_sg.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_sg.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_sg.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_sg.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_ph.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_ph.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_ph.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_ph.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_id.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_id.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_id.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_id.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_hk.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_hk.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_hk.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_hk.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_vn.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_vn.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_vn.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_vn.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_tw.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_tw.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_tw.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_tw.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_my.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_my.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_my.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_my.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_th.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_th.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_th.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_th.d;
+COUNT(1)
+0
+connect con2,localhost,root,,;
+FLUSH PRIVILEGES;
+connect con3,localhost,u,,;
+SHOW DATABASES;
+Database
+information_schema
+test
+SET ROLE operations_cluster;
+SHOW DATABASES;
+Database
+bob_live_hk
+bob_live_id
+bob_live_my
+bob_live_ph
+bob_live_sg
+bob_live_th
+bob_live_tw
+bob_live_vn
+information_schema
+oms_live_hk
+oms_live_id
+oms_live_my
+oms_live_ph
+oms_live_sg
+oms_live_th
+oms_live_tw
+oms_live_vn
+test
+SELECT COUNT(1) FROM oms_live_sg.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_sg.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_sg.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_sg.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_ph.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_ph.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_ph.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_ph.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_id.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_id.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_id.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_id.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_hk.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_hk.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_hk.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_hk.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_vn.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_vn.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_vn.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_vn.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_tw.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_tw.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_tw.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_tw.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_my.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_my.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_my.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_my.d;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_th.a;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_th.b;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_th.c;
+COUNT(1)
+0
+SELECT COUNT(1) FROM oms_live_th.d;
+COUNT(1)
+0
+connect con4,localhost,root,,;
+DROP DATABASE bob_live_sg;
+DROP DATABASE oms_live_sg;
+DROP DATABASE bob_live_ph;
+DROP DATABASE oms_live_ph;
+DROP DATABASE bob_live_id;
+DROP DATABASE oms_live_id;
+DROP DATABASE bob_live_hk;
+DROP DATABASE oms_live_hk;
+DROP DATABASE bob_live_vn;
+DROP DATABASE oms_live_vn;
+DROP DATABASE bob_live_tw;
+DROP DATABASE oms_live_tw;
+DROP DATABASE bob_live_my;
+DROP DATABASE oms_live_my;
+DROP DATABASE bob_live_th;
+DROP DATABASE oms_live_th;
+DROP ROLE operations_sg;
+DROP ROLE a_sg;
+DROP ROLE b_sg;
+DROP ROLE c_sg;
+DROP ROLE d_sg;
+DROP ROLE operations_ph;
+DROP ROLE a_ph;
+DROP ROLE b_ph;
+DROP ROLE c_ph;
+DROP ROLE d_ph;
+DROP ROLE operations_id;
+DROP ROLE a_id;
+DROP ROLE b_id;
+DROP ROLE c_id;
+DROP ROLE d_id;
+DROP ROLE operations_hk;
+DROP ROLE a_hk;
+DROP ROLE b_hk;
+DROP ROLE c_hk;
+DROP ROLE d_hk;
+DROP ROLE operations_vn;
+DROP ROLE a_vn;
+DROP ROLE b_vn;
+DROP ROLE c_vn;
+DROP ROLE d_vn;
+DROP ROLE operations_tw;
+DROP ROLE a_tw;
+DROP ROLE b_tw;
+DROP ROLE c_tw;
+DROP ROLE d_tw;
+DROP ROLE operations_my;
+DROP ROLE a_my;
+DROP ROLE b_my;
+DROP ROLE c_my;
+DROP ROLE d_my;
+DROP ROLE operations_th;
+DROP ROLE a_th;
+DROP ROLE b_th;
+DROP ROLE c_th;
+DROP ROLE d_th;
+DROP USER u;
+DROP ROLE operations_cluster;
diff --git a/mysql-test/suite/roles/flush_roles-12366.test b/mysql-test/suite/roles/flush_roles-12366.test
new file mode 100644
index 00000000000..343ac4abf72
--- /dev/null
+++ b/mysql-test/suite/roles/flush_roles-12366.test
@@ -0,0 +1,379 @@
+--source include/not_embedded.inc
+--echo #
+--echo # MDEV-12366: FLUSH PRIVILEGES can break hierarchy of roles
+--echo #
+--echo # This testcase contains a user, who is granted a master role
+--echo # operations_cluster. operations_cluster is granted 8 different roles
+--echo # who in turn each have 4 different roles granted to them.
+--echo #
+--echo # Only the leaf roles contain privileges to access databases.
+--echo # Make sure the user has access to all databases if the master role
+--echo # is granted to him.
+--echo #
+CREATE USER u;
+CREATE ROLE operations_cluster;
+GRANT operations_cluster TO u;
+CREATE DATABASE bob_live_sg;
+CREATE TABLE bob_live_sg.a (i INT(10));
+CREATE TABLE bob_live_sg.b (i INT(10));
+CREATE TABLE bob_live_sg.c (i INT(10));
+CREATE TABLE bob_live_sg.d (i INT(10));
+CREATE DATABASE oms_live_sg;
+CREATE TABLE oms_live_sg.a (i INT(10));
+CREATE TABLE oms_live_sg.b (i INT(10));
+CREATE TABLE oms_live_sg.c (i INT(10));
+CREATE TABLE oms_live_sg.d (i INT(10));
+CREATE DATABASE bob_live_ph;
+CREATE TABLE bob_live_ph.a (i INT(10));
+CREATE TABLE bob_live_ph.b (i INT(10));
+CREATE TABLE bob_live_ph.c (i INT(10));
+CREATE TABLE bob_live_ph.d (i INT(10));
+CREATE DATABASE oms_live_ph;
+CREATE TABLE oms_live_ph.a (i INT(10));
+CREATE TABLE oms_live_ph.b (i INT(10));
+CREATE TABLE oms_live_ph.c (i INT(10));
+CREATE TABLE oms_live_ph.d (i INT(10));
+CREATE DATABASE bob_live_id;
+CREATE TABLE bob_live_id.a (i INT(10));
+CREATE TABLE bob_live_id.b (i INT(10));
+CREATE TABLE bob_live_id.c (i INT(10));
+CREATE TABLE bob_live_id.d (i INT(10));
+CREATE DATABASE oms_live_id;
+CREATE TABLE oms_live_id.a (i INT(10));
+CREATE TABLE oms_live_id.b (i INT(10));
+CREATE TABLE oms_live_id.c (i INT(10));
+CREATE TABLE oms_live_id.d (i INT(10));
+CREATE DATABASE bob_live_hk;
+CREATE TABLE bob_live_hk.a (i INT(10));
+CREATE TABLE bob_live_hk.b (i INT(10));
+CREATE TABLE bob_live_hk.c (i INT(10));
+CREATE TABLE bob_live_hk.d (i INT(10));
+CREATE DATABASE oms_live_hk;
+CREATE TABLE oms_live_hk.a (i INT(10));
+CREATE TABLE oms_live_hk.b (i INT(10));
+CREATE TABLE oms_live_hk.c (i INT(10));
+CREATE TABLE oms_live_hk.d (i INT(10));
+CREATE DATABASE bob_live_vn;
+CREATE TABLE bob_live_vn.a (i INT(10));
+CREATE TABLE bob_live_vn.b (i INT(10));
+CREATE TABLE bob_live_vn.c (i INT(10));
+CREATE TABLE bob_live_vn.d (i INT(10));
+CREATE DATABASE oms_live_vn;
+CREATE TABLE oms_live_vn.a (i INT(10));
+CREATE TABLE oms_live_vn.b (i INT(10));
+CREATE TABLE oms_live_vn.c (i INT(10));
+CREATE TABLE oms_live_vn.d (i INT(10));
+CREATE DATABASE bob_live_tw;
+CREATE TABLE bob_live_tw.a (i INT(10));
+CREATE TABLE bob_live_tw.b (i INT(10));
+CREATE TABLE bob_live_tw.c (i INT(10));
+CREATE TABLE bob_live_tw.d (i INT(10));
+CREATE DATABASE oms_live_tw;
+CREATE TABLE oms_live_tw.a (i INT(10));
+CREATE TABLE oms_live_tw.b (i INT(10));
+CREATE TABLE oms_live_tw.c (i INT(10));
+CREATE TABLE oms_live_tw.d (i INT(10));
+CREATE DATABASE bob_live_my;
+CREATE TABLE bob_live_my.a (i INT(10));
+CREATE TABLE bob_live_my.b (i INT(10));
+CREATE TABLE bob_live_my.c (i INT(10));
+CREATE TABLE bob_live_my.d (i INT(10));
+CREATE DATABASE oms_live_my;
+CREATE TABLE oms_live_my.a (i INT(10));
+CREATE TABLE oms_live_my.b (i INT(10));
+CREATE TABLE oms_live_my.c (i INT(10));
+CREATE TABLE oms_live_my.d (i INT(10));
+CREATE DATABASE bob_live_th;
+CREATE TABLE bob_live_th.a (i INT(10));
+CREATE TABLE bob_live_th.b (i INT(10));
+CREATE TABLE bob_live_th.c (i INT(10));
+CREATE TABLE bob_live_th.d (i INT(10));
+CREATE DATABASE oms_live_th;
+CREATE TABLE oms_live_th.a (i INT(10));
+CREATE TABLE oms_live_th.b (i INT(10));
+CREATE TABLE oms_live_th.c (i INT(10));
+CREATE TABLE oms_live_th.d (i INT(10));
+CREATE ROLE a_sg;
+CREATE ROLE b_sg;
+CREATE ROLE c_sg;
+CREATE ROLE d_sg;
+CREATE ROLE operations_sg;
+GRANT a_sg TO operations_sg;
+GRANT b_sg TO operations_sg;
+GRANT c_sg TO operations_sg;
+GRANT d_sg TO operations_sg;
+GRANT SELECT ON bob_live_sg.a TO a_sg;
+GRANT SELECT ON bob_live_sg.b TO b_sg;
+GRANT SELECT ON bob_live_sg.c TO c_sg;
+GRANT SELECT ON bob_live_sg.d TO d_sg;
+GRANT SELECT ON oms_live_sg.a TO a_sg;
+GRANT SELECT ON oms_live_sg.b TO b_sg;
+GRANT SELECT ON oms_live_sg.c TO c_sg;
+GRANT SELECT ON oms_live_sg.d TO d_sg;
+CREATE ROLE a_ph;
+CREATE ROLE b_ph;
+CREATE ROLE c_ph;
+CREATE ROLE d_ph;
+CREATE ROLE operations_ph;
+GRANT a_ph TO operations_ph;
+GRANT b_ph TO operations_ph;
+GRANT c_ph TO operations_ph;
+GRANT d_ph TO operations_ph;
+GRANT SELECT ON bob_live_ph.a TO a_ph;
+GRANT SELECT ON bob_live_ph.b TO b_ph;
+GRANT SELECT ON bob_live_ph.c TO c_ph;
+GRANT SELECT ON bob_live_ph.d TO d_ph;
+GRANT SELECT ON oms_live_ph.a TO a_ph;
+GRANT SELECT ON oms_live_ph.b TO b_ph;
+GRANT SELECT ON oms_live_ph.c TO c_ph;
+GRANT SELECT ON oms_live_ph.d TO d_ph;
+CREATE ROLE a_id;
+CREATE ROLE b_id;
+CREATE ROLE c_id;
+CREATE ROLE d_id;
+CREATE ROLE operations_id;
+GRANT a_id TO operations_id;
+GRANT b_id TO operations_id;
+GRANT c_id TO operations_id;
+GRANT d_id TO operations_id;
+GRANT SELECT ON bob_live_id.a TO a_id;
+GRANT SELECT ON bob_live_id.b TO b_id;
+GRANT SELECT ON bob_live_id.c TO c_id;
+GRANT SELECT ON bob_live_id.d TO d_id;
+GRANT SELECT ON oms_live_id.a TO a_id;
+GRANT SELECT ON oms_live_id.b TO b_id;
+GRANT SELECT ON oms_live_id.c TO c_id;
+GRANT SELECT ON oms_live_id.d TO d_id;
+CREATE ROLE a_hk;
+CREATE ROLE b_hk;
+CREATE ROLE c_hk;
+CREATE ROLE d_hk;
+CREATE ROLE operations_hk;
+GRANT a_hk TO operations_hk;
+GRANT b_hk TO operations_hk;
+GRANT c_hk TO operations_hk;
+GRANT d_hk TO operations_hk;
+GRANT SELECT ON bob_live_hk.a TO a_hk;
+GRANT SELECT ON bob_live_hk.b TO b_hk;
+GRANT SELECT ON bob_live_hk.c TO c_hk;
+GRANT SELECT ON bob_live_hk.d TO d_hk;
+GRANT SELECT ON oms_live_hk.a TO a_hk;
+GRANT SELECT ON oms_live_hk.b TO b_hk;
+GRANT SELECT ON oms_live_hk.c TO c_hk;
+GRANT SELECT ON oms_live_hk.d TO d_hk;
+CREATE ROLE a_vn;
+CREATE ROLE b_vn;
+CREATE ROLE c_vn;
+CREATE ROLE d_vn;
+CREATE ROLE operations_vn;
+GRANT a_vn TO operations_vn;
+GRANT b_vn TO operations_vn;
+GRANT c_vn TO operations_vn;
+GRANT d_vn TO operations_vn;
+GRANT SELECT ON bob_live_vn.a TO a_vn;
+GRANT SELECT ON bob_live_vn.b TO b_vn;
+GRANT SELECT ON bob_live_vn.c TO c_vn;
+GRANT SELECT ON bob_live_vn.d TO d_vn;
+GRANT SELECT ON oms_live_vn.a TO a_vn;
+GRANT SELECT ON oms_live_vn.b TO b_vn;
+GRANT SELECT ON oms_live_vn.c TO c_vn;
+GRANT SELECT ON oms_live_vn.d TO d_vn;
+CREATE ROLE a_tw;
+CREATE ROLE b_tw;
+CREATE ROLE c_tw;
+CREATE ROLE d_tw;
+CREATE ROLE operations_tw;
+GRANT a_tw TO operations_tw;
+GRANT b_tw TO operations_tw;
+GRANT c_tw TO operations_tw;
+GRANT d_tw TO operations_tw;
+GRANT SELECT ON bob_live_tw.a TO a_tw;
+GRANT SELECT ON bob_live_tw.b TO b_tw;
+GRANT SELECT ON bob_live_tw.c TO c_tw;
+GRANT SELECT ON bob_live_tw.d TO d_tw;
+GRANT SELECT ON oms_live_tw.a TO a_tw;
+GRANT SELECT ON oms_live_tw.b TO b_tw;
+GRANT SELECT ON oms_live_tw.c TO c_tw;
+GRANT SELECT ON oms_live_tw.d TO d_tw;
+CREATE ROLE a_my;
+CREATE ROLE b_my;
+CREATE ROLE c_my;
+CREATE ROLE d_my;
+CREATE ROLE operations_my;
+GRANT a_my TO operations_my;
+GRANT b_my TO operations_my;
+GRANT c_my TO operations_my;
+GRANT d_my TO operations_my;
+GRANT SELECT ON bob_live_my.a TO a_my;
+GRANT SELECT ON bob_live_my.b TO b_my;
+GRANT SELECT ON bob_live_my.c TO c_my;
+GRANT SELECT ON bob_live_my.d TO d_my;
+GRANT SELECT ON oms_live_my.a TO a_my;
+GRANT SELECT ON oms_live_my.b TO b_my;
+GRANT SELECT ON oms_live_my.c TO c_my;
+GRANT SELECT ON oms_live_my.d TO d_my;
+CREATE ROLE a_th;
+CREATE ROLE b_th;
+CREATE ROLE c_th;
+CREATE ROLE d_th;
+CREATE ROLE operations_th;
+GRANT a_th TO operations_th;
+GRANT b_th TO operations_th;
+GRANT c_th TO operations_th;
+GRANT d_th TO operations_th;
+GRANT SELECT ON bob_live_th.a TO a_th;
+GRANT SELECT ON bob_live_th.b TO b_th;
+GRANT SELECT ON bob_live_th.c TO c_th;
+GRANT SELECT ON bob_live_th.d TO d_th;
+GRANT SELECT ON oms_live_th.a TO a_th;
+GRANT SELECT ON oms_live_th.b TO b_th;
+GRANT SELECT ON oms_live_th.c TO c_th;
+GRANT SELECT ON oms_live_th.d TO d_th;
+GRANT operations_sg TO operations_cluster;
+GRANT operations_ph TO operations_cluster;
+GRANT operations_id TO operations_cluster;
+GRANT operations_hk TO operations_cluster;
+GRANT operations_vn TO operations_cluster;
+GRANT operations_tw TO operations_cluster;
+GRANT operations_my TO operations_cluster;
+GRANT operations_th TO operations_cluster;
+
+connect(con1,localhost,u,,);
+SHOW DATABASES;
+SET ROLE operations_cluster;
+SHOW DATABASES;
+SELECT COUNT(1) FROM oms_live_sg.a;
+SELECT COUNT(1) FROM oms_live_sg.b;
+SELECT COUNT(1) FROM oms_live_sg.c;
+SELECT COUNT(1) FROM oms_live_sg.d;
+SELECT COUNT(1) FROM oms_live_ph.a;
+SELECT COUNT(1) FROM oms_live_ph.b;
+SELECT COUNT(1) FROM oms_live_ph.c;
+SELECT COUNT(1) FROM oms_live_ph.d;
+SELECT COUNT(1) FROM oms_live_id.a;
+SELECT COUNT(1) FROM oms_live_id.b;
+SELECT COUNT(1) FROM oms_live_id.c;
+SELECT COUNT(1) FROM oms_live_id.d;
+SELECT COUNT(1) FROM oms_live_hk.a;
+SELECT COUNT(1) FROM oms_live_hk.b;
+SELECT COUNT(1) FROM oms_live_hk.c;
+SELECT COUNT(1) FROM oms_live_hk.d;
+SELECT COUNT(1) FROM oms_live_vn.a;
+SELECT COUNT(1) FROM oms_live_vn.b;
+SELECT COUNT(1) FROM oms_live_vn.c;
+SELECT COUNT(1) FROM oms_live_vn.d;
+SELECT COUNT(1) FROM oms_live_tw.a;
+SELECT COUNT(1) FROM oms_live_tw.b;
+SELECT COUNT(1) FROM oms_live_tw.c;
+SELECT COUNT(1) FROM oms_live_tw.d;
+SELECT COUNT(1) FROM oms_live_my.a;
+SELECT COUNT(1) FROM oms_live_my.b;
+SELECT COUNT(1) FROM oms_live_my.c;
+SELECT COUNT(1) FROM oms_live_my.d;
+SELECT COUNT(1) FROM oms_live_th.a;
+SELECT COUNT(1) FROM oms_live_th.b;
+SELECT COUNT(1) FROM oms_live_th.c;
+SELECT COUNT(1) FROM oms_live_th.d;
+
+
+connect(con2,localhost,root,,);
+FLUSH PRIVILEGES;
+
+connect(con3,localhost,u,,);
+SHOW DATABASES;
+SET ROLE operations_cluster;
+SHOW DATABASES;
+SELECT COUNT(1) FROM oms_live_sg.a;
+SELECT COUNT(1) FROM oms_live_sg.b;
+SELECT COUNT(1) FROM oms_live_sg.c;
+SELECT COUNT(1) FROM oms_live_sg.d;
+SELECT COUNT(1) FROM oms_live_ph.a;
+SELECT COUNT(1) FROM oms_live_ph.b;
+SELECT COUNT(1) FROM oms_live_ph.c;
+SELECT COUNT(1) FROM oms_live_ph.d;
+SELECT COUNT(1) FROM oms_live_id.a;
+SELECT COUNT(1) FROM oms_live_id.b;
+SELECT COUNT(1) FROM oms_live_id.c;
+SELECT COUNT(1) FROM oms_live_id.d;
+SELECT COUNT(1) FROM oms_live_hk.a;
+SELECT COUNT(1) FROM oms_live_hk.b;
+SELECT COUNT(1) FROM oms_live_hk.c;
+SELECT COUNT(1) FROM oms_live_hk.d;
+SELECT COUNT(1) FROM oms_live_vn.a;
+SELECT COUNT(1) FROM oms_live_vn.b;
+SELECT COUNT(1) FROM oms_live_vn.c;
+SELECT COUNT(1) FROM oms_live_vn.d;
+SELECT COUNT(1) FROM oms_live_tw.a;
+SELECT COUNT(1) FROM oms_live_tw.b;
+SELECT COUNT(1) FROM oms_live_tw.c;
+SELECT COUNT(1) FROM oms_live_tw.d;
+SELECT COUNT(1) FROM oms_live_my.a;
+SELECT COUNT(1) FROM oms_live_my.b;
+SELECT COUNT(1) FROM oms_live_my.c;
+SELECT COUNT(1) FROM oms_live_my.d;
+SELECT COUNT(1) FROM oms_live_th.a;
+SELECT COUNT(1) FROM oms_live_th.b;
+SELECT COUNT(1) FROM oms_live_th.c;
+SELECT COUNT(1) FROM oms_live_th.d;
+
+
+connect(con4,localhost,root,,);
+
+DROP DATABASE bob_live_sg;
+DROP DATABASE oms_live_sg;
+DROP DATABASE bob_live_ph;
+DROP DATABASE oms_live_ph;
+DROP DATABASE bob_live_id;
+DROP DATABASE oms_live_id;
+DROP DATABASE bob_live_hk;
+DROP DATABASE oms_live_hk;
+DROP DATABASE bob_live_vn;
+DROP DATABASE oms_live_vn;
+DROP DATABASE bob_live_tw;
+DROP DATABASE oms_live_tw;
+DROP DATABASE bob_live_my;
+DROP DATABASE oms_live_my;
+DROP DATABASE bob_live_th;
+DROP DATABASE oms_live_th;
+DROP ROLE operations_sg;
+DROP ROLE a_sg;
+DROP ROLE b_sg;
+DROP ROLE c_sg;
+DROP ROLE d_sg;
+DROP ROLE operations_ph;
+DROP ROLE a_ph;
+DROP ROLE b_ph;
+DROP ROLE c_ph;
+DROP ROLE d_ph;
+DROP ROLE operations_id;
+DROP ROLE a_id;
+DROP ROLE b_id;
+DROP ROLE c_id;
+DROP ROLE d_id;
+DROP ROLE operations_hk;
+DROP ROLE a_hk;
+DROP ROLE b_hk;
+DROP ROLE c_hk;
+DROP ROLE d_hk;
+DROP ROLE operations_vn;
+DROP ROLE a_vn;
+DROP ROLE b_vn;
+DROP ROLE c_vn;
+DROP ROLE d_vn;
+DROP ROLE operations_tw;
+DROP ROLE a_tw;
+DROP ROLE b_tw;
+DROP ROLE c_tw;
+DROP ROLE d_tw;
+DROP ROLE operations_my;
+DROP ROLE a_my;
+DROP ROLE b_my;
+DROP ROLE c_my;
+DROP ROLE d_my;
+DROP ROLE operations_th;
+DROP ROLE a_th;
+DROP ROLE b_th;
+DROP ROLE c_th;
+DROP ROLE d_th;
+DROP USER u;
+DROP ROLE operations_cluster;
diff --git a/mysql-test/suite/roles/set_role-13655.result b/mysql-test/suite/roles/set_role-13655.result
new file mode 100644
index 00000000000..c30e4115953
--- /dev/null
+++ b/mysql-test/suite/roles/set_role-13655.result
@@ -0,0 +1,52 @@
+#
+# MDEV-13655: SET ROLE does not properly grant privileges.
+#
+# We must test that if aditional db privileges get granted to a role
+# which previously inherited privileges from another granted role
+# keep the internal memory structures intact.
+#
+create role simple;
+#
+# First we create an entry with privileges for databases for the simple role.
+#
+grant select, insert, update, delete, lock tables, execute on t.* to simple;
+create role admin;
+#
+# Now we grant the simple role to admin. This means that db privileges
+# should propagate to admin.
+#
+grant simple to admin;
+show grants for admin;
+Grants for admin
+GRANT simple TO 'admin'
+GRANT USAGE ON *.* TO 'admin'
+GRANT USAGE ON *.* TO 'simple'
+GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES, EXECUTE ON `t`.* TO 'simple'
+#
+# Finally, we give the admin all the available privileges for the db.
+#
+grant all on t.* to admin;
+#
+# Create a user to test out the new roles;
+#
+create user foo;
+grant admin to foo;
+connect foo,localhost,foo,,,,,;
+create database t;
+ERROR 42000: Access denied for user 'foo'@'%' to database 't'
+set role admin;
+show grants;
+Grants for foo@%
+GRANT admin TO 'foo'@'%'
+GRANT USAGE ON *.* TO 'foo'@'%'
+GRANT simple TO 'admin'
+GRANT USAGE ON *.* TO 'admin'
+GRANT ALL PRIVILEGES ON `t`.* TO 'admin'
+GRANT USAGE ON *.* TO 'simple'
+GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES, EXECUTE ON `t`.* TO 'simple'
+create database t;
+drop database t;
+connection default;
+drop role simple;
+drop role admin;
+drop user foo;
diff --git a/mysql-test/suite/roles/set_role-13655.test b/mysql-test/suite/roles/set_role-13655.test
new file mode 100644
index 00000000000..97a82109276
--- /dev/null
+++ b/mysql-test/suite/roles/set_role-13655.test
@@ -0,0 +1,49 @@
+source include/not_embedded.inc;
+
+--echo #
+--echo # MDEV-13655: SET ROLE does not properly grant privileges.
+--echo #
+--echo # We must test that if aditional db privileges get granted to a role
+--echo # which previously inherited privileges from another granted role
+--echo # keep the internal memory structures intact.
+--echo #
+
+create role simple;
+
+--echo #
+--echo # First we create an entry with privileges for databases for the simple role.
+--echo #
+grant select, insert, update, delete, lock tables, execute on t.* to simple;
+create role admin;
+
+--echo #
+--echo # Now we grant the simple role to admin. This means that db privileges
+--echo # should propagate to admin.
+--echo #
+grant simple to admin;
+show grants for admin;
+
+--echo #
+--echo # Finally, we give the admin all the available privileges for the db.
+--echo #
+grant all on t.* to admin;
+
+--echo #
+--echo # Create a user to test out the new roles;
+--echo #
+create user foo;
+grant admin to foo;
+
+connect (foo,localhost,foo,,,,,);
+--error ER_DBACCESS_DENIED_ERROR
+create database t;
+set role admin;
+show grants;
+create database t;
+drop database t;
+
+connection default;
+
+drop role simple;
+drop role admin;
+drop user foo;
diff --git a/mysql-test/suite/roles/set_role-recursive.result b/mysql-test/suite/roles/set_role-recursive.result
index 53b28a25261..2b34c3eeebe 100644
--- a/mysql-test/suite/roles/set_role-recursive.result
+++ b/mysql-test/suite/roles/set_role-recursive.result
@@ -16,11 +16,11 @@ Host User Role Admin_option
test_role1 test_role2 N
grant select on *.* to test_role2;
select * from mysql.user where user like 'test_role1';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
- test_role1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+ test_role1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000
select * from mysql.user where user like 'test_role2';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
- test_role2 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+ test_role2 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000
select * from mysql.roles_mapping;
ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping'
show grants;
diff --git a/mysql-test/suite/roles/set_role-simple.result b/mysql-test/suite/roles/set_role-simple.result
index 29b176776e7..9af698c7b09 100644
--- a/mysql-test/suite/roles/set_role-simple.result
+++ b/mysql-test/suite/roles/set_role-simple.result
@@ -11,8 +11,8 @@ localhost root test_role1 Y
localhost test_user test_role1 N
grant select on *.* to test_role1;
select * from mysql.user where user='test_role1';
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
- test_role1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
+ test_role1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000
select * from mysql.roles_mapping;
ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping'
show grants;
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 ebbe9efc9df..facd40a6018 100644
--- a/mysql-test/suite/rpl/r/rpl_create_drop_view.result
+++ b/mysql-test/suite/rpl/r/rpl_create_drop_view.result
@@ -99,7 +99,7 @@ DROP VIEW v1;
ERROR 42S02: Unknown VIEW: 'test.v1'
DROP VIEW IF EXISTS v2;
Warnings:
-Note 4090 Unknown VIEW: 'test.v2'
+Note 4092 Unknown VIEW: 'test.v2'
# Syncing slave with master
connection slave;
SELECT * FROM v1;
diff --git a/mysql-test/suite/rpl/r/rpl_ctype_latin1.result b/mysql-test/suite/rpl/r/rpl_ctype_latin1.result
new file mode 100644
index 00000000000..5399581ac26
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_ctype_latin1.result
@@ -0,0 +1,34 @@
+include/master-slave.inc
+[connection master]
+#
+# Start of 10.2 tests
+#
+#
+# MDEV-14249 Wrong character set info of Query_log_event and the query in Query_log_event constructed by different charsets cause error when slave apply the event.
+#
+SET NAMES latin1;
+CREATE TABLE `tё` (`tё` INT);
+CREATE VIEW `vё` AS SELECT 'vё';
+CREATE PROCEDURE `pё`() SELECT 'pё';
+select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "t%";
+hex(table_name)
+74C391E28098
+select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "v%";
+hex(table_name)
+76C391E28098
+connection slave;
+select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "t%";
+hex(table_name)
+74C391E28098
+select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "v%";
+hex(table_name)
+76C391E28098
+SHOW PROCEDURE STATUS LIKE 'p%';
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
+test pё PROCEDURE root@localhost ts ts DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
+connection master;
+DROP TABLE `tё`;
+DROP VIEW `vё`;
+DROP PROCEDURE `pё`;
+connection slave;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_events.result b/mysql-test/suite/rpl/r/rpl_events.result
index f7f802a57e6..4b2226109d9 100644
--- a/mysql-test/suite/rpl/r/rpl_events.result
+++ b/mysql-test/suite/rpl/r/rpl_events.result
@@ -2,17 +2,15 @@ include/master-slave.inc
[connection master]
SET @old_event_scheduler = @@global.event_scheduler;
set global event_scheduler=1;
-DROP EVENT IF EXISTS test.justonce;
-drop table if exists t1,t2;
CREATE TABLE `t1` (
`id` INT(10) UNSIGNED NOT NULL,
`c` VARCHAR(50) NOT NULL,
`ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
INSERT INTO t1 (id, c) VALUES (1, 'manually');
"Creating event test.justonce on the master"
-CREATE EVENT test.justonce ON SCHEDULE EVERY 2 SECOND DO
+CREATE EVENT test.justonce ON SCHEDULE EVERY 2 SECOND DO
INSERT IGNORE INTO t1 (id, c) VALUES (2, 'from justonce');
"Checking event is active on master"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
@@ -31,7 +29,7 @@ db name status originator
test justonce SLAVESIDE_DISABLED 1
"Dropping event test.slave_once on the slave"
DROP EVENT IF EXISTS test.slave_once;
-CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
+CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
INSERT IGNORE INTO t1(id, c) VALUES (3, 'from slave_once');
"Checking event status on the slave for originator value = slave's server_id"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_once';
@@ -43,7 +41,7 @@ connection master;
"Dropping event test.justonce on the master"
DROP EVENT IF EXISTS test.justonce;
"Creating event test.er on the master"
-CREATE EVENT test.er ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
+CREATE EVENT test.er ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
INSERT IGNORE INTO t1(id, c) VALUES (4, 'from er');
"Checking event status on the master"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
@@ -56,7 +54,7 @@ db name status originator body
test er SLAVESIDE_DISABLED 1 INSERT IGNORE INTO t1(id, c) VALUES (4, 'from er')
connection master;
"Altering event test.er on the master"
-ALTER EVENT test.er ON SCHEDULE EVERY 5 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
+ALTER EVENT test.er ON SCHEDULE EVERY 5 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
INSERT IGNORE INTO t1(id, c) VALUES (5, 'from alter er');
"Checking event status on the master"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
@@ -78,7 +76,7 @@ connection slave;
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
db name status originator
"Creating event test.slave_terminate on the slave"
-CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
+CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
INSERT IGNORE INTO t1(id, c) VALUES (6, 'from slave_terminate');
"Checking event status on the slave"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_terminate';
@@ -87,7 +85,7 @@ test slave_terminate ENABLED 2
"Dropping event test.slave_terminate on the slave"
DROP EVENT test.slave_terminate;
"Creating event test.slave_terminate with DISABLE ON SLAVE on the slave"
-CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND DISABLE ON SLAVE DO
+CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND DISABLE ON SLAVE DO
INSERT IGNORE INTO t1(c) VALUES (7, 'from slave_terminate');
"Checking event status on the slave"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_terminate';
@@ -100,7 +98,6 @@ connection master;
DROP TABLE t1;
connection slave;
connection master;
-connection master;
CREATE TABLE t28953 (a INT);
CREATE EVENT event1 ON SCHEDULE EVERY 1 YEAR
DO BEGIN
diff --git a/mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result b/mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result
new file mode 100644
index 00000000000..75a22b78a32
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result
@@ -0,0 +1,82 @@
+include/master-slave.inc
+[connection master]
+connection master;
+SET @@SESSION.gtid_domain_id=0;
+CREATE TABLE t (a INT);
+connection slave;
+connection slave;
+call mtr.add_suppression("connecting slave requested to start from.*which is not in the master's binlog");
+include/stop_slave.inc
+CHANGE MASTER TO master_use_gtid=slave_pos;
+connection master;
+SET @@SESSION.gtid_domain_id=11;
+SET @@SESSION.server_id=111;
+SET @@SESSION.gtid_seq_no=1;
+INSERT INTO t SET a=1;
+connection slave;
+SET @save.gtid_slave_pos=@@global.gtid_slave_pos;
+SET @@global.gtid_slave_pos=concat(@@global.gtid_slave_pos, ",", 11, "-", 111, "-", 1 + 1);
+Warnings:
+Warning 1947 Specified GTID 0-1-1 conflicts with the binary log which contains a more recent GTID 0-2-2. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_error.inc [errno=1236]
+connection master;
+FLUSH BINARY LOGS;
+PURGE BINARY LOGS TO 'master-bin.000002';;
+FLUSH BINARY LOGS DELETE_DOMAIN_ID=(11);
+SELECT @@global.gtid_binlog_pos, @@global.gtid_binlog_state;
+@@global.gtid_binlog_pos @@global.gtid_binlog_state
+0-1-1 0-1-1
+connection slave;
+SELECT @@global.gtid_slave_pos;
+@@global.gtid_slave_pos
+0-1-1,11-111-2
+include/start_slave.inc
+==== BEGIN include/start_slave.inc ====
+ con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+START SLAVE;
+.==== BEGIN include/wait_for_slave_to_start.inc ====
+. con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+..==== BEGIN include/wait_for_slave_io_to_start.inc ====
+.. con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+...==== BEGIN include/wait_for_slave_param.inc [Slave_IO_Running] ====
+... con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+Waiting until 'Slave_IO_Running' = 'Yes' [timeout='300', $slave_error_param='Last_IO_Errno']
+[connection slave]
+...==== END include/wait_for_slave_param.inc [Slave_IO_Running] ====
+... con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+[connection slave]
+..==== END include/wait_for_slave_io_to_start.inc ====
+.. con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+..==== BEGIN include/wait_for_slave_sql_to_start.inc ====
+.. con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+...==== BEGIN include/wait_for_slave_param.inc [Slave_SQL_Running] ====
+... con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+Waiting until 'Slave_SQL_Running' = 'Yes' [timeout='300', $slave_error_param='1']
+[connection slave]
+...==== END include/wait_for_slave_param.inc [Slave_SQL_Running] ====
+... con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+[connection slave]
+..==== END include/wait_for_slave_sql_to_start.inc ====
+.. con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+[connection slave]
+.==== END include/wait_for_slave_to_start.inc ====
+. con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+[connection slave]
+==== END include/start_slave.inc ====
+ con='slave' warn='1' qlog='1' rlog='1' aborterr='1'
+connection master;
+INSERT INTO t SET a=1;
+connection slave;
+include/wait_for_slave_io_error.inc [errno=1236]
+connection master;
+FLUSH BINARY LOGS;
+PURGE BINARY LOGS TO 'master-bin.000004';;
+FLUSH BINARY LOGS DELETE_DOMAIN_ID=(11);
+connection slave;
+include/start_slave.inc
+connection master;
+SET @@SESSION.gtid_domain_id=0;
+DROP TABLE t;
+connection slave;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result b/mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result
new file mode 100644
index 00000000000..dc6a67b48d2
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result
@@ -0,0 +1,42 @@
+include/master-slave.inc
+[connection master]
+connection slave;
+call mtr.add_suppression("Slave IO thread did not receive an expected Rows-log end-of-statement");
+call mtr.add_suppression("Relay log write failure: could not queue event from master");
+SET @save_debug= @@global.debug;
+SET GLOBAL debug_dbug="+d,simulate_stmt_end_rows_event_loss";
+include/stop_slave.inc
+CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, MASTER_USE_GTID=SLAVE_POS;
+connection master;
+CREATE TABLE t (a INT, b text(8192));;
+INSERT INTO t values (1, repeat('b', 8192)), (1, repeat('b', 8192));
+connection slave;
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_error.inc [errno=1595]
+SET GLOBAL debug_dbug="-d,simulate_stmt_end_rows_event_loss";
+include/start_slave.inc
+connection master;
+connection slave;
+connection slave;
+include/stop_slave.inc
+connection master;
+SET @save_log_bin_compress= @@GLOBAL.log_bin_compress;
+SET @save_log_bin_compress_min_len= @@GLOBAL.log_bin_compress_min_len;
+SET @@GLOBAL.log_bin_compress=ON;
+SET @@GLOBAL.log_bin_compress_min_len=10;
+INSERT INTO t values (2, repeat('b', 8192)), (2, repeat('b', 8192));
+connection slave;
+SET GLOBAL debug_dbug="+d,simulate_stmt_end_rows_event_loss";
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_error.inc [errno=1595]
+SET GLOBAL debug_dbug="-d,simulate_stmt_end_rows_event_loss";
+include/start_slave.inc
+connection master;
+connection slave;
+connection master;
+SET @@GLOBAL.log_bin_compress= @save_log_bin_compress;
+SET @@GLOBAL.log_bin_compress_min_len= @save_log_bin_compress_min_len;
+DROP TABLE t;
+connection slave;
+SET GLOBAL debug_dbug= @save_debug;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_row_log.result b/mysql-test/suite/rpl/r/rpl_row_log.result
index 0aa718cd405..d0021ac610f 100644
--- a/mysql-test/suite/rpl/r/rpl_row_log.result
+++ b/mysql-test/suite/rpl/r/rpl_row_log.result
@@ -226,7 +226,6 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Binlog_checkpoint # # master-bin.000002
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=MyISAM
master-bin.000002 # Gtid # # GTID #-#-#
@@ -268,7 +267,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=MyISAM
slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002
slave-bin.000002 # Gtid # # GTID #-#-#
slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=MyISAM
slave-bin.000002 # Gtid # # BEGIN GTID #-#-#
diff --git a/mysql-test/suite/rpl/r/rpl_row_log_innodb.result b/mysql-test/suite/rpl/r/rpl_row_log_innodb.result
index 46ad3cb9557..1bf5ec91ed4 100644
--- a/mysql-test/suite/rpl/r/rpl_row_log_innodb.result
+++ b/mysql-test/suite/rpl/r/rpl_row_log_innodb.result
@@ -226,7 +226,6 @@ master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Binlog_checkpoint # # master-bin.000002
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=InnoDB
master-bin.000002 # Gtid # # GTID #-#-#
@@ -268,7 +267,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=InnoDB
slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002
slave-bin.000002 # Gtid # # GTID #-#-#
slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=InnoDB
slave-bin.000002 # Gtid # # BEGIN GTID #-#-#
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync.result
index 6d574681d73..106efb555d3 100644
--- a/mysql-test/suite/rpl/r/rpl_semi_sync.result
+++ b/mysql-test/suite/rpl/r/rpl_semi_sync.result
@@ -4,6 +4,7 @@ connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
+call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave;
call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply");
@@ -176,7 +177,7 @@ Variable_name Value
Rpl_semi_sync_master_yes_tx 14
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
-Rpl_semi_sync_master_clients 1
+Rpl_semi_sync_master_clients 0
[ semi-sync replication of these transactions will fail ]
insert into t1 values (500);
[ master status should be OFF ]
@@ -321,7 +322,6 @@ connection slave;
include/stop_slave.inc
reset slave;
connection master;
-kill query _tid;
connection slave;
include/start_slave.inc
connection master;
@@ -353,7 +353,6 @@ include/stop_slave.inc
reset slave;
connection master;
reset master;
-kill query _tid;
set sql_log_bin=0;
grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password';
flush privileges;
@@ -404,7 +403,6 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
Variable_name Value
Rpl_semi_sync_slave_status OFF
connection master;
-kill query _tid;
[ Semi-sync status on master should be ON ]
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result
index 927113726fa..c61340f3967 100644
--- a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result
+++ b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result
@@ -5,6 +5,7 @@ connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
+call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave;
call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply");
@@ -177,7 +178,7 @@ Variable_name Value
Rpl_semi_sync_master_yes_tx 16
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
-Rpl_semi_sync_master_clients 1
+Rpl_semi_sync_master_clients 0
[ semi-sync replication of these transactions will fail ]
insert into t1 values (500);
[ master status should be OFF ]
@@ -322,7 +323,6 @@ connection slave;
include/stop_slave.inc
reset slave;
connection master;
-kill query _tid;
connection slave;
include/start_slave.inc
connection master;
@@ -354,7 +354,6 @@ include/stop_slave.inc
reset slave;
connection master;
reset master;
-kill query _tid;
set sql_log_bin=0;
grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password';
flush privileges;
@@ -405,7 +404,6 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
Variable_name Value
Rpl_semi_sync_slave_status OFF
connection master;
-kill query _tid;
[ Semi-sync status on master should be ON ]
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result
index 30280551ce2..6a23f24b66d 100644
--- a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result
+++ b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result
@@ -5,6 +5,7 @@ connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
+call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave;
call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply");
@@ -177,7 +178,7 @@ Variable_name Value
Rpl_semi_sync_master_yes_tx 14
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
-Rpl_semi_sync_master_clients 1
+Rpl_semi_sync_master_clients 0
[ semi-sync replication of these transactions will fail ]
insert into t1 values (500);
[ master status should be OFF ]
@@ -322,7 +323,6 @@ connection slave;
include/stop_slave.inc
reset slave;
connection master;
-kill query _tid;
connection slave;
include/start_slave.inc
connection master;
@@ -354,7 +354,6 @@ include/stop_slave.inc
reset slave;
connection master;
reset master;
-kill query _tid;
set sql_log_bin=0;
grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password';
flush privileges;
@@ -405,7 +404,6 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
Variable_name Value
Rpl_semi_sync_slave_status OFF
connection master;
-kill query _tid;
[ Semi-sync status on master should be ON ]
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_event.result b/mysql-test/suite/rpl/r/rpl_semi_sync_event.result
index c347ff410ac..917e7c2b02b 100644
--- a/mysql-test/suite/rpl/r/rpl_semi_sync_event.result
+++ b/mysql-test/suite/rpl/r/rpl_semi_sync_event.result
@@ -5,6 +5,7 @@ call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Semi-sync master .* waiting for slave reply");
call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
+call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave;
call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply");
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_event_after_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync_event_after_sync.result
index c237eb8df47..24daf0d72b5 100644
--- a/mysql-test/suite/rpl/r/rpl_semi_sync_event_after_sync.result
+++ b/mysql-test/suite/rpl/r/rpl_semi_sync_event_after_sync.result
@@ -6,6 +6,7 @@ call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Semi-sync master .* waiting for slave reply");
call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
+call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave;
call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply");
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_skip_repl.result b/mysql-test/suite/rpl/r/rpl_semi_sync_skip_repl.result
new file mode 100644
index 00000000000..811715d1439
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_semi_sync_skip_repl.result
@@ -0,0 +1,30 @@
+include/master-slave.inc
+[connection master]
+connection master;
+call mtr.add_suppression("Timeout waiting for reply of binlog");
+SET @@GLOBAL.rpl_semi_sync_master_enabled = 1;
+SET @@GLOBAL.rpl_semi_sync_master_timeout=100;
+connection slave;
+include/stop_slave.inc
+SET @@GLOBAL.replicate_events_marked_for_skip=FILTER_ON_MASTER;
+SET @@GLOBAL. rpl_semi_sync_slave_enabled = 1;
+include/start_slave.inc
+connection master;
+CREATE TABLE t1 (a INT) ENGINE=innodb;
+SET @@GLOBAL.debug_dbug= "d,dbug_master_binlog_over_2GB";
+SET @@SESSION.skip_replication=1;
+INSERT INTO t1 SET a=1;
+SET @@SESSION.skip_replication=0;
+INSERT INTO t1 SET a=0;
+connection slave;
+connection master;
+SET @@GLOBAL.debug_dbug="";
+SET @@GLOBAL. rpl_semi_sync_master_timeout = 10000;
+SET @@GLOBAL. rpl_semi_sync_master_enabled = 0;
+connection master;
+DROP TABLE t1;
+connection slave;
+include/stop_slave.inc
+SET @@GLOBAL. rpl_semi_sync_slave_enabled = 0;
+SET @@GLOBAL.replicate_events_marked_for_skip = REPLICATE;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result b/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result
deleted file mode 100644
index 68ad4877927..00000000000
--- a/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result
+++ /dev/null
@@ -1,73 +0,0 @@
-include/master-slave.inc
-[connection master]
-call mtr.add_suppression("Read semi-sync reply network error");
-call mtr.add_suppression("Timeout waiting for reply of binlog");
-INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master';
-connection slave;
-INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave';
-UNINSTALL PLUGIN rpl_semi_sync_slave;
-connection master;
-UNINSTALL PLUGIN rpl_semi_sync_master;
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (1);
-DROP TABLE t1;
-connection slave;
-include/install_semisync.inc
-connection master;
-connection slave;
-connection slave;
-show global status like "Slave%_running";
-Variable_name Value
-Slave_running ON
-Slaves_running 1
-UNINSTALL PLUGIN rpl_semi_sync_slave;
-Warnings:
-Warning 1620 Plugin is busy and will be uninstalled on shutdown
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-plugin_name plugin_status
-rpl_semi_sync_slave DELETED
-connection master;
-show global status like "Slave%_connect%";
-Variable_name Value
-Slave_connections 2
-Slaves_connected 1
-UNINSTALL PLUGIN rpl_semi_sync_master;
-Warnings:
-Warning 1620 Plugin is busy and will be uninstalled on shutdown
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-plugin_name plugin_status
-rpl_semi_sync_master DELETED
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (2);
-DROP TABLE t1;
-connection slave;
-show status like "Rpl_semi_sync_slave_status";
-Variable_name Value
-Rpl_semi_sync_slave_status ON
-connection master;
-show status like "Rpl_semi_sync_master_status";
-Variable_name Value
-Rpl_semi_sync_master_status ON
-show status like "Rpl_semi_sync_master_clients";
-Variable_name Value
-Rpl_semi_sync_master_clients 1
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-plugin_name plugin_status
-rpl_semi_sync_master DELETED
-connection slave;
-include/stop_slave.inc
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-plugin_name plugin_status
-connection master;
-create table t2 (a int);
-drop table t2;
-connection slave;
-include/start_slave.inc
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-plugin_name plugin_status
-connection master;
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (3);
-DROP TABLE t1;
-connection slave;
-include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result b/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result
new file mode 100644
index 00000000000..9607e8a7998
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result
@@ -0,0 +1,353 @@
+include/master-slave.inc
+[connection master]
+CALL mtr.add_suppression("Failed to start semi-sync ACK receiver thread.*");
+CALL mtr.add_suppression("Failed to register slave to semi-sync ACK receiver thread.*");
+CALL mtr.add_suppression("Failed to stop ack receiver thread on pthread_join.*");
+CALL mtr.add_suppression("Got an error reading communication packets:*");
+CALL mtr.add_suppression("Timeout waiting for reply of binlog*");
+CALL mtr.add_suppression("slave_read_sync_header*");
+CALL mtr.add_suppression("Missing magic number for semi-sync*");
+CALL mtr.add_suppression("Got timeout reading communication packets*");
+CALL mtr.add_suppression("Failed to call*");
+CALL mtr.add_suppression("Execution failed on master*");
+CALL mtr.add_suppression("Failed on request_dump()*");
+CALL mtr.add_suppression("Semi-sync master failed on*");
+CALL mtr.add_suppression("Master command COM_BINLOG_DUMP failed*");
+CALL mtr.add_suppression("on master failed*");
+CALL mtr.add_suppression("Master server does not support semi-sync*");
+CALL mtr.add_suppression("Semi-sync slave net_flush*");
+CALL mtr.add_suppression("Failed to flush master info*");
+CALL mtr.add_suppression("Request to stop slave SQL Thread received while apply*");
+connection master;
+[ enable semi-sync on master ]
+set global rpl_semi_sync_master_enabled = 1;
+show variables like 'rpl_semi_sync_master_enabled';
+Variable_name Value
+rpl_semi_sync_master_enabled ON
+connection slave;
+[ enable semi-sync on slave ]
+stop slave;
+set global rpl_semi_sync_slave_enabled = 1;
+start slave;
+show status like 'rpl_semi_sync_slave%';
+Variable_name Value
+Rpl_semi_sync_slave_send_ack 0
+Rpl_semi_sync_slave_status ON
+connection master;
+CREATE TABLE t1(a INT) ENGINE=InnoDB;
+connection slave;
+connection master;
+connect con1,localhost,root,,;
+connect con2,localhost,root,,;
+connect con3,localhost,root,,;
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name Value
+Rpl_semi_sync_master_clients 1
+show status like "rpl_semi_sync_master_yes_tx";
+Variable_name Value
+Rpl_semi_sync_master_yes_tx 1
+#########################################
+# Test rpl_semi_sync_master_wait_point #
+#########################################
+# Test after_sync and after_commit first.
+#Test after_sync
+connection con1;
+SET GLOBAL rpl_semi_sync_master_timeout = 1000000;
+SET GLOBAL rpl_semi_sync_master_wait_point= 'AFTER_SYNC';
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL after_sync_done WAIT_FOR end";
+INSERT into t1 values (1);;
+connection con2;
+SET DEBUG_SYNC= "now WAIT_FOR after_sync_done";
+connection slave;
+#slave can see record (1) after sync slave with master
+select * from t1;
+a
+1
+connection con2;
+#con2 shouldn't see record (1)
+select * from t1;
+a
+SET DEBUG_SYNC= "now SIGNAL end";
+connection con1;
+connection con1;
+select * from t1;
+a
+1
+truncate table t1;
+connection slave;
+connection con1;
+SET DEBUG_SYNC= 'reset';
+SET DEBUG_SYNC= "commit_before_get_LOCK_log SIGNAL before_fetch_done WAIT_FOR more_queue";
+INSERT into t1 VALUES (1);;
+connection con2;
+SET DEBUG_SYNC= "now WAIT_FOR before_fetch_done";
+SET DEBUG_SYNC= "after_semisync_queue SIGNAL more_queue";
+INSERT INTO t1 VALUES (2);
+connection con1;
+connection con1;
+SET DEBUG_SYNC= 'reset';
+SET DEBUG_SYNC= "commit_before_get_LOCK_log SIGNAL before_fetch_done WAIT_FOR disable_semisync";
+INSERT into t1 VALUES (3);;
+connection con2;
+SET DEBUG_SYNC= "now WAIT_FOR before_fetch_done";
+SET GLOBAL rpl_semi_sync_master_enabled= 0;
+SET DEBUG_SYNC= "now SIGNAL disable_semisync";
+connection con1;
+SET GLOBAL rpl_semi_sync_master_enabled = 1;
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name Value
+Rpl_semi_sync_master_clients 1
+#Test after_commit
+connection con1;
+SET GLOBAL rpl_semi_sync_master_wait_point= 'AFTER_COMMIT';
+SET DEBUG_SYNC= "after_group_after_commit SIGNAL after_commit_done WAIT_FOR end";
+INSERT into t1 values (4);;
+connection con2;
+SET DEBUG_SYNC= "now WAIT_FOR after_commit_done";
+connection slave;
+select * from t1;
+a
+1
+2
+3
+4
+connection con2;
+select * from t1;
+a
+1
+2
+3
+4
+SET DEBUG_SYNC= "now SIGNAL end";
+connection con1;
+connection con1;
+select * from t1;
+a
+1
+2
+3
+4
+truncate table t1;
+#######################################################
+# Test some other options in order to cover the patch #
+#######################################################
+connection slave;
+# Test rpl_semi_sync_slave_trace_level
+SET GLOBAL rpl_semi_sync_slave_trace_level= 1;
+SET GLOBAL rpl_semi_sync_slave_trace_level= 16;
+SET GLOBAL rpl_semi_sync_slave_trace_level= 64;
+SET GLOBAL rpl_semi_sync_slave_trace_level= 128;
+SET GLOBAL rpl_semi_sync_slave_trace_level= 32;
+connection master;
+# Test rpl_semi_sync_master_trace_level
+SET GLOBAL rpl_semi_sync_master_trace_level= 1;
+SET GLOBAL rpl_semi_sync_master_trace_level= 16;
+SET GLOBAL rpl_semi_sync_master_trace_level= 64;
+SET GLOBAL rpl_semi_sync_master_trace_level= 128;
+SET GLOBAL rpl_semi_sync_master_trace_level= 32;
+# Test rpl_semi_sync_master_timeout
+SET GLOBAL rpl_semi_sync_master_timeout= 1000;
+SET GLOBAL rpl_semi_sync_master_timeout= 10000;
+SET GLOBAL rpl_semi_sync_master_timeout = 1000000;
+# Test rpl_semi_sync_slave_kill_conn_timeout
+SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 10;
+SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 20;
+SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 60;
+SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 5;
+############################################
+# Test rpl_semi_sync_master_wait_no_slave #
+############################################
+SET GLOBAL rpl_semi_sync_master_wait_no_slave = 1;
+connection slave;
+STOP SLAVE IO_THREAD;
+include/wait_for_slave_io_to_stop.inc
+connection con1;
+SET GLOBAL rpl_semi_sync_master_timeout = 1000;
+INSERT INTO t1 values (1);;
+connection con1;
+# Rpl_semi_sync_master_no_tx should be non-zero
+SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx'
+connection slave;
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_to_start.inc
+connection con1;
+INSERT INTO t1 values (2);
+connection slave;
+connection con1;
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name Value
+Rpl_semi_sync_master_clients 1
+show status like 'Rpl_semi_sync_master_status';
+Variable_name Value
+Rpl_semi_sync_master_status ON
+connection slave;
+STOP SLAVE IO_THREAD;
+include/wait_for_slave_io_to_stop.inc
+connection con1;
+SET GLOBAL rpl_semi_sync_master_wait_no_slave= 0;
+SET GLOBAL rpl_semi_sync_master_timeout= 1000000000;
+INSERT INTO t1 values (3);
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name Value
+Rpl_semi_sync_master_clients 0
+show status like 'Rpl_semi_sync_master_status';
+Variable_name Value
+Rpl_semi_sync_master_status OFF
+connection slave;
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_to_start.inc
+connection con1;
+SET GLOBAL rpl_semi_sync_master_timeout= 10000000;
+SET GLOBAL rpl_semi_sync_master_wait_no_slave= 1;
+INSERT INTO t1 values (4);
+connection slave;
+connection con1;
+show status like 'Rpl_semi_sync_master_status';
+Variable_name Value
+Rpl_semi_sync_master_status ON
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name Value
+Rpl_semi_sync_master_clients 1
+##########################################
+# Test rpl_semi_sync_slave_delay_master #
+##########################################
+connection slave;
+SET GLOBAL rpl_semi_sync_slave_delay_master= 1;
+START SLAVE IO_THREAD;
+Warnings:
+Note 1254 Slave is already running
+include/wait_for_slave_io_to_start.inc
+connection con1;
+INSERT INTO t1 values (3);
+include/sync_slave_io_with_master.inc
+connection con1;
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name Value
+Rpl_semi_sync_master_clients 1
+show status like 'Rpl_semi_sync_master_status';
+Variable_name Value
+Rpl_semi_sync_master_status ON
+connection slave;
+connection slave;
+select * from t1 order by a;
+a
+1
+2
+3
+3
+4
+connection con1;
+select * from t1 order by a;
+a
+1
+2
+3
+3
+4
+connection slave;
+SET GLOBAL rpl_semi_sync_slave_delay_master = 0;
+STOP SLAVE IO_THREAD;
+include/wait_for_slave_io_to_stop.inc
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_to_start.inc
+##########################################################
+# Test rpl_semi_sync_master_enabled and new ACK thread #
+#########################################################
+connection con1;
+SET GLOBAL rpl_semi_sync_master_enabled = 0;
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name Value
+Rpl_semi_sync_master_clients 1
+INSERT INTO t1 VALUES (1);
+SET GLOBAL rpl_semi_sync_master_enabled = 1;
+INSERT INTO t1 VALUES (2);
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name Value
+Rpl_semi_sync_master_clients 1
+# Test failure of select error .
+SET GLOBAL debug = 'd,rpl_semisync_simulate_select_error';
+Warnings:
+Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+INSERT INTO t1 VALUES(3);
+connection slave;
+connection con1;
+# Test failure of pthread_create
+SET GLOBAL rpl_semi_sync_master_enabled = 0;
+SET GLOBAL debug = 'd,rpl_semisync_simulate_create_thread_failure';
+Warnings:
+Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+SET GLOBAL rpl_semi_sync_master_enabled= ON;
+# Test failure of pthread_join
+SET GLOBAL rpl_semi_sync_master_enabled= OFF;
+#
+# Failure on registering semisync slave
+#
+SET GLOBAL debug= 'd,rpl_semisync_simulate_add_slave_failure';
+Warnings:
+Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+SET GLOBAL rpl_semi_sync_master_enabled= ON;
+connection slave;
+STOP SLAVE IO_THREAD;
+include/wait_for_slave_io_to_stop.inc
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_to_start.inc
+connection con1;
+SET GLOBAL debug='';
+Warnings:
+Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+connection slave;
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_to_start.inc
+connection con1;
+connection slave;
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name Value
+Rpl_semi_sync_master_clients 0
+##################################################################
+# Test fixing of BUG#70669 #
+#SLAVE CAN'T CONTINUE REPLICATION AFTER MASTER'S CRASH RECOVERY #
+#################################################################
+connection con1;
+SET GLOBAL sync_binlog = 1;
+CREATE TABLE t2 (c1 INT);
+connection slave;
+connection con1;
+INSERT INTO t2 values (1);
+connection slave;
+connection con2;
+connection con1;
+connection slave;
+show tables like 't2';
+Tables_in_test (t2)
+t2
+select * from t2;
+c1
+1
+connection con1;
+INSERT INTO t2 VALUES (2);
+connection con2;
+INSERT INTO t2 VALUES (3);
+connection con1;
+connection con2;
+connection con1;
+SET GLOBAL sync_binlog = 0;
+DROP TABLE t2;
+connection con2;
+connection slave;
+show tables like 't2';
+Tables_in_test (t2)
+connection con2;
+#cleanup
+connection master;
+SET DEBUG_SYNC= 'reset';
+disconnect con1;
+disconnect con2;
+disconnect con3;
+SET GLOBAL rpl_semi_sync_master_timeout= 10000;
+SET GLOBAL rpl_semi_sync_master_enabled = 0;
+DROP TABLE t1;
+connection slave;
+SET GLOBAL rpl_semi_sync_slave_enabled = 0;
+stop slave;
+start slave;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result
index 2849e5b7ae3..97cc4dad8ad 100644
--- a/mysql-test/suite/rpl/r/rpl_sp.result
+++ b/mysql-test/suite/rpl/r/rpl_sp.result
@@ -17,7 +17,7 @@ insert into t1 values (b);
insert into t1 values (unix_timestamp());
end|
select * from mysql.proc where name='foo' and db='mysqltest1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL NO DEFINER begin
declare b int;
set b = 8;
@@ -28,10 +28,10 @@ declare b int;
set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
-end
+end NONE
connection slave;
select * from mysql.proc where name='foo' and db='mysqltest1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL NO DEFINER begin
declare b int;
set b = 8;
@@ -42,7 +42,7 @@ declare b int;
set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
-end
+end NONE
connection master;
set timestamp=1000000000;
call foo();
@@ -128,7 +128,7 @@ show warnings;
Level Code Message
Error 1062 Duplicate entry '20' for key 'a'
Warning 1196 Some non-transactional changed tables couldn't be rolled back
-Note 4092 At line 4 in mysqltest1.foo4
+Note 4094 At line 4 in mysqltest1.foo4
select * from t2;
a
20
@@ -137,19 +137,19 @@ select * from t2;
a
20
select * from mysql.proc where name="foo4" and db='mysqltest1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
mysqltest1 foo4 PROCEDURE foo4 SQL CONTAINS_SQL YES DEFINER begin
insert into t2 values(20),(20);
end root@localhost # # latin1 latin1_swedish_ci latin1_swedish_ci begin
insert into t2 values(20),(20);
-end
+end NONE
connection master;
drop procedure foo4;
select * from mysql.proc where name="foo4" and db='mysqltest1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
connection slave;
select * from mysql.proc where name="foo4" and db='mysqltest1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
connection master;
drop procedure foo;
drop procedure foo2;
@@ -235,22 +235,22 @@ select fn3();
fn3()
0
select * from mysql.proc where db='mysqltest1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
mysqltest1 fn1 FUNCTION fn1 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp();
end root@localhost # # latin1 latin1_swedish_ci latin1_swedish_ci begin
return unix_timestamp();
-end
+end NONE
mysqltest1 fn2 FUNCTION fn2 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp();
end zedjzlcsjhd@localhost # # latin1 latin1_swedish_ci latin1_swedish_ci begin
return unix_timestamp();
-end
+end NONE
mysqltest1 fn3 FUNCTION fn3 SQL READS_SQL_DATA NO DEFINER int(11) begin
return 0;
end root@localhost # # latin1 latin1_swedish_ci latin1_swedish_ci begin
return 0;
-end
+end NONE
select * from t1;
a
1000000000
@@ -260,22 +260,22 @@ select * from t1;
a
1000000000
select * from mysql.proc where db='mysqltest1';
-db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
mysqltest1 fn1 FUNCTION fn1 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp();
end root@localhost # # latin1 latin1_swedish_ci latin1_swedish_ci begin
return unix_timestamp();
-end
+end NONE
mysqltest1 fn2 FUNCTION fn2 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp();
end zedjzlcsjhd@localhost # # latin1 latin1_swedish_ci latin1_swedish_ci begin
return unix_timestamp();
-end
+end NONE
mysqltest1 fn3 FUNCTION fn3 SQL READS_SQL_DATA NO DEFINER int(11) begin
return 0;
end root@localhost # # latin1 latin1_swedish_ci latin1_swedish_ci begin
return 0;
-end
+end NONE
connection master;
delete from t2;
alter table t2 add unique (a);
@@ -291,7 +291,7 @@ end|
do fn1(100);
Warnings:
Error 1062 Duplicate entry '100' for key 'a'
-Note 4092 At line 3 in mysqltest1.fn1
+Note 4094 At line 3 in mysqltest1.fn1
Warning 1196 Some non-transactional changed tables couldn't be rolled back
select fn1(20);
ERROR 23000: Duplicate entry '20' for key 'a'
diff --git a/mysql-test/suite/rpl/r/rpl_stm_log.result b/mysql-test/suite/rpl/r/rpl_stm_log.result
index 6453538009a..0b3f9bfe350 100644
--- a/mysql-test/suite/rpl/r/rpl_stm_log.result
+++ b/mysql-test/suite/rpl/r/rpl_stm_log.result
@@ -222,7 +222,6 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Binlog_checkpoint # # master-bin.000002
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=MyISAM
master-bin.000002 # Gtid # # GTID #-#-#
@@ -260,7 +259,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=MyISAM
slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002
slave-bin.000002 # Gtid # # GTID #-#-#
slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=MyISAM
slave-bin.000002 # Gtid # # BEGIN GTID #-#-#
diff --git a/mysql-test/suite/rpl/r/rpl_update.result b/mysql-test/suite/rpl/r/rpl_update.result
new file mode 100644
index 00000000000..31bc50a78de
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_update.result
@@ -0,0 +1,16 @@
+include/master-slave.inc
+[connection master]
+set sql_mode=simultaneous_assignment;
+create table t1 (a int, b int);
+insert into t1 values(1, 2);
+update t1 set a=b, b=a;
+select * from t1;
+a b
+2 1
+connection slave;
+select * from t1;
+a b
+2 1
+connection master;
+drop table t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_view_debug.result b/mysql-test/suite/rpl/r/rpl_view_debug.result
index 22032c3fb90..497f4303698 100644
--- a/mysql-test/suite/rpl/r/rpl_view_debug.result
+++ b/mysql-test/suite/rpl/r/rpl_view_debug.result
@@ -23,7 +23,7 @@ v1
connection master;
set @@debug_dbug="d,simulate_register_view_failure";
CREATE VIEW v2 as SELECT * FROM t1;
-ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
+ERROR HY000: Out of memory.
show tables;
Tables_in_test
t1
diff --git a/mysql-test/suite/rpl/t/rpl_ctype_latin1.test b/mysql-test/suite/rpl/t/rpl_ctype_latin1.test
new file mode 100644
index 00000000000..a85254214d2
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_ctype_latin1.test
@@ -0,0 +1,44 @@
+--source include/have_lowercase0.inc
+--disable_warnings
+--source include/master-slave.inc
+--enable_warnings
+
+--echo #
+--echo # Start of 10.2 tests
+--echo #
+
+
+--echo #
+--echo # MDEV-14249 Wrong character set info of Query_log_event and the query in Query_log_event constructed by different charsets cause error when slave apply the event.
+--echo #
+
+#
+# The below tests uses a sequence of bytes 0xD191,
+# which in a utf8 console looks like Ñ‘ (CYRILIC SMALL LETTER YO).
+# Don't be mislead. This sequence is used in latin1 context and
+# represents a sequence of two characters:
+# U+00D1 CAPITAL LATIN LETTER N WITH TILDE (_latin1 0xD1)
+# U+2018 LEFT SINGLE QUOTATION MARK (_latin1 0x91)
+#
+
+SET NAMES latin1;
+CREATE TABLE `tё` (`tё` INT);
+CREATE VIEW `vё` AS SELECT 'vё';
+CREATE PROCEDURE `pё`() SELECT 'pё';
+
+select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "t%";
+select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "v%";
+
+--sync_slave_with_master
+select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "t%";
+select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "v%";
+--replace_column 5 ts 6 ts
+SHOW PROCEDURE STATUS LIKE 'p%';
+
+--connection master
+DROP TABLE `tё`;
+DROP VIEW `vё`;
+DROP PROCEDURE `pё`;
+--sync_slave_with_master
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_events.test b/mysql-test/suite/rpl/t/rpl_events.test
index 5bdf8ad2412..3e73fc7a3ee 100644
--- a/mysql-test/suite/rpl/t/rpl_events.test
+++ b/mysql-test/suite/rpl/t/rpl_events.test
@@ -9,16 +9,158 @@
SET @old_event_scheduler = @@global.event_scheduler;
set global event_scheduler=1;
-let $engine_type= MyISAM;
+# first, we need a table to record something from an event
+
+eval CREATE TABLE `t1` (
+ `id` INT(10) UNSIGNED NOT NULL,
+ `c` VARCHAR(50) NOT NULL,
+ `ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 (id, c) VALUES (1, 'manually');
+
+# We create the event so that it inserts exactly 1 row in the table
+# A recuring event is used so that we can be sure the event will
+# fire regardless of timing delays on the server. Otherwise, it is
+# possible for the event to timeout before it has inserted a row.
+--echo "Creating event test.justonce on the master"
+CREATE EVENT test.justonce ON SCHEDULE EVERY 2 SECOND DO
+ INSERT IGNORE INTO t1 (id, c) VALUES (2, 'from justonce');
+
+# Show the event is alive and present on master
+--echo "Checking event is active on master"
+SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
+
+# Wait until event has fired. We know this because t1 will contain
+# the row from the event.
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM t1 WHERE c = 'from justonce';
+--source include/wait_condition.inc
+
+# check that table t1 contains something
+--echo "Checking event data on the master"
+let $events_done=`SELECT count(*) FROM t1 id`;
+--disable_query_log
+eval SELECT $events_done > 0 as ONE;
+--enable_query_log
---source include/rpl_events.inc
+sync_slave_with_master;
+
+--echo "Checking event data on the slave"
+--disable_query_log
+eval SELECT count(*) - $events_done as ZERO FROM t1 id;
+--enable_query_log
+
+--echo "Checking event is inactive on slave"
+SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
+
+# Create an event on the slave and check to see what the originator is.
+--echo "Dropping event test.slave_once on the slave"
+--disable_warnings
+DROP EVENT IF EXISTS test.slave_once;
+--enable_warnings
+
+# Create an event on slave and check its state. An event shouldn't be executed
+# so set start time in 1 hour.
+CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
+ INSERT IGNORE INTO t1(id, c) VALUES (3, 'from slave_once');
+
+--echo "Checking event status on the slave for originator value = slave's server_id"
+SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_once';
+
+--echo "Dropping event test.slave_once on the slave"
+--disable_warnings
+DROP EVENT IF EXISTS test.slave_once;
+--enable_warnings
+
+connection master;
+
+# BUG#20384 - disable events on slave
+--echo "Dropping event test.justonce on the master"
+--disable_warnings
+DROP EVENT IF EXISTS test.justonce;
+--enable_warnings
+
+# Create an event on master and check its state on slave. An event shouldn't be executed
+# so set start time in 1 hour. Check that changes of event statement replicated to slave
+
+--echo "Creating event test.er on the master"
+CREATE EVENT test.er ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
+ INSERT IGNORE INTO t1(id, c) VALUES (4, 'from er');
+
+--echo "Checking event status on the master"
+SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
+
+sync_slave_with_master;
+
+--echo "Checking event status on the slave"
+SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
+
+connection master;
+--echo "Altering event test.er on the master"
+ALTER EVENT test.er ON SCHEDULE EVERY 5 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
+ INSERT IGNORE INTO t1(id, c) VALUES (5, 'from alter er');
+
+--echo "Checking event status on the master"
+SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
+
+sync_slave_with_master;
+
+--echo "Checking event status on the slave"
+SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
+
+connection master;
+--echo "Dropping event test.er on the master"
+DROP EVENT test.er;
+
+--echo "Checking event status on the master"
+SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
+
+--disable_info
+
+sync_slave_with_master;
+
+--echo "Checking event status on the slave"
+SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
+
+# test the DISABLE ON SLAVE for setting event SLAVESIDE_DISABLED as status
+# on CREATE EVENT
+
+# Create an event on slave and check its status. An event shouldn't be executed
+# so set start time in 1 hour.
+
+--echo "Creating event test.slave_terminate on the slave"
+CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
+ INSERT IGNORE INTO t1(id, c) VALUES (6, 'from slave_terminate');
+
+--echo "Checking event status on the slave"
+SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_terminate';
+
+--echo "Dropping event test.slave_terminate on the slave"
+DROP EVENT test.slave_terminate;
+
+--echo "Creating event test.slave_terminate with DISABLE ON SLAVE on the slave"
+CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND DISABLE ON SLAVE DO
+ INSERT IGNORE INTO t1(c) VALUES (7, 'from slave_terminate');
+
+--echo "Checking event status on the slave"
+SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_terminate';
+
+--echo "Dropping event test.slave_terminate on the slave"
+DROP EVENT test.slave_terminate;
+
+--echo "Cleanup"
+
+connection master;
+DROP TABLE t1;
+sync_slave_with_master;
+connection master;
#
# Bug #28953 Using events in a replication let the slave crash.
#
-connection master;
-
CREATE TABLE t28953 (a INT);
DELIMITER |;
@@ -39,7 +181,7 @@ DROP EVENT event2;
#
# BUG#44331
# This test verifies if the definer is consistent between master and slave,
-# when the event is created without the DEFINER clause set explicitly or the
+# when the event is created without the DEFINER clause set explicitly or the
# DEFINER is set to CURRENT_USER
#
CREATE TABLE test.t1(details CHAR(30));
@@ -53,7 +195,7 @@ CREATE DEFINER=CURRENT_USER /*!50000 EVENT event44331_2 */
ON SCHEDULE AT CURRENT_TIMESTAMP
ON COMPLETION PRESERVE DISABLE
DO INSERT INTO test.t1 VALUES('event event44331_2 fired - DEFINER=CURRENT_USER');
-
+
CREATE DEFINER=CURRENT_USER() EVENT event44331_3
ON SCHEDULE AT CURRENT_TIMESTAMP
ON COMPLETION PRESERVE DISABLE
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test b/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test
new file mode 100644
index 00000000000..622e66c5263
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test
@@ -0,0 +1,98 @@
+# In case master's gtid binlog state is divergent from the slave's gtid_slave_pos
+# slave may not be able to connect.
+# For instance when slave is more updated in some of domains, see
+# MDEV-12012 as example, the master's state may require adjustment.
+# In a specific case of an "old" divergent domain, that is there
+# won't be no more event groups from it generated, the states can be
+# made compatible with wiping the problematic domain away. After that slave
+# becomes connectable.
+#
+# Notice that the slave applied gtid state is not really required to
+# be similarly cleaned in order for replication to flow.
+# However this could lead to an expected error when the master
+# resumes binlogging of such domain which the test demonstrate.
+
+--source include/master-slave.inc
+
+--connection master
+# enforce the default domain_id binlogging explicitly
+SET @@SESSION.gtid_domain_id=0;
+CREATE TABLE t (a INT);
+--sync_slave_with_master
+
+--connection slave
+call mtr.add_suppression("connecting slave requested to start from.*which is not in the master's binlog");
+
+--source include/stop_slave.inc
+CHANGE MASTER TO master_use_gtid=slave_pos;
+
+--connection master
+# create extra gtid domains for binlog state
+--let $extra_domain_id=11
+--let $extra_domain_server_id=111
+--let $extra_gtid_seq_no=1
+--eval SET @@SESSION.gtid_domain_id=$extra_domain_id
+--eval SET @@SESSION.server_id=$extra_domain_server_id
+--eval SET @@SESSION.gtid_seq_no=$extra_gtid_seq_no
+INSERT INTO t SET a=1;
+
+#
+# Set up the slave replication state as if slave knows more events from the extra
+# domain.
+#
+--connection slave
+SET @save.gtid_slave_pos=@@global.gtid_slave_pos;
+--eval SET @@global.gtid_slave_pos=concat(@@global.gtid_slave_pos, ",", $extra_domain_id, "-", $extra_domain_server_id, "-", $extra_gtid_seq_no + 1)
+
+# unsuccessful attempt to start slave
+START SLAVE IO_THREAD;
+--let $slave_io_errno=1236
+--source include/wait_for_slave_io_error.inc
+
+--connection master
+# adjust the master binlog state
+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
+--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID=($extra_domain_id)
+SELECT @@global.gtid_binlog_pos, @@global.gtid_binlog_state;
+--connection slave
+SELECT @@global.gtid_slave_pos;
+# start the slave sucessfully
+--let rpl_debug=1
+--source include/start_slave.inc
+--let rpl_debug=0
+
+--connection master
+# but the following gtid from the *extra* domain will break replication
+INSERT INTO t SET a=1;
+
+# take note of the slave io thread error due to being dismissed
+# extra domain at connection to master which tried becoming active;
+# slave is to stop.
+--connection slave
+--let $errno=1236
+--source include/wait_for_slave_io_error.inc
+
+# let's apply the very same medicine
+--connection master
+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
+--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID=($extra_domain_id)
+
+--connection slave
+--source include/start_slave.inc
+
+#
+# cleanup
+#
+--connection master
+SET @@SESSION.gtid_domain_id=0;
+DROP TABLE t;
+
+sync_slave_with_master;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test
index 981cecb66ad..1c087c550d0 100644
--- a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test
+++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test
@@ -25,7 +25,7 @@ sync_slave_with_master;
connection master;
# Delete './master-bin.000001' from index file.
let $MYSQLD_DATADIR= `SELECT @@DATADIR`;
-let $file= $MYSQLD_DATADIR/master-bin.index;
+let TRUNCATE_FILE= $MYSQLD_DATADIR/master-bin.index;
source include/truncate_file.inc;
if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`)
diff --git a/mysql-test/suite/rpl/t/rpl_mdev359.test b/mysql-test/suite/rpl/t/rpl_mdev359.test
index 3026c6d363e..5b02ecd72c0 100644
--- a/mysql-test/suite/rpl/t/rpl_mdev359.test
+++ b/mysql-test/suite/rpl/t/rpl_mdev359.test
@@ -1,4 +1,3 @@
---source include/have_semisync.inc
--source include/not_embedded.inc
--source include/have_debug_sync.inc
--source include/have_binlog_format_mixed_or_statement.inc
diff --git a/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt
new file mode 100644
index 00000000000..144bbca0730
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt
@@ -0,0 +1,2 @@
+--binlog-row-event-max-size=8192
+
diff --git a/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test
new file mode 100644
index 00000000000..5b2d99f3bf1
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test
@@ -0,0 +1,66 @@
+--source include/have_debug.inc
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+# Loss of STMT_END flagged event must error out the IO thread
+--connection slave
+call mtr.add_suppression("Slave IO thread did not receive an expected Rows-log end-of-statement");
+call mtr.add_suppression("Relay log write failure: could not queue event from master");
+
+SET @save_debug= @@global.debug;
+SET GLOBAL debug_dbug="+d,simulate_stmt_end_rows_event_loss";
+--source include/stop_slave.inc
+--replace_result $MASTER_MYPORT MASTER_PORT
+--eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, MASTER_USE_GTID=SLAVE_POS
+
+--connection master
+--let $max_row_size=8192
+--eval CREATE TABLE t (a INT, b text($max_row_size));
+--eval INSERT INTO t values (1, repeat('b', $max_row_size)), (1, repeat('b', $max_row_size))
+
+# Prove that the missed STMT_END marked rows-event causes the io thread stop.
+--connection slave
+START SLAVE IO_THREAD;
+--let $slave_io_errno=1595
+--source include/wait_for_slave_io_error.inc
+SET GLOBAL debug_dbug="-d,simulate_stmt_end_rows_event_loss";
+--source include/start_slave.inc
+
+--connection master
+sync_slave_with_master;
+
+# Compressed version of the above
+--connection slave
+--source include/stop_slave.inc
+
+--connection master
+SET @save_log_bin_compress= @@GLOBAL.log_bin_compress;
+SET @save_log_bin_compress_min_len= @@GLOBAL.log_bin_compress_min_len;
+
+SET @@GLOBAL.log_bin_compress=ON;
+SET @@GLOBAL.log_bin_compress_min_len=10;
+
+--eval INSERT INTO t values (2, repeat('b', $max_row_size)), (2, repeat('b', $max_row_size))
+
+# Prove that the missed STMT_END marked rows-event causes the io thread stop.
+--connection slave
+SET GLOBAL debug_dbug="+d,simulate_stmt_end_rows_event_loss";
+START SLAVE IO_THREAD;
+--let $slave_io_errno=1595
+--source include/wait_for_slave_io_error.inc
+SET GLOBAL debug_dbug="-d,simulate_stmt_end_rows_event_loss";
+--source include/start_slave.inc
+
+--connection master
+sync_slave_with_master;
+
+# cleanup
+
+--connection master
+SET @@GLOBAL.log_bin_compress= @save_log_bin_compress;
+SET @@GLOBAL.log_bin_compress_min_len= @save_log_bin_compress_min_len;
+DROP TABLE t;
+sync_slave_with_master;
+SET GLOBAL debug_dbug= @save_debug;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test
index b8f3c8130be..4d96fd694ec 100644
--- a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test
@@ -1,4 +1,3 @@
-source include/have_semisync.inc;
source include/not_embedded.inc;
source include/have_innodb.inc;
source include/master-slave.inc;
@@ -11,6 +10,8 @@ call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Semi-sync master .* waiting for slave reply");
call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
+call mtr.add_suppression("mysqld: Got an error reading communication packets");
+
connection slave;
call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply");
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_skip_repl.test b/mysql-test/suite/rpl/t/rpl_semi_sync_skip_repl.test
new file mode 100644
index 00000000000..f5c423741a6
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync_skip_repl.test
@@ -0,0 +1,61 @@
+# MDEV-14721 Big transaction events get lost on semisync master when
+# replicate_events_marked_for_skip=FILTER_ON_MASTER
+#
+# When events of a big transaction are binlogged offsetting over 2GB from
+# the beginning of the log the semisync master's dump thread
+# lost such events.
+# The test verifies the fixes' correctness simulating the 2GB offset.
+
+source include/not_embedded.inc;
+source include/have_innodb.inc;
+source include/have_debug.inc;
+source include/master-slave.inc;
+
+--connection master
+# Suppress warnings that might be generated during the test
+call mtr.add_suppression("Timeout waiting for reply of binlog");
+
+--let $sav_enabled_master=`SELECT @@GLOBAL.rpl_semi_sync_master_enabled `
+--let $sav_timeout_master=`SELECT @@GLOBAL.rpl_semi_sync_master_timeout `
+SET @@GLOBAL.rpl_semi_sync_master_enabled = 1;
+SET @@GLOBAL.rpl_semi_sync_master_timeout=100;
+
+--connection slave
+source include/stop_slave.inc;
+--let $sav_skip_marked_slave=`SELECT @@GLOBAL.replicate_events_marked_for_skip `
+SET @@GLOBAL.replicate_events_marked_for_skip=FILTER_ON_MASTER;
+--let $sav_enabled_slave=`SELECT @@GLOBAL.rpl_semi_sync_slave_enabled `
+SET @@GLOBAL. rpl_semi_sync_slave_enabled = 1;
+
+source include/start_slave.inc;
+
+--connection master
+CREATE TABLE t1 (a INT) ENGINE=innodb;
+
+# Make the following events as if they offset over 2GB from the beginning of binlog
+SET @@GLOBAL.debug_dbug= "d,dbug_master_binlog_over_2GB";
+SET @@SESSION.skip_replication=1;
+INSERT INTO t1 SET a=1;
+SET @@SESSION.skip_replication=0;
+INSERT INTO t1 SET a=0;
+
+--sync_slave_with_master
+
+#
+# Clean up
+#
+--connection master
+SET @@GLOBAL.debug_dbug="";
+--eval SET @@GLOBAL. rpl_semi_sync_master_timeout = $sav_timeout_master
+--eval SET @@GLOBAL. rpl_semi_sync_master_enabled = $sav_enabled_master
+
+--connection master
+DROP TABLE t1;
+
+--sync_slave_with_master
+source include/stop_slave.inc;
+--eval SET @@GLOBAL. rpl_semi_sync_slave_enabled = $sav_enabled_slave
+--eval SET @@GLOBAL.replicate_events_marked_for_skip = $sav_skip_marked_slave
+
+--let $rpl_only_running_threads= 1
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test b/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test
deleted file mode 100644
index 360706922ea..00000000000
--- a/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test
+++ /dev/null
@@ -1,132 +0,0 @@
-###############################################################################
-# Bug#17638477 UNINSTALL AND INSTALL SEMI-SYNC PLUGIN CAUSES SLAVES TO BREAK
-# Problem: Uninstallation of Semi sync plugin should be blocked when it is
-# in use.
-# Test case: Uninstallation of semi sync should be allowed
-# On Master:
-# 1) When there is no dump thread
-# 2) When there are no semi sync slaves (i.e., async replication).
-# On Slave:
-# 1) When there is no I/O thread
-# 2) When there are no semi sync enabled I/O thread (i.e.,async replication).
-###############################################################################
-
---source include/have_semisync_plugin.inc
---source include/not_embedded.inc
---source include/have_binlog_format_statement.inc
---source include/master-slave.inc
-
-call mtr.add_suppression("Read semi-sync reply network error");
-call mtr.add_suppression("Timeout waiting for reply of binlog");
-
-###############################################################################
-# Case 1: Uninstallation of semi sync plugins should be allowed when it is
-# not in use i.e., when asynchronous replication is active.
-###############################################################################
-# Step 1.1: Install semi sync master plugin on master
-INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master';
-
-# Step 1.2: Install semi sync slave plugin on slave
---connection slave
-INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave';
-
-# Step 1.3: Uninstallation of semisync plugin on master and slave should be
-# allowed at this state as there is no semi sync replication enabled between
-# master and slave.
-UNINSTALL PLUGIN rpl_semi_sync_slave;
---connection master
-UNINSTALL PLUGIN rpl_semi_sync_master;
-
-# Step 1.4: Check that replication is working fine at the end of the test case.
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (1);
-DROP TABLE t1;
---sync_slave_with_master
-
-###############################################################################
-# Case 2: Uninstallation of semi sync plugins should be disallowed
-# when it is in use i.e., when semi sync replication is active
-###############################################################################
-# Step 2.1: Install and enable semi sync replication between master and slave
---source include/install_semisync.inc
-
-# Step 2.2: Check that rpl_semi_sync_slave uninstallation on Slave is not
-# possible at this state
---connection slave
-show global status like "Slave%_running";
-
-UNINSTALL PLUGIN rpl_semi_sync_slave;
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-
-# Step 2.3: Check that rpl_semi_sync_master uninstallation on Master is not
-# possible at this state
---connection master
-
-# The following is to catch errors if the next uninstall plugin would succeed
-show global status like "Slave%_connect%";
-
-UNINSTALL PLUGIN rpl_semi_sync_master;
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-
-# Step 2.4: Check that replication is working fine at the end of the test case.
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (2);
-DROP TABLE t1;
---sync_slave_with_master
-
-# Step 2.5: Make sure rpl_semi_sync_master_status on Master and
-# rpl_semi_sync_slave_staus on Slave are ON
-show status like "Rpl_semi_sync_slave_status";
-
-###############################################################################
-# Case 3: Uninstallation of semi sync plugin should be disallowed when there
-# are semi sync slaves even though rpl_semi_sync_master_enabled= OFF;.
-###############################################################################
-# Step 3.1: Disable semi sync on master
---connection master
-show status like "Rpl_semi_sync_master_status";
-
-# Step 3.2: Check that still Rpl_semi_sync_master_clients is 1
-show status like "Rpl_semi_sync_master_clients";
-
-# Step 3.3: Since Rpl_semi_sync_master_clients is 1, uninstallation of
-# rpl_semi_sync_master should be disallowed.
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-
-###############################################################################
-# Case 4: Uninstallation of semi sync plugin should be allowed when it is not
-# in use. Same as Case 1 but this case is to check the case after enabling and
-# disabling semi sync replication.
-###############################################################################
-
-# Step 4.1: Stop IO thread on slave.
---connection slave
---source include/stop_slave.inc
-
-# Step 4.2: Disable semi sync on slave.
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-
---connection master
-# Send something to the slave so that the master would notice that nobody's listening.
-create table t2 (a int); drop table t2;
-# and wait for plugin to be unloaded automatically
-let $wait_condition=select count(*) = 0 from information_schema.plugins where plugin_name like 'rpl_%';
---source include/wait_condition.inc
-
---connection slave
-
-# Step 4.3: Start IO thread on slave.
---source include/start_slave.inc
-
-# Step 4.4: Uninstall semi sync plugin, it should be successful now.
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-
-# Step 4.7: Check that replication is working fine at the end of the test case
---connection master
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (3);
-DROP TABLE t1;
---sync_slave_with_master
-
-# Cleanup
-source include/rpl_end.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test b/mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test
index 6e4dc456a27..dcff4030fdb 100644
--- a/mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test
@@ -1,4 +1,3 @@
-source include/have_semisync.inc;
source include/not_embedded.inc;
source include/have_innodb.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_semisync_ali_issues-master.opt b/mysql-test/suite/rpl/t/rpl_semisync_ali_issues-master.opt
new file mode 100644
index 00000000000..2672d4ff35e
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_semisync_ali_issues-master.opt
@@ -0,0 +1 @@
+--binlog_format=row
diff --git a/mysql-test/suite/rpl/t/rpl_semisync_ali_issues-slave.opt b/mysql-test/suite/rpl/t/rpl_semisync_ali_issues-slave.opt
new file mode 100644
index 00000000000..2672d4ff35e
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_semisync_ali_issues-slave.opt
@@ -0,0 +1 @@
+--binlog_format=row
diff --git a/mysql-test/suite/rpl/t/rpl_semisync_ali_issues.test b/mysql-test/suite/rpl/t/rpl_semisync_ali_issues.test
new file mode 100644
index 00000000000..52cd9e31753
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_semisync_ali_issues.test
@@ -0,0 +1,410 @@
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+--source include/master-slave.inc
+
+CALL mtr.add_suppression("Failed to start semi-sync ACK receiver thread.*");
+CALL mtr.add_suppression("Failed to register slave to semi-sync ACK receiver thread.*");
+CALL mtr.add_suppression("Failed to stop ack receiver thread on pthread_join.*");
+CALL mtr.add_suppression("Got an error reading communication packets:*");
+CALL mtr.add_suppression("Timeout waiting for reply of binlog*");
+CALL mtr.add_suppression("slave_read_sync_header*");
+CALL mtr.add_suppression("Missing magic number for semi-sync*");
+CALL mtr.add_suppression("Got timeout reading communication packets*");
+CALL mtr.add_suppression("Failed to call*");
+CALL mtr.add_suppression("Execution failed on master*");
+CALL mtr.add_suppression("Failed on request_dump()*");
+CALL mtr.add_suppression("Semi-sync master failed on*");
+CALL mtr.add_suppression("Master command COM_BINLOG_DUMP failed*");
+CALL mtr.add_suppression("on master failed*");
+CALL mtr.add_suppression("Master server does not support semi-sync*");
+CALL mtr.add_suppression("Semi-sync slave net_flush*");
+CALL mtr.add_suppression("Failed to flush master info*");
+CALL mtr.add_suppression("Request to stop slave SQL Thread received while apply*");
+
+connection master;
+echo [ enable semi-sync on master ];
+set global rpl_semi_sync_master_enabled = 1;
+show variables like 'rpl_semi_sync_master_enabled';
+
+connection slave;
+echo [ enable semi-sync on slave ];
+stop slave;
+set global rpl_semi_sync_slave_enabled = 1;
+start slave;
+show status like 'rpl_semi_sync_slave%';
+
+connection master;
+CREATE TABLE t1(a INT) ENGINE=InnoDB;
+sync_slave_with_master;
+
+connection master;
+connect(con1,localhost,root,,);
+connect(con2,localhost,root,,);
+connect(con3,localhost,root,,);
+
+show status like 'Rpl_semi_sync_master_clients';
+show status like "rpl_semi_sync_master_yes_tx";
+
+--echo #########################################
+--echo # Test rpl_semi_sync_master_wait_point #
+--echo #########################################
+--echo # Test after_sync and after_commit first.
+
+--echo #Test after_sync
+connection con1;
+# Let's set a very large timeout value for testing purpose.
+SET GLOBAL rpl_semi_sync_master_timeout = 1000000;
+SET GLOBAL rpl_semi_sync_master_wait_point= 'AFTER_SYNC';
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL after_sync_done WAIT_FOR end";
+--send INSERT into t1 values (1);
+
+connection con2;
+SET DEBUG_SYNC= "now WAIT_FOR after_sync_done";
+
+sync_slave_with_master;
+--echo #slave can see record (1) after sync slave with master
+select * from t1;
+
+connection con2;
+--echo #con2 shouldn't see record (1)
+select * from t1;
+SET DEBUG_SYNC= "now SIGNAL end";
+
+connection con1;
+reap;
+
+connection con1;
+select * from t1;
+truncate table t1;
+
+sync_slave_with_master;
+
+# Test more threads in one semisync queue
+connection con1;
+SET DEBUG_SYNC= 'reset';
+SET DEBUG_SYNC= "commit_before_get_LOCK_log SIGNAL before_fetch_done WAIT_FOR more_queue";
+#SET DEBUG_SYNC= "before_semisync_fetch SIGNAL before_fetch_done WAIT_FOR more_queue";
+--send INSERT into t1 VALUES (1);
+
+connection con2;
+SET DEBUG_SYNC= "now WAIT_FOR before_fetch_done";
+SET DEBUG_SYNC= "after_semisync_queue SIGNAL more_queue";
+INSERT INTO t1 VALUES (2);
+
+connection con1;
+reap;
+
+# Test more threads in one semisync queue, but disable semisync before
+# waiting.
+connection con1;
+SET DEBUG_SYNC= 'reset';
+SET DEBUG_SYNC= "commit_before_get_LOCK_log SIGNAL before_fetch_done WAIT_FOR disable_semisync";
+#SET DEBUG_SYNC= "before_semisync_fetch SIGNAL before_fetch_done WAIT_FOR more_queue";
+#SET DEBUG_SYNC= "before_semisync_fetch SIGNAL before_fetch_done WAIT_FOR disable_semisync";
+--send INSERT into t1 VALUES (3);
+
+connection con2;
+SET DEBUG_SYNC= "now WAIT_FOR before_fetch_done";
+SET GLOBAL rpl_semi_sync_master_enabled= 0;
+SET DEBUG_SYNC= "now SIGNAL disable_semisync";
+
+connection con1;
+reap;
+SET GLOBAL rpl_semi_sync_master_enabled = 1;
+show status like 'Rpl_semi_sync_master_clients';
+
+--echo #Test after_commit
+connection con1;
+SET GLOBAL rpl_semi_sync_master_wait_point= 'AFTER_COMMIT';
+SET DEBUG_SYNC= "after_group_after_commit SIGNAL after_commit_done WAIT_FOR end";
+--send INSERT into t1 values (4);
+
+connection con2;
+SET DEBUG_SYNC= "now WAIT_FOR after_commit_done";
+
+sync_slave_with_master;
+select * from t1;
+
+connection con2;
+select * from t1;
+SET DEBUG_SYNC= "now SIGNAL end";
+
+connection con1;
+reap;
+
+connection con1;
+select * from t1;
+truncate table t1;
+
+--echo #######################################################
+--echo # Test some other options in order to cover the patch #
+--echo #######################################################
+connection slave;
+--echo # Test rpl_semi_sync_slave_trace_level
+SET GLOBAL rpl_semi_sync_slave_trace_level= 1;
+SET GLOBAL rpl_semi_sync_slave_trace_level= 16;
+SET GLOBAL rpl_semi_sync_slave_trace_level= 64;
+SET GLOBAL rpl_semi_sync_slave_trace_level= 128;
+SET GLOBAL rpl_semi_sync_slave_trace_level= 32;
+connection master;
+--echo # Test rpl_semi_sync_master_trace_level
+SET GLOBAL rpl_semi_sync_master_trace_level= 1;
+SET GLOBAL rpl_semi_sync_master_trace_level= 16;
+SET GLOBAL rpl_semi_sync_master_trace_level= 64;
+SET GLOBAL rpl_semi_sync_master_trace_level= 128;
+SET GLOBAL rpl_semi_sync_master_trace_level= 32;
+--echo # Test rpl_semi_sync_master_timeout
+SET GLOBAL rpl_semi_sync_master_timeout= 1000;
+SET GLOBAL rpl_semi_sync_master_timeout= 10000;
+SET GLOBAL rpl_semi_sync_master_timeout = 1000000;
+
+--echo # Test rpl_semi_sync_slave_kill_conn_timeout
+SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 10;
+SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 20;
+SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 60;
+SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 5;
+
+--echo ############################################
+--echo # Test rpl_semi_sync_master_wait_no_slave #
+--echo ############################################
+SET GLOBAL rpl_semi_sync_master_wait_no_slave = 1;
+connection slave;
+STOP SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_stop.inc
+
+connection con1;
+SET GLOBAL rpl_semi_sync_master_timeout = 1000;
+--send INSERT INTO t1 values (1);
+
+connection con1;
+reap;
+echo # Rpl_semi_sync_master_no_tx should be non-zero
+SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx';
+
+# test rpl_semi_sync_master_wait_no_slave = 0
+connection slave;
+START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
+
+connection con1;
+INSERT INTO t1 values (2);
+sync_slave_with_master;
+connection con1;
+show status like 'Rpl_semi_sync_master_clients';
+show status like 'Rpl_semi_sync_master_status';
+
+connection slave;
+STOP SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_stop.inc
+
+connection con1;
+SET GLOBAL rpl_semi_sync_master_wait_no_slave= 0;
+SET GLOBAL rpl_semi_sync_master_timeout= 1000000000;
+INSERT INTO t1 values (3);
+show status like 'Rpl_semi_sync_master_clients';
+show status like 'Rpl_semi_sync_master_status';
+
+
+connection slave;
+START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
+
+connection con1;
+--let $status_var= Rpl_semi_sync_master_status
+--let $status_var_value=ON
+--source include/wait_for_status_var.inc
+
+SET GLOBAL rpl_semi_sync_master_timeout= 10000000;
+SET GLOBAL rpl_semi_sync_master_wait_no_slave= 1;
+INSERT INTO t1 values (4);
+sync_slave_with_master;
+
+connection con1;
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_clients';
+
+--echo ##########################################
+--echo # Test rpl_semi_sync_slave_delay_master #
+--echo ##########################################
+
+connection slave;
+SET GLOBAL rpl_semi_sync_slave_delay_master= 1;
+START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
+
+connection con1;
+INSERT INTO t1 values (3);
+--source include/sync_slave_io_with_master.inc
+
+connection con1;
+show status like 'Rpl_semi_sync_master_clients';
+show status like 'Rpl_semi_sync_master_status';
+
+sync_slave_with_master;
+
+connection slave;
+select * from t1 order by a;
+connection con1;
+select * from t1 order by a;
+
+connection slave;
+SET GLOBAL rpl_semi_sync_slave_delay_master = 0;
+STOP SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_stop.inc
+START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
+
+--echo ##########################################################
+--echo # Test rpl_semi_sync_master_enabled and new ACK thread #
+--echo #########################################################
+connection con1;
+SET GLOBAL rpl_semi_sync_master_enabled = 0;
+show status like 'Rpl_semi_sync_master_clients';
+INSERT INTO t1 VALUES (1);
+SET GLOBAL rpl_semi_sync_master_enabled = 1;
+INSERT INTO t1 VALUES (2);
+show status like 'Rpl_semi_sync_master_clients';
+
+--echo # Test failure of select error .
+SET GLOBAL debug = 'd,rpl_semisync_simulate_select_error';
+# It can still receive ACK from semi-sync slave
+INSERT INTO t1 VALUES(3);
+sync_slave_with_master;
+
+connection con1;
+--echo # Test failure of pthread_create
+SET GLOBAL rpl_semi_sync_master_enabled = 0;
+SET GLOBAL debug = 'd,rpl_semisync_simulate_create_thread_failure';
+SET GLOBAL rpl_semi_sync_master_enabled= ON;
+
+--let $wait_condition= SELECT @@global.rpl_semi_sync_master_enabled = 0
+--source include/wait_condition.inc
+
+# Todo: implement the thread join failure simulation
+--echo # Test failure of pthread_join
+#SET GLOBAL DEBUG = 'd,rpl_semisync_simulate_thread_join_failure';
+#SET GLOBAL rpl_semi_sync_master_enabled= ON;
+#
+#--let $wait_condition= SELECT @@global.rpl_semi_sync_master_enabled = 0
+#--source include/wait_condition.inc
+SET GLOBAL rpl_semi_sync_master_enabled= OFF;
+
+--echo #
+--echo # Failure on registering semisync slave
+--echo #
+SET GLOBAL debug= 'd,rpl_semisync_simulate_add_slave_failure';
+SET GLOBAL rpl_semi_sync_master_enabled= ON;
+
+connection slave;
+STOP SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_stop.inc
+START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
+
+connection con1;
+#--echo # Should be Zero.
+# Todo: implement the add_slave_failure simulation. Meanwhile
+# the status will be 1.
+# show status like 'Rpl_semi_sync_master_clients';
+SET GLOBAL debug='';
+
+--let $status_var= Rpl_semi_sync_master_clients
+--let $status_var_value= 1
+--let $status_type= GLOBAL
+--source include/wait_for_status_var.inc
+
+connection slave;
+--disable_warnings
+START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
+--enable_warnings
+
+connection con1;
+sync_slave_with_master;
+
+show status like 'Rpl_semi_sync_master_clients';
+
+--echo ##################################################################
+--echo # Test fixing of BUG#70669 #
+--echo #SLAVE CAN'T CONTINUE REPLICATION AFTER MASTER'S CRASH RECOVERY #
+--echo #################################################################
+connection con1;
+SET GLOBAL sync_binlog = 1;
+CREATE TABLE t2 (c1 INT);
+sync_slave_with_master;
+
+connection con1;
+# Block the session before its events are synced to disk
+#SET DEBUG_SYNC = 'before_sync_binlog_file SIGNAL before_sync_done WAIT_FOR continue';
+send INSERT INTO t2 values (1);
+
+connection slave;
+--let $table= t2
+--let $count= 1
+--source include/wait_until_rows_count.inc
+
+connection con2;
+#SET DEBUG_SYNC= "now WAIT_FOR before_sync_done";
+#SET DEBUG_SYNC = "now SIGNAL continue";
+
+connection con1;
+reap;
+
+sync_slave_with_master;
+show tables like 't2';
+select * from t2;
+
+connection con1;
+#SET DEBUG_SYNC= "before_update_pos SIGNAL leader_ready WAIT_FOR follower_ready";
+send INSERT INTO t2 VALUES (2);
+
+connection con2;
+#SET DEBUG_SYNC= "now WAIT_FOR leader_ready";
+#SET DEBUG_SYNC= "after_sync_queue SIGNAL follower_ready";
+send INSERT INTO t2 VALUES (3);
+
+connection con1;
+reap;
+connection con2;
+reap;
+
+connection con1;
+#SET DEBUG_SYNC = 'before_sync_binlog_file SIGNAL before_sync_done WAIT_FOR continue';
+SET GLOBAL sync_binlog = 0;
+
+# Todo: fix this simulation and implement the intended sync protocol.
+# As a workaround the DROP sender explicitly okays
+# which naturally increments the binlog position.
+#send DROP TABLE t2;
+DROP TABLE t2;
+
+connection con2;
+#SET DEBUG_SYNC= "now WAIT_FOR before_sync_done";
+
+sync_slave_with_master;
+
+# t2 should be dropped
+show tables like 't2';
+
+connection con2;
+#SET DEBUG_SYNC = "now SIGNAL continue";
+
+# This block is commented out on purpose. See the todo/workaround above.
+#connection con1;
+#reap;
+
+
+--echo #cleanup
+connection master;
+SET DEBUG_SYNC= 'reset';
+disconnect con1;
+disconnect con2;
+disconnect con3;
+SET GLOBAL rpl_semi_sync_master_timeout= 10000;
+SET GLOBAL rpl_semi_sync_master_enabled = 0;
+DROP TABLE t1;
+connection slave;
+SET GLOBAL rpl_semi_sync_slave_enabled = 0;
+stop slave;start slave;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_update.test b/mysql-test/suite/rpl/t/rpl_update.test
new file mode 100644
index 00000000000..b38078770a5
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_update.test
@@ -0,0 +1,15 @@
+source include/master-slave.inc;
+
+#
+# MDEV-13417 UPDATE produces wrong values if an updated column is later used as an update source
+#
+set sql_mode=simultaneous_assignment;
+create table t1 (a int, b int);
+insert into t1 values(1, 2);
+update t1 set a=b, b=a;
+select * from t1;
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+source include/rpl_end.inc;
diff --git a/mysql-test/suite/rpl/t/semisync_future-7591.test b/mysql-test/suite/rpl/t/semisync_future-7591.test
index daf3d2f8571..866041d2579 100644
--- a/mysql-test/suite/rpl/t/semisync_future-7591.test
+++ b/mysql-test/suite/rpl/t/semisync_future-7591.test
@@ -1,4 +1,3 @@
---source include/have_semisync.inc
--source include/master-slave.inc
call mtr.add_suppression("Timeout waiting for reply of binlog*");
diff --git a/mysql-test/suite/rpl/t/semisync_memleak_4066.test b/mysql-test/suite/rpl/t/semisync_memleak_4066.test
index f888f764b43..e88e2335696 100644
--- a/mysql-test/suite/rpl/t/semisync_memleak_4066.test
+++ b/mysql-test/suite/rpl/t/semisync_memleak_4066.test
@@ -1,7 +1,6 @@
#
# MDEV-4066 semisync_master + temporary tables causes memory leaks
#
-source include/have_semisync.inc;
source include/have_binlog_format_row.inc;
source include/master-slave.inc;
diff --git a/mysql-test/suite/sql_sequence/alter.result b/mysql-test/suite/sql_sequence/alter.result
index 0400843c98a..3cf085bc948 100644
--- a/mysql-test/suite/sql_sequence/alter.result
+++ b/mysql-test/suite/sql_sequence/alter.result
@@ -212,7 +212,7 @@ ERROR 42S02: 'test.t1' is not a SEQUENCE
drop table t1;
alter sequence if exists t1 minvalue=100;
Warnings:
-Note 4089 Unknown SEQUENCE: 'test.t1'
+Note 4091 Unknown SEQUENCE: 'test.t1'
alter sequence t1 minvalue=100;
ERROR 42S02: Table 'test.t1' doesn't exist
create sequence t1;
diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result
index 0a44dfe8931..6af43a3faa4 100644
--- a/mysql-test/suite/sql_sequence/create.result
+++ b/mysql-test/suite/sql_sequence/create.result
@@ -165,7 +165,7 @@ drop sequence t1;
ERROR 42S02: 'test.t1' is not a SEQUENCE
drop sequence if exists t1;
Warnings:
-Note 4089 Unknown SEQUENCE: 'test.t1'
+Note 4091 Unknown SEQUENCE: 'test.t1'
create sequence t1 start with 10 maxvalue=9;
ERROR HY000: Sequence 'test.t1' values are conflicting
create sequence t1 minvalue= 100 maxvalue=10;
@@ -377,7 +377,7 @@ key key1 (next_not_cached_value)
ERROR HY000: Sequence 'test.t1' table structure is invalid (Sequence tables cannot have any keys)
drop sequence if exists t1;
Warnings:
-Note 4089 Unknown SEQUENCE: 'test.t1'
+Note 4091 Unknown SEQUENCE: 'test.t1'
create sequence t1;
create sequence t2;
create table t3 (a int) engine=myisam;
@@ -387,8 +387,8 @@ CREATE SEQUENCE s1;
drop sequence s1;
drop sequence if exists t1,t2,t3,t4;
Warnings:
-Note 4089 Unknown SEQUENCE: 'test.t3'
-Note 4089 Unknown SEQUENCE: 'test.t4'
+Note 4091 Unknown SEQUENCE: 'test.t3'
+Note 4091 Unknown SEQUENCE: 'test.t4'
drop table if exists t1,t2,t3;
Warnings:
Note 1051 Unknown table 'test.t1'
@@ -414,9 +414,9 @@ CREATE TABLE t2 (a int);
CREATE SEQUENCE s1;
drop sequence if exists t1,t2,s1,s2;
Warnings:
-Note 4089 Unknown SEQUENCE: 'test.t1'
-Note 4089 Unknown SEQUENCE: 'test.t2'
-Note 4089 Unknown SEQUENCE: 'test.s2'
+Note 4091 Unknown SEQUENCE: 'test.t1'
+Note 4091 Unknown SEQUENCE: 'test.t2'
+Note 4091 Unknown SEQUENCE: 'test.s2'
drop table if exists t1,t2;
CREATE TEMPORARY SEQUENCE s1;
DROP SEQUENCE s1;
@@ -482,6 +482,7 @@ select previous value for t1;
previous value for t1
1
CREATE TEMPORARY SEQUENCE t1 start with 100 minvalue 100 maxvalue 200 increment by 1 cache 10 engine=innodb;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
select previous value for t1;
previous value for t1
NULL
@@ -633,3 +634,10 @@ create temporary table s (i int);
drop temporary sequence s;
ERROR 42S02: Unknown SEQUENCE: 'test.s'
drop table s;
+#
+# MDEV-15115 Assertion failure in CREATE SEQUENCE...ROW_FORMAT=REDUNDANT
+#
+CREATE SEQUENCE seq1 ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+DROP SEQUENCE seq1;
+CREATE TEMPORARY SEQUENCE seq1 ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+DROP TEMPORARY SEQUENCE seq1;
diff --git a/mysql-test/suite/sql_sequence/create.test b/mysql-test/suite/sql_sequence/create.test
index 6696e78db92..65c0641eab9 100644
--- a/mysql-test/suite/sql_sequence/create.test
+++ b/mysql-test/suite/sql_sequence/create.test
@@ -362,6 +362,7 @@ CREATE SEQUENCE t1 start with 1 minvalue 1 maxvalue 10 increment by 1 cache 10 e
select next value for t1;
select previous value for t1;
CREATE TEMPORARY SEQUENCE t1 start with 100 minvalue 100 maxvalue 200 increment by 1 cache 10 engine=innodb;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
select previous value for t1;
select next value for t1;
select previous value for t1;
@@ -449,3 +450,11 @@ create temporary table s (i int);
--error ER_UNKNOWN_SEQUENCES
drop temporary sequence s;
drop table s;
+
+--echo #
+--echo # MDEV-15115 Assertion failure in CREATE SEQUENCE...ROW_FORMAT=REDUNDANT
+--echo #
+CREATE SEQUENCE seq1 ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+DROP SEQUENCE seq1;
+CREATE TEMPORARY SEQUENCE seq1 ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+DROP TEMPORARY SEQUENCE seq1;
diff --git a/mysql-test/suite/sql_sequence/default.result b/mysql-test/suite/sql_sequence/default.result
new file mode 100644
index 00000000000..37d536d9020
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/default.result
@@ -0,0 +1,187 @@
+drop table if exists t1,s1,s2;
+Warnings:
+Note 1051 Unknown table 'test.t1'
+Note 1051 Unknown table 'test.s1'
+Note 1051 Unknown table 'test.s2'
+drop view if exists v1;
+Warnings:
+Note 4092 Unknown VIEW: 'test.v1'
+#
+# Test DEFAULT
+#
+CREATE SEQUENCE s1 nocache engine=myisam;
+CREATE table t1 (a int default next value for s1, b int);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT nextval(`test`.`s1`),
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 SET b=1;
+insert into t1 SET b=2;
+insert into t1 (b) values (3),(4);
+select * from t1;
+a b
+1 1
+2 2
+3 3
+4 4
+update t1 set b=5 where a=1;
+delete from t1 where b=1;
+select * from t1;
+a b
+1 5
+2 2
+3 3
+4 4
+#
+# Executing DEFAULT function
+#
+INSERT into t1 values(default(a),10);
+INSERT into t1 values(default(a),default(a));
+update t1 set a=default(a), b=12 where b=2;
+select * from t1;
+a b
+1 5
+8 12
+3 3
+4 4
+5 10
+6 7
+select default(a), a, b from t1;
+default(a) a b
+9 1 5
+10 8 12
+11 3 3
+12 4 4
+13 5 10
+14 6 7
+select * from s1;
+next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
+15 1 9223372036854775806 1 1 0 0 0
+select * from t1 where default(a) > 0;
+a b
+1 5
+8 12
+3 3
+4 4
+5 10
+6 7
+select * from s1;
+next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
+16 1 9223372036854775806 1 1 0 0 0
+#
+# View
+#
+create view v1 as select * from t1;
+insert into v1 set b=20;
+select * from v1;
+a b
+1 5
+8 12
+3 3
+4 4
+5 10
+6 7
+16 20
+drop view v1;
+#
+# Alter table
+#
+CREATE SEQUENCE s2 nocache engine=myisam;
+alter table t1 add column c int default next value for s2, add column d int default previous value for s2;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT nextval(`test`.`s1`),
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT nextval(`test`.`s2`),
+ `d` int(11) DEFAULT lastval(`test`.`s2`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t1;
+a b c d
+1 5 1 1
+8 12 2 2
+3 3 3 3
+4 4 4 4
+5 10 5 5
+6 7 6 6
+16 20 7 7
+drop sequence s2;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT nextval(`test`.`s1`),
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT nextval(`test`.`s2`),
+ `d` int(11) DEFAULT lastval(`test`.`s2`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+drop sequence s1;
+#
+# LOCK TABLES
+#
+CREATE SEQUENCE s1 nocache engine=myisam;
+CREATE table t1 (a int default next value for s1, b int);
+insert into t1 (b) values (3),(4);
+LOCK TABLE t1 WRITE;
+insert into t1 (b) values (5),(6);
+ERROR HY000: Table 's1' was not locked with LOCK TABLES
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE, s1 WRITE;
+insert into t1 (b) values (5),(6);
+select default(a) from t1;
+default(a)
+5
+6
+7
+8
+UNLOCK TABLES;
+LOCK TABLE t1 READ;
+insert into t1 (b) values (5),(6);
+ERROR HY000: Table 's1' was not locked with LOCK TABLES
+select default(a) from t1;
+ERROR HY000: Table 's1' was not locked with LOCK TABLES
+UNLOCK TABLES;
+LOCK TABLE t1 READ, s1 read;
+insert into t1 (b) values (5),(6);
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+select default(a) from t1;
+ERROR HY000: Table 's1' was locked with a READ lock and can't be updated
+UNLOCK TABLES;
+drop table t1;
+drop sequence s1;
+#
+# Testing prepared statements
+#
+CREATE or replace SEQUENCE s1 nocache engine=myisam;
+CREATE or replace table t1 (a int default next value for s1, b int);
+PREPARE stmt FROM "insert into t1 (b) values(?)";
+execute stmt using 1;
+execute stmt using 2;
+execute stmt using 3;
+select * from t1;
+a b
+1 1
+2 2
+3 3
+drop table t1,s1;
+deallocate prepare stmt;
+#
+# Wrong usage of default
+#
+CREATE table t1 (a int default next value for s1, b int);
+ERROR 42S02: Table 'test.s1' doesn't exist
+CREATE SEQUENCE s1 nocache engine=myisam;
+CREATE table t1 (a int default next value for s1, b int);
+DROP SEQUENCE s1;
+insert into t1 (b) values (5),(6);
+ERROR 42S02: Table 'test.s1' doesn't exist
+ALTER TABLE t1 add column c int;
+ERROR 42S02: Table 'test.s1' doesn't exist
+CREATE SEQUENCE s1 nocache engine=myisam;
+ALTER TABLE t1 add column c int;
+ALTER TABLE t1 add column d int default next value for s_not_exits;
+ERROR 42S02: Table 'test.s_not_exits' doesn't exist
+drop table t1;
+drop sequence s1;
diff --git a/mysql-test/suite/sql_sequence/default.test b/mysql-test/suite/sql_sequence/default.test
new file mode 100644
index 00000000000..017165c1a80
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/default.test
@@ -0,0 +1,125 @@
+#
+# Testing sequence in DEFAULT clause
+#
+--source include/have_sequence.inc
+
+drop table if exists t1,s1,s2;
+drop view if exists v1;
+
+--echo #
+--echo # Test DEFAULT
+--echo #
+
+CREATE SEQUENCE s1 nocache engine=myisam;
+CREATE table t1 (a int default next value for s1, b int);
+show create table t1;
+insert into t1 SET b=1;
+insert into t1 SET b=2;
+insert into t1 (b) values (3),(4);
+select * from t1;
+update t1 set b=5 where a=1;
+delete from t1 where b=1;
+select * from t1;
+
+--echo #
+--echo # Executing DEFAULT function
+--echo #
+
+INSERT into t1 values(default(a),10);
+INSERT into t1 values(default(a),default(a));
+update t1 set a=default(a), b=12 where b=2;
+select * from t1;
+select default(a), a, b from t1;
+select * from s1;
+select * from t1 where default(a) > 0;
+select * from s1;
+
+--echo #
+--echo # View
+--echo #
+
+create view v1 as select * from t1;
+insert into v1 set b=20;
+select * from v1;
+drop view v1;
+
+--echo #
+--echo # Alter table
+--echo #
+
+CREATE SEQUENCE s2 nocache engine=myisam;
+alter table t1 add column c int default next value for s2, add column d int default previous value for s2;
+show create table t1;
+select * from t1;
+drop sequence s2;
+show create table t1;
+drop table t1;
+drop sequence s1;
+
+--echo #
+--echo # LOCK TABLES
+--echo #
+
+CREATE SEQUENCE s1 nocache engine=myisam;
+CREATE table t1 (a int default next value for s1, b int);
+insert into t1 (b) values (3),(4);
+LOCK TABLE t1 WRITE;
+--error ER_TABLE_NOT_LOCKED
+insert into t1 (b) values (5),(6);
+UNLOCK TABLES;
+
+LOCK TABLE t1 WRITE, s1 WRITE;
+insert into t1 (b) values (5),(6);
+select default(a) from t1;
+UNLOCK TABLES;
+
+LOCK TABLE t1 READ;
+--error ER_TABLE_NOT_LOCKED
+insert into t1 (b) values (5),(6);
+--error ER_TABLE_NOT_LOCKED
+select default(a) from t1;
+UNLOCK TABLES;
+
+LOCK TABLE t1 READ, s1 read;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+insert into t1 (b) values (5),(6);
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+select default(a) from t1;
+UNLOCK TABLES;
+
+drop table t1;
+drop sequence s1;
+
+--echo #
+--echo # Testing prepared statements
+--echo #
+
+CREATE or replace SEQUENCE s1 nocache engine=myisam;
+CREATE or replace table t1 (a int default next value for s1, b int);
+PREPARE stmt FROM "insert into t1 (b) values(?)";
+execute stmt using 1;
+execute stmt using 2;
+execute stmt using 3;
+select * from t1;
+drop table t1,s1;
+deallocate prepare stmt;
+
+--echo #
+--echo # Wrong usage of default
+--echo #
+
+--error ER_NO_SUCH_TABLE
+CREATE table t1 (a int default next value for s1, b int);
+CREATE SEQUENCE s1 nocache engine=myisam;
+CREATE table t1 (a int default next value for s1, b int);
+DROP SEQUENCE s1;
+--error ER_NO_SUCH_TABLE
+insert into t1 (b) values (5),(6);
+--error ER_NO_SUCH_TABLE
+ALTER TABLE t1 add column c int;
+CREATE SEQUENCE s1 nocache engine=myisam;
+ALTER TABLE t1 add column c int;
+--error ER_NO_SUCH_TABLE
+ALTER TABLE t1 add column d int default next value for s_not_exits;
+drop table t1;
+drop sequence s1;
diff --git a/mysql-test/suite/sql_sequence/grant.result b/mysql-test/suite/sql_sequence/grant.result
new file mode 100644
index 00000000000..7085d548588
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/grant.result
@@ -0,0 +1,60 @@
+SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'NO_AUTO_CREATE_USER', '');
+create database mysqltest_1;
+use mysqltest_1;
+grant all on mysqltest_1.* to 'normal'@'%';
+grant select on mysqltest_1.* to 'read_only'@'%';
+grant select,insert on mysqltest_1.* to 'read_write'@'%';
+grant select,insert,alter on mysqltest_1.* to 'alter'@'%';
+grant alter on mysqltest_1.* to only_alter@'%';
+connect normal,localhost,normal,,mysqltest_1;
+connect read_only,localhost,read_only,,mysqltest_1;
+connect read_write,localhost,read_write,,mysqltest_1;
+connect alter,localhost,alter,,mysqltest_1;
+connect only_alter, localhost, only_alter,,mysqltest_1;
+connection normal;
+create sequence s1;
+select next value for s1;
+next value for s1
+1
+alter sequence s1 restart= 11;
+select * from s1;
+next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
+11 1 9223372036854775806 1 1 1000 0 0
+connection read_only;
+select next value for s1;
+ERROR 42000: INSERT command denied to user 'read_only'@'localhost' for table 's1'
+alter sequence s1 restart= 11;
+ERROR 42000: ALTER command denied to user 'read_only'@'localhost' for table 's1'
+select * from s1;
+next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
+11 1 9223372036854775806 1 1 1000 0 0
+connection read_write;
+select next value for s1;
+next value for s1
+11
+alter sequence s1 restart= 11;
+ERROR 42000: ALTER command denied to user 'read_write'@'localhost' for table 's1'
+select * from s1;
+next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
+1011 1 9223372036854775806 1 1 1000 0 0
+connection alter;
+select next value for s1;
+next value for s1
+12
+alter sequence s1 restart= 11;
+select * from s1;
+next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
+11 1 9223372036854775806 1 1 1000 0 0
+connection only_alter;
+select next value for s1;
+ERROR 42000: INSERT command denied to user 'only_alter'@'localhost' for table 's1'
+alter sequence s1 restart= 11;
+select * from s1;
+ERROR 42000: SELECT command denied to user 'only_alter'@'localhost' for table 's1'
+connection default;
+drop database mysqltest_1;
+drop user 'normal'@'%';
+drop user 'read_only'@'%';
+drop user 'read_write'@'%';
+drop user 'alter'@'%';
+drop user 'only_alter'@'%';
diff --git a/mysql-test/suite/sql_sequence/grant.test b/mysql-test/suite/sql_sequence/grant.test
new file mode 100644
index 00000000000..3a911d79671
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/grant.test
@@ -0,0 +1,67 @@
+#
+# Test some grants with sequences
+# Note that replication.test also does some grant testing
+#
+
+# Grant tests not performed with embedded server
+-- source include/not_embedded.inc
+
+
+SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'NO_AUTO_CREATE_USER', '');
+create database mysqltest_1;
+use mysqltest_1;
+grant all on mysqltest_1.* to 'normal'@'%';
+grant select on mysqltest_1.* to 'read_only'@'%';
+grant select,insert on mysqltest_1.* to 'read_write'@'%';
+grant select,insert,alter on mysqltest_1.* to 'alter'@'%';
+grant alter on mysqltest_1.* to only_alter@'%';
+
+connect(normal,localhost,normal,,mysqltest_1);
+connect(read_only,localhost,read_only,,mysqltest_1);
+connect(read_write,localhost,read_write,,mysqltest_1);
+connect(alter,localhost,alter,,mysqltest_1);
+connect(only_alter, localhost, only_alter,,mysqltest_1);
+
+connection normal;
+create sequence s1;
+select next value for s1;
+alter sequence s1 restart= 11;
+select * from s1;
+
+connection read_only;
+--error ER_TABLEACCESS_DENIED_ERROR
+select next value for s1;
+--error ER_TABLEACCESS_DENIED_ERROR
+alter sequence s1 restart= 11;
+select * from s1;
+
+connection read_write;
+select next value for s1;
+--error ER_TABLEACCESS_DENIED_ERROR
+alter sequence s1 restart= 11;
+select * from s1;
+
+connection alter;
+select next value for s1;
+alter sequence s1 restart= 11;
+select * from s1;
+
+connection only_alter;
+--error ER_TABLEACCESS_DENIED_ERROR
+select next value for s1;
+alter sequence s1 restart= 11;
+--error ER_TABLEACCESS_DENIED_ERROR
+select * from s1;
+
+#
+# Cleanup
+#
+
+connection default;
+drop database mysqltest_1;
+drop user 'normal'@'%';
+drop user 'read_only'@'%';
+drop user 'read_write'@'%';
+drop user 'alter'@'%';
+drop user 'only_alter'@'%';
+
diff --git a/mysql-test/suite/sql_sequence/mysqldump.result b/mysql-test/suite/sql_sequence/mysqldump.result
index 0067709db54..5a3711ebda3 100644
--- a/mysql-test/suite/sql_sequence/mysqldump.result
+++ b/mysql-test/suite/sql_sequence/mysqldump.result
@@ -39,3 +39,11 @@ CREATE TABLE `x1` (
/*!40101 SET character_set_client = @saved_cs_client */;
INSERT INTO `x1` VALUES (1,1,9223372036854775806,1,1,1000,0,0);
DROP TABLE a1,t1,x1;
+set default_storage_engine=InnoDB;
+create sequence t1;
+LOCK TABLES t1 READ;
+SELECT * FROM t1;
+next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
+1 1 9223372036854775806 1 1 1000 0 0
+unlock tables;
+drop table t1;
diff --git a/mysql-test/suite/sql_sequence/mysqldump.test b/mysql-test/suite/sql_sequence/mysqldump.test
index 8d5c2d0869d..308f06d5e8d 100644
--- a/mysql-test/suite/sql_sequence/mysqldump.test
+++ b/mysql-test/suite/sql_sequence/mysqldump.test
@@ -13,3 +13,14 @@ insert into t1 values (1),(2);
CREATE SEQUENCE x1 engine=innodb;
--exec $MYSQL_DUMP --compact test
DROP TABLE a1,t1,x1;
+
+#
+# MDEV-12887 UT_LIST_GET_LEN(trx->lock.trx_locks) == 0 when mysqldump sequence
+#
+
+set default_storage_engine=InnoDB;
+create sequence t1;
+LOCK TABLES t1 READ;
+SELECT * FROM t1;
+unlock tables;
+drop table t1;
diff --git a/mysql-test/suite/sql_sequence/other.result b/mysql-test/suite/sql_sequence/other.result
index 87c36394975..e3ec94cf2c5 100644
--- a/mysql-test/suite/sql_sequence/other.result
+++ b/mysql-test/suite/sql_sequence/other.result
@@ -162,3 +162,25 @@ select next value for s1;
ERROR HY000: Can't execute the query because you have a conflicting read lock
unlock tables;
drop sequence s1;
+#
+# MDEV-14761
+# Assertion `!mysql_parse_status || thd->is_error() ||
+# thd->get_internal_handler()' failed in parse_sql
+#
+CREATE SEQUENCE s1;
+ALTER SEQUENCE s1 MAXVALUE 100 NO MAXVALUE;
+ERROR HY000: Option 'MAXVALUE' used twice in statement
+DROP SEQUENCE s1;
+#
+# Don't allow SEQUENCE to be used with CHECK or virtual fields
+#
+CREATE SEQUENCE s1 nocache engine=myisam;
+CREATE table t1 (a int check (next value for s1 > 0));
+ERROR HY000: Function or expression 'nextval()' cannot be used in the CHECK clause of `a`
+CREATE table t1 (a int check (previous value for s1 > 0));
+ERROR HY000: Function or expression 'lastval()' cannot be used in the CHECK clause of `a`
+CREATE table t1 (a int check (setval(s1,10)));
+ERROR HY000: Function or expression 'setval()' cannot be used in the CHECK clause of `a`
+CREATE TABLE t1 (a int, b int as (next value for s1 > 0));
+ERROR HY000: Function or expression 'nextval()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+drop sequence s1;
diff --git a/mysql-test/suite/sql_sequence/other.test b/mysql-test/suite/sql_sequence/other.test
index edd4cc7acc7..ff0db9e158d 100644
--- a/mysql-test/suite/sql_sequence/other.test
+++ b/mysql-test/suite/sql_sequence/other.test
@@ -131,3 +131,29 @@ create sequence s2;
select next value for s1;
unlock tables;
drop sequence s1;
+
+--echo #
+--echo # MDEV-14761
+--echo # Assertion `!mysql_parse_status || thd->is_error() ||
+--echo # thd->get_internal_handler()' failed in parse_sql
+--echo #
+
+CREATE SEQUENCE s1;
+--error ER_DUP_ARGUMENT
+ALTER SEQUENCE s1 MAXVALUE 100 NO MAXVALUE;
+DROP SEQUENCE s1;
+
+--echo #
+--echo # Don't allow SEQUENCE to be used with CHECK or virtual fields
+--echo #
+
+CREATE SEQUENCE s1 nocache engine=myisam;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE table t1 (a int check (next value for s1 > 0));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE table t1 (a int check (previous value for s1 > 0));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE table t1 (a int check (setval(s1,10)));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a int, b int as (next value for s1 > 0));
+drop sequence s1;
diff --git a/mysql-test/suite/sql_sequence/rename.result b/mysql-test/suite/sql_sequence/rename.result
new file mode 100644
index 00000000000..26f529b57ef
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/rename.result
@@ -0,0 +1,6 @@
+CREATE SEQUENCE seq1;
+RENAME TABLE seq1 TO seq2, seq3 TO seq4;
+ERROR 42S02: Table 'test.seq3' doesn't exist
+LOCK TABLE seq1 READ;
+UNLOCK TABLES;
+drop table seq1;
diff --git a/mysql-test/suite/sql_sequence/rename.test b/mysql-test/suite/sql_sequence/rename.test
new file mode 100644
index 00000000000..232a1bda5ea
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/rename.test
@@ -0,0 +1,6 @@
+CREATE SEQUENCE seq1;
+--error ER_NO_SUCH_TABLE
+RENAME TABLE seq1 TO seq2, seq3 TO seq4;
+LOCK TABLE seq1 READ;
+UNLOCK TABLES;
+drop table seq1;
diff --git a/mysql-test/suite/sql_sequence/replication.result b/mysql-test/suite/sql_sequence/replication.result
index 0397e801a16..d5e5dcc75eb 100644
--- a/mysql-test/suite/sql_sequence/replication.result
+++ b/mysql-test/suite/sql_sequence/replication.result
@@ -1056,6 +1056,35 @@ select next value for s1, cycle_count from s1;
next value for s1 cycle_count
9223372036854775805 3
drop sequence s1;
+###########################################
+test default()
+###########################################
+connection master;
+CREATE SEQUENCE s1 nocache engine=myisam;
+CREATE table t1 (a int default next value for s1, b int);
+insert into t1 (b) values (1),(2);
+select default(a) from t1;
+default(a)
+3
+4
+select * from t1;
+a b
+1 1
+2 2
+select * from s1;
+next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
+5 1 9223372036854775806 1 1 0 0 0
+connection slave;
+connection s_normal_3;
+select * from t1;
+a b
+1 1
+2 2
+select * from s1;
+next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
+5 1 9223372036854775806 1 1 0 0 0
+connection master;
+drop table t1,s1;
connection master;
drop database s_db;
drop user normal_1@'%';
diff --git a/mysql-test/suite/sql_sequence/replication.test b/mysql-test/suite/sql_sequence/replication.test
index 50ca7dad378..e26fde8a329 100644
--- a/mysql-test/suite/sql_sequence/replication.test
+++ b/mysql-test/suite/sql_sequence/replication.test
@@ -851,6 +851,28 @@ select next value for s1, cycle_count from s1;
select next value for s1, cycle_count from s1;
drop sequence s1;
+--echo ###########################################
+--echo test default()
+--echo ###########################################
+connection master;
+
+CREATE SEQUENCE s1 nocache engine=myisam;
+CREATE table t1 (a int default next value for s1, b int);
+insert into t1 (b) values (1),(2);
+select default(a) from t1;
+select * from t1;
+select * from s1;
+--sync_slave_with_master
+connection s_normal_3;
+select * from t1;
+select * from s1;
+connection master;
+drop table t1,s1;
+
+#
+# Cleanup
+#
+
connection master;
drop database s_db;
drop user normal_1@'%';
diff --git a/mysql-test/suite/storage_engine/autoincrement.result b/mysql-test/suite/storage_engine/autoincrement.result
index 44cb8650441..541486e44de 100644
--- a/mysql-test/suite/storage_engine/autoincrement.result
+++ b/mysql-test/suite/storage_engine/autoincrement.result
@@ -51,15 +51,15 @@ LAST_INSERT_ID()
5
SET sql_mode = '<INITIAL_SQL_MODE>';
SHOW TABLE STATUS FROM test LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 <STORAGE_ENGINE> # # # # # # # # 6 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 <STORAGE_ENGINE> # # # # # # # # 6 # # # # # # # # N
INSERT INTO t1 (a,b) VALUES (6,'g'),(7,'h');
SELECT LAST_INSERT_ID();
LAST_INSERT_ID()
5
SHOW TABLE STATUS FROM test LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 # # # # # # # # # 8 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 # # # # # # # # # 8 # # # # # # # # N
INSERT INTO t1 (a,b) VALUES (NULL,'i'),(9,'j');
SELECT a,b FROM t1 ORDER BY a;
a b
@@ -77,12 +77,12 @@ SELECT LAST_INSERT_ID();
LAST_INSERT_ID()
8
SHOW TABLE STATUS FROM test LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 # # # # # # # # # 10 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 # # # # # # # # # 10 # # # # # # # # N
INSERT INTO t1 (a,b) VALUES (20,'k');
SHOW TABLE STATUS FROM test LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 # # # # # # # # # 21 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 # # # # # # # # # 21 # # # # # # # # N
INSERT INTO t1 (a,b) VALUES (NULL,'l');
SELECT a,b FROM t1 ORDER BY a;
a b
@@ -102,8 +102,8 @@ SELECT LAST_INSERT_ID();
LAST_INSERT_ID()
21
SHOW TABLE STATUS FROM test LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 # # # # # # # # # 22 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 # # # # # # # # # 22 # # # # # # # # N
INSERT INTO t1 (a,b) VALUES (-5,'m');
SELECT a,b FROM t1 ORDER BY a;
a b
diff --git a/mysql-test/suite/storage_engine/autoincrement.test b/mysql-test/suite/storage_engine/autoincrement.test
index ddb0ab1b464..1ca0b650039 100644
--- a/mysql-test/suite/storage_engine/autoincrement.test
+++ b/mysql-test/suite/storage_engine/autoincrement.test
@@ -50,7 +50,7 @@ if (!$mysql_errname)
# SHOW TABLE STATUS shows the auto-increment value in column 11,
# that's all we need here and further
--source mask_engine.inc
- --replace_column 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+ --replace_column 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # 19 #
SHOW TABLE STATUS FROM test LIKE 't1';
# Mix of automatic and explicit values
@@ -58,7 +58,7 @@ if (!$mysql_errname)
INSERT INTO t1 (a,b) VALUES (6,'g'),(7,'h');
SELECT LAST_INSERT_ID();
- --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+ --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # 19 #
SHOW TABLE STATUS FROM test LIKE 't1';
@@ -66,21 +66,21 @@ if (!$mysql_errname)
SELECT a,b FROM t1 ORDER BY a;
SELECT LAST_INSERT_ID();
- --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+ --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # 19 #
SHOW TABLE STATUS FROM test LIKE 't1';
# Creating a gap in the sequence
INSERT INTO t1 (a,b) VALUES (20,'k');
- --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+ --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # 19 #
SHOW TABLE STATUS FROM test LIKE 't1';
INSERT INTO t1 (a,b) VALUES (NULL,'l');
SELECT a,b FROM t1 ORDER BY a;
SELECT LAST_INSERT_ID();
- --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+ --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # 19 #
SHOW TABLE STATUS FROM test LIKE 't1';
# Negative values: we will try to insert one just to check that it does not cause a crash,
diff --git a/mysql-test/suite/storage_engine/misc.result b/mysql-test/suite/storage_engine/misc.result
index 3643611aa49..43d6a131b3a 100644
--- a/mysql-test/suite/storage_engine/misc.result
+++ b/mysql-test/suite/storage_engine/misc.result
@@ -94,5 +94,7 @@ time_zone_transition Time_zone_id NULL NULL
time_zone_transition Transition_time NULL NULL
time_zone_transition_type Time_zone_id NULL NULL
time_zone_transition_type Transition_type_id NULL NULL
+transaction_registry commit_id NULL NULL
+transaction_registry transaction_id NULL NULL
user Host NULL NULL
user User NULL NULL
diff --git a/mysql-test/suite/storage_engine/show_table_status.result b/mysql-test/suite/storage_engine/show_table_status.result
index 98de48f816b..b020bbe6a00 100644
--- a/mysql-test/suite/storage_engine/show_table_status.result
+++ b/mysql-test/suite/storage_engine/show_table_status.result
@@ -23,6 +23,8 @@ Collation latin1_swedish_ci
Checksum NULL
Create_options
Comment
+Max_index_length ###
+Temporary N
Name t2
Engine <STORAGE_ENGINE>
Version 10
@@ -41,6 +43,8 @@ Collation latin1_swedish_ci
Checksum NULL
Create_options
Comment
+Max_index_length ###
+Temporary N
Name t3
Engine <STORAGE_ENGINE>
Version 10
@@ -59,4 +63,6 @@ Collation utf8_general_ci
Checksum NULL
Create_options
Comment
+Max_index_length ###
+Temporary N
DROP TABLE t1, t2, t3;
diff --git a/mysql-test/suite/storage_engine/show_table_status.test b/mysql-test/suite/storage_engine/show_table_status.test
index 469d7e33a20..2fd5c6a706a 100644
--- a/mysql-test/suite/storage_engine/show_table_status.test
+++ b/mysql-test/suite/storage_engine/show_table_status.test
@@ -22,7 +22,7 @@ INSERT INTO t2 (a,b) VALUES (1,'bar');
--let $table_options = CHARACTER SET utf8
--source create_table.inc
---replace_column 2 <STORAGE_ENGINE> 4 ### 6 ### 7 ### 8 ### 9 ### 10 ### 12 ### 13 ###
+--replace_column 2 <STORAGE_ENGINE> 4 ### 6 ### 7 ### 8 ### 9 ### 10 ### 12 ### 13 ### 19 ###
--query_vertical SHOW TABLE STATUS WHERE name IN ( 't1', 't2', 't3' )
DROP TABLE t1, t2, t3;
diff --git a/mysql-test/suite/storage_engine/truncate_table.result b/mysql-test/suite/storage_engine/truncate_table.result
index d8dc5046442..eac58272e48 100644
--- a/mysql-test/suite/storage_engine/truncate_table.result
+++ b/mysql-test/suite/storage_engine/truncate_table.result
@@ -8,20 +8,20 @@ a b
DROP TABLE t1;
CREATE TABLE t1 (a <INT_COLUMN> KEY AUTO_INCREMENT, c <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 # # # # # # # # # 1 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 # # # # # # # # # 1 # # # # # # # # N
INSERT INTO t1 (c) VALUES ('a'),('b'),('c');
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 # # # # # # # # # 4 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 # # # # # # # # # 4 # # # # # # # # N
TRUNCATE TABLE t1;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 # # # # # # # # # 1 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 # # # # # # # # # 1 # # # # # # # # N
INSERT INTO t1 (c) VALUES ('d');
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 # # # # # # # # # 2 # # # # # # #
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 # # # # # # # # # 2 # # # # # # # # N
SELECT a,c FROM t1;
a c
1 d
diff --git a/mysql-test/suite/storage_engine/truncate_table.test b/mysql-test/suite/storage_engine/truncate_table.test
index a9277b39619..6a6301f4be0 100644
--- a/mysql-test/suite/storage_engine/truncate_table.test
+++ b/mysql-test/suite/storage_engine/truncate_table.test
@@ -36,19 +36,19 @@ if ($mysql_errname)
}
if (!$mysql_errname)
{
- --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+ --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # 19 #
SHOW TABLE STATUS LIKE 't1';
INSERT INTO t1 (c) VALUES ('a'),('b'),('c');
- --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+ --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # 19 #
SHOW TABLE STATUS LIKE 't1';
TRUNCATE TABLE t1;
- --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+ --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # 19 #
SHOW TABLE STATUS LIKE 't1';
INSERT INTO t1 (c) VALUES ('d');
- --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+ --replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # 19 #
SHOW TABLE STATUS LIKE 't1';
SELECT a,c FROM t1;
diff --git a/mysql-test/suite/sys_vars/inc/sysvars_server.inc b/mysql-test/suite/sys_vars/inc/sysvars_server.inc
index b5c800e858a..d14e905378c 100644
--- a/mysql-test/suite/sys_vars/inc/sysvars_server.inc
+++ b/mysql-test/suite/sys_vars/inc/sysvars_server.inc
@@ -19,6 +19,7 @@ select * from information_schema.system_variables
variable_name not like 'debug%' and
variable_name not like 'wsrep%' and
variable_name not in (
+ 'in_predicate_conversion_threshold',
'have_openssl',
'have_symlink',
'hostname',
@@ -26,6 +27,7 @@ select * from information_schema.system_variables
'lower_case_file_system',
'lower_case_table_names',
'open_files_limit',
+ 'plugin_maturity',
'rand_seed1',
'rand_seed2',
'system_time_zone',
diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_abort_loads.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_abort_loads.result
new file mode 100644
index 00000000000..1e2beea707e
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_abort_loads.result
@@ -0,0 +1,95 @@
+
+# innodb_buffer_pool_load_incomplete defaults 0
+SELECT variable_name, variable_value
+FROM information_schema.global_status
+WHERE LOWER(variable_name) = 'innodb_buffer_pool_load_incomplete';
+variable_name variable_value
+INNODB_BUFFER_POOL_LOAD_INCOMPLETE OFF
+
+# populate with data
+CREATE TABLE t1 (
+c01 blob, c02 blob, c03 blob, c04 blob, c05 blob,
+c06 blob, c07 blob, c08 blob, c09 blob, c10 blob,
+c11 blob, c12 blob, c13 blob, c14 blob, c15 blob,
+c16 blob, c17 blob, c18 blob, c19 blob, c20 blob,
+c21 blob, c22 blob, c23 blob, c24 blob, c25 blob,
+c26 blob, c27 blob, c28 blob, c29 blob, c30 blob,
+c31 blob, c32 blob, c33 blob, c34 blob, c35 blob,
+c36 blob, c37 blob, c38 blob, c39 blob, c40 blob,
+c41 blob, c42 blob, c43 blob, c44 blob, c45 blob,
+c46 blob, c47 blob, c48 blob, c49 blob, c50 blob,
+c51 blob, c52 blob, c53 blob, c54 blob, c55 blob,
+c56 blob, c57 blob, c58 blob, c59 blob, c60 blob,
+c61 blob, c62 blob, c63 blob, c64 blob
+) ROW_FORMAT=dynamic;
+SET @a = repeat('a', 16 * 1024);
+INSERT INTO t1 VALUES (@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a
+);
+SET GLOBAL innodb_buffer_pool_dump_now=1;
+
+# Restart server
+
+# Abort after 16 pages
+SET GLOBAL innodb_buffer_pool_load_pages_abort=16,
+GLOBAL innodb_buffer_pool_load_now=1,
+GLOBAL innodb_buffer_pool_dump_at_shutdown=1;
+SELECT variable_name, SUBSTR(variable_value, 1, 38) as VALUE
+FROM information_schema.global_status
+WHERE LOWER(variable_name) IN ('innodb_buffer_pool_load_incomplete','innodb_buffer_pool_load_status')
+ORDER BY variable_name;
+variable_name VALUE
+INNODB_BUFFER_POOL_LOAD_INCOMPLETE ON
+INNODB_BUFFER_POOL_LOAD_STATUS Buffer pool(s) load aborted on request
+
+# Restart server
+
+# Load buffer pool
+SET GLOBAL innodb_buffer_pool_load_now=1;
+
+# Should be more than previous as we didn't overwrite our save file
+select count(*) > Previous_loaded as Loaded_more from information_schema.INNODB_BUFFER_PAGE WHERE PAGE_TYPE='BLOB' group by PAGE_TYPE;;
+Loaded_more
+1
+
+# Successful, so innodb_buffer_pool_load_incomplete should be FALSE
+SELECT variable_name, SUBSTR(variable_value, 1, 33) as VALUE
+FROM information_schema.global_status
+WHERE LOWER(variable_name) IN ('innodb_buffer_pool_load_incomplete','innodb_buffer_pool_load_status')
+ORDER BY variable_name;
+variable_name VALUE
+INNODB_BUFFER_POOL_LOAD_INCOMPLETE OFF
+INNODB_BUFFER_POOL_LOAD_STATUS Buffer pool(s) load completed at
+
+# innodb_buffer_pool_dump_now=1 should reset the innodb_buffer_pool_load_incomplete status
+SET GLOBAL innodb_buffer_pool_dump_now=1;
+SELECT variable_name, SUBSTR(variable_value, 1, 33) as VALUE
+FROM information_schema.global_status
+WHERE LOWER(variable_name) IN ('innodb_buffer_pool_load_incomplete', 'innodb_buffer_pool_dump_status');
+variable_name VALUE
+INNODB_BUFFER_POOL_DUMP_STATUS Buffer pool(s) dump completed at
+INNODB_BUFFER_POOL_LOAD_INCOMPLETE OFF
+
+# Restart server
+
+# Load buffer pool
+SET GLOBAL innodb_buffer_pool_load_now=1;
+
+# Should be same amount
+select abs(Previously_dumped - count(*)) <= 2 as Loaded_about_same_size from information_schema.INNODB_BUFFER_PAGE WHERE PAGE_TYPE='BLOB' group by PAGE_TYPE;;
+Loaded_about_same_size
+1
+
+# Clean up
+DROP TABLE t1;
diff --git a/mysql-test/suite/sys_vars/r/innodb_spin_wait_delay_basic.result b/mysql-test/suite/sys_vars/r/innodb_spin_wait_delay_basic.result
index 88516a854fe..b76ba4933f2 100644
--- a/mysql-test/suite/sys_vars/r/innodb_spin_wait_delay_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_spin_wait_delay_basic.result
@@ -1,28 +1,28 @@
SET @start_global_value = @@global.innodb_spin_wait_delay;
SELECT @start_global_value;
@start_global_value
-6
+4
Valid values are zero or above
select @@global.innodb_spin_wait_delay >=0;
@@global.innodb_spin_wait_delay >=0
1
select @@global.innodb_spin_wait_delay;
@@global.innodb_spin_wait_delay
-6
+4
select @@session.innodb_spin_wait_delay;
ERROR HY000: Variable 'innodb_spin_wait_delay' is a GLOBAL variable
show global variables like 'innodb_spin_wait_delay';
Variable_name Value
-innodb_spin_wait_delay 6
+innodb_spin_wait_delay 4
show session variables like 'innodb_spin_wait_delay';
Variable_name Value
-innodb_spin_wait_delay 6
+innodb_spin_wait_delay 4
select * from information_schema.global_variables where variable_name='innodb_spin_wait_delay';
VARIABLE_NAME VARIABLE_VALUE
-INNODB_SPIN_WAIT_DELAY 6
+INNODB_SPIN_WAIT_DELAY 4
select * from information_schema.session_variables where variable_name='innodb_spin_wait_delay';
VARIABLE_NAME VARIABLE_VALUE
-INNODB_SPIN_WAIT_DELAY 6
+INNODB_SPIN_WAIT_DELAY 4
set global innodb_spin_wait_delay=10;
select @@global.innodb_spin_wait_delay;
@@global.innodb_spin_wait_delay
@@ -38,7 +38,7 @@ ERROR HY000: Variable 'innodb_spin_wait_delay' is a GLOBAL variable and should b
set global innodb_spin_wait_delay=DEFAULT;
select @@global.innodb_spin_wait_delay;
@@global.innodb_spin_wait_delay
-6
+4
set global innodb_spin_wait_delay=0;
select @@global.innodb_spin_wait_delay;
@@global.innodb_spin_wait_delay
@@ -111,4 +111,4 @@ INNODB_SPIN_WAIT_DELAY 0
SET @@global.innodb_spin_wait_delay = @start_global_value;
SELECT @@global.innodb_spin_wait_delay;
@@global.innodb_spin_wait_delay
-6
+4
diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
index cb3291dadea..87c837986ac 100644
--- a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
+++ b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
@@ -1,63 +1,63 @@
SET @start_global_value = @@global.optimizer_switch;
SELECT @start_global_value;
@start_global_value
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
select @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
show global variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
show session variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
select * from information_schema.global_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
select * from information_schema.session_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
set global optimizer_switch=10;
set session optimizer_switch=5;
select @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_grouping_derived=off
+index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_grouping_derived=off
+index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
set global optimizer_switch="index_merge_sort_union=on";
set session optimizer_switch="index_merge=off";
select @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_grouping_derived=off
+index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_grouping_derived=off
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
show global variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_grouping_derived=off
+optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
show session variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_grouping_derived=off
+optimizer_switch index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
select * from information_schema.global_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_grouping_derived=off
+OPTIMIZER_SWITCH index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
select * from information_schema.session_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_grouping_derived=off
+OPTIMIZER_SWITCH index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
set session optimizer_switch="default";
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_grouping_derived=off
+index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
set optimizer_switch = replace(@@optimizer_switch, '=off', '=on');
Warnings:
Warning 1681 'engine_condition_pushdown=on' is deprecated and will be removed in a future release
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
set global optimizer_switch=1.1;
ERROR 42000: Incorrect argument type to variable 'optimizer_switch'
set global optimizer_switch=1e1;
@@ -69,4 +69,4 @@ ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'foobar'
SET @@global.optimizer_switch = @start_global_value;
SELECT @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result
index 7454f0b0089..0c90462df59 100644
--- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result
+++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result
@@ -65,6 +65,12 @@ set global rpl_semi_sync_master_enabled=1e1;
ERROR 42000: Incorrect argument type to variable 'rpl_semi_sync_master_enabled'
set global rpl_semi_sync_master_enabled="some text";
ERROR 42000: Variable 'rpl_semi_sync_master_enabled' can't be set to the value of 'some text'
+connect con1,localhost,root,,;
+connect con2,localhost,root,,;
+disconnect con1;
+disconnect con2;
+connection default;
+SET @@global.rpl_semi_sync_master_enabled = 1;
SET @@global.rpl_semi_sync_master_enabled = @start_global_value;
select @@global.rpl_semi_sync_master_enabled;
@@global.rpl_semi_sync_master_enabled
diff --git a/mysql-test/suite/sys_vars/r/slave_transaction_retry_errors.result b/mysql-test/suite/sys_vars/r/slave_transaction_retry_errors.result
new file mode 100644
index 00000000000..a7815bb3f78
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/slave_transaction_retry_errors.result
@@ -0,0 +1,21 @@
+select @@global.slave_transaction_retry_errors;
+@@global.slave_transaction_retry_errors
+1213,1205,10,20,400
+select @@session.slave_transaction_retry_errors;
+ERROR HY000: Variable 'slave_transaction_retry_errors' is a GLOBAL variable
+show global variables like 'slave_transaction_retry_errors';
+Variable_name Value
+slave_transaction_retry_errors 1213,1205,10,20,400
+show session variables like 'slave_transaction_retry_errors';
+Variable_name Value
+slave_transaction_retry_errors 1213,1205,10,20,400
+select * from information_schema.global_variables where variable_name='slave_transaction_retry_errors';
+VARIABLE_NAME VARIABLE_VALUE
+SLAVE_TRANSACTION_RETRY_ERRORS 1213,1205,10,20,400
+select * from information_schema.session_variables where variable_name='slave_transaction_retry_errors';
+VARIABLE_NAME VARIABLE_VALUE
+SLAVE_TRANSACTION_RETRY_ERRORS 1213,1205,10,20,400
+set global slave_transaction_retry_errors=1;
+ERROR HY000: Variable 'slave_transaction_retry_errors' is a read only variable
+set session slave_transaction_retry_errors=1;
+ERROR HY000: Variable 'slave_transaction_retry_errors' is a read only variable
diff --git a/mysql-test/suite/sys_vars/r/slave_transaction_retry_interval_basic.result b/mysql-test/suite/sys_vars/r/slave_transaction_retry_interval_basic.result
new file mode 100644
index 00000000000..8be45f83341
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/slave_transaction_retry_interval_basic.result
@@ -0,0 +1,126 @@
+SET @start_global_value = @@global.slave_transaction_retry_interval;
+SELECT @start_global_value;
+@start_global_value
+0
+'#--------------------FN_DYNVARS_149_01-------------------------#'
+SET @@global.slave_transaction_retry_interval = 50;
+SET @@global.slave_transaction_retry_interval = DEFAULT;
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+0
+'#--------------------FN_DYNVARS_149_02-------------------------#'
+SET @@global.slave_transaction_retry_interval = DEFAULT;
+SELECT @@global.slave_transaction_retry_interval = 10;
+@@global.slave_transaction_retry_interval = 10
+0
+'#--------------------FN_DYNVARS_149_03-------------------------#'
+SET @@global.slave_transaction_retry_interval = 0;
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+0
+SET @@global.slave_transaction_retry_interval = 1;
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+1
+SET @@global.slave_transaction_retry_interval = 15;
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+15
+SET @@global.slave_transaction_retry_interval = 1024;
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+1024
+SET @@global.slave_transaction_retry_interval = 2147483648;
+Warnings:
+Warning 1292 Truncated incorrect slave_transaction_retry_interval value: '2147483648'
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+3600
+SET @@global.slave_transaction_retry_interval = 2147483648*2-1;
+Warnings:
+Warning 1292 Truncated incorrect slave_transaction_retry_interval value: '4294967295'
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+3600
+SET @@global.slave_transaction_retry_interval = 2147483649*2;
+Warnings:
+Warning 1292 Truncated incorrect slave_transaction_retry_interval value: '4294967298'
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+3600
+SET @@global.slave_transaction_retry_interval = 4294967295;
+Warnings:
+Warning 1292 Truncated incorrect slave_transaction_retry_interval value: '4294967295'
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+3600
+'#--------------------FN_DYNVARS_149_04-------------------------#'
+SET @@slave_transaction_retry_interval = 2;
+ERROR HY000: Variable 'slave_transaction_retry_interval' is a GLOBAL variable and should be set with SET GLOBAL
+SET @@session.slave_transaction_retry_interval = 3;
+ERROR HY000: Variable 'slave_transaction_retry_interval' is a GLOBAL variable and should be set with SET GLOBAL
+SET @@local.slave_transaction_retry_interval = 4;
+ERROR HY000: Variable 'slave_transaction_retry_interval' is a GLOBAL variable and should be set with SET GLOBAL
+'#------------------FN_DYNVARS_149_05-----------------------#'
+SET @@global.slave_transaction_retry_interval = -1;
+Warnings:
+Warning 1292 Truncated incorrect slave_transaction_retry_interval value: '-1'
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+0
+SET @@global.slave_transaction_retry_interval = 2147483649*2147483649;
+Warnings:
+Warning 1292 Truncated incorrect slave_transaction_retry_interval value: '4611686022722355201'
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+3600
+SET @@global.slave_transaction_retry_interval = 65530.34;
+ERROR 42000: Incorrect argument type to variable 'slave_transaction_retry_interval'
+SET @@global.slave_transaction_retry_interval = '100';
+ERROR 42000: Incorrect argument type to variable 'slave_transaction_retry_interval'
+SET @@global.slave_transaction_retry_interval = 7483649.56;
+ERROR 42000: Incorrect argument type to variable 'slave_transaction_retry_interval'
+SET @@global.slave_transaction_retry_interval = ON;
+ERROR 42000: Incorrect argument type to variable 'slave_transaction_retry_interval'
+SET @@global.slave_transaction_retry_interval = OFF;
+ERROR 42000: Incorrect argument type to variable 'slave_transaction_retry_interval'
+'#------------------FN_DYNVARS_149_06-----------------------#'
+SET @@global.slave_transaction_retry_interval = 3000;
+SELECT @@global.slave_transaction_retry_interval = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='slave_transaction_retry_interval';
+@@global.slave_transaction_retry_interval = VARIABLE_VALUE
+1
+'#------------------FN_DYNVARS_149_07-----------------------#'
+SELECT count(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='slave_transaction_retry_interval';
+count(VARIABLE_VALUE)
+1
+'#------------------FN_DYNVARS_149_08-----------------------#'
+SET @@global.slave_transaction_retry_interval = TRUE;
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+1
+SET @@global.slave_transaction_retry_interval = FALSE;
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+0
+'#---------------------FN_DYNVARS_149_09----------------------#'
+SET @@global.slave_transaction_retry_interval = 60*60;
+SELECT @@slave_transaction_retry_interval = @@global.slave_transaction_retry_interval;
+@@slave_transaction_retry_interval = @@global.slave_transaction_retry_interval
+1
+'#---------------------FN_DYNVARS_149_10----------------------#'
+SET slave_transaction_retry_interval = 2048;
+ERROR HY000: Variable 'slave_transaction_retry_interval' is a GLOBAL variable and should be set with SET GLOBAL
+SELECT slave_transaction_retry_interval;
+ERROR 42S22: Unknown column 'slave_transaction_retry_interval' in 'field list'
+SELECT @@slave_transaction_retry_interval;
+@@slave_transaction_retry_interval
+3600
+SET global slave_transaction_retry_interval = 99;
+SET @@global.slave_transaction_retry_interval = @start_global_value;
+SELECT @@global.slave_transaction_retry_interval;
+@@global.slave_transaction_retry_interval
+0
diff --git a/mysql-test/suite/sys_vars/r/sql_mode_basic.result b/mysql-test/suite/sys_vars/r/sql_mode_basic.result
index 3bd813334eb..a200f620a7c 100644
--- a/mysql-test/suite/sys_vars/r/sql_mode_basic.result
+++ b/mysql-test/suite/sys_vars/r/sql_mode_basic.result
@@ -158,7 +158,7 @@ MYSQL40,HIGH_NOT_PRECEDENCE
SET @@global.sql_mode = ORACLE;
SELECT @@global.sql_mode;
@@global.sql_mode
-PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
+PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT
SET @@global.sql_mode = POSTGRESQL;
SELECT @@global.sql_mode;
@@global.sql_mode
@@ -288,7 +288,7 @@ MYSQL40,HIGH_NOT_PRECEDENCE
SET @@session.sql_mode = ORACLE;
SELECT @@session.sql_mode;
@@session.sql_mode
-PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
+PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT
SET @@session.sql_mode = POSTGRESQL;
SELECT @@session.sql_mode;
@@session.sql_mode
@@ -357,17 +357,17 @@ REAL_AS_FLOAT,PIPES_AS_CONCAT
SET @@global.sql_mode = 50000;
SELECT @@global.sql_mode;
@@global.sql_mode
-PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,NO_UNSIGNED_SUBTRACTION,POSTGRESQL,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
+PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,NO_UNSIGNED_SUBTRACTION,POSTGRESQL,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT
SET @@global.sql_mode = 500000;
SELECT @@global.sql_mode;
@@global.sql_mode
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,POSTGRESQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,HIGH_NOT_PRECEDENCE
-SET @@global.sql_mode = 8589934591;
+SET @@global.sql_mode = 17179869183;
SELECT @@global.sql_mode;
@@global.sql_mode
-REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL
-SET @@global.sql_mode = 8589934592;
-ERROR 42000: Variable 'sql_mode' can't be set to the value of '8589934592'
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT
+SET @@global.sql_mode = 17179869184;
+ERROR 42000: Variable 'sql_mode' can't be set to the value of '17179869184'
SET @@global.sql_mode = 0.4;
ERROR 42000: Incorrect argument type to variable 'sql_mode'
'#---------------------FN_DYNVARS_152_08----------------------#'
@@ -397,7 +397,7 @@ ANSI_QUOTES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,A
SET @@global.sql_mode = 'ONLY_FULL_GROUP_BY,PIPES_AS_CONCAT,REAL_AS_FLOAT,ORACLE,POSTGRESQL';
SELECT @@global.sql_mode;
@@global.sql_mode
-REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,POSTGRESQL,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,POSTGRESQL,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT
SET @@session.sql_mode = 'ERROR_FOR_DIVISION_BY_ZERO,FOOBAR,IGNORE_SPACE';
ERROR 42000: Variable 'sql_mode' can't be set to the value of 'FOOBAR'
SET @@sql_mode=',';
diff --git a/mysql-test/suite/sys_vars/r/sysvars_debug.result b/mysql-test/suite/sys_vars/r/sysvars_debug.result
index f50e796bff4..b544f6b50d9 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_debug.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_debug.result
@@ -1,5 +1,6 @@
select * from information_schema.system_variables
where variable_name like 'debug%'
+ or variable_name = 'in_predicate_conversion_threshold'
order by variable_name;
VARIABLE_NAME DEBUG
SESSION_VALUE
@@ -85,3 +86,17 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT NULL
+VARIABLE_NAME IN_PREDICATE_CONVERSION_THRESHOLD
+SESSION_VALUE 1000
+GLOBAL_VALUE 1000
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 1000
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE INT UNSIGNED
+VARIABLE_COMMENT The minimum number of scalar elements in the value list of IN predicate that triggers its conversion to IN subquery
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 4294967295
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index 9d15f3f5a78..ab66efb13d4 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -4,7 +4,8 @@ variable_name not in (
'innodb_disallow_writes', # only available WITH_WSREP
'innodb_numa_interleave', # only available WITH_NUMA
'innodb_sched_priority_cleaner', # linux only
-'innodb_use_native_aio') # default value depends on OS
+'innodb_use_native_aio', # default value depends on OS
+'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing
order by variable_name;
VARIABLE_NAME INNODB_ADAPTIVE_FLUSHING
SESSION_VALUE NULL
@@ -1334,7 +1335,7 @@ NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST fcfs,vats
-READ_ONLY NO
+READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_LOCK_WAIT_TIMEOUT
SESSION_VALUE 50
@@ -1996,12 +1997,12 @@ READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_SPIN_WAIT_DELAY
SESSION_VALUE NULL
-GLOBAL_VALUE 6
+GLOBAL_VALUE 4
GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE 6
+DEFAULT_VALUE 4
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE INT UNSIGNED
-VARIABLE_COMMENT Maximum delay between polling for a spin lock (6 by default)
+VARIABLE_COMMENT Maximum delay between polling for a spin lock (4 by default)
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 6000
NUMERIC_BLOCK_SIZE 0
@@ -2402,7 +2403,7 @@ READ_ONLY YES
COMMAND_LINE_ARGUMENT NONE
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
-GLOBAL_VALUE 5.7.20
+GLOBAL_VALUE 5.7.21
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
VARIABLE_SCOPE GLOBAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
index e52e0d30abe..09ac37198f0 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -8,6 +8,7 @@ where variable_name not like 'aria%' and
variable_name not like 'debug%' and
variable_name not like 'wsrep%' and
variable_name not in (
+'in_predicate_conversion_threshold',
'have_openssl',
'have_symlink',
'hostname',
@@ -15,6 +16,7 @@ variable_name not in (
'lower_case_file_system',
'lower_case_table_names',
'open_files_limit',
+'plugin_maturity',
'rand_seed1',
'rand_seed2',
'system_time_zone',
@@ -899,7 +901,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE OFF
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN
-VARIABLE_COMMENT This option causes CREATE TABLE to create all TIMESTAMP columns as NULL with DEFAULT NULL attribute, Without this option, TIMESTAMP columns are NOT NULL and have implicit DEFAULT clauses. The old behavior is deprecated.
+VARIABLE_COMMENT This option causes CREATE TABLE to create all TIMESTAMP columns as NULL with DEFAULT NULL attribute, Without this option, TIMESTAMP columns are NOT NULL and have implicit DEFAULT clauses.
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
@@ -1438,20 +1440,6 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
-VARIABLE_NAME IN_SUBQUERY_CONVERSION_THRESHOLD
-SESSION_VALUE 1000
-GLOBAL_VALUE 1000
-GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE 1000
-VARIABLE_SCOPE SESSION
-VARIABLE_TYPE BIGINT UNSIGNED
-VARIABLE_COMMENT The minimum number of scalar elements in the value list of IN predicate that triggers its conversion to IN subquery
-NUMERIC_MIN_VALUE 0
-NUMERIC_MAX_VALUE 18446744073709551615
-NUMERIC_BLOCK_SIZE 1
-ENUM_VALUE_LIST NULL
-READ_ONLY NO
-COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME IN_TRANSACTION
SESSION_VALUE 0
GLOBAL_VALUE NULL
@@ -2685,17 +2673,17 @@ ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_SWITCH
-SESSION_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
-GLOBAL_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+SESSION_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+GLOBAL_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+DEFAULT_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
VARIABLE_SCOPE SESSION
VARIABLE_TYPE FLAGSET
VARIABLE_COMMENT Fine-tune the optimizer behavior
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
-ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_grouping_derived,default
+ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,default
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_USE_CONDITION_SELECTIVITY
@@ -3188,20 +3176,6 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
-VARIABLE_NAME PLUGIN_MATURITY
-SESSION_VALUE NULL
-GLOBAL_VALUE unknown
-GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE unknown
-VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE ENUM
-VARIABLE_COMMENT The lowest desirable plugin maturity. Plugins less mature than that will not be installed or loaded
-NUMERIC_MIN_VALUE NULL
-NUMERIC_MAX_VALUE NULL
-NUMERIC_BLOCK_SIZE NULL
-ENUM_VALUE_LIST unknown,experimental,alpha,beta,gamma,stable
-READ_ONLY YES
-COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME PORT
SESSION_VALUE NULL
GLOBAL_VALUE MASTER_MYPORT
@@ -3815,7 +3789,7 @@ VARIABLE_COMMENT Sets the sql mode
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
-ENUM_VALUE_LIST REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL
+ENUM_VALUE_LIST REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME SQL_NOTES
@@ -4084,6 +4058,34 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME SYSTEM_VERSIONING_ALTER_HISTORY
+SESSION_VALUE ERROR
+GLOBAL_VALUE ERROR
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE ERROR
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE ENUM
+VARIABLE_COMMENT Versioning ALTER TABLE mode. ERROR: Fail ALTER with error; KEEP: Keep historical system rows and subject them to ALTER;
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST ERROR,KEEP
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME SYSTEM_VERSIONING_ASOF
+SESSION_VALUE DEFAULT
+GLOBAL_VALUE DEFAULT
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE DEFAULT
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE VARCHAR
+VARIABLE_COMMENT Default value for the FOR SYSTEM_TIME AS OF clause
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST DEFAULT
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT NULL
VARIABLE_NAME TABLE_DEFINITION_CACHE
SESSION_VALUE NULL
GLOBAL_VALUE 400
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff
index b27c493c6c4..cb9e84b81c8 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff
@@ -1,5 +1,5 @@
---- sysvars_server_notembedded.result 2017-11-17 17:00:22.470630255 +0100
-+++ sysvars_server_notembedded,32bit.reject 2017-11-17 19:12:42.732453556 +0100
+--- sysvars_server_notembedded.result 2017-12-15 20:57:40.174654761 +0200
++++ sysvars_server_notembedded,32bit.reject 2017-12-15 21:02:20.476044700 +0200
@@ -58,7 +58,7 @@
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE 1
@@ -1116,7 +1116,46 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
-@@ -4048,7 +4048,7 @@
+@@ -4034,10 +4034,10 @@
+ GLOBAL_VALUE_ORIGIN COMPILE-TIME
+ DEFAULT_VALUE 10000
+ VARIABLE_SCOPE GLOBAL
+-VARIABLE_TYPE BIGINT UNSIGNED
++VARIABLE_TYPE INT UNSIGNED
+ VARIABLE_COMMENT The timeout value (in ms) for semi-synchronous replication in the master
+ NUMERIC_MIN_VALUE 0
+-NUMERIC_MAX_VALUE 18446744073709551615
++NUMERIC_MAX_VALUE 4294967295
+ NUMERIC_BLOCK_SIZE 1
+ ENUM_VALUE_LIST NULL
+ READ_ONLY NO
+@@ -4048,10 +4048,10 @@
+ GLOBAL_VALUE_ORIGIN COMPILE-TIME
+ DEFAULT_VALUE 32
+ VARIABLE_SCOPE GLOBAL
+-VARIABLE_TYPE BIGINT UNSIGNED
++VARIABLE_TYPE INT UNSIGNED
+ VARIABLE_COMMENT The tracing level for semi-sync replication.
+ NUMERIC_MIN_VALUE 0
+-NUMERIC_MAX_VALUE 18446744073709551615
++NUMERIC_MAX_VALUE 4294967295
+ NUMERIC_BLOCK_SIZE 1
+ ENUM_VALUE_LIST NULL
+ READ_ONLY NO
+@@ -4132,10 +4132,10 @@
+ GLOBAL_VALUE_ORIGIN COMPILE-TIME
+ DEFAULT_VALUE 32
+ VARIABLE_SCOPE GLOBAL
+-VARIABLE_TYPE BIGINT UNSIGNED
++VARIABLE_TYPE INT UNSIGNED
+ VARIABLE_COMMENT The tracing level for semi-sync replication.
+ NUMERIC_MIN_VALUE 0
+-NUMERIC_MAX_VALUE 18446744073709551615
++NUMERIC_MAX_VALUE 4294967295
+ NUMERIC_BLOCK_SIZE 1
+ ENUM_VALUE_LIST NULL
+ READ_ONLY NO
+@@ -4174,7 +4174,7 @@
GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE 1
VARIABLE_SCOPE SESSION
@@ -1125,7 +1164,7 @@
VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 4294967295
-@@ -4230,7 +4230,7 @@
+@@ -4356,7 +4356,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL
@@ -1134,7 +1173,7 @@
VARIABLE_COMMENT Maximum number of parallel threads to use on slave for events in a single replication domain. When using multiple domains, this can be used to limit a single domain from grabbing all threads and thus stalling other domains. The default of 0 means to allow a domain to grab as many threads as it wants, up to the value of slave_parallel_threads.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16383
-@@ -4272,7 +4272,7 @@
+@@ -4398,7 +4398,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1073741824
VARIABLE_SCOPE GLOBAL
@@ -1143,7 +1182,7 @@
VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave.
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 1073741824
-@@ -4300,7 +4300,7 @@
+@@ -4426,7 +4426,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 131072
VARIABLE_SCOPE GLOBAL
@@ -1152,7 +1191,7 @@
VARIABLE_COMMENT Limit on how much memory SQL threads should use per parallel replication thread when reading ahead in the relay log looking for opportunities for parallel replication. Only used when --slave-parallel-threads > 0.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 2147483647
-@@ -4328,7 +4328,7 @@
+@@ -4454,7 +4454,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL
@@ -1161,7 +1200,7 @@
VARIABLE_COMMENT If non-zero, number of threads to spawn to apply in parallel events on the slave that were group-committed on the master or were logged with GTID in different replication domains. Note that these threads are in addition to the IO and SQL threads, which are always created by a replication slave
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16383
-@@ -4342,7 +4342,7 @@
+@@ -4468,7 +4468,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL
@@ -1170,16 +1209,25 @@
VARIABLE_COMMENT Alias for slave_parallel_threads
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16383
-@@ -4398,7 +4398,7 @@
+@@ -4524,7 +4524,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
- VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout, before giving up and stopping
+ VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock, elapsed lock wait timeout or listed in slave_transaction_retry_errors, before giving up and stopping
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
-@@ -4426,7 +4426,7 @@
+@@ -4552,7 +4552,7 @@
+ GLOBAL_VALUE_ORIGIN COMPILE-TIME
+ DEFAULT_VALUE 0
+ VARIABLE_SCOPE GLOBAL
+-VARIABLE_TYPE BIGINT UNSIGNED
++VARIABLE_TYPE INT UNSIGNED
+ VARIABLE_COMMENT Interval of the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout or listed in slave_transaction_retry_errors
+ NUMERIC_MIN_VALUE 0
+ NUMERIC_MAX_VALUE 3600
+@@ -4580,7 +4580,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 2
VARIABLE_SCOPE GLOBAL
@@ -1188,7 +1236,7 @@
VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 31536000
-@@ -4485,7 +4485,7 @@
+@@ -4639,7 +4639,7 @@
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size
NUMERIC_MIN_VALUE 1024
@@ -1197,7 +1245,7 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
-@@ -4790,7 +4790,7 @@
+@@ -4944,7 +4944,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 256
VARIABLE_SCOPE GLOBAL
@@ -1206,7 +1254,7 @@
VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 524288
-@@ -4888,7 +4888,7 @@
+@@ -5042,7 +5042,7 @@
GLOBAL_VALUE_ORIGIN AUTO
DEFAULT_VALUE 400
VARIABLE_SCOPE GLOBAL
@@ -1215,7 +1263,7 @@
VARIABLE_COMMENT The number of cached table definitions
NUMERIC_MIN_VALUE 400
NUMERIC_MAX_VALUE 524288
-@@ -4902,7 +4902,7 @@
+@@ -5056,7 +5056,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 2000
VARIABLE_SCOPE GLOBAL
@@ -1224,7 +1272,7 @@
VARIABLE_COMMENT The number of cached open tables
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 1048576
-@@ -4972,7 +4972,7 @@
+@@ -5126,7 +5126,7 @@
GLOBAL_VALUE_ORIGIN AUTO
DEFAULT_VALUE 256
VARIABLE_SCOPE GLOBAL
@@ -1233,7 +1281,7 @@
VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16384
-@@ -4986,7 +4986,7 @@
+@@ -5140,7 +5140,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10
VARIABLE_SCOPE GLOBAL
@@ -1242,7 +1290,7 @@
VARIABLE_COMMENT Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.This variable has no effect, and is deprecated. It will be removed in a future release.
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 512
-@@ -5191,15 +5191,15 @@
+@@ -5345,15 +5345,15 @@
READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME TMP_DISK_TABLE_SIZE
@@ -1262,7 +1310,7 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
-@@ -5213,7 +5213,7 @@
+@@ -5367,7 +5367,7 @@
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size.
NUMERIC_MIN_VALUE 1024
@@ -1271,7 +1319,7 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
-@@ -5227,7 +5227,7 @@
+@@ -5381,7 +5381,7 @@
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Alias for tmp_memory_table_size. If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table.
NUMERIC_MIN_VALUE 1024
@@ -1280,7 +1328,7 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
-@@ -5238,7 +5238,7 @@
+@@ -5392,7 +5392,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 8192
VARIABLE_SCOPE SESSION
@@ -1289,7 +1337,7 @@
VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 134217728
-@@ -5252,7 +5252,7 @@
+@@ -5406,7 +5406,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 4096
VARIABLE_SCOPE SESSION
@@ -1298,7 +1346,7 @@
VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 134217728
-@@ -5350,7 +5350,7 @@
+@@ -5504,7 +5504,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 28800
VARIABLE_SCOPE SESSION
@@ -1307,7 +1355,7 @@
VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 31536000
-@@ -5455,7 +5455,7 @@
+@@ -5609,7 +5609,7 @@
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME OPEN_FILES_LIMIT
VARIABLE_SCOPE GLOBAL
@@ -1316,7 +1364,7 @@
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 or autoset then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
-@@ -5468,7 +5468,7 @@
+@@ -5622,7 +5622,7 @@
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes
NUMERIC_MIN_VALUE 0
@@ -1325,7 +1373,7 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
-@@ -5478,7 +5478,7 @@
+@@ -5632,7 +5632,7 @@
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes
NUMERIC_MIN_VALUE 0
@@ -1334,7 +1382,7 @@
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
-@@ -5573,7 +5573,7 @@
+@@ -5727,7 +5727,7 @@
VARIABLE_NAME LOG_TC_SIZE
GLOBAL_VALUE_ORIGIN AUTO
VARIABLE_SCOPE GLOBAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index aadb885135d..63f50e34ed3 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -8,6 +8,7 @@ where variable_name not like 'aria%' and
variable_name not like 'debug%' and
variable_name not like 'wsrep%' and
variable_name not in (
+'in_predicate_conversion_threshold',
'have_openssl',
'have_symlink',
'hostname',
@@ -15,6 +16,7 @@ variable_name not in (
'lower_case_file_system',
'lower_case_table_names',
'open_files_limit',
+'plugin_maturity',
'rand_seed1',
'rand_seed2',
'system_time_zone',
@@ -927,7 +929,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE OFF
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN
-VARIABLE_COMMENT This option causes CREATE TABLE to create all TIMESTAMP columns as NULL with DEFAULT NULL attribute, Without this option, TIMESTAMP columns are NOT NULL and have implicit DEFAULT clauses. The old behavior is deprecated.
+VARIABLE_COMMENT This option causes CREATE TABLE to create all TIMESTAMP columns as NULL with DEFAULT NULL attribute, Without this option, TIMESTAMP columns are NOT NULL and have implicit DEFAULT clauses.
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
@@ -1564,20 +1566,6 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
-VARIABLE_NAME IN_SUBQUERY_CONVERSION_THRESHOLD
-SESSION_VALUE 1000
-GLOBAL_VALUE 1000
-GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE 1000
-VARIABLE_SCOPE SESSION
-VARIABLE_TYPE BIGINT UNSIGNED
-VARIABLE_COMMENT The minimum number of scalar elements in the value list of IN predicate that triggers its conversion to IN subquery
-NUMERIC_MIN_VALUE 0
-NUMERIC_MAX_VALUE 18446744073709551615
-NUMERIC_BLOCK_SIZE 1
-ENUM_VALUE_LIST NULL
-READ_ONLY NO
-COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME IN_TRANSACTION
SESSION_VALUE 0
GLOBAL_VALUE NULL
@@ -2895,17 +2883,17 @@ ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_SWITCH
-SESSION_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
-GLOBAL_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+SESSION_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+GLOBAL_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+DEFAULT_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
VARIABLE_SCOPE SESSION
VARIABLE_TYPE FLAGSET
VARIABLE_COMMENT Fine-tune the optimizer behavior
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
-ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_grouping_derived,default
+ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,default
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_USE_CONDITION_SELECTIVITY
@@ -3398,20 +3386,6 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
-VARIABLE_NAME PLUGIN_MATURITY
-SESSION_VALUE NULL
-GLOBAL_VALUE unknown
-GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE unknown
-VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE ENUM
-VARIABLE_COMMENT The lowest desirable plugin maturity. Plugins less mature than that will not be installed or loaded
-NUMERIC_MIN_VALUE NULL
-NUMERIC_MAX_VALUE NULL
-NUMERIC_BLOCK_SIZE NULL
-ENUM_VALUE_LIST unknown,experimental,alpha,beta,gamma,stable
-READ_ONLY YES
-COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME PORT
SESSION_VALUE NULL
GLOBAL_VALUE MASTER_MYPORT
@@ -4014,6 +3988,132 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME RPL_SEMI_SYNC_MASTER_ENABLED
+SESSION_VALUE NULL
+GLOBAL_VALUE OFF
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE OFF
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BOOLEAN
+VARIABLE_COMMENT Enable semi-synchronous replication master (disabled by default).
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST OFF,ON
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
+VARIABLE_NAME RPL_SEMI_SYNC_MASTER_TIMEOUT
+SESSION_VALUE NULL
+GLOBAL_VALUE 10000
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 10000
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT The timeout value (in ms) for semi-synchronous replication in the master
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME RPL_SEMI_SYNC_MASTER_TRACE_LEVEL
+SESSION_VALUE NULL
+GLOBAL_VALUE 32
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 32
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT The tracing level for semi-sync replication.
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME RPL_SEMI_SYNC_MASTER_WAIT_NO_SLAVE
+SESSION_VALUE NULL
+GLOBAL_VALUE ON
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE ON
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BOOLEAN
+VARIABLE_COMMENT Wait until timeout when no semi-synchronous replication slave available (enabled by default).
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST OFF,ON
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
+VARIABLE_NAME RPL_SEMI_SYNC_MASTER_WAIT_POINT
+SESSION_VALUE NULL
+GLOBAL_VALUE AFTER_COMMIT
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE AFTER_COMMIT
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE ENUM
+VARIABLE_COMMENT Should transaction wait for semi-sync ack after having synced binlog, or after having committed in storage engine.
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST AFTER_SYNC,AFTER_COMMIT
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME RPL_SEMI_SYNC_SLAVE_DELAY_MASTER
+SESSION_VALUE NULL
+GLOBAL_VALUE OFF
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE OFF
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BOOLEAN
+VARIABLE_COMMENT Only write master info file when ack is needed.
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST OFF,ON
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
+VARIABLE_NAME RPL_SEMI_SYNC_SLAVE_ENABLED
+SESSION_VALUE NULL
+GLOBAL_VALUE OFF
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE OFF
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BOOLEAN
+VARIABLE_COMMENT Enable semi-synchronous replication slave (disabled by default).
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST OFF,ON
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
+VARIABLE_NAME RPL_SEMI_SYNC_SLAVE_KILL_CONN_TIMEOUT
+SESSION_VALUE NULL
+GLOBAL_VALUE 5
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 5
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE INT UNSIGNED
+VARIABLE_COMMENT Timeout for the mysql connection used to kill the slave io_thread's connection on master. This timeout comes into play when stop slave is executed.
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 4294967295
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
+VARIABLE_NAME RPL_SEMI_SYNC_SLAVE_TRACE_LEVEL
+SESSION_VALUE NULL
+GLOBAL_VALUE 32
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 32
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT The tracing level for semi-sync replication.
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME SECURE_AUTH
SESSION_VALUE NULL
GLOBAL_VALUE ON
@@ -4399,13 +4499,41 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
-VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout, before giving up and stopping
+VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock, elapsed lock wait timeout or listed in slave_transaction_retry_errors, before giving up and stopping
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME SLAVE_TRANSACTION_RETRY_ERRORS
+SESSION_VALUE NULL
+GLOBAL_VALUE 1213,1205
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE VARCHAR
+VARIABLE_COMMENT Tells the slave thread to retry transaction for replication when a query event returns an error from the provided list. Deadlock and elapsed lock wait timeout errors are automatically added to this list
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST NULL
+READ_ONLY YES
+COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME SLAVE_TRANSACTION_RETRY_INTERVAL
+SESSION_VALUE NULL
+GLOBAL_VALUE 0
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 0
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT Interval of the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout or listed in slave_transaction_retry_errors
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 3600
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME SLAVE_TYPE_CONVERSIONS
SESSION_VALUE NULL
GLOBAL_VALUE
@@ -4571,7 +4699,7 @@ VARIABLE_COMMENT Sets the sql mode
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
-ENUM_VALUE_LIST REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL
+ENUM_VALUE_LIST REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME SQL_NOTES
@@ -4882,6 +5010,34 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME SYSTEM_VERSIONING_ALTER_HISTORY
+SESSION_VALUE ERROR
+GLOBAL_VALUE ERROR
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE ERROR
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE ENUM
+VARIABLE_COMMENT Versioning ALTER TABLE mode. ERROR: Fail ALTER with error; KEEP: Keep historical system rows and subject them to ALTER;
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST ERROR,KEEP
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME SYSTEM_VERSIONING_ASOF
+SESSION_VALUE DEFAULT
+GLOBAL_VALUE DEFAULT
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE DEFAULT
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE VARCHAR
+VARIABLE_COMMENT Default value for the FOR SYSTEM_TIME AS OF clause
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST DEFAULT
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT NULL
VARIABLE_NAME TABLE_DEFINITION_CACHE
SESSION_VALUE NULL
GLOBAL_VALUE 400
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_abort_loads.opt b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_abort_loads.opt
new file mode 100644
index 00000000000..787f6ce532d
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_abort_loads.opt
@@ -0,0 +1,5 @@
+--loose-default-storage-engine=innodb
+--loose-innodb_buffer_pool_load_at_startup=0
+--loose-innodb_buffer_pool_dump_at_shutdown=0
+--loose-innodb-buffer-pool-size=8M
+--loose-innodb-page-size=16k
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_abort_loads.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_abort_loads.test
new file mode 100644
index 00000000000..4a4411101e2
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_abort_loads.test
@@ -0,0 +1,149 @@
+#
+# MDEV-11455 - add status variable innodb_buffer_pool_load_abort
+#
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+--echo
+--echo # innodb_buffer_pool_load_incomplete defaults 0
+SELECT variable_name, variable_value
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_load_incomplete';
+
+--echo
+--echo # populate with data
+
+CREATE TABLE t1 (
+c01 blob, c02 blob, c03 blob, c04 blob, c05 blob,
+c06 blob, c07 blob, c08 blob, c09 blob, c10 blob,
+c11 blob, c12 blob, c13 blob, c14 blob, c15 blob,
+c16 blob, c17 blob, c18 blob, c19 blob, c20 blob,
+c21 blob, c22 blob, c23 blob, c24 blob, c25 blob,
+c26 blob, c27 blob, c28 blob, c29 blob, c30 blob,
+c31 blob, c32 blob, c33 blob, c34 blob, c35 blob,
+c36 blob, c37 blob, c38 blob, c39 blob, c40 blob,
+c41 blob, c42 blob, c43 blob, c44 blob, c45 blob,
+c46 blob, c47 blob, c48 blob, c49 blob, c50 blob,
+c51 blob, c52 blob, c53 blob, c54 blob, c55 blob,
+c56 blob, c57 blob, c58 blob, c59 blob, c60 blob,
+c61 blob, c62 blob, c63 blob, c64 blob
+) ROW_FORMAT=dynamic;
+
+SET @a = repeat('a', 16 * 1024);
+INSERT INTO t1 VALUES (@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a,@a,
+@a,@a,@a,@a
+);
+
+SET GLOBAL innodb_buffer_pool_dump_now=1;
+# Wait for for the dump to complete
+let $wait_condition =
+ SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at '
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
+-- source include/wait_condition.inc
+
+--echo
+--echo # Restart server
+--source include/restart_mysqld.inc
+
+--echo
+--echo # Abort after 16 pages
+SET GLOBAL innodb_buffer_pool_load_pages_abort=16,
+ GLOBAL innodb_buffer_pool_load_now=1,
+ GLOBAL innodb_buffer_pool_dump_at_shutdown=1;
+
+let $wait_condition =
+ SELECT SUBSTR(variable_value, 1, 19) = 'Buffer pool(s) load'
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_load_status';
+-- source include/wait_condition.inc
+
+SELECT variable_name, SUBSTR(variable_value, 1, 38) as VALUE
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) IN ('innodb_buffer_pool_load_incomplete','innodb_buffer_pool_load_status')
+ ORDER BY variable_name;
+
+--let $incomplete=`select count(*) as BLOB_PAGES from information_schema.INNODB_BUFFER_PAGE WHERE PAGE_TYPE='BLOB' group by PAGE_TYPE`
+
+# Shouldn't dump at shutdown due to innodb_buffer_pool_load_incomplete
+
+--echo
+--echo # Restart server
+--source include/restart_mysqld.inc
+
+--echo
+--echo # Load buffer pool
+SET GLOBAL innodb_buffer_pool_load_now=1;
+
+# Wait for for the load to complete
+let $wait_condition =
+ SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) load completed at '
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_load_status';
+-- source include/wait_condition.inc
+
+--echo
+--echo # Should be more than previous as we didn't overwrite our save file
+--replace_result $incomplete Previous_loaded
+--eval select count(*) > $incomplete as Loaded_more from information_schema.INNODB_BUFFER_PAGE WHERE PAGE_TYPE='BLOB' group by PAGE_TYPE;
+
+--echo
+--echo # Successful, so innodb_buffer_pool_load_incomplete should be FALSE
+SELECT variable_name, SUBSTR(variable_value, 1, 33) as VALUE
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) IN ('innodb_buffer_pool_load_incomplete','innodb_buffer_pool_load_status')
+ ORDER BY variable_name;
+
+--echo
+--echo # innodb_buffer_pool_dump_now=1 should reset the innodb_buffer_pool_load_incomplete status
+
+SET GLOBAL innodb_buffer_pool_dump_now=1;
+# Wait for for the dump to complete
+let $wait_condition =
+ SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at '
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
+-- source include/wait_condition.inc
+
+SELECT variable_name, SUBSTR(variable_value, 1, 33) as VALUE
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) IN ('innodb_buffer_pool_load_incomplete', 'innodb_buffer_pool_dump_status');
+
+--let $fulldump=`select count(*) as BLOB_PAGES from information_schema.INNODB_BUFFER_PAGE WHERE PAGE_TYPE='BLOB' group by PAGE_TYPE`
+
+--echo
+--echo # Restart server
+--source include/restart_mysqld.inc
+
+--echo
+--echo # Load buffer pool
+SET GLOBAL innodb_buffer_pool_load_now=1;
+
+# Wait for for the load to complete
+let $wait_condition =
+ SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) load completed at '
+ FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_load_status';
+-- source include/wait_condition.inc
+
+--echo
+--echo # Should be same amount
+--replace_result $fulldump Previously_dumped
+--eval select abs($fulldump - count(*)) <= 2 as Loaded_about_same_size from information_schema.INNODB_BUFFER_PAGE WHERE PAGE_TYPE='BLOB' group by PAGE_TYPE;
+
+--echo
+--echo # Clean up
+
+--remove_file $MYSQLTEST_VARDIR/mysqld.1/data/ib_buffer_pool
+DROP TABLE t1;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test
index 2ff03a53c42..68653d3a9a7 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test
@@ -6,7 +6,6 @@
#
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_enabled;
SET @start_global_value = @@global.rpl_semi_sync_master_enabled;
@@ -52,6 +51,35 @@ set global rpl_semi_sync_master_enabled=1e1;
--error ER_WRONG_VALUE_FOR_VAR
set global rpl_semi_sync_master_enabled="some text";
+#
+# Test conflicting concurrent setting
+#
+--let $val_saved= `SELECT @@global.rpl_semi_sync_master_enabled`
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+--let $iter=100
+--disable_query_log
+while ($iter)
+{
+ --connection con1
+ --send_eval SET @@global.rpl_semi_sync_master_enabled = $iter % 2
+
+ --connection con2
+ --send_eval SET @@global.rpl_semi_sync_master_enabled = ($iter + 1) % 2
+
+ --connection con1
+ reap;
+ --connection con2
+ reap;
+
+ --dec $iter
+}
+--enable_query_log
+disconnect con1;
+disconnect con2;
+
+--connection default
+--eval SET @@global.rpl_semi_sync_master_enabled = $val_saved
#
# Cleanup
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test
index 74d3c41150b..d312fa1c367 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test
@@ -5,7 +5,6 @@
# 2010-01-21 OBN - Added
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_timeout;
SET @start_global_value = @@global.rpl_semi_sync_master_timeout;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test
index c41b53fe5e6..3419254bafd 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test
@@ -5,7 +5,6 @@
# 2010-01-21 OBN - Added
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_trace_level;
SET @start_global_value = @@global.rpl_semi_sync_master_trace_level;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test
index d4a46a08140..60ca4425e5b 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test
@@ -6,7 +6,6 @@
#
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_wait_no_slave;
SET @start_global_value = @@global.rpl_semi_sync_master_wait_no_slave;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_point_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_point_basic.test
index 8125cf8d653..2f8cd8ec160 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_point_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_point_basic.test
@@ -1,5 +1,4 @@
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_wait_point;
SET @start_global_value = @@global.rpl_semi_sync_master_wait_point;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test
index c7ce371970d..71be941cbdc 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test
@@ -6,7 +6,6 @@
#
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_slave_enabled;
SET @start_global_value = @@global.rpl_semi_sync_slave_enabled;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test
index d7e001b7322..74b6ac0a6ae 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test
@@ -5,7 +5,6 @@
# 2010-01-21 OBN - Added
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_slave_trace_level;
SET @start_global_value = @@global.rpl_semi_sync_slave_trace_level;
diff --git a/mysql-test/suite/sys_vars/t/slave_transaction_retry_errors-master.opt b/mysql-test/suite/sys_vars/t/slave_transaction_retry_errors-master.opt
new file mode 100644
index 00000000000..a93f9f02f70
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/slave_transaction_retry_errors-master.opt
@@ -0,0 +1 @@
+--slave_transaction_retry_errors="10,20, 5000, 400"
diff --git a/mysql-test/suite/sys_vars/t/slave_transaction_retry_errors.test b/mysql-test/suite/sys_vars/t/slave_transaction_retry_errors.test
new file mode 100644
index 00000000000..aa2299cf815
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/slave_transaction_retry_errors.test
@@ -0,0 +1,19 @@
+--source include/not_embedded.inc
+#
+# only global
+#
+select @@global.slave_transaction_retry_errors;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.slave_transaction_retry_errors;
+show global variables like 'slave_transaction_retry_errors';
+show session variables like 'slave_transaction_retry_errors';
+select * from information_schema.global_variables where variable_name='slave_transaction_retry_errors';
+select * from information_schema.session_variables where variable_name='slave_transaction_retry_errors';
+
+#
+# show that it's read-only
+#
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set global slave_transaction_retry_errors=1;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set session slave_transaction_retry_errors=1;
diff --git a/mysql-test/suite/sys_vars/t/slave_transaction_retry_interval_basic.test b/mysql-test/suite/sys_vars/t/slave_transaction_retry_interval_basic.test
new file mode 100644
index 00000000000..4d8d55901d1
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/slave_transaction_retry_interval_basic.test
@@ -0,0 +1,190 @@
+--source include/not_embedded.inc
+#
+# only global
+#
+####### mysql-test\t\slave_transaction_retry_interval_basic.test ##############
+# #
+# Variable Name: slave_transaction_retry_interval #
+# Scope: GLOBAL #
+# Access Type: Dynamic #
+# Data Type: numeric #
+# Default Value: 10 #
+# Range: #
+# #
+# #
+# Creation Date: 2008-02-07 #
+# Author: Rizwan #
+# #
+# Description: Test Cases of Dynamic System Variable #
+# slave_transaction_retry_interval #
+# that checks the behavior of this variable in the following ways#
+# * Default Value #
+# * Valid & Invalid values #
+# * Scope & Access method #
+# * Data Integrity #
+# #
+# Reference: http://dev.mysql.com/doc/refman/5.1/en/ #
+# server-system-variables.html #
+# #
+###############################################################################
+
+--source include/not_embedded.inc
+--source include/load_sysvars.inc
+
+###################################################################
+# START OF slave_transaction_retry_interval TESTS #
+###################################################################
+
+
+#############################################################
+# Save initial value #
+#############################################################
+
+SET @start_global_value = @@global.slave_transaction_retry_interval;
+SELECT @start_global_value;
+
+--echo '#--------------------FN_DYNVARS_149_01-------------------------#'
+###################################################################
+# Display the DEFAULT value of slave_transaction_retry_interval #
+###################################################################
+
+SET @@global.slave_transaction_retry_interval = 50;
+SET @@global.slave_transaction_retry_interval = DEFAULT;
+SELECT @@global.slave_transaction_retry_interval;
+
+--echo '#--------------------FN_DYNVARS_149_02-------------------------#'
+###################################################################
+# Check the DEFAULT value of slave_transaction_retry_interval #
+###################################################################
+
+SET @@global.slave_transaction_retry_interval = DEFAULT;
+SELECT @@global.slave_transaction_retry_interval = 10;
+
+--echo '#--------------------FN_DYNVARS_149_03-------------------------#'
+###############################################################################
+# Change the value of slave_transaction_retry_interval to a valid value for
+# GLOBAL Scope
+###############################################################################
+
+SET @@global.slave_transaction_retry_interval = 0;
+SELECT @@global.slave_transaction_retry_interval;
+SET @@global.slave_transaction_retry_interval = 1;
+SELECT @@global.slave_transaction_retry_interval;
+SET @@global.slave_transaction_retry_interval = 15;
+SELECT @@global.slave_transaction_retry_interval;
+SET @@global.slave_transaction_retry_interval = 1024;
+SELECT @@global.slave_transaction_retry_interval;
+SET @@global.slave_transaction_retry_interval = 2147483648;
+SELECT @@global.slave_transaction_retry_interval;
+SET @@global.slave_transaction_retry_interval = 2147483648*2-1;
+SELECT @@global.slave_transaction_retry_interval;
+SET @@global.slave_transaction_retry_interval = 2147483649*2;
+SELECT @@global.slave_transaction_retry_interval;
+SET @@global.slave_transaction_retry_interval = 4294967295;
+SELECT @@global.slave_transaction_retry_interval;
+
+--echo '#--------------------FN_DYNVARS_149_04-------------------------#'
+##############################################################################
+# Check if variable can be access with session scope #
+##############################################################################
+
+--Error ER_GLOBAL_VARIABLE
+SET @@slave_transaction_retry_interval = 2;
+
+--Error ER_GLOBAL_VARIABLE
+SET @@session.slave_transaction_retry_interval = 3;
+
+--Error ER_GLOBAL_VARIABLE
+SET @@local.slave_transaction_retry_interval = 4;
+
+
+--echo '#------------------FN_DYNVARS_149_05-----------------------#'
+############################################################################
+# Change the value of slave_transaction_retry_interval to an invalid value #
+############################################################################
+
+SET @@global.slave_transaction_retry_interval = -1;
+SELECT @@global.slave_transaction_retry_interval;
+
+SET @@global.slave_transaction_retry_interval = 2147483649*2147483649;
+SELECT @@global.slave_transaction_retry_interval;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.slave_transaction_retry_interval = 65530.34;
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.slave_transaction_retry_interval = '100';
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.slave_transaction_retry_interval = 7483649.56;
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.slave_transaction_retry_interval = ON;
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.slave_transaction_retry_interval = OFF;
+
+--echo '#------------------FN_DYNVARS_149_06-----------------------#'
+####################################################################
+# Check if the value in GLOBAL Table matches value in variable #
+####################################################################
+
+SET @@global.slave_transaction_retry_interval = 3000;
+SELECT @@global.slave_transaction_retry_interval = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='slave_transaction_retry_interval';
+
+
+--echo '#------------------FN_DYNVARS_149_07-----------------------#'
+###########################################################################
+# Check if the value is present in INFORMATION_SCHEMA.SESSION_VARIABLES #
+###########################################################################
+
+SELECT count(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='slave_transaction_retry_interval';
+
+
+--echo '#------------------FN_DYNVARS_149_08-----------------------#'
+####################################################################
+# Check if TRUE and FALSE values can be used on variable #
+####################################################################
+
+SET @@global.slave_transaction_retry_interval = TRUE;
+SELECT @@global.slave_transaction_retry_interval;
+SET @@global.slave_transaction_retry_interval = FALSE;
+SELECT @@global.slave_transaction_retry_interval;
+
+
+--echo '#---------------------FN_DYNVARS_149_09----------------------#'
+###############################################################################
+# Check if accessing variable with and without GLOBAL point to same variable #
+###############################################################################
+
+
+SET @@global.slave_transaction_retry_interval = 60*60;
+SELECT @@slave_transaction_retry_interval = @@global.slave_transaction_retry_interval;
+
+
+--echo '#---------------------FN_DYNVARS_149_10----------------------#'
+###############################################################################
+# Check if slave_transaction_retry_interval can be accessed without @@ sign
+# and scope
+###############################################################################
+
+--Error ER_GLOBAL_VARIABLE
+SET slave_transaction_retry_interval = 2048;
+--Error ER_BAD_FIELD_ERROR
+SELECT slave_transaction_retry_interval;
+
+SELECT @@slave_transaction_retry_interval;
+
+#verifying another another syntax for setting value
+SET global slave_transaction_retry_interval = 99;
+
+####################################
+# Restore initial value #
+####################################
+
+SET @@global.slave_transaction_retry_interval = @start_global_value;
+SELECT @@global.slave_transaction_retry_interval;
+
+########################################################
+# END OF slave_transaction_retry_interval TESTS #
+########################################################
diff --git a/mysql-test/suite/sys_vars/t/sql_mode_basic.test b/mysql-test/suite/sys_vars/t/sql_mode_basic.test
index 1730af50c17..b4841ecd3ff 100644
--- a/mysql-test/suite/sys_vars/t/sql_mode_basic.test
+++ b/mysql-test/suite/sys_vars/t/sql_mode_basic.test
@@ -307,11 +307,11 @@ SELECT @@global.sql_mode;
SET @@global.sql_mode = 500000;
SELECT @@global.sql_mode;
-SET @@global.sql_mode = 8589934591;
+SET @@global.sql_mode = 17179869183;
SELECT @@global.sql_mode;
--Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.sql_mode = 8589934592;
+SET @@global.sql_mode = 17179869184;
# use of decimal values
diff --git a/mysql-test/suite/sys_vars/t/sysvars_debug.test b/mysql-test/suite/sys_vars/t/sysvars_debug.test
index fbdcbd683df..71d396e2df3 100644
--- a/mysql-test/suite/sys_vars/t/sysvars_debug.test
+++ b/mysql-test/suite/sys_vars/t/sysvars_debug.test
@@ -4,4 +4,5 @@
--vertical_results
select * from information_schema.system_variables
where variable_name like 'debug%'
+ or variable_name = 'in_predicate_conversion_threshold'
order by variable_name;
diff --git a/mysql-test/suite/sys_vars/t/sysvars_innodb.test b/mysql-test/suite/sys_vars/t/sysvars_innodb.test
index 2abafda34c6..fe91835eac5 100644
--- a/mysql-test/suite/sys_vars/t/sysvars_innodb.test
+++ b/mysql-test/suite/sys_vars/t/sysvars_innodb.test
@@ -16,5 +16,6 @@ select * from information_schema.system_variables
'innodb_disallow_writes', # only available WITH_WSREP
'innodb_numa_interleave', # only available WITH_NUMA
'innodb_sched_priority_cleaner', # linux only
- 'innodb_use_native_aio') # default value depends on OS
+ 'innodb_use_native_aio', # default value depends on OS
+ 'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing
order by variable_name;
diff --git a/mysql-test/suite/sys_vars/t/wsrep_on_basic.opt b/mysql-test/suite/sys_vars/t/wsrep_on_basic.opt
new file mode 100644
index 00000000000..aa1fb6cb155
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/wsrep_on_basic.opt
@@ -0,0 +1 @@
+--innodb-lock-schedule-algorithm=FCFS
diff --git a/mysql-test/suite/unit/suite.pm b/mysql-test/suite/unit/suite.pm
index 4a46272f041..c92363a8601 100644
--- a/mysql-test/suite/unit/suite.pm
+++ b/mysql-test/suite/unit/suite.pm
@@ -40,8 +40,8 @@ sub start_test {
my $bin=$ENV{MTR_BINDIR} || '..';
return "Not run for embedded server" if $::opt_embedded_server;
return "Not configured to run ctest" unless -f "$bin/CTestTestfile.cmake";
- my ($ctest_vs)= $opt_vs_config ? "--build-config $opt_vs_config" : "";
- my (@ctest_list)= `cd "$bin" && ctest $opt_vs_config --show-only --verbose`;
+ my ($ctest_vs)= $opt_vs_config ? "-C $opt_vs_config" : "";
+ my (@ctest_list)= `cd "$bin" && ctest $ctest_vs --show-only --verbose`;
return "No ctest" if $?;
my ($command, %tests, $prefix);
@@ -51,7 +51,9 @@ sub start_test {
$command= $';
$prefix= /libmariadb/ ? 'conc_' : '';
} elsif (/^ +Test +#\d+: +/) {
- $tests{$prefix.$'}=$command;
+ if ($command ne "NOT_AVAILABLE") {
+ $tests{$prefix.$'}=$command;
+ }
}
}
bless { ctests => { %tests } };
diff --git a/mysql-test/suite/vcol/r/range.result b/mysql-test/suite/vcol/r/range.result
index ad7a39bc11c..5b081a5dbe8 100644
--- a/mysql-test/suite/vcol/r/range.result
+++ b/mysql-test/suite/vcol/r/range.result
@@ -4,6 +4,6 @@ create table t2 (a int, b int) engine=myisam;
insert into t2 values (1,2),(2,4);
select * from t1 inner join t2 on ( t2.b = t1.v or t2.a = t1.pk );
pk i v a b
-1 1 0 1 2
-2 2 0 2 4
+1 1 2 1 2
+2 2 4 2 4
drop table t1, t2;
diff --git a/mysql-test/suite/versioning/common.inc b/mysql-test/suite/versioning/common.inc
new file mode 100644
index 00000000000..4324dd27cd8
--- /dev/null
+++ b/mysql-test/suite/versioning/common.inc
@@ -0,0 +1,80 @@
+--disable_query_log
+source include/have_innodb.inc;
+
+set @@session.time_zone='+00:00';
+select ifnull(max(transaction_id), 0) into @start_trx_id from mysql.transaction_registry;
+set @test_start=now(6);
+
+delimiter ~~;
+create procedure if not exists verify_vtq()
+begin
+ set @i= 0;
+ select
+ @i:= @i + 1 as No,
+ transaction_id > 0 as A,
+ commit_id > transaction_id as B,
+ begin_timestamp > @test_start as C,
+ commit_timestamp >= begin_timestamp as D
+ from mysql.transaction_registry
+ where transaction_id > @start_trx_id;
+ select ifnull(max(transaction_id), 0)
+ into @start_trx_id
+ from mysql.transaction_registry;
+end~~
+
+create function if not exists sys_commit_ts(sys_field varchar(255))
+returns varchar(255)
+deterministic
+begin
+ if @@default_storage_engine = 'InnoDB' then
+ return concat('vtq_commit_ts(', sys_field, ')');
+ elseif @@default_storage_engine = 'MyISAM' then
+ return sys_field;
+ end if;
+ return NULL;
+end~~
+
+create procedure if not exists verify_vtq_dummy(recs int)
+begin
+ declare i int default 1;
+ create temporary table tmp (No int, A bool, B bool, C bool, D bool);
+ while i <= recs do
+ insert into tmp values (i, 1, 1, 1, 1);
+ set i= i + 1;
+ end while;
+ select * from tmp;
+ drop table tmp;
+end~~
+
+create procedure concat_exec2(a varchar(255), b varchar(255))
+begin
+ prepare stmt from concat(a, b);
+ execute stmt;
+ deallocate prepare stmt;
+end~~
+
+create procedure concat_exec3(a varchar(255), b varchar(255), c varchar(255))
+begin
+ prepare stmt from concat(a, b, c);
+ execute stmt;
+ deallocate prepare stmt;
+end~~
+delimiter ;~~
+
+let $default_engine= `select @@default_storage_engine`;
+let $non_default_engine= `select if(@@default_storage_engine = 'InnoDB', 'MyISAM', 'InnoDB')`;
+let $sys_datatype_expl= timestamp(6);
+let $sys_datatype_expl_uc= TIMESTAMP(6);
+let $sys_datatype_max= TIMESTAMP'2038-01-19 03:14:07.999999';
+
+if ($MTR_COMBINATION_MYISAM)
+{
+ --let $MTR_COMBINATION_TIMESTAMP= 1
+}
+if ($MTR_COMBINATION_TRX_ID)
+{
+ let $sys_datatype_expl= bigint(20) unsigned;
+ let $sys_datatype_expl_uc= BIGINT(20) UNSIGNED;
+ let $sys_datatype_max= 18446744073709551615;
+}
+--enable_query_log
diff --git a/mysql-test/suite/versioning/common.opt b/mysql-test/suite/versioning/common.opt
new file mode 100644
index 00000000000..412290a7585
--- /dev/null
+++ b/mysql-test/suite/versioning/common.opt
@@ -0,0 +1 @@
+--plugin-load-add=test_versioning
diff --git a/mysql-test/suite/versioning/common_finish.inc b/mysql-test/suite/versioning/common_finish.inc
new file mode 100644
index 00000000000..6894267f353
--- /dev/null
+++ b/mysql-test/suite/versioning/common_finish.inc
@@ -0,0 +1,7 @@
+--disable_query_log
+drop procedure verify_vtq;
+drop procedure verify_vtq_dummy;
+drop function sys_commit_ts;
+drop procedure concat_exec2;
+drop procedure concat_exec3;
+--enable_query_log
diff --git a/mysql-test/suite/handler/disabled.def b/mysql-test/suite/versioning/disabled.def
index 888298bbb09..e0f1483d0ef 100644
--- a/mysql-test/suite/handler/disabled.def
+++ b/mysql-test/suite/versioning/disabled.def
@@ -9,3 +9,7 @@
# Do not use any TAB characters for whitespace.
#
##############################################################################
+ddl : DDL Survival WIP
+vtmd : DDL Survival WIP
+vtmd_show : DDL Survival WIP
+cte: MDEV-14820
diff --git a/mysql-test/suite/versioning/engines.combinations b/mysql-test/suite/versioning/engines.combinations
new file mode 100644
index 00000000000..561c5656929
--- /dev/null
+++ b/mysql-test/suite/versioning/engines.combinations
@@ -0,0 +1,8 @@
+[timestamp]
+default-storage-engine=innodb
+
+[trx_id]
+default-storage-engine=innodb
+
+[myisam]
+default-storage-engine=myisam
diff --git a/mysql-test/suite/versioning/engines.inc b/mysql-test/suite/versioning/engines.inc
new file mode 100644
index 00000000000..c841fece702
--- /dev/null
+++ b/mysql-test/suite/versioning/engines.inc
@@ -0,0 +1 @@
+--source include/have_innodb.inc
diff --git a/mysql-test/suite/versioning/key_type.combinations b/mysql-test/suite/versioning/key_type.combinations
new file mode 100644
index 00000000000..1929aee9a84
--- /dev/null
+++ b/mysql-test/suite/versioning/key_type.combinations
@@ -0,0 +1,2 @@
+[unique]
+[pk]
diff --git a/mysql-test/suite/versioning/key_type.inc b/mysql-test/suite/versioning/key_type.inc
new file mode 100644
index 00000000000..648430771cf
--- /dev/null
+++ b/mysql-test/suite/versioning/key_type.inc
@@ -0,0 +1,23 @@
+--disable_query_log
+if ($MTR_COMBINATION_UNIQUE)
+{
+ set @KEY_TYPE= 'unique';
+}
+if ($MTR_COMBINATION_PK)
+{
+ set @KEY_TYPE= 'primary key';
+}
+
+delimiter ~~;
+create procedure create_table(name varchar(255), cols varchar(255))
+begin
+ if (cols is null or cols = '') then
+ set cols= '';
+ else
+ set cols= concat(', ', cols);
+ end if;
+ set @str= concat('create or replace table ', name, '(id int ', @KEY_TYPE, cols, ') with system versioning');
+ prepare stmt from @str; execute stmt; drop prepare stmt;
+end~~
+delimiter ;~~
+--enable_query_log
diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result
new file mode 100644
index 00000000000..8693f24591c
--- /dev/null
+++ b/mysql-test/suite/versioning/r/alter.result
@@ -0,0 +1,521 @@
+select @@system_versioning_alter_history;
+@@system_versioning_alter_history
+ERROR
+create table t(
+a int
+);
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t drop system versioning;
+ERROR HY000: Table `t` is not system-versioned
+alter table t add system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t add column y int;
+ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER.
+alter table t engine innodb;
+ERROR HY000: Not allowed for system-versioned `test`.`t`. Change to/from native system versioning engine is prohibited.
+alter table t drop system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+set system_versioning_alter_history= keep;
+alter table t add system versioning;
+alter table t drop system versioning, drop column row_start;
+ERROR 42000: Can't DROP COLUMN `row_start`; check that it exists
+alter table t drop system versioning;
+alter table t
+add column trx_start bigint(20) unsigned as row start invisible,
+add column trx_end bigint(20) unsigned as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+ERROR HY000: `trx_start` must be of type TIMESTAMP(6) for system-versioned table `t`
+alter table t
+add column trx_start timestamp as row start invisible,
+add column trx_end timestamp as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+ERROR HY000: `trx_start` must be of type TIMESTAMP(6) for system-versioned table `t`
+alter table t
+add column trx_start timestamp(6) not null as row start invisible,
+add column trx_end timestamp(6) not null as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+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 'as row start invisible,
+add column trx_end timestamp(6) not null as row end invi' at line 2
+alter table t
+add column trx_start timestamp(6) as row start invisible,
+add column trx_end timestamp(6) as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `trx_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `trx_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`trx_start`, `trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t drop system versioning;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `trx_start`'
+alter table t drop column trx_start, drop column trx_end;
+select row_start from t;
+row_start
+alter table t drop system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t add column trx_start timestamp(6) as row start;
+ERROR HY000: Table `t` is not system-versioned
+alter table t add system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t add column b int;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t add column c int;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t add column d int first;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `d` int(11) DEFAULT NULL,
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t add column e int after d;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL,
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t drop column a;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create or replace table t (
+a int,
+row_start timestamp(6) as row start invisible,
+row_end timestamp(6) as row end invisible,
+period for system_time(row_start, row_end))
+with system versioning;
+select * from t for system_time all;
+a
+alter table t drop column row_start;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_end`'
+alter table t drop column row_end;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_start`'
+alter table t drop column row_start, drop column row_end;
+select * from t for system_time all;
+a
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t drop column row_start;
+ERROR 42000: Can't DROP COLUMN `row_start`; check that it exists
+alter table t drop column row_end;
+ERROR 42000: Can't DROP COLUMN `row_end`; check that it exists
+create or replace table t (
+a int,
+row_start timestamp(6) as row start invisible,
+row_end timestamp(6) as row end invisible,
+period for system_time(row_start, row_end))
+with system versioning;
+select * from t for system_time all;
+a
+alter table t drop column row_start, drop column row_end;
+select * from t for system_time all;
+a
+create or replace table t(
+a int
+);
+insert into t values(1);
+alter table t add system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+insert into t values(2);
+select * from t for system_time all;
+a
+1
+2
+select * from t;
+a
+1
+2
+update t set a=3 where a=1;
+select * from t;
+a
+3
+2
+select * from t for system_time all;
+a
+3
+2
+1
+select row_start from t where a=3 into @tm;
+alter table t add column b int;
+select @tm=row_start from t where a=3;
+@tm=row_start
+1
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+select * from t;
+a b
+3 NULL
+2 NULL
+select * from t for system_time all;
+a b
+3 NULL
+2 NULL
+1 NULL
+alter table t drop system versioning;
+select * from t;
+a b
+3 NULL
+2 NULL
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t modify a int with system versioning;
+ERROR HY000: Table `t` is not system-versioned
+alter table t modify a int without system versioning;
+ERROR HY000: Table `t` is not system-versioned
+alter table t add system versioning;
+alter table t modify a int without system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t modify a int with system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create or replace table t(
+a int
+) engine=innodb;
+alter table t
+add column trx_start timestamp(6) as row start invisible,
+add column trx_end timestamp(6) as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `trx_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `trx_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`trx_start`, `trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+# Issue #211: drop of system columns required before drop system versioning
+alter table t drop column trx_start, drop column trx_end;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t drop system versioning;
+insert into t values(1);
+call verify_vtq;
+No A B C D
+alter table t
+add column trx_start bigint(20) unsigned as row start invisible,
+add column trx_end bigint(20) unsigned as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+call verify_vtq;
+No A B C D
+1 1 1 1 1
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START INVISIBLE,
+ `trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`trx_start`, `trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t drop column trx_start, drop column trx_end;
+call verify_vtq;
+No A B C D
+alter table t drop system versioning, algorithm=copy;
+call verify_vtq;
+No A B C D
+alter table t add system versioning, algorithm=copy;
+call verify_vtq;
+No A B C D
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+update t set a= 2;
+select * from t for system_time all;
+a
+2
+1
+alter table t add column b int, algorithm=copy;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+select * from t;
+a b
+2 NULL
+call verify_vtq;
+No A B C D
+alter table t drop column b, algorithm=copy;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+select * from t for system_time all;
+a
+2
+1
+call verify_vtq;
+No A B C D
+alter table t drop system versioning, algorithm=copy;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+call verify_vtq;
+No A B C D
+create or replace table t (a int);
+insert t values (1),(2),(3),(4);
+alter table t add b int auto_increment null unique;
+select * from t;
+a b
+1 1
+2 2
+3 3
+4 4
+drop table t;
+create or replace table t (a int) with system versioning engine=innodb;
+insert into t values (1), (2), (3);
+delete from t where a<3;
+alter table t add b int not null unique;
+Got one of the listed errors
+alter table t add b int auto_increment unique;
+Got one of the listed errors
+alter table t add b int auto_increment null unique;
+select * from t;
+a b
+3 1
+select * from t for system_time all;
+a b
+1 NULL
+2 NULL
+3 1
+insert into t values (4, 0);
+select * from t for system_time all;
+a b
+1 NULL
+2 NULL
+3 1
+4 4
+create or replace table t (a int) with system versioning;
+insert into t values (1), (2), (3);
+delete from t where a<3;
+alter table t add b int not null unique;
+Got one of the listed errors
+alter table t add b int auto_increment unique;
+Got one of the listed errors
+alter table t add b int auto_increment null unique;
+select * from t;
+a b
+3 1
+select * from t for system_time all;
+a b
+1 NULL
+2 NULL
+3 1
+insert into t values (4, 0);
+select * from t for system_time all;
+a b
+1 NULL
+2 NULL
+3 1
+4 2
+create or replace table t (a int, b int primary key, c int unique) with system versioning;
+insert t values (1,2,3),(1,3,4),(1,4,5);
+alter table t drop system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) DEFAULT NULL,
+ PRIMARY KEY (`b`),
+ UNIQUE KEY `c` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t;
+a b c
+1 2 3
+1 3 4
+1 4 5
+create or replace table t (
+a int,
+row_start timestamp(6) as row start invisible,
+row_end timestamp(6) as row end invisible,
+period for system_time(row_start, row_end)
+) with system versioning;
+alter table t change column row_start asdf timestamp(6);
+ERROR HY000: Can not change system versioning field `row_start`
+insert into t values (1);
+alter table t modify column row_start bigint unsigned;
+ERROR HY000: Can not change system versioning field `row_start`
+set system_versioning_alter_history= SURVIVE;
+ERROR 42000: Variable 'system_versioning_alter_history' can't be set to the value of 'SURVIVE'
+set system_versioning_alter_history= 'DROP';
+ERROR 42000: Variable 'system_versioning_alter_history' can't be set to the value of 'DROP'
+create or replace table t (a int) with system versioning;
+alter table t add system versioning;
+ERROR HY000: Table `t` is already system-versioned
+alter table t add system versioning, drop system versioning;
+ERROR HY000: Table `t` is already system-versioned
+set @@system_versioning_alter_history=keep;
+create or replace table t(x int, y int) with system versioning engine=innodb;
+alter table t modify y int without system versioning;
+insert into t values(1, 1);
+update t set y=2;
+# MDEV-14681 Bogus ER_UNSUPPORTED_EXTENSION
+create or replace table t1 (pk int auto_increment unique) with system versioning;
+insert into t1 values (1);
+delete from t1;
+alter table t1 engine=myisam;
+# MDEV-14692 crash in MDL_context::upgrade_shared_lock()
+create or replace temporary table t (a int);
+alter table t change column if exists b c bigint unsigned generated always as row start;
+ERROR HY000: System versioning prohibited for TEMPORARY tables
+alter table t change column if exists b c bigint unsigned generated always as row end;
+ERROR HY000: System versioning prohibited for TEMPORARY tables
+alter table t add system versioning;
+ERROR HY000: System versioning prohibited for TEMPORARY tables
+drop table t;
+# MDEV-14744 trx_id-based and transaction-based mixup in assertion
+create or replace table t (c text) engine=innodb with system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `c` text DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t add fulltext key (c);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+create or replace table t (a int) with system versioning;
+alter table t drop column a;
+ERROR HY000: Table `t` must have at least one versioned column
+alter table t drop column a, drop column a;
+ERROR 42000: Can't DROP COLUMN `a`; check that it exists
+create or replace table t1 (row_start int);
+alter table t1 with system versioning;
+ERROR 42S21: Duplicate column name 'row_start'
+create or replace table t1 (row_end int);
+alter table t1 with system versioning;
+ERROR 42S21: Duplicate column name 'row_end'
+create or replace table t1 (a int, row_start int) with system versioning;
+ERROR 42S21: Duplicate column name 'row_start'
+create or replace table t1 (a int) with system versioning;
+set statement system_versioning_alter_history=keep for
+alter table t1 add column row_start int;
+ERROR 42S21: Duplicate column name 'row_start'
+set statement system_versioning_alter_history=keep for
+alter table t1 add column row_start timestamp(6);
+ERROR 42S21: Duplicate column name 'row_start'
+# MDEV-14798 Add, drop system versioning semantic and syntax
+create or replace table t (
+a int,
+row_start timestamp(6) generated always as row start,
+row_end timestamp(6) generated always as row end,
+period for system_time(row_start, row_end)
+) with system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+alter table t
+drop column row_start,
+drop column row_end,
+drop period for system_time,
+drop system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t drop period for system_time;
+ERROR HY000: Table `t` is not system-versioned
+create or replace table t (
+a int,
+row_start timestamp(6) generated always as row start,
+row_end timestamp(6) generated always as row end,
+period for system_time(row_start, row_end)
+) with system versioning;
+alter table t drop period for system_time;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_start`, DROP COLUMN `row_end`'
+alter table t drop column sys_trx_start, drop period for system_time;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_start`, DROP COLUMN `row_end`'
+alter table t drop column sys_trx_end, drop period for system_time;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_start`, DROP COLUMN `row_end`'
+alter table t add period for system_time(sys_trx_start, sys_trx_end);
+ERROR HY000: Table `t` is already system-versioned
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/r/auto_increment.result b/mysql-test/suite/versioning/r/auto_increment.result
new file mode 100644
index 00000000000..8ff1bed8fe3
--- /dev/null
+++ b/mysql-test/suite/versioning/r/auto_increment.result
@@ -0,0 +1,65 @@
+create table t1(
+id int unsigned auto_increment primary key,
+x int unsigned,
+y int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning;
+create table t2(
+id int unsigned auto_increment primary key,
+x int unsigned,
+y int unsigned);
+insert into t1(x, y) values(1, 11);
+insert into t2(x, y) values(1, 11);
+insert into t1(x, y) values(2, 12);
+insert into t2(x, y) values(2, 12);
+insert into t1(x, y) values(3, 13);
+insert into t2(x, y) values(3, 13);
+insert into t1(x, y) values(4, 14);
+insert into t2(x, y) values(4, 14);
+insert into t1(x, y) values(5, 15);
+insert into t2(x, y) values(5, 15);
+insert into t1(x, y) values(6, 16);
+insert into t2(x, y) values(6, 16);
+insert into t1(x, y) values(7, 17);
+insert into t2(x, y) values(7, 17);
+insert into t1(x, y) values(8, 18);
+insert into t2(x, y) values(8, 18);
+insert into t1(x, y) values(9, 19);
+insert into t2(x, y) values(9, 19);
+select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id;
+A x y x y
+1 1 11 1 11
+1 2 12 2 12
+1 3 13 3 13
+1 4 14 4 14
+1 5 15 5 15
+1 6 16 6 16
+1 7 17 7 17
+1 8 18 8 18
+1 9 19 9 19
+delete from t1 where x = 2;
+delete from t2 where x = 2;
+select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id;
+A x y x y
+1 1 11 1 11
+1 3 13 3 13
+1 4 14 4 14
+1 5 15 5 15
+1 6 16 6 16
+1 7 17 7 17
+1 8 18 8 18
+1 9 19 9 19
+delete from t1 where x > 7;
+delete from t2 where x > 7;
+select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id;
+A x y x y
+1 1 11 1 11
+1 3 13 3 13
+1 4 14 4 14
+1 5 15 5 15
+1 6 16 6 16
+1 7 17 7 17
+drop table t1;
+drop table t2;
diff --git a/mysql-test/suite/versioning/r/commit_id.result b/mysql-test/suite/versioning/r/commit_id.result
new file mode 100644
index 00000000000..1f4c1344f7d
--- /dev/null
+++ b/mysql-test/suite/versioning/r/commit_id.result
@@ -0,0 +1,100 @@
+create table t1(
+id int auto_increment primary key,
+sys_trx_start bigint unsigned as row start invisible,
+sys_trx_end bigint unsigned as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end)
+)
+with system versioning
+engine innodb;
+insert into t1 values ();
+set @ts0= now(6);
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx0;
+select transaction_id = @tx0 from mysql.transaction_registry
+order by transaction_id desc limit 1;
+transaction_id = @tx0
+1
+set @ts1= now(6);
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx1;
+select transaction_id = @tx1 from mysql.transaction_registry
+order by transaction_id desc limit 1;
+transaction_id = @tx1
+1
+set @ts2= now(6);
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx2;
+select transaction_id = @tx2 from mysql.transaction_registry
+order by transaction_id desc limit 1;
+transaction_id = @tx2
+1
+set @ts3= now(6);
+select
+vtq_trx_id(@ts0) < @tx0 as A,
+vtq_trx_id(@ts0, true) = @tx0 as B,
+vtq_trx_id(@ts1) = @tx0 as C,
+vtq_trx_id(@ts1, true) = @tx1 as D,
+vtq_trx_id(@ts2) = @tx1 as E,
+vtq_trx_id(@ts2, true) = @tx2 as F,
+vtq_trx_id(@ts3) = @tx2 as G,
+vtq_trx_id(@ts3, true) is null as H;
+A B C D E F G H
+1 1 1 1 1 1 1 1
+select
+vtq_commit_id(@ts0) < @tx0 as A,
+vtq_commit_id(@ts0, true) = vtq_commit_id(null, @tx0) as B,
+vtq_commit_id(@ts1) = vtq_commit_id(null, @tx0) as C,
+vtq_commit_id(@ts1, true) = vtq_commit_id(null, @tx1) as D,
+vtq_commit_id(@ts2) = vtq_commit_id(null, @tx1) as E,
+vtq_commit_id(@ts2, true) = vtq_commit_id(null, @tx2) as F,
+vtq_commit_id(@ts3) = vtq_commit_id(null, @tx2) as G,
+vtq_commit_id(@ts3, true) is null as H;
+A B C D E F G H
+1 1 1 1 1 1 1 1
+select
+vtq_trx_sees(@tx1, @tx0) as A,
+not vtq_trx_sees(@tx0, @tx1) as B,
+vtq_trx_sees_eq(@tx1, @tx1) as C,
+not vtq_trx_sees(@tx1, @tx1) as D,
+vtq_trx_sees(@tx2, 0) as E,
+vtq_trx_sees(-1, @tx2) as F;
+A B C D E F
+1 1 1 1 1 1
+select vtq_trx_sees(0, @tx2);
+vtq_trx_sees(0, @tx2)
+NULL
+set transaction isolation level read uncommitted;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx3;
+select isolation_level = 'READ-UNCOMMITTED' from mysql.transaction_registry where transaction_id = @tx3;
+isolation_level = 'READ-UNCOMMITTED'
+1
+set transaction isolation level read committed;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx4;
+select isolation_level = 'READ-COMMITTED' from mysql.transaction_registry where transaction_id = @tx4;
+isolation_level = 'READ-COMMITTED'
+1
+set transaction isolation level serializable;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx5;
+select isolation_level = 'SERIALIZABLE' from mysql.transaction_registry where transaction_id = @tx5;
+isolation_level = 'SERIALIZABLE'
+1
+set transaction isolation level repeatable read;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx6;
+select isolation_level = 'REPEATABLE-READ' from mysql.transaction_registry where transaction_id = @tx6;
+isolation_level = 'REPEATABLE-READ'
+1
+drop table t1;
+call verify_vtq;
+No A B C D
+1 1 1 1 1
+2 1 1 1 1
+3 1 1 1 1
+4 1 1 1 1
+5 1 1 1 1
+6 1 1 1 1
+7 1 1 1 1
+8 1 1 1 1
diff --git a/mysql-test/suite/versioning/r/create.result b/mysql-test/suite/versioning/r/create.result
new file mode 100644
index 00000000000..871ba3a928c
--- /dev/null
+++ b/mysql-test/suite/versioning/r/create.result
@@ -0,0 +1,470 @@
+drop table if exists t1;
+create table t1 (
+x1 int unsigned,
+Sys_start SYS_DATATYPE as row start invisible comment 'start',
+Sys_end SYS_DATATYPE as row end invisible comment 'end',
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x1` int(10) unsigned DEFAULT NULL,
+ `Sys_start` SYS_DATATYPE GENERATED ALWAYS AS ROW START INVISIBLE COMMENT 'start',
+ `Sys_end` SYS_DATATYPE GENERATED ALWAYS AS ROW END INVISIBLE COMMENT 'end',
+ PERIOD FOR SYSTEM_TIME (`Sys_start`, `Sys_end`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+select table_catalog,table_schema,table_name,table_type,version,table_rows,avg_row_length,data_free,auto_increment,check_time,table_collation,checksum,create_options,table_comment from information_schema.tables where table_name='t1';
+table_catalog def
+table_schema test
+table_name t1
+table_type SYSTEM VERSIONED
+version 10
+table_rows 0
+avg_row_length 0
+data_free 0
+auto_increment NULL
+check_time NULL
+table_collation latin1_swedish_ci
+checksum NULL
+create_options
+table_comment
+select table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,character_maximum_length,character_octet_length,character_set_name,collation_name,column_key,extra,column_comment,is_generated,generation_expression from information_schema.columns where table_name='t1';
+table_catalog def
+table_schema test
+table_name t1
+column_name x1
+ordinal_position 1
+column_default NULL
+character_maximum_length NULL
+character_octet_length NULL
+character_set_name NULL
+collation_name NULL
+column_key
+extra
+column_comment
+is_generated NEVER
+generation_expression NULL
+table_catalog def
+table_schema test
+table_name t1
+column_name Sys_start
+ordinal_position 2
+column_default NULL
+character_maximum_length NULL
+character_octet_length NULL
+character_set_name NULL
+collation_name NULL
+column_key
+extra INVISIBLE
+column_comment start
+is_generated ALWAYS
+generation_expression ROW START
+table_catalog def
+table_schema test
+table_name t1
+column_name Sys_end
+ordinal_position 3
+column_default NULL
+character_maximum_length NULL
+character_octet_length NULL
+character_set_name NULL
+collation_name NULL
+column_key
+extra INVISIBLE
+column_comment end
+is_generated ALWAYS
+generation_expression ROW END
+# Implicit fields test
+create or replace table t1 (
+x2 int unsigned
+) with system versioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x2` int(10) unsigned DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create or replace table t1 (
+x3 int unsigned,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (x, Sys_end)
+) with system versioning;
+ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end`
+create or replace table t1 (
+x4 int unsigned,
+Sys_start timestamp(6) as row start invisible,
+Sys_end2 timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end2`
+create or replace table t1 (
+x5 int unsigned,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, x)
+) with system versioning;
+ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end`
+create or replace table t1 (
+x6 int unsigned,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+ERROR HY000: Wrong parameters for `t1`: missing 'AS ROW START'
+create or replace table t1 (
+x7 int unsigned,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_end)
+);
+ERROR HY000: Wrong parameters for `t1`: missing 'WITH SYSTEM VERSIONING'
+create or replace table t1 (
+x8 int unsigned,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (sys_insert, sys_remove)
+) with system versioning;
+ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end`
+create or replace table t1 (
+x9 int unsigned,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_end)
+);
+ERROR HY000: Wrong parameters for `t1`: missing 'WITH SYSTEM VERSIONING'
+create or replace table t1 (
+x10 int unsigned,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_start)
+);
+ERROR HY000: Wrong parameters for `t1`: missing 'WITH SYSTEM VERSIONING'
+create or replace table t1 (
+x11 int unsigned,
+Sys_start bigint unsigned as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+Got one of the listed errors
+create or replace table t1 (
+x12 int unsigned,
+Sys_start timestamp(6) as row start invisible,
+Sys_end bigint unsigned as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+Got one of the listed errors
+create or replace table t1 (
+x13 int unsigned,
+Sys_start bigint as row start invisible,
+Sys_end bigint unsigned as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning engine innodb;
+ERROR HY000: `Sys_start` must be of type TIMESTAMP(6) for system-versioned table `t1`
+create or replace table t1 (
+x14 int unsigned,
+Sys_start bigint unsigned as row start invisible,
+Sys_end bigint as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning engine innodb;
+ERROR HY000: `Sys_end` must be of type BIGINT(20) UNSIGNED for system-versioned table `t1`
+create or replace table t1 (
+x15 int with system versioning,
+B int
+);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x15` int(11) DEFAULT NULL,
+ `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create or replace table t1 (
+x16 int with system versioning,
+B int
+) with system versioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x16` int(11) DEFAULT NULL,
+ `B` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create or replace table t1 (
+x17 int,
+B int without system versioning
+);
+create or replace table t1 (
+x18 int,
+B int without system versioning
+) with system versioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x18` int(11) DEFAULT NULL,
+ `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create or replace table t1 (
+x19 int with system versioning,
+B int without system versioning
+);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x19` int(11) DEFAULT NULL,
+ `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create or replace table t1 (
+x20 int with system versioning,
+B int without system versioning
+) with system versioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x20` int(11) DEFAULT NULL,
+ `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create or replace table t1 (
+x21 int without system versioning
+);
+create or replace table t1 (
+x22 int without system versioning
+) with system versioning;
+ERROR HY000: Table `t1` must have at least one versioned column
+create or replace table t1 (a int) with system versioning;
+create table tt1 like t1;
+show create table tt1;
+Table Create Table
+tt1 CREATE TABLE `tt1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+drop table tt1;
+create temporary table tt1 like t1;
+Warnings:
+Warning 1105 System versioning is stripped from temporary `test.tt1`
+# Temporary is stripped from versioning
+show create table tt1;
+Table Create Table
+tt1 CREATE TEMPORARY TABLE `tt1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+# CREATE TABLE ... SELECT
+create or replace table t1 (x23 int) with system versioning;
+create or replace table t0(
+y int,
+st timestamp(6) as row start,
+en timestamp(6) as row end,
+period for system_time (st, en)
+) with system versioning;
+## For non-versioned table:
+### 1. invisible fields are not included
+create or replace table t2 as select * from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x23` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+### 2. all visible fields are included
+create or replace table t3 as select * from t0;
+select * from t0;
+y st en
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `y` int(11) DEFAULT NULL,
+ `st` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
+ `en` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+## For versioned table
+insert into t1 values (1);
+select row_start from t1 into @row_start;
+insert into t0 (y) values (2);
+select st from t0 into @st;
+create or replace table t2 with system versioning as select * from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x23` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+#### invisible fields are not copied
+select * from t2;
+x23
+1
+select * from t2 where row_start <= @row_start;
+x23
+### 2. source table with visible system fields, target with invisible
+create or replace table t3 with system versioning as select * from t0;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `y` int(11) DEFAULT NULL,
+ `st` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
+ `en` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+select * from t3 where y > 2;
+y st en
+select y from t3 where st = @st and row_start > @st;
+y
+2
+### 3. source and target table with visible system fields
+create or replace table t3 (
+st timestamp(6) as row start invisible,
+en timestamp(6) as row end invisible,
+period for system_time (st, en)
+) with system versioning as select * from t0;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `y` int(11) DEFAULT NULL,
+ `st` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `en` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`st`, `en`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+select y from t3;
+y
+2
+select y from t3 where st = @st;
+y
+### 4. system fields not or wrongly selected
+create or replace table t3 with system versioning select x23 from t1;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `x23` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+select * from t3;
+x23
+1
+create or replace table t3 with system versioning select x23, row_start from t1;
+ERROR HY000: Wrong parameters for `t3`: missing 'AS ROW END'
+create or replace table t3 with system versioning select x23, row_end from t1;
+ERROR HY000: Wrong parameters for `t3`: missing 'AS ROW START'
+# Prepare checking for historical row
+delete from t1;
+select row_end from t1 for system_time all into @row_end;
+delete from t0;
+select en from t0 for system_time all into @en;
+## Combinations of versioned + non-versioned
+create or replace table t2 (y int);
+insert into t2 values (3);
+create or replace table t3 with system versioning select * from t1 for system_time all, t2;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `x23` int(11) DEFAULT NULL,
+ `y` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+select * from t3 for system_time all;
+x23 y
+1 3
+select * from t3 for system_time all where row_start = @row_start and row_end = @row_end;
+x23 y
+create or replace table t2 like t0;
+insert into t2 (y) values (1), (2);
+delete from t2 where y = 2;
+create or replace table t3 select * from t2 for system_time all;
+select st, en from t3 where y = 1 into @st, @en;
+select y from t2 for system_time all where st = @st and en = @en;
+y
+1
+select st, en from t3 where y = 2 into @st, @en;
+select y from t2 for system_time all where st = @st and en = @en;
+y
+2
+## Default engine detection
+create or replace table t1 (x25 int) with system versioning engine NON_DEFAULT_ENGINE;
+create or replace table t2
+as select x25, row_start, row_end from t1 for system_time all;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x25` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+create or replace table t2 with system versioning
+as select x25, row_start, row_end from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x25` int(11) DEFAULT NULL
+) ENGINE=NON_DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create or replace table t1 (
+x26 int,
+st bigint unsigned as row start,
+en bigint unsigned as row end,
+period for system_time (st, en)
+) with system versioning engine innodb;
+create or replace table t2 with system versioning engine myisam
+as select * from t1;
+ERROR HY000: `st` must be of type TIMESTAMP(6) for system-versioned table `t2`
+create or replace table t1 (x27 int, id int) with system versioning engine NON_DEFAULT_ENGINE;
+create or replace table t2 (b int, id int);
+create or replace table t3 with system versioning
+as select t2.b, t1.x27, t1.row_start, t1.row_end from t2 inner join t1 on t2.id=t1.id;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `b` int(11) DEFAULT NULL,
+ `x27` int(11) DEFAULT NULL
+) ENGINE=NON_DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+## Errors
+create or replace temporary table t (x28 int) with system versioning;
+ERROR HY000: System versioning prohibited for TEMPORARY tables
+create or replace table t1 (
+x29 int unsigned,
+Sys_start0 timestamp(6) as row start invisible,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+ERROR HY000: Duplicate ROW START column `Sys_start`
+create or replace table t1 (
+x29 int unsigned,
+Sys_end0 timestamp(6) as row end invisible,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+ERROR HY000: Duplicate ROW END column `Sys_end`
+## System fields detection
+create or replace table t1 (x30 int) with system versioning;
+create or replace table t2 (
+y int,
+st timestamp(6) as row start invisible,
+en timestamp(6) as row end invisible,
+period for system_time (st, en)
+) with system versioning;
+create or replace table t3
+as select x30, y, row_start, row_end, st, en from t1, t2;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `x30` int(11) DEFAULT NULL,
+ `y` int(11) DEFAULT NULL,
+ `st` timestamp(6) NOT NULL INVISIBLE DEFAULT '0000-00-00 00:00:00.000000',
+ `en` timestamp(6) NOT NULL INVISIBLE DEFAULT '0000-00-00 00:00:00.000000'
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+create or replace table t3 (
+y int,
+st timestamp(6) as row start invisible,
+en timestamp(6) as row end invisible,
+period for system_time (st, en)
+) with system versioning
+as select x30, y, row_start, row_end, st, en from t1, t2;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `x30` int(11) DEFAULT NULL,
+ `y` int(11) DEFAULT NULL,
+ `st` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `en` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`st`, `en`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+# MDEV-14828 Server crashes in JOIN::prepare / setup_fields on 2nd execution of PS [#437]
+create or replace table t1 (x int) with system versioning;
+prepare bad from 'create or replace table t2 with system versioning as select * from t1';
+execute bad;
+execute bad;
+execute bad;
+execute bad;
+execute bad;
+execute bad;
+execute bad;
+execute bad;
+# bad is good.
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/r/cte.result b/mysql-test/suite/versioning/r/cte.result
new file mode 100644
index 00000000000..fda5e086be2
--- /dev/null
+++ b/mysql-test/suite/versioning/r/cte.result
@@ -0,0 +1,118 @@
+set default_storage_engine=innodb;
+create or replace table dept (
+dept_id int(10) primary key,
+name varchar(100)
+)
+with system versioning;
+create or replace table emp (
+emp_id int(10) primary key,
+dept_id int(10) not null,
+name varchar(100) not null,
+mgr int(10),
+salary int(10) not null,
+constraint `dept-emp-fk`
+ foreign key (dept_id) references dept (dept_id)
+on delete cascade
+on update restrict,
+constraint `mgr-fk`
+ foreign key (mgr) references emp (emp_id)
+on delete restrict
+on update restrict
+)
+with system versioning;
+insert into dept (dept_id, name) values (10, "accounting");
+insert into emp (emp_id, name, salary, dept_id, mgr) values
+(1, "bill", 1000, 10, null),
+(20, "john", 500, 10, 1),
+(30, "jane", 750, 10,1 );
+select max(sys_trx_start) into @ts_1 from emp;
+update emp set mgr=30 where name ="john";
+select sys_trx_start into @ts_2 from emp where name="john";
+/* All report to 'Bill' */
+with recursive
+ancestors
+as
+(
+select e.emp_id, e.name, e.mgr, e.salary
+from emp for system_time as of timestamp @ts_1 as e
+where name = 'bill'
+ union
+select e.emp_id, e.name, e.mgr, e.salary
+from emp for system_time as of timestamp @ts_1 as e,
+ancestors as a
+where e.mgr = a.emp_id
+)
+select * from ancestors;
+emp_id name mgr salary
+1 bill NULL 1000
+20 john 1 500
+30 jane 1 750
+/* Expected 3 rows */
+with recursive
+ancestors
+as
+(
+select e.emp_id, e.name, e.mgr, e.salary
+from emp for system_time as of timestamp @ts_2 as e
+where name = 'bill'
+ union
+select e.emp_id, e.name, e.mgr, e.salary
+from emp for system_time as of timestamp @ts_2 as e,
+ancestors as a
+where e.mgr = a.emp_id
+)
+select * from ancestors;
+emp_id name mgr salary
+1 bill NULL 1000
+30 jane 1 750
+20 john 30 500
+create or replace table emp ( emp_id int, name varchar(127), mgr int) with system versioning;
+create or replace table addr ( emp_id int, address varchar(100)) with system versioning;
+insert emp values (1, 'bill', 0), (2, 'bill', 1), (3, 'kate', 1);
+insert addr values (1, 'Moscow'), (2, 'New York'), (3, 'London');
+set @ts=now(6);
+delete from emp;
+delete from addr;
+with recursive
+ancestors
+as
+(
+select e.emp_id, e.name, e.mgr
+from emp for system_time as of timestamp @ts as e
+where name = 'bill'
+ union
+select ee.emp_id, ee.name, ee.mgr
+from emp for system_time as of timestamp @ts as ee, ancestors as a
+where ee.mgr = a.emp_id
+)
+select * from ancestors;
+emp_id name mgr
+1 bill 0
+2 bill 1
+3 kate 1
+insert emp values (4, 'john', 1);
+insert addr values (4, 'Paris');
+with ancestors as (select * from emp natural join addr) select * from ancestors;
+emp_id name mgr address
+4 john 1 Paris
+with ancestors as (select * from emp natural join addr) select * from ancestors for system_time all;
+emp_id name mgr address
+1 bill 0 Moscow
+2 bill 1 New York
+3 kate 1 London
+4 john 1 Paris
+with ancestors as (select * from (select * from emp natural join addr) for system_time all as t) select * from ancestors;
+emp_id name mgr address
+1 bill 0 Moscow
+2 bill 1 New York
+3 kate 1 London
+4 john 1 Paris
+select * from (select * from emp natural join addr) for system_time all as t;
+emp_id name mgr address
+1 bill 0 Moscow
+2 bill 1 New York
+3 kate 1 London
+4 john 1 Paris
+drop table emp;
+drop table dept;
+drop table addr;
diff --git a/mysql-test/suite/versioning/r/ddl.result b/mysql-test/suite/versioning/r/ddl.result
new file mode 100644
index 00000000000..a4323b89ee1
--- /dev/null
+++ b/mysql-test/suite/versioning/r/ddl.result
@@ -0,0 +1,211 @@
+set @@session.time_zone='+00:00';
+select ifnull(max(transaction_id), 0) into @start_trx_id from mysql.transaction_registry;
+set @test_start=now(6);
+create procedure if not exists verify_vtq()
+begin
+set @i= 0;
+select
+@i:= @i + 1 as No,
+transaction_id > 0 as A,
+commit_id > transaction_id as B,
+begin_timestamp > @test_start as C,
+commit_timestamp >= begin_timestamp as D
+from mysql.transaction_registry
+where transaction_id > @start_trx_id;
+select ifnull(max(transaction_id), 0)
+into @start_trx_id
+from mysql.transaction_registry;
+end~~
+create function if not exists default_engine()
+returns varchar(255)
+deterministic
+begin
+declare e varchar(255);
+select lower(engine) from information_schema.engines where support='DEFAULT' into e;
+return e;
+end~~
+create function if not exists sys_datatype()
+returns varchar(255)
+deterministic
+begin
+if default_engine() = 'innodb' then
+return 'bigint unsigned';
+elseif default_engine() = 'myisam' then
+return 'timestamp(6)';
+end if;
+return NULL;
+end~~
+create function if not exists sys_commit_ts(sys_field varchar(255))
+returns varchar(255)
+deterministic
+begin
+if default_engine() = 'innodb' then
+return concat('vtq_commit_ts(', sys_field, ')');
+elseif default_engine() = 'myisam' then
+return sys_field;
+end if;
+return NULL;
+end~~
+create procedure if not exists innodb_verify_vtq(recs int)
+begin
+declare i int default 1;
+if default_engine() = 'innodb' then
+call verify_vtq;
+elseif default_engine() = 'myisam' then
+create temporary table tmp (No int, A bool, B bool, C bool, D bool);
+while i <= recs do
+insert into tmp values (i, 1, 1, 1, 1);
+set i= i + 1;
+end while;
+select * from tmp;
+drop table tmp;
+end if;
+end~~
+create procedure concat_exec2(a varchar(255), b varchar(255))
+begin
+prepare stmt from concat(a, b);
+execute stmt;
+deallocate prepare stmt;
+end~~
+create procedure concat_exec3(a varchar(255), b varchar(255), c varchar(255))
+begin
+prepare stmt from concat(a, b, c);
+execute stmt;
+deallocate prepare stmt;
+end~~
+create function get_archive_table_name()
+returns varchar(255)
+begin
+return (select archive_name from t_vtmd for system_time all where archive_name is not NULL
+order by start desc limit 1);
+end~~
+create procedure drop_last_archive()
+begin
+call concat_exec2('drop table ', get_archive_table_name());
+end~~
+set versioning_alter_history= survive;
+create or replace table t (a int) with system versioning;
+insert into t values (1);
+update t set a=2 where a=1;
+select sys_trx_start from t where a=2 into @tm;
+alter table t add column b int;
+select * from t;
+a b
+2 NULL
+call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
+a
+2
+1
+call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
+@tm=sys_trx_start
+1
+select @tm<sys_trx_start from t where a=2;
+@tm<sys_trx_start
+1
+select sys_trx_start from t where a=2 into @tm;
+call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
+@tm=sys_trx_end
+1
+call drop_last_archive();
+set versioning_alter_history= keep;
+drop table t_vtmd;
+drop table t;
+set versioning_alter_history= survive;
+create or replace table t (a int) with system versioning;
+insert into t values (1);
+update t set a=2 where a=1;
+select sys_trx_start from t where a=2 into @tm;
+alter table t add column b int;
+select * from t;
+a b
+2 NULL
+call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
+a
+2
+1
+call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
+@tm=sys_trx_start
+1
+select @tm<sys_trx_start from t where a=2;
+@tm<sys_trx_start
+1
+select sys_trx_start from t where a=2 into @tm;
+call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
+@tm=sys_trx_end
+1
+call drop_last_archive();
+set versioning_alter_history= keep;
+drop table t_vtmd;
+drop table t;
+set versioning_alter_history= survive;
+create or replace table t (a int) with system versioning engine innodb;
+insert into t values (1);
+update t set a=2 where a=1;
+select sys_trx_start from t where a=2 into @tm;
+alter table t add column b int;
+select * from t;
+a b
+2 NULL
+call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
+a
+2
+1
+call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
+@tm=sys_trx_start
+1
+select @tm<sys_trx_start from t where a=2;
+@tm<sys_trx_start
+1
+select sys_trx_start from t where a=2 into @tm;
+call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
+@tm=sys_trx_end
+1
+call drop_last_archive();
+set versioning_alter_history= keep;
+drop table t_vtmd;
+drop table t;
+set versioning_alter_history= survive;
+create or replace table t (a int) with system versioning engine innodb;
+insert into t values (1);
+update t set a=2 where a=1;
+alter table t add column b int, algorithm=inplace;
+set versioning_alter_history = keep;
+drop function get_archive_table_name;
+drop procedure drop_last_archive;
+select * from mysql.vtmd_template;
+start end name archive_name col_renames
+show create table mysql.vtmd_template;
+Table Create Table
+vtmd_template CREATE TABLE `vtmd_template` (
+ `start` bigint(20) unsigned GENERATED ALWAYS AS ROW START COMMENT 'TRX_ID of table lifetime start',
+ `end` bigint(20) unsigned GENERATED ALWAYS AS ROW END NOT NULL COMMENT 'TRX_ID of table lifetime end',
+ `name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT 'Table name during current lifetime period',
+ `archive_name` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'Name of archive table',
+ `col_renames` blob DEFAULT NULL COMMENT 'Column name mappings from previous lifetime',
+ PRIMARY KEY (`end`),
+ KEY `archive_name` (`archive_name`),
+ PERIOD FOR SYSTEM_TIME (`start`, `end`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0 WITH SYSTEM VERSIONING
+call verify_vtq;
+No A B C D
+1 1 1 1 1
+2 1 1 1 1
+3 1 1 1 1
+4 1 1 1 1
+5 1 1 1 1
+6 1 1 1 1
+7 1 1 1 1
+8 1 1 1 1
+9 1 1 1 1
+10 1 1 1 1
+11 1 1 1 1
+12 1 1 1 1
+drop table t;
+drop table t_vtmd;
+drop procedure verify_vtq;
+drop procedure innodb_verify_vtq;
+drop function default_engine;
+drop function sys_commit_ts;
+drop function sys_datatype;
+drop procedure concat_exec2;
+drop procedure concat_exec3;
diff --git a/mysql-test/suite/versioning/r/debug.result b/mysql-test/suite/versioning/r/debug.result
new file mode 100644
index 00000000000..406717f8b5d
--- /dev/null
+++ b/mysql-test/suite/versioning/r/debug.result
@@ -0,0 +1,54 @@
+create table t1 (a int);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+create temporary table tt1 (a int) with system versioning;
+ERROR HY000: System versioning prohibited for TEMPORARY tables
+set @old_dbug=@@global.debug_dbug;
+set global debug_dbug='+d,sysvers_force';
+create table t2 (a int);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create temporary table tt2 (a int) with system versioning;
+show create table tt2;
+Table Create Table
+tt2 CREATE TEMPORARY TABLE `tt2` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+connect con1, localhost, root;
+create table t3 (a int);
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create temporary table tt3 (a int) with system versioning;
+show create table tt3;
+Table Create Table
+tt3 CREATE TEMPORARY TABLE `tt3` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+disconnect con1;
+connection default;
+set debug_dbug='+d,sysvers_show';
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+create table t4 (a int);
+show create table t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `a` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+set global debug_dbug=@old_dbug;
+drop table t1, t2, t3, t4;
diff --git a/mysql-test/suite/versioning/r/delete.result b/mysql-test/suite/versioning/r/delete.result
new file mode 100644
index 00000000000..faf8bf6176f
--- /dev/null
+++ b/mysql-test/suite/versioning/r/delete.result
@@ -0,0 +1,119 @@
+create or replace table t1(
+XNo int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning;
+insert into t1(XNo) values(0);
+insert into t1(XNo) values(1);
+insert into t1(XNo) values(2);
+insert into t1(XNo) values(3);
+insert into t1(XNo) values(4);
+insert into t1(XNo) values(5);
+insert into t1(XNo) values(6);
+insert into t1(XNo) values(7);
+insert into t1(XNo) values(8);
+insert into t1(XNo) values(9);
+select XNo, sys_end < MAXVAL from t1 for system_time all;
+XNo sys_end < MAXVAL
+0 0
+1 0
+2 0
+3 0
+4 0
+5 0
+6 0
+7 0
+8 0
+9 0
+delete from t1 where XNo = 0;
+delete from t1 where XNo = 1;
+delete from t1 where XNo > 5;
+create view vt1 as select XNo from t1;
+select XNo as XNo_vt1 from vt1;
+XNo_vt1
+2
+3
+4
+5
+delete from vt1 where XNo = 3;
+select XNo as XNo_vt1 from vt1;
+XNo_vt1
+2
+4
+5
+drop view vt1;
+drop table t1;
+create or replace table t1(
+x int,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning;
+insert into t1(x) values (1);
+select sys_start into @sys_start from t1;
+delete from t1;
+select * from t1;
+x
+select x = 1 as A, sys_start = @sys_start as B, sys_end > sys_start as C from t1 for system_time all;
+A B C
+1 1 1
+drop table t1;
+create or replace table t1(
+x int,
+y int,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning;
+create or replace table t2 like t1;
+insert into t1(x, y) values (1, 1), (2, 2), (3, 3), (14, 4);
+insert into t2(x, y) values (11, 1), (12, 2), (13, 32), (14, 4);
+delete t1, t2 from t1 join t2 where t1.y = 3 and t2.y = 32;
+select x as t1_x from t1;
+t1_x
+1
+2
+14
+select x as t2_x from t2;
+t2_x
+11
+12
+14
+delete t1, t2 from t1 join t2 where t1.x = t2.x;
+select x as t1_x from t1;
+t1_x
+1
+2
+select x as t2_x from t2;
+t2_x
+11
+12
+select x as t1_x_all from t1 for system_time all;
+t1_x_all
+1
+2
+3
+14
+select x as t2_x_all from t2 for system_time all;
+t2_x_all
+11
+12
+13
+14
+drop table t1;
+drop table t2;
+# Basic + delete from view
+# Check sys_start, sys_end
+# Multi-delete
+# Update + delete
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+update t1 set x= 2;
+delete from t1;
+select x from t1 for system_time all;
+x
+2
+1
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/r/derived.result b/mysql-test/suite/versioning/r/derived.result
new file mode 100644
index 00000000000..0792093bbc4
--- /dev/null
+++ b/mysql-test/suite/versioning/r/derived.result
@@ -0,0 +1,295 @@
+create table emp
+(
+emp_id int,
+name varchar(127),
+mgr int
+) with system versioning;
+insert into emp values (1, 'bill', 0),
+(2, 'bill', 1),
+(3, 'kate', 1);
+set @ts=now(6);
+delete from emp;
+insert into emp values (4, 'john', 1);
+with ancestors as (select * from emp) select * from ancestors;
+emp_id name mgr
+4 john 1
+set @tmp= "with ancestors as (select * from emp) select * from ancestors";
+prepare stmt from @tmp;
+execute stmt;
+emp_id name mgr
+4 john 1
+drop prepare stmt;
+with ancestors as (select * from emp for system_time all) select * from ancestors;
+emp_id name mgr
+1 bill 0
+2 bill 1
+3 kate 1
+4 john 1
+set @tmp= "with ancestors as (select * from emp for system_time all) select * from ancestors";
+prepare stmt from @tmp;
+execute stmt;
+emp_id name mgr
+1 bill 0
+2 bill 1
+3 kate 1
+4 john 1
+drop prepare stmt;
+with recursive ancestors as (select * from emp) select * from ancestors;
+emp_id name mgr
+4 john 1
+set @tmp= "with recursive ancestors as (select * from emp) select * from ancestors";
+prepare stmt from @tmp;
+execute stmt;
+emp_id name mgr
+4 john 1
+drop prepare stmt;
+select emp_id from (select emp_id from emp where row_end>'2031-1-1') as tmp;
+emp_id
+4
+set @tmp= "select emp_id from (select emp_id from emp where row_end>'2031-1-1') as tmp";
+prepare stmt from @tmp;
+execute stmt;
+emp_id
+4
+drop prepare stmt;
+with recursive
+ancestors
+as
+(
+select e.emp_id, e.name, e.mgr
+from emp as e
+where name = 'john'
+ union
+select ee.emp_id, ee.name, ee.mgr
+from emp as ee, ancestors as a
+where ee.mgr = a.emp_id
+)
+select * from ancestors;
+emp_id name mgr
+4 john 1
+set @tmp= "
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr
+ from emp as e
+ where name = 'john'
+ union
+ select ee.emp_id, ee.name, ee.mgr
+ from emp as ee, ancestors as a
+ where ee.mgr = a.emp_id
+)
+select * from ancestors";
+prepare stmt from @tmp;
+execute stmt;
+emp_id name mgr
+4 john 1
+drop prepare stmt;
+with recursive
+ancestors
+as
+(
+select e.emp_id, e.name, e.mgr
+from emp for system_time as of timestamp @ts as e
+where name = 'bill'
+ union
+select ee.emp_id, ee.name, ee.mgr
+from emp for system_time as of timestamp @ts as ee,
+ancestors as a
+where ee.mgr = a.emp_id
+)
+select * from ancestors;
+emp_id name mgr
+1 bill 0
+2 bill 1
+3 kate 1
+set @tmp= "
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr
+ from emp for system_time as of timestamp @ts as e
+ where name = 'bill'
+ union
+ select ee.emp_id, ee.name, ee.mgr
+ from emp for system_time as of timestamp @ts as ee,
+ ancestors as a
+ where ee.mgr = a.emp_id
+)
+select * from ancestors";
+prepare stmt from @tmp;
+execute stmt;
+emp_id name mgr
+1 bill 0
+2 bill 1
+3 kate 1
+drop prepare stmt;
+drop table emp;
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int) with system versioning;
+insert into t1 values (1);
+set @t0= now(6);
+delete from t1;
+insert into t1 values (2);
+insert into t2 values (10);
+select * from (select *, t1.row_end, t1.row_end as endo from t1) as s0;
+x row_end endo
+2 # #
+select * from (select *, t1.row_end, t2.row_start from t1, t2) as s0;
+x y row_end row_start
+2 10 # #
+# SYSTEM_TIME propagation from inner to outer
+select * from (select * from t1 for system_time as of timestamp @t0, t2) as s0;
+x y
+1 10
+with s1 as (select * from t1 for system_time as of timestamp @t0, t2) select * from s1;
+x y
+1 10
+# leading table selection
+select * from (select *, t1.row_end from t2, t1 for system_time as of timestamp @t0) as s2;
+y x row_end
+10 1 #
+with s3 as (select *, t1.row_end from t2, t1 for system_time as of timestamp @t0) select * from s3;
+y x row_end
+10 1 #
+### VIEW instead of t1
+set @q= concat("create view vt1 as select * from t1 for system_time as of timestamp '", @t0, "'");
+prepare q from @q;
+execute q;
+drop prepare q;
+create view vt2 as select * from t1;
+# SYSTEM_TIME propagation from view
+select * from vt1;
+x
+1
+# SYSTEM_TIME propagation from inner to outer
+select * from (select * from vt1, t2) as s0;
+x y
+1 10
+### SYSTEM_TIME clash
+select * from (select * from t1 for system_time all) for system_time all as dt0;
+ERROR HY000: Table `dt0` is not system-versioned
+select * from vt1 for system_time all;
+ERROR HY000: Table `vt1` is not system-versioned
+with dt1 as (select * from t1 for system_time all)
+select * from dt1 for system_time all;
+ERROR HY000: Table `dt1` is not system-versioned
+### UNION
+set @t1= now(6);
+delete from t2;
+insert into t2 values (3);
+# SYSTEM_TIME is not propagated
+select x from t1 union
+select y from t2;
+x
+2
+3
+select x from t1 for system_time as of @t0 union
+select y from t2;
+x
+1
+3
+select x from t1 union
+select y from t2 for system_time as of @t1;
+x
+2
+10
+select x from t1 for system_time as of @t0 union
+select y from t2 for system_time as of @t1;
+x
+1
+10
+# LEFT/RIGHT JOIN
+create or replace table t1 (x int, y int) with system versioning;
+create or replace table t2 (x int, y int) with system versioning;
+insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
+insert into t2 values (1, 2), (2, 1), (3, 1);
+## Outer or inner SYSTEM_TIME produces same expression
+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`.`t1`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t1`.`row_start` <= <cache>(current_timestamp(6)) and `test`.`t2`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t2`.`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`.`t1`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t1`.`row_start` <= <cache>(current_timestamp(6)) and `test`.`t2`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t2`.`row_start` <= <cache>(current_timestamp(6))
+Fine result: queries A and B are equal.
+## LEFT JOIN: t1, t2 versioned
+select * from (
+select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2
+from t1 left join t2 on t1.x = t2.x)
+as derived;
+LJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+alter table t2 drop system versioning;
+## LEFT JOIN: t1 versioned
+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)
+as derived;
+LJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+alter table t1 drop system versioning;
+alter table t2 add system versioning;
+## LEFT JOIN: t2 versioned
+select * from (
+select t1.x as LJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2
+from t1 left join t2 on t1.x = t2.x)
+as derived;
+LJ3_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+alter table t1 add system versioning;
+## RIGHT JOIN: t1, t2 versioned
+select * from (
+select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2
+from t1 right join t2 on t1.x = t2.x)
+as derived;
+RJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+alter table t2 drop system versioning;
+## RIGHT JOIN: t1 versioned
+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)
+as derived;
+RJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+alter table t1 drop system versioning;
+alter table t2 add system versioning;
+## RIGHT JOIN: t2 versioned
+select * from (
+select t1.x as RJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2
+from t1 right join t2 on t1.x = t2.x)
+as derived;
+RJ3_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+drop table t1, t2;
+drop view vt1, vt2;
diff --git a/mysql-test/suite/versioning/r/foreign,trx_id.rdiff b/mysql-test/suite/versioning/r/foreign,trx_id.rdiff
new file mode 100644
index 00000000000..c2c66ed11e1
--- /dev/null
+++ b/mysql-test/suite/versioning/r/foreign,trx_id.rdiff
@@ -0,0 +1,166 @@
+--- suite/versioning/r/foreign.result
++++ suite/versioning/r/foreign,trx_id.reject
+@@ -6,8 +6,8 @@
+ ) engine innodb;
+ create table child(
+ parent_id int,
+-sys_start timestamp(6) as row start invisible,
+-sys_end timestamp(6) as row end invisible,
++sys_start bigint(20) unsigned as row start invisible,
++sys_end bigint(20) unsigned as row end invisible,
+ period for system_time(sys_start, sys_end),
+ foreign key(parent_id) references parent(id)
+ on delete restrict
+@@ -39,8 +39,8 @@
+ ) engine innodb;
+ create table child(
+ parent_id int(10) unsigned primary key,
+-sys_start timestamp(6) as row start invisible,
+-sys_end timestamp(6) as row end invisible,
++sys_start bigint(20) unsigned as row start invisible,
++sys_end bigint(20) unsigned as row end invisible,
+ period for system_time(sys_start, sys_end),
+ foreign key(parent_id) references parent(id)
+ ) engine innodb with system versioning;
+@@ -58,19 +58,39 @@
+ ) engine innodb;
+ create table child(
+ parent_id int,
+-sys_start timestamp(6) as row start invisible,
+-sys_end timestamp(6) as row end invisible,
++sys_start bigint(20) unsigned as row start invisible,
++sys_end bigint(20) unsigned as row end invisible,
+ period for system_time(sys_start, sys_end),
+ foreign key(parent_id) references parent(id)
+ on delete cascade
+ on update cascade
+ ) engine innodb with system versioning;
+-ERROR HY000: CASCADE is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
++insert into parent values(1);
++insert into child values(1);
++delete from parent where id = 1;
++delete from child where parent_id = 1;
++delete from parent where id = 1;
++select * from child;
++parent_id
++select * from child for system_time all;
++parent_id
++1
++insert into parent values(1);
++insert into child values(1);
++update parent set id = id + 1;
++select * from child;
++parent_id
++2
++select * from child for system_time all;
++parent_id
++1
++2
++drop table child;
+ drop table parent;
+ create or replace table parent (
+ id int primary key,
+-sys_start timestamp(6) as row start invisible,
+-sys_end timestamp(6) as row end invisible,
++sys_start bigint(20) unsigned as row start invisible,
++sys_end bigint(20) unsigned as row end invisible,
+ period for system_time(sys_start, sys_end)
+ ) with system versioning
+ engine innodb;
+@@ -97,8 +117,8 @@
+ create or replace table child (
+ id int primary key,
+ parent_id int not null,
+-row_start timestamp(6) as row start invisible,
+-row_end timestamp(6) as row end invisible,
++row_start bigint(20) unsigned as row start invisible,
++row_end bigint(20) unsigned as row end invisible,
+ period for system_time(row_start, row_end),
+ constraint `parent-fk`
+ foreign key (parent_id) references parent (id)
+@@ -106,7 +126,18 @@
+ on update restrict
+ ) with system versioning
+ engine innodb;
+-ERROR HY000: CASCADE is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
++insert into parent (id) values (3);
++insert into child (id, parent_id) values (3, 3);
++## FIXME: #415 update of foreign constraints is disabled
++delete from child;
++## FIXME END
++delete from parent;
++select * from child;
++id parent_id
++select *, row_start < row_end, row_end < MAXVAL from child for system_time all;
++id parent_id row_start < row_end row_end < MAXVAL
++3 3 1 1
++drop table child;
+ drop table parent;
+ #################
+ # Test SET NULL #
+@@ -116,22 +147,39 @@
+ ) engine innodb;
+ create table child(
+ parent_id int,
+-sys_start timestamp(6) as row start invisible,
+-sys_end timestamp(6) as row end invisible,
++sys_start bigint(20) unsigned as row start invisible,
++sys_end bigint(20) unsigned as row end invisible,
+ period for system_time(sys_start, sys_end),
+ foreign key(parent_id) references parent(id)
+ on delete set null
+ on update set null
+ ) engine innodb with system versioning;
+-ERROR HY000: SET NULL is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
++insert into parent values(1);
++insert into child values(1);
++delete from child;
++insert into child values(1);
++## FIXME: #415 update of foreign constraints is disabled
++delete from child where parent_id = 1;
++## FIXME END
++delete from parent where id = 1;
++select * from child;
++parent_id
++select * from child for system_time from timestamp 0 to timestamp now(6);
++parent_id
++1
++1
++delete from child;
++insert into parent values(1);
++insert into child values(1);
++drop table child;
+ drop table parent;
+ ###########################
+ # Parent table is foreign #
+ ###########################
+ create or replace table parent(
+ id int unique key,
+-sys_start timestamp(6) as row start invisible,
+-sys_end timestamp(6) as row end invisible,
++sys_start bigint(20) unsigned as row start invisible,
++sys_end bigint(20) unsigned as row end invisible,
+ period for system_time(sys_start, sys_end)
+ ) engine innodb with system versioning;
+ create or replace table child(
+@@ -162,16 +210,16 @@
+ create or replace table a (
+ cola int(10) primary key,
+ v_cola int(10) as (cola mod 10) virtual,
+-sys_start timestamp(6) as row start invisible,
+-sys_end timestamp(6) as row end invisible,
++sys_start bigint(20) unsigned as row start invisible,
++sys_end bigint(20) unsigned as row end invisible,
+ period for system_time(sys_start, sys_end)
+ ) engine=innodb with system versioning;
+ create index v_cola on a (v_cola);
+ create or replace table b(
+ cola int(10),
+ v_cola int(10),
+-sys_start timestamp(6) as row start invisible,
+-sys_end timestamp(6) as row end invisible,
++sys_start bigint(20) unsigned as row start invisible,
++sys_end bigint(20) unsigned as row end invisible,
+ period for system_time(sys_start, sys_end)
+ ) engine=innodb with system versioning;
+ alter table b add constraint `v_cola_fk`
diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result
new file mode 100644
index 00000000000..bb9042fff9f
--- /dev/null
+++ b/mysql-test/suite/versioning/r/foreign.result
@@ -0,0 +1,183 @@
+#################
+# Test RESTRICT #
+#################
+create table parent(
+id int unique key
+) engine innodb;
+create table child(
+parent_id int,
+sys_start timestamp(6) as row start invisible,
+sys_end timestamp(6) as row end invisible,
+period for system_time(sys_start, sys_end),
+foreign key(parent_id) references parent(id)
+on delete restrict
+on update restrict
+) engine innodb with system versioning;
+insert into parent values(1);
+insert into child values(1);
+delete from parent where id = 1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+delete from child where parent_id = 1;
+delete from parent where id = 1;
+insert into parent values(1);
+insert into child values(1);
+update parent set id=id+1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+delete from child;
+update parent set id=id+1;
+select * from child for system_time from timestamp 0 to timestamp now(6);
+parent_id
+1
+1
+drop table child;
+drop table parent;
+##############################################
+# Test when clustered index is a foreign key #
+##############################################
+create table parent(
+id int(10) unsigned unique key
+) engine innodb;
+create table child(
+parent_id int(10) unsigned primary key,
+sys_start timestamp(6) as row start invisible,
+sys_end timestamp(6) as row end invisible,
+period for system_time(sys_start, sys_end),
+foreign key(parent_id) references parent(id)
+) engine innodb with system versioning;
+insert into parent values(1);
+insert into child values(1);
+delete from parent where id = 1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+drop table child;
+drop table parent;
+################
+# Test CASCADE #
+################
+create table parent(
+id int unique key
+) engine innodb;
+create table child(
+parent_id int,
+sys_start timestamp(6) as row start invisible,
+sys_end timestamp(6) as row end invisible,
+period for system_time(sys_start, sys_end),
+foreign key(parent_id) references parent(id)
+on delete cascade
+on update cascade
+) engine innodb with system versioning;
+ERROR HY000: CASCADE is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
+drop table parent;
+create or replace table parent (
+id int primary key,
+sys_start timestamp(6) as row start invisible,
+sys_end timestamp(6) as row end invisible,
+period for system_time(sys_start, sys_end)
+) with system versioning
+engine innodb;
+create or replace table child (
+x int,
+parent_id int not null,
+constraint `parent-fk`
+ foreign key (parent_id) references parent (id)
+on delete cascade
+on update restrict
+)
+engine innodb;
+insert into parent (id) values (2);
+insert into child (x, parent_id) values (2, 2);
+delete from parent;
+select * from child;
+x parent_id
+drop table child;
+drop table parent;
+create or replace table parent (
+id int primary key
+)
+engine innodb;
+create or replace table child (
+id int primary key,
+parent_id int not null,
+row_start timestamp(6) as row start invisible,
+row_end timestamp(6) as row end invisible,
+period for system_time(row_start, row_end),
+constraint `parent-fk`
+ foreign key (parent_id) references parent (id)
+on delete cascade
+on update restrict
+) with system versioning
+engine innodb;
+ERROR HY000: CASCADE is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
+drop table parent;
+#################
+# Test SET NULL #
+#################
+create table parent(
+id int unique key
+) engine innodb;
+create table child(
+parent_id int,
+sys_start timestamp(6) as row start invisible,
+sys_end timestamp(6) as row end invisible,
+period for system_time(sys_start, sys_end),
+foreign key(parent_id) references parent(id)
+on delete set null
+on update set null
+) engine innodb with system versioning;
+ERROR HY000: SET NULL is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
+drop table parent;
+###########################
+# Parent table is foreign #
+###########################
+create or replace table parent(
+id int unique key,
+sys_start timestamp(6) as row start invisible,
+sys_end timestamp(6) as row end invisible,
+period for system_time(sys_start, sys_end)
+) engine innodb with system versioning;
+create or replace table child(
+parent_id int,
+foreign key(parent_id) references parent(id)
+) engine innodb;
+insert into parent values(1);
+insert into child values(1);
+delete from parent;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+update parent set id=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+delete from child;
+delete from parent;
+insert into child values(1);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+insert into parent values(1);
+insert into child values(1);
+delete from parent;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+update parent set id=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+drop table child;
+drop table parent;
+###################
+# crash on DELETE #
+###################
+create or replace table a (
+cola int(10) primary key,
+v_cola int(10) as (cola mod 10) virtual,
+sys_start timestamp(6) as row start invisible,
+sys_end timestamp(6) as row end invisible,
+period for system_time(sys_start, sys_end)
+) engine=innodb with system versioning;
+create index v_cola on a (v_cola);
+create or replace table b(
+cola int(10),
+v_cola int(10),
+sys_start timestamp(6) as row start invisible,
+sys_end timestamp(6) as row end invisible,
+period for system_time(sys_start, sys_end)
+) engine=innodb with system versioning;
+alter table b add constraint `v_cola_fk`
+foreign key (v_cola) references a (v_cola);
+insert into a(cola) values (12);
+insert into b(cola, v_cola) values (10,2);
+delete from a;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`b`, CONSTRAINT `v_cola_fk` FOREIGN KEY (`v_cola`) REFERENCES `a` (`v_cola`))
+drop table b, a;
diff --git a/mysql-test/suite/versioning/r/insert.result b/mysql-test/suite/versioning/r/insert.result
new file mode 100644
index 00000000000..01d829d3430
--- /dev/null
+++ b/mysql-test/suite/versioning/r/insert.result
@@ -0,0 +1,112 @@
+create or replace table t1(
+x int unsigned,
+y int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning;
+insert into t1(x, y) values(3, 4);
+insert into t1(x, y) values(2, 3);
+insert into t1 values(40, 33);
+select x, y, sys_end < MAXVAL from t1;
+x y sys_end < MAXVAL
+3 4 0
+2 3 0
+40 33 0
+create or replace table t1(
+id int unsigned auto_increment primary key,
+x int unsigned,
+y int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning;
+insert into t1(x, y) values(33, 44);
+insert into t1(id, x, y) values(20, 33, 44);
+insert into t1 values(40, 33, 44);
+select id, x, y, sys_end < MAXVAL from t1;
+id x y sys_end < MAXVAL
+1 33 44 0
+20 33 44 0
+40 33 44 0
+create or replace table t1(
+x int unsigned,
+y int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning;
+create view vt1_1 as select x, y from t1;
+insert into t1(x, y) values(8001, 9001);
+insert into vt1_1(x, y) values(1001, 2001);
+insert into vt1_1 values(1002, 2002);
+select x, y, sys_end < MAXVAL from t1;
+x y sys_end < MAXVAL
+8001 9001 0
+1001 2001 0
+1002 2002 0
+select x, y from vt1_1;
+x y
+8001 9001
+1001 2001
+1002 2002
+drop view vt1_1;
+create or replace table t1( id bigint primary key, a int, b int) with system versioning;
+insert into t1 values(1, 1, 1);
+select row_start, row_end from t1 into @sys_start, @sys_end;
+select id, a, b from t1;
+id a b
+1 1 1
+insert into t1 values(2, 2, 2);
+select id, a, b, row_start > @sys_start as C, row_end = @sys_end as D from t1 where id = 2;
+id a b C D
+2 2 2 1 1
+drop table t1;
+create or replace table t1(
+x int unsigned,
+y int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning;
+create or replace table t2 like t1;
+insert into t1(x, y) values (1, 1000), (2, 2000), (3, 3000), (4, 4000), (5, 5000), (6, 6000), (7, 7000), (8, 8000), (9, 9000);
+delete from t1 where x >= 1;
+insert into t1(x, y) values (1, 1001), (2, 2001), (3, 3001), (4, 4001), (5, 5001), (6, 6001);
+insert into t1(x, y, sys_start) values (7, 7001, DEFAULT);
+insert into t1(x, y, sys_end) values (8, 8001, DEFAULT);
+insert into t1(x, y, sys_start, sys_end) values (9, 9001, DEFAULT, DEFAULT);
+insert into t2 select x, y from t1 for system_time all;
+select x, y from t1;
+x y
+1 1001
+2 2001
+3 3001
+4 4001
+5 5001
+6 6001
+7 7001
+8 8001
+9 9001
+select x, y from t2;
+x y
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8000
+9 9000
+1 1001
+2 2001
+3 3001
+4 4001
+5 5001
+6 6001
+7 7001
+8 8001
+9 9001
+drop table t1;
+drop table t2;
diff --git a/mysql-test/suite/versioning/r/insert2.result b/mysql-test/suite/versioning/r/insert2.result
new file mode 100644
index 00000000000..1a8131130b1
--- /dev/null
+++ b/mysql-test/suite/versioning/r/insert2.result
@@ -0,0 +1,104 @@
+create table t1(
+x int unsigned,
+sys_start bigint unsigned as row start invisible,
+sys_end bigint unsigned as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning engine=innodb;
+create table t2(x int unsigned) engine=innodb;
+start transaction;
+insert into t1(x) values(1);
+commit;
+start transaction;
+insert into t2(x) values(1);
+savepoint a;
+insert into t1(x) values(1);
+rollback to a;
+commit;
+insert into t2(x) values (1);
+create or replace table t1 (
+x int,
+y int as (x) virtual,
+sys_trx_start bigint unsigned as row start invisible,
+sys_trx_end bigint unsigned as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end)
+) engine=innodb with system versioning;
+insert into t1 values (1, null);
+update t1 set x= x + 1;
+select x, y, sys_trx_end = 18446744073709551615 as current from t1 for system_time all;
+x y current
+2 2 1
+1 1 0
+create or replace table t1 (
+x int,
+row_start timestamp(6) as row start invisible,
+row_end timestamp(6) as row end invisible,
+period for system_time (row_start, row_end)
+) with system versioning;
+insert into t1 values (1), (2);
+insert into t1 (row_start) select row_end from t1;
+ERROR HY000: The value specified for generated column 'row_start' in table 't1' ignored
+set sql_mode='';
+insert into t1 (row_start, row_end) values (DEFAULT, 1);
+Warnings:
+Warning 1906 The value specified for generated column 'row_end' in table 't1' ignored
+set sql_mode=default;
+select @@sql_mode into @saved_mode;
+set sql_mode= '';
+insert into t1 (x, row_start, row_end) values (3, 4, 5);
+Warnings:
+Warning 1906 The value specified for generated column 'row_start' in table 't1' ignored
+Warning 1906 The value specified for generated column 'row_end' in table 't1' ignored
+set sql_mode= @saved_mode;
+insert into t1 (row_start, row_end) values (DEFAULT, DEFAULT);
+select * from t1;
+x
+1
+2
+NULL
+3
+NULL
+# MDEV-14792 INSERT without column list into table with explicit versioning columns produces bad data
+create or replace table t1 (
+i int,
+s timestamp(6) as row start,
+e timestamp(6) as row end,
+c varchar(8),
+period for system_time(s, e))
+with system versioning;
+insert into t1 values (1, null, null, 'foo');
+select i, c, e>TIMESTAMP'2038-01-01 00:00:00' AS current_row from t1;
+i c current_row
+1 foo 1
+drop table t1;
+drop table t2;
+set timestamp=1000000019;
+select now() < sysdate();
+now() < sysdate()
+1
+create table t1 (a int) with system versioning;
+insert t1 values (1);
+set @a=sysdate(6);
+select * from t1 for system_time as of now(6);
+a
+select * from t1 for system_time as of sysdate(6);
+a
+1
+update t1 set a=2;
+delete from t1;
+select *, row_start > @a, row_end > @a from t1 for system_time all;
+a row_start > @a row_end > @a
+1 0 1
+2 1 1
+#
+# MDEV-14871 Server crashes in fill_record / fill_record_n_invoke_before_triggers upon inserting into versioned table with trigger
+#
+create or replace table t1 (pk int primary key) with system versioning;
+create trigger tr before insert on t1 for each row select 1 into @a;
+insert into t1 values (1),(2);
+drop table t1;
+create table t1 (pk int primary key, i int) with system versioning;
+replace into t1 values (1,10),(1,100),(1,1000);
+select pk,i,row_end > '2038-01-01' from t1 for system_time all;
+pk i row_end > '2038-01-01'
+1 1000 1
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/load_data.result b/mysql-test/suite/versioning/r/load_data.result
new file mode 100644
index 00000000000..5e7b36c9a6a
--- /dev/null
+++ b/mysql-test/suite/versioning/r/load_data.result
@@ -0,0 +1,8 @@
+CREATE TABLE t1 (a INT, b INT, c INT, vc INT AS (c), UNIQUE(a), UNIQUE(b)) WITH SYSTEM VERSIONING;
+INSERT IGNORE INTO t1 (a,b,c) VALUES (1,2,3);
+SELECT a, b, c FROM t1 INTO OUTFILE '15330.data';
+LOAD DATA INFILE '15330.data' IGNORE INTO TABLE t1 (a,b,c);
+Warnings:
+Warning 1062 Duplicate entry '1' for key 'a'
+LOAD DATA INFILE '15330.data' REPLACE INTO TABLE t1 (a,b,c);
+DROP TABLE t1;
diff --git a/mysql-test/suite/versioning/r/online.result b/mysql-test/suite/versioning/r/online.result
new file mode 100644
index 00000000000..b2a34481d63
--- /dev/null
+++ b/mysql-test/suite/versioning/r/online.result
@@ -0,0 +1,34 @@
+set system_versioning_alter_history=keep;
+create or replace table t (a int, b int) engine=innodb;
+alter table t add system versioning, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED
+alter table t add system versioning, lock=shared;
+alter table t drop column b, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED
+alter table t drop column b, algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned tables. Try ALGORITHM=COPY
+alter table t add index idx(a), lock=none;
+alter table t drop system versioning, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED
+alter table t drop system versioning, algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned tables. Try ALGORITHM=COPY
+create or replace table t (a int, b int) engine=innodb;
+alter table t
+add s bigint unsigned as row start,
+add e bigint unsigned as row end,
+add period for system_time(s, e),
+add system versioning,
+lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED
+alter table t
+add s bigint unsigned as row start,
+add e bigint unsigned as row end,
+add period for system_time(s, e),
+add system versioning;
+alter table t drop column b, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED
+alter table t add index idx(a), lock=none;
+alter table t drop column s, drop column e;
+alter table t drop system versioning, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED
+drop table t;
diff --git a/mysql-test/suite/versioning/r/optimized.result b/mysql-test/suite/versioning/r/optimized.result
new file mode 100644
index 00000000000..1586676b904
--- /dev/null
+++ b/mysql-test/suite/versioning/r/optimized.result
@@ -0,0 +1,64 @@
+create table t (
+a int,
+b int without system versioning
+) with system versioning;
+insert into t values(1, 2);
+insert into t values(3, 4);
+select * from t;
+a b
+1 2
+3 4
+select a from t for system_time as of timestamp now(6);
+a
+1
+3
+select a, b, b+0 from t for system_time as of timestamp now(6);
+a b b+0
+1 2 2
+3 4 4
+select * from t for system_time as of timestamp now(6);
+a b
+1 2
+3 4
+select count(*) from t for system_time as of timestamp now(6) group by b;
+count(*)
+1
+1
+select * from t for system_time as of timestamp now(6) order by b asc;
+a b
+1 2
+3 4
+select * from t for system_time as of timestamp now(6) order by b desc;
+a b
+3 4
+1 2
+select * from t for system_time as of timestamp now(6) group by a having a=2;
+a b
+select * from t for system_time as of timestamp now(6) group by b having b=2;
+a b
+1 2
+select a from t for system_time as of timestamp now(6) where b=2;
+a
+1
+select a from t for system_time as of timestamp now(6) where b=NULL;
+a
+select a from t for system_time as of timestamp now(6) where b is NULL;
+a
+select count(*), b from t for system_time as of timestamp now(6) group by b having b=NULL;
+count(*) b
+select a, b from t;
+a b
+1 2
+3 4
+create or replace table t (
+a int,
+b int not null without system versioning
+) with system versioning;
+insert into t values (1, 2), (3, 4);
+select * from t for system_time as of timestamp now(6);
+a b
+1 2
+3 4
+select * from t for system_time as of timestamp now(6) where b is NULL;
+a b
+drop table t;
diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result
new file mode 100644
index 00000000000..decf22d4118
--- /dev/null
+++ b/mysql-test/suite/versioning/r/partition.result
@@ -0,0 +1,572 @@
+set system_versioning_alter_history=keep;
+# Check conventional partitioning on temporal tables
+create table t1 (x int)
+with system versioning
+partition by range columns (x) (
+partition p0 values less than (100),
+partition p1 values less than (1000));
+insert into t1 values (3), (300);
+select * from t1;
+x
+3
+300
+select * from t1 partition (p0);
+x
+3
+select * from t1 partition (p1);
+x
+300
+delete from t1;
+select * from t1;
+x
+select * from t1 partition (p0);
+x
+select * from t1 partition (p1);
+x
+select * from t1 for system_time all;
+x
+3
+300
+select * from t1 partition (p0) for system_time all;
+x
+3
+select * from t1 partition (p1) for system_time all;
+x
+300
+# Engine change native <-> non-native versioning prohibited
+create or replace table t1 (i int) engine=DEFAULT_ENGINE with system versioning partition by hash(i);
+alter table t1 engine=NON_DEFAULT_ENGINE;
+ERROR HY000: Not allowed for system-versioned `test`.`t1`. Change to/from native system versioning engine is prohibited.
+## CREATE TABLE
+create or replace table t1 (x int)
+partition by system_time (
+partition p0 history,
+partition pn current);
+ERROR HY000: Table `t1` is not system-versioned
+create or replace table t1 (x int);
+alter table t1
+partition by system_time (
+partition p0 history,
+partition pn current);
+ERROR HY000: Table `t1` is not system-versioned
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0 current);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0 current,
+partition p1 current);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0 history,
+partition p1 history);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition pn current,
+partition p0 history);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0,
+partition pn current);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0 history,
+partition pn current);
+## ALTER TABLE
+alter table t1 add partition (
+partition p1 current);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+alter table t1 add partition (
+partition p1 history);
+Warnings:
+Warning 4113 Maybe missing parameters: no rotation condition for multiple HISTORY partitions.
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME
+(PARTITION `p0` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+insert into t1 values (1), (2);
+alter table t1 drop partition pn;
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+alter table t1 drop partition p1;
+alter table t1 drop partition p0;
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+select x from t1;
+x
+1
+2
+# Bug #260: incorrect IB partitioning warning
+create or replace table t1 (x int)
+with system versioning
+partition by system_time limit 1 (
+partition p0 history,
+partition pn current);
+alter table t1 change x big int;
+create or replace table t1 (i int) engine myisam partition by hash(i) partitions 2;
+alter table t1 add partition (partition px history);
+ERROR HY000: Wrong partitioning type, expected type: `SYSTEM_TIME`
+## INSERT, UPDATE, DELETE
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0 history,
+partition pn current);
+set @now= now(6);
+insert into t1 values (1);
+set @str= concat('select x, row_start < @now as A, row_end > @now as B from t1 partition (p0)');
+prepare select_p0 from @str;
+set @str= concat('select x, row_start > @now as C, row_end = timestamp\'2038-01-19 03:14:07.999999\' as D from t1 partition (pn)');
+prepare select_pn from @str;
+execute select_p0;
+x A B
+execute select_pn;
+x C D
+1 1 1
+set @str= concat('select row_start from t1 partition (pn) into @ts0');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+set @now= now(6);
+delete from t1;
+execute select_p0;
+x A B
+1 1 1
+execute select_pn;
+x C D
+set @str= concat('select row_start from t1 partition (p0) into @ts1');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+select @ts0 = @ts1;
+@ts0 = @ts1
+1
+set @now= now(6);
+insert into t1 values (2);
+execute select_p0;
+x A B
+1 1 0
+execute select_pn;
+x C D
+2 1 1
+set @str= concat('select row_start from t1 partition (pn) into @ts0');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+set @now= now(6);
+update t1 set x = x + 1;
+execute select_p0;
+x A B
+1 1 0
+2 1 1
+execute select_pn;
+x C D
+3 1 1
+drop prepare select_p0;
+drop prepare select_pn;
+set @str= concat('select row_start from t1 partition (p0) where x = 2 into @ts1');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+set @str= concat('select row_end from t1 partition (p0) where x = 2 into @ts2');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+set @str= concat('select row_start from t1 partition (pn) into @ts3');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+select @ts0 = @ts1;
+@ts0 = @ts1
+1
+select @ts2 = @ts3;
+@ts2 = @ts3
+1
+## rotation by LIMIT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time limit 0 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'LIMIT'
+create or replace table t1 (x int)
+with system versioning
+partition by system_time limit 2 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 2
+(PARTITION `p0` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+alter table t1 drop partition non_existent;
+ERROR HY000: Error in list of partitions to DROP
+insert into t1 values (1), (2), (3), (4), (5), (6);
+select * from t1 partition (pn);
+x
+1
+2
+3
+4
+5
+6
+delete from t1 where x < 4;
+delete from t1;
+select * from t1 partition (p0);
+x
+1
+2
+3
+select * from t1 partition (p1);
+x
+4
+5
+6
+insert into t1 values (7), (8);
+Warnings:
+Warning 4112 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+### warn about full partition
+delete from t1;
+Warnings:
+Warning 4112 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+select * from t1 partition (p1) order by x;
+x
+4
+5
+6
+7
+8
+### Assertion in ALTER on warning from partitioning LIMIT [#446]
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1), (2);
+delete from t1;
+alter table t1 partition by system_time limit 1 (
+partition p1 history,
+partition pn current);
+## rotation by INTERVAL
+create or replace table t1 (x int)
+with system versioning
+partition by system_time interval 0 second (
+partition p0 history,
+partition p1 history,
+partition pn current);
+ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL'
+create or replace table t1 (x int)
+with system versioning
+partition by system_time interval 1 second starts 12345 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+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 'starts 12345 (
+partition p0 history,
+partition p1 history,
+partition pn current)' at line 3
+create table t1 (i int) with system versioning
+partition by system_time interval 6 day limit 98
+(partition p0 history, partition ver_pn current);
+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 'limit 98
+(partition p0 history, partition ver_pn current)' at line 2
+### ha_partition::update_row() check
+create or replace table t1 (x int)
+with system versioning
+partition by system_time interval 1 second (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t1 values (1), (2), (3), (4);
+select * from t1 partition (pn);
+x
+1
+2
+3
+4
+delete from t1 where x < 3;
+delete from t1;
+Warnings:
+Warning 4112 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+select * from t1 partition (p0) order by x;
+x
+1
+2
+select * from t1 partition (p1) order by x;
+x
+3
+4
+### ha_partition::write_row() check
+create or replace table t1 (x int)
+with system versioning
+partition by system_time interval 1 second (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t1 values (1);
+update t1 set x= 2;
+update t1 set x= 3;
+Warnings:
+Warning 4112 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+select * from t1 partition (p0);
+x
+1
+select * from t1 partition (p1);
+x
+2
+## Subpartitions
+create or replace table t1 (x int)
+with system versioning
+partition by system_time limit 2
+subpartition by key (x)
+subpartitions 2 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t1 (x) values (1), (2), (3), (4), (5);
+select * from t1 partition (pnsp0);
+x
+1
+3
+5
+select * from t1 partition (pnsp1);
+x
+2
+4
+### warn about full partition
+delete from t1 where x < 3;
+delete from t1;
+delete from t1;
+select * from t1 partition (p0sp0);
+x
+1
+3
+5
+select * from t1 partition (p0sp1);
+x
+2
+4
+select * from t1 partition (p1sp0);
+x
+select * from t1 partition (p1sp1);
+x
+create or replace table t1 (a bigint)
+with system versioning
+partition by range (a)
+(partition p0 values less than (20) engine innodb,
+partition p1 values less than maxvalue engine innodb);
+insert into t1 values (1);
+create or replace table t1 (
+f_int1 integer default 0
+) with system versioning
+partition by range(f_int1)
+subpartition by hash(f_int1)
+( partition part1 values less than (1000)
+(subpartition subpart11 storage engine = 'innodb',
+subpartition subpart12 storage engine = 'innodb'));
+insert into t1 values (1);
+create or replace table t1 (i int) engine=innodb partition by key(i);
+alter table t1 add system versioning;
+insert into t1 values();
+# MDEV-14722 Assertion in ha_commit_trans for sub-statement
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 day (
+partition p1 history,
+partition pc current);
+create or replace table t2 (f int);
+create or replace trigger tr before insert on t2
+for each row select table_rows from information_schema.tables
+where table_name = 't1' into @a;
+insert into t2 values (1);
+# MDEV-14740 Locking assertion for system_time partitioning
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 week (
+partition p1 history,
+partition pn current);
+create or replace table t2 (f int);
+create or replace trigger tr before insert on t2
+for each row select count(*) from t1 into @a;
+insert into t2 values (1);
+# MDEV-14741 Assertion `(trx)->start_file == 0' failed in row_truncate_table_for_mysql()
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 hour (
+partition p1 history,
+partition pn current);
+set autocommit= off;
+truncate table t1;
+set autocommit= on;
+# MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES
+create or replace table t1 (x int) with system versioning;
+lock table t1 write;
+alter table t1 partition by system_time interval 1 week (
+partition p1 history,
+partition pn current);
+unlock tables;
+# MDEV-14748 Assertion in ha_myisammrg::attach_children()
+create or replace table t1 (x int) engine=myisam with system versioning
+partition by system_time interval 1 month (partition p1 history, partition pn current);
+create or replace table t2 (x int) engine=myisam;
+create or replace table t3 (x int) engine=merge union=(t2);
+create or replace table t4 (x int) engine=myisam;
+create or replace trigger tr after insert on t4 for each row insert into t2
+( select x from t3 ) union ( select x from t1 );
+insert into t4 values (1);
+# MDEV-14821 Assertion failure
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (0), (1);
+update t1 set x= x + 1;
+alter table t1 partition by system_time limit 1 (
+partition p1 history,
+partition p2 history,
+partition pn current);
+delete from t1 where x = 1;
+delete from t1 where x = 2;
+# MDEV-14923 Assertion upon INSERT into locked versioned partitioned table
+create or replace table t1 (x int) with system versioning
+partition by system_time (partition p1 history, partition pn current);
+lock table t1 write;
+alter table t1 add partition (partition p1 history);
+ERROR HY000: Duplicate partition name p1
+insert into t1 values (1);
+unlock tables;
+create or replace table t1 (pk int) with system versioning
+partition by system_time interval 10 year (
+partition p1 history,
+partition p2 history,
+partition pn current
+);
+ERROR 22003: TIMESTAMP value is out of range in 'INTERVAL'
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 hour (
+partition p0 history, partition pn current);
+set @ts=(select partition_description from information_schema.partitions
+where table_schema='test' and table_name='t1' and partition_name='p0');
+alter table t1 add column b int;
+select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
+partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
+p0 1 SYSTEM_TIME 00:00:00.000000
+pn 2 SYSTEM_TIME NULL
+Warnings:
+Warning 1292 Truncated incorrect time value: 'CURRENT'
+alter table t1 add partition (partition p1 history, partition p2 history);
+select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
+partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
+p0 1 SYSTEM_TIME 00:00:00.000000
+p1 2 SYSTEM_TIME 01:00:00.000000
+p2 3 SYSTEM_TIME 02:00:00.000000
+pn 4 SYSTEM_TIME NULL
+Warnings:
+Warning 1292 Truncated incorrect time value: 'CURRENT'
+alter table t1 drop partition p0;
+select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
+partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
+p1 1 SYSTEM_TIME 01:00:00.000000
+p2 2 SYSTEM_TIME 02:00:00.000000
+pn 3 SYSTEM_TIME NULL
+Warnings:
+Warning 1292 Truncated incorrect time value: 'CURRENT'
+alter table t1 drop partition p2;
+ERROR HY000: Can only drop oldest partitions when rotating by INTERVAL
+select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
+partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
+p1 1 SYSTEM_TIME 01:00:00.000000
+p2 2 SYSTEM_TIME 02:00:00.000000
+pn 3 SYSTEM_TIME NULL
+Warnings:
+Warning 1292 Truncated incorrect time value: 'CURRENT'
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 second
+subpartition by key (i) subpartitions 2
+(partition p1 history, partition pn current);
+insert t1 values (1);
+delete from t1;
+insert t1 values (2);
+Warnings:
+Warning 4112 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+delete from t1;
+Warnings:
+Warning 4112 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+alter table t1 add partition (partition p0 history, partition p2 history);
+select subpartition_name,table_rows from information_schema.partitions where table_schema='test' and table_name='t1';
+subpartition_name table_rows
+p1sp0 1
+p1sp1 0
+p0sp0 0
+p0sp1 1
+p2sp0 0
+p2sp1 0
+pnsp0 0
+pnsp1 0
+## pruning check
+set @ts=(select partition_description from information_schema.partitions
+where table_schema='test' and table_name='t1' and partition_name='p0' limit 1);
+insert into t1 values (4),(5);
+select * from t1;
+i
+4
+5
+explain partitions select * from t1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL 2 Using where
+explain partitions select * from t1 for system_time as of from_unixtime(@ts);
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1_p1sp0,p1_p1sp1,p0_p0sp0,p0_p0sp1,p2_p2sp0,p2_p2sp1,pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL # Using where
+set @ts=(select row_end from t1 for system_time all where i=1);
+select * from t1 for system_time all where row_end = @ts;
+i
+1
+explain partitions select * from t1 for system_time all where row_end = @ts;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1_p1sp0,p1_p1sp1 # NULL NULL NULL NULL # #
+#
+# MDEV-15103 Assertion in ha_partition::part_records() for updating VIEW
+#
+create or replace table t1 (pk int primary key, f int) with system versioning
+partition by system_time limit 100 (partition p1 history, partition pn current);
+insert into t1 values (1,10), (2,20);
+create or replace view v1 as select * from t1;
+update v1 set f= 30;
+#
+# MDEV-15168 Unexpected ER_VERS_ENGINE_UNSUPPORTED upon dropping versioning on a partitioned table
+#
+create or replace table t (a int) with system versioning
+partition by system_time (partition p1 history, partition pn current);
+alter table t drop system versioning;
+ERROR HY000: Can not DROP SYSTEM VERSIONING for table `t` partitioned BY SYSTEM_TIME
+# MDEV-15191 Assertion `bit < (map)->n_bits' failed in bitmap_is_set upon INSERT
+create or replace table t1 (i int) with system versioning;
+insert into t1 values (1), (2);
+update t1 set i= 3;
+alter table t1 partition by system_time interval 1 month (partition p1 history, partition pn current);
+lock table t1 write;
+alter table t1 add partition (partition p2 history);
+insert into t1 values (4);
+unlock tables;
+# MDEV-15036 Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' in Diagnostics_area::set_ok_status or unexpected ER_RANGE_NOT_INCREASING_ERROR
+create or replace table t1 (a int) with system versioning
+partition by system_time limit 2 (
+partition p1 history, partition p2 history,
+partition p3 history, partition pn current);
+insert into t1 values (1),(2),(3);
+update t1 set a = 4;
+delete from t1;
+delete from t1 where a is not null;
+# Test cleanup
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/r/replace.result b/mysql-test/suite/versioning/r/replace.result
new file mode 100644
index 00000000000..54ab5b49c2a
--- /dev/null
+++ b/mysql-test/suite/versioning/r/replace.result
@@ -0,0 +1,10 @@
+call create_table('t', 'x int');
+insert t values (1, 2);
+replace t values (1, 3);
+select *, row_end>TIMESTAMP'2038-01-01 00:00:00' as current from t for system_time all
+order by x;
+id x current
+1 2 0
+1 3 1
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/r/rpl.result b/mysql-test/suite/versioning/r/rpl.result
new file mode 100644
index 00000000000..c5770a91c77
--- /dev/null
+++ b/mysql-test/suite/versioning/r/rpl.result
@@ -0,0 +1,167 @@
+include/master-slave.inc
+[connection master]
+connection slave;
+connection master;
+CREATE TABLE t1 (x int) with system versioning;
+insert into t1 values (1);
+SELECT * FROM t1;
+x
+1
+delete from t1;
+select * from t1;
+x
+select * from t1 for system_time all;
+x
+1
+connection slave;
+select * from t1;
+x
+select * from t1 for system_time all;
+x
+1
+connection master;
+insert into t1 values (2);
+connection slave;
+select * from t1;
+x
+2
+connection master;
+update t1 set x = 3;
+connection slave;
+select * from t1;
+x
+3
+select * from t1 for system_time all;
+x
+1
+3
+2
+# check unversioned -> versioned replication
+connection master;
+create or replace table t1 (x int primary key);
+connection slave;
+alter table t1 with system versioning;
+connection master;
+insert into t1 values (1);
+connection slave;
+select * from t1;
+x
+1
+select * from t1 for system_time all;
+x
+1
+connection master;
+update t1 set x= 2 where x = 1;
+connection slave;
+select * from t1;
+x
+2
+select * from t1 for system_time all;
+x
+1
+2
+connection master;
+delete from t1;
+connection slave;
+select * from t1;
+x
+select * from t1 for system_time all;
+x
+1
+2
+# same thing (UPDATE, DELETE), but without PK
+connection master;
+create or replace table t1 (x int);
+connection slave;
+alter table t1 with system versioning;
+connection master;
+insert into t1 values (1);
+update t1 set x= 2 where x = 1;
+connection slave;
+select * from t1;
+x
+2
+select * from t1 for system_time all;
+x
+2
+1
+connection master;
+delete from t1;
+connection slave;
+select * from t1;
+x
+select * from t1 for system_time all;
+x
+2
+1
+# multi-update
+connection master;
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (x int) with system versioning;
+insert into t1 values (1);
+insert into t2 values (2);
+update t1, t2 set t1.x=11, t2.x=22;
+connection slave;
+select * from t1;
+x
+11
+select * from t2;
+x
+22
+select * from t1 for system_time all;
+x
+11
+1
+select * from t2 for system_time all;
+x
+22
+2
+# MDEV-14767 system_versioning_alter_history breaks ALTER replication
+## Case 1: KEEP on the master, ALTER will work on the slave
+connection master;
+create or replace table t1 (a int) with system versioning;
+set system_versioning_alter_history= KEEP;
+alter table t1 add column b int;
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=INNODB_OR_MYISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+## Case 2: ERROR on the master, it'll fail on the master, the slave won't see it
+connection master;
+set system_versioning_alter_history= ERROR;
+alter table t1 drop column b;
+ERROR HY000: Not allowed for system-versioned `test`.`t1`. Change @@system_versioning_alter_history to proceed with ALTER.
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=INNODB_OR_MYISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+## Case 3: table is not versioned on the master, ALTER will work on the slave
+connection master;
+create or replace table t1 (a int);
+connection slave;
+create or replace table t1 (a int) with system versioning;
+connection master;
+alter table t1 add column b int;
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=INNODB_OR_MYISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+connection master;
+drop table t1, t2;
+create table t1 (i int) with system versioning partition by system_time limit 8 ( partition p1 history, partition p2 history, partition pn current );
+insert into t1 values (1);
+update t1 set i = 1;
+update t1 set i = 0;
+connection slave;
+connection master;
+drop table t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result
new file mode 100644
index 00000000000..e1de47ff9fc
--- /dev/null
+++ b/mysql-test/suite/versioning/r/select.result
@@ -0,0 +1,514 @@
+create or replace table t1 (
+x int unsigned,
+y int unsigned,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end)
+) with system versioning;
+insert into t1 (x, y) values
+(0, 100),
+(1, 101),
+(2, 102),
+(3, 103),
+(4, 104),
+(5, 105),
+(6, 106),
+(7, 107),
+(8, 108),
+(9, 109);
+set @t0= now(6);
+delete from t1 where x = 3;
+delete from t1 where x > 7;
+insert into t1(x, y) values(3, 33);
+select sys_trx_start from t1 where x = 3 and y = 33 into @t1;
+select x, y from t1;
+x y
+0 100
+1 101
+2 102
+4 104
+5 105
+6 106
+7 107
+3 33
+select x as ASOF_x, y from t1 for system_time as of timestamp @t0;
+ASOF_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as FROMTO_x, y from t1 for system_time from timestamp '0-0-0 0:0:0' to timestamp @t1;
+FROMTO_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as BETWAND_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1;
+BETWAND_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+select x as ALL_x, y from t1 for system_time all;
+ALL_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+ASOF2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+FROMTO2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+BETWAND2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+create or replace table t1 (
+x int unsigned,
+y int unsigned
+) with system versioning;
+create or replace table t2 (
+x int unsigned,
+y int unsigned
+) with system versioning;
+insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
+insert into t2 values (1, 2), (2, 1), (3, 1);
+set @t0= now(6);
+select t1.x as IJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x;
+IJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x;
+LJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x;
+RJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+delete from t1;
+delete from t2;
+explain extended 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;
+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`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`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
+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`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0`) where 1
+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
+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` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0`) where 1
+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
+1 1 1 2
+1 2 1 2
+1 3 1 2
+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;
+LJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+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;
+RJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+drop table t1;
+drop table t2;
+create table t1(
+A int
+) with system versioning;
+insert into t1 values(1);
+select * from t1;
+A
+1
+create or replace table t1 (x int);
+insert into t1 values (1);
+select * from t1 for system_time all;
+ERROR HY000: Table `t1` is not system-versioned
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+select * from t1 for system_time all for update;
+x
+1
+create or replace table t1 (a int not null auto_increment primary key) with system versioning;
+select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
+a
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (a int) with system versioning;
+insert into t1 values(1);
+insert into t2 values(1);
+create view v1 as select * from t2 inner join t1 using (a);
+select * from v1;
+a
+1
+drop view v1;
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create view vt1 as select a from t1;
+select * from t1 natural join vt1;
+a
+1
+drop view vt1;
+create or replace table t1(x int) with system versioning;
+select * from (t1 as r left join t1 as u using (x)), t1;
+x x
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create trigger read_end after update on t1
+for each row set @end = old.row_end;
+update t1 set a=2;
+select @end;
+@end
+MAX_RESULT
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int) with system versioning;
+insert into t1 values (1);
+insert into t2 values (2);
+select * from (select * from t1 cross join t2) as tmp;
+a b
+1 2
+select * from (select * from (select * from t1 cross join t2) as tmp1) as tmp2;
+a b
+1 2
+select * from (select * from t1 cross join t2 for system_time as of timestamp ('0-0-0')) as tmp;
+a b
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+select * from t1 for system_time all natural left join t2 for system_time all;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+create or replace view v1 as select a1 from t1;
+select * from v1 natural join t2;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+select * from v1 natural left join t2;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+select * from v1 natural right join t2;
+a2 a1
+1 1
+2 1
+1 2
+2 2
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a
+2 1
+3 1
+2 2
+3 2
+2 3
+3 3
+1 NULL
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int) with system versioning;
+insert into t1 values (1), (2), (3);
+delete from t1 where x = 3;
+insert into t2 values (1);
+select * from t1, t2 for system_time all;
+x y
+1 1
+2 1
+select * from (select * from t1 for system_time all, t2 for system_time all)
+for system_time all as t;
+ERROR HY000: Table `t` is not system-versioned
+# TRANSACTION/TIMESTAMP specifier in SYSTEM_TIME [MDEV-14645, Issue #396]
+create or replace table t1 (x int) with system versioning engine myisam;
+select * from t1 for system_time as of transaction 1;
+ERROR HY000: Transaction system versioning for `t1` is not supported
+create or replace table t1 (
+x int,
+sys_trx_start bigint unsigned as row start invisible,
+sys_trx_end bigint unsigned as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end)
+) with system versioning engine innodb;
+insert into t1 values (1);
+set @ts= now(6);
+delete from t1;
+select sys_trx_start from t1 for system_time all into @trx_start;
+## ensure @trx_start is much lower than unix timestamp
+select @trx_start < unix_timestamp(@ts) - 100 as trx_start_good;
+trx_start_good
+1
+## TIMESTAMP specifier
+select x from t1 for system_time as of timestamp @ts;
+x
+1
+set @ts= timestamp'1-1-1 0:0:0';
+## TRANSACTION specifier
+select x from t1 for system_time as of transaction @trx_start;
+x
+1
+## no specifier (auto-detection)
+select x from t1 for system_time as of @ts;
+x
+select x from t1 for system_time as of @trx_start;
+x
+1
+### Issue #365, bug 4 (related to #226, optimized fields)
+create or replace table t1 (i int, b int) with system versioning;
+insert into t1 values (0, 0), (0, 0);
+select min(i) over (partition by b) as f
+from (select i + 0 as i, b from t1) as tt
+order by i;
+f
+0
+0
+### Issue #365, bug 5 (dangling AND)
+create or replace table t1 (a int);
+create or replace table t2 (b int) with system versioning;
+select * from t1
+where exists (select 1 from t2 where t2.b = t1.a and t2.b = t1.a);
+a
+### Issue #365, bug 9 (not a derived subquery)
+create or replace table t1 (x int) with system versioning;
+select t1.x in (select x from t1) a from t1, (select x from t1) b;
+a
+### Issue #365, bug 10 (WHERE cond freed prematurely for PS)
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+create or replace view v1 as select x from t1 where x = 1;
+prepare stmt from "
+select x from t1 where x in (select x from v1);";
+execute stmt;
+x
+1
+execute stmt;
+x
+1
+### Issue #365, bug 11 (WHERE cond not top level item)
+create or replace table t1 (a int, b int, key idx(a)) with system versioning;
+insert into t1 values (1, 1), (2, 2);
+select * from t1 where (a, 2) in ((1, 1), (2, 2)) and b = 1;
+a b
+### Issue #398, NOW is now non-magic
+create or replace table t1 (x int) with system versioning;
+select * from t1 for system_time as of current_timestamp;
+x
+select * from t1 for system_time as of now;
+ERROR 42S22: Unknown column 'now' in 'where clause'
+### Issue #405, NATURAL JOIN failure
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int);
+create or replace view v1 as select a, row_start, row_end from t1 where a > round(rand()*1000);
+select * from v1 natural join t2;
+a b
+### Issue #406, MDEV-14633 Assertion on TRT read
+create or replace table t1 (pk int primary key, i int, t time, key (i)) with system versioning;
+insert into t1 values (1, 10, '15:01:53'), (2, 20, '00:00:00');
+delete from t1;
+select * from t1 where t = '00:00:00' and i > 0 and row_end <> '2012-12-12 00:00:00';
+pk i t
+### MDEV-14816 Assertion `join->best_read < double(1.797...e+308L)' failed in bool greedy_search
+create or replace table t1 (f1 int) with system versioning;
+create or replace table t2 (f2 int) with system versioning;
+create or replace table t3 (f3 int);
+create or replace table t4 (f4 int);
+insert into t1 values (1), (2), (3), (4);
+insert into t2 values (1), (2), (3);
+insert into t3 values (1), (2);
+insert into t4 values (1);
+select * from
+t1 as t1a
+left join t2 as t2a left join (t3 as t3a inner join t1) on t2a.f2 = t3a.f3 on t1a.f1 = t2a.f2
+left join (t2 join t3 inner join t4) on t2a.f2 = t1a.f1;
+f1 f2 f3 f1 f2 f3 f4
+1 1 1 1 1 1 1
+2 2 2 1 1 1 1
+1 1 1 2 1 1 1
+2 2 2 2 1 1 1
+1 1 1 3 1 1 1
+2 2 2 3 1 1 1
+1 1 1 4 1 1 1
+2 2 2 4 1 1 1
+1 1 1 1 1 2 1
+2 2 2 1 1 2 1
+1 1 1 2 1 2 1
+2 2 2 2 1 2 1
+1 1 1 3 1 2 1
+2 2 2 3 1 2 1
+1 1 1 4 1 2 1
+2 2 2 4 1 2 1
+1 1 1 1 2 1 1
+2 2 2 1 2 1 1
+1 1 1 2 2 1 1
+2 2 2 2 2 1 1
+1 1 1 3 2 1 1
+2 2 2 3 2 1 1
+1 1 1 4 2 1 1
+2 2 2 4 2 1 1
+1 1 1 1 2 2 1
+2 2 2 1 2 2 1
+1 1 1 2 2 2 1
+2 2 2 2 2 2 1
+1 1 1 3 2 2 1
+2 2 2 3 2 2 1
+1 1 1 4 2 2 1
+2 2 2 4 2 2 1
+1 1 1 1 3 1 1
+2 2 2 1 3 1 1
+1 1 1 2 3 1 1
+2 2 2 2 3 1 1
+1 1 1 3 3 1 1
+2 2 2 3 3 1 1
+1 1 1 4 3 1 1
+2 2 2 4 3 1 1
+1 1 1 1 3 2 1
+2 2 2 1 3 2 1
+1 1 1 2 3 2 1
+2 2 2 2 3 2 1
+1 1 1 3 3 2 1
+2 2 2 3 3 2 1
+1 1 1 4 3 2 1
+2 2 2 4 3 2 1
+3 3 NULL NULL 1 1 1
+3 3 NULL NULL 1 2 1
+3 3 NULL NULL 2 1 1
+3 3 NULL NULL 2 2 1
+3 3 NULL NULL 3 1 1
+3 3 NULL NULL 3 2 1
+4 NULL NULL NULL NULL NULL NULL
+### MDEV-15004 parser greedily parses AS OF TIMESTAMP
+select timestamp'2016-02-30 08:07:06';
+ERROR HY000: Incorrect DATETIME value: '2016-02-30 08:07:06'
+select * from t1 for system_time as of timestamp'2016-02-30 08:07:06';
+ERROR HY000: Incorrect DATETIME value: '2016-02-30 08:07:06'
+select timestamp('2003-12-31 12:00:00','12:00:00');
+timestamp('2003-12-31 12:00:00','12:00:00')
+2004-01-01 00:00:00
+select * from t1 for system_time as of timestamp('2003-12-31 12:00:00','12:00:00');
+f1
+drop view v1;
+drop table t1, t2, t3, t4;
+call verify_vtq_dummy(34);
+No A B C D
+1 1 1 1 1
+2 1 1 1 1
+3 1 1 1 1
+4 1 1 1 1
+5 1 1 1 1
+6 1 1 1 1
+7 1 1 1 1
+8 1 1 1 1
+9 1 1 1 1
+10 1 1 1 1
+11 1 1 1 1
+12 1 1 1 1
+13 1 1 1 1
+14 1 1 1 1
+15 1 1 1 1
+16 1 1 1 1
+17 1 1 1 1
+18 1 1 1 1
+19 1 1 1 1
+20 1 1 1 1
+21 1 1 1 1
+22 1 1 1 1
+23 1 1 1 1
+24 1 1 1 1
+25 1 1 1 1
+26 1 1 1 1
+27 1 1 1 1
+28 1 1 1 1
+29 1 1 1 1
+30 1 1 1 1
+31 1 1 1 1
+32 1 1 1 1
+33 1 1 1 1
+34 1 1 1 1
diff --git a/mysql-test/suite/versioning/r/select2,trx_id.rdiff b/mysql-test/suite/versioning/r/select2,trx_id.rdiff
new file mode 100644
index 00000000000..6b1d6527a21
--- /dev/null
+++ b/mysql-test/suite/versioning/r/select2,trx_id.rdiff
@@ -0,0 +1,38 @@
+--- select2.result
++++ select2,trx_id.result~
+@@ -22,6 +22,8 @@
+ delete from t1 where x > 7;
+ insert into t1(x, y) values(3, 33);
+ select sys_start from t1 where x = 3 and y = 33 into @t1;
++set @x1= @t1;
++select vtq_commit_ts(@x1) into @t1;
+ select x, y from t1;
+ x y
+ 0 100
+@@ -82,7 +84,7 @@
+ 8 108
+ 9 109
+ 3 33
+-select x as ASOF2_x, y from t1 for system_time as of @t0;
++select x as ASOF2_x, y from t1 for system_time as of @x0;
+ ASOF2_x y
+ 0 100
+ 1 101
+@@ -94,7 +96,7 @@
+ 7 107
+ 8 108
+ 9 109
+-select x as FROMTO2_x, y from t1 for system_time from '0-0-0 0:0:0' to @t1;
++select x as FROMTO2_x, y from t1 for system_time from @x0 to @x1;
+ FROMTO2_x y
+ 0 100
+ 1 101
+@@ -106,7 +108,7 @@
+ 7 107
+ 8 108
+ 9 109
+-select x as BETWAND2_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1;
++select x as BETWAND2_x, y from t1 for system_time between transaction @x0 and transaction @x1;
+ BETWAND2_x y
+ 0 100
+ 1 101
diff --git a/mysql-test/suite/versioning/r/select2.result b/mysql-test/suite/versioning/r/select2.result
new file mode 100644
index 00000000000..9267ab8c913
--- /dev/null
+++ b/mysql-test/suite/versioning/r/select2.result
@@ -0,0 +1,336 @@
+create table t1(
+x int unsigned,
+y int unsigned,
+sys_start SYS_TYPE as row start invisible,
+sys_end SYS_TYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning engine=ENGINE;
+insert into t1 (x, y) values
+(0, 100),
+(1, 101),
+(2, 102),
+(3, 103),
+(4, 104),
+(5, 105),
+(6, 106),
+(7, 107),
+(8, 108),
+(9, 109);
+set @t0= now(6);
+select sys_start from t1 limit 1 into @x0;
+delete from t1 where x = 3;
+delete from t1 where x > 7;
+insert into t1(x, y) values(3, 33);
+select sys_start from t1 where x = 3 and y = 33 into @t1;
+select x, y from t1;
+x y
+0 100
+1 101
+2 102
+4 104
+5 105
+6 106
+7 107
+3 33
+select x as ASOF_x, y from t1 for system_time as of timestamp @t0;
+ASOF_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as FROMTO_x, y from t1 for system_time from '0-0-0 0:0:0' to timestamp @t1;
+FROMTO_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as BETWAND_x, y from t1 for system_time between '0-0-0 0:0:0' and timestamp @t1;
+BETWAND_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+select x as ALL_x, y from t1 for system_time all;
+ALL_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+select x as ASOF2_x, y from t1 for system_time as of @t0;
+ASOF2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as FROMTO2_x, y from t1 for system_time from '0-0-0 0:0:0' to @t1;
+FROMTO2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as BETWAND2_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1;
+BETWAND2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+drop table t1;
+create table t1(
+x int,
+y int,
+sys_start SYS_TYPE as row start invisible,
+sys_end SYS_TYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning engine=ENGINE;
+create table t2 like t1;
+insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
+insert into t2 values (1, 2), (2, 1), (3, 1);
+set @t0= now(6);
+select t1.x as IJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x;
+IJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x;
+LJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x;
+RJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+delete from t1;
+delete from t2;
+select IJ2_x1,y1,x2,y2 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
+1 1 1 2
+1 2 1 2
+1 3 1 2
+select LJ2_x1,y1,x2,y2 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;
+LJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+select RJ2_x1,y1,x2,y2 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;
+RJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+drop table t1;
+drop table t2;
+# MDEV-14686 Server crashes in Item_field::used_tables on 2nd call of SP [#422]
+create or replace table t1 (called int, bad int) with system versioning;
+create or replace procedure bad() select * from t1 where bad in (select called from t1);
+called bad
+called bad
+called bad
+called bad
+called bad
+called bad
+called bad
+called bad
+# bad() is good.
+# MDEV-14751 Server crashes in TABLE::versioned on 2nd execution of SP [#431]
+create or replace table t1 (called_bad int);
+create or replace table t2 (b int);
+create or replace procedure bad() select * from t1 where ( 5, 6 ) in ( select b, b from t2 ) and called_bad in ( select max(b) from t2 );
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+# bad() is good.
+# MDEV-14786 Server crashes in Item_cond::transform on 2nd execution of SP querying from a view [#436]
+create or replace table t1 (called_bad int) with system versioning;
+create or replace view v1 as select called_bad from t1 where called_bad < 5;
+create or replace procedure bad() select called_bad from v1;
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+# bad() is good.
+# wildcard expansion on hidden fields.
+create or replace table t1(
+A int
+) with system versioning;
+insert into t1 values(1);
+select * from t1;
+A
+1
+create or replace table t1 (x int);
+insert into t1 values (1);
+select * from t1 for system_time all;
+ERROR HY000: Table `t1` is not system-versioned
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+select * from t1 for system_time as of now() for update;
+x
+1
+create or replace table t1 (a int not null auto_increment primary key) with system versioning;
+select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
+a
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (a int) with system versioning;
+insert into t1 values(1);
+insert into t2 values(1);
+create or replace view v1 as select * from t2 inner join t1 using (a);
+select * from v1;
+a
+1
+drop view v1;
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create view vt1 as select a from t1;
+select * from t1 natural join vt1;
+a
+1
+drop view vt1;
+create or replace table t1(x int) with system versioning;
+select * from (t1 as r left join t1 as u using (x)), t1;
+x x
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create trigger read_end after update on t1
+for each row set @end = old.row_end;
+update t1 set a=2;
+select @end;
+@end
+MAX_RESULT
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int) with system versioning;
+insert into t1 values (1);
+insert into t2 values (2);
+select * from (select * from t1 cross join t2) as tmp;
+a b
+1 2
+select * from (select * from (select * from t1 cross join t2) as tmp1) as tmp2;
+a b
+1 2
+select * from (select * from t1 cross join t2 for system_time as of timestamp ('0-0-0')) as tmp;
+a b
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+select * from t1 for system_time all natural left join t2 for system_time all;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+create or replace view v1 as select a1 from t1;
+select * from v1 natural join t2;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+select * from v1 natural left join t2;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+select * from v1 natural right join t2;
+a2 a1
+1 1
+2 1
+1 2
+2 2
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a
+2 1
+3 1
+2 2
+3 2
+2 3
+3 3
+1 NULL
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int) with system versioning;
+insert into t1 values (1), (2), (3);
+delete from t1 where x = 3;
+insert into t2 values (1);
+select * from t1, t2 for system_time all;
+x y
+1 1
+2 1
+select * from (select * from t1 for system_time all, t2 for system_time all) for system_time all as t;
+ERROR HY000: Table `t` is not system-versioned
+select * from (t1 for system_time all join t2 for system_time all) for system_time all;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
+drop view v1;
+drop table t1, t2;
diff --git a/mysql-test/suite/versioning/r/simple.result b/mysql-test/suite/versioning/r/simple.result
new file mode 100644
index 00000000000..7b42fed45c5
--- /dev/null
+++ b/mysql-test/suite/versioning/r/simple.result
@@ -0,0 +1,73 @@
+set default_storage_engine=innodb;
+create or replace table dept (
+dept_id int(10) primary key,
+name varchar(100)
+)
+with system versioning;
+create or replace table emp (
+emp_id int(10) primary key,
+dept_id int(10),
+name varchar(100),
+salary int(10),
+constraint `dept-emp-fk`
+ foreign key (dept_id) references dept (dept_id)
+on delete restrict
+on update restrict
+)
+with system versioning;
+select now() into @ts_0;
+insert into dept (dept_id, name) values (10, "accounting");
+commit;
+select row_start into @ts_1 from dept where dept_id=10;
+insert into emp (emp_id, name, salary, dept_id) values (1, "bill", 1000, 10);
+commit;
+select row_start into @ts_2 from emp where name="bill";
+select * from emp;
+emp_id dept_id name salary
+1 10 bill 1000
+update emp set salary=2000 where name="bill";
+commit;
+select row_start into @ts_3 from emp where name="bill";
+select * from emp;
+emp_id dept_id name salary
+1 10 bill 2000
+select * from emp for system_time as of timestamp @ts_2;
+emp_id dept_id name salary
+1 10 bill 1000
+select * from emp for system_time as of timestamp @ts_3;
+emp_id dept_id name salary
+1 10 bill 2000
+select * from emp e, dept d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+1 10 bill 2000 10 accounting
+select * from
+emp for system_time from timestamp @ts_1 to timestamp @ts_2 e,
+dept for system_time from timestamp @ts_1 to timestamp @ts_2 d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+set statement system_versioning_asof=@ts_0 for
+select * from emp e, dept d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+set statement system_versioning_asof=@ts_1 for
+select * from emp e, dept d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+set statement system_versioning_asof=@ts_2 for
+select * from emp e, dept d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+1 10 bill 1000 10 accounting
+set statement system_versioning_asof=@ts_3 for
+select * from emp e, dept d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+1 10 bill 2000 10 accounting
+drop table emp, dept;
diff --git a/mysql-test/suite/versioning/r/sysvars.result b/mysql-test/suite/versioning/r/sysvars.result
new file mode 100644
index 00000000000..22f53ca6fbe
--- /dev/null
+++ b/mysql-test/suite/versioning/r/sysvars.result
@@ -0,0 +1,129 @@
+create table t (a int) with system versioning;
+insert into t values (1);
+update t set a= 2;
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof DEFAULT
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof DEFAULT
+select * from t;
+a
+2
+set system_versioning_asof= '2031-1-1 0:0:0';
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 2031-01-01 00:00:00.000000
+select * from t;
+a
+2
+set system_versioning_asof= '2011-1-1 0:0:0';
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 2011-01-01 00:00:00.000000
+select * from t;
+a
+set global system_versioning_asof= 'alley';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'alley'
+set global system_versioning_asof= null;
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'NULL'
+set global system_versioning_asof= 1;
+ERROR 42000: Incorrect argument type to variable 'system_versioning_asof'
+set global system_versioning_asof= 1.1;
+ERROR 42000: Incorrect argument type to variable 'system_versioning_asof'
+set system_versioning_asof= 'alley';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'alley'
+set system_versioning_asof= null;
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'NULL'
+set system_versioning_asof= 1;
+ERROR 42000: Incorrect argument type to variable 'system_versioning_asof'
+set system_versioning_asof= 1.1;
+ERROR 42000: Incorrect argument type to variable 'system_versioning_asof'
+# GLOBAL @@system_versioning_asof
+set global system_versioning_asof= '1911-11-11 11:11:11.1111119';
+Warnings:
+Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
+Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1911-11-11 11:11:11.111111
+set global system_versioning_asof= '1900-01-01 00:00:00';
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1900-01-01 00:00:00.000000
+set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
+Warnings:
+Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1911-11-11 11:11:11.111111
+set @ts= timestamp'1900-01-01 00:00:00';
+set global system_versioning_asof= @ts;
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1900-01-01 00:00:00.000000
+set global system_versioning_asof= default;
+select @@global.system_versioning_asof;
+@@global.system_versioning_asof
+DEFAULT
+# SESSION @@system_versioning_asof
+set system_versioning_asof= '1911-11-11 11:11:11.1111119';
+Warnings:
+Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
+Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1911-11-11 11:11:11.111111
+set system_versioning_asof= '1900-01-01 00:00:00';
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1900-01-01 00:00:00.000000
+set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
+Warnings:
+Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1911-11-11 11:11:11.111111
+set @ts= timestamp'1900-01-01 00:00:00';
+set system_versioning_asof= @ts;
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1900-01-01 00:00:00.000000
+# DEFAULT: value is copied from GLOBAL to SESSION
+set global system_versioning_asof= timestamp'1911-11-11 11:11:11.111111';
+set system_versioning_asof= '1900-01-01 00:00:00';
+select @@global.system_versioning_asof != @@system_versioning_asof as different;
+different
+1
+set system_versioning_asof= default;
+select @@global.system_versioning_asof = @@system_versioning_asof as equal;
+equal
+1
+set global system_versioning_asof= DEFAULT;
+set system_versioning_asof= DEFAULT;
+select @@global.system_versioning_asof, @@system_versioning_asof;
+@@global.system_versioning_asof @@system_versioning_asof
+DEFAULT DEFAULT
+select * from t for system_time all;
+a
+2
+1
+select * from t;
+a
+2
+select * from t for system_time as of timestamp current_timestamp(6);
+a
+2
+select * from t for system_time all;
+a
+2
+1
+select * from t for system_time from '0-0-0' to current_timestamp(6);
+a
+2
+1
+select * from t for system_time between '0-0-0' and current_timestamp(6);
+a
+2
+1
+drop table t;
diff --git a/mysql-test/suite/versioning/r/truncate.result b/mysql-test/suite/versioning/r/truncate.result
new file mode 100644
index 00000000000..181b120eafb
--- /dev/null
+++ b/mysql-test/suite/versioning/r/truncate.result
@@ -0,0 +1,88 @@
+create table t (a int);
+delete history from t before system_time now();
+ERROR HY000: Table `t` is not system-versioned
+create or replace table t (a int) with system versioning;
+insert into t values (1);
+update t set a=2;
+set @test = 'correct';
+create trigger trg_before before delete on t for each row set @test = 'incorrect';
+create trigger trg_after after delete on t for each row set @test = 'incorrect';
+delete history from t;
+select @test from t;
+@test
+correct
+drop table t;
+create table t (a int) with system versioning;
+insert into t values (1), (2);
+update t set a=11 where a=1;
+set @ts1=now(6);
+update t set a=22 where a=2;
+select * from t for system_time all;
+a
+11
+22
+1
+2
+delete history from t before system_time timestamp @ts1;
+select * from t for system_time all;
+a
+11
+22
+2
+prepare stmt from 'delete history from t';
+execute stmt;
+drop prepare stmt;
+select * from t for system_time all;
+a
+11
+22
+delete from t;
+create or replace procedure truncate_sp()
+begin
+delete history from t before system_time timestamp now(6);
+end~~
+call truncate_sp;
+select * from t for system_time all;
+a
+drop procedure truncate_sp;
+# Truncate partitioned
+create or replace table t (a int)
+with system versioning
+engine myisam
+partition by system_time limit 1 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t values (1);
+update t set a= 2;
+update t set a= 3;
+delete history from t;
+select * from t for system_time all;
+a
+3
+# VIEW
+create or replace table t (i int) with system versioning;
+delete history from t;
+create or replace view v as select * from t;
+delete history from v;
+ERROR 42S02: 'v' is a view
+create or replace table t (i int);
+delete history from t;
+ERROR HY000: Table `t` is not system-versioned
+create or replace view v as select * from t;
+delete history from v;
+ERROR 42S02: 'v' is a view
+prepare stmt from 'delete history from t';
+ERROR HY000: Table `t` is not system-versioned
+drop table t;
+drop view v;
+create or replace table t (i int);
+create or replace view v as select * from t;
+drop table v;
+ERROR 42S02: 'test.v' is a view
+lock table v write;
+delete history from v before system_time now(6);
+ERROR 42S02: 'v' is a view
+unlock tables;
+drop view v;
+drop table t;
diff --git a/mysql-test/suite/versioning/r/truncate_privilege.result b/mysql-test/suite/versioning/r/truncate_privilege.result
new file mode 100644
index 00000000000..e378407afde
--- /dev/null
+++ b/mysql-test/suite/versioning/r/truncate_privilege.result
@@ -0,0 +1,33 @@
+connect root,localhost,root,,test;
+connection root;
+create database mysqltest;
+create user mysqltest_1@localhost;
+connect user1,localhost,mysqltest_1,,test;
+connection user1;
+connection root;
+create table mysqltest.t (a int) with system versioning;
+connection user1;
+show grants;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+delete history from mysqltest.t before system_time now();
+ERROR 42000: DELETE VERSIONING ROWS command denied to user 'mysqltest_1'@'localhost' for table 't'
+connection root;
+grant delete history on mysqltest.* to mysqltest_1@localhost;
+grant delete history on mysqltest.t to mysqltest_1@localhost;
+connection user1;
+show grants;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT DELETE VERSIONING ROWS ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+GRANT DELETE VERSIONING ROWS ON `mysqltest`.`t` TO 'mysqltest_1'@'localhost'
+delete history from mysqltest.t before system_time now();
+connection root;
+grant all on *.* to mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'mysqltest_1'@'localhost'
+GRANT DELETE VERSIONING ROWS ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+GRANT DELETE VERSIONING ROWS ON `mysqltest`.`t` TO 'mysqltest_1'@'localhost'
+drop user mysqltest_1@localhost;
+drop database mysqltest;
diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result
new file mode 100644
index 00000000000..30ca278eaea
--- /dev/null
+++ b/mysql-test/suite/versioning/r/trx_id.result
@@ -0,0 +1,131 @@
+create or replace table t1 (
+x int,
+sys_trx_start bigint(20) unsigned as row start invisible,
+sys_trx_end bigint(20) unsigned as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end)
+) with system versioning engine innodb;
+insert into t1 (x) values (1);
+# ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry
+set @@system_versioning_alter_history=keep;
+create or replace table t1 (x int) engine innodb;
+insert into t1 values (1);
+alter table t1
+add column s bigint unsigned as row start,
+add column e bigint unsigned as row end,
+add period for system_time(s, e),
+add system versioning,
+algorithm=inplace;
+select s from t1 into @trx_start;
+select count(*) = 1 from mysql.transaction_registry where transaction_id = @trx_start;
+count(*) = 1
+1
+create or replace table t1 (x int) engine innodb;
+select count(*) from mysql.transaction_registry into @tmp;
+alter table t1
+add column s bigint unsigned as row start,
+add column e bigint unsigned as row end,
+add period for system_time(s, e),
+add system versioning,
+algorithm=inplace;
+select count(*) = @tmp from mysql.transaction_registry;
+count(*) = @tmp
+1
+create or replace table t1 (x int) engine innodb;
+insert into t1 values (1);
+alter table t1
+add column s bigint unsigned as row start,
+add column e bigint unsigned as row end,
+add period for system_time(s, e),
+add system versioning,
+algorithm=copy;
+select s from t1 into @trx_start;
+select count(*) = 1 from mysql.transaction_registry where transaction_id = @trx_start;
+count(*) = 1
+1
+create or replace table t1 (x int) engine innodb;
+select count(*) from mysql.transaction_registry into @tmp;
+alter table t1
+add column s bigint unsigned as row start,
+add column e bigint unsigned as row end,
+add period for system_time(s, e),
+add system versioning,
+algorithm=copy;
+select count(*) = @tmp + 1 from mysql.transaction_registry;
+count(*) = @tmp + 1
+1
+# TRX_ID to TIMESTAMP versioning switch
+create or replace table t1 (
+x int,
+sys_start bigint unsigned as row start invisible,
+sys_end bigint unsigned as row end invisible,
+period for system_time (sys_start, sys_end)
+) engine innodb with system versioning;
+insert into t1 values (1);
+alter table t1 drop column sys_start, drop column sys_end;
+select row_end = 18446744073709551615 as transaction_based from t1 for system_time all;
+transaction_based
+1
+# Simple vs SEES algorithms
+create or replace table t1 (
+x int,
+sys_start bigint(20) unsigned as row start invisible,
+sys_end bigint(20) unsigned as row end invisible,
+period for system_time (sys_start, sys_end)
+) with system versioning engine innodb;
+set transaction isolation level read committed;
+start transaction;
+insert into t1 values (1);
+connect con1,localhost,root,,test;
+set transaction isolation level read committed;
+start transaction;
+insert into t1 values (2);
+connect con2,localhost,root,,test;
+set transaction isolation level read committed;
+start transaction;
+insert into t1 values (3);
+commit;
+disconnect con2;
+connection default;
+set @ts1= sysdate(6);
+connection con1;
+commit;
+disconnect con1;
+connection default;
+set @ts2= sysdate(6);
+commit;
+set @ts3= sysdate(6);
+select sys_start from t1 where x = 1 into @trx_id1;
+select sys_start from t1 where x = 2 into @trx_id2;
+select sys_start from t1 where x = 3 into @trx_id3;
+select @trx_id1 < @trx_id2, @trx_id2 < @trx_id3;
+@trx_id1 < @trx_id2 @trx_id2 < @trx_id3
+1 1
+select @ts1 < @ts2, @ts2 < @ts3;
+@ts1 < @ts2 @ts2 < @ts3
+1 1
+# MVCC is resolved
+select * from t1 for system_time as of transaction @trx_id1;
+x
+1
+2
+3
+select * from t1 for system_time as of timestamp @ts1;
+x
+3
+select * from t1 for system_time as of transaction @trx_id2;
+x
+2
+3
+select * from t1 for system_time as of timestamp @ts2;
+x
+2
+3
+select * from t1 for system_time as of transaction @trx_id3;
+x
+3
+select * from t1 for system_time as of timestamp @ts3;
+x
+1
+2
+3
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/update,trx_id.rdiff b/mysql-test/suite/versioning/r/update,trx_id.rdiff
new file mode 100644
index 00000000000..037ec548072
--- /dev/null
+++ b/mysql-test/suite/versioning/r/update,trx_id.rdiff
@@ -0,0 +1,13 @@
+--- suite/versioning/r/update.result
++++ suite/versioning/r/update.reject
+@@ -88,10 +88,8 @@
+ 5 3 1
+ 3 1 0
+ 2 1 0
+-3 2 0
+ 4 1 0
+ 5 1 0
+-5 2 0
+ drop table t1;
+ create table t1 (
+ id int primary key auto_increment,
diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result
new file mode 100644
index 00000000000..8e42e7d413d
--- /dev/null
+++ b/mysql-test/suite/versioning/r/update.result
@@ -0,0 +1,243 @@
+create table t1(
+x int unsigned,
+y int unsigned,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+insert into t1(x, y) values (1, 1000), (2, 2000), (3, 3000), (4, 4000), (5, 5000), (6, 6000), (7, 7000), (8, 8000), (9, 9000);
+select x, y from t1;
+x y
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8000
+9 9000
+update t1 set y = y + 1 where x > 7;
+select x, y from t1;
+x y
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8001
+9 9001
+select x, y from t1 for system_time all;
+x y
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8001
+9 9001
+8 8000
+9 9000
+drop table t1;
+create table t1 (
+id bigint primary key,
+x int,
+y int without system versioning,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+insert into t1 values(1, 1, 1);
+set @ins_t= now(6);
+select sys_trx_start into @tmp1 from t1;
+update t1 set x= 11, y= 11 where id = 1;
+select @tmp1 < sys_trx_start as A1, x, y from t1;
+A1 x y
+1 11 11
+select sys_trx_start into @tmp1 from t1;
+update t1 set y= 1 where id = 1;
+select @tmp1 = sys_trx_start as A2, x from t1;
+A2 x
+1 11
+drop table t1;
+create table t1 (
+x int,
+y int,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end)
+) with system versioning;
+insert into t1 (x, y) values (1, 1), (2, 1), (3, 1), (4, 1), (5, 1);
+start transaction;
+update t1 set y= y + 1 where x = 3;
+update t1 set y= y + 1 where x = 2;
+update t1 set y= y + 1 where x = 3;
+update t1 set y= y + 1 where x > 3;
+update t1 set y= y + 1 where x > 4;
+commit;
+select x, y, sys_trx_end = MAXVAL as current from t1 for system_time all;
+x y current
+1 1 1
+2 2 1
+3 3 1
+4 2 1
+5 3 1
+3 1 0
+2 1 0
+3 2 0
+4 1 0
+5 1 0
+5 2 0
+drop table t1;
+create table t1 (
+id int primary key auto_increment,
+x int,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+set @t0= now(6);
+insert into t1 (x) values (1);
+set @t1= now(6);
+update t1 set x= 2 where id = 1;
+set @t2= now(6);
+update t1 set x= 3 where id = 1;
+select x from t1 for system_time as of timestamp @t0;
+x
+select x from t1 for system_time as of timestamp @t1;
+x
+1
+select x from t1 for system_time as of timestamp @t2;
+x
+2
+select x from t1 for system_time as of timestamp now(6);
+x
+3
+drop table t1;
+create table t1(
+x int unsigned,
+sys_trx_end SYS_DATATYPE as row end invisible,
+sys_trx_start SYS_DATATYPE as row start invisible,
+y int unsigned,
+period for system_time (sys_trx_start, sys_trx_end),
+primary key(x, y))
+with system versioning;
+insert into t1(x, y) values (1, 1000), (3, 3000), (4, 4000), (5, 5000);
+insert into t1(x, y) values(3, 3000) on duplicate key update y = y+1;
+insert into t1(x, y) values(4, 4444) on duplicate key update y = y+1;
+select x, y from t1 for system_time all;
+x y
+1 1000
+3 3000
+3 3001
+4 4000
+4 4444
+5 5000
+select x, y from t1;
+x y
+1 1000
+3 3001
+4 4000
+4 4444
+5 5000
+drop table t1;
+create table t1 (
+x int unsigned,
+y int unsigned,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+create table t2 like t1;
+insert into t1(x, y) values (1, 1000), (2, 2000), (3, 3000), (4, 4000), (5, 5000), (6, 6000), (7, 7000), (8, 8000), (9, 9000);
+insert into t2(x, y) values (1, 1010), (2, 2010), (3, 3010), (4, 4010), (5, 5010), (6, 6010), (7, 7010), (8, 8010), (9, 9010);
+update t1, t2 set t1.y = t1.x + t1.y, t2.y = t2.x + t2.y where t1.x > 7 and t2.x < 7;
+select x, y from t1 for system_time all;
+x y
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8008
+9 9009
+8 8000
+9 9000
+select x, y from t1;
+x y
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8008
+9 9009
+select x, y from t2 for system_time all;
+x y
+1 1011
+2 2012
+3 3013
+4 4014
+5 5015
+6 6016
+7 7010
+8 8010
+9 9010
+1 1010
+2 2010
+3 3010
+4 4010
+5 5010
+6 6010
+select x, y from t2;
+x y
+1 1011
+2 2012
+3 3013
+4 4014
+5 5015
+6 6016
+7 7010
+8 8010
+9 9010
+drop table t1;
+drop table t2;
+create table t1 (
+id bigint primary key without system versioning,
+name varchar(128),
+salary bigint without system versioning,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+create table t2 like t1;
+insert into t1 values (1, "Jeremy", 3000);
+insert into t2 values (1, "Jeremy", 4000);
+select sys_trx_start into @tmp1 from t1;
+select sys_trx_start into @tmp2 from t2;
+update t1, t2 set t1.name= "Jerry", t2.name= "Jerry" where t1.id = t2.id and t1.name = "Jeremy";
+select @tmp1 < sys_trx_start as A1, name from t1;
+A1 name
+1 Jerry
+select @tmp2 < sys_trx_start as A2, name from t2;
+A2 name
+1 Jerry
+select sys_trx_start into @tmp1 from t1;
+select sys_trx_start into @tmp2 from t2;
+update t1, t2 set t1.salary= 2500, t2.salary= 2500 where t1.id = t2.id and t1.name = "Jerry";
+select @tmp1 = sys_trx_start as B1, salary from t1;
+B1 salary
+1 2500
+select @tmp2 = sys_trx_start as B2, salary from t2;
+B2 salary
+1 2500
+drop table t1;
+drop table t2;
diff --git a/mysql-test/suite/versioning/r/update2.result b/mysql-test/suite/versioning/r/update2.result
new file mode 100644
index 00000000000..73e6c5b393d
--- /dev/null
+++ b/mysql-test/suite/versioning/r/update2.result
@@ -0,0 +1,21 @@
+### Issue #365, bug 7 (duplicate of historical row)
+create or replace table t1 (a int primary key, b int)
+with system versioning engine myisam;
+insert into t1 (a) values (1);
+replace t1 values (1,2),(1,3),(2,4);
+create or replace table t1 (pk int, a char(3), b char(3), primary key(pk))
+engine=innodb with system versioning;
+insert into t1 (pk) values (1);
+connect con1,localhost,root,,test;
+start transaction;
+select * from t1 for update;
+pk a b
+1 NULL NULL
+connection default;
+update t1 set b = 'foo';
+connection con1;
+update t1 set a = 'bar';
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+disconnect con1;
+connection default;
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/view.result b/mysql-test/suite/versioning/r/view.result
new file mode 100644
index 00000000000..3a85f918623
--- /dev/null
+++ b/mysql-test/suite/versioning/r/view.result
@@ -0,0 +1,137 @@
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+select now(6) into @t1;
+update t1 set x= 2;
+select now(6) into @t2;
+delete from t1;
+set @vt1= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'");
+prepare stmt from @vt1;
+execute stmt;
+drop prepare stmt;
+set @vt2= concat("create or replace view vt2 as select *, row_end from t1 for system_time as of timestamp '", @t2, "'");
+prepare stmt from @vt2;
+execute stmt;
+drop prepare stmt;
+select * from t1;
+x
+create or replace view vt1 as select * from t1;
+show create view vt1;
+View Create View character_set_client collation_connection
+vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x` from `t1` latin1 latin1_swedish_ci
+drop view vt1;
+drop view vt2;
+create or replace view vt1 as select * from t1 for system_time all;
+select * from vt1;
+x
+2
+1
+prepare stmt from 'select * from vt1';
+execute stmt;
+x
+2
+1
+drop prepare stmt;
+set @str= concat('create or replace view vt1 as
+select * from t1 for system_time as of timestamp "', @t1, '"');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+select * from t1 for system_time as of timestamp @t1;
+x
+1
+select * from vt1;
+x
+1
+insert into vt1 values (3);
+select * from t1;
+x
+3
+select * from vt1;
+x
+1
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1), (2);
+set @t1=now(6);
+delete from t1 where x=2;
+set @t2=now(6);
+delete from t1 where x=1;
+set @t3=now(6);
+set @tmp= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'");
+prepare stmt from @tmp;
+execute stmt;
+drop prepare stmt;
+select * from vt1;
+x
+1
+2
+# VIEW with parameters [#151]
+create or replace table t1 (x int) with system versioning;
+create or replace view vt1(c) as select x from t1;
+show create view vt1;
+View Create View character_set_client collation_connection
+vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `c` from `t1` latin1 latin1_swedish_ci
+# VIEW over JOIN of versioned tables [#153]
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int) with system versioning;
+insert into t1 values (1);
+insert into t2 values (2);
+create or replace view vt12 as select * from t1 cross join t2;
+select * from vt12;
+a b
+1 2
+create or replace view vt12 as select * from t1 for system_time as of timestamp ('0-0-0') cross join t2;
+select * from vt12;
+a b
+# VIEW improvements [#183]
+create or replace table t3 (x int);
+create or replace view vt1 as select * from t1, t2, t3;
+show create view vt1;
+View Create View character_set_client collation_connection
+vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b`,`t3`.`x` AS `x` from ((`t1` join `t2`) join `t3`) latin1 latin1_swedish_ci
+create or replace view vt1 as select * from t3, t2, t1;
+show create view vt1;
+View Create View character_set_client collation_connection
+vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t3`.`x` AS `x`,`t2`.`b` AS `b`,`t1`.`a` AS `a` from ((`t3` join `t2`) join `t1`) latin1 latin1_swedish_ci
+create or replace view vt1 as select a, t2.row_end as endo from t3, t1, t2;
+show create view vt1;
+View Create View character_set_client collation_connection
+vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`row_end` AS `endo` from ((`t3` join `t1`) join `t2`) latin1 latin1_swedish_ci
+# VIEW over UNION [#269]
+create or replace view vt1 as select * from t1 union select * from t1;
+select * from vt1;
+a
+1
+# VIEW over UNION with non-versioned [#393]
+create or replace table t2 (a int);
+create or replace view vt1 as select * from t1 union select * from t2;
+select * from vt1;
+a
+1
+# MDEV-14689 crash on second PS execute
+create or replace table t1 (a int);
+create or replace view v1 as select * from t1;
+create or replace table t2 (b int) with system versioning;
+prepare stmt from 'select a from v1 inner join t2 group by a order by a';
+execute stmt;
+a
+execute stmt;
+a
+drop database test;
+create database test;
+use test;
+create table t1 (a int) with system versioning;
+insert t1 values (1),(2);
+set @a=now(6);
+create view v1 as select * from t1;
+delete from t1;
+select * from v1;
+a
+select * from v1 for system_time as of @a;
+a
+1
+2
+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`.`a` AS `a` from `t1` latin1 latin1_swedish_ci
+drop view v1;
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/vtmd.result b/mysql-test/suite/versioning/r/vtmd.result
new file mode 100644
index 00000000000..ece5f5af61a
--- /dev/null
+++ b/mysql-test/suite/versioning/r/vtmd.result
@@ -0,0 +1,365 @@
+create or replace procedure drop_archives (in vtmd_name varchar(64))
+begin
+declare archive_name varchar(64);
+declare cur_done bool default false;
+declare cur cursor for
+select cur_tmp.archive_name from cur_tmp;
+declare continue handler for not found set cur_done = true;
+set @tmp= concat('
+ create or replace temporary table
+ cur_tmp as
+ select vtmd.archive_name from ', vtmd_name, '
+ for system_time all as vtmd
+ where vtmd.archive_name is not null
+ group by vtmd.archive_name');
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+open cur;
+fetch_loop: loop
+fetch cur into archive_name;
+if cur_done then
+leave fetch_loop;
+end if;
+set @tmp= concat('drop table ', archive_name);
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+end loop;
+drop table cur_tmp;
+end~~
+create or replace procedure check_vtmd (in vtmd_name varchar(64))
+begin
+set @tmp= concat('
+ create or replace temporary table
+ tmp_vtmd with system versioning as
+ select * from ', vtmd_name, '
+ for system_time all as vtmd');
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+set @inf= 0xFFFFFFFFFFFFFFFF + 0;
+set @start= null;
+select start from tmp_vtmd for system_time all order by start limit 1 into @start;
+select @start > 0 and @start < @inf;
+select
+start >= @start as A_start,
+(@start:= end) and end = @inf as B_end,
+name,
+substr(archive_name, 1, instr(archive_name, '_')) as C_archive_name
+from tmp_vtmd for system_time all;
+drop table tmp_vtmd;
+end~~
+create or replace procedure show_tables()
+begin
+show tables;
+select table_name, table_schema from information_schema.tables
+where table_schema not in ('mysql', 'performance_schema', 'information_schema', 'mtr')
+order by table_name;
+end~~
+set versioning_alter_history= keep;
+create table t0 (z int) with system versioning;
+show tables;
+Tables_in_test
+t0
+set versioning_alter_history= survive;
+create or replace table t0 (y int) with system versioning;
+show tables;
+Tables_in_test
+t0
+t0_vtmd
+show create table t0_vtmd;
+Table Create Table
+t0_vtmd CREATE TABLE `t0_vtmd` (
+ `start` bigint(20) unsigned GENERATED ALWAYS AS ROW START COMMENT 'TRX_ID of table lifetime start',
+ `end` bigint(20) unsigned GENERATED ALWAYS AS ROW END NOT NULL COMMENT 'TRX_ID of table lifetime end',
+ `name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT 'Table name during current lifetime period',
+ `archive_name` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'Name of archive table',
+ `col_renames` blob DEFAULT NULL COMMENT 'Column name mappings from previous lifetime',
+ PRIMARY KEY (`end`),
+ KEY `archive_name` (`archive_name`),
+ PERIOD FOR SYSTEM_TIME (`start`, `end`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0 WITH SYSTEM VERSIONING
+call check_vtmd('t0_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 1 t0 NULL
+set versioning_alter_history= keep;
+drop table t0;
+set versioning_alter_history= survive;
+create table t0 (x int) with system versioning;
+ERROR HY000: VTMD error: `test.t0_vtmd` exists and not empty!
+drop table t0_vtmd;
+create table t0 (y int) with system versioning;
+create or replace table t0 (x int) with system versioning;
+insert into t0 values (1);
+set @t0= now(6);
+alter table t0 add column (y int);
+select * from t0 for system_time as of @t0;
+x
+1
+select * from t0;
+x y
+1 NULL
+call check_vtmd('t0_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 0 t0 t0_
+1 0 t0 t0_
+1 1 t0 NULL
+call drop_archives('t0_vtmd');
+drop table t0_vtmd;
+alter table t0 drop column y;
+call check_vtmd('t0_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 1 t0 t0_
+call drop_archives('t0_vtmd');
+set versioning_alter_history= keep;
+drop tables t0, t0_vtmd;
+set versioning_alter_history= survive;
+set versioning_alter_history= keep;
+create or replace table x0 (x int) with system versioning;
+set versioning_alter_history= survive;
+rename table x0 to d0;
+show tables;
+Tables_in_test
+d0
+set versioning_alter_history= keep;
+drop table d0;
+set versioning_alter_history= survive;
+create or replace table x0 (x int) with system versioning;
+rename table x0 to d0;
+show tables;
+Tables_in_test
+d0
+d0_vtmd
+call check_vtmd('d0_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 0 x0 NULL
+1 1 d0 NULL
+set versioning_alter_history= keep;
+drop table d0;
+set versioning_alter_history= survive;
+create or replace table x0 (x int) with system versioning;
+rename table x0 to d0;
+ERROR HY000: VTMD error: `test.d0_vtmd` table already exists!
+show tables;
+Tables_in_test
+d0_vtmd
+x0
+x0_vtmd
+drop table x0_vtmd;
+rename table x0 to d0;
+Warnings:
+Warning 4122 `test.d0_vtmd` table already exists!
+show tables;
+Tables_in_test
+d0
+d0_vtmd
+rename table d0 to duck;
+rename table duck to bay;
+rename table bay to sheer;
+rename table sheer to t0;
+call check_vtmd('t0_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 0 x0 NULL
+1 0 d0 NULL
+1 0 duck NULL
+1 0 bay NULL
+1 0 sheer NULL
+1 1 t0 NULL
+alter table t0 add column (y int);
+call check_vtmd('t0_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 0 x0 t0_
+1 0 d0 t0_
+1 0 duck t0_
+1 0 bay t0_
+1 0 sheer t0_
+1 0 t0 t0_
+1 1 t0 NULL
+alter table t0 add column (z int);
+alter table t0 drop column y;
+alter table t0 drop column z;
+create database db0;
+rename table t0 to db0.t0;
+show tables;
+Tables_in_test
+use db0;
+show tables;
+Tables_in_db0
+t0
+t0_vtmd
+call test.check_vtmd('db0.t0_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 0 x0 t0_
+1 0 d0 t0_
+1 0 duck t0_
+1 0 bay t0_
+1 0 sheer t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 1 t0 NULL
+create database db1;
+rename table t0 to db1.other_name;
+show tables;
+Tables_in_db0
+use db1;
+show tables;
+Tables_in_db1
+other_name
+other_name_vtmd
+call test.check_vtmd('db1.other_name_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 0 x0 t0_
+1 0 d0 t0_
+1 0 duck t0_
+1 0 bay t0_
+1 0 sheer t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 NULL
+1 1 other_name NULL
+alter table other_name rename to t1;
+call test.check_vtmd('db1.t1_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 0 x0 t0_
+1 0 d0 t0_
+1 0 duck t0_
+1 0 bay t0_
+1 0 sheer t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 NULL
+1 0 other_name NULL
+1 1 t1 NULL
+alter table t1 rename to test.t2, add column (y int);
+use test;
+show tables;
+Tables_in_test
+t2
+t2_vtmd
+call check_vtmd('t2_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 0 x0 t0_
+1 0 d0 t0_
+1 0 duck t0_
+1 0 bay t0_
+1 0 sheer t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 t0_
+1 0 t0 t1_
+1 0 other_name t1_
+1 0 t1 t1_
+1 1 t2 NULL
+create or replace table t3 (x int) with system versioning;
+alter table t3 change x x bigint;
+alter table t3 change x x bigint after sys_trx_start;
+call check_vtmd('t3_vtmd');
+@start > 0 and @start < @inf
+1
+A_start B_end name C_archive_name
+1 0 t3 t3_
+1 0 t3 t3_
+1 1 t3 NULL
+set versioning_hide= auto;
+call show_tables();
+Tables_in_test
+t2
+t2_vtmd
+t3
+t3_vtmd
+table_name table_schema
+t2 test
+t2_vtmd test
+t3 test
+t3_vtmd test
+set versioning_hide= implicit;
+call show_tables();
+Tables_in_test
+t2
+t2_vtmd
+t3
+t3_vtmd
+table_name table_schema
+t2 test
+t2_vtmd test
+t3 test
+t3_vtmd test
+set versioning_hide= full;
+call show_tables();
+Tables_in_test
+t2
+t2_vtmd
+t3
+t3_vtmd
+table_name table_schema
+t2 test
+t2_vtmd test
+t3 test
+t3_vtmd test
+set versioning_hide= never;
+call show_tables();
+Tables_in_test
+t0_TIMESTAMP_SUFFIX
+t0_TIMESTAMP_SUFFIX
+t0_TIMESTAMP_SUFFIX
+t0_TIMESTAMP_SUFFIX
+t2
+t2_vtmd
+t3
+t3_TIMESTAMP_SUFFIX
+t3_TIMESTAMP_SUFFIX
+t3_vtmd
+table_name table_schema
+t0_TIMESTAMP_SUFFIX test
+t0_TIMESTAMP_SUFFIX test
+t0_TIMESTAMP_SUFFIX test
+t0_TIMESTAMP_SUFFIX test
+t1_TIMESTAMP_SUFFIX db1
+t2 test
+t2_vtmd test
+t3 test
+t3_TIMESTAMP_SUFFIX test
+t3_TIMESTAMP_SUFFIX test
+t3_vtmd test
+set versioning_hide= auto;
+create or replace table u0_vtmd (x int) with system versioning;
+show tables;
+Tables_in_test
+t2
+t2_vtmd
+t3
+t3_vtmd
+u0_vtmd
+u0_vtmd_vtmd
+Warnings:
+Warning 4122 Table `test.u0_vtmd` is not a VTMD table
+set versioning_alter_history= survive;
+create or replace table t (x int) with system versioning;
+select * from t for system_time all;
+x sys_trx_start sys_trx_end
+drop database db0;
+drop database db1;
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/r/vtmd_show.result b/mysql-test/suite/versioning/r/vtmd_show.result
new file mode 100644
index 00000000000..4c77182c5de
--- /dev/null
+++ b/mysql-test/suite/versioning/r/vtmd_show.result
@@ -0,0 +1,229 @@
+create or replace procedure drop_archives (in vtmd_name varchar(64))
+begin
+declare archive_name varchar(64);
+declare cur_done bool default false;
+declare cur cursor for
+select cur_tmp.archive_name from cur_tmp;
+declare continue handler for not found set cur_done = true;
+set @tmp= concat('
+ create or replace temporary table
+ cur_tmp as
+ select vtmd.archive_name from ', vtmd_name, '
+ for system_time all as vtmd
+ where vtmd.archive_name is not null
+ group by vtmd.archive_name');
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+open cur;
+fetch_loop: loop
+fetch cur into archive_name;
+if cur_done then
+leave fetch_loop;
+end if;
+set @tmp= concat('drop table ', archive_name);
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+end loop;
+drop table cur_tmp;
+end~~
+create procedure test_01(in engine varchar(64))
+begin
+set @tmp = concat('create table t (a int) with system versioning engine ', engine);
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+set @tm1 = now(6);
+alter table t add column b int;
+set @tm2 = now(6);
+alter table t add column c int;
+show create table t for system_time as of timestamp @tm1;
+show create table t for system_time as of timestamp @tm2;
+show create table t for system_time as of now;
+show create table t for system_time as of timestamp now(6);
+show create table t;
+set @tm3 = now(6);
+rename table t to tt;
+show create table tt for system_time as of timestamp @tm3;
+set @tm4 = now(6);
+alter table tt add column d int;
+show create table tt for system_time as of timestamp @tm3;
+show create table tt for system_time as of timestamp @tm4;
+show create table tt;
+drop table tt;
+call drop_archives('tt_vtmd');
+drop table tt_vtmd;
+end~~
+create table t (a int) with system versioning;
+show create table t for system_time as of now;
+ERROR HY000: VTMD error: Table 'test.t_vtmd' doesn't exist
+set versioning_alter_history=survive;
+create or replace table t (a int) with system versioning;
+show create table t for system_time between timestamp @tm1 and timestamp @tm1;
+ERROR HY000: SYSTEM_TIME range selector is prohibited
+show create table t for system_time from timestamp @tm1 to timestamp @tm1;
+ERROR HY000: SYSTEM_TIME range selector is prohibited
+show create table t for system_time as of timestamp '01-01-1990';
+ERROR HY000: VTMD error: Table 'test.t' doesn't exist
+show create table t for system_time as of timestamp '01-01-2020';
+ERROR HY000: VTMD error: Table 'test.t' doesn't exist
+drop table t;
+call drop_archives('t_vtmd');
+drop table t_vtmd;
+call test_01('myisam');
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+tt CREATE TABLE `tt` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+tt CREATE TABLE `tt` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+tt CREATE TABLE `tt` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+tt CREATE TABLE `tt` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+call test_01('innodb');
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+tt CREATE TABLE `tt` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+tt CREATE TABLE `tt` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+tt CREATE TABLE `tt` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+Table Create Table
+tt CREATE TABLE `tt` (
+ `a` int(11) DEFAULT NULL,
+ `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
+ `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+drop procedure test_01;
+drop procedure drop_archives;
diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test
new file mode 100644
index 00000000000..128397b6cc8
--- /dev/null
+++ b/mysql-test/suite/versioning/t/alter.test
@@ -0,0 +1,443 @@
+select @@system_versioning_alter_history;
+
+create table t(
+ a int
+);
+show create table t;
+--error ER_VERS_NOT_VERSIONED
+alter table t drop system versioning;
+
+alter table t add system versioning;
+show create table t;
+
+--error ER_VERS_ALTER_NOT_ALLOWED
+alter table t add column y int;
+--error ER_VERS_ALTER_ENGINE_PROHIBITED
+alter table t engine innodb;
+
+alter table t drop system versioning;
+show create table t;
+
+set system_versioning_alter_history= keep;
+
+alter table t add system versioning;
+--error ER_CANT_DROP_FIELD_OR_KEY
+alter table t drop system versioning, drop column row_start;
+alter table t drop system versioning;
+
+--error ER_VERS_FIELD_WRONG_TYPE
+alter table t
+ add column trx_start bigint(20) unsigned as row start invisible,
+ add column trx_end bigint(20) unsigned as row end invisible,
+ add period for system_time(trx_start, trx_end),
+ add system versioning;
+
+--error ER_VERS_FIELD_WRONG_TYPE
+alter table t
+ add column trx_start timestamp as row start invisible,
+ add column trx_end timestamp as row end invisible,
+ add period for system_time(trx_start, trx_end),
+ add system versioning;
+
+--error ER_PARSE_ERROR
+alter table t
+ add column trx_start timestamp(6) not null as row start invisible,
+ add column trx_end timestamp(6) not null as row end invisible,
+ add period for system_time(trx_start, trx_end),
+ add system versioning;
+
+alter table t
+ add column trx_start timestamp(6) as row start invisible,
+ add column trx_end timestamp(6) as row end invisible,
+ add period for system_time(trx_start, trx_end),
+ add system versioning;
+show create table t;
+
+--error ER_MISSING
+alter table t drop system versioning;
+
+alter table t drop column trx_start, drop column trx_end;
+select row_start from t;
+alter table t drop system versioning;
+show create table t;
+
+--error ER_VERS_NOT_VERSIONED
+alter table t add column trx_start timestamp(6) as row start;
+
+alter table t add system versioning;
+show create table t;
+
+alter table t add column b int;
+show create table t;
+
+alter table t add column c int;
+show create table t;
+
+alter table t add column d int first;
+show create table t;
+
+alter table t add column e int after d;
+show create table t;
+
+alter table t drop column a;
+show create table t;
+
+create or replace table t (
+ a int,
+ row_start timestamp(6) as row start invisible,
+ row_end timestamp(6) as row end invisible,
+ period for system_time(row_start, row_end))
+with system versioning;
+
+select * from t for system_time all;
+--error ER_MISSING
+alter table t drop column row_start;
+--error ER_MISSING
+alter table t drop column row_end;
+alter table t drop column row_start, drop column row_end;
+select * from t for system_time all;
+show create table t;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+alter table t drop column row_start;
+--error ER_CANT_DROP_FIELD_OR_KEY
+alter table t drop column row_end;
+
+create or replace table t (
+ a int,
+ row_start timestamp(6) as row start invisible,
+ row_end timestamp(6) as row end invisible,
+ period for system_time(row_start, row_end))
+with system versioning;
+
+select * from t for system_time all;
+alter table t drop column row_start, drop column row_end;
+select * from t for system_time all;
+
+create or replace table t(
+ a int
+);
+insert into t values(1);
+alter table t add system versioning;
+show create table t;
+insert into t values(2);
+select * from t for system_time all;
+select * from t;
+
+update t set a=3 where a=1;
+select * from t;
+select * from t for system_time all;
+select row_start from t where a=3 into @tm;
+alter table t add column b int;
+select @tm=row_start from t where a=3;
+show create table t;
+select * from t;
+select * from t for system_time all;
+
+alter table t drop system versioning;
+select * from t;
+show create table t;
+
+--error ER_VERS_NOT_VERSIONED
+alter table t modify a int with system versioning;
+--error ER_VERS_NOT_VERSIONED
+alter table t modify a int without system versioning;
+
+alter table t add system versioning;
+
+alter table t modify a int without system versioning;
+show create table t;
+
+alter table t modify a int with system versioning;
+show create table t;
+
+# TODO: move TRX_ID cases to separate test
+-- source suite/versioning/common.inc
+create or replace table t(
+ a int
+) engine=innodb;
+
+alter table t
+ add column trx_start timestamp(6) as row start invisible,
+ add column trx_end timestamp(6) as row end invisible,
+ add period for system_time(trx_start, trx_end),
+ add system versioning;
+
+show create table t;
+--echo # Issue #211: drop of system columns required before drop system versioning
+alter table t drop column trx_start, drop column trx_end;
+show create table t;
+
+alter table t drop system versioning;
+
+insert into t values(1);
+
+call verify_vtq;
+alter table t
+ add column trx_start bigint(20) unsigned as row start invisible,
+ add column trx_end bigint(20) unsigned as row end invisible,
+ add period for system_time(trx_start, trx_end),
+ add system versioning;
+call verify_vtq;
+
+show create table t;
+alter table t drop column trx_start, drop column trx_end;
+
+call verify_vtq;
+alter table t drop system versioning, algorithm=copy;
+call verify_vtq;
+
+alter table t add system versioning, algorithm=copy;
+call verify_vtq;
+
+show create table t;
+
+update t set a= 2;
+select * from t for system_time all;
+
+alter table t add column b int, algorithm=copy;
+show create table t;
+select * from t;
+call verify_vtq;
+
+alter table t drop column b, algorithm=copy;
+show create table t;
+select * from t for system_time all;
+call verify_vtq;
+
+## FIXME: #414 IB: inplace for VERS_TIMESTAMP versioning
+if (0)
+{
+alter table t drop system versioning, algorithm=inplace;
+call verify_vtq;
+
+alter table t add system versioning, algorithm=inplace;
+call verify_vtq;
+show create table t;
+
+update t set a= 1;
+select * from t for system_time all;
+call verify_vtq;
+
+alter table t add column b int, algorithm=inplace;
+show create table t;
+select * from t;
+call verify_vtq;
+
+alter table t drop column b, algorithm=inplace;
+show create table t;
+select * from t for system_time all;
+}
+## FIXME END
+
+alter table t drop system versioning, algorithm=copy;
+show create table t;
+call verify_vtq;
+
+# nullable autoinc test w/o versioning
+create or replace table t (a int);
+insert t values (1),(2),(3),(4);
+alter table t add b int auto_increment null unique;
+select * from t;
+drop table t;
+
+create or replace table t (a int) with system versioning engine=innodb;
+insert into t values (1), (2), (3);
+delete from t where a<3;
+--error ER_DUP_ENTRY, ER_DUP_ENTRY
+alter table t add b int not null unique;
+--error ER_UNSUPPORTED_EXTENSION, ER_UNSUPPORTED_EXTENSION
+alter table t add b int auto_increment unique;
+alter table t add b int auto_increment null unique;
+select * from t;
+select * from t for system_time all;
+insert into t values (4, 0);
+select * from t for system_time all;
+
+create or replace table t (a int) with system versioning;
+insert into t values (1), (2), (3);
+delete from t where a<3;
+--error ER_DUP_ENTRY, ER_DUP_ENTRY
+alter table t add b int not null unique;
+--error ER_UNSUPPORTED_EXTENSION, ER_UNSUPPORTED_EXTENSION
+alter table t add b int auto_increment unique;
+alter table t add b int auto_increment null unique;
+select * from t;
+select * from t for system_time all;
+insert into t values (4, 0);
+select * from t for system_time all;
+
+create or replace table t (a int, b int primary key, c int unique) with system versioning;
+insert t values (1,2,3),(1,3,4),(1,4,5);
+alter table t drop system versioning;
+show create table t;
+select * from t;
+
+create or replace table t (
+ a int,
+ row_start timestamp(6) as row start invisible,
+ row_end timestamp(6) as row end invisible,
+ period for system_time(row_start, row_end)
+) with system versioning;
+--error ER_VERS_ALTER_SYSTEM_FIELD
+alter table t change column row_start asdf timestamp(6);
+insert into t values (1);
+--error ER_VERS_ALTER_SYSTEM_FIELD
+alter table t modify column row_start bigint unsigned;
+
+## These experimental options are now disabled
+
+--error ER_WRONG_VALUE_FOR_VAR
+set system_versioning_alter_history= SURVIVE;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set system_versioning_alter_history= 'DROP';
+
+if (0)
+{
+create or replace table t (a int) with system versioning engine innodb;
+insert into t values (1);
+update t set a = 2;
+select * from t for system_time all;
+alter table t add column b int;
+select * from t for system_time all;
+
+create or replace table t (a int) with system versioning engine myisam;
+insert into t values (1);
+update t set a = 2;
+select * from t for system_time all;
+alter table t add column b int;
+select * from t for system_time all;
+
+create or replace table non_empty (
+ a int,
+ row_start bigint(20) unsigned,
+ row_end bigint(20) unsigned
+) engine innodb;
+insert into non_empty values (1, 100, 200);
+
+--error ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN
+alter table non_empty
+ change column row_start row_start bigint(20) unsigned as row start invisible;
+--error ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN
+alter table non_empty
+ change column row_end row_end bigint(20) unsigned as row end invisible;
+drop table non_empty;
+
+create or replace table t (a int primary key) with system versioning;
+insert into t values (1);
+update t set a=2;
+alter table t drop primary key, add primary key (a), drop system versioning;
+select * from t;
+--replace_result InnoDB INNODB_OR_MYISAM MyISAM INNODB_OR_MYISAM
+show create table t;
+
+create or replace table t (a int primary key) with system versioning;
+insert into t values (1);
+update t set a=2;
+alter table t drop system versioning;
+select * from t;
+--replace_result InnoDB INNODB_OR_MYISAM MyISAM INNODB_OR_MYISAM
+show create table t;
+
+
+call verify_vtq;
+}
+
+create or replace table t (a int) with system versioning;
+--error ER_VERS_ALREADY_VERSIONED
+alter table t add system versioning;
+--error ER_VERS_ALREADY_VERSIONED
+alter table t add system versioning, drop system versioning;
+
+set @@system_versioning_alter_history=keep;
+create or replace table t(x int, y int) with system versioning engine=innodb;
+alter table t modify y int without system versioning;
+insert into t values(1, 1);
+update t set y=2;
+
+--echo # MDEV-14681 Bogus ER_UNSUPPORTED_EXTENSION
+create or replace table t1 (pk int auto_increment unique) with system versioning;
+insert into t1 values (1);
+delete from t1;
+alter table t1 engine=myisam;
+
+--echo # MDEV-14692 crash in MDL_context::upgrade_shared_lock()
+create or replace temporary table t (a int);
+--error ER_VERS_TEMPORARY
+alter table t change column if exists b c bigint unsigned generated always as row start;
+--error ER_VERS_TEMPORARY
+alter table t change column if exists b c bigint unsigned generated always as row end;
+--error ER_VERS_TEMPORARY
+alter table t add system versioning;
+drop table t;
+
+--echo # MDEV-14744 trx_id-based and transaction-based mixup in assertion
+create or replace table t (c text) engine=innodb with system versioning;
+show create table t;
+alter table t add fulltext key (c);
+
+create or replace table t (a int) with system versioning;
+--error ER_VERS_TABLE_MUST_HAVE_COLUMNS
+alter table t drop column a;
+--error ER_CANT_DROP_FIELD_OR_KEY
+alter table t drop column a, drop column a;
+
+create or replace table t1 (row_start int);
+--error ER_DUP_FIELDNAME
+alter table t1 with system versioning;
+
+create or replace table t1 (row_end int);
+--error ER_DUP_FIELDNAME
+alter table t1 with system versioning;
+
+--error ER_DUP_FIELDNAME
+create or replace table t1 (a int, row_start int) with system versioning;
+
+create or replace table t1 (a int) with system versioning;
+
+--error ER_DUP_FIELDNAME
+set statement system_versioning_alter_history=keep for
+alter table t1 add column row_start int;
+
+--error ER_DUP_FIELDNAME
+set statement system_versioning_alter_history=keep for
+alter table t1 add column row_start timestamp(6);
+
+--echo # MDEV-14798 Add, drop system versioning semantic and syntax
+create or replace table t (
+ a int,
+ row_start timestamp(6) generated always as row start,
+ row_end timestamp(6) generated always as row end,
+ period for system_time(row_start, row_end)
+) with system versioning;
+show create table t;
+
+alter table t
+ drop column row_start,
+ drop column row_end,
+ drop period for system_time,
+ drop system versioning;
+show create table t;
+
+--error ER_VERS_NOT_VERSIONED
+alter table t drop period for system_time;
+
+create or replace table t (
+ a int,
+ row_start timestamp(6) generated always as row start,
+ row_end timestamp(6) generated always as row end,
+ period for system_time(row_start, row_end)
+) with system versioning;
+--error ER_MISSING
+alter table t drop period for system_time;
+--error ER_MISSING
+alter table t drop column sys_trx_start, drop period for system_time;
+--error ER_MISSING
+alter table t drop column sys_trx_end, drop period for system_time;
+
+--error ER_VERS_ALREADY_VERSIONED
+alter table t add period for system_time(sys_trx_start, sys_trx_end);
+
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/t/auto_increment.test b/mysql-test/suite/versioning/t/auto_increment.test
new file mode 100644
index 00000000000..804c0424179
--- /dev/null
+++ b/mysql-test/suite/versioning/t/auto_increment.test
@@ -0,0 +1,50 @@
+-- source suite/versioning/engines.inc
+-- source suite/versioning/common.inc
+
+--replace_result $sys_datatype_expl SYS_DATATYPE
+eval create table t1(
+ id int unsigned auto_increment primary key,
+ x int unsigned,
+ y int unsigned,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_start, sys_end))
+ with system versioning;
+
+eval create table t2(
+ id int unsigned auto_increment primary key,
+ x int unsigned,
+ y int unsigned);
+
+insert into t1(x, y) values(1, 11);
+insert into t2(x, y) values(1, 11);
+insert into t1(x, y) values(2, 12);
+insert into t2(x, y) values(2, 12);
+insert into t1(x, y) values(3, 13);
+insert into t2(x, y) values(3, 13);
+insert into t1(x, y) values(4, 14);
+insert into t2(x, y) values(4, 14);
+insert into t1(x, y) values(5, 15);
+insert into t2(x, y) values(5, 15);
+insert into t1(x, y) values(6, 16);
+insert into t2(x, y) values(6, 16);
+insert into t1(x, y) values(7, 17);
+insert into t2(x, y) values(7, 17);
+insert into t1(x, y) values(8, 18);
+insert into t2(x, y) values(8, 18);
+insert into t1(x, y) values(9, 19);
+insert into t2(x, y) values(9, 19);
+
+select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id;
+delete from t1 where x = 2;
+delete from t2 where x = 2;
+
+select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id;
+delete from t1 where x > 7;
+delete from t2 where x > 7;
+
+select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id;
+drop table t1;
+drop table t2;
+
+-- source suite/versioning/common_finish.inc
diff --git a/mysql-test/suite/versioning/t/commit_id.test b/mysql-test/suite/versioning/t/commit_id.test
new file mode 100644
index 00000000000..68d73416054
--- /dev/null
+++ b/mysql-test/suite/versioning/t/commit_id.test
@@ -0,0 +1,94 @@
+-- source suite/versioning/common.inc
+
+create table t1(
+ id int auto_increment primary key,
+ sys_trx_start bigint unsigned as row start invisible,
+ sys_trx_end bigint unsigned as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end)
+)
+with system versioning
+engine innodb;
+
+
+# VTQ_TRX_ID, VTQ_COMMIT_ID, VTQ_TRX_SEES #
+
+insert into t1 values ();
+
+--real_sleep 0.01
+set @ts0= now(6);
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx0;
+select transaction_id = @tx0 from mysql.transaction_registry
+order by transaction_id desc limit 1;
+
+set @ts1= now(6);
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx1;
+select transaction_id = @tx1 from mysql.transaction_registry
+order by transaction_id desc limit 1;
+
+set @ts2= now(6);
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx2;
+select transaction_id = @tx2 from mysql.transaction_registry
+order by transaction_id desc limit 1;
+
+set @ts3= now(6);
+
+select
+ vtq_trx_id(@ts0) < @tx0 as A,
+ vtq_trx_id(@ts0, true) = @tx0 as B,
+ vtq_trx_id(@ts1) = @tx0 as C,
+ vtq_trx_id(@ts1, true) = @tx1 as D,
+ vtq_trx_id(@ts2) = @tx1 as E,
+ vtq_trx_id(@ts2, true) = @tx2 as F,
+ vtq_trx_id(@ts3) = @tx2 as G,
+ vtq_trx_id(@ts3, true) is null as H;
+
+select
+ vtq_commit_id(@ts0) < @tx0 as A,
+ vtq_commit_id(@ts0, true) = vtq_commit_id(null, @tx0) as B,
+ vtq_commit_id(@ts1) = vtq_commit_id(null, @tx0) as C,
+ vtq_commit_id(@ts1, true) = vtq_commit_id(null, @tx1) as D,
+ vtq_commit_id(@ts2) = vtq_commit_id(null, @tx1) as E,
+ vtq_commit_id(@ts2, true) = vtq_commit_id(null, @tx2) as F,
+ vtq_commit_id(@ts3) = vtq_commit_id(null, @tx2) as G,
+ vtq_commit_id(@ts3, true) is null as H;
+
+select
+ vtq_trx_sees(@tx1, @tx0) as A,
+ not vtq_trx_sees(@tx0, @tx1) as B,
+ vtq_trx_sees_eq(@tx1, @tx1) as C,
+ not vtq_trx_sees(@tx1, @tx1) as D,
+ vtq_trx_sees(@tx2, 0) as E,
+ vtq_trx_sees(-1, @tx2) as F;
+
+select vtq_trx_sees(0, @tx2);
+
+# VTQ_ISO_LEVEL #
+
+set transaction isolation level read uncommitted;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx3;
+select isolation_level = 'READ-UNCOMMITTED' from mysql.transaction_registry where transaction_id = @tx3;
+
+set transaction isolation level read committed;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx4;
+select isolation_level = 'READ-COMMITTED' from mysql.transaction_registry where transaction_id = @tx4;
+
+set transaction isolation level serializable;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx5;
+select isolation_level = 'SERIALIZABLE' from mysql.transaction_registry where transaction_id = @tx5;
+
+set transaction isolation level repeatable read;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx6;
+select isolation_level = 'REPEATABLE-READ' from mysql.transaction_registry where transaction_id = @tx6;
+
+
+drop table t1;
+call verify_vtq;
+
+-- source suite/versioning/common_finish.inc
diff --git a/mysql-test/suite/versioning/t/create.test b/mysql-test/suite/versioning/t/create.test
new file mode 100644
index 00000000000..ce135e66ec9
--- /dev/null
+++ b/mysql-test/suite/versioning/t/create.test
@@ -0,0 +1,367 @@
+--source suite/versioning/engines.inc
+--source suite/versioning/common.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+--replace_result $default_engine DEFAULT_ENGINE $sys_datatype_expl SYS_DATATYPE NULL ''
+eval create table t1 (
+ x1 int unsigned,
+ Sys_start $sys_datatype_expl as row start invisible comment 'start',
+ Sys_end $sys_datatype_expl as row end invisible comment 'end',
+ period for system_time (Sys_start, Sys_end)
+) with system versioning;
+--replace_result $default_engine DEFAULT_ENGINE $sys_datatype_expl SYS_DATATYPE
+show create table t1;
+
+--query_vertical select table_catalog,table_schema,table_name,table_type,version,table_rows,avg_row_length,data_free,auto_increment,check_time,table_collation,checksum,create_options,table_comment from information_schema.tables where table_name='t1'
+--query_vertical select table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,character_maximum_length,character_octet_length,character_set_name,collation_name,column_key,extra,column_comment,is_generated,generation_expression from information_schema.columns where table_name='t1'
+
+--echo # Implicit fields test
+create or replace table t1 (
+ x2 int unsigned
+) with system versioning;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+
+--replace_result $default_engine DEFAULT_ENGINE
+--error ER_VERS_PERIOD_COLUMNS
+eval create or replace table t1 (
+ x3 int unsigned,
+ Sys_start timestamp(6) as row start invisible,
+ Sys_end timestamp(6) as row end invisible,
+ period for system_time (x, Sys_end)
+) with system versioning;
+
+--replace_result $default_engine DEFAULT_ENGINE
+--error ER_VERS_PERIOD_COLUMNS
+eval create or replace table t1 (
+ x4 int unsigned,
+ Sys_start timestamp(6) as row start invisible,
+ Sys_end2 timestamp(6) as row end invisible,
+ period for system_time (Sys_start, Sys_end)
+) with system versioning;
+
+--replace_result $default_engine DEFAULT_ENGINE
+--error ER_VERS_PERIOD_COLUMNS
+eval create or replace table t1 (
+ x5 int unsigned,
+ Sys_start timestamp(6) as row start invisible,
+ Sys_end timestamp(6) as row end invisible,
+ period for system_time (Sys_start, x)
+) with system versioning;
+
+--error ER_MISSING
+create or replace table t1 (
+ x6 int unsigned,
+ period for system_time (Sys_start, Sys_end)
+) with system versioning;
+
+--replace_result $default_engine DEFAULT_ENGINE
+--error ER_MISSING
+eval create or replace table t1 (
+ x7 int unsigned,
+ Sys_start timestamp(6) as row start invisible,
+ Sys_end timestamp(6) as row end invisible,
+ period for system_time (Sys_start, Sys_end)
+);
+
+--replace_result $default_engine DEFAULT_ENGINE
+--error ER_VERS_PERIOD_COLUMNS
+eval create or replace table t1 (
+ x8 int unsigned,
+ Sys_start timestamp(6) as row start invisible,
+ Sys_end timestamp(6) as row end invisible,
+ period for system_time (sys_insert, sys_remove)
+) with system versioning;
+
+--replace_result $default_engine DEFAULT_ENGINE
+--error ER_MISSING
+eval create or replace table t1 (
+ x9 int unsigned,
+ Sys_start timestamp(6) as row start invisible,
+ Sys_end timestamp(6) as row end invisible,
+ period for system_time (Sys_start, Sys_end)
+);
+
+--replace_result $default_engine DEFAULT_ENGINE
+--error ER_MISSING
+eval create or replace table t1 (
+ x10 int unsigned,
+ Sys_start timestamp(6) as row start invisible,
+ Sys_end timestamp(6) as row end invisible,
+ period for system_time (Sys_start, Sys_start)
+);
+
+--error ER_VERS_FIELD_WRONG_TYPE, ER_VERS_FIELD_WRONG_TYPE
+create or replace table t1 (
+ x11 int unsigned,
+ Sys_start bigint unsigned as row start invisible,
+ Sys_end timestamp(6) as row end invisible,
+ period for system_time (Sys_start, Sys_end)
+) with system versioning;
+
+--error ER_VERS_FIELD_WRONG_TYPE, ER_VERS_FIELD_WRONG_TYPE
+create or replace table t1 (
+ x12 int unsigned,
+ Sys_start timestamp(6) as row start invisible,
+ Sys_end bigint unsigned as row end invisible,
+ period for system_time (Sys_start, Sys_end)
+) with system versioning;
+
+--error ER_VERS_FIELD_WRONG_TYPE
+create or replace table t1 (
+ x13 int unsigned,
+ Sys_start bigint as row start invisible,
+ Sys_end bigint unsigned as row end invisible,
+ period for system_time (Sys_start, Sys_end)
+) with system versioning engine innodb;
+
+--error ER_VERS_FIELD_WRONG_TYPE
+create or replace table t1 (
+ x14 int unsigned,
+ Sys_start bigint unsigned as row start invisible,
+ Sys_end bigint as row end invisible,
+ period for system_time (Sys_start, Sys_end)
+) with system versioning engine innodb;
+
+# columns with/without system versioning
+
+create or replace table t1 (
+ x15 int with system versioning,
+ B int
+);
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+
+create or replace table t1 (
+ x16 int with system versioning,
+ B int
+) with system versioning;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+
+create or replace table t1 (
+ x17 int,
+ B int without system versioning
+);
+
+create or replace table t1 (
+ x18 int,
+ B int without system versioning
+) with system versioning;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+
+create or replace table t1 (
+ x19 int with system versioning,
+ B int without system versioning
+);
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+
+create or replace table t1 (
+ x20 int with system versioning,
+ B int without system versioning
+) with system versioning;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+
+create or replace table t1 (
+ x21 int without system versioning
+);
+
+--error ER_VERS_TABLE_MUST_HAVE_COLUMNS
+create or replace table t1 (
+ x22 int without system versioning
+) with system versioning;
+
+# CREATE TABLE ... LIKE
+create or replace table t1 (a int) with system versioning;
+create table tt1 like t1;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table tt1;
+drop table tt1;
+create temporary table tt1 like t1;
+--echo # Temporary is stripped from versioning
+--replace_result $default_engine DEFAULT_ENGINE
+show create table tt1;
+
+--echo # CREATE TABLE ... SELECT
+create or replace table t1 (x23 int) with system versioning;
+--replace_result $default_engine DEFAULT_ENGINE
+eval create or replace table t0(
+ y int,
+ st timestamp(6) as row start,
+ en timestamp(6) as row end,
+ period for system_time (st, en)
+) with system versioning;
+
+--echo ## For non-versioned table:
+--echo ### 1. invisible fields are not included
+create or replace table t2 as select * from t1;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t2;
+
+--echo ### 2. all visible fields are included
+create or replace table t3 as select * from t0;
+select * from t0;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t3;
+
+--echo ## For versioned table
+insert into t1 values (1);
+select row_start from t1 into @row_start;
+insert into t0 (y) values (2);
+select st from t0 into @st;
+
+create or replace table t2 with system versioning as select * from t1;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t2;
+--echo #### invisible fields are not copied
+select * from t2;
+select * from t2 where row_start <= @row_start;
+
+--echo ### 2. source table with visible system fields, target with invisible
+create or replace table t3 with system versioning as select * from t0;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t3;
+select * from t3 where y > 2;
+select y from t3 where st = @st and row_start > @st;
+
+--echo ### 3. source and target table with visible system fields
+--replace_result $default_engine DEFAULT_ENGINE
+eval create or replace table t3 (
+ st timestamp(6) as row start invisible,
+ en timestamp(6) as row end invisible,
+ period for system_time (st, en)
+) with system versioning as select * from t0;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t3;
+select y from t3;
+select y from t3 where st = @st;
+
+--echo ### 4. system fields not or wrongly selected
+create or replace table t3 with system versioning select x23 from t1;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t3;
+select * from t3;
+--error ER_MISSING
+create or replace table t3 with system versioning select x23, row_start from t1;
+--error ER_MISSING
+create or replace table t3 with system versioning select x23, row_end from t1;
+
+--echo # Prepare checking for historical row
+delete from t1;
+select row_end from t1 for system_time all into @row_end;
+delete from t0;
+select en from t0 for system_time all into @en;
+
+--echo ## Combinations of versioned + non-versioned
+create or replace table t2 (y int);
+insert into t2 values (3);
+create or replace table t3 with system versioning select * from t1 for system_time all, t2;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t3;
+select * from t3 for system_time all;
+select * from t3 for system_time all where row_start = @row_start and row_end = @row_end;
+
+create or replace table t2 like t0;
+insert into t2 (y) values (1), (2);
+delete from t2 where y = 2;
+
+create or replace table t3 select * from t2 for system_time all;
+select st, en from t3 where y = 1 into @st, @en;
+select y from t2 for system_time all where st = @st and en = @en;
+select st, en from t3 where y = 2 into @st, @en;
+select y from t2 for system_time all where st = @st and en = @en;
+
+--echo ## Default engine detection
+--replace_result $non_default_engine NON_DEFAULT_ENGINE
+eval create or replace table t1 (x25 int) with system versioning engine $non_default_engine;
+create or replace table t2
+as select x25, row_start, row_end from t1 for system_time all;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t2;
+
+create or replace table t2 with system versioning
+as select x25, row_start, row_end from t1;
+--replace_result $non_default_engine NON_DEFAULT_ENGINE
+show create table t2;
+
+create or replace table t1 (
+ x26 int,
+ st bigint unsigned as row start,
+ en bigint unsigned as row end,
+ period for system_time (st, en)
+) with system versioning engine innodb;
+--error ER_VERS_FIELD_WRONG_TYPE
+create or replace table t2 with system versioning engine myisam
+as select * from t1;
+
+--replace_result $non_default_engine NON_DEFAULT_ENGINE
+eval create or replace table t1 (x27 int, id int) with system versioning engine $non_default_engine;
+create or replace table t2 (b int, id int);
+create or replace table t3 with system versioning
+as select t2.b, t1.x27, t1.row_start, t1.row_end from t2 inner join t1 on t2.id=t1.id;
+--replace_result $non_default_engine NON_DEFAULT_ENGINE
+show create table t3;
+
+--echo ## Errors
+
+--error ER_VERS_TEMPORARY
+create or replace temporary table t (x28 int) with system versioning;
+
+--error ER_VERS_DUPLICATE_ROW_START_END
+create or replace table t1 (
+ x29 int unsigned,
+ Sys_start0 timestamp(6) as row start invisible,
+ Sys_start timestamp(6) as row start invisible,
+ Sys_end timestamp(6) as row end invisible,
+ period for system_time (Sys_start, Sys_end)
+) with system versioning;
+
+--error ER_VERS_DUPLICATE_ROW_START_END
+create or replace table t1 (
+ x29 int unsigned,
+ Sys_end0 timestamp(6) as row end invisible,
+ Sys_start timestamp(6) as row start invisible,
+ Sys_end timestamp(6) as row end invisible,
+ period for system_time (Sys_start, Sys_end)
+) with system versioning;
+
+--echo ## System fields detection
+create or replace table t1 (x30 int) with system versioning;
+--replace_result $default_engine DEFAULT_ENGINE
+eval create or replace table t2 (
+ y int,
+ st timestamp(6) as row start invisible,
+ en timestamp(6) as row end invisible,
+ period for system_time (st, en)
+) with system versioning;
+
+create or replace table t3
+as select x30, y, row_start, row_end, st, en from t1, t2;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t3;
+
+--replace_result $default_engine DEFAULT_ENGINE
+eval create or replace table t3 (
+ y int,
+ st timestamp(6) as row start invisible,
+ en timestamp(6) as row end invisible,
+ period for system_time (st, en)
+) with system versioning
+as select x30, y, row_start, row_end, st, en from t1, t2;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t3;
+
+--echo # MDEV-14828 Server crashes in JOIN::prepare / setup_fields on 2nd execution of PS [#437]
+create or replace table t1 (x int) with system versioning;
+prepare bad from 'create or replace table t2 with system versioning as select * from t1';
+execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad;
+--echo # bad is good.
+
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/t/cte.test b/mysql-test/suite/versioning/t/cte.test
new file mode 100644
index 00000000000..9df0bb3dfba
--- /dev/null
+++ b/mysql-test/suite/versioning/t/cte.test
@@ -0,0 +1,101 @@
+-- source include/have_innodb.inc
+set default_storage_engine=innodb;
+create or replace table dept (
+ dept_id int(10) primary key,
+ name varchar(100)
+)
+with system versioning;
+
+create or replace table emp (
+ emp_id int(10) primary key,
+ dept_id int(10) not null,
+ name varchar(100) not null,
+ mgr int(10),
+ salary int(10) not null,
+ constraint `dept-emp-fk`
+ foreign key (dept_id) references dept (dept_id)
+ on delete cascade
+ on update restrict,
+ constraint `mgr-fk`
+ foreign key (mgr) references emp (emp_id)
+ on delete restrict
+ on update restrict
+)
+with system versioning;
+
+insert into dept (dept_id, name) values (10, "accounting");
+
+insert into emp (emp_id, name, salary, dept_id, mgr) values
+(1, "bill", 1000, 10, null),
+(20, "john", 500, 10, 1),
+(30, "jane", 750, 10,1 );
+
+select max(sys_trx_start) into @ts_1 from emp;
+
+update emp set mgr=30 where name ="john";
+select sys_trx_start into @ts_2 from emp where name="john";
+
+/* All report to 'Bill' */
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr, e.salary
+ from emp for system_time as of timestamp @ts_1 as e
+ where name = 'bill'
+ union
+ select e.emp_id, e.name, e.mgr, e.salary
+ from emp for system_time as of timestamp @ts_1 as e,
+ ancestors as a
+ where e.mgr = a.emp_id
+)
+select * from ancestors;
+
+/* Expected 3 rows */
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr, e.salary
+ from emp for system_time as of timestamp @ts_2 as e
+ where name = 'bill'
+ union
+ select e.emp_id, e.name, e.mgr, e.salary
+ from emp for system_time as of timestamp @ts_2 as e,
+ ancestors as a
+ where e.mgr = a.emp_id
+)
+select * from ancestors;
+
+create or replace table emp ( emp_id int, name varchar(127), mgr int) with system versioning;
+create or replace table addr ( emp_id int, address varchar(100)) with system versioning;
+insert emp values (1, 'bill', 0), (2, 'bill', 1), (3, 'kate', 1);
+insert addr values (1, 'Moscow'), (2, 'New York'), (3, 'London');
+set @ts=now(6);
+delete from emp;
+delete from addr;
+
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr
+ from emp for system_time as of timestamp @ts as e
+ where name = 'bill'
+ union
+ select ee.emp_id, ee.name, ee.mgr
+ from emp for system_time as of timestamp @ts as ee, ancestors as a
+ where ee.mgr = a.emp_id
+)
+select * from ancestors;
+
+insert emp values (4, 'john', 1);
+insert addr values (4, 'Paris');
+with ancestors as (select * from emp natural join addr) select * from ancestors;
+with ancestors as (select * from emp natural join addr) select * from ancestors for system_time all;
+with ancestors as (select * from (select * from emp natural join addr) for system_time all as t) select * from ancestors;
+select * from (select * from emp natural join addr) for system_time all as t;
+
+drop table emp;
+drop table dept;
+drop table addr;
diff --git a/mysql-test/suite/versioning/t/ddl.test b/mysql-test/suite/versioning/t/ddl.test
new file mode 100644
index 00000000000..5be62281a6d
--- /dev/null
+++ b/mysql-test/suite/versioning/t/ddl.test
@@ -0,0 +1,105 @@
+-- source suite/versioning/common.inc
+
+delimiter ~~;
+create function get_archive_table_name()
+returns varchar(255)
+begin
+ return (select archive_name from t_vtmd for system_time all where archive_name is not NULL
+ order by start desc limit 1);
+end~~
+
+create procedure drop_last_archive()
+begin
+ call concat_exec2('drop table ', get_archive_table_name());
+end~~
+delimiter ;~~
+
+set versioning_alter_history= survive;
+
+create or replace table t (a int) with system versioning;
+insert into t values (1);
+update t set a=2 where a=1;
+select sys_trx_start from t where a=2 into @tm;
+alter table t add column b int;
+
+select * from t;
+call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
+
+call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
+select @tm<sys_trx_start from t where a=2;
+select sys_trx_start from t where a=2 into @tm;
+call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
+
+call drop_last_archive();
+
+
+set versioning_alter_history= keep;
+drop table t_vtmd;
+drop table t;
+set versioning_alter_history= survive;
+
+# same for INNODB ALGORITHM=COPY
+create or replace table t (a int) with system versioning;
+insert into t values (1);
+update t set a=2 where a=1;
+select sys_trx_start from t where a=2 into @tm;
+alter table t add column b int;
+
+select * from t;
+call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
+
+call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
+select @tm<sys_trx_start from t where a=2;
+select sys_trx_start from t where a=2 into @tm;
+call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
+
+call drop_last_archive();
+
+
+set versioning_alter_history= keep;
+drop table t_vtmd;
+drop table t;
+set versioning_alter_history= survive;
+
+# same for INNODB default ALGORITHM
+create or replace table t (a int) with system versioning engine innodb;
+insert into t values (1);
+update t set a=2 where a=1;
+select sys_trx_start from t where a=2 into @tm;
+alter table t add column b int;
+
+select * from t;
+call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
+
+call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
+select @tm<sys_trx_start from t where a=2;
+select sys_trx_start from t where a=2 into @tm;
+call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
+
+call drop_last_archive();
+
+
+set versioning_alter_history= keep;
+drop table t_vtmd;
+drop table t;
+set versioning_alter_history= survive;
+
+# no DDL for INNODB explicit ALGORITHM=INPLACE
+create or replace table t (a int) with system versioning engine innodb;
+insert into t values (1);
+update t set a=2 where a=1;
+alter table t add column b int, algorithm=inplace;
+
+set versioning_alter_history = keep;
+
+drop function get_archive_table_name;
+drop procedure drop_last_archive;
+
+select * from mysql.vtmd_template;
+show create table mysql.vtmd_template;
+
+call verify_vtq;
+drop table t;
+drop table t_vtmd;
+
+-- source suite/versioning/common_finish.inc
diff --git a/mysql-test/suite/versioning/t/debug.test b/mysql-test/suite/versioning/t/debug.test
new file mode 100644
index 00000000000..c6d5bd60861
--- /dev/null
+++ b/mysql-test/suite/versioning/t/debug.test
@@ -0,0 +1,35 @@
+--source include/have_debug.inc
+
+create table t1 (a int);
+show create table t1;
+
+--error ER_VERS_TEMPORARY
+create temporary table tt1 (a int) with system versioning;
+
+set @old_dbug=@@global.debug_dbug;
+set global debug_dbug='+d,sysvers_force';
+
+create table t2 (a int);
+show create table t2;
+
+create temporary table tt2 (a int) with system versioning;
+show create table tt2;
+
+--connect con1, localhost, root
+
+create table t3 (a int);
+show create table t3;
+
+create temporary table tt3 (a int) with system versioning;
+show create table tt3;
+--disconnect con1
+--connection default
+
+set debug_dbug='+d,sysvers_show';
+
+show create table t3;
+create table t4 (a int);
+show create table t4;
+
+set global debug_dbug=@old_dbug;
+drop table t1, t2, t3, t4;
diff --git a/mysql-test/suite/versioning/t/delete.test b/mysql-test/suite/versioning/t/delete.test
new file mode 100644
index 00000000000..4c2f4daccd7
--- /dev/null
+++ b/mysql-test/suite/versioning/t/delete.test
@@ -0,0 +1,86 @@
+source suite/versioning/engines.inc;
+source suite/versioning/common.inc;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create or replace table t1(
+ XNo int unsigned,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_start, sys_end))
+ with system versioning;
+
+insert into t1(XNo) values(0);
+insert into t1(XNo) values(1);
+insert into t1(XNo) values(2);
+insert into t1(XNo) values(3);
+insert into t1(XNo) values(4);
+insert into t1(XNo) values(5);
+insert into t1(XNo) values(6);
+insert into t1(XNo) values(7);
+insert into t1(XNo) values(8);
+insert into t1(XNo) values(9);
+replace_result $sys_datatype_max MAXVAL;
+eval select XNo, sys_end < $sys_datatype_max from t1 for system_time all;
+delete from t1 where XNo = 0;
+delete from t1 where XNo = 1;
+delete from t1 where XNo > 5;
+create view vt1 as select XNo from t1;
+select XNo as XNo_vt1 from vt1;
+delete from vt1 where XNo = 3;
+select XNo as XNo_vt1 from vt1;
+drop view vt1;
+drop table t1;
+
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create or replace table t1(
+ x int,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_start, sys_end))
+ with system versioning;
+
+insert into t1(x) values (1);
+select sys_start into @sys_start from t1;
+delete from t1;
+select * from t1;
+select x = 1 as A, sys_start = @sys_start as B, sys_end > sys_start as C from t1 for system_time all;
+drop table t1;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create or replace table t1(
+ x int,
+ y int,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_start, sys_end))
+ with system versioning;
+create or replace table t2 like t1;
+insert into t1(x, y) values (1, 1), (2, 2), (3, 3), (14, 4);
+insert into t2(x, y) values (11, 1), (12, 2), (13, 32), (14, 4);
+delete t1, t2 from t1 join t2 where t1.y = 3 and t2.y = 32;
+select x as t1_x from t1;
+select x as t2_x from t2;
+delete t1, t2 from t1 join t2 where t1.x = t2.x;
+select x as t1_x from t1;
+select x as t2_x from t2;
+select x as t1_x_all from t1 for system_time all;
+select x as t2_x_all from t2 for system_time all;
+drop table t1;
+drop table t2;
+
+--echo # Basic + delete from view
+
+--echo # Check sys_start, sys_end
+
+--echo # Multi-delete
+
+--echo # Update + delete
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+update t1 set x= 2;
+delete from t1;
+select x from t1 for system_time all;
+
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/t/derived.test b/mysql-test/suite/versioning/t/derived.test
new file mode 100644
index 00000000000..9784a4a0d2f
--- /dev/null
+++ b/mysql-test/suite/versioning/t/derived.test
@@ -0,0 +1,236 @@
+create table emp
+(
+ emp_id int,
+ name varchar(127),
+ mgr int
+) with system versioning;
+
+insert into emp values (1, 'bill', 0),
+ (2, 'bill', 1),
+ (3, 'kate', 1);
+set @ts=now(6);
+delete from emp;
+insert into emp values (4, 'john', 1);
+
+with ancestors as (select * from emp) select * from ancestors;
+set @tmp= "with ancestors as (select * from emp) select * from ancestors";
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+with ancestors as (select * from emp for system_time all) select * from ancestors;
+set @tmp= "with ancestors as (select * from emp for system_time all) select * from ancestors";
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+with recursive ancestors as (select * from emp) select * from ancestors;
+set @tmp= "with recursive ancestors as (select * from emp) select * from ancestors";
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+select emp_id from (select emp_id from emp where row_end>'2031-1-1') as tmp;
+set @tmp= "select emp_id from (select emp_id from emp where row_end>'2031-1-1') as tmp";
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr
+ from emp as e
+ where name = 'john'
+ union
+ select ee.emp_id, ee.name, ee.mgr
+ from emp as ee, ancestors as a
+ where ee.mgr = a.emp_id
+)
+select * from ancestors;
+set @tmp= "
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr
+ from emp as e
+ where name = 'john'
+ union
+ select ee.emp_id, ee.name, ee.mgr
+ from emp as ee, ancestors as a
+ where ee.mgr = a.emp_id
+)
+select * from ancestors";
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+#385
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr
+ from emp for system_time as of timestamp @ts as e
+ where name = 'bill'
+ union
+ select ee.emp_id, ee.name, ee.mgr
+ from emp for system_time as of timestamp @ts as ee,
+ ancestors as a
+ where ee.mgr = a.emp_id
+)
+select * from ancestors;
+set @tmp= "
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr
+ from emp for system_time as of timestamp @ts as e
+ where name = 'bill'
+ union
+ select ee.emp_id, ee.name, ee.mgr
+ from emp for system_time as of timestamp @ts as ee,
+ ancestors as a
+ where ee.mgr = a.emp_id
+)
+select * from ancestors";
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+drop table emp;
+
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int) with system versioning;
+insert into t1 values (1);
+set @t0= now(6);
+delete from t1;
+insert into t1 values (2);
+insert into t2 values (10);
+
+--replace_column 2 # 3 #
+select * from (select *, t1.row_end, t1.row_end as endo from t1) as s0;
+--replace_column 3 # 4 #
+select * from (select *, t1.row_end, t2.row_start from t1, t2) as s0;
+
+--echo # SYSTEM_TIME propagation from inner to outer
+select * from (select * from t1 for system_time as of timestamp @t0, t2) as s0;
+with s1 as (select * from t1 for system_time as of timestamp @t0, t2) select * from s1;
+--echo # leading table selection
+--replace_column 3 #
+select * from (select *, t1.row_end from t2, t1 for system_time as of timestamp @t0) as s2;
+--replace_column 3 #
+with s3 as (select *, t1.row_end from t2, t1 for system_time as of timestamp @t0) select * from s3;
+
+--echo ### VIEW instead of t1
+set @q= concat("create view vt1 as select * from t1 for system_time as of timestamp '", @t0, "'");
+prepare q from @q; execute q; drop prepare q;
+create view vt2 as select * from t1;
+
+--echo # SYSTEM_TIME propagation from view
+select * from vt1;
+--echo # SYSTEM_TIME propagation from inner to outer
+select * from (select * from vt1, t2) as s0;
+
+--echo ### SYSTEM_TIME clash
+--error ER_VERS_NOT_VERSIONED
+select * from (select * from t1 for system_time all) for system_time all as dt0;
+--error ER_VERS_NOT_VERSIONED
+select * from vt1 for system_time all;
+--error ER_VERS_NOT_VERSIONED
+with dt1 as (select * from t1 for system_time all)
+select * from dt1 for system_time all;
+
+--echo ### UNION
+set @t1= now(6);
+delete from t2;
+insert into t2 values (3);
+--echo # SYSTEM_TIME is not propagated
+select x from t1 union
+select y from t2;
+select x from t1 for system_time as of @t0 union
+select y from t2;
+select x from t1 union
+select y from t2 for system_time as of @t1;
+select x from t1 for system_time as of @t0 union
+select y from t2 for system_time as of @t1;
+
+--echo # LEFT/RIGHT JOIN
+create or replace table t1 (x int, y int) with system versioning;
+create or replace table t2 (x int, y int) with system versioning;
+
+insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
+insert into t2 values (1, 2), (2, 1), (3, 1);
+
+--echo ## Outer or inner SYSTEM_TIME produces same expression
+
+--disable_warnings
+--disable_query_log
+explain extended
+select * from (
+ select t1.x, t1.y as y1, t2.x as x2, t2.y as y2
+ from t1 join t2 on t1.x = t2.x) for system_time as of now() as t;
+
+let $a=`show warnings`;
+--echo Query A:
+echo $a;
+
+explain extended
+select * from (
+ select t1.x, t1.y as y1, t2.x as x2, t2.y as y2
+ from t1 for system_time as of now()
+ join t2 for system_time as of now() on t1.x = t2.x) as t;
+
+let $b=`show warnings`;
+--echo Query B:
+echo $b;
+
+if ($a == $b)
+{
+ --echo Fine result: queries A and B are equal.
+}
+--enable_query_log
+--enable_warnings
+
+--echo ## LEFT JOIN: t1, t2 versioned
+select * from (
+ select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2
+ from t1 left join t2 on t1.x = t2.x)
+as derived;
+
+alter table t2 drop system versioning;
+
+--echo ## LEFT JOIN: t1 versioned
+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)
+as derived;
+
+alter table t1 drop system versioning;
+alter table t2 add system versioning;
+
+--echo ## LEFT JOIN: t2 versioned
+select * from (
+ select t1.x as LJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2
+ from t1 left join t2 on t1.x = t2.x)
+as derived;
+
+alter table t1 add system versioning;
+
+--echo ## RIGHT JOIN: t1, t2 versioned
+select * from (
+ select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2
+ from t1 right join t2 on t1.x = t2.x)
+as derived;
+
+alter table t2 drop system versioning;
+
+--echo ## RIGHT JOIN: t1 versioned
+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)
+as derived;
+
+alter table t1 drop system versioning;
+alter table t2 add system versioning;
+
+--echo ## RIGHT JOIN: t2 versioned
+select * from (
+ select t1.x as RJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2
+ from t1 right join t2 on t1.x = t2.x)
+as derived;
+
+drop table t1, t2;
+drop view vt1, vt2;
+
diff --git a/mysql-test/suite/versioning/t/engines.combinations b/mysql-test/suite/versioning/t/engines.combinations
new file mode 100644
index 00000000000..561c5656929
--- /dev/null
+++ b/mysql-test/suite/versioning/t/engines.combinations
@@ -0,0 +1,8 @@
+[timestamp]
+default-storage-engine=innodb
+
+[trx_id]
+default-storage-engine=innodb
+
+[myisam]
+default-storage-engine=myisam
diff --git a/mysql-test/suite/versioning/t/foreign.combinations b/mysql-test/suite/versioning/t/foreign.combinations
new file mode 100644
index 00000000000..1a0812cfafe
--- /dev/null
+++ b/mysql-test/suite/versioning/t/foreign.combinations
@@ -0,0 +1,5 @@
+[timestamp]
+default-storage-engine=innodb
+
+[trx_id]
+default-storage-engine=innodb
diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test
new file mode 100644
index 00000000000..040d7564360
--- /dev/null
+++ b/mysql-test/suite/versioning/t/foreign.test
@@ -0,0 +1,285 @@
+--source suite/versioning/common.inc
+
+--echo #################
+--echo # Test RESTRICT #
+--echo #################
+
+create table parent(
+ id int unique key
+) engine innodb;
+
+eval create table child(
+ parent_id int,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time(sys_start, sys_end),
+ foreign key(parent_id) references parent(id)
+ on delete restrict
+ on update restrict
+) engine innodb with system versioning;
+
+insert into parent values(1);
+insert into child values(1);
+
+-- error ER_ROW_IS_REFERENCED_2
+delete from parent where id = 1;
+delete from child where parent_id = 1;
+delete from parent where id = 1;
+
+insert into parent values(1);
+insert into child values(1);
+-- error ER_ROW_IS_REFERENCED_2
+update parent set id=id+1;
+delete from child;
+update parent set id=id+1;
+select * from child for system_time from timestamp 0 to timestamp now(6);
+
+drop table child;
+drop table parent;
+
+--echo ##############################################
+--echo # Test when clustered index is a foreign key #
+--echo ##############################################
+
+create table parent(
+ id int(10) unsigned unique key
+) engine innodb;
+
+eval create table child(
+ parent_id int(10) unsigned primary key,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time(sys_start, sys_end),
+ foreign key(parent_id) references parent(id)
+) engine innodb with system versioning;
+
+insert into parent values(1);
+insert into child values(1);
+
+-- error ER_ROW_IS_REFERENCED_2
+delete from parent where id = 1;
+
+drop table child;
+drop table parent;
+
+--echo ################
+--echo # Test CASCADE #
+--echo ################
+
+create table parent(
+ id int unique key
+) engine innodb;
+
+--disable_abort_on_error
+eval create table child(
+ parent_id int,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time(sys_start, sys_end),
+ foreign key(parent_id) references parent(id)
+ on delete cascade
+ on update cascade
+) engine innodb with system versioning;
+--enable_abort_on_error
+
+if ($MTR_COMBINATION_TRX_ID) {
+insert into parent values(1);
+insert into child values(1);
+
+delete from parent where id = 1;
+delete from child where parent_id = 1;
+delete from parent where id = 1;
+select * from child;
+select * from child for system_time all;
+
+insert into parent values(1);
+insert into child values(1);
+update parent set id = id + 1;
+select * from child;
+select * from child for system_time all;
+
+drop table child;
+}
+drop table parent;
+eval create or replace table parent (
+ id int primary key,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time(sys_start, sys_end)
+) with system versioning
+engine innodb;
+
+create or replace table child (
+ x int,
+ parent_id int not null,
+ constraint `parent-fk`
+ foreign key (parent_id) references parent (id)
+ on delete cascade
+ on update restrict
+)
+engine innodb;
+
+insert into parent (id) values (2);
+insert into child (x, parent_id) values (2, 2);
+delete from parent;
+select * from child;
+
+drop table child;
+drop table parent;
+
+create or replace table parent (
+ id int primary key
+)
+engine innodb;
+
+--disable_abort_on_error
+eval create or replace table child (
+ id int primary key,
+ parent_id int not null,
+ row_start $sys_datatype_expl as row start invisible,
+ row_end $sys_datatype_expl as row end invisible,
+ period for system_time(row_start, row_end),
+ constraint `parent-fk`
+ foreign key (parent_id) references parent (id)
+ on delete cascade
+ on update restrict
+) with system versioning
+engine innodb;
+--enable_abort_on_error
+
+if ($MTR_COMBINATION_TRX_ID) {
+insert into parent (id) values (3);
+insert into child (id, parent_id) values (3, 3);
+--echo ## FIXME: #415 update of foreign constraints is disabled
+delete from child;
+--echo ## FIXME END
+delete from parent;
+select * from child;
+--replace_result $sys_datatype_max MAXVAL
+eval select *, row_start < row_end, row_end < $sys_datatype_max from child for system_time all;
+
+drop table child;
+}
+drop table parent;
+
+--echo #################
+--echo # Test SET NULL #
+--echo #################
+
+create table parent(
+ id int unique key
+) engine innodb;
+
+--disable_abort_on_error
+eval create table child(
+ parent_id int,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time(sys_start, sys_end),
+ foreign key(parent_id) references parent(id)
+ on delete set null
+ on update set null
+) engine innodb with system versioning;
+--enable_abort_on_error
+
+if ($MTR_COMBINATION_TRX_ID) {
+insert into parent values(1);
+insert into child values(1);
+delete from child;
+insert into child values(1);
+
+--echo ## FIXME: #415 update of foreign constraints is disabled
+delete from child where parent_id = 1;
+--echo ## FIXME END
+delete from parent where id = 1;
+select * from child;
+select * from child for system_time from timestamp 0 to timestamp now(6);
+delete from child;
+
+insert into parent values(1);
+insert into child values(1);
+## FIXME: #415 update of foreign constraints is disabled
+if (0)
+{
+update parent set id=id+1;
+select * from child;
+select * from child for system_time from timestamp 0 to timestamp now(6);
+}
+## FIXME END
+
+drop table child;
+}
+drop table parent;
+
+--echo ###########################
+--echo # Parent table is foreign #
+--echo ###########################
+
+eval create or replace table parent(
+ id int unique key,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time(sys_start, sys_end)
+) engine innodb with system versioning;
+
+create or replace table child(
+ parent_id int,
+ foreign key(parent_id) references parent(id)
+) engine innodb;
+
+insert into parent values(1);
+insert into child values(1);
+-- error ER_ROW_IS_REFERENCED_2
+delete from parent;
+-- error ER_ROW_IS_REFERENCED_2
+update parent set id=2;
+
+delete from child;
+delete from parent;
+
+-- error ER_NO_REFERENCED_ROW_2
+insert into child values(1);
+
+insert into parent values(1);
+insert into child values(1);
+-- error ER_ROW_IS_REFERENCED_2
+delete from parent;
+-- error ER_ROW_IS_REFERENCED_2
+update parent set id=2;
+
+drop table child;
+drop table parent;
+
+--echo ###################
+--echo # crash on DELETE #
+--echo ###################
+
+eval create or replace table a (
+ cola int(10) primary key,
+ v_cola int(10) as (cola mod 10) virtual,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time(sys_start, sys_end)
+) engine=innodb with system versioning;
+
+create index v_cola on a (v_cola);
+
+eval create or replace table b(
+ cola int(10),
+ v_cola int(10),
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time(sys_start, sys_end)
+) engine=innodb with system versioning;
+
+alter table b add constraint `v_cola_fk`
+foreign key (v_cola) references a (v_cola);
+
+insert into a(cola) values (12);
+insert into b(cola, v_cola) values (10,2);
+--error ER_ROW_IS_REFERENCED_2
+delete from a;
+
+drop table b, a;
+
+--source suite/versioning/common_finish.inc
diff --git a/mysql-test/suite/versioning/t/insert.test b/mysql-test/suite/versioning/t/insert.test
new file mode 100644
index 00000000000..0324df64d0c
--- /dev/null
+++ b/mysql-test/suite/versioning/t/insert.test
@@ -0,0 +1,82 @@
+source suite/versioning/engines.inc;
+source suite/versioning/common.inc;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create or replace table t1(
+ x int unsigned,
+ y int unsigned,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_start, sys_end))
+with system versioning;
+
+insert into t1(x, y) values(3, 4);
+insert into t1(x, y) values(2, 3);
+insert into t1 values(40, 33);
+replace_result $sys_datatype_max MAXVAL;
+eval select x, y, sys_end < $sys_datatype_max from t1;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create or replace table t1(
+ id int unsigned auto_increment primary key,
+ x int unsigned,
+ y int unsigned,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_start, sys_end))
+with system versioning;
+
+insert into t1(x, y) values(33, 44);
+insert into t1(id, x, y) values(20, 33, 44);
+insert into t1 values(40, 33, 44);
+replace_result $sys_datatype_max MAXVAL;
+eval select id, x, y, sys_end < $sys_datatype_max from t1;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create or replace table t1(
+ x int unsigned,
+ y int unsigned,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_start, sys_end))
+with system versioning;
+create view vt1_1 as select x, y from t1;
+insert into t1(x, y) values(8001, 9001);
+insert into vt1_1(x, y) values(1001, 2001);
+insert into vt1_1 values(1002, 2002);
+replace_result $sys_datatype_max MAXVAL;
+eval select x, y, sys_end < $sys_datatype_max from t1;
+select x, y from vt1_1;
+drop view vt1_1;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create or replace table t1( id bigint primary key, a int, b int) with system versioning;
+insert into t1 values(1, 1, 1);
+select row_start, row_end from t1 into @sys_start, @sys_end;
+select id, a, b from t1;
+insert into t1 values(2, 2, 2);
+select id, a, b, row_start > @sys_start as C, row_end = @sys_end as D from t1 where id = 2;
+drop table t1;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create or replace table t1(
+ x int unsigned,
+ y int unsigned,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_start, sys_end))
+with system versioning;
+create or replace table t2 like t1;
+insert into t1(x, y) values (1, 1000), (2, 2000), (3, 3000), (4, 4000), (5, 5000), (6, 6000), (7, 7000), (8, 8000), (9, 9000);
+delete from t1 where x >= 1;
+insert into t1(x, y) values (1, 1001), (2, 2001), (3, 3001), (4, 4001), (5, 5001), (6, 6001);
+insert into t1(x, y, sys_start) values (7, 7001, DEFAULT);
+insert into t1(x, y, sys_end) values (8, 8001, DEFAULT);
+insert into t1(x, y, sys_start, sys_end) values (9, 9001, DEFAULT, DEFAULT);
+insert into t2 select x, y from t1 for system_time all;
+select x, y from t1;
+select x, y from t2;
+drop table t1;
+drop table t2;
+
+-- source suite/versioning/common_finish.inc
diff --git a/mysql-test/suite/versioning/t/insert2.test b/mysql-test/suite/versioning/t/insert2.test
new file mode 100644
index 00000000000..b65f3c55b94
--- /dev/null
+++ b/mysql-test/suite/versioning/t/insert2.test
@@ -0,0 +1,104 @@
+--source include/have_innodb.inc
+
+# VTQ test
+
+create table t1(
+ x int unsigned,
+ sys_start bigint unsigned as row start invisible,
+ sys_end bigint unsigned as row end invisible,
+ period for system_time (sys_start, sys_end))
+with system versioning engine=innodb;
+
+create table t2(x int unsigned) engine=innodb;
+
+start transaction;
+insert into t1(x) values(1);
+commit;
+
+start transaction;
+insert into t2(x) values(1);
+savepoint a;
+insert into t1(x) values(1);
+rollback to a;
+commit;
+
+insert into t2(x) values (1);
+
+# virtual columns
+create or replace table t1 (
+ x int,
+ y int as (x) virtual,
+ sys_trx_start bigint unsigned as row start invisible,
+ sys_trx_end bigint unsigned as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end)
+) engine=innodb with system versioning;
+insert into t1 values (1, null);
+update t1 set x= x + 1;
+select x, y, sys_trx_end = 18446744073709551615 as current from t1 for system_time all;
+
+create or replace table t1 (
+ x int,
+ row_start timestamp(6) as row start invisible,
+ row_end timestamp(6) as row end invisible,
+ period for system_time (row_start, row_end)
+) with system versioning;
+insert into t1 values (1), (2);
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
+insert into t1 (row_start) select row_end from t1;
+set sql_mode='';
+insert into t1 (row_start, row_end) values (DEFAULT, 1);
+set sql_mode=default;
+select @@sql_mode into @saved_mode;
+set sql_mode= '';
+insert into t1 (x, row_start, row_end) values (3, 4, 5);
+set sql_mode= @saved_mode;
+insert into t1 (row_start, row_end) values (DEFAULT, DEFAULT);
+select * from t1;
+
+--echo # MDEV-14792 INSERT without column list into table with explicit versioning columns produces bad data
+create or replace table t1 (
+ i int,
+ s timestamp(6) as row start,
+ e timestamp(6) as row end,
+ c varchar(8),
+ period for system_time(s, e))
+with system versioning;
+insert into t1 values (1, null, null, 'foo');
+select i, c, e>TIMESTAMP'2038-01-01 00:00:00' AS current_row from t1;
+
+drop table t1;
+drop table t2;
+
+#
+# MDEV-14788 System versioning cannot be based on local timestamps, as it is now
+#
+set timestamp=1000000019;
+select now() < sysdate();
+create table t1 (a int) with system versioning;
+insert t1 values (1);
+
+--source suite/versioning/wait_system_clock.inc
+set @a=sysdate(6);
+
+select * from t1 for system_time as of now(6);
+select * from t1 for system_time as of sysdate(6);
+update t1 set a=2;
+delete from t1;
+--sorted_result
+select *, row_start > @a, row_end > @a from t1 for system_time all;
+
+--echo #
+--echo # MDEV-14871 Server crashes in fill_record / fill_record_n_invoke_before_triggers upon inserting into versioned table with trigger
+--echo #
+create or replace table t1 (pk int primary key) with system versioning;
+create trigger tr before insert on t1 for each row select 1 into @a;
+insert into t1 values (1),(2);
+drop table t1;
+
+#
+# MDEV-14794 Limitations which the row end as a part of PK imposes due to CURRENT_TIMESTAMP behavior and otherwise
+#
+create table t1 (pk int primary key, i int) with system versioning;
+replace into t1 values (1,10),(1,100),(1,1000);
+select pk,i,row_end > '2038-01-01' from t1 for system_time all;
+drop table t1;
diff --git a/mysql-test/suite/versioning/t/load_data.test b/mysql-test/suite/versioning/t/load_data.test
new file mode 100644
index 00000000000..4db6eee6c4d
--- /dev/null
+++ b/mysql-test/suite/versioning/t/load_data.test
@@ -0,0 +1,12 @@
+#
+# MDEV-15330 Server crash or assertion `table->insert_values' failure in write_record upon LOAD DATA
+#
+CREATE TABLE t1 (a INT, b INT, c INT, vc INT AS (c), UNIQUE(a), UNIQUE(b)) WITH SYSTEM VERSIONING;
+INSERT IGNORE INTO t1 (a,b,c) VALUES (1,2,3);
+
+SELECT a, b, c FROM t1 INTO OUTFILE '15330.data';
+LOAD DATA INFILE '15330.data' IGNORE INTO TABLE t1 (a,b,c);
+LOAD DATA INFILE '15330.data' REPLACE INTO TABLE t1 (a,b,c);
+
+# Cleanup
+DROP TABLE t1;
diff --git a/mysql-test/suite/versioning/t/online.test b/mysql-test/suite/versioning/t/online.test
new file mode 100644
index 00000000000..4fbd5d85100
--- /dev/null
+++ b/mysql-test/suite/versioning/t/online.test
@@ -0,0 +1,42 @@
+--source include/have_innodb.inc
+
+set system_versioning_alter_history=keep;
+
+create or replace table t (a int, b int) engine=innodb;
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t add system versioning, lock=none;
+alter table t add system versioning, lock=shared;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t drop column b, lock=none;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t drop column b, algorithm=inplace;
+alter table t add index idx(a), lock=none;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t drop system versioning, lock=none;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t drop system versioning, algorithm=inplace;
+
+
+create or replace table t (a int, b int) engine=innodb;
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t
+ add s bigint unsigned as row start,
+ add e bigint unsigned as row end,
+ add period for system_time(s, e),
+ add system versioning,
+ lock=none;
+alter table t
+ add s bigint unsigned as row start,
+ add e bigint unsigned as row end,
+ add period for system_time(s, e),
+ add system versioning;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t drop column b, lock=none;
+alter table t add index idx(a), lock=none;
+alter table t drop column s, drop column e;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t drop system versioning, lock=none;
+
+drop table t;
diff --git a/mysql-test/suite/versioning/t/optimized.test b/mysql-test/suite/versioning/t/optimized.test
new file mode 100644
index 00000000000..93dd6ed6fc6
--- /dev/null
+++ b/mysql-test/suite/versioning/t/optimized.test
@@ -0,0 +1,33 @@
+create table t (
+ a int,
+ b int without system versioning
+) with system versioning;
+
+insert into t values(1, 2);
+insert into t values(3, 4);
+select * from t;
+select a from t for system_time as of timestamp now(6);
+select a, b, b+0 from t for system_time as of timestamp now(6);
+select * from t for system_time as of timestamp now(6);
+select count(*) from t for system_time as of timestamp now(6) group by b;
+select * from t for system_time as of timestamp now(6) order by b asc;
+select * from t for system_time as of timestamp now(6) order by b desc;
+select * from t for system_time as of timestamp now(6) group by a having a=2;
+select * from t for system_time as of timestamp now(6) group by b having b=2;
+select a from t for system_time as of timestamp now(6) where b=2;
+select a from t for system_time as of timestamp now(6) where b=NULL;
+select a from t for system_time as of timestamp now(6) where b is NULL;
+select count(*), b from t for system_time as of timestamp now(6) group by b having b=NULL;
+select a, b from t;
+
+create or replace table t (
+ a int,
+ b int not null without system versioning
+) with system versioning;
+
+insert into t values (1, 2), (3, 4);
+
+select * from t for system_time as of timestamp now(6);
+select * from t for system_time as of timestamp now(6) where b is NULL;
+
+drop table t;
diff --git a/mysql-test/suite/versioning/t/partition.combinations b/mysql-test/suite/versioning/t/partition.combinations
new file mode 100644
index 00000000000..4d73ef5a5ea
--- /dev/null
+++ b/mysql-test/suite/versioning/t/partition.combinations
@@ -0,0 +1,5 @@
+[timestamp]
+default-storage-engine=innodb
+
+[myisam]
+default-storage-engine=myisam
diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test
new file mode 100644
index 00000000000..12fea2b86c2
--- /dev/null
+++ b/mysql-test/suite/versioning/t/partition.test
@@ -0,0 +1,487 @@
+-- source include/have_partition.inc
+-- source suite/versioning/common.inc
+
+set system_versioning_alter_history=keep;
+--echo # Check conventional partitioning on temporal tables
+
+create table t1 (x int)
+with system versioning
+partition by range columns (x) (
+ partition p0 values less than (100),
+ partition p1 values less than (1000));
+
+insert into t1 values (3), (300);
+select * from t1;
+select * from t1 partition (p0);
+select * from t1 partition (p1);
+
+delete from t1;
+select * from t1;
+select * from t1 partition (p0);
+select * from t1 partition (p1);
+select * from t1 for system_time all;
+select * from t1 partition (p0) for system_time all;
+select * from t1 partition (p1) for system_time all;
+
+--echo # Engine change native <-> non-native versioning prohibited
+--replace_result $default_engine DEFAULT_ENGINE
+eval create or replace table t1 (i int) engine=$default_engine with system versioning partition by hash(i);
+--replace_result $non_default_engine NON_DEFAULT_ENGINE
+--error ER_VERS_ALTER_ENGINE_PROHIBITED
+eval alter table t1 engine=$non_default_engine;
+
+
+--echo ## CREATE TABLE
+
+--error ER_VERS_NOT_VERSIONED
+create or replace table t1 (x int)
+partition by system_time (
+ partition p0 history,
+ partition pn current);
+
+create or replace table t1 (x int);
+--error ER_VERS_NOT_VERSIONED
+alter table t1
+partition by system_time (
+ partition p0 history,
+ partition pn current);
+
+--error ER_VERS_WRONG_PARTS
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+ partition p0 current);
+
+--error ER_VERS_WRONG_PARTS
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+ partition p0 current,
+ partition p1 current);
+
+--error ER_VERS_WRONG_PARTS
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+ partition p0 history,
+ partition p1 history);
+
+--error ER_VERS_WRONG_PARTS
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+ partition pn current,
+ partition p0 history);
+
+--error ER_VERS_WRONG_PARTS
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+ partition p0,
+ partition pn current);
+
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+ partition p0 history,
+ partition pn current);
+
+
+--echo ## ALTER TABLE
+
+--error ER_VERS_WRONG_PARTS
+alter table t1 add partition (
+ partition p1 current);
+
+alter table t1 add partition (
+ partition p1 history);
+
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+
+insert into t1 values (1), (2);
+
+--error ER_VERS_WRONG_PARTS
+alter table t1 drop partition pn;
+alter table t1 drop partition p1;
+--error ER_VERS_WRONG_PARTS
+alter table t1 drop partition p0;
+
+select x from t1;
+
+--echo # Bug #260: incorrect IB partitioning warning
+create or replace table t1 (x int)
+with system versioning
+partition by system_time limit 1 (
+ partition p0 history,
+ partition pn current);
+alter table t1 change x big int;
+
+create or replace table t1 (i int) engine myisam partition by hash(i) partitions 2;
+--error ER_PARTITION_WRONG_TYPE
+alter table t1 add partition (partition px history);
+
+
+--echo ## INSERT, UPDATE, DELETE
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+ partition p0 history,
+ partition pn current);
+
+set @now= now(6);
+insert into t1 values (1);
+set @str= concat('select x, row_start < @now as A, row_end > @now as B from t1 partition (p0)');
+prepare select_p0 from @str;
+set @str= concat('select x, row_start > @now as C, row_end = timestamp\'2038-01-19 03:14:07.999999\' as D from t1 partition (pn)');
+prepare select_pn from @str;
+
+execute select_p0;
+execute select_pn;
+
+set @str= concat('select row_start from t1 partition (pn) into @ts0');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+
+--source suite/versioning/wait_system_clock.inc
+
+set @now= now(6);
+delete from t1;
+execute select_p0;
+execute select_pn;
+
+set @str= concat('select row_start from t1 partition (p0) into @ts1');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+
+select @ts0 = @ts1;
+
+set @now= now(6);
+insert into t1 values (2);
+
+--source suite/versioning/wait_system_clock.inc
+
+execute select_p0;
+execute select_pn;
+
+set @str= concat('select row_start from t1 partition (pn) into @ts0');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+
+set @now= now(6);
+update t1 set x = x + 1;
+
+--source suite/versioning/wait_system_clock.inc
+
+execute select_p0;
+execute select_pn;
+
+drop prepare select_p0;
+drop prepare select_pn;
+
+set @str= concat('select row_start from t1 partition (p0) where x = 2 into @ts1');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+set @str= concat('select row_end from t1 partition (p0) where x = 2 into @ts2');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+set @str= concat('select row_start from t1 partition (pn) into @ts3');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+
+select @ts0 = @ts1;
+select @ts2 = @ts3;
+
+--echo ## rotation by LIMIT
+--error ER_PART_WRONG_VALUE
+create or replace table t1 (x int)
+with system versioning
+partition by system_time limit 0 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+create or replace table t1 (x int)
+with system versioning
+partition by system_time limit 2 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+
+--error ER_DROP_PARTITION_NON_EXISTENT
+alter table t1 drop partition non_existent;
+
+insert into t1 values (1), (2), (3), (4), (5), (6);
+select * from t1 partition (pn);
+delete from t1 where x < 4;
+delete from t1;
+select * from t1 partition (p0);
+select * from t1 partition (p1);
+
+insert into t1 values (7), (8);
+--echo ### warn about full partition
+delete from t1;
+select * from t1 partition (p1) order by x;
+
+--echo ### Assertion in ALTER on warning from partitioning LIMIT [#446]
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1), (2);
+delete from t1;
+alter table t1 partition by system_time limit 1 (
+ partition p1 history,
+ partition pn current);
+
+--echo ## rotation by INTERVAL
+--error ER_PART_WRONG_VALUE
+create or replace table t1 (x int)
+with system versioning
+partition by system_time interval 0 second (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+--error ER_PARSE_ERROR
+create or replace table t1 (x int)
+with system versioning
+partition by system_time interval 1 second starts 12345 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+--error ER_PARSE_ERROR
+create table t1 (i int) with system versioning
+ partition by system_time interval 6 day limit 98
+ (partition p0 history, partition ver_pn current);
+
+--echo ### ha_partition::update_row() check
+create or replace table t1 (x int)
+with system versioning
+partition by system_time interval 1 second (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+insert into t1 values (1), (2), (3), (4);
+select * from t1 partition (pn);
+delete from t1 where x < 3;
+
+--sleep 2
+delete from t1;
+
+select * from t1 partition (p0) order by x;
+select * from t1 partition (p1) order by x;
+
+--echo ### ha_partition::write_row() check
+create or replace table t1 (x int)
+with system versioning
+partition by system_time interval 1 second (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+insert into t1 values (1);
+update t1 set x= 2;
+sleep 2;
+update t1 set x= 3;
+select * from t1 partition (p0);
+select * from t1 partition (p1);
+
+--echo ## Subpartitions
+create or replace table t1 (x int)
+with system versioning
+partition by system_time limit 2
+subpartition by key (x)
+subpartitions 2 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+insert into t1 (x) values (1), (2), (3), (4), (5);
+select * from t1 partition (pnsp0);
+select * from t1 partition (pnsp1);
+
+--echo ### warn about full partition
+delete from t1 where x < 3;
+delete from t1;
+delete from t1;
+select * from t1 partition (p0sp0);
+select * from t1 partition (p0sp1);
+select * from t1 partition (p1sp0);
+select * from t1 partition (p1sp1);
+
+create or replace table t1 (a bigint)
+with system versioning
+partition by range (a)
+(partition p0 values less than (20) engine innodb,
+ partition p1 values less than maxvalue engine innodb);
+insert into t1 values (1);
+
+create or replace table t1 (
+ f_int1 integer default 0
+) with system versioning
+partition by range(f_int1)
+subpartition by hash(f_int1)
+( partition part1 values less than (1000)
+(subpartition subpart11 storage engine = 'innodb',
+subpartition subpart12 storage engine = 'innodb'));
+insert into t1 values (1);
+
+create or replace table t1 (i int) engine=innodb partition by key(i);
+alter table t1 add system versioning;
+insert into t1 values();
+
+--echo # MDEV-14722 Assertion in ha_commit_trans for sub-statement
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 day (
+ partition p1 history,
+ partition pc current);
+create or replace table t2 (f int);
+create or replace trigger tr before insert on t2
+for each row select table_rows from information_schema.tables
+where table_name = 't1' into @a;
+insert into t2 values (1);
+
+--echo # MDEV-14740 Locking assertion for system_time partitioning
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 week (
+ partition p1 history,
+ partition pn current);
+create or replace table t2 (f int);
+create or replace trigger tr before insert on t2
+for each row select count(*) from t1 into @a;
+insert into t2 values (1);
+
+--echo # MDEV-14741 Assertion `(trx)->start_file == 0' failed in row_truncate_table_for_mysql()
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 hour (
+ partition p1 history,
+ partition pn current);
+set autocommit= off;
+truncate table t1;
+set autocommit= on;
+
+--echo # MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES
+create or replace table t1 (x int) with system versioning;
+lock table t1 write;
+alter table t1 partition by system_time interval 1 week (
+ partition p1 history,
+ partition pn current);
+unlock tables;
+
+--echo # MDEV-14748 Assertion in ha_myisammrg::attach_children()
+create or replace table t1 (x int) engine=myisam with system versioning
+ partition by system_time interval 1 month (partition p1 history, partition pn current);
+create or replace table t2 (x int) engine=myisam;
+create or replace table t3 (x int) engine=merge union=(t2);
+create or replace table t4 (x int) engine=myisam;
+create or replace trigger tr after insert on t4 for each row insert into t2
+ ( select x from t3 ) union ( select x from t1 );
+insert into t4 values (1);
+
+--echo # MDEV-14821 Assertion failure
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (0), (1);
+update t1 set x= x + 1;
+alter table t1 partition by system_time limit 1 (
+ partition p1 history,
+ partition p2 history,
+ partition pn current);
+delete from t1 where x = 1;
+delete from t1 where x = 2;
+
+--echo # MDEV-14923 Assertion upon INSERT into locked versioned partitioned table
+create or replace table t1 (x int) with system versioning
+partition by system_time (partition p1 history, partition pn current);
+lock table t1 write;
+--error ER_SAME_NAME_PARTITION
+alter table t1 add partition (partition p1 history);
+insert into t1 values (1);
+unlock tables;
+
+--error ER_DATA_OUT_OF_RANGE
+create or replace table t1 (pk int) with system versioning
+partition by system_time interval 10 year (
+ partition p1 history,
+ partition p2 history,
+ partition pn current
+);
+
+# INTERVAL and ALTER TABLE
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 hour (
+ partition p0 history, partition pn current);
+
+set @ts=(select partition_description from information_schema.partitions
+ where table_schema='test' and table_name='t1' and partition_name='p0');
+
+alter table t1 add column b int;
+select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
+alter table t1 add partition (partition p1 history, partition p2 history);
+select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
+alter table t1 drop partition p0;
+select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
+--error ER_VERS_DROP_PARTITION_INTERVAL
+alter table t1 drop partition p2;
+select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
+
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 second
+ subpartition by key (i) subpartitions 2
+ (partition p1 history, partition pn current);
+insert t1 values (1); delete from t1;
+sleep 1;
+insert t1 values (2); delete from t1;
+alter table t1 add partition (partition p0 history, partition p2 history);
+select subpartition_name,table_rows from information_schema.partitions where table_schema='test' and table_name='t1';
+
+--echo ## pruning check
+set @ts=(select partition_description from information_schema.partitions
+ where table_schema='test' and table_name='t1' and partition_name='p0' limit 1);
+insert into t1 values (4),(5);
+--sorted_result
+select * from t1;
+explain partitions select * from t1;
+--replace_column 10 #
+explain partitions select * from t1 for system_time as of from_unixtime(@ts);
+set @ts=(select row_end from t1 for system_time all where i=1);
+select * from t1 for system_time all where row_end = @ts;
+--replace_column 5 # 10 # 11 #
+explain partitions select * from t1 for system_time all where row_end = @ts;
+
+--echo #
+--echo # MDEV-15103 Assertion in ha_partition::part_records() for updating VIEW
+--echo #
+create or replace table t1 (pk int primary key, f int) with system versioning
+partition by system_time limit 100 (partition p1 history, partition pn current);
+insert into t1 values (1,10), (2,20);
+create or replace view v1 as select * from t1;
+update v1 set f= 30;
+
+--echo #
+--echo # MDEV-15168 Unexpected ER_VERS_ENGINE_UNSUPPORTED upon dropping versioning on a partitioned table
+--echo #
+create or replace table t (a int) with system versioning
+ partition by system_time (partition p1 history, partition pn current);
+--error ER_DROP_VERSIONING_SYSTEM_TIME_PARTITION
+alter table t drop system versioning;
+
+--echo # MDEV-15191 Assertion `bit < (map)->n_bits' failed in bitmap_is_set upon INSERT
+create or replace table t1 (i int) with system versioning;
+insert into t1 values (1), (2);
+update t1 set i= 3;
+alter table t1 partition by system_time interval 1 month (partition p1 history, partition pn current);
+lock table t1 write;
+alter table t1 add partition (partition p2 history);
+insert into t1 values (4);
+unlock tables;
+
+--echo # MDEV-15036 Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' in Diagnostics_area::set_ok_status or unexpected ER_RANGE_NOT_INCREASING_ERROR
+create or replace table t1 (a int) with system versioning
+partition by system_time limit 2 (
+ partition p1 history, partition p2 history,
+ partition p3 history, partition pn current);
+insert into t1 values (1),(2),(3);
+update t1 set a = 4;
+delete from t1;
+delete from t1 where a is not null;
+
+--echo # Test cleanup
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/t/replace.test b/mysql-test/suite/versioning/t/replace.test
new file mode 100644
index 00000000000..194606555db
--- /dev/null
+++ b/mysql-test/suite/versioning/t/replace.test
@@ -0,0 +1,13 @@
+--source suite/versioning/common.inc
+--source suite/versioning/key_type.inc
+--source suite/versioning/engines.inc
+
+call create_table('t', 'x int');
+
+insert t values (1, 2);
+replace t values (1, 3);
+select *, row_end>TIMESTAMP'2038-01-01 00:00:00' as current from t for system_time all
+order by x;
+
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/t/rpl.test b/mysql-test/suite/versioning/t/rpl.test
new file mode 100644
index 00000000000..a9e3af45af8
--- /dev/null
+++ b/mysql-test/suite/versioning/t/rpl.test
@@ -0,0 +1,136 @@
+--source suite/versioning/engines.inc
+--source include/have_partition.inc
+--source include/master-slave.inc
+
+#BUG#12662190 - COM_COMMIT IS NOT INCREMENTED FROM THE BINARY LOGS ON SLAVE, COM_BEGIN IS
+#Testing command counters -BEFORE.
+#Storing the before counts of Slave
+connection slave;
+let $slave_com_commit_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_commit', Value, 1);
+let $slave_com_insert_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_insert', Value, 1);
+let $slave_com_delete_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_delete', Value, 1);
+let $slave_com_update_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_update', Value, 1);
+
+connection master;
+CREATE TABLE t1 (x int) with system versioning;
+insert into t1 values (1);
+SELECT * FROM t1;
+delete from t1;
+select * from t1;
+select * from t1 for system_time all;
+sync_slave_with_master;
+select * from t1;
+select * from t1 for system_time all;
+
+connection master;
+insert into t1 values (2);
+sync_slave_with_master;
+select * from t1;
+
+connection master;
+update t1 set x = 3;
+sync_slave_with_master;
+select * from t1;
+select * from t1 for system_time all;
+
+--echo # check unversioned -> versioned replication
+connection master;
+create or replace table t1 (x int primary key);
+sync_slave_with_master;
+alter table t1 with system versioning;
+
+connection master;
+insert into t1 values (1);
+sync_slave_with_master;
+select * from t1;
+select * from t1 for system_time all;
+
+connection master;
+update t1 set x= 2 where x = 1;
+sync_slave_with_master;
+select * from t1;
+select * from t1 for system_time all;
+
+connection master;
+delete from t1;
+sync_slave_with_master;
+select * from t1;
+select * from t1 for system_time all;
+
+--echo # same thing (UPDATE, DELETE), but without PK
+connection master;
+create or replace table t1 (x int);
+sync_slave_with_master;
+alter table t1 with system versioning;
+
+connection master;
+insert into t1 values (1);
+update t1 set x= 2 where x = 1;
+sync_slave_with_master;
+select * from t1;
+select * from t1 for system_time all;
+
+connection master;
+delete from t1;
+sync_slave_with_master;
+select * from t1;
+select * from t1 for system_time all;
+
+--echo # multi-update
+connection master;
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (x int) with system versioning;
+insert into t1 values (1);
+insert into t2 values (2);
+update t1, t2 set t1.x=11, t2.x=22;
+sync_slave_with_master;
+select * from t1;
+select * from t2;
+select * from t1 for system_time all;
+select * from t2 for system_time all;
+
+--echo # MDEV-14767 system_versioning_alter_history breaks ALTER replication
+--echo ## Case 1: KEEP on the master, ALTER will work on the slave
+connection master;
+create or replace table t1 (a int) with system versioning;
+set system_versioning_alter_history= KEEP;
+alter table t1 add column b int;
+sync_slave_with_master;
+--replace_result InnoDB INNODB_OR_MYISAM MyISAM INNODB_OR_MYISAM
+show create table t1;
+
+--echo ## Case 2: ERROR on the master, it'll fail on the master, the slave won't see it
+connection master;
+set system_versioning_alter_history= ERROR;
+--error ER_VERS_ALTER_NOT_ALLOWED
+alter table t1 drop column b;
+sync_slave_with_master;
+--replace_result InnoDB INNODB_OR_MYISAM MyISAM INNODB_OR_MYISAM
+show create table t1;
+
+--echo ## Case 3: table is not versioned on the master, ALTER will work on the slave
+connection master;
+create or replace table t1 (a int);
+sync_slave_with_master;
+create or replace table t1 (a int) with system versioning;
+connection master;
+alter table t1 add column b int;
+sync_slave_with_master;
+--replace_result InnoDB INNODB_OR_MYISAM MyISAM INNODB_OR_MYISAM
+show create table t1;
+
+connection master;
+drop table t1, t2;
+
+#
+# MDEV-15395 Wrong result or Assertion `old_part_id == m_last_part' failed in ha_partition::update_row on slave
+#
+create table t1 (i int) with system versioning partition by system_time limit 8 ( partition p1 history, partition p2 history, partition pn current );
+insert into t1 values (1);
+update t1 set i = 1;
+update t1 set i = 0;
+sync_slave_with_master;
+connection master;
+drop table t1;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test
new file mode 100644
index 00000000000..2f24f7d8fc0
--- /dev/null
+++ b/mysql-test/suite/versioning/t/select.test
@@ -0,0 +1,307 @@
+--source suite/versioning/engines.inc
+--source suite/versioning/common.inc
+
+# test_01
+
+--replace_result $sys_datatype_expl SYS_DATATYPE
+eval create or replace table t1 (
+ x int unsigned,
+ y int unsigned,
+ sys_trx_start $sys_datatype_expl as row start invisible,
+ sys_trx_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end)
+) with system versioning;
+
+insert into t1 (x, y) values
+ (0, 100),
+ (1, 101),
+ (2, 102),
+ (3, 103),
+ (4, 104),
+ (5, 105),
+ (6, 106),
+ (7, 107),
+ (8, 108),
+ (9, 109);
+
+set @t0= now(6);
+if ($MTR_COMBINATION_TRX_ID)
+{
+--disable_query_log
+ select sys_trx_start from t1 limit 1 into @x0;
+--enable_query_log
+}
+
+delete from t1 where x = 3;
+delete from t1 where x > 7;
+
+insert into t1(x, y) values(3, 33);
+select sys_trx_start from t1 where x = 3 and y = 33 into @t1;
+if ($MTR_COMBINATION_TRX_ID)
+{
+--disable_query_log
+ set @x1= @t1;
+ select vtq_commit_ts(@x1) into @t1;
+--enable_query_log
+}
+
+select x, y from t1;
+select x as ASOF_x, y from t1 for system_time as of timestamp @t0;
+select x as FROMTO_x, y from t1 for system_time from timestamp '0-0-0 0:0:0' to timestamp @t1;
+select x as BETWAND_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1;
+select x as ALL_x, y from t1 for system_time all;
+
+--disable_query_log
+if ($MTR_COMBINATION_TRX_ID)
+{
+ select x as ASOF2_x, y from t1 for system_time as of @x0;
+ select x as FROMTO2_x, y from t1 for system_time from @x0 to @x1;
+ select x as BETWAND2_x, y from t1 for system_time between transaction @x0 and transaction @x1;
+}
+if ($MTR_COMBINATION_TIMESTAMP)
+{
+ select x as ASOF2_x, y from t1 for system_time as of @t0;
+ select x as FROMTO2_x, y from t1 for system_time from timestamp '0-0-0 0:0:0' to timestamp @t1;
+ select x as BETWAND2_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1;
+}
+--enable_query_log
+
+# test_02
+
+create or replace table t1 (
+ x int unsigned,
+ y int unsigned
+) with system versioning;
+create or replace table t2 (
+ x int unsigned,
+ y int unsigned
+) with system versioning;
+
+insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
+insert into t2 values (1, 2), (2, 1), (3, 1);
+set @t0= now(6);
+
+select t1.x as IJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x;
+select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x;
+select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x;
+
+delete from t1;
+delete from t2;
+
+#384
+explain extended 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;
+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;
+#383
+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;
+
+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;
+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;
+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;
+
+drop table t1;
+drop table t2;
+
+# Wildcard expansion on hidden fields
+
+create table t1(
+ A int
+) with system versioning;
+insert into t1 values(1);
+select * from t1;
+
+create or replace table t1 (x int);
+insert into t1 values (1);
+--error ER_VERS_NOT_VERSIONED
+select * from t1 for system_time all;
+
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+select * from t1 for system_time all for update;
+
+create or replace table t1 (a int not null auto_increment primary key) with system versioning;
+select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
+
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (a int) with system versioning;
+insert into t1 values(1);
+insert into t2 values(1);
+create view v1 as select * from t2 inner join t1 using (a);
+select * from v1;
+drop view v1;
+
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create view vt1 as select a from t1;
+select * from t1 natural join vt1;
+drop view vt1;
+
+create or replace table t1(x int) with system versioning;
+select * from (t1 as r left join t1 as u using (x)), t1;
+
+# @end should be max
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create trigger read_end after update on t1
+ for each row set @end = old.row_end;
+update t1 set a=2;
+--replace_result 18446744073709551615 MAX_RESULT "2038-01-19 03:14:07.999999" MAX_RESULT
+select @end;
+
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int) with system versioning;
+insert into t1 values (1);
+insert into t2 values (2);
+select * from (select * from t1 cross join t2) as tmp;
+select * from (select * from (select * from t1 cross join t2) as tmp1) as tmp2;
+select * from (select * from t1 cross join t2 for system_time as of timestamp ('0-0-0')) as tmp;
+
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+select * from t1 for system_time all natural left join t2 for system_time all;
+
+# natural join of a view and table
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+create or replace view v1 as select a1 from t1;
+
+select * from v1 natural join t2;
+select * from v1 natural left join t2;
+select * from v1 natural right join t2;
+
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int) with system versioning;
+insert into t1 values (1), (2), (3);
+delete from t1 where x = 3;
+insert into t2 values (1);
+select * from t1, t2 for system_time all;
+
+--error ER_VERS_NOT_VERSIONED
+select * from (select * from t1 for system_time all, t2 for system_time all)
+for system_time all as t;
+
+--echo # TRANSACTION/TIMESTAMP specifier in SYSTEM_TIME [MDEV-14645, Issue #396]
+create or replace table t1 (x int) with system versioning engine myisam;
+--error ER_VERS_ENGINE_UNSUPPORTED
+select * from t1 for system_time as of transaction 1;
+
+create or replace table t1 (
+ x int,
+ sys_trx_start bigint unsigned as row start invisible,
+ sys_trx_end bigint unsigned as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end)
+) with system versioning engine innodb;
+insert into t1 values (1);
+set @ts= now(6);
+delete from t1;
+select sys_trx_start from t1 for system_time all into @trx_start;
+
+--echo ## ensure @trx_start is much lower than unix timestamp
+select @trx_start < unix_timestamp(@ts) - 100 as trx_start_good;
+
+--echo ## TIMESTAMP specifier
+select x from t1 for system_time as of timestamp @ts;
+
+set @ts= timestamp'1-1-1 0:0:0';
+
+--echo ## TRANSACTION specifier
+select x from t1 for system_time as of transaction @trx_start;
+
+--echo ## no specifier (auto-detection)
+select x from t1 for system_time as of @ts;
+select x from t1 for system_time as of @trx_start;
+
+--echo ### Issue #365, bug 4 (related to #226, optimized fields)
+create or replace table t1 (i int, b int) with system versioning;
+insert into t1 values (0, 0), (0, 0);
+select min(i) over (partition by b) as f
+from (select i + 0 as i, b from t1) as tt
+order by i;
+
+--echo ### Issue #365, bug 5 (dangling AND)
+create or replace table t1 (a int);
+create or replace table t2 (b int) with system versioning;
+select * from t1
+where exists (select 1 from t2 where t2.b = t1.a and t2.b = t1.a);
+
+--echo ### Issue #365, bug 9 (not a derived subquery)
+create or replace table t1 (x int) with system versioning;
+select t1.x in (select x from t1) a from t1, (select x from t1) b;
+
+--echo ### Issue #365, bug 10 (WHERE cond freed prematurely for PS)
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+create or replace view v1 as select x from t1 where x = 1;
+prepare stmt from "
+select x from t1 where x in (select x from v1);";
+execute stmt;
+execute stmt;
+
+--echo ### Issue #365, bug 11 (WHERE cond not top level item)
+create or replace table t1 (a int, b int, key idx(a)) with system versioning;
+insert into t1 values (1, 1), (2, 2);
+select * from t1 where (a, 2) in ((1, 1), (2, 2)) and b = 1;
+
+--echo ### Issue #398, NOW is now non-magic
+create or replace table t1 (x int) with system versioning;
+select * from t1 for system_time as of current_timestamp;
+--error ER_BAD_FIELD_ERROR
+select * from t1 for system_time as of now;
+
+--echo ### Issue #405, NATURAL JOIN failure
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int);
+create or replace view v1 as select a, row_start, row_end from t1 where a > round(rand()*1000);
+select * from v1 natural join t2;
+
+--echo ### Issue #406, MDEV-14633 Assertion on TRT read
+create or replace table t1 (pk int primary key, i int, t time, key (i)) with system versioning;
+insert into t1 values (1, 10, '15:01:53'), (2, 20, '00:00:00');
+delete from t1;
+--disable_warnings
+select * from t1 where t = '00:00:00' and i > 0 and row_end <> '2012-12-12 00:00:00';
+--enable_warnings
+
+--echo ### MDEV-14816 Assertion `join->best_read < double(1.797...e+308L)' failed in bool greedy_search
+create or replace table t1 (f1 int) with system versioning;
+create or replace table t2 (f2 int) with system versioning;
+create or replace table t3 (f3 int);
+create or replace table t4 (f4 int);
+insert into t1 values (1), (2), (3), (4);
+insert into t2 values (1), (2), (3);
+insert into t3 values (1), (2);
+insert into t4 values (1);
+select * from
+ t1 as t1a
+ left join t2 as t2a left join (t3 as t3a inner join t1) on t2a.f2 = t3a.f3 on t1a.f1 = t2a.f2
+ left join (t2 join t3 inner join t4) on t2a.f2 = t1a.f1;
+
+--echo ### MDEV-15004 parser greedily parses AS OF TIMESTAMP
+--error ER_WRONG_VALUE
+select timestamp'2016-02-30 08:07:06';
+--error ER_WRONG_VALUE
+select * from t1 for system_time as of timestamp'2016-02-30 08:07:06';
+select timestamp('2003-12-31 12:00:00','12:00:00');
+select * from t1 for system_time as of timestamp('2003-12-31 12:00:00','12:00:00');
+
+drop view v1;
+drop table t1, t2, t3, t4;
+
+call verify_vtq_dummy(34);
+
+-- source suite/versioning/common_finish.inc
diff --git a/mysql-test/suite/versioning/t/select2.test b/mysql-test/suite/versioning/t/select2.test
new file mode 100644
index 00000000000..bedda892c82
--- /dev/null
+++ b/mysql-test/suite/versioning/t/select2.test
@@ -0,0 +1,208 @@
+--source suite/versioning/engines.inc
+--source suite/versioning/common.inc
+
+replace_result $default_engine ENGINE $sys_datatype_expl SYS_TYPE;
+eval create table t1(
+ x int unsigned,
+ y int unsigned,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_start, sys_end))
+with system versioning engine=$default_engine;
+
+insert into t1 (x, y) values
+ (0, 100),
+ (1, 101),
+ (2, 102),
+ (3, 103),
+ (4, 104),
+ (5, 105),
+ (6, 106),
+ (7, 107),
+ (8, 108),
+ (9, 109);
+set @t0= now(6);
+select sys_start from t1 limit 1 into @x0;
+
+delete from t1 where x = 3;
+delete from t1 where x > 7;
+
+insert into t1(x, y) values(3, 33);
+select sys_start from t1 where x = 3 and y = 33 into @t1;
+if($MTR_COMBINATION_TRX_ID) {
+ set @x1= @t1;
+ select vtq_commit_ts(@x1) into @t1;
+}
+
+select x, y from t1;
+select x as ASOF_x, y from t1 for system_time as of timestamp @t0;
+select x as FROMTO_x, y from t1 for system_time from '0-0-0 0:0:0' to timestamp @t1;
+select x as BETWAND_x, y from t1 for system_time between '0-0-0 0:0:0' and timestamp @t1;
+select x as ALL_x, y from t1 for system_time all;
+
+if($MTR_COMBINATION_TRX_ID) {
+ select x as ASOF2_x, y from t1 for system_time as of @x0;
+ select x as FROMTO2_x, y from t1 for system_time from @x0 to @x1;
+ select x as BETWAND2_x, y from t1 for system_time between transaction @x0 and transaction @x1;
+}
+if(!$MTR_COMBINATION_TRX_ID) {
+ select x as ASOF2_x, y from t1 for system_time as of @t0;
+ select x as FROMTO2_x, y from t1 for system_time from '0-0-0 0:0:0' to @t1;
+ select x as BETWAND2_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1;
+}
+
+drop table t1;
+
+replace_result $default_engine ENGINE $sys_datatype_expl SYS_TYPE;
+eval create table t1(
+ x int,
+ y int,
+ sys_start $sys_datatype_expl as row start invisible,
+ sys_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_start, sys_end))
+with system versioning engine=$default_engine;
+
+create table t2 like t1;
+
+insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
+insert into t2 values (1, 2), (2, 1), (3, 1);
+set @t0= now(6);
+
+select t1.x as IJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x;
+select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x;
+select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x;
+
+delete from t1;
+delete from t2;
+
+select IJ2_x1,y1,x2,y2 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;
+select LJ2_x1,y1,x2,y2 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;
+select RJ2_x1,y1,x2,y2 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;
+
+drop table t1;
+drop table t2;
+
+--echo # MDEV-14686 Server crashes in Item_field::used_tables on 2nd call of SP [#422]
+create or replace table t1 (called int, bad int) with system versioning;
+create or replace procedure bad() select * from t1 where bad in (select called from t1);
+--disable_query_log
+call bad; call bad; call bad; call bad; call bad; call bad; call bad; call bad;
+drop procedure bad;
+--enable_query_log
+--echo # bad() is good.
+
+--echo # MDEV-14751 Server crashes in TABLE::versioned on 2nd execution of SP [#431]
+create or replace table t1 (called_bad int);
+create or replace table t2 (b int);
+create or replace procedure bad() select * from t1 where ( 5, 6 ) in ( select b, b from t2 ) and called_bad in ( select max(b) from t2 );
+--disable_query_log
+call bad; call bad; call bad; call bad; call bad; call bad; call bad; call bad;
+drop procedure bad;
+--enable_query_log
+--echo # bad() is good.
+
+--echo # MDEV-14786 Server crashes in Item_cond::transform on 2nd execution of SP querying from a view [#436]
+create or replace table t1 (called_bad int) with system versioning;
+create or replace view v1 as select called_bad from t1 where called_bad < 5;
+create or replace procedure bad() select called_bad from v1;
+--disable_query_log
+call bad; call bad; call bad; call bad; call bad; call bad; call bad; call bad;
+drop procedure bad;
+--enable_query_log
+--echo # bad() is good.
+
+--echo # wildcard expansion on hidden fields.
+create or replace table t1(
+ A int
+) with system versioning;
+insert into t1 values(1);
+select * from t1;
+
+create or replace table t1 (x int);
+insert into t1 values (1);
+--error ER_VERS_NOT_VERSIONED
+select * from t1 for system_time all;
+
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+select * from t1 for system_time as of now() for update;
+
+create or replace table t1 (a int not null auto_increment primary key) with system versioning;
+select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
+
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (a int) with system versioning;
+insert into t1 values(1);
+insert into t2 values(1);
+create or replace view v1 as select * from t2 inner join t1 using (a);
+select * from v1;
+drop view v1;
+
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create view vt1 as select a from t1;
+select * from t1 natural join vt1;
+drop view vt1;
+
+create or replace table t1(x int) with system versioning;
+select * from (t1 as r left join t1 as u using (x)), t1;
+
+# @end should be max
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create trigger read_end after update on t1
+ for each row set @end = old.row_end;
+update t1 set a=2;
+--replace_result 18446744073709551615 MAX_RESULT "2038-01-19 03:14:07.999999" MAX_RESULT
+select @end;
+
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int) with system versioning;
+insert into t1 values (1);
+insert into t2 values (2);
+select * from (select * from t1 cross join t2) as tmp;
+select * from (select * from (select * from t1 cross join t2) as tmp1) as tmp2;
+select * from (select * from t1 cross join t2 for system_time as of timestamp ('0-0-0')) as tmp;
+
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+select * from t1 for system_time all natural left join t2 for system_time all;
+
+# natural join of a view and table
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+create or replace view v1 as select a1 from t1;
+
+select * from v1 natural join t2;
+select * from v1 natural left join t2;
+select * from v1 natural right join t2;
+
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int) with system versioning;
+insert into t1 values (1), (2), (3);
+delete from t1 where x = 3;
+insert into t2 values (1);
+select * from t1, t2 for system_time all;
+
+--error ER_VERS_NOT_VERSIONED
+select * from (select * from t1 for system_time all, t2 for system_time all) for system_time all as t;
+--error ER_PARSE_ERROR
+select * from (t1 for system_time all join t2 for system_time all) for system_time all;
+
+drop view v1;
+drop table t1, t2;
+
+-- source suite/versioning/common_finish.inc
diff --git a/mysql-test/suite/versioning/t/simple.test b/mysql-test/suite/versioning/t/simple.test
new file mode 100644
index 00000000000..d61e9ffd47c
--- /dev/null
+++ b/mysql-test/suite/versioning/t/simple.test
@@ -0,0 +1,73 @@
+-- source include/have_innodb.inc
+set default_storage_engine=innodb;
+create or replace table dept (
+ dept_id int(10) primary key,
+ name varchar(100)
+)
+with system versioning;
+
+create or replace table emp (
+ emp_id int(10) primary key,
+ dept_id int(10),
+ name varchar(100),
+ salary int(10),
+ constraint `dept-emp-fk`
+ foreign key (dept_id) references dept (dept_id)
+ on delete restrict
+ on update restrict
+)
+with system versioning;
+
+select now() into @ts_0;
+
+insert into dept (dept_id, name) values (10, "accounting");
+commit;
+
+select row_start into @ts_1 from dept where dept_id=10;
+
+insert into emp (emp_id, name, salary, dept_id) values (1, "bill", 1000, 10);
+commit;
+
+select row_start into @ts_2 from emp where name="bill";
+
+select * from emp;
+
+update emp set salary=2000 where name="bill";
+commit;
+
+select row_start into @ts_3 from emp where name="bill";
+
+select * from emp;
+select * from emp for system_time as of timestamp @ts_2;
+select * from emp for system_time as of timestamp @ts_3;
+select * from emp e, dept d
+where d.dept_id = 10
+ and d.dept_id = e.dept_id;
+
+select * from
+ emp for system_time from timestamp @ts_1 to timestamp @ts_2 e,
+ dept for system_time from timestamp @ts_1 to timestamp @ts_2 d
+where d.dept_id = 10
+ and d.dept_id = e.dept_id;
+
+set statement system_versioning_asof=@ts_0 for
+select * from emp e, dept d
+where d.dept_id = 10
+ and d.dept_id = e.dept_id;
+
+set statement system_versioning_asof=@ts_1 for
+select * from emp e, dept d
+where d.dept_id = 10
+ and d.dept_id = e.dept_id;
+
+set statement system_versioning_asof=@ts_2 for
+select * from emp e, dept d
+where d.dept_id = 10
+ and d.dept_id = e.dept_id;
+
+set statement system_versioning_asof=@ts_3 for
+select * from emp e, dept d
+where d.dept_id = 10
+ and d.dept_id = e.dept_id;
+
+drop table emp, dept;
diff --git a/mysql-test/suite/versioning/t/sysvars.test b/mysql-test/suite/versioning/t/sysvars.test
new file mode 100644
index 00000000000..08b520e959e
--- /dev/null
+++ b/mysql-test/suite/versioning/t/sysvars.test
@@ -0,0 +1,87 @@
+create table t (a int) with system versioning;
+insert into t values (1);
+update t set a= 2;
+
+show global variables like 'system_versioning_asof';
+show variables like 'system_versioning_asof';
+select * from t;
+
+set system_versioning_asof= '2031-1-1 0:0:0';
+show variables like 'system_versioning_asof';
+select * from t;
+
+set system_versioning_asof= '2011-1-1 0:0:0';
+show variables like 'system_versioning_asof';
+select * from t;
+
+# global
+--error ER_WRONG_VALUE_FOR_VAR
+set global system_versioning_asof= 'alley';
+--error ER_WRONG_VALUE_FOR_VAR
+set global system_versioning_asof= null;
+--error ER_WRONG_TYPE_FOR_VAR
+set global system_versioning_asof= 1;
+--error ER_WRONG_TYPE_FOR_VAR
+set global system_versioning_asof= 1.1;
+
+# session
+--error ER_WRONG_VALUE_FOR_VAR
+set system_versioning_asof= 'alley';
+--error ER_WRONG_VALUE_FOR_VAR
+set system_versioning_asof= null;
+--error ER_WRONG_TYPE_FOR_VAR
+set system_versioning_asof= 1;
+--error ER_WRONG_TYPE_FOR_VAR
+set system_versioning_asof= 1.1;
+
+--echo # GLOBAL @@system_versioning_asof
+set global system_versioning_asof= '1911-11-11 11:11:11.1111119';
+show global variables like 'system_versioning_asof';
+
+set global system_versioning_asof= '1900-01-01 00:00:00';
+show global variables like 'system_versioning_asof';
+
+set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
+show global variables like 'system_versioning_asof';
+
+set @ts= timestamp'1900-01-01 00:00:00';
+set global system_versioning_asof= @ts;
+show global variables like 'system_versioning_asof';
+
+set global system_versioning_asof= default;
+select @@global.system_versioning_asof;
+
+--echo # SESSION @@system_versioning_asof
+set system_versioning_asof= '1911-11-11 11:11:11.1111119';
+show variables like 'system_versioning_asof';
+
+set system_versioning_asof= '1900-01-01 00:00:00';
+show variables like 'system_versioning_asof';
+
+set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
+show variables like 'system_versioning_asof';
+
+set @ts= timestamp'1900-01-01 00:00:00';
+set system_versioning_asof= @ts;
+show variables like 'system_versioning_asof';
+
+--echo # DEFAULT: value is copied from GLOBAL to SESSION
+set global system_versioning_asof= timestamp'1911-11-11 11:11:11.111111';
+set system_versioning_asof= '1900-01-01 00:00:00';
+select @@global.system_versioning_asof != @@system_versioning_asof as different;
+set system_versioning_asof= default;
+select @@global.system_versioning_asof = @@system_versioning_asof as equal;
+
+set global system_versioning_asof= DEFAULT;
+set system_versioning_asof= DEFAULT;
+select @@global.system_versioning_asof, @@system_versioning_asof;
+
+select * from t for system_time all;
+
+select * from t;
+select * from t for system_time as of timestamp current_timestamp(6);
+select * from t for system_time all;
+select * from t for system_time from '0-0-0' to current_timestamp(6);
+select * from t for system_time between '0-0-0' and current_timestamp(6);
+
+drop table t;
diff --git a/mysql-test/suite/versioning/t/truncate.test b/mysql-test/suite/versioning/t/truncate.test
new file mode 100644
index 00000000000..f52d52d81ea
--- /dev/null
+++ b/mysql-test/suite/versioning/t/truncate.test
@@ -0,0 +1,90 @@
+--source include/have_partition.inc
+--source suite/versioning/engines.inc
+
+create table t (a int);
+--error ER_VERS_NOT_VERSIONED
+delete history from t before system_time now();
+
+# TRUNCATE is not DELETE and trigger must not be called.
+create or replace table t (a int) with system versioning;
+insert into t values (1);
+update t set a=2;
+set @test = 'correct';
+create trigger trg_before before delete on t for each row set @test = 'incorrect';
+create trigger trg_after after delete on t for each row set @test = 'incorrect';
+delete history from t;
+select @test from t;
+drop table t;
+
+create table t (a int) with system versioning;
+insert into t values (1), (2);
+update t set a=11 where a=1;
+--real_sleep 0.01
+set @ts1=now(6);
+--real_sleep 0.01
+update t set a=22 where a=2;
+select * from t for system_time all;
+delete history from t before system_time timestamp @ts1;
+select * from t for system_time all;
+prepare stmt from 'delete history from t';
+execute stmt; drop prepare stmt;
+select * from t for system_time all;
+delete from t;
+
+delimiter ~~;
+create or replace procedure truncate_sp()
+begin
+ delete history from t before system_time timestamp now(6);
+end~~
+delimiter ;~~
+call truncate_sp;
+select * from t for system_time all;
+
+drop procedure truncate_sp;
+
+--echo # Truncate partitioned
+create or replace table t (a int)
+with system versioning
+engine myisam
+partition by system_time limit 1 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+insert into t values (1);
+update t set a= 2;
+update t set a= 3;
+delete history from t;
+select * from t for system_time all;
+
+--echo # VIEW
+create or replace table t (i int) with system versioning;
+delete history from t;
+create or replace view v as select * from t;
+--error ER_IT_IS_A_VIEW
+delete history from v;
+
+create or replace table t (i int);
+--error ER_VERS_NOT_VERSIONED
+delete history from t;
+create or replace view v as select * from t;
+--error ER_IT_IS_A_VIEW
+delete history from v;
+--error ER_VERS_NOT_VERSIONED
+prepare stmt from 'delete history from t';
+
+drop table t;
+drop view v;
+
+#
+# MDEV-15402 Assertion `table' failed in mysql_delete on attempt to delete history from view
+#
+create or replace table t (i int);
+create or replace view v as select * from t;
+--error ER_IT_IS_A_VIEW
+drop table v;
+lock table v write;
+--error ER_IT_IS_A_VIEW
+delete history from v before system_time now(6);
+unlock tables;
+drop view v;
+drop table t;
diff --git a/mysql-test/suite/versioning/t/truncate_privilege.test b/mysql-test/suite/versioning/t/truncate_privilege.test
new file mode 100644
index 00000000000..dcdad59039a
--- /dev/null
+++ b/mysql-test/suite/versioning/t/truncate_privilege.test
@@ -0,0 +1,41 @@
+# Can't test with embedded server
+-- source include/not_embedded.inc
+
+--source include/have_innodb.inc
+
+# Save the initial number of concurrent sessions
+--source include/count_sessions.inc
+
+connect (root,localhost,root,,test);
+connection root;
+
+--disable_warnings
+create database mysqltest;
+--enable_warnings
+
+create user mysqltest_1@localhost;
+connect (user1,localhost,mysqltest_1,,test);
+connection user1;
+
+connection root;
+create table mysqltest.t (a int) with system versioning;
+
+connection user1;
+show grants;
+--error ER_TABLEACCESS_DENIED_ERROR
+delete history from mysqltest.t before system_time now();
+
+connection root;
+grant delete history on mysqltest.* to mysqltest_1@localhost;
+grant delete history on mysqltest.t to mysqltest_1@localhost;
+
+connection user1;
+show grants;
+delete history from mysqltest.t before system_time now();
+
+connection root;
+grant all on *.* to mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+
+drop user mysqltest_1@localhost;
+drop database mysqltest;
diff --git a/mysql-test/suite/versioning/t/trx_id.test b/mysql-test/suite/versioning/t/trx_id.test
new file mode 100644
index 00000000000..f1dbbf66cae
--- /dev/null
+++ b/mysql-test/suite/versioning/t/trx_id.test
@@ -0,0 +1,119 @@
+-- source include/have_innodb.inc
+-- source include/not_embedded.inc
+
+create or replace table t1 (
+ x int,
+ sys_trx_start bigint(20) unsigned as row start invisible,
+ sys_trx_end bigint(20) unsigned as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end)
+) with system versioning engine innodb;
+
+insert into t1 (x) values (1);
+
+--echo # ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry
+set @@system_versioning_alter_history=keep;
+
+create or replace table t1 (x int) engine innodb;
+insert into t1 values (1);
+alter table t1
+ add column s bigint unsigned as row start,
+ add column e bigint unsigned as row end,
+ add period for system_time(s, e),
+ add system versioning,
+ algorithm=inplace;
+select s from t1 into @trx_start;
+select count(*) = 1 from mysql.transaction_registry where transaction_id = @trx_start;
+
+create or replace table t1 (x int) engine innodb;
+select count(*) from mysql.transaction_registry into @tmp;
+alter table t1
+ add column s bigint unsigned as row start,
+ add column e bigint unsigned as row end,
+ add period for system_time(s, e),
+ add system versioning,
+ algorithm=inplace;
+select count(*) = @tmp from mysql.transaction_registry;
+
+create or replace table t1 (x int) engine innodb;
+insert into t1 values (1);
+alter table t1
+ add column s bigint unsigned as row start,
+ add column e bigint unsigned as row end,
+ add period for system_time(s, e),
+ add system versioning,
+ algorithm=copy;
+select s from t1 into @trx_start;
+select count(*) = 1 from mysql.transaction_registry where transaction_id = @trx_start;
+
+create or replace table t1 (x int) engine innodb;
+select count(*) from mysql.transaction_registry into @tmp;
+alter table t1
+ add column s bigint unsigned as row start,
+ add column e bigint unsigned as row end,
+ add period for system_time(s, e),
+ add system versioning,
+ algorithm=copy;
+# With MDEV-14511 the transaction will be registered even for empty tables.
+select count(*) = @tmp + 1 from mysql.transaction_registry;
+
+--echo # TRX_ID to TIMESTAMP versioning switch
+create or replace table t1 (
+ x int,
+ sys_start bigint unsigned as row start invisible,
+ sys_end bigint unsigned as row end invisible,
+ period for system_time (sys_start, sys_end)
+) engine innodb with system versioning;
+insert into t1 values (1);
+alter table t1 drop column sys_start, drop column sys_end;
+select row_end = 18446744073709551615 as transaction_based from t1 for system_time all;
+
+--echo # Simple vs SEES algorithms
+create or replace table t1 (
+ x int,
+ sys_start bigint(20) unsigned as row start invisible,
+ sys_end bigint(20) unsigned as row end invisible,
+ period for system_time (sys_start, sys_end)
+) with system versioning engine innodb;
+
+set transaction isolation level read committed;
+start transaction;
+insert into t1 values (1);
+--connect (con1,localhost,root,,test)
+set transaction isolation level read committed;
+start transaction;
+insert into t1 values (2);
+--connect (con2,localhost,root,,test)
+set transaction isolation level read committed;
+start transaction;
+insert into t1 values (3);
+commit;
+--disconnect con2
+--connection default
+--sleep 0.01
+set @ts1= sysdate(6);
+--connection con1
+commit;
+--disconnect con1
+--connection default
+--sleep 0.01
+set @ts2= sysdate(6);
+commit;
+--sleep 0.01
+set @ts3= sysdate(6);
+
+select sys_start from t1 where x = 1 into @trx_id1;
+select sys_start from t1 where x = 2 into @trx_id2;
+select sys_start from t1 where x = 3 into @trx_id3;
+
+select @trx_id1 < @trx_id2, @trx_id2 < @trx_id3;
+select @ts1 < @ts2, @ts2 < @ts3;
+
+--echo # MVCC is resolved
+select * from t1 for system_time as of transaction @trx_id1;
+select * from t1 for system_time as of timestamp @ts1;
+select * from t1 for system_time as of transaction @trx_id2;
+select * from t1 for system_time as of timestamp @ts2;
+select * from t1 for system_time as of transaction @trx_id3;
+select * from t1 for system_time as of timestamp @ts3;
+
+drop table t1;
diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test
new file mode 100644
index 00000000000..67d7db952ae
--- /dev/null
+++ b/mysql-test/suite/versioning/t/update.test
@@ -0,0 +1,150 @@
+source suite/versioning/engines.inc;
+source suite/versioning/common.inc;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create table t1(
+ x int unsigned,
+ y int unsigned,
+ sys_trx_start $sys_datatype_expl as row start invisible,
+ sys_trx_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end))
+ with system versioning;
+
+insert into t1(x, y) values (1, 1000), (2, 2000), (3, 3000), (4, 4000), (5, 5000), (6, 6000), (7, 7000), (8, 8000), (9, 9000);
+select x, y from t1;
+update t1 set y = y + 1 where x > 7;
+select x, y from t1;
+select x, y from t1 for system_time all;
+drop table t1;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create table t1 (
+ id bigint primary key,
+ x int,
+ y int without system versioning,
+ sys_trx_start $sys_datatype_expl as row start invisible,
+ sys_trx_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+insert into t1 values(1, 1, 1);
+set @ins_t= now(6);
+select sys_trx_start into @tmp1 from t1;
+update t1 set x= 11, y= 11 where id = 1;
+select @tmp1 < sys_trx_start as A1, x, y from t1;
+select sys_trx_start into @tmp1 from t1;
+update t1 set y= 1 where id = 1;
+select @tmp1 = sys_trx_start as A2, x from t1;
+drop table t1;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create table t1 (
+ x int,
+ y int,
+ sys_trx_start $sys_datatype_expl as row start invisible,
+ sys_trx_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end)
+) with system versioning;
+
+insert into t1 (x, y) values (1, 1), (2, 1), (3, 1), (4, 1), (5, 1);
+
+start transaction;
+update t1 set y= y + 1 where x = 3;
+update t1 set y= y + 1 where x = 2;
+update t1 set y= y + 1 where x = 3;
+update t1 set y= y + 1 where x > 3;
+update t1 set y= y + 1 where x > 4;
+commit;
+
+replace_result $sys_datatype_max MAXVAL;
+eval select x, y, sys_trx_end = $sys_datatype_max as current from t1 for system_time all;
+
+drop table t1;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create table t1 (
+ id int primary key auto_increment,
+ x int,
+ sys_trx_start $sys_datatype_expl as row start invisible,
+ sys_trx_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+
+set @t0= now(6);
+insert into t1 (x) values (1);
+set @t1= now(6);
+update t1 set x= 2 where id = 1;
+set @t2= now(6);
+update t1 set x= 3 where id = 1;
+
+select x from t1 for system_time as of timestamp @t0;
+select x from t1 for system_time as of timestamp @t1;
+select x from t1 for system_time as of timestamp @t2;
+select x from t1 for system_time as of timestamp now(6);
+
+drop table t1;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create table t1(
+ x int unsigned,
+ sys_trx_end $sys_datatype_expl as row end invisible,
+ sys_trx_start $sys_datatype_expl as row start invisible,
+ y int unsigned,
+ period for system_time (sys_trx_start, sys_trx_end),
+ primary key(x, y))
+with system versioning;
+insert into t1(x, y) values (1, 1000), (3, 3000), (4, 4000), (5, 5000);
+insert into t1(x, y) values(3, 3000) on duplicate key update y = y+1;
+insert into t1(x, y) values(4, 4444) on duplicate key update y = y+1;
+select x, y from t1 for system_time all;
+select x, y from t1;
+drop table t1;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create table t1 (
+ x int unsigned,
+ y int unsigned,
+ sys_trx_start $sys_datatype_expl as row start invisible,
+ sys_trx_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end))
+ with system versioning;
+create table t2 like t1;
+insert into t1(x, y) values (1, 1000), (2, 2000), (3, 3000), (4, 4000), (5, 5000), (6, 6000), (7, 7000), (8, 8000), (9, 9000);
+insert into t2(x, y) values (1, 1010), (2, 2010), (3, 3010), (4, 4010), (5, 5010), (6, 6010), (7, 7010), (8, 8010), (9, 9010);
+update t1, t2 set t1.y = t1.x + t1.y, t2.y = t2.x + t2.y where t1.x > 7 and t2.x < 7;
+select x, y from t1 for system_time all;
+select x, y from t1;
+select x, y from t2 for system_time all;
+select x, y from t2;
+drop table t1;
+drop table t2;
+
+replace_result $sys_datatype_expl SYS_DATATYPE;
+eval create table t1 (
+ id bigint primary key without system versioning,
+ name varchar(128),
+ salary bigint without system versioning,
+ sys_trx_start $sys_datatype_expl as row start invisible,
+ sys_trx_end $sys_datatype_expl as row end invisible,
+ period for system_time (sys_trx_start, sys_trx_end))
+ with system versioning;
+create table t2 like t1;
+
+insert into t1 values (1, "Jeremy", 3000);
+insert into t2 values (1, "Jeremy", 4000);
+
+select sys_trx_start into @tmp1 from t1;
+select sys_trx_start into @tmp2 from t2;
+update t1, t2 set t1.name= "Jerry", t2.name= "Jerry" where t1.id = t2.id and t1.name = "Jeremy";
+select @tmp1 < sys_trx_start as A1, name from t1;
+select @tmp2 < sys_trx_start as A2, name from t2;
+
+select sys_trx_start into @tmp1 from t1;
+select sys_trx_start into @tmp2 from t2;
+update t1, t2 set t1.salary= 2500, t2.salary= 2500 where t1.id = t2.id and t1.name = "Jerry";
+select @tmp1 = sys_trx_start as B1, salary from t1;
+select @tmp2 = sys_trx_start as B2, salary from t2;
+
+drop table t1;
+drop table t2;
+
+source suite/versioning/common_finish.inc;
diff --git a/mysql-test/suite/versioning/t/update2.test b/mysql-test/suite/versioning/t/update2.test
new file mode 100644
index 00000000000..87ca3746b12
--- /dev/null
+++ b/mysql-test/suite/versioning/t/update2.test
@@ -0,0 +1,31 @@
+source include/have_innodb.inc;
+
+echo ### Issue #365, bug 7 (duplicate of historical row);
+create or replace table t1 (a int primary key, b int)
+with system versioning engine myisam;
+insert into t1 (a) values (1);
+
+replace t1 values (1,2),(1,3),(2,4);
+
+#
+# MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE
+#
+
+create or replace table t1 (pk int, a char(3), b char(3), primary key(pk))
+ engine=innodb with system versioning;
+
+insert into t1 (pk) values (1);
+connect (con1,localhost,root,,test);
+start transaction;
+select * from t1 for update;
+connection default;
+send update t1 set b = 'foo';
+connection con1;
+let $wait_condition= select count(*) from information_schema.innodb_lock_waits;
+source include/wait_condition.inc;
+error ER_LOCK_DEADLOCK;
+update t1 set a = 'bar';
+disconnect con1;
+connection default;
+reap;
+drop table t1;
diff --git a/mysql-test/suite/versioning/t/view.test b/mysql-test/suite/versioning/t/view.test
new file mode 100644
index 00000000000..b63c91c4fa7
--- /dev/null
+++ b/mysql-test/suite/versioning/t/view.test
@@ -0,0 +1,116 @@
+--source suite/versioning/engines.inc
+--source suite/versioning/common.inc
+
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+
+select now(6) into @t1;
+update t1 set x= 2;
+
+select now(6) into @t2;
+delete from t1;
+
+set @vt1= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'");
+prepare stmt from @vt1; execute stmt; drop prepare stmt;
+
+set @vt2= concat("create or replace view vt2 as select *, row_end from t1 for system_time as of timestamp '", @t2, "'");
+prepare stmt from @vt2; execute stmt; drop prepare stmt;
+
+select * from t1;
+
+create or replace view vt1 as select * from t1;
+--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT
+show create view vt1;
+
+drop view vt1;
+drop view vt2;
+
+create or replace view vt1 as select * from t1 for system_time all;
+select * from vt1;
+prepare stmt from 'select * from vt1'; execute stmt; drop prepare stmt;
+
+set @str= concat('create or replace view vt1 as
+select * from t1 for system_time as of timestamp "', @t1, '"');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+select * from t1 for system_time as of timestamp @t1;
+select * from vt1;
+
+insert into vt1 values (3);
+select * from t1;
+select * from vt1;
+
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1), (2);
+set @t1=now(6);
+delete from t1 where x=2;
+set @t2=now(6);
+delete from t1 where x=1;
+set @t3=now(6);
+
+set @tmp= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'");
+prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+select * from vt1;
+
+--echo # VIEW with parameters [#151]
+create or replace table t1 (x int) with system versioning;
+create or replace view vt1(c) as select x from t1;
+--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT
+show create view vt1;
+
+--echo # VIEW over JOIN of versioned tables [#153]
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int) with system versioning;
+insert into t1 values (1);
+insert into t2 values (2);
+create or replace view vt12 as select * from t1 cross join t2;
+select * from vt12;
+create or replace view vt12 as select * from t1 for system_time as of timestamp ('0-0-0') cross join t2;
+select * from vt12;
+
+--echo # VIEW improvements [#183]
+create or replace table t3 (x int);
+create or replace view vt1 as select * from t1, t2, t3;
+--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT
+show create view vt1;
+create or replace view vt1 as select * from t3, t2, t1;
+--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT
+show create view vt1;
+create or replace view vt1 as select a, t2.row_end as endo from t3, t1, t2;
+--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT
+show create view vt1;
+
+--echo # VIEW over UNION [#269]
+create or replace view vt1 as select * from t1 union select * from t1;
+select * from vt1;
+
+--echo # VIEW over UNION with non-versioned [#393]
+create or replace table t2 (a int);
+create or replace view vt1 as select * from t1 union select * from t2;
+select * from vt1;
+
+--echo # MDEV-14689 crash on second PS execute
+create or replace table t1 (a int);
+create or replace view v1 as select * from t1;
+create or replace table t2 (b int) with system versioning;
+prepare stmt from 'select a from v1 inner join t2 group by a order by a';
+execute stmt;
+execute stmt;
+drop database test;
+create database test;
+use test;
+
+#
+# MDEV-15146 SQLError[4122]: View is not system versioned
+#
+
+create table t1 (a int) with system versioning;
+insert t1 values (1),(2);
+set @a=now(6);
+create view v1 as select * from t1;
+delete from t1;
+select * from v1;
+select * from v1 for system_time as of @a;
+show create view v1;
+drop view v1;
+drop table t1;
diff --git a/mysql-test/suite/versioning/t/vtmd.test b/mysql-test/suite/versioning/t/vtmd.test
new file mode 100644
index 00000000000..dcb39a332fc
--- /dev/null
+++ b/mysql-test/suite/versioning/t/vtmd.test
@@ -0,0 +1,206 @@
+-- source include/have_innodb.inc
+set default_storage_engine=innodb;
+
+delimiter ~~;
+create or replace procedure drop_archives (in vtmd_name varchar(64))
+begin
+ declare archive_name varchar(64);
+ declare cur_done bool default false;
+ declare cur cursor for
+ select cur_tmp.archive_name from cur_tmp;
+ declare continue handler for not found set cur_done = true;
+
+ set @tmp= concat('
+ create or replace temporary table
+ cur_tmp as
+ select vtmd.archive_name from ', vtmd_name, '
+ for system_time all as vtmd
+ where vtmd.archive_name is not null
+ group by vtmd.archive_name');
+ prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+ open cur;
+ fetch_loop: loop
+ fetch cur into archive_name;
+ if cur_done then
+ leave fetch_loop;
+ end if;
+ set @tmp= concat('drop table ', archive_name);
+ prepare stmt from @tmp; execute stmt; drop prepare stmt;
+ end loop;
+
+ drop table cur_tmp;
+end~~
+delimiter ;~~
+
+delimiter ~~;
+create or replace procedure check_vtmd (in vtmd_name varchar(64))
+begin
+ set @tmp= concat('
+ create or replace temporary table
+ tmp_vtmd with system versioning as
+ select * from ', vtmd_name, '
+ for system_time all as vtmd');
+ prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+ set @inf= 0xFFFFFFFFFFFFFFFF + 0;
+ set @start= null;
+ select start from tmp_vtmd for system_time all order by start limit 1 into @start;
+ select @start > 0 and @start < @inf;
+ select
+ start >= @start as A_start,
+ (@start:= end) and end = @inf as B_end,
+ name,
+ substr(archive_name, 1, instr(archive_name, '_')) as C_archive_name
+ from tmp_vtmd for system_time all;
+
+ drop table tmp_vtmd;
+end~~
+delimiter ;~~
+
+delimiter ~~;
+create or replace procedure show_tables()
+begin
+ show tables;
+ select table_name, table_schema from information_schema.tables
+ where table_schema not in ('mysql', 'performance_schema', 'information_schema', 'mtr')
+ order by table_name;
+end~~
+delimiter ;~~
+
+# create
+set versioning_alter_history= keep;
+create table t0 (z int) with system versioning;
+show tables;
+set versioning_alter_history= survive;
+create or replace table t0 (y int) with system versioning;
+show tables;
+show create table t0_vtmd;
+call check_vtmd('t0_vtmd');
+
+set versioning_alter_history= keep;
+drop table t0;
+set versioning_alter_history= survive;
+--error ER_VERS_VTMD_ERROR
+create table t0 (x int) with system versioning;
+
+drop table t0_vtmd;
+create table t0 (y int) with system versioning;
+create or replace table t0 (x int) with system versioning;
+
+# alter
+insert into t0 values (1);
+set @t0= now(6);
+alter table t0 add column (y int);
+select * from t0 for system_time as of @t0;
+select * from t0;
+call check_vtmd('t0_vtmd');
+
+call drop_archives('t0_vtmd');
+drop table t0_vtmd;
+alter table t0 drop column y;
+call check_vtmd('t0_vtmd');
+
+call drop_archives('t0_vtmd');
+set versioning_alter_history= keep;
+drop tables t0, t0_vtmd;
+set versioning_alter_history= survive;
+
+# rename
+set versioning_alter_history= keep;
+create or replace table x0 (x int) with system versioning;
+set versioning_alter_history= survive;
+rename table x0 to d0;
+show tables;
+
+set versioning_alter_history= keep;
+drop table d0;
+set versioning_alter_history= survive;
+create or replace table x0 (x int) with system versioning;
+rename table x0 to d0;
+show tables;
+call check_vtmd('d0_vtmd');
+
+set versioning_alter_history= keep;
+drop table d0;
+set versioning_alter_history= survive;
+create or replace table x0 (x int) with system versioning;
+
+--error ER_VERS_VTMD_ERROR
+rename table x0 to d0;
+show tables;
+
+drop table x0_vtmd;
+rename table x0 to d0;
+show tables;
+
+rename table d0 to duck;
+rename table duck to bay;
+rename table bay to sheer;
+rename table sheer to t0;
+call check_vtmd('t0_vtmd');
+
+alter table t0 add column (y int);
+call check_vtmd('t0_vtmd');
+
+# rename to different schema
+alter table t0 add column (z int);
+alter table t0 drop column y;
+alter table t0 drop column z;
+
+create database db0;
+rename table t0 to db0.t0;
+show tables;
+use db0;
+show tables;
+call test.check_vtmd('db0.t0_vtmd');
+
+create database db1;
+rename table t0 to db1.other_name;
+show tables;
+use db1;
+show tables;
+call test.check_vtmd('db1.other_name_vtmd');
+
+# alter rename
+alter table other_name rename to t1;
+call test.check_vtmd('db1.t1_vtmd');
+
+# alter rename and modify to different schema
+alter table t1 rename to test.t2, add column (y int);
+use test;
+show tables;
+call check_vtmd('t2_vtmd');
+
+create or replace table t3 (x int) with system versioning;
+alter table t3 change x x bigint;
+alter table t3 change x x bigint after sys_trx_start;
+call check_vtmd('t3_vtmd');
+
+# hide archive tables
+set versioning_hide= auto;
+call show_tables();
+
+set versioning_hide= implicit;
+call show_tables();
+
+set versioning_hide= full;
+call show_tables();
+
+set versioning_hide= never;
+--replace_regex /\d{8}_\d{6}_\d{6}/TIMESTAMP_SUFFIX/
+call show_tables();
+
+# wrong VTMD handling
+set versioning_hide= auto;
+create or replace table u0_vtmd (x int) with system versioning;
+show tables;
+
+set versioning_alter_history= survive;
+create or replace table t (x int) with system versioning;
+select * from t for system_time all;
+
+drop database db0;
+drop database db1;
+drop database test;
+create database test;
diff --git a/mysql-test/suite/versioning/t/vtmd_show.test b/mysql-test/suite/versioning/t/vtmd_show.test
new file mode 100644
index 00000000000..b740ba43ea1
--- /dev/null
+++ b/mysql-test/suite/versioning/t/vtmd_show.test
@@ -0,0 +1,92 @@
+-- source include/have_innodb.inc
+
+delimiter ~~;
+create or replace procedure drop_archives (in vtmd_name varchar(64))
+begin
+ declare archive_name varchar(64);
+ declare cur_done bool default false;
+ declare cur cursor for
+ select cur_tmp.archive_name from cur_tmp;
+ declare continue handler for not found set cur_done = true;
+
+ set @tmp= concat('
+ create or replace temporary table
+ cur_tmp as
+ select vtmd.archive_name from ', vtmd_name, '
+ for system_time all as vtmd
+ where vtmd.archive_name is not null
+ group by vtmd.archive_name');
+ prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+ open cur;
+ fetch_loop: loop
+ fetch cur into archive_name;
+ if cur_done then
+ leave fetch_loop;
+ end if;
+ set @tmp= concat('drop table ', archive_name);
+ prepare stmt from @tmp; execute stmt; drop prepare stmt;
+ end loop;
+
+ drop table cur_tmp;
+end~~
+delimiter ;~~
+
+delimiter ~~;
+create procedure test_01(in engine varchar(64))
+begin
+ set @tmp = concat('create table t (a int) with system versioning engine ', engine);
+ prepare stmt from @tmp; execute stmt; drop prepare stmt;
+
+ set @tm1 = now(6);
+ alter table t add column b int;
+
+ set @tm2 = now(6);
+ alter table t add column c int;
+
+ show create table t for system_time as of timestamp @tm1;
+ show create table t for system_time as of timestamp @tm2;
+ show create table t for system_time as of now;
+ show create table t for system_time as of timestamp now(6);
+ show create table t;
+
+ set @tm3 = now(6);
+ rename table t to tt;
+ show create table tt for system_time as of timestamp @tm3;
+
+ set @tm4 = now(6);
+ alter table tt add column d int;
+ show create table tt for system_time as of timestamp @tm3;
+ show create table tt for system_time as of timestamp @tm4;
+ show create table tt;
+
+ drop table tt;
+ call drop_archives('tt_vtmd');
+ drop table tt_vtmd;
+end~~
+delimiter ;~~
+
+create table t (a int) with system versioning;
+--error ER_VERS_VTMD_ERROR
+show create table t for system_time as of now;
+
+set versioning_alter_history=survive;
+
+create or replace table t (a int) with system versioning;
+--error ER_VERS_RANGE_PROHIBITED
+show create table t for system_time between timestamp @tm1 and timestamp @tm1;
+--error ER_VERS_RANGE_PROHIBITED
+show create table t for system_time from timestamp @tm1 to timestamp @tm1;
+--error ER_VERS_VTMD_ERROR
+show create table t for system_time as of timestamp '01-01-1990';
+--error ER_VERS_VTMD_ERROR
+show create table t for system_time as of timestamp '01-01-2020';
+drop table t;
+call drop_archives('t_vtmd');
+drop table t_vtmd;
+
+call test_01('myisam');
+call test_01('innodb');
+
+drop procedure test_01;
+drop procedure drop_archives;
diff --git a/mysql-test/suite/versioning/wait_system_clock.inc b/mysql-test/suite/versioning/wait_system_clock.inc
new file mode 100644
index 00000000000..21bbe7aea21
--- /dev/null
+++ b/mysql-test/suite/versioning/wait_system_clock.inc
@@ -0,0 +1,10 @@
+#
+# windows has a rather low-resolution system clock
+# wait until the event from the past will actually be in the past
+#
+if (`select @@version_compile_os in ("win32","win64","windows")`)
+{
+ let $_past=`select max(row_start) from t1`;
+ --let $wait_condition=select TIMESTAMP'$_past' < sysdate(6)
+ --source include/wait_condition.inc
+}
diff --git a/mysql-test/suite/wsrep/suite.pm b/mysql-test/suite/wsrep/suite.pm
index b6c5bf15ca1..03e23b8d7cb 100644
--- a/mysql-test/suite/wsrep/suite.pm
+++ b/mysql-test/suite/wsrep/suite.pm
@@ -9,8 +9,10 @@ return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" unless defined $::mysqld_variables{'wsrep-on'};
my ($provider) = grep { -f $_ } $ENV{WSREP_PROVIDER},
- "/usr/lib/galera/libgalera_smm.so",
- "/usr/lib64/galera/libgalera_smm.so";
+ "/usr/lib64/galera-3/libgalera_smm.so",
+ "/usr/lib64/galera/libgalera_smm.so",
+ "/usr/lib/galera-3/libgalera_smm.so",
+ "/usr/lib/galera/libgalera_smm.so";
return "No wsrep provider library" unless -f $provider;
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index 79a01d5e0c4..7f692f36f4e 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -269,15 +269,15 @@ drop table if exists t1, t2;
create table t1 (a int, b int, c int, d int, e int, f int, g int, h int,i int, primary key (a,b,c,d,e,f,g,i,h)) engine=MyISAM;
insert ignore into t1 (a) values(1);
---replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X
+--replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X 19 X
show table status like 't1';
alter table t1 modify a int;
---replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X
+--replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X 19 X
show table status like 't1';
drop table t1;
create table t1 (a int not null, b int not null, c int not null, d int not null, e int not null, f int not null, g int not null, h int not null,i int not null, primary key (a,b,c,d,e,f,g,i,h)) engine=MyISAM;
insert ignore into t1 (a) values(1);
---replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X
+--replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X 19 X
show table status like 't1';
drop table t1;
@@ -1882,6 +1882,34 @@ alter table t1 drop column a, drop index a;
show create table t1;
drop table t1;
+#
+# MDEV-14694 ALTER COLUMN IF EXISTS .. causes syntax error
+#
+
+create table t1 (i int);
+alter table t1 alter column if exists a set default 1;
+alter table t1 alter column if exists a drop default;
+show create table t1;
+drop table t1;
+
+--echo #
+--echo # MDEV-13508 Check that rename of columns changes defaults, virtual
+--echo # columns and constraints
+--echo #
+
+create table t1 (a int, b int, check(a>b));
+alter table t1 change column a b int, change column b a int;
+show create table t1;
+drop table t1;
+
+create table t1 (a int primary key, b int, c int default (a+b) check (a+b>0),
+ d int as (a+b),
+ key (b),
+ constraint test check (a+b > 1));
+alter table t1 change b new_b int not null, add column b char(1), add constraint new check (length(b) > 0);
+show create table t1;
+drop table t1;
+
--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/binary_to_hex.test b/mysql-test/t/binary_to_hex.test
index 8312a246d0c..be4fb301e40 100644
--- a/mysql-test/t/binary_to_hex.test
+++ b/mysql-test/t/binary_to_hex.test
@@ -72,5 +72,25 @@ SELECT * FROM t2;
#Cleanup
DROP TABLE t1, t2;
+# MDEV-14593 human-readable XA RECOVER
+
+create table t1 (a int);
+
+--write_file $MYSQLTEST_VARDIR/tmp/mdev-14593.sql
+DELIMITER /
+XA START 'tr1', 'bq'/
+INSERT INTO t1 VALUES (0)/
+XA END 'tr1', 'bq'/
+XA PREPARE 'tr1', 'bq'/
+XA RECOVER/
+XA ROLLBACK 'tr1', 'bq'/
+EOF
+--exec $MYSQL test --binary-as-hex < $MYSQLTEST_VARDIR/tmp/mdev-14593.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mdev-14593.sql;
+
+
+#Cleanup
+DROP TABLE t1;
+
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/bootstrap.test b/mysql-test/t/bootstrap.test
index e8589fa9242..1ae9b13e050 100644
--- a/mysql-test/t/bootstrap.test
+++ b/mysql-test/t/bootstrap.test
@@ -7,7 +7,7 @@ drop table if exists t1;
# Add the datadir to the bootstrap command
let $MYSQLD_DATADIR= `select @@datadir`;
-let $MYSQLD_BOOTSTRAP_CMD= $MYSQLD_BOOTSTRAP_CMD --datadir=$MYSQLD_DATADIR --default-storage-engine=MyISAM --loose-skip-innodb;
+let $MYSQLD_BOOTSTRAP_CMD= $MYSQLD_BOOTSTRAP_CMD --datadir=$MYSQLD_DATADIR --default-storage-engine=MyISAM --loose-skip-innodb --plugin-maturity=unknown;
#
# Check that --bootstrap reads from stdin
#
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
index 17e8be839a8..b514dbb5b2d 100644
--- a/mysql-test/t/cast.test
+++ b/mysql-test/t/cast.test
@@ -587,3 +587,140 @@ SHOW CREATE TABLE t1;
SELECT * FROM t1;
DROP TABLE t1;
SET sql_mode=DEFAULT;
+
+
+--echo #
+--echo # MDEV-14376 Explicit CAST(CHAR(N)) erroneously escalates warnings to errors in STRICT_ALL_TABLES
+--echo #
+
+SET sql_mode=STRICT_ALL_TABLES;
+SELECT CAST('xxx' AS CHAR(1));
+
+CREATE OR REPLACE TABLE t1 (a VARCHAR(1));
+INSERT INTO t1 VALUES (CAST('xxx' AS CHAR(1)));
+DROP TABLE t1;
+
+CREATE OR REPLACE TABLE t1 (a VARCHAR(3));
+INSERT INTO t1 VALUES ('xxx');
+UPDATE t1 SET a=CAST(a AS CHAR(1));
+DROP TABLE t1;
+
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE a VARCHAR(30) CHARACTER SET latin1;
+ SET a=CAST('xxx' AS CHAR(1));
+END;
+$$
+DELIMITER ;$$
+
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE a VARCHAR(30) CHARACTER SET latin1;
+ SET a=CAST(_latin1'xxx' AS CHAR(1) CHARACTER SET latin1);
+END;
+$$
+DELIMITER ;$$
+
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE a VARCHAR(30) CHARACTER SET latin1;
+ SET a=CAST(_latin1'xxx' AS CHAR(1) CHARACTER SET utf8);
+END;
+$$
+DELIMITER ;$$
+
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE a VARCHAR(30) CHARACTER SET utf8;
+ SET a=CAST('xxx' AS CHAR(1));
+END;
+$$
+DELIMITER ;$$
+
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE a VARCHAR(30) CHARACTER SET utf8;
+ SET a=CAST(_latin1'xxx' AS CHAR(1) CHARACTER SET latin1);
+END;
+$$
+DELIMITER ;$$
+
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE a VARCHAR(30) CHARACTER SET utf8;
+ SET a=CAST(_latin1'xxx' AS CHAR(1) CHARACTER SET utf8);
+END;
+$$
+DELIMITER ;$$
+
+
+--echo # Conversion problems still escalate warnings to errors (without right truncation)
+
+DELIMITER $$;
+--error ER_CANNOT_CONVERT_CHARACTER
+BEGIN NOT ATOMIC
+ DECLARE a VARCHAR(30) CHARACTER SET utf8;
+ SET a=CAST(_utf8 0xD18F AS CHAR(1) CHARACTER SET latin1);
+END;
+$$
+DELIMITER ;$$
+
+
+--echo # Conversion problems still escalate warnings to errors (with right truncation)
+
+DELIMITER $$;
+--error ER_CANNOT_CONVERT_CHARACTER
+BEGIN NOT ATOMIC
+ DECLARE a VARCHAR(30) CHARACTER SET utf8;
+ SET a=CAST(_utf8 0xD18FD18F AS CHAR(1) CHARACTER SET latin1);
+END;
+$$
+DELIMITER ;$$
+
+
+--echo # CAST(number AS CHAR) escalates warnings to errors on truncation
+
+CREATE OR REPLACE TABLE t1 (a VARCHAR(10));
+--error ER_TRUNCATED_WRONG_VALUE
+INSERT INTO t1 VALUES (CAST(123 AS CHAR(1)));
+DROP TABLE t1;
+
+CREATE OR REPLACE TABLE t1 (a VARCHAR(10));
+INSERT INTO t1 VALUES ('1');
+--error ER_TRUNCATED_WRONG_VALUE
+UPDATE t1 SET a=CAST(123 AS CHAR(1));
+DROP TABLE t1;
+
+DELIMITER $$;
+--error ER_TRUNCATED_WRONG_VALUE
+BEGIN NOT ATOMIC
+ DECLARE a VARCHAR(10);
+ SET a=CAST(123 AS CHAR(1));
+END;
+$$
+DELIMITER ;$$
+
+
+--echo # CAST(temporal AS CHAR) escalates warnings to errors on truncation
+
+CREATE OR REPLACE TABLE t1 (a VARCHAR(10));
+--error ER_TRUNCATED_WRONG_VALUE
+INSERT INTO t1 VALUES (CAST(TIME'10:20:30' AS CHAR(1)));
+DROP TABLE t1;
+
+CREATE OR REPLACE TABLE t1 (a VARCHAR(10));
+INSERT INTO t1 VALUES ('1');
+--error ER_TRUNCATED_WRONG_VALUE
+UPDATE t1 SET a=CAST(TIME'10:20:30' AS CHAR(1));
+DROP TABLE t1;
+
+DELIMITER $$;
+--error ER_TRUNCATED_WRONG_VALUE
+BEGIN NOT ATOMIC
+ DECLARE a VARCHAR(10);
+ SET a=CAST(TIME'10:20:30' AS CHAR(1));
+END;
+$$
+DELIMITER ;$$
+
+SET sql_mode=DEFAULT;
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index a8c4eff7365..af5c427852c 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -1785,6 +1785,149 @@ create table t1(ID decimal(2,1) unsigned NOT NULL, PRIMARY KEY (ID))engine=memor
select 2.1 ID;
drop table t1;
+#
+# many keys with long names and comments
+#
+--error ER_CANT_CREATE_TABLE
+create table t1 (
+ f01 int, f02 int, f03 int, f04 int, f05 int, f06 int, f07 int, f08 int, f09 int, f10 int, f11 int, f12 int, f13 int, f14 int, f15 int, f16 int, f17 int, f18 int, f19 int, f20 int, f21 int, f22 int, f23 int, f24 int, f25 int, f26 int, f27 int, f28 int, f29 int, f30 int, f31 int, f32 int, f33 int, f34 int, f35 int, f36 int, f37 int, f38 int, f39 int, f40 int, f41 int, f42 int, f43 int, f44 int, f45 int, f46 int, f47 int, f48 int, f49 int, f50 int, f51 int, f52 int, f53 int, f54 int, f55 int, f56 int, f57 int, f58 int, f59 int, f60 int, f61 int, f62 int, f63 int, f64 int,
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0001 (f01) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0002 (f02) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0003 (f03) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0004 (f04) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0005 (f05) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0006 (f06) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0007 (f07) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0008 (f08) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0009 (f09) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0010 (f10) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0011 (f11) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0012 (f12) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0013 (f13) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0014 (f14) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0015 (f15) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0016 (f16) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0017 (f17) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0018 (f18) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0019 (f19) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0020 (f20) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0021 (f21) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0022 (f22) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0023 (f23) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0024 (f24) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0025 (f25) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0026 (f26) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0027 (f27) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0028 (f28) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0029 (f29) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0030 (f30) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0031 (f31) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0032 (f32) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0033 (f33) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0034 (f34) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0035 (f35) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0036 (f36) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0037 (f37) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0038 (f38) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0039 (f39) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0040 (f40) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0041 (f41) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0042 (f42) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0043 (f43) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0044 (f44) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0045 (f45) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0046 (f46) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0047 (f47) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0048 (f48) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0049 (f49) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0050 (f50) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0051 (f51) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0052 (f52) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0053 (f53) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0054 (f54) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0055 (f55) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0056 (f56) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0057 (f57) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0058 (f58) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0059 (f59) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0060 (f60) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0061 (f61) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0062 (f62) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0063 (f63) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0064 (f64) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ fend int);
+
+create table t1 (
+ f01 int, f02 int, f03 int, f04 int, f05 int, f06 int, f07 int, f08 int, f09 int, f10 int, f11 int, f12 int, f13 int, f14 int, f15 int, f16 int, f17 int, f18 int, f19 int, f20 int, f21 int, f22 int, f23 int, f24 int, f25 int, f26 int, f27 int, f28 int, f29 int, f30 int, f31 int, f32 int, f33 int, f34 int, f35 int, f36 int, f37 int, f38 int, f39 int, f40 int, f41 int, f42 int, f43 int, f44 int, f45 int, f46 int, f47 int, f48 int, f49 int, f50 int, f51 int, f52 int, f53 int, f54 int, f55 int, f56 int, f57 int, f58 int, f59 int, f60 int, f61 int, f62 int, f63 int, f64 int,
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0001 (f01) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0002 (f02) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0003 (f03) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0004 (f04) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0005 (f05) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0006 (f06) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0007 (f07) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0008 (f08) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0009 (f09) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0010 (f10) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0011 (f11) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0012 (f12) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0013 (f13) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0014 (f14) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0015 (f15) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0016 (f16) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0017 (f17) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0018 (f18) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0019 (f19) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0020 (f20) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0021 (f21) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0022 (f22) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0023 (f23) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0024 (f24) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0025 (f25) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0026 (f26) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0027 (f27) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0028 (f28) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0029 (f29) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0030 (f30) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0031 (f31) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0032 (f32) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0033 (f33) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0034 (f34) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0035 (f35) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0036 (f36) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0037 (f37) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0038 (f38) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0039 (f39) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0040 (f40) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0041 (f41) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0042 (f42) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0043 (f43) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0044 (f44) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0045 (f45) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0046 (f46) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0047 (f47) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0048 (f48) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0049 (f49) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0050 (f50) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0051 (f51) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0052 (f52) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0053 (f53) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0054 (f54) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0055 (f55) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0056 (f56) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0057 (f57) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0058 (f58) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0059 (f59) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0060 (f60) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0061 (f61) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0062 (f62) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0063 (f63) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
+ fend int);
+--error ER_CANT_CREATE_TABLE
+alter table t1 add
+ key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0064 (f64) comment 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy';
+drop table t1;
+
--echo End of 5.5 tests
#
diff --git a/mysql-test/t/create_drop_binlog.test b/mysql-test/t/create_drop_binlog.test
index d31ccd73429..6b2b1bbf1f5 100644
--- a/mysql-test/t/create_drop_binlog.test
+++ b/mysql-test/t/create_drop_binlog.test
@@ -2,6 +2,8 @@
--source include/have_log_bin.inc
--source include/binlog_start_pos.inc
+reset master;
+
--let $pos=`select $binlog_start_pos + 73`
--let $binlog_file=query_get_value(SHOW MASTER STATUS, File, 1)
diff --git a/mysql-test/t/create_or_replace.test b/mysql-test/t/create_or_replace.test
index abf470b62d5..4ef4189694b 100644
--- a/mysql-test/t/create_or_replace.test
+++ b/mysql-test/t/create_or_replace.test
@@ -396,3 +396,27 @@ CREATE OR REPLACE TABLE t1 AS SELECT f1();
UNLOCK TABLES;
DROP FUNCTION f1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-11071 - Assertion `thd->transaction.stmt.is_empty()' failed in
+--echo # Locked_tables_list::unlock_locked_tables
+--echo #
+CREATE TEMPORARY TABLE t1(a INT) ENGINE=InnoDB;
+CREATE TEMPORARY TABLE t2(a INT);
+CREATE TABLE t3(a INT);
+LOCK TABLE t2 WRITE;
+SELECT * FROM t2;
+# drops t2
+--error ER_UNSUPPORT_COMPRESSED_TEMPORARY_TABLE
+CREATE OR REPLACE TEMPORARY TABLE t1(a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+# make sure we didn't leave locked tables mode
+--error ER_TABLE_NOT_LOCKED
+SELECT * FROM t3;
+# drops t1
+--error ER_UNSUPPORT_COMPRESSED_TEMPORARY_TABLE
+CREATE OR REPLACE TEMPORARY TABLE t2(a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+# make sure we didn't leave locked tables mode
+--error ER_TABLE_NOT_LOCKED
+SELECT * FROM t3;
+UNLOCK TABLES;
+DROP TABLE t3;
diff --git a/mysql-test/t/cte_grant.test b/mysql-test/t/cte_grant.test
index 44fd4a0bc6e..c6627c05829 100644
--- a/mysql-test/t/cte_grant.test
+++ b/mysql-test/t/cte_grant.test
@@ -76,4 +76,55 @@ select * from mysqltest.v3;
connection root;
revoke all privileges on mysqltest.v1 from mysqltest_1@localhost;
drop user mysqltest_1@localhost;
-drop database mysqltest; \ No newline at end of file
+drop database mysqltest;
+
+--echo #
+--echo # MDEV-13453: privileges checking for CTE
+--echo #
+
+create database db;
+use db;
+create table t1 (i int);
+insert into t1
+ values (3), (7), (1), (4), (2), (3), (1);
+
+create table t2 (a int, b int);
+insert into t2
+ values (3,10), (7,11), (1,17), (4,15), (2,11), (3,10), (1,15);
+
+create user foo@localhost;
+grant SELECT on db.t1 to foo@localhost;
+grant SELECT(a) on db.t2 to foo@localhost;
+
+--connect (con1,localhost,foo,,)
+use db;
+with cte as (select * from t1 where i < 4)
+ select * from cte;
+with cte as (select * from t1 where i < 4 group by i)
+ select * from cte;
+with cte as (select * from t1 where i < 4)
+ select * from cte cte1 where i < 2 union select * from cte cte2 where i > 2;
+with cte as (select * from t1 where i < 4 group by i)
+ select * from cte cte1 where i < 2 union select * from cte cte2 where i > 2;
+
+--error ER_COLUMNACCESS_DENIED_ERROR
+with cte as (select b from t2 where a < 4)
+ select * from cte cte1 where b < 15 union select * from cte cte2 where b > 15;
+with cte as (select a from t2 where a < 4)
+ select * from cte cte1 where a < 2 union select * from cte cte2 where a > 2;
+
+--connection default
+revoke SELECT on db.t1 from foo@localhost;
+
+--connection con1
+
+--error ER_TABLEACCESS_DENIED_ERROR
+with cte as (select * from t1 where i < 4)
+ select * from cte;
+
+# Cleanup
+--disconnect con1
+
+--connection default
+drop database db;
+drop user foo@localhost;
diff --git a/mysql-test/t/cte_nonrecursive.test b/mysql-test/t/cte_nonrecursive.test
index 742e8f6e4d7..3d073183877 100644
--- a/mysql-test/t/cte_nonrecursive.test
+++ b/mysql-test/t/cte_nonrecursive.test
@@ -790,3 +790,202 @@ SHOW CREATE VIEW cte_test;
SELECT * FROM cte_test;
DROP VIEW cte_test;
+
+--echo #
+--echo # mdev-14755 : PS for query using CTE in select with subquery
+--echo #
+
+create table t1 (a int);
+insert into t1 values
+ (7), (2), (8), (1), (3), (2), (7), (5), (4), (7), (9), (8);
+
+let $q1=
+with cte as
+(select a from t1 where a between 4 and 7 group by a)
+(select a from cte where exists( select a from t1 where cte.a=t1.a ))
+union
+(select a from t1 where a < 2);
+
+eval $q1;
+eval prepare stmt from "$q1";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+let $q2=
+with cte as
+(select a from t1 where a between 4 and 7 group by a)
+(select a from t1 where a < 2)
+union
+(select a from cte where exists( select a from t1 where cte.a=t1.a ));
+
+eval $q2;
+eval prepare stmt from "$q2";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+let $q3=
+with cte as
+(select a from t1 where a between 4 and 7)
+(select a from t1 where a < 2)
+union
+(select a from cte where exists( select a from t1 where cte.a=t1.a ));
+
+eval $q3;
+eval prepare stmt from "$q3";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+let $q4=
+with cte as
+(select a from t1 where a between 4 and 7)
+(select a from cte
+ where exists( select a from t1 where t1.a < 2 and cte.a=t1.a ))
+union
+(select a from cte where exists( select a from t1 where cte.a=t1.a ));
+
+eval $q4;
+eval prepare stmt from "$q4";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-14852: CTE using temporary table in query
+--echo # with two references to the CTE
+--echo #
+
+create temporary table t1 (i int);
+insert into t1 values (5),(4),(1),(2),(3);
+
+with
+c1 as (select i from t1),
+c2 as (select i from c1 where c1.i=2)
+select i from c1 where i > 3 union select i from c2;
+
+drop table t1;
+
+create table t1 (term char(10));
+create temporary table t2 (term char(10));
+
+insert into t1 values ('TERM01'),('TERM02'),('TERM03');
+insert into t2 values ('TERM02'),('TERM03'),('TERM04');
+
+with c1 as (select * from t1), c2 as (select * from t2)
+(select * from c1 left outer join c2 on c1.term = c2.term)
+union all
+(select * from c1 right outer join c2 on c1.term = c2.term
+ where c1.term is null);
+
+drop table t1,t2;
+
+--echo #
+--echo # MDEV-14969: view using subquery with attached CTE
+--echo #
+
+create table region (
+ r_regionkey int,
+ r_name char(25),
+ primary key (r_regionkey)
+);
+insert into region values
+(0,'AFRICA'), (1,'AMERICA'), (2,'ASIA'), (3,'EUROPE'), (4,'MIDDLE EAST');
+
+create table nation (
+ n_nationkey int,
+ n_name char(25),
+ n_regionkey int,
+ primary key (n_nationkey),
+ key i_n_regionkey (n_regionkey)
+);
+insert into nation values
+(0,'ALGERIA',0), (1,'ARGENTINA',1), (2,'BRAZIL',1), (3,'CANADA',1),
+(4,'EGYPT',4), (5,'ETHIOPIA',0), (6,'FRANCE',3), (7,'GERMANY',3),
+(8,'INDIA',2), (9,'INDONESIA',2), (10,'IRAN',4), (11,'IRAQ',4),
+(12,'JAPAN',2), (13,'JORDAN',4), (14,'KENYA',0), (15,'MOROCCO',0),
+(16,'MOZAMBIQUE',0), (17,'PERU',1), (18,'CHINA',2), (19,'ROMANIA',3),
+(20,'SAUDI ARABIA',4), (21,'VIETNAM',2), (22,'RUSSIA',3),
+(23,'UNITED KINGDOM',3), (24,'UNITED STATES',1);
+
+select * from nation n ,region r
+ where n.n_regionkey = r.r_regionkey and
+ r.r_regionkey in
+ (with t as (select * from region where r_regionkey <= 3 )
+ select r_regionkey from t where r_name <> "ASIA");
+
+create view v as
+select * from nation n ,region r
+ where n.n_regionkey = r.r_regionkey and
+ r.r_regionkey in
+ (with t as (select * from region where r_regionkey <= 3)
+ select r_regionkey from t where r_name <> "ASIA");
+
+show create view v;
+select * from v;
+
+drop view v;
+drop table region, nation;
+
+--echo #
+--echo # MDEV-15120: cte name used with database name
+--echo #
+
+--error ER_NO_SUCH_TABLE
+WITH cte AS (SELECT 1 AS a) SELECT test.cte.a FROM test.cte;
+
+CREATE DATABASE db1;
+USE db1;
+
+--error ER_NO_SUCH_TABLE
+WITH cte AS (SELECT 1 AS a) SELECT db1.cte.a FROM db1.cte;
+
+DROP DATABASE db1;
+USE test;
+
+--echo #
+--echo # MDEV-15119: CTE c2 specified after CTE c1 and is used in
+--echo # CTE c3 that is embedded into the spec of c1
+--echo #
+
+CREATE TABLE t1 (i int);
+INSERT INTO t1 VALUES (1),(2),(3);
+
+--error ER_NO_SUCH_TABLE
+WITH c1 AS (WITH c3 AS (SELECT * FROM c2) SELECT * FROM c3),
+ c2 AS (SELECT * FROM t1)
+SELECT * FROM c1;
+
+WITH RECURSIVE c1 AS (WITH c3 AS (SELECT * FROM c2) SELECT * FROM c3),
+ c2 AS (SELECT * FROM t1)
+SELECT * FROM c1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14297: Lost name of a explicitly named CTE column used in
+--echo # the non-recursive CTE via prepared statement
+--echo #
+
+CREATE TABLE t1 (i int);
+INSERT INTO t1 VALUES (1),(2),(3);
+
+PREPARE stmt FROM "WITH cte(a) AS (SELECT 1) SELECT * FROM cte";
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+PREPARE stmt FROM "CREATE VIEW v1 AS WITH cte(a) AS (SELECT 1) SELECT * FROM cte";
+EXECUTE stmt;
+SELECT * FROM v1;
+DEALLOCATE PREPARE stmt;
+
+PREPARE stmt FROM "CREATE VIEW v2 AS WITH cte(a) AS (SELECT * FROM t1) SELECT * FROM cte";
+EXECUTE stmt;
+SELECT * FROM v2;
+DEALLOCATE PREPARE stmt;
+
+DROP TABLE t1;
+DROP VIEW v1,v2;
diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test
index 7d7600f0e88..7ed55a1daaa 100644
--- a/mysql-test/t/cte_recursive.test
+++ b/mysql-test/t/cte_recursive.test
@@ -1949,6 +1949,157 @@ SELECT *
FROM cte1;
--echo #
+--echo # mdev-14629: a user-defined variable is defined by the recursive CTE
+--echo #
+
+set @var=
+(
+ with recursive cte_tab(a) as (
+ select 1
+ union
+ select a+1 from cte_tab
+ where a<3)
+ select count(*) from cte_tab
+);
+
+select @var;
+
+create table t1(a int, b int);
+insert into t1 values (3,8),(1,5),(5,7),(7,4),(4,3);
+
+set @var=
+(
+ with recursive summ(a,s) as (
+ select 1, 0 union
+ select t1.b, t1.b+summ.s from summ, t1
+ where summ.a=t1.a)
+ select s from summ
+ order by a desc
+ limit 1
+);
+
+select @var;
+
+--ERROR ER_UNACCEPTABLE_MUTUAL_RECURSION
+set @var=
+(
+ with recursive
+ cte_1 as (
+ select 1
+ union
+ select * from cte_2),
+ cte_2 as (
+ select * from cte_1
+ union
+ select a from t1, cte_2
+ where t1.a=cte_2.a)
+ select * from cte_2
+ limit 1
+);
+
+drop table t1;
+
+--echo #
+--echo # mdev-14777: crash caused by the same as in mdev-14755
+--echo #
+
+--source include/have_sequence.inc
+
+CREATE TABLE t1 (i1 int NOT NULL, i2 int);
+CREATE TABLE t2 (d1 int NOT NULL PRIMARY KEY);
+CREATE TABLE t3 (i int );
+
+insert into t1 select seq,seq from seq_1_to_100000;
+insert into t2 select seq from seq_1000_to_100000;
+insert into t3 select seq from seq_1_to_1000;
+
+SELECT *
+FROM
+(
+ SELECT *
+ FROM
+ (
+ WITH RECURSIVE rt AS
+ (
+ SELECT i2 P, i1 C FROM t1 WHERE i1 IN (SELECT d1 FROM t2)
+ UNION
+ SELECT t1.i2 P, rt.C C FROM t1, rt
+ )
+ SELECT C,P
+ FROM ( SELECT P,C FROM rt WHERE NOT EXISTS (SELECT 1 FROM t1) ) Y
+ ) X
+ WHERE 1 = 1
+) K, t3;
+
+drop table t1,t2,t3;
+
+--echo #
+--echo # mdev-14879: subquery with recursive reference in WHERE of CTE
+--echo #
+
+create table flights
+(departure varchar(32),
+ arrival varchar(32),
+ carrier varchar(20),
+ flight_number char(7));
+
+insert into flights values
+('Seattle', 'Frankfurt', 'Lufthansa', 'LH 491'),
+('Seattle', 'Chicago', 'American', 'AA 2573'),
+('Seattle', 'Los Angeles', 'Alaska Air', 'AS 410'),
+('Chicago', 'New York', 'American', 'AA 375'),
+('Chicago', 'Montreal', 'Air Canada', 'AC 3053'),
+('Los Angeles', 'New York', 'Delta', 'DL 1197'),
+('Moscow', 'Tokyo', 'Aeroflot', 'SU 264'),
+('New York', 'Paris', 'Air France', 'AF 23'),
+('Frankfurt', 'Moscow', 'Lufthansa', 'LH 1444'),
+('Tokyo', 'Seattle', 'ANA', 'NH 178'),
+('Los Angeles', 'Tokyo', 'ANA', 'NH 175'),
+('Moscow', 'Los Angeles', 'Aeroflot', 'SU 106'),
+('Montreal', 'Paris', 'Air Canada', 'AC 870'),
+('Cairo', 'Paris', 'Air France', 'AF 503'),
+('New York', 'Seattle', 'American', 'AA 45'),
+('Paris', 'Chicago', 'Air France', 'AF 6734');
+
+with recursive destinations (city) as
+( select a.arrival from flights a where a.departure='Cairo'
+ union
+ select b.arrival from destinations r, flights b where r.city=b.departure)
+select * from destinations;
+
+set standard_compliant_cte=0;
+
+let $q=
+with recursive destinations (city, legs) as
+(
+ select a.arrival, 1 from flights a where a.departure='Cairo'
+ union
+ select b.arrival, r.legs + 1 from destinations r, flights b
+ where r.city=b.departure and b.arrival not in (select city from destinations)
+)
+select * from destinations;
+
+eval $q;
+eval explain extended $q;
+
+set standard_compliant_cte=default;
+
+drop table flights;
+
+--echo #
+--echo # MDEV-15162: Setting user variable in recursive CTE
+--echo #
+
+SET @c=1;
+
+WITH RECURSIVE cte AS
+ (SELECT 5
+ UNION
+ SELECT @c:=@c+1 FROM cte WHERE @c<3)
+SELECT * FROM cte;
+
+
+--echo #
--echo # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
--echo #
@@ -1976,3 +2127,184 @@ DROP TABLE a_tbl;
--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT
WITH RECURSIVE x AS (SELECT 1,2 UNION ALL SELECT 1 FROM x) SELECT * FROM x;
+--echo #
+--echo # MDEV-15162: Setting user variable in recursive CTE
+--echo #
+
+SET @c=1;
+
+WITH RECURSIVE cte AS
+ (SELECT 5
+ UNION
+ SELECT @c:=@c+1 FROM cte WHERE @c<3)
+SELECT * FROM cte;
+
+--echo #
+--echo # MDEV-14883: recursive references in operands of INTERSECT / EXCEPT
+--echo #
+
+create table flights
+(departure varchar(32),
+ arrival varchar(32),
+ carrier varchar(20),
+ flight_number char(7));
+
+insert into flights values
+('Seattle', 'Frankfurt', 'Lufthansa', 'LH 491'),
+('Seattle', 'Amsterdam', 'KLM', 'KL 6032'),
+('Seattle', 'Chicago', 'American', 'AA 2573'),
+('Seattle', 'Los Angeles', 'Alaska Air', 'AS 410'),
+('Chicago', 'New York', 'American', 'AA 375'),
+('Chicago', 'Montreal', 'Air Canada', 'AC 3053'),
+('Los Angeles', 'New York', 'Delta', 'DL 1197'),
+('New York', 'London', 'British Airways', 'BA 1511'),
+('London', 'Moscow', 'British Airways', 'BA 233'),
+('Moscow', 'Tokyo', 'Aeroflot', 'SU 264'),
+('Moscow', 'Dubai', 'Emirates', 'EK 2421'),
+('Dubai', 'Tokyo', 'Emirates', 'EK 318'),
+('Dubai', 'Bangkok', 'Emirates', 'EK 2142'),
+('Beijing', 'Bangkok', 'Air China', 'CA 757'),
+('Beijing', 'Tokyo', 'Air China', 'CA 6653'),
+('Moscow', 'Bangkok', 'Aeroflot', 'SU 270'),
+('New York', 'Reykjavik', 'Icelandair', 'FL 416'),
+('New York', 'Paris', 'Air France', 'AF 23'),
+('Amsterdam', 'Moscow', 'KLM', 'KL 903'),
+('Frankfurt', 'Dubai', 'Lufthansa', 'LH 630'),
+('Frankfurt', 'Moscow', 'Lufthansa', 'LH 1444'),
+('Reykjavik', 'London', 'British Airways', 'BA 2229'),
+('Frankfurt', 'Beijing', 'Air China', 'CA 966'),
+('Tokyo', 'Seattle', 'ANA', 'NH 178'),
+('Los Angeles', 'Tokyo', 'ANA', 'NH 175'),
+('Moscow', 'Los Angeles', 'Aeroflot', 'SU 106'),
+('Montreal', 'Paris', 'Air Canada', 'AC 870'),
+('London', 'Delhi', 'British Airways', 'BA 143'),
+('Delhi', 'Bangkok', 'Air India', 'AI 306'),
+('Delhi', 'Dubai', 'Air India', 'AI 995'),
+('Dubai', 'Cairo', 'Emirates', 'EK 927'),
+('Cairo', 'Paris', 'Air France', 'AF 503'),
+('Amsterdam', 'New York', 'Delta', 'DL 47'),
+('New York', 'Seattle', 'American', 'AA 45'),
+('Paris', 'Chicago', 'Air France', 'AF 6734');
+
+create table distances
+(city1 varchar(32),
+ city2 varchar(32),
+ dist int);
+
+insert into distances values
+('Seattle', 'Frankfurt', 5080),
+('Seattle', 'Amsterdam', 4859),
+('Seattle', 'Chicago', 1733),
+('Seattle', 'Los Angeles', 960),
+('Chicago', 'New York', 712),
+('Chicago', 'Montreal', 746),
+('Los Angeles', 'New York', 2446),
+('New York', 'London', 3459),
+('London', 'Moscow', 1554),
+('Moscow', 'Tokyo', 4647),
+('Moscow', 'Dubai', 2298),
+('Dubai', 'Tokyo', 4929),
+('Dubai', 'Bangkok', 3050),
+('Beijing', 'Bangkok', 2046),
+('Beijing', 'Tokyo', 1301),
+('Moscow', 'Bangkok', 4390),
+('New York', 'Reykjavik', 2613),
+('New York', 'Paris', 3625),
+('Amsterdam', 'Moscow', 1334),
+('Frankfurt', 'Dubai', 3003),
+('Frankfurt', 'Moscow', 1256),
+('Reykjavik', 'London', 1173),
+('Frankfurt', 'Beijing', 4836),
+('Tokyo', 'Seattle', 4783),
+('Los Angeles', 'Tokyo', 5479),
+('Moscow', 'Los Angeles', 6071),
+('Moscow', 'Reykjavik', 2052),
+('Montreal', 'Paris', 3425),
+('London', 'Delhi', 4159),
+('London', 'Paris', 214),
+('Delhi', 'Bangkok', 1810),
+('Delhi', 'Dubai', 1369),
+('Delhi', 'Beijing', 2350),
+('Dubai', 'Cairo', 1501),
+('Cairo', 'Paris', 1992),
+('Amsterdam', 'New York', 3643),
+('New York', 'Seattle', 2402),
+('Paris', 'Chicago', 4136),
+('Paris', 'Los Angeles', 5647);
+
+with recursive destinations (city) as
+(
+ select a.arrival from flights a where a.departure = 'Seattle'
+ union
+ select b.arrival from destinations r, flights b where r.city = b.departure
+)
+select * from destinations;
+
+with recursive destinations (city) as
+(
+ select a.arrival from flights a, distances d
+ where a.departure = 'Seattle' and
+ a.departure = d.city1 and a.arrival = d.city2 and
+ d.dist < 4000
+ union
+ select b.arrival from destinations r, flights b, distances d
+ where r.city = b.departure and
+ b.departure = d.city1 and b.arrival = d.city2 and
+ d.dist < 4000
+)
+select * from destinations;
+
+set standard_compliant_cte=0;
+
+with recursive legs_to_destinations
+ (departure, arrival, dist, leg_no, acc_mileage) as
+(
+ select a.departure, a.arrival, d.dist, 1, d.dist
+ from flights a, distances d
+ where a.departure = 'Seattle' and
+ a.departure = d.city1 and a.arrival = d.city2 and
+ d.dist < 4000
+ union all
+ select b.departure, b.arrival, d.dist, r.leg_no + 1, r.acc_mileage + d.dist
+ from legs_to_destinations r, flights b, distances d
+ where r.arrival = b.departure and
+ b.departure = d.city1 and b.arrival = d.city2 and
+ d.dist < 4000 and
+ b.arrival not in (select arrival from legs_to_destinations)
+)
+select * from legs_to_destinations;
+
+set standard_compliant_cte=default;
+
+with recursive destinations (city) as
+(
+ select a.arrival from flights a, distances d
+ where a.departure = 'Seattle' and
+ a.departure = d.city1 and a.arrival = d.city2 and
+ d.dist < 4000
+ union
+ select b.arrival from destinations r, flights b
+ where r.city = b.departure
+ intersect
+ select city2 from destinations s, distances d
+ where s.city = d.city1 and d.dist < 4000
+)
+select * from destinations;
+
+with recursive destinations (city) as
+(
+ select a.arrival from flights a where a.departure = 'Seattle'
+ union
+ select * from
+ (
+ select b.arrival from destinations r, flights b
+ where r.city = b.departure
+ except
+ select arrival from flights
+ where arrival in
+ ('New York', 'London', 'Moscow', 'Dubai', 'Cairo', 'Tokyo')
+ ) t
+)
+select * from destinations;
+
+drop table flights, distances;
diff --git a/mysql-test/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test
index 8c51bfef2d8..31d4ff7f802 100644
--- a/mysql-test/t/ctype_latin1.test
+++ b/mysql-test/t/ctype_latin1.test
@@ -411,6 +411,9 @@ let $coll='latin1_nopad_bin';
let $coll_pad='latin1_bin';
--source include/ctype_pad_all_engines.inc
+SET NAMES latin1;
+--source include/ctype_like_range_mdev14350.inc
+
--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/ctype_like_range.test b/mysql-test/t/ctype_like_range.test
index e8784990d36..3055abe5f59 100644
--- a/mysql-test/t/ctype_like_range.test
+++ b/mysql-test/t/ctype_like_range.test
@@ -155,5 +155,45 @@ SELECT a, HEX(mn), HEX(mx) FROM t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results
+--echo #
+
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_swedish_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_general_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET ucs2 COLLATE ucs2_unicode_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf16 COLLATE utf16_unicode_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf32 COLLATE utf32_unicode_nopad_ci);
+INSERT INTO t1 VALUES ('111%');
+SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1;
+DROP TABLE t1;
+
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/ctype_ucs2_uca.test b/mysql-test/t/ctype_ucs2_uca.test
index bc6d6150ee6..0aed0956f6c 100644
--- a/mysql-test/t/ctype_ucs2_uca.test
+++ b/mysql-test/t/ctype_ucs2_uca.test
@@ -16,6 +16,10 @@ let $coll='ucs2_unicode_520_nopad_ci';
let $coll_pad='ucs2_unicode_520_ci';
--source include/ctype_pad_all_engines.inc
+SET NAMES utf8, collation_connection=ucs2_unicode_520_nopad_ci;
+--source include/ctype_like_range_mdev14350.inc
+SET NAMES utf8;
+
--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/ctype_utf16_uca.test b/mysql-test/t/ctype_utf16_uca.test
index 95ce74076d0..46d572fbe81 100644
--- a/mysql-test/t/ctype_utf16_uca.test
+++ b/mysql-test/t/ctype_utf16_uca.test
@@ -238,6 +238,11 @@ let $coll='utf16_unicode_520_nopad_ci';
let $coll_pad='utf16_unicode_520_ci';
--source include/ctype_pad_all_engines.inc
+SET NAMES utf8, collation_connection=utf16_unicode_520_nopad_ci;
+--source include/ctype_like_range_mdev14350.inc
+SET NAMES utf8;
+
+
--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/ctype_utf32_uca.test b/mysql-test/t/ctype_utf32_uca.test
index e5eb3b6d881..334d8fd1d48 100644
--- a/mysql-test/t/ctype_utf32_uca.test
+++ b/mysql-test/t/ctype_utf32_uca.test
@@ -260,6 +260,11 @@ let $coll='utf32_unicode_520_nopad_ci';
let $coll_pad='utf32_unicode_520_ci';
--source include/ctype_pad_all_engines.inc
+SET NAMES utf8, collation_connection=utf32_unicode_520_nopad_ci;
+--source include/ctype_like_range_mdev14350.inc
+SET NAMES utf8;
+
+
--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index adb846a0df2..b839042b91e 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -1879,6 +1879,18 @@ let $ctype_unescape_combinations=selected;
--source include/ctype_unescape.inc
--echo #
+--echo # MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
+--echo #
+
+SET NAMES utf8;
+SELECT CHAR(0xDF USING latin1);
+CREATE OR REPLACE VIEW v1 AS SELECT CHAR(0xDF USING latin1) AS c;
+SHOW CREATE VIEW v1;
+SELECT * FROM v1;
+DROP VIEW v1;
+
+
+--echo #
--echo # End of 10.0 tests
--echo #
diff --git a/mysql-test/t/ctype_utf8_uca.test b/mysql-test/t/ctype_utf8_uca.test
index 670998a367b..0879b4d2810 100644
--- a/mysql-test/t/ctype_utf8_uca.test
+++ b/mysql-test/t/ctype_utf8_uca.test
@@ -14,6 +14,9 @@ let $coll='utf8_unicode_520_nopad_ci';
let $coll_pad='utf8_unicode_520_ci';
--source include/ctype_pad_all_engines.inc
+SET NAMES utf8 COLLATE utf8_unicode_nopad_ci;
+--source include/ctype_like_range_mdev14350.inc
+
--echo #
--echo # End of 10.2 tests
diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test
index 94b5d77ad90..7aa644fe8a9 100644
--- a/mysql-test/t/ctype_utf8mb4.test
+++ b/mysql-test/t/ctype_utf8mb4.test
@@ -1923,6 +1923,24 @@ SELECT * FROM t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-8949: COLUMN_CREATE unicode name breakage
+--echo #
+
+SET NAMES utf8mb4;
+SELECT COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
+SELECT COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
+SELECT COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E
+as int);
+
+CREATE TABLE t1 AS SELECT
+ COLUMN_LIST(COLUMN_CREATE('a',1)),
+ COLUMN_JSON(COLUMN_CREATE('b',1));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+SET NAMES default;
+
+--echo #
--echo # End of 10.0 tests
--echo #
diff --git a/mysql-test/t/ctype_utf8mb4_uca.test b/mysql-test/t/ctype_utf8mb4_uca.test
index fe76ed45e3f..160cb48bad6 100644
--- a/mysql-test/t/ctype_utf8mb4_uca.test
+++ b/mysql-test/t/ctype_utf8mb4_uca.test
@@ -100,6 +100,11 @@ let $coll='utf8mb4_unicode_520_nopad_ci';
let $coll_pad='utf8mb4_unicode_520_ci';
--source include/ctype_pad_all_engines.inc
+SET NAMES utf8mb4 COLLATE utf8mb4_unicode_520_nopad_ci;
+--source include/ctype_like_range_mdev14350.inc
+SET NAMES utf8mb4;
+
+
--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/custom_aggregate_functions.test b/mysql-test/t/custom_aggregate_functions.test
new file mode 100644
index 00000000000..13eb3bed2af
--- /dev/null
+++ b/mysql-test/t/custom_aggregate_functions.test
@@ -0,0 +1,785 @@
+create table t2 (sal int(10));
+delimiter |;
+
+create aggregate function f1(x INT) returns int
+begin
+ declare continue handler for not found return 0;
+ loop
+ fetch group next row;
+ insert into t2 (sal) values (x);
+ end loop;
+end|
+
+delimiter ;|
+
+create table t1 (sal int(10),id int(10));
+INSERT INTO t1 (sal,id) VALUES (5000,1);
+INSERT INTO t1 (sal,id) VALUES (2000,1);
+INSERT INTO t1 (sal,id) VALUES (1000,1);
+select f1(sal) from t1 where id>= 1;
+select * from t2;
+drop table t2;
+drop function f1;
+
+delimiter |;
+--error ER_INVALID_AGGREGATE_FUNCTION
+create aggregate function f1(x INT) returns INT
+begin
+ insert into t1(sal) values (x);
+ return x;
+end|
+
+--error ER_NOT_AGGREGATE_FUNCTION
+create function f1(x INT) returns INT
+begin
+ set x=5;
+ fetch group next row;
+return x+1;
+end |
+
+create aggregate function f1(x INT) returns INT
+begin
+ declare continue handler for not found return x;
+ loop
+ fetch group next row;
+ end loop;
+end |
+delimiter ;|
+
+select f1(1);
+show create function f1;
+--error ER_PARSE_ERROR
+alter function f1 aggregate none;
+show create function f1;
+select f1(1);
+drop function f1;
+
+
+delimiter |;
+
+
+create aggregate function f2(i int) returns int
+begin
+ FEtCH GROUP NEXT ROW;
+ if i <= 0 then
+ return 0;
+ elseif i = 1 then
+ return (select count(*) from t1 where id = i);
+ else
+ return (select count(*) + f2( i - 1) from t1 where id = i);
+ end if;
+end|
+select f2(1)|
+# Since currently recursive functions are disallowed ER_SP_NO_RECURSION
+# error will be returned, once we will allow them error about
+# insufficient number of locked tables will be returned instead.
+--error ER_SP_NO_RECURSION
+select f2(2)|
+--error ER_SP_NO_RECURSION
+select f2(3)|
+drop function f2|
+
+create aggregate function f1(x int) returns int
+begin
+ declare mini int default 0;
+ declare continue handler for not found return mini;
+ loop
+ fetch group next row;
+ set mini= mini+x;
+ fetch group next row;
+ end loop;
+end|
+
+
+delimiter ;|
+
+select f1(10);
+select f1(sal) from t1;
+select f1(sal) from t1 where 1=0;
+drop function f1;
+delimiter |;
+
+
+#WITHOUT RETURN STATEMENT IN AGGREGATE FUNCTIONS
+--error 1320
+create aggregate function f1(x int) returns int
+begin
+ declare mini int default 0;
+ LOOP
+ FETCH GROUP NEXT ROW;
+ set mini = mini + x;
+ END LOOP;
+end|
+
+#without handler
+create aggregate function f1(x int) returns int
+begin
+ declare mini int default 0;
+ LOOP
+ FETCH GROUP NEXT ROW;
+ set mini = mini + x;
+ END LOOP;
+ return -1;
+end|
+
+--error 1329
+select f1(sal) from t1|
+drop function f1|
+
+#without loop
+create aggregate function f1(x int) returns int
+begin
+ declare mini int default 0;
+ declare continue handler for not found return mini;
+ FETCH GROUP NEXT ROW;
+ set mini = mini + x;
+end|
+
+--error 1321
+select f1(sal) from t1|
+drop function f1|
+
+
+create aggregate function f1(x int) returns int
+begin
+ declare mini int default 0;
+ declare continue handler for not found set mini=-1;
+ LOOP
+ FETCH GROUP NEXT ROW;
+ set mini = mini + x;
+ END LOOP;
+ return 0;
+end|
+
+--error 1321
+select f1(sal) from t1|
+drop function f1|
+drop table t1|
+
+delimiter ;|
+
+# primary indexing
+
+create table t1 (sal int, id int, val int, counter int, primary key(id));
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 1, 10, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (2000, 2, 16, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 3, 18, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 4, 15, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (3000, 5, 11, 5);
+
+delimiter |;
+
+create aggregate function f1(x INT) returns double
+begin
+ declare z double default 0;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ set z= z+x;
+ end loop;
+end|
+
+delimiter ;|
+
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter order by val;
+--sorted_result
+select id, f1(sal) from t1;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by id;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter order by counter;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter order by val;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter order by id;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val order by counter;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val order by id;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val order by val;
+drop table t1;
+
+#unique index
+
+create table t1 (sal int, id int, val int, counter int, primary key(id), unique key(val));
+
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 1, 10, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (2000, 2, NULL, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 3, 18, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 4, 15, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (3000, 5, 11, 5);
+
+--sorted_result
+select id, f1(sal) from t1;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by id;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter order by counter;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter order by val;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter order by id;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val order by counter;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val order by id;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val order by val;
+drop table t1;
+
+# compound indexing
+create table t1 (sal int, id int, val int, counter int, primary key(id), INDEX name (val,counter));
+
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 1, 10, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (2000, 2, 10, 4);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 3, 18, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 4, 11, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (3000, 5, 11, 5);
+--sorted_result
+select id, f1(sal) from t1;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by id;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter order by counter;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter order by val;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by counter order by id;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val order by counter;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val order by id;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by val order by val;
+drop table t1;
+drop function f1;
+
+# prepared statement with aggregate functions
+
+delimiter |;
+
+create aggregate function f1(x INT) returns double
+begin
+ declare z double default 0;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ set z= z+x;
+ end loop;
+end|
+
+create aggregate function f2() returns double
+begin
+ declare z int default 0;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ set z = z+1;
+ end loop;
+end|
+
+delimiter ;|
+
+create table t1 (sal int, id int, val int, counter int);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 2, 10, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (2000, 1, 16, 5);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 2, 18, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 3, 15, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (3000, 4, 11, 4);
+
+prepare test from "select f2() from t1 where id>= ?";
+set @param= 2;
+execute test using @param;
+execute test using @param;
+execute test using @param;
+execute test using @param;
+set @param= 1;
+execute test using @param;
+set @param= 3;
+execute test using @param;
+set @param= 4;
+execute test using @param;
+deallocate prepare test;
+
+prepare test from "select f1(sal) from t1 where id>= ?";
+set @param= 2;
+execute test using @param;
+execute test using @param;
+execute test using @param;
+execute test using @param;
+set @param= 1;
+execute test using @param;
+set @param= 3;
+execute test using @param;
+set @param= 4;
+execute test using @param;
+set @param= 5;
+execute test using @param;
+deallocate prepare test;
+
+drop function f2;
+
+prepare test from "select f1(sal) from t1 where id>= ?";
+set @param= 2;
+execute test using @param;
+drop function f1;
+
+create function f1(x int) returns int
+ return -1;
+
+execute test using @param;
+
+drop function f1;
+
+delimiter |;
+
+create aggregate function f1(x INT) returns double
+begin
+ declare z double default 0;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ set z= z+x;
+ end loop;
+end|
+
+delimiter ;|
+
+execute test using @param;
+
+deallocate prepare test;
+
+drop table t1;
+drop function f1;
+
+create table t1 (sal int, id int, val varchar(10), counter int);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 2, 'ab', 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 1, 'cd', 5);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 2, 'ef', 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 3, 'gh', 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 4, 'ij', 4);
+
+create table t2 (sal int, id int, val int, counter int);
+INSERT INTO t2 (sal, id, val, counter) VALUES (1000, 2, 10, 2);
+INSERT INTO t2 (sal, id, val, counter) VALUES (2000, 1, 16, 5);
+INSERT INTO t2 (sal, id, val, counter) VALUES (6000, 2, 18, 1);
+INSERT INTO t2 (sal, id, val, counter) VALUES (5000, 3, 15, 3);
+INSERT INTO t2 (sal, id, val, counter) VALUES (3000, 4, 11, 4);
+delimiter |;
+
+create aggregate function f1(x double) returns double
+begin
+ declare z double default 0;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ set z= z+x;
+ end loop;
+end|
+
+create aggregate function f2(x INT) returns CHAR(10)
+ begin
+ declare mini INT default 0;
+ declare continue handler for not found return mini;
+ loop
+ fetch group next row;
+ set mini= mini + x;
+ end loop;
+end|
+
+create aggregate function f3(x INT) returns CHAR(10)
+ begin
+ declare mini INT default 0;
+ declare continue handler for not found return mini;
+ loop
+ fetch group next row;
+ set mini= mini + x;
+ fetch group next row;
+ set mini= mini - x;
+ end loop;
+end|
+
+create aggregate function f4(x INT, y varchar(10)) returns varchar(1000)
+begin
+ declare str varchar(1000) default '';
+ declare continue handler for not found return str;
+ loop
+ fetch group next row;
+ set str= concat(str,y);
+ end loop;
+end|
+
+create aggregate function f5(x INT) returns varchar(1000)
+begin
+ declare z int default 0;
+ DECLARE cur1 CURSOR FOR SELECT sal FROM test.t2;
+ declare continue handler for not found return 0;
+ loop
+ fetch group next row;
+ set z = z+x;
+ end loop;
+end|
+
+
+
+create function f6(x int) returns int
+return (select f1(sal) from t1)|
+
+delimiter ;|
+
+select f1(sal) from t1;
+
+# group by test
+
+--sorted_result
+select f1(sal) from t1 where id>= 1 group by counter;
+
+# multiple fetch statements in the loop
+--sorted_result
+select f3(sal) from t1;
+
+# incorrect column type
+--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
+select f2(val) from t1;
+
+#subquery
+--sorted_result
+select val, id, c from (select f1(sal) as c from t2) as t1, t2;
+
+#multiple calls to an aggregate function
+--sorted_result
+select f1(sal),f1(val), f1(id), f1(sal) from t2;
+
+#string type, also more than one areguments
+--sorted_result
+select f4(sal, val) from t1;
+
+#select f1((select sal from t2 where id= 1)) from t1;
+--sorted_result
+select c from (select f1(sal) as c from t2) as t1;
+
+# this fails as more than one row is returned
+#select f1((select val from t2 where id > 1)) from t1;
+
+select f1((select val from t2 where 0 > 1)) from t1;
+select f1((select val from t2 where id= 1)) from t1;
+
+select f5(sal) from t1;
+
+SELECT f1(sal)*f1(sal) FROM t1;
+
+--sorted_result
+SELECT (SELECT f1(sal) FROM t1) FROM t2;
+--sorted_result
+select id, f1(sal) from t1;
+--sorted_result
+select id, f1(sal) from t1 where id>= 1;
+--sorted_result
+select f1(sal), f1(sal) from t1 where id>= 1 group by counter;
+--sorted_result
+select f1(sal), f1(sal) from t1 where id>= 1 group by id ;
+--sorted_result
+select f1(sal) from t1 where id>= 1 group by id ;
+select f1(sal) from t1 where id>= 1 order by counter;
+select f1(sal) from t1 where id>= 1 group by id order by counter;
+select counter, id, f1(sal) from t1 where id>= 1 group by id order by counter;
+select id, f1(sal) from t1 where id>= 1 group by id order by counter;
+drop table t1;
+drop table t2;
+drop function f1;
+drop function f2;
+drop function f3;
+drop function f4;
+drop function f5;
+drop function f6;
+
+
+delimiter |;
+
+# aggregate AND function
+
+create aggregate function f1(x INT) returns INT
+begin
+ declare z double default 1000;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ set z= (z&x);
+ end loop;
+end|
+
+delimiter ;|
+
+create table t1 (sal int, id int, val int, counter int);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 2, 10, 2);
+INSERT INTO t1 (sal, id, val, counter) VALUES (7000, 1, 16, 5);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 2, 18, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 3, 15, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (3000, 4, 11, 4);
+INSERT INTO t1 (sal, id, val, counter) VALUES (2000, 5, 10, 7);
+INSERT INTO t1 (sal, id, val, counter) VALUES (5000, 7, 13, 8);
+INSERT INTO t1 (sal, id, val, counter) VALUES (6000, 6, 19, 9);
+INSERT INTO t1 (sal, id, val, counter) VALUES (7000, 7, 12, 0);
+INSERT INTO t1 (sal, id, val, counter) VALUES (4000, 6, 14, 1);
+INSERT INTO t1 (sal, id, val, counter) VALUES (8000, 5, 19, 3);
+INSERT INTO t1 (sal, id, val, counter) VALUES (9000, 4, 11, 4);
+INSERT INTO t1 (sal, id, val, counter) VALUES (1000, 3, 11, 2);
+
+select f1(sal) from t1 where id>= 1;
+drop function f1;
+
+delimiter |;
+
+# aggregate AVG function
+
+create aggregate function f1(x INT) returns double
+begin
+ declare z double default 0;
+ declare count double default 0;
+ declare continue handler for not found return z/count;
+ loop
+ fetch group next row;
+ set z= z+x;
+ set count= count+1;
+ end loop;
+end|
+
+delimiter ;|
+select f1(sal) from t1 where id>= 1;
+drop function f1;
+delimiter |;
+
+# aggregate MAX function
+
+create aggregate function f1(x INT) returns INT
+begin
+ declare maxi INT default -1;
+ declare continue handler for not found return maxi;
+ loop
+ fetch group next row;
+ if maxi < x then
+ set maxi= x;
+ end if;
+ end loop;
+end|
+
+delimiter ;|
+select f1(sal) from t1 where id>= 1;
+drop function f1;
+delimiter |;
+
+# aggregate MIN function
+
+create aggregate function f1(x INT) returns double
+begin
+ declare mini INT default 100000;
+ declare continue handler for not found return mini;
+ loop
+ fetch group next row;
+ if mini > x then
+ set mini = x;
+ end if;
+ end loop;
+end|
+
+delimiter ;|
+select f1(sal) from t1 where id>= 1;
+drop function f1;
+delimiter |;
+
+# aggregate XOR function
+
+create aggregate function f1(x INT) returns double
+begin
+ declare z double default 0;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ set z= z^x;
+ end loop;
+end|
+
+delimiter ;|
+select f1(sal) from t1 where id>= 1;
+drop function f1;
+delimiter |;
+
+# aggregate SUM function
+
+create aggregate function f1(x INT) returns INT
+begin
+ declare z int default 0;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ set z= z+x;
+ end loop;
+end|
+
+delimiter ;|
+select f1(sal) from t1 where id>= 1;
+delimiter |;
+
+
+create aggregate function f2() returns INT
+begin
+ declare z double default 0;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ set z= z+1;
+ end loop;
+end|
+
+delimiter ;|
+
+# no parameters
+select f2() from t1;
+
+create table t2 (sal int, id int);
+INSERT INTO t2 (sal, id) VALUES (NULL, 1);
+INSERT INTO t2 (sal, id) VALUES (2000, 1);
+INSERT INTO t2 (sal, id) VALUES (3000, 1);
+
+# null values
+select f1(sal) from t2;
+
+# no tables
+select f1(1);
+
+# aggregate function called from regular functions
+create function f3() returns int
+return (select f1(sal) from t1);
+select f3();
+
+create function f4() returns INT
+return 1;
+
+# regular functions called from aggregate functions
+delimiter |;
+create aggregate function f5() returns INT
+begin
+ declare z double default 0;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ set z= z+f3();
+ end loop;
+end|
+
+delimiter ;|
+select f5() from t2;
+delimiter |;
+
+# aggregate functions called from aggregate functions
+create aggregate function f6(x INT) returns INT
+begin
+ declare z int default 0;
+ declare continue handler for not found return z;
+ loop
+ fetch group next row;
+ if x then
+ set z= z+(select f1(sal) from t1);
+ end if;
+ end loop;
+end|
+
+delimiter ;|
+select f6(sal) from t2;
+
+# GROUP BY AND ORDER BY
+--sorted_result
+select id, f1(sal) from t1 where id>= 1 group by id;
+--sorted_result
+select counter, f1(sal) from t1 where id>= 1 group by counter;
+--sorted_result
+select val, f1(sal) from t1 where id>= 1 group by val;
+--sorted_result
+select counter, f1(sal) from t1 where id>= 1 group by id order by counter;
+--sorted_result
+select counter, id, f1(sal), f1(sal) from t1 where id>= 1 group by id order by counter;
+--sorted_result
+select counter, id, f1(sal), sum(distinct sal) from t1 where id>= 1 group by id order by counter desc;
+
+
+##### insert aggregate function value into a table ######
+create table t3 (i int);
+INSERT INTO t3 (i) select f1(sal) from t1;
+select * from t3;
+
+delimiter |;
+
+create aggregate function f7(x INT) returns INT
+begin
+ declare z int default 0;
+ DECLARE done BOOLEAN DEFAULT FALSE;
+ DECLARE a,b,c INT;
+ DECLARE cur1 CURSOR FOR SELECT id FROM test.t2;
+ declare continue handler for not found return z;
+
+ outer_loop: LOOP
+ FETCH GROUP NEXT ROW;
+ set z= z+x;
+ inner_block: begin
+ DECLARE cur2 CURSOR FOR SELECT id FROM test.t2;
+ DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
+ OPEN cur2;
+
+ read_loop: LOOP
+ FETCH cur2 INTO a;
+ IF done THEN
+ CLOSE cur2;
+ LEAVE read_loop;
+ END IF;
+ END LOOP read_loop;
+
+ end inner_block;
+ END LOOP outer_loop;
+
+end|
+
+delimiter ;|
+select f7(sal) from t1;
+
+drop table t1;
+drop table t2;
+drop table t3;
+drop function f1;
+drop function f2;
+drop function f3;
+drop function f4;
+drop function f5;
+drop function f6;
+drop function f7;
+
+delimiter |;
+create aggregate function f1(x date) returns date
+begin
+ declare continue handler for not found return x;
+ loop
+ fetch group next row;
+ end loop;
+end|
+delimiter ;|
+select f1('2001-01-01'),cast(f1('2001-01-01') as time);
+drop function f1;
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index d30a6d7fd9e..466d79af409 100644
--- a/mysql-test/t/derived.test
+++ b/mysql-test/t/derived.test
@@ -897,6 +897,44 @@ select distinct t1.id, tt.id, tt.data
drop table t1;
+--echo #
+--echo # MDEV-14241: Server crash in key_copy / get_matching_chain_by_join_key
+--echo # or valgrind warnings
+--echo #
+
+CREATE TABLE t1 (a VARCHAR(10)) ENGINE=MyISAM;
+CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES ('foo'),('bar');
+
+CREATE TABLE t2 (b integer auto_increment primary key) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (NULL),(NULL);
+
+CREATE TABLE t3 (c VARCHAR(1024) CHARACTER SET utf8, d INT) ENGINE=MyISAM;
+CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3;
+INSERT INTO t3 VALUES ('abc',NULL),('def',4);
+
+SET join_cache_level= 8;
+explain
+SELECT * FROM v1, t2, v3 WHERE a = c AND b = d;
+SELECT * FROM v1, t2, v3 WHERE a = c AND b = d;
+
+DROP VIEW v1, v3;
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # MDEV-14786: Server crashes in Item_cond::transform on 2nd
+--echo # execution of SP querying from a view
+--echo #
+create table t1 (i int, row_start timestamp(6) not null default now(),
+ row_end timestamp(6) not null default '2030-01-01 0:0:0');
+create view v1 as select i from t1 where i < 5 and (row_end =
+TIMESTAMP'2030-01-01 0:0:0' or row_end is null);
+create procedure pr(x int) select i from v1;
+call pr(1);
+call pr(2);
+drop procedure pr;
+drop view v1;
+drop table t1;
--echo # end of 5.5
diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test
index a9bb998bc33..e728a9590a1 100644
--- a/mysql-test/t/derived_cond_pushdown.test
+++ b/mysql-test/t/derived_cond_pushdown.test
@@ -873,11 +873,585 @@ eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
-
+
drop view v1,v2,v3,v4;
drop view v_union,v2_union,v3_union,v4_union;
drop view v_double,v_char,v_decimal;
-drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;
+drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;
+
+--echo #
+--echo # MDEV-14579: pushdown conditions into materialized views/derived tables
+--echo # that are defined with EXIST or/and INTERSECT
+--echo #
+
+create table t1 (a int, b int, c int);
+create table t2 (a int, b int, c int);
+
+insert into t1 values
+ (1,21,345), (1,33,7), (8,33,114), (1,21,500), (1,19,117), (5,14,787),
+ (8,33,123), (9,10,211), (5,16,207), (1,33,988), (5,27,132), (1,21,104),
+ (6,20,309), (6,20,315), (1,21,101), (4,33,404), (9,10,800), (1,21,123);
+
+insert into t2 values
+ (2,3,207), (1,16,909), (5,14,312),
+ (5,33,207), (6,20,211), (1,19,132),
+ (8,33,117), (3,21,231), (6,23,303);
+
+create view v1 as
+ select a, b, min(c) as c from t1
+ where t1.a<9 group by a,b having c < 300
+ intersect
+ select a, b, min(c) as c from t1
+ where t1.b>10 group by a,b having c > 100;
+
+--echo # using intersect in view definition
+--echo # conjunctive subformulas : pushing into WHERE
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using intersect in view definition
+--echo # conjunctive subformulas : pushing into WHERE
+--echo # pushing equalities
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a=8);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using intersect in view definition
+--echo # conjunctive subformulas : pushing into WHERE using equalities
+let $query= select * from v1,t2 where (v1.a=t2.a) and (t2.a=8);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using intersect in view definition
+--echo # conjunctive subformulas : pushing into HAVING
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.c>200);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using intersect in view definition
+--echo # conjunctive subformulas : pushing into WHERE
+--echo # conjunctive subformulas : pushing into HAVING
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>110);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using intersect in view definition
+--echo # extracted or formula : pushing into WHERE
+let $query=
+ select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using intersect in view definition
+--echo # extracted or formula : pushing into HAVING
+let $query=
+ select * from v1,t2 where
+ (v1.a=t2.a) and ((v1.c>200) or (v1.c<105));
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using intersect in view definition
+--echo # extracted or formula : pushing into WHERE
+--echo # extracted or formula : pushing into HAVING using equalities
+--echo # pushing equalities
+let $query=
+ select * from v1,t2 where
+ ((v1.a>3) and (t2.c>110) and (v1.c=t2.c)) or
+ ((v1.a=1) and (v1.c<110));
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using intersect in view definition
+--echo # prepare of a query
+--echo # conjunctive subformulas : pushing into WHERE
+--echo # conjunctive subformulas : pushing into HAVING
+prepare stmt from "select * from v1,t2
+ where (v1.a=t2.a) and (v1.a<5) and (v1.c>110);";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+--echo # using intersect in derived table definition
+--echo # extracted or formula : pushing into WHERE using equalities
+--echo # extracted or formula : pushing into HAVING
+--echo # pushing equalities
+let $query=
+ select *
+ from t2,
+ (select a, b, min(c) as c from t1
+ where t1.a<9 group by a,b having c < 300
+ intersect
+ select a, b, min(c) as c from t1
+ where t1.b>10 group by a,b having c > 100) as d1
+ where
+ (d1.b=t2.b) and
+ (((t2.b>13) and (t2.c=909)) or
+ ((d1.a<4) and (d1.c<200)));
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+create view v1 as
+ select a, b, max(c) as c from t1
+ where t1.a<9 group by a,b having c > 200
+ except
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300;
+
+--echo # using except in view definition
+--echo # conjunctive subformulas : pushing into WHERE
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using except in view definition
+--echo # conjunctive subformulas : pushing into WHERE
+--echo # pushing equalities
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a=6);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using except in view definition
+--echo # conjunctive subformulas : pushing into WHERE using equalities
+let $query= select * from v1,t2 where (v1.a=t2.a) and (t2.a=6);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using except in view definition
+--echo # conjunctive subformulas : pushing into HAVING
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.c>500);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using except in view definition
+--echo # conjunctive subformulas : pushing into WHERE
+--echo # conjunctive subformulas : pushing into HAVING
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>500);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using except in view definition
+--echo # extracted or formula : pushing into WHERE
+let $query=
+ select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using except in view definition
+--echo # extracted or formula : pushing into HAVING
+let $query=
+ select * from v1,t2 where
+ (v1.a=t2.a) and ((v1.c<400) or (v1.c>800));
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using except in view definition
+--echo # extracted or formula : pushing into WHERE
+--echo # extracted or formula : pushing into HAVING using equalities
+--echo # pushing equalities
+let $query=
+ select * from v1,t2 where
+ (v1.c=t2.c) and
+ ((v1.a>1) and (t2.c<500)) or
+ ((v1.a=1) and (v1.c>500));
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+--echo # using except in view definition
+--echo # prepare of a query
+--echo # conjunctive subformulas : pushing into WHERE
+--echo # conjunctive subformulas : pushing into HAVING
+prepare stmt from "select * from v1,t2
+ where (v1.a=t2.a) and (v1.a<5) and (v1.c>500);";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+--echo # using except in view definition
+--echo # extracted or formula : pushing into WHERE using equalities
+--echo # extracted or formula : pushing into HAVING
+--echo # pushing equalities
+let $query=
+ select *
+ from t2,
+ (select a, b, max(c) as c from t1
+ where t1.a<9 group by a,b having c > 200
+ except
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300) as d1
+ where
+ (d1.b=t2.b) and
+ (((t2.b>13) and (t2.c=988)) or
+ ((d1.a>4) and (d1.c>500)));
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using union and intersect in view definition
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, min(c) as c from t1
+ where t1.a<9 group by a,b having c > 200
+ union
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300
+ intersect
+ select a, b, max(c) as c from t1
+ where t1.a>3 group by a,b having c < 530;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using union and intersect in view definition
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, min(c) as c from t1
+ where t1.a<9 group by a,b having c > 200
+ intersect
+ select a, b, max(c) as c from t1
+ where t1.a>3 group by a,b having c < 500
+ union
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using union and except in view definition
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, min(c) as c from t1
+ where t1.a<9 group by a,b having c > 200
+ union
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300
+ except
+ select a, b, max(c) as c from t1
+ where t1.a>3 group by a,b having c < 530;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using union and except in view definition
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, min(c) as c from t1
+ where t1.a<9 group by a,b having c > 200
+ except
+ select a, b, max(c) as c from t1
+ where t1.a>3 group by a,b having c < 500
+ union
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using except and intersect in view definition
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300
+ intersect
+ select a, b, max(c) as c from t1
+ where t1.a<7 group by a,b having c < 500
+ except
+ select a, b, max(c) as c from t1
+ where t1.a<9 group by a,b having c > 150;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<150);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using except and intersect in view definition
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300
+ except
+ select a, b, max(c) as c from t1
+ where t1.a<9 group by a,b having c > 150
+ intersect
+ select a, b, max(c) as c from t1
+ where t1.a<7 group by a,b having c < 500;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using except, intersect and union in view definition
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300
+ except
+ select a, b, max(c) as c from t1
+ where t1.a<9 group by a,b having c > 150
+ intersect
+ select a, b, max(c) as c from t1
+ where t1.a<7 group by a,b having c < 500
+ union
+ select a, b, max(c) as c from t1
+ where t1.a<7 group by a,b having c < 120;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using intersect in view definition
+--echo # using embedded view
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300
+ intersect
+ select a, b, max(c) as c from t1
+ where t1.a<9 group by a,b having c > 120;
+
+create view v2 as
+ select a, b, max(c) as c from v1
+ where v1.a<7 group by a,b;
+
+let $query= select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1,v2;
+
+--echo # using except in view definition
+--echo # using embedded view
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c < 300
+ except
+ select a, b, max(c) as c from t1
+ where t1.a<9 group by a,b having c > 150;
+
+create view v2 as
+ select a, b, max(c) as c from v1
+ where v1.a<7 group by a,b;
+
+let $query= select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1,v2;
+
+--echo # using intersect in view definition
+--echo # conditions are pushed in different parts of selects
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, max(c) as c from t1
+ where t1.a<9 group by a having c > 300
+ intersect
+ select a, b, max(c) as c from t1
+ where t1.b<21 group by b having c > 200;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.b>12) and (v1.c<450);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using except in view definition
+--echo # conditions are pushed in different parts of selects
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, max(c) as c from t1
+ where t1.b>20 group by a having c > 300
+ except
+ select a, b, max(c) as c from t1
+ where t1.a<7 group by b having c > 150;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<2) and (v1.b<30) and (v1.c>450);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using except and union in view definition
+--echo # conditions are pushed in different parts of selects
+--echo # conjunctive subformulas : pushing into HAVING
+--echo # extracted or formula : pushing into WHERE
+--echo # extracted or formula : pushing into HAVING
+create view v1 as
+ select a, b, max(c) as c from t1
+ where t1.b>20 group by a having c > 300
+ except
+ select a, b, max(c) as c from t1
+ where t1.a<7 group by b having c > 150;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and ((v1.a<2) or (v1.a<5)) and (v1.c>450);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using union and intersect in view definition
+--echo # conditions are pushed in different parts of selects
+--echo # conjunctive subformulas : pushing into WHERE and HAVING
+create view v1 as
+ select a, b, max(c) as c from t1
+ where t1.a<9 group by a having c > 100
+ intersect
+ select a, b, max(c) as c from t1
+ where t1.a>3 group by b having c < 800
+ union
+ select a, b, max(c) as c from t1
+ where t1.b>10 group by a,b having c > 300;
+
+let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>1) and (v1.b > 12) and (v1.c>400);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+create table t3 (a int, b int, c int);
+insert into t3 values
+ (1,21,345), (2,33,7), (8,33,114), (3,21,500), (1,19,107), (5,14,787),
+ (4,33,123), (9,10,211), (11,16,207), (10,33,988), (5,27,132), (12,21,104),
+ (6,20,309), (16,20,315), (16,21,101), (18,33,404), (19,10,800), (10,21,123),
+ (17,11,708), (6,20,214);
+
+create index i1 on t3(a);
+
+--echo # conjunctive subformulas : pushing into WHERE
+--echo # pushed condition gives range access
+create view v1 as
+ select a, b, max(c) as max_c from t3
+ where a>0 group by a;
+
+let $query= select * from v1,t2 where (v1.b=t2.b) and (v1.a<5);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using union in view definition
+--echo # conjunctive subformulas : pushing into WHERE
+--echo # pushed condition gives range access
+create view v1 as
+ select a, b, max(c) as c from t3
+ where t3.a>1 group by a
+ union
+ select a, b, max(c) as c from t3
+ where t3.a>2 group by a;
+
+let $query= select * from v1,t2 where (v1.b=t2.b) and (v1.a<4);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+--echo # using union in view definition
+--echo # conjunctive subformulas : pushing into WHERE
+--echo # pushed condition gives range access in one of the selects
+create view v1 as
+ select a, b, max(c) as c from t3
+ where t3.a>1 group by a
+ union
+ select a, b, max(c) as c from t3
+ where t3.b<21 group by b;
+
+let $query= select * from v1,t2 where (v1.b=t2.b) and (v1.a<3);
+eval $no_pushdown $query;
+eval $query;
+eval explain $query;
+eval explain format=json $query;
+
+drop view v1;
+
+alter table t3 drop index i1;
+
+drop table t1,t2,t3;
--echo #
--echo # MDEV-10782: condition extracted from a multiple equality
@@ -1567,11 +2141,36 @@ eval explain format=json $q;
drop table t1;
--echo #
+--echo # MDEV-13454: consequence of mdev-14368 fixed for 5.5
+--echo #
+
+SET sql_mode = 'ONLY_FULL_GROUP_BY';
+
+create table t1 (id int, id2 int);
+insert into t1 values (1,1),(2,3),(3,4),(7,2);
+
+create table t2(id2 int);
+insert t2 values (1),(2),(3);
+
+let $q=
+SELECT * FROM t1
+ LEFT OUTER JOIN
+ (SELECT id2, COUNT(*) as ct FROM t2 GROUP BY id2) vc USING (id2)
+WHERE (vc.ct>0);
+
+eval $q;
+eval EXPLAIN FORMAT=JSON $q;
+
+DROP TABLE t1,t2;
+
+SET sql_mode = DEFAULT;
+
+--echo #
--echo # MDEV-10855: Pushdown into derived with window functions
--echo #
set @save_optimizer_switch= @@optimizer_switch;
-set optimizer_switch='split_grouping_derived=off';
+set optimizer_switch='split_materialized=off';
create table t1 (a int, c varchar(16));
insert into t1 values
@@ -1682,28 +2281,62 @@ set optimizer_switch= @save_optimizer_switch;
--echo #
let
-$no_splitting= set statement optimizer_switch='split_grouping_derived=off' for;
+$no_splitting= set statement optimizer_switch='split_materialized=off' for;
-create table t1 (a int);
+create table t1 (a int, b int, index idx_b(b)) engine=myisam;
insert into t1 values
-(8), (5), (1), (2), (9), (7), (2), (7);
+(8,3), (5,7), (1,2), (2,1), (9,7), (7,5), (2,2), (7,3),
+(9,3), (8,1), (4,5), (2,3);
-create table t2 (a int, b int, index idx(a));
+create table t2 (a int, b int, c char(127), index idx_a(a)) engine=myisam;
insert into t2 values
- (7,10), (1,20), (2,23), (7,18), (1,30),
- (4,71), (3,15), (7,82), (8,12), (4,15),
- (11,33), (10,42), (4,53), (10,17), (2,90);
+ (7,10,'x'), (1,20,'a'), (2,23,'b'), (7,18,'z'), (1,30,'c'),
+ (4,71,'d'), (3,15,'x'), (7,82,'y'), (8,12,'t'), (4,15,'b'),
+ (11,33,'a'), (10,42,'u'), (4,53,'p'), (10,17,'r'), (2,90,'x'),
+ (17,10,'s'), (11,20,'v'), (12,23,'y'), (17,18,'a'), (11,30,'d'),
+ (24,71,'h'), (23,15,'i'), (27,82,'k'), (28,12,'p'), (24,15,'q'),
+ (31,33,'f'), (30,42,'h'), (40,53,'m'), (30,17,'o'), (21,90,'b'),
+ (37,10,'e'), (31,20,'g'), (32,23,'f'), (37,18,'n'), (41,30,'l'),
+ (54,71,'j'), (53,15,'w'), (57,82,'z'), (58,12,'k'), (54,15,'p'),
+ (61,33,'c'), (60,42,'a'), (62,53,'x'), (67,17,'g'), (64,90,'v');
+
+insert into t2 select a+10, b+10, concat(c,'f') from t2;
+
+analyze table t1,t2;
let $q1=
-select t1.a,t.max,t.min
+select t1.a,t.s,t.m
from t1 join
- (select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) t
- on t1.a=t.a;
+ (select a, sum(t2.b) as s, min(t2.c) as m from t2 group by t2.a) t
+ on t1.a=t.a
+where t1.b < 3;
eval $no_splitting $q1;
eval $q1;
eval explain extended $q1;
-eval explain format=json $q1;
+eval explain format=json $q1;
+eval prepare stmt from "$q1";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+let $q10=
+select t1.a,t.s,t.m
+from t1 join
+ (select a, sum(t2.b) as s, min(t2.b) as m from t2 group by t2.a) t
+ on t1.a=t.a
+where t1.b <= 5;
+
+eval $no_splitting $q10;
+eval $q10;
+eval explain extended $q10;
+eval explain format=json $q10;
+eval prepare stmt from "$q10";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+delete from t1 where t1.b between 2 and 5;
let $q2=
select t1.a,t.max,t.min
@@ -1716,68 +2349,122 @@ eval $q2;
eval explain extended $q2;
eval explain format=json $q2;
-create table t3 (a int, c varchar(16));
+create table t3 (a int, b int, c char(127), index idx_b(b)) engine=myisam;
insert into t3 values
-(8,'aa'), (5,'cc'), (1,'bb'), (2,'aa'), (9,'cc'),
-(7,'aa'), (2,'aa'), (7,'bb');
+(8,11,'aa'), (5,15,'cc'), (1,14,'bb'), (2,12,'aa'), (7,17,'cc'),
+(7,18,'aa'), (2,11,'aa'), (7,10,'bb'), (3,11,'dd'), (4,12,'ee'),
+(5,14,'dd'), (9,12,'ee');
-create table t4 (a int, b int, c varchar(16), index idx(a,c));
+create table t4 (a int, b int, c char(127), index idx(a,c)) engine=myisam;
insert into t4 values
(7,10,'cc'), (1,20,'aa'), (2,23,'bb'), (7,18,'cc'), (1,30,'bb'),
- (4,71,'xx'), (3,15,'aa'), (7,82,'bb'), (8,12,'dd'), (4,15,'aa'),
- (11,33,'yy'), (10,42,'zz'), (4,53,'xx'), (10,17,'yy'), (7,12,'bb'),
+ (4,71,'xx'), (3,15,'aa'), (7,82,'aa'), (8,12,'dd'), (4,15,'aa'),
+ (11,33,'yy'), (10,42,'zz'), (4,53,'xx'), (10,17,'yy'), (7,12,'cc'),
(8,20,'dd'), (7,32,'bb'), (1,50,'aa'), (3,40,'bb'), (3,77,'aa');
+insert into t4 select a+10, b+10, concat(c,'f') from t4;
+
+analyze table t3,t4;
+
let $q3=
select t3.a,t3.c,t.max,t.min
from t3 join
(select a, c, max(b) max, min(b) min from t4 group by a,c) t
- on t3.a=t.a and t3.c=t.c;
+ on t3.a=t.a and t3.c=t.c
+where t3.b > 15;
eval $no_splitting $q3;
eval $q3;
eval explain extended $q3;
eval explain format=json $q3;
+let $q30=
+select t3.a,t3.c,t.max,t.min
+from t3 join
+ (select a, c, max(b) max, min(b) min from t4 group by a,c) t
+ on t3.a=t.a and t3.c=t.c
+where t3.b <= 15;
+
+eval $no_splitting $q30;
+eval $q30;
+eval explain extended $q30;
+eval explain format=json $q30;
+
let $q4=
select t3.a,t3.c,t.max,t.min
from t3 join
(select a, c, max(b) max, min(b) min from t4 group by c,a) t
- on t3.a=t.a and t3.c=t.c;
+ on t3.a=t.a and t3.c=t.c
+where t3.b > 15;
eval $no_splitting $q4;
eval $q4;
eval explain extended $q4;
eval explain format=json $q4;
-drop index idx on t2;
-create index idx on t2(b);
-create index idx on t3(a);
-create index idx2 on t4(c);
-insert into t3 select a+1, concat(c,'f') from t3;
-insert into t3 select a+1, concat(c,'h') from t3;
-insert into t4 select a+1, b+10, concat(c,'h') from t4;
+let $q40=
+select t3.a,t3.c,t.max,t.min
+from t3 join
+ (select a, c, max(b) max, min(b) min from t4 group by c,a) t
+ on t3.a=t.a and t3.c=t.c
+where t3.b <= 15;
+
+eval $no_splitting $q40;
+eval $q40;
+eval explain extended $q40;
+eval explain format=json $q40;
+
+drop index idx_a on t2;
+create index idx on t2(c,b);
+create index idx_a on t3(a);
+create index idx_c on t4(c);
+insert into t3 select a+10, b+10, concat(c,'f') from t3;
+insert into t3 select a+100, b+100, concat(c,'g') from t3;
+insert into t4 select a+100, b+100, concat(c,'g') from t4;
+insert into t4 select a+1000, b+1000, concat(c,'h') from t4;
+
+analyze table t2,t3,t4;
let $q5=
-select t2.a,t2.b,t3.c,t.max,t.min
+select t2.a,t2.b,t2.c,t.c as t_c,t.max,t.min
from t2, t3, (select c, max(b) max, min(b) min from t4 group by c) t
-where t2.b > 50 and t2.a=t3.a and t3.c=t.c;
+where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c;
eval $no_splitting $q5;
eval $q5;
eval explain extended $q5;
eval explain format=json $q5;
+let $q50=
+select t2.a,t2.b,t2.c,t.c as t_c,t.max,t.min
+from t2, t3, (select c, max(b) max, min(b) min from t4 group by c) t
+where t2.b < 40 and t2.a=t3.a and t3.c=t.c;
+
+eval $no_splitting $q50;
+eval $q50;
+eval explain extended $q50;
+eval explain format=json $q50;
+
let $q6=
select *
from t2, t3, (select c, b, sum(b) over (partition by c) from t4 ) t
-where t2.b > 50 and t2.a=t3.a and t3.c=t.c;
+where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c;
eval $no_splitting $q6;
eval $q6;
eval explain extended $q6;
eval explain format=json $q6;
+let $q60=
+select *
+from t2, t3, (select c, b, sum(b) over (partition by c) from t4 ) t
+where t2.b < 40 and t2.a=t3.a and t3.c=t.c;
+
+eval $no_splitting $q60;
+eval $q60;
+eval explain extended $q60;
+eval explain format=json $q60;
+
drop table t1,t2,t3,t4;
--echo #
@@ -1791,18 +2478,23 @@ INSERT INTO t1 VALUES (1),(9),(3);
CREATE TABLE t2 (a int, i int);
INSERT INTO t2 VALUES (1,9),(2,3),(3,7),(4,1);
-CREATE TABLE t3 (a int, c varchar(8), index(c));
+CREATE TABLE t3 (a int, c char(127), index(c));
INSERT INTO t3 VALUES (1,'foo'),(3,'bar'),(4,'foo'),(2,'bar');
+INSERT INTO t3 SELECT a, concat(c,'a') FROM t3;
+
+CREATE TABLE t4 (a int, c char(127), index(a));
+INSERT INTO t4 VALUES
+ (3,'abc'),(1,'foo'),(4,'def'),(8,'xxx'),(3,'yyy'),
+ (5,'zzz'),(9,'xyz'),(2,'yxz'),(5,'zxy'),(7,'zyx') ;
-CREATE TABLE t4 (c varchar(8));
-INSERT INTO t4 VALUES ('abc'),('foo'),('def');
+ANALYZE TABLE t1,t2,t3,t4;
CREATE VIEW v1 AS
SELECT c FROM t3
WHERE a IN ( SELECT t2.a FROM t1 JOIN t2 WHERE t1.i = t2.i ) GROUP BY c ;
let $q1=
-SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 );
+SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 ) and a < 2;
eval $no_splitting $q1;
eval $q1;
@@ -1852,3 +2544,72 @@ SELECT * FROM v3 JOIN t1 ON (bmax = b);
DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
+--echo #
+--echo # MDEV-14845: Impossible where for derived with GROUP BY
+--echo #
+
+CREATE TABLE t1 (pk INT PRIMARY KEY);
+
+INSERT INTO t1 VALUES (1),(2);
+
+let $q=
+WITH cte AS ( SELECT pk FROM t1 WHERE pk IS NULL GROUP BY pk )
+SELECT * FROM cte;
+
+eval $q;
+eval EXPLAIN EXTENDED $q;
+
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14880: assertion failure in optimizer when splitting is applied
+--echo #
+
+CREATE TABLE t1 (pk1 INT PRIMARY KEY, f INT) ENGINE=Aria;
+INSERT INTO t1 VALUES (1,0),(2,0);
+
+CREATE TABLE t2 (pk2 INT PRIMARY KEY) ENGINE=Aria;
+INSERT INTO t2 VALUES (1),(2),(3);
+
+CREATE VIEW v2 AS SELECT pk2, COUNT(*) AS cnt FROM t2 GROUP BY pk2;
+
+let $q=
+SELECT * FROM t1 INNER JOIN v2 ON pk1 = pk2 WHERE f <> 5;
+
+eval $q;
+eval EXPLAIN EXTENDED $q;
+eval EXPLAIN FORMAT=JSON $q;
+
+DROP VIEW v2;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # MDEV-15017: splittable table is constant table
+--echo #
+
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+
+CREATE TABLE t2 (pk INT, b INT, PRIMARY KEY (pk)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,2),(3,4);
+
+CREATE VIEW v2 AS SELECT pk, MIN(b) FROM t2 GROUP BY pk;
+
+SELECT * FROM t1 LEFT JOIN v2 ON (a = pk);
+
+DROP VIEW v2;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # MDEV-14994: splittable table with no rows
+--echo #
+
+CREATE TABLE t1 (f INT PRIMARY KEY) ENGINE=MyISAM;
+CREATE VIEW v1 AS SELECT a.* FROM t1 AS a STRAIGHT_JOIN t1 AS b;
+CREATE VIEW v2 AS SELECT f FROM v1 GROUP BY f;
+
+SELECT * FROM v1 JOIN v2 ON v1.f = v2.f;
+EXPLAIN EXTENDED
+SELECT * FROM v1 JOIN v2 ON v1.f = v2.f;
+
+DROP VIEW v1,v2;
+DROP TABLE t1;
diff --git a/mysql-test/t/dyncol.test b/mysql-test/t/dyncol.test
index c0d22e9d1c4..f2c0a31c898 100644
--- a/mysql-test/t/dyncol.test
+++ b/mysql-test/t/dyncol.test
@@ -920,6 +920,23 @@ SELECT COLUMN_JSON(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL));
SELECT COLUMN_JSON(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL));
+
+--echo #
+--echo # MDEV-7533: COLUMN_JSON() doesn't escape control characters
+--echo # in string values
+--echo #
+SELECT COLUMN_JSON(COLUMN_CREATE('test','"\\\t\n\Z')) AS json;
+SELECT COLUMN_JSON(COLUMN_CREATE('test','First line\nSecond line')) AS json;
+
+--echo #
+--echo # MDEV-15230: column_json breaks cyrillic in 10.1.31
+--echo #
+set names utf8;
+create table t1 (b blob);
+insert into t1 values (column_create('description',column_create('title','ОпиÑание')));
+select column_json(b) from t1;
+drop table t1;
+
--echo #
--echo # end of 10.0 tests
--echo #
diff --git a/mysql-test/t/explain_json.test b/mysql-test/t/explain_json.test
index d253b8380e9..c3665b1818b 100644
--- a/mysql-test/t/explain_json.test
+++ b/mysql-test/t/explain_json.test
@@ -406,3 +406,14 @@ explain format=json
select a, (select max(a) from t1 where t0.a<5 and t1.b<t0.a) from t0;
drop table t0,t1;
+--echo #
+--echo # MDEV-10844: EXPLAIN FORMAT=JSON doesn't show order direction for filesort
+--echo #
+
+create table t1 (a int, b int);
+insert into t1 values (1,2),(3,4),(2,3);
+explain format=json select * from t1 order by a, b desc;
+explain format=json select * from t1 order by a desc, b desc;
+explain format=json select * from t1 order by a desc, b ;
+drop table t1;
+
diff --git a/mysql-test/t/frm_bad_row_type-7333.test b/mysql-test/t/frm_bad_row_type-7333.test
index 5100a85cb22..916550402c9 100644
--- a/mysql-test/t/frm_bad_row_type-7333.test
+++ b/mysql-test/t/frm_bad_row_type-7333.test
@@ -9,6 +9,6 @@ copy_file std_data/bad_row_type.frm $datadir/test/bad_row_type.frm;
select * from bad_row_type;
show create table bad_row_type;
-replace_column 12 x 13 x;
+replace_column 12 x 13 x 19 x;
show table status like 'bad_row_type';
drop table bad_row_type;
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 12d36ce645b..2e53ce7f112 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -683,6 +683,21 @@ SELECT * FROM t1 WHERE MATCH (txt1,txt2) AGAINST ('ööö1' IN BOOLEAN MODE);
SELECT * FROM t1 WHERE MATCH (txt1,txt2) AGAINST ('ùùù2' IN BOOLEAN MODE);
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14743: Server crashes in Item_func_match::init_search
+--echo #
+
+CREATE TABLE t1 (f VARCHAR(8));
+INSERT INTO t1 VALUES ('foo'),('bar');
+
+SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) );
+SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE )) as f1, MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) as f2 from t1 ;
+explain extended
+SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE )) as f1, MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) as f2 from t1 ;
+
+drop table t1;
+
--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/mysql-test/t/func_concat.test b/mysql-test/t/func_concat.test
index be573f494a2..69dd2c4063e 100644
--- a/mysql-test/t/func_concat.test
+++ b/mysql-test/t/func_concat.test
@@ -236,3 +236,9 @@ SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TRIM(t) t2 FROM t1) sub;
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # MDEV-13790 UNHEX() of a somewhat complicated CONCAT() returns NULL
+--echo #
+
+SELECT UNHEX(CONCAT('414C2', HEX(8 + ROUND(RAND()*7)), SUBSTR(SHA(UUID()),6,33),HEX(2+ROUND(RAND()*8)))) IS NULL AS c1;
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index 1038fc0f6d0..5cbc6969e02 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -915,3 +915,76 @@ DROP TABLE t1;
--echo #
--echo # End of 10.2 tests
--echo #
+
+
+--echo #
+--echo # Start of 10.3 tests
+--echo #
+
+#
+# MDEV-11297: Add support for LIMIT clause in GROUP_CONCAT()
+#
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+create table t1 (grp int, a bigint unsigned, c char(10) , d char(10) not null);
+insert into t1 values (1,1,NULL,"a");
+insert into t1 values (1,10,"b","a");
+insert into t1 values (1,11,"c","a");
+insert into t1 values (2,2,"c","a");
+insert into t1 values (2,3,"b","b");
+insert into t1 values (3,4,"E","a");
+insert into t1 values (3,5,"C","b");
+insert into t1 values (3,6,"D","c");
+insert into t1 values (3,7,"E","c");
+
+
+select grp,group_concat(c) from t1 group by grp;
+select grp,group_concat(c limit 1 ) from t1 group by grp;
+select grp,group_concat(c limit 1,1 ) from t1 group by grp;
+select grp,group_concat(c limit 1,10 ) from t1 group by grp;
+select grp,group_concat(c limit 1000) from t1 group by grp;
+select group_concat(grp limit 0) from t1;
+--error ER_PARSE_ERROR
+select group_concat(grp limit "sdjadjs") from t1
+--error ER_PARSE_ERROR
+select grp,group_concat(c limit 5.5) from t1 group by grp ;
+select grp,group_concat(distinct c limit 1,10 ) from t1 group by grp;
+select grp,group_concat(c order by a) from t1 group by grp;
+select grp,group_concat(c order by a limit 2 ) from t1 group by grp;
+select grp,group_concat(c order by a limit 1,1 ) from t1 group by grp;
+select grp,group_concat(c order by c) from t1 group by grp;
+select grp,group_concat(c order by c limit 2) from t1 group by grp;
+select grp,group_concat(c order by c desc) from t1 group by grp;
+select grp,group_concat(c order by c desc limit 2) from t1 group by grp;
+
+drop table t1;
+
+create table t2 (a int, b varchar(10));
+insert into t2 values(1,'a'),(1,'b'),(NULL,'c'),(2,'x'),(2,'y');
+select group_concat(a,b limit 2) from t2;
+
+set @x=4;
+prepare STMT from 'select group_concat(b limit ?) from t2';
+execute STMT using @x;
+set @x=2;
+execute STMT using @x;
+set @x=1000;
+execute STMT using @x;
+set @x=0;
+execute STMT using @x;
+set @x="adasfa";
+--error ER_INVALID_VALUE_TO_LIMIT
+execute STMT using @x;
+set @x=-1;
+--error ER_WRONG_ARGUMENTS
+execute STMT using @x;
+set @x=4;
+prepare STMT from 'select group_concat(a,b limit ?) from t2';
+execute STMT using @x;
+drop table t2;
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 8f6062fd2c2..b99fad159c2 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -676,3 +676,17 @@ EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-15340 Wrong result HOUR(case_expression_with_time_and_datetime)
+--echo #
+
+# This is to make sure that TIME_FUZZY_DATE is always passed to str_to_time(),
+# so empty strings are compared as TIME'00:00:00' all around the code:
+# when using Arg_comparator (e.g. in binary comparison operators), and
+# when not using it (e.g. in IN predicate).
+
+SELECT
+ TIME'00:00:00'='' AS c1_true,
+ TIME'00:00:00' IN ('', TIME'10:20:30') AS c2_true,
+ TIME'00:00:00' NOT IN ('', TIME'10:20:30') AS c3_false;
diff --git a/mysql-test/t/func_isnull.test b/mysql-test/t/func_isnull.test
index 326574e0515..4c59fa3cbe8 100644
--- a/mysql-test/t/func_isnull.test
+++ b/mysql-test/t/func_isnull.test
@@ -38,5 +38,51 @@ INSERT INTO t1( id ) VALUES ( NULL );
SELECT t1.id FROM t1 WHERE (id is not null and id is null );
DROP TABLE t1;
-# End of 5.1 tests
+--echo # End of 5.1 tests
+--echo #
+--echo # MDEV-14911: IS NULL for field from mergeable view
+--echo #
+
+CREATE TABLE t1 (d1 datetime NOT NULL);
+INSERT INTO t1 VALUES
+ ('0000-00-00 00:00:00'), ('0000-00-00 00:00:00'), ('1979-09-03 20:49:36');
+
+SELECT * FROM t1;
+SELECT * FROM t1 WHERE d1 IS NULL;
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE d1 IS NULL;
+SELECT count(*) FROM t1 WHERE d1 IS NULL;
+
+CREATE VIEW v1 AS (SELECT * FROM t1);
+SELECT * FROM v1;
+SELECT * FROM v1 WHERE d1 IS NULL;
+EXPLAIN EXTENDED SELECT * FROM v1 WHERE d1 IS NULL;
+SELECT count(*) FROM v1 WHERE d1 IS NULL;
+
+SET @save_optimizer_switch=@@optimizer_switch;
+
+SET SESSION optimizer_switch='derived_merge=off';
+SELECT count(*) FROM ( SELECT * FROM t1 ) AS a1 WHERE d1 IS NULL;
+SET SESSION optimizer_switch='derived_merge=on';
+SELECT count(*) FROM ( SELECT * FROM t1 ) AS a1 WHERE d1 IS NULL;
+
+SET optimizer_switch=@save_optimizer_switch;
+
+CREATE TABLE t2 (d1 datetime NOT NULL);
+INSERT INTO t2 VALUES
+ ('1980-09-03 20:49:36'), ('0000-00-00 00:00:00'), ('1979-09-03 20:49:36');
+
+SELECT * FROM t2 LEFT JOIN t1 ON t2.d1=t1.d1 WHERE t1.d1 IS NULL;
+EXPLAIN EXTENDED
+SELECT * FROM t2 LEFT JOIN t1 ON t2.d1=t1.d1 WHERE t1.d1 IS NULL;
+
+SELECT * FROM t2 LEFT JOIN v1 ON t2.d1=v1.d1 WHERE v1.d1 IS NULL;
+EXPLAIN EXTENDED
+SELECT * FROM t2 LEFT JOIN v1 ON t2.d1=v1.d1 WHERE v1.d1 IS NULL;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # End of 5.5 tests
+--echo #
diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test
index 47ed0c3ca75..91fc67570f5 100644
--- a/mysql-test/t/func_json.test
+++ b/mysql-test/t/func_json.test
@@ -9,6 +9,7 @@ select json_value('{"key1":123}', '$.key2');
select json_value('{"key1":123}', '$.key1');
select json_value('{"key1":[1,2,3]}', '$.key1');
select json_value('{"key1": [1,2,3], "key1":123}', '$.key1');
+select JSON_VALUE('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }','$.z');
select json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key2');
select json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key1');
@@ -377,6 +378,19 @@ SELECT JSON_OBJECT("user","Jožko MrkviÄká") as json_data;
select json_contains_path('{"foo":"bar"}', 'one', '$[]');
+#
+# MDEV-13971 crash in skip_num_constant.
+#
+select JSON_VALID(0x36f0c8dccd83c5eac156da);
+
+#
+# MDEV-13970 crash in Item_func_json_extract::read_json.
+#
+create table t1(a double not null);
+insert into t1 values (2),(1);
+select 1 from t1 where json_extract(a,'$','$[81]');
+drop table t1;
+
--echo #
--echo # Start of 10.3 tests
--echo #
diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index 91ee449a7ff..9f452e632ec 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -1153,6 +1153,27 @@ SELECT str, str1, b,c FROM t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-14613: Assertion `fixed == 0' failed in Item_func::fix_fields
+--echo #
+
+CREATE TABLE `t1` (
+ `numgtfmt` char(10) COLLATE utf8_bin NOT NULL
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+create view v1(numgtfmt)
+as
+select 'x' from t1
+union
+select 'x' from t1 ;
+
+SELECT * FROM v1 WHERE numgtfmt = NAME_CONST('wnumgtfmt',_utf8'QEDITIONS' COLLATE 'utf8_bin');
+
+# Cleanup
+DROP VIEW v1;
+DROP TABLE t1;
+
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test
index 47072ba5ffe..3509e225a34 100644
--- a/mysql-test/t/func_set.test
+++ b/mysql-test/t/func_set.test
@@ -136,18 +136,14 @@ SELECT * FROM t1 WHERE FIND_IN_SET(NULL, NULL) IS UNKNOWN;
--echo
DROP TABLE t1;
---echo #
---echo # Start of 5.3 tests
---echo #
--echo #
---echo # MDEV-4512 Valgrind warnings in my_long10_to_str_8bit on INTERVAL and DATE_ADD with incorrect types
+--echo # MDEV-14596 Crash in INTERVAL(ROW(..),ROW(..))
--echo #
-CREATE TABLE t1 (pk INT PRIMARY KEY);
-INSERT INTO t1 VALUES (10),(11);
-SELECT INTERVAL( 9, 1, DATE_ADD( pk, INTERVAL pk MINUTE_SECOND ), 9, 8, 3, 5, 2, 1 ) FROM t1;
-DROP TABLE t1;
---echo #
---echo # End of 5.3 tests
---echo #
+--error ER_OPERAND_COLUMNS
+SELECT INTERVAL(ROW(1,1),ROW(1,2));
+--error ER_OPERAND_COLUMNS
+SELECT INTERVAL(1,ROW(1,2));
+--error ER_OPERAND_COLUMNS
+SELECT INTERVAL(ROW(1,2),1);
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index a75330ab981..dbb7502a3ec 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1810,6 +1810,18 @@ set global max_allowed_packet=default;
--echo #
--echo #
+--echo # Start of 10.0 tests
+--echo #
+
+--echo #
+--echo # MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
+--echo #
+
+EXPLAIN EXTENDED SELECT CHAR(0xDF USING latin1);
+EXPLAIN EXTENDED SELECT CHAR(0xDF USING `binary`);
+EXPLAIN EXTENDED SELECT CHAR(0xDF);
+
+--echo #
--echo # Start of 10.1 tests
--echo #
@@ -1854,6 +1866,15 @@ SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64(
DROP TABLE t1;
--echo #
+--echo # End of 10.1 tests
+--echo #
+
+
+--echo #
+--echo # Start of 10.3 tests
+--echo #
+
+--echo #
--echo # MDEV-12685 Oracle-compatible function CHR()
--echo #
select chr(65);
@@ -1865,15 +1886,6 @@ drop database mysqltest1;
use test;
--echo #
---echo # End of 10.1 tests
---echo #
-
-
---echo #
---echo # Start of 10.3 tests
---echo #
-
---echo #
--echo # MDEV-12592 Illegal mix of collations with the HEX function
--echo #
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 09c13598cfd..a475c33b925 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -1945,3 +1945,56 @@ SELECT CONVERT_TZ(ROW(1,1),1,1);
SELECT CONVERT_TZ(1, ROW(1,1), 1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CONVERT_TZ(1, 1, ROW(1,1));
+
+
+--echo #
+--echo # MDEV-15340 Wrong result HOUR(case_expression_with_time_and_datetime)
+--echo #
+
+SET TIMESTAMP=UNIX_TIMESTAMP('2018-02-17 01:02:03');
+SELECT
+ COALESCE(TIME'800:00:00', NOW()) AS c,
+ HOUR(COALESCE(TIME'800:00:00',NOW())) AS hc;
+
+SELECT
+ CASE WHEN TRUE THEN TIME'800:00:00' ELSE NOW() END AS c,
+ HOUR(CASE WHEN TRUE THEN TIME'800:00:00' ELSE NOW() END) AS hc;
+
+SELECT
+ IFNULL(TIME'800:00:00', NOW()) AS c,
+ HOUR(IFNULL(TIME'800:00:00', NOW())) AS hc;
+
+SELECT
+ IF(TRUE,TIME'800:00:00', NOW()) AS c,
+ HOUR(IF(TRUE,TIME'800:00:00', NOW())) AS hc;
+
+SELECT
+ ADDTIME(TIME'10:20:30', TIMESTAMP'2001-01-01 00:00:00') AS c1,
+ ADDTIME(TIME'10:20:30', COALESCE(TIMESTAMP'2001-01-01 00:00:00',TIMESTAMP'2001-01-01 00:00:00')) AS c2,
+ ADDTIME(TIME'10:20:30', DATE'2001-01-01') AS c3,
+ ADDTIME(TIME'10:20:30', COALESCE(DATE'2001-01-01',TIMESTAMP'2001-01-01 00:00:00')) AS c4;
+
+#
+# Make sure that time functions that in 10.2 used get_arg0_time()
+# do not mix days to hours for dates with zero YYYYMM and non-zero days.
+#
+
+SELECT
+ HOUR(TIMESTAMP'0000-00-01 10:00:00') AS h0,
+ TIME_TO_SEC(TIMESTAMP'0000-00-01 10:00:00') AS tts0,
+ TIME_TO_SEC(TIMESTAMP'0000-00-01 10:00:00.1') AS tts1,
+ CAST(TIMESTAMP'0000-00-01 10:00:00' AS TIME) AS c0,
+ CAST(TIMESTAMP'0000-00-01 10:00:00.1' AS TIME(1)) AS c2;
+
+SET TIMESTAMP=DEFAULT;
+
+--echo #
+--echo # MDEV-15363 Wrong result for CAST(LAST_DAY(TIME'00:00:00') AS TIME)
+--echo #
+
+SET TIMESTAMP=UNIX_TIMESTAMP('2018-02-17 01:02:03');
+SELECT
+ LAST_DAY(TIME'00:00:00') AS c1,
+ CAST(CAST(LAST_DAY(TIME'00:00:00') AS DATE) AS TIME) AS c2,
+ CAST(LAST_DAY(TIME'00:00:00') AS TIME) AS c3;
+SET TIMESTAMP=DEFAULT;
diff --git a/mysql-test/t/gis-json.test b/mysql-test/t/gis-json.test
index 5e695fbca9c..b91ef235fd0 100644
--- a/mysql-test/t/gis-json.test
+++ b/mysql-test/t/gis-json.test
@@ -40,6 +40,10 @@ SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),10);
SELECT ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 1);
SELECT ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 5);
+SELECT st_astext(st_geomfromgeojson('{"type": "MultiLineString","coordinates": []}')) as a;
+SELECT st_astext(st_geomfromgeojson('{"type": "Polygon","coordinates": []}')) as a;
+SELECT st_astext(st_geomfromgeojson('{"type": "MultiPolygon","coordinates": []}')) as a;
+
--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test
index 976398359c6..41388090427 100644
--- a/mysql-test/t/gis-rtree.test
+++ b/mysql-test/t/gis-rtree.test
@@ -3,15 +3,12 @@
#
# test of rtree (using with spatial data)
#
---disable_warnings
-DROP TABLE IF EXISTS t1, t2;
---enable_warnings
CREATE TABLE t1 (
- fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL,
SPATIAL KEY(g)
-) ENGINE=MyISAM;
+);
SHOW CREATE TABLE t1;
@@ -31,9 +28,9 @@ SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160
DROP TABLE t1;
CREATE TABLE t2 (
- fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL
-) ENGINE=MyISAM;
+);
let $1=10;
while ($1)
@@ -50,9 +47,9 @@ while ($1)
ALTER TABLE t2 ADD SPATIAL KEY(g);
SHOW CREATE TABLE t2;
SELECT count(*) FROM t2;
-EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g,
+EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
-SELECT fid, AsText(g) FROM t2 WHERE Within(g,
+SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
let $1=10;
@@ -70,7 +67,6 @@ while ($1)
DROP TABLE t2;
-drop table if exists t1;
CREATE TABLE t1 (a geometry NOT NULL, SPATIAL (a));
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
@@ -110,10 +106,10 @@ drop table t1;
#
CREATE TABLE t1 (
- fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL,
SPATIAL KEY(g)
-) ENGINE=MyISAM;
+);
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 2, 2 3)')),(GeomFromText('LineString(1 2, 2 4)'));
#select * from t1 where g<GeomFromText('LineString(1 2, 2 3)');
@@ -125,12 +121,10 @@ CREATE TABLE t1 (
name VARCHAR(32),
SPATIAL KEY (line)
-
-
-) engine=myisam;
+);
ALTER TABLE t1 DISABLE KEYS;
-INSERT INTO t1 (name, kind, line) VALUES
+INSERT INTO t1 (name, kind, line) VALUES
("Aadaouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
("Aadassiye", "pp", GeomFromText("POINT(35.816667 36.216667)")),
("Aadbel", "pp", GeomFromText("POINT(34.533333 36.100000)")),
@@ -172,7 +166,7 @@ CREATE TABLE t2 (geom GEOMETRY NOT NULL, SPATIAL KEY gk(geom));
INSERT IGNORE INTO t2 SELECT GeomFromText(st) FROM t1;
drop table t1, t2;
-CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`)) DEFAULT CHARSET=latin1;
INSERT INTO t1 (geometry) VALUES
(PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000
@@ -193,7 +187,7 @@ drop table t1;
CREATE TABLE t1 (
c1 geometry NOT NULL default '',
SPATIAL KEY i1 (c1)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+) DEFAULT CHARSET=latin1;
INSERT INTO t1 (c1) VALUES (
PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
-18.6055555000 -66.8158332999,
@@ -207,7 +201,7 @@ DROP TABLE t1;
CREATE TABLE t1 (
c1 geometry NOT NULL default '',
SPATIAL KEY i1 (c1)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+) DEFAULT CHARSET=latin1;
INSERT INTO t1 (c1) VALUES (
PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
-18.6055555000 -66.8158332999,
@@ -252,7 +246,7 @@ CREATE TABLE t1 (id bigint(12) unsigned NOT NULL auto_increment,
spatial_point point NOT NULL,
PRIMARY KEY(id),
SPATIAL KEY (spatial_point)
- )ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+ ) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
#
INSERT INTO t1 (c2, c1, c3, spatial_point) VALUES
('y', 's', 'j', GeomFromText('POINT(167 74)')),
@@ -848,7 +842,7 @@ INSERT INTO t1(foo) VALUES ('');
DROP TABLE t1;
#
-# Bug #23578: Corruption prevents Optimize table from working properly with a
+# Bug #23578: Corruption prevents Optimize table from working properly with a
# spatial index
#
@@ -931,12 +925,12 @@ DROP TABLE t1;
--echo #
---echo # Bug #57323/11764487: myisam corruption with insert ignore
+--echo # Bug #57323/11764487: myisam corruption with insert ignore
--echo # and invalid spatial data
--echo #
CREATE TABLE t1(a POINT NOT NULL, b GEOMETRY NOT NULL,
- SPATIAL KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
+ SPATIAL KEY(a), SPATIAL KEY(b));
INSERT INTO t1 VALUES(GEOMFROMTEXT("point (0 0)"), GEOMFROMTEXT("point (1 1)"));
--error ER_CANT_CREATE_GEOMETRY_OBJECT
INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=GEOMFROMTEXT("error");
@@ -946,7 +940,7 @@ SELECT ASTEXT(a), ASTEXT(b) FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a INT NOT NULL, b GEOMETRY NOT NULL,
- KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
+ KEY(a), SPATIAL KEY(b));
INSERT INTO t1 VALUES(0, GEOMFROMTEXT("point (1 1)"));
--error ER_CANT_CREATE_GEOMETRY_OBJECT
INSERT IGNORE INTO t1 SET a=0, b=GEOMFROMTEXT("error");
@@ -959,11 +953,11 @@ DROP TABLE t1;
#
# MDEV-4521 MBRContains, MBRWithin no longer work with geometries of different type.
-#
+#
CREATE TABLE t1 (
l LINESTRING NOT NULL,
SPATIAL KEY(l)
-) ENGINE = myisam;
+);
INSERT INTO t1 VALUES(GeomFromText('LINESTRING(0 0, 1 1)'));
INSERT INTO t1 VALUES(GeomFromText('LINESTRING(1 1, 2 2)'));
@@ -985,7 +979,7 @@ DROP TABLE t1;
--echo #
--echo # MDEV-8239 Reverse spatial operations OP(const, field) do not get optimized
--echo #
-CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a)) ENGINE=MyISAM;
+CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a));
INSERT INTO t1 VALUES (Point(1,2)),(Point(1,3));
EXPLAIN SELECT * FROM t1 WHERE MBRINTERSECTS(a,Point(1,2));
EXPLAIN SELECT * FROM t1 WHERE ST_INTERSECTS(a,Point(1,2));
@@ -996,7 +990,7 @@ DROP TABLE t1;
--echo #
--echo # MDEV-8610 "WHERE CONTAINS(indexed_geometry_column,1)" causes full table scan
--echo #
-CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a)) ENGINE=MyISAM;
+CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a));
INSERT INTO t1 VALUES (Point(1,1)),(Point(2,2)),(Point(3,3));
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1);
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index a2df97949d8..275939df5c5 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -1790,6 +1790,32 @@ select t1.c1 as c1, t2.c2 as c1 from t1, t2 where t1.c1 < 20 and t2.c2 > 5 group
drop table t1, t2;
#
+# MDEV-12350: Heap corruption, overrun buffer, ASAN errors, server crash in my_fill_8bit / filesort
+#
+
+SET @old_sort_buff_size = @@sort_buffer_size;
+SET @@sort_buffer_size=256*1024;
+CREATE TABLE t1 (c INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+ (2011),(1977),(1982),(2027),(2023),(NULL),(NULL),(2004),(1974),(2032),
+ (1993),(NULL),(1995),(2034),(NULL),(2009),(1900),(NULL),(2025),(1900),
+ (2033),(1900),(2012),(NULL),(2009),(1992),(1974),(1974),(2012),(2028),
+ (2007),(2012),(1900),(1983),(1900),(2010),(1987),(1994),(1981),(2032),
+ (2010),(1989),(2014),(1900),(1900),(1976),(1978),(2007),(2030),(NULL),
+ (2002),(1997),(1900),(NULL),(2000),(2027),(1975),(2026),(1975),(2026),
+ (2029),(1977),(1900),(1900),(2031),(1993),(1986),(2012),(1979),(2013),
+ (1994),(2014),(2025),(2006),(1971),(1974),(2021),(2011),(NULL),(1991),
+ (2001),(1977),(2023),(2012),(1900),(1978),(1998),(NULL),(1988),(1999),
+ (2017),(2008),(1976),(1900),(2005),(2030),(2023),(1900),(1978),(1990),
+ (1978),(1987),(2030),(1900),(2034),(2006),(2015),(2001),(2019),(2024),
+ (2030),(1989),(1997),(2007),(2023),(1994),(1971),(2011),(2011),(2015),
+ (1984),(1978),(1979),(1989),(2008),(2030);
+
+SELECT ExtractValue('<a></a>','/a') AS f1, SPACE(c) AS f2 FROM t1 GROUP BY f1, f2 WITH ROLLUP;
+SET @@sort_buffer_size = @old_sort_buff_size;
+DROP TABLE t1;
+
+#
# End of MariaDB 5.5 tests
#
diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test
index 3d8f7dc42b7..3675a09d82f 100644
--- a/mysql-test/t/having.test
+++ b/mysql-test/t/having.test
@@ -729,6 +729,23 @@ HAVING UPPER(`column_1`) LIKE '8%';
drop table t1;
--echo #
+--echo # mdev-14368: grouping query with alias for aggregate function in HAVING
+--echo # when sql_mode = 'ONLY_FULL_GROUP_BY'
+
+
+set @save_sql_mode= @@sql_mode;
+set sql_mode = 'ONLY_FULL_GROUP_BY';
+
+create table t1(a int);
+insert t1 values (4),(1),(2),(1), (3),(4);
+
+SELECT a, COUNT(a) as ct FROM t1 GROUP BY a HAVING ct>0;
+
+set sql_mode=@save_sql_mode;
+
+drop table t1;
+
+--echo #
--echo # Bug mdev-5160: two-way join with HAVING over the second table
--echo #
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 9c306de0e3f..1f72d0b6129 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -81,7 +81,7 @@ select * from information_schema.STATISTICS where TABLE_SCHEMA = "mysqltest";
show keys from t3 where Key_name = "a_data";
show tables like 't%';
---replace_column 8 # 12 # 13 #
+--replace_column 8 # 12 # 13 # 19 #
show table status;
show full columns from t3 like "a%";
show full columns from mysql.db like "Insert%";
@@ -721,7 +721,7 @@ drop table t1;
CREATE TABLE t1 (a int);
CREATE TABLE t2 (b int);
---replace_column 8 # 12 # 13 #
+--replace_column 8 # 12 # 13 # 19 #
SHOW TABLE STATUS FROM test
WHERE name IN ( SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_TYPE='BASE TABLE');
@@ -867,7 +867,7 @@ drop table t1;
use mysql;
INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL',
'NO','DEFINER','','','BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03',
-'2006-03-02 18:40:03','','','utf8','utf8_general_ci','utf8_general_ci','n/a');
+'2006-03-02 18:40:03','','','utf8','utf8_general_ci','utf8_general_ci','n/a', 'NONE');
select routine_name from information_schema.routines where ROUTINE_SCHEMA='test';
delete from proc where name='';
use test;
diff --git a/mysql-test/t/intersect.test b/mysql-test/t/intersect.test
index 99a54606291..98b6d1eb1c6 100644
--- a/mysql-test/t/intersect.test
+++ b/mysql-test/t/intersect.test
@@ -190,4 +190,19 @@ show create view v1;
drop view v1;
drop tables t1,t2,t3;
+--echo #
+--echo # MDEV-14346:incorrect result of intersect with ANY/ALL/IN subquery
+--echo #
+CREATE TABLE t (i INT);
+INSERT INTO t VALUES (1),(2);
+SELECT * FROM t WHERE i != ANY ( SELECT 6 INTERSECT SELECT 3 );
+
+select i from t where
+ exists ((select 6 as r from dual having t.i <> 6)
+ intersect
+ (select 3 from dual having t.i <> 3));
+
+drop table t;
+
+
--echo # End of 10.3 tests
diff --git a/mysql-test/t/invisible_binlog.test b/mysql-test/t/invisible_binlog.test
new file mode 100644
index 00000000000..654afcc39c3
--- /dev/null
+++ b/mysql-test/t/invisible_binlog.test
@@ -0,0 +1,32 @@
+--source include/master-slave.inc
+
+--connection master
+create table t1(a int , b int invisible);
+insert into t1 values(1);
+insert into t1(a,b) values(2,2);
+select a,b from t1;
+desc t1;
+
+create table t2(a int , b int invisible default 5);
+insert into t2 values(1);
+insert into t2(a,b) values(2,2);
+select a,b from t2;
+desc t2;
+
+
+--sync_slave_with_master
+select * from t1;
+select a,b from t1;
+desc t1;
+show create table t1;
+
+select * from t2;
+select a,b from t2;
+desc t2;
+show create table t2;
+
+
+--connection master
+drop table t1,t2;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/t/invisible_field.test b/mysql-test/t/invisible_field.test
new file mode 100644
index 00000000000..884abb1238d
--- /dev/null
+++ b/mysql-test/t/invisible_field.test
@@ -0,0 +1,240 @@
+FLUSH STATUS;
+create table t1(abc int primary key, xyz int invisible);
+SHOW STATUS LIKE 'Feature_invisible_columns';
+desc t1;
+show create table t1;
+select TABLE_CATALOG,TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,EXTRA from INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA='test' and TABLE_NAME='t1';
+drop table t1;
+--error ER_TABLE_MUST_HAVE_COLUMNS
+create table t1(a1 int invisible);
+--error ER_PARSE_ERROR
+create table t1(a1 blob,invisible(a1));
+--error ER_INVISIBLE_NOT_NULL_WITHOUT_DEFAULT
+create table t1(a1 int primary key invisible ,a2 int unique invisible , a3 blob,a4 int not null invisible unique);
+--error ER_TABLE_MUST_HAVE_COLUMNS
+create table t1(abc int not null invisible);
+--echo MDEV-14849 CREATE + ALTER with user-invisible columns produce invalid table definition
+create or replace table t1 (pk int auto_increment primary key invisible, i int);
+--error ER_INVISIBLE_NOT_NULL_WITHOUT_DEFAULT
+alter table t1 modify pk int invisible;
+drop table t1;
+create table t1(a int invisible, b int);
+#should automatically add null
+insert into t1 values(1);
+insert into t1(a) values(2);
+insert into t1(b) values(3);
+insert into t1(a,b) values(5,5);
+select * from t1;
+select a,b from t1;
+delete from t1;
+insert into t1 values(1),(2),(3),(4);
+select * from t1;
+select a from t1;
+drop table t1;
+
+--echo #more complex case of invisible
+create table t1(a int , b int invisible , c int invisible auto_increment unique, d blob , e int unique, f int);
+desc t1;
+insert into t1 values(1,'d blob',1,1),(1,'d blob',11,1),(1,'d blob',2,1),(1,'d blob',3,1),(1,'d blob',41,1);
+select * from t1;
+select a,b,c,d,e,f from t1;
+drop table t1;
+
+--echo #more complex case of invisible with sql_mode=NO_AUTO_VALUE_ON_ZERO
+set sql_mode='NO_AUTO_VALUE_ON_ZERO';
+create table t1(a int , b int invisible , c int invisible auto_increment unique, d blob , e int unique, f int);
+desc t1;
+insert into t1 values(1,'d blob',1,1),(1,'d blob',11,1),(1,'d blob',2,1),(1,'d blob',3,1),(1,'d blob',41,1);
+select * from t1;
+select a,b,c,d,e,f from t1;
+drop table t1;
+set sql_mode='';
+
+--error ER_PARSE_ERROR
+create table sdsdsd(a int , b int, invisible(a,b));
+create table t1(a int,abc int as (a mod 3) virtual invisible);
+desc t1;
+--error ER_WRONG_VALUE_COUNT_ON_ROW
+insert into t1 values(1,default);
+insert into t1 values(1),(22),(233);
+select * from t1;
+select a,abc from t1;
+drop table t1;
+create table t1(abc int primary key invisible auto_increment, a int);
+desc t1;
+show create table t1;
+insert into t1 values(1);
+insert into t1 values(2);
+insert into t1 values(3);
+select * from t1;
+select abc,a from t1;
+delete from t1;
+insert into t1 values(1),(2),(3),(4),(6);
+select abc,a from t1;
+drop table t1;
+create table t1(abc int);
+--error ER_TABLE_MUST_HAVE_COLUMNS
+alter table t1 change abc ss int invisible;
+alter table t1 add column xyz int;
+alter table t1 modify column abc int ;
+desc t1;
+--error ER_WRONG_VALUE_COUNT_ON_ROW
+insert into t1 values(22);
+alter table t1 modify column abc int invisible;
+desc t1;
+insert into t1 values(12);
+drop table t1;
+--echo #some test on copy table structure with table data;
+--echo #table with invisible fields and unique keys;
+create table t1(a int , b int invisible , c int invisible auto_increment unique, d blob , e int unique, f int);
+desc t1;
+insert into t1 values(1,'d blob',1,1),(1,'d blob',11,1),(1,'d blob',2,1),(1,'d blob',3,1),(1,'d blob',41,1);
+select * from t1;
+select a,b,c,d,e,f from t1;
+--echo #this won't copy invisible fields and keys;
+create table t2 as select * from t1;
+desc t2;
+select * from t2;
+--error ER_BAD_FIELD_ERROR
+select a,b,c,d,e,f from t2;
+drop table t2;
+--echo #now this will copy invisible fields
+create table t2 as select a,b,c,d,e,f from t1;
+desc t2;
+select * from t2;
+select a,b,c,d,e,f from t2;
+drop table t2,t1;
+--echo #some test related to copy of data from one table to another;
+create table t1(a int , b int invisible , c int invisible auto_increment unique, d blob , e int unique, f int);
+insert into t1 values(1,'d blob',1,1),(1,'d blob',11,1),(1,'d blob',2,1),(1,'d blob',3,1),(1,'d blob',41,1);
+select a,b,c,d,e,f from t1;
+create table t2(a int , b int invisible , c int invisible , d blob , e int unique, f int);
+insert into t2 select * from t1;
+select a,b,c,d,e,f from t2;
+truncate t2;
+insert into t2 (a,b,c,d,e,f) select a,b,c,d,e,f from t1;
+select a,b,c,d,e,f from t2;
+truncate t2;
+drop table t1,t2;
+--echo #some test related to creating view on table with invisible column;
+create table t1(a int , b int invisible , c int invisible auto_increment unique, d blob , e int unique, f int);
+insert into t1 values(1,'d blob',1,1),(1,'d blob',11,1),(1,'d blob',2,1),(1,'d blob',3,1),(1,'d blob',41,1);
+create view v as select * from t1;
+desc v;
+select * from v;
+--echo #v does not have invisible column;
+--error ER_BAD_FIELD_ERROR
+select a,b,c,d,e,f from v;
+insert into v values(1,21,32,4);
+select * from v;
+--error ER_BAD_FIELD_ERROR
+insert into v(a,b,c,d,e,f) values(1,12,3,4,5,6);
+drop view v;
+create view v as select a,b,c,d,e,f from t1;
+desc v;
+select * from v;
+--echo #v does have invisible column but they aren't invisible anymore.
+select a,b,c,d,e,f from v;
+insert into v values(1,26,33,4,45,66);
+select a,b,c,d,e,f from v;
+insert into v(a,b,c,d,e,f) values(1,32,31,41,5,6);
+select a,b,c,d,e,f from v;
+drop view v;
+drop table t1;
+--echo #now invisible column in where and some join query
+create table t1 (a int unique , b int invisible unique, c int unique invisible);
+insert into t1(a,b,c) values(1,1,1);
+insert into t1(a,b,c) values(2,2,2);
+insert into t1(a,b,c) values(3,3,3);
+insert into t1(a,b,c) values(4,4,4);
+insert into t1(a,b,c) values(21,21,26);
+insert into t1(a,b,c) values(31,31,35);
+insert into t1(a,b,c) values(41,41,45);
+insert into t1(a,b,c) values(22,22,24);
+insert into t1(a,b,c) values(32,32,33);
+insert into t1(a,b,c) values(42,42,43);
+explain select * from t1 where b=3;
+select * from t1 where b=3;
+explain select * from t1 where c=3;
+select * from t1 where c=3;
+create table t2 as select a,b,c from t1;
+desc t2;
+explain select * from t1,t2 where t1.b = t2.c and t1.c = t2.b;
+select * from t1,t2 where t1.b = t2.c and t1.c = t2.b;
+drop table t1,t2;
+--echo #Unhide invisible columns
+create table t1 (a int primary key, b int invisible, c int invisible unique);
+show create table t1;
+desc t1;
+alter table t1 modify column b int;
+desc t1;
+alter table t1 change column c d int;
+desc t1;
+drop table t1;
+SHOW STATUS LIKE 'Feature_invisible_columns';
+--echo #invisible is non reserved
+create table t1(a int unique , invisible int invisible, c int );
+desc t1;
+alter table t1 change column invisible hid int invisible;
+desc t1;
+drop table t1;
+##Internal temp table
+CREATE TABLE t1 (b int);
+INSERT t1 values(1);
+INSERT t1 values(2);
+INSERT t1 values(3);
+INSERT t1 values(4);
+INSERT t1 values(5);
+CREATE TABLE t2 (a int invisible) SELECT * FROM t1;
+select * from t2 order by b;
+select a,b from t2 order by b;
+CREATE TABLE t3 (b int, a int invisible) SELECT * FROM t1;
+select * from t3 order by b;
+select a,b from t3 order by b;
+--error ER_TABLE_MUST_HAVE_COLUMNS
+CREATE TABLE t4 (b int invisible) SELECT * FROM t1;
+--error ER_TABLE_MUST_HAVE_COLUMNS
+CREATE TABLE t5 (a int invisible) SELECT b as a FROM t1;
+drop table t1,t2,t3;
+
+create table t1 (a int , b int invisible default 3, c int , d int invisible default 6);
+DELIMITER //;
+CREATE PROCEDURE
+insert_t1(a int, b int)
+MODIFIES SQL DATA
+insert into t1 values(a,b);
+//
+DELIMITER ;//
+call insert_t1(1,1);
+call insert_t1(2,2);
+select * from t1 order by a;
+select a,b,c,d from t1 order by a;
+DROP PROCEDURE insert_t1;
+delete from t1;
+prepare insert_1 from "insert into t1 values(@a,@c)";
+prepare insert_2 from "insert into t1(a,b,c) values(@a,@b,@c)";
+set @a=1, @c=1;
+execute insert_1;
+set @a=2,@b=2, @c=2;
+execute insert_2;
+select a,b,c,d from t1 order by a;
+drop table t1;
+#MDEV-15085 Non constant default getting Null values
+create table t1(a int default 5 invisible, b int);
+create table t2(a int default (b+11) invisible, b int);
+insert into t1 values(1);
+select a,b from t1;
+insert into t2 values(1);
+select a,b from t2;
+drop table t1,t2;
+
+#
+# natural join and using
+#
+create table t1 (a int invisible, b int, c int);
+create table t2 (a int, b int, d int);
+insert t1 (a,b,c) values (0,2,3), (10, 20, 30);
+insert t2 (a,b,d) values (1,2,4), (10, 30, 40);
+select * from t1 join t2 using (a);
+select * from t1 natural join t2;
+drop table t1, t2;
diff --git a/mysql-test/t/invisible_field_debug.test b/mysql-test/t/invisible_field_debug.test
new file mode 100644
index 00000000000..8674620e055
--- /dev/null
+++ b/mysql-test/t/invisible_field_debug.test
@@ -0,0 +1,272 @@
+--source include/have_debug.inc
+##TEST for invisible coloumn level 2
+set @old_debug= @@debug_dbug;
+create table t_tmp(a int, b int);
+set debug_dbug= "+d,test_pseudo_invisible";
+create table t1(a int);
+set debug_dbug=@old_debug;
+insert into t1 values(1);
+desc t1;
+show create table t1;
+select a , invisible from t1;
+##field should not be resolved in fill_record
+--error ER_BAD_FIELD_ERROR
+insert into t1(a, invisible) values(99,99);
+--error ER_BAD_FIELD_ERROR
+insert into t1(invisible) values(99);
+insert into t_tmp select a, invisible from t1;
+--error ER_WRONG_VALUE_COUNT_ON_ROW
+insert into t1 select * from t_tmp;
+--error ER_BAD_FIELD_ERROR
+insert into t1(a,invisible) select * from t_tmp;
+
+select a , invisible from t1;
+insert into t1 values (5), (invisible+1);
+select a , invisible from t1;
+delete from t1 where a > 1;
+
+##Update
+update t1 set a = invisible where a=1;
+select a , invisible from t1;
+update t1 set a = (select invisible+100 from t1 limit 1) where a=(select a from t1 limit 1);
+select a , invisible from t1;
+
+--error ER_BAD_FIELD_ERROR
+update t1 set invisible = 23 where a=(select a from t1 limit 1);
+--error ER_BAD_FIELD_ERROR
+update t1 set invisible = 101 where a=(select a from t1 limit 1);
+--error ER_BAD_FIELD_ERROR
+update t1 set invisible = (select invisible+100 from t1 limit 1) where a=(select invisible from t1 limit 1);
+select a , invisible from t1;
+##if changed then error
+set @a=12;
+--error ER_BAD_FIELD_ERROR
+update t1 set invisible = (select @a from dual) where a=(select a from t1 limit 1);
+select a , invisible from t1;
+--error ER_BAD_FIELD_ERROR
+update t1 set invisible = (select invisible+100 from t1 limit 1) where a=(select a from t1 limit 1);
+select a , invisible from t1;
+
+##set
+set @a=(select invisible from t1 limit 1);
+select @a from dual;
+--error ER_BAD_FIELD_ERROR
+alter table t1 add constraint a check (invisible > 2);
+set debug_dbug= "+d,test_pseudo_invisible";
+--error ER_BAD_FIELD_ERROR
+create table t2(a int, b int as (invisible +2) virtual);
+create table t2(a int , b int);
+insert into t2 values(2,2);
+insert into t2 select a, invisible from t1;
+set debug_dbug=@old_debug;
+select * from t1;
+select invisible ,a from t1;
+drop table t1,t2,t_tmp;
+
+##TEST for invisible coloumn level 3
+
+set debug_dbug= "+d,test_completely_invisible";
+create table t1(a int);
+set debug_dbug=@old_debug;
+
+desc t1;
+show create table t1;
+insert into t1 values(1);
+select * from t1;
+
+--error ER_BAD_FIELD_ERROR
+select invisible ,a from t1;
+
+set debug_dbug= "+d,test_completely_invisible";
+select invisible ,a from t1;
+set debug_dbug=@old_debug;
+
+create table t2 (invisible int);
+--error ER_BAD_FIELD_ERROR
+select * from t1 join t2 using (invisible);
+--error ER_BAD_FIELD_ERROR
+select * from t2 join t1 using (invisible);
+
+insert t2 values (8),(9);
+select * from t1 natural join t2;
+select * from t2 natural join t1;
+
+drop table t1, t2;
+
+##TEST for Alter table for invisibleness level 2
+
+set debug_dbug= "+d,test_pseudo_invisible";
+create table t1(a int);
+set debug_dbug=@old_debug;
+
+desc t1;
+insert into t1 values(1);
+select * from t1;
+select invisible ,a from t1;
+
+## Alter should not be possible
+
+--error ER_BAD_FIELD_ERROR
+ALTER table t1 change invisible b int;
+select * from t1;
+select invisible ,a from t1;
+
+--error ER_BAD_FIELD_ERROR
+ALTER table t1 modify invisible char;
+select * from t1;
+select invisible ,a from t1;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER table t1 drop invisible;
+select * from t1;
+select invisible ,a from t1;
+
+--error ER_DUP_FIELDNAME
+ALTER table t1 add invisible int;
+select * from t1;
+select invisible ,a from t1;
+
+ALTER table t1 add invisible2 int default 2;
+select * from t1;
+select invisible ,a from t1;
+
+--error ER_BAD_FIELD_ERROR
+create trigger trg before insert on t1 for each row set new.invisible=1;
+create trigger trg before insert on t1 for each row set @a:=new.invisible;
+
+drop table t1;
+
+##TEST for Alter table for invisibleness level 3
+
+set debug_dbug= "+d,test_completely_invisible";
+create table t1(a int);
+
+set debug_dbug=@old_debug;
+--error ER_BAD_FIELD_ERROR
+create trigger trg before insert on t1 for each row set new.invisible=1;
+--error ER_BAD_FIELD_ERROR
+create trigger trg before insert on t1 for each row set @a:=new.invisible;
+set debug_dbug= "+d,test_completely_invisible";
+
+desc t1;
+insert into t1 values(1);
+select * from t1;
+select invisible ,a from t1;
+
+## Alter should not be possible
+
+--error ER_BAD_FIELD_ERROR
+ALTER table t1 change invisible b int;
+select * from t1;
+select invisible ,a from t1;
+
+--error ER_BAD_FIELD_ERROR
+ALTER table t1 modify invisible char;
+select * from t1;
+select invisible ,a from t1;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER table t1 drop invisible;
+select * from t1;
+select invisible ,a from t1;
+
+ALTER table t1 add invisible int;
+select * from t1;
+select invisible1, invisible ,a from t1;
+
+ALTER table t1 add hid int default 2;
+select * from t1;
+select invisible ,a from t1;
+
+drop table t1;
+set debug_dbug=@old_debug;
+
+## Test Index on USER_DEFINED_INVISIBLE
+
+Create table t1( a int default(99) invisible, b int);
+insert into t1 values(1);
+insert into t1 values(2);
+insert into t1 values(3);
+insert into t1 values(4);
+select * from t1 order by b;
+alter table t1 add index(a);
+alter table t1 add index(a,b);
+show index from t1;
+drop table t1;
+
+## Test Index on PSEUDO_invisible_INVISIBLE
+
+set debug_dbug= "+d,test_pseudo_invisible";
+Create table t1( a int default(99) invisible, b int);
+
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+Create table t2( a int default(99) invisible, b int, unique(invisible));
+
+set debug_dbug=@old_debug;
+insert into t1 values(1);
+insert into t1 values(2);
+insert into t1 values(3);
+insert into t1 values(4);
+select * from t1 order by b;
+select invisible, a, b from t1 order by b;
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+alter table t1 add index(invisible);
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+alter table t1 add index(b,invisible);
+show index from t1;
+drop table t1;
+
+## Test Index on COMPLETELY_INVISIBLE
+
+set debug_dbug= "+d,test_completely_invisible";
+Create table t1( a int default(99) invisible, b int);
+
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+Create table t2( a int default(99) invisible, b int, unique(invisible));
+insert into t1 values(1);
+insert into t1 values(2);
+insert into t1 values(3);
+insert into t1 values(4);
+select * from t1 order by b;
+select invisible, a, b from t1 order by b;
+set debug_dbug=@old_debug;
+
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+alter table t1 add index(invisible);
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+alter table t1 add index(b,invisible);
+show index from t1;
+drop table t1;
+## Sytem Generated index on invisible column
+set debug_dbug= "+d,test_completely_invisible,test_invisible_index";
+## index name will be invisible
+Create table t1( a int default(99) , b int,c int, index(b));
+set debug_dbug=@old_debug;
+Show index from t1;
+select * from INFORMATION_SCHEMA.STATISTICS where TABLE_SCHEMA ='test' and table_name='t1';
+show create table t1;
+insert into t1 values(1,1,1);
+insert into t1 values(2,2,2);
+insert into t1 values(3,3,3);
+insert into t1 values(4,4,4);
+set debug_dbug= "+d,test_completely_invisible,test_invisible_index";
+select invisible, a ,b from t1 order by b;
+explain select * from t1 where invisible =9;
+alter table t1 add x int default 3;
+select invisible, a ,b from t1;
+set debug_dbug=@old_debug;
+Show index from t1;
+## Sytem Generated Index modification
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+create index a1 on t1(invisible);
+set debug_dbug= "+d,test_completely_invisible,test_invisible_index";
+## index does not exist for user
+--error ER_CANT_DROP_FIELD_OR_KEY
+drop index invisible on t1;
+explain select * from t1 where invisible =9;
+## index name will be changed
+create index invisible on t1(c);
+explain select * from t1 where invisible =9;
+show indexes in t1;
+drop table t1;
+set @old_debug= @@debug_dbug;
diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test
index 611f5ab8942..b775725903c 100644
--- a/mysql-test/t/join_cache.test
+++ b/mysql-test/t/join_cache.test
@@ -3825,6 +3825,51 @@ set join_cache_level = default;
DROP TABLE t1,t2;
--echo #
+--echo # MDEV-14960: BNLH used for materialized semi-join
+--echo #
+
+CREATE TABLE t1 (i1 int);
+CREATE TABLE t2 (e1 int);
+CREATE TABLE t4 (e1 int);
+CREATE TABLE t5 (e1 int);
+
+INSERT INTO t1 VALUES
+ (1),(2),(3),(4),(5),(6),(7),(8);
+INSERT INTO t1 SELECT i1+8 FROM t1;
+INSERT INTO t1 SELECT i1+16 FROM t1;
+INSERT INTO t1 SELECT i1+32 FROM t1;
+INSERT INTO t1 SELECT i1+64 FROM t1;
+INSERT INTO t2 SELECT * FROM t1;
+INSERT INTO t4 SELECT * FROM t1;
+INSERT INTO t5 SELECT * FROM t1;
+
+set @save_optimizer_switch= @@optimizer_switch;
+SET join_cache_level = 6;
+SET join_buffer_size=4096;
+SET join_buffer_space_limit=4096;
+SET optimizer_switch = 'join_cache_hashed=on,optimize_join_buffer_size=on';
+
+let $q=
+SELECT * FROM t1
+WHERE
+ i1 < 10 AND
+ i1 IN
+ (SELECT i1 FROM
+ (SELECT (t4.e1) i1 FROM t4
+ LEFT JOIN t5 ON t4.e1 = t5.e1
+ LEFT JOIN (SELECT e1 FROM t2 ) AS d ON t4.e1 = d.e1) a);
+
+eval EXPLAIN $q;
+eval $q;
+
+SET join_cache_level = default;
+SET join_buffer_size = default;
+SET join_buffer_space_limit= default;
+set optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE t1,t4,t5,t2;
+
+--echo #
--echo # MDEV-5123 Remove duplicated conditions pushed both to join_tab->select_cond and join_tab->cache_select->cond for blocked joins.
--echo #
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index 88861511d79..acbe19b5e87 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -1962,6 +1962,20 @@ DROP FUNCTION f1;
DROP TABLE t1,t2;
+--echo #
+--echo # MDEV-10397: Server crashes in key_copy with join_cache_level > 2 and join on BIT fields
+--echo #
+
+CREATE TABLE t1 (b1 BIT NOT NULL);
+INSERT INTO t1 VALUES (0),(1);
+
+CREATE TABLE t2 (b2 BIT NOT NULL);
+INSERT INTO t2 VALUES (0),(1);
+
+SET SESSION JOIN_CACHE_LEVEL = 3;
+SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2;
+DROP TABLE t1, t2;
+
--echo # end of 5.5 tests
SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/loadxml.test b/mysql-test/t/loadxml.test
index 0bd97a81649..623deea6ec6 100644
--- a/mysql-test/t/loadxml.test
+++ b/mysql-test/t/loadxml.test
@@ -143,3 +143,22 @@ LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c1);
LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
DROP VIEW v1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14628 Wrong autoinc value assigned by LOAD XML in the NO_AUTO_VALUE_ON_ZERO mode
+--echo #
+
+SET sql_mode=NO_AUTO_VALUE_ON_ZERO;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT);
+LOAD XML INFILE '../../std_data/loaddata/mdev14628a.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+SELECT * FROM t1 ORDER BY b;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+SET sql_mode='';
+CREATE TABLE t1 (id INT, g GEOMETRY NOT NULL);
+--error ER_WARN_NULL_TO_NOTNULL
+LOAD XML INFILE '../../std_data/loaddata/mdev14628b.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+SELECT * FROM t1;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
diff --git a/mysql-test/t/mdev_14586.test b/mysql-test/t/mdev_14586.test
new file mode 100644
index 00000000000..8b3d3780151
--- /dev/null
+++ b/mysql-test/t/mdev_14586.test
@@ -0,0 +1,27 @@
+create table t1(a bit(1), b int auto_increment ,id int, index(a,b));
+insert into t1 values(1,null,1);
+insert into t1 values(1,null,2);
+insert into t1 values(0,null,3);
+insert into t1 values(0,null,4);
+select a+0, b as auto_increment , id from t1 order by id;
+drop table t1;
+create table t1(a int auto_increment, b bit(5) ,id int, index (b,a));
+insert into t1 values(null,b'1',1);
+insert into t1 values(null,b'1',2);
+insert into t1 values(null,b'11',3);
+insert into t1 values(null,b'11',4);
+select a as auto_increment, b+0, id from t1 order by id;
+drop table t1;
+create table t1(a bit(1), b int auto_increment , c bit(1) , d bit(1), id int,index(a,c,b,d));
+insert into t1 values(1,null,1,1,1);
+insert into t1 values(1,null,1,1,2);
+insert into t1 values(0,null,1,1,3);
+insert into t1 values(1,null,0,1,4);
+select a+0, b as auto_increment, c+0, d+0, id from t1 order by id;
+drop table t1;
+CREATE TABLE t1 (b BIT(1), pk INTEGER AUTO_INCREMENT PRIMARY KEY);
+ALTER TABLE t1 ADD INDEX(b,pk);
+INSERT INTO t1 VALUES (1,b'1');
+ALTER TABLE t1 DROP PRIMARY KEY;
+select b+0, pk as auto_increment from t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 99309e6a7f0..edc4a364ad9 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -1461,9 +1461,7 @@ DROP TABLE t1, m1;
# and there is incorrect merge table
#
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=FIRST;
---replace_column 8 # 9 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 17 # 19 # 20 #
-SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE
-TABLE_SCHEMA = 'test' and TABLE_NAME='tm1';
+SELECT table_schema, table_name, table_type, engine, version, row_format, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='tm1';
DROP TABLE tm1;
@@ -1559,7 +1557,7 @@ CREATE TABLE m1 (
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(t1);
insert into m1 (col1) values (1);
---error ER_DUP_ENTRY
+--error ER_DUP_KEY
insert into m1 (col1) values (1);
drop table m1, t1;
@@ -1593,7 +1591,7 @@ CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE (c1), UNIQUE (c2));
CREATE TABLE m1 (c1 INT, c2 INT, UNIQUE (c1)) ENGINE=MRG_MyISAM INSERT_METHOD=LAST UNION=(t1);
INSERT INTO m1 VALUES (1,2);
--echo # insert the duplicate value into the merge table
---error ER_DUP_ENTRY
+--error ER_DUP_KEY
INSERT INTO m1 VALUES (3,2);
DROP TABLE m1,t1;
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index 1407e9fcf98..450868721cd 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -786,13 +786,11 @@ INSERT INTO t1 VALUES
#
SELECT _id FROM t1;
DELETE FROM t1 WHERE _id < 8;
---replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
-SHOW TABLE STATUS LIKE 't1';
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
CHECK TABLE t1 EXTENDED;
OPTIMIZE TABLE t1;
CHECK TABLE t1 EXTENDED;
---replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
-SHOW TABLE STATUS LIKE 't1';
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
SELECT _id FROM t1;
DROP TABLE t1;
#
@@ -828,13 +826,11 @@ INSERT INTO t1 VALUES
#
SELECT _id FROM t1;
DELETE FROM t1 WHERE _id < 8;
---replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
-SHOW TABLE STATUS LIKE 't1';
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
CHECK TABLE t1 EXTENDED;
REPAIR TABLE t1 QUICK;
CHECK TABLE t1 EXTENDED;
---replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
-SHOW TABLE STATUS LIKE 't1';
+SELECT table_name, engine, version, row_format, Table_rows, Data_free, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
SELECT _id FROM t1;
DROP TABLE t1;
#
@@ -864,8 +860,7 @@ DROP TABLE t1;
# Bug#24607 - MyISAM pointer size determined incorrectly
#
CREATE TABLE t1 (c1 TEXT) AVG_ROW_LENGTH=70100 MAX_ROWS=4100100100;
---replace_column 5 X 6 X 7 X 9 X 10 X 11 X 12 X 13 X 14 X 16 X
-SHOW TABLE STATUS LIKE 't1';
+SELECT table_name, engine, version, row_format, max_data_length, max_index_length, create_options, table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='t1';
DROP TABLE t1;
#
@@ -1148,22 +1143,22 @@ DROP TABLE t1;
# Bug#4692 - DISABLE/ENABLE KEYS waste a space
#
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE INDEX (c1), INDEX (c2)) ENGINE=MYISAM;
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
INSERT INTO t1 VALUES (1,1);
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 DISABLE KEYS;
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 ENABLE KEYS;
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 DISABLE KEYS;
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 ENABLE KEYS;
---replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
+--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 19 #
SHOW TABLE STATUS LIKE 't1';
#--exec ls -log var/master-data/test/t1.MYI
#--exec myisamchk -dvv var/master-data/test/t1.MYI
diff --git a/mysql-test/t/myisam_optimize.test b/mysql-test/t/myisam_optimize.test
index 5f0b8fc7666..5e133aea853 100644
--- a/mysql-test/t/myisam_optimize.test
+++ b/mysql-test/t/myisam_optimize.test
@@ -46,3 +46,20 @@ connection default;
drop table t1;
set debug_sync='reset';
+--echo # End of 5.5 tests
+
+#
+# MDEV-11539 test_if_reopen: Assertion `strcmp(share->unique_file_name,filename) || share->last_version' failed upon select from I_S
+#
+CREATE TABLE t1 (i INT) ENGINE=MyISAM;
+INSERT t1 VALUES (1);
+LOCK TABLE t1 WRITE;
+OPTIMIZE TABLE t1;
+--disable_result_log
+SELECT * FROM INFORMATION_SCHEMA.TABLES;
+--enable_result_log
+SELECT * FROM t1;
+UNLOCK TABLES;
+DROP TABLE t1;
+
+--echo # End of 10.0 tests
diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test
index a19be30e68f..0171fe6c7ba 100644
--- a/mysql-test/t/mysql_upgrade.test
+++ b/mysql-test/t/mysql_upgrade.test
@@ -219,3 +219,25 @@ DROP TABLE test.t1;
SET GLOBAL enforce_storage_engine=NULL;
--echo End of 10.1 tests
+
+--echo Start of 10.3 tests
+
+--echo #
+--echo # Ensure that mysql_upgrade correctly sets truncate_versioning_priv
+--echo # on upgrade from 10.2
+--echo #
+
+flush privileges;
+CREATE USER 'user3'@'%';
+GRANT USAGE ON *.* TO 'user3'@'%';
+GRANT ALL PRIVILEGES ON `roelt`.`test2` TO 'user3'@'%';
+alter table mysql.user drop column Delete_history_priv;
+alter table mysql.db drop column Delete_history_priv;
+--source include/restart_mysqld.inc
+--echo Run mysql_upgrade with all privileges on a user
+--exec $MYSQL_UPGRADE --force --silent 2>&1
+--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
+flush privileges;
+SHOW GRANTS FOR 'user3'@'%';
+DROP USER 'user3'@'%';
+update mysql.db set Delete_history_priv='Y' where db like 'test%';
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index e5bc36f6851..6988b2a8e9b 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -589,3 +589,9 @@ eval SET GLOBAL SERVER_ID = $old_server_id;
--exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_group_id.binlog
--exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_group_id_checksum.binlog
--exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_none.binlog
+
+#
+# MDEV-12372 mysqlbinlog --version output is the same on 10.x as on 5.5.x, and contains not only version
+#
+replace_regex /.*mysqlbinlog(\.exe)? Ver .* for .* at [-_a-zA-Z0-9]+/mysqlbinlog Ver VER for OS at ARCH/;
+exec $MYSQL_BINLOG --version;
diff --git a/mysql-test/t/mysqlbinlog_row_big.test b/mysql-test/t/mysqlbinlog_row_big.test
index 44bceaad66b..229cc8a31fc 100644
--- a/mysql-test/t/mysqlbinlog_row_big.test
+++ b/mysql-test/t/mysqlbinlog_row_big.test
@@ -146,4 +146,3 @@ DROP TABLE t1;
# NOTE: If you want to see the *huge* mysqlbinlog output, disable next line:
#
--remove_file $MYSQLTEST_VARDIR/$mysqlbinlog_output
-
diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test
index 1613f8e7a4f..27d3286685b 100644
--- a/mysql-test/t/mysqld--help.test
+++ b/mysql-test/t/mysqld--help.test
@@ -19,7 +19,7 @@ exec $MYSQLD_BOOTSTRAP_CMD --symbolic-links=0 --lower-case-table-names=1 --help
perl;
# Variables which we don't want to display in the result file since
# their paths may vary:
- @skipvars=qw/basedir open-files-limit general-log-file log plugin-dir
+ @skipvars=qw/basedir open-files-limit general-log-file log plugin-dir plugin-maturity
log-slow-queries pid-file slow-query-log-file log-basename
datadir slave-load-tmpdir tmpdir socket thread-pool-size
large-files-support lower-case-file-system system-time-zone
@@ -30,7 +30,7 @@ perl;
feedback debug temp-pool ssl des-key-file xtradb sequence
thread-concurrency super-large-pages mutex-deadlock-detector
connect null-audit aria oqgraph sphinx thread-handling
- test-sql-discovery rpl-semi-sync query-cache-info
+ test-sql-discovery query-cache-info in-predicate-conversion-threshold
query-response-time metadata-lock-info locales unix-socket
wsrep file-key-management cracklib-password-check user-variables/;
diff --git a/mysql-test/t/mysqldump-nl.test b/mysql-test/t/mysqldump-nl.test
index 311996e77c3..4513fb2c637 100644
--- a/mysql-test/t/mysqldump-nl.test
+++ b/mysql-test/t/mysqldump-nl.test
@@ -36,3 +36,23 @@ show tables from `mysqltest1
drop database `mysqltest1
1tsetlqsym`;
+
+create database `test```;
+create database `test\``
+\! ls
+#`;
+
+show databases like 'test%';
+
+exec $MYSQL_DUMP --compact --comment --add-drop-database --databases 'test`' 'test\`
+\! ls
+#';
+
+exec $MYSQL_DUMP --compact --comment --add-drop-database --databases 'test`' 'test\`
+\! ls
+#' | $MYSQL;
+
+drop database `test```;
+drop database `test\``
+\! ls
+#`;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 9f74f4ad9c0..6dde5aa7bc6 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1453,7 +1453,7 @@ insert into u1 values (4);
create view v1 (c1) as select * from t1;
# Backup should not fail for Bug#21527. Flush priviliges test begins.
---exec $MYSQL_DUMP --skip-comments --add-drop-table --flush-privileges --ignore-table=mysql.general_log --ignore-table=mysql.slow_log --databases mysqldump_myDB mysql > $MYSQLTEST_VARDIR/tmp/bug21527.sql
+--exec $MYSQL_DUMP --skip-comments --add-drop-table --flush-privileges --ignore-table=mysql.general_log --ignore-table=mysql.slow_log --ignore-table=mysql.transaction_registry --databases mysqldump_myDB mysql > $MYSQLTEST_VARDIR/tmp/bug21527.sql
# Clean up
connection root;
@@ -2646,3 +2646,46 @@ CREATE TRIGGER tt1_t1 BEFORE INSERT ON t1 FOR EACH ROW
INSERT INTO t1 (a) VALUES (1),(2),(3);
--exec $MYSQL_DUMP --triggers --no-data --no-create-info --add-drop-trigger --skip-comments --databases test
DROP TABLE t1;
+--echo #
+--echo # Test for Invisible columns
+--echo #
+create database d;
+use d;
+
+--echo # Invisble field table
+create table t1(a int , b int invisible);
+insert into t1 values(1);
+insert into t1(a,b) values(1,2);
+
+--echo # not invisible field table --complete-insert wont be used
+create table t2(a int , b int);
+insert into t2(a,b) values(1,2);
+insert into t2(a,b) values(1,2);
+
+--echo # Invisble field table
+create table t3(invisible int , `a b c & $!@#$%^&*( )` int invisible default 4, `ds=~!@ \# $% ^ & * ( ) _ - = +` int invisible default 5);
+insert into t3 values(1);
+insert into t3 values(5);
+insert into t3 values(2);
+insert into t3(`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +` ) values(1,2,3);
+CREATE TABLE t4(ËÃÃŒÃÎËÃ1 INT);
+insert into t4 values(1);
+--exec $MYSQL_DUMP --compact d
+
+--echo #Check side effect on --complete insert
+--exec $MYSQL_DUMP --compact --complete-insert d
+--echo #Check xml
+--exec $MYSQL_DUMP --skip-create-options --skip-comments -X d
+
+#import data
+--exec $MYSQL_DUMP --skip-comments d > $MYSQLTEST_VARDIR/tmp/invisible_dump.sql
+DROP table t1,t2,t3;
+
+--exec $MYSQL d < $MYSQLTEST_VARDIR/tmp/invisible_dump.sql
+
+select * from t1;
+select a,b from t1;
+select * from t2;
+select * from t3;
+desc t3;
+drop database d;
diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test
index 35bb7aca085..a3db700f787 100644
--- a/mysql-test/t/openssl_1.test
+++ b/mysql-test/t/openssl_1.test
@@ -260,8 +260,9 @@ set global sql_mode=default;
# MDEV-9605 mysqlbinlog does not accept ssl-ca option as expected.
#
+--replace_regex /SSL connection error:.*/SSL connection error/
--error 1
---exec $MYSQL_BINLOG --read-from-remote-server --ssl-ca --user=root --host=localhost nobinlog.111111
+--exec $MYSQL_BINLOG --read-from-remote-server --ssl-ca --user=root --host=localhost nobinlog.111111 2>&1
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/opt_tvc.test b/mysql-test/t/opt_tvc.test
index 2e00308aa78..d5c9a5cbd3d 100644
--- a/mysql-test/t/opt_tvc.test
+++ b/mysql-test/t/opt_tvc.test
@@ -1,3 +1,8 @@
+#
+# MDEV-12176 Transform [NOT] IN predicate with long list of values INTO [NOT] IN subquery
+#
+source include/have_debug.inc;
+
create table t1 (a int, b int);
insert into t1
@@ -28,7 +33,7 @@ eval explain extended $query;
--echo # set minimum number of values in VALUEs list when optimization works to 2
-set @@in_subquery_conversion_threshold= 2;
+set @@in_predicate_conversion_threshold= 2;
--echo # single IN-predicate in WHERE-part
@@ -251,27 +256,27 @@ deallocate prepare stmt;
--echo # use inside out access from tvc rows
let $query= select * from t3 where a in (1,4,10);
-set @@in_subquery_conversion_threshold= default;
+set @@in_predicate_conversion_threshold= default;
eval $query;
eval explain extended $query;
-set @@in_subquery_conversion_threshold= 2;
+set @@in_predicate_conversion_threshold= 2;
eval $query;
eval explain extended $query;
--echo # use vectors in IN predeicate
-set @@in_subquery_conversion_threshold= 4;
+set @@in_predicate_conversion_threshold= 4;
let $query=
select * from t1 where (a,b) in ((1,2),(3,4));
eval $query;
eval explain extended $query;
-set @@in_subquery_conversion_threshold= 2;
+set @@in_predicate_conversion_threshold= 2;
--echo # trasformation works for the one IN predicate and doesn't work for the other
-set @@in_subquery_conversion_threshold= 5;
+set @@in_predicate_conversion_threshold= 5;
let $query=
select * from t2
@@ -280,7 +285,7 @@ where (a,b) in ((1,2),(8,9)) and
eval $query;
eval explain extended $query;
-set @@in_subquery_conversion_threshold= 2;
+set @@in_predicate_conversion_threshold= 2;
--echo #
--echo # mdev-14281: conversion of NOT IN predicate into subquery predicate
@@ -312,4 +317,46 @@ eval explain extended $query;
drop table t1, t2, t3;
-set @@in_subquery_conversion_threshold= default;
+set @@in_predicate_conversion_threshold= default;
+
+--echo #
+--echo # MDEV-14947: conversion of TVC with only NULL values
+--echo #
+
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (3), (2), (7);
+
+let $q=
+SELECT * FROM t1 WHERE i IN (NULL, NULL, NULL, NULL, NULL);
+
+eval $q;
+eval EXPLAIN EXTENDED $q;
+
+SET in_predicate_conversion_threshold= 5;
+
+eval $q;
+eval EXPLAIN EXTENDED $q;
+
+SET in_predicate_conversion_threshold= default;
+
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14835: conversion of TVC with BIGINT or YEAR values
+--echo #
+
+SET @@in_predicate_conversion_threshold= 2;
+
+CREATE TABLE t1 (a BIGINT);
+CREATE TABLE t2 (y YEAR);
+
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (2009), (2010), (2011);
+
+SELECT * FROM t1 WHERE a IN ('1','5','3');
+
+SELECT * FROM t2 WHERE y IN ('2009','2011');
+
+DROP TABLE t1,t2;
+
+SET @@in_predicate_conversion_threshold= default;
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 8722401ccae..b047a31c863 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -1958,6 +1958,44 @@ UNION
ORDER BY NULL, @a0 := 3, @a1 := 3, @a2 := 3, @a3 := 3, @a4 := 3,
@a5 := 3, @a6 := 3, @a7 := 3, @a8 := 3, @a9 := 3, @a10 := 3 );
+
+--echo #
+--echo # mdev-6706: semi-join with duplicate weedout + ORDER BY
+--echo #
+
+CREATE TABLE t1 (f1 VARCHAR(3)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('foo');
+
+CREATE TABLE t2 (f2 VARCHAR(3)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('bar'),('baz');
+
+CREATE TABLE t3
+(i3_key INT, f3_key VARCHAR(3), f3 VARCHAR(3), KEY(f3_key,i3_key))
+ ENGINE=MyISAM;
+INSERT INTO t3 VALUES (0,'qux','qux'),(8,'bar','bar');
+
+let $q1=
+SELECT CONCAT( f1, f2 ) AS field FROM t1, t2
+WHERE f1 = ANY ( SELECT f1
+ FROM t1
+ LEFT JOIN ( t3 AS t3a, t3 AS t3b )
+ ON ( t3b.f3_key = t3a.f3 )
+ WHERE t3a.f3 < f1 OR t3b.f3 != f1 );
+let $q2=
+SELECT CONCAT( f1, f2 ) AS field FROM t1, t2
+WHERE f1 = ANY ( SELECT f1
+ FROM t1
+ LEFT JOIN ( t3 AS t3a, t3 AS t3b )
+ ON ( t3b.f3_key = t3a.f3 )
+ WHERE t3a.f3 < f1 OR t3b.f3 != f1 )
+ORDER BY field;
+
+eval $q1;
+eval $q2;
+eval EXPLAIN EXTENDED $q2;
+
+DROP TABLE t1,t2,t3;
+
--echo End of 5.5 tests
--echo #
@@ -2106,3 +2144,46 @@ INSERT INTO t1 VALUES (1),(2),(3);
SELECT DISTINCT pk FROM t1 GROUP BY 'foo';
SELECT DISTINCT pk FROM t1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-13994: Bad join results with orderby_uses_equalities=on
+--echo #
+
+CREATE TABLE books (
+ id int(16) NOT NULL AUTO_INCREMENT,
+ library_id int(16) NOT NULL DEFAULT 0,
+ wings_id int(12) NOT NULL DEFAULT 0,
+ scheduled_for_removal int(1) DEFAULT 0,
+ PRIMARY KEY (id),
+ KEY library_idx (library_id)
+) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+
+INSERT INTO books VALUES (32625,8663,707,0),(32624,8663,505,1);
+
+CREATE TABLE wings (
+ id int(11) NOT NULL AUTO_INCREMENT,
+ department_id int(11) DEFAULT NULL,
+ PRIMARY KEY (id)
+) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+
+INSERT INTO wings VALUES (505,11745),(707,11768);
+
+let $q=
+SELECT wings.id as wing_id, wings.department_id FROM wings
+ WHERE wings.id IN ( SELECT books.wings_id FROM books
+ WHERE books.library_id = 8663 AND
+ books.scheduled_for_removal=0 )
+ORDER BY wings.id;
+
+SET @save_optimizer_switch=@@optimizer_switch;
+
+SET optimizer_switch='orderby_uses_equalities=off';
+eval $q;
+
+SET optimizer_switch='orderby_uses_equalities=on';
+eval $q;
+eval explain extended $q;
+
+set optimizer_switch= @save_optimizer_switch;
+
+DROP TABLE books, wings;
diff --git a/mysql-test/t/order_by_innodb.test b/mysql-test/t/order_by_innodb.test
index 097eddd24f1..0debb777749 100644
--- a/mysql-test/t/order_by_innodb.test
+++ b/mysql-test/t/order_by_innodb.test
@@ -61,3 +61,50 @@ from t1
where key1<3 or key2<3;
drop table t0, t1;
+
+--echo #
+--echo # MDEV-14071: wrong results with orderby_uses_equalities=on
+--echo # (duplicate of MDEV-13994)
+--echo #
+
+CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB;
+CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB;
+CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES
+ (127,0,1),(188,0,1),(206,0,1),(218,0,1),(292,0,1),(338,0,1),(375,0,1),
+ (381,0,1),(409,0,1),(466,0,1),(469,0,1),(498,0,1),(656,0,1);
+INSERT INTO t1 VALUES
+ (77,4,0),(86,7,0),(96,6,0),(96,7,0),(99,9,0),(99,10,0),(99,11,0),(104,4,0),
+ (106,5,0),(148,6,0),(177,6,0),(181,5,0),(188,8,0),(218,8,0),(253,7,0),
+ (268,4,0),(338,4,0),(409,7,0),(466,8,0),(469,8,0),(498,8,0),(656,8,0);
+
+INSERT INTO t2 VALUES
+ (127,7),(188,8),(188,9),(206,6),(218,8),(218,9),(292,7),(338,4),(338,5),
+ (375,6),(381,5),(409,7),(409,8),(466,8),(466,9),(469,8),(469,9),(498,8),
+ (498,9),(656,8),(656,9);
+INSERT INTO t3 VALUES
+ (4,'four'),(5,'five'),(6,'six'),(7,'seven'),(8,'eight'),(9,'nine');
+
+let $q1=
+SELECT i,n
+FROM t1 INNER JOIN t2 USING (i,j) LEFT JOIN t3 USING (j)
+WHERE i IN (SELECT i FROM t1 WHERE z=1) AND z=0 ORDER BY i;
+let $q2=
+SELECT i,n
+FROM t1 x INNER JOIN t2 USING (i,j) LEFT JOIN t3 USING (j)
+WHERE EXISTS (SELECT * FROM t1 WHERE i=x.i AND z=1) AND z=0 ORDER BY i;
+
+SET @save_optimizer_switch=@@optimizer_switch;
+
+SET optimizer_switch='orderby_uses_equalities=off';
+eval $q1;
+eval $q2;
+
+SET optimizer_switch='orderby_uses_equalities=on';
+eval $q1;
+eval $q2;
+
+set optimizer_switch= @save_optimizer_switch;
+
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index 608c8812e01..7b7d1457426 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -445,6 +445,7 @@ INSERT INTO t1 VALUES (1,1,0), (1,1,1), (1,1,2), (1,1,53), (1,1,4), (1,1,5),
(1,19,1);
SELECT COUNT(*) FROM t1 WHERE b NOT IN ( 1,2,6,7,9,10,11 );
SELECT SUM(c) FROM t1 WHERE b NOT IN ( 1,2,6,7,9,10,11 );
+SELECT SUM(c+0.0) FROM t1 WHERE b NOT IN ( 1,2,6,7,9,10,11 );
ALTER TABLE t1 DROP INDEX b;
SELECT COUNT(*) FROM t1 WHERE b NOT IN ( 1,2,6,7,9,10,11 );
SELECT SUM(c) FROM t1 WHERE b NOT IN ( 1,2,6,7,9,10,11 );
@@ -2812,6 +2813,7 @@ INSERT INTO t1 VALUES (123,123,'2001-04-14','address123','city123',40,51),
(257,257,'2010-03-06','address257','city257',40,47);
--enable_query_log
+--sorted_result
select * from t1 where hours_worked_per_week = 40 and weeks_worked_last_year = 52 and dob < '1949-11-21';
select * from t1 IGNORE INDEX(dob, weeks_worked_last_year, hours_worked_per_week) where hours_worked_per_week = 40 and weeks_worked_last_year = 52 and dob < '1949-11-21';
@@ -2885,8 +2887,21 @@ alter table t1 drop partition if exists p5;
DROP TABLE t1;
+#
+# MDEV-14696 Server crashes in in prep_alter_part_table on 2nd execution of PS.
+#
+
+CREATE TABLE t1 (a INT) ENGINE=MyISAM PARTITION BY RANGE(a) (PARTITION p1 VALUES LESS THAN (0));
+ALTER TABLE t1 ADD PARTITION (PARTITION p2 VALUES LESS THAN (1));
+PREPARE stmt FROM 'ALTER TABLE t1 ADD PARTITION IF NOT EXISTS (PARTITION p2 VALUES LESS THAN (2))';
+EXECUTE stmt;
+EXECUTE stmt;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
--echo #
---echo # Start of 10.1 tests
+--echo # End of 10.0 tests
--echo #
--echo #
diff --git a/mysql-test/t/partition_alter.test b/mysql-test/t/partition_alter.test
index ce6672c4b9d..62a3e1c0777 100644
--- a/mysql-test/t/partition_alter.test
+++ b/mysql-test/t/partition_alter.test
@@ -114,3 +114,14 @@ insert into t1 values(0, 1, 1, NULL, now(), now());
alter online table t1 delay_key_write=1;
show create table t1;
drop table t1;
+
+#
+# MDEV-14817 Server crashes in prep_alter_part_table() after table lock and multiple add partition
+#
+create or replace table t1 (x int) partition by hash (x) (partition p1, partition p2);
+lock table t1 write;
+--error ER_SAME_NAME_PARTITION
+alter table t1 add partition (partition p1);
+--error ER_SAME_NAME_PARTITION
+alter table t1 add partition (partition p1);
+drop table t1;
diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test
index 300121e88fd..7b5a69fe622 100644
--- a/mysql-test/t/partition_innodb.test
+++ b/mysql-test/t/partition_innodb.test
@@ -991,3 +991,31 @@ SELECT b FROM t1 WHERE b = 0;
SELECT b FROM t1 WHERE b = 0;
--disconnect con1
DROP TABLE t1;
+
+--echo #
+--echo # Bug#26390658 RENAMING A PARTITIONED TABLE DOES NOT UPDATE
+--echo # MYSQL.INNODB_TABLE_STATS
+--echo #
+
+CREATE DATABASE test_jfg;
+
+CREATE TABLE test_jfg.test_jfg1 (id int(10) unsigned NOT NULL,PRIMARY
+KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=1;
+CREATE TABLE test_jfg.test_jfg2 (id int(10) unsigned NOT NULL,PRIMARY
+KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=1
+PARTITION BY RANGE ( id ) (PARTITION p1000 VALUES LESS THAN (1000)
+ENGINE = InnoDB,PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE =
+InnoDB);
+
+--replace_result #p# #P#
+SELECT database_name, table_name FROM mysql.innodb_table_stats WHERE
+database_name = 'test_jfg';
+
+RENAME TABLE test_jfg.test_jfg1 TO test_jfg.test_jfg11;
+RENAME TABLE test_jfg.test_jfg2 TO test_jfg.test_jfg12;
+
+--replace_result #p# #P#
+SELECT database_name, table_name FROM mysql.innodb_table_stats WHERE
+database_name = 'test_jfg';
+
+DROP DATABASE test_jfg;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index ec55b9c9d21..a2f7d3c7bdc 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -3857,6 +3857,21 @@ deallocate prepare stmt;
drop view v1,v2,v3;
drop table t1,t2,t3;
+--echo #
+--echo # MDEV-10657: incorrect result returned with binary protocol
+--echo # (prepared statements)
+--echo #
+
+create table t1 (code varchar(10) primary key);
+INSERT INTO t1(code) VALUES ('LINE1'), ('LINE2'), ('LINE3');
+SELECT X.*
+FROM
+ (SELECT CODE, RN
+ FROM
+ (SELECT A.CODE, @cnt := @cnt + 1 AS RN
+ FROM t1 A, (SELECT @cnt := 0) C) T
+ ) X;
+drop table t1;
--echo # End of 5.5 tests
--echo #
@@ -4476,3 +4491,184 @@ EXECUTE IMMEDIATE 'CALL p1(?)' USING DEFAULT;
--error ER_SP_NOT_VAR_ARG
EXECUTE IMMEDIATE 'CALL p1(?)' USING IGNORE;
DROP PROCEDURE p1;
+
+
+--echo #
+--echo # MDEV-14434 Wrong result for CHARSET(CONCAT(?,const))
+--echo #
+
+SET NAMES utf8;
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(5,_latin1'a'))";
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(?,_latin1'a'))" USING 5;
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(?,_latin1'a'))" USING 5.5;
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(?,_latin1'a'))" USING 5.5e0;
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(?,_latin1'a'))" USING TIME'10:20:30';
+EXECUTE IMMEDIATE "SELECT CHARSET(CONCAT(?,_latin1'a'))" USING TIMESTAMP'2001-01-01 10:20:30';
+
+EXECUTE IMMEDIATE "SELECT COERCIBILITY(?)" USING 5;
+EXECUTE IMMEDIATE "SELECT COERCIBILITY(?)" USING 5.5;
+EXECUTE IMMEDIATE "SELECT COERCIBILITY(?)" USING 5.5e0;
+EXECUTE IMMEDIATE "SELECT COERCIBILITY(?)" USING TIME'10:20:30';
+EXECUTE IMMEDIATE "SELECT COERCIBILITY(?)" USING TIMESTAMP'2001-01-01 10:20:30';
+
+--echo #
+--echo # MDEV-14435 Different UNSIGNED flag of out user variable for YEAR parameter for direct vs prepared CALL
+--echo #
+
+CREATE PROCEDURE p1(OUT v INT UNSIGNED) SET v = 2010;
+CALL p1(@a);
+PREPARE stmt FROM 'CALL p1(?)';
+EXECUTE stmt USING @b;
+DEALLOCATE PREPARE stmt;
+CREATE TABLE t1 AS SELECT @a AS a, @b AS b;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+DROP PROCEDURE p1;
+
+CREATE PROCEDURE p1(OUT v YEAR) SET v = 2010;
+CALL p1(@a);
+PREPARE stmt FROM 'CALL p1(?)';
+EXECUTE stmt USING @b;
+DEALLOCATE PREPARE stmt;
+CREATE TABLE t1 AS SELECT @a AS a, @b AS b;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+DROP PROCEDURE p1;
+
+CREATE PROCEDURE p1(OUT v BIT(16)) SET v = 2010;
+CALL p1(@a);
+PREPARE stmt FROM 'CALL p1(?)';
+EXECUTE stmt USING @b;
+DEALLOCATE PREPARE stmt;
+CREATE TABLE t1 AS SELECT @a AS a, @b AS b;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+DROP PROCEDURE p1;
+
+--echo #
+--echo # MDEV-14426 Assertion in Diagnostics_area::set_error_status when using a bad datetime with PS and SP
+--echo #
+
+DELIMITER $$;
+CREATE PROCEDURE p1(OUT a VARCHAR(20))
+BEGIN
+ SET a=10;
+END;
+$$
+--error ER_TRUNCATED_WRONG_VALUE
+BEGIN NOT ATOMIC
+ DECLARE a DATETIME;
+ CALL p1(a);
+END;
+$$
+--error ER_TRUNCATED_WRONG_VALUE
+BEGIN NOT ATOMIC
+ DECLARE a DATETIME;
+ EXECUTE IMMEDIATE 'CALL p1(?)' USING a;
+END;
+$$
+--error ER_TRUNCATED_WRONG_VALUE
+BEGIN NOT ATOMIC
+ DECLARE a DATETIME;
+ PREPARE stmt FROM 'CALL p1(?)';
+ EXECUTE stmt USING a;
+ DEALLOCATE PREPARE stmt;
+END;
+$$
+DELIMITER ;$$
+DROP PROCEDURE p1;
+
+--echo #
+--echo # MDEV-14454 Binary protocol returns wrong collation ID for SP OUT parameters
+--echo #
+
+CREATE PROCEDURE p1(OUT v CHAR(32) CHARACTER SET utf8) SET v='aaa';
+PREPARE stmt1 FROM 'CALL p1(?)';
+EXECUTE stmt1 USING @a;
+CREATE TABLE t1 AS SELECT @a AS c1;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+DROP PROCEDURE p1;
+
+--echo #
+--echo # MDEV-14467 Item_param: replace {INT|DECIMAL|REAL|STRING|TIME}_VALUE with Type_handler
+--echo #
+
+EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT 1 FROM DUAL LIMIT ?' USING 10;
+EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT 1 FROM DUAL LIMIT ?' USING 10.1;
+EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT 1 FROM DUAL LIMIT ?' USING 10.1e0;
+EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT 1 FROM DUAL LIMIT ?' USING '10';
+EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT 1 FROM DUAL LIMIT ?' USING TIME'10:10:10';
+
+EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 AS SELECT 1 AS a,? AS b' USING 1;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 AS SELECT 10 AS a,? AS b' USING 10;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 AS SELECT 999999999 AS a,? AS b' USING 999999999;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 AS SELECT 2147483647 AS a,? AS b' USING 2147483647;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14603 signal 11 with short stacktrace
+--echo #
+
+SET NAMES utf8;
+CREATE TABLE t1(i INT);
+CREATE PROCEDURE p1(tn VARCHAR(32))
+ EXECUTE IMMEDIATE CONCAT('ANALYZE TABLE ',tn);
+CALL p1('t1');
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+SET NAMES utf8;
+CREATE PROCEDURE p1()
+ EXECUTE IMMEDIATE CONCAT('SELECT ',CONVERT(RAND() USING latin1));
+--disable_result_log
+CALL p1();
+--enable_result_log
+DROP PROCEDURE p1;
+
+SET NAMES utf8;
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ PREPARE stmt FROM CONCAT('SELECT ',CONVERT(RAND() USING latin1));
+ EXECUTE stmt;
+ DEALLOCATE PREPARE stmt;
+END;
+$$
+DELIMITER ;$$
+--disable_result_log
+CALL p1();
+--enable_result_log
+DROP PROCEDURE p1;
+
+SET NAMES utf8;
+CREATE PROCEDURE p1(a VARCHAR(10) CHARACTER SET utf8)
+ EXECUTE IMMEDIATE 'SELECT ?' USING CONCAT(a, CONVERT(RAND() USING latin1));
+--disable_result_log
+CALL p1('x');
+--enable_result_log
+DROP PROCEDURE p1;
+
+SET NAMES utf8;
+DELIMITER $$;
+CREATE PROCEDURE p1(a VARCHAR(10) CHARACTER SET utf8)
+BEGIN
+ PREPARE stmt FROM 'SELECT ?';
+ EXECUTE stmt USING CONCAT(a, CONVERT(RAND() USING latin1));
+ DEALLOCATE PREPARE stmt;
+END;
+$$
+DELIMITER ;$$
+--disable_result_log
+CALL p1('x');
+DROP PROCEDURE p1;
diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test
index 9dfab0f07ba..01a0164722d 100644
--- a/mysql-test/t/ps_1general.test
+++ b/mysql-test/t/ps_1general.test
@@ -306,13 +306,13 @@ prepare stmt4 from ' show index from t2 from test ';
execute stmt4;
prepare stmt4 from ' show table status from test like ''t2%'' ';
# egalize date and time values
---replace_column 8 # 12 # 13 # 14 #
+--replace_column 8 # 12 # 13 # 14 # 19 #
# Bug#4288 : prepared statement 'show table status ..', wrong output on execute
execute stmt4;
# try the same with the big table
prepare stmt4 from ' show table status from test like ''t9%'' ';
# egalize date and time values
---replace_column 8 # 12 # 13 # 14 #
+--replace_column 8 # 12 # 13 # 14 # 19 #
# Bug#4288
execute stmt4;
prepare stmt4 from ' show status like ''Threads_running'' ';
diff --git a/mysql-test/t/query_cache_debug.test b/mysql-test/t/query_cache_debug.test
index 31f2d786efb..22ff1d45e63 100644
--- a/mysql-test/t/query_cache_debug.test
+++ b/mysql-test/t/query_cache_debug.test
@@ -299,3 +299,55 @@ RESET QUERY CACHE;
DROP TABLE t1;
SET GLOBAL query_cache_size= DEFAULT;
SET GLOBAL query_cache_type= DEFAULT;
+
+--echo #
+--echo # MDEV-14526: MariaDB keeps crashing under load when
+--echo # query_cache_type is changed
+--echo #
+
+CREATE TABLE t1 (
+ `id` int(10) NOT NULL AUTO_INCREMENT,
+ `k` int(10) default '0',
+ PRIMARY KEY (`id`))
+ENGINE=MyISAM;
+
+INSERT IGNORE INTO t1 VALUES
+ (NULL,1),(NULL,8),(NULL,NULL),(NULL,NULL),(NULL,4),(NULL,9),(NULL,7),
+ (NULL,3),(NULL,NULL),(NULL,2),(NULL,3),(NULL,NULL),(NULL,2),(NULL,7),
+ (NULL,1),(NULL,2),(NULL,4),(NULL,NULL),(NULL,1),(NULL,1),(NULL,4);
+
+SET GLOBAL query_cache_size= 1024*1024;
+SET GLOBAL query_cache_type= 1;
+
+--connect (con2,localhost,root,,test)
+--connect (con1,localhost,root,,test)
+set debug_sync="wait_in_query_cache_store_query SIGNAL parked WAIT_FOR go";
+--send
+
+ SELECT DISTINCT id FROM t1 WHERE id BETWEEN 5603 AND 16218 ORDER BY k;
+
+--connection default
+
+set debug_sync="now WAIT_FOR parked";
+--connection con2
+--send
+ SET GLOBAL query_cache_type= 0;
+
+--connection default
+set debug_sync="now SIGNAL go";
+
+--connection con1
+--reap
+--connection con2
+--reap
+
+# Cleanup
+--disconnect con1
+--disconnect con2
+--connection default
+set debug_sync= 'RESET';
+DROP TABLE t1;
+SEt GLOBAL query_cache_size= DEFAULT;
+SEt GLOBAL query_cache_type= DEFAULT;
+
+--echo # End of 5.5 tests
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index ca6ac61d27a..36e0e32b28b 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -3,12 +3,6 @@
#
--source include/have_innodb.inc
-set in_subquery_conversion_threshold=10000;
-
---disable_warnings
-drop table if exists t1, t2, t3, t10, t100;
---enable_warnings
-
CREATE TABLE t1 (
event_date date DEFAULT '0000-00-00' NOT NULL,
type int(11) DEFAULT '0' NOT NULL,
@@ -2050,5 +2044,3 @@ drop table t1,t2,t3;
--echo #
--echo # End of 10.2 tests
--echo #
-
-set in_subquery_conversion_threshold=default;
diff --git a/mysql-test/t/repair.test b/mysql-test/t/repair.test
index a6df0dc5979..5494e370133 100644
--- a/mysql-test/t/repair.test
+++ b/mysql-test/t/repair.test
@@ -115,7 +115,7 @@ SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
DROP TABLE t1;
---echo End of 4.1 tests
+--echo # End of 4.1 tests
#
# BUG#36055 - mysql_upgrade doesn't really 'upgrade' tables
@@ -147,7 +147,8 @@ REPAIR TABLE t1 USE_FRM;
SELECT * FROM t1;
DROP TABLE t1;
-# End of 5.0 tests
+
+--echo # End of 5.0 tests
#
# Bug#18775 - Temporary table from alter table visible to other threads
@@ -219,3 +220,21 @@ create view v1 as select * from t1;
repair view v1;
drop view v1;
drop table t1;
+
+--echo # End of 5.5 tests
+
+#
+# MDEV-11539 test_if_reopen: Assertion `strcmp(share->unique_file_name,filename) || share->last_version' failed upon select from I_S
+#
+CREATE TABLE t1 (i INT) ENGINE=MyISAM;
+INSERT t1 VALUES (1);
+LOCK TABLE t1 WRITE;
+REPAIR TABLE t1;
+--disable_result_log
+SELECT * FROM INFORMATION_SCHEMA.TABLES;
+--enable_result_log
+SELECT * FROM t1;
+UNLOCK TABLES;
+DROP TABLE t1;
+
+--echo # End of 10.0 tests
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index e8d5f9fa445..52ef4aa2111 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -2229,7 +2229,7 @@ drop table t1,t2;
create table t1 (f1 int not null auto_increment primary key, f2 varchar(10));
create table t11 like t1;
insert into t1 values(1,""),(2,"");
---replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X
+--replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X 19 X
show table status like 't1%';
select 123 as a from t1 where f1 is null;
drop table t1,t11;
diff --git a/mysql-test/t/show_bad_definer-5553.test b/mysql-test/t/show_bad_definer-5553.test
index c5b6f1b3d10..7c7f253ae7d 100644
--- a/mysql-test/t/show_bad_definer-5553.test
+++ b/mysql-test/t/show_bad_definer-5553.test
@@ -7,6 +7,6 @@ create database mysqltest1; # all-open privileges on test db desroy the test
use mysqltest1;
create table t1(id int primary key);
create definer=unknownuser@'%' sql security definer view v1 as select t1.id from t1 group by t1.id;
---replace_column 8 # 12 # 13 #
+--replace_column 8 # 12 # 13 # 19 #
show table status;
drop database mysqltest1;
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index d84226460f2..a24fa632ea5 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -890,62 +890,62 @@ DROP FUNCTION f1;
# Part 2: check that table with non-latin1 characters are dumped/restored
# correctly.
#
-
+# See MDEV-14651 for details
# Ensure that all needed objects are dropped.
-set names koi8r;
+#set names koi8r;
---disable_warnings
-DROP DATABASE IF EXISTS mysqltest1;
---enable_warnings
+#--disable_warnings
+#DROP DATABASE IF EXISTS mysqltest1;
+#--enable_warnings
# Create objects.
-CREATE DATABASE mysqltest1;
+#CREATE DATABASE mysqltest1;
-use mysqltest1;
+#use mysqltest1;
-CREATE TABLE t1(ËÏÌÏÎËÁ1 INT);
+#CREATE TABLE t1(ËÏÌÏÎËÁ1 INT);
# Check:
# - Dump mysqltest1;
---let $outfile1=$MYSQLTEST_VARDIR/tmp/show_check.mysqltest1.sql
+#--let $outfile1=$MYSQLTEST_VARDIR/tmp/show_check.mysqltest1.sql
---source include/count_sessions.inc
---echo
---echo ---> Dumping mysqltest1 to outfile1
---exec $MYSQL_DUMP --default-character-set=latin1 --character-sets-dir=$MYSQL_SHAREDIR/charsets --databases mysqltest1 > $outfile1
+#--source include/count_sessions.inc
+#--echo
+#--echo ---> Dumping mysqltest1 to outfile1
+#--exec $MYSQL_DUMP --default-character-set=latin1 --character-sets-dir=$MYSQL_SHAREDIR/charsets --databases mysqltest1 > $outfile1
# Take care that the additional session caused by MYSQL_DUMP has disappeared.
---source include/wait_until_count_sessions.inc
+#--source include/wait_until_count_sessions.inc
# - Clean mysqltest1;
---echo
---echo
+#--echo
+#--echo
-DROP DATABASE mysqltest1;
+#DROP DATABASE mysqltest1;
# - Restore mysqltest1;
---echo
---echo
+#--echo
+#--echo
---source include/count_sessions.inc
---echo ---> Restoring mysqltest1...
---exec $MYSQL test < $outfile1
---remove_file $outfile1
+#--source include/count_sessions.inc
+#--echo ---> Restoring mysqltest1...
+#--exec $MYSQL test < $outfile1
+#--remove_file $outfile1
# Take care that the additional session caused by MYSQL has disappeared.
---source include/wait_until_count_sessions.inc
+#--source include/wait_until_count_sessions.inc
# - Check definition of the table.
-SHOW CREATE TABLE mysqltest1.t1;
+#SHOW CREATE TABLE mysqltest1.t1;
# Cleanup.
-DROP DATABASE mysqltest1;
-use test;
+#DROP DATABASE mysqltest1;
+#use test;
#
# Bug#28808 log_queries_not_using_indexes variable dynamic change is ignored
diff --git a/mysql-test/t/simultaneous_assignment.test b/mysql-test/t/simultaneous_assignment.test
new file mode 100644
index 00000000000..a21e33346d6
--- /dev/null
+++ b/mysql-test/t/simultaneous_assignment.test
@@ -0,0 +1,204 @@
+-- source include/have_innodb.inc
+SET sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,SIMULTANEOUS_ASSIGNMENT';
+
+--echo #
+--echo # MDEV-13417 UPDATE produces wrong values if an UPDATEd column is later used as an UPDATE source
+--echo #
+
+CREATE TABLE t1 (c1 INTEGER, c2 INTEGER, c3 INTEGER) ENGINE=InnoDb;
+INSERT INTO t1(c1,c2,c3) VALUES (1,1,1);
+CREATE TABLE t2 (c1 INTEGER, c2 INTEGER, c3 INTEGER) ENGINE=InnoDb;
+INSERT INTO t2(c1,c2,c3) VALUES (1,1,1);
+
+--echo #
+--echo # Check that a column is only updated once.
+--echo #
+
+--error ER_UPDATED_COLUMN_ONLY_ONCE
+UPDATE t1
+ SET c1 = 1,
+ c1 = 2;
+
+--error ER_UPDATED_COLUMN_ONLY_ONCE
+UPDATE t1, t2
+ SET t1.c1 = t1.c1 + 1,
+ t1.c2 = t1.c1 + 1,
+ t2.c2 = t1.c2 + 1,
+ t2.c2 = t1.c2 + 1;
+
+--echo #
+--echo # Check standard update
+--echo #
+
+UPDATE t1
+ SET c1 = c1+1,
+ c2 = c1+1,
+ c3 = c2+1
+ WHERE c1=10;
+
+START TRANSACTION;
+UPDATE t1
+ SET c1 = c1+1,
+ c2 = c1+1,
+ c3 = c2+1;
+SELECT * FROM t1;
+ROLLBACK;
+
+--echo #
+--echo # Check update through a single view
+--echo #
+
+CREATE VIEW v1 (a, b) AS SELECT c1, c2 FROM t1;
+--error ER_UPDATED_COLUMN_ONLY_ONCE
+UPDATE v1
+ SET a = 10,
+ a = b+1;
+SELECT * FROM t1;
+DROP VIEW v1;
+
+CREATE VIEW v1 (a, b) AS SELECT c2, c2 FROM t1;
+--error ER_UPDATED_COLUMN_ONLY_ONCE
+UPDATE v1
+ SET a = 10,
+ b = 20;
+SELECT * FROM t1;
+DROP VIEW v1;
+
+--echo #
+--echo # Check update through a multi table view
+--echo #
+
+CREATE VIEW v1 (a, b) AS SELECT t1.c1, t2.c1 FROM t1, t2 WHERE t1.c1=t2.c1;
+--error ER_VIEW_MULTIUPDATE
+UPDATE v1
+ SET a = 10,
+ b = 20;
+
+START TRANSACTION;
+UPDATE v1
+ SET a = 10;
+ROLLBACK;
+
+--error ER_UPDATED_COLUMN_ONLY_ONCE
+UPDATE v1
+ SET a = 10,
+ a = a + 1;
+DROP VIEW v1;
+
+--echo #
+--echo # Check multi update
+--echo #
+
+START TRANSACTION;
+UPDATE t1, t2
+ SET t1.c1 = t1.c1 + 1,
+ t1.c2 = t1.c1 + 1,
+ t2.c2 = t1.c2 + 1,
+ t2.c3 = t2.c2 + 1
+WHERE t1.c1=t2.c1;
+SELECT * FROM t1;
+SELECT * FROM t2;
+ROLLBACK;
+
+DELIMITER /;
+CREATE TRIGGER tr1 BEFORE UPDATE ON t1 FOR EACH ROW
+BEGIN
+ INSERT INTO t2 VALUES(10+old.c1,10+old.c2,10+old.c3);
+ INSERT INTO t2 VALUES(20+new.c1,10+new.c2,10+new.c3);
+END;
+/
+DELIMITER ;/
+START TRANSACTION;
+UPDATE t1
+ SET c1 = c1+1,
+ c2 = c1+1,
+ c3 = c2+1;
+SELECT * FROM t1;
+SELECT * FROM t2;
+ROLLBACK;
+
+DROP TABLE t1;
+DROP TABLE t2;
+
+--echo #
+--echo # Check update fired by INSERT ... ON DUPLICATE KEY UPDATE
+--echo #
+
+CREATE TABLE t1 (
+ id INT(11) NOT NULL AUTO_INCREMENT,
+ name VARCHAR(60) NOT NULL,
+ nb_visits INT NOT NULL,
+ nb_visits_prev INT NOT NULL default 0,
+ PRIMARY KEY (id),
+ UNIQUE KEY name (name)
+) ENGINE=InnoDB AUTO_INCREMENT=1;
+
+INSERT INTO t1(name, nb_visits) VALUES('nico', 1)
+ ON DUPLICATE KEY UPDATE nb_visits = nb_visits + 1;
+SELECT * FROM t1;
+INSERT INTO t1(name, nb_visits) VALUES('nico', 1)
+ ON DUPLICATE KEY UPDATE nb_visits = nb_visits + 1, nb_visits_prev=nb_visits;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # Update table with virtual column
+--echo #
+
+CREATE TABLE t1 (c1 INTEGER, c2 INTEGER, c3 INTEGER AS (c1 MOD 10) VIRTUAL, c4 INTEGER AS (c1+c2 MOD 5) PERSISTENT ) ENGINE=InnoDb;
+INSERT INTO t1(c1,c2) VALUES (1,1);
+
+SELECT * FROM t1;
+UPDATE t1 SET c2 = 10, c1 = c2;
+SELECT * FROM t1;
+UPDATE t1 SET c2 = 4, c1 = c2;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # Update dynamic column
+--echo #
+SET @@local.character_set_connection='latin1';
+CREATE TABLE assets (
+ item_name VARCHAR(32) PRIMARY KEY,
+ dynamic_col1 BLOB,
+ dynamic_col2 BLOB
+);
+
+INSERT INTO assets VALUES ('Thinkpad Laptop', COLUMN_CREATE('color', 'black', 'price', 500),COLUMN_CREATE('CPU', 'Core I7', 'memory', '8Go'));
+INSERT INTO assets VALUES ('Thinkpad Laptop2', COLUMN_CREATE('color', 'yellow', 'price', 700),COLUMN_CREATE('CPU', 'Core I7', 'memory', '16Go'));
+SELECT item_name, COLUMN_GET(dynamic_col1, 'color' as char) AS color1,
+ COLUMN_GET(dynamic_col2, 'color' as char) AS color2
+ FROM assets;
+UPDATE assets
+ SET dynamic_col1=COLUMN_ADD(dynamic_col1, 'warranty', '3 years'),
+ dynamic_col2=dynamic_col1
+ WHERE item_name LIKE 'Thinkpad Laptop%';
+
+SELECT item_name, COLUMN_GET(dynamic_col1, 'warranty' as char) AS waranty1,
+ COLUMN_GET(dynamic_col2, 'warranty' as char) AS waranty2,
+ COLUMN_GET(dynamic_col2, 'color' as char) AS color2
+ FROM assets;
+
+DROP TABLE assets;
+
+--echo #
+--echo # Update TEXT column
+--echo #
+
+CREATE TABLE ft2(copy TEXT,copy2 TEXT,FULLTEXT(copy)) ENGINE=MyISAM;
+INSERT INTO ft2(copy) VALUES
+ ('MySQL vs MariaDB database'),
+ ('Oracle vs MariaDB database'),
+ ('PostgreSQL vs MariaDB database'),
+ ('MariaDB overview'),
+ ('Foreign keys'),
+ ('Primary keys'),
+ ('Indexes'),
+ ('Transactions'),
+ ('Triggers');
+SELECT * FROM ft2;
+UPDATE ft2 SET copy = UPPER(copy),
+ copy2= copy;
+SELECT * FROM ft2;
+DROP TABLE ft2;
diff --git a/mysql-test/t/sp-big.test b/mysql-test/t/sp-big.test
index 6541e546e43..4220541697e 100644
--- a/mysql-test/t/sp-big.test
+++ b/mysql-test/t/sp-big.test
@@ -1,11 +1,7 @@
#
# Bug #11602: SP with very large body not handled well
#
-
---disable_warnings
-drop procedure if exists test.longprocedure;
-drop table if exists t1;
---enable_warnings
+source include/have_sequence.inc;
create table t1 (a int);
insert into t1 values (1),(2),(3);
@@ -85,3 +81,37 @@ select f1 from t1 limit 1;
select f1 from t2 limit 1;
drop procedure p1;
drop table t1, t2;
+
+#
+# Loops with many iterations
+# (Item_equal must be created in the execution arena)
+#
+create table t1 (
+ `id1` int unsigned not null default '0',
+ `id2` int unsigned not null default '0',
+ `link_type` int unsigned not null default '0',
+ `visibility` tinyint not null default '0',
+ `data` varchar(255) not null default '',
+ `time` int unsigned not null default '0',
+ `version` int unsigned not null default '0',
+ primary key (id1, link_type, visibility, id2)
+) default collate=latin1_bin;
+
+delimiter //;
+create procedure select_test()
+begin
+ declare id1_cond int;
+ set id1_cond = 1;
+ while id1_cond <= 10000 do
+ select count(*) as cnt from (select id1 from t1 force index (primary) where id1 = id1_cond and link_type = 1 and visibility = 1 order by id2 desc) as t into @cnt;
+ set id1_cond = id1_cond + 1;
+ end while;
+end//
+delimiter ;//
+
+insert t1 select seq, seq, 1, 1, seq, seq, seq from seq_1_to_2000;
+set @before=unix_timestamp();
+call select_test();
+select unix_timestamp() - @before < 60;
+drop procedure select_test;
+drop table t1;
diff --git a/mysql-test/t/sp-code.test b/mysql-test/t/sp-code.test
index 29b6764ebc6..1f2f5191f0a 100644
--- a/mysql-test/t/sp-code.test
+++ b/mysql-test/t/sp-code.test
@@ -758,3 +758,172 @@ DELIMITER ;$$
SHOW PROCEDURE CODE p1;
DROP PROCEDURE p1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14415 Add Oracle-style FOR loop to sql_mode=DEFAULT
+--echo #
+
+--echo # Integer range FOR loop
+
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ FOR i IN 1..3
+ DO
+ SELECT i;
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+CALL p1;
+SHOW PROCEDURE CODE p1;
+DROP PROCEDURE p1;
+
+
+--echo # Nested integer range FOR loops
+
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ fori:
+ FOR i IN 1..3
+ DO
+ forj:
+ FOR j IN 1..3
+ DO
+ IF i = 3 THEN
+ LEAVE fori;
+ END IF;
+ IF j = 3 THEN
+ LEAVE forj;
+ END IF;
+ SELECT i,j;
+ END FOR;
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+CALL p1;
+SHOW PROCEDURE CODE p1;
+DROP PROCEDURE p1;
+
+
+--echo # Explicit cursor FOR loops
+
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE cur0 CURSOR FOR SELECT 10 AS a, 'b0' AS b;
+ DECLARE cur1 CURSOR FOR SELECT 10 AS a, 'b0' AS b;
+ DECLARE cur2 CURSOR FOR SELECT 10 AS a, 'b0' AS b;
+ FOR rec1 IN cur1
+ DO
+ SELECT rec1.a, rec1.b;
+ SET rec1.a= 11;
+ SET rec1.b= 'b1';
+ SELECT rec1.a, rec1.b;
+ END FOR;
+ FOR rec0 IN cur0
+ DO
+ SET rec0.a= 10;
+ SET rec0.b='b0';
+ END FOR;
+ FOR rec2 IN cur2
+ DO
+ SET rec2.a= 10;
+ SET rec2.b='b0';
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+SHOW PROCEDURE CODE p1;
+DROP PROCEDURE p1;
+
+
+--echo # Nested explicit cursor FOR loops
+
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE cur0 CURSOR FOR SELECT 10 AS a, 'b0' AS b;
+ FOR rec0 IN cur0
+ DO
+ BEGIN
+ DECLARE cur1 CURSOR FOR SELECT 11 AS a, 'b1' AS b;
+ SET rec0.a= 11;
+ SET rec0.b= 'b0';
+ FOR rec1 IN cur1
+ DO
+ SET rec1.a= 11;
+ SET rec1.b= 'b1';
+ BEGIN
+ DECLARE cur2 CURSOR FOR SELECT 12 AS a, 'b2' AS b;
+ FOR rec2 IN cur2
+ DO
+ SET rec2.a=12;
+ SET rec2.b='b2';
+ END FOR;
+ END;
+ END FOR;
+ END;
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+SHOW PROCEDURE CODE p1;
+DROP PROCEDURE p1;
+
+
+--echo # Implicit cursor FOR loops
+
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ FOR rec1 IN (SELECT 11 AS a, 'b1' AS b)
+ DO
+ SELECT rec1.a, rec1.b;
+ SET rec1.a= 11;
+ SET rec1.b= 'b1';
+ SELECT rec1.a, rec1.b;
+ END FOR;
+ FOR rec0 IN (SELECT 10 AS a, 'b0' AS b)
+ DO
+ SET rec0.a= 10;
+ SET rec0.b='b0';
+ END FOR;
+ FOR rec2 IN (SELECT 12 AS a, 'b2' AS b)
+ DO
+ SET rec2.a= 10;
+ SET rec2.b='b0';
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+SHOW PROCEDURE CODE p1;
+DROP PROCEDURE p1;
+
+--echo # Nested implicit cursor FOR loops
+
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ FOR rec0 IN (SELECT 10 AS a, 'b0' AS b)
+ DO
+ SET rec0.a= 11;
+ SET rec0.b= 'b0';
+ FOR rec1 IN (SELECT 11 AS a, 'b1' AS b)
+ DO
+ SET rec1.a= 11;
+ SET rec1.b= 'b1';
+ FOR rec2 IN (SELECT 12 AS a, 'b2' AS b)
+ DO
+ SET rec2.a=12;
+ SET rec2.b='b2';
+ END FOR;
+ END FOR;
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+SHOW PROCEDURE CODE p1;
+DROP PROCEDURE p1;
diff --git a/mysql-test/t/sp-cursor.test b/mysql-test/t/sp-cursor.test
index 394dc56556a..2e7a72cf8d0 100644
--- a/mysql-test/t/sp-cursor.test
+++ b/mysql-test/t/sp-cursor.test
@@ -474,3 +474,136 @@ DROP PROCEDURE p1;
--echo #
--echo # End of MDEV-12457 Cursors with parameters
--echo #
+
+
+--echo #
+--echo # MDEV-14415 Add Oracle-style FOR loop to sql_mode=DEFAULT
+--echo #
+
+--echo # Explicit cursor
+
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES (1,'b1'), (2,'b2'), (3,'b3');
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE cur CURSOR FOR SELECT * FROM t1;
+ FOR rec IN cur
+ DO
+ SELECT rec.a AS a, rec.b AS b;
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+DROP TABLE t1;
+
+--echo # Explicit cursor with parameters
+
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES (1,'b1'), (2,'b2'), (3,'b3');
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE cur CURSOR(pa INT) FOR SELECT * FROM t1 WHERE a>=pa;
+ FOR rec IN cur(2)
+ DO
+ SELECT rec.a AS a, rec.b AS b;
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+DROP TABLE t1;
+
+--echo # Explicit cursor + label
+
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES ('1','b1'), ('2','b2');
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE cur CURSOR FOR SELECT * FROM t1;
+ forrec:
+ FOR rec IN cur
+ DO
+ SELECT rec.a AS a, rec.b AS b;
+ IF rec.a = 2 THEN
+ LEAVE forrec;
+ END IF;
+ END FOR forrec;
+END;
+$$
+DELIMITER ;$$
+DROP TABLE t1;
+
+--echo # Explicit cursor + FETCH inside the loop body produce an error on "NOT FOUND"
+
+DELIMITER $$;
+--error ER_SP_FETCH_NO_DATA
+BEGIN NOT ATOMIC
+ DECLARE x INT;
+ DECLARE cur CURSOR FOR SELECT 1 AS x;
+ FOR rec IN cur
+ DO
+ FETCH cur INTO x;
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+
+
+--echo # Explicit cursor + FETCH inside the loop body are normally handled by "HANDLER FOR NOT FOUND"
+
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE done INT DEFAULT 0;
+ DECLARE cur CURSOR FOR SELECT 1 AS x, 'y1' AS y UNION
+ SELECT 2,'y2' UNION
+ SELECT 3,'y3';
+ DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
+ forrec:
+ FOR rec IN cur
+ DO
+ SELECT CONCAT(rec.x, ' ', rec.y) AS 'Implicit FETCH';
+ FETCH cur INTO rec;
+ IF done THEN
+ SELECT 'NO DATA' AS `Explicit FETCH`;
+ LEAVE forrec;
+ ELSE
+ SELECT CONCAT(rec.x, ' ', rec.y) AS 'Explicit FETCH';
+ END IF;
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+
+
+--echo # Implicit cursor
+
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES ('1','b1'), ('2','b2');
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ FOR rec IN (SELECT * FROM t1)
+ DO
+ SELECT rec.a AS a, rec.b AS b;
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+DROP TABLE t1;
+
+--echo # Implicit cursor + label
+
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES ('1','b1'), ('2','b2');
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ forrec:
+ FOR rec IN (SELECT * FROM t1)
+ DO
+ SELECT rec.a AS a, rec.b AS b;
+ IF rec.a = 2 THEN
+ LEAVE forrec;
+ END IF;
+ END FOR;
+END;
+$$
+DELIMITER ;$$
+DROP TABLE t1;
diff --git a/mysql-test/t/sp-destruct.test b/mysql-test/t/sp-destruct.test
index 31da235d906..0cd80bd5427 100644
--- a/mysql-test/t/sp-destruct.test
+++ b/mysql-test/t/sp-destruct.test
@@ -10,7 +10,7 @@
-- source include/not_embedded.inc
# Supress warnings written to the log file
-call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted");
+call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 21, found 20. The table is probably corrupted");
call mtr.add_suppression("Stored routine .test...bug14233_[123].: invalid value in column mysql.proc");
# Backup proc table
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index aa537d3596b..0e16948f438 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -1746,7 +1746,7 @@ drop procedure bug15091;
drop function if exists bug16896;
--enable_warnings
---error ER_PARSE_ERROR
+--error ER_INVALID_AGGREGATE_FUNCTION
create aggregate function bug16896() returns int return 1;
#
diff --git a/mysql-test/t/sp-for-loop.test b/mysql-test/t/sp-for-loop.test
new file mode 100644
index 00000000000..6350e9fb9d3
--- /dev/null
+++ b/mysql-test/t/sp-for-loop.test
@@ -0,0 +1,212 @@
+--echo #
+--echo # MDEV-14415 Add Oracle-style FOR loop to sql_mode=DEFAULT
+--echo #
+
+
+CREATE TABLE t1 (a INT);
+DELIMITER /;
+FOR i IN 1..3
+DO
+ INSERT INTO t1 VALUES (i);
+END FOR;
+/
+DELIMITER ;/
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+# Dots must have no delimiters in between
+
+DELIMITER /;
+--error ER_PARSE_ERROR
+CREATE FUNCTION f1 (lower_bound INT, upper_bound INT, lim INT) RETURNS INT
+BEGIN
+ DECLARE total INT DEFAULT 0;
+ FOR i IN lower_bound . . upper_bound
+ DO
+ NULL
+ END FOR;
+ RETURN total;
+END;
+/
+DELIMITER ;/
+
+
+DELIMITER /;
+CREATE FUNCTION f1 (lower_bound INT, upper_bound INT, lim INT) RETURNS INT
+BEGIN
+ DECLARE total INT DEFAULT 0;
+ lab:
+ FOR i IN lower_bound .. upper_bound
+ DO
+ SET total= total + i;
+ IF i = lim THEN
+ LEAVE lab;
+ END IF;
+ -- Bounds are calculated only once.
+ -- The below assignments have no effect on the loop condition
+ SET lower_bound= 900;
+ SET upper_bound= 1000;
+ END FOR;
+ RETURN total;
+END;
+/
+DELIMITER ;/
+SELECT f1(1, 3, 100) FROM DUAL;
+SELECT f1(1, 3, 2) FROM DUAL;
+DROP FUNCTION f1;
+
+
+DELIMITER /;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+ DECLARE total INT DEFAULT 0;
+ FOR i IN 1 .. 5
+ DO
+ SET total= total + 1000;
+ forj:
+ FOR j IN 1 .. 5
+ DO
+ SET total= total + 1;
+ IF j = 3 THEN
+ LEAVE forj; -- End the internal loop
+ END IF;
+ END FOR;
+ END FOR;
+ RETURN total;
+END;
+/
+DELIMITER ;/
+SELECT f1() FROM DUAL;
+DROP FUNCTION f1;
+
+
+DELIMITER /;
+CREATE FUNCTION f1 (a INT, b INT) RETURNS INT
+BEGIN
+ DECLARE total INT DEFAULT 0;
+ fori:
+ FOR i IN REVERSE a..1
+ DO
+ SET total= total + i;
+ IF i = b THEN
+ LEAVE fori;
+ END IF;
+ END FOR;
+ RETURN total;
+END
+/
+DELIMITER ;/
+SELECT f1(3, 100) FROM DUAL;
+SELECT f1(3, 2) FROM DUAL;
+DROP FUNCTION f1;
+
+
+--echo # Testing labeled FOR LOOP statement
+
+DELIMITER /;
+CREATE FUNCTION f1 (a INT, limita INT, b INT, limitb INT) RETURNS INT
+BEGIN
+ DECLARE total INT DEFAULT 0;
+ la:
+ FOR ia IN 1 .. a
+ DO
+ SET total= total + 1000;
+ lb:
+ FOR ib IN 1 .. b
+ DO
+ SET total= total + 1;
+ IF ib = limitb THEN
+ LEAVE lb;
+ END IF;
+ IF ia = limita THEN
+ LEAVE la;
+ END IF;
+ END FOR lb;
+ END FOR la;
+ RETURN total;
+END;
+/
+DELIMITER ;/
+SELECT f1(1, 1, 1, 1) FROM DUAL;
+SELECT f1(1, 2, 1, 2) FROM DUAL;
+SELECT f1(2, 1, 2, 1) FROM DUAL;
+SELECT f1(2, 1, 2, 2) FROM DUAL;
+SELECT f1(2, 2, 2, 2) FROM DUAL;
+SELECT f1(2, 3, 2, 3) FROM DUAL;
+DROP FUNCTION f1;
+
+
+--echo # Testing labeled ITERATE in a labeled FOR LOOP statement
+
+DELIMITER /;
+CREATE FUNCTION f1 (a INT, b INT, blim INT) RETURNS INT
+BEGIN
+ DECLARE total INT DEFAULT 0;
+ la:
+ FOR ia IN 1 .. a
+ DO
+ SET total= total + 1000;
+ BEGIN
+ DECLARE ib INT DEFAULT 1;
+ WHILE ib <= b
+ DO
+ IF ib > blim THEN
+ ITERATE la;
+ END IF;
+ SET ib= ib + 1;
+ SET total= total + 1;
+ END WHILE;
+ END;
+ END FOR la;
+ RETURN total;
+END;
+/
+DELIMITER ;/
+SELECT f1(3,3,0), f1(3,3,1), f1(3,3,2), f1(3,3,3), f1(3,3,4) FROM DUAL;
+DROP FUNCTION f1;
+
+
+--echo # Testing INTERATE statement
+
+DELIMITER /;
+CREATE FUNCTION f1(a INT) RETURNS INT
+BEGIN
+ DECLARE total INT DEFAULT 0;
+ fori:
+ FOR i IN 1 .. a
+ DO
+ IF i=5 THEN
+ ITERATE fori;
+ END IF;
+ SET total= total + 1;
+ END FOR;
+ RETURN total;
+END;
+/
+DELIMITER ;/
+SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL;
+DROP FUNCTION f1;
+
+
+DELIMITER /;
+CREATE FUNCTION f1(a INT) RETURNS INT
+BEGIN
+ DECLARE total INT DEFAULT 0;
+ lj:
+ FOR j IN 1 .. 2
+ DO
+ FOR i IN 1 .. a
+ DO
+ IF i=5 THEN
+ ITERATE lj;
+ END IF;
+ SET total= total + 1;
+ END FOR;
+ END FOR;
+ RETURN total;
+END;
+/
+DELIMITER ;/
+SELECT f1(3), f1(4), f1(5) FROM DUAL;
+DROP FUNCTION f1;
diff --git a/mysql-test/t/sp-row.test b/mysql-test/t/sp-row.test
index 5928c8cb76d..837e24c89c0 100644
--- a/mysql-test/t/sp-row.test
+++ b/mysql-test/t/sp-row.test
@@ -274,7 +274,7 @@ BEGIN
END;
$$
DELIMITER ;$$
---error ER_OPERAND_COLUMNS
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
@@ -287,7 +287,7 @@ BEGIN
END;
$$
DELIMITER ;$$
---error ER_OPERAND_COLUMNS
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 3b615d29166..ceed2bbea7f 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -6317,7 +6317,7 @@ set names utf8|
drop database if exists това_е_дълго_име_за_база_данни_нали|
--enable_warnings
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')|
+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')|
--error ER_SP_PROC_TABLE_CORRUPT
call това_е_дълго_име_за_база_данни_нали.това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго()|
drop database това_е_дълго_име_за_база_данни_нали|
@@ -9583,6 +9583,172 @@ drop procedure p;
drop view v;
drop table t, tmp_t;
+
+--echo #
+--echo # MDEV-13936: Server crashes in Time_and_counter_tracker::incr_loops
+--echo #
+CREATE TABLE t1 (i INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE RAND() > 0.5;
+CREATE FUNCTION f1() RETURNS INT RETURN ( SELECT MAX(i) FROM v1 );
+
+--error ER_NON_INSERTABLE_TABLE
+REPLACE INTO v1 VALUES (f1());
+SET @aux = f1();
+
+# Cleanup
+DROP FUNCTION f1;
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14857: problem with 10.2.11 server crashing when
+--echo # executing stored procedure
+--echo #
+
+SET max_sp_recursion_depth=10;
+
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT);
+
+delimiter ||;
+
+CREATE PROCEDURE proc_0()
+BEGIN
+ CALL empty_1();
+ CALL proc_1();
+END ||
+
+CREATE PROCEDURE proc_1()
+BEGIN
+ CALL proc_2();
+ CALL proc_3();
+ CALL proc_4();
+ CALL proc_5();
+END ||
+
+CREATE PROCEDURE proc_2()
+ CALL proc_6();
+||
+
+CREATE PROCEDURE proc_3()
+BEGIN
+ CALL empty_2();
+ CALL empty_3();
+END ||
+
+CREATE PROCEDURE proc_4()
+ CALL proc_7();
+||
+
+CREATE PROCEDURE proc_5()
+ CALL proc_select();
+||
+
+CREATE PROCEDURE proc_6()
+BEGIN
+ CALL empty_4();
+ CALL empty_5();
+ CALL empty_6();
+ CALL empty_7();
+ CALL proc_8();
+END ||
+
+CREATE PROCEDURE proc_7()
+ CALL proc_9('foo');
+||
+
+CREATE PROCEDURE proc_8()
+ CALL proc_10();
+||
+
+CREATE PROCEDURE proc_9(IN opt VARCHAR(40))
+ IF LEFT(opt,1) <> '_' THEN
+ CALL proc_11();
+ END IF;
+||
+
+CREATE PROCEDURE proc_10()
+ CALL proc_12();
+||
+
+CREATE PROCEDURE proc_11()
+BEGIN
+ CALL empty_8();
+ CALL empty_9();
+ CALL empty_10();
+ CALL proc_13();
+END ||
+
+CREATE PROCEDURE proc_12()
+BEGIN
+ CALL empty_11();
+ CALL empty_12();
+ CALL empty_13();
+END ||
+
+CREATE PROCEDURE proc_13()
+BEGIN
+ CALL proc_9('_bar');
+ CALL empty_14();
+END ||
+
+delimiter ;||
+
+CREATE PROCEDURE empty_1() BEGIN END ;
+CREATE PROCEDURE empty_2() BEGIN END ;
+CREATE PROCEDURE empty_3() BEGIN END ;
+CREATE PROCEDURE empty_4() BEGIN END ;
+CREATE PROCEDURE empty_5() BEGIN END ;
+CREATE PROCEDURE empty_6() BEGIN END ;
+CREATE PROCEDURE empty_7() BEGIN END ;
+CREATE PROCEDURE empty_8() BEGIN END ;
+CREATE PROCEDURE empty_9() BEGIN END ;
+CREATE PROCEDURE empty_10() BEGIN END ;
+CREATE PROCEDURE empty_11() BEGIN END ;
+CREATE PROCEDURE empty_12() BEGIN END ;
+CREATE PROCEDURE empty_13() BEGIN END ;
+CREATE PROCEDURE empty_14() BEGIN END ;
+
+CREATE PROCEDURE proc_select()
+ SELECT * FROM t1 WHERE NOT EXISTS ( SELECT * FROM t2)
+;
+
+CALL proc_0();
+
+# Cleanup
+DROP PROCEDURE empty_1;
+DROP PROCEDURE empty_2;
+DROP PROCEDURE empty_3;
+DROP PROCEDURE empty_4;
+DROP PROCEDURE empty_5;
+DROP PROCEDURE empty_6;
+DROP PROCEDURE empty_7;
+DROP PROCEDURE empty_8;
+DROP PROCEDURE empty_9;
+DROP PROCEDURE empty_10;
+DROP PROCEDURE empty_11;
+DROP PROCEDURE empty_12;
+DROP PROCEDURE empty_13;
+DROP PROCEDURE empty_14;
+DROP PROCEDURE proc_0;
+DROP PROCEDURE proc_1;
+DROP PROCEDURE proc_2;
+DROP PROCEDURE proc_3;
+DROP PROCEDURE proc_4;
+DROP PROCEDURE proc_5;
+DROP PROCEDURE proc_6;
+DROP PROCEDURE proc_7;
+DROP PROCEDURE proc_8;
+DROP PROCEDURE proc_9;
+DROP PROCEDURE proc_10;
+DROP PROCEDURE proc_11;
+DROP PROCEDURE proc_12;
+DROP PROCEDURE proc_13;
+DROP PROCEDURE proc_select;
+DROP TABLE t1, t2;
+
+SET max_sp_recursion_depth=default;
+
--echo #End of 10.1 tests
--echo #
@@ -9644,6 +9810,40 @@ CALL p1();
DROP PROCEDURE p1;
--echo #
+--echo # MDEV-15057 Crash when using an unknown identifier as an SP parameter
+--echo #
+
+CREATE OR REPLACE PROCEDURE p1 (a VARCHAR(10)) SELECT 1;
+--error ER_BAD_FIELD_ERROR
+CALL p1(a);
+drop procedure p1;
+
+DELIMITER |;
+
+CREATE OR REPLACE PROCEDURE p1 (a VARCHAR(10)) SELECT a|
+CREATE OR REPLACE PROCEDURE p2 ()
+BEGIN
+ DECLARE name VARCHAR(10);
+ SET name="hello";
+ call p1(name);
+END|
+CREATE OR REPLACE PROCEDURE p3 ()
+BEGIN
+ DECLARE name VARCHAR(10);
+ SET name="hello";
+ call p1(name2);
+END|
+
+DELIMITER ;|
+
+call p2();
+--error ER_BAD_FIELD_ERROR
+call p3();
+drop procedure p1;
+drop procedure p2;
+drop procedure p3;
+
+--echo #
--echo # Start of 10.3 tests
--echo #
@@ -9757,6 +9957,131 @@ DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
+--echo #
+--echo # MDEV-14228 MariaDB crashes with function
+--echo #
+
+CREATE TABLE t1 (c VARCHAR(16), KEY(c));
+INSERT INTO t1 VALUES ('foo');
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+ DECLARE v VARCHAR(16);
+ FOR v IN (SELECT DISTINCT c FROM t1)
+ DO
+ IF (v = 'bar') THEN
+ SELECT 1 INTO @a;
+ END IF;
+ END FOR;
+ RETURN 'qux';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+ DECLARE v ROW TYPE OF t1;
+ IF v = 'bar' THEN
+ RETURN 'eq';
+ END IF;
+ RETURN 'ne';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DELIMITER $$;
+CREATE FUNCTION f1() RETURNS VARCHAR(16)
+BEGIN
+ DECLARE v ROW(a INT);
+ IF v = 'bar' THEN
+ RETURN 'eq';
+ END IF;
+ RETURN 'ne';
+END $$
+DELIMITER ;$$
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+SELECT f1();
+DROP FUNCTION f1;
+
+DROP TABLE t1;
+
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+BEGIN NOT ATOMIC
+ DECLARE v ROW(a INT);
+ SELECT v IN ('a','b');
+END $$
+DELIMITER ;$$
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+BEGIN NOT ATOMIC
+DECLARE v ROW(a INT);
+ SELECT 'a' IN (v,'b');
+END $$
+DELIMITER ;$$
+
+DELIMITER $$;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
+BEGIN NOT ATOMIC
+ DECLARE v ROW(a INT);
+ SELECT 'a' IN ('b',v);
+END $$
+DELIMITER ;$$
+
+--echo #
+--echo # MDEV-15112 Inconsistent evaluation of spvariable=0 in strict mode
+--echo #
+
+SET sql_mode=STRICT_ALL_TABLES;
+CREATE OR REPLACE TABLE t1 (e TIMESTAMP(6));
+INSERT INTO t1 VALUES ('2001-01-01 10:20:30');
+
+DELIMITER $$;
+CREATE FUNCTION f1(a VARBINARY(255))
+RETURNS INT
+DETERMINISTIC
+BEGIN
+ RETURN a = timestamp'2038-01-19 03:14:07.999999'
+ OR a = 0;
+END
+$$
+CREATE FUNCTION f2(a VARBINARY(255))
+RETURNS INT
+DETERMINISTIC
+BEGIN
+ RETURN a = 0;
+END
+$$
+CREATE OR REPLACE FUNCTION f3(a VARBINARY(255))
+RETURNS INT
+DETERMINISTIC
+BEGIN
+ RETURN a = timestamp'2038-01-19 03:14:07.999999'
+ OR a = sleep(0);
+END
+$$
+DELIMITER ;$$
+
+--error ER_TRUNCATED_WRONG_VALUE
+SELECT f1(e) FROM t1;
+--error ER_TRUNCATED_WRONG_VALUE
+SELECT f2(e) FROM t1;
+--error ER_TRUNCATED_WRONG_VALUE
+SELECT f3(e) FROM t1;
+
+DROP FUNCTION f1;
+DROP FUNCTION f2;
+DROP FUNCTION f3;
+DROP TABLE t1;
+
--echo # Test affected rows from an sp
create table t1 (a int);
diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test
index 31e38db34e5..9f38dc935e7 100644
--- a/mysql-test/t/sql_mode.test
+++ b/mysql-test/t/sql_mode.test
@@ -264,7 +264,7 @@ select @@sql_mode;
set sql_mode=16384+(65536*4);
select @@sql_mode;
--error 1231
-set sql_mode=2147483648*2*2; # that mode does not exist
+set sql_mode=2147483648*2*2*2; # that mode does not exist
select @@sql_mode;
#
diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test
index bff45fca583..92fba9ab0a6 100644
--- a/mysql-test/t/status.test
+++ b/mysql-test/t/status.test
@@ -420,6 +420,16 @@ while ($i)
enable_query_log;
SET @@global.table_open_cache= @old_table_open_cache;
+--echo #
+--echo # MDEV-14505 - Threads_running becomes scalability bottleneck
+--echo #
+--echo # Session status for Threads_running is currently always 1.
+SHOW STATUS LIKE 'Threads_running';
+SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='THREADS_RUNNING';
+FLUSH STATUS;
+SHOW STATUS LIKE 'Threads_running';
+SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='THREADS_RUNNING';
+
# Restore global concurrent_insert value. Keep in the end of the test file.
--connection default
set @@global.concurrent_insert= @old_concurrent_insert;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 5e1e1494fee..c5cec99cebf 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -188,10 +188,10 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce','test');
INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
pseudo='joce');
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
@@ -1834,13 +1834,13 @@ drop table t1, t2;
#
create table t1 (a int, b int);
insert into t1 values (1,2);
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
select 1 = (select * from t1);
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
select (select * from t1) = 1;
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
select (1,2) = (select a from t1);
--- error ER_OPERAND_COLUMNS
+-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
select (select a from t1) = (1,2);
-- error ER_OPERAND_COLUMNS
select (1,2,3) = (select * from t1);
@@ -6078,6 +6078,33 @@ SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
--echo #
drop table t1, t2;
+--echo #
+--echo # MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+--echo # (5.5 test)
+--echo #
+SET @optimiser_switch_save= @@optimizer_switch;
+
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+
+--echo End of 5.5 tests
--echo # End of 10.0 tests
--echo #
diff --git a/mysql-test/t/system_mysql_db_fix40123.test b/mysql-test/t/system_mysql_db_fix40123.test
index fd1212d4ce6..2d17a0964e5 100644
--- a/mysql-test/t/system_mysql_db_fix40123.test
+++ b/mysql-test/t/system_mysql_db_fix40123.test
@@ -72,7 +72,7 @@ CREATE TABLE time_zone_leap_second ( Transition_time bigint signed NOT NULL,
-- disable_query_log
# Drop all tables created by this test
-DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, proxies_priv, innodb_index_stats, innodb_table_stats, table_stats, column_stats, index_stats, roles_mapping, gtid_slave_pos;
+DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, proxies_priv, innodb_index_stats, innodb_table_stats, transaction_registry, table_stats, column_stats, index_stats, roles_mapping, gtid_slave_pos;
-- enable_query_log
diff --git a/mysql-test/t/system_mysql_db_fix50030.test b/mysql-test/t/system_mysql_db_fix50030.test
index c3e7dd7b9b1..9506c3465e7 100644
--- a/mysql-test/t/system_mysql_db_fix50030.test
+++ b/mysql-test/t/system_mysql_db_fix50030.test
@@ -79,7 +79,7 @@ INSERT INTO servers VALUES ('test','localhost','test','root','', 0,'','mysql','r
-- disable_query_log
# Drop all tables created by this test
-DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, proxies_priv, innodb_index_stats, innodb_table_stats, table_stats, column_stats, index_stats, roles_mapping, gtid_slave_pos;
+DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, proxies_priv, innodb_index_stats, innodb_table_stats, transaction_registry, table_stats, column_stats, index_stats, roles_mapping, gtid_slave_pos;
-- enable_query_log
diff --git a/mysql-test/t/system_mysql_db_fix50117.test b/mysql-test/t/system_mysql_db_fix50117.test
index dcc765ae132..f8bef3da162 100644
--- a/mysql-test/t/system_mysql_db_fix50117.test
+++ b/mysql-test/t/system_mysql_db_fix50117.test
@@ -96,7 +96,7 @@ CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_b
-- disable_query_log
# Drop all tables created by this test
-DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, proxies_priv, innodb_index_stats, innodb_table_stats, table_stats, column_stats, index_stats, roles_mapping, gtid_slave_pos;
+DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, proxies_priv, innodb_index_stats, innodb_table_stats, transaction_registry, table_stats, column_stats, index_stats, roles_mapping, gtid_slave_pos;
-- enable_query_log
diff --git a/mysql-test/t/thread_id_overflow.test b/mysql-test/t/thread_id_overflow.test
new file mode 100644
index 00000000000..e93e14f4284
--- /dev/null
+++ b/mysql-test/t/thread_id_overflow.test
@@ -0,0 +1,35 @@
+# test 32bit overflow with connection id
+--source include/have_debug.inc
+
+
+# Connect and disconnect once, to create a "hole" in connection ids
+connect con1, localhost,root;
+disconnect con1;
+
+connect con2, localhost,root;
+connection con2;
+
+connection default;
+let $max_id = `SELECT MAX(ID) FROM INFORMATION_SCHEMA.PROCESSLIST`;
+
+SET @orig_debug=@@debug_dbug;
+SET GLOBAL DEBUG_DBUG='+d,thread_id_overflow';
+
+connect con3, localhost,root;
+connection con3;
+# next line gives UINT32_MAX -1;
+SELECT CONNECTION_ID();
+
+connection default;
+SET GLOBAL DEBUG_DBUG=@orig_debug;
+
+connect con4, localhost,root;
+connection con4;
+--replace_result $max_id max_id
+eval select IF(connection_id() - $max_id = 1,'Good','Bad') as result;
+
+disconnect con4;
+disconnect con3;
+disconnect con2;
+
+connection default;
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index aeab884670d..1557ef200e5 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2643,8 +2643,33 @@ DROP TABLE t1;
SET TIMESTAMP=DEFAULT;
set time_zone= @@global.time_zone;
+--echo #
+--echo # MDEV-13936: Server crashes in Time_and_counter_tracker::incr_loops
+--echo #
+
+CREATE TABLE t1 (i INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE RAND() > 0.5;
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int);
+
+create trigger trg after insert on t2 for each row
+ INSERT INTO t3 SELECT MAX(i) FROM v1 UNION SELECT MAX(i) FROM v1;
+
+drop table t1;
+
+--error ER_NO_SUCH_TABLE
+insert into t2 value (2);
+CREATE TABLE t1 (i INT);
+insert into t2 value (2);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+
+--echo End of 10.1 tests.
+
#
-# MDEV-10915 Count number of exceuted triggers
+# MDEV-10915 Count number of executed triggers
#
create table t1 (i int);
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index b8029d616a5..dafa9f9456e 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -768,6 +768,83 @@ SELECT * FROM t1;
DROP TABLE t1;
SET timestamp=DEFAULT;
+--echo #
+--echo # MDEV-15310 Range optimizer does not work well for "WHERE temporal_column NOT IN (const_list)"
+--echo #
+
+--echo #
+--echo # DATETIME(0)
+--echo #
+
+CREATE TABLE t1 (a DATETIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:02', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:03', 'yes');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01','2001-01-01 23:00:02');
+SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01','2001-01-01 23:00:02');
+DROP TABLE t1;
+
+
+--echo #
+--echo # DATETIME(1)
+--echo #
+
+CREATE TABLE t1 (a DATETIME(1), filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:02.1', 'no');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:03.1', 'yes');
+INSERT INTO t1 VALUES ('2001-01-01 23:00:04.1', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01.1','2001-01-01 23:00:02.1');
+SELECT * FROM t1 WHERE a NOT IN ('2001-01-01 23:00:01.1','2001-01-01 23:00:02.1');
+DROP TABLE t1;
+
--echo #
--echo # End of 10.3 tests
diff --git a/mysql-test/t/type_set.test b/mysql-test/t/type_set.test
index 8c26d5a4366..637ad40c316 100644
--- a/mysql-test/t/type_set.test
+++ b/mysql-test/t/type_set.test
@@ -240,3 +240,11 @@ EXPLAIN SELECT * FROM t1 WHERE a='1x';
EXPLAIN SELECT * FROM t1 WHERE a='1.0';
EXPLAIN SELECT * FROM t1 WHERE a='1.1';
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-11155 Bad error message when creating a SET column with comma and non-ASCII characters
+--echo #
+
+SET NAMES utf8;
+--error ER_ILLEGAL_VALUE_FOR_TYPE
+CREATE TABLE t1 (a SET('a,bü'));
diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test
index 5f3f58df166..6fffd948dc5 100644
--- a/mysql-test/t/type_time.test
+++ b/mysql-test/t/type_time.test
@@ -776,3 +776,494 @@ INSERT INTO t1 VALUES ('10:20:30'),('10:20:31'),('10:20:32');
SELECT a FROM t1 WHERE a IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') ORDER BY a;
DROP TABLE t1;
SET timestamp=DEFAULT;
+
+--echo #
+--echo # MDEV-15176 Storing DATETIME-alike VARCHAR data into TIME produces wrong results
+--echo #
+
+SET sql_mode='';
+CREATE OR REPLACE TABLE t0 (d VARCHAR(64));
+INSERT INTO t0 VALUES ('0000-00-00 10:20:30');
+INSERT INTO t0 VALUES ('0000-00-01 10:20:30');
+INSERT INTO t0 VALUES ('0000-01-00 10:20:30');
+INSERT INTO t0 VALUES ('0000-01-01 10:20:30');
+INSERT INTO t0 VALUES ('0001-00-00 10:20:30');
+INSERT INTO t0 VALUES ('0001-00-01 10:20:30');
+INSERT INTO t0 VALUES ('0001-01-00 10:20:30');
+INSERT INTO t0 VALUES ('0001-01-01 10:20:30');
+
+SET @@global.mysql56_temporal_format=false;
+CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1));
+INSERT INTO t1 SELECT d,d,d FROM t0;
+SELECT * FROM t1 ORDER BY d;
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1));
+INSERT INTO t1 SELECT CONCAT(d,'x'),CONCAT(d,'x'),CONCAT(d,'x') FROM t0;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+SET @@global.mysql56_temporal_format=true;
+CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1));
+INSERT INTO t1 SELECT d,d,d FROM t0;
+SELECT * FROM t1;
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1));
+INSERT INTO t1 SELECT CONCAT(d,'x'),CONCAT(d,'x'),CONCAT(d,'x') FROM t0;
+SELECT * FROM t1 ORDER BY d;
+DROP TABLE t1;
+
+DROP TABLE t0;
+SET sql_mode=DEFAULT;
+
+--echo #
+--echo # MDEV-15287 Bad result for LEAST/GREATEST(datetime_alike_string, time)
+--echo #
+
+--vertical_results
+
+SELECT
+ GREATEST('2010-01-01 10:10:10',TIME('-20:20:20')) AS gt_minus20_implicit,
+ GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-20:20:20')) AS gt_minis20_explicit,
+ GREATEST('2010-01-01 10:10:10',TIME('20:20:20')) AS gt_plus20_implicit,
+ GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('20:20:20')) AS gt_plus20_explicit;
+SELECT
+ HOUR(GREATEST('2010-01-01 10:10:10',TIME('-20:20:20'))) AS gt_minus20_implicit,
+ HOUR(GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-20:20:20'))) AS gt_minis20_explicit,
+ HOUR(GREATEST('2010-01-01 10:10:10',TIME('20:20:20'))) AS gt_plus20_implicit,
+ HOUR(GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('20:20:20'))) AS gt_plus20_explicit;
+
+SELECT
+ LEAST('2010-01-01 10:10:10',TIME('-20:20:20')) AS lt_minus20_implicit,
+ LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-20:20:20')) AS lt_minus20_explicit,
+ LEAST('2010-01-01 10:10:10',TIME('20:20:20')) AS lt_plus20_implicit,
+ LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('20:20:20')) AS lt_plus20_explicit;
+SELECT
+ HOUR(LEAST('2010-01-01 10:10:10',TIME('-20:20:20'))) AS lt_minus20_implicit,
+ HOUR(LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-20:20:20'))) AS lt_minus20_explicit,
+ HOUR(LEAST('2010-01-01 10:10:10',TIME('20:20:20'))) AS lt_plus20_implicit,
+ HOUR(LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('20:20:20'))) AS lt_plus20_explicit;
+
+SELECT
+ GREATEST('2010-01-01 10:10:10',TIME('-200:20:20')) AS gt_minus200_implicit,
+ GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-200:20:20')) AS gt_minus200_explictit,
+ GREATEST('2010-01-01 10:10:10',TIME('200:20:20')) AS gt_plus200_implicit,
+ GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('200:20:20')) AS gt_plus200_explicit;
+SELECT
+ HOUR(GREATEST('2010-01-01 10:10:10',TIME('-200:20:20'))) AS gt_minus200_implicit,
+ HOUR(GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-200:20:20'))) AS gt_minus200_explictit,
+ HOUR(GREATEST('2010-01-01 10:10:10',TIME('200:20:20'))) AS gt_plus200_implicit,
+ HOUR(GREATEST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('200:20:20'))) AS gt_plus200_explicit;
+
+SELECT
+ LEAST('2010-01-01 10:10:10',TIME('-200:20:20')) AS lt_minus200_implicit,
+ LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-200:20:20')) AS lt_minus200_explictit,
+ LEAST('2010-01-01 10:10:10',TIME('200:20:20')) AS lt_plus200_implicit,
+ LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('200:20:20')) AS lt_plus200_explicit;
+SELECT
+ HOUR(LEAST('2010-01-01 10:10:10',TIME('-200:20:20'))) AS lt_minus200_implicit,
+ HOUR(LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('-200:20:20'))) AS lt_minus200_explictit,
+ HOUR(LEAST('2010-01-01 10:10:10',TIME('200:20:20'))) AS lt_plus200_implicit,
+ HOUR(LEAST(CAST('2010-01-01 10:10:10' AS TIME(6)),TIME('200:20:20'))) AS lt_plus200_explicit;
+
+--horizontal_results
+
+
+--echo #
+--echo # MDEV-15293 CAST(AS TIME) returns bad results for LAST_VALUE(),NAME_CONST(),SP variable
+--echo #
+
+SELECT CAST(DATE'2001-01-01' AS TIME);
+SELECT CAST(LAST_VALUE(DATE'2001-01-01') AS TIME);
+SELECT CAST(NAME_CONST('name',DATE'2001-01-01') AS TIME);
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE a DATE DEFAULT '2001-01-01';
+ SELECT CAST(a AS TIME);
+END;
+$$
+DELIMITER ;$$
+
+CREATE OR REPLACE TABLE t1 (dt DATE,country VARCHAR(10), amount INT);
+INSERT INTO t1 VALUES ('2000-01-01','DE',102);
+SELECT
+ dt, country, amount,
+ FIRST_VALUE(dt) OVER () AS first,
+ MINUTE(FIRST_VALUE(dt) OVER ()) AS m_first,
+ LAST_VALUE(dt) OVER () AS last,
+ MINUTE(LAST_VALUE(dt) OVER ()) AS m_last
+FROM t1
+ORDER BY country, dt;
+SELECT
+ dt, country, amount,
+ FIRST_VALUE(dt) OVER () AS first,
+ CAST(FIRST_VALUE(dt) OVER () AS TIME) AS t_first,
+ LAST_VALUE(dt) OVER () AS last,
+ CAST(LAST_VALUE(dt) OVER () AS TIME) AS t_last
+FROM t1
+ORDER BY country, dt;
+DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-15310 Range optimizer does not work well for "WHERE temporal_column NOT IN (const_list)"
+--echo #
+
+--echo #
+--echo # TIME(0), positive within 24 hour
+--echo #
+
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:01', 'no');
+INSERT INTO t1 VALUES ('23:00:02', 'no');
+INSERT INTO t1 VALUES ('23:00:03', 'yes');
+INSERT INTO t1 VALUES ('23:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('23:00:01','23:00:02');
+SELECT * FROM t1 WHERE a NOT IN ('23:00:01','23:00:02');
+DROP TABLE t1;
+
+--echo #
+--echo # TIME(0), negative
+--echo #
+
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:01', 'no');
+INSERT INTO t1 VALUES ('-23:00:02', 'no');
+INSERT INTO t1 VALUES ('-23:00:03', 'yes');
+INSERT INTO t1 VALUES ('-23:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('-23:00:01','-23:00:02');
+SELECT * FROM t1 WHERE a NOT IN ('-23:00:01','-23:00:02');
+DROP TABLE t1;
+
+--echo #
+--echo # TIME(0), positive ouside 24 hours
+--echo #
+
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:01', 'no');
+INSERT INTO t1 VALUES ('24:00:02', 'no');
+INSERT INTO t1 VALUES ('24:00:03', 'yes');
+INSERT INTO t1 VALUES ('24:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('24:00:01','24:00:02');
+SELECT * FROM t1 WHERE a NOT IN ('24:00:01','24:00:02');
+DROP TABLE t1;
+
+--echo #
+--echo # TIME(0), negative, ouside 24 hours
+--echo #
+
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:01', 'no');
+INSERT INTO t1 VALUES ('-24:00:02', 'no');
+INSERT INTO t1 VALUES ('-24:00:03', 'yes');
+INSERT INTO t1 VALUES ('-24:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('-24:00:01','-24:00:02');
+SELECT * FROM t1 WHERE a NOT IN ('-24:00:01','-24:00:02');
+DROP TABLE t1;
+
+--echo #
+--echo # TIME(0), positive, huge
+--echo #
+
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:01', 'no');
+INSERT INTO t1 VALUES ('838:00:02', 'no');
+INSERT INTO t1 VALUES ('838:00:03', 'yes');
+INSERT INTO t1 VALUES ('838:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('838:00:01','838:00:02');
+SELECT * FROM t1 WHERE a NOT IN ('838:00:01','838:00:02');
+DROP TABLE t1;
+
+--echo #
+--echo # TIME(0), negative, huge
+--echo #
+
+CREATE TABLE t1 (a TIME, filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:01', 'no');
+INSERT INTO t1 VALUES ('-838:00:02', 'no');
+INSERT INTO t1 VALUES ('-838:00:03', 'yes');
+INSERT INTO t1 VALUES ('-838:00:04', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('-838:00:01','-838:00:02');
+SELECT * FROM t1 WHERE a NOT IN ('-838:00:01','-838:00:02');
+DROP TABLE t1;
+
+--echo #
+--echo # TIME(1), positive within 24 hours
+--echo #
+
+CREATE TABLE t1 (a TIME(1), filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('23:00:02.1', 'no');
+INSERT INTO t1 VALUES ('23:00:03.1', 'yes');
+INSERT INTO t1 VALUES ('23:00:04.1', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('23:00:01.1','23:00:02.1');
+SELECT * FROM t1 WHERE a NOT IN ('23:00:01.1','23:00:02.1');
+DROP TABLE t1;
+
+--echo #
+--echo # TIME(1), negative within 24 hours
+--echo #
+
+CREATE TABLE t1 (a TIME(1), filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:02.1', 'no');
+INSERT INTO t1 VALUES ('-23:00:03.1', 'yes');
+INSERT INTO t1 VALUES ('-23:00:04.1', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('-23:00:01.1','-23:00:02.1');
+SELECT * FROM t1 WHERE a NOT IN ('-23:00:01.1','-23:00:02.1');
+DROP TABLE t1;
+
+--echo #
+--echo # TIME(1), positive, huge
+--echo #
+
+CREATE TABLE t1 (a TIME(1), filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('838:00:02.1', 'no');
+INSERT INTO t1 VALUES ('838:00:03.1', 'yes');
+INSERT INTO t1 VALUES ('838:00:04.1', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('838:00:01.1','838:00:02.1');
+SELECT * FROM t1 WHERE a NOT IN ('838:00:01.1','838:00:02.1');
+DROP TABLE t1;
+
+--echo #
+--echo # TIME(1), negative, huge
+--echo #
+
+CREATE TABLE t1 (a TIME(1), filler CHAR(200), KEY(a));
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:01.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:02.1', 'no');
+INSERT INTO t1 VALUES ('-838:00:03.1', 'yes');
+INSERT INTO t1 VALUES ('-838:00:04.1', 'yes');
+EXPLAIN SELECT * FROM t1 WHERE a NOT IN ('-838:00:01.1','-838:00:02.1');
+SELECT * FROM t1 WHERE a NOT IN ('-838:00:01.1','-838:00:02.1');
+DROP TABLE t1;
diff --git a/mysql-test/t/type_time_6065.test b/mysql-test/t/type_time_6065.test
index 6e29b849be5..fc91c530760 100644
--- a/mysql-test/t/type_time_6065.test
+++ b/mysql-test/t/type_time_6065.test
@@ -172,6 +172,29 @@ eval $query;
DROP TABLE t1,t2,t3;
SET TIMESTAMP=0; # back to current time
+
+--echo #
+--echo # MDEV-15262 Wrong results for SELECT..WHERE non_indexed_datetime_column=indexed_time_column
+--echo #
+
+SET TIMESTAMP=UNIX_TIMESTAMP('2012-01-31 10:14:35');
+CREATE TABLE t1 (col_time_key TIME, KEY(col_time_key));
+CREATE TABLE t2 (col_datetime_key DATETIME);
+INSERT INTO t1 VALUES ('-760:00:00'),('760:00:00');
+INSERT INTO t1 VALUES ('-770:00:00'),('770:00:00');
+INSERT INTO t2 SELECT * FROM t1;
+SELECT * FROM t2 STRAIGHT_JOIN t1 IGNORE INDEX(col_time_key) WHERE col_time_key = col_datetime_key;
+SELECT * FROM t2 STRAIGHT_JOIN t1 FORCE INDEX (col_time_key) WHERE col_time_key = col_datetime_key;
+INSERT INTO t1 VALUES ('-838:59:59'),('838:59:59');
+INSERT INTO t2 VALUES (DATE_ADD(CURRENT_DATE, INTERVAL '-838:59:59' HOUR_SECOND));
+INSERT INTO t2 VALUES (DATE_ADD(CURRENT_DATE, INTERVAL '838:59:59' HOUR_SECOND));
+INSERT INTO t2 VALUES (DATE_ADD(CURRENT_DATE, INTERVAL '-839:00:00' HOUR_SECOND));
+INSERT INTO t2 VALUES (DATE_ADD(CURRENT_DATE, INTERVAL '839:00:00' HOUR_SECOND));
+SELECT * FROM t2 STRAIGHT_JOIN t1 IGNORE INDEX(col_time_key) WHERE col_time_key = col_datetime_key;
+SELECT * FROM t2 STRAIGHT_JOIN t1 FORCE INDEX (col_time_key) WHERE col_time_key = col_datetime_key;
+DROP TABLE t1, t2;
+SET TIMESTAMP=DEFAULT;
+
#
# End of 10.0 tests
#
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index a2e1fd09ade..f86cae87524 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -1434,6 +1434,42 @@ select e,f, (e , f) in (select e,b from t1 union select c,d from t2) as sub from
select avg(f), (e , f) in (select e,b from t1 union select c,d from t2) as sub from t3 group by sub;
drop table t1,t2,t3;
+--echo #
+--echo # MDEV-14715 Assertion `!table || (!table->read_set ||
+--echo # bitmap_is_set(table->read_set, field_index))'
+--echo # failed in Field_num::val_decimal
+--echo #
+
+CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1, NULL),(3, 4);
+
+(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + sum(a))
+UNION
+(SELECT 2, 2);
+
+(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1)
+UNION
+(SELECT 2, 2);
+
+SELECT a, b FROM t1
+UNION
+(SELECT a, VAR_POP(a) AS f FROM v1 GROUP BY a ORDER BY b/a );
+
+DROP TABLE t1;
+
+--error ER_VIEW_INVALID
+(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1)
+UNION
+(SELECT 2, 2);
+
+DROP VIEW v1;
+
+--error ER_NO_SUCH_TABLE
+(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1)
+UNION
+(SELECT 2, 2);
+
--echo End of 5.5 tests
--echo #
diff --git a/mysql-test/t/update_innodb.test b/mysql-test/t/update_innodb.test
index 0e93e7d9593..acc8aceab00 100644
--- a/mysql-test/t/update_innodb.test
+++ b/mysql-test/t/update_innodb.test
@@ -39,6 +39,18 @@ drop view v1;
drop table t1,t2,t3,t4;
--echo #
+--echo # MDEV-14862: Server crashes in Bitmap<64u>::merge / add_key_field
+--echo #
+
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE TABLE t2 (b INT) ENGINE=InnoDB;
+DELETE FROM v1 WHERE a IN ( SELECT a FROM t2 );
+DELETE FROM v1 WHERE (a,a) IN ( SELECT a,a FROM t2 );
+drop view v1;
+drop table t1,t2;
+
+--echo #
--echo # MDEV-10232 Scalar result of subquery changes after adding an outer select stmt
--echo #
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 847fb843ec8..f78ddd6f49e 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -87,7 +87,7 @@ explain extended select c from v6;
# show table/table status test
show tables;
show full tables;
---replace_column 8 # 12 # 13 # 14 #
+--replace_column 8 # 12 # 13 # 14 # 19 #
show table status;
drop view v1,v2,v3,v4,v5,v6;
@@ -738,7 +738,7 @@ create view v1 as select x1() from t1;
drop function x1;
-- error ER_VIEW_INVALID
select * from v1;
---replace_column 8 # 12 # 13 #
+--replace_column 8 # 12 # 13 # 19 #
show table status;
drop view v1;
drop table t1;
@@ -751,7 +751,7 @@ create view v1 as select a from t1;
alter table t1 change a aa int;
--error ER_VIEW_INVALID
select * from v1;
---replace_column 8 # 12 # 13 #
+--replace_column 8 # 12 # 13 # 19 #
show table status;
show create view v1;
drop view v1;
@@ -5109,118 +5109,6 @@ deallocate prepare stmt1;
drop view v1,v2;
drop table t1,t2;
---echo #
---echo # MDEV-6251: SIGSEGV in query optimizer (in set_check_materialized
---echo # with MERGE view)
---echo #
-
-CREATE TABLE t1 (a1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t2 (b1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t3 (c1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t4 (d1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t5 (e1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t6 (f1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-
-CREATE OR REPLACE view v1 AS
- SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-;
-
-SELECT 1
-FROM (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t1)
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t2) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t3) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t4) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t5) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t6) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t7) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t8) ON 1=1
-;
-
-SELECT 1
-FROM (v1 t1)
-LEFT OUTER JOIN (v1 t2) ON 1=1
-LEFT OUTER JOIN (v1 t3) ON 1=1
-LEFT OUTER JOIN (v1 t4) ON 1=1
-LEFT OUTER JOIN (v1 t5) ON 1=1
-LEFT OUTER JOIN (v1 t6) ON 1=1
-LEFT OUTER JOIN (v1 t7) ON 1=1
-LEFT OUTER JOIN (v1 t8) ON 1=1
-;
-
-drop view v1;
-drop table t1,t2,t3,t4,t5,t6;
-
--echo # -----------------------------------------------------------------
--echo # -- End of 5.3 tests.
--echo # -----------------------------------------------------------------
@@ -5519,6 +5407,18 @@ PREPARE stmt FROM 'REPLACE INTO v2 SELECT a FROM t3';
drop view v1,v2;
drop table t3;
+--echo #
+--echo # MDEV-14619: VIEW and GROUP_CONCAT
+--echo #
+
+CREATE TABLE t1 (str text);
+INSERT INTO t1 VALUES ("My"),("SQL");
+CREATE VIEW v1 AS SELECT GROUP_CONCAT(str SEPARATOR '\\') FROM t1;
+SELECT * FROM v1;
+SHOW CREATE VIEW v1;
+drop view v1;
+drop table t1;
+
--echo # -----------------------------------------------------------------
--echo # -- End of 5.5 tests.
--echo # -----------------------------------------------------------------
diff --git a/mysql-test/t/win.test b/mysql-test/t/win.test
index c353cd8b599..c46aaecfbbf 100644
--- a/mysql-test/t/win.test
+++ b/mysql-test/t/win.test
@@ -2038,5 +2038,35 @@ EXECUTE stmt;
DROP TABLE t1;
--echo #
+--echo # MDEV-13384: "window" seems like a reserved column name but it's not listed as one
+--echo #
+--echo # Currently we allow window as an identifier, except for table aliases.
+--echo #
+
+CREATE TABLE door (id INT, window VARCHAR(10));
+
+--error ER_PARSE_ERROR
+SELECT id
+FROM door as window;
+
+SELECT id, window
+FROM door;
+
+--error ER_PARSE_ERROR
+SELECT id, window
+FROM door as window;
+
+DROP TABLE door;
+
+--echo #
+--echo # MDEV-13352: Server crashes in st_join_table::remove_duplicates
+--echo #
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT DISTINCT ROW_NUMBER() OVER(), i FROM t1 WHERE 0;
+SELECT ROW_NUMBER() OVER(), i FROM t1 WHERE 0;
+DROP TABLE t1;
+
+--echo #
--echo # Start of 10.3 tests
--echo #
diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test
index c1f36129d75..736d0c0de29 100644
--- a/mysql-test/t/xa.test
+++ b/mysql-test/t/xa.test
@@ -80,9 +80,57 @@ xa rollback 'testa','testb';
xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
select * from t1;
-
disconnect con1;
+--source include/wait_until_count_sessions.inc
+
connection default;
+
+# MDEV-14593 human-readable XA RECOVER
+xa start 'tr1';
+insert t1 values (40);
+xa end 'tr1';
+xa prepare 'tr1';
+xa recover format='SQL';
+xa rollback 'tr1';
+
+xa start 'tr1', 'bq';
+insert t1 values (40);
+xa end 'tr1', 'bq';
+xa prepare 'tr1', 'bq';
+xa recover format='SQL';
+xa rollback 'tr1', 'bq';
+
+xa start 'tr1', 'bq', 3;
+insert t1 values (40);
+xa end 'tr1', 'bq', 3;
+xa prepare 'tr1', 'bq', 3;
+xa recover format='SQL';
+xa rollback 'tr1', 'bq', 3;
+
+xa start 'tr1#$';
+insert t1 values (40);
+xa end 'tr1#$';
+xa prepare 'tr1#$';
+xa recover format='SQL';
+xa rollback 'tr1#$';
+
+xa start 'tr1#$', 'bq';
+insert t1 values (40);
+xa end 'tr1#$', 'bq';
+xa prepare 'tr1#$', 'bq';
+xa recover format='SQL';
+xa rollback 'tr1#$', 'bq';
+
+xa start 'tr1#$', 'bq', 3;
+insert t1 values (40);
+xa end 'tr1#$', 'bq', 3;
+xa prepare 'tr1#$', 'bq', 3;
+xa recover format='RAW';
+--error ER_UNKNOWN_EXPLAIN_FORMAT
+xa recover format='PLAIN';
+xa recover format='SQL';
+xa rollback 'tr1#$', 'bq', 3;
+
drop table t1;
#
@@ -326,6 +374,20 @@ DROP TABLE t1;
--echo #
+--echo # MDEV-14609 XA Transction unable to ROLLBACK TO SAVEPOINT
+--echo #
+
+CREATE TABLE t1 (c1 INT) ENGINE=INNODB;
+XA START 'xa1';
+SAVEPOINT savepoint1;
+INSERT INTO t1 (c1) VALUES (1),(2),(3),(4);
+ROLLBACK TO SAVEPOINT savepoint1;
+XA END 'xa1';
+XA ROLLBACK 'xa1';
+DROP TABLE t1;
+
+
+--echo #
--echo # Bug#12352846 - TRANS_XA_START(THD*):
--echo # ASSERTION THD->TRANSACTION.XID_STATE.XID.IS_NULL()
--echo # FAILED
@@ -379,7 +441,6 @@ connection default;
DROP TABLE t1, t2;
disconnect con2;
-
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test
index 76625bd4e92..b567f03a431 100644
--- a/mysql-test/t/xml.test
+++ b/mysql-test/t/xml.test
@@ -713,7 +713,7 @@ FROM t1;
SELECT UPDATEXML(txt, CONCAT('//', REPEAT('b', 63)), '63/63+') FROM t1;
DROP TABLE t1;
-# This will call my_str_realloc_mysqld()
+# This will call realloc()
CREATE TABLE t1 (a TEXT);
INSERT INTO t1 VALUES (CONCAT('<a><', REPEAT('b',128),'>b128</',REPEAT('b',128),'><',REPEAT('c',512),'>c512</',REPEAT('c',512),'></a>'));
SELECT ExtractValue (a, CONCAT('//',REPEAT('c',512))) AS c512 FROM t1;
@@ -748,6 +748,15 @@ SELECT *,IF(@i:=c1,ExtractValue('<a><b>b1</b><b>b2</b></a>','//b[$@i]'),0) AS xp
SELECT * FROM t1 WHERE c2=IF(@i:=c1,ExtractValue('<a><b>b1</b><b>b2</b></a>','//b[$@i]'),0);
DROP TABLE t1;
+--echo #
+--echo # MDEV-15118 ExtractValue(xml,something_complex) does not work
+--echo #
+
+CREATE TABLE t1 (a TEXT);
+INSERT INTO t1 VALUES (CONCAT('<a>aaa</a>'));
+SELECT ExtractValue(a, '/a') AS a FROM t1;
+SELECT ExtractValue(a, FROM_BASE64(TO_BASE64('/a'))) AS a FROM t1;
+DROP TABLE t1;
--echo #
--echo # End of 10.0 tests
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 265f3aa86b7..c911cd064cd 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -36,7 +36,8 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c my_default.c
string.c thr_alarm.c thr_lock.c thr_mutex.c
thr_rwlock.c thr_timer.c
tree.c typelib.c base64.c my_memmem.c
- my_getpagesize.c
+ my_getpagesize.c
+ guess_malloc_library.c
lf_alloc-pin.c lf_dynarray.c lf_hash.c
safemalloc.c my_new.cc
my_getncpus.c my_safehash.c my_chmod.c my_rnd.c
diff --git a/mysys/file_logger.c b/mysys/file_logger.c
index 078286cd7d0..35a077c4391 100644
--- a/mysys/file_logger.c
+++ b/mysys/file_logger.c
@@ -172,7 +172,7 @@ int logger_vprintf(LOGGER_HANDLE *log, const char* fmt, va_list ap)
if (n_bytes >= sizeof(cvtbuf))
n_bytes= sizeof(cvtbuf) - 1;
- result= my_write(log->file, (uchar *) cvtbuf, n_bytes, MYF(0));
+ result= (int)my_write(log->file, (uchar *) cvtbuf, n_bytes, MYF(0));
exit:
flogger_mutex_unlock(&log->lock);
@@ -196,7 +196,7 @@ int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size)
goto exit; /* Log rotation needed but failed */
}
- result= my_write(log->file, (uchar *) buffer, size, MYF(0));
+ result= (int)my_write(log->file, (uchar *) buffer, size, MYF(0));
exit:
flogger_mutex_unlock(&log->lock);
diff --git a/mysys/get_password.c b/mysys/get_password.c
index 8a507d94e9b..2b63a686d07 100644
--- a/mysys/get_password.c
+++ b/mysys/get_password.c
@@ -64,7 +64,6 @@ char *get_tty_password(const char *opt_message)
{
char to[80];
char *pos=to,*end=to+sizeof(to)-1;
- int i=0;
DBUG_ENTER("get_tty_password");
_cputs(opt_message ? opt_message : "Enter password: ");
for (;;)
diff --git a/mysys/guess_malloc_library.c b/mysys/guess_malloc_library.c
new file mode 100644
index 00000000000..ed86ae0679c
--- /dev/null
+++ b/mysys/guess_malloc_library.c
@@ -0,0 +1,65 @@
+/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
+ Copyright (c) 2012, 2017, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/* guess_malloc_library() deduces, to the best of its ability,
+ the currently used malloc library and its version */
+
+#include <stddef.h>
+#include "my_global.h"
+#include <m_string.h>
+
+typedef const char* (*tc_version_type)(int*, int*, const char**);
+typedef int (*mallctl_type)(const char*, void*, size_t*, void*, size_t);
+
+char *guess_malloc_library()
+{
+ tc_version_type tc_version_func;
+ mallctl_type mallctl_func;
+#ifndef HAVE_DLOPEN
+ return (char*) MALLOC_LIBRARY;
+#else
+ static char buf[128];
+
+ if (strcmp(MALLOC_LIBRARY, "system") != 0)
+ {
+ return (char*) MALLOC_LIBRARY;
+ }
+
+ /* tcmalloc */
+ tc_version_func= (tc_version_type) dlsym(RTLD_DEFAULT, "tc_version");
+ if (tc_version_func)
+ {
+ int major, minor;
+ const char* ver_str = tc_version_func(&major, &minor, NULL);
+ strxnmov(buf, sizeof(buf)-1, "tcmalloc ", ver_str, NULL);
+ return buf;
+ }
+
+ /* jemalloc */
+ mallctl_func= (mallctl_type) dlsym(RTLD_DEFAULT, "mallctl");
+ if (mallctl_func)
+ {
+ char *ver;
+ size_t len = sizeof(ver);
+ mallctl_func("version", &ver, &len, NULL, 0);
+ strxnmov(buf, sizeof(buf)-1, "jemalloc ", ver, NULL);
+ return buf;
+ }
+
+ return (char*) MALLOC_LIBRARY;
+#endif
+}
+
diff --git a/mysys/hash.c b/mysys/hash.c
index 57242735d99..d9952afe318 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -380,7 +380,7 @@ static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
my_bool my_hash_insert(HASH *info, const uchar *record)
{
int flag;
- uint idx, halfbuff, first_index;
+ size_t idx, halfbuff, first_index;
size_t length;
my_hash_value_type current_hash_nr, UNINIT_VAR(rec_hash_nr),
UNINIT_VAR(rec2_hash_nr);
diff --git a/mysys/lf_alloc-pin.c b/mysys/lf_alloc-pin.c
index bf2b8a12846..4e4917962ab 100644
--- a/mysys/lf_alloc-pin.c
+++ b/mysys/lf_alloc-pin.c
@@ -161,7 +161,7 @@ LF_PINS *lf_pinbox_get_pins(LF_PINBOX *pinbox)
pinstack_top_ver is 32 bits; 16 low bits are the index in the
array, to the first element of the list. 16 high bits are a version
(every time the 16 low bits are updated, the 16 high bits are
- incremented). Versioniong prevents the ABA problem.
+ incremented). Versioning prevents the ABA problem.
*/
top_ver= pinbox->pinstack_top_ver;
do
@@ -430,7 +430,7 @@ static void alloc_free(uchar *first,
{
anext_node(last)= tmp.node;
} while (!my_atomic_casptr((void **)(char *)&allocator->top,
- (void **)&tmp.ptr, first) && LF_BACKOFF);
+ (void **)&tmp.ptr, first) && LF_BACKOFF());
}
/*
@@ -501,7 +501,7 @@ void *lf_alloc_new(LF_PINS *pins)
{
node= allocator->top;
lf_pin(pins, 0, node);
- } while (node != allocator->top && LF_BACKOFF);
+ } while (node != allocator->top && LF_BACKOFF());
if (!node)
{
node= (void *)my_malloc(allocator->element_size, MYF(MY_WME));
diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c
index 430f1007f30..a7c07679993 100644
--- a/mysys/lf_hash.c
+++ b/mysys/lf_hash.c
@@ -86,12 +86,12 @@ typedef struct {
1 - error (callbck returned 1)
*/
static int l_find(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr,
- const uchar *key, uint keylen, CURSOR *cursor, LF_PINS *pins,
+ const uchar *key, size_t keylen, CURSOR *cursor, LF_PINS *pins,
my_hash_walk_action callback)
{
uint32 cur_hashnr;
const uchar *cur_key;
- uint cur_keylen;
+ size_t cur_keylen;
intptr link;
DBUG_ASSERT(!cs || !callback); /* should not be set both */
@@ -102,7 +102,7 @@ retry:
do { /* PTR() isn't necessary below, head is a dummy node */
cursor->curr= (LF_SLIST *)(*cursor->prev);
lf_pin(pins, 1, cursor->curr);
- } while (*cursor->prev != (intptr)cursor->curr && LF_BACKOFF);
+ } while (*cursor->prev != (intptr)cursor->curr && LF_BACKOFF());
for (;;)
{
@@ -117,7 +117,7 @@ retry:
link= cursor->curr->link;
cursor->next= PTR(link);
lf_pin(pins, 0, cursor->next);
- } while (link != cursor->curr->link && LF_BACKOFF);
+ } while (link != cursor->curr->link && LF_BACKOFF());
if (!DELETED(link))
{
@@ -145,7 +145,7 @@ retry:
and remove this deleted node
*/
if (my_atomic_casptr((void **) cursor->prev,
- (void **) &cursor->curr, cursor->next) && LF_BACKOFF)
+ (void **) &cursor->curr, cursor->next) && LF_BACKOFF())
lf_alloc_free(pins, cursor->curr);
else
goto retry;
diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c
index 125b3a4632d..0085c375aa1 100644
--- a/mysys/ma_dyncol.c
+++ b/mysys/ma_dyncol.c
@@ -3818,6 +3818,58 @@ end:
DBUG_RETURN(rc);
}
+static
+my_bool dynstr_append_json_quoted(DYNAMIC_STRING *str,
+ const char *append, size_t len)
+{
+ size_t additional= ((str->alloc_increment && str->alloc_increment > 6) ?
+ str->alloc_increment :
+ 10);
+ size_t lim= additional;
+ size_t i;
+ if (dynstr_realloc(str, len + additional + 2))
+ return TRUE;
+ str->str[str->length++]= '"';
+ for (i= 0; i < len; i++)
+ {
+ register char c= append[i];
+ if (unlikely(((uchar)c) <= 0x1F))
+ {
+ if (lim < 5)
+ {
+ if (dynstr_realloc(str, additional))
+ return TRUE;
+ lim+= additional;
+ }
+ lim-= 5;
+ str->str[str->length++]= '\\';
+ str->str[str->length++]= 'u';
+ str->str[str->length++]= '0';
+ str->str[str->length++]= '0';
+ str->str[str->length++]= (c < 0x10 ? '0' : '1');
+ c%= 0x10;
+ str->str[str->length++]= (c < 0xA ? '0' + c : 'A' + (c - 0xA));
+ }
+ else
+ {
+ if (c == '"' || c == '\\')
+ {
+ if (!lim)
+ {
+ if (dynstr_realloc(str, additional))
+ return TRUE;
+ lim= additional;
+ }
+ lim--;
+ str->str[str->length++]= '\\';
+ }
+ str->str[str->length++]= c;
+ }
+ }
+ str->str[str->length++]= '"';
+ return FALSE;
+}
+
enum enum_dyncol_func_result
mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
@@ -3883,7 +3935,10 @@ mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
return ER_DYNCOL_RESOURCE;
}
if (quote)
- rc= dynstr_append_quoted(str, from, len, quote);
+ if (quote == DYNCOL_JSON_ESC)
+ rc= dynstr_append_json_quoted(str, from, len);
+ else
+ rc= dynstr_append_quoted(str, from, len, quote);
else
rc= dynstr_append_mem(str, from, len);
if (alloc)
@@ -4183,8 +4238,8 @@ mariadb_dyncol_json_internal(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json,
}
else
{
- if ((rc= mariadb_dyncol_val_str(json, &val,
- &my_charset_utf8_general_ci, '"')) < 0)
+ if ((rc= mariadb_dyncol_val_str(json, &val, DYNCOL_UTF, DYNCOL_JSON_ESC))
+ < 0)
goto err;
}
}
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index a52ea2c5c40..d63547e0936 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -115,6 +115,7 @@ init_functions(IO_CACHE* info)
DBUG_ASSERT(!(info->myflags & MY_ENCRYPT));
info->read_function = info->share ? _my_b_cache_read_r : _my_b_cache_read;
info->write_function = info->share ? _my_b_cache_write_r : _my_b_cache_write;
+ info->myflags&= ~MY_FULL_IO;
break;
case TYPE_NOT_SET:
DBUG_ASSERT(0);
@@ -271,7 +272,7 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
else
{
/* Clear mutex so that safe_mutex will notice that it's not initialized */
- bzero((char*) &info->append_buffer_lock, sizeof(info));
+ bzero((char*) &info->append_buffer_lock, sizeof(info->append_buffer_lock));
}
#endif
@@ -455,6 +456,8 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
{
info->read_end=info->write_pos;
info->end_of_file=my_b_tell(info);
+ /* Ensure we will read all data */
+ info->myflags|= MY_FULL_IO;
/*
Trigger a new seek only if we have a valid
file handle.
@@ -469,6 +472,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
info->seek_not_done=1;
}
info->end_of_file = ~(my_off_t) 0;
+ info->myflags&= ~MY_FULL_IO;
}
pos=info->request_pos+(seek_offset-info->pos_in_file);
if (type == WRITE_CACHE)
@@ -508,7 +512,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
info->read_end= info->buffer;
_my_b_encr_read(info, 0, 0); /* prefill the buffer */
info->write_pos= info->read_pos;
- info->pos_in_file+= info->buffer_length;
+ info->seek_not_done=1;
}
}
else
@@ -553,7 +557,7 @@ int _my_b_read(IO_CACHE *info, uchar *Buffer, size_t Count)
}
res= info->read_function(info, Buffer, Count);
if (res && info->error >= 0)
- info->error+= left_length; /* update number or read bytes */
+ info->error+= (int)left_length; /* update number or read bytes */
return res;
}
@@ -1917,13 +1921,12 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
{
if (append_cache)
{
-
if (mysql_file_write(info->file, info->write_buffer, length,
info->myflags | MY_NABP))
+ {
info->error= -1;
- else
- info->error= 0;
-
+ DBUG_RETURN(-1);
+ }
info->end_of_file+= info->write_pos - info->append_read_pos;
info->append_read_pos= info->write_buffer;
DBUG_ASSERT(info->end_of_file == mysql_file_tell(info->file, MYF(0)));
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index 2499094037d..ef163ee24d3 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -249,18 +249,16 @@ my_off_t my_b_filelength(IO_CACHE *info)
}
-size_t
+my_bool
my_b_write_backtick_quote(IO_CACHE *info, const char *str, size_t len)
{
const uchar *start;
const uchar *p= (const uchar *)str;
const uchar *end= p + len;
size_t count;
- size_t total= 0;
if (my_b_write(info, (uchar *)"`", 1))
- return (size_t)-1;
- ++total;
+ return 1;
for (;;)
{
start= p;
@@ -268,35 +266,32 @@ my_b_write_backtick_quote(IO_CACHE *info, const char *str, size_t len)
++p;
count= p - start;
if (count && my_b_write(info, start, count))
- return (size_t)-1;
- total+= count;
+ return 1;
if (p >= end)
break;
if (my_b_write(info, (uchar *)"``", 2))
- return (size_t)-1;
- total+= 2;
+ return 1;
++p;
}
- if (my_b_write(info, (uchar *)"`", 1))
- return (size_t)-1;
- ++total;
- return total;
+ return (my_b_write(info, (uchar *)"`", 1));
}
/*
Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
- Used for logging in MySQL
- returns number of written character, or (size_t) -1 on error
+ Used for logging in MariaDB
+
+ @return 0 ok
+ 1 error
*/
-size_t my_b_printf(IO_CACHE *info, const char* fmt, ...)
+my_bool my_b_printf(IO_CACHE *info, const char* fmt, ...)
{
size_t result;
va_list args;
va_start(args,fmt);
result=my_b_vprintf(info, fmt, args);
va_end(args);
- return result;
+ return result == (size_t) -1;
}
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 2f0f2bf05c0..edf8cd3be8a 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -2429,7 +2429,7 @@ restart:
The call is thread safe because only the current
thread might change the block->hash_link value
*/
- error= my_pwrite(block->hash_link->file,
+ error= (int)my_pwrite(block->hash_link->file,
block->buffer + block->offset,
block->length - block->offset,
block->hash_link->diskpos + block->offset,
@@ -2674,7 +2674,7 @@ static void read_block_primary(SIMPLE_KEY_CACHE_CB *keycache,
else
{
block->status|= BLOCK_READ;
- block->length= got_length;
+ block->length= (uint)got_length;
/*
Do not set block->offset here. If this block is marked
BLOCK_CHANGED later, we want to flush only the modified part. So
@@ -3809,7 +3809,7 @@ static int flush_cached_blocks(SIMPLE_KEY_CACHE_CB *keycache,
(BLOCK_READ | BLOCK_IN_FLUSH | BLOCK_CHANGED | BLOCK_IN_USE));
block->status|= BLOCK_IN_FLUSHWRITE;
keycache_pthread_mutex_unlock(&keycache->cache_lock);
- error= my_pwrite(file, block->buffer + block->offset,
+ error= (int)my_pwrite(file, block->buffer + block->offset,
block->length - block->offset,
block->hash_link->diskpos + block->offset,
MYF(MY_NABP | MY_WAIT_IF_FULL));
diff --git a/mysys/my_access.c b/mysys/my_access.c
index 75774240406..0f3263a79c3 100644
--- a/mysys/my_access.c
+++ b/mysys/my_access.c
@@ -38,7 +38,7 @@ int my_access(const char *path, int amode)
attributes = GetFileAttributes(path);
if (attributes == INVALID_FILE_ATTRIBUTES ||
- (attributes & FILE_ATTRIBUTE_READONLY) && (amode & W_OK))
+ ((attributes & FILE_ATTRIBUTE_READONLY) && (amode & W_OK)))
{
my_errno= errno= EACCES;
return -1;
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index 83716bf11e1..84bff47d1a9 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -34,13 +34,6 @@ static const char *strip_path(const char *s)
return prev;
}
-#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
-#include <link.h>
-static ptrdiff_t offset= 0;
-#else
-#define offset 0
-#endif
-
/*
The following is very much single-threaded code and it's only supposed
to be used on shutdown or for a crash report
@@ -56,6 +49,13 @@ static ptrdiff_t offset= 0;
static bfd *bfdh= 0;
static asymbol **symtable= 0;
+#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
+#include <link.h>
+static ElfW(Addr) offset= 0;
+#else
+#define offset 0
+#endif
+
/**
finds a file name, a line number, and a function name corresponding to addr.
@@ -145,10 +145,52 @@ err:
#include <m_string.h>
#include <ctype.h>
+#include <sys/wait.h>
static int in[2], out[2];
-static int initialized= 0;
+static pid_t pid;
+static char addr2line_binary[1024];
static char output[1024];
+
+int start_addr2line_fork(const char *binary_path)
+{
+
+ if (pid > 0)
+ {
+ /* Don't leak FDs */
+ close(in[1]);
+ close(out[0]);
+ /* Don't create zombie processes. */
+ waitpid(pid, NULL, 0);
+ }
+
+ if (pipe(in) < 0)
+ return 1;
+ if (pipe(out) < 0)
+ return 1;
+
+ pid = fork();
+ if (pid == -1)
+ return 1;
+
+ if (!pid) /* child */
+ {
+ dup2(in[0], 0);
+ dup2(out[1], 1);
+ close(in[0]);
+ close(in[1]);
+ close(out[0]);
+ close(out[1]);
+ execlp("addr2line", "addr2line", "-C", "-f", "-e", binary_path, NULL);
+ exit(1);
+ }
+
+ close(in[0]);
+ close(out[1]);
+
+ return 0;
+}
+
int my_addr_resolve(void *ptr, my_addr_loc *loc)
{
char input[32];
@@ -156,69 +198,88 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
ssize_t total_bytes_read = 0;
ssize_t extra_bytes_read = 0;
+ ssize_t parsed = 0;
fd_set set;
struct timeval timeout;
int filename_start = -1;
int line_number_start = -1;
- ssize_t i;
- FD_ZERO(&set);
- FD_SET(out[0], &set);
+ Dl_info info;
+ void *offset;
+
+ if (!dladdr(ptr, &info))
+ return 1;
+ if (strcmp(addr2line_binary, info.dli_fname))
+ {
+ /* We use dli_fname in case the path is longer than the length of our static
+ string. We don't want to allocate anything dynamicaly here as we are in
+ a "crashed" state. */
+ if (start_addr2line_fork(info.dli_fname))
+ {
+ addr2line_binary[0] = '\0';
+ return 2;
+ }
+ /* Save result for future comparisons. */
+ strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary));
+ }
+ offset = info.dli_fbase;
len= my_snprintf(input, sizeof(input), "%p\n", ptr - offset);
if (write(in[1], input, len) <= 0)
- return 1;
+ return 3;
- /* 10 ms should be plenty of time for addr2line to issue a response. */
+ 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 = 10000;
+ timeout.tv_usec = 100000;
/* Read in a loop till all the output from addr2line is complete. */
- while (select(out[0] + 1, &set, NULL, NULL, &timeout) > 0)
+ while (parsed == total_bytes_read &&
+ select(out[0] + 1, &set, NULL, NULL, &timeout) > 0)
{
extra_bytes_read= read(out[0], output + total_bytes_read,
sizeof(output) - total_bytes_read);
if (extra_bytes_read < 0)
- return 2;
+ return 4;
/* Timeout or max bytes read. */
if (extra_bytes_read == 0)
break;
total_bytes_read += extra_bytes_read;
- }
-
- /* Failed starting addr2line. */
- if (total_bytes_read == 0)
- return 3;
- /* Go through the addr2line response and get the required data.
- The response is structured in 2 lines. The first line contains the function
- name, while the second one contains <filename>:<line number> */
- for (i = 0; i < total_bytes_read; i++) {
- if (output[i] == '\n') {
- filename_start = i + 1;
- output[i] = '\0';
- }
- if (filename_start != -1 && output[i] == ':') {
- line_number_start = i + 1;
- output[i] = '\0';
- }
- if (line_number_start != -1) {
- loc->line= atoi(output + line_number_start);
- break;
+ /* Go through the addr2line response and get the required data.
+ The response is structured in 2 lines. The first line contains the function
+ name, while the second one contains <filename>:<line number> */
+ for (; parsed < total_bytes_read; parsed++)
+ {
+ if (output[parsed] == '\n')
+ {
+ filename_start = parsed + 1;
+ output[parsed] = '\0';
+ }
+ if (filename_start != -1 && output[parsed] == ':')
+ {
+ line_number_start = parsed + 1;
+ output[parsed] = '\0';
+ break;
+ }
}
}
+
/* Response is malformed. */
if (filename_start == -1 || line_number_start == -1)
- return 4;
+ return 5;
loc->func= output;
loc->file= output + filename_start;
+ loc->line= atoi(output + line_number_start);
/* Addr2line was unable to extract any meaningful information. */
if (strcmp(loc->file, "??") == 0)
- return 5;
+ return 6;
loc->file= strip_path(loc->file);
@@ -227,41 +288,6 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
const char *my_addr_resolve_init()
{
- if (!initialized)
- {
- pid_t pid;
-
-#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
- struct link_map *lm = (struct link_map*) dlopen(0, RTLD_NOW);
- if (lm)
- offset= lm->l_addr;
-#endif
-
- if (pipe(in) < 0)
- return "pipe(in)";
- if (pipe(out) < 0)
- return "pipe(out)";
-
- pid = fork();
- if (pid == -1)
- return "fork";
-
- if (!pid) /* child */
- {
- dup2(in[0], 0);
- dup2(out[1], 1);
- close(in[0]);
- close(in[1]);
- close(out[0]);
- close(out[1]);
- execlp("addr2line", "addr2line", "-C", "-f", "-e", my_progname, NULL);
- exit(1);
- }
-
- close(in[0]);
- close(out[1]);
- initialized= 1;
- }
return 0;
}
#endif
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index 3df73127998..7139466be17 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -26,12 +26,15 @@
#define MALLOC_FLAG(A) ((A & 1) ? MY_THREAD_SPECIFIC : 0)
+#define TRASH_MEM(X) TRASH_FREE(((char*)(X) + ((X)->size-(X)->left)), (X)->left)
+
/*
Initialize memory root
SYNOPSIS
init_alloc_root()
mem_root - memory root to initialize
+ name - name of memroot (for debugging)
block_size - size of chunks (blocks) used for memory allocation
(It is external size of chunk i.e. it should include
memory required for internal structures, thus it
@@ -51,13 +54,13 @@
Because of this, we store in MY_THREAD_SPECIFIC as bit 1 in block_size
*/
-void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
+void init_alloc_root(MEM_ROOT *mem_root, const char *name, size_t block_size,
size_t pre_alloc_size __attribute__((unused)),
myf my_flags)
{
DBUG_ENTER("init_alloc_root");
- DBUG_PRINT("enter",("root: %p prealloc: %zu", mem_root,
- pre_alloc_size));
+ DBUG_PRINT("enter",("root: %p name: %s prealloc: %zu", mem_root,
+ name, pre_alloc_size));
mem_root->free= mem_root->used= mem_root->pre_alloc= 0;
mem_root->min_malloc= 32;
@@ -69,18 +72,20 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
mem_root->block_num= 4; /* We shift this with >>2 */
mem_root->first_block_usage= 0;
mem_root->total_alloc= 0;
+ mem_root->name= name;
#if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG))
if (pre_alloc_size)
{
if ((mem_root->free= mem_root->pre_alloc=
- (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)),
- MYF(my_flags))))
+ (USED_MEM*) my_malloc(pre_alloc_size + ALIGN_SIZE(sizeof(USED_MEM)),
+ MYF(my_flags))))
{
mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
mem_root->total_alloc= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
mem_root->free->left= pre_alloc_size;
mem_root->free->next= 0;
+ TRASH_MEM(mem_root->free);
}
}
#endif
@@ -152,6 +157,7 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
mem->left= pre_alloc_size;
mem->next= *prev;
*prev= mem_root->pre_alloc= mem;
+ TRASH_MEM(mem);
}
else
{
@@ -172,7 +178,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
#if defined(HAVE_valgrind) && defined(EXTRA_DEBUG)
reg1 USED_MEM *next;
DBUG_ENTER("alloc_root");
- DBUG_PRINT("enter",("root: %p", mem_root));
+ DBUG_PRINT("enter",("root: %p name: %s", mem_root, mem_root->name));
DBUG_ASSERT(alloc_root_inited(mem_root));
@@ -207,7 +213,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
reg1 USED_MEM *next= 0;
reg2 USED_MEM **prev;
DBUG_ENTER("alloc_root");
- DBUG_PRINT("enter",("root: %p", mem_root));
+ DBUG_PRINT("enter",("root: %p name: %s", mem_root, mem_root->name));
DBUG_ASSERT(alloc_root_inited(mem_root));
DBUG_EXECUTE_IF("simulate_out_of_memory",
@@ -255,6 +261,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
next->size= get_size;
next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
*prev=next;
+ TRASH_MEM(next);
}
point= (uchar*) ((char*) next+ (next->size-next->left));
@@ -298,6 +305,10 @@ void *multi_alloc_root(MEM_ROOT *root, ...)
char **ptr, *start, *res;
size_t tot_length, length;
DBUG_ENTER("multi_alloc_root");
+ /*
+ We don't need to do DBUG_PRINT here as it will be done when alloc_root
+ is called
+ */
va_start(args, root);
tot_length= 0;
@@ -323,9 +334,9 @@ void *multi_alloc_root(MEM_ROOT *root, ...)
DBUG_RETURN((void*) start);
}
-#define TRASH_MEM(X) TRASH(((char*)(X) + ((X)->size-(X)->left)), (X)->left)
-/* Mark all data in blocks free for reusage */
+#if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG))
+/** Mark all data in blocks free for reusage */
static inline void mark_blocks_free(MEM_ROOT* root)
{
@@ -355,6 +366,7 @@ static inline void mark_blocks_free(MEM_ROOT* root)
root->first_block_usage= 0;
root->block_num= 4;
}
+#endif
/*
@@ -380,7 +392,8 @@ void free_root(MEM_ROOT *root, myf MyFlags)
{
reg1 USED_MEM *next,*old;
DBUG_ENTER("free_root");
- DBUG_PRINT("enter",("root: %p flags: %u", root, (uint) MyFlags));
+ DBUG_PRINT("enter",("root: %p name: %s flags: %u", root, root->name,
+ (uint) MyFlags));
#if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG))
/*
diff --git a/mysys/my_atomic_writes.c b/mysys/my_atomic_writes.c
index 0b54a207713..7f1e353c121 100644
--- a/mysys/my_atomic_writes.c
+++ b/mysys/my_atomic_writes.c
@@ -259,7 +259,7 @@ static my_bool shannon_has_atomic_write(File file, int page_size)
************************************************************************/
/*
- Initalize automic write sub systems.
+ Initialize automic write sub systems.
Checks if we have any devices that supports atomic write
*/
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index a0c1a23d63c..b6963739613 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -166,6 +166,9 @@ static inline uint get_first_set(my_bitmap_map value, uint word_pos)
return MY_BIT_NONE; /* Impossible */
}
+/*
+ Initialize a bitmap object. All bits will be set to zero
+*/
my_bool my_bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits,
my_bool thread_safe)
diff --git a/mysys/my_compare.c b/mysys/my_compare.c
index 5ba1b409abb..4d384936a55 100644
--- a/mysys/my_compare.c
+++ b/mysys/my_compare.c
@@ -20,8 +20,8 @@
#include <my_compare.h>
#include <my_sys.h>
-int ha_compare_text(CHARSET_INFO *charset_info, const uchar *a, uint a_length,
- const uchar *b, uint b_length, my_bool part_key)
+int ha_compare_text(CHARSET_INFO *charset_info, const uchar *a, size_t a_length,
+ const uchar *b, size_t b_length, my_bool part_key)
{
if (!part_key)
return charset_info->coll->strnncollsp(charset_info, a, a_length,
diff --git a/mysys/my_conio.c b/mysys/my_conio.c
index 0af5706cace..21f30bd9b67 100644
--- a/mysys/my_conio.c
+++ b/mysys/my_conio.c
@@ -47,7 +47,7 @@ static HANDLE my_coninpfh= 0; /* console input */
static
int my_pthread_auto_mutex_lock(HANDLE* ph, const char* name, int id, int time)
{
- int res;
+ DWORD res;
char tname[FN_REFLEN];
sprintf(tname, "%s-%08X", name, id);
@@ -203,7 +203,7 @@ char* my_cgets(char *buffer, size_t clen, size_t* plen)
if (*plen > 0 && buffer[*plen - 1] == '\r')
{
char tmp[3];
- int tmplen= sizeof(tmp);
+ DWORD tmplen= (DWORD)sizeof(tmp);
*plen= *plen - 1;
/* read /n left in the buffer */
diff --git a/mysys/my_context.c b/mysys/my_context.c
index cf10738bdbd..5423f59d19b 100644
--- a/mysys/my_context.c
+++ b/mysys/my_context.c
@@ -707,7 +707,7 @@ my_context_continue(struct my_context *c)
{
/*
This seems to be a common trick to run ConvertThreadToFiber() only on the
- first occurence in a thread, in a way that works on multiple Windows
+ first occurrence in a thread, in a way that works on multiple Windows
versions.
*/
void *current_fiber= GetCurrentFiber();
diff --git a/mysys/my_default.c b/mysys/my_default.c
index 37f6d2bfbbf..dc8523576c6 100644
--- a/mysys/my_default.c
+++ b/mysys/my_default.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2011, 2018, 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
@@ -233,7 +234,7 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv,
(char **) &my_defaults_group_suffix);
if (! my_defaults_group_suffix)
- my_defaults_group_suffix= getenv(STRINGIFY_ARG(DEFAULT_GROUP_SUFFIX_ENV));
+ my_defaults_group_suffix= getenv("MYSQL_GROUP_SUFFIX");
if (forced_extra_defaults && !defaults_already_read)
{
@@ -487,8 +488,7 @@ int load_defaults(const char *conf_file, const char **groups,
easily command line options override options in configuration files
NOTES
- In case of fatal error, the function will print a warning and do
- exit(1)
+ In case of fatal error, the function will print a warning and returns 2
To free used memory one should call free_defaults() with the argument
that was put in *argv
@@ -519,7 +519,7 @@ int my_load_defaults(const char *conf_file, const char **groups,
uint args_sep= my_getopt_use_args_separator ? 1 : 0;
DBUG_ENTER("load_defaults");
- init_alloc_root(&alloc, 512, 0, MYF(0));
+ init_alloc_root(&alloc, "my_load_defaults", 512, 0, MYF(0));
if ((dirs= init_default_directories(&alloc)) == NULL)
goto err;
/*
@@ -641,8 +641,7 @@ int my_load_defaults(const char *conf_file, const char **groups,
err:
fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
- exit(1);
- return 0; /* Keep compiler happy */
+ return 2;
}
@@ -1043,7 +1042,7 @@ void my_print_default_files(const char *conf_file)
{
const char **dirs;
MEM_ROOT alloc;
- init_alloc_root(&alloc, 512, 0, MYF(0));
+ init_alloc_root(&alloc, "my_print_defaults", 512, 0, MYF(0));
if ((dirs= init_default_directories(&alloc)) == NULL)
{
@@ -1185,7 +1184,7 @@ static const char **init_default_directories(MEM_ROOT *alloc)
{
errors += add_directory(alloc, fname_buffer, dirs);
- strncat(fname_buffer, "/data", sizeof(fname_buffer));
+ strcat_s(fname_buffer, sizeof(fname_buffer), "/data");
errors += add_directory(alloc, fname_buffer, dirs);
}
}
diff --git a/mysys/my_delete.c b/mysys/my_delete.c
index 0faf6079d98..beece473a01 100644
--- a/mysys/my_delete.c
+++ b/mysys/my_delete.c
@@ -83,7 +83,7 @@ static int my_win_unlink(const char *name)
{
HANDLE handle= INVALID_HANDLE_VALUE;
DWORD attributes;
- DWORD last_error;
+ uint last_error;
char unique_filename[MAX_PATH + 35];
unsigned long long tsc; /* time stamp counter, for unique filename*/
@@ -148,7 +148,7 @@ static int my_win_unlink(const char *name)
name, tsc);
if (!MoveFile(name, unique_filename))
{
- DBUG_PRINT("warning", ("moving %s to unique filename failed, error %u\n",
+ DBUG_PRINT("warning", ("moving %s to unique filename failed, error %lu\n",
name,GetLastError()));
}
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index c9bfe2e1eaa..830b7f42473 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -236,7 +236,7 @@ int handle_options(int *argc, char ***argv,
{
is_cmdline_arg= 1;
- /* save the separator too if skip unkown options */
+ /* save the separator too if skip unknown options */
if (my_getopt_skip_unknown)
(*argv)[argvpos++]= cur_arg;
else
@@ -826,7 +826,7 @@ static int setval(const struct my_option *opts, void *value, char *argument,
*((ulonglong*)value)=
find_set_from_flags(opts->typelib, opts->typelib->count,
*(ulonglong *)value, opts->def_value,
- argument, strlen(argument),
+ argument, (uint)strlen(argument),
&error, &error_len);
if (error)
{
@@ -969,31 +969,43 @@ my_bool getopt_compare_strings(register const char *s, register const char *t,
/*
function: eval_num_suffix
- Transforms suffix like k/m/g to their real value.
+ Transforms suffix like k/m/g/t/p/e to their real value.
*/
-static inline long eval_num_suffix(char *suffix, int *error)
+static inline ulonglong eval_num_suffix(char *suffix, int *error)
{
- long num= 1;
- if (*suffix == 'k' || *suffix == 'K')
- num*= 1024L;
- else if (*suffix == 'm' || *suffix == 'M')
- num*= 1024L * 1024L;
- else if (*suffix == 'g' || *suffix == 'G')
- num*= 1024L * 1024L * 1024L;
- else if (*suffix)
- {
+ switch (*suffix) {
+ case '\0':
+ return 1ULL;
+ case 'k':
+ case 'K':
+ return 1ULL << 10;
+ case 'm':
+ case 'M':
+ return 1ULL << 20;
+ case 'g':
+ case 'G':
+ return 1ULL << 30;
+ case 't':
+ case 'T':
+ return 1ULL << 40;
+ case 'p':
+ case 'P':
+ return 1ULL << 50;
+ case 'e':
+ case 'E':
+ return 1ULL << 60;
+ default:
*error= 1;
- return 0;
+ return 0ULL;
}
- return num;
}
/*
function: eval_num_suffix_ll
Transforms a number with a suffix to real number. Suffix can
- be k|K for kilo, m|M for mega or g|G for giga.
+ be k|K for kilo, m|M for mega, etc.
*/
static longlong eval_num_suffix_ll(char *argument,
@@ -1026,7 +1038,7 @@ static longlong eval_num_suffix_ll(char *argument,
function: eval_num_suffix_ull
Transforms a number with a suffix to positive Integer. Suffix can
- be k|K for kilo, m|M for mega or g|G for giga.
+ be k|K for kilo, m|M for mega, etc.
*/
static ulonglong eval_num_suffix_ull(char *argument,
@@ -1609,7 +1621,7 @@ void my_print_variables(const struct my_option *options)
for (optp= options; optp->name; optp++)
{
- length= strlen(optp->name)+1;
+ length= (uint)strlen(optp->name)+1;
if (length > name_space)
name_space= length;
}
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 7db0a58d471..9bd1185a3bf 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -105,6 +105,10 @@ my_bool my_init(void)
if (my_thread_global_init())
return 1;
+#if defined(SAFEMALLOC) && !defined(DBUG_OFF)
+ dbug_sanity= sf_sanity;
+#endif
+
/* $HOME is needed early to parse configuration files located in ~/ */
if ((home_dir= getenv("HOME")) != 0)
home_dir= intern_filename(home_dir_buff, home_dir);
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index d5f54f00b85..dc6b7cfd292 100644
--- a/mysys/my_lib.c
+++ b/mysys/my_lib.c
@@ -119,10 +119,6 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
DBUG_ENTER("my_dir");
DBUG_PRINT("my",("path: '%s' MyFlags: %lu",path,MyFlags));
-#if !defined(HAVE_READDIR_R)
- mysql_mutex_lock(&THR_LOCK_open);
-#endif
-
tmp_file= directory_file_name(tmp_path, path);
if (!(dirp= opendir(tmp_path)))
@@ -136,7 +132,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
MYF(MyFlags)))
goto error;
- init_alloc_root(&dirh->root, NAMES_START_SIZE, NAMES_START_SIZE,
+ init_alloc_root(&dirh->root, "dir", NAMES_START_SIZE, NAMES_START_SIZE,
MYF(MyFlags));
dp= (struct dirent*) dirent_tmp;
@@ -174,9 +170,6 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
}
(void) closedir(dirp);
-#if !defined(HAVE_READDIR_R)
- mysql_mutex_unlock(&THR_LOCK_open);
-#endif
if (MyFlags & MY_WANT_SORT)
sort_dynamic(&dirh->array, (qsort_cmp) comp_names);
@@ -187,9 +180,6 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
DBUG_RETURN(&dirh->dir);
error:
-#if !defined(HAVE_READDIR_R)
- mysql_mutex_unlock(&THR_LOCK_open);
-#endif
my_errno=errno;
if (dirp)
(void) closedir(dirp);
@@ -216,12 +206,12 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
ushort mode;
char tmp_path[FN_REFLEN], *tmp_file,attrib;
#ifdef _WIN64
- __int64 handle;
+ __int64 handle= -1;
#else
- long handle;
+ long handle= -1;
#endif
DBUG_ENTER("my_dir");
- DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags));
+ DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,(int)MyFlags));
/* Put LIB-CHAR as last path-character if not there */
tmp_file=tmp_path;
@@ -245,7 +235,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
MYF(MyFlags)))
goto error;
- init_alloc_root(&dirh->root, NAMES_START_SIZE, NAMES_START_SIZE,
+ init_alloc_root(&dirh->root, "dir", NAMES_START_SIZE, NAMES_START_SIZE,
MYF(MyFlags));
if ((handle=_findfirst(tmp_path,&find)) == -1L)
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index 082d8e9f5a0..34b1723e13c 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -34,7 +34,6 @@ static int win_lock(File fd, int locktype, my_off_t start, my_off_t length,
DWORD dwFlags;
OVERLAPPED ov= {0};
HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
- DWORD lastError= 0;
int i;
int timeout_millis= timeout_sec * 1000;
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index dc02d3896bd..6a3ec8da093 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -109,7 +109,7 @@ void *my_malloc(size_t size, myf my_flags)
my_error(EE_OUTOFMEMORY, MYF(ME_BELL + ME_WAITTANG +
ME_NOREFRESH + ME_FATALERROR),size);
if (my_flags & MY_FAE)
- exit(1);
+ abort();
}
else
{
@@ -200,8 +200,6 @@ void *my_realloc(void *oldpoint, size_t size, myf my_flags)
/**
Free memory allocated with my_malloc.
- @remark Relies on free being able to handle a NULL argument.
-
@param ptr Pointer to the memory allocated by my_malloc.
*/
void my_free(void *ptr)
@@ -214,6 +212,13 @@ void my_free(void *ptr)
my_bool old_flags;
old_size= MALLOC_SIZE_AND_FLAG(ptr, &old_flags);
update_malloc_size(- (longlong) old_size - MALLOC_PREFIX_SIZE, old_flags);
+#ifndef SAFEMALLOC
+ /*
+ Trash memory if not safemalloc. We don't have to do this if safemalloc
+ is used as safemalloc will also do trashing
+ */
+ TRASH_FREE(ptr, old_size);
+#endif
sf_free(MALLOC_FIX_POINTER_FOR_FREE(ptr));
}
DBUG_VOID_RETURN;
diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c
index 20e53a23ab5..0b84ed0cd82 100644
--- a/mysys/my_pthread.c
+++ b/mysys/my_pthread.c
@@ -21,6 +21,7 @@
#include <signal.h>
#include <m_string.h>
#include <thr_alarm.h>
+#include <my_pthread.h>
#if (defined(__BSD__) || defined(_BSDI_VERSION))
#define SCHED_POLICY SCHED_RR
diff --git a/mysys/my_read.c b/mysys/my_read.c
index 922da5a7e95..89b368e9800 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -35,11 +35,10 @@
size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
{
- size_t readbytes, save_count;
+ size_t readbytes, save_count= 0;
DBUG_ENTER("my_read");
DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %lu",
Filedes, Buffer, (ulong) Count, MyFlags));
- save_count= Count;
if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
MyFlags|= my_global_flags;
@@ -61,47 +60,52 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
if (readbytes != Count)
{
- my_errno= errno;
- if (errno == 0 || (readbytes != (size_t) -1 &&
- (MyFlags & (MY_NABP | MY_FNABP))))
- my_errno= HA_ERR_FILE_TOO_SHORT;
+ int got_errno= my_errno= errno;
DBUG_PRINT("warning",("Read only %d bytes off %lu from %d, errno: %d",
(int) readbytes, (ulong) Count, Filedes,
- my_errno));
+ got_errno));
+
+ if (got_errno == 0 || (readbytes != (size_t) -1 &&
+ (MyFlags & (MY_NABP | MY_FNABP))))
+ my_errno= HA_ERR_FILE_TOO_SHORT;
- if ((readbytes == 0 || (int) readbytes == -1) && errno == EINTR)
+ if ((readbytes == 0 || (int) readbytes == -1) && got_errno == EINTR)
{
DBUG_PRINT("debug", ("my_read() was interrupted and returned %ld",
(long) readbytes));
continue; /* Interrupted */
}
+ /* Do a read retry if we didn't get enough data on first read */
+ if (readbytes != (size_t) -1 && readbytes != 0 &&
+ (MyFlags & MY_FULL_IO))
+ {
+ Buffer+= readbytes;
+ Count-= readbytes;
+ save_count+= readbytes;
+ continue;
+ }
+
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
{
if (readbytes == (size_t) -1)
my_error(EE_READ,
MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
- my_filename(Filedes),my_errno);
+ my_filename(Filedes), got_errno);
else if (MyFlags & (MY_NABP | MY_FNABP))
my_error(EE_EOFERR,
MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
- my_filename(Filedes),my_errno);
+ my_filename(Filedes), got_errno);
}
if (readbytes == (size_t) -1 ||
((MyFlags & (MY_FNABP | MY_NABP)) && !(MyFlags & MY_FULL_IO)))
DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
- if (readbytes != (size_t) -1 && (MyFlags & MY_FULL_IO))
- {
- Buffer+= readbytes;
- Count-= readbytes;
- continue;
- }
}
if (MyFlags & (MY_NABP | MY_FNABP))
readbytes= 0; /* Ok on read */
- else if (MyFlags & MY_FULL_IO)
- readbytes= save_count;
+ else
+ readbytes+= save_count;
break;
}
DBUG_RETURN(readbytes);
diff --git a/mysys/my_sync.c b/mysys/my_sync.c
index d1e239692f1..cf8dfb6a8c8 100644
--- a/mysys/my_sync.c
+++ b/mysys/my_sync.c
@@ -133,8 +133,6 @@ int my_sync(File fd, myf my_flags)
} /* my_sync */
-static const char cur_dir_name[]= {FN_CURLIB, 0};
-
/*
Force directory information to disk.
@@ -151,6 +149,7 @@ int my_sync_dir(const char *dir_name __attribute__((unused)),
myf my_flags __attribute__((unused)))
{
#ifdef NEED_EXPLICIT_SYNC_DIR
+ static const char cur_dir_name[]= {FN_CURLIB, 0};
File dir_fd;
int res= 0;
const char *correct_dir_name;
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 678bfc459c7..2faa704b998 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -341,14 +341,12 @@ void my_thread_end(void)
tmp, pthread_self(), tmp ? (long) tmp->id : 0L);
#endif
-#ifdef HAVE_PSI_INTERFACE
/*
Remove the instrumentation for this thread.
This must be done before trashing st_my_thread_var,
because the LF_HASH depends on it.
*/
- PSI_THREAD_CALL(delete_current_thread)();
-#endif
+ PSI_CALL_delete_current_thread();
/*
We need to disable DBUG early for this thread to ensure that the
@@ -385,7 +383,6 @@ void my_thread_end(void)
/* Trash variable so that we can detect false accesses to my_thread_var */
tmp->init= 2;
- TRASH(tmp, sizeof(*tmp));
free(tmp);
}
}
diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c
index 54b272d7025..514e9a92ecf 100644
--- a/mysys/my_wincond.c
+++ b/mysys/my_wincond.c
@@ -98,9 +98,10 @@ int pthread_attr_init(pthread_attr_t *connect_att)
return 0;
}
-int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack)
+int pthread_attr_setstacksize(pthread_attr_t *connect_att,size_t stack)
{
- connect_att->dwStackSize=stack;
+ DBUG_ASSERT(stack < UINT_MAX);
+ connect_att->dwStackSize=(DWORD)stack;
return 0;
}
diff --git a/mysys/my_windac.c b/mysys/my_windac.c
index 9b489759625..720bf3b4894 100644
--- a/mysys/my_windac.c
+++ b/mysys/my_windac.c
@@ -17,21 +17,6 @@
#include "m_string.h"
#ifdef __WIN__
-/* Windows NT/2000 discretionary access control utility functions. */
-
-/*
- Check if the operating system is built on NT technology.
-
- RETURN
- 0 Windows 95/98/Me
- 1 otherwise
-*/
-
-static my_bool is_nt()
-{
- return GetVersion() < 0x80000000;
-}
-
/*
Auxiliary structure to store pointers to the data which we need to keep
around while SECURITY_ATTRIBUTES is in use.
@@ -86,12 +71,6 @@ int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror,
PSID owner_sid;
My_security_attr *attr;
- if (! is_nt())
- {
- *psa= 0;
- return 0;
- }
-
/*
Get SID of Everyone group. Easier to retrieve all SIDs each time
this function is called than worry about thread safety.
diff --git a/mysys/my_winerr.c b/mysys/my_winerr.c
index a3f6229b74e..ccd94d92d80 100644
--- a/mysys/my_winerr.c
+++ b/mysys/my_winerr.c
@@ -96,7 +96,7 @@ access violations */
static int get_errno_from_oserr(unsigned long oserrno)
{
- int i;
+ size_t i;
/* check the table for the OS error code */
for (i= 0; i < ERRTABLESIZE; ++i)
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c
index f3335621c38..080eeb49f63 100644
--- a/mysys/my_winthread.c
+++ b/mysys/my_winthread.c
@@ -79,10 +79,10 @@ int pthread_create(pthread_t *thread_id, const pthread_attr_t *attr,
par->arg= param;
stack_size= attr?attr->dwStackSize:0;
- handle= _beginthreadex(NULL, stack_size , pthread_start, par, 0, thread_id);
+ handle= _beginthreadex(NULL, stack_size , pthread_start, par, 0, (uint *)thread_id);
if (!handle)
goto error_return;
- DBUG_PRINT("info", ("thread id=%u",*thread_id));
+ DBUG_PRINT("info", ("thread id=%lu",*thread_id));
/* Do not need thread handle, close it */
CloseHandle((HANDLE)handle);
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 892e09148ef..38a75120303 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -146,8 +146,12 @@ const char *my_open_parent_dir_nosymlinks(const char *pathname, int *pdfd);
return NOAT;
#endif
+#ifndef _WIN32
#define CREATE_NOSYMLINK_FUNCTION(PROTO,AT,NOAT) \
static int PROTO { NOSYMLINK_FUNCTION_BODY(AT,NOAT) }
+#else
+#define CREATE_NOSYMLINK_FUNCTION(PROTO,AT,NOAT)
+#endif
#ifdef _WIN32
#include <sys/stat.h>
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index b8d9442fbc9..ae8993fbf00 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -330,7 +330,7 @@ static int bad_ptr(const char *where, void *ptr)
magicend[3] != MAGICEND3)
{
DBUG_PRINT("error",("Overrun buffer %p", ptr));
- warn("Error: %s overrun buffer %p", where);
+ warn("Error: %s overrun buffer %p", where, ptr);
fprintf(stderr, "Allocated at ");
print_stack(irem->frame);
return 1;
@@ -340,7 +340,7 @@ static int bad_ptr(const char *where, void *ptr)
}
/* check all allocated memory list for consistency */
-static int sf_sanity()
+int sf_sanity()
{
struct st_irem *irem;
int flag= 0;
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 398ade7ad59..619172a5a6a 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -70,7 +70,7 @@ static void print_buffer(char *buffer, size_t count)
@return Zero on success.
*/
-static int safe_print_str(const char *addr, int max_len)
+static int safe_print_str(const char *addr, size_t max_len)
{
int fd;
pid_t tid;
@@ -147,7 +147,7 @@ static int safe_print_str(const char *addr, int max_len)
returns 1, it does not mean 100% that the pointer is corrupted.
*/
-int my_safe_print_str(const char* val, int max_len)
+int my_safe_print_str(const char* val, size_t max_len)
{
char *heap_end;
@@ -703,7 +703,7 @@ void my_print_stacktrace(uchar* unused1, ulong unused2, my_bool silent)
if(have_source)
{
const char *base_file_name= my_basename(line.FileName);
- my_safe_printf_stderr("[%s:%u]",
+ my_safe_printf_stderr("[%s:%lu]",
base_file_name, line.LineNumber);
}
my_safe_printf_stderr("%s", "\n");
@@ -733,7 +733,7 @@ void my_write_core(int unused)
if(GetModuleFileName(NULL, path, sizeof(path)))
{
_splitpath(path, NULL, NULL,dump_fname,NULL);
- strncat(dump_fname, ".dmp", sizeof(dump_fname));
+ strcat_s(dump_fname, sizeof(dump_fname), ".dmp");
}
hFile= CreateFile(dump_fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
@@ -763,7 +763,7 @@ void my_write_core(int unused)
}
-int my_safe_print_str(const char *val, int len)
+int my_safe_print_str(const char *val, size_t len)
{
__try
{
@@ -780,7 +780,7 @@ int my_safe_print_str(const char *val, int len)
size_t my_write_stderr(const void *buf, size_t count)
{
- return (size_t) write(fileno(stderr), buf, count);
+ return (size_t) write(fileno(stderr), buf, (uint)count);
}
diff --git a/mysys/string.c b/mysys/string.c
index a0fa3a02e17..18c5f4ec9af 100644
--- a/mysys/string.c
+++ b/mysys/string.c
@@ -178,9 +178,9 @@ my_bool dynstr_append_quoted(DYNAMIC_STRING *str,
const char *append, size_t len,
char quote)
{
- uint additional= (str->alloc_increment ? str->alloc_increment : 10);
- uint lim= additional;
- uint i;
+ size_t additional= (str->alloc_increment ? str->alloc_increment : 10);
+ size_t lim= additional;
+ size_t i;
if (dynstr_realloc(str, len + additional + 2))
return TRUE;
str->str[str->length++]= quote;
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index a101c23be58..357923cf388 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -36,13 +36,6 @@
#define ETIME ETIMEDOUT
#endif
-uint thr_client_alarm;
-static int alarm_aborted=1; /* No alarm thread */
-my_bool thr_alarm_inited= 0, my_disable_thr_alarm= 0;
-volatile my_bool alarm_thread_running= 0;
-time_t next_alarm_expire_time= ~ (time_t) 0;
-static sig_handler process_alarm_part2(int sig);
-
#ifdef DBUG_OFF
#define reset_index_in_queue(alarm_data)
#else
@@ -55,9 +48,16 @@ static sig_handler process_alarm_part2(int sig);
#define one_signal_hand_sigmask(A,B,C)
#endif
+my_bool thr_alarm_inited= 0, my_disable_thr_alarm= 0;
#if !defined(__WIN__)
+uint thr_client_alarm;
+static int alarm_aborted=1; /* No alarm thread */
+volatile my_bool alarm_thread_running= 0;
+time_t next_alarm_expire_time= ~ (time_t) 0;
+static sig_handler process_alarm_part2(int sig);
+
static mysql_mutex_t LOCK_alarm;
static mysql_cond_t COND_alarm;
static sigset_t full_signal_set;
@@ -274,7 +274,7 @@ void thr_end_alarm(thr_alarm_t *alarmed)
/*
Come here when some alarm in queue is due.
Mark all alarms with are finnished in list.
- Shedule alarms to be sent again after 1-10 sec (many alarms at once)
+ Schedule alarms to be sent again after 1-10 sec (many alarms at once)
If alarm_aborted is set then all alarms are given and resent
every second.
*/
@@ -426,7 +426,7 @@ void end_thr_alarm(my_bool free_structures)
if (alarm_aborted != 1) /* If memory not freed */
{
mysql_mutex_lock(&LOCK_alarm);
- DBUG_PRINT("info",("Resheduling %d waiting alarms",alarm_queue.elements));
+ DBUG_PRINT("info",("Rescheduling %d waiting alarms",alarm_queue.elements));
alarm_aborted= -1; /* mark aborted */
if (alarm_queue.elements || (alarm_thread_running && free_structures))
{
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index 49cb3ea600f..268a2b80f63 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -240,7 +240,7 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
if (!mp->file)
{
fprintf(stderr,
- "safe_mutex: Trying to lock unitialized mutex at %s, line %d\n",
+ "safe_mutex: Trying to lock uninitialized mutex at %s, line %d\n",
file, line);
fflush(stderr);
abort();
@@ -585,7 +585,7 @@ int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
if (!mp->file)
{
fprintf(stderr,
- "safe_mutex: Trying to destroy unitialized mutex at %s, line %d\n",
+ "safe_mutex: Trying to destroy uninitialized mutex at %s, line %d\n",
file, line);
fflush(stderr);
abort();
diff --git a/mysys/tree.c b/mysys/tree.c
index 13f9bd808a2..b07d56ec942 100644
--- a/mysys/tree.c
+++ b/mysys/tree.c
@@ -130,7 +130,8 @@ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit,
}
if (!(tree->with_delete= MY_TEST(my_flags & MY_TREE_WITH_DELETE)))
{
- init_alloc_root(&tree->mem_root, default_alloc_size, 0, MYF(my_flags));
+ init_alloc_root(&tree->mem_root, "tree", default_alloc_size, 0,
+ MYF(my_flags));
tree->mem_root.min_malloc= sizeof(TREE_ELEMENT)+tree->size_of_element;
}
DBUG_VOID_RETURN;
diff --git a/mysys/typelib.c b/mysys/typelib.c
index e45ede2c43a..f0be211fd46 100644
--- a/mysys/typelib.c
+++ b/mysys/typelib.c
@@ -45,18 +45,6 @@ int find_type_with_warning(const char *x, TYPELIB *typelib, const char *option)
}
-int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
-{
- int res;
- if ((res= find_type_with_warning(x, typelib, option)) <= 0)
- {
- sf_leaking_memory= 1; /* no memory leak reports here */
- exit(1);
- }
- return res;
-}
-
-
/**
Search after a string in a list of strings. Endspace in x is not compared.
diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c
index df208507590..8e66e0372c1 100644
--- a/mysys/waiting_threads.c
+++ b/mysys/waiting_threads.c
@@ -618,7 +618,7 @@ retry:
{
rc= *shared_ptr;
lf_pin(arg->thd->pins, 0, rc);
- } while (rc != *shared_ptr && LF_BACKOFF);
+ } while (rc != *shared_ptr && LF_BACKOFF());
if (rc == 0)
{
diff --git a/mysys_ssl/my_crypt.cc b/mysys_ssl/my_crypt.cc
index 92f4012d175..db303f37b0e 100644
--- a/mysys_ssl/my_crypt.cc
+++ b/mysys_ssl/my_crypt.cc
@@ -323,24 +323,11 @@ unsigned int my_aes_ctx_size(enum my_aes_mode)
return MY_AES_CTX_SIZE;
}
-#ifdef HAVE_YASSL
-#include <random.hpp>
-int my_random_bytes(uchar* buf, int num)
-{
- TaoCrypt::RandomNumberGenerator rand;
- rand.GenerateBlock((TaoCrypt::byte*) buf, num);
- return MY_AES_OK;
-}
-#else
-
int my_random_bytes(uchar *buf, int num)
{
- RAND_METHOD *rand = RAND_OpenSSL();
- if (rand == NULL || rand->bytes(buf, num) != 1)
+ if (RAND_bytes(buf, num) != 1)
return MY_AES_OPENSSL_ERROR;
return MY_AES_OK;
}
-#endif
}
-
diff --git a/mysys_ssl/openssl.c b/mysys_ssl/openssl.c
index 3f841eec92f..f3dc8f4277c 100644
--- a/mysys_ssl/openssl.c
+++ b/mysys_ssl/openssl.c
@@ -51,7 +51,7 @@ int check_openssl_compatibility()
EVP_MD_CTX *md5_ctx;
if (!CRYPTO_set_mem_functions(coc_malloc, NULL, NULL))
- return 1;
+ return 0;
testing= 1;
alloc_size= alloc_count= 0;
diff --git a/mysys_ssl/yassl.cc b/mysys_ssl/yassl.cc
index 23376c82b4f..4e9c21ebfd1 100644
--- a/mysys_ssl/yassl.cc
+++ b/mysys_ssl/yassl.cc
@@ -26,6 +26,7 @@
#include "aes.hpp"
using yaSSL::yaERR_remove_state;
+using yaSSL::yaRAND_bytes;
#define EVP_CIPH_ECB_MODE 0x1U
#define EVP_CIPH_CBC_MODE 0x2U
diff --git a/pcre/pcregrep.c b/pcre/pcregrep.c
index 317f7454e13..a58ff823509 100644
--- a/pcre/pcregrep.c
+++ b/pcre/pcregrep.c
@@ -951,7 +951,7 @@ Returns: TRUE if the path is not excluded
static BOOL
test_incexc(char *path, patstr *ip, patstr *ep)
{
-int plen = strlen(path);
+int plen = (int)strlen(path);
for (; ep != NULL; ep = ep->next)
{
@@ -2502,7 +2502,7 @@ compile_pattern(patstr *p, int options, int popts, int fromfile,
char buffer[PATBUFSIZE];
const char *error;
char *ps = p->string;
-int patlen = strlen(ps);
+int patlen = (int)strlen(ps);
int errptr;
if (p->compiled != NULL) return TRUE;
diff --git a/pcre/pcretest.c b/pcre/pcretest.c
index f1303037281..a0e65ed9808 100644
--- a/pcre/pcretest.c
+++ b/pcre/pcretest.c
@@ -1904,7 +1904,7 @@ for (;;)
{
if (f == stdin) printf("%s", prompt);
- if (fgets((char *)here, rlen, f) == NULL)
+ if (fgets((char *)here, (int)rlen, f) == NULL)
return (here == start)? NULL : start;
}
@@ -2025,7 +2025,7 @@ pcre_uint32 c = 0;
int yield = 0;
if (length < 0)
- length = strlen((char *)p);
+ length = (int)strlen((char *)p);
while (length-- > 0)
{
diff --git a/plugin/audit_null/audit_null.c b/plugin/audit_null/audit_null.c
index 2747063670c..0f4efc25ef3 100644
--- a/plugin/audit_null/audit_null.c
+++ b/plugin/audit_null/audit_null.c
@@ -145,7 +145,7 @@ static void audit_null_notify(MYSQL_THD thd __attribute__((unused)),
break;
case MYSQL_AUDIT_TABLE_RENAME:
snprintf(buf, sizeof(buf), "rename to %s.%s",
- event_table->new_database, event_table->new_table);
+ event_table->new_database.str, event_table->new_table.str);
buf[sizeof(buf)-1]= 0;
op= buf;
break;
@@ -154,7 +154,7 @@ static void audit_null_notify(MYSQL_THD thd __attribute__((unused)),
fprintf(f, "%s[%s] @ %s [%s]\t%s.%s : %s\n",
event_table->priv_user, event_table->user,
event_table->host, ip,
- event_table->database, event_table->table, op);
+ event_table->database.str, event_table->table.str, op);
}
}
diff --git a/plugin/auth_examples/qa_auth_client.c b/plugin/auth_examples/qa_auth_client.c
index a7ee2f83a39..2153ee71504 100644
--- a/plugin/auth_examples/qa_auth_client.c
+++ b/plugin/auth_examples/qa_auth_client.c
@@ -90,7 +90,7 @@ static int test_plugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
return CR_ERROR;
/* send the reply to the server */
res= vio->write_packet(vio, (const unsigned char *) reply,
- strlen(reply) + 1);
+ (int)strlen(reply) + 1);
if (res)
return CR_ERROR;
diff --git a/plugin/auth_examples/qa_auth_interface.c b/plugin/auth_examples/qa_auth_interface.c
index b65acb5ea16..08ddbf7f30a 100644
--- a/plugin/auth_examples/qa_auth_interface.c
+++ b/plugin/auth_examples/qa_auth_interface.c
@@ -226,7 +226,7 @@ static int test_plugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
return CR_ERROR;
/* send the reply to the server */
res= vio->write_packet(vio, (const unsigned char *) reply,
- strlen(reply) + 1);
+ (int)strlen(reply) + 1);
if (res)
return CR_ERROR;
diff --git a/plugin/auth_examples/test_plugin.c b/plugin/auth_examples/test_plugin.c
index 2b20a8cb56c..8cc17894be4 100644
--- a/plugin/auth_examples/test_plugin.c
+++ b/plugin/auth_examples/test_plugin.c
@@ -205,7 +205,7 @@ static int test_plugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
return CR_ERROR;
/* send the reply to the server */
res= vio->write_packet(vio, (const unsigned char *) reply,
- strlen(reply) + 1);
+ (int)strlen(reply) + 1);
if (res)
return CR_ERROR;
diff --git a/plugin/auth_gssapi/mysql-test/auth_gssapi/basic.result b/plugin/auth_gssapi/mysql-test/auth_gssapi/basic.result
index dc5155fac8c..b7cf3d8e488 100644
--- a/plugin/auth_gssapi/mysql-test/auth_gssapi/basic.result
+++ b/plugin/auth_gssapi/mysql-test/auth_gssapi/basic.result
@@ -1,16 +1,24 @@
INSTALL SONAME 'auth_gssapi';
+Warnings:
+Note 1105 SSPI: using principal name 'localhost', mech 'Negotiate'
CREATE USER 'GSSAPI_SHORTNAME' IDENTIFIED WITH gssapi;
+connect con1,localhost,$GSSAPI_SHORTNAME,,;
SELECT USER(),CURRENT_USER();
USER() CURRENT_USER()
GSSAPI_SHORTNAME@localhost GSSAPI_SHORTNAME@%
+disconnect con1;
+connection default;
DROP USER 'GSSAPI_SHORTNAME';
CREATE USER nosuchuser IDENTIFIED WITH gssapi;
ERROR 28000: GSSAPI name mismatch, requested 'nosuchuser', actual name 'GSSAPI_SHORTNAME'
DROP USER nosuchuser;
CREATE USER usr1 IDENTIFIED WITH gssapi as 'GSSAPI_FULLNAME';
+connect con1,localhost,usr1,,;
SELECT USER(),CURRENT_USER();
USER() CURRENT_USER()
usr1@localhost usr1@%
+disconnect con1;
+connection default;
DROP USER usr1;
CREATE USER nosuchuser IDENTIFIED WITH gssapi AS 'nosuchuser@EXAMPLE.COM';
ERROR 28000: GSSAPI name mismatch, requested 'nosuchuser@EXAMPLE.COM', actual name 'GSSAPI_FULLNAME'
diff --git a/plugin/auth_gssapi/server_plugin.cc b/plugin/auth_gssapi/server_plugin.cc
index 6ffcf5c65c1..5db86cffbe4 100644
--- a/plugin/auth_gssapi/server_plugin.cc
+++ b/plugin/auth_gssapi/server_plugin.cc
@@ -56,7 +56,7 @@ static int first_packet_len;
*/
char *srv_principal_name;
char *srv_keytab_path;
-char *srv_mech_name=(char *)"";
+const char *srv_mech_name="";
unsigned long srv_mech;
/**
@@ -110,7 +110,7 @@ static int initialize_plugin(void *unused)
strcpy(first_packet, srv_principal_name);
strcpy(first_packet + strlen(srv_principal_name) + 1,srv_mech_name);
- first_packet_len = strlen(srv_principal_name) + strlen(srv_mech_name) + 2;
+ first_packet_len = (int)(strlen(srv_principal_name) + strlen(srv_mech_name) + 2);
return 0;
}
diff --git a/plugin/auth_gssapi/server_plugin.h b/plugin/auth_gssapi/server_plugin.h
index 1348835e653..6284a319d03 100644
--- a/plugin/auth_gssapi/server_plugin.h
+++ b/plugin/auth_gssapi/server_plugin.h
@@ -37,7 +37,7 @@ typedef enum
extern unsigned long srv_mech;
extern char *srv_principal_name;
-extern char *srv_mech_name;
+extern const char *srv_mech_name;
extern char *srv_keytab_path;
/*
Check, with GSSAPI/SSPI username of logged on user.
diff --git a/plugin/auth_gssapi/sspi_errmsg.cc b/plugin/auth_gssapi/sspi_errmsg.cc
index 961ef51f42e..8e59da6f1ed 100644
--- a/plugin/auth_gssapi/sspi_errmsg.cc
+++ b/plugin/auth_gssapi/sspi_errmsg.cc
@@ -138,7 +138,7 @@ void sspi_errmsg(int err, char *buf, size_t size)
len = FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
err, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
- buf, size, NULL);
+ buf, (DWORD)size, NULL);
if(len > 0)
{
diff --git a/plugin/auth_gssapi/sspi_server.cc b/plugin/auth_gssapi/sspi_server.cc
index 73c74c2e200..c382c447ef3 100644
--- a/plugin/auth_gssapi/sspi_server.cc
+++ b/plugin/auth_gssapi/sspi_server.cc
@@ -108,7 +108,7 @@ static int get_client_name_from_context(CtxtHandle *ctxt,
sspi_ret= ImpersonateSecurityContext(ctxt);
if (sspi_ret == SEC_E_OK)
{
- ULONG len= name_len;
+ ULONG len= (ULONG)name_len;
if (!GetUserNameEx(NameSamCompatible, name, &len))
{
log_error(GetLastError(), "GetUserNameEx");
@@ -163,7 +163,7 @@ int auth_server(MYSQL_PLUGIN_VIO *vio, const char *user, size_t user_len, int co
}
sspi_ret= AcquireCredentialsHandle(
srv_principal_name,
- srv_mech_name,
+ (LPSTR)srv_mech_name,
SECPKG_CRED_INBOUND,
NULL,
NULL,
@@ -282,12 +282,12 @@ int plugin_init()
{
srv_principal_name= get_default_principal_name();
}
- my_printf_error(0, "SSPI: using principal name '%s', mech '%s'",
+ my_printf_error(ER_UNKNOWN_ERROR, "SSPI: using principal name '%s', mech '%s'",
ME_ERROR_LOG | ME_NOTE, srv_principal_name, srv_mech_name);
ret = AcquireCredentialsHandle(
srv_principal_name,
- srv_mech_name,
+ (LPSTR)srv_mech_name,
SECPKG_CRED_INBOUND,
NULL,
NULL,
diff --git a/plugin/aws_key_management/aws_key_management_plugin.cc b/plugin/aws_key_management/aws_key_management_plugin.cc
index 60ca6fd1ff3..b99beb0774d 100644
--- a/plugin/aws_key_management/aws_key_management_plugin.cc
+++ b/plugin/aws_key_management/aws_key_management_plugin.cc
@@ -469,7 +469,7 @@ static int read_and_decrypt_key(const char *path, KEY_INFO *info)
return(ENCRYPTION_KEY_BUFFER_TOO_SMALL);
}
memcpy(info->data, plaintext.GetUnderlyingData(), len);
- info->length= len;
+ info->length= (unsigned int)len;
return(0);
}
@@ -527,7 +527,7 @@ static int generate_and_save_datakey(uint keyid, uint version)
my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: Can't create file %s", ME_ERROR_LOG, filename);
return(-1);
}
- size_t len= byteBuffer.GetLength();
+ unsigned int len= (unsigned int)byteBuffer.GetLength();
if (write(fd, byteBuffer.GetUnderlyingData(), len) != len)
{
my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: can't write to %s", ME_ERROR_LOG, filename);
diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc
index 8ed6ef64b0c..826a929643d 100644
--- a/plugin/feedback/feedback.cc
+++ b/plugin/feedback/feedback.cc
@@ -93,7 +93,7 @@ static COND* make_cond(THD *thd, TABLE_LIST *tables, LEX_STRING *filter)
{
Item_cond_or *res= NULL;
Name_resolution_context nrc;
- const char *db= tables->db, *table= tables->alias;
+ const char *db= tables->db.str, *table= tables->alias.str;
LEX_CSTRING *field= &tables->table->field[0]->field_name;
CHARSET_INFO *cs= &my_charset_latin1;
diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc
index bcd10f6713f..92f186a1e2a 100644
--- a/plugin/feedback/sender_thread.cc
+++ b/plugin/feedback/sender_thread.cc
@@ -40,7 +40,7 @@ ulong interval= 60*60*24*7; ///< in seconds (one week)
*/
static int table_to_string(TABLE *table, String *result)
{
- bool res;
+ int res;
char buff1[MAX_FIELD_WIDTH], buff2[MAX_FIELD_WIDTH];
String str1(buff1, sizeof(buff1), system_charset_info);
String str2(buff2, sizeof(buff2), system_charset_info);
@@ -64,7 +64,7 @@ static int table_to_string(TABLE *table, String *result)
}
}
- res = res || result->append('\n');
+ res = res || (int)result->append('\n');
/*
Note, "|=" and not "||" - because we want to call ha_rnd_end()
@@ -105,8 +105,7 @@ static int prepare_for_fill(TABLE_LIST *tables)
thd->set_time();
thd->init_for_queries();
thd->real_id= pthread_self();
- thd->db= NULL;
- thd->db_length= 0;
+ thd->db= null_clex_str;
thd->security_ctx->host_or_ip= "";
thd->security_ctx->db_access= DB_ACLS;
thd->security_ctx->master_access= ~NO_ACCESS;
@@ -114,11 +113,9 @@ static int prepare_for_fill(TABLE_LIST *tables)
lex_start(thd);
mysql_init_select(thd->lex);
- tables->init_one_table(INFORMATION_SCHEMA_NAME.str,
- INFORMATION_SCHEMA_NAME.length,
- i_s_feedback->table_name,
- strlen(i_s_feedback->table_name),
- 0, TL_READ);
+ LEX_CSTRING tbl_name= {i_s_feedback->table_name, strlen(i_s_feedback->table_name) };
+
+ tables->init_one_table(&INFORMATION_SCHEMA_NAME, &tbl_name, 0, TL_READ);
tables->schema_table= i_s_feedback;
tables->table= create_schema_table(thd, tables);
if (!tables->table)
diff --git a/plugin/feedback/url_http.cc b/plugin/feedback/url_http.cc
index 4851097e63f..76aef909756 100644
--- a/plugin/feedback/url_http.cc
+++ b/plugin/feedback/url_http.cc
@@ -40,9 +40,9 @@ class Url_http: public Url {
bool ssl;
LEX_STRING proxy_host, proxy_port;
- int use_proxy()
+ bool use_proxy()
{
- return proxy_host.length;
+ return proxy_host.length != 0;
}
Url_http(LEX_STRING &url_arg, LEX_STRING &host_arg,
@@ -166,7 +166,7 @@ int Url_http::send(const char* data, size_t data_length)
{
my_socket fd= INVALID_SOCKET;
char buf[1024];
- uint len= 0;
+ size_t len= 0;
addrinfo *addrs, *addr, filter= {0, AF_UNSPEC, SOCK_STREAM, 6, 0, 0, 0, 0};
int res= use_proxy() ?
@@ -186,7 +186,7 @@ int Url_http::send(const char* data, size_t data_length)
if (fd == INVALID_SOCKET)
continue;
- if (connect(fd, addr->ai_addr, addr->ai_addrlen) == 0)
+ if (connect(fd, addr->ai_addr, (int) addr->ai_addrlen) == 0)
break;
closesocket(fd);
diff --git a/plugin/feedback/utils.cc b/plugin/feedback/utils.cc
index 09abbb2de23..64510161691 100644
--- a/plugin/feedback/utils.cc
+++ b/plugin/feedback/utils.cc
@@ -92,12 +92,19 @@ static int uname(struct utsname *buf)
{
OSVERSIONINFOEX ver;
ver.dwOSVersionInfoSize = (DWORD)sizeof(ver);
+ /* GetVersionEx got deprecated, we need it anyway, so disable deprecation warnings. */
+#ifdef _MSC_VER
+#pragma warning (disable : 4996)
+#endif
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#endif
if (!GetVersionEx((OSVERSIONINFO *)&ver))
return -1;
buf->nodename[0]= 0;
strcpy(buf->sysname, "Windows");
- sprintf(buf->release, "%d.%d", ver.dwMajorVersion, ver.dwMinorVersion);
+ sprintf(buf->release, "%d.%d", (int)ver.dwMajorVersion, (int)ver.dwMinorVersion);
const char *version_str= get_os_version_name(&ver);
if(version_str && version_str[0])
@@ -106,7 +113,7 @@ static int uname(struct utsname *buf)
{
/* Fallback for unknown versions, e.g "Windows <major_ver>.<minor_ver>" */
sprintf(buf->version, "Windows %d.%d%s",
- ver.dwMajorVersion, ver.dwMinorVersion,
+ (int)ver.dwMajorVersion, (int)ver.dwMinorVersion,
(ver.wProductType == VER_NT_WORKSTATION ? "" : " Server"));
}
diff --git a/plugin/fulltext/plugin_example.c b/plugin/fulltext/plugin_example.c
index 778918cb439..72d78db50f1 100644
--- a/plugin/fulltext/plugin_example.c
+++ b/plugin/fulltext/plugin_example.c
@@ -150,7 +150,7 @@ static void add_word(MYSQL_FTPARSER_PARAM *param, const char *word, size_t len)
MYSQL_FTPARSER_BOOLEAN_INFO bool_info=
{ FT_TOKEN_WORD, 0, 0, 0, 0, ' ', 0 };
- param->mysql_add_word(param, word, len, &bool_info);
+ param->mysql_add_word(param, word, (int)len, &bool_info);
}
/*
diff --git a/plugin/handler_socket/handlersocket/database.cpp b/plugin/handler_socket/handlersocket/database.cpp
index b21d58d243b..a76428b29d3 100644
--- a/plugin/handler_socket/handlersocket/database.cpp
+++ b/plugin/handler_socket/handlersocket/database.cpp
@@ -297,9 +297,9 @@ dbcontext::init_thread(const void *stack_bottom, volatile int& shutdown_flag)
#else
thd->options |= OPTION_BIN_LOG;
#endif
- safeFree(thd->db);
- thd->db = 0;
- thd->db = my_strdup("handlersocket", MYF(0));
+ safeFree((char*) thd->db.str);
+ thd->db.str= my_strdup("handlersocket", MYF(0));
+ thd->db.length= sizeof("handlersocket")-1;
}
thd->variables.option_bits |= OPTION_TABLE_LOCK;
my_pthread_setspecific_ptr(THR_THD, thd);
@@ -1005,8 +1005,9 @@ dbcontext::cmd_open(dbcallback_i& cb, const cmd_open_args& arg)
bool refresh = true;
const thr_lock_type lock_type = for_write_flag ? TL_WRITE : TL_READ;
#if MYSQL_VERSION_ID >= 50505
- tables.init_one_table(arg.dbn, strlen(arg.dbn), arg.tbl, strlen(arg.tbl),
- arg.tbl, lock_type);
+ LEX_CSTRING db_name= { arg.dbn, strlen(arg.dbn) };
+ LEX_CSTRING tbl_name= { arg.tbl, strlen(arg.tbl) };
+ tables.init_one_table(&db_name, &tbl_name, 0, lock_type);
tables.mdl_request.init(MDL_key::TABLE, arg.dbn, arg.tbl,
for_write_flag ? MDL_SHARED_WRITE : MDL_SHARED_READ, MDL_TRANSACTION);
Open_table_context ot_act(thd, 0);
diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc
deleted file mode 100644
index 975b2e13253..00000000000
--- a/plugin/semisync/semisync_master.cc
+++ /dev/null
@@ -1,1218 +0,0 @@
-/* Copyright (C) 2007 Google Inc.
- Copyright (c) 2008, 2013, Oracle and/or its affiliates.
- Copyright (c) 2011, 2016, 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
- 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-1301 USA */
-
-
-#include <my_global.h>
-#include "semisync_master.h"
-
-#define TIME_THOUSAND 1000
-#define TIME_MILLION 1000000
-#define TIME_BILLION 1000000000
-
-/* This indicates whether semi-synchronous replication is enabled. */
-char rpl_semi_sync_master_enabled;
-unsigned long rpl_semi_sync_master_wait_point =
- SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT;
-unsigned long rpl_semi_sync_master_timeout;
-unsigned long rpl_semi_sync_master_trace_level;
-char rpl_semi_sync_master_status = 0;
-unsigned long rpl_semi_sync_master_yes_transactions = 0;
-unsigned long rpl_semi_sync_master_no_transactions = 0;
-unsigned long rpl_semi_sync_master_off_times = 0;
-unsigned long rpl_semi_sync_master_timefunc_fails = 0;
-unsigned long rpl_semi_sync_master_wait_timeouts = 0;
-unsigned long rpl_semi_sync_master_wait_sessions = 0;
-unsigned long rpl_semi_sync_master_wait_pos_backtraverse = 0;
-unsigned long rpl_semi_sync_master_avg_trx_wait_time = 0;
-unsigned long long rpl_semi_sync_master_trx_wait_num = 0;
-unsigned long rpl_semi_sync_master_avg_net_wait_time = 0;
-unsigned long long rpl_semi_sync_master_net_wait_num = 0;
-unsigned long rpl_semi_sync_master_clients = 0;
-unsigned long long rpl_semi_sync_master_net_wait_time = 0;
-unsigned long long rpl_semi_sync_master_trx_wait_time = 0;
-char rpl_semi_sync_master_wait_no_slave = 1;
-
-
-static int getWaitTime(const struct timespec& start_ts);
-
-static unsigned long long timespec_to_usec(const struct timespec *ts)
-{
- return (unsigned long long) ts->tv_sec * TIME_MILLION + ts->tv_nsec / TIME_THOUSAND;
-}
-
-/*******************************************************************************
- *
- * <ActiveTranx> class : manage all active transaction nodes
- *
- ******************************************************************************/
-
-ActiveTranx::ActiveTranx(mysql_mutex_t *lock,
- unsigned long trace_level)
- : Trace(trace_level), allocator_(max_connections),
- num_entries_(max_connections << 1), /* Transaction hash table size
- * is set to double the size
- * of max_connections */
- lock_(lock)
-{
- /* No transactions are in the list initially. */
- trx_front_ = NULL;
- trx_rear_ = NULL;
-
- /* Create the hash table to find a transaction's ending event. */
- trx_htb_ = new TranxNode *[num_entries_];
- for (int idx = 0; idx < num_entries_; ++idx)
- trx_htb_[idx] = NULL;
-
- sql_print_information("Semi-sync replication initialized for transactions.");
-}
-
-ActiveTranx::~ActiveTranx()
-{
- delete [] trx_htb_;
- trx_htb_ = NULL;
- num_entries_ = 0;
-}
-
-unsigned int ActiveTranx::calc_hash(const unsigned char *key,
- unsigned int length)
-{
- unsigned int nr = 1, nr2 = 4;
-
- /* The hash implementation comes from calc_hashnr() in mysys/hash.c. */
- while (length--)
- {
- nr ^= (((nr & 63)+nr2)*((unsigned int) (unsigned char) *key++))+ (nr << 8);
- nr2 += 3;
- }
- return((unsigned int) nr);
-}
-
-unsigned int ActiveTranx::get_hash_value(const char *log_file_name,
- my_off_t log_file_pos)
-{
- unsigned int hash1 = calc_hash((const unsigned char *)log_file_name,
- strlen(log_file_name));
- unsigned int hash2 = calc_hash((const unsigned char *)(&log_file_pos),
- sizeof(log_file_pos));
-
- return (hash1 + hash2) % num_entries_;
-}
-
-int ActiveTranx::compare(const char *log_file_name1, my_off_t log_file_pos1,
- const char *log_file_name2, my_off_t log_file_pos2)
-{
- int cmp = strcmp(log_file_name1, log_file_name2);
-
- if (cmp != 0)
- return cmp;
-
- if (log_file_pos1 > log_file_pos2)
- return 1;
- else if (log_file_pos1 < log_file_pos2)
- return -1;
- return 0;
-}
-
-int ActiveTranx::insert_tranx_node(const char *log_file_name,
- my_off_t log_file_pos)
-{
- const char *kWho = "ActiveTranx:insert_tranx_node";
- TranxNode *ins_node;
- int result = 0;
- unsigned int hash_val;
-
- function_enter(kWho);
-
- ins_node = allocator_.allocate_node();
- if (!ins_node)
- {
- sql_print_error("%s: transaction node allocation failed for: (%s, %lu)",
- kWho, log_file_name, (unsigned long)log_file_pos);
- result = -1;
- goto l_end;
- }
-
- /* insert the binlog position in the active transaction list. */
- strncpy(ins_node->log_name_, log_file_name, FN_REFLEN-1);
- ins_node->log_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */
- ins_node->log_pos_ = log_file_pos;
-
- if (!trx_front_)
- {
- /* The list is empty. */
- trx_front_ = trx_rear_ = ins_node;
- }
- else
- {
- int cmp = compare(ins_node, trx_rear_);
- if (cmp > 0)
- {
- /* Compare with the tail first. If the transaction happens later in
- * binlog, then make it the new tail.
- */
- trx_rear_->next_ = ins_node;
- trx_rear_ = ins_node;
- }
- else
- {
- /* Otherwise, it is an error because the transaction should hold the
- * mysql_bin_log.LOCK_log when appending events.
- */
- sql_print_error("%s: binlog write out-of-order, tail (%s, %lu), "
- "new node (%s, %lu)", kWho,
- trx_rear_->log_name_, (unsigned long)trx_rear_->log_pos_,
- ins_node->log_name_, (unsigned long)ins_node->log_pos_);
- result = -1;
- goto l_end;
- }
- }
-
- hash_val = get_hash_value(ins_node->log_name_, ins_node->log_pos_);
- ins_node->hash_next_ = trx_htb_[hash_val];
- trx_htb_[hash_val] = ins_node;
-
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: insert (%s, %lu) in entry(%u)", kWho,
- ins_node->log_name_, (unsigned long)ins_node->log_pos_,
- hash_val);
-
- l_end:
- return function_exit(kWho, result);
-}
-
-bool ActiveTranx::is_tranx_end_pos(const char *log_file_name,
- my_off_t log_file_pos)
-{
- const char *kWho = "ActiveTranx::is_tranx_end_pos";
- function_enter(kWho);
-
- unsigned int hash_val = get_hash_value(log_file_name, log_file_pos);
- TranxNode *entry = trx_htb_[hash_val];
-
- while (entry != NULL)
- {
- if (compare(entry, log_file_name, log_file_pos) == 0)
- break;
-
- entry = entry->hash_next_;
- }
-
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: probe (%s, %lu) in entry(%u)", kWho,
- log_file_name, (unsigned long)log_file_pos, hash_val);
-
- function_exit(kWho, (entry != NULL));
- return (entry != NULL);
-}
-
-int ActiveTranx::clear_active_tranx_nodes(const char *log_file_name,
- my_off_t log_file_pos)
-{
- const char *kWho = "ActiveTranx::::clear_active_tranx_nodes";
- TranxNode *new_front;
-
- function_enter(kWho);
-
- if (log_file_name != NULL)
- {
- new_front = trx_front_;
-
- while (new_front)
- {
- if (compare(new_front, log_file_name, log_file_pos) > 0)
- break;
- new_front = new_front->next_;
- }
- }
- else
- {
- /* If log_file_name is NULL, clear everything. */
- new_front = NULL;
- }
-
- if (new_front == NULL)
- {
- /* No active transaction nodes after the call. */
-
- /* Clear the hash table. */
- memset(trx_htb_, 0, num_entries_ * sizeof(TranxNode *));
- allocator_.free_all_nodes();
-
- /* Clear the active transaction list. */
- if (trx_front_ != NULL)
- {
- trx_front_ = NULL;
- trx_rear_ = NULL;
- }
-
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: cleared all nodes", kWho);
- }
- else if (new_front != trx_front_)
- {
- TranxNode *curr_node, *next_node;
-
- /* Delete all transaction nodes before the confirmation point. */
- int n_frees = 0;
- curr_node = trx_front_;
- while (curr_node != new_front)
- {
- next_node = curr_node->next_;
- n_frees++;
-
- /* Remove the node from the hash table. */
- unsigned int hash_val = get_hash_value(curr_node->log_name_, curr_node->log_pos_);
- TranxNode **hash_ptr = &(trx_htb_[hash_val]);
- while ((*hash_ptr) != NULL)
- {
- if ((*hash_ptr) == curr_node)
- {
- (*hash_ptr) = curr_node->hash_next_;
- break;
- }
- hash_ptr = &((*hash_ptr)->hash_next_);
- }
-
- curr_node = next_node;
- }
-
- trx_front_ = new_front;
- allocator_.free_nodes_before(trx_front_);
-
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: cleared %d nodes back until pos (%s, %lu)",
- kWho, n_frees,
- trx_front_->log_name_, (unsigned long)trx_front_->log_pos_);
- }
-
- return function_exit(kWho, 0);
-}
-
-
-/*******************************************************************************
- *
- * <ReplSemiSyncMaster> class: the basic code layer for sync-replication master.
- * <ReplSemiSyncSlave> class: the basic code layer for sync-replication slave.
- *
- * The most important functions during semi-syn replication listed:
- *
- * Master:
- * . reportReplyBinlog(): called by the binlog dump thread when it receives
- * the slave's status information.
- * . updateSyncHeader(): based on transaction waiting information, decide
- * whether to request the slave to reply.
- * . writeTranxInBinlog(): called by the transaction thread when it finishes
- * writing all transaction events in binlog.
- * . commitTrx(): transaction thread wait for the slave reply.
- *
- * Slave:
- * . slaveReadSyncHeader(): read the semi-sync header from the master, get the
- * sync status and get the payload for events.
- * . slaveReply(): reply to the master about the replication progress.
- *
- ******************************************************************************/
-
-ReplSemiSyncMaster::ReplSemiSyncMaster()
- : active_tranxs_(NULL),
- init_done_(false),
- reply_file_name_inited_(false),
- reply_file_pos_(0L),
- wait_file_name_inited_(false),
- wait_file_pos_(0),
- master_enabled_(false),
- wait_timeout_(0L),
- state_(0)
-{
- strcpy(reply_file_name_, "");
- strcpy(wait_file_name_, "");
-}
-
-int ReplSemiSyncMaster::initObject()
-{
- int result;
- const char *kWho = "ReplSemiSyncMaster::initObject";
-
- if (init_done_)
- {
- fprintf(stderr, "%s called twice\n", kWho);
- return 1;
- }
- init_done_ = true;
-
- /* References to the parameter works after set_options(). */
- setWaitTimeout(rpl_semi_sync_master_timeout);
- setTraceLevel(rpl_semi_sync_master_trace_level);
-
- /* Mutex initialization can only be done after MY_INIT(). */
- mysql_mutex_init(key_ss_mutex_LOCK_binlog_,
- &LOCK_binlog_, MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_ss_cond_COND_binlog_send_,
- &COND_binlog_send_, NULL);
-
- if (rpl_semi_sync_master_enabled)
- result = enableMaster();
- else
- result = disableMaster();
-
- return result;
-}
-
-int ReplSemiSyncMaster::enableMaster()
-{
- int result = 0;
-
- /* Must have the lock when we do enable of disable. */
- lock();
-
- if (!getMasterEnabled())
- {
- active_tranxs_ = new ActiveTranx(&LOCK_binlog_, trace_level_);
- if (active_tranxs_ != NULL)
- {
- commit_file_name_inited_ = false;
- reply_file_name_inited_ = false;
- wait_file_name_inited_ = false;
-
- set_master_enabled(true);
- state_ = true;
- sql_print_information("Semi-sync replication enabled on the master.");
- }
- else
- {
- sql_print_error("Cannot allocate memory to enable semi-sync on the master.");
- result = -1;
- }
- }
-
- unlock();
-
- return result;
-}
-
-int ReplSemiSyncMaster::disableMaster()
-{
- /* Must have the lock when we do enable of disable. */
- lock();
-
- if (getMasterEnabled())
- {
- /* Switch off the semi-sync first so that waiting transaction will be
- * waken up.
- */
- switch_off();
-
- assert(active_tranxs_ != NULL);
- delete active_tranxs_;
- active_tranxs_ = NULL;
-
- reply_file_name_inited_ = false;
- wait_file_name_inited_ = false;
- commit_file_name_inited_ = false;
-
- set_master_enabled(false);
- sql_print_information("Semi-sync replication disabled on the master.");
- }
-
- unlock();
-
- return 0;
-}
-
-void ReplSemiSyncMaster::cleanup()
-{
- if (init_done_)
- {
- mysql_mutex_destroy(&LOCK_binlog_);
- mysql_cond_destroy(&COND_binlog_send_);
- init_done_= 0;
- }
-
- delete active_tranxs_;
-}
-
-void ReplSemiSyncMaster::lock()
-{
- mysql_mutex_lock(&LOCK_binlog_);
-}
-
-void ReplSemiSyncMaster::unlock()
-{
- mysql_mutex_unlock(&LOCK_binlog_);
-}
-
-void ReplSemiSyncMaster::cond_broadcast()
-{
- mysql_cond_broadcast(&COND_binlog_send_);
-}
-
-int ReplSemiSyncMaster::cond_timewait(struct timespec *wait_time)
-{
- const char *kWho = "ReplSemiSyncMaster::cond_timewait()";
- int wait_res;
-
- function_enter(kWho);
- wait_res= mysql_cond_timedwait(&COND_binlog_send_,
- &LOCK_binlog_, wait_time);
- return function_exit(kWho, wait_res);
-}
-
-void ReplSemiSyncMaster::add_slave()
-{
- lock();
- rpl_semi_sync_master_clients++;
- unlock();
-}
-
-void ReplSemiSyncMaster::remove_slave()
-{
- lock();
- rpl_semi_sync_master_clients--;
-
- /* Only switch off if semi-sync is enabled and is on */
- if (getMasterEnabled() && is_on())
- {
- /* If user has chosen not to wait if no semi-sync slave available
- and the last semi-sync slave exits, turn off semi-sync on master
- immediately.
- */
- if (!rpl_semi_sync_master_wait_no_slave &&
- rpl_semi_sync_master_clients == 0)
- switch_off();
- }
- unlock();
-}
-
-bool ReplSemiSyncMaster::is_semi_sync_slave()
-{
- int null_value;
- long long val= 0;
- get_user_var_int("rpl_semi_sync_slave", &val, &null_value);
- return val;
-}
-
-int ReplSemiSyncMaster::reportReplyBinlog(uint32 server_id,
- const char *log_file_name,
- my_off_t log_file_pos)
-{
- const char *kWho = "ReplSemiSyncMaster::reportReplyBinlog";
- int cmp;
- bool can_release_threads = false;
- bool need_copy_send_pos = true;
-
- if (!(getMasterEnabled()))
- return 0;
-
- function_enter(kWho);
-
- lock();
-
- /* This is the real check inside the mutex. */
- if (!getMasterEnabled())
- goto l_end;
-
- if (!is_on())
- /* We check to see whether we can switch semi-sync ON. */
- try_switch_on(server_id, log_file_name, log_file_pos);
-
- /* The position should increase monotonically, if there is only one
- * thread sending the binlog to the slave.
- * In reality, to improve the transaction availability, we allow multiple
- * sync replication slaves. So, if any one of them get the transaction,
- * the transaction session in the primary can move forward.
- */
- if (reply_file_name_inited_)
- {
- cmp = ActiveTranx::compare(log_file_name, log_file_pos,
- reply_file_name_, reply_file_pos_);
-
- /* If the requested position is behind the sending binlog position,
- * would not adjust sending binlog position.
- * We based on the assumption that there are multiple semi-sync slave,
- * and at least one of them shou/ld be up to date.
- * If all semi-sync slaves are behind, at least initially, the primary
- * can find the situation after the waiting timeout. After that, some
- * slaves should catch up quickly.
- */
- if (cmp < 0)
- {
- /* If the position is behind, do not copy it. */
- need_copy_send_pos = false;
- }
- }
-
- if (need_copy_send_pos)
- {
- strmake_buf(reply_file_name_, log_file_name);
- reply_file_pos_ = log_file_pos;
- reply_file_name_inited_ = true;
-
- /* Remove all active transaction nodes before this point. */
- assert(active_tranxs_ != NULL);
- active_tranxs_->clear_active_tranx_nodes(log_file_name, log_file_pos);
-
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: Got reply at (%s, %lu)", kWho,
- log_file_name, (unsigned long)log_file_pos);
- }
-
- if (rpl_semi_sync_master_wait_sessions > 0)
- {
- /* Let us check if some of the waiting threads doing a trx
- * commit can now proceed.
- */
- cmp = ActiveTranx::compare(reply_file_name_, reply_file_pos_,
- wait_file_name_, wait_file_pos_);
- if (cmp >= 0)
- {
- /* Yes, at least one waiting thread can now proceed:
- * let us release all waiting threads with a broadcast
- */
- can_release_threads = true;
- wait_file_name_inited_ = false;
- }
- }
-
- l_end:
- unlock();
-
- if (can_release_threads)
- {
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: signal all waiting threads.", kWho);
-
- cond_broadcast();
- }
-
- return function_exit(kWho, 0);
-}
-
-int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
- my_off_t trx_wait_binlog_pos)
-{
- const char *kWho = "ReplSemiSyncMaster::commitTrx";
-
- function_enter(kWho);
-
- if (getMasterEnabled() && trx_wait_binlog_name)
- {
- struct timespec start_ts;
- struct timespec abstime;
- int wait_result;
- PSI_stage_info old_stage;
-
- set_timespec(start_ts, 0);
-
- DEBUG_SYNC(current_thd, "rpl_semisync_master_commit_trx_before_lock");
- /* Acquire the mutex. */
- lock();
-
- /* This must be called after acquired the lock */
- THD_ENTER_COND(NULL, &COND_binlog_send_, &LOCK_binlog_,
- & stage_waiting_for_semi_sync_ack_from_slave,
- & old_stage);
-
- /* This is the real check inside the mutex. */
- if (!getMasterEnabled() || !is_on())
- goto l_end;
-
- if (trace_level_ & kTraceDetail)
- {
- sql_print_information("%s: wait pos (%s, %lu), repl(%d)\n", kWho,
- trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos,
- (int)is_on());
- }
-
- while (is_on() && !thd_killed(current_thd))
- {
- if (reply_file_name_inited_)
- {
- int cmp = ActiveTranx::compare(reply_file_name_, reply_file_pos_,
- trx_wait_binlog_name, trx_wait_binlog_pos);
- if (cmp >= 0)
- {
- /* We have already sent the relevant binlog to the slave: no need to
- * wait here.
- */
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: Binlog reply is ahead (%s, %lu),",
- kWho, reply_file_name_, (unsigned long)reply_file_pos_);
- break;
- }
- }
-
- /* Let us update the info about the minimum binlog position of waiting
- * threads.
- */
- if (wait_file_name_inited_)
- {
- int cmp = ActiveTranx::compare(trx_wait_binlog_name, trx_wait_binlog_pos,
- wait_file_name_, wait_file_pos_);
- if (cmp <= 0)
- {
- /* This thd has a lower position, let's update the minimum info. */
- strmake_buf(wait_file_name_, trx_wait_binlog_name);
- wait_file_pos_ = trx_wait_binlog_pos;
-
- rpl_semi_sync_master_wait_pos_backtraverse++;
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: move back wait position (%s, %lu),",
- kWho, wait_file_name_, (unsigned long)wait_file_pos_);
- }
- }
- else
- {
- strmake_buf(wait_file_name_, trx_wait_binlog_name);
- wait_file_pos_ = trx_wait_binlog_pos;
- wait_file_name_inited_ = true;
-
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: init wait position (%s, %lu),",
- kWho, wait_file_name_, (unsigned long)wait_file_pos_);
- }
-
- /* Calcuate the waiting period. */
- long diff_secs = (long) (wait_timeout_ / TIME_THOUSAND);
- long diff_nsecs = (long) ((wait_timeout_ % TIME_THOUSAND) * TIME_MILLION);
- long nsecs = start_ts.tv_nsec + diff_nsecs;
- abstime.tv_sec = start_ts.tv_sec + diff_secs + nsecs/TIME_BILLION;
- abstime.tv_nsec = nsecs % TIME_BILLION;
-
- /* In semi-synchronous replication, we wait until the binlog-dump
- * thread has received the reply on the relevant binlog segment from the
- * replication slave.
- *
- * Let us suspend this thread to wait on the condition;
- * when replication has progressed far enough, we will release
- * these waiting threads.
- */
- rpl_semi_sync_master_wait_sessions++;
-
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: wait %lu ms for binlog sent (%s, %lu)",
- kWho, wait_timeout_,
- wait_file_name_, (unsigned long)wait_file_pos_);
-
- wait_result = cond_timewait(&abstime);
- rpl_semi_sync_master_wait_sessions--;
-
- if (wait_result != 0)
- {
- /* This is a real wait timeout. */
- sql_print_warning("Timeout waiting for reply of binlog (file: %s, pos: %lu), "
- "semi-sync up to file %s, position %lu.",
- trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos,
- reply_file_name_, (unsigned long)reply_file_pos_);
- rpl_semi_sync_master_wait_timeouts++;
-
- /* switch semi-sync off */
- switch_off();
- }
- else
- {
- int wait_time;
-
- wait_time = getWaitTime(start_ts);
- if (wait_time < 0)
- {
- if (trace_level_ & kTraceGeneral)
- {
- sql_print_error("Replication semi-sync getWaitTime fail at "
- "wait position (%s, %lu)",
- trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos);
- }
- rpl_semi_sync_master_timefunc_fails++;
- }
- else
- {
- rpl_semi_sync_master_trx_wait_num++;
- rpl_semi_sync_master_trx_wait_time += wait_time;
- }
- }
- }
-
- /*
- At this point, the binlog file and position of this transaction
- must have been removed from ActiveTranx.
- active_tranxs_ may be NULL if someone disabled semi sync during
- cond_timewait()
- */
- assert(thd_killed(current_thd) || !active_tranxs_ ||
- !active_tranxs_->is_tranx_end_pos(trx_wait_binlog_name,
- trx_wait_binlog_pos));
-
- l_end:
- /* Update the status counter. */
- if (is_on())
- rpl_semi_sync_master_yes_transactions++;
- else
- rpl_semi_sync_master_no_transactions++;
-
- /* The lock held will be released by thd_exit_cond, so no need to
- call unlock() here */
- THD_EXIT_COND(NULL, & old_stage);
- }
-
- return function_exit(kWho, 0);
-}
-
-/* Indicate that semi-sync replication is OFF now.
- *
- * What should we do when it is disabled? The problem is that we want
- * the semi-sync replication enabled again when the slave catches up
- * later. But, it is not that easy to detect that the slave has caught
- * up. This is caused by the fact that MySQL's replication protocol is
- * asynchronous, meaning that if the master does not use the semi-sync
- * protocol, the slave would not send anything to the master.
- * Still, if the master is sending (N+1)-th event, we assume that it is
- * an indicator that the slave has received N-th event and earlier ones.
- *
- * If semi-sync is disabled, all transactions still update the wait
- * position with the last position in binlog. But no transactions will
- * wait for confirmations and the active transaction list would not be
- * maintained. In binlog dump thread, updateSyncHeader() checks whether
- * the current sending event catches up with last wait position. If it
- * does match, semi-sync will be switched on again.
- */
-int ReplSemiSyncMaster::switch_off()
-{
- const char *kWho = "ReplSemiSyncMaster::switch_off";
- int result;
-
- function_enter(kWho);
- state_ = false;
-
- /* Clear the active transaction list. */
- assert(active_tranxs_ != NULL);
- result = active_tranxs_->clear_active_tranx_nodes(NULL, 0);
-
- rpl_semi_sync_master_off_times++;
- wait_file_name_inited_ = false;
- reply_file_name_inited_ = false;
- sql_print_information("Semi-sync replication switched OFF.");
- cond_broadcast(); /* wake up all waiting threads */
-
- return function_exit(kWho, result);
-}
-
-int ReplSemiSyncMaster::try_switch_on(int server_id,
- const char *log_file_name,
- my_off_t log_file_pos)
-{
- const char *kWho = "ReplSemiSyncMaster::try_switch_on";
- bool semi_sync_on = false;
-
- function_enter(kWho);
-
- /* If the current sending event's position is larger than or equal to the
- * 'largest' commit transaction binlog position, the slave is already
- * catching up now and we can switch semi-sync on here.
- * If commit_file_name_inited_ indicates there are no recent transactions,
- * we can enable semi-sync immediately.
- */
- if (commit_file_name_inited_)
- {
- int cmp = ActiveTranx::compare(log_file_name, log_file_pos,
- commit_file_name_, commit_file_pos_);
- semi_sync_on = (cmp >= 0);
- }
- else
- {
- semi_sync_on = true;
- }
-
- if (semi_sync_on)
- {
- /* Switch semi-sync replication on. */
- state_ = true;
-
- sql_print_information("Semi-sync replication switched ON with slave (server_id: %d) "
- "at (%s, %lu)",
- server_id, log_file_name,
- (unsigned long)log_file_pos);
- }
-
- return function_exit(kWho, 0);
-}
-
-int ReplSemiSyncMaster::reserveSyncHeader(unsigned char *header,
- unsigned long size)
-{
- const char *kWho = "ReplSemiSyncMaster::reserveSyncHeader";
- function_enter(kWho);
-
- int hlen=0;
- if (!is_semi_sync_slave())
- {
- hlen= 0;
- }
- else
- {
- /* No enough space for the extra header, disable semi-sync master */
- if (sizeof(kSyncHeader) > size)
- {
- sql_print_warning("No enough space in the packet "
- "for semi-sync extra header, "
- "semi-sync replication disabled");
- disableMaster();
- return 0;
- }
-
- /* Set the magic number and the sync status. By default, no sync
- * is required.
- */
- memcpy(header, kSyncHeader, sizeof(kSyncHeader));
- hlen= sizeof(kSyncHeader);
- }
- return function_exit(kWho, hlen);
-}
-
-int ReplSemiSyncMaster::updateSyncHeader(unsigned char *packet,
- const char *log_file_name,
- my_off_t log_file_pos,
- uint32 server_id)
-{
- const char *kWho = "ReplSemiSyncMaster::updateSyncHeader";
- int cmp = 0;
- bool sync = false;
-
- /* If the semi-sync master is not enabled, or the slave is not a semi-sync
- * target, do not request replies from the slave.
- */
- if (!getMasterEnabled() || !is_semi_sync_slave())
- return 0;
-
- function_enter(kWho);
-
- lock();
-
- /* This is the real check inside the mutex. */
- if (!getMasterEnabled())
- goto l_end; // sync= false at this point in time
-
- if (is_on())
- {
- /* semi-sync is ON */
- /* sync= false; No sync unless a transaction is involved. */
-
- if (reply_file_name_inited_)
- {
- cmp = ActiveTranx::compare(log_file_name, log_file_pos,
- reply_file_name_, reply_file_pos_);
- if (cmp <= 0)
- {
- /* If we have already got the reply for the event, then we do
- * not need to sync the transaction again.
- */
- goto l_end;
- }
- }
-
- if (wait_file_name_inited_)
- {
- cmp = ActiveTranx::compare(log_file_name, log_file_pos,
- wait_file_name_, wait_file_pos_);
- }
- else
- {
- cmp = 1;
- }
-
- /* If we are already waiting for some transaction replies which
- * are later in binlog, do not wait for this one event.
- */
- if (cmp >= 0)
- {
- /*
- * We only wait if the event is a transaction's ending event.
- */
- assert(active_tranxs_ != NULL);
- sync = active_tranxs_->is_tranx_end_pos(log_file_name,
- log_file_pos);
- }
- }
- else
- {
- if (commit_file_name_inited_)
- {
- int cmp = ActiveTranx::compare(log_file_name, log_file_pos,
- commit_file_name_, commit_file_pos_);
- sync = (cmp >= 0);
- }
- else
- {
- sync = true;
- }
- }
-
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: server(%d), (%s, %lu) sync(%d), repl(%d)",
- kWho, server_id, log_file_name,
- (unsigned long)log_file_pos, sync, (int)is_on());
-
- l_end:
- unlock();
-
- /* We do not need to clear sync flag because we set it to 0 when we
- * reserve the packet header.
- */
- if (sync)
- {
- (packet)[2] = kPacketFlagSync;
- }
-
- return function_exit(kWho, 0);
-}
-
-int ReplSemiSyncMaster::writeTranxInBinlog(const char* log_file_name,
- my_off_t log_file_pos)
-{
- const char *kWho = "ReplSemiSyncMaster::writeTranxInBinlog";
- int result = 0;
-
- function_enter(kWho);
-
- lock();
-
- /* This is the real check inside the mutex. */
- if (!getMasterEnabled())
- goto l_end;
-
- /* Update the 'largest' transaction commit position seen so far even
- * though semi-sync is switched off.
- * It is much better that we update commit_file_* here, instead of
- * inside commitTrx(). This is mostly because updateSyncHeader()
- * will watch for commit_file_* to decide whether to switch semi-sync
- * on. The detailed reason is explained in function updateSyncHeader().
- */
- if (commit_file_name_inited_)
- {
- int cmp = ActiveTranx::compare(log_file_name, log_file_pos,
- commit_file_name_, commit_file_pos_);
- if (cmp > 0)
- {
- /* This is a larger position, let's update the maximum info. */
- strncpy(commit_file_name_, log_file_name, FN_REFLEN-1);
- commit_file_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */
- commit_file_pos_ = log_file_pos;
- }
- }
- else
- {
- strncpy(commit_file_name_, log_file_name, FN_REFLEN-1);
- commit_file_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */
- commit_file_pos_ = log_file_pos;
- commit_file_name_inited_ = true;
- }
-
- if (is_on())
- {
- assert(active_tranxs_ != NULL);
- if(active_tranxs_->insert_tranx_node(log_file_name, log_file_pos))
- {
- /*
- if insert tranx_node failed, print a warning message
- and turn off semi-sync
- */
- sql_print_warning("Semi-sync failed to insert tranx_node for binlog file: %s, position: %lu",
- log_file_name, (ulong)log_file_pos);
- switch_off();
- }
- }
-
- l_end:
- unlock();
-
- return function_exit(kWho, result);
-}
-
-int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id,
- const char *event_buf)
-{
- const char *kWho = "ReplSemiSyncMaster::readSlaveReply";
- const unsigned char *packet;
- char log_file_name[FN_REFLEN];
- my_off_t log_file_pos;
- ulong log_file_len = 0;
- ulong packet_len;
- int result = -1;
- struct timespec start_ts;
- ulong trc_level = trace_level_;
- LINT_INIT_STRUCT(start_ts);
-
- function_enter(kWho);
-
- assert((unsigned char)event_buf[1] == kPacketMagicNum);
- if ((unsigned char)event_buf[2] != kPacketFlagSync)
- {
- /* current event does not require reply */
- result = 0;
- goto l_end;
- }
-
- if (trc_level & kTraceNetWait)
- set_timespec(start_ts, 0);
-
- /* We flush to make sure that the current event is sent to the network,
- * instead of being buffered in the TCP/IP stack.
- */
- if (net_flush(net))
- {
- sql_print_error("Semi-sync master failed on net_flush() "
- "before waiting for slave reply");
- goto l_end;
- }
-
- net_clear(net, 0);
- if (trc_level & kTraceDetail)
- sql_print_information("%s: Wait for replica's reply", kWho);
-
- /* Wait for the network here. Though binlog dump thread can indefinitely wait
- * here, transactions would not wait indefintely.
- * Transactions wait on binlog replies detected by binlog dump threads. If
- * binlog dump threads wait too long, transactions will timeout and continue.
- */
- packet_len = my_net_read(net);
-
- if (trc_level & kTraceNetWait)
- {
- int wait_time = getWaitTime(start_ts);
- if (wait_time < 0)
- {
- sql_print_error("Semi-sync master wait for reply "
- "fail to get wait time.");
- rpl_semi_sync_master_timefunc_fails++;
- }
- else
- {
- rpl_semi_sync_master_net_wait_num++;
- rpl_semi_sync_master_net_wait_time += wait_time;
- }
- }
-
- if (packet_len == packet_error || packet_len < REPLY_BINLOG_NAME_OFFSET)
- {
- if (packet_len == packet_error)
- sql_print_error("Read semi-sync reply network error: %s (errno: %d)",
- net->last_error, net->last_errno);
- else
- sql_print_error("Read semi-sync reply length error: %s (errno: %d)",
- net->last_error, net->last_errno);
- goto l_end;
- }
-
- packet = net->read_pos;
- if (packet[REPLY_MAGIC_NUM_OFFSET] != ReplSemiSyncMaster::kPacketMagicNum)
- {
- sql_print_error("Read semi-sync reply magic number error");
- goto l_end;
- }
-
- log_file_pos = uint8korr(packet + REPLY_BINLOG_POS_OFFSET);
- log_file_len = packet_len - REPLY_BINLOG_NAME_OFFSET;
- if (log_file_len >= FN_REFLEN)
- {
- sql_print_error("Read semi-sync reply binlog file length too large");
- goto l_end;
- }
- strncpy(log_file_name, (const char*)packet + REPLY_BINLOG_NAME_OFFSET, log_file_len);
- log_file_name[log_file_len] = 0;
-
- if (trc_level & kTraceDetail)
- sql_print_information("%s: Got reply (%s, %lu)",
- kWho, log_file_name, (ulong)log_file_pos);
-
- result = reportReplyBinlog(server_id, log_file_name, log_file_pos);
-
- l_end:
- return function_exit(kWho, result);
-}
-
-
-int ReplSemiSyncMaster::resetMaster()
-{
- const char *kWho = "ReplSemiSyncMaster::resetMaster";
- int result = 0;
-
- function_enter(kWho);
-
-
- lock();
-
- state_ = getMasterEnabled()? 1 : 0;
-
- wait_file_name_inited_ = false;
- reply_file_name_inited_ = false;
- commit_file_name_inited_ = false;
-
- rpl_semi_sync_master_yes_transactions = 0;
- rpl_semi_sync_master_no_transactions = 0;
- rpl_semi_sync_master_off_times = 0;
- rpl_semi_sync_master_timefunc_fails = 0;
- rpl_semi_sync_master_wait_sessions = 0;
- rpl_semi_sync_master_wait_pos_backtraverse = 0;
- rpl_semi_sync_master_trx_wait_num = 0;
- rpl_semi_sync_master_trx_wait_time = 0;
- rpl_semi_sync_master_net_wait_num = 0;
- rpl_semi_sync_master_net_wait_time = 0;
-
- unlock();
-
- return function_exit(kWho, result);
-}
-
-void ReplSemiSyncMaster::setExportStats()
-{
- lock();
-
- rpl_semi_sync_master_status = state_;
- rpl_semi_sync_master_avg_trx_wait_time=
- ((rpl_semi_sync_master_trx_wait_num) ?
- (unsigned long)((double)rpl_semi_sync_master_trx_wait_time /
- ((double)rpl_semi_sync_master_trx_wait_num)) : 0);
- rpl_semi_sync_master_avg_net_wait_time=
- ((rpl_semi_sync_master_net_wait_num) ?
- (unsigned long)((double)rpl_semi_sync_master_net_wait_time /
- ((double)rpl_semi_sync_master_net_wait_num)) : 0);
-
- unlock();
-}
-
-/* Get the waiting time given the wait's staring time.
- *
- * Return:
- * >= 0: the waiting time in microsecons(us)
- * < 0: error in get time or time back traverse
- */
-static int getWaitTime(const struct timespec& start_ts)
-{
- unsigned long long start_usecs, end_usecs;
- struct timespec end_ts;
-
- /* Starting time in microseconds(us). */
- start_usecs = timespec_to_usec(&start_ts);
-
- /* Get the wait time interval. */
- set_timespec(end_ts, 0);
-
- /* Ending time in microseconds(us). */
- end_usecs = timespec_to_usec(&end_ts);
-
- if (end_usecs < start_usecs)
- return -1;
-
- return (int)(end_usecs - start_usecs);
-}
diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc
deleted file mode 100644
index b46cf5d79cb..00000000000
--- a/plugin/semisync/semisync_master_plugin.cc
+++ /dev/null
@@ -1,496 +0,0 @@
-/* Copyright (C) 2007 Google Inc.
- Copyright (c) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
- Use is subject to license terms.
-
- This program is free 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-1301 USA */
-
-
-#include <my_global.h>
-#include "semisync_master.h"
-#include "sql_class.h" // THD
-
-static ReplSemiSyncMaster repl_semisync;
-
-C_MODE_START
-
-int repl_semi_report_binlog_update(Binlog_storage_param *param,
- const char *log_file,
- my_off_t log_pos, uint32 flags)
-{
- int error= 0;
-
- if (repl_semisync.getMasterEnabled())
- {
- /*
- Let us store the binlog file name and the position, so that
- we know how long to wait for the binlog to the replicated to
- the slave in synchronous replication.
- */
- error= repl_semisync.writeTranxInBinlog(log_file,
- log_pos);
- }
-
- return error;
-}
-
-int repl_semi_request_commit(Trans_param *param)
-{
- return 0;
-}
-
-int repl_semi_report_binlog_sync(Binlog_storage_param *param,
- const char *log_file,
- my_off_t log_pos, uint32 flags)
-{
- int error= 0;
- if (rpl_semi_sync_master_wait_point ==
- SEMI_SYNC_MASTER_WAIT_POINT_AFTER_BINLOG_SYNC)
- {
- error = repl_semisync.commitTrx(log_file, log_pos);
- }
-
- return error;
-}
-
-int repl_semi_report_commit(Trans_param *param)
-{
- if (rpl_semi_sync_master_wait_point !=
- SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT)
- {
- return 0;
- }
-
- bool is_real_trans= param->flags & TRANS_IS_REAL_TRANS;
-
- if (is_real_trans && param->log_pos)
- {
- const char *binlog_name= param->log_file;
- return repl_semisync.commitTrx(binlog_name, param->log_pos);
- }
- return 0;
-}
-
-int repl_semi_report_rollback(Trans_param *param)
-{
- return repl_semi_report_commit(param);
-}
-
-int repl_semi_binlog_dump_start(Binlog_transmit_param *param,
- const char *log_file,
- my_off_t log_pos)
-{
- bool semi_sync_slave= repl_semisync.is_semi_sync_slave();
-
- if (semi_sync_slave)
- {
- /* One more semi-sync slave */
- repl_semisync.add_slave();
-
- /*
- Let's assume this semi-sync slave has already received all
- binlog events before the filename and position it requests.
- */
- repl_semisync.reportReplyBinlog(param->server_id, log_file, log_pos);
- }
- sql_print_information("Start %s binlog_dump to slave (server_id: %d), pos(%s, %lu)",
- semi_sync_slave ? "semi-sync" : "asynchronous",
- param->server_id, log_file, (unsigned long)log_pos);
-
- return 0;
-}
-
-int repl_semi_binlog_dump_end(Binlog_transmit_param *param)
-{
- bool semi_sync_slave= repl_semisync.is_semi_sync_slave();
-
- sql_print_information("Stop %s binlog_dump to slave (server_id: %d)",
- semi_sync_slave ? "semi-sync" : "asynchronous",
- param->server_id);
- if (semi_sync_slave)
- {
- /* One less semi-sync slave */
- repl_semisync.remove_slave();
- }
- return 0;
-}
-
-int repl_semi_reserve_header(Binlog_transmit_param *param,
- unsigned char *header,
- unsigned long size, unsigned long *len)
-{
- *len += repl_semisync.reserveSyncHeader(header, size);
- return 0;
-}
-
-int repl_semi_before_send_event(Binlog_transmit_param *param,
- unsigned char *packet, unsigned long len,
- const char *log_file, my_off_t log_pos)
-{
- return repl_semisync.updateSyncHeader(packet,
- log_file,
- log_pos,
- param->server_id);
-}
-
-int repl_semi_after_send_event(Binlog_transmit_param *param,
- const char *event_buf, unsigned long len)
-{
- if (repl_semisync.is_semi_sync_slave())
- {
- THD *thd= current_thd;
- /*
- Possible errors in reading slave reply are ignored deliberately
- because we do not want dump thread to quit on this. Error
- messages are already reported.
- */
- (void) repl_semisync.readSlaveReply(&thd->net,
- param->server_id, event_buf);
- thd->clear_error();
- }
- return 0;
-}
-
-int repl_semi_reset_master(Binlog_transmit_param *param)
-{
- if (repl_semisync.resetMaster())
- return 1;
- return 0;
-}
-
-C_MODE_END
-
-/*
- semisync system variables
- */
-static void fix_rpl_semi_sync_master_timeout(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val);
-
-static void fix_rpl_semi_sync_master_trace_level(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val);
-
-static void fix_rpl_semi_sync_master_enabled(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val);
-
-static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_master_enabled,
- PLUGIN_VAR_OPCMDARG,
- "Enable semi-synchronous replication master (disabled by default). ",
- NULL, // check
- &fix_rpl_semi_sync_master_enabled, // update
- 0);
-
-/* NOTE: must match order of rpl_semi_sync_master_wait_point_t */
-static const char *rpl_semi_sync_master_wait_point_names[] =
-{
- "AFTER_SYNC",
- "AFTER_COMMIT",
- NullS
-};
-
-static TYPELIB rpl_semi_sync_master_wait_point_typelib =
-{
- array_elements(rpl_semi_sync_master_wait_point_names) - 1,
- "",
- rpl_semi_sync_master_wait_point_names,
- NULL
-};
-
-static MYSQL_SYSVAR_ENUM(
- wait_point,
- rpl_semi_sync_master_wait_point,
- PLUGIN_VAR_RQCMDARG,
- "Should transaction wait for semi-sync ack after having synced binlog, "
- "or after having committed in storeage engine.",
- NULL, // check
- NULL, // update
- SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT,
- &rpl_semi_sync_master_wait_point_typelib);
-
-static MYSQL_SYSVAR_ULONG(timeout, rpl_semi_sync_master_timeout,
- PLUGIN_VAR_OPCMDARG,
- "The timeout value (in ms) for semi-synchronous replication in the master",
- NULL, // check
- fix_rpl_semi_sync_master_timeout, // update
- 10000, 0, ~0UL, 1);
-
-static MYSQL_SYSVAR_BOOL(wait_no_slave, rpl_semi_sync_master_wait_no_slave,
- PLUGIN_VAR_OPCMDARG,
- "Wait until timeout when no semi-synchronous replication slave available (enabled by default). ",
- NULL, // check
- NULL, // update
- 1);
-
-static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_master_trace_level,
- PLUGIN_VAR_OPCMDARG,
- "The tracing level for semi-sync replication.",
- NULL, // check
- &fix_rpl_semi_sync_master_trace_level, // update
- 32, 0, ~0UL, 1);
-
-static SYS_VAR* semi_sync_master_system_vars[]= {
- MYSQL_SYSVAR(enabled),
- MYSQL_SYSVAR(wait_point),
- MYSQL_SYSVAR(timeout),
- MYSQL_SYSVAR(wait_no_slave),
- MYSQL_SYSVAR(trace_level),
- NULL,
-};
-
-
-static void fix_rpl_semi_sync_master_timeout(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val)
-{
- *(unsigned long *)ptr= *(unsigned long *)val;
- repl_semisync.setWaitTimeout(rpl_semi_sync_master_timeout);
- return;
-}
-
-static void fix_rpl_semi_sync_master_trace_level(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val)
-{
- *(unsigned long *)ptr= *(unsigned long *)val;
- repl_semisync.setTraceLevel(rpl_semi_sync_master_trace_level);
- return;
-}
-
-static void fix_rpl_semi_sync_master_enabled(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val)
-{
- *(char *)ptr= *(char *)val;
- if (rpl_semi_sync_master_enabled)
- {
- if (repl_semisync.enableMaster() != 0)
- rpl_semi_sync_master_enabled = false;
- }
- else
- {
- if (repl_semisync.disableMaster() != 0)
- rpl_semi_sync_master_enabled = true;
- }
-
- return;
-}
-
-Trans_observer trans_observer = {
- sizeof(Trans_observer), // len
-
- repl_semi_report_commit, // after_commit
- repl_semi_report_rollback, // after_rollback
-};
-
-Binlog_storage_observer storage_observer = {
- sizeof(Binlog_storage_observer), // len
-
- repl_semi_report_binlog_update, // report_update
- repl_semi_report_binlog_sync, // after_sync
-};
-
-Binlog_transmit_observer transmit_observer = {
- sizeof(Binlog_transmit_observer), // len
-
- repl_semi_binlog_dump_start, // start
- repl_semi_binlog_dump_end, // stop
- repl_semi_reserve_header, // reserve_header
- repl_semi_before_send_event, // before_send_event
- repl_semi_after_send_event, // after_send_event
- repl_semi_reset_master, // reset
-};
-
-
-#define SHOW_FNAME(name) \
- rpl_semi_sync_master_show_##name
-
-#define DEF_SHOW_FUNC(name, show_type) \
- static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, char *buff) \
- { \
- repl_semisync.setExportStats(); \
- var->type= show_type; \
- var->value= (char *)&rpl_semi_sync_master_##name; \
- return 0; \
- }
-
-DEF_SHOW_FUNC(status, SHOW_BOOL)
-DEF_SHOW_FUNC(clients, SHOW_LONG)
-DEF_SHOW_FUNC(wait_sessions, SHOW_LONG)
-DEF_SHOW_FUNC(trx_wait_time, SHOW_LONGLONG)
-DEF_SHOW_FUNC(trx_wait_num, SHOW_LONGLONG)
-DEF_SHOW_FUNC(net_wait_time, SHOW_LONGLONG)
-DEF_SHOW_FUNC(net_wait_num, SHOW_LONGLONG)
-DEF_SHOW_FUNC(avg_net_wait_time, SHOW_LONG)
-DEF_SHOW_FUNC(avg_trx_wait_time, SHOW_LONG)
-
-
-/* plugin status variables */
-static SHOW_VAR semi_sync_master_status_vars[]= {
- {"Rpl_semi_sync_master_status",
- (char*) &SHOW_FNAME(status),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_clients",
- (char*) &SHOW_FNAME(clients),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_yes_tx",
- (char*) &rpl_semi_sync_master_yes_transactions,
- SHOW_LONG},
- {"Rpl_semi_sync_master_no_tx",
- (char*) &rpl_semi_sync_master_no_transactions,
- SHOW_LONG},
- {"Rpl_semi_sync_master_wait_sessions",
- (char*) &SHOW_FNAME(wait_sessions),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_no_times",
- (char*) &rpl_semi_sync_master_off_times,
- SHOW_LONG},
- {"Rpl_semi_sync_master_timefunc_failures",
- (char*) &rpl_semi_sync_master_timefunc_fails,
- SHOW_LONG},
- {"Rpl_semi_sync_master_wait_pos_backtraverse",
- (char*) &rpl_semi_sync_master_wait_pos_backtraverse,
- SHOW_LONG},
- {"Rpl_semi_sync_master_tx_wait_time",
- (char*) &SHOW_FNAME(trx_wait_time),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_tx_waits",
- (char*) &SHOW_FNAME(trx_wait_num),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_tx_avg_wait_time",
- (char*) &SHOW_FNAME(avg_trx_wait_time),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_net_wait_time",
- (char*) &SHOW_FNAME(net_wait_time),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_net_waits",
- (char*) &SHOW_FNAME(net_wait_num),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_net_avg_wait_time",
- (char*) &SHOW_FNAME(avg_net_wait_time),
- SHOW_SIMPLE_FUNC},
- {NULL, NULL, SHOW_LONG},
-};
-
-#ifdef HAVE_PSI_INTERFACE
-PSI_mutex_key key_ss_mutex_LOCK_binlog_;
-
-static PSI_mutex_info all_semisync_mutexes[]=
-{
- { &key_ss_mutex_LOCK_binlog_, "LOCK_binlog_", 0}
-};
-
-PSI_cond_key key_ss_cond_COND_binlog_send_;
-
-static PSI_cond_info all_semisync_conds[]=
-{
- { &key_ss_cond_COND_binlog_send_, "COND_binlog_send_", 0}
-};
-#endif /* HAVE_PSI_INTERFACE */
-
-PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave=
-{ 0, "Waiting for semi-sync ACK from slave", 0};
-
-#ifdef HAVE_PSI_INTERFACE
-PSI_stage_info *all_semisync_stages[]=
-{
- & stage_waiting_for_semi_sync_ack_from_slave
-};
-
-static void init_semisync_psi_keys(void)
-{
- const char* category= "semisync";
- int count;
-
- count= array_elements(all_semisync_mutexes);
- mysql_mutex_register(category, all_semisync_mutexes, count);
-
- count= array_elements(all_semisync_conds);
- mysql_cond_register(category, all_semisync_conds, count);
-
- count= array_elements(all_semisync_stages);
- mysql_stage_register(category, all_semisync_stages, count);
-}
-#endif /* HAVE_PSI_INTERFACE */
-
-static int semi_sync_master_plugin_init(void *p)
-{
-#ifdef HAVE_PSI_INTERFACE
- init_semisync_psi_keys();
-#endif
-
- if (repl_semisync.initObject())
- return 1;
- if (register_trans_observer(&trans_observer, p))
- return 1;
- if (register_binlog_storage_observer(&storage_observer, p))
- return 1;
- if (register_binlog_transmit_observer(&transmit_observer, p))
- return 1;
- return 0;
-}
-
-static int semi_sync_master_plugin_deinit(void *p)
-{
- if (unregister_trans_observer(&trans_observer, p))
- {
- sql_print_error("unregister_trans_observer failed");
- return 1;
- }
- if (unregister_binlog_storage_observer(&storage_observer, p))
- {
- sql_print_error("unregister_binlog_storage_observer failed");
- return 1;
- }
- if (unregister_binlog_transmit_observer(&transmit_observer, p))
- {
- sql_print_error("unregister_binlog_transmit_observer failed");
- return 1;
- }
- repl_semisync.cleanup();
- sql_print_information("unregister_replicator OK");
- return 0;
-}
-
-struct Mysql_replication semi_sync_master_plugin= {
- MYSQL_REPLICATION_INTERFACE_VERSION
-};
-
-/*
- Plugin library descriptor
-*/
-maria_declare_plugin(semisync_master)
-{
- MYSQL_REPLICATION_PLUGIN,
- &semi_sync_master_plugin,
- "rpl_semi_sync_master",
- "He Zhenxing",
- "Semi-synchronous replication master",
- PLUGIN_LICENSE_GPL,
- semi_sync_master_plugin_init, /* Plugin Init */
- semi_sync_master_plugin_deinit, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
- semi_sync_master_status_vars, /* status variables */
- semi_sync_master_system_vars, /* system variables */
- "1.0",
- MariaDB_PLUGIN_MATURITY_STABLE
-}
-maria_declare_plugin_end;
-
diff --git a/plugin/semisync/semisync_slave.cc b/plugin/semisync/semisync_slave.cc
deleted file mode 100644
index ff8a40aafac..00000000000
--- a/plugin/semisync/semisync_slave.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-/* Copyright (c) 2008 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
-
- This program is free 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-1301 USA */
-
-
-#include <my_global.h>
-#include "semisync_slave.h"
-
-char rpl_semi_sync_slave_enabled;
-char rpl_semi_sync_slave_status= 0;
-unsigned long rpl_semi_sync_slave_trace_level;
-
-int ReplSemiSyncSlave::initObject()
-{
- int result= 0;
- const char *kWho = "ReplSemiSyncSlave::initObject";
-
- if (init_done_)
- {
- fprintf(stderr, "%s called twice\n", kWho);
- return 1;
- }
- init_done_ = true;
-
- /* References to the parameter works after set_options(). */
- setSlaveEnabled(rpl_semi_sync_slave_enabled);
- setTraceLevel(rpl_semi_sync_slave_trace_level);
-
- return result;
-}
-
-int ReplSemiSyncSlave::slaveReadSyncHeader(const char *header,
- unsigned long total_len,
- bool *need_reply,
- const char **payload,
- unsigned long *payload_len)
-{
- const char *kWho = "ReplSemiSyncSlave::slaveReadSyncHeader";
- int read_res = 0;
- function_enter(kWho);
-
- if ((unsigned char)(header[0]) == kPacketMagicNum)
- {
- *need_reply = (header[1] & kPacketFlagSync);
- *payload_len = total_len - 2;
- *payload = header + 2;
-
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: reply - %d", kWho, *need_reply);
- }
- else
- {
- sql_print_error("Missing magic number for semi-sync packet, packet "
- "len: %lu", total_len);
- read_res = -1;
- }
-
- return function_exit(kWho, read_res);
-}
-
-int ReplSemiSyncSlave::slaveStart(Binlog_relay_IO_param *param)
-{
- bool semi_sync= getSlaveEnabled();
-
- sql_print_information("Slave I/O thread: Start %s replication to\
- master '%s@%s:%d' in log '%s' at position %lu",
- semi_sync ? "semi-sync" : "asynchronous",
- param->user, param->host, param->port,
- param->master_log_name[0] ? param->master_log_name : "FIRST",
- (unsigned long)param->master_log_pos);
-
- if (semi_sync && !rpl_semi_sync_slave_status)
- rpl_semi_sync_slave_status= 1;
- return 0;
-}
-
-int ReplSemiSyncSlave::slaveStop(Binlog_relay_IO_param *param)
-{
- if (rpl_semi_sync_slave_status)
- rpl_semi_sync_slave_status= 0;
- if (mysql_reply)
- mysql_close(mysql_reply);
- mysql_reply= 0;
- return 0;
-}
-
-int ReplSemiSyncSlave::slaveReply(MYSQL *mysql,
- const char *binlog_filename,
- my_off_t binlog_filepos)
-{
- const char *kWho = "ReplSemiSyncSlave::slaveReply";
- NET *net= &mysql->net;
- uchar reply_buffer[REPLY_MAGIC_NUM_LEN
- + REPLY_BINLOG_POS_LEN
- + REPLY_BINLOG_NAME_LEN];
- int reply_res, name_len = strlen(binlog_filename);
-
- function_enter(kWho);
-
- /* Prepare the buffer of the reply. */
- reply_buffer[REPLY_MAGIC_NUM_OFFSET] = kPacketMagicNum;
- int8store(reply_buffer + REPLY_BINLOG_POS_OFFSET, binlog_filepos);
- memcpy(reply_buffer + REPLY_BINLOG_NAME_OFFSET,
- binlog_filename,
- name_len + 1 /* including trailing '\0' */);
-
- if (trace_level_ & kTraceDetail)
- sql_print_information("%s: reply (%s, %lu)", kWho,
- binlog_filename, (ulong)binlog_filepos);
-
- net_clear(net, 0);
- /* Send the reply. */
- reply_res = my_net_write(net, reply_buffer,
- name_len + REPLY_BINLOG_NAME_OFFSET);
- if (!reply_res)
- {
- reply_res = net_flush(net);
- if (reply_res)
- sql_print_error("Semi-sync slave net_flush() reply failed");
- }
- else
- {
- sql_print_error("Semi-sync slave send reply failed: %s (%d)",
- net->last_error, net->last_errno);
- }
-
- return function_exit(kWho, reply_res);
-}
diff --git a/plugin/semisync/semisync_slave.h b/plugin/semisync/semisync_slave.h
deleted file mode 100644
index 1bf8cf31972..00000000000
--- a/plugin/semisync/semisync_slave.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (c) 2006 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
-
- This program is free 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-1301 USA */
-
-
-#ifndef SEMISYNC_SLAVE_H
-#define SEMISYNC_SLAVE_H
-
-#include "semisync.h"
-
-/**
- The extension class for the slave of semi-synchronous replication
-*/
-class ReplSemiSyncSlave
- :public ReplSemiSyncBase {
-public:
- ReplSemiSyncSlave()
- :slave_enabled_(false)
- {}
- ~ReplSemiSyncSlave() {}
-
- void setTraceLevel(unsigned long trace_level) {
- trace_level_ = trace_level;
- }
-
- /* Initialize this class after MySQL parameters are initialized. this
- * function should be called once at bootstrap time.
- */
- int initObject();
-
- bool getSlaveEnabled() {
- return slave_enabled_;
- }
- void setSlaveEnabled(bool enabled) {
- slave_enabled_ = enabled;
- }
-
- /* A slave reads the semi-sync packet header and separate the metadata
- * from the payload data.
- *
- * Input:
- * header - (IN) packet header pointer
- * total_len - (IN) total packet length: metadata + payload
- * need_reply - (IN) whether the master is waiting for the reply
- * payload - (IN) payload: the replication event
- * payload_len - (IN) payload length
- *
- * Return:
- * 0: success; non-zero: error
- */
- int slaveReadSyncHeader(const char *header, unsigned long total_len, bool *need_reply,
- const char **payload, unsigned long *payload_len);
-
- /* A slave replies to the master indicating its replication process. It
- * indicates that the slave has received all events before the specified
- * binlog position.
- *
- * Input:
- * mysql - (IN) the mysql network connection
- * binlog_filename - (IN) the reply point's binlog file name
- * binlog_filepos - (IN) the reply point's binlog file offset
- *
- * Return:
- * 0: success; non-zero: error
- */
- int slaveReply(MYSQL *mysql, const char *binlog_filename,
- my_off_t binlog_filepos);
-
- int slaveStart(Binlog_relay_IO_param *param);
- int slaveStop(Binlog_relay_IO_param *param);
-
-private:
- /* True when initObject has been called */
- bool init_done_;
- bool slave_enabled_; /* semi-sycn is enabled on the slave */
- MYSQL *mysql_reply; /* connection to send reply */
-};
-
-
-/* System and status variables for the slave component */
-extern char rpl_semi_sync_slave_enabled;
-extern unsigned long rpl_semi_sync_slave_trace_level;
-extern char rpl_semi_sync_slave_status;
-
-#endif /* SEMISYNC_SLAVE_H */
diff --git a/plugin/semisync/semisync_slave_plugin.cc b/plugin/semisync/semisync_slave_plugin.cc
deleted file mode 100644
index df9e8e10429..00000000000
--- a/plugin/semisync/semisync_slave_plugin.cc
+++ /dev/null
@@ -1,234 +0,0 @@
-/* Copyright (C) 2007 Google Inc.
- Copyright (C) 2008 MySQL AB
- Use is subject to license terms
-
- This program is free 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-1301 USA */
-
-
-#include <my_global.h>
-#include "semisync_slave.h"
-#include <mysql.h>
-
-static ReplSemiSyncSlave repl_semisync;
-
-/*
- indicate whether or not the slave should send a reply to the master.
-
- This is set to true in repl_semi_slave_read_event if the current
- event read is the last event of a transaction. And the value is
- checked in repl_semi_slave_queue_event.
-*/
-bool semi_sync_need_reply= false;
-
-C_MODE_START
-
-int repl_semi_reset_slave(Binlog_relay_IO_param *param)
-{
- // TODO: reset semi-sync slave status here
- return 0;
-}
-
-int repl_semi_slave_request_dump(Binlog_relay_IO_param *param,
- uint32 flags)
-{
- MYSQL *mysql= param->mysql;
- MYSQL_RES *res= 0;
- MYSQL_ROW row;
- const char *query;
-
- if (!repl_semisync.getSlaveEnabled())
- return 0;
-
- /* Check if master server has semi-sync plugin installed */
- query= "SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'";
- if (mysql_real_query(mysql, query, strlen(query)) ||
- !(res= mysql_store_result(mysql)))
- {
- sql_print_error("Execution failed on master: %s", query);
- return 1;
- }
-
- row= mysql_fetch_row(res);
- if (!row)
- {
- /* Master does not support semi-sync */
- sql_print_warning("Master server does not support semi-sync, "
- "fallback to asynchronous replication");
- rpl_semi_sync_slave_status= 0;
- mysql_free_result(res);
- return 0;
- }
- mysql_free_result(res);
-
- /*
- Tell master dump thread that we want to do semi-sync
- replication
- */
- query= "SET @rpl_semi_sync_slave= 1";
- if (mysql_real_query(mysql, query, strlen(query)))
- {
- sql_print_error("Set 'rpl_semi_sync_slave=1' on master failed");
- return 1;
- }
- mysql_free_result(mysql_store_result(mysql));
- rpl_semi_sync_slave_status= 1;
- return 0;
-}
-
-int repl_semi_slave_read_event(Binlog_relay_IO_param *param,
- const char *packet, unsigned long len,
- const char **event_buf, unsigned long *event_len)
-{
- if (rpl_semi_sync_slave_status)
- return repl_semisync.slaveReadSyncHeader(packet, len,
- &semi_sync_need_reply,
- event_buf, event_len);
- *event_buf= packet;
- *event_len= len;
- return 0;
-}
-
-int repl_semi_slave_queue_event(Binlog_relay_IO_param *param,
- const char *event_buf,
- unsigned long event_len,
- uint32 flags)
-{
- if (rpl_semi_sync_slave_status && semi_sync_need_reply)
- {
- /*
- We deliberately ignore the error in slaveReply, such error
- should not cause the slave IO thread to stop, and the error
- messages are already reported.
- */
- (void) repl_semisync.slaveReply(param->mysql,
- param->master_log_name,
- param->master_log_pos);
- }
- return 0;
-}
-
-int repl_semi_slave_io_start(Binlog_relay_IO_param *param)
-{
- return repl_semisync.slaveStart(param);
-}
-
-int repl_semi_slave_io_end(Binlog_relay_IO_param *param)
-{
- return repl_semisync.slaveStop(param);
-}
-
-C_MODE_END
-
-static void fix_rpl_semi_sync_slave_enabled(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val)
-{
- *(char *)ptr= *(char *)val;
- repl_semisync.setSlaveEnabled(rpl_semi_sync_slave_enabled != 0);
- return;
-}
-
-static void fix_rpl_semi_sync_trace_level(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val)
-{
- *(unsigned long *)ptr= *(unsigned long *)val;
- repl_semisync.setTraceLevel(rpl_semi_sync_slave_trace_level);
- return;
-}
-
-/* plugin system variables */
-static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_slave_enabled,
- PLUGIN_VAR_OPCMDARG,
- "Enable semi-synchronous replication slave (disabled by default). ",
- NULL, // check
- &fix_rpl_semi_sync_slave_enabled, // update
- 0);
-
-static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_slave_trace_level,
- PLUGIN_VAR_OPCMDARG,
- "The tracing level for semi-sync replication.",
- NULL, // check
- &fix_rpl_semi_sync_trace_level, // update
- 32, 0, ~0UL, 1);
-
-static SYS_VAR* semi_sync_slave_system_vars[]= {
- MYSQL_SYSVAR(enabled),
- MYSQL_SYSVAR(trace_level),
- NULL,
-};
-
-
-/* plugin status variables */
-static SHOW_VAR semi_sync_slave_status_vars[]= {
- {"Rpl_semi_sync_slave_status",
- (char*) &rpl_semi_sync_slave_status, SHOW_BOOL},
- {NULL, NULL, SHOW_BOOL},
-};
-
-Binlog_relay_IO_observer relay_io_observer = {
- sizeof(Binlog_relay_IO_observer), // len
-
- repl_semi_slave_io_start, // start
- repl_semi_slave_io_end, // stop
- repl_semi_slave_request_dump, // request_transmit
- repl_semi_slave_read_event, // after_read_event
- repl_semi_slave_queue_event, // after_queue_event
- repl_semi_reset_slave, // reset
-};
-
-static int semi_sync_slave_plugin_init(void *p)
-{
- if (repl_semisync.initObject())
- return 1;
- if (register_binlog_relay_io_observer(&relay_io_observer, p))
- return 1;
- return 0;
-}
-
-static int semi_sync_slave_plugin_deinit(void *p)
-{
- if (unregister_binlog_relay_io_observer(&relay_io_observer, p))
- return 1;
- return 0;
-}
-
-
-struct Mysql_replication semi_sync_slave_plugin= {
- MYSQL_REPLICATION_INTERFACE_VERSION
-};
-
-/*
- Plugin library descriptor
-*/
-maria_declare_plugin(semisync_slave)
-{
- MYSQL_REPLICATION_PLUGIN,
- &semi_sync_slave_plugin,
- "rpl_semi_sync_slave",
- "He Zhenxing",
- "Semi-synchronous replication slave",
- PLUGIN_LICENSE_GPL,
- semi_sync_slave_plugin_init, /* Plugin Init */
- semi_sync_slave_plugin_deinit, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
- semi_sync_slave_status_vars, /* status variables */
- semi_sync_slave_system_vars, /* system variables */
- "1.0",
- MariaDB_PLUGIN_MATURITY_STABLE
-}
-maria_declare_plugin_end;
-
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index be05671fb2e..16e506626e5 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -298,7 +298,7 @@ static size_t big_buffer_alloced= 0;
static unsigned int query_log_limit= 0;
static char servhost[256];
-static size_t servhost_len;
+static uint servhost_len;
static char *syslog_ident;
static char syslog_ident_buffer[128]= "mysql-server_auditing";
@@ -438,6 +438,7 @@ static const char *syslog_facility_names[]=
"LOG_LOCAL4", "LOG_LOCAL5", "LOG_LOCAL6", "LOG_LOCAL7",
0
};
+#ifndef _WIN32
static unsigned int syslog_facility_codes[]=
{
LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH,
@@ -452,6 +453,7 @@ static unsigned int syslog_facility_codes[]=
LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3,
LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7,
};
+#endif
static TYPELIB syslog_facility_typelib=
{
array_elements(syslog_facility_names) - 1, "syslog_facility_typelib",
@@ -469,11 +471,13 @@ static const char *syslog_priority_names[]=
0
};
+#ifndef _WIN32
static unsigned int syslog_priority_codes[]=
{
LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR,
LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG,
};
+#endif
static TYPELIB syslog_priority_typelib=
{
@@ -620,7 +624,7 @@ static void remove_blanks(char *user)
struct user_name
{
- int name_len;
+ size_t name_len;
char *name;
};
@@ -655,7 +659,7 @@ static int cmp_users(const void *ia, const void *ib)
{
const struct user_name *a= (const struct user_name *) ia;
const struct user_name *b= (const struct user_name *) ib;
- int dl= a->name_len - b->name_len;
+ int dl= (int)(a->name_len - b->name_len);
if (dl != 0)
return dl;
@@ -663,7 +667,7 @@ static int cmp_users(const void *ia, const void *ib)
}
-static char *coll_search(struct user_coll *c, const char *n, int len)
+static char *coll_search(struct user_coll *c, const char *n, size_t len)
{
struct user_name un;
struct user_name *found;
@@ -675,7 +679,7 @@ static char *coll_search(struct user_coll *c, const char *n, int len)
}
-static int coll_insert(struct user_coll *c, char *n, int len)
+static int coll_insert(struct user_coll *c, char *n, size_t len)
{
if (c->n_users >= c->n_alloced)
{
@@ -915,7 +919,7 @@ static void get_str_n(char *dest, int *dest_len, size_t dest_size,
memcpy(dest, src, src_len);
dest[src_len]= 0;
- *dest_len= src_len;
+ *dest_len= (int)src_len;
}
@@ -1088,7 +1092,7 @@ static void setup_connection_connect(struct connection_info *cn,
cn->log_always= 0;
cn->thread_id= event->thread_id;
get_str_n(cn->db, &cn->db_length, sizeof(cn->db),
- event->database, event->database_length);
+ event->database.str, event->database.length);
get_str_n(cn->user, &cn->user_length, sizeof(cn->db),
event->user, event->user_length);
get_str_n(cn->host, &cn->host_length, sizeof(cn->host),
@@ -1176,7 +1180,7 @@ static void setup_connection_table(struct connection_info *cn,
cn->log_always= 0;
cn->query_length= 0;
get_str_n(cn->db, &cn->db_length, sizeof(cn->db),
- event->database, event->database_length);
+ event->database.str, event->database.length);
get_str_n(cn->user, &cn->user_length, sizeof(cn->db),
event->user, SAFE_STRLEN(event->user));
get_str_n(cn->host, &cn->host_length, sizeof(cn->host),
@@ -1230,12 +1234,12 @@ static void change_connection(struct connection_info *cn,
event->ip, event->ip_length);
}
-static int write_log(const char *message, int len)
+static int write_log(const char *message, size_t len)
{
if (output_type == OUTPUT_FILE)
{
if (logfile &&
- (is_active= (logger_write(logfile, message, len) == len)))
+ (is_active= (logger_write(logfile, message, len) == (int)len)))
return 0;
++log_write_failures;
return 1;
@@ -1244,7 +1248,7 @@ static int write_log(const char *message, int len)
{
syslog(syslog_facility_codes[syslog_facility] |
syslog_priority_codes[syslog_priority],
- "%s %.*s", syslog_info, len, message);
+ "%s %.*s", syslog_info, (int)len, message);
}
return 0;
}
@@ -1324,7 +1328,7 @@ static int log_connection_event(const struct mysql_event_connection *event,
event->ip, event->ip_length,
event->thread_id, 0, type);
csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize,
- ",%.*s,,%d", event->database_length, event->database, event->status);
+ ",%.*s,,%d", event->database.length, event->database.str, event->status);
message[csize]= '\n';
return write_log(message, csize + 1);
}
@@ -1737,13 +1741,13 @@ static int log_table(const struct connection_info *cn,
(void) time(&ctime);
csize= log_header(message, sizeof(message)-1, &ctime,
servhost, servhost_len,
- event->user, SAFE_STRLEN(event->user),
- event->host, SAFE_STRLEN(event->host),
- event->ip, SAFE_STRLEN(event->ip),
+ event->user, (unsigned int)SAFE_STRLEN(event->user),
+ event->host, (unsigned int)SAFE_STRLEN(event->host),
+ event->ip, (unsigned int)SAFE_STRLEN(event->ip),
event->thread_id, cn->query_id, type);
csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize,
- ",%.*s,%.*s,",event->database_length, event->database,
- event->table_length, event->table);
+ ",%.*s,%.*s,",event->database.length, event->database.str,
+ event->table.length, event->table.str);
message[csize]= '\n';
return write_log(message, csize + 1);
}
@@ -1759,15 +1763,15 @@ static int log_rename(const struct connection_info *cn,
(void) time(&ctime);
csize= log_header(message, sizeof(message)-1, &ctime,
servhost, servhost_len,
- event->user, SAFE_STRLEN(event->user),
- event->host, SAFE_STRLEN(event->host),
- event->ip, SAFE_STRLEN(event->ip),
+ event->user, (unsigned int)SAFE_STRLEN(event->user),
+ event->host, (unsigned int)SAFE_STRLEN(event->host),
+ event->ip, (unsigned int)SAFE_STRLEN(event->ip),
event->thread_id, cn->query_id, "RENAME");
csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize,
- ",%.*s,%.*s|%.*s.%.*s,",event->database_length, event->database,
- event->table_length, event->table,
- event->new_database_length, event->new_database,
- event->new_table_length, event->new_table);
+ ",%.*s,%.*s|%.*s.%.*s,",event->database.length, event->database.str,
+ event->table.length, event->table.str,
+ event->new_database.length, event->new_database.str,
+ event->new_table.length, event->new_table.str);
message[csize]= '\n';
return write_log(message, csize + 1);
}
@@ -1832,7 +1836,7 @@ static void update_connection_info(struct connection_info *cn,
/* Change DB */
if (mysql_57_started)
get_str_n(cn->db, &cn->db_length, sizeof(cn->db),
- event->database, event->database_length);
+ event->database.str, event->database.length);
else
get_str_n(cn->db, &cn->db_length, sizeof(cn->db),
event->general_query, event->general_query_length);
@@ -1858,9 +1862,9 @@ static void update_connection_info(struct connection_info *cn,
if (ci_needs_setup(cn))
setup_connection_query(cn, event);
- if (mode == 0 && cn->db_length == 0 && event->database_length > 0)
+ if (mode == 0 && cn->db_length == 0 && event->database.length > 0)
get_str_n(cn->db, &cn->db_length, sizeof(cn->db),
- event->database, event->database_length);
+ event->database.str, event->database.length);
if (event->general_error_code == 0)
{
@@ -1875,7 +1879,7 @@ static void update_connection_info(struct connection_info *cn,
event->general_query + 4, event->general_query_length - 4);
else
get_str_n(cn->db, &cn->db_length, sizeof(cn->db),
- event->database, event->database_length);
+ event->database.str, event->database.length);
}
}
update_general_user(cn, event);
@@ -1916,9 +1920,9 @@ static void update_connection_info(struct connection_info *cn,
event->ip, SAFE_STRLEN(event->ip));
}
- if (cn->db_length == 0 && event->database_length != 0)
+ if (cn->db_length == 0 && event->database.length != 0)
get_str_n(cn->db, &cn->db_length, sizeof(cn->db),
- event->database, event->database_length);
+ event->database.str, event->database.length);
if (mode == 0)
cn->query_id= event->query_id;
@@ -2106,6 +2110,7 @@ struct mysql_event_general_v8
static void auditing_v8(MYSQL_THD thd, struct mysql_event_general_v8 *ev_v8)
{
+#ifdef __linux__
#ifdef DBUG_OFF
#ifdef __x86_64__
static const int cmd_off= 4200;
@@ -2127,7 +2132,7 @@ static void auditing_v8(MYSQL_THD thd, struct mysql_event_general_v8 *ev_v8)
static const int db_len_off= 68;
#endif /*x86_64*/
#endif /*DBUG_OFF*/
-
+#endif /* __linux__ */
struct mysql_event_general event;
if (ev_v8->event_class != MYSQL_AUDIT_GENERAL_CLASS)
@@ -2145,8 +2150,8 @@ static void auditing_v8(MYSQL_THD thd, struct mysql_event_general_v8 *ev_v8)
event.general_charset= ev_v8->general_charset;
event.general_time= ev_v8->general_time;
event.general_rows= ev_v8->general_rows;
- event.database= 0;
- event.database_length= 0;
+ event.database.str= 0;
+ event.database.length= 0;
if (event.general_query_length > 0)
{
@@ -2154,8 +2159,8 @@ static void auditing_v8(MYSQL_THD thd, struct mysql_event_general_v8 *ev_v8)
event.general_command= "Query";
event.general_command_length= 5;
#ifdef __linux__
- event.database= *(char **) (((char *) thd) + db_off);
- event.database_length= *(size_t *) (((char *) thd) + db_len_off);
+ event.database.str= *(char **) (((char *) thd) + db_off);
+ event.database.length= *(size_t *) (((char *) thd) + db_len_off);
#endif /*__linux*/
}
#ifdef __linux__
@@ -2342,7 +2347,7 @@ static int server_audit_init(void *p __attribute__((unused)))
if (gethostname(servhost, sizeof(servhost)))
strcpy(servhost, "unknown");
- servhost_len= strlen(servhost);
+ servhost_len= (uint)strlen(servhost);
logger_init_mutexes();
#if defined(HAVE_PSI_INTERFACE) && !defined(FLOGGER_NO_PSI)
diff --git a/plugin/server_audit/test_audit_v4.c b/plugin/server_audit/test_audit_v4.c
index 65571b14c11..8cb24bc693b 100644
--- a/plugin/server_audit/test_audit_v4.c
+++ b/plugin/server_audit/test_audit_v4.c
@@ -57,11 +57,11 @@ static int auditing_v4(MYSQL_THD thd, mysql_event_class_t class, const void *ev)
ev_302.general_error_code= event->general_error_code;
ev_302.general_thread_id= event->general_thread_id;
ev_302.general_user= event->general_user.str;
- ev_302.general_user_length= event->general_user.length;
+ ev_302.general_user_length= (unsigned int)event->general_user.length;
ev_302.general_command= event->general_command.str;
- ev_302.general_command_length= event->general_command.length;
+ ev_302.general_command_length= (unsigned int)event->general_command.length;
ev_302.general_query= event->general_query.str;
- ev_302.general_query_length= event->general_query.length;
+ ev_302.general_query_length= (unsigned int)event->general_query.length;
ev_302.general_charset= event->general_charset;
ev_302.general_time= event->general_time;
ev_302.general_rows= event->general_rows;
diff --git a/plugin/simple_password_check/simple_password_check.c b/plugin/simple_password_check/simple_password_check.c
index dd4051e8169..5a76c3d3005 100644
--- a/plugin/simple_password_check/simple_password_check.c
+++ b/plugin/simple_password_check/simple_password_check.c
@@ -15,6 +15,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <mysqld_error.h>
+#include <my_attribute.h>
#include <mysql/plugin_password_validation.h>
#include <ctype.h>
#include <string.h>
@@ -24,7 +25,7 @@ static unsigned min_length, min_digits, min_letters, min_others;
static int validate(MYSQL_CONST_LEX_STRING *username,
MYSQL_CONST_LEX_STRING *password)
{
- unsigned digits=0 , uppers=0 , lowers=0, others=0, length= password->length;
+ unsigned digits=0 , uppers=0 , lowers=0, others=0, length= (unsigned)password->length;
const char *ptr= password->str, *end= ptr + length;
if (strncmp(password->str, username->str, length) == 0)
@@ -50,7 +51,9 @@ static int validate(MYSQL_CONST_LEX_STRING *username,
others < min_others;
}
-static void fix_min_length(MYSQL_THD thd, struct st_mysql_sys_var *var,
+static void fix_min_length(MYSQL_THD thd __attribute__((unused)),
+ struct st_mysql_sys_var *var
+ __attribute__((unused)),
void *var_ptr, const void *save)
{
unsigned int new_min_length;
diff --git a/plugin/userstat/index_stats.cc b/plugin/userstat/index_stats.cc
index 87e6da63e38..0528507c50e 100644
--- a/plugin/userstat/index_stats.cc
+++ b/plugin/userstat/index_stats.cc
@@ -17,27 +17,26 @@ static int index_stats_fill(THD *thd, TABLE_LIST *tables, COND *cond)
INDEX_STATS *index_stats =
(INDEX_STATS*) my_hash_element(&global_index_stats, i);
TABLE_LIST tmp_table;
- char *index_name;
- size_t schema_name_length, table_name_length, index_name_length;
+ const char *index_name;
+ size_t index_name_length;
bzero((char*) &tmp_table,sizeof(tmp_table));
- tmp_table.db= index_stats->index;
- tmp_table.table_name= strend(index_stats->index)+1;
+ tmp_table.db.str= index_stats->index;
+ tmp_table.db.length= strlen(index_stats->index);
+ tmp_table.table_name.str= index_stats->index + tmp_table.db.length + 1;
+ tmp_table.table_name.length= strlen(tmp_table.table_name.str);
tmp_table.grant.privilege= 0;
- if (check_access(thd, SELECT_ACL, tmp_table.db,
+ if (check_access(thd, SELECT_ACL, tmp_table.db.str,
&tmp_table.grant.privilege, NULL, 0, 1) ||
check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
continue;
- index_name= strend(tmp_table.table_name)+1;
- schema_name_length= (tmp_table.table_name - index_stats->index) -1;
- table_name_length= (index_name - tmp_table.table_name)-1;
- index_name_length= (index_stats->index_name_length - schema_name_length -
- table_name_length - 3);
+ index_name= tmp_table.table_name.str + tmp_table.table_name.length + 1;
+ index_name_length= (index_stats->index_name_length - tmp_table.db.length -
+ tmp_table.table_name.length - 3);
- table->field[0]->store(tmp_table.db, (uint)schema_name_length,
- system_charset_info);
- table->field[1]->store(tmp_table.table_name, (uint) table_name_length,
+ table->field[0]->store(tmp_table.db.str, tmp_table.db.length, system_charset_info);
+ table->field[1]->store(tmp_table.table_name.str, tmp_table.table_name.length,
system_charset_info);
table->field[2]->store(index_name, (uint) index_name_length, system_charset_info);
table->field[3]->store((longlong)index_stats->rows_read, TRUE);
diff --git a/plugin/userstat/table_stats.cc b/plugin/userstat/table_stats.cc
index 7b522a388d7..3119e516e06 100644
--- a/plugin/userstat/table_stats.cc
+++ b/plugin/userstat/table_stats.cc
@@ -26,10 +26,12 @@ static int table_stats_fill(THD *thd, TABLE_LIST *tables, COND *cond)
table_name_length= strlen(table_stats->table + schema_length + 1);
bzero((char*) &tmp_table,sizeof(tmp_table));
- tmp_table.db= table_stats->table;
- tmp_table.table_name= end_of_schema+1;
+ tmp_table.db.str= table_stats->table;
+ tmp_table.db.length= schema_length;
+ tmp_table.table_name.str= end_of_schema+1;
+ tmp_table.table_name.length= table_name_length;
tmp_table.grant.privilege= 0;
- if (check_access(thd, SELECT_ACL, tmp_table.db,
+ if (check_access(thd, SELECT_ACL, tmp_table.db.str,
&tmp_table.grant.privilege, NULL, 0, 1) ||
check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX,
1))
diff --git a/plugin/semisync/CMakeLists.txt b/plugin/versioning/CMakeLists.txt
index 88998fb3093..fc741121e10 100644
--- a/plugin/semisync/CMakeLists.txt
+++ b/plugin/versioning/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, MariaDB corporation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -13,16 +13,5 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-SET(SEMISYNC_MASTER_SOURCES
- semisync.cc semisync_master.cc semisync_master_plugin.cc
- semisync.h semisync_master.h)
-
-MYSQL_ADD_PLUGIN(semisync_master ${SEMISYNC_MASTER_SOURCES}
- RECOMPILE_FOR_EMBEDDED)
-
-SET(SEMISYNC_SLAVE_SOURCES semisync.cc semisync_slave.cc
- semisync_slave_plugin.cc semisync.h semisync_slave.h )
-
-MYSQL_ADD_PLUGIN(semisync_slave ${SEMISYNC_SLAVE_SOURCES}
- RECOMPILE_FOR_EMBEDDED)
-
+MYSQL_ADD_PLUGIN(test_versioning versioning.cc RECOMPILE_FOR_EMBEDDED
+ MODULE_ONLY COMPONENT Test)
diff --git a/plugin/versioning/versioning.cc b/plugin/versioning/versioning.cc
new file mode 100644
index 00000000000..e48f74bc4cb
--- /dev/null
+++ b/plugin/versioning/versioning.cc
@@ -0,0 +1,204 @@
+/* Copyright (c) 2016, MariaDB corporation. All rights
+ reserved.
+
+ This program is free 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-1301 USA */
+
+#define MYSQL_SERVER 1
+#include <my_global.h>
+#include <mysql_version.h>
+#include <mysqld.h>
+#include <mysql/plugin.h>
+#include "sql_plugin.h" // st_plugin_int
+#include "sql_class.h"
+#include "item.h"
+#include "vers_utils.h"
+
+/* System Versioning: VTQ_TRX_ID(), VTQ_COMMIT_ID(), VTQ_BEGIN_TS(), VTQ_COMMIT_TS(), VTQ_ISO_LEVEL() */
+template <TR_table::field_id_t VTQ_FIELD>
+class Create_func_vtq : public Create_native_func
+{
+public:
+ virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list);
+
+ static Create_func_vtq<VTQ_FIELD> s_singleton;
+
+protected:
+ Create_func_vtq<VTQ_FIELD>() {}
+ virtual ~Create_func_vtq<VTQ_FIELD>() {}
+};
+
+template<TR_table::field_id_t VTQ_FIELD>
+Create_func_vtq<VTQ_FIELD> Create_func_vtq<VTQ_FIELD>::s_singleton;
+
+template <TR_table::field_id_t VTQ_FIELD>
+Item*
+Create_func_vtq<VTQ_FIELD>::create_native(THD *thd, LEX_CSTRING *name,
+ List<Item> *item_list)
+{
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ switch (VTQ_FIELD)
+ {
+ case TR_table::FLD_BEGIN_TS:
+ case TR_table::FLD_COMMIT_TS:
+ func= new (thd->mem_root) Item_func_vtq_ts(thd, param_1, VTQ_FIELD);
+ break;
+ case TR_table::FLD_TRX_ID:
+ case TR_table::FLD_COMMIT_ID:
+ case TR_table::FLD_ISO_LEVEL:
+ func= new (thd->mem_root) Item_func_vtq_id(thd, param_1, VTQ_FIELD);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+ break;
+ }
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ switch (VTQ_FIELD)
+ {
+ case TR_table::FLD_TRX_ID:
+ case TR_table::FLD_COMMIT_ID:
+ func= new (thd->mem_root) Item_func_vtq_id(thd, param_1, param_2, VTQ_FIELD);
+ break;
+ default:
+ goto error;
+ }
+ break;
+ }
+ error:
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str);
+ break;
+ }
+ }
+
+ return func;
+};
+
+template <class Item_func_vtq_trx_seesX>
+class Create_func_vtq_trx_sees : public Create_native_func
+{
+public:
+ virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list)
+ {
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_func_vtq_trx_seesX(thd, param_1, param_2);
+ break;
+ }
+ default:
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str);
+ break;
+ }
+
+ return func;
+ }
+
+ static Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX> s_singleton;
+
+protected:
+ Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX>() {}
+ virtual ~Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX>() {}
+};
+
+template<class X>
+Create_func_vtq_trx_sees<X> Create_func_vtq_trx_sees<X>::s_singleton;
+
+#define BUILDER(F) & F::s_singleton
+
+static Native_func_registry func_array[] =
+{
+ { { C_STRING_WITH_LEN("VTQ_BEGIN_TS") }, BUILDER(Create_func_vtq<TR_table::FLD_BEGIN_TS>)},
+ { { C_STRING_WITH_LEN("VTQ_COMMIT_ID") }, BUILDER(Create_func_vtq<TR_table::FLD_COMMIT_ID>)},
+ { { C_STRING_WITH_LEN("VTQ_COMMIT_TS") }, BUILDER(Create_func_vtq<TR_table::FLD_COMMIT_TS>)},
+ { { C_STRING_WITH_LEN("VTQ_ISO_LEVEL") }, BUILDER(Create_func_vtq<TR_table::FLD_ISO_LEVEL>)},
+ { { C_STRING_WITH_LEN("VTQ_TRX_ID") }, BUILDER(Create_func_vtq<TR_table::FLD_TRX_ID>)},
+ { { C_STRING_WITH_LEN("VTQ_TRX_SEES") }, BUILDER(Create_func_vtq_trx_sees<Item_func_vtq_trx_sees>)},
+ { { C_STRING_WITH_LEN("VTQ_TRX_SEES_EQ") }, BUILDER(Create_func_vtq_trx_sees<Item_func_vtq_trx_sees_eq>)},
+ { {0, 0}, NULL}
+};
+
+
+/*
+ Disable __attribute__() on non-gcc compilers.
+*/
+#if !defined(__attribute__) && !defined(__GNUC__)
+#define __attribute__(A)
+#endif
+
+static int versioning_plugin_init(void *p __attribute__ ((unused)))
+{
+ DBUG_ENTER("versioning_plugin_init");
+ // No need in locking since we so far single-threaded
+ int res= item_create_append(func_array);
+ if (res)
+ {
+ my_message(ER_PLUGIN_IS_NOT_LOADED, "Can't append function array" , MYF(0));
+ DBUG_RETURN(res);
+ }
+
+ DBUG_RETURN(0);
+}
+
+static int versioning_plugin_deinit(void *p __attribute__ ((unused)))
+{
+ DBUG_ENTER("versioning_plugin_deinit");
+ DBUG_RETURN(0);
+}
+
+struct st_mysql_daemon versioning_plugin=
+{ MYSQL_REPLICATION_INTERFACE_VERSION };
+
+/*
+ Plugin library descriptor
+*/
+
+maria_declare_plugin(versioning)
+{
+ MYSQL_REPLICATION_PLUGIN, // initialized after MYSQL_STORAGE_ENGINE_PLUGIN
+ &versioning_plugin,
+ "test_versioning",
+ "MariaDB Corp",
+ "System Vesioning testing features",
+ PLUGIN_LICENSE_GPL,
+ versioning_plugin_init, /* Plugin Init */
+ versioning_plugin_deinit, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
+}
+maria_declare_plugin_end;
diff --git a/plugin/win_auth_client/common.cc b/plugin/win_auth_client/common.cc
index 30a8e0b3b13..8e4eb318252 100644
--- a/plugin/win_auth_client/common.cc
+++ b/plugin/win_auth_client/common.cc
@@ -69,7 +69,7 @@ Connection::Connection(MYSQL_PLUGIN_VIO *vio): m_vio(vio), m_error(0)
int Connection::write(const Blob &blob)
{
- m_error= m_vio->write_packet(m_vio, blob.ptr(), blob.len());
+ m_error= m_vio->write_packet(m_vio, blob.ptr(), (int)blob.len());
#ifndef DBUG_OFF
if (m_error)
@@ -392,8 +392,8 @@ char* wchar_to_utf8(const wchar_t *string, size_t *len)
int res= WideCharToMultiByte(CP_UTF8, // convert to UTF-8
0, // conversion flags
string, // input buffer
- str_len, // its length
- buf, buf_len, // output buffer and its size
+ (int)str_len, // its length
+ buf, (int)buf_len, // output buffer and its size
NULL, NULL); // default character (not used)
if (res)
@@ -460,8 +460,8 @@ wchar_t* utf8_to_wchar(const char *string, size_t *len)
res= MultiByteToWideChar(CP_UTF8, // convert from UTF-8
0, // conversion flags
string, // input buffer
- buf_len, // its size
- buf, buf_len); // output buffer and its size
+ (int)buf_len, // its size
+ buf, (int)buf_len); // output buffer and its size
if (res)
{
buf[res]= '\0';
@@ -504,7 +504,7 @@ const char* get_last_error_message(Error_message_buf buf)
buf[0]= '\0';
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR)buf, sizeof(buf), NULL );
+ (LPTSTR)buf, ERRMSG_BUFSIZE , NULL );
return buf;
}
diff --git a/plugin/win_auth_client/common.h b/plugin/win_auth_client/common.h
index 415294b1ed9..cd7dc8c2e66 100644
--- a/plugin/win_auth_client/common.h
+++ b/plugin/win_auth_client/common.h
@@ -77,8 +77,8 @@ void error_log_print(const char *fmt, ...)
error_log_vprint(Level, fmt, args);
va_end(args);
}
-
-typedef char Error_message_buf[1024];
+#define ERRMSG_BUFSIZE 1024
+typedef char Error_message_buf[ERRMSG_BUFSIZE];
const char* get_last_error_message(Error_message_buf);
diff --git a/plugin/win_auth_client/handshake.h b/plugin/win_auth_client/handshake.h
index adab4715c99..66d492f79ab 100644
--- a/plugin/win_auth_client/handshake.h
+++ b/plugin/win_auth_client/handshake.h
@@ -49,7 +49,7 @@ class Security_buffer: public SecBufferDesc
m_buf.BufferType= SECBUFFER_TOKEN;
m_buf.pvBuffer= ptr;
- m_buf.cbBuffer= len;
+ m_buf.cbBuffer= (ULONG)len;
}
/// If @c false, no deallocation will be done in the destructor.
@@ -100,7 +100,7 @@ public:
Handshake(const char *ssp, side_t side);
virtual ~Handshake();
- int Handshake::packet_processing_loop();
+ int packet_processing_loop();
bool virtual is_complete() const
{
diff --git a/plugin/win_auth_client/handshake_client.cc b/plugin/win_auth_client/handshake_client.cc
index 856dda76217..7969a6f3c49 100644
--- a/plugin/win_auth_client/handshake_client.cc
+++ b/plugin/win_auth_client/handshake_client.cc
@@ -160,7 +160,7 @@ int Handshake_client::write_packet(Blob &data)
Store in byte 255 the number of 512b blocks that are needed to
keep all the data.
*/
- unsigned block_count= data.len()/512 + ((data.len() % 512) ? 1 : 0);
+ unsigned block_count= (uint)(data.len()/512) + ((data.len() % 512) ? 1 : 0);
#if !defined(DBUG_OFF) && defined(WINAUTH_USE_DBUG_LIB)
diff --git a/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm b/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm
index 9f684ae6b0c..9268cb3e06b 100644
--- a/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm
+++ b/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm
@@ -9,8 +9,10 @@ return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" unless defined $::mysqld_variables{'wsrep-on'};
my ($provider) = grep { -f $_ } $ENV{WSREP_PROVIDER},
- "/usr/lib/galera/libgalera_smm.so",
- "/usr/lib64/galera/libgalera_smm.so";
+ "/usr/lib64/galera-3/libgalera_smm.so",
+ "/usr/lib64/galera/libgalera_smm.so",
+ "/usr/lib/galera-3/libgalera_smm.so",
+ "/usr/lib/galera/libgalera_smm.so";
return "No wsrep provider library" unless -f $provider;
diff --git a/scripts/galera_recovery.sh b/scripts/galera_recovery.sh
index de2e653c497..09de6721762 100644
--- a/scripts/galera_recovery.sh
+++ b/scripts/galera_recovery.sh
@@ -68,7 +68,7 @@ parse_arguments() {
wsrep_recover_position() {
# Redirect server's error log to the log file.
- eval /usr/sbin/mysqld $cmdline_args --user=$user --wsrep_recover \
+ eval @sbindir@/mysqld $cmdline_args --user=$user --wsrep_recover \
--disable-log-error 2> "$log_file"
ret=$?
if [ $ret -ne 0 ]; then
diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh
index cc6db192de2..9381120a097 100644
--- a/scripts/mysql_config.sh
+++ b/scripts/mysql_config.sh
@@ -17,25 +17,6 @@
# This script reports various configuration settings that may be needed
# when using the MariaDB client library.
-which ()
-{
- IFS="${IFS= }"; save_ifs="$IFS"; IFS=':'
- for file
- do
- for dir in $PATH
- do
- if test -f $dir/$file
- then
- echo "$dir/$file"
- continue 2
- fi
- done
- echo "which: no $file in ($PATH)"
- exit 1
- done
- IFS="$save_ifs"
-}
-
#
# If we can find the given directory relatively to where mysql_config is
# we should use this instead of the incompiled one.
@@ -70,7 +51,7 @@ get_full_path ()
case $file in
/*) echo "$file";;
*/*) tmp=`pwd`/$file; echo $tmp | sed -e 's;/\./;/;' ;;
- *) which $file ;;
+ *) command -v $file ;;
esac
}
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 07565f7046d..5afeb6a6f47 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -24,9 +24,11 @@ builddir=""
ldata="@localstatedir@"
langdir=""
srcdir=""
+log_error=""
args=""
defaults=""
+defaults_group_suffix=""
mysqld_opt=""
user=""
silent_startup="--silent-startup"
@@ -65,6 +67,9 @@ Usage: $0 [OPTIONS]
--defaults-extra-file=name
Read this file after the global files are read.
--defaults-file=name Only read default options from the given file name.
+ --defaults-group-suffix=name
+ In addition to the given groups, read also groups with
+ this suffix
--force Causes mysql_install_db to run even if DNS does not
work. In that case, grant table entries that
normally use hostnames will use IP addresses.
@@ -136,6 +141,8 @@ parse_arguments()
--builddir=*) builddir=`parse_arg "$arg"` ;;
--srcdir=*) srcdir=`parse_arg "$arg"` ;;
--ldata=*|--datadir=*|--data=*) ldata=`parse_arg "$arg"` ;;
+ --log-error=*)
+ log_error=`parse_arg "$arg"` ;;
--user=*)
# Note that the user will be passed to mysqld so that it runs
# as 'user' (crucial e.g. if log-bin=/some_other_path/
@@ -147,6 +154,8 @@ parse_arguments()
--help) usage ;;
--no-defaults|--defaults-file=*|--defaults-extra-file=*)
defaults="$arg" ;;
+ --defaults-group-suffix=*)
+ defaults_group_suffix="$arg" ;;
--cross-bootstrap|--windows)
# Used when building the MariaDB system tables on a different host than
@@ -288,7 +297,7 @@ fi
# Now we can get arguments from the groups [mysqld] and [mysql_install_db]
# in the my.cfg file, then re-run to merge with command line arguments.
-parse_arguments `"$print_defaults" $defaults --mysqld mysql_install_db`
+parse_arguments `"$print_defaults" $defaults $defaults_group_suffix --mysqld mysql_install_db`
parse_arguments PICK-ARGS-FROM-ARGV "$@"
# Configure paths to support files
@@ -452,7 +461,7 @@ fi
mysqld_bootstrap="${MYSQLD_BOOTSTRAP-$mysqld}"
mysqld_install_cmd_line()
{
- "$mysqld_bootstrap" $defaults "$mysqld_opt" --bootstrap $silent_startup\
+ "$mysqld_bootstrap" $defaults $defaults_group_suffix "$mysqld_opt" --bootstrap $silent_startup\
"--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --enforce-storage-engine="" \
$args --max_allowed_packet=8M \
--net_buffer_length=16K
@@ -475,9 +484,14 @@ if { echo "use mysql;$install_params"; cat "$create_system_tables" "$create_syst
then
s_echo "OK"
else
+ log_file_place=$ldata
+ if test -n "$log_error"
+ then
+ log_file_place="$log_error or $log_file_place"
+ fi
echo
echo "Installation of system tables failed! Examine the logs in"
- echo "$ldata for more information."
+ echo "$log_file_place for more information."
echo
echo "The problem could be conflicting information in an external"
echo "my.cnf files. You can ignore these by doing:"
@@ -486,7 +500,7 @@ else
echo
echo "You can also try to start the mysqld daemon with:"
echo
- echo " shell> $mysqld --skip-grant --general-log &"
+ echo " shell> $mysqld --skip-grant-tables --general-log &"
echo
echo "and use the command line tool $bindir/mysql"
echo "to connect to the mysql database and look at the grant tables:"
@@ -497,8 +511,8 @@ else
echo "Try 'mysqld --help' if you have problems with paths. Using"
echo "--general-log gives you a log in $ldata that may be helpful."
link_to_help
- echo "MariaDB is hosted on launchpad; You can find the latest source and"
- echo "email lists at http://launchpad.net/maria"
+ echo "You can find the latest source at https://downloads.mariadb.org and"
+ echo "the maria-discuss email list at https://launchpad.net/~maria-discuss"
echo
echo "Please check all of the above before submitting a bug report"
echo "at http://mariadb.org/jira"
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index 3b0255abdae..08f5eadaf7b 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -23,17 +23,19 @@ set sql_mode='';
set @orig_storage_engine=@@storage_engine;
set storage_engine=myisam;
+set system_versioning_alter_history=keep;
+
set @have_innodb= (select count(engine) from information_schema.engines where engine='INNODB' and support != 'NO');
SET @innodb_or_myisam=IF(@have_innodb <> 0, 'InnoDB', 'MyISAM');
-CREATE TABLE IF NOT EXISTS db ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Database privileges';
+CREATE TABLE IF NOT EXISTS db ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_history_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Database privileges';
-- Remember for later if db table already existed
set @had_db_table= @@warning_count != 0;
CREATE TABLE IF NOT EXISTS host ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges';
-CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tablespace_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) DEFAULT 0 NOT NULL, plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, authentication_string TEXT NOT NULL, password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, default_role char(80) binary DEFAULT '' NOT NULL, max_statement_time decimal(12,6) DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
+CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tablespace_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_history_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) DEFAULT 0 NOT NULL, plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, authentication_string TEXT NOT NULL, password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, default_role char(80) binary DEFAULT '' NOT NULL, max_statement_time decimal(12,6) DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
-- Remember for later if user table already existed
set @had_user_table= @@warning_count != 0;
@@ -49,7 +51,7 @@ CREATE TABLE IF NOT EXISTS plugin ( name varchar(64) DEFAULT '' NOT NULL, dl var
CREATE TABLE IF NOT EXISTS servers ( Server_name char(64) NOT NULL DEFAULT '', Host char(64) NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(80) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT(4) NOT NULL DEFAULT '0', Socket char(64) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner char(64) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) CHARACTER SET utf8 comment='MySQL Foreign Servers table';
-CREATE TABLE IF NOT EXISTS tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(141) DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
+CREATE TABLE IF NOT EXISTS tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(141) DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
CREATE TABLE IF NOT EXISTS columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';
@@ -80,7 +82,7 @@ CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsign
CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones';
-CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob NOT NULL, body longblob NOT NULL, definer char(141) collate utf8_bin DEFAULT '' NOT NULL, created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, modified timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH', 'EMPTY_STRING_IS_NULL') DEFAULT '' NOT NULL, comment text collate utf8_bin NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
+CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob NOT NULL, body longblob NOT NULL, definer char(141) collate utf8_bin DEFAULT '' NOT NULL, created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, modified timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH', 'EMPTY_STRING_IS_NULL', 'SIMULTANEOUS_ASSIGNMENT') DEFAULT '' NOT NULL, comment text collate utf8_bin NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, aggregate enum('NONE', 'GROUP') DEFAULT 'NONE' NOT NULL, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(141) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
@@ -101,7 +103,7 @@ PREPARE stmt FROM @str;
EXECUTE stmt;
DROP PREPARE stmt;
-CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, modified TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
+CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, modified TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
SET @create_innodb_table_stats="CREATE TABLE IF NOT EXISTS innodb_table_stats (
database_name VARCHAR(64) NOT NULL,
@@ -129,6 +131,19 @@ SET @create_innodb_index_stats="CREATE TABLE IF NOT EXISTS innodb_index_stats (
PRIMARY KEY (database_name, table_name, index_name, stat_name)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0";
+SET @create_transaction_registry="CREATE TABLE IF NOT EXISTS transaction_registry (
+ transaction_id BIGINT UNSIGNED NOT NULL,
+ commit_id BIGINT UNSIGNED NOT NULL,
+ begin_timestamp TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
+ commit_timestamp TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
+ isolation_level ENUM('READ-UNCOMMITTED', 'READ-COMMITTED',
+ 'REPEATABLE-READ', 'SERIALIZABLE') NOT NULL,
+ PRIMARY KEY (transaction_id),
+ UNIQUE KEY (commit_id),
+ INDEX (begin_timestamp),
+ INDEX (commit_timestamp, transaction_id)
+) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0";
+
SET @str=IF(@have_innodb <> 0, @create_innodb_table_stats, "SET @dummy = 0");
PREPARE stmt FROM @str;
EXECUTE stmt;
@@ -139,6 +154,11 @@ PREPARE stmt FROM @str;
EXECUTE stmt;
DROP PREPARE stmt;
+SET @str=IF(@have_innodb <> 0, @create_transaction_registry, "SET @dummy = 0");
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
SET @cmd="CREATE TABLE IF NOT EXISTS slave_relay_log_info (
Number_of_lines INTEGER UNSIGNED NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
Relay_log_name TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.',
diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql
index 9556e7ba160..4821b18bcbf 100644
--- a/scripts/mysql_system_tables_data.sql
+++ b/scripts/mysql_system_tables_data.sql
@@ -30,8 +30,8 @@ SELECT LOWER( REPLACE((SELECT REPLACE(@@hostname,'_','\_')),'%','\%') )INTO @cur
-- Fill "db" table with default grants for anyone to
-- access database 'test' and 'test_%' if "db" table didn't exist
CREATE TEMPORARY TABLE tmp_db LIKE db;
-INSERT INTO tmp_db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y');
-INSERT INTO tmp_db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y');
+INSERT INTO tmp_db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y','Y');
+INSERT INTO tmp_db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N','Y','Y','Y');
INSERT INTO db SELECT * FROM tmp_db WHERE @had_db_table=0;
DROP TABLE tmp_db;
@@ -42,12 +42,12 @@ CREATE TEMPORARY TABLE tmp_user_nopasswd LIKE user;
CREATE TEMPORARY TABLE tmp_user_socket LIKE user;
CREATE TEMPORARY TABLE tmp_user_anonymous LIKE user;
-- Classic passwordless root account.
-INSERT INTO tmp_user_nopasswd VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N', 'N','', 0);
-REPLACE INTO tmp_user_nopasswd SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0 FROM dual WHERE @current_hostname != 'localhost';
-REPLACE INTO tmp_user_nopasswd VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0);
-REPLACE INTO tmp_user_nopasswd VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
+INSERT INTO tmp_user_nopasswd VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N', 'N','', 0);
+REPLACE INTO tmp_user_nopasswd SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0 FROM dual WHERE @current_hostname != 'localhost';
+REPLACE INTO tmp_user_nopasswd VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0);
+REPLACE INTO tmp_user_nopasswd VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
-- More secure root account using unix sucket auth.
-INSERT INTO tmp_user_socket VALUES ('localhost',IFNULL(@auth_root_socket, 'root'),'','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'unix_socket','','N', 'N','', 0);
+INSERT INTO tmp_user_socket VALUES ('localhost',IFNULL(@auth_root_socket, 'root'),'','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'unix_socket','','N', 'N','', 0);
-- Anonymous user with no privileges.
INSERT INTO tmp_user_anonymous (host,user) VALUES ('localhost','');
INSERT INTO tmp_user_anonymous (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost';
diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql
index 10e2dcf21fb..8e27dfbdc7e 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -74,7 +74,7 @@ ALTER TABLE tables_priv
COLLATE utf8_general_ci DEFAULT '' NOT NULL,
MODIFY Table_priv set('Select','Insert','Update','Delete','Create',
'Drop','Grant','References','Index','Alter',
- 'Create View','Show view','Trigger')
+ 'Create View','Show view','Trigger','Delete versioning rows')
COLLATE utf8_general_ci DEFAULT '' NOT NULL,
COMMENT='Table privileges';
@@ -449,7 +449,8 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL,
'HIGH_NOT_PRECEDENCE',
'NO_ENGINE_SUBSTITUTION',
'PAD_CHAR_TO_FULL_LENGTH',
- 'EMPTY_STRING_IS_NULL'
+ 'EMPTY_STRING_IS_NULL',
+ 'SIMULTANEOUS_ASSIGNMENT'
) DEFAULT '' NOT NULL,
DEFAULT CHARACTER SET utf8;
@@ -519,6 +520,10 @@ ALTER TABLE proc MODIFY body_utf8 longblob DEFAULT NULL;
ALTER TABLE proc MODIFY comment
text collate utf8_bin NOT NULL;
+# MDEV-7773: Stored Aggregate Functions
+ALTER TABLE proc ADD aggregate enum('NONE', 'GROUP') DEFAULT 'NONE' NOT NULL
+ AFTER body_utf8;
+
#
# EVENT privilege
#
@@ -574,7 +579,8 @@ ALTER TABLE event MODIFY sql_mode
'HIGH_NOT_PRECEDENCE',
'NO_ENGINE_SUBSTITUTION',
'PAD_CHAR_TO_FULL_LENGTH',
- 'EMPTY_STRING_IS_NULL'
+ 'EMPTY_STRING_IS_NULL',
+ 'SIMULTANEOUS_ASSIGNMENT'
) DEFAULT '' NOT NULL AFTER on_completion;
ALTER TABLE event MODIFY name char(64) CHARACTER SET utf8 NOT NULL default '';
@@ -641,6 +647,23 @@ ALTER TABLE user MODIFY Create_tablespace_priv enum('N','Y') COLLATE utf8_genera
UPDATE user SET Create_tablespace_priv = Super_priv WHERE @hadCreateTablespacePriv = 0;
+#
+# System versioning
+#
+
+ALTER TABLE user change Truncate_versioning_priv Delete_history_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL DEFAULT 'N';
+ALTER TABLE db change Truncate_versioning_priv Delete_history_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL DEFAULT 'N';
+
+SET @had_user_delete_history_priv := 0;
+SELECT @had_user_delete_history_priv :=1 FROM user WHERE Delete_history_priv LIKE '%';
+
+ALTER TABLE user add Delete_history_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL DEFAULT 'N' after Create_tablespace_priv;
+ALTER TABLE user modify Delete_history_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL DEFAULT 'N';
+ALTER TABLE db add Delete_history_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL DEFAULT 'N' after Trigger_priv;
+ALTER TABLE db modify Delete_history_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL DEFAULT 'N';
+
+UPDATE user SET Delete_history_priv = Super_priv WHERE @had_user_delete_history_priv = 0;
+
ALTER TABLE user ADD plugin char(64) DEFAULT '', ADD authentication_string TEXT;
ALTER TABLE user ADD password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
ALTER TABLE user ADD is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 80a93c979ac..5797bdc68d7 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -103,35 +103,6 @@ EOF
exit 1
}
-my_which ()
-{
- save_ifs="${IFS-UNSET}"
- IFS=:
- ret=0
- for file
- do
- for dir in $PATH
- do
- if [ -f "$dir/$file" ]
- then
- echo "$dir/$file"
- continue 2
- fi
- done
-
- ret=1 #signal an error
- break
- done
-
- if [ "$save_ifs" = UNSET ]
- then
- unset IFS
- else
- IFS="$save_ifs"
- fi
- return $ret # Success
-}
-
find_in_bin() {
if test -x "$MY_BASEDIR_VERSION/bin/$1"
then
@@ -220,7 +191,8 @@ wsrep_pick_url() {
log_error "WSREP: 'wsrep_urls' is DEPRECATED! Use wsrep_cluster_address to specify multiple addresses instead."
- if ! which nc >/dev/null; then
+ if ! command -v nc >/dev/null
+ then
log_error "ERROR: nc tool not found in PATH! Make sure you have it installed."
return 1
fi
@@ -646,8 +618,7 @@ plugin_dir="${plugin_dir}${PLUGIN_VARIANT}"
# Ensure that 'logger' exists, if it's requested
if [ $want_syslog -eq 1 ]
then
- my_which logger > /dev/null 2>&1
- if [ $? -ne 0 ]
+ if ! command -v logger > /dev/null
then
log_error "--syslog requested, but no 'logger' program found. Please ensure that 'logger' is in your PATH, or do not specify the --syslog option to mysqld_safe."
exit 1
@@ -878,7 +849,7 @@ fi
if @TARGET_LINUX@ && test $flush_caches -eq 1
then
# Locate sync, ensure it exists.
- if ! my_which sync > /dev/null 2>&1
+ if ! command -v sync > /dev/null
then
log_error "sync command not found, required for --flush-caches"
exit 1
@@ -890,7 +861,7 @@ then
fi
# Locate sysctl, ensure it exists.
- if ! my_which sysctl > /dev/null 2>&1
+ if ! command -v sysctl > /dev/null
then
log_error "sysctl command not found, required for --flush-caches"
exit 1
@@ -934,7 +905,7 @@ cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS"
if @TARGET_LINUX@ && test $numa_interleave -eq 1
then
# Locate numactl, ensure it exists.
- if ! my_which numactl > /dev/null 2>&1
+ if ! command -v numactl > /dev/null
then
log_error "numactl command not found, required for --numa-interleave"
exit 1
@@ -977,8 +948,8 @@ if expr "${-}" : '.*x' > /dev/null
then
:
else
- exec 1>&-
- exec 2>&-
+ exec 1>/dev/null
+ exec 2>/dev/null
fi
# maximum number of wsrep restarts
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index 9b09935abbf..e72b74ab6d1 100755
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -20,13 +20,13 @@ set -u
WSREP_SST_OPT_BYPASS=0
WSREP_SST_OPT_BINLOG=""
-WSREP_SST_OPT_CONF_SUFFIX=""
WSREP_SST_OPT_DATA=""
WSREP_SST_OPT_AUTH=${WSREP_SST_OPT_AUTH:-}
WSREP_SST_OPT_USER=${WSREP_SST_OPT_USER:-}
WSREP_SST_OPT_PSWD=${WSREP_SST_OPT_PSWD:-}
WSREP_SST_OPT_DEFAULT=""
WSREP_SST_OPT_EXTRA_DEFAULT=""
+WSREP_SST_OPT_SUFFIX_DEFAULT=""
while [ $# -gt 0 ]; do
case "$1" in
@@ -35,19 +35,16 @@ case "$1" in
#
# Break address string into host:port/path parts
#
- if echo $WSREP_SST_OPT_ADDR | grep -qe '^\[.*\]'
- then
- # IPv6 notation
- readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR/\]*/\]}
- readonly WSREP_SST_OPT_HOST_UNESCAPED=$(echo $WSREP_SST_OPT_HOST | \
- cut -d '[' -f 2 | cut -d ']' -f 1)
- else
- # "traditional" notation
- readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*}
- fi
+ readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*}
+ readonly WSREP_SST_OPT_HOST_UNESCAPED=`echo "$WSREP_SST_OPT_HOST"|awk '{if(match($0,/^\[.*\]$/)) $0=substr($0,2,RLENGTH-2);print}'`
readonly WSREP_SST_OPT_ADDR_PORT=$(echo $WSREP_SST_OPT_ADDR | \
cut -d ']' -f 2 | cut -s -d ':' -f 2 | cut -d '/' -f 1)
readonly WSREP_SST_OPT_PATH=${WSREP_SST_OPT_ADDR#*/}
+ readonly WSREP_SST_OPT_MODULE=${WSREP_SST_OPT_PATH%%/*}
+ remain=${WSREP_SST_OPT_PATH#*/}
+ readonly WSREP_SST_OPT_LSN=${remain%%/*}
+ remain=${remain#*/}
+ readonly WSREP_SST_OPT_SST_VER=${remain%%/*}
shift
;;
'--bypass')
@@ -66,7 +63,7 @@ case "$1" in
shift
;;
'--defaults-group-suffix')
- WSREP_SST_OPT_CONF_SUFFIX="$2"
+ readonly WSREP_SST_OPT_SUFFIX_DEFAULT="$1=$2"
shift
;;
'--host')
@@ -122,11 +119,10 @@ shift
done
readonly WSREP_SST_OPT_BYPASS
readonly WSREP_SST_OPT_BINLOG
-readonly WSREP_SST_OPT_CONF_SUFFIX
-if [ -n "${WSREP_SST_OPT_ADDR_PORT:-}" ]; then
+if [ -n "${WSREP_SST_OPT_ADDR:-}" ]; then
if [ -n "${WSREP_SST_OPT_PORT:-}" ]; then
- if [ "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then
+ if [ -n "$WSREP_SST_OPT_ADDR_PORT" -a "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then
wsrep_log_error "port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR"
exit 2
fi
@@ -144,13 +140,13 @@ CLIENT_DIR="$SCRIPTS_DIR/../client"
if [ -x "$CLIENT_DIR/mysql" ]; then
MYSQL_CLIENT="$CLIENT_DIR/mysql"
else
- MYSQL_CLIENT=$(which mysql)
+ MYSQL_CLIENT=mysql
fi
if [ -x "$CLIENT_DIR/mysqldump" ]; then
MYSQLDUMP="$CLIENT_DIR/mysqldump"
else
- MYSQLDUMP=$(which mysqldump)
+ MYSQLDUMP=mysqldump
fi
if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
@@ -158,22 +154,21 @@ if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
else
- MY_PRINT_DEFAULTS=$(which my_print_defaults)
+ MY_PRINT_DEFAULTS=my_print_defaults
fi
-readonly WSREP_SST_OPT_CONF="$WSREP_SST_OPT_DEFAULT $WSREP_SST_OPT_EXTRA_DEFAULT"
-MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF"
+readonly WSREP_SST_OPT_CONF="$WSREP_SST_OPT_DEFAULT $WSREP_SST_OPT_EXTRA_DEFAULT $WSREP_SST_OPT_SUFFIX_DEFAULT"
+readonly MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF"
+
wsrep_auth_not_set()
{
[ -z "$WSREP_SST_OPT_AUTH" -o "$WSREP_SST_OPT_AUTH" = "(null)" ]
}
-# For Bug:1200727
-if $MY_PRINT_DEFAULTS sst | grep -q "wsrep_sst_auth"
-then
- if wsrep_auth_not_set
- then
- WSREP_SST_OPT_AUTH=$($MY_PRINT_DEFAULTS sst | grep -- "--wsrep_sst_auth" | cut -d= -f2)
+# State Snapshot Transfer authentication password was displayed in the ps output. Bug fixed #1200727.
+if $MY_PRINT_DEFAULTS sst | grep -q "wsrep_sst_auth"; then
+ if wsrep_auth_not_set; then
+ WSREP_SST_OPT_AUTH=$($MY_PRINT_DEFAULTS sst | grep -- "--wsrep_sst_auth" | cut -d= -f2)
fi
fi
readonly WSREP_SST_OPT_AUTH
@@ -226,10 +221,10 @@ wsrep_check_program()
{
local prog=$1
- if ! which $prog >/dev/null
+ if ! command -v $prog >/dev/null
then
echo "'$prog' not found in PATH"
- return 2 # no such file or directory
+ exit 2 # ENOENT no such file or directory
fi
}
@@ -239,11 +234,9 @@ wsrep_check_programs()
while [ $# -gt 0 ]
do
- wsrep_check_program $1 || ret=$?
+ wsrep_check_program $1
shift
done
-
- return $ret
}
#
@@ -251,7 +244,7 @@ wsrep_check_programs()
# process like encryption, etc.....
# parse such configuration option. (group for xb settings is [sst] in my.cnf
#
-# 1st param: group : name of the config file section, e.g. mysqld
+# 1st param: group (config file section like sst) or my_print_defaults argument (like --mysqld)
# 2nd param: var : name of the variable in the section, e.g. server-id
# 3rd param: - : default value for the param
parse_cnf()
@@ -260,24 +253,15 @@ parse_cnf()
local var=$2
local reval=""
- # print the default settings for given group using my_print_default.
# normalize the variable names specified in cnf file (user can use _ or - for example log-bin or log_bin)
- # then grep for needed variable
+ # then search for needed variable
# finally get the variable value (if variables has been specified multiple time use the last value only)
- # look in group+suffix
- if [[ -n $WSREP_SST_OPT_CONF_SUFFIX ]]; then
- reval=$($MY_PRINT_DEFAULTS "${group}${WSREP_SST_OPT_CONF_SUFFIX}" | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1)
- fi
-
- # look in group
- if [[ -z $reval ]]; then
- reval=$($MY_PRINT_DEFAULTS $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1)
- fi
+ reval=$($MY_PRINT_DEFAULTS "${group}" | awk -v var="${var}" 'BEGIN { OFS=FS="=" } { gsub(/_/,"-",$1); if ( $1=="--"var) lastval=substr($0,length($1)+2) } END { print lastval}')
# use default if we haven't found a value
- if [[ -z $reval ]]; then
- [[ -n $3 ]] && reval=$3
+ if [ -z $reval ]; then
+ [ -n $3 ] && reval=$3
fi
echo $reval
}
diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh
index 6f0218fcc88..7b7cbab06ca 100644
--- a/scripts/wsrep_sst_mariabackup.sh
+++ b/scripts/wsrep_sst_mariabackup.sh
@@ -77,7 +77,7 @@ sdecomp=""
# 5.6.21 PXC and later can't donate to an older joiner
sst_ver=1
-if which pv &>/dev/null && pv --help | grep -q FORMAT;then
+if pv --help 2>/dev/null | grep -q FORMAT;then
pvopts+=$pvformat
fi
pcmd="pv $pvopts"
@@ -172,10 +172,7 @@ get_transfer()
fi
if [[ $tfmt == 'nc' ]];then
- if [[ ! -x `which nc` ]];then
- wsrep_log_error "nc(netcat) not found in path: $PATH"
- exit 2
- fi
+ wsrep_check_programs nc
wsrep_log_info "Using netcat as streamer"
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
if nc -h 2>&1 | grep -q ncat;then
@@ -188,11 +185,8 @@ get_transfer()
fi
else
tfmt='socat'
+ wsrep_check_programs socat
wsrep_log_info "Using socat as streamer"
- if [[ ! -x `which socat` ]];then
- wsrep_log_error "socat not found in path: $PATH"
- exit 2
- fi
if [[ $encrypt -eq 2 || $encrypt -eq 3 ]] && ! socat -V | grep -q "WITH_OPENSSL 1";then
wsrep_log_error "Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt)"
@@ -281,7 +275,7 @@ get_footprint()
adjust_progress()
{
- if [[ ! -x `which pv` ]];then
+ if ! command -v pv >/dev/null;then
wsrep_log_error "pv not found in path: $PATH"
wsrep_log_error "Disabling all progress/rate-limiting"
pcmd=""
@@ -571,7 +565,7 @@ recv_joiner()
pushd ${dir} 1>/dev/null
set +e
- if [[ $tmt -gt 0 && -x `which timeout` ]];then
+ if [[ $tmt -gt 0 ]] && command -v timeout >/dev/null;then
if timeout --help | grep -q -- '-k';then
ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd"
else
@@ -630,10 +624,7 @@ send_donor()
}
-if [[ ! -x `which $INNOBACKUPEX_BIN` ]];then
- wsrep_log_error "${INNOBACKUPEX_BIN} not in path: $PATH"
- exit 2
-fi
+wsrep_check_programs "$INNOBACKUPEX_BIN"
rm -f "${MAGIC_FILE}"
@@ -659,7 +650,7 @@ INNOEXTRA=""
if [[ $ssyslog -eq 1 ]];then
- if [[ ! -x `which logger` ]];then
+ if ! command -v logger >/dev/null;then
wsrep_log_error "logger not in path: $PATH. Ignoring"
else
@@ -943,7 +934,7 @@ then
wsrep_log_info "Compressed qpress files found"
- if [[ ! -x `which qpress` ]];then
+ if ! command -v qpress >/dev/null;then
wsrep_log_error "qpress not found in path: $PATH"
exit 22
fi
diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh
index 8cfdd4e6553..d28a1c161ce 100644
--- a/scripts/wsrep_sst_mysqldump.sh
+++ b/scripts/wsrep_sst_mysqldump.sh
@@ -17,10 +17,6 @@
# This is a reference script for mysqldump-based state snapshot tansfer
-# This variable is not used in mysqldump sst, so better initialize it
-# to avoid shell's "parameter not set" message.
-WSREP_SST_OPT_CONF=""
-
. $(dirname $0)/wsrep_sst_common
PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
@@ -57,10 +53,10 @@ then
fi
# Check client version
-if ! $MYSQL_CLIENT --version | grep 'Distrib 10.' >/dev/null
+if ! $MYSQL_CLIENT --version | grep 'Distrib 10\.[1-9]' >/dev/null
then
$MYSQL_CLIENT --version >&2
- wsrep_log_error "this operation requires MySQL client version 10 or newer"
+ wsrep_log_error "this operation requires MySQL client version 10.1 or newer"
exit $EINVAL
fi
@@ -118,7 +114,7 @@ $MYSQL_CLIENT $AUTH -S$WSREP_SST_OPT_SOCKET --disable-reconnect --connect_timeou
tail -1 | awk -F ' ' '{ print $2 }')
MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\
-"$AUTH -h${WSREP_SST_OPT_HOST_UNESCAPED:-$WSREP_SST_OPT_HOST} "\
+"$AUTH -h${WSREP_SST_OPT_HOST_UNESCAPED} "\
"-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10"
# Check if binary logging is enabled on the joiner node.
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index 24720ff3587..7fc83c1139c 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -71,7 +71,7 @@ check_pid_and_port()
grep '[[:space:]]\+rsync[[:space:]]\+'"$rsync_pid" 2>/dev/null)"
;;
*)
- if ! which lsof > /dev/null; then
+ if ! command -v lsof > /dev/null; then
wsrep_log_error "lsof tool not found in PATH! Make sure you have it installed."
exit 2 # ENOENT
fi
@@ -102,10 +102,10 @@ check_pid_and_port()
is_local_ip()
{
local address="$1"
- local get_addr_bin=`which ifconfig`
- if [ -z "$get_addr_bin" ]
+ local get_addr_bin
+ if ! command -v ifconfig > /dev/null
then
- get_addr_bin=`which ip`
+ get_addr_bin=ip
get_addr_bin="$get_addr_bin address show"
# Add an slash at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41
# ip output format is "X.X.X.X/mask"
@@ -113,6 +113,7 @@ is_local_ip()
else
# Add an space at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41
# ifconfig output format is "X.X.X.X "
+ get_addr_bin=ifconfig
address="$address "
fi
@@ -135,19 +136,7 @@ fi
WSREP_LOG_DIR=${WSREP_LOG_DIR:-""}
# if WSREP_LOG_DIR env. variable is not set, try to get it from my.cnf
if [ -z "$WSREP_LOG_DIR" ]; then
- WSREP_LOG_DIR=$(parse_cnf mariadb-10.0 innodb_log_group_home_dir "")
-fi
-if [ -z "$WSREP_LOG_DIR" ]; then
- WSREP_LOG_DIR=$(parse_cnf mysqld innodb_log_group_home_dir "")
-fi
-if [ -z "$WSREP_LOG_DIR" ]; then
- WSREP_LOG_DIR=$(parse_cnf server innodb_log_group_home_dir "")
-fi
-if [ -z "$WSREP_LOG_DIR" ]; then
- WSREP_LOG_DIR=$(parse_cnf mariadb innodb_log_group_home_dir "")
-fi
-if [ -z "$WSREP_LOG_DIR" ]; then
- WSREP_LOG_DIR=$(parse_cnf mysqld-10.0 innodb_log_group_home_dir "")
+ WSREP_LOG_DIR=$(parse_cnf --mysqld innodb-log-group-home-dir '')
fi
if [ -n "$WSREP_LOG_DIR" ]; then
diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh
index 40e686d4d6b..e7313e4e188 100644
--- a/scripts/wsrep_sst_xtrabackup-v2.sh
+++ b/scripts/wsrep_sst_xtrabackup-v2.sh
@@ -32,9 +32,6 @@ ecode=0
ssyslog=""
ssystag=""
XTRABACKUP_PID=""
-SST_PORT=""
-REMOTEIP=""
-REMOTEHOST=""
tca=""
tcert=""
tkey=""
@@ -42,7 +39,6 @@ sockopt=""
progress=""
ttime=0
totime=0
-lsn=""
ecmd=""
rlimit=""
# Initially
@@ -77,12 +73,7 @@ ssl_cert=""
ssl_ca=""
ssl_key=""
-# Required for backup locks
-# For backup locks it is 1 sent by joiner
-# 5.6.21 PXC and later can't donate to an older joiner
-sst_ver=1
-
-if which pv &>/dev/null && pv --help | grep -q FORMAT;then
+if pv --help 2>/dev/null | grep -q FORMAT;then
pvopts+=$pvformat
fi
pcmd="pv $pvopts"
@@ -97,6 +88,13 @@ MAGIC_FILE="${DATA}/${INFO_FILE}"
# Setting the path for ss and ip
export PATH="/usr/sbin:/sbin:$PATH"
+OS=$(uname)
+
+if ! which lsof > /dev/null; then
+ wsrep_log_error "lsof tool not found in PATH! Make sure you have it installed."
+ exit 2 # ENOENT
+fi
+
timeit(){
local stage=$1
shift
@@ -251,17 +249,10 @@ verify_file_exists()
get_transfer()
{
- if [[ -z $SST_PORT ]];then
- TSST_PORT=4444
- else
- TSST_PORT=$SST_PORT
- fi
+ TSST_PORT=${WSREP_SST_OPT_PORT:-4444}
if [[ $tfmt == 'nc' ]];then
- if [[ ! -x `which nc` ]];then
- wsrep_log_error "nc(netcat) not found in path: $PATH"
- exit 2
- fi
+ wsrep_check_programs nc
if [[ $encrypt -eq 2 || $encrypt -eq 3 || $encrypt -eq 4 ]]; then
wsrep_log_error "******** FATAL ERROR *********************** "
@@ -280,15 +271,12 @@ get_transfer()
fi
else
# netcat doesn't understand [] around IPv6 address
- tcmd="nc ${REMOTEIP//[\[\]]/} ${TSST_PORT}"
+ tcmd="nc ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}"
fi
else
tfmt='socat'
wsrep_log_info "Using socat as streamer"
- if [[ ! -x `which socat` ]];then
- wsrep_log_error "socat not found in path: $PATH"
- exit 2
- fi
+ wsrep_check_programs socat
donor_extra=""
joiner_extra=""
@@ -342,7 +330,7 @@ get_transfer()
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tcert},cafile=${tca}${joiner_extra}${sockopt} stdio"
else
wsrep_log_info "Encrypting with CERT: $tcert, CA: $tca"
- tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tcert},cafile=${tca}${donor_extra}${sockopt}"
+ tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert=${tcert},cafile=${tca}${donor_extra}${sockopt}"
fi
elif [[ $encrypt -eq 3 ]];then
wsrep_log_warning "**** WARNING **** encrypt=3 is deprecated and will be removed in a future release"
@@ -359,7 +347,7 @@ get_transfer()
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tcert},key=${tkey},verify=0${joiner_extra}${sockopt} stdio"
else
wsrep_log_info "Encrypting with CERT: $tcert, KEY: $tkey"
- tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tcert},key=${tkey},verify=0${sockopt}"
+ tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert=${tcert},key=${tkey},verify=0${sockopt}"
fi
elif [[ $encrypt -eq 4 ]]; then
wsrep_log_info "Using openssl based encryption with socat: with key, crt, and ca"
@@ -380,7 +368,7 @@ get_transfer()
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${ssl_cert},key=${ssl_key},cafile=${ssl_ca},verify=1${joiner_extra}${sockopt} stdio"
else
wsrep_log_info "Encrypting with CERT: $ssl_cert, KEY: $ssl_key, CA: $ssl_ca"
- tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${ssl_cert},key=${ssl_key},cafile=${ssl_ca},verify=1${donor_extra}${sockopt}"
+ tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert=${ssl_cert},key=${ssl_key},cafile=${ssl_ca},verify=1${donor_extra}${sockopt}"
fi
else
@@ -391,7 +379,7 @@ get_transfer()
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then
tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio"
else
- tcmd="socat -u stdio TCP:${REMOTEIP}:${TSST_PORT}${sockopt}"
+ tcmd="socat -u stdio TCP:${WSREP_SST_OPT_HOST}:${TSST_PORT}${sockopt}"
fi
fi
fi
@@ -400,7 +388,7 @@ get_transfer()
get_footprint()
{
pushd $WSREP_SST_OPT_DATA 1>/dev/null
- payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c | awk 'END { print $1 }')
+ payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }')
if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress";then
# QuickLZ has around 50% compression ratio
# When compression/compaction used, the progress is only an approximate.
@@ -414,7 +402,7 @@ get_footprint()
adjust_progress()
{
- if [[ ! -x `which pv` ]];then
+ if ! command -v pv >/dev/null;then
wsrep_log_error "pv not found in path: $PATH"
wsrep_log_error "Disabling all progress/rate-limiting"
pcmd=""
@@ -452,7 +440,11 @@ read_cnf()
progress=$(parse_cnf sst progress "")
rebuild=$(parse_cnf sst rebuild 0)
ttime=$(parse_cnf sst time 0)
- cpat=$(parse_cnf sst cpat '.*\.pem$\|.*init\.ok$\|.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$')
+ if [ "${OS}" = "FreeBSD" ]; then
+ cpat=$(parse_cnf sst cpat '.*\.pem$|.*init\.ok$|.*galera\.cache$|.*sst_in_progress$|.*\.sst$|.*gvwstate\.dat$|.*grastate\.dat$|.*\.err$|.*\.log$|.*RPM_UPGRADE_MARKER$|.*RPM_UPGRADE_HISTORY$')
+ else
+ cpat=$(parse_cnf sst cpat '.*\.pem$\|.*init\.ok$\|.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$')
+ fi
ealgo=$(parse_cnf xtrabackup encrypt "")
ekey=$(parse_cnf xtrabackup encrypt-key "")
ekeyfile=$(parse_cnf xtrabackup encrypt-key-file "")
@@ -470,15 +462,15 @@ read_cnf()
# Pull the parameters needed for encrypt=4
ssl_ca=$(parse_cnf sst ssl-ca "")
if [[ -z "$ssl_ca" ]]; then
- ssl_ca=$(parse_cnf mysqld ssl-ca "")
+ ssl_ca=$(parse_cnf --mysqld ssl-ca "")
fi
ssl_cert=$(parse_cnf sst ssl-cert "")
if [[ -z "$ssl_cert" ]]; then
- ssl_cert=$(parse_cnf mysqld ssl-cert "")
+ ssl_cert=$(parse_cnf --mysqld ssl-cert "")
fi
ssl_key=$(parse_cnf sst ssl-key "")
if [[ -z "$ssl_key" ]]; then
- ssl_key=$(parse_cnf mysqld ssl-key "")
+ ssl_key=$(parse_cnf --mysqld ssl-key "")
fi
rlimit=$(parse_cnf sst rlimit "")
@@ -492,7 +484,7 @@ read_cnf()
ssystag+="-"
if [[ $ssyslog -ne -1 ]];then
- if $MY_PRINT_DEFAULTS mysqld_safe | tr '_' '-' | grep -q -- "--syslog";then
+ if $MY_PRINT_DEFAULTS mysqld_safe | grep -q -- "--syslog";then
ssyslog=1
fi
fi
@@ -635,18 +627,6 @@ kill_xtrabackup()
rm -f "$XTRABACKUP_PID" || true
}
-setup_ports()
-{
- if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then
- SST_PORT=$WSREP_SST_OPT_PORT
- REMOTEIP=$WSREP_SST_OPT_HOST
- lsn=$(echo $WSREP_SST_OPT_PATH | awk -F '[/]' '{ print $2 }')
- sst_ver=$(echo $WSREP_SST_OPT_PATH | awk -F '[/]' '{ print $3 }')
- else
- SST_PORT=$WSREP_SST_OPT_PORT
- fi
-}
-
# waits ~1 minute for nc/socat to open the port and then reports ready
# (regardless of timeout)
wait_for_listen()
@@ -654,22 +634,24 @@ wait_for_listen()
local HOST=$1
local PORT=$2
local MODULE=$3
+ local LSOF_OUT
for i in {1..300}
do
- ss -p state listening "( sport = :$PORT )" | grep -qE 'socat|nc' && break
+ LSOF_OUT=$(lsof -sTCP:LISTEN -i TCP:${PORT} -a -c nc -c socat -F c 2> /dev/null || :)
+ [ -n "${LSOF_OUT}" ] && break
sleep 0.2
done
- echo "ready ${HOST}:${PORT}/${MODULE}//$sst_ver"
+ echo "ready ${HOST}:${PORT}/${MODULE}//${WSREP_SST_OPT_SST_VER:-1}"
}
check_extra()
{
local use_socket=1
if [[ $uextra -eq 1 ]];then
- if $MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--thread-handling=" | grep -q 'pool-of-threads';then
- local eport=$($MY_PRINT_DEFAULTS mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2)
+ if [ $(parse_cnf --mysqld thread-handling) = 'pool-of-threads'];then
+ local eport=$(parse_cnf --mysqld extra-port)
if [[ -n $eport ]];then
# Xtrabackup works only locally.
# Hence, setting host to 127.0.0.1 unconditionally.
@@ -705,7 +687,7 @@ recv_joiner()
pushd ${dir} 1>/dev/null
set +e
- if [[ $tmt -gt 0 && -x `which timeout` ]];then
+ if [[ $tmt -gt 0 ]] && command -v timeout >/dev/null;then
if timeout --help | grep -q -- '-k';then
ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd"
else
@@ -801,10 +783,7 @@ check_for_version()
}
-if [[ ! -x `which $INNOBACKUPEX_BIN` ]];then
- wsrep_log_error "innobackupex not in path: $PATH"
- exit 2
-fi
+wsrep_check_programs "$INNOBACKUPEX_BIN"
# check the version, we require XB-2.4 to ensure that we can pass the
# datadir via the command-line option
@@ -830,7 +809,6 @@ if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor'
fi
read_cnf
-setup_ports
if ${INNOBACKUPEX_BIN} /tmp --help 2>/dev/null | grep -q -- '--version-check'; then
disver="--no-version-check"
@@ -846,7 +824,7 @@ INNOEXTRA=""
if [[ $ssyslog -eq 1 ]];then
- if [[ ! -x `which logger` ]];then
+ if ! command -v logger >/dev/null;then
wsrep_log_error "logger not in path: $PATH. Ignoring"
else
@@ -864,20 +842,24 @@ if [[ $ssyslog -eq 1 ]];then
logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@"
}
- INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts --apply-log \$rebuildcmd \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply "
- INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_DEFAULT} $disver $impts --datadir=${DATA} --move-back --force-non-empty-directories \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move "
- INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_DEFAULT} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)"
+ INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply "
+ INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move "
+ INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)"
fi
else
- INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts --apply-log \$rebuildcmd \${DATA} &>\${DATA}/innobackup.prepare.log"
- INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_DEFAULT} --defaults-group=mysqld${WSREP_SST_OPT_CONF_SUFFIX} $disver $impts --datadir=${DATA} --move-back --force-non-empty-directories \${DATA} &>\${DATA}/innobackup.move.log"
- INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_DEFAULT} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2>\${DATA}/innobackup.backup.log"
+ INNOAPPLY="&>\${DATA}/innobackup.prepare.log"
+ INNOMOVE="&>\${DATA}/innobackup.move.log"
+ INNOBACKUP="2>\${DATA}/innobackup.backup.log"
fi
get_stream
get_transfer
+INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts --apply-log \$rebuildcmd \${DATA} ${INNOAPPLY}"
+INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} ${INNOMOVE}"
+INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir ${INNOBACKUP}"
+
if [ "$WSREP_SST_OPT_ROLE" = "donor" ]
then
trap cleanup_donor EXIT
@@ -885,13 +867,13 @@ then
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
then
usrst=0
- if [[ -z $sst_ver ]];then
+ if [[ -z $WSREP_SST_OPT_SST_VER ]];then
wsrep_log_error "Upgrade joiner to 5.6.21 or higher for backup locks support"
wsrep_log_error "The joiner is not supported for this version of donor"
exit 93
fi
- if [[ -z $(parse_cnf mysqld tmpdir "") && -z $(parse_cnf xtrabackup tmpdir "") ]];then
+ if [[ -z $(parse_cnf --mysqld tmpdir "") && -z $(parse_cnf xtrabackup tmpdir "") ]];then
xtmpdir=$(mktemp -d)
tmpopts=" --tmpdir=$xtmpdir "
wsrep_log_info "Using $xtmpdir as xtrabackup temporary directory"
@@ -948,7 +930,7 @@ then
wsrep_log_info "Sleeping before data transfer for SST"
sleep 10
- wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP} ${SST_PORT:-4444}"
+ wsrep_log_info "Streaming the backup to joiner at ${WSREP_SST_OPT_HOST} ${WSREP_SST_OPT_PORT:-4444}"
# Add compression to the head of the stream (if specified)
if [[ -n $scomp ]]; then
@@ -1010,9 +992,9 @@ then
[[ -e $SST_PROGRESS_FILE ]] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE"
[[ -n $SST_PROGRESS_FILE ]] && touch $SST_PROGRESS_FILE
- ib_home_dir=$(parse_cnf mysqld innodb-data-home-dir "")
- ib_log_dir=$(parse_cnf mysqld innodb-log-group-home-dir "")
- ib_undo_dir=$(parse_cnf mysqld innodb-undo-directory "")
+ ib_home_dir=$(parse_cnf --mysqld innodb-data-home-dir "")
+ ib_log_dir=$(parse_cnf --mysqld innodb-log-group-home-dir "")
+ ib_undo_dir=$(parse_cnf --mysqld innodb-undo-directory "")
stagemsg="Joiner-Recv"
@@ -1072,9 +1054,13 @@ then
wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories"
- find $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -regex $cpat -prune -o -exec rm -rfv {} 1>&2 \+
+ if [ "${OS}" = "FreeBSD" ]; then
+ find -E $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+
+ else
+ find $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+
+ fi
- tempdir=$(parse_cnf mysqld log-bin "")
+ tempdir=$(parse_cnf --mysqld log-bin "")
if [[ -n ${tempdir:-} ]];then
binlog_dir=$(dirname $tempdir)
binlog_file=$(basename $tempdir)
@@ -1119,7 +1105,7 @@ then
wsrep_log_info "Compressed qpress files found"
- if [[ ! -x `which qpress` ]];then
+ if ! command -v qpress >/dev/null;then
wsrep_log_error "qpress not found in path: $PATH"
exit 22
fi
diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh
index ca3c0129837..d80677e7a76 100644
--- a/scripts/wsrep_sst_xtrabackup.sh
+++ b/scripts/wsrep_sst_xtrabackup.sh
@@ -30,15 +30,13 @@ encrypt=0
nproc=1
ecode=0
XTRABACKUP_PID=""
-SST_PORT=""
-REMOTEIP=""
tcert=""
tpem=""
sockopt=""
progress=""
ttime=0
totime=0
-lsn=""
+lsn="${WSREP_SST_OPT_LSN}"
incremental=0
ecmd=""
rlimit=""
@@ -54,7 +52,7 @@ pvformat="-F '%N => Rate:%r Avg:%a Elapsed:%t %e Bytes: %b %p' "
pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE "
uextra=0
-if which pv &>/dev/null && pv --help | grep -q FORMAT;then
+if pv --help 2>/dev/null | grep -q FORMAT;then
pvopts+=$pvformat
fi
pcmd="pv $pvopts"
@@ -136,17 +134,10 @@ get_keys()
get_transfer()
{
- if [[ -z $SST_PORT ]];then
- TSST_PORT=4444
- else
- TSST_PORT=$SST_PORT
- fi
+ TSST_PORT=${WSREP_SST_OPT_PORT:-4444}
if [[ $tfmt == 'nc' ]];then
- if [[ ! -x `which nc` ]];then
- wsrep_log_error "nc(netcat) not found in path: $PATH"
- exit 2
- fi
+ wsrep_check_programs nc
wsrep_log_info "Using netcat as streamer"
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
if nc -h 2>&1 | grep -q ncat;then
@@ -155,15 +146,12 @@ get_transfer()
tcmd="nc -dl ${TSST_PORT}"
fi
else
- tcmd="nc ${REMOTEIP} ${TSST_PORT}"
+ tcmd="nc ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}"
fi
else
tfmt='socat'
+ wsrep_check_programs socat
wsrep_log_info "Using socat as streamer"
- if [[ ! -x `which socat` ]];then
- wsrep_log_error "socat not found in path: $PATH"
- exit 2
- fi
if [[ $encrypt -eq 2 ]] && ! socat -V | grep -q OPENSSL;then
wsrep_log_info "NOTE: socat is not openssl enabled, falling back to plain transfer"
@@ -181,34 +169,23 @@ get_transfer()
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=$tpem,cafile=${tcert}${sockopt} stdio"
else
wsrep_log_info "Encrypting with PEM $tpem, CA: $tcert"
- tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=$tpem,cafile=${tcert}${sockopt}"
+ tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert=$tpem,cafile=${tcert}${sockopt}"
fi
else
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio"
else
- tcmd="socat -u stdio TCP:${REMOTEIP}:${TSST_PORT}${sockopt}"
+ tcmd="socat -u stdio TCP:${WSREP_SST_OPT_HOST}:${TSST_PORT}${sockopt}"
fi
fi
fi
}
-parse_cnf()
-{
- local group=$1
- local var=$2
- reval=$($MY_PRINT_DEFAULTS $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2-)
- if [[ -z $reval ]];then
- [[ -n $3 ]] && reval=$3
- fi
- echo $reval
-}
-
get_footprint()
{
pushd $WSREP_SST_OPT_DATA 1>/dev/null
- payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c | awk 'END { print $1 }')
+ payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }')
if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress";then
# QuickLZ has around 50% compression ratio
# When compression/compaction used, the progress is only an approximate.
@@ -354,17 +331,6 @@ kill_xtrabackup()
rm -f "$XTRABACKUP_PID"
}
-setup_ports()
-{
- if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then
- 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 }')
- else
- SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }')
- fi
-}
-
# waits ~10 seconds for nc to open the port and then reports ready
# (regardless of timeout)
wait_for_listen()
@@ -388,8 +354,8 @@ check_extra()
{
local use_socket=1
if [[ $uextra -eq 1 ]];then
- if $MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--thread-handling=" | grep -q 'pool-of-threads';then
- local eport=$($MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2)
+ if [ $(parse_cnf --mysqld thread-handling) = 'pool-of-threads'];then
+ local eport=$(parse_cnf --mysqld extra-port)
if [[ -n $eport ]];then
# Xtrabackup works only locally.
# Hence, setting host to 127.0.0.1 unconditionally.
@@ -409,10 +375,7 @@ check_extra()
fi
}
-if [[ ! -x `which innobackupex` ]];then
- wsrep_log_error "innobackupex not in path: $PATH"
- exit 2
-fi
+wsrep_check_programs "innobackupex"
rm -f "${MAGIC_FILE}"
@@ -466,7 +429,7 @@ then
check_extra
- wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP} ${SST_PORT}"
+ wsrep_log_info "Streaming the backup to joiner at ${WSREP_SST_OPT_HOST} ${WSREP_SST_OPT_PORT}"
if [[ -n $progress ]];then
get_footprint
@@ -547,14 +510,9 @@ then
# May need xtrabackup_checkpoints later on
rm -f ${DATA}/xtrabackup_binary ${DATA}/xtrabackup_galera_info ${DATA}/xtrabackup_logfile
- ADDR=${WSREP_SST_OPT_ADDR}
- if [ -z "${SST_PORT}" ]
- then
- SST_PORT=4444
- ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $1 }'):${SST_PORT}"
- fi
+ ADDR="${WSREP_SST_OPT_HOST}:${WSREP_SST_OPT_PORT:-4444}"
- wait_for_listen ${SST_PORT} ${ADDR} ${MODULE} &
+ wait_for_listen ${WSREP_SST_OPT_PORT:-4444} ${ADDR} ${MODULE} &
trap sig_joiner_cleanup HUP PIPE INT TERM
trap cleanup_joiner EXIT
@@ -645,7 +603,7 @@ then
wsrep_log_info "Compressed qpress files found"
- if [[ ! -x `which qpress` ]];then
+ if ! command -v qpress >/dev/null;then
wsrep_log_error "qpress not found in path: $PATH"
exit 22
fi
diff --git a/sql-common/client.c b/sql-common/client.c
index d2dc79672db..94f50eae30b 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -96,6 +96,7 @@ my_bool net_flush(NET *net);
#ifndef _WIN32
#include <errno.h>
#define SOCKET_ERROR -1
+#define INVALID_SOCKET -1
#endif
#ifdef __WIN__
@@ -258,7 +259,6 @@ HANDLE create_named_pipe(MYSQL *mysql, uint connect_timeout, char **arg_host,
char pipe_name[1024];
DWORD dwMode;
int i;
- my_bool testing_named_pipes=0;
char *host= *arg_host, *unix_socket= *arg_unix_socket;
if ( ! unix_socket || (unix_socket)[0] == 0x00)
@@ -369,7 +369,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
char *shared_memory_base_name = mysql->options.shared_memory_base_name;
static const char *name_prefixes[] = {"","Global\\"};
const char *prefix;
- int i;
+ uint i;
/*
If this is NULL, somebody freed the MYSQL* options. mysql_close()
@@ -740,7 +740,7 @@ void free_old_query(MYSQL *mysql)
if (mysql->fields)
free_root(&mysql->field_alloc,MYF(0));
/* Assume rowlength < 8192 */
- init_alloc_root(&mysql->field_alloc, 8192, 0,
+ init_alloc_root(&mysql->field_alloc, "fields", 8192, 0,
MYF(mysql->options.use_thread_specific_memory ?
MY_THREAD_SPECIFIC : 0));
mysql->fields= 0;
@@ -915,13 +915,6 @@ static int cli_report_progress(MYSQL *mysql, char *pkt, uint length)
return 0;
}
-#ifdef __WIN__
-static my_bool is_NT(void)
-{
- char *os=getenv("OS");
- return (os && !strcmp(os, "Windows_NT")) ? 1 : 0;
-}
-#endif
/**************************************************************************
Shut down connection
@@ -1234,11 +1227,12 @@ void mysql_read_default_options(struct st_mysql_options *options,
options->max_allowed_packet= atoi(opt_arg);
break;
case OPT_protocol:
- if ((options->protocol= find_type(opt_arg, &sql_protocol_typelib,
+ if (options->protocol != UINT_MAX32 &&
+ (options->protocol= find_type(opt_arg, &sql_protocol_typelib,
FIND_TYPE_BASIC)) <= 0)
{
fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
- exit(1);
+ options->protocol= UINT_MAX32;
}
break;
case OPT_shared_memory_base_name:
@@ -1463,7 +1457,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
DBUG_RETURN(0);
}
/* Assume rowlength < 8192 */
- init_alloc_root(&result->alloc, 8192, 0,
+ init_alloc_root(&result->alloc, "result", 8192, 0,
MYF(mysql->options.use_thread_specific_memory ?
MY_THREAD_SPECIFIC : 0));
result->alloc.min_malloc=sizeof(MYSQL_ROWS);
@@ -2971,7 +2965,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
/* new "use different plugin" packet */
uint len;
auth_plugin_name= (char*)mysql->net.read_pos + 1;
- len= strlen(auth_plugin_name); /* safe as my_net_read always appends \0 */
+ len= (uint)strlen(auth_plugin_name); /* safe as my_net_read always appends \0 */
mpvio.cached_server_reply.pkt_len= pkt_length - len - 2;
mpvio.cached_server_reply.pkt= mysql->net.read_pos + len + 2;
DBUG_PRINT ("info", ("change plugin packet from server for plugin %s",
@@ -3133,6 +3127,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
my_free(mysql->options.my_cnf_file);
my_free(mysql->options.my_cnf_group);
mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
+ if (mysql->options.protocol == UINT_MAX32)
+ goto error;
}
/* Some empty-string-tests are done because of ODBC */
@@ -3212,7 +3208,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
{
my_socket sock= socket(AF_UNIX, SOCK_STREAM, 0);
DBUG_PRINT("info", ("Using socket"));
- if (sock == SOCKET_ERROR)
+ if (sock == INVALID_SOCKET)
{
set_mysql_extended_error(mysql, CR_SOCKET_CREATE_ERROR,
unknown_sqlstate,
@@ -3259,7 +3255,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
if (!net->vio &&
(mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
- (! have_tcpip && (unix_socket || !host && is_NT()))))
+ (! have_tcpip && (unix_socket || !host ))))
{
if ((hPipe= create_named_pipe(mysql, mysql->options.connect_timeout,
(char**) &host, (char**) &unix_socket)) ==
@@ -3293,7 +3289,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
struct addrinfo *res_lst, hints, *t_res;
int gai_errno;
char port_buf[NI_MAXSERV];
- my_socket sock= SOCKET_ERROR;
+ my_socket sock= INVALID_SOCKET;
int saved_error= 0, status= -1;
unix_socket=0; /* This is not used */
@@ -3341,7 +3337,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
t_res->ai_family, t_res->ai_socktype,
t_res->ai_protocol));
sock= socket(t_res->ai_family, t_res->ai_socktype, t_res->ai_protocol);
- if (sock == SOCKET_ERROR)
+ if (sock == INVALID_SOCKET)
{
saved_error= socket_errno;
continue;
@@ -3358,7 +3354,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
DBUG_PRINT("info", ("Connect socket"));
status= connect_sync_or_async(mysql, net, sock,
- t_res->ai_addr, t_res->ai_addrlen);
+ t_res->ai_addr, (uint)t_res->ai_addrlen);
/*
Here we rely on my_connect() to return success only if the
connect attempt was really successful. Otherwise we would stop
@@ -3383,7 +3379,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
freeaddrinfo(res_lst);
- if (sock == SOCKET_ERROR)
+ if (sock == INVALID_SOCKET)
{
set_mysql_extended_error(mysql, CR_IPSOCK_ERROR, unknown_sqlstate,
ER(CR_IPSOCK_ERROR), saved_error);
diff --git a/sql-common/client_plugin.c b/sql-common/client_plugin.c
index f93e50125c5..f81660f8986 100644
--- a/sql-common/client_plugin.c
+++ b/sql-common/client_plugin.c
@@ -251,7 +251,7 @@ int mysql_client_plugin_init()
bzero(&mysql, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */
mysql_mutex_init(0, &LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW);
- init_alloc_root(&mem_root, 128, 128, MYF(0));
+ init_alloc_root(&mem_root, "client_plugin", 128, 128, MYF(0));
bzero(&plugin_list, sizeof(plugin_list));
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index c8d8453b62f..c4731d6b601 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -293,7 +293,7 @@ static void get_microseconds(ulong *val, MYSQL_TIME_STATUS *status,
#define MAX_DATE_PARTS 8
my_bool
-str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
+str_to_datetime(const char *str, size_t length, MYSQL_TIME *l_time,
ulonglong flags, MYSQL_TIME_STATUS *status)
{
const char *end=str+length, *pos;
@@ -457,7 +457,7 @@ err:
TRUE on error
*/
-my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
+my_bool str_to_time(const char *str, size_t length, MYSQL_TIME *l_time,
ulonglong fuzzydate, MYSQL_TIME_STATUS *status)
{
ulong date[5];
@@ -1426,31 +1426,3 @@ double TIME_to_double(const MYSQL_TIME *my_time)
d+= my_time->second_part/(double)TIME_SECOND_PART_FACTOR;
return my_time->neg ? -d : d;
}
-
-longlong pack_time(const MYSQL_TIME *my_time)
-{
- return ((((((my_time->year * 13ULL +
- my_time->month) * 32ULL +
- my_time->day) * 24ULL +
- my_time->hour) * 60ULL +
- my_time->minute) * 60ULL +
- my_time->second) * 1000000ULL +
- my_time->second_part) * (my_time->neg ? -1 : 1);
-}
-
-#define get_one(WHERE, FACTOR) WHERE= (ulong)(packed % FACTOR); packed/= FACTOR
-
-MYSQL_TIME *unpack_time(longlong packed, MYSQL_TIME *my_time)
-{
- if ((my_time->neg= packed < 0))
- packed= -packed;
- get_one(my_time->second_part, 1000000ULL);
- get_one(my_time->second, 60U);
- get_one(my_time->minute, 60U);
- get_one(my_time->hour, 24U);
- get_one(my_time->day, 32U);
- get_one(my_time->month, 13U);
- my_time->year= (uint)packed;
- my_time->time_type= MYSQL_TIMESTAMP_DATETIME;
- return my_time;
-}
diff --git a/sql-common/mysql_async.c b/sql-common/mysql_async.c
index 1bac16edd1e..a19955c49de 100644
--- a/sql-common/mysql_async.c
+++ b/sql-common/mysql_async.c
@@ -135,7 +135,7 @@ my_recv_async(struct mysql_async_context *b, my_socket fd,
for (;;)
{
- res= recv(fd, buf, size, IF_WIN(0, MSG_DONTWAIT));
+ res= recv(fd, buf, (int)size, IF_WIN(0, MSG_DONTWAIT));
if (res >= 0 || IS_BLOCKING_ERROR())
return res;
b->events_to_wait_for= MYSQL_WAIT_READ;
@@ -163,7 +163,7 @@ my_send_async(struct mysql_async_context *b, my_socket fd,
for (;;)
{
- res= send(fd, buf, size, IF_WIN(0, MSG_DONTWAIT));
+ res= send(fd, buf, (int)size, IF_WIN(0, MSG_DONTWAIT));
if (res >= 0 || IS_BLOCKING_ERROR())
return res;
b->events_to_wait_for= MYSQL_WAIT_WRITE;
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 0f67032bcbe..c7c4df279e7 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -1,5 +1,5 @@
# Copyright (c) 2006, 2014, Oracle and/or its affiliates.
-# Copyright (c) 2010, 2016, MariaDB Corporation
+# Copyright (c) 2010, 2018, 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
@@ -36,7 +36,7 @@ ELSE()
ENDIF()
INCLUDE_DIRECTORIES(
-${CMAKE_SOURCE_DIR}/include
+${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/sql
${PCRE_INCLUDES}
${ZLIB_INCLUDE_DIR}
@@ -110,7 +110,7 @@ SET (SQL_SOURCE
debug_sync.cc
sql_repl.cc sql_select.cc sql_show.cc sql_state.c
group_by_handler.cc
- sql_statistics.cc sql_string.cc
+ sql_statistics.cc sql_string.cc lex_string.h
sql_table.cc sql_test.cc sql_trigger.cc sql_udf.cc sql_union.cc
sql_update.cc sql_view.cc strfunc.cc table.cc thr_malloc.cc
sql_time.cc tztime.cc unireg.cc item_xmlfunc.cc
@@ -122,7 +122,7 @@ SET (SQL_SOURCE
rpl_rli.cc rpl_mi.cc sql_servers.cc sql_audit.cc
sql_connect.cc scheduler.cc sql_partition_admin.cc
sql_profile.cc event_parse_data.cc sql_alter.cc
- sql_signal.cc rpl_handler.cc mdl.cc sql_admin.cc
+ sql_signal.cc mdl.cc sql_admin.cc
transaction.cc sys_vars.cc sql_truncate.cc datadict.cc
sql_reload.cc item_inetfunc.cc
@@ -138,17 +138,22 @@ SET (SQL_SOURCE
my_apc.cc mf_iocache_encr.cc item_jsonfunc.cc
my_json_writer.cc
rpl_gtid.cc rpl_parallel.cc
+ semisync.cc semisync_master.cc semisync_slave.cc
+ semisync_master_ack_receiver.cc
sql_type.cc
item_windowfunc.cc sql_window.cc
sql_cte.cc
+ item_vers.cc
sql_sequence.cc sql_sequence.h ha_sequence.h
sql_tvc.cc sql_tvc.h
+ opt_split.cc
${WSREP_SOURCES}
table_cache.cc encryption.cc temporary_tables.cc
proxy_protocol.cc
${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc
${GEN_SOURCES}
${MYSYS_LIBWRAP_SOURCE}
+ vtmd.cc
)
IF (CMAKE_SYSTEM_NAME MATCHES "Linux" OR
diff --git a/sql/authors.h b/sql/authors.h
index 3a8f5497248..609b77059f4 100644
--- a/sql/authors.h
+++ b/sql/authors.h
@@ -75,6 +75,8 @@ struct show_table_authors_st show_table_authors[]= {
"Prepared statements (4.1), Cursors (5.0), GET_LOCK (10.0)" },
{ "Ian Gilfillan", "South Africa", "MariaDB documentation"},
{ "Federico Razolli", "Italy", "MariaDB documentation Italian translation"},
+ { "Vinchen", "Shenzhen, China", "Instant ADD Column for InnoDB, Spider engine optimization, from Tencent Game DBA Team" },
+ { "Willhan", "Shenzhen, China", "Big Column Compression, Spider engine optimization, from Tencent Game DBA Team" },
/* People working on MySQL code base (not NDB) */
{ "Guilhem Bichot", "Bordeaux, France", "Replication (since 4.0)" },
diff --git a/sql/compat56.cc b/sql/compat56.cc
index 6cbf4a66ac8..16c25924d6e 100644
--- a/sql/compat56.cc
+++ b/sql/compat56.cc
@@ -45,8 +45,10 @@
*/
longlong TIME_to_longlong_time_packed(const MYSQL_TIME *ltime)
{
- /* If month is 0, we mix day with hours: "1 00:10:10" -> "24:00:10" */
- long hms= (((ltime->month ? 0 : ltime->day * 24) + ltime->hour) << 12) |
+ DBUG_ASSERT(ltime->year == 0);
+ DBUG_ASSERT(ltime->month == 0);
+ // Mix days with hours: "1 00:10:10" -> "24:10:10"
+ long hms= ((ltime->day * 24 + ltime->hour) << 12) |
(ltime->minute << 6) | ltime->second;
longlong tmp= MY_PACKED_TIME_MAKE(hms, ltime->second_part);
return ltime->neg ? -tmp : tmp;
diff --git a/sql/contributors.h b/sql/contributors.h
index 88a4a088acf..7369dcd141d 100644
--- a/sql/contributors.h
+++ b/sql/contributors.h
@@ -38,8 +38,9 @@ struct show_table_contributors_st {
struct show_table_contributors_st show_table_contributors[]= {
/* MariaDB foundation sponsors, in contribution, size , time order */
{"Booking.com", "https://www.booking.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
- {"Alibaba Cloud", "https://intl.aliyun.com", "Platinum Sponsor of the MariaDB Foundation"},
+ {"Alibaba Cloud", "https://www.alibabacloud.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"Tencent Cloud", "https://cloud.tencent.com", "Platinum Sponsor of the MariaDB Foundation"},
+ {"Microsoft", "https://microsoft.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"MariaDB Corporation", "https://mariadb.com", "Founding member, Gold Sponsor of the MariaDB Foundation"},
{"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"},
{"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
diff --git a/sql/create_options.cc b/sql/create_options.cc
index d010b73c222..7837beb516f 100644
--- a/sql/create_options.cc
+++ b/sql/create_options.cc
@@ -545,7 +545,7 @@ uint engine_option_value::frm_length()
if value.str is NULL, this option is not written to frm (=DEFAULT)
*/
- return value.str ? 1 + name.length + 2 + value.length : 0;
+ return value.str ? (uint)(1 + name.length + 2 + value.length) : 0;
}
@@ -613,7 +613,8 @@ uchar *engine_option_value::frm_image(uchar *buff)
{
if (value.str)
{
- *buff++= name.length;
+ DBUG_ASSERT(name.length <= 0xff);
+ *buff++= (uchar)name.length;
memcpy(buff, name.str, name.length);
buff+= name.length;
int2store(buff, value.length | (quoted_value ? FRM_QUOTED_VALUE : 0));
@@ -729,7 +730,7 @@ uchar *engine_option_value::frm_read(const uchar *buff, const uchar *buff_end,
@retval FALSE OK
*/
-bool engine_table_options_frm_read(const uchar *buff, uint length,
+bool engine_table_options_frm_read(const uchar *buff, size_t length,
TABLE_SHARE *share)
{
const uchar *buff_end= buff + length;
diff --git a/sql/create_options.h b/sql/create_options.h
index 41e8abcb232..c82cb875743 100644
--- a/sql/create_options.h
+++ b/sql/create_options.h
@@ -87,7 +87,7 @@ bool parse_option_list(THD* thd, handlerton *hton, void *option_struct,
engine_option_value **option_list,
ha_create_table_option *rules,
bool suppress_warning, MEM_ROOT *root);
-bool engine_table_options_frm_read(const uchar *buff, uint length,
+bool engine_table_options_frm_read(const uchar *buff, size_t length,
TABLE_SHARE *share);
engine_option_value *merge_engine_table_options(engine_option_value *source,
engine_option_value *changes,
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index d44b313ec24..58a01a77849 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -465,13 +465,13 @@ static int debug_sync_qsort_cmp(const void* arg1, const void* arg2)
static st_debug_sync_action *debug_sync_find(st_debug_sync_action *actionarr,
int quantity,
const char *dsp_name,
- uint name_len)
+ size_t name_len)
{
st_debug_sync_action *action;
int low ;
int high ;
int mid ;
- int diff ;
+ ssize_t diff ;
DBUG_ASSERT(actionarr);
DBUG_ASSERT(dsp_name);
DBUG_ASSERT(name_len);
diff --git a/sql/derror.cc b/sql/derror.cc
index 8be1c26b7e4..8011f8c4020 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -213,8 +213,11 @@ static File open_error_msg_file(const char *file_name, const char *language,
O_RDONLY | O_SHARE | O_BINARY,
MYF(0))) < 0)
goto err;
- sql_print_warning("An old style --language or -lc-message-dir value with language specific part detected: %s", lc_messages_dir);
- sql_print_warning("Use --lc-messages-dir without language specific part instead.");
+ if (global_system_variables.log_warnings > 2)
+ {
+ sql_print_warning("An old style --language or -lc-message-dir value with language specific part detected: %s", lc_messages_dir);
+ sql_print_warning("Use --lc-messages-dir without language specific part instead.");
+ }
}
error_pos=1;
if (mysql_file_read(file, (uchar*) head, 32, MYF(MY_NABP)))
diff --git a/sql/des_key_file.cc b/sql/des_key_file.cc
index e7785a0a223..1f81fb9fd3f 100644
--- a/sql/des_key_file.cc
+++ b/sql/des_key_file.cc
@@ -59,7 +59,7 @@ load_des_key_file(const char *file_name)
char *start, *end;
char buf[1024], offset;
st_des_keyblock keyblock;
- uint length;
+ size_t length;
if (!(length=my_b_gets(&io,buf,sizeof(buf)-1)))
break; // End of file
diff --git a/sql/discover.cc b/sql/discover.cc
index a683166fb7f..7184cde5e03 100644
--- a/sql/discover.cc
+++ b/sql/discover.cc
@@ -136,7 +136,7 @@ int writefrm(const char *path, const char *db, const char *table,
}
else
{
- error= mysql_file_write(file, frmdata, len, MYF(MY_WME | MY_NABP));
+ error= (int)mysql_file_write(file, frmdata, len, MYF(MY_WME | MY_NABP));
if (!error && !tmp_table && opt_sync_frm)
error= mysql_file_sync(file, MYF(MY_WME)) ||
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index c85192ee258..59aa6bcabc6 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -171,11 +171,11 @@ Event_creation_ctx::load_from_db(THD *thd,
*/
bool
-Event_queue_element_for_exec::init(LEX_CSTRING db, LEX_CSTRING n)
+Event_queue_element_for_exec::init(const LEX_CSTRING *db, const LEX_CSTRING *n)
{
- if (!(dbname.str= my_strndup(db.str, dbname.length= db.length, MYF(MY_WME))))
+ if (!(dbname.str= my_strndup(db->str, dbname.length= db->length, MYF(MY_WME))))
return TRUE;
- if (!(name.str= my_strndup(n.str, name.length= n.length, MYF(MY_WME))))
+ if (!(name.str= my_strndup(n->str, name.length= n->length, MYF(MY_WME))))
{
my_free(const_cast<char*>(dbname.str));
return TRUE;
@@ -209,7 +209,7 @@ Event_basic::Event_basic()
{
DBUG_ENTER("Event_basic::Event_basic");
/* init memory root */
- init_sql_alloc(&mem_root, 256, 512, MYF(0));
+ init_sql_alloc(&mem_root, "Event_basic", 256, 512, MYF(0));
dbname.str= name.str= NULL;
dbname.length= name.length= 0;
time_zone= NULL;
@@ -1196,7 +1196,7 @@ Event_timed::get_create_event(THD *thd, String *buf)
buf->append(STRING_WITH_LEN("CREATE "));
append_definer(thd, buf, &definer_user, &definer_host);
buf->append(STRING_WITH_LEN("EVENT "));
- append_identifier(thd, buf, name.str, name.length);
+ append_identifier(thd, buf, &name);
if (expression)
{
@@ -1266,15 +1266,15 @@ Event_job_data::construct_sp_sql(THD *thd, String *sp_sql)
sp_sql->length(0);
- sp_sql->append(C_STRING_WITH_LEN("CREATE "));
- sp_sql->append(C_STRING_WITH_LEN("PROCEDURE "));
+ sp_sql->append(STRING_WITH_LEN("CREATE "));
+ sp_sql->append(STRING_WITH_LEN("PROCEDURE "));
/*
Let's use the same name as the event name to perhaps produce a
better error message in case it is a part of some parse error.
We're using append_identifier here to successfully parse
events with reserved names.
*/
- append_identifier(thd, sp_sql, name.str, name.length);
+ append_identifier(thd, sp_sql, &name);
/*
The default SQL security of a stored procedure is DEFINER. We
@@ -1282,7 +1282,7 @@ Event_job_data::construct_sp_sql(THD *thd, String *sp_sql)
let's execute the procedure with the invoker rights to save on
resets of security contexts.
*/
- sp_sql->append(C_STRING_WITH_LEN("() SQL SECURITY INVOKER "));
+ sp_sql->append(STRING_WITH_LEN("() SQL SECURITY INVOKER "));
sp_sql->append(&body);
@@ -1310,10 +1310,10 @@ Event_job_data::construct_drop_event_sql(THD *thd, String *sp_sql)
sp_sql->set(buffer.str, buffer.length, system_charset_info);
sp_sql->length(0);
- sp_sql->append(C_STRING_WITH_LEN("DROP EVENT "));
- append_identifier(thd, sp_sql, dbname.str, dbname.length);
+ sp_sql->append(STRING_WITH_LEN("DROP EVENT "));
+ append_identifier(thd, sp_sql, &dbname);
sp_sql->append('.');
- append_identifier(thd, sp_sql, name.str, name.length);
+ append_identifier(thd, sp_sql, &name);
DBUG_RETURN(thd->is_fatal_error);
}
@@ -1355,7 +1355,7 @@ Event_job_data::execute(THD *thd, bool drop)
mysql_change_db will be invoked anyway later, to activate the
procedure database before it's executed.
*/
- thd->set_db(dbname.str, dbname.length);
+ thd->set_db(&dbname);
lex_start(thd);
diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h
index 884bbd7d701..8afed7df4c9 100644
--- a/sql/event_data_objects.h
+++ b/sql/event_data_objects.h
@@ -37,7 +37,7 @@ public:
~Event_queue_element_for_exec();
bool
- init(LEX_CSTRING dbname, LEX_CSTRING name);
+ init(const LEX_CSTRING *dbname, const LEX_CSTRING *name);
LEX_CSTRING dbname;
LEX_CSTRING name;
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 9d899cb637e..61b1c2de15d 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -41,38 +41,38 @@ static
const TABLE_FIELD_TYPE event_table_fields[ET_FIELD_COUNT] =
{
{
- { C_STRING_WITH_LEN("db") },
- { C_STRING_WITH_LEN("char(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("db") },
+ { STRING_WITH_LEN("char(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("name") },
- { C_STRING_WITH_LEN("char(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("name") },
+ { STRING_WITH_LEN("char(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("body") },
- { C_STRING_WITH_LEN("longblob") },
+ { STRING_WITH_LEN("body") },
+ { STRING_WITH_LEN("longblob") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("definer") },
- { C_STRING_WITH_LEN("char(") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("definer") },
+ { STRING_WITH_LEN("char(") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("execute_at") },
- { C_STRING_WITH_LEN("datetime") },
+ { STRING_WITH_LEN("execute_at") },
+ { STRING_WITH_LEN("datetime") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("interval_value") },
- { C_STRING_WITH_LEN("int(11)") },
+ { STRING_WITH_LEN("interval_value") },
+ { STRING_WITH_LEN("int(11)") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("interval_field") },
- { C_STRING_WITH_LEN("enum('YEAR','QUARTER','MONTH','DAY',"
+ { STRING_WITH_LEN("interval_field") },
+ { STRING_WITH_LEN("enum('YEAR','QUARTER','MONTH','DAY',"
"'HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR',"
"'DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND',"
"'DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND',"
@@ -80,43 +80,43 @@ const TABLE_FIELD_TYPE event_table_fields[ET_FIELD_COUNT] =
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("created") },
- { C_STRING_WITH_LEN("timestamp") },
+ { STRING_WITH_LEN("created") },
+ { STRING_WITH_LEN("timestamp") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("modified") },
- { C_STRING_WITH_LEN("timestamp") },
+ { STRING_WITH_LEN("modified") },
+ { STRING_WITH_LEN("timestamp") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("last_executed") },
- { C_STRING_WITH_LEN("datetime") },
+ { STRING_WITH_LEN("last_executed") },
+ { STRING_WITH_LEN("datetime") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("starts") },
- { C_STRING_WITH_LEN("datetime") },
+ { STRING_WITH_LEN("starts") },
+ { STRING_WITH_LEN("datetime") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("ends") },
- { C_STRING_WITH_LEN("datetime") },
+ { STRING_WITH_LEN("ends") },
+ { STRING_WITH_LEN("datetime") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("status") },
- { C_STRING_WITH_LEN("enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')") },
+ { STRING_WITH_LEN("status") },
+ { STRING_WITH_LEN("enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("on_completion") },
- { C_STRING_WITH_LEN("enum('DROP','PRESERVE')") },
+ { STRING_WITH_LEN("on_completion") },
+ { STRING_WITH_LEN("enum('DROP','PRESERVE')") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("sql_mode") },
- { C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
+ { STRING_WITH_LEN("sql_mode") },
+ { STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
"'IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY',"
"'NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
@@ -124,46 +124,49 @@ const TABLE_FIELD_TYPE event_table_fields[ET_FIELD_COUNT] =
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
"'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES',"
"'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER',"
- "'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')") },
+ "'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH',"
+ "'EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("comment") },
- { C_STRING_WITH_LEN("char(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("comment") },
+ { STRING_WITH_LEN("char(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("originator") },
- { C_STRING_WITH_LEN("int(10)") },
+ { STRING_WITH_LEN("originator") },
+ { STRING_WITH_LEN("int(10)") },
{NULL, 0}
},
{
- { C_STRING_WITH_LEN("time_zone") },
- { C_STRING_WITH_LEN("char(64)") },
- { C_STRING_WITH_LEN("latin1") }
+ { STRING_WITH_LEN("time_zone") },
+ { STRING_WITH_LEN("char(64)") },
+ { STRING_WITH_LEN("latin1") }
},
{
- { C_STRING_WITH_LEN("character_set_client") },
- { C_STRING_WITH_LEN("char(32)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("character_set_client") },
+ { STRING_WITH_LEN("char(32)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("collation_connection") },
- { C_STRING_WITH_LEN("char(32)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("collation_connection") },
+ { STRING_WITH_LEN("char(32)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("db_collation") },
- { C_STRING_WITH_LEN("char(32)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("db_collation") },
+ { STRING_WITH_LEN("char(32)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("body_utf8") },
- { C_STRING_WITH_LEN("longblob") },
+ { STRING_WITH_LEN("body_utf8") },
+ { STRING_WITH_LEN("longblob") },
{ NULL, 0 }
}
};
+static LEX_CSTRING MYSQL_EVENT_NAME= { STRING_WITH_LEN("event") };
+
static const TABLE_FIELD_DEF
event_table_def= {ET_FIELD_COUNT, event_table_fields, 0, (uint*) 0};
@@ -538,7 +541,7 @@ Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *i_s_table,
DBUG_ENTER("Event_db_repository::fill_schema_events");
DBUG_PRINT("info",("db=%s", db? db:"(null)"));
- event_table.init_one_table("mysql", 5, "event", 5, "event", TL_READ);
+ event_table.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_EVENT_NAME, 0, TL_READ);
if (open_system_tables_for_read(thd, &event_table, &open_tables_backup))
DBUG_RETURN(TRUE);
@@ -600,7 +603,7 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type,
TABLE_LIST tables;
DBUG_ENTER("Event_db_repository::open_event_table");
- tables.init_one_table("mysql", 5, "event", 5, "event", lock_type);
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_EVENT_NAME, 0, lock_type);
if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
DBUG_RETURN(TRUE);
@@ -1066,7 +1069,7 @@ Event_db_repository::load_named_event(THD *thd, const LEX_CSTRING *dbname,
DBUG_PRINT("enter",("thd: %p name: %*s", thd,
(int) name->length, name->str));
- event_table.init_one_table("mysql", 5, "event", 5, "event", TL_READ);
+ event_table.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_EVENT_NAME, 0, TL_READ);
/* Reset sql_mode during data dictionary operations. */
thd->variables.sql_mode= 0;
@@ -1183,48 +1186,11 @@ Event_db_repository::check_system_tables(THD *thd)
{
TABLE_LIST tables;
int ret= FALSE;
- const unsigned int event_priv_column_position= 29;
-
DBUG_ENTER("Event_db_repository::check_system_tables");
DBUG_PRINT("enter", ("thd: %p", thd));
- /* Check mysql.db */
- tables.init_one_table("mysql", 5, "db", 2, "db", TL_READ);
-
- if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
- {
- ret= 1;
- sql_print_error("Cannot open mysql.db");
- }
- else
- {
- if (table_intact.check(tables.table, &mysql_db_table_def))
- ret= 1;
-
- close_mysql_tables(thd);
- }
- /* Check mysql.user */
- tables.init_one_table("mysql", 5, "user", 4, "user", TL_READ);
-
- if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
- {
- ret= 1;
- sql_print_error("Cannot open mysql.user");
- }
- else
- {
- if (tables.table->s->fields < event_priv_column_position ||
- strncmp(tables.table->field[event_priv_column_position]->field_name.str,
- STRING_WITH_LEN("Event_priv")))
- {
- sql_print_error("mysql.user has no `Event_priv` column at position %d",
- event_priv_column_position);
- ret= 1;
- }
- close_mysql_tables(thd);
- }
/* Check mysql.event */
- tables.init_one_table("mysql", 5, "event", 5, "event", TL_READ);
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_EVENT_NAME, 0, TL_READ);
if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index e46326afe18..7cc3e50f235 100644
--- a/sql/event_queue.cc
+++ b/sql/event_queue.cc
@@ -617,7 +617,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
top= (Event_queue_element*) queue_top(&queue);
- thd->set_current_time(); /* Get current time */
+ thd->set_start_time(); /* Get current time */
next_activation_at= top->execute_at;
if (next_activation_at > thd->query_start())
@@ -637,7 +637,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
}
if (!(*event_name= new Event_queue_element_for_exec()) ||
- (*event_name)->init(top->dbname, top->name))
+ (*event_name)->init(&top->dbname, &top->name))
{
ret= TRUE;
break;
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index d9db7afe1ab..f459fd34aee 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -49,11 +49,11 @@ Event_db_repository *Event_worker_thread::db_repository;
static
-const LEX_STRING scheduler_states_names[] =
+const LEX_CSTRING scheduler_states_names[] =
{
- { C_STRING_WITH_LEN("INITIALIZED") },
- { C_STRING_WITH_LEN("RUNNING") },
- { C_STRING_WITH_LEN("STOPPING") }
+ { STRING_WITH_LEN("INITIALIZED") },
+ { STRING_WITH_LEN("RUNNING") },
+ { STRING_WITH_LEN("STOPPING") }
};
struct scheduler_param {
@@ -297,7 +297,6 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
DBUG_ENTER("Event_worker_thread::run");
DBUG_PRINT("info", ("Time is %u, THD: %p", (uint)my_time(0), thd));
- inc_thread_running();
if (res)
goto end;
@@ -326,7 +325,6 @@ end:
event->name.str));
delete event;
- dec_thread_running();
deinit_event_thread(thd);
DBUG_VOID_RETURN;
@@ -648,14 +646,11 @@ Event_scheduler::stop()
state= STOPPING;
DBUG_PRINT("info", ("Scheduler thread has id %lu",
(ulong) scheduler_thd->thread_id));
- /* Lock from delete */
- mysql_mutex_lock(&scheduler_thd->LOCK_thd_data);
/* This will wake up the thread if it waits on Queue's conditional */
sql_print_information("Event Scheduler: Killing the scheduler thread, "
"thread id %lu",
(ulong) scheduler_thd->thread_id);
scheduler_thd->awake(KILL_CONNECTION);
- mysql_mutex_unlock(&scheduler_thd->LOCK_thd_data);
/* thd could be 0x0, when shutting down */
sql_print_information("Event Scheduler: "
diff --git a/sql/events.cc b/sql/events.cc
index 3ad546217a7..2fbb16861f6 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -826,12 +826,12 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
*/
if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS)
{
- DBUG_ASSERT(thd->lex->select_lex.db);
- if (!is_infoschema_db(thd->lex->select_lex.db) && // There is no events in I_S
- check_access(thd, EVENT_ACL, thd->lex->select_lex.db,
+ DBUG_ASSERT(thd->lex->select_lex.db.str);
+ if (!is_infoschema_db(&thd->lex->select_lex.db) && // There is no events in I_S
+ check_access(thd, EVENT_ACL, thd->lex->select_lex.db.str,
NULL, NULL, 0, 0))
DBUG_RETURN(1);
- db= normalize_db_name(thd->lex->select_lex.db, db_tmp, sizeof(db_tmp));
+ db= normalize_db_name(thd->lex->select_lex.db.str, db_tmp, sizeof(db_tmp));
}
ret= db_repository->fill_schema_events(thd, tables, db);
@@ -1252,7 +1252,7 @@ int wsrep_create_event_query(THD *thd, uchar** buf, size_t* buf_len)
if (create_query_string(thd, &log_query))
{
WSREP_WARN("events create string failed: schema: %s, query: %s",
- (thd->db ? thd->db : "(null)"), thd->query());
+ thd->get_db(), thd->query());
return 1;
}
return wsrep_to_buf_helper(thd, log_query.ptr(), log_query.length(), buf, buf_len);
diff --git a/sql/field.cc b/sql/field.cc
index 51562dd4198..e47b6e9c989 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1228,7 +1228,7 @@ bool Field::can_optimize_range(const Item_bool_func *cond,
}
-int Field::store_hex_hybrid(const char *str, uint length)
+int Field::store_hex_hybrid(const char *str, size_t length)
{
DBUG_ASSERT(result_type() != STRING_RESULT);
ulonglong nr;
@@ -1253,6 +1253,59 @@ warn:
}
+bool Field::load_data_set_null(THD *thd)
+{
+ reset();
+ set_null();
+ if (!maybe_null())
+ {
+ if (this != table->next_number_field)
+ set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_NULL_TO_NOTNULL, 1);
+ }
+ set_has_explicit_value(); // Do not auto-update this field
+ return false;
+}
+
+
+bool Field::sp_prepare_and_store_item(THD *thd, Item **value)
+{
+ DBUG_ENTER("Field::sp_prepare_and_store_item");
+ DBUG_ASSERT(value);
+
+ Item *expr_item;
+
+ if (!(expr_item= thd->sp_prepare_func_item(value, 1)))
+ goto error;
+
+ /*
+ expr_item is now fixed, it's safe to call cmp_type()
+ */
+ if (expr_item->cmp_type() == ROW_RESULT)
+ {
+ my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
+ goto error;
+ }
+
+ /* Save the value in the field. Convert the value if needed. */
+
+ expr_item->save_in_field(this, 0);
+
+ if (!thd->is_error())
+ DBUG_RETURN(false);
+
+error:
+ /*
+ In case of error during evaluation, leave the result field set to NULL.
+ Sic: we can't do it in the beginning of the function because the
+ result field might be needed for its own re-evaluation, e.g. case of
+ set x = x + 1;
+ */
+ set_null();
+ DBUG_ASSERT(thd->is_error());
+ DBUG_RETURN(true);
+}
+
+
/**
Numeric fields base class constructor.
*/
@@ -1414,8 +1467,7 @@ Value_source::Converter_string_to_number::check_edom_and_truncation(THD *thd,
int Field_num::check_edom_and_important_data_truncation(const char *type,
bool edom,
CHARSET_INFO *cs,
- const char *str,
- uint length,
+ const char *str, size_t length,
const char *end)
{
/* Test if we get an empty string or garbage */
@@ -1437,7 +1489,7 @@ int Field_num::check_edom_and_important_data_truncation(const char *type,
int Field_num::check_edom_and_truncation(const char *type, bool edom,
CHARSET_INFO *cs,
- const char *str, uint length,
+ const char *str, size_t length,
const char *end)
{
int rc= check_edom_and_important_data_truncation(type, edom,
@@ -1471,7 +1523,7 @@ int Field_num::check_edom_and_truncation(const char *type, bool edom,
1 error
*/
-bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len,
+bool Field_num::get_int(CHARSET_INFO *cs, const char *from, size_t len,
longlong *rnd, ulonglong unsigned_max,
longlong signed_min, longlong signed_max)
{
@@ -1504,7 +1556,7 @@ bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len,
goto out_of_range;
}
}
- if (get_thd()->count_cuted_fields &&
+ if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
check_int(cs, from, len, end, error))
return 1;
return 0;
@@ -1515,7 +1567,7 @@ out_of_range:
}
-double Field_real::get_double(const char *str, uint length, CHARSET_INFO *cs,
+double Field_real::get_double(const char *str, size_t length, CHARSET_INFO *cs,
int *error)
{
char *end;
@@ -1525,7 +1577,7 @@ double Field_real::get_double(const char *str, uint length, CHARSET_INFO *cs,
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
*error= 1;
}
- else if (get_thd()->count_cuted_fields &&
+ else if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
check_edom_and_truncation("double", str == end,
cs, str, length, end))
*error= 1;
@@ -1589,7 +1641,8 @@ String *Field::val_int_as_str(String *val_buffer, bool unsigned_val)
Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
uchar null_bit_arg,
utype unireg_check_arg, const LEX_CSTRING *field_name_arg)
- :ptr(ptr_arg), null_ptr(null_ptr_arg), table(0), orig_table(0),
+ :ptr(ptr_arg), invisible(VISIBLE),
+ null_ptr(null_ptr_arg), table(0), orig_table(0),
table_name(0), field_name(*field_name_arg), option_list(0),
option_struct(0), key_start(0), part_of_key(0),
part_of_key_not_clustered(0), part_of_sortkey(0),
@@ -1700,7 +1753,7 @@ bool Field::compatible_field_size(uint field_metadata,
}
-int Field::store(const char *to, uint length, CHARSET_INFO *cs,
+int Field::store(const char *to, size_t length, CHARSET_INFO *cs,
enum_check_fields check_level)
{
int res;
@@ -1859,7 +1912,7 @@ void Field::make_field(Send_field *field)
if (orig_table && orig_table->s->db.str && *orig_table->s->db.str)
{
field->db_name= orig_table->s->db.str;
- if (orig_table->pos_in_table_list &&
+ if (orig_table->pos_in_table_list &&
orig_table->pos_in_table_list->schema_table)
field->org_table_name= (orig_table->pos_in_table_list->
schema_table->table_name);
@@ -1987,6 +2040,48 @@ bool Field_num::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
}
+bool Field_vers_trx_id::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate, ulonglong trx_id)
+{
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ DBUG_ASSERT(ltime);
+ if (!table || !table->s)
+ return true;
+ DBUG_ASSERT(table->versioned(VERS_TRX_ID) ||
+ (table->versioned() && table->s->table_category == TABLE_CATEGORY_TEMPORARY));
+ if (!trx_id)
+ return true;
+
+ THD *thd= get_thd();
+ DBUG_ASSERT(thd);
+ if (trx_id == ULONGLONG_MAX)
+ {
+ thd->variables.time_zone->gmt_sec_to_TIME(ltime, TIMESTAMP_MAX_VALUE);
+ ltime->second_part= TIME_MAX_SECOND_PART;
+ return false;
+ }
+ if (cached == trx_id)
+ {
+ *ltime= cache;
+ return false;
+ }
+
+ TR_table trt(thd);
+ bool found= trt.query(trx_id);
+ if (found)
+ {
+ trt[TR_table::FLD_COMMIT_TS]->get_date(&cache, fuzzydate);
+ *ltime= cache;
+ cached= trx_id;
+ return false;
+ }
+
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_VERS_NO_TRX_ID, ER_THD(thd, ER_VERS_NO_TRX_ID),
+ (longlong) trx_id);
+ return true;
+}
+
+
Field_str::Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
const LEX_CSTRING *field_name_arg,
@@ -2095,7 +2190,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy)
{
uint store_length;
copy->str= ptr;
- copy->length= pack_length();
+ copy->length= pack_length_in_rec();
copy->field= this;
if (flags & BLOB_FLAG)
{
@@ -2143,7 +2238,7 @@ bool Field::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
Needs to be changed if/when we want to support different time formats.
*/
-int Field::store_time_dec(MYSQL_TIME *ltime, uint dec)
+int Field::store_time_dec(const MYSQL_TIME *ltime, uint dec)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
char buff[MAX_DATE_STRING_REP_LENGTH];
@@ -2179,8 +2274,11 @@ Field *Field::make_new_field(MEM_ROOT *root, TABLE *new_table,
*/
tmp->unireg_check= Field::NONE;
tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG |
- ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
+ ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG |
+ VERS_SYS_START_FLAG | VERS_SYS_END_FLAG |
+ VERS_UPDATE_UNVERSIONED_FLAG);
tmp->reset_fields();
+ tmp->invisible= VISIBLE;
return tmp;
}
@@ -2281,6 +2379,41 @@ Field_row::~Field_row()
}
+bool Field_row::sp_prepare_and_store_item(THD *thd, Item **value)
+{
+ DBUG_ENTER("Field_row::sp_prepare_and_store_item");
+
+ if (value[0]->type() == Item::NULL_ITEM)
+ {
+ /*
+ We're in a auto-generated sp_inst_set, to assign
+ the explicit default NULL value to a ROW variable.
+ */
+ m_table->set_all_fields_to_null();
+ DBUG_RETURN(false);
+ }
+
+ /**
+ - In case if we're assigning a ROW variable from another ROW variable,
+ value[0] points to Item_splocal. sp_fix_func_item() will return the
+ fixed underlying Item_field pointing to Field_row.
+ - In case if we're assigning from a ROW() value, src and value[0] will
+ point to the same Item_row.
+ */
+ Item *src;
+ if (!(src= thd->sp_fix_func_item(value)) ||
+ src->cmp_type() != ROW_RESULT ||
+ src->cols() != m_table->s->fields)
+ {
+ my_error(ER_OPERAND_COLUMNS, MYF(0), m_table->s->fields);
+ m_table->set_all_fields_to_null();
+ DBUG_RETURN(true);
+ }
+
+ DBUG_RETURN(m_table->sp_set_all_fields_from_item(thd, src));
+}
+
+
/****************************************************************************
Functions for the Field_decimal class
This is an number stored as a pre-space (or pre-zero) string
@@ -2332,7 +2465,7 @@ void Field_decimal::overflow(bool negative)
}
-int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
+int Field_decimal::store(const char *from_arg, size_t len, CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
char buff[STRING_BUFFER_USUAL_SIZE];
@@ -2476,7 +2609,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
it makes the code easer to read.
*/
- if (get_thd()->count_cuted_fields)
+ if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{
// Skip end spaces
for (;from != end && my_isspace(&my_charset_bin, *from); from++) ;
@@ -2646,7 +2779,8 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
{
if (pos == right_wall)
{
- if (get_thd()->count_cuted_fields && !is_cuted_fields_incr)
+ if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
+ !is_cuted_fields_incr)
break; // Go on below to see if we lose non zero digits
return 0;
}
@@ -2712,7 +2846,6 @@ int Field_decimal::store(double nr)
return 1;
}
- reg4 uint i;
size_t length;
uchar fyllchar,*to;
char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
@@ -2728,7 +2861,7 @@ int Field_decimal::store(double nr)
else
{
to=ptr;
- for (i=field_length-length ; i-- > 0 ;)
+ for (size_t i=field_length-length ; i-- > 0 ;)
*to++ = fyllchar;
memcpy(to,buff,length);
return 0;
@@ -3014,7 +3147,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value)
}
-int Field_new_decimal::store(const char *from, uint length,
+int Field_new_decimal::store(const char *from, size_t length,
CHARSET_INFO *charset_arg)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
@@ -3039,7 +3172,7 @@ int Field_new_decimal::store(const char *from, uint length,
DBUG_RETURN(1);
}
- if (thd->count_cuted_fields)
+ if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{
if (check_edom_and_important_data_truncation("decimal",
err && err != E_DEC_TRUNCATED,
@@ -3084,7 +3217,7 @@ int Field_new_decimal::store(const char *from, uint length,
- in err2: store_value() truncated 1.123 to 1.12, e.g. for DECIMAL(10,2)
Also, we send a note if a string had some trailing spaces: '1.12 '
*/
- if (thd->count_cuted_fields &&
+ if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
(err == E_DEC_TRUNCATED ||
err2 == E_DEC_TRUNCATED ||
end < from + length))
@@ -3153,7 +3286,7 @@ int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
}
-int Field_new_decimal::store_time_dec(MYSQL_TIME *ltime, uint dec_arg)
+int Field_new_decimal::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg)
{
my_decimal decimal_value;
return store_value(date2my_decimal(ltime, &decimal_value));
@@ -3221,7 +3354,7 @@ int Field_new_decimal::cmp(const uchar *a,const uchar*b)
void Field_new_decimal::sort_string(uchar *buff,
- uint length __attribute__((unused)))
+ uint)
{
memcpy(buff, ptr, bin_size);
}
@@ -3392,7 +3525,7 @@ Item *Field_new_decimal::get_equal_const_item(THD *thd, const Context &ctx,
}
-int Field_num::store_time_dec(MYSQL_TIME *ltime, uint dec_arg)
+int Field_num::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg)
{
longlong v= TIME_to_ulonglong(ltime);
if (ltime->neg == 0)
@@ -3405,7 +3538,7 @@ int Field_num::store_time_dec(MYSQL_TIME *ltime, uint dec_arg)
** tiny int
****************************************************************************/
-int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
+int Field_tiny::store(const char *from,size_t len,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
int error;
@@ -3581,7 +3714,7 @@ void Field_tiny::sql_type(String &res) const
Field type short int (2 byte)
****************************************************************************/
-int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
+int Field_short::store(const char *from,size_t len,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
int store_tmp;
@@ -3770,7 +3903,7 @@ void Field_short::sql_type(String &res) const
Field type medium int (3 byte)
****************************************************************************/
-int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
+int Field_medium::store(const char *from,size_t len,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
int store_tmp;
@@ -3961,7 +4094,7 @@ void Field_medium::sql_type(String &res) const
** long int
****************************************************************************/
-int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
+int Field_long::store(const char *from,size_t len,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
long store_tmp;
@@ -4089,17 +4222,17 @@ String *Field_long::val_str(String *val_buffer,
{
ASSERT_COLUMN_MARKED_FOR_READ;
CHARSET_INFO *cs= &my_charset_numeric;
- uint length;
- uint mlength=MY_MAX(field_length+1,12*cs->mbmaxlen);
+ size_t length;
+ size_t mlength=MY_MAX(field_length+1,12*cs->mbmaxlen);
val_buffer->alloc(mlength);
char *to=(char*) val_buffer->ptr();
int32 j;
j=sint4korr(ptr);
if (unsigned_flag)
- length=cs->cset->long10_to_str(cs,to,mlength, 10,(long) (uint32)j);
+ length=cs->cset->long10_to_str(cs,to,mlength, 10,(uint32) j);
else
- length=cs->cset->long10_to_str(cs,to,mlength,-10,(long) j);
+ length=cs->cset->long10_to_str(cs,to,mlength,-10,j);
val_buffer->length(length);
if (zerofill)
prepend_zeros(val_buffer);
@@ -4148,7 +4281,7 @@ void Field_long::sql_type(String &res) const
Field type longlong int (8 bytes)
****************************************************************************/
-int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
+int Field_longlong::store(const char *from,size_t len,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
int error= 0;
@@ -4161,7 +4294,7 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
- else if (get_thd()->count_cuted_fields &&
+ else if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
check_int(cs, from, len, end, error))
error= 1;
else
@@ -4295,6 +4428,26 @@ void Field_longlong::sql_type(String &res) const
add_zerofill_and_unsigned(res);
}
+void Field_longlong::set_max()
+{
+ ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
+ set_notnull();
+ int8store(ptr, unsigned_flag ? ULONGLONG_MAX : LONGLONG_MAX);
+}
+
+bool Field_longlong::is_max()
+{
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ if (unsigned_flag)
+ {
+ ulonglong j;
+ j= uint8korr(ptr);
+ return j == ULONGLONG_MAX;
+ }
+ longlong j;
+ j= sint8korr(ptr);
+ return j == LONGLONG_MAX;
+}
/*
Floating-point numbers
@@ -4304,7 +4457,7 @@ void Field_longlong::sql_type(String &res) const
single precision float
****************************************************************************/
-int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
+int Field_float::store(const char *from,size_t len,CHARSET_INFO *cs)
{
int error;
Field_float::store(get_double(from, len, cs, &error));
@@ -4483,7 +4636,7 @@ void Field_float::sql_type(String &res) const
double precision floating point numbers
****************************************************************************/
-int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
+int Field_double::store(const char *from,size_t len,CHARSET_INFO *cs)
{
int error;
Field_double::store(get_double(from, len, cs, &error));
@@ -4646,7 +4799,7 @@ int Field_real::store_decimal(const my_decimal *dm)
return store(dbl);
}
-int Field_real::store_time_dec(MYSQL_TIME *ltime, uint dec_arg)
+int Field_real::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg)
{
return store(TIME_to_double(ltime));
}
@@ -4661,6 +4814,15 @@ double Field_double::val_real(void)
}
+longlong Field_double::val_int_from_real(bool want_unsigned_result)
+{
+ Converter_double_to_longlong conv(val_real(), want_unsigned_result);
+ if (!want_unsigned_result && conv.error())
+ conv.push_warning(get_thd(), Field_double::val_real(), false);
+ return conv.result();
+}
+
+
my_decimal *Field_real::val_decimal(my_decimal *decimal_value)
{
ASSERT_COLUMN_MARKED_FOR_READ;
@@ -4919,7 +5081,14 @@ copy_or_convert_to_datetime(THD *thd, const MYSQL_TIME *from, MYSQL_TIME *to)
}
-int Field_timestamp::store_time_dec(MYSQL_TIME *ltime, uint dec)
+sql_mode_t Field_timestamp::sql_mode_for_timestamp(THD *thd) const
+{
+ // We don't want to store invalid or fuzzy datetime values in TIMESTAMP
+ return (thd->variables.sql_mode & MODE_NO_ZERO_DATE) | MODE_NO_ZERO_IN_DATE;
+}
+
+
+int Field_timestamp::store_time_dec(const MYSQL_TIME *ltime, uint dec)
{
int unused;
ErrConvTime str(ltime);
@@ -4927,14 +5096,12 @@ int Field_timestamp::store_time_dec(MYSQL_TIME *ltime, uint dec)
MYSQL_TIME l_time;
bool valid= !copy_or_convert_to_datetime(thd, ltime, &l_time) &&
!check_date(&l_time, pack_time(&l_time) != 0,
- (thd->variables.sql_mode & MODE_NO_ZERO_DATE) |
- MODE_NO_ZERO_IN_DATE, &unused);
-
+ sql_mode_for_timestamp(thd), &unused);
return store_TIME_with_warning(thd, &l_time, &str, false, valid);
}
-int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
+int Field_timestamp::store(const char *from,size_t len,CHARSET_INFO *cs)
{
MYSQL_TIME l_time;
MYSQL_TIME_STATUS status;
@@ -4942,11 +5109,8 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
ErrConvString str(from, len, cs);
THD *thd= get_thd();
- /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
have_smth_to_conv= !str_to_datetime(cs, from, len, &l_time,
- (thd->variables.sql_mode &
- MODE_NO_ZERO_DATE) |
- MODE_NO_ZERO_IN_DATE, &status);
+ sql_mode_for_timestamp(thd), &status);
return store_TIME_with_warning(thd, &l_time, &str,
status.warnings, have_smth_to_conv);
}
@@ -4959,9 +5123,8 @@ int Field_timestamp::store(double nr)
ErrConvDouble str(nr);
THD *thd= get_thd();
- longlong tmp= double_to_datetime(nr, &l_time, (thd->variables.sql_mode &
- MODE_NO_ZERO_DATE) |
- MODE_NO_ZERO_IN_DATE, &error);
+ longlong tmp= double_to_datetime(nr, &l_time, sql_mode_for_timestamp(thd),
+ &error);
return store_TIME_with_warning(thd, &l_time, &str, error, tmp != -1);
}
@@ -4973,10 +5136,8 @@ int Field_timestamp::store(longlong nr, bool unsigned_val)
ErrConvInteger str(nr, unsigned_val);
THD *thd= get_thd();
- /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
- longlong tmp= number_to_datetime(nr, 0, &l_time, (thd->variables.sql_mode &
- MODE_NO_ZERO_DATE) |
- MODE_NO_ZERO_IN_DATE, &error);
+ longlong tmp= number_to_datetime(nr, 0, &l_time, sql_mode_for_timestamp(thd),
+ &error);
return store_TIME_with_warning(thd, &l_time, &str, error, tmp != -1);
}
@@ -5152,6 +5313,27 @@ int Field_timestamp::set_time()
return 0;
}
+
+bool Field_timestamp::load_data_set_null(THD *thd)
+{
+ if (!maybe_null())
+ {
+ /*
+ Timestamp fields that are NOT NULL are autoupdated if there is no
+ corresponding value in the data file.
+ */
+ set_time();
+ }
+ else
+ {
+ reset();
+ set_null();
+ }
+ set_has_explicit_value(); // Do not auto-update this field
+ return false;
+}
+
+
#ifdef NOT_USED
static void store_native(ulonglong num, uchar *to, uint bytes)
{
@@ -5250,10 +5432,8 @@ int Field_timestamp::store_decimal(const my_decimal *d)
error= 2;
}
else
- tmp= number_to_datetime(nr, sec_part, &ltime, TIME_NO_ZERO_IN_DATE |
- (thd->variables.sql_mode &
- MODE_NO_ZERO_DATE), &error);
-
+ tmp= number_to_datetime(nr, sec_part, &ltime, sql_mode_for_timestamp(thd),
+ &error);
return store_TIME_with_warning(thd, &ltime, &str, error, tmp != -1);
}
@@ -5307,6 +5487,27 @@ void Field_timestampf::store_TIME(my_time_t timestamp, ulong sec_part)
my_timestamp_to_binary(&tm, ptr, dec);
}
+void Field_timestampf::set_max()
+{
+ DBUG_ENTER("Field_timestampf::set_max");
+ ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
+ DBUG_ASSERT(dec == TIME_SECOND_PART_DIGITS);
+
+ set_notnull();
+ mi_int4store(ptr, TIMESTAMP_MAX_VALUE);
+ mi_int3store(ptr + 4, TIME_MAX_SECOND_PART);
+
+ DBUG_VOID_RETURN;
+}
+
+bool Field_timestampf::is_max()
+{
+ DBUG_ENTER("Field_timestampf::is_max");
+ ASSERT_COLUMN_MARKED_FOR_READ;
+
+ DBUG_RETURN(mi_sint4korr(ptr) == TIMESTAMP_MAX_VALUE &&
+ mi_sint3korr(ptr + 4) == TIME_MAX_SECOND_PART);
+}
my_time_t Field_timestampf::get_timestamp(const uchar *pos,
ulong *sec_part) const
@@ -5341,11 +5542,9 @@ void Field_temporal::set_warnings(Sql_condition::enum_warning_level trunc_level,
a DATE field and non-zero time part is thrown away.
*/
if (was_cut & MYSQL_TIME_WARN_TRUNCATED)
- set_datetime_warning(trunc_level, WARN_DATA_TRUNCATED,
- str, mysql_type_to_time_type(type()), 1);
+ set_datetime_warning(trunc_level, WARN_DATA_TRUNCATED, str, ts_type, 1);
if (was_cut & MYSQL_TIME_WARN_OUT_OF_RANGE)
- set_datetime_warning(ER_WARN_DATA_OUT_OF_RANGE,
- str, mysql_type_to_time_type(type()), 1);
+ set_datetime_warning(ER_WARN_DATA_OUT_OF_RANGE, str, ts_type, 1);
}
@@ -5381,20 +5580,21 @@ int Field_temporal_with_date::store_TIME_with_warning(MYSQL_TIME *ltime,
}
else if (!MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) &&
(MYSQL_TIME_WARN_HAVE_NOTES(was_cut) ||
- (mysql_type_to_time_type(type()) == MYSQL_TIMESTAMP_DATE &&
+ (type_handler()->mysql_timestamp_type() == MYSQL_TIMESTAMP_DATE &&
(ltime->hour || ltime->minute || ltime->second || ltime->second_part))))
{
trunc_level= Sql_condition::WARN_LEVEL_NOTE;
was_cut|= MYSQL_TIME_WARN_TRUNCATED;
ret= 3;
}
- set_warnings(trunc_level, str, was_cut, mysql_type_to_time_type(type()));
+ set_warnings(trunc_level, str, was_cut,
+ type_handler()->mysql_timestamp_type());
store_TIME(ltime);
return was_cut ? ret : 0;
}
-int Field_temporal_with_date::store(const char *from, uint len, CHARSET_INFO *cs)
+int Field_temporal_with_date::store(const char *from, size_t len, CHARSET_INFO *cs)
{
MYSQL_TIME ltime;
MYSQL_TIME_STATUS status;
@@ -5434,7 +5634,7 @@ int Field_temporal_with_date::store(longlong nr, bool unsigned_val)
}
-int Field_temporal_with_date::store_time_dec(MYSQL_TIME *ltime, uint dec)
+int Field_temporal_with_date::store_time_dec(const MYSQL_TIME *ltime, uint dec)
{
int error= 0, have_smth_to_conv= 1;
ErrConvTime str(ltime);
@@ -5478,7 +5678,7 @@ my_decimal *Field_temporal::val_decimal(my_decimal *d)
if (get_date(&ltime, 0))
{
bzero(&ltime, sizeof(ltime));
- ltime.time_type= mysql_type_to_time_type(type());
+ ltime.time_type= type_handler()->mysql_timestamp_type();
}
return TIME_to_my_decimal(&ltime, d);
}
@@ -5508,30 +5708,28 @@ Item *Field_temporal::get_equal_const_item_datetime(THD *thd,
const_item->field_type() != MYSQL_TYPE_TIMESTAMP) ||
const_item->decimals != decimals())
{
- MYSQL_TIME ltime;
- if (const_item->field_type() == MYSQL_TYPE_TIME ?
- const_item->get_date_with_conversion(&ltime, 0) :
- const_item->get_date(&ltime, 0))
+ Datetime dt(thd, const_item, 0);
+ if (!dt.is_valid_datetime())
return NULL;
/*
See comments about truncation in the same place in
Field_time::get_equal_const_item().
*/
- return new (thd->mem_root) Item_datetime_literal(thd, &ltime,
+ return new (thd->mem_root) Item_datetime_literal(thd,
+ dt.get_mysql_time(),
decimals());
}
break;
case ANY_SUBST:
if (!is_temporal_type_with_date(const_item->field_type()))
{
- MYSQL_TIME ltime;
- if (const_item->get_date_with_conversion(&ltime,
- TIME_FUZZY_DATES |
- TIME_INVALID_DATES))
+ Datetime dt(thd, const_item, TIME_FUZZY_DATES | TIME_INVALID_DATES);
+ if (!dt.is_valid_datetime())
return NULL;
return new (thd->mem_root)
- Item_datetime_literal_for_invalid_dates(thd, &ltime,
- ltime.second_part ?
+ Item_datetime_literal_for_invalid_dates(thd, dt.get_mysql_time(),
+ dt.get_mysql_time()->
+ second_part ?
TIME_SECOND_PART_DIGITS : 0);
}
break;
@@ -5551,34 +5749,38 @@ int Field_time::store_TIME_with_warning(MYSQL_TIME *ltime,
int was_cut,
int have_smth_to_conv)
{
- Sql_condition::enum_warning_level trunc_level= Sql_condition::WARN_LEVEL_WARN;
- int ret= 2;
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
if (!have_smth_to_conv)
{
bzero(ltime, sizeof(*ltime));
- was_cut= MYSQL_TIME_WARN_TRUNCATED;
- ret= 1;
+ store_TIME(ltime);
+ set_warnings(Sql_condition::WARN_LEVEL_WARN, str, MYSQL_TIME_WARN_TRUNCATED);
+ return 1;
}
- else if (!MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) &&
- ((ltime->year || ltime->month) ||
- MYSQL_TIME_WARN_HAVE_NOTES(was_cut)))
+ if (ltime->year != 0 || ltime->month != 0)
{
- if (ltime->year || ltime->month)
- ltime->year= ltime->month= ltime->day= 0;
- trunc_level= Sql_condition::WARN_LEVEL_NOTE;
- was_cut|= MYSQL_TIME_WARN_TRUNCATED;
- ret= 3;
+ ltime->year= ltime->month= ltime->day= 0;
+ was_cut|= MYSQL_TIME_NOTE_TRUNCATED;
}
- set_warnings(trunc_level, str, was_cut, MYSQL_TIMESTAMP_TIME);
+ my_time_trunc(ltime, decimals());
store_TIME(ltime);
- return was_cut ? ret : 0;
+ if (!MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) &&
+ MYSQL_TIME_WARN_HAVE_NOTES(was_cut))
+ {
+ set_warnings(Sql_condition::WARN_LEVEL_NOTE, str,
+ was_cut | MYSQL_TIME_WARN_TRUNCATED);
+ return 3;
+ }
+ set_warnings(Sql_condition::WARN_LEVEL_WARN, str, was_cut);
+ return was_cut ? 2 : 0;
}
-void Field_time::store_TIME(MYSQL_TIME *ltime)
+void Field_time::store_TIME(const MYSQL_TIME *ltime)
{
+ DBUG_ASSERT(ltime->year == 0);
+ DBUG_ASSERT(ltime->month == 0);
long tmp= (ltime->day*24L+ltime->hour)*10000L +
(ltime->minute*100+ltime->second);
if (ltime->neg)
@@ -5586,7 +5788,7 @@ void Field_time::store_TIME(MYSQL_TIME *ltime)
int3store(ptr,tmp);
}
-int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
+int Field_time::store(const char *from,size_t len,CHARSET_INFO *cs)
{
MYSQL_TIME ltime;
MYSQL_TIME_STATUS status;
@@ -5612,7 +5814,10 @@ static void calc_datetime_days_diff(MYSQL_TIME *ltime, long days)
long daydiff= calc_daynr(ltime->year, ltime->month, ltime->day) - days;
ltime->year= ltime->month= 0;
if (daydiff >=0 )
+ {
ltime->day= daydiff;
+ ltime->time_type= MYSQL_TIMESTAMP_TIME;
+ }
else
{
longlong timediff= ((((daydiff * 24LL +
@@ -5620,13 +5825,12 @@ static void calc_datetime_days_diff(MYSQL_TIME *ltime, long days)
ltime->minute) * 60LL +
ltime->second) * 1000000LL +
ltime->second_part);
- unpack_time(timediff, ltime);
+ unpack_time(timediff, ltime, MYSQL_TIMESTAMP_TIME);
}
- ltime->time_type= MYSQL_TIMESTAMP_TIME;
}
-int Field_time::store_time_dec(MYSQL_TIME *ltime, uint dec)
+int Field_time::store_time_dec(const MYSQL_TIME *ltime, uint dec)
{
MYSQL_TIME l_time= *ltime;
ErrConvTime str(ltime);
@@ -5812,8 +6016,10 @@ int Field_time_hires::reset()
}
-void Field_time_hires::store_TIME(MYSQL_TIME *ltime)
+void Field_time_hires::store_TIME(const MYSQL_TIME *ltime)
{
+ DBUG_ASSERT(ltime->year == 0);
+ DBUG_ASSERT(ltime->month == 0);
ulonglong packed= sec_part_shift(pack_time(ltime), dec) + zero_point;
store_bigendian(packed, ptr, Field_time_hires::pack_length());
}
@@ -5875,10 +6081,8 @@ Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
{
MYSQL_TIME ltime;
// Get the value of const_item with conversion from DATETIME to TIME
- if (const_item->get_time_with_conversion(thd, &ltime,
- TIME_TIME_ONLY |
- TIME_FUZZY_DATES |
- TIME_INVALID_DATES))
+ ulonglong fuzzydate= Time::comparison_flags_for_get_date();
+ if (const_item->get_time_with_conversion(thd, &ltime, fuzzydate))
return NULL;
/*
Replace a DATE/DATETIME constant to a TIME constant:
@@ -5951,14 +6155,7 @@ bool Field_time_hires::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
packed= sec_part_unshift(packed - zero_point, dec);
- unpack_time(packed, ltime);
- /*
- unpack_time() returns MYSQL_TIMESTAMP_DATETIME.
- To get MYSQL_TIMESTAMP_TIME we need few adjustments
- */
- ltime->time_type= MYSQL_TIMESTAMP_TIME;
- ltime->hour+= (ltime->month*32+ltime->day)*24;
- ltime->month= ltime->day= 0;
+ unpack_time(packed, ltime, MYSQL_TIMESTAMP_TIME);
return false;
}
@@ -5995,9 +6192,8 @@ int Field_timef::reset()
return 0;
}
-void Field_timef::store_TIME(MYSQL_TIME *ltime)
+void Field_timef::store_TIME(const MYSQL_TIME *ltime)
{
- my_time_trunc(ltime, decimals());
longlong tmp= TIME_to_longlong_time_packed(ltime);
my_time_packed_to_binary(tmp, ptr, dec);
}
@@ -6017,7 +6213,7 @@ bool Field_timef::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
** Can handle 2 byte or 4 byte years!
****************************************************************************/
-int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
+int Field_year::store(const char *from, size_t len,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
char *end;
@@ -6031,7 +6227,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
return 1;
}
- if (get_thd()->count_cuted_fields &&
+ if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
(error= check_int(cs, from, len, end, error)))
{
if (error == 1) /* empty or incorrect string */
@@ -6086,7 +6282,7 @@ int Field_year::store(longlong nr, bool unsigned_val)
}
-int Field_year::store_time_dec(MYSQL_TIME *ltime, uint dec_arg)
+int Field_year::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg)
{
ErrConvTime str(ltime);
if (Field_year::store(ltime->year, 0))
@@ -6359,10 +6555,9 @@ Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx,
case ANY_SUBST:
if (!is_temporal_type_with_date(const_item->field_type()))
{
- MYSQL_TIME ltime;
// Get the value of const_item with conversion from TIME to DATETIME
- if (const_item->get_date_with_conversion(&ltime,
- TIME_FUZZY_DATES | TIME_INVALID_DATES))
+ Datetime dt(thd, const_item, TIME_FUZZY_DATES | TIME_INVALID_DATES);
+ if (!dt.is_valid_datetime())
return NULL;
/*
Replace the constant to a DATE or DATETIME constant.
@@ -6375,26 +6570,23 @@ Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx,
(assuming CURRENT_DATE is '2015-08-30'
*/
- if (non_zero_hhmmssuu(&ltime))
+ if (!dt.hhmmssff_is_zero())
return new (thd->mem_root)
- Item_datetime_literal_for_invalid_dates(thd, &ltime,
- ltime.second_part ?
+ Item_datetime_literal_for_invalid_dates(thd, dt.get_mysql_time(),
+ dt.get_mysql_time()->
+ second_part ?
TIME_SECOND_PART_DIGITS : 0);
- datetime_to_date(&ltime);
return new (thd->mem_root)
- Item_date_literal_for_invalid_dates(thd, &ltime);
+ Item_date_literal_for_invalid_dates(thd, Date(&dt).get_mysql_time());
}
break;
case IDENTITY_SUBST:
if (const_item->field_type() != MYSQL_TYPE_DATE)
{
- MYSQL_TIME ltime;
- if (const_item->field_type() == MYSQL_TYPE_TIME ?
- const_item->get_date_with_conversion(&ltime, 0) :
- const_item->get_date(&ltime, 0))
+ Date d(thd, const_item, 0);
+ if (!d.is_valid_date())
return NULL;
- datetime_to_date(&ltime);
- return new (thd->mem_root) Item_date_literal(thd, &ltime);
+ return new (thd->mem_root) Item_date_literal(thd, d.get_mysql_time());
}
break;
}
@@ -6622,7 +6814,7 @@ bool Field_datetime_hires::get_TIME(MYSQL_TIME *ltime, const uchar *pos,
{
ASSERT_COLUMN_MARKED_FOR_READ;
ulonglong packed= read_bigendian(pos, Field_datetime_hires::pack_length());
- unpack_time(sec_part_unshift(packed, dec), ltime);
+ unpack_time(sec_part_unshift(packed, dec), ltime, MYSQL_TIMESTAMP_DATETIME);
return validate_MMDD(packed, ltime->month, ltime->day, fuzzydate);
}
@@ -6739,7 +6931,7 @@ Field_longstr::report_if_important_data(const char *pstr, const char *end,
bool count_spaces)
{
THD *thd= get_thd();
- if ((pstr < end) && thd->count_cuted_fields)
+ if ((pstr < end) && thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{
if (test_if_important_data(field_charset, pstr, end))
{
@@ -6761,7 +6953,7 @@ Field_longstr::report_if_important_data(const char *pstr, const char *end,
/* Copy a string and fill with space */
-int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
+int Field_string::store(const char *from, size_t length,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
uint copy_length;
@@ -6827,7 +7019,7 @@ int Field_str::store(double nr)
else
set_warning(WARN_DATA_TRUNCATED, 1);
}
- return store(buff, length, &my_charset_numeric);
+ return store(buff, (uint)length, &my_charset_numeric);
}
uint Field::is_equal(Create_field *new_field)
@@ -6959,7 +7151,7 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)),
ASSERT_COLUMN_MARKED_FOR_READ;
/* See the comment for Field_long::store(long long) */
DBUG_ASSERT(!table || table->in_use == current_thd);
- uint length;
+ size_t length;
if (get_thd()->variables.sql_mode &
MODE_PAD_CHAR_TO_FULL_LENGTH)
length= my_charpos(field_charset, ptr, ptr + field_length,
@@ -7022,11 +7214,11 @@ Field_string::compatible_field_size(uint field_metadata,
int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
- uint a_len, b_len;
+ size_t a_len, b_len;
if (field_charset->mbmaxlen != 1)
{
- uint char_len= field_length/field_charset->mbmaxlen;
+ size_t char_len= field_length/field_charset->mbmaxlen;
a_len= my_charpos(field_charset, a_ptr, a_ptr + field_length, char_len);
b_len= my_charpos(field_charset, b_ptr, b_ptr + field_length, char_len);
}
@@ -7044,7 +7236,7 @@ int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr)
void Field_string::sort_string(uchar *to,uint length)
{
- uint tmp __attribute__((unused))=
+ IF_DBUG(size_t tmp= ,)
field_charset->coll->strnxfrm(field_charset,
to, length,
char_length() *
@@ -7060,7 +7252,7 @@ void Field_string::sql_type(String &res) const
{
THD *thd= table->in_use;
CHARSET_INFO *cs=res.charset();
- ulong length;
+ size_t length;
length= cs->cset->snprintf(cs,(char*) res.ptr(),
res.alloced_length(), "%s(%d)",
@@ -7077,9 +7269,9 @@ void Field_string::sql_type(String &res) const
uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length)
{
- uint length= MY_MIN(field_length,max_length);
- uint local_char_length= max_length/field_charset->mbmaxlen;
- DBUG_PRINT("debug", ("Packing field '%s' - length: %u ", field_name.str,
+ size_t length= MY_MIN(field_length,max_length);
+ size_t local_char_length= max_length/field_charset->mbmaxlen;
+ DBUG_PRINT("debug", ("Packing field '%s' - length: %zu ", field_name.str,
length));
if (length > local_char_length)
@@ -7234,14 +7426,14 @@ uint Field_string::max_packed_col_length(uint max_length)
uint Field_string::get_key_image(uchar *buff, uint length, imagetype type_arg)
{
- uint bytes = my_charpos(field_charset, (char*) ptr,
+ size_t bytes = my_charpos(field_charset, (char*) ptr,
(char*) ptr + field_length,
length / field_charset->mbmaxlen);
memcpy(buff, ptr, bytes);
if (bytes < length)
field_charset->cset->fill(field_charset, (char*) buff + bytes,
length - bytes, field_charset->pad_char);
- return bytes;
+ return (uint)bytes;
}
@@ -7310,7 +7502,7 @@ int Field_varstring::save_field_metadata(uchar *metadata_ptr)
return 2;
}
-int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
+int Field_varstring::store(const char *from,size_t length,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
uint copy_length;
@@ -7411,8 +7603,8 @@ int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length)
{
- uint length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
- uint local_char_length= max_key_length / field_charset->mbmaxlen;
+ size_t length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
+ size_t local_char_length= max_key_length / field_charset->mbmaxlen;
local_char_length= my_charpos(field_charset, ptr + length_bytes,
ptr + length_bytes + length, local_char_length);
@@ -7461,7 +7653,7 @@ void Field_varstring::sort_string(uchar *to,uint length)
}
#ifndef DBUG_OFF
- uint rc=
+ size_t rc=
#endif
field_charset->coll->strnxfrm(field_charset, to, length,
char_length() * field_charset->strxfrm_multiply,
@@ -7493,7 +7685,7 @@ void Field_varstring::sql_type(String &res) const
{
THD *thd= table->in_use;
CHARSET_INFO *cs=res.charset();
- ulong length;
+ size_t length;
length= cs->cset->snprintf(cs,(char*) res.ptr(),
res.alloced_length(), "%s(%d)",
@@ -7842,12 +8034,12 @@ String *Field_longstr::uncompress(String *val_buffer, String *val_ptr,
}
-int Field_varstring_compressed::store(const char *from, uint length,
+int Field_varstring_compressed::store(const char *from, size_t length,
CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- uint to_length= MY_MIN(field_length, field_charset->mbmaxlen * length + 1);
- int rc= compress((char*) get_data(), &to_length, from, length, cs);
+ uint to_length= (uint)MY_MIN(field_length, field_charset->mbmaxlen * length + 1);
+ int rc= compress((char*) get_data(), &to_length, from, (uint)length, cs);
store_length(to_length);
return rc;
}
@@ -7972,10 +8164,10 @@ int Field_blob::copy_value(Field_blob *from)
}
-int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
+int Field_blob::store(const char *from,size_t length,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- uint copy_length, new_length;
+ size_t copy_length, new_length;
String_copier copier;
char *tmp;
char buff[STRING_BUFFER_USUAL_SIZE];
@@ -7994,7 +8186,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
DBUG_ASSERT(length <= max_data_length());
new_length= length;
- copy_length= (uint)MY_MIN(UINT_MAX,table->in_use->variables.group_concat_max_len);
+ copy_length= (size_t)MY_MIN(UINT_MAX,table->in_use->variables.group_concat_max_len);
if (new_length > copy_length)
{
new_length= Well_formed_prefix(cs,
@@ -8047,7 +8239,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
return 0;
}
copy_length= copier.well_formed_copy(field_charset,
- (char*) value.ptr(), new_length,
+ (char*) value.ptr(), (uint)new_length,
cs, from, length);
Field_blob::store_length(copy_length);
bmove(ptr+packlength,(uchar*) &tmp,sizeof(char*));
@@ -8170,7 +8362,7 @@ int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
uint Field_blob::get_key_image(uchar *buff,uint length, imagetype type_arg)
{
- uint32 blob_length= get_length(ptr);
+ size_t blob_length= get_length(ptr);
uchar *blob;
#ifdef HAVE_SPATIAL
@@ -8188,7 +8380,7 @@ uint Field_blob::get_key_image(uchar *buff,uint length, imagetype type_arg)
return image_length;
}
blob= get_ptr();
- gobj= Geometry::construct(&buffer, (char*) blob, blob_length);
+ gobj= Geometry::construct(&buffer, (char*) blob, (uint32)blob_length);
if (!gobj || gobj->get_mbr(&mbr, &dummy))
bzero(buff, image_length);
else
@@ -8203,12 +8395,12 @@ uint Field_blob::get_key_image(uchar *buff,uint length, imagetype type_arg)
#endif /*HAVE_SPATIAL*/
blob= get_ptr();
- uint local_char_length= length / field_charset->mbmaxlen;
+ size_t local_char_length= length / field_charset->mbmaxlen;
local_char_length= my_charpos(field_charset, blob, blob + blob_length,
local_char_length);
set_if_smaller(blob_length, local_char_length);
- if ((uint32) length > blob_length)
+ if (length > blob_length)
{
/*
Must clear this as we do a memcmp in opt_range.cc to detect
@@ -8234,14 +8426,14 @@ void Field_blob::set_key_image(const uchar *buff,uint length)
int Field_blob::key_cmp(const uchar *key_ptr, uint max_key_length)
{
uchar *blob1;
- uint blob_length=get_length(ptr);
+ size_t blob_length=get_length(ptr);
memcpy(&blob1, ptr+packlength, sizeof(char*));
CHARSET_INFO *cs= charset();
- uint local_char_length= max_key_length / cs->mbmaxlen;
+ size_t local_char_length= max_key_length / cs->mbmaxlen;
local_char_length= my_charpos(cs, blob1, blob1+blob_length,
local_char_length);
set_if_smaller(blob_length, local_char_length);
- return Field_blob::cmp(blob1, blob_length,
+ return Field_blob::cmp(blob1, (uint32)blob_length,
key_ptr+HA_KEY_BLOB_LENGTH,
uint2korr(key_ptr));
}
@@ -8312,7 +8504,7 @@ void Field_blob::sort_string(uchar *to,uint length)
}
#ifndef DBUG_OFF
- uint rc=
+ size_t rc=
#endif
field_charset->coll->strnxfrm(field_charset, to, length, length,
(const uchar*) buf.ptr(), buf.length(),
@@ -8401,6 +8593,7 @@ uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length)
@return New pointer into memory based on from + length of the data
*/
+
const uchar *Field_blob::unpack(uchar *to, const uchar *from,
const uchar *from_end, uint param_data)
{
@@ -8416,7 +8609,6 @@ const uchar *Field_blob::unpack(uchar *to, const uchar *from,
if (from + master_packlength + length > from_end)
DBUG_RETURN(0);
set_ptr(length, const_cast<uchar*> (from) + master_packlength);
- DBUG_DUMP("record", to, table->s->reclength);
DBUG_RETURN(from + master_packlength + length);
}
@@ -8452,11 +8644,11 @@ uint Field_blob::is_equal(Create_field *new_field)
}
-int Field_blob_compressed::store(const char *from, uint length,
+int Field_blob_compressed::store(const char *from, size_t length,
CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- uint to_length= MY_MIN(max_data_length(), field_charset->mbmaxlen * length + 1);
+ uint to_length= (uint)MY_MIN(max_data_length(), field_charset->mbmaxlen * length + 1);
int rc;
if (value.alloc(to_length))
@@ -8465,7 +8657,7 @@ int Field_blob_compressed::store(const char *from, uint length,
return -1;
}
- rc= compress((char*) value.ptr(), &to_length, from, length, cs);
+ rc= compress((char*) value.ptr(), &to_length, from, (uint)length, cs);
set_ptr(to_length, (uchar*) value.ptr());
return rc;
}
@@ -8550,7 +8742,7 @@ uint gis_field_options_image(uchar *buff, List<Create_field> &create_fields)
}
-uint gis_field_options_read(const uchar *buf, uint buf_len,
+uint gis_field_options_read(const uchar *buf, size_t buf_len,
Field_geom::storage_type *st_type,uint *precision, uint *scale, uint *srid)
{
const uchar *buf_end= buf + buf_len;
@@ -8656,7 +8848,7 @@ int Field_geom::store_decimal(const my_decimal *)
}
-int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
+int Field_geom::store(const char *from, size_t length, CHARSET_INFO *cs)
{
if (!length)
bzero(ptr, Field_blob::pack_length());
@@ -8673,7 +8865,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
wkb_type > (uint32) Geometry::wkb_last)
goto err;
- if (geom_type != Field::GEOM_GEOMETRY &&
+ if (geom_type != Field::GEOM_GEOMETRY &&
geom_type != Field::GEOM_GEOMETRYCOLLECTION &&
(uint32) geom_type != wkb_type)
{
@@ -8734,6 +8926,22 @@ bool Field_geom::can_optimize_range(const Item_bool_func *cond,
return item->cmp_type() == STRING_RESULT;
}
+
+bool Field_geom::load_data_set_null(THD *thd)
+{
+ Field_blob::reset();
+ if (!maybe_null())
+ {
+ my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field_name.str,
+ thd->get_stmt_da()->current_row_for_warning());
+ return true;
+ }
+ set_null();
+ set_has_explicit_value(); // Do not auto-update this field
+ return false;
+}
+
+
#endif /*HAVE_SPATIAL*/
/****************************************************************************
@@ -8765,7 +8973,7 @@ void Field_enum::store_type(ulonglong value)
(if there isn't a empty value in the enum)
*/
-int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
+int Field_enum::store(const char *from,size_t length,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
int err= 0;
@@ -8782,7 +8990,7 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
}
/* Remove end space */
- length= field_charset->cset->lengthsp(field_charset, from, length);
+ length= (uint)field_charset->cset->lengthsp(field_charset, from, length);
uint tmp=find_type2(typelib, from, length, field_charset);
if (!tmp)
{
@@ -8797,7 +9005,7 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
set_warning(WARN_DATA_TRUNCATED, 1);
err= 1;
}
- if (!get_thd()->count_cuted_fields && !length)
+ if ((get_thd()->count_cuted_fields <= CHECK_FIELD_EXPRESSION) && !length)
err= 0;
}
else
@@ -8824,7 +9032,7 @@ int Field_enum::store(longlong nr, bool unsigned_val)
if ((ulonglong) nr > typelib->count || nr == 0)
{
set_warning(WARN_DATA_TRUNCATED, 1);
- if (nr != 0 || get_thd()->count_cuted_fields)
+ if (nr != 0 || get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{
nr= 0;
error= 1;
@@ -8948,7 +9156,7 @@ Field *Field_enum::make_new_field(MEM_ROOT *root, TABLE *new_table,
*/
-int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
+int Field_set::store(const char *from,size_t length,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
bool got_warning= 0;
@@ -9367,14 +9575,14 @@ uint Field_bit::is_equal(Create_field *new_field)
}
-int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs)
+int Field_bit::store(const char *from, size_t length, CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
int delta;
for (; length && !*from; from++, length--) // skip left 0's
;
- delta= bytes_in_rec - length;
+ delta= (int)(bytes_in_rec - length);
if (delta < -1 ||
(delta == -1 && (uchar) *from > ((1 << bit_len) - 1)) ||
@@ -9535,7 +9743,7 @@ int Field_bit::key_cmp(const uchar *str, uint length)
str++;
length--;
}
- return memcmp(ptr, str, length);
+ return memcmp(ptr, str, bytes_in_rec);
}
@@ -9650,9 +9858,9 @@ Field_bit::compatible_field_size(uint field_metadata,
void Field_bit::sql_type(String &res) const
{
CHARSET_INFO *cs= res.charset();
- ulong length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
+ size_t length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
"bit(%d)", (int) field_length);
- res.length((uint) length);
+ res.length(length);
}
@@ -9803,7 +10011,7 @@ Field_bit_as_char::Field_bit_as_char(uchar *ptr_arg, uint32 len_arg,
}
-int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
+int Field_bit_as_char::store(const char *from, size_t length, CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
int delta;
@@ -9811,7 +10019,7 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
for (; length && !*from; from++, length--) // skip left 0's
;
- delta= bytes_in_rec - length;
+ delta= (int)(bytes_in_rec - length);
if (delta < 0 ||
(delta == 0 && bits && (uint) (uchar) *from >= (uint) (1 << bits)))
@@ -9834,9 +10042,9 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
void Field_bit_as_char::sql_type(String &res) const
{
CHARSET_INFO *cs= res.charset();
- ulong length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
+ size_t length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
"bit(%d)", (int) field_length);
- res.length((uint) length);
+ res.length(length);
}
@@ -9912,7 +10120,7 @@ bool Column_definition::create_interval_from_interval_list(MEM_ROOT *mem_root,
}
}
interval->type_names[i]= value.str;
- interval->type_lengths[i]= value.length;
+ interval->type_lengths[i]= (uint)value.length;
}
interval->type_names[interval->count]= 0; // End marker
interval->type_lengths[interval->count]= 0;
@@ -10050,6 +10258,8 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name,
uint filter= VCOL_IMPOSSIBLE;
if (type != VCOL_GENERATED_VIRTUAL && type != VCOL_DEFAULT)
filter|= VCOL_NOT_STRICTLY_DETERMINISTIC;
+ if (type == VCOL_GENERATED_VIRTUAL)
+ filter|= VCOL_NOT_VIRTUAL;
if (ret || (res.errors & filter))
{
@@ -10251,8 +10461,8 @@ bool Column_definition::check(THD *thd)
TIMESTAMP columns get implicit DEFAULT value when
explicit_defaults_for_timestamp is not set.
*/
- if (opt_explicit_defaults_for_timestamp ||
- !is_timestamp_type())
+ if ((opt_explicit_defaults_for_timestamp ||
+ !is_timestamp_type()) && !vers_sys_field())
{
flags|= NO_DEFAULT_VALUE_FLAG;
}
@@ -10307,7 +10517,8 @@ Field *make_field(TABLE_SHARE *share,
Field::geometry_type geom_type, uint srid,
Field::utype unireg_check,
TYPELIB *interval,
- const LEX_CSTRING *field_name)
+ const LEX_CSTRING *field_name,
+ uint32 flags)
{
uchar *UNINIT_VAR(bit_ptr);
uchar UNINIT_VAR(bit_offset);
@@ -10492,11 +10703,22 @@ Field *make_field(TABLE_SHARE *share,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
case MYSQL_TYPE_LONGLONG:
- return new (mem_root)
- Field_longlong(ptr,field_length,null_pos,null_bit,
- unireg_check, field_name,
- f_is_zerofill(pack_flag) != 0,
- f_is_dec(pack_flag) == 0);
+ if (flags & (VERS_SYS_START_FLAG|VERS_SYS_END_FLAG))
+ {
+ return new (mem_root)
+ Field_vers_trx_id(ptr, field_length, null_pos, null_bit,
+ unireg_check, field_name,
+ f_is_zerofill(pack_flag) != 0,
+ f_is_dec(pack_flag) == 0);
+ }
+ else
+ {
+ return new (mem_root)
+ Field_longlong(ptr,field_length,null_pos,null_bit,
+ unireg_check, field_name,
+ f_is_zerofill(pack_flag) != 0,
+ f_is_dec(pack_flag) == 0);
+ }
case MYSQL_TYPE_TIMESTAMP:
{
uint dec= field_length > MAX_DATETIME_WIDTH ?
@@ -10573,6 +10795,11 @@ Field *make_field(TABLE_SHARE *share,
return 0;
}
+bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item) const
+{
+ return item->type() == Item::DATE_ITEM;
+}
+
/** Create a field suitable for create of table. */
@@ -10594,6 +10821,8 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
option_list= old_field->option_list;
pack_flag= 0;
compression_method_ptr= 0;
+ versioning= VERSIONING_NOT_SET;
+ invisible= old_field->invisible;
if (orig_field)
{
@@ -10731,6 +10960,7 @@ Column_definition::redefine_stage1_common(const Column_definition *dup_field,
flags= dup_field->flags;
interval= dup_field->interval;
vcol_info= dup_field->vcol_info;
+ invisible= dup_field->invisible;
}
@@ -10856,11 +11086,12 @@ uint32 Field_blob::max_display_length()
@param cut_increment - whenever we should increase cut fields count
@note
- This function won't produce warning and increase cut fields counter
- if count_cuted_fields == CHECK_FIELD_IGNORE for current thread.
+ This function won't produce warning or notes or increase cut fields counter
+ if count_cuted_fields == CHECK_FIELD_IGNORE or CHECK_FIELD_EXPRESSION
+ for the current thread.
- if count_cuted_fields == CHECK_FIELD_IGNORE then we ignore notes.
- This allows us to avoid notes in optimisation, like convert_constant_item().
+ This allows us to avoid notes in optimisation, like
+ convert_constant_item().
@retval
1 if count_cuted_fields == CHECK_FIELD_IGNORE and error level is not NOTE
@@ -10877,7 +11108,7 @@ Field::set_warning(Sql_condition::enum_warning_level level, uint code,
will have table == NULL.
*/
THD *thd= get_thd();
- if (thd->count_cuted_fields)
+ if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{
thd->cuted_fields+= cut_increment;
push_warning_printf(thd, level, code, ER_THD(thd, code), field_name.str,
diff --git a/sql/field.h b/sql/field.h
index eb6510bc9a4..186d9b0e47a 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -46,12 +46,15 @@ class Item_func;
class Item_bool_func;
class Item_equal;
class Virtual_tmp_table;
+class Qualified_column_ident;
+class Table_ident;
enum enum_check_fields
{
CHECK_FIELD_IGNORE,
+ CHECK_FIELD_EXPRESSION,
CHECK_FIELD_WARN,
- CHECK_FIELD_ERROR_FOR_NULL
+ CHECK_FIELD_ERROR_FOR_NULL,
};
/*
@@ -215,7 +218,7 @@ protected:
my_decimal *buf)
{
DBUG_ASSERT(length < UINT_MAX32);
- m_error= str2my_decimal(mask, str, (uint) length, cs,
+ m_error= str2my_decimal(mask, str, length, cs,
buf, (const char **) &m_end_of_num);
// E_DEC_TRUNCATED means a very minor truncation: '1e-100' -> 0
m_edom= m_error && m_error != E_DEC_TRUNCATED;
@@ -313,7 +316,7 @@ protected:
return decimal_value;
}
- longlong longlong_from_hex_hybrid(const char *str, uint32 length)
+ longlong longlong_from_hex_hybrid(const char *str, size_t length)
{
const char *end= str + length;
const char *ptr= end - MY_MIN(length, sizeof(longlong));
@@ -489,37 +492,6 @@ inline enum_field_types real_type_to_type(enum_field_types real_type)
}
-static inline enum enum_mysql_timestamp_type
-mysql_type_to_time_type(enum enum_field_types mysql_type)
-{
- switch(mysql_type) {
- case MYSQL_TYPE_TIME2:
- case MYSQL_TYPE_TIME: return MYSQL_TIMESTAMP_TIME;
- case MYSQL_TYPE_TIMESTAMP2:
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_DATETIME2:
- case MYSQL_TYPE_DATETIME: return MYSQL_TIMESTAMP_DATETIME;
- case MYSQL_TYPE_NEWDATE:
- case MYSQL_TYPE_DATE: return MYSQL_TIMESTAMP_DATE;
- default: return MYSQL_TIMESTAMP_ERROR;
- }
-}
-
-
-/**
- Tests if field type is temporal, i.e. represents
- DATE, TIME, DATETIME or TIMESTAMP types in SQL.
-
- @param type Field type, as returned by field->type().
- @retval true If field type is temporal
- @retval false If field type is not temporal
-*/
-inline bool is_temporal_type(enum_field_types type)
-{
- return mysql_type_to_time_type(type) != MYSQL_TIMESTAMP_ERROR;
-}
-
-
enum enum_vcol_info_type
{
VCOL_GENERATED_VIRTUAL, VCOL_GENERATED_STORED,
@@ -558,6 +530,7 @@ static inline const char *vcol_type_name(enum_vcol_info_type type)
#define VCOL_TIME_FUNC 8
#define VCOL_AUTO_INC 16
#define VCOL_IMPOSSIBLE 32
+#define VCOL_NOT_VIRTUAL 64 /* Function can't be virtual */
#define VCOL_NOT_STRICTLY_DETERMINISTIC \
(VCOL_NON_DETERMINISTIC | VCOL_TIME_FUNC | VCOL_SESSION_FUNC)
@@ -669,11 +642,21 @@ public:
DBUG_ASSERT(size < UINT_MAX32);
return thd_alloc(current_thd, (uint) size);
}
- static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); }
+ static void operator delete(void *ptr_arg, size_t size) { TRASH_FREE(ptr_arg, size); }
static void operator delete(void *ptr, MEM_ROOT *mem_root)
{ DBUG_ASSERT(0); }
+ /**
+ Used by System Versioning.
+ */
+ virtual void set_max()
+ { DBUG_ASSERT(0); }
+ virtual bool is_max()
+ { DBUG_ASSERT(0); return false; }
+
uchar *ptr; // Position to field in record
+
+ field_visibility_t invisible;
/**
Byte where the @c NULL bit is stored inside a record. If this Field is a
@c NOT @c NULL field, this member is @c NULL.
@@ -812,16 +795,16 @@ public:
@retval false - conversion is needed
*/
virtual bool memcpy_field_possible(const Field *from) const= 0;
- virtual int store(const char *to, uint length,CHARSET_INFO *cs)=0;
- virtual int store_hex_hybrid(const char *str, uint length);
+ virtual int store(const char *to, size_t length,CHARSET_INFO *cs)=0;
+ virtual int store_hex_hybrid(const char *str, size_t length);
virtual int store(double nr)=0;
virtual int store(longlong nr, bool unsigned_val)=0;
virtual int store_decimal(const my_decimal *d)=0;
- virtual int store_time_dec(MYSQL_TIME *ltime, uint dec);
+ virtual int store_time_dec(const MYSQL_TIME *ltime, uint dec);
virtual int store_timestamp(my_time_t timestamp, ulong sec_part);
- int store_time(MYSQL_TIME *ltime)
+ int store_time(const MYSQL_TIME *ltime)
{ return store_time_dec(ltime, TIME_SECOND_PART_DIGITS); }
- int store(const char *to, uint length, CHARSET_INFO *cs,
+ int store(const char *to, size_t length, CHARSET_INFO *cs,
enum_check_fields check_level);
int store(const LEX_STRING *ls, CHARSET_INFO *cs)
{
@@ -840,6 +823,10 @@ public:
}
virtual double val_real(void)=0;
virtual longlong val_int(void)=0;
+ virtual ulonglong val_uint(void)
+ {
+ return (ulonglong) val_int();
+ }
virtual bool val_bool(void)= 0;
virtual my_decimal *val_decimal(my_decimal *);
inline String *val_str(String *str) { return val_str(str, str); }
@@ -998,8 +985,19 @@ public:
{
return bitmap_is_set(&table->has_value_set, field_index);
}
+ void clear_has_explicit_value()
+ {
+ bitmap_clear_bit(&table->has_value_set, field_index);
+ }
bool set_explicit_default(Item *value);
+ virtual my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const
+ { DBUG_ASSERT(0); return 0; }
+ my_time_t get_timestamp(ulong *sec_part) const
+ {
+ return get_timestamp(ptr, sec_part);
+ }
+
/**
Evaluates the @c UPDATE default function, if one exists, and stores the
result in the record buffer. If no such function exists for the column,
@@ -1161,6 +1159,8 @@ public:
{ if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; }
inline bool maybe_null(void) const
{ return null_ptr != 0 || table->maybe_null; }
+ // Set to NULL on LOAD DATA or LOAD XML
+ virtual bool load_data_set_null(THD *thd);
/* @return true if this field is NULL-able (even if temporarily) */
inline bool real_maybe_null(void) const { return null_ptr != 0; }
@@ -1439,6 +1439,21 @@ public:
FIELD_FLAGS_COLUMN_FORMAT;
}
+ bool vers_sys_field() const
+ {
+ return flags & (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG);
+ }
+
+ bool vers_update_unversioned() const
+ {
+ return flags & VERS_UPDATE_UNVERSIONED_FLAG;
+ }
+
+ virtual bool vers_trx_id() const
+ {
+ return false;
+ }
+
/*
Validate a non-null field value stored in the given record
according to the current thread settings, e.g. sql_mode.
@@ -1532,6 +1547,7 @@ public:
{
return NULL;
}
+ virtual bool sp_prepare_and_store_item(THD *thd, Item **value);
friend int cre_myisam(char * name, register TABLE *form, uint options,
ulonglong auto_increment_value);
@@ -1603,20 +1619,20 @@ class Field_num :public Field {
protected:
int check_edom_and_important_data_truncation(const char *type, bool edom,
CHARSET_INFO *cs,
- const char *str, uint length,
+ const char *str, size_t length,
const char *end_of_num);
int check_edom_and_truncation(const char *type, bool edom,
CHARSET_INFO *cs,
- const char *str, uint length,
+ const char *str, size_t length,
const char *end_of_num);
- int check_int(CHARSET_INFO *cs, const char *str, uint length,
+ int check_int(CHARSET_INFO *cs, const char *str, size_t length,
const char *int_end, int error)
{
return check_edom_and_truncation("integer",
error == MY_ERRNO_EDOM || str == int_end,
cs, str, length, int_end);
}
- bool get_int(CHARSET_INFO *cs, const char *from, uint len,
+ bool get_int(CHARSET_INFO *cs, const char *from, size_t len,
longlong *rnd, ulonglong unsigned_max,
longlong signed_min, longlong signed_max);
void prepend_zeros(String *value) const;
@@ -1670,7 +1686,7 @@ public:
field_metadata, length));
return length;
}
- int store_time_dec(MYSQL_TIME *ltime, uint dec);
+ int store_time_dec(const MYSQL_TIME *ltime, uint dec);
double pos_in_interval(Field *min, Field *max)
{
return pos_in_interval_val_real(min, max);
@@ -1703,8 +1719,8 @@ public:
int store(double nr);
int store(longlong nr, bool unsigned_val);
int store_decimal(const my_decimal *);
- int store(const char *to,uint length,CHARSET_INFO *cs)=0;
- int store_hex_hybrid(const char *str, uint length)
+ int store(const char *to,size_t length,CHARSET_INFO *cs)=0;
+ int store_hex_hybrid(const char *str, size_t length)
{
return store(str, length, &my_charset_bin);
}
@@ -1787,7 +1803,7 @@ public:
/* base class for float and double and decimal (old one) */
class Field_real :public Field_num {
protected:
- double get_double(const char *str, uint length, CHARSET_INFO *cs, int *err);
+ double get_double(const char *str, size_t length, CHARSET_INFO *cs, int *err);
public:
bool not_fixed;
@@ -1815,7 +1831,7 @@ public:
field_length >= from->field_length;
}
int store_decimal(const my_decimal *);
- int store_time_dec(MYSQL_TIME *ltime, uint dec);
+ int store_time_dec(const MYSQL_TIME *ltime, uint dec);
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
my_decimal *val_decimal(my_decimal *);
bool val_bool() { return val_real() != 0e0; }
@@ -1843,7 +1859,7 @@ public:
return eq_def(from) ? get_identical_copy_func() : do_field_string;
}
int reset(void);
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
double val_real(void);
@@ -1902,10 +1918,10 @@ public:
bool store_value(const my_decimal *decimal_value);
bool store_value(const my_decimal *decimal_value, int *native_error);
void set_value_on_overflow(my_decimal *decimal_value, bool sign);
- int store(const char *to, uint length, CHARSET_INFO *charset);
+ int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
- int store_time_dec(MYSQL_TIME *ltime, uint dec);
+ int store_time_dec(const MYSQL_TIME *ltime, uint dec);
int store_decimal(const my_decimal *);
double val_real(void);
longlong val_int(void);
@@ -1948,7 +1964,7 @@ public:
const Type_handler *type_handler() const { return &type_handler_tiny; }
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int reset(void) { ptr[0]=0; return 0; }
@@ -1998,7 +2014,7 @@ public:
const Type_handler *type_handler() const { return &type_handler_short; }
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;}
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int reset(void) { ptr[0]=ptr[1]=0; return 0; }
@@ -2033,7 +2049,7 @@ public:
const Type_handler *type_handler() const { return &type_handler_int24; }
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
@@ -2073,7 +2089,7 @@ public:
const Type_handler *type_handler() const { return &type_handler_long; }
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
@@ -2119,7 +2135,7 @@ public:
const Type_handler *type_handler() const { return &type_handler_longlong; }
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int reset(void)
@@ -2146,6 +2162,57 @@ public:
{
return unpack_int64(to, from, from_end);
}
+
+ void set_max();
+ bool is_max();
+};
+
+
+class Field_vers_trx_id :public Field_longlong {
+ MYSQL_TIME cache;
+ ulonglong cached;
+public:
+ Field_vers_trx_id(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
+ uchar null_bit_arg, enum utype unireg_check_arg,
+ const LEX_CSTRING *field_name_arg, bool zero_arg,
+ bool unsigned_arg)
+ : Field_longlong(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
+ unireg_check_arg, field_name_arg, zero_arg,
+ unsigned_arg),
+ cached(0)
+ {}
+ enum_field_types real_type() const { return MYSQL_TYPE_LONGLONG; }
+ enum_field_types type() const { return MYSQL_TYPE_LONGLONG;}
+ uint size_of() const { return sizeof(*this); }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate, ulonglong trx_id);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return get_date(ltime, fuzzydate, (ulonglong) val_int());
+ }
+ bool test_if_equality_guarantees_uniqueness(const Item *item) const;
+ bool can_optimize_keypart_ref(const Item_bool_func *cond,
+ const Item *item) const
+ {
+ return true;
+ }
+
+ bool can_optimize_group_min_max(const Item_bool_func *cond,
+ const Item *const_item) const
+ {
+ return true;
+ }
+ bool can_optimize_range(const Item_bool_func *cond,
+ const Item *item,
+ bool is_eq_func) const
+ {
+ return true;
+ }
+ /* cmp_type() cannot be TIME_RESULT, because we want to compare this field against
+ integers. But in all other cases we treat it as TIME_RESULT! */
+ bool vers_trx_id() const
+ {
+ return true;
+ }
};
@@ -2172,7 +2239,7 @@ public:
}
const Type_handler *type_handler() const { return &type_handler_float; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int reset(void) { bzero(ptr,sizeof(float)); return 0; }
@@ -2191,6 +2258,7 @@ private:
class Field_double :public Field_real {
+ longlong val_int_from_real(bool want_unsigned_result);
public:
Field_double(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg,
@@ -2223,18 +2291,13 @@ public:
}
const Type_handler *type_handler() const { return &type_handler_double; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int reset(void) { bzero(ptr,sizeof(double)); return 0; }
double val_real(void);
- longlong val_int(void)
- {
- Converter_double_to_longlong conv(Field_double::val_real(), false);
- if (conv.error())
- conv.push_warning(get_thd(), Field_double::val_real(), false);
- return conv.result();
- }
+ longlong val_int(void) { return val_int_from_real(false); }
+ ulonglong val_uint(void) { return (ulonglong) val_int_from_real(true); }
String *val_str(String*,String *);
bool send_binary(Protocol *protocol);
int cmp(const uchar *,const uchar *);
@@ -2263,7 +2326,7 @@ public:
{
return do_field_string;
}
- int store(const char *to, uint length, CHARSET_INFO *cs)
+ int store(const char *to, size_t length, CHARSET_INFO *cs)
{ null[0]=1; return 0; }
int store(double nr) { null[0]=1; return 0; }
int store(longlong nr, bool unsigned_val) { null[0]=1; return 0; }
@@ -2285,13 +2348,11 @@ public:
bool can_optimize_keypart_ref(const Item_bool_func *cond,
const Item *item) const
{
- DBUG_ASSERT(0);
return false;
}
bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const
{
- DBUG_ASSERT(0);
return false;
}
};
@@ -2308,7 +2369,7 @@ public:
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
field_name_arg)
{ flags|= BINARY_FLAG; }
- int store_hex_hybrid(const char *str, uint length)
+ int store_hex_hybrid(const char *str, size_t length)
{
return store(str, length, &my_charset_bin);
}
@@ -2385,10 +2446,10 @@ public:
:Field_temporal(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg)
{}
- int store(const char *to, uint length, CHARSET_INFO *charset);
+ int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
- int store_time_dec(MYSQL_TIME *ltime, uint dec);
+ int store_time_dec(const MYSQL_TIME *ltime, uint dec);
int store_decimal(const my_decimal *);
bool validate_value_in_record(THD *thd, const uchar *record) const;
};
@@ -2396,6 +2457,7 @@ public:
class Field_timestamp :public Field_temporal {
protected:
+ sql_mode_t sql_mode_for_timestamp(THD *thd) const;
int store_TIME_with_warning(THD *, MYSQL_TIME *, const ErrConv *,
int warnings, bool have_smth_to_conv);
public:
@@ -2407,10 +2469,10 @@ public:
const Type_handler *type_handler() const { return &type_handler_timestamp; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
Copy_func *get_copy_func(const Field *from) const;
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
- int store_time_dec(MYSQL_TIME *ltime, uint dec);
+ int store_time_dec(const MYSQL_TIME *ltime, uint dec);
int store_decimal(const my_decimal *);
int store_timestamp(my_time_t timestamp, ulong sec_part);
int save_in_field(Field *to);
@@ -2432,7 +2494,7 @@ public:
return res;
}
/* Get TIMESTAMP field value as seconds since begging of Unix Epoch */
- virtual my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const;
+ my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const;
my_time_t get_timestamp(ulong *sec_part) const
{
return get_timestamp(ptr, sec_part);
@@ -2457,6 +2519,7 @@ public:
{
return get_equal_const_item_datetime(thd, ctx, const_item);
}
+ bool load_data_set_null(THD *thd);
uint size_of() const { return sizeof(*this); }
};
@@ -2561,8 +2624,14 @@ public:
{
return memcmp(a_ptr, b_ptr, pack_length());
}
+ void set_max();
+ bool is_max();
void store_TIME(my_time_t timestamp, ulong sec_part);
my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const;
+ my_time_t get_timestamp(ulong *sec_part) const
+ {
+ return get_timestamp(ptr, sec_part);
+ }
uint size_of() const { return sizeof(*this); }
};
@@ -2603,10 +2672,10 @@ public:
}
return do_field_int;
}
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
- int store_time_dec(MYSQL_TIME *ltime, uint dec);
+ int store_time_dec(const MYSQL_TIME *ltime, uint dec);
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
@@ -2687,9 +2756,14 @@ class Field_time :public Field_temporal {
*/
long curdays;
protected:
- virtual void store_TIME(MYSQL_TIME *ltime);
+ virtual void store_TIME(const MYSQL_TIME *ltime);
int store_TIME_with_warning(MYSQL_TIME *ltime, const ErrConv *str,
int was_cut, int have_smth_to_conv);
+ void set_warnings(Sql_condition::enum_warning_level level,
+ const ErrConv *str, int was_cut)
+ {
+ Field_temporal::set_warnings(level, str, was_cut, MYSQL_TIMESTAMP_TIME);
+ }
bool check_zero_in_date_with_warn(ulonglong fuzzydate);
static void do_field_time(Copy_field *copy);
public:
@@ -2716,8 +2790,8 @@ public:
return real_type() == from->real_type() &&
decimals() == from->decimals();
}
- int store_time_dec(MYSQL_TIME *ltime, uint dec);
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store_time_dec(const MYSQL_TIME *ltime, uint dec);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int store_decimal(const my_decimal *);
@@ -2771,7 +2845,7 @@ public:
*/
class Field_time_hires :public Field_time_with_dec {
longlong zero_point;
- void store_TIME(MYSQL_TIME *ltime);
+ void store_TIME(const MYSQL_TIME *);
public:
Field_time_hires(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
@@ -2797,7 +2871,7 @@ public:
TIME(0..6) - MySQL56 version
*/
class Field_timef :public Field_time_with_dec {
- void store_TIME(MYSQL_TIME *ltime);
+ void store_TIME(const MYSQL_TIME *ltime);
int save_field_metadata(uchar *metadata_ptr)
{
*metadata_ptr= (uchar) decimals();
@@ -3090,7 +3164,7 @@ public:
(has_charset() ? ' ' : 0));
return 0;
}
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
using Field_str::store;
double val_real(void);
longlong val_int(void);
@@ -3194,7 +3268,7 @@ public:
!compression_method() == !from->compression_method() &&
length_bytes == ((Field_varstring*) from)->length_bytes;
}
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
using Field_str::store;
double val_real(void);
longlong val_int(void);
@@ -3250,7 +3324,7 @@ public:
{ return compression_method_ptr; }
private:
Compression_method *compression_method_ptr;
- int store(const char *to, uint length, CHARSET_INFO *charset);
+ int store(const char *to, size_t length, CHARSET_INFO *charset);
using Field_str::store;
String *val_str(String *, String *);
double val_real(void);
@@ -3410,7 +3484,7 @@ public:
!compression_method() == !from->compression_method() &&
!table->copy_blobs;
}
- int store(const char *to, uint length, CHARSET_INFO *charset);
+ int store(const char *to, size_t length, CHARSET_INFO *charset);
using Field_str::store;
double val_real(void);
longlong val_int(void);
@@ -3453,9 +3527,10 @@ public:
void reset_fields() { bzero((uchar*) &value,sizeof(value)); bzero((uchar*) &read_value,sizeof(read_value)); }
uint32 get_field_buffer_size(void) { return value.alloced_length(); }
void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number);
- inline void store_length(uint32 number)
+ inline void store_length(size_t number)
{
- store_length(ptr, packlength, number);
+ DBUG_ASSERT(number < UINT_MAX32);
+ store_length(ptr, packlength, (uint32)number);
}
inline uint32 get_length(uint row_offset= 0) const
{ return get_length(ptr+row_offset, this->packlength); }
@@ -3563,7 +3638,7 @@ public:
{ return compression_method_ptr; }
private:
Compression_method *compression_method_ptr;
- int store(const char *to, uint length, CHARSET_INFO *charset);
+ int store(const char *to, size_t length, CHARSET_INFO *charset);
using Field_str::store;
String *val_str(String *, String *);
double val_real(void);
@@ -3630,7 +3705,7 @@ public:
bool is_eq_func) const;
void sql_type(String &str) const;
uint is_equal(Create_field *new_field);
- int store(const char *to, uint length, CHARSET_INFO *charset);
+ int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int store_decimal(const my_decimal *);
@@ -3649,6 +3724,7 @@ public:
but the underlying blob must still be reset.
*/
int reset(void) { return Field_blob::reset() || !maybe_null(); }
+ bool load_data_set_null(THD *thd);
geometry_type get_geometry_type() { return geom_type; };
static geometry_type geometry_type_merge(geometry_type, geometry_type);
@@ -3656,7 +3732,7 @@ public:
};
uint gis_field_options_image(uchar *buff, List<Create_field> &create_fields);
-uint gis_field_options_read(const uchar *buf, uint buf_len,
+uint gis_field_options_read(const uchar *buf, size_t buf_len,
Field_geom::storage_type *st_type,uint *precision, uint *scale, uint *srid);
#endif /*HAVE_SPATIAL*/
@@ -3710,7 +3786,7 @@ public:
return save_in_field_str(to);
}
bool memcpy_field_possible(const Field *from) const { return false; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
double val_real(void);
@@ -3777,7 +3853,7 @@ public:
flags=(flags & ~ENUM_FLAG) | SET_FLAG;
}
int store_field(Field *from) { return from->save_in_field(this); }
- int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr) { return Field_set::store((longlong) nr, FALSE); }
int store(longlong nr, bool unsigned_val);
@@ -3833,7 +3909,7 @@ public:
}
int save_in_field(Field *to) { return to->store(val_int(), true); }
bool memcpy_field_possible(const Field *from) const { return false; }
- int store(const char *to, uint length, CHARSET_INFO *charset);
+ int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int store_decimal(const my_decimal *);
@@ -3952,7 +4028,7 @@ public:
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg);
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
uint size_of() const { return sizeof(*this); }
- int store(const char *to, uint length, CHARSET_INFO *charset);
+ int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr) { return Field_bit::store(nr); }
int store(longlong nr, bool unsigned_val)
{ return Field_bit::store(nr, unsigned_val); }
@@ -3970,6 +4046,7 @@ public:
{}
~Field_row();
Virtual_tmp_table **virtual_tmp_table_addr() { return &m_table; }
+ bool sp_prepare_and_store_item(THD *thd, Item **value);
};
@@ -3982,7 +4059,8 @@ Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
CHARSET_INFO *cs,
Field::geometry_type geom_type, uint srid,
Field::utype unireg_check,
- TYPELIB *interval, const LEX_CSTRING *field_name);
+ TYPELIB *interval, const LEX_CSTRING *field_name,
+ uint32 flags);
/*
Create field class for CREATE TABLE
@@ -4036,12 +4114,19 @@ class Column_definition: public Sql_alloc,
public:
LEX_CSTRING field_name;
LEX_CSTRING comment; // Comment for field
+ enum enum_column_versioning
+ {
+ VERSIONING_NOT_SET,
+ WITH_VERSIONING,
+ WITHOUT_VERSIONING
+ };
Item *on_update; // ON UPDATE NOW()
/*
At various stages in execution this can be length of field in bytes or
max number of characters.
*/
ulonglong length;
+ field_visibility_t invisible;
/*
The value of `length' as set by parser: is the number of characters
for most of the types, or of bytes for BLOBs or numeric types.
@@ -4068,19 +4153,23 @@ public:
*default_value, // Default value
*check_constraint; // Check constraint
+ enum_column_versioning versioning;
+
Column_definition()
:Type_handler_hybrid_field_type(&type_handler_null),
compression_method_ptr(0),
comment(null_clex_str),
- on_update(NULL), length(0), decimals(0),
+ on_update(NULL), length(0), invisible(VISIBLE), decimals(0),
flags(0), pack_length(0), key_length(0), unireg_check(Field::NONE),
interval(0), charset(&my_charset_bin),
srid(0), geom_type(Field::GEOM_GEOMETRY),
option_list(NULL), pack_flag(0),
- vcol_info(0), default_value(0), check_constraint(0)
+ vcol_info(0), default_value(0), check_constraint(0),
+ versioning(VERSIONING_NOT_SET)
{
interval_list.empty();
}
+
Column_definition(THD *thd, Field *field, Field *orig_field);
void set_attributes(const Lex_field_type_st &type, CHARSET_INFO *cs);
void create_length_to_internal_length_null()
@@ -4107,6 +4196,10 @@ public:
length*= charset->mbmaxlen;
key_length= pack_length;
}
+ bool vers_sys_field() const
+ {
+ return flags & (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG);
+ }
void create_length_to_internal_length_bit();
void create_length_to_internal_length_newdecimal();
@@ -4207,7 +4300,7 @@ public:
(uint32)length, null_pos, null_bit,
pack_flag, type_handler(), charset,
geom_type, srid, unireg_check, interval,
- field_name_arg);
+ field_name_arg, flags);
}
Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *field_name_arg) const
@@ -4287,7 +4380,6 @@ public:
bool resolve_type_refs(THD *);
};
-
/**
This class is used during a stored routine or a trigger execution,
at sp_rcontext::create() time.
@@ -4309,8 +4401,8 @@ public:
*/
class Spvar_definition: public Column_definition
{
- class Qualified_column_ident *m_column_type_ref; // for %TYPE
- class Table_ident *m_table_rowtype_ref; // for table%ROWTYPE
+ Qualified_column_ident *m_column_type_ref; // for %TYPE
+ Table_ident *m_table_rowtype_ref; // for table%ROWTYPE
bool m_cursor_rowtype_ref; // for cursor%ROWTYPE
uint m_cursor_rowtype_offset; // for cursor%ROWTYPE
Row_definition_list *m_row_field_definitions; // for ROW
@@ -4337,20 +4429,20 @@ public:
bool is_column_type_ref() const { return m_column_type_ref != 0; }
bool is_table_rowtype_ref() const { return m_table_rowtype_ref != 0; }
bool is_cursor_rowtype_ref() const { return m_cursor_rowtype_ref; }
- class Qualified_column_ident *column_type_ref() const
+ Qualified_column_ident *column_type_ref() const
{
return m_column_type_ref;
}
- void set_column_type_ref(class Qualified_column_ident *ref)
+ void set_column_type_ref(Qualified_column_ident *ref)
{
m_column_type_ref= ref;
}
- class Table_ident *table_rowtype_ref() const
+ Table_ident *table_rowtype_ref() const
{
return m_table_rowtype_ref;
}
- void set_table_rowtype_ref(class Table_ident *ref)
+ void set_table_rowtype_ref(Table_ident *ref)
{
DBUG_ASSERT(ref);
set_handler(&type_handler_row);
@@ -4549,5 +4641,21 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name,
#define f_no_default(x) ((x) & FIELDFLAG_NO_DEFAULT)
#define f_bit_as_char(x) ((x) & FIELDFLAG_TREAT_BIT_AS_CHAR)
#define f_is_hex_escape(x) ((x) & FIELDFLAG_HEX_ESCAPE)
+#define f_visibility(x) (static_cast<field_visibility_t> ((x) & INVISIBLE_MAX_BITS))
+
+inline
+ulonglong TABLE::vers_end_id() const
+{
+ DBUG_ASSERT(versioned(VERS_TRX_ID));
+ return static_cast<ulonglong>(vers_end_field()->val_int());
+}
+
+inline
+ulonglong TABLE::vers_start_id() const
+{
+ DBUG_ASSERT(versioned(VERS_TRX_ID));
+ return static_cast<ulonglong>(vers_start_field()->val_int());
+}
+
#endif /* FIELD_INCLUDED */
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index a817db51569..d648c90e114 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -122,6 +122,7 @@ static int set_bad_null_error(Field *field, int err)
field->set_warning(Sql_condition::WARN_LEVEL_WARN, err, 1);
/* fall through */
case CHECK_FIELD_IGNORE:
+ case CHECK_FIELD_EXPRESSION:
return 0;
case CHECK_FIELD_ERROR_FOR_NULL:
if (!field->table->in_use->no_errors)
@@ -388,7 +389,7 @@ static void do_field_varbinary_pre50(Copy_field *copy)
copy->from_field->val_str(&copy->tmp);
/* Use the same function as in 4.1 to trim trailing spaces */
- uint length= my_lengthsp_8bit(&my_charset_bin, copy->tmp.c_ptr_quick(),
+ size_t length= my_lengthsp_8bit(&my_charset_bin, copy->tmp.c_ptr_quick(),
copy->from_field->field_length);
copy->to_field->store(copy->tmp.c_ptr_quick(), length,
@@ -480,7 +481,7 @@ static void do_cut_string_complex(Copy_field *copy)
(char*) copy->from_ptr,
(char*) from_end,
copy->to_length / cs->mbmaxlen);
- uint copy_length= prefix.length();
+ size_t copy_length= prefix.length();
if (copy->to_length < copy_length)
copy_length= copy->to_length;
memcpy(copy->to_ptr, copy->from_ptr, copy_length);
@@ -528,7 +529,8 @@ static void do_varstring1(Copy_field *copy)
if (length > copy->to_length- 1)
{
length=copy->to_length - 1;
- if (copy->from_field->table->in_use->count_cuted_fields &&
+ if (copy->from_field->table->in_use->count_cuted_fields >
+ CHECK_FIELD_EXPRESSION &&
copy->to_field)
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
@@ -547,7 +549,7 @@ static void do_varstring1_mb(Copy_field *copy)
Well_formed_prefix prefix(cs, (char*) from_ptr, from_length, to_char_length);
if (prefix.length() < from_length)
{
- if (current_thd->count_cuted_fields)
+ if (current_thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
}
@@ -562,7 +564,8 @@ static void do_varstring2(Copy_field *copy)
if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
{
length=copy->to_length-HA_KEY_BLOB_LENGTH;
- if (copy->from_field->table->in_use->count_cuted_fields &&
+ if (copy->from_field->table->in_use->count_cuted_fields >
+ CHECK_FIELD_EXPRESSION &&
copy->to_field)
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
@@ -582,7 +585,7 @@ static void do_varstring2_mb(Copy_field *copy)
Well_formed_prefix prefix(cs, (char*) from_beg, from_length, char_length);
if (prefix.length() < from_length)
{
- if (current_thd->count_cuted_fields)
+ if (current_thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
}
@@ -607,7 +610,7 @@ void Copy_field::set(uchar *to,Field *from)
{
from_ptr=from->ptr;
to_ptr=to;
- from_length=from->pack_length();
+ from_length=from->pack_length_in_rec();
if (from->maybe_null())
{
from_null_ptr=from->null_ptr;
@@ -655,9 +658,9 @@ void Copy_field::set(Field *to,Field *from,bool save)
from_field=from;
to_field=to;
from_ptr=from->ptr;
- from_length=from->pack_length();
+ from_length=from->pack_length_in_rec();
to_ptr= to->ptr;
- to_length=to_field->pack_length();
+ to_length=to_field->pack_length_in_rec();
// set up null handling
from_null_ptr=to_null_ptr=0;
diff --git a/sql/filesort.cc b/sql/filesort.cc
index d2e167ce7bf..00dfa08bba8 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -25,9 +25,6 @@
#include "mariadb.h"
#include "sql_priv.h"
#include "filesort.h"
-#ifdef HAVE_STDDEF_H
-#include <stddef.h> /* for macro offsetof */
-#endif
#include <m_ctype.h>
#include "sql_sort.h"
#include "probes_mysql.h"
@@ -71,7 +68,7 @@ static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
uchar *buff, uchar *buff_end);
static bool check_if_pq_applicable(Sort_param *param, SORT_INFO *info,
TABLE *table,
- ha_rows records, ulong memory_available);
+ ha_rows records, size_t memory_available);
void Sort_param::init_for_filesort(uint sortlen, TABLE *table,
ulong max_length_for_sort_data,
@@ -92,7 +89,10 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table,
table->field, sort_length, &addon_buf);
}
if (addon_field)
- res_length= addon_buf.length;
+ {
+ DBUG_ASSERT(addon_buf.length < UINT_MAX32);
+ res_length= (uint)addon_buf.length;
+ }
else
{
res_length= ref_length;
@@ -102,7 +102,7 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table,
*/
sort_length+= ref_length;
}
- rec_length= sort_length + addon_buf.length;
+ rec_length= sort_length + (uint)addon_buf.length;
max_rows= maxrows;
}
@@ -713,6 +713,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
handler *file;
MY_BITMAP *save_read_set, *save_write_set, *save_vcol_set;
Item *sort_cond;
+ ha_rows retval;
DBUG_ENTER("find_all_keys");
DBUG_PRINT("info",("using: %s",
(select ? select->quick ? "ranges" : "where":
@@ -770,7 +771,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
if (quick_select)
{
if (select->quick->reset())
- DBUG_RETURN(HA_POS_ERROR);
+ goto err;
}
DEBUG_SYNC(thd, "after_index_merge_phase1");
@@ -807,7 +808,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
(void) file->extra(HA_EXTRA_NO_CACHE);
file->ha_rnd_end();
}
- DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
+ goto err; /* purecov: inspected */
}
bool write_record= false;
@@ -829,11 +830,11 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
MY_BITMAP *tmp_write_set= sort_form->write_set;
MY_BITMAP *tmp_vcol_set= sort_form->vcol_set;
- if (select->cond->with_subselect)
+ if (select->cond->with_subquery())
sort_form->column_bitmaps_set(save_read_set, save_write_set,
save_vcol_set);
write_record= (select->skip_record(thd) > 0);
- if (select->cond->with_subselect)
+ if (select->cond->with_subquery())
sort_form->column_bitmaps_set(tmp_read_set,
tmp_write_set,
tmp_vcol_set);
@@ -855,7 +856,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
if (idx == param->max_keys_per_buffer)
{
if (write_keys(param, fs_info, idx, buffpek_pointers, tempfile))
- DBUG_RETURN(HA_POS_ERROR);
+ goto err;
idx= 0;
indexpos++;
}
@@ -881,12 +882,12 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
file->ha_rnd_end();
}
- if (thd->is_error())
- DBUG_RETURN(HA_POS_ERROR);
-
/* Signal we should use orignal column read and write maps */
sort_form->column_bitmaps_set(save_read_set, save_write_set, save_vcol_set);
+ if (thd->is_error())
+ DBUG_RETURN(HA_POS_ERROR);
+
DBUG_PRINT("test",("error: %d indexpos: %d",error,indexpos));
if (error != HA_ERR_END_OF_FILE)
{
@@ -896,11 +897,15 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
if (indexpos && idx &&
write_keys(param, fs_info, idx, buffpek_pointers, tempfile))
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
- const ha_rows retval=
- my_b_inited(tempfile) ?
- (ha_rows) (my_b_tell(tempfile)/param->rec_length) : idx;
+ retval= (my_b_inited(tempfile) ?
+ (ha_rows) (my_b_tell(tempfile)/param->rec_length) :
+ idx);
DBUG_PRINT("info", ("find_all_keys return %llu", (ulonglong) retval));
DBUG_RETURN(retval);
+
+err:
+ sort_form->column_bitmaps_set(save_read_set, save_write_set, save_vcol_set);
+ DBUG_RETURN(HA_POS_ERROR);
} /* find_all_keys */
@@ -998,7 +1003,8 @@ Type_handler_string_result::make_sort_key(uchar *to, Item *item,
if (maybe_null)
*to++= 1;
char *tmp_buffer= param->tmp_buffer ? param->tmp_buffer : (char*) to;
- String tmp(tmp_buffer, param->sort_length, cs);
+ String tmp(tmp_buffer, param->tmp_buffer ? param->sort_length :
+ sort_field->length, cs);
String *res= item->str_result(&tmp);
if (!res)
{
@@ -1023,8 +1029,8 @@ Type_handler_string_result::make_sort_key(uchar *to, Item *item,
if (use_strnxfrm(cs))
{
- uint tmp_length __attribute__((unused));
- tmp_length= cs->coll->strnxfrm(cs, to, sort_field->length,
+ IF_DBUG(size_t tmp_length= ,)
+ cs->coll->strnxfrm(cs, to, sort_field->length,
item->max_char_length() *
cs->strxfrm_multiply,
(uchar*) res->ptr(), res->length(),
@@ -1343,10 +1349,10 @@ static bool save_index(Sort_param *param, uint count,
false - PQ will be slower than merge-sort, or there is not enough memory.
*/
-bool check_if_pq_applicable(Sort_param *param,
+static bool check_if_pq_applicable(Sort_param *param,
SORT_INFO *filesort_info,
TABLE *table, ha_rows num_rows,
- ulong memory_available)
+ size_t memory_available)
{
DBUG_ENTER("check_if_pq_applicable");
@@ -1368,7 +1374,7 @@ bool check_if_pq_applicable(Sort_param *param,
DBUG_RETURN(false);
}
- ulong num_available_keys=
+ size_t num_available_keys=
memory_available / (param->rec_length + sizeof(char*));
// We need 1 extra record in the buffer, when using PQ.
param->max_keys_per_buffer= (uint) param->max_rows + 1;
@@ -1398,7 +1404,7 @@ bool check_if_pq_applicable(Sort_param *param,
// Try to strip off addon fields.
if (param->addon_field)
{
- const ulong row_length=
+ const size_t row_length=
param->sort_length + param->ref_length + sizeof(char*);
num_available_keys= memory_available / row_length;
@@ -1408,7 +1414,7 @@ bool check_if_pq_applicable(Sort_param *param,
const double sort_merge_cost=
get_merge_many_buffs_cost_fast(num_rows,
num_available_keys,
- row_length);
+ (uint)row_length);
/*
PQ has cost:
(insert + qsort) * log(queue size) / TIME_FOR_COMPARE_ROWID +
@@ -1880,7 +1886,7 @@ Type_handler_string_result::sortlength(THD *thd,
set_if_smaller(sortorder->length, thd->variables.max_sort_length);
if (use_strnxfrm((cs= item->collation.collation)))
{
- sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
+ sortorder->length= (uint)cs->coll->strnxfrmlen(cs, sortorder->length);
}
else if (cs == &my_charset_bin)
{
@@ -1963,7 +1969,7 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
if (use_strnxfrm((cs=sortorder->field->sort_charset())))
{
*multi_byte_charset= true;
- sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
+ sortorder->length= (uint)cs->coll->strnxfrmlen(cs, sortorder->length);
}
if (sortorder->field->maybe_null())
length++; // Place for NULL marker
diff --git a/sql/filesort_utils.cc b/sql/filesort_utils.cc
index 11be9229c1d..b39bb880c15 100644
--- a/sql/filesort_utils.cc
+++ b/sql/filesort_utils.cc
@@ -105,7 +105,7 @@ uchar **Filesort_buffer::alloc_sort_buffer(uint num_records,
DBUG_EXECUTE_IF("alloc_sort_buffer_fail",
DBUG_SET("+d,simulate_out_of_memory"););
- buff_size= num_records * (record_length + sizeof(uchar*));
+ buff_size= ((size_t)num_records) * (record_length + sizeof(uchar*));
set_if_bigger(buff_size, record_length * MERGEBUFF2);
if (!m_idx_array.is_null())
diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc
index da70daea4a8..ce1f4394ebd 100644
--- a/sql/gcalc_slicescan.cc
+++ b/sql/gcalc_slicescan.cc
@@ -137,13 +137,13 @@ static void GCALC_DBUG_PRINT_PI(const Gcalc_heap::Info *pi)
static void GCALC_DBUG_PRINT_SLICE(const char *header,
const Gcalc_scan_iterator::point *slice)
{
- int nbuf;
+ size_t nbuf;
char buf[1024];
nbuf= strlen(header);
strcpy(buf, header);
for (; slice; slice= slice->get_next())
{
- int lnbuf= nbuf;
+ size_t lnbuf= nbuf;
lnbuf+= sprintf(buf + lnbuf, "%d\t", slice->thread);
lnbuf+= sprintf(buf + lnbuf, "%s\t", gcalc_ev_name(slice->event));
@@ -170,7 +170,7 @@ static void GCALC_DBUG_PRINT_SLICE(const char *header,
Gcalc_dyn_list::Gcalc_dyn_list(size_t blk_size, size_t sizeof_item):
m_blk_size(blk_size - ALLOC_ROOT_MIN_BLOCK_SIZE),
m_sizeof_item(ALIGN_SIZE(sizeof_item)),
- m_points_per_blk((m_blk_size - PH_DATA_OFFSET) / m_sizeof_item),
+ m_points_per_blk((uint)((m_blk_size - PH_DATA_OFFSET) / m_sizeof_item)),
m_blk_hook(&m_first_blk),
m_free(NULL),
m_keep(NULL)
diff --git a/sql/gen_lex_token.cc b/sql/gen_lex_token.cc
index 4b5e0746eac..b36df5e94be 100644
--- a/sql/gen_lex_token.cc
+++ b/sql/gen_lex_token.cc
@@ -130,6 +130,8 @@ void compute_tokens()
set_token(WITH_CUBE_SYM, "WITH CUBE");
set_token(WITH_ROLLUP_SYM, "WITH ROLLUP");
+ set_token(WITH_SYSTEM_SYM, "WITH SYSTEM");
+ set_token(FOR_SYSTEM_TIME_SYM, "FOR SYSTEM_TIME");
set_token(VALUES_IN_SYM, "VALUES IN");
set_token(VALUES_LESS_SYM, "VALUES LESS");
set_token(NOT2_SYM, "!");
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 6bebf5d8676..76e80711a22 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2005, 2017, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, MariaDB
+ Copyright (c) 2009, 2018, 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
@@ -35,7 +35,7 @@
Partitioning lays the foundation for more manageable databases that are
extremely large. It does also lay the foundation for more parallelism
in the execution of queries. This functionality will grow with later
- versions of MySQL.
+ versions of MySQL/MariaDB.
The partition is setup to use table locks. It implements an partition "SHARE"
that is inserted into a hash by table name. You can use this to store
@@ -58,6 +58,7 @@
#include "sql_plugin.h"
#include "sql_show.h" // append_identifier
#include "sql_admin.h" // SQL_ADMIN_MSG_TEXT_SIZE
+#include "sql_select.h"
#include "debug_sync.h"
@@ -73,9 +74,7 @@
HA_REC_NOT_IN_SEQ | \
HA_CAN_REPAIR)
#define PARTITION_DISABLED_TABLE_FLAGS (HA_CAN_GEOMETRY | \
- HA_CAN_FULLTEXT | \
HA_DUPLICATE_POS | \
- HA_CAN_SQL_HANDLER | \
HA_CAN_INSERT_DELAYED | \
HA_READ_BEFORE_WRITE_REMOVAL |\
HA_CAN_TABLES_WITHOUT_ROLLBACK)
@@ -90,10 +89,7 @@ static handler *partition_create_handler(handlerton *hton,
TABLE_SHARE *share,
MEM_ROOT *mem_root);
static uint partition_flags();
-static uint alter_table_flags(uint flags);
-
-extern "C" int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
-extern "C" int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
+static ulonglong alter_table_flags(ulonglong flags);
/*
If frm_error() is called then we will use this to to find out what file
@@ -126,7 +122,6 @@ static void init_partition_psi_keys(void)
static int partition_initialize(void *p)
{
-
handlerton *partition_hton;
partition_hton= (handlerton *)p;
@@ -160,9 +155,6 @@ static int partition_initialize(void *p)
bool Partition_share::init(uint num_parts)
{
DBUG_ENTER("Partition_share::init");
- mysql_mutex_init(key_partition_auto_inc_mutex,
- &auto_inc_mutex,
- MY_MUTEX_INIT_FAST);
auto_inc_initialized= false;
partition_name_hash_initialized= false;
next_auto_inc_val= 0;
@@ -185,7 +177,7 @@ bool Partition_share::init(uint num_parts)
New partition object
*/
-static handler *partition_create_handler(handlerton *hton,
+static handler *partition_create_handler(handlerton *hton,
TABLE_SHARE *share,
MEM_ROOT *mem_root)
{
@@ -222,14 +214,12 @@ static uint partition_flags()
return HA_CAN_PARTITION;
}
-static uint alter_table_flags(uint flags __attribute__((unused)))
+static ulonglong alter_table_flags(ulonglong /* flags */)
{
return (HA_PARTITION_FUNCTION_SUPPORTED |
HA_FAST_CHANGE_PARTITION);
}
-const uint32 ha_partition::NO_CURRENT_PART_ID= NOT_A_PARTITION_ID;
-
/*
Constructor method
@@ -245,12 +235,19 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share)
:handler(hton, share)
{
DBUG_ENTER("ha_partition::ha_partition(table)");
- init_alloc_root(&m_mem_root, 512, 512, MYF(0));
- init_handler_variables();
+ ha_partition_init();
DBUG_VOID_RETURN;
}
+/* Initialize all partition variables */
+
+void ha_partition::ha_partition_init()
+{
+ init_alloc_root(&m_mem_root, "ha_partition", 512, 512, MYF(0));
+ init_handler_variables();
+}
+
/*
Constructor method
@@ -267,8 +264,7 @@ ha_partition::ha_partition(handlerton *hton, partition_info *part_info)
{
DBUG_ENTER("ha_partition::ha_partition(part_info)");
DBUG_ASSERT(part_info);
- init_alloc_root(&m_mem_root, 512, 512, MYF(0));
- init_handler_variables();
+ ha_partition_init();
m_part_info= part_info;
m_create_handler= TRUE;
m_is_sub_partitioned= m_part_info->is_sub_partitioned();
@@ -294,8 +290,7 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share,
:handler(hton, share)
{
DBUG_ENTER("ha_partition::ha_partition(clone)");
- init_alloc_root(&m_mem_root, 512, 512, MYF(0));
- init_handler_variables();
+ ha_partition_init();
m_part_info= part_info_arg;
m_create_handler= TRUE;
m_is_sub_partitioned= m_part_info->is_sub_partitioned();
@@ -358,6 +353,7 @@ void ha_partition::init_handler_variables()
m_curr_key_info[0]= NULL;
m_curr_key_info[1]= NULL;
m_part_func_monotonicity_info= NON_MONOTONIC;
+ m_key_not_found= FALSE;
auto_increment_lock= FALSE;
auto_increment_safe_stmt_log_lock= FALSE;
/*
@@ -372,6 +368,30 @@ void ha_partition::init_handler_variables()
part_share= NULL;
m_new_partitions_share_refs.empty();
m_part_ids_sorted_by_num_of_records= NULL;
+ m_partitions_to_open= NULL;
+
+ m_range_info= NULL;
+ m_mrr_full_buffer_size= 0;
+ m_mrr_new_full_buffer_size= 0;
+ m_mrr_full_buffer= NULL;
+ m_mrr_range_first= NULL;
+
+ m_pre_calling= FALSE;
+ m_pre_call_use_parallel= FALSE;
+
+ ft_first= ft_current= NULL;
+ bulk_access_executing= FALSE; // For future
+
+ /*
+ Clear bitmaps to allow on one to call my_bitmap_free() on them at any time
+ */
+ my_bitmap_clear(&m_bulk_insert_started);
+ my_bitmap_clear(&m_locked_partitions);
+ my_bitmap_clear(&m_partitions_to_reset);
+ my_bitmap_clear(&m_key_not_found_partitions);
+ my_bitmap_clear(&m_mrr_used_partitions);
+ my_bitmap_clear(&m_opened_partitions);
+ m_file_sample= NULL;
#ifdef DONT_HAVE_TO_BE_INITALIZED
m_start_key.flag= 0;
@@ -381,9 +401,9 @@ void ha_partition::init_handler_variables()
const char *ha_partition::table_type() const
-{
+{
// we can do this since we only support a single engine type
- return m_file[0]->table_type();
+ return m_file[0]->table_type();
}
@@ -684,6 +704,7 @@ int ha_partition::create(const char *name, TABLE *table_arg,
partition_element *part_elem;
handler **file, **abort_file;
DBUG_ENTER("ha_partition::create");
+ DBUG_PRINT("enter", ("name: '%s'", name));
DBUG_ASSERT(!fn_frm_ext(name));
@@ -697,7 +718,6 @@ int ha_partition::create(const char *name, TABLE *table_arg,
if (get_from_handler_file(name, ha_thd()->mem_root, false))
DBUG_RETURN(TRUE);
DBUG_ASSERT(m_file_buffer);
- DBUG_PRINT("enter", ("name: (%s)", name));
name_buffer_ptr= m_name_buffer_ptr;
file= m_file;
/*
@@ -960,7 +980,7 @@ int ha_partition::rename_partitions(const char *path)
When state is PART_IS_CHANGED it means that we have created a new
TEMP partition that is to be renamed to normal partition name and
we are to delete the old partition with currently the normal name.
-
+
We perform this operation by
1) Delete old partition with normal partition name
2) Signal this in table log entry
@@ -1195,7 +1215,7 @@ int ha_partition::preload_keys(THD *thd, HA_CHECK_OPT *check_opt)
DBUG_RETURN(handle_opt_partitions(thd, check_opt, PRELOAD_KEYS_PARTS));
}
-
+
/*
Handle optimize/analyze/check/repair of one partition
@@ -1217,7 +1237,7 @@ int ha_partition::handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt,
int error;
handler *file= m_file[part_id];
DBUG_ENTER("handle_opt_part");
- DBUG_PRINT("enter", ("flag = %u", flag));
+ DBUG_PRINT("enter", ("flag: %u", flag));
if (flag == OPTIMIZE_PARTS)
error= file->ha_optimize(thd, check_opt);
@@ -1261,24 +1281,24 @@ int ha_partition::handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt,
/*
- print a message row formatted for ANALYZE/CHECK/OPTIMIZE/REPAIR TABLE
+ print a message row formatted for ANALYZE/CHECK/OPTIMIZE/REPAIR TABLE
(modelled after mi_check_print_msg)
TODO: move this into the handler, or rewrite mysql_admin_table.
*/
-static bool print_admin_msg(THD* thd, uint len,
+bool print_admin_msg(THD* thd, uint len,
const char* msg_type,
const char* db_name, String &table_name,
const char* op_name, const char *fmt, ...)
ATTRIBUTE_FORMAT(printf, 7, 8);
-static bool print_admin_msg(THD* thd, uint len,
+bool print_admin_msg(THD* thd, uint len,
const char* msg_type,
const char* db_name, String &table_name,
const char* op_name, const char *fmt, ...)
{
va_list args;
Protocol *protocol= thd->protocol;
- uint length;
- uint msg_length;
+ size_t length;
+ size_t msg_length;
char name[NAME_LEN*2+2];
char *msgbuf;
bool error= true;
@@ -1290,7 +1310,7 @@ static bool print_admin_msg(THD* thd, uint len,
va_end(args);
if (msg_length >= (len - 1))
goto err;
- msgbuf[len - 1] = 0; // healthy paranoia
+ msgbuf[len - 1]= 0; // healthy paranoia
if (!thd->vio_ok())
@@ -1299,7 +1319,7 @@ static bool print_admin_msg(THD* thd, uint len,
goto err;
}
- length=(uint) (strxmov(name, db_name, ".", table_name.c_ptr_safe(), NullS) - name);
+ length=(size_t)(strxmov(name, db_name, ".", table_name.c_ptr_safe(), NullS) - name);
/*
TODO: switch from protocol to push_warning here. The main reason we didn't
it yet is parallel repair, which threads have no THD object accessible via
@@ -1384,7 +1404,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
print_admin_msg(thd, MYSQL_ERRMSG_SIZE, "error",
table_share->db.str, table->alias,
opt_op_name[flag],
- "Subpartition %s returned error",
+ "Subpartition %s returned error",
sub_elem->partition_name);
}
/* reset part_state for the remaining partitions */
@@ -1410,7 +1430,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
{
print_admin_msg(thd, MYSQL_ERRMSG_SIZE, "error",
table_share->db.str, table->alias,
- opt_op_name[flag], "Partition %s returned error",
+ opt_op_name[flag], "Partition %s returned error",
part_elem->partition_name);
}
/* reset part_state for the remaining partitions */
@@ -1452,7 +1472,7 @@ bool ha_partition::check_and_repair(THD *thd)
} while (*(++file));
DBUG_RETURN(FALSE);
}
-
+
/**
@breif Check if the table can be automatically repaired
@@ -1492,7 +1512,7 @@ bool ha_partition::is_crashed() const
} while (*(++file));
DBUG_RETURN(FALSE);
}
-
+
/*
Prepare by creating a new partition
@@ -1537,7 +1557,8 @@ int ha_partition::prepare_new_partition(TABLE *tbl,
if ((error= set_up_table_before_create(tbl, part_name, create_info, p_elem)))
goto error_create;
- tbl->s->connect_string = p_elem->connect_string;
+ if (!(file->ht->flags & HTON_CAN_READ_CONNECT_STRING_IN_PARTITION))
+ tbl->s->connect_string= p_elem->connect_string;
if ((error= file->ha_create(part_name, tbl, create_info)))
{
/*
@@ -1872,7 +1893,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
in the partitions.
*/
- uint disable_non_uniq_indexes = indexes_are_disabled();
+ uint disable_non_uniq_indexes= indexes_are_disabled();
i= 0;
part_count= 0;
@@ -2016,6 +2037,11 @@ int ha_partition::copy_partitions(ulonglong * const copied,
else
set_linear_hash_mask(m_part_info, m_part_info->num_subparts);
}
+ else if (m_part_info->part_type == VERSIONING_PARTITION)
+ {
+ if (m_part_info->check_constants(ha_thd(), m_part_info))
+ goto init_error;
+ }
while (reorg_part < m_reorged_parts)
{
@@ -2100,7 +2126,7 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
HA_STATUS_AUTO is optimized so it will not always be forwarded
to all partitions, but HA_STATUS_VARIABLE will.
*/
- info(HA_STATUS_VARIABLE);
+ info(HA_STATUS_VARIABLE | HA_STATUS_OPEN);
info(HA_STATUS_AUTO);
@@ -2111,10 +2137,11 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
DATA DIRECTORY and INDEX DIRECTORY are never applied to the whole
partitioned table, only its parts.
*/
- my_bool from_alter = (create_info->data_file_name == (const char*) -1);
- create_info->data_file_name= create_info->index_file_name = NULL;
+ my_bool from_alter= (create_info->data_file_name == (const char*) -1);
+ create_info->data_file_name= create_info->index_file_name= NULL;
- create_info->connect_string= null_clex_str;
+ if (!(m_file[0]->ht->flags & HTON_CAN_READ_CONNECT_STRING_IN_PARTITION))
+ create_info->connect_string= null_clex_str;
/*
We do not need to update the individual partition DATA DIRECTORY settings
@@ -2132,8 +2159,8 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
List_iterator<partition_element> part_it(m_part_info->partitions);
partition_element *part_elem, *sub_elem;
uint num_subparts= m_part_info->num_subparts;
- uint num_parts = num_subparts ? m_file_tot_parts / num_subparts
- : m_file_tot_parts;
+ uint num_parts= (num_subparts ? m_file_tot_parts / num_subparts :
+ m_file_tot_parts);
HA_CREATE_INFO dummy_info;
memset(&dummy_info, 0, sizeof(dummy_info));
@@ -2182,38 +2209,19 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
DBUG_ASSERT(sub_elem);
part= i * num_subparts + j;
DBUG_ASSERT(part < m_file_tot_parts && m_file[part]);
- if (ha_legacy_type(m_file[part]->ht) == DB_TYPE_INNODB)
- {
- dummy_info.data_file_name= dummy_info.index_file_name = NULL;
- m_file[part]->update_create_info(&dummy_info);
-
- if (dummy_info.data_file_name || sub_elem->data_file_name)
- {
- sub_elem->data_file_name = (char*) dummy_info.data_file_name;
- }
- if (dummy_info.index_file_name || sub_elem->index_file_name)
- {
- sub_elem->index_file_name = (char*) dummy_info.index_file_name;
- }
- }
+ dummy_info.data_file_name= dummy_info.index_file_name = NULL;
+ m_file[part]->update_create_info(&dummy_info);
+ sub_elem->data_file_name = (char*) dummy_info.data_file_name;
+ sub_elem->index_file_name = (char*) dummy_info.index_file_name;
}
}
else
{
DBUG_ASSERT(m_file[i]);
- if (ha_legacy_type(m_file[i]->ht) == DB_TYPE_INNODB)
- {
- dummy_info.data_file_name= dummy_info.index_file_name= NULL;
- m_file[i]->update_create_info(&dummy_info);
- if (dummy_info.data_file_name || part_elem->data_file_name)
- {
- part_elem->data_file_name = (char*) dummy_info.data_file_name;
- }
- if (dummy_info.index_file_name || part_elem->index_file_name)
- {
- part_elem->index_file_name = (char*) dummy_info.index_file_name;
- }
- }
+ dummy_info.data_file_name= dummy_info.index_file_name= NULL;
+ m_file[i]->update_create_info(&dummy_info);
+ part_elem->data_file_name = (char*) dummy_info.data_file_name;
+ part_elem->index_file_name = (char*) dummy_info.index_file_name;
}
}
DBUG_VOID_RETURN;
@@ -2268,7 +2276,7 @@ void ha_partition::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
comment Original comment
RETURN VALUE
- new comment
+ new comment
DESCRIPTION
No comment changes so far
@@ -2395,7 +2403,7 @@ uint ha_partition::count_query_cache_dependant_tables(uint8 *tables_type)
/* Here we rely on the fact that all tables are of the same type */
uint8 type= m_file[0]->table_cache_type();
(*tables_type)|= type;
- DBUG_PRINT("info", ("cnt: %u", (uint)m_tot_parts));
+ DBUG_PRINT("enter", ("cnt: %u", (uint) m_tot_parts));
/*
We need save underlying tables only for HA_CACHE_TBL_ASKTRANSACT:
HA_CACHE_TBL_NONTRANSACT - because all changes goes through partition table
@@ -2436,7 +2444,7 @@ reg_query_cache_dependant_table(THD *thd,
(++(*block_table))->n= ++(*n);
if (!cache->insert_table(thd, cache_key_len,
cache_key, (*block_table),
- table_share->db.length,
+ (uint32) table_share->db.length,
(uint8) (cache_key_len -
table_share->table_cache_key.length),
type,
@@ -2550,7 +2558,7 @@ register_query_cache_dependant_tables(THD *thd,
@return status
@retval TRUE Error
@retval FALSE Success
-
+
@details
Set up
1) Comment on partition
@@ -2560,12 +2568,12 @@ register_query_cache_dependant_tables(THD *thd,
*/
int ha_partition::set_up_table_before_create(TABLE *tbl,
- const char *partition_name_with_path,
+ const char *partition_name_with_path,
HA_CREATE_INFO *info,
partition_element *part_elem)
{
int error= 0;
- const char *partition_name;
+ LEX_CSTRING part_name;
THD *thd= ha_thd();
DBUG_ENTER("set_up_table_before_create");
@@ -2575,15 +2583,16 @@ int ha_partition::set_up_table_before_create(TABLE *tbl,
DBUG_RETURN(1);
tbl->s->max_rows= part_elem->part_max_rows;
tbl->s->min_rows= part_elem->part_min_rows;
- partition_name= strrchr(partition_name_with_path, FN_LIBCHAR);
+ part_name.str= strrchr(partition_name_with_path, FN_LIBCHAR)+1;
+ part_name.length= strlen(part_name.str);
if ((part_elem->index_file_name &&
(error= append_file_to_dir(thd,
(const char**)&part_elem->index_file_name,
- partition_name+1))) ||
+ &part_name))) ||
(part_elem->data_file_name &&
(error= append_file_to_dir(thd,
(const char**)&part_elem->data_file_name,
- partition_name+1))))
+ &part_name))))
{
DBUG_RETURN(error);
}
@@ -2640,10 +2649,10 @@ static uint name_add(char *dest, const char *first_name, const char *sec_name)
bool ha_partition::create_handler_file(const char *name)
{
partition_element *part_elem, *subpart_elem;
- uint i, j, part_name_len, subpart_name_len;
- uint tot_partition_words, tot_name_len, num_parts;
- uint tot_parts= 0;
- uint tot_len_words, tot_len_byte, chksum, tot_name_words;
+ size_t i, j, part_name_len, subpart_name_len;
+ size_t tot_partition_words, tot_name_len, num_parts;
+ size_t tot_parts= 0;
+ size_t tot_len_words, tot_len_byte, chksum, tot_name_words;
char *name_buffer_ptr;
uchar *file_buffer, *engine_array;
bool result= TRUE;
@@ -2655,8 +2664,7 @@ bool ha_partition::create_handler_file(const char *name)
DBUG_ENTER("create_handler_file");
num_parts= m_part_info->partitions.elements;
- DBUG_PRINT("info", ("table name = %s, num_parts = %u", name,
- num_parts));
+ DBUG_PRINT("enter", ("table name: %s num_parts: %zu", name, num_parts));
tot_name_len= 0;
for (i= 0; i < num_parts; i++)
{
@@ -2775,7 +2783,7 @@ bool ha_partition::create_handler_file(const char *name)
{
uchar buffer[4];
part_elem= part_it++;
- uint length = part_elem->connect_string.length;
+ size_t length= part_elem->connect_string.length;
int4store(buffer, length);
if (my_write(file, buffer, 4, MYF(MY_WME | MY_NABP)) ||
my_write(file, (uchar *) part_elem->connect_string.str, length,
@@ -2973,7 +2981,7 @@ bool ha_partition::read_par_file(const char *name)
if (chksum)
goto err2;
m_tot_parts= uint4korr((file_buffer) + PAR_NUM_PARTS_OFFSET);
- DBUG_PRINT("info", ("No of parts = %u", m_tot_parts));
+ DBUG_PRINT("info", ("No of parts: %u", m_tot_parts));
tot_partition_words= (m_tot_parts + PAR_WORD_SIZE - 1) / PAR_WORD_SIZE;
tot_name_len_offset= file_buffer + PAR_ENGINES_OFFSET +
@@ -3079,7 +3087,7 @@ bool ha_partition::setup_engine_array(MEM_ROOT *mem_root)
}
my_afree(engine_array);
-
+
if (create_handlers(mem_root))
{
clear_handler_file();
@@ -3166,7 +3174,7 @@ bool ha_partition::insert_partition_name_in_hash(const char *name, uint part_id,
{
PART_NAME_DEF *part_def;
uchar *part_name;
- uint part_name_length;
+ size_t part_name_length;
DBUG_ENTER("ha_partition::insert_partition_name_in_hash");
/*
Calculate and store the length here, to avoid doing it when
@@ -3186,7 +3194,7 @@ bool ha_partition::insert_partition_name_in_hash(const char *name, uint part_id,
DBUG_RETURN(true);
memcpy(part_name, name, part_name_length + 1);
part_def->partition_name= part_name;
- part_def->length= part_name_length;
+ part_def->length= (uint)part_name_length;
part_def->part_id= part_id;
part_def->is_subpart= is_subpart;
if (my_hash_insert(&part_share->partition_name_hash, (uchar *) part_def))
@@ -3361,63 +3369,59 @@ void ha_partition::free_partition_bitmaps()
my_bitmap_free(&m_locked_partitions);
my_bitmap_free(&m_partitions_to_reset);
my_bitmap_free(&m_key_not_found_partitions);
+ my_bitmap_free(&m_opened_partitions);
+ my_bitmap_free(&m_mrr_used_partitions);
}
/**
Helper function for initializing all internal bitmaps.
+
+ Note:
+ All bitmaps, including partially allocated, are freed in
+ free_partion_bitmaps()
*/
bool ha_partition::init_partition_bitmaps()
{
DBUG_ENTER("ha_partition::init_partition_bitmaps");
+
/* Initialize the bitmap we use to minimize ha_start_bulk_insert calls */
if (my_bitmap_init(&m_bulk_insert_started, NULL, m_tot_parts + 1, FALSE))
DBUG_RETURN(true);
- bitmap_clear_all(&m_bulk_insert_started);
/* Initialize the bitmap we use to keep track of locked partitions */
if (my_bitmap_init(&m_locked_partitions, NULL, m_tot_parts, FALSE))
- {
- my_bitmap_free(&m_bulk_insert_started);
DBUG_RETURN(true);
- }
- bitmap_clear_all(&m_locked_partitions);
/*
Initialize the bitmap we use to keep track of partitions which may have
something to reset in ha_reset().
*/
if (my_bitmap_init(&m_partitions_to_reset, NULL, m_tot_parts, FALSE))
- {
- my_bitmap_free(&m_bulk_insert_started);
- my_bitmap_free(&m_locked_partitions);
DBUG_RETURN(true);
- }
- bitmap_clear_all(&m_partitions_to_reset);
/*
Initialize the bitmap we use to keep track of partitions which returned
HA_ERR_KEY_NOT_FOUND from index_read_map.
*/
if (my_bitmap_init(&m_key_not_found_partitions, NULL, m_tot_parts, FALSE))
- {
- my_bitmap_free(&m_bulk_insert_started);
- my_bitmap_free(&m_locked_partitions);
- my_bitmap_free(&m_partitions_to_reset);
DBUG_RETURN(true);
- }
- bitmap_clear_all(&m_key_not_found_partitions);
- m_key_not_found= false;
+
+ if (bitmap_init(&m_mrr_used_partitions, NULL, m_tot_parts, TRUE))
+ DBUG_RETURN(true);
+
+ if (my_bitmap_init(&m_opened_partitions, NULL, m_tot_parts, FALSE))
+ DBUG_RETURN(true);
+
+ m_file_sample= NULL;
+
/* Initialize the bitmap for read/lock_partitions */
if (!m_is_clone_of)
{
DBUG_ASSERT(!m_clone_mem_root);
if (m_part_info->set_partition_bitmaps(NULL))
- {
- free_partition_bitmaps();
DBUG_RETURN(true);
- }
}
DBUG_RETURN(false);
}
@@ -3448,7 +3452,6 @@ bool ha_partition::init_partition_bitmaps()
int ha_partition::open(const char *name, int mode, uint test_if_locked)
{
- char *name_buffer_ptr;
int error= HA_ERR_INITIALIZATION;
handler **file;
char name_buff[FN_REFLEN + 1];
@@ -3462,7 +3465,6 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
m_part_field_array= m_part_info->full_part_field_array;
if (get_from_handler_file(name, &table->mem_root, MY_TEST(m_is_clone_of)))
DBUG_RETURN(error);
- name_buffer_ptr= m_name_buffer_ptr;
if (populate_partition_name_hash())
{
DBUG_RETURN(HA_ERR_INITIALIZATION);
@@ -3482,13 +3484,37 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
}
if (init_partition_bitmaps())
- DBUG_RETURN(error);
-
- DBUG_ASSERT(m_part_info);
+ goto err_alloc;
+
+ if ((error= m_part_info->set_partition_bitmaps(m_partitions_to_open)))
+ goto err_alloc;
+
+ /* Allocate memory used with MMR */
+ if (!(m_range_info= (void **)
+ my_multi_malloc(MYF(MY_WME),
+ &m_range_info, sizeof(range_id_t) * m_tot_parts,
+ &m_stock_range_seq, sizeof(uint) * m_tot_parts,
+ &m_mrr_buffer, sizeof(HANDLER_BUFFER) * m_tot_parts,
+ &m_mrr_buffer_size, sizeof(uint) * m_tot_parts,
+ &m_part_mrr_range_length, sizeof(uint) * m_tot_parts,
+ &m_part_mrr_range_first,
+ sizeof(PARTITION_PART_KEY_MULTI_RANGE *) * m_tot_parts,
+ &m_part_mrr_range_current,
+ sizeof(PARTITION_PART_KEY_MULTI_RANGE *) * m_tot_parts,
+ &m_partition_part_key_multi_range_hld,
+ sizeof(PARTITION_PART_KEY_MULTI_RANGE_HLD) *
+ m_tot_parts,
+ NullS)))
+ goto err_alloc;
+
+ bzero(m_mrr_buffer, m_tot_parts * sizeof(HANDLER_BUFFER));
+ bzero(m_part_mrr_range_first,
+ sizeof(PARTITION_PART_KEY_MULTI_RANGE *) * m_tot_parts);
if (m_is_clone_of)
{
uint i, alloc_len;
+ char *name_buffer_ptr;
DBUG_ASSERT(m_clone_mem_root);
/* Allocate an array of handler pointers for the partitions handlers. */
alloc_len= (m_tot_parts + 1) * sizeof(handler*);
@@ -3498,6 +3524,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
goto err_alloc;
}
memset(m_file, 0, alloc_len);
+ name_buffer_ptr= m_name_buffer_ptr;
/*
Populate them by cloning the original partitions. This also opens them.
Note that file->ref is allocated too.
@@ -3505,6 +3532,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= m_is_clone_of->m_file;
for (i= 0; i < m_tot_parts; i++)
{
+ if (!bitmap_is_set(&m_is_clone_of->m_opened_partitions, i))
+ continue;
+
if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
goto err_handler;
@@ -3515,36 +3545,35 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= &m_file[i];
goto err_handler;
}
+ if (!m_file_sample)
+ m_file_sample= m_file[i];
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
+ bitmap_set_bit(&m_opened_partitions, i);
}
}
else
{
- file= m_file;
- do
- {
- if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
- name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
- goto err_handler;
- table->s->connect_string = m_connect_string[(uint)(file-m_file)];
- if ((error= (*file)->ha_open(table, name_buff, mode,
- test_if_locked | HA_OPEN_NO_PSI_CALL)))
- goto err_handler;
- bzero(&table->s->connect_string, sizeof(LEX_STRING));
- if (m_file == file)
- m_num_locks= (*file)->lock_count();
- DBUG_ASSERT(m_num_locks == (*file)->lock_count());
- name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
- } while (*(++file));
+ if ((error= open_read_partitions(name_buff, sizeof(name_buff))))
+ goto err_handler;
+ m_num_locks= m_file_sample->lock_count();
}
-
+ /*
+ We want to know the upper bound for locks, to allocate enough memory.
+ There is no performance lost if we simply return in lock_count() the
+ maximum number locks needed, only some minor over allocation of memory
+ in get_lock_data().
+ */
+ m_num_locks*= m_tot_parts;
+
file= m_file;
- ref_length= (*file)->ref_length;
- check_table_flags= (((*file)->ha_table_flags() &
+ ref_length= get_open_file_sample()->ref_length;
+ check_table_flags= ((get_open_file_sample()->ha_table_flags() &
~(PARTITION_DISABLED_TABLE_FLAGS)) |
(PARTITION_ENABLED_TABLE_FLAGS));
while (*(++file))
{
+ if (!bitmap_is_set(&m_opened_partitions, (uint)(file - m_file)))
+ continue;
/* MyISAM can have smaller ref_length for partitions with MAX_ROWS set */
set_if_bigger(ref_length, ((*file)->ref_length));
/*
@@ -3557,12 +3586,12 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
{
error= HA_ERR_INITIALIZATION;
/* set file to last handler, so all of them are closed */
- file = &m_file[m_tot_parts - 1];
+ file= &m_file[m_tot_parts - 1];
goto err_handler;
}
}
- key_used_on_scan= m_file[0]->key_used_on_scan;
- implicit_emptied= m_file[0]->implicit_emptied;
+ key_used_on_scan= get_open_file_sample()->key_used_on_scan;
+ implicit_emptied= get_open_file_sample()->implicit_emptied;
/*
Add 2 bytes for partition id in position ref length.
ref_length=max_in_all_partitions(ref_length) + PARTITION_BYTES_IN_POS
@@ -3588,15 +3617,21 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
m_part_info->part_expr->get_monotonicity_info();
else if (m_part_info->list_of_part_fields)
m_part_func_monotonicity_info= MONOTONIC_STRICT_INCREASING;
- info(HA_STATUS_VARIABLE | HA_STATUS_CONST);
+ info(HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_OPEN);
DBUG_RETURN(0);
err_handler:
DEBUG_SYNC(ha_thd(), "partition_open_error");
+ file= &m_file[m_tot_parts - 1];
while (file-- != m_file)
- (*file)->ha_close();
+ {
+ if (bitmap_is_set(&m_opened_partitions, (uint)(file - m_file)))
+ (*file)->ha_close();
+ }
err_alloc:
free_partition_bitmaps();
+ my_free(m_range_info);
+ m_range_info= 0;
DBUG_RETURN(error);
}
@@ -3674,7 +3709,7 @@ handler *ha_partition::clone(const char *name, MEM_ROOT *mem_root)
/*
Allocate new_handler->ref here because otherwise ha_open will allocate it
- on this->table->mem_root and we will not be able to reclaim that memory
+ on this->table->mem_root and we will not be able to reclaim that memory
when the clone handler object is destroyed.
*/
if (!(new_handler->ref= (uchar*) alloc_root(mem_root,
@@ -3716,20 +3751,69 @@ int ha_partition::close(void)
{
bool first= TRUE;
handler **file;
+ uint i;
+ st_partition_ft_info *tmp_ft_info;
DBUG_ENTER("ha_partition::close");
-
DBUG_ASSERT(table->s == table_share);
- destroy_record_priority_queue();
- free_partition_bitmaps();
DBUG_ASSERT(m_part_info);
+
+ destroy_record_priority_queue();
+
+ for (; ft_first ; ft_first= tmp_ft_info)
+ {
+ tmp_ft_info= ft_first->next;
+ my_free(ft_first);
+ }
+
+ /* Free active mrr_ranges */
+ for (i= 0; i < m_tot_parts; i++)
+ {
+ if (m_part_mrr_range_first[i])
+ {
+ PARTITION_PART_KEY_MULTI_RANGE *tmp_mrr_range_first=
+ m_part_mrr_range_first[i];
+ do
+ {
+ PARTITION_PART_KEY_MULTI_RANGE *tmp_mrr_range_current;
+ tmp_mrr_range_current= tmp_mrr_range_first;
+ tmp_mrr_range_first= tmp_mrr_range_first->next;
+ my_free(tmp_mrr_range_current);
+ } while (tmp_mrr_range_first);
+ }
+ }
+ if (m_mrr_range_first)
+ {
+ do
+ {
+ m_mrr_range_current= m_mrr_range_first;
+ m_mrr_range_first= m_mrr_range_first->next;
+ if (m_mrr_range_current->key[0])
+ my_free(m_mrr_range_current->key[0]);
+ if (m_mrr_range_current->key[1])
+ my_free(m_mrr_range_current->key[1]);
+ my_free(m_mrr_range_current);
+ } while (m_mrr_range_first);
+ }
+ my_free(m_range_info);
+ m_range_info= NULL; // Safety
+
+ if (m_mrr_full_buffer)
+ {
+ my_free(m_mrr_full_buffer);
+ m_mrr_full_buffer= NULL;
+ m_mrr_full_buffer_size= 0;
+ }
file= m_file;
repeat:
do
{
- (*file)->ha_close();
+ if (!first || bitmap_is_set(&m_opened_partitions, (uint)(file - m_file)))
+ (*file)->ha_close();
} while (*(++file));
+ free_partition_bitmaps();
+
if (first && m_added_file && m_added_file[0])
{
file= m_added_file;
@@ -3783,7 +3867,7 @@ repeat:
int ha_partition::external_lock(THD *thd, int lock_type)
{
- uint error;
+ int error;
uint i, first_used_partition;
MY_BITMAP *used_partitions;
DBUG_ENTER("ha_partition::external_lock");
@@ -3801,7 +3885,7 @@ int ha_partition::external_lock(THD *thd, int lock_type)
i < m_tot_parts;
i= bitmap_get_next_set(used_partitions, i))
{
- DBUG_PRINT("info", ("external_lock(thd, %d) part %d", lock_type, i));
+ DBUG_PRINT("info", ("external_lock(thd, %d) part %u", lock_type, i));
if ((error= m_file[i]->ha_external_lock(thd, lock_type)))
{
if (lock_type != F_UNLCK)
@@ -3830,8 +3914,13 @@ int ha_partition::external_lock(THD *thd, int lock_type)
(void) (*file)->ha_external_lock(thd, lock_type);
} while (*(++file));
}
- if (lock_type == F_WRLCK && m_part_info->part_expr)
- m_part_info->part_expr->walk(&Item::register_field_in_read_map, 1, 0);
+ if (lock_type == F_WRLCK)
+ {
+ if (m_part_info->part_expr)
+ m_part_info->part_expr->walk(&Item::register_field_in_read_map, 1, 0);
+ if (m_part_info->part_type == VERSIONING_PARTITION)
+ m_part_info->vers_set_hist_part(thd);
+ }
DBUG_RETURN(0);
err_handler:
@@ -3917,7 +4006,7 @@ THR_LOCK_DATA **ha_partition::store_lock(THD *thd,
i < m_tot_parts;
i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
{
- DBUG_PRINT("info", ("store lock %d iteration", i));
+ DBUG_PRINT("info", ("store lock %u iteration", i));
to= m_file[i]->store_lock(thd, to, lock_type);
}
}
@@ -3978,25 +4067,14 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
@returns Number of locks returned in call to store_lock
@desc
- Returns the number of store locks needed in call to store lock.
- We return number of partitions we will lock multiplied with number of
- locks needed by each partition. Assists the above functions in allocating
- sufficient space for lock structures.
+ Returns the maxinum possible number of store locks needed in call to
+ store lock.
*/
uint ha_partition::lock_count() const
{
DBUG_ENTER("ha_partition::lock_count");
- /*
- The caller want to know the upper bound, to allocate enough memory.
- There is no performance lost if we simply return maximum number locks
- needed, only some minor over allocation of memory in get_lock_data().
-
- Also notice that this may be called for another thread != table->in_use,
- when mysql_lock_abort_for_thread() is called. So this is more safe, then
- using number of partitions after pruning.
- */
- DBUG_RETURN(m_tot_parts * m_num_locks);
+ DBUG_RETURN(m_num_locks);
}
@@ -4075,7 +4153,7 @@ void ha_partition::try_semi_consistent_read(bool yes)
{
uint i;
DBUG_ENTER("ha_partition::try_semi_consistent_read");
-
+
i= bitmap_get_first_set(&(m_part_info->read_partitions));
DBUG_ASSERT(i != MY_BIT_NONE);
for (;
@@ -4140,7 +4218,7 @@ int ha_partition::write_row(uchar * buf)
sql_mode_t saved_sql_mode= thd->variables.sql_mode;
bool saved_auto_inc_field_not_null= table->auto_increment_field_not_null;
DBUG_ENTER("ha_partition::write_row");
- DBUG_ASSERT(buf == m_rec0);
+ DBUG_PRINT("enter", ("partition this: %p", this));
/*
If we have an auto_increment column and we are writing a changed row
@@ -4148,15 +4226,8 @@ int ha_partition::write_row(uchar * buf)
*/
if (have_auto_increment)
{
- if (!part_share->auto_inc_initialized &&
- !table_share->next_number_keypart)
- {
- /*
- If auto_increment in table_share is not initialized, start by
- initializing it.
- */
- info(HA_STATUS_AUTO);
- }
+ if (!table_share->next_number_keypart)
+ update_next_auto_inc_val();
error= update_auto_increment();
/*
@@ -4200,7 +4271,7 @@ int ha_partition::write_row(uchar * buf)
goto exit;
}
m_last_part= part_id;
- DBUG_PRINT("info", ("Insert in partition %d", part_id));
+ DBUG_PRINT("info", ("Insert in partition %u", part_id));
start_part_bulk_insert(thd, part_id);
tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
@@ -4208,6 +4279,7 @@ int ha_partition::write_row(uchar * buf)
if (have_auto_increment && !table->s->next_number_keypart)
set_auto_increment_if_higher(table->next_number_field);
reenable_binlog(thd);
+
exit:
thd->variables.sql_mode= saved_sql_mode;
table->auto_increment_field_not_null= saved_auto_inc_field_not_null;
@@ -4242,29 +4314,15 @@ exit:
int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
{
THD *thd= ha_thd();
- uint32 new_part_id, old_part_id;
+ uint32 new_part_id, old_part_id= m_last_part;
int error= 0;
- longlong func_value;
DBUG_ENTER("ha_partition::update_row");
m_err_rec= NULL;
// Need to read partition-related columns, to locate the row's partition:
DBUG_ASSERT(bitmap_is_subset(&m_part_info->full_part_field_set,
table->read_set));
- if ((error= get_parts_for_update(old_data, new_data, table->record[0],
- m_part_info, &old_part_id, &new_part_id,
- &func_value)))
- {
- m_part_info->err_value= func_value;
- goto exit;
- }
- DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), old_part_id));
- if (!bitmap_is_set(&(m_part_info->lock_partitions), new_part_id))
- {
- error= HA_ERR_NOT_IN_LOCK_PARTITIONS;
- goto exit;
- }
-
+#ifndef DBUG_OFF
/*
The protocol for updating a row is:
1) position the handler (cursor) on the row to be updated,
@@ -4282,17 +4340,26 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
Notice that HA_READ_BEFORE_WRITE_REMOVAL does not require this protocol,
so this is not supported for this engine.
*/
- if (old_part_id != m_last_part)
+ error= get_part_for_buf(old_data, m_rec0, m_part_info, &old_part_id);
+ DBUG_ASSERT(!error);
+ DBUG_ASSERT(old_part_id == m_last_part);
+ DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), old_part_id));
+#endif
+
+ if ((error= get_part_for_buf(new_data, m_rec0, m_part_info, &new_part_id)))
+ goto exit;
+ if (!bitmap_is_set(&(m_part_info->lock_partitions), new_part_id))
{
- m_err_rec= old_data;
- DBUG_RETURN(HA_ERR_ROW_IN_WRONG_PARTITION);
+ error= HA_ERR_NOT_IN_LOCK_PARTITIONS;
+ goto exit;
}
+
m_last_part= new_part_id;
start_part_bulk_insert(thd, new_part_id);
if (new_part_id == old_part_id)
{
- DBUG_PRINT("info", ("Update in partition %d", new_part_id));
+ DBUG_PRINT("info", ("Update in partition %u", (uint) new_part_id));
tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
error= m_file[new_part_id]->ha_update_row(old_data, new_data);
reenable_binlog(thd);
@@ -4312,8 +4379,8 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
This gives the same behavior for partitioned vs non partitioned tables.
*/
table->next_number_field= NULL;
- DBUG_PRINT("info", ("Update from partition %d to partition %d",
- old_part_id, new_part_id));
+ DBUG_PRINT("info", ("Update from partition %u to partition %u",
+ (uint) old_part_id, (uint) new_part_id));
tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
error= m_file[new_part_id]->ha_write_row((uchar*) new_data);
reenable_binlog(thd);
@@ -4325,12 +4392,7 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
error= m_file[old_part_id]->ha_delete_row(old_data);
reenable_binlog(thd);
if (error)
- {
-#ifdef IN_THE_FUTURE
- (void) m_file[new_part_id]->delete_last_inserted_row(new_data);
-#endif
goto exit;
- }
}
exit:
@@ -4349,8 +4411,11 @@ exit:
bitmap_is_set(table->write_set,
table->found_next_number_field->field_index))
{
- if (!part_share->auto_inc_initialized)
- info(HA_STATUS_AUTO);
+ update_next_auto_inc_val();
+ /*
+ The following call is safe as part_share->auto_inc_initialized
+ (tested in the call) is guaranteed to be set for update statements.
+ */
set_auto_increment_if_higher(table->found_next_number_field);
}
DBUG_RETURN(error);
@@ -4387,7 +4452,6 @@ exit:
int ha_partition::delete_row(const uchar *buf)
{
- uint32 part_id;
int error;
THD *thd= ha_thd();
DBUG_ENTER("ha_partition::delete_row");
@@ -4395,16 +4459,7 @@ int ha_partition::delete_row(const uchar *buf)
DBUG_ASSERT(bitmap_is_subset(&m_part_info->full_part_field_set,
table->read_set));
- if ((error= get_part_for_delete(buf, m_rec0, m_part_info, &part_id)))
- {
- DBUG_RETURN(error);
- }
- /* Should never call delete_row on a partition which is not read */
- DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), part_id));
- DBUG_ASSERT(bitmap_is_set(&(m_part_info->lock_partitions), part_id));
- if (!bitmap_is_set(&(m_part_info->lock_partitions), part_id))
- DBUG_RETURN(HA_ERR_NOT_IN_LOCK_PARTITIONS);
-
+#ifndef DBUG_OFF
/*
The protocol for deleting a row is:
1) position the handler (cursor) on the row to be deleted,
@@ -4422,18 +4477,26 @@ int ha_partition::delete_row(const uchar *buf)
Notice that HA_READ_BEFORE_WRITE_REMOVAL does not require this protocol,
so this is not supported for this engine.
- TODO: change the assert in InnoDB into an error instead and make this one
- an assert instead and remove the get_part_for_delete()!
+ For partitions by system_time, get_part_for_buf() is always either current
+ or last historical partition, but DELETE HISTORY can delete from any
+ historical partition. So, skip the check in this case.
*/
- if (part_id != m_last_part)
+ if (!thd->lex->vers_conditions) // if not DELETE HISTORY
{
- m_err_rec= buf;
- DBUG_RETURN(HA_ERR_ROW_IN_WRONG_PARTITION);
+ uint32 part_id;
+ error= get_part_for_buf(buf, m_rec0, m_part_info, &part_id);
+ DBUG_ASSERT(!error);
+ DBUG_ASSERT(part_id == m_last_part);
}
+ DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), m_last_part));
+ DBUG_ASSERT(bitmap_is_set(&(m_part_info->lock_partitions), m_last_part));
+#endif
+
+ if (!bitmap_is_set(&(m_part_info->lock_partitions), m_last_part))
+ DBUG_RETURN(HA_ERR_NOT_IN_LOCK_PARTITIONS);
- m_last_part= part_id;
tmp_disable_binlog(thd);
- error= m_file[part_id]->ha_delete_row(buf);
+ error= m_file[m_last_part]->ha_delete_row(buf);
reenable_binlog(thd);
DBUG_RETURN(error);
}
@@ -4637,9 +4700,9 @@ void ha_partition::start_part_bulk_insert(THD *thd, uint part_id)
DESCRIPTION
If the estimated number of rows to insert is less than 10 (but not 0)
the new buffer size is same as original buffer size.
- In case of first partition of when partition function is monotonic
+ In case of first partition of when partition function is monotonic
new buffer size is same as the original buffer size.
- For rest of the partition total buffer of 10*original_size is divided
+ For rest of the partition total buffer of 10*original_size is divided
equally if number of partition is more than 10 other wise each partition
will be allowed to use original buffer size.
*/
@@ -4677,7 +4740,7 @@ long ha_partition::estimate_read_buffer_size(long original_size)
If monotonic partitioning function was used
guess that 50 % of the inserts goes to the first partition
For all other cases, guess on equal distribution between the partitions
-*/
+*/
ha_rows ha_partition::guess_bulk_insert_rows()
{
DBUG_ENTER("guess_bulk_insert_rows");
@@ -4686,7 +4749,7 @@ ha_rows ha_partition::guess_bulk_insert_rows()
DBUG_RETURN(estimation_rows_to_insert);
/* If first insert/partition and monotonic partition function, guess 50%. */
- if (!m_bulk_inserted_rows &&
+ if (!m_bulk_inserted_rows &&
m_part_func_monotonicity_info != NON_MONOTONIC &&
m_tot_parts > 1)
DBUG_RETURN(estimation_rows_to_insert / 2);
@@ -4752,7 +4815,7 @@ int ha_partition::end_bulk_insert()
>0 Error code
0 Success
- DESCRIPTION
+ DESCRIPTION
rnd_init() is called when the server wants the storage engine to do a
table scan or when the server wants to access data through rnd_pos.
@@ -4788,7 +4851,10 @@ int ha_partition::rnd_init(bool scan)
*/
if (bitmap_is_overlapping(&m_part_info->full_part_field_set,
table->write_set))
+ {
+ DBUG_PRINT("info", ("partition set full bitmap"));
bitmap_set_all(table->read_set);
+ }
else
{
/*
@@ -4797,6 +4863,7 @@ int ha_partition::rnd_init(bool scan)
fields of the partition functions are read such that we can
calculate the partition id to place updated and deleted records.
*/
+ DBUG_PRINT("info", ("partition set part_field bitmap"));
bitmap_union(table->read_set, &m_part_info->full_part_field_set);
}
}
@@ -4805,9 +4872,9 @@ int ha_partition::rnd_init(bool scan)
DBUG_PRINT("info", ("m_part_info->read_partitions: %p",
m_part_info->read_partitions.bitmap));
part_id= bitmap_get_first_set(&(m_part_info->read_partitions));
- DBUG_PRINT("info", ("m_part_spec.start_part %d", part_id));
+ DBUG_PRINT("info", ("m_part_spec.start_part: %u", (uint) part_id));
- if (MY_BIT_NONE == part_id)
+ if (part_id == MY_BIT_NONE)
{
error= 0;
goto err1;
@@ -4817,7 +4884,7 @@ int ha_partition::rnd_init(bool scan)
We have a partition and we are scanning with rnd_next
so we bump our cache
*/
- DBUG_PRINT("info", ("rnd_init on partition %d", part_id));
+ DBUG_PRINT("info", ("rnd_init on partition: %u", (uint) part_id));
if (scan)
{
/*
@@ -4826,26 +4893,29 @@ int ha_partition::rnd_init(bool scan)
*/
rnd_end();
late_extra_cache(part_id);
- if ((error= m_file[part_id]->ha_rnd_init(scan)))
- goto err;
+
+ m_index_scan_type= partition_no_index_scan;
}
- else
+
+ for (i= part_id;
+ i < m_tot_parts;
+ i= bitmap_get_next_set(&m_part_info->read_partitions, i))
{
- for (i= part_id;
- i < m_tot_parts;
- i= bitmap_get_next_set(&m_part_info->read_partitions, i))
- {
- if ((error= m_file[i]->ha_rnd_init(scan)))
- goto err;
- }
+ if ((error= m_file[i]->ha_rnd_init(scan)))
+ goto err;
}
+
m_scan_value= scan;
m_part_spec.start_part= part_id;
m_part_spec.end_part= m_tot_parts - 1;
- DBUG_PRINT("info", ("m_scan_value=%d", m_scan_value));
+ m_rnd_init_and_first= TRUE;
+ DBUG_PRINT("info", ("m_scan_value: %u", m_scan_value));
DBUG_RETURN(0);
err:
+ if (scan)
+ late_extra_no_cache(part_id);
+
/* Call rnd_end for all previously inited partitions. */
for (;
part_id < i;
@@ -4877,13 +4947,10 @@ int ha_partition::rnd_end()
switch (m_scan_value) {
case 2: // Error
break;
- case 1:
- if (NO_CURRENT_PART_ID != m_part_spec.start_part) // Table scan
- {
+ case 1: // Table scan
+ if (m_part_spec.start_part != NO_CURRENT_PART_ID)
late_extra_no_cache(m_part_spec.start_part);
- m_file[m_part_spec.start_part]->ha_rnd_end();
- }
- break;
+ /* fall through */
case 0:
uint i;
for (i= bitmap_get_first_set(&m_part_info->read_partitions);
@@ -4899,6 +4966,7 @@ int ha_partition::rnd_end()
DBUG_RETURN(0);
}
+
/*
read next row during full table scan (scan in random row order)
@@ -4923,14 +4991,15 @@ int ha_partition::rnd_end()
int ha_partition::rnd_next(uchar *buf)
{
handler *file;
- int result= HA_ERR_END_OF_FILE;
+ int result= HA_ERR_END_OF_FILE, error;
uint part_id= m_part_spec.start_part;
DBUG_ENTER("ha_partition::rnd_next");
+ DBUG_PRINT("enter", ("partition this: %p", this));
/* upper level will increment this once again at end of call */
decrement_statistics(&SSV::ha_read_rnd_next_count);
- if (NO_CURRENT_PART_ID == part_id)
+ if (part_id == NO_CURRENT_PART_ID)
{
/*
The original set of partitions to scan was empty and thus we report
@@ -4938,16 +5007,26 @@ int ha_partition::rnd_next(uchar *buf)
*/
goto end;
}
-
+
DBUG_ASSERT(m_scan_value == 1);
+
+ if (m_rnd_init_and_first)
+ {
+ m_rnd_init_and_first= FALSE;
+ error= handle_pre_scan(FALSE, check_parallel_search());
+ if (m_pre_calling || error)
+ DBUG_RETURN(error);
+ }
+
file= m_file[part_id];
-
+
while (TRUE)
{
result= file->ha_rnd_next(buf);
if (!result)
{
m_last_part= part_id;
+ DBUG_PRINT("info", ("partition m_last_part: %u", (uint) m_last_part));
m_part_spec.start_part= part_id;
table->status= 0;
DBUG_RETURN(0);
@@ -4964,10 +5043,6 @@ int ha_partition::rnd_next(uchar *buf)
/* End current partition */
late_extra_no_cache(part_id);
- DBUG_PRINT("info", ("rnd_end on partition %d", part_id));
- if ((result= file->ha_rnd_end()))
- break;
-
/* Shift to next partition */
part_id= bitmap_get_next_set(&m_part_info->read_partitions, part_id);
if (part_id >= m_tot_parts)
@@ -4976,15 +5051,14 @@ int ha_partition::rnd_next(uchar *buf)
break;
}
m_last_part= part_id;
+ DBUG_PRINT("info", ("partition m_last_part: %u", (uint) m_last_part));
m_part_spec.start_part= part_id;
file= m_file[part_id];
- DBUG_PRINT("info", ("rnd_init on partition %d", part_id));
- if ((result= file->ha_rnd_init(1)))
- break;
late_extra_cache(part_id);
}
end:
+ DBUG_PRINT("exit", ("reset start_part"));
m_part_spec.start_part= NO_CURRENT_PART_ID;
end_dont_reset_start_part:
DBUG_RETURN(result);
@@ -5019,7 +5093,7 @@ end_dont_reset_start_part:
void ha_partition::position(const uchar *record)
{
handler *file= m_file[m_last_part];
- uint pad_length;
+ size_t pad_length;
DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), m_last_part));
DBUG_ENTER("ha_partition::position");
@@ -5094,7 +5168,7 @@ int ha_partition::rnd_pos_by_record(uchar *record)
{
DBUG_ENTER("ha_partition::rnd_pos_by_record");
- if (unlikely(get_part_for_delete(record, m_rec0, m_part_info, &m_last_part)))
+ if (unlikely(get_part_for_buf(record, m_rec0, m_part_info, &m_last_part)))
DBUG_RETURN(1);
DBUG_RETURN(handler::rnd_pos_by_record(record));
@@ -5134,12 +5208,13 @@ bool ha_partition::init_record_priority_queue()
*/
if (!m_ordered_rec_buffer)
{
- uint alloc_len;
+ size_t alloc_len;
uint used_parts= bitmap_bits_set(&m_part_info->read_partitions);
+ DBUG_ASSERT(used_parts > 0);
/* Allocate record buffer for each used partition. */
m_priority_queue_rec_len= m_rec_length + PARTITION_BYTES_IN_POS;
if (!m_using_extended_keys)
- m_priority_queue_rec_len += m_file[0]->ref_length;
+ m_priority_queue_rec_len += get_open_file_sample()->ref_length;
alloc_len= used_parts * m_priority_queue_rec_len;
/* Allocate a key for temporary use when setting up the scan. */
alloc_len+= table_share->max_key_length;
@@ -5165,20 +5240,15 @@ bool ha_partition::init_record_priority_queue()
ptr+= m_priority_queue_rec_len;
}
m_start_key.key= (const uchar*)ptr;
-
+
/* Initialize priority queue, initialized to reading forward. */
int (*cmp_func)(void *, uchar *, uchar *);
- void *cmp_arg;
- if (!m_using_extended_keys)
- {
+ void *cmp_arg= (void*) this;
+ if (!m_using_extended_keys && !(table_flags() & HA_CMP_REF_IS_EXPENSIVE))
cmp_func= cmp_key_rowid_part_id;
- cmp_arg= (void*)this;
- }
else
- {
cmp_func= cmp_key_part_id;
- cmp_arg= (void*)m_curr_key_info;
- }
+ DBUG_PRINT("info", ("partition queue_init(1) used_parts: %u", used_parts));
if (init_queue(&m_queue, used_parts, 0, 0, cmp_func, cmp_arg, 0, 0))
{
my_free(m_ordered_rec_buffer);
@@ -5229,8 +5299,8 @@ int ha_partition::index_init(uint inx, bool sorted)
int error= 0;
uint i;
DBUG_ENTER("ha_partition::index_init");
+ DBUG_PRINT("enter", ("partition this: %p inx: %u sorted: %u", this, inx, sorted));
- DBUG_PRINT("info", ("inx %u sorted %u", inx, sorted));
active_index= inx;
m_part_spec.start_part= NO_CURRENT_PART_ID;
m_start_key.length= 0;
@@ -5265,11 +5335,14 @@ int ha_partition::index_init(uint inx, bool sorted)
But this is required for operations that may need to change data only.
*/
if (get_lock_type() == F_WRLCK)
+ {
+ DBUG_PRINT("info", ("partition set part_field bitmap"));
bitmap_union(table->read_set, &m_part_info->full_part_field_set);
+ }
if (sorted)
{
/*
- An ordered scan is requested. We must make sure all fields of the
+ An ordered scan is requested. We must make sure all fields of the
used index are in the read set, as partitioning requires them for
sorting (see ha_partition::handle_ordered_index_scan).
@@ -5336,19 +5409,21 @@ err:
int ha_partition::index_end()
{
int error= 0;
- uint i;
+ handler **file;
DBUG_ENTER("ha_partition::index_end");
active_index= MAX_KEY;
m_part_spec.start_part= NO_CURRENT_PART_ID;
- for (i= bitmap_get_first_set(&m_part_info->read_partitions);
- i < m_tot_parts;
- i= bitmap_get_next_set(&m_part_info->read_partitions, i))
+ file= m_file;
+ do
{
- int tmp;
- if ((tmp= m_file[i]->ha_index_end()))
- error= tmp;
- }
+ if ((*file)->inited == INDEX)
+ {
+ int tmp;
+ if ((tmp= (*file)->ha_index_end()))
+ error= tmp;
+ }
+ } while (*(++file));
destroy_record_priority_queue();
DBUG_RETURN(error);
}
@@ -5397,34 +5472,26 @@ int ha_partition::index_read_map(uchar *buf, const uchar *key,
/* Compare two part_no partition numbers */
static int cmp_part_ids(uchar *ref1, uchar *ref2)
{
- /* The following was taken from ha_partition::cmp_ref */
- my_ptrdiff_t diff1= ref2[1] - ref1[1];
- my_ptrdiff_t diff2= ref2[0] - ref1[0];
- if (!diff1 && !diff2)
- return 0;
-
- if (diff1 > 0)
- return(-1);
-
- if (diff1 < 0)
- return(+1);
-
- if (diff2 > 0)
- return(-1);
-
- return(+1);
+ uint32 diff2= uint2korr(ref2);
+ uint32 diff1= uint2korr(ref1);
+ if (diff2 > diff1)
+ return -1;
+ if (diff2 < diff1)
+ return 1;
+ return 0;
}
/*
@brief
- Provide ordering by (key_value, part_no).
+ Provide ordering by (key_value, part_no).
*/
-extern "C" int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2)
+extern "C" int cmp_key_part_id(void *ptr, uchar *ref1, uchar *ref2)
{
+ ha_partition *file= (ha_partition*)ptr;
int res;
- if ((res= key_rec_cmp(key_p, ref1 + PARTITION_BYTES_IN_POS,
+ if ((res= key_rec_cmp(file->m_curr_key_info, ref1 + PARTITION_BYTES_IN_POS,
ref2 + PARTITION_BYTES_IN_POS)))
{
return res;
@@ -5434,7 +5501,7 @@ extern "C" int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2)
/*
@brief
- Provide ordering by (key_value, underying_table_rowid, part_no).
+ Provide ordering by (key_value, underying_table_rowid, part_no).
*/
extern "C" int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2)
{
@@ -5459,26 +5526,26 @@ extern "C" int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2)
Common routine for a number of index_read variants
@param buf Buffer where the record should be returned.
- @param have_start_key TRUE <=> the left endpoint is available, i.e.
+ @param have_start_key TRUE <=> the left endpoint is available, i.e.
we're in index_read call or in read_range_first
call and the range has left endpoint.
FALSE <=> there is no left endpoint (we're in
read_range_first() call and the range has no left
endpoint).
-
+
@return Operation status
- @retval 0 OK
+ @retval 0 OK
@retval HA_ERR_END_OF_FILE Whole index scanned, without finding the record.
@retval HA_ERR_KEY_NOT_FOUND Record not found, but index cursor positioned.
@retval other error code.
@details
- Start scanning the range (when invoked from read_range_first()) or doing
+ Start scanning the range (when invoked from read_range_first()) or doing
an index lookup (when invoked from index_read_XXX):
- If possible, perform partition selection
- Find the set of partitions we're going to use
- Depending on whether we need ordering:
- NO: Get the first record from first used partition (see
+ NO: Get the first record from first used partition (see
handle_unordered_scan_next_partition)
YES: Fill the priority queue and get the record that is the first in
the ordering
@@ -5496,7 +5563,7 @@ int ha_partition::common_index_read(uchar *buf, bool have_start_key)
if (have_start_key)
{
- m_start_key.length= key_len= calculate_key_len(table, active_index,
+ m_start_key.length= key_len= calculate_key_len(table, active_index,
m_start_key.key,
m_start_key.keypart_map);
DBUG_PRINT("info", ("have_start_key map %lu find_flag %u len %u",
@@ -5508,7 +5575,7 @@ int ha_partition::common_index_read(uchar *buf, bool have_start_key)
DBUG_RETURN(error);
}
- if (have_start_key &&
+ if (have_start_key &&
(m_start_key.flag == HA_READ_PREFIX_LAST ||
m_start_key.flag == HA_READ_PREFIX_LAST_OR_PREV ||
m_start_key.flag == HA_READ_BEFORE_KEY))
@@ -5528,7 +5595,9 @@ int ha_partition::common_index_read(uchar *buf, bool have_start_key)
The unordered index scan will use the partition set created.
*/
DBUG_PRINT("info", ("doing unordered scan"));
- error= handle_unordered_scan_next_partition(buf);
+ error= handle_pre_scan(FALSE, FALSE);
+ if (!error)
+ error= handle_unordered_scan_next_partition(buf);
}
else
{
@@ -5576,7 +5645,7 @@ int ha_partition::index_first(uchar * buf)
/*
Start an index scan from rightmost record and return first record
-
+
SYNOPSIS
index_last()
buf Read row in MySQL Row Format
@@ -5609,7 +5678,7 @@ int ha_partition::index_last(uchar * buf)
SYNOPSIS
ha_partition::common_first_last()
-
+
see index_first for rest
*/
@@ -5621,7 +5690,11 @@ int ha_partition::common_first_last(uchar *buf)
return error;
if (!m_ordered_scan_ongoing &&
m_index_scan_type != partition_index_last)
- return handle_unordered_scan_next_partition(buf);
+ {
+ if ((error= handle_pre_scan(FALSE, check_parallel_search())))
+ return error;
+ return handle_unordered_scan_next_partition(buf);
+ }
return handle_ordered_index_scan(buf, FALSE);
}
@@ -5649,7 +5722,7 @@ int ha_partition::index_read_idx_map(uchar *buf, uint index,
get_partition_set(table, buf, index, &m_start_key, &m_part_spec);
- /*
+ /*
We have either found exactly 1 partition
(in which case start_part == end_part)
or no matching partitions (start_part > end_part)
@@ -5714,7 +5787,8 @@ int ha_partition::index_next(uchar * buf)
and if direction changes, we must step back those partitions in
the record queue so we don't return a value from the wrong direction.
*/
- DBUG_ASSERT(m_index_scan_type != partition_index_last);
+ if (m_index_scan_type == partition_index_last)
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
if (!m_ordered_scan_ongoing)
{
DBUG_RETURN(handle_unordered_next(buf, FALSE));
@@ -5747,13 +5821,30 @@ int ha_partition::index_next_same(uchar *buf, const uchar *key, uint keylen)
decrement_statistics(&SSV::ha_read_next_count);
DBUG_ASSERT(keylen == m_start_key.length);
- DBUG_ASSERT(m_index_scan_type != partition_index_last);
+ if (m_index_scan_type == partition_index_last)
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
if (!m_ordered_scan_ongoing)
DBUG_RETURN(handle_unordered_next(buf, TRUE));
DBUG_RETURN(handle_ordered_next(buf, TRUE));
}
+int ha_partition::index_read_last_map(uchar *buf,
+ const uchar *key,
+ key_part_map keypart_map)
+{
+ DBUG_ENTER("ha_partition::index_read_last_map");
+
+ m_ordered= true; // Safety measure
+ end_range= NULL;
+ m_index_scan_type= partition_index_read_last;
+ m_start_key.key= key;
+ m_start_key.keypart_map= keypart_map;
+ m_start_key.flag= HA_READ_PREFIX_LAST;
+ DBUG_RETURN(common_index_read(buf, true));
+}
+
+
/*
Read next record when performing index scan backwards
@@ -5775,7 +5866,8 @@ int ha_partition::index_prev(uchar * buf)
decrement_statistics(&SSV::ha_read_prev_count);
/* TODO: read comment in index_next */
- DBUG_ASSERT(m_index_scan_type != partition_index_first);
+ if (m_index_scan_type == partition_index_first)
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
DBUG_RETURN(handle_ordered_prev(buf));
}
@@ -5846,6 +5938,989 @@ int ha_partition::read_range_next()
DBUG_RETURN(handle_unordered_next(table->record[0], eq_range));
}
+/**
+ Create a copy of all keys used by multi_range_read()
+
+ @retval 0 ok
+ @retval HA_ERR_END_OF_FILE no keys in range
+ @retval other value: error
+
+ TODO to save memory:
+ - If (mrr_mode & HA_MRR_MATERIALIZED_KEYS) is set then the keys data is
+ stable and we don't have to copy the keys, only store a pointer to the
+ key.
+ - When allocating key data, store things in a MEM_ROOT buffer instead of
+ a malloc() per key. This will simplify and speed up the current code
+ and use less memory.
+*/
+
+int ha_partition::multi_range_key_create_key(RANGE_SEQ_IF *seq,
+ range_seq_t seq_it)
+{
+ uint i, length;
+ key_range *start_key, *end_key;
+ KEY_MULTI_RANGE *range;
+ DBUG_ENTER("ha_partition::multi_range_key_create_key");
+
+ bitmap_clear_all(&m_mrr_used_partitions);
+ m_mrr_range_length= 0;
+ bzero(m_part_mrr_range_length,
+ sizeof(*m_part_mrr_range_length) * m_tot_parts);
+ if (!m_mrr_range_first)
+ {
+ if (!(m_mrr_range_first= (PARTITION_KEY_MULTI_RANGE *)
+ my_multi_malloc(MYF(MY_WME),
+ &m_mrr_range_current,
+ sizeof(PARTITION_KEY_MULTI_RANGE),
+ NullS)))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+
+ m_mrr_range_first->id= 1;
+ m_mrr_range_first->key[0]= NULL;
+ m_mrr_range_first->key[1]= NULL;
+ m_mrr_range_first->next= NULL;
+ }
+ else
+ m_mrr_range_current= m_mrr_range_first;
+
+ for (i= 0; i < m_tot_parts; i++)
+ {
+ if (!m_part_mrr_range_first[i])
+ {
+ if (!(m_part_mrr_range_first[i]= (PARTITION_PART_KEY_MULTI_RANGE *)
+ my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+ &m_part_mrr_range_current[i],
+ sizeof(PARTITION_PART_KEY_MULTI_RANGE),
+ NullS)))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ else
+ {
+ m_part_mrr_range_current[i]= m_part_mrr_range_first[i];
+ m_part_mrr_range_current[i]->partition_key_multi_range= NULL;
+ }
+ }
+ m_mrr_range_current->key_multi_range.start_key.key= NULL;
+ m_mrr_range_current->key_multi_range.end_key.key= NULL;
+
+ while (!seq->next(seq_it, &m_mrr_range_current->key_multi_range))
+ {
+ m_mrr_range_length++;
+ range= &m_mrr_range_current->key_multi_range;
+
+ /* Copy start key */
+ start_key= &range->start_key;
+ DBUG_PRINT("info",("partition range->range_flag: %u", range->range_flag));
+ DBUG_PRINT("info",("partition start_key->key: %p", start_key->key));
+ DBUG_PRINT("info",("partition start_key->length: %u", start_key->length));
+ DBUG_PRINT("info",("partition start_key->keypart_map: %lu",
+ start_key->keypart_map));
+ DBUG_PRINT("info",("partition start_key->flag: %u", start_key->flag));
+
+ if (start_key->key)
+ {
+ length= start_key->length;
+ if (!m_mrr_range_current->key[0] ||
+ m_mrr_range_current->length[0] < length)
+ {
+ if (m_mrr_range_current->key[0])
+ my_free(m_mrr_range_current->key[0]);
+ if (!(m_mrr_range_current->key[0]=
+ (uchar *) my_malloc(length, MYF(MY_WME))))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ m_mrr_range_current->length[0]= length;
+ }
+ memcpy(m_mrr_range_current->key[0], start_key->key, length);
+ start_key->key= m_mrr_range_current->key[0];
+ }
+
+ /* Copy end key */
+ end_key= &range->end_key;
+ DBUG_PRINT("info",("partition end_key->key: %p", end_key->key));
+ DBUG_PRINT("info",("partition end_key->length: %u", end_key->length));
+ DBUG_PRINT("info",("partition end_key->keypart_map: %lu",
+ end_key->keypart_map));
+ DBUG_PRINT("info",("partition end_key->flag: %u", end_key->flag));
+ if (end_key->key)
+ {
+ length= end_key->length;
+ if (!m_mrr_range_current->key[1] ||
+ m_mrr_range_current->length[1] < length)
+ {
+ if (m_mrr_range_current->key[1])
+ my_free(m_mrr_range_current->key[1]);
+ if (!(m_mrr_range_current->key[1]=
+ (uchar *) my_malloc(length, MYF(MY_WME))))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ m_mrr_range_current->length[1]= length;
+ }
+ memcpy(m_mrr_range_current->key[1], end_key->key, length);
+ end_key->key= m_mrr_range_current->key[1];
+ }
+
+ m_mrr_range_current->ptr= m_mrr_range_current->key_multi_range.ptr;
+ m_mrr_range_current->key_multi_range.ptr= m_mrr_range_current;
+
+ if (start_key->key && (start_key->flag & HA_READ_KEY_EXACT))
+ get_partition_set(table, table->record[0], active_index,
+ start_key, &m_part_spec);
+ else
+ {
+ m_part_spec.start_part= 0;
+ m_part_spec.end_part= m_tot_parts - 1;
+ }
+
+ /* Copy key to those partitions that needs it */
+ for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++)
+ {
+ if (bitmap_is_set(&(m_part_info->read_partitions), i))
+ {
+ bitmap_set_bit(&m_mrr_used_partitions, i);
+ m_part_mrr_range_length[i]++;
+ m_part_mrr_range_current[i]->partition_key_multi_range=
+ m_mrr_range_current;
+
+ if (!m_part_mrr_range_current[i]->next)
+ {
+ PARTITION_PART_KEY_MULTI_RANGE *tmp_part_mrr_range;
+ if (!(tmp_part_mrr_range= (PARTITION_PART_KEY_MULTI_RANGE *)
+ my_malloc(sizeof(PARTITION_PART_KEY_MULTI_RANGE),
+ MYF(MY_WME | MY_ZEROFILL))))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+
+ m_part_mrr_range_current[i]->next= tmp_part_mrr_range;
+ m_part_mrr_range_current[i]= tmp_part_mrr_range;
+ }
+ else
+ {
+ m_part_mrr_range_current[i]= m_part_mrr_range_current[i]->next;
+ m_part_mrr_range_current[i]->partition_key_multi_range= NULL;
+ }
+ }
+ }
+
+ if (!m_mrr_range_current->next)
+ {
+ /* Add end of range sentinel */
+ PARTITION_KEY_MULTI_RANGE *tmp_mrr_range;
+ if (!(tmp_mrr_range= (PARTITION_KEY_MULTI_RANGE *)
+ my_malloc(sizeof(PARTITION_KEY_MULTI_RANGE), MYF(MY_WME))))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+
+ tmp_mrr_range->id= m_mrr_range_current->id + 1;
+ tmp_mrr_range->key[0]= NULL;
+ tmp_mrr_range->key[1]= NULL;
+ tmp_mrr_range->next= NULL;
+ m_mrr_range_current->next= tmp_mrr_range;
+ }
+ m_mrr_range_current= m_mrr_range_current->next;
+ }
+
+ if (!m_mrr_range_length)
+ {
+ DBUG_PRINT("Warning",("No keys to use for mrr"));
+ DBUG_RETURN(HA_ERR_END_OF_FILE);
+ }
+
+ /* set start and end part */
+ m_part_spec.start_part= bitmap_get_first_set(&m_mrr_used_partitions);
+
+ for (i= m_tot_parts; i-- > 0;)
+ {
+ if (bitmap_is_set(&m_mrr_used_partitions, i))
+ {
+ m_part_spec.end_part= i;
+ break;
+ }
+ }
+ for (i= 0; i < m_tot_parts; i++)
+ {
+ m_partition_part_key_multi_range_hld[i].partition= this;
+ m_partition_part_key_multi_range_hld[i].part_id= i;
+ m_partition_part_key_multi_range_hld[i].partition_part_key_multi_range=
+ m_part_mrr_range_first[i];
+ }
+ DBUG_PRINT("return",("OK"));
+ DBUG_RETURN(0);
+}
+
+
+static void partition_multi_range_key_get_key_info(void *init_params,
+ uint *length,
+ key_part_map *map)
+{
+ PARTITION_PART_KEY_MULTI_RANGE_HLD *hld=
+ (PARTITION_PART_KEY_MULTI_RANGE_HLD *)init_params;
+ ha_partition *partition= hld->partition;
+ key_range *start_key= (&partition->m_mrr_range_first->
+ key_multi_range.start_key);
+ DBUG_ENTER("partition_multi_range_key_get_key_info");
+ *length= start_key->length;
+ *map= start_key->keypart_map;
+ DBUG_VOID_RETURN;
+}
+
+
+static range_seq_t partition_multi_range_key_init(void *init_params,
+ uint n_ranges,
+ uint flags)
+{
+ PARTITION_PART_KEY_MULTI_RANGE_HLD *hld=
+ (PARTITION_PART_KEY_MULTI_RANGE_HLD *)init_params;
+ ha_partition *partition= hld->partition;
+ uint i= hld->part_id;
+ DBUG_ENTER("partition_multi_range_key_init");
+ partition->m_mrr_range_init_flags= flags;
+ hld->partition_part_key_multi_range= partition->m_part_mrr_range_first[i];
+ DBUG_RETURN(init_params);
+}
+
+
+static bool partition_multi_range_key_next(range_seq_t seq,
+ KEY_MULTI_RANGE *range)
+{
+ PARTITION_PART_KEY_MULTI_RANGE_HLD *hld=
+ (PARTITION_PART_KEY_MULTI_RANGE_HLD *)seq;
+ PARTITION_KEY_MULTI_RANGE *partition_key_multi_range=
+ hld->partition_part_key_multi_range->partition_key_multi_range;
+ DBUG_ENTER("partition_multi_range_key_next");
+ if (!partition_key_multi_range)
+ DBUG_RETURN(TRUE);
+ *range= partition_key_multi_range->key_multi_range;
+ hld->partition_part_key_multi_range=
+ hld->partition_part_key_multi_range->next;
+ DBUG_RETURN(FALSE);
+}
+
+
+static bool partition_multi_range_key_skip_record(range_seq_t seq,
+ range_id_t range_info,
+ uchar *rowid)
+{
+ PARTITION_PART_KEY_MULTI_RANGE_HLD *hld=
+ (PARTITION_PART_KEY_MULTI_RANGE_HLD *)seq;
+ DBUG_ENTER("partition_multi_range_key_skip_record");
+ DBUG_RETURN(hld->partition->m_seq_if->skip_record(hld->partition->m_seq,
+ range_info, rowid));
+}
+
+
+static bool partition_multi_range_key_skip_index_tuple(range_seq_t seq,
+ range_id_t range_info)
+{
+ PARTITION_PART_KEY_MULTI_RANGE_HLD *hld=
+ (PARTITION_PART_KEY_MULTI_RANGE_HLD *)seq;
+ DBUG_ENTER("partition_multi_range_key_skip_index_tuple");
+ DBUG_RETURN(hld->partition->m_seq_if->skip_index_tuple(hld->partition->m_seq,
+ range_info));
+}
+
+ha_rows ha_partition::multi_range_read_info_const(uint keyno,
+ RANGE_SEQ_IF *seq,
+ void *seq_init_param,
+ uint n_ranges, uint *bufsz,
+ uint *mrr_mode,
+ Cost_estimate *cost)
+{
+ int error;
+ uint i;
+ handler **file;
+ ha_rows rows= 0;
+ uint ret_mrr_mode= 0;
+ range_seq_t seq_it;
+ part_id_range save_part_spec;
+ DBUG_ENTER("ha_partition::multi_range_read_info_const");
+ DBUG_PRINT("enter", ("partition this: %p", this));
+
+ m_mrr_new_full_buffer_size= 0;
+ save_part_spec= m_part_spec;
+
+ seq_it= seq->init(seq_init_param, n_ranges, *mrr_mode);
+ if ((error= multi_range_key_create_key(seq, seq_it)))
+ {
+ if (error == HA_ERR_END_OF_FILE) // No keys in range
+ {
+ rows= 0;
+ goto calc_cost;
+ }
+ /*
+ This error means that we can't do multi_range_read for the moment
+ (probably running out of memory) and we need to fallback to
+ normal reads
+ */
+ m_part_spec= save_part_spec;
+ DBUG_RETURN(HA_POS_ERROR);
+ }
+ m_part_seq_if.get_key_info=
+ seq->get_key_info ? partition_multi_range_key_get_key_info : NULL;
+ m_part_seq_if.init= partition_multi_range_key_init;
+ m_part_seq_if.next= partition_multi_range_key_next;
+ m_part_seq_if.skip_record= (seq->skip_record ?
+ partition_multi_range_key_skip_record : NULL);
+ m_part_seq_if.skip_index_tuple= (seq->skip_index_tuple ?
+ partition_multi_range_key_skip_index_tuple :
+ NULL);
+ file= m_file;
+ do
+ {
+ i= (uint)(file - m_file);
+ DBUG_PRINT("info",("partition part_id: %u", i));
+ if (bitmap_is_set(&m_mrr_used_partitions, i))
+ {
+ ha_rows tmp_rows;
+ uint tmp_mrr_mode;
+ m_mrr_buffer_size[i]= 0;
+ tmp_mrr_mode= *mrr_mode;
+ tmp_rows= (*file)->
+ multi_range_read_info_const(keyno, &m_part_seq_if,
+ &m_partition_part_key_multi_range_hld[i],
+ m_part_mrr_range_length[i],
+ &m_mrr_buffer_size[i],
+ &tmp_mrr_mode, cost);
+ if (tmp_rows == HA_POS_ERROR)
+ {
+ m_part_spec= save_part_spec;
+ DBUG_RETURN(HA_POS_ERROR);
+ }
+ rows+= tmp_rows;
+ ret_mrr_mode|= tmp_mrr_mode;
+ m_mrr_new_full_buffer_size+= m_mrr_buffer_size[i];
+ }
+ } while (*(++file));
+ *mrr_mode= ret_mrr_mode;
+
+calc_cost:
+ m_part_spec= save_part_spec;
+ cost->reset();
+ cost->avg_io_cost= 1;
+ if ((*mrr_mode & HA_MRR_INDEX_ONLY) && rows > 2)
+ cost->io_count= keyread_time(keyno, n_ranges, (uint) rows);
+ else
+ cost->io_count= read_time(keyno, n_ranges, rows);
+ cost->cpu_cost= (double) rows / TIME_FOR_COMPARE + 0.01;
+ DBUG_RETURN(rows);
+}
+
+
+ha_rows ha_partition::multi_range_read_info(uint keyno, uint n_ranges,
+ uint keys,
+ uint key_parts, uint *bufsz,
+ uint *mrr_mode,
+ Cost_estimate *cost)
+{
+ uint i;
+ handler **file;
+ ha_rows rows;
+ DBUG_ENTER("ha_partition::multi_range_read_info");
+ DBUG_PRINT("enter", ("partition this: %p", this));
+
+ m_mrr_new_full_buffer_size= 0;
+ file= m_file;
+ do
+ {
+ i= (uint)(file - m_file);
+ if (bitmap_is_set(&(m_part_info->read_partitions), (i)))
+ {
+ m_mrr_buffer_size[i]= 0;
+ if ((rows= (*file)->multi_range_read_info(keyno, n_ranges, keys,
+ key_parts,
+ &m_mrr_buffer_size[i],
+ mrr_mode, cost)))
+ DBUG_RETURN(rows);
+ m_mrr_new_full_buffer_size+= m_mrr_buffer_size[i];
+ }
+ } while (*(++file));
+
+ cost->reset();
+ cost->avg_io_cost= 1;
+ if (*mrr_mode & HA_MRR_INDEX_ONLY)
+ cost->io_count= keyread_time(keyno, n_ranges, (uint) rows);
+ else
+ cost->io_count= read_time(keyno, n_ranges, rows);
+ DBUG_RETURN(0);
+}
+
+
+int ha_partition::multi_range_read_init(RANGE_SEQ_IF *seq,
+ void *seq_init_param,
+ uint n_ranges, uint mrr_mode,
+ HANDLER_BUFFER *buf)
+{
+ int error;
+ uint i;
+ handler **file;
+ uchar *tmp_buffer;
+ DBUG_ENTER("ha_partition::multi_range_read_init");
+ DBUG_PRINT("enter", ("partition this: %p", this));
+
+ m_seq_if= seq;
+ m_seq= seq->init(seq_init_param, n_ranges, mrr_mode);
+ if ((error= multi_range_key_create_key(seq, m_seq)))
+ DBUG_RETURN(0);
+
+ m_part_seq_if.get_key_info= (seq->get_key_info ?
+ partition_multi_range_key_get_key_info :
+ NULL);
+ m_part_seq_if.init= partition_multi_range_key_init;
+ m_part_seq_if.next= partition_multi_range_key_next;
+ m_part_seq_if.skip_record= (seq->skip_record ?
+ partition_multi_range_key_skip_record :
+ NULL);
+ m_part_seq_if.skip_index_tuple= (seq->skip_index_tuple ?
+ partition_multi_range_key_skip_index_tuple :
+ NULL);
+
+ /* m_mrr_new_full_buffer_size was calculated in multi_range_read_info */
+ if (m_mrr_full_buffer_size < m_mrr_new_full_buffer_size)
+ {
+ if (m_mrr_full_buffer)
+ my_free(m_mrr_full_buffer);
+ if (!(m_mrr_full_buffer=
+ (uchar *) my_malloc(m_mrr_new_full_buffer_size, MYF(MY_WME))))
+ {
+ m_mrr_full_buffer_size= 0;
+ error= HA_ERR_OUT_OF_MEM;
+ goto error;
+ }
+ m_mrr_full_buffer_size= m_mrr_new_full_buffer_size;
+ }
+
+ tmp_buffer= m_mrr_full_buffer;
+ file= m_file;
+ do
+ {
+ i= (uint)(file - m_file);
+ DBUG_PRINT("info",("partition part_id: %u", i));
+ if (bitmap_is_set(&m_mrr_used_partitions, i))
+ {
+ if (m_mrr_new_full_buffer_size)
+ {
+ if (m_mrr_buffer_size[i])
+ {
+ m_mrr_buffer[i].buffer= tmp_buffer;
+ m_mrr_buffer[i].end_of_used_area= tmp_buffer;
+ tmp_buffer+= m_mrr_buffer_size[i];
+ m_mrr_buffer[i].buffer_end= tmp_buffer;
+ }
+ }
+ else
+ m_mrr_buffer[i]= *buf;
+
+ if ((error= (*file)->
+ multi_range_read_init(&m_part_seq_if,
+ &m_partition_part_key_multi_range_hld[i],
+ m_part_mrr_range_length[i],
+ mrr_mode,
+ &m_mrr_buffer[i])))
+ goto error;
+ m_stock_range_seq[i]= 0;
+ }
+ } while (*(++file));
+
+ m_multi_range_read_first= TRUE;
+ m_mrr_range_current= m_mrr_range_first;
+ m_index_scan_type= partition_read_multi_range;
+ m_mrr_mode= mrr_mode;
+ m_mrr_n_ranges= n_ranges;
+ DBUG_RETURN(0);
+
+error:
+ DBUG_RETURN(error);
+}
+
+
+int ha_partition::multi_range_read_next(range_id_t *range_info)
+{
+ int error;
+ DBUG_ENTER("ha_partition::multi_range_read_next");
+ DBUG_PRINT("enter", ("partition this: %p partition m_mrr_mode: %u",
+ this, m_mrr_mode));
+
+ if ((m_mrr_mode & HA_MRR_SORTED))
+ {
+ if (m_multi_range_read_first)
+ {
+ if ((error= handle_ordered_index_scan(table->record[0], FALSE)))
+ DBUG_RETURN(error);
+ if (!m_pre_calling)
+ m_multi_range_read_first= FALSE;
+ }
+ else if ((error= handle_ordered_next(table->record[0], eq_range)))
+ DBUG_RETURN(error);
+ *range_info= m_mrr_range_current->ptr;
+ }
+ else
+ {
+ if (m_multi_range_read_first)
+ {
+ if ((error= handle_unordered_scan_next_partition(table->record[0])))
+ DBUG_RETURN(error);
+ if (!m_pre_calling)
+ m_multi_range_read_first= FALSE;
+ }
+ else if ((error= handle_unordered_next(table->record[0], FALSE)))
+ DBUG_RETURN(error);
+
+ *range_info=
+ ((PARTITION_KEY_MULTI_RANGE *) m_range_info[m_last_part])->ptr;
+ }
+ DBUG_RETURN(0);
+}
+
+
+int ha_partition::multi_range_read_explain_info(uint mrr_mode, char *str,
+ size_t size)
+{
+ DBUG_ENTER("ha_partition::multi_range_read_explain_info");
+ DBUG_RETURN(get_open_file_sample()->
+ multi_range_read_explain_info(mrr_mode, str, size));
+}
+
+
+/**
+ Find and retrieve the Full Text Search relevance ranking for a search string
+ in a full text index.
+
+ @param handler Full Text Search handler
+ @param record Search string
+ @param length Length of the search string
+
+ @retval Relevance value
+*/
+
+float partition_ft_find_relevance(FT_INFO *handler,
+ uchar *record, uint length)
+{
+ st_partition_ft_info *info= (st_partition_ft_info *)handler;
+ uint m_last_part= ((ha_partition*) info->file)->last_part();
+ FT_INFO *m_handler= info->part_ft_info[m_last_part];
+ DBUG_ENTER("partition_ft_find_relevance");
+ if (!m_handler)
+ DBUG_RETURN((float)-1.0);
+ DBUG_RETURN(m_handler->please->find_relevance(m_handler, record, length));
+}
+
+
+/**
+ Retrieve the Full Text Search relevance ranking for the current
+ full text search.
+
+ @param handler Full Text Search handler
+
+ @retval Relevance value
+*/
+
+float partition_ft_get_relevance(FT_INFO *handler)
+{
+ st_partition_ft_info *info= (st_partition_ft_info *)handler;
+ uint m_last_part= ((ha_partition*) info->file)->last_part();
+ FT_INFO *m_handler= info->part_ft_info[m_last_part];
+ DBUG_ENTER("partition_ft_get_relevance");
+ if (!m_handler)
+ DBUG_RETURN((float)-1.0);
+ DBUG_RETURN(m_handler->please->get_relevance(m_handler));
+}
+
+
+/**
+ Free the memory for a full text search handler.
+
+ @param handler Full Text Search handler
+*/
+
+void partition_ft_close_search(FT_INFO *handler)
+{
+ st_partition_ft_info *info= (st_partition_ft_info *)handler;
+ info->file->ft_close_search(handler);
+}
+
+
+/**
+ Free the memory for a full text search handler.
+
+ @param handler Full Text Search handler
+*/
+
+void ha_partition::ft_close_search(FT_INFO *handler)
+{
+ uint i;
+ st_partition_ft_info *info= (st_partition_ft_info *)handler;
+ DBUG_ENTER("ha_partition::ft_close_search");
+
+ for (i= 0; i < m_tot_parts; i++)
+ {
+ FT_INFO *m_handler= info->part_ft_info[i];
+ DBUG_ASSERT(!m_handler ||
+ (m_handler->please && m_handler->please->close_search));
+ if (m_handler &&
+ m_handler->please &&
+ m_handler->please->close_search)
+ m_handler->please->close_search(m_handler);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/* Partition Full Text search function table */
+_ft_vft partition_ft_vft =
+{
+ NULL, // partition_ft_read_next
+ partition_ft_find_relevance,
+ partition_ft_close_search,
+ partition_ft_get_relevance,
+ NULL // partition_ft_reinit_search
+};
+
+
+/**
+ Initialize a full text search.
+*/
+
+int ha_partition::ft_init()
+{
+ int error;
+ uint i= 0;
+ uint32 part_id;
+ DBUG_ENTER("ha_partition::ft_init");
+ DBUG_PRINT("info", ("partition this: %p", this));
+
+ /*
+ For operations that may need to change data, we may need to extend
+ read_set.
+ */
+ if (get_lock_type() == F_WRLCK)
+ {
+ /*
+ If write_set contains any of the fields used in partition and
+ subpartition expression, we need to set all bits in read_set because
+ the row may need to be inserted in a different [sub]partition. In
+ other words update_row() can be converted into write_row(), which
+ requires a complete record.
+ */
+ if (bitmap_is_overlapping(&m_part_info->full_part_field_set,
+ table->write_set))
+ bitmap_set_all(table->read_set);
+ else
+ {
+ /*
+ Some handlers only read fields as specified by the bitmap for the
+ read set. For partitioned handlers we always require that the
+ fields of the partition functions are read such that we can
+ calculate the partition id to place updated and deleted records.
+ */
+ bitmap_union(table->read_set, &m_part_info->full_part_field_set);
+ }
+ }
+
+ /* Now we see what the index of our first important partition is */
+ DBUG_PRINT("info", ("m_part_info->read_partitions: %p",
+ (void *) m_part_info->read_partitions.bitmap));
+ part_id= bitmap_get_first_set(&(m_part_info->read_partitions));
+ DBUG_PRINT("info", ("m_part_spec.start_part %u", (uint) part_id));
+
+ if (part_id == MY_BIT_NONE)
+ {
+ error= 0;
+ goto err1;
+ }
+
+ DBUG_PRINT("info", ("ft_init on partition %u", (uint) part_id));
+ /*
+ ft_end() is needed for partitioning to reset internal data if scan
+ is already in use
+ */
+ if (m_pre_calling)
+ {
+ if ((error= pre_ft_end()))
+ goto err1;
+ }
+ else
+ ft_end();
+ m_index_scan_type= partition_ft_read;
+ for (i= part_id; i < m_tot_parts; i++)
+ {
+ if (bitmap_is_set(&(m_part_info->read_partitions), i))
+ {
+ error= m_pre_calling ? m_file[i]->pre_ft_init() : m_file[i]->ft_init();
+ if (error)
+ goto err2;
+ }
+ }
+ m_scan_value= 1;
+ m_part_spec.start_part= part_id;
+ m_part_spec.end_part= m_tot_parts - 1;
+ m_ft_init_and_first= TRUE;
+ DBUG_PRINT("info", ("m_scan_value: %u", m_scan_value));
+ DBUG_RETURN(0);
+
+err2:
+ late_extra_no_cache(part_id);
+ while ((int)--i >= (int)part_id)
+ {
+ if (bitmap_is_set(&(m_part_info->read_partitions), i))
+ {
+ if (m_pre_calling)
+ m_file[i]->pre_ft_end();
+ else
+ m_file[i]->ft_end();
+ }
+ }
+err1:
+ m_scan_value= 2;
+ m_part_spec.start_part= NO_CURRENT_PART_ID;
+ DBUG_RETURN(error);
+}
+
+
+/**
+ Initialize a full text search during a bulk access request.
+*/
+
+int ha_partition::pre_ft_init()
+{
+ bool save_m_pre_calling;
+ int error;
+ DBUG_ENTER("ha_partition::pre_ft_init");
+ save_m_pre_calling= m_pre_calling;
+ m_pre_calling= TRUE;
+ error= ft_init();
+ m_pre_calling= save_m_pre_calling;
+ DBUG_RETURN(error);
+}
+
+
+/**
+ Terminate a full text search.
+*/
+
+void ha_partition::ft_end()
+{
+ handler **file;
+ DBUG_ENTER("ha_partition::ft_end");
+ DBUG_PRINT("info", ("partition this: %p", this));
+
+ switch (m_scan_value) {
+ case 2: // Error
+ break;
+ case 1: // Table scan
+ if (NO_CURRENT_PART_ID != m_part_spec.start_part)
+ late_extra_no_cache(m_part_spec.start_part);
+ file= m_file;
+ do
+ {
+ if (bitmap_is_set(&(m_part_info->read_partitions), (uint)(file - m_file)))
+ {
+ if (m_pre_calling)
+ (*file)->pre_ft_end();
+ else
+ (*file)->ft_end();
+ }
+ } while (*(++file));
+ break;
+ }
+ m_scan_value= 2;
+ m_part_spec.start_part= NO_CURRENT_PART_ID;
+ ft_current= 0;
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ Terminate a full text search during a bulk access request.
+*/
+
+int ha_partition::pre_ft_end()
+{
+ bool save_m_pre_calling;
+ DBUG_ENTER("ha_partition::pre_ft_end");
+ save_m_pre_calling= m_pre_calling;
+ m_pre_calling= TRUE;
+ ft_end();
+ m_pre_calling= save_m_pre_calling;
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Initialize a full text search using the extended API.
+
+ @param flags Search flags
+ @param inx Key number
+ @param key Key value
+
+ @return FT_INFO structure if successful
+ NULL otherwise
+*/
+
+FT_INFO *ha_partition::ft_init_ext(uint flags, uint inx, String *key)
+{
+ FT_INFO *ft_handler;
+ handler **file;
+ st_partition_ft_info *ft_target, **parent;
+ DBUG_ENTER("ha_partition::ft_init_ext");
+
+ if (ft_current)
+ parent= &ft_current->next;
+ else
+ parent= &ft_first;
+
+ if (!(ft_target= *parent))
+ {
+ FT_INFO **tmp_ft_info;
+ if (!(ft_target= (st_partition_ft_info *)
+ my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+ &ft_target,
+ sizeof(st_partition_ft_info),
+ &tmp_ft_info,
+ sizeof(FT_INFO *) * m_tot_parts,
+ NullS)))
+ {
+ my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
+ DBUG_RETURN(NULL);
+ }
+ ft_target->part_ft_info= tmp_ft_info;
+ (*parent)= ft_target;
+ }
+
+ ft_current= ft_target;
+ file= m_file;
+ do
+ {
+ if (bitmap_is_set(&(m_part_info->read_partitions), (uint)(file - m_file)))
+ {
+ if ((ft_handler= (*file)->ft_init_ext(flags, inx, key)))
+ (*file)->ft_handler= ft_handler;
+ else
+ (*file)->ft_handler= NULL;
+ ft_target->part_ft_info[file - m_file]= ft_handler;
+ }
+ else
+ {
+ (*file)->ft_handler= NULL;
+ ft_target->part_ft_info[file - m_file]= NULL;
+ }
+ } while (*(++file));
+
+ ft_target->please= &partition_ft_vft;
+ ft_target->file= this;
+ DBUG_RETURN((FT_INFO*)ft_target);
+}
+
+
+/**
+ Return the next record from the FT result set during an ordered index
+ pre-scan
+
+ @param use_parallel Is it a parallel search
+
+ @return >0 Error code
+ 0 Success
+*/
+
+int ha_partition::pre_ft_read(bool use_parallel)
+{
+ bool save_m_pre_calling;
+ int error;
+ DBUG_ENTER("ha_partition::pre_ft_read");
+ DBUG_PRINT("info", ("partition this: %p", this));
+ save_m_pre_calling= m_pre_calling;
+ m_pre_calling= TRUE;
+ m_pre_call_use_parallel= use_parallel;
+ error= ft_read(table->record[0]);
+ m_pre_calling= save_m_pre_calling;
+ DBUG_RETURN(error);
+}
+
+
+/**
+ Return the first or next record in a full text search.
+
+ @param buf Buffer where the record should be returned
+
+ @return >0 Error code
+ 0 Success
+*/
+
+int ha_partition::ft_read(uchar *buf)
+{
+ handler *file;
+ int result= HA_ERR_END_OF_FILE, error;
+ uint part_id= m_part_spec.start_part;
+ DBUG_ENTER("ha_partition::ft_read");
+ DBUG_PRINT("info", ("partition this: %p", this));
+ DBUG_PRINT("info", ("part_id: %u", part_id));
+
+ if (part_id == NO_CURRENT_PART_ID)
+ {
+ /*
+ The original set of partitions to scan was empty and thus we report
+ the result here.
+ */
+ DBUG_PRINT("info", ("NO_CURRENT_PART_ID"));
+ goto end;
+ }
+
+ DBUG_ASSERT(m_scan_value == 1);
+
+ if (m_ft_init_and_first) // First call to ft_read()
+ {
+ m_ft_init_and_first= FALSE;
+ if (!bulk_access_executing)
+ {
+ error= handle_pre_scan(FALSE, check_parallel_search());
+ if (m_pre_calling || error)
+ DBUG_RETURN(error);
+ }
+ late_extra_cache(part_id);
+ }
+
+ file= m_file[part_id];
+
+ while (TRUE)
+ {
+ if (!(result= file->ft_read(buf)))
+ {
+ /* Found row: remember position and return it. */
+ m_part_spec.start_part= m_last_part= part_id;
+ table->status= 0;
+ DBUG_RETURN(0);
+ }
+
+ /*
+ if we get here, then the current partition ft_next returned failure
+ */
+ if (result == HA_ERR_RECORD_DELETED)
+ continue; // Probably MyISAM
+
+ if (result != HA_ERR_END_OF_FILE)
+ goto end_dont_reset_start_part; // Return error
+
+ /* End current partition */
+ late_extra_no_cache(part_id);
+ DBUG_PRINT("info", ("stopping using partition %u", (uint) part_id));
+
+ /* Shift to next partition */
+ while (++part_id < m_tot_parts &&
+ !bitmap_is_set(&(m_part_info->read_partitions), part_id))
+ ;
+ if (part_id >= m_tot_parts)
+ {
+ result= HA_ERR_END_OF_FILE;
+ break;
+ }
+ m_part_spec.start_part= m_last_part= part_id;
+ file= m_file[part_id];
+ DBUG_PRINT("info", ("now using partition %u", (uint) part_id));
+ late_extra_cache(part_id);
+ }
+
+end:
+ m_part_spec.start_part= NO_CURRENT_PART_ID;
+end_dont_reset_start_part:
+ table->status= STATUS_NOT_FOUND;
+ DBUG_RETURN(result);
+}
+
/*
Common routine to set up index scans
@@ -5856,7 +6931,7 @@ int ha_partition::read_range_next()
needs it to calculcate partitioning function
values)
- idx_read_flag TRUE <=> m_start_key has range start endpoint which
+ idx_read_flag TRUE <=> m_start_key has range start endpoint which
probably can be used to determine the set of partitions
to scan.
FALSE <=> there is no start endpoint.
@@ -5878,7 +6953,7 @@ int ha_partition::partition_scan_set_up(uchar * buf, bool idx_read_flag)
DBUG_ENTER("ha_partition::partition_scan_set_up");
if (idx_read_flag)
- get_partition_set(table,buf,active_index,&m_start_key,&m_part_spec);
+ get_partition_set(table, buf, active_index, &m_start_key, &m_part_spec);
else
{
m_part_spec.start_part= 0;
@@ -5899,8 +6974,8 @@ int ha_partition::partition_scan_set_up(uchar * buf, bool idx_read_flag)
We discovered a single partition to scan, this never needs to be
performed using the ordered index scan.
*/
- DBUG_PRINT("info", ("index scan using the single partition %d",
- m_part_spec.start_part));
+ DBUG_PRINT("info", ("index scan using the single partition %u",
+ (uint) m_part_spec.start_part));
m_ordered_scan_ongoing= FALSE;
}
else
@@ -5927,6 +7002,206 @@ int ha_partition::partition_scan_set_up(uchar * buf, bool idx_read_flag)
DBUG_RETURN(0);
}
+/**
+ Check if we can search partitions in parallel
+
+ @retval TRUE yes
+ @retval FALSE no
+*/
+
+bool ha_partition::check_parallel_search()
+{
+ TABLE_LIST *table_list= table->pos_in_table_list;
+ st_select_lex *select_lex;
+ JOIN *join;
+ DBUG_ENTER("ha_partition::check_parallel_search");
+ if (!table_list)
+ goto not_parallel;
+
+ while (table_list->parent_l)
+ table_list= table_list->parent_l;
+
+ select_lex= table_list->select_lex;
+ DBUG_PRINT("info",("partition select_lex: %p", select_lex));
+ if (!select_lex)
+ goto not_parallel;
+ if (!select_lex->explicit_limit)
+ {
+ DBUG_PRINT("info",("partition not using explicit_limit"));
+ goto parallel;
+ }
+
+ join= select_lex->join;
+ DBUG_PRINT("info",("partition join: %p", join));
+ if (join && join->skip_sort_order)
+ {
+ DBUG_PRINT("info",("partition order_list.elements: %u",
+ select_lex->order_list.elements));
+ if (select_lex->order_list.elements)
+ {
+ Item *item= *select_lex->order_list.first->item;
+ DBUG_PRINT("info",("partition item: %p", item));
+ DBUG_PRINT("info",("partition item->type(): %u", item->type()));
+ DBUG_PRINT("info",("partition m_part_info->part_type: %u",
+ m_part_info->part_type));
+ DBUG_PRINT("info",("partition m_is_sub_partitioned: %s",
+ m_is_sub_partitioned ? "TRUE" : "FALSE"));
+ DBUG_PRINT("info",("partition m_part_info->part_expr: %p",
+ m_part_info->part_expr));
+ if (item->type() == Item::FIELD_ITEM &&
+ m_part_info->part_type == RANGE_PARTITION &&
+ !m_is_sub_partitioned &&
+ (!m_part_info->part_expr ||
+ m_part_info->part_expr->type() == Item::FIELD_ITEM))
+ {
+ Field *order_field= ((Item_field *)item)->field;
+ DBUG_PRINT("info",("partition order_field: %p", order_field));
+ if (order_field && order_field->table == table_list->table)
+ {
+ Field *part_field= m_part_info->full_part_field_array[0];
+ if (set_top_table_fields)
+ order_field= top_table_field[order_field->field_index];
+ DBUG_PRINT("info",("partition order_field: %p", order_field));
+ DBUG_PRINT("info",("partition part_field: %p", part_field));
+ if (part_field == order_field)
+ {
+ /*
+ We are using ORDER BY partition_field LIMIT #
+ In this case, let's not do things in parallel as it's
+ likely that the query can be satisfied from the first
+ partition
+ */
+ DBUG_PRINT("info",("partition with ORDER on partition field"));
+ goto not_parallel;
+ }
+ }
+ }
+ DBUG_PRINT("info",("partition have order"));
+ goto parallel;
+ }
+
+ DBUG_PRINT("info",("partition group_list.elements: %u",
+ select_lex->group_list.elements));
+ if (select_lex->group_list.elements)
+ {
+ Item *item= *select_lex->group_list.first->item;
+ DBUG_PRINT("info",("partition item: %p", item));
+ DBUG_PRINT("info",("partition item->type(): %u", item->type()));
+ DBUG_PRINT("info",("partition m_part_info->part_type: %u",
+ m_part_info->part_type));
+ DBUG_PRINT("info",("partition m_is_sub_partitioned: %s",
+ m_is_sub_partitioned ? "TRUE" : "FALSE"));
+ DBUG_PRINT("info",("partition m_part_info->part_expr: %p",
+ m_part_info->part_expr));
+ if (item->type() == Item::FIELD_ITEM &&
+ m_part_info->part_type == RANGE_PARTITION &&
+ !m_is_sub_partitioned &&
+ (!m_part_info->part_expr ||
+ m_part_info->part_expr->type() == Item::FIELD_ITEM))
+ {
+ Field *group_field= ((Item_field *)item)->field;
+ DBUG_PRINT("info",("partition group_field: %p", group_field));
+ if (group_field && group_field->table == table_list->table)
+ {
+ Field *part_field= m_part_info->full_part_field_array[0];
+ if (set_top_table_fields)
+ group_field= top_table_field[group_field->field_index];
+ DBUG_PRINT("info",("partition group_field: %p", group_field));
+ DBUG_PRINT("info",("partition part_field: %p", part_field));
+ if (part_field == group_field)
+ {
+ DBUG_PRINT("info",("partition with GROUP BY on partition field"));
+ goto not_parallel;
+ }
+ }
+ }
+ DBUG_PRINT("info",("partition with GROUP BY"));
+ goto parallel;
+ }
+ }
+ else if (select_lex->order_list.elements ||
+ select_lex->group_list.elements)
+ {
+ DBUG_PRINT("info",("partition is not skip_order"));
+ DBUG_PRINT("info",("partition order_list.elements: %u",
+ select_lex->order_list.elements));
+ DBUG_PRINT("info",("partition group_list.elements: %u",
+ select_lex->group_list.elements));
+ goto parallel;
+ }
+ DBUG_PRINT("info",("partition is not skip_order"));
+
+not_parallel:
+ DBUG_PRINT("return",("partition FALSE"));
+ DBUG_RETURN(FALSE);
+
+parallel:
+ DBUG_PRINT("return",("partition TRUE"));
+ DBUG_RETURN(TRUE);
+}
+
+
+int ha_partition::handle_pre_scan(bool reverse_order, bool use_parallel)
+{
+ uint i;
+ DBUG_ENTER("ha_partition::handle_pre_scan");
+ DBUG_PRINT("enter",
+ ("m_part_spec.start_part: %u m_part_spec.end_part: %u",
+ (uint) m_part_spec.start_part, (uint) m_part_spec.end_part));
+
+ for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++)
+ {
+ if (!(bitmap_is_set(&(m_part_info->read_partitions), i)))
+ continue;
+ int error;
+ handler *file= m_file[i];
+
+ switch (m_index_scan_type) {
+ case partition_index_read:
+ error= file->pre_index_read_map(m_start_key.key,
+ m_start_key.keypart_map,
+ m_start_key.flag,
+ use_parallel);
+ break;
+ case partition_index_first:
+ error= file->pre_index_first(use_parallel);
+ break;
+ case partition_index_last:
+ error= file->pre_index_last(use_parallel);
+ break;
+ case partition_index_read_last:
+ error= file->pre_index_read_last_map(m_start_key.key,
+ m_start_key.keypart_map,
+ use_parallel);
+ break;
+ case partition_read_range:
+ error= file->pre_read_range_first(m_start_key.key? &m_start_key: NULL,
+ end_range, eq_range, TRUE, use_parallel);
+ break;
+ case partition_read_multi_range:
+ if (!bitmap_is_set(&m_mrr_used_partitions, i))
+ continue;
+ error= file->pre_multi_range_read_next(use_parallel);
+ break;
+ case partition_ft_read:
+ error= file->pre_ft_read(use_parallel);
+ break;
+ case partition_no_index_scan:
+ error= file->pre_rnd_next(use_parallel);
+ break;
+ default:
+ DBUG_ASSERT(FALSE);
+ DBUG_RETURN(0);
+ }
+ if (error == HA_ERR_END_OF_FILE)
+ error= 0;
+ if (error)
+ DBUG_RETURN(error);
+ }
+ table->status= 0;
+ DBUG_RETURN(0);
+}
+
/****************************************************************************
Unordered Index Scan Routines
@@ -5973,7 +7248,16 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same)
partition_read_range is_next_same are always local constants
*/
- if (m_index_scan_type == partition_read_range)
+ if (m_index_scan_type == partition_read_multi_range)
+ {
+ if (!(error= file->
+ multi_range_read_next(&m_range_info[m_part_spec.start_part])))
+ {
+ m_last_part= m_part_spec.start_part;
+ DBUG_RETURN(0);
+ }
+ }
+ else if (m_index_scan_type == partition_read_range)
{
if (!(error= file->read_range_next()))
{
@@ -5990,7 +7274,7 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same)
DBUG_RETURN(0);
}
}
- else
+ else
{
if (!(error= file->ha_index_next(buf)))
{
@@ -6013,7 +7297,7 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same)
SYNOPSIS
handle_unordered_scan_next_partition()
- buf Read row in MySQL Row Format
+ buf Read row in MariaDB Row Format
RETURN VALUE
HA_ERR_END_OF_FILE End of scan
@@ -6031,6 +7315,7 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
int saved_error= HA_ERR_END_OF_FILE;
DBUG_ENTER("ha_partition::handle_unordered_scan_next_partition");
+ /* Read next partition that includes start_part */
if (i)
i= bitmap_get_next_set(&m_part_info->read_partitions, i - 1);
else
@@ -6043,34 +7328,29 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
int error;
handler *file= m_file[i];
m_part_spec.start_part= i;
+
switch (m_index_scan_type) {
+ case partition_read_multi_range:
+ if (!bitmap_is_set(&m_mrr_used_partitions, i))
+ continue;
+ DBUG_PRINT("info", ("read_multi_range on partition %u", i));
+ error= file->multi_range_read_next(&m_range_info[i]);
+ break;
case partition_read_range:
- DBUG_PRINT("info", ("read_range_first on partition %d", i));
+ DBUG_PRINT("info", ("read_range_first on partition %u", i));
error= file->read_range_first(m_start_key.key? &m_start_key: NULL,
end_range, eq_range, FALSE);
break;
case partition_index_read:
- DBUG_PRINT("info", ("index_read on partition %d", i));
+ DBUG_PRINT("info", ("index_read on partition %u", i));
error= file->ha_index_read_map(buf, m_start_key.key,
m_start_key.keypart_map,
m_start_key.flag);
break;
case partition_index_first:
- DBUG_PRINT("info", ("index_first on partition %d", i));
+ DBUG_PRINT("info", ("index_first on partition %u", i));
error= file->ha_index_first(buf);
break;
- case partition_index_first_unordered:
- /*
- We perform a scan without sorting and this means that we
- should not use the index_first since not all handlers
- support it and it is also unnecessary to restrict sort
- order.
- */
- DBUG_PRINT("info", ("read_range_first on partition %d", i));
- table->record[0]= buf;
- error= file->read_range_first(0, end_range, eq_range, 0);
- table->record[0]= m_rec0;
- break;
default:
DBUG_ASSERT(FALSE);
DBUG_RETURN(1);
@@ -6084,12 +7364,12 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
DBUG_RETURN(error);
/*
- If HA_ERR_KEY_NOT_FOUND, we must return that error instead of
+ If HA_ERR_KEY_NOT_FOUND, we must return that error instead of
HA_ERR_END_OF_FILE, to be able to continue search.
*/
if (saved_error != HA_ERR_KEY_NOT_FOUND)
saved_error= error;
- DBUG_PRINT("info", ("END_OF_FILE/KEY_NOT_FOUND on partition %d", i));
+ DBUG_PRINT("info", ("END_OF_FILE/KEY_NOT_FOUND on partition %u", i));
}
if (saved_error == HA_ERR_END_OF_FILE)
m_part_spec.start_part= NO_CURRENT_PART_ID;
@@ -6100,7 +7380,7 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
/**
Common routine to start index scan with ordered results.
- @param[out] buf Read row in MySQL Row Format
+ @param[out] buf Read row in MariaDB Row Format
@return Operation status
@retval HA_ERR_END_OF_FILE End of scan
@@ -6126,19 +7406,31 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
{
+ int error;
uint i;
uint j= queue_first_element(&m_queue);
+ uint smallest_range_seq= 0;
bool found= FALSE;
uchar *part_rec_buf_ptr= m_ordered_rec_buffer;
int saved_error= HA_ERR_END_OF_FILE;
DBUG_ENTER("ha_partition::handle_ordered_index_scan");
+ DBUG_PRINT("enter", ("partition this: %p", this));
+
+ if (m_pre_calling)
+ error= handle_pre_scan(reverse_order, m_pre_call_use_parallel);
+ else
+ error= handle_pre_scan(reverse_order, check_parallel_search());
+ if (error)
+ DBUG_RETURN(error);
if (m_key_not_found)
{
+ /* m_key_not_found was set in the previous call to this function */
m_key_not_found= false;
bitmap_clear_all(&m_key_not_found_partitions);
}
m_top_entry= NO_CURRENT_PART_ID;
+ DBUG_PRINT("info", ("partition queue_remove_all(1)"));
queue_remove_all(&m_queue);
DBUG_ASSERT(bitmap_is_set(&m_part_info->read_partitions,
m_part_spec.start_part));
@@ -6158,14 +7450,14 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
DBUG_PRINT("info", ("m_part_spec.start_part %u first_used_part %u",
m_part_spec.start_part, i));
for (/* continue from above */ ;
- i <= m_part_spec.end_part;
- i= bitmap_get_next_set(&m_part_info->read_partitions, i))
+ i <= m_part_spec.end_part ;
+ i= bitmap_get_next_set(&m_part_info->read_partitions, i),
+ part_rec_buf_ptr+= m_priority_queue_rec_len)
{
DBUG_PRINT("info", ("reading from part %u (scan_type: %u)",
i, m_index_scan_type));
DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr));
uchar *rec_buf_ptr= part_rec_buf_ptr + PARTITION_BYTES_IN_POS;
- int error;
handler *file= m_file[i];
switch (m_index_scan_type) {
@@ -6174,6 +7466,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
m_start_key.key,
m_start_key.keypart_map,
m_start_key.flag);
+ /* Caller has specified reverse_order */
break;
case partition_index_first:
error= file->ha_index_first(rec_buf_ptr);
@@ -6185,16 +7478,49 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
break;
case partition_read_range:
{
- /*
+ /*
This can only read record to table->record[0], as it was set when
the table was being opened. We have to memcpy data ourselves.
*/
error= file->read_range_first(m_start_key.key? &m_start_key: NULL,
end_range, eq_range, TRUE);
- memcpy(rec_buf_ptr, table->record[0], m_rec_length);
+ if (!error)
+ memcpy(rec_buf_ptr, table->record[0], m_rec_length);
reverse_order= FALSE;
break;
}
+ case partition_read_multi_range:
+ {
+ if (!bitmap_is_set(&m_mrr_used_partitions, i))
+ continue;
+ DBUG_PRINT("info", ("partition %u", i));
+ error= file->multi_range_read_next(&m_range_info[i]);
+ DBUG_PRINT("info", ("error: %d", error));
+ if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
+ {
+ bitmap_clear_bit(&m_mrr_used_partitions, i);
+ continue;
+ }
+ if (!error)
+ {
+ memcpy(rec_buf_ptr, table->record[0], m_rec_length);
+ reverse_order= FALSE;
+ m_stock_range_seq[i]= (((PARTITION_KEY_MULTI_RANGE *)
+ m_range_info[i])->id);
+ /* Test if the key is in the first key range */
+ if (m_stock_range_seq[i] != m_mrr_range_current->id)
+ {
+ /*
+ smallest_range_seq contains the smallest key range we have seen
+ so far
+ */
+ if (!smallest_range_seq || smallest_range_seq > m_stock_range_seq[i])
+ smallest_range_seq= m_stock_range_seq[i];
+ continue;
+ }
+ }
+ break;
+ }
default:
DBUG_ASSERT(FALSE);
DBUG_RETURN(HA_ERR_END_OF_FILE);
@@ -6212,10 +7538,6 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
*/
queue_element(&m_queue, j++)= part_rec_buf_ptr;
}
- else if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
- {
- DBUG_RETURN(error);
- }
else if (error == HA_ERR_KEY_NOT_FOUND)
{
DBUG_PRINT("info", ("HA_ERR_KEY_NOT_FOUND from partition %u", i));
@@ -6223,7 +7545,53 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
m_key_not_found= true;
saved_error= error;
}
- part_rec_buf_ptr+= m_priority_queue_rec_len;
+ else if (error != HA_ERR_END_OF_FILE)
+ {
+ DBUG_RETURN(error);
+ }
+ }
+
+ if (!found && smallest_range_seq)
+ {
+ /* We know that there is an existing row based on code above */
+ found= TRUE;
+ part_rec_buf_ptr= m_ordered_rec_buffer;
+
+ /*
+ No key found in the first key range
+ Collect all partitions that has a key in smallest_range_seq
+ */
+ DBUG_PRINT("info", ("partition !found && smallest_range_seq"));
+ for (i= bitmap_get_first_set(&m_part_info->read_partitions);
+ i <= m_part_spec.end_part;
+ i= bitmap_get_next_set(&m_part_info->read_partitions, i))
+ {
+ DBUG_PRINT("info", ("partition current_part: %u", i));
+ if (i < m_part_spec.start_part)
+ {
+ part_rec_buf_ptr+= m_priority_queue_rec_len;
+ DBUG_PRINT("info", ("partition i < m_part_spec.start_part"));
+ continue;
+ }
+ if (!bitmap_is_set(&m_mrr_used_partitions, i))
+ {
+ part_rec_buf_ptr+= m_priority_queue_rec_len;
+ DBUG_PRINT("info", ("partition !bitmap_is_set(&m_mrr_used_partitions, i)"));
+ continue;
+ }
+ DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr));
+ if (smallest_range_seq == m_stock_range_seq[i])
+ {
+ m_stock_range_seq[i]= 0;
+ queue_element(&m_queue, j++)= (uchar *) part_rec_buf_ptr;
+ DBUG_PRINT("info", ("partition smallest_range_seq == m_stock_range_seq[i]"));
+ }
+ part_rec_buf_ptr+= m_priority_queue_rec_len;
+ }
+
+ /* Update global m_mrr_range_current to the current range */
+ while (m_mrr_range_current->id < smallest_range_seq)
+ m_mrr_range_current= m_mrr_range_current->next;
}
if (found)
{
@@ -6232,12 +7600,11 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
after that read the first entry and copy it to the buffer to return in.
*/
queue_set_max_at_top(&m_queue, reverse_order);
- queue_set_cmp_arg(&m_queue, m_using_extended_keys? m_curr_key_info : (void*)this);
+ queue_set_cmp_arg(&m_queue, (void*) this);
m_queue.elements= j - queue_first_element(&m_queue);
queue_fix(&m_queue);
return_top_record(buf);
- table->status= 0;
- DBUG_PRINT("info", ("Record returned from partition %d", m_top_entry));
+ DBUG_PRINT("info", ("Record returned from partition %u", m_top_entry));
DBUG_RETURN(0);
}
DBUG_RETURN(saved_error);
@@ -6260,11 +7627,28 @@ void ha_partition::return_top_record(uchar *buf)
uint part_id;
uchar *key_buffer= queue_top(&m_queue);
uchar *rec_buffer= key_buffer + PARTITION_BYTES_IN_POS;
+ DBUG_ENTER("ha_partition::return_top_record");
+ DBUG_PRINT("enter", ("partition this: %p", this));
part_id= uint2korr(key_buffer);
memcpy(buf, rec_buffer, m_rec_length);
m_last_part= part_id;
+ DBUG_PRINT("info", ("partition m_last_part: %u", m_last_part));
m_top_entry= part_id;
+ table->status= 0; // Found an existing row
+ m_file[part_id]->return_record_by_parent();
+ DBUG_VOID_RETURN;
+}
+
+/*
+ This function is only used if the partitioned table has own partitions.
+ This can happen if the partitioned VP engine is used (part of spider).
+*/
+
+void ha_partition::return_record_by_parent()
+{
+ m_file[m_last_part]->return_record_by_parent();
+ DBUG_ASSERT(0);
}
@@ -6283,6 +7667,7 @@ int ha_partition::handle_ordered_index_scan_key_not_found()
uchar *part_buf= m_ordered_rec_buffer;
uchar *curr_rec_buf= NULL;
DBUG_ENTER("ha_partition::handle_ordered_index_scan_key_not_found");
+ DBUG_PRINT("enter", ("partition this: %p", this));
DBUG_ASSERT(m_key_not_found);
/*
Loop over all used partitions to get the correct offset
@@ -6303,7 +7688,10 @@ int ha_partition::handle_ordered_index_scan_key_not_found()
/* HA_ERR_KEY_NOT_FOUND is not allowed from index_next! */
DBUG_ASSERT(error != HA_ERR_KEY_NOT_FOUND);
if (!error)
+ {
+ DBUG_PRINT("info", ("partition queue_insert(1)"));
queue_insert(&m_queue, part_buf);
+ }
else if (error != HA_ERR_END_OF_FILE && error != HA_ERR_KEY_NOT_FOUND)
DBUG_RETURN(error);
}
@@ -6340,11 +7728,15 @@ int ha_partition::handle_ordered_index_scan_key_not_found()
int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same)
{
int error;
+ DBUG_ENTER("ha_partition::handle_ordered_next");
+
+ if (m_top_entry == NO_CURRENT_PART_ID)
+ DBUG_RETURN(HA_ERR_END_OF_FILE);
+
uint part_id= m_top_entry;
uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS;
handler *file;
- DBUG_ENTER("ha_partition::handle_ordered_next");
-
+
if (m_key_not_found)
{
if (is_next_same)
@@ -6386,6 +7778,122 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same)
error= file->read_range_next();
memcpy(rec_buf, table->record[0], m_rec_length);
}
+ else if (m_index_scan_type == partition_read_multi_range)
+ {
+ DBUG_PRINT("info", ("partition_read_multi_range route"));
+ DBUG_PRINT("info", ("part_id: %u", part_id));
+ bool get_next= FALSE;
+ error= file->multi_range_read_next(&m_range_info[part_id]);
+ DBUG_PRINT("info", ("error: %d", error));
+ if (error == HA_ERR_KEY_NOT_FOUND)
+ error= HA_ERR_END_OF_FILE;
+ if (error == HA_ERR_END_OF_FILE)
+ {
+ bitmap_clear_bit(&m_mrr_used_partitions, part_id);
+ DBUG_PRINT("info", ("partition m_queue.elements: %u", m_queue.elements));
+ if (m_queue.elements)
+ {
+ DBUG_PRINT("info", ("partition queue_remove_top(1)"));
+ queue_remove_top(&m_queue);
+ if (m_queue.elements)
+ {
+ return_top_record(buf);
+ DBUG_PRINT("info", ("Record returned from partition %u (3)",
+ m_top_entry));
+ DBUG_RETURN(0);
+ }
+ }
+ get_next= TRUE;
+ }
+ else if (!error)
+ {
+ DBUG_PRINT("info", ("m_range_info[%u])->id: %u", part_id,
+ ((PARTITION_KEY_MULTI_RANGE *)
+ m_range_info[part_id])->id));
+ DBUG_PRINT("info", ("m_mrr_range_current->id: %u",
+ m_mrr_range_current->id));
+ memcpy(rec_buf, table->record[0], m_rec_length);
+ if (((PARTITION_KEY_MULTI_RANGE *) m_range_info[part_id])->id !=
+ m_mrr_range_current->id)
+ {
+ m_stock_range_seq[part_id]=
+ ((PARTITION_KEY_MULTI_RANGE *) m_range_info[part_id])->id;
+ DBUG_PRINT("info", ("partition queue_remove_top(2)"));
+ queue_remove_top(&m_queue);
+ if (!m_queue.elements)
+ get_next= TRUE;
+ }
+ }
+ if (get_next)
+ {
+ DBUG_PRINT("info", ("get_next route"));
+ uint i, j= 0, smallest_range_seq= UINT_MAX32;
+ for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++)
+ {
+ if (!(bitmap_is_set(&(m_part_info->read_partitions), i)))
+ continue;
+ if (!bitmap_is_set(&m_mrr_used_partitions, i))
+ continue;
+ if (smallest_range_seq > m_stock_range_seq[i])
+ smallest_range_seq= m_stock_range_seq[i];
+ }
+
+ DBUG_PRINT("info", ("smallest_range_seq: %u", smallest_range_seq));
+ if (smallest_range_seq != UINT_MAX32)
+ {
+ uchar *part_rec_buf_ptr= m_ordered_rec_buffer;
+ DBUG_PRINT("info", ("partition queue_remove_all(2)"));
+ queue_remove_all(&m_queue);
+ DBUG_PRINT("info", ("m_part_spec.start_part: %u",
+ m_part_spec.start_part));
+
+ for (i= bitmap_get_first_set(&m_part_info->read_partitions);
+ i <= m_part_spec.end_part;
+ i= bitmap_get_next_set(&m_part_info->read_partitions, i),
+ part_rec_buf_ptr+= m_priority_queue_rec_len)
+ {
+ DBUG_PRINT("info",("partition part_id: %u", i));
+ if (i < m_part_spec.start_part)
+ {
+ DBUG_PRINT("info",("partition i < m_part_spec.start_part"));
+ continue;
+ }
+ if (!bitmap_is_set(&m_mrr_used_partitions, i))
+ {
+ DBUG_PRINT("info",("partition !bitmap_is_set(&m_mrr_used_partitions, i)"));
+ continue;
+ }
+ DBUG_PRINT("info",("partition uint2korr: %u",
+ uint2korr(part_rec_buf_ptr)));
+ DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr));
+ DBUG_PRINT("info", ("partition m_stock_range_seq[%u]: %u",
+ i, m_stock_range_seq[i]));
+ if (smallest_range_seq == m_stock_range_seq[i])
+ {
+ m_stock_range_seq[i]= 0;
+ DBUG_PRINT("info", ("partition queue_insert(2)"));
+ queue_insert(&m_queue, part_rec_buf_ptr);
+ j++;
+ }
+ }
+ while (m_mrr_range_current->id < smallest_range_seq)
+ m_mrr_range_current= m_mrr_range_current->next;
+
+ DBUG_PRINT("info",("partition m_mrr_range_current: %p",
+ m_mrr_range_current));
+ DBUG_PRINT("info",("partition m_mrr_range_current->id: %u",
+ m_mrr_range_current ? m_mrr_range_current->id : 0));
+ queue_set_max_at_top(&m_queue, FALSE);
+ queue_set_cmp_arg(&m_queue, (void*) this);
+ m_queue.elements= j;
+ queue_fix(&m_queue);
+ return_top_record(buf);
+ DBUG_PRINT("info", ("Record returned from partition %u (4)",
+ m_top_entry));
+ DBUG_RETURN(0);
+ }
+ }
+ }
else if (!is_next_same)
error= file->ha_index_next(rec_buf);
else
@@ -6394,16 +7902,16 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same)
if (error)
{
- if (error == HA_ERR_END_OF_FILE)
+ if (error == HA_ERR_END_OF_FILE && m_queue.elements)
{
/* Return next buffered row */
+ DBUG_PRINT("info", ("partition queue_remove_top(3)"));
queue_remove_top(&m_queue);
if (m_queue.elements)
{
+ return_top_record(buf);
DBUG_PRINT("info", ("Record returned from partition %u (2)",
m_top_entry));
- return_top_record(buf);
- table->status= 0;
error= 0;
}
}
@@ -6439,30 +7947,35 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same)
int ha_partition::handle_ordered_prev(uchar *buf)
{
int error;
+ DBUG_ENTER("ha_partition::handle_ordered_prev");
+ DBUG_PRINT("enter", ("partition: %p", this));
+
+ if (m_top_entry == NO_CURRENT_PART_ID)
+ DBUG_RETURN(HA_ERR_END_OF_FILE);
+
uint part_id= m_top_entry;
uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS;
handler *file= m_file[part_id];
- DBUG_ENTER("ha_partition::handle_ordered_prev");
if ((error= file->ha_index_prev(rec_buf)))
{
- if (error == HA_ERR_END_OF_FILE)
+ if (error == HA_ERR_END_OF_FILE && m_queue.elements)
{
+ DBUG_PRINT("info", ("partition queue_remove_top(4)"));
queue_remove_top(&m_queue);
if (m_queue.elements)
{
return_top_record(buf);
- DBUG_PRINT("info", ("Record returned from partition %d (2)",
+ DBUG_PRINT("info", ("Record returned from partition %u (2)",
m_top_entry));
error= 0;
- table->status= 0;
}
}
DBUG_RETURN(error);
}
queue_replace_top(&m_queue);
return_top_record(buf);
- DBUG_PRINT("info", ("Record returned from partition %d", m_top_entry));
+ DBUG_PRINT("info", ("Record returned from partition %u", m_top_entry));
DBUG_RETURN(0);
}
@@ -6508,7 +8021,7 @@ int ha_partition::compare_number_of_records(ha_partition *me,
::info() is used to return information to the optimizer.
Currently this table handler doesn't implement most of the fields
really needed. SHOW also makes use of this data
- Another note, if your handler doesn't proved exact record count,
+ Another note, if your handler doesn't provide exact record count,
you will probably want to have the following in your code:
if (records < 2)
records = 2;
@@ -6614,7 +8127,8 @@ int ha_partition::info(uint flag)
{
set_if_bigger(part_share->next_auto_inc_val,
auto_increment_value);
- part_share->auto_inc_initialized= true;
+ if (can_use_for_auto_inc_init())
+ part_share->auto_inc_initialized= true;
DBUG_PRINT("info", ("initializing next_auto_inc_val to %lu",
(ulong) part_share->next_auto_inc_val));
}
@@ -6734,15 +8248,18 @@ int ha_partition::info(uint flag)
do
{
file= *file_array;
- /* Get variables if not already done */
- if (!(flag & HA_STATUS_VARIABLE) ||
- !bitmap_is_set(&(m_part_info->read_partitions),
- (uint)(file_array - m_file)))
- file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag);
- if (file->stats.records > max_records)
+ if (bitmap_is_set(&(m_opened_partitions), (uint)(file_array - m_file)))
{
- max_records= file->stats.records;
- handler_instance= i;
+ /* Get variables if not already done */
+ if (!(flag & HA_STATUS_VARIABLE) ||
+ !bitmap_is_set(&(m_part_info->read_partitions),
+ (uint) (file_array - m_file)))
+ file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag);
+ if (file->stats.records > max_records)
+ {
+ max_records= file->stats.records;
+ handler_instance= i;
+ }
}
i++;
} while (*(++file_array));
@@ -6812,6 +8329,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_STATS *stat_info,
stat_info->data_file_length= file->stats.data_file_length;
stat_info->max_data_file_length= file->stats.max_data_file_length;
stat_info->index_file_length= file->stats.index_file_length;
+ stat_info->max_index_file_length= file->stats.max_index_file_length;
stat_info->delete_length= file->stats.delete_length;
stat_info->create_time= file->stats.create_time;
stat_info->update_time= file->stats.update_time;
@@ -6823,6 +8341,95 @@ void ha_partition::get_dynamic_partition_info(PARTITION_STATS *stat_info,
}
+void ha_partition::set_partitions_to_open(List<String> *partition_names)
+{
+ m_partitions_to_open= partition_names;
+}
+
+
+int ha_partition::open_read_partitions(char *name_buff, size_t name_buff_size)
+{
+ handler **file;
+ char *name_buffer_ptr;
+ int error;
+
+ name_buffer_ptr= m_name_buffer_ptr;
+ file= m_file;
+ m_file_sample= NULL;
+ do
+ {
+ int n_file= (int)(file-m_file);
+ int is_open= bitmap_is_set(&m_opened_partitions, n_file);
+ int should_be_open= bitmap_is_set(&m_part_info->read_partitions, n_file);
+
+ if (is_open && !should_be_open)
+ {
+ if ((error= (*file)->ha_close()))
+ goto err_handler;
+ bitmap_clear_bit(&m_opened_partitions, n_file);
+ }
+ else if (!is_open && should_be_open)
+ {
+ LEX_CSTRING save_connect_string= table->s->connect_string;
+ if ((error= create_partition_name(name_buff, name_buff_size,
+ table->s->normalized_path.str,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto err_handler;
+ if (!((*file)->ht->flags & HTON_CAN_READ_CONNECT_STRING_IN_PARTITION))
+ table->s->connect_string= m_connect_string[(uint)(file-m_file)];
+ error= (*file)->ha_open(table, name_buff, m_mode,
+ m_open_test_lock | HA_OPEN_NO_PSI_CALL);
+ table->s->connect_string= save_connect_string;
+ if (error)
+ goto err_handler;
+ bitmap_set_bit(&m_opened_partitions, n_file);
+ m_last_part= n_file;
+ }
+ if (!m_file_sample && should_be_open)
+ m_file_sample= *file;
+ name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
+ } while (*(++file));
+
+err_handler:
+ return error;
+}
+
+
+int ha_partition::change_partitions_to_open(List<String> *partition_names)
+{
+ char name_buff[FN_REFLEN+1];
+ int error= 0;
+
+ if (m_is_clone_of)
+ return 0;
+
+ m_partitions_to_open= partition_names;
+ if ((error= m_part_info->set_partition_bitmaps(partition_names)))
+ goto err_handler;
+
+ if (m_lock_type != F_UNLCK)
+ {
+ /*
+ That happens after the LOCK TABLE statement.
+ Do nothing in this case.
+ */
+ return 0;
+ }
+
+ if (bitmap_cmp(&m_opened_partitions, &m_part_info->read_partitions) != 0)
+ return 0;
+
+ if ((error= read_par_file(table->s->normalized_path.str)) ||
+ (error= open_read_partitions(name_buff, sizeof(name_buff))))
+ goto err_handler;
+
+ clear_handler_file();
+
+err_handler:
+ return error;
+}
+
+
/**
General function to prepare handler for certain behavior.
@@ -7123,7 +8730,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_STATS *stat_info,
HA_EXTRA_DELETE_CANNOT_BATCH:
HA_EXTRA_UPDATE_CANNOT_BATCH:
Inform handler that delete_row()/update_row() cannot batch deletes/updates
- and should perform them immediately. This may be needed when table has
+ and should perform them immediately. This may be needed when table has
AFTER DELETE/UPDATE triggers which access to subject table.
These flags are reset by the handler::extra(HA_EXTRA_RESET) call.
@@ -7139,7 +8746,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_STATS *stat_info,
int ha_partition::extra(enum ha_extra_function operation)
{
DBUG_ENTER("ha_partition:extra");
- DBUG_PRINT("info", ("operation: %d", (int) operation));
+ DBUG_PRINT("enter", ("operation: %d", (int) operation));
switch (operation) {
/* Category 1), used by most handlers */
@@ -7160,13 +8767,13 @@ int ha_partition::extra(enum ha_extra_function operation)
{
if (!m_myisam)
DBUG_RETURN(loop_extra(operation));
- break;
}
+ break;
/* Category 3), used by MyISAM handlers */
case HA_EXTRA_PREPARE_FOR_UPDATE:
/*
- Needs to be run on the first partition in the range now, and
+ Needs to be run on the first partition in the range now, and
later in late_extra_cache, when switching to a new partition to scan.
*/
m_extra_prepare_for_update= TRUE;
@@ -7235,18 +8842,9 @@ int ha_partition::extra(enum ha_extra_function operation)
with row being inserted by PK/unique key without reporting error
to the SQL-layer.
- This optimization is not safe for partitioned table in general case
- since we may have to put new version of row into partition which is
- different from partition in which old version resides (for example
- when we partition by non-PK column or by some column which is not
- part of unique key which were violated).
- And since NDB which is the only engine at the moment that supports
- this optimization handles partitioning on its own we simple disable
- it here. (BTW for NDB this optimization is safe since it supports
- only KEY partitioning and won't use this optimization for tables
- which have additional unique constraints).
+ At this time, this is safe by limitation of ha_partition
*/
- break;
+ DBUG_RETURN(loop_extra(operation));
}
/* Category 7), used by federated handlers */
case HA_EXTRA_INSERT_WITH_UPDATE:
@@ -7260,20 +8858,42 @@ int ha_partition::extra(enum ha_extra_function operation)
}
/* Category 9) Operations only used by MERGE */
case HA_EXTRA_ADD_CHILDREN_LIST:
+ DBUG_RETURN(loop_extra(operation));
case HA_EXTRA_ATTACH_CHILDREN:
- case HA_EXTRA_IS_ATTACHED_CHILDREN:
- case HA_EXTRA_DETACH_CHILDREN:
{
- /* Special actions for MERGE tables. Ignore. */
+ int result;
+ uint num_locks;
+ handler **file;
+ if ((result= loop_extra(operation)))
+ DBUG_RETURN(result);
+
+ /* Recalculate lock count as each child may have different set of locks */
+ num_locks= 0;
+ file= m_file;
+ do
+ {
+ num_locks+= (*file)->lock_count();
+ } while (*(++file));
+
+ m_num_locks= num_locks;
break;
}
+ case HA_EXTRA_IS_ATTACHED_CHILDREN:
+ DBUG_RETURN(loop_extra(operation));
+ case HA_EXTRA_DETACH_CHILDREN:
+ DBUG_RETURN(loop_extra(operation));
+ case HA_EXTRA_MARK_AS_LOG_TABLE:
/*
http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html
says we no longer support logging to partitioned tables, so we fail
here.
*/
- case HA_EXTRA_MARK_AS_LOG_TABLE:
DBUG_RETURN(ER_UNSUPORTED_LOG_ENGINE);
+ case HA_EXTRA_STARTING_ORDERED_INDEX_SCAN:
+ case HA_EXTRA_BEGIN_ALTER_COPY:
+ case HA_EXTRA_END_ALTER_COPY:
+ case HA_EXTRA_FAKE_START_STMT:
+ DBUG_RETURN(loop_extra(operation));
default:
{
/* Temporary crash to discover what is wrong */
@@ -7309,7 +8929,8 @@ int ha_partition::reset(void)
i < m_tot_parts;
i= bitmap_get_next_set(&m_partitions_to_reset, i))
{
- if ((tmp= m_file[i]->ha_reset()))
+ if (bitmap_is_set(&m_opened_partitions, i) &&
+ (tmp= m_file[i]->ha_reset()))
result= tmp;
}
bitmap_clear_all(&m_partitions_to_reset);
@@ -7354,7 +8975,7 @@ int ha_partition::extra_opt(enum ha_extra_function operation, ulong cachesize)
void ha_partition::prepare_extra_cache(uint cachesize)
{
DBUG_ENTER("ha_partition::prepare_extra_cache()");
- DBUG_PRINT("info", ("cachesize %u", cachesize));
+ DBUG_PRINT("enter", ("cachesize %u", cachesize));
m_extra_cache= TRUE;
m_extra_cache_size= cachesize;
@@ -7421,12 +9042,17 @@ int ha_partition::loop_extra(enum ha_extra_function operation)
int result= 0, tmp;
uint i;
DBUG_ENTER("ha_partition::loop_extra()");
-
+
for (i= bitmap_get_first_set(&m_part_info->lock_partitions);
i < m_tot_parts;
i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
{
- if ((tmp= m_file[i]->extra(operation)))
+ /*
+ This can be called after an error in ha_open.
+ In this case calling 'extra' can crash.
+ */
+ if (bitmap_is_set(&m_opened_partitions, i) &&
+ (tmp= m_file[i]->extra(operation)))
result= tmp;
}
/* Add all used partitions to be called in reset(). */
@@ -7450,9 +9076,9 @@ void ha_partition::late_extra_cache(uint partition_id)
{
handler *file;
DBUG_ENTER("ha_partition::late_extra_cache");
- DBUG_PRINT("info", ("extra_cache %u prepare %u partid %u size %u",
- m_extra_cache, m_extra_prepare_for_update,
- partition_id, m_extra_cache_size));
+ DBUG_PRINT("enter", ("extra_cache %u prepare %u partid %u size %u",
+ m_extra_cache, m_extra_prepare_for_update,
+ partition_id, m_extra_cache_size));
if (!m_extra_cache && !m_extra_prepare_for_update)
DBUG_VOID_RETURN;
@@ -7516,7 +9142,7 @@ void ha_partition::late_extra_no_cache(uint partition_id)
const key_map *ha_partition::keys_to_use_for_scanning()
{
DBUG_ENTER("ha_partition::keys_to_use_for_scanning");
- DBUG_RETURN(m_file[0]->keys_to_use_for_scanning());
+ DBUG_RETURN(get_open_file_sample()->keys_to_use_for_scanning());
}
@@ -7649,7 +9275,7 @@ ha_rows ha_partition::records_in_range(uint inx, key_range *min_key,
!= NO_CURRENT_PART_ID)
{
rows= m_file[part_id]->records_in_range(inx, min_key, max_key);
-
+
DBUG_PRINT("info", ("part %u match %lu rows of %lu", part_id, (ulong) rows,
(ulong) m_file[part_id]->stats.records));
@@ -7739,7 +9365,7 @@ double ha_partition::read_time(uint index, uint ranges, ha_rows rows)
{
DBUG_ENTER("ha_partition::read_time");
- DBUG_RETURN(m_file[0]->read_time(index, ranges, rows));
+ DBUG_RETURN(get_open_file_sample()->read_time(index, ranges, rows));
}
@@ -7751,7 +9377,8 @@ double ha_partition::read_time(uint index, uint ranges, ha_rows rows)
ha_rows ha_partition::records()
{
- ha_rows rows, tot_rows= 0;
+ int error;
+ ha_rows tot_rows= 0;
uint i;
DBUG_ENTER("ha_partition::records");
@@ -7759,11 +9386,13 @@ ha_rows ha_partition::records()
i < m_tot_parts;
i= bitmap_get_next_set(&m_part_info->read_partitions, i))
{
- rows= m_file[i]->records();
- if (rows == HA_POS_ERROR)
+ ha_rows rows;
+ if ((error= m_file[i]->pre_records()) ||
+ (rows= m_file[i]->records()) == HA_POS_ERROR)
DBUG_RETURN(HA_POS_ERROR);
tot_rows+= rows;
}
+ DBUG_PRINT("exit", ("records: %lld", (longlong) tot_rows));
DBUG_RETURN(tot_rows);
}
@@ -7787,7 +9416,7 @@ bool ha_partition::can_switch_engines()
{
handler **file;
DBUG_ENTER("ha_partition::can_switch_engines");
-
+
file= m_file;
do
{
@@ -8022,10 +9651,9 @@ void ha_partition::print_error(int error, myf errflag)
{
THD *thd= ha_thd();
DBUG_ENTER("ha_partition::print_error");
-
- /* Should probably look for my own errors first */
DBUG_PRINT("enter", ("error: %d", error));
+ /* Should probably look for my own errors first */
if ((error == HA_ERR_NO_PARTITION_FOUND) &&
! (thd->lex->alter_info.flags & Alter_info::ALTER_TRUNCATE_PARTITION))
{
@@ -8050,7 +9678,7 @@ void ha_partition::print_error(int error, myf errflag)
str.append("(");
str.append_ulonglong(m_last_part);
str.append(" != ");
- if (get_part_for_delete(m_err_rec, m_rec0, m_part_info, &part_id))
+ if (get_part_for_buf(m_err_rec, m_rec0, m_part_info, &part_id))
str.append("?");
else
str.append_ulonglong(part_id);
@@ -8142,9 +9770,9 @@ handler::Table_flags ha_partition::table_flags() const
alter_table_flags must be on handler/table level, not on hton level
due to the ha_partition hton does not know what the underlying hton is.
*/
-uint ha_partition::alter_table_flags(uint flags)
+ulonglong ha_partition::alter_table_flags(ulonglong flags)
{
- uint flags_to_return;
+ ulonglong flags_to_return;
DBUG_ENTER("ha_partition::alter_table_flags");
flags_to_return= ht->alter_table_flags(flags);
@@ -8160,20 +9788,36 @@ uint ha_partition::alter_table_flags(uint flags)
bool ha_partition::check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{
- handler **file;
- bool ret= COMPATIBLE_DATA_YES;
-
/*
The check for any partitioning related changes have already been done
in mysql_alter_table (by fix_partition_func), so it is only up to
the underlying handlers.
*/
- for (file= m_file; *file; file++)
- if ((ret= (*file)->check_if_incompatible_data(create_info,
- table_changes)) !=
- COMPATIBLE_DATA_YES)
- break;
- return ret;
+ List_iterator<partition_element> part_it(m_part_info->partitions);
+ HA_CREATE_INFO dummy_info= *create_info;
+ uint i=0;
+ while (partition_element *part_elem= part_it++)
+ {
+ if (m_is_sub_partitioned)
+ {
+ List_iterator<partition_element> subpart_it(part_elem->subpartitions);
+ while (partition_element *sub_elem= subpart_it++)
+ {
+ dummy_info.data_file_name= sub_elem->data_file_name;
+ dummy_info.index_file_name= sub_elem->index_file_name;
+ if (m_file[i++]->check_if_incompatible_data(&dummy_info, table_changes))
+ return COMPATIBLE_DATA_NO;
+ }
+ }
+ else
+ {
+ dummy_info.data_file_name= part_elem->data_file_name;
+ dummy_info.index_file_name= part_elem->index_file_name;
+ if (m_file[i++]->check_if_incompatible_data(&dummy_info, table_changes))
+ return COMPATIBLE_DATA_NO;
+ }
+ }
+ return COMPATIBLE_DATA_YES;
}
@@ -8512,7 +10156,7 @@ uint ha_partition::min_record_length(uint options) const
the same record. Otherwise we use the particular handler to decide if
they are the same. Sort in partition id order if not equal.
- MariaDB note:
+ MariaDB note:
Please don't merge the code from MySQL that does this:
We get two references and need to check if those records are the same.
@@ -8526,15 +10170,18 @@ uint ha_partition::min_record_length(uint options) const
int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2)
{
int cmp;
- my_ptrdiff_t diff1, diff2;
+ uint32 diff1, diff2;
DBUG_ENTER("ha_partition::cmp_ref");
- cmp = m_file[0]->cmp_ref((ref1 + PARTITION_BYTES_IN_POS),
- (ref2 + PARTITION_BYTES_IN_POS));
+ cmp= get_open_file_sample()->cmp_ref((ref1 + PARTITION_BYTES_IN_POS),
+ (ref2 + PARTITION_BYTES_IN_POS));
if (cmp)
DBUG_RETURN(cmp);
- if ((ref1[0] == ref2[0]) && (ref1[1] == ref2[1]))
+ diff2= uint2korr(ref2);
+ diff1= uint2korr(ref1);
+
+ if (diff1 == diff2)
{
/* This means that the references are same and are in same partition.*/
DBUG_RETURN(0);
@@ -8547,22 +10194,7 @@ int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2)
Remove this assert if DB_ROW_ID is changed to be per partition.
*/
DBUG_ASSERT(!m_innodb);
-
- diff1= ref2[1] - ref1[1];
- diff2= ref2[0] - ref1[0];
- if (diff1 > 0)
- {
- DBUG_RETURN(-1);
- }
- if (diff1 < 0)
- {
- DBUG_RETURN(+1);
- }
- if (diff2 > 0)
- {
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(+1);
+ DBUG_RETURN(diff2 > diff1 ? -1 : 1);
}
@@ -8571,6 +10203,82 @@ int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2)
****************************************************************************/
+/**
+ Retreive new values for part_share->next_auto_inc_val if needed
+
+ This is needed if the value has not been initialized or if one of
+ the underlying partitions require that the value should be re-calculated
+*/
+
+void ha_partition::update_next_auto_inc_val()
+{
+ if (!part_share->auto_inc_initialized ||
+ need_info_for_auto_inc())
+ info(HA_STATUS_AUTO);
+}
+
+
+/**
+ Determine whether a partition needs auto-increment initialization.
+
+ @return
+ TRUE A partition needs auto-increment initialization
+ FALSE No partition needs auto-increment initialization
+
+ Resets part_share->auto_inc_initialized if next auto_increment needs to be
+ recalculated.
+*/
+
+bool ha_partition::need_info_for_auto_inc()
+{
+ handler **file= m_file;
+ DBUG_ENTER("ha_partition::need_info_for_auto_inc");
+
+ do
+ {
+ if ((*file)->need_info_for_auto_inc())
+ {
+ /* We have to get new auto_increment values from handler */
+ part_share->auto_inc_initialized= FALSE;
+ DBUG_RETURN(TRUE);
+ }
+ } while (*(++file));
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Determine if all partitions can use the current auto-increment value for
+ auto-increment initialization.
+
+ @return
+ TRUE All partitions can use the current auto-increment
+ value for auto-increment initialization
+ FALSE All partitions cannot use the current
+ auto-increment value for auto-increment
+ initialization
+
+ Notes
+ This function is only called for ::info(HA_STATUS_AUTO) and is
+ mainly used by the Spider engine, which returns false
+ except in the case of DROP TABLE or ALTER TABLE when it returns TRUE.
+ Other engines always returns TRUE for this call.
+*/
+
+bool ha_partition::can_use_for_auto_inc_init()
+{
+ handler **file= m_file;
+ DBUG_ENTER("ha_partition::can_use_for_auto_inc_init");
+
+ do
+ {
+ if (!(*file)->can_use_for_auto_inc_init())
+ DBUG_RETURN(FALSE);
+ } while (*(++file));
+ DBUG_RETURN(TRUE);
+}
+
+
int ha_partition::reset_auto_increment(ulonglong value)
{
handler **file= m_file;
@@ -8604,8 +10312,8 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong *nb_reserved_values)
{
DBUG_ENTER("ha_partition::get_auto_increment");
- DBUG_PRINT("info", ("offset: %lu inc: %lu desired_values: %lu "
- "first_value: %lu", (ulong) offset, (ulong) increment,
+ DBUG_PRINT("enter", ("offset: %lu inc: %lu desired_values: %lu "
+ "first_value: %lu", (ulong) offset, (ulong) increment,
(ulong) nb_desired_values, (ulong) *first_value));
DBUG_ASSERT(increment && nb_desired_values);
*first_value= 0;
@@ -8649,7 +10357,7 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
/*
Get a lock for handling the auto_increment in part_share
for avoiding two concurrent statements getting the same number.
- */
+ */
lock_auto_increment();
@@ -8660,8 +10368,8 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
based replication. Because the statement-based binary log contains
only the first generated value used by the statement, and slaves assumes
all other generated values used by this statement were consecutive to
- this first one, we must exclusively lock the generator until the statement
- is done.
+ this first one, we must exclusively lock the generator until the
+ statement is done.
*/
if (!auto_increment_safe_stmt_log_lock &&
thd->lex->sql_command != SQLCOM_INSERT &&
@@ -8924,8 +10632,8 @@ int ha_partition::check_misplaced_rows(uint read_part_id, bool do_repair)
}
else
{
- DBUG_PRINT("info", ("Moving row from partition %d to %d",
- read_part_id, correct_part_id));
+ DBUG_PRINT("info", ("Moving row from partition %u to %u",
+ (uint) read_part_id, (uint) correct_part_id));
/*
Insert row into correct partition. Notice that there are no commit
@@ -8956,19 +10664,19 @@ int ha_partition::check_misplaced_rows(uint read_part_id, bool do_repair)
{
/* Log this error, so the DBA can notice it and fix it! */
sql_print_error("Table '%-192s' failed to move/insert a row"
- " from part %d into part %d:\n%s",
+ " from part %u into part %u:\n%s",
table->s->table_name.str,
- read_part_id,
- correct_part_id,
+ (uint) read_part_id,
+ (uint) correct_part_id,
str.c_ptr_safe());
}
print_admin_msg(ha_thd(), MYSQL_ERRMSG_SIZE, "error",
table_share->db.str, table->alias,
opt_op_name[REPAIR_PARTS],
"Failed to move/insert a row"
- " from part %d into part %d:\n%s",
- read_part_id,
- correct_part_id,
+ " from part %u into part %u:\n%s",
+ (uint) read_part_id,
+ (uint) correct_part_id,
str.c_ptr_safe());
break;
}
@@ -8989,14 +10697,14 @@ int ha_partition::check_misplaced_rows(uint read_part_id, bool do_repair)
append_row_to_str(str);
/* Log this error, so the DBA can notice it and fix it! */
- sql_print_error("Table '%-192s': Delete from part %d failed with"
+ sql_print_error("Table '%-192s': Delete from part %u failed with"
" error %d. But it was already inserted into"
- " part %d, when moving the misplaced row!"
+ " part %u, when moving the misplaced row!"
"\nPlease manually fix the duplicate row:\n%s",
table->s->table_name.str,
- read_part_id,
+ (uint) read_part_id,
result,
- correct_part_id,
+ (uint) correct_part_id,
str.c_ptr_safe());
break;
}
@@ -9074,10 +10782,8 @@ int ha_partition::check_for_upgrade(HA_CHECK_OPT *check_opt)
partition_info::enum_key_algorithm old_algorithm;
old_algorithm= m_part_info->key_algorithm;
error= HA_ADMIN_FAILED;
- append_identifier(ha_thd(), &db_name, table_share->db.str,
- table_share->db.length);
- append_identifier(ha_thd(), &table_name, table_share->table_name.str,
- table_share->table_name.length);
+ append_identifier(ha_thd(), &db_name, &table_share->db);
+ append_identifier(ha_thd(), &table_name, &table_share->table_name);
if (m_part_info->key_algorithm != partition_info::KEY_ALGORITHM_NONE)
{
/*
@@ -9126,6 +10832,670 @@ int ha_partition::check_for_upgrade(HA_CHECK_OPT *check_opt)
}
+TABLE_LIST *ha_partition::get_next_global_for_child()
+{
+ handler **file;
+ DBUG_ENTER("ha_partition::get_next_global_for_child");
+ for (file= m_file; *file; file++)
+ {
+ TABLE_LIST *table_list;
+ if ((table_list= (*file)->get_next_global_for_child()))
+ DBUG_RETURN(table_list);
+ }
+ DBUG_RETURN(0);
+}
+
+
+const COND *ha_partition::cond_push(const COND *cond)
+{
+ handler **file= m_file;
+ COND *res_cond= NULL;
+ DBUG_ENTER("ha_partition::cond_push");
+
+ if (set_top_table_fields)
+ {
+ /*
+ We want to do this in a separate loop to not come into a situation
+ where we have only done cond_push() to some of the tables
+ */
+ do
+ {
+ if (((*file)->set_top_table_and_fields(top_table,
+ top_table_field,
+ top_table_fields)))
+ DBUG_RETURN(cond); // Abort cond push, no error
+ } while (*(++file));
+ file= m_file;
+ }
+
+ do
+ {
+ if ((*file)->pushed_cond != cond)
+ {
+ if ((*file)->cond_push(cond))
+ res_cond= (COND *) cond;
+ else
+ (*file)->pushed_cond= cond;
+ }
+ } while (*(++file));
+ DBUG_RETURN(res_cond);
+}
+
+
+void ha_partition::cond_pop()
+{
+ handler **file= m_file;
+ DBUG_ENTER("ha_partition::cond_push");
+
+ do
+ {
+ (*file)->cond_pop();
+ } while (*(++file));
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ Perform bulk update preparation on each partition.
+
+ SYNOPSIS
+ start_bulk_update()
+
+ RETURN VALUE
+ TRUE Error
+ FALSE Success
+*/
+
+bool ha_partition::start_bulk_update()
+{
+ handler **file= m_file;
+ DBUG_ENTER("ha_partition::start_bulk_update");
+
+ if (bitmap_is_overlapping(&m_part_info->full_part_field_set,
+ table->write_set))
+ DBUG_RETURN(TRUE);
+
+ do
+ {
+ if ((*file)->start_bulk_update())
+ DBUG_RETURN(TRUE);
+ } while (*(++file));
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Perform bulk update execution on each partition. A bulk update allows
+ a handler to batch the updated rows instead of performing the updates
+ one row at a time.
+
+ SYNOPSIS
+ exec_bulk_update()
+
+ RETURN VALUE
+ TRUE Error
+ FALSE Success
+*/
+
+int ha_partition::exec_bulk_update(ha_rows *dup_key_found)
+{
+ int error;
+ handler **file= m_file;
+ DBUG_ENTER("ha_partition::exec_bulk_update");
+
+ do
+ {
+ if ((error= (*file)->exec_bulk_update(dup_key_found)))
+ DBUG_RETURN(error);
+ } while (*(++file));
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Perform bulk update cleanup on each partition.
+
+ SYNOPSIS
+ end_bulk_update()
+
+ RETURN VALUE
+ NONE
+*/
+
+int ha_partition::end_bulk_update()
+{
+ int error= 0;
+ handler **file= m_file;
+ DBUG_ENTER("ha_partition::end_bulk_update");
+
+ do
+ {
+ int tmp;
+ if ((tmp= (*file)->end_bulk_update()))
+ error= tmp;
+ } while (*(++file));
+ DBUG_RETURN(error);
+}
+
+
+/**
+ Add the row to the bulk update on the partition on which the row is stored.
+ A bulk update allows a handler to batch the updated rows instead of
+ performing the updates one row at a time.
+
+ SYNOPSIS
+ bulk_update_row()
+ old_data Old record
+ new_data New record
+ dup_key_found Number of duplicate keys found
+
+ RETURN VALUE
+ >1 Error
+ 1 Bulk update not used, normal operation used
+ 0 Bulk update used by handler
+*/
+
+int ha_partition::bulk_update_row(const uchar *old_data, const uchar *new_data,
+ ha_rows *dup_key_found)
+{
+ int error= 0;
+ uint32 part_id;
+ longlong func_value;
+ my_bitmap_map *old_map;
+ DBUG_ENTER("ha_partition::bulk_update_row");
+
+ old_map= dbug_tmp_use_all_columns(table, table->read_set);
+ error= m_part_info->get_partition_id(m_part_info, &part_id,
+ &func_value);
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+ if (unlikely(error))
+ {
+ m_part_info->err_value= func_value;
+ goto end;
+ }
+
+ error= m_file[part_id]->ha_bulk_update_row(old_data, new_data,
+ dup_key_found);
+
+end:
+ DBUG_RETURN(error);
+}
+
+
+/**
+ Perform bulk delete preparation on each partition.
+
+ SYNOPSIS
+ start_bulk_delete()
+
+ RETURN VALUE
+ TRUE Error
+ FALSE Success
+*/
+
+bool ha_partition::start_bulk_delete()
+{
+ handler **file= m_file;
+ DBUG_ENTER("ha_partition::start_bulk_delete");
+
+ do
+ {
+ if ((*file)->start_bulk_delete())
+ DBUG_RETURN(TRUE);
+ } while (*(++file));
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Perform bulk delete cleanup on each partition.
+
+ SYNOPSIS
+ end_bulk_delete()
+
+ RETURN VALUE
+ >0 Error
+ 0 Success
+*/
+
+int ha_partition::end_bulk_delete()
+{
+ int error= 0;
+ handler **file= m_file;
+ DBUG_ENTER("ha_partition::end_bulk_delete");
+
+ do
+ {
+ int tmp;
+ if ((tmp= (*file)->end_bulk_delete()))
+ error= tmp;
+ } while (*(++file));
+ DBUG_RETURN(error);
+}
+
+
+/**
+ Perform initialization for a direct update request.
+
+ SYNOPSIS
+ direct_update_rows_init()
+
+ RETURN VALUE
+ >0 Error
+ 0 Success
+*/
+
+int ha_partition::direct_update_rows_init()
+{
+ int error;
+ uint i, found;
+ handler *file;
+ DBUG_ENTER("ha_partition::direct_update_rows_init");
+
+ if (bitmap_is_overlapping(&m_part_info->full_part_field_set,
+ table->write_set))
+ {
+ DBUG_PRINT("info", ("partition FALSE by updating part_key"));
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ }
+
+ m_part_spec.start_part= 0;
+ m_part_spec.end_part= m_tot_parts - 1;
+ m_direct_update_part_spec= m_part_spec;
+
+ found= 0;
+ for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++)
+ {
+ if (bitmap_is_set(&(m_part_info->read_partitions), i) &&
+ bitmap_is_set(&(m_part_info->lock_partitions), i))
+ {
+ file= m_file[i];
+ if ((error= (m_pre_calling ?
+ file->pre_direct_update_rows_init() :
+ file->direct_update_rows_init())))
+ {
+ DBUG_PRINT("info", ("partition FALSE by storage engine"));
+ DBUG_RETURN(error);
+ }
+ found++;
+ }
+ }
+
+ TABLE_LIST *table_list= table->pos_in_table_list;
+ if (found != 1 && table_list)
+ {
+ while (table_list->parent_l)
+ table_list= table_list->parent_l;
+ st_select_lex *select_lex= table_list->select_lex;
+ DBUG_PRINT("info", ("partition select_lex: %p", select_lex));
+ if (select_lex && select_lex->explicit_limit)
+ {
+ DBUG_PRINT("info", ("partition explicit_limit=TRUE"));
+ DBUG_PRINT("info", ("partition offset_limit: %p",
+ select_lex->offset_limit));
+ DBUG_PRINT("info", ("partition select_limit: %p",
+ select_lex->select_limit));
+ DBUG_PRINT("info", ("partition FALSE by select_lex"));
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ }
+ }
+ DBUG_PRINT("info", ("partition OK"));
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Do initialization for performing parallel direct update
+ for a handlersocket update request.
+
+ SYNOPSIS
+ pre_direct_update_rows_init()
+
+ RETURN VALUE
+ >0 Error
+ 0 Success
+*/
+
+int ha_partition::pre_direct_update_rows_init()
+{
+ bool save_m_pre_calling;
+ int error;
+ DBUG_ENTER("ha_partition::pre_direct_update_rows_init");
+ save_m_pre_calling= m_pre_calling;
+ m_pre_calling= TRUE;
+ error= direct_update_rows_init();
+ m_pre_calling= save_m_pre_calling;
+ DBUG_RETURN(error);
+}
+
+
+/**
+ Execute a direct update request. A direct update request updates all
+ qualified rows in a single operation, rather than one row at a time.
+ The direct update operation is pushed down to each individual
+ partition.
+
+ SYNOPSIS
+ direct_update_rows()
+ update_rows Number of updated rows
+
+ RETURN VALUE
+ >0 Error
+ 0 Success
+*/
+
+int ha_partition::direct_update_rows(ha_rows *update_rows_result)
+{
+ int error;
+ bool rnd_seq= FALSE;
+ ha_rows update_rows= 0;
+ uint32 i;
+ DBUG_ENTER("ha_partition::direct_update_rows");
+
+ /* If first call to direct_update_rows with RND scan */
+ if ((m_pre_calling ? pre_inited : inited) == RND && m_scan_value == 1)
+ {
+ rnd_seq= TRUE;
+ m_scan_value= 2;
+ }
+
+ *update_rows_result= 0;
+ for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++)
+ {
+ handler *file= m_file[i];
+ if (bitmap_is_set(&(m_part_info->read_partitions), i) &&
+ bitmap_is_set(&(m_part_info->lock_partitions), i))
+ {
+ if (rnd_seq && (m_pre_calling ? file->pre_inited : file->inited) == NONE)
+ {
+ if ((error= (m_pre_calling ?
+ file->ha_pre_rnd_init(TRUE) :
+ file->ha_rnd_init(TRUE))))
+ DBUG_RETURN(error);
+ }
+ if ((error= (m_pre_calling ?
+ (file)->pre_direct_update_rows() :
+ (file)->ha_direct_update_rows(&update_rows))))
+ {
+ if (rnd_seq)
+ {
+ if (m_pre_calling)
+ file->ha_pre_rnd_end();
+ else
+ file->ha_rnd_end();
+ }
+ DBUG_RETURN(error);
+ }
+ *update_rows_result+= update_rows;
+ }
+ if (rnd_seq)
+ {
+ if ((error= (m_pre_calling ?
+ file->ha_pre_index_or_rnd_end() :
+ file->ha_index_or_rnd_end())))
+ DBUG_RETURN(error);
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Start parallel execution of a direct update for a handlersocket update
+ request. A direct update request updates all qualified rows in a single
+ operation, rather than one row at a time. The direct update operation
+ is pushed down to each individual partition.
+
+ SYNOPSIS
+ pre_direct_update_rows()
+
+ RETURN VALUE
+ >0 Error
+ 0 Success
+*/
+
+int ha_partition::pre_direct_update_rows()
+{
+ bool save_m_pre_calling;
+ int error;
+ ha_rows not_used= 0;
+ DBUG_ENTER("ha_partition::pre_direct_update_rows");
+ save_m_pre_calling= m_pre_calling;
+ m_pre_calling= TRUE;
+ error= direct_update_rows(&not_used);
+ m_pre_calling= save_m_pre_calling;
+ DBUG_RETURN(error);
+}
+
+
+/**
+ Perform initialization for a direct delete request.
+
+ SYNOPSIS
+ direct_delete_rows_init()
+
+ RETURN VALUE
+ >0 Error
+ 0 Success
+*/
+
+int ha_partition::direct_delete_rows_init()
+{
+ int error;
+ uint i, found;
+ DBUG_ENTER("ha_partition::direct_delete_rows_init");
+
+ m_part_spec.start_part= 0;
+ m_part_spec.end_part= m_tot_parts - 1;
+ m_direct_update_part_spec= m_part_spec;
+
+ found= 0;
+ for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++)
+ {
+ if (bitmap_is_set(&(m_part_info->read_partitions), i) &&
+ bitmap_is_set(&(m_part_info->lock_partitions), i))
+ {
+ handler *file= m_file[i];
+ if ((error= (m_pre_calling ?
+ file->pre_direct_delete_rows_init() :
+ file->direct_delete_rows_init())))
+ {
+ DBUG_PRINT("exit", ("error in direct_delete_rows_init"));
+ DBUG_RETURN(error);
+ }
+ found++;
+ }
+ }
+
+ TABLE_LIST *table_list= table->pos_in_table_list;
+ if (found != 1 && table_list)
+ {
+ while (table_list->parent_l)
+ table_list= table_list->parent_l;
+ st_select_lex *select_lex= table_list->select_lex;
+ DBUG_PRINT("info", ("partition select_lex: %p", select_lex));
+ if (select_lex && select_lex->explicit_limit)
+ {
+ DBUG_PRINT("info", ("partition explicit_limit: TRUE"));
+ DBUG_PRINT("info", ("partition offset_limit: %p",
+ select_lex->offset_limit));
+ DBUG_PRINT("info", ("partition select_limit: %p",
+ select_lex->select_limit));
+ DBUG_PRINT("info", ("partition FALSE by select_lex"));
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ }
+ }
+ DBUG_PRINT("exit", ("OK"));
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Do initialization for performing parallel direct delete
+ for a handlersocket delete request.
+
+ SYNOPSIS
+ pre_direct_delete_rows_init()
+
+ RETURN VALUE
+ >0 Error
+ 0 Success
+*/
+
+int ha_partition::pre_direct_delete_rows_init()
+{
+ bool save_m_pre_calling;
+ int error;
+ DBUG_ENTER("ha_partition::pre_direct_delete_rows_init");
+ save_m_pre_calling= m_pre_calling;
+ m_pre_calling= TRUE;
+ error= direct_delete_rows_init();
+ m_pre_calling= save_m_pre_calling;
+ DBUG_RETURN(error);
+}
+
+
+/**
+ Execute a direct delete request. A direct delete request deletes all
+ qualified rows in a single operation, rather than one row at a time.
+ The direct delete operation is pushed down to each individual
+ partition.
+
+ SYNOPSIS
+ direct_delete_rows()
+ delete_rows Number of deleted rows
+
+ RETURN VALUE
+ >0 Error
+ 0 Success
+*/
+
+int ha_partition::direct_delete_rows(ha_rows *delete_rows_result)
+{
+ int error;
+ bool rnd_seq= FALSE;
+ ha_rows delete_rows= 0;
+ uint32 i;
+ handler *file;
+ DBUG_ENTER("ha_partition::direct_delete_rows");
+
+ if ((m_pre_calling ? pre_inited : inited) == RND && m_scan_value == 1)
+ {
+ rnd_seq= TRUE;
+ m_scan_value= 2;
+ }
+
+ *delete_rows_result= 0;
+ m_part_spec= m_direct_update_part_spec;
+ for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++)
+ {
+ file= m_file[i];
+ if (bitmap_is_set(&(m_part_info->read_partitions), i) &&
+ bitmap_is_set(&(m_part_info->lock_partitions), i))
+ {
+ if (rnd_seq && (m_pre_calling ? file->pre_inited : file->inited) == NONE)
+ {
+ if ((error= (m_pre_calling ?
+ file->ha_pre_rnd_init(TRUE) :
+ file->ha_rnd_init(TRUE))))
+ DBUG_RETURN(error);
+ }
+ if ((error= (m_pre_calling ?
+ file->pre_direct_delete_rows() :
+ file->ha_direct_delete_rows(&delete_rows))))
+ {
+ if (m_pre_calling)
+ file->ha_pre_rnd_end();
+ else
+ file->ha_rnd_end();
+ DBUG_RETURN(error);
+ }
+ delete_rows_result+= delete_rows;
+ }
+ if (rnd_seq)
+ {
+ if ((error= (m_pre_calling ?
+ file->ha_pre_index_or_rnd_end() :
+ file->ha_index_or_rnd_end())))
+ DBUG_RETURN(error);
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Start parallel execution of a direct delete for a handlersocket delete
+ request. A direct delete request deletes all qualified rows in a single
+ operation, rather than one row at a time. The direct delete operation
+ is pushed down to each individual partition.
+
+ SYNOPSIS
+ pre_direct_delete_rows()
+
+ RETURN VALUE
+ >0 Error
+ 0 Success
+*/
+
+int ha_partition::pre_direct_delete_rows()
+{
+ bool save_m_pre_calling;
+ int error;
+ ha_rows not_used;
+ DBUG_ENTER("ha_partition::pre_direct_delete_rows");
+ save_m_pre_calling= m_pre_calling;
+ m_pre_calling= TRUE;
+ error= direct_delete_rows(&not_used);
+ m_pre_calling= save_m_pre_calling;
+ DBUG_RETURN(error);
+}
+
+/**
+ Push metadata for the current operation down to each partition.
+
+ SYNOPSIS
+ info_push()
+
+ RETURN VALUE
+ >0 Error
+ 0 Success
+*/
+
+int ha_partition::info_push(uint info_type, void *info)
+{
+ int error= 0;
+ handler **file= m_file;
+ DBUG_ENTER("ha_partition::info_push");
+
+ do
+ {
+ int tmp;
+ if ((tmp= (*file)->info_push(info_type, info)))
+ error= tmp;
+ } while (*(++file));
+ DBUG_RETURN(error);
+}
+
+
+void ha_partition::clear_top_table_fields()
+{
+ handler **file;
+ DBUG_ENTER("ha_partition::clear_top_table_fields");
+
+ if (set_top_table_fields)
+ {
+ set_top_table_fields= FALSE;
+ top_table= NULL;
+ top_table_field= NULL;
+ top_table_fields= 0;
+ for (file= m_file; *file; file++)
+ (*file)->clear_top_table_fields();
+ }
+ DBUG_VOID_RETURN;
+}
+
+
struct st_mysql_storage_engine partition_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 0402908c640..534b6335e79 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -67,6 +67,21 @@ public:
}
};
+class ha_partition;
+
+/* Partition Full Text Search info */
+struct st_partition_ft_info
+{
+ struct _ft_vft *please;
+ st_partition_ft_info *next;
+ ha_partition *file;
+ FT_INFO **part_ft_info;
+};
+
+
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+extern PSI_mutex_key key_partition_auto_inc_mutex;
+#endif
/**
Partition specific Handler_share.
@@ -85,27 +100,116 @@ public:
HASH partition_name_hash;
/** Storage for each partitions Handler_share */
Parts_share_refs partitions_share_refs;
- Partition_share() {}
+ Partition_share()
+ : auto_inc_initialized(false),
+ next_auto_inc_val(0),
+ partition_name_hash_initialized(false),
+ partition_names(NULL)
+ {
+ mysql_mutex_init(key_partition_auto_inc_mutex,
+ &auto_inc_mutex,
+ MY_MUTEX_INIT_FAST);
+ }
+
~Partition_share()
{
- DBUG_ENTER("Partition_share::~Partition_share");
mysql_mutex_destroy(&auto_inc_mutex);
+ if (partition_names)
+ {
+ my_free(partition_names);
+ }
if (partition_name_hash_initialized)
+ {
my_hash_free(&partition_name_hash);
- DBUG_VOID_RETURN;
+ }
}
+
bool init(uint num_parts);
- void lock_auto_inc()
+
+ /**
+ Release reserved auto increment values not used.
+ @param thd Thread.
+ @param table_share Table Share
+ @param next_insert_id Next insert id (first non used auto inc value).
+ @param max_reserved End of reserved auto inc range.
+ */
+ void release_auto_inc_if_possible(THD *thd, TABLE_SHARE *table_share,
+ const ulonglong next_insert_id,
+ const ulonglong max_reserved);
+
+ /** lock mutex protecting auto increment value next_auto_inc_val. */
+ inline void lock_auto_inc()
{
mysql_mutex_lock(&auto_inc_mutex);
}
- void unlock_auto_inc()
+ /** unlock mutex protecting auto increment value next_auto_inc_val. */
+ inline void unlock_auto_inc()
{
mysql_mutex_unlock(&auto_inc_mutex);
}
+ /**
+ Populate partition_name_hash with partition and subpartition names
+ from part_info.
+ @param part_info Partition info containing all partitions metadata.
+
+ @return Operation status.
+ @retval false Success.
+ @retval true Failure.
+ */
+ bool populate_partition_name_hash(partition_info *part_info);
+ /** Get partition name.
+
+ @param part_id Partition id (for subpartitioned table only subpartition
+ names will be returned.)
+
+ @return partition name or NULL if error.
+ */
+ const char *get_partition_name(size_t part_id) const;
+private:
+ const uchar **partition_names;
+ /**
+ Insert [sub]partition name into partition_name_hash
+ @param name Partition name.
+ @param part_id Partition id.
+ @param is_subpart True if subpartition else partition.
+
+ @return Operation status.
+ @retval false Success.
+ @retval true Failure.
+ */
+ bool insert_partition_name_in_hash(const char *name,
+ uint part_id,
+ bool is_subpart);
};
+typedef struct st_partition_key_multi_range
+{
+ uint id;
+ uchar *key[2];
+ uint length[2];
+ KEY_MULTI_RANGE key_multi_range;
+ range_id_t ptr;
+ st_partition_key_multi_range *next;
+} PARTITION_KEY_MULTI_RANGE;
+
+
+typedef struct st_partition_part_key_multi_range
+{
+ PARTITION_KEY_MULTI_RANGE *partition_key_multi_range;
+ st_partition_part_key_multi_range *next;
+} PARTITION_PART_KEY_MULTI_RANGE;
+
+
+class ha_partition;
+typedef struct st_partition_part_key_multi_range_hld
+{
+ ha_partition *partition;
+ uint32 part_id;
+ PARTITION_PART_KEY_MULTI_RANGE *partition_part_key_multi_range;
+} PARTITION_PART_KEY_MULTI_RANGE_HLD;
+
+extern "C" int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
extern "C" int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
class ha_partition :public handler
@@ -115,16 +219,17 @@ private:
{
partition_index_read= 0,
partition_index_first= 1,
- partition_index_first_unordered= 2,
partition_index_last= 3,
partition_index_read_last= 4,
partition_read_range = 5,
- partition_no_index_scan= 6
+ partition_no_index_scan= 6,
+ partition_read_multi_range = 7,
+ partition_ft_read= 8
};
/* Data for the partition handler */
int m_mode; // Open mode
uint m_open_test_lock; // Open test_if_locked
- uchar *m_file_buffer; // Content of the .par file
+ uchar *m_file_buffer; // Content of the .par file
char *m_name_buffer_ptr; // Pointer to first partition name
MEM_ROOT m_mem_root;
plugin_ref *m_engine_array; // Array of types of the handlers
@@ -137,6 +242,8 @@ private:
partition_info *m_part_info; // local reference to partition
Field **m_part_field_array; // Part field array locally to save acc
uchar *m_ordered_rec_buffer; // Row and key buffer for ord. idx scan
+ st_partition_ft_info *ft_first;
+ st_partition_ft_info *ft_current;
/*
Current index.
When used in key_rec_cmp: If clustered pk, index compare
@@ -153,10 +260,10 @@ private:
Length of an element in m_ordered_rec_buffer. The elements are composed of
[part_no] [table->record copy] [underlying_table_rowid]
-
+
underlying_table_rowid is only stored when the table has no extended keys.
*/
- uint m_priority_queue_rec_len;
+ size_t m_priority_queue_rec_len;
/*
If true, then sorting records by key value also sorts them by their
@@ -201,14 +308,16 @@ private:
bool m_create_handler; // Handler used to create table
bool m_is_sub_partitioned; // Is subpartitioned
bool m_ordered_scan_ongoing;
+ bool m_rnd_init_and_first;
+ bool m_ft_init_and_first;
- /*
+ /*
If set, this object was created with ha_partition::clone and doesn't
"own" the m_part_info structure.
*/
ha_partition *m_is_clone_of;
MEM_ROOT *m_clone_mem_root;
-
+
/*
We keep track if all underlying handlers are MyISAM since MyISAM has a
great number of extra flags not needed by other handlers.
@@ -253,6 +362,12 @@ private:
ha_rows m_bulk_inserted_rows;
/** used for prediction of start_bulk_insert rows */
enum_monotonicity_info m_part_func_monotonicity_info;
+ part_id_range m_direct_update_part_spec;
+ bool m_pre_calling;
+ bool m_pre_call_use_parallel;
+ /* Keep track of bulk access requests */
+ bool bulk_access_executing;
+
/** keep track of locked partitions */
MY_BITMAP m_locked_partitions;
/** Stores shared auto_increment etc. */
@@ -270,7 +385,24 @@ private:
/** partitions that returned HA_ERR_KEY_NOT_FOUND. */
MY_BITMAP m_key_not_found_partitions;
bool m_key_not_found;
+ List<String> *m_partitions_to_open;
+ MY_BITMAP m_opened_partitions;
+ /** This is one of the m_file-s that it guaranteed to be opened. */
+ /** It is set in open_read_partitions() */
+ handler *m_file_sample;
public:
+ handler **get_child_handlers()
+ {
+ return m_file;
+ }
+ virtual part_id_range *get_part_spec()
+ {
+ return &m_part_spec;
+ }
+ virtual uint get_no_current_part_id()
+ {
+ return NO_CURRENT_PART_ID;
+ }
Partition_share *get_part_share() { return part_share; }
handler *clone(const char *name, MEM_ROOT *mem_root);
virtual void set_part_info(partition_info *part_info)
@@ -278,6 +410,9 @@ public:
m_part_info= part_info;
m_is_sub_partitioned= part_info->is_sub_partitioned();
}
+
+ virtual void return_record_by_parent();
+
/*
-------------------------------------------------------------------------
MODULE create/delete handler object
@@ -296,6 +431,7 @@ public:
ha_partition *clone_arg,
MEM_ROOT *clone_mem_root_arg);
~ha_partition();
+ void ha_partition_init();
/*
A partition handler has no characteristics in itself. It only inherits
those from the underlying handlers. Here we set-up those constants to
@@ -422,8 +558,7 @@ public:
virtual THR_LOCK_DATA **store_lock(THD * thd, THR_LOCK_DATA ** to,
enum thr_lock_type lock_type);
virtual int external_lock(THD * thd, int lock_type);
- LEX_CSTRING *engine_name()
- { return hton_name(table->part_info->default_engine_type); }
+ LEX_CSTRING *engine_name() { return hton_name(partition_ht()); }
/*
When table is locked a statement is started by calling start_stmt
instead of external_lock
@@ -479,8 +614,23 @@ public:
number of calls to write_row.
*/
virtual int write_row(uchar * buf);
+ virtual bool start_bulk_update();
+ virtual int exec_bulk_update(ha_rows *dup_key_found);
+ virtual int end_bulk_update();
+ virtual int bulk_update_row(const uchar *old_data, const uchar *new_data,
+ ha_rows *dup_key_found);
virtual int update_row(const uchar * old_data, const uchar * new_data);
+ virtual int direct_update_rows_init();
+ virtual int pre_direct_update_rows_init();
+ virtual int direct_update_rows(ha_rows *update_rows);
+ virtual int pre_direct_update_rows();
+ virtual bool start_bulk_delete();
+ virtual int end_bulk_delete();
virtual int delete_row(const uchar * buf);
+ virtual int direct_delete_rows_init();
+ virtual int pre_direct_delete_rows_init();
+ virtual int direct_delete_rows(ha_rows *delete_rows);
+ virtual int pre_direct_delete_rows();
virtual int delete_all_rows(void);
virtual int truncate();
virtual void start_bulk_insert(ha_rows rows, uint flags);
@@ -599,20 +749,16 @@ public:
virtual int index_last(uchar * buf);
virtual int index_next_same(uchar * buf, const uchar * key, uint keylen);
+ int index_read_last_map(uchar *buf,
+ const uchar *key,
+ key_part_map keypart_map);
+
/*
read_first_row is virtual method but is only implemented by
handler.cc, no storage engine has implemented it so neither
will the partition handler.
-
- virtual int read_first_row(uchar *buf, uint primary_key);
- */
- /*
- We don't implement multi read range yet, will do later.
- virtual int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
- KEY_MULTI_RANGE *ranges, uint range_count,
- bool sorted, HANDLER_BUFFER *buffer);
- virtual int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
+ virtual int read_first_row(uchar *buf, uint primary_key);
*/
@@ -621,12 +767,59 @@ public:
bool eq_range, bool sorted);
virtual int read_range_next();
+
+ HANDLER_BUFFER *m_mrr_buffer;
+ uint *m_mrr_buffer_size;
+ uchar *m_mrr_full_buffer;
+ uint m_mrr_full_buffer_size;
+ uint m_mrr_new_full_buffer_size;
+ MY_BITMAP m_mrr_used_partitions;
+ uint *m_stock_range_seq;
+ uint m_current_range_seq;
+ uint m_mrr_mode;
+ uint m_mrr_n_ranges;
+ range_id_t *m_range_info;
+ bool m_multi_range_read_first;
+ uint m_mrr_range_init_flags;
+ uint m_mrr_range_length;
+ PARTITION_KEY_MULTI_RANGE *m_mrr_range_first;
+ PARTITION_KEY_MULTI_RANGE *m_mrr_range_current;
+ uint *m_part_mrr_range_length;
+ PARTITION_PART_KEY_MULTI_RANGE **m_part_mrr_range_first;
+ PARTITION_PART_KEY_MULTI_RANGE **m_part_mrr_range_current;
+ PARTITION_PART_KEY_MULTI_RANGE_HLD *m_partition_part_key_multi_range_hld;
+ range_seq_t m_seq;
+ RANGE_SEQ_IF *m_seq_if;
+ RANGE_SEQ_IF m_part_seq_if;
+
+ virtual int multi_range_key_create_key(
+ RANGE_SEQ_IF *seq,
+ range_seq_t seq_it
+ );
+ virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
+ void *seq_init_param,
+ uint n_ranges, uint *bufsz,
+ uint *mrr_mode,
+ Cost_estimate *cost);
+ virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *mrr_mode, Cost_estimate *cost);
+ virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
+ uint n_ranges, uint mrr_mode,
+ HANDLER_BUFFER *buf);
+ virtual int multi_range_read_next(range_id_t *range_info);
+ virtual int multi_range_read_explain_info(uint mrr_mode, char *str,
+ size_t size);
+ uint last_part() { return m_last_part; }
+
private:
bool init_record_priority_queue();
void destroy_record_priority_queue();
int common_index_read(uchar * buf, bool have_start_key);
int common_first_last(uchar * buf);
int partition_scan_set_up(uchar * buf, bool idx_read_flag);
+ bool check_parallel_search();
+ int handle_pre_scan(bool reverse_order, bool use_parallel);
int handle_unordered_next(uchar * buf, bool next_same);
int handle_unordered_scan_next_partition(uchar * buf);
int handle_ordered_index_scan(uchar * buf, bool reverse_order);
@@ -647,6 +840,9 @@ public:
virtual int info(uint);
void get_dynamic_partition_info(PARTITION_STATS *stat_info,
uint part_id);
+ void set_partitions_to_open(List<String> *partition_names);
+ int change_partitions_to_open(List<String> *partition_names);
+ int open_read_partitions(char *name_buff, size_t name_buff_size);
virtual int extra(enum ha_extra_function operation);
virtual int extra_opt(enum ha_extra_function operation, ulong cachesize);
virtual int reset(void);
@@ -667,12 +863,13 @@ private:
Query_cache_block_table
**block_table,
handler *file, uint *n);
- static const uint NO_CURRENT_PART_ID;
+ static const uint NO_CURRENT_PART_ID= NOT_A_PARTITION_ID;
int loop_extra(enum ha_extra_function operation);
int loop_extra_alter(enum ha_extra_function operations);
void late_extra_cache(uint partition_id);
void late_extra_no_cache(uint partition_id);
void prepare_extra_cache(uint cachesize);
+ handler *get_open_file_sample() const { return m_file_sample; }
public:
/*
@@ -916,7 +1113,7 @@ public:
special file for handling names of partitions, engine types.
HA_REC_NOT_IN_SEQ is always set for partition handler since we cannot
guarantee that the records will be returned in sequence.
- HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_CAN_SQL_HANDLER, HA_DUPLICATE_POS,
+ HA_DUPLICATE_POS,
HA_CAN_INSERT_DELAYED, HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is disabled
until further investigated.
*/
@@ -991,14 +1188,14 @@ public:
wrapper function for handlerton alter_table_flags, since
the ha_partition_hton cannot know all its capabilities
*/
- virtual uint alter_table_flags(uint flags);
+ virtual ulonglong alter_table_flags(ulonglong flags);
/*
unireg.cc will call the following to make sure that the storage engine
can handle the data it is about to send.
The maximum supported values is the minimum of all handlers in the table
*/
- uint min_of_the_max_uint(uint (handler::*operator_func)(void) const) const;
+ uint min_of_the_max_uint(uint (handler::*operator_func)(void) const) const;
virtual uint max_supported_record_length() const;
virtual uint max_supported_keys() const;
virtual uint max_supported_key_parts() const;
@@ -1043,6 +1240,8 @@ public:
auto_increment_column_changed
-------------------------------------------------------------------------
*/
+ virtual bool need_info_for_auto_inc();
+ virtual bool can_use_for_auto_inc_init();
virtual void get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong nb_desired_values,
ulonglong *first_value,
@@ -1050,16 +1249,17 @@ public:
virtual void release_auto_increment();
private:
virtual int reset_auto_increment(ulonglong value);
+ void update_next_auto_inc_val();
virtual void lock_auto_increment()
{
/* lock already taken */
if (auto_increment_safe_stmt_log_lock)
return;
- DBUG_ASSERT(!auto_increment_lock);
- if(table_share->tmp_table == NO_TMP_TABLE)
+ if (table_share->tmp_table == NO_TMP_TABLE)
{
- auto_increment_lock= TRUE;
part_share->lock_auto_inc();
+ DBUG_ASSERT(!auto_increment_lock);
+ auto_increment_lock= TRUE;
}
}
virtual void unlock_auto_increment()
@@ -1069,10 +1269,10 @@ private:
It will be set to false and thus unlocked at the end of the statement by
ha_partition::release_auto_increment.
*/
- if(auto_increment_lock && !auto_increment_safe_stmt_log_lock)
+ if (auto_increment_lock && !auto_increment_safe_stmt_log_lock)
{
- part_share->unlock_auto_inc();
auto_increment_lock= FALSE;
+ part_share->unlock_auto_inc();
}
}
virtual void set_auto_increment_if_higher(Field *field)
@@ -1080,7 +1280,8 @@ private:
ulonglong nr= (((Field_num*) field)->unsigned_flag ||
field->val_int() > 0) ? field->val_int() : 0;
lock_auto_increment();
- DBUG_ASSERT(part_share->auto_inc_initialized);
+ DBUG_ASSERT(part_share->auto_inc_initialized ||
+ !can_use_for_auto_inc_init());
/* must check when the mutex is taken */
if (nr >= part_share->next_auto_inc_val)
part_share->next_auto_inc_val= nr + 1;
@@ -1129,14 +1330,15 @@ public:
-------------------------------------------------------------------------
MODULE fulltext index
-------------------------------------------------------------------------
- Fulltext stuff not yet.
- -------------------------------------------------------------------------
- virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
- virtual FT_INFO *ft_init_ext(uint flags,uint inx,const uchar *key,
- uint keylen)
- { return NULL; }
- virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
*/
+ void ft_close_search(FT_INFO *handler);
+ virtual int ft_init();
+ virtual int pre_ft_init();
+ virtual void ft_end();
+ virtual int pre_ft_end();
+ virtual FT_INFO *ft_init_ext(uint flags, uint inx, String *key);
+ virtual int ft_read(uchar *buf);
+ virtual int pre_ft_read(bool use_parallel);
/*
-------------------------------------------------------------------------
@@ -1198,6 +1400,16 @@ public:
virtual bool is_crashed() const;
virtual int check_for_upgrade(HA_CHECK_OPT *check_opt);
+ /*
+ -------------------------------------------------------------------------
+ MODULE condition pushdown
+ -------------------------------------------------------------------------
+ */
+ virtual const COND *cond_push(const COND *cond);
+ virtual void cond_pop();
+ virtual void clear_top_table_fields();
+ virtual int info_push(uint info_type, void *info);
+
private:
int handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, uint flags);
int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt, uint part_id,
@@ -1225,6 +1437,7 @@ public:
/* Enabled keycache for performance reasons, WL#4571 */
virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt);
virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
+ virtual TABLE_LIST *get_next_global_for_child();
/*
-------------------------------------------------------------------------
@@ -1271,7 +1484,26 @@ public:
return h;
}
+ ha_rows part_records(void *_part_elem)
+ {
+ partition_element *part_elem= reinterpret_cast<partition_element *>(_part_elem);
+ DBUG_ASSERT(m_part_info);
+ uint32 sub_factor= m_part_info->num_subparts ? m_part_info->num_subparts : 1;
+ uint32 part_id= part_elem->id * sub_factor;
+ uint32 part_id_end= part_id + sub_factor;
+ DBUG_ASSERT(part_id_end <= m_tot_parts);
+ ha_rows part_recs= 0;
+ for (; part_id < part_id_end; ++part_id)
+ {
+ handler *file= m_file[part_id];
+ DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), part_id));
+ file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_OPEN);
+ part_recs+= file->stats.records;
+ }
+ return part_recs;
+ }
+
friend int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
+ friend int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
};
-
#endif /* HA_PARTITION_INCLUDED */
diff --git a/sql/ha_sequence.cc b/sql/ha_sequence.cc
index 93f6f32d473..4afa2168b8d 100644
--- a/sql/ha_sequence.cc
+++ b/sql/ha_sequence.cc
@@ -259,7 +259,8 @@ int ha_sequence::write_row(uchar *buf)
sequence->copy(&tmp_seq);
rows_changed++;
/* We have to do the logging while we hold the sequence mutex */
- error= binlog_log_row(table, 0, buf, log_func);
+ if (table->file->check_table_binlog_row_based(1))
+ error= binlog_log_row(table, 0, buf, log_func);
row_already_logged= 1;
}
diff --git a/sql/handler.cc b/sql/handler.cc
index c260b5da54d..3d85d4d132c 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+ Copyright (c) 2009, 2018, 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
@@ -23,7 +23,7 @@
#include "mariadb.h"
#include "sql_priv.h"
#include "unireg.h"
-#include "rpl_handler.h"
+#include "rpl_rli.h"
#include "sql_cache.h" // query_cache, query_cache_*
#include "sql_connect.h" // global_table_stats
#include "key.h" // key_copy, key_unpack, key_cmp_if_same, key_cmp
@@ -50,6 +50,7 @@
#ifdef WITH_ARIA_STORAGE_ENGINE
#include "../storage/maria/ha_maria.h"
#endif
+#include "semisync_master.h"
#include "wsrep_mysqld.h"
#include "wsrep.h"
@@ -797,7 +798,9 @@ static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
*/
void ha_close_connection(THD* thd)
{
- plugin_foreach(thd, closecon_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, 0);
+ plugin_foreach_with_mask(thd, closecon_handlerton,
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ PLUGIN_IS_DELETED|PLUGIN_IS_READY, 0);
}
static my_bool kill_handlerton(THD *thd, plugin_ref plugin,
@@ -1414,6 +1417,40 @@ int ha_commit_trans(THD *thd, bool all)
goto err;
}
+#if 1 // FIXME: This should be done in ha_prepare().
+ if (rw_trans || (thd->lex->sql_command == SQLCOM_ALTER_TABLE &&
+ thd->lex->alter_info.flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING))
+ {
+ ulonglong trx_start_id= 0, trx_end_id= 0;
+ for (Ha_trx_info *ha_info= trans->ha_list; ha_info; ha_info= ha_info->next())
+ {
+ if (ha_info->ht()->prepare_commit_versioned)
+ {
+ trx_end_id= ha_info->ht()->prepare_commit_versioned(thd, &trx_start_id);
+ if (trx_end_id)
+ break; // FIXME: use a common ID for cross-engine transactions
+ }
+ }
+
+ if (trx_end_id)
+ {
+ if (!TR_table::use_transaction_registry)
+ {
+ my_error(ER_VERS_TRT_IS_DISABLED, MYF(0));
+ goto err;
+ }
+ DBUG_ASSERT(trx_start_id);
+ TR_table trt(thd, true);
+ if (trt.update(trx_start_id, trx_end_id))
+ goto err;
+ // 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);
+ }
+ }
+#endif
+
if (trans->no_2pc || (rw_ha_count <= 1))
{
error= ha_commit_one_phase(thd, all);
@@ -1484,7 +1521,10 @@ done:
mysql_mutex_assert_not_owner(mysql_bin_log.get_log_lock());
mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
- RUN_HOOK(transaction, after_commit, (thd, FALSE));
+#ifdef HAVE_REPLICATION
+ repl_semisync_master.wait_after_commit(thd, all);
+ DEBUG_SYNC(thd, "after_group_after_commit");
+#endif
goto end;
/* Come here if error and we need to rollback. */
@@ -1729,7 +1769,9 @@ int ha_rollback_trans(THD *thd, bool all)
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER_THD(thd, ER_WARNING_NOT_COMPLETE_ROLLBACK));
- (void) RUN_HOOK(transaction, after_rollback, (thd, FALSE));
+#ifdef HAVE_REPLICATION
+ repl_semisync_master.wait_after_rollback(thd, all);
+#endif
DBUG_RETURN(error);
}
@@ -1987,6 +2029,97 @@ int ha_recover(HASH *commit_list)
}
/**
+ return the XID as it appears in the SQL function's arguments.
+ So this string can be passed to XA START, XA PREPARE etc...
+
+ @note
+ the 'buf' has to have space for at least SQL_XIDSIZE bytes.
+*/
+
+
+/*
+ 'a'..'z' 'A'..'Z', '0'..'9'
+ and '-' '_' ' ' symbols don't have to be
+ converted.
+*/
+
+static const char xid_needs_conv[128]=
+{
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
+ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,
+ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
+};
+
+uint get_sql_xid(XID *xid, char *buf)
+{
+ int tot_len= xid->gtrid_length + xid->bqual_length;
+ int i;
+ const char *orig_buf= buf;
+
+ for (i=0; i<tot_len; i++)
+ {
+ uchar c= ((uchar *) xid->data)[i];
+ if (c >= 128 || xid_needs_conv[c])
+ break;
+ }
+
+ if (i >= tot_len)
+ {
+ /* No need to convert characters to hexadecimals. */
+ *buf++= '\'';
+ memcpy(buf, xid->data, xid->gtrid_length);
+ buf+= xid->gtrid_length;
+ *buf++= '\'';
+ if (xid->bqual_length > 0 || xid->formatID != 1)
+ {
+ *buf++= ',';
+ *buf++= '\'';
+ memcpy(buf, xid->data+xid->gtrid_length, xid->bqual_length);
+ buf+= xid->bqual_length;
+ *buf++= '\'';
+ }
+ }
+ else
+ {
+ *buf++= 'X';
+ *buf++= '\'';
+ for (i= 0; i < xid->gtrid_length; i++)
+ {
+ *buf++=_dig_vec_lower[((uchar*) xid->data)[i] >> 4];
+ *buf++=_dig_vec_lower[((uchar*) xid->data)[i] & 0x0f];
+ }
+ *buf++= '\'';
+ if (xid->bqual_length > 0 || xid->formatID != 1)
+ {
+ *buf++= ',';
+ *buf++= 'X';
+ *buf++= '\'';
+ for (; i < tot_len; i++)
+ {
+ *buf++=_dig_vec_lower[((uchar*) xid->data)[i] >> 4];
+ *buf++=_dig_vec_lower[((uchar*) xid->data)[i] & 0x0f];
+ }
+ *buf++= '\'';
+ }
+ }
+
+ if (xid->formatID != 1)
+ {
+ *buf++= ',';
+ buf+= my_longlong10_to_str_8bit(&my_charset_bin, buf,
+ MY_INT64_NUM_DECIMAL_DIGITS, -10, xid->formatID);
+ }
+
+ return (uint)(buf - orig_buf);
+}
+
+
+/**
return the list of XID's to a client, the same way SHOW commands do.
@note
@@ -1995,7 +2128,8 @@ int ha_recover(HASH *commit_list)
It can be easily fixed later, if necessary.
*/
-static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol)
+static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol,
+ char *data, uint data_len, CHARSET_INFO *data_cs)
{
if (xs->xa_state == XA_PREPARED)
{
@@ -2003,8 +2137,7 @@ static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol)
protocol->store_longlong((longlong) xs->xid.formatID, FALSE);
protocol->store_longlong((longlong) xs->xid.gtrid_length, FALSE);
protocol->store_longlong((longlong) xs->xid.bqual_length, FALSE);
- protocol->store(xs->xid.data, xs->xid.gtrid_length + xs->xid.bqual_length,
- &my_charset_bin);
+ protocol->store(data, data_len, data_cs);
if (protocol->write())
return TRUE;
}
@@ -2012,11 +2145,28 @@ static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol)
}
+static my_bool xa_recover_callback_short(XID_STATE *xs, Protocol *protocol)
+{
+ return xa_recover_callback(xs, protocol, xs->xid.data,
+ xs->xid.gtrid_length + xs->xid.bqual_length, &my_charset_bin);
+}
+
+
+static my_bool xa_recover_callback_verbose(XID_STATE *xs, Protocol *protocol)
+{
+ char buf[SQL_XIDSIZE];
+ uint len= get_sql_xid(&xs->xid, buf);
+ return xa_recover_callback(xs, protocol, buf, len,
+ &my_charset_utf8_general_ci);
+}
+
+
bool mysql_xa_recover(THD *thd)
{
List<Item> field_list;
Protocol *protocol= thd->protocol;
MEM_ROOT *mem_root= thd->mem_root;
+ my_hash_walk_action action;
DBUG_ENTER("mysql_xa_recover");
field_list.push_back(new (mem_root)
@@ -2028,16 +2178,32 @@ bool mysql_xa_recover(THD *thd)
field_list.push_back(new (mem_root)
Item_int(thd, "bqual_length", 0,
MY_INT32_NUM_DECIMAL_DIGITS), mem_root);
- field_list.push_back(new (mem_root)
- Item_empty_string(thd, "data",
- XIDDATASIZE), mem_root);
+ {
+ uint len;
+ CHARSET_INFO *cs;
+
+ if (thd->lex->verbose)
+ {
+ len= SQL_XIDSIZE;
+ cs= &my_charset_utf8_general_ci;
+ action= (my_hash_walk_action) xa_recover_callback_verbose;
+ }
+ else
+ {
+ len= XIDDATASIZE;
+ cs= &my_charset_bin;
+ action= (my_hash_walk_action) xa_recover_callback_short;
+ }
+
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "data", len, cs), mem_root);
+ }
if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(1);
- if (xid_cache_iterate(thd, (my_hash_walk_action) xa_recover_callback,
- protocol))
+ if (xid_cache_iterate(thd, action, protocol))
DBUG_RETURN(1);
my_eof(thd);
DBUG_RETURN(0);
@@ -2337,7 +2503,7 @@ const char *get_canonical_filename(handler *file, const char *path,
The .frm file will be deleted only if we return 0.
*/
int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
- const char *db, const char *alias, bool generate_warning)
+ const LEX_CSTRING *db, const LEX_CSTRING *alias, bool generate_warning)
{
handler *file;
char tmp_path[FN_REFLEN];
@@ -2370,12 +2536,9 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
dummy_share.path.str= (char*) path;
dummy_share.path.length= strlen(path);
dummy_share.normalized_path= dummy_share.path;
- dummy_share.db.str= (char*) db;
- dummy_share.db.length= strlen(db);
- dummy_share.table_name.str= (char*) alias;
- dummy_share.table_name.length= strlen(alias);
- dummy_table.alias.set(alias, dummy_share.table_name.length,
- table_alias_charset);
+ dummy_share.db= *db;
+ dummy_share.table_name= *alias;
+ dummy_table.alias.set(alias->str, alias->length, table_alias_charset);
file->change_table_ptr(&dummy_table, &dummy_share);
file->print_error(error, MYF(intercept ? ME_JUST_WARNING : 0));
}
@@ -2446,7 +2609,7 @@ double handler::keyread_time(uint index, uint ranges, ha_rows rows)
engines that support that (e.g. InnoDB) may want to overwrite this method.
The model counts in the time to read index entries from cache.
*/
- ulong len= table->key_info[index].key_length + ref_length;
+ size_t len= table->key_info[index].key_length + ref_length;
if (index == table->s->primary_key && table->file->primary_key_is_clustered())
len= table->s->stored_rec_length;
double keys_per_block= (stats.block_size/2.0/len+1);
@@ -2497,7 +2660,8 @@ PSI_table_share *handler::ha_table_share_psi() const
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
*/
int handler::ha_open(TABLE *table_arg, const char *name, int mode,
- uint test_if_locked, MEM_ROOT *mem_root)
+ uint test_if_locked, MEM_ROOT *mem_root,
+ List<String> *partitions_to_open)
{
int error;
DBUG_ENTER("handler::ha_open");
@@ -2512,6 +2676,8 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
DBUG_PRINT("info", ("old m_lock_type: %d F_UNLCK %d", m_lock_type, F_UNLCK));
DBUG_ASSERT(alloc_root_inited(&table->mem_root));
+ set_partitions_to_open(partitions_to_open);
+
if ((error=open(name,mode,test_if_locked)))
{
if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
@@ -2895,45 +3061,6 @@ void handler::adjust_next_insert_id_after_explicit_value(ulonglong nr)
}
-/** @brief
- Computes the largest number X:
- - smaller than or equal to "nr"
- - of the form: auto_increment_offset + N * auto_increment_increment
- where N>=0.
-
- SYNOPSIS
- prev_insert_id
- nr Number to "round down"
- variables variables struct containing auto_increment_increment and
- auto_increment_offset
-
- RETURN
- The number X if it exists, "nr" otherwise.
-*/
-inline ulonglong
-prev_insert_id(ulonglong nr, struct system_variables *variables)
-{
- if (unlikely(nr < variables->auto_increment_offset))
- {
- /*
- There's nothing good we can do here. That is a pathological case, where
- the offset is larger than the column's max possible value, i.e. not even
- the first sequence value may be inserted. User will receive warning.
- */
- DBUG_PRINT("info",("auto_increment: nr: %lu cannot honour "
- "auto_increment_offset: %lu",
- (ulong) nr, variables->auto_increment_offset));
- return nr;
- }
- if (variables->auto_increment_increment == 1)
- return nr; // optimization of the formula below
- nr= (((nr - variables->auto_increment_offset)) /
- (ulonglong) variables->auto_increment_increment);
- return (nr * (ulonglong) variables->auto_increment_increment +
- variables->auto_increment_offset);
-}
-
-
/**
Update the auto_increment field if necessary.
@@ -3046,6 +3173,25 @@ int handler::update_auto_increment()
DBUG_RETURN(0);
}
+ // ALTER TABLE ... ADD COLUMN ... AUTO_INCREMENT
+ if (thd->lex->sql_command == SQLCOM_ALTER_TABLE)
+ {
+ if (table->versioned())
+ {
+ Field *end= table->vers_end_field();
+ DBUG_ASSERT(end);
+ bitmap_set_bit(table->read_set, end->field_index);
+ if (!end->is_max())
+ {
+ if (!table->next_number_field->real_maybe_null())
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+ table->next_number_field->set_null();
+ DBUG_RETURN(0);
+ }
+ }
+ table->next_number_field->set_notnull();
+ }
+
if ((nr= next_insert_id) >= auto_inc_interval_for_cur_row.maximum())
{
/* next_insert_id is beyond what is reserved, so we reserve more. */
@@ -3145,7 +3291,7 @@ int handler::update_auto_increment()
/* Store field without warning (Warning will be printed by insert) */
save_count_cuted_fields= thd->count_cuted_fields;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
- tmp= table->next_number_field->store((longlong) nr, TRUE);
+ tmp= table->next_number_field->store((longlong)nr, TRUE);
thd->count_cuted_fields= save_count_cuted_fields;
if (unlikely(tmp)) // Out of range value in store
@@ -3346,9 +3492,11 @@ void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag)
if (key == NULL)
{
- /* Key is unknown */
- str.copy("", 0, system_charset_info);
- my_printf_error(ER_DUP_ENTRY, msg, errflag, str.c_ptr(), "*UNKNOWN*");
+ /*
+ Key is unknown. Should only happen if storage engine reports wrong
+ duplicate key number.
+ */
+ my_printf_error(ER_DUP_ENTRY, msg, errflag, "", "*UNKNOWN*");
}
else
{
@@ -3449,11 +3597,9 @@ void handler::print_error(int error, myf errflag)
if (table)
{
uint key_nr=get_dup_key(error);
- if ((int) key_nr >= 0)
+ if ((int) key_nr >= 0 && key_nr < table->s->keys)
{
- print_keydup_error(table,
- key_nr == MAX_KEY ? NULL : &table->key_info[key_nr],
- errflag);
+ print_keydup_error(table, &table->key_info[key_nr], errflag);
DBUG_VOID_RETURN;
}
}
@@ -3535,13 +3681,19 @@ void handler::print_error(int error, myf errflag)
textno=ER_UNSUPPORTED_EXTENSION;
break;
case HA_ERR_RECORD_FILE_FULL:
- case HA_ERR_INDEX_FILE_FULL:
{
textno=ER_RECORD_FILE_FULL;
/* Write the error message to error log */
errflag|= ME_NOREFRESH;
break;
}
+ case HA_ERR_INDEX_FILE_FULL:
+ {
+ textno=ER_INDEX_FILE_FULL;
+ /* Write the error message to error log */
+ errflag|= ME_NOREFRESH;
+ break;
+ }
case HA_ERR_LOCK_WAIT_TIMEOUT:
textno=ER_LOCK_WAIT_TIMEOUT;
break;
@@ -3845,7 +3997,7 @@ static bool update_frm_version(TABLE *table)
int4store(version, MYSQL_VERSION_ID);
- if ((result= mysql_file_pwrite(file, (uchar*) version, 4, 51L, MYF_RW)))
+ if ((result= (int)mysql_file_pwrite(file, (uchar*) version, 4, 51L, MYF_RW)))
goto err;
table->s->mysql_version= MYSQL_VERSION_ID;
@@ -4058,7 +4210,7 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
int
handler::ha_bulk_update_row(const uchar *old_data, const uchar *new_data,
- uint *dup_key_found)
+ ha_rows *dup_key_found)
{
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
m_lock_type == F_WRLCK);
@@ -4265,6 +4417,9 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table,
HA_CREATE_INFO *create_info= ha_alter_info->create_info;
+ if (altered_table->versioned(VERS_TIMESTAMP))
+ DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
+
Alter_inplace_info::HA_ALTER_FLAGS inplace_offline_operations=
Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH |
Alter_inplace_info::ALTER_COLUMN_NAME |
@@ -4574,6 +4729,7 @@ void handler::get_dynamic_partition_info(PARTITION_STATS *stat_info,
stat_info->data_file_length= stats.data_file_length;
stat_info->max_data_file_length= stats.max_data_file_length;
stat_info->index_file_length= stats.index_file_length;
+ stat_info->max_index_file_length=stats.max_index_file_length;
stat_info->delete_length= stats.delete_length;
stat_info->create_time= stats.create_time;
stat_info->update_time= stats.update_time;
@@ -4623,7 +4779,7 @@ void handler::update_global_table_stats()
}
memcpy(table_stats->table, table->s->table_cache_key.str,
table->s->table_cache_key.length);
- table_stats->table_name_length= table->s->table_cache_key.length;
+ table_stats->table_name_length= (uint)table->s->table_cache_key.length;
table_stats->engine_type= ht->db_type;
/* No need to set variables to 0, as we use MY_ZEROFILL above */
@@ -4666,7 +4822,7 @@ void handler::update_global_index_stats()
if (index_rows_read[index])
{
INDEX_STATS* index_stats;
- uint key_length;
+ size_t key_length;
KEY *key_info = &table->key_info[index]; // Rows were read using this
DBUG_ASSERT(key_info->cache_name);
@@ -4725,7 +4881,6 @@ int ha_create_table(THD *thd, const char *path,
TABLE_SHARE share;
bool temp_table __attribute__((unused)) =
create_info->options & (HA_LEX_CREATE_TMP_TABLE | HA_CREATE_TMP_ALTER);
-
DBUG_ENTER("ha_create_table");
init_tmp_table_share(thd, &share, db, 0, table_name, path);
@@ -4753,7 +4908,8 @@ int ha_create_table(THD *thd, const char *path,
share.m_psi= PSI_CALL_get_table_share(temp_table, &share);
- if (open_table_from_share(thd, &share, "", 0, READ_ALL, 0, &table, true))
+ if (open_table_from_share(thd, &share, &empty_clex_str, 0, READ_ALL, 0,
+ &table, true))
goto err;
update_create_info_from_table(create_info, &table);
@@ -4767,8 +4923,8 @@ int ha_create_table(THD *thd, const char *path,
if (!thd->is_error())
my_error(ER_CANT_CREATE_TABLE, MYF(0), db, table_name, error);
table.file->print_error(error, MYF(ME_JUST_WARNING));
- PSI_CALL_drop_table_share(temp_table, share.db.str, share.db.length,
- share.table_name.str, share.table_name.length);
+ PSI_CALL_drop_table_share(temp_table, share.db.str, (uint)share.db.length,
+ share.table_name.str, (uint)share.table_name.length);
}
(void) closefrm(&table);
@@ -5064,7 +5220,7 @@ private:
*hton will be NULL.
*/
-bool ha_table_exists(THD *thd, const char *db, const char *table_name,
+bool ha_table_exists(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name,
handlerton **hton, bool *is_sequence)
{
handlerton *dummy;
@@ -5079,7 +5235,7 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name,
is_sequence= &dummy2;
*is_sequence= 0;
- TDC_element *element= tdc_lock_share(thd, db, table_name);
+ TDC_element *element= tdc_lock_share(thd, db->str, table_name->str);
if (element && element != MY_ERRPTR)
{
if (hton)
@@ -5091,8 +5247,8 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name,
char path[FN_REFLEN + 1];
size_t path_len = build_table_filename(path, sizeof(path) - 1,
- db, table_name, "", 0);
- st_discover_existence_args args= {path, path_len, db, table_name, 0, true};
+ db->str, table_name->str, "", 0);
+ st_discover_existence_args args= {path, path_len, db->str, table_name->str, 0, true};
if (file_ext_exists(path, path_len, reg_ext))
{
@@ -5135,14 +5291,12 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name,
{
TABLE_LIST table;
uint flags = GTS_TABLE | GTS_VIEW;
-
if (!hton)
flags|= GTS_NOLOCK;
Table_exists_error_handler no_such_table_handler;
thd->push_internal_handler(&no_such_table_handler);
- table.init_one_table(db, strlen(db), table_name, strlen(table_name),
- table_name, TL_READ);
+ table.init_one_table(db, table_name, 0, TL_READ);
TABLE_SHARE *share= tdc_acquire_share(thd, &table, flags);
thd->pop_internal_handler();
@@ -5281,7 +5435,7 @@ static my_bool discover_names(THD *thd, plugin_ref plugin,
if (ht->state == SHOW_OPTION_YES && ht->discover_table_names)
{
- uint old_elements= args->result->tables->elements();
+ size_t old_elements= args->result->tables->elements();
if (ht->discover_table_names(ht, args->db, args->dirp, args->result))
return 1;
@@ -5290,7 +5444,7 @@ static my_bool discover_names(THD *thd, plugin_ref plugin,
a corresponding .frm file; but custom engine discover methods might
*/
if (ht->discover_table_names != hton_ext_based_table_discovery)
- args->possible_duplicates+= args->result->tables->elements() - old_elements;
+ args->possible_duplicates+= (uint)(args->result->tables->elements() - old_elements);
}
return 0;
@@ -5344,6 +5498,27 @@ int ha_discover_table_names(THD *thd, LEX_CSTRING *db, MY_DIR *dirp,
}
+/*
+int handler::pre_read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
+ KEY_MULTI_RANGE *ranges,
+ uint range_count,
+ bool sorted, HANDLER_BUFFER *buffer,
+ bool use_parallel)
+{
+ int result;
+ DBUG_ENTER("handler::pre_read_multi_range_first");
+ result = pre_read_range_first(ranges->start_key.keypart_map ?
+ &ranges->start_key : 0,
+ ranges->end_key.keypart_map ?
+ &ranges->end_key : 0,
+ test(ranges->range_flag & EQ_RANGE),
+ sorted,
+ use_parallel);
+ DBUG_RETURN(result);
+}
+*/
+
+
/**
Read first row between two ranges.
Store ranges for future calls to read_range_next.
@@ -5702,8 +5877,10 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
1 Row needs to be logged
*/
-inline bool handler::check_table_binlog_row_based(bool binlog_row)
+bool handler::check_table_binlog_row_based(bool binlog_row)
{
+ if (table->versioned(VERS_TRX_ID))
+ return false;
if (unlikely((table->in_use->variables.sql_log_bin_off)))
return 0; /* Called by partitioning engine */
if (unlikely((!check_table_binlog_row_based_done)))
@@ -5852,10 +6029,10 @@ static int write_locked_table_maps(THD *thd)
static int check_wsrep_max_ws_rows();
-static int binlog_log_row_internal(TABLE* table,
- const uchar *before_record,
- const uchar *after_record,
- Log_func *log_func)
+int binlog_log_row(TABLE* table,
+ const uchar *before_record,
+ const uchar *after_record,
+ Log_func *log_func)
{
bool error= 0;
THD *const thd= table->in_use;
@@ -5890,16 +6067,6 @@ static int binlog_log_row_internal(TABLE* table,
return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
}
-int binlog_log_row(TABLE* table,
- const uchar *before_record,
- const uchar *after_record,
- Log_func *log_func)
-{
- if (!table->file->check_table_binlog_row_based(1))
- return 0;
- return binlog_log_row_internal(table, before_record, after_record, log_func);
-}
-
int handler::ha_external_lock(THD *thd, int lock_type)
{
@@ -6000,6 +6167,7 @@ int handler::ha_reset()
/* Reset information about pushed engine conditions */
cancel_pushed_idx_cond();
/* Reset information about pushed index conditions */
+ clear_top_table_fields();
DBUG_RETURN(reset());
}
@@ -6048,7 +6216,8 @@ int handler::ha_write_row(uchar *buf)
if (likely(!error) && !row_already_logged)
{
rows_changed++;
- error= binlog_log_row(table, 0, buf, log_func);
+ if (table->file->check_table_binlog_row_based(1))
+ error= binlog_log_row(table, 0, buf, log_func);
}
DEBUG_SYNC_C("ha_write_row_end");
DBUG_RETURN(error);
@@ -6080,7 +6249,8 @@ int handler::ha_update_row(const uchar *old_data, const uchar *new_data)
if (likely(!error) && !row_already_logged)
{
rows_changed++;
- error= binlog_log_row(table, old_data, new_data, log_func);
+ if (table->file->check_table_binlog_row_based(1))
+ error= binlog_log_row(table, old_data, new_data, log_func);
}
return error;
}
@@ -6135,12 +6305,66 @@ int handler::ha_delete_row(const uchar *buf)
if (likely(!error))
{
rows_changed++;
- error= binlog_log_row(table, buf, 0, log_func);
+ if (table->file->check_table_binlog_row_based(1))
+ error= binlog_log_row(table, buf, 0, log_func);
}
return error;
}
+/**
+ Execute a direct update request. A direct update request updates all
+ qualified rows in a single operation, rather than one row at a time.
+ In a Spider cluster the direct update operation is pushed down to the
+ child levels of the cluster.
+
+ Note that this can't be used in case of statment logging
+
+ @param update_rows Number of updated rows.
+
+ @retval 0 Success.
+ @retval != 0 Failure.
+*/
+
+int handler::ha_direct_update_rows(ha_rows *update_rows)
+{
+ int error;
+
+ MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
+ mark_trx_read_write();
+
+ error = direct_update_rows(update_rows);
+ MYSQL_UPDATE_ROW_DONE(error);
+ return error;
+}
+
+
+/**
+ Execute a direct delete request. A direct delete request deletes all
+ qualified rows in a single operation, rather than one row at a time.
+ In a Spider cluster the direct delete operation is pushed down to the
+ child levels of the cluster.
+
+ @param delete_rows Number of deleted rows.
+
+ @retval 0 Success.
+ @retval != 0 Failure.
+*/
+
+int handler::ha_direct_delete_rows(ha_rows *delete_rows)
+{
+ int error;
+ /* Ensure we are not using binlog row */
+ DBUG_ASSERT(!table->in_use->is_current_stmt_binlog_format_row());
+
+ MYSQL_DELETE_ROW_START(table_share->db.str, table_share->table_name.str);
+ mark_trx_read_write();
+
+ error = direct_delete_rows(delete_rows);
+ MYSQL_DELETE_ROW_DONE(error);
+ return error;
+}
+
/** @brief
use_hidden_primary_key() is called in case of an update/delete when
@@ -6524,7 +6748,7 @@ bool HA_CREATE_INFO::check_conflicting_charset_declarations(CHARSET_INFO *cs)
/* Remove all indexes for a given table from global index statistics */
static
-int del_global_index_stats_for_table(THD *thd, uchar* cache_key, uint cache_key_length)
+int del_global_index_stats_for_table(THD *thd, uchar* cache_key, size_t cache_key_length)
{
int res = 0;
DBUG_ENTER("del_global_index_stats_for_table");
@@ -6565,7 +6789,7 @@ int del_global_table_stat(THD *thd, LEX_CSTRING *db, LEX_CSTRING *table)
TABLE_STATS *table_stats;
int res = 0;
uchar *cache_key;
- uint cache_key_length;
+ size_t cache_key_length;
DBUG_ENTER("del_global_table_stat");
cache_key_length= db->length + 1 + table->length + 1;
@@ -6602,7 +6826,7 @@ end:
int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info)
{
INDEX_STATS *index_stats;
- uint key_length= table->s->table_cache_key.length + key_info->name.length + 1;
+ size_t key_length= table->s->table_cache_key.length + key_info->name.length + 1;
int res = 0;
DBUG_ENTER("del_global_index_stat");
mysql_mutex_lock(&LOCK_global_index_stats);
@@ -6615,3 +6839,578 @@ int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info)
mysql_mutex_unlock(&LOCK_global_index_stats);
DBUG_RETURN(res);
}
+
+bool Vers_parse_info::is_start(const char *name) const
+{
+ DBUG_ASSERT(name);
+ return as_row.start && as_row.start == LString_i(name);
+}
+bool Vers_parse_info::is_end(const char *name) const
+{
+ DBUG_ASSERT(name);
+ return as_row.end && as_row.end == LString_i(name);
+}
+bool Vers_parse_info::is_start(const Create_field &f) const
+{
+ return f.flags & VERS_SYS_START_FLAG;
+}
+bool Vers_parse_info::is_end(const Create_field &f) const
+{
+ return f.flags & VERS_SYS_END_FLAG;
+}
+
+static Create_field *vers_init_sys_field(THD *thd, const char *field_name, int flags, bool integer)
+{
+ Create_field *f= new (thd->mem_root) Create_field();
+ if (!f)
+ return NULL;
+
+ memset(f, 0, sizeof(*f));
+ f->field_name.str= field_name;
+ f->field_name.length= strlen(field_name);
+ f->charset= system_charset_info;
+ f->flags= flags | NOT_NULL_FLAG;
+ if (integer)
+ {
+ f->set_handler(&type_handler_longlong);
+ f->length= MY_INT64_NUM_DECIMAL_DIGITS - 1;
+ f->flags|= UNSIGNED_FLAG;
+ }
+ else
+ {
+ f->set_handler(&type_handler_timestamp2);
+ f->length= MAX_DATETIME_PRECISION;
+ }
+ f->invisible= DBUG_EVALUATE_IF("sysvers_show", VISIBLE, INVISIBLE_SYSTEM);
+
+ if (f->check(thd))
+ return NULL;
+
+ return f;
+}
+
+static bool vers_create_sys_field(THD *thd, const char *field_name,
+ Alter_info *alter_info, int flags)
+{
+ Create_field *f= vers_init_sys_field(thd, field_name, flags, false);
+ if (!f)
+ return true;
+
+ alter_info->flags|= Alter_info::ALTER_ADD_COLUMN;
+ alter_info->create_list.push_back(f);
+
+ return false;
+}
+
+const LString Vers_parse_info::default_start= "row_start";
+const LString Vers_parse_info::default_end= "row_end";
+
+bool Vers_parse_info::fix_implicit(THD *thd, Alter_info *alter_info, int *added)
+{
+ // If user specified some of these he must specify the others too. Do nothing.
+ if (*this)
+ return false;
+
+ alter_info->flags|= Alter_info::ALTER_ADD_COLUMN;
+
+ system_time= start_end_t(default_start, default_end);
+ as_row= system_time;
+
+ if (vers_create_sys_field(thd, default_start, alter_info, VERS_SYS_START_FLAG) ||
+ vers_create_sys_field(thd, default_end, alter_info, VERS_SYS_END_FLAG))
+ {
+ return true;
+ }
+ if (added)
+ *added+= 2;
+ return false;
+}
+
+bool Table_scope_and_contents_source_st::vers_native(THD *thd) const
+{
+ if (ha_check_storage_engine_flag(db_type, HTON_NATIVE_SYS_VERSIONING))
+ return true;
+
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ partition_info *info= thd->work_part_info;
+ if (info && !(used_fields & HA_CREATE_USED_ENGINE))
+ {
+ if (handlerton *hton= info->default_engine_type)
+ return ha_check_storage_engine_flag(hton, HTON_NATIVE_SYS_VERSIONING);
+
+ List_iterator_fast<partition_element> it(info->partitions);
+ while (partition_element *partition_element= it++)
+ {
+ if (partition_element->find_engine_flag(HTON_NATIVE_SYS_VERSIONING))
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+bool Table_scope_and_contents_source_st::vers_fix_system_fields(
+ THD *thd,
+ Alter_info *alter_info,
+ const TABLE_LIST &create_table,
+ const TABLE_LIST *select_tables,
+ List<Item> *items,
+ bool *versioned_write)
+{
+ DBUG_ASSERT(!(alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING));
+ int vers_tables= 0;
+
+ if (select_tables)
+ {
+ for (const TABLE_LIST *table= select_tables; table; table= table->next_local)
+ {
+ if (table->table && table->table->versioned())
+ vers_tables++;
+ }
+ }
+
+ DBUG_EXECUTE_IF("sysvers_force", if (!tmp_table()) {
+ alter_info->flags|= Alter_info::ALTER_ADD_SYSTEM_VERSIONING;
+ options|= HA_VERSIONED_TABLE; });
+
+ // Possibly override default storage engine to match one used in source table.
+ if (vers_tables && alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING &&
+ !(used_fields & HA_CREATE_USED_ENGINE))
+ {
+ List_iterator_fast<Create_field> it(alter_info->create_list);
+ while (Create_field *f= it++)
+ {
+ if (vers_info.is_start(*f) || vers_info.is_end(*f))
+ {
+ if (f->field)
+ {
+ db_type= f->field->orig_table->file->ht;
+ }
+ break;
+ }
+ }
+ }
+
+ if (!vers_info.need_check(alter_info))
+ return false;
+
+ if (!vers_info.versioned_fields && vers_info.unversioned_fields &&
+ !(alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING))
+ {
+ // All is correct but this table is not versioned.
+ options&= ~HA_VERSIONED_TABLE;
+ return false;
+ }
+
+ if (!(alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING) && vers_info)
+ {
+ my_error(ER_MISSING, MYF(0), create_table.table_name.str,
+ "WITH SYSTEM VERSIONING");
+ return true;
+ }
+
+ if (vers_tables)
+ {
+ DBUG_ASSERT(options & HA_VERSIONED_TABLE);
+ DBUG_ASSERT(versioned_write);
+ *versioned_write= true;
+ }
+
+ List_iterator<Create_field> it(alter_info->create_list);
+ bool explicit_declared= vers_info.as_row.start || vers_info.as_row.end;
+ while (Create_field *f= it++)
+ {
+ if ((f->versioning == Column_definition::VERSIONING_NOT_SET &&
+ !(alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING)) ||
+ f->versioning == Column_definition::WITHOUT_VERSIONING)
+ {
+ f->flags|= VERS_UPDATE_UNVERSIONED_FLAG;
+ }
+
+ /* Assign selected implicit fields when no explicit fields */
+ if (!vers_tables || explicit_declared)
+ continue;
+
+ DBUG_ASSERT(versioned_write);
+ if (vers_info.is_start(*f) &&
+ vers_info.default_start == f->field_name)
+ {
+ if (vers_info.as_row.start)
+ it.remove();
+ else
+ {
+ vers_info.set_start(f->field_name);
+ *versioned_write= false;
+ }
+ continue;
+ }
+ if (vers_info.is_end(*f) &&
+ vers_info.default_end == f->field_name)
+ {
+ if (vers_info.as_row.end)
+ it.remove();
+ else
+ {
+ vers_info.set_end(f->field_name);
+ *versioned_write= false;
+ }
+ continue;
+ }
+ } // while (Create_field *f= it++)
+
+ /* Assign selected system fields to explicit system fields if any */
+ if (vers_tables)
+ {
+ it.rewind();
+ while (Create_field *f= it++)
+ {
+ uint flags_left= VERS_SYSTEM_FIELD;
+ if (flags_left && (vers_info.is_start(*f) || vers_info.is_end(*f)) && !f->field)
+ {
+ uint sys_flag= f->flags & flags_left;
+ flags_left-= sys_flag;
+ List_iterator_fast<Item> it2(*items);
+ while (Item *item= it2++)
+ {
+ if (item->type() != Item::FIELD_ITEM)
+ continue;
+ Field *fld= static_cast<Item_field *>(item)->field;
+ DBUG_ASSERT(fld);
+ if ((fld->flags & sys_flag) &&
+ LString_i(f->field_name) == fld->field_name)
+ {
+ f->field= fld;
+ *versioned_write= false;
+ }
+ } // while (item)
+ } // if (flags_left ...
+ } // while (Create_field *f= it++)
+ } // if (vers_tables)
+
+ int added= 0;
+ if (vers_info.fix_implicit(thd, alter_info, &added))
+ return true;
+
+ DBUG_ASSERT(added >= 0);
+ if (vers_tables)
+ {
+ DBUG_ASSERT(items);
+ while (added--)
+ {
+ Item_default_value *item= new (thd->mem_root)
+ Item_default_value(thd, thd->lex->current_context());
+ items->push_back(item, thd->mem_root);
+ }
+ }
+
+ int plain_cols= 0; // columns don't have WITH or WITHOUT SYSTEM VERSIONING
+ int vers_cols= 0; // columns have WITH SYSTEM VERSIONING
+ it.rewind();
+ while (const Create_field *f= it++)
+ {
+ if (vers_info.is_start(*f) || vers_info.is_end(*f))
+ continue;
+
+ if (f->versioning == Column_definition::VERSIONING_NOT_SET)
+ plain_cols++;
+ else if (f->versioning == Column_definition::WITH_VERSIONING)
+ vers_cols++;
+ }
+
+ if (!thd->lex->tmp_table() &&
+ // CREATE from SELECT (Create_fields are not yet added)
+ !select_tables &&
+ vers_cols == 0 &&
+ (plain_cols == 0 || !vers_info))
+ {
+ my_error(ER_VERS_TABLE_MUST_HAVE_COLUMNS, MYF(0),
+ create_table.table_name.str);
+ return true;
+ }
+
+ if (vers_info.check_with_conditions(create_table.table_name.str))
+ return true;
+
+ bool native= vers_native(thd);
+ if (vers_info.check_sys_fields(create_table.table_name.str, alter_info, native))
+ return true;
+
+ return false;
+}
+
+bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info,
+ HA_CREATE_INFO *create_info, TABLE *table)
+{
+ TABLE_SHARE *share= table->s;
+ const char *table_name= share->table_name.str;
+
+ if (!need_check(alter_info) && !share->versioned)
+ return false;
+
+ if (DBUG_EVALUATE_IF("sysvers_force", 0, share->tmp_table))
+ {
+ my_error(ER_VERS_TEMPORARY, MYF(0));
+ return true;
+ }
+
+ if (alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING &&
+ table->versioned())
+ {
+ my_error(ER_VERS_ALREADY_VERSIONED, MYF(0), table_name);
+ return true;
+ }
+
+ if (alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING)
+ {
+ if (!share->versioned)
+ {
+ my_error(ER_VERS_NOT_VERSIONED, MYF(0), table_name);
+ return true;
+ }
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (table->part_info &&
+ table->part_info->part_type == VERSIONING_PARTITION)
+ {
+ my_error(ER_DROP_VERSIONING_SYSTEM_TIME_PARTITION, MYF(0), table_name);
+ return true;
+ }
+#endif
+
+ return false;
+ }
+
+ {
+ List_iterator_fast<Create_field> it(alter_info->create_list);
+ while (Create_field *f= it++)
+ {
+ if (f->change.length && f->flags & VERS_SYSTEM_FIELD)
+ {
+ my_error(ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN, MYF(0));
+ return true;
+ }
+ }
+ }
+
+ if ((alter_info->flags & Alter_info::ALTER_DROP_PERIOD ||
+ versioned_fields || unversioned_fields) && !share->versioned)
+ {
+ my_error(ER_VERS_NOT_VERSIONED, MYF(0), table_name);
+ return true;
+ }
+
+ if (share->versioned)
+ {
+ if (alter_info->flags & Alter_info::ALTER_ADD_PERIOD)
+ {
+ my_error(ER_VERS_ALREADY_VERSIONED, MYF(0), table_name);
+ return true;
+ }
+
+ // copy info from existing table
+ create_info->options|= HA_VERSIONED_TABLE;
+
+ DBUG_ASSERT(share->vers_start_field() && share->vers_end_field());
+ LString start(share->vers_start_field()->field_name);
+ LString end(share->vers_end_field()->field_name);
+ DBUG_ASSERT(start.ptr() && end.ptr());
+
+ as_row= start_end_t(start, end);
+ system_time= as_row;
+
+ if (alter_info->create_list.elements)
+ {
+ List_iterator_fast<Create_field> it(alter_info->create_list);
+ while (Create_field *f= it++)
+ {
+ if (f->versioning == Column_definition::WITHOUT_VERSIONING)
+ f->flags|= VERS_UPDATE_UNVERSIONED_FLAG;
+
+ if (f->change.str && (start == f->change || end == f->change))
+ {
+ my_error(ER_VERS_ALTER_SYSTEM_FIELD, MYF(0), f->change.str);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ if (fix_implicit(thd, alter_info))
+ return true;
+
+ if (alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING)
+ {
+ if (check_with_conditions(table_name))
+ return true;
+ bool native= create_info->vers_native(thd);
+ if (check_sys_fields(table_name, alter_info, native))
+ return true;
+ }
+
+ return false;
+}
+
+bool
+Vers_parse_info::fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_info,
+ TABLE_LIST &src_table, TABLE_LIST &table)
+{
+ List_iterator<Create_field> it(alter_info.create_list);
+ Create_field *f, *f_start=NULL, *f_end= NULL;
+
+ DBUG_ASSERT(alter_info.create_list.elements > 2);
+
+ if (create_info.tmp_table())
+ {
+ int remove= 2;
+ while (remove && (f= it++))
+ {
+ if (f->flags & VERS_SYSTEM_FIELD)
+ {
+ it.remove();
+ remove--;
+ }
+ }
+ DBUG_ASSERT(remove == 0);
+ push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_UNKNOWN_ERROR,
+ "System versioning is stripped from temporary `%s.%s`",
+ table.db.str, table.table_name.str);
+ return false;
+ }
+
+ while ((f= it++))
+ {
+ if (f->flags & VERS_SYS_START_FLAG)
+ {
+ f_start= f;
+ if (f_end)
+ break;
+ }
+ else if (f->flags & VERS_SYS_END_FLAG)
+ {
+ f_end= f;
+ if (f_start)
+ break;
+ }
+ }
+
+ if (!f_start || !f_end)
+ {
+ my_error(ER_MISSING, MYF(0), src_table.table_name.str,
+ f_start ? "AS ROW END" : "AS ROW START");
+ return true;
+ }
+
+ as_row= start_end_t(f_start->field_name, f_end->field_name);
+ system_time= as_row;
+
+ create_info.options|= HA_VERSIONED_TABLE;
+ return false;
+}
+
+bool Vers_parse_info::need_check(const Alter_info *alter_info) const
+{
+ return versioned_fields || unversioned_fields ||
+ alter_info->flags & Alter_info::ALTER_ADD_PERIOD ||
+ alter_info->flags & Alter_info::ALTER_DROP_PERIOD ||
+ alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING ||
+ alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING || *this;
+}
+
+bool Vers_parse_info::check_with_conditions(const char *table_name) const
+{
+ if (!as_row.start || !as_row.end)
+ {
+ my_error(ER_MISSING, MYF(0), table_name,
+ as_row.start ? "AS ROW END" : "AS ROW START");
+ return true;
+ }
+
+ if (!system_time.start || !system_time.end)
+ {
+ my_error(ER_MISSING, MYF(0), table_name, "PERIOD FOR SYSTEM_TIME");
+ return true;
+ }
+
+ if (as_row.start != system_time.start || as_row.end != system_time.end)
+ {
+ my_error(ER_VERS_PERIOD_COLUMNS, MYF(0), as_row.start.str, as_row.end.str);
+ return true;
+ }
+
+ return false;
+}
+
+bool Vers_parse_info::check_sys_fields(const char *table_name,
+ Alter_info *alter_info, bool native)
+{
+ List_iterator<Create_field> it(alter_info->create_list);
+ uint found_flag= 0;
+ while (Create_field *f= it++)
+ {
+ vers_sys_type_t f_check_unit= VERS_UNDEFINED;
+ uint sys_flag= f->flags & VERS_SYSTEM_FIELD;
+
+ if (!sys_flag)
+ continue;
+
+ if (sys_flag & found_flag)
+ {
+ my_error(ER_VERS_DUPLICATE_ROW_START_END, MYF(0),
+ found_flag & VERS_SYS_START_FLAG ? "START" : "END",
+ f->field_name.str);
+ return true;
+ }
+
+ sys_flag|= found_flag;
+
+ if ((f->type_handler() == &type_handler_datetime2 ||
+ f->type_handler() == &type_handler_timestamp2) &&
+ f->length == MAX_DATETIME_FULL_WIDTH)
+ {
+ f_check_unit= VERS_TIMESTAMP;
+ }
+ else if (native
+ && f->type_handler() == &type_handler_longlong
+ && (f->flags & UNSIGNED_FLAG)
+ && f->length == (MY_INT64_NUM_DECIMAL_DIGITS - 1))
+ {
+ f_check_unit= VERS_TRX_ID;
+ }
+ else
+ {
+ if (!check_unit)
+ check_unit= VERS_TIMESTAMP;
+ goto error;
+ }
+
+ if (f_check_unit)
+ {
+ if (check_unit)
+ {
+ if (check_unit == f_check_unit)
+ {
+ if (check_unit == VERS_TRX_ID && !TR_table::use_transaction_registry)
+ {
+ my_error(ER_VERS_TRT_IS_DISABLED, MYF(0));
+ return true;
+ }
+ return false;
+ }
+ error:
+ my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), f->field_name.str,
+ check_unit == VERS_TIMESTAMP ?
+ "TIMESTAMP(6)" :
+ "BIGINT(20) UNSIGNED",
+ table_name);
+ return true;
+ }
+ check_unit= f_check_unit;
+ }
+ }
+
+ my_error(ER_MISSING, MYF(0), table_name, found_flag & VERS_SYS_START_FLAG ?
+ "ROW END" : found_flag ? "ROW START" : "ROW START/END");
+ return true;
+}
diff --git a/sql/handler.h b/sql/handler.h
index fc98e53e308..29a837b5ea8 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -34,6 +34,7 @@
#include "structs.h" /* SHOW_COMP_OPTION */
#include "sql_array.h" /* Dynamic_array<> */
#include "mdl.h"
+#include "vers_string.h"
#include "sql_analyze_stmt.h" // for Exec_time_tracker
@@ -161,6 +162,7 @@ enum enum_alter_inplace_result {
*/
#define HA_BINLOG_ROW_CAPABLE (1ULL << 34)
#define HA_BINLOG_STMT_CAPABLE (1ULL << 35)
+
/*
When a multiple key conflict happens in a REPLACE command mysql
expects the conflicts to be reported in the ascending order of
@@ -286,6 +288,17 @@ enum enum_alter_inplace_result {
*/
#define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
+/* The following are used by Spider */
+#define HA_CAN_FORCE_BULK_UPDATE (1ULL << 50)
+#define HA_CAN_FORCE_BULK_DELETE (1ULL << 51)
+#define HA_CAN_DIRECT_UPDATE_AND_DELETE (1ULL << 52)
+
+/* The following is for partition handler */
+#define HA_CAN_MULTISTEP_MERGE (1LL << 53)
+
+/* calling cmp_ref() on the engine is expensive */
+#define HA_CMP_REF_IS_EXPENSIVE (1ULL << 54)
+
/* bits in index_flags(index_number) for what you can do with index */
#define HA_READ_NEXT 1 /* TODO really use this flag */
#define HA_READ_PREV 2 /* supports ::index_prev */
@@ -400,6 +413,8 @@ enum enum_alter_inplace_result {
#define HA_LEX_CREATE_TMP_TABLE 1U
#define HA_CREATE_TMP_ALTER 8U
#define HA_LEX_CREATE_SEQUENCE 16U
+#define HA_VERSIONED_TABLE 32U
+#define HA_VTMD 64U
#define HA_MAX_REC_LENGTH 65535
@@ -435,6 +450,12 @@ static const uint MYSQL_START_TRANS_OPT_READ_WRITE = 4;
#define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE)
#define HA_CHECK_ALL (~0U)
+/* Options for info_push() */
+#define INFO_KIND_UPDATE_FIELDS 101
+#define INFO_KIND_UPDATE_VALUES 102
+#define INFO_KIND_FORCE_LIMIT_BEGIN 103
+#define INFO_KIND_FORCE_LIMIT_END 104
+
enum legacy_db_type
{
/* note these numerical values are fixed and can *not* be changed */
@@ -651,6 +672,15 @@ struct xid_t {
};
typedef struct xid_t XID;
+/*
+ The size of XID string representation in the form
+ 'gtrid', 'bqual', formatID
+ see xid_t::get_sql_string() for details.
+*/
+#define SQL_XIDSIZE (XIDDATASIZE * 2 + 8 + MY_INT64_NUM_DECIMAL_DIGITS)
+/* The 'buf' has to have space for at least SQL_XIDSIZE bytes. */
+uint get_sql_xid(XID *xid, char *buf);
+
/* for recover() handlerton call */
#define MIN_XID_LIST_SIZE 128
#define MAX_XID_LIST_SIZE (1024*128)
@@ -1219,7 +1249,7 @@ struct handlerton
bool (*flush_logs)(handlerton *hton);
bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
uint (*partition_flags)();
- uint (*alter_table_flags)(uint flags);
+ ulonglong (*alter_table_flags)(ulonglong flags);
int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables,
class Item *cond,
@@ -1382,6 +1412,16 @@ struct handlerton
*/
int (*discover_table_structure)(handlerton *hton, THD* thd,
TABLE_SHARE *share, HA_CREATE_INFO *info);
+
+ /*
+ System Versioning
+ */
+ /** Determine if system-versioned data was modified by the transaction.
+ @param[in,out] thd current session
+ @param[out] trx_id transaction start ID
+ @return transaction commit ID
+ @retval 0 if no system-versioned data was affected by the transaction */
+ ulonglong (*prepare_commit_versioned)(THD *thd, ulonglong *trx_id);
};
@@ -1429,10 +1469,15 @@ handlerton *ha_default_tmp_handlerton(THD *thd);
*/
#define HTON_NO_BINLOG_ROW_OPT (1 << 9)
#define HTON_SUPPORTS_EXTENDED_KEYS (1 <<10) //supports extended keys
+#define HTON_NATIVE_SYS_VERSIONING (1 << 11) //Engine supports System Versioning
// MySQL compatibility. Unused.
#define HTON_SUPPORTS_FOREIGN_KEYS (1 << 0) //Foreign key constraint supported.
+#define HTON_CAN_MERGE (1 <<11) //Merge type table
+// Engine needs to access the main connect string in partitions
+#define HTON_CAN_READ_CONNECT_STRING_IN_PARTITION (1 <<12)
+
class Ha_trx_info;
struct THD_TRANS
@@ -1633,6 +1678,7 @@ typedef struct {
ulonglong data_file_length;
ulonglong max_data_file_length;
ulonglong index_file_length;
+ ulonglong max_index_file_length;
ulonglong delete_length;
ha_rows records;
ulong mean_rec_length;
@@ -1674,6 +1720,86 @@ struct Schema_specification_st
}
};
+class Create_field;
+
+enum vers_sys_type_t
+{
+ VERS_UNDEFINED= 0,
+ VERS_TIMESTAMP,
+ VERS_TRX_ID
+};
+
+struct Vers_parse_info
+{
+ Vers_parse_info() :
+ check_unit(VERS_UNDEFINED),
+ versioned_fields(false),
+ unversioned_fields(false)
+ {}
+
+ struct start_end_t
+ {
+ start_end_t()
+ {}
+ start_end_t(LEX_CSTRING _start, LEX_CSTRING _end) :
+ start(_start),
+ end(_end) {}
+ LString_i start;
+ LString_i end;
+ };
+
+ start_end_t system_time;
+ start_end_t as_row;
+ vers_sys_type_t check_unit;
+
+ void set_system_time(LString start, LString end)
+ {
+ system_time.start= start;
+ system_time.end= end;
+ }
+
+protected:
+ friend struct Table_scope_and_contents_source_st;
+ void set_start(const LEX_CSTRING field_name)
+ {
+ as_row.start= field_name;
+ system_time.start= field_name;
+ }
+ void set_end(const LEX_CSTRING field_name)
+ {
+ as_row.end= field_name;
+ system_time.end= field_name;
+ }
+ bool is_start(const char *name) const;
+ bool is_end(const char *name) const;
+ bool is_start(const Create_field &f) const;
+ bool is_end(const Create_field &f) const;
+ bool fix_implicit(THD *thd, Alter_info *alter_info, int *added= NULL);
+ operator bool() const
+ {
+ return as_row.start || as_row.end || system_time.start || system_time.end;
+ }
+ bool need_check(const Alter_info *alter_info) const;
+ bool check_with_conditions(const char *table_name) const;
+ bool check_sys_fields(const char *table_name, Alter_info *alter_info,
+ bool native);
+
+public:
+ static const LString default_start;
+ static const LString default_end;
+
+ bool fix_alter_info(THD *thd, Alter_info *alter_info,
+ HA_CREATE_INFO *create_info, TABLE *table);
+ bool fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_info,
+ TABLE_LIST &src_table, TABLE_LIST &table);
+
+ /**
+ At least one field was specified 'WITH/WITHOUT SYSTEM VERSIONING'.
+ Useful for error handling.
+ */
+ bool versioned_fields : 1;
+ bool unversioned_fields : 1;
+};
/**
A helper struct for table DDL statements, e.g.:
@@ -1695,9 +1821,9 @@ struct Table_scope_and_contents_source_st
LEX_CUSTRING tabledef_version;
LEX_CSTRING connect_string;
LEX_CSTRING comment;
+ LEX_CSTRING alias;
const char *password, *tablespace;
const char *data_file_name, *index_file_name;
- const char *alias;
ulonglong max_rows,min_rows;
ulonglong auto_increment_value;
ulong table_options; ///< HA_OPTION_ values
@@ -1749,6 +1875,16 @@ struct Table_scope_and_contents_source_st
bool table_was_deleted;
sequence_definition *seq_create_info;
+ Vers_parse_info vers_info;
+
+ bool vers_fix_system_fields(THD *thd, Alter_info *alter_info,
+ const TABLE_LIST &create_table,
+ const TABLE_LIST *select_table= NULL,
+ List<Item> *items= NULL,
+ bool *versioned_write= NULL);
+
+ bool vers_native(THD *thd) const;
+
void init()
{
bzero(this, sizeof(*this));
@@ -1759,6 +1895,16 @@ struct Table_scope_and_contents_source_st
db_type= tmp_table() ? ha_default_tmp_handlerton(thd)
: ha_default_handlerton(thd);
}
+
+ bool versioned() const
+ {
+ return options & HA_VERSIONED_TABLE;
+ }
+
+ bool vtmd() const
+ {
+ return options & HA_VTMD;
+ }
};
@@ -1802,6 +1948,13 @@ struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET);
return false;
}
+ ulong table_options_with_row_type()
+ {
+ if (row_type == ROW_TYPE_DYNAMIC || row_type == ROW_TYPE_PAGE)
+ return table_options | HA_OPTION_PACK_RECORD;
+ else
+ return table_options;
+ }
};
@@ -2025,6 +2178,14 @@ public:
static const HA_ALTER_FLAGS ALTER_DROP_CHECK_CONSTRAINT= 1ULL << 40;
+ static const HA_ALTER_FLAGS ALTER_DROP_HISTORICAL = 1ULL << 41;
+
+ static const HA_ALTER_FLAGS ALTER_COLUMN_UNVERSIONED = 1ULL << 42;
+
+ static const HA_ALTER_FLAGS ALTER_ADD_SYSTEM_VERSIONING= 1ULL << 43;
+
+ static const HA_ALTER_FLAGS ALTER_DROP_SYSTEM_VERSIONING= 1ULL << 44;
+
/**
Create options (like MAX_ROWS) for the new version of table.
@@ -2575,9 +2736,10 @@ public:
ha_statistics():
data_file_length(0), max_data_file_length(0),
- index_file_length(0), delete_length(0), auto_increment_value(0),
- records(0), deleted(0), mean_rec_length(0), create_time(0),
- check_time(0), update_time(0), block_size(0), mrr_length_per_rec(0)
+ index_file_length(0), max_index_file_length(0), delete_length(0),
+ auto_increment_value(0), records(0), deleted(0), mean_rec_length(0),
+ create_time(0), check_time(0), update_time(0), block_size(0),
+ mrr_length_per_rec(0)
{}
};
@@ -2708,7 +2870,8 @@ public:
/** Length of ref (1-8 or the clustered key length) */
uint ref_length;
FT_INFO *ft_handler;
- enum {NONE=0, INDEX, RND} inited;
+ enum init_stat { NONE=0, INDEX, RND };
+ init_stat inited, pre_inited;
const COND *pushed_cond;
/**
@@ -2774,6 +2937,11 @@ public:
virtual void unbind_psi();
virtual void rebind_psi();
+ bool set_top_table_fields;
+ struct TABLE *top_table;
+ Field **top_table_field;
+ uint top_table_fields;
+
private:
/**
The lock type set by when calling::ha_external_lock(). This is
@@ -2802,13 +2970,15 @@ public:
key_used_on_scan(MAX_KEY),
active_index(MAX_KEY), keyread(MAX_KEY),
ref_length(sizeof(my_off_t)),
- ft_handler(0), inited(NONE),
+ ft_handler(0), inited(NONE), pre_inited(NONE),
pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
tracker(NULL),
pushed_idx_cond(NULL),
pushed_idx_cond_keyno(MAX_KEY),
auto_inc_intervals_count(0),
- m_psi(NULL), m_lock_type(F_UNLCK), ha_share(NULL)
+ m_psi(NULL), set_top_table_fields(FALSE), top_table(0),
+ top_table_field(0), top_table_fields(0),
+ m_lock_type(F_UNLCK), ha_share(NULL)
{
DBUG_PRINT("info",
("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
@@ -2829,7 +2999,7 @@ public:
/* ha_ methods: pubilc wrappers for private virtual API */
int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked,
- MEM_ROOT *mem_root= 0);
+ MEM_ROOT *mem_root= 0, List<String> *partitions_to_open=NULL);
int ha_index_init(uint idx, bool sorted)
{
DBUG_EXECUTE_IF("ha_index_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
@@ -2941,7 +3111,7 @@ public:
DBUG_RETURN(ret);
}
int ha_bulk_update_row(const uchar *old_data, const uchar *new_data,
- uint *dup_key_found);
+ ha_rows *dup_key_found);
int ha_delete_all_rows();
int ha_truncate();
int ha_reset_auto_increment(ulonglong value);
@@ -3082,6 +3252,7 @@ public:
Number of rows in table. It will only be called if
(table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
*/
+ virtual int pre_records() { return 0; }
virtual ha_rows records() { return stats.records; }
/**
Return upper bound of current number of records in the table
@@ -3138,7 +3309,7 @@ public:
@retval 0 Success
@retval >0 Error code
*/
- virtual int exec_bulk_update(uint *dup_key_found)
+ virtual int exec_bulk_update(ha_rows *dup_key_found)
{
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
@@ -3147,7 +3318,7 @@ public:
Perform any needed clean-up, no outstanding updates are there at the
moment.
*/
- virtual void end_bulk_update() { return; }
+ virtual int end_bulk_update() { return 0; }
/**
Execute all outstanding deletes and close down the bulk delete.
@@ -3159,6 +3330,79 @@ public:
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
}
+ virtual int pre_index_read_map(const uchar *key,
+ key_part_map keypart_map,
+ enum ha_rkey_function find_flag,
+ bool use_parallel)
+ { return 0; }
+ virtual int pre_index_first(bool use_parallel)
+ { return 0; }
+ virtual int pre_index_last(bool use_parallel)
+ { return 0; }
+ virtual int pre_index_read_last_map(const uchar *key,
+ key_part_map keypart_map,
+ bool use_parallel)
+ { return 0; }
+/*
+ virtual int pre_read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
+ KEY_MULTI_RANGE *ranges,
+ uint range_count,
+ bool sorted, HANDLER_BUFFER *buffer,
+ bool use_parallel);
+*/
+ virtual int pre_multi_range_read_next(bool use_parallel)
+ { return 0; }
+ virtual int pre_read_range_first(const key_range *start_key,
+ const key_range *end_key,
+ bool eq_range, bool sorted,
+ bool use_parallel)
+ { return 0; }
+ virtual int pre_ft_read(bool use_parallel)
+ { return 0; }
+ virtual int pre_rnd_next(bool use_parallel)
+ { return 0; }
+ int ha_pre_rnd_init(bool scan)
+ {
+ int result;
+ DBUG_ENTER("ha_pre_rnd_init");
+ DBUG_ASSERT(pre_inited==NONE || (pre_inited==RND && scan));
+ pre_inited= (result= pre_rnd_init(scan)) ? NONE: RND;
+ DBUG_RETURN(result);
+ }
+ int ha_pre_rnd_end()
+ {
+ DBUG_ENTER("ha_pre_rnd_end");
+ DBUG_ASSERT(pre_inited==RND);
+ pre_inited=NONE;
+ DBUG_RETURN(pre_rnd_end());
+ }
+ virtual int pre_rnd_init(bool scan) { return 0; }
+ virtual int pre_rnd_end() { return 0; }
+ virtual int pre_index_init(uint idx, bool sorted) { return 0; }
+ virtual int pre_index_end() { return 0; }
+ int ha_pre_index_init(uint idx, bool sorted)
+ {
+ int result;
+ DBUG_ENTER("ha_pre_index_init");
+ DBUG_ASSERT(pre_inited==NONE);
+ if (!(result= pre_index_init(idx, sorted)))
+ pre_inited=INDEX;
+ DBUG_RETURN(result);
+ }
+ int ha_pre_index_end()
+ {
+ DBUG_ENTER("ha_pre_index_end");
+ DBUG_ASSERT(pre_inited==INDEX);
+ pre_inited=NONE;
+ DBUG_RETURN(pre_index_end());
+ }
+ int ha_pre_index_or_rnd_end()
+ {
+ return (pre_inited == INDEX ?
+ ha_pre_index_end() :
+ pre_inited == RND ? ha_pre_rnd_end() : 0 );
+ }
+
/**
@brief
Positions an index cursor to the index specified in the
@@ -3191,6 +3435,18 @@ protected:
virtual int index_last(uchar * buf)
{ return HA_ERR_WRONG_COMMAND; }
virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
+ /**
+ @brief
+ The following functions works like index_read, but it find the last
+ row with the current key value or prefix.
+ @returns @see index_read_map().
+ */
+ virtual int index_read_last_map(uchar * buf, const uchar * key,
+ key_part_map keypart_map)
+ {
+ uint key_len= calculate_key_len(table, active_index, key, keypart_map);
+ return index_read_last(buf, key, key_len);
+ }
virtual int close(void)=0;
inline void update_rows_read()
{
@@ -3267,10 +3523,12 @@ public:
int compare_key(key_range *range);
int compare_key2(key_range *range) const;
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
- void ft_end() { ft_handler=NULL; }
+ virtual int pre_ft_init() { return HA_ERR_WRONG_COMMAND; }
+ virtual void ft_end() {}
+ virtual int pre_ft_end() { return 0; }
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
{ return NULL; }
-private:
+public:
virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
virtual int rnd_next(uchar *buf)=0;
virtual int rnd_pos(uchar * buf, uchar *pos)=0;
@@ -3290,6 +3548,7 @@ public:
/* Same as above, but with statistics */
inline int ha_ft_read(uchar *buf);
+ inline void ha_ft_end() { ft_end(); ft_handler=NULL; }
int ha_rnd_next(uchar *buf);
int ha_rnd_pos(uchar *buf, uchar *pos);
inline int ha_rnd_pos_by_record(uchar *buf);
@@ -3319,6 +3578,9 @@ public:
virtual int info(uint)=0; // see my_base.h for full description
virtual void get_dynamic_partition_info(PARTITION_STATS *stat_info,
uint part_id);
+ virtual void set_partitions_to_open(List<String> *partition_names) {}
+ virtual int change_partitions_to_open(List<String> *partition_names)
+ { return 0; }
virtual int extra(enum ha_extra_function operation)
{ return 0; }
virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
@@ -3347,6 +3609,8 @@ public:
virtual void try_semi_consistent_read(bool) {}
virtual void unlock_row() {}
virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
+ virtual bool need_info_for_auto_inc() { return 0; }
+ virtual bool can_use_for_auto_inc_init() { return 1; }
virtual void get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong nb_desired_values,
ulonglong *first_value,
@@ -3454,6 +3718,7 @@ public:
return 0;
}
virtual void set_part_info(partition_info *part_info) {return;}
+ virtual void return_record_by_parent() { return; }
virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
@@ -3658,6 +3923,41 @@ public:
virtual void cond_pop() { return; };
/**
+ Push metadata for the current operation down to the table handler.
+ */
+ virtual int info_push(uint info_type, void *info) { return 0; };
+
+ /**
+ This function is used to get correlating of a parent (table/column)
+ and children (table/column). When conditions are pushed down to child
+ table (like child of myisam_merge), child table needs to know about
+ which table/column is my parent for understanding conditions.
+ */
+ virtual int set_top_table_and_fields(TABLE *top_table,
+ Field **top_table_field,
+ uint top_table_fields)
+ {
+ if (!set_top_table_fields)
+ {
+ set_top_table_fields= TRUE;
+ this->top_table= top_table;
+ this->top_table_field= top_table_field;
+ this->top_table_fields= top_table_fields;
+ }
+ return 0;
+ }
+ virtual void clear_top_table_fields()
+ {
+ if (set_top_table_fields)
+ {
+ set_top_table_fields= FALSE;
+ top_table= NULL;
+ top_table_field= NULL;
+ top_table_fields= 0;
+ }
+ }
+
+ /**
Push down an index condition to the handler.
The server will use this method to push down a condition it wants
@@ -3690,6 +3990,10 @@ public:
pushed_idx_cond_keyno= MAX_KEY;
in_range_check_pushed_down= false;
}
+
+ /* Needed for partition / spider */
+ virtual TABLE_LIST *get_next_global_for_child() { return NULL; }
+
/**
Part of old, deprecated in-place ALTER API.
*/
@@ -3964,7 +4268,7 @@ public:
but we don't have a primary key
*/
virtual void use_hidden_primary_key();
- virtual uint alter_table_flags(uint flags)
+ virtual ulonglong alter_table_flags(ulonglong flags)
{
if (ht->alter_table_flags)
return ht->alter_table_flags(flags);
@@ -4001,8 +4305,8 @@ protected:
virtual int delete_table(const char *name);
public:
- inline bool check_table_binlog_row_based(bool binlog_row);
-private:
+ bool check_table_binlog_row_based(bool binlog_row);
+
/* Cache result to avoid extra calls */
inline void mark_trx_read_write()
{
@@ -4012,6 +4316,8 @@ private:
mark_trx_read_write_internal();
}
}
+
+private:
void mark_trx_read_write_internal();
bool check_table_binlog_row_based_internal(bool binlog_row);
@@ -4073,6 +4379,49 @@ private:
{
return HA_ERR_WRONG_COMMAND;
}
+
+ /* Perform initialization for a direct update request */
+public:
+ int ha_direct_update_rows(ha_rows *update_rows);
+ virtual int direct_update_rows_init()
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+private:
+ virtual int pre_direct_update_rows_init()
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+ virtual int direct_update_rows(ha_rows *update_rows __attribute__((unused)))
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+ virtual int pre_direct_update_rows()
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+
+ /* Perform initialization for a direct delete request */
+public:
+ int ha_direct_delete_rows(ha_rows *delete_rows);
+ virtual int direct_delete_rows_init()
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+private:
+ virtual int pre_direct_delete_rows_init()
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+ virtual int direct_delete_rows(ha_rows *delete_rows __attribute__((unused)))
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+ virtual int pre_direct_delete_rows()
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+
/**
Reset state of file to after 'open'.
This function is called after every statement for all tables used
@@ -4130,6 +4479,11 @@ protected:
virtual int index_read(uchar * buf, const uchar * key, uint key_len,
enum ha_rkey_function find_flag)
{ return HA_ERR_WRONG_COMMAND; }
+ virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
+ {
+ my_errno= HA_ERR_WRONG_COMMAND;
+ return HA_ERR_WRONG_COMMAND;
+ }
friend class ha_partition;
friend class ha_sequence;
public:
@@ -4147,7 +4501,7 @@ public:
@retval 1 Bulk delete not used, normal operation used
*/
virtual int bulk_update_row(const uchar *old_data, const uchar *new_data,
- uint *dup_key_found)
+ ha_rows *dup_key_found)
{
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
@@ -4253,6 +4607,11 @@ public:
*/
virtual int find_unique_row(uchar *record, uint unique_ref)
{ return -1; /*unsupported */}
+
+ bool native_versioned() const
+ { DBUG_ASSERT(ht); return partition_ht()->flags & HTON_NATIVE_SYS_VERSIONING; }
+ virtual void update_partition(uint part_id)
+ {}
protected:
Handler_share *get_ha_share_ptr();
void set_ha_share_ptr(Handler_share *arg_ha_share);
@@ -4330,7 +4689,7 @@ int ha_create_table(THD *thd, const char *path,
const char *db, const char *table_name,
HA_CREATE_INFO *create_info, LEX_CUSTRING *frm);
int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
- const char *db, const char *alias, bool generate_warning);
+ const LEX_CSTRING *db, const LEX_CSTRING *alias, bool generate_warning);
/* statistics and info */
bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
@@ -4368,7 +4727,7 @@ public:
int ha_discover_table(THD *thd, TABLE_SHARE *share);
int ha_discover_table_names(THD *thd, LEX_CSTRING *db, MY_DIR *dirp,
Discovered_table_list *result, bool reusable);
-bool ha_table_exists(THD *thd, const char *db, const char *table_name,
+bool ha_table_exists(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name,
handlerton **hton= 0, bool *is_sequence= 0);
#endif
@@ -4419,9 +4778,9 @@ const char *get_canonical_filename(handler *file, const char *path,
bool mysql_xa_recover(THD *thd);
void commit_checkpoint_notify_ha(handlerton *hton, void *cookie);
-inline const char *table_case_name(HA_CREATE_INFO *info, const char *name)
+inline const LEX_CSTRING *table_case_name(HA_CREATE_INFO *info, const LEX_CSTRING *name)
{
- return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
+ return ((lower_case_table_names == 2 && info->alias.str) ? &info->alias : name);
}
typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
diff --git a/sql/hostname.cc b/sql/hostname.cc
index 0e60dde893c..2d39a8bb03d 100644
--- a/sql/hostname.cc
+++ b/sql/hostname.cc
@@ -180,7 +180,7 @@ void hostname_cache_unlock()
static void prepare_hostname_cache_key(const char *ip_string,
char *ip_key)
{
- int ip_string_length= strlen(ip_string);
+ size_t ip_string_length= strlen(ip_string);
DBUG_ASSERT(ip_string_length < HOST_ENTRY_KEY_SIZE);
memset(ip_key, 0, HOST_ENTRY_KEY_SIZE);
@@ -229,12 +229,12 @@ static void add_hostname_impl(const char *ip_key, const char *hostname,
{
if (hostname != NULL)
{
- uint len= strlen(hostname);
+ size_t len= strlen(hostname);
if (len > sizeof(entry->m_hostname) - 1)
len= sizeof(entry->m_hostname) - 1;
memcpy(entry->m_hostname, hostname, len);
entry->m_hostname[len]= '\0';
- entry->m_hostname_length= len;
+ entry->m_hostname_length= (uint)len;
DBUG_PRINT("info",
("Adding/Updating '%s' -> '%s' (validated) to the hostname cache...'",
@@ -702,12 +702,12 @@ int ip_to_hostname(struct sockaddr_storage *ip_storage,
/* Simulating ipv4 192.0.2.126 */
debug_addr= & debug_sock_addr[0];
debug_addr->sin_family= AF_INET;
- debug_addr->sin_addr.s_addr= inet_addr("192.0.2.126");
+ inet_pton(AF_INET,"192.0.2.126", &debug_addr->sin_addr);
/* Simulating ipv4 192.0.2.127 */
debug_addr= & debug_sock_addr[1];
debug_addr->sin_family= AF_INET;
- debug_addr->sin_addr.s_addr= inet_addr("192.0.2.127");
+ inet_pton(AF_INET,"192.0.2.127", &debug_addr->sin_addr);
debug_addr_info[0].ai_addr= (struct sockaddr*) & debug_sock_addr[0];
debug_addr_info[0].ai_addrlen= sizeof (struct sockaddr_in);
@@ -734,12 +734,12 @@ int ip_to_hostname(struct sockaddr_storage *ip_storage,
/* Simulating ipv4 192.0.2.5 */
debug_addr= & debug_sock_addr[0];
debug_addr->sin_family= AF_INET;
- debug_addr->sin_addr.s_addr= inet_addr("192.0.2.5");
+ inet_pton(AF_INET,"192.0.2.5", &debug_addr->sin_addr);
/* Simulating ipv4 192.0.2.4 */
debug_addr= & debug_sock_addr[1];
debug_addr->sin_family= AF_INET;
- debug_addr->sin_addr.s_addr= inet_addr("192.0.2.4");
+ inet_pton(AF_INET,"192.0.2.4", &debug_addr->sin_addr);
debug_addr_info[0].ai_addr= (struct sockaddr*) & debug_sock_addr[0];
debug_addr_info[0].ai_addrlen= sizeof (struct sockaddr_in);
@@ -774,44 +774,13 @@ int ip_to_hostname(struct sockaddr_storage *ip_storage,
debug_addr= & debug_sock_addr[0];
debug_addr->sin6_family= AF_INET6;
ip6= & debug_addr->sin6_addr;
- /* inet_pton not available on Windows XP. */
- ip6->s6_addr[ 0] = 0x20;
- ip6->s6_addr[ 1] = 0x01;
- ip6->s6_addr[ 2] = 0x0d;
- ip6->s6_addr[ 3] = 0xb8;
- ip6->s6_addr[ 4] = 0x00;
- ip6->s6_addr[ 5] = 0x00;
- ip6->s6_addr[ 6] = 0x00;
- ip6->s6_addr[ 7] = 0x00;
- ip6->s6_addr[ 8] = 0x00;
- ip6->s6_addr[ 9] = 0x00;
- ip6->s6_addr[10] = 0x00;
- ip6->s6_addr[11] = 0x00;
- ip6->s6_addr[12] = 0x00;
- ip6->s6_addr[13] = 0x06;
- ip6->s6_addr[14] = 0x00;
- ip6->s6_addr[15] = 0x7e;
+ inet_pton(AF_INET6,"2001:DB8::6:7E",ip6);
/* Simulating ipv6 2001:DB8::6:7F */
debug_addr= & debug_sock_addr[1];
debug_addr->sin6_family= AF_INET6;
ip6= & debug_addr->sin6_addr;
- ip6->s6_addr[ 0] = 0x20;
- ip6->s6_addr[ 1] = 0x01;
- ip6->s6_addr[ 2] = 0x0d;
- ip6->s6_addr[ 3] = 0xb8;
- ip6->s6_addr[ 4] = 0x00;
- ip6->s6_addr[ 5] = 0x00;
- ip6->s6_addr[ 6] = 0x00;
- ip6->s6_addr[ 7] = 0x00;
- ip6->s6_addr[ 8] = 0x00;
- ip6->s6_addr[ 9] = 0x00;
- ip6->s6_addr[10] = 0x00;
- ip6->s6_addr[11] = 0x00;
- ip6->s6_addr[12] = 0x00;
- ip6->s6_addr[13] = 0x06;
- ip6->s6_addr[14] = 0x00;
- ip6->s6_addr[15] = 0x7f;
+ inet_pton(AF_INET6,"2001:DB8::6:7F",ip6);
debug_addr_info[0].ai_addr= (struct sockaddr*) & debug_sock_addr[0];
debug_addr_info[0].ai_addrlen= sizeof (struct sockaddr_in6);
@@ -946,7 +915,7 @@ int ip_to_hostname(struct sockaddr_storage *ip_storage,
{
err_status=
- vio_get_normalized_ip_string(addr_info->ai_addr, addr_info->ai_addrlen,
+ vio_get_normalized_ip_string(addr_info->ai_addr, (int)addr_info->ai_addrlen,
ip_buffer, sizeof (ip_buffer));
DBUG_ASSERT(!err_status);
}
@@ -990,7 +959,7 @@ int ip_to_hostname(struct sockaddr_storage *ip_storage,
char ip_buffer[HOST_ENTRY_KEY_SIZE];
err_status=
- vio_get_normalized_ip_string(addr_info->ai_addr, addr_info->ai_addrlen,
+ vio_get_normalized_ip_string(addr_info->ai_addr, (int)addr_info->ai_addrlen,
ip_buffer, sizeof (ip_buffer));
DBUG_ASSERT(!err_status);
diff --git a/sql/innodb_priv.h b/sql/innodb_priv.h
index 27aa9ac8645..7fbaa7cfc2f 100644
--- a/sql/innodb_priv.h
+++ b/sql/innodb_priv.h
@@ -22,11 +22,11 @@
class THD;
-int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
+int get_quote_char_for_identifier(THD *thd, const char *name, size_t length);
bool schema_table_store_record(THD *thd, TABLE *table);
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
-uint strconvert(CHARSET_INFO *from_cs, const char *from, uint from_length,
- CHARSET_INFO *to_cs, char *to, uint to_length,
+uint strconvert(CHARSET_INFO *from_cs, const char *from, size_t from_length,
+ CHARSET_INFO *to_cs, char *to, size_t to_length,
uint *errors);
void sql_print_error(const char *format, ...);
diff --git a/sql/item.cc b/sql/item.cc
index fb620aa84d9..d3345f69a40 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2017, MariaDB Corporation
+ Copyright (c) 2010, 2018, 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
@@ -78,6 +78,12 @@ inline void set_max_sum_func_level(THD *thd, SELECT_LEX *select)
select->nest_level - 1);
}
+
+MEM_ROOT *get_thd_memroot(THD *thd)
+{
+ return thd->mem_root;
+}
+
/*****************************************************************************
** Item functions
*****************************************************************************/
@@ -124,38 +130,6 @@ longlong Item::val_datetime_packed_result()
/**
Get date/time/datetime.
- Optionally extend TIME result to DATETIME.
-*/
-bool Item::get_date_with_conversion(MYSQL_TIME *ltime, ulonglong fuzzydate)
-{
- THD *thd= current_thd;
-
- /*
- Some TIME type items return error when trying to do get_date()
- without TIME_TIME_ONLY set (e.g. Item_field for Field_time).
- In the SQL standard time->datetime conversion mode we add TIME_TIME_ONLY.
- In the legacy time->datetime conversion mode we do not add TIME_TIME_ONLY
- and leave it to get_date() to check date.
- */
- ulonglong time_flag= (field_type() == MYSQL_TYPE_TIME &&
- !(thd->variables.old_behavior & OLD_MODE_ZERO_DATE_TIME_CAST)) ?
- TIME_TIME_ONLY : 0;
- if (get_date(ltime, fuzzydate | time_flag))
- return true;
- if (ltime->time_type == MYSQL_TIMESTAMP_TIME &&
- !(fuzzydate & TIME_TIME_ONLY))
- {
- MYSQL_TIME tmp;
- if (time_to_datetime_with_warn(thd, ltime, &tmp, fuzzydate))
- return null_value= true;
- *ltime= tmp;
- }
- return false;
-}
-
-
-/**
- Get date/time/datetime.
If DATETIME or DATE result is returned, it's converted to TIME.
*/
bool Item::get_time_with_conversion(THD *thd, MYSQL_TIME *ltime,
@@ -532,7 +506,6 @@ Item::Item(THD *thd):
marker= 0;
maybe_null=null_value=with_sum_func=with_window_func=with_field=0;
in_rollup= 0;
- with_subselect= 0;
/* Initially this item is not attached to any JOIN_TAB. */
join_tab_idx= MAX_TABLES;
@@ -577,8 +550,7 @@ Item::Item(THD *thd, Item *item):
with_window_func(item->with_window_func),
with_field(item->with_field),
fixed(item->fixed),
- is_autogenerated_name(item->is_autogenerated_name),
- with_subselect(item->has_subquery())
+ is_autogenerated_name(item->is_autogenerated_name)
{
next= thd->free_list; // Put in free list
thd->free_list= this;
@@ -612,7 +584,7 @@ void Item::print_item_w_name(String *str, enum_query_type query_type)
DBUG_ASSERT(name.length == strlen(name.str));
THD *thd= current_thd;
str->append(STRING_WITH_LEN(" AS "));
- append_identifier(thd, str, name.str, name.length);
+ append_identifier(thd, str, &name);
}
}
@@ -758,10 +730,10 @@ Item_ident::Item_ident(THD *thd, Name_resolution_context *context_arg,
Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg,
const LEX_CSTRING *field_name_arg)
:Item_result_field(thd), orig_db_name(NullS),
- orig_table_name(view_arg->table_name),
+ orig_table_name(view_arg->table_name.str),
orig_field_name(*field_name_arg),
context(&view_arg->view->select_lex.context),
- db_name(NullS), table_name(view_arg->alias),
+ db_name(NullS), table_name(view_arg->alias.str),
field_name(*field_name_arg),
alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX),
cached_table(NULL), depended_from(NULL), can_be_depended(TRUE)
@@ -883,6 +855,34 @@ bool Item_field::add_field_to_set_processor(void *arg)
DBUG_RETURN(FALSE);
}
+
+/**
+ Rename fields in an expression to new field name as speficied by ALTER TABLE
+*/
+
+bool Item_field::rename_fields_processor(void *arg)
+{
+ Item::func_processor_rename *rename= (Item::func_processor_rename*) arg;
+ List_iterator<Create_field> def_it(rename->fields);
+ Create_field *def;
+
+ while ((def=def_it++))
+ {
+ if (def->change.str &&
+ (!db_name || !db_name[0] ||
+ !my_strcasecmp(table_alias_charset, db_name, rename->db_name.str)) &&
+ (!table_name || !table_name[0] ||
+ !my_strcasecmp(table_alias_charset, table_name, rename->table_name.str)) &&
+ !my_strcasecmp(system_charset_info, field_name.str, def->change.str))
+ {
+ field_name= def->field_name;
+ break;
+ }
+ }
+ return 0;
+}
+
+
/**
Check if an Item_field references some field from a list of fields.
@@ -1150,6 +1150,16 @@ bool Item::check_type_can_return_text(const char *opname) const
bool Item::check_type_scalar(const char *opname) const
{
+ /*
+ fixed==true usually means than the Item has an initialized
+ and reliable data type handler and attributes.
+ Item_outer_ref is an exception. It copies the data type and the attributes
+ from the referenced Item in the constructor, but then sets "fixed" to false,
+ and re-fixes itself again in fix_inner_refs().
+ This hack in Item_outer_ref should probably be refactored eventually.
+ Discuss with Sanja.
+ */
+ DBUG_ASSERT(fixed || type() == REF_ITEM);
const Type_handler *handler= type_handler();
if (handler->is_scalar_type())
return false;
@@ -1158,7 +1168,7 @@ bool Item::check_type_scalar(const char *opname) const
}
-void Item::set_name(THD *thd, const char *str, uint length, CHARSET_INFO *cs)
+void Item::set_name(THD *thd, const char *str, size_t length, CHARSET_INFO *cs)
{
if (!length)
{
@@ -1417,67 +1427,73 @@ Item *Item_param::safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
As a extra convenience the time structure is reset on error or NULL values!
*/
-bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
+bool Item::get_date_from_int(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
- if (field_type() == MYSQL_TYPE_TIME)
- fuzzydate|= TIME_TIME_ONLY;
+ longlong value= val_int();
+ bool neg= !unsigned_flag && value < 0;
+ if (null_value || int_to_datetime_with_warn(neg, neg ? -value : value,
+ ltime, fuzzydate,
+ field_name_or_null()))
+ return null_value|= make_zero_date(ltime, fuzzydate);
+ return null_value= false;
+}
- switch (result_type()) {
- case INT_RESULT:
- {
- longlong value= val_int();
- bool neg= !unsigned_flag && value < 0;
- if (field_type() == MYSQL_TYPE_YEAR)
- {
- if (max_length == 2)
- {
- if (value < 70)
- value+= 2000;
- else if (value <= 1900)
- value+= 1900;
- }
- value*= 10000; /* make it YYYYMMHH */
- }
- if (null_value || int_to_datetime_with_warn(neg, neg ? -value : value,
- ltime, fuzzydate,
- field_name_or_null()))
- goto err;
- break;
- }
- case REAL_RESULT:
- {
- double value= val_real();
- if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate,
- field_name_or_null()))
- goto err;
- break;
- }
- case DECIMAL_RESULT:
- {
- my_decimal value, *res;
- if (!(res= val_decimal(&value)) ||
- decimal_to_datetime_with_warn(res, ltime, fuzzydate,
- field_name_or_null()))
- goto err;
- break;
- }
- case STRING_RESULT:
+
+bool Item::get_date_from_year(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ longlong value= val_int();
+ DBUG_ASSERT(unsigned_flag || value >= 0);
+ if (max_length == 2)
{
- char buff[40];
- String tmp(buff,sizeof(buff), &my_charset_bin),*res;
- if (!(res=val_str(&tmp)) ||
- str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
- ltime, fuzzydate))
- goto err;
- break;
- }
- default:
- DBUG_ASSERT(0);
+ if (value < 70)
+ value+= 2000;
+ else if (value <= 1900)
+ value+= 1900;
}
+ value*= 10000; /* make it YYYYMMHH */
+ if (null_value || int_to_datetime_with_warn(false, value,
+ ltime, fuzzydate,
+ field_name_or_null()))
+ return null_value|= make_zero_date(ltime, fuzzydate);
+ return null_value= false;
+}
- return null_value= 0;
-err:
+bool Item::get_date_from_real(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ double value= val_real();
+ if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate,
+ field_name_or_null()))
+ return null_value|= make_zero_date(ltime, fuzzydate);
+ return null_value= false;
+}
+
+
+bool Item::get_date_from_decimal(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ my_decimal value, *res;
+ if (!(res= val_decimal(&value)) ||
+ decimal_to_datetime_with_warn(res, ltime, fuzzydate,
+ field_name_or_null()))
+ return null_value|= make_zero_date(ltime, fuzzydate);
+ return null_value= false;
+}
+
+
+bool Item::get_date_from_string(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ char buff[40];
+ String tmp(buff,sizeof(buff), &my_charset_bin),*res;
+ if (!(res=val_str(&tmp)) ||
+ str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
+ ltime, fuzzydate))
+ return null_value|= make_zero_date(ltime, fuzzydate);
+ return null_value= false;
+}
+
+
+bool Item::make_zero_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
/*
if the item was not null and convertion failed, we return a zero date
if allowed, otherwise - null.
@@ -1499,7 +1515,7 @@ err:
*/
ltime->time_type= MYSQL_TIMESTAMP_TIME;
}
- return null_value|= !(fuzzydate & TIME_FUZZY_DATES);
+ return !(fuzzydate & TIME_FUZZY_DATES);
}
bool Item::get_seconds(ulonglong *sec, ulong *sec_part)
@@ -1743,6 +1759,16 @@ my_decimal *Item_sp_variable::val_decimal(my_decimal *decimal_value)
}
+bool Item_sp_variable::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ DBUG_ASSERT(fixed);
+ Item *it= this_item();
+ bool val= it->get_date(ltime, fuzzydate);
+ null_value= it->null_value;
+ return val;
+}
+
+
bool Item_sp_variable::is_null()
{
return this_item()->is_null();
@@ -1779,7 +1805,7 @@ Item_splocal::Item_splocal(THD *thd, const LEX_CSTRING *sp_var_name,
bool Item_splocal::fix_fields(THD *thd, Item **ref)
{
- Item *item= thd->spcont->get_item(m_var_idx);
+ Item_field *item= thd->spcont->get_variable(m_var_idx);
set_handler(item->type_handler());
return fix_fields_from_item(thd, ref, item);
}
@@ -1790,7 +1816,7 @@ Item_splocal::this_item()
{
DBUG_ASSERT(m_sp == m_thd->spcont->m_sp);
DBUG_ASSERT(fixed);
- return m_thd->spcont->get_item(m_var_idx);
+ return m_thd->spcont->get_variable(m_var_idx);
}
const Item *
@@ -1798,7 +1824,7 @@ Item_splocal::this_item() const
{
DBUG_ASSERT(m_sp == m_thd->spcont->m_sp);
DBUG_ASSERT(fixed);
- return m_thd->spcont->get_item(m_var_idx);
+ return m_thd->spcont->get_variable(m_var_idx);
}
@@ -1807,7 +1833,7 @@ Item_splocal::this_item_addr(THD *thd, Item **)
{
DBUG_ASSERT(m_sp == thd->spcont->m_sp);
DBUG_ASSERT(fixed);
- return thd->spcont->get_item_addr(m_var_idx);
+ return thd->spcont->get_variable_addr(m_var_idx);
}
@@ -1904,7 +1930,7 @@ bool Item_splocal::check_cols(uint n)
bool Item_splocal_row_field::fix_fields(THD *thd, Item **ref)
{
- Item *item= thd->spcont->get_item(m_var_idx)->element_index(m_field_idx);
+ Item *item= thd->spcont->get_variable(m_var_idx)->element_index(m_field_idx);
return fix_fields_from_item(thd, ref, item);
}
@@ -1914,7 +1940,7 @@ Item_splocal_row_field::this_item()
{
DBUG_ASSERT(m_sp == m_thd->spcont->m_sp);
DBUG_ASSERT(fixed);
- return m_thd->spcont->get_item(m_var_idx)->element_index(m_field_idx);
+ return m_thd->spcont->get_variable(m_var_idx)->element_index(m_field_idx);
}
@@ -1923,7 +1949,7 @@ Item_splocal_row_field::this_item() const
{
DBUG_ASSERT(m_sp == m_thd->spcont->m_sp);
DBUG_ASSERT(fixed);
- return m_thd->spcont->get_item(m_var_idx)->element_index(m_field_idx);
+ return m_thd->spcont->get_variable(m_var_idx)->element_index(m_field_idx);
}
@@ -1932,7 +1958,7 @@ Item_splocal_row_field::this_item_addr(THD *thd, Item **)
{
DBUG_ASSERT(m_sp == thd->spcont->m_sp);
DBUG_ASSERT(fixed);
- return thd->spcont->get_item(m_var_idx)->addr(m_field_idx);
+ return thd->spcont->get_variable(m_var_idx)->addr(m_field_idx);
}
@@ -1959,14 +1985,11 @@ bool Item_splocal_row_field::set_value(THD *thd, sp_rcontext *ctx, Item **it)
bool Item_splocal_row_field_by_name::fix_fields(THD *thd, Item **it)
{
m_thd= thd;
- Item *item, *row= m_thd->spcont->get_item(m_var_idx);
- if (row->element_index_by_name(&m_field_idx, m_field_name))
- {
- my_error(ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD, MYF(0),
- m_name.str, m_field_name.str);
+ if (thd->spcont->find_row_field_by_name_or_error(&m_field_idx,
+ m_var_idx,
+ m_field_name))
return true;
- }
- item= row->element_index(m_field_idx);
+ Item *item= thd->spcont->get_variable(m_var_idx)->element_index(m_field_idx);
set_handler(item->type_handler());
return fix_fields_from_item(thd, it, item);
}
@@ -2091,6 +2114,13 @@ my_decimal *Item_name_const::val_decimal(my_decimal *decimal_value)
return val;
}
+bool Item_name_const::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ DBUG_ASSERT(fixed);
+ bool rc= value_item->get_date(ltime, fuzzydate);
+ null_value= value_item->null_value;
+ return rc;
+}
bool Item_name_const::is_null()
{
@@ -2171,8 +2201,10 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref)
String s(buf, sizeof(buf), &my_charset_bin);
s.length(0);
- if (value_item->fix_fields(thd, &value_item) ||
- name_item->fix_fields(thd, &name_item) ||
+ if ((!value_item->fixed &&
+ value_item->fix_fields(thd, &value_item)) ||
+ (!name_item->fixed &&
+ name_item->fix_fields(thd, &name_item)) ||
!value_item->const_item() ||
!name_item->const_item() ||
!(item_name= name_item->val_str(&s))) // Can't have a NULL name
@@ -2700,15 +2732,15 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll,
0 if an error occured
*/
-Item* Item_func_or_sum::build_clone(THD *thd, MEM_ROOT *mem_root)
+Item* Item_func_or_sum::build_clone(THD *thd)
{
- Item_func_or_sum *copy= (Item_func_or_sum *) get_copy(thd, mem_root);
+ Item_func_or_sum *copy= (Item_func_or_sum *) get_copy(thd);
if (!copy)
return 0;
if (arg_count > 2)
{
copy->args=
- (Item**) alloc_root(mem_root, sizeof(Item*) * arg_count);
+ (Item**) alloc_root(thd->mem_root, sizeof(Item*) * arg_count);
if (!copy->args)
return 0;
}
@@ -2718,7 +2750,7 @@ Item* Item_func_or_sum::build_clone(THD *thd, MEM_ROOT *mem_root)
for (uint i= 0; i < arg_count; i++)
{
- Item *arg_clone= args[i]->build_clone(thd, mem_root);
+ Item *arg_clone= args[i]->build_clone(thd);
if (!arg_clone)
return 0;
copy->args[i]= arg_clone;
@@ -2726,6 +2758,252 @@ Item* Item_func_or_sum::build_clone(THD *thd, MEM_ROOT *mem_root)
return copy;
}
+Item_sp::Item_sp(THD *thd, Name_resolution_context *context_arg,
+ sp_name *name_arg) :
+ context(context_arg), m_name(name_arg), m_sp(NULL), func_ctx(NULL),
+ sp_result_field(NULL)
+{
+ dummy_table= (TABLE*) thd->calloc(sizeof(TABLE) + sizeof(TABLE_SHARE) +
+ sizeof(Query_arena));
+ dummy_table->s= (TABLE_SHARE*) (dummy_table + 1);
+ /* TODO(cvicentiu) Move this sp_query_arena in the class as a direct member.
+ Currently it can not be done due to header include dependencies. */
+ sp_query_arena= (Query_arena *) (dummy_table->s + 1);
+ memset(&sp_mem_root, 0, sizeof(sp_mem_root));
+}
+
+const char *
+Item_sp::func_name(THD *thd) const
+{
+ /* Calculate length to avoid reallocation of string for sure */
+ size_t len= (((m_name->m_explicit_name ? m_name->m_db.length : 0) +
+ m_name->m_name.length)*2 + //characters*quoting
+ 2 + // ` and `
+ (m_name->m_explicit_name ?
+ 3 : 0) + // '`', '`' and '.' for the db
+ 1 + // end of string
+ ALIGN_SIZE(1)); // to avoid String reallocation
+ String qname((char *)alloc_root(thd->mem_root, len), len,
+ system_charset_info);
+
+ qname.length(0);
+ if (m_name->m_explicit_name)
+ {
+ append_identifier(thd, &qname, &m_name->m_db);
+ qname.append('.');
+ }
+ append_identifier(thd, &qname, &m_name->m_name);
+ return qname.c_ptr_safe();
+}
+
+void
+Item_sp::cleanup()
+{
+ delete sp_result_field;
+ sp_result_field= NULL;
+ m_sp= NULL;
+ delete func_ctx;
+ func_ctx= NULL;
+ free_root(&sp_mem_root, MYF(0));
+ dummy_table->alias.free();
+}
+
+/**
+ @brief Checks if requested access to function can be granted to user.
+ If function isn't found yet, it searches function first.
+ If function can't be found or user don't have requested access
+ error is raised.
+
+ @param thd thread handler
+
+ @return Indication if the access was granted or not.
+ @retval FALSE Access is granted.
+ @retval TRUE Requested access can't be granted or function doesn't exists.
+
+*/
+bool
+Item_sp::sp_check_access(THD *thd)
+{
+ DBUG_ENTER("Item_sp::sp_check_access");
+ DBUG_ASSERT(m_sp);
+ DBUG_RETURN(m_sp->check_execute_access(thd));
+}
+
+/**
+ @brief Execute function & store value in field.
+
+ @return Function returns error status.
+ @retval FALSE on success.
+ @retval TRUE if an error occurred.
+*/
+bool Item_sp::execute(THD *thd, bool *null_value, Item **args, uint arg_count)
+{
+ if (execute_impl(thd, args, arg_count))
+ {
+ *null_value= 1;
+ context->process_error(thd);
+ if (thd->killed)
+ thd->send_kill_message();
+ return true;
+ }
+
+ /* Check that the field (the value) is not NULL. */
+
+ *null_value= sp_result_field->is_null();
+ return (*null_value);
+}
+
+/**
+ @brief Execute function and store the return value in the field.
+
+ @note This function was intended to be the concrete implementation of
+ the interface function execute. This was never realized.
+
+ @return The error state.
+ @retval FALSE on success
+ @retval TRUE if an error occurred.
+*/
+bool
+Item_sp::execute_impl(THD *thd, Item **args, uint arg_count)
+{
+ Sub_statement_state statement_state;
+ Security_context *save_security_ctx= thd->security_ctx;
+ enum enum_sp_data_access access=
+ (m_sp->daccess() == SP_DEFAULT_ACCESS) ?
+ SP_DEFAULT_ACCESS_MAPPING : m_sp->daccess();
+
+ DBUG_ENTER("Item_sp::execute_impl");
+
+ if (context->security_ctx)
+ {
+ /* Set view definer security context */
+ thd->security_ctx= context->security_ctx;
+ }
+
+ if (sp_check_access(thd))
+ {
+ thd->security_ctx= save_security_ctx;
+ DBUG_RETURN(TRUE);
+ }
+
+ /*
+ Throw an error if a non-deterministic function is called while
+ statement-based replication (SBR) is active.
+ */
+
+ if (!m_sp->detistic() && !trust_function_creators &&
+ (access == SP_CONTAINS_SQL || access == SP_MODIFIES_SQL_DATA) &&
+ (mysql_bin_log.is_open() &&
+ thd->variables.binlog_format == BINLOG_FORMAT_STMT))
+ {
+ my_error(ER_BINLOG_UNSAFE_ROUTINE, MYF(0));
+ thd->security_ctx= save_security_ctx;
+ DBUG_RETURN(TRUE);
+ }
+
+ /*
+ Disable the binlogging if this is not a SELECT statement. If this is a
+ SELECT, leave binlogging on, so execute_function() code writes the
+ function call into binlog.
+ */
+ thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION);
+
+ /*
+ If this function is an aggregate function, we want to initialise the
+ mem_root only once per group. For a regular stored function, we will
+ initialise once for each call to execute_function.
+ */
+ m_sp->agg_type();
+ DBUG_ASSERT(m_sp->agg_type() == GROUP_AGGREGATE ||
+ (m_sp->agg_type() == NOT_AGGREGATE && !func_ctx));
+ if (!func_ctx)
+ {
+ init_sql_alloc(&sp_mem_root, "Item_sp", MEM_ROOT_BLOCK_SIZE, 0, MYF(0));
+ *sp_query_arena= Query_arena(&sp_mem_root,
+ Query_arena::STMT_INITIALIZED_FOR_SP);
+ }
+
+ bool err_status= m_sp->execute_function(thd, args, arg_count,
+ sp_result_field, &func_ctx,
+ sp_query_arena);
+ /*
+ We free the function context when the function finished executing normally
+ (quit_func == TRUE) or the function has exited with an error.
+ */
+ if (err_status || func_ctx->quit_func)
+ {
+ /* Free Items allocated during function execution. */
+ delete func_ctx;
+ func_ctx= NULL;
+ sp_query_arena->free_items();
+ free_root(&sp_mem_root, MYF(0));
+ memset(&sp_mem_root, 0, sizeof(sp_mem_root));
+ }
+ thd->restore_sub_statement_state(&statement_state);
+
+ thd->security_ctx= save_security_ctx;
+ DBUG_RETURN(err_status);
+}
+
+
+/**
+ @brief Initialize the result field by creating a temporary dummy table
+ and assign it to a newly created field object. Meta data used to
+ create the field is fetched from the sp_head belonging to the stored
+ proceedure found in the stored procedure functon cache.
+
+ @note This function should be called from fix_fields to init the result
+ field. It is some what related to Item_field.
+
+ @see Item_field
+
+ @param thd A pointer to the session and thread context.
+
+ @return Function return error status.
+ @retval TRUE is returned on an error
+ @retval FALSE is returned on success.
+*/
+
+bool
+Item_sp::init_result_field(THD *thd, uint max_length, uint maybe_null,
+ bool *null_value, LEX_CSTRING *name)
+{
+ DBUG_ENTER("Item_sp::init_result_field");
+
+ DBUG_ASSERT(m_sp != NULL);
+ DBUG_ASSERT(sp_result_field == NULL);
+
+ /*
+ A Field needs to be attached to a Table.
+ Below we "create" a dummy table by initializing
+ the needed pointers.
+ */
+ dummy_table->alias.set("", 0, table_alias_charset);
+ dummy_table->in_use= thd;
+ dummy_table->copy_blobs= TRUE;
+ dummy_table->s->table_cache_key= empty_clex_str;
+ dummy_table->s->table_name= empty_clex_str;
+ dummy_table->maybe_null= maybe_null;
+
+ if (!(sp_result_field= m_sp->create_result_field(max_length, name,
+ dummy_table)))
+ DBUG_RETURN(TRUE);
+
+ if (sp_result_field->pack_length() > sizeof(result_buf))
+ {
+ void *tmp;
+ if (!(tmp= thd->alloc(sp_result_field->pack_length())))
+ DBUG_RETURN(TRUE);
+ sp_result_field->move_field((uchar*) tmp);
+ }
+ else
+ sp_result_field->move_field(result_buf);
+
+ sp_result_field->null_ptr= (uchar *) null_value;
+ sp_result_field->null_bit= 1;
+
+ DBUG_RETURN(FALSE);
+}
/**
@brief
@@ -2743,19 +3021,13 @@ Item* Item_func_or_sum::build_clone(THD *thd, MEM_ROOT *mem_root)
0 if an error occured
*/
-Item* Item_ref::build_clone(THD *thd, MEM_ROOT *mem_root)
+Item* Item_ref::build_clone(THD *thd)
{
- Item_ref *copy= (Item_ref *) get_copy(thd, mem_root);
- if (!copy)
- return 0;
- copy->ref=
- (Item**) alloc_root(mem_root, sizeof(Item*));
- if (!copy->ref)
- return 0;
- Item *item_clone= (* ref)->build_clone(thd, mem_root);
- if (!item_clone)
+ Item_ref *copy= (Item_ref *) get_copy(thd);
+ if (!copy ||
+ !(copy->ref= (Item**) alloc_root(thd->mem_root, sizeof(Item*))) ||
+ !(*copy->ref= (* ref)->build_clone(thd)))
return 0;
- *copy->ref= item_clone;
return copy;
}
@@ -3026,7 +3298,7 @@ void Item_ident::print(String *str, enum_query_type query_type)
bool use_db_name= use_table_name && db_name && db_name[0] && !alias_name_used;
if (use_db_name && (query_type & QT_ITEM_IDENT_SKIP_DB_NAMES))
- use_db_name= !thd->db || strcmp(thd->db, db_name);
+ use_db_name= !thd->db.str || strcmp(thd->db.str, db_name);
if (use_db_name)
use_db_name= !(cached_table && cached_table->belong_to_view &&
@@ -3083,7 +3355,7 @@ void Item_ident::print(String *str, enum_query_type query_type)
append_identifier(thd, str, t_name, (uint) strlen(t_name));
str->append('.');
}
- append_identifier(thd, str, field_name.str, field_name.length);
+ append_identifier(thd, str, &field_name);
}
/* ARGSUSED */
@@ -3356,7 +3628,7 @@ longlong Item_field::val_int_endpoint(bool left_endp, bool *incl_endp)
This is always 'signed'. Unsigned values are created with Item_uint()
*/
-Item_int::Item_int(THD *thd, const char *str_arg, uint length):
+Item_int::Item_int(THD *thd, const char *str_arg, size_t length):
Item_num(thd)
{
char *end_ptr= (char*) str_arg + length;
@@ -3403,7 +3675,7 @@ Item *Item_bool::neg_transformer(THD *thd)
}
-Item_uint::Item_uint(THD *thd, const char *str_arg, uint length):
+Item_uint::Item_uint(THD *thd, const char *str_arg, size_t length):
Item_int(thd, str_arg, length)
{
unsigned_flag= 1;
@@ -3434,7 +3706,7 @@ void Item_uint::print(String *str, enum_query_type query_type)
}
-Item_decimal::Item_decimal(THD *thd, const char *str_arg, uint length,
+Item_decimal::Item_decimal(THD *thd, const char *str_arg, size_t length,
CHARSET_INFO *charset):
Item_num(thd)
{
@@ -3702,6 +3974,15 @@ my_decimal *Item_null::val_decimal(my_decimal *decimal_value)
}
+bool Item_null::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ // following assert is redundant, because fixed=1 assigned in constructor
+ DBUG_ASSERT(fixed == 1);
+ make_zero_date(ltime, fuzzydate);
+ return (null_value= true);
+}
+
+
Item *Item_null::safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
{
return this;
@@ -3714,20 +3995,6 @@ Item *Item_null::clone_item(THD *thd)
/*********************** Item_param related ******************************/
-/**
- Default function of Item_param::set_param_func, so in case
- of malformed packet the server won't SIGSEGV.
-*/
-
-static void
-default_set_param_func(Item_param *param,
- uchar **pos __attribute__((unused)),
- ulong len __attribute__((unused)))
-{
- param->set_null();
-}
-
-
Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg,
uint pos_in_query_arg, uint len_in_query_arg):
Item_basic_value(thd),
@@ -3745,8 +4012,8 @@ Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg,
state(NO_VALUE),
/* Don't pretend to be a literal unless value for this item is set. */
item_type(PARAM_ITEM),
+ m_empty_string_is_null(false),
indicator(STMT_INDICATOR_NONE),
- set_param_func(default_set_param_func),
m_out_param_info(NULL),
/*
Set m_is_settable_routine_parameter to "true" by default.
@@ -3770,7 +4037,10 @@ Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg,
void Item_param::set_null()
{
DBUG_ENTER("Item_param::set_null");
- /* These are cleared after each execution by reset() method */
+ /*
+ These are cleared after each execution by reset() method or by setting
+ other value.
+ */
null_value= 1;
/*
Because of NULL and string values we need to set max_length for each new
@@ -3787,11 +4057,14 @@ void Item_param::set_null()
void Item_param::set_int(longlong i, uint32 max_length_arg)
{
DBUG_ENTER("Item_param::set_int");
+ DBUG_ASSERT(value.type_handler()->cmp_type() == INT_RESULT);
value.integer= (longlong) i;
- state= INT_VALUE;
+ state= SHORT_DATA_VALUE;
+ collation.set_numeric();
max_length= max_length_arg;
decimals= 0;
maybe_null= 0;
+ null_value= 0;
fix_type(Item::INT_ITEM);
DBUG_VOID_RETURN;
}
@@ -3799,11 +4072,14 @@ void Item_param::set_int(longlong i, uint32 max_length_arg)
void Item_param::set_double(double d)
{
DBUG_ENTER("Item_param::set_double");
+ DBUG_ASSERT(value.type_handler()->cmp_type() == REAL_RESULT);
value.real= d;
- state= REAL_VALUE;
+ state= SHORT_DATA_VALUE;
+ collation.set_numeric();
max_length= DBL_DIG + 8;
decimals= NOT_FIXED_DEC;
maybe_null= 0;
+ null_value= 0;
fix_type(Item::REAL_ITEM);
DBUG_VOID_RETURN;
}
@@ -3825,38 +4101,48 @@ void Item_param::set_decimal(const char *str, ulong length)
{
char *end;
DBUG_ENTER("Item_param::set_decimal");
+ DBUG_ASSERT(value.type_handler()->cmp_type() == DECIMAL_RESULT);
end= (char*) str+length;
- str2my_decimal(E_DEC_FATAL_ERROR, str, &decimal_value, &end);
- state= DECIMAL_VALUE;
- decimals= decimal_value.frac;
+ str2my_decimal(E_DEC_FATAL_ERROR, str, &value.m_decimal, &end);
+ state= SHORT_DATA_VALUE;
+ decimals= value.m_decimal.frac;
+ collation.set_numeric();
max_length=
- my_decimal_precision_to_length_no_truncation(decimal_value.precision(),
+ my_decimal_precision_to_length_no_truncation(value.m_decimal.precision(),
decimals, unsigned_flag);
maybe_null= 0;
+ null_value= 0;
fix_type(Item::DECIMAL_ITEM);
DBUG_VOID_RETURN;
}
void Item_param::set_decimal(const my_decimal *dv, bool unsigned_arg)
{
- state= DECIMAL_VALUE;
+ DBUG_ASSERT(value.type_handler()->cmp_type() == DECIMAL_RESULT);
+ state= SHORT_DATA_VALUE;
- my_decimal2decimal(dv, &decimal_value);
+ my_decimal2decimal(dv, &value.m_decimal);
- decimals= (uint8) decimal_value.frac;
+ decimals= (uint8) value.m_decimal.frac;
+ collation.set_numeric();
unsigned_flag= unsigned_arg;
- max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
+ max_length= my_decimal_precision_to_length(value.m_decimal.intg + decimals,
decimals, unsigned_flag);
+ maybe_null= 0;
+ null_value= 0;
fix_type(Item::DECIMAL_ITEM);
}
void Item_param::fix_temporal(uint32 max_length_arg, uint decimals_arg)
{
- state= TIME_VALUE;
+ state= SHORT_DATA_VALUE;
+ collation.set_numeric();
max_length= max_length_arg;
decimals= decimals_arg;
+ maybe_null= 0;
+ null_value= 0;
fix_type(Item::DATE_ITEM);
}
@@ -3864,7 +4150,10 @@ void Item_param::fix_temporal(uint32 max_length_arg, uint decimals_arg)
void Item_param::set_time(const MYSQL_TIME *tm,
uint32 max_length_arg, uint decimals_arg)
{
+ DBUG_ASSERT(value.type_handler()->cmp_type() == TIME_RESULT);
value.time= *tm;
+ maybe_null= 0;
+ null_value= 0;
fix_temporal(max_length_arg, decimals_arg);
}
@@ -3886,6 +4175,7 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type,
uint32 max_length_arg)
{
DBUG_ENTER("Item_param::set_time");
+ DBUG_ASSERT(value.type_handler()->cmp_type() == TIME_RESULT);
value.time= *tm;
value.time.time_type= time_type;
@@ -3895,29 +4185,47 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type,
ErrConvTime str(&value.time);
make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
&str, time_type, 0);
- set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR);
+ set_zero_time(&value.time, time_type);
}
maybe_null= 0;
+ null_value= 0;
fix_temporal(max_length_arg,
tm->second_part > 0 ? TIME_SECOND_PART_DIGITS : 0);
DBUG_VOID_RETURN;
}
-bool Item_param::set_str(const char *str, ulong length)
+bool Item_param::set_str(const char *str, ulong length,
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{
DBUG_ENTER("Item_param::set_str");
+ DBUG_ASSERT(value.type_handler()->cmp_type() == STRING_RESULT);
/*
Assign string with no conversion: data is converted only after it's
been written to the binary log.
*/
uint dummy_errors;
- if (str_value.copy(str, length, &my_charset_bin, &my_charset_bin,
- &dummy_errors))
+ if (value.m_string.copy(str, length, fromcs, tocs, &dummy_errors))
DBUG_RETURN(TRUE);
- state= STRING_VALUE;
+ /*
+ Set str_value_ptr to make sure it's in sync with str_value.
+ This is needed in case if we're called from Item_param::set_value(),
+ from the code responsible for setting OUT parameters in
+ sp_head::execute_procedure(). This makes sure that
+ Protocol_binary::send_out_parameters() later gets a valid value
+ from Item_param::val_str().
+ Note, for IN parameters, Item_param::convert_str_value() will be called
+ later, which will convert the value from the client character set to the
+ connection character set, and will reset both str_value and str_value_ptr.
+ */
+ value.m_string_ptr.set(value.m_string.ptr(),
+ value.m_string.length(),
+ value.m_string.charset());
+ state= SHORT_DATA_VALUE;
+ collation.set(tocs, DERIVATION_COERCIBLE);
max_length= length;
maybe_null= 0;
+ null_value= 0;
/* max_length and decimals are set after charset conversion */
/* sic: str may be not null-terminated, don't add DBUG_PRINT here */
fix_type(Item::STRING_ITEM);
@@ -3928,6 +4236,7 @@ bool Item_param::set_str(const char *str, ulong length)
bool Item_param::set_longdata(const char *str, ulong length)
{
DBUG_ENTER("Item_param::set_longdata");
+ DBUG_ASSERT(value.type_handler()->cmp_type() == STRING_RESULT);
/*
If client character set is multibyte, end of long data packet
@@ -3938,7 +4247,7 @@ bool Item_param::set_longdata(const char *str, ulong length)
(here), and first have to concatenate all pieces together,
write query to the binary log and only then perform conversion.
*/
- if (str_value.length() + length > max_long_data_size)
+ if (value.m_string.length() + length > max_long_data_size)
{
my_message(ER_UNKNOWN_ERROR,
"Parameter of prepared statement which is set through "
@@ -3948,10 +4257,11 @@ bool Item_param::set_longdata(const char *str, ulong length)
DBUG_RETURN(true);
}
- if (str_value.append(str, length, &my_charset_bin))
+ if (value.m_string.append(str, length, &my_charset_bin))
DBUG_RETURN(TRUE);
state= LONG_DATA_VALUE;
maybe_null= 0;
+ null_value= 0;
fix_type(Item::STRING_ITEM);
DBUG_RETURN(FALSE);
@@ -4011,16 +4321,16 @@ bool Item_param::set_from_item(THD *thd, Item *item)
else
{
unsigned_flag= item->unsigned_flag;
- set_int(val, MY_INT64_NUM_DECIMAL_DIGITS);
- set_handler_by_result_type(item->result_type());
- DBUG_RETURN(!unsigned_flag && value.integer < 0 ? 1 : 0);
+ set_handler(item->type_handler());
+ DBUG_RETURN(set_limit_clause_param(val));
}
}
struct st_value tmp;
if (!item->save_in_value(&tmp))
{
- if (item->type_handler()->Item_param_set_from_value(thd, this, item, &tmp))
- DBUG_RETURN(true);
+ const Type_handler *h= item->type_handler();
+ set_handler(h);
+ DBUG_RETURN(set_value(thd, item, &tmp, h));
}
else
set_null();
@@ -4040,16 +4350,16 @@ void Item_param::reset()
{
DBUG_ENTER("Item_param::reset");
/* Shrink string buffer if it's bigger than max possible CHAR column */
- if (str_value.alloced_length() > MAX_CHAR_WIDTH)
- str_value.free();
+ if (value.m_string.alloced_length() > MAX_CHAR_WIDTH)
+ value.m_string.free();
else
- str_value.length(0);
- str_value_ptr.length(0);
+ value.m_string.length(0);
+ value.m_string_ptr.length(0);
/*
We must prevent all charset conversions until data has been written
to the binary log.
*/
- str_value.set_charset(&my_charset_bin);
+ value.m_string.set_charset(&my_charset_bin);
collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
state= NO_VALUE;
maybe_null= 1;
@@ -4078,19 +4388,9 @@ int Item_param::save_in_field(Field *field, bool no_conversions)
Garbage (e.g. in case of a memory overrun) is handled after the switch.
*/
switch (state) {
- case INT_VALUE:
- return field->store(value.integer, unsigned_flag);
- case REAL_VALUE:
- return field->store(value.real);
- case DECIMAL_VALUE:
- return field->store_decimal(&decimal_value);
- case TIME_VALUE:
- field->store_time_dec(&value.time, decimals);
- return 0;
- case STRING_VALUE:
+ case SHORT_DATA_VALUE:
case LONG_DATA_VALUE:
- return field->store(str_value.ptr(), str_value.length(),
- str_value.charset());
+ return value.type_handler()->Item_save_in_field(this, field, no_conversions);
case NULL_VALUE:
return set_field_to_null_with_conversions(field, no_conversions);
case DEFAULT_VALUE:
@@ -4110,6 +4410,28 @@ int Item_param::save_in_field(Field *field, bool no_conversions)
}
+bool Item_param::can_return_value() const
+{
+ // There's no "default". See comments in Item_param::save_in_field().
+ switch (state) {
+ case SHORT_DATA_VALUE:
+ case LONG_DATA_VALUE:
+ return true;
+ case IGNORE_VALUE:
+ case DEFAULT_VALUE:
+ invalid_default_param();
+ // fall through
+ case NULL_VALUE:
+ return false;
+ case NO_VALUE:
+ DBUG_ASSERT(0); // Should not be possible
+ return false;
+ }
+ DBUG_ASSERT(0); // Garbage
+ return false;
+}
+
+
void Item_param::invalid_default_param() const
{
my_message(ER_INVALID_DEFAULT_PARAM,
@@ -4119,166 +4441,133 @@ void Item_param::invalid_default_param() const
bool Item_param::get_date(MYSQL_TIME *res, ulonglong fuzzydate)
{
- if (state == TIME_VALUE)
+ /*
+ LIMIT clause parameter should not call get_date()
+ For non-LIMIT parameters, handlers must be the same.
+ */
+ DBUG_ASSERT(type_handler()->result_type() ==
+ value.type_handler()->result_type());
+ if (state == SHORT_DATA_VALUE &&
+ value.type_handler()->cmp_type() == TIME_RESULT)
{
*res= value.time;
return 0;
}
- return Item::get_date(res, fuzzydate);
+ return type_handler()->Item_get_date(this, res, fuzzydate);
}
-double Item_param::val_real()
+double Item_param::PValue::val_real() const
{
- // There's no "default". See comments in Item_param::save_in_field().
- switch (state) {
- case REAL_VALUE:
- return value.real;
- case INT_VALUE:
- return (double) value.integer;
- case DECIMAL_VALUE:
+ switch (type_handler()->cmp_type()) {
+ case REAL_RESULT:
+ return real;
+ case INT_RESULT:
+ return (double) integer;
+ case DECIMAL_RESULT:
{
double result;
- my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &result);
+ my_decimal2double(E_DEC_FATAL_ERROR, &m_decimal, &result);
return result;
}
- case STRING_VALUE:
- case LONG_DATA_VALUE:
- {
- return double_from_string_with_check(&str_value);
- }
- case TIME_VALUE:
+ case STRING_RESULT:
+ return double_from_string_with_check(&m_string);
+ case TIME_RESULT:
/*
This works for example when user says SELECT ?+0.0 and supplies
time value for the placeholder.
*/
- return TIME_to_double(&value.time);
- case IGNORE_VALUE:
- case DEFAULT_VALUE:
- invalid_default_param();
- // fall through
- case NULL_VALUE:
- return 0.0;
- case NO_VALUE:
- DBUG_ASSERT(0); // Should not be possible
- return 0.0;
+ return TIME_to_double(&time);
+ case ROW_RESULT:
+ DBUG_ASSERT(0);
+ break;
}
- DBUG_ASSERT(0); // Garbage
return 0.0;
-}
+}
-longlong Item_param::val_int()
-{
- // There's no "default". See comments in Item_param::save_in_field().
- switch (state) {
- case REAL_VALUE:
- return (longlong) rint(value.real);
- case INT_VALUE:
- return value.integer;
- case DECIMAL_VALUE:
+longlong Item_param::PValue::val_int(const Type_std_attributes *attr) const
+{
+ switch (type_handler()->cmp_type()) {
+ case REAL_RESULT:
+ return (longlong) rint(real);
+ case INT_RESULT:
+ return integer;
+ case DECIMAL_RESULT:
{
longlong i;
- my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &i);
+ my_decimal2int(E_DEC_FATAL_ERROR, &m_decimal, attr->unsigned_flag, &i);
return i;
}
- case STRING_VALUE:
- case LONG_DATA_VALUE:
- {
- return longlong_from_string_with_check(&str_value);
- }
- case TIME_VALUE:
- return (longlong) TIME_to_ulonglong(&value.time);
- case IGNORE_VALUE:
- case DEFAULT_VALUE:
- invalid_default_param();
- // fall through
- case NULL_VALUE:
- return 0;
- case NO_VALUE:
- DBUG_ASSERT(0); // Should not be possible
- return 0;
+ case STRING_RESULT:
+ return longlong_from_string_with_check(&m_string);
+ case TIME_RESULT:
+ return (longlong) TIME_to_ulonglong(&time);
+ case ROW_RESULT:
+ DBUG_ASSERT(0);
+ break;
}
- DBUG_ASSERT(0); // Garbage
return 0;
}
-my_decimal *Item_param::val_decimal(my_decimal *dec)
+my_decimal *Item_param::PValue::val_decimal(my_decimal *dec,
+ const Type_std_attributes *attr)
{
- // There's no "default". See comments in Item_param::save_in_field().
- switch (state) {
- case DECIMAL_VALUE:
- return &decimal_value;
- case REAL_VALUE:
- double2my_decimal(E_DEC_FATAL_ERROR, value.real, dec);
+ switch (type_handler()->cmp_type()) {
+ case DECIMAL_RESULT:
+ return &m_decimal;
+ case REAL_RESULT:
+ double2my_decimal(E_DEC_FATAL_ERROR, real, dec);
return dec;
- case INT_VALUE:
- int2my_decimal(E_DEC_FATAL_ERROR, value.integer, unsigned_flag, dec);
+ case INT_RESULT:
+ int2my_decimal(E_DEC_FATAL_ERROR, integer, attr->unsigned_flag, dec);
return dec;
- case STRING_VALUE:
- case LONG_DATA_VALUE:
- return decimal_from_string_with_check(dec, &str_value);
- case TIME_VALUE:
- {
- return TIME_to_my_decimal(&value.time, dec);
- }
- case IGNORE_VALUE:
- case DEFAULT_VALUE:
- invalid_default_param();
- // fall through
- case NULL_VALUE:
- return 0;
- case NO_VALUE:
- DBUG_ASSERT(0); // Should not be possible
- return 0;
+ case STRING_RESULT:
+ return decimal_from_string_with_check(dec, &m_string);
+ case TIME_RESULT:
+ return TIME_to_my_decimal(&time, dec);
+ case ROW_RESULT:
+ DBUG_ASSERT(0);
+ break;
}
- DBUG_ASSERT(0); // Gabrage
return 0;
}
-String *Item_param::val_str(String* str)
-{
- // There's no "default". See comments in Item_param::save_in_field().
- switch (state) {
- case STRING_VALUE:
- case LONG_DATA_VALUE:
- return &str_value_ptr;
- case REAL_VALUE:
- str->set_real(value.real, NOT_FIXED_DEC, &my_charset_bin);
+String *Item_param::PValue::val_str(String *str,
+ const Type_std_attributes *attr)
+{
+ switch (type_handler()->cmp_type()) {
+ case STRING_RESULT:
+ return &m_string_ptr;
+ case REAL_RESULT:
+ str->set_real(real, NOT_FIXED_DEC, &my_charset_bin);
return str;
- case INT_VALUE:
- str->set(value.integer, &my_charset_bin);
+ case INT_RESULT:
+ str->set(integer, &my_charset_bin);
return str;
- case DECIMAL_VALUE:
- if (my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value,
- 0, 0, 0, str) <= 1)
+ case DECIMAL_RESULT:
+ if (my_decimal2string(E_DEC_FATAL_ERROR, &m_decimal, 0, 0, 0, str) <= 1)
return str;
return NULL;
- case TIME_VALUE:
+ case TIME_RESULT:
{
if (str->reserve(MAX_DATE_STRING_REP_LENGTH))
- break;
- str->length((uint) my_TIME_to_str(&value.time, (char*) str->ptr(),
- decimals));
+ return NULL;
+ str->length((uint) my_TIME_to_str(&time, (char*) str->ptr(),
+ attr->decimals));
str->set_charset(&my_charset_bin);
return str;
}
- case IGNORE_VALUE:
- case DEFAULT_VALUE:
- invalid_default_param();
- // fall through
- case NULL_VALUE:
- return NULL;
- case NO_VALUE:
- DBUG_ASSERT(0); // Should not be possible
- return NULL;
+ case ROW_RESULT:
+ DBUG_ASSERT(0);
+ break;
}
- DBUG_ASSERT(0); // Garbage
return NULL;
}
+
/**
Return Param item values in string format, for generating the dynamic
query used in update/binary logs.
@@ -4290,43 +4579,42 @@ String *Item_param::val_str(String* str)
that binary log contains wrong statement
*/
-const String *Item_param::query_val_str(THD *thd, String* str) const
+const String *Item_param::value_query_val_str(THD *thd, String *str) const
{
- // There's no "default". See comments in Item_param::save_in_field().
- switch (state) {
- case INT_VALUE:
+ switch (value.type_handler()->cmp_type()) {
+ case INT_RESULT:
str->set_int(value.integer, unsigned_flag, &my_charset_bin);
return str;
- case REAL_VALUE:
+ case REAL_RESULT:
str->set_real(value.real, NOT_FIXED_DEC, &my_charset_bin);
return str;
- case DECIMAL_VALUE:
- if (my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value,
+ case DECIMAL_RESULT:
+ if (my_decimal2string(E_DEC_FATAL_ERROR, &value.m_decimal,
0, 0, 0, str) > 1)
return &my_null_string;
return str;
- case TIME_VALUE:
+ case TIME_RESULT:
{
static const uint32 typelen= 9; // "TIMESTAMP" is the longest type name
char *buf, *ptr;
str->length(0);
/*
TODO: in case of error we need to notify replication
- that binary log contains wrong statement
+ that binary log contains wrong statement
*/
if (str->reserve(MAX_DATE_STRING_REP_LENGTH + 3 + typelen))
- break;
+ return NULL;
/* Create date string inplace */
switch (value.time.time_type) {
case MYSQL_TIMESTAMP_DATE:
- str->append(C_STRING_WITH_LEN("DATE"));
+ str->append(STRING_WITH_LEN("DATE"));
break;
case MYSQL_TIMESTAMP_TIME:
- str->append(C_STRING_WITH_LEN("TIME"));
+ str->append(STRING_WITH_LEN("TIME"));
break;
case MYSQL_TIMESTAMP_DATETIME:
- str->append(C_STRING_WITH_LEN("TIMESTAMP"));
+ str->append(STRING_WITH_LEN("TIMESTAMP"));
break;
case MYSQL_TIMESTAMP_ERROR:
case MYSQL_TIMESTAMP_NONE:
@@ -4341,15 +4629,29 @@ const String *Item_param::query_val_str(THD *thd, String* str) const
str->length((uint32) (ptr - buf));
return str;
}
- case STRING_VALUE:
- case LONG_DATA_VALUE:
+ case STRING_RESULT:
{
str->length(0);
append_query_string(value.cs_info.character_set_client, str,
- str_value.ptr(), str_value.length(),
+ value.m_string.ptr(), value.m_string.length(),
thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES);
return str;
}
+ case ROW_RESULT:
+ DBUG_ASSERT(0);
+ break;
+ }
+ return NULL;
+}
+
+
+const String *Item_param::query_val_str(THD *thd, String* str) const
+{
+ // There's no "default". See comments in Item_param::save_in_field().
+ switch (state) {
+ case SHORT_DATA_VALUE:
+ case LONG_DATA_VALUE:
+ return value_query_val_str(thd, str);
case IGNORE_VALUE:
case DEFAULT_VALUE:
return &my_default_string;
@@ -4372,19 +4674,20 @@ const String *Item_param::query_val_str(THD *thd, String* str) const
bool Item_param::convert_str_value(THD *thd)
{
bool rc= FALSE;
- if (state == STRING_VALUE || state == LONG_DATA_VALUE)
+ if ((state == SHORT_DATA_VALUE || state == LONG_DATA_VALUE) &&
+ value.type_handler()->cmp_type() == STRING_RESULT)
{
- rc= value.cs_info.convert_if_needed(thd, &str_value);
+ rc= value.cs_info.convert_if_needed(thd, &value.m_string);
/* Here str_value is guaranteed to be in final_character_set_of_str_value */
/*
str_value_ptr is returned from val_str(). It must be not alloced
to prevent it's modification by val_str() invoker.
*/
- str_value_ptr.set(str_value.ptr(), str_value.length(),
- str_value.charset());
+ value.m_string_ptr.set(value.m_string.ptr(), value.m_string.length(),
+ value.m_string.charset());
/* Synchronize item charset and length with value charset */
- fix_charset_and_length_from_str_value(DERIVATION_COERCIBLE);
+ fix_charset_and_length_from_str_value(value.m_string, DERIVATION_COERCIBLE);
}
return rc;
}
@@ -4393,18 +4696,48 @@ bool Item_param::convert_str_value(THD *thd)
bool Item_param::basic_const_item() const
{
DBUG_ASSERT(fixed || state == NO_VALUE);
- if (state == NO_VALUE || state == TIME_VALUE)
+ if (state == NO_VALUE ||
+ (state == SHORT_DATA_VALUE && type_handler()->cmp_type() == TIME_RESULT))
return FALSE;
return TRUE;
}
+Item *Item_param::value_clone_item(THD *thd)
+{
+ MEM_ROOT *mem_root= thd->mem_root;
+ switch (value.type_handler()->cmp_type()) {
+ case INT_RESULT:
+ return (unsigned_flag ?
+ new (mem_root) Item_uint(thd, name.str, value.integer, max_length) :
+ new (mem_root) Item_int(thd, name.str, value.integer, max_length));
+ case REAL_RESULT:
+ return new (mem_root) Item_float(thd, name.str, value.real, decimals,
+ max_length);
+ case DECIMAL_RESULT:
+ return 0; // Should create Item_decimal. See MDEV-11361.
+ case STRING_RESULT:
+ return new (mem_root) Item_string(thd, name.str,
+ value.m_string.c_ptr_quick(),
+ value.m_string.length(),
+ value.m_string.charset(),
+ collation.derivation,
+ collation.repertoire);
+ case TIME_RESULT:
+ break;
+ case ROW_RESULT:
+ DBUG_ASSERT(0);
+ break;
+ }
+ return 0;
+}
+
+
/* see comments in the header file */
Item *
Item_param::clone_item(THD *thd)
{
- MEM_ROOT *mem_root= thd->mem_root;
// There's no "default". See comments in Item_param::save_in_field().
switch (state) {
case IGNORE_VALUE:
@@ -4412,24 +4745,13 @@ Item_param::clone_item(THD *thd)
invalid_default_param();
// fall through
case NULL_VALUE:
- return new (mem_root) Item_null(thd, name.str);
- case INT_VALUE:
- return (unsigned_flag ?
- new (mem_root) Item_uint(thd, name.str, value.integer, max_length) :
- new (mem_root) Item_int(thd, name.str, value.integer, max_length));
- case REAL_VALUE:
- return new (mem_root) Item_float(thd, name.str, value.real, decimals,
- max_length);
- case DECIMAL_VALUE:
- return 0; // Should create Item_decimal. See MDEV-11361.
- case STRING_VALUE:
+ return new (thd->mem_root) Item_null(thd, name.str);
+ case SHORT_DATA_VALUE:
case LONG_DATA_VALUE:
- return new (mem_root) Item_string(thd, name.str, str_value.c_ptr_quick(),
- str_value.length(), str_value.charset(),
- collation.derivation,
- collation.repertoire);
- case TIME_VALUE:
- return 0;
+ {
+ DBUG_ASSERT(type_handler()->cmp_type() == value.type_handler()->cmp_type());
+ return value_clone_item(thd);
+ }
case NO_VALUE:
return 0;
}
@@ -4438,6 +4760,24 @@ Item_param::clone_item(THD *thd)
}
+bool Item_param::value_eq(const Item *item, bool binary_cmp) const
+{
+ switch (value.type_handler()->cmp_type()) {
+ case INT_RESULT:
+ return int_eq(value.integer, item);
+ case REAL_RESULT:
+ return real_eq(value.real, item);
+ case STRING_RESULT:
+ return str_eq(&value.m_string, item, binary_cmp);
+ case DECIMAL_RESULT:
+ case TIME_RESULT:
+ case ROW_RESULT:
+ break;
+ }
+ return false;
+}
+
+
bool
Item_param::eq(const Item *item, bool binary_cmp) const
{
@@ -4452,15 +4792,9 @@ Item_param::eq(const Item *item, bool binary_cmp) const
return false;
case NULL_VALUE:
return null_eq(item);
- case INT_VALUE:
- return int_eq(value.integer, item);
- case REAL_VALUE:
- return real_eq(value.real, item);
- case STRING_VALUE:
+ case SHORT_DATA_VALUE:
case LONG_DATA_VALUE:
- return str_eq(&str_value, item, binary_cmp);
- case DECIMAL_VALUE:
- case TIME_VALUE:
+ return value_eq(item, binary_cmp);
case NO_VALUE:
return false;
}
@@ -4521,18 +4855,14 @@ Item_param::set_param_type_and_swap_value(Item_param *src)
{
Type_std_attributes::set(src);
set_handler(src->type_handler());
- set_param_func= src->set_param_func;
item_type= src->item_type;
maybe_null= src->maybe_null;
null_value= src->null_value;
state= src->state;
fixed= src->fixed;
- value= src->value;
- decimal_value.swap(src->decimal_value);
- str_value.swap(src->str_value);
- str_value_ptr.swap(src->str_value_ptr);
+ value.swap(src->value);
}
@@ -4577,65 +4907,23 @@ bool
Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
{
Item *arg= *it;
-
- if (arg->is_null())
+ struct st_value tmp;
+ /*
+ The OUT parameter is bound to some data type.
+ It's important not to touch m_type_handler,
+ to make sure the next mysql_stmt_execute()
+ correctly fetches the value from the client-server protocol,
+ using set_param_func().
+ */
+ if (arg->save_in_value(&tmp) ||
+ set_value(thd, arg, &tmp, arg->type_handler()))
{
set_null();
- return FALSE;
- }
-
- null_value= FALSE;
-
- switch (arg->result_type()) {
- case STRING_RESULT:
- {
- char str_buffer[STRING_BUFFER_USUAL_SIZE];
- String sv_buffer(str_buffer, sizeof(str_buffer), &my_charset_bin);
- String *sv= arg->val_str(&sv_buffer);
-
- if (!sv)
- return TRUE;
-
- set_str(sv->c_ptr_safe(), sv->length());
- str_value_ptr.set(str_value.ptr(),
- str_value.length(),
- str_value.charset());
- collation.set(str_value.charset(), DERIVATION_COERCIBLE);
- decimals= 0;
- break;
- }
-
- case REAL_RESULT:
- set_double(arg->val_real());
- break;
-
- case INT_RESULT:
- set_int(arg->val_int(), arg->max_length);
- break;
-
- case DECIMAL_RESULT:
- {
- my_decimal dv_buf;
- my_decimal *dv= arg->val_decimal(&dv_buf);
-
- if (!dv)
- return TRUE;
-
- set_decimal(dv, !dv->sign());
- break;
- }
-
- default:
- /* That can not happen. */
-
- DBUG_ASSERT(TRUE); // Abort in debug mode.
-
- set_null(); // Set to NULL in release mode.
- return FALSE;
+ return false;
}
-
- set_handler_by_result_type(arg->result_type());
- return FALSE;
+ /* It is wrapper => other set_* shoud set null_value */
+ DBUG_ASSERT(null_value == false);
+ return false;
}
@@ -5325,7 +5613,8 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
select->having_fix_field &&
- select_ref != not_found_item && !group_by_ref)
+ select_ref != not_found_item && !group_by_ref &&
+ !ref->alias_name_used)
{
/*
Report the error if fields was found only in the SELECT item list and
@@ -5465,7 +5754,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
*/
Name_resolution_context *last_checked_context= context;
Item **ref= (Item **) not_found_item;
- SELECT_LEX *current_sel= (SELECT_LEX *) thd->lex->current_select;
+ SELECT_LEX *current_sel= thd->lex->current_select;
Name_resolution_context *outer_context= 0;
SELECT_LEX *select= 0;
/* Currently derived tables cannot be correlated */
@@ -5799,11 +6088,11 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(fixed == 0);
Field *from_field= (Field *)not_found_field;
bool outer_fixed= false;
+ SELECT_LEX *select= thd->lex->current_select;
- if (thd->lex->current_select->in_tvc)
+ if (select && select->in_tvc)
{
- my_error(ER_FIELD_REFERENCE_IN_TVC, MYF(0),
- full_name(), thd->where);
+ my_error(ER_FIELD_REFERENCE_IN_TVC, MYF(0), full_name());
return(1);
}
@@ -5815,6 +6104,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
expression to 'reference', i.e. it substitute that expression instead
of this Item_field
*/
+ DBUG_ASSERT(context);
if ((from_field= find_field_in_tables(thd, this,
context->first_name_resolution_table,
context->last_name_resolution_table,
@@ -5827,13 +6117,14 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
not_found_field)
{
int ret;
+
/* Look up in current select's item_list to find aliased fields */
- if (thd->lex->current_select->is_item_list_lookup)
+ if (select && select->is_item_list_lookup)
{
uint counter;
enum_resolution_type resolution;
Item** res= find_item_in_list(this,
- thd->lex->current_select->item_list,
+ select->item_list,
&counter, REPORT_EXCEPT_NOT_FOUND,
&resolution);
if (!res)
@@ -5865,7 +6156,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
- set_max_sum_func_level(thd, thd->lex->current_select);
+ set_max_sum_func_level(thd, select);
set_field(new_field);
return 0;
}
@@ -5884,7 +6175,6 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (err)
return TRUE;
- SELECT_LEX *select= thd->lex->current_select;
thd->change_item_tree(reference,
select->context_analysis_place == IN_GROUP_BY &&
alias_name_used ? *rf->ref : rf);
@@ -5893,11 +6183,17 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
- set_max_sum_func_level(thd, thd->lex->current_select);
+ set_max_sum_func_level(thd, select);
return FALSE;
}
}
}
+
+ if (!select)
+ {
+ my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where);
+ goto error;
+ }
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
goto error;
outer_fixed= TRUE;
@@ -5926,9 +6222,9 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level ==
- thd->lex->current_select->nest_level)
+ select->nest_level)
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
- thd->lex->current_select->nest_level);
+ select->nest_level);
/*
if it is not expression from merged VIEW we will set this field.
@@ -5946,11 +6242,11 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
set_field(from_field);
}
- else if (thd->mark_used_columns != MARK_COLUMNS_NONE)
+ else if (should_mark_column(thd->column_usage))
{
TABLE *table= field->table;
MY_BITMAP *current_bitmap, *other_bitmap;
- if (thd->mark_used_columns == MARK_COLUMNS_READ)
+ if (thd->column_usage == MARK_COLUMNS_READ)
{
current_bitmap= table->read_set;
other_bitmap= table->write_set;
@@ -5994,11 +6290,12 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
fix_session_vcol_expr_for_read(thd, field, field->vcol_info);
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
!outer_fixed && !thd->lex->in_sum_func &&
- thd->lex->current_select->cur_pos_in_select_list != UNDEF_POS &&
- thd->lex->current_select->join)
+ select &&
+ select->cur_pos_in_select_list != UNDEF_POS &&
+ select->join)
{
- thd->lex->current_select->join->non_agg_fields.push_back(this, thd->mem_root);
- marker= thd->lex->current_select->cur_pos_in_select_list;
+ select->join->non_agg_fields.push_back(this, thd->mem_root);
+ marker= select->cur_pos_in_select_list;
}
mark_non_agg_field:
/*
@@ -6035,7 +6332,7 @@ mark_non_agg_field:
if (outer_fixed)
thd->lex->in_sum_func->outer_fields.push_back(this, thd->mem_root);
else if (thd->lex->in_sum_func->nest_level !=
- thd->lex->current_select->nest_level)
+ select->nest_level)
select_lex->set_non_agg_field_used(true);
}
}
@@ -6669,13 +6966,13 @@ int Item_int::save_in_field(Field *field, bool no_conversions)
Item *Item_int::clone_item(THD *thd)
{
- return new (thd->mem_root) Item_int(thd, name.str, value, max_length);
+ return new (thd->mem_root) Item_int(thd, name.str, value, max_length, unsigned_flag);
}
-void Item_datetime::set(longlong packed)
+void Item_datetime::set(longlong packed, enum_mysql_timestamp_type ts_type)
{
- unpack_time(packed, &ltime);
+ unpack_time(packed, &ltime, ts_type);
}
int Item_datetime::save_in_field(Field *field, bool no_conversions)
@@ -6833,7 +7130,7 @@ static uint nr_of_decimals(const char *str, const char *end)
Item->name should be fixed to use LEX_STRING eventually.
*/
-Item_float::Item_float(THD *thd, const char *str_arg, uint length):
+Item_float::Item_float(THD *thd, const char *str_arg, size_t length):
Item_num(thd)
{
int error;
@@ -6843,13 +7140,13 @@ Item_float::Item_float(THD *thd, const char *str_arg, uint length):
if (error)
{
char tmp[NAME_LEN + 1];
- my_snprintf(tmp, sizeof(tmp), "%.*s", length, str_arg);
+ my_snprintf(tmp, sizeof(tmp), "%.*s", (int)length, str_arg);
my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", tmp);
}
presentation= name.str= str_arg;
name.length= strlen(str_arg);
decimals=(uint8) nr_of_decimals(str_arg, str_arg+length);
- max_length=length;
+ max_length=(uint32)length;
fixed= 1;
}
@@ -6886,10 +7183,9 @@ inline uint char_val(char X)
}
-void Item_hex_constant::hex_string_init(THD *thd, const char *str,
- uint str_length)
+void Item_hex_constant::hex_string_init(THD *thd, const char *str, size_t str_length)
{
- max_length=(str_length+1)/2;
+ max_length=(uint)((str_length+1)/2);
char *ptr=(char*) thd->alloc(max_length+1);
if (!ptr)
{
@@ -6951,7 +7247,7 @@ void Item_hex_string::print(String *str, enum_query_type query_type)
In number context this is a longlong value.
*/
-Item_bin_string::Item_bin_string(THD *thd, const char *str, uint str_length):
+Item_bin_string::Item_bin_string(THD *thd, const char *str, size_t str_length):
Item_hex_hybrid(thd)
{
const char *end= str + str_length - 1;
@@ -6959,7 +7255,7 @@ Item_bin_string::Item_bin_string(THD *thd, const char *str, uint str_length):
uchar bits= 0;
uint power= 1;
- max_length= (str_length + 7) >> 3;
+ max_length= (uint)((str_length + 7) >> 3);
if (!(ptr= (char*) thd->alloc(max_length + 1)))
return;
str_value.set(ptr, max_length, &my_charset_bin);
@@ -6999,7 +7295,6 @@ bool Item_temporal_literal::eq(const Item *item, bool binary_cmp) const
&((Item_temporal_literal *) item)->cached_time);
}
-
void Item_date_literal::print(String *str, enum_query_type query_type)
{
str->append("DATE'");
@@ -7342,7 +7637,7 @@ Item *Item_field::derived_field_transformer_for_where(THD *thd, uchar *arg)
st_select_lex *sel= (st_select_lex *)arg;
Item *producing_item= find_producing_item(this, sel);
if (producing_item)
- return producing_item->build_clone(thd, thd->mem_root);
+ return producing_item->build_clone(thd);
return this;
}
@@ -7354,7 +7649,7 @@ Item *Item_direct_view_ref::derived_field_transformer_for_where(THD *thd,
st_select_lex *sel= (st_select_lex *)arg;
Item *producing_item= find_producing_item(this, sel);
DBUG_ASSERT (producing_item != NULL);
- return producing_item->build_clone(thd, thd->mem_root);
+ return producing_item->build_clone(thd);
}
return this;
}
@@ -7400,7 +7695,7 @@ Item *Item_field::derived_grouping_field_transformer_for_where(THD *thd,
st_select_lex *sel= (st_select_lex *)arg;
Grouping_tmp_field *gr_field= find_matching_grouping_field(this, sel);
if (gr_field)
- return gr_field->producing_item->build_clone(thd, thd->mem_root);
+ return gr_field->producing_item->build_clone(thd);
return this;
}
@@ -7413,7 +7708,7 @@ Item_direct_view_ref::derived_grouping_field_transformer_for_where(THD *thd,
return this;
st_select_lex *sel= (st_select_lex *)arg;
Grouping_tmp_field *gr_field= find_matching_grouping_field(this, sel);
- return gr_field->producing_item->build_clone(thd, thd->mem_root);
+ return gr_field->producing_item->build_clone(thd);
}
void Item_field::print(String *str, enum_query_type query_type)
@@ -7428,26 +7723,6 @@ void Item_field::print(String *str, enum_query_type query_type)
}
-bool Item_field_row::element_index_by_name(uint *idx,
- const LEX_CSTRING &name) const
-{
- Field *field;
- for (uint i= 0; (field= get_row_field(i)); i++)
- {
- // Use the same comparison style with sp_context::find_variable()
- if (!my_strnncoll(system_charset_info,
- (const uchar *) field->field_name.str,
- field->field_name.length,
- (const uchar *) name.str, name.length))
- {
- *idx= i;
- return false;
- }
- }
- return true;
-}
-
-
void Item_temptable_field::print(String *str, enum_query_type query_type)
{
/*
@@ -7943,8 +8218,7 @@ void Item_ref::print(String *str, enum_query_type query_type)
!table_name && name.str && alias_name_used)
{
THD *thd= current_thd;
- append_identifier(thd, str, (*ref)->real_item()->name.str,
- (*ref)->real_item()->name.length);
+ append_identifier(thd, str, &(*ref)->real_item()->name);
}
else
(*ref)->print(str, query_type);
@@ -8253,7 +8527,7 @@ Item_cache_wrapper::Item_cache_wrapper(THD *thd, Item *item_arg):
with_sum_func= orig_item->with_sum_func;
with_field= orig_item->with_field;
name= item_arg->name;
- with_subselect= orig_item->with_subselect;
+ m_with_subquery= orig_item->with_subquery();
if ((expr_value= orig_item->get_cache(thd)))
expr_value->setup(thd, orig_item);
@@ -8680,7 +8954,7 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
*/
Field *fld= ((Item_field*) ref_item)->field;
DBUG_ASSERT(fld && fld->table);
- if (thd->mark_used_columns == MARK_COLUMNS_READ)
+ if (thd->column_usage == MARK_COLUMNS_READ)
bitmap_set_bit(fld->table->read_set, fld->field_index);
}
}
@@ -8981,7 +9255,7 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
if (!newptr)
goto error;
fix_session_vcol_expr_for_read(thd, def_field, def_field->default_value);
- if (thd->mark_used_columns != MARK_COLUMNS_NONE)
+ if (should_mark_column(thd->column_usage))
def_field->default_value->expr->walk(&Item::register_field_in_read_map, 1, 0);
def_field->move_field(newptr+1, def_field->maybe_null() ? newptr : 0, 1);
}
@@ -9163,7 +9437,7 @@ bool Item_ignore_value::send(Protocol *protocol, st_value *buffer)
bool Item_insert_value::eq(const Item *item, bool binary_cmp) const
{
return item->type() == INSERT_VALUE_ITEM &&
- ((Item_default_value *)item)->arg->eq(arg, binary_cmp);
+ ((Item_insert_value *)item)->arg->eq(arg, binary_cmp);
}
@@ -9259,15 +9533,16 @@ void Item_trigger_field::setup_field(THD *thd, TABLE *table,
So instead we do it in Table_triggers_list::mark_fields_used()
method which is called during execution of these statements.
*/
- enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
- thd->mark_used_columns= MARK_COLUMNS_NONE;
+ enum_column_usage saved_column_usage= thd->column_usage;
+ thd->column_usage= want_privilege == SELECT_ACL ? COLUMNS_READ
+ : COLUMNS_WRITE;
/*
Try to find field by its name and if it will be found
set field_idx properly.
*/
(void)find_field_in_table(thd, table, field_name.str, field_name.length,
0, &field_idx);
- thd->mark_used_columns= save_mark_used_columns;
+ thd->column_usage= saved_column_usage;
triggers= table->triggers;
table_grants= table_grant_info;
}
@@ -9294,7 +9569,7 @@ void Item_trigger_field::set_required_privilege(bool rw)
bool Item_trigger_field::set_value(THD *thd, sp_rcontext * /*ctx*/, Item **it)
{
- Item *item= sp_prepare_func_item(thd, it);
+ Item *item= thd->sp_prepare_func_item(it);
if (!item)
return true;
@@ -9751,13 +10026,7 @@ bool Item_cache_temporal::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
return 1;
}
- unpack_time(value, ltime);
- ltime->time_type= mysql_timestamp_type();
- if (ltime->time_type == MYSQL_TIMESTAMP_TIME)
- {
- ltime->hour+= (ltime->month*32+ltime->day)*24;
- ltime->month= ltime->day= 0;
- }
+ unpack_time(value, ltime, mysql_timestamp_type());
return 0;
}
@@ -9802,7 +10071,7 @@ Item *Item_cache_temporal::convert_to_basic_const_item(THD *thd)
else
{
MYSQL_TIME ltime;
- unpack_time(val_datetime_packed(), &ltime);
+ unpack_time(val_datetime_packed(), &ltime, MYSQL_TIMESTAMP_DATETIME);
new_item= (Item*) new (thd->mem_root) Item_datetime_literal(thd, &ltime,
decimals);
}
@@ -10173,6 +10442,12 @@ String *Item_type_holder::val_str(String*)
return 0;
}
+bool Item_type_holder::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ DBUG_ASSERT(0); // should never be called
+ return true;
+}
+
void Item_result_field::cleanup()
{
DBUG_ENTER("Item_result_field::cleanup()");
@@ -10289,11 +10564,11 @@ const char *dbug_print_item(Item *item)
ulonglong save_option_bits= thd->variables.option_bits;
thd->variables.option_bits &= ~OPTION_QUOTE_SHOW_CREATE;
- item->print(&str ,QT_EXPLAIN);
+ item->print(&str, QT_EXPLAIN);
thd->variables.option_bits= save_option_bits;
- if (str.c_ptr() == buf)
+ if (str.c_ptr_safe() == buf)
return buf;
else
return "Couldn't fit into buffer";
@@ -10358,6 +10633,12 @@ Item_field::excl_dep_on_grouping_fields(st_select_lex *sel)
return find_matching_grouping_field(this, sel) != NULL;
}
+bool Item_field::vers_trx_id() const
+{
+ DBUG_ASSERT(field);
+ return field->vers_trx_id();
+}
+
void Item::register_in(THD *thd)
{
next= thd->free_list;
diff --git a/sql/item.h b/sql/item.h
index dbbc93c5e9d..2a7b92dd601 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -2,7 +2,7 @@
#define SQL_ITEM_INCLUDED
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, MariaDB
+ Copyright (c) 2009, 2018, 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
@@ -87,7 +87,11 @@ public:
};
+#ifdef DBUG_OFF
+static inline const char *dbug_print_item(Item *item) { return NULL; }
+#else
const char *dbug_print_item(Item *item);
+#endif
class Virtual_tmp_table;
class sp_head;
@@ -128,8 +132,6 @@ enum precedence {
HIGHEST_PRECEDENCE
};
-typedef Bounds_checked_array<Item*> Ref_ptr_array;
-
bool mark_unsupported_function(const char *where, void *store, uint result);
/* convenience helper for mark_unsupported_function() above */
@@ -303,6 +305,28 @@ public:
}
};
+class Name_resolution_context_backup
+{
+ Name_resolution_context &ctx;
+ TABLE_LIST &table_list;
+ table_map save_map;
+ Name_resolution_context_state ctx_state;
+
+public:
+ Name_resolution_context_backup(Name_resolution_context &_ctx, TABLE_LIST &_table_list)
+ : ctx(_ctx), table_list(_table_list), save_map(_table_list.map)
+ {
+ ctx_state.save_state(&ctx, &table_list);
+ ctx.table_list= &table_list;
+ ctx.first_name_resolution_table= &table_list;
+ }
+ ~Name_resolution_context_backup()
+ {
+ ctx_state.restore_state(&ctx, &table_list);
+ table_list.map= save_map;
+ }
+};
+
/*
This enum is used to report information about monotonicity of function
@@ -391,6 +415,8 @@ public:
virtual const Send_field *get_out_param_info() const
{ return NULL; }
+
+ virtual Item_param *get_item_param() { return 0; }
};
@@ -541,7 +567,6 @@ public:
String_copier_for_item(THD *thd): m_thd(thd) { }
};
-
class Item: public Value_source,
public Type_all_attributes
{
@@ -562,7 +587,7 @@ class Item: public Value_source,
public:
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return alloc_root(mem_root, size); }
- static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
+ static void operator delete(void *ptr,size_t size) { TRASH_FREE(ptr, size); }
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
enum Type {FIELD_ITEM= 0, FUNC_ITEM, SUM_FUNC_ITEM,
@@ -659,13 +684,12 @@ protected:
value= NULL;
return value;
}
- bool get_date_with_conversion_from_item(Item *item,
- MYSQL_TIME *ltime,
- ulonglong fuzzydate)
- {
- DBUG_ASSERT(fixed == 1);
- return (null_value= item->get_date_with_conversion(ltime, fuzzydate));
- }
+ /*
+ This method is used if the item was not null but convertion to
+ TIME/DATE/DATETIME failed. We return a zero date if allowed,
+ otherwise - null.
+ */
+ bool make_zero_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
public:
/*
@@ -701,9 +725,6 @@ public:
bool fixed; /* If item fixed with fix_fields */
bool is_autogenerated_name; /* indicate was name of this Item
autogenerated or set by user */
- bool with_subselect; /* If this item is a subselect or some
- of its arguments is or contains a
- subselect */
// alloc & destruct is done as start of select on THD::mem_root
Item(THD *thd);
/*
@@ -722,7 +743,7 @@ public:
name.length= 0;
#endif
} /*lint -e1509 */
- void set_name(THD *thd, const char *str, uint length, CHARSET_INFO *cs);
+ void set_name(THD *thd, const char *str, size_t length, CHARSET_INFO *cs);
void set_name_no_truncate(THD *thd, const char *str, uint length,
CHARSET_INFO *cs);
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
@@ -777,6 +798,10 @@ public:
return type_handler()->field_type();
}
virtual const Type_handler *type_handler() const= 0;
+ virtual uint field_flags() const
+ {
+ return 0;
+ }
const Type_handler *type_handler_for_comparison() const
{
return type_handler()->type_handler_for_comparison();
@@ -1197,7 +1222,7 @@ public:
virtual bool basic_const_item() const { return 0; }
/* cloning of constant items (0 if it is not const) */
virtual Item *clone_item(THD *thd) { return 0; }
- virtual Item* build_clone(THD *thd, MEM_ROOT *mem_root) { return get_copy(thd, mem_root); }
+ virtual Item* build_clone(THD *thd) { return get_copy(thd); }
virtual cond_result eq_cmp_result() const { return COND_OK; }
inline uint float_length(uint decimals_par) const
{ return decimals < FLOATING_POINT_DECIMALS ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
@@ -1347,19 +1372,23 @@ public:
void split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &fields,
Item **ref, uint flags);
- virtual bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ virtual bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)= 0;
+ bool get_date_from_int(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date_from_year(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date_from_real(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date_from_decimal(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date_from_string(MYSQL_TIME *ltime, ulonglong fuzzydate);
bool get_time(MYSQL_TIME *ltime)
- { return get_date(ltime, TIME_TIME_ONLY | TIME_INVALID_DATES); }
- // Get date with automatic TIME->DATETIME conversion
- bool get_date_with_conversion(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ { return get_date(ltime, Time::flags_for_get_date()); }
/*
- Get time with automatic DATE/DATETIME to TIME conversion.
+ Get time with automatic DATE/DATETIME to TIME conversion,
+ by subtracting CURRENT_DATE.
- Performce a reserve operation to get_date_with_conversion().
+ Performce a reverse operation to CAST(time AS DATETIME)
Suppose:
- we have a set of items (typically with the native MYSQL_TYPE_TIME type)
whose item->get_date() return TIME1 value, and
- - item->get_date_with_conversion() for the same Items return DATETIME1,
+ - CAST(AS DATETIME) for the same Items return DATETIME1,
after applying time-to-datetime conversion to TIME1.
then all items (typically of the native MYSQL_TYPE_{DATE|DATETIME} types)
@@ -1388,22 +1417,21 @@ public:
// Get a DATE or DATETIME value in numeric packed format for comparison
virtual longlong val_datetime_packed()
{
- MYSQL_TIME ltime;
ulonglong fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES;
- return get_date_with_conversion(&ltime, fuzzydate) ? 0 : pack_time(&ltime);
+ Datetime dt(current_thd, this, fuzzydate);
+ return dt.is_valid_datetime() ? pack_time(dt.get_mysql_time()) : 0;
}
// Get a TIME value in numeric packed format for comparison
virtual longlong val_time_packed()
{
- MYSQL_TIME ltime;
- ulonglong fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES | TIME_TIME_ONLY;
- return get_date(&ltime, fuzzydate) ? 0 : pack_time(&ltime);
+ Time tm(this, Time::comparison_flags_for_get_date());
+ return tm.is_valid_time() ? pack_time(tm.get_mysql_time()) : 0;
}
longlong val_datetime_packed_result();
longlong val_time_packed_result()
{
MYSQL_TIME ltime;
- ulonglong fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES | TIME_TIME_ONLY;
+ ulonglong fuzzydate= Time::comparison_flags_for_get_date();
return get_date_result(&ltime, fuzzydate) ? 0 : pack_time(&ltime);
}
@@ -1638,6 +1666,7 @@ public:
*/
virtual bool check_partition_func_processor(void *arg) { return 1;}
virtual bool vcol_in_partition_func_processor(void *arg) { return 0; }
+ virtual bool rename_fields_processor(void *arg) { return 0; }
/** Processor used to check acceptability of an item in the defining
expression for a virtual column
@@ -1651,6 +1680,12 @@ public:
uint errors; /* Bits of possible errors */
const char *name; /* Not supported function */
};
+ struct func_processor_rename
+ {
+ LEX_CSTRING db_name;
+ LEX_CSTRING table_name;
+ List<Create_field> fields;
+ };
virtual bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(full_name(), arg, VCOL_IMPOSSIBLE);
@@ -1667,7 +1702,7 @@ public:
virtual bool set_fields_as_dependent_processor(void *arg) { return 0; }
/*============== End of Item processor list ======================*/
- virtual Item *get_copy(THD *thd, MEM_ROOT *mem_root)=0;
+ virtual Item *get_copy(THD *thd)=0;
bool cache_const_expr_analyzer(uchar **arg);
Item* cache_const_expr_transformer(THD *thd, uchar *arg);
@@ -1711,10 +1746,6 @@ public:
// Row emulation
virtual uint cols() const { return 1; }
virtual Item* element_index(uint i) { return this; }
- virtual bool element_index_by_name(uint *idx, const LEX_CSTRING &name) const
- {
- return true; // Error
- }
virtual Item** addr(uint i) { return 0; }
virtual bool check_cols(uint c);
bool check_type_traditional_scalar(const char *opname) const;
@@ -1745,6 +1776,8 @@ public:
virtual Item_field *field_for_view_update() { return 0; }
+ virtual bool vers_trx_id() const
+ { return false; }
virtual Item *neg_transformer(THD *thd) { return NULL; }
virtual Item *update_value_transformer(THD *thd, uchar *select_arg)
{ return this; }
@@ -1871,9 +1904,10 @@ public:
virtual bool is_outer_field() const { DBUG_ASSERT(fixed); return FALSE; }
/**
- Checks if this item or any of its decendents contains a subquery.
+ Checks if this item or any of its decendents contains a subquery. This is a
+ replacement of the former Item::has_subquery() and Item::with_subselect.
*/
- virtual bool has_subquery() const { return with_subselect; }
+ virtual bool with_subquery() const { DBUG_ASSERT(fixed); return false; }
Item* set_expr_cache(THD *thd);
@@ -1939,16 +1973,33 @@ public:
}
};
+MEM_ROOT *get_thd_memroot(THD *thd);
template <class T>
-inline Item* get_item_copy (THD *thd, MEM_ROOT *mem_root, T* item)
+inline Item* get_item_copy (THD *thd, T* item)
{
- Item *copy= new (mem_root) T(*item);
- copy->register_in(thd);
+ Item *copy= new (get_thd_memroot(thd)) T(*item);
+ if (copy)
+ copy->register_in(thd);
return copy;
}
+/*
+ This class is a replacement for the former member Item::with_subselect.
+ Determines if the descendant Item is a subselect or some of
+ its arguments is or contains a subselect.
+*/
+class With_subquery_cache
+{
+protected:
+ bool m_with_subquery;
+public:
+ With_subquery_cache(): m_with_subquery(false) { }
+ void join(const Item *item) { m_with_subquery|= item->with_subquery(); }
+};
+
+
class Type_geometry_attributes
{
uint m_geometry_type;
@@ -2171,7 +2222,8 @@ protected:
uint repertoire() const { return MY_STRING_METADATA::repertoire; }
size_t char_length() const { return MY_STRING_METADATA::char_length; }
};
- void fix_charset_and_length_from_str_value(Derivation dv, Metadata metadata)
+ void fix_charset_and_length(CHARSET_INFO *cs,
+ Derivation dv, Metadata metadata)
{
/*
We have to have a different max_length than 'length' here to
@@ -2180,13 +2232,13 @@ protected:
number of chars for a string of this type because we in Create_field::
divide the max_length with mbmaxlen).
*/
- collation.set(str_value.charset(), dv, metadata.repertoire());
+ collation.set(cs, dv, metadata.repertoire());
fix_char_length(metadata.char_length());
decimals= NOT_FIXED_DEC;
}
- void fix_charset_and_length_from_str_value(Derivation dv)
+ void fix_charset_and_length_from_str_value(const String &str, Derivation dv)
{
- fix_charset_and_length_from_str_value(dv, Metadata(&str_value));
+ fix_charset_and_length(str.charset(), dv, Metadata(&str));
}
Item_basic_value(THD *thd): Item(thd) {}
/*
@@ -2285,6 +2337,7 @@ public:
longlong val_int();
String *val_str(String *sp);
my_decimal *val_decimal(my_decimal *decimal_value);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
bool is_null();
public:
@@ -2375,7 +2428,7 @@ public:
bool append_for_log(THD *thd, String *str);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item *get_copy(THD *thd) { return 0; }
/*
Override the inherited create_field_for_create_select(),
@@ -2503,7 +2556,7 @@ public:
purposes.
*/
virtual void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item *get_copy(THD *thd) { return 0; }
private:
uint m_case_expr_id;
@@ -2547,6 +2600,7 @@ public:
longlong val_int();
String *val_str(String *sp);
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
bool is_null();
virtual void print(String *str, enum_query_type query_type);
@@ -2573,8 +2627,8 @@ public:
{
return mark_unsupported_function("name_const()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_name_const>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_name_const>(thd, this); }
};
class Item_num: public Item_basic_constant
@@ -2583,6 +2637,10 @@ public:
Item_num(THD *thd): Item_basic_constant(thd) { collation.set_numeric(); }
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
bool check_partition_func_processor(void *int_arg) { return FALSE;}
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ }
};
#define NO_CACHED_FIELD_INDEX ((uint)(-1))
@@ -2704,14 +2762,18 @@ public:
longlong val_int() { return field->val_int(); }
String *val_str(String *str) { return field->val_str(str); }
my_decimal *val_decimal(my_decimal *dec) { return field->val_decimal(dec); }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return field->get_date(ltime, fuzzydate);
+ }
void make_field(THD *thd, Send_field *tmp_field);
const Type_handler *type_handler() const
{
const Type_handler *handler= field->type_handler();
return handler->type_handler_for_item_field();
}
- Item* get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_ident_for_show>(thd, mem_root, this); }
+ Item* get_copy(THD *thd)
+ { return get_item_copy<Item_ident_for_show>(thd, this); }
};
@@ -2787,6 +2849,10 @@ public:
return field->type_handler();
}
TYPELIB *get_typelib() const { return field->get_typelib(); }
+ uint32 field_flags() const
+ {
+ return field->flags;
+ }
enum_monotonicity_info get_monotonicity_info() const
{
return MONOTONIC_STRICT_INCREASING;
@@ -2855,6 +2921,7 @@ public:
bool update_table_bitmaps_processor(void *arg);
bool switch_to_nullable_fields_processor(void *arg);
bool update_vcol_processor(void *arg);
+ bool rename_fields_processor(void *arg);
bool check_vcol_func_processor(void *arg)
{
context= 0;
@@ -2883,6 +2950,7 @@ public:
uint32 max_display_length() const { return field->max_display_length(); }
Item_field *field_for_view_update() { return this; }
int fix_outer_field(THD *thd, Field **field, Item **reference);
+ virtual bool vers_trx_id() const;
virtual Item *update_value_transformer(THD *thd, uchar *select_arg);
Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
Item *derived_field_transformer_for_where(THD *thd, uchar *arg);
@@ -2895,8 +2963,8 @@ public:
bool cleanup_excluding_const_fields_processor(void *arg)
{ return field && const_item() ? 0 : cleanup_processor(arg); }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_field>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_field>(thd, this); }
bool is_outer_field() const
{
DBUG_ASSERT(fixed);
@@ -2924,12 +2992,11 @@ public:
:Item_field(thd, field),
Item_args()
{ }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_field_row>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_field_row>(thd, this); }
const Type_handler *type_handler() const { return &type_handler_row; }
uint cols() const { return arg_count; }
- bool element_index_by_name(uint *idx, const LEX_CSTRING &name) const;
Item* element_index(uint i) { return arg_count ? args[i] : this; }
Item** addr(uint i) { return arg_count ? args + i : NULL; }
bool check_cols(uint c)
@@ -2942,7 +3009,6 @@ public:
return false;
}
bool row_create_items(THD *thd, List<Spvar_definition> *list);
- Field *get_row_field(uint i) const;
};
@@ -3005,6 +3071,7 @@ public:
longlong val_int();
String *val_str(String *str);
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
int save_in_field(Field *field, bool no_conversions);
int save_safe_in_field(Field *field);
bool send(Protocol *protocol, st_value *buffer);
@@ -3020,8 +3087,8 @@ public:
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
bool check_partition_func_processor(void *int_arg) {return FALSE;}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_null>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_null>(thd, this); }
};
class Item_null_result :public Item_null
@@ -3062,12 +3129,27 @@ public:
For example in case of 'SELECT ?' you'll get MYSQL_TYPE_STRING both
in result set and placeholders metadata, no matter what type you will
supply for this placeholder in mysql_stmt_execute.
+
+ Item_param has two Type_handler pointers,
+ which can point to different handlers:
+
+ 1. In the Type_handler_hybrid_field_type member
+ It's initialized in:
+ - Item_param::setup_conversion(), for client-server PS protocol,
+ according to the bind type.
+ - Item_param::set_from_item(), for EXECUTE and EXECUTE IMMEDIATE,
+ according to the actual parameter data type.
+
+ 2. In the "value" member.
+ It's initialized in:
+ - Item_param::set_param_func(), for client-server PS protocol.
+ - Item_param::set_from_item(), for EXECUTE and EXECUTE IMMEDIATE.
*/
class Item_param :public Item_basic_value,
private Settable_routine_parameter,
public Rewritable_query_parameter,
- public Type_handler_hybrid_field_type,
+ private Type_handler_hybrid_field_type,
public Type_geometry_attributes
{
/*
@@ -3113,9 +3195,8 @@ class Item_param :public Item_basic_value,
*/
enum enum_item_param_state
{
- NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE,
- STRING_VALUE, TIME_VALUE, LONG_DATA_VALUE,
- DECIMAL_VALUE, DEFAULT_VALUE, IGNORE_VALUE
+ NO_VALUE, NULL_VALUE, SHORT_DATA_VALUE, LONG_DATA_VALUE,
+ DEFAULT_VALUE, IGNORE_VALUE
} state;
enum Type item_type;
@@ -3128,7 +3209,6 @@ class Item_param :public Item_basic_value,
void fix_temporal(uint32 max_length_arg, uint decimals_arg);
-public:
struct CONVERSION_INFO
{
/*
@@ -3170,31 +3250,71 @@ public:
}
};
+ bool m_empty_string_is_null;
+
+ class PValue_simple
+ {
+ public:
+ union
+ {
+ longlong integer;
+ double real;
+ CONVERSION_INFO cs_info;
+ MYSQL_TIME time;
+ };
+ void swap(PValue_simple &other)
+ {
+ swap_variables(PValue_simple, *this, other);
+ }
+ };
+
+ class PValue: public Type_handler_hybrid_field_type,
+ public PValue_simple,
+ public Value_source
+ {
+ public:
+ PValue(): Type_handler_hybrid_field_type(&type_handler_null) {}
+ my_decimal m_decimal;
+ String m_string;
+ /*
+ A buffer for string and long data values. Historically all allocated
+ values returned from val_str() were treated as eligible to
+ modification. I. e. in some cases Item_func_concat can append it's
+ second argument to return value of the first one. Because of that we
+ can't return the original buffer holding string data from val_str(),
+ and have to have one buffer for data and another just pointing to
+ the data. This is the latter one and it's returned from val_str().
+ Can not be declared inside the union as it's not a POD type.
+ */
+ String m_string_ptr;
+
+ void swap(PValue &other)
+ {
+ Type_handler_hybrid_field_type::swap(other);
+ PValue_simple::swap(other);
+ m_decimal.swap(other.m_decimal);
+ m_string.swap(other.m_string);
+ m_string_ptr.swap(other.m_string_ptr);
+ }
+ double val_real() const;
+ longlong val_int(const Type_std_attributes *attr) const;
+ my_decimal *val_decimal(my_decimal *dec, const Type_std_attributes *attr);
+ String *val_str(String *str, const Type_std_attributes *attr);
+ };
+
+ PValue value;
+
+ const String *value_query_val_str(THD *thd, String* str) const;
+ bool value_eq(const Item *item, bool binary_cmp) const;
+ Item *value_clone_item(THD *thd);
+ bool can_return_value() const;
+
+public:
/*
Used for bulk protocol only.
*/
enum enum_indicator_type indicator;
- /*
- A buffer for string and long data values. Historically all allocated
- values returned from val_str() were treated as eligible to
- modification. I. e. in some cases Item_func_concat can append it's
- second argument to return value of the first one. Because of that we
- can't return the original buffer holding string data from val_str(),
- and have to have one buffer for data and another just pointing to
- the data. This is the latter one and it's returned from val_str().
- Can not be declared inside the union as it's not a POD type.
- */
- String str_value_ptr;
- my_decimal decimal_value;
- union
- {
- longlong integer;
- double real;
- CONVERSION_INFO cs_info;
- MYSQL_TIME time;
- } value;
-
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
@@ -3213,10 +3333,22 @@ public:
return item_type;
}
- double val_real();
- longlong val_int();
- my_decimal *val_decimal(my_decimal*);
- String *val_str(String*);
+ double val_real()
+ {
+ return can_return_value() ? value.val_real() : 0e0;
+ }
+ longlong val_int()
+ {
+ return can_return_value() ? value.val_int(this) : 0;
+ }
+ my_decimal *val_decimal(my_decimal *dec)
+ {
+ return can_return_value() ? value.val_decimal(dec, this) : NULL;
+ }
+ String *val_str(String *str)
+ {
+ return can_return_value() ? value.val_str(str, this) : NULL;
+ }
bool get_date(MYSQL_TIME *tm, ulonglong fuzzydate);
int save_in_field(Field *field, bool no_conversions);
@@ -3227,20 +3359,64 @@ public:
void set_double(double i);
void set_decimal(const char *str, ulong length);
void set_decimal(const my_decimal *dv, bool unsigned_arg);
- bool set_str(const char *str, ulong length);
+ bool set_str(const char *str, ulong length,
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
bool set_longdata(const char *str, ulong length);
void set_time(MYSQL_TIME *tm, timestamp_type type, uint32 max_length_arg);
void set_time(const MYSQL_TIME *tm, uint32 max_length_arg, uint decimals_arg);
bool set_from_item(THD *thd, Item *item);
void reset();
+
+ void set_param_tiny(uchar **pos, ulong len);
+ void set_param_short(uchar **pos, ulong len);
+ void set_param_int32(uchar **pos, ulong len);
+ void set_param_int64(uchar **pos, ulong len);
+ void set_param_float(uchar **pos, ulong len);
+ void set_param_double(uchar **pos, ulong len);
+ void set_param_decimal(uchar **pos, ulong len);
+ void set_param_time(uchar **pos, ulong len);
+ void set_param_datetime(uchar **pos, ulong len);
+ void set_param_date(uchar **pos, ulong len);
+ void set_param_str(uchar **pos, ulong len);
+
+ void setup_conversion(THD *thd, uchar param_type);
+ void setup_conversion_blob(THD *thd);
+ void setup_conversion_string(THD *thd, CHARSET_INFO *fromcs);
+
/*
Assign placeholder value from bind data.
Note, that 'len' has different semantics in embedded library (as we
don't need to check that packet is not broken there). See
sql_prepare.cc for details.
*/
- void (*set_param_func)(Item_param *param, uchar **pos, ulong len);
+ void set_param_func(uchar **pos, ulong len)
+ {
+ /*
+ To avoid Item_param::set_xxx() asserting on data type mismatch,
+ we set the value type handler here:
+ - It can not be initialized yet after Item_param::setup_conversion().
+ - Also, for LIMIT clause parameters, the value type handler might have
+ changed from the real type handler to type_handler_longlong.
+ So here we'll restore it.
+ */
+ const Type_handler *h= Item_param::type_handler();
+ value.set_handler(h);
+ h->Item_param_set_param_func(this, pos, len);
+ }
+
+ bool set_value(THD *thd, const Type_all_attributes *attr,
+ const st_value *val, const Type_handler *h)
+ {
+ value.set_handler(h); // See comments in set_param_func()
+ return h->Item_param_set_from_value(thd, this, attr, val);
+ }
+ bool set_limit_clause_param(longlong nr)
+ {
+ value.set_handler(&type_handler_longlong);
+ set_int(nr, MY_INT64_NUM_DECIMAL_DIGITS);
+ return !unsigned_flag && value.integer < 0;
+ }
const String *query_val_str(THD *thd, String *str) const;
bool convert_str_value(THD *thd);
@@ -3266,7 +3442,8 @@ public:
}
bool has_int_value() const
{
- return state == INT_VALUE;
+ return state == SHORT_DATA_VALUE &&
+ value.type_handler()->cmp_type() == INT_RESULT;
}
/*
This method is used to make a copy of a basic constant item when
@@ -3295,7 +3472,7 @@ public:
bool append_for_log(THD *thd, String *str);
bool check_vcol_func_processor(void *int_arg) {return FALSE;}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item *get_copy(THD *thd) { return 0; }
private:
void invalid_default_param() const;
@@ -3307,6 +3484,8 @@ private:
public:
virtual const Send_field *get_out_param_info() const;
+ Item_param *get_item_param() { return this; }
+
virtual void make_field(THD *thd, Send_field *field);
private:
@@ -3319,23 +3498,31 @@ class Item_int :public Item_num
{
public:
longlong value;
- Item_int(THD *thd, int32 i,uint length= MY_INT32_NUM_DECIMAL_DIGITS):
+ Item_int(THD *thd, int32 i,size_t length= MY_INT32_NUM_DECIMAL_DIGITS):
Item_num(thd), value((longlong) i)
- { max_length=length; fixed= 1; }
- Item_int(THD *thd, longlong i,uint length= MY_INT64_NUM_DECIMAL_DIGITS):
+ { max_length=(uint32)length; fixed= 1; }
+ Item_int(THD *thd, longlong i,size_t length= MY_INT64_NUM_DECIMAL_DIGITS):
Item_num(thd), value(i)
- { max_length=length; fixed= 1; }
- Item_int(THD *thd, ulonglong i, uint length= MY_INT64_NUM_DECIMAL_DIGITS):
+ { max_length=(uint32)length; fixed= 1; }
+ Item_int(THD *thd, ulonglong i, size_t length= MY_INT64_NUM_DECIMAL_DIGITS):
Item_num(thd), value((longlong)i)
- { max_length=length; fixed= 1; unsigned_flag= 1; }
- Item_int(THD *thd, const char *str_arg,longlong i,uint length):
+ { max_length=(uint32)length; fixed= 1; unsigned_flag= 1; }
+ Item_int(THD *thd, const char *str_arg,longlong i,size_t length):
Item_num(thd), value(i)
{
- max_length=length;
+ max_length=(uint32)length;
name.str= str_arg; name.length= safe_strlen(name.str);
fixed= 1;
}
- Item_int(THD *thd, const char *str_arg, uint length=64);
+ Item_int(THD *thd, const char *str_arg,longlong i,size_t length, bool flag):
+ Item_num(thd), value(i)
+ {
+ max_length=(uint32)length;
+ name.str= str_arg; name.length= safe_strlen(name.str);
+ fixed= 1;
+ unsigned_flag= flag;
+ }
+ Item_int(THD *thd, const char *str_arg, size_t length=64);
enum Type type() const { return INT_ITEM; }
const Type_handler *type_handler() const
{ return type_handler_long_or_longlong(); }
@@ -3357,8 +3544,8 @@ public:
{ return (uint) (max_length - MY_TEST(value < 0)); }
bool eq(const Item *item, bool binary_cmp) const
{ return int_eq(value, item); }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_int>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_int>(thd, this); }
};
@@ -3380,7 +3567,7 @@ public:
class Item_uint :public Item_int
{
public:
- Item_uint(THD *thd, const char *str_arg, uint length);
+ Item_uint(THD *thd, const char *str_arg, size_t length);
Item_uint(THD *thd, ulonglong i): Item_int(thd, i, 10) {}
Item_uint(THD *thd, const char *str_arg, longlong i, uint length);
double val_real()
@@ -3390,8 +3577,8 @@ public:
virtual void print(String *str, enum_query_type query_type);
Item *neg(THD *thd);
uint decimal_precision() const { return max_length; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_uint>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_uint>(thd, this); }
};
@@ -3404,7 +3591,12 @@ public:
int save_in_field(Field *field, bool no_conversions);
longlong val_int();
double val_real() { return (double)val_int(); }
- void set(longlong packed);
+ void set(longlong packed, enum_mysql_timestamp_type ts_type);
+ bool get_date(MYSQL_TIME *to, ulonglong fuzzydate)
+ {
+ *to= ltime;
+ return false;
+ }
};
@@ -3414,7 +3606,7 @@ class Item_decimal :public Item_num
protected:
my_decimal decimal_value;
public:
- Item_decimal(THD *thd, const char *str_arg, uint length,
+ Item_decimal(THD *thd, const char *str_arg, size_t length,
CHARSET_INFO *charset);
Item_decimal(THD *thd, const char *str, const my_decimal *val_arg,
uint decimal_par, uint length);
@@ -3437,8 +3629,8 @@ public:
uint decimal_precision() const { return decimal_value.precision(); }
bool eq(const Item *, bool binary_cmp) const;
void set_decimal_value(my_decimal *value_par);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_decimal>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_decimal>(thd, this); }
};
@@ -3447,7 +3639,7 @@ class Item_float :public Item_num
const char *presentation;
public:
double value;
- Item_float(THD *thd, const char *str_arg, uint length);
+ Item_float(THD *thd, const char *str_arg, size_t length);
Item_float(THD *thd, const char *str, double val_arg, uint decimal_par,
uint length): Item_num(thd), value(val_arg)
{
@@ -3488,8 +3680,8 @@ public:
virtual void print(String *str, enum_query_type query_type);
bool eq(const Item *item, bool binary_cmp) const
{ return real_eq(value, item); }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_float>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_float>(thd, this); }
};
@@ -3519,7 +3711,7 @@ class Item_string :public Item_basic_constant
protected:
void fix_from_value(Derivation dv, const Metadata metadata)
{
- fix_charset_and_length_from_str_value(dv, metadata);
+ fix_charset_and_length(str_value.charset(), dv, metadata);
// it is constant => can be used without fix_fields (and frequently used)
fixed= 1;
}
@@ -3558,7 +3750,7 @@ public:
str_value.set_or_copy_aligned(str, length, cs);
fix_and_set_name_from_value(thd, dv, Metadata(&str_value, repertoire));
}
- Item_string(THD *thd, const char *str, uint length,
+ Item_string(THD *thd, const char *str, size_t length,
CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE):
Item_basic_constant(thd)
{
@@ -3574,21 +3766,21 @@ public:
fix_and_set_name_from_value(thd, dv, Metadata(&str_value, repertoire));
}
// Constructors with an externally provided item name
- Item_string(THD *thd, const char *name_par, const char *str, uint length,
+ Item_string(THD *thd, const char *name_par, const char *str, size_t length,
CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE):
Item_basic_constant(thd)
{
str_value.set_or_copy_aligned(str, length, cs);
fix_from_value(dv, Metadata(&str_value));
- set_name(thd, name_par, (uint) safe_strlen(name_par), system_charset_info);
+ set_name(thd, name_par,safe_strlen(name_par), system_charset_info);
}
- Item_string(THD *thd, const char *name_par, const char *str, uint length,
+ Item_string(THD *thd, const char *name_par, const char *str, size_t length,
CHARSET_INFO *cs, Derivation dv, uint repertoire):
Item_basic_constant(thd)
{
str_value.set_or_copy_aligned(str, length, cs);
fix_from_value(dv, Metadata(&str_value, repertoire));
- set_name(thd, name_par, (uint) safe_strlen(name_par), system_charset_info);
+ set_name(thd, name_par, safe_strlen(name_par), system_charset_info);
}
void print_value(String *to) const
{
@@ -3603,6 +3795,10 @@ public:
return (String*) &str_value;
}
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return get_date_from_string(ltime, fuzzydate);
+ }
int save_in_field(Field *field, bool no_conversions);
const Type_handler *type_handler() const { return &type_handler_varchar; }
bool basic_const_item() const { return 1; }
@@ -3679,8 +3875,8 @@ public:
return MYSQL_TYPE_STRING; // Not a temporal literal
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_string>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_string>(thd, this); }
};
@@ -3785,10 +3981,10 @@ class Item_return_date_time :public Item_partition_func_safe_string
enum_field_types date_time_field_type;
public:
Item_return_date_time(THD *thd, const char *name_arg, uint length_arg,
- enum_field_types field_type_arg):
+ enum_field_types field_type_arg, uint dec_arg= 0):
Item_partition_func_safe_string(thd, name_arg, length_arg, &my_charset_bin),
date_time_field_type(field_type_arg)
- { decimals= 0; }
+ { decimals= dec_arg; }
const Type_handler *type_handler() const
{
return Type_handler::get_handler_by_field_type(date_time_field_type);
@@ -3864,13 +4060,13 @@ public:
class Item_hex_constant: public Item_basic_constant
{
private:
- void hex_string_init(THD *thd, const char *str, uint str_length);
+ void hex_string_init(THD *thd, const char *str, size_t str_length);
public:
Item_hex_constant(THD *thd): Item_basic_constant(thd)
{
hex_string_init(thd, "", 0);
}
- Item_hex_constant(THD *thd, const char *str, uint str_length):
+ Item_hex_constant(THD *thd, const char *str, size_t str_length):
Item_basic_constant(thd)
{
hex_string_init(thd, str, str_length);
@@ -3890,6 +4086,10 @@ public:
str_value.bin_eq(&((Item_hex_constant*)item)->str_value);
}
String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ }
};
@@ -3902,7 +4102,7 @@ class Item_hex_hybrid: public Item_hex_constant
{
public:
Item_hex_hybrid(THD *thd): Item_hex_constant(thd) {}
- Item_hex_hybrid(THD *thd, const char *str, uint str_length):
+ Item_hex_hybrid(THD *thd, const char *str, size_t str_length):
Item_hex_constant(thd, str, str_length) {}
uint decimal_precision() const;
double val_real()
@@ -3934,8 +4134,8 @@ public:
return &type_handler_longlong;
}
void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_hex_hybrid>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_hex_hybrid>(thd, this); }
};
@@ -3952,7 +4152,7 @@ class Item_hex_string: public Item_hex_constant
{
public:
Item_hex_string(THD *thd): Item_hex_constant(thd) {}
- Item_hex_string(THD *thd, const char *str, uint str_length):
+ Item_hex_string(THD *thd, const char *str, size_t str_length):
Item_hex_constant(thd, str, str_length) {}
longlong val_int()
{
@@ -3975,15 +4175,15 @@ public:
collation.collation);
}
void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_hex_string>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_hex_string>(thd, this); }
};
class Item_bin_string: public Item_hex_hybrid
{
public:
- Item_bin_string(THD *thd, const char *str,uint str_length);
+ Item_bin_string(THD *thd, const char *str, size_t str_length);
};
@@ -3996,13 +4196,14 @@ public:
Constructor for Item_date_literal.
@param ltime DATE value.
*/
- Item_temporal_literal(THD *thd, MYSQL_TIME *ltime): Item_basic_constant(thd)
+ Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime)
+ :Item_basic_constant(thd)
{
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
decimals= 0;
cached_time= *ltime;
}
- Item_temporal_literal(THD *thd, MYSQL_TIME *ltime, uint dec_arg):
+ Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime, uint dec_arg):
Item_basic_constant(thd)
{
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
@@ -4038,7 +4239,7 @@ public:
class Item_date_literal: public Item_temporal_literal
{
public:
- Item_date_literal(THD *thd, MYSQL_TIME *ltime)
+ Item_date_literal(THD *thd, const MYSQL_TIME *ltime)
:Item_temporal_literal(thd, ltime)
{
max_length= MAX_DATE_WIDTH;
@@ -4056,8 +4257,8 @@ public:
void print(String *str, enum_query_type query_type);
Item *clone_item(THD *thd);
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_date_literal>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_date_literal>(thd, this); }
};
@@ -4067,7 +4268,7 @@ public:
class Item_time_literal: public Item_temporal_literal
{
public:
- Item_time_literal(THD *thd, MYSQL_TIME *ltime, uint dec_arg):
+ Item_time_literal(THD *thd, const MYSQL_TIME *ltime, uint dec_arg):
Item_temporal_literal(thd, ltime, dec_arg)
{
max_length= MIN_TIME_WIDTH + (decimals ? decimals + 1 : 0);
@@ -4077,8 +4278,8 @@ public:
void print(String *str, enum_query_type query_type);
Item *clone_item(THD *thd);
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_time_literal>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_time_literal>(thd, this); }
};
@@ -4088,7 +4289,7 @@ public:
class Item_datetime_literal: public Item_temporal_literal
{
public:
- Item_datetime_literal(THD *thd, MYSQL_TIME *ltime, uint dec_arg):
+ Item_datetime_literal(THD *thd, const MYSQL_TIME *ltime, uint dec_arg):
Item_temporal_literal(thd, ltime, dec_arg)
{
max_length= MAX_DATETIME_WIDTH + (decimals ? decimals + 1 : 0);
@@ -4100,8 +4301,8 @@ public:
void print(String *str, enum_query_type query_type);
Item *clone_item(THD *thd);
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_datetime_literal>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_datetime_literal>(thd, this); }
};
@@ -4134,7 +4335,7 @@ class Item_date_literal_for_invalid_dates: public Item_date_literal
in sql_mode=TRADITIONAL.
*/
public:
- Item_date_literal_for_invalid_dates(THD *thd, MYSQL_TIME *ltime)
+ Item_date_literal_for_invalid_dates(THD *thd, const MYSQL_TIME *ltime)
:Item_date_literal(thd, ltime) { }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
@@ -4152,7 +4353,7 @@ class Item_datetime_literal_for_invalid_dates: public Item_datetime_literal
{
public:
Item_datetime_literal_for_invalid_dates(THD *thd,
- MYSQL_TIME *ltime, uint dec_arg)
+ const MYSQL_TIME *ltime, uint dec_arg)
:Item_datetime_literal(thd, ltime, dec_arg) { }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
@@ -4229,7 +4430,8 @@ public:
*/
class Item_func_or_sum: public Item_result_field,
public Item_args,
- public Used_tables_and_const_cache
+ public Used_tables_and_const_cache,
+ public With_subquery_cache
{
protected:
bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
@@ -4312,6 +4514,7 @@ public:
Used_tables_and_const_cache(item) { }
Item_func_or_sum(THD *thd, List<Item> &list):
Item_result_field(thd), Item_args(thd, list) { }
+ bool with_subquery() const { DBUG_ASSERT(fixed); return m_with_subquery; }
bool walk(Item_processor processor, bool walk_subquery, void *arg)
{
if (walk_args(processor, walk_subquery, arg))
@@ -4338,9 +4541,38 @@ public:
virtual void fix_length_and_dec()= 0;
bool const_item() const { return const_item_cache; }
table_map used_tables() const { return used_tables_cache; }
- Item* build_clone(THD *thd, MEM_ROOT *mem_root);
+ Item* build_clone(THD *thd);
};
+class sp_head;
+class sp_name;
+struct st_sp_security_context;
+
+class Item_sp
+{
+public:
+ Name_resolution_context *context;
+ sp_name *m_name;
+ sp_head *m_sp;
+ TABLE *dummy_table;
+ uchar result_buf[64];
+ sp_rcontext *func_ctx;
+ MEM_ROOT sp_mem_root;
+ Query_arena *sp_query_arena;
+
+ /*
+ The result field of the stored function.
+ */
+ Field *sp_result_field;
+ Item_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name_arg);
+ const char *func_name(THD *thd) const;
+ void cleanup();
+ bool sp_check_access(THD *thd);
+ bool execute(THD *thd, bool *null_value, Item **args, uint arg_count);
+ bool execute_impl(THD *thd, Item **args, uint arg_count);
+ bool init_result_field(THD *thd, uint max_length, uint maybe_null,
+ bool *null_value, LEX_CSTRING *name);
+};
class Item_ref :public Item_ident
{
@@ -4521,17 +4753,17 @@ public:
return (*ref)->is_outer_field();
}
- Item* build_clone(THD *thd, MEM_ROOT *mem_root);
+ Item* build_clone(THD *thd);
/**
Checks if the item tree that ref points to contains a subquery.
*/
- virtual bool has_subquery() const
- {
- return (*ref)->has_subquery();
+ virtual bool with_subquery() const
+ {
+ return (*ref)->with_subquery();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_ref>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_ref>(thd, this); }
bool excl_dep_on_table(table_map tab_map)
{
table_map used= used_tables();
@@ -4557,6 +4789,12 @@ public:
return 0;
return cleanup_processor(arg);
}
+ virtual bool vers_trx_id() const
+ {
+ DBUG_ASSERT(ref);
+ DBUG_ASSERT(*ref);
+ return (*ref)->vers_trx_id();
+ }
};
@@ -4599,8 +4837,8 @@ public:
bool is_null();
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
virtual Ref_Type ref_type() { return DIRECT_REF; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_direct_ref>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_direct_ref>(thd, this); }
};
@@ -4645,7 +4883,8 @@ class Expression_cache_tracker;
The objects of this class can store its values in an expression cache.
*/
-class Item_cache_wrapper :public Item_result_field
+class Item_cache_wrapper :public Item_result_field,
+ public With_subquery_cache
{
private:
/* Pointer on the cached expression */
@@ -4672,6 +4911,7 @@ public:
enum Type type() const { return EXPR_CACHE_ITEM; }
enum Type real_type() const { return orig_item->type(); }
+ bool with_subquery() const { DBUG_ASSERT(fixed); return m_with_subquery; }
bool set_cache(THD *thd);
Expression_cache_tracker* init_tracker(MEM_ROOT *mem_root);
@@ -4763,9 +5003,9 @@ public:
{
return mark_unsupported_function("cache", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cache_wrapper>(thd, mem_root, this); }
- Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_wrapper>(thd, this); }
+ Item *build_clone(THD *thd) { return 0; }
};
@@ -4933,8 +5173,8 @@ public:
item_equal= NULL;
Item_direct_ref::cleanup();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_direct_view_ref>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_direct_view_ref>(thd, this); }
};
@@ -5027,8 +5267,8 @@ public:
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
virtual void print(String *str, enum_query_type query_type);
table_map used_tables() const;
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_ref_null_helper>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_ref_null_helper>(thd, this); }
};
/*
@@ -5071,6 +5311,7 @@ public:
#include "item_xmlfunc.h"
#include "item_jsonfunc.h"
#include "item_create.h"
+#include "item_vers.h"
#endif
/**
@@ -5188,10 +5429,12 @@ public:
my_decimal *val_decimal(my_decimal *);
double val_real();
longlong val_int();
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_string(ltime, fuzzydate); }
void copy();
int save_in_field(Field *field, bool no_conversions);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_copy_string>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_copy_string>(thd, this); }
};
@@ -5213,9 +5456,11 @@ public:
{
return null_value ? 0 : cached_value;
}
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_int(ltime, fuzzydate); }
virtual void copy();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_copy_int>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_copy_int>(thd, this); }
};
@@ -5232,8 +5477,8 @@ public:
{
return null_value ? 0.0 : (double) (ulonglong) cached_value;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_copy_uint>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_copy_uint>(thd, this); }
};
@@ -5255,13 +5500,17 @@ public:
{
return (longlong) rint(val_real());
}
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return get_date_from_real(ltime, fuzzydate);
+ }
void copy()
{
cached_value= item->val_real();
null_value= item->null_value;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_copy_float>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_copy_float>(thd, this); }
};
@@ -5280,9 +5529,13 @@ public:
}
double val_real();
longlong val_int();
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return get_date_from_decimal(ltime, fuzzydate);
+ }
void copy();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_copy_decimal>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_copy_decimal>(thd, this); }
};
@@ -5716,6 +5969,7 @@ public:
}
virtual void store(Item *item);
+ virtual Item *get_item() { return example; }
virtual bool cache_value()= 0;
bool basic_const_item() const
{ return MY_TEST(example && example->basic_const_item()); }
@@ -5773,11 +6027,22 @@ public:
longlong val_int();
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_int(ltime, fuzzydate); }
bool cache_value();
int save_in_field(Field *field, bool no_conversions);
Item *convert_to_basic_const_item(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cache_int>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_int>(thd, this); }
+};
+
+
+class Item_cache_year: public Item_cache_int
+{
+public:
+ Item_cache_year(THD *thd): Item_cache_int(thd, &type_handler_year) { }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_year(ltime, fuzzydate); }
};
@@ -5812,8 +6077,8 @@ public:
Item_cache_time(THD *thd)
:Item_cache_temporal(thd, &type_handler_time2) { }
bool cache_value();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cache_time>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_time>(thd, this); }
};
@@ -5822,8 +6087,8 @@ class Item_cache_datetime: public Item_cache_temporal
public:
Item_cache_datetime(THD *thd)
:Item_cache_temporal(thd, &type_handler_datetime2) { }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cache_datetime>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_datetime>(thd, this); }
};
@@ -5832,8 +6097,8 @@ class Item_cache_date: public Item_cache_temporal
public:
Item_cache_date(THD *thd)
:Item_cache_temporal(thd, &type_handler_newdate) { }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cache_date>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_date>(thd, this); }
};
@@ -5848,10 +6113,12 @@ public:
longlong val_int();
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_real(ltime, fuzzydate); }
bool cache_value();
Item *convert_to_basic_const_item(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cache_real>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_real>(thd, this); }
};
@@ -5866,10 +6133,12 @@ public:
longlong val_int();
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_decimal(ltime, fuzzydate); }
bool cache_value();
Item *convert_to_basic_const_item(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cache_decimal>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_decimal>(thd, this); }
};
@@ -5892,12 +6161,14 @@ public:
longlong val_int();
String* val_str(String *);
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_string(ltime, fuzzydate); }
CHARSET_INFO *charset() const { return value->charset(); };
int save_in_field(Field *field, bool no_conversions);
bool cache_value();
Item *convert_to_basic_const_item(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cache_str>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_str>(thd, this); }
};
@@ -5921,8 +6192,8 @@ public:
*/
return Item::safe_charset_converter(thd, tocs);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cache_str_for_nullif>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_str_for_nullif>(thd, this); }
};
@@ -5972,6 +6243,11 @@ public:
illegal_method_call((const char*)"val_decimal");
return 0;
};
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ illegal_method_call((const char*)"val_decimal");
+ return true;
+ }
uint cols() const { return item_count; }
Item *element_index(uint i) { return values[i]; }
@@ -5992,8 +6268,8 @@ public:
}
bool cache_value();
virtual void set_null();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cache_row>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_row>(thd, this); }
};
@@ -6010,37 +6286,59 @@ class Item_type_holder: public Item,
{
protected:
TYPELIB *enum_set_typelib;
+private:
+ void init_flags(Item *item)
+ {
+ if (item->real_type() == Item::FIELD_ITEM)
+ {
+ Item_field *item_field= (Item_field *)item->real_item();
+ m_flags|= (item_field->field->flags &
+ (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG));
+ // TODO: additional field flag?
+ m_vers_trx_id= item_field->field->vers_trx_id();
+ }
+ }
public:
Item_type_holder(THD *thd, Item *item)
:Item(thd, item),
Type_handler_hybrid_field_type(item->real_type_handler()),
- enum_set_typelib(0)
+ enum_set_typelib(0),
+ m_flags(0),
+ m_vers_trx_id(false)
{
DBUG_ASSERT(item->fixed);
maybe_null= item->maybe_null;
+ init_flags(item);
}
Item_type_holder(THD *thd,
- const LEX_CSTRING *name_arg,
+ Item *item,
const Type_handler *handler,
const Type_all_attributes *attr,
bool maybe_null_arg)
:Item(thd),
Type_handler_hybrid_field_type(handler),
Type_geometry_attributes(handler, attr),
- enum_set_typelib(attr->get_typelib())
+ enum_set_typelib(attr->get_typelib()),
+ m_flags(0),
+ m_vers_trx_id(false)
{
- name= *name_arg;
+ name= item->name;
Type_std_attributes::set(*attr);
maybe_null= maybe_null_arg;
+ init_flags(item);
}
const Type_handler *type_handler() const
{
- const Type_handler *handler= Type_handler_hybrid_field_type::type_handler();
+ const Type_handler *handler= m_vers_trx_id ?
+ &type_handler_vers_trx_id :
+ Type_handler_hybrid_field_type::type_handler();
return handler->type_handler_for_item_field();
}
const Type_handler *real_type_handler() const
{
+ if (m_vers_trx_id)
+ return &type_handler_vers_trx_id;
return Type_handler_hybrid_field_type::type_handler();
}
@@ -6050,6 +6348,7 @@ public:
longlong val_int();
my_decimal *val_decimal(my_decimal *);
String *val_str(String*);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
Field *create_tmp_field(bool group, TABLE *table)
{
return Item_type_holder::real_type_handler()->
@@ -6064,7 +6363,20 @@ public:
{
Type_geometry_attributes::set_geometry_type(type);
}
- Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item* get_copy(THD *thd) { return 0; }
+
+private:
+ uint m_flags;
+ bool m_vers_trx_id;
+public:
+ uint32 field_flags() const
+ {
+ return m_flags;
+ }
+ virtual bool vers_trx_id() const
+ {
+ return m_vers_trx_id;
+ }
};
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index fe73bfc3622..6e19cfcdf80 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -127,9 +127,12 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const char *funcname,
many cases.
*/
set_handler(items[0]->type_handler()->type_handler_for_comparison());
+ m_vers_trx_id= items[0]->vers_trx_id();
for (uint i= 1 ; i < nitems ; i++)
{
unsigned_count+= items[i]->unsigned_flag;
+ if (!m_vers_trx_id)
+ m_vers_trx_id= items[i]->vers_trx_id();
if (aggregate_for_comparison(items[i]->type_handler()->
type_handler_for_comparison()))
{
@@ -421,7 +424,7 @@ void Item_func::convert_const_compared_to_int_field(THD *thd)
args[field= 1]->real_item()->type() == FIELD_ITEM)
{
Item_field *field_item= (Item_field*) (args[field]->real_item());
- if ((field_item->field_type() == MYSQL_TYPE_LONGLONG ||
+ if (((field_item->field_type() == MYSQL_TYPE_LONGLONG && !field_item->vers_trx_id()) ||
field_item->field_type() == MYSQL_TYPE_YEAR))
convert_const_to_int(thd, field_item, &args[!field]);
}
@@ -1223,6 +1226,7 @@ bool Item_in_optimizer::is_top_level_item()
void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent,
Item **ref, bool merge)
{
+ DBUG_ASSERT(fixed);
/* This will re-calculate attributes of our Item_in_subselect: */
Item_bool_func::fix_after_pullout(new_parent, ref, merge);
@@ -1246,6 +1250,33 @@ bool Item_in_optimizer::eval_not_null_tables(void *opt_arg)
}
+void Item_in_optimizer::print(String *str, enum_query_type query_type)
+{
+ restore_first_argument();
+ Item_func::print(str, query_type);
+}
+
+
+/**
+ "Restore" first argument before fix_fields() call (after it is harmless).
+
+ @Note: Main pointer to left part of IN/ALL/ANY subselect is subselect's
+ lest_expr (see Item_in_optimizer::fix_left) so changes made during
+ fix_fields will be rolled back there which can make
+ Item_in_optimizer::args[0] unusable on second execution before fix_left()
+ call. This call fix the pointer.
+*/
+
+void Item_in_optimizer::restore_first_argument()
+{
+ if (args[1]->type() == Item::SUBSELECT_ITEM &&
+ ((Item_subselect *)args[1])->is_in_predicate())
+ {
+ args[0]= ((Item_in_subselect *)args[1])->left_expr;
+ }
+}
+
+
bool Item_in_optimizer::fix_left(THD *thd)
{
DBUG_ENTER("Item_in_optimizer::fix_left");
@@ -1365,7 +1396,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
}
if (args[1]->maybe_null)
maybe_null=1;
- with_subselect= 1;
+ m_with_subquery= true;
with_sum_func= with_sum_func || args[1]->with_sum_func;
with_field= with_field || args[1]->with_field;
used_tables_and_const_cache_join(args[1]);
@@ -1419,6 +1450,7 @@ bool Item_in_optimizer::invisible_mode()
Item *Item_in_optimizer::expr_cache_insert_transformer(THD *thd, uchar *unused)
{
DBUG_ENTER("Item_in_optimizer::expr_cache_insert_transformer");
+ DBUG_ASSERT(fixed);
if (invisible_mode())
DBUG_RETURN(this);
@@ -1443,6 +1475,7 @@ Item *Item_in_optimizer::expr_cache_insert_transformer(THD *thd, uchar *unused)
void Item_in_optimizer::get_cache_parameters(List<Item> &parameters)
{
+ DBUG_ASSERT(fixed);
/* Add left expression to the list of the parameters of the subquery */
if (!invisible_mode())
{
@@ -1680,6 +1713,7 @@ Item *Item_in_optimizer::transform(THD *thd, Item_transformer transformer,
{
Item *new_item;
+ DBUG_ASSERT(fixed);
DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
DBUG_ASSERT(arg_count == 2);
@@ -1731,6 +1765,7 @@ Item *Item_in_optimizer::transform(THD *thd, Item_transformer transformer,
bool Item_in_optimizer::is_expensive_processor(void *arg)
{
+ DBUG_ASSERT(fixed);
return args[0]->is_expensive_processor(arg) ||
args[1]->is_expensive_processor(arg);
}
@@ -1738,6 +1773,7 @@ bool Item_in_optimizer::is_expensive_processor(void *arg)
bool Item_in_optimizer::is_expensive()
{
+ DBUG_ASSERT(fixed);
return args[0]->is_expensive() || args[1]->is_expensive();
}
@@ -1839,6 +1875,19 @@ bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const
}
+bool Item_func_interval::fix_fields(THD *thd, Item **ref)
+{
+ if (Item_long_func::fix_fields(thd, ref))
+ return true;
+ for (uint i= 0 ; i < row->cols(); i++)
+ {
+ if (row->element_index(i)->check_cols(1))
+ return true;
+ }
+ return false;
+}
+
+
void Item_func_interval::fix_length_and_dec()
{
uint rows= row->cols();
@@ -2322,9 +2371,25 @@ Item_func_ifnull::str_op(String *str)
bool Item_func_ifnull::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
DBUG_ASSERT(fixed == 1);
- if (!args[0]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
- return (null_value= false);
- return (null_value= args[1]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES));
+ for (uint i= 0; i < 2; i++)
+ {
+ Datetime dt(current_thd, args[i], fuzzydate & ~TIME_FUZZY_DATES);
+ if (!(dt.copy_to_mysql_time(ltime, mysql_timestamp_type())))
+ return (null_value= false);
+ }
+ return (null_value= true);
+}
+
+
+bool Item_func_ifnull::time_op(MYSQL_TIME *ltime)
+{
+ DBUG_ASSERT(fixed == 1);
+ for (uint i= 0; i < 2; i++)
+ {
+ if (!Time(args[i]).copy_to_mysql_time(ltime))
+ return (null_value= false);
+ }
+ return (null_value= true);
}
@@ -2667,7 +2732,9 @@ void Item_func_nullif::print(String *str, enum_query_type query_type)
Therefore, after equal field propagation args[0] and args[2] can point
to different items.
*/
- if ((query_type & QT_ITEM_ORIGINAL_FUNC_NULLIF) || args[0] == args[2])
+ if ((query_type & QT_ITEM_ORIGINAL_FUNC_NULLIF) ||
+ (arg_count == 2) ||
+ (args[0] == args[2]))
{
/*
If QT_ITEM_ORIGINAL_FUNC_NULLIF is requested,
@@ -2685,10 +2752,14 @@ void Item_func_nullif::print(String *str, enum_query_type query_type)
- one "a" for comparison
- another "a" for the returned value!
*/
- DBUG_ASSERT(args[0] == args[2] || current_thd->lex->context_analysis_only);
+ DBUG_ASSERT(arg_count == 2 ||
+ args[0] == args[2] || current_thd->lex->context_analysis_only);
str->append(func_name());
str->append('(');
- args[2]->print(str, query_type);
+ if (arg_count == 2)
+ args[0]->print(str, query_type);
+ else
+ args[2]->print(str, query_type);
str->append(',');
args[1]->print(str, query_type);
str->append(')');
@@ -2798,7 +2869,19 @@ Item_func_nullif::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
DBUG_ASSERT(fixed == 1);
if (!compare())
return (null_value= true);
- return (null_value= args[2]->get_date(ltime, fuzzydate));
+ Datetime dt(current_thd, args[2], fuzzydate);
+ return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
+}
+
+
+bool
+Item_func_nullif::time_op(MYSQL_TIME *ltime)
+{
+ DBUG_ASSERT(fixed == 1);
+ if (!compare())
+ return (null_value= true);
+ return (null_value= Time(args[2]).copy_to_mysql_time(ltime));
+
}
@@ -2939,7 +3022,18 @@ bool Item_func_case::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
Item *item= find_item();
if (!item)
return (null_value= true);
- return (null_value= item->get_date_with_conversion(ltime, fuzzydate));
+ Datetime dt(current_thd, item, fuzzydate);
+ return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
+}
+
+
+bool Item_func_case::time_op(MYSQL_TIME *ltime)
+{
+ DBUG_ASSERT(fixed == 1);
+ Item *item= find_item();
+ if (!item)
+ return (null_value= true);
+ return (null_value= Time(item).copy_to_mysql_time(ltime));
}
@@ -3349,7 +3443,20 @@ bool Item_func_coalesce::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
DBUG_ASSERT(fixed == 1);
for (uint i= 0; i < arg_count; i++)
{
- if (!args[i]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
+ Datetime dt(current_thd, args[i], fuzzydate & ~TIME_FUZZY_DATES);
+ if (!dt.copy_to_mysql_time(ltime, mysql_timestamp_type()))
+ return (null_value= false);
+ }
+ return (null_value= true);
+}
+
+
+bool Item_func_coalesce::time_op(MYSQL_TIME *ltime)
+{
+ DBUG_ASSERT(fixed == 1);
+ for (uint i= 0; i < arg_count; i++)
+ {
+ if (!Time(args[i]).copy_to_mysql_time(ltime))
return (null_value= false);
}
return (null_value= true);
@@ -4623,7 +4730,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
with_sum_func|= item->with_sum_func;
with_field|= item->with_field;
- with_subselect|= item->has_subquery();
+ m_with_subquery|= item->with_subquery();
with_window_func|= item->with_window_func;
maybe_null|= item->maybe_null;
}
@@ -4937,20 +5044,20 @@ void Item_cond::neg_arguments(THD *thd)
0 if an error occured
*/
-Item *Item_cond::build_clone(THD *thd, MEM_ROOT *mem_root)
+Item *Item_cond::build_clone(THD *thd)
{
List_iterator_fast<Item> li(list);
Item *item;
- Item_cond *copy= (Item_cond *) get_copy(thd, mem_root);
+ Item_cond *copy= (Item_cond *) get_copy(thd);
if (!copy)
return 0;
copy->list.empty();
while ((item= li++))
{
- Item *arg_clone= item->build_clone(thd, mem_root);
+ Item *arg_clone= item->build_clone(thd);
if (!arg_clone)
return 0;
- if (copy->list.push_back(arg_clone, mem_root))
+ if (copy->list.push_back(arg_clone, thd->mem_root))
return 0;
}
return copy;
@@ -5290,7 +5397,6 @@ bool fix_escape_item(THD *thd, Item *escape_item, String *tmp_str,
return FALSE;
}
-
bool Item_func_like::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
@@ -5485,7 +5591,7 @@ void Regexp_processor_pcre::pcre_exec_warn(int rc) const
switch (rc)
{
case PCRE_ERROR_NULL:
- errmsg= "pcre_exec: null arguement passed";
+ errmsg= "pcre_exec: null argument passed";
break;
case PCRE_ERROR_BADOPTION:
errmsg= "pcre_exec: bad option";
@@ -5588,9 +5694,9 @@ int Regexp_processor_pcre::pcre_exec_with_warn(const pcre *code,
}
-bool Regexp_processor_pcre::exec(const char *str, int length, int offset)
+bool Regexp_processor_pcre::exec(const char *str, size_t length, size_t offset)
{
- m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, &m_pcre_extra, str, length, offset, 0,
+ m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, &m_pcre_extra, str, (int)length, (int)offset, 0,
m_SubStrVec, array_elements(m_SubStrVec));
return false;
}
@@ -6627,7 +6733,7 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
used_tables_cache|= item->used_tables();
tmp_table_map= item->not_null_tables();
not_null_tables_cache|= tmp_table_map;
- DBUG_ASSERT(!item->with_sum_func && !item->with_subselect);
+ DBUG_ASSERT(!item->with_sum_func && !item->with_subquery());
if (item->maybe_null)
maybe_null= 1;
if (!item->get_item_equal())
@@ -6960,20 +7066,20 @@ longlong Item_func_dyncol_exists::val_int()
null_value= 1;
return 1;
}
- if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci))
+ if (my_charset_same(nm->charset(), DYNCOL_UTF))
{
buf.str= (char *) nm->ptr();
buf.length= nm->length();
}
else
{
- uint strlen= nm->length() * my_charset_utf8_general_ci.mbmaxlen + 1;
+ uint strlen= nm->length() * DYNCOL_UTF->mbmaxlen + 1;
uint dummy_errors;
buf.str= (char *) current_thd->alloc(strlen);
if (buf.str)
{
buf.length=
- copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci,
+ copy_and_convert(buf.str, strlen, DYNCOL_UTF,
nm->ptr(), nm->length(), nm->charset(),
&dummy_errors);
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 7bab02db263..4caf7e4622d 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -268,8 +268,8 @@ public:
Item_func_istrue(THD *thd, Item *a): Item_func_truth(thd, a, true, true) {}
~Item_func_istrue() {}
virtual const char* func_name() const { return "istrue"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_istrue>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_istrue>(thd, this); }
};
@@ -284,8 +284,8 @@ public:
Item_func_truth(thd, a, true, false) {}
~Item_func_isnottrue() {}
virtual const char* func_name() const { return "isnottrue"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_isnottrue>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_isnottrue>(thd, this); }
};
@@ -299,8 +299,8 @@ public:
Item_func_isfalse(THD *thd, Item *a): Item_func_truth(thd, a, false, true) {}
~Item_func_isfalse() {}
virtual const char* func_name() const { return "isfalse"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_isfalse>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_isfalse>(thd, this); }
};
@@ -315,8 +315,8 @@ public:
Item_func_truth(thd, a, false, false) {}
~Item_func_isnotfalse() {}
virtual const char* func_name() const { return "isnotfalse"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_isnotfalse>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_isnotfalse>(thd, this); }
};
@@ -356,7 +356,7 @@ public:
Item_in_optimizer(THD *thd, Item *a, Item *b):
Item_bool_func(thd, a, b), cache(0), expr_cache(0),
save_cache(0), result_for_null_param(UNKNOWN)
- { with_subselect= true; }
+ { m_with_subquery= true; }
bool fix_fields(THD *, Item **);
bool fix_left(THD *thd);
table_map not_null_tables() const { return 0; }
@@ -378,8 +378,10 @@ public:
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool invisible_mode();
void reset_cache() { cache= NULL; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_in_optimizer>(thd, mem_root, this); }
+ virtual void print(String *str, enum_query_type query_type);
+ void restore_first_argument();
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_in_optimizer>(thd, this); }
};
@@ -539,10 +541,10 @@ public:
return add_key_fields_optimize_op(join, key_fields, and_level,
usable_tables, sargables, false);
}
- Item *build_clone(THD *thd, MEM_ROOT *mem_root)
+ Item *build_clone(THD *thd)
{
Item_bool_rowready_func2 *clone=
- (Item_bool_rowready_func2 *) Item_func::build_clone(thd, mem_root);
+ (Item_bool_rowready_func2 *) Item_func::build_clone(thd);
if (clone)
{
clone->cmp.comparators= 0;
@@ -573,8 +575,8 @@ public:
Item_args::propagate_equal_fields(thd, Context_boolean(), cond);
return this;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_xor>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_xor>(thd, this); }
};
class Item_func_not :public Item_bool_func
@@ -592,8 +594,8 @@ public:
Item *neg_transformer(THD *thd);
bool fix_fields(THD *, Item **);
virtual void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_not>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_not>(thd, this); }
};
class Item_maxmin_subselect;
@@ -641,8 +643,8 @@ public:
void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
uint *and_level, table_map usable_tables,
SARGABLE_PARAM **sargables);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_trig_cond>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_trig_cond>(thd, this); }
};
class Item_func_not_all :public Item_func_not
@@ -679,8 +681,8 @@ public:
longlong val_int();
const char *func_name() const { return "<nop>"; }
Item *neg_transformer(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_nop_all>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_nop_all>(thd, this); }
};
@@ -720,8 +722,8 @@ public:
uint in_equality_no;
virtual uint exists2in_reserved_items() { return 1; };
friend class Arg_comparator;
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_eq>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_eq>(thd, this); }
};
class Item_func_equal :public Item_bool_rowready_func2
@@ -744,8 +746,8 @@ public:
return add_key_fields_optimize_op(join, key_fields, and_level,
usable_tables, sargables, true);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_equal>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_equal>(thd, this); }
};
@@ -760,8 +762,8 @@ public:
cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return ">="; }
Item *negated_item(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_ge>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_ge>(thd, this); }
};
@@ -776,8 +778,8 @@ public:
cond_result eq_cmp_result() const { return COND_FALSE; }
const char *func_name() const { return ">"; }
Item *negated_item(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_gt>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_gt>(thd, this); }
};
@@ -792,8 +794,8 @@ public:
cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return "<="; }
Item *negated_item(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_le>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_le>(thd, this); }
};
@@ -808,8 +810,8 @@ public:
cond_result eq_cmp_result() const { return COND_FALSE; }
const char *func_name() const { return "<"; }
Item *negated_item(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_lt>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_lt>(thd, this); }
};
@@ -833,8 +835,8 @@ public:
Item *negated_item(THD *thd);
void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
table_map usable_tables, SARGABLE_PARAM **sargables);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_ne>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_ne>(thd, this); }
};
@@ -923,8 +925,8 @@ public:
cond);
return this;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_between>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_between>(thd, this); }
longlong val_int_cmp_string();
longlong val_int_cmp_temporal();
@@ -951,8 +953,8 @@ public:
agg_arg_charsets_for_comparison(cmp_collation, args, 2);
fix_char_length(2); // returns "1" or "0" or "-1"
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_strcmp>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_strcmp>(thd, this); }
};
@@ -976,6 +978,7 @@ public:
Item_func_interval(THD *thd, Item_row *a):
Item_long_func(thd, a), row(a), intervals(0)
{ }
+ bool fix_fields(THD *, Item **);
longlong val_int();
void fix_length_and_dec();
const char *func_name() const { return "interval"; }
@@ -985,8 +988,8 @@ public:
str->append(func_name());
print_args(str, 0, query_type);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_interval>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_interval>(thd, this); }
};
@@ -1002,6 +1005,7 @@ public:
String *str_op(String *);
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool time_op(MYSQL_TIME *ltime);
void fix_length_and_dec()
{
if (!aggregate_for_result(func_name(), args, arg_count, true))
@@ -1009,8 +1013,8 @@ public:
}
const char *func_name() const { return "coalesce"; }
table_map not_null_tables() const { return 0; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_coalesce>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_coalesce>(thd, this); }
};
@@ -1074,6 +1078,7 @@ public:
String *str_op(String *str);
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool time_op(MYSQL_TIME *ltime);
void fix_length_and_dec()
{
Item_func_case_abbreviation2::fix_length_and_dec2(args);
@@ -1082,8 +1087,8 @@ public:
const char *func_name() const { return "ifnull"; }
table_map not_null_tables() const { return 0; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_ifnull>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_ifnull>(thd, this); }
};
@@ -1107,7 +1112,12 @@ public:
bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
- return get_date_with_conversion_from_item(find_item(), ltime, fuzzydate);
+ Datetime dt(current_thd, find_item(), fuzzydate);
+ return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
+ }
+ bool time_op(MYSQL_TIME *ltime)
+ {
+ return (null_value= Time(find_item()).copy_to_mysql_time(ltime));
}
longlong int_op()
{
@@ -1145,8 +1155,8 @@ public:
const char *func_name() const { return "if"; }
bool eval_not_null_tables(void *opt_arg);
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_if>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_if>(thd, this); }
private:
void cache_type_info(Item *source);
};
@@ -1166,8 +1176,8 @@ public:
{
fix_length_and_dec2_eliminate_null(args + 1);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_nvl2>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_nvl2>(thd, this); }
};
@@ -1219,6 +1229,7 @@ public:
arg_count= 2; // See the comment to the constructor
}
bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool time_op(MYSQL_TIME *ltime);
double real_op();
longlong int_op();
String *str_op(String *str);
@@ -1253,8 +1264,8 @@ public:
cond, &args[2]);
return this;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_nullif>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_nullif>(thd, this); }
Item *derived_field_transformer_for_having(THD *thd, uchar *arg)
{ reset_first_arg_if_needed(); return this; }
Item *derived_field_transformer_for_where(THD *thd, uchar *arg)
@@ -1318,7 +1329,7 @@ public:
{
return MY_TEST(compare(collation, base + pos1 * size, base + pos2 * size));
}
- virtual Item_result result_type()= 0;
+ virtual const Type_handler *type_handler() const= 0;
};
class in_string :public in_vector
@@ -1349,7 +1360,7 @@ public:
Item_string_for_in_vector *to= (Item_string_for_in_vector*) item;
to->set_value(str);
}
- Item_result result_type() { return STRING_RESULT; }
+ const Type_handler *type_handler() const { return &type_handler_varchar; }
};
class in_longlong :public in_vector
@@ -1376,7 +1387,7 @@ public:
((Item_int*) item)->unsigned_flag= (bool)
((packed_longlong*) base)[pos].unsigned_flag;
}
- Item_result result_type() { return INT_RESULT; }
+ const Type_handler *type_handler() const { return &type_handler_longlong; }
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
};
@@ -1402,9 +1413,11 @@ public:
void value_to_item(uint pos, Item *item)
{
packed_longlong *val= reinterpret_cast<packed_longlong*>(base)+pos;
- Item_datetime *dt= reinterpret_cast<Item_datetime*>(item);
- dt->set(val->val);
+ Item_datetime *dt= static_cast<Item_datetime*>(item);
+ dt->set(val->val, type_handler()->mysql_timestamp_type());
}
+ uchar *get_value(Item *item)
+ { return get_value_internal(item, type_handler()->field_type()); }
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
};
@@ -1416,8 +1429,7 @@ public:
:in_temporal(thd, elements)
{}
void set(uint pos,Item *item);
- uchar *get_value(Item *item)
- { return get_value_internal(item, MYSQL_TYPE_DATETIME); }
+ const Type_handler *type_handler() const { return &type_handler_datetime2; }
};
@@ -1428,8 +1440,7 @@ public:
:in_temporal(thd, elements)
{}
void set(uint pos,Item *item);
- uchar *get_value(Item *item)
- { return get_value_internal(item, MYSQL_TYPE_TIME); }
+ const Type_handler *type_handler() const { return &type_handler_time2; }
};
@@ -1445,7 +1456,7 @@ public:
{
((Item_float*)item)->value= ((double*) base)[pos];
}
- Item_result result_type() { return REAL_RESULT; }
+ const Type_handler *type_handler() const { return &type_handler_double; }
};
@@ -1463,7 +1474,7 @@ public:
Item_decimal *item_dec= (Item_decimal*)item;
item_dec->set_decimal_value(dec);
}
- Item_result result_type() { return DECIMAL_RESULT; }
+ const Type_handler *type_handler() const { return &type_handler_newdecimal; }
};
@@ -2108,15 +2119,16 @@ public:
String *str_op(String *);
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool time_op(MYSQL_TIME *ltime);
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; }
- Item *build_clone(THD *thd, MEM_ROOT *mem_root)
+ Item *build_clone(THD *thd)
{
- Item_func_case *clone= (Item_func_case *) Item_func::build_clone(thd, mem_root);
+ Item_func_case *clone= (Item_func_case *) Item_func::build_clone(thd);
if (clone)
clone->arg_buffer= 0;
return clone;
@@ -2151,8 +2163,8 @@ public:
return this;
}
Item *find_item();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_case_searched>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_case_searched>(thd, this); }
};
@@ -2197,17 +2209,17 @@ public:
void fix_length_and_dec();
Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond);
Item *find_item();
- Item *build_clone(THD *thd, MEM_ROOT *mem_root)
+ Item *build_clone(THD *thd)
{
Item_func_case_simple *clone= (Item_func_case_simple *)
- Item_func_case::build_clone(thd, mem_root);
+ Item_func_case::build_clone(thd);
uint ncases= when_count();
if (clone && clone->Predicant_to_list_comparator::init_clone(thd, ncases))
return NULL;
return clone;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_case_simple>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_case_simple>(thd, this); }
};
@@ -2222,8 +2234,8 @@ public:
{ Item_func::print(str, query_type); }
void fix_length_and_dec();
Item *find_item();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_decode_oracle>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_decode_oracle>(thd, this); }
};
@@ -2384,11 +2396,11 @@ public:
bool eval_not_null_tables(void *opt_arg);
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool count_sargable_conds(void *arg);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_in>(thd, mem_root, this); }
- Item *build_clone(THD *thd, MEM_ROOT *mem_root)
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_in>(thd, this); }
+ Item *build_clone(THD *thd)
{
- Item_func_in *clone= (Item_func_in *) Item_func::build_clone(thd, mem_root);
+ Item_func_in *clone= (Item_func_in *) Item_func::build_clone(thd);
if (clone)
{
clone->array= 0;
@@ -2436,7 +2448,7 @@ public:
void set(uint pos,Item *item);
uchar *get_value(Item *item);
friend class Item_func_in;
- Item_result result_type() { return ROW_RESULT; }
+ const Type_handler *type_handler() const { return &type_handler_row; }
cmp_item *get_cmp_item() { return &tmp; }
};
@@ -2485,9 +2497,9 @@ public:
bool arg_is_datetime_notnull_field()
{
Item **args= arguments();
- if (args[0]->type() == Item::FIELD_ITEM)
+ if (args[0]->real_item()->type() == Item::FIELD_ITEM)
{
- Field *field=((Item_field*) args[0])->field;
+ Field *field=((Item_field*) args[0]->real_item())->field;
if (((field->type() == MYSQL_TYPE_DATE) ||
(field->type() == MYSQL_TYPE_DATETIME)) &&
@@ -2516,8 +2528,8 @@ public:
bool top_level);
table_map not_null_tables() const { return 0; }
Item *neg_transformer(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_isnull>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_isnull>(thd, this); }
};
/* Functions used by HAVING for rewriting IN subquery */
@@ -2564,8 +2576,8 @@ public:
Item *neg_transformer(THD *thd);
void print(String *str, enum_query_type query_type);
void top_level_item() { abort_on_null=1; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_isnotnull>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_isnotnull>(thd, this); }
};
@@ -2706,8 +2718,8 @@ public:
bool find_selective_predicates_list_processor(void *arg);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_like>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_like>(thd, this); }
};
@@ -2765,7 +2777,7 @@ public:
{
return !m_is_const && compile(item, false);
}
- bool exec(const char *str, int length, int offset);
+ bool exec(const char *str, size_t length, size_t offset);
bool exec(String *str, int offset, uint n_result_offsets_to_convert);
bool exec(Item *item, int offset, uint n_result_offsets_to_convert);
bool match() const { return m_pcre_exec_rc < 0 ? 0 : 1; }
@@ -2818,11 +2830,11 @@ public:
void fix_length_and_dec();
const char *func_name() const { return "regexp"; }
enum precedence precedence() const { return CMP_PRECEDENCE; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_regex>(thd, mem_root, this); }
- Item *build_clone(THD *thd, MEM_ROOT *mem_root)
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_regex>(thd, this); }
+ Item *build_clone(THD *thd)
{
- Item_func_regex *clone= (Item_func_regex*) Item_bool_func::build_clone(thd, mem_root);
+ Item_func_regex *clone= (Item_func_regex*) Item_bool_func::build_clone(thd);
if (clone)
clone->re.reset();
return clone;
@@ -2867,8 +2879,8 @@ public:
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
const char *func_name() const { return "regexp_instr"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_regexp_instr>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_regexp_instr>(thd, this); }
};
@@ -2945,7 +2957,7 @@ public:
Item *compile(THD *thd, Item_analyzer analyzer, uchar **arg_p,
Item_transformer transformer, uchar *arg_t);
bool eval_not_null_tables(void *opt_arg);
- Item *build_clone(THD *thd, MEM_ROOT *mem_root);
+ Item *build_clone(THD *thd);
};
template <template<class> class LI, class T> class Item_equal_iterator;
@@ -3119,7 +3131,7 @@ public:
void set_context_field(Item_field *ctx_field) { context_field= ctx_field; }
void set_link_equal_fields(bool flag) { link_equal_fields= flag; }
- Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item* get_copy(THD *thd) { return 0; }
/*
This does not comply with the specification of the virtual method,
but Item_equal items are processed distinguishly anyway
@@ -3273,8 +3285,8 @@ public:
void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
table_map usable_tables, SARGABLE_PARAM **sargables);
SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cond_and>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cond_and>(thd, this); }
};
inline bool is_cond_and(Item *item)
@@ -3300,8 +3312,8 @@ public:
table_map not_null_tables() const { return and_tables_cache; }
Item *copy_andor_structure(THD *thd);
Item *neg_transformer(THD *thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_cond_or>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cond_or>(thd, this); }
};
class Item_func_dyncol_check :public Item_bool_func
@@ -3311,8 +3323,8 @@ public:
longlong val_int();
const char *func_name() const { return "column_check"; }
bool need_parentheses_in_default() { return false; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_dyncol_check>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_dyncol_check>(thd, this); }
};
class Item_func_dyncol_exists :public Item_bool_func
@@ -3323,8 +3335,8 @@ public:
longlong val_int();
const char *func_name() const { return "column_exists"; }
bool need_parentheses_in_default() { return false; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_dyncol_exists>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_dyncol_exists>(thd, this); }
};
@@ -3352,8 +3364,8 @@ public:
:Item_func_cursor_bool_attr(thd, name, offset) { }
const char *func_name() const { return "%ISOPEN"; }
longlong val_int();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_cursor_isopen>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_cursor_isopen>(thd, this); }
};
@@ -3364,8 +3376,8 @@ public:
:Item_func_cursor_bool_attr(thd, name, offset) { maybe_null= true; }
const char *func_name() const { return "%FOUND"; }
longlong val_int();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_cursor_found>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_cursor_found>(thd, this); }
};
@@ -3376,8 +3388,8 @@ public:
:Item_func_cursor_bool_attr(thd, name, offset) { maybe_null= true; }
const char *func_name() const { return "%NOTFOUND"; }
longlong val_int();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_cursor_notfound>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_cursor_notfound>(thd, this); }
};
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 5d6d9742c7a..548ce3bac94 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -43,38 +43,6 @@
*/
/**
- Adapter for native functions with a variable number of arguments.
- The main use of this class is to discard the following calls:
- <code>foo(expr1 AS name1, expr2 AS name2, ...)</code>
- which are syntactically correct (the syntax can refer to a UDF),
- but semantically invalid for native functions.
-*/
-
-class Create_native_func : public Create_func
-{
-public:
- virtual Item *create_func(THD *thd, LEX_CSTRING *name,
- List<Item> *item_list);
-
- /**
- Builder method, with no arguments.
- @param thd The current thread
- @param name The native function name
- @param item_list The function parameters, none of which are named
- @return An item representing the function call
- */
- virtual Item *create_native(THD *thd, LEX_CSTRING *name,
- List<Item> *item_list) = 0;
-
-protected:
- /** Constructor. */
- Create_native_func() {}
- /** Destructor. */
- virtual ~Create_native_func() {}
-};
-
-
-/**
Adapter for functions that takes exactly zero arguments.
*/
@@ -3285,7 +3253,7 @@ Create_qfunc::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list)
{
LEX_CSTRING db;
- if (! thd->db && ! thd->lex->sphead)
+ if (! thd->db.str && ! thd->lex->sphead)
{
/*
The proper error message should be in the lines of:
@@ -3303,7 +3271,7 @@ Create_qfunc::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list)
return NULL;
}
- if (thd->lex->copy_db_to(&db.str, &db.length))
+ if (thd->lex->copy_db_to(&db))
return NULL;
return create_with_db(thd, &db, name, false, item_list);
@@ -3316,7 +3284,7 @@ Create_udf_func Create_udf_func::s_singleton;
Item*
Create_udf_func::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list)
{
- udf_func *udf= find_udf(name->str, (uint) name->length);
+ udf_func *udf= find_udf(name->str, name->length);
DBUG_ASSERT(udf);
return create(thd, udf, item_list);
}
@@ -6827,12 +6795,6 @@ Create_func_year_week::create_native(THD *thd, LEX_CSTRING *name,
}
-struct Native_func_registry
-{
- LEX_CSTRING name;
- Create_func *builder;
-};
-
#define BUILDER(F) & F::s_singleton
#ifdef HAVE_SPATIAL
@@ -6854,347 +6816,347 @@ struct Native_func_registry
static Native_func_registry func_array[] =
{
- { { C_STRING_WITH_LEN("ABS") }, BUILDER(Create_func_abs)},
- { { C_STRING_WITH_LEN("ACOS") }, BUILDER(Create_func_acos)},
- { { C_STRING_WITH_LEN("ADDTIME") }, BUILDER(Create_func_addtime)},
- { { C_STRING_WITH_LEN("AES_DECRYPT") }, BUILDER(Create_func_aes_decrypt)},
- { { C_STRING_WITH_LEN("AES_ENCRYPT") }, BUILDER(Create_func_aes_encrypt)},
- { { C_STRING_WITH_LEN("AREA") }, GEOM_BUILDER(Create_func_area)},
- { { C_STRING_WITH_LEN("ASBINARY") }, GEOM_BUILDER(Create_func_as_wkb)},
- { { C_STRING_WITH_LEN("ASIN") }, BUILDER(Create_func_asin)},
- { { C_STRING_WITH_LEN("ASTEXT") }, GEOM_BUILDER(Create_func_as_wkt)},
- { { C_STRING_WITH_LEN("ASWKB") }, GEOM_BUILDER(Create_func_as_wkb)},
- { { C_STRING_WITH_LEN("ASWKT") }, GEOM_BUILDER(Create_func_as_wkt)},
- { { C_STRING_WITH_LEN("ATAN") }, BUILDER(Create_func_atan)},
- { { C_STRING_WITH_LEN("ATAN2") }, BUILDER(Create_func_atan)},
- { { C_STRING_WITH_LEN("BENCHMARK") }, BUILDER(Create_func_benchmark)},
- { { C_STRING_WITH_LEN("BIN") }, BUILDER(Create_func_bin)},
- { { C_STRING_WITH_LEN("BINLOG_GTID_POS") }, BUILDER(Create_func_binlog_gtid_pos)},
- { { C_STRING_WITH_LEN("BIT_COUNT") }, BUILDER(Create_func_bit_count)},
- { { C_STRING_WITH_LEN("BIT_LENGTH") }, BUILDER(Create_func_bit_length)},
- { { C_STRING_WITH_LEN("BOUNDARY") }, GEOM_BUILDER(Create_func_boundary)},
- { { C_STRING_WITH_LEN("BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
- { { C_STRING_WITH_LEN("CEIL") }, BUILDER(Create_func_ceiling)},
- { { C_STRING_WITH_LEN("CEILING") }, BUILDER(Create_func_ceiling)},
- { { C_STRING_WITH_LEN("CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
- { { C_STRING_WITH_LEN("CHARACTER_LENGTH") }, BUILDER(Create_func_char_length)},
- { { C_STRING_WITH_LEN("CHAR_LENGTH") }, BUILDER(Create_func_char_length)},
- { { C_STRING_WITH_LEN("CHR") }, BUILDER(Create_func_chr)},
- { { C_STRING_WITH_LEN("COERCIBILITY") }, BUILDER(Create_func_coercibility)},
- { { C_STRING_WITH_LEN("COLUMN_CHECK") }, BUILDER(Create_func_dyncol_check)},
- { { C_STRING_WITH_LEN("COLUMN_EXISTS") }, BUILDER(Create_func_dyncol_exists)},
- { { C_STRING_WITH_LEN("COLUMN_LIST") }, BUILDER(Create_func_dyncol_list)},
- { { C_STRING_WITH_LEN("COLUMN_JSON") }, BUILDER(Create_func_dyncol_json)},
- { { C_STRING_WITH_LEN("COMPRESS") }, BUILDER(Create_func_compress)},
- { { C_STRING_WITH_LEN("CONCAT") }, BUILDER(Create_func_concat)},
- { { C_STRING_WITH_LEN("CONCAT_OPERATOR_ORACLE") }, BUILDER(Create_func_concat_operator_oracle)},
- { { C_STRING_WITH_LEN("CONCAT_WS") }, BUILDER(Create_func_concat_ws)},
- { { C_STRING_WITH_LEN("CONNECTION_ID") }, BUILDER(Create_func_connection_id)},
- { { C_STRING_WITH_LEN("CONV") }, BUILDER(Create_func_conv)},
- { { C_STRING_WITH_LEN("CONVERT_TZ") }, BUILDER(Create_func_convert_tz)},
- { { C_STRING_WITH_LEN("CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
- { { C_STRING_WITH_LEN("COS") }, BUILDER(Create_func_cos)},
- { { C_STRING_WITH_LEN("COT") }, BUILDER(Create_func_cot)},
- { { C_STRING_WITH_LEN("CRC32") }, BUILDER(Create_func_crc32)},
- { { C_STRING_WITH_LEN("CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
- { { C_STRING_WITH_LEN("DATEDIFF") }, BUILDER(Create_func_datediff)},
- { { C_STRING_WITH_LEN("DAYNAME") }, BUILDER(Create_func_dayname)},
- { { C_STRING_WITH_LEN("DAYOFMONTH") }, BUILDER(Create_func_dayofmonth)},
- { { C_STRING_WITH_LEN("DAYOFWEEK") }, BUILDER(Create_func_dayofweek)},
- { { C_STRING_WITH_LEN("DAYOFYEAR") }, BUILDER(Create_func_dayofyear)},
- { { C_STRING_WITH_LEN("DEGREES") }, BUILDER(Create_func_degrees)},
- { { C_STRING_WITH_LEN("DECODE_HISTOGRAM") }, BUILDER(Create_func_decode_histogram)},
- { { C_STRING_WITH_LEN("DECODE_ORACLE") }, BUILDER(Create_func_decode_oracle)},
- { { C_STRING_WITH_LEN("DES_DECRYPT") }, BUILDER(Create_func_des_decrypt)},
- { { C_STRING_WITH_LEN("DES_ENCRYPT") }, BUILDER(Create_func_des_encrypt)},
- { { C_STRING_WITH_LEN("DIMENSION") }, GEOM_BUILDER(Create_func_dimension)},
- { { C_STRING_WITH_LEN("DISJOINT") }, GEOM_BUILDER(Create_func_mbr_disjoint)},
- { { C_STRING_WITH_LEN("ELT") }, BUILDER(Create_func_elt)},
- { { C_STRING_WITH_LEN("ENCODE") }, BUILDER(Create_func_encode)},
- { { C_STRING_WITH_LEN("ENCRYPT") }, BUILDER(Create_func_encrypt)},
- { { C_STRING_WITH_LEN("ENDPOINT") }, GEOM_BUILDER(Create_func_endpoint)},
- { { C_STRING_WITH_LEN("ENVELOPE") }, GEOM_BUILDER(Create_func_envelope)},
- { { C_STRING_WITH_LEN("EQUALS") }, GEOM_BUILDER(Create_func_equals)},
- { { C_STRING_WITH_LEN("EXP") }, BUILDER(Create_func_exp)},
- { { C_STRING_WITH_LEN("EXPORT_SET") }, BUILDER(Create_func_export_set)},
- { { C_STRING_WITH_LEN("EXTERIORRING") }, GEOM_BUILDER(Create_func_exteriorring)},
- { { C_STRING_WITH_LEN("EXTRACTVALUE") }, BUILDER(Create_func_xml_extractvalue)},
- { { C_STRING_WITH_LEN("FIELD") }, BUILDER(Create_func_field)},
- { { C_STRING_WITH_LEN("FIND_IN_SET") }, BUILDER(Create_func_find_in_set)},
- { { C_STRING_WITH_LEN("FLOOR") }, BUILDER(Create_func_floor)},
- { { C_STRING_WITH_LEN("FORMAT") }, BUILDER(Create_func_format)},
- { { C_STRING_WITH_LEN("FOUND_ROWS") }, BUILDER(Create_func_found_rows)},
- { { C_STRING_WITH_LEN("FROM_BASE64") }, BUILDER(Create_func_from_base64)},
- { { C_STRING_WITH_LEN("FROM_DAYS") }, BUILDER(Create_func_from_days)},
- { { C_STRING_WITH_LEN("FROM_UNIXTIME") }, BUILDER(Create_func_from_unixtime)},
- { { C_STRING_WITH_LEN("GEOMCOLLFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("GEOMCOLLFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("GEOMETRYCOLLECTIONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("GEOMETRYCOLLECTIONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("GEOMETRYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("GEOMETRYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("GEOMETRYN") }, GEOM_BUILDER(Create_func_geometryn)},
- { { C_STRING_WITH_LEN("GEOMETRYTYPE") }, GEOM_BUILDER(Create_func_geometry_type)},
- { { C_STRING_WITH_LEN("GEOMFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("GEOMFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("GET_LOCK") }, BUILDER(Create_func_get_lock)},
- { { C_STRING_WITH_LEN("GLENGTH") }, GEOM_BUILDER(Create_func_glength)},
- { { C_STRING_WITH_LEN("GREATEST") }, BUILDER(Create_func_greatest)},
- { { C_STRING_WITH_LEN("HEX") }, BUILDER(Create_func_hex)},
- { { C_STRING_WITH_LEN("IFNULL") }, BUILDER(Create_func_ifnull)},
- { { C_STRING_WITH_LEN("INET_ATON") }, BUILDER(Create_func_inet_aton)},
- { { C_STRING_WITH_LEN("INET_NTOA") }, BUILDER(Create_func_inet_ntoa)},
- { { C_STRING_WITH_LEN("INET6_ATON") }, BUILDER(Create_func_inet6_aton)},
- { { C_STRING_WITH_LEN("INET6_NTOA") }, BUILDER(Create_func_inet6_ntoa)},
- { { C_STRING_WITH_LEN("IS_IPV4") }, BUILDER(Create_func_is_ipv4)},
- { { C_STRING_WITH_LEN("IS_IPV6") }, BUILDER(Create_func_is_ipv6)},
- { { C_STRING_WITH_LEN("IS_IPV4_COMPAT") }, BUILDER(Create_func_is_ipv4_compat)},
- { { C_STRING_WITH_LEN("IS_IPV4_MAPPED") }, BUILDER(Create_func_is_ipv4_mapped)},
- { { C_STRING_WITH_LEN("INSTR") }, BUILDER(Create_func_instr)},
- { { C_STRING_WITH_LEN("INTERIORRINGN") }, GEOM_BUILDER(Create_func_interiorringn)},
- { { C_STRING_WITH_LEN("INTERSECTS") }, GEOM_BUILDER(Create_func_mbr_intersects)},
- { { C_STRING_WITH_LEN("ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
- { { C_STRING_WITH_LEN("ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
- { { C_STRING_WITH_LEN("ISNULL") }, BUILDER(Create_func_isnull)},
- { { C_STRING_WITH_LEN("ISRING") }, GEOM_BUILDER(Create_func_isring)},
- { { C_STRING_WITH_LEN("ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)},
- { { C_STRING_WITH_LEN("IS_FREE_LOCK") }, BUILDER(Create_func_is_free_lock)},
- { { C_STRING_WITH_LEN("IS_USED_LOCK") }, BUILDER(Create_func_is_used_lock)},
- { { C_STRING_WITH_LEN("JSON_ARRAY") }, BUILDER(Create_func_json_array)},
- { { C_STRING_WITH_LEN("JSON_ARRAY_APPEND") }, BUILDER(Create_func_json_array_append)},
- { { C_STRING_WITH_LEN("JSON_ARRAY_INSERT") }, BUILDER(Create_func_json_array_insert)},
- { { C_STRING_WITH_LEN("JSON_COMPACT") }, BUILDER(Create_func_json_compact)},
- { { C_STRING_WITH_LEN("JSON_CONTAINS") }, BUILDER(Create_func_json_contains)},
- { { C_STRING_WITH_LEN("JSON_CONTAINS_PATH") }, BUILDER(Create_func_json_contains_path)},
- { { C_STRING_WITH_LEN("JSON_DEPTH") }, BUILDER(Create_func_json_depth)},
- { { C_STRING_WITH_LEN("JSON_DETAILED") }, BUILDER(Create_func_json_detailed)},
- { { C_STRING_WITH_LEN("JSON_EXISTS") }, BUILDER(Create_func_json_exists)},
- { { C_STRING_WITH_LEN("JSON_EXTRACT") }, BUILDER(Create_func_json_extract)},
- { { C_STRING_WITH_LEN("JSON_INSERT") }, BUILDER(Create_func_json_insert)},
- { { C_STRING_WITH_LEN("JSON_KEYS") }, BUILDER(Create_func_json_keys)},
- { { C_STRING_WITH_LEN("JSON_LENGTH") }, BUILDER(Create_func_json_length)},
- { { C_STRING_WITH_LEN("JSON_LOOSE") }, BUILDER(Create_func_json_loose)},
- { { C_STRING_WITH_LEN("JSON_MERGE") }, BUILDER(Create_func_json_merge)},
- { { C_STRING_WITH_LEN("JSON_QUERY") }, BUILDER(Create_func_json_query)},
- { { C_STRING_WITH_LEN("JSON_QUOTE") }, BUILDER(Create_func_json_quote)},
- { { C_STRING_WITH_LEN("JSON_OBJECT") }, BUILDER(Create_func_json_object)},
- { { C_STRING_WITH_LEN("JSON_REMOVE") }, BUILDER(Create_func_json_remove)},
- { { C_STRING_WITH_LEN("JSON_REPLACE") }, BUILDER(Create_func_json_replace)},
- { { C_STRING_WITH_LEN("JSON_SET") }, BUILDER(Create_func_json_set)},
- { { C_STRING_WITH_LEN("JSON_SEARCH") }, BUILDER(Create_func_json_search)},
- { { C_STRING_WITH_LEN("JSON_TYPE") }, BUILDER(Create_func_json_type)},
- { { C_STRING_WITH_LEN("JSON_UNQUOTE") }, BUILDER(Create_func_json_unquote)},
- { { C_STRING_WITH_LEN("JSON_VALID") }, BUILDER(Create_func_json_valid)},
- { { C_STRING_WITH_LEN("JSON_VALUE") }, BUILDER(Create_func_json_value)},
- { { C_STRING_WITH_LEN("LAST_DAY") }, BUILDER(Create_func_last_day)},
- { { C_STRING_WITH_LEN("LAST_INSERT_ID") }, BUILDER(Create_func_last_insert_id)},
- { { C_STRING_WITH_LEN("LCASE") }, BUILDER(Create_func_lcase)},
- { { C_STRING_WITH_LEN("LEAST") }, BUILDER(Create_func_least)},
- { { C_STRING_WITH_LEN("LENGTH") }, BUILDER(Create_func_length)},
- { { C_STRING_WITH_LEN("LENGTHB") }, BUILDER(Create_func_octet_length)},
+ { { STRING_WITH_LEN("ABS") }, BUILDER(Create_func_abs)},
+ { { STRING_WITH_LEN("ACOS") }, BUILDER(Create_func_acos)},
+ { { STRING_WITH_LEN("ADDTIME") }, BUILDER(Create_func_addtime)},
+ { { STRING_WITH_LEN("AES_DECRYPT") }, BUILDER(Create_func_aes_decrypt)},
+ { { STRING_WITH_LEN("AES_ENCRYPT") }, BUILDER(Create_func_aes_encrypt)},
+ { { STRING_WITH_LEN("AREA") }, GEOM_BUILDER(Create_func_area)},
+ { { STRING_WITH_LEN("ASBINARY") }, GEOM_BUILDER(Create_func_as_wkb)},
+ { { STRING_WITH_LEN("ASIN") }, BUILDER(Create_func_asin)},
+ { { STRING_WITH_LEN("ASTEXT") }, GEOM_BUILDER(Create_func_as_wkt)},
+ { { STRING_WITH_LEN("ASWKB") }, GEOM_BUILDER(Create_func_as_wkb)},
+ { { STRING_WITH_LEN("ASWKT") }, GEOM_BUILDER(Create_func_as_wkt)},
+ { { STRING_WITH_LEN("ATAN") }, BUILDER(Create_func_atan)},
+ { { STRING_WITH_LEN("ATAN2") }, BUILDER(Create_func_atan)},
+ { { STRING_WITH_LEN("BENCHMARK") }, BUILDER(Create_func_benchmark)},
+ { { STRING_WITH_LEN("BIN") }, BUILDER(Create_func_bin)},
+ { { STRING_WITH_LEN("BINLOG_GTID_POS") }, BUILDER(Create_func_binlog_gtid_pos)},
+ { { STRING_WITH_LEN("BIT_COUNT") }, BUILDER(Create_func_bit_count)},
+ { { STRING_WITH_LEN("BIT_LENGTH") }, BUILDER(Create_func_bit_length)},
+ { { STRING_WITH_LEN("BOUNDARY") }, GEOM_BUILDER(Create_func_boundary)},
+ { { STRING_WITH_LEN("BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
+ { { STRING_WITH_LEN("CEIL") }, BUILDER(Create_func_ceiling)},
+ { { STRING_WITH_LEN("CEILING") }, BUILDER(Create_func_ceiling)},
+ { { STRING_WITH_LEN("CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
+ { { STRING_WITH_LEN("CHARACTER_LENGTH") }, BUILDER(Create_func_char_length)},
+ { { STRING_WITH_LEN("CHAR_LENGTH") }, BUILDER(Create_func_char_length)},
+ { { STRING_WITH_LEN("CHR") }, BUILDER(Create_func_chr)},
+ { { STRING_WITH_LEN("COERCIBILITY") }, BUILDER(Create_func_coercibility)},
+ { { STRING_WITH_LEN("COLUMN_CHECK") }, BUILDER(Create_func_dyncol_check)},
+ { { STRING_WITH_LEN("COLUMN_EXISTS") }, BUILDER(Create_func_dyncol_exists)},
+ { { STRING_WITH_LEN("COLUMN_LIST") }, BUILDER(Create_func_dyncol_list)},
+ { { STRING_WITH_LEN("COLUMN_JSON") }, BUILDER(Create_func_dyncol_json)},
+ { { STRING_WITH_LEN("COMPRESS") }, BUILDER(Create_func_compress)},
+ { { STRING_WITH_LEN("CONCAT") }, BUILDER(Create_func_concat)},
+ { { STRING_WITH_LEN("CONCAT_OPERATOR_ORACLE") }, BUILDER(Create_func_concat_operator_oracle)},
+ { { STRING_WITH_LEN("CONCAT_WS") }, BUILDER(Create_func_concat_ws)},
+ { { STRING_WITH_LEN("CONNECTION_ID") }, BUILDER(Create_func_connection_id)},
+ { { STRING_WITH_LEN("CONV") }, BUILDER(Create_func_conv)},
+ { { STRING_WITH_LEN("CONVERT_TZ") }, BUILDER(Create_func_convert_tz)},
+ { { STRING_WITH_LEN("CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
+ { { STRING_WITH_LEN("COS") }, BUILDER(Create_func_cos)},
+ { { STRING_WITH_LEN("COT") }, BUILDER(Create_func_cot)},
+ { { STRING_WITH_LEN("CRC32") }, BUILDER(Create_func_crc32)},
+ { { STRING_WITH_LEN("CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
+ { { STRING_WITH_LEN("DATEDIFF") }, BUILDER(Create_func_datediff)},
+ { { STRING_WITH_LEN("DAYNAME") }, BUILDER(Create_func_dayname)},
+ { { STRING_WITH_LEN("DAYOFMONTH") }, BUILDER(Create_func_dayofmonth)},
+ { { STRING_WITH_LEN("DAYOFWEEK") }, BUILDER(Create_func_dayofweek)},
+ { { STRING_WITH_LEN("DAYOFYEAR") }, BUILDER(Create_func_dayofyear)},
+ { { STRING_WITH_LEN("DEGREES") }, BUILDER(Create_func_degrees)},
+ { { STRING_WITH_LEN("DECODE_HISTOGRAM") }, BUILDER(Create_func_decode_histogram)},
+ { { STRING_WITH_LEN("DECODE_ORACLE") }, BUILDER(Create_func_decode_oracle)},
+ { { STRING_WITH_LEN("DES_DECRYPT") }, BUILDER(Create_func_des_decrypt)},
+ { { STRING_WITH_LEN("DES_ENCRYPT") }, BUILDER(Create_func_des_encrypt)},
+ { { STRING_WITH_LEN("DIMENSION") }, GEOM_BUILDER(Create_func_dimension)},
+ { { STRING_WITH_LEN("DISJOINT") }, GEOM_BUILDER(Create_func_mbr_disjoint)},
+ { { STRING_WITH_LEN("ELT") }, BUILDER(Create_func_elt)},
+ { { STRING_WITH_LEN("ENCODE") }, BUILDER(Create_func_encode)},
+ { { STRING_WITH_LEN("ENCRYPT") }, BUILDER(Create_func_encrypt)},
+ { { STRING_WITH_LEN("ENDPOINT") }, GEOM_BUILDER(Create_func_endpoint)},
+ { { STRING_WITH_LEN("ENVELOPE") }, GEOM_BUILDER(Create_func_envelope)},
+ { { STRING_WITH_LEN("EQUALS") }, GEOM_BUILDER(Create_func_equals)},
+ { { STRING_WITH_LEN("EXP") }, BUILDER(Create_func_exp)},
+ { { STRING_WITH_LEN("EXPORT_SET") }, BUILDER(Create_func_export_set)},
+ { { STRING_WITH_LEN("EXTERIORRING") }, GEOM_BUILDER(Create_func_exteriorring)},
+ { { STRING_WITH_LEN("EXTRACTVALUE") }, BUILDER(Create_func_xml_extractvalue)},
+ { { STRING_WITH_LEN("FIELD") }, BUILDER(Create_func_field)},
+ { { STRING_WITH_LEN("FIND_IN_SET") }, BUILDER(Create_func_find_in_set)},
+ { { STRING_WITH_LEN("FLOOR") }, BUILDER(Create_func_floor)},
+ { { STRING_WITH_LEN("FORMAT") }, BUILDER(Create_func_format)},
+ { { STRING_WITH_LEN("FOUND_ROWS") }, BUILDER(Create_func_found_rows)},
+ { { STRING_WITH_LEN("FROM_BASE64") }, BUILDER(Create_func_from_base64)},
+ { { STRING_WITH_LEN("FROM_DAYS") }, BUILDER(Create_func_from_days)},
+ { { STRING_WITH_LEN("FROM_UNIXTIME") }, BUILDER(Create_func_from_unixtime)},
+ { { STRING_WITH_LEN("GEOMCOLLFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("GEOMCOLLFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("GEOMETRYCOLLECTIONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("GEOMETRYCOLLECTIONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("GEOMETRYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("GEOMETRYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("GEOMETRYN") }, GEOM_BUILDER(Create_func_geometryn)},
+ { { STRING_WITH_LEN("GEOMETRYTYPE") }, GEOM_BUILDER(Create_func_geometry_type)},
+ { { STRING_WITH_LEN("GEOMFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("GEOMFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("GET_LOCK") }, BUILDER(Create_func_get_lock)},
+ { { STRING_WITH_LEN("GLENGTH") }, GEOM_BUILDER(Create_func_glength)},
+ { { STRING_WITH_LEN("GREATEST") }, BUILDER(Create_func_greatest)},
+ { { STRING_WITH_LEN("HEX") }, BUILDER(Create_func_hex)},
+ { { STRING_WITH_LEN("IFNULL") }, BUILDER(Create_func_ifnull)},
+ { { STRING_WITH_LEN("INET_ATON") }, BUILDER(Create_func_inet_aton)},
+ { { STRING_WITH_LEN("INET_NTOA") }, BUILDER(Create_func_inet_ntoa)},
+ { { STRING_WITH_LEN("INET6_ATON") }, BUILDER(Create_func_inet6_aton)},
+ { { STRING_WITH_LEN("INET6_NTOA") }, BUILDER(Create_func_inet6_ntoa)},
+ { { STRING_WITH_LEN("IS_IPV4") }, BUILDER(Create_func_is_ipv4)},
+ { { STRING_WITH_LEN("IS_IPV6") }, BUILDER(Create_func_is_ipv6)},
+ { { STRING_WITH_LEN("IS_IPV4_COMPAT") }, BUILDER(Create_func_is_ipv4_compat)},
+ { { STRING_WITH_LEN("IS_IPV4_MAPPED") }, BUILDER(Create_func_is_ipv4_mapped)},
+ { { STRING_WITH_LEN("INSTR") }, BUILDER(Create_func_instr)},
+ { { STRING_WITH_LEN("INTERIORRINGN") }, GEOM_BUILDER(Create_func_interiorringn)},
+ { { STRING_WITH_LEN("INTERSECTS") }, GEOM_BUILDER(Create_func_mbr_intersects)},
+ { { STRING_WITH_LEN("ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
+ { { STRING_WITH_LEN("ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
+ { { STRING_WITH_LEN("ISNULL") }, BUILDER(Create_func_isnull)},
+ { { STRING_WITH_LEN("ISRING") }, GEOM_BUILDER(Create_func_isring)},
+ { { STRING_WITH_LEN("ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)},
+ { { STRING_WITH_LEN("IS_FREE_LOCK") }, BUILDER(Create_func_is_free_lock)},
+ { { STRING_WITH_LEN("IS_USED_LOCK") }, BUILDER(Create_func_is_used_lock)},
+ { { STRING_WITH_LEN("JSON_ARRAY") }, BUILDER(Create_func_json_array)},
+ { { STRING_WITH_LEN("JSON_ARRAY_APPEND") }, BUILDER(Create_func_json_array_append)},
+ { { STRING_WITH_LEN("JSON_ARRAY_INSERT") }, BUILDER(Create_func_json_array_insert)},
+ { { STRING_WITH_LEN("JSON_COMPACT") }, BUILDER(Create_func_json_compact)},
+ { { STRING_WITH_LEN("JSON_CONTAINS") }, BUILDER(Create_func_json_contains)},
+ { { STRING_WITH_LEN("JSON_CONTAINS_PATH") }, BUILDER(Create_func_json_contains_path)},
+ { { STRING_WITH_LEN("JSON_DEPTH") }, BUILDER(Create_func_json_depth)},
+ { { STRING_WITH_LEN("JSON_DETAILED") }, BUILDER(Create_func_json_detailed)},
+ { { STRING_WITH_LEN("JSON_EXISTS") }, BUILDER(Create_func_json_exists)},
+ { { STRING_WITH_LEN("JSON_EXTRACT") }, BUILDER(Create_func_json_extract)},
+ { { STRING_WITH_LEN("JSON_INSERT") }, BUILDER(Create_func_json_insert)},
+ { { STRING_WITH_LEN("JSON_KEYS") }, BUILDER(Create_func_json_keys)},
+ { { STRING_WITH_LEN("JSON_LENGTH") }, BUILDER(Create_func_json_length)},
+ { { STRING_WITH_LEN("JSON_LOOSE") }, BUILDER(Create_func_json_loose)},
+ { { STRING_WITH_LEN("JSON_MERGE") }, BUILDER(Create_func_json_merge)},
+ { { STRING_WITH_LEN("JSON_QUERY") }, BUILDER(Create_func_json_query)},
+ { { STRING_WITH_LEN("JSON_QUOTE") }, BUILDER(Create_func_json_quote)},
+ { { STRING_WITH_LEN("JSON_OBJECT") }, BUILDER(Create_func_json_object)},
+ { { STRING_WITH_LEN("JSON_REMOVE") }, BUILDER(Create_func_json_remove)},
+ { { STRING_WITH_LEN("JSON_REPLACE") }, BUILDER(Create_func_json_replace)},
+ { { STRING_WITH_LEN("JSON_SET") }, BUILDER(Create_func_json_set)},
+ { { STRING_WITH_LEN("JSON_SEARCH") }, BUILDER(Create_func_json_search)},
+ { { STRING_WITH_LEN("JSON_TYPE") }, BUILDER(Create_func_json_type)},
+ { { STRING_WITH_LEN("JSON_UNQUOTE") }, BUILDER(Create_func_json_unquote)},
+ { { STRING_WITH_LEN("JSON_VALID") }, BUILDER(Create_func_json_valid)},
+ { { STRING_WITH_LEN("JSON_VALUE") }, BUILDER(Create_func_json_value)},
+ { { STRING_WITH_LEN("LAST_DAY") }, BUILDER(Create_func_last_day)},
+ { { STRING_WITH_LEN("LAST_INSERT_ID") }, BUILDER(Create_func_last_insert_id)},
+ { { STRING_WITH_LEN("LCASE") }, BUILDER(Create_func_lcase)},
+ { { STRING_WITH_LEN("LEAST") }, BUILDER(Create_func_least)},
+ { { STRING_WITH_LEN("LENGTH") }, BUILDER(Create_func_length)},
+ { { STRING_WITH_LEN("LENGTHB") }, BUILDER(Create_func_octet_length)},
#ifndef DBUG_OFF
- { { C_STRING_WITH_LEN("LIKE_RANGE_MIN") }, BUILDER(Create_func_like_range_min)},
- { { C_STRING_WITH_LEN("LIKE_RANGE_MAX") }, BUILDER(Create_func_like_range_max)},
+ { { STRING_WITH_LEN("LIKE_RANGE_MIN") }, BUILDER(Create_func_like_range_min)},
+ { { STRING_WITH_LEN("LIKE_RANGE_MAX") }, BUILDER(Create_func_like_range_max)},
#endif
- { { C_STRING_WITH_LEN("LINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("LINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("LINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("LN") }, BUILDER(Create_func_ln)},
- { { C_STRING_WITH_LEN("LOAD_FILE") }, BUILDER(Create_func_load_file)},
- { { C_STRING_WITH_LEN("LOCATE") }, BUILDER(Create_func_locate)},
- { { C_STRING_WITH_LEN("LOG") }, BUILDER(Create_func_log)},
- { { C_STRING_WITH_LEN("LOG10") }, BUILDER(Create_func_log10)},
- { { C_STRING_WITH_LEN("LOG2") }, BUILDER(Create_func_log2)},
- { { C_STRING_WITH_LEN("LOWER") }, BUILDER(Create_func_lcase)},
- { { C_STRING_WITH_LEN("LPAD") }, BUILDER(Create_func_lpad)},
- { { C_STRING_WITH_LEN("LTRIM") }, BUILDER(Create_func_ltrim)},
- { { C_STRING_WITH_LEN("MAKEDATE") }, BUILDER(Create_func_makedate)},
- { { C_STRING_WITH_LEN("MAKETIME") }, BUILDER(Create_func_maketime)},
- { { C_STRING_WITH_LEN("MAKE_SET") }, BUILDER(Create_func_make_set)},
- { { C_STRING_WITH_LEN("MASTER_GTID_WAIT") }, BUILDER(Create_func_master_gtid_wait)},
- { { C_STRING_WITH_LEN("MASTER_POS_WAIT") }, BUILDER(Create_func_master_pos_wait)},
- { { C_STRING_WITH_LEN("MBRCONTAINS") }, GEOM_BUILDER(Create_func_mbr_contains)},
- { { C_STRING_WITH_LEN("MBRDISJOINT") }, GEOM_BUILDER(Create_func_mbr_disjoint)},
- { { C_STRING_WITH_LEN("MBREQUAL") }, GEOM_BUILDER(Create_func_mbr_equals)},
- { { C_STRING_WITH_LEN("MBREQUALS") }, GEOM_BUILDER(Create_func_mbr_equals)},
- { { C_STRING_WITH_LEN("MBRINTERSECTS") }, GEOM_BUILDER(Create_func_mbr_intersects)},
- { { C_STRING_WITH_LEN("MBROVERLAPS") }, GEOM_BUILDER(Create_func_mbr_overlaps)},
- { { C_STRING_WITH_LEN("MBRTOUCHES") }, GEOM_BUILDER(Create_func_touches)},
- { { C_STRING_WITH_LEN("MBRWITHIN") }, GEOM_BUILDER(Create_func_mbr_within)},
- { { C_STRING_WITH_LEN("MD5") }, BUILDER(Create_func_md5)},
- { { C_STRING_WITH_LEN("MLINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("MLINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("MONTHNAME") }, BUILDER(Create_func_monthname)},
- { { C_STRING_WITH_LEN("MPOINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("MPOINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("MPOLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("MPOLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("MULTILINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("MULTILINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("MULTIPOINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("MULTIPOINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("MULTIPOLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("MULTIPOLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("NAME_CONST") }, BUILDER(Create_func_name_const)},
- { { C_STRING_WITH_LEN("NVL") }, BUILDER(Create_func_ifnull)},
- { { C_STRING_WITH_LEN("NVL2") }, BUILDER(Create_func_nvl2)},
- { { C_STRING_WITH_LEN("NULLIF") }, BUILDER(Create_func_nullif)},
- { { C_STRING_WITH_LEN("NUMGEOMETRIES") }, GEOM_BUILDER(Create_func_numgeometries)},
- { { C_STRING_WITH_LEN("NUMINTERIORRINGS") }, GEOM_BUILDER(Create_func_numinteriorring)},
- { { C_STRING_WITH_LEN("NUMPOINTS") }, GEOM_BUILDER(Create_func_numpoints)},
- { { C_STRING_WITH_LEN("OCT") }, BUILDER(Create_func_oct)},
- { { C_STRING_WITH_LEN("OCTET_LENGTH") }, BUILDER(Create_func_octet_length)},
- { { C_STRING_WITH_LEN("ORD") }, BUILDER(Create_func_ord)},
- { { C_STRING_WITH_LEN("OVERLAPS") }, GEOM_BUILDER(Create_func_mbr_overlaps)},
- { { C_STRING_WITH_LEN("PERIOD_ADD") }, BUILDER(Create_func_period_add)},
- { { C_STRING_WITH_LEN("PERIOD_DIFF") }, BUILDER(Create_func_period_diff)},
- { { C_STRING_WITH_LEN("PI") }, BUILDER(Create_func_pi)},
- { { C_STRING_WITH_LEN("POINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("POINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("POINTN") }, GEOM_BUILDER(Create_func_pointn)},
- { { C_STRING_WITH_LEN("POINTONSURFACE") }, GEOM_BUILDER(Create_func_pointonsurface)},
- { { C_STRING_WITH_LEN("POLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("POLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("POW") }, BUILDER(Create_func_pow)},
- { { C_STRING_WITH_LEN("POWER") }, BUILDER(Create_func_pow)},
- { { C_STRING_WITH_LEN("QUOTE") }, BUILDER(Create_func_quote)},
- { { C_STRING_WITH_LEN("REGEXP_INSTR") }, BUILDER(Create_func_regexp_instr)},
- { { C_STRING_WITH_LEN("REGEXP_REPLACE") }, BUILDER(Create_func_regexp_replace)},
- { { C_STRING_WITH_LEN("REGEXP_SUBSTR") }, BUILDER(Create_func_regexp_substr)},
- { { C_STRING_WITH_LEN("RADIANS") }, BUILDER(Create_func_radians)},
- { { C_STRING_WITH_LEN("RAND") }, BUILDER(Create_func_rand)},
- { { C_STRING_WITH_LEN("RELEASE_LOCK") }, BUILDER(Create_func_release_lock)},
- { { C_STRING_WITH_LEN("REPLACE_ORACLE") },
+ { { STRING_WITH_LEN("LINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("LINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("LINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("LN") }, BUILDER(Create_func_ln)},
+ { { STRING_WITH_LEN("LOAD_FILE") }, BUILDER(Create_func_load_file)},
+ { { STRING_WITH_LEN("LOCATE") }, BUILDER(Create_func_locate)},
+ { { STRING_WITH_LEN("LOG") }, BUILDER(Create_func_log)},
+ { { STRING_WITH_LEN("LOG10") }, BUILDER(Create_func_log10)},
+ { { STRING_WITH_LEN("LOG2") }, BUILDER(Create_func_log2)},
+ { { STRING_WITH_LEN("LOWER") }, BUILDER(Create_func_lcase)},
+ { { STRING_WITH_LEN("LPAD") }, BUILDER(Create_func_lpad)},
+ { { STRING_WITH_LEN("LTRIM") }, BUILDER(Create_func_ltrim)},
+ { { STRING_WITH_LEN("MAKEDATE") }, BUILDER(Create_func_makedate)},
+ { { STRING_WITH_LEN("MAKETIME") }, BUILDER(Create_func_maketime)},
+ { { STRING_WITH_LEN("MAKE_SET") }, BUILDER(Create_func_make_set)},
+ { { STRING_WITH_LEN("MASTER_GTID_WAIT") }, BUILDER(Create_func_master_gtid_wait)},
+ { { STRING_WITH_LEN("MASTER_POS_WAIT") }, BUILDER(Create_func_master_pos_wait)},
+ { { STRING_WITH_LEN("MBRCONTAINS") }, GEOM_BUILDER(Create_func_mbr_contains)},
+ { { STRING_WITH_LEN("MBRDISJOINT") }, GEOM_BUILDER(Create_func_mbr_disjoint)},
+ { { STRING_WITH_LEN("MBREQUAL") }, GEOM_BUILDER(Create_func_mbr_equals)},
+ { { STRING_WITH_LEN("MBREQUALS") }, GEOM_BUILDER(Create_func_mbr_equals)},
+ { { STRING_WITH_LEN("MBRINTERSECTS") }, GEOM_BUILDER(Create_func_mbr_intersects)},
+ { { STRING_WITH_LEN("MBROVERLAPS") }, GEOM_BUILDER(Create_func_mbr_overlaps)},
+ { { STRING_WITH_LEN("MBRTOUCHES") }, GEOM_BUILDER(Create_func_touches)},
+ { { STRING_WITH_LEN("MBRWITHIN") }, GEOM_BUILDER(Create_func_mbr_within)},
+ { { STRING_WITH_LEN("MD5") }, BUILDER(Create_func_md5)},
+ { { STRING_WITH_LEN("MLINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("MLINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("MONTHNAME") }, BUILDER(Create_func_monthname)},
+ { { STRING_WITH_LEN("MPOINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("MPOINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("MPOLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("MPOLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("MULTILINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("MULTILINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("MULTIPOINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("MULTIPOINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("MULTIPOLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("MULTIPOLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("NAME_CONST") }, BUILDER(Create_func_name_const)},
+ { { STRING_WITH_LEN("NVL") }, BUILDER(Create_func_ifnull)},
+ { { STRING_WITH_LEN("NVL2") }, BUILDER(Create_func_nvl2)},
+ { { STRING_WITH_LEN("NULLIF") }, BUILDER(Create_func_nullif)},
+ { { STRING_WITH_LEN("NUMGEOMETRIES") }, GEOM_BUILDER(Create_func_numgeometries)},
+ { { STRING_WITH_LEN("NUMINTERIORRINGS") }, GEOM_BUILDER(Create_func_numinteriorring)},
+ { { STRING_WITH_LEN("NUMPOINTS") }, GEOM_BUILDER(Create_func_numpoints)},
+ { { STRING_WITH_LEN("OCT") }, BUILDER(Create_func_oct)},
+ { { STRING_WITH_LEN("OCTET_LENGTH") }, BUILDER(Create_func_octet_length)},
+ { { STRING_WITH_LEN("ORD") }, BUILDER(Create_func_ord)},
+ { { STRING_WITH_LEN("OVERLAPS") }, GEOM_BUILDER(Create_func_mbr_overlaps)},
+ { { STRING_WITH_LEN("PERIOD_ADD") }, BUILDER(Create_func_period_add)},
+ { { STRING_WITH_LEN("PERIOD_DIFF") }, BUILDER(Create_func_period_diff)},
+ { { STRING_WITH_LEN("PI") }, BUILDER(Create_func_pi)},
+ { { STRING_WITH_LEN("POINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("POINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("POINTN") }, GEOM_BUILDER(Create_func_pointn)},
+ { { STRING_WITH_LEN("POINTONSURFACE") }, GEOM_BUILDER(Create_func_pointonsurface)},
+ { { STRING_WITH_LEN("POLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("POLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("POW") }, BUILDER(Create_func_pow)},
+ { { STRING_WITH_LEN("POWER") }, BUILDER(Create_func_pow)},
+ { { STRING_WITH_LEN("QUOTE") }, BUILDER(Create_func_quote)},
+ { { STRING_WITH_LEN("REGEXP_INSTR") }, BUILDER(Create_func_regexp_instr)},
+ { { STRING_WITH_LEN("REGEXP_REPLACE") }, BUILDER(Create_func_regexp_replace)},
+ { { STRING_WITH_LEN("REGEXP_SUBSTR") }, BUILDER(Create_func_regexp_substr)},
+ { { STRING_WITH_LEN("RADIANS") }, BUILDER(Create_func_radians)},
+ { { STRING_WITH_LEN("RAND") }, BUILDER(Create_func_rand)},
+ { { STRING_WITH_LEN("RELEASE_LOCK") }, BUILDER(Create_func_release_lock)},
+ { { STRING_WITH_LEN("REPLACE_ORACLE") },
BUILDER(Create_func_replace_oracle)},
- { { C_STRING_WITH_LEN("REVERSE") }, BUILDER(Create_func_reverse)},
- { { C_STRING_WITH_LEN("ROUND") }, BUILDER(Create_func_round)},
- { { C_STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad)},
- { { C_STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim)},
- { { C_STRING_WITH_LEN("SEC_TO_TIME") }, BUILDER(Create_func_sec_to_time)},
- { { C_STRING_WITH_LEN("SHA") }, BUILDER(Create_func_sha)},
- { { C_STRING_WITH_LEN("SHA1") }, BUILDER(Create_func_sha)},
- { { C_STRING_WITH_LEN("SHA2") }, BUILDER(Create_func_sha2)},
- { { C_STRING_WITH_LEN("SIGN") }, BUILDER(Create_func_sign)},
- { { C_STRING_WITH_LEN("SIN") }, BUILDER(Create_func_sin)},
- { { C_STRING_WITH_LEN("SLEEP") }, BUILDER(Create_func_sleep)},
- { { C_STRING_WITH_LEN("SOUNDEX") }, BUILDER(Create_func_soundex)},
- { { C_STRING_WITH_LEN("SPACE") }, BUILDER(Create_func_space)},
- { { C_STRING_WITH_LEN("SQRT") }, BUILDER(Create_func_sqrt)},
- { { C_STRING_WITH_LEN("SRID") }, GEOM_BUILDER(Create_func_srid)},
- { { C_STRING_WITH_LEN("STARTPOINT") }, GEOM_BUILDER(Create_func_startpoint)},
- { { C_STRING_WITH_LEN("STRCMP") }, BUILDER(Create_func_strcmp)},
- { { C_STRING_WITH_LEN("STR_TO_DATE") }, BUILDER(Create_func_str_to_date)},
- { { C_STRING_WITH_LEN("ST_AREA") }, GEOM_BUILDER(Create_func_area)},
- { { C_STRING_WITH_LEN("ST_ASBINARY") }, GEOM_BUILDER(Create_func_as_wkb)},
- { { C_STRING_WITH_LEN("ST_ASGEOJSON") }, GEOM_BUILDER(Create_func_as_geojson)},
- { { C_STRING_WITH_LEN("ST_ASTEXT") }, GEOM_BUILDER(Create_func_as_wkt)},
- { { C_STRING_WITH_LEN("ST_ASWKB") }, GEOM_BUILDER(Create_func_as_wkb)},
- { { C_STRING_WITH_LEN("ST_ASWKT") }, GEOM_BUILDER(Create_func_as_wkt)},
- { { C_STRING_WITH_LEN("ST_BOUNDARY") }, GEOM_BUILDER(Create_func_boundary)},
- { { C_STRING_WITH_LEN("ST_BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
- { { C_STRING_WITH_LEN("ST_CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
- { { C_STRING_WITH_LEN("ST_CONTAINS") }, GEOM_BUILDER(Create_func_contains)},
- { { C_STRING_WITH_LEN("ST_CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
- { { C_STRING_WITH_LEN("ST_CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
- { { C_STRING_WITH_LEN("ST_DIFFERENCE") }, GEOM_BUILDER(Create_func_difference)},
- { { C_STRING_WITH_LEN("ST_DIMENSION") }, GEOM_BUILDER(Create_func_dimension)},
- { { C_STRING_WITH_LEN("ST_DISJOINT") }, GEOM_BUILDER(Create_func_disjoint)},
- { { C_STRING_WITH_LEN("ST_DISTANCE") }, GEOM_BUILDER(Create_func_distance)},
- { { C_STRING_WITH_LEN("ST_ENDPOINT") }, GEOM_BUILDER(Create_func_endpoint)},
- { { C_STRING_WITH_LEN("ST_ENVELOPE") }, GEOM_BUILDER(Create_func_envelope)},
- { { C_STRING_WITH_LEN("ST_EQUALS") }, GEOM_BUILDER(Create_func_equals)},
- { { C_STRING_WITH_LEN("ST_EXTERIORRING") }, GEOM_BUILDER(Create_func_exteriorring)},
- { { C_STRING_WITH_LEN("ST_GEOMCOLLFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_GEOMCOLLFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_GEOMETRYCOLLECTIONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_GEOMETRYCOLLECTIONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_GEOMETRYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_GEOMETRYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_GEOMETRYN") }, GEOM_BUILDER(Create_func_geometryn)},
- { { C_STRING_WITH_LEN("ST_GEOMETRYTYPE") }, GEOM_BUILDER(Create_func_geometry_type)},
- { { C_STRING_WITH_LEN("ST_GEOMFROMGEOJSON") }, GEOM_BUILDER(Create_func_geometry_from_json)},
- { { C_STRING_WITH_LEN("ST_GEOMFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_GEOMFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("REVERSE") }, BUILDER(Create_func_reverse)},
+ { { STRING_WITH_LEN("ROUND") }, BUILDER(Create_func_round)},
+ { { STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad)},
+ { { STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim)},
+ { { STRING_WITH_LEN("SEC_TO_TIME") }, BUILDER(Create_func_sec_to_time)},
+ { { STRING_WITH_LEN("SHA") }, BUILDER(Create_func_sha)},
+ { { STRING_WITH_LEN("SHA1") }, BUILDER(Create_func_sha)},
+ { { STRING_WITH_LEN("SHA2") }, BUILDER(Create_func_sha2)},
+ { { STRING_WITH_LEN("SIGN") }, BUILDER(Create_func_sign)},
+ { { STRING_WITH_LEN("SIN") }, BUILDER(Create_func_sin)},
+ { { STRING_WITH_LEN("SLEEP") }, BUILDER(Create_func_sleep)},
+ { { STRING_WITH_LEN("SOUNDEX") }, BUILDER(Create_func_soundex)},
+ { { STRING_WITH_LEN("SPACE") }, BUILDER(Create_func_space)},
+ { { STRING_WITH_LEN("SQRT") }, BUILDER(Create_func_sqrt)},
+ { { STRING_WITH_LEN("SRID") }, GEOM_BUILDER(Create_func_srid)},
+ { { STRING_WITH_LEN("STARTPOINT") }, GEOM_BUILDER(Create_func_startpoint)},
+ { { STRING_WITH_LEN("STRCMP") }, BUILDER(Create_func_strcmp)},
+ { { STRING_WITH_LEN("STR_TO_DATE") }, BUILDER(Create_func_str_to_date)},
+ { { STRING_WITH_LEN("ST_AREA") }, GEOM_BUILDER(Create_func_area)},
+ { { STRING_WITH_LEN("ST_ASBINARY") }, GEOM_BUILDER(Create_func_as_wkb)},
+ { { STRING_WITH_LEN("ST_ASGEOJSON") }, GEOM_BUILDER(Create_func_as_geojson)},
+ { { STRING_WITH_LEN("ST_ASTEXT") }, GEOM_BUILDER(Create_func_as_wkt)},
+ { { STRING_WITH_LEN("ST_ASWKB") }, GEOM_BUILDER(Create_func_as_wkb)},
+ { { STRING_WITH_LEN("ST_ASWKT") }, GEOM_BUILDER(Create_func_as_wkt)},
+ { { STRING_WITH_LEN("ST_BOUNDARY") }, GEOM_BUILDER(Create_func_boundary)},
+ { { STRING_WITH_LEN("ST_BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
+ { { STRING_WITH_LEN("ST_CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
+ { { STRING_WITH_LEN("ST_CONTAINS") }, GEOM_BUILDER(Create_func_contains)},
+ { { STRING_WITH_LEN("ST_CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
+ { { STRING_WITH_LEN("ST_CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
+ { { STRING_WITH_LEN("ST_DIFFERENCE") }, GEOM_BUILDER(Create_func_difference)},
+ { { STRING_WITH_LEN("ST_DIMENSION") }, GEOM_BUILDER(Create_func_dimension)},
+ { { STRING_WITH_LEN("ST_DISJOINT") }, GEOM_BUILDER(Create_func_disjoint)},
+ { { STRING_WITH_LEN("ST_DISTANCE") }, GEOM_BUILDER(Create_func_distance)},
+ { { STRING_WITH_LEN("ST_ENDPOINT") }, GEOM_BUILDER(Create_func_endpoint)},
+ { { STRING_WITH_LEN("ST_ENVELOPE") }, GEOM_BUILDER(Create_func_envelope)},
+ { { STRING_WITH_LEN("ST_EQUALS") }, GEOM_BUILDER(Create_func_equals)},
+ { { STRING_WITH_LEN("ST_EXTERIORRING") }, GEOM_BUILDER(Create_func_exteriorring)},
+ { { STRING_WITH_LEN("ST_GEOMCOLLFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_GEOMCOLLFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_GEOMETRYCOLLECTIONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_GEOMETRYCOLLECTIONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_GEOMETRYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_GEOMETRYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_GEOMETRYN") }, GEOM_BUILDER(Create_func_geometryn)},
+ { { STRING_WITH_LEN("ST_GEOMETRYTYPE") }, GEOM_BUILDER(Create_func_geometry_type)},
+ { { STRING_WITH_LEN("ST_GEOMFROMGEOJSON") }, GEOM_BUILDER(Create_func_geometry_from_json)},
+ { { STRING_WITH_LEN("ST_GEOMFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_GEOMFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
#ifndef DBUG_OFF
- { { C_STRING_WITH_LEN("ST_GIS_DEBUG") }, GEOM_BUILDER(Create_func_gis_debug)},
+ { { STRING_WITH_LEN("ST_GIS_DEBUG") }, GEOM_BUILDER(Create_func_gis_debug)},
#endif
- { { C_STRING_WITH_LEN("ST_EQUALS") }, GEOM_BUILDER(Create_func_equals)},
- { { C_STRING_WITH_LEN("ST_INTERIORRINGN") }, GEOM_BUILDER(Create_func_interiorringn)},
- { { C_STRING_WITH_LEN("ST_INTERSECTS") }, GEOM_BUILDER(Create_func_intersects)},
- { { C_STRING_WITH_LEN("ST_INTERSECTION") }, GEOM_BUILDER(Create_func_intersection)},
- { { C_STRING_WITH_LEN("ST_ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
- { { C_STRING_WITH_LEN("ST_ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
- { { C_STRING_WITH_LEN("ST_ISRING") }, GEOM_BUILDER(Create_func_isring)},
- { { C_STRING_WITH_LEN("ST_ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)},
- { { C_STRING_WITH_LEN("ST_LENGTH") }, GEOM_BUILDER(Create_func_glength)},
- { { C_STRING_WITH_LEN("ST_LINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_LINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_LINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_MLINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_MLINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_MPOINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_MPOINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_MPOLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_MPOLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_MULTILINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_MULTILINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_MULTIPOINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_MULTIPOINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_MULTIPOLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_MULTIPOLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_NUMGEOMETRIES") }, GEOM_BUILDER(Create_func_numgeometries)},
- { { C_STRING_WITH_LEN("ST_NUMINTERIORRINGS") }, GEOM_BUILDER(Create_func_numinteriorring)},
- { { C_STRING_WITH_LEN("ST_NUMPOINTS") }, GEOM_BUILDER(Create_func_numpoints)},
- { { C_STRING_WITH_LEN("ST_OVERLAPS") }, GEOM_BUILDER(Create_func_overlaps)},
- { { C_STRING_WITH_LEN("ST_POINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_POINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_POINTN") }, GEOM_BUILDER(Create_func_pointn)},
- { { C_STRING_WITH_LEN("ST_POINTONSURFACE") }, GEOM_BUILDER(Create_func_pointonsurface)},
- { { C_STRING_WITH_LEN("ST_POLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
- { { C_STRING_WITH_LEN("ST_POLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { { C_STRING_WITH_LEN("ST_RELATE") }, GEOM_BUILDER(Create_func_relate)},
- { { C_STRING_WITH_LEN("ST_SRID") }, GEOM_BUILDER(Create_func_srid)},
- { { C_STRING_WITH_LEN("ST_STARTPOINT") }, GEOM_BUILDER(Create_func_startpoint)},
- { { C_STRING_WITH_LEN("ST_SYMDIFFERENCE") }, GEOM_BUILDER(Create_func_symdifference)},
- { { C_STRING_WITH_LEN("ST_TOUCHES") }, GEOM_BUILDER(Create_func_touches)},
- { { C_STRING_WITH_LEN("ST_UNION") }, GEOM_BUILDER(Create_func_union)},
- { { C_STRING_WITH_LEN("ST_WITHIN") }, GEOM_BUILDER(Create_func_within)},
- { { C_STRING_WITH_LEN("ST_X") }, GEOM_BUILDER(Create_func_x)},
- { { C_STRING_WITH_LEN("ST_Y") }, GEOM_BUILDER(Create_func_y)},
- { { C_STRING_WITH_LEN("SUBSTR_ORACLE") },
+ { { STRING_WITH_LEN("ST_EQUALS") }, GEOM_BUILDER(Create_func_equals)},
+ { { STRING_WITH_LEN("ST_INTERIORRINGN") }, GEOM_BUILDER(Create_func_interiorringn)},
+ { { STRING_WITH_LEN("ST_INTERSECTS") }, GEOM_BUILDER(Create_func_intersects)},
+ { { STRING_WITH_LEN("ST_INTERSECTION") }, GEOM_BUILDER(Create_func_intersection)},
+ { { STRING_WITH_LEN("ST_ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
+ { { STRING_WITH_LEN("ST_ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
+ { { STRING_WITH_LEN("ST_ISRING") }, GEOM_BUILDER(Create_func_isring)},
+ { { STRING_WITH_LEN("ST_ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)},
+ { { STRING_WITH_LEN("ST_LENGTH") }, GEOM_BUILDER(Create_func_glength)},
+ { { STRING_WITH_LEN("ST_LINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_LINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_LINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_MLINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_MLINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_MPOINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_MPOINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_MPOLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_MPOLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_MULTILINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_MULTILINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_MULTIPOINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_MULTIPOINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_MULTIPOLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_MULTIPOLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_NUMGEOMETRIES") }, GEOM_BUILDER(Create_func_numgeometries)},
+ { { STRING_WITH_LEN("ST_NUMINTERIORRINGS") }, GEOM_BUILDER(Create_func_numinteriorring)},
+ { { STRING_WITH_LEN("ST_NUMPOINTS") }, GEOM_BUILDER(Create_func_numpoints)},
+ { { STRING_WITH_LEN("ST_OVERLAPS") }, GEOM_BUILDER(Create_func_overlaps)},
+ { { STRING_WITH_LEN("ST_POINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_POINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_POINTN") }, GEOM_BUILDER(Create_func_pointn)},
+ { { STRING_WITH_LEN("ST_POINTONSURFACE") }, GEOM_BUILDER(Create_func_pointonsurface)},
+ { { STRING_WITH_LEN("ST_POLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { STRING_WITH_LEN("ST_POLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { STRING_WITH_LEN("ST_RELATE") }, GEOM_BUILDER(Create_func_relate)},
+ { { STRING_WITH_LEN("ST_SRID") }, GEOM_BUILDER(Create_func_srid)},
+ { { STRING_WITH_LEN("ST_STARTPOINT") }, GEOM_BUILDER(Create_func_startpoint)},
+ { { STRING_WITH_LEN("ST_SYMDIFFERENCE") }, GEOM_BUILDER(Create_func_symdifference)},
+ { { STRING_WITH_LEN("ST_TOUCHES") }, GEOM_BUILDER(Create_func_touches)},
+ { { STRING_WITH_LEN("ST_UNION") }, GEOM_BUILDER(Create_func_union)},
+ { { STRING_WITH_LEN("ST_WITHIN") }, GEOM_BUILDER(Create_func_within)},
+ { { STRING_WITH_LEN("ST_X") }, GEOM_BUILDER(Create_func_x)},
+ { { STRING_WITH_LEN("ST_Y") }, GEOM_BUILDER(Create_func_y)},
+ { { STRING_WITH_LEN("SUBSTR_ORACLE") },
BUILDER(Create_func_substr_oracle)},
- { { C_STRING_WITH_LEN("SUBSTRING_INDEX") }, BUILDER(Create_func_substr_index)},
- { { C_STRING_WITH_LEN("SUBTIME") }, BUILDER(Create_func_subtime)},
- { { C_STRING_WITH_LEN("TAN") }, BUILDER(Create_func_tan)},
- { { C_STRING_WITH_LEN("TIMEDIFF") }, BUILDER(Create_func_timediff)},
- { { C_STRING_WITH_LEN("TIME_FORMAT") }, BUILDER(Create_func_time_format)},
- { { C_STRING_WITH_LEN("TIME_TO_SEC") }, BUILDER(Create_func_time_to_sec)},
- { { C_STRING_WITH_LEN("TOUCHES") }, GEOM_BUILDER(Create_func_touches)},
- { { C_STRING_WITH_LEN("TO_BASE64") }, BUILDER(Create_func_to_base64)},
- { { C_STRING_WITH_LEN("TO_DAYS") }, BUILDER(Create_func_to_days)},
- { { C_STRING_WITH_LEN("TO_SECONDS") }, BUILDER(Create_func_to_seconds)},
- { { C_STRING_WITH_LEN("UCASE") }, BUILDER(Create_func_ucase)},
- { { C_STRING_WITH_LEN("UNCOMPRESS") }, BUILDER(Create_func_uncompress)},
- { { C_STRING_WITH_LEN("UNCOMPRESSED_LENGTH") }, BUILDER(Create_func_uncompressed_length)},
- { { C_STRING_WITH_LEN("UNHEX") }, BUILDER(Create_func_unhex)},
- { { C_STRING_WITH_LEN("UNIX_TIMESTAMP") }, BUILDER(Create_func_unix_timestamp)},
- { { C_STRING_WITH_LEN("UPDATEXML") }, BUILDER(Create_func_xml_update)},
- { { C_STRING_WITH_LEN("UPPER") }, BUILDER(Create_func_ucase)},
- { { C_STRING_WITH_LEN("UUID") }, BUILDER(Create_func_uuid)},
- { { C_STRING_WITH_LEN("UUID_SHORT") }, BUILDER(Create_func_uuid_short)},
- { { C_STRING_WITH_LEN("VERSION") }, BUILDER(Create_func_version)},
- { { C_STRING_WITH_LEN("WEEKDAY") }, BUILDER(Create_func_weekday)},
- { { C_STRING_WITH_LEN("WEEKOFYEAR") }, BUILDER(Create_func_weekofyear)},
- { { C_STRING_WITH_LEN("WITHIN") }, GEOM_BUILDER(Create_func_within)},
- { { C_STRING_WITH_LEN("X") }, GEOM_BUILDER(Create_func_x)},
- { { C_STRING_WITH_LEN("Y") }, GEOM_BUILDER(Create_func_y)},
- { { C_STRING_WITH_LEN("YEARWEEK") }, BUILDER(Create_func_year_week)},
+ { { STRING_WITH_LEN("SUBSTRING_INDEX") }, BUILDER(Create_func_substr_index)},
+ { { STRING_WITH_LEN("SUBTIME") }, BUILDER(Create_func_subtime)},
+ { { STRING_WITH_LEN("TAN") }, BUILDER(Create_func_tan)},
+ { { STRING_WITH_LEN("TIMEDIFF") }, BUILDER(Create_func_timediff)},
+ { { STRING_WITH_LEN("TIME_FORMAT") }, BUILDER(Create_func_time_format)},
+ { { STRING_WITH_LEN("TIME_TO_SEC") }, BUILDER(Create_func_time_to_sec)},
+ { { STRING_WITH_LEN("TOUCHES") }, GEOM_BUILDER(Create_func_touches)},
+ { { STRING_WITH_LEN("TO_BASE64") }, BUILDER(Create_func_to_base64)},
+ { { STRING_WITH_LEN("TO_DAYS") }, BUILDER(Create_func_to_days)},
+ { { STRING_WITH_LEN("TO_SECONDS") }, BUILDER(Create_func_to_seconds)},
+ { { STRING_WITH_LEN("UCASE") }, BUILDER(Create_func_ucase)},
+ { { STRING_WITH_LEN("UNCOMPRESS") }, BUILDER(Create_func_uncompress)},
+ { { STRING_WITH_LEN("UNCOMPRESSED_LENGTH") }, BUILDER(Create_func_uncompressed_length)},
+ { { STRING_WITH_LEN("UNHEX") }, BUILDER(Create_func_unhex)},
+ { { STRING_WITH_LEN("UNIX_TIMESTAMP") }, BUILDER(Create_func_unix_timestamp)},
+ { { STRING_WITH_LEN("UPDATEXML") }, BUILDER(Create_func_xml_update)},
+ { { STRING_WITH_LEN("UPPER") }, BUILDER(Create_func_ucase)},
+ { { STRING_WITH_LEN("UUID") }, BUILDER(Create_func_uuid)},
+ { { STRING_WITH_LEN("UUID_SHORT") }, BUILDER(Create_func_uuid_short)},
+ { { STRING_WITH_LEN("VERSION") }, BUILDER(Create_func_version)},
+ { { STRING_WITH_LEN("WEEKDAY") }, BUILDER(Create_func_weekday)},
+ { { STRING_WITH_LEN("WEEKOFYEAR") }, BUILDER(Create_func_weekofyear)},
+ { { STRING_WITH_LEN("WITHIN") }, GEOM_BUILDER(Create_func_within)},
+ { { STRING_WITH_LEN("X") }, GEOM_BUILDER(Create_func_x)},
+ { { STRING_WITH_LEN("Y") }, GEOM_BUILDER(Create_func_y)},
+ { { STRING_WITH_LEN("YEARWEEK") }, BUILDER(Create_func_year_week)},
{ {0, 0}, NULL}
};
@@ -7218,8 +7180,6 @@ get_native_fct_hash_key(const uchar *buff, size_t *length,
int item_create_init()
{
- Native_func_registry *func;
-
DBUG_ENTER("item_create_init");
if (my_hash_init(& native_functions_hash,
@@ -7232,7 +7192,16 @@ int item_create_init()
MYF(0)))
DBUG_RETURN(1);
- for (func= func_array; func->builder != NULL; func++)
+ DBUG_RETURN(item_create_append(func_array));
+}
+
+int item_create_append(Native_func_registry array[])
+{
+ Native_func_registry *func;
+
+ DBUG_ENTER("item_create_append");
+
+ for (func= array; func->builder != NULL; func++)
{
if (my_hash_insert(& native_functions_hash, (uchar*) func))
DBUG_RETURN(1);
@@ -7307,7 +7276,7 @@ have_important_literal_warnings(const MYSQL_TIME_STATUS *status)
*/
Item *create_temporal_literal(THD *thd,
- const char *str, uint length,
+ const char *str, size_t length,
CHARSET_INFO *cs,
enum_field_types type,
bool send_error)
diff --git a/sql/item_create.h b/sql/item_create.h
index 128a19a1c15..5983a092cdc 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -19,6 +19,8 @@
#ifndef ITEM_CREATE_H
#define ITEM_CREATE_H
+#include "item_func.h" // Cast_target
+
typedef struct st_udf_func udf_func;
/**
@@ -67,6 +69,38 @@ protected:
/**
+ Adapter for native functions with a variable number of arguments.
+ The main use of this class is to discard the following calls:
+ <code>foo(expr1 AS name1, expr2 AS name2, ...)</code>
+ which are syntactically correct (the syntax can refer to a UDF),
+ but semantically invalid for native functions.
+*/
+
+class Create_native_func : public Create_func
+{
+public:
+ virtual Item *create_func(THD *thd, LEX_CSTRING *name,
+ List<Item> *item_list);
+
+ /**
+ Builder method, with no arguments.
+ @param thd The current thread
+ @param name The native function name
+ @param item_list The function parameters, none of which are named
+ @return An item representing the function call
+ */
+ virtual Item *create_native(THD *thd, LEX_CSTRING *name,
+ List<Item> *item_list) = 0;
+
+protected:
+ /** Constructor. */
+ Create_native_func() {}
+ /** Destructor. */
+ virtual ~Create_native_func() {}
+};
+
+
+/**
Function builder for qualified functions.
This builder is used with functions call using a qualified function name
syntax, as in <code>db.func(expr, expr, ...)</code>.
@@ -158,7 +192,7 @@ protected:
Item *create_temporal_literal(THD *thd,
- const char *str, uint length,
+ const char *str, size_t length,
CHARSET_INFO *cs,
enum_field_types type,
bool send_error);
@@ -172,7 +206,14 @@ Item *create_temporal_literal(THD *thd, const String *str,
type, send_error);
}
+struct Native_func_registry
+{
+ LEX_CSTRING name;
+ Create_func *builder;
+};
+
int item_create_init();
+int item_create_append(Native_func_registry array[]);
void item_create_cleanup();
Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 659ec29e452..4e79b45f5d6 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -54,6 +54,7 @@
#include "set_var.h"
#include "debug_sync.h"
#include "sql_base.h"
+#include "sql_cte.h"
#ifdef NO_EMBEDDED_ACCESS_CHECKS
#define sp_restore_security_context(A,B) while (0) {}
@@ -153,12 +154,19 @@ void Item_func::sync_with_sum_func_and_with_field(List<Item> &list)
bool Item_func::check_argument_types_like_args0() const
{
- uint cols;
- if (arg_count == 0)
+ if (arg_count < 2)
return false;
- cols= args[0]->cols();
+ uint cols= args[0]->cols();
+ bool is_scalar= args[0]->type_handler()->is_scalar_type();
for (uint i= 1; i < arg_count; i++)
{
+ if (is_scalar != args[i]->type_handler()->is_scalar_type())
+ {
+ my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
+ args[0]->type_handler()->name().ptr(),
+ args[i]->type_handler()->name().ptr(), func_name());
+ return true;
+ }
if (args[i]->check_cols(cols))
return true;
}
@@ -362,7 +370,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
with_window_func= with_window_func || item->with_window_func;
with_field= with_field || item->with_field;
used_tables_and_const_cache_join(item);
- with_subselect|= item->has_subquery();
+ m_with_subquery|= item->with_subquery();
}
}
if (check_arguments())
@@ -696,6 +704,7 @@ my_decimal *Item_real_func::val_decimal(my_decimal *decimal_value)
}
+#ifdef HAVE_DLOPEN
void Item_udf_func::fix_num_length_and_dec()
{
uint fl_length= 0;
@@ -712,6 +721,7 @@ void Item_udf_func::fix_num_length_and_dec()
max_length= float_length(NOT_FIXED_DEC);
}
}
+#endif
void Item_func::signal_divide_by_null()
@@ -919,7 +929,6 @@ String *Item_func_hybrid_field_type::val_str_from_date_op(String *str)
if (date_op_with_null_check(&ltime) ||
(null_value= str->alloc(MAX_DATE_STRING_REP_LENGTH)))
return (String *) 0;
- ltime.time_type= mysql_timestamp_type();
str->length(my_TIME_to_str(&ltime, const_cast<char*>(str->ptr()), decimals));
str->set_charset(&my_charset_bin);
DBUG_ASSERT(!null_value);
@@ -931,7 +940,6 @@ double Item_func_hybrid_field_type::val_real_from_date_op()
MYSQL_TIME ltime;
if (date_op_with_null_check(&ltime))
return 0;
- ltime.time_type= mysql_timestamp_type();
return TIME_to_double(&ltime);
}
@@ -940,7 +948,6 @@ longlong Item_func_hybrid_field_type::val_int_from_date_op()
MYSQL_TIME ltime;
if (date_op_with_null_check(&ltime))
return 0;
- ltime.time_type= mysql_timestamp_type();
return TIME_to_ulonglong(&ltime);
}
@@ -953,7 +960,40 @@ Item_func_hybrid_field_type::val_decimal_from_date_op(my_decimal *dec)
my_decimal_set_zero(dec);
return 0;
}
- ltime.time_type= mysql_timestamp_type();
+ return date2my_decimal(&ltime, dec);
+}
+
+
+String *Item_func_hybrid_field_type::val_str_from_time_op(String *str)
+{
+ MYSQL_TIME ltime;
+ if (time_op_with_null_check(&ltime) ||
+ (null_value= my_TIME_to_str(&ltime, str, decimals)))
+ return NULL;
+ return str;
+}
+
+double Item_func_hybrid_field_type::val_real_from_time_op()
+{
+ MYSQL_TIME ltime;
+ return time_op_with_null_check(&ltime) ? 0 : TIME_to_double(&ltime);
+}
+
+longlong Item_func_hybrid_field_type::val_int_from_time_op()
+{
+ MYSQL_TIME ltime;
+ return time_op_with_null_check(&ltime) ? 0 : TIME_to_ulonglong(&ltime);
+}
+
+my_decimal *
+Item_func_hybrid_field_type::val_decimal_from_time_op(my_decimal *dec)
+{
+ MYSQL_TIME ltime;
+ if (time_op_with_null_check(&ltime))
+ {
+ my_decimal_set_zero(dec);
+ return 0;
+ }
return date2my_decimal(&ltime, dec);
}
@@ -2695,7 +2735,7 @@ bool Item_func_min_max::get_date_native(MYSQL_TIME *ltime, ulonglong fuzzy_date)
for (uint i=0; i < arg_count ; i++)
{
- longlong res= args[i]->val_temporal_packed(Item_func_min_max::field_type());
+ longlong res= args[i]->val_datetime_packed();
/* Check if we need to stop (because of error or KILL) and stop the loop */
if (args[i]->null_value)
@@ -2704,22 +2744,7 @@ bool Item_func_min_max::get_date_native(MYSQL_TIME *ltime, ulonglong fuzzy_date)
if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
min_max= res;
}
- unpack_time(min_max, ltime);
-
- if (Item_func_min_max::field_type() == MYSQL_TYPE_DATE)
- {
- ltime->time_type= MYSQL_TIMESTAMP_DATE;
- ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
- }
- else if (Item_func_min_max::field_type() == MYSQL_TYPE_TIME)
- {
- ltime->time_type= MYSQL_TIMESTAMP_TIME;
- ltime->hour+= (ltime->month * 32 + ltime->day) * 24;
- ltime->year= ltime->month= ltime->day= 0;
- if (adjust_time_range_with_warn(ltime,
- std::min<uint>(decimals, TIME_SECOND_PART_DIGITS)))
- return (null_value= true);
- }
+ unpack_time(min_max, ltime, mysql_timestamp_type());
if (!(fuzzy_date & TIME_TIME_ONLY) &&
((null_value= check_date_with_warn(ltime, fuzzy_date,
@@ -2730,6 +2755,29 @@ bool Item_func_min_max::get_date_native(MYSQL_TIME *ltime, ulonglong fuzzy_date)
}
+bool Item_func_min_max::get_time_native(MYSQL_TIME *ltime)
+{
+ DBUG_ASSERT(fixed == 1);
+
+ Time value(args[0]);
+ if (!value.is_valid_time())
+ return (null_value= true);
+
+ for (uint i= 1; i < arg_count ; i++)
+ {
+ Time tmp(args[i]);
+ if (!tmp.is_valid_time())
+ return (null_value= true);
+
+ int cmp= value.cmp(&tmp);
+ if ((cmp_sign < 0 ? cmp : -cmp) < 0)
+ value= tmp;
+ }
+ value.copy_to_mysql_time(ltime);
+ return (null_value= 0);
+}
+
+
String *Item_func_min_max::val_str_native(String *str)
{
String *UNINIT_VAR(res);
@@ -3196,7 +3244,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
DBUG_RETURN(TRUE); // Fatal error flag is set!
- udf_func *tmp_udf=find_udf(u_d->name.str,(uint) u_d->name.length,1);
+ udf_func *tmp_udf=find_udf(u_d->name.str,u_d->name.length,1);
if (!tmp_udf)
{
@@ -3249,7 +3297,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
func->maybe_null=1;
func->with_sum_func= func->with_sum_func || item->with_sum_func;
func->with_field= func->with_field || item->with_field;
- func->with_subselect|= item->with_subselect;
+ func->With_subquery_cache::join(item);
func->used_tables_and_const_cache_join(item);
f_args.arg_type[i]=item->result_type();
}
@@ -3291,7 +3339,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
f_args.lengths[i]= arguments[i]->max_length;
f_args.maybe_null[i]= (char) arguments[i]->maybe_null;
f_args.attributes[i]= arguments[i]->name.str;
- f_args.attribute_lengths[i]= arguments[i]->name.length;
+ f_args.attribute_lengths[i]= (ulong)arguments[i]->name.length;
if (arguments[i]->const_item())
{
@@ -4378,7 +4426,7 @@ user_var_entry *get_variable(HASH *hash, LEX_CSTRING *name,
name->length)) &&
create_if_not_exists)
{
- uint size=ALIGN_SIZE(sizeof(user_var_entry))+name->length+1+extra_size;
+ size_t size=ALIGN_SIZE(sizeof(user_var_entry))+name->length+1+extra_size;
if (!my_hash_inited(hash))
return 0;
if (!(entry = (user_var_entry*) my_malloc(size,
@@ -4507,10 +4555,13 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
TABLE_LIST *derived;
for (derived= unit->derived;
derived;
- derived= derived->select_lex->master_unit()->derived)
+ derived= unit->derived)
{
derived->set_materialized_derived();
derived->prohibit_cond_pushdown= true;
+ if (unit->with_element && unit->with_element->is_recursive)
+ break;
+ unit= derived->select_lex->master_unit();
}
}
@@ -4596,7 +4647,7 @@ bool Item_func_set_user_var::register_field_in_bitmap(void *arg)
*/
static bool
-update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
+update_hash(user_var_entry *entry, bool set_null, void *ptr, size_t length,
Item_result type, CHARSET_INFO *cs,
bool unsigned_arg)
{
@@ -4657,7 +4708,7 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
bool
-Item_func_set_user_var::update_hash(void *ptr, uint length,
+Item_func_set_user_var::update_hash(void *ptr, size_t length,
Item_result res_type,
CHARSET_INFO *cs,
bool unsigned_arg)
@@ -5321,7 +5372,7 @@ get_var_with_binlog(THD *thd, enum_sql_command sql_command,
return 0;
}
- uint size;
+ size_t size;
/*
First we need to store value of var_entry, when the next situation
appears:
@@ -5388,7 +5439,7 @@ void Item_func_get_user_var::fix_length_and_dec()
if (!error && m_var_entry)
{
unsigned_flag= m_var_entry->unsigned_flag;
- max_length= m_var_entry->length;
+ max_length= (uint32)m_var_entry->length;
collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT);
set_handler_by_result_type(m_var_entry->type);
switch (result_type()) {
@@ -5432,7 +5483,7 @@ bool Item_func_get_user_var::const_item() const
void Item_func_get_user_var::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("@"));
- append_identifier(current_thd, str, name.str, name.length);
+ append_identifier(current_thd, str, &name);
}
@@ -5469,7 +5520,7 @@ bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
DBUG_ASSERT(fixed == 0);
DBUG_ASSERT(thd->lex->exchange);
if (Item::fix_fields(thd, ref) ||
- !(entry= get_variable(&thd->user_vars, &name, 1)))
+ !(entry= get_variable(&thd->user_vars, &org_name, 1)))
return TRUE;
entry->type= STRING_RESULT;
/*
@@ -5527,10 +5578,17 @@ my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer)
}
+bool Item_user_var_as_out_param::get_date(MYSQL_TIME *ltime, ulonglong fuzzy)
+{
+ DBUG_ASSERT(0);
+ return true;
+}
+
+
void Item_user_var_as_out_param::print_for_load(THD *thd, String *str)
{
str->append('@');
- append_identifier(thd, str, name.str, name.length);
+ append_identifier(thd, str, &org_name);
}
@@ -5602,7 +5660,7 @@ void Item_func_get_system_var::fix_length_and_dec()
(char*) var->value_ptr(current_thd, var_type, &component) :
*(char**) var->value_ptr(current_thd, var_type, &component);
if (cptr)
- max_length= system_charset_info->cset->numchars(system_charset_info,
+ max_length= (uint32)system_charset_info->cset->numchars(system_charset_info,
cptr,
cptr + strlen(cptr));
mysql_mutex_unlock(&LOCK_global_system_variables);
@@ -5614,7 +5672,7 @@ void Item_func_get_system_var::fix_length_and_dec()
{
mysql_mutex_lock(&LOCK_global_system_variables);
LEX_STRING *ls= ((LEX_STRING*)var->value_ptr(current_thd, var_type, &component));
- max_length= system_charset_info->cset->numchars(system_charset_info,
+ max_length= (uint32)system_charset_info->cset->numchars(system_charset_info,
ls->str,
ls->str + ls->length);
mysql_mutex_unlock(&LOCK_global_system_variables);
@@ -6238,35 +6296,24 @@ longlong Item_func_row_count::val_int()
Item_func_sp::Item_func_sp(THD *thd, Name_resolution_context *context_arg,
sp_name *name):
- Item_func(thd), context(context_arg), m_name(name), m_sp(NULL), sp_result_field(NULL)
+ Item_func(thd), Item_sp(thd, context_arg, name)
{
maybe_null= 1;
- dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
- dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
}
Item_func_sp::Item_func_sp(THD *thd, Name_resolution_context *context_arg,
sp_name *name_arg, List<Item> &list):
- Item_func(thd, list), context(context_arg), m_name(name_arg), m_sp(NULL),
- sp_result_field(NULL)
+ Item_func(thd, list), Item_sp(thd, context_arg, name_arg)
{
maybe_null= 1;
- dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
- dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
}
void
Item_func_sp::cleanup()
{
- if (sp_result_field)
- {
- delete sp_result_field;
- sp_result_field= NULL;
- }
- m_sp= NULL;
- dummy_table->alias.free();
+ Item_sp::cleanup();
Item_func::cleanup();
}
@@ -6274,25 +6321,7 @@ const char *
Item_func_sp::func_name() const
{
THD *thd= current_thd;
- /* Calculate length to avoid reallocation of string for sure */
- uint len= (((m_name->m_explicit_name ? m_name->m_db.length : 0) +
- m_name->m_name.length)*2 + //characters*quoting
- 2 + // ` and `
- (m_name->m_explicit_name ?
- 3 : 0) + // '`', '`' and '.' for the db
- 1 + // end of string
- ALIGN_SIZE(1)); // to avoid String reallocation
- String qname((char *)alloc_root(thd->mem_root, len), len,
- system_charset_info);
-
- qname.length(0);
- if (m_name->m_explicit_name)
- {
- append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length);
- qname.append('.');
- }
- append_identifier(thd, &qname, m_name->m_name.str, m_name->m_name.length);
- return qname.c_ptr_safe();
+ return Item_sp::func_name(thd);
}
@@ -6306,75 +6335,6 @@ void my_missing_function_error(const LEX_CSTRING &token, const char *func_name)
/**
- @brief Initialize the result field by creating a temporary dummy table
- and assign it to a newly created field object. Meta data used to
- create the field is fetched from the sp_head belonging to the stored
- proceedure found in the stored procedure functon cache.
-
- @note This function should be called from fix_fields to init the result
- field. It is some what related to Item_field.
-
- @see Item_field
-
- @param thd A pointer to the session and thread context.
-
- @return Function return error status.
- @retval TRUE is returned on an error
- @retval FALSE is returned on success.
-*/
-
-bool
-Item_func_sp::init_result_field(THD *thd, sp_head *sp)
-{
- TABLE_SHARE *share;
- DBUG_ENTER("Item_func_sp::init_result_field");
-
- DBUG_ASSERT(m_sp == NULL);
- DBUG_ASSERT(sp_result_field == NULL);
-
- if (!(m_sp= sp))
- {
- my_missing_function_error (m_name->m_name, ErrConvDQName(m_name).ptr());
- context->process_error(thd);
- DBUG_RETURN(TRUE);
- }
-
- /*
- A Field need to be attached to a Table.
- Below we "create" a dummy table by initializing
- the needed pointers.
- */
-
- share= dummy_table->s;
- dummy_table->alias.set("", 0, table_alias_charset);
- dummy_table->maybe_null = maybe_null;
- dummy_table->in_use= thd;
- dummy_table->copy_blobs= TRUE;
- share->table_cache_key= empty_clex_str;
- share->table_name= empty_clex_str;
-
- if (!(sp_result_field= m_sp->create_result_field(max_length, &name, dummy_table)))
- {
- DBUG_RETURN(TRUE);
- }
-
- if (sp_result_field->pack_length() > sizeof(result_buf))
- {
- void *tmp;
- if (!(tmp= thd->alloc(sp_result_field->pack_length())))
- DBUG_RETURN(TRUE);
- sp_result_field->move_field((uchar*) tmp);
- }
- else
- sp_result_field->move_field(result_buf);
-
- sp_result_field->null_ptr= (uchar *) &null_value;
- sp_result_field->null_bit= 1;
- DBUG_RETURN(FALSE);
-}
-
-
-/**
@note
Deterministic stored procedures are considered inexpensive.
Consequently such procedures may be evaluated during optimization,
@@ -6408,95 +6368,11 @@ void Item_func_sp::fix_length_and_dec()
}
-/**
- @brief Execute function & store value in field.
-
- @return Function returns error status.
- @retval FALSE on success.
- @retval TRUE if an error occurred.
-*/
-
bool
Item_func_sp::execute()
{
- THD *thd= current_thd;
-
/* Execute function and store the return value in the field. */
-
- if (execute_impl(thd))
- {
- null_value= 1;
- context->process_error(thd);
- if (thd->killed)
- thd->send_kill_message();
- return TRUE;
- }
-
- /* Check that the field (the value) is not NULL. */
-
- null_value= sp_result_field->is_null();
-
- return null_value;
-}
-
-
-/**
- @brief Execute function and store the return value in the field.
-
- @note This function was intended to be the concrete implementation of
- the interface function execute. This was never realized.
-
- @return The error state.
- @retval FALSE on success
- @retval TRUE if an error occurred.
-*/
-bool
-Item_func_sp::execute_impl(THD *thd)
-{
- bool err_status= TRUE;
- Sub_statement_state statement_state;
- Security_context *save_security_ctx= thd->security_ctx;
- enum enum_sp_data_access access=
- (m_sp->daccess() == SP_DEFAULT_ACCESS) ?
- SP_DEFAULT_ACCESS_MAPPING : m_sp->daccess();
-
- DBUG_ENTER("Item_func_sp::execute_impl");
-
- if (context->security_ctx)
- {
- /* Set view definer security context */
- thd->security_ctx= context->security_ctx;
- }
- if (sp_check_access(thd))
- goto error;
-
- /*
- Throw an error if a non-deterministic function is called while
- statement-based replication (SBR) is active.
- */
-
- if (!m_sp->detistic() && !trust_function_creators &&
- (access == SP_CONTAINS_SQL || access == SP_MODIFIES_SQL_DATA) &&
- (mysql_bin_log.is_open() &&
- thd->variables.binlog_format == BINLOG_FORMAT_STMT))
- {
- my_error(ER_BINLOG_UNSAFE_ROUTINE, MYF(0));
- goto error;
- }
-
- /*
- Disable the binlogging if this is not a SELECT statement. If this is a
- SELECT, leave binlogging on, so execute_function() code writes the
- function call into binlog.
- */
- thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION);
- err_status= m_sp->execute_function(thd, args, arg_count, sp_result_field);
- thd->restore_sub_statement_state(&statement_state);
-
-error:
- thd->security_ctx= save_security_ctx;
-
- DBUG_RETURN(err_status);
+ return Item_sp::execute(current_thd, &null_value, args, arg_count);
}
@@ -6561,29 +6437,6 @@ longlong Item_func_sqlcode::val_int()
}
-/**
- @brief Checks if requested access to function can be granted to user.
- If function isn't found yet, it searches function first.
- If function can't be found or user don't have requested access
- error is raised.
-
- @param thd thread handler
-
- @return Indication if the access was granted or not.
- @retval FALSE Access is granted.
- @retval TRUE Requested access can't be granted or function doesn't exists.
-
-*/
-
-bool
-Item_func_sp::sp_check_access(THD *thd)
-{
- DBUG_ENTER("Item_func_sp::sp_check_access");
- DBUG_ASSERT(m_sp);
- DBUG_RETURN(m_sp->check_execute_access(thd));
-}
-
-
bool
Item_func_sp::fix_fields(THD *thd, Item **ref)
{
@@ -6608,8 +6461,8 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
whether to return "Access denied" or "Routine does not exist".
*/
res= sp ? sp->check_execute_access(thd) :
- check_routine_access(thd, EXECUTE_ACL, m_name->m_db.str,
- m_name->m_name.str,
+ check_routine_access(thd, EXECUTE_ACL, &m_name->m_db,
+ &m_name->m_name,
&sp_handler_function, false);
thd->security_ctx= save_security_ctx;
@@ -6620,20 +6473,66 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
}
}
+
+ /* Custom aggregates are transformed into an Item_sum_sp. We can not do this
+ earlier as we have no way of knowing what kind of Item we should create
+ when parsing the query.
+
+ TODO(cvicentiu): See if this limitation can be lifted.
+ */
+
+ DBUG_ASSERT(m_sp == NULL);
+ if (!(m_sp= sp))
+ {
+ my_missing_function_error(m_name->m_name, ErrConvDQName(m_name).ptr());
+ context->process_error(thd);
+ DBUG_RETURN(TRUE);
+ }
+
/*
- We must call init_result_field before Item_func::fix_fields()
+ We must call init_result_field before Item_func::fix_fields()
to make m_sp and result_field members available to fix_length_and_dec(),
which is called from Item_func::fix_fields().
*/
- res= init_result_field(thd, sp);
+ res= init_result_field(thd, max_length, maybe_null, &null_value, &name);
if (res)
- DBUG_RETURN(res);
+ DBUG_RETURN(TRUE);
+
+ if (m_sp->agg_type() == GROUP_AGGREGATE)
+ {
+ List<Item> list;
+ list.empty();
+ for (uint i=0; i < arg_count; i++)
+ list.push_back(*(args+i));
+
+ Item_sum_sp *item_sp;
+ Query_arena *arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+
+ if (arg_count)
+ item_sp= new (thd->mem_root) Item_sum_sp(thd, context, m_name, sp, list);
+ else
+ item_sp= new (thd->mem_root) Item_sum_sp(thd, context, m_name, sp);
+
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ if (!item_sp)
+ DBUG_RETURN(TRUE);
+ *ref= item_sp;
+ item_sp->name= name;
+ bool err= item_sp->fix_fields(thd, ref);
+ if (err)
+ DBUG_RETURN(TRUE);
+
+ list.empty();
+ DBUG_RETURN(FALSE);
+ }
res= Item_func::fix_fields(thd, ref);
if (res)
- DBUG_RETURN(res);
+ DBUG_RETURN(TRUE);
if (thd->lex->is_view_context_analysis())
{
@@ -6771,6 +6670,15 @@ my_decimal *Item_func_last_value::val_decimal(my_decimal *decimal_value)
}
+bool Item_func_last_value::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ evaluate_sideeffects();
+ bool tmp= last_value->get_date(ltime, fuzzydate);
+ null_value= last_value->null_value;
+ return tmp;
+}
+
+
void Item_func_last_value::fix_length_and_dec()
{
last_value= args[arg_count -1];
@@ -6781,7 +6689,7 @@ void Item_func_last_value::fix_length_and_dec()
void Cursor_ref::print_func(String *str, const char *func_name)
{
- append_identifier(current_thd, str, m_cursor_name.str, m_cursor_name.length);
+ append_identifier(current_thd, str, &m_cursor_name);
str->append(func_name);
}
@@ -6838,14 +6746,22 @@ longlong Item_func_nextval::val_int()
longlong value;
int error;
const char *key;
- TABLE *table= table_list->table;
uint length= get_table_def_key(table_list, &key);
- THD *thd= table->in_use;
+ THD *thd;
SEQUENCE_LAST_VALUE *entry;
char buff[80];
String key_buff(buff,sizeof(buff), &my_charset_bin);
- DBUG_ASSERT(table && table->s->sequence);
DBUG_ENTER("Item_func_nextval::val_int");
+ update_table();
+ DBUG_ASSERT(table && table->s->sequence);
+ thd= table->in_use;
+
+ if (thd->count_cuted_fields == CHECK_FIELD_EXPRESSION)
+ {
+ /* Alter table checking if function works */
+ null_value= 0;
+ DBUG_RETURN(0);
+ }
if (table->s->tmp_table != NO_TMP_TABLE)
{
@@ -6895,9 +6811,10 @@ longlong Item_func_nextval::val_int()
void Item_func_nextval::print(String *str, enum_query_type query_type)
{
char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME];
- const char *d_name= table_list->db, *t_name= table_list->table_name;
- bool use_db_name= d_name && d_name[0];
- THD *thd= current_thd;
+ LEX_CSTRING d_name= table_list->db;
+ LEX_CSTRING t_name= table_list->table_name;
+ bool use_db_name= d_name.str && d_name.str[0];
+ THD *thd= current_thd; // Don't trust 'table'
str->append(func_name());
str->append('(');
@@ -6909,23 +6826,23 @@ void Item_func_nextval::print(String *str, enum_query_type query_type)
if (lower_case_table_names > 0)
{
- strmake(t_name_buff, t_name, MAX_ALIAS_NAME-1);
- my_casedn_str(files_charset_info, t_name_buff);
- t_name= t_name_buff;
+ strmake(t_name_buff, t_name.str, MAX_ALIAS_NAME-1);
+ t_name.length= my_casedn_str(files_charset_info, t_name_buff);
+ t_name.str= t_name_buff;
if (use_db_name)
{
- strmake(d_name_buff, d_name, MAX_ALIAS_NAME-1);
- my_casedn_str(files_charset_info, d_name_buff);
- d_name= d_name_buff;
+ strmake(d_name_buff, d_name.str, MAX_ALIAS_NAME-1);
+ d_name.length= my_casedn_str(files_charset_info, d_name_buff);
+ d_name.str= d_name_buff;
}
}
if (use_db_name)
{
- append_identifier(thd, str, d_name, (uint)strlen(d_name));
+ append_identifier(thd, str, &d_name);
str->append('.');
}
- append_identifier(thd, str, t_name, (uint) strlen(t_name));
+ append_identifier(thd, str, &t_name);
str->append(')');
}
@@ -6937,12 +6854,14 @@ longlong Item_func_lastval::val_int()
const char *key;
SEQUENCE_LAST_VALUE *entry;
uint length= get_table_def_key(table_list, &key);
- THD *thd= table_list->table->in_use;
+ THD *thd;
char buff[80];
String key_buff(buff,sizeof(buff), &my_charset_bin);
DBUG_ENTER("Item_func_lastval::val_int");
+ update_table();
+ thd= table->in_use;
- if (table_list->table->s->tmp_table != NO_TMP_TABLE)
+ if (table->s->tmp_table != NO_TMP_TABLE)
{
/*
Temporary tables has an extra \0 at end to distinguish it from
@@ -6961,7 +6880,7 @@ longlong Item_func_lastval::val_int()
null_value= 1;
DBUG_RETURN(0);
}
- if (entry->check_version(table_list->table))
+ if (entry->check_version(table))
{
/* Table droped and re-created, remove current version */
my_hash_delete(&thd->sequences, (uchar*) entry);
@@ -6986,10 +6905,20 @@ longlong Item_func_setval::val_int()
{
longlong value;
int error;
- TABLE *table= table_list->table;
- DBUG_ASSERT(table && table->s->sequence);
+ THD *thd;
DBUG_ENTER("Item_func_setval::val_int");
+ update_table();
+ DBUG_ASSERT(table && table->s->sequence);
+ thd= table->in_use;
+
+ if (thd->count_cuted_fields == CHECK_FIELD_EXPRESSION)
+ {
+ /* Alter table checking if function works */
+ null_value= 0;
+ DBUG_RETURN(0);
+ }
+
value= nextval;
error= table->s->sequence->set_value(table, nextval, round, is_used);
if (error)
@@ -7006,9 +6935,10 @@ longlong Item_func_setval::val_int()
void Item_func_setval::print(String *str, enum_query_type query_type)
{
char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME];
- const char *d_name= table_list->db, *t_name= table_list->table_name;
- bool use_db_name= d_name && d_name[0];
- THD *thd= table_list->table->in_use;
+ LEX_CSTRING d_name= table_list->db;
+ LEX_CSTRING t_name= table_list->table_name;
+ bool use_db_name= d_name.str && d_name.str[0];
+ THD *thd= current_thd; // Don't trust 'table'
str->append(func_name());
str->append('(');
@@ -7020,23 +6950,23 @@ void Item_func_setval::print(String *str, enum_query_type query_type)
if (lower_case_table_names > 0)
{
- strmake(t_name_buff, t_name, MAX_ALIAS_NAME-1);
- my_casedn_str(files_charset_info, t_name_buff);
- t_name= t_name_buff;
+ strmake(t_name_buff, t_name.str, MAX_ALIAS_NAME-1);
+ t_name.length= my_casedn_str(files_charset_info, t_name_buff);
+ t_name.str= t_name_buff;
if (use_db_name)
{
- strmake(d_name_buff, d_name, MAX_ALIAS_NAME-1);
- my_casedn_str(files_charset_info, d_name_buff);
- d_name= d_name_buff;
+ strmake(d_name_buff, d_name.str, MAX_ALIAS_NAME-1);
+ d_name.length= my_casedn_str(files_charset_info, d_name_buff);
+ d_name.str= d_name_buff;
}
}
if (use_db_name)
{
- append_identifier(thd, str, d_name, (uint)strlen(d_name));
+ append_identifier(thd, str, &d_name);
str->append('.');
}
- append_identifier(thd, str, t_name, (uint) strlen(t_name));
+ append_identifier(thd, str, &t_name);
str->append(',');
str->append_longlong(nextval);
str->append(',');
diff --git a/sql/item_func.h b/sql/item_func.h
index c3a717614fb..38a40e71544 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -30,6 +30,9 @@ extern "C" /* Bug in BSDI include file */
}
#endif
+#include "sql_udf.h" // udf_handler
+#include "my_decimal.h" // string2my_decimal
+
class Item_func :public Item_func_or_sum
{
@@ -160,14 +163,9 @@ public:
void print_args(String *str, uint from, enum_query_type query_type);
inline bool get_arg0_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
- return (null_value=args[0]->get_date_with_conversion(ltime, fuzzy_date));
- }
- inline bool get_arg0_time(MYSQL_TIME *ltime)
- {
- null_value= args[0]->get_time(ltime);
- DBUG_ASSERT(null_value ||
- ltime->time_type != MYSQL_TIMESTAMP_TIME || ltime->day == 0);
- return null_value;
+ DBUG_ASSERT(!(fuzzy_date & TIME_TIME_ONLY));
+ Datetime dt(current_thd, args[0], fuzzy_date);
+ return (null_value= dt.copy_to_mysql_time(ltime));
}
bool is_null() {
update_null_value();
@@ -386,6 +384,8 @@ public:
my_decimal *val_decimal(my_decimal *decimal_value);
longlong val_int()
{ DBUG_ASSERT(fixed == 1); return (longlong) rint(val_real()); }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_real(ltime, fuzzydate); }
const Type_handler *type_handler() const { return &type_handler_double; }
void fix_length_and_dec()
{ decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
@@ -445,11 +445,17 @@ class Item_func_hybrid_field_type: public Item_hybrid_func
*/
bool date_op_with_null_check(MYSQL_TIME *ltime)
{
- bool rc= date_op(ltime,
- field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0);
+ bool rc= date_op(ltime, 0);
DBUG_ASSERT(!rc ^ null_value);
return rc;
}
+ bool time_op_with_null_check(MYSQL_TIME *ltime)
+ {
+ bool rc= time_op(ltime);
+ DBUG_ASSERT(!rc ^ null_value);
+ DBUG_ASSERT(rc || ltime->time_type == MYSQL_TIMESTAMP_TIME);
+ return rc;
+ }
String *str_op_with_null_check(String *str)
{
String *res= str_op(str);
@@ -486,32 +492,30 @@ public:
{
return real_op();
}
- bool get_date_from_date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
- {
- return date_op(ltime,
- (fuzzydate |
- (field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0)));
- }
// Value methods that involve conversion
String *val_str_from_decimal_op(String *str);
String *val_str_from_real_op(String *str);
String *val_str_from_int_op(String *str);
String *val_str_from_date_op(String *str);
+ String *val_str_from_time_op(String *str);
my_decimal *val_decimal_from_str_op(my_decimal *dec);
my_decimal *val_decimal_from_real_op(my_decimal *dec);
my_decimal *val_decimal_from_int_op(my_decimal *dec);
my_decimal *val_decimal_from_date_op(my_decimal *dec);
+ my_decimal *val_decimal_from_time_op(my_decimal *dec);
longlong val_int_from_str_op();
longlong val_int_from_real_op();
longlong val_int_from_decimal_op();
longlong val_int_from_date_op();
+ longlong val_int_from_time_op();
double val_real_from_str_op();
double val_real_from_decimal_op();
double val_real_from_date_op();
+ double val_real_from_time_op();
double val_real_from_int_op();
bool get_date_from_str_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
@@ -607,11 +611,18 @@ public:
/**
@brief Performs the operation that this functions implements when
- field type is a temporal type.
+ field type is DATETIME or DATE.
@return The result of the operation.
*/
virtual bool date_op(MYSQL_TIME *res, ulonglong fuzzy_date)= 0;
+ /**
+ @brief Performs the operation that this functions implements when
+ field type is TIME.
+ @return The result of the operation.
+ */
+ virtual bool time_op(MYSQL_TIME *res)= 0;
+
};
@@ -674,6 +685,11 @@ public:
DBUG_ASSERT(0);
return true;
}
+ bool time_op(MYSQL_TIME *ltime)
+ {
+ DBUG_ASSERT(0);
+ return true;
+ }
};
@@ -755,6 +771,8 @@ public:
{ collation.set_numeric(); }
double val_real();
String *val_str(String*str);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_int(ltime, fuzzydate); }
const Type_handler *type_handler() const= 0;
void fix_length_and_dec() {}
};
@@ -819,8 +837,8 @@ public:
{
return Cursor_ref::print_func(str, func_name());
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_cursor_rowcount>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_cursor_rowcount>(thd, this); }
};
@@ -839,8 +857,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_connection_id>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_connection_id>(thd, this); }
};
@@ -896,8 +914,8 @@ public:
virtual void print(String *str, enum_query_type query_type);
uint decimal_precision() const { return args[0]->decimal_precision(); }
bool need_parentheses_in_default() { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_signed>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_signed>(thd, this); }
};
@@ -927,8 +945,8 @@ public:
}
uint decimal_precision() const { return max_length; }
virtual void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_unsigned>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_unsigned>(thd, this); }
};
@@ -948,6 +966,8 @@ public:
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal*);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_decimal(ltime, fuzzydate); }
const Type_handler *type_handler() const { return &type_handler_newdecimal; }
void fix_length_and_dec_generic() {}
void fix_length_and_dec()
@@ -957,8 +977,8 @@ public:
const char *func_name() const { return "decimal_typecast"; }
virtual void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_decimal_typecast>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_decimal_typecast>(thd, this); }
};
@@ -980,12 +1000,11 @@ public:
const char *func_name() const { return "double_typecast"; }
virtual void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_double_typecast>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_double_typecast>(thd, this); }
};
-
class Item_func_additive_op :public Item_num_op
{
public:
@@ -1007,8 +1026,8 @@ public:
longlong int_op();
double real_op();
my_decimal *decimal_op(my_decimal *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_plus>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_plus>(thd, this); }
};
class Item_func_minus :public Item_func_additive_op
@@ -1038,8 +1057,8 @@ public:
Item_func_additive_op::fix_length_and_dec_int();
fix_unsigned_flag();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_minus>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_minus>(thd, this); }
};
@@ -1057,8 +1076,8 @@ public:
void fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_mul>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_mul>(thd, this); }
};
@@ -1076,8 +1095,8 @@ public:
void fix_length_and_dec_double();
void fix_length_and_dec_int();
void result_precision();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_div>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_div>(thd, this); }
};
@@ -1100,8 +1119,8 @@ public:
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
bool need_parentheses_in_default() { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_int_div>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_int_div>(thd, this); }
};
@@ -1135,8 +1154,8 @@ public:
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_mod>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_mod>(thd, this); }
};
@@ -1161,8 +1180,8 @@ public:
void fix_length_and_dec();
uint decimal_precision() const { return args[0]->decimal_precision(); }
bool need_parentheses_in_default() { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_neg>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_neg>(thd, this); }
};
@@ -1178,8 +1197,8 @@ public:
void fix_length_and_dec_double();
void fix_length_and_dec_decimal();
void fix_length_and_dec();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_abs>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_abs>(thd, this); }
};
// A class to handle logarithmic and trigonometric functions
@@ -1204,8 +1223,8 @@ public:
Item_func_exp(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "exp"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_exp>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_exp>(thd, this); }
};
@@ -1215,8 +1234,8 @@ public:
Item_func_ln(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "ln"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_ln>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_ln>(thd, this); }
};
@@ -1227,8 +1246,8 @@ public:
Item_func_log(THD *thd, Item *a, Item *b): Item_dec_func(thd, a, b) {}
double val_real();
const char *func_name() const { return "log"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_log>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_log>(thd, this); }
};
@@ -1238,8 +1257,8 @@ public:
Item_func_log2(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "log2"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_log2>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_log2>(thd, this); }
};
@@ -1249,8 +1268,8 @@ public:
Item_func_log10(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "log10"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_log10>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_log10>(thd, this); }
};
@@ -1260,8 +1279,8 @@ public:
Item_func_sqrt(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "sqrt"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sqrt>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sqrt>(thd, this); }
};
@@ -1271,8 +1290,8 @@ public:
Item_func_pow(THD *thd, Item *a, Item *b): Item_dec_func(thd, a, b) {}
double val_real();
const char *func_name() const { return "pow"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_pow>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_pow>(thd, this); }
};
@@ -1282,8 +1301,8 @@ public:
Item_func_acos(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "acos"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_acos>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_acos>(thd, this); }
};
class Item_func_asin :public Item_dec_func
@@ -1292,8 +1311,8 @@ public:
Item_func_asin(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "asin"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_asin>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_asin>(thd, this); }
};
class Item_func_atan :public Item_dec_func
@@ -1303,8 +1322,8 @@ public:
Item_func_atan(THD *thd, Item *a, Item *b): Item_dec_func(thd, a, b) {}
double val_real();
const char *func_name() const { return "atan"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_atan>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_atan>(thd, this); }
};
class Item_func_cos :public Item_dec_func
@@ -1313,8 +1332,8 @@ public:
Item_func_cos(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "cos"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_cos>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_cos>(thd, this); }
};
class Item_func_sin :public Item_dec_func
@@ -1323,8 +1342,8 @@ public:
Item_func_sin(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "sin"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sin>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sin>(thd, this); }
};
class Item_func_tan :public Item_dec_func
@@ -1333,8 +1352,8 @@ public:
Item_func_tan(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "tan"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_tan>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_tan>(thd, this); }
};
class Item_func_cot :public Item_dec_func
@@ -1343,8 +1362,8 @@ public:
Item_func_cot(THD *thd, Item *a): Item_dec_func(thd, a) {}
double val_real();
const char *func_name() const { return "cot"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_cot>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_cot>(thd, this); }
};
@@ -1366,8 +1385,8 @@ public:
longlong int_op();
double real_op();
my_decimal *decimal_op(my_decimal *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_ceiling>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_ceiling>(thd, this); }
};
@@ -1379,8 +1398,8 @@ public:
longlong int_op();
double real_op();
my_decimal *decimal_op(my_decimal *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_floor>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_floor>(thd, this); }
};
/* This handles round and truncate */
@@ -1404,8 +1423,8 @@ public:
{
args[0]->type_handler()->Item_func_round_fix_length_and_dec(this);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_round>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_round>(thd, this); }
};
@@ -1429,8 +1448,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_rand>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_rand>(thd, this); }
private:
void seed_random (Item * val);
};
@@ -1446,8 +1465,8 @@ public:
uint decimal_precision() const { return 1; }
void fix_length_and_dec() { fix_char_length(2); }
longlong val_int();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sign>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sign>(thd, this); }
};
@@ -1465,8 +1484,8 @@ public:
const char *func_name() const { return name; }
void fix_length_and_dec()
{ decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_units>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_units>(thd, this); }
};
@@ -1496,6 +1515,7 @@ public:
longlong val_int_native();
my_decimal *val_decimal_native(my_decimal *);
bool get_date_native(MYSQL_TIME *res, ulonglong fuzzydate);
+ bool get_time_native(MYSQL_TIME *res);
double val_real()
{
@@ -1560,8 +1580,8 @@ class Item_func_min :public Item_func_min_max
public:
Item_func_min(THD *thd, List<Item> &list): Item_func_min_max(thd, list, 1) {}
const char *func_name() const { return "least"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_min>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_min>(thd, this); }
};
class Item_func_max :public Item_func_min_max
@@ -1569,8 +1589,8 @@ class Item_func_max :public Item_func_min_max
public:
Item_func_max(THD *thd, List<Item> &list): Item_func_min_max(thd, list, -1) {}
const char *func_name() const { return "greatest"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_max>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_max>(thd, this); }
};
@@ -1590,6 +1610,10 @@ public:
longlong val_int() { return args[0]->val_int(); }
String *val_str(String *str) { return args[0]->val_str(str); }
my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return args[0]->get_date(ltime, fuzzydate);
+ }
const char *func_name() const { return "rollup_const"; }
bool const_item() const { return 0; }
const Type_handler *type_handler() const { return args[0]->type_handler(); }
@@ -1601,8 +1625,8 @@ public:
/* The item could be a NULL constant. */
null_value= args[0]->is_null();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_rollup_const>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_rollup_const>(thd, this); }
};
@@ -1623,8 +1647,8 @@ public:
Item_func_octet_length(THD *thd, Item *a): Item_long_func_length(thd, a) {}
longlong val_int();
const char *func_name() const { return "octet_length"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_octet_length>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_octet_length>(thd, this); }
};
class Item_func_bit_length :public Item_longlong_func
@@ -1638,8 +1662,8 @@ public:
}
longlong val_int();
const char *func_name() const { return "bit_length"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_bit_length>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_bit_length>(thd, this); }
};
class Item_func_char_length :public Item_long_func_length
@@ -1649,8 +1673,8 @@ public:
Item_func_char_length(THD *thd, Item *a): Item_long_func_length(thd, a) {}
longlong val_int();
const char *func_name() const { return "char_length"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_char_length>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_char_length>(thd, this); }
};
class Item_func_coercibility :public Item_long_func
@@ -1670,8 +1694,8 @@ public:
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{ return this; }
bool const_item() const { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_coercibility>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_coercibility>(thd, this); }
};
@@ -1703,8 +1727,8 @@ public:
agg_arg_charsets_for_comparison(cmp_collation, args, 2);
}
virtual void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_locate>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_locate>(thd, this); }
};
@@ -1718,8 +1742,8 @@ public:
longlong val_int();
const char *func_name() const { return "field"; }
void fix_length_and_dec();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_field>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_field>(thd, this); }
};
@@ -1733,8 +1757,8 @@ public:
longlong val_int();
const char *func_name() const { return "ascii"; }
void fix_length_and_dec() { max_length=3; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_ascii>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_ascii>(thd, this); }
};
class Item_func_ord :public Item_long_func
@@ -1747,8 +1771,8 @@ public:
void fix_length_and_dec() { fix_char_length(7); }
longlong val_int();
const char *func_name() const { return "ord"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_ord>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_ord>(thd, this); }
};
class Item_func_find_in_set :public Item_long_func
@@ -1765,8 +1789,8 @@ public:
longlong val_int();
const char *func_name() const { return "find_in_set"; }
void fix_length_and_dec();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_find_in_set>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_find_in_set>(thd, this); }
};
/* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */
@@ -1794,8 +1818,8 @@ public:
longlong val_int();
const char *func_name() const { return "|"; }
enum precedence precedence() const { return BITOR_PRECEDENCE; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_bit_or>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_bit_or>(thd, this); }
};
class Item_func_bit_and :public Item_func_bit
@@ -1805,8 +1829,8 @@ public:
longlong val_int();
const char *func_name() const { return "&"; }
enum precedence precedence() const { return BITAND_PRECEDENCE; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_bit_and>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_bit_and>(thd, this); }
};
class Item_func_bit_count :public Item_long_func
@@ -1818,8 +1842,8 @@ public:
longlong val_int();
const char *func_name() const { return "bit_count"; }
void fix_length_and_dec() { max_length=2; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_bit_count>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_bit_count>(thd, this); }
};
class Item_func_shift_left :public Item_func_bit
@@ -1829,8 +1853,8 @@ public:
longlong val_int();
const char *func_name() const { return "<<"; }
enum precedence precedence() const { return SHIFT_PRECEDENCE; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_shift_left>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_shift_left>(thd, this); }
};
class Item_func_shift_right :public Item_func_bit
@@ -1840,8 +1864,8 @@ public:
longlong val_int();
const char *func_name() const { return ">>"; }
enum precedence precedence() const { return SHIFT_PRECEDENCE; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_shift_right>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_shift_right>(thd, this); }
};
class Item_func_bit_neg :public Item_func_bit
@@ -1856,8 +1880,8 @@ public:
str->append(func_name());
args[0]->print_parenthesised(str, query_type, precedence());
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_bit_neg>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_bit_neg>(thd, this); }
};
@@ -1881,8 +1905,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_last_insert_id>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_last_insert_id>(thd, this); }
};
@@ -1905,8 +1929,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_benchmark>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_benchmark>(thd, this); }
};
@@ -1932,8 +1956,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sleep>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sleep>(thd, this); }
};
@@ -2032,6 +2056,10 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
}
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ }
};
@@ -2060,8 +2088,8 @@ class Item_func_udf_float :public Item_udf_func
String *val_str(String *str);
const Type_handler *type_handler() const { return &type_handler_double; }
void fix_length_and_dec() { fix_num_length_and_dec(); }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_udf_float>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_udf_float>(thd, this); }
};
@@ -2078,8 +2106,8 @@ public:
String *val_str(String *str);
const Type_handler *type_handler() const { return &type_handler_longlong; }
void fix_length_and_dec() { decimals= 0; max_length= 21; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_udf_int>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_udf_int>(thd, this); }
};
@@ -2096,8 +2124,8 @@ public:
String *val_str(String *str);
const Type_handler *type_handler() const { return &type_handler_newdecimal; }
void fix_length_and_dec() { fix_num_length_and_dec(); }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_udf_decimal>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_udf_decimal>(thd, this); }
};
@@ -2135,8 +2163,8 @@ public:
}
const Type_handler *type_handler() const { return string_type_handler(); }
void fix_length_and_dec();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_udf_str>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_udf_str>(thd, this); }
};
#else /* Dummy functions to get sql_yacc.cc compiled */
@@ -2218,8 +2246,8 @@ class Item_func_get_lock :public Item_long_func
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_get_lock>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_get_lock>(thd, this); }
};
class Item_func_release_lock :public Item_long_func
@@ -2242,8 +2270,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_release_lock>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_release_lock>(thd, this); }
};
/* replication functions */
@@ -2273,8 +2301,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_master_pos_wait>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_master_pos_wait>(thd, this); }
};
@@ -2298,8 +2326,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_master_gtid_wait>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_master_gtid_wait>(thd, this); }
};
@@ -2329,6 +2357,8 @@ public:
Field *create_field_for_create_select(TABLE *table)
{ return create_table_field_from_handler(table); }
bool check_vcol_func_processor(void *arg);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return type_handler()->Item_get_date(this, ltime, fuzzydate); }
};
@@ -2380,7 +2410,7 @@ public:
String *str_result(String *str);
my_decimal *val_decimal_result(my_decimal *);
bool is_null_result();
- bool update_hash(void *ptr, uint length, enum Item_result type,
+ bool update_hash(void *ptr, size_t length, enum Item_result type,
CHARSET_INFO *cs, bool unsigned_arg);
bool send(Protocol *protocol, st_value *buffer);
void make_field(THD *thd, Send_field *tmp_field);
@@ -2406,8 +2436,8 @@ public:
bool register_field_in_bitmap(void *arg);
bool set_entry(THD *thd, bool create_if_not_exists);
void cleanup();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_set_user_var>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_set_user_var>(thd, this); }
};
@@ -2434,8 +2464,8 @@ public:
table_map used_tables() const
{ return const_item() ? 0 : RAND_TABLE_BIT; }
bool eq(const Item *item, bool binary_cmp) const;
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_get_user_var>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_get_user_var>(thd, this); }
private:
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
@@ -2458,20 +2488,22 @@ public:
*/
class Item_user_var_as_out_param :public Item
{
- LEX_CSTRING name;
+ LEX_CSTRING org_name;
user_var_entry *entry;
public:
Item_user_var_as_out_param(THD *thd, const LEX_CSTRING *a)
- :Item(thd), name(*a)
+ :Item(thd)
{
DBUG_ASSERT(a->length < UINT_MAX32);
- set_name(thd, a->str, (uint) a->length, system_charset_info);
+ org_name= *a;
+ set_name(thd, a->str, a->length, system_charset_info);
}
/* We should return something different from FIELD_ITEM here */
enum Type type() const { return STRING_ITEM;}
double val_real();
longlong val_int();
String *val_str(String *str);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
my_decimal *val_decimal(my_decimal *decimal_buffer);
/* fix_fields() binds variable name with its entry structure */
bool fix_fields(THD *thd, Item **ref);
@@ -2479,8 +2511,8 @@ public:
void set_null_value(CHARSET_INFO* cs);
void set_value(const char *str, uint length, CHARSET_INFO* cs);
const Type_handler *type_handler() const { return &type_handler_double; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_user_var_as_out_param>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_user_var_as_out_param>(thd, this); }
};
@@ -2519,6 +2551,10 @@ public:
String* val_str(String*);
my_decimal *val_decimal(my_decimal *dec_buf)
{ return val_decimal_from_real(dec_buf); }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ }
/* TODO: fix to support views */
const char *func_name() const { return "get_system_var"; }
/**
@@ -2534,8 +2570,8 @@ public:
void cleanup();
bool check_vcol_func_processor(void *arg);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_get_system_var>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_get_system_var>(thd, this); }
};
@@ -2589,9 +2625,9 @@ public:
{
return mark_unsupported_function("match ... against()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_match>(thd, mem_root, this); }
- Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_match>(thd, this); }
+ Item *build_clone(THD *thd) { return 0; }
private:
/**
Check whether storage engine for given table,
@@ -2636,8 +2672,8 @@ public:
longlong val_int();
const char *func_name() const { return "^"; }
enum precedence precedence() const { return BITXOR_PRECEDENCE; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_bit_xor>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_bit_xor>(thd, this); }
};
class Item_func_is_free_lock :public Item_long_func
@@ -2654,8 +2690,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_is_free_lock>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_is_free_lock>(thd, this); }
};
class Item_func_is_used_lock :public Item_long_func
@@ -2672,8 +2708,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_is_used_lock>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_is_used_lock>(thd, this); }
};
@@ -2721,8 +2757,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_row_count>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_row_count>(thd, this); }
};
@@ -2732,26 +2768,12 @@ public:
*
*/
-class sp_head;
-class sp_name;
-struct st_sp_security_context;
-
-class Item_func_sp :public Item_func
+class Item_func_sp :public Item_func,
+ public Item_sp
{
private:
- Name_resolution_context *context;
- sp_name *m_name;
- mutable sp_head *m_sp;
- TABLE *dummy_table;
- uchar result_buf[64];
- /*
- The result field of the concrete stored function.
- */
- Field *sp_result_field;
bool execute();
- bool execute_impl(THD *thd);
- bool init_result_field(THD *thd, sp_head *sp);
protected:
bool is_expensive_processor(void *arg)
@@ -2843,7 +2865,6 @@ public:
virtual bool change_context_processor(void *cntx)
{ context= (Name_resolution_context *)cntx; return FALSE; }
- bool sp_check_access(THD * thd);
virtual enum Functype functype() const { return FUNC_SP; }
bool fix_fields(THD *thd, Item **ref);
@@ -2864,11 +2885,11 @@ public:
{
return TRUE;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sp>(thd, mem_root, this); }
- Item *build_clone(THD *thd, MEM_ROOT *mem_root)
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sp>(thd, this); }
+ Item *build_clone(THD *thd)
{
- Item_func_sp *clone= (Item_func_sp *) Item_func::build_clone(thd, mem_root);
+ Item_func_sp *clone= (Item_func_sp *) Item_func::build_clone(thd);
if (clone)
clone->sp_result_field= NULL;
return clone;
@@ -2892,8 +2913,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_found_rows>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_found_rows>(thd, this); }
};
@@ -2911,8 +2932,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_oracle_sql_rowcount>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_oracle_sql_rowcount>(thd, this); }
};
@@ -2935,8 +2956,8 @@ public:
maybe_null= null_value= false;
max_length= 11;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sqlcode>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sqlcode>(thd, this); }
};
@@ -2955,8 +2976,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_uuid_short>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_uuid_short>(thd, this); }
};
@@ -2970,6 +2991,7 @@ public:
longlong val_int();
String *val_str(String *);
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
void fix_length_and_dec();
const char *func_name() const { return "last_value"; }
const Type_handler *type_handler() const { return last_value->type_handler(); }
@@ -2985,8 +3007,8 @@ public:
Item_func::update_used_tables();
maybe_null= last_value->maybe_null;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_last_value>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_last_value>(thd, this); }
};
@@ -2996,9 +3018,10 @@ class Item_func_nextval :public Item_longlong_func
{
protected:
TABLE_LIST *table_list;
+ TABLE *table;
public:
- Item_func_nextval(THD *thd, TABLE_LIST *table):
- Item_longlong_func(thd), table_list(table) {}
+ Item_func_nextval(THD *thd, TABLE_LIST *table_list_arg):
+ Item_longlong_func(thd), table_list(table_list_arg) {}
longlong val_int();
const char *func_name() const { return "nextval"; }
void fix_length_and_dec()
@@ -3007,14 +3030,31 @@ public:
max_length= MAX_BIGINT_WIDTH;
maybe_null= 1; /* In case of errors */
}
+ /*
+ update_table() function must be called during the value function
+ as in case of DEFAULT the sequence table may not yet be open
+ while fix_fields() are called
+ */
+ void update_table()
+ {
+ if (!(table= table_list->table))
+ {
+ /*
+ If nextval was used in DEFAULT then next_local points to
+ the table_list used by to open the sequence table
+ */
+ table= table_list->next_local->table;
+ }
+ }
bool const_item() const { return 0; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_nextval>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_nextval>(thd, this); }
void print(String *str, enum_query_type query_type);
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg,
- VCOL_NON_DETERMINISTIC);
+ (VCOL_NON_DETERMINISTIC |
+ VCOL_NOT_VIRTUAL));
}
};
@@ -3024,12 +3064,12 @@ public:
class Item_func_lastval :public Item_func_nextval
{
public:
- Item_func_lastval(THD *thd, TABLE_LIST *table):
- Item_func_nextval(thd, table) {}
+ Item_func_lastval(THD *thd, TABLE_LIST *table_list_arg):
+ Item_func_nextval(thd, table_list_arg) {}
longlong val_int();
const char *func_name() const { return "lastval"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_lastval>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_lastval>(thd, this); }
};
@@ -3041,16 +3081,16 @@ class Item_func_setval :public Item_func_nextval
ulonglong round;
bool is_used;
public:
- Item_func_setval(THD *thd, TABLE_LIST *table, longlong nextval_arg,
+ Item_func_setval(THD *thd, TABLE_LIST *table_list_arg, longlong nextval_arg,
ulonglong round_arg, bool is_used_arg)
- : Item_func_nextval(thd, table),
+ : Item_func_nextval(thd, table_list_arg),
nextval(nextval_arg), round(round_arg), is_used(is_used_arg)
{}
longlong val_int();
const char *func_name() const { return "setval"; }
void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_setval>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_setval>(thd, this); }
};
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index a060ed221bf..aee44a7a01f 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -165,6 +165,9 @@ String *Item_func_geometry_from_json::val_str(String *str)
case Geometry::GEOJ_TOO_FEW_POINTS:
code= ER_GEOJSON_TOO_FEW_POINTS;
break;
+ case Geometry::GEOJ_EMPTY_COORDINATES:
+ code= ER_GEOJSON_EMPTY_COORDINATES;
+ break;
case Geometry::GEOJ_POLYGON_NOT_CLOSED:
code= ER_GEOJSON_NOT_CLOSED;
break;
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index d332d067c37..8101433abb5 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -202,8 +202,8 @@ public:
Item_geometry_func(thd, a, srid) {}
const char *func_name() const { return "st_geometryfromtext"; }
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_geometry_from_text>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_geometry_from_text>(thd, this); }
};
class Item_func_geometry_from_wkb: public Item_geometry_func
@@ -219,8 +219,8 @@ public:
Item_geometry_func(thd, a, srid) {}
const char *func_name() const { return "st_geometryfromwkb"; }
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_geometry_from_wkb>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_geometry_from_wkb>(thd, this); }
};
@@ -241,8 +241,8 @@ public:
Item_geometry_func(thd, js, opt, srid) {}
const char *func_name() const { return "st_geomfromgeojson"; }
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_geometry_from_json>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_geometry_from_json>(thd, this); }
};
@@ -254,8 +254,8 @@ public:
const char *func_name() const { return "st_astext"; }
String *val_str_ascii(String *);
void fix_length_and_dec();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_as_wkt>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_as_wkt>(thd, this); }
};
class Item_func_as_wkb: public Item_binary_func_args_geometry
@@ -273,8 +273,8 @@ public:
max_length= (uint32) UINT_MAX32;
maybe_null= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_as_wkb>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_as_wkb>(thd, this); }
};
@@ -296,8 +296,8 @@ public:
const char *func_name() const { return "st_asgeojson"; }
void fix_length_and_dec();
String *val_str_ascii(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_as_geojson>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_as_geojson>(thd, this); }
};
@@ -314,8 +314,8 @@ public:
fix_length_and_charset(20, default_charset());
maybe_null= 1;
};
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_geometry_type>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_geometry_type>(thd, this); }
};
@@ -349,8 +349,8 @@ public:
{}
const char *func_name() const { return "st_convexhull"; }
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_convexhull>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_convexhull>(thd, this); }
};
@@ -362,8 +362,8 @@ public:
const char *func_name() const { return "st_centroid"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_centroid>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_centroid>(thd, this); }
};
class Item_func_envelope: public Item_geometry_func_args_geometry
@@ -374,8 +374,8 @@ public:
const char *func_name() const { return "st_envelope"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_envelope>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_envelope>(thd, this); }
};
@@ -408,8 +408,8 @@ public:
:Item_geometry_func_args_geometry(thd, a) {}
const char *func_name() const { return "st_boundary"; }
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_boundary>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_boundary>(thd, this); }
};
@@ -424,8 +424,8 @@ public:
const char *func_name() const { return "point"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_point>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_point>(thd, this); }
};
class Item_func_spatial_decomp: public Item_geometry_func_args_geometry
@@ -450,8 +450,8 @@ public:
}
}
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_spatial_decomp>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_spatial_decomp>(thd, this); }
};
class Item_func_spatial_decomp_n: public Item_geometry_func_args_geometry
@@ -483,8 +483,8 @@ public:
}
}
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_spatial_decomp_n>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_spatial_decomp_n>(thd, this); }
};
class Item_func_spatial_collection: public Item_geometry_func
@@ -521,8 +521,8 @@ public:
}
const char *func_name() const { return "geometrycollection"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_spatial_collection>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_spatial_collection>(thd, this); }
};
@@ -571,7 +571,7 @@ public:
usable_tables, sargables, false);
}
bool need_parentheses_in_default() { return false; }
- Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item *build_clone(THD *thd) { return 0; }
};
@@ -583,8 +583,8 @@ public:
{ }
longlong val_int();
const char *func_name() const;
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_spatial_mbr_rel>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_spatial_mbr_rel>(thd, this); }
};
@@ -599,8 +599,8 @@ public:
{ }
longlong val_int();
const char *func_name() const;
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_spatial_precise_rel>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_spatial_precise_rel>(thd, this); }
};
@@ -622,8 +622,8 @@ public:
longlong val_int();
const char *func_name() const { return "st_relate"; }
bool need_parentheses_in_default() { return false; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_spatial_relate>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_spatial_relate>(thd, this); }
};
@@ -658,8 +658,8 @@ public:
{
Item_func::print(str, query_type);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_spatial_operation>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_spatial_operation>(thd, this); }
};
@@ -715,8 +715,8 @@ public:
:Item_geometry_func_args_geometry(thd, obj, distance) {}
const char *func_name() const { return "st_buffer"; }
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_buffer>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_buffer>(thd, this); }
};
@@ -729,8 +729,8 @@ public:
const char *func_name() const { return "st_isempty"; }
void fix_length_and_dec() { maybe_null= 1; }
bool need_parentheses_in_default() { return false; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_isempty>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_isempty>(thd, this); }
};
class Item_func_issimple: public Item_long_func_args_geometry
@@ -746,8 +746,8 @@ public:
const char *func_name() const { return "st_issimple"; }
void fix_length_and_dec() { decimals=0; max_length=2; }
uint decimal_precision() const { return 1; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_issimple>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_issimple>(thd, this); }
};
class Item_func_isclosed: public Item_long_func_args_geometry
@@ -759,8 +759,8 @@ public:
const char *func_name() const { return "st_isclosed"; }
void fix_length_and_dec() { decimals=0; max_length=2; }
uint decimal_precision() const { return 1; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_isclosed>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_isclosed>(thd, this); }
};
class Item_func_isring: public Item_func_issimple
@@ -769,8 +769,8 @@ public:
Item_func_isring(THD *thd, Item *a): Item_func_issimple(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_isring"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_isring>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_isring>(thd, this); }
};
class Item_func_dimension: public Item_long_func_args_geometry
@@ -781,8 +781,8 @@ public:
longlong val_int();
const char *func_name() const { return "st_dimension"; }
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_dimension>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_dimension>(thd, this); }
};
@@ -797,8 +797,8 @@ public:
Item_real_func::fix_length_and_dec();
maybe_null= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_x>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_x>(thd, this); }
};
@@ -813,8 +813,8 @@ public:
Item_real_func::fix_length_and_dec();
maybe_null= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_y>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_y>(thd, this); }
};
@@ -826,8 +826,8 @@ public:
longlong val_int();
const char *func_name() const { return "st_numgeometries"; }
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_numgeometries>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_numgeometries>(thd, this); }
};
@@ -839,8 +839,8 @@ public:
longlong val_int();
const char *func_name() const { return "st_numinteriorrings"; }
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_numinteriorring>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_numinteriorring>(thd, this); }
};
@@ -852,8 +852,8 @@ public:
longlong val_int();
const char *func_name() const { return "st_numpoints"; }
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_numpoints>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_numpoints>(thd, this); }
};
@@ -868,8 +868,8 @@ public:
Item_real_func::fix_length_and_dec();
maybe_null= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_area>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_area>(thd, this); }
};
@@ -886,8 +886,8 @@ public:
Item_real_func::fix_length_and_dec();
maybe_null= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_glength>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_glength>(thd, this); }
};
@@ -899,8 +899,8 @@ public:
longlong val_int();
const char *func_name() const { return "srid"; }
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_srid>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_srid>(thd, this); }
};
@@ -916,8 +916,8 @@ public:
:Item_real_func_args_geometry_geometry(thd, a, b) {}
double val_real();
const char *func_name() const { return "st_distance"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_distance>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_distance>(thd, this); }
};
@@ -933,8 +933,8 @@ public:
const char *func_name() const { return "st_pointonsurface"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_pointonsurface>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_pointonsurface>(thd, this); }
};
@@ -951,8 +951,8 @@ class Item_func_gis_debug: public Item_long_func
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_gis_debug>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_gis_debug>(thd, this); }
};
#endif
diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h
index bd0a95b5270..d934cef43dd 100644
--- a/sql/item_inetfunc.h
+++ b/sql/item_inetfunc.h
@@ -39,8 +39,8 @@ public:
maybe_null= 1;
unsigned_flag= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_inet_aton>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_inet_aton>(thd, this); }
};
@@ -61,8 +61,8 @@ public:
fix_length_and_charset(3 * 8 + 7, default_charset());
maybe_null= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_inet_ntoa>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_inet_ntoa>(thd, this); }
};
@@ -130,8 +130,8 @@ public:
fix_length_and_charset(16, &my_charset_bin);
maybe_null= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_inet6_aton>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_inet6_aton>(thd, this); }
protected:
virtual bool calc_value(const String *arg, String *buffer);
@@ -164,8 +164,8 @@ public:
maybe_null= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_inet6_ntoa>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_inet6_ntoa>(thd, this); }
protected:
virtual bool calc_value(const String *arg, String *buffer);
@@ -186,8 +186,8 @@ public:
public:
virtual const char *func_name() const
{ return "is_ipv4"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_is_ipv4>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_is_ipv4>(thd, this); }
protected:
virtual bool calc_value(const String *arg);
@@ -208,8 +208,8 @@ public:
public:
virtual const char *func_name() const
{ return "is_ipv6"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_is_ipv6>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_is_ipv6>(thd, this); }
protected:
virtual bool calc_value(const String *arg);
@@ -230,8 +230,8 @@ public:
public:
virtual const char *func_name() const
{ return "is_ipv4_compat"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_is_ipv4_compat>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_is_ipv4_compat>(thd, this); }
protected:
virtual bool calc_value(const String *arg);
@@ -252,8 +252,8 @@ public:
public:
virtual const char *func_name() const
{ return "is_ipv4_mapped"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_is_ipv4_mapped>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_is_ipv4_mapped>(thd, this); }
protected:
virtual bool calc_value(const String *arg);
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index 54ffa5a2e63..4b2de7cf28b 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -69,6 +69,7 @@ static inline bool append_simple(String *s, const uchar *a, size_t a_len)
/*
Appends JSON string to the String object taking charsets in
consideration.
+*/
static int st_append_json(String *s,
CHARSET_INFO *json_cs, const uchar *js, uint js_len)
{
@@ -82,9 +83,8 @@ static int st_append_json(String *s,
return 0;
}
- return js_len;
+ return str_len;
}
-*/
/*
@@ -475,6 +475,9 @@ String *Item_func_json_value::val_str(String *str)
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length());
+ str->length(0);
+ str->set_charset(&my_charset_utf8mb4_bin);
+
path.cur_step= path.p.steps;
continue_search:
if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
@@ -515,8 +518,7 @@ bool Item_func_json_value::check_and_get_value(json_engine_t *je, String *res,
return true;
}
- res->set((const char *) je->value, je->value_len, je->s.cs);
- return false;
+ return st_append_json(res, je->s.cs, je->value, je->value_len);
}
@@ -779,10 +781,10 @@ String *Item_func_json_extract::read_json(String *str,
{
str->set_charset(js->charset());
str->length(0);
- }
- if (possible_multiple_values && str->append("[", 1))
- goto error;
+ if (possible_multiple_values && str->append("[", 1))
+ goto error;
+ }
json_get_path_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length(), &p);
diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h
index 77e7588be25..354de69eee4 100644
--- a/sql/item_jsonfunc.h
+++ b/sql/item_jsonfunc.h
@@ -54,8 +54,8 @@ public:
Item_bool_func::fix_length_and_dec();
maybe_null= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_valid>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_valid>(thd, this); }
};
@@ -70,8 +70,8 @@ public:
Item_bool_func(thd, js, i_path) {}
const char *func_name() const { return "json_exists"; }
void fix_length_and_dec();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_exists>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_exists>(thd, this); }
longlong val_int();
};
@@ -89,8 +89,8 @@ public:
void fix_length_and_dec();
String *val_str(String *);
virtual bool check_and_get_value(json_engine_t *je, String *res, int *error);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_value>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_value>(thd, this); }
};
@@ -102,8 +102,8 @@ public:
bool is_json_type() { return true; }
const char *func_name() const { return "json_query"; }
bool check_and_get_value(json_engine_t *je, String *res, int *error);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_query>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_query>(thd, this); }
};
@@ -117,8 +117,8 @@ public:
const char *func_name() const { return "json_quote"; }
void fix_length_and_dec();
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_quote>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_quote>(thd, this); }
};
@@ -132,8 +132,8 @@ public:
const char *func_name() const { return "json_unquote"; }
void fix_length_and_dec();
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_unquote>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_unquote>(thd, this); }
};
@@ -168,8 +168,8 @@ public:
longlong val_int();
double val_real();
uint get_n_paths() const { return arg_count - 1; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_extract>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_extract>(thd, this); }
};
@@ -187,8 +187,8 @@ public:
const char *func_name() const { return "json_contains"; }
void fix_length_and_dec();
longlong val_int();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_contains>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_contains>(thd, this); }
};
@@ -210,8 +210,8 @@ public:
void fix_length_and_dec();
void cleanup();
longlong val_int();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_contains_path>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_contains_path>(thd, this); }
};
@@ -229,8 +229,8 @@ public:
bool is_json_type() { return true; }
void fix_length_and_dec();
const char *func_name() const { return "json_array"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_array>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_array>(thd, this); }
};
@@ -246,8 +246,8 @@ public:
String *val_str(String *);
uint get_n_paths() const { return arg_count/2; }
const char *func_name() const { return "json_array_append"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_array_append>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_array_append>(thd, this); }
};
@@ -258,8 +258,8 @@ public:
Item_func_json_array_append(thd, list) {}
String *val_str(String *);
const char *func_name() const { return "json_array_insert"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_array_insert>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_array_insert>(thd, this); }
};
@@ -273,8 +273,8 @@ public:
String *val_str(String *);
bool is_json_type() { return true; }
const char *func_name() const { return "json_object"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_object>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_object>(thd, this); }
};
@@ -288,8 +288,8 @@ public:
String *val_str(String *);
bool is_json_type() { return true; }
const char *func_name() const { return "json_merge"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_merge>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_merge>(thd, this); }
};
@@ -311,8 +311,8 @@ public:
const char *func_name() const { return "json_length"; }
void fix_length_and_dec();
longlong val_int();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_length>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_length>(thd, this); }
};
@@ -327,8 +327,8 @@ public:
const char *func_name() const { return "json_depth"; }
void fix_length_and_dec() { max_length= 10; }
longlong val_int();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_depth>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_depth>(thd, this); }
};
@@ -341,8 +341,8 @@ public:
const char *func_name() const { return "json_type"; }
void fix_length_and_dec();
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_type>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_type>(thd, this); }
};
@@ -364,8 +364,8 @@ public:
return mode_insert ?
(mode_replace ? "json_set" : "json_insert") : "json_update";
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_insert>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_insert>(thd, this); }
};
@@ -380,8 +380,8 @@ public:
String *val_str(String *);
uint get_n_paths() const { return arg_count - 1; }
const char *func_name() const { return "json_remove"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_remove>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_remove>(thd, this); }
};
@@ -397,8 +397,8 @@ public:
const char *func_name() const { return "json_keys"; }
void fix_length_and_dec();
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_keys>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_keys>(thd, this); }
};
@@ -422,8 +422,8 @@ public:
void fix_length_and_dec();
String *val_str(String *);
uint get_n_paths() const { return arg_count > 4 ? arg_count - 4 : 0; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_search>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_search>(thd, this); }
};
@@ -451,8 +451,8 @@ public:
String *val_str(String *str);
String *val_json(String *str);
bool is_json_type() { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_json_format>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_json_format>(thd, this); }
};
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 9c029b16292..64794093bec 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -64,7 +64,7 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
with_sum_func= with_sum_func || item->with_sum_func;
with_window_func = with_window_func || item->with_window_func;
with_field= with_field || item->with_field;
- with_subselect|= item->with_subselect;
+ m_with_subquery|= item->with_subquery();
}
fixed= 1;
return FALSE;
@@ -163,15 +163,15 @@ void Item_row::bring_value()
}
-Item* Item_row::build_clone(THD *thd, MEM_ROOT *mem_root)
+Item* Item_row::build_clone(THD *thd)
{
- Item_row *copy= (Item_row *) get_copy(thd, mem_root);
+ Item_row *copy= (Item_row *) get_copy(thd);
if (!copy)
return 0;
- copy->args= (Item**) alloc_root(mem_root, sizeof(Item*) * arg_count);
+ copy->args= (Item**) alloc_root(thd->mem_root, sizeof(Item*) * arg_count);
for (uint i= 0; i < arg_count; i++)
{
- Item *arg_clone= args[i]->build_clone(thd, mem_root);
+ Item *arg_clone= args[i]->build_clone(thd);
if (!arg_clone)
return 0;
copy->args[i]= arg_clone;
diff --git a/sql/item_row.h b/sql/item_row.h
index a6fdd2b212c..064cb0782b1 100644
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@ -35,7 +35,8 @@
*/
class Item_row: public Item,
private Item_args,
- private Used_tables_and_const_cache
+ private Used_tables_and_const_cache,
+ private With_subquery_cache
{
table_map not_null_tables_cache;
/**
@@ -52,6 +53,7 @@ public:
not_null_tables_cache(0), with_null(0)
{ }
+ bool with_subquery() const { DBUG_ASSERT(fixed); return m_with_subquery; }
enum Type type() const { return ROW_ITEM; };
const Type_handler *type_handler() const { return &type_handler_row; }
void illegal_method_call(const char *);
@@ -80,6 +82,11 @@ public:
illegal_method_call((const char*)"val_decimal");
return 0;
};
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ illegal_method_call((const char*)"get_date");
+ return true;
+ }
bool fix_fields(THD *thd, Item **ref);
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
void cleanup();
@@ -128,9 +135,9 @@ public:
}
bool check_vcol_func_processor(void *arg) {return FALSE; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_row>(thd, mem_root, this); }
- Item *build_clone(THD *thd, MEM_ROOT *mem_root);
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_row>(thd, this); }
+ Item *build_clone(THD *thd);
};
#endif /* ITEM_ROW_INCLUDED */
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 90bfb11e822..7c32fde72fe 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2017, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, MariaDB
+ Copyright (c) 2009, 2018, 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
@@ -202,9 +202,9 @@ String *Item_func_sha2::val_str_ascii(String *str)
const char *input_ptr;
size_t input_len;
+ input_string= args[0]->val_str(str);
str->set_charset(&my_charset_bin);
- input_string= args[0]->val_str(str);
if (input_string == NULL)
{
null_value= TRUE;
@@ -527,14 +527,14 @@ String *Item_func_decode_histogram::val_str(String *str)
DBUG_ASSERT(0);
}
/* show delta with previous value */
- int size= my_snprintf(numbuf, sizeof(numbuf),
+ size_t size= my_snprintf(numbuf, sizeof(numbuf),
representation_by_type[type], val - prev);
str->append(numbuf, size);
str->append(",");
prev= val;
}
/* show delta with max */
- int size= my_snprintf(numbuf, sizeof(numbuf),
+ size_t size= my_snprintf(numbuf, sizeof(numbuf),
representation_by_type[type], 1.0 - prev);
str->append(numbuf, size);
@@ -545,99 +545,106 @@ String *Item_func_decode_histogram::val_str(String *str)
///////////////////////////////////////////////////////////////////////////////
+/*
+ Realloc the result buffer.
+ NOTE: We should be prudent in the initial allocation unit -- the
+ size of the arguments is a function of data distribution, which
+ can be any. Instead of overcommitting at the first row, we grow
+ the allocated amount by the factor of 2. This ensures that no
+ more than 25% of memory will be overcommitted on average.
+
+ @param IN/OUT str - the result string
+ @param IN length - new total space required in "str"
+ @retval false - on success
+ @retval true - on error
+*/
+
+bool Item_func_concat::realloc_result(String *str, uint length) const
+{
+ if (str->alloced_length() >= length)
+ return false; // Alloced space is big enough, nothing to do.
+
+ if (str->alloced_length() == 0)
+ return str->alloc(length);
+
+ /*
+ Item_func_concat::val_str() makes sure the result length does not grow
+ higher than max_allowed_packet. So "length" is limited to 1G here.
+ We can't say anything about the current value of str->alloced_length(),
+ as str was initially set by args[0]->val_str(str).
+ So multiplication by 2 can overflow, if args[0] for some reasons
+ did not limit the result to max_alloced_packet. But it's not harmful,
+ "str" will be realloced exactly to "length" bytes in case of overflow.
+ */
+ uint new_length= MY_MAX(str->alloced_length() * 2, length);
+ return str->realloc(new_length);
+}
+
+
/**
Concatenate args with the following premises:
If only one arg (which is ok), return value of arg;
- Don't reallocate val_str() if not absolute necessary.
*/
String *Item_func_concat::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
THD *thd= current_thd;
- String *res,*use_as_buff;
- uint i;
- bool is_const= 0;
+ String *res;
null_value=0;
- if (!(res= arg_val_str(0, str, &is_const)))
+ if (!(res= args[0]->val_str(str)))
goto null;
- use_as_buff= &tmp_value;
- for (i=1 ; i < arg_count ; i++)
+
+ if (res != str)
+ str->copy(res->ptr(), res->length(), res->charset());
+
+ for (uint i= 1 ; i < arg_count ; i++)
{
- if (res->length() == 0)
- {
- /*
- CONCAT accumulates its result in the result of its the first
- non-empty argument. Because of this we need is_const to be
- evaluated only for it.
- */
- if (!(res= arg_val_str(i, str, &is_const)))
- goto null;
- }
- else
- {
- const String *res2;
- if (!(res2=args[i]->val_str(use_as_buff)))
- goto null;
- if (res2->length() == 0)
- continue;
- if (!(res= append_value(thd, res, is_const, str, &use_as_buff, res2)))
- goto null;
- is_const= 0;
- }
+ if (!(res= args[i]->val_str(&tmp_value)) ||
+ append_value(thd, str, res))
+ goto null;
}
- res->set_charset(collation.collation);
- return res;
+
+ str->set_charset(collation.collation);
+ return str;
null:
- null_value=1;
+ null_value= true;
return 0;
}
String *Item_func_concat_operator_oracle::val_str(String *str)
{
- THD *thd= current_thd;
DBUG_ASSERT(fixed == 1);
- String *res, *use_as_buff;
+ THD *thd= current_thd;
+ String *res;
uint i;
- bool is_const= false;
- null_value= 0;
+ null_value=0;
// Search first non null argument
for (i= 0; i < arg_count; i++)
{
- if ((res= arg_val_str(i, str, &is_const)))
+ if ((res= args[i]->val_str(str)))
break;
}
if (i == arg_count)
goto null;
- use_as_buff= &tmp_value;
+ if (res != str)
+ str->copy(res->ptr(), res->length(), res->charset());
for (i++ ; i < arg_count ; i++)
{
- if (res->length() == 0)
- {
- // See comments in Item_func_concat::val_str()
- String *tmp;
- if (!(tmp= arg_val_str(i, str, &is_const)))
- continue;
- res= tmp;
- }
- else
- {
- const String *res2;
- if (!(res2= args[i]->val_str(use_as_buff)) || res2->length() == 0)
- continue;
- if (!(res= append_value(thd, res, is_const, str, &use_as_buff, res2)))
- goto null;
- is_const= 0;
- }
+ if (!(res= args[i]->val_str(&tmp_value)) || res->length() == 0)
+ continue;
+ if (append_value(thd, str, res))
+ goto null;
}
- res->set_charset(collation.collation);
- return res;
+
+ str->set_charset(collation.collation);
+ return str;
null:
null_value= true;
@@ -645,115 +652,21 @@ null:
}
-String *Item_func_concat::append_value(THD *thd,
- String *res,
- bool res_is_const,
- String *str,
- String **use_as_buff,
- const String *res2)
+bool Item_func_concat::append_value(THD *thd, String *res, const String *app)
{
- DBUG_ASSERT(res2->length() > 0);
-
- if ((ulong) res->length() + (ulong) res2->length() >
+ uint concat_len;
+ if ((concat_len= res->length() + app->length()) >
thd->variables.max_allowed_packet)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
- ER_THD(thd, ER_WARN_ALLOWED_PACKET_OVERFLOWED),
- func_name(),
+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
thd->variables.max_allowed_packet);
- return NULL;
- }
-
- uint32 concat_len= res->length() + res2->length();
-
- if (!res_is_const && res->alloced_length() >= concat_len)
- { // Use old buffer
- return res->append(*res2) ? NULL : res;
- }
-
- if (str->alloced_length() >= concat_len)
- {
- if (str->ptr() == res2->ptr())
- {
- if (str->replace(0, 0, *res))
- return NULL;
- }
- else
- {
- if (str->copy(*res) || str->append(*res2))
- return NULL;
- }
- *use_as_buff= &tmp_value;
- return str;
+ return true;
}
-
- if (res == &tmp_value)
- {
- if (res->append(*res2)) // Must be a blob
- return NULL;
- return res;
- }
-
- if (res2 == &tmp_value)
- { // This can happend only 1 time
- if (tmp_value.replace(0, 0, *res))
- return NULL;
- *use_as_buff= str; // Put next arg here
- return &tmp_value;
- }
-
- if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
- res2->ptr() <= tmp_value.ptr() + tmp_value.alloced_length())
- {
- /*
- This happens really seldom:
- In this case res2 is sub string of tmp_value. We will
- now work in place in tmp_value to set it to res | res2
- */
- /* Chop the last characters in tmp_value that isn't in res2 */
- tmp_value.length((uint32) (res2->ptr() - tmp_value.ptr()) +
- res2->length());
- /* Place res2 at start of tmp_value, remove chars before res2 */
- if (tmp_value.replace(0,(uint32) (res2->ptr() - tmp_value.ptr()),
- *res))
- return NULL;
- *use_as_buff= str; // Put next arg here
- return &tmp_value;
- }
-
- /*
- Two big const strings
- NOTE: We should be prudent in the initial allocation unit -- the
- size of the arguments is a function of data distribution, which
- can be any. Instead of overcommitting at the first row, we grow
- the allocated amount by the factor of 2. This ensures that no
- more than 25% of memory will be overcommitted on average.
- */
-
- if (tmp_value.alloced_length() < concat_len)
- {
- if (tmp_value.alloced_length() == 0)
- {
- if (tmp_value.alloc(concat_len))
- return NULL;
- }
- else
- {
- uint32 new_len= tmp_value.alloced_length() > INT_MAX32 ?
- UINT_MAX32 - 1 :
- tmp_value.alloced_length() * 2;
- set_if_bigger(new_len, concat_len);
- if (tmp_value.realloc(new_len))
- return NULL;
- }
- }
-
- if (tmp_value.copy(*res) || tmp_value.append(*res2))
- return NULL;
-
- *use_as_buff= str;
- return &tmp_value;
+ DBUG_ASSERT(!res->uses_buffer_owned_by(app));
+ DBUG_ASSERT(!app->uses_buffer_owned_by(res));
+ return realloc_result(res, concat_len) || res->append(*app);
}
@@ -1651,7 +1564,7 @@ String *Item_str_conv::val_str(String *str)
null_value=0;
if (multiply == 1)
{
- uint len;
+ size_t len;
res= copy_if_not_alloced(&tmp_value, res, res->length());
len= converter(collation.collation, (char*) res->ptr(), res->length(),
(char*) res->ptr(), res->length());
@@ -1660,7 +1573,7 @@ String *Item_str_conv::val_str(String *str)
}
else
{
- uint len= res->length() * multiply;
+ size_t len= res->length() * multiply;
tmp_value.alloc(len);
tmp_value.set_charset(collation.collation);
len= converter(collation.collation, (char*) res->ptr(), res->length(),
@@ -2276,9 +2189,8 @@ char *Item_func_password::alloc(THD *thd, const char *password,
String *Item_func_encrypt::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- String *res =args[0]->val_str(str);
-
#ifdef HAVE_CRYPT
+ String *res =args[0]->val_str(str);
char salt[3],*salt_ptr;
if ((null_value=args[0]->null_value))
return 0;
@@ -2383,13 +2295,13 @@ String *Item_func_database::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
THD *thd= current_thd;
- if (thd->db == NULL)
+ if (thd->db.str == NULL)
{
null_value= 1;
return 0;
}
else
- str->copy(thd->db, thd->db_length, system_charset_info);
+ str->copy(thd->db.str, thd->db.length, system_charset_info);
null_value= 0;
return str;
}
@@ -2408,7 +2320,7 @@ String *Item_func_sqlerrm::val_str(String *str)
system_charset_info);
return str;
}
- str->copy(C_STRING_WITH_LEN("normal, successful completition"),
+ str->copy(STRING_WITH_LEN("normal, successful completition"),
system_charset_info);
return str;
}
@@ -2918,6 +2830,20 @@ String *Item_func_make_set::val_str(String *str)
}
+void Item_func_char::print(String *str, enum_query_type query_type)
+{
+ str->append(Item_func_char::func_name());
+ str->append('(');
+ print_args(str, 0, query_type);
+ if (collation.collation != &my_charset_bin)
+ {
+ str->append(STRING_WITH_LEN(" using "));
+ str->append(collation.collation->csname);
+ }
+ str->append(')');
+}
+
+
String *Item_func_char::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
@@ -3604,10 +3530,10 @@ void Item_func_weight_string::fix_length_and_dec()
*/
if (!(max_length= result_length))
{
- uint char_length;
+ size_t char_length;
char_length= ((cs->state & MY_CS_STRNXFRM_BAD_NWEIGHTS) || !nweights) ?
args[0]->max_char_length() : nweights * cs->levels_for_order;
- max_length= cs->coll->strnxfrmlen(cs, char_length * cs->mbmaxlen);
+ max_length= (uint32)cs->coll->strnxfrmlen(cs, char_length * cs->mbmaxlen);
}
maybe_null= 1;
}
@@ -3618,7 +3544,7 @@ String *Item_func_weight_string::val_str(String *str)
{
String *res;
CHARSET_INFO *cs= args[0]->collation.collation;
- uint tmp_length, frm_length;
+ size_t tmp_length, frm_length;
DBUG_ASSERT(fixed == 1);
if (args[0]->result_type() != STRING_RESULT ||
@@ -3632,7 +3558,7 @@ String *Item_func_weight_string::val_str(String *str)
*/
if (!(tmp_length= result_length))
{
- uint char_length;
+ size_t char_length;
if (cs->state & MY_CS_STRNXFRM_BAD_NWEIGHTS)
{
/*
@@ -3678,7 +3604,7 @@ String *Item_func_weight_string::val_str(String *str)
frm_length= cs->coll->strnxfrm(cs,
(uchar *) str->ptr(), tmp_length,
- nweights ? nweights : tmp_length,
+ nweights ? nweights : (uint)tmp_length,
(const uchar *) res->ptr(), res->length(),
flags);
DBUG_ASSERT(frm_length <= tmp_length);
@@ -4517,20 +4443,19 @@ bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg)
if (res)
{
// guaranty UTF-8 string for names
- if (my_charset_same(res->charset(), &my_charset_utf8_general_ci))
+ if (my_charset_same(res->charset(), DYNCOL_UTF))
{
keys_str[i].length= res->length();
keys_str[i].str= thd->strmake(res->ptr(), res->length());
}
else
{
- uint strlen= res->length() * my_charset_utf8_general_ci.mbmaxlen + 1;
+ uint strlen= res->length() * DYNCOL_UTF->mbmaxlen + 1;
uint dummy_errors;
- char *str= (char *) thd->alloc(strlen);
- if (str)
+ if (char *str= (char *) thd->alloc(strlen))
{
keys_str[i].length=
- copy_and_convert(str, strlen, &my_charset_utf8_general_ci,
+ copy_and_convert(str, strlen, DYNCOL_UTF,
res->ptr(), res->length(), res->charset(),
&dummy_errors);
keys_str[i].str= str;
@@ -4750,9 +4675,10 @@ String *Item_func_dyncol_json::val_str(String *str)
char *ptr;
size_t length, alloc_length;
dynstr_reassociate(&json, &ptr, &length, &alloc_length);
- str->reset(ptr, length, alloc_length, &my_charset_utf8_general_ci);
+ str->reset(ptr, length, alloc_length, DYNCOL_UTF);
null_value= FALSE;
}
+ str->set_charset(DYNCOL_UTF);
return str;
null:
@@ -4852,20 +4778,20 @@ bool Item_dyncol_get::get_dyn_value(THD *thd, DYNAMIC_COLUMN_VALUE *val,
return 1;
}
- if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci))
+ if (my_charset_same(nm->charset(), DYNCOL_UTF))
{
buf.str= (char *) nm->ptr();
buf.length= nm->length();
}
else
{
- uint strlen= nm->length() * my_charset_utf8_general_ci.mbmaxlen + 1;
+ uint strlen= nm->length() * DYNCOL_UTF->mbmaxlen + 1;
uint dummy_errors;
buf.str= (char *) thd->alloc(strlen);
if (buf.str)
{
buf.length=
- copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci,
+ copy_and_convert(buf.str, strlen, DYNCOL_UTF,
nm->ptr(), nm->length(), nm->charset(),
&dummy_errors);
}
@@ -5289,7 +5215,6 @@ String *Item_func_dyncol_list::val_str(String *str)
goto null;
str->length(0);
- str->set_charset(&my_charset_utf8_general_ci);
for (i= 0; i < count; i++)
{
append_identifier(current_thd, str, names[i].str, names[i].length);
@@ -5299,6 +5224,7 @@ String *Item_func_dyncol_list::val_str(String *str)
null_value= FALSE;
if (names)
my_free(names);
+ str->set_charset(DYNCOL_UTF);
return str;
null:
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index fbcf69d00ce..08601b9d9d4 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -62,6 +62,8 @@ public:
longlong val_int();
double val_real();
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_string(ltime, fuzzydate); }
const Type_handler *type_handler() const { return string_type_handler(); }
void left_right_max_length();
bool fix_fields(THD *thd, Item **ref);
@@ -147,8 +149,8 @@ public:
fix_length_and_charset(32, default_charset());
}
const char *func_name() const { return "md5"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_md5>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_md5>(thd, this); }
};
@@ -159,8 +161,8 @@ public:
String *val_str_ascii(String *);
void fix_length_and_dec();
const char *func_name() const { return "sha"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sha>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sha>(thd, this); }
};
class Item_func_sha2 :public Item_str_ascii_checksum_func
@@ -171,8 +173,8 @@ public:
String *val_str_ascii(String *);
void fix_length_and_dec();
const char *func_name() const { return "sha2"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sha2>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sha2>(thd, this); }
};
class Item_func_to_base64 :public Item_str_ascii_checksum_func
@@ -184,8 +186,8 @@ public:
String *val_str_ascii(String *);
void fix_length_and_dec();
const char *func_name() const { return "to_base64"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_to_base64>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_to_base64>(thd, this); }
};
class Item_func_from_base64 :public Item_str_binary_checksum_func
@@ -197,8 +199,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "from_base64"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_from_base64>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_from_base64>(thd, this); }
};
#include <my_crypt.h>
@@ -223,8 +225,8 @@ public:
Item_aes_crypt(thd, a, b) {}
void fix_length_and_dec();
const char *func_name() const { return "aes_encrypt"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_aes_encrypt>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_aes_encrypt>(thd, this); }
};
class Item_func_aes_decrypt :public Item_aes_crypt
@@ -234,8 +236,8 @@ public:
Item_aes_crypt(thd, a, b) {}
void fix_length_and_dec();
const char *func_name() const { return "aes_decrypt"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_aes_decrypt>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_aes_decrypt>(thd, this); }
};
@@ -244,45 +246,22 @@ class Item_func_concat :public Item_str_func
protected:
String tmp_value;
/*
- Get the i-th argument val_str() and its const_item()
- @param i[IN] - The argument number
- @param str[IN] - The buffer for val_str()
- @param is_const[IN/OUT] - If args[i]->val_str() returned a non-null value,
- then args[i]->const_item() is returned here.
- Otherwise, the value of is_const is not touched.
- @retval - the result of val_str().
- */
- String *arg_val_str(uint i, String *str, bool *is_const)
- {
- String *res= args[i]->val_str(str);
- if (res)
- *is_const= args[i]->const_item();
- return res;
- }
- /*
Append a non-NULL value to the result.
@param [IN] thd - The current thread.
@param [IN/OUT] res - The current val_str() return value.
- @param [IN] res_is_const - If "false", then OK to append to "res"
- @param [IN/OUT] str - The val_str() argument.
- @param [IN] res2 - The value to be appended.
- @param [IN/OUT] use_as_buff - Which buffer to use for the next argument:
- args[next_arg]->val_str(use_as_buff)
+ @param [IN] app - The value to be appended.
+ @retval - false on success, true on error
*/
- String *append_value(THD *thd,
- String *res,
- bool res_is_const,
- String *str,
- String **use_as_buff,
- const String *res2);
+ bool append_value(THD *thd, String *res, const String *app);
+ bool realloc_result(String *str, uint length) const;
public:
Item_func_concat(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
Item_func_concat(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "concat"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_concat>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_concat>(thd, this); }
};
@@ -301,9 +280,9 @@ public:
{ }
String *val_str(String *);
const char *func_name() const { return "concat_operator_oracle"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ Item *get_copy(THD *thd)
{
- return get_item_copy<Item_func_concat_operator_oracle>(thd, mem_root, this);
+ return get_item_copy<Item_func_concat_operator_oracle>(thd, this);
}
};
@@ -321,8 +300,8 @@ public:
maybe_null= 1;
}
const char *func_name() const { return "decode_histogram"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_decode_histogram>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_decode_histogram>(thd, this); }
};
class Item_func_concat_ws :public Item_str_func
@@ -334,8 +313,8 @@ public:
void fix_length_and_dec();
const char *func_name() const { return "concat_ws"; }
table_map not_null_tables() const { return 0; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_concat_ws>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_concat_ws>(thd, this); }
};
class Item_func_reverse :public Item_str_func
@@ -346,8 +325,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "reverse"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_reverse>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_reverse>(thd, this); }
};
@@ -361,8 +340,8 @@ public:
void fix_length_and_dec();
String *val_str_internal(String *str, String *empty_string_for_null);
const char *func_name() const { return "replace"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_replace>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_replace>(thd, this); }
};
@@ -374,8 +353,8 @@ public:
Item_func_replace(thd, org, find, replace) {}
String *val_str(String *to) { return val_str_internal(to, &tmp_emtpystr); };
const char *func_name() const { return "replace_oracle"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_replace_oracle>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_replace_oracle>(thd, this); }
};
@@ -400,7 +379,7 @@ public:
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
const char *func_name() const { return "regexp_replace"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0;}
+ Item *get_copy(THD *thd) { return 0;}
};
@@ -422,7 +401,7 @@ public:
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
const char *func_name() const { return "regexp_substr"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item *get_copy(THD *thd) { return 0; }
};
@@ -436,8 +415,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "insert"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_insert>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_insert>(thd, this); }
};
@@ -459,8 +438,8 @@ public:
Item_func_lcase(THD *thd, Item *item): Item_str_conv(thd, item) {}
const char *func_name() const { return "lcase"; }
void fix_length_and_dec();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_lcase>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_lcase>(thd, this); }
};
class Item_func_ucase :public Item_str_conv
@@ -469,8 +448,8 @@ public:
Item_func_ucase(THD *thd, Item *item): Item_str_conv(thd, item) {}
const char *func_name() const { return "ucase"; }
void fix_length_and_dec();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_ucase>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_ucase>(thd, this); }
};
@@ -482,8 +461,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "left"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_left>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_left>(thd, this); }
};
@@ -495,8 +474,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "right"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_right>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_right>(thd, this); }
};
@@ -512,8 +491,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "substr"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_substr>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_substr>(thd, this); }
};
class Item_func_substr_oracle :public Item_func_substr
@@ -527,8 +506,8 @@ public:
Item_func_substr_oracle(THD *thd, Item *a, Item *b, Item *c):
Item_func_substr(thd, a, b, c) {}
const char *func_name() const { return "substr_oracle"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_substr_oracle>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_substr_oracle>(thd, this); }
};
class Item_func_substr_index :public Item_str_func
@@ -540,8 +519,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "substring_index"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_substr_index>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_substr_index>(thd, this); }
};
@@ -574,8 +553,8 @@ public:
const char *func_name() const { return "trim"; }
void print(String *str, enum_query_type query_type);
virtual const char *mode_name() const { return "both"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_trim>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_trim>(thd, this); }
};
@@ -587,8 +566,8 @@ public:
String *val_str(String *);
const char *func_name() const { return "ltrim"; }
const char *mode_name() const { return "leading"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_ltrim>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_ltrim>(thd, this); }
};
@@ -600,8 +579,8 @@ public:
String *val_str(String *);
const char *func_name() const { return "rtrim"; }
const char *mode_name() const { return "trailing"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_rtrim>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_rtrim>(thd, this); }
};
@@ -639,8 +618,8 @@ public:
"password" : "old_password"); }
static char *alloc(THD *thd, const char *password, size_t pass_len,
enum PW_Alg al);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_password>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_password>(thd, this); }
};
@@ -661,8 +640,8 @@ public:
max_length = args[0]->max_length + 9;
}
const char *func_name() const { return "des_encrypt"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_des_encrypt>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_des_encrypt>(thd, this); }
};
class Item_func_des_decrypt :public Item_str_binary_checksum_func
@@ -683,8 +662,8 @@ public:
max_length-= 9U;
}
const char *func_name() const { return "des_decrypt"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_des_decrypt>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_des_decrypt>(thd, this); }
};
@@ -719,8 +698,8 @@ public:
{
return FALSE;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_encrypt>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_encrypt>(thd, this); }
};
#include "sql_crypt.h"
@@ -739,8 +718,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "encode"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_encode>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_encode>(thd, this); }
protected:
virtual void crypto_transform(String *);
private:
@@ -754,8 +733,8 @@ class Item_func_decode :public Item_func_encode
public:
Item_func_decode(THD *thd, Item *a, Item *seed_arg): Item_func_encode(thd, a, seed_arg) {}
const char *func_name() const { return "decode"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_decode>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_decode>(thd, this); }
protected:
void crypto_transform(String *);
};
@@ -794,8 +773,8 @@ public:
}
const char *func_name() const { return "database"; }
const char *fully_qualified_func_name() const { return "database()"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_database>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_database>(thd, this); }
};
@@ -815,8 +794,8 @@ public:
max_length= 512 * system_charset_info->mbmaxlen;
null_value= maybe_null= false;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sqlerrm>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sqlerrm>(thd, this); }
};
@@ -847,8 +826,8 @@ public:
{
return save_str_value_in_field(field, &str_value);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_user>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_user>(thd, this); }
};
@@ -897,8 +876,8 @@ public:
return mark_unsupported_function(fully_qualified_func_name(), arg,
VCOL_SESSION_FUNC);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_current_role>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_current_role>(thd, this); }
};
@@ -910,8 +889,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "soundex"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_soundex>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_soundex>(thd, this); }
};
@@ -924,8 +903,8 @@ public:
String *val_str(String *str);
void fix_length_and_dec();
const char *func_name() const { return "elt"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_elt>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_elt>(thd, this); }
};
@@ -938,8 +917,8 @@ public:
String *val_str(String *str);
void fix_length_and_dec();
const char *func_name() const { return "make_set"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_make_set>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_make_set>(thd, this); }
};
@@ -955,8 +934,8 @@ public:
String *val_str_ascii(String *);
void fix_length_and_dec();
const char *func_name() const { return "format"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_format>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_format>(thd, this); }
};
@@ -978,8 +957,9 @@ public:
max_length= arg_count * 4;
}
const char *func_name() const { return "char"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_char>(thd, mem_root, this); }
+ void print(String *str, enum_query_type query_type);
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_char>(thd, this); }
};
class Item_func_chr :public Item_func_char
@@ -993,8 +973,8 @@ public:
max_length= 4;
}
const char *func_name() const { return "chr"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_chr>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_chr>(thd, this); }
};
class Item_func_repeat :public Item_str_func
@@ -1006,8 +986,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "repeat"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_repeat>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_repeat>(thd, this); }
};
@@ -1018,8 +998,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "space"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_space>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_space>(thd, this); }
};
@@ -1035,8 +1015,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_binlog_gtid_pos>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_binlog_gtid_pos>(thd, this); }
};
@@ -1062,8 +1042,8 @@ public:
Item_func_pad(thd, arg1, arg2) {}
String *val_str(String *);
const char *func_name() const { return "rpad"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_rpad>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_rpad>(thd, this); }
};
@@ -1076,8 +1056,8 @@ public:
Item_func_pad(thd, arg1, arg2) {}
String *val_str(String *);
const char *func_name() const { return "lpad"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_lpad>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_lpad>(thd, this); }
};
@@ -1094,8 +1074,8 @@ public:
max_length=64;
maybe_null= 1;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_conv>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_conv>(thd, this); }
};
@@ -1129,8 +1109,8 @@ public:
fix_char_length(args[0]->max_length * 2);
m_arg0_type_handler= args[0]->type_handler();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_hex>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_hex>(thd, this); }
};
class Item_func_unhex :public Item_str_func
@@ -1150,8 +1130,8 @@ public:
decimals=0;
max_length=(1+args[0]->max_length)/2;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_unhex>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_unhex>(thd, this); }
};
@@ -1182,8 +1162,8 @@ public:
Item_func_like_range_min(THD *thd, Item *a, Item *b):
Item_func_like_range(thd, a, b, true) { }
const char *func_name() const { return "like_range_min"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_like_range_min>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_like_range_min>(thd, this); }
};
@@ -1193,8 +1173,8 @@ public:
Item_func_like_range_max(THD *thd, Item *a, Item *b):
Item_func_like_range(thd, a, b, false) { }
const char *func_name() const { return "like_range_max"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_like_range_max>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_like_range_max>(thd, this); }
};
#endif
@@ -1220,8 +1200,8 @@ public:
void print(String *str, enum_query_type query_type);
const char *func_name() const { return "cast_as_binary"; }
bool need_parentheses_in_default() { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_binary>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_binary>(thd, this); }
};
@@ -1242,8 +1222,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_load_file>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_load_file>(thd, this); }
};
@@ -1259,8 +1239,8 @@ class Item_func_export_set: public Item_str_func
String *val_str(String *str);
void fix_length_and_dec();
const char *func_name() const { return "export_set"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_export_set>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_export_set>(thd, this); }
};
@@ -1278,8 +1258,8 @@ public:
2 * collation.collation->mbmaxlen;
max_length= (uint32) MY_MIN(max_result_length, MAX_BLOB_WIDTH);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_quote>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_quote>(thd, this); }
};
class Item_func_conv_charset :public Item_str_func
@@ -1362,8 +1342,8 @@ public:
void fix_length_and_dec();
const char *func_name() const { return "convert"; }
void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_conv_charset>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_conv_charset>(thd, this); }
};
class Item_func_set_collation :public Item_str_func
@@ -1384,8 +1364,8 @@ public:
return args[0]->field_for_view_update();
}
bool need_parentheses_in_default() { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_set_collation>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_set_collation>(thd, this); }
};
@@ -1413,8 +1393,8 @@ public:
:Item_func_expr_str_metadata(thd, a) { }
String *val_str(String *);
const char *func_name() const { return "charset"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_charset>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_charset>(thd, this); }
};
@@ -1425,8 +1405,8 @@ public:
:Item_func_expr_str_metadata(thd, a) {}
String *val_str(String *);
const char *func_name() const { return "collation"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_collation>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_collation>(thd, this); }
};
@@ -1460,8 +1440,8 @@ public:
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{ return this; }
void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_weight_string>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_weight_string>(thd, this); }
};
class Item_func_crc32 :public Item_long_func
@@ -1475,8 +1455,8 @@ public:
const char *func_name() const { return "crc32"; }
void fix_length_and_dec() { max_length=10; }
longlong val_int();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_crc32>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_crc32>(thd, this); }
};
class Item_func_uncompressed_length : public Item_long_func_length
@@ -1488,8 +1468,8 @@ public:
const char *func_name() const{return "uncompressed_length";}
void fix_length_and_dec() { max_length=10; maybe_null= true; }
longlong val_int();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_uncompressed_length>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_uncompressed_length>(thd, this); }
};
#ifdef HAVE_COMPRESS
@@ -1507,8 +1487,8 @@ public:
void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;}
const char *func_name() const{return "compress";}
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_compress>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_compress>(thd, this); }
};
class Item_func_uncompress: public Item_str_binary_checksum_func
@@ -1520,8 +1500,8 @@ public:
void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; }
const char *func_name() const{return "uncompress";}
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_uncompress>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_uncompress>(thd, this); }
};
@@ -1541,8 +1521,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_uuid>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_uuid>(thd, this); }
};
@@ -1564,8 +1544,8 @@ public:
String *val_str(String *);
void print(String *str, enum_query_type query_type);
enum Functype functype() const { return DYNCOL_FUNC; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_dyncol_create>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_dyncol_create>(thd, this); }
};
@@ -1578,25 +1558,25 @@ public:
const char *func_name() const{ return "column_add"; }
String *val_str(String *);
void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_dyncol_add>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_dyncol_add>(thd, this); }
};
class Item_func_dyncol_json: public Item_str_func
{
public:
- Item_func_dyncol_json(THD *thd, Item *str): Item_str_func(thd, str) {}
+ Item_func_dyncol_json(THD *thd, Item *str): Item_str_func(thd, str)
+ {collation.set(DYNCOL_UTF);}
const char *func_name() const{ return "column_json"; }
String *val_str(String *);
void fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
- collation.set(&my_charset_bin);
decimals= 0;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_dyncol_json>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_dyncol_json>(thd, this); }
};
/*
@@ -1637,20 +1617,21 @@ public:
bool get_dyn_value(THD *thd, DYNAMIC_COLUMN_VALUE *val, String *tmp);
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_dyncol_get>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_dyncol_get>(thd, this); }
};
class Item_func_dyncol_list: public Item_str_func
{
public:
- Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str) {};
+ Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str)
+ {collation.set(DYNCOL_UTF);}
void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; };
const char *func_name() const{ return "column_list"; }
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_dyncol_list>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_dyncol_list>(thd, this); }
};
#endif /* ITEM_STRFUNC_INCLUDED */
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 3a7d8582913..a8051ccd469 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -64,7 +64,6 @@ Item_subselect::Item_subselect(THD *thd_arg):
#ifndef DBUG_OFF
exec_counter= 0;
#endif
- with_subselect= 1;
reset();
/*
Item value is NULL if select_result_interceptor didn't change this value
@@ -2134,7 +2133,10 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
}
else
{
- Item *item= (Item*) select_lex->item_list.head()->real_item();
+ Item *item= (Item*) select_lex->item_list.head();
+ if (item->type() != REF_ITEM ||
+ ((Item_ref*)item)->ref_type() != Item_ref::VIEW_REF)
+ item= item->real_item();
if (select_lex->table_list.elements)
{
@@ -3099,7 +3101,7 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg)
new (thd->mem_root)
Item_direct_ref(thd,
&unit->outer_select()->context,
- optimizer->arguments()[0]->addr(i),
+ optimizer->arguments()[0]->addr((int)i),
(char *)"<no matter>",
&exists_outer_expr_name)),
thd->mem_root);
@@ -4366,6 +4368,9 @@ table_map subselect_union_engine::upper_select_const_tables()
void subselect_single_select_engine::print(String *str,
enum_query_type query_type)
{
+ With_clause* with_clause= select_lex->get_with_clause();
+ if (with_clause)
+ with_clause->print(str, query_type);
select_lex->print(get_thd(), str, query_type);
}
@@ -4935,11 +4940,10 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
DBUG_RETURN(TRUE);
char buf[32];
- uint len= my_snprintf(buf, sizeof(buf), "<subquery%u>", subquery_id);
- char *name;
- if (!(name= (char*)thd->alloc(len + 1)))
+ LEX_CSTRING name;
+ name.length= my_snprintf(buf, sizeof(buf), "<subquery%u>", subquery_id);
+ if (!(name.str= (char*) thd->memdup(buf, name.length + 1)))
DBUG_RETURN(TRUE);
- memcpy(name, buf, len+1);
result_sink->get_tmp_table_param()->materialized_subquery= true;
if (item->substype() == Item_subselect::IN_SUBS &&
@@ -4949,7 +4953,7 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
}
if (result_sink->create_result_table(thd, tmp_columns, TRUE,
tmp_create_options,
- name, TRUE, TRUE, FALSE, 0))
+ &name, TRUE, TRUE, FALSE, 0))
DBUG_RETURN(TRUE);
tmp_table= result_sink->table;
@@ -5035,7 +5039,7 @@ bool subselect_hash_sj_engine::make_semi_join_conds()
/* Name resolution context for all tmp_table columns created below. */
Name_resolution_context *context;
Item_in_subselect *item_in= (Item_in_subselect *) item;
-
+ LEX_CSTRING table_name;
DBUG_ENTER("subselect_hash_sj_engine::make_semi_join_conds");
DBUG_ASSERT(semi_join_conds == NULL);
@@ -5045,10 +5049,9 @@ bool subselect_hash_sj_engine::make_semi_join_conds()
if (!(tmp_table_ref= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST))))
DBUG_RETURN(TRUE);
- tmp_table_ref->init_one_table(STRING_WITH_LEN(""),
- tmp_table->alias.c_ptr(),
- tmp_table->alias.length(),
- NULL, TL_READ);
+ table_name.str= tmp_table->alias.c_ptr();
+ table_name.length= tmp_table->alias.length(),
+ tmp_table_ref->init_one_table(&empty_clex_str, &table_name, NULL, TL_READ);
tmp_table_ref->table= tmp_table;
context= new Name_resolution_context;
@@ -5499,7 +5502,7 @@ int subselect_hash_sj_engine::exec()
if (has_covering_null_row)
{
- DBUG_ASSERT(count_partial_match_columns = field_count);
+ DBUG_ASSERT(count_partial_match_columns == field_count);
count_pm_keys= 0;
}
else if (has_covering_null_columns)
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 9e548e94ac1..dfe3287615b 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -182,6 +182,7 @@ public:
return null_value;
}
bool fix_fields(THD *thd, Item **ref);
+ bool with_subquery() const { DBUG_ASSERT(fixed); return true; }
bool mark_as_dependent(THD *thd, st_select_lex *select, Item *item);
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
void recalc_used_tables(st_select_lex *new_parent, bool after_pullout);
@@ -263,8 +264,8 @@ public:
void register_as_with_rec_ref(With_element *with_elem);
void init_expr_cache_tracker(THD *thd);
- Item* build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
- Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item* build_clone(THD *thd) { return 0; }
+ Item* get_copy(THD *thd) { return 0; }
bool wrap_tvc_in_derived_table(THD *thd, st_select_lex *tvc_sl);
@@ -400,6 +401,8 @@ public:
String *val_str(String*);
my_decimal *val_decimal(my_decimal *);
bool val_bool();
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_int(ltime, fuzzydate); }
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
void print(String *str, enum_query_type query_type);
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 269190ef3df..25a0f68f575 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -30,6 +30,10 @@
#include "sql_priv.h"
#include "sql_select.h"
#include "uniques.h"
+#include "sp_rcontext.h"
+#include "sp.h"
+#include "sql_parse.h"
+#include "sp_head.h"
/**
Calculate the affordable RAM limit for structures like TREE or Unique
@@ -790,7 +794,7 @@ bool Aggregator_distinct::setup(THD *thd)
if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
0,
(select_lex->options | thd->variables.option_bits),
- HA_POS_ERROR, const_cast<char*>(""))))
+ HA_POS_ERROR, &empty_clex_str)))
return TRUE;
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
table->no_rows=1;
@@ -1126,7 +1130,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
return TRUE;
set_if_bigger(decimals, args[i]->decimals);
- with_subselect|= args[i]->with_subselect;
+ m_with_subquery|= args[i]->with_subquery();
with_window_func|= args[i]->with_window_func;
}
result_field=0;
@@ -1146,18 +1150,20 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
bool
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
{
+ DBUG_ENTER("Item_sum_hybrid::fix_fields");
DBUG_ASSERT(fixed == 0);
Item *item= args[0];
if (init_sum_func_check(thd))
- return TRUE;
+ DBUG_RETURN(TRUE);
// 'item' can be changed during fix_fields
if ((!item->fixed && item->fix_fields(thd, args)) ||
(item= args[0])->check_cols(1))
- return TRUE;
- with_subselect= args[0]->with_subselect;
+ DBUG_RETURN(TRUE);
+
+ m_with_subquery= args[0]->with_subquery();
with_window_func|= args[0]->with_window_func;
fix_length_and_dec();
@@ -1166,11 +1172,11 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
result_field=0;
if (check_sum_func(thd, ref))
- return TRUE;
+ DBUG_RETURN(TRUE);
orig_args[0]= args[0];
fixed= 1;
- return FALSE;
+ DBUG_RETURN(FALSE);
}
@@ -1201,15 +1207,16 @@ void Item_sum_hybrid::fix_length_and_dec()
void Item_sum_hybrid::setup_hybrid(THD *thd, Item *item, Item *value_arg)
{
+ DBUG_ENTER("Item_sum_hybrid::setup_hybrid");
if (!(value= item->get_cache(thd)))
- return;
+ DBUG_VOID_RETURN;
value->setup(thd, item);
value->store(value_arg);
/* Don't cache value, as it will change */
if (!item->const_item())
value->set_used_tables(RAND_TABLE_BIT);
if (!(arg_cache= item->get_cache(thd)))
- return;
+ DBUG_VOID_RETURN;
arg_cache->setup(thd, item);
/* Don't cache value, as it will change */
if (!item->const_item())
@@ -1217,23 +1224,178 @@ void Item_sum_hybrid::setup_hybrid(THD *thd, Item *item, Item *value_arg)
cmp= new Arg_comparator();
if (cmp)
cmp->set_cmp_func(this, (Item**)&arg_cache, (Item**)&value, FALSE);
+ DBUG_VOID_RETURN;
}
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table)
{
+ DBUG_ENTER("Item_sum_hybrid::create_tmp_field");
+
if (args[0]->type() == Item::FIELD_ITEM)
{
Field *field= ((Item_field*) args[0])->field;
if ((field= create_tmp_field_from_field(table->in_use, field, &name,
table, NULL)))
field->flags&= ~NOT_NULL_FLAG;
- return field;
+ DBUG_RETURN(field);
}
- return tmp_table_field_from_field_type(table);
+ DBUG_RETURN(tmp_table_field_from_field_type(table));
+}
+
+/***********************************************************************
+** Item_sum_sp class
+***********************************************************************/
+
+Item_sum_sp::Item_sum_sp(THD *thd, Name_resolution_context *context_arg,
+ sp_name *name_arg, sp_head *sp, List<Item> &list)
+ :Item_sum(thd, list), Item_sp(thd, context_arg, name_arg)
+{
+ maybe_null= 1;
+ quick_group= 0;
+ m_sp= sp;
+}
+
+Item_sum_sp::Item_sum_sp(THD *thd, Name_resolution_context *context_arg,
+ sp_name *name_arg, sp_head *sp)
+ :Item_sum(thd), Item_sp(thd, context_arg, name_arg)
+{
+ maybe_null= 1;
+ quick_group= 0;
+ m_sp= sp;
}
+bool
+Item_sum_sp::fix_fields(THD *thd, Item **ref)
+{
+ DBUG_ASSERT(fixed == 0);
+ if (init_sum_func_check(thd))
+ return TRUE;
+ decimals= 0;
+
+ m_sp= m_sp ? m_sp : sp_handler_function.sp_find_routine(thd, m_name, true);
+
+ if (!m_sp)
+ {
+ my_missing_function_error(m_name->m_name, ErrConvDQName(m_name).ptr());
+ context->process_error(thd);
+ return TRUE;
+ }
+
+ if (init_result_field(thd, max_length, maybe_null, &null_value, &name))
+ return TRUE;
+
+ for (uint i= 0 ; i < arg_count ; i++)
+ {
+ if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
+ return TRUE;
+ set_if_bigger(decimals, args[i]->decimals);
+ m_with_subquery|= args[i]->with_subquery();
+ with_window_func|= args[i]->with_window_func;
+ }
+ result_field= NULL;
+ max_length= float_length(decimals);
+ null_value= 1;
+ fix_length_and_dec();
+
+ if (check_sum_func(thd, ref))
+ return TRUE;
+
+ memcpy(orig_args, args, sizeof(Item *) * arg_count);
+ fixed= 1;
+ return FALSE;
+}
+
+/**
+ Execute function to store value in result field.
+ This is called when we need the value to be returned for the function.
+ Here we send a signal in form of the server status that all rows have been
+ fetched and now we have to exit from the function with the return value.
+ @return Function returns error status.
+ @retval FALSE on success.
+ @retval TRUE if an error occurred.
+*/
+
+bool
+Item_sum_sp::execute()
+{
+ THD *thd= current_thd;
+ bool res;
+ uint old_server_status= thd->server_status;
+
+ /* We set server status so we can send a signal to exit from the
+ function with the return value. */
+
+ thd->server_status= SERVER_STATUS_LAST_ROW_SENT;
+ res= Item_sp::execute(thd, &null_value, args, arg_count);
+ thd->server_status= old_server_status;
+ return res;
+}
+
+/**
+ Handles the aggregation of the values.
+ @note: See class description for more details on how and why this is done.
+ @return The error state.
+ @retval FALSE on success.
+ @retval TRUE if an error occurred.
+*/
+
+bool
+Item_sum_sp::add()
+{
+ return execute_impl(current_thd, args, arg_count);
+}
+
+
+void
+Item_sum_sp::clear()
+{
+ delete func_ctx;
+ func_ctx= NULL;
+ sp_query_arena->free_items();
+ free_root(&sp_mem_root, MYF(0));
+}
+
+const Type_handler *Item_sum_sp::type_handler() const
+{
+ DBUG_ENTER("Item_sum_sp::type_handler");
+ DBUG_PRINT("info", ("m_sp = %p", (void *) m_sp));
+ DBUG_ASSERT(sp_result_field);
+ // This converts ENUM/SET to STRING
+ const Type_handler *handler= sp_result_field->type_handler();
+ DBUG_RETURN(handler->type_handler_for_item_field());
+}
+
+void
+Item_sum_sp::cleanup()
+{
+ Item_sp::cleanup();
+ Item_sum::cleanup();
+}
+
+/**
+ Initialize local members with values from the Field interface.
+ @note called from Item::fix_fields.
+*/
+
+void
+Item_sum_sp::fix_length_and_dec()
+{
+ DBUG_ENTER("Item_sum_sp::fix_length_and_dec");
+ DBUG_ASSERT(sp_result_field);
+ Type_std_attributes::set(sp_result_field);
+ Item_sum::fix_length_and_dec();
+ DBUG_VOID_RETURN;
+}
+
+const char *
+Item_sum_sp::func_name() const
+{
+ THD *thd= current_thd;
+ return Item_sp::func_name(thd);
+}
+
/***********************************************************************
** reset and add of sum_func
***********************************************************************/
@@ -1245,6 +1407,7 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table)
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item)
:Item_sum_num(thd, item),
Type_handler_hybrid_field_type(item),
+ direct_added(FALSE), direct_reseted_field(FALSE),
curr_dec_buff(item->curr_dec_buff),
count(item->count)
{
@@ -1264,6 +1427,15 @@ Item *Item_sum_sum::copy_or_same(THD* thd)
}
+void Item_sum_sum::cleanup()
+{
+ DBUG_ENTER("Item_sum_sum::cleanup");
+ direct_added= direct_reseted_field= FALSE;
+ Item_sum_num::cleanup();
+ DBUG_VOID_RETURN;
+}
+
+
void Item_sum_sum::clear()
{
DBUG_ENTER("Item_sum_sum::clear");
@@ -1313,6 +1485,38 @@ void Item_sum_sum::fix_length_and_dec()
}
+void Item_sum_sum::direct_add(my_decimal *add_sum_decimal)
+{
+ DBUG_ENTER("Item_sum_sum::direct_add");
+ DBUG_PRINT("info", ("add_sum_decimal: %p", add_sum_decimal));
+ direct_added= TRUE;
+ direct_reseted_field= FALSE;
+ if (add_sum_decimal)
+ {
+ direct_sum_is_null= FALSE;
+ direct_sum_decimal= *add_sum_decimal;
+ }
+ else
+ {
+ direct_sum_is_null= TRUE;
+ direct_sum_decimal= decimal_zero;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void Item_sum_sum::direct_add(double add_sum_real, bool add_sum_is_null)
+{
+ DBUG_ENTER("Item_sum_sum::direct_add");
+ DBUG_PRINT("info", ("add_sum_real: %f", add_sum_real));
+ direct_added= TRUE;
+ direct_reseted_field= FALSE;
+ direct_sum_is_null= add_sum_is_null;
+ direct_sum_real= add_sum_real;
+ DBUG_VOID_RETURN;
+}
+
+
bool Item_sum_sum::add()
{
DBUG_ENTER("Item_sum_sum::add");
@@ -1326,50 +1530,84 @@ void Item_sum_sum::add_helper(bool perform_removal)
if (result_type() == DECIMAL_RESULT)
{
- my_decimal value;
- const my_decimal *val= aggr->arg_val_decimal(&value);
- if (!aggr->arg_is_null(true))
+ if (unlikely(direct_added))
{
- if (perform_removal)
+ /* Add value stored by Item_sum_sum::direct_add */
+ DBUG_ASSERT(!perform_removal);
+
+ direct_added= FALSE;
+ if (likely(!direct_sum_is_null))
{
- if (count > 0)
+ my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1),
+ &direct_sum_decimal, dec_buffs + curr_dec_buff);
+ curr_dec_buff^= 1;
+ null_value= 0;
+ }
+ }
+ else
+ {
+ direct_reseted_field= FALSE;
+ my_decimal value;
+ const my_decimal *val= aggr->arg_val_decimal(&value);
+ if (!aggr->arg_is_null(true))
+ {
+ if (perform_removal)
{
- my_decimal_sub(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff ^ 1),
- dec_buffs + curr_dec_buff, val);
- count--;
+ if (count > 0)
+ {
+ my_decimal_sub(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff ^ 1),
+ dec_buffs + curr_dec_buff, val);
+ count--;
+ }
+ else
+ DBUG_VOID_RETURN;
}
else
- DBUG_VOID_RETURN;
- }
- else
- {
- count++;
- my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff ^ 1),
- val, dec_buffs + curr_dec_buff);
+ {
+ count++;
+ my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff ^ 1),
+ val, dec_buffs + curr_dec_buff);
+ }
+ curr_dec_buff^= 1;
+ null_value= (count > 0) ? 0 : 1;
}
- curr_dec_buff^= 1;
- null_value= (count > 0) ? 0 : 1;
}
}
else
{
- if (perform_removal && count > 0)
- sum-= aggr->arg_val_real();
+ if (unlikely(direct_added))
+ {
+ /* Add value stored by Item_sum_sum::direct_add */
+ DBUG_ASSERT(!perform_removal);
+
+ direct_added= FALSE;
+ if (!direct_sum_is_null)
+ {
+ sum+= direct_sum_real;
+ null_value= 0;
+ }
+ }
else
- sum+= aggr->arg_val_real();
- if (!aggr->arg_is_null(true))
{
- if (perform_removal)
+ direct_reseted_field= FALSE;
+ if (perform_removal && count > 0)
+ sum-= aggr->arg_val_real();
+ else
+ sum+= aggr->arg_val_real();
+ if (!aggr->arg_is_null(true))
{
- if (count > 0)
+ if (perform_removal)
{
- count--;
+ if (count > 0)
+ {
+ count--;
+ }
}
- }
- else
- count++;
+ else
+ count++;
- null_value= (count > 0) ? 0 : 1;
+ null_value= (count > 0) ? 0 : 1;
+ }
}
}
DBUG_VOID_RETURN;
@@ -1556,22 +1794,46 @@ bool Aggregator_distinct::arg_is_null(bool use_null_value)
Item *Item_sum_count::copy_or_same(THD* thd)
{
- return new (thd->mem_root) Item_sum_count(thd, this);
+ DBUG_ENTER("Item_sum_count::copy_or_same");
+ DBUG_RETURN(new (thd->mem_root) Item_sum_count(thd, this));
+}
+
+
+void Item_sum_count::direct_add(longlong add_count)
+{
+ DBUG_ENTER("Item_sum_count::direct_add");
+ DBUG_PRINT("info", ("add_count: %lld", add_count));
+ direct_counted= TRUE;
+ direct_reseted_field= FALSE;
+ direct_count= add_count;
+ DBUG_VOID_RETURN;
}
void Item_sum_count::clear()
{
+ DBUG_ENTER("Item_sum_count::clear");
count= 0;
+ DBUG_VOID_RETURN;
}
bool Item_sum_count::add()
{
- if (aggr->arg_is_null(false))
- return 0;
- count++;
- return 0;
+ DBUG_ENTER("Item_sum_count::add");
+ if (direct_counted)
+ {
+ direct_counted= FALSE;
+ count+= direct_count;
+ }
+ else
+ {
+ direct_reseted_field= FALSE;
+ if (aggr->arg_is_null(false))
+ DBUG_RETURN(0);
+ count++;
+ }
+ DBUG_RETURN(0);
}
@@ -1590,10 +1852,11 @@ void Item_sum_count::remove()
longlong Item_sum_count::val_int()
{
+ DBUG_ENTER("Item_sum_count::val_int");
DBUG_ASSERT(fixed == 1);
if (aggr)
aggr->endup();
- return (longlong) count;
+ DBUG_RETURN((longlong)count);
}
@@ -1601,6 +1864,8 @@ void Item_sum_count::cleanup()
{
DBUG_ENTER("Item_sum_count::cleanup");
count= 0;
+ direct_counted= FALSE;
+ direct_reseted_field= FALSE;
Item_sum_int::cleanup();
DBUG_VOID_RETURN;
}
@@ -2015,10 +2280,13 @@ Item *Item_sum_variance::result_item(THD *thd, Field *field)
void Item_sum_hybrid::clear()
{
+ DBUG_ENTER("Item_sum_hybrid::clear");
value->clear();
null_value= 1;
+ DBUG_VOID_RETURN;
}
+
bool
Item_sum_hybrid::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
@@ -2031,51 +2299,66 @@ Item_sum_hybrid::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
return retval;
}
+
+void Item_sum_hybrid::direct_add(Item *item)
+{
+ DBUG_ENTER("Item_sum_hybrid::direct_add");
+ DBUG_PRINT("info", ("item: %p", item));
+ direct_added= TRUE;
+ direct_item= item;
+ DBUG_VOID_RETURN;
+}
+
+
double Item_sum_hybrid::val_real()
{
+ DBUG_ENTER("Item_sum_hybrid::val_real");
DBUG_ASSERT(fixed == 1);
if (null_value)
- return 0.0;
+ DBUG_RETURN(0.0);
double retval= value->val_real();
if ((null_value= value->null_value))
DBUG_ASSERT(retval == 0.0);
- return retval;
+ DBUG_RETURN(retval);
}
longlong Item_sum_hybrid::val_int()
{
+ DBUG_ENTER("Item_sum_hybrid::val_int");
DBUG_ASSERT(fixed == 1);
if (null_value)
- return 0;
+ DBUG_RETURN(0);
longlong retval= value->val_int();
if ((null_value= value->null_value))
DBUG_ASSERT(retval == 0);
- return retval;
+ DBUG_RETURN(retval);
}
my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
{
+ DBUG_ENTER("Item_sum_hybrid::val_decimal");
DBUG_ASSERT(fixed == 1);
if (null_value)
- return 0;
+ DBUG_RETURN(0);
my_decimal *retval= value->val_decimal(val);
if ((null_value= value->null_value))
DBUG_ASSERT(retval == NULL);
- return retval;
+ DBUG_RETURN(retval);
}
String *
Item_sum_hybrid::val_str(String *str)
{
+ DBUG_ENTER("Item_sum_hybrid::val_str");
DBUG_ASSERT(fixed == 1);
if (null_value)
- return 0;
+ DBUG_RETURN(0);
String *retval= value->val_str(str);
if ((null_value= value->null_value))
DBUG_ASSERT(retval == NULL);
- return retval;
+ DBUG_RETURN(retval);
}
@@ -2099,6 +2382,7 @@ void Item_sum_hybrid::cleanup()
void Item_sum_hybrid::no_rows_in_result()
{
+ DBUG_ENTER("Item_sum_hybrid::no_rows_in_result");
/* We may be called here twice in case of ref field in function */
if (was_values)
{
@@ -2106,6 +2390,7 @@ void Item_sum_hybrid::no_rows_in_result()
was_null_value= value->null_value;
clear();
}
+ DBUG_VOID_RETURN;
}
void Item_sum_hybrid::restore_to_before_no_rows_in_result()
@@ -2120,14 +2405,26 @@ void Item_sum_hybrid::restore_to_before_no_rows_in_result()
Item *Item_sum_min::copy_or_same(THD* thd)
{
+ DBUG_ENTER("Item_sum_min::copy_or_same");
Item_sum_min *item= new (thd->mem_root) Item_sum_min(thd, this);
item->setup_hybrid(thd, args[0], value);
- return item;
+ DBUG_RETURN(item);
}
bool Item_sum_min::add()
{
+ Item *tmp_item;
+ DBUG_ENTER("Item_sum_min::add");
+ DBUG_PRINT("enter", ("this: %p", this));
+
+ if (unlikely(direct_added))
+ {
+ /* Change to use direct_item */
+ tmp_item= arg_cache->get_item();
+ arg_cache->store(direct_item);
+ }
+ DBUG_PRINT("info", ("null_value: %s", null_value ? "TRUE" : "FALSE"));
/* args[0] < value */
arg_cache->cache_value();
if (!arg_cache->null_value &&
@@ -2137,7 +2434,13 @@ bool Item_sum_min::add()
value->cache_value();
null_value= 0;
}
- return 0;
+ if (unlikely(direct_added))
+ {
+ /* Restore original item */
+ direct_added= FALSE;
+ arg_cache->store(tmp_item);
+ }
+ DBUG_RETURN(0);
}
@@ -2151,8 +2454,19 @@ Item *Item_sum_max::copy_or_same(THD* thd)
bool Item_sum_max::add()
{
+ Item *tmp_item;
+ DBUG_ENTER("Item_sum_max::add");
+ DBUG_PRINT("enter", ("this: %p", this));
+
+ if (unlikely(direct_added))
+ {
+ /* Change to use direct_item */
+ tmp_item= arg_cache->get_item();
+ arg_cache->store(direct_item);
+ }
/* args[0] > value */
arg_cache->cache_value();
+ DBUG_PRINT("info", ("null_value: %s", null_value ? "TRUE" : "FALSE"));
if (!arg_cache->null_value &&
(null_value || cmp->compare() > 0))
{
@@ -2160,7 +2474,13 @@ bool Item_sum_max::add()
value->cache_value();
null_value= 0;
}
- return 0;
+ if (unlikely(direct_added))
+ {
+ /* Restore original item */
+ direct_added= FALSE;
+ arg_cache->store(tmp_item);
+ }
+ DBUG_RETURN(0);
}
@@ -2211,7 +2531,7 @@ bool Item_sum_bit::remove_as_window(ulonglong value)
}
// Prevent overflow;
- num_values_added = std::min(num_values_added, num_values_added - 1);
+ num_values_added = MY_MIN(num_values_added, num_values_added - 1);
set_bits_from_counters();
return 0;
}
@@ -2224,7 +2544,7 @@ bool Item_sum_bit::add_as_window(ulonglong value)
bit_counters[i]+= (value & (1ULL << i)) ? 1 : 0;
}
// Prevent overflow;
- num_values_added = std::max(num_values_added, num_values_added + 1);
+ num_values_added = MY_MAX(num_values_added, num_values_added + 1);
set_bits_from_counters();
return 0;
}
@@ -2339,14 +2659,26 @@ void Item_sum_num::reset_field()
void Item_sum_hybrid::reset_field()
{
+ Item *tmp_item, *arg0;
+ DBUG_ENTER("Item_sum_hybrid::reset_field");
+
+ arg0= args[0];
+ if (unlikely(direct_added))
+ {
+ /* Switch to use direct item */
+ tmp_item= value->get_item();
+ value->store(direct_item);
+ arg0= direct_item;
+ }
+
switch(result_type()) {
case STRING_RESULT:
{
char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff),result_field->charset()),*res;
- res=args[0]->val_str(&tmp);
- if (args[0]->null_value)
+ res= arg0->val_str(&tmp);
+ if (arg0->null_value)
{
result_field->set_null();
result_field->reset();
@@ -2360,11 +2692,11 @@ void Item_sum_hybrid::reset_field()
}
case INT_RESULT:
{
- longlong nr=args[0]->val_int();
+ longlong nr= arg0->val_int();
if (maybe_null)
{
- if (args[0]->null_value)
+ if (arg0->null_value)
{
nr=0;
result_field->set_null();
@@ -2372,16 +2704,17 @@ void Item_sum_hybrid::reset_field()
else
result_field->set_notnull();
}
+ DBUG_PRINT("info", ("nr: %lld", nr));
result_field->store(nr, unsigned_flag);
break;
}
case REAL_RESULT:
{
- double nr= args[0]->val_real();
+ double nr= arg0->val_real();
if (maybe_null)
{
- if (args[0]->null_value)
+ if (arg0->null_value)
{
nr=0.0;
result_field->set_null();
@@ -2394,11 +2727,11 @@ void Item_sum_hybrid::reset_field()
}
case DECIMAL_RESULT:
{
- my_decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
+ my_decimal value_buff, *arg_dec= arg0->val_decimal(&value_buff);
if (maybe_null)
{
- if (args[0]->null_value)
+ if (arg0->null_value)
result_field->set_null();
else
result_field->set_notnull();
@@ -2416,26 +2749,49 @@ void Item_sum_hybrid::reset_field()
case TIME_RESULT:
DBUG_ASSERT(0);
}
+
+ if (unlikely(direct_added))
+ {
+ direct_added= FALSE;
+ value->store(tmp_item);
+ }
+ DBUG_VOID_RETURN;
}
void Item_sum_sum::reset_field()
{
+ my_bool null_flag;
DBUG_ASSERT (aggr->Aggrtype() != Aggregator::DISTINCT_AGGREGATOR);
if (result_type() == DECIMAL_RESULT)
{
- my_decimal value, *arg_val= args[0]->val_decimal(&value);
- if (!arg_val) // Null
- arg_val= &decimal_zero;
+ my_decimal value, *arg_val;
+ if (unlikely(direct_added))
+ arg_val= &direct_sum_decimal;
+ else
+ {
+ if (!(arg_val= args[0]->val_decimal(&value)))
+ arg_val= &decimal_zero; // Null
+ }
result_field->store_decimal(arg_val);
}
else
{
DBUG_ASSERT(result_type() == REAL_RESULT);
- double nr= args[0]->val_real(); // Nulls also return 0
+ double nr= likely(!direct_added) ? args[0]->val_real() : direct_sum_real;
float8store(result_field->ptr, nr);
}
- if (args[0]->null_value)
+
+ if (unlikely(direct_added))
+ {
+ direct_added= FALSE;
+ direct_reseted_field= TRUE;
+ null_flag= direct_sum_is_null;
+ }
+ else
+ null_flag= args[0]->null_value;
+
+ if (null_flag)
result_field->set_null();
else
result_field->set_notnull();
@@ -2444,13 +2800,22 @@ void Item_sum_sum::reset_field()
void Item_sum_count::reset_field()
{
+ DBUG_ENTER("Item_sum_count::reset_field");
uchar *res=result_field->ptr;
longlong nr=0;
DBUG_ASSERT (aggr->Aggrtype() != Aggregator::DISTINCT_AGGREGATOR);
- if (!args[0]->maybe_null || !args[0]->is_null())
- nr=1;
+ if (unlikely(direct_counted))
+ {
+ nr= direct_count;
+ direct_counted= FALSE;
+ direct_reseted_field= TRUE;
+ }
+ else if (!args[0]->maybe_null || !args[0]->is_null())
+ nr= 1;
+ DBUG_PRINT("info", ("nr: %lld", nr));
int8store(res,nr);
+ DBUG_VOID_RETURN;
}
@@ -2518,13 +2883,26 @@ void Item_sum_sum::update_field()
DBUG_ASSERT (aggr->Aggrtype() != Aggregator::DISTINCT_AGGREGATOR);
if (result_type() == DECIMAL_RESULT)
{
- my_decimal value, *arg_val= args[0]->val_decimal(&value);
- if (!args[0]->null_value)
+ my_decimal value, *arg_val;
+ my_bool null_flag;
+ if (unlikely(direct_added || direct_reseted_field))
+ {
+ direct_added= direct_reseted_field= FALSE;
+ arg_val= &direct_sum_decimal;
+ null_flag= direct_sum_is_null;
+ }
+ else
+ {
+ arg_val= args[0]->val_decimal(&value);
+ null_flag= args[0]->null_value;
+ }
+
+ if (!null_flag)
{
if (!result_field->is_null())
{
- my_decimal field_value,
- *field_val= result_field->val_decimal(&field_value);
+ my_decimal field_value;
+ my_decimal *field_val= result_field->val_decimal(&field_value);
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, field_val);
result_field->store_decimal(dec_buffs);
}
@@ -2538,11 +2916,22 @@ void Item_sum_sum::update_field()
else
{
double old_nr,nr;
- uchar *res=result_field->ptr;
+ uchar *res= result_field->ptr;
+ my_bool null_flag;
float8get(old_nr,res);
- nr= args[0]->val_real();
- if (!args[0]->null_value)
+ if (unlikely(direct_added || direct_reseted_field))
+ {
+ direct_added= direct_reseted_field= FALSE;
+ null_flag= direct_sum_is_null;
+ nr= direct_sum_real;
+ }
+ else
+ {
+ nr= args[0]->val_real();
+ null_flag= args[0]->null_value;
+ }
+ if (!null_flag)
{
old_nr+=nr;
result_field->set_notnull();
@@ -2554,13 +2943,21 @@ void Item_sum_sum::update_field()
void Item_sum_count::update_field()
{
+ DBUG_ENTER("Item_sum_count::update_field");
longlong nr;
uchar *res=result_field->ptr;
nr=sint8korr(res);
- if (!args[0]->maybe_null || !args[0]->is_null())
+ if (unlikely(direct_counted || direct_reseted_field))
+ {
+ direct_counted= direct_reseted_field= FALSE;
+ nr+= direct_count;
+ }
+ else if (!args[0]->maybe_null || !args[0]->is_null())
nr++;
+ DBUG_PRINT("info", ("nr: %lld", nr));
int8store(res,nr);
+ DBUG_VOID_RETURN;
}
@@ -2618,6 +3015,13 @@ Item *Item_sum_avg::result_item(THD *thd, Field *field)
void Item_sum_hybrid::update_field()
{
+ DBUG_ENTER("Item_sum_hybrid::update_field");
+ Item *tmp_item;
+ if (unlikely(direct_added))
+ {
+ tmp_item= args[0];
+ args[0]= direct_item;
+ }
switch (result_type()) {
case STRING_RESULT:
min_max_update_str_field();
@@ -2631,12 +3035,19 @@ void Item_sum_hybrid::update_field()
default:
min_max_update_real_field();
}
+ if (unlikely(direct_added))
+ {
+ direct_added= FALSE;
+ args[0]= tmp_item;
+ }
+ DBUG_VOID_RETURN;
}
void
Item_sum_hybrid::min_max_update_str_field()
{
+ DBUG_ENTER("Item_sum_hybrid::min_max_update_str_field");
DBUG_ASSERT(cmp);
String *res_str=args[0]->val_str(&cmp->value1);
@@ -2649,6 +3060,7 @@ Item_sum_hybrid::min_max_update_str_field()
result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
result_field->set_notnull();
}
+ DBUG_VOID_RETURN;
}
@@ -2657,6 +3069,7 @@ Item_sum_hybrid::min_max_update_real_field()
{
double nr,old_nr;
+ DBUG_ENTER("Item_sum_hybrid::min_max_update_real_field");
old_nr=result_field->val_real();
nr= args[0]->val_real();
if (!args[0]->null_value)
@@ -2669,6 +3082,7 @@ Item_sum_hybrid::min_max_update_real_field()
else if (result_field->is_null(0))
result_field->set_null();
result_field->store(old_nr);
+ DBUG_VOID_RETURN;
}
@@ -2677,6 +3091,7 @@ Item_sum_hybrid::min_max_update_int_field()
{
longlong nr,old_nr;
+ DBUG_ENTER("Item_sum_hybrid::min_max_update_int_field");
old_nr=result_field->val_int();
nr=args[0]->val_int();
if (!args[0]->null_value)
@@ -2696,7 +3111,9 @@ Item_sum_hybrid::min_max_update_int_field()
}
else if (result_field->is_null(0))
result_field->set_null();
+ DBUG_PRINT("info", ("nr: %lld", old_nr));
result_field->store(old_nr, unsigned_flag);
+ DBUG_VOID_RETURN;
}
@@ -2707,6 +3124,7 @@ Item_sum_hybrid::min_max_update_int_field()
void
Item_sum_hybrid::min_max_update_decimal_field()
{
+ DBUG_ENTER("Item_sum_hybrid::min_max_update_decimal_field");
my_decimal old_val, nr_val;
const my_decimal *old_nr;
const my_decimal *nr= args[0]->val_decimal(&nr_val);
@@ -2727,6 +3145,7 @@ Item_sum_hybrid::min_max_update_decimal_field()
}
else if (result_field->is_null(0))
result_field->set_null();
+ DBUG_VOID_RETURN;
}
@@ -2850,7 +3269,7 @@ double Item_sum_udf_float::val_real()
double res;
DBUG_ASSERT(fixed == 1);
DBUG_ENTER("Item_sum_udf_float::val");
- DBUG_PRINT("info",("result_type: %d arg_count: %d",
+ DBUG_PRINT("enter",("result_type: %d arg_count: %d",
args[0]->result_type(), arg_count));
res= udf.val(&tmp_null_value);
null_value= tmp_null_value;
@@ -2894,7 +3313,7 @@ my_decimal *Item_sum_udf_decimal::val_decimal(my_decimal *dec_buf)
my_bool tmp_null_value;
DBUG_ASSERT(fixed == 1);
DBUG_ENTER("Item_func_udf_decimal::val_decimal");
- DBUG_PRINT("info",("result_type: %d arg_count: %d",
+ DBUG_PRINT("enter",("result_type: %d arg_count: %d",
args[0]->result_type(), arg_count));
res= udf.val_decimal(&tmp_null_value, dec_buf);
@@ -2920,7 +3339,7 @@ longlong Item_sum_udf_int::val_int()
longlong res;
DBUG_ASSERT(fixed == 1);
DBUG_ENTER("Item_sum_udf_int::val_int");
- DBUG_PRINT("info",("result_type: %d arg_count: %d",
+ DBUG_PRINT("enter",("result_type: %d arg_count: %d",
args[0]->result_type(), arg_count));
res= udf.val_int(&tmp_null_value);
null_value= tmp_null_value;
@@ -3114,6 +3533,11 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
uint old_length= result->length();
+ ulonglong *offset_limit= &item->copy_offset_limit;
+ ulonglong *row_limit = &item->copy_row_limit;
+ if (item->limit_clause && !(*row_limit))
+ return 1;
+
if (item->no_appended)
item->no_appended= FALSE;
else
@@ -3121,6 +3545,14 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
tmp.length(0);
+ if (item->limit_clause && (*offset_limit))
+ {
+ item->row_count++;
+ item->no_appended= TRUE;
+ (*offset_limit)--;
+ return 0;
+ }
+
for (; arg < arg_end; arg++)
{
String *res;
@@ -3150,6 +3582,8 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
result->append(*res);
}
+ if (item->limit_clause)
+ (*row_limit)--;
item->row_count++;
/* stop if length of result more than max_length */
@@ -3163,7 +3597,7 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
as this is never used to limit the length of the data.
Cut is done with the third argument.
*/
- uint add_length= Well_formed_prefix(cs,
+ size_t add_length= Well_formed_prefix(cs,
ptr + old_length,
ptr + max_length,
result->length()).length();
@@ -3198,7 +3632,8 @@ Item_func_group_concat::
Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
bool distinct_arg, List<Item> *select_list,
const SQL_I_List<ORDER> &order_list,
- String *separator_arg)
+ String *separator_arg, bool limit_clause,
+ Item *row_limit_arg, Item *offset_limit_arg)
:Item_sum(thd), tmp_table_param(0), separator(separator_arg), tree(0),
unique_filter(NULL), table(0),
order(0), context(context_arg),
@@ -3207,7 +3642,9 @@ Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
row_count(0),
distinct(distinct_arg),
warning_for_row(FALSE),
- force_copy_fields(0), original(0)
+ force_copy_fields(0), row_limit(NULL),
+ offset_limit(NULL), limit_clause(limit_clause),
+ copy_offset_limit(0), copy_row_limit(0), original(0)
{
Item *item_select;
Item **arg_ptr;
@@ -3249,6 +3686,11 @@ Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
/* orig_args is only used for print() */
orig_args= (Item**) (order + arg_count_order);
memcpy(orig_args, args, sizeof(Item*) * arg_count);
+ if (limit_clause)
+ {
+ row_limit= row_limit_arg;
+ offset_limit= offset_limit_arg;
+ }
}
@@ -3268,7 +3710,9 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
warning_for_row(item->warning_for_row),
always_null(item->always_null),
force_copy_fields(item->force_copy_fields),
- original(item)
+ row_limit(item->row_limit), offset_limit(item->offset_limit),
+ limit_clause(item->limit_clause),copy_offset_limit(item->copy_offset_limit),
+ copy_row_limit(item->copy_row_limit), original(item)
{
quick_group= item->quick_group;
result.set_charset(collation.collation);
@@ -3363,6 +3807,10 @@ void Item_func_group_concat::clear()
null_value= TRUE;
warning_for_row= FALSE;
no_appended= TRUE;
+ if (offset_limit)
+ copy_offset_limit= offset_limit->val_int();
+ if (row_limit)
+ copy_row_limit= row_limit->val_int();
if (tree)
reset_tree(tree);
if (unique_filter)
@@ -3447,7 +3895,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref)
args[i]->fix_fields(thd, args + i)) ||
args[i]->check_cols(1))
return TRUE;
- with_subselect|= args[i]->with_subselect;
+ m_with_subquery|= args[i]->with_subquery();
with_window_func|= args[i]->with_window_func;
}
@@ -3578,7 +4026,7 @@ bool Item_func_group_concat::setup(THD *thd)
(ORDER*) 0, 0, TRUE,
(select_lex->options |
thd->variables.option_bits),
- HA_POS_ERROR, (char*) "")))
+ HA_POS_ERROR, &empty_clex_str)))
DBUG_RETURN(TRUE);
table->file->extra(HA_EXTRA_NO_ROWS);
table->no_rows= 1;
@@ -3617,6 +4065,12 @@ bool Item_func_group_concat::setup(THD *thd)
(void*)this,
tree_key_length,
ram_limitation(thd));
+ if ((row_limit && row_limit->cmp_type() != INT_RESULT) ||
+ (offset_limit && offset_limit->cmp_type() != INT_RESULT))
+ {
+ my_error(ER_INVALID_VALUE_TO_LIMIT, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
DBUG_RETURN(FALSE);
}
@@ -3682,7 +4136,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type)
}
}
str->append(STRING_WITH_LEN(" separator \'"));
- str->append(*separator);
+ str->append_for_single_quote(separator->ptr(), separator->length());
str->append(STRING_WITH_LEN("\')"));
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index e91728a1aa1..1ed3d870bcc 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -355,7 +355,7 @@ public:
ROW_NUMBER_FUNC, RANK_FUNC, DENSE_RANK_FUNC, PERCENT_RANK_FUNC,
CUME_DIST_FUNC, NTILE_FUNC, FIRST_VALUE_FUNC, LAST_VALUE_FUNC,
NTH_VALUE_FUNC, LEAD_FUNC, LAG_FUNC, PERCENTILE_CONT_FUNC,
- PERCENTILE_DISC_FUNC
+ PERCENTILE_DISC_FUNC, SP_AGGREGATE_FUNC
};
Item **ref_by; /* pointer to a ref to the object used to register it */
@@ -521,6 +521,7 @@ public:
Item *get_arg(uint i) const { return args[i]; }
Item *set_arg(uint i, THD *thd, Item *new_val);
uint get_arg_count() const { return arg_count; }
+ virtual Item **get_args() { return fixed ? orig_args : args; }
/* Initialization of distinct related members */
void init_aggregator()
@@ -733,6 +734,10 @@ public:
longlong val_int() { return val_int_from_real(); /* Real as default */ }
String *val_str(String*str);
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ }
void reset_field();
};
@@ -757,14 +762,20 @@ class Item_sum_sum :public Item_sum_num,
public Type_handler_hybrid_field_type
{
protected:
+ bool direct_added;
+ bool direct_reseted_field;
+ bool direct_sum_is_null;
+ double direct_sum_real;
double sum;
+ my_decimal direct_sum_decimal;
my_decimal dec_buffs[2];
uint curr_dec_buff;
void fix_length_and_dec();
public:
Item_sum_sum(THD *thd, Item *item_par, bool distinct):
- Item_sum_num(thd, item_par)
+ Item_sum_num(thd, item_par), direct_added(FALSE),
+ direct_reseted_field(FALSE)
{
set_distinct(distinct);
}
@@ -773,6 +784,9 @@ public:
{
return has_with_distinct() ? SUM_DISTINCT_FUNC : SUM_FUNC;
}
+ void cleanup();
+ void direct_add(my_decimal *add_sum_decimal);
+ void direct_add(double add_sum_real, bool add_sum_is_null);
void clear();
bool add();
double val_real();
@@ -792,8 +806,8 @@ public:
}
Item *copy_or_same(THD* thd);
void remove();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_sum>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_sum>(thd, this); }
bool supports_removal() const
{
@@ -808,6 +822,9 @@ private:
class Item_sum_count :public Item_sum_int
{
+ bool direct_counted;
+ bool direct_reseted_field;
+ longlong direct_count;
longlong count;
friend class Aggregator_distinct;
@@ -817,9 +834,10 @@ class Item_sum_count :public Item_sum_int
void cleanup();
void remove();
- public:
+public:
Item_sum_count(THD *thd, Item *item_par):
- Item_sum_int(thd, item_par), count(0)
+ Item_sum_int(thd, item_par), direct_counted(FALSE),
+ direct_reseted_field(FALSE), count(0)
{}
/**
@@ -831,12 +849,14 @@ class Item_sum_count :public Item_sum_int
*/
Item_sum_count(THD *thd, List<Item> &list):
- Item_sum_int(thd, list), count(0)
+ Item_sum_int(thd, list), direct_counted(FALSE),
+ direct_reseted_field(FALSE), count(0)
{
set_distinct(TRUE);
}
Item_sum_count(THD *thd, Item_sum_count *item):
- Item_sum_int(thd, item), count(item->count)
+ Item_sum_int(thd, item), direct_counted(FALSE),
+ direct_reseted_field(FALSE), count(item->count)
{}
enum Sumfunctype sum_func () const
{
@@ -851,13 +871,14 @@ class Item_sum_count :public Item_sum_int
longlong val_int();
void reset_field();
void update_field();
+ void direct_add(longlong add_count);
const char *func_name() const
{
return has_with_distinct() ? "count(distinct " : "count(";
}
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_count>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_count>(thd, this); }
bool supports_removal() const
{
@@ -912,8 +933,8 @@ public:
count= 0;
Item_sum_sum::cleanup();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_avg>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_avg>(thd, this); }
bool supports_removal() const
{
@@ -978,8 +999,8 @@ public:
count= 0;
Item_sum_num::cleanup();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_variance>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_variance>(thd, this); }
};
/*
@@ -999,8 +1020,8 @@ class Item_sum_std :public Item_sum_variance
Item *result_item(THD *thd, Field *field);
const char *func_name() const { return "std("; }
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_std>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_std>(thd, this); }
};
// This class is a string or number function depending on num_func
@@ -1009,6 +1030,8 @@ class Item_cache;
class Item_sum_hybrid :public Item_sum, public Type_handler_hybrid_field_type
{
protected:
+ bool direct_added;
+ Item *direct_item;
Item_cache *value, *arg_cache;
Arg_comparator *cmp;
int cmp_sign;
@@ -1019,19 +1042,20 @@ protected:
Item_sum_hybrid(THD *thd, Item *item_par,int sign):
Item_sum(thd, item_par),
Type_handler_hybrid_field_type(&type_handler_longlong),
- value(0), arg_cache(0), cmp(0),
+ direct_added(FALSE), value(0), arg_cache(0), cmp(0),
cmp_sign(sign), was_values(TRUE)
{ collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
:Item_sum(thd, item),
Type_handler_hybrid_field_type(item),
- value(item->value), arg_cache(0),
+ direct_added(FALSE), value(item->value), arg_cache(0),
cmp_sign(item->cmp_sign), was_values(item->was_values)
{ }
bool fix_fields(THD *, Item **);
void fix_length_and_dec();
void setup_hybrid(THD *thd, Item *item, Item *value_arg);
void clear();
+ void direct_add(Item *item);
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal *);
@@ -1069,8 +1093,8 @@ public:
bool add();
const char *func_name() const { return "min("; }
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_min>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_min>(thd, this); }
};
@@ -1084,8 +1108,8 @@ public:
bool add();
const char *func_name() const { return "max("; }
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_max>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_max>(thd, this); }
};
@@ -1165,8 +1189,8 @@ public:
bool add();
const char *func_name() const { return "bit_or("; }
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_or>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_or>(thd, this); }
private:
void set_bits_from_counters();
@@ -1182,8 +1206,8 @@ public:
bool add();
const char *func_name() const { return "bit_and("; }
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_and>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_and>(thd, this); }
private:
void set_bits_from_counters();
@@ -1197,13 +1221,143 @@ public:
bool add();
const char *func_name() const { return "bit_xor("; }
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_xor>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_xor>(thd, this); }
private:
void set_bits_from_counters();
};
+class sp_head;
+class sp_name;
+class Query_arena;
+struct st_sp_security_context;
+
+/*
+ Item_sum_sp handles STORED AGGREGATE FUNCTIONS
+
+ Each Item_sum_sp represents a custom aggregate function. Inside the
+ function's body, we require at least one occurence of FETCH GROUP NEXT ROW
+ instruction. This cursor is what makes custom stored aggregates possible.
+
+ During computation the function's add method is called. This in turn performs
+ an execution of the function. The function will execute from the current
+ function context (and instruction), if one exists, or from the start if not.
+ See Item_sp for more details.
+
+ Upon encounter of FETCH GROUP NEXT ROW instruction, the function will pause
+ execution. We assume that the user has performed the necessary additions for
+ a row, between two encounters of FETCH GROUP NEXT ROW.
+
+ Example:
+ create aggregate function f1(x INT) returns int
+ begin
+ declare continue handler for not found return s;
+ declare s int default 0
+ loop
+ fetch group next row;
+ set s = s + x;
+ end loop;
+ end
+
+ The function will always stop after an encounter of FETCH GROUP NEXT ROW,
+ except (!) on first encounter, as the value for the first row in the
+ group is already set in the argument x. This behaviour is done so when
+ a user writes a function, he should "logically" include FETCH GROUP NEXT ROW
+ before any "add" instructions in the stored function. This means however that
+ internally, the first occurence doesn't stop the function. See the
+ implementation of FETCH GROUP NEXT ROW for details as to how it happens.
+
+ Either way, one should assume that after calling "Item_sum_sp::add()" that
+ the values for that particular row have been added to the aggregation.
+
+ To produce values for val_xxx methods we need an extra syntactic construct.
+ We require a continue handler when "no more rows are available". val_xxx
+ methods force a function return by executing the function again, while
+ setting a server flag that no more rows have been found. This implies
+ that val_xxx methods should only be called once per group however.
+
+ Example:
+ DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN ret_val;
+*/
+class Item_sum_sp :public Item_sum,
+ public Item_sp
+{
+ private:
+ bool execute();
+
+public:
+ Item_sum_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name,
+ sp_head *sp);
+
+ Item_sum_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name,
+ sp_head *sp, List<Item> &list);
+
+ enum Sumfunctype sum_func () const
+ {
+ return SP_AGGREGATE_FUNC;
+ }
+ void fix_length_and_dec();
+ bool fix_fields(THD *thd, Item **ref);
+ const char *func_name() const;
+ const Type_handler *type_handler() const;
+ bool add();
+
+ /* val_xx functions */
+ longlong val_int()
+ {
+ if(execute())
+ return 0;
+ return sp_result_field->val_int();
+ }
+
+ double val_real()
+ {
+ if(execute())
+ return 0.0;
+ return sp_result_field->val_real();
+ }
+
+ my_decimal *val_decimal(my_decimal *dec_buf)
+ {
+ if(execute())
+ return NULL;
+ return sp_result_field->val_decimal(dec_buf);
+ }
+
+ String *val_str(String *str)
+ {
+ String buf;
+ char buff[20];
+ buf.set(buff, 20, str->charset());
+ buf.length(0);
+ if (execute())
+ return NULL;
+ /*
+ result_field will set buf pointing to internal buffer
+ of the resul_field. Due to this it will change any time
+ when SP is executed. In order to prevent occasional
+ corruption of returned value, we make here a copy.
+ */
+ sp_result_field->val_str(&buf);
+ str->copy(buf);
+ return str;
+ }
+ void reset_field(){DBUG_ASSERT(0);}
+ void update_field(){DBUG_ASSERT(0);}
+ void clear();
+ void cleanup();
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return execute() || sp_result_field->get_date(ltime, fuzzydate);
+ }
+ inline Field *get_sp_result_field()
+ {
+ return sp_result_field;
+ }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_sp>(thd, this); }
+};
/* Items to get the value of a stored sum function */
@@ -1228,6 +1382,10 @@ public:
{
return mark_unsupported_function(name.str, arg, VCOL_IMPOSSIBLE);
}
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ }
};
@@ -1255,8 +1413,8 @@ public:
my_decimal *val_decimal(my_decimal *dec) { return val_decimal_from_real(dec); }
String *val_str(String *str) { return val_string_from_real(str); }
double val_real();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_avg_field_double>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_avg_field_double>(thd, this); }
};
@@ -1275,8 +1433,8 @@ public:
longlong val_int() { return val_int_from_decimal(); }
String *val_str(String *str) { return val_string_from_decimal(str); }
my_decimal *val_decimal(my_decimal *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_avg_field_decimal>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_avg_field_decimal>(thd, this); }
};
@@ -1296,8 +1454,8 @@ public:
{ return val_decimal_from_real(dec_buf); }
bool is_null() { update_null_value(); return null_value; }
const Type_handler *type_handler() const { return &type_handler_double; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_variance_field>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_variance_field>(thd, this); }
};
@@ -1309,8 +1467,8 @@ public:
{ }
enum Type type() const { return FIELD_STD_ITEM; }
double val_real();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_std_field>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_std_field>(thd, this); }
};
@@ -1377,6 +1535,10 @@ public:
void update_field() {};
void cleanup();
virtual void print(String *str, enum_query_type query_type);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ }
};
@@ -1396,8 +1558,8 @@ class Item_sum_udf_float :public Item_udf_sum
const Type_handler *type_handler() const { return &type_handler_double; }
void fix_length_and_dec() { fix_num_length_and_dec(); }
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_udf_float>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_udf_float>(thd, this); }
};
@@ -1418,8 +1580,8 @@ public:
const Type_handler *type_handler() const { return &type_handler_longlong; }
void fix_length_and_dec() { decimals=0; max_length=21; }
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_udf_int>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_udf_int>(thd, this); }
};
@@ -1459,8 +1621,8 @@ public:
const Type_handler *type_handler() const { return string_type_handler(); }
void fix_length_and_dec();
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_udf_str>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_udf_str>(thd, this); }
};
@@ -1480,8 +1642,8 @@ public:
const Type_handler *type_handler() const { return &type_handler_newdecimal; }
void fix_length_and_dec() { fix_num_length_and_dec(); }
Item *copy_or_same(THD* thd);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_udf_decimal>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_udf_decimal>(thd, this); }
};
#else /* Dummy functions to get sql_yacc.cc compiled */
@@ -1601,6 +1763,16 @@ class Item_func_group_concat : public Item_sum
bool always_null;
bool force_copy_fields;
bool no_appended;
+ /** Limits the rows in the result */
+ Item *row_limit;
+ /** Skips a particular number of rows in from the result*/
+ Item *offset_limit;
+ bool limit_clause;
+ /* copy of the offset limit */
+ ulonglong copy_offset_limit;
+ /*copy of the row limit */
+ ulonglong copy_row_limit;
+
/*
Following is 0 normal object and pointer to original one for copy
(to correctly free resources)
@@ -1617,7 +1789,8 @@ class Item_func_group_concat : public Item_sum
public:
Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
bool is_distinct, List<Item> *is_select,
- const SQL_I_List<ORDER> &is_order, String *is_separator);
+ const SQL_I_List<ORDER> &is_order, String *is_separator,
+ bool limit_clause, Item *row_limit, Item *offset_limit);
Item_func_group_concat(THD *thd, Item_func_group_concat *item);
~Item_func_group_concat();
@@ -1662,14 +1835,18 @@ public:
{
return val_decimal_from_string(decimal_value);
}
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return get_date_from_string(ltime, fuzzydate);
+ }
String* val_str(String* str);
Item *copy_or_same(THD* thd);
void no_rows_in_result() {}
virtual void print(String *str, enum_query_type query_type);
virtual bool change_context_processor(void *cntx)
{ context= (Name_resolution_context *)cntx; return FALSE; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_group_concat>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_group_concat>(thd, this); }
};
#endif /* ITEM_SUM_INCLUDED */
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 3a7684fe7b4..4ddeb83b163 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -709,8 +709,7 @@ static bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
For example, '1.1' -> '1.100000'
*/
-static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
- uint count, ulonglong *values,
+static bool get_interval_info(const char *str, size_t length,CHARSET_INFO *cs, size_t count, ulonglong *values,
bool transform_msec)
{
const char *end=str+length;
@@ -993,15 +992,15 @@ longlong Item_func_quarter::val_int()
longlong Item_func_hour::val_int()
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- return get_arg0_time(&ltime) ? 0 : ltime.hour;
+ Time tm(args[0], Time::Options_for_cast());
+ return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->hour;
}
longlong Item_func_minute::val_int()
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- return get_arg0_time(&ltime) ? 0 : ltime.minute;
+ Time tm(args[0], Time::Options_for_cast());
+ return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->minute;
}
/**
@@ -1010,8 +1009,8 @@ longlong Item_func_minute::val_int()
longlong Item_func_second::val_int()
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- return get_arg0_time(&ltime) ? 0 : ltime.second;
+ Time tm(args[0], Time::Options_for_cast());
+ return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->second;
}
@@ -1267,24 +1266,20 @@ longlong Item_func_unix_timestamp::val_int_endpoint(bool left_endp, bool *incl_e
longlong Item_func_time_to_sec::int_op()
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- if (get_arg0_time(&ltime))
- return 0;
-
- longlong seconds=ltime.hour*3600L+ltime.minute*60+ltime.second;
- return ltime.neg ? -seconds : seconds;
+ Time tm(args[0], Time::Options_for_cast());
+ return ((null_value= !tm.is_valid_time())) ? 0 : tm.to_seconds();
}
my_decimal *Item_func_time_to_sec::decimal_op(my_decimal* buf)
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- if (get_arg0_time(&ltime))
+ Time tm(args[0], Time::Options_for_cast());
+ if ((null_value= !tm.is_valid_time()))
return 0;
-
- longlong seconds= ltime.hour*3600L+ltime.minute*60+ltime.second;
- return seconds2my_decimal(ltime.neg, seconds, ltime.second_part, buf);
+ const MYSQL_TIME *ltime= tm.get_mysql_time();
+ longlong seconds= tm.to_seconds_abs();
+ return seconds2my_decimal(ltime->neg, seconds, ltime->second_part, buf);
}
@@ -1991,7 +1986,7 @@ String *Item_func_date_format::val_str(String *str)
const MY_LOCALE *lc= 0;
DBUG_ASSERT(fixed == 1);
- if (get_arg0_date(&l_time, is_time_format ? TIME_TIME_ONLY : 0))
+ if ((null_value= args[0]->get_date(&l_time, is_time_format ? TIME_TIME_ONLY : 0)))
return 0;
if (!(format = args[1]->val_str(str)) || !format->length())
@@ -2427,13 +2422,15 @@ void Item_char_typecast::print(String *str, enum_query_type query_type)
}
-void Item_char_typecast::check_truncation_with_warn(String *src, uint dstlen)
+void Item_char_typecast::check_truncation_with_warn(String *src, size_t dstlen)
{
if (dstlen < src->length())
{
THD *thd= current_thd;
char char_type[40];
ErrConvString err(src);
+ bool save_abort_on_warning= thd->abort_on_warning;
+ thd->abort_on_warning&= !m_suppress_warning_to_error_escalation;
my_snprintf(char_type, sizeof(char_type), "%s(%lu)",
cast_cs == &my_charset_bin ? "BINARY" : "CHAR",
(ulong) cast_length);
@@ -2441,11 +2438,12 @@ void Item_char_typecast::check_truncation_with_warn(String *src, uint dstlen)
ER_TRUNCATED_WRONG_VALUE,
ER_THD(thd, ER_TRUNCATED_WRONG_VALUE), char_type,
err.ptr());
+ thd->abort_on_warning= save_abort_on_warning;
}
}
-String *Item_char_typecast::reuse(String *src, uint32 length)
+String *Item_char_typecast::reuse(String *src, size_t length)
{
DBUG_ASSERT(length <= src->length());
check_truncation_with_warn(src, length);
@@ -2551,7 +2549,7 @@ void Item_char_typecast::fix_length_and_dec_numeric()
}
-void Item_char_typecast::fix_length_and_dec_str()
+void Item_char_typecast::fix_length_and_dec_generic()
{
fix_length_and_dec_internal(from_cs= args[0]->dynamic_result() ?
0 :
@@ -2604,17 +2602,12 @@ void Item_char_typecast::fix_length_and_dec_internal(CHARSET_INFO *from_cs)
bool Item_time_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
- if (get_arg0_time(ltime))
- return 1;
+ Time tm(args[0], Time::Options_for_cast());
+ if ((null_value= !tm.is_valid_time()))
+ return true;
+ tm.copy_to_mysql_time(ltime);
if (decimals < TIME_SECOND_PART_DIGITS)
my_time_trunc(ltime, decimals);
- /*
- MYSQL_TIMESTAMP_TIME value can have non-zero day part,
- which we should not lose.
- */
- if (ltime->time_type != MYSQL_TIMESTAMP_TIME)
- ltime->year= ltime->month= ltime->day= 0;
- ltime->time_type= MYSQL_TIMESTAMP_TIME;
return (fuzzy_date & TIME_TIME_ONLY) ? 0 :
(null_value= check_date_with_warn(ltime, fuzzy_date,
MYSQL_TIMESTAMP_ERROR));
@@ -2768,7 +2761,7 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
// ADDTIME function AND the first argument is TIME
if (args[0]->get_time(&l_time1) ||
args[1]->get_time(&l_time2) ||
- l_time2.time_type == MYSQL_TIMESTAMP_DATETIME)
+ l_time2.time_type != MYSQL_TIMESTAMP_TIME)
return (null_value= 1);
is_time= (l_time1.time_type == MYSQL_TIMESTAMP_TIME);
}
@@ -2933,10 +2926,9 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
longlong Item_func_microsecond::val_int()
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- if (!get_arg0_date(&ltime, TIME_TIME_ONLY))
- return ltime.second_part;
- return 0;
+ Time tm(args[0], Time::Options_for_cast());
+ return ((null_value= !tm.is_valid_time())) ?
+ 0 : tm.get_mysql_time()->second_part;
}
@@ -2947,14 +2939,13 @@ longlong Item_func_timestamp_diff::val_int()
long microseconds;
long months= 0;
int neg= 1;
+ THD *thd= current_thd;
+ ulonglong fuzzydate= TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE;
+
+ null_value= 0;
- null_value= 0;
- if (args[0]->get_date_with_conversion(&ltime1,
- TIME_NO_ZERO_DATE |
- TIME_NO_ZERO_IN_DATE) ||
- args[1]->get_date_with_conversion(&ltime2,
- TIME_NO_ZERO_DATE |
- TIME_NO_ZERO_IN_DATE))
+ if (Datetime(thd, args[0], fuzzydate).copy_to_mysql_time(&ltime1) ||
+ Datetime(thd, args[1], fuzzydate).copy_to_mysql_time(&ltime2))
goto null_date;
if (calc_time_diff(&ltime2,&ltime1, 1,
@@ -3320,7 +3311,7 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
bool Item_func_last_day::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
- if (get_arg0_date(ltime, fuzzy_date) ||
+ if (get_arg0_date(ltime, fuzzy_date & ~TIME_TIME_ONLY) ||
(ltime->month == 0))
return (null_value=1);
uint month_idx= ltime->month-1;
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 9c102e8a666..c3bda9d85ba 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -66,8 +66,8 @@ public:
{
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_period_add>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_period_add>(thd, this); }
};
@@ -84,8 +84,8 @@ public:
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_period_diff>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_period_diff>(thd, this); }
};
@@ -109,8 +109,8 @@ public:
{
return !has_date_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_to_days>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_to_days>(thd, this); }
};
@@ -137,8 +137,8 @@ public:
{
return !has_date_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_to_seconds>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_to_seconds>(thd, this); }
};
@@ -160,8 +160,8 @@ public:
{
return !has_date_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_dayofmonth>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_dayofmonth>(thd, this); }
};
@@ -181,6 +181,10 @@ public:
str->set(nr, collation.collation);
return str;
}
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return get_date_from_int(ltime, fuzzydate);
+ }
const char *func_name() const { return "month"; }
const Type_handler *type_handler() const { return &type_handler_long; }
void fix_length_and_dec()
@@ -195,8 +199,8 @@ public:
{
return !has_date_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_month>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_month>(thd, this); }
};
@@ -217,8 +221,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_monthname>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_monthname>(thd, this); }
};
@@ -240,8 +244,8 @@ public:
{
return !has_date_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_dayofyear>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_dayofyear>(thd, this); }
};
@@ -263,8 +267,8 @@ public:
{
return !has_time_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_hour>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_hour>(thd, this); }
};
@@ -286,8 +290,8 @@ public:
{
return !has_time_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_minute>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_minute>(thd, this); }
};
@@ -309,8 +313,8 @@ public:
{
return !has_date_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_quarter>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_quarter>(thd, this); }
};
@@ -332,8 +336,8 @@ public:
{
return !has_time_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_second>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_second>(thd, this); }
};
@@ -365,8 +369,8 @@ public:
{
return arg_count == 2;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_week>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_week>(thd, this); }
};
class Item_func_yearweek :public Item_long_func
@@ -393,8 +397,8 @@ public:
{
return !has_date_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_yearweek>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_yearweek>(thd, this); }
};
@@ -418,8 +422,8 @@ public:
{
return !has_date_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_year>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_year>(thd, this); }
};
@@ -441,6 +445,10 @@ public:
{
return (odbc_type ? "dayofweek" : "weekday");
}
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ }
const Type_handler *type_handler() const { return &type_handler_long; }
void fix_length_and_dec()
{
@@ -454,8 +462,8 @@ public:
{
return !has_date_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_weekday>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_weekday>(thd, this); }
};
class Item_func_dayname :public Item_func_weekday
@@ -533,8 +541,8 @@ public:
}
longlong int_op();
my_decimal *decimal_op(my_decimal* buf);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_unix_timestamp>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_unix_timestamp>(thd, this); }
};
@@ -556,8 +564,8 @@ public:
}
longlong int_op();
my_decimal *decimal_op(my_decimal* buf);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_time_to_sec>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_time_to_sec>(thd, this); }
};
@@ -684,8 +692,8 @@ public:
Item_func_curtime_local(THD *thd, uint dec): Item_func_curtime(thd, dec) {}
const char *func_name() const { return "curtime"; }
virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_curtime_local>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_curtime_local>(thd, this); }
};
@@ -695,8 +703,8 @@ public:
Item_func_curtime_utc(THD *thd, uint dec): Item_func_curtime(thd, dec) {}
const char *func_name() const { return "utc_time"; }
virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_curtime_utc>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_curtime_utc>(thd, this); }
};
@@ -723,8 +731,8 @@ public:
Item_func_curdate_local(THD *thd): Item_func_curdate(thd) {}
const char *func_name() const { return "curdate"; }
void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_curdate_local>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_curdate_local>(thd, this); }
};
@@ -734,8 +742,8 @@ public:
Item_func_curdate_utc(THD *thd): Item_func_curdate(thd) {}
const char *func_name() const { return "utc_date"; }
void store_now_in_TIME(THD* thd, MYSQL_TIME *now_time);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_curdate_utc>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_curdate_utc>(thd, this); }
};
@@ -772,8 +780,8 @@ public:
int save_in_field(Field *field, bool no_conversions);
virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
virtual enum Functype functype() const { return NOW_FUNC; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_now_local>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_now_local>(thd, this); }
};
@@ -789,8 +797,8 @@ public:
return mark_unsupported_function(func_name(), "()", arg,
VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_now_utc>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_now_utc>(thd, this); }
};
@@ -813,8 +821,8 @@ public:
VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC);
}
virtual enum Functype functype() const { return SYSDATE_FUNC; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sysdate_local>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sysdate_local>(thd, this); }
};
@@ -832,8 +840,8 @@ public:
{
return has_date_args() || has_time_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_from_days>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_from_days>(thd, this); }
};
@@ -860,8 +868,8 @@ public:
return false;
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_date_format>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_date_format>(thd, this); }
};
class Item_func_time_format: public Item_func_date_format
@@ -871,8 +879,8 @@ public:
Item_func_date_format(thd, a, b) { is_time_format= true; }
const char *func_name() const { return "time_format"; }
bool check_vcol_func_processor(void *arg) { return false; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_time_format>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_time_format>(thd, this); }
};
@@ -886,8 +894,8 @@ class Item_func_from_unixtime :public Item_datetimefunc
const char *func_name() const { return "from_unixtime"; }
void fix_length_and_dec();
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_from_unixtime>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_from_unixtime>(thd, this); }
};
@@ -931,8 +939,8 @@ class Item_func_convert_tz :public Item_datetimefunc
}
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
void cleanup();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_convert_tz>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_convert_tz>(thd, this); }
};
@@ -949,8 +957,8 @@ public:
maybe_null= true;
}
const char *func_name() const { return "sec_to_time"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sec_to_time>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_sec_to_time>(thd, this); }
};
@@ -970,8 +978,8 @@ public:
void print(String *str, enum_query_type query_type);
enum precedence precedence() const { return ADDINTERVAL_PRECEDENCE; }
bool need_parentheses_in_default() { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_date_add_interval>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_date_add_interval>(thd, this); }
};
@@ -1078,8 +1086,8 @@ class Item_extract :public Item_int_func
}
return true;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_extract>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_extract>(thd, this); }
};
@@ -1089,30 +1097,37 @@ class Item_char_typecast :public Item_str_func
CHARSET_INFO *cast_cs, *from_cs;
bool charset_conversion;
String tmp_value;
+ bool m_suppress_warning_to_error_escalation;
bool has_explicit_length() const { return cast_length != ~0U; }
- String *reuse(String *src, uint32 length);
+ String *reuse(String *src, size_t length);
String *copy(String *src, CHARSET_INFO *cs);
uint adjusted_length_with_warn(uint length);
- void check_truncation_with_warn(String *src, uint dstlen);
+ void check_truncation_with_warn(String *src, size_t dstlen);
void fix_length_and_dec_internal(CHARSET_INFO *fromcs);
public:
Item_char_typecast(THD *thd, Item *a, uint length_arg, CHARSET_INFO *cs_arg):
- Item_str_func(thd, a), cast_length(length_arg), cast_cs(cs_arg) {}
+ Item_str_func(thd, a), cast_length(length_arg), cast_cs(cs_arg),
+ m_suppress_warning_to_error_escalation(false) {}
enum Functype functype() const { return CHAR_TYPECAST_FUNC; }
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "cast_as_char"; }
CHARSET_INFO *cast_charset() const { return cast_cs; }
String *val_str(String *a);
+ void fix_length_and_dec_generic();
void fix_length_and_dec_numeric();
- void fix_length_and_dec_str();
+ void fix_length_and_dec_str()
+ {
+ fix_length_and_dec_generic();
+ m_suppress_warning_to_error_escalation= true;
+ }
void fix_length_and_dec()
{
args[0]->type_handler()->Item_char_typecast_fix_length_and_dec(this);
}
void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_char_typecast>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_char_typecast>(thd, this); }
};
@@ -1136,8 +1151,8 @@ public:
{
args[0]->type_handler()->Item_date_typecast_fix_length_and_dec(this);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_date_typecast>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_date_typecast>(thd, this); }
};
@@ -1154,8 +1169,8 @@ public:
{
args[0]->type_handler()->Item_time_typecast_fix_length_and_dec(this);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_time_typecast>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_time_typecast>(thd, this); }
};
@@ -1172,8 +1187,8 @@ public:
{
args[0]->type_handler()->Item_datetime_typecast_fix_length_and_dec(this);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_datetime_typecast>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_datetime_typecast>(thd, this); }
};
@@ -1186,8 +1201,8 @@ public:
Item_datefunc(thd, a, b) {}
const char *func_name() const { return "makedate"; }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_makedate>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_makedate>(thd, this); }
};
@@ -1204,8 +1219,8 @@ public:
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
void print(String *str, enum_query_type query_type);
const char *func_name() const { return "add_time"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_add_time>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_add_time>(thd, this); }
};
class Item_func_timediff :public Item_timefunc
@@ -1222,8 +1237,8 @@ public:
maybe_null= true;
}
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_timediff>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_timediff>(thd, this); }
};
class Item_func_maketime :public Item_timefunc
@@ -1244,8 +1259,8 @@ public:
}
const char *func_name() const { return "maketime"; }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_maketime>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_maketime>(thd, this); }
};
@@ -1267,8 +1282,8 @@ public:
{
return !has_time_args();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_microsecond>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_microsecond>(thd, this); }
};
@@ -1288,8 +1303,8 @@ public:
maybe_null=1;
}
virtual void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_timestamp_diff>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_timestamp_diff>(thd, this); }
};
@@ -1314,8 +1329,8 @@ public:
fix_length_and_charset(17, default_charset());
}
virtual void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_get_format>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_get_format>(thd, this); }
};
@@ -1334,8 +1349,8 @@ public:
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
const char *func_name() const { return "str_to_date"; }
void fix_length_and_dec();
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_str_to_date>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_str_to_date>(thd, this); }
};
@@ -1347,8 +1362,8 @@ public:
Item_func_last_day(THD *thd, Item *a): Item_datefunc(thd, a) {}
const char *func_name() const { return "last_day"; }
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_last_day>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_last_day>(thd, this); }
};
#endif /* ITEM_TIMEFUNC_INCLUDED */
diff --git a/sql/item_vers.cc b/sql/item_vers.cc
new file mode 100644
index 00000000000..32a6c67f2fe
--- /dev/null
+++ b/sql/item_vers.cc
@@ -0,0 +1,182 @@
+/* Copyright (c) 2017, 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-1301, USA */
+
+
+/**
+ @brief
+ System Versioning items
+*/
+
+#include "mariadb.h"
+#include "sql_priv.h"
+
+#include "sql_class.h"
+#include "tztime.h"
+#include "item.h"
+
+Item_func_vtq_ts::Item_func_vtq_ts(THD *thd, Item* a, TR_table::field_id_t _vtq_field) :
+ Item_datetimefunc(thd, a),
+ vtq_field(_vtq_field)
+{
+ decimals= 6;
+ null_value= true;
+ DBUG_ASSERT(arg_count == 1 && args[0]);
+}
+
+
+bool
+Item_func_vtq_ts::get_date(MYSQL_TIME *res, ulonglong fuzzy_date)
+{
+ THD *thd= current_thd; // can it differ from constructor's?
+ DBUG_ASSERT(thd);
+ DBUG_ASSERT(args[0]);
+ if (args[0]->result_type() != INT_RESULT)
+ {
+ my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0),
+ args[0]->type_handler()->name().ptr(),
+ func_name());
+ return true;
+ }
+ ulonglong trx_id= args[0]->val_uint();
+ if (trx_id == ULONGLONG_MAX)
+ {
+ null_value= false;
+ thd->variables.time_zone->gmt_sec_to_TIME(res, TIMESTAMP_MAX_VALUE);
+ res->second_part= TIME_MAX_SECOND_PART;
+ return false;
+ }
+
+ TR_table trt(thd);
+
+ null_value= !trt.query(trx_id);
+ if (null_value)
+ {
+ my_error(ER_VERS_NO_TRX_ID, MYF(0), (longlong) trx_id);
+ return true;
+ }
+
+ return trt[vtq_field]->get_date(res, fuzzy_date);
+}
+
+
+Item_func_vtq_id::Item_func_vtq_id(THD *thd, Item* a, TR_table::field_id_t _vtq_field,
+ bool _backwards) :
+ Item_longlong_func(thd, a),
+ vtq_field(_vtq_field),
+ backwards(_backwards)
+{
+ decimals= 0;
+ unsigned_flag= 1;
+ null_value= true;
+ DBUG_ASSERT(arg_count == 1 && args[0]);
+}
+
+Item_func_vtq_id::Item_func_vtq_id(THD *thd, Item* a, Item* b, TR_table::field_id_t _vtq_field) :
+ Item_longlong_func(thd, a, b),
+ vtq_field(_vtq_field),
+ backwards(false)
+{
+ decimals= 0;
+ unsigned_flag= 1;
+ null_value= true;
+ DBUG_ASSERT(arg_count == 2 && args[0] && args[1]);
+}
+
+longlong
+Item_func_vtq_id::get_by_trx_id(ulonglong trx_id)
+{
+ THD *thd= current_thd;
+ DBUG_ASSERT(thd);
+
+ if (trx_id == ULONGLONG_MAX)
+ {
+ null_value= true;
+ return 0;
+ }
+
+ TR_table trt(thd);
+ null_value= !trt.query(trx_id);
+ if (null_value)
+ return 0;
+
+ return trt[vtq_field]->val_int();
+}
+
+longlong
+Item_func_vtq_id::get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards)
+{
+ THD *thd= current_thd;
+ DBUG_ASSERT(thd);
+
+ TR_table trt(thd);
+ null_value= !trt.query(commit_ts, backwards);
+ if (null_value)
+ return 0;
+
+ return trt[vtq_field]->val_int();
+}
+
+longlong
+Item_func_vtq_id::val_int()
+{
+ if (args[0]->is_null())
+ {
+ if (arg_count < 2 || vtq_field == TR_table::FLD_TRX_ID)
+ {
+ null_value= true;
+ return 0;
+ }
+ return get_by_trx_id(args[1]->val_uint());
+ }
+ else
+ {
+ MYSQL_TIME commit_ts;
+ if (args[0]->get_date(&commit_ts, 0))
+ {
+ null_value= true;
+ return 0;
+ }
+ if (arg_count > 1)
+ {
+ backwards= args[1]->val_bool();
+ DBUG_ASSERT(arg_count == 2);
+ }
+ return get_by_commit_ts(commit_ts, backwards);
+ }
+}
+
+Item_func_vtq_trx_sees::Item_func_vtq_trx_sees(THD *thd, Item* a, Item* b) :
+ Item_bool_func(thd, a, b),
+ accept_eq(false)
+{
+ null_value= true;
+ DBUG_ASSERT(arg_count == 2 && args[0] && args[1]);
+}
+
+longlong
+Item_func_vtq_trx_sees::val_int()
+{
+ THD *thd= current_thd;
+ DBUG_ASSERT(thd);
+
+ DBUG_ASSERT(arg_count > 1);
+ ulonglong trx_id1= args[0]->val_uint();
+ ulonglong trx_id0= args[1]->val_uint();
+ bool result= accept_eq;
+
+ TR_table trt(thd);
+ null_value= trt.query_sees(result, trx_id1, trx_id0);
+ return result;
+}
diff --git a/sql/item_vers.h b/sql/item_vers.h
new file mode 100644
index 00000000000..39ed4ecda1f
--- /dev/null
+++ b/sql/item_vers.h
@@ -0,0 +1,114 @@
+#ifndef ITEM_VERS_INCLUDED
+#define ITEM_VERS_INCLUDED
+/* Copyright (c) 2017, 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-1301, USA */
+
+
+/* System Versioning items */
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface /* gcc class implementation */
+#endif
+
+class Item_func_vtq_ts: public Item_datetimefunc
+{
+ TR_table::field_id_t vtq_field;
+public:
+ Item_func_vtq_ts(THD *thd, Item* a, TR_table::field_id_t _vtq_field);
+ const char *func_name() const
+ {
+ if (vtq_field == TR_table::FLD_BEGIN_TS)
+ {
+ return "vtq_begin_ts";
+ }
+ return "vtq_commit_ts";
+ }
+ bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_vtq_ts>(thd, this); }
+ void fix_length_and_dec() { fix_attributes_datetime(decimals); }
+};
+
+class Item_func_vtq_id : public Item_longlong_func
+{
+ TR_table::field_id_t vtq_field;
+ bool backwards;
+
+ longlong get_by_trx_id(ulonglong trx_id);
+ longlong get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards);
+
+public:
+ Item_func_vtq_id(THD *thd, Item* a, TR_table::field_id_t _vtq_field, bool _backwards= false);
+ Item_func_vtq_id(THD *thd, Item* a, Item* b, TR_table::field_id_t _vtq_field);
+
+ const char *func_name() const
+ {
+ switch (vtq_field)
+ {
+ case TR_table::FLD_TRX_ID:
+ return "vtq_trx_id";
+ case TR_table::FLD_COMMIT_ID:
+ return "vtq_commit_id";
+ case TR_table::FLD_ISO_LEVEL:
+ return "vtq_iso_level";
+ default:
+ DBUG_ASSERT(0);
+ }
+ return NULL;
+ }
+
+ void fix_length_and_dec()
+ {
+ Item_int_func::fix_length_and_dec();
+ max_length= 20;
+ }
+
+ longlong val_int();
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_vtq_id>(thd, this); }
+};
+
+class Item_func_vtq_trx_sees : public Item_bool_func
+{
+protected:
+ bool accept_eq;
+
+public:
+ Item_func_vtq_trx_sees(THD *thd, Item* a, Item* b);
+ const char *func_name() const
+ {
+ return "vtq_trx_sees";
+ }
+ longlong val_int();
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_vtq_trx_sees>(thd, this); }
+};
+
+class Item_func_vtq_trx_sees_eq :
+ public Item_func_vtq_trx_sees
+{
+public:
+ Item_func_vtq_trx_sees_eq(THD *thd, Item* a, Item* b) :
+ Item_func_vtq_trx_sees(thd, a, b)
+ {
+ accept_eq= true;
+ }
+ const char *func_name() const
+ {
+ return "vtq_trx_sees_eq";
+ }
+};
+
+#endif /* ITEM_VERS_INCLUDED */
diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc
index 8432ab43ad8..85ca8b0624e 100644
--- a/sql/item_windowfunc.cc
+++ b/sql/item_windowfunc.cc
@@ -334,8 +334,8 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref)
return TRUE;
}
Type_std_attributes::set(args[0]);
- for (uint i= 0; i < arg_count && !with_subselect; i++)
- with_subselect= with_subselect || args[i]->with_subselect;
+ for (uint i= 0; i < arg_count && !m_with_subquery; i++)
+ m_with_subquery|= args[i]->with_subquery();
Item *item2= args[0]->real_item();
if (item2->type() == Item::FIELD_ITEM)
@@ -440,6 +440,17 @@ Item_sum_hybrid_simple::val_str(String *str)
return retval;
}
+bool Item_sum_hybrid_simple::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ DBUG_ASSERT(fixed == 1);
+ if (null_value)
+ return 0;
+ bool retval= value->get_date(ltime, fuzzydate);
+ if ((null_value= value->null_value))
+ DBUG_ASSERT(retval == true);
+ return retval;
+}
+
Field *Item_sum_hybrid_simple::create_tmp_field(bool group, TABLE *table)
{
DBUG_ASSERT(0);
@@ -536,5 +547,10 @@ void Item_window_func::print(String *str, enum_query_type query_type)
{
window_func()->print(str, query_type);
str->append(" over ");
+#ifndef DBUG_OFF
+ if (!window_spec) // one can call dbug_print_item() anytime in gdb
+ str->append(window_name);
+ else
+#endif
window_spec->print(str, query_type);
}
diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h
index 849c298f5aa..cb85a2c06d1 100644
--- a/sql/item_windowfunc.h
+++ b/sql/item_windowfunc.h
@@ -146,8 +146,8 @@ public:
return "row_number";
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_row_number>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_row_number>(thd, this); }
};
@@ -221,8 +221,8 @@ public:
}
Item_sum_int::cleanup();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_rank>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_rank>(thd, this); }
};
@@ -291,8 +291,8 @@ class Item_sum_dense_rank: public Item_sum_int
}
Item_sum_int::cleanup();
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_dense_rank>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_dense_rank>(thd, this); }
};
class Item_sum_hybrid_simple : public Item_sum,
@@ -319,6 +319,7 @@ class Item_sum_hybrid_simple : public Item_sum,
my_decimal *val_decimal(my_decimal *);
void reset_field();
String *val_str(String *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
void update_field();
@@ -354,8 +355,8 @@ class Item_sum_first_value : public Item_sum_hybrid_simple
return "first_value";
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_first_value>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_first_value>(thd, this); }
};
/*
@@ -380,8 +381,8 @@ class Item_sum_last_value : public Item_sum_hybrid_simple
return "last_value";
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_last_value>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_last_value>(thd, this); }
};
class Item_sum_nth_value : public Item_sum_hybrid_simple
@@ -400,8 +401,8 @@ class Item_sum_nth_value : public Item_sum_hybrid_simple
return "nth_value";
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_nth_value>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_nth_value>(thd, this); }
};
class Item_sum_lead : public Item_sum_hybrid_simple
@@ -420,8 +421,8 @@ class Item_sum_lead : public Item_sum_hybrid_simple
return "lead";
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_lead>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_lead>(thd, this); }
};
class Item_sum_lag : public Item_sum_hybrid_simple
@@ -440,8 +441,8 @@ class Item_sum_lag : public Item_sum_hybrid_simple
return "lag";
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_lag>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_lag>(thd, this); }
};
/*
@@ -532,8 +533,8 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count
}
void setup_window_func(THD *thd, Window_spec *window_spec);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_percent_rank>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_percent_rank>(thd, this); }
private:
longlong cur_rank; // Current rank of the current row.
@@ -619,8 +620,8 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
// requires.
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_cume_dist>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_cume_dist>(thd, this); }
ulonglong get_row_number()
{
@@ -694,8 +695,8 @@ class Item_sum_ntile : public Item_sum_window_with_row_count
const Type_handler *type_handler() const { return &type_handler_longlong; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_ntile>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_ntile>(thd, this); }
private:
longlong get_num_quantiles() { return args[0]->val_int(); }
@@ -825,8 +826,8 @@ public:
// requires.
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_percentile_disc>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_percentile_disc>(thd, this); }
void setup_window_func(THD *thd, Window_spec *window_spec);
void setup_hybrid(THD *thd, Item *item);
bool fix_fields(THD *thd, Item **ref);
@@ -955,8 +956,8 @@ public:
// requires.
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_sum_percentile_cont>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_percentile_cont>(thd, this); }
void setup_window_func(THD *thd, Window_spec *window_spec);
void setup_hybrid(THD *thd, Item *item);
bool fix_fields(THD *thd, Item **ref);
@@ -1265,6 +1266,29 @@ public:
return res;
}
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ bool res;
+ if (force_return_blank)
+ {
+ null_value= true;
+ res= true;
+ }
+ else if (read_value_from_result_field)
+ {
+ if ((null_value= result_field->is_null()))
+ res= true;
+ else
+ res= result_field->get_date(ltime, fuzzydate);
+ }
+ else
+ {
+ res= window_func()->get_date(ltime, fuzzydate);
+ null_value= window_func()->null_value;
+ }
+ return res;
+ }
+
void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &fields, uint flags);
@@ -1281,7 +1305,7 @@ public:
void print(String *str, enum_query_type query_type);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ Item *get_copy(THD *thd) { return 0; }
};
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index b08d43f041c..5156bd08ef2 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -247,8 +247,8 @@ public:
Item_nodeset_func(thd, pxml) {}
const char *func_name() const { return "xpath_rootelement"; }
String *val_nodeset(String *nodeset);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_func_rootelement>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_func_rootelement>(thd, this); }
};
@@ -260,8 +260,8 @@ public:
Item_nodeset_func(thd, a, b, pxml) {}
const char *func_name() const { return "xpath_union"; }
String *val_nodeset(String *nodeset);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_func_union>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_func_union>(thd, this); }
};
@@ -294,8 +294,8 @@ public:
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
const char *func_name() const { return "xpath_selfbyname"; }
String *val_nodeset(String *nodeset);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_func_selfbyname>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_func_selfbyname>(thd, this); }
};
@@ -308,8 +308,8 @@ public:
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
const char *func_name() const { return "xpath_childbyname"; }
String *val_nodeset(String *nodeset);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_func_childbyname>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_func_childbyname>(thd, this); }
};
@@ -324,8 +324,8 @@ public:
need_self(need_self_arg) {}
const char *func_name() const { return "xpath_descendantbyname"; }
String *val_nodeset(String *nodeset);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_func_descendantbyname>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_func_descendantbyname>(thd, this); }
};
@@ -340,8 +340,8 @@ public:
need_self(need_self_arg) {}
const char *func_name() const { return "xpath_ancestorbyname"; }
String *val_nodeset(String *nodeset);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_func_ancestorbyname>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_func_ancestorbyname>(thd, this); }
};
@@ -354,8 +354,8 @@ public:
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
const char *func_name() const { return "xpath_parentbyname"; }
String *val_nodeset(String *nodeset);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_func_parentbyname>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_func_parentbyname>(thd, this); }
};
@@ -368,8 +368,8 @@ public:
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
const char *func_name() const { return "xpath_attributebyname"; }
String *val_nodeset(String *nodeset);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_func_attributebyname>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_func_attributebyname>(thd, this); }
};
@@ -385,8 +385,8 @@ public:
Item_nodeset_func(thd, a, b, pxml) {}
const char *func_name() const { return "xpath_predicate"; }
String *val_nodeset(String *nodeset);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_func_predicate>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_func_predicate>(thd, this); }
};
@@ -398,8 +398,8 @@ public:
Item_nodeset_func(thd, a, b, pxml) { }
const char *func_name() const { return "xpath_elementbyindex"; }
String *val_nodeset(String *nodeset);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_func_elementbyindex>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_func_elementbyindex>(thd, this); }
};
@@ -426,8 +426,8 @@ public:
}
return args[0]->val_real() ? 1 : 0;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_xpath_cast_bool>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_xpath_cast_bool>(thd, this); }
};
@@ -440,8 +440,8 @@ public:
Item_xpath_cast_number(THD *thd, Item *a): Item_real_func(thd, a) {}
const char *func_name() const { return "xpath_cast_number"; }
virtual double val_real() { return args[0]->val_real(); }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_xpath_cast_number>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_xpath_cast_number>(thd, this); }
};
@@ -457,8 +457,8 @@ public:
String *val_nodeset(String *res)
{ return string_cache; }
void fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_context_cache>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_context_cache>(thd, this); }
};
@@ -478,8 +478,8 @@ public:
return ((MY_XPATH_FLT*)flt->ptr())->pos + 1;
return 0;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_xpath_position>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_xpath_position>(thd, this); }
};
@@ -501,8 +501,8 @@ public:
return predicate_supplied_context_size;
return res->length() / sizeof(MY_XPATH_FLT);
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_xpath_count>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_xpath_count>(thd, this); }
};
@@ -546,8 +546,8 @@ public:
}
return sum;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_xpath_sum>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_xpath_sum>(thd, this); }
};
@@ -624,8 +624,8 @@ public:
}
return 0;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_nodeset_to_const_comparator>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_nodeset_to_const_comparator>(thd, this); }
};
@@ -2734,7 +2734,7 @@ void Item_xml_str_func::fix_length_and_dec()
bool Item_xml_str_func::fix_fields(THD *thd, Item **ref)
{
- String *xp, tmp;
+ String *xp;
MY_XPATH xpath;
int rc;
@@ -2762,7 +2762,13 @@ bool Item_xml_str_func::fix_fields(THD *thd, Item **ref)
return true;
}
- if (!(xp= args[1]->val_str(&tmp)))
+ /*
+ Get the XPath query text from args[1] and cache it in m_xpath_query.
+ Its fragments will be referenced by items created during my_xpath_parse(),
+ e.g. by Item_nodeset_func_axisbyname::node_name.
+ */
+ if (!(xp= args[1]->val_str(&m_xpath_query)) ||
+ (xp != &m_xpath_query && m_xpath_query.copy(*xp)))
return false; // Will return NULL
my_xpath_init(&xpath);
xpath.thd= thd;
diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h
index 3c071b897e2..33e85ba5628 100644
--- a/sql/item_xmlfunc.h
+++ b/sql/item_xmlfunc.h
@@ -62,6 +62,7 @@ protected:
return parse(res, cache);
}
};
+ String m_xpath_query; // XPath query text
Item *nodeset_func;
XML xml;
bool get_xml(XML *xml_arg, bool cache= false)
@@ -96,8 +97,8 @@ public:
Item_xml_str_func(thd, a, b) {}
const char *func_name() const { return "extractvalue"; }
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_xml_extractvalue>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_xml_extractvalue>(thd, this); }
};
@@ -112,8 +113,8 @@ public:
Item_xml_str_func(thd, a, b, c) {}
const char *func_name() const { return "updatexml"; }
String *val_str(String *);
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_xml_update>(thd, mem_root, this); }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_func_xml_update>(thd, this); }
};
#endif /* ITEM_XMLFUNC_INCLUDED */
diff --git a/sql/key.cc b/sql/key.cc
index 3ee083e560f..8642820ff3f 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2018, 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
@@ -21,9 +22,6 @@
#include "key.h" // key_rec_cmp
#include "field.h" // Field
-using std::min;
-using std::max;
-
/*
Search after a key that starts with 'field'
@@ -65,7 +63,8 @@ int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
i < (int) key_count ;
i++, key_info++)
{
- if (key_info->key_part[0].offset == fieldpos)
+ if (key_info->key_part[0].offset == fieldpos &&
+ key_info->key_part[0].field->type() != MYSQL_TYPE_BIT)
{ /* Found key. Calc keylength */
*key_length= *keypart= 0;
return i; /* Use this key */
@@ -84,7 +83,8 @@ int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
j < key_info->user_defined_key_parts ;
j++, key_part++)
{
- if (key_part->offset == fieldpos)
+ if (key_part->offset == fieldpos &&
+ key_part->field->type() != MYSQL_TYPE_BIT)
{
*keypart= j;
return i; /* Use this key */
@@ -135,7 +135,7 @@ void key_copy(uchar *to_key, const uchar *from_record, KEY *key_info,
Don't copy data for null values
The -1 below is to subtract the null byte which is already handled
*/
- length= min<uint>(key_length, key_part->store_length-1);
+ length= MY_MIN(key_length, uint(key_part->store_length)-1);
if (with_zerofill)
bzero((char*) to_key, length);
continue;
@@ -145,7 +145,7 @@ void key_copy(uchar *to_key, const uchar *from_record, KEY *key_info,
key_part->key_part_flag & HA_VAR_LENGTH_PART)
{
key_length-= HA_KEY_BLOB_LENGTH;
- length= min<uint>(key_length, key_part->length);
+ length= MY_MIN(key_length, key_part->length);
uint bytes= key_part->field->get_key_image(to_key, length, Field::itRAW);
if (with_zerofill && bytes < length)
bzero((char*) to_key + bytes, length - bytes);
@@ -153,7 +153,7 @@ void key_copy(uchar *to_key, const uchar *from_record, KEY *key_info,
}
else
{
- length= min<uint>(key_length, key_part->length);
+ length= MY_MIN(key_length, key_part->length);
Field *field= key_part->field;
CHARSET_INFO *cs= field->charset();
uint bytes= field->get_key_image(to_key, length, Field::itRAW);
@@ -205,7 +205,7 @@ void key_restore(uchar *to_record, const uchar *from_key, KEY *key_info,
Don't copy data for null bytes
The -1 below is to subtract the null byte which is already handled
*/
- length= min<uint>(key_length, key_part->store_length-1);
+ length= MY_MIN(key_length, uint(key_part->store_length)-1);
continue;
}
}
@@ -247,7 +247,7 @@ void key_restore(uchar *to_record, const uchar *from_key, KEY *key_info,
my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
field->move_field_offset(ptrdiff);
key_length-= HA_KEY_BLOB_LENGTH;
- length= min<uint>(key_length, key_part->length);
+ length= MY_MIN(key_length, key_part->length);
old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
field->set_key_image(from_key, length);
dbug_tmp_restore_column_map(field->table->write_set, old_map);
@@ -256,7 +256,7 @@ void key_restore(uchar *to_record, const uchar *from_key, KEY *key_info,
}
else
{
- length= min<uint>(key_length, key_part->length);
+ length= MY_MIN(key_length, key_part->length);
/* skip the byte with 'uneven' bits, if used */
memcpy(to_record + key_part->offset, from_key + used_uneven_bits
, (size_t) length - used_uneven_bits);
@@ -314,12 +314,12 @@ bool key_cmp_if_same(TABLE *table,const uchar *key,uint idx,uint key_length)
return 1;
continue;
}
- length= min((uint) (key_end-key), store_length);
+ length= MY_MIN((uint) (key_end-key), store_length);
if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
FIELDFLAG_PACK)))
{
CHARSET_INFO *cs= key_part->field->charset();
- uint char_length= key_part->length / cs->mbmaxlen;
+ size_t char_length= key_part->length / cs->mbmaxlen;
const uchar *pos= table->record[0] + key_part->offset;
if (length > char_length)
{
@@ -385,14 +385,14 @@ void field_unpack(String *to, Field *field, const uchar *rec, uint max_length,
which can break a multi-byte characters in the middle.
Align, returning not more than "char_length" characters.
*/
- uint charpos, char_length= max_length / cs->mbmaxlen;
+ size_t charpos, char_length= max_length / cs->mbmaxlen;
if ((charpos= my_charpos(cs, tmp.ptr(),
tmp.ptr() + tmp.length(),
char_length)) < tmp.length())
tmp.length(charpos);
}
if (max_length < field->pack_length())
- tmp.length(min(tmp.length(),max_length));
+ tmp.length(MY_MIN(tmp.length(),max_length));
ErrConvString err(&tmp);
to->append(err.ptr());
}
@@ -427,6 +427,8 @@ void key_unpack(String *to, TABLE *table, KEY *key)
key_part < key_part_end;
key_part++)
{
+ if (key_part->field->invisible > INVISIBLE_USER)
+ continue;
if (to->length())
to->append('-');
if (key_part->null_bit)
@@ -697,7 +699,7 @@ ulong key_hashnr(KEY *key_info, uint used_key_parts, const uchar *key)
{
uchar *pos= (uchar*)key;
CHARSET_INFO *UNINIT_VAR(cs);
- uint UNINIT_VAR(length), UNINIT_VAR(pack_length);
+ size_t UNINIT_VAR(length), UNINIT_VAR(pack_length);
bool is_string= TRUE;
key+= key_part->length;
@@ -754,7 +756,7 @@ ulong key_hashnr(KEY *key_info, uint used_key_parts, const uchar *key)
{
if (cs->mbmaxlen > 1)
{
- uint char_length= my_charpos(cs, pos + pack_length,
+ size_t char_length= my_charpos(cs, pos + pack_length,
pos + pack_length + length,
length / cs->mbmaxlen);
set_if_smaller(length, char_length);
@@ -801,7 +803,7 @@ bool key_buf_cmp(KEY *key_info, uint used_key_parts,
uchar *pos1= (uchar*)key1;
uchar *pos2= (uchar*)key2;
CHARSET_INFO *UNINIT_VAR(cs);
- uint UNINIT_VAR(length1), UNINIT_VAR(length2), UNINIT_VAR(pack_length);
+ size_t UNINIT_VAR(length1), UNINIT_VAR(length2), UNINIT_VAR(pack_length);
bool is_string= TRUE;
key1+= key_part->length;
@@ -865,13 +867,13 @@ bool key_buf_cmp(KEY *key_info, uint used_key_parts,
Compare the strings taking into account length in characters
and collation
*/
- uint byte_len1= length1, byte_len2= length2;
+ size_t byte_len1= length1, byte_len2= length2;
if (cs->mbmaxlen > 1)
{
- uint char_length1= my_charpos(cs, pos1 + pack_length,
+ size_t char_length1= my_charpos(cs, pos1 + pack_length,
pos1 + pack_length + length1,
length1 / cs->mbmaxlen);
- uint char_length2= my_charpos(cs, pos2 + pack_length,
+ size_t char_length2= my_charpos(cs, pos2 + pack_length,
pos2 + pack_length + length2,
length2 / cs->mbmaxlen);
set_if_smaller(length1, char_length1);
diff --git a/sql/keycaches.cc b/sql/keycaches.cc
index 6de775d3f2d..9db51ee1801 100644
--- a/sql/keycaches.cc
+++ b/sql/keycaches.cc
@@ -30,17 +30,17 @@ class NAMED_ILINK :public ilink
{
public:
const char *name;
- uint name_length;
+ size_t name_length;
uchar* data;
NAMED_ILINK(I_List<NAMED_ILINK> *links, const char *name_arg,
- uint name_length_arg, uchar* data_arg)
+ size_t name_length_arg, uchar* data_arg)
:name_length(name_length_arg), data(data_arg)
{
name= my_strndup(name_arg, name_length, MYF(MY_WME));
links->push_back(this);
}
- inline bool cmp(const char *name_cmp, uint length)
+ inline bool cmp(const char *name_cmp, size_t length)
{
return length == name_length && !memcmp(name, name_cmp, length);
}
@@ -50,7 +50,7 @@ public:
}
};
-uchar* find_named(I_List<NAMED_ILINK> *list, const char *name, uint length,
+uchar* find_named(I_List<NAMED_ILINK> *list, const char *name, size_t length,
NAMED_ILINK **found)
{
I_List_iterator<NAMED_ILINK> it(*list);
@@ -68,7 +68,7 @@ uchar* find_named(I_List<NAMED_ILINK> *list, const char *name, uint length,
}
-bool NAMED_ILIST::delete_element(const char *name, uint length, void (*free_element)(const char *name, uchar*))
+bool NAMED_ILIST::delete_element(const char *name, size_t length, void (*free_element)(const char *name, uchar*))
{
I_List_iterator<NAMED_ILINK> it(*this);
NAMED_ILINK *element;
@@ -100,7 +100,7 @@ void NAMED_ILIST::delete_elements(void (*free_element)(const char *name, uchar*)
/* Key cache functions */
-LEX_CSTRING default_key_cache_base= {C_STRING_WITH_LEN("default")};
+LEX_CSTRING default_key_cache_base= {STRING_WITH_LEN("default")};
KEY_CACHE zero_key_cache; ///< @@nonexistent_cache.param->value_ptr() points here
@@ -112,11 +112,11 @@ KEY_CACHE *get_key_cache(const LEX_CSTRING *cache_name)
cache_name->str, cache_name->length, 0));
}
-KEY_CACHE *create_key_cache(const char *name, uint length)
+KEY_CACHE *create_key_cache(const char *name, size_t length)
{
KEY_CACHE *key_cache;
DBUG_ENTER("create_key_cache");
- DBUG_PRINT("enter",("name: %.*s", length, name));
+ DBUG_PRINT("enter",("name: %.*s", (int)length, name));
if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE),
MYF(MY_ZEROFILL | MY_WME))))
@@ -144,7 +144,7 @@ KEY_CACHE *create_key_cache(const char *name, uint length)
}
-KEY_CACHE *get_or_create_key_cache(const char *name, uint length)
+KEY_CACHE *get_or_create_key_cache(const char *name, size_t length)
{
LEX_CSTRING key_cache_name;
KEY_CACHE *key_cache;
@@ -180,9 +180,9 @@ bool process_key_caches(process_key_cache_t func, void *param)
/* Rpl_filter functions */
-LEX_STRING default_rpl_filter_base= {C_STRING_WITH_LEN("")};
+LEX_CSTRING default_rpl_filter_base= {STRING_WITH_LEN("")};
-Rpl_filter *get_rpl_filter(LEX_STRING *filter_name)
+Rpl_filter *get_rpl_filter(LEX_CSTRING *filter_name)
{
if (!filter_name->length)
filter_name= &default_rpl_filter_base;
@@ -190,11 +190,11 @@ Rpl_filter *get_rpl_filter(LEX_STRING *filter_name)
filter_name->str, filter_name->length, 0));
}
-Rpl_filter *create_rpl_filter(const char *name, uint length)
+Rpl_filter *create_rpl_filter(const char *name, size_t length)
{
Rpl_filter *filter;
DBUG_ENTER("create_rpl_filter");
- DBUG_PRINT("enter",("name: %.*s", length, name));
+ DBUG_PRINT("enter",("name: %.*s", (int)length, name));
filter= new Rpl_filter;
if (filter)
@@ -209,9 +209,9 @@ Rpl_filter *create_rpl_filter(const char *name, uint length)
}
-Rpl_filter *get_or_create_rpl_filter(const char *name, uint length)
+Rpl_filter *get_or_create_rpl_filter(const char *name, size_t length)
{
- LEX_STRING rpl_filter_name;
+ LEX_CSTRING rpl_filter_name;
Rpl_filter *filter;
rpl_filter_name.str= (char *) name;
diff --git a/sql/keycaches.h b/sql/keycaches.h
index 1b58dccfe34..ff0380ba09a 100644
--- a/sql/keycaches.h
+++ b/sql/keycaches.h
@@ -31,7 +31,7 @@ class NAMED_ILIST: public I_List<NAMED_ILINK>
{
public:
void delete_elements(void (*free_element)(const char*, uchar*));
- bool delete_element(const char *name, uint length, void (*free_element)(const char*, uchar*));
+ bool delete_element(const char *name, size_t length, void (*free_element)(const char*, uchar*));
};
/* For key cache */
@@ -39,19 +39,19 @@ extern LEX_CSTRING default_key_cache_base;
extern KEY_CACHE zero_key_cache;
extern NAMED_ILIST key_caches;
-KEY_CACHE *create_key_cache(const char *name, uint length);
+KEY_CACHE *create_key_cache(const char *name, size_t length);
KEY_CACHE *get_key_cache(const LEX_CSTRING *cache_name);
-KEY_CACHE *get_or_create_key_cache(const char *name, uint length);
+KEY_CACHE *get_or_create_key_cache(const char *name, size_t length);
void free_key_cache(const char *name, KEY_CACHE *key_cache);
bool process_key_caches(process_key_cache_t func, void *param);
/* For Rpl_filter */
-extern LEX_STRING default_rpl_filter_base;
+extern LEX_CSTRING default_rpl_filter_base;
extern NAMED_ILIST rpl_filters;
-Rpl_filter *create_rpl_filter(const char *name, uint length);
-Rpl_filter *get_rpl_filter(LEX_STRING *filter_name);
-Rpl_filter *get_or_create_rpl_filter(const char *name, uint length);
+Rpl_filter *create_rpl_filter(const char *name, size_t length);
+Rpl_filter *get_rpl_filter(LEX_CSTRING *filter_name);
+Rpl_filter *get_or_create_rpl_filter(const char *name, size_t length);
void free_rpl_filter(const char *name, Rpl_filter *filter);
void free_all_rpl_filters(void);
diff --git a/sql/lex.h b/sql/lex.h
index 63b0567c5d0..41a81c737f7 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -181,6 +181,7 @@ static SYMBOL symbols[] = {
{ "DELAYED", SYM(DELAYED_SYM)},
{ "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM)},
{ "DELETE", SYM(DELETE_SYM)},
+ { "DELETE_DOMAIN_ID", SYM(DELETE_DOMAIN_ID_SYM)},
{ "DESC", SYM(DESC)},
{ "DESCRIBE", SYM(DESCRIBE)},
{ "DES_KEY_FILE", SYM(DES_KEY_FILE)},
@@ -272,6 +273,7 @@ static SYMBOL symbols[] = {
{ "HAVING", SYM(HAVING)},
{ "HELP", SYM(HELP_SYM)},
{ "HIGH_PRIORITY", SYM(HIGH_PRIORITY)},
+ { "HISTORY", SYM(HISTORY_SYM)},
{ "HOST", SYM(HOST_SYM)},
{ "HOSTS", SYM(HOSTS_SYM)},
{ "HOUR", SYM(HOUR_SYM)},
@@ -307,6 +309,7 @@ static SYMBOL symbols[] = {
{ "INT8", SYM(BIGINT)},
{ "INTEGER", SYM(INT_SYM)},
{ "INTERVAL", SYM(INTERVAL_SYM)},
+ { "INVISIBLE", SYM(INVISIBLE_SYM)},
{ "INTO", SYM(INTO)},
{ "IO", SYM(IO_SYM)},
{ "IO_THREAD", SYM(RELAY_THREAD)},
@@ -458,6 +461,7 @@ static SYMBOL symbols[] = {
{ "PAGE_CHECKSUM", SYM(PAGE_CHECKSUM_SYM)},
{ "PARSER", SYM(PARSER_SYM)},
{ "PARSE_VCOL_EXPR", SYM(PARSE_VCOL_EXPR_SYM)},
+ { "PERIOD", SYM(PERIOD_SYM)},
{ "PARTIAL", SYM(PARTIAL)},
{ "PARTITION", SYM(PARTITION_SYM)},
{ "PARTITIONING", SYM(PARTITIONING_SYM)},
@@ -627,6 +631,8 @@ static SYMBOL symbols[] = {
{ "SUSPEND", SYM(SUSPEND_SYM)},
{ "SWAPS", SYM(SWAPS_SYM)},
{ "SWITCHES", SYM(SWITCHES_SYM)},
+ { "SYSTEM", SYM(SYSTEM)},
+ { "SYSTEM_TIME", SYM(SYSTEM_TIME_SYM)},
{ "TABLE", SYM(TABLE_SYM)},
{ "TABLE_NAME", SYM(TABLE_NAME_SYM)},
{ "TABLES", SYM(TABLES)},
@@ -692,6 +698,7 @@ static SYMBOL symbols[] = {
{ "VIA", SYM(VIA_SYM)},
{ "VIEW", SYM(VIEW_SYM)},
{ "VIRTUAL", SYM(VIRTUAL_SYM)},
+ { "VERSIONING", SYM(VERSIONING_SYM)},
{ "WAIT", SYM(WAIT_SYM)},
{ "WARNINGS", SYM(WARNINGS)},
{ "WEEK", SYM(WEEK_SYM)},
@@ -702,6 +709,7 @@ static SYMBOL symbols[] = {
{ "WINDOW", SYM(WINDOW_SYM)},
{ "WITH", SYM(WITH)},
{ "WITHIN", SYM(WITHIN)},
+ { "WITHOUT", SYM(WITHOUT)},
{ "WORK", SYM(WORK_SYM)},
{ "WRAPPER", SYM(WRAPPER_SYM)},
{ "WRITE", SYM(WRITE_SYM)},
diff --git a/sql/lex_string.h b/sql/lex_string.h
new file mode 100644
index 00000000000..9df84f67b6a
--- /dev/null
+++ b/sql/lex_string.h
@@ -0,0 +1,52 @@
+/*
+ Copyright (c) 2018, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+
+#ifndef LEX_STRING_INCLUDED
+#define LEX_STRING_INCLUDED
+
+typedef struct st_mysql_const_lex_string LEX_CSTRING;
+
+/* Functions to compare if two lex strings are equal */
+inline bool lex_string_cmp(CHARSET_INFO *charset,
+ const LEX_CSTRING *a,
+ const LEX_CSTRING *b)
+{
+ return my_strcasecmp(charset, a->str, b->str);
+}
+
+/*
+ Compare to LEX_CSTRING's and return 0 if equal
+*/
+inline bool cmp(const LEX_CSTRING *a, const LEX_CSTRING *b)
+{
+ return (a->length != b->length ||
+ memcmp(a->str, b->str, a->length));
+}
+
+/*
+ Compare if two LEX_CSTRING are equal. Assumption is that
+ character set is ASCII (like for plugin names)
+*/
+inline bool lex_string_eq(const LEX_CSTRING *a,
+ const LEX_CSTRING *b)
+{
+ if (a->length != b->length)
+ return 1; /* Different */
+ return strcasecmp(a->str, b->str) != 0;
+}
+
+#endif /* LEX_STRING_INCLUDED */
diff --git a/sql/lock.cc b/sql/lock.cc
index 8e43001e742..864e9f76293 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -294,7 +294,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags)
if (lock_tables_check(thd, tables, count, flags))
DBUG_RETURN(NULL);
- if (!(thd->variables.option_bits & OPTION_TABLE_LOCK))
+ if (!(thd->variables.option_bits & OPTION_TABLE_LOCK) &&
+ !(flags & MYSQL_LOCK_USE_MALLOC))
gld_flags|= GET_LOCK_ON_THD;
if (! (sql_lock= get_lock_data(thd, tables, count, gld_flags)))
@@ -415,7 +416,8 @@ static int lock_external(THD *thd, TABLE **tables, uint count)
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
{
mysql_unlock_tables(thd, sql_lock,
- thd->variables.option_bits & OPTION_TABLE_LOCK);
+ (thd->variables.option_bits & OPTION_TABLE_LOCK) ||
+ !(sql_lock->flags & GET_LOCK_ON_THD));
}
@@ -433,7 +435,10 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
if (sql_lock->lock_count)
thr_multi_unlock(sql_lock->locks, sql_lock->lock_count, 0);
if (free_lock)
+ {
+ DBUG_ASSERT(!(sql_lock->flags & GET_LOCK_ON_THD));
my_free(sql_lock);
+ }
if (!errors)
thd->clear_error();
THD_STAGE_INFO(thd, org_stage);
@@ -668,6 +673,7 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
sql_lock->table_count=a->table_count+b->table_count;
sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count*2);
+ sql_lock->flags= 0;
memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks));
memcpy(sql_lock->locks+a->lock_count,b->locks,
b->lock_count*sizeof(*b->locks));
@@ -782,6 +788,7 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
to= table_buf= sql_lock->table= (TABLE**) (locks + lock_count * 2);
sql_lock->table_count= table_count;
+ sql_lock->flags= flags;
for (i=0 ; i < count ; i++)
{
@@ -1086,8 +1093,8 @@ void Global_read_lock::unlock_global_read_lock(THD *thd)
int ret = wsrep->resync(wsrep);
if (ret != WSREP_OK)
{
- WSREP_WARN("resync failed %d for FTWRL: db: %s, query: %s", ret,
- (thd->db ? thd->db : "(null)"), thd->query());
+ WSREP_WARN("resync failed %d for FTWRL: db: %s, query: %s",
+ ret, thd->get_db(), thd->query());
DBUG_VOID_RETURN;
}
}
@@ -1173,7 +1180,7 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd)
if (rcode != WSREP_OK)
{
WSREP_WARN("FTWRL desync failed %d for schema: %s, query: %s",
- rcode, (thd->db ? thd->db : "(null)"), thd->query());
+ rcode, thd->get_db(), thd->query());
my_message(ER_LOCK_DEADLOCK, "wsrep desync failed for FTWRL", MYF(0));
DBUG_RETURN(TRUE);
}
diff --git a/sql/log.cc b/sql/log.cc
index be8b24da8df..8ed53a60195 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -49,10 +49,10 @@
#endif
#include "sql_plugin.h"
-#include "rpl_handler.h"
#include "debug_sync.h"
#include "sql_show.h"
#include "my_pthread.h"
+#include "semisync_master.h"
#include "wsrep_mysqld.h"
#include "sp_rcontext.h"
#include "sp_head.h"
@@ -87,8 +87,8 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all);
static int binlog_prepare(handlerton *hton, THD *thd, bool all);
static int binlog_start_consistent_snapshot(handlerton *hton, THD *thd);
-static LEX_STRING const write_error_msg=
- { C_STRING_WITH_LEN("error writing to the binary log") };
+static const LEX_CSTRING write_error_msg=
+ { STRING_WITH_LEN("error writing to the binary log") };
static my_bool opt_optimize_thread_scheduling= TRUE;
ulong binlog_checksum_options;
@@ -608,19 +608,19 @@ int check_if_log_table(const TABLE_LIST *table,
const char *error_msg)
{
int result= 0;
- if (table->db_length == 5 &&
- !my_strcasecmp(table_alias_charset, table->db, "mysql"))
+ if (table->db.length == 5 &&
+ !my_strcasecmp(table_alias_charset, table->db.str, "mysql"))
{
- const char *table_name= table->table_name;
+ const char *table_name= table->table_name.str;
- if (table->table_name_length == 11 &&
+ if (table->table_name.length == 11 &&
!my_strcasecmp(table_alias_charset, table_name, "general_log"))
{
result= QUERY_LOG_GENERAL;
goto end;
}
- if (table->table_name_length == 8 &&
+ if (table->table_name.length == 8 &&
!my_strcasecmp(table_alias_charset, table_name, "slow_log"))
{
result= QUERY_LOG_SLOW;
@@ -688,10 +688,9 @@ void Log_to_csv_event_handler::cleanup()
*/
bool Log_to_csv_event_handler::
- log_general(THD *thd, my_hrtime_t event_time, const char *user_host,
- uint user_host_len, my_thread_id thread_id_arg,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len,
+ log_general(THD *thd, my_hrtime_t event_time, const char *user_host, size_t user_host_len, my_thread_id thread_id_arg,
+ const char *command_type, size_t command_type_len,
+ const char *sql_text, size_t sql_text_len,
CHARSET_INFO *client_cs)
{
TABLE_LIST table_list;
@@ -716,9 +715,7 @@ bool Log_to_csv_event_handler::
save_thd_options= thd->variables.option_bits;
thd->variables.option_bits&= ~OPTION_BIN_LOG;
- table_list.init_one_table(MYSQL_SCHEMA_NAME.str, MYSQL_SCHEMA_NAME.length,
- GENERAL_LOG_NAME.str, GENERAL_LOG_NAME.length,
- GENERAL_LOG_NAME.str,
+ table_list.init_one_table(&MYSQL_SCHEMA_NAME, &GENERAL_LOG_NAME, 0,
TL_WRITE_CONCURRENT_INSERT);
/*
@@ -854,9 +851,9 @@ err:
bool Log_to_csv_event_handler::
log_slow(THD *thd, my_hrtime_t current_time,
- const char *user_host, uint user_host_len,
+ const char *user_host, size_t user_host_len,
ulonglong query_utime, ulonglong lock_utime, bool is_command,
- const char *sql_text, uint sql_text_len)
+ const char *sql_text, size_t sql_text_len)
{
TABLE_LIST table_list;
TABLE *table;
@@ -881,9 +878,7 @@ bool Log_to_csv_event_handler::
*/
save_time_zone_used= thd->time_zone_used;
- table_list.init_one_table(MYSQL_SCHEMA_NAME.str, MYSQL_SCHEMA_NAME.length,
- SLOW_LOG_NAME.str, SLOW_LOG_NAME.length,
- SLOW_LOG_NAME.str,
+ table_list.init_one_table(&MYSQL_SCHEMA_NAME, &SLOW_LOG_NAME, 0,
TL_WRITE_CONCURRENT_INSERT);
if (!(table= open_log_table(thd, &table_list, &open_tables_backup)))
@@ -937,9 +932,9 @@ bool Log_to_csv_event_handler::
goto err;
/* fill database field */
- if (thd->db)
+ if (thd->db.str)
{
- if (table->field[6]->store(thd->db, thd->db_length, client_cs))
+ if (table->field[6]->store(thd->db.str, thd->db.length, client_cs))
goto err;
table->field[6]->set_notnull();
}
@@ -1035,9 +1030,7 @@ int Log_to_csv_event_handler::
log_name= &SLOW_LOG_NAME;
}
- table_list.init_one_table(MYSQL_SCHEMA_NAME.str, MYSQL_SCHEMA_NAME.length,
- log_name->str, log_name->length, log_name->str,
- TL_WRITE_CONCURRENT_INSERT);
+ table_list.init_one_table(&MYSQL_SCHEMA_NAME, log_name, 0, TL_WRITE_CONCURRENT_INSERT);
table= open_log_table(thd, &table_list, &open_tables_backup);
if (table)
@@ -1077,9 +1070,9 @@ void Log_to_file_event_handler::init_pthread_objects()
bool Log_to_file_event_handler::
log_slow(THD *thd, my_hrtime_t current_time,
- const char *user_host, uint user_host_len,
+ const char *user_host, size_t user_host_len,
ulonglong query_utime, ulonglong lock_utime, bool is_command,
- const char *sql_text, uint sql_text_len)
+ const char *sql_text, size_t sql_text_len)
{
Silence_log_table_errors error_handler;
thd->push_internal_handler(&error_handler);
@@ -1098,10 +1091,9 @@ bool Log_to_file_event_handler::
*/
bool Log_to_file_event_handler::
- log_general(THD *thd, my_hrtime_t event_time, const char *user_host,
- uint user_host_len, my_thread_id thread_id_arg,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len,
+ log_general(THD *thd, my_hrtime_t event_time, const char *user_host, size_t user_host_len, my_thread_id thread_id_arg,
+ const char *command_type, size_t command_type_len,
+ const char *sql_text, size_t sql_text_len,
CHARSET_INFO *client_cs)
{
Silence_log_table_errors error_handler;
@@ -1304,7 +1296,7 @@ bool LOGGER::flush_general_log()
TRUE error occurred
*/
-bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
+bool LOGGER::slow_log_print(THD *thd, const char *query, size_t query_length,
ulonglong current_utime)
{
@@ -1353,7 +1345,7 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
{
is_command= TRUE;
query= command_name[thd->get_command()].str;
- query_length= command_name[thd->get_command()].length;
+ query_length= (uint)command_name[thd->get_command()].length;
}
for (current_handler= slow_log_handler_list; *current_handler ;)
@@ -1368,7 +1360,7 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
}
bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
- const char *query, uint query_length)
+ const char *query, size_t query_length)
{
bool error= FALSE;
Log_event_handler **current_handler= general_log_handler_list;
@@ -1385,8 +1377,8 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
mysql_audit_general_log(thd, hrtime_to_time(current_time),
user_host_buff, user_host_len,
command_name[(uint) command].str,
- command_name[(uint) command].length,
- query, query_length);
+ (uint)command_name[(uint) command].length,
+ query, (uint)query_length);
if (opt_log && log_command(thd, command))
{
@@ -1408,7 +1400,7 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
const char *format, va_list args)
{
- uint message_buff_len= 0;
+ size_t message_buff_len= 0;
char message_buff[MAX_LOG_BUFFER_SIZE];
/* prepare message */
@@ -2263,8 +2255,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
String log_query(buf, sizeof(buf), &my_charset_bin);
if (log_query.copy(STRING_WITH_LEN("SAVEPOINT "), &my_charset_bin) ||
- append_identifier(thd, &log_query,
- thd->lex->ident.str, thd->lex->ident.length))
+ append_identifier(thd, &log_query, &thd->lex->ident))
DBUG_RETURN(1);
int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
@@ -2306,8 +2297,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
char buf[1024];
String log_query(buf, sizeof(buf), &my_charset_bin);
if (log_query.copy(STRING_WITH_LEN("ROLLBACK TO "), &my_charset_bin) ||
- append_identifier(thd, &log_query,
- thd->lex->ident.str, thd->lex->ident.length))
+ append_identifier(thd, &log_query, &thd->lex->ident))
DBUG_RETURN(1);
int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
@@ -2391,7 +2381,7 @@ File open_binlog(IO_CACHE *log, const char *log_file_name, const char **errmsg)
*errmsg = "Could not open log file";
goto err;
}
- if (init_io_cache(log, file, binlog_file_cache_size, READ_CACHE, 0, 0,
+ if (init_io_cache(log, file, (size_t)binlog_file_cache_size, READ_CACHE, 0, 0,
MYF(MY_WME|MY_DONT_CHECK_FILESIZE)))
{
sql_print_error("Failed to create a cache on log (file '%s')",
@@ -2470,7 +2460,7 @@ static int find_uniq_filename(char *name, ulong next_log_number)
char buff[FN_REFLEN], ext_buf[FN_REFLEN];
struct st_my_dir *dir_info;
reg1 struct fileinfo *file_info;
- ulong max_found, next, number;
+ ulong max_found, next, UNINIT_VAR(number);
size_t buf_length, length;
char *start, *end;
int error= 0;
@@ -2672,7 +2662,7 @@ bool MYSQL_LOG::open(
if (log_type == LOG_NORMAL)
{
char *end;
- int len=my_snprintf(buff, sizeof(buff), "%s, Version: %s (%s). "
+ size_t len=my_snprintf(buff, sizeof(buff), "%s, Version: %s (%s). "
#ifdef EMBEDDED_LIBRARY
"embedded library\n",
my_progname, server_version, MYSQL_COMPILATION_COMMENT
@@ -2879,15 +2869,14 @@ void MYSQL_QUERY_LOG::reopen_file()
TRUE - error occurred
*/
-bool MYSQL_QUERY_LOG::write(time_t event_time, const char *user_host,
- uint user_host_len, my_thread_id thread_id_arg,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len)
+bool MYSQL_QUERY_LOG::write(time_t event_time, const char *user_host, size_t user_host_len, my_thread_id thread_id_arg,
+ const char *command_type, size_t command_type_len,
+ const char *sql_text, size_t sql_text_len)
{
char buff[32];
char local_time_buff[MAX_TIME_SIZE];
struct tm start;
- uint time_buff_len= 0;
+ size_t time_buff_len= 0;
mysql_mutex_lock(&LOCK_log);
@@ -2981,10 +2970,9 @@ err:
*/
bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
- const char *user_host,
- uint user_host_len, ulonglong query_utime,
+ const char *user_host, size_t user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
- const char *sql_text, uint sql_text_len)
+ const char *sql_text, size_t sql_text_len)
{
bool error= 0;
char llbuff[22];
@@ -2993,7 +2981,6 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
mysql_mutex_lock(&LOCK_log);
if (is_open())
{ // Safety agains reopen
- int tmp_errno= 0;
char buff[80], *end;
char query_time_buff[22+7], lock_time_buff[22+7];
size_t buff_len;
@@ -3015,16 +3002,13 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
/* Note that my_b_write() assumes it knows the length for this */
if (my_b_write(&log_file, (uchar*) buff, buff_len))
- tmp_errno= errno;
+ goto err;
}
const uchar uh[]= "# User@Host: ";
- if (my_b_write(&log_file, uh, sizeof(uh) - 1))
- tmp_errno= errno;
- if (my_b_write(&log_file, (uchar*) user_host, user_host_len))
- tmp_errno= errno;
- if (my_b_write(&log_file, (uchar*) "\n", 1))
- tmp_errno= errno;
- }
+ if (my_b_write(&log_file, uh, sizeof(uh) - 1) ||
+ my_b_write(&log_file, (uchar*) user_host, user_host_len) ||
+ my_b_write(&log_file, (uchar*) "\n", 1))
+ goto err;
/* For slow query log */
sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0);
@@ -3033,15 +3017,14 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
"# Thread_id: %lu Schema: %s QC_hit: %s\n"
"# Query_time: %s Lock_time: %s Rows_sent: %lu Rows_examined: %lu\n"
"# Rows_affected: %lu Bytes_sent: %lu\n",
- (ulong) thd->thread_id, (thd->db ? thd->db : ""),
+ (ulong) thd->thread_id, thd->get_db(),
((thd->query_plan_flags & QPLAN_QC) ? "Yes" : "No"),
query_time_buff, lock_time_buff,
(ulong) thd->get_sent_row_count(),
(ulong) thd->get_examined_row_count(),
(ulong) thd->get_affected_rows(),
- (ulong) (thd->status_var.bytes_sent - thd->bytes_sent_old))
- == (size_t) -1)
- tmp_errno= errno;
+ (ulong) (thd->status_var.bytes_sent - thd->bytes_sent_old)))
+ goto err;
if ((thd->variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_QUERY_PLAN)
&& thd->tmp_tables_used &&
@@ -3050,13 +3033,13 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
"Tmp_table_sizes: %s\n",
(ulong) thd->tmp_tables_used,
(ulong) thd->tmp_tables_disk_used,
- llstr(thd->tmp_tables_size, llbuff)) == (uint) -1)
- tmp_errno= errno;
+ llstr(thd->tmp_tables_size, llbuff)))
+ goto err;
- if (thd->spcont)
- if (my_b_printf(&log_file, "# Stored_routine: %s\n",
- ErrConvDQName(thd->spcont->m_sp).ptr()) == (uint) -1)
- tmp_errno= errno;
+ if (thd->spcont &&
+ my_b_printf(&log_file, "# Stored_routine: %s\n",
+ ErrConvDQName(thd->spcont->m_sp).ptr()))
+ goto err;
if ((thd->variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_QUERY_PLAN) &&
(thd->query_plan_flags &
@@ -3078,22 +3061,23 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
thd->query_plan_fsort_passes,
((thd->query_plan_flags & QPLAN_FILESORT_PRIORITY_QUEUE) ?
"Yes" : "No")
- ) == (size_t) -1)
- tmp_errno= errno;
+ ))
+ goto err;
if (thd->variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_EXPLAIN &&
thd->lex->explain)
{
StringBuffer<128> buf;
DBUG_ASSERT(!thd->free_list);
if (!print_explain_for_slow_log(thd->lex, thd, &buf))
- my_b_printf(&log_file, "%s", buf.c_ptr_safe());
+ if (my_b_printf(&log_file, "%s", buf.c_ptr_safe()))
+ goto err;
thd->free_items();
}
- if (thd->db && strcmp(thd->db, db))
+ if (thd->db.str && strcmp(thd->db.str, db))
{ // Database changed
- if (my_b_printf(&log_file,"use %s;\n",thd->db) == (size_t) -1)
- tmp_errno= errno;
- strmov(db,thd->db);
+ if (my_b_printf(&log_file,"use %s;\n",thd->db.str))
+ goto err;
+ strmov(db,thd->db.str);
}
if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
{
@@ -3128,7 +3112,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
*end='\n';
if (my_b_write(&log_file, (uchar*) "SET ", 4) ||
my_b_write(&log_file, (uchar*) buff + 1, (uint) (end-buff)))
- tmp_errno= errno;
+ goto err;
}
if (is_command)
{
@@ -3137,24 +3121,27 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
DBUG_EXECUTE_IF("simulate_slow_log_write_error",
{DBUG_SET("+d,simulate_file_write_error");});
if(my_b_write(&log_file, (uchar*) buff, buff_len))
- tmp_errno= errno;
+ goto err;
}
if (my_b_write(&log_file, (uchar*) sql_text, sql_text_len) ||
my_b_write(&log_file, (uchar*) ";\n",2) ||
flush_io_cache(&log_file))
- tmp_errno= errno;
- if (tmp_errno)
- {
- error= 1;
- if (! write_error)
- {
- write_error= 1;
- sql_print_error(ER_THD(thd, ER_ERROR_ON_WRITE), name, tmp_errno);
- }
+ goto err;
+
}
}
+end:
mysql_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
+
+err:
+ error= 1;
+ if (! write_error)
+ {
+ write_error= 1;
+ sql_print_error(ER_THD(thd, ER_ERROR_ON_WRITE), name, errno);
+ }
+ goto end;
}
@@ -3211,7 +3198,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period)
group_commit_trigger_lock_wait(0),
sync_period_ptr(sync_period), sync_counter(0),
state_file_deleted(false), binlog_state_recover_done(false),
- is_relay_log(0), signal_cnt(0),
+ is_relay_log(0), relay_signal_cnt(0),
checksum_alg_reset(BINLOG_CHECKSUM_ALG_UNDEF),
relay_log_checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF),
description_event_for_exec(0), description_event_for_queue(0),
@@ -3281,7 +3268,8 @@ void MYSQL_BIN_LOG::cleanup()
mysql_mutex_destroy(&LOCK_xid_list);
mysql_mutex_destroy(&LOCK_binlog_background_thread);
mysql_mutex_destroy(&LOCK_binlog_end_pos);
- mysql_cond_destroy(&update_cond);
+ mysql_cond_destroy(&COND_relay_log_updated);
+ mysql_cond_destroy(&COND_bin_log_updated);
mysql_cond_destroy(&COND_queue_busy);
mysql_cond_destroy(&COND_xid_list);
mysql_cond_destroy(&COND_binlog_background_thread);
@@ -3316,7 +3304,8 @@ void MYSQL_BIN_LOG::init_pthread_objects()
mysql_mutex_setflags(&LOCK_index, MYF_NO_DEADLOCK_DETECTION);
mysql_mutex_init(key_BINLOG_LOCK_xid_list,
&LOCK_xid_list, MY_MUTEX_INIT_FAST);
- mysql_cond_init(m_key_update_cond, &update_cond, 0);
+ mysql_cond_init(m_key_relay_log_update, &COND_relay_log_updated, 0);
+ mysql_cond_init(m_key_bin_log_update, &COND_bin_log_updated, 0);
mysql_cond_init(m_key_COND_queue_busy, &COND_queue_busy, 0);
mysql_cond_init(key_BINLOG_COND_xid_list, &COND_xid_list, 0);
@@ -3635,8 +3624,8 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
Write the current binlog checkpoint into the log, so XA recovery will
know from where to start recovery.
*/
- uint off= dirname_length(log_file_name);
- uint len= strlen(log_file_name) - off;
+ size_t off= dirname_length(log_file_name);
+ size_t len= strlen(log_file_name) - off;
char *entry_mem, *name_mem;
if (!(new_xid_list_entry = (xid_count_per_binlog *)
my_multi_malloc(MYF(MY_WME),
@@ -3646,8 +3635,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
goto err;
memcpy(name_mem, log_file_name+off, len);
new_xid_list_entry->binlog_name= name_mem;
- new_xid_list_entry->binlog_name_len= len;
+ new_xid_list_entry->binlog_name_len= (int)len;
new_xid_list_entry->xid_count= 0;
+ new_xid_list_entry->notify_count= 0;
/*
Find the name for the Initial binlog checkpoint.
@@ -3665,7 +3655,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
if (!b)
b= new_xid_list_entry;
strmake(buf, b->binlog_name, b->binlog_name_len);
- Binlog_checkpoint_log_event ev(buf, len);
+ Binlog_checkpoint_log_event ev(buf, (uint)len);
DBUG_EXECUTE_IF("crash_before_write_checkpoint_event",
flush_io_cache(&log_file);
mysql_file_sync(log_file.file, MYF(MY_WME));
@@ -3802,6 +3792,11 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
close_purge_index_file();
#endif
+ /* Notify the io thread that binlog is rotated to a new file */
+ if (is_relay_log)
+ signal_relay_log_update();
+ else
+ update_binlog_end_pos();
DBUG_RETURN(0);
err:
@@ -3952,7 +3947,7 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
for (;;)
{
- uint length;
+ size_t length;
my_off_t offset= my_b_tell(&index_file);
DBUG_EXECUTE_IF("simulate_find_log_pos_error",
@@ -4022,7 +4017,7 @@ end:
int MYSQL_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock)
{
int error= 0;
- uint length;
+ size_t length;
char fname[FN_REFLEN];
char *full_fname= linfo->log_file_name;
@@ -4171,14 +4166,6 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
mysql_mutex_unlock(&LOCK_xid_list);
}
- /*
- The following mutex is needed to ensure that no threads call
- 'delete thd' as we would then risk missing a 'rollback' from this
- thread. If the transaction involved MyISAM tables, it should go
- into binlog even on rollback.
- */
- mysql_mutex_lock(&LOCK_thread_count);
-
/* Save variables so that we can reopen the log */
save_name=name;
name=0; // Protect against free
@@ -4285,7 +4272,6 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
err:
if (error == 1)
name= const_cast<char*>(save_name);
- mysql_mutex_unlock(&LOCK_thread_count);
if (!is_relay_log)
{
@@ -4721,7 +4707,7 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *reclaimed_space,
for (;;)
{
- uint length;
+ size_t length;
if ((length=my_b_gets(&purge_index_file, log_info.log_file_name,
FN_REFLEN)) <= 1)
@@ -5008,7 +4994,55 @@ MYSQL_BIN_LOG::is_xidlist_idle_nolock()
return true;
}
+#ifdef WITH_WSREP
+inline bool
+is_gtid_cached_internal(IO_CACHE *file)
+{
+ uchar data[EVENT_TYPE_OFFSET+1];
+ bool result= false;
+ my_off_t write_pos= my_b_tell(file);
+ if (reinit_io_cache(file, READ_CACHE, 0, 0, 0))
+ return false;
+ /*
+ In the cache we have gtid event if , below condition is true,
+ */
+ my_b_read(file, data, sizeof(data));
+ uint event_type= (uchar)data[EVENT_TYPE_OFFSET];
+ if (event_type == GTID_LOG_EVENT)
+ result= true;
+ /*
+ Cleanup , Why because we have not read the full buffer
+ and this will cause next to next reinit_io_cache(called in write_cache)
+ to make cache empty.
+ */
+ file->read_pos= file->read_end;
+ if (reinit_io_cache(file, WRITE_CACHE, write_pos, 0, 0))
+ return false;
+ return result;
+}
+#endif
+#ifdef WITH_WSREP
+inline bool
+MYSQL_BIN_LOG::is_gtid_cached(THD *thd)
+{
+ binlog_cache_mngr *mngr= (binlog_cache_mngr *) thd_get_ha_data(
+ thd, binlog_hton);
+ if (!mngr)
+ return false;
+ binlog_cache_data *cache_trans= mngr->get_binlog_cache_data(
+ use_trans_cache(thd, true));
+ binlog_cache_data *cache_stmt= mngr->get_binlog_cache_data(
+ use_trans_cache(thd, false));
+ if (cache_trans && !cache_trans->empty() &&
+ is_gtid_cached_internal(&cache_trans->cache_log))
+ return true;
+ if (cache_stmt && !cache_stmt->empty() &&
+ is_gtid_cached_internal(&cache_stmt->cache_log))
+ return true;
+ return false;
+}
+#endif
/**
Create a new log file name.
@@ -5020,7 +5054,7 @@ MYSQL_BIN_LOG::is_xidlist_idle_nolock()
void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident)
{
- uint dir_len = dirname_length(log_file_name);
+ size_t dir_len = dirname_length(log_file_name);
if (dir_len >= FN_REFLEN)
dir_len=FN_REFLEN-1;
strnmov(buf, log_file_name, dir_len);
@@ -5121,7 +5155,12 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
new file name in the current binary log file.
*/
if ((error= generate_new_name(new_name, name, 0)))
+ {
+#ifdef ENABLE_AND_FIX_HANG
+ close_on_error= TRUE;
+#endif
goto end;
+ }
new_name_ptr=new_name;
if (log_type == LOG_BIN)
@@ -5152,13 +5191,20 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
}
bytes_written += r.data_written;
}
- /*
- Update needs to be signalled even if there is no rotate event
- log rotation should give the waiting thread a signal to
- discover EOF and move on to the next log.
- */
- signal_update();
}
+
+ /*
+ Update needs to be signalled even if there is no rotate event
+ log rotation should give the waiting thread a signal to
+ discover EOF and move on to the next log.
+ */
+ if ((error= flush_io_cache(&log_file)))
+ {
+ close_on_error= TRUE;
+ goto end;
+ }
+ update_binlog_end_pos();
+
old_name=name;
name=0; // Don't free name
close_flag= LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX;
@@ -5289,7 +5335,7 @@ bool MYSQL_BIN_LOG::append_no_lock(Log_event* ev)
if (my_b_append_tell(&log_file) > max_size)
error= new_file_without_locking();
err:
- signal_update(); // Safe as we don't call close
+ update_binlog_end_pos();
DBUG_RETURN(error);
}
@@ -5350,7 +5396,7 @@ bool MYSQL_BIN_LOG::write_event_buffer(uchar* buf, uint len)
err:
my_safe_afree(ebuf, len);
if (!error)
- signal_update();
+ update_binlog_end_pos();
DBUG_RETURN(error);
}
@@ -5601,7 +5647,36 @@ THD::binlog_start_trans_and_stmt()
cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF)
{
this->binlog_set_stmt_begin();
- if (in_multi_stmt_transaction_mode())
+ bool mstmt_mode= in_multi_stmt_transaction_mode();
+#ifdef WITH_WSREP
+ /* Write Gtid
+ Get domain id only when gtid mode is set
+ If this event is replicate through a master then ,
+ we will forward the same gtid another nodes
+ We have to do this only one time in mysql transaction.
+ Since this function is called multiple times , We will check for
+ ha_info->is_started()
+ */
+ Ha_trx_info *ha_info;
+ ha_info= this->ha_data[binlog_hton->slot].ha_info + (mstmt_mode ? 1 : 0);
+
+ if (!ha_info->is_started() && wsrep_gtid_mode
+ && this->variables.gtid_seq_no)
+ {
+ binlog_cache_mngr *const cache_mngr=
+ (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
+ binlog_cache_data *cache_data= cache_mngr->get_binlog_cache_data(1);
+ IO_CACHE *file= &cache_data->cache_log;
+ Log_event_writer writer(file, cache_data);
+ Gtid_log_event gtid_event(this, this->variables.gtid_seq_no,
+ this->variables.gtid_domain_id,
+ true, LOG_EVENT_SUPPRESS_USE_F,
+ true, 0);
+ gtid_event.server_id= this->variables.server_id;
+ writer.write(&gtid_event);
+ }
+#endif
+ if (mstmt_mode)
trans_register_ha(this, TRUE, binlog_hton);
trans_register_ha(this, FALSE, binlog_hton);
/*
@@ -5881,7 +5956,7 @@ MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone,
DBUG_PRINT("enter", ("standalone: %d", standalone));
#ifdef WITH_WSREP
- if (WSREP(thd) && thd->wsrep_trx_meta.gtid.seqno != -1 && wsrep_gtid_mode)
+ if (WSREP(thd) && thd->wsrep_trx_meta.gtid.seqno != -1 && wsrep_gtid_mode && !thd->variables.gtid_seq_no)
{
domain_id= wsrep_gtid_domain_id;
} else {
@@ -5935,6 +6010,12 @@ MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone,
/* Write the event to the binary log. */
DBUG_ASSERT(this == &mysql_bin_log);
+
+#ifdef WITH_WSREP
+ if (wsrep_gtid_mode && is_gtid_cached(thd))
+ DBUG_RETURN(false);
+#endif
+
if (write_event(&gtid_event))
DBUG_RETURN(true);
status_var_add(thd->status_var.binlog_bytes_written, gtid_event.data_written);
@@ -6233,7 +6314,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
prev_binlog_id= current_binlog_id;
DBUG_EXECUTE_IF("binlog_force_commit_id",
{
- const LEX_STRING commit_name= { C_STRING_WITH_LEN("commit_id") };
+ const LEX_CSTRING commit_name= { STRING_WITH_LEN("commit_id") };
bool null_value;
user_var_entry *entry=
(user_var_entry*) my_hash_search(&thd->user_vars,
@@ -6350,6 +6431,7 @@ err:
{
my_off_t offset= my_b_tell(file);
bool check_purge= false;
+ DBUG_ASSERT(!is_relay_log);
if (!error)
{
@@ -6364,25 +6446,23 @@ err:
mysql_mutex_assert_owner(&LOCK_log);
mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
- bool first= true;
- bool last= true;
- if ((error= RUN_HOOK(binlog_storage, after_flush,
- (thd, log_file_name, file->pos_in_file,
- synced, first, last))))
+#ifdef HAVE_REPLICATION
+ if (repl_semisync_master.report_binlog_update(thd, log_file_name,
+ file->pos_in_file))
{
sql_print_error("Failed to run 'after_flush' hooks");
error= 1;
}
else
+#endif
{
- /* update binlog_end_pos so it can be read by dump thread
- *
- * note: must be _after_ the RUN_HOOK(after_flush) or else
- * semi-sync-plugin might not have put the transaction into
- * it's list before dump-thread tries to send it
- */
+ /*
+ update binlog_end_pos so it can be read by dump thread
+ note: must be _after_ the RUN_HOOK(after_flush) or else
+ semi-sync might not have put the transaction into
+ it's list before dump-thread tries to send it
+ */
update_binlog_end_pos(offset);
-
if ((error= rotate(false, &check_purge)))
check_purge= false;
}
@@ -6399,15 +6479,14 @@ err:
mysql_mutex_assert_not_owner(&LOCK_log);
mysql_mutex_assert_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
- bool first= true;
- bool last= true;
- if (RUN_HOOK(binlog_storage, after_sync,
- (thd, log_file_name, file->pos_in_file,
- first, last)))
+#ifdef HAVE_REPLICATION
+ if (repl_semisync_master.wait_after_sync(log_file_name,
+ file->pos_in_file))
{
error=1;
/* error is already printed inside hook */
}
+#endif
/*
Take mutex to protect against a reader seeing partial writes of 64-bit
@@ -6493,7 +6572,7 @@ bool general_log_print(THD *thd, enum enum_server_command command,
}
bool general_log_write(THD *thd, enum enum_server_command command,
- const char *query, uint query_length)
+ const char *query, size_t query_length)
{
/* Write the message to the log if we want to log this king of commands */
if (logger.log_command(thd, command) || mysql_audit_general_enabled())
@@ -6674,6 +6753,120 @@ void MYSQL_BIN_LOG::checkpoint_and_purge(ulong binlog_id)
purge();
}
+
+/**
+ Searches for the first (oldest) binlog file name in in the binlog index.
+
+ @param[in,out] buf_arg pointer to a buffer to hold found
+ the first binary log file name
+ @return NULL on success, otherwise error message
+*/
+static const char* get_first_binlog(char* buf_arg)
+{
+ IO_CACHE *index_file;
+ size_t length;
+ char fname[FN_REFLEN];
+ const char* errmsg= NULL;
+
+ DBUG_ENTER("get_first_binlog");
+
+ DBUG_ASSERT(mysql_bin_log.is_open());
+
+ mysql_bin_log.lock_index();
+
+ index_file=mysql_bin_log.get_index_file();
+ if (reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 0))
+ {
+ errmsg= "failed to create a cache on binlog index";
+ goto end;
+ }
+ /* The file ends with EOF or empty line */
+ if ((length=my_b_gets(index_file, fname, sizeof(fname))) <= 1)
+ {
+ errmsg= "empty binlog index";
+ goto end;
+ }
+ else
+ {
+ fname[length-1]= 0; // Remove end \n
+ }
+ if (normalize_binlog_name(buf_arg, fname, false))
+ {
+ errmsg= "cound not normalize the first file name in the binlog index";
+ goto end;
+ }
+end:
+ mysql_bin_log.unlock_index();
+
+ DBUG_RETURN(errmsg);
+}
+
+/**
+ Check weather the gtid binlog state can safely remove gtid
+ domains passed as the argument. A safety condition is satisfied when
+ there are no events from the being deleted domains in the currently existing
+ binlog files. Upon successful check the supplied domains are removed
+ from @@gtid_binlog_state. The caller is supposed to rotate binlog so that
+ the active latest file won't have the deleted domains in its Gtid_list header.
+
+ @param domain_drop_lex gtid domain id sequence from lex.
+ Passed as a pointer to dynamic array must be not empty
+ unless pointer value NULL.
+ @retval zero on success
+ @retval > 0 ineffective call none from the *non* empty
+ gtid domain sequence is deleted
+ @retval < 0 on error
+*/
+static int do_delete_gtid_domain(DYNAMIC_ARRAY *domain_drop_lex)
+{
+ int rc= 0;
+ Gtid_list_log_event *glev= NULL;
+ char buf[FN_REFLEN];
+ File file;
+ IO_CACHE cache;
+ const char* errmsg= NULL;
+ char errbuf[MYSQL_ERRMSG_SIZE]= {0};
+
+ if (!domain_drop_lex)
+ return 0; // still "effective" having empty domain sequence to delete
+
+ DBUG_ASSERT(domain_drop_lex->elements > 0);
+ mysql_mutex_assert_owner(mysql_bin_log.get_log_lock());
+
+ if ((errmsg= get_first_binlog(buf)) != NULL)
+ goto end;
+ bzero((char*) &cache, sizeof(cache));
+ if ((file= open_binlog(&cache, buf, &errmsg)) == (File) -1)
+ goto end;
+ errmsg= get_gtid_list_event(&cache, &glev);
+ end_io_cache(&cache);
+ mysql_file_close(file, MYF(MY_WME));
+
+ DBUG_EXECUTE_IF("inject_binlog_delete_domain_init_error",
+ errmsg= "injected error";);
+ if (errmsg)
+ goto end;
+ errmsg= rpl_global_gtid_binlog_state.drop_domain(domain_drop_lex,
+ glev, errbuf);
+
+end:
+ if (errmsg)
+ {
+ if (strlen(errmsg) > 0)
+ {
+ my_error(ER_BINLOG_CANT_DELETE_GTID_DOMAIN, MYF(0), errmsg);
+ rc= -1;
+ }
+ else
+ {
+ rc= 1;
+ }
+ }
+ delete glev;
+
+ return rc;
+}
+
/**
The method is a shortcut of @c rotate() and @c purge().
LOCK_log is acquired prior to rotate and is released after it.
@@ -6683,16 +6876,24 @@ void MYSQL_BIN_LOG::checkpoint_and_purge(ulong binlog_id)
@retval
nonzero - error in rotating routine.
*/
-int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate)
+int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate,
+ DYNAMIC_ARRAY *domain_drop_lex)
{
- int error= 0;
+ int err_gtid=0, error= 0;
ulong prev_binlog_id;
DBUG_ENTER("MYSQL_BIN_LOG::rotate_and_purge");
bool check_purge= false;
mysql_mutex_lock(&LOCK_log);
prev_binlog_id= current_binlog_id;
- if ((error= rotate(force_rotate, &check_purge)))
+
+ if ((err_gtid= do_delete_gtid_domain(domain_drop_lex)))
+ {
+ // inffective attempt to delete merely skips rotate and purge
+ if (err_gtid < 0)
+ error= 1; // otherwise error is propagated the user
+ }
+ else if ((error= rotate(force_rotate, &check_purge)))
check_purge= false;
/*
NOTE: Run purge_logs wo/ holding LOCK_log because it does not need
@@ -6718,7 +6919,7 @@ uint MYSQL_BIN_LOG::next_file_id()
class CacheWriter: public Log_event_writer
{
public:
- ulong remains;
+ size_t remains;
CacheWriter(THD *thd_arg, IO_CACHE *file_arg, bool do_checksum,
Binlog_crypt_data *cr)
@@ -6771,9 +6972,9 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
mysql_mutex_assert_owner(&LOCK_log);
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
DBUG_RETURN(ER_ERROR_ON_WRITE);
- uint length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
- long val;
- ulong end_log_pos_inc= 0; // each event processed adds BINLOG_CHECKSUM_LEN 2 t
+ size_t length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
+ size_t val;
+ size_t end_log_pos_inc= 0; // each event processed adds BINLOG_CHECKSUM_LEN 2 t
uchar header[LOG_EVENT_HEADER_LEN];
CacheWriter writer(thd, &log_file, binlog_checksum_options, &crypto);
@@ -6798,7 +6999,7 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
split.
*/
- group= (uint)my_b_tell(&log_file);
+ group= (size_t)my_b_tell(&log_file);
hdr_offs= carry= 0;
do
@@ -6810,12 +7011,12 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
if (unlikely(carry > 0))
{
DBUG_ASSERT(carry < LOG_EVENT_HEADER_LEN);
- uint tail= LOG_EVENT_HEADER_LEN - carry;
+ size_t tail= LOG_EVENT_HEADER_LEN - carry;
/* assemble both halves */
memcpy(&header[carry], (char *)cache->read_pos, tail);
- ulong len= uint4korr(header + EVENT_LEN_OFFSET);
+ uint32 len= uint4korr(header + EVENT_LEN_OFFSET);
writer.remains= len;
/* fix end_log_pos */
@@ -6895,7 +7096,7 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
int4store(ev + EVENT_LEN_OFFSET, ev_len + writer.checksum_len);
writer.remains= ev_len;
- if (writer.write(ev, std::min<uint>(ev_len, length - hdr_offs)))
+ if (writer.write(ev, MY_MIN(ev_len, length - hdr_offs)))
DBUG_RETURN(ER_ERROR_ON_WRITE);
/* next event header at ... */
@@ -6959,7 +7160,7 @@ bool MYSQL_BIN_LOG::write_incident_already_locked(THD *thd)
uint error= 0;
DBUG_ENTER("MYSQL_BIN_LOG::write_incident_already_locked");
Incident incident= INCIDENT_LOST_EVENTS;
- Incident_log_event ev(thd, incident, write_error_msg);
+ Incident_log_event ev(thd, incident, &write_error_msg);
if (likely(is_open()))
{
@@ -6986,7 +7187,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd)
if (!(error= write_incident_already_locked(thd)) &&
!(error= flush_and_sync(0)))
{
- signal_update();
+ update_binlog_end_pos();
if ((error= rotate(false, &check_purge)))
check_purge= false;
}
@@ -7027,7 +7228,7 @@ MYSQL_BIN_LOG::write_binlog_checkpoint_event_already_locked(const char *name_arg
*/
if (!write_event(&ev) && !flush_and_sync(0))
{
- signal_update();
+ update_binlog_end_pos();
}
else
{
@@ -7096,8 +7297,15 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd,
mode. Also, do not write the cached updates to binlog if binary logging is
disabled (log-bin/sql_log_bin).
*/
- if (wsrep_emulate_bin_log || !(thd->variables.option_bits & OPTION_BIN_LOG))
+ if (wsrep_emulate_bin_log)
+ {
+ DBUG_RETURN(0);
+ }
+ else if (!(thd->variables.option_bits & OPTION_BIN_LOG))
+ {
+ cache_mngr->need_unlog= false;
DBUG_RETURN(0);
+ }
entry.thd= thd;
entry.cache_mngr= cache_mngr;
@@ -7120,7 +7328,7 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd,
if (cache_mngr->stmt_cache.has_incident() ||
cache_mngr->trx_cache.has_incident())
{
- Incident_log_event inc_ev(thd, INCIDENT_LOST_EVENTS, write_error_msg);
+ Incident_log_event inc_ev(thd, INCIDENT_LOST_EVENTS, &write_error_msg);
entry.incident_event= &inc_ev;
DBUG_RETURN(write_transaction_to_binlog_events(&entry));
}
@@ -7455,7 +7663,11 @@ MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry)
else if (is_leader)
trx_group_commit_leader(entry);
else if (!entry->queued_by_other)
+ {
+ DEBUG_SYNC(entry->thd, "after_semisync_queue");
+
entry->thd->wait_for_wakeup_ready();
+ }
else
{
/*
@@ -7624,7 +7836,7 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
commit_id= (last_in_queue == leader ? 0 : (uint64)leader->thd->query_id);
DBUG_EXECUTE_IF("binlog_force_commit_id",
{
- const LEX_STRING commit_name= { C_STRING_WITH_LEN("commit_id") };
+ const LEX_CSTRING commit_name= { STRING_WITH_LEN("commit_id") };
bool null_value;
user_var_entry *entry=
(user_var_entry*) my_hash_search(&leader->thd->user_vars,
@@ -7700,31 +7912,31 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
mysql_mutex_assert_owner(&LOCK_log);
mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
- bool first= true, last;
+
for (current= queue; current != NULL; current= current->next)
{
- last= current->next == NULL;
+#ifdef HAVE_REPLICATION
if (!current->error &&
- RUN_HOOK(binlog_storage, after_flush,
- (current->thd,
- current->cache_mngr->last_commit_pos_file,
- current->cache_mngr->last_commit_pos_offset, synced,
- first, last)))
+ repl_semisync_master.
+ report_binlog_update(current->thd,
+ current->cache_mngr->last_commit_pos_file,
+ current->cache_mngr->
+ last_commit_pos_offset))
{
current->error= ER_ERROR_ON_WRITE;
current->commit_errno= -1;
current->error_cache= NULL;
any_error= true;
}
- first= false;
+#endif
}
- /* update binlog_end_pos so it can be read by dump thread
- *
- * note: must be _after_ the RUN_HOOK(after_flush) or else
- * semi-sync-plugin might not have put the transaction into
- * it's list before dump-thread tries to send it
- */
+ /*
+ update binlog_end_pos so it can be read by dump thread
+ Note: must be _after_ the RUN_HOOK(after_flush) or else
+ semi-sync might not have put the transaction into
+ it's list before dump-thread tries to send it
+ */
update_binlog_end_pos(commit_offset);
if (any_error)
@@ -7786,18 +7998,19 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
mysql_mutex_assert_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
- bool first= true, last;
+ bool first __attribute__((unused))= true;
+ bool last __attribute__((unused));
for (current= queue; current != NULL; current= current->next)
{
last= current->next == NULL;
- if (!current->error &&
- RUN_HOOK(binlog_storage, after_sync,
- (current->thd, current->cache_mngr->last_commit_pos_file,
- current->cache_mngr->last_commit_pos_offset,
- first, last)))
- {
- /* error is already printed inside hook */
- }
+#ifdef HAVE_REPLICATION
+ if (!current->error)
+ current->error=
+ repl_semisync_master.wait_after_sync(current->cache_mngr->
+ last_commit_pos_file,
+ current->cache_mngr->
+ last_commit_pos_offset);
+#endif
first= false;
}
}
@@ -8108,10 +8321,10 @@ void MYSQL_BIN_LOG::wait_for_update_relay_log(THD* thd)
DBUG_ENTER("wait_for_update_relay_log");
mysql_mutex_assert_owner(&LOCK_log);
- thd->ENTER_COND(&update_cond, &LOCK_log,
+ thd->ENTER_COND(&COND_relay_log_updated, &LOCK_log,
&stage_slave_has_read_all_relay_log,
&old_stage);
- mysql_cond_wait(&update_cond, &LOCK_log);
+ mysql_cond_wait(&COND_relay_log_updated, &LOCK_log);
thd->EXIT_COND(&old_stage);
DBUG_VOID_RETURN;
}
@@ -8141,9 +8354,9 @@ int MYSQL_BIN_LOG::wait_for_update_binlog_end_pos(THD* thd,
thd_wait_begin(thd, THD_WAIT_BINLOG);
mysql_mutex_assert_owner(get_binlog_end_pos_lock());
if (!timeout)
- mysql_cond_wait(&update_cond, get_binlog_end_pos_lock());
+ mysql_cond_wait(&COND_bin_log_updated, get_binlog_end_pos_lock());
else
- ret= mysql_cond_timedwait(&update_cond, get_binlog_end_pos_lock(),
+ ret= mysql_cond_timedwait(&COND_bin_log_updated, get_binlog_end_pos_lock(),
timeout);
thd_wait_end(thd);
DBUG_RETURN(ret);
@@ -8188,7 +8401,8 @@ void MYSQL_BIN_LOG::close(uint exiting)
relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
write_event(&s);
bytes_written+= s.data_written;
- signal_update();
+ flush_io_cache(&log_file);
+ update_binlog_end_pos();
/*
When we shut down server, write out the binlog state to a separate
@@ -8407,14 +8621,6 @@ bool flush_error_log()
return result;
}
-void MYSQL_BIN_LOG::signal_update()
-{
- DBUG_ENTER("MYSQL_BIN_LOG::signal_update");
- signal_cnt++;
- mysql_cond_broadcast(&update_cond);
- DBUG_VOID_RETURN;
-}
-
#ifdef _WIN32
static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
size_t length, size_t buffLen)
@@ -8459,7 +8665,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer,
struct tm tm_tmp;
struct tm *start;
THD *thd= 0;
- int tag_length= 0;
+ size_t tag_length= 0;
char tag[NAME_LEN];
DBUG_ENTER("print_buffer_to_file");
DBUG_PRINT("enter",("buffer: %s", buffer));
@@ -8495,7 +8701,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer,
(unsigned long) (thd ? thd->thread_id : 0),
(level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ?
"Warning" : "Note"),
- tag_length, tag,
+ (int) tag_length, tag,
(int) length, buffer);
fflush(stderr);
@@ -9398,11 +9604,19 @@ TC_LOG_BINLOG::log_and_order(THD *thd, my_xid xid, bool all,
if (err)
DBUG_RETURN(0);
+
+ bool need_unlog= cache_mngr->need_unlog;
+ /*
+ The transaction won't need the flag anymore.
+ Todo/fixme: consider to move the statement into cache_mngr->reset()
+ relocated to the current or later point.
+ */
+ cache_mngr->need_unlog= false;
/*
If using explicit user XA, we will not have XID. We must still return a
non-zero cookie (as zero cookie signals error).
*/
- if (!xid || !cache_mngr->need_unlog)
+ if (!xid || !need_unlog)
DBUG_RETURN(BINLOG_COOKIE_DUMMY(cache_mngr->delayed_error));
else
DBUG_RETURN(BINLOG_COOKIE_MAKE(cache_mngr->binlog_id,
@@ -9475,6 +9689,9 @@ TC_LOG_BINLOG::mark_xid_done(ulong binlog_id, bool write_checkpoint)
if (b->binlog_id == binlog_id)
{
--b->xid_count;
+
+ DBUG_ASSERT(b->xid_count >= 0); // catch unmatched (++) decrement
+
break;
}
first= false;
@@ -9574,9 +9791,20 @@ void
TC_LOG_BINLOG::commit_checkpoint_notify(void *cookie)
{
xid_count_per_binlog *entry= static_cast<xid_count_per_binlog *>(cookie);
+ bool found_entry= false;
mysql_mutex_lock(&LOCK_binlog_background_thread);
- entry->next_in_queue= binlog_background_thread_queue;
- binlog_background_thread_queue= entry;
+ /* count the same notification kind from different engines */
+ for (xid_count_per_binlog *link= binlog_background_thread_queue;
+ link && !found_entry; link= link->next_in_queue)
+ {
+ if ((found_entry= (entry == link)))
+ entry->notify_count++;
+ }
+ if (!found_entry)
+ {
+ entry->next_in_queue= binlog_background_thread_queue;
+ binlog_background_thread_queue= entry;
+ }
mysql_cond_signal(&COND_binlog_background_thread);
mysql_mutex_unlock(&LOCK_binlog_background_thread);
}
@@ -9671,13 +9899,16 @@ binlog_background_thread(void *arg __attribute__((unused)))
);
while (queue)
{
+ long count= queue->notify_count;
THD_STAGE_INFO(thd, stage_binlog_processing_checkpoint_notify);
DEBUG_SYNC(thd, "binlog_background_thread_before_mark_xid_done");
/* Set the thread start time */
thd->set_time();
/* Grab next pointer first, as mark_xid_done() may free the element. */
next= queue->next_in_queue;
- mysql_bin_log.mark_xid_done(queue->binlog_id, true);
+ queue->notify_count= 0;
+ for (long i= 0; i <= count; i++)
+ mysql_bin_log.mark_xid_done(queue->binlog_id, true);
queue= next;
DBUG_EXECUTE_IF("binlog_background_checkpoint_processed",
@@ -9770,7 +10001,8 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name,
goto err1;
if (do_xa)
- init_alloc_root(&mem_root, TC_LOG_PAGE_SIZE, TC_LOG_PAGE_SIZE, MYF(0));
+ init_alloc_root(&mem_root, "TC_LOG_BINLOG", TC_LOG_PAGE_SIZE,
+ TC_LOG_PAGE_SIZE, MYF(0));
fdle->flags&= ~LOG_EVENT_BINLOG_IN_USE_F; // abort on the first error
@@ -9787,7 +10019,7 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name,
for (;;)
{
while ((ev= Log_event::read_log_event(first_round ? first_log : &log,
- 0, fdle, opt_master_verify_checksum))
+ fdle, opt_master_verify_checksum))
&& ev->is_valid())
{
enum Log_event_type typ= ev->get_type_code();
@@ -9808,7 +10040,7 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name,
case BINLOG_CHECKPOINT_EVENT:
if (first_round && do_xa)
{
- uint dir_len;
+ size_t dir_len;
Binlog_checkpoint_log_event *cev= (Binlog_checkpoint_log_event *)ev;
if (cev->binlog_file_len >= FN_REFLEN)
sql_print_warning("Incorrect binlog checkpoint event with too "
@@ -10028,7 +10260,7 @@ MYSQL_BIN_LOG::do_binlog_recovery(const char *opt_name, bool do_xa_recovery)
return 1;
}
- if ((ev= Log_event::read_log_event(&log, 0, &fdle,
+ if ((ev= Log_event::read_log_event(&log, &fdle,
opt_master_verify_checksum)) &&
ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
{
@@ -10205,7 +10437,7 @@ static struct st_mysql_sys_var *binlog_sys_vars[]=
static void
set_binlog_snapshot_file(const char *src)
{
- int dir_len = dirname_length(src);
+ size_t dir_len = dirname_length(src);
strmake_buf(binlog_snapshot_file, src + dir_len);
}
@@ -10248,6 +10480,74 @@ TC_LOG_BINLOG::set_status_variables(THD *thd)
}
}
+
+/*
+ Find the Gtid_list_log_event at the start of a binlog.
+
+ NULL for ok, non-NULL error message for error.
+
+ If ok, then the event is returned in *out_gtid_list. This can be NULL if we
+ get back to binlogs written by old server version without GTID support. If
+ so, it means we have reached the point to start from, as no GTID events can
+ exist in earlier binlogs.
+*/
+const char *
+get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list)
+{
+ Format_description_log_event init_fdle(BINLOG_VERSION);
+ Format_description_log_event *fdle;
+ Log_event *ev;
+ const char *errormsg = NULL;
+
+ *out_gtid_list= NULL;
+
+ if (!(ev= Log_event::read_log_event(cache, &init_fdle,
+ opt_master_verify_checksum)) ||
+ ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
+ {
+ if (ev)
+ delete ev;
+ return "Could not read format description log event while looking for "
+ "GTID position in binlog";
+ }
+
+ fdle= static_cast<Format_description_log_event *>(ev);
+
+ for (;;)
+ {
+ Log_event_type typ;
+
+ ev= Log_event::read_log_event(cache, fdle, opt_master_verify_checksum);
+ if (!ev)
+ {
+ errormsg= "Could not read GTID list event while looking for GTID "
+ "position in binlog";
+ break;
+ }
+ typ= ev->get_type_code();
+ if (typ == GTID_LIST_EVENT)
+ break; /* Done, found it */
+ if (typ == START_ENCRYPTION_EVENT)
+ {
+ if (fdle->start_decryption((Start_encryption_log_event*) ev))
+ errormsg= "Could not set up decryption for binlog.";
+ }
+ delete ev;
+ if (typ == ROTATE_EVENT || typ == STOP_EVENT ||
+ typ == FORMAT_DESCRIPTION_EVENT || typ == START_ENCRYPTION_EVENT)
+ continue; /* Continue looking */
+
+ /* We did not find any Gtid_list_log_event, must be old binlog. */
+ ev= NULL;
+ break;
+ }
+
+ delete fdle;
+ *out_gtid_list= static_cast<Gtid_list_log_event *>(ev);
+ return errormsg;
+}
+
+
struct st_mysql_storage_engine binlog_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
diff --git a/sql/log.h b/sql/log.h
index 30829bdb33c..098824d9ec8 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -349,19 +349,23 @@ public:
/* for documentation of mutexes held in various places in code */
};
+/* Tell the io thread if we can delay the master info sync. */
+#define SEMI_SYNC_SLAVE_DELAY_SYNC 1
+/* Tell the io thread if the current event needs a ack. */
+#define SEMI_SYNC_NEED_ACK 2
+
class MYSQL_QUERY_LOG: public MYSQL_LOG
{
public:
MYSQL_QUERY_LOG() : last_time(0) {}
void reopen_file();
- bool write(time_t event_time, const char *user_host,
- uint user_host_len, my_thread_id thread_id,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len);
+ bool write(time_t event_time, const char *user_host, size_t user_host_len, my_thread_id thread_id,
+ const char *command_type, size_t command_type_len,
+ const char *sql_text, size_t sql_text_len);
bool write(THD *thd, time_t current_time,
- const char *user_host, uint user_host_len,
+ const char *user_host, size_t user_host_len,
ulonglong query_utime, ulonglong lock_utime, bool is_command,
- const char *sql_text, uint sql_text_len);
+ const char *sql_text, size_t sql_text_len);
bool open_slow_log(const char *log_name)
{
char buf[FN_REFLEN];
@@ -425,14 +429,18 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
#ifdef HAVE_PSI_INTERFACE
/** The instrumentation key to use for @ LOCK_index. */
PSI_mutex_key m_key_LOCK_index;
- /** The instrumentation key to use for @ update_cond. */
- PSI_cond_key m_key_update_cond;
+ /** The instrumentation key to use for @ COND_relay_log_updated */
+ PSI_cond_key m_key_relay_log_update;
+ /** The instrumentation key to use for @ COND_bin_log_updated */
+ PSI_cond_key m_key_bin_log_update;
/** The instrumentation key to use for opening the log file. */
PSI_file_key m_key_file_log;
/** The instrumentation key to use for opening the log index file. */
PSI_file_key m_key_file_log_index;
PSI_file_key m_key_COND_queue_busy;
+ /** The instrumentation key to use for LOCK_binlog_end_pos. */
+ PSI_mutex_key m_key_LOCK_binlog_end_pos;
#endif
struct group_commit_entry
@@ -488,7 +496,7 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
mysql_mutex_t LOCK_binlog_end_pos;
mysql_mutex_t LOCK_xid_list;
mysql_cond_t COND_xid_list;
- mysql_cond_t update_cond;
+ mysql_cond_t COND_relay_log_updated, COND_bin_log_updated;
ulonglong bytes_written;
IO_CACHE index_file;
char index_file_name[FN_REFLEN];
@@ -562,7 +570,13 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
bool write_transaction_to_binlog_events(group_commit_entry *entry);
void trx_group_commit_leader(group_commit_entry *leader);
bool is_xidlist_idle_nolock();
-
+#ifdef WITH_WSREP
+ /*
+ When this mariadb node is slave and galera enabled. So in this case
+ we write the gtid in wsrep_run_commit itself.
+ */
+ inline bool is_gtid_cached(THD *thd);
+#endif
public:
/*
A list of struct xid_count_per_binlog is used to keep track of how many
@@ -582,6 +596,7 @@ public:
ulong binlog_id;
/* Total prepared XIDs and pending checkpoint requests in this binlog. */
long xid_count;
+ long notify_count;
/* For linking in requests to the binlog background thread. */
xid_count_per_binlog *next_in_queue;
xid_count_per_binlog(); /* Give link error if constructor used. */
@@ -598,7 +613,7 @@ public:
/* This is relay log */
bool is_relay_log;
- ulong signal_cnt; // update of the counter is checked by heartbeat
+ ulong relay_signal_cnt; // update of the counter is checked by heartbeat
enum enum_binlog_checksum_alg checksum_alg_reset; // to contain a new value when binlog is rotated
/*
Holds the last seen in Relay-Log FD's checksum alg value.
@@ -661,16 +676,20 @@ public:
#ifdef HAVE_PSI_INTERFACE
void set_psi_keys(PSI_mutex_key key_LOCK_index,
- PSI_cond_key key_update_cond,
+ PSI_cond_key key_relay_log_update,
+ PSI_cond_key key_bin_log_update,
PSI_file_key key_file_log,
PSI_file_key key_file_log_index,
- PSI_file_key key_COND_queue_busy)
+ PSI_file_key key_COND_queue_busy,
+ PSI_mutex_key key_LOCK_binlog_end_pos)
{
m_key_LOCK_index= key_LOCK_index;
- m_key_update_cond= key_update_cond;
+ m_key_relay_log_update= key_relay_log_update;
+ m_key_bin_log_update= key_bin_log_update;
m_key_file_log= key_file_log;
m_key_file_log_index= key_file_log_index;
m_key_COND_queue_busy= key_COND_queue_busy;
+ m_key_LOCK_binlog_end_pos= key_LOCK_binlog_end_pos;
}
#endif
@@ -707,7 +726,53 @@ public:
DBUG_VOID_RETURN;
}
void set_max_size(ulong max_size_arg);
- void signal_update();
+
+ /* Handle signaling that relay has been updated */
+ void signal_relay_log_update()
+ {
+ mysql_mutex_assert_owner(&LOCK_log);
+ DBUG_ASSERT(is_relay_log);
+ DBUG_ENTER("MYSQL_BIN_LOG::signal_relay_log_update");
+ relay_signal_cnt++;
+ mysql_cond_broadcast(&COND_relay_log_updated);
+ DBUG_VOID_RETURN;
+ }
+ void signal_bin_log_update()
+ {
+ mysql_mutex_assert_owner(&LOCK_binlog_end_pos);
+ DBUG_ASSERT(!is_relay_log);
+ DBUG_ENTER("MYSQL_BIN_LOG::signal_bin_log_update");
+ mysql_cond_broadcast(&COND_bin_log_updated);
+ DBUG_VOID_RETURN;
+ }
+ void update_binlog_end_pos()
+ {
+ if (is_relay_log)
+ signal_relay_log_update();
+ else
+ {
+ lock_binlog_end_pos();
+ binlog_end_pos= my_b_safe_tell(&log_file);
+ signal_bin_log_update();
+ unlock_binlog_end_pos();
+ }
+ }
+ void update_binlog_end_pos(my_off_t pos)
+ {
+ mysql_mutex_assert_owner(&LOCK_log);
+ mysql_mutex_assert_not_owner(&LOCK_binlog_end_pos);
+ lock_binlog_end_pos();
+ /*
+ Note: it would make more sense to assert(pos > binlog_end_pos)
+ but there are two places triggered by mtr that has pos == binlog_end_pos
+ i didn't investigate but accepted as it should do no harm
+ */
+ DBUG_ASSERT(pos >= binlog_end_pos);
+ binlog_end_pos= pos;
+ signal_bin_log_update();
+ unlock_binlog_end_pos();
+ }
+
void wait_for_sufficient_commits();
void binlog_trigger_immediate_group_commit();
void wait_for_update_relay_log(THD* thd);
@@ -759,7 +824,7 @@ public:
int update_log_index(LOG_INFO* linfo, bool need_update_threads);
int rotate(bool force_rotate, bool* check_purge);
void checkpoint_and_purge(ulong binlog_id);
- int rotate_and_purge(bool force_rotate);
+ int rotate_and_purge(bool force_rotate, DYNAMIC_ARRAY* drop_gtid_domain= NULL);
/**
Flush binlog cache and synchronize to disk.
@@ -807,7 +872,7 @@ public:
inline char* get_log_fname() { return log_file_name; }
inline char* get_name() { return name; }
inline mysql_mutex_t* get_log_lock() { return &LOCK_log; }
- inline mysql_cond_t* get_log_cond() { return &update_cond; }
+ inline mysql_cond_t* get_bin_log_cond() { return &COND_bin_log_updated; }
inline IO_CACHE* get_log_file() { return &log_file; }
inline void lock_index() { mysql_mutex_lock(&LOCK_index);}
@@ -831,23 +896,6 @@ public:
bool check_strict_gtid_sequence(uint32 domain_id, uint32 server_id,
uint64 seq_no);
-
- void update_binlog_end_pos(my_off_t pos)
- {
- mysql_mutex_assert_owner(&LOCK_log);
- mysql_mutex_assert_not_owner(&LOCK_binlog_end_pos);
- lock_binlog_end_pos();
- /**
- * note: it would make more sense to assert(pos > binlog_end_pos)
- * but there are two places triggered by mtr that has pos == binlog_end_pos
- * i didn't investigate but accepted as it should do no harm
- */
- DBUG_ASSERT(pos >= binlog_end_pos);
- binlog_end_pos= pos;
- signal_update();
- unlock_binlog_end_pos();
- }
-
/**
* used when opening new file, and binlog_end_pos moves backwards
*/
@@ -858,7 +906,7 @@ public:
lock_binlog_end_pos();
binlog_end_pos= pos;
strcpy(binlog_end_pos_file, file_name);
- signal_update();
+ signal_bin_log_update();
unlock_binlog_end_pos();
}
@@ -901,16 +949,14 @@ public:
virtual void cleanup()= 0;
virtual bool log_slow(THD *thd, my_hrtime_t current_time,
- const char *user_host,
- uint user_host_len, ulonglong query_utime,
+ const char *user_host, size_t user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
- const char *sql_text, uint sql_text_len)= 0;
+ const char *sql_text, size_t sql_text_len)= 0;
virtual bool log_error(enum loglevel level, const char *format,
va_list args)= 0;
- virtual bool log_general(THD *thd, my_hrtime_t event_time, const char *user_host,
- uint user_host_len, my_thread_id thread_id,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len,
+ virtual bool log_general(THD *thd, my_hrtime_t event_time, const char *user_host, size_t user_host_len, my_thread_id thread_id,
+ const char *command_type, size_t command_type_len,
+ const char *sql_text, size_t sql_text_len,
CHARSET_INFO *client_cs)= 0;
virtual ~Log_event_handler() {}
};
@@ -930,16 +976,14 @@ public:
virtual void cleanup();
virtual bool log_slow(THD *thd, my_hrtime_t current_time,
- const char *user_host,
- uint user_host_len, ulonglong query_utime,
+ const char *user_host, size_t user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
- const char *sql_text, uint sql_text_len);
+ const char *sql_text, size_t sql_text_len);
virtual bool log_error(enum loglevel level, const char *format,
va_list args);
- virtual bool log_general(THD *thd, my_hrtime_t event_time, const char *user_host,
- uint user_host_len, my_thread_id thread_id,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len,
+ virtual bool log_general(THD *thd, my_hrtime_t event_time, const char *user_host, size_t user_host_len, my_thread_id thread_id,
+ const char *command_type, size_t command_type_len,
+ const char *sql_text, size_t sql_text_len,
CHARSET_INFO *client_cs);
int activate_log(THD *thd, uint log_type);
@@ -962,16 +1006,14 @@ public:
virtual void cleanup();
virtual bool log_slow(THD *thd, my_hrtime_t current_time,
- const char *user_host,
- uint user_host_len, ulonglong query_utime,
+ const char *user_host, size_t user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
- const char *sql_text, uint sql_text_len);
+ const char *sql_text, size_t sql_text_len);
virtual bool log_error(enum loglevel level, const char *format,
va_list args);
- virtual bool log_general(THD *thd, my_hrtime_t event_time, const char *user_host,
- uint user_host_len, my_thread_id thread_id,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len,
+ virtual bool log_general(THD *thd, my_hrtime_t event_time, const char *user_host, size_t user_host_len, my_thread_id thread_id,
+ const char *command_type, size_t command_type_len,
+ const char *sql_text, size_t sql_text_len,
CHARSET_INFO *client_cs);
void flush();
void init_pthread_objects();
@@ -1025,12 +1067,12 @@ public:
void cleanup_end();
bool error_log_print(enum loglevel level, const char *format,
va_list args);
- bool slow_log_print(THD *thd, const char *query, uint query_length,
+ bool slow_log_print(THD *thd, const char *query, size_t query_length,
ulonglong current_utime);
bool general_log_print(THD *thd,enum enum_server_command command,
const char *format, va_list args);
bool general_log_write(THD *thd, enum enum_server_command command,
- const char *query, uint query_length);
+ const char *query, size_t query_length);
/* we use this function to setup all enabled log event handlers */
int set_handlers(ulonglong error_log_printer,
@@ -1082,7 +1124,7 @@ bool general_log_print(THD *thd, enum enum_server_command command,
const char *format,...);
bool general_log_write(THD *thd, enum enum_server_command command,
- const char *query, uint query_length);
+ const char *query, size_t query_length);
void binlog_report_wait_for(THD *thd, THD *other_thd);
void sql_perror(const char *message);
@@ -1169,4 +1211,9 @@ static inline TC_LOG *get_tc_log_implementation()
return &tc_log_mmap;
}
+
+class Gtid_list_log_event;
+const char *
+get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list);
+
#endif /* LOG_H */
diff --git a/sql/log_event.cc b/sql/log_event.cc
index f1ceaec6456..ac610f978fc 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -18,7 +18,6 @@
#include "mariadb.h"
#include "sql_priv.h"
-#include "mysqld_error.h"
#ifndef MYSQL_CLIENT
#include "unireg.h"
@@ -44,6 +43,9 @@
#include <strfunc.h>
#include "compat56.h"
#include "wsrep_mysqld.h"
+#include "sql_insert.h"
+#else
+#include "mysqld_error.h"
#endif /* MYSQL_CLIENT */
#include <my_bitmap.h>
@@ -54,8 +56,6 @@
#define my_b_write_string(A, B) my_b_write((A), (uchar*)(B), (uint) (sizeof(B) - 1))
-using std::max;
-
/**
BINLOG_CHECKSUM variable.
*/
@@ -216,12 +216,12 @@ is_parallel_retry_error(rpl_group_info *rgi, int err)
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
rpl_group_info *rgi, THD *thd,
TABLE *table, const char * type,
- const char *log_name, ulong pos)
+ const char *log_name, my_off_t pos)
{
const char *handler_error= (ha_error ? HA_ERR(ha_error) : NULL);
char buff[MAX_SLAVE_ERRMSG], *slider;
const char *buff_end= buff + sizeof(buff);
- uint len;
+ size_t len;
Diagnostics_area::Sql_condition_iterator it=
thd->get_stmt_da()->sql_conditions();
Relay_log_info const *rli= rgi->rli;
@@ -250,14 +250,14 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error,
rli->report(level, errcode, rgi->gtid_info(),
"Could not execute %s event on table %s.%s;"
"%s handler error %s; "
- "the event's master log %s, end_log_pos %lu",
+ "the event's master log %s, end_log_pos %llu",
type, table->s->db.str, table->s->table_name.str,
buff, handler_error == NULL ? "<unknown>" : handler_error,
log_name, pos);
else
rli->report(level, errcode, rgi->gtid_info(),
"Could not execute %s event on table %s.%s;"
- "%s the event's master log %s, end_log_pos %lu",
+ "%s the event's master log %s, end_log_pos %llu",
type, table->s->db.str, table->s->table_name.str,
buff, log_name, pos);
}
@@ -290,10 +290,9 @@ public:
flags Flags for the cache
DESCRIPTION
-
- Class used to guarantee copy of cache to file before exiting the
- current block. On successful copy of the cache, the cache will
- be reinited as a WRITE_CACHE.
+ Cache common parameters and ensure common flush_data() code
+ on successful copy of the cache, the cache will be reinited as a
+ WRITE_CACHE.
Currently, a pointer to the cache is provided in the
constructor, but it would be possible to create a subclass
@@ -305,28 +304,36 @@ public:
reinit_io_cache(m_cache, WRITE_CACHE, 0L, FALSE, TRUE);
}
- ~Write_on_release_cache()
+ ~Write_on_release_cache() {}
+
+ bool flush_data()
{
#ifdef MYSQL_CLIENT
- if(m_ev == NULL)
+ if (m_ev == NULL)
{
- copy_event_cache_to_file_and_reinit(m_cache, m_file);
- if (m_flags & FLUSH_F)
- fflush(m_file);
+ if (copy_event_cache_to_file_and_reinit(m_cache, m_file))
+ return 1;
+ if ((m_flags & FLUSH_F) && fflush(m_file))
+ return 1;
}
else // if m_ev<>NULL, then storing the output in output_buf
{
LEX_STRING tmp_str;
+ bool res;
if (copy_event_cache_to_string_and_reinit(m_cache, &tmp_str))
- exit(1);
- m_ev->output_buf.append(&tmp_str);
+ return 1;
+ /* use 2 argument append as tmp_str is not \0 terminated */
+ res= m_ev->output_buf.append(tmp_str.str, tmp_str.length);
my_free(tmp_str.str);
+ return res ? res : 0;
}
#else /* MySQL_SERVER */
- copy_event_cache_to_file_and_reinit(m_cache, m_file);
- if (m_flags & FLUSH_F)
- fflush(m_file);
+ if (copy_event_cache_to_file_and_reinit(m_cache, m_file))
+ return 1;
+ if ((m_flags & FLUSH_F) && fflush(m_file))
+ return 1;
#endif
+ return 0;
}
/*
@@ -364,27 +371,36 @@ private:
*/
#ifdef MYSQL_CLIENT
-static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
+static bool pretty_print_str(IO_CACHE* cache, const char* str, int len)
{
const char* end = str + len;
- my_b_write_byte(cache, '\'');
+ if (my_b_write_byte(cache, '\''))
+ goto err;
+
while (str < end)
{
char c;
+ int error;
+
switch ((c=*str++)) {
- case '\n': my_b_write(cache, (uchar*)"\\n", 2); break;
- case '\r': my_b_write(cache, (uchar*)"\\r", 2); break;
- case '\\': my_b_write(cache, (uchar*)"\\\\", 2); break;
- case '\b': my_b_write(cache, (uchar*)"\\b", 2); break;
- case '\t': my_b_write(cache, (uchar*)"\\t", 2); break;
- case '\'': my_b_write(cache, (uchar*)"\\'", 2); break;
- case 0 : my_b_write(cache, (uchar*)"\\0", 2); break;
+ case '\n': error= my_b_write(cache, (uchar*)"\\n", 2); break;
+ case '\r': error= my_b_write(cache, (uchar*)"\\r", 2); break;
+ case '\\': error= my_b_write(cache, (uchar*)"\\\\", 2); break;
+ case '\b': error= my_b_write(cache, (uchar*)"\\b", 2); break;
+ case '\t': error= my_b_write(cache, (uchar*)"\\t", 2); break;
+ case '\'': error= my_b_write(cache, (uchar*)"\\'", 2); break;
+ case 0 : error= my_b_write(cache, (uchar*)"\\0", 2); break;
default:
- my_b_write_byte(cache, c);
+ error= my_b_write_byte(cache, c);
break;
}
+ if (error)
+ goto err;
}
- my_b_write_byte(cache, '\'');
+ return my_b_write_byte(cache, '\'');
+
+err:
+ return 1;
}
#endif /* MYSQL_CLIENT */
@@ -699,7 +715,7 @@ static inline int read_str(const char **buf, const char *buf_end,
Transforms a string into "" or its expression in X'HHHH' form.
*/
-char *str_to_hex(char *to, const char *from, uint len)
+char *str_to_hex(char *to, const char *from, size_t len)
{
if (len)
{
@@ -1144,19 +1160,25 @@ int append_query_string(CHARSET_INFO *csinfo, String *to,
#ifdef MYSQL_CLIENT
-static void print_set_option(IO_CACHE* file, uint32 bits_changed,
+static bool print_set_option(IO_CACHE* file, uint32 bits_changed,
uint32 option, uint32 flags, const char* name,
bool* need_comma)
{
if (bits_changed & option)
{
if (*need_comma)
- my_b_write(file, (uchar*)", ", 2);
- my_b_printf(file, "%s=%d", name, MY_TEST(flags & option));
+ if (my_b_write(file, (uchar*)", ", 2))
+ goto err;
+ if (my_b_printf(file, "%s=%d", name, MY_TEST(flags & option)))
+ goto err;
*need_comma= 1;
}
+ return 0;
+err:
+ return 1;
}
#endif
+
/**************************************************************************
Log_event methods (= the parent class of all events)
**************************************************************************/
@@ -1327,7 +1349,7 @@ Log_event::Log_event(const char* buf,
*/
log_pos+= data_written; /* purecov: inspected */
}
- DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
+ DBUG_PRINT("info", ("log_pos: %llu", log_pos));
flags= uint2korr(buf + FLAGS_OFFSET);
if (((uchar)buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
@@ -1456,7 +1478,7 @@ void Log_event::init_show_field_list(THD *thd, List<Item>* field_list)
mem_root);
field_list->push_back(new (mem_root)
Item_return_int(thd, "Pos",
- MY_INT32_NUM_DECIMAL_DIGITS,
+ MY_INT64_NUM_DECIMAL_DIGITS,
MYSQL_TYPE_LONGLONG),
mem_root);
field_list->push_back(new (mem_root)
@@ -1468,7 +1490,7 @@ void Log_event::init_show_field_list(THD *thd, List<Item>* field_list)
mem_root);
field_list->push_back(new (mem_root)
Item_return_int(thd, "End_log_pos",
- MY_INT32_NUM_DECIMAL_DIGITS,
+ MY_INT64_NUM_DECIMAL_DIGITS,
MYSQL_TYPE_LONGLONG),
mem_root);
field_list->push_back(new (mem_root) Item_empty_string(thd, "Info", 20),
@@ -1583,13 +1605,13 @@ int Log_event_writer::encrypt_and_write(const uchar *pos, size_t len)
if (ctx)
{
- dstsize= encryption_encrypted_length(len, ENCRYPTION_KEY_SYSTEM_DATA,
+ dstsize= encryption_encrypted_length((uint)len, ENCRYPTION_KEY_SYSTEM_DATA,
crypto->key_version);
if (!(dst= (uchar*)my_safe_alloca(dstsize)))
return 1;
uint dstlen;
- if (encryption_ctx_update(ctx, pos, len, dst, &dstlen))
+ if (encryption_ctx_update(ctx, pos, (uint)len, dst, &dstlen))
goto err;
if (maybe_write_event_len(dst, dstlen))
return 1;
@@ -1677,12 +1699,12 @@ int Log_event_writer::write_footer()
Log_event::write_header()
*/
-bool Log_event::write_header(ulong event_data_length)
+bool Log_event::write_header(size_t event_data_length)
{
uchar header[LOG_EVENT_HEADER_LEN];
ulong now;
DBUG_ENTER("Log_event::write_header");
- DBUG_PRINT("enter", ("filepos: %lld length: %lu type: %d",
+ DBUG_PRINT("enter", ("filepos: %lld length: %zu type: %d",
(longlong) writer->pos(), event_data_length,
(int) get_type_code()));
@@ -1712,6 +1734,8 @@ bool Log_event::write_header(ulong event_data_length)
*/
log_pos= writer->pos() + data_written;
+
+ DBUG_EXECUTE_IF("dbug_master_binlog_over_2GB", log_pos += (1ULL <<31););
}
now= get_time(); // Query start time
@@ -1776,8 +1800,8 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN)
DBUG_RETURN(LOG_READ_BOGUS);
- if (data_len > max(max_allowed_packet,
- opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER))
+ if (data_len > MY_MAX(max_allowed_packet,
+ opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER))
DBUG_RETURN(LOG_READ_TOO_LARGE);
if (likely(data_len > LOG_EVENT_MINIMAL_HEADER_LEN))
@@ -1854,7 +1878,7 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
DBUG_RETURN(0);
}
-Log_event* Log_event::read_log_event(IO_CACHE* file, mysql_mutex_t* log_lock,
+Log_event* Log_event::read_log_event(IO_CACHE* file,
const Format_description_log_event *fdle,
my_bool crc_check)
{
@@ -1864,9 +1888,6 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, mysql_mutex_t* log_lock,
const char *error= 0;
Log_event *res= 0;
- if (log_lock)
- mysql_mutex_lock(log_lock);
-
switch (read_log_event(file, &event, fdle, BINLOG_CHECKSUM_ALG_OFF))
{
case 0:
@@ -1903,8 +1924,6 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, mysql_mutex_t* log_lock,
res->register_temp_buf(event.release(), true);
err:
- if (log_lock)
- mysql_mutex_unlock(log_lock);
if (error)
{
DBUG_ASSERT(!res);
@@ -1914,9 +1933,9 @@ err:
#endif
if (event.length() >= OLD_HEADER_LEN)
sql_print_error("Error in Log_event::read_log_event(): '%s',"
- " data_len: %lu, event_type: %d", error,
- uint4korr(&event[EVENT_LEN_OFFSET]),
- (uchar)event[EVENT_TYPE_OFFSET]);
+ " data_len: %lu, event_type: %u", error,
+ (ulong) uint4korr(&event[EVENT_LEN_OFFSET]),
+ (uint) (uchar)event[EVENT_TYPE_OFFSET]);
else
sql_print_error("Error in Log_event::read_log_event(): '%s'", error);
/*
@@ -2246,7 +2265,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
#ifdef MYSQL_CLIENT
-static void hexdump_minimal_header_to_io_cache(IO_CACHE *file,
+static bool hexdump_minimal_header_to_io_cache(IO_CACHE *file,
my_off_t offset,
uchar *ptr)
{
@@ -2259,15 +2278,18 @@ static void hexdump_minimal_header_to_io_cache(IO_CACHE *file,
more headers (which must be printed by other methods, if desired).
*/
char emit_buf[120]; // Enough for storing one line
- my_b_printf(file,
- "# "
- "|Timestamp "
- "|Type "
- "|Master ID "
- "|Size "
- "|Master Pos "
- "|Flags\n");
- size_t const emit_buf_written=
+ size_t emit_buf_written;
+
+ if (my_b_printf(file,
+ "# "
+ "|Timestamp "
+ "|Type "
+ "|Master ID "
+ "|Size "
+ "|Master Pos "
+ "|Flags\n"))
+ goto err;
+ emit_buf_written=
my_snprintf(emit_buf, sizeof(emit_buf),
"# %8llx " /* Position */
"|%02x %02x %02x %02x " /* Timestamp */
@@ -2285,8 +2307,13 @@ static void hexdump_minimal_header_to_io_cache(IO_CACHE *file,
ptr[17], ptr[18]); /* Flags */
DBUG_ASSERT(static_cast<size_t>(emit_buf_written) < sizeof(emit_buf));
- my_b_write(file, reinterpret_cast<uchar*>(emit_buf), emit_buf_written);
- my_b_write(file, (uchar*)"#\n", 2);
+ if (my_b_write(file, reinterpret_cast<uchar*>(emit_buf), emit_buf_written) ||
+ my_b_write(file, (uchar*)"#\n", 2))
+ goto err;
+
+ return 0;
+err:
+ return 1;
}
@@ -2311,7 +2338,7 @@ static void format_hex_line(char *emit_buff)
HEXDUMP_BYTES_PER_LINE + 2]= '\0';
}
-static void hexdump_data_to_io_cache(IO_CACHE *file,
+static bool hexdump_data_to_io_cache(IO_CACHE *file,
my_off_t offset,
uchar *ptr,
my_off_t size)
@@ -2333,7 +2360,7 @@ static void hexdump_data_to_io_cache(IO_CACHE *file,
my_off_t i;
if (size == 0)
- return;
+ return 0; // ok, nothing to do
format_hex_line(emit_buffer);
/*
@@ -2363,8 +2390,9 @@ static void hexdump_data_to_io_cache(IO_CACHE *file,
(ulonglong) starting_offset);
/* remove \0 left after printing address */
emit_buffer[2 + emit_buf_written]= ' ';
- my_b_write(file, reinterpret_cast<uchar*>(emit_buffer),
- sizeof(emit_buffer) - 1);
+ if (my_b_write(file, reinterpret_cast<uchar*>(emit_buffer),
+ sizeof(emit_buffer) - 1))
+ goto err;
c= emit_buffer + 2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2;
h= emit_buffer + 2 + 8 + 2;
format_hex_line(emit_buffer);
@@ -2399,17 +2427,23 @@ static void hexdump_data_to_io_cache(IO_CACHE *file,
/* pad unprinted area */
memset(h, ' ',
(HEXDUMP_BYTES_PER_LINE * 3 + 1) - (h - (emit_buffer + 2 + 8 + 2)));
- my_b_write(file, reinterpret_cast<uchar*>(emit_buffer),
- c - emit_buffer);
+ if (my_b_write(file, reinterpret_cast<uchar*>(emit_buffer),
+ c - emit_buffer))
+ goto err;
}
- my_b_write(file, (uchar*)"#\n", 2);
+ if (my_b_write(file, (uchar*)"#\n", 2))
+ goto err;
+
+ return 0;
+err:
+ return 1;
}
/*
Log_event::print_header()
*/
-void Log_event::print_header(IO_CACHE* file,
+bool Log_event::print_header(IO_CACHE* file,
PRINT_EVENT_INFO* print_event_info,
bool is_more __attribute__((unused)))
{
@@ -2417,10 +2451,11 @@ void Log_event::print_header(IO_CACHE* file,
my_off_t hexdump_from= print_event_info->hexdump_from;
DBUG_ENTER("Log_event::print_header");
- my_b_write_byte(file, '#');
- print_timestamp(file);
- my_b_printf(file, " server id %lu end_log_pos %s ", (ulong) server_id,
- llstr(log_pos,llbuff));
+ if (my_b_write_byte(file, '#') ||
+ print_timestamp(file) ||
+ my_b_printf(file, " server id %lu end_log_pos %s ", (ulong) server_id,
+ llstr(log_pos,llbuff)))
+ goto err;
/* print the checksum */
@@ -2430,8 +2465,10 @@ void Log_event::print_header(IO_CACHE* file,
char checksum_buf[BINLOG_CHECKSUM_LEN * 2 + 4]; // to fit to "%p "
size_t const bytes_written=
my_snprintf(checksum_buf, sizeof(checksum_buf), "0x%08x ", crc);
- my_b_printf(file, "%s ", get_type(&binlog_checksum_typelib, checksum_alg));
- my_b_printf(file, checksum_buf, bytes_written);
+ if (my_b_printf(file, "%s ", get_type(&binlog_checksum_typelib,
+ checksum_alg)) ||
+ my_b_printf(file, checksum_buf, bytes_written))
+ goto err;
}
/* mysqlbinlog --hexdump */
@@ -2444,24 +2481,32 @@ void Log_event::print_header(IO_CACHE* file,
size-= hdr_len;
- my_b_printf(file, "# Position\n");
+ if (my_b_printf(file, "# Position\n"))
+ goto err;
/* Write the header, nicely formatted by field. */
- hexdump_minimal_header_to_io_cache(file, hexdump_from, ptr);
+ if (hexdump_minimal_header_to_io_cache(file, hexdump_from, ptr))
+ goto err;
ptr+= hdr_len;
hexdump_from+= hdr_len;
/* Print the rest of the data, mimicking "hexdump -C" output. */
- hexdump_data_to_io_cache(file, hexdump_from, ptr, size);
+ if (hexdump_data_to_io_cache(file, hexdump_from, ptr, size))
+ goto err;
/*
Prefix the next line so that the output from print_helper()
will appear as a comment.
*/
- my_b_write(file, (uchar*)"# Event: ", 9);
+ if (my_b_write(file, (uchar*)"# Event: ", 9))
+ goto err;
}
- DBUG_VOID_RETURN;
+
+ DBUG_RETURN(0);
+
+err:
+ DBUG_RETURN(1);
}
@@ -2469,7 +2514,7 @@ void Log_event::print_header(IO_CACHE* file,
Prints a quoted string to io cache.
Control characters are displayed as hex sequence, e.g. \x00
Single-quote and backslash characters are escaped with a \
-
+
@param[in] file IO cache
@param[in] prt Pointer to string
@param[in] length String length
@@ -2556,12 +2601,14 @@ my_b_write_quoted_with_length(IO_CACHE *file, const uchar *ptr, uint length)
@param[in] sl Signed number
@param[in] ul Unsigned number
*/
-static void
+static bool
my_b_write_sint32_and_uint32(IO_CACHE *file, int32 si, uint32 ui)
{
- my_b_printf(file, "%d", si);
+ bool res= my_b_printf(file, "%d", si);
if (si < 0)
- my_b_printf(file, " (%u)", ui);
+ if (my_b_printf(file, " (%u)", ui))
+ res= 1;
+ return res;
}
@@ -2580,8 +2627,8 @@ my_b_write_sint32_and_uint32(IO_CACHE *file, int32 si, uint32 ui)
*/
static size_t
-log_event_print_value(IO_CACHE *file, const uchar *ptr,
- uint type, uint meta,
+log_event_print_value(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info,
+ const uchar *ptr, uint type, uint meta,
char *typestr, size_t typestr_length)
{
uint32 length= 0;
@@ -2964,19 +3011,15 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
return my_b_write_quoted_with_length(file, ptr, length);
case MYSQL_TYPE_DECIMAL:
- my_b_printf(file,
- "!! Old DECIMAL (mysql-4.1 or earlier). "
- "Not enough metadata to display the value. ");
+ print_event_info->flush_for_error();
+ fprintf(stderr, "\nError: Found Old DECIMAL (mysql-4.1 or earlier). "
+ "Not enough metadata to display the value.\n");
break;
-
default:
- {
- char tmp[5];
- my_snprintf(tmp, sizeof(tmp), "%04x", meta);
- my_b_printf(file,
- "!! Don't know how to handle column type=%d meta=%d (%s)",
- type, meta, tmp);
- }
+ print_event_info->flush_for_error();
+ fprintf(stderr,
+ "\nError: Don't know how to handle column type: %d meta: %d (%04x)\n",
+ type, meta, meta);
break;
}
*typestr= 0;
@@ -2997,7 +3040,8 @@ return_null:
@param[in] value Pointer to packed row
@param[in] prefix Row's SQL clause ("SET", "WHERE", etc)
- @retval - number of bytes scanned.
+ @retval 0 error
+ # number of bytes scanned.
*/
@@ -3027,9 +3071,10 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
value+= (bitmap_bits_set(cols_bitmap) + 7) / 8;
if (!no_fill_output)
- my_b_printf(file, "%s", prefix);
+ if (my_b_printf(file, "%s", prefix))
+ goto err;
- for (size_t i= 0; i < td->size(); i ++)
+ for (uint i= 0; i < (uint)td->size(); i ++)
{
size_t size;
int is_null= (null_bits[null_bit_index / 8]
@@ -3039,7 +3084,8 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
continue;
if (!no_fill_output)
- my_b_printf(file, "### @%d=", static_cast<int>(i + 1));
+ if (my_b_printf(file, "### @%d=", static_cast<int>(i + 1)))
+ goto err;
if (!is_null)
{
@@ -3047,8 +3093,9 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
if (value + fsize > m_rows_end)
{
if (!no_fill_output)
- my_b_printf(file, "***Corrupted replication event was detected."
- " Not printing the value***\n");
+ if (my_b_printf(file, "***Corrupted replication event was detected."
+ " Not printing the value***\n"))
+ goto err;
value+= fsize;
return 0;
}
@@ -3056,7 +3103,7 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
if (!no_fill_output)
{
- size= log_event_print_value(file,is_null? NULL: value,
+ size= log_event_print_value(file, print_event_info, is_null? NULL: value,
td->type(i), td->field_metadata(i),
typestr, sizeof(typestr));
#ifdef WHEN_FLASHBACK_REVIEW_READY
@@ -3067,12 +3114,14 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
// Using a tmp IO_CACHE to get the value output
open_cached_file(&tmp_cache, NULL, NULL, 0, MYF(MY_WME | MY_NABP));
- size= log_event_print_value(&tmp_cache, is_null? NULL: value,
+ size= log_event_print_value(&tmp_cache, print_event_info,
+ is_null ? NULL: value,
td->type(i), td->field_metadata(i),
typestr, sizeof(typestr));
- if (copy_event_cache_to_string_and_reinit(&tmp_cache, &review_str))
- exit(1);
+ error= copy_event_cache_to_string_and_reinit(&tmp_cache, &review_str);
close_cached_file(&tmp_cache);
+ if (error)
+ return 0;
switch (td->type(i)) // Converting a string to HEX format
{
@@ -3090,12 +3139,14 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
exit(1);
}
octet2hex((char*) hex_str.ptr(), tmp_str.ptr(), tmp_str.length());
- my_b_printf(review_sql, ", UNHEX('%s')", hex_str.ptr());
+ if (my_b_printf(review_sql, ", UNHEX('%s')", hex_str.ptr()))
+ goto err;
break;
default:
tmp_str.free();
- tmp_str.append(review_str.str, review_str.length);
- my_b_printf(review_sql, ", %s", tmp_str.ptr());
+ if (tmp_str.append(review_str.str, review_str.length) ||
+ my_b_printf(review_sql, ", %s", tmp_str.ptr()))
+ goto err;
break;
}
my_free(revieww_str.str);
@@ -3106,36 +3157,40 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
{
IO_CACHE tmp_cache;
open_cached_file(&tmp_cache, NULL, NULL, 0, MYF(MY_WME | MY_NABP));
- size= log_event_print_value(&tmp_cache,is_null? NULL: value,
+ size= log_event_print_value(&tmp_cache, print_event_info,
+ is_null ? NULL: value,
td->type(i), td->field_metadata(i),
typestr, sizeof(typestr));
close_cached_file(&tmp_cache);
}
if (!size)
- return 0;
+ goto err;
if (!is_null)
value+= size;
if (print_event_info->verbose > 1 && !no_fill_output)
{
- my_b_write(file, (uchar*)" /* ", 4);
-
- my_b_printf(file, "%s ", typestr);
-
- my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
- td->field_metadata(i),
- td->maybe_null(i), is_null);
- my_b_write(file, (uchar*)"*/", 2);
+ if (my_b_write(file, (uchar*)" /* ", 4) ||
+ my_b_printf(file, "%s ", typestr) ||
+ my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
+ td->field_metadata(i),
+ td->maybe_null(i), is_null) ||
+ my_b_write(file, (uchar*)"*/", 2))
+ goto err;
}
if (!no_fill_output)
- my_b_write_byte(file, '\n');
+ if (my_b_write_byte(file, '\n'))
+ goto err;
null_bit_index++;
}
return value - value0;
+
+err:
+ return 0;
}
@@ -3174,10 +3229,10 @@ void Rows_log_event::change_to_flashback_event(PRINT_EVENT_INFO *print_event_inf
if (!(length1= print_verbose_one_row(NULL, td, print_event_info,
&m_cols, value,
(const uchar*) "", TRUE)))
- {
- fprintf(stderr, "\nError row length: %zu\n", length1);
- exit(1);
- }
+ {
+ fprintf(stderr, "\nError row length: %zu\n", length1);
+ exit(1);
+ }
value+= length1;
swap_buff1= (uchar *) my_malloc(length1, MYF(0));
@@ -3256,18 +3311,230 @@ end:
delete td;
}
+/**
+ Calc length of a packed value of the given SQL type
+
+ @param[in] ptr Pointer to string
+ @param[in] type Column type
+ @param[in] meta Column meta information
+
+ @retval - number of bytes scanned from ptr.
+ Except in case of NULL, in which case we return 1 to indicate ok
+*/
+
+static size_t calc_field_event_length(const uchar *ptr, uint type, uint meta)
+{
+ uint32 length= 0;
+
+ if (type == MYSQL_TYPE_STRING)
+ {
+ if (meta >= 256)
+ {
+ uint byte0= meta >> 8;
+ uint byte1= meta & 0xFF;
+
+ if ((byte0 & 0x30) != 0x30)
+ {
+ /* a long CHAR() field: see #37426 */
+ length= byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
+ type= byte0 | 0x30;
+ }
+ else
+ length = meta & 0xFF;
+ }
+ else
+ length= meta;
+ }
+
+ switch (type) {
+ case MYSQL_TYPE_LONG:
+ case MYSQL_TYPE_TIMESTAMP:
+ return 4;
+ case MYSQL_TYPE_TINY:
+ case MYSQL_TYPE_YEAR:
+ return 1;
+ case MYSQL_TYPE_SHORT:
+ return 2;
+ case MYSQL_TYPE_INT24:
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_NEWDATE:
+ case MYSQL_TYPE_DATE:
+ return 3;
+ case MYSQL_TYPE_LONGLONG:
+ case MYSQL_TYPE_DATETIME:
+ return 8;
+ case MYSQL_TYPE_NEWDECIMAL:
+ {
+ uint precision= meta >> 8;
+ uint decimals= meta & 0xFF;
+ uint bin_size= my_decimal_get_binary_size(precision, decimals);
+ return bin_size;
+ }
+ case MYSQL_TYPE_FLOAT:
+ return 4;
+ case MYSQL_TYPE_DOUBLE:
+ return 8;
+ case MYSQL_TYPE_BIT:
+ {
+ /* Meta-data: bit_len, bytes_in_rec, 2 bytes */
+ uint nbits= ((meta >> 8) * 8) + (meta & 0xFF);
+ length= (nbits + 7) / 8;
+ return length;
+ }
+ case MYSQL_TYPE_TIMESTAMP2:
+ return my_timestamp_binary_length(meta);
+ case MYSQL_TYPE_DATETIME2:
+ return my_datetime_binary_length(meta);
+ case MYSQL_TYPE_TIME2:
+ return my_time_binary_length(meta);
+ case MYSQL_TYPE_ENUM:
+ switch (meta & 0xFF) {
+ case 1:
+ case 2:
+ return (meta & 0xFF);
+ default:
+ /* Unknown ENUM packlen=%d", meta & 0xFF */
+ return 0;
+ }
+ break;
+ case MYSQL_TYPE_SET:
+ return meta & 0xFF;
+ case MYSQL_TYPE_BLOB:
+ return (meta <= 4 ? meta : 0);
+ case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_VAR_STRING:
+ length= meta;
+ /* fall through */
+ case MYSQL_TYPE_STRING:
+ if (length < 256)
+ return (uint) *ptr + 1;
+ return uint2korr(ptr) + 2;
+ case MYSQL_TYPE_DECIMAL:
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+size_t
+Rows_log_event::calc_row_event_length(table_def *td,
+ PRINT_EVENT_INFO *print_event_info,
+ MY_BITMAP *cols_bitmap,
+ const uchar *value)
+{
+ const uchar *value0= value;
+ const uchar *null_bits= value;
+ uint null_bit_index= 0;
+
+ /*
+ Skip metadata bytes which gives the information about nullabity of master
+ columns. Master writes one bit for each affected column.
+ */
+
+ value+= (bitmap_bits_set(cols_bitmap) + 7) / 8;
+
+ for (uint i= 0; i < (uint)td->size(); i ++)
+ {
+ int is_null;
+ is_null= (null_bits[null_bit_index / 8] >> (null_bit_index % 8)) & 0x01;
+
+ if (bitmap_is_set(cols_bitmap, i) == 0)
+ continue;
+
+ if (!is_null)
+ {
+ size_t size;
+ size_t fsize= td->calc_field_size((uint)i, (uchar*) value);
+ if (value + fsize > m_rows_end)
+ {
+ /* Corrupted replication event was detected, skipping entry */
+ return 0;
+ }
+ if (!(size= calc_field_event_length(value, td->type(i),
+ td->field_metadata(i))))
+ return 0;
+ value+= size;
+ }
+ null_bit_index++;
+ }
+ return value - value0;
+}
+
+
+/**
+ Calculate how many rows there are in the event
+
+ @param[in] file IO cache
+ @param[in] print_event_into Print parameters
+*/
+
+void Rows_log_event::count_row_events(PRINT_EVENT_INFO *print_event_info)
+{
+ Table_map_log_event *map;
+ table_def *td;
+ uint row_events;
+ Log_event_type general_type_code= get_general_type_code();
+
+ switch (general_type_code) {
+ case WRITE_ROWS_EVENT:
+ case DELETE_ROWS_EVENT:
+ row_events= 1;
+ break;
+ case UPDATE_ROWS_EVENT:
+ row_events= 2;
+ break;
+ default:
+ DBUG_ASSERT(0); /* Not possible */
+ return;
+ }
+
+ if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
+ !(td= map->create_table_def()))
+ {
+ /* Row event for unknown table */
+ return;
+ }
+
+ for (const uchar *value= m_rows_buf; value < m_rows_end; )
+ {
+ size_t length;
+ print_event_info->row_events++;
+
+ /* Print the first image */
+ if (!(length= calc_row_event_length(td, print_event_info,
+ &m_cols, value)))
+ break;
+ value+= length;
+ DBUG_ASSERT(value <= m_rows_end);
+
+ /* Print the second image (for UPDATE only) */
+ if (row_events == 2)
+ {
+ if (!(length= calc_row_event_length(td, print_event_info,
+ &m_cols_ai, value)))
+ break;
+ value+= length;
+ DBUG_ASSERT(value <= m_rows_end);
+ }
+ }
+ delete td;
+}
+
/**
Print a row event into IO cache in human readable form (in SQL format)
-
+
@param[in] file IO cache
@param[in] print_event_into Print parameters
*/
-void Rows_log_event::print_verbose(IO_CACHE *file,
+
+bool Rows_log_event::print_verbose(IO_CACHE *file,
PRINT_EVENT_INFO *print_event_info)
{
Table_map_log_event *map;
- table_def *td;
+ table_def *td= 0;
const char *sql_command, *sql_clause1, *sql_clause2;
const char *sql_command_short __attribute__((unused));
Log_event_type general_type_code= get_general_type_code();
@@ -3281,9 +3548,10 @@ void Rows_log_event::print_verbose(IO_CACHE *file,
uint8 extra_payload_len= extra_data_len - EXTRA_ROW_INFO_HDR_BYTES;
assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
- my_b_printf(file, "### Extra row data format: %u, len: %u :",
- m_extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET],
- extra_payload_len);
+ if (my_b_printf(file, "### Extra row data format: %u, len: %u :",
+ m_extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET],
+ extra_payload_len))
+ goto err;
if (extra_payload_len)
{
/*
@@ -3294,9 +3562,11 @@ void Rows_log_event::print_verbose(IO_CACHE *file,
char buff[buff_len];
str_to_hex(buff, (const char*) &m_extra_row_data[EXTRA_ROW_INFO_HDR_BYTES],
extra_payload_len);
- my_b_printf(file, "%s", buff);
+ if (my_b_printf(file, "%s", buff))
+ goto err;
}
- my_b_printf(file, "\n");
+ if (my_b_printf(file, "\n"))
+ goto err;
}
switch (general_type_code) {
@@ -3323,41 +3593,45 @@ void Rows_log_event::print_verbose(IO_CACHE *file,
sql_command_short= "";
DBUG_ASSERT(0); /* Not possible */
}
-
+
if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
!(td= map->create_table_def()))
{
- my_b_printf(file, "### Row event for unknown table #%lu",
- (ulong) m_table_id);
- return;
+ return (my_b_printf(file, "### Row event for unknown table #%lu",
+ (ulong) m_table_id));
}
/* If the write rows event contained no values for the AI */
if (((general_type_code == WRITE_ROWS_EVENT) && (m_rows_buf==m_rows_end)))
{
- my_b_printf(file, "### INSERT INTO %`s.%`s VALUES ()\n",
- map->get_db_name(), map->get_table_name());
+ if (my_b_printf(file, "### INSERT INTO %`s.%`s VALUES ()\n",
+ map->get_db_name(), map->get_table_name()))
+ goto err;
goto end;
}
for (const uchar *value= m_rows_buf; value < m_rows_end; )
{
size_t length;
- my_b_printf(file, "### %s %`s.%`s\n",
- sql_command,
- map->get_db_name(), map->get_table_name());
+ print_event_info->row_events++;
+ if (my_b_printf(file, "### %s %`s.%`s\n",
+ sql_command,
+ map->get_db_name(), map->get_table_name()))
+ goto err;
#ifdef WHEN_FLASHBACK_REVIEW_READY
if (need_flashback_review)
- my_b_printf(review_sql, "\nINSERT INTO `%s`.`%s` VALUES ('%s'",
- map->get_review_dbname(), map->get_review_tablename(), sql_command_short);
+ if (my_b_printf(review_sql, "\nINSERT INTO `%s`.`%s` VALUES ('%s'",
+ map->get_review_dbname(), map->get_review_tablename(),
+ sql_command_short))
+ goto err;
#endif
/* Print the first image */
if (!(length= print_verbose_one_row(file, td, print_event_info,
&m_cols, value,
(const uchar*) sql_clause1)))
- goto end;
+ goto err;
value+= length;
/* Print the second image (for UPDATE only) */
@@ -3366,7 +3640,7 @@ void Rows_log_event::print_verbose(IO_CACHE *file,
if (!(length= print_verbose_one_row(file, td, print_event_info,
&m_cols_ai, value,
(const uchar*) sql_clause2)))
- goto end;
+ goto err;
value+= length;
}
#ifdef WHEN_FLASHBACK_REVIEW_READY
@@ -3374,16 +3648,22 @@ void Rows_log_event::print_verbose(IO_CACHE *file,
{
if (need_flashback_review)
for (size_t i= 0; i < td->size(); i ++)
- my_b_printf(review_sql, ", NULL");
+ if (my_b_printf(review_sql, ", NULL"))
+ goto err;
}
if (need_flashback_review)
- my_b_printf(review_sql, ")%s\n", print_event_info->delimiter);
+ if (my_b_printf(review_sql, ")%s\n", print_event_info->delimiter))
+ goto err;
#endif
}
end:
delete td;
+ return 0;
+err:
+ delete td;
+ return 1;
}
void free_table_map_log_event(Table_map_log_event *event)
@@ -3391,7 +3671,7 @@ void free_table_map_log_event(Table_map_log_event *event)
delete event;
}
-void Log_event::print_base64(IO_CACHE* file,
+bool Log_event::print_base64(IO_CACHE* file,
PRINT_EVENT_INFO* print_event_info,
bool more)
{
@@ -3399,14 +3679,6 @@ void Log_event::print_base64(IO_CACHE* file,
uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
DBUG_ENTER("Log_event::print_base64");
- size_t const tmp_str_sz= my_base64_needed_encoded_length((int) size);
- char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
- if (!tmp_str) {
- fprintf(stderr, "\nError: Out of memory. "
- "Could not print correct binlog event.\n");
- DBUG_VOID_RETURN;
- }
-
if (is_flashback)
{
uint tmp_size= size;
@@ -3452,27 +3724,41 @@ void Log_event::print_base64(IO_CACHE* file,
delete ev;
}
- if (my_base64_encode(ptr, (size_t) size, tmp_str))
+ if (print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
+ print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS &&
+ ! print_event_info->short_form)
{
- DBUG_ASSERT(0);
- }
-
- if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
- {
- if (my_b_tell(file) == 0)
- my_b_write_string(file, "\nBINLOG '\n");
+ size_t const tmp_str_sz= my_base64_needed_encoded_length((int) size);
+ bool error= 0;
+ char *tmp_str;
+ if (!(tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME))))
+ goto err;
- my_b_printf(file, "%s\n", tmp_str);
+ if (my_base64_encode(ptr, (size_t) size, tmp_str))
+ {
+ DBUG_ASSERT(0);
+ }
- if (!more)
- my_b_printf(file, "'%s\n", print_event_info->delimiter);
+ if (my_b_tell(file) == 0)
+ if (my_b_write_string(file, "\nBINLOG '\n"))
+ error= 1;
+ if (!error && my_b_printf(file, "%s\n", tmp_str))
+ error= 1;
+ if (!more && !error)
+ if (my_b_printf(file, "'%s\n", print_event_info->delimiter))
+ error= 1;
+ my_free(tmp_str);
+ if (error)
+ goto err;
}
#ifdef WHEN_FLASHBACK_REVIEW_READY
- if (print_event_info->verbose || need_flashback_review)
+ if (print_event_info->verbose || print_event_info->print_row_count ||
+ need_flashback_review)
#else
// Flashback need the table_map to parse the event
- if (print_event_info->verbose || is_flashback)
+ if (print_event_info->verbose || print_event_info->print_row_count ||
+ is_flashback)
#endif
{
Rows_log_event *ev= NULL;
@@ -3547,27 +3833,49 @@ void Log_event::print_base64(IO_CACHE* file,
if (ev)
{
+ bool error= 0;
+
#ifdef WHEN_FLASHBACK_REVIEW_READY
ev->need_flashback_review= need_flashback_review;
if (print_event_info->verbose)
- ev->print_verbose(file, print_event_info);
+ {
+ if (ev->print_verbose(file, print_event_info))
+ goto err;
+ }
else
{
IO_CACHE tmp_cache;
- open_cached_file(&tmp_cache, NULL, NULL, 0, MYF(MY_WME | MY_NABP));
- ev->print_verbose(&tmp_cache, print_event_info);
+
+ if (open_cached_file(&tmp_cache, NULL, NULL, 0,
+ MYF(MY_WME | MY_NABP)))
+ {
+ delete ev;
+ goto err;
+ }
+
+ error= ev->print_verbose(&tmp_cache, print_event_info);
close_cached_file(&tmp_cache);
+ if (error)
+ {
+ delete ev;
+ goto err;
+ }
}
#else
if (print_event_info->verbose)
- ev->print_verbose(file, print_event_info);
+ error= ev->print_verbose(file, print_event_info);
+ else
+ ev->count_row_events(print_event_info);
#endif
delete ev;
+ if (error)
+ goto err;
}
}
+ DBUG_RETURN(0);
- my_free(tmp_str);
- DBUG_VOID_RETURN;
+err:
+ DBUG_RETURN(1);
}
@@ -3575,7 +3883,7 @@ void Log_event::print_base64(IO_CACHE* file,
Log_event::print_timestamp()
*/
-void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
+bool Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
{
struct tm *res;
time_t my_when= when;
@@ -3584,14 +3892,13 @@ void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
ts = &my_when;
res=localtime(ts);
- my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
- res->tm_year % 100,
- res->tm_mon+1,
- res->tm_mday,
- res->tm_hour,
- res->tm_min,
- res->tm_sec);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
+ res->tm_year % 100,
+ res->tm_mon+1,
+ res->tm_mday,
+ res->tm_hour,
+ res->tm_min,
+ res->tm_sec));
}
#endif /* MYSQL_CLIENT */
@@ -3955,8 +4262,7 @@ Query_log_event::Query_log_event()
Creates an event for binlogging
The value for `errcode' should be supplied by caller.
*/
-Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
- ulong query_length, bool using_trans,
+Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, size_t query_length, bool using_trans,
bool direct, bool suppress_use, int errcode)
:Log_event(thd_arg,
@@ -3965,7 +4271,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
(suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
using_trans),
data_buf(0), query(query_arg), catalog(thd_arg->catalog),
- db(thd_arg->db), q_len((uint32) query_length),
+ db(thd_arg->db.str), q_len((uint32) query_length),
thread_id(thd_arg->thread_id),
/* save the original thread id; we already know the server id */
slave_proxy_id((ulong)thd_arg->variables.pseudo_thread_id),
@@ -4182,7 +4488,7 @@ get_str_len_and_pointer(const Log_event::Byte **src,
static void copy_str_and_move(const char **src,
Log_event::Byte **dst,
- uint len)
+ size_t len)
{
memcpy(*dst, *src, len);
*src= (const char *)*dst;
@@ -4315,7 +4621,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
event from the relay log.
*/
DBUG_ASSERT(description_event->binlog_version < 4);
- master_data_written= data_written;
+ master_data_written= (uint32)data_written;
}
/*
We have parsed everything we know in the post header for QUERY_EVENT,
@@ -4631,7 +4937,7 @@ Query_log_event::dummy_event(String *packet, ulong ev_offset,
possibly just @`!`).
*/
static const char var_name[]= "!dummyvar";
- uint name_len= data_len - (min_user_var_event_len - 1);
+ size_t name_len= data_len - (min_user_var_event_len - 1);
p[EVENT_TYPE_OFFSET]= USER_VAR_EVENT;
int4store(p + LOG_EVENT_HEADER_LEN, name_len);
@@ -4750,7 +5056,7 @@ Query_log_event::begin_event(String *packet, ulong ev_offset,
@todo
print the catalog ??
*/
-void Query_log_event::print_query_header(IO_CACHE* file,
+bool Query_log_event::print_query_header(IO_CACHE* file,
PRINT_EVENT_INFO* print_event_info)
{
// TODO: print the catalog ??
@@ -4760,10 +5066,12 @@ void Query_log_event::print_query_header(IO_CACHE* file,
if (!print_event_info->short_form)
{
- print_header(file, print_event_info, FALSE);
- my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
- get_type_str(), (ulong) thread_id, (ulong) exec_time,
- error_code);
+ if (print_header(file, print_event_info, FALSE) ||
+ my_b_printf(file,
+ "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
+ get_type_str(), (ulong) thread_id, (ulong) exec_time,
+ error_code))
+ goto err;
}
if ((flags & LOG_EVENT_SUPPRESS_USE_F))
@@ -4777,7 +5085,8 @@ void Query_log_event::print_query_header(IO_CACHE* file,
if (different_db)
memcpy(print_event_info->db, db, db_len + 1);
if (db[0] && different_db)
- my_b_printf(file, "use %`s%s\n", db, print_event_info->delimiter);
+ if (my_b_printf(file, "use %`s%s\n", db, print_event_info->delimiter))
+ goto err;
}
end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
@@ -4788,15 +5097,17 @@ void Query_log_event::print_query_header(IO_CACHE* file,
}
end= strmov(end, print_event_info->delimiter);
*end++='\n';
- my_b_write(file, (uchar*) buff, (uint) (end-buff));
+ if (my_b_write(file, (uchar*) buff, (uint) (end-buff)))
+ goto err;
if ((!print_event_info->thread_id_printed ||
((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
thread_id != print_event_info->thread_id)))
{
// If --short-form, print deterministic value instead of pseudo_thread_id.
- my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
- short_form ? 999999999 : (ulong)thread_id,
- print_event_info->delimiter);
+ if (my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
+ short_form ? 999999999 : (ulong)thread_id,
+ print_event_info->delimiter))
+ goto err;
print_event_info->thread_id= thread_id;
print_event_info->thread_id_printed= 1;
}
@@ -4821,18 +5132,20 @@ void Query_log_event::print_query_header(IO_CACHE* file,
if (unlikely(tmp)) /* some bits have changed */
{
bool need_comma= 0;
- my_b_write_string(file, "SET ");
- print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
- "@@session.foreign_key_checks", &need_comma);
- print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
- "@@session.sql_auto_is_null", &need_comma);
- print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
- "@@session.unique_checks", &need_comma);
- print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
- "@@session.autocommit", &need_comma);
- print_set_option(file, tmp, OPTION_NO_CHECK_CONSTRAINT_CHECKS, ~flags2,
- "@@session.check_constraint_checks", &need_comma);
- my_b_printf(file,"%s\n", print_event_info->delimiter);
+ if (my_b_write_string(file, "SET ") ||
+ print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
+ "@@session.foreign_key_checks", &need_comma)||
+ print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
+ "@@session.sql_auto_is_null", &need_comma) ||
+ print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
+ "@@session.unique_checks", &need_comma) ||
+ print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
+ "@@session.autocommit", &need_comma) ||
+ print_set_option(file, tmp, OPTION_NO_CHECK_CONSTRAINT_CHECKS,
+ ~flags2,
+ "@@session.check_constraint_checks", &need_comma) ||
+ my_b_printf(file,"%s\n", print_event_info->delimiter))
+ goto err;
print_event_info->flags2= flags2;
}
}
@@ -4855,17 +5168,19 @@ void Query_log_event::print_query_header(IO_CACHE* file,
!print_event_info->sql_mode_inited)))
{
char llbuff[22];
- my_b_printf(file,"SET @@session.sql_mode=%s%s\n",
- ullstr(sql_mode, llbuff), print_event_info->delimiter);
+ if (my_b_printf(file,"SET @@session.sql_mode=%s%s\n",
+ ullstr(sql_mode, llbuff), print_event_info->delimiter))
+ goto err;
print_event_info->sql_mode= sql_mode;
print_event_info->sql_mode_inited= 1;
}
if (print_event_info->auto_increment_increment != auto_increment_increment ||
print_event_info->auto_increment_offset != auto_increment_offset)
{
- my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
- auto_increment_increment,auto_increment_offset,
- print_event_info->delimiter);
+ if (my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
+ auto_increment_increment,auto_increment_offset,
+ print_event_info->delimiter))
+ goto err;
print_event_info->auto_increment_increment= auto_increment_increment;
print_event_info->auto_increment_offset= auto_increment_offset;
}
@@ -4880,18 +5195,20 @@ void Query_log_event::print_query_header(IO_CACHE* file,
if (cs_info)
{
/* for mysql client */
- my_b_printf(file, "/*!\\C %s */%s\n",
- cs_info->csname, print_event_info->delimiter);
- }
- my_b_printf(file,"SET "
- "@@session.character_set_client=%d,"
- "@@session.collation_connection=%d,"
- "@@session.collation_server=%d"
- "%s\n",
- uint2korr(charset),
- uint2korr(charset+2),
- uint2korr(charset+4),
- print_event_info->delimiter);
+ if (my_b_printf(file, "/*!\\C %s */%s\n",
+ cs_info->csname, print_event_info->delimiter))
+ goto err;
+ }
+ if (my_b_printf(file,"SET "
+ "@@session.character_set_client=%d,"
+ "@@session.collation_connection=%d,"
+ "@@session.collation_server=%d"
+ "%s\n",
+ uint2korr(charset),
+ uint2korr(charset+2),
+ uint2korr(charset+4),
+ print_event_info->delimiter))
+ goto err;
memcpy(print_event_info->charset, charset, 6);
print_event_info->charset_inited= 1;
}
@@ -4900,31 +5217,40 @@ void Query_log_event::print_query_header(IO_CACHE* file,
if (memcmp(print_event_info->time_zone_str,
time_zone_str, time_zone_len+1))
{
- my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
- time_zone_str, print_event_info->delimiter);
+ if (my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
+ time_zone_str, print_event_info->delimiter))
+ goto err;
memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
}
}
if (lc_time_names_number != print_event_info->lc_time_names_number)
{
- my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
- lc_time_names_number, print_event_info->delimiter);
+ if (my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
+ lc_time_names_number, print_event_info->delimiter))
+ goto err;
print_event_info->lc_time_names_number= lc_time_names_number;
}
if (charset_database_number != print_event_info->charset_database_number)
{
if (charset_database_number)
- my_b_printf(file, "SET @@session.collation_database=%d%s\n",
- charset_database_number, print_event_info->delimiter);
- else
- my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
- print_event_info->delimiter);
+ {
+ if (my_b_printf(file, "SET @@session.collation_database=%d%s\n",
+ charset_database_number, print_event_info->delimiter))
+ goto err;
+ }
+ else if (my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
+ print_event_info->delimiter))
+ goto err;
print_event_info->charset_database_number= charset_database_number;
}
+ return 0;
+
+err:
+ return 1;
}
-void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+bool Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
Write_on_release_cache cache(&print_event_info->head_cache, file, 0, this);
@@ -4934,25 +5260,32 @@ void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
*/
DBUG_EXECUTE_IF ("simulate_file_write_error",
{(&cache)->write_pos= (&cache)->write_end- 500;});
- print_query_header(&cache, print_event_info);
+ if (print_query_header(&cache, print_event_info))
+ goto err;
if (!is_flashback)
{
- my_b_write(&cache, (uchar*) query, q_len);
- my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
+ if (my_b_write(&cache, (uchar*) query, q_len) ||
+ my_b_printf(&cache, "\n%s\n", print_event_info->delimiter))
+ goto err;
}
else // is_flashback == 1
{
if (strcmp("BEGIN", query) == 0)
{
- my_b_write(&cache, (uchar*) "COMMIT", 6);
- my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
+ if (my_b_write(&cache, (uchar*) "COMMIT", 6) ||
+ my_b_printf(&cache, "\n%s\n", print_event_info->delimiter))
+ goto err;
}
else if (strcmp("COMMIT", query) == 0)
{
- my_b_write(&cache, (uchar*) "BEGIN", 5);
- my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
+ if (my_b_write(&cache, (uchar*) "BEGIN", 5) ||
+ my_b_printf(&cache, "\n%s\n", print_event_info->delimiter))
+ goto err;
}
}
+ return cache.flush_data();
+err:
+ return 1;
}
#endif /* MYSQL_CLIENT */
@@ -4988,8 +5321,12 @@ bool test_if_equal_repl_errors(int expected_error, int actual_error)
switch (expected_error) {
case ER_DUP_ENTRY:
case ER_DUP_ENTRY_WITH_KEY_NAME:
+ case ER_DUP_KEY:
case ER_AUTOINC_READ_FAILED:
- return (actual_error == ER_AUTOINC_READ_FAILED ||
+ return (actual_error == ER_DUP_ENTRY ||
+ actual_error == ER_DUP_ENTRY_WITH_KEY_NAME ||
+ actual_error == ER_DUP_KEY ||
+ actual_error == ER_AUTOINC_READ_FAILED ||
actual_error == HA_ERR_AUTOINC_ERANGE);
case ER_UNKNOWN_TABLE:
return actual_error == ER_IT_IS_A_VIEW;
@@ -5020,7 +5357,7 @@ bool test_if_equal_repl_errors(int expected_error, int actual_error)
int Query_log_event::do_apply_event(rpl_group_info *rgi,
const char *query_arg, uint32 q_len_arg)
{
- LEX_STRING new_db;
+ LEX_CSTRING new_db;
int expected_error,actual_error= 0;
Schema_specification_st db_options;
uint64 sub_id= 0;
@@ -5041,12 +5378,12 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
new_db.length= db_len;
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
- thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
+ thd->set_db(&new_db); /* allocates a copy of 'db' */
/*
Setting the character set and collation of the current database thd->db.
*/
- load_db_opt_by_name(thd, thd->db, &db_options);
+ load_db_opt_by_name(thd, thd->db.str, &db_options);
if (db_options.default_table_charset)
thd->db_charset= db_options.default_table_charset;
thd->variables.auto_increment_increment= auto_increment_increment;
@@ -5070,7 +5407,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
::do_apply_event(), then the companion SET also have so
we don't need to reset_one_shot_variables().
*/
- if (is_trans_keyword() || rpl_filter->db_ok(thd->db))
+ if (is_trans_keyword() || rpl_filter->db_ok(thd->db.str))
{
thd->set_time(when, when_sec_part);
thd->set_query_and_id((char*)query_arg, q_len_arg,
@@ -5105,7 +5442,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
if (sql_mode_inited)
thd->variables.sql_mode=
(sql_mode_t) ((thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) |
- (sql_mode & ~(ulong) MODE_NO_DIR_IN_CREATE));
+ (sql_mode & ~(sql_mode_t) MODE_NO_DIR_IN_CREATE));
if (charset_inited)
{
rpl_sql_thread_info *sql_info= thd->system_thread_info.rpl_sql_info;
@@ -5238,7 +5575,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
DBUG_ASSERT(thd->m_statement_psi == NULL);
thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
stmt_info_rpl.m_key,
- thd->db, thd->db_length,
+ thd->db.str, thd->db.length,
thd->charset());
THD_STAGE_INFO(thd, stage_init);
MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query(), thd->query_length());
@@ -5372,7 +5709,7 @@ compare_errors:
"Error '%s' on query. Default database: '%s'. Query: '%s'",
(actual_error ? thd->get_stmt_da()->message() :
"unexpected success or fatal error"),
- print_slave_db_safe(thd->db), query_arg);
+ thd->get_db(), query_arg);
thd->is_slave_error= 1;
}
@@ -5429,7 +5766,7 @@ end:
TABLE uses the db.table syntax.
*/
thd->catalog= 0;
- thd->set_db(NULL, 0); /* will free the current database */
+ thd->set_db(&null_clex_str); /* will free the current database */
thd->reset_query();
DBUG_PRINT("info", ("end: query= 0"));
@@ -5563,7 +5900,7 @@ void Start_log_event_v3::pack_info(Protocol *protocol)
*/
#ifdef MYSQL_CLIENT
-void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+bool Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
DBUG_ENTER("Start_log_event_v3::print");
@@ -5572,16 +5909,21 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
if (!print_event_info->short_form)
{
- print_header(&cache, print_event_info, FALSE);
- my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
- binlog_version, server_version);
- print_timestamp(&cache);
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
+ binlog_version, server_version) ||
+ print_timestamp(&cache))
+ goto err;
if (created)
- my_b_printf(&cache," at startup");
- my_b_printf(&cache, "\n");
+ if (my_b_printf(&cache," at startup"))
+ goto err;
+ if (my_b_printf(&cache, "\n"))
+ goto err;
if (flags & LOG_EVENT_BINLOG_IN_USE_F)
- my_b_printf(&cache, "# Warning: this binlog is either in use or was not "
- "closed properly.\n");
+ if (my_b_printf(&cache,
+ "# Warning: this binlog is either in use or was not "
+ "closed properly.\n"))
+ goto err;
}
if (!is_artificial_event() && created)
{
@@ -5592,9 +5934,12 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
and rollback unfinished transaction.
Probably this can be done with RESET CONNECTION (syntax to be defined).
*/
- my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
+ if (my_b_printf(&cache,"RESET CONNECTION%s\n",
+ print_event_info->delimiter))
+ goto err;
#else
- my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
+ if (my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter))
+ goto err;
#endif
}
if (temp_buf &&
@@ -5602,11 +5947,15 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
!print_event_info->short_form)
{
if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
- my_b_printf(&cache, "BINLOG '\n");
- print_base64(&cache, print_event_info, FALSE);
+ if (my_b_printf(&cache, "BINLOG '\n"))
+ goto err;
+ if (print_base64(&cache, print_event_info, FALSE))
+ goto err;
print_event_info->printed_fd_event= TRUE;
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(cache.flush_data());
+err:
+ DBUG_RETURN(1);
}
#endif /* MYSQL_CLIENT */
@@ -6289,7 +6638,7 @@ int Start_encryption_log_event::do_update_pos(rpl_group_info *rgi)
#endif
#ifndef MYSQL_SERVER
-void Start_encryption_log_event::print(FILE* file,
+bool Start_encryption_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info)
{
Write_on_release_cache cache(&print_event_info->head_cache, file);
@@ -6301,7 +6650,9 @@ void Start_encryption_log_event::print(FILE* file,
buf.append(STRING_WITH_LEN(", nonce: "));
buf.append_hex(nonce, BINLOG_NONCE_LENGTH);
buf.append(STRING_WITH_LEN("\n# The rest of the binlog is encrypted!\n"));
- my_b_write(&cache, (uchar*)buf.ptr(), buf.length());
+ if (my_b_write(&cache, (uchar*)buf.ptr(), buf.length()))
+ return 1;
+ return (cache.flush_data());
}
#endif
/**************************************************************************
@@ -6326,7 +6677,7 @@ void Start_encryption_log_event::print(FILE* file,
*/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Load_log_event::print_query(THD *thd, bool need_db, const char *cs,
+bool Load_log_event::print_query(THD *thd, bool need_db, const char *cs,
String *buf, my_off_t *fn_start,
my_off_t *fn_end, const char *qualify_db)
{
@@ -6422,6 +6773,7 @@ void Load_log_event::print_query(THD *thd, bool need_db, const char *cs,
}
buf->append(STRING_WITH_LEN(")"));
}
+ return 0;
}
@@ -6665,26 +7017,27 @@ err:
*/
#ifdef MYSQL_CLIENT
-void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+bool Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
- print(file, print_event_info, 0);
+ return print(file, print_event_info, 0);
}
-void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
+bool Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
bool commented)
{
Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
-
+ bool different_db= 1;
DBUG_ENTER("Load_log_event::print");
+
if (!print_event_info->short_form)
{
- print_header(&cache, print_event_info, FALSE);
- my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
- thread_id, exec_time);
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
+ thread_id, exec_time))
+ goto err;
}
- bool different_db= 1;
if (db)
{
/*
@@ -6697,69 +7050,86 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
!commented)
memcpy(print_event_info->db, db, db_len + 1);
}
-
+
if (db && db[0] && different_db)
- my_b_printf(&cache, "%suse %`s%s\n",
- commented ? "# " : "",
- db, print_event_info->delimiter);
+ if (my_b_printf(&cache, "%suse %`s%s\n",
+ commented ? "# " : "",
+ db, print_event_info->delimiter))
+ goto err;
if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
- my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
- commented ? "# " : "", (ulong)thread_id,
- print_event_info->delimiter);
- my_b_printf(&cache, "%sLOAD DATA ",
- commented ? "# " : "");
+ if (my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
+ commented ? "# " : "", (ulong)thread_id,
+ print_event_info->delimiter))
+ goto err;
+ if (my_b_printf(&cache, "%sLOAD DATA ",
+ commented ? "# " : ""))
+ goto err;
if (check_fname_outside_temp_buf())
- my_b_write_string(&cache, "LOCAL ");
- my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
+ if (my_b_write_string(&cache, "LOCAL "))
+ goto err;
+ if (my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname))
+ goto err;
if (sql_ex.opt_flags & REPLACE_FLAG)
- my_b_write_string(&cache, "REPLACE ");
+ {
+ if (my_b_write_string(&cache, "REPLACE "))
+ goto err;
+ }
else if (sql_ex.opt_flags & IGNORE_FLAG)
- my_b_write_string(&cache, "IGNORE ");
-
- my_b_printf(&cache, "INTO TABLE `%s`", table_name);
- my_b_write_string(&cache, " FIELDS TERMINATED BY ");
- pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
+ if (my_b_write_string(&cache, "IGNORE "))
+ goto err;
- if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
- my_b_write_string(&cache, " OPTIONALLY ");
- my_b_write_string(&cache, " ENCLOSED BY ");
- pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
-
- my_b_write_string(&cache, " ESCAPED BY ");
- pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
-
- my_b_write_string(&cache, " LINES TERMINATED BY ");
- pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
+ if (my_b_printf(&cache, "INTO TABLE `%s`", table_name) ||
+ my_b_write_string(&cache, " FIELDS TERMINATED BY ") ||
+ pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len))
+ goto err;
+ if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
+ if (my_b_write_string(&cache, " OPTIONALLY "))
+ goto err;
+ if (my_b_write_string(&cache, " ENCLOSED BY ") ||
+ pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len) ||
+ my_b_write_string(&cache, " ESCAPED BY ") ||
+ pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len) ||
+ my_b_write_string(&cache, " LINES TERMINATED BY ") ||
+ pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len))
+ goto err;
if (sql_ex.line_start)
{
- my_b_write_string(&cache," STARTING BY ");
- pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
+ if (my_b_write_string(&cache," STARTING BY ") ||
+ pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len))
+ goto err;
}
if ((long) skip_lines > 0)
- my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
+ if (my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines))
+ goto err;
if (num_fields)
{
uint i;
const char* field = fields;
- my_b_write_string(&cache, " (");
+ if (my_b_write_string(&cache, " ("))
+ goto err;
for (i = 0; i < num_fields; i++)
{
if (i)
- my_b_write_byte(&cache, ',');
- my_b_printf(&cache, "%`s", field);
-
+ if (my_b_write_byte(&cache, ','))
+ goto err;
+ if (my_b_printf(&cache, "%`s", field))
+ goto err;
field += field_lens[i] + 1;
}
- my_b_write_byte(&cache, ')');
+ if (my_b_write_byte(&cache, ')'))
+ goto err;
}
- my_b_printf(&cache, "%s\n", print_event_info->delimiter);
- DBUG_VOID_RETURN;
+ if (my_b_printf(&cache, "%s\n", print_event_info->delimiter))
+ goto err;
+ DBUG_RETURN(cache.flush_data());
+err:
+ DBUG_RETURN(1);
}
#endif /* MYSQL_CLIENT */
@@ -6827,14 +7197,14 @@ void Load_log_event::set_fields(const char* affected_db,
int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
bool use_rli_only_for_errors)
{
- LEX_STRING new_db;
+ LEX_CSTRING new_db;
Relay_log_info const *rli= rgi->rli;
Rpl_filter *rpl_filter= rli->mi->rpl_filter;
DBUG_ENTER("Load_log_event::do_apply_event");
new_db.length= db_len;
- new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
- thd->set_db(new_db.str, new_db.length);
+ new_db.str= rpl_filter->get_rewrite_db(db, &new_db.length);
+ thd->set_db(&new_db);
DBUG_ASSERT(thd->query() == 0);
thd->clear_error(1);
@@ -6871,21 +7241,20 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
::do_apply_event(), then the companion SET also have so
we don't need to reset_one_shot_variables().
*/
- if (rpl_filter->db_ok(thd->db))
+ if (rpl_filter->db_ok(thd->db.str))
{
thd->set_time(when, when_sec_part);
thd->set_query_id(next_query_id());
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
TABLE_LIST tables;
- tables.init_one_table(thd->strmake(thd->db, thd->db_length),
- thd->db_length,
- table_name, strlen(table_name),
- table_name, TL_WRITE);
+ LEX_CSTRING db_name= { thd->strmake(thd->db.str, thd->db.length), thd->db.length };
+ LEX_CSTRING tbl_name= { table_name, strlen(table_name) };
+ tables.init_one_table(&db_name, &tbl_name, 0, TL_WRITE);
tables.updating= 1;
// the table will be opened in mysql_load
- if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
+ if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db.str, &tables))
{
// TODO: this is a bug - this needs to be moved to the I/O thread
if (net)
@@ -6971,7 +7340,7 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
ex.skip_lines = skip_lines;
List<Item> field_list;
thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
- set_fields(tables.db, field_list, &thd->lex->select_lex.context);
+ set_fields(tables.db.str, field_list, &thd->lex->select_lex.context);
thd->variables.pseudo_thread_id= thread_id;
if (net)
{
@@ -6997,7 +7366,7 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
"warning(s). Default database: '%s'",
(char*) table_name, log_pos, RPL_LOG_NAME,
(ulong) thd->cuted_fields,
- print_slave_db_safe(thd->db));
+ thd->get_db());
}
if (net)
net->pkt_nr= thd->net.pkt_nr;
@@ -7016,9 +7385,9 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
error:
thd->net.vio = 0;
- const char *remember_db= thd->db;
+ const char *remember_db= thd->get_db();
thd->catalog= 0;
- thd->set_db(NULL, 0); /* will free the current database */
+ thd->set_db(&null_clex_str); /* will free the current database */
thd->reset_query();
thd->get_stmt_da()->set_overwrite_status(true);
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
@@ -7067,7 +7436,7 @@ error:
}
rli->report(ERROR_LEVEL, sql_errno, rgi->gtid_info(), "\
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
- err, (char*)table_name, print_slave_db_safe(remember_db));
+ err, (char*)table_name, remember_db);
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
DBUG_RETURN(1);
}
@@ -7080,7 +7449,7 @@ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
"Running LOAD DATA INFILE on table '%-.64s'."
" Default database: '%-.64s'",
(char*)table_name,
- print_slave_db_safe(remember_db));
+ remember_db);
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, rgi->gtid_info(),
ER_THD(thd, ER_SLAVE_FATAL_ERROR), buf);
@@ -7118,19 +7487,25 @@ void Rotate_log_event::pack_info(Protocol *protocol)
*/
#ifdef MYSQL_CLIENT
-void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+bool Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
+ if (print_event_info->short_form)
+ return 0;
+
char buf[22];
Write_on_release_cache cache(&print_event_info->head_cache, file,
Write_on_release_cache::FLUSH_F);
-
- if (print_event_info->short_form)
- return;
- print_header(&cache, print_event_info, FALSE);
- my_b_write_string(&cache, "\tRotate to ");
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_write_string(&cache, "\tRotate to "))
+ goto err;
if (new_log_ident)
- my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
- my_b_printf(&cache, " pos: %s\n", llstr(pos, buf));
+ if (my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len))
+ goto err;
+ if (my_b_printf(&cache, " pos: %s\n", llstr(pos, buf)))
+ goto err;
+ return cache.flush_data();
+err:
+ return 1;
}
#endif /* MYSQL_CLIENT */
@@ -7335,18 +7710,21 @@ Binlog_checkpoint_log_event::do_shall_skip(rpl_group_info *rgi)
#ifdef MYSQL_CLIENT
-void Binlog_checkpoint_log_event::print(FILE *file,
+bool Binlog_checkpoint_log_event::print(FILE *file,
PRINT_EVENT_INFO *print_event_info)
{
+ if (print_event_info->short_form)
+ return 0;
+
Write_on_release_cache cache(&print_event_info->head_cache, file,
Write_on_release_cache::FLUSH_F);
- if (print_event_info->short_form)
- return;
- print_header(&cache, print_event_info, FALSE);
- my_b_write_string(&cache, "\tBinlog checkpoint ");
- my_b_write(&cache, (uchar*)binlog_file_name, binlog_file_len);
- my_b_write_byte(&cache, '\n');
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_write_string(&cache, "\tBinlog checkpoint ") ||
+ my_b_write(&cache, (uchar*)binlog_file_name, binlog_file_len) ||
+ my_b_write_byte(&cache, '\n'))
+ return 1;
+ return cache.flush_data();
}
#endif /* MYSQL_CLIENT */
@@ -7664,7 +8042,7 @@ Gtid_log_event::do_shall_skip(rpl_group_info *rgi)
#else /* !MYSQL_SERVER */
-void
+bool
Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
{
Write_on_release_cache cache(&print_event_info->head_cache, file,
@@ -7676,26 +8054,34 @@ Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
{
print_header(&cache, print_event_info, FALSE);
longlong10_to_str(seq_no, buf, 10);
- my_b_printf(&cache, "\tGTID %u-%u-%s", domain_id, server_id, buf);
+ if (my_b_printf(&cache, "\tGTID %u-%u-%s", domain_id, server_id, buf))
+ goto err;
if (flags2 & FL_GROUP_COMMIT_ID)
{
longlong10_to_str(commit_id, buf2, 10);
- my_b_printf(&cache, " cid=%s", buf2);
+ if (my_b_printf(&cache, " cid=%s", buf2))
+ goto err;
}
if (flags2 & FL_DDL)
- my_b_write_string(&cache, " ddl");
+ if (my_b_write_string(&cache, " ddl"))
+ goto err;
if (flags2 & FL_TRANSACTIONAL)
- my_b_write_string(&cache, " trans");
+ if (my_b_write_string(&cache, " trans"))
+ goto err;
if (flags2 & FL_WAITED)
- my_b_write_string(&cache, " waited");
- my_b_printf(&cache, "\n");
+ if (my_b_write_string(&cache, " waited"))
+ goto err;
+ if (my_b_printf(&cache, "\n"))
+ goto err;
if (!print_event_info->allow_parallel_printed ||
print_event_info->allow_parallel != !!(flags2 & FL_ALLOW_PARALLEL))
{
- my_b_printf(&cache,
+ if (my_b_printf(&cache,
"/*!100101 SET @@session.skip_parallel_replication=%u*/%s\n",
- !(flags2 & FL_ALLOW_PARALLEL), print_event_info->delimiter);
+ !(flags2 & FL_ALLOW_PARALLEL),
+ print_event_info->delimiter))
+ goto err;
print_event_info->allow_parallel= !!(flags2 & FL_ALLOW_PARALLEL);
print_event_info->allow_parallel_printed= true;
}
@@ -7703,8 +8089,10 @@ Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
if (!print_event_info->domain_id_printed ||
print_event_info->domain_id != domain_id)
{
- my_b_printf(&cache, "/*!100001 SET @@session.gtid_domain_id=%u*/%s\n",
- domain_id, print_event_info->delimiter);
+ if (my_b_printf(&cache,
+ "/*!100001 SET @@session.gtid_domain_id=%u*/%s\n",
+ domain_id, print_event_info->delimiter))
+ goto err;
print_event_info->domain_id= domain_id;
print_event_info->domain_id_printed= true;
}
@@ -7712,18 +8100,25 @@ Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
if (!print_event_info->server_id_printed ||
print_event_info->server_id != server_id)
{
- my_b_printf(&cache, "/*!100001 SET @@session.server_id=%u*/%s\n",
- server_id, print_event_info->delimiter);
+ if (my_b_printf(&cache, "/*!100001 SET @@session.server_id=%u*/%s\n",
+ server_id, print_event_info->delimiter))
+ goto err;
print_event_info->server_id= server_id;
print_event_info->server_id_printed= true;
}
if (!is_flashback)
- my_b_printf(&cache, "/*!100001 SET @@session.gtid_seq_no=%s*/%s\n",
- buf, print_event_info->delimiter);
+ if (my_b_printf(&cache, "/*!100001 SET @@session.gtid_seq_no=%s*/%s\n",
+ buf, print_event_info->delimiter))
+ goto err;
}
if (!(flags2 & FL_STANDALONE))
- my_b_printf(&cache, is_flashback ? "COMMIT\n%s\n" : "BEGIN\n%s\n", print_event_info->delimiter);
+ if (my_b_printf(&cache, is_flashback ? "COMMIT\n%s\n" : "BEGIN\n%s\n", print_event_info->delimiter))
+ goto err;
+
+ return cache.flush_data();
+err:
+ return 1;
}
#endif /* MYSQL_SERVER */
@@ -7961,28 +8356,37 @@ Gtid_list_log_event::pack_info(Protocol *protocol)
#else /* !MYSQL_SERVER */
-void
+bool
Gtid_list_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
{
- if (!print_event_info->short_form)
- {
- Write_on_release_cache cache(&print_event_info->head_cache, file,
- Write_on_release_cache::FLUSH_F);
- char buf[21];
- uint32 i;
+ if (print_event_info->short_form)
+ return 0;
- print_header(&cache, print_event_info, FALSE);
- my_b_printf(&cache, "\tGtid list [");
- for (i= 0; i < count; ++i)
- {
- longlong10_to_str(list[i].seq_no, buf, 10);
- my_b_printf(&cache, "%u-%u-%s", list[i].domain_id,
- list[i].server_id, buf);
- if (i < count-1)
- my_b_printf(&cache, ",\n# ");
- }
- my_b_printf(&cache, "]\n");
+ Write_on_release_cache cache(&print_event_info->head_cache, file,
+ Write_on_release_cache::FLUSH_F);
+ char buf[21];
+ uint32 i;
+
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_printf(&cache, "\tGtid list ["))
+ goto err;
+
+ for (i= 0; i < count; ++i)
+ {
+ longlong10_to_str(list[i].seq_no, buf, 10);
+ if (my_b_printf(&cache, "%u-%u-%s", list[i].domain_id,
+ list[i].server_id, buf))
+ goto err;
+ if (i < count-1)
+ if (my_b_printf(&cache, ",\n# "))
+ goto err;
}
+ if (my_b_printf(&cache, "]\n"))
+ goto err;
+
+ return cache.flush_data();
+err:
+ return 1;
}
#endif /* MYSQL_SERVER */
@@ -7993,7 +8397,7 @@ Gtid_list_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
fully contruct the event object.
*/
bool
-Gtid_list_log_event::peek(const char *event_start, uint32 event_len,
+Gtid_list_log_event::peek(const char *event_start, size_t event_len,
enum enum_binlog_checksum_alg checksum_alg,
rpl_gtid **out_gtid_list, uint32 *out_list_len,
const Format_description_log_event *fdev)
@@ -8114,7 +8518,7 @@ bool Intvar_log_event::write()
*/
#ifdef MYSQL_CLIENT
-void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+bool Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
char llbuff[22];
const char *UNINIT_VAR(msg);
@@ -8123,11 +8527,13 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
if (!print_event_info->short_form)
{
- print_header(&cache, print_event_info, FALSE);
- my_b_write_string(&cache, "\tIntvar\n");
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_write_string(&cache, "\tIntvar\n"))
+ goto err;
}
- my_b_printf(&cache, "SET ");
+ if (my_b_printf(&cache, "SET "))
+ goto err;
switch (type) {
case LAST_INSERT_ID_EVENT:
msg="LAST_INSERT_ID";
@@ -8140,8 +8546,13 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
msg="INVALID_INT";
break;
}
- my_b_printf(&cache, "%s=%s%s\n",
- msg, llstr(val,llbuff), print_event_info->delimiter);
+ if (my_b_printf(&cache, "%s=%s%s\n",
+ msg, llstr(val,llbuff), print_event_info->delimiter))
+ goto err;
+
+ return cache.flush_data();
+err:
+ return 1;
}
#endif
@@ -8240,7 +8651,7 @@ bool Rand_log_event::write()
#ifdef MYSQL_CLIENT
-void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+bool Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
Write_on_release_cache cache(&print_event_info->head_cache, file,
Write_on_release_cache::FLUSH_F);
@@ -8248,12 +8659,18 @@ void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
char llbuff[22],llbuff2[22];
if (!print_event_info->short_form)
{
- print_header(&cache, print_event_info, FALSE);
- my_b_write_string(&cache, "\tRand\n");
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_write_string(&cache, "\tRand\n"))
+ goto err;
}
- my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
- llstr(seed1, llbuff),llstr(seed2, llbuff2),
- print_event_info->delimiter);
+ if (my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
+ llstr(seed1, llbuff),llstr(seed2, llbuff2),
+ print_event_info->delimiter))
+ goto err;
+
+ return cache.flush_data();
+err:
+ return 1;
}
#endif /* MYSQL_CLIENT */
@@ -8365,7 +8782,7 @@ bool Xid_log_event::write()
#ifdef MYSQL_CLIENT
-void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+bool Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
Write_on_release_cache cache(&print_event_info->head_cache, file,
Write_on_release_cache::FLUSH_F, this);
@@ -8375,10 +8792,17 @@ void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
char buf[64];
longlong10_to_str(xid, buf, 10);
- print_header(&cache, print_event_info, FALSE);
- my_b_printf(&cache, "\tXid = %s\n", buf);
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_printf(&cache, "\tXid = %s\n", buf))
+ goto err;
}
- my_b_printf(&cache, is_flashback ? "BEGIN%s\n" : "COMMIT%s\n", print_event_info->delimiter);
+ if (my_b_printf(&cache, is_flashback ? "BEGIN%s\n" : "COMMIT%s\n",
+ print_event_info->delimiter))
+ goto err;
+
+ return cache.flush_data();
+err:
+ return 1;
}
#endif /* MYSQL_CLIENT */
@@ -8704,7 +9128,7 @@ bool User_var_log_event::write()
uchar buf2[MY_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
uint unsigned_len= 0;
uint buf1_length;
- ulong event_length;
+ size_t event_length;
int4store(buf, name_len);
@@ -8767,23 +9191,26 @@ bool User_var_log_event::write()
*/
#ifdef MYSQL_CLIENT
-void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+bool User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
Write_on_release_cache cache(&print_event_info->head_cache, file,
Write_on_release_cache::FLUSH_F);
if (!print_event_info->short_form)
{
- print_header(&cache, print_event_info, FALSE);
- my_b_write_string(&cache, "\tUser_var\n");
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_write_string(&cache, "\tUser_var\n"))
+ goto err;
}
- my_b_write_string(&cache, "SET @");
- my_b_write_backtick_quote(&cache, name, name_len);
+ if (my_b_write_string(&cache, "SET @") ||
+ my_b_write_backtick_quote(&cache, name, name_len))
+ goto err;
if (is_null)
{
- my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
+ if (my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter))
+ goto err;
}
else
{
@@ -8793,13 +9220,17 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
char real_buf[FMT_G_BUFSIZE(14)];
float8get(real_val, val);
sprintf(real_buf, "%.14g", real_val);
- my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
+ if (my_b_printf(&cache, ":=%s%s\n", real_buf,
+ print_event_info->delimiter))
+ goto err;
break;
case INT_RESULT:
char int_buf[22];
longlong10_to_str(uint8korr(val), int_buf,
((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10));
- my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
+ if (my_b_printf(&cache, ":=%s%s\n", int_buf,
+ print_event_info->delimiter))
+ goto err;
break;
case DECIMAL_RESULT:
{
@@ -8815,7 +9246,9 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
bin2decimal((uchar*) val+2, &dec, precision, scale);
decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
str_buf[str_len]= 0;
- my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
+ if (my_b_printf(&cache, ":=%s%s\n", str_buf,
+ print_event_info->delimiter))
+ goto err;
break;
}
case STRING_RESULT:
@@ -8836,11 +9269,12 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
*/
char *hex_str;
CHARSET_INFO *cs;
+ bool error;
// 2 hex digits / byte
hex_str= (char *) my_malloc(2 * val_len + 1 + 3, MYF(MY_WME));
if (!hex_str)
- return;
+ goto err;
str_to_hex(hex_str, val, val_len);
/*
For proper behaviour when mysqlbinlog|mysql, we need to explicitly
@@ -8849,24 +9283,31 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
character set. But there's not much to do about this and it's unlikely.
*/
if (!(cs= get_charset(charset_number, MYF(0))))
- /*
+ { /*
Generate an unusable command (=> syntax error) is probably the best
thing we can do here.
*/
- my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
+ error= my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
+ }
else
- my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
- cs->csname, hex_str, cs->name,
- print_event_info->delimiter);
+ error= my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
+ cs->csname, hex_str, cs->name,
+ print_event_info->delimiter);
my_free(hex_str);
- }
+ if (error)
+ goto err;
break;
+ }
case ROW_RESULT:
default:
DBUG_ASSERT(0);
- return;
+ break;
}
}
+
+ return cache.flush_data();
+err:
+ return 1;
}
#endif
@@ -8930,7 +9371,7 @@ int User_var_log_event::do_apply_event(rpl_group_info *rgi)
break;
}
case STRING_RESULT:
- it= new (thd->mem_root) Item_string(thd, val, val_len, charset);
+ it= new (thd->mem_root) Item_string(thd, val, (uint)val_len, charset);
break;
case ROW_RESULT:
default:
@@ -8989,19 +9430,25 @@ User_var_log_event::do_shall_skip(rpl_group_info *rgi)
#ifdef HAVE_REPLICATION
#ifdef MYSQL_CLIENT
-void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
+bool Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
{
+ if (print_event_info->short_form)
+ return 0;
+
Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
- if (print_event_info->short_form)
- return;
if (what != ENCRYPTED)
{
- print_header(&cache, print_event_info, FALSE);
- my_b_printf(&cache, "\n# Unknown event\n");
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_printf(&cache, "\n# Unknown event\n"))
+ goto err;
}
- else
- my_b_printf(&cache, "# Encrypted event\n");
+ else if (my_b_printf(&cache, "# Encrypted event\n"))
+ goto err;
+
+ return cache.flush_data();
+err:
+ return 1;
}
#endif
@@ -9014,16 +9461,18 @@ void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info
*/
#ifdef MYSQL_CLIENT
-void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+bool Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
+ if (print_event_info->short_form)
+ return 0;
+
Write_on_release_cache cache(&print_event_info->head_cache, file,
Write_on_release_cache::FLUSH_F, this);
- if (print_event_info->short_form)
- return;
-
- print_header(&cache, print_event_info, FALSE);
- my_b_write_string(&cache, "\tStop\n");
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_write_string(&cache, "\tStop\n"))
+ return 1;
+ return cache.flush_data();
}
#endif /* MYSQL_CLIENT */
@@ -9205,22 +9654,25 @@ Create_file_log_event::Create_file_log_event(const char* buf, uint len,
*/
#ifdef MYSQL_CLIENT
-void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
+bool Create_file_log_event::print(FILE* file,
+ PRINT_EVENT_INFO* print_event_info,
bool enable_local)
{
- Write_on_release_cache cache(&print_event_info->head_cache, file);
-
if (print_event_info->short_form)
{
if (enable_local && check_fname_outside_temp_buf())
- Load_log_event::print(file, print_event_info);
- return;
+ return Load_log_event::print(file, print_event_info);
+ return 0;
}
+ Write_on_release_cache cache(&print_event_info->head_cache, file);
+
if (enable_local)
{
- Load_log_event::print(file, print_event_info,
- !check_fname_outside_temp_buf());
+ if (Load_log_event::print(file, print_event_info,
+ !check_fname_outside_temp_buf()))
+ goto err;
+
/**
reduce the size of io cache so that the write function is called
for every call to my_b_printf().
@@ -9232,16 +9684,24 @@ void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info
That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
SHOW BINLOG EVENTS we don't.
*/
- my_b_write_byte(&cache, '#');
+ if (my_b_write_byte(&cache, '#'))
+ goto err;
}
- my_b_printf(&cache, " file_id: %d block_len: %d\n", file_id, block_len);
+ if (my_b_printf(&cache, " file_id: %d block_len: %d\n", file_id, block_len))
+ goto err;
+
+ return cache.flush_data();
+err:
+ return 1;
+
}
-void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+bool Create_file_log_event::print(FILE* file,
+ PRINT_EVENT_INFO* print_event_info)
{
- print(file, print_event_info, 0);
+ return print(file, print_event_info, 0);
}
#endif /* MYSQL_CLIENT */
@@ -9307,7 +9767,7 @@ int Create_file_log_event::do_apply_event(rpl_group_info *rgi)
fname_buf);
goto err;
}
-
+
// a trick to avoid allocating another buffer
fname= fname_buf;
fname_len= (uint) (strmov(ext, ".data") - fname);
@@ -9322,7 +9782,7 @@ int Create_file_log_event::do_apply_event(rpl_group_info *rgi)
}
end_io_cache(&file);
mysql_file_close(fd, MYF(0));
-
+
// fname_buf now already has .data, not .info, because we did our trick
/* old copy may exist already */
mysql_file_delete(key_file_log_event_data, fname_buf, MYF(0));
@@ -9420,16 +9880,22 @@ bool Append_block_log_event::write()
*/
#ifdef MYSQL_CLIENT
-void Append_block_log_event::print(FILE* file,
+bool Append_block_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info)
{
+ if (print_event_info->short_form)
+ return 0;
+
Write_on_release_cache cache(&print_event_info->head_cache, file);
- if (print_event_info->short_form)
- return;
- print_header(&cache, print_event_info, FALSE);
- my_b_printf(&cache, "\n#%s: file_id: %d block_len: %d\n",
- get_type_str(), file_id, block_len);
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_printf(&cache, "\n#%s: file_id: %d block_len: %d\n",
+ get_type_str(), file_id, block_len))
+ goto err;
+
+ return cache.flush_data();
+err:
+ return 1;
}
#endif /* MYSQL_CLIENT */
@@ -9579,15 +10045,19 @@ bool Delete_file_log_event::write()
*/
#ifdef MYSQL_CLIENT
-void Delete_file_log_event::print(FILE* file,
+bool Delete_file_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info)
{
+ if (print_event_info->short_form)
+ return 0;
+
Write_on_release_cache cache(&print_event_info->head_cache, file);
- if (print_event_info->short_form)
- return;
- print_header(&cache, print_event_info, FALSE);
- my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id))
+ return 1;
+
+ return cache.flush_data();
}
#endif /* MYSQL_CLIENT */
@@ -9679,16 +10149,20 @@ bool Execute_load_log_event::write()
*/
#ifdef MYSQL_CLIENT
-void Execute_load_log_event::print(FILE* file,
+bool Execute_load_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info)
{
+ if (print_event_info->short_form)
+ return 0;
+
Write_on_release_cache cache(&print_event_info->head_cache, file);
- if (print_event_info->short_form)
- return;
- print_header(&cache, print_event_info, FALSE);
- my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
- file_id);
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
+ file_id))
+ return 1;
+
+ return cache.flush_data();
}
#endif
@@ -9735,7 +10209,6 @@ int Execute_load_log_event::do_apply_event(rpl_group_info *rgi)
}
if (!(lev= (Load_log_event*)
Log_event::read_log_event(&file,
- (mysql_mutex_t*)0,
rli->relay_log.description_event_for_exec,
opt_slave_sql_verify_checksum)) ||
lev->get_type_code() != NEW_LOAD_EVENT)
@@ -9911,22 +10384,24 @@ Execute_load_query_log_event::write_post_header_for_derived()
#ifdef MYSQL_CLIENT
-void Execute_load_query_log_event::print(FILE* file,
+bool Execute_load_query_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info)
{
- print(file, print_event_info, 0);
+ return print(file, print_event_info, 0);
}
/**
Prints the query as LOAD DATA LOCAL and with rewritten filename.
*/
-void Execute_load_query_log_event::print(FILE* file,
+bool Execute_load_query_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info,
const char *local_fname)
{
Write_on_release_cache cache(&print_event_info->head_cache, file);
- print_query_header(&cache, print_event_info);
+ if (print_query_header(&cache, print_event_info))
+ goto err;
+
/**
reduce the size of io cache so that the write function is called
for every call to my_b_printf().
@@ -9937,24 +10412,33 @@ void Execute_load_query_log_event::print(FILE* file,
if (local_fname)
{
- my_b_write(&cache, (uchar*) query, fn_pos_start);
- my_b_write_string(&cache, " LOCAL INFILE ");
- pretty_print_str(&cache, local_fname, strlen(local_fname));
+ if (my_b_write(&cache, (uchar*) query, fn_pos_start) ||
+ my_b_write_string(&cache, " LOCAL INFILE ") ||
+ pretty_print_str(&cache, local_fname, (int)strlen(local_fname)))
+ goto err;
if (dup_handling == LOAD_DUP_REPLACE)
- my_b_write_string(&cache, " REPLACE");
- my_b_write_string(&cache, " INTO");
- my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
- my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
+ if (my_b_write_string(&cache, " REPLACE"))
+ goto err;
+
+ if (my_b_write_string(&cache, " INTO") ||
+ my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end) ||
+ my_b_printf(&cache, "\n%s\n", print_event_info->delimiter))
+ goto err;
}
else
{
- my_b_write(&cache, (uchar*) query, q_len);
- my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
+ if (my_b_write(&cache, (uchar*) query, q_len) ||
+ my_b_printf(&cache, "\n%s\n", print_event_info->delimiter))
+ goto err;
}
if (!print_event_info->short_form)
my_b_printf(&cache, "# file_id: %d \n", file_id);
+
+ return cache.flush_data();
+err:
+ return 1;
}
#endif
@@ -10934,7 +11418,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
if (global_system_variables.log_warnings)
slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table,
get_type_str(),
- RPL_LOG_NAME, (ulong) log_pos);
+ RPL_LOG_NAME, log_pos);
thd->clear_error(1);
error= 0;
if (idempotent_error == 0)
@@ -10986,7 +11470,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
if (global_system_variables.log_warnings)
slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table,
get_type_str(),
- RPL_LOG_NAME, (ulong) log_pos);
+ RPL_LOG_NAME, log_pos);
thd->clear_error(1);
error= 0;
}
@@ -10997,7 +11481,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
{
slave_rows_error_report(ERROR_LEVEL, error, rgi, thd, table,
get_type_str(),
- RPL_LOG_NAME, (ulong) log_pos);
+ RPL_LOG_NAME, log_pos);
/*
@todo We should probably not call
reset_current_stmt_binlog_format_row() from here.
@@ -11027,7 +11511,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
thd->is_error() ? 0 : error,
rgi, thd, table,
get_type_str(),
- RPL_LOG_NAME, (ulong) log_pos);
+ RPL_LOG_NAME, log_pos);
DBUG_RETURN(error);
err:
@@ -11097,7 +11581,7 @@ static int rows_event_stmt_cleanup(rpl_group_info *rgi, THD * thd)
already. So there should be no need to rollback the transaction.
*/
DBUG_ASSERT(! thd->transaction_rollback_request);
- error|= (error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
+ error|= (int)(error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
/*
Now what if this is not a transactional engine? we still need to
@@ -11267,7 +11751,7 @@ void Rows_log_event::pack_info(Protocol *protocol)
#endif
#ifdef MYSQL_CLIENT
-void Rows_log_event::print_helper(FILE *file,
+bool Rows_log_event::print_helper(FILE *file,
PRINT_EVENT_INFO *print_event_info,
char const *const name)
{
@@ -11276,33 +11760,51 @@ void Rows_log_event::print_helper(FILE *file,
#ifdef WHEN_FLASHBACK_REVIEW_READY
IO_CACHE *const sql= &print_event_info->review_sql_cache;
#endif
+ bool const last_stmt_event= get_flags(STMT_END_F);
if (!print_event_info->short_form)
{
- bool const last_stmt_event= get_flags(STMT_END_F);
print_header(head, print_event_info, !last_stmt_event);
- my_b_printf(head, "\t%s: table id %lu%s\n",
- name, m_table_id,
- last_stmt_event ? " flags: STMT_END_F" : "");
- print_base64(body, print_event_info, !last_stmt_event);
+ if (my_b_printf(head, "\t%s: table id %lu%s\n",
+ name, m_table_id,
+ last_stmt_event ? " flags: STMT_END_F" : ""))
+ goto err;
}
+ if (!print_event_info->short_form || print_event_info->print_row_count)
+ if (print_base64(body, print_event_info, !last_stmt_event))
+ goto err;
- if (get_flags(STMT_END_F))
+ if (last_stmt_event)
{
- LEX_STRING tmp_str;
-
- copy_event_cache_to_string_and_reinit(head, &tmp_str);
- output_buf.append(&tmp_str);
- my_free(tmp_str.str);
- copy_event_cache_to_string_and_reinit(body, &tmp_str);
- output_buf.append(&tmp_str);
- my_free(tmp_str.str);
+ if (!is_flashback)
+ {
+ if (copy_event_cache_to_file_and_reinit(head, file) ||
+ copy_event_cache_to_file_and_reinit(body, file))
+ goto err;
+ }
+ else
+ {
+ LEX_STRING tmp_str;
+ if (copy_event_cache_to_string_and_reinit(head, &tmp_str))
+ return 1;
+ output_buf.append(tmp_str.str, tmp_str.length); // Not \0 terminated
+ my_free(tmp_str.str);
+ if (copy_event_cache_to_string_and_reinit(body, &tmp_str))
+ return 1;
+ output_buf.append(tmp_str.str, tmp_str.length);
+ my_free(tmp_str.str);
#ifdef WHEN_FLASHBACK_REVIEW_READY
- copy_event_cache_to_string_and_reinit(sql, &tmp_str);
- output_buf.append(&tmp_str);
- my_free(tmp_str.str);
+ if (copy_event_cache_to_string_and_reinit(sql, &tmp_str))
+ return 1;
+ output_buf.append(tmp_str.str, tmp_str.length);
+ my_free(tmp_str.str);
#endif
+ }
}
+
+ return 0;
+err:
+ return 1;
}
#endif
@@ -11390,25 +11892,28 @@ void Annotate_rows_log_event::pack_info(Protocol* protocol)
#endif
#ifdef MYSQL_CLIENT
-void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
+bool Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
{
- if (pinfo->short_form)
- return;
-
- print_header(&pinfo->head_cache, pinfo, TRUE);
- my_b_printf(&pinfo->head_cache, "\tAnnotate_rows:\n");
-
char *pbeg; // beginning of the next line
char *pend; // end of the next line
uint cnt= 0; // characters counter
+ if (!pinfo->short_form)
+ {
+ if (print_header(&pinfo->head_cache, pinfo, TRUE) ||
+ my_b_printf(&pinfo->head_cache, "\tAnnotate_rows:\n"))
+ goto err;
+ }
+ else if (my_b_printf(&pinfo->head_cache, "# Annotate_rows:\n"))
+ goto err;
+
for (pbeg= m_query_txt; ; pbeg= pend)
{
// skip all \r's and \n's at the beginning of the next line
for (;; pbeg++)
{
if (++cnt > m_query_len)
- return;
+ return 0;
if (*pbeg != '\r' && *pbeg != '\n')
break;
@@ -11421,10 +11926,15 @@ void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
;
// print next line
- my_b_write(&pinfo->head_cache, (const uchar*) "#Q> ", 4);
- my_b_write(&pinfo->head_cache, (const uchar*) pbeg, pend - pbeg);
- my_b_write(&pinfo->head_cache, (const uchar*) "\n", 1);
+ if (my_b_write(&pinfo->head_cache, (const uchar*) "#Q> ", 4) ||
+ my_b_write(&pinfo->head_cache, (const uchar*) pbeg, pend - pbeg) ||
+ my_b_write(&pinfo->head_cache, (const uchar*) "\n", 1))
+ goto err;
}
+
+ return 0;
+err:
+ return 1;
}
#endif
@@ -11721,7 +12231,7 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
bytes_read= (uint) (ptr_after_colcnt - (uchar *)buf);
- DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
+ DBUG_PRINT("info", ("Bytes read: %d", bytes_read));
if (bytes_read < event_len)
{
m_field_metadata_size= net_field_length(&ptr_after_colcnt);
@@ -11777,7 +12287,7 @@ int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len,
LOG_EVENT_MINIMAL_HEADER_LEN) + TABLE_MAP_HEADER_LEN;
int len_diff;
- if (!(len_diff= new_len - m_dblen))
+ if (!(len_diff= (int)(new_len - m_dblen)))
{
memcpy((void*) (temp_buf + header_len + 1), new_db, m_dblen + 1);
memcpy((void*) m_dbnam, new_db, m_dblen + 1);
@@ -11799,7 +12309,7 @@ int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len,
// Rewrite temp_buf
char* ptr= new_temp_buf;
- ulong cnt= 0;
+ size_t cnt= 0;
// Copy header and change event length
memcpy(ptr, temp_buf, header_len);
@@ -11808,7 +12318,8 @@ int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len,
cnt += header_len;
// Write new db name length and new name
- *ptr++ = new_len;
+ DBUG_ASSERT(new_len < 0xff);
+ *ptr++ = (char)new_len;
memcpy(ptr, new_db, new_len + 1);
ptr += new_len + 1;
cnt += m_dblen + 2;
@@ -11927,7 +12438,7 @@ check_table_map(rpl_group_info *rgi, RPL_TABLE_LIST *table_list)
Relay_log_info *rli= rgi->rli;
if ((rgi->thd->slave_thread /* filtering is for slave only */ ||
IF_WSREP((WSREP(rgi->thd) && rgi->thd->wsrep_applier), 0)) &&
- (!rli->mi->rpl_filter->db_ok(table_list->db) ||
+ (!rli->mi->rpl_filter->db_ok(table_list->db.str) ||
(rli->mi->rpl_filter->is_on() && !rli->mi->rpl_filter->tables_ok("", table_list))))
res= FILTERED_OUT;
else
@@ -11939,8 +12450,8 @@ check_table_map(rpl_group_info *rgi, RPL_TABLE_LIST *table_list)
if (ptr->table_id == table_list->table_id)
{
- if (strcmp(ptr->db, table_list->db) ||
- strcmp(ptr->alias, table_list->table_name) ||
+ if (cmp(&ptr->db, &table_list->db) ||
+ cmp(&ptr->alias, &table_list->table_name) ||
ptr->lock_type != TL_WRITE) // the ::do_apply_event always sets TL_WRITE
res= SAME_ID_MAPPING_DIFFERENT_TABLE;
else
@@ -11960,7 +12471,7 @@ int Table_map_log_event::do_apply_event(rpl_group_info *rgi)
{
RPL_TABLE_LIST *table_list;
char *db_mem, *tname_mem;
- size_t dummy_len;
+ size_t dummy_len, db_mem_length, tname_mem_length;
void *memory;
Rpl_filter *filter;
Relay_log_info const *rli= rgi->rli;
@@ -11978,19 +12489,20 @@ int Table_map_log_event::do_apply_event(rpl_group_info *rgi)
/* call from mysql_client_binlog_statement() will not set rli->mi */
filter= rgi->thd->slave_thread ? rli->mi->rpl_filter : global_rpl_filter;
- strmov(db_mem, filter->get_rewrite_db(m_dbnam, &dummy_len));
- strmov(tname_mem, m_tblnam);
+ db_mem_length= strmov(db_mem, filter->get_rewrite_db(m_dbnam, &dummy_len))- db_mem;
+ tname_mem_length= strmov(tname_mem, m_tblnam)- tname_mem;
- table_list->init_one_table(db_mem, strlen(db_mem),
- tname_mem, strlen(tname_mem),
- tname_mem, TL_WRITE);
+ LEX_CSTRING tmp_db_name= {db_mem, db_mem_length };
+ LEX_CSTRING tmp_tbl_name= {tname_mem, tname_mem_length };
+ table_list->init_one_table(&tmp_db_name, &tmp_tbl_name, 0, TL_WRITE);
table_list->table_id= DBUG_EVALUATE_IF("inject_tblmap_same_id_maps_diff_table", 0, m_table_id);
table_list->updating= 1;
table_list->required_type= TABLE_TYPE_NORMAL;
- DBUG_PRINT("debug", ("table: %s is mapped to %u", table_list->table_name,
- table_list->table_id));
+ DBUG_PRINT("debug", ("table: %s is mapped to %u",
+ table_list->table_name.str,
+ table_list->table_id));
table_list->master_had_triggers= ((m_flags & TM_BIT_HAS_TRIGGERS_F) ? 1 : 0);
DBUG_PRINT("debug", ("table->master_had_triggers=%d",
(int)table_list->master_had_triggers));
@@ -12159,19 +12671,29 @@ void Table_map_log_event::pack_info(Protocol *protocol)
#ifdef MYSQL_CLIENT
-void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
+bool Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
{
if (!print_event_info->short_form)
{
print_header(&print_event_info->head_cache, print_event_info, TRUE);
- my_b_printf(&print_event_info->head_cache,
- "\tTable_map: %`s.%`s mapped to number %lu%s\n",
- m_dbnam, m_tblnam, m_table_id,
- ((m_flags & TM_BIT_HAS_TRIGGERS_F) ?
- " (has triggers)" : ""));
- print_base64(&print_event_info->body_cache, print_event_info, TRUE);
- copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, file);
+ if (my_b_printf(&print_event_info->head_cache,
+ "\tTable_map: %`s.%`s mapped to number %lu%s\n",
+ m_dbnam, m_tblnam, m_table_id,
+ ((m_flags & TM_BIT_HAS_TRIGGERS_F) ?
+ " (has triggers)" : "")))
+ goto err;
}
+ if (!print_event_info->short_form || print_event_info->print_row_count)
+ {
+ if (print_base64(&print_event_info->body_cache, print_event_info, TRUE) ||
+ copy_event_cache_to_file_and_reinit(&print_event_info->head_cache,
+ file))
+ goto err;
+ }
+
+ return 0;
+err:
+ return 1;
}
#endif
@@ -12504,6 +13026,17 @@ Rows_log_event::write_row(rpl_group_info *rgi,
DBUG_RETURN(HA_ERR_GENERIC); // in case if error is not set yet
}
+ // Handle INSERT.
+ // Set vers fields when replicating from not system-versioned table.
+ if (m_type == WRITE_ROWS_EVENT_V1 && table->versioned(VERS_TIMESTAMP))
+ {
+ ulong sec_part;
+ bitmap_set_bit(table->read_set, table->vers_start_field()->field_index);
+ // Check whether a row came from unversioned table and fix vers fields.
+ if (table->vers_start_field()->get_timestamp(&sec_part) == 0 && sec_part == 0)
+ table->vers_update_fields();
+ }
+
/*
Try to write record. If a corresponding record already exists in the table,
we try to change it using ha_update_row() if possible. Otherwise we delete
@@ -12741,14 +13274,14 @@ Write_rows_log_event::do_exec_row(rpl_group_info *rgi)
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
#ifdef MYSQL_CLIENT
-void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
+bool Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
{
DBUG_EXECUTE_IF("simulate_cache_read_error",
{DBUG_SET("+d,simulate_my_b_fill_error");});
- Rows_log_event::print_helper(file, print_event_info, is_flashback ? "Delete_rows" : "Write_rows");
+ return Rows_log_event::print_helper(file, print_event_info, is_flashback ? "Delete_rows" : "Write_rows");
}
-void Write_rows_compressed_log_event::print(FILE *file,
+bool Write_rows_compressed_log_event::print(FILE *file,
PRINT_EVENT_INFO* print_event_info)
{
char *new_buf;
@@ -12760,14 +13293,20 @@ void Write_rows_compressed_log_event::print(FILE *file,
{
free_temp_buf();
register_temp_buf(new_buf, true);
- Rows_log_event::print_helper(file, print_event_info,
- "Write_compressed_rows");
+ if (Rows_log_event::print_helper(file, print_event_info,
+ "Write_compressed_rows"))
+ goto err;
}
else
{
- my_b_printf(&print_event_info->head_cache,
- "ERROR: uncompress write_compressed_rows failed\n");
+ if (my_b_printf(&print_event_info->head_cache,
+ "ERROR: uncompress write_compressed_rows failed\n"))
+ goto err;
}
+
+ return 0;
+err:
+ return 1;
}
#endif
@@ -12824,7 +13363,10 @@ static bool record_compare(TABLE *table)
/* Compare fields */
for (Field **ptr=table->field ; *ptr ; ptr++)
{
-
+ if (table->versioned() && (*ptr)->vers_sys_field())
+ {
+ continue;
+ }
/**
We only compare field contents that are not null.
NULL fields (i.e., their null bits) were compared
@@ -12959,10 +13501,11 @@ void issue_long_find_row_warning(Log_event_type type,
sql_print_information("The slave is applying a ROW event on behalf of a%s statement "
"on table %s and is currently taking a considerable amount "
- "of time (%ld seconds). This is due to the fact that it is %s "
+ "of time (%lld seconds). This is due to the fact that it is %s "
"while looking up records to be processed. Consider adding a "
"primary key (or unique key) to the table to improve "
- "performance.", evt_type, table_name, delta, scan_type);
+ "performance.",
+ evt_type, table_name, (long) delta, scan_type);
}
}
}
@@ -13019,6 +13562,27 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
prepare_record(table, m_width, FALSE);
error= unpack_current_row(rgi);
+ m_vers_from_plain= false;
+ if (table->versioned())
+ {
+ Field *row_end= table->vers_end_field();
+ DBUG_ASSERT(table->read_set);
+ bitmap_set_bit(table->read_set, row_end->field_index);
+ // check whether master table is unversioned
+ if (row_end->val_int() == 0)
+ {
+ // row_start initialized with NULL when came from plain table.
+ // Set it notnull() because record_compare() count NULLs.
+ table->vers_start_field()->set_notnull();
+ bitmap_set_bit(table->write_set, row_end->field_index);
+ // Plain source table may have a PRIMARY KEY. And row_end is always
+ // a part of PRIMARY KEY. Set it to max value for engine to find it in
+ // index. Needed for an UPDATE/DELETE cases.
+ table->vers_end_field()->set_max();
+ m_vers_from_plain= true;
+ }
+ }
+
DBUG_PRINT("info",("looking for the following record"));
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
@@ -13400,7 +13964,19 @@ int Delete_rows_log_event::do_exec_row(rpl_group_info *rgi)
if (!error)
{
m_table->mark_columns_per_binlog_row_image();
- error= m_table->file->ha_delete_row(m_table->record[0]);
+ if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP))
+ {
+ Field *end= m_table->vers_end_field();
+ bitmap_set_bit(m_table->write_set, end->field_index);
+ store_record(m_table, record[1]);
+ end->set_time();
+ error= m_table->file->ha_update_row(m_table->record[1],
+ m_table->record[0]);
+ }
+ else
+ {
+ error= m_table->file->ha_delete_row(m_table->record[0]);
+ }
m_table->default_column_bitmaps();
}
if (invoke_triggers && !error &&
@@ -13415,13 +13991,13 @@ int Delete_rows_log_event::do_exec_row(rpl_group_info *rgi)
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
#ifdef MYSQL_CLIENT
-void Delete_rows_log_event::print(FILE *file,
+bool Delete_rows_log_event::print(FILE *file,
PRINT_EVENT_INFO* print_event_info)
{
- Rows_log_event::print_helper(file, print_event_info, is_flashback ? "Write_rows" : "Delete_rows");
+ return Rows_log_event::print_helper(file, print_event_info, is_flashback ? "Write_rows" : "Delete_rows");
}
-void Delete_rows_compressed_log_event::print(FILE *file,
+bool Delete_rows_compressed_log_event::print(FILE *file,
PRINT_EVENT_INFO* print_event_info)
{
char *new_buf;
@@ -13433,14 +14009,20 @@ void Delete_rows_compressed_log_event::print(FILE *file,
{
free_temp_buf();
register_temp_buf(new_buf, true);
- Rows_log_event::print_helper(file, print_event_info,
- "Delete_compressed_rows");
+ if (Rows_log_event::print_helper(file, print_event_info,
+ "Delete_compressed_rows"))
+ goto err;
}
else
{
- my_b_printf(&print_event_info->head_cache,
- "ERROR: uncompress delete_compressed_rows failed\n");
+ if (my_b_printf(&print_event_info->head_cache,
+ "ERROR: uncompress delete_compressed_rows failed\n"))
+ goto err;
}
+
+ return 0;
+err:
+ return 1;
}
#endif
@@ -13657,9 +14239,17 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
m_table->mark_columns_per_binlog_row_image();
+ if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP))
+ m_table->vers_update_fields();
error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
if (error == HA_ERR_RECORD_IS_THE_SAME)
error= 0;
+ if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP))
+ {
+ store_record(m_table, record[2]);
+ error= vers_insert_history_row(m_table);
+ restore_record(m_table, record[2]);
+ }
m_table->default_column_bitmaps();
if (invoke_triggers && !error &&
@@ -13676,13 +14266,15 @@ err:
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
#ifdef MYSQL_CLIENT
-void Update_rows_log_event::print(FILE *file,
+bool Update_rows_log_event::print(FILE *file,
PRINT_EVENT_INFO* print_event_info)
{
- Rows_log_event::print_helper(file, print_event_info, "Update_rows");
+ return Rows_log_event::print_helper(file, print_event_info, "Update_rows");
}
-void Update_rows_compressed_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
+bool
+Update_rows_compressed_log_event::print(FILE *file,
+ PRINT_EVENT_INFO *print_event_info)
{
char *new_buf;
ulong len;
@@ -13693,14 +14285,20 @@ void Update_rows_compressed_log_event::print(FILE *file, PRINT_EVENT_INFO *print
{
free_temp_buf();
register_temp_buf(new_buf, true);
- Rows_log_event::print_helper(file, print_event_info,
- "Update_compressed_rows");
+ if (Rows_log_event::print_helper(file, print_event_info,
+ "Update_compressed_rows"))
+ goto err;
}
else
{
- my_b_printf(&print_event_info->head_cache,
- "ERROR: uncompress update_compressed_rows failed\n");
+ if (my_b_printf(&print_event_info->head_cache,
+ "ERROR: uncompress update_compressed_rows failed\n"))
+ goto err;
}
+
+ return 0;
+err:
+ return 1;
}
#endif
@@ -13839,16 +14437,18 @@ err:
#ifdef MYSQL_CLIENT
-void
-Incident_log_event::print(FILE *file,
- PRINT_EVENT_INFO *print_event_info)
+bool Incident_log_event::print(FILE *file,
+ PRINT_EVENT_INFO *print_event_info)
{
if (print_event_info->short_form)
- return;
+ return 0;
Write_on_release_cache cache(&print_event_info->head_cache, file);
- print_header(&cache, print_event_info, FALSE);
- my_b_printf(&cache, "\n# Incident: %s\nRELOAD DATABASE; # Shall generate syntax error\n", description());
+
+ if (print_header(&cache, print_event_info, FALSE) ||
+ my_b_printf(&cache, "\n# Incident: %s\nRELOAD DATABASE; # Shall generate syntax error\n", description()))
+ return 1;
+ return cache.flush_data();
}
#endif
@@ -13924,19 +14524,20 @@ void Ignorable_log_event::pack_info(Protocol *protocol)
#ifdef MYSQL_CLIENT
/* Print for its unrecognized ignorable event */
-void
-Ignorable_log_event::print(FILE *file,
- PRINT_EVENT_INFO *print_event_info)
+bool Ignorable_log_event::print(FILE *file,
+ PRINT_EVENT_INFO *print_event_info)
{
if (print_event_info->short_form)
- return;
+ return 0;
- print_header(&print_event_info->head_cache, print_event_info, FALSE);
- my_b_printf(&print_event_info->head_cache, "\tIgnorable\n");
- my_b_printf(&print_event_info->head_cache,
- "# Ignorable event type %d (%s)\n", number, description);
- copy_event_cache_to_file_and_reinit(&print_event_info->head_cache,
- file);
+ if (print_header(&print_event_info->head_cache, print_event_info, FALSE) ||
+ my_b_printf(&print_event_info->head_cache, "\tIgnorable\n") ||
+ my_b_printf(&print_event_info->head_cache,
+ "# Ignorable event type %d (%s)\n", number, description) ||
+ copy_event_cache_to_file_and_reinit(&print_event_info->head_cache,
+ file))
+ return 1;
+ return 0;
}
#endif
@@ -13948,15 +14549,8 @@ Ignorable_log_event::print(FILE *file,
they will always be printed for the first event.
*/
st_print_event_info::st_print_event_info()
- :flags2_inited(0), sql_mode_inited(0), sql_mode(0),
- auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
- lc_time_names_number(~0),
- charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
- thread_id(0), thread_id_printed(false), server_id(0),
- server_id_printed(false), domain_id(0), domain_id_printed(false),
- allow_parallel(true), allow_parallel_printed(false), skip_replication(0),
- base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE)
{
+ myf const flags = MYF(MY_WME | MY_NABP);
/*
Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
program's startup, but these explicit bzero() is for the day someone
@@ -13967,14 +14561,68 @@ st_print_event_info::st_print_event_info()
bzero(time_zone_str, sizeof(time_zone_str));
delimiter[0]= ';';
delimiter[1]= 0;
- myf const flags = MYF(MY_WME | MY_NABP);
+ flags2_inited= 0;
+ sql_mode_inited= 0;
+ row_events= 0;
+ sql_mode= 0;
+ auto_increment_increment= 0;
+ auto_increment_offset= 0;
+ charset_inited= 0;
+ lc_time_names_number= ~0;
+ charset_database_number= ILLEGAL_CHARSET_INFO_NUMBER;
+ thread_id= 0;
+ server_id= 0;
+ domain_id= 0;
+ thread_id_printed= false;
+ server_id_printed= false;
+ domain_id_printed= false;
+ allow_parallel= true;
+ allow_parallel_printed= false;
+ found_row_event= false;
+ print_row_count= false;
+ short_form= false;
+ skip_replication= 0;
+ printed_fd_event=FALSE;
+ file= 0;
+ base64_output_mode=BASE64_OUTPUT_UNSPEC;
open_cached_file(&head_cache, NULL, NULL, 0, flags);
open_cached_file(&body_cache, NULL, NULL, 0, flags);
#ifdef WHEN_FLASHBACK_REVIEW_READY
open_cached_file(&review_sql_cache, NULL, NULL, 0, flags);
#endif
}
-#endif
+
+
+bool copy_event_cache_to_string_and_reinit(IO_CACHE *cache, LEX_STRING *to)
+{
+ reinit_io_cache(cache, READ_CACHE, 0L, FALSE, FALSE);
+ if (cache->end_of_file > SIZE_T_MAX ||
+ !(to->str= (char*) my_malloc((to->length= (size_t)cache->end_of_file), MYF(0))))
+ {
+ perror("Out of memory: can't allocate memory in copy_event_cache_to_string_and_reinit().");
+ goto err;
+ }
+ if (my_b_read(cache, (uchar*) to->str, to->length))
+ {
+ my_free(to->str);
+ perror("Can't read data from IO_CACHE");
+ return true;
+ }
+ reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE);
+ return false;
+
+err:
+ to->str= 0;
+ to->length= 0;
+ return true;
+}
+#endif /* MYSQL_CLIENT */
+
+bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache, FILE *file)
+{
+ return (my_b_copy_to_file(cache, file) ||
+ reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE));
+}
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
@@ -14012,4 +14660,4 @@ bool event_that_should_be_ignored(const char *buf)
return 1;
return 0;
}
-#endif
+#endif /* MYSQL_SERVER */
diff --git a/sql/log_event.h b/sql/log_event.h
index c8f3241cb3d..97e06c165b9 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -802,6 +802,8 @@ class Format_description_log_event;
class Relay_log_info;
class binlog_cache_data;
+bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache, FILE *file);
+
#ifdef MYSQL_CLIENT
enum enum_base64_output_mode {
BASE64_OUTPUT_NEVER= 0,
@@ -813,6 +815,8 @@ enum enum_base64_output_mode {
BASE64_OUTPUT_MODE_COUNT
};
+bool copy_event_cache_to_string_and_reinit(IO_CACHE *cache, LEX_STRING *to);
+
/*
A structure for mysqlbinlog to know how to print events
@@ -832,53 +836,38 @@ typedef struct st_print_event_info
that was printed. We cache these so that we don't have to print
them if they are unchanged.
*/
- // TODO: have the last catalog here ??
char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is
- bool flags2_inited;
- uint32 flags2;
- bool sql_mode_inited;
- sql_mode_t sql_mode; /* must be same as THD.variables.sql_mode */
- ulong auto_increment_increment, auto_increment_offset;
- bool charset_inited;
char charset[6]; // 3 variables, each of them storable in 2 bytes
char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
+ char delimiter[16];
+ sql_mode_t sql_mode; /* must be same as THD.variables.sql_mode */
+ my_thread_id thread_id;
+ ulonglong row_events;
+ ulong auto_increment_increment, auto_increment_offset;
uint lc_time_names_number;
uint charset_database_number;
- my_thread_id thread_id;
- bool thread_id_printed;
+ uint verbose;
+ uint32 flags2;
uint32 server_id;
- bool server_id_printed;
uint32 domain_id;
+ uint8 common_header_len;
+ enum_base64_output_mode base64_output_mode;
+ my_off_t hexdump_from;
+
+ table_mapping m_table_map;
+ table_mapping m_table_map_ignored;
+ bool flags2_inited;
+ bool sql_mode_inited;
+ bool charset_inited;
+ bool thread_id_printed;
+ bool server_id_printed;
bool domain_id_printed;
bool allow_parallel;
bool allow_parallel_printed;
-
- /*
- Track when @@skip_replication changes so we need to output a SET
- statement for it.
- */
- int skip_replication;
-
- st_print_event_info();
-
- ~st_print_event_info() {
- close_cached_file(&head_cache);
- close_cached_file(&body_cache);
-#ifdef WHEN_FLASHBACK_REVIEW_READY
- close_cached_file(&review_sql_cache);
-#endif
- }
- bool init_ok() /* tells if construction was successful */
- { return my_b_inited(&head_cache) && my_b_inited(&body_cache)
-#ifdef WHEN_FLASHBACK_REVIEW_READY
- && my_b_inited(&review_sql_cache)
-#endif
- ; }
-
-
+ bool found_row_event;
+ bool print_row_count;
/* Settings on how to print the events */
bool short_form;
- enum_base64_output_mode base64_output_mode;
/*
This is set whenever a Format_description_event is printed.
Later, when an event is printed in base64, this flag is tested: if
@@ -886,13 +875,11 @@ typedef struct st_print_event_info
the base64 event, so an error message is generated.
*/
bool printed_fd_event;
- my_off_t hexdump_from;
- uint8 common_header_len;
- char delimiter[16];
-
- uint verbose;
- table_mapping m_table_map;
- table_mapping m_table_map_ignored;
+ /*
+ Track when @@skip_replication changes so we need to output a SET
+ statement for it.
+ */
+ bool skip_replication;
/*
These two caches are used by the row-based replication events to
@@ -905,6 +892,28 @@ typedef struct st_print_event_info
/* Storing the SQL for reviewing */
IO_CACHE review_sql_cache;
#endif
+ FILE *file;
+ st_print_event_info();
+
+ ~st_print_event_info() {
+ close_cached_file(&head_cache);
+ close_cached_file(&body_cache);
+#ifdef WHEN_FLASHBACK_REVIEW_READY
+ close_cached_file(&review_sql_cache);
+#endif
+ }
+ bool init_ok() /* tells if construction was successful */
+ { return my_b_inited(&head_cache) && my_b_inited(&body_cache)
+#ifdef WHEN_FLASHBACK_REVIEW_READY
+ && my_b_inited(&review_sql_cache)
+#endif
+ ; }
+ void flush_for_error()
+ {
+ if (!copy_event_cache_to_file_and_reinit(&head_cache, file))
+ copy_event_cache_to_file_and_reinit(&body_cache, file);
+ fflush(file);
+ }
} PRINT_EVENT_INFO;
#endif
@@ -1194,7 +1203,7 @@ public:
/* The number of seconds the query took to run on the master. */
ulong exec_time;
/* Number of bytes written by write() function */
- ulong data_written;
+ size_t data_written;
/*
The master's server id (is preserved in the relay log; used to
@@ -1244,17 +1253,17 @@ public:
#endif /* HAVE_REPLICATION */
virtual const char* get_db()
{
- return thd ? thd->db : 0;
+ return thd ? thd->db.str : 0;
}
#else
Log_event() : temp_buf(0), when(0), flags(0) {}
ha_checksum crc;
/* print*() functions are used by mysqlbinlog */
- virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;
- void print_timestamp(IO_CACHE* file, time_t *ts = 0);
- void print_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
+ virtual bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;
+ bool print_timestamp(IO_CACHE* file, time_t *ts = 0);
+ bool print_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
bool is_more);
- void print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
+ bool print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
bool is_more);
#endif /* MYSQL_SERVER */
@@ -1300,7 +1309,6 @@ public:
constructor and pass description_event as an argument.
*/
static Log_event* read_log_event(IO_CACHE* file,
- mysql_mutex_t* log_lock,
const Format_description_log_event
*description_event,
my_bool crc_check);
@@ -1356,10 +1364,10 @@ public:
static void operator delete(void*, void*) { }
#ifdef MYSQL_SERVER
- bool write_header(ulong data_length);
- bool write_data(const uchar *buf, ulong data_length)
+ bool write_header(size_t event_data_length);
+ bool write_data(const uchar *buf, size_t data_length)
{ return writer->write_data(buf, data_length); }
- bool write_data(const char *buf, ulong data_length)
+ bool write_data(const char *buf, size_t data_length)
{ return write_data((uchar*)buf, data_length); }
bool write_footer()
{ return writer->write_footer(); }
@@ -2106,15 +2114,15 @@ public:
#ifdef MYSQL_SERVER
- Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
+ Query_log_event(THD* thd_arg, const char* query_arg, size_t query_length,
bool using_trans, bool direct, bool suppress_use, int error);
const char* get_db() { return db; }
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
#endif /* HAVE_REPLICATION */
#else
- void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Query_log_event();
@@ -2453,7 +2461,7 @@ protected:
const Format_description_log_event* description_event);
public:
- void print_query(THD *thd, bool need_db, const char *cs, String *buf,
+ bool print_query(THD *thd, bool need_db, const char *cs, String *buf,
my_off_t *fn_start, my_off_t *fn_end,
const char *qualify_db);
my_thread_id thread_id;
@@ -2490,10 +2498,10 @@ public:
bool is_concurrent;
/* fname doesn't point to memory inside Log_event::temp_buf */
- void set_fname_outside_temp_buf(const char *afname, uint alen)
+ void set_fname_outside_temp_buf(const char *afname, size_t alen)
{
fname= afname;
- fname_len= alen;
+ fname_len= (uint)alen;
local_fname= TRUE;
}
/* fname doesn't point to memory inside Log_event::temp_buf */
@@ -2519,8 +2527,8 @@ public:
void pack_info(Protocol* protocol);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented);
#endif
/*
@@ -2617,7 +2625,7 @@ public:
#endif /* HAVE_REPLICATION */
#else
Start_log_event_v3() {}
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Start_log_event_v3(const char* buf, uint event_len,
@@ -2686,7 +2694,7 @@ public:
write_data(nonce, BINLOG_NONCE_LENGTH);
}
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Start_encryption_log_event(
@@ -2874,7 +2882,7 @@ Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg,
void pack_info(Protocol* protocol);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Intvar_log_event(const char* buf,
@@ -2955,7 +2963,7 @@ class Rand_log_event: public Log_event
void pack_info(Protocol* protocol);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Rand_log_event(const char* buf,
@@ -3005,7 +3013,7 @@ class Xid_log_event: public Log_event
void pack_info(Protocol* protocol);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Xid_log_event(const char* buf,
@@ -3042,9 +3050,9 @@ public:
UNSIGNED_F= 1
};
const char *name;
- uint name_len;
+ size_t name_len;
const char *val;
- ulong val_len;
+ size_t val_len;
Item_result type;
uint charset_number;
bool is_null;
@@ -3052,8 +3060,8 @@ public:
#ifdef MYSQL_SERVER
bool deferred;
query_id_t query_id;
- User_var_log_event(THD* thd_arg, const char *name_arg, uint name_len_arg,
- const char *val_arg, ulong val_len_arg, Item_result type_arg,
+ User_var_log_event(THD* thd_arg, const char *name_arg, size_t name_len_arg,
+ const char *val_arg, size_t val_len_arg, Item_result type_arg,
uint charset_number_arg, uchar flags_arg,
bool using_trans, bool direct)
:Log_event(thd_arg, 0, using_trans),
@@ -3067,7 +3075,7 @@ public:
}
void pack_info(Protocol* protocol);
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
User_var_log_event(const char* buf, uint event_len,
@@ -3115,7 +3123,7 @@ public:
Stop_log_event() :Log_event()
{}
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Stop_log_event(const char* buf,
@@ -3211,7 +3219,7 @@ public:
void pack_info(Protocol* protocol);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Rotate_log_event(const char* buf, uint event_len,
@@ -3251,7 +3259,7 @@ public:
void pack_info(Protocol *protocol);
#endif
#else
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
Binlog_checkpoint_log_event(const char *buf, uint event_len,
const Format_description_log_event *description_event);
@@ -3376,7 +3384,7 @@ public:
virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
#else
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
Gtid_log_event(const char *buf, uint event_len,
const Format_description_log_event *description_event);
@@ -3490,7 +3498,7 @@ public:
void pack_info(Protocol *protocol);
#endif
#else
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
Gtid_list_log_event(const char *buf, uint event_len,
const Format_description_log_event *description_event);
@@ -3511,7 +3519,7 @@ public:
virtual int do_apply_event(rpl_group_info *rgi);
enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
- static bool peek(const char *event_start, uint32 event_len,
+ static bool peek(const char *event_start, size_t event_len,
enum enum_binlog_checksum_alg checksum_alg,
rpl_gtid **out_gtid_list, uint32 *out_list_len,
const Format_description_log_event *fdev);
@@ -3554,8 +3562,8 @@ public:
void pack_info(Protocol* protocol);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info,
bool enable_local);
#endif
@@ -3627,7 +3635,7 @@ public:
virtual int get_create_or_append() const;
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Append_block_log_event(const char* buf, uint event_len,
@@ -3667,8 +3675,8 @@ public:
void pack_info(Protocol* protocol);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info,
bool enable_local);
#endif
@@ -3708,7 +3716,7 @@ public:
void pack_info(Protocol* protocol);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Execute_load_log_event(const char* buf, uint event_len,
@@ -3804,9 +3812,9 @@ public:
void pack_info(Protocol* protocol);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
/* Prints the query as LOAD DATA LOCAL and with rewritten filename */
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info,
const char *local_fname);
#endif
Execute_load_query_log_event(const char* buf, uint event_len,
@@ -3851,12 +3859,12 @@ public:
/* constructor for hopelessly corrupted events */
Unknown_log_event(): Log_event(), what(ENCRYPTED) {}
~Unknown_log_event() {}
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ bool print(FILE* file, PRINT_EVENT_INFO* print_event_info);
Log_event_type get_type_code() { return UNKNOWN_EVENT;}
bool is_valid() const { return 1; }
};
#endif
-char *str_to_hex(char *to, const char *from, uint len);
+char *str_to_hex(char *to, const char *from, size_t len);
/**
@class Annotate_rows_log_event
@@ -3896,7 +3904,7 @@ public:
#endif
#ifdef MYSQL_CLIENT
- virtual void print(FILE*, PRINT_EVENT_INFO*);
+ virtual bool print(FILE*, PRINT_EVENT_INFO*);
#endif
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
@@ -4316,7 +4324,7 @@ public:
#endif
#ifdef MYSQL_CLIENT
- virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ virtual bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
@@ -4437,15 +4445,21 @@ public:
#ifdef MYSQL_CLIENT
/* not for direct call, each derived has its own ::print() */
- virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
+ virtual bool print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
void change_to_flashback_event(PRINT_EVENT_INFO *print_event_info, uchar *rows_buff, Log_event_type ev_type);
- void print_verbose(IO_CACHE *file,
+ bool print_verbose(IO_CACHE *file,
PRINT_EVENT_INFO *print_event_info);
size_t print_verbose_one_row(IO_CACHE *file, table_def *td,
PRINT_EVENT_INFO *print_event_info,
MY_BITMAP *cols_bitmap,
const uchar *ptr, const uchar *prefix,
const my_bool no_fill_output= 0); // if no_fill_output=1, then print result is unnecessary
+ size_t calc_row_event_length(table_def *td,
+ PRINT_EVENT_INFO *print_event_info,
+ MY_BITMAP *cols_bitmap,
+ const uchar *value);
+ void count_row_events(PRINT_EVENT_INFO *print_event_info);
+
#endif
#ifdef MYSQL_SERVER
@@ -4552,7 +4566,7 @@ protected:
void uncompress_buf();
#ifdef MYSQL_CLIENT
- void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name);
+ bool print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name);
#endif
#ifdef MYSQL_SERVER
@@ -4594,6 +4608,8 @@ protected:
uchar *m_extra_row_data; /* Pointer to extra row data if any */
/* If non null, first byte is length */
+ bool m_vers_from_plain;
+
/* helper functions */
@@ -4744,6 +4760,7 @@ public:
__attribute__((unused)),
const uchar *after_record)
{
+ DBUG_ASSERT(!table->versioned(VERS_TRX_ID));
return thd->binlog_write_row(table, is_transactional, after_record);
}
#endif
@@ -4756,7 +4773,7 @@ private:
virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
#ifdef MYSQL_CLIENT
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
@@ -4780,7 +4797,7 @@ public:
#endif
private:
#if defined(MYSQL_CLIENT)
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
};
@@ -4825,6 +4842,7 @@ public:
const uchar *before_record,
const uchar *after_record)
{
+ DBUG_ASSERT(!table->versioned(VERS_TRX_ID));
return thd->binlog_update_row(table, is_transactional,
before_record, after_record);
}
@@ -4843,7 +4861,7 @@ protected:
virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
#ifdef MYSQL_CLIENT
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
@@ -4867,7 +4885,7 @@ public:
#endif
private:
#if defined(MYSQL_CLIENT)
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
};
@@ -4914,6 +4932,7 @@ public:
const uchar *after_record
__attribute__((unused)))
{
+ DBUG_ASSERT(!table->versioned(VERS_TRX_ID));
return thd->binlog_delete_row(table, is_transactional,
before_record);
}
@@ -4927,7 +4946,7 @@ protected:
virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
#ifdef MYSQL_CLIENT
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
@@ -4950,7 +4969,7 @@ public:
#endif
private:
#if defined(MYSQL_CLIENT)
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
};
@@ -5009,21 +5028,20 @@ public:
DBUG_VOID_RETURN;
}
- Incident_log_event(THD *thd_arg, Incident incident, LEX_STRING const msg)
+ Incident_log_event(THD *thd_arg, Incident incident, const LEX_CSTRING *msg)
: Log_event(thd_arg, 0, FALSE), m_incident(incident)
{
DBUG_ENTER("Incident_log_event::Incident_log_event");
DBUG_PRINT("enter", ("m_incident: %d", m_incident));
- m_message.str= NULL;
m_message.length= 0;
- if (!(m_message.str= (char*) my_malloc(msg.length+1, MYF(MY_WME))))
+ if (!(m_message.str= (char*) my_malloc(msg->length+1, MYF(MY_WME))))
{
/* Mark this event invalid */
m_incident= INCIDENT_NONE;
DBUG_VOID_RETURN;
}
- strmake(m_message.str, msg.str, msg.length);
- m_message.length= msg.length;
+ strmake(m_message.str, msg->str, msg->length);
+ m_message.length= msg->length;
set_direct_logging();
/* Replicate the incident irregardless of @@skip_replication. */
flags&= ~LOG_EVENT_SKIP_REPLICATION_F;
@@ -5044,7 +5062,7 @@ public:
virtual ~Incident_log_event();
#ifdef MYSQL_CLIENT
- virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ virtual bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
@@ -5111,7 +5129,7 @@ public:
#endif
#ifdef MYSQL_CLIENT
- virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ virtual bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
virtual Log_event_type get_type_code() { return IGNORABLE_LOG_EVENT; }
@@ -5121,38 +5139,6 @@ public:
virtual int get_data_size() { return IGNORABLE_HEADER_LEN; }
};
-
-static inline bool copy_event_cache_to_string_and_reinit(IO_CACHE *cache, LEX_STRING *to)
-{
- String tmp;
-
- reinit_io_cache(cache, READ_CACHE, 0L, FALSE, FALSE);
- if (tmp.append(cache, (uint32)cache->end_of_file))
- goto err;
- reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE);
-
- /*
- Can't change the order, because the String::release() will clear the
- length.
- */
- to->length= tmp.length();
- to->str= tmp.release();
-
- return false;
-
-err:
- perror("Out of memory: can't allocate memory in copy_event_cache_to_string_and_reinit().");
- return true;
-}
-
-static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache,
- FILE *file)
-{
- return
- my_b_copy_to_file(cache, file) ||
- reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE);
-}
-
#ifdef MYSQL_SERVER
/*****************************************************************************
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 2c079a34d56..20986050203 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1845,7 +1845,7 @@ void Old_rows_log_event::pack_info(Protocol *protocol)
#ifdef MYSQL_CLIENT
-void Old_rows_log_event::print_helper(FILE *file,
+bool Old_rows_log_event::print_helper(FILE *file,
PRINT_EVENT_INFO *print_event_info,
char const *const name)
{
@@ -1854,18 +1854,23 @@ void Old_rows_log_event::print_helper(FILE *file,
if (!print_event_info->short_form)
{
bool const last_stmt_event= get_flags(STMT_END_F);
- print_header(head, print_event_info, !last_stmt_event);
- my_b_printf(head, "\t%s: table id %lu%s\n",
- name, m_table_id,
- last_stmt_event ? " flags: STMT_END_F" : "");
- print_base64(body, print_event_info, !last_stmt_event);
+ if (print_header(head, print_event_info, !last_stmt_event) ||
+ my_b_printf(head, "\t%s: table id %lu%s\n",
+ name, m_table_id,
+ last_stmt_event ? " flags: STMT_END_F" : "") ||
+ print_base64(body, print_event_info, !last_stmt_event))
+ goto err;
}
if (get_flags(STMT_END_F))
{
- copy_event_cache_to_file_and_reinit(head, file);
- copy_event_cache_to_file_and_reinit(body, file);
+ if (copy_event_cache_to_file_and_reinit(head, file) ||
+ copy_event_cache_to_file_and_reinit(body, file))
+ goto err;
}
+ return 0;
+err:
+ return 1;
}
#endif
@@ -2491,10 +2496,11 @@ Write_rows_log_event_old::do_exec_row(rpl_group_info *rgi)
#ifdef MYSQL_CLIENT
-void Write_rows_log_event_old::print(FILE *file,
+bool Write_rows_log_event_old::print(FILE *file,
PRINT_EVENT_INFO* print_event_info)
{
- Old_rows_log_event::print_helper(file, print_event_info, "Write_rows_old");
+ return Old_rows_log_event::print_helper(file, print_event_info,
+ "Write_rows_old");
}
#endif
@@ -2598,10 +2604,11 @@ int Delete_rows_log_event_old::do_exec_row(rpl_group_info *rgi)
#ifdef MYSQL_CLIENT
-void Delete_rows_log_event_old::print(FILE *file,
+bool Delete_rows_log_event_old::print(FILE *file,
PRINT_EVENT_INFO* print_event_info)
{
- Old_rows_log_event::print_helper(file, print_event_info, "Delete_rows_old");
+ return Old_rows_log_event::print_helper(file, print_event_info,
+ "Delete_rows_old");
}
#endif
@@ -2736,9 +2743,10 @@ Update_rows_log_event_old::do_exec_row(rpl_group_info *rgi)
#ifdef MYSQL_CLIENT
-void Update_rows_log_event_old::print(FILE *file,
+bool Update_rows_log_event_old::print(FILE *file,
PRINT_EVENT_INFO* print_event_info)
{
- Old_rows_log_event::print_helper(file, print_event_info, "Update_rows_old");
+ return Old_rows_log_event::print_helper(file, print_event_info,
+ "Update_rows_old");
}
#endif
diff --git a/sql/log_event_old.h b/sql/log_event_old.h
index 40e01d37318..d18c980bdfe 100644
--- a/sql/log_event_old.h
+++ b/sql/log_event_old.h
@@ -116,7 +116,7 @@ public:
#ifdef MYSQL_CLIENT
/* not for direct call, each derived has its own ::print() */
- virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
+ virtual bool print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
#endif
#ifndef MYSQL_CLIENT
@@ -166,7 +166,7 @@ protected:
const Format_description_log_event *description_event);
#ifdef MYSQL_CLIENT
- void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name);
+ bool print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name);
#endif
#ifndef MYSQL_CLIENT
@@ -379,7 +379,7 @@ public:
private:
#ifdef MYSQL_CLIENT
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
@@ -455,7 +455,7 @@ public:
protected:
#ifdef MYSQL_CLIENT
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
@@ -529,7 +529,7 @@ public:
protected:
#ifdef MYSQL_CLIENT
- void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+ bool print(FILE *file, PRINT_EVENT_INFO *print_event_info);
#endif
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
diff --git a/sql/mdl.cc b/sql/mdl.cc
index 4efc8b0e361..bf708c945f4 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -20,7 +20,7 @@
#include "sql_array.h"
#include "rpl_rli.h"
#include <lf.h>
-#include <mysqld_error.h>
+#include "unireg.h"
#include <mysql/plugin.h>
#include <mysql/service_thd_wait.h>
#include <mysql/psi/mysql_stage.h>
diff --git a/sql/mdl.h b/sql/mdl.h
index f30c976ac94..be9cc806ec2 100644
--- a/sql/mdl.h
+++ b/sql/mdl.h
@@ -21,8 +21,6 @@
#include <mysql_com.h>
#include <lf.h>
-#include <algorithm>
-
class THD;
class MDL_context;
@@ -373,8 +371,7 @@ public:
character set is utf-8, we can safely assume that no
character starts with a zero byte.
*/
- using std::min;
- return memcmp(m_ptr, rhs->m_ptr, min(m_length, rhs->m_length));
+ return memcmp(m_ptr, rhs->m_ptr, MY_MIN(m_length, rhs->m_length));
}
MDL_key(const MDL_key *rhs)
diff --git a/sql/mf_iocache_encr.cc b/sql/mf_iocache_encr.cc
index 546e0fe03a0..9724ca4e19e 100644
--- a/sql/mf_iocache_encr.cc
+++ b/sql/mf_iocache_encr.cc
@@ -145,9 +145,10 @@ static int my_b_encr_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
if (info->seek_not_done)
{
- DBUG_ASSERT(info->pos_in_file == 0);
+ DBUG_ASSERT(info->pos_in_file % info->buffer_length == 0);
+ my_off_t wpos= info->pos_in_file / info->buffer_length * crypt_data->block_length;
- if ((mysql_file_seek(info->file, 0, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR))
+ if ((mysql_file_seek(info->file, wpos, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR))
{
info->error= -1;
DBUG_RETURN(1);
@@ -176,9 +177,9 @@ static int my_b_encr_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
crypt_data->inbuf_counter= crypt_data->counter;
set_iv(iv, info->pos_in_file, crypt_data->inbuf_counter);
- if (encryption_crypt(Buffer, length, ebuffer, &elength,
- crypt_data->key, sizeof(crypt_data->key),
- iv, sizeof(iv), ENCRYPTION_FLAG_ENCRYPT,
+ if (encryption_crypt(Buffer, (uint)length, ebuffer, &elength,
+ crypt_data->key, (uint) sizeof(crypt_data->key),
+ iv, (uint) sizeof(iv), ENCRYPTION_FLAG_ENCRYPT,
keyid, keyver))
{
my_errno= 1;
@@ -193,7 +194,7 @@ static int my_b_encr_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
buffer_length bytes should *always* produce block_length bytes
*/
DBUG_ASSERT(crypt_data->block_length == 0 || crypt_data->block_length == wlength);
- DBUG_ASSERT(elength <= encryption_encrypted_length(length, keyid, keyver));
+ DBUG_ASSERT(elength <= encryption_encrypted_length((uint)length, keyid, keyver));
crypt_data->block_length= wlength;
}
else
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
index c532a489684..ec3c85b34c4 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -1656,10 +1656,10 @@ int DsMrr_impl::dsmrr_explain_info(uint mrr_mode, char *str, size_t size)
else if (mrr_mode & DSMRR_IMPL_SORT_ROWIDS)
used_str= rowid_ordered;
- uint used_str_len= strlen(used_str);
- uint copy_len= MY_MIN(used_str_len, size);
+ size_t used_str_len= strlen(used_str);
+ size_t copy_len= MY_MIN(used_str_len, size);
memcpy(str, used_str, copy_len);
- return copy_len;
+ return (int)copy_len;
}
return 0;
}
@@ -1718,7 +1718,7 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
else
{
cost->reset();
- *buffer_size= MY_MAX(*buffer_size,
+ *buffer_size= (uint)MY_MAX(*buffer_size,
(size_t)(1.2*rows_in_last_step) * elem_size +
primary_file->ref_length + table->key_info[keynr].key_length);
}
diff --git a/sql/my_apc.cc b/sql/my_apc.cc
index c86e554e591..9a0310234a2 100644
--- a/sql/my_apc.cc
+++ b/sql/my_apc.cc
@@ -35,7 +35,7 @@
void Apc_target::init(mysql_mutex_t *target_mutex)
{
DBUG_ASSERT(!enabled);
- LOCK_thd_data_ptr= target_mutex;
+ LOCK_thd_kill_ptr= target_mutex;
#ifndef DBUG_OFF
n_calls_processed= 0;
#endif
@@ -46,7 +46,7 @@ void Apc_target::init(mysql_mutex_t *target_mutex)
void Apc_target::enqueue_request(Call_request *qe)
{
- mysql_mutex_assert_owner(LOCK_thd_data_ptr);
+ mysql_mutex_assert_owner(LOCK_thd_kill_ptr);
if (apc_calls)
{
Call_request *after= apc_calls->prev;
@@ -72,7 +72,7 @@ void Apc_target::enqueue_request(Call_request *qe)
void Apc_target::dequeue_request(Call_request *qe)
{
- mysql_mutex_assert_owner(LOCK_thd_data_ptr);
+ mysql_mutex_assert_owner(LOCK_thd_kill_ptr);
if (apc_calls == qe)
{
if ((apc_calls= apc_calls->next) == qe)
@@ -146,14 +146,14 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call,
int wait_res= 0;
PSI_stage_info old_stage;
- caller_thd->ENTER_COND(&apc_request.COND_request, LOCK_thd_data_ptr,
+ caller_thd->ENTER_COND(&apc_request.COND_request, LOCK_thd_kill_ptr,
&stage_show_explain, &old_stage);
/* todo: how about processing other errors here? */
while (!apc_request.processed && (wait_res != ETIMEDOUT))
{
- /* We own LOCK_thd_data_ptr */
+ /* We own LOCK_thd_kill_ptr */
wait_res= mysql_cond_timedwait(&apc_request.COND_request,
- LOCK_thd_data_ptr, &abstime);
+ LOCK_thd_kill_ptr, &abstime);
// &apc_request.LOCK_request, &abstime);
if (caller_thd->killed)
break;
@@ -164,7 +164,7 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call,
/*
The wait has timed out, or this thread was KILLed.
Remove the request from the queue (ok to do because we own
- LOCK_thd_data_ptr)
+ LOCK_thd_kill_ptr)
*/
apc_request.processed= TRUE;
dequeue_request(&apc_request);
@@ -177,7 +177,7 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call,
res= FALSE;
}
/*
- exit_cond() will call mysql_mutex_unlock(LOCK_thd_data_ptr) for us:
+ exit_cond() will call mysql_mutex_unlock(LOCK_thd_kill_ptr) for us:
*/
caller_thd->EXIT_COND(&old_stage);
@@ -186,7 +186,7 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call,
}
else
{
- mysql_mutex_unlock(LOCK_thd_data_ptr);
+ mysql_mutex_unlock(LOCK_thd_kill_ptr);
}
return res;
}
@@ -203,11 +203,11 @@ void Apc_target::process_apc_requests()
{
Call_request *request;
- mysql_mutex_lock(LOCK_thd_data_ptr);
+ mysql_mutex_lock(LOCK_thd_kill_ptr);
if (!(request= get_first_in_queue()))
{
/* No requests in the queue */
- mysql_mutex_unlock(LOCK_thd_data_ptr);
+ mysql_mutex_unlock(LOCK_thd_kill_ptr);
break;
}
@@ -226,7 +226,7 @@ void Apc_target::process_apc_requests()
n_calls_processed++;
#endif
mysql_cond_signal(&request->COND_request);
- mysql_mutex_unlock(LOCK_thd_data_ptr);
+ mysql_mutex_unlock(LOCK_thd_kill_ptr);
}
}
diff --git a/sql/my_apc.h b/sql/my_apc.h
index 46c6fbd549d..a04e09257b9 100644
--- a/sql/my_apc.h
+++ b/sql/my_apc.h
@@ -44,7 +44,7 @@ class THD;
*/
class Apc_target
{
- mysql_mutex_t *LOCK_thd_data_ptr;
+ mysql_mutex_t *LOCK_thd_kill_ptr;
public:
Apc_target() : enabled(0), apc_calls(NULL) {}
~Apc_target() { DBUG_ASSERT(!enabled && !apc_calls);}
@@ -66,9 +66,9 @@ public:
void disable()
{
DBUG_ASSERT(enabled);
- mysql_mutex_lock(LOCK_thd_data_ptr);
+ mysql_mutex_lock(LOCK_thd_kill_ptr);
bool process= !--enabled && have_apc_requests();
- mysql_mutex_unlock(LOCK_thd_data_ptr);
+ mysql_mutex_unlock(LOCK_thd_kill_ptr);
if (unlikely(process))
process_apc_requests();
}
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index 6d1c746fca8..338f78d8f08 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -238,7 +238,7 @@ int my_decimal2binary(uint mask, const my_decimal *d, uchar *bin, int prec,
E_DEC_OOM
*/
-int str2my_decimal(uint mask, const char *from, uint length,
+int str2my_decimal(uint mask, const char *from, size_t length,
CHARSET_INFO *charset, my_decimal *decimal_value,
const char **end_ptr)
{
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index 918213568fc..22800c24338 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -288,7 +288,7 @@ int my_decimal_set_zero(my_decimal *d)
{
/*
We need the up-cast here, since my_decimal has sign() member functions,
- which conflicts with decimal_t::size
+ which conflicts with decimal_t::sign
(and decimal_make_zero is a macro, rather than a funcion).
*/
decimal_make_zero(static_cast<decimal_t*>(d));
@@ -365,11 +365,11 @@ int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end)
}
-int str2my_decimal(uint mask, const char *from, uint length,
+int str2my_decimal(uint mask, const char *from, size_t length,
CHARSET_INFO *charset, my_decimal *decimal_value,
const char **end);
-inline int str2my_decimal(uint mask, const char *from, uint length,
+inline int str2my_decimal(uint mask, const char *from, size_t length,
CHARSET_INFO *charset, my_decimal *decimal_value)
{
const char *end;
diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc
index 1d61986034a..d219e88b98b 100644
--- a/sql/my_json_writer.cc
+++ b/sql/my_json_writer.cc
@@ -221,7 +221,7 @@ bool Single_line_formatting_helper::on_add_member(const char *name)
buf_ptr+=len;
*(buf_ptr++)= 0;
- line_len= owner->indent_level + len + 1;
+ line_len= owner->indent_level + (uint)len + 1;
state= ADD_MEMBER;
return true; // handled
}
@@ -286,7 +286,7 @@ bool Single_line_formatting_helper::on_add_str(const char *str)
memcpy(buf_ptr, str, len);
buf_ptr+=len;
*(buf_ptr++)= 0;
- line_len += len + 4;
+ line_len += (uint)len + 4;
return true; // handled
}
diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h
index c4b528ae10d..3c127bd178c 100644
--- a/sql/my_json_writer.h
+++ b/sql/my_json_writer.h
@@ -173,6 +173,10 @@ public:
class Json_writer_nesting_guard
{
+#ifdef DBUG_OFF
+public:
+ Json_writer_nesting_guard(Json_writer *) {}
+#else
Json_writer* writer;
int indent_level;
public:
@@ -185,6 +189,7 @@ public:
{
DBUG_ASSERT(indent_level == writer->indent_level);
}
+#endif
};
diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc
index 30f2d4f6526..c76b279048b 100644
--- a/sql/mysql_install_db.cc
+++ b/sql/mysql_install_db.cc
@@ -442,7 +442,6 @@ static int set_directory_permissions(const char *dir, const char *os_user)
ACL* pOldDACL;
SECURITY_DESCRIPTOR* pSD= NULL;
EXPLICIT_ACCESS ea={0};
- BOOL isWellKnownSID= FALSE;
WELL_KNOWN_SID_TYPE wellKnownSidType = WinNullSid;
PSID pSid= NULL;
@@ -509,7 +508,7 @@ static int set_directory_permissions(const char *dir, const char *os_user)
ea.grfInheritance= CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE;
ea.Trustee.TrusteeType= TRUSTEE_IS_UNKNOWN;
ACL* pNewDACL= 0;
- DWORD err= SetEntriesInAcl(1,&ea,pOldDACL,&pNewDACL);
+ SetEntriesInAcl(1,&ea,pOldDACL,&pNewDACL);
if (pNewDACL)
{
SetSecurityInfo(hDir,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL,
@@ -524,28 +523,6 @@ static int set_directory_permissions(const char *dir, const char *os_user)
}
-/*
- Give directory permissions for special service user NT SERVICE\servicename
- this user is available only on Win7 and later.
-*/
-
-void grant_directory_permissions_to_service()
-{
- char service_user[MAX_PATH+ 12];
- OSVERSIONINFO info;
- info.dwOSVersionInfoSize= sizeof(info);
- GetVersionEx(&info);
- if (info.dwMajorVersion >6 ||
- (info.dwMajorVersion== 6 && info.dwMinorVersion > 0)
- && opt_service)
- {
- my_snprintf(service_user,sizeof(service_user), "NT SERVICE\\%s",
- opt_service);
- set_directory_permissions(opt_datadir, service_user);
- }
-}
-
-
/* Create database instance (including registering as service etc) .*/
static int create_db_instance()
@@ -668,7 +645,6 @@ static int create_db_instance()
if (opt_service && opt_service[0])
{
ret= register_service();
- grant_directory_permissions_to_service();
if (ret)
goto end;
}
diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc
index 2f242bebb0d..599f4a40ea0 100644
--- a/sql/mysql_upgrade_service.cc
+++ b/sql/mysql_upgrade_service.cc
@@ -51,7 +51,7 @@ static char *opt_service;
static SC_HANDLE service;
static SC_HANDLE scm;
HANDLE mysqld_process; // mysqld.exe started for upgrade
-DWORD initial_service_state= -1; // initial state of the service
+DWORD initial_service_state= UINT_MAX; // initial state of the service
HANDLE logfile_handle;
/*
@@ -126,7 +126,7 @@ static void die(const char *fmt, ...)
Stop service that we started, if it was not initally running at
program start.
*/
- if (initial_service_state != -1 && initial_service_state != SERVICE_RUNNING)
+ if (initial_service_state != UINT_MAX && initial_service_state != SERVICE_RUNNING)
{
SERVICE_STATUS service_status;
ControlService(service, SERVICE_CONTROL_STOP, &service_status);
@@ -252,7 +252,7 @@ void stop_mysqld_service()
Remeber initial state of the service, we will restore it on
exit.
*/
- if(initial_service_state == -1)
+ if(initial_service_state == UINT_MAX)
initial_service_state= ssp.dwCurrentState;
switch(ssp.dwCurrentState)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index fd794bfe02b..4ee9cda70bf 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -46,7 +46,6 @@
#include "sql_servers.h" // servers_free, servers_init
#include "init.h" // unireg_init
#include "derror.h" // init_errmessage
-#include "derror.h" // init_errmessage
#include "des_key_file.h" // load_des_key_file
#include "sql_manager.h" // stop_handle_manager, start_handle_manager
#include "sql_expression_cache.h" // subquery_cache_miss, subquery_cache_hit
@@ -97,8 +96,10 @@
#include "set_var.h"
#include "rpl_injector.h"
+#include "semisync_master.h"
+#include "semisync_slave.h"
-#include "rpl_handler.h"
+#include "transaction.h"
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
@@ -444,6 +445,7 @@ my_bool opt_replicate_annotate_row_events= 0;
my_bool opt_mysql56_temporal_format=0, strict_password_validation= 1;
my_bool opt_explicit_defaults_for_timestamp= 0;
char *opt_slave_skip_errors;
+char *opt_slave_transaction_retry_errors;
/*
Legacy global handlerton. These will be removed (please do not add more).
@@ -491,7 +493,6 @@ uint protocol_version;
uint lower_case_table_names;
ulong tc_heuristic_recover= 0;
int32 thread_count, service_thread_count;
-int32 thread_running;
int32 slave_open_temp_tables;
ulong thread_created;
ulong back_log, connect_timeout, concurrency, server_id;
@@ -499,6 +500,7 @@ ulong what_to_log;
ulong slow_launch_time;
ulong open_files_limit, max_binlog_size;
ulong slave_trans_retries;
+ulong slave_trans_retry_interval;
uint slave_net_timeout;
ulong slave_exec_mode_options;
ulong slave_run_triggers_for_rbr= 0;
@@ -557,7 +559,7 @@ ulong max_prepared_stmt_count;
statements.
*/
ulong prepared_stmt_count=0;
-my_thread_id global_thread_id= 1;
+my_thread_id global_thread_id= 0;
ulong current_pid;
ulong slow_launch_threads = 0;
uint sync_binlog_period= 0, sync_relaylog_period= 0,
@@ -623,7 +625,7 @@ char mysql_real_data_home[FN_REFLEN],
*opt_init_file, *opt_tc_log_file;
char *lc_messages_dir_ptr= lc_messages_dir, *log_error_file_ptr;
char mysql_unpacked_real_data_home[FN_REFLEN];
-int mysql_unpacked_real_data_home_len;
+size_t mysql_unpacked_real_data_home_len;
uint mysql_real_data_home_len, mysql_data_home_len= 1;
uint reg_ext_length;
const key_map key_map_empty(0);
@@ -764,6 +766,9 @@ mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats,
/* This protects against changes in master_info_index */
mysql_mutex_t LOCK_active_mi;
+/* This protects connection id.*/
+mysql_mutex_t LOCK_thread_id;
+
/**
The below lock protects access to two global server variables:
max_prepared_stmt_count and prepared_stmt_count. These variables
@@ -776,7 +781,7 @@ mysql_mutex_t LOCK_prepared_stmt_count;
mysql_mutex_t LOCK_des_key_file;
#endif
mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
-mysql_rwlock_t LOCK_system_variables_hash;
+mysql_prlock_t LOCK_system_variables_hash;
mysql_cond_t COND_thread_count, COND_start_thread;
pthread_t signal_thread;
pthread_attr_t connection_attrib;
@@ -909,7 +914,7 @@ PSI_mutex_key key_LOCK_des_key_file;
PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_BINLOG_LOCK_binlog_background_thread,
- m_key_LOCK_binlog_end_pos,
+ key_LOCK_binlog_end_pos,
key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log,
@@ -931,8 +936,11 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_LOCK_thread_count, key_LOCK_thread_cache,
key_PARTITION_LOCK_auto_inc;
PSI_mutex_key key_RELAYLOG_LOCK_index;
+PSI_mutex_key key_LOCK_relaylog_end_pos;
+PSI_mutex_key key_LOCK_thread_id;
PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state,
key_LOCK_rpl_thread, key_LOCK_rpl_thread_pool, key_LOCK_parallel_entry;
+PSI_mutex_key key_LOCK_binlog;
PSI_mutex_key key_LOCK_stats,
key_LOCK_global_user_client_stats, key_LOCK_global_table_stats,
@@ -944,6 +952,10 @@ PSI_mutex_key key_LOCK_after_binlog_sync;
PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered,
key_LOCK_slave_background;
PSI_mutex_key key_TABLE_SHARE_LOCK_share;
+PSI_mutex_key key_LOCK_ack_receiver;
+
+PSI_mutex_key key_TABLE_SHARE_LOCK_rotation;
+PSI_cond_key key_TABLE_SHARE_COND_rotation;
static PSI_mutex_info all_server_mutexes[]=
{
@@ -962,12 +974,14 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_BINLOG_LOCK_index, "MYSQL_BIN_LOG::LOCK_index", 0},
{ &key_BINLOG_LOCK_xid_list, "MYSQL_BIN_LOG::LOCK_xid_list", 0},
{ &key_BINLOG_LOCK_binlog_background_thread, "MYSQL_BIN_LOG::LOCK_binlog_background_thread", 0},
- { &m_key_LOCK_binlog_end_pos, "MYSQL_BIN_LOG::LOCK_binlog_end_pos", 0 },
+ { &key_LOCK_binlog_end_pos, "MYSQL_BIN_LOG::LOCK_binlog_end_pos", 0 },
{ &key_RELAYLOG_LOCK_index, "MYSQL_RELAY_LOG::LOCK_index", 0},
+ { &key_LOCK_relaylog_end_pos, "MYSQL_RELAY_LOG::LOCK_binlog_end_pos", 0},
{ &key_delayed_insert_mutex, "Delayed_insert::mutex", 0},
{ &key_hash_filo_lock, "hash_filo::lock", 0},
{ &key_LOCK_active_mi, "LOCK_active_mi", PSI_FLAG_GLOBAL},
{ &key_LOCK_connection_count, "LOCK_connection_count", PSI_FLAG_GLOBAL},
+ { &key_LOCK_thread_id, "LOCK_thread_id", PSI_FLAG_GLOBAL},
{ &key_LOCK_crypt, "LOCK_crypt", PSI_FLAG_GLOBAL},
{ &key_LOCK_delayed_create, "LOCK_delayed_create", PSI_FLAG_GLOBAL},
{ &key_LOCK_delayed_insert, "LOCK_delayed_insert", PSI_FLAG_GLOBAL},
@@ -1006,6 +1020,7 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_structure_guard_mutex, "Query_cache::structure_guard_mutex", 0},
{ &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0},
{ &key_TABLE_SHARE_LOCK_share, "TABLE_SHARE::LOCK_share", 0},
+ { &key_TABLE_SHARE_LOCK_rotation, "TABLE_SHARE::LOCK_rotation", 0},
{ &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL},
{ &key_LOCK_prepare_ordered, "LOCK_prepare_ordered", PSI_FLAG_GLOBAL},
{ &key_LOCK_after_binlog_sync, "LOCK_after_binlog_sync", PSI_FLAG_GLOBAL},
@@ -1020,14 +1035,16 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_LOCK_binlog_state, "LOCK_binlog_state", 0},
{ &key_LOCK_rpl_thread, "LOCK_rpl_thread", 0},
{ &key_LOCK_rpl_thread_pool, "LOCK_rpl_thread_pool", 0},
- { &key_LOCK_parallel_entry, "LOCK_parallel_entry", 0}
+ { &key_LOCK_parallel_entry, "LOCK_parallel_entry", 0},
+ { &key_LOCK_ack_receiver, "Ack_receiver::mutex", 0},
+ { &key_LOCK_binlog, "LOCK_binlog", 0}
};
PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock,
- key_LOCK_SEQUENCE;
-
+ key_LOCK_SEQUENCE,
+ key_rwlock_LOCK_vers_stats, key_rwlock_LOCK_stat_serial;
static PSI_rwlock_info all_server_rwlocks[]=
{
@@ -1040,14 +1057,17 @@ static PSI_rwlock_info all_server_rwlocks[]=
{ &key_rwlock_LOCK_sys_init_slave, "LOCK_sys_init_slave", PSI_FLAG_GLOBAL},
{ &key_LOCK_SEQUENCE, "LOCK_SEQUENCE", 0},
{ &key_rwlock_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
- { &key_rwlock_query_cache_query_lock, "Query_cache_query::lock", 0}
+ { &key_rwlock_query_cache_query_lock, "Query_cache_query::lock", 0},
+ { &key_rwlock_LOCK_vers_stats, "Vers_field_stats::lock", 0},
+ { &key_rwlock_LOCK_stat_serial, "TABLE_SHARE::LOCK_stat_serial", 0}
};
#ifdef HAVE_MMAP
PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool;
#endif /* HAVE_MMAP */
-PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
+PSI_cond_key key_BINLOG_COND_xid_list,
+ key_BINLOG_COND_bin_log_updated, key_BINLOG_COND_relay_log_updated,
key_BINLOG_COND_binlog_background_thread,
key_BINLOG_COND_binlog_background_thread_end,
key_COND_cache_status_changed, key_COND_manager,
@@ -1061,9 +1081,10 @@ PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
key_rpl_group_info_sleep_cond,
key_TABLE_SHARE_cond, key_user_level_lock_cond,
key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache,
- key_COND_start_thread,
+ key_COND_start_thread, key_COND_binlog_send,
key_BINLOG_COND_queue_busy;
-PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready,
+PSI_cond_key key_RELAYLOG_COND_relay_log_updated,
+ key_RELAYLOG_COND_bin_log_updated, key_COND_wakeup_ready,
key_COND_wait_commit;
PSI_cond_key key_RELAYLOG_COND_queue_busy;
PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
@@ -1072,6 +1093,7 @@ PSI_cond_key key_COND_rpl_thread_queue, key_COND_rpl_thread,
key_COND_parallel_entry, key_COND_group_commit_orderer,
key_COND_prepare_ordered, key_COND_slave_background;
PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates;
+PSI_cond_key key_COND_ack_receiver;
static PSI_cond_info all_server_conds[]=
{
@@ -1084,12 +1106,13 @@ static PSI_cond_info all_server_conds[]=
{ &key_COND_pool, "TC_LOG_MMAP::COND_pool", 0},
{ &key_TC_LOG_MMAP_COND_queue_busy, "TC_LOG_MMAP::COND_queue_busy", 0},
#endif /* HAVE_MMAP */
+ { &key_BINLOG_COND_bin_log_updated, "MYSQL_BIN_LOG::COND_bin_log_updated", 0}, { &key_BINLOG_COND_relay_log_updated, "MYSQL_BIN_LOG::COND_relay_log_updated", 0},
{ &key_BINLOG_COND_xid_list, "MYSQL_BIN_LOG::COND_xid_list", 0},
- { &key_BINLOG_update_cond, "MYSQL_BIN_LOG::update_cond", 0},
{ &key_BINLOG_COND_binlog_background_thread, "MYSQL_BIN_LOG::COND_binlog_background_thread", 0},
{ &key_BINLOG_COND_binlog_background_thread_end, "MYSQL_BIN_LOG::COND_binlog_background_thread_end", 0},
{ &key_BINLOG_COND_queue_busy, "MYSQL_BIN_LOG::COND_queue_busy", 0},
- { &key_RELAYLOG_update_cond, "MYSQL_RELAY_LOG::update_cond", 0},
+ { &key_RELAYLOG_COND_relay_log_updated, "MYSQL_RELAY_LOG::COND_relay_log_updated", 0},
+ { &key_RELAYLOG_COND_bin_log_updated, "MYSQL_RELAY_LOG::COND_bin_log_updated", 0},
{ &key_RELAYLOG_COND_queue_busy, "MYSQL_RELAY_LOG::COND_queue_busy", 0},
{ &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0},
{ &key_COND_wait_commit, "wait_for_commit::COND_wait_commit", 0},
@@ -1123,13 +1146,17 @@ static PSI_cond_info all_server_conds[]=
{ &key_COND_slave_background, "COND_slave_background", 0},
{ &key_COND_start_thread, "COND_start_thread", PSI_FLAG_GLOBAL},
{ &key_COND_wait_gtid, "COND_wait_gtid", 0},
- { &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0}
+ { &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0},
+ { &key_COND_ack_receiver, "Ack_receiver::cond", 0},
+ { &key_COND_binlog_send, "COND_binlog_send", 0},
+ { &key_TABLE_SHARE_COND_rotation, "TABLE_SHARE::COND_rotation", 0}
};
PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
key_thread_handle_manager, key_thread_main,
key_thread_one_connection, key_thread_signal_hand,
key_thread_slave_background, key_rpl_parallel_thread;
+PSI_thread_key key_thread_ack_receiver;
static PSI_thread_info all_server_threads[]=
{
@@ -1156,6 +1183,7 @@ static PSI_thread_info all_server_threads[]=
{ &key_thread_one_connection, "one_connection", 0},
{ &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL},
{ &key_thread_slave_background, "slave_background", PSI_FLAG_GLOBAL},
+ { &key_thread_ack_receiver, "Ack_receiver", PSI_FLAG_GLOBAL},
{ &key_rpl_parallel_thread, "rpl_parallel_thread", 0}
};
@@ -1222,7 +1250,7 @@ void net_after_header_psi(struct st_net *net, void *user_data,
{
thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
stmt_info_new_packet.m_key,
- thd->db, thd->db_length,
+ thd->get_db(), thd->db.length,
thd->charset());
THD_STAGE_INFO(thd, stage_init);
@@ -1351,7 +1379,7 @@ private:
void Buffered_logs::init()
{
- init_alloc_root(&m_root, 1024, 0, MYF(0));
+ init_alloc_root(&m_root, "Buffered_logs", 1024, 0, MYF(0));
}
void Buffered_logs::cleanup()
@@ -1633,13 +1661,11 @@ static void close_connections(void)
{
if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
{
- (void) mysql_socket_shutdown(base_ip_sock, SHUT_RDWR);
(void) mysql_socket_close(base_ip_sock);
base_ip_sock= MYSQL_INVALID_SOCKET;
}
if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
{
- (void) mysql_socket_shutdown(extra_ip_sock, SHUT_RDWR);
(void) mysql_socket_close(extra_ip_sock);
extra_ip_sock= MYSQL_INVALID_SOCKET;
}
@@ -1671,7 +1697,6 @@ static void close_connections(void)
#ifdef HAVE_SYS_UN_H
if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
{
- (void) mysql_socket_shutdown(unix_sock, SHUT_RDWR);
(void) mysql_socket_close(unix_sock);
(void) unlink(mysqld_unix_port);
unix_sock= MYSQL_INVALID_SOCKET;
@@ -1708,7 +1733,7 @@ static void close_connections(void)
#endif
tmp->set_killed(KILL_SERVER_HARD);
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
- mysql_mutex_lock(&tmp->LOCK_thd_data);
+ mysql_mutex_lock(&tmp->LOCK_thd_kill);
if (tmp->mysys_var)
{
tmp->mysys_var->abort=1;
@@ -1731,13 +1756,14 @@ static void close_connections(void)
}
mysql_mutex_unlock(&tmp->mysys_var->mutex);
}
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
}
mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
Events::deinit();
slave_prepare_for_shutdown();
mysql_bin_log.stop_background_thread();
+ ack_receiver.stop();
/*
Give threads time to die.
@@ -2049,8 +2075,8 @@ pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
extern "C" sig_handler print_signal_warning(int sig)
{
if (global_system_variables.log_warnings)
- sql_print_warning("Got signal %d from thread %ld", sig,
- (ulong) my_thread_id());
+ sql_print_warning("Got signal %d from thread %u", sig,
+ (uint)my_thread_id());
#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
my_sigset(sig,print_signal_warning); /* int. thread system calls */
#endif
@@ -2167,6 +2193,9 @@ static void mysqld_exit(int exit_code)
(long) global_status_var.global_memory_used);
if (!opt_debugging && !my_disable_leak_check && exit_code == 0)
{
+#ifdef SAFEMALLOC
+ sf_report_leaked_memory(0);
+#endif
DBUG_SLOW_ASSERT(global_status_var.global_memory_used == 0);
}
cleanup_tls();
@@ -2216,7 +2245,9 @@ void clean_up(bool print_message)
ha_end();
if (tc_log)
tc_log->close();
- delegates_destroy();
+#ifdef HAVE_REPLICATION
+ semi_sync_master_deinit();
+#endif
xid_cache_free();
tdc_deinit();
mdl_destroy();
@@ -2338,6 +2369,7 @@ static void clean_up_mutexes()
mysql_mutex_destroy(&LOCK_crypt);
mysql_mutex_destroy(&LOCK_user_conn);
mysql_mutex_destroy(&LOCK_connection_count);
+ mysql_mutex_destroy(&LOCK_thread_id);
mysql_mutex_destroy(&LOCK_stats);
mysql_mutex_destroy(&LOCK_global_user_client_stats);
mysql_mutex_destroy(&LOCK_global_table_stats);
@@ -2357,7 +2389,7 @@ static void clean_up_mutexes()
mysql_rwlock_destroy(&LOCK_sys_init_connect);
mysql_rwlock_destroy(&LOCK_sys_init_slave);
mysql_mutex_destroy(&LOCK_global_system_variables);
- mysql_rwlock_destroy(&LOCK_system_variables_hash);
+ mysql_prlock_destroy(&LOCK_system_variables_hash);
mysql_mutex_destroy(&LOCK_short_uuid_generator);
mysql_mutex_destroy(&LOCK_prepared_stmt_count);
mysql_mutex_destroy(&LOCK_error_messages);
@@ -2478,10 +2510,9 @@ static void set_user(const char *user, struct passwd *user_info_arg)
allow_coredumps();
}
-
+#if !defined(__WIN__)
static void set_effective_user(struct passwd *user_info_arg)
{
-#if !defined(__WIN__)
DBUG_ASSERT(user_info_arg != 0);
if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
{
@@ -2494,9 +2525,8 @@ static void set_effective_user(struct passwd *user_info_arg)
unireg_abort(1);
}
allow_coredumps();
-#endif
}
-
+#endif
/** Change root user if started with @c --chroot . */
static void set_root(const char *path)
@@ -2711,7 +2741,7 @@ static void network_init(void)
#ifdef _WIN32
/* create named pipe */
- if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap &&
+ if (mysqld_unix_port[0] && !opt_bootstrap &&
opt_enable_named_pipe)
{
@@ -2901,16 +2931,17 @@ void unlink_thd(THD *thd)
DBUG_ENTER("unlink_thd");
DBUG_PRINT("enter", ("thd: %p", thd));
+ thd->cleanup();
+ thd->add_status_to_global();
+ unlink_not_visible_thd(thd);
+
/*
Do not decrement when its wsrep system thread. wsrep_applier is set for
applier as well as rollbacker threads.
*/
if (IF_WSREP(!thd->wsrep_applier, 1))
dec_connection_count(thd->scheduler);
- thd->cleanup();
- thd->add_status_to_global();
- unlink_not_visible_thd(thd);
thd->free_connection();
DBUG_VOID_RETURN;
@@ -2948,13 +2979,11 @@ static bool cache_thread(THD *thd)
DBUG_PRINT("info", ("Adding thread to cache"));
cached_thread_count++;
-#ifdef HAVE_PSI_THREAD_INTERFACE
/*
Delete the instrumentation for the job that just completed,
before parking this pthread in the cache (blocked on COND_thread_cache).
*/
- PSI_THREAD_CALL(delete_current_thread)();
-#endif
+ PSI_CALL_delete_current_thread();
#ifndef DBUG_OFF
while (_db_is_pushed_())
@@ -3001,15 +3030,13 @@ static bool cache_thread(THD *thd)
*/
thd->store_globals();
-#ifdef HAVE_PSI_THREAD_INTERFACE
/*
Create new instrumentation for the new THD job,
and attach it to this running pthread.
*/
- PSI_thread *psi= PSI_THREAD_CALL(new_thread)(key_thread_one_connection,
+ PSI_thread *psi= PSI_CALL_new_thread(key_thread_one_connection,
thd, thd->thread_id);
- PSI_THREAD_CALL(set_thread)(psi);
-#endif
+ PSI_CALL_set_thread(psi);
/* reset abort flag for the thread */
thd->mysys_var->abort= 0;
@@ -3540,10 +3567,8 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
if (!abort_loop)
{
abort_loop=1; // mark abort for threads
-#ifdef HAVE_PSI_THREAD_INTERFACE
/* Delete the instrumentation for the signal thread */
- PSI_THREAD_CALL(delete_current_thread)();
-#endif
+ PSI_CALL_delete_current_thread();
#ifdef USE_ONE_SIGNAL_HAND
pthread_t tmp;
if ((error= mysql_thread_create(0, /* Not instrumented */
@@ -3660,8 +3685,6 @@ void my_message_sql(uint error, const char *str, myf MyFlags)
extern "C" void *my_str_malloc_mysqld(size_t size);
-extern "C" void my_str_free_mysqld(void *ptr);
-extern "C" void *my_str_realloc_mysqld(void *ptr, size_t size);
void *my_str_malloc_mysqld(size_t size)
{
@@ -3669,17 +3692,6 @@ void *my_str_malloc_mysqld(size_t size)
}
-void my_str_free_mysqld(void *ptr)
-{
- my_free(ptr);
-}
-
-void *my_str_realloc_mysqld(void *ptr, size_t size)
-{
- return my_realloc(ptr, size, MYF(MY_FAE));
-}
-
-
#ifdef __WIN__
pthread_handler_t handle_shutdown(void *arg)
@@ -3735,14 +3747,8 @@ check_enough_stack_size(int recurse_level)
}
-/*
- Initialize my_str_malloc() and my_str_free()
-*/
static void init_libstrings()
{
- my_str_malloc= &my_str_malloc_mysqld;
- my_str_free= &my_str_free_mysqld;
- my_str_realloc= &my_str_realloc_mysqld;
#ifndef EMBEDDED_LIBRARY
my_string_stack_guard= check_enough_stack_size;
#endif
@@ -3753,7 +3759,7 @@ ulonglong my_pcre_frame_size;
static void init_pcre()
{
pcre_malloc= pcre_stack_malloc= my_str_malloc_mysqld;
- pcre_free= pcre_stack_free= my_str_free_mysqld;
+ pcre_free= pcre_stack_free= my_free;
pcre_stack_guard= check_enough_stack_size_slow;
/* See http://pcre.org/original/doc/html/pcrestack.html */
my_pcre_frame_size= -pcre_exec(NULL, NULL, NULL, -999, -999, 0, NULL, 0);
@@ -4235,10 +4241,12 @@ static int init_common_variables()
constructor (called before main()).
*/
mysql_bin_log.set_psi_keys(key_BINLOG_LOCK_index,
- key_BINLOG_update_cond,
+ key_BINLOG_COND_relay_log_updated,
+ key_BINLOG_COND_bin_log_updated,
key_file_binlog,
key_file_binlog_index,
- key_BINLOG_COND_queue_busy);
+ key_BINLOG_COND_queue_busy,
+ key_LOCK_binlog_end_pos);
#endif
/*
@@ -4252,7 +4260,7 @@ static int init_common_variables()
/* TODO: remove this when my_time_t is 64 bit compatible */
if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time))
{
- sql_print_error("This MySQL server doesn't support dates later then 2038");
+ sql_print_error("This MySQL server doesn't support dates later than 2038");
exit(1);
}
@@ -4710,6 +4718,8 @@ static int init_common_variables()
return 1;
}
+ global_system_variables.in_subquery_conversion_threshold= IN_SUBQUERY_CONVERSION_THRESHOLD;
+
return 0;
}
@@ -4735,7 +4745,7 @@ static int init_thread_environment()
&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
mysql_mutex_record_order(&LOCK_active_mi, &LOCK_global_system_variables);
mysql_mutex_record_order(&LOCK_status, &LOCK_thread_count);
- mysql_rwlock_init(key_rwlock_LOCK_system_variables_hash,
+ mysql_prlock_init(key_rwlock_LOCK_system_variables_hash,
&LOCK_system_variables_hash);
mysql_mutex_init(key_LOCK_prepared_stmt_count,
&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
@@ -4745,6 +4755,8 @@ static int init_thread_environment()
&LOCK_short_uuid_generator, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_connection_count,
&LOCK_connection_count, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_LOCK_thread_id,
+ &LOCK_thread_id, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_stats, &LOCK_stats, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_global_user_client_stats,
&LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST);
@@ -5131,13 +5143,6 @@ static int init_server_components()
xid_cache_init();
- /*
- initialize delegates for extension observers, errors have already
- been reported in the function
- */
- if (delegates_init())
- unireg_abort(1);
-
/* need to configure logging before initializing storage engines */
if (!opt_bin_log_used && !WSREP_ON)
{
@@ -5169,6 +5174,13 @@ static int init_server_components()
"this server. However this will be ignored as the "
"--log-bin option is not defined.");
}
+
+ if (repl_semisync_master.init_object() ||
+ repl_semisync_slave.init_object())
+ {
+ sql_print_error("Could not initialize semisync.");
+ unireg_abort(1);
+ }
#endif
if (opt_bin_log)
@@ -5285,10 +5297,7 @@ static int init_server_components()
{
unireg_abort(1);
}
- }
- if (opt_bin_log)
- {
log_bin_basename=
rpl_make_log_name(opt_bin_logname, pidfile_name,
opt_bin_logname ? "" : "-bin");
@@ -5674,8 +5683,8 @@ static void test_lc_time_sz()
DBUG_ENTER("test_lc_time_sz");
for (MY_LOCALE **loc= my_locales; *loc; loc++)
{
- uint max_month_len= 0;
- uint max_day_len = 0;
+ size_t max_month_len= 0;
+ size_t max_day_len= 0;
for (const char **month= (*loc)->month_names->type_names; *month; month++)
{
set_if_bigger(max_month_len,
@@ -5822,8 +5831,8 @@ int mysqld_main(int argc, char **argv)
*/
init_server_psi_keys();
/* Instrument the main thread */
- PSI_thread *psi= PSI_THREAD_CALL(new_thread)(key_thread_main, NULL, 0);
- PSI_THREAD_CALL(set_thread)(psi);
+ PSI_thread *psi= PSI_CALL_new_thread(key_thread_main, NULL, 0);
+ PSI_CALL_set_thread(psi);
/*
Now that some instrumentation is in place,
@@ -5942,9 +5951,6 @@ int mysqld_main(int argc, char **argv)
#ifdef __WIN__
if (!opt_console)
{
- if (reopen_fstreams(log_error_file, stdout, stderr))
- unireg_abort(1);
- setbuf(stderr, NULL);
FreeConsole(); // Remove window
}
@@ -6106,12 +6112,14 @@ int mysqld_main(int argc, char **argv)
mysqld_port, MYSQL_COMPILATION_COMMENT);
}
+#ifndef _WIN32
// try to keep fd=0 busy
- if (!freopen(IF_WIN("NUL","/dev/null"), "r", stdin))
+ if (!freopen("/dev/null", "r", stdin))
{
// fall back on failure
fclose(stdin);
}
+#endif
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
Service.SetRunning();
@@ -6145,13 +6153,11 @@ int mysqld_main(int argc, char **argv)
mysql_mutex_unlock(&LOCK_start_thread);
#endif /* __WIN__ */
-#ifdef HAVE_PSI_THREAD_INTERFACE
/*
Disable the main thread instrumentation,
to avoid recording events during the shutdown.
*/
- PSI_THREAD_CALL(delete_current_thread)();
-#endif
+ PSI_CALL_delete_current_thread();
/* Wait until cleanup is done */
mysql_mutex_lock(&LOCK_thread_count);
@@ -6160,7 +6166,7 @@ int mysqld_main(int argc, char **argv)
mysql_mutex_unlock(&LOCK_thread_count);
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
- if (Service.IsNT() && start_mode)
+ if (start_mode)
Service.Stop();
else
{
@@ -6185,10 +6191,10 @@ int mysqld_main(int argc, char **argv)
****************************************************************************/
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
-int mysql_service(void *p)
+void mysql_service(void *p)
{
if (my_thread_init())
- return 1;
+ abort();
if (use_opt_args)
win_main(opt_argc, opt_argv);
@@ -6196,7 +6202,6 @@ int mysql_service(void *p)
win_main(Service.my_argc, Service.my_argv);
my_thread_end();
- return 0;
}
@@ -6247,7 +6252,7 @@ default_service_handling(char **argv,
the option name) should be quoted if it contains a string.
*/
*pos++= ' ';
- if (opt_delim= strchr(extra_opt, '='))
+ if ((opt_delim= strchr(extra_opt, '=')))
{
size_t length= ++opt_delim - extra_opt;
pos= strnmov(pos, extra_opt, length);
@@ -6303,87 +6308,86 @@ int mysqld_main(int argc, char **argv)
return 1;
}
- if (Service.GetOS()) /* true NT family */
+
+ char file_path[FN_REFLEN];
+ my_path(file_path, argv[0], ""); /* Find name in path */
+ fn_format(file_path,argv[0],file_path,"", MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
+
+ if (argc == 2)
{
- char file_path[FN_REFLEN];
- my_path(file_path, argv[0], ""); /* Find name in path */
- fn_format(file_path,argv[0],file_path,"",
- MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
+ if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
+ file_path, "", NULL))
+ return 0;
- if (argc == 2)
- {
- if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
- file_path, "", NULL))
- return 0;
- if (Service.IsService(argv[1])) /* Start an optional service */
- {
- /*
- Only add the service name to the groups read from the config file
- if it's not "MySQL". (The default service name should be 'mysqld'
- but we started a bad tradition by calling it MySQL from the start
- and we are now stuck with it.
- */
- if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
- load_default_groups[load_default_groups_sz-2]= argv[1];
- start_mode= 1;
- Service.Init(argv[1], mysql_service);
- return 0;
- }
- }
- else if (argc == 3) /* install or remove any optional service */
- {
- if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
- NULL))
- return 0;
- if (Service.IsService(argv[2]))
- {
- /*
- mysqld was started as
- mysqld --defaults-file=my_path\my.ini service-name
- */
- use_opt_args=1;
- opt_argc= 2; // Skip service-name
- opt_argv=argv;
- start_mode= 1;
- if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
- load_default_groups[load_default_groups_sz-2]= argv[2];
- Service.Init(argv[2], mysql_service);
- return 0;
- }
- }
- else if (argc == 4 || argc == 5)
+ if (Service.IsService(argv[1])) /* Start an optional service */
{
/*
- This may seem strange, because we handle --local-service while
- preserving 4.1's behavior of allowing any one other argument that is
- passed to the service on startup. (The assumption is that this is
- --defaults-file=file, but that was not enforced in 4.1, so we don't
- enforce it here.)
+ Only add the service name to the groups read from the config file
+ if it's not "MySQL". (The default service name should be 'mysqld'
+ but we started a bad tradition by calling it MySQL from the start
+ and we are now stuck with it.
*/
- const char *extra_opt= NullS;
- const char *account_name = NullS;
- int index;
- for (index = 3; index < argc; index++)
- {
- if (!strcmp(argv[index], "--local-service"))
- account_name= "NT AUTHORITY\\LocalService";
- else
- extra_opt= argv[index];
- }
-
- if (argc == 4 || account_name)
- if (!default_service_handling(argv, argv[2], argv[2], file_path,
- extra_opt, account_name))
- return 0;
+ if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
+ load_default_groups[load_default_groups_sz-2]= argv[1];
+ start_mode= 1;
+ Service.Init(argv[1], mysql_service);
+ return 0;
}
- else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
+ }
+ else if (argc == 3) /* install or remove any optional service */
+ {
+ if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
+ NULL))
+ return 0;
+ if (Service.IsService(argv[2]))
{
- /* start the default service */
+ /*
+ mysqld was started as
+ mysqld --defaults-file=my_path\my.ini service-name
+ */
+ use_opt_args=1;
+ opt_argc= 2; // Skip service-name
+ opt_argv=argv;
start_mode= 1;
- Service.Init(MYSQL_SERVICENAME, mysql_service);
+ if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
+ load_default_groups[load_default_groups_sz-2]= argv[2];
+ Service.Init(argv[2], mysql_service);
return 0;
}
}
+ else if (argc == 4 || argc == 5)
+ {
+ /*
+ This may seem strange, because we handle --local-service while
+ preserving 4.1's behavior of allowing any one other argument that is
+ passed to the service on startup. (The assumption is that this is
+ --defaults-file=file, but that was not enforced in 4.1, so we don't
+ enforce it here.)
+ */
+ const char *extra_opt= NullS;
+ const char *account_name = NullS;
+ int index;
+ for (index = 3; index < argc; index++)
+ {
+ if (!strcmp(argv[index], "--local-service"))
+ account_name= "NT AUTHORITY\\LocalService";
+ else
+ extra_opt= argv[index];
+ }
+
+ if (argc == 4 || account_name)
+ if (!default_service_handling(argv, argv[2], argv[2], file_path,
+ extra_opt, account_name))
+ return 0;
+ }
+ else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
+ {
+ /* start the default service */
+ start_mode= 1;
+ Service.Init(MYSQL_SERVICENAME, mysql_service);
+ return 0;
+ }
+
/* Start as standalone server */
Service.my_argc=argc;
Service.my_argv=argv;
@@ -7317,7 +7321,7 @@ struct my_option my_long_options[]=
"The value has to be a multiple of 256.",
&opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size,
0, GET_ULONG, REQUIRED_ARG,
- /* def_value */ 8192, /* min_value */ 256, /* max_value */ ULONG_MAX,
+ /* def_value */ 8192, /* min_value */ 256, /* max_value */ UINT_MAX32-1,
/* sub_size */ 0, /* block_size */ 256,
/* app_type */ 0
},
@@ -7759,6 +7763,7 @@ struct my_option my_long_options[]=
MYSQL_SUGGEST_ANALOG_OPTION("max-binlog-dump-events", "--debug-max-binlog-dump-events"),
MYSQL_SUGGEST_ANALOG_OPTION("sporadic-binlog-dump-fail", "--debug-sporadic-binlog-dump-fail"),
MYSQL_COMPATIBILITY_OPTION("new"),
+ MYSQL_COMPATIBILITY_OPTION("show_compatibility_56"),
/* The following options were added after 5.6.10 */
MYSQL_TO_BE_IMPLEMENTED_OPTION("rpl-stop-slave-timeout"),
@@ -8231,6 +8236,27 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff,
return 0;
}
+#define SHOW_FNAME(name) \
+ rpl_semi_sync_master_show_##name
+
+#define DEF_SHOW_FUNC(name, show_type) \
+ static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, char *buff) \
+ { \
+ repl_semisync_master.set_export_stats(); \
+ var->type= show_type; \
+ var->value= (char *)&rpl_semi_sync_master_##name; \
+ return 0; \
+ }
+
+DEF_SHOW_FUNC(status, SHOW_BOOL)
+DEF_SHOW_FUNC(clients, SHOW_LONG)
+DEF_SHOW_FUNC(wait_sessions, SHOW_LONG)
+DEF_SHOW_FUNC(trx_wait_time, SHOW_LONGLONG)
+DEF_SHOW_FUNC(trx_wait_num, SHOW_LONGLONG)
+DEF_SHOW_FUNC(net_wait_time, SHOW_LONGLONG)
+DEF_SHOW_FUNC(net_wait_num, SHOW_LONGLONG)
+DEF_SHOW_FUNC(avg_net_wait_time, SHOW_LONG)
+DEF_SHOW_FUNC(avg_trx_wait_time, SHOW_LONG)
#ifdef HAVE_YASSL
@@ -8491,6 +8517,7 @@ SHOW_VAR status_vars[]= {
{"Feature_dynamic_columns", (char*) offsetof(STATUS_VAR, feature_dynamic_columns), SHOW_LONG_STATUS},
{"Feature_fulltext", (char*) offsetof(STATUS_VAR, feature_fulltext), SHOW_LONG_STATUS},
{"Feature_gis", (char*) offsetof(STATUS_VAR, feature_gis), SHOW_LONG_STATUS},
+ {"Feature_invisible_columns", (char*) offsetof(STATUS_VAR, feature_invisible_columns), SHOW_LONG_STATUS},
{"Feature_locale", (char*) offsetof(STATUS_VAR, feature_locale), SHOW_LONG_STATUS},
{"Feature_subquery", (char*) offsetof(STATUS_VAR, feature_subquery), SHOW_LONG_STATUS},
{"Feature_timezone", (char*) offsetof(STATUS_VAR, feature_timezone), SHOW_LONG_STATUS},
@@ -8501,7 +8528,7 @@ SHOW_VAR status_vars[]= {
{"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
{"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
{"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
- {"Handler_external_lock", (char*) offsetof(STATUS_VAR, ha_external_lock_count), SHOW_LONGLONG_STATUS},
+ {"Handler_external_lock", (char*) offsetof(STATUS_VAR, ha_external_lock_count), SHOW_LONG_STATUS},
{"Handler_icp_attempts", (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS},
{"Handler_icp_match", (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS},
{"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_mrr_init_count), SHOW_LONG_STATUS},
@@ -8548,6 +8575,26 @@ SHOW_VAR status_vars[]= {
{"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS},
{"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS},
{"Rows_tmp_read", (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS},
+#ifdef HAVE_REPLICATION
+ {"Rpl_semi_sync_master_status", (char*) &SHOW_FNAME(status), SHOW_FUNC},
+ {"Rpl_semi_sync_master_clients", (char*) &SHOW_FNAME(clients), SHOW_FUNC},
+ {"Rpl_semi_sync_master_yes_tx", (char*) &rpl_semi_sync_master_yes_transactions, SHOW_LONG},
+ {"Rpl_semi_sync_master_no_tx", (char*) &rpl_semi_sync_master_no_transactions, SHOW_LONG},
+ {"Rpl_semi_sync_master_wait_sessions", (char*) &SHOW_FNAME(wait_sessions), SHOW_FUNC},
+ {"Rpl_semi_sync_master_no_times", (char*) &rpl_semi_sync_master_off_times, SHOW_LONG},
+ {"Rpl_semi_sync_master_timefunc_failures", (char*) &rpl_semi_sync_master_timefunc_fails, SHOW_LONG},
+ {"Rpl_semi_sync_master_wait_pos_backtraverse", (char*) &rpl_semi_sync_master_wait_pos_backtraverse, SHOW_LONG},
+ {"Rpl_semi_sync_master_tx_wait_time", (char*) &SHOW_FNAME(trx_wait_time), SHOW_FUNC},
+ {"Rpl_semi_sync_master_tx_waits", (char*) &SHOW_FNAME(trx_wait_num), SHOW_FUNC},
+ {"Rpl_semi_sync_master_tx_avg_wait_time", (char*) &SHOW_FNAME(avg_trx_wait_time), SHOW_FUNC},
+ {"Rpl_semi_sync_master_net_wait_time", (char*) &SHOW_FNAME(net_wait_time), SHOW_FUNC},
+ {"Rpl_semi_sync_master_net_waits", (char*) &SHOW_FNAME(net_wait_num), SHOW_FUNC},
+ {"Rpl_semi_sync_master_net_avg_wait_time", (char*) &SHOW_FNAME(avg_net_wait_time), SHOW_FUNC},
+ {"Rpl_semi_sync_master_request_ack", (char*) &rpl_semi_sync_master_request_ack, SHOW_LONGLONG},
+ {"Rpl_semi_sync_master_get_ack", (char*)&rpl_semi_sync_master_get_ack, SHOW_LONGLONG},
+ {"Rpl_semi_sync_slave_status", (char*) &rpl_semi_sync_slave_status, SHOW_BOOL},
+ {"Rpl_semi_sync_slave_send_ack", (char*) &rpl_semi_sync_slave_send_ack, SHOW_LONGLONG},
+#endif /* HAVE_REPLICATION */
#ifdef HAVE_QUERY_CACHE
{"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
{"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
@@ -8640,7 +8687,7 @@ SHOW_VAR status_vars[]= {
{"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_NOFLUSH},
{"Threads_connected", (char*) &connection_count, SHOW_INT},
{"Threads_created", (char*) &thread_created, SHOW_LONG_NOFLUSH},
- {"Threads_running", (char*) &thread_running, SHOW_INT},
+ {"Threads_running", (char*) offsetof(STATUS_VAR, threads_running), SHOW_UINT32_STATUS},
{"Transactions_multi_engine", (char*) &transactions_multi_engine, SHOW_LONG},
{"Rpl_transactions_multi_engine", (char*) &rpl_transactions_multi_engine, SHOW_LONG},
{"Transactions_gtid_foreign_engine", (char*) &transactions_gtid_foreign_engine, SHOW_LONG},
@@ -8708,7 +8755,7 @@ static int option_cmp(my_option *a, my_option *b)
static void print_help()
{
MEM_ROOT mem_root;
- init_alloc_root(&mem_root, 4096, 4096, MYF(0));
+ init_alloc_root(&mem_root, "help", 4096, 4096, MYF(0));
pop_dynamic(&all_options);
add_many_options(&all_options, pfs_early_options,
@@ -8817,7 +8864,7 @@ static int mysql_init_variables(void)
kill_in_progress= 0;
cleanup_done= 0;
test_flags= select_errors= dropping_tables= ha_open_options=0;
- thread_count= thread_running= kill_cached_threads= wake_thread= 0;
+ thread_count= kill_cached_threads= wake_thread= 0;
service_thread_count= 0;
slave_open_temp_tables= 0;
cached_thread_count= 0;
@@ -8862,7 +8909,7 @@ static int mysql_init_variables(void)
denied_connections= 0;
executed_events= 0;
global_query_id= 1;
- global_thread_id= 1;
+ global_thread_id= 0;
strnmov(server_version, MYSQL_SERVER_VERSION, sizeof(server_version)-1);
threads.empty();
thread_cache.empty();
@@ -9044,12 +9091,12 @@ mysqld_get_one_option(int optid, const struct my_option *opt, char *argument)
opt->name);
break;
case OPT_MYSQL_COMPATIBILITY:
- sql_print_warning("'%s' is MySQL 5.6 compatible option. Not used or needed "
- "in MariaDB.", opt->name);
+ sql_print_warning("'%s' is MySQL 5.6 / 5.7 compatible option. Not used or "
+ "needed in MariaDB.", opt->name);
break;
case OPT_MYSQL_TO_BE_IMPLEMENTED:
- sql_print_warning("'%s' is MySQL 5.6 compatible option. To be implemented "
- "in later versions.", opt->name);
+ sql_print_warning("'%s' is MySQL 5.6 / 5.7 compatible option. To be "
+ "implemented in later versions.", opt->name);
break;
case 'a':
SYSVAR_AUTOSIZE(global_system_variables.sql_mode, MODE_ANSI);
@@ -9637,8 +9684,10 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
flush_time= 0;
#ifdef HAVE_REPLICATION
- if (opt_slave_skip_errors)
- init_slave_skip_errors(opt_slave_skip_errors);
+ if (init_slave_skip_errors(opt_slave_skip_errors))
+ return 1;
+ if (init_slave_transaction_retry_errors(opt_slave_transaction_retry_errors))
+ return 1;
#endif
if (global_system_variables.max_join_size == HA_POS_ERROR)
@@ -9805,7 +9854,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
/* Ensure that some variables are not set higher than needed */
if (thread_cache_size > max_connections)
SYSVAR_AUTOSIZE(thread_cache_size, max_connections);
-
+
return 0;
}
@@ -9953,7 +10002,7 @@ static int fix_paths(void)
my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
mysql_unpacked_real_data_home_len=
- (int) strlen(mysql_unpacked_real_data_home);
+ strlen(mysql_unpacked_real_data_home);
if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
--mysql_unpacked_real_data_home_len;
@@ -10283,6 +10332,10 @@ PSI_stage_info stage_waiting_for_insert= { 0, "Waiting for INSERT", 0};
PSI_stage_info stage_waiting_for_master_to_send_event= { 0, "Waiting for master to send event", 0};
PSI_stage_info stage_waiting_for_master_update= { 0, "Waiting for master update", 0};
PSI_stage_info stage_waiting_for_relay_log_space= { 0, "Waiting for the slave SQL thread to free enough relay log space", 0};
+PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave=
+{ 0, "Waiting for semi-sync ACK from slave", 0};
+PSI_stage_info stage_waiting_for_semi_sync_slave={ 0, "Waiting for semi-sync slave connection", 0};
+PSI_stage_info stage_reading_semi_sync_ack={ 0, "Reading semi-sync ACK from slave", 0};
PSI_stage_info stage_waiting_for_slave_mutex_on_exit= { 0, "Waiting for slave mutex on exit", 0};
PSI_stage_info stage_waiting_for_slave_thread_to_start= { 0, "Waiting for slave thread to start", 0};
PSI_stage_info stage_waiting_for_table_flush= { 0, "Waiting for table flush", 0};
@@ -10443,6 +10496,9 @@ PSI_stage_info *all_server_stages[]=
& stage_gtid_wait_other_connection,
& stage_slave_background_process_request,
& stage_slave_background_wait_request,
+ & stage_waiting_for_semi_sync_ack_from_slave,
+ & stage_waiting_for_semi_sync_slave,
+ & stage_reading_semi_sync_ack,
& stage_waiting_for_deadlock_kill
};
@@ -10539,3 +10595,96 @@ void init_server_psi_keys(void)
}
#endif /* HAVE_PSI_INTERFACE */
+
+
+/*
+ Connection ID allocation.
+
+ We need to maintain thread_ids in the 32bit range,
+ because this is how it is passed to the client in the protocol.
+
+ The idea is to maintain a id range, initially set to
+ (0,UINT32_MAX). Whenever new id is needed, we increment the
+ lower limit and return its new value.
+
+ On "overflow", if id can not be generated anymore(i.e lower == upper -1),
+ we recalculate the range boundaries.
+ To do that, we first collect thread ids that are in use, by traversing
+ THD list, and find largest region within (0,UINT32_MAX), that is still free.
+
+*/
+
+static my_thread_id thread_id_max= UINT_MAX32;
+
+#include <vector>
+#include <algorithm>
+
+/*
+ Find largest unused thread_id range.
+
+ i.e for every number N within the returned range,
+ there is no existing connection with thread_id equal to N.
+
+ The range is exclusive, lower bound is always >=0 and
+ upper bound <=MAX_UINT32.
+
+ @param[out] low - lower bound for the range
+ @param[out] high - upper bound for the range
+*/
+static void recalculate_thread_id_range(my_thread_id *low, my_thread_id *high)
+{
+ std::vector<my_thread_id> ids;
+
+ // Add sentinels
+ ids.push_back(0);
+ ids.push_back(UINT_MAX32);
+
+ mysql_mutex_lock(&LOCK_thread_count);
+
+ I_List_iterator<THD> it(threads);
+ THD *thd;
+ while ((thd=it++))
+ ids.push_back(thd->thread_id);
+
+ mysql_mutex_unlock(&LOCK_thread_count);
+
+ std::sort(ids.begin(), ids.end());
+ my_thread_id max_gap= 0;
+ for (size_t i= 0; i < ids.size() - 1; i++)
+ {
+ my_thread_id gap= ids[i+1] - ids[i];
+ if (gap > max_gap)
+ {
+ *low= ids[i];
+ *high= ids[i+1];
+ max_gap= gap;
+ }
+ }
+
+ if (max_gap < 2)
+ {
+ /* Can't find free id. This is not really possible,
+ we'd need 2^32 connections for this to happen.*/
+ sql_print_error("Cannot find free connection id.");
+ abort();
+ }
+}
+
+
+my_thread_id next_thread_id(void)
+{
+ my_thread_id retval;
+ DBUG_EXECUTE_IF("thread_id_overflow", global_thread_id= thread_id_max-2;);
+
+ mysql_mutex_lock(&LOCK_thread_id);
+
+ if (unlikely(global_thread_id == thread_id_max - 1))
+ {
+ recalculate_thread_id_range(&global_thread_id, &thread_id_max);
+ }
+
+ retval= ++global_thread_id;
+
+ mysql_mutex_unlock(&LOCK_thread_id);
+ return retval;
+}
diff --git a/sql/mysqld.h b/sql/mysqld.h
index e09b6486e02..069ad85dd16 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -37,7 +37,6 @@ class Time_zone;
struct scheduler_functions;
-typedef struct st_mysql_const_lex_string LEX_CSTRING;
typedef struct st_mysql_show_var SHOW_VAR;
#if MAX_INDEXES <= 64
@@ -179,6 +178,36 @@ extern char *opt_backup_history_logname, *opt_backup_progress_logname,
*opt_backup_settings_name;
extern const char *log_output_str;
extern const char *log_backup_output_str;
+
+/* System Versioning begin */
+enum vers_system_time_t
+{
+ SYSTEM_TIME_UNSPECIFIED = 0,
+ SYSTEM_TIME_AS_OF,
+ SYSTEM_TIME_FROM_TO,
+ SYSTEM_TIME_BETWEEN,
+ SYSTEM_TIME_BEFORE,
+ SYSTEM_TIME_ALL
+};
+
+struct vers_asof_timestamp_t
+{
+ ulong type;
+ MYSQL_TIME ltime;
+ vers_asof_timestamp_t() :
+ type(SYSTEM_TIME_UNSPECIFIED)
+ {}
+};
+
+enum vers_alter_history_enum
+{
+ VERS_ALTER_HISTORY_ERROR= 0,
+ VERS_ALTER_HISTORY_KEEP,
+ VERS_ALTER_HISTORY_SURVIVE,
+ VERS_ALTER_HISTORY_DROP
+};
+/* System Versioning end */
+
extern char *mysql_home_ptr, *pidfile_name_ptr;
extern MYSQL_PLUGIN_IMPORT char glob_hostname[FN_REFLEN];
extern char mysql_home[FN_REFLEN];
@@ -208,6 +237,7 @@ extern my_bool slave_allow_batching;
extern my_bool allow_slave_start;
extern LEX_CSTRING reason_slave_blocked;
extern ulong slave_trans_retries;
+extern ulong slave_trans_retry_interval;
extern uint slave_net_timeout;
extern int max_user_connections;
extern volatile ulong cached_thread_count;
@@ -235,7 +265,7 @@ extern "C" MYSQL_PLUGIN_IMPORT ulong server_id;
extern ulong concurrency;
extern time_t server_start_time, flush_status_time;
extern char *opt_mysql_tmpdir, mysql_charsets_dir[];
-extern int mysql_unpacked_real_data_home_len;
+extern size_t mysql_unpacked_real_data_home_len;
extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
extern const char *first_keyword, *delayed_user, *binary_keyword;
extern MYSQL_PLUGIN_IMPORT const char *my_localhost;
@@ -288,7 +318,7 @@ extern PSI_mutex_key key_LOCK_des_key_file;
extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_BINLOG_LOCK_binlog_background_thread,
- m_key_LOCK_binlog_end_pos,
+ key_LOCK_binlog_end_pos,
key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log,
@@ -308,18 +338,22 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_LOCK_start_thread,
key_LOCK_error_messages, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc;
extern PSI_mutex_key key_RELAYLOG_LOCK_index;
+extern PSI_mutex_key key_LOCK_relaylog_end_pos;
extern PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state,
key_LOCK_rpl_thread, key_LOCK_rpl_thread_pool, key_LOCK_parallel_entry;
extern PSI_mutex_key key_TABLE_SHARE_LOCK_share, key_LOCK_stats,
key_LOCK_global_user_client_stats, key_LOCK_global_table_stats,
- key_LOCK_global_index_stats, key_LOCK_wakeup_ready, key_LOCK_wait_commit;
+ key_LOCK_global_index_stats, key_LOCK_wakeup_ready, key_LOCK_wait_commit,
+ key_TABLE_SHARE_LOCK_rotation;
extern PSI_mutex_key key_LOCK_gtid_waiting;
extern PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock,
- key_LOCK_SEQUENCE;
+ key_LOCK_SEQUENCE,
+ key_rwlock_LOCK_vers_stats, key_rwlock_LOCK_stat_serial;
+
#ifdef HAVE_MMAP
extern PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool;
#endif /* HAVE_MMAP */
@@ -339,7 +373,8 @@ extern PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
key_TABLE_SHARE_cond, key_user_level_lock_cond,
key_COND_start_thread,
key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache;
-extern PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready,
+extern PSI_cond_key key_RELAYLOG_COND_relay_log_updated,
+ key_RELAYLOG_COND_bin_log_updated, key_COND_wakeup_ready,
key_COND_wait_commit;
extern PSI_cond_key key_RELAYLOG_COND_queue_busy;
extern PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
@@ -347,6 +382,7 @@ extern PSI_cond_key key_COND_rpl_thread, key_COND_rpl_thread_queue,
key_COND_rpl_thread_stop, key_COND_rpl_thread_pool,
key_COND_parallel_entry, key_COND_group_commit_orderer;
extern PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates;
+extern PSI_cond_key key_TABLE_SHARE_COND_rotation;
extern PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
key_thread_handle_manager, key_thread_kill_server, key_thread_main,
@@ -590,11 +626,10 @@ extern mysql_mutex_t LOCK_des_key_file;
extern mysql_mutex_t LOCK_server_started;
extern mysql_cond_t COND_server_started;
extern mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
-extern mysql_rwlock_t LOCK_system_variables_hash;
+extern mysql_prlock_t LOCK_system_variables_hash;
extern mysql_cond_t COND_thread_count, COND_start_thread;
extern mysql_cond_t COND_manager;
extern mysql_cond_t COND_slave_background;
-extern int32 thread_running;
extern int32 thread_count, service_thread_count;
extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
@@ -737,15 +772,7 @@ inline query_id_t get_query_id()
}
/* increment global_thread_id and return it. */
-inline __attribute__((warn_unused_result)) my_thread_id next_thread_id()
-{
- return my_atomic_add64_explicit((int64*) &global_thread_id, 1, MY_MEMORY_ORDER_RELAXED);
-}
-
-#if defined(MYSQL_DYNAMIC_PLUGIN) && defined(_WIN32)
-extern "C" my_thread_id next_thread_id_noinline();
-#define next_thread_id() next_thread_id_noinline()
-#endif
+extern __attribute__((warn_unused_result)) my_thread_id next_thread_id(void);
/*
TODO: Replace this with an inline function.
@@ -784,16 +811,6 @@ inline void thread_safe_decrement64(int64 *value)
(void) my_atomic_add64_explicit(value, -1, MY_MEMORY_ORDER_RELAXED);
}
-inline void inc_thread_running()
-{
- thread_safe_increment32(&thread_running);
-}
-
-inline void dec_thread_running()
-{
- thread_safe_decrement32(&thread_running);
-}
-
extern void set_server_version(char *buf, size_t size);
#define current_thd _current_thd()
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index fd0139c1e03..4c3771bc710 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2012, 2017, MariaDB Corporation
+ Copyright (c) 2012, 2018, 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
@@ -53,6 +53,7 @@
#ifdef EXTRA_DEBUG
#define EXTRA_DEBUG_fprintf fprintf
#define EXTRA_DEBUG_fflush fflush
+#define EXTRA_DEBUG_ASSERT DBUG_ASSERT
#else
static void inline EXTRA_DEBUG_fprintf(...) {}
#ifndef MYSQL_SERVER
@@ -68,6 +69,9 @@ static int inline EXTRA_DEBUG_fflush(...) { return 0; }
static void inline MYSQL_SERVER_my_error(...) {}
#endif
+#ifndef EXTRA_DEBUG_ASSERT
+# define EXTRA_DEBUG_ASSERT(X) do {} while(0)
+#endif
/*
The following handles the differences when this is linked between the
@@ -104,7 +108,7 @@ extern uint test_flags;
extern ulong bytes_sent, bytes_received, net_big_packet_count;
#ifdef HAVE_QUERY_CACHE
#define USE_QUERY_CACHE
-extern void query_cache_insert(void *thd, const char *packet, ulong length,
+extern void query_cache_insert(void *thd, const char *packet, size_t length,
unsigned pkt_nr);
#endif // HAVE_QUERY_CACHE
#define update_statistics(A) A
@@ -117,7 +121,7 @@ extern my_bool thd_net_is_killed();
#endif
-static my_bool net_write_buff(NET *, const uchar *, ulong);
+static my_bool net_write_buff(NET *, const uchar *, size_t len);
my_bool net_allocate_new_packet(NET *net, void *thd, uint my_flags);
@@ -542,13 +546,13 @@ net_write_command(NET *net,uchar command,
*/
static my_bool
-net_write_buff(NET *net, const uchar *packet, ulong len)
+net_write_buff(NET *net, const uchar *packet, size_t len)
{
- ulong left_length;
+ size_t left_length;
if (net->compress && net->max_packet > MAX_PACKET_LENGTH)
- left_length= (ulong) (MAX_PACKET_LENGTH - (net->write_pos - net->buff));
+ left_length= (MAX_PACKET_LENGTH - (net->write_pos - net->buff));
else
- left_length= (ulong) (net->buff_end - net->write_pos);
+ left_length= (net->buff_end - net->write_pos);
#ifdef DEBUG_DATA_PACKETS
DBUG_DUMP("data_written", packet, len);
@@ -1034,7 +1038,7 @@ retry:
#endif
if (i == 0)
{ /* First parts is packet length */
- ulong helping;
+ size_t helping;
#ifndef DEBUG_DATA_PACKETS
DBUG_DUMP("packet_header", net->buff+net->where_b,
NET_HEADER_SIZE);
@@ -1160,7 +1164,7 @@ packets_out_of_order:
("Packets out of order (Found: %d, expected %u)",
(int) net->buff[net->where_b + 3],
net->pkt_nr));
- DBUG_ASSERT(0);
+ EXTRA_DEBUG_ASSERT(0);
/*
We don't make noise server side, since the client is expected
to break the protocol for e.g. --send LOAD DATA .. LOCAL where
@@ -1238,7 +1242,7 @@ my_net_read_packet_reallen(NET *net, my_bool read_from_server, ulong* reallen)
size_t total_length= 0;
do
{
- net->where_b += len;
+ net->where_b += (ulong)len;
total_length += len;
len = my_real_read(net,&complen, 0);
} while (len == MAX_PACKET_LENGTH);
@@ -1251,10 +1255,10 @@ my_net_read_packet_reallen(NET *net, my_bool read_from_server, ulong* reallen)
if (len != packet_error)
{
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
- *reallen = len;
+ *reallen = (ulong)len;
}
MYSQL_NET_READ_DONE(0, len);
- return len;
+ return (ulong)len;
#ifdef HAVE_COMPRESS
}
else
@@ -1352,7 +1356,7 @@ my_net_read_packet_reallen(NET *net, my_bool read_from_server, ulong* reallen)
MYSQL_NET_READ_DONE(1, 0);
return packet_error;
}
- buf_length+= complen;
+ buf_length+= (ulong)complen;
*reallen += packet_len;
}
@@ -1366,7 +1370,7 @@ my_net_read_packet_reallen(NET *net, my_bool read_from_server, ulong* reallen)
}
#endif /* HAVE_COMPRESS */
MYSQL_NET_READ_DONE(0, len);
- return len;
+ return (ulong)len;
}
diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc
index e05e43a0a59..9c754763aab 100644
--- a/sql/nt_servc.cc
+++ b/sql/nt_servc.cc
@@ -64,19 +64,6 @@ NTService::~NTService()
-------------------------------------------------------------------------- */
-BOOL NTService::GetOS()
-{
- bOsNT = FALSE;
- memset(&osVer, 0, sizeof(OSVERSIONINFO));
- osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (GetVersionEx(&osVer))
- {
- if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT)
- bOsNT = TRUE;
- }
- return bOsNT;
-}
-
/**
Registers the main service thread with the service manager.
@@ -86,18 +73,18 @@ BOOL NTService::GetOS()
*/
-long NTService::Init(LPCSTR szInternName,void *ServiceThread)
+long NTService::Init(LPCSTR szInternName, THREAD_FC ServiceThread)
{
pService = this;
- fpServiceThread = (THREAD_FC)ServiceThread;
+ fpServiceThread = ServiceThread;
ServiceName = new char[lstrlen(szInternName)+1];
lstrcpy(ServiceName,szInternName);
SERVICE_TABLE_ENTRY stb[] =
{
- { (char *)szInternName,(LPSERVICE_MAIN_FUNCTION) ServiceMain} ,
+ { (char *)szInternName, ServiceMain} ,
{ NULL, NULL }
};
@@ -232,7 +219,6 @@ void NTService::ServiceMain(DWORD argc, LPTSTR *argv)
// registration function
if (!(pService->hServiceStatusHandle =
RegisterServiceCtrlHandler(pService->ServiceName,
- (LPHANDLER_FUNCTION)
NTService::ServiceCtrlHandler)))
goto error;
@@ -293,7 +279,7 @@ void NTService::SetSlowStarting(unsigned long timeout)
BOOL NTService::StartService()
{
// Start the real service's thread (application)
- if (!(hThreadHandle = (HANDLE) _beginthread((THREAD_FC)fpServiceThread,0,
+ if (!(hThreadHandle = (HANDLE) _beginthread(fpServiceThread,0,
(void *) this)))
return FALSE;
bRunning = TRUE;
diff --git a/sql/nt_servc.h b/sql/nt_servc.h
index 6781fe0ddfa..8ba29519c8f 100644
--- a/sql/nt_servc.h
+++ b/sql/nt_servc.h
@@ -45,10 +45,8 @@ class NTService
int nError;
DWORD dwState;
- BOOL GetOS(); // returns TRUE if WinNT
- BOOL IsNT() { return bOsNT;}
//init service entry point
- long Init(LPCSTR szInternName,void *ServiceThread);
+ long Init(LPCSTR szInternName,THREAD_FC ServiceThread);
//application shutdown event
void SetShutdownEvent(HANDLE hEvent){ hShutdownEvent=hEvent; }
@@ -101,8 +99,8 @@ class NTService
void StopService();
BOOL StartService();
- static void ServiceMain(DWORD argc, LPTSTR *argv);
- static void ServiceCtrlHandler (DWORD ctrlCode);
+ static void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
+ static void WINAPI ServiceCtrlHandler (DWORD ctrlCode);
void Exit(DWORD error);
BOOL SetStatus (DWORD dwCurrentState,DWORD dwWin32ExitCode,
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 3180c509737..38dbed92a22 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1236,7 +1236,8 @@ QUICK_SELECT_I::QUICK_SELECT_I()
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
bool no_alloc, MEM_ROOT *parent_alloc,
bool *create_error)
- :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
+ :thd(thd), no_alloc(no_alloc), parent_alloc(parent_alloc),
+ free_file(0),cur_range(NULL),last_range(0),dont_free(0)
{
my_bitmap_map *bitmap;
DBUG_ENTER("QUICK_RANGE_SELECT::QUICK_RANGE_SELECT");
@@ -1253,7 +1254,8 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
if (!no_alloc && !parent_alloc)
{
// Allocates everything through the internal memroot
- init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0,
+ init_sql_alloc(&alloc, "QUICK_RANGE_SELECT",
+ thd->variables.range_alloc_block_size, 0,
MYF(MY_THREAD_SPECIFIC));
thd->mem_root= &alloc;
}
@@ -1350,7 +1352,8 @@ QUICK_INDEX_SORT_SELECT::QUICK_INDEX_SORT_SELECT(THD *thd_param,
index= MAX_KEY;
head= table;
bzero(&read_record, sizeof(read_record));
- init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0,
+ init_sql_alloc(&alloc, "QUICK_INDEX_SORT_SELECT",
+ thd->variables.range_alloc_block_size, 0,
MYF(MY_THREAD_SPECIFIC));
DBUG_VOID_RETURN;
}
@@ -1421,7 +1424,8 @@ QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param,
head= table;
record= head->record[0];
if (!parent_alloc)
- init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0,
+ init_sql_alloc(&alloc, "QUICK_ROR_INTERSECT_SELECT",
+ thd->variables.range_alloc_block_size, 0,
MYF(MY_THREAD_SPECIFIC));
else
bzero(&alloc, sizeof(MEM_ROOT));
@@ -1540,7 +1544,7 @@ end:
head->file= org_file;
/* Restore head->read_set (and write_set) to what they had before the call */
- head->column_bitmaps_set(save_read_set, save_write_set);
+ head->column_bitmaps_set(save_read_set, save_write_set, save_vcol_set);
if (reset())
{
@@ -1697,7 +1701,8 @@ QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param,
head= table;
rowid_length= table->file->ref_length;
record= head->record[0];
- init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0,
+ init_sql_alloc(&alloc, "QUICK_ROR_UNION_SELECT",
+ thd->variables.range_alloc_block_size, 0,
MYF(MY_THREAD_SPECIFIC));
thd_param->mem_root= &alloc;
}
@@ -2070,7 +2075,7 @@ public:
/* Table read plans are allocated on MEM_ROOT and are never deleted */
static void *operator new(size_t size, MEM_ROOT *mem_root)
{ return (void*) alloc_root(mem_root, (uint) size); }
- static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
+ static void operator delete(void *ptr,size_t size) { TRASH_FREE(ptr, size); }
static void operator delete(void *ptr, MEM_ROOT *mem_root) { /* Never called */ }
virtual ~TABLE_READ_PLAN() {} /* Remove gcc warning */
@@ -2452,7 +2457,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
param.possible_keys.clear_all();
thd->no_errors=1; // Don't warn about NULL
- init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0,
+ init_sql_alloc(&alloc, "test_quick_select",
+ thd->variables.range_alloc_block_size, 0,
MYF(MY_THREAD_SPECIFIC));
if (!(param.key_parts=
(KEY_PART*) alloc_root(&alloc,
@@ -3026,7 +3032,8 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond)
SEL_TREE *tree;
double rows;
- init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0,
+ init_sql_alloc(&alloc, "calculate_cond_selectivity_for_table",
+ thd->variables.range_alloc_block_size, 0,
MYF(MY_THREAD_SPECIFIC));
param.thd= thd;
param.mem_root= &alloc;
@@ -3443,7 +3450,8 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
my_bitmap_map *old_sets[2];
prune_param.part_info= part_info;
- init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0,
+ init_sql_alloc(&alloc, "prune_partitions",
+ thd->variables.range_alloc_block_size, 0,
MYF(MY_THREAD_SPECIFIC));
range_par->mem_root= &alloc;
range_par->old_root= thd->mem_root;
@@ -3454,7 +3462,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
free_root(&alloc,MYF(0)); // Return memory & allocator
DBUG_RETURN(FALSE);
}
-
+
dbug_tmp_use_all_columns(table, old_sets,
table->read_set, table->write_set);
range_par->thd= thd;
@@ -3980,7 +3988,7 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
simply set res= -1 as if the mapper had returned that.
TODO: What to do here is defined in WL#4065.
*/
- if (ppar->arg_stack[0]->part == 0)
+ if (ppar->arg_stack[0]->part == 0 || ppar->part_info->part_type == VERSIONING_PARTITION)
{
uint32 i;
uint32 store_length_array[MAX_KEY];
@@ -6198,7 +6206,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
&key_ptr, 0);
keypart_map= (keypart_map << 1) | 1;
}
- min_range.length= max_range.length= (size_t) (key_ptr - key_val);
+ min_range.length= max_range.length= (uint) (key_ptr - key_val);
min_range.keypart_map= max_range.keypart_map= keypart_map;
records= (info->param->table->file->
records_in_range(scan->keynr, &min_range, &max_range));
@@ -6729,7 +6737,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool update_tbl_stats,
double read_time)
{
- uint idx, best_idx;
+ uint idx, UNINIT_VAR(best_idx);
SEL_ARG *key_to_read= NULL;
ha_rows UNINIT_VAR(best_records); /* protected by key_to_read */
uint UNINIT_VAR(best_mrr_flags), /* protected by key_to_read */
@@ -7048,7 +7056,7 @@ SEL_TREE *Item_func_in::get_func_mm_tree(RANGE_OPT_PARAM *param,
if (negated)
{
- if (array && array->result_type() != ROW_RESULT)
+ if (array && array->type_handler()->result_type() != ROW_RESULT)
{
/*
We get here for conditions in form "t.key NOT IN (c1, c2, ...)",
@@ -7339,6 +7347,7 @@ SEL_TREE *Item_func_in::get_func_row_mm_tree(RANGE_OPT_PARAM *param,
key_col->bring_value();
key_col_info.comparator= row_cmp_item->get_comparator(i);
+ DBUG_ASSERT(key_col_info.comparator);
key_col_info.comparator->store_value(key_col);
col_comparators++;
@@ -7949,7 +7958,7 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param,
}
uint maybe_null= (uint) field->real_maybe_null();
- uint field_length= field->pack_length() + maybe_null;
+ size_t field_length= field->pack_length() + maybe_null;
size_t offset= maybe_null;
size_t length= key_part->store_length;
@@ -10263,8 +10272,8 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
ulong count=count_key_part_usage(root,pos->next_key_part);
if (count > pos->next_key_part->use_count)
{
- sql_print_information("Use_count: Wrong count for key at %p, %lu "
- "should be %lu", (long unsigned int)pos,
+ sql_print_information("Use_count: Wrong count for key at %p: %lu "
+ "should be %lu", pos,
pos->next_key_part->use_count, count);
return;
}
@@ -10273,7 +10282,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
}
if (e_count != elements)
sql_print_warning("Wrong use count: %u (should be %u) for tree at %p",
- e_count, elements, (long unsigned int) this);
+ e_count, elements, this);
}
#endif
@@ -11386,7 +11395,10 @@ int QUICK_RANGE_SELECT::reset()
buf_size/= 2;
}
if (!mrr_buf_desc)
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ {
+ error= HA_ERR_OUT_OF_MEM;
+ goto err;
+ }
/* Initialize the handler buffer. */
mrr_buf_desc->buffer= mrange_buff;
@@ -13608,7 +13620,8 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
DBUG_ASSERT(!parent_alloc);
if (!parent_alloc)
{
- init_sql_alloc(&alloc, join->thd->variables.range_alloc_block_size, 0,
+ init_sql_alloc(&alloc, "QUICK_GROUP_MIN_MAX_SELECT",
+ join->thd->variables.range_alloc_block_size, 0,
MYF(MY_THREAD_SPECIFIC));
join->thd->mem_root= &alloc;
}
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 95e231433d2..bd85a12d4a1 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -1047,6 +1047,10 @@ bool quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
class QUICK_RANGE_SELECT : public QUICK_SELECT_I
{
protected:
+ THD *thd;
+ bool no_alloc;
+ MEM_ROOT *parent_alloc;
+
/* true if we enabled key only reads */
handler *file;
@@ -1085,6 +1089,9 @@ public:
QUICK_RANGE_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc,
MEM_ROOT *parent_alloc, bool *create_err);
~QUICK_RANGE_SELECT();
+ virtual QUICK_RANGE_SELECT *clone(bool *create_error)
+ { return new QUICK_RANGE_SELECT(thd, head, index, no_alloc, parent_alloc,
+ create_error); }
void need_sorted_output();
int init();
@@ -1155,6 +1162,12 @@ public:
:QUICK_RANGE_SELECT(thd, table, index_arg, no_alloc, parent_alloc,
create_err)
{};
+ virtual QUICK_RANGE_SELECT *clone(bool *create_error)
+ {
+ DBUG_ASSERT(0);
+ return new QUICK_RANGE_SELECT_GEOM(thd, head, index, no_alloc,
+ parent_alloc, create_error);
+ }
virtual int get_next();
};
@@ -1584,6 +1597,8 @@ class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
{
public:
QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint used_key_parts);
+ virtual QUICK_RANGE_SELECT *clone(bool *create_error)
+ { DBUG_ASSERT(0); return new QUICK_SELECT_DESC(this, used_key_parts); }
int get_next();
bool reverse_sorted() { return 1; }
int get_type() { return QS_TYPE_RANGE_DESC; }
@@ -1651,6 +1666,38 @@ class SQL_SELECT :public Sql_alloc {
};
+class SQL_SELECT_auto
+{
+ SQL_SELECT *select;
+public:
+ SQL_SELECT_auto(): select(NULL)
+ {}
+ ~SQL_SELECT_auto()
+ {
+ delete select;
+ }
+ SQL_SELECT_auto&
+ operator= (SQL_SELECT *_select)
+ {
+ select= _select;
+ return *this;
+ }
+ operator SQL_SELECT * () const
+ {
+ return select;
+ }
+ SQL_SELECT *
+ operator-> () const
+ {
+ return select;
+ }
+ operator bool () const
+ {
+ return select;
+ }
+};
+
+
class FT_SELECT: public QUICK_RANGE_SELECT
{
public:
@@ -1658,6 +1705,8 @@ public:
QUICK_RANGE_SELECT (thd, table, key, 1, NULL, create_err)
{ (void) init(); }
~FT_SELECT() { file->ft_end(); }
+ virtual QUICK_RANGE_SELECT *clone(bool *create_error)
+ { DBUG_ASSERT(0); return new FT_SELECT(thd, head, index, create_error); }
int init() { return file->ft_init(); }
int reset() { return 0; }
int get_next() { return file->ha_ft_read(record); }
diff --git a/sql/opt_split.cc b/sql/opt_split.cc
new file mode 100644
index 00000000000..0cb76f03917
--- /dev/null
+++ b/sql/opt_split.cc
@@ -0,0 +1,1137 @@
+/*
+ Copyright (c) 2017 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
+ 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-1301 USA */
+
+/*
+ This file contains functions to support the splitting technique.
+ This optimization technique can be applied to equi-joins involving
+ materialized tables such as materialized views, materialized derived tables
+ and materialized CTEs. The technique also could be applied to materialized
+ semi-joins though the code below does not support this usage yet.
+
+ Here are the main ideas behind this technique that we'll call SM optimization
+ (SplitMaterialization).
+
+ Consider the query
+ SELECT t1.a, t.min
+ FROM t1, (SELECT t2.a, MIN(t2.b) as min FROM t2 GROUP BY t2.a) t
+ WHERE t1.a = t.a and t1.b < const
+
+ Re-write the query into
+ SELECT t1.a, t.min
+ FROM t1, LATERAL (SELECT t2.a, MIN(t2.b) as min
+ FROM t2 WHERE t2.a = t1.a GROUP BY t2.a) t
+ WHERE t1.b < const
+
+ The execution of the original query (Q1) does the following:
+ 1. Executes the query in the specification of the derived table
+ and puts the result set into a temporary table with an index
+ on the first column.
+ 2. Joins t1 with the temporary table using the its index.
+
+ The execution of the transformed query (Q1R) follows these steps:
+ 1. For each row of t1 where t1.b < const a temporary table
+ containing all rows of of t2 with t2.a = t1.a is created
+ 2. If there are any rows in the temporary table aggregation
+ is performed for them
+ 3. The result of the aggregation is joined with t1.
+
+ The second execution can win if:
+ a) There is an efficient way to select rows of t2 for which t2.a = t1.a
+ (For example if there is an index on t2.a)
+ and
+ b) The number of temporary tables created for partitions
+ is much smaller that the total number of partitions
+
+ It should be noted that for the transformed query aggregation
+ for a partition may be performed several times.
+
+ As we can see the optimization basically splits table t2 into
+ partitions and performs aggregation over each of them
+ independently.
+
+ If we have only one equi-join condition then we either push it as
+ for Q1R or we don't. In a general case we may have much more options.
+ Consider the query (Q3)
+ SELECT
+ FROM t1,t2 (SELECT t3.a, t3.b, MIN(t3.c) as min
+ FROM t3 GROUP BY a,b) t
+ WHERE t.a = t1.a AND t.b = t2.b
+ AND t1.c < c1 and t2.c < c2
+ AND P(t1,t2);
+ (P(t1,t2) designates some additional conditions over columns of t1,t2).
+
+ Assuming that there indexes on t3(a,b) and t3(b) here we have several
+ reasonable options to push equi-join conditions into the derived.
+ All these options should be taken into account when the optimizer
+ evaluates different join orders. When the join order (t1,t,t2) is
+ evaluated there is only one way of splitting : to push the condition
+ t.a = t1.a into t. With the join order (t2,t,t1) only the condition
+ t.b = t2.b can be pushed. When the join orders (t1,t2,t) and (t2,t1,t)
+ are evaluated then the optimizer should consider pushing t.a = t1.a,
+ t.b = t2.b and (t.a = t1.a AND t.b = t2.b) to choose the best condition
+ for splitting. Apparently here last condition is the best one because
+ it provides the miximum possible number of partitions.
+
+ If we dropped the index on t3(a,b) and created the index on t3(a) instead
+ then we would have two options for splitting: to push t.a = t1.a or to
+ push t.b = t2.b. If the selectivity of the index t3(a) is better than
+ the selectivity of t3(b) then the first option is preferred.
+
+ Although the condition (t.a = t1.a AND t.b = t2.b) provides a better
+ splitting than the condition t.a = t1.a the latter will be used for
+ splitting if the execution plan with the join order (t1,t,t2) turns out
+ to be the cheapest one. It's quite possible when the join condition
+ P(t1,t2) has a bad selectivity.
+
+ Whenever the optimizer evaluates the cost of using a splitting it
+ compares it with the cost of materialization without splitting.
+
+ If we just drop the index on t3(a,b) the chances that the splitting
+ will be used becomes much lower but they still exists providing that
+ the fanout of the partial join of t1 and t2 is small enough.
+*/
+
+/*
+ Splitting can be applied to a materialized table specified by the query
+ with post-join operations that require partitioning of the result set produced
+ by the join expression used in the FROM clause the query such as GROUP BY
+ operation and window function operation. In any of these cases the post-join
+ operation can be executed independently for any partition only over the rows
+ of this partition. Also if the set of all partitions is divided into disjoint
+ subsets the operation can applied to each subset independently. In this case
+ all rows are first partitioned into the groups each of which contains all the
+ rows from the partitions belonging the same subset and then each group
+ is subpartitioned into groups in the the post join operation.
+
+ The set of all rows belonging to the union of several partitions is called
+ here superpartition. If a grouping operation is defined by the list
+ e_1,...,e_n then any set S = {e_i1,...,e_ik} can be used to devide all rows
+ into superpartions such that for any two rows r1, r2 the following holds:
+ e_ij(r1) = e_ij(r2) for each e_ij from S. We use the splitting technique
+ only if S consists of references to colums of the joined tables.
+ For example if the GROUP BY list looks like this a, g(b), c we can consider
+ applying the splitting technique to the superpartitions defined by {a,c},
+ {a}, {c} (a and c here may be the references to the columns from different
+ tables).
+*/
+
+ /*
+ The following describes when and how the optimizer decides whether it
+ makes sense to employ the splitting technique.
+
+ 1. For each instance of a materialized table (derived/view/CTE) it is
+ checked that it is potentially splittable. Now it is done right after the
+ execution plan for the select specifying this table has been chosen.
+
+ 2. Any potentially splittable materialized table T is subject to two-phase
+ optimization. It means that the optimizer first builds the best execution
+ plan for join that specifies T. Then the control is passed back to the
+ optimization process of the embedding select Q. After the execution plan
+ for Q has been chosen the optimizer finishes the optimization of the join
+ specifying T.
+
+ 3. When the optimizer builds the container with the KEYUSE structures
+ for the join of embedding select it detects the equi-join conditions
+ PC that potentially could be pushed into a potentially splittable
+ materialized table T. The collected information about such conditions
+ is stored together with other facts on potential splittings for table T.
+
+ 4. When the optimizer starts looking for the best execution plan for the
+ embedding select Q for each potentially splittable materialized table T
+ it creates special KEYUSE structures for pushable equi-join conditions
+ PC. These structures are used to add new elements to the container
+ of KEYUSE structures built for T. The specifics of these elements is
+ that they can be ebabled and disabled during the process of choosing
+ the best plan for Q.
+
+ 5. When the optimizer extends a partial join order with a potentially
+ splittable materialized table T (in function best_access_path) it
+ first evaluates a new execution plan for the modified specification
+ of T that adds all equi-join conditions that can be pushed with
+ current join prefix to the WHERE conditions of the original
+ specification of T. If the cost of the new plan is better than the
+ the cost of the original materialized table then the optimizer
+ prefers to use splitting for the current join prefix. As the cost
+ of the plan depends only on the pushed conditions it makes sense
+ to cache this plan for other prefixes.
+
+ 6. The optimizer takes into account the cost of splitting / materialization
+ of a potentially splittable materialized table T as a startup cost
+ to access table T.
+
+ 7. When the optimizer finally chooses the best execution plan for
+ the embedding select Q and this plan prefers using splitting
+ for table T with pushed equi-join conditions PC then the execution
+ plan for the underlying join with these conditions is chosen for T.
+*/
+
+/*
+ The implementation of the splitting technique below allows to apply
+ the technique only to a materialized derived table / view / CTE whose
+ specification is either a select with GROUP BY or a non-grouping select
+ with window functions that share the same PARTITION BY list.
+*/
+
+#include "mariadb.h"
+#include "sql_select.h"
+
+/* Info on a splitting field */
+struct SplM_field_info
+{
+ /* Splitting field in the materialized table T */
+ Field *mat_field;
+ /* The item from the select list of the specification of T */
+ Item *producing_item;
+ /* The corresponding splitting field from the specification of T */
+ Field *underlying_field;
+};
+
+
+/* Info on the splitting execution plan saved in SplM_opt_info::cache */
+struct SplM_plan_info
+{
+ /* The cached splitting execution plan P */
+ struct st_position *best_positions;
+ /* The cost of the above plan */
+ double cost;
+ /* Selectivity of splitting used in P */
+ double split_sel;
+ /* For fast search of KEYUSE_EXT elements used for splitting in P */
+ struct KEYUSE_EXT *keyuse_ext_start;
+ /* The tables that contains the fields used for splitting in P */
+ TABLE *table;
+ /* The number of the key from 'table' used for splitting in P */
+ uint key;
+ /* Number of the components of 'key' used for splitting in P */
+ uint parts;
+};
+
+
+/*
+ The structure contains the information that is used by the optimizer
+ for potentially splittable materialization of T that is a materialized
+ derived_table / view / CTE
+*/
+class SplM_opt_info : public Sql_alloc
+{
+public:
+ /* The join for the select specifying T */
+ JOIN *join;
+ /* The map of tables from 'join' whose columns can be used for partitioning */
+ table_map tables_usable_for_splitting;
+ /* Info about the fields of the joined tables usable for splitting */
+ SplM_field_info *spl_fields;
+ /* The number of elements in the above list */
+ uint spl_field_cnt;
+ /* Contains the structures to generate all KEYUSEs for pushable equalities */
+ List<KEY_FIELD> added_key_fields;
+ /* The cache of evaluated execution plans for 'join' with pushed equalities */
+ List<SplM_plan_info> plan_cache;
+ /* Cost of best execution plan for join when nothing is pushed */
+ double unsplit_cost;
+ /* Cardinality of T when nothing is pushed */
+ double unsplit_card;
+ /* Lastly evaluated execution plan for 'join' with pushed equalities */
+ SplM_plan_info *last_plan;
+
+ SplM_plan_info *find_plan(TABLE *table, uint key, uint parts);
+};
+
+
+void TABLE::set_spl_opt_info(SplM_opt_info *spl_info)
+{
+ if (spl_info)
+ spl_info->join->spl_opt_info= spl_info;
+ spl_opt_info= spl_info;
+}
+
+
+void TABLE::deny_splitting()
+{
+ DBUG_ASSERT(spl_opt_info != NULL);
+ spl_opt_info->join->spl_opt_info= NULL;
+ spl_opt_info= NULL;
+}
+
+
+/* This structure is auxiliary and used only in the function that follows it */
+struct SplM_field_ext_info: public SplM_field_info
+{
+ uint item_no;
+ bool is_usable_for_ref_access;
+};
+
+
+/**
+ @brief
+ Check whether this join is one for potentially splittable materialized table
+
+ @details
+ The function checks whether this join is for select that specifies
+ a potentially splittable materialized table T. If so, the collected
+ info on potential splittability of T is attached to the field spl_opt_info
+ of the TABLE structure for T.
+
+ The function returns a positive answer if the following holds:
+ 1. the optimizer switch 'split_materialized' is set 'on'
+ 2. the select owning this join specifies a materialized derived/view/cte T
+ 3. this is the only select in the specification of T
+ 4. condition pushdown is not prohibited into T
+ 5. T is not recursive
+ 6. not all of this join are constant or optimized away
+ 7. T is either
+ 7.1. a grouping table with GROUP BY list P
+ or
+ 7.2. a non-grouping table with window functions over the same non-empty
+ partition specified by the PARTITION BY list P
+ 8. P contains some references on the columns of the joined tables C
+ occurred also in the select list of this join
+ 9. There are defined some keys usable for ref access of fields from C
+ with available statistics.
+
+ @retval
+ true if the answer is positive
+ false otherwise
+*/
+
+bool JOIN::check_for_splittable_materialized()
+{
+ ORDER *partition_list= 0;
+ st_select_lex_unit *unit= select_lex->master_unit();
+ TABLE_LIST *derived= unit->derived;
+ if (!(optimizer_flag(thd, OPTIMIZER_SWITCH_SPLIT_MATERIALIZED)) || // !(1)
+ !(derived && derived->is_materialized_derived()) || // !(2)
+ (unit->first_select()->next_select()) || // !(3)
+ (derived->prohibit_cond_pushdown) || // !(4)
+ (derived->is_recursive_with_table()) || // !(5)
+ (table_count == 0 || const_tables == top_join_tab_count)) // !(6)
+ return false;
+ if (group_list) // (7.1)
+ {
+ if (!select_lex->have_window_funcs())
+ partition_list= group_list;
+ }
+ else if (select_lex->have_window_funcs() &&
+ select_lex->window_specs.elements == 1) // (7.2)
+ {
+ partition_list=
+ select_lex->window_specs.head()->partition_list->first;
+ }
+ if (!partition_list)
+ return false;
+
+ ORDER *ord;
+ Dynamic_array<SplM_field_ext_info> candidates;
+
+ /*
+ Select from partition_list all candidates for splitting.
+ A candidate must be
+ - field item or refer to such (8.1)
+ - item mentioned in the select list (8.2)
+ Put info about such candidates into the array candidates
+ */
+ table_map usable_tables= 0; // tables that contains the candidate
+ for (ord= partition_list; ord; ord= ord->next)
+ {
+ Item *ord_item= *ord->item;
+ if (ord_item->real_item()->type() != Item::FIELD_ITEM) // !(8.1)
+ continue;
+
+ Field *ord_field= ((Item_field *) (ord_item->real_item()))->field;
+
+ JOIN_TAB *tab= ord_field->table->reginfo.join_tab;
+ if (tab->is_inner_table_of_outer_join())
+ continue;
+
+ List_iterator<Item> li(fields_list);
+ Item *item;
+ uint item_no= 0;
+ while ((item= li++))
+ {
+ if ((*ord->item)->eq(item, 0)) // (8.2)
+ {
+ SplM_field_ext_info new_elem;
+ new_elem.producing_item= item;
+ new_elem.item_no= item_no;
+ new_elem.mat_field= derived->table->field[item_no];
+ new_elem.underlying_field= ord_field;
+ new_elem.is_usable_for_ref_access= false;
+ candidates.push(new_elem);
+ usable_tables|= ord_field->table->map;
+ break;
+ }
+ item_no++;
+ }
+ }
+ if (candidates.elements() == 0) // no candidates satisfying (8.1) && (8.2)
+ return false;
+
+ /*
+ For each table from this join find the keys that can be used for ref access
+ of the fields mentioned in the 'array candidates'
+ */
+
+ SplM_field_ext_info *cand;
+ SplM_field_ext_info *cand_start= &candidates.at(0);
+ SplM_field_ext_info *cand_end= cand_start + candidates.elements();
+
+ for (JOIN_TAB *tab= join_tab;
+ tab < join_tab + top_join_tab_count; tab++)
+ {
+ TABLE *table= tab->table;
+ if (!(table->map & usable_tables))
+ continue;
+
+ table->keys_usable_for_splitting.clear_all();
+ uint i;
+ for (i= 0; i < table->s->keys; i++)
+ {
+ if (!table->keys_in_use_for_query.is_set(i))
+ continue;
+ KEY *key_info= table->key_info + i;
+ uint key_parts= table->actual_n_key_parts(key_info);
+ uint usable_kp_cnt= 0;
+ for ( ; usable_kp_cnt < key_parts; usable_kp_cnt++)
+ {
+ if (key_info->actual_rec_per_key(usable_kp_cnt) == 0)
+ break;
+ int fldnr= key_info->key_part[usable_kp_cnt].fieldnr;
+
+ for (cand= cand_start; cand < cand_end; cand++)
+ {
+ if (cand->underlying_field->field_index + 1 == fldnr)
+ {
+ cand->is_usable_for_ref_access= true;
+ break;
+ }
+ }
+ if (cand == cand_end)
+ break;
+ }
+ if (usable_kp_cnt)
+ table->keys_usable_for_splitting.set_bit(i);
+ }
+ }
+
+ /* Count the candidate fields that can be accessed by ref */
+ uint spl_field_cnt= (uint)candidates.elements();
+ for (cand= cand_start; cand < cand_end; cand++)
+ {
+ if (!cand->is_usable_for_ref_access)
+ spl_field_cnt--;
+ }
+
+ if (!spl_field_cnt) // No candidate field can be accessed by ref => !(9)
+ return false;
+
+ /*
+ Create a structure of the type SplM_opt_info and fill it with
+ the collected info on potential splittability of T
+ */
+ SplM_opt_info *spl_opt_info= new (thd->mem_root) SplM_opt_info();
+ SplM_field_info *spl_field=
+ (SplM_field_info *) (thd->calloc(sizeof(SplM_field_info) *
+ spl_field_cnt));
+
+ if (!(spl_opt_info && spl_field)) // consider T as not good for splitting
+ return false;
+
+ spl_opt_info->join= this;
+ spl_opt_info->tables_usable_for_splitting= 0;
+ spl_opt_info->spl_field_cnt= spl_field_cnt;
+ spl_opt_info->spl_fields= spl_field;
+ for (cand= cand_start; cand < cand_end; cand++)
+ {
+ if (!cand->is_usable_for_ref_access)
+ continue;
+ spl_field->producing_item= cand->producing_item;
+ spl_field->underlying_field= cand->underlying_field;
+ spl_field->mat_field= cand->mat_field;
+ spl_opt_info->tables_usable_for_splitting|=
+ cand->underlying_field->table->map;
+ spl_field++;
+ }
+
+ /* Attach this info to the table T */
+ derived->table->set_spl_opt_info(spl_opt_info);
+
+ return true;
+}
+
+
+/**
+ @brief
+ Collect info on KEY_FIELD usable for splitting
+
+ @param
+ key_field KEY_FIELD to collect info on
+
+ @details
+ The function assumes that this table is potentially splittable.
+ The function checks whether the KEY_FIELD structure key_field built for
+ this table was created for a splitting field f. If so, the function does
+ the following using info from key_field:
+ 1. Builds an equality of the form f = key_field->val that could be
+ pushed into this table.
+ 2. Creates a new KEY_FIELD structure for this equality and stores
+ a reference to this structure in this->spl_opt_info.
+*/
+
+void TABLE::add_splitting_info_for_key_field(KEY_FIELD *key_field)
+{
+ DBUG_ASSERT(spl_opt_info != NULL);
+ JOIN *join= spl_opt_info->join;
+ Field *field= key_field->field;
+ SplM_field_info *spl_field= spl_opt_info->spl_fields;
+ uint i= spl_opt_info->spl_field_cnt;
+ for ( ; i; i--, spl_field++)
+ {
+ if (spl_field->mat_field == field)
+ break;
+ }
+ if (!i) // field is not usable for splitting
+ return;
+
+ /*
+ Any equality condition that can be potentially pushed into the
+ materialized derived table is constructed now though later it may turn out
+ that it is not needed, because it is not used for splitting.
+ The reason for this is that the failure to construct it when it has to be
+ injected causes denial for further processing of the query.
+ Formally this equality is needed in the KEY_FIELD structure constructed
+ here that will be used to generate additional keyuses usable for splitting.
+ However key_field.cond could be used for this purpose (see implementations
+ of virtual function can_optimize_keypart_ref()).
+
+ The condition is built in such a form that it can be added to the WHERE
+ condition of the select that specifies this table.
+ */
+ THD *thd= in_use;
+ Item *left_item= spl_field->producing_item->build_clone(thd);
+ Item *right_item= key_field->val->build_clone(thd);
+ Item_func_eq *eq_item= 0;
+ if (left_item && right_item)
+ {
+ right_item->walk(&Item::set_fields_as_dependent_processor,
+ false, join->select_lex);
+ right_item->update_used_tables();
+ eq_item= new (thd->mem_root) Item_func_eq(thd, left_item, right_item);
+ }
+ if (!eq_item)
+ return;
+ KEY_FIELD *added_key_field=
+ (KEY_FIELD *) thd->alloc(sizeof(KEY_FIELD));
+ if (!added_key_field ||
+ spl_opt_info->added_key_fields.push_back(added_key_field,thd->mem_root))
+ return;
+ added_key_field->field= spl_field->underlying_field;
+ added_key_field->cond= eq_item;
+ added_key_field->val= key_field->val;
+ added_key_field->level= 0;
+ added_key_field->optimize= KEY_OPTIMIZE_EQ;
+ added_key_field->eq_func= true;
+ added_key_field->null_rejecting= true;
+ added_key_field->cond_guard= NULL;
+ added_key_field->sj_pred_no= UINT_MAX;
+ return;
+}
+
+
+static bool
+add_ext_keyuse_for_splitting(Dynamic_array<KEYUSE_EXT> *ext_keyuses,
+ KEY_FIELD *added_key_field, uint key, uint part)
+{
+ KEYUSE_EXT keyuse_ext;
+ Field *field= added_key_field->field;
+
+ JOIN_TAB *tab=field->table->reginfo.join_tab;
+ key_map possible_keys=field->get_possible_keys();
+ possible_keys.intersect(field->table->keys_usable_for_splitting);
+ tab->keys.merge(possible_keys);
+
+ Item_func_eq *eq_item= (Item_func_eq *) (added_key_field->cond);
+ keyuse_ext.table= field->table;
+ keyuse_ext.val= eq_item->arguments()[1];
+ keyuse_ext.key= key;
+ keyuse_ext.keypart=part;
+ keyuse_ext.keypart_map= (key_part_map) 1 << part;
+ keyuse_ext.used_tables= keyuse_ext.val->used_tables();
+ keyuse_ext.optimize= added_key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
+ keyuse_ext.ref_table_rows= 0;
+ keyuse_ext.null_rejecting= added_key_field->null_rejecting;
+ keyuse_ext.cond_guard= added_key_field->cond_guard;
+ keyuse_ext.sj_pred_no= added_key_field->sj_pred_no;
+ keyuse_ext.validity_ref= 0;
+ keyuse_ext.needed_in_prefix= added_key_field->val->used_tables();
+ keyuse_ext.validity_var= false;
+ return ext_keyuses->push(keyuse_ext);
+}
+
+
+static int
+sort_ext_keyuse(KEYUSE_EXT *a, KEYUSE_EXT *b)
+{
+ if (a->table->tablenr != b->table->tablenr)
+ return (int) (a->table->tablenr - b->table->tablenr);
+ if (a->key != b->key)
+ return (int) (a->key - b->key);
+ return (int) (a->keypart - b->keypart);
+}
+
+
+static void
+sort_ext_keyuses(Dynamic_array<KEYUSE_EXT> *keyuses)
+{
+ KEYUSE_EXT *first_keyuse= &keyuses->at(0);
+ my_qsort(first_keyuse, keyuses->elements(), sizeof(KEYUSE_EXT),
+ (qsort_cmp) sort_ext_keyuse);
+}
+
+
+/**
+ @brief
+ Add info on keyuses usable for splitting into an array
+*/
+
+static bool
+add_ext_keyuses_for_splitting_field(Dynamic_array<KEYUSE_EXT> *ext_keyuses,
+ KEY_FIELD *added_key_field)
+{
+ Field *field= added_key_field->field;
+ TABLE *table= field->table;
+ for (uint key= 0; key < table->s->keys; key++)
+ {
+ if (!(table->keys_usable_for_splitting.is_set(key)))
+ continue;
+ KEY *key_info= table->key_info + key;
+ uint key_parts= table->actual_n_key_parts(key_info);
+ KEY_PART_INFO *key_part_info= key_info->key_part;
+ for (uint part=0; part < key_parts; part++, key_part_info++)
+ {
+ if (!field->eq(key_part_info->field))
+ continue;
+ if (add_ext_keyuse_for_splitting(ext_keyuses, added_key_field, key, part))
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/*
+ @brief
+ Cost of the post join operation used in specification of splittable table
+*/
+
+static
+double spl_postjoin_oper_cost(THD *thd, double join_record_count, uint rec_len)
+{
+ double cost;
+ cost= get_tmp_table_write_cost(thd, join_record_count,rec_len) *
+ join_record_count; // cost to fill tmp table
+ cost+= get_tmp_table_lookup_cost(thd, join_record_count,rec_len) *
+ join_record_count; // cost to perform post join operation used here
+ cost+= get_tmp_table_lookup_cost(thd, join_record_count, rec_len) +
+ (join_record_count == 0 ? 0 :
+ join_record_count * log2 (join_record_count)) *
+ SORT_INDEX_CMP_COST; // cost to perform sorting
+ return cost;
+}
+
+/**
+ @brief
+ Add KEYUSE structures that can be usable for splitting
+
+ @details
+ This function is called only for joins created for potentially
+ splittable materialized tables. The function does the following:
+ 1. Creates the dynamic array ext_keyuses_for_splitting of KEYUSE_EXT
+ structures and fills is with info about all keyuses that
+ could be used for splitting.
+ 2. Sort the array ext_keyuses_for_splitting for fast access by key
+ on certain columns.
+ 3. Collects and stores cost and cardinality info on the best execution
+ plan that does not use splitting and save this plan together with
+ corresponding array of keyuses.
+ 4. Expand this array with KEYUSE elements built from the info stored
+ in ext_keyuses_for_splitting that could be produced by pushed
+ equalities employed for splitting.
+ 5. Prepare the extended array of keyuses to be used in the function
+ best_access_plan()
+*/
+
+void JOIN::add_keyuses_for_splitting()
+{
+ uint i;
+ uint idx;
+ KEYUSE_EXT *keyuse_ext;
+ KEYUSE_EXT keyuse_ext_end;
+ double oper_cost;
+ uint rec_len;
+ uint added_keyuse_count;
+ TABLE *table= select_lex->master_unit()->derived->table;
+ List_iterator_fast<KEY_FIELD> li(spl_opt_info->added_key_fields);
+ KEY_FIELD *added_key_field;
+ if (!spl_opt_info->added_key_fields.elements)
+ goto err;
+ if (!(ext_keyuses_for_splitting= new Dynamic_array<KEYUSE_EXT>))
+ goto err;
+ while ((added_key_field= li++))
+ {
+ (void) add_ext_keyuses_for_splitting_field(ext_keyuses_for_splitting,
+ added_key_field);
+ }
+ added_keyuse_count= (uint)ext_keyuses_for_splitting->elements();
+ if (!added_keyuse_count)
+ goto err;
+ sort_ext_keyuses(ext_keyuses_for_splitting);
+ bzero((char*) &keyuse_ext_end, sizeof(keyuse_ext_end));
+ if (ext_keyuses_for_splitting->push(keyuse_ext_end))
+ goto err;
+
+ spl_opt_info->unsplit_card= join_record_count;
+
+ rec_len= table->s->rec_buff_length;
+
+ oper_cost= spl_postjoin_oper_cost(thd, join_record_count, rec_len);
+
+ spl_opt_info->unsplit_cost= best_positions[table_count-1].read_time +
+ oper_cost;
+
+ if (!(save_qep= new Join_plan_state(table_count + 1)))
+ goto err;
+
+ save_query_plan(save_qep);
+
+ if (!keyuse.buffer &&
+ my_init_dynamic_array(&keyuse, sizeof(KEYUSE), 20, 64,
+ MYF(MY_THREAD_SPECIFIC)))
+ goto err;
+
+ if (allocate_dynamic(&keyuse,
+ save_qep->keyuse.elements +
+ added_keyuse_count))
+ goto err;
+
+ memcpy(keyuse.buffer,
+ save_qep->keyuse.buffer,
+ (size_t) save_qep->keyuse.elements * keyuse.size_of_element);
+ keyuse.elements= save_qep->keyuse.elements;
+
+ keyuse_ext= &ext_keyuses_for_splitting->at(0);
+ idx= save_qep->keyuse.elements;
+ for (i=0; i < added_keyuse_count; i++, keyuse_ext++, idx++)
+ {
+ set_dynamic(&keyuse, (KEYUSE *) keyuse_ext, idx);
+ KEYUSE *added_keyuse= ((KEYUSE *) (keyuse.buffer)) + idx;
+ added_keyuse->validity_ref= &keyuse_ext->validity_var;
+ }
+
+ if (sort_and_filter_keyuse(thd, &keyuse, true))
+ goto err;
+ optimize_keyuse(this, &keyuse);
+
+ for (uint i= 0; i < table_count; i++)
+ {
+ JOIN_TAB *tab= join_tab + i;
+ map2table[tab->table->tablenr]= tab;
+ }
+
+ return;
+
+err:
+ if (save_qep)
+ restore_query_plan(save_qep);
+ table->deny_splitting();
+ return;
+}
+
+
+/**
+ @brief
+ Add KEYUSE structures that can be usable for splitting of this joined table
+*/
+
+void JOIN_TAB::add_keyuses_for_splitting()
+{
+ DBUG_ASSERT(table->spl_opt_info != NULL);
+ SplM_opt_info *spl_opt_info= table->spl_opt_info;
+ spl_opt_info->join->add_keyuses_for_splitting();
+}
+
+
+/*
+ @brief
+ Find info on the splitting plan by the splitting key
+*/
+
+SplM_plan_info *SplM_opt_info::find_plan(TABLE *table, uint key, uint parts)
+{
+ List_iterator_fast<SplM_plan_info> li(plan_cache);
+ SplM_plan_info *spl_plan;
+ while ((spl_plan= li++))
+ {
+ if (spl_plan->table == table &&
+ spl_plan->key == key &&
+ spl_plan->parts == parts)
+ break;
+ }
+ return spl_plan;
+}
+
+
+/*
+ @breaf
+ Enable/Disable a keyuses that can be used for splitting
+ */
+
+static
+void reset_validity_vars_for_keyuses(KEYUSE_EXT *key_keyuse_ext_start,
+ TABLE *table, uint key,
+ table_map remaining_tables,
+ bool validity_val)
+{
+ KEYUSE_EXT *keyuse_ext= key_keyuse_ext_start;
+ do
+ {
+ if (!(keyuse_ext->needed_in_prefix & remaining_tables))
+ {
+ /*
+ The enabling/disabling flags are set just in KEYUSE_EXT structures.
+ Yet keyuses that are used by best_access_path() have pointers
+ to these flags.
+ */
+ keyuse_ext->validity_var= validity_val;
+ }
+ keyuse_ext++;
+ }
+ while (keyuse_ext->key == key && keyuse_ext->table == table);
+}
+
+
+/**
+ @brief
+ Choose the best splitting to extend the evaluated partial join
+
+ @param
+ record_count estimated cardinality of the extended partial join
+ remaining_tables tables not joined yet
+
+ @details
+ This function is called during the search for the best execution
+ plan of the join that contains this table T. The function is called
+ every time when the optimizer tries to extend a partial join by
+ joining it with table T. Depending on what tables are already in the
+ partial join different equalities usable for splitting can be pushed
+ into T. The function evaluates different variants and chooses the
+ best one. Then the function finds the plan for the materializing join
+ with the chosen equality conditions pushed into it. If the cost of the
+ plan turns out to be less than the cost of the best plan without
+ splitting the function set it as the true plan of materialization
+ of the table T.
+ The function caches the found plans for materialization of table T
+ together if the info what key was used for splitting. Next time when
+ the optimizer prefers to use the same key the plan is taken from
+ the cache of plans
+
+ @retval
+ Pointer to the info on the found plan that employs the pushed equalities
+ if the plan has been chosen, NULL - otherwise.
+*/
+
+SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count,
+ table_map remaining_tables)
+{
+ SplM_opt_info *spl_opt_info= table->spl_opt_info;
+ DBUG_ASSERT(spl_opt_info != NULL);
+ JOIN *join= spl_opt_info->join;
+ THD *thd= join->thd;
+ table_map tables_usable_for_splitting=
+ spl_opt_info->tables_usable_for_splitting;
+ KEYUSE_EXT *keyuse_ext= &join->ext_keyuses_for_splitting->at(0);
+ KEYUSE_EXT *best_key_keyuse_ext_start;
+ TABLE *best_table= 0;
+ double best_rec_per_key= DBL_MAX;
+ SplM_plan_info *spl_plan= 0;
+ uint best_key;
+ uint best_key_parts;
+
+ /*
+ Check whether there are keys that can be used to join T employing splitting
+ and if so, select the best out of such keys
+ */
+ for (uint tablenr= 0; tablenr < join->table_count; tablenr++)
+ {
+ if (!((1ULL << tablenr) & tables_usable_for_splitting))
+ continue;
+ JOIN_TAB *tab= join->map2table[tablenr];
+ TABLE *table= tab->table;
+ do
+ {
+ uint key= keyuse_ext->key;
+ KEYUSE_EXT *key_keyuse_ext_start= keyuse_ext;
+ key_part_map found_parts= 0;
+ do
+ {
+ if (keyuse_ext->needed_in_prefix & remaining_tables)
+ {
+ keyuse_ext++;
+ continue;
+ }
+ if (!(keyuse_ext->keypart_map & found_parts))
+ {
+ if ((!found_parts && !keyuse_ext->keypart) ||
+ (found_parts && ((keyuse_ext->keypart_map >> 1) & found_parts)))
+ found_parts|= keyuse_ext->keypart_map;
+ else
+ {
+ do
+ {
+ keyuse_ext++;
+ }
+ while (keyuse_ext->key == key && keyuse_ext->table == table);
+ break;
+ }
+ }
+ KEY *key_info= table->key_info + key;
+ double rec_per_key=
+ key_info->actual_rec_per_key(keyuse_ext->keypart);
+ if (rec_per_key < best_rec_per_key)
+ {
+ best_table= keyuse_ext->table;
+ best_key= keyuse_ext->key;
+ best_key_parts= keyuse_ext->keypart + 1;
+ best_rec_per_key= rec_per_key;
+ best_key_keyuse_ext_start= key_keyuse_ext_start;
+ }
+ keyuse_ext++;
+ }
+ while (keyuse_ext->key == key && keyuse_ext->table == table);
+ }
+ while (keyuse_ext->table == table);
+ }
+ spl_opt_info->last_plan= 0;
+ if (best_table)
+ {
+ /*
+ The key for splitting was chosen, look for the plan for this key
+ in the cache
+ */
+ spl_plan= spl_opt_info->find_plan(best_table, best_key, best_key_parts);
+ if (!spl_plan &&
+ (spl_plan= (SplM_plan_info *) thd->alloc(sizeof(SplM_plan_info))) &&
+ (spl_plan->best_positions=
+ (POSITION *) thd->alloc(sizeof(POSITION) * join->table_count)) &&
+ !spl_opt_info->plan_cache.push_back(spl_plan))
+ {
+ /*
+ The plan for the chosen key has not been found in the cache.
+ Build a new plan and save info on it in the cache
+ */
+ table_map all_table_map= (1 << join->table_count) - 1;
+ reset_validity_vars_for_keyuses(best_key_keyuse_ext_start, best_table,
+ best_key, remaining_tables, true);
+ choose_plan(join, all_table_map & ~join->const_table_map);
+ spl_plan->keyuse_ext_start= best_key_keyuse_ext_start;
+ spl_plan->table= best_table;
+ spl_plan->key= best_key;
+ spl_plan->parts= best_key_parts;
+ spl_plan->split_sel= best_rec_per_key /
+ (spl_opt_info->unsplit_card ?
+ spl_opt_info->unsplit_card : 1);
+
+ uint rec_len= table->s->rec_buff_length;
+
+ double split_card= spl_opt_info->unsplit_card * spl_plan->split_sel;
+ double oper_cost= split_card *
+ spl_postjoin_oper_cost(thd, split_card, rec_len);
+ spl_plan->cost= join->best_positions[join->table_count-1].read_time +
+ + oper_cost;
+
+ memcpy((char *) spl_plan->best_positions,
+ (char *) join->best_positions,
+ sizeof(POSITION) * join->table_count);
+ reset_validity_vars_for_keyuses(best_key_keyuse_ext_start, best_table,
+ best_key, remaining_tables, false);
+ }
+ if (spl_plan)
+ {
+ if(record_count * spl_plan->cost < spl_opt_info->unsplit_cost)
+ {
+ /*
+ The best plan that employs splitting is cheaper than
+ the plan without splitting
+ */
+ spl_opt_info->last_plan= spl_plan;
+ }
+ }
+ }
+
+ /* Set the cost of the preferred materialization for this partial join */
+ records= (ha_rows)spl_opt_info->unsplit_card;
+ spl_plan= spl_opt_info->last_plan;
+ if (spl_plan)
+ {
+ startup_cost= record_count * spl_plan->cost;
+ records= (ha_rows) (records * spl_plan->split_sel);
+ }
+ else
+ startup_cost= spl_opt_info->unsplit_cost;
+ return spl_plan;
+}
+
+
+/**
+ @brief
+ Inject equalities for splitting used by the materialization join
+
+ @param
+ remaining_tables used to filter out the equalities that cannot
+ be pushed.
+
+ @details
+ This function is called by JOIN_TAB::fix_splitting that is used
+ to fix the chosen splitting of a splittable materialized table T
+ in the final query execution plan. In this plan the table T
+ is joined just before the 'remaining_tables'. So all equalities
+ usable for splitting whose right parts do not depend on any of
+ remaining tables can be pushed into join for T.
+ The function also marks the select that specifies T as
+ UNCACHEABLE_DEPENDENT_INJECTED.
+
+ @retval
+ false on success
+ true on failure
+*/
+
+bool JOIN::inject_best_splitting_cond(table_map remaining_tables)
+{
+ Item *inj_cond= 0;
+ List<Item> inj_cond_list;
+ List_iterator<KEY_FIELD> li(spl_opt_info->added_key_fields);
+ KEY_FIELD *added_key_field;
+ while ((added_key_field= li++))
+ {
+ if (remaining_tables & added_key_field->val->used_tables())
+ continue;
+ if (inj_cond_list.push_back(added_key_field->cond, thd->mem_root))
+ return true;
+ }
+ DBUG_ASSERT(inj_cond_list.elements);
+ switch (inj_cond_list.elements) {
+ case 1:
+ inj_cond= inj_cond_list.head(); break;
+ default:
+ inj_cond= new (thd->mem_root) Item_cond_and(thd, inj_cond_list);
+ if (!inj_cond)
+ return true;
+ }
+ if (inj_cond)
+ inj_cond->fix_fields(thd,0);
+
+ if (inject_cond_into_where(inj_cond))
+ return true;
+
+ select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
+ st_select_lex_unit *unit= select_lex->master_unit();
+ unit->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
+
+ return false;
+}
+
+
+/**
+ @brief
+ Fix the splitting chosen for a splittable table in the final query plan
+
+ @param
+ spl_plan info on the splitting plan chosen for the splittable table T
+ remaining_tables the table T is joined just before these tables
+
+ @details
+ If in the final query plan the optimizer has chosen a splitting plan
+ then the function sets this plan as the final execution plan to
+ materialized the table T. Otherwise the plan that does not use
+ splitting is set for the materialization.
+
+ @retval
+ false on success
+ true on failure
+*/
+
+bool JOIN_TAB::fix_splitting(SplM_plan_info *spl_plan,
+ table_map remaining_tables)
+{
+ SplM_opt_info *spl_opt_info= table->spl_opt_info;
+ DBUG_ASSERT(table->spl_opt_info != 0);
+ JOIN *md_join= spl_opt_info->join;
+ if (spl_plan)
+ {
+ memcpy((char *) md_join->best_positions,
+ (char *) spl_plan->best_positions,
+ sizeof(POSITION) * md_join->table_count);
+ if (md_join->inject_best_splitting_cond(remaining_tables))
+ return true;
+ /*
+ This is called for a proper work of JOIN::get_best_combination()
+ called for the join that materializes T
+ */
+ reset_validity_vars_for_keyuses(spl_plan->keyuse_ext_start,
+ spl_plan->table,
+ spl_plan->key,
+ remaining_tables,
+ true);
+ }
+ else
+ {
+ md_join->restore_query_plan(md_join->save_qep);
+ }
+ return false;
+}
+
+
+/**
+ @brief
+ Fix the splittings chosen splittable tables in the final query plan
+
+ @details
+ The function calls JOIN_TAB::fix_splittins for all potentially
+ splittable tables in this join to set all final materialization
+ plans chosen for these tables.
+
+ @retval
+ false on success
+ true on failure
+*/
+
+bool JOIN::fix_all_splittings_in_plan()
+{
+ table_map prev_tables= 0;
+ table_map all_tables= (1 << table_count) - 1;
+ for (uint tablenr= 0; tablenr < table_count; tablenr++)
+ {
+ POSITION *cur_pos= &best_positions[tablenr];
+ JOIN_TAB *tab= cur_pos->table;
+ if (tablenr >= const_tables && tab->table->is_splittable())
+ {
+ SplM_plan_info *spl_plan= cur_pos->spl_plan;
+ if (tab->fix_splitting(spl_plan, all_tables & ~prev_tables))
+ return true;
+ }
+ prev_tables|= tab->table->map;
+ }
+ return false;
+}
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 72da68816ad..eff28d0c27d 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -446,10 +446,6 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
Item_in_subselect *subq_pred, bool *remove);
static TABLE_LIST *alloc_join_nest(THD *thd);
static uint get_tmp_table_rec_length(Ref_ptr_array p_list, uint elements);
-static double get_tmp_table_lookup_cost(THD *thd, double row_count,
- uint row_size);
-static double get_tmp_table_write_cost(THD *thd, double row_count,
- uint row_size);
bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables);
static SJ_MATERIALIZATION_INFO *
at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab,
@@ -1501,6 +1497,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
{
TABLE_LIST *outer_tbl= subq_pred->emb_on_expr_nest;
TABLE_LIST *wrap_nest;
+ LEX_CSTRING sj_wrap_name= { STRING_WITH_LEN("(sj-wrap)") };
/*
We're dealing with
@@ -1526,7 +1523,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
}
wrap_nest->embedding= outer_tbl->embedding;
wrap_nest->join_list= outer_tbl->join_list;
- wrap_nest->alias= (char*) "(sj-wrap)";
+ wrap_nest->alias= sj_wrap_name;
wrap_nest->nested_join->join_list.empty();
wrap_nest->nested_join->join_list.push_back(outer_tbl, thd->mem_root);
@@ -1565,6 +1562,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
TABLE_LIST *sj_nest;
NESTED_JOIN *nested_join;
+ LEX_CSTRING sj_nest_name= { STRING_WITH_LEN("(sj-nest)") };
if (!(sj_nest= alloc_join_nest(thd)))
{
DBUG_RETURN(TRUE);
@@ -1573,7 +1571,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
sj_nest->join_list= emb_join_list;
sj_nest->embedding= emb_tbl_nest;
- sj_nest->alias= (char*) "(sj-nest)";
+ sj_nest->alias= sj_nest_name;
sj_nest->sj_subq_pred= subq_pred;
sj_nest->original_subq_pred_used_tables= subq_pred->used_tables() |
subq_pred->left_expr->used_tables();
@@ -1631,7 +1629,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
// The subqueries were replaced for Item_int(1) earlier
subq_pred->reset_strategy(SUBS_SEMI_JOIN); // for subsequent executions
- /*TODO: also reset the 'with_subselect' there. */
+ /*TODO: also reset the 'm_with_subquery' there. */
/* n. Adjust the parent_join->table_count counter */
uint table_no= parent_join->table_count;
@@ -1846,13 +1844,15 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
const int SUBQERY_TEMPTABLE_NAME_MAX_LEN= 20;
-static void create_subquery_temptable_name(char *to, uint number)
+static void create_subquery_temptable_name(LEX_STRING *str, uint number)
{
+ char *to= str->str;
DBUG_ASSERT(number < 10000);
to= strmov(to, "<subquery");
to= int10_to_str((int) number, to, 10);
to[0]= '>';
to[1]= 0;
+ str->length= (size_t) (to - str->str)+1;
}
@@ -1880,7 +1880,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
TABLE_LIST *tl;
bool optimization_delayed= TRUE;
TABLE_LIST *jtbm;
- char *tbl_alias;
+ LEX_STRING tbl_alias;
THD *thd= parent_join->thd;
DBUG_ENTER("convert_subq_to_jtbm");
@@ -1889,7 +1889,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
*remove_item= TRUE;
- if (!(tbl_alias= (char*)thd->calloc(SUBQERY_TEMPTABLE_NAME_MAX_LEN)) ||
+ if (!(tbl_alias.str= (char*)thd->calloc(SUBQERY_TEMPTABLE_NAME_MAX_LEN)) ||
!(jtbm= alloc_join_nest(thd))) //todo: this is not a join nest!
{
DBUG_RETURN(TRUE);
@@ -1929,9 +1929,10 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
jtbm->jtbm_table_no= parent_join->table_count;
- create_subquery_temptable_name(tbl_alias,
+ create_subquery_temptable_name(&tbl_alias,
subq_pred->unit->first_select()->select_number);
- jtbm->alias= tbl_alias;
+ jtbm->alias.str= tbl_alias.str;
+ jtbm->alias.length= tbl_alias.length;
parent_join->table_count++;
DBUG_RETURN(thd->is_fatal_error);
}
@@ -1951,9 +1952,10 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
DBUG_EXECUTE("where", print_where(conds,"SJ-EXPR", QT_ORDINARY););
- create_subquery_temptable_name(tbl_alias, hash_sj_engine->materialize_join->
+ create_subquery_temptable_name(&tbl_alias, hash_sj_engine->materialize_join->
select_lex->select_number);
- jtbm->alias= tbl_alias;
+ jtbm->alias.str= tbl_alias.str;
+ jtbm->alias.length= tbl_alias.length;
parent_lex->have_merged_subqueries= TRUE;
@@ -2468,7 +2470,7 @@ static uint get_tmp_table_rec_length(Ref_ptr_array p_items, uint elements)
@return the cost of one lookup
*/
-static double
+double
get_tmp_table_lookup_cost(THD *thd, double row_count, uint row_size)
{
if (row_count * row_size > thd->variables.max_heap_table_size)
@@ -2488,7 +2490,7 @@ get_tmp_table_lookup_cost(THD *thd, double row_count, uint row_size)
@return the cost of writing one row
*/
-static double
+double
get_tmp_table_write_cost(THD *thd, double row_count, uint row_size)
{
double lookup_cost= get_tmp_table_lookup_cost(thd, row_count, row_size);
@@ -2666,7 +2668,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
LooseScan detector in best_access_path)
*/
remaining_tables &= ~new_join_tab->table->map;
- table_map dups_producing_tables;
+ table_map dups_producing_tables, UNINIT_VAR(prev_dups_producing_tables),
+ UNINIT_VAR(prev_sjm_lookup_tables);
if (idx == join->const_tables)
dups_producing_tables= 0;
@@ -2677,7 +2680,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
if ((emb_sj_nest= new_join_tab->emb_sj_nest))
dups_producing_tables |= emb_sj_nest->sj_inner_tables;
- Semi_join_strategy_picker **strategy;
+ Semi_join_strategy_picker **strategy, **prev_strategy= 0;
if (idx == join->const_tables)
{
/* First table, initialize pickers */
@@ -2729,23 +2732,54 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
3. We have no clue what to do about fanount of semi-join Y.
*/
if ((dups_producing_tables & handled_fanout) ||
- (read_time < *current_read_time &&
+ (read_time < *current_read_time &&
!(handled_fanout & pos->inner_tables_handled_with_other_sjs)))
{
- /* Mark strategy as used */
- (*strategy)->mark_used();
- pos->sj_strategy= sj_strategy;
- if (sj_strategy == SJ_OPT_MATERIALIZE)
- join->sjm_lookup_tables |= handled_fanout;
+ DBUG_ASSERT(pos->sj_strategy != sj_strategy);
+ /*
+ If the strategy choosen first time or
+ the strategy replace strategy which was used to exectly the same
+ tables
+ */
+ if (pos->sj_strategy == SJ_OPT_NONE ||
+ handled_fanout ==
+ (prev_dups_producing_tables ^ dups_producing_tables))
+ {
+ prev_strategy= strategy;
+ if (pos->sj_strategy == SJ_OPT_NONE)
+ {
+ prev_dups_producing_tables= dups_producing_tables;
+ prev_sjm_lookup_tables= join->sjm_lookup_tables;
+ }
+ /* Mark strategy as used */
+ (*strategy)->mark_used();
+ pos->sj_strategy= sj_strategy;
+ if (sj_strategy == SJ_OPT_MATERIALIZE)
+ join->sjm_lookup_tables |= handled_fanout;
+ else
+ join->sjm_lookup_tables &= ~handled_fanout;
+ *current_read_time= read_time;
+ *current_record_count= rec_count;
+ dups_producing_tables &= ~handled_fanout;
+ //TODO: update bitmap of semi-joins that were handled together with
+ // others.
+ if (is_multiple_semi_joins(join, join->positions, idx,
+ handled_fanout))
+ pos->inner_tables_handled_with_other_sjs |= handled_fanout;
+ }
else
- join->sjm_lookup_tables &= ~handled_fanout;
- *current_read_time= read_time;
- *current_record_count= rec_count;
- dups_producing_tables &= ~handled_fanout;
- //TODO: update bitmap of semi-joins that were handled together with
- // others.
- if (is_multiple_semi_joins(join, join->positions, idx, handled_fanout))
- pos->inner_tables_handled_with_other_sjs |= handled_fanout;
+ {
+ /* Conflict fall to most general variant */
+ (*prev_strategy)->set_empty();
+ dups_producing_tables= prev_dups_producing_tables;
+ join->sjm_lookup_tables= prev_sjm_lookup_tables;
+ // mark it 'none' to avpoid loops
+ pos->sj_strategy= SJ_OPT_NONE;
+ // next skip to last;
+ strategy= pickers +
+ (sizeof(pickers)/sizeof(Semi_join_strategy_picker*) - 3);
+ continue;
+ }
}
else
{
@@ -3677,6 +3711,7 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
sjm->sjm_table_param.init();
sjm->sjm_table_param.bit_fields_as_long= TRUE;
SELECT_LEX *subq_select= emb_sj_nest->sj_subq_pred->unit->first_select();
+ const LEX_CSTRING sj_materialize_name= { STRING_WITH_LEN("sj-materialize") };
Ref_ptr_array p_items= subq_select->ref_pointer_array;
for (uint i= 0; i < subq_select->item_list.elements; i++)
sjm->sjm_table_cols.push_back(p_items[i], thd->mem_root);
@@ -3690,7 +3725,7 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
1, /*save_sum_fields*/
thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS,
HA_POS_ERROR /*rows_limit */,
- (char*)"sj-materialize")))
+ &sj_materialize_name)))
DBUG_RETURN(TRUE); /* purecov: inspected */
sjm->table->map= emb_sj_nest->nested_join->used_tables;
sjm->table->file->extra(HA_EXTRA_WRITE_CACHE);
@@ -4094,7 +4129,8 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
using_unique_constraint= TRUE;
/* STEP 3: Allocate memory for temptable description */
- init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
+ init_sql_alloc(&own_root, "SJ_TMP_TABLE",
+ TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
if (!multi_alloc_root(&own_root,
&table, sizeof(*table),
&share, sizeof(*share),
@@ -5307,6 +5343,7 @@ TABLE *create_dummy_tmp_table(THD *thd)
sjm_table_param.init();
sjm_table_param.field_count= 1;
List<Item> sjm_table_cols;
+ const LEX_CSTRING dummy_name= { STRING_WITH_LEN("dummy") };
Item *column_item= new (thd->mem_root) Item_int(thd, 1);
if (!column_item)
DBUG_RETURN(NULL);
@@ -5319,7 +5356,7 @@ TABLE *create_dummy_tmp_table(THD *thd)
thd->variables.option_bits |
TMP_TABLE_ALL_COLUMNS,
HA_POS_ERROR /*rows_limit */,
- (char*)"dummy", TRUE /* Do not open */)))
+ &dummy_name, TRUE /* Do not open */)))
{
DBUG_RETURN(NULL);
}
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 72b28473e15..43d1c2de7ad 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -398,6 +398,8 @@ int opt_sum_query(THD *thd,
const_result= 0;
break;
}
+ longlong info_limit= 1;
+ table->file->info_push(INFO_KIND_FORCE_LIMIT_BEGIN, &info_limit);
if (!(error= table->file->ha_index_init((uint) ref.key, 1)))
error= (is_max ?
get_index_max_value(table, &ref, range_fl) :
@@ -410,6 +412,7 @@ int opt_sum_query(THD *thd,
error= HA_ERR_KEY_NOT_FOUND;
table->file->ha_end_keyread();
table->file->ha_index_end();
+ table->file->info_push(INFO_KIND_FORCE_LIMIT_END, NULL);
if (error)
{
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc
index 390afc575ca..ef9b07cca47 100644
--- a/sql/opt_table_elimination.cc
+++ b/sql/opt_table_elimination.cc
@@ -1810,6 +1810,7 @@ static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl)
{
DBUG_PRINT("info", ("Eliminated table %s", table->alias.c_ptr()));
tab->type= JT_CONST;
+ tab->table->const_table= 1;
join->eliminated_tables |= table->map;
join->const_table_map|= table->map;
set_position(join, join->const_tables++, tab, (KEYUSE*)0);
diff --git a/sql/parse_file.cc b/sql/parse_file.cc
index aedb7a4f0af..90d766f15d2 100644
--- a/sql/parse_file.cc
+++ b/sql/parse_file.cc
@@ -760,12 +760,12 @@ File_parser::parse(uchar* base, MEM_ROOT *mem_root,
{
File_option *parameter= parameters+first_param,
*parameters_end= parameters+required;
- int len= 0;
+ size_t len= 0;
for (; parameter < parameters_end; parameter++)
{
len= parameter->name.length;
// check length
- if (len < (end-ptr) && ptr[len] != '=')
+ if (len < (size_t)(end-ptr) && ptr[len] != '=')
continue;
// check keyword
if (memcmp(parameter->name.str, ptr, len) == 0)
diff --git a/sql/partition_element.h b/sql/partition_element.h
index c774994b7f5..45900c77cfc 100644
--- a/sql/partition_element.h
+++ b/sql/partition_element.h
@@ -26,7 +26,8 @@ enum partition_type {
NOT_A_PARTITION= 0,
RANGE_PARTITION,
HASH_PARTITION,
- LIST_PARTITION
+ LIST_PARTITION,
+ VERSIONING_PARTITION
};
enum partition_state {
@@ -89,8 +90,21 @@ typedef struct p_elem_val
struct st_ddl_log_memory_entry;
-class partition_element :public Sql_alloc {
+enum stat_trx_field
+{
+ STAT_TRX_END= 0
+};
+
+class partition_element :public Sql_alloc
+{
public:
+ enum elem_type
+ {
+ CONVENTIONAL= 0,
+ CURRENT,
+ HISTORY
+ };
+
List<partition_element> subpartitions;
List<part_elem_value> list_val_list;
ha_rows part_max_rows;
@@ -109,6 +123,21 @@ public:
bool has_null_value;
bool signed_flag; // Range value signed
bool max_value; // MAXVALUE range
+ uint32 id;
+ bool empty;
+
+ // TODO: subclass partition_element by partitioning type to avoid such semantic
+ // mixup
+ elem_type type()
+ {
+ return (elem_type)(int(signed_flag) << 1 | int(max_value));
+ }
+
+ void type(elem_type val)
+ {
+ max_value= (bool)(val & 1);
+ signed_flag= (bool)(val & 2);
+ }
partition_element()
: part_max_rows(0), part_min_rows(0), range_value(0),
@@ -117,9 +146,10 @@ public:
data_file_name(NULL), index_file_name(NULL),
engine_type(NULL), connect_string(null_clex_str), part_state(PART_NORMAL),
nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE),
- signed_flag(FALSE), max_value(FALSE)
- {
- }
+ signed_flag(FALSE), max_value(FALSE),
+ id(UINT_MAX32),
+ empty(true)
+ {}
partition_element(partition_element *part_elem)
: part_max_rows(part_elem->part_max_rows),
part_min_rows(part_elem->part_min_rows),
@@ -132,10 +162,35 @@ public:
connect_string(null_clex_str),
part_state(part_elem->part_state),
nodegroup_id(part_elem->nodegroup_id),
- has_null_value(FALSE)
+ has_null_value(FALSE),
+ id(part_elem->id),
+ empty(part_elem->empty)
+ {}
+ ~partition_element() {}
+
+ part_column_list_val& get_col_val(uint idx)
{
+ DBUG_ASSERT(type() == CONVENTIONAL || list_val_list.elements == 1);
+ part_elem_value *ev= list_val_list.head();
+ DBUG_ASSERT(ev);
+ DBUG_ASSERT(ev->col_val_array);
+ return ev->col_val_array[idx];
+ }
+
+ bool find_engine_flag(uint32 flag)
+ {
+ if (ha_check_storage_engine_flag(engine_type, flag))
+ return true;
+
+ List_iterator_fast<partition_element> it(subpartitions);
+ while (partition_element *element= it++)
+ {
+ if (element->find_engine_flag(flag))
+ return true;
+ }
+
+ return false;
}
- ~partition_element() {}
};
#endif /* PARTITION_ELEMENT_INCLUDED */
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 6fdbdfce893..87d322cf7fa 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2006, 2015, Oracle and/or its affiliates.
- Copyright (c) 2010, 2015, MariaDB
+ Copyright (c) 2010, 2018, 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
@@ -21,6 +21,8 @@
#endif
#include "mariadb.h"
+#include <my_global.h>
+#include <tztime.h>
#include "sql_priv.h"
// Required to get server definitions for mysql/plugin.h right
#include "sql_plugin.h"
@@ -30,6 +32,9 @@
#include "sql_parse.h"
#include "sql_acl.h" // *_ACL
#include "sql_base.h" // fill_record
+#include "sql_statistics.h" // vers_stat_end
+#include "vers_utils.h"
+#include "lock.h"
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
@@ -42,13 +47,12 @@ partition_info *partition_info::get_clone(THD *thd)
List_iterator<partition_element> part_it(partitions);
partition_element *part;
- partition_info *clone= new (mem_root) partition_info();
+ partition_info *clone= new (mem_root) partition_info(*this);
if (!clone)
{
mem_alloc_error(sizeof(partition_info));
DBUG_RETURN(NULL);
}
- memcpy(clone, this, sizeof(partition_info));
memset(&(clone->read_partitions), 0, sizeof(clone->read_partitions));
memset(&(clone->lock_partitions), 0, sizeof(clone->lock_partitions));
clone->bitmaps_are_initialized= FALSE;
@@ -114,6 +118,19 @@ partition_info *partition_info::get_clone(THD *thd)
part_clone->list_val_list.push_back(new_val, mem_root);
}
}
+ if (part_type == VERSIONING_PARTITION && vers_info)
+ {
+ // clone Vers_part_info; set now_part, hist_part
+ clone->vers_info= new (mem_root) Vers_part_info(*vers_info);
+ List_iterator<partition_element> it(clone->partitions);
+ while ((part= it++))
+ {
+ if (vers_info->now_part && part->id == vers_info->now_part->id)
+ clone->vers_info->now_part= part;
+ else if (vers_info->hist_part && part->id == vers_info->hist_part->id)
+ clone->vers_info->hist_part= part;
+ } // while ((part= it++))
+ } // if (part_type == VERSIONING_PARTITION ...
DBUG_RETURN(clone);
}
@@ -128,8 +145,7 @@ partition_info *partition_info::get_clone(THD *thd)
@retval false Partition not found
*/
-bool partition_info::add_named_partition(const char *part_name,
- uint length)
+bool partition_info::add_named_partition(const char *part_name, size_t length)
{
HASH *part_name_hash;
PART_NAME_DEF *part_def;
@@ -180,8 +196,7 @@ bool partition_info::add_named_partition(const char *part_name,
@param part_elem Partition element that matched.
*/
-bool partition_info::set_named_partition_bitmap(const char *part_name,
- uint length)
+bool partition_info::set_named_partition_bitmap(const char *part_name, size_t length)
{
DBUG_ENTER("partition_info::set_named_partition_bitmap");
bitmap_clear_all(&read_partitions);
@@ -200,13 +215,55 @@ bool partition_info::set_named_partition_bitmap(const char *part_name,
@param table_list Table list pointing to table to prune.
@return Operation status
+ @retval false Success
+ @retval true Failure
+*/
+bool partition_info::set_read_partitions(List<char> *partition_names)
+{
+ DBUG_ENTER("partition_info::set_read_partitions");
+ if (!partition_names || !partition_names->elements)
+ {
+ DBUG_RETURN(true);
+ }
+
+ uint num_names= partition_names->elements;
+ List_iterator<char> partition_names_it(*partition_names);
+ uint i= 0;
+ /*
+ TODO: When adding support for FK in partitioned tables, the referenced
+ table must probably lock all partitions for read, and also write depending
+ of ON DELETE/UPDATE.
+ */
+ bitmap_clear_all(&read_partitions);
+
+ /* No check for duplicate names or overlapping partitions/subpartitions. */
+
+ DBUG_PRINT("info", ("Searching through partition_name_hash"));
+ do
+ {
+ char *part_name= partition_names_it++;
+ if (add_named_partition(part_name, strlen(part_name)))
+ DBUG_RETURN(true);
+ } while (++i < num_names);
+ DBUG_RETURN(false);
+}
+
+
+
+/**
+ Prune away partitions not mentioned in the PARTITION () clause,
+ if used.
+
+ @param partition_names list of names of partitions.
+
+ @return Operation status
@retval true Failure
@retval false Success
*/
-bool partition_info::prune_partition_bitmaps(TABLE_LIST *table_list)
+bool partition_info::prune_partition_bitmaps(List<String> *partition_names)
{
- List_iterator<String> partition_names_it(*(table_list->partition_names));
- uint num_names= table_list->partition_names->elements;
+ List_iterator<String> partition_names_it(*(partition_names));
+ uint num_names= partition_names->elements;
uint i= 0;
DBUG_ENTER("partition_info::prune_partition_bitmaps");
@@ -236,8 +293,7 @@ bool partition_info::prune_partition_bitmaps(TABLE_LIST *table_list)
/**
Set read/lock_partitions bitmap over non pruned partitions
- @param table_list Possible TABLE_LIST which can contain
- list of partition names to query
+ @param partition_names list of partition names to query
@return Operation status
@retval FALSE OK
@@ -247,7 +303,7 @@ bool partition_info::prune_partition_bitmaps(TABLE_LIST *table_list)
@note OK to call multiple times without the need for free_bitmaps.
*/
-bool partition_info::set_partition_bitmaps(TABLE_LIST *table_list)
+bool partition_info::set_partition_bitmaps(List<String> *partition_names)
{
DBUG_ENTER("partition_info::set_partition_bitmaps");
@@ -256,16 +312,15 @@ bool partition_info::set_partition_bitmaps(TABLE_LIST *table_list)
if (!bitmaps_are_initialized)
DBUG_RETURN(TRUE);
- if (table_list &&
- table_list->partition_names &&
- table_list->partition_names->elements)
+ if (partition_names &&
+ partition_names->elements)
{
if (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)
{
my_error(ER_PARTITION_CLAUSE_ON_NONPARTITIONED, MYF(0));
DBUG_RETURN(true);
}
- if (prune_partition_bitmaps(table_list))
+ if (prune_partition_bitmaps(partition_names))
DBUG_RETURN(TRUE);
}
else
@@ -279,6 +334,27 @@ bool partition_info::set_partition_bitmaps(TABLE_LIST *table_list)
}
+/**
+ Set read/lock_partitions bitmap over non pruned partitions
+
+ @param table_list Possible TABLE_LIST which can contain
+ list of partition names to query
+
+ @return Operation status
+ @retval FALSE OK
+ @retval TRUE Failed to allocate memory for bitmap or list of partitions
+ did not match
+
+ @note OK to call multiple times without the need for free_bitmaps.
+*/
+bool partition_info::set_partition_bitmaps_from_table(TABLE_LIST *table_list)
+{
+ List<String> *partition_names= table_list ?
+ NULL : table_list->partition_names;
+ return set_partition_bitmaps(partition_names);
+}
+
+
/*
Create a memory area where default partition names are stored and fill it
up with the names.
@@ -341,7 +417,7 @@ char *partition_info::create_default_partition_names(THD *thd, uint part_no,
char *partition_info::create_default_subpartition_name(THD *thd, uint subpart_no,
const char *part_name)
{
- uint size_alloc= strlen(part_name) + MAX_PART_NAME_SIZE;
+ size_t size_alloc= strlen(part_name) + MAX_PART_NAME_SIZE;
char *ptr= (char*) thd->calloc(size_alloc);
DBUG_ENTER("create_default_subpartition_name");
@@ -780,6 +856,115 @@ bool partition_info::has_unique_name(partition_element *element)
DBUG_RETURN(TRUE);
}
+bool partition_info::vers_init_info(THD * thd)
+{
+ part_type= VERSIONING_PARTITION;
+ list_of_part_fields= TRUE;
+ column_list= TRUE;
+ num_columns= 1;
+ vers_info= new (thd->mem_root) Vers_part_info;
+ if (!vers_info)
+ {
+ mem_alloc_error(sizeof(Vers_part_info));
+ return true;
+ }
+ return false;
+}
+
+void partition_info::vers_set_hist_part(THD *thd)
+{
+ if (vers_info->limit)
+ {
+ ha_partition *hp= (ha_partition*)(table->file);
+ partition_element *next= NULL;
+ List_iterator<partition_element> it(partitions);
+ while (next != vers_info->hist_part)
+ next= it++;
+ ha_rows records= hp->part_records(next);
+ while ((next= it++) != vers_info->now_part)
+ {
+ ha_rows next_records= hp->part_records(next);
+ if (next_records == 0)
+ break;
+ vers_info->hist_part= next;
+ records= next_records;
+ }
+ if (records > vers_info->limit)
+ {
+ if (next == vers_info->now_part)
+ goto warn;
+ vers_info->hist_part= next;
+ }
+ return;
+ }
+
+ if (vers_info->interval.is_set())
+ {
+ if (vers_info->hist_part->range_value > thd->system_time)
+ return;
+
+ partition_element *next= NULL;
+ List_iterator<partition_element> it(partitions);
+ while (next != vers_info->hist_part)
+ next= it++;
+
+ while ((next= it++) != vers_info->now_part)
+ {
+ vers_info->hist_part= next;
+ if (next->range_value > thd->system_time)
+ return;
+ }
+ goto warn;
+ }
+ return;
+warn:
+ my_error(WARN_VERS_PART_FULL, MYF(ME_WARNING|ME_ERROR_LOG),
+ table->s->db.str, table->s->error_table_name(),
+ vers_info->hist_part->partition_name);
+}
+
+
+bool partition_info::vers_setup_expression(THD * thd, uint32 alter_add)
+{
+ if (!table->versioned())
+ {
+ // frm must be corrupted, normally CREATE/ALTER TABLE checks for that
+ my_error(ER_FILE_CORRUPT, MYF(0), table->s->path.str);
+ return true;
+ }
+
+ DBUG_ASSERT(part_type == VERSIONING_PARTITION);
+ DBUG_ASSERT(table->versioned(VERS_TIMESTAMP));
+ DBUG_ASSERT(num_columns == 1);
+
+ if (!alter_add)
+ {
+ Field *row_end= table->vers_end_field();
+ part_field_list.push_back(row_end->field_name.str, thd->mem_root);
+ DBUG_ASSERT(part_field_list.elements == 1);
+ // needed in handle_list_of_fields()
+ row_end->flags|= GET_FIXED_FIELDS_FLAG;
+ }
+
+ if (alter_add)
+ {
+ List_iterator<partition_element> it(partitions);
+ partition_element *el;
+ for(uint32 id= 0; ((el= it++)); id++)
+ {
+ DBUG_ASSERT(el->type() != partition_element::CONVENTIONAL);
+ /* Newly added element is inserted before AS_OF_NOW. */
+ if (el->id == UINT_MAX32 || el->type() == partition_element::CURRENT)
+ {
+ el->id= id;
+ if (el->type() == partition_element::CURRENT)
+ break;
+ }
+ }
+ }
+ return false;
+}
+
/*
Check that the partition/subpartition is setup to use the correct
@@ -942,394 +1127,6 @@ error:
}
-/*
- This routine allocates an array for all range constants to achieve a fast
- check what partition a certain value belongs to. At the same time it does
- also check that the range constants are defined in increasing order and
- that the expressions are constant integer expressions.
-
- SYNOPSIS
- check_range_constants()
- thd Thread object
-
- RETURN VALUE
- TRUE An error occurred during creation of range constants
- FALSE Successful creation of range constant mapping
-
- DESCRIPTION
- This routine is called from check_partition_info to get a quick error
- before we came too far into the CREATE TABLE process. It is also called
- from fix_partition_func every time we open the .frm file. It is only
- called for RANGE PARTITIONed tables.
-*/
-
-bool partition_info::check_range_constants(THD *thd)
-{
- partition_element* part_def;
- bool first= TRUE;
- uint i;
- List_iterator<partition_element> it(partitions);
- int result= TRUE;
- DBUG_ENTER("partition_info::check_range_constants");
- DBUG_PRINT("enter", ("RANGE with %d parts, column_list = %u", num_parts,
- column_list));
-
- if (column_list)
- {
- part_column_list_val *loc_range_col_array;
- part_column_list_val *UNINIT_VAR(current_largest_col_val);
- uint num_column_values= part_field_list.elements;
- uint size_entries= sizeof(part_column_list_val) * num_column_values;
- range_col_array= (part_column_list_val*) thd->calloc(num_parts *
- size_entries);
- if (unlikely(range_col_array == NULL))
- {
- mem_alloc_error(num_parts * size_entries);
- goto end;
- }
- loc_range_col_array= range_col_array;
- i= 0;
- do
- {
- part_def= it++;
- {
- List_iterator<part_elem_value> list_val_it(part_def->list_val_list);
- part_elem_value *range_val= list_val_it++;
- part_column_list_val *col_val= range_val->col_val_array;
-
- if (fix_column_value_functions(thd, range_val, i))
- goto end;
- memcpy(loc_range_col_array, (const void*)col_val, size_entries);
- loc_range_col_array+= num_column_values;
- if (!first)
- {
- if (compare_column_values((const void*)current_largest_col_val,
- (const void*)col_val) >= 0)
- goto range_not_increasing_error;
- }
- current_largest_col_val= col_val;
- }
- first= FALSE;
- } while (++i < num_parts);
- }
- else
- {
- longlong UNINIT_VAR(current_largest);
- longlong part_range_value;
- bool signed_flag= !part_expr->unsigned_flag;
-
- range_int_array= (longlong*) thd->alloc(num_parts * sizeof(longlong));
- if (unlikely(range_int_array == NULL))
- {
- mem_alloc_error(num_parts * sizeof(longlong));
- goto end;
- }
- i= 0;
- do
- {
- part_def= it++;
- if ((i != (num_parts - 1)) || !defined_max_value)
- {
- part_range_value= part_def->range_value;
- if (!signed_flag)
- part_range_value-= 0x8000000000000000ULL;
- }
- else
- part_range_value= LONGLONG_MAX;
-
- if (!first)
- {
- if (unlikely(current_largest > part_range_value) ||
- (unlikely(current_largest == part_range_value) &&
- (part_range_value < LONGLONG_MAX ||
- i != (num_parts - 1) ||
- !defined_max_value)))
- goto range_not_increasing_error;
- }
- range_int_array[i]= part_range_value;
- current_largest= part_range_value;
- first= FALSE;
- } while (++i < num_parts);
- }
- result= FALSE;
-end:
- DBUG_RETURN(result);
-
-range_not_increasing_error:
- my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
- goto end;
-}
-
-
-/*
- Support routines for check_list_constants used by qsort to sort the
- constant list expressions. One routine for integers and one for
- column lists.
-
- SYNOPSIS
- list_part_cmp()
- a First list constant to compare with
- b Second list constant to compare with
-
- RETURN VALUE
- +1 a > b
- 0 a == b
- -1 a < b
-*/
-
-extern "C"
-int partition_info_list_part_cmp(const void* a, const void* b)
-{
- longlong a1= ((LIST_PART_ENTRY*)a)->list_value;
- longlong b1= ((LIST_PART_ENTRY*)b)->list_value;
- if (a1 < b1)
- return -1;
- else if (a1 > b1)
- return +1;
- else
- return 0;
-}
-
-
-int partition_info::list_part_cmp(const void* a, const void* b)
-{
- return partition_info_list_part_cmp(a, b);
-}
-
-
-/*
- Compare two lists of column values in RANGE/LIST partitioning
- SYNOPSIS
- compare_column_values()
- first First column list argument
- second Second column list argument
- RETURN VALUES
- 0 Equal
- -1 First argument is smaller
- +1 First argument is larger
-*/
-
-extern "C"
-int partition_info_compare_column_values(const void *first_arg,
- const void *second_arg)
-{
- const part_column_list_val *first= (part_column_list_val*)first_arg;
- const part_column_list_val *second= (part_column_list_val*)second_arg;
- partition_info *part_info= first->part_info;
- Field **field;
-
- for (field= part_info->part_field_array; *field;
- field++, first++, second++)
- {
- if (first->max_value || second->max_value)
- {
- if (first->max_value && second->max_value)
- return 0;
- if (second->max_value)
- return -1;
- else
- return +1;
- }
- if (first->null_value || second->null_value)
- {
- if (first->null_value && second->null_value)
- continue;
- if (second->null_value)
- return +1;
- else
- return -1;
- }
- int res= (*field)->cmp((const uchar*)first->column_value,
- (const uchar*)second->column_value);
- if (res)
- return res;
- }
- return 0;
-}
-
-
-int partition_info::compare_column_values(const void *first_arg,
- const void *second_arg)
-{
- return partition_info_compare_column_values(first_arg, second_arg);
-}
-
-
-/*
- This routine allocates an array for all list constants to achieve a fast
- check what partition a certain value belongs to. At the same time it does
- also check that there are no duplicates among the list constants and that
- that the list expressions are constant integer expressions.
-
- SYNOPSIS
- check_list_constants()
- thd Thread object
-
- RETURN VALUE
- TRUE An error occurred during creation of list constants
- FALSE Successful creation of list constant mapping
-
- DESCRIPTION
- This routine is called from check_partition_info to get a quick error
- before we came too far into the CREATE TABLE process. It is also called
- from fix_partition_func every time we open the .frm file. It is only
- called for LIST PARTITIONed tables.
-*/
-
-bool partition_info::check_list_constants(THD *thd)
-{
- uint i, size_entries, num_column_values;
- uint list_index= 0;
- part_elem_value *list_value;
- bool result= TRUE;
- longlong type_add, calc_value;
- void *curr_value;
- void *UNINIT_VAR(prev_value);
- partition_element* part_def;
- bool found_null= FALSE;
- qsort_cmp compare_func;
- void *ptr;
- List_iterator<partition_element> list_func_it(partitions);
- DBUG_ENTER("partition_info::check_list_constants");
-
- DBUG_ASSERT(part_type == LIST_PARTITION);
-
- num_list_values= 0;
- /*
- We begin by calculating the number of list values that have been
- defined in the first step.
-
- We use this number to allocate a properly sized array of structs
- to keep the partition id and the value to use in that partition.
- In the second traversal we assign them values in the struct array.
-
- Finally we sort the array of structs in order of values to enable
- a quick binary search for the proper value to discover the
- partition id.
- After sorting the array we check that there are no duplicates in the
- list.
- */
-
- i= 0;
- do
- {
- part_def= list_func_it++;
- if (part_def->has_null_value)
- {
- if (found_null)
- {
- my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
- goto end;
- }
- has_null_value= TRUE;
- has_null_part_id= i;
- found_null= TRUE;
- }
- num_list_values+= part_def->list_val_list.elements;
- } while (++i < num_parts);
- list_func_it.rewind();
- num_column_values= part_field_list.elements;
- size_entries= column_list ?
- (num_column_values * sizeof(part_column_list_val)) :
- sizeof(LIST_PART_ENTRY);
- if (unlikely(!(ptr= thd->calloc((num_list_values+1) * size_entries))))
- goto end;
- if (column_list)
- {
- part_column_list_val *loc_list_col_array;
- loc_list_col_array= (part_column_list_val*)ptr;
- list_col_array= (part_column_list_val*)ptr;
- compare_func= partition_info_compare_column_values;
- i= 0;
- do
- {
- part_def= list_func_it++;
- if (part_def->max_value)
- {
- // DEFAULT is not a real value so let's exclude it from sorting.
- DBUG_ASSERT(num_list_values);
- num_list_values--;
- continue;
- }
- List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
- while ((list_value= list_val_it2++))
- {
- part_column_list_val *col_val= list_value->col_val_array;
- if (unlikely(fix_column_value_functions(thd, list_value, i)))
- {
- DBUG_RETURN(TRUE);
- }
- memcpy(loc_list_col_array, (const void*)col_val, size_entries);
- loc_list_col_array+= num_column_values;
- }
- } while (++i < num_parts);
- }
- else
- {
- compare_func= partition_info_list_part_cmp;
- list_array= (LIST_PART_ENTRY*)ptr;
- i= 0;
- /*
- Fix to be able to reuse signed sort functions also for unsigned
- partition functions.
- */
- type_add= (longlong)(part_expr->unsigned_flag ?
- 0x8000000000000000ULL :
- 0ULL);
-
- do
- {
- part_def= list_func_it++;
- if (part_def->max_value && part_type == LIST_PARTITION)
- {
- // DEFAULT is not a real value so let's exclude it from sorting.
- DBUG_ASSERT(num_list_values);
- num_list_values--;
- continue;
- }
- List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
- while ((list_value= list_val_it2++))
- {
- calc_value= list_value->value - type_add;
- list_array[list_index].list_value= calc_value;
- list_array[list_index++].partition_id= i;
- }
- } while (++i < num_parts);
- }
- DBUG_ASSERT(fixed);
- if (num_list_values)
- {
- bool first= TRUE;
- /*
- list_array and list_col_array are unions, so this works for both
- variants of LIST partitioning.
- */
- my_qsort((void*)list_array, num_list_values, size_entries,
- compare_func);
-
- i= 0;
- do
- {
- DBUG_ASSERT(i < num_list_values);
- curr_value= column_list ? (void*)&list_col_array[num_column_values * i] :
- (void*)&list_array[i];
- if (likely(first || compare_func(curr_value, prev_value)))
- {
- prev_value= curr_value;
- first= FALSE;
- }
- else
- {
- my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
- goto end;
- }
- } while (++i < num_list_values);
- }
- result= FALSE;
-end:
- DBUG_RETURN(result);
-}
-
/**
Check if we allow DATA/INDEX DIRECTORY, if not warn and set them to NULL.
@@ -1380,12 +1177,14 @@ static void warn_if_dir_in_part_elem(THD *thd, partition_element *part_elem)
bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
handler *file, HA_CREATE_INFO *info,
- bool add_or_reorg_part)
+ partition_info *add_or_reorg_part)
{
handlerton *table_engine= default_engine_type;
uint i, tot_partitions;
bool result= TRUE, table_engine_set;
const char *same_name;
+ uint32 hist_parts= 0;
+ uint32 now_parts= 0;
DBUG_ENTER("partition_info::check_partition_info");
DBUG_ASSERT(default_engine_type != partition_hton);
@@ -1427,7 +1226,8 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
}
if (unlikely(is_sub_partitioned() &&
(!(part_type == RANGE_PARTITION ||
- part_type == LIST_PARTITION))))
+ part_type == LIST_PARTITION ||
+ part_type == VERSIONING_PARTITION))))
{
/* Only RANGE and LIST partitioning can be subpartitioned */
my_error(ER_SUBPARTITION_ERROR, MYF(0));
@@ -1489,6 +1289,19 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
my_error(ER_SAME_NAME_PARTITION, MYF(0), same_name);
goto end;
}
+
+ if (part_type == VERSIONING_PARTITION)
+ {
+ DBUG_ASSERT(vers_info);
+ if (num_parts < 2 || !vers_info->now_part)
+ {
+ DBUG_ASSERT(info);
+ DBUG_ASSERT(info->alias.str);
+ my_error(ER_VERS_WRONG_PARTS, MYF(0), info->alias.str);
+ goto end;
+ }
+ DBUG_ASSERT(num_parts == partitions.elements);
+ }
i= 0;
{
List_iterator<partition_element> part_it(partitions);
@@ -1569,6 +1382,18 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
}
}
}
+ if (part_type == VERSIONING_PARTITION)
+ {
+ if (part_elem->type() == partition_element::HISTORY)
+ {
+ hist_parts++;
+ }
+ else
+ {
+ DBUG_ASSERT(part_elem->type() == partition_element::CURRENT);
+ now_parts++;
+ }
+ }
} while (++i < num_parts);
if (!table_engine_set &&
num_parts_not_set != 0 &&
@@ -1586,6 +1411,24 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
goto end;
}
+ if (hist_parts > 1)
+ {
+ if (vers_info->limit == 0 && !vers_info->interval.is_set())
+ {
+ push_warning_printf(thd,
+ Sql_condition::WARN_LEVEL_WARN,
+ WARN_VERS_PARAMETERS,
+ ER_THD(thd, WARN_VERS_PARAMETERS),
+ "no rotation condition for multiple HISTORY partitions.");
+ }
+ }
+ if (unlikely(now_parts > 1))
+ {
+ my_error(ER_VERS_WRONG_PARTS, MYF(0), info->alias.str);
+ goto end;
+ }
+
+
DBUG_ASSERT(table_engine != partition_hton &&
default_engine_type == table_engine);
if (eng_type)
@@ -1600,12 +1443,13 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
if (add_or_reorg_part)
{
- if (unlikely((part_type == RANGE_PARTITION &&
- check_range_constants(thd)) ||
- (part_type == LIST_PARTITION &&
- check_list_constants(thd))))
+ if (unlikely(part_type == VERSIONING_PARTITION &&
+ vers_setup_expression(thd, add_or_reorg_part->partitions.elements)))
+ goto end;
+ if (check_constants(thd, this))
goto end;
}
+
result= FALSE;
end:
DBUG_RETURN(result);
@@ -1630,8 +1474,8 @@ void partition_info::print_no_partition_found(TABLE *table_arg, myf errflag)
THD *thd= current_thd;
bzero(&table_list, sizeof(table_list));
- table_list.db= table_arg->s->db.str;
- table_list.table_name= table_arg->s->table_name.str;
+ table_list.db= table_arg->s->db;
+ table_list.table_name= table_arg->s->table_name;
if (check_single_table_access(thd,
SELECT_ACL, &table_list, TRUE))
@@ -2350,8 +2194,7 @@ bool partition_info::fix_column_value_functions(THD *thd,
sql_mode_t save_sql_mode;
bool save_got_warning;
- if (!(column_item= get_column_item(column_item,
- field)))
+ if (!(column_item= get_column_item(column_item, field)))
{
result= TRUE;
goto end;
@@ -2364,6 +2207,7 @@ bool partition_info::fix_column_value_functions(THD *thd,
thd->got_warning)
{
my_error(ER_WRONG_TYPE_COLUMN_VALUE_ERROR, MYF(0));
+ thd->variables.sql_mode= save_sql_mode;
result= TRUE;
goto end;
}
@@ -2384,6 +2228,7 @@ end:
DBUG_RETURN(result);
}
+
/**
Fix partition data from parser.
@@ -2474,6 +2319,8 @@ bool partition_info::fix_parser_data(THD *thd)
part_elem= it++;
List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
num_elements= part_elem->list_val_list.elements;
+ if (!num_elements && error_if_requires_values())
+ DBUG_RETURN(true);
DBUG_ASSERT(part_type == RANGE_PARTITION ?
num_elements == 1U : TRUE);
@@ -2815,6 +2662,30 @@ bool partition_info::has_same_partitioning(partition_info *new_part_info)
}
+bool partition_info::vers_trx_id_to_ts(THD* thd, Field* in_trx_id, Field_timestamp& out_ts)
+{
+ DBUG_ASSERT(table);
+ handlerton *hton= plugin_hton(table->s->db_plugin);
+ DBUG_ASSERT(hton);
+ ulonglong trx_id= in_trx_id->val_int();
+ TR_table trt(thd);
+ bool found= trt.query(trx_id);
+ if (!found)
+ {
+ push_warning_printf(thd,
+ Sql_condition::WARN_LEVEL_WARN,
+ WARN_VERS_TRX_MISSING,
+ ER_THD(thd, WARN_VERS_TRX_MISSING),
+ trx_id);
+ return true;
+ }
+ MYSQL_TIME ts;
+ trt[TR_table::FLD_COMMIT_TS]->get_date(&ts, 0);
+ out_ts.store_time_dec(&ts, 6);
+ return false;
+}
+
+
void partition_info::print_debug(const char *str, uint *value)
{
DBUG_ENTER("print_debug");
@@ -2875,3 +2746,20 @@ bool check_partition_dirs(partition_info *part_info)
}
#endif /* WITH_PARTITION_STORAGE_ENGINE */
+
+bool partition_info::error_if_requires_values() const
+{
+ switch (part_type) {
+ case NOT_A_PARTITION:
+ case HASH_PARTITION:
+ case VERSIONING_PARTITION:
+ break;
+ case RANGE_PARTITION:
+ my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "RANGE", "LESS THAN");
+ return true;
+ case LIST_PARTITION:
+ my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "LIST", "IN");
+ return true;
+ }
+ return false;
+}
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 38a353c8507..6d2e222ec30 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -22,18 +22,60 @@
#include "sql_class.h"
#include "partition_element.h"
+#include "sql_partition.h"
class partition_info;
struct TABLE_LIST;
/* Some function typedefs */
-typedef int (*get_part_id_func)(partition_info *part_info,
- uint32 *part_id,
+typedef int (*get_part_id_func)(partition_info *part_info, uint32 *part_id,
longlong *func_value);
-typedef int (*get_subpart_id_func)(partition_info *part_info,
- uint32 *part_id);
+typedef int (*get_subpart_id_func)(partition_info *part_info, uint32 *part_id);
+typedef bool (*check_constants_func)(THD *thd, partition_info *part_info);
struct st_ddl_log_memory_entry;
+struct Vers_part_info : public Sql_alloc
+{
+ Vers_part_info() :
+ limit(0),
+ now_part(NULL),
+ hist_part(NULL)
+ {
+ interval.type= INTERVAL_LAST;
+ }
+ Vers_part_info(Vers_part_info &src) :
+ interval(src.interval),
+ limit(src.limit),
+ now_part(NULL),
+ hist_part(NULL)
+ {
+ }
+ bool initialized()
+ {
+ if (now_part)
+ {
+ DBUG_ASSERT(now_part->id != UINT_MAX32);
+ DBUG_ASSERT(now_part->type() == partition_element::CURRENT);
+ if (hist_part)
+ {
+ DBUG_ASSERT(hist_part->id != UINT_MAX32);
+ DBUG_ASSERT(hist_part->type() == partition_element::HISTORY);
+ }
+ return true;
+ }
+ return false;
+ }
+ struct {
+ my_time_t start;
+ INTERVAL step;
+ enum interval_type type;
+ bool is_set() { return type < INTERVAL_LAST; }
+ } interval;
+ ulonglong limit;
+ partition_element *now_part;
+ partition_element *hist_part;
+};
+
class partition_info : public Sql_alloc
{
public:
@@ -74,6 +116,8 @@ public:
get_part_id_func get_part_partition_id_charset;
get_subpart_id_func get_subpartition_id_charset;
+ check_constants_func check_constants;
+
/* NULL-terminated array of fields used in partitioned expression */
Field **part_field_array;
Field **subpart_field_array;
@@ -143,6 +187,8 @@ public:
part_column_list_val *range_col_array;
part_column_list_val *list_col_array;
};
+
+ Vers_part_info *vers_info;
/********************************************
* INTERVAL ANALYSIS
@@ -250,7 +296,7 @@ public:
part_expr(NULL), subpart_expr(NULL), item_free_list(NULL),
first_log_entry(NULL), exec_log_entry(NULL), frm_log_entry(NULL),
bitmaps_are_initialized(FALSE),
- list_array(NULL), err_value(0),
+ list_array(NULL), vers_info(NULL), err_value(0),
part_info_string(NULL),
curr_part_elem(NULL), current_partition(NULL),
curr_list_object(0), num_columns(0), table(NULL),
@@ -282,8 +328,9 @@ public:
~partition_info() {}
partition_info *get_clone(THD *thd);
- bool set_named_partition_bitmap(const char *part_name, uint length);
- bool set_partition_bitmaps(TABLE_LIST *table_list);
+ bool set_named_partition_bitmap(const char *part_name, size_t length);
+ bool set_partition_bitmaps(List<String> *partition_names);
+ bool set_partition_bitmaps_from_table(TABLE_LIST *table_list);
/* Answers the question if subpartitioning is used for a certain table */
bool is_sub_partitioned()
{
@@ -302,11 +349,9 @@ public:
const char *find_duplicate_field();
char *find_duplicate_name();
bool check_engine_mix(handlerton *engine_type, bool default_engine);
- bool check_range_constants(THD *thd);
- bool check_list_constants(THD *thd);
bool check_partition_info(THD *thd, handlerton **eng_type,
handler *file, HA_CREATE_INFO *info,
- bool check_partition_function);
+ partition_info *add_or_reorg_part= NULL);
void print_no_partition_found(TABLE *table, myf errflag);
void print_debug(const char *str, uint*);
Item* get_column_item(Item *item, Field *field);
@@ -323,7 +368,6 @@ public:
part_column_list_val *add_column_value(THD *thd);
bool set_part_expr(THD *thd, char *start_token, Item *item_ptr,
char *end_token, bool is_subpart);
- static int compare_column_values(const void *a, const void *b);
bool set_up_charset_field_preps(THD *thd);
bool check_partition_field_length();
bool init_column_part(THD *thd);
@@ -332,8 +376,8 @@ public:
size_t file_name_size, uint32 *part_id);
void report_part_expr_error(bool use_subpart_expr);
bool has_same_partitioning(partition_info *new_part_info);
+ bool error_if_requires_values() const;
private:
- static int list_part_cmp(const void* a, const void* b);
bool set_up_default_partitions(THD *thd, handler *file, HA_CREATE_INFO *info,
uint start_no);
bool set_up_default_subpartitions(THD *thd, handler *file,
@@ -342,10 +386,45 @@ private:
uint start_no);
char *create_default_subpartition_name(THD *thd, uint subpart_no,
const char *part_name);
- bool prune_partition_bitmaps(TABLE_LIST *table_list);
- bool add_named_partition(const char *part_name, uint length);
+ // FIXME: prune_partition_bitmaps() is duplicate of set_read_partitions()
+ bool prune_partition_bitmaps(List<String> *partition_names);
+ bool add_named_partition(const char *part_name, size_t length);
public:
+ bool set_read_partitions(List<char> *partition_names);
bool has_unique_name(partition_element *element);
+
+ bool vers_init_info(THD *thd);
+ bool vers_set_interval(Item *item, interval_type int_type, my_time_t start)
+ {
+ DBUG_ASSERT(part_type == VERSIONING_PARTITION);
+ vers_info->interval.type= int_type;
+ vers_info->interval.start= start;
+ return get_interval_value(item, int_type, &vers_info->interval.step) ||
+ vers_info->interval.step.neg || vers_info->interval.step.second_part ||
+ !(vers_info->interval.step.year || vers_info->interval.step.month ||
+ vers_info->interval.step.day || vers_info->interval.step.hour ||
+ vers_info->interval.step.minute || vers_info->interval.step.second);
+ }
+ bool vers_set_limit(ulonglong limit)
+ {
+ DBUG_ASSERT(part_type == VERSIONING_PARTITION);
+ vers_info->limit= limit;
+ return !limit;
+ }
+ void vers_set_hist_part(THD *thd);
+ bool vers_setup_expression(THD *thd, uint32 alter_add= 0); /* Stage 1. */
+ partition_element *get_partition(uint part_id)
+ {
+ List_iterator<partition_element> it(partitions);
+ partition_element *el;
+ while ((el= it++))
+ {
+ if (el->id == part_id)
+ return el;
+ }
+ return NULL;
+ }
+ bool vers_trx_id_to_ts(THD *thd, Field *in_trx_id, Field_timestamp &out_ts);
};
uint32 get_next_partition_id_range(struct st_partition_iter* part_iter);
diff --git a/sql/password.c b/sql/password.c
index 47f4fd1d422..5e9684acb25 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -296,7 +296,7 @@ void make_password_from_salt_323(char *to, const ulong *salt)
buf+len*2
*/
-char *octet2hex(char *to, const char *str, uint len)
+char *octet2hex(char *to, const char *str, size_t len)
{
const char *str_end= str + len;
for (; str != str_end; ++str)
diff --git a/sql/procedure.cc b/sql/procedure.cc
index e4bf589958e..d5b93433f92 100644
--- a/sql/procedure.cc
+++ b/sql/procedure.cc
@@ -96,7 +96,7 @@ setup_procedure(THD *thd,ORDER *param,select_result *result,
DBUG_RETURN(proc);
}
}
- my_error(ER_UNKNOWN_PROCEDURE, MYF(0), (*param->item)->name);
+ my_error(ER_UNKNOWN_PROCEDURE, MYF(0), (*param->item)->name.str);
*error=1;
DBUG_RETURN(0);
}
diff --git a/sql/procedure.h b/sql/procedure.h
index a1c9b95f20b..1c24901791c 100644
--- a/sql/procedure.h
+++ b/sql/procedure.h
@@ -59,7 +59,11 @@ public:
DBUG_ASSERT(0); // impossible
return mark_unsupported_function("proc", arg, VCOL_IMPOSSIBLE);
}
- Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ }
+ Item* get_copy(THD *thd) { return 0; }
};
class Item_proc_real :public Item_proc
diff --git a/sql/protocol.cc b/sql/protocol.cc
index dbaa8ae6a1e..032e79c9289 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -86,7 +86,7 @@ bool Protocol_binary::net_store_data_cs(const uchar *from, size_t length,
{
uint dummy_errors;
/* Calculate maxumum possible result length */
- uint conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
+ size_t conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
if (conv_length > 250)
{
@@ -106,8 +106,8 @@ bool Protocol_binary::net_store_data_cs(const uchar *from, size_t length,
net_store_data((const uchar*) convert->ptr(), convert->length()));
}
- ulong packet_length= packet->length();
- ulong new_length= packet_length + conv_length + 1;
+ size_t packet_length= packet->length();
+ size_t new_length= packet_length + conv_length + 1;
if (new_length > packet->alloced_length() && packet->realloc(new_length))
return 1;
@@ -480,8 +480,9 @@ bool net_send_error_packet(THD *thd, uint sql_errno, const char *err,
- ulonglong for bigger numbers.
*/
-static uchar *net_store_length_fast(uchar *packet, uint length)
+static uchar *net_store_length_fast(uchar *packet, size_t length)
{
+ DBUG_ASSERT(length < UINT_MAX16);
if (length < 251)
{
*packet=(uchar) length;
@@ -661,7 +662,7 @@ void net_send_progress_packet(THD *thd)
{
uchar buff[200], *pos;
const char *proc_info= thd->proc_info ? thd->proc_info : "";
- uint length= strlen(proc_info);
+ size_t length= strlen(proc_info);
ulonglong progress;
DBUG_ENTER("net_send_progress_packet");
@@ -1015,7 +1016,7 @@ bool Protocol::store(const char *from, CHARSET_INFO *cs)
{
if (!from)
return store_null();
- uint length= strlen(from);
+ size_t length= strlen(from);
return store(from, length, cs);
}
@@ -1327,6 +1328,7 @@ bool Protocol_text::send_out_parameters(List<Item_param> *sp_params)
continue;
}
+ DBUG_ASSERT(sparam->get_item_param() == NULL);
sparam->set_value(thd, thd->spcont, reinterpret_cast<Item **>(&item_param));
}
diff --git a/sql/proxy_protocol.cc b/sql/proxy_protocol.cc
index 0309cf42ddf..dbdb1566bc7 100644
--- a/sql/proxy_protocol.cc
+++ b/sql/proxy_protocol.cc
@@ -13,7 +13,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-#include <my_global.h>
+#include <mariadb.h>
#include <mysql.h>
#include <mysql_com.h>
#include <mysqld_error.h>
@@ -210,14 +210,19 @@ int parse_proxy_protocol_header(NET *net, proxy_peer_info *peer_info)
{
#define PROXY_V2_HEADER_LEN 16
/* read off 16 bytes of the header.*/
- long len= vio_read(vio, hdr + pos, PROXY_V2_HEADER_LEN - pos);
+ ssize_t len= vio_read(vio, hdr + pos, PROXY_V2_HEADER_LEN - pos);
if (len < 0)
return -1;
// 2 last bytes are the length in network byte order of the part following header
ushort trail_len= ((ushort)hdr[PROXY_V2_HEADER_LEN-2] >> 8) + hdr[PROXY_V2_HEADER_LEN-1];
if (trail_len > sizeof(hdr) - PROXY_V2_HEADER_LEN)
return -1;
- len= vio_read(vio, hdr + PROXY_V2_HEADER_LEN, trail_len);
+ if (trail_len > 0)
+ {
+ len= vio_read(vio, hdr + PROXY_V2_HEADER_LEN, trail_len);
+ if (len < 0)
+ return -1;
+ }
pos= PROXY_V2_HEADER_LEN + trail_len;
if (parse_v2_header(hdr, pos, peer_info))
return -1;
@@ -230,11 +235,10 @@ int parse_proxy_protocol_header(NET *net, proxy_peer_info *peer_info)
They will be treated as IPv4.
*/
sockaddr_storage tmp;
- int dst_len;
memset(&tmp, 0, sizeof(tmp));
vio_get_normalized_ip((const struct sockaddr *)&peer_info->peer_addr,
- sizeof(sockaddr_storage), (struct sockaddr *)&tmp, &dst_len);
- memcpy(&peer_info->peer_addr, &tmp, (size_t)dst_len);
+ sizeof(sockaddr_storage), (struct sockaddr *)&tmp);
+ memcpy(&peer_info->peer_addr, &tmp, sizeof(tmp));
}
return 0;
}
@@ -464,10 +468,9 @@ bool is_proxy_protocol_allowed(const sockaddr *addr)
case AF_INET:
case AF_INET6:
{
- int len=
+ size_t len=
(addr->sa_family == AF_INET)?sizeof(sockaddr_in):sizeof (sockaddr_in6);
- int dst_len;
- vio_get_normalized_ip(addr, len,normalized_addr, &dst_len);
+ vio_get_normalized_ip(addr, len,normalized_addr);
}
break;
default:
diff --git a/sql/records.cc b/sql/records.cc
index 650a51f7f37..ac84ca84ab6 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -205,14 +205,14 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
if (addon_field)
{
info->rec_buf= (uchar*) filesort->addon_buf.str;
- info->ref_length= filesort->addon_buf.length;
+ info->ref_length= (uint)filesort->addon_buf.length;
info->unpack= filesort->unpack;
}
else
{
empty_record(table);
info->record= table->record[0];
- info->ref_length= table->file->ref_length;
+ info->ref_length= (uint)table->file->ref_length;
}
info->select=select;
info->print_error=print_error;
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 20290e8bad8..68c7158e9e5 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -115,7 +115,7 @@ void unregister_slave(THD* thd, bool only_mine, bool need_mutex)
1 Error. Error message sent to client
*/
-int register_slave(THD* thd, uchar* packet, uint packet_length)
+int register_slave(THD* thd, uchar* packet, size_t packet_length)
{
int res;
SLAVE_INFO *si;
diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h
index c3584fb17f2..967d81bcf0d 100644
--- a/sql/repl_failsafe.h
+++ b/sql/repl_failsafe.h
@@ -41,7 +41,7 @@ extern HASH slave_list;
bool show_slave_hosts(THD* thd);
void init_slave_list();
void end_slave_list();
-int register_slave(THD* thd, uchar* packet, uint packet_length);
+int register_slave(THD* thd, uchar* packet, size_t packet_length);
void unregister_slave(THD* thd, bool only_mine, bool need_mutex);
#endif /* HAVE_REPLICATION */
diff --git a/sql/replication.h b/sql/replication.h
index 4731c2246ef..d8672310110 100644
--- a/sql/replication.h
+++ b/sql/replication.h
@@ -18,16 +18,14 @@
/***************************************************************************
NOTE: plugin locking.
- This API was created specifically for the semisync plugin and its locking
- logic is also matches semisync plugin usage pattern. In particular, a plugin
- is locked on Binlog_transmit_observer::transmit_start and is unlocked after
- Binlog_transmit_observer::transmit_stop. All other master observable events
- happen between these two and don't lock the plugin at all. This works well
- for the semisync_master plugin.
+
+ The plugin is locked on Binlog_transmit_observer::transmit_start and is
+ unlocked after Binlog_transmit_observer::transmit_stop. All other
+ master observable events happen between these two and don't lock the
+ plugin at all.
Also a plugin is locked on Binlog_relay_IO_observer::thread_start
- and unlocked after Binlog_relay_IO_observer::thread_stop. This works well for
- the semisync_slave plugin.
+ and unlocked after Binlog_relay_IO_observer::thread_stop.
***************************************************************************/
#include <mysql.h>
diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc
index d09b7aee31c..3fda2761430 100644
--- a/sql/rpl_filter.cc
+++ b/sql/rpl_filter.cc
@@ -105,9 +105,9 @@ Rpl_filter::tables_ok(const char* db, TABLE_LIST* tables)
if (!tables->updating)
continue;
some_tables_updating= 1;
- end= strmov(hash_key, tables->db ? tables->db : db);
+ end= strmov(hash_key, tables->db.str ? tables->db.str : db);
*end++= '.';
- len= (uint) (strmov(end, tables->table_name) - hash_key);
+ len= (uint) (strmov(end, tables->table_name.str) - hash_key);
if (do_table_inited) // if there are any do's
{
if (my_hash_search(&do_table, (uchar*) hash_key, len))
diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc
index d58a2ea4d3e..d7e43a8fb39 100644
--- a/sql/rpl_gtid.cc
+++ b/sql/rpl_gtid.cc
@@ -26,10 +26,10 @@
#include "rpl_gtid.h"
#include "rpl_rli.h"
#include "slave.h"
+#include "log_event.h"
-
-const LEX_STRING rpl_gtid_slave_state_table_name=
- { C_STRING_WITH_LEN("gtid_slave_pos") };
+const LEX_CSTRING rpl_gtid_slave_state_table_name=
+ { STRING_WITH_LEN("gtid_slave_pos") };
void
@@ -401,10 +401,7 @@ rpl_slave_state::truncate_state_table(THD *thd)
int err= 0;
tmp_disable_binlog(thd);
- tlist.init_one_table(STRING_WITH_LEN("mysql"),
- rpl_gtid_slave_state_table_name.str,
- rpl_gtid_slave_state_table_name.length,
- NULL, TL_WRITE);
+ tlist.init_one_table(&MYSQL_SCHEMA_NAME, &rpl_gtid_slave_state_table_name, NULL, TL_WRITE);
if (!(err= open_and_lock_tables(thd, &tlist, FALSE, 0)))
{
err= tlist.table->file->ha_truncate();
@@ -430,17 +427,17 @@ rpl_slave_state::truncate_state_table(THD *thd)
static const TABLE_FIELD_TYPE mysql_rpl_slave_state_coltypes[4]= {
- { { C_STRING_WITH_LEN("domain_id") },
- { C_STRING_WITH_LEN("int(10) unsigned") },
+ { { STRING_WITH_LEN("domain_id") },
+ { STRING_WITH_LEN("int(10) unsigned") },
{NULL, 0} },
- { { C_STRING_WITH_LEN("sub_id") },
- { C_STRING_WITH_LEN("bigint(20) unsigned") },
+ { { STRING_WITH_LEN("sub_id") },
+ { STRING_WITH_LEN("bigint(20) unsigned") },
{NULL, 0} },
- { { C_STRING_WITH_LEN("server_id") },
- { C_STRING_WITH_LEN("int(10) unsigned") },
+ { { STRING_WITH_LEN("server_id") },
+ { STRING_WITH_LEN("int(10) unsigned") },
{NULL, 0} },
- { { C_STRING_WITH_LEN("seq_no") },
- { C_STRING_WITH_LEN("bigint(20) unsigned") },
+ { { STRING_WITH_LEN("seq_no") },
+ { STRING_WITH_LEN("bigint(20) unsigned") },
{NULL, 0} },
};
@@ -582,7 +579,7 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
bool table_opened= false;
TABLE *table;
list_element *delete_list= 0, *next, *cur, **next_ptr_ptr, **best_ptr_ptr;
- uint64_t best_sub_id;
+ uint64 best_sub_id;
element *elem;
ulonglong thd_saved_option= thd->variables.option_bits;
Query_tables_list lex_backup;
@@ -655,8 +652,7 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
*/
suspended_wfc= thd->suspend_subsequent_commits();
thd->lex->reset_n_backup_query_tables_list(&lex_backup);
- tlist.init_one_table(STRING_WITH_LEN("mysql"), gtid_pos_table_name.str,
- gtid_pos_table_name.length, NULL, TL_WRITE);
+ tlist.init_one_table(&MYSQL_SCHEMA_NAME, &gtid_pos_table_name, NULL, TL_WRITE);
if ((err= open_and_lock_tables(thd, &tlist, FALSE, 0)))
goto end;
table_opened= true;
@@ -1673,7 +1669,6 @@ rpl_binlog_state::write_to_iocache(IO_CACHE *dest)
mysql_mutex_lock(&LOCK_binlog_state);
for (i= 0; i < hash.records; ++i)
{
- size_t res;
element *e= (element *)my_hash_element(&hash, i);
if (!e->last_gtid)
{
@@ -1693,8 +1688,8 @@ rpl_binlog_state::write_to_iocache(IO_CACHE *dest)
gtid= e->last_gtid;
longlong10_to_str(gtid->seq_no, buf, 10);
- res= my_b_printf(dest, "%u-%u-%s\n", gtid->domain_id, gtid->server_id, buf);
- if (res == (size_t) -1)
+ if (my_b_printf(dest, "%u-%u-%s\n", gtid->domain_id, gtid->server_id,
+ buf))
{
res= 1;
goto end;
@@ -1940,6 +1935,155 @@ end:
return res;
}
+/**
+ Remove domains supplied by the first argument from binlog state.
+ Removal is done for any domain whose last gtids (from all its servers) match
+ ones in Gtid list event of the 2nd argument.
+
+ @param ids gtid domain id sequence, may contain dups
+ @param glev pointer to Gtid list event describing
+ the match condition
+ @param errbuf [out] pointer to possible error message array
+
+ @retval NULL as success when at least one domain is removed
+ @retval "" empty string to indicate ineffective call
+ when no domains removed
+ @retval NOT EMPTY string otherwise an error message
+*/
+const char*
+rpl_binlog_state::drop_domain(DYNAMIC_ARRAY *ids,
+ Gtid_list_log_event *glev,
+ char* errbuf)
+{
+ DYNAMIC_ARRAY domain_unique; // sequece (unsorted) of unique element*:s
+ rpl_binlog_state::element* domain_unique_buffer[16];
+ ulong k, l;
+ const char* errmsg= NULL;
+
+ DBUG_ENTER("rpl_binlog_state::drop_domain");
+
+ my_init_dynamic_array2(&domain_unique,
+ sizeof(element*), domain_unique_buffer,
+ sizeof(domain_unique_buffer) / sizeof(element*), 4, 0);
+
+ mysql_mutex_lock(&LOCK_binlog_state);
+
+ /*
+ Gtid list is supposed to come from a binlog's Gtid_list event and
+ therefore should be a subset of the current binlog state. That is
+ for every domain in the list the binlog state contains a gtid with
+ sequence number not less than that of the list.
+ Exceptions of this inclusion rule are:
+ A. the list may still refer to gtids from already deleted domains.
+ Files containing them must have been purged whereas the file
+ with the list is not yet.
+ B. out of order groups were injected
+ C. manually build list of binlog files violating the inclusion
+ constraint.
+ While A is a normal case (not necessarily distinguishable from C though),
+ B and C may require the user's attention so any (incl the A's suspected)
+ inconsistency is diagnosed and *warned*.
+ */
+ for (l= 0, errbuf[0]= 0; l < glev->count; l++, errbuf[0]= 0)
+ {
+ rpl_gtid* rb_state_gtid= find_nolock(glev->list[l].domain_id,
+ glev->list[l].server_id);
+ if (!rb_state_gtid)
+ sprintf(errbuf,
+ "missing gtids from the '%u-%u' domain-server pair which is "
+ "referred to in the gtid list describing an earlier state. Ignore "
+ "if the domain ('%u') was already explicitly deleted",
+ glev->list[l].domain_id, glev->list[l].server_id,
+ glev->list[l].domain_id);
+ else if (rb_state_gtid->seq_no < glev->list[l].seq_no)
+ sprintf(errbuf,
+ "having a gtid '%u-%u-%llu' which is less than "
+ "the '%u-%u-%llu' of the gtid list describing an earlier state. "
+ "The state may have been affected by manually injecting "
+ "a lower sequence number gtid or via replication",
+ rb_state_gtid->domain_id, rb_state_gtid->server_id,
+ rb_state_gtid->seq_no, glev->list[l].domain_id,
+ glev->list[l].server_id, glev->list[l].seq_no);
+ if (strlen(errbuf)) // use strlen() as cheap flag
+ push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_BINLOG_CANT_DELETE_GTID_DOMAIN,
+ "The current gtid binlog state is incompatible with "
+ "a former one %s.", errbuf);
+ }
+
+ /*
+ For each domain_id from ids
+ when no such domain in binlog state
+ warn && continue
+ For each domain.server's last gtid
+ when not locate the last gtid in glev.list
+ error out binlog state can't change
+ otherwise continue
+ */
+ for (ulong i= 0; i < ids->elements; i++)
+ {
+ rpl_binlog_state::element *elem= NULL;
+ ulong *ptr_domain_id;
+ bool not_match;
+
+ ptr_domain_id= (ulong*) dynamic_array_ptr(ids, i);
+ elem= (rpl_binlog_state::element *)
+ my_hash_search(&hash, (const uchar *) ptr_domain_id, 0);
+ if (!elem)
+ {
+ push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_BINLOG_CANT_DELETE_GTID_DOMAIN,
+ "The gtid domain being deleted ('%lu') is not in "
+ "the current binlog state", *ptr_domain_id);
+ continue;
+ }
+
+ for (not_match= true, k= 0; k < elem->hash.records; k++)
+ {
+ rpl_gtid *d_gtid= (rpl_gtid *)my_hash_element(&elem->hash, k);
+ for (ulong l= 0; l < glev->count && not_match; l++)
+ not_match= !(*d_gtid == glev->list[l]);
+ }
+
+ if (not_match)
+ {
+ sprintf(errbuf, "binlog files may contain gtids from the domain ('%lu') "
+ "being deleted. Make sure to first purge those files",
+ *ptr_domain_id);
+ errmsg= errbuf;
+ goto end;
+ }
+ // compose a sequence of unique pointers to domain object
+ for (k= 0; k < domain_unique.elements; k++)
+ {
+ if ((rpl_binlog_state::element*) dynamic_array_ptr(&domain_unique, k)
+ == elem)
+ break; // domain_id's elem has been already in
+ }
+ if (k == domain_unique.elements) // proven not to have duplicates
+ insert_dynamic(&domain_unique, (uchar*) &elem);
+ }
+
+ // Domain removal from binlog state
+ for (k= 0; k < domain_unique.elements; k++)
+ {
+ rpl_binlog_state::element *elem= *(rpl_binlog_state::element**)
+ dynamic_array_ptr(&domain_unique, k);
+ my_hash_free(&elem->hash);
+ my_hash_delete(&hash, (uchar*) elem);
+ }
+
+ DBUG_ASSERT(strlen(errbuf) == 0);
+
+ if (domain_unique.elements == 0)
+ errmsg= "";
+
+end:
+ mysql_mutex_unlock(&LOCK_binlog_state);
+ delete_dynamic(&domain_unique);
+
+ DBUG_RETURN(errmsg);
+}
slave_connection_state::slave_connection_state()
{
@@ -1991,10 +2135,7 @@ slave_connection_state::load(const char *slave_request, size_t len)
for (;;)
{
if (!(rec= (uchar *)my_malloc(sizeof(entry), MYF(MY_WME))))
- {
- my_error(ER_OUTOFMEMORY, MYF(0), (int) sizeof(*gtid));
return 1;
- }
gtid= &((entry *)rec)->gtid;
if (gtid_parser_helper(&p, end, gtid))
{
@@ -2610,10 +2751,7 @@ gtid_waiting::get_entry(uint32 domain_id)
return e;
if (!(e= (hash_element *)my_malloc(sizeof(*e), MYF(MY_WME))))
- {
- my_error(ER_OUTOFMEMORY, MYF(0), (int) sizeof(*e));
return NULL;
- }
if (init_queue(&e->queue, 8, offsetof(queue_element, wait_seq_no), 0,
cmp_queue_elem, NULL, 1+offsetof(queue_element, queue_idx), 1))
diff --git a/sql/rpl_gtid.h b/sql/rpl_gtid.h
index c473ff40ee9..604289acd6b 100644
--- a/sql/rpl_gtid.h
+++ b/sql/rpl_gtid.h
@@ -23,7 +23,7 @@
/* Definitions for MariaDB global transaction ID (GTID). */
-extern const LEX_STRING rpl_gtid_slave_state_table_name;
+extern const LEX_CSTRING rpl_gtid_slave_state_table_name;
class String;
@@ -34,6 +34,13 @@ struct rpl_gtid
uint64 seq_no;
};
+inline bool operator==(const rpl_gtid& lhs, const rpl_gtid& rhs)
+{
+ return
+ lhs.domain_id == rhs.domain_id &&
+ lhs.server_id == rhs.server_id &&
+ lhs.seq_no == rhs.seq_no;
+};
enum enum_gtid_skip_type {
GTID_SKIP_NOT, GTID_SKIP_STANDALONE, GTID_SKIP_TRANSACTION
@@ -93,6 +100,7 @@ struct gtid_waiting {
class Relay_log_info;
struct rpl_group_info;
+class Gtid_list_log_event;
/*
Replication slave state.
@@ -315,6 +323,7 @@ struct rpl_binlog_state
rpl_gtid *find_nolock(uint32 domain_id, uint32 server_id);
rpl_gtid *find(uint32 domain_id, uint32 server_id);
rpl_gtid *find_most_recent(uint32 domain_id);
+ const char* drop_domain(DYNAMIC_ARRAY *ids, Gtid_list_log_event *glev, char*);
};
diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc
deleted file mode 100644
index e3ff2a17a6a..00000000000
--- a/sql/rpl_handler.cc
+++ /dev/null
@@ -1,553 +0,0 @@
-/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- 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-1301 USA */
-
-#include "mariadb.h"
-#include "sql_priv.h"
-#include "unireg.h"
-
-#include "rpl_mi.h"
-#include "sql_repl.h"
-#include "log_event.h"
-#include "rpl_filter.h"
-#include <my_dir.h>
-#include "rpl_handler.h"
-
-Trans_delegate *transaction_delegate;
-Binlog_storage_delegate *binlog_storage_delegate;
-#ifdef HAVE_REPLICATION
-Binlog_transmit_delegate *binlog_transmit_delegate;
-Binlog_relay_IO_delegate *binlog_relay_io_delegate;
-#endif /* HAVE_REPLICATION */
-
-/*
- structure to save transaction log filename and position
-*/
-typedef struct Trans_binlog_info {
- my_off_t log_pos;
- char log_file[FN_REFLEN];
-} Trans_binlog_info;
-
-int get_user_var_int(const char *name,
- long long int *value, int *null_value)
-{
- bool null_val;
- user_var_entry *entry=
- (user_var_entry*) my_hash_search(&current_thd->user_vars,
- (uchar*) name, strlen(name));
- if (!entry)
- return 1;
- *value= entry->val_int(&null_val);
- if (null_value)
- *null_value= null_val;
- return 0;
-}
-
-int get_user_var_real(const char *name,
- double *value, int *null_value)
-{
- bool null_val;
- user_var_entry *entry=
- (user_var_entry*) my_hash_search(&current_thd->user_vars,
- (uchar*) name, strlen(name));
- if (!entry)
- return 1;
- *value= entry->val_real(&null_val);
- if (null_value)
- *null_value= null_val;
- return 0;
-}
-
-int get_user_var_str(const char *name, char *value,
- size_t len, unsigned int precision, int *null_value)
-{
- String str;
- bool null_val;
- user_var_entry *entry=
- (user_var_entry*) my_hash_search(&current_thd->user_vars,
- (uchar*) name, strlen(name));
- if (!entry)
- return 1;
- entry->val_str(&null_val, &str, precision);
- strncpy(value, str.c_ptr(), len);
- if (null_value)
- *null_value= null_val;
- return 0;
-}
-
-int delegates_init()
-{
- static my_aligned_storage<sizeof(Trans_delegate), MY_ALIGNOF(long)> trans_mem;
- static my_aligned_storage<sizeof(Binlog_storage_delegate),
- MY_ALIGNOF(long)> storage_mem;
-#ifdef HAVE_REPLICATION
- static my_aligned_storage<sizeof(Binlog_transmit_delegate),
- MY_ALIGNOF(long)> transmit_mem;
- static my_aligned_storage<sizeof(Binlog_relay_IO_delegate),
- MY_ALIGNOF(long)> relay_io_mem;
-#endif
-
- void *place_trans_mem= trans_mem.data;
- void *place_storage_mem= storage_mem.data;
-
- transaction_delegate= new (place_trans_mem) Trans_delegate;
-
- if (!transaction_delegate->is_inited())
- {
- sql_print_error("Initialization of transaction delegates failed. "
- "Please report a bug.");
- return 1;
- }
-
- binlog_storage_delegate= new (place_storage_mem) Binlog_storage_delegate;
-
- if (!binlog_storage_delegate->is_inited())
- {
- sql_print_error("Initialization binlog storage delegates failed. "
- "Please report a bug.");
- return 1;
- }
-
-#ifdef HAVE_REPLICATION
- void *place_transmit_mem= transmit_mem.data;
- void *place_relay_io_mem= relay_io_mem.data;
-
- binlog_transmit_delegate= new (place_transmit_mem) Binlog_transmit_delegate;
-
- if (!binlog_transmit_delegate->is_inited())
- {
- sql_print_error("Initialization of binlog transmit delegates failed. "
- "Please report a bug.");
- return 1;
- }
-
- binlog_relay_io_delegate= new (place_relay_io_mem) Binlog_relay_IO_delegate;
-
- if (!binlog_relay_io_delegate->is_inited())
- {
- sql_print_error("Initialization binlog relay IO delegates failed. "
- "Please report a bug.");
- return 1;
- }
-#endif
-
- return 0;
-}
-
-void delegates_destroy()
-{
- if (transaction_delegate)
- transaction_delegate->~Trans_delegate();
- if (binlog_storage_delegate)
- binlog_storage_delegate->~Binlog_storage_delegate();
-#ifdef HAVE_REPLICATION
- if (binlog_transmit_delegate)
- binlog_transmit_delegate->~Binlog_transmit_delegate();
- if (binlog_relay_io_delegate)
- binlog_relay_io_delegate->~Binlog_relay_IO_delegate();
-#endif /* HAVE_REPLICATION */
-}
-
-/*
- This macro is used by almost all the Delegate methods to iterate
- over all the observers running given callback function of the
- delegate.
- */
-#define FOREACH_OBSERVER(r, f, do_lock, args) \
- param.server_id= thd->variables.server_id; \
- read_lock(); \
- Observer_info_iterator iter= observer_info_iter(); \
- Observer_info *info= iter++; \
- for (; info; info= iter++) \
- { \
- if (do_lock) plugin_lock(thd, plugin_int_to_ref(info->plugin_int)); \
- if (((Observer *)info->observer)->f \
- && ((Observer *)info->observer)->f args) \
- { \
- r= 1; \
- sql_print_error("Run function '" #f "' in plugin '%s' failed", \
- info->plugin_int->name.str); \
- break; \
- } \
- } \
- unlock();
-
-
-int Trans_delegate::after_commit(THD *thd, bool all)
-{
- Trans_param param;
- Trans_binlog_info *log_info;
- bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
- int ret= 0;
-
- param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
-
- log_info= thd->semisync_info;
-
- param.log_file= log_info && log_info->log_file[0] ? log_info->log_file : 0;
- param.log_pos= log_info ? log_info->log_pos : 0;
-
- FOREACH_OBSERVER(ret, after_commit, false, (&param));
-
- /*
- This is the end of a real transaction or autocommit statement, we
- can mark the memory unused.
- */
- if (is_real_trans && log_info)
- {
- log_info->log_file[0]= 0;
- log_info->log_pos= 0;
- }
- return ret;
-}
-
-int Trans_delegate::after_rollback(THD *thd, bool all)
-{
- Trans_param param;
- Trans_binlog_info *log_info;
- bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
- int ret= 0;
-
- param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
-
- log_info= thd->semisync_info;
-
- param.log_file= log_info && log_info->log_file[0] ? log_info->log_file : 0;
- param.log_pos= log_info ? log_info->log_pos : 0;
-
- FOREACH_OBSERVER(ret, after_rollback, false, (&param));
-
- /*
- This is the end of a real transaction or autocommit statement, we
- can mark the memory unused.
- */
- if (is_real_trans && log_info)
- {
- log_info->log_file[0]= 0;
- log_info->log_pos= 0;
- }
- return ret;
-}
-
-int Binlog_storage_delegate::after_flush(THD *thd,
- const char *log_file,
- my_off_t log_pos,
- bool synced,
- bool first_in_group,
- bool last_in_group)
-{
- Binlog_storage_param param;
- Trans_binlog_info *log_info;
- uint32 flags=0;
- int ret= 0;
-
- if (synced)
- flags |= BINLOG_STORAGE_IS_SYNCED;
- if (first_in_group)
- flags|= BINLOG_GROUP_COMMIT_LEADER;
- if (last_in_group)
- flags|= BINLOG_GROUP_COMMIT_TRAILER;
-
- if (!(log_info= thd->semisync_info))
- {
- if(!(log_info=
- (Trans_binlog_info*) my_malloc(sizeof(Trans_binlog_info), MYF(0))))
- return 1;
- thd->semisync_info= log_info;
- }
-
- strmake_buf(log_info->log_file, log_file+dirname_length(log_file));
- log_info->log_pos = log_pos;
-
- FOREACH_OBSERVER(ret, after_flush, false,
- (&param, log_info->log_file, log_info->log_pos, flags));
- return ret;
-}
-
-int Binlog_storage_delegate::after_sync(THD *thd,
- const char *log_file,
- my_off_t log_pos,
- bool first_in_group,
- bool last_in_group)
-{
- Binlog_storage_param param;
- uint32 flags=0;
-
- if (first_in_group)
- flags|= BINLOG_GROUP_COMMIT_LEADER;
- if (last_in_group)
- flags|= BINLOG_GROUP_COMMIT_TRAILER;
-
- int ret= 0;
- FOREACH_OBSERVER(ret, after_sync, false,
- (&param, log_file+dirname_length(log_file), log_pos, flags));
-
- return ret;
-}
-
-#ifdef HAVE_REPLICATION
-int Binlog_transmit_delegate::transmit_start(THD *thd, ushort flags,
- const char *log_file,
- my_off_t log_pos)
-{
- Binlog_transmit_param param;
- param.flags= flags;
-
- int ret= 0;
- FOREACH_OBSERVER(ret, transmit_start, true, (&param, log_file, log_pos));
- return ret;
-}
-
-int Binlog_transmit_delegate::transmit_stop(THD *thd, ushort flags)
-{
- Binlog_transmit_param param;
- param.flags= flags;
-
- int ret= 0;
- FOREACH_OBSERVER(ret, transmit_stop, false, (&param));
- return ret;
-}
-
-int Binlog_transmit_delegate::reserve_header(THD *thd, ushort flags,
- String *packet)
-{
- /* NOTE2ME: Maximum extra header size for each observer, I hope 32
- bytes should be enough for each Observer to reserve their extra
- header. If later found this is not enough, we can increase this
- /HEZX
- */
-#define RESERVE_HEADER_SIZE 32
- unsigned char header[RESERVE_HEADER_SIZE];
- ulong hlen;
- Binlog_transmit_param param;
- param.flags= flags;
- param.server_id= thd->variables.server_id;
-
- int ret= 0;
- read_lock();
- Observer_info_iterator iter= observer_info_iter();
- Observer_info *info= iter++;
- for (; info; info= iter++)
- {
- hlen= 0;
- if (((Observer *)info->observer)->reserve_header
- && ((Observer *)info->observer)->reserve_header(&param,
- header,
- RESERVE_HEADER_SIZE,
- &hlen))
- {
- ret= 1;
- break;
- }
- if (hlen == 0)
- continue;
- if (hlen > RESERVE_HEADER_SIZE || packet->append((char *)header, hlen))
- {
- ret= 1;
- break;
- }
- }
- unlock();
- return ret;
-}
-
-int Binlog_transmit_delegate::before_send_event(THD *thd, ushort flags,
- String *packet,
- const char *log_file,
- my_off_t log_pos)
-{
- Binlog_transmit_param param;
- param.flags= flags;
-
- int ret= 0;
- FOREACH_OBSERVER(ret, before_send_event, false,
- (&param, (uchar *)packet->c_ptr(),
- packet->length(),
- log_file+dirname_length(log_file), log_pos));
- return ret;
-}
-
-int Binlog_transmit_delegate::after_send_event(THD *thd, ushort flags,
- String *packet)
-{
- Binlog_transmit_param param;
- param.flags= flags;
-
- int ret= 0;
- FOREACH_OBSERVER(ret, after_send_event, false,
- (&param, packet->c_ptr(), packet->length()));
- return ret;
-}
-
-int Binlog_transmit_delegate::after_reset_master(THD *thd, ushort flags)
-
-{
- Binlog_transmit_param param;
- param.flags= flags;
-
- int ret= 0;
- FOREACH_OBSERVER(ret, after_reset_master, false, (&param));
- return ret;
-}
-
-void Binlog_relay_IO_delegate::init_param(Binlog_relay_IO_param *param,
- Master_info *mi)
-{
- param->mysql= mi->mysql;
- param->user= mi->user;
- param->host= mi->host;
- param->port= mi->port;
- param->master_log_name= mi->master_log_name;
- param->master_log_pos= mi->master_log_pos;
-}
-
-int Binlog_relay_IO_delegate::thread_start(THD *thd, Master_info *mi)
-{
- Binlog_relay_IO_param param;
- init_param(&param, mi);
-
- int ret= 0;
- FOREACH_OBSERVER(ret, thread_start, true, (&param));
- return ret;
-}
-
-
-int Binlog_relay_IO_delegate::thread_stop(THD *thd, Master_info *mi)
-{
-
- Binlog_relay_IO_param param;
- init_param(&param, mi);
-
- int ret= 0;
- FOREACH_OBSERVER(ret, thread_stop, false, (&param));
- return ret;
-}
-
-int Binlog_relay_IO_delegate::before_request_transmit(THD *thd,
- Master_info *mi,
- ushort flags)
-{
- Binlog_relay_IO_param param;
- init_param(&param, mi);
-
- int ret= 0;
- FOREACH_OBSERVER(ret, before_request_transmit, false, (&param, (uint32)flags));
- return ret;
-}
-
-int Binlog_relay_IO_delegate::after_read_event(THD *thd, Master_info *mi,
- const char *packet, ulong len,
- const char **event_buf,
- ulong *event_len)
-{
- Binlog_relay_IO_param param;
- init_param(&param, mi);
-
- int ret= 0;
- FOREACH_OBSERVER(ret, after_read_event, false,
- (&param, packet, len, event_buf, event_len));
- return ret;
-}
-
-int Binlog_relay_IO_delegate::after_queue_event(THD *thd, Master_info *mi,
- const char *event_buf,
- ulong event_len,
- bool synced)
-{
- Binlog_relay_IO_param param;
- init_param(&param, mi);
-
- uint32 flags=0;
- if (synced)
- flags |= BINLOG_STORAGE_IS_SYNCED;
-
- int ret= 0;
- FOREACH_OBSERVER(ret, after_queue_event, false,
- (&param, event_buf, event_len, flags));
- return ret;
-}
-
-int Binlog_relay_IO_delegate::after_reset_slave(THD *thd, Master_info *mi)
-
-{
- Binlog_relay_IO_param param;
- init_param(&param, mi);
-
- int ret= 0;
- FOREACH_OBSERVER(ret, after_reset_slave, false, (&param));
- return ret;
-}
-#endif /* HAVE_REPLICATION */
-
-int register_trans_observer(Trans_observer *observer, void *p)
-{
- return transaction_delegate->add_observer(observer, (st_plugin_int *)p);
-}
-
-int unregister_trans_observer(Trans_observer *observer, void *p)
-{
- return transaction_delegate->remove_observer(observer, (st_plugin_int *)p);
-}
-
-int register_binlog_storage_observer(Binlog_storage_observer *observer, void *p)
-{
- return binlog_storage_delegate->add_observer(observer, (st_plugin_int *)p);
-}
-
-int unregister_binlog_storage_observer(Binlog_storage_observer *observer, void *p)
-{
- return binlog_storage_delegate->remove_observer(observer, (st_plugin_int *)p);
-}
-
-#ifdef HAVE_REPLICATION
-int register_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p)
-{
- return binlog_transmit_delegate->add_observer(observer, (st_plugin_int *)p);
-}
-
-int unregister_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p)
-{
- return binlog_transmit_delegate->remove_observer(observer, (st_plugin_int *)p);
-}
-
-int register_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p)
-{
- return binlog_relay_io_delegate->add_observer(observer, (st_plugin_int *)p);
-}
-
-int unregister_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p)
-{
- return binlog_relay_io_delegate->remove_observer(observer, (st_plugin_int *)p);
-}
-#else
-int register_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p)
-{
- return 0;
-}
-
-int unregister_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p)
-{
- return 0;
-}
-
-int register_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p)
-{
- return 0;
-}
-
-int unregister_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p)
-{
- return 0;
-}
-#endif /* HAVE_REPLICATION */
diff --git a/sql/rpl_handler.h b/sql/rpl_handler.h
deleted file mode 100644
index afcfd9d55b1..00000000000
--- a/sql/rpl_handler.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- 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-1301 USA */
-
-#ifndef RPL_HANDLER_H
-#define RPL_HANDLER_H
-
-#include "sql_priv.h"
-#include "rpl_mi.h"
-#include "rpl_rli.h"
-#include "sql_plugin.h"
-#include "replication.h"
-
-class Observer_info {
-public:
- void *observer;
- st_plugin_int *plugin_int;
-
- Observer_info(void *ob, st_plugin_int *p)
- :observer(ob), plugin_int(p)
- { }
-};
-
-class Delegate {
-public:
- typedef List<Observer_info> Observer_info_list;
- typedef List_iterator<Observer_info> Observer_info_iterator;
-
- int add_observer(void *observer, st_plugin_int *plugin)
- {
- int ret= FALSE;
- if (!inited)
- return TRUE;
- write_lock();
- Observer_info_iterator iter(observer_info_list);
- Observer_info *info= iter++;
- while (info && info->observer != observer)
- info= iter++;
- if (!info)
- {
- info= new Observer_info(observer, plugin);
- if (!info || observer_info_list.push_back(info, &memroot))
- ret= TRUE;
- }
- else
- ret= TRUE;
- unlock();
- return ret;
- }
-
- int remove_observer(void *observer, st_plugin_int *plugin)
- {
- int ret= FALSE;
- if (!inited)
- return TRUE;
- write_lock();
- Observer_info_iterator iter(observer_info_list);
- Observer_info *info= iter++;
- while (info && info->observer != observer)
- info= iter++;
- if (info)
- {
- iter.remove();
- delete info;
- }
- else
- ret= TRUE;
- unlock();
- return ret;
- }
-
- inline Observer_info_iterator observer_info_iter()
- {
- return Observer_info_iterator(observer_info_list);
- }
-
- inline bool is_empty()
- {
- return observer_info_list.is_empty();
- }
-
- inline int read_lock()
- {
- if (!inited)
- return TRUE;
- return rw_rdlock(&lock);
- }
-
- inline int write_lock()
- {
- if (!inited)
- return TRUE;
- return rw_wrlock(&lock);
- }
-
- inline int unlock()
- {
- if (!inited)
- return TRUE;
- return rw_unlock(&lock);
- }
-
- inline bool is_inited()
- {
- return inited;
- }
-
- Delegate()
- {
- inited= FALSE;
- if (my_rwlock_init(&lock, NULL))
- return;
- init_sql_alloc(&memroot, 1024, 0, MYF(0));
- inited= TRUE;
- }
- ~Delegate()
- {
- inited= FALSE;
- rwlock_destroy(&lock);
- free_root(&memroot, MYF(0));
- }
-
-private:
- Observer_info_list observer_info_list;
- rw_lock_t lock;
- MEM_ROOT memroot;
- bool inited;
-};
-
-class Trans_delegate
- :public Delegate {
-public:
- typedef Trans_observer Observer;
- int before_commit(THD *thd, bool all);
- int before_rollback(THD *thd, bool all);
- int after_commit(THD *thd, bool all);
- int after_rollback(THD *thd, bool all);
-};
-
-class Binlog_storage_delegate
- :public Delegate {
-public:
- typedef Binlog_storage_observer Observer;
- int after_flush(THD *thd, const char *log_file,
- my_off_t log_pos, bool synced,
- bool first_in_group, bool last_in_group);
- int after_sync(THD *thd, const char *log_file, my_off_t log_pos,
- bool first_in_group, bool last_in_group);
-};
-
-#ifdef HAVE_REPLICATION
-class Binlog_transmit_delegate
- :public Delegate {
-public:
- typedef Binlog_transmit_observer Observer;
- int transmit_start(THD *thd, ushort flags,
- const char *log_file, my_off_t log_pos);
- int transmit_stop(THD *thd, ushort flags);
- int reserve_header(THD *thd, ushort flags, String *packet);
- int before_send_event(THD *thd, ushort flags,
- String *packet, const
- char *log_file, my_off_t log_pos );
- int after_send_event(THD *thd, ushort flags,
- String *packet);
- int after_reset_master(THD *thd, ushort flags);
-};
-
-class Binlog_relay_IO_delegate
- :public Delegate {
-public:
- typedef Binlog_relay_IO_observer Observer;
- int thread_start(THD *thd, Master_info *mi);
- int thread_stop(THD *thd, Master_info *mi);
- int before_request_transmit(THD *thd, Master_info *mi, ushort flags);
- int after_read_event(THD *thd, Master_info *mi,
- const char *packet, ulong len,
- const char **event_buf, ulong *event_len);
- int after_queue_event(THD *thd, Master_info *mi,
- const char *event_buf, ulong event_len,
- bool synced);
- int after_reset_slave(THD *thd, Master_info *mi);
-private:
- void init_param(Binlog_relay_IO_param *param, Master_info *mi);
-};
-#endif /* HAVE_REPLICATION */
-
-int delegates_init();
-void delegates_destroy();
-
-extern Trans_delegate *transaction_delegate;
-extern Binlog_storage_delegate *binlog_storage_delegate;
-#ifdef HAVE_REPLICATION
-extern Binlog_transmit_delegate *binlog_transmit_delegate;
-extern Binlog_relay_IO_delegate *binlog_relay_io_delegate;
-#endif /* HAVE_REPLICATION */
-
-/*
- if there is no observers in the delegate, we can return 0
- immediately.
-*/
-#define RUN_HOOK(group, hook, args) \
- (group ##_delegate->is_empty() ? \
- 0 : group ##_delegate->hook args)
-
-#endif /* RPL_HANDLER_H */
diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc
index d7081f766ec..b855dec35f9 100644
--- a/sql/rpl_injector.cc
+++ b/sql/rpl_injector.cc
@@ -185,7 +185,8 @@ int injector::record_incident(THD *thd, Incident incident)
return mysql_bin_log.rotate_and_purge(true);
}
-int injector::record_incident(THD *thd, Incident incident, LEX_STRING const message)
+int injector::record_incident(THD *thd, Incident incident,
+ const LEX_CSTRING *message)
{
Incident_log_event ev(thd, incident, message);
if (int error= mysql_bin_log.write(&ev))
diff --git a/sql/rpl_injector.h b/sql/rpl_injector.h
index dc7bfb6503a..bfb53a38d90 100644
--- a/sql/rpl_injector.h
+++ b/sql/rpl_injector.h
@@ -302,7 +302,7 @@ public:
void new_trans(THD *, transaction *);
int record_incident(THD*, Incident incident);
- int record_incident(THD*, Incident incident, LEX_STRING const message);
+ int record_incident(THD*, Incident incident, const LEX_CSTRING *message);
private:
explicit injector();
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index 9661e0b0353..55a66719e56 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -1360,7 +1360,7 @@ Master_info_index::get_master_info(const LEX_CSTRING *connection_name,
{
Master_info *mi;
char buff[MAX_CONNECTION_NAME+1], *res;
- uint buff_length;
+ size_t buff_length;
DBUG_ENTER("get_master_info");
DBUG_PRINT("enter",
("connection_name: '%.*s'", (int) connection_name->length,
@@ -1914,7 +1914,7 @@ char *Domain_id_filter::as_string(enum_list_type type)
return NULL;
// Store the total number of elements followed by the individual elements.
- ulong cur_len= sprintf(buf, "%u", ids->elements);
+ size_t cur_len= sprintf(buf, "%u", ids->elements);
sz-= cur_len;
for (uint i= 0; i < ids->elements; i++)
diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h
index 610bc77b683..260c35e8c04 100644
--- a/sql/rpl_mi.h
+++ b/sql/rpl_mi.h
@@ -133,6 +133,19 @@ public:
extern TYPELIB slave_parallel_mode_typelib;
+typedef struct st_rows_event_tracker
+{
+ char binlog_file_name[FN_REFLEN];
+ my_off_t first_seen;
+ my_off_t last_seen;
+ bool stmt_end_seen;
+ void update(const char* file_name, my_off_t pos,
+ const char* buf,
+ const Format_description_log_event *fdle);
+ void reset();
+ bool check_and_report(const char* file_name, my_off_t pos);
+} Rows_event_tracker;
+
/*****************************************************************************
Replication IO Thread
@@ -301,6 +314,14 @@ class Master_info : public Slave_reporting_capability
uint64 gtid_reconnect_event_skip_count;
/* gtid_event_seen is false until we receive first GTID event from master. */
bool gtid_event_seen;
+ /**
+ The struct holds some history of Rows- log-event reading/queuing
+ by the receiver thread. Its fields are updated per each such event
+ at time of queue_event(), and they are checked to detect
+ the Rows- event group integrity violation at time of first non-Rows-
+ event gets handled.
+ */
+ Rows_event_tracker rows_event_tracker;
bool in_start_all_slaves, in_stop_all_slaves;
bool in_flush_all_relay_logs;
uint users; /* Active user for object */
@@ -311,6 +332,11 @@ class Master_info : public Slave_reporting_capability
/* The parallel replication mode. */
enum_slave_parallel_mode parallel_mode;
+ /*
+ semi_ack is used to identify if the current binlog event needs an
+ ACK from slave, or if delay_master is enabled.
+ */
+ int semi_ack;
};
int init_master_info(Master_info* mi, const char* master_info_fname,
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index 4a6e813d73b..b2b13c5467b 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -255,10 +255,8 @@ signal_error_to_sql_driver_thread(THD *thd, rpl_group_info *rgi, int err)
rgi->rli->abort_slave= true;
rgi->rli->stop_for_until= false;
mysql_mutex_lock(rgi->rli->relay_log.get_log_lock());
+ rgi->rli->relay_log.signal_relay_log_update();
mysql_mutex_unlock(rgi->rli->relay_log.get_log_lock());
- rgi->rli->relay_log.lock_binlog_end_pos();
- rgi->rli->relay_log.signal_update();
- rgi->rli->relay_log.unlock_binlog_end_pos();
}
@@ -823,7 +821,7 @@ do_retry:
for (;;)
{
old_offset= cur_offset;
- ev= Log_event::read_log_event(&rlog, 0, description_event,
+ ev= Log_event::read_log_event(&rlog, description_event,
opt_slave_sql_verify_checksum);
cur_offset= my_b_tell(&rlog);
@@ -1395,7 +1393,7 @@ handle_rpl_parallel_thread(void *arg)
thd->clear_error();
thd->catalog= 0;
thd->reset_query();
- thd->reset_db(NULL, 0);
+ thd->reset_db(&null_clex_str);
thd_proc_info(thd, "Slave worker thread exiting");
thd->temporary_tables= 0;
@@ -1624,10 +1622,19 @@ int rpl_parallel_resize_pool_if_no_slaves(void)
}
+/**
+ Resize pool if not active or busy (in which case we may be in
+ resize to 0
+*/
+
int
rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool)
{
- if (!pool->count)
+ bool resize;
+ mysql_mutex_lock(&pool->LOCK_rpl_thread_pool);
+ resize= !pool->count || pool->busy;
+ mysql_mutex_unlock(&pool->LOCK_rpl_thread_pool);
+ if (resize)
return rpl_parallel_change_thread_count(pool, opt_slave_parallel_threads,
0);
return 0;
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index efb256fbe11..04109ddadb4 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -70,10 +70,12 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery)
relay_log_state.init();
#ifdef HAVE_PSI_INTERFACE
relay_log.set_psi_keys(key_RELAYLOG_LOCK_index,
- key_RELAYLOG_update_cond,
+ key_RELAYLOG_COND_relay_log_updated,
+ key_RELAYLOG_COND_bin_log_updated,
key_file_relaylog,
key_file_relaylog_index,
- key_RELAYLOG_COND_queue_busy);
+ key_RELAYLOG_COND_queue_busy,
+ key_LOCK_relaylog_end_pos);
#endif
group_relay_log_name[0]= event_relay_log_name[0]=
@@ -538,7 +540,7 @@ read_relay_log_description_event(IO_CACHE *cur_log, ulonglong start_pos,
if (my_b_tell(cur_log) >= start_pos)
break;
- if (!(ev= Log_event::read_log_event(cur_log, 0, fdev,
+ if (!(ev= Log_event::read_log_event(cur_log, fdev,
opt_slave_sql_verify_checksum)))
{
DBUG_PRINT("info",("could not read event, cur_log->error=%d",
@@ -1525,8 +1527,7 @@ scan_one_gtid_slave_pos_table(THD *thd, HASH *hash, DYNAMIC_ARRAY *array,
int err= 0;
thd->reset_for_next_command();
- tlist.init_one_table(STRING_WITH_LEN("mysql"), tablename->str,
- tablename->length, NULL, TL_READ);
+ tlist.init_one_table(&MYSQL_SCHEMA_NAME, tablename, NULL, TL_READ);
if ((err= open_and_lock_tables(thd, &tlist, FALSE, 0)))
goto end;
table_opened= true;
@@ -1640,15 +1641,14 @@ static int
scan_all_gtid_slave_pos_table(THD *thd, int (*cb)(THD *, LEX_CSTRING *, void *),
void *cb_data)
{
- static LEX_CSTRING mysql_db_name= {C_STRING_WITH_LEN("mysql")};
char path[FN_REFLEN];
MY_DIR *dirp;
thd->reset_for_next_command();
- if (lock_schema_name(thd, mysql_db_name.str))
+ if (lock_schema_name(thd, MYSQL_SCHEMA_NAME.str))
return 1;
- build_table_filename(path, sizeof(path) - 1, mysql_db_name.str, "", "", 0);
+ build_table_filename(path, sizeof(path) - 1, MYSQL_SCHEMA_NAME.str, "", "", 0);
if (!(dirp= my_dir(path, MYF(MY_DONT_SORT))))
{
my_error(ER_FILE_NOT_FOUND, MYF(0), path, my_errno);
@@ -1663,7 +1663,7 @@ scan_all_gtid_slave_pos_table(THD *thd, int (*cb)(THD *, LEX_CSTRING *, void *),
Discovered_table_list tl(thd, &files);
int err;
- err= ha_discover_table_names(thd, &mysql_db_name, dirp, &tl, false);
+ err= ha_discover_table_names(thd, &MYSQL_SCHEMA_NAME, dirp, &tl, false);
my_dirend(dirp);
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
@@ -1717,12 +1717,12 @@ process_gtid_pos_table(THD *thd, LEX_CSTRING *table_name, void *hton,
if (!is_default)
{
/* Ignore the redundant table. */
- sql_print_warning(warning_msg, table_name->str, entry->table_name);
+ sql_print_warning(warning_msg, table_name->str, entry->table_name.str);
return 0;
}
else
{
- sql_print_warning(warning_msg, entry->table_name, table_name->str);
+ sql_print_warning(warning_msg, entry->table_name.str, table_name->str);
/* Delete the redundant table, and proceed to add this one instead. */
*next_ptr= entry->next;
my_free(entry);
@@ -1926,8 +1926,7 @@ find_gtid_pos_tables_cb(THD *thd, LEX_CSTRING *table_name, void *arg)
int err;
thd->reset_for_next_command();
- tlist.init_one_table(STRING_WITH_LEN("mysql"), table_name->str,
- table_name->length, NULL, TL_READ);
+ tlist.init_one_table(&MYSQL_SCHEMA_NAME, table_name, NULL, TL_READ);
if ((err= open_and_lock_tables(thd, &tlist, FALSE, 0)))
goto end;
table= tlist.table;
diff --git a/sql/rpl_tblmap.cc b/sql/rpl_tblmap.cc
index 80d093722f7..7284e4be15c 100644
--- a/sql/rpl_tblmap.cc
+++ b/sql/rpl_tblmap.cc
@@ -46,7 +46,8 @@ table_mapping::table_mapping()
offsetof(entry,table_id),sizeof(ulong),
0,0,0);
/* We don't preallocate any block, this is consistent with m_free=0 above */
- init_alloc_root(&m_mem_root, TABLE_ID_HASH_SIZE*sizeof(entry), 0, MYF(0));
+ init_alloc_root(&m_mem_root, "table_mapping",
+ TABLE_ID_HASH_SIZE*sizeof(entry), 0, MYF(0));
DBUG_VOID_RETURN;
}
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index 774f582b4b9..58711078db6 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -141,10 +141,10 @@ max_display_length_for_field(enum_field_types sql_type, unsigned int metadata)
*/
case MYSQL_TYPE_TINY_BLOB:
- return my_set_bits(1 * 8);
+ return (uint32)my_set_bits(1 * 8);
case MYSQL_TYPE_MEDIUM_BLOB:
- return my_set_bits(3 * 8);
+ return (uint32)my_set_bits(3 * 8);
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_BLOB_COMPRESSED:
@@ -153,11 +153,11 @@ max_display_length_for_field(enum_field_types sql_type, unsigned int metadata)
blobs are of type MYSQL_TYPE_BLOB. In that case, we have to look
at the length instead to decide what the max display size is.
*/
- return my_set_bits(metadata * 8);
+ return (uint32)my_set_bits(metadata * 8);
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_GEOMETRY:
- return my_set_bits(4 * 8);
+ return (uint32)my_set_bits(4 * 8);
default:
return ~(uint32) 0;
@@ -414,7 +414,7 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_
case MYSQL_TYPE_VARCHAR_COMPRESSED:
{
CHARSET_INFO *cs= str->charset();
- uint32 length=
+ size_t length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
"varchar(%u)%s", metadata,
type == MYSQL_TYPE_VARCHAR_COMPRESSED ? " compressed"
@@ -427,7 +427,7 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_
{
CHARSET_INFO *cs= str->charset();
int bit_length= 8 * (metadata >> 8) + (metadata & 0xFF);
- uint32 length=
+ size_t length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
"bit(%d)", bit_length);
str->length(length);
@@ -437,7 +437,7 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_
case MYSQL_TYPE_DECIMAL:
{
CHARSET_INFO *cs= str->charset();
- uint32 length=
+ size_t length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
"decimal(%d,?)/*old*/", metadata);
str->length(length);
@@ -447,7 +447,7 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_
case MYSQL_TYPE_NEWDECIMAL:
{
CHARSET_INFO *cs= str->charset();
- uint32 length=
+ size_t length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
"decimal(%d,%d)", metadata >> 8, metadata & 0xff);
str->length(length);
@@ -503,7 +503,7 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_
*/
CHARSET_INFO *cs= str->charset();
uint bytes= (((metadata >> 4) & 0x300) ^ 0x300) + (metadata & 0x00ff);
- uint32 length=
+ size_t length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
"char(%d)", bytes / field_cs->mbmaxlen);
str->length(length);
diff --git a/plugin/semisync/semisync.cc b/sql/semisync.cc
index df37f03ec2f..a8a11f091db 100644
--- a/plugin/semisync/semisync.cc
+++ b/sql/semisync.cc
@@ -19,14 +19,14 @@
#include <my_global.h>
#include "semisync.h"
-const unsigned char ReplSemiSyncBase::kPacketMagicNum = 0xef;
-const unsigned char ReplSemiSyncBase::kPacketFlagSync = 0x01;
+const unsigned char Repl_semi_sync_base::k_packet_magic_num= 0xef;
+const unsigned char Repl_semi_sync_base::k_packet_flag_sync= 0x01;
-const unsigned long Trace::kTraceGeneral = 0x0001;
-const unsigned long Trace::kTraceDetail = 0x0010;
-const unsigned long Trace::kTraceNetWait = 0x0020;
-const unsigned long Trace::kTraceFunction = 0x0040;
+const unsigned long Trace::k_trace_general= 0x0001;
+const unsigned long Trace::k_trace_detail= 0x0010;
+const unsigned long Trace::k_trace_net_wait= 0x0020;
+const unsigned long Trace::k_trace_function= 0x0040;
-const unsigned char ReplSemiSyncBase::kSyncHeader[2] =
- {ReplSemiSyncBase::kPacketMagicNum, 0};
+const unsigned char Repl_semi_sync_base::k_sync_header[2]=
+ {Repl_semi_sync_base::k_packet_magic_num, 0};
diff --git a/plugin/semisync/semisync.h b/sql/semisync.h
index 28577296817..9deb6c5fd01 100644
--- a/plugin/semisync/semisync.h
+++ b/sql/semisync.h
@@ -1,6 +1,5 @@
/* Copyright (C) 2007 Google Inc.
Copyright (C) 2008 MySQL AB
- Use is subject to license terms
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,18 +18,9 @@
#ifndef SEMISYNC_H
#define SEMISYNC_H
-#define MYSQL_SERVER
-#define HAVE_REPLICATION
-#include <my_pthread.h>
-#include <sql_priv.h>
-#include <sql_class.h>
-#include "unireg.h"
-#include <replication.h>
-#include "log.h" /* sql_print_information */
-
-typedef struct st_mysql_show_var SHOW_VAR;
-typedef struct st_mysql_sys_var SYS_VAR;
-
+#include "mysqld.h"
+#include "log_event.h"
+#include "replication.h"
/**
This class is used to trace function calls and other process
@@ -38,44 +28,32 @@ typedef struct st_mysql_sys_var SYS_VAR;
*/
class Trace {
public:
- static const unsigned long kTraceFunction;
- static const unsigned long kTraceGeneral;
- static const unsigned long kTraceDetail;
- static const unsigned long kTraceNetWait;
-
- unsigned long trace_level_; /* the level for tracing */
+ static const unsigned long k_trace_function;
+ static const unsigned long k_trace_general;
+ static const unsigned long k_trace_detail;
+ static const unsigned long k_trace_net_wait;
- inline void function_enter(const char *func_name)
- {
- if (trace_level_ & kTraceFunction)
- sql_print_information("---> %s enter", func_name);
- }
- inline int function_exit(const char *func_name, int exit_code)
- {
- if (trace_level_ & kTraceFunction)
- sql_print_information("<--- %s exit (%d)", func_name, exit_code);
- return exit_code;
- }
+ unsigned long m_trace_level; /* the level for tracing */
Trace()
- :trace_level_(0L)
+ :m_trace_level(0L)
{}
Trace(unsigned long trace_level)
- :trace_level_(trace_level)
+ :m_trace_level(trace_level)
{}
};
/**
Base class for semi-sync master and slave classes
*/
-class ReplSemiSyncBase
+class Repl_semi_sync_base
:public Trace {
public:
- static const unsigned char kSyncHeader[2]; /* three byte packet header */
+ static const unsigned char k_sync_header[2]; /* three byte packet header */
/* Constants in network packet header. */
- static const unsigned char kPacketMagicNum;
- static const unsigned char kPacketFlagSync;
+ static const unsigned char k_packet_magic_num;
+ static const unsigned char k_packet_flag_sync;
};
/* The layout of a semisync slave reply packet:
@@ -89,5 +67,7 @@ public:
#define REPLY_MAGIC_NUM_OFFSET 0
#define REPLY_BINLOG_POS_OFFSET (REPLY_MAGIC_NUM_OFFSET + REPLY_MAGIC_NUM_LEN)
#define REPLY_BINLOG_NAME_OFFSET (REPLY_BINLOG_POS_OFFSET + REPLY_BINLOG_POS_LEN)
+#define REPLY_MESSAGE_MAX_LENGTH \
+ (REPLY_MAGIC_NUM_LEN + REPLY_BINLOG_POS_LEN + REPLY_BINLOG_NAME_LEN)
#endif /* SEMISYNC_H */
diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc
new file mode 100644
index 00000000000..3c88bdddad4
--- /dev/null
+++ b/sql/semisync_master.cc
@@ -0,0 +1,1352 @@
+/* Copyright (C) 2007 Google Inc.
+ Copyright (c) 2008, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2011, 2016, 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
+ 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-1301 USA */
+
+
+#include <my_global.h>
+#include "semisync_master.h"
+
+#define TIME_THOUSAND 1000
+#define TIME_MILLION 1000000
+#define TIME_BILLION 1000000000
+
+/* This indicates whether semi-synchronous replication is enabled. */
+my_bool rpl_semi_sync_master_enabled= 0;
+unsigned long long rpl_semi_sync_master_request_ack = 0;
+unsigned long long rpl_semi_sync_master_get_ack = 0;
+my_bool rpl_semi_sync_master_wait_no_slave = 1;
+my_bool rpl_semi_sync_master_status = 0;
+ulong rpl_semi_sync_master_wait_point =
+ SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT;
+ulong rpl_semi_sync_master_timeout;
+ulong rpl_semi_sync_master_trace_level;
+ulong rpl_semi_sync_master_yes_transactions = 0;
+ulong rpl_semi_sync_master_no_transactions = 0;
+ulong rpl_semi_sync_master_off_times = 0;
+ulong rpl_semi_sync_master_timefunc_fails = 0;
+ulong rpl_semi_sync_master_wait_timeouts = 0;
+ulong rpl_semi_sync_master_wait_sessions = 0;
+ulong rpl_semi_sync_master_wait_pos_backtraverse = 0;
+ulong rpl_semi_sync_master_avg_trx_wait_time = 0;
+ulonglong rpl_semi_sync_master_trx_wait_num = 0;
+ulong rpl_semi_sync_master_avg_net_wait_time = 0;
+ulonglong rpl_semi_sync_master_net_wait_num = 0;
+ulong rpl_semi_sync_master_clients = 0;
+ulonglong rpl_semi_sync_master_net_wait_time = 0;
+ulonglong rpl_semi_sync_master_trx_wait_time = 0;
+
+Repl_semi_sync_master repl_semisync_master;
+Ack_receiver ack_receiver;
+
+/*
+ structure to save transaction log filename and position
+*/
+typedef struct Trans_binlog_info {
+ my_off_t log_pos;
+ char log_file[FN_REFLEN];
+} Trans_binlog_info;
+
+static int get_wait_time(const struct timespec& start_ts);
+
+static ulonglong timespec_to_usec(const struct timespec *ts)
+{
+ return (ulonglong) ts->tv_sec * TIME_MILLION + ts->tv_nsec / TIME_THOUSAND;
+}
+
+/*******************************************************************************
+ *
+ * <Active_tranx> class : manage all active transaction nodes
+ *
+ ******************************************************************************/
+
+Active_tranx::Active_tranx(mysql_mutex_t *lock,
+ ulong trace_level)
+ : Trace(trace_level), m_allocator(max_connections),
+ m_num_entries(max_connections << 1), /* Transaction hash table size
+ * is set to double the size
+ * of max_connections */
+ m_lock(lock)
+{
+ /* No transactions are in the list initially. */
+ m_trx_front = NULL;
+ m_trx_rear = NULL;
+
+ /* Create the hash table to find a transaction's ending event. */
+ m_trx_htb = new Tranx_node *[m_num_entries];
+ for (int idx = 0; idx < m_num_entries; ++idx)
+ m_trx_htb[idx] = NULL;
+
+ sql_print_information("Semi-sync replication initialized for transactions.");
+}
+
+Active_tranx::~Active_tranx()
+{
+ delete [] m_trx_htb;
+ m_trx_htb = NULL;
+ m_num_entries = 0;
+}
+
+unsigned int Active_tranx::calc_hash(const unsigned char *key, size_t length)
+{
+ unsigned int nr = 1, nr2 = 4;
+
+ /* The hash implementation comes from calc_hashnr() in mysys/hash.c. */
+ while (length--)
+ {
+ nr ^= (((nr & 63)+nr2)*((unsigned int) (unsigned char) *key++))+ (nr << 8);
+ nr2 += 3;
+ }
+ return((unsigned int) nr);
+}
+
+unsigned int Active_tranx::get_hash_value(const char *log_file_name,
+ my_off_t log_file_pos)
+{
+ unsigned int hash1 = calc_hash((const unsigned char *)log_file_name,
+ strlen(log_file_name));
+ unsigned int hash2 = calc_hash((const unsigned char *)(&log_file_pos),
+ sizeof(log_file_pos));
+
+ return (hash1 + hash2) % m_num_entries;
+}
+
+int Active_tranx::compare(const char *log_file_name1, my_off_t log_file_pos1,
+ const char *log_file_name2, my_off_t log_file_pos2)
+{
+ int cmp = strcmp(log_file_name1, log_file_name2);
+
+ if (cmp != 0)
+ return cmp;
+
+ if (log_file_pos1 > log_file_pos2)
+ return 1;
+ else if (log_file_pos1 < log_file_pos2)
+ return -1;
+ return 0;
+}
+
+int Active_tranx::insert_tranx_node(const char *log_file_name,
+ my_off_t log_file_pos)
+{
+ Tranx_node *ins_node;
+ int result = 0;
+ unsigned int hash_val;
+
+ DBUG_ENTER("Active_tranx:insert_tranx_node");
+
+ ins_node = m_allocator.allocate_node();
+ if (!ins_node)
+ {
+ sql_print_error("%s: transaction node allocation failed for: (%s, %lu)",
+ "Active_tranx:insert_tranx_node",
+ log_file_name, (ulong)log_file_pos);
+ result = -1;
+ goto l_end;
+ }
+
+ /* insert the binlog position in the active transaction list. */
+ strncpy(ins_node->log_name, log_file_name, FN_REFLEN-1);
+ ins_node->log_name[FN_REFLEN-1] = 0; /* make sure it ends properly */
+ ins_node->log_pos = log_file_pos;
+
+ if (!m_trx_front)
+ {
+ /* The list is empty. */
+ m_trx_front = m_trx_rear = ins_node;
+ }
+ else
+ {
+ int cmp = compare(ins_node, m_trx_rear);
+ if (cmp > 0)
+ {
+ /* Compare with the tail first. If the transaction happens later in
+ * binlog, then make it the new tail.
+ */
+ m_trx_rear->next = ins_node;
+ m_trx_rear = ins_node;
+ }
+ else
+ {
+ /* Otherwise, it is an error because the transaction should hold the
+ * mysql_bin_log.LOCK_log when appending events.
+ */
+ sql_print_error("%s: binlog write out-of-order, tail (%s, %lu), "
+ "new node (%s, %lu)", "Active_tranx:insert_tranx_node",
+ m_trx_rear->log_name, (ulong)m_trx_rear->log_pos,
+ ins_node->log_name, (ulong)ins_node->log_pos);
+ result = -1;
+ goto l_end;
+ }
+ }
+
+ hash_val = get_hash_value(ins_node->log_name, ins_node->log_pos);
+ ins_node->hash_next = m_trx_htb[hash_val];
+ m_trx_htb[hash_val] = ins_node;
+
+ DBUG_PRINT("semisync", ("%s: insert (%s, %lu) in entry(%u)",
+ "Active_tranx:insert_tranx_node",
+ ins_node->log_name, (ulong)ins_node->log_pos,
+ hash_val));
+ l_end:
+
+ DBUG_RETURN(result);
+}
+
+bool Active_tranx::is_tranx_end_pos(const char *log_file_name,
+ my_off_t log_file_pos)
+{
+ DBUG_ENTER("Active_tranx::is_tranx_end_pos");
+
+ unsigned int hash_val = get_hash_value(log_file_name, log_file_pos);
+ Tranx_node *entry = m_trx_htb[hash_val];
+
+ while (entry != NULL)
+ {
+ if (compare(entry, log_file_name, log_file_pos) == 0)
+ break;
+
+ entry = entry->hash_next;
+ }
+
+ DBUG_PRINT("semisync", ("%s: probe (%s, %lu) in entry(%u)",
+ "Active_tranx::is_tranx_end_pos",
+ log_file_name, (ulong)log_file_pos, hash_val));
+
+ DBUG_RETURN(entry != NULL);
+}
+
+int Active_tranx::clear_active_tranx_nodes(const char *log_file_name,
+ my_off_t log_file_pos)
+{
+ Tranx_node *new_front;
+
+ DBUG_ENTER("Active_tranx::::clear_active_tranx_nodes");
+
+ if (log_file_name != NULL)
+ {
+ new_front = m_trx_front;
+
+ while (new_front)
+ {
+ if (compare(new_front, log_file_name, log_file_pos) > 0)
+ break;
+ new_front = new_front->next;
+ }
+ }
+ else
+ {
+ /* If log_file_name is NULL, clear everything. */
+ new_front = NULL;
+ }
+
+ if (new_front == NULL)
+ {
+ /* No active transaction nodes after the call. */
+
+ /* Clear the hash table. */
+ memset(m_trx_htb, 0, m_num_entries * sizeof(Tranx_node *));
+ m_allocator.free_all_nodes();
+
+ /* Clear the active transaction list. */
+ if (m_trx_front != NULL)
+ {
+ m_trx_front = NULL;
+ m_trx_rear = NULL;
+ }
+
+ DBUG_PRINT("semisync", ("%s: cleared all nodes",
+ "Active_tranx::::clear_active_tranx_nodes"));
+ }
+ else if (new_front != m_trx_front)
+ {
+ Tranx_node *curr_node, *next_node;
+
+ /* Delete all transaction nodes before the confirmation point. */
+ int n_frees = 0;
+ curr_node = m_trx_front;
+ while (curr_node != new_front)
+ {
+ next_node = curr_node->next;
+ n_frees++;
+
+ /* Remove the node from the hash table. */
+ unsigned int hash_val = get_hash_value(curr_node->log_name, curr_node->log_pos);
+ Tranx_node **hash_ptr = &(m_trx_htb[hash_val]);
+ while ((*hash_ptr) != NULL)
+ {
+ if ((*hash_ptr) == curr_node)
+ {
+ (*hash_ptr) = curr_node->hash_next;
+ break;
+ }
+ hash_ptr = &((*hash_ptr)->hash_next);
+ }
+
+ curr_node = next_node;
+ }
+
+ m_trx_front = new_front;
+ m_allocator.free_nodes_before(m_trx_front);
+
+ DBUG_PRINT("semisync", ("%s: cleared %d nodes back until pos (%s, %lu)",
+ "Active_tranx::::clear_active_tranx_nodes",
+ n_frees,
+ m_trx_front->log_name, (ulong)m_trx_front->log_pos));
+ }
+
+ DBUG_RETURN(0);
+}
+
+
+/*******************************************************************************
+ *
+ * <Repl_semi_sync_master> class: the basic code layer for syncsync master.
+ * <Repl_semi_sync_slave> class: the basic code layer for syncsync slave.
+ *
+ * The most important functions during semi-syn replication listed:
+ *
+ * Master:
+ * . report_reply_binlog(): called by the binlog dump thread when it receives
+ * the slave's status information.
+ * . update_sync_header(): based on transaction waiting information, decide
+ * whether to request the slave to reply.
+ * . write_tranx_in_binlog(): called by the transaction thread when it finishes
+ * writing all transaction events in binlog.
+ * . commit_trx(): transaction thread wait for the slave reply.
+ *
+ * Slave:
+ * . slave_read_sync_header(): read the semi-sync header from the master, get
+ * the sync status and get the payload for events.
+ * . slave_reply(): reply to the master about the replication progress.
+ *
+ ******************************************************************************/
+
+Repl_semi_sync_master::Repl_semi_sync_master()
+ : m_active_tranxs(NULL),
+ m_init_done(false),
+ m_reply_file_name_inited(false),
+ m_reply_file_pos(0L),
+ m_wait_file_name_inited(false),
+ m_wait_file_pos(0),
+ m_master_enabled(false),
+ m_wait_timeout(0L),
+ m_state(0),
+ m_wait_point(0)
+{
+ strcpy(m_reply_file_name, "");
+ strcpy(m_wait_file_name, "");
+}
+
+int Repl_semi_sync_master::init_object()
+{
+ int result;
+
+ m_init_done = true;
+
+ /* References to the parameter works after set_options(). */
+ set_wait_timeout(rpl_semi_sync_master_timeout);
+ set_trace_level(rpl_semi_sync_master_trace_level);
+ set_wait_point(rpl_semi_sync_master_wait_point);
+
+ /* Mutex initialization can only be done after MY_INIT(). */
+ mysql_mutex_init(key_LOCK_binlog,
+ &LOCK_binlog, MY_MUTEX_INIT_FAST);
+ mysql_cond_init(key_COND_binlog_send,
+ &COND_binlog_send, NULL);
+
+ if (rpl_semi_sync_master_enabled)
+ {
+ result = enable_master();
+ if (!result)
+ result= ack_receiver.start(); /* Start the ACK thread. */
+ }
+ else
+ {
+ result = disable_master();
+ }
+
+ /*
+ If rpl_semi_sync_master_wait_no_slave is disabled, let's temporarily
+ switch off semisync to avoid hang if there's none active slave.
+ */
+ if (!rpl_semi_sync_master_wait_no_slave)
+ switch_off();
+
+ return result;
+}
+
+int Repl_semi_sync_master::enable_master()
+{
+ int result = 0;
+
+ /* Must have the lock when we do enable of disable. */
+ lock();
+
+ if (!get_master_enabled())
+ {
+ m_active_tranxs = new Active_tranx(&LOCK_binlog, m_trace_level);
+ if (m_active_tranxs != NULL)
+ {
+ m_commit_file_name_inited = false;
+ m_reply_file_name_inited = false;
+ m_wait_file_name_inited = false;
+
+ set_master_enabled(true);
+ m_state = true;
+ sql_print_information("Semi-sync replication enabled on the master.");
+ }
+ else
+ {
+ sql_print_error("Cannot allocate memory to enable semi-sync on the master.");
+ result = -1;
+ }
+ }
+
+ unlock();
+
+ return result;
+}
+
+int Repl_semi_sync_master::disable_master()
+{
+ /* Must have the lock when we do enable of disable. */
+ lock();
+
+ if (get_master_enabled())
+ {
+ /* Switch off the semi-sync first so that waiting transaction will be
+ * waken up.
+ */
+ switch_off();
+
+ assert(m_active_tranxs != NULL);
+ delete m_active_tranxs;
+ m_active_tranxs = NULL;
+
+ m_reply_file_name_inited = false;
+ m_wait_file_name_inited = false;
+ m_commit_file_name_inited = false;
+
+ set_master_enabled(false);
+ sql_print_information("Semi-sync replication disabled on the master.");
+ }
+
+ unlock();
+
+ return 0;
+}
+
+void Repl_semi_sync_master::cleanup()
+{
+ if (m_init_done)
+ {
+ mysql_mutex_destroy(&LOCK_binlog);
+ mysql_cond_destroy(&COND_binlog_send);
+ m_init_done= 0;
+ }
+
+ delete m_active_tranxs;
+}
+
+void Repl_semi_sync_master::lock()
+{
+ mysql_mutex_lock(&LOCK_binlog);
+}
+
+void Repl_semi_sync_master::unlock()
+{
+ mysql_mutex_unlock(&LOCK_binlog);
+}
+
+void Repl_semi_sync_master::cond_broadcast()
+{
+ mysql_cond_broadcast(&COND_binlog_send);
+}
+
+int Repl_semi_sync_master::cond_timewait(struct timespec *wait_time)
+{
+ int wait_res;
+
+ DBUG_ENTER("Repl_semi_sync_master::cond_timewait()");
+
+ wait_res= mysql_cond_timedwait(&COND_binlog_send,
+ &LOCK_binlog, wait_time);
+
+ DBUG_RETURN(wait_res);
+}
+
+void Repl_semi_sync_master::add_slave()
+{
+ lock();
+ rpl_semi_sync_master_clients++;
+ unlock();
+}
+
+void Repl_semi_sync_master::remove_slave()
+{
+ lock();
+ rpl_semi_sync_master_clients--;
+
+ /* Only switch off if semi-sync is enabled and is on */
+ if (get_master_enabled() && is_on())
+ {
+ /* If user has chosen not to wait if no semi-sync slave available
+ and the last semi-sync slave exits, turn off semi-sync on master
+ immediately.
+ */
+ if (!rpl_semi_sync_master_wait_no_slave &&
+ rpl_semi_sync_master_clients == 0)
+ switch_off();
+ }
+ unlock();
+}
+
+int Repl_semi_sync_master::report_reply_packet(uint32 server_id,
+ const uchar *packet,
+ ulong packet_len)
+{
+ int result= -1;
+ char log_file_name[FN_REFLEN+1];
+ my_off_t log_file_pos;
+ ulong log_file_len = 0;
+
+ DBUG_ENTER("Repl_semi_sync_master::report_reply_packet");
+
+ if (unlikely(packet[REPLY_MAGIC_NUM_OFFSET] !=
+ Repl_semi_sync_master::k_packet_magic_num))
+ {
+ sql_print_error("Read semi-sync reply magic number error");
+ goto l_end;
+ }
+
+ if (unlikely(packet_len < REPLY_BINLOG_NAME_OFFSET))
+ {
+ sql_print_error("Read semi-sync reply length error: packet is too small");
+ goto l_end;
+ }
+
+ log_file_pos = uint8korr(packet + REPLY_BINLOG_POS_OFFSET);
+ log_file_len = packet_len - REPLY_BINLOG_NAME_OFFSET;
+ if (unlikely(log_file_len >= FN_REFLEN))
+ {
+ sql_print_error("Read semi-sync reply binlog file length too large");
+ goto l_end;
+ }
+ strncpy(log_file_name, (const char*)packet + REPLY_BINLOG_NAME_OFFSET, log_file_len);
+ log_file_name[log_file_len] = 0;
+
+ DBUG_ASSERT(dirname_length(log_file_name) == 0);
+
+ DBUG_PRINT("semisync", ("%s: Got reply(%s, %lu) from server %u",
+ "Repl_semi_sync_master::report_reply_packet",
+ log_file_name, (ulong)log_file_pos, server_id));
+
+ rpl_semi_sync_master_get_ack++;
+ report_reply_binlog(server_id, log_file_name, log_file_pos);
+
+l_end:
+
+ DBUG_RETURN(result);
+}
+
+int Repl_semi_sync_master::report_reply_binlog(uint32 server_id,
+ const char *log_file_name,
+ my_off_t log_file_pos)
+{
+ int cmp;
+ bool can_release_threads = false;
+ bool need_copy_send_pos = true;
+
+ DBUG_ENTER("Repl_semi_sync_master::report_reply_binlog");
+
+ if (!(get_master_enabled()))
+ DBUG_RETURN(0);
+
+ lock();
+
+ /* This is the real check inside the mutex. */
+ if (!get_master_enabled())
+ goto l_end;
+
+ if (!is_on())
+ /* We check to see whether we can switch semi-sync ON. */
+ try_switch_on(server_id, log_file_name, log_file_pos);
+
+ /* The position should increase monotonically, if there is only one
+ * thread sending the binlog to the slave.
+ * In reality, to improve the transaction availability, we allow multiple
+ * sync replication slaves. So, if any one of them get the transaction,
+ * the transaction session in the primary can move forward.
+ */
+ if (m_reply_file_name_inited)
+ {
+ cmp = Active_tranx::compare(log_file_name, log_file_pos,
+ m_reply_file_name, m_reply_file_pos);
+
+ /* If the requested position is behind the sending binlog position,
+ * would not adjust sending binlog position.
+ * We based on the assumption that there are multiple semi-sync slave,
+ * and at least one of them shou/ld be up to date.
+ * If all semi-sync slaves are behind, at least initially, the primary
+ * can find the situation after the waiting timeout. After that, some
+ * slaves should catch up quickly.
+ */
+ if (cmp < 0)
+ {
+ /* If the position is behind, do not copy it. */
+ need_copy_send_pos = false;
+ }
+ }
+
+ if (need_copy_send_pos)
+ {
+ strmake_buf(m_reply_file_name, log_file_name);
+ m_reply_file_pos = log_file_pos;
+ m_reply_file_name_inited = true;
+
+ /* Remove all active transaction nodes before this point. */
+ assert(m_active_tranxs != NULL);
+ m_active_tranxs->clear_active_tranx_nodes(log_file_name, log_file_pos);
+
+ DBUG_PRINT("semisync", ("%s: Got reply at (%s, %lu)",
+ "Repl_semi_sync_master::report_reply_binlog",
+ log_file_name, (ulong)log_file_pos));
+ }
+
+ if (rpl_semi_sync_master_wait_sessions > 0)
+ {
+ /* Let us check if some of the waiting threads doing a trx
+ * commit can now proceed.
+ */
+ cmp = Active_tranx::compare(m_reply_file_name, m_reply_file_pos,
+ m_wait_file_name, m_wait_file_pos);
+ if (cmp >= 0)
+ {
+ /* Yes, at least one waiting thread can now proceed:
+ * let us release all waiting threads with a broadcast
+ */
+ can_release_threads = true;
+ m_wait_file_name_inited = false;
+ }
+ }
+
+ l_end:
+ unlock();
+
+ if (can_release_threads)
+ {
+ DBUG_PRINT("semisync", ("%s: signal all waiting threads.",
+ "Repl_semi_sync_master::report_reply_binlog"));
+
+ cond_broadcast();
+ }
+
+ DBUG_RETURN(0);
+}
+
+int Repl_semi_sync_master::wait_after_sync(const char *log_file, my_off_t log_pos)
+{
+ if (!get_master_enabled())
+ return 0;
+
+ int ret= 0;
+ if(log_pos &&
+ wait_point() == SEMI_SYNC_MASTER_WAIT_POINT_AFTER_BINLOG_SYNC)
+ ret= commit_trx(log_file + dirname_length(log_file), log_pos);
+
+ return ret;
+}
+
+int Repl_semi_sync_master::wait_after_commit(THD* thd, bool all)
+{
+ if (!get_master_enabled())
+ return 0;
+
+ int ret= 0;
+ const char *log_file;
+ my_off_t log_pos;
+
+ bool is_real_trans=
+ (all || thd->transaction.all.ha_list == 0);
+ /*
+ The coordinates are propagated to this point having been computed
+ in report_binlog_update
+ */
+ Trans_binlog_info *log_info= thd->semisync_info;
+ log_file= log_info && log_info->log_file[0] ? log_info->log_file : 0;
+ log_pos= log_info ? log_info->log_pos : 0;
+
+ DBUG_ASSERT(!log_file || dirname_length(log_file) == 0);
+
+ if (is_real_trans &&
+ log_pos &&
+ wait_point() == SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT)
+ ret= commit_trx(log_file, log_pos);
+
+ if (is_real_trans && log_info)
+ {
+ log_info->log_file[0]= 0;
+ log_info->log_pos= 0;
+ }
+
+ return ret;
+}
+
+int Repl_semi_sync_master::wait_after_rollback(THD *thd, bool all)
+{
+ return wait_after_commit(thd, all);
+}
+
+/**
+ The method runs after flush to binary log is done.
+*/
+int Repl_semi_sync_master::report_binlog_update(THD* thd, const char *log_file,
+ my_off_t log_pos)
+{
+ if (get_master_enabled())
+ {
+ Trans_binlog_info *log_info;
+
+ if (!(log_info= thd->semisync_info))
+ {
+ if(!(log_info=
+ (Trans_binlog_info*) my_malloc(sizeof(Trans_binlog_info), MYF(0))))
+ return 1;
+ thd->semisync_info= log_info;
+ }
+ strcpy(log_info->log_file, log_file + dirname_length(log_file));
+ log_info->log_pos = log_pos;
+
+ return write_tranx_in_binlog(log_info->log_file, log_pos);
+ }
+
+ return 0;
+}
+
+int Repl_semi_sync_master::dump_start(THD* thd,
+ const char *log_file,
+ my_off_t log_pos)
+{
+ if (!thd->semi_sync_slave)
+ return 0;
+
+ if (ack_receiver.add_slave(thd))
+ {
+ sql_print_error("Failed to register slave to semi-sync ACK receiver "
+ "thread. Turning off semisync");
+ thd->semi_sync_slave= 0;
+ return 1;
+ }
+
+ add_slave();
+ report_reply_binlog(thd->variables.server_id,
+ log_file + dirname_length(log_file), log_pos);
+ sql_print_information("Start semi-sync binlog_dump to slave "
+ "(server_id: %ld), pos(%s, %lu)",
+ (long) thd->variables.server_id, log_file,
+ (ulong) log_pos);
+
+ return 0;
+}
+
+void Repl_semi_sync_master::dump_end(THD* thd)
+{
+ if (!thd->semi_sync_slave)
+ return;
+
+ sql_print_information("Stop semi-sync binlog_dump to slave (server_id: %ld)",
+ (long) thd->variables.server_id);
+
+ remove_slave();
+ ack_receiver.remove_slave(thd);
+
+ return;
+}
+
+int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name,
+ my_off_t trx_wait_binlog_pos)
+{
+
+ DBUG_ENTER("Repl_semi_sync_master::commit_trx");
+
+ if (get_master_enabled() && trx_wait_binlog_name)
+ {
+ struct timespec start_ts;
+ struct timespec abstime;
+ int wait_result;
+ PSI_stage_info old_stage;
+
+ set_timespec(start_ts, 0);
+
+ DEBUG_SYNC(current_thd, "rpl_semisync_master_commit_trx_before_lock");
+ /* Acquire the mutex. */
+ lock();
+
+ /* This must be called after acquired the lock */
+ THD_ENTER_COND(NULL, &COND_binlog_send, &LOCK_binlog,
+ & stage_waiting_for_semi_sync_ack_from_slave,
+ & old_stage);
+
+ /* This is the real check inside the mutex. */
+ if (!get_master_enabled() || !is_on())
+ goto l_end;
+
+ DBUG_PRINT("semisync", ("%s: wait pos (%s, %lu), repl(%d)\n",
+ "Repl_semi_sync_master::commit_trx",
+ trx_wait_binlog_name, (ulong)trx_wait_binlog_pos,
+ (int)is_on()));
+
+ while (is_on() && !thd_killed(current_thd))
+ {
+ if (m_reply_file_name_inited)
+ {
+ int cmp = Active_tranx::compare(m_reply_file_name, m_reply_file_pos,
+ trx_wait_binlog_name,
+ trx_wait_binlog_pos);
+ if (cmp >= 0)
+ {
+ /* We have already sent the relevant binlog to the slave: no need to
+ * wait here.
+ */
+ DBUG_PRINT("semisync", ("%s: Binlog reply is ahead (%s, %lu),",
+ "Repl_semi_sync_master::commit_trx",
+ m_reply_file_name,
+ (ulong)m_reply_file_pos));
+ break;
+ }
+ }
+
+ /* Let us update the info about the minimum binlog position of waiting
+ * threads.
+ */
+ if (m_wait_file_name_inited)
+ {
+ int cmp = Active_tranx::compare(trx_wait_binlog_name,
+ trx_wait_binlog_pos,
+ m_wait_file_name, m_wait_file_pos);
+ if (cmp <= 0)
+ {
+ /* This thd has a lower position, let's update the minimum info. */
+ strmake_buf(m_wait_file_name, trx_wait_binlog_name);
+ m_wait_file_pos = trx_wait_binlog_pos;
+
+ rpl_semi_sync_master_wait_pos_backtraverse++;
+ DBUG_PRINT("semisync", ("%s: move back wait position (%s, %lu),",
+ "Repl_semi_sync_master::commit_trx",
+ m_wait_file_name, (ulong)m_wait_file_pos));
+ }
+ }
+ else
+ {
+ strmake_buf(m_wait_file_name, trx_wait_binlog_name);
+ m_wait_file_pos = trx_wait_binlog_pos;
+ m_wait_file_name_inited = true;
+
+ DBUG_PRINT("semisync", ("%s: init wait position (%s, %lu),",
+ "Repl_semi_sync_master::commit_trx",
+ m_wait_file_name, (ulong)m_wait_file_pos));
+ }
+
+ /* Calcuate the waiting period. */
+ long diff_secs = (long) (m_wait_timeout / TIME_THOUSAND);
+ long diff_nsecs = (long) ((m_wait_timeout % TIME_THOUSAND) * TIME_MILLION);
+ long nsecs = start_ts.tv_nsec + diff_nsecs;
+ abstime.tv_sec = start_ts.tv_sec + diff_secs + nsecs/TIME_BILLION;
+ abstime.tv_nsec = nsecs % TIME_BILLION;
+
+ /* In semi-synchronous replication, we wait until the binlog-dump
+ * thread has received the reply on the relevant binlog segment from the
+ * replication slave.
+ *
+ * Let us suspend this thread to wait on the condition;
+ * when replication has progressed far enough, we will release
+ * these waiting threads.
+ */
+ rpl_semi_sync_master_wait_sessions++;
+
+ DBUG_PRINT("semisync", ("%s: wait %lu ms for binlog sent (%s, %lu)",
+ "Repl_semi_sync_master::commit_trx",
+ m_wait_timeout,
+ m_wait_file_name, (ulong)m_wait_file_pos));
+
+ wait_result = cond_timewait(&abstime);
+ rpl_semi_sync_master_wait_sessions--;
+
+ if (wait_result != 0)
+ {
+ /* This is a real wait timeout. */
+ sql_print_warning("Timeout waiting for reply of binlog (file: %s, pos: %lu), "
+ "semi-sync up to file %s, position %lu.",
+ trx_wait_binlog_name, (ulong)trx_wait_binlog_pos,
+ m_reply_file_name, (ulong)m_reply_file_pos);
+ rpl_semi_sync_master_wait_timeouts++;
+
+ /* switch semi-sync off */
+ switch_off();
+ }
+ else
+ {
+ int wait_time;
+
+ wait_time = get_wait_time(start_ts);
+ if (wait_time < 0)
+ {
+ DBUG_PRINT("semisync", ("Replication semi-sync getWaitTime fail at "
+ "wait position (%s, %lu)",
+ trx_wait_binlog_name,
+ (ulong)trx_wait_binlog_pos));
+ rpl_semi_sync_master_timefunc_fails++;
+ }
+ else
+ {
+ rpl_semi_sync_master_trx_wait_num++;
+ rpl_semi_sync_master_trx_wait_time += wait_time;
+ }
+ }
+ }
+
+ /*
+ At this point, the binlog file and position of this transaction
+ must have been removed from Active_tranx.
+ m_active_tranxs may be NULL if someone disabled semi sync during
+ cond_timewait()
+ */
+ assert(thd_killed(current_thd) || !m_active_tranxs ||
+ !m_active_tranxs->is_tranx_end_pos(trx_wait_binlog_name,
+ trx_wait_binlog_pos));
+
+ l_end:
+ /* Update the status counter. */
+ if (is_on())
+ rpl_semi_sync_master_yes_transactions++;
+ else
+ rpl_semi_sync_master_no_transactions++;
+
+ /* The lock held will be released by thd_exit_cond, so no need to
+ call unlock() here */
+ THD_EXIT_COND(NULL, & old_stage);
+ }
+
+ DBUG_RETURN(0);
+}
+
+/* Indicate that semi-sync replication is OFF now.
+ *
+ * What should we do when it is disabled? The problem is that we want
+ * the semi-sync replication enabled again when the slave catches up
+ * later. But, it is not that easy to detect that the slave has caught
+ * up. This is caused by the fact that MySQL's replication protocol is
+ * asynchronous, meaning that if the master does not use the semi-sync
+ * protocol, the slave would not send anything to the master.
+ * Still, if the master is sending (N+1)-th event, we assume that it is
+ * an indicator that the slave has received N-th event and earlier ones.
+ *
+ * If semi-sync is disabled, all transactions still update the wait
+ * position with the last position in binlog. But no transactions will
+ * wait for confirmations and the active transaction list would not be
+ * maintained. In binlog dump thread, update_sync_header() checks whether
+ * the current sending event catches up with last wait position. If it
+ * does match, semi-sync will be switched on again.
+ */
+int Repl_semi_sync_master::switch_off()
+{
+ int result;
+
+ DBUG_ENTER("Repl_semi_sync_master::switch_off");
+
+ m_state = false;
+
+ /* Clear the active transaction list. */
+ assert(m_active_tranxs != NULL);
+ result = m_active_tranxs->clear_active_tranx_nodes(NULL, 0);
+
+ rpl_semi_sync_master_off_times++;
+ m_wait_file_name_inited = false;
+ m_reply_file_name_inited = false;
+ sql_print_information("Semi-sync replication switched OFF.");
+ cond_broadcast(); /* wake up all waiting threads */
+
+ DBUG_RETURN(result);
+}
+
+int Repl_semi_sync_master::try_switch_on(int server_id,
+ const char *log_file_name,
+ my_off_t log_file_pos)
+{
+ bool semi_sync_on = false;
+
+ DBUG_ENTER("Repl_semi_sync_master::try_switch_on");
+
+ /* If the current sending event's position is larger than or equal to the
+ * 'largest' commit transaction binlog position, the slave is already
+ * catching up now and we can switch semi-sync on here.
+ * If m_commit_file_name_inited indicates there are no recent transactions,
+ * we can enable semi-sync immediately.
+ */
+ if (m_commit_file_name_inited)
+ {
+ int cmp = Active_tranx::compare(log_file_name, log_file_pos,
+ m_commit_file_name, m_commit_file_pos);
+ semi_sync_on = (cmp >= 0);
+ }
+ else
+ {
+ semi_sync_on = true;
+ }
+
+ if (semi_sync_on)
+ {
+ /* Switch semi-sync replication on. */
+ m_state = true;
+
+ sql_print_information("Semi-sync replication switched ON with slave (server_id: %d) "
+ "at (%s, %lu)",
+ server_id, log_file_name,
+ (ulong)log_file_pos);
+ }
+
+ DBUG_RETURN(0);
+}
+
+int Repl_semi_sync_master::reserve_sync_header(String* packet)
+{
+ DBUG_ENTER("Repl_semi_sync_master::reserve_sync_header");
+
+ /* Set the magic number and the sync status. By default, no sync
+ * is required.
+ */
+ packet->append(reinterpret_cast<const char*>(k_sync_header),
+ sizeof(k_sync_header));
+ DBUG_RETURN(0);
+}
+
+int Repl_semi_sync_master::update_sync_header(THD* thd, unsigned char *packet,
+ const char *log_file_name,
+ my_off_t log_file_pos,
+ bool* need_sync)
+{
+ int cmp = 0;
+ bool sync = false;
+
+ DBUG_ENTER("Repl_semi_sync_master::update_sync_header");
+
+ /* If the semi-sync master is not enabled, or the slave is not a semi-sync
+ * target, do not request replies from the slave.
+ */
+ if (!get_master_enabled() || !thd->semi_sync_slave)
+ {
+ *need_sync = false;
+ DBUG_RETURN(0);
+ }
+
+ lock();
+
+ /* This is the real check inside the mutex. */
+ if (!get_master_enabled())
+ {
+ assert(sync == false);
+ goto l_end;
+ }
+
+ if (is_on())
+ {
+ /* semi-sync is ON */
+ sync = false; /* No sync unless a transaction is involved. */
+
+ if (m_reply_file_name_inited)
+ {
+ cmp = Active_tranx::compare(log_file_name, log_file_pos,
+ m_reply_file_name, m_reply_file_pos);
+ if (cmp <= 0)
+ {
+ /* If we have already got the reply for the event, then we do
+ * not need to sync the transaction again.
+ */
+ goto l_end;
+ }
+ }
+
+ if (m_wait_file_name_inited)
+ {
+ cmp = Active_tranx::compare(log_file_name, log_file_pos,
+ m_wait_file_name, m_wait_file_pos);
+ }
+ else
+ {
+ cmp = 1;
+ }
+
+ /* If we are already waiting for some transaction replies which
+ * are later in binlog, do not wait for this one event.
+ */
+ if (cmp >= 0)
+ {
+ /*
+ * We only wait if the event is a transaction's ending event.
+ */
+ assert(m_active_tranxs != NULL);
+ sync = m_active_tranxs->is_tranx_end_pos(log_file_name,
+ log_file_pos);
+ }
+ }
+ else
+ {
+ if (m_commit_file_name_inited)
+ {
+ int cmp = Active_tranx::compare(log_file_name, log_file_pos,
+ m_commit_file_name, m_commit_file_pos);
+ sync = (cmp >= 0);
+ }
+ else
+ {
+ sync = true;
+ }
+ }
+
+ DBUG_PRINT("semisync", ("%s: server(%lu), (%s, %lu) sync(%d), repl(%d)",
+ "Repl_semi_sync_master::update_sync_header",
+ thd->variables.server_id, log_file_name,
+ (ulong)log_file_pos, sync, (int)is_on()));
+ *need_sync= sync;
+
+ l_end:
+ unlock();
+
+ /* We do not need to clear sync flag because we set it to 0 when we
+ * reserve the packet header.
+ */
+ if (sync)
+ {
+ (packet)[2] = k_packet_flag_sync;
+ }
+
+ DBUG_RETURN(0);
+}
+
+int Repl_semi_sync_master::write_tranx_in_binlog(const char* log_file_name,
+ my_off_t log_file_pos)
+{
+ int result = 0;
+
+ DBUG_ENTER("Repl_semi_sync_master::write_tranx_in_binlog");
+
+ lock();
+
+ /* This is the real check inside the mutex. */
+ if (!get_master_enabled())
+ goto l_end;
+
+ /* Update the 'largest' transaction commit position seen so far even
+ * though semi-sync is switched off.
+ * It is much better that we update m_commit_file* here, instead of
+ * inside commit_trx(). This is mostly because update_sync_header()
+ * will watch for m_commit_file* to decide whether to switch semi-sync
+ * on. The detailed reason is explained in function update_sync_header().
+ */
+ if (m_commit_file_name_inited)
+ {
+ int cmp = Active_tranx::compare(log_file_name, log_file_pos,
+ m_commit_file_name, m_commit_file_pos);
+ if (cmp > 0)
+ {
+ /* This is a larger position, let's update the maximum info. */
+ strncpy(m_commit_file_name, log_file_name, FN_REFLEN-1);
+ m_commit_file_name[FN_REFLEN-1] = 0; /* make sure it ends properly */
+ m_commit_file_pos = log_file_pos;
+ }
+ }
+ else
+ {
+ strncpy(m_commit_file_name, log_file_name, FN_REFLEN-1);
+ m_commit_file_name[FN_REFLEN-1] = 0; /* make sure it ends properly */
+ m_commit_file_pos = log_file_pos;
+ m_commit_file_name_inited = true;
+ }
+
+ if (is_on())
+ {
+ assert(m_active_tranxs != NULL);
+ if(m_active_tranxs->insert_tranx_node(log_file_name, log_file_pos))
+ {
+ /*
+ if insert tranx_node failed, print a warning message
+ and turn off semi-sync
+ */
+ sql_print_warning("Semi-sync failed to insert tranx_node for binlog file: %s, position: %lu",
+ log_file_name, (ulong)log_file_pos);
+ switch_off();
+ }
+ else
+ {
+ rpl_semi_sync_master_request_ack++;
+ }
+ }
+
+ l_end:
+ unlock();
+
+ DBUG_RETURN(result);
+}
+
+int Repl_semi_sync_master::flush_net(THD *thd,
+ const char *event_buf)
+{
+ int result = -1;
+ NET* net= &thd->net;
+
+ DBUG_ENTER("Repl_semi_sync_master::flush_net");
+
+ assert((unsigned char)event_buf[1] == k_packet_magic_num);
+ if ((unsigned char)event_buf[2] != k_packet_flag_sync)
+ {
+ /* current event does not require reply */
+ result = 0;
+ goto l_end;
+ }
+
+ /* We flush to make sure that the current event is sent to the network,
+ * instead of being buffered in the TCP/IP stack.
+ */
+ if (net_flush(net))
+ {
+ sql_print_error("Semi-sync master failed on net_flush() "
+ "before waiting for slave reply");
+ goto l_end;
+ }
+
+ net_clear(net, 0);
+ net->pkt_nr++;
+ result = 0;
+ rpl_semi_sync_master_net_wait_num++;
+
+ l_end:
+ thd->clear_error();
+
+ DBUG_RETURN(result);
+}
+
+int Repl_semi_sync_master::after_reset_master()
+{
+ int result = 0;
+
+ DBUG_ENTER("Repl_semi_sync_master::after_reset_master");
+
+ if (rpl_semi_sync_master_enabled)
+ {
+ sql_print_information("Enable Semi-sync Master after reset master");
+ enable_master();
+ }
+
+ lock();
+
+ if (rpl_semi_sync_master_clients == 0 &&
+ !rpl_semi_sync_master_wait_no_slave)
+ m_state = 0;
+ else
+ m_state = get_master_enabled()? 1 : 0;
+
+ m_wait_file_name_inited = false;
+ m_reply_file_name_inited = false;
+ m_commit_file_name_inited = false;
+
+ rpl_semi_sync_master_yes_transactions = 0;
+ rpl_semi_sync_master_no_transactions = 0;
+ rpl_semi_sync_master_off_times = 0;
+ rpl_semi_sync_master_timefunc_fails = 0;
+ rpl_semi_sync_master_wait_sessions = 0;
+ rpl_semi_sync_master_wait_pos_backtraverse = 0;
+ rpl_semi_sync_master_trx_wait_num = 0;
+ rpl_semi_sync_master_trx_wait_time = 0;
+ rpl_semi_sync_master_net_wait_num = 0;
+ rpl_semi_sync_master_net_wait_time = 0;
+
+ unlock();
+
+ DBUG_RETURN(result);
+}
+
+int Repl_semi_sync_master::before_reset_master()
+{
+ int result = 0;
+
+ DBUG_ENTER("Repl_semi_sync_master::before_reset_master");
+
+ if (rpl_semi_sync_master_enabled)
+ disable_master();
+
+ DBUG_RETURN(result);
+}
+
+void Repl_semi_sync_master::check_and_switch()
+{
+ lock();
+ if (get_master_enabled() && is_on())
+ {
+ if (!rpl_semi_sync_master_wait_no_slave
+ && rpl_semi_sync_master_clients == 0)
+ switch_off();
+ }
+ unlock();
+}
+
+void Repl_semi_sync_master::set_export_stats()
+{
+ lock();
+
+ rpl_semi_sync_master_status = m_state;
+ rpl_semi_sync_master_avg_trx_wait_time=
+ ((rpl_semi_sync_master_trx_wait_num) ?
+ (ulong)((double)rpl_semi_sync_master_trx_wait_time /
+ ((double)rpl_semi_sync_master_trx_wait_num)) : 0);
+ rpl_semi_sync_master_avg_net_wait_time=
+ ((rpl_semi_sync_master_net_wait_num) ?
+ (ulong)((double)rpl_semi_sync_master_net_wait_time /
+ ((double)rpl_semi_sync_master_net_wait_num)) : 0);
+
+ unlock();
+}
+
+/* Get the waiting time given the wait's staring time.
+ *
+ * Return:
+ * >= 0: the waiting time in microsecons(us)
+ * < 0: error in get time or time back traverse
+ */
+static int get_wait_time(const struct timespec& start_ts)
+{
+ ulonglong start_usecs, end_usecs;
+ struct timespec end_ts;
+
+ /* Starting time in microseconds(us). */
+ start_usecs = timespec_to_usec(&start_ts);
+
+ /* Get the wait time interval. */
+ set_timespec(end_ts, 0);
+
+ /* Ending time in microseconds(us). */
+ end_usecs = timespec_to_usec(&end_ts);
+
+ if (end_usecs < start_usecs)
+ return -1;
+
+ return (int)(end_usecs - start_usecs);
+}
+
+void semi_sync_master_deinit()
+{
+ repl_semisync_master.cleanup();
+ ack_receiver.cleanup();
+}
diff --git a/plugin/semisync/semisync_master.h b/sql/semisync_master.h
index c2862476ec8..3b05d9e0348 100644
--- a/plugin/semisync/semisync_master.h
+++ b/sql/semisync_master.h
@@ -20,26 +20,25 @@
#define SEMISYNC_MASTER_H
#include "semisync.h"
+#include "semisync_master_ack_receiver.h"
#ifdef HAVE_PSI_INTERFACE
-extern PSI_mutex_key key_ss_mutex_LOCK_binlog_;
-extern PSI_cond_key key_ss_cond_COND_binlog_send_;
+extern PSI_mutex_key key_LOCK_binlog;
+extern PSI_cond_key key_COND_binlog_send;
#endif
-extern PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave;
-
-struct TranxNode {
- char log_name_[FN_REFLEN];
- my_off_t log_pos_;
- struct TranxNode *next_; /* the next node in the sorted list */
- struct TranxNode *hash_next_; /* the next node during hash collision */
+struct Tranx_node {
+ char log_name[FN_REFLEN];
+ my_off_t log_pos;
+ struct Tranx_node *next; /* the next node in the sorted list */
+ struct Tranx_node *hash_next; /* the next node during hash collision */
};
/**
- @class TranxNodeAllocator
+ @class Tranx_node_allocator
This class provides memory allocating and freeing methods for
- TranxNode. The main target is performance.
+ Tranx_node. The main target is performance.
@section ALLOCATE How to allocate a node
The pointer of the first node after 'last_node' in current_block is
@@ -52,7 +51,7 @@ struct TranxNode {
After some nodes are freed, there probably are some free nodes before
the sequence of the allocated nodes, but we do not reuse it. It is better
to keep the allocated nodes are in the sequence, for it is more efficient
- for allocating and freeing TranxNode.
+ for allocating and freeing Tranx_node.
@section FREENODE How to free nodes
There are two methods for freeing nodes. They are free_all_nodes and
@@ -69,23 +68,23 @@ struct TranxNode {
more efficient.
*/
#define BLOCK_TRANX_NODES 16
-class TranxNodeAllocator
+class Tranx_node_allocator
{
public:
/**
@param reserved_nodes
- The number of reserved TranxNodes. It is used to set 'reserved_blocks'
- which can contain at least 'reserved_nodes' number of TranxNodes. When
+ The number of reserved Tranx_nodes. It is used to set 'reserved_blocks'
+ which can contain at least 'reserved_nodes' number of Tranx_nodes. When
freeing memory, we will reserve at least reserved_blocks of Blocks not
freed.
*/
- TranxNodeAllocator(uint reserved_nodes) :
+ Tranx_node_allocator(uint reserved_nodes) :
reserved_blocks(reserved_nodes/BLOCK_TRANX_NODES +
(reserved_nodes%BLOCK_TRANX_NODES > 1 ? 2 : 1)),
first_block(NULL), last_block(NULL),
current_block(NULL), last_node(-1), block_num(0) {}
- ~TranxNodeAllocator()
+ ~Tranx_node_allocator()
{
Block *block= first_block;
while (block != NULL)
@@ -102,11 +101,11 @@ public:
it are in use. A new Block is allocated and is put into the rear of the
Block link table if no Block is free.
- @return Return a TranxNode *, or NULL if an error occurred.
+ @return Return a Tranx_node *, or NULL if an error occurred.
*/
- TranxNode *allocate_node()
+ Tranx_node *allocate_node()
{
- TranxNode *trx_node;
+ Tranx_node *trx_node;
Block *block= current_block;
if (last_node == BLOCK_TRANX_NODES-1)
@@ -124,10 +123,10 @@ public:
}
trx_node= &(current_block->nodes[++last_node]);
- trx_node->log_name_[0] = '\0';
- trx_node->log_pos_= 0;
- trx_node->next_= 0;
- trx_node->hash_next_= 0;
+ trx_node->log_name[0] = '\0';
+ trx_node->log_pos= 0;
+ trx_node->next= 0;
+ trx_node->hash_next= 0;
return trx_node;
}
@@ -152,7 +151,7 @@ public:
@return Return 0, or 1 if an error occurred.
*/
- int free_nodes_before(TranxNode* node)
+ int free_nodes_before(Tranx_node* node)
{
Block *block;
Block *prev_block= NULL;
@@ -187,16 +186,16 @@ private:
uint reserved_blocks;
/**
- A sequence memory which contains BLOCK_TRANX_NODES TranxNodes.
+ A sequence memory which contains BLOCK_TRANX_NODES Tranx_nodes.
- BLOCK_TRANX_NODES The number of TranxNodes which are in a Block.
+ BLOCK_TRANX_NODES The number of Tranx_nodes which are in a Block.
next Every Block has a 'next' pointer which points to the next Block.
These linking Blocks constitute a Block link table.
*/
struct Block {
Block *next;
- TranxNode nodes[BLOCK_TRANX_NODES];
+ Tranx_node nodes[BLOCK_TRANX_NODES];
};
/**
@@ -291,47 +290,47 @@ private:
/**
This class manages memory for active transaction list.
- We record each active transaction with a TranxNode, each session
+ We record each active transaction with a Tranx_node, each session
can have only one open transaction. Because of EVENT, the total
active transaction nodes can exceed the maximum allowed
connections.
*/
-class ActiveTranx
+class Active_tranx
:public Trace {
private:
- TranxNodeAllocator allocator_;
+ Tranx_node_allocator m_allocator;
/* These two record the active transaction list in sort order. */
- TranxNode *trx_front_, *trx_rear_;
+ Tranx_node *m_trx_front, *m_trx_rear;
- TranxNode **trx_htb_; /* A hash table on active transactions. */
+ Tranx_node **m_trx_htb; /* A hash table on active transactions. */
- int num_entries_; /* maximum hash table entries */
- mysql_mutex_t *lock_; /* mutex lock */
+ int m_num_entries; /* maximum hash table entries */
+ mysql_mutex_t *m_lock; /* mutex lock */
inline void assert_lock_owner();
- inline unsigned int calc_hash(const unsigned char *key,unsigned int length);
+ inline unsigned int calc_hash(const unsigned char *key, size_t length);
unsigned int get_hash_value(const char *log_file_name, my_off_t log_file_pos);
int compare(const char *log_file_name1, my_off_t log_file_pos1,
- const TranxNode *node2) {
+ const Tranx_node *node2) {
return compare(log_file_name1, log_file_pos1,
- node2->log_name_, node2->log_pos_);
+ node2->log_name, node2->log_pos);
}
- int compare(const TranxNode *node1,
+ int compare(const Tranx_node *node1,
const char *log_file_name2, my_off_t log_file_pos2) {
- return compare(node1->log_name_, node1->log_pos_,
+ return compare(node1->log_name, node1->log_pos,
log_file_name2, log_file_pos2);
}
- int compare(const TranxNode *node1, const TranxNode *node2) {
- return compare(node1->log_name_, node1->log_pos_,
- node2->log_name_, node2->log_pos_);
+ int compare(const Tranx_node *node1, const Tranx_node *node2) {
+ return compare(node1->log_name, node1->log_pos,
+ node2->log_name, node2->log_pos);
}
public:
- ActiveTranx(mysql_mutex_t *lock, unsigned long trace_level);
- ~ActiveTranx();
+ Active_tranx(mysql_mutex_t *lock, unsigned long trace_level);
+ ~Active_tranx();
/* Insert an active transaction node with the specified position.
*
@@ -367,49 +366,49 @@ public:
/**
The extension class for the master of semi-synchronous replication
*/
-class ReplSemiSyncMaster
- :public ReplSemiSyncBase {
+class Repl_semi_sync_master
+ :public Repl_semi_sync_base {
private:
- ActiveTranx *active_tranxs_; /* active transaction list: the list will
+ Active_tranx *m_active_tranxs; /* active transaction list: the list will
be cleared when semi-sync switches off. */
- /* True when initObject has been called */
- bool init_done_;
+ /* True when init_object has been called */
+ bool m_init_done;
/* This cond variable is signaled when enough binlog has been sent to slave,
* so that a waiting trx can return the 'ok' to the client for a commit.
*/
- mysql_cond_t COND_binlog_send_;
+ mysql_cond_t COND_binlog_send;
/* Mutex that protects the following state variables and the active
* transaction list.
* Under no cirumstances we can acquire mysql_bin_log.LOCK_log if we are
- * already holding LOCK_binlog_ because it can cause deadlocks.
+ * already holding m_LOCK_binlog because it can cause deadlocks.
*/
- mysql_mutex_t LOCK_binlog_;
+ mysql_mutex_t LOCK_binlog;
- /* This is set to true when reply_file_name_ contains meaningful data. */
- bool reply_file_name_inited_;
+ /* This is set to true when m_reply_file_name contains meaningful data. */
+ bool m_reply_file_name_inited;
/* The binlog name up to which we have received replies from any slaves. */
- char reply_file_name_[FN_REFLEN];
+ char m_reply_file_name[FN_REFLEN];
/* The position in that file up to which we have the reply from any slaves. */
- my_off_t reply_file_pos_;
+ my_off_t m_reply_file_pos;
/* This is set to true when we know the 'smallest' wait position. */
- bool wait_file_name_inited_;
+ bool m_wait_file_name_inited;
/* NULL, or the 'smallest' filename that a transaction is waiting for
* slave replies.
*/
- char wait_file_name_[FN_REFLEN];
+ char m_wait_file_name[FN_REFLEN];
/* The smallest position in that file that a trx is waiting for: the trx
* can proceed and send an 'ok' to the client when the master has got the
* reply from the slave indicating that it already got the binlog events.
*/
- my_off_t wait_file_pos_;
+ my_off_t m_wait_file_pos;
/* This is set to true when we know the 'largest' transaction commit
* position in the binlog file.
@@ -418,19 +417,22 @@ class ReplSemiSyncMaster
* switch off. Binlog-dump thread can use the three fields to detect when
* slaves catch up on replication so that semi-sync can switch on again.
*/
- bool commit_file_name_inited_;
+ bool m_commit_file_name_inited;
/* The 'largest' binlog filename that a commit transaction is seeing. */
- char commit_file_name_[FN_REFLEN];
+ char m_commit_file_name[FN_REFLEN];
/* The 'largest' position in that file that a commit transaction is seeing. */
- my_off_t commit_file_pos_;
+ my_off_t m_commit_file_pos;
/* All global variables which can be set by parameters. */
- volatile bool master_enabled_; /* semi-sync is enabled on the master */
- unsigned long wait_timeout_; /* timeout period(ms) during tranx wait */
+ volatile bool m_master_enabled; /* semi-sync is enabled on the master */
+ unsigned long m_wait_timeout; /* timeout period(ms) during tranx wait */
- bool state_; /* whether semi-sync is switched */
+ bool m_state; /* whether semi-sync is switched */
+
+ /*Waiting for ACK before/after innodb commit*/
+ ulong m_wait_point;
void lock();
void unlock();
@@ -439,11 +441,11 @@ class ReplSemiSyncMaster
/* Is semi-sync replication on? */
bool is_on() {
- return (state_);
+ return (m_state);
}
void set_master_enabled(bool enabled) {
- master_enabled_ = enabled;
+ m_master_enabled = enabled;
}
/* Switch semi-sync off because of timeout in transaction waiting. */
@@ -454,35 +456,46 @@ class ReplSemiSyncMaster
const char *log_file_name, my_off_t log_file_pos);
public:
- ReplSemiSyncMaster();
- ~ReplSemiSyncMaster() {}
+ Repl_semi_sync_master();
+ ~Repl_semi_sync_master() {}
void cleanup();
- bool getMasterEnabled() {
- return master_enabled_;
+ bool get_master_enabled() {
+ return m_master_enabled;
}
- void setTraceLevel(unsigned long trace_level) {
- trace_level_ = trace_level;
- if (active_tranxs_)
- active_tranxs_->trace_level_ = trace_level;
+ void set_trace_level(unsigned long trace_level) {
+ m_trace_level = trace_level;
+ if (m_active_tranxs)
+ m_active_tranxs->m_trace_level = trace_level;
}
/* Set the transaction wait timeout period, in milliseconds. */
- void setWaitTimeout(unsigned long wait_timeout) {
- wait_timeout_ = wait_timeout;
+ void set_wait_timeout(unsigned long wait_timeout) {
+ m_wait_timeout = wait_timeout;
+ }
+
+ /*set the ACK point, after binlog sync or after transaction commit*/
+ void set_wait_point(unsigned long ack_point)
+ {
+ m_wait_point = ack_point;
+ }
+
+ ulong wait_point() //no cover line
+ {
+ return m_wait_point; //no cover line
}
/* Initialize this class after MySQL parameters are initialized. this
* function should be called once at bootstrap time.
*/
- int initObject();
+ int init_object();
/* Enable the object to enable semi-sync replication inside the master. */
- int enableMaster();
+ int enable_master();
/* Enable the object to enable semi-sync replication inside the master. */
- int disableMaster();
+ int disable_master();
/* Add a semi-sync replication slave */
void add_slave();
@@ -490,8 +503,9 @@ class ReplSemiSyncMaster
/* Remove a semi-sync replication slave */
void remove_slave();
- /* Is the slave servered by the thread requested semi-sync */
- bool is_semi_sync_slave();
+ /* It parses a reply packet and call report_reply_binlog to handle it. */
+ int report_reply_packet(uint32 server_id, const uchar *packet,
+ ulong packet_len);
/* In semi-sync replication, reports up to which binlog position we have
* received replies from the slave indicating that it already get the events.
@@ -505,9 +519,9 @@ class ReplSemiSyncMaster
* Return:
* 0: success; non-zero: error
*/
- int reportReplyBinlog(uint32 server_id,
- const char* log_file_name,
- my_off_t end_offset);
+ int report_reply_binlog(uint32 server_id,
+ const char* log_file_name,
+ my_off_t end_offset);
/* Commit a transaction in the final step. This function is called from
* InnoDB before returning from the low commit. If semi-sync is switch on,
@@ -524,45 +538,64 @@ class ReplSemiSyncMaster
* Return:
* 0: success; non-zero: error
*/
- int commitTrx(const char* trx_wait_binlog_name,
- my_off_t trx_wait_binlog_pos);
+ int commit_trx(const char* trx_wait_binlog_name,
+ my_off_t trx_wait_binlog_pos);
+
+ /*Wait for ACK after writing/sync binlog to file*/
+ int wait_after_sync(const char* log_file, my_off_t log_pos);
+
+ /*Wait for ACK after commting the transaction*/
+ int wait_after_commit(THD* thd, bool all);
+
+ /*Wait after the transaction is rollback*/
+ int wait_after_rollback(THD *thd, bool all);
+ /*Store the current binlog position in m_active_tranxs. This position should
+ * be acked by slave*/
+ int report_binlog_update(THD *thd, const char *log_file,my_off_t log_pos);
+
+ int dump_start(THD* thd,
+ const char *log_file,
+ my_off_t log_pos);
+
+ void dump_end(THD* thd);
/* Reserve space in the replication event packet header:
* . slave semi-sync off: 1 byte - (0)
* . slave semi-sync on: 3 byte - (0, 0xef, 0/1}
- *
+ *
* Input:
- * header - (IN) the header buffer
- * size - (IN) size of the header buffer
+ * packet - (IN) the header buffer
*
* Return:
* size of the bytes reserved for header
*/
- int reserveSyncHeader(unsigned char *header, unsigned long size);
+ int reserve_sync_header(String* packet);
/* Update the sync bit in the packet header to indicate to the slave whether
* the master will wait for the reply of the event. If semi-sync is switched
* off and we detect that the slave is catching up, we switch semi-sync on.
*
* Input:
+ * THD - (IN) current dump thread
* packet - (IN) the packet containing the replication event
* log_file_name - (IN) the event ending position's file name
* log_file_pos - (IN) the event ending position's file offset
+ * need_sync - (IN) identify if flush_net is needed to call.
* server_id - (IN) master server id number
*
* Return:
* 0: success; non-zero: error
*/
- int updateSyncHeader(unsigned char *packet,
- const char *log_file_name,
- my_off_t log_file_pos,
- uint32 server_id);
+ int update_sync_header(THD* thd, unsigned char *packet,
+ const char *log_file_name,
+ my_off_t log_file_pos,
+ bool* need_sync);
/* Called when a transaction finished writing binlog events.
* . update the 'largest' transactions' binlog event position
* . insert the ending position in the active transaction list if
* semi-sync is on
- *
+ *
* Input: (the transaction events' ending binlog position)
* log_file_name - (IN) transaction ending position's file name
* log_file_pos - (IN) transaction ending position's file offset
@@ -570,28 +603,25 @@ class ReplSemiSyncMaster
* Return:
* 0: success; non-zero: error
*/
- int writeTranxInBinlog(const char* log_file_name, my_off_t log_file_pos);
+ int write_tranx_in_binlog(const char* log_file_name, my_off_t log_file_pos);
/* Read the slave's reply so that we know how much progress the slave makes
* on receive replication events.
- *
- * Input:
- * net - (IN) the connection to master
- * server_id - (IN) master server id number
- * event_buf - (IN) pointer to the event packet
- *
- * Return:
- * 0: success; non-zero: error
*/
- int readSlaveReply(NET *net, uint32 server_id, const char *event_buf);
+ int flush_net(THD* thd, const char *event_buf);
/* Export internal statistics for semi-sync replication. */
- void setExportStats();
+ void set_export_stats();
/* 'reset master' command is issued from the user and semi-sync need to
* go off for that.
*/
- int resetMaster();
+ int after_reset_master();
+
+ /*called before reset master*/
+ int before_reset_master();
+
+ void check_and_switch();
};
enum rpl_semi_sync_master_wait_point_t {
@@ -599,27 +629,32 @@ enum rpl_semi_sync_master_wait_point_t {
SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT,
};
+extern Repl_semi_sync_master repl_semisync_master;
+extern Ack_receiver ack_receiver;
+
/* System and status variables for the master component */
-extern char rpl_semi_sync_master_enabled;
-extern char rpl_semi_sync_master_status;
-extern unsigned long rpl_semi_sync_master_wait_point;
-extern unsigned long rpl_semi_sync_master_clients;
-extern unsigned long rpl_semi_sync_master_timeout;
-extern unsigned long rpl_semi_sync_master_trace_level;
-extern unsigned long rpl_semi_sync_master_yes_transactions;
-extern unsigned long rpl_semi_sync_master_no_transactions;
-extern unsigned long rpl_semi_sync_master_off_times;
-extern unsigned long rpl_semi_sync_master_wait_timeouts;
-extern unsigned long rpl_semi_sync_master_timefunc_fails;
-extern unsigned long rpl_semi_sync_master_num_timeouts;
-extern unsigned long rpl_semi_sync_master_wait_sessions;
-extern unsigned long rpl_semi_sync_master_wait_pos_backtraverse;
-extern unsigned long rpl_semi_sync_master_avg_trx_wait_time;
-extern unsigned long rpl_semi_sync_master_avg_net_wait_time;
-extern unsigned long long rpl_semi_sync_master_net_wait_num;
-extern unsigned long long rpl_semi_sync_master_trx_wait_num;
-extern unsigned long long rpl_semi_sync_master_net_wait_time;
-extern unsigned long long rpl_semi_sync_master_trx_wait_time;
+extern my_bool rpl_semi_sync_master_enabled;
+extern my_bool rpl_semi_sync_master_status;
+extern ulong rpl_semi_sync_master_wait_point;
+extern ulong rpl_semi_sync_master_clients;
+extern ulong rpl_semi_sync_master_timeout;
+extern ulong rpl_semi_sync_master_trace_level;
+extern ulong rpl_semi_sync_master_yes_transactions;
+extern ulong rpl_semi_sync_master_no_transactions;
+extern ulong rpl_semi_sync_master_off_times;
+extern ulong rpl_semi_sync_master_wait_timeouts;
+extern ulong rpl_semi_sync_master_timefunc_fails;
+extern ulong rpl_semi_sync_master_num_timeouts;
+extern ulong rpl_semi_sync_master_wait_sessions;
+extern ulong rpl_semi_sync_master_wait_pos_backtraverse;
+extern ulong rpl_semi_sync_master_avg_trx_wait_time;
+extern ulong rpl_semi_sync_master_avg_net_wait_time;
+extern ulonglong rpl_semi_sync_master_net_wait_num;
+extern ulonglong rpl_semi_sync_master_trx_wait_num;
+extern ulonglong rpl_semi_sync_master_net_wait_time;
+extern ulonglong rpl_semi_sync_master_trx_wait_time;
+extern unsigned long long rpl_semi_sync_master_request_ack;
+extern unsigned long long rpl_semi_sync_master_get_ack;
/*
This indicates whether we should keep waiting if no semi-sync slave
@@ -628,5 +663,12 @@ extern unsigned long long rpl_semi_sync_master_trx_wait_time;
1 (default) : keep waiting until timeout even no available semi-sync slave.
*/
extern char rpl_semi_sync_master_wait_no_slave;
+extern Repl_semi_sync_master repl_semisync_master;
+
+extern PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave;
+extern PSI_stage_info stage_reading_semi_sync_ack;
+extern PSI_stage_info stage_waiting_for_semi_sync_slave;
+
+void semi_sync_master_deinit();
#endif /* SEMISYNC_MASTER_H */
diff --git a/sql/semisync_master_ack_receiver.cc b/sql/semisync_master_ack_receiver.cc
new file mode 100644
index 00000000000..ac17c7de40b
--- /dev/null
+++ b/sql/semisync_master_ack_receiver.cc
@@ -0,0 +1,307 @@
+/* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ 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-1301 USA */
+
+#include <my_global.h>
+#include "semisync_master.h"
+#include "semisync_master_ack_receiver.h"
+
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+extern PSI_mutex_key key_LOCK_ack_receiver;
+extern PSI_cond_key key_COND_ack_receiver;
+#endif
+#ifdef HAVE_PSI_THREAD_INTERFACE
+extern PSI_thread_key key_thread_ack_receiver;
+#endif
+extern Repl_semi_sync_master repl_semisync;
+
+/* Callback function of ack receive thread */
+pthread_handler_t ack_receive_handler(void *arg)
+{
+ Ack_receiver *recv= reinterpret_cast<Ack_receiver *>(arg);
+
+ my_thread_init();
+ recv->run();
+ my_thread_end();
+
+ return NULL;
+}
+
+Ack_receiver::Ack_receiver()
+{
+ DBUG_ENTER("Ack_receiver::Ack_receiver");
+
+ m_status= ST_DOWN;
+ mysql_mutex_init(key_LOCK_ack_receiver, &m_mutex,
+ MY_MUTEX_INIT_FAST);
+ mysql_cond_init(key_COND_ack_receiver, &m_cond, NULL);
+ m_pid= 0;
+
+ DBUG_VOID_RETURN;
+}
+
+void Ack_receiver::cleanup()
+{
+ DBUG_ENTER("Ack_receiver::~Ack_receiver");
+
+ stop();
+ mysql_mutex_destroy(&m_mutex);
+ mysql_cond_destroy(&m_cond);
+
+ DBUG_VOID_RETURN;
+}
+
+bool Ack_receiver::start()
+{
+ DBUG_ENTER("Ack_receiver::start");
+
+ mysql_mutex_lock(&m_mutex);
+ if(m_status == ST_DOWN)
+ {
+ pthread_attr_t attr;
+
+ m_status= ST_UP;
+
+ if (DBUG_EVALUATE_IF("rpl_semisync_simulate_create_thread_failure", 1, 0) ||
+ pthread_attr_init(&attr) != 0 ||
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) != 0 ||
+#ifndef _WIN32
+ pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) != 0 ||
+#endif
+ mysql_thread_create(key_thread_ack_receiver, &m_pid,
+ &attr, ack_receive_handler, this))
+ {
+ sql_print_error("Failed to start semi-sync ACK receiver thread, "
+ " could not create thread(errno:%d)", errno);
+
+ m_status= ST_DOWN;
+ mysql_mutex_unlock(&m_mutex);
+
+ DBUG_RETURN(true);
+ }
+ (void) pthread_attr_destroy(&attr);
+ }
+ mysql_mutex_unlock(&m_mutex);
+
+ DBUG_RETURN(false);
+}
+
+void Ack_receiver::stop()
+{
+ DBUG_ENTER("Ack_receiver::stop");
+
+ mysql_mutex_lock(&m_mutex);
+ if (m_status == ST_UP)
+ {
+ m_status= ST_STOPPING;
+ mysql_cond_broadcast(&m_cond);
+
+ while (m_status == ST_STOPPING)
+ mysql_cond_wait(&m_cond, &m_mutex);
+
+ DBUG_ASSERT(m_status == ST_DOWN);
+
+ m_pid= 0;
+ }
+ mysql_mutex_unlock(&m_mutex);
+
+ DBUG_VOID_RETURN;
+}
+
+bool Ack_receiver::add_slave(THD *thd)
+{
+ Slave *slave;
+ DBUG_ENTER("Ack_receiver::add_slave");
+
+ if (!(slave= new Slave))
+ DBUG_RETURN(true);
+
+ slave->thd= thd;
+ slave->vio= *thd->net.vio;
+ slave->vio.mysql_socket.m_psi= NULL;
+ slave->vio.read_timeout= 1;
+
+ mysql_mutex_lock(&m_mutex);
+ m_slaves.push_back(slave);
+ m_slaves_changed= true;
+ mysql_cond_broadcast(&m_cond);
+ mysql_mutex_unlock(&m_mutex);
+
+ DBUG_RETURN(false);
+}
+
+void Ack_receiver::remove_slave(THD *thd)
+{
+ I_List_iterator<Slave> it(m_slaves);
+ Slave *slave;
+ DBUG_ENTER("Ack_receiver::remove_slave");
+
+ mysql_mutex_lock(&m_mutex);
+
+ while ((slave= it++))
+ {
+ if (slave->thd == thd)
+ {
+ delete slave;
+ m_slaves_changed= true;
+ break;
+ }
+ }
+ mysql_mutex_unlock(&m_mutex);
+
+ DBUG_VOID_RETURN;
+}
+
+inline void Ack_receiver::set_stage_info(const PSI_stage_info &stage)
+{
+ MYSQL_SET_STAGE(stage.m_key, __FILE__, __LINE__);
+}
+
+inline void Ack_receiver::wait_for_slave_connection()
+{
+ set_stage_info(stage_waiting_for_semi_sync_slave);
+ mysql_cond_wait(&m_cond, &m_mutex);
+}
+
+my_socket Ack_receiver::get_slave_sockets(fd_set *fds, uint *count)
+{
+ my_socket max_fd= INVALID_SOCKET;
+ Slave *slave;
+ I_List_iterator<Slave> it(m_slaves);
+
+ *count= 0;
+ FD_ZERO(fds);
+ while ((slave= it++))
+ {
+ (*count)++;
+ my_socket fd= slave->sock_fd();
+ max_fd= (fd > max_fd ? fd : max_fd);
+ FD_SET(fd, fds);
+ }
+
+ return max_fd;
+}
+
+/* Auxilary function to initialize a NET object with given net buffer. */
+static void init_net(NET *net, unsigned char *buff, unsigned int buff_len)
+{
+ memset(net, 0, sizeof(NET));
+ net->max_packet= buff_len;
+ net->buff= buff;
+ net->buff_end= buff + buff_len;
+ net->read_pos= net->buff;
+}
+
+void Ack_receiver::run()
+{
+ // skip LOCK_global_system_variables due to the 3rd arg
+ THD *thd= new THD(next_thread_id(), false, true);
+ NET net;
+ unsigned char net_buff[REPLY_MESSAGE_MAX_LENGTH];
+ fd_set read_fds;
+ my_socket max_fd= INVALID_SOCKET;
+ Slave *slave;
+
+ my_thread_init();
+
+ DBUG_ENTER("Ack_receiver::run");
+
+ sql_print_information("Starting ack receiver thread");
+ thd->system_thread= SYSTEM_THREAD_SEMISYNC_MASTER_BACKGROUND;
+ thd->thread_stack= (char*) &thd;
+ thd->store_globals();
+ thd->security_ctx->skip_grants();
+ thread_safe_increment32(&service_thread_count);
+ thd->set_command(COM_DAEMON);
+ init_net(&net, net_buff, REPLY_MESSAGE_MAX_LENGTH);
+
+ mysql_mutex_lock(&m_mutex);
+ m_slaves_changed= true;
+ mysql_mutex_unlock(&m_mutex);
+
+ while (1)
+ {
+ fd_set fds;
+ int ret;
+ uint slave_count;
+
+ mysql_mutex_lock(&m_mutex);
+ if (unlikely(m_status == ST_STOPPING))
+ goto end;
+
+ set_stage_info(stage_waiting_for_semi_sync_ack_from_slave);
+ if (unlikely(m_slaves_changed))
+ {
+ if (unlikely(m_slaves.is_empty()))
+ {
+ wait_for_slave_connection();
+ mysql_mutex_unlock(&m_mutex);
+ continue;
+ }
+
+ max_fd= get_slave_sockets(&read_fds, &slave_count);
+ m_slaves_changed= false;
+ DBUG_PRINT("info", ("fd count %u, max_fd %d", slave_count,(int) max_fd));
+ }
+
+ struct timeval tv= {1, 0};
+ fds= read_fds;
+ /* select requires max fd + 1 for the first argument */
+ ret= select((int)(max_fd+1), &fds, NULL, NULL, &tv);
+ if (ret <= 0)
+ {
+ mysql_mutex_unlock(&m_mutex);
+
+ ret= DBUG_EVALUATE_IF("rpl_semisync_simulate_select_error", -1, ret);
+
+ if (ret == -1)
+ sql_print_information("Failed to select() on semi-sync dump sockets, "
+ "error: errno=%d", socket_errno);
+ /* Sleep 1us, so other threads can catch the m_mutex easily. */
+ my_sleep(1);
+ continue;
+ }
+
+ set_stage_info(stage_reading_semi_sync_ack);
+ I_List_iterator<Slave> it(m_slaves);
+
+ while ((slave= it++))
+ {
+ if (FD_ISSET(slave->sock_fd(), &fds))
+ {
+ ulong len;
+
+ net_clear(&net, 0);
+ net.vio= &slave->vio;
+
+ len= my_net_read(&net);
+ if (likely(len != packet_error))
+ repl_semisync_master.report_reply_packet(slave->server_id(),
+ net.read_pos, len);
+ else if (net.last_errno == ER_NET_READ_ERROR)
+ FD_CLR(slave->sock_fd(), &read_fds);
+ }
+ }
+ mysql_mutex_unlock(&m_mutex);
+ }
+end:
+ sql_print_information("Stopping ack receiver thread");
+ m_status= ST_DOWN;
+ delete thd;
+ thread_safe_decrement32(&service_thread_count);
+ signal_thd_deleted();
+ mysql_cond_broadcast(&m_cond);
+ mysql_mutex_unlock(&m_mutex);
+ DBUG_VOID_RETURN;
+}
diff --git a/sql/semisync_master_ack_receiver.h b/sql/semisync_master_ack_receiver.h
new file mode 100644
index 00000000000..619748a2159
--- /dev/null
+++ b/sql/semisync_master_ack_receiver.h
@@ -0,0 +1,119 @@
+/* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ 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-1301 USA */
+
+#ifndef SEMISYNC_MASTER_ACK_RECEIVER_DEFINED
+#define SEMISYNC_MASTER_ACK_RECEIVER_DEFINED
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "sql_class.h"
+#include "semisync.h"
+/**
+ Ack_receiver is responsible to control ack receive thread and maintain
+ slave information used by ack receive thread.
+
+ There are mainly four operations on ack receive thread:
+ start: start ack receive thread
+ stop: stop ack receive thread
+ add_slave: maintain a new semisync slave's information
+ remove_slave: remove a semisync slave's information
+ */
+class Ack_receiver : public Repl_semi_sync_base
+{
+public:
+ Ack_receiver();
+ ~Ack_receiver() {}
+ void cleanup();
+ /**
+ Notify ack receiver to receive acks on the dump session.
+
+ It adds the given dump thread into the slave list and wakes
+ up ack thread if it is waiting for any slave coming.
+
+ @param[in] thd THD of a dump thread.
+
+ @return it return false if succeeds, otherwise true is returned.
+ */
+ bool add_slave(THD *thd);
+
+ /**
+ Notify ack receiver not to receive ack on the dump session.
+
+ it removes the given dump thread from slave list.
+
+ @param[in] thd THD of a dump thread.
+ */
+ void remove_slave(THD *thd);
+
+ /**
+ Start ack receive thread
+
+ @return it return false if succeeds, otherwise true is returned.
+ */
+ bool start();
+
+ /**
+ Stop ack receive thread
+ */
+ void stop();
+
+ /**
+ The core of ack receive thread.
+
+ It monitors all slaves' sockets and receives acks when they come.
+ */
+ void run();
+
+ void set_trace_level(unsigned long trace_level)
+ {
+ m_trace_level= trace_level;
+ }
+private:
+ enum status {ST_UP, ST_DOWN, ST_STOPPING};
+ uint8 m_status;
+ /*
+ Protect m_status, m_slaves_changed and m_slaves. ack thread and other
+ session may access the variables at the same time.
+ */
+ mysql_mutex_t m_mutex;
+ mysql_cond_t m_cond;
+ /* If slave list is updated(add or remove). */
+ bool m_slaves_changed;
+
+ class Slave :public ilink
+ {
+public:
+ THD *thd;
+ Vio vio;
+
+ my_socket sock_fd() { return vio.mysql_socket.fd; }
+ uint server_id() { return thd->variables.server_id; }
+ };
+
+ I_List<Slave> m_slaves;
+
+ pthread_t m_pid;
+
+/* Declare them private, so no one can copy the object. */
+ Ack_receiver(const Ack_receiver &ack_receiver);
+ Ack_receiver& operator=(const Ack_receiver &ack_receiver);
+
+ void set_stage_info(const PSI_stage_info &stage);
+ void wait_for_slave_connection();
+ my_socket get_slave_sockets(fd_set *fds, uint *count);
+};
+
+extern Ack_receiver ack_receiver;
+#endif
diff --git a/sql/semisync_slave.cc b/sql/semisync_slave.cc
new file mode 100644
index 00000000000..86d0176dac1
--- /dev/null
+++ b/sql/semisync_slave.cc
@@ -0,0 +1,251 @@
+/* Copyright (c) 2008 MySQL AB, 2009 Sun Microsystems, Inc.
+ Use is subject to license terms.
+
+ This program is free 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-1301 USA */
+
+
+#include <my_global.h>
+#include "semisync_slave.h"
+
+Repl_semi_sync_slave repl_semisync_slave;
+
+my_bool rpl_semi_sync_slave_enabled= 0;
+
+char rpl_semi_sync_slave_delay_master;
+my_bool rpl_semi_sync_slave_status= 0;
+ulong rpl_semi_sync_slave_trace_level;
+
+/*
+ indicate whether or not the slave should send a reply to the master.
+
+ This is set to true in repl_semi_slave_read_event if the current
+ event read is the last event of a transaction. And the value is
+ checked in repl_semi_slave_queue_event.
+*/
+bool semi_sync_need_reply= false;
+unsigned int rpl_semi_sync_slave_kill_conn_timeout;
+unsigned long long rpl_semi_sync_slave_send_ack = 0;
+
+int Repl_semi_sync_slave::init_object()
+{
+ int result= 0;
+
+ m_init_done = true;
+
+ /* References to the parameter works after set_options(). */
+ set_slave_enabled(rpl_semi_sync_slave_enabled);
+ set_trace_level(rpl_semi_sync_slave_trace_level);
+ set_delay_master(rpl_semi_sync_slave_delay_master);
+ set_kill_conn_timeout(rpl_semi_sync_slave_kill_conn_timeout);
+
+ return result;
+}
+
+int Repl_semi_sync_slave::slave_read_sync_header(const char *header,
+ unsigned long total_len,
+ int *semi_flags,
+ const char **payload,
+ unsigned long *payload_len)
+{
+ int read_res = 0;
+ DBUG_ENTER("Repl_semi_sync_slave::slave_read_sync_header");
+
+ if (rpl_semi_sync_slave_status)
+ {
+ if (DBUG_EVALUATE_IF("semislave_corrupt_log", 0, 1)
+ && (unsigned char)(header[0]) == k_packet_magic_num)
+ {
+ semi_sync_need_reply = (header[1] & k_packet_flag_sync);
+ *payload_len = total_len - 2;
+ *payload = header + 2;
+
+ DBUG_PRINT("semisync", ("%s: reply - %d",
+ "Repl_semi_sync_slave::slave_read_sync_header",
+ semi_sync_need_reply));
+
+ if (semi_sync_need_reply)
+ *semi_flags |= SEMI_SYNC_NEED_ACK;
+ if (is_delay_master())
+ *semi_flags |= SEMI_SYNC_SLAVE_DELAY_SYNC;
+ }
+ else
+ {
+ sql_print_error("Missing magic number for semi-sync packet, packet "
+ "len: %lu", total_len);
+ read_res = -1;
+ }
+ } else {
+ *payload= header;
+ *payload_len= total_len;
+ }
+
+ DBUG_RETURN(read_res);
+}
+
+int Repl_semi_sync_slave::slave_start(Master_info *mi)
+{
+ bool semi_sync= get_slave_enabled();
+
+ sql_print_information("Slave I/O thread: Start %s replication to\
+ master '%s@%s:%d' in log '%s' at position %lu",
+ semi_sync ? "semi-sync" : "asynchronous",
+ const_cast<char *>(mi->user), mi->host, mi->port,
+ const_cast<char *>(mi->master_log_name),
+ (unsigned long)(mi->master_log_pos));
+
+ if (semi_sync && !rpl_semi_sync_slave_status)
+ rpl_semi_sync_slave_status= 1;
+
+ /*clear the counter*/
+ rpl_semi_sync_slave_send_ack= 0;
+ return 0;
+}
+
+int Repl_semi_sync_slave::slave_stop(Master_info *mi)
+{
+ if (rpl_semi_sync_slave_status)
+ rpl_semi_sync_slave_status= 0;
+ if (get_slave_enabled())
+ kill_connection(mi->mysql);
+ return 0;
+}
+
+int Repl_semi_sync_slave::reset_slave(Master_info *mi)
+{
+ return 0;
+}
+
+void Repl_semi_sync_slave::kill_connection(MYSQL *mysql)
+{
+ if (!mysql)
+ return;
+
+ char kill_buffer[30];
+ MYSQL *kill_mysql = NULL;
+ kill_mysql = mysql_init(kill_mysql);
+ mysql_options(kill_mysql, MYSQL_OPT_CONNECT_TIMEOUT, &m_kill_conn_timeout);
+ mysql_options(kill_mysql, MYSQL_OPT_READ_TIMEOUT, &m_kill_conn_timeout);
+ mysql_options(kill_mysql, MYSQL_OPT_WRITE_TIMEOUT, &m_kill_conn_timeout);
+
+ bool ret= (!mysql_real_connect(kill_mysql, mysql->host,
+ mysql->user, mysql->passwd,0, mysql->port, mysql->unix_socket, 0));
+ if (DBUG_EVALUATE_IF("semisync_slave_failed_kill", 1, 0) || ret)
+ {
+ sql_print_information("cannot connect to master to kill slave io_thread's "
+ "connection");
+ if (!ret)
+ mysql_close(kill_mysql);
+ return;
+ }
+ size_t kill_buffer_length = my_snprintf(kill_buffer, 30, "KILL %lu",
+ mysql->thread_id);
+ mysql_real_query(kill_mysql, kill_buffer, (ulong)kill_buffer_length);
+ mysql_close(kill_mysql);
+}
+
+int Repl_semi_sync_slave::request_transmit(Master_info *mi)
+{
+ MYSQL *mysql= mi->mysql;
+ MYSQL_RES *res= 0;
+ MYSQL_ROW row;
+ const char *query;
+
+ if (!get_slave_enabled())
+ return 0;
+
+ query= "SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'";
+ if (mysql_real_query(mysql, query, (ulong)strlen(query)) ||
+ !(res= mysql_store_result(mysql)))
+ {
+ sql_print_error("Execution failed on master: %s, error :%s", query, mysql_error(mysql));
+ return 1;
+ }
+
+ row= mysql_fetch_row(res);
+ if (DBUG_EVALUATE_IF("master_not_support_semisync", 1, 0)
+ || !row)
+ {
+ /* Master does not support semi-sync */
+ sql_print_warning("Master server does not support semi-sync, "
+ "fallback to asynchronous replication");
+ rpl_semi_sync_slave_status= 0;
+ mysql_free_result(res);
+ return 0;
+ }
+ mysql_free_result(res);
+
+ /*
+ Tell master dump thread that we want to do semi-sync
+ replication
+ */
+ query= "SET @rpl_semi_sync_slave= 1";
+ if (mysql_real_query(mysql, query, (ulong)strlen(query)))
+ {
+ sql_print_error("Set 'rpl_semi_sync_slave=1' on master failed");
+ return 1;
+ }
+ mysql_free_result(mysql_store_result(mysql));
+ rpl_semi_sync_slave_status= 1;
+
+ return 0;
+}
+
+int Repl_semi_sync_slave::slave_reply(Master_info *mi)
+{
+ MYSQL* mysql= mi->mysql;
+ const char *binlog_filename= const_cast<char *>(mi->master_log_name);
+ my_off_t binlog_filepos= mi->master_log_pos;
+
+ NET *net= &mysql->net;
+ uchar reply_buffer[REPLY_MAGIC_NUM_LEN
+ + REPLY_BINLOG_POS_LEN
+ + REPLY_BINLOG_NAME_LEN];
+ int reply_res = 0;
+ size_t name_len = strlen(binlog_filename);
+
+ DBUG_ENTER("Repl_semi_sync_slave::slave_reply");
+
+ if (rpl_semi_sync_slave_status && semi_sync_need_reply)
+ {
+ /* Prepare the buffer of the reply. */
+ reply_buffer[REPLY_MAGIC_NUM_OFFSET] = k_packet_magic_num;
+ int8store(reply_buffer + REPLY_BINLOG_POS_OFFSET, binlog_filepos);
+ memcpy(reply_buffer + REPLY_BINLOG_NAME_OFFSET,
+ binlog_filename,
+ name_len + 1 /* including trailing '\0' */);
+
+ DBUG_PRINT("semisync", ("%s: reply (%s, %lu)",
+ "Repl_semi_sync_slave::slave_reply",
+ binlog_filename, (ulong)binlog_filepos));
+
+ net_clear(net, 0);
+ /* Send the reply. */
+ reply_res = my_net_write(net, reply_buffer,
+ name_len + REPLY_BINLOG_NAME_OFFSET);
+ if (!reply_res)
+ {
+ reply_res = DBUG_EVALUATE_IF("semislave_failed_net_flush", 1, net_flush(net));
+ if (reply_res)
+ sql_print_error("Semi-sync slave net_flush() reply failed");
+ rpl_semi_sync_slave_send_ack++;
+ }
+ else
+ {
+ sql_print_error("Semi-sync slave send reply failed: %s (%d)",
+ net->last_error, net->last_errno);
+ }
+ }
+
+ DBUG_RETURN(reply_res);
+}
diff --git a/sql/semisync_slave.h b/sql/semisync_slave.h
new file mode 100644
index 00000000000..d65262f151d
--- /dev/null
+++ b/sql/semisync_slave.h
@@ -0,0 +1,115 @@
+/* Copyright (c) 2006 MySQL AB, 2009 Sun Microsystems, Inc.
+ Use is subject to license terms.
+
+ This program is free 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-1301 USA */
+
+
+#ifndef SEMISYNC_SLAVE_H
+#define SEMISYNC_SLAVE_H
+
+#include "semisync.h"
+#include "my_global.h"
+#include "sql_priv.h"
+#include "rpl_mi.h"
+#include "mysql.h"
+
+class Master_info;
+
+/**
+ The extension class for the slave of semi-synchronous replication
+*/
+class Repl_semi_sync_slave
+ :public Repl_semi_sync_base {
+public:
+ Repl_semi_sync_slave() :m_slave_enabled(false) {}
+ ~Repl_semi_sync_slave() {}
+
+ void set_trace_level(unsigned long trace_level) {
+ m_trace_level = trace_level;
+ }
+
+ /* Initialize this class after MySQL parameters are initialized. this
+ * function should be called once at bootstrap time.
+ */
+ int init_object();
+
+ bool get_slave_enabled() {
+ return m_slave_enabled;
+ }
+
+ void set_slave_enabled(bool enabled) {
+ m_slave_enabled = enabled;
+ }
+
+ bool is_delay_master(){
+ return m_delay_master;
+ }
+
+ void set_delay_master(bool enabled) {
+ m_delay_master = enabled;
+ }
+
+ void set_kill_conn_timeout(unsigned int timeout) {
+ m_kill_conn_timeout = timeout;
+ }
+
+ /* A slave reads the semi-sync packet header and separate the metadata
+ * from the payload data.
+ *
+ * Input:
+ * header - (IN) packet header pointer
+ * total_len - (IN) total packet length: metadata + payload
+ * semi_flags - (IN) store flags: SEMI_SYNC_SLAVE_DELAY_SYNC and
+ SEMI_SYNC_NEED_ACK
+ * payload - (IN) payload: the replication event
+ * payload_len - (IN) payload length
+ *
+ * Return:
+ * 0: success; non-zero: error
+ */
+ int slave_read_sync_header(const char *header, unsigned long total_len,
+ int *semi_flags,
+ const char **payload, unsigned long *payload_len);
+
+ /* A slave replies to the master indicating its replication process. It
+ * indicates that the slave has received all events before the specified
+ * binlog position.
+ */
+ int slave_reply(Master_info* mi);
+ int slave_start(Master_info *mi);
+ int slave_stop(Master_info *mi);
+ int request_transmit(Master_info*);
+ void kill_connection(MYSQL *mysql);
+ int reset_slave(Master_info *mi);
+
+private:
+ /* True when init_object has been called */
+ bool m_init_done;
+ bool m_slave_enabled; /* semi-sycn is enabled on the slave */
+ bool m_delay_master;
+ unsigned int m_kill_conn_timeout;
+};
+
+
+/* System and status variables for the slave component */
+extern my_bool rpl_semi_sync_slave_enabled;
+extern my_bool rpl_semi_sync_slave_status;
+extern ulong rpl_semi_sync_slave_trace_level;
+extern Repl_semi_sync_slave repl_semisync_slave;
+
+extern char rpl_semi_sync_slave_delay_master;
+extern unsigned int rpl_semi_sync_slave_kill_conn_timeout;
+extern unsigned long long rpl_semi_sync_slave_send_ack;
+
+#endif /* SEMISYNC_SLAVE_H */
diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc
index ff9780a9531..b59475645fa 100644
--- a/sql/session_tracker.cc
+++ b/sql/session_tracker.cc
@@ -419,7 +419,6 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
{
sys_var *svar;
LEX_CSTRING var;
- uint not_used;
lasts= (char *) memchr(token, separator, rest);
@@ -433,7 +432,7 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
var.length= rest;
/* Remove leading/trailing whitespace. */
- trim_whitespace(char_set, &var, &not_used);
+ trim_whitespace(char_set, &var);
if(!strcmp(var.str, "*"))
{
@@ -501,7 +500,6 @@ bool Session_sysvars_tracker::check_var_list(THD *thd,
for (;;)
{
LEX_CSTRING var;
- uint not_used;
lasts= (char *) memchr(token, separator, rest);
@@ -515,7 +513,7 @@ bool Session_sysvars_tracker::check_var_list(THD *thd,
var.length= rest;
/* Remove leading/trailing whitespace. */
- trim_whitespace(char_set, &var, &not_used);
+ trim_whitespace(char_set, &var);
if(!strcmp(var.str, "*") &&
!find_sys_var_ex(thd, var.str, var.length, throw_error, true))
@@ -974,7 +972,7 @@ bool Current_schema_tracker::store(THD *thd, String *buf)
It saves length of database name and name of database name +
length of saved length of database length.
*/
- length= db_length= thd->db_length;
+ length= db_length= thd->db.length;
length += net_length_size(length);
compile_time_assert(SESSION_TRACK_SCHEMA < 251);
@@ -991,7 +989,7 @@ bool Current_schema_tracker::store(THD *thd, String *buf)
buf->q_net_store_length(length);
/* Length and current schema name */
- buf->q_net_store_data((const uchar *)thd->db, thd->db_length);
+ buf->q_net_store_data((const uchar *)thd->db.str, thd->db.length);
reset();
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 311b33bc0dd..1bdbd4e1f6e 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -324,14 +324,14 @@ do { \
sval.length= sval.str ? strlen(sval.str) : 0; \
break; \
case SHOW_LEX_STRING: \
- sval= *(LEX_STRING *) value; \
+ sval= *(LEX_CSTRING *) value; \
break
longlong sys_var::val_int(bool *is_null,
THD *thd, enum_var_type type,
const LEX_CSTRING *base)
{
- LEX_STRING sval;
+ LEX_CSTRING sval;
AutoWLock lock(&PLock_global_system_variables);
const uchar *value= value_ptr(thd, type, base);
*is_null= false;
@@ -357,13 +357,13 @@ longlong sys_var::val_int(bool *is_null,
String *sys_var::val_str_nolock(String *str, THD *thd, const uchar *value)
{
- static LEX_STRING bools[]=
+ static LEX_CSTRING bools[]=
{
- { C_STRING_WITH_LEN("OFF") },
- { C_STRING_WITH_LEN("ON") }
+ { STRING_WITH_LEN("OFF") },
+ { STRING_WITH_LEN("ON") }
};
- LEX_STRING sval;
+ LEX_CSTRING sval;
switch (show_type())
{
case_get_string_as_lex_string;
@@ -395,7 +395,7 @@ String *sys_var::val_str(String *str,
double sys_var::val_real(bool *is_null,
THD *thd, enum_var_type type, const LEX_CSTRING *base)
{
- LEX_STRING sval;
+ LEX_CSTRING sval;
AutoWLock lock(&PLock_global_system_variables);
const uchar *value= value_ptr(thd, type, base);
*is_null= false;
@@ -597,10 +597,10 @@ int mysql_del_sys_var_chain(sys_var *first)
{
int result= 0;
- mysql_rwlock_wrlock(&LOCK_system_variables_hash);
+ mysql_prlock_wrlock(&LOCK_system_variables_hash);
for (sys_var *var= first; var; var= var->next)
result|= my_hash_delete(&system_variable_hash, (uchar*) var);
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
return result;
}
@@ -673,7 +673,7 @@ SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted, enum enum_var_type scope)
0 Unknown variable (error message is given)
*/
-sys_var *intern_find_sys_var(const char *str, uint length)
+sys_var *intern_find_sys_var(const char *str, size_t length)
{
sys_var *var;
@@ -853,7 +853,7 @@ set_var::set_var(THD *thd, enum_var_type type_arg, sys_var *var_arg,
// names are utf8
if (!(value= new (thd->mem_root) Item_string_sys(thd,
item->field_name.str,
- item->field_name.length)))
+ (uint)item->field_name.length)))
value=value_arg; /* Give error message later */
}
else
@@ -1082,7 +1082,7 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond)
cond= make_cond_for_info_schema(thd, cond, tables);
thd->count_cuted_fields= CHECK_FIELD_WARN;
- mysql_rwlock_rdlock(&LOCK_system_variables_hash);
+ mysql_prlock_rdlock(&LOCK_system_variables_hash);
for (uint i= 0; i < system_variable_hash.records; i++)
{
@@ -1245,7 +1245,7 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond)
}
res= 0;
end:
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
thd->count_cuted_fields= save_count_cuted_fields;
return res;
}
@@ -1323,7 +1323,7 @@ resolve_engine_list_item(THD *thd, plugin_ref *list, uint32 *idx,
{
LEX_CSTRING item_str;
plugin_ref ref;
- uint32_t i;
+ uint32 i;
THD *thd_or_null = (temp_copy ? thd : NULL);
item_str.str= pos;
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index e7afe7a679a..3e9e94bbbfd 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -952,10 +952,10 @@ ER_OUT_OF_RESOURCES
cze "Málo prostoru/paměti pro thread"
dan "Udgået for tråde/hukommelse"
nla "Geen thread geheugen meer; controleer of mysqld of andere processen al het beschikbare geheugen gebruikt. Zo niet, dan moet u wellicht 'ulimit' gebruiken om mysqld toe te laten meer geheugen te benutten, of u kunt extra swap ruimte toevoegen"
- eng "Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space"
+ eng "Out of memory."
est "Mälu sai otsa. Võimalik, et aitab swap-i lisamine või käsu 'ulimit' abil MariaDB-le rohkema mälu kasutamise lubamine"
fre "Manque de 'threads'/mémoire"
- ger "Kein Speicher mehr vorhanden. Prüfen Sie, ob mysqld oder ein anderer Prozess den gesamten Speicher verbraucht. Wenn nicht, sollten Sie mit 'ulimit' dafür sorgen, dass mysqld mehr Speicher benutzen darf, oder mehr Swap-Speicher einrichten"
+ ger "Kein Speicher mehr vorhanden."
greek "ΠÏόβλημα με τη διαθέσιμη μνήμη (Out of thread space/memory)"
hun "Elfogyott a thread-memoria"
ita "Fine dello spazio/memoria per i thread"
@@ -964,14 +964,14 @@ ER_OUT_OF_RESOURCES
nor "Tomt for tråd plass/minne"
norwegian-ny "Tomt for tråd plass/minne"
pol "Zbyt mało miejsca/pamięci dla w?tku"
- por "Sem memória. Verifique se o mysqld ou algum outro processo está usando toda memória disponível. Se não, você pode ter que usar 'ulimit' para permitir ao mysqld usar mais memória ou você pode adicionar mais área de 'swap'"
- rum "Out of memory; Verifica daca mysqld sau vreun alt proces foloseste toate memoria disponbila. Altfel, trebuie sa folosesi 'ulimit' ca sa permiti lui memoria disponbila. Altfel, trebuie sa folosesi 'ulimit' ca sa permiti lui mysqld sa foloseasca mai multa memorie ori adauga mai mult spatiu pentru swap (swap space)"
- rus "ÐедоÑтаточно памÑти; удоÑтоверьтеÑÑŒ, что mysqld или какой-либо другой процеÑÑ Ð½Ðµ занимает вÑÑŽ доÑтупную памÑÑ‚ÑŒ. ЕÑли нет, то вы можете иÑпользовать ulimit, чтобы выделить Ð´Ð»Ñ mysqld больше памÑти, или увеличить объем файла подкачки"
- serbian "Nema memorije; Proverite da li MariaDB server ili neki drugi proces koristi svu slobodnu memoriju. (UNIX: Ako ne, probajte da upotrebite 'ulimit' komandu da biste dozvolili daemon-u da koristi više memorije ili probajte da dodate više swap memorije)"
+ por "Sem memória."
+ rum "Out of memory."
+ rus "ÐедоÑтаточно памÑти."
+ serbian "Nema memorije."
slo "Málo miesta-pamäti pre vlákno"
spa "Memoria/espacio de tranpaso insuficiente"
- swe "Fick slut på minnet. Kontrollera om mysqld eller någon annan process använder allt tillgängligt minne. Om inte, försök använda 'ulimit' eller allokera mera swap"
- ukr "Брак пам'ÑÑ‚Ñ–; Перевірте чи mysqld або ÑкіÑÑŒ інші процеÑи викориÑтовують уÑÑŽ доÑтупну пам'ÑÑ‚ÑŒ. Як ні, то ви можете ÑкориÑтатиÑÑ 'ulimit', аби дозволити mysqld викориÑтовувати більше пам'ÑÑ‚Ñ– або ви можете додати більше міÑÑ†Ñ Ð¿Ñ–Ð´ Ñвап"
+ swe "Fick slut på minnet."
+ ukr "Брак пам'ÑÑ‚Ñ–."
ER_BAD_HOST_ERROR 08S01
cze "Nemohu zjistit jméno stroje pro Vaši adresu"
dan "Kan ikke få værtsnavn for din adresse"
@@ -1801,33 +1801,33 @@ ER_WRONG_AUTO_KEY 42000 S1009
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 "Ðевірне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ–; Може бути лише один автоматичний Ñтовбець, що повинен бути визначений Ñк ключ"
-ER_UNUSED_9
- eng "You should never see it"
+ER_BINLOG_CANT_DELETE_GTID_DOMAIN
+ eng "Could not delete gtid domain. Reason: %s."
ER_NORMAL_SHUTDOWN
- cze "%s (%s): normální ukonÄení\n"
- dan "%s (%s): Normal nedlukning\n"
- nla "%s (%s): Normaal afgesloten \n"
- eng "%s (%s): Normal shutdown\n"
- est "%s (%s): MariaDB lõpetas\n"
- fre "%s (%s): Arrêt normal du serveur\n"
- ger "%s (%s): Normal heruntergefahren\n"
- greek "%s (%s): Φυσιολογική διαδικασία shutdown\n"
- hindi "%s (%s): सामानà¥à¤¯ शटडाउन\n"
- hun "%s (%s): Normal leallitas\n"
- ita "%s (%s): Shutdown normale\n"
- jpn "%s (%s): 通常シャットダウン\n"
- kor "%s (%s): ì •ìƒì ì¸ shutdown\n"
- nor "%s (%s): Normal avslutning\n"
- norwegian-ny "%s (%s): Normal nedkopling\n"
- pol "%s (%s): Standardowe zakończenie działania\n"
- por "%s (%s): 'Shutdown' normal\n"
- rum "%s (%s): Terminare normala\n"
- rus "%s (%s): ÐšÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð¾Ñтановка\n"
- serbian "%s (%s): Normalno gašenje\n"
- slo "%s (%s): normálne ukonÄenie\n"
- spa "%s (%s): Apagado normal\n"
- swe "%s (%s): Normal avslutning\n"
- ukr "%s (%s): Ðормальне завершеннÑ\n"
+ cze "%s (%s): normální ukonÄení"
+ dan "%s (%s): Normal nedlukning"
+ nla "%s (%s): Normaal afgesloten "
+ eng "%s (%s): Normal shutdown"
+ est "%s (%s): MariaDB lõpetas"
+ fre "%s (%s): Arrêt normal du serveur"
+ ger "%s (%s): Normal heruntergefahren"
+ greek "%s (%s): Φυσιολογική διαδικασία shutdown"
+ hindi "%s (%s): सामानà¥à¤¯ शटडाउन"
+ hun "%s (%s): Normal leallitas"
+ ita "%s (%s): Shutdown normale"
+ jpn "%s (%s): 通常シャットダウン"
+ kor "%s (%s): ì •ìƒì ì¸ shutdown"
+ nor "%s (%s): Normal avslutning"
+ norwegian-ny "%s (%s): Normal nedkopling"
+ pol "%s (%s): Standardowe zakończenie działania"
+ por "%s (%s): 'Shutdown' normal"
+ rum "%s (%s): Terminare normala"
+ rus "%s (%s): ÐšÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð¾Ñтановка"
+ serbian "%s (%s): Normalno gašenje"
+ slo "%s (%s): normálne ukonÄenie"
+ spa "%s (%s): Apagado normal"
+ swe "%s (%s): Normal avslutning"
+ ukr "%s (%s): Ðормальне завершеннÑ"
ER_GOT_SIGNAL
cze "%s: pÅ™ijat signal %d, konÄím\n"
dan "%s: Fangede signal %d. Afslutter!!\n"
@@ -4528,18 +4528,18 @@ ER_TABLE_CANT_HANDLE_FT
spa "El tipo de tabla usada (%s) no soporta índices FULLTEXT"
swe "Tabelltypen (%s) har inte hantering av FULLTEXT-index"
ukr "ВикориÑтаний тип таблиці (%s) не підтримує FULLTEXT індекÑів"
-ER_CANNOT_ADD_FOREIGN
- nla "Kan foreign key beperking niet toevoegen"
- eng "Cannot add foreign key constraint"
- fre "Impossible d'ajouter des contraintes d'index externe"
- ger "Fremdschlüssel-Beschränkung kann nicht hinzugefügt werden"
- ita "Impossibile aggiungere il vincolo di integrita' referenziale (foreign key constraint)"
- jpn "外部キー制約を追加ã§ãã¾ã›ã‚“。"
- por "Não pode acrescentar uma restrição de chave estrangeira"
- rus "Ðевозможно добавить Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ ключа"
- serbian "Ne mogu da dodam proveru spoljnog kljuÄa"
- spa "No puede adicionar clave extranjera constraint"
- swe "Kan inte lägga till 'FOREIGN KEY constraint'"
+ER_CANNOT_ADD_FOREIGN
+ nla "Kan foreign key beperking niet toevoegen vor `%s`"
+ eng "Cannot add foreign key constraint for `%s`"
+ fre "Impossible d'ajouter des contraintes d'index externe à `%s`"
+ ger "Fremdschlüssel-Beschränkung kann nicht hinzugefügt werden für `%s`"
+ ita "Impossibile aggiungere il vincolo di integrita' referenziale (foreign key constraint) a `%s`"
+ jpn "`%s` 外部キー制約を追加ã§ãã¾ã›ã‚“。"
+ por "Não pode acrescentar uma restrição de chave estrangeira para `%s`"
+ rus "Ðевозможно добавить Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ ключа Ð´Ð»Ñ `%s`"
+ 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`'"
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"
@@ -5752,8 +5752,8 @@ ER_MAX_PREPARED_STMT_COUNT_REACHED 42000
eng "Can't create more than max_prepared_stmt_count statements (current value: %lu)"
ger "Kann nicht mehr Anweisungen als max_prepared_stmt_count erzeugen (aktueller Wert: %lu)"
ER_VIEW_RECURSIVE
- eng "`%-.192s`.`%-.192s` contains view recursion"
- ger "`%-.192s`.`%-.192s` enthält View-Rekursion"
+ eng "%`s.%`s contains view recursion"
+ ger "%`s.%`s enthält View-Rekursion"
ER_NON_GROUPING_FIELD_USED 42000
eng "Non-grouping field '%-.192s' is used in %-.64s clause"
ger "In der %-.192s-Klausel wird das die Nicht-Gruppierungsspalte '%-.64s' verwendet"
@@ -6249,37 +6249,37 @@ ER_BINLOG_LOGGING_IMPOSSIBLE
eng "Binary logging not possible. Message: %s"
ger "Binärlogging nicht möglich. Meldung: %s"
ER_VIEW_NO_CREATION_CTX
- eng "View `%-.64s`.`%-.64s` has no creation context"
- ger "View `%-.64s`.`%-.64s` hat keinen Erzeugungskontext"
+ eng "View %`s.%`s has no creation context"
+ ger "View %`s.%`s hat keinen Erzeugungskontext"
ER_VIEW_INVALID_CREATION_CTX
- eng "Creation context of view `%-.64s`.`%-.64s' is invalid"
- ger "Erzeugungskontext des Views`%-.64s`.`%-.64s' ist ungültig"
+ eng "Creation context of view %`s.%`s is invalid"
+ ger "Erzeugungskontext des Views%`s.%`s ist ungültig"
ER_SR_INVALID_CREATION_CTX
- eng "Creation context of stored routine `%-.64s`.`%-.64s` is invalid"
- ger "Erzeugungskontext der gespeicherten Routine`%-.64s`.`%-.64s` ist ungültig"
+ eng "Creation context of stored routine %`s.%`s is invalid"
+ ger "Erzeugungskontext der gespeicherten Routine%`s.%`s ist ungültig"
ER_TRG_CORRUPTED_FILE
- eng "Corrupted TRG file for table `%-.64s`.`%-.64s`"
- ger "Beschädigte TRG-Datei für Tabelle `%-.64s`.`%-.64s`"
+ eng "Corrupted TRG file for table %`s.%`s"
+ ger "Beschädigte TRG-Datei für Tabelle %`s.%`s"
ER_TRG_NO_CREATION_CTX
- eng "Triggers for table `%-.64s`.`%-.64s` have no creation context"
- ger "Trigger für Tabelle `%-.64s`.`%-.64s` haben keinen Erzeugungskontext"
+ eng "Triggers for table %`s.%`s have no creation context"
+ ger "Trigger für Tabelle %`s.%`s haben keinen Erzeugungskontext"
ER_TRG_INVALID_CREATION_CTX
- eng "Trigger creation context of table `%-.64s`.`%-.64s` is invalid"
- ger "Trigger-Erzeugungskontext der Tabelle `%-.64s`.`%-.64s` ist ungültig"
+ eng "Trigger creation context of table %`s.%`s is invalid"
+ ger "Trigger-Erzeugungskontext der Tabelle %`s.%`s ist ungültig"
ER_EVENT_INVALID_CREATION_CTX
- eng "Creation context of event `%-.64s`.`%-.64s` is invalid"
- ger "Erzeugungskontext des Events `%-.64s`.`%-.64s` ist ungültig"
+ eng "Creation context of event %`s.%`s is invalid"
+ ger "Erzeugungskontext des Events %`s.%`s ist ungültig"
ER_TRG_CANT_OPEN_TABLE
- eng "Cannot open table for trigger `%-.64s`.`%-.64s`"
- ger "Kann Tabelle für den Trigger `%-.64s`.`%-.64s` nicht öffnen"
+ eng "Cannot open table for trigger %`s.%`s"
+ ger "Kann Tabelle für den Trigger %`s.%`s nicht öffnen"
ER_CANT_CREATE_SROUTINE
- eng "Cannot create stored routine `%-.64s`. Check warnings"
- ger "Kann gespeicherte Routine `%-.64s` nicht erzeugen. Beachten Sie die Warnungen"
+ eng "Cannot create stored routine %`s. Check warnings"
+ ger "Kann gespeicherte Routine %`s nicht erzeugen. Beachten Sie die Warnungen"
ER_UNUSED_11
eng "You should never see it"
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT
- eng "The BINLOG statement of type `%s` was not preceded by a format description BINLOG statement"
- ger "Der BINLOG-Anweisung vom Typ `%s` ging keine BINLOG-Anweisung zur Formatbeschreibung voran"
+ eng "The BINLOG statement of type %s was not preceded by a format description BINLOG statement"
+ ger "Der BINLOG-Anweisung vom Typ %s ging keine BINLOG-Anweisung zur Formatbeschreibung voran"
ER_SLAVE_CORRUPT_EVENT
eng "Corrupted replication event was detected"
ger "Beschädigtes Replikationsereignis entdeckt"
@@ -6596,7 +6596,7 @@ ER_MULTI_UPDATE_KEY_CONFLICT
# When translating this error message make sure to include "ALTER TABLE" in the
# message as mysqlcheck parses the error message looking for ALTER TABLE.
ER_TABLE_NEEDS_REBUILD
- eng "Table rebuild required. Please do \"ALTER TABLE `%-.32s` FORCE\" or dump/reload to fix it!"
+ eng "Table rebuild required. Please do \"ALTER TABLE %`s FORCE\" or dump/reload to fix it!"
WARN_OPTION_BELOW_LIMIT
eng "The value of '%s' should be no less than the value of '%s'"
@@ -6850,8 +6850,8 @@ ER_CANT_SET_GTID_NEXT_WHEN_OWNING_GTID
eng "GTID_NEXT cannot be changed by a client that owns a GTID. The client owns %s. Ownership is released on COMMIT or ROLLBACK"
ER_UNKNOWN_EXPLAIN_FORMAT
- eng "Unknown EXPLAIN format name: '%s'"
- rus "ÐеизвеÑтное Ð¸Ð¼Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° команды EXPLAIN: '%s'"
+ eng "Unknown %s format name: '%s'"
+ rus "ÐеизвеÑтное Ð¸Ð¼Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° команды %s: '%s'"
ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION 25006
eng "Cannot execute statement in a READ ONLY transaction"
@@ -6899,8 +6899,8 @@ ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2
ER_SLAVE_SILENT_RETRY_TRANSACTION
eng "Slave must silently retry current transaction"
-ER_DISCARD_FK_CHECKS_RUNNING
- eng "There is a foreign key check running on table '%-.192s'. Cannot discard the table"
+ER_UNUSED_22
+ eng "You should never see it"
ER_TABLE_SCHEMA_MISMATCH
eng "Schema mismatch (%s)"
@@ -7330,7 +7330,7 @@ ER_SUBQUERIES_NOT_SUPPORTED 42000
eng "%s does not support subqueries or stored functions"
ER_SET_STATEMENT_NOT_SUPPORTED 42000
eng "The system variable %.200s cannot be set in SET STATEMENT."
-ER_UNUSED_17
+ER_UNUSED_9
eng "You should never see it"
ER_USER_CREATE_EXISTS
eng "Can't create user '%-.64s'@'%-.64s'; it already exists"
@@ -7747,6 +7747,12 @@ ER_SUM_FUNC_WITH_WINDOW_FUNC_AS_ARG
ER_NET_OK_PACKET_TOO_LARGE
eng "OK packet too large"
+ER_GEOJSON_EMPTY_COORDINATES
+ eng "Incorrect GeoJSON format - empty 'coordinates' array."
+
+ER_MYROCKS_CANT_NOPAD_COLLATION
+ eng "MyRocks doesn't currently support collations with \"No pad\" attribute."
+
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
eng "Illegal parameter data types %s and %s for operation '%s'"
ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
@@ -7790,8 +7796,6 @@ ER_WRONG_NUMBER_OF_VALUES_IN_TVC
eng "The used table value constructor has a different number of values"
ER_FIELD_REFERENCE_IN_TVC
eng "Field reference '%-.192s' can't be used in table value constructor"
-ER_NOT_SINGLE_ELEMENT_ORDER_LIST
- eng "Incorrect number of elements in the order list for '%s'"
ER_WRONG_TYPE_FOR_PERCENTILE_FUNC
eng "Numeric datatype is required for %s function"
ER_ARGUMENT_NOT_CONSTANT
@@ -7800,3 +7804,108 @@ ER_ARGUMENT_OUT_OF_RANGE
eng "Argument to the %s function does not belong to the range [0,1]"
ER_WRONG_TYPE_OF_ARGUMENT
eng "%s function only accepts arguments that can be converted to numerical types"
+ER_NOT_AGGREGATE_FUNCTION
+ eng "Non-aggregate function contains aggregate specific instructions: (FETCH GROUP NEXT ROW)"
+ER_INVALID_AGGREGATE_FUNCTION
+ eng "Aggregate specific instruction(FETCH GROUP NEXT ROW) missing from the aggregate function"
+ER_INVALID_VALUE_TO_LIMIT
+ eng "Limit only accepts integer values"
+ER_INVISIBLE_NOT_NULL_WITHOUT_DEFAULT
+ eng "Invisible column %`s must have a default value"
+
+
+# MariaDB error numbers related to System Versioning
+
+ER_UPDATE_INFO_WITH_SYSTEM_VERSIONING
+ eng "Rows matched: %ld Changed: %ld Inserted: %ld Warnings: %ld"
+
+ER_VERS_FIELD_WRONG_TYPE
+ eng "%`s must be of type %s for system-versioned table %`s"
+
+ER_VERS_ENGINE_UNSUPPORTED
+ eng "Transaction system versioning for %`s is not supported"
+
+ER_UNUSED_23
+ eng "You should never see it"
+
+ER_PARTITION_WRONG_TYPE
+ eng "Wrong partitioning type, expected type: %`s"
+
+WARN_VERS_PART_FULL
+ eng "Versioned table %`s.%`s: partition %`s is full, add more HISTORY partitions"
+
+WARN_VERS_PARAMETERS
+ eng "Maybe missing parameters: %s"
+
+ER_VERS_DROP_PARTITION_INTERVAL
+ eng "Can only drop oldest partitions when rotating by INTERVAL"
+
+WARN_VERS_TRX_MISSING
+ eng "VTQ missing transaction ID %lu"
+
+WARN_VERS_PART_NON_HISTORICAL
+ eng "Partition %`s contains non-historical data"
+
+ER_VERS_ALTER_NOT_ALLOWED
+ eng "Not allowed for system-versioned %`s.%`s. Change @@system_versioning_alter_history to proceed with ALTER."
+
+ER_VERS_ALTER_ENGINE_PROHIBITED
+ eng "Not allowed for system-versioned %`s.%`s. Change to/from native system versioning engine is prohibited."
+
+ER_VERS_RANGE_PROHIBITED
+ eng "SYSTEM_TIME range selector is prohibited"
+
+ER_VERS_VTMD_ERROR
+ eng "VTMD error: %s"
+
+ER_VERS_TABLE_MUST_HAVE_COLUMNS
+ eng "Table %`s must have at least one versioned column"
+
+ER_VERS_NOT_VERSIONED
+ eng "Table %`s is not system-versioned"
+
+ER_MISSING
+ eng "Wrong parameters for %`s: missing '%s'"
+
+ER_VERS_PERIOD_COLUMNS
+ eng "PERIOD FOR SYSTEM_TIME must use columns %`s and %`s"
+
+ER_PART_WRONG_VALUE
+ eng "Wrong parameters for partitioned %`s: wrong value for '%s'"
+
+ER_VERS_WRONG_PARTS
+ eng "Wrong partitions for %`s: must have at least one HISTORY and exactly one last CURRENT"
+
+ER_VERS_NO_TRX_ID
+ eng "TRX_ID %llu not found in `mysql.transaction_registry`"
+
+ER_VERS_ALTER_SYSTEM_FIELD
+ eng "Can not change system versioning field %`s"
+
+ER_DROP_VERSIONING_SYSTEM_TIME_PARTITION
+ eng "Can not DROP SYSTEM VERSIONING for table %`s partitioned BY SYSTEM_TIME"
+
+ER_NOT_LOG_TABLE
+ eng "Table %`s.%`s is not a log table"
+
+ER_VERS_TRT_IS_DISABLED
+ eng "Transaction registry is disabled"
+
+ER_VERS_DUPLICATE_ROW_START_END
+ eng "Duplicate ROW %s column %`s"
+
+ER_VERS_ALREADY_VERSIONED
+ eng "Table %`s is already system-versioned"
+
+ER_UNUSED_24
+ eng "You should never see it"
+
+ER_VERS_TEMPORARY
+ eng "System versioning prohibited for TEMPORARY tables"
+
+ER_VERS_NOT_SUPPORTED
+ eng "%s is not supported for %s system-versioned tables"
+ER_INDEX_FILE_FULL
+ eng "The index file for table '%-.192s' is full"
+ER_UPDATED_COLUMN_ONLY_ONCE
+ eng "The column %`s.%`s cannot be changed more than once in a single UPDATE statement"
diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc
index c99ad088e9f..cdda49c5796 100644
--- a/sql/signal_handler.cc
+++ b/sql/signal_handler.cc
@@ -88,7 +88,7 @@ extern "C" sig_handler handle_fatal_signal(int sig)
tm.tm_hour, tm.tm_min, tm.tm_sec);
if (opt_expect_abort
#ifdef _WIN32
- && sig == EXCEPTION_BREAKPOINT /* __debugbreak in my_sigabrt_hander() */
+ && sig == (int)EXCEPTION_BREAKPOINT /* __debugbreak in my_sigabrt_hander() */
#else
&& sig == SIGABRT
#endif
@@ -298,7 +298,9 @@ extern "C" sig_handler handle_fatal_signal(int sig)
#ifdef HAVE_WRITE_CORE
if (test_flags & TEST_CORE_ON_SIGNAL)
{
- my_safe_printf_stderr("%s", "Writing a core file\n");
+ char buff[80];
+ my_getwd(buff, sizeof(buff), 0);
+ my_safe_printf_stderr("Writing a core file at %s\n", buff);
fflush(stderr);
my_write_core(sig);
}
diff --git a/sql/slave.cc b/sql/slave.cc
index 94e35bec4f8..bf70db66f35 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -41,9 +41,8 @@
#include <sql_common.h>
#include <errmsg.h>
#include <ssl_compat.h>
-#include <mysqld_error.h>
+#include "unireg.h"
#include <mysys_err.h>
-#include "rpl_handler.h"
#include <signal.h>
#include <mysql.h>
#include <myisam.h>
@@ -61,6 +60,7 @@
#include "debug_sync.h"
#include "rpl_parallel.h"
#include "sql_show.h"
+#include "semisync_slave.h"
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
@@ -72,6 +72,9 @@
bool use_slave_mask = 0;
MY_BITMAP slave_error_mask;
char slave_skip_error_names[SHOW_VAR_FUNC_BUFF_SIZE];
+uint *slave_transaction_retry_errors;
+uint slave_transaction_retry_error_length= 0;
+char slave_transaction_retry_error_names[SHOW_VAR_FUNC_BUFF_SIZE];
char* slave_load_tmpdir = 0;
Master_info *active_mi= 0;
@@ -156,7 +159,8 @@ static bool wait_for_relay_log_space(Relay_log_info* rli);
static bool io_slave_killed(Master_info* mi);
static bool sql_slave_killed(rpl_group_info *rgi);
static int init_slave_thread(THD*, Master_info *, SLAVE_THD_TYPE);
-static void print_slave_skip_errors(void);
+static void make_slave_skip_errors_printable(void);
+static void make_slave_transaction_retry_errors_printable(void);
static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi);
static int safe_reconnect(THD*, MYSQL*, Master_info*, bool);
static int connect_to_master(THD*, MYSQL*, Master_info*, bool, bool);
@@ -306,9 +310,9 @@ build_gtid_pos_create_query(THD *thd, String *query,
{
bool err= false;
err|= query->append(gtid_pos_table_definition1);
- err|= append_identifier(thd, query, table_name->str, table_name->length);
+ err|= append_identifier(thd, query, table_name);
err|= query->append(gtid_pos_table_definition2);
- err|= append_identifier(thd, query, engine_name->str, engine_name->length);
+ err|= append_identifier(thd, query, engine_name);
return err;
}
@@ -327,7 +331,7 @@ gtid_pos_table_creation(THD *thd, plugin_ref engine, LEX_CSTRING *table_name)
return 1;
}
- thd->set_db("mysql", 5);
+ thd->set_db(&MYSQL_SCHEMA_NAME);
thd->clear_error();
ulonglong thd_saved_option= thd->variables.option_bits;
/* This query shuold not be binlogged. */
@@ -512,9 +516,7 @@ handle_slave_background(void *arg __attribute__((unused)))
THD *to_kill= p->to_kill;
kill_list= p->next;
- mysql_mutex_lock(&to_kill->LOCK_thd_data);
to_kill->awake(KILL_CONNECTION);
- mysql_mutex_unlock(&to_kill->LOCK_thd_data);
mysql_mutex_lock(&to_kill->LOCK_wakeup_ready);
to_kill->rgi_slave->killed_for_retry=
rpl_group_info::RETRY_KILL_KILLED;
@@ -635,7 +637,6 @@ start_slave_background_thread()
sql_print_error("Failed to create thread while initialising slave");
return 1;
}
-
mysql_mutex_lock(&LOCK_slave_background);
while (!slave_background_thread_gtid_loaded)
mysql_cond_wait(&COND_slave_background, &LOCK_slave_background);
@@ -707,15 +708,6 @@ int init_slave()
}
/*
- If --slave-skip-errors=... was not used, the string value for the
- system variable has not been set up yet. Do it now.
- */
- if (!use_slave_mask)
- {
- print_slave_skip_errors();
- }
-
- /*
If master_host is not specified, try to read it from the master_info file.
If master_host is specified, create the master_info file if it doesn't
exists.
@@ -812,12 +804,12 @@ int init_recovery(Master_info* mi, const char** errmsg)
DBUG_RETURN(0);
}
-
+
/**
Convert slave skip errors bitmap into a printable string.
*/
-static void print_slave_skip_errors(void)
+static void make_slave_skip_errors_printable(void)
{
/*
To be safe, we want 10 characters of room in the buffer for a number
@@ -826,7 +818,7 @@ static void print_slave_skip_errors(void)
plus a NUL terminator. That is a max 6 digit number.
*/
const size_t MIN_ROOM= 10;
- DBUG_ENTER("print_slave_skip_errors");
+ DBUG_ENTER("make_slave_skip_errors_printable");
DBUG_ASSERT(sizeof(slave_skip_error_names) > MIN_ROOM);
DBUG_ASSERT(MAX_SLAVE_ERROR <= 999999); // 6 digits
@@ -848,14 +840,14 @@ static void print_slave_skip_errors(void)
else
{
char *buff= slave_skip_error_names;
- char *bend= buff + sizeof(slave_skip_error_names);
+ char *bend= buff + sizeof(slave_skip_error_names) - MIN_ROOM;
int errnum;
for (errnum= 0; errnum < MAX_SLAVE_ERROR; errnum++)
{
if (bitmap_is_set(&slave_error_mask, errnum))
{
- if (buff + MIN_ROOM >= bend)
+ if (buff >= bend)
break; /* purecov: tested */
buff= int10_to_str(errnum, buff, 10);
*buff++= ',';
@@ -885,24 +877,24 @@ static void print_slave_skip_errors(void)
Called from get_options() in mysqld.cc on start-up
*/
-void init_slave_skip_errors(const char* arg)
+bool init_slave_skip_errors(const char* arg)
{
const char *p;
DBUG_ENTER("init_slave_skip_errors");
+ if (!arg || !*arg) // No errors defined
+ goto end;
+
if (my_bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0))
- {
- fprintf(stderr, "Badly out of memory, please check your system status\n");
- exit(1);
- }
- use_slave_mask = 1;
+ DBUG_RETURN(1);
+
+ use_slave_mask= 1;
for (;my_isspace(system_charset_info,*arg);++arg)
/* empty */;
if (!my_strnncoll(system_charset_info,(uchar*)arg,4,(const uchar*)"all",4))
{
bitmap_set_all(&slave_error_mask);
- print_slave_skip_errors();
- DBUG_VOID_RETURN;
+ goto end;
}
for (p= arg ; *p; )
{
@@ -914,11 +906,109 @@ void init_slave_skip_errors(const char* arg)
while (!my_isdigit(system_charset_info,*p) && *p)
p++;
}
- /* Convert slave skip errors bitmap into a printable string. */
- print_slave_skip_errors();
+
+end:
+ make_slave_skip_errors_printable();
+ DBUG_RETURN(0);
+}
+
+/**
+ Make printable version if slave_transaction_retry_errors
+ This is never empty as at least ER_LOCK_DEADLOCK and ER_LOCK_WAIT_TIMEOUT
+ will be there
+*/
+
+static void make_slave_transaction_retry_errors_printable(void)
+{
+ /*
+ To be safe, we want 10 characters of room in the buffer for a number
+ plus terminators. Also, we need some space for constant strings.
+ 10 characters must be sufficient for a number plus {',' | '...'}
+ plus a NUL terminator. That is a max 6 digit number.
+ */
+ const size_t MIN_ROOM= 10;
+ char *buff= slave_transaction_retry_error_names;
+ char *bend= buff + sizeof(slave_transaction_retry_error_names) - MIN_ROOM;
+ uint i;
+ DBUG_ENTER("make_slave_transaction_retry_errors_printable");
+ DBUG_ASSERT(sizeof(slave_transaction_retry_error_names) > MIN_ROOM);
+
+ /* Make @@slave_transaction_retry_errors show a human-readable value */
+ opt_slave_transaction_retry_errors= slave_transaction_retry_error_names;
+
+ for (i= 0; i < slave_transaction_retry_error_length && buff < bend; i++)
+ {
+ buff= int10_to_str(slave_transaction_retry_errors[i], buff, 10);
+ *buff++= ',';
+ }
+ if (buff != slave_transaction_retry_error_names)
+ buff--; // Remove last ','
+ if (i < slave_transaction_retry_error_length)
+ {
+ /* Couldn't show all errors */
+ buff= strmov(buff, "..."); /* purecov: tested */
+ }
+ *buff=0;
+ DBUG_PRINT("exit", ("error_names: '%s'",
+ slave_transaction_retry_error_names));
DBUG_VOID_RETURN;
}
+
+bool init_slave_transaction_retry_errors(const char* arg)
+{
+ const char *p;
+ long err_code;
+ uint i;
+ DBUG_ENTER("init_slave_transaction_retry_errors");
+
+ /* Handle empty strings */
+ if (!arg)
+ arg= "";
+
+ slave_transaction_retry_error_length= 2;
+ for (;my_isspace(system_charset_info,*arg);++arg)
+ /* empty */;
+ for (p= arg; *p; )
+ {
+ if (!(p= str2int(p, 10, 0, LONG_MAX, &err_code)))
+ break;
+ slave_transaction_retry_error_length++;
+ while (!my_isdigit(system_charset_info,*p) && *p)
+ p++;
+ }
+
+ if (!(slave_transaction_retry_errors=
+ (uint *) my_once_alloc(sizeof(int) *
+ slave_transaction_retry_error_length,
+ MYF(MY_WME))))
+ DBUG_RETURN(1);
+
+ /*
+ Temporary error codes:
+ currently, InnoDB deadlock detected by InnoDB or lock
+ wait timeout (innodb_lock_wait_timeout exceeded
+ */
+ slave_transaction_retry_errors[0]= ER_LOCK_DEADLOCK;
+ slave_transaction_retry_errors[1]= ER_LOCK_WAIT_TIMEOUT;
+
+ /* Add user codes after this */
+ for (p= arg, i= 2; *p; )
+ {
+ if (!(p= str2int(p, 10, 0, LONG_MAX, &err_code)))
+ break;
+ if (err_code > 0 && err_code < ER_ERROR_LAST)
+ slave_transaction_retry_errors[i++]= (uint) err_code;
+ while (!my_isdigit(system_charset_info,*p) && *p)
+ p++;
+ }
+ slave_transaction_retry_error_length= i;
+
+ make_slave_transaction_retry_errors_printable();
+ DBUG_RETURN(0);
+}
+
+
int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
{
DBUG_ENTER("terminate_slave_threads");
@@ -987,7 +1077,7 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
mysql_mutex_unlock(log_lock);
}
- DBUG_RETURN(retval);
+ DBUG_RETURN(retval);
}
@@ -1070,7 +1160,7 @@ terminate_slave_thread(THD *thd,
int error __attribute__((unused));
DBUG_PRINT("loop", ("killing slave thread"));
- mysql_mutex_lock(&thd->LOCK_thd_data);
+ mysql_mutex_lock(&thd->LOCK_thd_kill);
#ifndef DONT_USE_THR_ALARM
/*
Error codes from pthread_kill are:
@@ -1080,9 +1170,9 @@ terminate_slave_thread(THD *thd,
int err __attribute__((unused))= pthread_kill(thd->real_id, thr_client_alarm);
DBUG_ASSERT(err != EINVAL);
#endif
- thd->awake(NOT_KILLED);
+ thd->awake_no_mutex(NOT_KILLED);
- mysql_mutex_unlock(&thd->LOCK_thd_data);
+ mysql_mutex_unlock(&thd->LOCK_thd_kill);
/*
There is a small chance that slave thread might miss the first
@@ -1500,7 +1590,7 @@ const char *print_slave_db_safe(const char* db)
int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
const char *default_val)
{
- uint length;
+ size_t length;
DBUG_ENTER("init_strvar_from_file");
if ((length=my_b_gets(f,var, max_size)))
@@ -2110,7 +2200,7 @@ when it try to get the value of TIME_ZONE global variable from master.";
if (++dbug_count < 3)
goto heartbeat_network_error;
});
- if (mysql_real_query(mysql, query, strlen(query)))
+ if (mysql_real_query(mysql, query, (ulong)strlen(query)))
{
if (check_io_slave_killed(mi, NULL))
goto slave_killed_err;
@@ -2158,7 +2248,7 @@ when it try to get the value of TIME_ZONE global variable from master.";
Once the first FD will be received its alg descriptor will replace
the being queried one.
*/
- rc= mysql_real_query(mysql, query, strlen(query));
+ rc= mysql_real_query(mysql, query,(ulong)strlen(query));
if (rc != 0)
{
if (check_io_slave_killed(mi, NULL))
@@ -2736,7 +2826,7 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi,
bool *suppress_warnings)
{
uchar buf[1024], *pos= buf;
- uint report_host_len=0, report_user_len=0, report_password_len=0;
+ size_t report_host_len=0, report_user_len=0, report_password_len=0;
DBUG_ENTER("register_slave_on_master");
*suppress_warnings= FALSE;
@@ -2744,7 +2834,7 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi,
report_host_len= strlen(report_host);
if (report_host_len > HOSTNAME_LENGTH)
{
- sql_print_warning("The length of report_host is %d. "
+ sql_print_warning("The length of report_host is %zu. "
"It is larger than the max length(%d), so this "
"slave cannot be registered to the master.",
report_host_len, HOSTNAME_LENGTH);
@@ -2755,7 +2845,7 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi,
report_user_len= strlen(report_user);
if (report_user_len > USERNAME_LENGTH)
{
- sql_print_warning("The length of report_user is %d. "
+ sql_print_warning("The length of report_user is %zu. "
"It is larger than the max length(%d), so this "
"slave cannot be registered to the master.",
report_user_len, USERNAME_LENGTH);
@@ -2766,7 +2856,7 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi,
report_password_len= strlen(report_password);
if (report_password_len > MAX_PASSWORD_LENGTH)
{
- sql_print_warning("The length of report_password is %d. "
+ sql_print_warning("The length of report_password is %zu. "
"It is larger than the max length(%d), so this "
"slave cannot be registered to the master.",
report_password_len, MAX_PASSWORD_LENGTH);
@@ -2787,7 +2877,7 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi,
/* The master will fill in master_id */
int4store(pos, 0); pos+= 4;
- if (simple_command(mysql, COM_REGISTER_SLAVE, buf, (size_t) (pos- buf), 0))
+ if (simple_command(mysql, COM_REGISTER_SLAVE, buf, (ulong) (pos- buf), 0))
{
if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
{
@@ -3054,7 +3144,7 @@ void show_master_info_get_fields(THD *thd, List<Item> *field_list,
mem_root);
field_list->push_back(new (mem_root)
Item_empty_string(thd, "Gtid_Slave_Pos",
- gtid_pos_length),
+ (uint)gtid_pos_length),
mem_root);
}
DBUG_VOID_RETURN;
@@ -3496,11 +3586,9 @@ static int request_dump(THD *thd, MYSQL* mysql, Master_info* mi,
if (opt_log_slave_updates && opt_replicate_annotate_row_events)
binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
- if (RUN_HOOK(binlog_relay_io,
- before_request_transmit,
- (thd, mi, binlog_flags)))
+ if (repl_semisync_slave.request_transmit(mi))
DBUG_RETURN(1);
-
+
// TODO if big log files: Change next to int8store()
int4store(buf, (ulong) mi->master_log_pos);
int2store(buf + 4, binlog_flags);
@@ -3571,7 +3659,8 @@ static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings,
we suppress prints to .err file as long as the reconnect
happens without problems
*/
- *suppress_warnings= TRUE;
+ *suppress_warnings=
+ global_system_variables.log_warnings < 2 ? TRUE : FALSE;
}
else
{
@@ -3598,14 +3687,20 @@ static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings,
DBUG_RETURN(len - 1);
}
-/*
+
+/**
Check if the current error is of temporary nature of not.
Some errors are temporary in nature, such as
ER_LOCK_DEADLOCK and ER_LOCK_WAIT_TIMEOUT.
+
+ @retval 0 if fatal error
+ @retval 1 temporary error, do retry
*/
+
int
has_temporary_error(THD *thd)
{
+ uint current_errno;
DBUG_ENTER("has_temporary_error");
DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
@@ -3623,14 +3718,12 @@ has_temporary_error(THD *thd)
if (!thd->is_error())
DBUG_RETURN(0);
- /*
- Temporary error codes:
- currently, InnoDB deadlock detected by InnoDB or lock
- wait timeout (innodb_lock_wait_timeout exceeded
- */
- if (thd->get_stmt_da()->sql_errno() == ER_LOCK_DEADLOCK ||
- thd->get_stmt_da()->sql_errno() == ER_LOCK_WAIT_TIMEOUT)
- DBUG_RETURN(1);
+ current_errno= thd->get_stmt_da()->sql_errno();
+ for (uint i= 0; i < slave_transaction_retry_error_length; i++)
+ {
+ if (current_errno == slave_transaction_retry_errors[i])
+ DBUG_RETURN(1);
+ }
DBUG_RETURN(0);
}
@@ -4281,8 +4374,9 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli,
exec_res= 0;
serial_rgi->cleanup_context(thd, 1);
/* chance for concurrent connection to get more locks */
- slave_sleep(thd, MY_MIN(serial_rgi->trans_retries,
+ slave_sleep(thd, MY_MAX(MY_MIN(serial_rgi->trans_retries,
MAX_SLAVE_RETRY_PAUSE),
+ slave_trans_retry_interval),
sql_slave_killed, serial_rgi);
serial_rgi->trans_retries++;
mysql_mutex_lock(&rli->data_lock); // because of SHOW STATUS
@@ -4367,7 +4461,7 @@ static bool check_io_slave_killed(Master_info *mi, const char *info)
@param[in] mysql MySQL connection.
@param[in] mi Master connection information.
@param[in,out] retry_count Number of attempts to reconnect.
- @param[in] suppress_warnings TRUE when a normal net read timeout
+ @param[in] suppress_warnings TRUE when a normal net read timeout
has caused to reconnecting.
@param[in] messages Messages to print/log, see
reconnect_messages[] array.
@@ -4496,6 +4590,7 @@ pthread_handler_t handle_slave_io(void *arg)
mi->abort_slave = 0;
mysql_mutex_unlock(&mi->run_lock);
mysql_cond_broadcast(&mi->start_cond);
+ mi->rows_event_tracker.reset();
DBUG_PRINT("master_info",("log_file_name: '%s' position: %llu",
mi->master_log_name, mi->master_log_pos));
@@ -4520,7 +4615,8 @@ pthread_handler_t handle_slave_io(void *arg)
}
- if (RUN_HOOK(binlog_relay_io, thread_start, (thd, mi)))
+ if (DBUG_EVALUATE_IF("failed_slave_start", 1, 0)
+ || repl_semisync_slave.slave_start(mi))
{
mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL,
ER_THD(thd, ER_SLAVE_FATAL_ERROR),
@@ -4578,6 +4674,10 @@ connected:
*/
mi->gtid_reconnect_event_skip_count= mi->events_queued_since_last_gtid;
mi->gtid_event_seen= false;
+ /*
+ Reset stale state of the rows-event group tracker at reconnect.
+ */
+ mi->rows_event_tracker.reset();
}
#ifdef ENABLED_DEBUG_SYNC
@@ -4710,9 +4810,10 @@ Stopping slave I/O thread due to out-of-memory error from master");
retry_count=0; // ok event, reset retry counter
THD_STAGE_INFO(thd, stage_queueing_master_event_to_the_relay_log);
event_buf= (const char*)mysql->net.read_pos + 1;
- if (RUN_HOOK(binlog_relay_io, after_read_event,
- (thd, mi,(const char*)mysql->net.read_pos + 1,
- event_len, &event_buf, &event_len)))
+ mi->semi_ack= 0;
+ if (repl_semisync_slave.
+ slave_read_sync_header((const char*)mysql->net.read_pos + 1, event_len,
+ &(mi->semi_ack), &event_buf, &event_len))
{
mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL,
ER_THD(thd, ER_SLAVE_FATAL_ERROR),
@@ -4761,9 +4862,6 @@ Stopping slave I/O thread due to out-of-memory error from master");
tokenamount -= network_read_len;
}
- /* XXX: 'synced' should be updated by queue_event to indicate
- whether event has been synced to disk */
- bool synced= 0;
if (queue_event(mi, event_buf, event_len))
{
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL,
@@ -4772,8 +4870,8 @@ Stopping slave I/O thread due to out-of-memory error from master");
goto err;
}
- if (RUN_HOOK(binlog_relay_io, after_queue_event,
- (thd, mi, event_buf, event_len, synced)))
+ if (rpl_semi_sync_slave_status && (mi->semi_ack & SEMI_SYNC_NEED_ACK) &&
+ repl_semisync_slave.slave_reply(mi))
{
mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL,
ER_THD(thd, ER_SLAVE_FATAL_ERROR),
@@ -4782,7 +4880,16 @@ Stopping slave I/O thread due to out-of-memory error from master");
}
if (mi->using_gtid == Master_info::USE_GTID_NO &&
- flush_master_info(mi, TRUE, TRUE))
+ /*
+ If rpl_semi_sync_slave_delay_master is enabled, we will flush
+ master info only when ack is needed. This may lead to at least one
+ group transaction delay but affords better performance improvement.
+ */
+ (!repl_semisync_slave.get_slave_enabled() ||
+ (!(mi->semi_ack & SEMI_SYNC_SLAVE_DELAY_SYNC) ||
+ (mi->semi_ack & (SEMI_SYNC_NEED_ACK)))) &&
+ (DBUG_EVALUATE_IF("failed_flush_master_info", 1, 0) ||
+ flush_master_info(mi, TRUE, TRUE)))
{
sql_print_error("Failed to flush master info file");
goto err;
@@ -4836,9 +4943,9 @@ err:
IO_RPL_LOG_NAME, mi->master_log_pos,
tmp.c_ptr_safe());
}
- RUN_HOOK(binlog_relay_io, thread_stop, (thd, mi));
+ repl_semisync_slave.slave_stop(mi);
thd->reset_query();
- thd->reset_db(NULL, 0);
+ thd->reset_db(&null_clex_str);
if (mysql)
{
/*
@@ -4870,9 +4977,7 @@ err_during_init:
// TODO: make rpl_status part of Master_info
change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
- mysql_mutex_lock(&LOCK_thread_count);
- thd->unlink();
- mysql_mutex_unlock(&LOCK_thread_count);
+ thd->assert_not_linked();
delete thd;
thread_safe_decrement32(&service_thread_count);
signal_thd_deleted();
@@ -5426,7 +5531,7 @@ pthread_handler_t handle_slave_sql(void *arg)
*/
thd->catalog= 0;
thd->reset_query();
- thd->reset_db(NULL, 0);
+ thd->reset_db(&null_clex_str);
if (rli->mi->using_gtid != Master_info::USE_GTID_NO)
{
ulong domain_count;
@@ -5551,11 +5656,7 @@ err_during_init:
rpl_parallel_resize_pool_if_no_slaves();
- /* TODO: Check if this lock is needed */
- mysql_mutex_lock(&LOCK_thread_count);
delete serial_rgi;
- mysql_mutex_unlock(&LOCK_thread_count);
-
delete thd;
thread_safe_decrement32(&service_thread_count);
signal_thd_deleted();
@@ -5982,7 +6083,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
char* new_buf = NULL;
char new_buf_arr[4096];
bool is_malloc = false;
-
+ bool is_rows_event= false;
/*
FD_q must have been prepared for the first R_a event
inside get_master_version_and_clock()
@@ -6164,7 +6265,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
mysql_mutex_unlock(log_lock);
goto err;
}
- rli->relay_log.signal_update();
+ rli->relay_log.signal_relay_log_update();
mysql_mutex_unlock(log_lock);
mi->gtid_reconnect_event_skip_count= 0;
@@ -6416,11 +6517,11 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
got_gtid_event= true;
if (mi->using_gtid == Master_info::USE_GTID_NO)
goto default_action;
- if (unlikely(!mi->gtid_event_seen))
+ if (unlikely(mi->gtid_reconnect_event_skip_count))
{
- mi->gtid_event_seen= true;
- if (mi->gtid_reconnect_event_skip_count)
+ if (likely(!mi->gtid_event_seen))
{
+ mi->gtid_event_seen= true;
/*
If we are reconnecting, and we need to skip a partial event group
already queued to the relay log before the reconnect, then we check
@@ -6449,13 +6550,45 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
rpl_slave_state_tostring_helper(&error_msg, &event_gtid, &first);
goto err;
}
+ if (global_system_variables.log_warnings > 1)
+ {
+ bool first= true;
+ StringBuffer<1024> gtid_text;
+ rpl_slave_state_tostring_helper(&gtid_text, &mi->last_queued_gtid,
+ &first);
+ sql_print_information("Slave IO thread is reconnected to "
+ "receive Gtid_log_event %s. It is to skip %llu "
+ "already received events including the gtid one",
+ gtid_text.ptr(),
+ mi->events_queued_since_last_gtid);
+ }
+ goto default_action;
}
- }
+ else
+ {
+ bool first;
+ StringBuffer<1024> gtid_text;
- if (unlikely(mi->gtid_reconnect_event_skip_count))
- {
- goto default_action;
+ gtid_text.append(STRING_WITH_LEN("Last received gtid: "));
+ first= true;
+ rpl_slave_state_tostring_helper(&gtid_text, &mi->last_queued_gtid,
+ &first);
+ gtid_text.append(STRING_WITH_LEN(", currently received: "));
+ first= true;
+ rpl_slave_state_tostring_helper(&gtid_text, &event_gtid, &first);
+
+ error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
+ sql_print_error("Slave IO thread has received a new Gtid_log_event "
+ "while skipping already logged events "
+ "after reconnect. %s. %llu remains to be skipped. "
+ "The number of originally read events was %llu",
+ gtid_text.ptr(),
+ mi->gtid_reconnect_event_skip_count,
+ mi->events_queued_since_last_gtid);
+ goto err;
+ }
}
+ mi->gtid_event_seen= true;
/*
We have successfully queued to relay log everything before this GTID, so
@@ -6522,8 +6655,34 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
goto err;
}
}
- buf = new_buf;
is_compress_event = true;
+ buf = new_buf;
+ /*
+ As we are uncertain about compressed V2 rows events, we don't track
+ them
+ */
+ if (LOG_EVENT_IS_ROW_V2((Log_event_type) buf[EVENT_TYPE_OFFSET]))
+ goto default_action;
+ /* fall through */
+ case WRITE_ROWS_EVENT_V1:
+ case UPDATE_ROWS_EVENT_V1:
+ case DELETE_ROWS_EVENT_V1:
+ case WRITE_ROWS_EVENT:
+ case UPDATE_ROWS_EVENT:
+ case DELETE_ROWS_EVENT:
+ {
+ is_rows_event= true;
+ mi->rows_event_tracker.update(mi->master_log_name,
+ mi->master_log_pos,
+ buf,
+ mi->rli.relay_log.
+ description_event_for_queue);
+
+ DBUG_EXECUTE_IF("simulate_stmt_end_rows_event_loss",
+ {
+ mi->rows_event_tracker.stmt_end_seen= false;
+ });
+ }
goto default_action;
#ifndef DBUG_OFF
@@ -6582,6 +6741,21 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
}
/*
+ Integrity of Rows- event group check.
+ A sequence of Rows- events must end with STMT_END_F flagged one.
+ Even when Heartbeat event interrupts Rows- events flow this must indicate a
+ malfunction e.g logging on the master.
+ */
+ if (((uchar) buf[EVENT_TYPE_OFFSET] != HEARTBEAT_LOG_EVENT) &&
+ !is_rows_event &&
+ mi->rows_event_tracker.check_and_report(mi->master_log_name,
+ mi->master_log_pos))
+ {
+ error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
+ goto err;
+ }
+
+ /*
If we filter events master-side (eg. @@skip_replication), we will see holes
in the event positions from the master. If we see such a hole, adjust
mi->master_log_pos accordingly so we maintain the correct position (for
@@ -6709,7 +6883,8 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
if (got_gtid_event)
rli->ign_gtids.update(&event_gtid);
}
- rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
+ // the slave SQL thread needs to re-check
+ rli->relay_log.signal_relay_log_update();
DBUG_PRINT("info", ("master_log_pos: %lu, event originating from %u server, ignored",
(ulong) mi->master_log_pos, uint4korr(buf + SERVER_ID_OFFSET)));
}
@@ -6749,6 +6924,21 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
The whole of the current event group is queued. So in case of
reconnect we can start from after the current GTID.
*/
+ if (mi->gtid_reconnect_event_skip_count)
+ {
+ bool first= true;
+ StringBuffer<1024> gtid_text;
+
+ rpl_slave_state_tostring_helper(&gtid_text, &mi->last_queued_gtid,
+ &first);
+ sql_print_error("Slave IO thread received a terminal event from "
+ "group %s whose retrieval was interrupted "
+ "with reconnect. We still had %llu events to read. "
+ "The number of originally read events was %llu",
+ gtid_text.ptr(),
+ mi->gtid_reconnect_event_skip_count,
+ mi->events_queued_since_last_gtid);
+ }
mi->gtid_current_pos.update(&mi->last_queued_gtid);
mi->events_queued_since_last_gtid= 0;
@@ -7219,7 +7409,7 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size)
MYSQL_BIN_LOG::open() will write the buffered description event.
*/
old_pos= rli->event_relay_log_pos;
- if ((ev= Log_event::read_log_event(cur_log,0,
+ if ((ev= Log_event::read_log_event(cur_log,
rli->relay_log.description_event_for_exec,
opt_slave_sql_verify_checksum)))
@@ -7748,6 +7938,92 @@ bool rpl_master_erroneous_autoinc(THD *thd)
return FALSE;
}
+
+static bool get_row_event_stmt_end(const char* buf,
+ const Format_description_log_event *fdle)
+{
+ uint8 const common_header_len= fdle->common_header_len;
+ Log_event_type event_type= (Log_event_type)(uchar)buf[EVENT_TYPE_OFFSET];
+
+ uint8 const post_header_len= fdle->post_header_len[event_type-1];
+ const char *flag_start= buf + common_header_len;
+ /*
+ The term 4 below signifies that master is of 'an intermediate source', see
+ Rows_log_event::Rows_log_event.
+ */
+ flag_start += RW_MAPID_OFFSET + ((post_header_len == 6) ? 4 : RW_FLAGS_OFFSET);
+
+ return (uint2korr(flag_start) & Rows_log_event::STMT_END_F) != 0;
+}
+
+
+/*
+ Reset log event tracking data.
+*/
+
+void Rows_event_tracker::reset()
+{
+ binlog_file_name[0]= 0;
+ first_seen= last_seen= 0;
+ stmt_end_seen= false;
+}
+
+
+/*
+ Update log event tracking data.
+
+ The first- and last- seen event binlog position get memorized, as
+ well as the end-of-statement status of the last one.
+*/
+
+void Rows_event_tracker::update(const char* file_name, my_off_t pos,
+ const char* buf,
+ const Format_description_log_event *fdle)
+{
+ if (!first_seen)
+ {
+ first_seen= pos;
+ strmake(binlog_file_name, file_name, sizeof(binlog_file_name) - 1);
+ }
+ last_seen= pos;
+ DBUG_ASSERT(stmt_end_seen == 0); // We can only have one
+ stmt_end_seen= get_row_event_stmt_end(buf, fdle);
+};
+
+
+/**
+ The function is called at next event reading
+ after a sequence of Rows- log-events. It checks the end-of-statement status
+ of the past sequence to report on any isssue.
+ In the positive case the tracker gets reset.
+
+ @return true when the Rows- event group integrity found compromised,
+ false otherwise.
+*/
+bool Rows_event_tracker::check_and_report(const char* file_name,
+ my_off_t pos)
+{
+ if (last_seen)
+ {
+ // there was at least one "block" event previously
+ if (!stmt_end_seen)
+ {
+ sql_print_error("Slave IO thread did not receive an expected "
+ "Rows-log end-of-statement for event starting "
+ "at log '%s' position %llu "
+ "whose last block was seen at log '%s' position %llu. "
+ "The end-of-statement should have been delivered "
+ "before the current one at log '%s' position %llu",
+ binlog_file_name, first_seen,
+ binlog_file_name, last_seen, file_name, pos);
+ return true;
+ }
+ reset();
+ }
+
+ return false;
+}
+
/**
@} (end of group Replication)
*/
diff --git a/sql/slave.h b/sql/slave.h
index c856a6989ed..649d55b45b9 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -52,7 +52,7 @@
#define SLAVE_NET_TIMEOUT 60
-#define MAX_SLAVE_ERROR 2000
+#define MAX_SLAVE_ERROR ER_ERROR_LAST+1
#define MAX_REPLICATION_THREAD 64
@@ -132,6 +132,9 @@ extern ulong master_retry_count;
extern MY_BITMAP slave_error_mask;
extern char slave_skip_error_names[];
extern bool use_slave_mask;
+extern char slave_transaction_retry_error_names[];
+extern uint *slave_transaction_retry_errors;
+extern uint slave_transaction_retry_error_length;
extern char *slave_load_tmpdir;
extern char *master_info_file;
extern MYSQL_PLUGIN_IMPORT char *relay_log_info_file;
@@ -139,6 +142,7 @@ extern char *opt_relay_logname, *opt_relaylog_index_name;
extern my_bool opt_skip_slave_start, opt_reckless_slave;
extern my_bool opt_log_slave_updates;
extern char *opt_slave_skip_errors;
+extern char *opt_slave_transaction_retry_errors;
extern my_bool opt_replicate_annotate_row_events;
extern ulonglong relay_log_space_limit;
extern ulonglong opt_read_binlog_speed_limit;
@@ -184,7 +188,8 @@ extern const char *relay_log_basename;
int init_slave();
int init_recovery(Master_info* mi, const char** errmsg);
-void init_slave_skip_errors(const char* arg);
+bool init_slave_skip_errors(const char* arg);
+bool init_slave_transaction_retry_errors(const char* arg);
int register_slave_on_master(MYSQL* mysql);
int terminate_slave_threads(Master_info* mi, int thread_mask,
bool skip_lock = 0);
diff --git a/sql/sp.cc b/sql/sp.cc
index e02283d1f17..773a5479199 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -35,7 +35,6 @@
#include <my_user.h>
-
sp_cache **Sp_handler_procedure::get_cache(THD *thd) const
{
return &thd->sp_proc_cache;
@@ -93,79 +92,79 @@ static const
TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] =
{
{
- { C_STRING_WITH_LEN("db") },
- { C_STRING_WITH_LEN("char(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("db") },
+ { STRING_WITH_LEN("char(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("name") },
- { C_STRING_WITH_LEN("char(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("name") },
+ { STRING_WITH_LEN("char(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("type") },
- { C_STRING_WITH_LEN("enum('FUNCTION','PROCEDURE')") },
+ { STRING_WITH_LEN("type") },
+ { STRING_WITH_LEN("enum('FUNCTION','PROCEDURE')") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("specific_name") },
- { C_STRING_WITH_LEN("char(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("specific_name") },
+ { STRING_WITH_LEN("char(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("language") },
- { C_STRING_WITH_LEN("enum('SQL')") },
+ { STRING_WITH_LEN("language") },
+ { STRING_WITH_LEN("enum('SQL')") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("sql_data_access") },
- { C_STRING_WITH_LEN("enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')") },
+ { STRING_WITH_LEN("sql_data_access") },
+ { STRING_WITH_LEN("enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("is_deterministic") },
- { C_STRING_WITH_LEN("enum('YES','NO')") },
+ { STRING_WITH_LEN("is_deterministic") },
+ { STRING_WITH_LEN("enum('YES','NO')") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("security_type") },
- { C_STRING_WITH_LEN("enum('INVOKER','DEFINER')") },
+ { STRING_WITH_LEN("security_type") },
+ { STRING_WITH_LEN("enum('INVOKER','DEFINER')") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("param_list") },
- { C_STRING_WITH_LEN("blob") },
+ { STRING_WITH_LEN("param_list") },
+ { STRING_WITH_LEN("blob") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("returns") },
- { C_STRING_WITH_LEN("longblob") },
+ { STRING_WITH_LEN("returns") },
+ { STRING_WITH_LEN("longblob") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("body") },
- { C_STRING_WITH_LEN("longblob") },
+ { STRING_WITH_LEN("body") },
+ { STRING_WITH_LEN("longblob") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("definer") },
- { C_STRING_WITH_LEN("char(") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("definer") },
+ { STRING_WITH_LEN("char(") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("created") },
- { C_STRING_WITH_LEN("timestamp") },
+ { STRING_WITH_LEN("created") },
+ { STRING_WITH_LEN("timestamp") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("modified") },
- { C_STRING_WITH_LEN("timestamp") },
+ { STRING_WITH_LEN("modified") },
+ { STRING_WITH_LEN("timestamp") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("sql_mode") },
- { C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
+ { STRING_WITH_LEN("sql_mode") },
+ { STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
"'IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY',"
"'NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
@@ -174,32 +173,37 @@ TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] =
"'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES',"
"'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER',"
"'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH',"
- "'EMPTY_STRING_IS_NULL')") },
+ "'EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("comment") },
- { C_STRING_WITH_LEN("text") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("comment") },
+ { STRING_WITH_LEN("text") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("character_set_client") },
- { C_STRING_WITH_LEN("char(32)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("character_set_client") },
+ { STRING_WITH_LEN("char(32)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("collation_connection") },
- { C_STRING_WITH_LEN("char(32)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("collation_connection") },
+ { STRING_WITH_LEN("char(32)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("db_collation") },
- { C_STRING_WITH_LEN("char(32)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("db_collation") },
+ { STRING_WITH_LEN("char(32)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("body_utf8") },
- { C_STRING_WITH_LEN("longblob") },
+ { STRING_WITH_LEN("body_utf8") },
+ { STRING_WITH_LEN("longblob") },
+ { NULL, 0 }
+ },
+ {
+ { STRING_WITH_LEN("aggregate") },
+ { STRING_WITH_LEN("enum('NONE','GROUP')") },
{ NULL, 0 }
}
};
@@ -450,7 +454,7 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_backup *backup)
DBUG_ENTER("open_proc_table_for_read");
- table.init_one_table("mysql", 5, "proc", 4, "proc", TL_READ);
+ table.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PROC_NAME, NULL, TL_READ);
if (open_system_tables_for_read(thd, &table, backup))
DBUG_RETURN(NULL);
@@ -485,7 +489,7 @@ static TABLE *open_proc_table_for_update(THD *thd)
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
DBUG_ENTER("open_proc_table_for_update");
- table_list.init_one_table("mysql", 5, "proc", 4, "proc", TL_WRITE);
+ table_list.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PROC_NAME, NULL, TL_WRITE);
if (!(table= open_system_table_for_update(thd, &table_list)))
DBUG_RETURN(NULL);
@@ -583,6 +587,22 @@ bool st_sp_chistics::read_from_mysql_proc_row(THD *thd, TABLE *table)
return true;
suid= str.str[0] == 'I' ? SP_IS_NOT_SUID : SP_IS_SUID;
+ if (table->field[MYSQL_PROC_FIELD_AGGREGATE]->val_str_nopad(thd->mem_root,
+ &str))
+ return true;
+
+ switch (str.str[0]) {
+ case 'N':
+ agg_type= NOT_AGGREGATE;
+ break;
+ case 'G':
+ agg_type= GROUP_AGGREGATE;
+ break;
+ default:
+ agg_type= DEFAULT_AGGREGATE;
+ }
+
+
if (table->field[MYSQL_PROC_FIELD_COMMENT]->val_str_nopad(thd->mem_root,
&comment))
return true;
@@ -808,7 +828,6 @@ static sp_head *sp_compile(THD *thd, String *defstr, sql_mode_t sql_mode,
else
{
sp= thd->lex->sphead;
- sp->set_select_number(thd->select_number);
}
thd->pop_internal_handler();
@@ -1183,6 +1202,13 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const
table->field[MYSQL_PROC_FIELD_NAME]->
store(sp->m_name, system_charset_info);
+ if (sp->agg_type() != DEFAULT_AGGREGATE)
+ {
+ store_failed= store_failed ||
+ table->field[MYSQL_PROC_FIELD_AGGREGATE]->
+ store((longlong)sp->agg_type(),TRUE);
+ }
+
store_failed= store_failed ||
table->field[MYSQL_PROC_MYSQL_TYPE]->
store((longlong) type(), true);
@@ -1317,8 +1343,8 @@ log:
{
thd->clear_error();
- String log_query;
- log_query.set_charset(system_charset_info);
+ StringBuffer<128> log_query(thd->variables.character_set_client);
+ DBUG_ASSERT(log_query.charset()->mbminlen == 1);
if (show_create_sp(thd, &log_query,
sp->m_explicit_name ? sp->m_db : null_clex_str,
@@ -1494,6 +1520,9 @@ Sp_handler::sp_update_routine(THD *thd, const Database_qualified_name *name,
if (chistics->comment.str)
table->field[MYSQL_PROC_FIELD_COMMENT]->store(chistics->comment,
system_charset_info);
+ if (chistics->agg_type != DEFAULT_AGGREGATE)
+ table->field[MYSQL_PROC_FIELD_AGGREGATE]->
+ store((longlong)chistics->agg_type, TRUE);
if ((ret= table->file->ha_update_row(table->record[1],table->record[0])) &&
ret != HA_ERR_RECORD_IS_THE_SAME)
ret= SP_WRITE_ROW_FAILED;
@@ -1888,16 +1917,16 @@ Sp_handler::sp_exist_routines(THD *thd, TABLE_LIST *routines) const
sp_name *name;
LEX_CSTRING lex_db;
LEX_CSTRING lex_name;
- thd->make_lex_string(&lex_db, routine->db, strlen(routine->db));
- thd->make_lex_string(&lex_name, routine->table_name,
- strlen(routine->table_name));
+ thd->make_lex_string(&lex_db, routine->db.str, routine->db.length);
+ thd->make_lex_string(&lex_name, routine->table_name.str,
+ routine->table_name.length);
name= new sp_name(&lex_db, &lex_name, true);
sp_object_found= sp_find_routine(thd, name, false) != NULL;
thd->get_stmt_da()->clear_warning_info(thd->query_id);
if (! sp_object_found)
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE",
- routine->table_name);
+ routine->table_name.str);
DBUG_RETURN(TRUE);
}
}
@@ -2238,11 +2267,14 @@ Sp_handler::show_create_sp(THD *thd, String *buf,
sql_mode_t sql_mode) const
{
sql_mode_t old_sql_mode= thd->variables.sql_mode;
+ size_t agglen= (chistics.agg_type == GROUP_AGGREGATE)? 10 : 0;
+ LEX_CSTRING tmp;
+
/* Make some room to begin with */
if (buf->alloc(100 + db.length + 1 + name.length +
params.length + returns.length +
- chistics.comment.length + 10 /* length of " DEFINER= "*/ +
- USER_HOST_BUFF_SIZE))
+ chistics.comment.length + 10 /* length of " DEFINER= "*/ +
+ agglen + USER_HOST_BUFF_SIZE))
return true;
thd->variables.sql_mode= sql_mode;
@@ -2250,19 +2282,22 @@ Sp_handler::show_create_sp(THD *thd, String *buf,
if (ddl_options.or_replace())
buf->append(STRING_WITH_LEN("OR REPLACE "));
append_definer(thd, buf, &definer.user, &definer.host);
- buf->append(type_lex_cstring());
+ if (chistics.agg_type == GROUP_AGGREGATE)
+ buf->append(STRING_WITH_LEN("AGGREGATE "));
+ tmp= type_lex_cstring();
+ buf->append(&tmp);
buf->append(STRING_WITH_LEN(" "));
if (ddl_options.if_not_exists())
buf->append(STRING_WITH_LEN("IF NOT EXISTS "));
if (db.length > 0)
{
- append_identifier(thd, buf, db.str, db.length);
+ append_identifier(thd, buf, &db);
buf->append('.');
}
- append_identifier(thd, buf, name.str, name.length);
+ append_identifier(thd, buf, &name);
buf->append('(');
- buf->append(params);
+ buf->append(&params);
buf->append(')');
if (type() == TYPE_ENUM_FUNCTION)
{
@@ -2270,7 +2305,7 @@ Sp_handler::show_create_sp(THD *thd, String *buf,
buf->append(STRING_WITH_LEN(" RETURN "));
else
buf->append(STRING_WITH_LEN(" RETURNS "));
- buf->append(returns);
+ buf->append(&returns);
}
buf->append('\n');
switch (chistics.daccess) {
@@ -2292,7 +2327,7 @@ Sp_handler::show_create_sp(THD *thd, String *buf,
buf->append(STRING_WITH_LEN(" DETERMINISTIC\n"));
append_suid(buf, chistics.suid);
append_comment(buf, chistics.comment);
- buf->append(body);
+ buf->append(body.str, body.length); // Not \0 terminated
thd->variables.sql_mode= old_sql_mode;
return false;
}
diff --git a/sql/sp.h b/sql/sp.h
index ab307a3064e..4177ff05868 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -100,7 +100,7 @@ public:
virtual LEX_CSTRING type_lex_cstring() const= 0;
virtual LEX_CSTRING empty_body_lex_cstring() const
{
- static LEX_CSTRING m_empty_body= {C_STRING_WITH_LEN("???")};
+ static LEX_CSTRING m_empty_body= {STRING_WITH_LEN("???")};
DBUG_ASSERT(0);
return m_empty_body;
}
@@ -182,12 +182,12 @@ public:
stored_procedure_type type() const { return TYPE_ENUM_PROCEDURE; }
LEX_CSTRING type_lex_cstring() const
{
- static LEX_CSTRING m_type_str= {C_STRING_WITH_LEN("PROCEDURE")};
+ static LEX_CSTRING m_type_str= { STRING_WITH_LEN("PROCEDURE")};
return m_type_str;
}
LEX_CSTRING empty_body_lex_cstring() const
{
- static LEX_CSTRING m_empty_body= {C_STRING_WITH_LEN("BEGIN END")};
+ static LEX_CSTRING m_empty_body= { STRING_WITH_LEN("BEGIN END")};
return m_empty_body;
}
const char *show_create_routine_col1_caption() const
@@ -218,12 +218,12 @@ public:
stored_procedure_type type() const { return TYPE_ENUM_FUNCTION; }
LEX_CSTRING type_lex_cstring() const
{
- static LEX_CSTRING m_type_str= {C_STRING_WITH_LEN("FUNCTION")};
+ static LEX_CSTRING m_type_str= { STRING_WITH_LEN("FUNCTION")};
return m_type_str;
}
LEX_CSTRING empty_body_lex_cstring() const
{
- static LEX_CSTRING m_empty_body= {C_STRING_WITH_LEN("RETURN NULL")};
+ static LEX_CSTRING m_empty_body= { STRING_WITH_LEN("RETURN NULL")};
return m_empty_body;
}
const char *show_create_routine_col1_caption() const
@@ -253,7 +253,7 @@ public:
stored_procedure_type type() const { return TYPE_ENUM_TRIGGER; }
LEX_CSTRING type_lex_cstring() const
{
- static LEX_CSTRING m_type_str= {C_STRING_WITH_LEN("TRIGGER")};
+ static LEX_CSTRING m_type_str= { STRING_WITH_LEN("TRIGGER")};
return m_type_str;
}
MDL_key::enum_mdl_namespace get_mdl_type() const
@@ -370,6 +370,7 @@ enum
MYSQL_PROC_FIELD_COLLATION_CONNECTION,
MYSQL_PROC_FIELD_DB_COLLATION,
MYSQL_PROC_FIELD_BODY_UTF8,
+ MYSQL_PROC_FIELD_AGGREGATE,
MYSQL_PROC_FIELD_COUNT
};
diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc
index 342673bf619..4f7cf1557e4 100644
--- a/sql/sp_cache.cc
+++ b/sql/sp_cache.cc
@@ -23,7 +23,7 @@
#include "sp_head.h"
static mysql_mutex_t Cversion_lock;
-static ulong volatile Cversion= 0;
+static ulong volatile Cversion= 1;
/*
@@ -48,7 +48,7 @@ public:
return my_hash_insert(&m_hashtable, (const uchar *)sp);
}
- inline sp_head *lookup(char *name, uint namelen)
+ inline sp_head *lookup(char *name, size_t namelen)
{
return (sp_head *) my_hash_search(&m_hashtable, (const uchar *)name,
namelen);
@@ -238,6 +238,10 @@ void sp_cache_flush_obsolete(sp_cache **cp, sp_head **sp)
}
}
+void sp_cache_flush(sp_cache *cp, sp_head *sp)
+{
+ cp->remove(sp);
+}
/**
Return the current global version of the cache.
diff --git a/sql/sp_cache.h b/sql/sp_cache.h
index a045ff5d3c5..59e0fc186dd 100644
--- a/sql/sp_cache.h
+++ b/sql/sp_cache.h
@@ -60,6 +60,7 @@ void sp_cache_insert(sp_cache **cp, sp_head *sp);
sp_head *sp_cache_lookup(sp_cache **cp, const Database_qualified_name *name);
void sp_cache_invalidate();
void sp_cache_flush_obsolete(sp_cache **cp, sp_head **sp);
+void sp_cache_flush(sp_cache *cp, sp_head *sp);
ulong sp_cache_version();
void sp_cache_enforce_limit(sp_cache *cp, ulong upper_limit_for_elements);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f402b4919b9..cdb5e256e46 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -27,6 +27,7 @@
#include "sql_array.h" // Dynamic_array
#include "log_event.h" // Query_log_event
#include "sql_derived.h" // mysql_handle_derived
+#include "sql_select.h" // Virtual_tmp_table
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation
@@ -337,8 +338,8 @@ sp_get_flags_for_command(LEX *lex)
/**
Prepare an Item for evaluation (call of fix_fields).
- @param thd thread handler
@param it_addr pointer on item refernce
+ @param cols expected number of elements (1 for scalar, >=1 for ROWs)
@retval
NULL error
@@ -346,21 +347,32 @@ sp_get_flags_for_command(LEX *lex)
non-NULL prepared item
*/
-Item *
-sp_prepare_func_item(THD* thd, Item **it_addr, uint cols)
+Item *THD::sp_prepare_func_item(Item **it_addr, uint cols)
{
- DBUG_ENTER("sp_prepare_func_item");
+ DBUG_ENTER("THD::sp_prepare_func_item");
+ Item *res= sp_fix_func_item(it_addr);
+ if (res && res->check_cols(cols))
+ DBUG_RETURN(NULL);
+ DBUG_RETURN(res);
+}
+
+
+/**
+ Fix an Item for evaluation for SP.
+*/
+Item *THD::sp_fix_func_item(Item **it_addr)
+{
+ DBUG_ENTER("THD::sp_fix_func_item");
if (!(*it_addr)->fixed &&
- (*it_addr)->fix_fields(thd, it_addr))
+ (*it_addr)->fix_fields(this, it_addr))
{
DBUG_PRINT("info", ("fix_fields() failed"));
DBUG_RETURN(NULL);
}
- it_addr= (*it_addr)->this_item_addr(thd, it_addr);
+ it_addr= (*it_addr)->this_item_addr(this, it_addr);
- if ((!(*it_addr)->fixed &&
- (*it_addr)->fix_fields(thd, it_addr)) ||
- (*it_addr)->check_cols(cols))
+ if (!(*it_addr)->fixed &&
+ (*it_addr)->fix_fields(this, it_addr))
{
DBUG_PRINT("info", ("fix_fields() failed"));
DBUG_RETURN(NULL);
@@ -372,7 +384,6 @@ sp_prepare_func_item(THD* thd, Item **it_addr, uint cols)
/**
Evaluate an expression and store the result in the field.
- @param thd current thread object
@param result_field the field to store the result
@param expr_item_ptr the root item of the expression
@@ -382,67 +393,13 @@ sp_prepare_func_item(THD* thd, Item **it_addr, uint cols)
TRUE on error
*/
-bool
-sp_eval_expr(THD *thd, Item *result_item, Field *result_field,
- Item **expr_item_ptr)
+bool THD::sp_eval_expr(Field *result_field, Item **expr_item_ptr)
{
- Item *expr_item;
- enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
- bool save_abort_on_warning= thd->abort_on_warning;
- bool save_stmt_modified_non_trans_table=
- thd->transaction.stmt.modified_non_trans_table;
-
- DBUG_ENTER("sp_eval_expr");
-
- if (!*expr_item_ptr)
- goto error;
-
- if (!(expr_item= sp_prepare_func_item(thd, expr_item_ptr,
- result_item ? result_item->cols() : 1)))
- goto error;
-
- /*
- expr_item is now fixed, it's safe to call cmp_type()
- If result_item is NULL, then we're setting the RETURN value.
- */
- if ((!result_item || result_item->cmp_type() != ROW_RESULT) &&
- expr_item->cmp_type() == ROW_RESULT)
- {
- my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
- goto error;
- }
-
- /*
- Set THD flags to emit warnings/errors in case of overflow/type errors
- during saving the item into the field.
-
- Save original values and restore them after save.
- */
-
- thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
- thd->abort_on_warning= thd->is_strict_mode();
- thd->transaction.stmt.modified_non_trans_table= FALSE;
-
+ DBUG_ENTER("THD::sp_eval_expr");
+ DBUG_ASSERT(*expr_item_ptr);
+ Sp_eval_expr_state state(this);
/* Save the value in the field. Convert the value if needed. */
-
- expr_item->save_in_field(result_field, 0);
-
- thd->count_cuted_fields= save_count_cuted_fields;
- thd->abort_on_warning= save_abort_on_warning;
- thd->transaction.stmt.modified_non_trans_table= save_stmt_modified_non_trans_table;
-
- if (!thd->is_error())
- DBUG_RETURN(FALSE);
-
-error:
- /*
- In case of error during evaluation, leave the result field set to NULL.
- Sic: we can't do it in the beginning of the function because the
- result field might be needed for its own re-evaluation, e.g. case of
- set x = x + 1;
- */
- result_field->set_null();
- DBUG_RETURN (TRUE);
+ DBUG_RETURN(result_field->sp_prepare_and_store_item(this, expr_item_ptr));
}
@@ -514,7 +471,8 @@ sp_head::operator new(size_t size) throw()
MEM_ROOT own_root;
sp_head *sp;
- init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC, MYF(0));
+ init_sql_alloc(&own_root, "sp_head",
+ MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC, MYF(0));
sp= (sp_head *) alloc_root(&own_root, size);
if (sp == NULL)
DBUG_RETURN(NULL);
@@ -563,7 +521,7 @@ sp_head::sp_head(const Sp_handler *sph)
m_defstr(null_clex_str),
m_sp_cache_version(0),
m_creation_ctx(0),
- unsafe_flags(0), m_select_number(1),
+ unsafe_flags(0),
m_created(0),
m_modified(0),
m_recursion_level(0),
@@ -646,7 +604,6 @@ sp_head::set_stmt_end(THD *thd)
{
Lex_input_stream *lip= & thd->m_parser_state->m_lip; /* shortcut */
const char *end_ptr= lip->get_cpp_ptr(); /* shortcut */
- uint not_used;
/* Make the string of parameters. */
@@ -664,7 +621,7 @@ sp_head::set_stmt_end(THD *thd)
m_body.length= end_ptr - m_body_begin;
m_body.str= thd->strmake(m_body_begin, m_body.length);
- trim_whitespace(thd->charset(), &m_body, &not_used);
+ trim_whitespace(thd->charset(), &m_body);
/* Make the string of UTF-body. */
@@ -672,7 +629,7 @@ sp_head::set_stmt_end(THD *thd)
m_body_utf8.length= lip->get_body_utf8_length();
m_body_utf8.str= thd->strmake(lip->get_body_utf8_str(), m_body_utf8.length);
- trim_whitespace(thd->charset(), &m_body_utf8, &not_used);
+ trim_whitespace(thd->charset(), &m_body_utf8);
/*
Make the string of whole stored-program-definition query (in the
@@ -681,7 +638,7 @@ sp_head::set_stmt_end(THD *thd)
m_defstr.length= end_ptr - lip->get_cpp_buf();
m_defstr.str= thd->strmake(lip->get_cpp_buf(), m_defstr.length);
- trim_whitespace(thd->charset(), &m_defstr, &not_used);
+ trim_whitespace(thd->charset(), &m_defstr);
}
@@ -712,7 +669,7 @@ sp_head::~sp_head()
thd->lex->sphead= NULL;
lex_end(thd->lex);
delete thd->lex;
- thd->lex= lex;
+ thd->lex= thd->stmt_lex= lex;
}
my_hash_free(&m_sptabs);
@@ -917,7 +874,7 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
rewritables.sort(cmp_rqp_locations);
- thd->query_name_consts= rewritables.elements();
+ thd->query_name_consts= (uint)rewritables.elements();
for (Rewritable_query_parameter **rqp= rewritables.front();
rqp <= rewritables.back(); rqp++)
@@ -940,14 +897,14 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
<db_name> Name of current database
<flags> Flags struct
*/
- int buf_len= (qbuf.length() + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
- thd->db_length + QUERY_CACHE_FLAGS_SIZE + 1);
+ size_t buf_len= (qbuf.length() + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
+ thd->db.length + QUERY_CACHE_FLAGS_SIZE + 1);
if ((pbuf= (char *) alloc_root(thd->mem_root, buf_len)))
{
char *ptr= pbuf + qbuf.length();
memcpy(pbuf, qbuf.ptr(), qbuf.length());
*ptr= 0;
- int2store(ptr+1, thd->db_length);
+ int2store(ptr+1, thd->db.length);
}
else
DBUG_RETURN(TRUE);
@@ -999,6 +956,12 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
bool err_status= FALSE;
uint ip= 0;
sql_mode_t save_sql_mode;
+
+ // TODO(cvicentiu) See if you can drop this bit. This is used to resume
+ // execution from where we left off.
+ if (m_chistics.agg_type == GROUP_AGGREGATE)
+ ip= thd->spcont->instr_ptr;
+
bool save_abort_on_warning;
Query_arena *old_arena;
/* per-instruction arena */
@@ -1007,12 +970,13 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
backup_arena;
query_id_t old_query_id;
TABLE *old_derived_tables;
- LEX *old_lex;
+ LEX *old_lex, *old_stmt_lex;
Item_change_list old_change_list;
String old_packet;
uint old_server_status;
const uint status_backup_mask= SERVER_STATUS_CURSOR_EXISTS |
SERVER_STATUS_LAST_ROW_SENT;
+ MEM_ROOT *user_var_events_alloc_saved= 0;
Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
Object_creation_ctx *UNINIT_VAR(saved_creation_ctx);
Diagnostics_area *da= thd->get_stmt_da();
@@ -1023,7 +987,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
DBUG_RETURN(TRUE);
/* init per-instruction memroot */
- init_sql_alloc(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(&execute_mem_root, "per_instruction_memroot",
+ MEM_ROOT_BLOCK_SIZE, 0, MYF(0));
DBUG_ASSERT(!(m_flags & IS_INVOKED));
m_flags|= IS_INVOKED;
@@ -1110,11 +1075,12 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
do it in each instruction
*/
old_lex= thd->lex;
+ old_stmt_lex= thd->stmt_lex;
/*
We should also save Item tree change list to avoid rollback something
too early in the calling query.
*/
- thd->change_list.move_elements_to(&old_change_list);
+ thd->Item_change_list::move_elements_to(&old_change_list);
/*
Cursors will use thd->packet, so they may corrupt data which was prepared
for sending by upper level. OTOH cursors in the same routine can share this
@@ -1163,6 +1129,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
#if defined(ENABLED_PROFILING)
thd->profiling.discard_current_query();
#endif
+ thd->spcont->quit_func= TRUE;
break;
}
@@ -1190,9 +1157,11 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
Will write this SP statement into binlog separately.
TODO: consider changing the condition to "not inside event union".
*/
- MEM_ROOT *user_var_events_alloc_saved= thd->user_var_events_alloc;
if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
+ {
+ user_var_events_alloc_saved= thd->user_var_events_alloc;
thd->user_var_events_alloc= thd->mem_root;
+ }
sql_digest_state *parent_digest= thd->m_digest;
thd->m_digest= NULL;
@@ -1232,7 +1201,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
/* Reset sp_rcontext::end_partial_result_set flag. */
ctx->end_partial_result_set= FALSE;
- } while (!err_status && !thd->killed && !thd->is_fatal_error);
+ } while (!err_status && !thd->killed && !thd->is_fatal_error &&
+ !thd->spcont->pause_state);
#if defined(ENABLED_PROFILING)
thd->profiling.finish_current_query();
@@ -1248,14 +1218,20 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
thd->restore_active_arena(&execute_arena, &backup_arena);
- thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error
+ /* Only pop cursors when we're done with group aggregate running. */
+ if (m_chistics.agg_type != GROUP_AGGREGATE ||
+ (m_chistics.agg_type == GROUP_AGGREGATE && thd->spcont->quit_func))
+ thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error
/* Restore all saved */
+ if (m_chistics.agg_type == GROUP_AGGREGATE)
+ thd->spcont->instr_ptr= ip;
thd->server_status= (thd->server_status & ~status_backup_mask) | old_server_status;
old_packet.swap(thd->packet);
- DBUG_ASSERT(thd->change_list.is_empty());
- old_change_list.move_elements_to(&thd->change_list);
+ DBUG_ASSERT(thd->Item_change_list::is_empty());
+ old_change_list.move_elements_to(thd);
thd->lex= old_lex;
+ thd->stmt_lex= old_stmt_lex;
thd->set_query_id(old_query_id);
DBUG_ASSERT(!thd->derived_tables);
thd->derived_tables= old_derived_tables;
@@ -1410,7 +1386,7 @@ set_routine_security_ctx(THD *thd, sp_head *sp, Security_context **save_ctx)
*/
if (*save_ctx &&
check_routine_access(thd, EXECUTE_ACL,
- sp->m_db.str, sp->m_name.str, sp->m_handler, false))
+ &sp->m_db, &sp->m_name, sp->m_handler, false))
{
sp->m_security_ctx.restore_security_context(thd, *save_ctx);
*save_ctx= 0;
@@ -1425,7 +1401,7 @@ set_routine_security_ctx(THD *thd, sp_head *sp, Security_context **save_ctx)
bool sp_head::check_execute_access(THD *thd) const
{
return check_routine_access(thd, EXECUTE_ACL,
- m_db.str, m_name.str,
+ &m_db, &m_name,
m_handler, false);
}
@@ -1527,7 +1503,6 @@ sp_head::execute_trigger(THD *thd,
MEM_ROOT call_mem_root;
Query_arena call_arena(&call_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP);
Query_arena backup_arena;
-
DBUG_ENTER("sp_head::execute_trigger");
DBUG_PRINT("info", ("trigger %s", m_name.str));
@@ -1583,7 +1558,8 @@ sp_head::execute_trigger(THD *thd,
TODO: we should create sp_rcontext once per command and reuse it
on subsequent executions of a trigger.
*/
- init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(&call_mem_root, "execute_trigger", MEM_ROOT_BLOCK_SIZE, 0,
+ MYF(0));
thd->set_n_backup_active_arena(&call_arena, &backup_arena);
Row_definition_list defs;
@@ -1652,18 +1628,16 @@ err_with_cleanup:
bool
sp_head::execute_function(THD *thd, Item **argp, uint argcount,
- Field *return_value_fld)
+ Field *return_value_fld, sp_rcontext **func_ctx,
+ Query_arena *call_arena)
{
ulonglong UNINIT_VAR(binlog_save_options);
bool need_binlog_call= FALSE;
uint arg_no;
sp_rcontext *octx = thd->spcont;
- sp_rcontext *nctx = NULL;
char buf[STRING_BUFFER_USUAL_SIZE];
String binlog_buf(buf, sizeof(buf), &my_charset_bin);
bool err_status= FALSE;
- MEM_ROOT call_mem_root;
- Query_arena call_arena(&call_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP);
Query_arena backup_arena;
DBUG_ENTER("sp_head::execute_function");
DBUG_PRINT("info", ("function %s", m_name.str));
@@ -1696,23 +1670,25 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
TODO: we should create sp_rcontext once per command and reuse
it on subsequent executions of a function/trigger.
*/
- init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(0));
- thd->set_n_backup_active_arena(&call_arena, &backup_arena);
-
- if (!(nctx= rcontext_create(thd, return_value_fld, argp, argcount)))
+ if (!(*func_ctx))
{
- thd->restore_active_arena(&call_arena, &backup_arena);
- err_status= TRUE;
- goto err_with_cleanup;
- }
+ thd->set_n_backup_active_arena(call_arena, &backup_arena);
- /*
- We have to switch temporarily back to callers arena/memroot.
- Function arguments belong to the caller and so the may reference
- memory which they will allocate during calculation long after
- this function call will be finished (e.g. in Item::cleanup()).
- */
- thd->restore_active_arena(&call_arena, &backup_arena);
+ if (!(*func_ctx= rcontext_create(thd, return_value_fld, argp, argcount)))
+ {
+ thd->restore_active_arena(call_arena, &backup_arena);
+ err_status= TRUE;
+ goto err_with_cleanup;
+ }
+
+ /*
+ We have to switch temporarily back to callers arena/memroot.
+ Function arguments belong to the caller and so the may reference
+ memory which they will allocate during calculation long after
+ this function call will be finished (e.g. in Item::cleanup()).
+ */
+ thd->restore_active_arena(call_arena, &backup_arena);
+ }
/* Pass arguments. */
for (arg_no= 0; arg_no < argcount; arg_no++)
@@ -1720,7 +1696,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
/* Arguments must be fixed in Item_func_sp::fix_fields */
DBUG_ASSERT(argp[arg_no]->fixed);
- if ((err_status= nctx->set_variable(thd, arg_no, &(argp[arg_no]))))
+ if ((err_status= (*func_ctx)->set_parameter(thd, arg_no, &(argp[arg_no]))))
goto err_with_cleanup;
}
@@ -1740,9 +1716,9 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
{
binlog_buf.length(0);
binlog_buf.append(STRING_WITH_LEN("SELECT "));
- append_identifier(thd, &binlog_buf, m_db.str, m_db.length);
+ append_identifier(thd, &binlog_buf, &m_db);
binlog_buf.append('.');
- append_identifier(thd, &binlog_buf, m_name.str, m_name.length);
+ append_identifier(thd, &binlog_buf, &m_name);
binlog_buf.append('(');
for (arg_no= 0; arg_no < argcount; arg_no++)
{
@@ -1752,7 +1728,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
if (arg_no)
binlog_buf.append(',');
- Item *item= nctx->get_item(arg_no);
+ Item_field *item= (*func_ctx)->get_parameter(arg_no);
str_value= item->type_handler()->print_item_value(thd, item,
&str_value_holder);
if (str_value)
@@ -1762,7 +1738,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
}
binlog_buf.append(')');
}
- thd->spcont= nctx;
+ thd->spcont= *func_ctx;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *save_security_ctx;
@@ -1803,11 +1779,11 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
sp_rcontext and allocate all these objects (and sp_rcontext
itself) on it directly rather than juggle with arenas.
*/
- thd->set_n_backup_active_arena(&call_arena, &backup_arena);
+ thd->set_n_backup_active_arena(call_arena, &backup_arena);
err_status= execute(thd, TRUE);
- thd->restore_active_arena(&call_arena, &backup_arena);
+ thd->restore_active_arena(call_arena, &backup_arena);
if (need_binlog_call)
{
@@ -1833,11 +1809,11 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
}
}
- if (!err_status)
+ if (!err_status && thd->spcont->quit_func)
{
/* We need result only in function but not in trigger */
- if (!nctx->is_return_value_set())
+ if (!(*func_ctx)->is_return_value_set())
{
my_error(ER_SP_NORETURNEND, MYF(0), m_name.str);
err_status= TRUE;
@@ -1849,9 +1825,6 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
#endif
err_with_cleanup:
- delete nctx;
- call_arena.free_items();
- free_root(&call_mem_root, MYF(0));
thd->spcont= octx;
/*
@@ -1968,7 +1941,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
Item *tmp_item= null_item;
if (!null_item ||
- nctx->set_variable(thd, i, &tmp_item))
+ nctx->set_parameter(thd, i, &tmp_item))
{
DBUG_PRINT("error", ("set variable failed"));
err_status= TRUE;
@@ -1977,7 +1950,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
}
else
{
- if (nctx->set_variable(thd, i, it_args.ref()))
+ if (nctx->set_parameter(thd, i, it_args.ref()))
{
DBUG_PRINT("error", ("set variable 2 failed"));
err_status= TRUE;
@@ -2065,26 +2038,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (!err_status)
{
- /*
- Normally the counter is not reset between parsing and first execution,
- but it is possible in case of error to have parsing on one CALL and
- first execution (where VIEW will be parsed and added). So we store the
- counter after parsing and restore it before execution just to avoid
- repeating SELECT numbers.
- */
- thd->select_number= m_select_number;
-
err_status= execute(thd, TRUE);
- DBUG_PRINT("info", ("execute returned %d", (int) err_status));
- /*
- This execution of the SP was aborted with an error (e.g. "Table not
- found"). However it might still have consumed some numbers from the
- thd->select_number counter. The next sp->exec() call must not use the
- consumed numbers, so we remember the first free number (We know that
- nobody will use it as this execution has stopped with an error).
- */
- if (err_status)
- set_select_number(thd->select_number);
}
if (save_log_general)
@@ -2124,7 +2078,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
DBUG_ASSERT(srp);
- if (srp->set_value(thd, octx, nctx->get_item_addr(i)))
+ if (srp->set_value(thd, octx, nctx->get_variable_addr(i)))
{
DBUG_PRINT("error", ("set value failed"));
err_status= TRUE;
@@ -2132,7 +2086,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
}
Send_field *out_param_info= new (thd->mem_root) Send_field();
- nctx->get_item(i)->make_field(thd, out_param_info);
+ nctx->get_parameter(i)->make_field(thd, out_param_info);
out_param_info->db_name= m_db.str;
out_param_info->table_name= m_name.str;
out_param_info->org_table_name= m_name.str;
@@ -2359,7 +2313,7 @@ sp_head::backpatch_goto(THD *thd, sp_label *lab,sp_label *lab_begin_block)
}
if (bp->instr_type == CPOP)
{
- int n= lab->ctx->diff_cursors(lab_begin_block->ctx, true);
+ uint n= lab->ctx->diff_cursors(lab_begin_block->ctx, true);
if (n == 0)
{
// Remove cpop instr
@@ -2376,7 +2330,7 @@ sp_head::backpatch_goto(THD *thd, sp_label *lab,sp_label *lab_begin_block)
}
if (bp->instr_type == HPOP)
{
- int n= lab->ctx->diff_handlers(lab_begin_block->ctx, true);
+ uint n= lab->ctx->diff_handlers(lab_begin_block->ctx, true);
if (n == 0)
{
// Remove hpop instr
@@ -2404,10 +2358,9 @@ sp_head::check_unresolved_goto()
if (m_backpatch_goto.elements > 0)
{
List_iterator_fast<bp_t> li(m_backpatch_goto);
- bp_t *bp;
- while ((bp= li++))
+ while (bp_t* bp= li++)
{
- if ((bp->instr_type == GOTO))
+ if (bp->instr_type == GOTO)
{
my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "GOTO", bp->lab->name.str);
has_unresolved_label=true;
@@ -2481,7 +2434,6 @@ sp_head::set_chistics(const st_sp_chistics &chistics)
m_chistics.comment.length);
}
-
void
sp_head::set_info(longlong created, longlong modified,
const st_sp_chistics &chistics, sql_mode_t sql_mode)
@@ -2529,6 +2481,7 @@ sp_head::restore_thd_mem_root(THD *thd)
Item *flist= free_list; // The old list
set_query_arena(thd); // Get new free_list and mem_root
state= STMT_INITIALIZED_FOR_SP;
+ is_stored_procedure= true;
DBUG_PRINT("info", ("mem_root %p returned from thd mem root %p",
&mem_root, &thd->mem_root));
@@ -2556,8 +2509,10 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
{
TABLE_LIST tables;
bzero((char*) &tables,sizeof(tables));
- tables.db= (char*) "mysql";
- tables.table_name= tables.alias= (char*) "proc";
+ tables.db= MYSQL_SCHEMA_NAME;
+ tables.table_name= MYSQL_PROC_NAME;
+ tables.alias= MYSQL_PROC_NAME;
+
*full_access= ((!check_table_access(thd, SELECT_ACL, &tables, FALSE,
1, TRUE) &&
(tables.grant.privilege & SELECT_ACL) != 0) ||
@@ -2681,7 +2636,7 @@ sp_head::show_create_routine(THD *thd, const Sp_handler *sph)
Item_empty_string(thd, col1_caption, NAME_CHAR_LEN),
thd->mem_root);
fields.push_back(new (mem_root)
- Item_empty_string(thd, "sql_mode", sql_mode.length),
+ Item_empty_string(thd, "sql_mode", (uint)sql_mode.length),
thd->mem_root);
{
@@ -2692,7 +2647,7 @@ sp_head::show_create_routine(THD *thd, const Sp_handler *sph)
Item_empty_string *stmt_fld=
new (mem_root) Item_empty_string(thd, col3_caption,
- MY_MAX(m_defstr.length, 1024));
+ (uint)MY_MAX(m_defstr.length, 1024));
stmt_fld->maybe_null= TRUE;
@@ -3058,13 +3013,13 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
bool parent_modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table;
thd->transaction.stmt.modified_non_trans_table= FALSE;
DBUG_ASSERT(!thd->derived_tables);
- DBUG_ASSERT(thd->change_list.is_empty());
+ DBUG_ASSERT(thd->Item_change_list::is_empty());
/*
Use our own lex.
We should not save old value since it is saved/restored in
sp_head::execute() when we are entering/leaving routine.
*/
- thd->lex= m_lex;
+ thd->lex= thd->stmt_lex= m_lex;
thd->set_query_id(next_query_id());
@@ -3275,7 +3230,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
Save start time info for the CALL statement and overwrite it with the
current time for log_slow_statement() to log the individual query timing.
*/
- thd->get_time(&time_info);
+ thd->backup_query_start_time(&time_info);
thd->set_time();
}
thd->store_slow_query_state(&backup_state);
@@ -3343,7 +3298,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
}
/* Restore the original query start time */
if (thd->enable_slow_log)
- thd->set_time(&time_info);
+ thd->restore_query_start_time(&time_info);
DBUG_RETURN(res || thd->is_error());
}
@@ -3352,7 +3307,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
void
sp_instr_stmt::print(String *str)
{
- uint i, len;
+ size_t i, len;
/* stmt CMD "..." */
if (str->reserve(SP_STMT_PRINT_MAXLEN+SP_INSTR_UINT_MAXLEN+8))
@@ -3386,7 +3341,7 @@ sp_instr_stmt::exec_core(THD *thd, uint *nextp)
{
MYSQL_QUERY_EXEC_START(thd->query(),
thd->thread_id,
- (char *) (thd->db ? thd->db : ""),
+ thd->get_db(),
&thd->security_ctx->priv_user[0],
(char *)thd->security_ctx->host_or_ip,
3);
@@ -3415,19 +3370,7 @@ int
sp_instr_set::exec_core(THD *thd, uint *nextp)
{
int res= thd->spcont->set_variable(thd, m_offset, &m_value);
-
- if (res)
- {
- /* Failed to evaluate the value. Reset the variable to NULL. */
-
- if (thd->spcont->set_variable(thd, m_offset, 0))
- {
- /* If this also failed, let's abort. */
- my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
- }
- }
delete_explain_query(thd->lex);
-
*nextp = m_ip+1;
return res;
}
@@ -3436,7 +3379,7 @@ void
sp_instr_set::print(String *str)
{
/* set name@offset ... */
- int rsrv = SP_INSTR_UINT_MAXLEN+6;
+ size_t rsrv = SP_INSTR_UINT_MAXLEN+6;
sp_variable *var = m_ctx->find_variable(m_offset);
/* 'var' should always be non-null, but just in case... */
@@ -3466,11 +3409,6 @@ sp_instr_set_row_field::exec_core(THD *thd, uint *nextp)
{
int res= thd->spcont->set_variable_row_field(thd, m_offset, m_field_offset,
&m_value);
- if (res)
- {
- /* Failed to evaluate the value. Reset the variable to NULL. */
- thd->spcont->set_variable_row_field_to_null(thd, m_offset, m_field_offset);
- }
delete_explain_query(thd->lex);
*nextp= m_ip + 1;
return res;
@@ -3481,7 +3419,7 @@ void
sp_instr_set_row_field::print(String *str)
{
/* set name@offset[field_offset] ... */
- int rsrv= SP_INSTR_UINT_MAXLEN + 6 + 6 + 3;
+ size_t rsrv= SP_INSTR_UINT_MAXLEN + 6 + 6 + 3;
sp_variable *var= m_ctx->find_variable(m_offset);
DBUG_ASSERT(var);
DBUG_ASSERT(var->field_def.is_row());
@@ -3514,23 +3452,9 @@ sp_instr_set_row_field::print(String *str)
int
sp_instr_set_row_field_by_name::exec_core(THD *thd, uint *nextp)
{
- int res;
- uint idx;
- Item_field_row *row= (Item_field_row*) thd->spcont->get_item(m_offset);
- if ((res= row->element_index_by_name(&idx, m_field_name)))
- {
- sp_variable *var= m_ctx->find_variable(m_offset);
- my_error(ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD, MYF(0),
- var->name.str, m_field_name.str);
- goto error;
- }
- res= thd->spcont->set_variable_row_field(thd, m_offset, idx, &m_value);
- if (res)
- {
- /* Failed to evaluate the value. Reset the variable to NULL. */
- thd->spcont->set_variable_row_field_to_null(thd, m_offset, idx);
- }
-error:
+ int res= thd->spcont->set_variable_row_field_by_name(thd, m_offset,
+ m_field_name,
+ &m_value);
delete_explain_query(thd->lex);
*nextp= m_ip + 1;
return res;
@@ -3541,7 +3465,7 @@ void
sp_instr_set_row_field_by_name::print(String *str)
{
/* set name.field@offset["field"] ... */
- int rsrv= SP_INSTR_UINT_MAXLEN + 6 + 6 + 3 + 2;
+ size_t rsrv= SP_INSTR_UINT_MAXLEN + 6 + 6 + 3 + 2;
sp_variable *var= m_ctx->find_variable(m_offset);
DBUG_ASSERT(var);
DBUG_ASSERT(var->field_def.is_table_rowtype_ref() ||
@@ -3694,7 +3618,7 @@ sp_instr_jump_if_not::exec_core(THD *thd, uint *nextp)
Item *it;
int res;
- it= sp_prepare_func_item(thd, &m_expr);
+ it= thd->sp_prepare_func_item(&m_expr);
if (! it)
{
res= -1;
@@ -4019,7 +3943,7 @@ sp_instr_cpush::print(String *str)
const LEX_CSTRING *cursor_name= m_ctx->find_cursor(m_cursor);
/* cpush name@offset */
- uint rsrv= SP_INSTR_UINT_MAXLEN+7;
+ size_t rsrv= SP_INSTR_UINT_MAXLEN+7;
if (cursor_name)
rsrv+= cursor_name->length;
@@ -4107,7 +4031,7 @@ sp_instr_copen::print(String *str)
const LEX_CSTRING *cursor_name= m_ctx->find_cursor(m_cursor);
/* copen name@offset */
- uint rsrv= SP_INSTR_UINT_MAXLEN+7;
+ size_t rsrv= SP_INSTR_UINT_MAXLEN+7;
if (cursor_name)
rsrv+= cursor_name->length;
@@ -4149,7 +4073,7 @@ sp_instr_cclose::print(String *str)
const LEX_CSTRING *cursor_name= m_ctx->find_cursor(m_cursor);
/* cclose name@offset */
- uint rsrv= SP_INSTR_UINT_MAXLEN+8;
+ size_t rsrv= SP_INSTR_UINT_MAXLEN+8;
if (cursor_name)
rsrv+= cursor_name->length;
@@ -4177,7 +4101,7 @@ sp_instr_cfetch::execute(THD *thd, uint *nextp)
Query_arena backup_arena;
DBUG_ENTER("sp_instr_cfetch::execute");
- res= c ? c->fetch(thd, &m_varlist) : -1;
+ res= c ? c->fetch(thd, &m_varlist, m_error_on_no_data) : -1;
*nextp= m_ip+1;
DBUG_RETURN(res);
@@ -4192,7 +4116,7 @@ sp_instr_cfetch::print(String *str)
const LEX_CSTRING *cursor_name= m_ctx->find_cursor(m_cursor);
/* cfetch name@offset vars... */
- uint rsrv= SP_INSTR_UINT_MAXLEN+8;
+ size_t rsrv= SP_INSTR_UINT_MAXLEN+8;
if (cursor_name)
rsrv+= cursor_name->length;
@@ -4216,6 +4140,35 @@ sp_instr_cfetch::print(String *str)
}
}
+int
+sp_instr_agg_cfetch::execute(THD *thd, uint *nextp)
+{
+ DBUG_ENTER("sp_instr_cfetch::execute");
+ int res= 0;
+ if (!thd->spcont->instr_ptr)
+ {
+ *nextp= m_ip+1;
+ thd->spcont->instr_ptr= m_ip + 1;
+ }
+ else if (!thd->spcont->pause_state)
+ thd->spcont->pause_state= TRUE;
+ else
+ {
+ thd->spcont->pause_state= FALSE;
+ if (thd->server_status == SERVER_STATUS_LAST_ROW_SENT)
+ {
+ my_message(ER_SP_FETCH_NO_DATA,
+ ER_THD(thd, ER_SP_FETCH_NO_DATA), MYF(0));
+ res= -1;
+ thd->spcont->quit_func= TRUE;
+ }
+ else
+ *nextp= m_ip + 1;
+ }
+ DBUG_RETURN(res);
+}
+
+
/*
sp_instr_cursor_copy_struct class functions
@@ -4234,7 +4187,7 @@ sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp)
{
DBUG_ENTER("sp_instr_cursor_copy_struct::exec_core");
int ret= 0;
- Item_field_row *row= (Item_field_row*) thd->spcont->get_item(m_var);
+ Item_field_row *row= (Item_field_row*) thd->spcont->get_variable(m_var);
DBUG_ASSERT(row->type_handler() == &type_handler_row);
/*
@@ -4418,7 +4371,7 @@ typedef struct st_sp_table
db_name\0table_name\0 - for temporary tables
*/
LEX_STRING qname;
- uint db_length, table_name_length;
+ size_t db_length, table_name_length;
bool temp; /* true if corresponds to a temporary table */
thr_lock_type lock_type; /* lock type used for prelocking */
uint lock_count;
@@ -4486,12 +4439,12 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
uint temp_table_key_length;
tname.length(0);
- tname.append(table->db, table->db_length);
+ tname.append(&table->db);
tname.append('\0');
- tname.append(table->table_name, table->table_name_length);
+ tname.append(&table->table_name);
tname.append('\0');
temp_table_key_length= tname.length();
- tname.append(table->alias);
+ tname.append(&table->alias);
tname.append('\0');
/*
@@ -4537,8 +4490,8 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
tab->qname.str= (char*) thd->memdup(tname.ptr(), tab->qname.length);
if (!tab->qname.str)
return FALSE;
- tab->table_name_length= table->table_name_length;
- tab->db_length= table->db_length;
+ tab->table_name_length= table->table_name.length;
+ tab->db_length= table->db.length;
tab->lock_type= table->lock_type;
tab->lock_count= tab->query_lock_count= 1;
tab->trg_event_map= table->trg_event_map;
@@ -4595,8 +4548,8 @@ sp_head::add_used_tables_to_table_list(THD *thd,
for (i=0 ; i < m_sptabs.records ; i++)
{
char *tab_buff, *key_buff;
- TABLE_LIST *table;
SP_TABLE *stab= (SP_TABLE*) my_hash_element(&m_sptabs, i);
+ LEX_CSTRING db_name;
if (stab->temp)
continue;
@@ -4606,15 +4559,26 @@ sp_head::add_used_tables_to_table_list(THD *thd,
stab->qname.length)))
DBUG_RETURN(FALSE);
+ db_name.str= key_buff;
+ db_name.length= stab->db_length;
+
+
for (uint j= 0; j < stab->lock_count; j++)
{
- table= (TABLE_LIST *)tab_buff;
- table->init_one_table_for_prelocking(key_buff, stab->db_length,
- key_buff + stab->db_length + 1, stab->table_name_length,
- key_buff + stab->db_length + stab->table_name_length + 2,
- stab->lock_type, true, belong_to_view, stab->trg_event_map,
- query_tables_last_ptr);
-
+ TABLE_LIST *table= (TABLE_LIST *)tab_buff;
+ LEX_CSTRING table_name= { key_buff + stab->db_length + 1,
+ stab->table_name_length };
+ LEX_CSTRING alias= { table_name.str + table_name.length + 1,
+ strlen(table_name.str + table_name.length + 1) };
+
+ table->init_one_table_for_prelocking(&db_name,
+ &table_name,
+ &alias,
+ stab->lock_type,
+ TABLE_LIST::PRELOCK_ROUTINE,
+ belong_to_view,
+ stab->trg_event_map,
+ query_tables_last_ptr);
tab_buff+= ALIGN_SIZE(sizeof(TABLE_LIST));
result= TRUE;
}
@@ -4634,7 +4598,7 @@ sp_head::add_used_tables_to_table_list(THD *thd,
TABLE_LIST *
sp_add_to_query_tables(THD *thd, LEX *lex,
- const char *db, const char *name,
+ const LEX_CSTRING *db, const LEX_CSTRING *name,
thr_lock_type locktype,
enum_mdl_type mdl_type)
{
@@ -4642,15 +4606,15 @@ sp_add_to_query_tables(THD *thd, LEX *lex,
if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
return NULL;
- table->db_length= strlen(db);
- table->db= thd->strmake(db, table->db_length);
- table->table_name_length= strlen(name);
- table->table_name= thd->strmake(name, table->table_name_length);
- table->alias= thd->strdup(name);
+ if (!thd->make_lex_string(&table->db, db->str, db->length) ||
+ !thd->make_lex_string(&table->table_name, name->str, name->length) ||
+ !thd->make_lex_string(&table->alias, name->str, name->length))
+ return NULL;
+
table->lock_type= locktype;
table->select_lex= lex->current_select;
table->cacheable_table= 1;
- table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name,
+ table->mdl_request.init(MDL_key::TABLE, table->db.str, table->table_name.str,
mdl_type, MDL_TRANSACTION);
lex->add_to_query_tables(table);
@@ -4777,7 +4741,7 @@ bool sp_head::add_for_loop_open_cursor(THD *thd, sp_pcontext *spcont,
sp_instr_cfetch *instr_cfetch=
new (thd->mem_root) sp_instr_cfetch(instructions(),
- spcont, coffset);
+ spcont, coffset, false);
if (instr_cfetch == NULL || add_instr(instr_cfetch))
return true;
instr_cfetch->add_to_varlist(index);
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 734c0dea3e3..7f041058829 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -164,7 +164,10 @@ public:
/*
Marks routines that have column type references: DECLARE a t1.a%TYPE;
*/
- HAS_COLUMN_TYPE_REFS= 8192
+ HAS_COLUMN_TYPE_REFS= 8192,
+ /* Set if has FETCH GROUP NEXT ROW instr. Used to ensure that only
+ functions with AGGREGATE keyword use the instr. */
+ HAS_AGGREGATE_INSTR= 16384
};
const Sp_handler *m_handler;
@@ -197,6 +200,7 @@ public:
enum_sp_suid_behaviour suid() const { return m_chistics.suid; }
bool detistic() const { return m_chistics.detistic; }
enum_sp_data_access daccess() const { return m_chistics.daccess; }
+ enum_sp_aggregate_type agg_type() const { return m_chistics.agg_type; }
/**
Is this routine being executed?
*/
@@ -209,7 +213,7 @@ public:
ulong sp_cache_version() const { return m_sp_cache_version; }
/** Set the value of the SP cache version. */
- void set_sp_cache_version(ulong version_arg)
+ void set_sp_cache_version(ulong version_arg) const
{
m_sp_cache_version= version_arg;
}
@@ -231,7 +235,7 @@ private:
is obsolete and should not be used --
sp_cache_flush_obsolete() will purge it.
*/
- ulong m_sp_cache_version;
+ mutable ulong m_sp_cache_version;
Stored_program_creation_ctx *m_creation_ctx;
/**
Boolean combination of (1<<flag), where flag is a member of
@@ -239,7 +243,6 @@ private:
*/
uint32 unsafe_flags;
- uint m_select_number;
public:
inline Stored_program_creation_ctx *get_creation_ctx()
{
@@ -343,7 +346,8 @@ public:
GRANT_INFO *grant_info);
bool
- execute_function(THD *thd, Item **args, uint argcount, Field *return_fld);
+ execute_function(THD *thd, Item **args, uint argcount, Field *return_fld,
+ sp_rcontext **nctx, Query_arena *call_arena);
bool
execute_procedure(THD *thd, List<Item> *args);
@@ -719,10 +723,14 @@ public:
const LEX_CSTRING &table);
void set_chistics(const st_sp_chistics &chistics);
+ inline void set_chistics_agg_type(enum enum_sp_aggregate_type type)
+ {
+ m_chistics.agg_type= type;
+ }
void set_info(longlong created, longlong modified,
const st_sp_chistics &chistics, sql_mode_t sql_mode);
- void set_definer(const char *definer, uint definerlen)
+ void set_definer(const char *definer, size_t definerlen)
{
AUTHID tmp;
tmp.parse(definer, definerlen);
@@ -822,8 +830,6 @@ public:
sp_pcontext *get_parse_context() { return m_pcont; }
- void set_select_number(uint num) { m_select_number= num; }
-
bool check_execute_access(THD *thd) const;
private:
@@ -1795,8 +1801,8 @@ class sp_instr_cfetch : public sp_instr
public:
- sp_instr_cfetch(uint ip, sp_pcontext *ctx, uint c)
- : sp_instr(ip, ctx), m_cursor(c)
+ sp_instr_cfetch(uint ip, sp_pcontext *ctx, uint c, bool error_on_no_data)
+ : sp_instr(ip, ctx), m_cursor(c), m_error_on_no_data(error_on_no_data)
{
m_varlist.empty();
}
@@ -1817,9 +1823,36 @@ private:
uint m_cursor;
List<sp_variable> m_varlist;
+ bool m_error_on_no_data;
}; // class sp_instr_cfetch : public sp_instr
+/*
+This class is created for the special fetch instruction
+FETCH GROUP NEXT ROW, used in the user-defined aggregate
+functions
+*/
+
+class sp_instr_agg_cfetch : public sp_instr
+{
+ sp_instr_agg_cfetch(const sp_instr_cfetch &); /**< Prevent use of these */
+ void operator=(sp_instr_cfetch &);
+
+public:
+
+ sp_instr_agg_cfetch(uint ip, sp_pcontext *ctx)
+ : sp_instr(ip, ctx){}
+
+ virtual ~sp_instr_agg_cfetch()
+ {}
+
+ virtual int execute(THD *thd, uint *nextp);
+
+ virtual void print(String *str){};
+}; // class sp_instr_agg_cfetch : public sp_instr
+
+
+
class sp_instr_error : public sp_instr
{
@@ -1904,17 +1937,10 @@ set_routine_security_ctx(THD *thd, sp_head *sp, Security_context **save_ctx);
TABLE_LIST *
sp_add_to_query_tables(THD *thd, LEX *lex,
- const char *db, const char *name,
+ const LEX_CSTRING *db, const LEX_CSTRING *name,
thr_lock_type locktype,
enum_mdl_type mdl_type);
-Item *
-sp_prepare_func_item(THD* thd, Item **it_addr, uint cols= 1);
-
-bool
-sp_eval_expr(THD *thd, Item *result_item, Field *result_field,
- Item **expr_item_ptr);
-
/**
@} (end of group Stored_Routines)
*/
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc
index 1e2081e3479..83d674e7500 100644
--- a/sql/sp_pcontext.cc
+++ b/sql/sp_pcontext.cc
@@ -171,12 +171,12 @@ uint sp_pcontext::diff_handlers(const sp_pcontext *ctx, bool exclusive) const
while (pctx && pctx != ctx)
{
- n+= pctx->m_handlers.elements();
+ n+= (uint)pctx->m_handlers.elements();
last_ctx= pctx;
pctx= pctx->parent_context();
}
if (pctx)
- return (exclusive && last_ctx ? n - last_ctx->m_handlers.elements() : n);
+ return (exclusive && last_ctx ? n -(uint) last_ctx->m_handlers.elements() : n);
return 0; // Didn't find ctx
}
@@ -189,12 +189,12 @@ uint sp_pcontext::diff_cursors(const sp_pcontext *ctx, bool exclusive) const
while (pctx && pctx != ctx)
{
- n+= pctx->m_cursors.elements();
+ n+= (uint)pctx->m_cursors.elements();
last_ctx= pctx;
pctx= pctx->parent_context();
}
if (pctx)
- return (exclusive && last_ctx ? n - last_ctx->m_cursors.elements() : n);
+ return (exclusive && last_ctx ? (uint)(n - last_ctx->m_cursors.elements()) : n);
return 0; // Didn't find ctx
}
@@ -202,7 +202,7 @@ uint sp_pcontext::diff_cursors(const sp_pcontext *ctx, bool exclusive) const
sp_variable *sp_pcontext::find_variable(const LEX_CSTRING *name,
bool current_scope_only) const
{
- uint i= m_vars.elements() - m_pboundary;
+ size_t i= m_vars.elements() - m_pboundary;
while (i--)
{
@@ -392,7 +392,7 @@ bool sp_pcontext::add_condition(THD *thd,
sp_condition_value *sp_pcontext::find_condition(const LEX_CSTRING *name,
bool current_scope_only) const
{
- uint i= m_conditions.elements();
+ size_t i= m_conditions.elements();
while (i--)
{
@@ -423,12 +423,12 @@ static sp_condition_value
static sp_condition sp_predefined_conditions[]=
{
// Warnings
- sp_condition(C_STRING_WITH_LEN("NO_DATA_FOUND"), &cond_no_data_found),
+ sp_condition(STRING_WITH_LEN("NO_DATA_FOUND"), &cond_no_data_found),
// Errors
- sp_condition(C_STRING_WITH_LEN("INVALID_CURSOR"), &cond_invalid_cursor),
- sp_condition(C_STRING_WITH_LEN("DUP_VAL_ON_INDEX"), &cond_dup_val_on_index),
- sp_condition(C_STRING_WITH_LEN("DUP_VAL_ON_INDEX"), &cond_dup_val_on_index2),
- sp_condition(C_STRING_WITH_LEN("TOO_MANY_ROWS"), &cond_too_many_rows)
+ sp_condition(STRING_WITH_LEN("INVALID_CURSOR"), &cond_invalid_cursor),
+ sp_condition(STRING_WITH_LEN("DUP_VAL_ON_INDEX"), &cond_dup_val_on_index),
+ sp_condition(STRING_WITH_LEN("DUP_VAL_ON_INDEX"), &cond_dup_val_on_index2),
+ sp_condition(STRING_WITH_LEN("TOO_MANY_ROWS"), &cond_too_many_rows)
};
@@ -605,7 +605,7 @@ const sp_pcursor *sp_pcontext::find_cursor(const LEX_CSTRING *name,
uint *poff,
bool current_scope_only) const
{
- uint i= m_cursors.elements();
+ uint i= (uint)m_cursors.elements();
while (i--)
{
diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h
index 990ad35cb57..6a6920d89e1 100644
--- a/sql/sp_pcontext.h
+++ b/sql/sp_pcontext.h
@@ -673,7 +673,7 @@ public:
{ return m_cursor_offset; }
uint frame_cursor_count() const
- { return m_cursors.elements(); }
+ { return (uint)m_cursors.elements(); }
uint max_cursor_index() const
{ return m_max_cursor_index + (uint)m_cursors.elements(); }
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 6716aa54170..4009f8dce30 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -40,6 +40,7 @@ sp_rcontext::sp_rcontext(const sp_head *owner,
Field *return_value_fld,
bool in_sub_stmt)
:end_partial_result_set(false),
+ pause_state(false), quit_func(false), instr_ptr(0),
m_sp(owner),
m_root_parsing_ctx(root_parsing_ctx),
m_var_table(NULL),
@@ -66,6 +67,7 @@ sp_rcontext *sp_rcontext::create(THD *thd,
Field *return_value_fld,
Row_definition_list &field_def_lst)
{
+ SELECT_LEX *save_current_select;
sp_rcontext *ctx= new (thd->mem_root) sp_rcontext(owner,
root_parsing_ctx,
return_value_fld,
@@ -73,14 +75,19 @@ sp_rcontext *sp_rcontext::create(THD *thd,
if (!ctx)
return NULL;
+ /* Reset current_select as it's checked in Item_ident::Item_ident */
+ save_current_select= thd->lex->current_select;
+ thd->lex->current_select= 0;
+
if (ctx->alloc_arrays(thd) ||
ctx->init_var_table(thd, field_def_lst) ||
ctx->init_var_items(thd, field_def_lst))
{
delete ctx;
- return NULL;
+ ctx= 0;
}
+ thd->lex->current_select= save_current_select;
return ctx;
}
@@ -309,7 +316,7 @@ bool sp_rcontext::init_var_items(THD *thd,
uint num_vars= m_root_parsing_ctx->max_var_index();
m_var_items.reset(
- static_cast<Item **> (
+ static_cast<Item_field **> (
thd->alloc(num_vars * sizeof (Item *))),
num_vars);
@@ -380,22 +387,13 @@ bool Item_field_row::row_create_items(THD *thd, List<Spvar_definition> *list)
}
-Field *Item_field_row::get_row_field(uint i) const
-{
- DBUG_ASSERT(field);
- Virtual_tmp_table **ptable= field->virtual_tmp_table_addr();
- DBUG_ASSERT(ptable);
- return ptable[0]->field[i];
-}
-
-
bool sp_rcontext::set_return_value(THD *thd, Item **return_value_item)
{
DBUG_ASSERT(m_return_value_fld);
m_return_value_set = true;
- return sp_eval_expr(thd, NULL, m_return_value_fld, return_value_item);
+ return thd->sp_eval_expr(m_return_value_fld, return_value_item);
}
@@ -415,7 +413,7 @@ bool sp_rcontext::push_cursor(THD *thd, sp_lex_keeper *lex_keeper)
}
-void sp_rcontext::pop_cursors(uint count)
+void sp_rcontext::pop_cursors(size_t count)
{
DBUG_ASSERT(m_ccount >= count);
@@ -604,100 +602,64 @@ uint sp_rcontext::exit_handler(Diagnostics_area *da)
int sp_rcontext::set_variable(THD *thd, uint idx, Item **value)
{
- Field *field= m_var_table->field[idx];
- if (!value)
- {
- field->set_null();
- return 0;
- }
- Item *dst= m_var_items[idx];
-
- if (dst->cmp_type() != ROW_RESULT)
- return sp_eval_expr(thd, dst, m_var_table->field[idx], value);
+ DBUG_ENTER("sp_rcontext::set_variable");
+ DBUG_ASSERT(value);
+ DBUG_RETURN(thd->sp_eval_expr(m_var_table->field[idx], value));
+}
- DBUG_ASSERT(dst->type() == Item::FIELD_ITEM);
- if (value[0]->type() == Item::NULL_ITEM)
- {
- /*
- We're in a auto-generated sp_inst_set, to assign
- the explicit default NULL value to a ROW variable.
- */
- for (uint i= 0; i < dst->cols(); i++)
- {
- Item_field_row *item_field_row= (Item_field_row*) dst;
- item_field_row->get_row_field(i)->set_null();
- }
- return false;
- }
- /**
- - In case if we're assigning a ROW variable from another ROW variable,
- value[0] points to Item_splocal. sp_prepare_func_item() will return the
- fixed underlying Item_field_spvar with ROW members in its aguments().
- - In case if we're assigning from a ROW() value, src and value[0] will
- point to the same Item_row.
- */
- Item *src;
- if (!(src= sp_prepare_func_item(thd, value, dst->cols())) ||
- src->cmp_type() != ROW_RESULT)
- {
- my_error(ER_OPERAND_COLUMNS, MYF(0), dst->cols());
- return true;
- }
- DBUG_ASSERT(dst->cols() == src->cols());
- for (uint i= 0; i < src->cols(); i++)
- set_variable_row_field(thd, idx, i, src->addr(i));
- return false;
+int sp_rcontext::set_variable_row_field(THD *thd, uint var_idx, uint field_idx,
+ Item **value)
+{
+ DBUG_ENTER("sp_rcontext::set_variable_row_field");
+ DBUG_ASSERT(value);
+ Virtual_tmp_table *vtable= virtual_tmp_table_for_row(var_idx);
+ DBUG_RETURN(thd->sp_eval_expr(vtable->field[field_idx], value));
}
-void sp_rcontext::set_variable_row_field_to_null(THD *thd,
- uint var_idx,
- uint field_idx)
+int sp_rcontext::set_variable_row_field_by_name(THD *thd, uint var_idx,
+ const LEX_CSTRING &field_name,
+ Item **value)
{
- Item *dst= get_item(var_idx);
- DBUG_ASSERT(dst->type() == Item::FIELD_ITEM);
- DBUG_ASSERT(dst->cmp_type() == ROW_RESULT);
- Item_field_row *item_field_row= (Item_field_row*) dst;
- item_field_row->get_row_field(field_idx)->set_null();
+ DBUG_ENTER("sp_rcontext::set_variable_row_field_by_name");
+ uint field_idx;
+ if (find_row_field_by_name_or_error(&field_idx, var_idx, field_name))
+ DBUG_RETURN(1);
+ DBUG_RETURN(set_variable_row_field(thd, var_idx, field_idx, value));
}
-int sp_rcontext::set_variable_row_field(THD *thd, uint var_idx, uint field_idx,
- Item **value)
+int sp_rcontext::set_variable_row(THD *thd, uint var_idx, List<Item> &items)
{
- DBUG_ASSERT(value);
- Item *dst= get_item(var_idx);
- DBUG_ASSERT(dst->type() == Item::FIELD_ITEM);
- DBUG_ASSERT(dst->cmp_type() == ROW_RESULT);
- Item_field_row *item_field_row= (Item_field_row*) dst;
+ DBUG_ENTER("sp_rcontext::set_variable_row");
+ DBUG_ASSERT(get_variable(var_idx)->cols() == items.elements);
+ Virtual_tmp_table *vtable= virtual_tmp_table_for_row(var_idx);
+ Sp_eval_expr_state state(thd);
+ DBUG_RETURN(vtable->sp_set_all_fields_from_item_list(thd, items));
+}
- Item *expr_item= sp_prepare_func_item(thd, value);
- if (!expr_item)
- {
- DBUG_ASSERT(thd->is_error());
- return true;
- }
- return sp_eval_expr(thd,
- item_field_row->arguments()[field_idx],
- item_field_row->get_row_field(field_idx),
- value);
+
+Virtual_tmp_table *sp_rcontext::virtual_tmp_table_for_row(uint var_idx)
+{
+ DBUG_ASSERT(get_variable(var_idx)->type() == Item::FIELD_ITEM);
+ DBUG_ASSERT(get_variable(var_idx)->cmp_type() == ROW_RESULT);
+ Field *field= m_var_table->field[var_idx];
+ Virtual_tmp_table **ptable= field->virtual_tmp_table_addr();
+ DBUG_ASSERT(ptable);
+ DBUG_ASSERT(ptable[0]);
+ return ptable[0];
}
-int sp_rcontext::set_variable_row(THD *thd, uint var_idx, List<Item> &items)
+bool sp_rcontext::find_row_field_by_name_or_error(uint *field_idx,
+ uint var_idx,
+ const LEX_CSTRING &field_name)
{
- DBUG_ENTER("sp_rcontext::set_variable_row");
- DBUG_ASSERT(get_item(var_idx)->cols() == items.elements);
- List_iterator<Item> it(items);
- Item *item;
- for (uint i= 0 ; (item= it++) ; i++)
- {
- int rc;
- if ((rc= set_variable_row_field(thd, var_idx, i, &item)))
- DBUG_RETURN(rc);
- }
- DBUG_RETURN(0);
+ Virtual_tmp_table *vtable= virtual_tmp_table_for_row(var_idx);
+ Field *row= m_var_table->field[var_idx];
+ return vtable->sp_find_field_by_name_or_error(field_idx,
+ row->field_name, field_name);
}
@@ -720,7 +682,7 @@ Item_cache *sp_rcontext::create_case_expr_holder(THD *thd,
bool sp_rcontext::set_case_expr(THD *thd, int case_expr_id,
Item **case_expr_item_ptr)
{
- Item *case_expr_item= sp_prepare_func_item(thd, case_expr_item_ptr);
+ Item *case_expr_item= thd->sp_prepare_func_item(case_expr_item_ptr);
if (!case_expr_item)
return true;
@@ -800,7 +762,13 @@ int sp_cursor::open_view_structure_only(THD *thd)
if (!(thd->lex->limit_rows_examined= new (thd->mem_root) Item_uint(thd, 0)))
return -1;
thd->no_errors= true; // Suppress ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT
+ DBUG_ASSERT(!thd->killed);
res= open(thd);
+ /*
+ The query possibly exited on LIMIT ROWS EXAMINED and set thd->killed.
+ Reset it now.
+ */
+ thd->reset_killed();
thd->no_errors= thd_no_errors_save;
thd->lex->limit_rows_examined= limit_rows_examined;
return res;
@@ -829,7 +797,7 @@ void sp_cursor::destroy()
}
-int sp_cursor::fetch(THD *thd, List<sp_variable> *vars)
+int sp_cursor::fetch(THD *thd, List<sp_variable> *vars, bool error_on_no_data)
{
if (! server_side_cursor)
{
@@ -840,7 +808,7 @@ int sp_cursor::fetch(THD *thd, List<sp_variable> *vars)
if (vars->elements != result.get_field_count() &&
(vars->elements != 1 ||
result.get_field_count() !=
- thd->spcont->get_item(vars->head()->offset)->cols()))
+ thd->spcont->get_variable(vars->head()->offset)->cols()))
{
my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS,
ER_THD(thd, ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0));
@@ -866,7 +834,7 @@ int sp_cursor::fetch(THD *thd, List<sp_variable> *vars)
if (! server_side_cursor->is_open())
{
m_found= false;
- if (thd->variables.sql_mode & MODE_ORACLE)
+ if (!error_on_no_data)
return 0;
my_message(ER_SP_FETCH_NO_DATA, ER_THD(thd, ER_SP_FETCH_NO_DATA), MYF(0));
return -1;
@@ -938,7 +906,7 @@ int sp_cursor::Select_fetch_into_spvars::send_data(List<Item> &items)
on attempt to assign a scalar value to a ROW variable.
*/
return spvar_list->elements == 1 &&
- (item= thd->spcont->get_item(spvar_list->head()->offset)) &&
+ (item= thd->spcont->get_variable(spvar_list->head()->offset)) &&
item->type_handler() == &type_handler_row &&
item->cols() == items.elements ?
thd->spcont->set_variable_row(thd, spvar_list->head()->offset, items) :
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
index 658972ece40..c4f4cf182da 100644
--- a/sql/sp_rcontext.h
+++ b/sql/sp_rcontext.h
@@ -178,6 +178,9 @@ public:
/// (if one is found). Otherwise the client will hang due to a violation
/// of the client/server protocol.
bool end_partial_result_set;
+ bool pause_state;
+ bool quit_func;
+ uint instr_ptr;
/// The stored program for which this runtime context is created. Used for
/// checking if correct runtime context is used for variable handling.
@@ -188,16 +191,39 @@ public:
// SP-variables.
/////////////////////////////////////////////////////////////////////////
+ uint argument_count() const
+ {
+ return m_root_parsing_ctx->context_var_count();
+ }
+
int set_variable(THD *thd, uint var_idx, Item **value);
- void set_variable_row_field_to_null(THD *thd, uint var_idx, uint field_idx);
int set_variable_row_field(THD *thd, uint var_idx, uint field_idx,
Item **value);
+ int set_variable_row_field_by_name(THD *thd, uint var_idx,
+ const LEX_CSTRING &field_name,
+ Item **value);
int set_variable_row(THD *thd, uint var_idx, List<Item> &items);
- Item *get_item(uint var_idx) const
+
+ int set_parameter(THD *thd, uint var_idx, Item **value)
+ {
+ DBUG_ASSERT(var_idx < argument_count());
+ return set_variable(thd, var_idx, value);
+ }
+
+ Item_field *get_variable(uint var_idx) const
{ return m_var_items[var_idx]; }
- Item **get_item_addr(uint var_idx) const
- { return m_var_items.array() + var_idx; }
+ Item **get_variable_addr(uint var_idx) const
+ { return ((Item **) m_var_items.array()) + var_idx; }
+
+ Item_field *get_parameter(uint var_idx) const
+ {
+ DBUG_ASSERT(var_idx < argument_count());
+ return get_variable(var_idx);
+ }
+
+ bool find_row_field_by_name_or_error(uint *field_idx, uint var_idx,
+ const LEX_CSTRING &field_name);
bool set_return_value(THD *thd, Item **return_value_item);
@@ -279,7 +305,7 @@ public:
/// Pop and delete given number of sp_cursor instance from the cursor stack.
///
/// @param count Number of cursors to pop & delete.
- void pop_cursors(uint count);
+ void pop_cursors(size_t count);
void pop_all_cursors()
{ pop_cursors(m_ccount); }
@@ -362,6 +388,8 @@ private:
/// @return Pointer to valid object on success, or NULL in case of error.
Item_cache *create_case_expr_holder(THD *thd, const Item *item) const;
+ Virtual_tmp_table *virtual_tmp_table_for_row(uint idx);
+
private:
/// Top-level (root) parsing context for this runtime context.
const sp_pcontext *m_root_parsing_ctx;
@@ -371,7 +399,7 @@ private:
/// Collection of Item_field proxies, each of them points to the
/// corresponding field in m_var_table.
- Bounds_checked_array<Item *> m_var_items;
+ Bounds_checked_array<Item_field *> m_var_items;
/// This is a pointer to a field, which should contain return value for
/// stored functions (only). For stored procedures, this pointer is NULL.
@@ -455,7 +483,7 @@ public:
ulonglong fetch_count() const
{ return m_fetch_count; }
- int fetch(THD *, List<sp_variable> *vars);
+ int fetch(THD *, List<sp_variable> *vars, bool error_on_no_data);
bool export_structure(THD *thd, Row_definition_list *list);
diff --git a/sql/spatial.cc b/sql/spatial.cc
index 19035a4e882..255ba3f0647 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -142,7 +142,7 @@ static void get_point(double *x, double *y, const char *data)
/***************************** Geometry *******************************/
-Geometry::Class_info *Geometry::find_class(const char *name, uint32 len)
+Geometry::Class_info *Geometry::find_class(const char *name, size_t len)
{
for (Class_info **cur_rt= ci_collection;
cur_rt < ci_collection_end; cur_rt++)
@@ -1041,7 +1041,7 @@ bool Gis_line_string::init_from_json(json_engine_t *je, bool er_on_3D,
}
if (n_points < 1)
{
- je->s.error= GEOJ_TOO_FEW_POINTS;
+ je->s.error= Geometry::GEOJ_TOO_FEW_POINTS;
return TRUE;
}
wkb->write_at_position(np_pos, n_points);
@@ -1440,6 +1440,15 @@ bool Gis_polygon::init_from_json(json_engine_t *je, bool er_on_3D, String *wkb)
}
n_linear_rings++;
}
+
+ if (je->s.error)
+ return TRUE;
+
+ if (n_linear_rings == 0)
+ {
+ je->s.error= Geometry::GEOJ_EMPTY_COORDINATES;
+ return TRUE;
+ }
wkb->write_at_position(lr_pos, n_linear_rings);
return FALSE;
}
@@ -1945,6 +1954,14 @@ bool Gis_multi_point::init_from_json(json_engine_t *je, bool er_on_3D,
n_points++;
}
+ if (je->s.error)
+ return TRUE;
+ if (n_points == 0)
+ {
+ je->s.error= Geometry::GEOJ_EMPTY_COORDINATES;
+ return TRUE;
+ }
+
wkb->write_at_position(np_pos, n_points);
return FALSE;
}
@@ -2214,6 +2231,15 @@ bool Gis_multi_line_string::init_from_json(json_engine_t *je, bool er_on_3D,
n_line_strings++;
}
+ if (je->s.error)
+ return TRUE;
+
+ if (n_line_strings == 0)
+ {
+ je->s.error= Geometry::GEOJ_EMPTY_COORDINATES;
+ return TRUE;
+ }
+
wkb->write_at_position(ls_pos, n_line_strings);
return FALSE;
}
@@ -2603,6 +2629,13 @@ bool Gis_multi_polygon::init_from_json(json_engine_t *je, bool er_on_3D,
n_polygons++;
}
+ if (je->s.error)
+ return TRUE;
+ if (n_polygons == 0)
+ {
+ je->s.error= Geometry::GEOJ_EMPTY_COORDINATES;
+ return TRUE;
+ }
wkb->write_at_position(np_pos, n_polygons);
return FALSE;
}
diff --git a/sql/spatial.h b/sql/spatial.h
index 78e850dc2d7..5818607de26 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -256,6 +256,7 @@ public:
GEOJ_TOO_FEW_POINTS= 2,
GEOJ_POLYGON_NOT_CLOSED= 3,
GEOJ_DIMENSION_NOT_SUPPORTED= 4,
+ GEOJ_EMPTY_COORDINATES= 5,
};
@@ -346,7 +347,7 @@ protected:
return ((type_id < wkb_point) || (type_id > wkb_last)) ?
NULL : ci_collection[type_id];
}
- static Class_info *find_class(const char *name, uint32 len);
+ static Class_info *find_class(const char *name, size_t len);
const char *append_points(String *txt, uint32 n_points,
const char *data, uint32 offset) const;
bool create_point(String *result, const char *data) const;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 7e31d448bdf..96ed36da755 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -59,123 +59,6 @@
bool mysql_user_table_is_in_short_password_format= false;
-static const
-TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = {
- {
- { C_STRING_WITH_LEN("Host") },
- { C_STRING_WITH_LEN("char(60)") },
- {NULL, 0}
- },
- {
- { C_STRING_WITH_LEN("Db") },
- { C_STRING_WITH_LEN("char(64)") },
- {NULL, 0}
- },
- {
- { C_STRING_WITH_LEN("User") },
- { C_STRING_WITH_LEN("char(") },
- {NULL, 0}
- },
- {
- { C_STRING_WITH_LEN("Select_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Insert_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Update_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Delete_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Create_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Drop_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Grant_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("References_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Index_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Alter_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Create_tmp_table_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Lock_tables_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Create_view_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Show_view_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Create_routine_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Alter_routine_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Execute_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Event_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- },
- {
- { C_STRING_WITH_LEN("Trigger_priv") },
- { C_STRING_WITH_LEN("enum('N','Y')") },
- { C_STRING_WITH_LEN("utf8") }
- }
-};
-
-const TABLE_FIELD_DEF
-mysql_db_table_def= {MYSQL_DB_FIELD_COUNT, mysql_db_table_fields, 0, (uint*) 0 };
-
static LEX_CSTRING native_password_plugin_name= {
STRING_WITH_LEN("mysql_native_password")
};
@@ -242,7 +125,7 @@ class ACL_USER_BASE :public ACL_ACCESS
public:
static void *operator new(size_t size, MEM_ROOT *mem_root)
{ return (void*) alloc_root(mem_root, size); }
-
+ static void operator delete(void *, MEM_ROOT *){}
uchar flags; // field used to store various state information
LEX_CSTRING user;
/* list to hold references to granted roles (ACL_ROLE instances) */
@@ -253,7 +136,7 @@ class ACL_USER :public ACL_USER_BASE
{
public:
acl_host_and_ip host;
- uint hostname_length;
+ size_t hostname_length;
USER_RESOURCES user_resource;
uint8 salt[SCRAMBLE_LENGTH + 1]; // scrambled password in binary form
uint8 salt_len; // 0 - no password, 4 - 3.20, 8 - 4.0, 20 - 4.1.1
@@ -695,9 +578,9 @@ bool ROLE_GRANT_PAIR::init(MEM_ROOT *mem, const char *username,
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
#define NORMAL_HANDSHAKE_SIZE 6
-#define ROLE_ASSIGN_COLUMN_IDX 43
-#define DEFAULT_ROLE_COLUMN_IDX 44
-#define MAX_STATEMENT_TIME_COLUMN_IDX 45
+#define ROLE_ASSIGN_COLUMN_IDX 44
+#define DEFAULT_ROLE_COLUMN_IDX 45
+#define MAX_STATEMENT_TIME_COLUMN_IDX 46
/* various flags valid for ACL_USER */
#define IS_ROLE (1L << 0)
@@ -739,7 +622,7 @@ static ACL_ROLE *find_acl_role(const char *user);
static ROLE_GRANT_PAIR *find_role_grant_pair(const LEX_CSTRING *u, const LEX_CSTRING *h, const LEX_CSTRING *r);
static ACL_USER_BASE *find_acl_user_base(const char *user, const char *host);
static bool update_user_table(THD *, const User_table &, const char *, const char *, const
- char *, uint);
+ char *, size_t new_password_len);
static bool acl_load(THD *thd, const Grant_tables& grant_tables);
static inline void get_grantor(THD *thd, char* grantor);
static bool add_role_user_mapping(const char *uname, const char *hname, const char *rname);
@@ -854,7 +737,7 @@ class Grant_table_base
if (table_exists())
return 0;
- my_error(ER_NO_SUCH_TABLE, MYF(0), tl.db, tl.alias);
+ my_error(ER_NO_SUCH_TABLE, MYF(0), tl.db.str, tl.alias.str);
return 1;
}
@@ -1019,9 +902,7 @@ class User_table: public Grant_table_base
void init(enum thr_lock_type lock_type)
{
/* We are relying on init_one_table zeroing out the TABLE_LIST structure. */
- tl.init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("user"),
- NULL, lock_type);
+ tl.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_USER_NAME, NULL, lock_type);
Grant_table_base::init(lock_type, false);
}
@@ -1065,9 +946,7 @@ class Db_table: public Grant_table_base
void init(enum thr_lock_type lock_type)
{
/* We are relying on init_one_table zeroing out the TABLE_LIST structure. */
- tl.init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("db"),
- NULL, lock_type);
+ tl.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_DB_NAME, NULL, lock_type);
Grant_table_base::init(lock_type, false);
}
};
@@ -1092,9 +971,8 @@ class Tables_priv_table: public Grant_table_base
void init(enum thr_lock_type lock_type, Grant_table_base *next_table= NULL)
{
/* We are relying on init_one_table zeroing out the TABLE_LIST structure. */
- tl.init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("tables_priv"),
- NULL, lock_type);
+ LEX_CSTRING MYSQL_TABLES_PRIV_NAME={STRING_WITH_LEN("tables_priv") };
+ tl.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_TABLES_PRIV_NAME, NULL, lock_type);
Grant_table_base::init(lock_type, false);
}
};
@@ -1118,9 +996,8 @@ class Columns_priv_table: public Grant_table_base
void init(enum thr_lock_type lock_type)
{
/* We are relying on init_one_table zeroing out the TABLE_LIST structure. */
- tl.init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("columns_priv"),
- NULL, lock_type);
+ LEX_CSTRING MYSQL_COLUMNS_PRIV_NAME={ STRING_WITH_LEN("columns_priv") };
+ tl.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_COLUMNS_PRIV_NAME, NULL, lock_type);
Grant_table_base::init(lock_type, false);
}
};
@@ -1139,9 +1016,8 @@ class Host_table: public Grant_table_base
void init(enum thr_lock_type lock_type)
{
/* We are relying on init_one_table zeroing out the TABLE_LIST structure. */
- tl.init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("host"),
- NULL, lock_type);
+ LEX_CSTRING MYSQL_HOST_NAME={STRING_WITH_LEN("host") };
+ tl.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HOST_NAME, NULL, lock_type);
Grant_table_base::init(lock_type, true);
}
};
@@ -1166,9 +1042,8 @@ class Procs_priv_table: public Grant_table_base
void init(enum thr_lock_type lock_type)
{
/* We are relying on init_one_table zeroing out the TABLE_LIST structure. */
- tl.init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("procs_priv"),
- NULL, lock_type);
+ LEX_CSTRING MYSQL_PROCS_PRIV_NAME={STRING_WITH_LEN("procs_priv") };
+ tl.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PROCS_PRIV_NAME, NULL, lock_type);
Grant_table_base::init(lock_type, true);
}
};
@@ -1192,9 +1067,8 @@ class Proxies_priv_table: public Grant_table_base
void init(enum thr_lock_type lock_type)
{
/* We are relying on init_one_table zeroing out the TABLE_LIST structure. */
- tl.init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("proxies_priv"),
- NULL, lock_type);
+ LEX_CSTRING MYSQL_PROXIES_PRIV_NAME={STRING_WITH_LEN("proxies_priv") };
+ tl.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PROXIES_PRIV_NAME, NULL, lock_type);
Grant_table_base::init(lock_type, true);
}
};
@@ -1215,9 +1089,8 @@ class Roles_mapping_table: public Grant_table_base
void init(enum thr_lock_type lock_type)
{
/* We are relying on init_one_table zeroing out the TABLE_LIST structure. */
- tl.init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("roles_mapping"),
- NULL, lock_type);
+ LEX_CSTRING MYSQL_ROLES_MAPPING_NAME={STRING_WITH_LEN("roles_mapping") };
+ tl.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_ROLES_MAPPING_NAME, NULL, lock_type);
Grant_table_base::init(lock_type, true);
}
};
@@ -1550,7 +1423,7 @@ static bool validate_password(LEX_USER *user, THD *thd)
*/
static void
-set_user_salt(ACL_USER *acl_user, const char *password, uint password_len)
+set_user_salt(ACL_USER *acl_user, const char *password, size_t password_len)
{
if (password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH)
{
@@ -1773,7 +1646,7 @@ bool acl_init(bool dont_read_acl_tables)
Choose from either native or old password plugins when assigning a password
*/
-static bool set_user_plugin (ACL_USER *user, int password_len)
+static bool set_user_plugin (ACL_USER *user, size_t password_len)
{
switch (password_len)
{
@@ -1823,7 +1696,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
grant_version++; /* Privileges updated */
const Host_table& host_table= tables.host_table();
- init_sql_alloc(&acl_memroot, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(&acl_memroot, "ACL", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
if (host_table.table_exists()) // "host" table may not exist (e.g. in MySQL 5.6.7+)
{
if (host_table.init_read_record(&read_record_info, thd))
@@ -1967,7 +1840,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
char *password= const_cast<char*>("");
if (user_table.password())
password= get_field(&acl_memroot, user_table.password());
- uint password_len= safe_strlen(password);
+ size_t password_len= safe_strlen(password);
user.auth_string.str= safe_str(password);
user.auth_string.length= password_len;
set_user_salt(&user, password, password_len);
@@ -2013,6 +1886,9 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
if (user_table.num_fields() <= 38 && (user.access & SUPER_ACL))
user.access|= TRIGGER_ACL;
+ if (user_table.num_fields() <= 46 && (user.access & DELETE_ACL))
+ user.access|= DELETE_HISTORY_ACL;
+
user.sort= get_sort(2, user.host.hostname, user.user.str);
user.hostname_length= safe_strlen(user.host.hostname);
user.user_resource.user_conn= 0;
@@ -2239,7 +2115,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
DBUG_RETURN(TRUE);
MEM_ROOT temp_root;
- init_alloc_root(&temp_root, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ init_alloc_root(&temp_root, "ACL_tmp", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
while (!(read_record_info.read_record()))
{
char *hostname= safe_str(get_field(&temp_root, roles_mapping_table.host()));
@@ -2683,8 +2559,8 @@ int acl_setrole(THD *thd, const char *rolename, ulonglong access)
/* merge the privileges */
Security_context *sctx= thd->security_ctx;
sctx->master_access= static_cast<ulong>(access);
- if (thd->db)
- sctx->db_access= acl_get(sctx->host, sctx->ip, sctx->user, thd->db, FALSE);
+ if (thd->db.str)
+ sctx->db_access= acl_get(sctx->host, sctx->ip, sctx->user, thd->db.str, FALSE);
if (!strcasecmp(rolename, "NONE"))
{
@@ -2692,8 +2568,8 @@ int acl_setrole(THD *thd, const char *rolename, ulonglong access)
}
else
{
- if (thd->db)
- sctx->db_access|= acl_get("", "", rolename, thd->db, FALSE);
+ if (thd->db.str)
+ sctx->db_access|= acl_get("", "", rolename, thd->db.str, FALSE);
/* mark the current role */
strmake_buf(thd->security_ctx->priv_role, rolename);
}
@@ -2717,7 +2593,7 @@ static void acl_update_role(const char *rolename, ulong privileges)
static void acl_update_user(const char *user, const char *host,
- const char *password, uint password_len,
+ const char *password, size_t password_len,
enum SSL_type ssl_type,
const char *ssl_cipher,
const char *x509_issuer,
@@ -2795,7 +2671,7 @@ static void acl_insert_role(const char *rolename, ulong privileges)
static void acl_insert_user(const char *user, const char *host,
- const char *password, uint password_len,
+ const char *password, size_t password_len,
enum SSL_type ssl_type,
const char *ssl_cipher,
const char *x509_issuer,
@@ -2861,37 +2737,42 @@ static void acl_insert_user(const char *user, const char *host,
}
-static void acl_update_db(const char *user, const char *host, const char *db,
+static bool acl_update_db(const char *user, const char *host, const char *db,
ulong privileges)
{
mysql_mutex_assert_owner(&acl_cache->lock);
+ bool updated= false;
+
for (uint i=0 ; i < acl_dbs.elements ; i++)
{
ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*);
if ((!acl_db->user && !user[0]) ||
- (acl_db->user &&
- !strcmp(user,acl_db->user)))
+ (acl_db->user &&
+ !strcmp(user,acl_db->user)))
{
if ((!acl_db->host.hostname && !host[0]) ||
- (acl_db->host.hostname &&
- !strcmp(host, acl_db->host.hostname)))
+ (acl_db->host.hostname &&
+ !strcmp(host, acl_db->host.hostname)))
{
- if ((!acl_db->db && !db[0]) ||
- (acl_db->db && !strcmp(db,acl_db->db)))
+ if ((!acl_db->db && !db[0]) ||
+ (acl_db->db && !strcmp(db,acl_db->db)))
- {
- if (privileges)
+ {
+ if (privileges)
{
acl_db->access= privileges;
acl_db->initial_access= acl_db->access;
}
- else
- delete_dynamic_element(&acl_dbs,i);
- }
+ else
+ delete_dynamic_element(&acl_dbs,i);
+ updated= true;
+ }
}
}
}
+
+ return updated;
}
@@ -3012,7 +2893,8 @@ exit:
(entry= (acl_entry*) malloc(sizeof(acl_entry)+key_length)))
{
entry->access=(db_access & host_access);
- entry->length=key_length;
+ DBUG_ASSERT(key_length < 0xffff);
+ entry->length=(uint16)key_length;
memcpy((uchar*) entry->key,key,key_length);
acl_cache->add(entry);
}
@@ -3405,6 +3287,7 @@ bool change_password(THD *thd, LEX_USER *user)
acl_user->auth_string.str= strmake_root(&acl_memroot, user->pwhash.str, user->pwhash.length);
acl_user->auth_string.length= user->pwhash.length;
set_user_salt(acl_user, user->pwhash.str, user->pwhash.length);
+
set_user_plugin(acl_user, user->pwhash.length);
}
else
@@ -3865,8 +3748,7 @@ bool hostname_requires_resolving(const char *hostname)
void set_authentication_plugin_from_password(const User_table& user_table,
- const char* password,
- uint password_length)
+ const char* password, size_t password_length)
{
if (password_length == SCRAMBLED_PASSWORD_CHAR_LENGTH)
{
@@ -3900,7 +3782,7 @@ void set_authentication_plugin_from_password(const User_table& user_table,
static bool update_user_table(THD *thd, const User_table& user_table,
const char *host, const char *user,
- const char *new_password, uint new_password_len)
+ const char *new_password, size_t new_password_len)
{
char user_key[MAX_KEY_LENGTH];
int error;
@@ -3959,14 +3841,13 @@ static bool test_if_create_new_users(THD *thd)
{
TABLE_LIST tl;
ulong db_access;
- tl.init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("user"), "user", TL_WRITE);
+ tl.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_USER_NAME, NULL, TL_WRITE);
create_new_users= 1;
db_access=acl_get(sctx->host, sctx->ip,
- sctx->priv_user, tl.db, 0);
+ sctx->priv_user, tl.db.str, 0);
if (sctx->priv_role[0])
- db_access|= acl_get("", "", sctx->priv_role, tl.db, 0);
+ db_access|= acl_get("", "", sctx->priv_role, tl.db.str, 0);
if (!(db_access & INSERT_ACL))
{
if (check_grant(thd, INSERT_ACL, &tl, FALSE, UINT_MAX, TRUE))
@@ -4383,9 +4264,21 @@ static int replace_db_table(TABLE *table, const char *db,
acl_cache->clear(1); // Clear privilege cache
if (old_row_exists)
acl_update_db(combo.user.str,combo.host.str,db,rights);
- else
- if (rights)
- acl_insert_db(combo.user.str,combo.host.str,db,rights);
+ else if (rights)
+ {
+ /*
+ If we did not have an already existing row, for users, we must always
+ insert an ACL_DB entry. For roles however, it is possible that one was
+ already created when DB privileges were propagated from other granted
+ roles onto the current role. For this case, first try to update the
+ existing entry, otherwise insert a new one.
+ */
+ if (!combo.is_role() ||
+ !acl_update_db(combo.user.str, combo.host.str, db, rights))
+ {
+ acl_insert_db(combo.user.str,combo.host.str,db,rights);
+ }
+ }
DBUG_RETURN(0);
/* This could only happen if the grant tables got corrupted */
@@ -5001,7 +4894,7 @@ table_hash_search(const char *host, const char *ip, const char *db,
static GRANT_COLUMN *
-column_hash_search(GRANT_TABLE *t, const char *cname, uint length)
+column_hash_search(GRANT_TABLE *t, const char *cname, size_t length)
{
if (!my_hash_inited(&t->hash_columns))
return (GRANT_COLUMN*) 0;
@@ -5941,8 +5834,8 @@ static bool merge_role_db_privileges(ACL_ROLE *grantee, const char *dbname,
(that should be merged) are sorted together. The grantee's ACL_DB element
is not necessarily the first and may be not present at all.
*/
- ACL_DB **first= NULL, *UNINIT_VAR(merged);
- ulong UNINIT_VAR(access), update_flags= 0;
+ ACL_DB **first= NULL, *merged= NULL;
+ ulong access= 0, update_flags= 0;
for (ACL_DB **cur= dbs.front(); cur <= dbs.back(); cur++)
{
if (!first || (!dbname && strcmp(cur[0]->db, cur[-1]->db)))
@@ -6147,8 +6040,8 @@ static bool merge_role_table_and_column_privileges(ACL_ROLE *grantee,
}
grants.sort(table_name_sort);
- GRANT_TABLE **first= NULL, *UNINIT_VAR(merged), **cur;
- ulong UNINIT_VAR(privs), UNINIT_VAR(cols), update_flags= 0;
+ GRANT_TABLE **first= NULL, *merged= NULL, **cur;
+ ulong privs= 0, cols= 0, update_flags= 0;
for (cur= grants.front(); cur <= grants.back(); cur++)
{
if (!first ||
@@ -6271,8 +6164,8 @@ static bool merge_role_routine_grant_privileges(ACL_ROLE *grantee,
}
grants.sort(routine_name_sort);
- GRANT_NAME **first= NULL, *UNINIT_VAR(merged);
- ulong UNINIT_VAR(privs);
+ GRANT_NAME **first= NULL, *merged= NULL;
+ ulong privs= 0 ;
for (GRANT_NAME **cur= grants.front(); cur <= grants.back(); cur++)
{
if (!first ||
@@ -6308,9 +6201,12 @@ static int merge_role_privileges(ACL_ROLE *role __attribute__((unused)),
{
PRIVS_TO_MERGE *data= (PRIVS_TO_MERGE *)context;
+ DBUG_ASSERT(grantee->counter > 0);
if (--grantee->counter)
return 1; // don't recurse into grantee just yet
+ grantee->counter= 1; // Mark the grantee as merged.
+
/* if we'll do db/table/routine privileges, create a hash of role names */
role_hash_t role_hash(role_key);
if (data->what != PRIVS_TO_MERGE::GLOBAL)
@@ -6453,7 +6349,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
if (f == (Field*)0)
{
my_error(ER_BAD_FIELD_ERROR, MYF(0),
- column->column.c_ptr(), table_list->alias);
+ column->column.c_ptr(), table_list->alias.str);
DBUG_RETURN(TRUE);
}
if (f == (Field *)-1)
@@ -6466,9 +6362,10 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
{
if (!(rights & CREATE_ACL))
{
- if (!ha_table_exists(thd, table_list->db, table_list->table_name))
+ if (!ha_table_exists(thd, &table_list->db, &table_list->table_name))
{
- my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
+ my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db.str,
+ table_list->alias.str);
DBUG_RETURN(TRUE);
}
}
@@ -6479,7 +6376,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
table_list->grant.want_privilege);
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
command, thd->security_ctx->priv_user,
- thd->security_ctx->host_or_ip, table_list->alias);
+ thd->security_ctx->host_or_ip, table_list->alias.str);
DBUG_RETURN(-1);
}
}
@@ -6555,7 +6452,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
if (revoke_grant)
{
my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0),
- Str->user.str, Str->host.str, table_list->table_name);
+ Str->user.str, Str->host.str, table_list->table_name.str);
result= TRUE;
continue;
}
@@ -6722,8 +6619,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list,
continue;
}
- db_name= table_list->db;
- table_name= table_list->table_name;
+ db_name= table_list->db.str;
+ table_name= table_list->table_name.str;
grant_name= routine_hash_search(Str->host.str, NullS, db_name,
Str->user.str, table_name, sph, 1);
if (!grant_name || !grant_name->init_privs)
@@ -7285,7 +7182,7 @@ static bool grant_load(THD *thd,
0,0,0, (my_hash_get_key) get_grant_table, 0,0);
(void) my_hash_init(&func_priv_hash, &my_charset_utf8_bin,
0,0,0, (my_hash_get_key) get_grant_table, 0,0);
- init_sql_alloc(&grant_memroot, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(&grant_memroot, "GRANT", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
t_table= tables_priv.table();
c_table= columns_priv.table();
@@ -7367,9 +7264,8 @@ static bool grant_load(THD *thd,
continue;
}
}
- uint type= procs_priv.routine_type()->val_int();
- const Sp_handler *sph= Sp_handler::handler((stored_procedure_type)
- type);
+ stored_procedure_type type= (stored_procedure_type)procs_priv.routine_type()->val_int();
+ const Sp_handler *sph= Sp_handler::handler(type);
if (!sph || !(hash= sph->get_priv_hash()))
{
sql_print_warning("'procs_priv' entry '%s' "
@@ -7403,11 +7299,10 @@ end_index_init:
DBUG_RETURN(return_val);
}
-
-static my_bool role_propagate_grants_action(void *ptr,
- void *unused __attribute__((unused)))
+static my_bool propagate_role_grants_action(void *role_ptr,
+ void *ptr __attribute__((unused)))
{
- ACL_ROLE *role= (ACL_ROLE *)ptr;
+ ACL_ROLE *role= static_cast<ACL_ROLE *>(role_ptr);
if (role->counter)
return 0;
@@ -7483,7 +7378,7 @@ bool grant_reload(THD *thd)
}
mysql_mutex_lock(&acl_cache->lock);
- my_hash_iterate(&acl_roles, role_propagate_grants_action, NULL);
+ my_hash_iterate(&acl_roles, propagate_role_grants_action, NULL);
mysql_mutex_unlock(&acl_cache->lock);
mysql_rwlock_unlock(&LOCK_grant);
@@ -7581,13 +7476,12 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
ulong orig_want_access= original_want_access;
/*
- If sequence is used as part of NEXT VALUE, PREVIUS VALUE or SELECT,
+ If sequence is used as part of NEXT VALUE, PREVIOUS VALUE or SELECT,
we need to modify the requested access rights depending on how the
sequence is used.
*/
- if (t_ref->sequence &
- (orig_want_access &
- (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL)))
+ if (t_ref->sequence &&
+ !(want_access & ~(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL)))
{
/*
We want to have either SELECT or INSERT rights to sequences depending
@@ -7597,6 +7491,11 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
INSERT_ACL : SELECT_ACL);
}
+ if (tl->with ||
+ (tl->select_lex &&
+ (tl->with= tl->select_lex->find_table_def_in_with_clauses(tl))))
+ continue;
+
const ACL_internal_table_access *access=
get_cached_table_access(&t_ref->grant.m_internal,
t_ref->get_db_name(),
@@ -7753,7 +7652,7 @@ err:
bool check_grant_column(THD *thd, GRANT_INFO *grant,
const char *db_name, const char *table_name,
- const char *name, uint length, Security_context *sctx)
+ const char *name, size_t length, Security_context *sctx)
{
GRANT_TABLE *grant_table;
GRANT_TABLE *grant_table_role;
@@ -7848,7 +7747,7 @@ err:
*/
bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
- const char *name, uint length)
+ const char *name, size_t length)
{
GRANT_INFO *grant;
const char *db_name;
@@ -8147,13 +8046,13 @@ bool check_grant_routine(THD *thd, ulong want_access,
for (table= procs; table; table= table->next_global)
{
GRANT_NAME *grant_proc;
- if ((grant_proc= routine_hash_search(host, sctx->ip, table->db, user,
- table->table_name, sph, 0)))
+ if ((grant_proc= routine_hash_search(host, sctx->ip, table->db.str, user,
+ table->table_name.str, sph, 0)))
table->grant.privilege|= grant_proc->privs;
if (role[0]) /* current role set check */
{
- if ((grant_proc= routine_hash_search("", NULL, table->db, role,
- table->table_name, sph, 0)))
+ if ((grant_proc= routine_hash_search("", NULL, table->db.str, role,
+ table->table_name.str, sph, 0)))
table->grant.privilege|= grant_proc->privs;
}
@@ -8172,7 +8071,7 @@ err:
char buff[1024];
const char *command="";
if (table)
- strxmov(buff, table->db, ".", table->table_name, NullS);
+ strxmov(buff, table->db.str, ".", table->table_name.str, NullS);
if (want_access & EXECUTE_ACL)
command= "execute";
else if (want_access & ALTER_PROC_ACL)
@@ -8235,7 +8134,7 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table)
{
ulong privilege;
Security_context *sctx= thd->security_ctx;
- const char *db = table->db ? table->db : thd->db;
+ const char *db = table->db.str ? table->db.str : thd->db.str;
GRANT_TABLE *grant_table;
GRANT_TABLE *grant_table_role= NULL;
@@ -8245,10 +8144,10 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table)
grant_table_role= NULL;
#else
grant_table= table_hash_search(sctx->host, sctx->ip, db, sctx->priv_user,
- table->table_name, 0);
+ table->table_name.str, 0);
if (sctx->priv_role[0])
grant_table_role= table_hash_search("", "", db, sctx->priv_role,
- table->table_name, 0);
+ table->table_name.str, 0);
#endif
table->grant.grant_table_user= grant_table; // Remember for column test
table->grant.grant_table_role= grant_table_role;
@@ -8465,13 +8364,14 @@ static const char *command_array[]=
"ALTER", "SHOW DATABASES", "SUPER", "CREATE TEMPORARY TABLES",
"LOCK TABLES", "EXECUTE", "REPLICATION SLAVE", "REPLICATION CLIENT",
"CREATE VIEW", "SHOW VIEW", "CREATE ROUTINE", "ALTER ROUTINE",
- "CREATE USER", "EVENT", "TRIGGER", "CREATE TABLESPACE"
+ "CREATE USER", "EVENT", "TRIGGER", "CREATE TABLESPACE",
+ "DELETE VERSIONING ROWS"
};
static uint command_lengths[]=
{
6, 6, 6, 6, 6, 4, 6, 8, 7, 4, 5, 10, 5, 5, 14, 5, 23, 11, 7, 17, 18, 11, 9,
- 14, 13, 11, 5, 7, 17
+ 14, 13, 11, 5, 7, 17, 22,
};
@@ -8576,7 +8476,7 @@ bool mysql_show_create_user(THD *thd, LEX_USER *lex_user)
hostname, NullS) - buff);
Item_string *field = new (thd->mem_root) Item_string_ascii(thd, "", 0);
if (!field)
- DBUG_RETURN(true);
+ DBUG_RETURN(true); // Error given my my_alloc()
field->name.str= buff;
field->name.length= head_length;
@@ -9161,7 +9061,8 @@ static int show_routine_grants(THD* thd,
}
}
global.append(STRING_WITH_LEN(" ON "));
- global.append(sph->type_lex_cstring());
+ LEX_CSTRING tmp= sph->type_lex_cstring();
+ global.append(&tmp);
global.append(' ');
append_identifier(thd, &global, grant_proc->db,
strlen(grant_proc->db));
@@ -10220,13 +10121,13 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
}
}
- binlog= true;
if (replace_user_table(thd, tables.user_table(), *user_name, 0, 0, 1, 0))
{
append_user(thd, &wrong_users, user_name);
result= TRUE;
continue;
}
+ binlog= true;
// every created role is automatically granted to its creator-admin
if (handle_as_role)
@@ -10993,8 +10894,10 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bzero((char*)tables, sizeof(TABLE_LIST));
user_list.empty();
- tables->db= (char*)sp_db;
- tables->table_name= tables->alias= (char*)sp_name;
+ tables->db.str= sp_db;
+ tables->db.length= sp_db ? strlen(sp_db) : 0;
+ tables->table_name.str= tables->alias.str= sp_name;
+ tables->table_name.length= tables->alias.length= sp_name ? strlen(sp_name) : 0;
thd->make_lex_string(&combo->user, combo->user.str, strlen(combo->user.str));
thd->make_lex_string(&combo->host, combo->host.str, strlen(combo->host.str));
@@ -11793,7 +11696,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
/* global privileges */
grant->privilege= sctx->master_access;
- if (!thd->db || strcmp(db, thd->db))
+ if (!thd->db.str || strcmp(db, thd->db.str))
{
/* db privileges */
grant->privilege|= acl_get(sctx->host, sctx->ip, sctx->priv_user, db, 0);
@@ -12388,7 +12291,7 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio)
}
mpvio->auth_info.user_name= sctx->user;
- mpvio->auth_info.user_name_length= strlen(sctx->user);
+ mpvio->auth_info.user_name_length= (uint)strlen(sctx->user);
mpvio->auth_info.auth_string= mpvio->acl_user->auth_string.str;
mpvio->auth_info.auth_string_length= (unsigned long) mpvio->acl_user->auth_string.length;
strmake_buf(mpvio->auth_info.authenticated_as, safe_str(mpvio->acl_user->user.str));
@@ -12426,12 +12329,10 @@ read_client_connect_attrs(char **ptr, char *end, CHARSET_INFO *from_cs)
if (length > 65535)
return true;
-#ifdef HAVE_PSI_THREAD_INTERFACE
- if (PSI_THREAD_CALL(set_thread_connect_attrs)(*ptr, (size_t)length, from_cs) &&
+ if (PSI_CALL_set_thread_connect_attrs(*ptr, (uint)length, from_cs) &&
current_thd->variables.log_warnings)
sql_print_warning("Connection attributes of length %llu were truncated",
length);
-#endif
return false;
}
@@ -12473,7 +12374,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
*passwd > 127 and become 2**32-127+ after casting to uint.
*/
uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
- (uchar) (*passwd++) : strlen(passwd));
+ (uchar) (*passwd++) : (uint)strlen(passwd));
db+= passwd_len + 1;
/*
@@ -12487,7 +12388,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
DBUG_RETURN (1);
}
- uint db_len= strlen(db);
+ size_t db_len= strlen(db);
char *next_field= db + db_len + 1;
@@ -12521,7 +12422,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
connection is closed. We don't want to accidentally free a wrong
pointer if connect failed.
*/
- thd->reset_db(NULL, 0);
+ thd->reset_db(&null_clex_str);
if (!initialized)
{
@@ -12687,7 +12588,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
char *user= end;
char *passwd= strend(user)+1;
- uint user_len= (uint)(passwd - user - 1), db_len;
+ size_t user_len= (size_t)(passwd - user - 1), db_len;
char *db= passwd;
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
uint dummy_errors;
@@ -12772,7 +12673,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
connection is closed. We don't want to accidentally free a wrong
pointer if connect failed.
*/
- thd->reset_db(NULL, 0);
+ thd->reset_db(&null_clex_str);
if (!initialized)
{
@@ -12830,7 +12731,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
plugin_name(mpvio->plugin)) != 0)
{
mpvio->cached_client_reply.pkt= passwd;
- mpvio->cached_client_reply.pkt_len= passwd_len;
+ mpvio->cached_client_reply.pkt_len= (uint)passwd_len;
mpvio->cached_client_reply.plugin= client_plugin;
mpvio->status= MPVIO_EXT::RESTART;
return packet_error;
@@ -12859,7 +12760,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
}
*buff= (uchar*) passwd;
- return passwd_len;
+ return (ulong)passwd_len;
#else
return 0;
#endif
@@ -13504,11 +13405,9 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
else
my_ok(thd);
-#ifdef HAVE_PSI_THREAD_INTERFACE
- PSI_THREAD_CALL(set_thread_user_host)
- (thd->main_security_ctx.user, strlen(thd->main_security_ctx.user),
- thd->main_security_ctx.host_or_ip, strlen(thd->main_security_ctx.host_or_ip));
-#endif
+ PSI_CALL_set_thread_user_host
+ (thd->main_security_ctx.user, (uint)strlen(thd->main_security_ctx.user),
+ thd->main_security_ctx.host_or_ip, (uint)strlen(thd->main_security_ctx.host_or_ip));
/* Ready to handle queries */
DBUG_RETURN(0);
@@ -13638,7 +13537,7 @@ static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio,
We need to figure out the correct scramble length here.
*/
if (pkt_len == SCRAMBLE_LENGTH_323 + 1)
- pkt_len= strnlen((char*)pkt, pkt_len);
+ pkt_len= (int)strnlen((char*)pkt, pkt_len);
if (pkt_len == 0) /* no password */
return info->auth_string[0] ? CR_AUTH_USER_CREDENTIALS : CR_OK;
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index e3dba20422d..a608ef0dd77 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -49,6 +49,7 @@
#define EVENT_ACL (1UL << 26)
#define TRIGGER_ACL (1UL << 27)
#define CREATE_TABLESPACE_ACL (1UL << 28)
+#define DELETE_HISTORY_ACL (1UL << 29)
/*
don't forget to update
1. static struct show_privileges_st sys_privileges[]
@@ -62,12 +63,13 @@
(UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | \
LOCK_TABLES_ACL | EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | \
- CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL | TRIGGER_ACL)
+ CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL | TRIGGER_ACL | \
+ DELETE_HISTORY_ACL)
#define TABLE_ACLS \
(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | \
- SHOW_VIEW_ACL | TRIGGER_ACL)
+ SHOW_VIEW_ACL | TRIGGER_ACL | DELETE_HISTORY_ACL)
#define COL_ACLS \
(SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL)
@@ -85,7 +87,7 @@
CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \
EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | \
ALTER_PROC_ACL | CREATE_USER_ACL | EVENT_ACL | TRIGGER_ACL | \
- CREATE_TABLESPACE_ACL)
+ CREATE_TABLESPACE_ACL | DELETE_HISTORY_ACL)
#define DEFAULT_CREATE_PROC_ACLS \
(ALTER_PROC_ACL | EXECUTE_ACL)
@@ -117,31 +119,37 @@
CREATE_PROC_ACL | ALTER_PROC_ACL )
#define DB_CHUNK4 (EXECUTE_ACL)
#define DB_CHUNK5 (EVENT_ACL | TRIGGER_ACL)
+#define DB_CHUNK6 (DELETE_HISTORY_ACL)
#define fix_rights_for_db(A) (((A) & DB_CHUNK0) | \
(((A) << 4) & DB_CHUNK1) | \
(((A) << 6) & DB_CHUNK2) | \
(((A) << 9) & DB_CHUNK3) | \
- (((A) << 2) & DB_CHUNK4))| \
- (((A) << 9) & DB_CHUNK5)
+ (((A) << 2) & DB_CHUNK4) | \
+ (((A) << 9) & DB_CHUNK5) | \
+ (((A) << 10) & DB_CHUNK6))
#define get_rights_for_db(A) (((A) & DB_CHUNK0) | \
(((A) & DB_CHUNK1) >> 4) | \
(((A) & DB_CHUNK2) >> 6) | \
(((A) & DB_CHUNK3) >> 9) | \
- (((A) & DB_CHUNK4) >> 2))| \
- (((A) & DB_CHUNK5) >> 9)
+ (((A) & DB_CHUNK4) >> 2) | \
+ (((A) & DB_CHUNK5) >> 9) | \
+ (((A) & DB_CHUNK6) >> 10))
#define TBL_CHUNK0 DB_CHUNK0
#define TBL_CHUNK1 DB_CHUNK1
#define TBL_CHUNK2 (CREATE_VIEW_ACL | SHOW_VIEW_ACL)
#define TBL_CHUNK3 TRIGGER_ACL
+#define TBL_CHUNK4 (DELETE_HISTORY_ACL)
#define fix_rights_for_table(A) (((A) & TBL_CHUNK0) | \
(((A) << 4) & TBL_CHUNK1) | \
(((A) << 11) & TBL_CHUNK2) | \
- (((A) << 15) & TBL_CHUNK3))
+ (((A) << 15) & TBL_CHUNK3) | \
+ (((A) << 16) & TBL_CHUNK4))
#define get_rights_for_table(A) (((A) & TBL_CHUNK0) | \
(((A) & TBL_CHUNK1) >> 4) | \
(((A) & TBL_CHUNK2) >> 11) | \
- (((A) & TBL_CHUNK3) >> 15))
+ (((A) & TBL_CHUNK3) >> 15) | \
+ (((A) & TBL_CHUNK4) >> 16))
#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8))
#define get_rights_for_column(A) (((A) & 7) | ((A) >> 8))
#define fix_rights_for_procedure(A) ((((A) << 18) & EXECUTE_ACL) | \
@@ -175,6 +183,7 @@ enum mysql_db_table_field
MYSQL_DB_FIELD_EXECUTE_PRIV,
MYSQL_DB_FIELD_EVENT_PRIV,
MYSQL_DB_FIELD_TRIGGER_PRIV,
+ MYSQL_DB_FIELD_DELETE_VERSIONING_ROWS_PRIV,
MYSQL_DB_FIELD_COUNT
};
@@ -189,8 +198,12 @@ extern LEX_CSTRING current_user_and_current_role;
static inline int access_denied_error_code(int passwd_used)
{
+#ifdef mysqld_error_find_printf_error_used
+ return 0;
+#else
return passwd_used == 2 ? ER_ACCESS_DENIED_NO_PASSWORD_ERROR
: ER_ACCESS_DENIED_ERROR;
+#endif
}
/* prototypes */
@@ -224,9 +237,9 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
bool any_combination_will_do, uint number, bool no_errors);
bool check_grant_column (THD *thd, GRANT_INFO *grant,
const char *db_name, const char *table_name,
- const char *name, uint length, Security_context *sctx);
+ const char *name, size_t length, Security_context *sctx);
bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
- const char *name, uint length);
+ const char *name, size_t length);
bool check_grant_all_columns(THD *thd, ulong want_access,
Field_iterator_table_ref *fields);
bool check_grant_routine(THD *thd, ulong want_access,
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 4ed8234aa64..4cff69060d1 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -77,7 +77,7 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table,
{
Protocol *protocol= thd->protocol;
protocol->prepare_for_resend();
- protocol->store(table->alias, system_charset_info);
+ protocol->store(table->alias.str, table->alias.length, system_charset_info);
protocol->store((char*) operator_name, system_charset_info);
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
protocol->store(errmsg, system_charset_info);
@@ -123,7 +123,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
*/
table_list->mdl_request.init(MDL_key::TABLE,
- table_list->db, table_list->table_name,
+ table_list->db.str, table_list->table_name.str,
MDL_EXCLUSIVE, MDL_TRANSACTION);
if (lock_table_names(thd, table_list, table_list->next_global,
@@ -135,7 +135,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
if (share == NULL)
DBUG_RETURN(0); // Can't open frm file
- if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, FALSE))
+ if (open_table_from_share(thd, share, &empty_clex_str, 0, 0, 0,
+ &tmp_table, FALSE))
{
tdc_release_share(share);
DBUG_RETURN(0); // Out of memory
@@ -218,7 +219,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
"Failed renaming data file");
goto end;
}
- if (dd_recreate_table(thd, table_list->db, table_list->table_name))
+ if (dd_recreate_table(thd, table_list->db.str, table_list->table_name.str))
{
error= send_check_errmsg(thd, table_list, "repair",
"Failed generating table from .frm file");
@@ -492,13 +493,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
for (table= tables; table; table= table->next_local)
{
char table_name[SAFE_NAME_LEN*2+2];
- const char *db= table->db;
+ const char *db= table->db.str;
bool fatal_error=0;
bool open_error;
bool collect_eis= FALSE;
- DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
- strxmov(table_name, db, ".", table->table_name, NullS);
+ DBUG_PRINT("admin", ("table: '%s'.'%s'", db, table->table_name.str));
+ strxmov(table_name, db, ".", table->table_name.str, NullS);
thd->open_options|= extra_open_options;
table->lock_type= lock_type;
/*
@@ -547,7 +548,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
close_thread_tables(thd);
table->table= NULL;
thd->mdl_context.release_transactional_locks();
- table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name,
+ table->mdl_request.init(MDL_key::TABLE, table->db.str, table->table_name.str,
MDL_SHARED_NO_READ_WRITE, MDL_TRANSACTION);
}
@@ -702,8 +703,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (lock_type == TL_WRITE && !table->table->s->tmp_table &&
table->mdl_request.type > MDL_SHARED_WRITE)
{
- if (wait_while_table_is_used(thd, table->table,
- HA_EXTRA_PREPARE_FOR_RENAME))
+ if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
goto err;
DEBUG_SYNC(thd, "after_admin_flush");
/* Flush entries in the query cache involving this table. */
@@ -818,7 +818,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
close_thread_tables(thd);
table->table= NULL;
thd->mdl_context.release_transactional_locks();
- table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name,
+ table->mdl_request.init(MDL_key::TABLE, table->db.str, table->table_name.str,
MDL_SHARED_NO_READ_WRITE, MDL_TRANSACTION);
table->mdl_request.set_type(MDL_SHARED_READ);
@@ -1041,7 +1041,7 @@ send_result_message:
if (!thd->open_temporary_tables(table) &&
(table->table= open_ltable(thd, table, lock_type, 0)))
{
- uint save_flags;
+ ulonglong save_flags;
/* Store the original value of alter_info->flags */
save_flags= alter_info->flags;
@@ -1118,11 +1118,11 @@ send_result_message:
if (what_to_upgrade)
length= my_snprintf(buf, sizeof(buf),
ER_THD(thd, ER_TABLE_NEEDS_UPGRADE),
- what_to_upgrade, table->table_name);
+ what_to_upgrade, table->table_name.str);
else
length= my_snprintf(buf, sizeof(buf),
ER_THD(thd, ER_TABLE_NEEDS_REBUILD),
- table->table_name);
+ table->table_name.str);
protocol->store(buf, length, system_charset_info);
fatal_error=1;
break;
@@ -1154,7 +1154,7 @@ send_result_message:
else if (open_for_modify || fatal_error)
{
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
- table->db, table->table_name, FALSE);
+ table->db.str, table->table_name.str, FALSE);
/*
May be something modified. Consequently, we have to
invalidate the query cache.
diff --git a/sql/sql_alloc.h b/sql/sql_alloc.h
index 4db12964f0a..c3bee260817 100644
--- a/sql/sql_alloc.h
+++ b/sql/sql_alloc.h
@@ -1,7 +1,7 @@
#ifndef SQL_ALLOC_INCLUDED
#define SQL_ALLOC_INCLUDED
/* Copyright (c) 2000, 2012, Oracle and/or its affiliates.
- Copyright (c) 2017, MariaDB AB
+ Copyright (c) 2017, 2018, 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
@@ -27,24 +27,21 @@ class Sql_alloc
public:
static void *operator new(size_t size) throw ()
{
- DBUG_ASSERT(size < UINT_MAX32);
- return thd_alloc(thd_get_current_thd(), uint(size));
+ return thd_alloc(thd_get_current_thd(), size);
}
static void *operator new[](size_t size) throw ()
{
- DBUG_ASSERT(size < UINT_MAX32);
- return thd_alloc(thd_get_current_thd(), uint(size));
+ return thd_alloc(thd_get_current_thd(), size);
}
static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
{ return alloc_root(mem_root, size); }
- static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
+ static void *operator new(size_t size, MEM_ROOT *mem_root) throw()
{ return alloc_root(mem_root, size); }
- static void operator delete(void *ptr, size_t size) { TRASH(ptr, size); }
- static void operator delete(void *ptr, MEM_ROOT *mem_root)
- { /* never called */ }
+ static void operator delete(void *ptr, size_t size) { TRASH_FREE(ptr, size); }
+ static void operator delete(void *, MEM_ROOT *){}
static void operator delete[](void *ptr, MEM_ROOT *mem_root)
{ /* never called */ }
- static void operator delete[](void *ptr, size_t size) { TRASH(ptr, size); }
+ static void operator delete[](void *ptr, size_t size) { TRASH_FREE(ptr, size); }
#ifdef HAVE_valgrind
bool dummy_for_valgrind;
inline Sql_alloc() :dummy_for_valgrind(0) {}
diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc
index 3d1e4c0fa65..2cc6504d2f3 100644
--- a/sql/sql_alter.cc
+++ b/sql/sql_alter.cc
@@ -86,8 +86,8 @@ bool Alter_info::set_requested_lock(const LEX_CSTRING *str)
Alter_table_ctx::Alter_table_ctx()
: datetime_field(NULL), error_if_not_empty(false),
tables_opened(0),
- db(NULL), table_name(NULL), alias(NULL),
- new_db(NULL), new_name(NULL), new_alias(NULL),
+ db(null_clex_str), table_name(null_clex_str), alias(null_clex_str),
+ new_db(null_clex_str), new_name(null_clex_str), new_alias(null_clex_str),
fk_error_if_delete_row(false), fk_error_id(NULL),
fk_error_table(NULL)
#ifdef DBUG_ASSERT_EXISTS
@@ -103,11 +103,11 @@ Alter_table_ctx::Alter_table_ctx()
Alter_table_ctx::Alter_table_ctx(THD *thd, TABLE_LIST *table_list,
uint tables_opened_arg,
- const char *new_db_arg,
- const char *new_name_arg)
+ const LEX_CSTRING *new_db_arg,
+ const LEX_CSTRING *new_name_arg)
: datetime_field(NULL), error_if_not_empty(false),
tables_opened(tables_opened_arg),
- new_db(new_db_arg), new_name(new_name_arg),
+ new_db(*new_db_arg), new_name(*new_name_arg),
fk_error_if_delete_row(false), fk_error_id(NULL),
fk_error_table(NULL)
#ifdef DBUG_ASSERT_EXISTS
@@ -123,29 +123,31 @@ Alter_table_ctx::Alter_table_ctx(THD *thd, TABLE_LIST *table_list,
table_name= table_list->table_name;
alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
- if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
+ if (!new_db.str || !my_strcasecmp(table_alias_charset, new_db.str, db.str))
new_db= db;
- if (new_name)
+ if (new_name.str)
{
- DBUG_PRINT("info", ("new_db.new_name: '%s'.'%s'", new_db, new_name));
+ DBUG_PRINT("info", ("new_db.new_name: '%s'.'%s'", new_db.str, new_name.str));
- if (lower_case_table_names == 1) // Convert new_name/new_alias to lower case
+ if (lower_case_table_names == 1) // Convert new_name/new_alias to lower
{
- my_casedn_str(files_charset_info, (char*) new_name);
+ new_name.length= my_casedn_str(files_charset_info, (char*) new_name.str);
new_alias= new_name;
}
else if (lower_case_table_names == 2) // Convert new_name to lower case
{
- new_alias= new_alias_buff;
- strmov(new_alias_buff, new_name);
- my_casedn_str(files_charset_info, (char*) new_name);
+ new_alias.str= new_alias_buff;
+ new_alias.length= new_name.length;
+ strmov(new_alias_buff, new_name.str);
+ new_name.length= my_casedn_str(files_charset_info, (char*) new_name.str);
+
}
else
new_alias= new_name; // LCTN=0 => case sensitive + case preserving
if (!is_database_changed() &&
- !my_strcasecmp(table_alias_charset, new_name, table_name))
+ !my_strcasecmp(table_alias_charset, new_name.str, table_name.str))
{
/*
Source and destination table names are equal:
@@ -161,22 +163,23 @@ Alter_table_ctx::Alter_table_ctx(THD *thd, TABLE_LIST *table_list,
new_name= table_name;
}
- my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%llx", tmp_file_prefix,
- current_pid, thd->thread_id);
+ tmp_name.str= tmp_name_buff;
+ tmp_name.length= my_snprintf(tmp_name_buff, sizeof(tmp_name_buff), "%s-%lx_%llx",
+ tmp_file_prefix, current_pid, thd->thread_id);
/* Safety fix for InnoDB */
if (lower_case_table_names)
- my_casedn_str(files_charset_info, tmp_name);
+ tmp_name.length= my_casedn_str(files_charset_info, tmp_name_buff);
if (table_list->table->s->tmp_table == NO_TMP_TABLE)
{
- build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0);
+ build_table_filename(path, sizeof(path) - 1, db.str, table_name.str, "", 0);
- build_table_filename(new_path, sizeof(new_path) - 1, new_db, new_name, "", 0);
+ build_table_filename(new_path, sizeof(new_path) - 1, new_db.str, new_name.str, "", 0);
build_table_filename(new_filename, sizeof(new_filename) - 1,
- new_db, new_name, reg_ext, 0);
+ new_db.str, new_name.str, reg_ext, 0);
- build_table_filename(tmp_path, sizeof(tmp_path) - 1, new_db, tmp_name, "",
+ build_table_filename(tmp_path, sizeof(tmp_path) - 1, new_db.str, tmp_name.str, "",
FN_IS_TMP);
}
else
@@ -227,14 +230,14 @@ bool Sql_cmd_alter_table::execute(THD *thd)
priv_needed|= DROP_ACL;
/* Must be set in the parser */
- DBUG_ASSERT(select_lex->db);
+ DBUG_ASSERT(select_lex->db.str);
DBUG_ASSERT(!(alter_info.flags & Alter_info::ALTER_EXCHANGE_PARTITION));
DBUG_ASSERT(!(alter_info.flags & Alter_info::ALTER_ADMIN_PARTITION));
- if (check_access(thd, priv_needed, first_table->db,
+ if (check_access(thd, priv_needed, first_table->db.str,
&first_table->grant.privilege,
&first_table->grant.m_internal,
0, 0) ||
- check_access(thd, INSERT_ACL | CREATE_ACL, select_lex->db,
+ check_access(thd, INSERT_ACL | CREATE_ACL, select_lex->db.str,
&priv,
NULL, /* Don't use first_tab->grant with sel_lex->db */
0, 0))
@@ -291,7 +294,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
// Rename of table
TABLE_LIST tmp_table;
memset(&tmp_table, 0, sizeof(tmp_table));
- tmp_table.table_name= lex->name.str;
+ tmp_table.table_name= lex->name;
tmp_table.db= select_lex->db;
tmp_table.grant.privilege= priv;
if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, FALSE,
@@ -316,13 +319,13 @@ bool Sql_cmd_alter_table::execute(THD *thd)
if ((!thd->is_current_stmt_binlog_format_row() ||
!thd->find_temporary_table(first_table)))
{
- WSREP_TO_ISOLATION_BEGIN(((lex->name.str) ? select_lex->db : NULL),
+ WSREP_TO_ISOLATION_BEGIN(((lex->name.str) ? select_lex->db.str : NULL),
((lex->name.str) ? lex->name.str : NULL),
first_table);
}
#endif /* WITH_WSREP */
- result= mysql_alter_table(thd, select_lex->db, lex->name.str,
+ result= mysql_alter_table(thd, &select_lex->db, &lex->name,
&create_info,
first_table,
&alter_info,
@@ -346,7 +349,7 @@ bool Sql_cmd_discard_import_tablespace::execute(THD *thd)
/* first table of first SELECT_LEX */
TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
- if (check_access(thd, ALTER_ACL, table_list->db,
+ if (check_access(thd, ALTER_ACL, table_list->db.str,
&table_list->grant.privilege,
&table_list->grant.m_internal,
0, 0))
diff --git a/sql/sql_alter.h b/sql/sql_alter.h
index a37d96934ea..4314d662d3d 100644
--- a/sql/sql_alter.h
+++ b/sql/sql_alter.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2010, 2014, Oracle and/or its affiliates.
- Copyright (c) 2013, 2014, Monty Program Ab.
+ Copyright (c) 2013, 2018, 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
@@ -38,68 +38,92 @@ public:
type of index to be added/dropped.
*/
- enum operations_used_flags
- {
- // Set for ADD [COLUMN]
- ALTER_ADD_COLUMN = 1L << 0,
- // Set for DROP [COLUMN]
- ALTER_DROP_COLUMN = 1L << 1,
- // Set for CHANGE [COLUMN] | MODIFY [CHANGE] & mysql_recreate_table
- ALTER_CHANGE_COLUMN = 1L << 2,
- // Set for ADD INDEX | ADD KEY | ADD PRIMARY KEY | ADD UNIQUE KEY |
- // ADD UNIQUE INDEX | ALTER ADD [COLUMN]
- ALTER_ADD_INDEX = 1L << 3,
- // Set for DROP PRIMARY KEY | DROP FOREIGN KEY | DROP KEY | DROP INDEX
- ALTER_DROP_INDEX = 1L << 4,
- // Set for RENAME [TO]
- ALTER_RENAME = 1L << 5,
- // Set for ORDER BY
- ALTER_ORDER = 1L << 6,
- // Set for table_options
- ALTER_OPTIONS = 1L << 7,
- // Set for ALTER [COLUMN] ... SET DEFAULT ... | DROP DEFAULT
- ALTER_CHANGE_COLUMN_DEFAULT = 1L << 8,
- // Set for DISABLE KEYS | ENABLE KEYS
- ALTER_KEYS_ONOFF = 1L << 9,
- // Set for FORCE, ENGINE(same engine), by mysql_recreate_table()
- ALTER_RECREATE = 1L << 10,
- // Set for ADD PARTITION
- ALTER_ADD_PARTITION = 1L << 11,
- // Set for DROP PARTITION
- ALTER_DROP_PARTITION = 1L << 12,
- // Set for COALESCE PARTITION
- ALTER_COALESCE_PARTITION = 1L << 13,
- // Set for REORGANIZE PARTITION ... INTO
- ALTER_REORGANIZE_PARTITION = 1L << 14,
- // Set for partition_options
- ALTER_PARTITION = 1L << 15,
- // Set for LOAD INDEX INTO CACHE ... PARTITION
- // Set for CACHE INDEX ... PARTITION
- ALTER_ADMIN_PARTITION = 1L << 16,
- // Set for REORGANIZE PARTITION
- ALTER_TABLE_REORG = 1L << 17,
- // Set for REBUILD PARTITION
- ALTER_REBUILD_PARTITION = 1L << 18,
- // Set for partitioning operations specifying ALL keyword
- ALTER_ALL_PARTITION = 1L << 19,
- // Set for REMOVE PARTITIONING
- ALTER_REMOVE_PARTITIONING = 1L << 20,
- // Set for ADD FOREIGN KEY
- ADD_FOREIGN_KEY = 1L << 21,
- // Set for DROP FOREIGN KEY
- DROP_FOREIGN_KEY = 1L << 22,
- // Set for EXCHANGE PARITION
- ALTER_EXCHANGE_PARTITION = 1L << 23,
- // Set by Sql_cmd_alter_table_truncate_partition::execute()
- ALTER_TRUNCATE_PARTITION = 1L << 24,
- // Set for ADD [COLUMN] FIRST | AFTER
- ALTER_COLUMN_ORDER = 1L << 25,
- ALTER_ADD_CHECK_CONSTRAINT = 1L << 27,
- ALTER_DROP_CHECK_CONSTRAINT = 1L << 28
- };
+ /** Set for ADD [COLUMN] */
+ static const ulonglong ALTER_ADD_COLUMN = 1ULL << 0;
+ /** Set for DROP [COLUMN] */
+ static const ulonglong ALTER_DROP_COLUMN = 1ULL << 1;
+ /** Set for CHANGE [COLUMN] | MODIFY [CHANGE] & mysql_recreate_table */
+ static const ulonglong ALTER_CHANGE_COLUMN = 1ULL << 2;
+ /** Set for ADD INDEX | ADD KEY | ADD PRIMARY KEY | ADD UNIQUE KEY |
+ ADD UNIQUE INDEX | ALTER ADD [COLUMN] */
+ static const ulonglong ALTER_ADD_INDEX = 1ULL << 3;
+ /** Set for DROP PRIMARY KEY | DROP FOREIGN KEY | DROP KEY | DROP INDEX */
+ static const ulonglong ALTER_DROP_INDEX = 1ULL << 4;
+ /** Set for RENAME [TO] */
+ static const ulonglong ALTER_RENAME = 1ULL << 5;
+ /** Set for ORDER BY */
+ static const ulonglong ALTER_ORDER = 1ULL << 6;
+ /** Set for table_options */
+ static const ulonglong ALTER_OPTIONS = 1ULL << 7;
+ /** Set for ALTER [COLUMN] ... SET DEFAULT ... | DROP DEFAULT */
+ static const ulonglong ALTER_CHANGE_COLUMN_DEFAULT = 1ULL << 8;
+ /** Set for DISABLE KEYS | ENABLE KEYS */
+ static const ulonglong ALTER_KEYS_ONOFF = 1ULL << 9;
+ /** Set for FORCE, ENGINE(same engine), by mysql_recreate_table() */
+ static const ulonglong ALTER_RECREATE = 1ULL << 10;
+ /** Set for ADD PARTITION */
+ static const ulonglong ALTER_ADD_PARTITION = 1ULL << 11;
+ /** Set for DROP PARTITION */
+ static const ulonglong ALTER_DROP_PARTITION = 1ULL << 12;
+ /** Set for COALESCE PARTITION */
+ static const ulonglong ALTER_COALESCE_PARTITION = 1ULL << 13;
+ /** Set for REORGANIZE PARTITION ... INTO */
+ static const ulonglong ALTER_REORGANIZE_PARTITION = 1ULL << 14;
+ /** Set for partition_options */
+ static const ulonglong ALTER_PARTITION = 1ULL << 15;
+ /** Set for LOAD INDEX INTO CACHE ... PARTITION
+ and CACHE INDEX ... PARTITION */
+ static const ulonglong ALTER_ADMIN_PARTITION = 1ULL << 16;
+ /** Set for REORGANIZE PARTITION */
+ static const ulonglong ALTER_TABLE_REORG = 1ULL << 17;
+ /** Set for REBUILD PARTITION */
+ static const ulonglong ALTER_REBUILD_PARTITION = 1ULL << 18;
+ /** Set for partitioning operations specifying ALL keyword */
+ static const ulonglong ALTER_ALL_PARTITION = 1ULL << 19;
+ /** Set for REMOVE PARTITIONING */
+ static const ulonglong ALTER_REMOVE_PARTITIONING = 1ULL << 20;
+ /** Set for ADD FOREIGN KEY */
+ static const ulonglong ADD_FOREIGN_KEY = 1ULL << 21;
+ /** Set for DROP FOREIGN KEY */
+ static const ulonglong DROP_FOREIGN_KEY = 1ULL << 22;
+ /** Set for EXCHANGE PARITION */
+ static const ulonglong ALTER_EXCHANGE_PARTITION = 1ULL << 23;
+ /** Set by Sql_cmd_alter_table_truncate_partition::execute() */
+ static const ulonglong ALTER_TRUNCATE_PARTITION = 1ULL << 24;
+ /** Set for ADD [COLUMN] FIRST | AFTER */
+ static const ulonglong ALTER_COLUMN_ORDER = 1ULL << 25;
+ static const ulonglong ALTER_ADD_CHECK_CONSTRAINT = 1ULL << 27;
+ static const ulonglong ALTER_DROP_CHECK_CONSTRAINT = 1ULL << 28;
+ static const ulonglong ALTER_RENAME_COLUMN = 1ULL << 29;
+ static const ulonglong ALTER_COLUMN_UNVERSIONED = 1ULL << 30;
+ static const ulonglong ALTER_ADD_SYSTEM_VERSIONING = 1ULL << 31;
+ static const ulonglong ALTER_DROP_SYSTEM_VERSIONING= 1ULL << 32;
+ static const ulonglong ALTER_ADD_PERIOD = 1ULL << 33;
+ static const ulonglong ALTER_DROP_PERIOD = 1ULL << 34;
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
+ bool data_modifying() const
+ {
+ return flags & (
+ ALTER_ADD_COLUMN |
+ ALTER_DROP_COLUMN |
+ ALTER_CHANGE_COLUMN |
+ ALTER_COLUMN_ORDER);
+ }
+
+ bool partition_modifying() const
+ {
+ return flags & (
+ ALTER_DROP_PARTITION |
+ ALTER_COALESCE_PARTITION |
+ ALTER_REORGANIZE_PARTITION |
+ ALTER_REMOVE_PARTITIONING |
+ ALTER_TABLE_REORG |
+ ALTER_EXCHANGE_PARTITION |
+ ALTER_TRUNCATE_PARTITION);
+ }
+
/**
The different values of the ALGORITHM clause.
Describes which algorithm to use when altering the table.
@@ -152,7 +176,7 @@ public:
};
List<Virtual_column_info> check_constraint_list;
// Type of ALTER TABLE operation.
- uint flags;
+ ulonglong flags;
// Enable or disable keys.
enum_enable_or_disable keys_onoff;
// List of partitions.
@@ -244,19 +268,19 @@ public:
Alter_table_ctx();
Alter_table_ctx(THD *thd, TABLE_LIST *table_list, uint tables_opened_arg,
- const char *new_db_arg, const char *new_name_arg);
+ const LEX_CSTRING *new_db_arg, const LEX_CSTRING *new_name_arg);
/**
@return true if the table is moved to another database, false otherwise.
*/
bool is_database_changed() const
- { return (new_db != db); };
+ { return (new_db.str != db.str); };
/**
@return true if the table is renamed, false otherwise.
*/
bool is_table_renamed() const
- { return (is_database_changed() || new_name != table_name); };
+ { return (is_database_changed() || new_name.str != table_name.str); };
/**
@return filename (including .frm) for the new table.
@@ -306,13 +330,14 @@ public:
Create_field *datetime_field;
bool error_if_not_empty;
uint tables_opened;
- const char *db;
- const char *table_name;
- const char *alias;
- const char *new_db;
- const char *new_name;
- const char *new_alias;
- char tmp_name[80];
+ LEX_CSTRING db;
+ LEX_CSTRING table_name;
+ LEX_CSTRING alias;
+ LEX_CSTRING new_db;
+ LEX_CSTRING new_name;
+ LEX_CSTRING new_alias;
+ LEX_CSTRING tmp_name;
+ char tmp_buff[80];
/**
Indicates that if a row is deleted during copying of data from old version
of table to the new version ER_FK_CANNOT_DELETE_PARENT error should be
@@ -326,7 +351,8 @@ public:
private:
char new_filename[FN_REFLEN + 1];
- char new_alias_buff[FN_REFLEN + 1];
+ char new_alias_buff[NAME_LEN + 1];
+ char tmp_name_buff[NAME_LEN + 1];
char path[FN_REFLEN + 1];
char new_path[FN_REFLEN + 1];
char tmp_path[FN_REFLEN + 1];
@@ -387,13 +413,15 @@ public:
/**
Sql_cmd_alter_sequence represents the ALTER SEQUENCE statement.
*/
-class Sql_cmd_alter_sequence : public Sql_cmd
+class Sql_cmd_alter_sequence : public Sql_cmd,
+ public DDL_options
{
public:
/**
Constructor, used to represent a ALTER TABLE statement.
*/
- Sql_cmd_alter_sequence()
+ Sql_cmd_alter_sequence(const DDL_options &options)
+ :DDL_options(options)
{}
~Sql_cmd_alter_sequence()
diff --git a/sql/sql_array.h b/sql/sql_array.h
index bbaa653b177..cad7b0e1c48 100644
--- a/sql/sql_array.h
+++ b/sql/sql_array.h
@@ -191,9 +191,10 @@ public:
return *((Elem*)pop_dynamic(&array));
}
- void del(uint idx)
+ void del(size_t idx)
{
- delete_dynamic_element(&array, idx);
+ DBUG_ASSERT(idx <= array.max_element);
+ delete_dynamic_element(&array, (uint)idx);
}
size_t elements() const
@@ -204,7 +205,7 @@ public:
void elements(size_t num_elements)
{
DBUG_ASSERT(num_elements <= array.max_element);
- array.elements= num_elements;
+ array.elements= (uint)num_elements;
}
void clear()
@@ -220,12 +221,12 @@ public:
bool resize(size_t new_size, Elem default_val)
{
size_t old_size= elements();
- if (allocate_dynamic(&array, new_size))
+ if (allocate_dynamic(&array, (uint)new_size))
return true;
if (new_size > old_size)
{
- set_dynamic(&array, (uchar*)&default_val, new_size - 1);
+ set_dynamic(&array, (uchar*)&default_val, (uint)(new_size - 1));
/*for (size_t i= old_size; i != new_size; i++)
{
at(i)= default_val;
@@ -258,4 +259,6 @@ public:
}
};
+typedef Bounds_checked_array<Item*> Ref_ptr_array;
+
#endif /* SQL_ARRAY_INCLUDED */
diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc
index 7c8b355b8d0..793e3a801b3 100644
--- a/sql/sql_audit.cc
+++ b/sql/sql_audit.cc
@@ -15,6 +15,7 @@
#include "mariadb.h"
#include "sql_priv.h"
+#include "mysqld.h"
#include "sql_audit.h"
extern int initialize_audit_plugin(st_plugin_int *plugin);
diff --git a/sql/sql_audit.h b/sql/sql_audit.h
index 7a11f5aa113..5c66138b466 100644
--- a/sql/sql_audit.h
+++ b/sql/sql_audit.h
@@ -121,15 +121,13 @@ void mysql_audit_general_log(THD *thd, time_t time,
event.general_thread_id= (unsigned long)thd->thread_id;
event.general_charset= thd->variables.character_set_client;
event.database= thd->db;
- event.database_length= (unsigned int)thd->db_length;
event.query_id= thd->query_id;
}
else
{
event.general_thread_id= 0;
event.general_charset= global_system_variables.character_set_client;
- event.database= "";
- event.database_length= 0;
+ event.database= null_clex_str;
event.query_id= 0;
}
@@ -175,7 +173,6 @@ void mysql_audit_general(THD *thd, uint event_subtype,
event.general_charset= thd->query_string.charset();
event.general_rows= thd->get_stmt_da()->current_row_for_warning();
event.database= thd->db;
- event.database_length= (uint)thd->db_length;
event.query_id= thd->query_id;
}
else
@@ -187,8 +184,7 @@ void mysql_audit_general(THD *thd, uint event_subtype,
event.general_query_length= 0;
event.general_charset= &my_charset_bin;
event.general_rows= 0;
- event.database= "";
- event.database_length= 0;
+ event.database= null_clex_str;
event.query_id= 0;
}
@@ -222,7 +218,6 @@ void mysql_audit_notify_connection_connect(THD *thd)
event.ip= sctx->ip;
event.ip_length= safe_strlen_uint(sctx->ip);
event.database= thd->db;
- event.database_length= safe_strlen_uint(thd->db);
mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event);
}
@@ -252,7 +247,6 @@ void mysql_audit_notify_connection_disconnect(THD *thd, int errcode)
event.ip= sctx->ip;
event.ip_length= safe_strlen_uint(sctx->ip) ;
event.database= thd->db;
- event.database_length= safe_strlen_uint(thd->db);
mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event);
}
@@ -283,7 +277,6 @@ void mysql_audit_notify_connection_change_user(THD *thd)
event.ip= sctx->ip;
event.ip_length= safe_strlen_uint(sctx->ip);
event.database= thd->db;
- event.database_length= safe_strlen_uint(thd->db);
mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event);
}
@@ -307,14 +300,10 @@ void mysql_audit_external_lock(THD *thd, TABLE_SHARE *share, int lock)
event.proxy_user= sctx->proxy_user;
event.host= sctx->host;
event.ip= sctx->ip;
- event.database= share->db.str;
- event.database_length= (unsigned int)share->db.length;
- event.table= share->table_name.str;
- event.table_length= (unsigned int)share->table_name.length;
- event.new_database= 0;
- event.new_database_length= 0;
- event.new_table= 0;
- event.new_table_length= 0;
+ event.database= share->db;
+ event.table= share->table_name;
+ event.new_database= null_clex_str;
+ event.new_table= null_clex_str;
event.query_id= thd->query_id;
mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event);
@@ -341,15 +330,11 @@ void mysql_audit_create_table(TABLE *table)
event.proxy_user= sctx->proxy_user;
event.host= sctx->host;
event.ip= sctx->ip;
- event.database= share->db.str;
- event.database_length= (unsigned int)share->db.length;
- event.table= share->table_name.str;
- event.table_length= (unsigned int)share->table_name.length;
- event.new_database= 0;
- event.new_database_length= 0;
- event.new_table= 0;
- event.new_table_length= 0;
- event.query_id= thd->query_id;
+ event.database= share->db;
+ event.table= share->table_name;
+ event.new_database= null_clex_str;
+ event.new_table= null_clex_str;
+ event.query_id= thd->query_id;
mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event);
}
@@ -373,23 +358,20 @@ void mysql_audit_drop_table(THD *thd, TABLE_LIST *table)
event.proxy_user= sctx->proxy_user;
event.host= sctx->host;
event.ip= sctx->ip;
- event.database= table->db;
- event.database_length= (unsigned int)table->db_length;
- event.table= table->table_name;
- event.table_length= (unsigned int)table->table_name_length;
- event.new_database= 0;
- event.new_database_length= 0;
- event.new_table= 0;
- event.new_table_length= 0;
- event.query_id= thd->query_id;
+ event.database= table->db;
+ event.table= table->table_name;
+ event.new_database= null_clex_str;
+ event.new_table= null_clex_str;
+ event.query_id= thd->query_id;
mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event);
}
}
static inline
-void mysql_audit_rename_table(THD *thd, const char *old_db, const char *old_tb,
- const char *new_db, const char *new_tb)
+void mysql_audit_rename_table(THD *thd, const LEX_CSTRING *old_db,
+ const LEX_CSTRING *old_tb,
+ const LEX_CSTRING *new_db, const LEX_CSTRING *new_tb)
{
if (mysql_audit_table_enabled())
{
@@ -406,14 +388,10 @@ void mysql_audit_rename_table(THD *thd, const char *old_db, const char *old_tb,
event.proxy_user= sctx->proxy_user;
event.host= sctx->host;
event.ip= sctx->ip;
- event.database= old_db;
- event.database_length= strlen_uint(old_db);
- event.table= old_tb;
- event.table_length= strlen_uint(old_tb);
- event.new_database= new_db;
- event.new_database_length= strlen_uint(new_db);
- event.new_table= new_tb;
- event.new_table_length= strlen_uint(new_tb);
+ event.database= *old_db;
+ event.table= *old_tb;
+ event.new_database= *new_db;
+ event.new_table= *new_tb;
event.query_id= thd->query_id;
mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event);
@@ -439,13 +417,9 @@ void mysql_audit_alter_table(THD *thd, TABLE_LIST *table)
event.host= sctx->host;
event.ip= sctx->ip;
event.database= table->db;
- event.database_length= (unsigned int)table->db_length;
event.table= table->table_name;
- event.table_length= (unsigned int)table->table_name_length;
- event.new_database= 0;
- event.new_database_length= 0;
- event.new_table= 0;
- event.new_table_length= 0;
+ event.new_database= null_clex_str;
+ event.new_table= null_clex_str;
event.query_id= thd->query_id;
mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 0a84dc2b351..902933ffed8 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -244,8 +244,9 @@ struct list_open_tables_arg
static my_bool list_open_tables_callback(TDC_element *element,
list_open_tables_arg *arg)
{
- char *db= (char*) element->m_key;
- char *table_name= (char*) element->m_key + strlen((char*) element->m_key) + 1;
+ const char *db= (char*) element->m_key;
+ size_t db_length= strlen(db);
+ const char *table_name= db + db_length + 1;
if (arg->db && my_strcasecmp(system_charset_info, arg->db, db))
return FALSE;
@@ -253,8 +254,10 @@ static my_bool list_open_tables_callback(TDC_element *element,
return FALSE;
/* Check if user has SELECT privilege for any column in the table */
- arg->table_list.db= db;
- arg->table_list.table_name= table_name;
+ arg->table_list.db.str= db;
+ arg->table_list.db.length= db_length;
+ arg->table_list.table_name.str= table_name;
+ arg->table_list.table_name.length= strlen(table_name);
arg->table_list.grant.privilege= 0;
if (check_table_access(arg->thd, SELECT_ACL, &arg->table_list, TRUE, 1, TRUE))
@@ -381,8 +384,8 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables,
for (TABLE_LIST *table= tables; table; table= table->next_local)
{
/* tdc_remove_table() also sets TABLE_SHARE::version to 0. */
- found|= tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, table->db,
- table->table_name, TRUE);
+ found|= tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, table->db.str,
+ table->table_name.str, TRUE);
}
if (!found)
wait_for_refresh=0; // Nothing to wait for
@@ -412,8 +415,8 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables,
table_list= table_list->next_global)
{
/* A check that the table was locked for write is done by the caller. */
- TABLE *table= find_table_for_mdl_upgrade(thd, table_list->db,
- table_list->table_name, TRUE);
+ TABLE *table= find_table_for_mdl_upgrade(thd, table_list->db.str,
+ table_list->table_name.str, TRUE);
/* May return NULL if this table has already been closed via an alias. */
if (! table)
@@ -463,7 +466,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables,
{
if (thd->killed)
break;
- if (tdc_wait_for_old_version(thd, table->db, table->table_name, timeout,
+ if (tdc_wait_for_old_version(thd, table->db.str, table->table_name.str, timeout,
MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DDL,
refresh_version))
{
@@ -530,9 +533,9 @@ static my_bool close_cached_connection_tables_callback(
/* close_cached_tables() only uses these elements */
if (!(tmp= (TABLE_LIST*) alloc_root(arg->thd->mem_root, sizeof(TABLE_LIST))) ||
- !(tmp->db= strdup_root(arg->thd->mem_root, element->share->db.str)) ||
- !(tmp->table_name= strdup_root(arg->thd->mem_root,
- element->share->table_name.str)))
+ !(arg->thd->make_lex_string(&tmp->db, element->share->db.str, element->share->db.length)) ||
+ !(arg->thd->make_lex_string(&tmp->table_name, element->share->table_name.str,
+ element->share->table_name.length)))
{
mysql_mutex_unlock(&element->LOCK_table_share);
return TRUE;
@@ -641,7 +644,7 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
DBUG_ASSERT(!share->tmp_table);
char key[MAX_DBKEY_LENGTH];
- uint key_length= share->table_cache_key.length;
+ size_t key_length= share->table_cache_key.length;
const char *db= key;
const char *table_name= db + share->db.length + 1;
@@ -878,6 +881,12 @@ void close_thread_table(THD *thd, TABLE **table_ptr)
table->file->update_global_index_stats();
}
+ /*
+ This look is needed to allow THD::notify_shared_lock() to
+ traverse the thd->open_tables list without having to worry that
+ some of the tables are removed from under it
+ */
+
mysql_mutex_lock(&thd->LOCK_thd_data);
*table_ptr=table->next;
mysql_mutex_unlock(&thd->LOCK_thd_data);
@@ -913,8 +922,7 @@ void close_thread_table(THD *thd, TABLE **table_ptr)
table_name Table name
NOTES:
- This is called by find_table_in_local_list() and
- find_table_in_global_list().
+ This is called by find_table_in_global_list().
RETURN VALUES
NULL Table not found
@@ -923,13 +931,13 @@ void close_thread_table(THD *thd, TABLE **table_ptr)
TABLE_LIST *find_table_in_list(TABLE_LIST *table,
TABLE_LIST *TABLE_LIST::*link,
- const char *db_name,
- const char *table_name)
+ const LEX_CSTRING *db_name,
+ const LEX_CSTRING *table_name)
{
for (; table; table= table->*link )
{
- if (strcmp(table->db, db_name) == 0 &&
- strcmp(table->table_name, table_name) == 0)
+ if (cmp(&table->db, db_name) == 0 &&
+ cmp(&table->table_name, table_name) == 0)
break;
}
return table;
@@ -974,9 +982,9 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
bool check_alias)
{
TABLE_LIST *res;
- const char *d_name, *t_name, *t_alias;
+ LEX_CSTRING *d_name, *t_name, *t_alias;
DBUG_ENTER("find_dup_table");
- DBUG_PRINT("enter", ("table alias: %s", table->alias));
+ DBUG_PRINT("enter", ("table alias: %s", table->alias.str));
/*
If this function called for query which update table (INSERT/UPDATE/...)
@@ -1000,12 +1008,12 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
*/
DBUG_ASSERT(table);
}
- d_name= table->db;
- t_name= table->table_name;
- t_alias= table->alias;
+ d_name= &table->db;
+ t_name= &table->table_name;
+ t_alias= &table->alias;
retry:
- DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name));
+ DBUG_PRINT("info", ("real table: %s.%s", d_name->str, t_name->str));
for (TABLE_LIST *tl= table_list;;)
{
if (tl &&
@@ -1033,7 +1041,7 @@ retry:
/* Skip if table alias does not match. */
if (check_alias)
{
- if (my_strcasecmp(table_alias_charset, t_alias, res->alias))
+ if (my_strcasecmp(table_alias_charset, t_alias->str, res->alias.str))
goto next;
}
@@ -1096,14 +1104,32 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
table= table->find_table_for_update();
- if (table->table && table->table->file->ht->db_type == DB_TYPE_MRG_MYISAM)
+ if (table->table &&
+ table->table->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
{
TABLE_LIST *child;
dup= NULL;
/* Check duplicates of all merge children. */
- for (child= table->next_global; child && child->parent_l == table;
+ for (child= table->next_global; child;
child= child->next_global)
{
+ if (child->table &&
+ child->table->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
+ continue;
+
+ /*
+ Ensure that the child has one parent that is the table that is
+ updated.
+ */
+ TABLE_LIST *tmp_parent= child;
+ while ((tmp_parent= tmp_parent->parent_l))
+ {
+ if (tmp_parent == table)
+ break;
+ }
+ if (!tmp_parent)
+ break;
+
if ((dup= find_dup_table(thd, child, child->next_global, check_alias)))
break;
}
@@ -1112,6 +1138,8 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
dup= find_dup_table(thd, table, table_list, check_alias);
return dup;
}
+
+
/*
Issue correct error message in case we found 2 duplicate tables which
prevent some update operation
@@ -1151,21 +1179,21 @@ void update_non_unique_table_error(TABLE_LIST *update,
if (update->view == duplicate->view)
my_error(!strncmp(operation, "INSERT", 6) ?
ER_NON_INSERTABLE_TABLE : ER_NON_UPDATABLE_TABLE, MYF(0),
- update->alias, operation);
+ update->alias.str, operation);
else
my_error(ER_VIEW_PREVENT_UPDATE, MYF(0),
- (duplicate->view ? duplicate->alias : update->alias),
- operation, update->alias);
+ (duplicate->view ? duplicate->alias.str : update->alias.str),
+ operation, update->alias.str);
return;
}
if (duplicate->view)
{
- my_error(ER_VIEW_PREVENT_UPDATE, MYF(0), duplicate->alias, operation,
- update->alias);
+ my_error(ER_VIEW_PREVENT_UPDATE, MYF(0), duplicate->alias.str, operation,
+ update->alias.str);
return;
}
}
- my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias, operation);
+ my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias.str, operation);
}
@@ -1230,8 +1258,8 @@ bool wait_while_table_is_used(THD *thd, TABLE *table,
prelocked mode, e.g. if we do CREATE TABLE .. SELECT f1();
*/
-void drop_open_table(THD *thd, TABLE *table, const char *db_name,
- const char *table_name)
+void drop_open_table(THD *thd, TABLE *table, const LEX_CSTRING *db_name,
+ const LEX_CSTRING *table_name)
{
DBUG_ENTER("drop_open_table");
if (table->s->tmp_table)
@@ -1244,7 +1272,7 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name,
table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
close_thread_table(thd, &thd->open_tables);
/* Remove the table share from the table cache. */
- tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db_name, table_name,
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db_name->str, table_name->str,
FALSE);
/* Remove the table from the storage engine and rm the .frm. */
quick_rm_table(thd, table_type, db_name, table_name, 0);
@@ -1481,11 +1509,12 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
TABLE *table;
const char *key;
uint key_length;
- const char *alias= table_list->alias;
+ const char *alias= table_list->alias.str;
uint flags= ot_ctx->get_flags();
MDL_ticket *mdl_ticket;
TABLE_SHARE *share;
uint gts_flags;
+ int part_names_error=0;
DBUG_ENTER("open_table");
/*
@@ -1583,6 +1612,12 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
table= best_table;
table->query_id= thd->query_id;
DBUG_PRINT("info",("Using locked table"));
+ if (table->part_info)
+ {
+ /* Set all [named] partitions as used. */
+ part_names_error=
+ table->file->change_partitions_to_open(table_list->partition_names);
+ }
goto reset;
}
/*
@@ -1595,13 +1630,13 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
to deadlocks) it should be disallowed.
*/
if (thd->mdl_context.is_lock_owner(MDL_key::TABLE,
- table_list->db,
- table_list->table_name,
+ table_list->db.str,
+ table_list->table_name.str,
MDL_SHARED))
{
char path[FN_REFLEN + 1];
build_table_filename(path, sizeof(path) - 1,
- table_list->db, table_list->table_name, reg_ext, 0);
+ table_list->db.str, table_list->table_name.str, reg_ext, 0);
/*
Note that we can't be 100% sure that it is a view since it's
possible that we either simply have not found unused TABLE
@@ -1636,7 +1671,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
locked tables list was created.
*/
if (thd->locked_tables_mode == LTM_PRELOCKED)
- my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
+ my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db.str, table_list->alias.str);
else
my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
DBUG_RETURN(TRUE);
@@ -1722,7 +1757,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
if (table_list->open_strategy == TABLE_LIST::OPEN_IF_EXISTS)
{
- if (!ha_table_exists(thd, table_list->db, table_list->table_name))
+ if (!ha_table_exists(thd, &table_list->db, &table_list->table_name))
DBUG_RETURN(FALSE);
}
else if (table_list->open_strategy == TABLE_LIST::OPEN_STUB)
@@ -1785,7 +1820,8 @@ retry_share:
}
if (table_list->sequence)
{
- my_error(ER_NOT_SEQUENCE, MYF(0), table_list->db, table_list->alias);
+ my_error(ER_NOT_SEQUENCE, MYF(0), table_list->db.str,
+ table_list->alias.str);
goto err_lock;
}
/*
@@ -1832,8 +1868,8 @@ retry_share:
bool wait_result;
thd->push_internal_handler(&mdl_deadlock_handler);
- wait_result= tdc_wait_for_old_version(thd, table_list->db,
- table_list->table_name,
+ wait_result= tdc_wait_for_old_version(thd, table_list->db.str,
+ table_list->table_name.str,
ot_ctx->get_timeout(),
mdl_ticket->get_deadlock_weight());
thd->pop_internal_handler();
@@ -1866,6 +1902,12 @@ retry_share:
{
DBUG_ASSERT(table->file != NULL);
MYSQL_REBIND_TABLE(table->file);
+ if (table->part_info)
+ {
+ /* Set all [named] partitions as used. */
+ part_names_error=
+ table->file->change_partitions_to_open(table_list->partition_names);
+ }
}
else
{
@@ -1875,10 +1917,11 @@ retry_share:
if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))))
goto err_lock;
- error= open_table_from_share(thd, share, alias,
+ error= open_table_from_share(thd, share, &table_list->alias,
HA_OPEN_KEYFILE | HA_TRY_READ_ONLY,
EXTRA_RECORD,
- thd->open_options, table, FALSE);
+ thd->open_options, table, FALSE,
+ table_list->partition_names);
if (error)
{
@@ -1927,9 +1970,12 @@ retry_share:
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (table->part_info)
{
- /* Set all [named] partitions as used. */
- if (table->part_info->set_partition_bitmaps(table_list))
+ /* Partitions specified were incorrect.*/
+ if (part_names_error)
+ {
+ table->file->print_error(part_names_error, MYF(0));
DBUG_RETURN(true);
+ }
}
else if (table_list->partition_names)
{
@@ -1940,7 +1986,7 @@ retry_share:
#endif
if (table_list->sequence && table->s->table_type != TABLE_TYPE_SEQUENCE)
{
- my_error(ER_NOT_SEQUENCE, MYF(0), table_list->db, table_list->alias);
+ my_error(ER_NOT_SEQUENCE, MYF(0), table_list->db.str, table_list->alias.str);
DBUG_RETURN(true);
}
@@ -2068,28 +2114,30 @@ Locked_tables_list::init_locked_tables(THD *thd)
table= table->next, m_locked_tables_count++)
{
TABLE_LIST *src_table_list= table->pos_in_table_list;
- char *db, *table_name, *alias;
- size_t db_len= table->s->db.length;
- size_t table_name_len= table->s->table_name.length;
- size_t alias_len= table->alias.length();
+ LEX_CSTRING db, table_name, alias;
+
+ db.length= table->s->db.length;
+ table_name.length= table->s->table_name.length;
+ alias.length= table->alias.length();
TABLE_LIST *dst_table_list;
if (! multi_alloc_root(&m_locked_tables_root,
&dst_table_list, sizeof(*dst_table_list),
- &db, db_len + 1,
- &table_name, table_name_len + 1,
- &alias, alias_len + 1,
+ &db.str, (size_t) db.length + 1,
+ &table_name.str, (size_t) table_name.length + 1,
+ &alias.str, (size_t) alias.length + 1,
NullS))
{
reset();
return TRUE;
}
- memcpy(db, table->s->db.str, db_len + 1);
- memcpy(table_name, table->s->table_name.str, table_name_len + 1);
- strmake(alias, table->alias.ptr(), alias_len);
- dst_table_list->init_one_table(db, db_len, table_name, table_name_len,
- alias, table->reginfo.lock_type);
+ memcpy((char*) db.str, table->s->db.str, db.length + 1);
+ memcpy((char*) table_name.str, table->s->table_name.str,
+ table_name.length + 1);
+ memcpy((char*) alias.str, table->alias.c_ptr(), alias.length + 1);
+ dst_table_list->init_one_table(&db, &table_name,
+ &alias, table->reginfo.lock_type);
dst_table_list->table= table;
dst_table_list->mdl_request.ticket= src_table_list->mdl_request.ticket;
@@ -2356,7 +2404,7 @@ bool
Locked_tables_list::reopen_tables(THD *thd)
{
Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN);
- size_t reopen_count= 0;
+ uint reopen_count= 0;
MYSQL_LOCK *lock;
MYSQL_LOCK *merged_lock;
DBUG_ENTER("Locked_tables_list::reopen_tables");
@@ -2424,7 +2472,7 @@ bool Locked_tables_list::restore_lock(THD *thd, TABLE_LIST *dst_table_list,
{
MYSQL_LOCK *merged_lock;
DBUG_ENTER("restore_lock");
- DBUG_ASSERT(!strcmp(dst_table_list->table_name, table->s->table_name.str));
+ DBUG_ASSERT(!strcmp(dst_table_list->table_name.str, table->s->table_name.str));
/* Ensure we have the memory to add the table back */
if (!(merged_lock= mysql_lock_merge(thd->lock, lock)))
@@ -2653,8 +2701,8 @@ ret:
static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share, TABLE *entry)
{
- if (Table_triggers_list::check_n_load(thd, share->db.str,
- share->table_name.str, entry, 0))
+ if (Table_triggers_list::check_n_load(thd, &share->db,
+ &share->table_name, entry, 0))
return TRUE;
/*
@@ -2671,10 +2719,9 @@ static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share, TABLE *entry)
query.length(0);
query.append("DELETE FROM ");
- append_identifier(thd, &query, share->db.str, share->db.length);
+ append_identifier(thd, &query, &share->db);
query.append(".");
- append_identifier(thd, &query, share->table_name.str,
- share->table_name.length);
+ append_identifier(thd, &query, &share->table_name);
/*
we bypass thd->binlog_query() here,
@@ -2710,7 +2757,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list)
DBUG_ASSERT(! share->is_view);
- if (open_table_from_share(thd, share, table_list->alias,
+ if (open_table_from_share(thd, share, &table_list->alias,
HA_OPEN_KEYFILE | HA_TRY_READ_ONLY,
EXTRA_RECORD,
ha_open_options | HA_OPEN_FOR_REPAIR,
@@ -2735,7 +2782,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list)
tdc_release_share(share);
/* Remove the repaired share from the table cache. */
tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
- table_list->db, table_list->table_name,
+ table_list->db.str, table_list->table_name.str,
FALSE);
end_free:
my_free(entry);
@@ -2838,10 +2885,7 @@ request_backoff_action(enum_open_table_action action_arg,
m_failed_table= (TABLE_LIST*) m_thd->alloc(sizeof(TABLE_LIST));
if (m_failed_table == NULL)
return TRUE;
- m_failed_table->init_one_table(table->db, table->db_length,
- table->table_name,
- table->table_name_length,
- table->alias, TL_WRITE);
+ m_failed_table->init_one_table(&table->db, &table->table_name, &table->alias, TL_WRITE);
m_failed_table->open_strategy= table->open_strategy;
m_failed_table->mdl_request.set_type(MDL_EXCLUSIVE);
}
@@ -2910,8 +2954,8 @@ Open_table_context::recover_from_failed_open()
get_timeout(), 0)))
break;
- tdc_remove_table(m_thd, TDC_RT_REMOVE_ALL, m_failed_table->db,
- m_failed_table->table_name, FALSE);
+ tdc_remove_table(m_thd, TDC_RT_REMOVE_ALL, m_failed_table->db.str,
+ m_failed_table->table_name.str, FALSE);
m_thd->get_stmt_da()->clear_warning_info(m_thd->query_id);
m_thd->clear_error(); // Clear error message
@@ -2946,8 +2990,8 @@ Open_table_context::recover_from_failed_open()
get_timeout(), 0)))
break;
- tdc_remove_table(m_thd, TDC_RT_REMOVE_ALL, m_failed_table->db,
- m_failed_table->table_name, FALSE);
+ tdc_remove_table(m_thd, TDC_RT_REMOVE_ALL, m_failed_table->db.str,
+ m_failed_table->table_name.str, FALSE);
result= auto_repair_table(m_thd, m_failed_table);
/*
@@ -3267,10 +3311,8 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
obtain proper metadata locks and do other necessary steps like
stored routine processing.
*/
- tables->db= tables->view_db.str;
- tables->db_length= tables->view_db.length;
- tables->table_name= tables->view_name.str;
- tables->table_name_length= tables->view_name.length;
+ tables->db= tables->view_db;
+ tables->table_name= tables->view_name;
}
else if (tables->select_lex)
{
@@ -3327,7 +3369,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
goto end;
}
DBUG_PRINT("tcache", ("opening table: '%s'.'%s' item: %p",
- tables->db, tables->table_name, tables)); //psergey: invalid read of size 1 here
+ tables->db.str, tables->table_name.str, tables));
(*counter)++;
/*
@@ -3343,7 +3385,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
DBUG_ASSERT(is_temporary_table(tables) || tables->table->s->sequence);
if (tables->sequence && tables->table->s->table_type != TABLE_TYPE_SEQUENCE)
{
- my_error(ER_NOT_SEQUENCE, MYF(0), tables->db, tables->alias);
+ my_error(ER_NOT_SEQUENCE, MYF(0), tables->db.str, tables->alias.str);
DBUG_RETURN(true);
}
}
@@ -3446,7 +3488,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
if (! ot_ctx->can_recover_from_failed_open() && safe_to_ignore_table)
{
DBUG_PRINT("info", ("open_table: ignoring table '%s'.'%s'",
- tables->db, tables->alias));
+ tables->db.str, tables->alias.str));
error= FALSE;
}
goto end;
@@ -3502,7 +3544,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
*/
if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
! has_prelocking_list &&
- tables->lock_type >= TL_WRITE_ALLOW_WRITE)
+ (tables->lock_type >= TL_WRITE_ALLOW_WRITE || thd->lex->default_used))
{
bool need_prelocking= FALSE;
TABLE_LIST **save_query_tables_last= lex->query_tables_last;
@@ -3669,7 +3711,7 @@ lock_table_names(THD *thd, const DDL_options_st &options,
MDL_request *schema_request= new (thd->mem_root) MDL_request;
if (schema_request == NULL)
DBUG_RETURN(TRUE);
- schema_request->init(MDL_key::SCHEMA, table->db, "",
+ schema_request->init(MDL_key::SCHEMA, table->db.str, "",
MDL_INTENTION_EXCLUSIVE,
MDL_TRANSACTION);
mdl_requests.push_front(schema_request);
@@ -3720,17 +3762,17 @@ lock_table_names(THD *thd, const DDL_options_st &options,
We come here in the case of lock timeout when executing CREATE TABLE.
Verify that table does exist (it usually does, as we got a lock conflict)
*/
- if (ha_table_exists(thd, tables_start->db, tables_start->table_name))
+ if (ha_table_exists(thd, &tables_start->db, &tables_start->table_name))
{
if (options.if_not_exists())
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_TABLE_EXISTS_ERROR,
ER_THD(thd, ER_TABLE_EXISTS_ERROR),
- tables_start->table_name);
+ tables_start->table_name.str);
}
else
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), tables_start->table_name);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), tables_start->table_name.str);
DBUG_RETURN(TRUE);
}
/*
@@ -3804,7 +3846,7 @@ open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start,
Note that find_table_for_mdl_upgrade() will report an error if
no suitable ticket is found.
*/
- if (!find_table_for_mdl_upgrade(thd, table->db, table->table_name, false))
+ if (!find_table_for_mdl_upgrade(thd, table->db.str, table->table_name.str, false))
return TRUE;
}
@@ -4089,7 +4131,7 @@ restart:
continue;
/* Schema tables may not have a TABLE object here. */
- if (tbl->file->ht->db_type == DB_TYPE_MRG_MYISAM)
+ if (tbl->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
{
/* MERGE tables need to access parent and child TABLE_LISTs. */
DBUG_ASSERT(tbl->pos_in_table_list == tables);
@@ -4120,7 +4162,7 @@ restart:
(*start)->table &&
(*start)->table->file->ht == myisam_hton &&
wsrep_thd_exec_mode(thd) == LOCAL_STATE &&
- !is_stat_table((*start)->db, (*start)->alias) &&
+ !is_stat_table(&(*start)->db, &(*start)->alias) &&
thd->get_command() != COM_STMT_PREPARE &&
((thd->lex->sql_command == SQLCOM_INSERT ||
thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
@@ -4208,15 +4250,62 @@ static bool table_already_fk_prelocked(TABLE_LIST *tl, LEX_CSTRING *db,
for (; tl; tl= tl->next_global )
{
if (tl->lock_type >= lock_type &&
- tl->prelocking_placeholder == TABLE_LIST::FK &&
- strcmp(tl->db, db->str) == 0 &&
- strcmp(tl->table_name, table->str) == 0)
+ tl->prelocking_placeholder == TABLE_LIST::PRELOCK_FK &&
+ strcmp(tl->db.str, db->str) == 0 &&
+ strcmp(tl->table_name.str, table->str) == 0)
return true;
}
return false;
}
+static bool internal_table_exists(TABLE_LIST *global_list,
+ const char *table_name)
+{
+ do
+ {
+ if (global_list->table_name.str == table_name)
+ return 1;
+ } while ((global_list= global_list->next_global));
+ return 0;
+}
+
+
+static bool
+add_internal_tables(THD *thd, Query_tables_list *prelocking_ctx,
+ TABLE_LIST *tables)
+{
+ TABLE_LIST *global_table_list= prelocking_ctx->query_tables;
+
+ do
+ {
+ /*
+ Skip table if already in the list. Can happen with prepared statements
+ */
+ if (tables->next_local &&
+ internal_table_exists(global_table_list, tables->table_name.str))
+ continue;
+
+ TABLE_LIST *tl= (TABLE_LIST *) thd->alloc(sizeof(TABLE_LIST));
+ if (!tl)
+ return TRUE;
+ tl->init_one_table_for_prelocking(&tables->db,
+ &tables->table_name,
+ NULL, tables->lock_type,
+ TABLE_LIST::PRELOCK_NONE,
+ 0, 0,
+ &prelocking_ctx->query_tables_last);
+ /*
+ Store link to the new table_list that will be used by open so that
+ Item_func_nextval() can find it
+ */
+ tables->next_local= tl;
+ } while ((tables= tables->next_global));
+ return FALSE;
+}
+
+
+
/**
Defines how prelocking algorithm for DML statements should handle table list
elements:
@@ -4243,21 +4332,23 @@ bool DML_prelocking_strategy::
handle_table(THD *thd, Query_tables_list *prelocking_ctx,
TABLE_LIST *table_list, bool *need_prelocking)
{
+ TABLE *table= table_list->table;
/* We rely on a caller to check that table is going to be changed. */
- DBUG_ASSERT(table_list->lock_type >= TL_WRITE_ALLOW_WRITE);
+ DBUG_ASSERT(table_list->lock_type >= TL_WRITE_ALLOW_WRITE ||
+ thd->lex->default_used);
if (table_list->trg_event_map)
{
- if (table_list->table->triggers)
+ if (table->triggers)
{
*need_prelocking= TRUE;
- if (table_list->table->triggers->
+ if (table->triggers->
add_tables_and_routines_for_triggers(thd, prelocking_ctx, table_list))
return TRUE;
}
- if (table_list->table->file->referenced_by_foreign_key())
+ if (table->file->referenced_by_foreign_key())
{
List <FOREIGN_KEY_INFO> fk_list;
List_iterator<FOREIGN_KEY_INFO> fk_list_it(fk_list);
@@ -4266,7 +4357,7 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx,
arena= thd->activate_stmt_arena_if_needed(&backup);
- table_list->table->file->get_parent_foreign_key_list(thd, &fk_list);
+ table->file->get_parent_foreign_key_list(thd, &fk_list);
if (thd->is_error())
{
if (arena)
@@ -4279,12 +4370,11 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx,
while ((fk= fk_list_it++))
{
// FK_OPTION_RESTRICT and FK_OPTION_NO_ACTION only need read access
- static bool can_write[]= { true, false, true, true, false, true };
uint8 op= table_list->trg_event_map;
thr_lock_type lock_type;
- if ((op & (1 << TRG_EVENT_DELETE) && can_write[fk->delete_method])
- || (op & (1 << TRG_EVENT_UPDATE) && can_write[fk->update_method]))
+ if ((op & (1 << TRG_EVENT_DELETE) && fk_modifies_child(fk->delete_method))
+ || (op & (1 << TRG_EVENT_UPDATE) && fk_modifies_child(fk->update_method)))
lock_type= TL_WRITE_ALLOW_WRITE;
else
lock_type= TL_READ;
@@ -4295,21 +4385,94 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx,
continue;
TABLE_LIST *tl= (TABLE_LIST *) thd->alloc(sizeof(TABLE_LIST));
- tl->init_one_table_for_prelocking(fk->foreign_db->str, fk->foreign_db->length,
- fk->foreign_table->str, fk->foreign_table->length,
- NULL, lock_type, false, table_list->belong_to_view,
- op, &prelocking_ctx->query_tables_last);
+ tl->init_one_table_for_prelocking(fk->foreign_db,
+ fk->foreign_table,
+ NULL, lock_type,
+ TABLE_LIST::PRELOCK_FK,
+ table_list->belong_to_view, op,
+ &prelocking_ctx->query_tables_last);
}
if (arena)
thd->restore_active_arena(arena, &backup);
}
}
+ /* Open any tables used by DEFAULT (like sequence tables) */
+ if (table->internal_tables &&
+ ((sql_command_flags[thd->lex->sql_command] & CF_INSERTS_DATA) ||
+ thd->lex->default_used))
+ {
+ Query_arena *arena, backup;
+ bool error;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ error= add_internal_tables(thd, prelocking_ctx,
+ table->internal_tables);
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ if (error)
+ {
+ *need_prelocking= TRUE;
+ return TRUE;
+ }
+ }
return FALSE;
}
/**
+ Open all tables used by DEFAULT functions.
+
+ This is different from normal open_and_lock_tables() as we may
+ already have other tables opened and locked and we have to merge the
+ new table with the old ones.
+*/
+
+bool open_and_lock_internal_tables(TABLE *table, bool lock_table)
+{
+ THD *thd= table->in_use;
+ TABLE_LIST *tl;
+ MYSQL_LOCK *save_lock,*new_lock;
+ DBUG_ENTER("open_internal_tables");
+
+ /* remove pointer to old select_lex which is already destroyed */
+ for (tl= table->internal_tables ; tl ; tl= tl->next_global)
+ tl->select_lex= 0;
+
+ uint counter;
+ MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
+ TABLE_LIST *tmp= table->internal_tables;
+ DML_prelocking_strategy prelocking_strategy;
+
+ if (open_tables(thd, thd->lex->create_info, &tmp, &counter, 0,
+ &prelocking_strategy))
+ goto err;
+
+ if (lock_table)
+ {
+ save_lock= thd->lock;
+ thd->lock= 0;
+ if (lock_tables(thd, table->internal_tables, counter,
+ MYSQL_LOCK_USE_MALLOC))
+ goto err;
+
+ if (!(new_lock= mysql_lock_merge(save_lock, thd->lock)))
+ {
+ thd->lock= save_lock;
+ mysql_unlock_tables(thd, save_lock, 1);
+ /* We don't have to close tables as caller will do that */
+ goto err;
+ }
+ thd->lock= new_lock;
+ }
+ DBUG_RETURN(0);
+
+err:
+ thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
+ DBUG_RETURN(1);
+}
+
+
+/**
Defines how prelocking algorithm for DML statements should handle view -
all view routines should be added to the prelocking set.
@@ -4460,7 +4623,7 @@ static bool check_lock_and_start_stmt(THD *thd,
Prelocking placeholder is not set for TABLE_LIST that
are directly used by TOP level statement.
*/
- DBUG_ASSERT(table_list->prelocking_placeholder == false);
+ DBUG_ASSERT(table_list->prelocking_placeholder == TABLE_LIST::PRELOCK_NONE);
/*
TL_WRITE_DEFAULT and TL_READ_DEFAULT are supposed to be parser only
@@ -4473,7 +4636,6 @@ static bool check_lock_and_start_stmt(THD *thd,
Last argument routine_modifies_data for read_lock_type_for_table()
is ignored, as prelocking placeholder will never be set here.
*/
- DBUG_ASSERT(table_list->prelocking_placeholder == false);
if (table_list->lock_type == TL_WRITE_DEFAULT)
lock_type= thd->update_lock_default;
else if (table_list->lock_type == TL_READ_DEFAULT)
@@ -4481,8 +4643,8 @@ static bool check_lock_and_start_stmt(THD *thd,
else
lock_type= table_list->lock_type;
- if ((int) lock_type > (int) TL_WRITE_ALLOW_WRITE &&
- (int) table_list->table->reginfo.lock_type <= (int) TL_WRITE_ALLOW_WRITE)
+ if ((int) lock_type >= (int) TL_WRITE_ALLOW_WRITE &&
+ (int) table_list->table->reginfo.lock_type < (int) TL_WRITE_ALLOW_WRITE)
{
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),
table_list->table->alias.c_ptr());
@@ -4636,7 +4798,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
*/
DBUG_ASSERT(table_list->table);
table= table_list->table;
- if (table->file->ht->db_type == DB_TYPE_MRG_MYISAM)
+ if (table->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
{
/* A MERGE table must not come here. */
/* purecov: begin tested */
@@ -5189,7 +5351,7 @@ Field *view_ref_found= (Field*) 0x2;
static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
{
DBUG_ENTER("update_field_dependencies");
- if (thd->mark_used_columns != MARK_COLUMNS_NONE)
+ if (should_mark_column(thd->column_usage))
{
MY_BITMAP *bitmap;
@@ -5203,7 +5365,7 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
if (field->vcol_info)
table->mark_virtual_col(field);
- if (thd->mark_used_columns == MARK_COLUMNS_READ)
+ if (thd->column_usage == MARK_COLUMNS_READ)
bitmap= table->read_set;
else
bitmap= table->write_set;
@@ -5211,13 +5373,13 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
/*
The test-and-set mechanism in the bitmap is not reliable during
multi-UPDATE statements under MARK_COLUMNS_READ mode
- (thd->mark_used_columns == MARK_COLUMNS_READ), as this bitmap contains
+ (thd->column_usage == MARK_COLUMNS_READ), as this bitmap contains
only those columns that are used in the SET clause. I.e they are being
set here. See multi_update::prepare()
*/
if (bitmap_fast_test_and_set(bitmap, field->field_index))
{
- if (thd->mark_used_columns == MARK_COLUMNS_WRITE)
+ if (thd->column_usage == MARK_COLUMNS_WRITE)
{
DBUG_PRINT("warning", ("Found duplicated field"));
thd->dup_field= field;
@@ -5228,11 +5390,9 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
}
DBUG_VOID_RETURN;
}
- if (table->get_fields_in_item_tree)
- field->flags|= GET_FIXED_FIELDS_FLAG;
table->used_fields++;
}
- else if (table->get_fields_in_item_tree)
+ if (table->get_fields_in_item_tree)
field->flags|= GET_FIXED_FIELDS_FLAG;
DBUG_VOID_RETURN;
}
@@ -5261,14 +5421,14 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
static Field *
find_field_in_view(THD *thd, TABLE_LIST *table_list,
- const char *name, uint length,
+ const char *name, size_t length,
const char *item_name, Item **ref,
bool register_tree_change)
{
DBUG_ENTER("find_field_in_view");
DBUG_PRINT("enter",
("view: '%s', field name: '%s', item name: '%s', ref %p",
- table_list->alias, name, item_name, ref));
+ table_list->alias.str, name, item_name, ref));
Field_iterator_view field_it;
field_it.set(table_list);
Query_arena *arena= 0, backup;
@@ -5342,8 +5502,7 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
*/
static Field *
-find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
- uint length, Item **ref, bool register_tree_change,
+find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, size_t length, Item **ref, bool register_tree_change,
TABLE_LIST **actual_table)
{
List_iterator_fast<Natural_join_column>
@@ -5463,10 +5622,10 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
*/
Field *
-find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
+find_field_in_table(THD *thd, TABLE *table, const char *name, size_t length,
bool allow_rowid, uint *cached_field_index_ptr)
{
- Field **field_ptr, *field;
+ Field *field;
uint cached_field_index= *cached_field_index_ptr;
DBUG_ENTER("find_field_in_table");
DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias.c_ptr(),
@@ -5476,34 +5635,23 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
if (cached_field_index < table->s->fields &&
!my_strcasecmp(system_charset_info,
table->field[cached_field_index]->field_name.str, name))
- field_ptr= table->field + cached_field_index;
- else if (table->s->name_hash.records)
- {
- field_ptr= (Field**) my_hash_search(&table->s->name_hash, (uchar*) name,
- length);
- if (field_ptr)
- {
- /*
- field_ptr points to field in TABLE_SHARE. Convert it to the matching
- field in table
- */
- field_ptr= (table->field + (field_ptr - table->s->field));
- }
- }
+ field= table->field[cached_field_index];
else
{
- if (!(field_ptr= table->field))
- DBUG_RETURN((Field *)0);
- for (; *field_ptr; ++field_ptr)
- if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name.str,
- name))
- break;
+ LEX_CSTRING fname= {name, length};
+ field= table->find_field_by_name(&fname);
}
- if (field_ptr && *field_ptr)
+ if (field)
{
- *cached_field_index_ptr= (uint)(field_ptr - table->field);
- field= *field_ptr;
+ if (field->invisible == INVISIBLE_FULL &&
+ DBUG_EVALUATE_IF("test_completely_invisible", 0, 1))
+ DBUG_RETURN((Field*)0);
+
+ if (field->invisible == INVISIBLE_SYSTEM &&
+ thd->column_usage != MARK_COLUMNS_READ &&
+ thd->column_usage != COLUMNS_READ)
+ DBUG_RETURN((Field*)0);
}
else
{
@@ -5513,6 +5661,7 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
DBUG_RETURN((Field*) 0);
field= table->field[table->s->rowid_field_offset-1];
}
+ *cached_field_index_ptr= field->field_index;
update_field_dependencies(thd, field, table);
@@ -5532,6 +5681,7 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
item_name [in] name of item if it will be created (VIEW)
db_name [in] optional database name that qualifies the
table_name [in] optional table name that qualifies the field
+ 0 for non-qualified field in natural joins
ref [in/out] if 'name' is resolved to a view field, ref
is set to point to the found view field
check_privileges [in] check privileges
@@ -5566,7 +5716,7 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
Field *
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
- const char *name, uint length,
+ const char *name, size_t length,
const char *item_name, const char *db_name,
const char *table_name, Item **ref,
bool check_privileges, bool allow_rowid,
@@ -5575,12 +5725,12 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
{
Field *fld;
DBUG_ENTER("find_field_in_table_ref");
- DBUG_ASSERT(table_list->alias);
+ DBUG_ASSERT(table_list->alias.str);
DBUG_ASSERT(name);
DBUG_ASSERT(item_name);
DBUG_PRINT("enter",
("table: '%s' field name: '%s' item name: '%s' ref %p",
- table_list->alias, name, item_name, ref));
+ table_list->alias.str, name, item_name, ref));
/*
Check that the table and database that qualify the current field name
@@ -5596,9 +5746,13 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
inside the view, but we want to search directly in the view columns
which are represented as a 'field_translation'.
- TODO: Ensure that table_name, db_name and tables->db always points to
- something !
+ tables->db.str may be 0 if we are preparing a statement
+ db_name is 0 if item doesn't have a db name
+ table_name is 0 if item doesn't have a specified table_name
*/
+ if (db_name && !db_name[0])
+ db_name= 0; // Simpler test later
+
if (/* Exclude nested joins. */
(!table_list->nested_join ||
/* Include merge views and information schema tables. */
@@ -5608,12 +5762,12 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
to search.
*/
table_name && table_name[0] &&
- (my_strcasecmp(table_alias_charset, table_list->alias, table_name) ||
- (db_name && db_name[0] && (!table_list->db || !table_list->db[0])) ||
- (db_name && db_name[0] && table_list->db && table_list->db[0] &&
+ (my_strcasecmp(table_alias_charset, table_list->alias.str, table_name) ||
+ (db_name && (!table_list->db.str || !table_list->db.str[0])) ||
+ (db_name && table_list->db.str && table_list->db.str[0] &&
(table_list->schema_table ?
- my_strcasecmp(system_charset_info, db_name, table_list->db) :
- strcmp(db_name, table_list->db)))))
+ my_strcasecmp(system_charset_info, db_name, table_list->db.str) :
+ strcmp(db_name, table_list->db.str)))))
DBUG_RETURN(0);
/*
@@ -5684,7 +5838,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
fld= WRONG_GRANT;
else
#endif
- if (thd->mark_used_columns != MARK_COLUMNS_NONE)
+ if (should_mark_column(thd->column_usage))
{
/*
Get rw_set correct for this field so that the handler
@@ -5701,7 +5855,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
field_to_set= ((Item_field*)it)->field;
else
{
- if (thd->mark_used_columns == MARK_COLUMNS_READ)
+ if (thd->column_usage == MARK_COLUMNS_READ)
it->walk(&Item::register_field_in_read_map, 0, 0);
else
it->walk(&Item::register_field_in_write_map, 0, 0);
@@ -5712,7 +5866,8 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
if (field_to_set)
{
TABLE *table= field_to_set->table;
- if (thd->mark_used_columns == MARK_COLUMNS_READ)
+ DBUG_ASSERT(table);
+ if (thd->column_usage == MARK_COLUMNS_READ)
bitmap_set_bit(table->read_set, field_to_set->field_index);
else
bitmap_set_bit(table->write_set, field_to_set->field_index);
@@ -5814,7 +5969,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
const char *db= item->db_name;
const char *table_name= item->table_name;
const char *name= item->field_name.str;
- uint length= item->field_name.length;
+ size_t length= item->field_name.length;
char name_buff[SAFE_NAME_LEN+1];
TABLE_LIST *cur_table= first_table;
TABLE_LIST *actual_table;
@@ -6363,6 +6518,8 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
Query_arena *arena, backup;
bool result= TRUE;
bool first_outer_loop= TRUE;
+ Field *field_1, *field_2;
+ field_visibility_t field_1_invisible, field_2_invisible;
/*
Leaf table references to which new natural join columns are added
if the leaves are != NULL.
@@ -6376,7 +6533,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
DBUG_ENTER("mark_common_columns");
DBUG_PRINT("info", ("operand_1: %s operand_2: %s",
- table_ref_1->alias, table_ref_2->alias));
+ table_ref_1->alias.str, table_ref_2->alias.str));
*found_using_fields= 0;
arena= thd->activate_stmt_arena_if_needed(&backup);
@@ -6389,13 +6546,23 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
bool is_using_column_1;
if (!(nj_col_1= it_1.get_or_create_column_ref(thd, leaf_1)))
goto err;
+
+ field_1= nj_col_1->field();
+ field_1_invisible= field_1 ? field_1->invisible : VISIBLE;
+
+ if (field_1_invisible == INVISIBLE_FULL)
+ continue;
+
field_name_1= nj_col_1->name();
is_using_column_1= using_fields &&
test_if_string_in_list(field_name_1->str, using_fields);
DBUG_PRINT ("info", ("field_name_1=%s.%s",
- nj_col_1->table_name() ? nj_col_1->table_name() : "",
+ nj_col_1->safe_table_name(),
field_name_1->str));
+ if (field_1_invisible && !is_using_column_1)
+ continue;
+
/*
Find a field with the same name in table_ref_2.
@@ -6410,10 +6577,16 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
const LEX_CSTRING *cur_field_name_2;
if (!(cur_nj_col_2= it_2.get_or_create_column_ref(thd, leaf_2)))
goto err;
+
+ field_2= cur_nj_col_2->field();
+ field_2_invisible= field_2 ? field_2->invisible : VISIBLE;
+
+ if (field_2_invisible == INVISIBLE_FULL)
+ continue;
+
cur_field_name_2= cur_nj_col_2->name();
DBUG_PRINT ("info", ("cur_field_name_2=%s.%s",
- cur_nj_col_2->table_name() ?
- cur_nj_col_2->table_name() : "",
+ cur_nj_col_2->safe_table_name(),
cur_field_name_2->str));
/*
@@ -6431,14 +6604,17 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
cur_field_name_2))
{
DBUG_PRINT ("info", ("match c1.is_common=%d", nj_col_1->is_common));
- if (cur_nj_col_2->is_common ||
- (found && (!using_fields || is_using_column_1)))
+ if (cur_nj_col_2->is_common || found)
{
my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1->str, thd->where);
goto err;
}
- nj_col_2= cur_nj_col_2;
- found= TRUE;
+ if ((!using_fields && !field_2_invisible) || is_using_column_1)
+ {
+ DBUG_ASSERT(nj_col_2 == NULL);
+ nj_col_2= cur_nj_col_2;
+ found= TRUE;
+ }
}
}
if (first_outer_loop && leaf_2)
@@ -6458,7 +6634,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
clause (if present), mark them as common fields, and add a new
equi-join condition to the ON clause.
*/
- if (nj_col_2 && (!using_fields ||is_using_column_1))
+ if (nj_col_2)
{
/*
Create non-fixed fully qualified field and let fix_fields to
@@ -6466,8 +6642,6 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
*/
Item *item_1= nj_col_1->create_item(thd);
Item *item_2= nj_col_2->create_item(thd);
- Field *field_1= nj_col_1->field();
- Field *field_2= nj_col_2->field();
Item_ident *item_ident_1, *item_ident_2;
Item_func_eq *eq_cond;
@@ -6507,11 +6681,6 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
if (!(eq_cond= new (thd->mem_root) Item_func_eq(thd, item_ident_1, item_ident_2)))
goto err; /* Out of memory. */
- if (field_1 && field_1->vcol_info)
- field_1->table->mark_virtual_col(field_1);
- if (field_2 && field_2->vcol_info)
- field_2->table->mark_virtual_col(field_2);
-
/*
Add the new equi-join condition to the ON clause. Notice that
fix_fields() is applied to all ON conditions in setup_conds()
@@ -6523,27 +6692,15 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
nj_col_1->is_common= nj_col_2->is_common= TRUE;
DBUG_PRINT ("info", ("%s.%s and %s.%s are common",
- nj_col_1->table_name() ?
- nj_col_1->table_name() : "",
+ nj_col_1->safe_table_name(),
nj_col_1->name()->str,
- nj_col_2->table_name() ?
- nj_col_2->table_name() : "",
+ nj_col_2->safe_table_name(),
nj_col_2->name()->str));
if (field_1)
- {
- TABLE *table_1= nj_col_1->table_ref->table;
- /* Mark field_1 used for table cache. */
- bitmap_set_bit(table_1->read_set, field_1->field_index);
- table_1->covering_keys.intersect(field_1->part_of_key);
- }
+ update_field_dependencies(thd, field_1, field_1->table);
if (field_2)
- {
- TABLE *table_2= nj_col_2->table_ref->table;
- /* Mark field_2 used for table cache. */
- bitmap_set_bit(table_2->read_set, field_2->field_index);
- table_2->covering_keys.intersect(field_2->part_of_key);
- }
+ update_field_dependencies(thd, field_2, field_2->table);
if (using_fields != NULL)
++(*found_using_fields);
@@ -7060,12 +7217,12 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
****************************************************************************/
bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
- List<Item> &fields, enum_mark_columns mark_used_columns,
+ List<Item> &fields, enum_column_usage column_usage,
List<Item> *sum_func_list, List<Item> *pre_fix,
bool allow_sum_func)
{
reg2 Item *item;
- enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
+ enum_column_usage saved_column_usage= thd->column_usage;
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
List_iterator<Item> it(fields);
bool save_is_item_list_lookup;
@@ -7073,8 +7230,8 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
DBUG_ENTER("setup_fields");
DBUG_PRINT("enter", ("ref_pointer_array: %p", ref_pointer_array.array()));
- thd->mark_used_columns= mark_used_columns;
- DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
+ thd->column_usage= column_usage;
+ DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
if (allow_sum_func)
thd->lex->allow_sum_func|=
(nesting_map)1 << thd->lex->current_select->nest_level;
@@ -7083,7 +7240,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
thd->lex->current_select->is_item_list_lookup= 0;
/*
- To prevent fail on forward lookup we fill it with zerows,
+ To prevent fail on forward lookup we fill it with zeroes,
then if we got pointer on zero after find_item_in_list we will know
that it is forward lookup.
@@ -7127,8 +7284,8 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
{
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
thd->lex->allow_sum_func= save_allow_sum_func;
- thd->mark_used_columns= save_mark_used_columns;
- DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
+ thd->column_usage= saved_column_usage;
+ DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
DBUG_RETURN(TRUE); /* purecov: inspected */
}
if (!ref.is_null())
@@ -7155,8 +7312,8 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
thd->lex->allow_sum_func= save_allow_sum_func;
- thd->mark_used_columns= save_mark_used_columns;
- DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
+ thd->column_usage= saved_column_usage;
+ DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
DBUG_RETURN(MY_TEST(thd->is_error()));
}
@@ -7447,7 +7604,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
0)
{
my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), name->c_ptr(),
- table->pos_in_table_list->alias);
+ table->pos_in_table_list->alias.str);
map->set_all();
return 1;
}
@@ -7518,8 +7675,8 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
DBUG_ASSERT(tables->is_leaf_for_name_resolution());
if ((table_name && my_strcasecmp(table_alias_charset, table_name,
- tables->alias)) ||
- (db_name && strcmp(tables->db,db_name)))
+ tables->alias.str)) ||
+ (db_name && strcmp(tables->db.str, db_name)))
continue;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -7581,6 +7738,14 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
for (; !field_iterator.end_of_fields(); field_iterator.next())
{
+ /*
+ field() is always NULL for views (see, e.g. Field_iterator_view or
+ Field_iterator_natural_join).
+ But view fields can never be invisible.
+ */
+ if ((field= field_iterator.field()) && field->invisible != VISIBLE)
+ continue;
+
Item *item;
if (!(item= field_iterator.create_item(thd)))
@@ -7690,13 +7855,13 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
*/
if (!table_name)
my_error(ER_NO_TABLES_USED, MYF(0));
- else if (!db_name && !thd->db)
+ else if (!db_name && !thd->db.str)
my_error(ER_NO_DB_ERROR, MYF(0));
else
{
char name[FN_REFLEN];
my_snprintf(name, sizeof(name), "%s.%s",
- db_name ? db_name : thd->db, table_name);
+ db_name ? db_name : thd->get_db(), table_name);
my_error(ER_BAD_TABLE_ERROR, MYF(0), name);
}
@@ -7829,14 +7994,10 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
TABLE_LIST *derived= select_lex->master_unit()->derived;
DBUG_ENTER("setup_conds");
- /* Do not fix conditions for the derived tables that have been merged */
- if (derived && derived->merged)
- DBUG_RETURN(0);
-
select_lex->is_item_list_lookup= 0;
- thd->mark_used_columns= MARK_COLUMNS_READ;
- DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
+ thd->column_usage= MARK_COLUMNS_READ;
+ DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
select_lex->cond_count= 0;
select_lex->between_count= 0;
select_lex->max_equal_elems= 0;
@@ -7930,6 +8091,9 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
List_iterator_fast<Item> f(fields),v(values);
Item *value, *fld;
Item_field *field;
+ Field *rfield;
+ TABLE *table;
+ bool only_unvers_fields= update && table_arg->versioned();
bool save_abort_on_warning= thd->abort_on_warning;
bool save_no_errors= thd->no_errors;
DBUG_ENTER("fill_record");
@@ -7940,21 +8104,7 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
only one row.
*/
if (fields.elements)
- {
- /*
- On INSERT or UPDATE fields are checked to be from the same table,
- thus we safely can take table from the first field.
- */
- fld= (Item_field*)f++;
- if (!(field= fld->field_for_view_update()))
- {
- my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name.str);
- goto err;
- }
- DBUG_ASSERT(field->field->table == table_arg);
table_arg->auto_increment_field_not_null= FALSE;
- f.rewind();
- }
while ((fld= f++))
{
@@ -7964,31 +8114,64 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
goto err;
}
value=v++;
- Field *rfield= field->field;
- TABLE* table= rfield->table;
+ DBUG_ASSERT(value);
+ rfield= field->field;
+ table= rfield->table;
if (table->next_number_field &&
rfield->field_index == table->next_number_field->field_index)
table->auto_increment_field_not_null= TRUE;
Item::Type type= value->type();
- if (rfield->vcol_info &&
+ bool vers_sys_field= table->versioned() && rfield->vers_sys_field();
+ if ((rfield->vcol_info || vers_sys_field) &&
type != Item::DEFAULT_VALUE_ITEM &&
type != Item::NULL_ITEM &&
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
- ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
+ ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN,
+ ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN),
rfield->field_name.str, table->s->table_name.str);
+ if (vers_sys_field)
+ continue;
}
- if (rfield->stored_in_db() &&
- (value->save_in_field(rfield, 0)) < 0 && !ignore_errors)
+ if (only_unvers_fields && !rfield->vers_update_unversioned())
+ only_unvers_fields= false;
+
+ if (rfield->stored_in_db())
{
- my_message(ER_UNKNOWN_ERROR, ER_THD(thd, ER_UNKNOWN_ERROR), MYF(0));
- goto err;
+ if (value->save_in_field(rfield, 0) < 0 && !ignore_errors)
+ {
+ my_message(ER_UNKNOWN_ERROR, ER_THD(thd, ER_UNKNOWN_ERROR), MYF(0));
+ goto err;
+ }
+ /*
+ In sql MODE_SIMULTANEOUS_ASSIGNMENT,
+ move field pointer on value stored in record[1]
+ which contains row before update (see MDEV-13417)
+ */
+ if (update && thd->variables.sql_mode & MODE_SIMULTANEOUS_ASSIGNMENT)
+ rfield->move_field_offset((my_ptrdiff_t) (table->record[1] -
+ table->record[0]));
}
rfield->set_explicit_default(value);
}
+ if (update && thd->variables.sql_mode & MODE_SIMULTANEOUS_ASSIGNMENT)
+ {
+ // restore fields pointers on record[0]
+ f.rewind();
+ while ((fld= f++))
+ {
+ rfield= fld->field_for_view_update()->field;
+ if (rfield->stored_in_db())
+ {
+ table= rfield->table;
+ rfield->move_field_offset((my_ptrdiff_t) (table->record[0] -
+ table->record[1]));
+ }
+ }
+ }
+
if (!update && table_arg->default_field &&
table_arg->update_default_fields(0, ignore_errors))
goto err;
@@ -7996,6 +8179,8 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
if (table_arg->vfield &&
table_arg->update_virtual_fields(table_arg->file, VCOL_UPDATE_FOR_WRITE))
goto err;
+ if (table_arg->versioned() && !only_unvers_fields)
+ table_arg->vers_update_fields();
thd->abort_on_warning= save_abort_on_warning;
thd->no_errors= save_no_errors;
DBUG_RETURN(thd->is_error());
@@ -8048,7 +8233,7 @@ void switch_defaults_to_nullable_trigger_fields(TABLE *table)
Field **trigger_field= table->field_to_fill();
/* True if we have NOT NULL fields and BEFORE triggers */
- if (trigger_field != table->field)
+ if (*trigger_field != *table->field)
{
for (Field **field_ptr= table->default_field; *field_ptr ; field_ptr++)
{
@@ -8119,7 +8304,7 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
List<Item> &values, bool ignore_errors,
enum trg_event_type event)
{
- bool result;
+ int result;
Table_triggers_list *triggers= table->triggers;
result= fill_record(thd, table, fields, values, ignore_errors,
@@ -8187,7 +8372,6 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
? table->next_number_field->field_index
: ~0U;
DBUG_ENTER("fill_record");
-
if (!*ptr)
{
/* No fields to update, quite strange!*/
@@ -8210,10 +8394,19 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
/* Ensure that all fields are from the same table */
DBUG_ASSERT(field->table == table);
- value=v++;
+ if (field->invisible)
+ {
+ all_fields_have_values= false;
+ continue;
+ }
+ else
+ value=v++;
+
+ bool vers_sys_field= table->versioned() && field->vers_sys_field();
+
if (field->field_index == autoinc_index)
table->auto_increment_field_not_null= TRUE;
- if (field->vcol_info)
+ if (field->vcol_info || (vers_sys_field && !ignore_errors))
{
Item::Type type= value->type();
if (type != Item::DEFAULT_VALUE_ITEM &&
@@ -8221,9 +8414,11 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
- ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
+ ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN,
+ ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN),
field->field_name.str, table->s->table_name.str);
+ if (vers_sys_field)
+ continue;
}
}
@@ -8242,6 +8437,8 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
if (table->vfield &&
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_WRITE))
goto err;
+ if (table->versioned())
+ table->vers_update_fields();
thd->abort_on_warning= abort_on_warning_saved;
DBUG_RETURN(thd->is_error());
@@ -8333,8 +8530,8 @@ my_bool mysql_rm_tmp_tables(void)
tmp_file_prefix_length))
{
char *ext= fn_ext(file->name);
- uint ext_len= strlen(ext);
- uint filePath_len= my_snprintf(filePath, sizeof(filePath),
+ size_t ext_len= strlen(ext);
+ size_t filePath_len= my_snprintf(filePath, sizeof(filePath),
"%s%c%s", tmpdir, FN_LIBCHAR,
file->name);
if (!strcmp(reg_ext, ext))
@@ -8372,84 +8569,6 @@ my_bool mysql_rm_tmp_tables(void)
unireg support functions
*****************************************************************************/
-/**
- A callback to the server internals that is used to address
- special cases of the locking protocol.
- Invoked when acquiring an exclusive lock, for each thread that
- has a conflicting shared metadata lock.
-
- This function:
- - aborts waiting of the thread on a data lock, to make it notice
- the pending exclusive lock and back off.
- - if the thread is an INSERT DELAYED thread, sends it a KILL
- signal to terminate it.
-
- @note This function does not wait for the thread to give away its
- locks. Waiting is done outside for all threads at once.
-
- @param thd Current thread context
- @param in_use The thread to wake up
- @param needs_thr_lock_abort Indicates that to wake up thread
- this call needs to abort its waiting
- on table-level lock.
-
- @retval TRUE if the thread was woken up
- @retval FALSE otherwise.
-
- @note It is one of two places where border between MDL and the
- rest of the server is broken.
-*/
-
-bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use,
- bool needs_thr_lock_abort)
-{
- bool signalled= FALSE;
- if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
- !in_use->killed)
- {
- in_use->set_killed(KILL_SYSTEM_THREAD);
- mysql_mutex_lock(&in_use->mysys_var->mutex);
- if (in_use->mysys_var->current_cond)
- {
- mysql_mutex_lock(in_use->mysys_var->current_mutex);
- mysql_cond_broadcast(in_use->mysys_var->current_cond);
- mysql_mutex_unlock(in_use->mysys_var->current_mutex);
- }
- mysql_mutex_unlock(&in_use->mysys_var->mutex);
- signalled= TRUE;
- }
-
- if (needs_thr_lock_abort)
- {
- mysql_mutex_lock(&in_use->LOCK_thd_data);
- for (TABLE *thd_table= in_use->open_tables;
- thd_table ;
- thd_table= thd_table->next)
- {
- /*
- Check for TABLE::needs_reopen() is needed since in some places we call
- handler::close() for table instance (and set TABLE::db_stat to 0)
- and do not remove such instances from the THD::open_tables
- for some time, during which other thread can see those instances
- (e.g. see partitioning code).
- */
- if (!thd_table->needs_reopen())
- {
- signalled|= mysql_lock_abort_for_thread(thd, thd_table);
- if (thd && WSREP(thd) && wsrep_thd_is_BF(thd, true))
- {
- WSREP_DEBUG("remove_table_from_cache: %llu",
- (unsigned long long) thd->real_id);
- wsrep_abort_thd((void *)thd, (void *)in_use, FALSE);
- }
- }
- }
- mysql_mutex_unlock(&in_use->LOCK_thd_data);
- }
- return signalled;
-}
-
-
int setup_ftfuncs(SELECT_LEX *select_lex)
{
List_iterator<Item_func_match> li(*(select_lex->ftfunc_list)),
@@ -8478,11 +8597,16 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
{
List_iterator<Item_func_match> li(*(select_lex->ftfunc_list));
Item_func_match *ifm;
- DBUG_PRINT("info",("Performing FULLTEXT search"));
while ((ifm=li++))
- if (ifm->init_search(thd, no_order))
- return 1;
+ if (unlikely(!ifm->fixed))
+ /*
+ it mean that clause where was FT function was removed, so we have
+ to remove the function from the list.
+ */
+ li.remove();
+ else if (ifm->init_search(thd, no_order))
+ return 1;
}
return 0;
}
@@ -8668,10 +8792,31 @@ open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup)
if ((table= open_ltable(thd, one_table, one_table->lock_type, flags)))
{
- DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_LOG);
- /* Make sure all columns get assigned to a default value */
- table->use_all_columns();
- DBUG_ASSERT(table->s->no_replicate);
+ if (table->s->table_category == TABLE_CATEGORY_LOG)
+ {
+ /* Make sure all columns get assigned to a default value */
+ table->use_all_columns();
+ DBUG_ASSERT(table->s->no_replicate);
+ }
+ else
+ {
+ my_error(ER_NOT_LOG_TABLE, MYF(0), table->s->db.str, table->s->table_name.str);
+ int error= 0;
+ if (table->current_lock != F_UNLCK)
+ {
+ table->current_lock= F_UNLCK;
+ error= table->file->ha_external_lock(thd, F_UNLCK);
+ }
+ if (error)
+ table->file->print_error(error, MYF(0));
+ else
+ {
+ tc_release_table(table);
+ thd->reset_open_tables_state(thd);
+ thd->restore_backup_open_tables_state(backup);
+ table= NULL;
+ }
+ }
}
else
thd->restore_backup_open_tables_state(backup);
diff --git a/sql/sql_base.h b/sql/sql_base.h
index bb33af66590..a6a85d47dc9 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -16,7 +16,7 @@
#ifndef SQL_BASE_INCLUDED
#define SQL_BASE_INCLUDED
-#include "sql_class.h" /* enum_mark_columns */
+#include "sql_class.h" /* enum_column_usage */
#include "sql_trigger.h" /* trg_event_type */
#include "mysqld.h" /* key_map */
#include "table_cache.h"
@@ -100,6 +100,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
*/
#define MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK 0x1000
#define MYSQL_LOCK_NOT_TEMPORARY 0x2000
+#define MYSQL_LOCK_USE_MALLOC 0x4000
/**
Only check THD::killed if waits happen (e.g. wait on MDL, wait on
table flush, wait on thr_lock.c locks) while opening and locking table.
@@ -135,8 +136,8 @@ void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
const MDL_savepoint &start_of_statement_svp);
TABLE_LIST *find_table_in_list(TABLE_LIST *table,
TABLE_LIST *TABLE_LIST::*link,
- const char *db_name,
- const char *table_name);
+ const LEX_CSTRING *db_name,
+ const LEX_CSTRING *table_name);
void close_thread_tables(THD *thd);
void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *);
void switch_defaults_to_nullable_trigger_fields(TABLE *table);
@@ -158,7 +159,7 @@ void make_leaves_list(THD *thd, List<TABLE_LIST> &list, TABLE_LIST *tables,
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list, uint wild_num);
bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
- List<Item> &item, enum_mark_columns mark_used_columns,
+ List<Item> &item, enum_column_usage column_usage,
List<Item> *sum_func_list, List<Item> *pre_fix,
bool allow_sum_func);
void unfix_fields(List<Item> &items);
@@ -174,14 +175,14 @@ find_field_in_tables(THD *thd, Item_ident *item,
bool check_privileges, bool register_tree_change);
Field *
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
- const char *name, uint length,
+ const char *name, size_t length,
const char *item_name, const char *db_name,
const char *table_name, Item **ref,
bool check_privileges, bool allow_rowid,
uint *cached_field_index_ptr,
bool register_tree_change, TABLE_LIST **actual_table);
Field *
-find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
+find_field_in_table(THD *thd, TABLE *table, const char *name, size_t length,
bool allow_rowid, uint *cached_field_index_ptr);
Field *
find_field_in_table_sef(TABLE *table, const char *name);
@@ -204,8 +205,8 @@ bool setup_tables_and_check_access(THD *thd,
bool wait_while_table_is_used(THD *thd, TABLE *table,
enum ha_extra_function function);
-void drop_open_table(THD *thd, TABLE *table, const char *db_name,
- const char *table_name);
+void drop_open_table(THD *thd, TABLE *table, const LEX_CSTRING *db_name,
+ const LEX_CSTRING *table_name);
void update_non_unique_table_error(TABLE_LIST *update,
const char *operation,
TABLE_LIST *duplicate);
@@ -257,6 +258,7 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags,
uint dt_phases);
bool open_tables_only_view_structure(THD *thd, TABLE_LIST *tables,
bool can_deadlock);
+bool open_and_lock_internal_tables(TABLE *table, bool lock);
bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
int decide_logging_format(THD *thd, TABLE_LIST *tables);
void close_thread_table(THD *thd, TABLE **table_ptr);
@@ -342,31 +344,22 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
}
inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table,
- const char *db_name,
- const char *table_name)
+ LEX_CSTRING *db_name,
+ LEX_CSTRING *table_name)
{
return find_table_in_list(table, &TABLE_LIST::next_global,
db_name, table_name);
}
-inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table,
- const char *db_name,
- const char *table_name)
-{
- return find_table_in_list(table, &TABLE_LIST::next_local,
- db_name, table_name);
-}
-
-
inline bool setup_fields_with_no_wrap(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &item,
- enum_mark_columns mark_used_columns,
+ enum_column_usage column_usage,
List<Item> *sum_func_list,
bool allow_sum_func)
{
bool res;
thd->lex->select_lex.no_wrap_view_item= TRUE;
- res= setup_fields(thd, ref_pointer_array, item, mark_used_columns,
+ res= setup_fields(thd, ref_pointer_array, item, column_usage,
sum_func_list, NULL, allow_sum_func);
thd->lex->select_lex.no_wrap_view_item= FALSE;
return res;
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index aa1a1cd6941..00270fb6f32 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -140,7 +140,7 @@ void mysql_client_binlog_statement(THD* thd)
my_error(ER_SYNTAX_ERROR, MYF(0));
DBUG_VOID_RETURN;
}
- size_t decoded_len= my_base64_needed_decoded_length(coded_len);
+ size_t decoded_len= my_base64_needed_decoded_length((int)coded_len);
/*
option_bits will be changed when applying the event. But we don't expect
diff --git a/sql/sql_bootstrap.cc b/sql/sql_bootstrap.cc
index ce7d7a9fc93..9fb22c6b4d4 100644
--- a/sql/sql_bootstrap.cc
+++ b/sql/sql_bootstrap.cc
@@ -82,14 +82,14 @@ int read_bootstrap_query(char *query, int *query_length,
*/
if (query_len + len + 1 >= MAX_BOOTSTRAP_QUERY_SIZE)
{
- int new_len= MAX_BOOTSTRAP_QUERY_SIZE - query_len - 1;
+ size_t new_len= MAX_BOOTSTRAP_QUERY_SIZE - query_len - 1;
if ((new_len > 0) && (query_len < MAX_BOOTSTRAP_QUERY_SIZE))
{
memcpy(query + query_len, line, new_len);
query_len+= new_len;
}
query[query_len]= '\0';
- *query_length= query_len;
+ *query_length= (int)query_len;
return READ_BOOTSTRAP_QUERY_SIZE;
}
@@ -111,7 +111,7 @@ int read_bootstrap_query(char *query, int *query_length,
Return the query found.
*/
query[query_len]= '\0';
- *query_length= query_len;
+ *query_length= (int)query_len;
return READ_BOOTSTRAP_SUCCESS;
}
}
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 6306441e4b4..1af9e2535d3 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -820,10 +820,10 @@ inline Query_cache_block * Query_cache_block_table::block()
Query_cache_block method(s)
*****************************************************************************/
-void Query_cache_block::init(ulong block_length)
+void Query_cache_block::init(size_t block_length)
{
DBUG_ENTER("Query_cache_block::init");
- DBUG_PRINT("qcache", ("init block: %p length: %lu", this,
+ DBUG_PRINT("qcache", ("init block: %p length: %zu", this,
block_length));
length = block_length;
used = 0;
@@ -1040,7 +1040,7 @@ uchar *query_cache_query_get_key(const uchar *record, size_t *length,
/**
libmysql convenience wrapper to insert data into query cache.
*/
-void query_cache_insert(void *thd_arg, const char *packet, ulong length,
+void query_cache_insert(void *thd_arg, const char *packet, size_t length,
unsigned pkt_nr)
{
THD *thd= (THD*) thd_arg;
@@ -1056,7 +1056,7 @@ void query_cache_insert(void *thd_arg, const char *packet, ulong length,
return;
query_cache.insert(thd, &thd->query_cache_tls,
- packet, length,
+ packet, (size_t)length,
pkt_nr);
}
@@ -1067,7 +1067,7 @@ void query_cache_insert(void *thd_arg, const char *packet, ulong length,
void
Query_cache::insert(THD *thd, Query_cache_tls *query_cache_tls,
- const char *packet, ulong length,
+ const char *packet, size_t length,
unsigned pkt_nr)
{
DBUG_ENTER("Query_cache::insert");
@@ -1100,7 +1100,7 @@ Query_cache::insert(THD *thd, Query_cache_tls *query_cache_tls,
Query_cache_block *result= header->result();
DUMP(this);
- DBUG_PRINT("qcache", ("insert packet %lu bytes long",length));
+ DBUG_PRINT("qcache", ("insert packet %zu bytes long",length));
/*
On success, STRUCT_UNLOCK is done by append_result_data. Otherwise, we
@@ -1190,7 +1190,11 @@ void Query_cache::end_of_result(THD *thd)
#endif
if (try_lock(thd, Query_cache::WAIT))
+ {
+ if (is_disabled())
+ query_cache_tls->first_query_block= NULL; // do not try again with QC
DBUG_VOID_RETURN;
+ }
query_block= query_cache_tls->first_query_block;
if (query_block)
@@ -1205,8 +1209,8 @@ void Query_cache::end_of_result(THD *thd)
BLOCK_LOCK_WR(query_block);
Query_cache_query *header= query_block->query();
Query_cache_block *last_result_block;
- ulong allign_size;
- ulong len;
+ size_t allign_size;
+ size_t len;
if (header->result() == 0)
{
@@ -1266,9 +1270,9 @@ void mysql_query_cache_invalidate4(THD *thd,
Query_cache methods
*****************************************************************************/
-Query_cache::Query_cache(ulong query_cache_limit_arg,
- ulong min_allocation_unit_arg,
- ulong min_result_data_size_arg,
+Query_cache::Query_cache(size_t query_cache_limit_arg,
+ size_t min_allocation_unit_arg,
+ size_t min_result_data_size_arg,
uint def_query_hash_size_arg,
uint def_table_hash_size_arg)
:query_cache_size(0),
@@ -1282,7 +1286,7 @@ Query_cache::Query_cache(ulong query_cache_limit_arg,
def_table_hash_size(ALIGN_SIZE(def_table_hash_size_arg)),
initialized(0)
{
- ulong min_needed= (ALIGN_SIZE(sizeof(Query_cache_block)) +
+ size_t min_needed= (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_block_table)) +
ALIGN_SIZE(sizeof(Query_cache_query)) + 3);
set_if_bigger(min_allocation_unit,min_needed);
@@ -1291,11 +1295,11 @@ Query_cache::Query_cache(ulong query_cache_limit_arg,
}
-ulong Query_cache::resize(ulong query_cache_size_arg)
+size_t Query_cache::resize(size_t query_cache_size_arg)
{
- ulong new_query_cache_size;
+ size_t new_query_cache_size;
DBUG_ENTER("Query_cache::resize");
- DBUG_PRINT("qcache", ("from %lu to %lu",query_cache_size,
+ DBUG_PRINT("qcache", ("from %zu to %zu",query_cache_size,
query_cache_size_arg));
DBUG_ASSERT(initialized);
@@ -1349,7 +1353,7 @@ ulong Query_cache::resize(ulong query_cache_size_arg)
}
-ulong Query_cache::set_min_res_unit(ulong size)
+size_t Query_cache::set_min_res_unit(size_t size)
{
DBUG_ASSERT(size % 8 == 0);
if (size < min_allocation_unit)
@@ -1361,7 +1365,7 @@ ulong Query_cache::set_min_res_unit(ulong size)
void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
{
TABLE_COUNTER_TYPE local_tables;
- ulong tot_length;
+ size_t tot_length;
const char *query;
size_t query_length;
uint8 tables_type;
@@ -1449,8 +1453,8 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
DBUG_PRINT("qcache", ("\
long %d, 4.1: %d, eof: %d, bin_proto: %d, more results %d, pkt_nr: %d, \
CS client: %u, CS result: %u, CS conn: %u, limit: %llu, TZ: %p, \
-sql mode: 0x%llx, sort len: %llu, conncat len: %llu, div_precision: %lu, \
-def_week_frmt: %lu, in_trans: %d, autocommit: %d",
+sql mode: 0x%llx, sort len: %llu, conncat len: %llu, div_precision: %zu, \
+def_week_frmt: %zu, in_trans: %d, autocommit: %d",
(int)flags.client_long_flag,
(int)flags.client_protocol_41,
(int)flags.client_depr_eof,
@@ -1501,18 +1505,18 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
query_length= thd->base_query.length();
/* Key is query + database + flag */
- if (thd->db_length)
+ if (thd->db.length)
{
memcpy((char*) (query + query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE),
- thd->db, thd->db_length);
+ thd->db.str, thd->db.length);
DBUG_PRINT("qcache", ("database: %s length: %u",
- thd->db, (unsigned) thd->db_length));
+ thd->db.str, (unsigned) thd->db.length));
}
else
{
DBUG_PRINT("qcache", ("No active database"));
}
- tot_length= (query_length + thd->db_length + 1 +
+ tot_length= (query_length + thd->db.length + 1 +
QUERY_CACHE_DB_LENGTH_SIZE + QUERY_CACHE_FLAGS_SIZE);
/*
We should only copy structure (don't use it location directly)
@@ -1534,7 +1538,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
Query_cache_block::QUERY, local_tables);
if (query_block != 0)
{
- DBUG_PRINT("qcache", ("query block %p allocated, %lu",
+ DBUG_PRINT("qcache", ("query block %p allocated, %zu",
query_block, query_block->used));
Query_cache_query *header = query_block->query();
@@ -1567,6 +1571,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
unlock();
+ DEBUG_SYNC(thd, "wait_in_query_cache_store_query");
+
// init_n_lock make query block locked
BLOCK_UNLOCK_WR(query_block);
}
@@ -1612,7 +1618,7 @@ end:
@retval TRUE On error
*/
static bool
-send_data_in_chunks(NET *net, const uchar *packet, ulong len)
+send_data_in_chunks(NET *net, const uchar *packet, size_t len)
{
/*
On the client we may require more memory than max_allowed_packet
@@ -1628,7 +1634,7 @@ send_data_in_chunks(NET *net, const uchar *packet, ulong len)
for max_allowed_packet, but large enough to ensure there is no
unnecessary overhead from too many syscalls per result set.
*/
- static const ulong MAX_CHUNK_LENGTH= 1024*1024;
+ static const size_t MAX_CHUNK_LENGTH= 1024*1024;
while (len > MAX_CHUNK_LENGTH)
{
@@ -1696,7 +1702,7 @@ size_t build_normalized_name(char *buff, size_t bufflen,
In case of -1, no error is sent to the client.
*) The buffer must be allocated memory of size:
- tot_length= query_length + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE;
+ tot_length= query_length + thd->db.length + 1 + QUERY_CACHE_FLAGS_SIZE;
*/
int
@@ -1709,7 +1715,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
#endif
Query_cache_block *result_block;
Query_cache_block_table *block_table, *block_table_end;
- ulong tot_length;
+ size_t tot_length;
Query_cache_query_flags flags;
const char *sql, *sql_end, *found_brace= 0;
DBUG_ENTER("Query_cache::send_result_to_client");
@@ -1817,7 +1823,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
sql++;
continue;
}
- /* fall trough */
+ /* fall through */
default:
break;
}
@@ -1855,7 +1861,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
as the previous one.
*/
size_t db_len= uint2korr(sql_end+1);
- if (thd->db_length != db_len)
+ if (thd->db.length != db_len)
{
/*
We should probably reallocate the buffer in this case,
@@ -1889,7 +1895,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
if (found_brace)
sql= found_brace;
make_base_query(&thd->base_query, sql, (size_t) (sql_end - sql),
- thd->db_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
+ thd->db.length + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
QUERY_CACHE_FLAGS_SIZE);
sql= thd->base_query.ptr();
query_length= thd->base_query.length();
@@ -1901,14 +1907,14 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
}
tot_length= (query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
- thd->db_length + QUERY_CACHE_FLAGS_SIZE);
+ thd->db.length + QUERY_CACHE_FLAGS_SIZE);
- if (thd->db_length)
+ if (thd->db.length)
{
memcpy((uchar*) sql + query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE,
- thd->db, thd->db_length);
+ thd->db.str, thd->db.length);
DBUG_PRINT("qcache", ("database: '%s' length: %u",
- thd->db, (uint) thd->db_length));
+ thd->db.str, (uint) thd->db.length));
}
else
{
@@ -1947,8 +1953,8 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
DBUG_PRINT("qcache", ("\
long %d, 4.1: %d, eof: %d, bin_proto: %d, more results %d, pkt_nr: %d, \
CS client: %u, CS result: %u, CS conn: %u, limit: %llu, TZ: %p, \
-sql mode: 0x%llx, sort len: %llu, conncat len: %llu, div_precision: %lu, \
-def_week_frmt: %lu, in_trans: %d, autocommit: %d",
+sql mode: 0x%llx, sort len: %llu, conncat len: %llu, div_precision: %zu, \
+def_week_frmt: %zu, in_trans: %d, autocommit: %d",
(int)flags.client_long_flag,
(int)flags.client_protocol_41,
(int)flags.client_depr_eof,
@@ -2064,14 +2070,17 @@ lookup:
}
bzero((char*) &table_list,sizeof(table_list));
- table_list.db = table->db();
- table_list.alias= table_list.table_name= table->table();
+ table_list.db.str= table->db();
+ table_list.db.length= strlen(table_list.db.str);
+ table_list.alias.str= table_list.table_name.str= table->table();
+ table_list.alias.length= table_list.table_name.length= strlen(table->table());
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_table_access(thd,SELECT_ACL,&table_list, FALSE, 1,TRUE))
{
DBUG_PRINT("qcache",
("probably no SELECT access to %s.%s => return to normal processing",
- table_list.db, table_list.alias));
+ table_list.db.str, table_list.alias.str));
unlock();
thd->query_cache_is_applicable= 0; // Query can't be cached
thd->lex->safe_to_cache_query= 0; // For prepared statements
@@ -2081,7 +2090,7 @@ lookup:
if (table_list.grant.want_privilege)
{
DBUG_PRINT("qcache", ("Need to check column privileges for %s.%s",
- table_list.db, table_list.alias));
+ table_list.db.str, table_list.alias.str));
BLOCK_UNLOCK_RD(query_block);
thd->query_cache_is_applicable= 0; // Query can't be cached
thd->lex->safe_to_cache_query= 0; // For prepared statements
@@ -2092,7 +2101,7 @@ lookup:
if (table->callback())
{
char qcache_se_key_name[FN_REFLEN + 10];
- uint qcache_se_key_len, db_length= strlen(table->db());
+ size_t qcache_se_key_len, db_length= strlen(table->db());
engine_data= table->engine_data();
qcache_se_key_len= build_normalized_name(qcache_se_key_name,
@@ -2106,16 +2115,16 @@ lookup:
table->suffix_length());
if (!(*table->callback())(thd, qcache_se_key_name,
- qcache_se_key_len, &engine_data))
+ (uint)qcache_se_key_len, &engine_data))
{
DBUG_PRINT("qcache", ("Handler does not allow caching for %.*s",
- qcache_se_key_len, qcache_se_key_name));
+ (int)qcache_se_key_len, qcache_se_key_name));
BLOCK_UNLOCK_RD(query_block);
if (engine_data != table->engine_data())
{
DBUG_PRINT("qcache",
("Handler require invalidation queries of %.*s %llu-%llu",
- qcache_se_key_len, qcache_se_key_name,
+ (int)qcache_se_key_len, qcache_se_key_name,
engine_data, table->engine_data()));
invalidate_table_internal(thd,
(uchar *) table->db(),
@@ -2141,7 +2150,7 @@ lookup:
}
else
DBUG_PRINT("qcache", ("handler allow caching %s,%s",
- table_list.db, table_list.alias));
+ table_list.db.str, table_list.alias.str));
}
move_to_query_list_end(query_block);
hits++;
@@ -2155,7 +2164,7 @@ lookup:
THD_STAGE_INFO(thd, stage_sending_cached_result_to_client);
do
{
- DBUG_PRINT("qcache", ("Results (len: %lu used: %lu headers: %u)",
+ DBUG_PRINT("qcache", ("Results (len: %zu used: %zu headers: %u)",
result_block->length, result_block->used,
(uint) (result_block->headers_len()+
ALIGN_SIZE(sizeof(Query_cache_result)))));
@@ -2317,7 +2326,7 @@ void Query_cache::invalidate(THD *thd, TABLE *table,
DBUG_VOID_RETURN;
}
-void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
+void Query_cache::invalidate(THD *thd, const char *key, size_t key_length,
my_bool using_transactions)
{
DBUG_ENTER("Query_cache::invalidate (key)");
@@ -2461,7 +2470,7 @@ void Query_cache::flush()
*/
-void Query_cache::pack(THD *thd, ulong join_limit, uint iteration_limit)
+void Query_cache::pack(THD *thd, size_t join_limit, uint iteration_limit)
{
DBUG_ENTER("Query_cache::pack");
@@ -2573,6 +2582,7 @@ void Query_cache::init()
*/
if (global_system_variables.query_cache_type == 0)
{
+ m_cache_status= DISABLE_REQUEST;
free_cache();
m_cache_status= DISABLED;
}
@@ -2580,11 +2590,11 @@ void Query_cache::init()
}
-ulong Query_cache::init_cache()
+size_t Query_cache::init_cache()
{
- uint mem_bin_count, num, step;
- ulong mem_bin_size, prev_size, inc;
- ulong max_mem_bin_size, approx_additional_data_size;
+ size_t mem_bin_count, num, step;
+ size_t mem_bin_size, prev_size, inc;
+ size_t additional_data_size, max_mem_bin_size, approx_additional_data_size;
int align;
DBUG_ENTER("Query_cache::init_cache");
@@ -2657,7 +2667,7 @@ ulong Query_cache::init_cache()
}
#endif
- DBUG_PRINT("qcache", ("cache length %lu, min unit %lu, %u bins",
+ DBUG_PRINT("qcache", ("cache length %zu, min unit %zu, %zu bins",
query_cache_size, min_allocation_unit, mem_bin_num));
steps = (Query_cache_memory_bin_step *) cache;
@@ -2681,9 +2691,9 @@ ulong Query_cache::init_cache()
mem_bin_size = max_mem_bin_size >> QUERY_CACHE_MEM_BIN_STEP_PWR2;
while (mem_bin_size > min_allocation_unit)
{
- ulong incr = (steps[step-1].size - mem_bin_size) / mem_bin_count;
- unsigned long size = mem_bin_size;
- for (uint i= mem_bin_count; i > 0; i--)
+ size_t incr = (steps[step-1].size - mem_bin_size) / mem_bin_count;
+ size_t size = mem_bin_size;
+ for (size_t i= mem_bin_count; i > 0; i--)
{
bins[num+i-1].init(size);
size += incr;
@@ -2706,9 +2716,9 @@ ulong Query_cache::init_cache()
steps[step].init(mem_bin_size, num + mem_bin_count - 1, inc);
{
- uint skiped = (min_allocation_unit - mem_bin_size)/inc;
- ulong size = mem_bin_size + inc*skiped;
- uint i = mem_bin_count - skiped;
+ size_t skiped = (min_allocation_unit - mem_bin_size)/inc;
+ size_t size = mem_bin_size + inc*skiped;
+ size_t i = mem_bin_count - skiped;
while (i-- > 0)
{
bins[num+i].init(size);
@@ -2788,13 +2798,17 @@ void Query_cache::make_disabled()
This function frees all resources allocated by the cache. You
have to call init_cache() before using the cache again. This function
- requires the structure_guard_mutex to be locked.
+ requires the cache to be locked (LOCKED_NO_WAIT, lock_and_suspend) or
+ disabling.
*/
void Query_cache::free_cache()
{
DBUG_ENTER("Query_cache::free_cache");
+ DBUG_ASSERT(m_cache_lock_status == LOCKED_NO_WAIT ||
+ m_cache_status == DISABLE_REQUEST);
+
/* Destroy locks */
Query_cache_block *block= queries_blocks;
if (block)
@@ -2802,6 +2816,13 @@ void Query_cache::free_cache()
do
{
Query_cache_query *query= block->query();
+ /*
+ There will not be new requests but some maybe not finished yet,
+ so wait for them by trying lock/unlock
+ */
+ BLOCK_LOCK_WR(block);
+ BLOCK_UNLOCK_WR(block);
+
mysql_rwlock_destroy(&query->lock);
block= block->next;
} while (block != queries_blocks);
@@ -2916,7 +2937,7 @@ my_bool Query_cache::free_old_query()
void Query_cache::free_query_internal(Query_cache_block *query_block)
{
DBUG_ENTER("Query_cache::free_query_internal");
- DBUG_PRINT("qcache", ("free query %p %lu bytes result",
+ DBUG_PRINT("qcache", ("free query %p %zu bytes result",
query_block,
query_block->query()->length() ));
@@ -2986,7 +3007,7 @@ void Query_cache::free_query_internal(Query_cache_block *query_block)
void Query_cache::free_query(Query_cache_block *query_block)
{
DBUG_ENTER("Query_cache::free_query");
- DBUG_PRINT("qcache", ("free query %p %lu bytes result",
+ DBUG_PRINT("qcache", ("free query %p %zu bytes result",
query_block,
query_block->query()->length() ));
@@ -3001,18 +3022,18 @@ void Query_cache::free_query(Query_cache_block *query_block)
*****************************************************************************/
Query_cache_block *
-Query_cache::write_block_data(ulong data_len, uchar* data,
- ulong header_len,
+Query_cache::write_block_data(size_t data_len, uchar* data,
+ size_t header_len,
Query_cache_block::block_type type,
TABLE_COUNTER_TYPE ntab)
{
- ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
+ size_t all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(ntab*sizeof(Query_cache_block_table)) +
header_len);
- ulong len = data_len + all_headers_len;
- ulong align_len= ALIGN_SIZE(len);
+ size_t len = data_len + all_headers_len;
+ size_t align_len= ALIGN_SIZE(len);
DBUG_ENTER("Query_cache::write_block_data");
- DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ DBUG_PRINT("qcache", ("data: %zd, header: %zd, all header: %zd",
data_len, header_len, all_headers_len));
Query_cache_block *block= allocate_block(MY_MAX(align_len,
min_allocation_unit),1, 0);
@@ -3030,33 +3051,33 @@ Query_cache::write_block_data(ulong data_len, uchar* data,
my_bool
Query_cache::append_result_data(Query_cache_block **current_block,
- ulong data_len, uchar* data,
+ size_t data_len, uchar* data,
Query_cache_block *query_block)
{
DBUG_ENTER("Query_cache::append_result_data");
- DBUG_PRINT("qcache", ("append %lu bytes to %p query",
+ DBUG_PRINT("qcache", ("append %zu bytes to %p query",
data_len, query_block));
if (query_block->query()->add(data_len) > query_cache_limit)
{
- DBUG_PRINT("qcache", ("size limit reached %lu > %lu",
+ DBUG_PRINT("qcache", ("size limit reached %zu > %zu",
query_block->query()->length(),
query_cache_limit));
DBUG_RETURN(0);
}
if (*current_block == 0)
{
- DBUG_PRINT("qcache", ("allocated first result data block %lu", data_len));
+ DBUG_PRINT("qcache", ("allocated first result data block %zu", data_len));
DBUG_RETURN(write_result_data(current_block, data_len, data, query_block,
Query_cache_block::RES_BEG));
}
Query_cache_block *last_block = (*current_block)->prev;
- DBUG_PRINT("qcache", ("lastblock %p len %lu used %lu",
+ DBUG_PRINT("qcache", ("lastblock %p len %zu used %zu",
last_block, last_block->length,
last_block->used));
my_bool success = 1;
- ulong last_block_free_space= last_block->length - last_block->used;
+ size_t last_block_free_space= last_block->length - last_block->used;
/*
We will first allocate and write the 'tail' of data, that doesn't fit
@@ -3065,8 +3086,8 @@ Query_cache::append_result_data(Query_cache_block **current_block,
*/
// Try join blocks if physically next block is free...
- ulong tail = data_len - last_block_free_space;
- ulong append_min = get_min_append_result_data_size();
+ size_t tail = data_len - last_block_free_space;
+ size_t append_min = get_min_append_result_data_size();
if (last_block_free_space < data_len &&
append_next_free_block(last_block,
MY_MAX(tail, append_min)))
@@ -3074,7 +3095,7 @@ Query_cache::append_result_data(Query_cache_block **current_block,
// If no space in last block (even after join) allocate new block
if (last_block_free_space < data_len)
{
- DBUG_PRINT("qcache", ("allocate new block for %lu bytes",
+ DBUG_PRINT("qcache", ("allocate new block for %zu bytes",
data_len-last_block_free_space));
Query_cache_block *new_block = 0;
success = write_result_data(&new_block, data_len-last_block_free_space,
@@ -3097,8 +3118,8 @@ Query_cache::append_result_data(Query_cache_block **current_block,
// Now finally write data to the last block
if (success && last_block_free_space > 0)
{
- ulong to_copy = MY_MIN(data_len,last_block_free_space);
- DBUG_PRINT("qcache", ("use free space %lub at block %p to copy %lub",
+ size_t to_copy = MY_MIN(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %zub at block %p to copy %zub",
last_block_free_space,last_block, to_copy));
memcpy((uchar*) last_block + last_block->used, data, to_copy);
last_block->used+=to_copy;
@@ -3108,12 +3129,12 @@ Query_cache::append_result_data(Query_cache_block **current_block,
my_bool Query_cache::write_result_data(Query_cache_block **result_block,
- ulong data_len, uchar* data,
+ size_t data_len, uchar* data,
Query_cache_block *query_block,
Query_cache_block::block_type type)
{
DBUG_ENTER("Query_cache::write_result_data");
- DBUG_PRINT("qcache", ("data_len %lu",data_len));
+ DBUG_PRINT("qcache", ("data_len %zu",data_len));
/*
Reserve block(s) for filling
@@ -3139,8 +3160,8 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
do
{
block->type = type;
- ulong length = block->used - headers_len;
- DBUG_PRINT("qcache", ("write %lu byte in block %p",length,
+ size_t length = block->used - headers_len;
+ DBUG_PRINT("qcache", ("write %zu byte in block %p",length,
block));
memcpy((uchar*) block+headers_len, rest, length);
rest += length;
@@ -3180,16 +3201,16 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
DBUG_RETURN(success);
}
-inline ulong Query_cache::get_min_first_result_data_size()
+inline size_t Query_cache::get_min_first_result_data_size()
{
if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
return min_result_data_size;
- ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
+ size_t avg_result = (query_cache_size - free_memory) / queries_in_cache;
avg_result = MY_MIN(avg_result, query_cache_limit);
return MY_MAX(min_result_data_size, avg_result);
}
-inline ulong Query_cache::get_min_append_result_data_size()
+inline size_t Query_cache::get_min_append_result_data_size()
{
return min_result_data_size;
}
@@ -3198,25 +3219,25 @@ inline ulong Query_cache::get_min_append_result_data_size()
Allocate one or more blocks to hold data
*/
my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
- ulong data_len,
+ size_t data_len,
Query_cache_block *query_block,
my_bool first_block_arg)
{
- ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
+ size_t all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_result)));
- ulong min_size = (first_block_arg ?
+ size_t min_size = (first_block_arg ?
get_min_first_result_data_size():
get_min_append_result_data_size());
Query_cache_block *prev_block= NULL;
Query_cache_block *new_block;
DBUG_ENTER("Query_cache::allocate_data_chain");
- DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu",
+ DBUG_PRINT("qcache", ("data_len %zu, all_headers_len %zu",
data_len, all_headers_len));
do
{
- ulong len= data_len + all_headers_len;
- ulong align_len= ALIGN_SIZE(len);
+ size_t len= data_len + all_headers_len;
+ size_t align_len= ALIGN_SIZE(len);
if (!(new_block= allocate_block(MY_MAX(min_size, align_len),
min_result_data_size == 0,
@@ -3233,7 +3254,7 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
Query_cache_result *header = new_block->result();
header->parent(query_block);
- DBUG_PRINT("qcache", ("Block len %lu used %lu",
+ DBUG_PRINT("qcache", ("Block len %zu used %zu",
new_block->length, new_block->used));
if (prev_block)
@@ -3283,7 +3304,7 @@ void Query_cache::invalidate_table(THD *thd, TABLE *table)
table->s->table_cache_key.length);
}
-void Query_cache::invalidate_table(THD *thd, uchar * key, uint32 key_length)
+void Query_cache::invalidate_table(THD *thd, uchar * key, size_t key_length)
{
DEBUG_SYNC(thd, "wait_in_query_cache_invalidate1");
@@ -3311,7 +3332,7 @@ void Query_cache::invalidate_table(THD *thd, uchar * key, uint32 key_length)
*/
void
-Query_cache::invalidate_table_internal(THD *thd, uchar *key, uint32 key_length)
+Query_cache::invalidate_table_internal(THD *thd, uchar *key, size_t key_length)
{
Query_cache_block *table_block=
(Query_cache_block*)my_hash_search(&tables, key, key_length);
@@ -3414,7 +3435,7 @@ Query_cache::register_tables_from_list(THD *thd, TABLE_LIST *tables_used,
if (!insert_table(thd, tables_used->table->s->table_cache_key.length,
tables_used->table->s->table_cache_key.str,
(*block_table),
- tables_used->db_length, 0,
+ tables_used->db.length, 0,
tables_used->table->file->table_cache_type(),
tables_used->callback_func,
tables_used->engine_data,
@@ -3477,16 +3498,15 @@ my_bool Query_cache::register_all_tables(THD *thd,
*/
my_bool
-Query_cache::insert_table(THD *thd, uint key_len, const char *key,
- Query_cache_block_table *node,
- uint32 db_length, uint8 suffix_length_arg,
+Query_cache::insert_table(THD *thd, size_t key_len, const char *key,
+ Query_cache_block_table *node, size_t db_length, uint8 suffix_length_arg,
uint8 cache_type,
qc_engine_callback callback,
ulonglong engine_data,
my_bool hash)
{
DBUG_ENTER("Query_cache::insert_table");
- DBUG_PRINT("qcache", ("insert table node %p, len %d",
+ DBUG_PRINT("qcache", ("insert table node %p, len %zu",
node, key_len));
Query_cache_block *table_block=
@@ -3552,7 +3572,7 @@ Query_cache::insert_table(THD *thd, uint key_len, const char *key,
}
char *db= header->db();
header->table(db + db_length + 1);
- header->key_length(key_len);
+ header->key_length((uint32)key_len);
header->suffix_length(suffix_length_arg);
header->type(cache_type);
header->callback(callback);
@@ -3624,15 +3644,15 @@ void Query_cache::unlink_table(Query_cache_block_table *node)
*****************************************************************************/
Query_cache_block *
-Query_cache::allocate_block(ulong len, my_bool not_less, ulong min)
+Query_cache::allocate_block(size_t len, my_bool not_less, size_t min)
{
DBUG_ENTER("Query_cache::allocate_block");
- DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu",
+ DBUG_PRINT("qcache", ("len %zu, not less %d, min %zu",
len, not_less,min));
if (len >= MY_MIN(query_cache_size, query_cache_limit))
{
- DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ DBUG_PRINT("qcache", ("Query cache hase only %zu memory and limit %zu",
query_cache_size, query_cache_limit));
DBUG_RETURN(0); // in any case we don't have such piece of memory
}
@@ -3656,11 +3676,11 @@ Query_cache::allocate_block(ulong len, my_bool not_less, ulong min)
Query_cache_block *
-Query_cache::get_free_block(ulong len, my_bool not_less, ulong min)
+Query_cache::get_free_block(size_t len, my_bool not_less, size_t min)
{
Query_cache_block *block = 0, *first = 0;
DBUG_ENTER("Query_cache::get_free_block");
- DBUG_PRINT("qcache",("length %lu, not_less %d, min %lu", len,
+ DBUG_PRINT("qcache",("length %zu, not_less %d, min %zu", len,
(int)not_less, min));
/* Find block with minimal size > len */
@@ -3751,7 +3771,7 @@ void Query_cache::free_memory_block(Query_cache_block *block)
}
-void Query_cache::split_block(Query_cache_block *block, ulong len)
+void Query_cache::split_block(Query_cache_block *block, size_t len)
{
DBUG_ENTER("Query_cache::split_block");
Query_cache_block *new_block = (Query_cache_block*)(((uchar*) block)+len);
@@ -3772,7 +3792,7 @@ void Query_cache::split_block(Query_cache_block *block, ulong len)
else
free_memory_block(new_block);
- DBUG_PRINT("qcache", ("split %p (%lu) new %p",
+ DBUG_PRINT("qcache", ("split %p (%zu) new %p",
block, len, new_block));
DBUG_VOID_RETURN;
}
@@ -3805,16 +3825,16 @@ Query_cache::join_free_blocks(Query_cache_block *first_block_arg,
my_bool Query_cache::append_next_free_block(Query_cache_block *block,
- ulong add_size)
+ size_t add_size)
{
Query_cache_block *next_block = block->pnext;
DBUG_ENTER("Query_cache::append_next_free_block");
- DBUG_PRINT("enter", ("block %p, add_size %lu", block,
+ DBUG_PRINT("enter", ("block %p, add_size %zu", block,
add_size));
if (next_block != first_block && next_block->is_free())
{
- ulong old_len = block->length;
+ size_t old_len = block->length;
exclude_from_free_memory_list(next_block);
next_block->destroy();
total_blocks--;
@@ -3864,14 +3884,14 @@ void Query_cache::insert_into_free_memory_list(Query_cache_block *free_block)
DBUG_VOID_RETURN;
}
-uint Query_cache::find_bin(ulong size)
+uint Query_cache::find_bin(size_t size)
{
DBUG_ENTER("Query_cache::find_bin");
// Binary search
- int left = 0, right = mem_bin_steps;
+ size_t left = 0, right = mem_bin_steps;
do
{
- int middle = (left + right) / 2;
+ size_t middle = (left + right) / 2;
if (steps[middle].size > size)
left = middle+1;
else
@@ -3880,15 +3900,15 @@ uint Query_cache::find_bin(ulong size)
if (left == 0)
{
// first bin not subordinate of common rules
- DBUG_PRINT("qcache", ("first bin (# 0), size %lu",size));
+ DBUG_PRINT("qcache", ("first bin (# 0), size %zu",size));
DBUG_RETURN(0);
}
- uint bin = steps[left].idx -
- (uint)((size - steps[left].size)/steps[left].increment);
+ size_t bin = steps[left].idx -
+ ((size - steps[left].size)/steps[left].increment);
- DBUG_PRINT("qcache", ("bin %u step %u, size %lu step size %lu",
+ DBUG_PRINT("qcache", ("bin %zu step %zu, size %zu step size %zu",
bin, left, size, steps[left].size));
- DBUG_RETURN(bin);
+ DBUG_RETURN((uint)bin);
}
@@ -4070,7 +4090,7 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used,
}
if (tables_used->derived)
{
- DBUG_PRINT("qcache", ("table: %s", tables_used->alias));
+ DBUG_PRINT("qcache", ("table: %s", tables_used->alias.str));
table_count--;
DBUG_PRINT("qcache", ("derived table skipped"));
continue;
@@ -4186,7 +4206,7 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
handler= table->file;
if (!handler->register_query_cache_table(thd,
table->s->normalized_path.str,
- table->s->normalized_path.length,
+ (uint)table->s->normalized_path.length,
&tables_used->callback_func,
&tables_used->engine_data))
{
@@ -4212,7 +4232,7 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
/**
Rearrange all memory blocks so that free memory joins at the
'bottom' of the allocated memory block containing all cache data.
- @see Query_cache::pack(ulong join_limit, uint iteration_limit)
+ @see Query_cache::pack(size_t join_limit, uint iteration_limit)
*/
void Query_cache::pack_cache()
@@ -4223,7 +4243,7 @@ void Query_cache::pack_cache()
uchar *border = 0;
Query_cache_block *before = 0;
- ulong gap = 0;
+ size_t gap = 0;
my_bool ok = 1;
Query_cache_block *block = first_block;
DUMP(this);
@@ -4257,7 +4277,7 @@ void Query_cache::pack_cache()
my_bool Query_cache::move_by_type(uchar **border,
- Query_cache_block **before, ulong *gap,
+ Query_cache_block **before, size_t *gap,
Query_cache_block *block)
{
DBUG_ENTER("Query_cache::move_by_type");
@@ -4279,7 +4299,7 @@ my_bool Query_cache::move_by_type(uchar **border,
block->pnext->pprev=block->pprev;
block->destroy();
total_blocks--;
- DBUG_PRINT("qcache", ("added to gap (%lu)", *gap));
+ DBUG_PRINT("qcache", ("added to gap (%zu)", *gap));
break;
}
case Query_cache_block::TABLE:
@@ -4288,7 +4308,7 @@ my_bool Query_cache::move_by_type(uchar **border,
DBUG_PRINT("qcache", ("block %p TABLE", block));
if (*border == 0)
break;
- ulong len = block->length, used = block->used;
+ size_t len = block->length, used = block->used;
Query_cache_block_table *list_root = block->table(0);
Query_cache_block_table *tprev = list_root->prev,
*tnext = list_root->next;
@@ -4338,7 +4358,7 @@ my_bool Query_cache::move_by_type(uchar **border,
/* Fix hash to point at moved block */
my_hash_replace(&tables, &record_idx, (uchar*) new_block);
- DBUG_PRINT("qcache", ("moved %lu bytes to %p, new gap at %p",
+ DBUG_PRINT("qcache", ("moved %zu bytes to %p, new gap at %p",
len, new_block, *border));
break;
}
@@ -4349,7 +4369,7 @@ my_bool Query_cache::move_by_type(uchar **border,
if (*border == 0)
break;
BLOCK_LOCK_WR(block);
- ulong len = block->length, used = block->used;
+ size_t len = block->length, used = block->used;
TABLE_COUNTER_TYPE n_tables = block->n_tables;
Query_cache_block *prev = block->prev,
*next = block->next,
@@ -4431,7 +4451,7 @@ my_bool Query_cache::move_by_type(uchar **border,
}
/* Fix hash to point at moved block */
my_hash_replace(&queries, &record_idx, (uchar*) new_block);
- DBUG_PRINT("qcache", ("moved %lu bytes to %p, new gap at %p",
+ DBUG_PRINT("qcache", ("moved %zu bytes to %p, new gap at %p",
len, new_block, *border));
break;
}
@@ -4448,7 +4468,7 @@ my_bool Query_cache::move_by_type(uchar **border,
BLOCK_LOCK_WR(query_block);
Query_cache_block *next= block->next, *prev= block->prev;
Query_cache_block::block_type type= block->type;
- ulong len = block->length, used = block->used;
+ size_t len = block->length, used = block->used;
Query_cache_block *pprev = block->pprev,
*pnext = block->pnext,
*new_block =(Query_cache_block*) *border;
@@ -4466,7 +4486,7 @@ my_bool Query_cache::move_by_type(uchar **border,
*border += len;
*before = new_block;
/* If result writing complete && we have free space in block */
- ulong free_space= new_block->length - new_block->used;
+ size_t free_space= new_block->length - new_block->used;
free_space-= free_space % ALIGN_SIZE(1);
if (query->result()->type == Query_cache_block::RESULT &&
new_block->length > new_block->used &&
@@ -4476,11 +4496,11 @@ my_bool Query_cache::move_by_type(uchar **border,
*border-= free_space;
*gap+= free_space;
DBUG_PRINT("qcache",
- ("rest of result free space added to gap (%lu)", *gap));
+ ("rest of result free space added to gap (%zu)", *gap));
new_block->length -= free_space;
}
BLOCK_UNLOCK_WR(query_block);
- DBUG_PRINT("qcache", ("moved %lu bytes to %p, new gap at %p",
+ DBUG_PRINT("qcache", ("moved %zu bytes to %p, new gap at %p",
len, new_block, *border));
break;
}
@@ -4520,7 +4540,7 @@ void Query_cache::relink(Query_cache_block *oblock,
}
-my_bool Query_cache::join_results(ulong join_limit)
+my_bool Query_cache::join_results(size_t join_limit)
{
my_bool has_moving = 0;
DBUG_ENTER("Query_cache::join_results");
@@ -4544,7 +4564,7 @@ my_bool Query_cache::join_results(ulong join_limit)
{
has_moving = 1;
Query_cache_block *first_result = header->result();
- ulong new_len = (header->length() +
+ size_t new_len = (header->length() +
ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_result)));
if (new_result_block->length >
@@ -4557,7 +4577,7 @@ my_bool Query_cache::join_results(ulong join_limit)
new_result_block->used = new_len;
new_result_block->next = new_result_block->prev = new_result_block;
- DBUG_PRINT("qcache", ("new block %lu/%lu (%lu)",
+ DBUG_PRINT("qcache", ("new block %zu/%zu (%zu)",
new_result_block->length,
new_result_block->used,
header->length()));
@@ -4568,9 +4588,9 @@ my_bool Query_cache::join_results(ulong join_limit)
Query_cache_block *result_block = first_result;
do
{
- ulong len = (result_block->used - result_block->headers_len() -
+ size_t len = (result_block->used - result_block->headers_len() -
ALIGN_SIZE(sizeof(Query_cache_result)));
- DBUG_PRINT("loop", ("add block %lu/%lu (%lu)",
+ DBUG_PRINT("loop", ("add block %zu/%zu (%zu)",
result_block->length,
result_block->used,
len));
@@ -4672,14 +4692,14 @@ void Query_cache::bins_dump()
return;
}
- DBUG_PRINT("qcache", ("mem_bin_num=%u, mem_bin_steps=%u",
+ DBUG_PRINT("qcache", ("mem_bin_num=%zu, mem_bin_steps=%zu",
mem_bin_num, mem_bin_steps));
DBUG_PRINT("qcache", ("-------------------------"));
DBUG_PRINT("qcache", (" size idx step"));
DBUG_PRINT("qcache", ("-------------------------"));
for (i=0; i < mem_bin_steps; i++)
{
- DBUG_PRINT("qcache", ("%10lu %3d %10lu", steps[i].size, steps[i].idx,
+ DBUG_PRINT("qcache", ("%10zu %3zd %10zu", steps[i].size, steps[i].idx,
steps[i].increment));
}
DBUG_PRINT("qcache", ("-------------------------"));
@@ -4687,13 +4707,13 @@ void Query_cache::bins_dump()
DBUG_PRINT("qcache", ("-------------------------"));
for (i=0; i < mem_bin_num; i++)
{
- DBUG_PRINT("qcache", ("%10lu %3d %p", bins[i].size, bins[i].number,
+ DBUG_PRINT("qcache", ("%10zu %3d %p", bins[i].size, bins[i].number,
&(bins[i])));
if (bins[i].free_blocks)
{
Query_cache_block *block = bins[i].free_blocks;
do{
- DBUG_PRINT("qcache", ("\\-- %lu %p %p %p %p %p",
+ DBUG_PRINT("qcache", ("\\-- %zu %p %p %p %p %p",
block->length,block,
block->next,block->prev,
block->pnext,block->pprev));
@@ -4720,7 +4740,7 @@ void Query_cache::cache_dump()
do
{
DBUG_PRINT("qcache",
- ("%10lu %10lu %1d %2d %p %p %p %p %p",
+ ("%10zu %10zu %1d %2d %p %p %p %p %p",
i->length, i->used, (int)i->type,
i->n_tables,i,
i->next,i->prev,i->pnext,
@@ -4776,7 +4796,7 @@ void Query_cache::queries_dump()
Query_cache_block *result_beg = result_block;
do
{
- DBUG_PRINT("qcache", ("-r- %u %lu/%lu %p %p %p %p %p",
+ DBUG_PRINT("qcache", ("-r- %u %zu/%zu %p %p %p %p %p",
(uint) result_block->type,
result_block->length, result_block->used,
result_block,
@@ -4854,7 +4874,7 @@ my_bool Query_cache::check_integrity(bool locked)
}
DBUG_PRINT("qcache", ("physical address check ..."));
- ulong free=0, used=0;
+ size_t free=0, used=0;
Query_cache_block * block = first_block;
do
{
@@ -4919,7 +4939,7 @@ my_bool Query_cache::check_integrity(bool locked)
}
else
{
- int idx = (((uchar*)bin) - ((uchar*)bins)) /
+ size_t idx = (((uchar*)bin) - ((uchar*)bins)) /
sizeof(Query_cache_memory_bin);
if (in_list(bins[idx].free_blocks, block, "free memory"))
result = 1;
@@ -4992,7 +5012,7 @@ my_bool Query_cache::check_integrity(bool locked)
if (used + free != query_cache_size)
{
DBUG_PRINT("error",
- ("used memory (%lu) + free memory (%lu) != query_cache_size (%lu)",
+ ("used memory (%zu) + free memory (%zu) != query_cache_size (%zu)",
used, free, query_cache_size));
result = 1;
}
@@ -5000,7 +5020,7 @@ my_bool Query_cache::check_integrity(bool locked)
if (free != free_memory)
{
DBUG_PRINT("error",
- ("free memory (%lu) != free_memory (%lu)",
+ ("free memory (%zu) != free_memory (%zu)",
free, free_memory));
result = 1;
}
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index aac8f141ade..98c5ded7f97 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -126,8 +126,8 @@ struct Query_cache_block
enum block_type {FREE, QUERY, RESULT, RES_CONT, RES_BEG,
RES_INCOMPLETE, TABLE, INCOMPLETE};
- ulong length; // length of all block
- ulong used; // length of data
+ size_t length; // length of all block
+ size_t used; // length of data
/*
Not used **pprev, **prev because really needed access to pervious block:
*pprev to join free blocks
@@ -139,7 +139,7 @@ struct Query_cache_block
TABLE_COUNTER_TYPE n_tables; // number of tables in query
inline bool is_free(void) { return type == FREE; }
- void init(ulong length);
+ void init(size_t length);
void destroy();
uint headers_len();
uchar* data(void);
@@ -155,7 +155,7 @@ struct Query_cache_query
mysql_rwlock_t lock;
Query_cache_block *res;
Query_cache_tls *wri;
- ulong len;
+ size_t len;
unsigned int last_pkt_nr;
uint8 tbls_type;
uint8 ready;
@@ -172,9 +172,9 @@ struct Query_cache_query
inline void writer(Query_cache_tls *p) { wri= p; }
inline uint8 tables_type() { return tbls_type; }
inline void tables_type(uint8 type) { tbls_type= type; }
- inline ulong length() { return len; }
- inline ulong add(ulong packet_len) { return(len+= packet_len); }
- inline void length(ulong length_arg) { len= length_arg; }
+ inline size_t length() { return len; }
+ inline size_t add(size_t packet_len) { return(len+= packet_len); }
+ inline void length(size_t length_arg) { len= length_arg; }
inline uchar* query()
{
return (((uchar*)this) + ALIGN_SIZE(sizeof(Query_cache_query)));
@@ -268,12 +268,12 @@ struct Query_cache_memory_bin
{
Query_cache_memory_bin() {} /* Remove gcc warning */
#ifndef DBUG_OFF
- ulong size;
+ size_t size;
#endif
uint number;
Query_cache_block *free_blocks;
- inline void init(ulong size_arg)
+ inline void init(size_t size_arg)
{
#ifndef DBUG_OFF
size = size_arg;
@@ -286,10 +286,10 @@ struct Query_cache_memory_bin
struct Query_cache_memory_bin_step
{
Query_cache_memory_bin_step() {} /* Remove gcc warning */
- ulong size;
- ulong increment;
- uint idx;
- inline void init(ulong size_arg, uint idx_arg, ulong increment_arg)
+ size_t size;
+ size_t increment;
+ size_t idx;
+ inline void init(size_t size_arg, size_t idx_arg, size_t increment_arg)
{
size = size_arg;
idx = idx_arg;
@@ -301,9 +301,9 @@ class Query_cache
{
public:
/* Info */
- ulong query_cache_size, query_cache_limit;
+ size_t query_cache_size, query_cache_limit;
/* statistics */
- ulong free_memory, queries_in_cache, hits, inserts, refused,
+ size_t free_memory, queries_in_cache, hits, inserts, refused,
free_memory_blocks, total_blocks, lowmem_prunes;
@@ -319,7 +319,7 @@ private:
Cache_staus m_cache_status;
void free_query_internal(Query_cache_block *point);
- void invalidate_table_internal(THD *thd, uchar *key, uint32 key_length);
+ void invalidate_table_internal(THD *thd, uchar *key, size_t key_length);
protected:
/*
@@ -347,10 +347,10 @@ protected:
Query_cache_memory_bin_step *steps; // bins spacing info
HASH queries, tables;
/* options */
- ulong min_allocation_unit, min_result_data_size;
+ size_t min_allocation_unit, min_result_data_size;
uint def_query_hash_size, def_table_hash_size;
- uint mem_bin_num, mem_bin_steps; // See at init_cache & find_bin
+ size_t mem_bin_num, mem_bin_steps; // See at init_cache & find_bin
bool initialized;
@@ -368,12 +368,12 @@ protected:
my_bool free_old_query();
void free_query(Query_cache_block *point);
my_bool allocate_data_chain(Query_cache_block **result_block,
- ulong data_len,
+ size_t data_len,
Query_cache_block *query_block,
my_bool first_block);
void invalidate_table(THD *thd, TABLE_LIST *table);
void invalidate_table(THD *thd, TABLE *table);
- void invalidate_table(THD *thd, uchar *key, uint32 key_length);
+ void invalidate_table(THD *thd, uchar *key, size_t key_length);
void invalidate_table(THD *thd, Query_cache_block *table_block);
void invalidate_query_block_list(THD *thd,
Query_cache_block_table *list_root);
@@ -386,19 +386,19 @@ protected:
TABLE_LIST *tables_used,
TABLE_COUNTER_TYPE tables);
void unlink_table(Query_cache_block_table *node);
- Query_cache_block *get_free_block (ulong len, my_bool not_less,
- ulong min);
+ Query_cache_block *get_free_block (size_t len, my_bool not_less,
+ size_t min);
void free_memory_block(Query_cache_block *point);
- void split_block(Query_cache_block *block, ulong len);
+ void split_block(Query_cache_block *block, size_t len);
Query_cache_block *join_free_blocks(Query_cache_block *first_block,
Query_cache_block *block_in_list);
my_bool append_next_free_block(Query_cache_block *block,
- ulong add_size);
+ size_t add_size);
void exclude_from_free_memory_list(Query_cache_block *free_block);
void insert_into_free_memory_list(Query_cache_block *new_block);
my_bool move_by_type(uchar **border, Query_cache_block **before,
- ulong *gap, Query_cache_block *i);
- uint find_bin(ulong size);
+ size_t *gap, Query_cache_block *i);
+ uint find_bin(size_t size);
void move_to_query_list_end(Query_cache_block *block);
void insert_into_free_memory_sorted_list(Query_cache_block *new_block,
Query_cache_block **list);
@@ -409,31 +409,31 @@ protected:
Query_cache_block *prev,
Query_cache_block *pnext,
Query_cache_block *pprev);
- my_bool join_results(ulong join_limit);
+ my_bool join_results(size_t join_limit);
/*
Following function control structure_guard_mutex
by themself or don't need structure_guard_mutex
*/
- ulong init_cache();
+ size_t init_cache();
void make_disabled();
void free_cache();
- Query_cache_block *write_block_data(ulong data_len, uchar* data,
- ulong header_len,
+ Query_cache_block *write_block_data(size_t data_len, uchar* data,
+ size_t header_len,
Query_cache_block::block_type type,
TABLE_COUNTER_TYPE ntab = 0);
my_bool append_result_data(Query_cache_block **result,
- ulong data_len, uchar* data,
+ size_t data_len, uchar* data,
Query_cache_block *parent);
my_bool write_result_data(Query_cache_block **result,
- ulong data_len, uchar* data,
+ size_t data_len, uchar* data,
Query_cache_block *parent,
Query_cache_block::block_type
type=Query_cache_block::RESULT);
- inline ulong get_min_first_result_data_size();
- inline ulong get_min_append_result_data_size();
- Query_cache_block *allocate_block(ulong len, my_bool not_less,
- ulong min);
+ inline size_t get_min_first_result_data_size();
+ inline size_t get_min_append_result_data_size();
+ Query_cache_block *allocate_block(size_t len, my_bool not_less,
+ size_t min);
/*
If query is cacheable return number tables in query
(query without tables not cached)
@@ -448,9 +448,9 @@ protected:
static my_bool ask_handler_allowance(THD *thd, TABLE_LIST *tables_used);
public:
- Query_cache(ulong query_cache_limit = ULONG_MAX,
- ulong min_allocation_unit = QUERY_CACHE_MIN_ALLOCATION_UNIT,
- ulong min_result_data_size = QUERY_CACHE_MIN_RESULT_DATA_SIZE,
+ Query_cache(size_t query_cache_limit = ULONG_MAX,
+ size_t min_allocation_unit = QUERY_CACHE_MIN_ALLOCATION_UNIT,
+ size_t min_result_data_size = QUERY_CACHE_MIN_RESULT_DATA_SIZE,
uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE,
uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE);
@@ -461,11 +461,11 @@ protected:
/* initialize cache (mutex) */
void init();
/* resize query cache (return real query size, 0 if disabled) */
- ulong resize(ulong query_cache_size);
+ size_t resize(size_t query_cache_size);
/* set limit on result size */
- inline void result_size_limit(ulong limit){query_cache_limit=limit;}
+ inline void result_size_limit(size_t limit){query_cache_limit=limit;}
/* set minimal result data allocation unit size */
- ulong set_min_res_unit(ulong size);
+ size_t set_min_res_unit(size_t size);
/* register query in cache */
void store_query(THD *thd, TABLE_LIST *used_tables);
@@ -482,7 +482,7 @@ protected:
void invalidate(THD *thd, CHANGED_TABLE_LIST *tables_used);
void invalidate_locked_for_write(THD *thd, TABLE_LIST *tables_used);
void invalidate(THD *thd, TABLE *table, my_bool using_transactions);
- void invalidate(THD *thd, const char *key, uint32 key_length,
+ void invalidate(THD *thd, const char *key, size_t key_length,
my_bool using_transactions);
/* Remove all queries that uses any of the tables in following database */
@@ -493,18 +493,18 @@ protected:
void flush();
void pack(THD *thd,
- ulong join_limit = QUERY_CACHE_PACK_LIMIT,
+ size_t join_limit = QUERY_CACHE_PACK_LIMIT,
uint iteration_limit = QUERY_CACHE_PACK_ITERATION);
void destroy();
void insert(THD *thd, Query_cache_tls *query_cache_tls,
const char *packet,
- ulong length,
+ size_t length,
unsigned pkt_nr);
- my_bool insert_table(THD *thd, uint key_len, const char *key,
+ my_bool insert_table(THD *thd, size_t key_len, const char *key,
Query_cache_block_table *node,
- uint32 db_length, uint8 suffix_length_arg,
+ size_t db_length, uint8 suffix_length_arg,
uint8 cache_type,
qc_engine_callback callback,
ulonglong engine_data,
@@ -563,8 +563,8 @@ struct Query_cache_query_flags
sql_mode_t sql_mode;
ulonglong max_sort_length;
ulonglong group_concat_max_len;
- ulong default_week_format;
- ulong div_precision_increment;
+ size_t default_week_format;
+ size_t div_precision_increment;
MY_LOCALE *lc_time_names;
};
#define QUERY_CACHE_FLAGS_SIZE sizeof(Query_cache_query_flags)
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 02f49b6d645..f10a5e51b59 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -138,7 +138,7 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_root)
columns(rhs.columns, mem_root),
name(rhs.name),
option_list(rhs.option_list),
- generated(rhs.generated)
+ generated(rhs.generated), invisible(false)
{
list_copy_and_replace_each_value(columns, mem_root);
}
@@ -553,9 +553,7 @@ char *thd_get_error_context_description(THD *thd, char *buffer,
String str(buffer, length, &my_charset_latin1);
const Security_context *sctx= &thd->main_security_ctx;
char header[256];
- int len;
-
- mysql_mutex_lock(&LOCK_thread_count);
+ size_t len;
/*
The pointers thd->query and thd->proc_info might change since they are
@@ -569,8 +567,8 @@ char *thd_get_error_context_description(THD *thd, char *buffer,
const char *proc_info= thd->proc_info;
len= my_snprintf(header, sizeof(header),
- "MySQL thread id %lu, OS thread handle %lu, query id %lu",
- (ulong) thd->thread_id, (ulong) thd->real_id, (ulong) thd->query_id);
+ "MySQL thread id %u, OS thread handle %lu, query id %llu",
+ (uint)thd->thread_id, (ulong) thd->real_id, (ulonglong) thd->query_id);
str.length(0);
str.append(header, len);
@@ -612,7 +610,6 @@ char *thd_get_error_context_description(THD *thd, char *buffer,
}
mysql_mutex_unlock(&thd->LOCK_thd_data);
}
- mysql_mutex_unlock(&LOCK_thread_count);
if (str.c_ptr_safe() == buffer)
return buffer;
@@ -704,14 +701,11 @@ handle_condition(THD *thd,
extern "C" void thd_kill_timeout(THD* thd)
{
thd->status_var.max_statement_time_exceeded++;
- mysql_mutex_lock(&thd->LOCK_thd_data);
/* Kill queries that can't cause data corruptions */
thd->awake(KILL_TIMEOUT);
- mysql_mutex_unlock(&thd->LOCK_thd_data);
}
-
-THD::THD(my_thread_id id, bool is_wsrep_applier)
+THD::THD(my_thread_id id, bool is_wsrep_applier, bool skip_global_sys_var_lock)
:Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION,
/* statement id */ 0),
rli_fake(0), rgi_fake(0), rgi_slave(NULL),
@@ -787,8 +781,14 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
the destructor works OK in case of an error. The main_mem_root
will be re-initialized in init_for_queries().
*/
- init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0,
- MYF(MY_THREAD_SPECIFIC));
+ init_sql_alloc(&main_mem_root, "THD::main_mem_root",
+ ALLOC_ROOT_MIN_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
+
+ /*
+ Allocation of user variables for binary logging is always done with main
+ mem root
+ */
+ user_var_events_alloc= mem_root;
stmt_arena= this;
thread_stack= 0;
@@ -819,6 +819,8 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
// Must be reset to handle error with THD's created for init of mysqld
lex->current_select= 0;
start_utime= utime_after_query= 0;
+ system_time= 0;
+ system_time_sec_part= 0;
utime_after_lock= 0L;
progress.arena= 0;
progress.report_to_client= 0;
@@ -898,7 +900,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
/* Call to init() below requires fully initialized Open_tables_state. */
reset_open_tables_state(this);
- init();
+ init(skip_global_sys_var_lock);
#if defined(ENABLED_PROFILING)
profiling.set_thd(this);
#endif
@@ -1269,10 +1271,11 @@ const Type_handler *THD::type_handler_for_date() const
Init common variables that has to be reset on start and on change_user
*/
-void THD::init(void)
+void THD::init(bool skip_lock)
{
DBUG_ENTER("thd::init");
- mysql_mutex_lock(&LOCK_global_system_variables);
+ if (!skip_lock)
+ mysql_mutex_lock(&LOCK_global_system_variables);
plugin_thdvar_init(this);
/*
plugin_thd_var_init() sets variables= global_system_variables, which
@@ -1285,8 +1288,8 @@ void THD::init(void)
::strmake(default_master_connection_buff,
global_system_variables.default_master_connection.str,
variables.default_master_connection.length);
-
- mysql_mutex_unlock(&LOCK_global_system_variables);
+ if (!skip_lock)
+ mysql_mutex_unlock(&LOCK_global_system_variables);
user_time.val= start_time= start_time_sec_part= 0;
@@ -1363,7 +1366,7 @@ void THD::init(void)
session_tracker.enable(this);
#endif //EMBEDDED_LIBRARY
- apc_target.init(&LOCK_thd_data);
+ apc_target.init(&LOCK_thd_kill);
DBUG_VOID_RETURN;
}
@@ -1478,6 +1481,75 @@ void THD::change_user(void)
sp_cache_clear(&sp_func_cache);
}
+/**
+ Change default database
+
+ @note This is coded to have as few instructions as possible under
+ LOCK_thd_data
+*/
+
+bool THD::set_db(const LEX_CSTRING *new_db)
+{
+ bool result= 0;
+ /*
+ Acquiring mutex LOCK_thd_data as we either free the memory allocated
+ for the database and reallocating the memory for the new db or memcpy
+ the new_db to the db.
+ */
+ /* Do not reallocate memory if current chunk is big enough. */
+ if (db.str && new_db->str && db.length >= new_db->length)
+ {
+ mysql_mutex_lock(&LOCK_thd_data);
+ db.length= new_db->length;
+ memcpy((char*) db.str, new_db->str, new_db->length+1);
+ mysql_mutex_unlock(&LOCK_thd_data);
+ }
+ else
+ {
+ const char *org_db= db.str;
+ const char *tmp= NULL;
+ if (new_db->str)
+ {
+ if (!(tmp= my_strndup(new_db->str, new_db->length, MYF(MY_WME | ME_FATALERROR))))
+ result= 1;
+ }
+
+ mysql_mutex_lock(&LOCK_thd_data);
+ db.str= tmp;
+ db.length= tmp ? new_db->length : 0;
+ mysql_mutex_unlock(&LOCK_thd_data);
+ my_free((char*) org_db);
+ }
+ PSI_CALL_set_thread_db(db.str, (int) db.length);
+ return result;
+}
+
+
+/**
+ Set the current database
+
+ @param new_db a pointer to the new database name.
+ @param new_db_len length of the new database name.
+
+ @note This operation just sets {db, db_length}. Switching the current
+ database usually involves other actions, like switching other database
+ attributes including security context. In the future, this operation
+ will be made private and more convenient interface will be provided.
+*/
+
+void THD::reset_db(const LEX_CSTRING *new_db)
+{
+ if (new_db->str != db.str || new_db->length != db.length)
+ {
+ if (db.str != 0)
+ DBUG_PRINT("QQ", ("Overwriting: %p", db.str));
+ mysql_mutex_lock(&LOCK_thd_data);
+ db= *new_db;
+ mysql_mutex_unlock(&LOCK_thd_data);
+ PSI_CALL_set_thread_db(db.str, (int) db.length);
+ }
+}
+
/* Do operations that may take a long time */
@@ -1556,8 +1628,8 @@ void THD::cleanup(void)
void THD::free_connection()
{
DBUG_ASSERT(free_connection_done == 0);
- my_free(db);
- db= NULL;
+ my_free((char*) db.str);
+ db= null_clex_str;
#ifndef EMBEDDED_LIBRARY
if (net.vio)
vio_delete(net.vio);
@@ -1627,9 +1699,13 @@ THD::~THD()
if (!status_in_global)
add_status_to_global();
- /* Ensure that no one is using THD */
- mysql_mutex_lock(&LOCK_thd_data);
- mysql_mutex_unlock(&LOCK_thd_data);
+ /*
+ Other threads may have a lock on LOCK_thd_kill to ensure that this
+ THD is not deleted while they access it. The following mutex_lock
+ ensures that no one else is using this THD and it's now safe to delete
+ */
+ mysql_mutex_lock(&LOCK_thd_kill);
+ mysql_mutex_unlock(&LOCK_thd_kill);
#ifdef WITH_WSREP
mysql_mutex_lock(&LOCK_wsrep_thd);
@@ -1811,17 +1887,17 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
This is normally called from another thread's THD object.
- @note Do always call this while holding LOCK_thd_data.
+ @note Do always call this while holding LOCK_thd_kill.
NOT_KILLED is used to awake a thread for a slave
*/
-void THD::awake(killed_state state_to_set)
+void THD::awake_no_mutex(killed_state state_to_set)
{
DBUG_ENTER("THD::awake");
DBUG_PRINT("enter", ("this: %p current_thd: %p state: %d",
this, current_thd, (int) state_to_set));
THD_CHECK_SENTRY(this);
- mysql_mutex_assert_owner(&LOCK_thd_data);
+ mysql_mutex_assert_owner(&LOCK_thd_kill);
print_aborted_warning(3, "KILLED");
@@ -1832,8 +1908,6 @@ void THD::awake(killed_state state_to_set)
if (killed >= KILL_CONNECTION)
state_to_set= killed;
- /* Set the 'killed' flag of 'this', which is the target THD object. */
- mysql_mutex_lock(&LOCK_thd_kill);
set_killed_no_mutex(state_to_set);
if (state_to_set >= KILL_CONNECTION || state_to_set == NOT_KILLED)
@@ -1920,7 +1994,6 @@ void THD::awake(killed_state state_to_set)
}
mysql_mutex_unlock(&mysys_var->mutex);
}
- mysql_mutex_unlock(&LOCK_thd_kill);
DBUG_VOID_RETURN;
}
@@ -1936,10 +2009,10 @@ void THD::disconnect()
{
Vio *vio= NULL;
- mysql_mutex_lock(&LOCK_thd_data);
-
set_killed(KILL_CONNECTION);
+ mysql_mutex_lock(&LOCK_thd_data);
+
#ifdef SIGNAL_WITH_VIO_CLOSE
/*
Since a active vio might might have not been set yet, in
@@ -1972,9 +2045,9 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
{
/* This code is similar to kill_delayed_threads() */
DBUG_PRINT("info", ("kill delayed thread"));
- mysql_mutex_lock(&in_use->LOCK_thd_data);
+ mysql_mutex_lock(&in_use->LOCK_thd_kill);
if (in_use->killed < KILL_CONNECTION)
- in_use->set_killed(KILL_CONNECTION);
+ in_use->set_killed_no_mutex(KILL_CONNECTION);
if (in_use->mysys_var)
{
mysql_mutex_lock(&in_use->mysys_var->mutex);
@@ -1985,7 +2058,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
in_use->mysys_var->abort= 1;
mysql_mutex_unlock(&in_use->mysys_var->mutex);
}
- mysql_mutex_unlock(&in_use->LOCK_thd_data);
+ mysql_mutex_unlock(&in_use->LOCK_thd_kill);
signalled= TRUE;
}
@@ -2110,7 +2183,7 @@ bool THD::store_globals()
return 1;
/*
mysys_var is concurrently readable by a killer thread.
- It is protected by LOCK_thd_data, it is not needed to lock while the
+ It is protected by LOCK_thd_kill, it is not needed to lock while the
pointer is changing from NULL not non-NULL. If the kill thread reads
NULL it doesn't refer to anything, but if it is non-NULL we need to
ensure that the thread doesn't proceed to assign another thread to
@@ -2161,9 +2234,9 @@ bool THD::store_globals()
void THD::reset_globals()
{
- mysql_mutex_lock(&LOCK_thd_data);
+ mysql_mutex_lock(&LOCK_thd_kill);
mysys_var= 0;
- mysql_mutex_unlock(&LOCK_thd_data);
+ mysql_mutex_unlock(&LOCK_thd_kill);
/* Undocking the thread specific data. */
set_current_thd(0);
@@ -2289,7 +2362,7 @@ void THD::cleanup_after_query()
*/
bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
- const char *from, uint from_length,
+ const char *from, size_t from_length,
CHARSET_INFO *from_cs)
{
DBUG_ENTER("THD::convert_string");
@@ -2316,7 +2389,7 @@ bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
dstcs and srccs cannot be &my_charset_bin.
*/
bool THD::convert_fix(CHARSET_INFO *dstcs, LEX_STRING *dst,
- CHARSET_INFO *srccs, const char *src, uint src_length,
+ CHARSET_INFO *srccs, const char *src, size_t src_length,
String_copier *status)
{
DBUG_ENTER("THD::convert_fix");
@@ -2334,7 +2407,7 @@ bool THD::convert_fix(CHARSET_INFO *dstcs, LEX_STRING *dst,
Copy or convert a string.
*/
bool THD::copy_fix(CHARSET_INFO *dstcs, LEX_STRING *dst,
- CHARSET_INFO *srccs, const char *src, uint src_length,
+ CHARSET_INFO *srccs, const char *src, size_t src_length,
String_copier *status)
{
DBUG_ENTER("THD::copy_fix");
@@ -2351,7 +2424,7 @@ bool THD::copy_fix(CHARSET_INFO *dstcs, LEX_STRING *dst,
class String_copier_with_error: public String_copier
{
public:
- bool check_errors(CHARSET_INFO *srccs, const char *src, uint src_length)
+ bool check_errors(CHARSET_INFO *srccs, const char *src, size_t src_length)
{
if (most_important_error_pos())
{
@@ -2366,7 +2439,7 @@ public:
bool THD::convert_with_error(CHARSET_INFO *dstcs, LEX_STRING *dst,
CHARSET_INFO *srccs,
- const char *src, uint src_length)
+ const char *src, size_t src_length)
{
String_copier_with_error status;
return convert_fix(dstcs, dst, srccs, src, src_length, &status) ||
@@ -2376,7 +2449,7 @@ bool THD::convert_with_error(CHARSET_INFO *dstcs, LEX_STRING *dst,
bool THD::copy_with_error(CHARSET_INFO *dstcs, LEX_STRING *dst,
CHARSET_INFO *srccs,
- const char *src, uint src_length)
+ const char *src, size_t src_length)
{
String_copier_with_error status;
return copy_fix(dstcs, dst, srccs, src, src_length, &status) ||
@@ -2431,7 +2504,7 @@ Item *THD::make_string_literal(const char *str, size_t length,
str= to.str;
length= to.length;
}
- return new (mem_root) Item_string(this, str, length,
+ return new (mem_root) Item_string(this, str, (uint)length,
variables.collation_connection,
DERIVATION_COERCIBLE, repertoire);
}
@@ -2443,7 +2516,7 @@ Item *THD::make_string_literal_nchar(const Lex_string_with_metadata_st &str)
if (!str.length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL))
return new (mem_root) Item_null(this, 0, national_charset_info);
- return new (mem_root) Item_string(this, str.str, str.length,
+ return new (mem_root) Item_string(this, str.str, (uint)str.length,
national_charset_info,
DERIVATION_COERCIBLE,
str.repertoire());
@@ -2456,7 +2529,7 @@ Item *THD::make_string_literal_charset(const Lex_string_with_metadata_st &str,
if (!str.length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL))
return new (mem_root) Item_null(this, 0, cs);
return new (mem_root) Item_string_with_introducer(this,
- str.str, str.length, cs);
+ str.str, (uint)str.length, cs);
}
@@ -2469,7 +2542,7 @@ Item *THD::make_string_literal_concat(Item *item, const LEX_CSTRING &str)
{
CHARSET_INFO *cs= variables.collation_connection;
uint repertoire= my_string_repertoire(cs, str.str, str.length);
- return new (mem_root) Item_string(this, str.str, str.length, cs,
+ return new (mem_root) Item_string(this, str.str, (uint)str.length, cs,
DERIVATION_COERCIBLE, repertoire);
}
return item;
@@ -2477,7 +2550,7 @@ Item *THD::make_string_literal_concat(Item *item, const LEX_CSTRING &str)
DBUG_ASSERT(item->type() == Item::STRING_ITEM);
DBUG_ASSERT(item->basic_const_item());
- static_cast<Item_string*>(item)->append(str.str, str.length);
+ static_cast<Item_string*>(item)->append(str.str, (uint)str.length);
if (!(item->collation.repertoire & MY_REPERTOIRE_EXTENDED))
{
// If the string has been pure ASCII so far, check the new part.
@@ -2539,7 +2612,7 @@ void THD::add_changed_table(TABLE *table)
}
-void THD::add_changed_table(const char *key, long key_length)
+void THD::add_changed_table(const char *key, size_t key_length)
{
DBUG_ENTER("THD::add_changed_table(key)");
CHANGED_TABLE_LIST **prev_changed = &transaction.changed_tables;
@@ -2552,7 +2625,7 @@ void THD::add_changed_table(const char *key, long key_length)
{
list_include(prev_changed, curr, changed_table_dup(key, key_length));
DBUG_PRINT("info",
- ("key_length: %ld %u", key_length,
+ ("key_length: %zu %zu", key_length,
(*prev_changed)->key_length));
DBUG_VOID_RETURN;
}
@@ -2563,7 +2636,7 @@ void THD::add_changed_table(const char *key, long key_length)
{
list_include(prev_changed, curr, changed_table_dup(key, key_length));
DBUG_PRINT("info",
- ("key_length: %ld %u", key_length,
+ ("key_length: %zu %zu", key_length,
(*prev_changed)->key_length));
DBUG_VOID_RETURN;
}
@@ -2575,13 +2648,13 @@ void THD::add_changed_table(const char *key, long key_length)
}
}
*prev_changed = changed_table_dup(key, key_length);
- DBUG_PRINT("info", ("key_length: %ld %u", key_length,
+ DBUG_PRINT("info", ("key_length: %zu %zu", key_length,
(*prev_changed)->key_length));
DBUG_VOID_RETURN;
}
-CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
+CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, size_t key_length)
{
CHANGED_TABLE_LIST* new_table =
(CHANGED_TABLE_LIST*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST))+
@@ -2750,10 +2823,14 @@ struct Item_change_record: public ilink
thd->mem_root (due to possible set_n_backup_active_arena called for thd).
*/
-void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
- MEM_ROOT *runtime_memroot)
+void
+Item_change_list::nocheck_register_item_tree_change(Item **place,
+ Item *old_value,
+ MEM_ROOT *runtime_memroot)
{
Item_change_record *change;
+ DBUG_ENTER("THD::nocheck_register_item_tree_change");
+ DBUG_PRINT("enter", ("Register %p <- %p", old_value, (*place)));
/*
Now we use one node per change, which adds some memory overhead,
but still is rather fast as we use alloc_root for allocations.
@@ -2766,12 +2843,13 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
OOM, thd->fatal_error() is called by the error handler of the
memroot. Just return.
*/
- return;
+ DBUG_VOID_RETURN;
}
change= new (change_mem) Item_change_record;
change->place= place;
change->old_value= old_value;
change_list.append(change);
+ DBUG_VOID_RETURN;
}
/**
@@ -2789,10 +2867,15 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
changes to substitute the same reference at both locations L1 and L2.
*/
-void THD::check_and_register_item_tree_change(Item **place, Item **new_value,
- MEM_ROOT *runtime_memroot)
+void
+Item_change_list::check_and_register_item_tree_change(Item **place,
+ Item **new_value,
+ MEM_ROOT *runtime_memroot)
{
Item_change_record *change;
+ DBUG_ENTER("THD::check_and_register_item_tree_change");
+ DBUG_PRINT("enter", ("Register: %p (%p) <- %p (%p)",
+ *place, place, *new_value, new_value));
I_List_iterator<Item_change_record> it(change_list);
while ((change= it++))
{
@@ -2802,20 +2885,21 @@ void THD::check_and_register_item_tree_change(Item **place, Item **new_value,
if (change)
nocheck_register_item_tree_change(place, change->old_value,
runtime_memroot);
+ DBUG_VOID_RETURN;
}
-void THD::rollback_item_tree_changes()
+void Item_change_list::rollback_item_tree_changes()
{
I_List_iterator<Item_change_record> it(change_list);
Item_change_record *change;
- DBUG_ENTER("rollback_item_tree_changes");
while ((change= it++))
+ {
*change->place= change->old_value;
+ }
/* We can forget about changes memory: it's allocated in runtime memroot */
change_list.empty();
- DBUG_VOID_RETURN;
}
@@ -3034,8 +3118,7 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange,
if (!dirname_length(exchange->file_name))
{
- strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->db ? thd->db : "",
- NullS);
+ strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->get_db(), NullS);
(void) fn_format(path, exchange->file_name, path, "", option);
}
else
@@ -3650,7 +3733,7 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
mvsp->type_handler() == &type_handler_row)
{
// SELECT INTO row_type_sp_variable
- if (thd->spcont->get_item(mvsp->offset)->cols() != list.elements)
+ if (thd->spcont->get_variable(mvsp->offset)->cols() != list.elements)
goto error;
m_var_sp_row= mvsp;
return 0;
@@ -3709,6 +3792,7 @@ void Query_arena::set_query_arena(Query_arena *set)
mem_root= set->mem_root;
free_list= set->free_list;
state= set->state;
+ is_stored_procedure= set->is_stored_procedure;
}
@@ -3725,12 +3809,11 @@ Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
enum enum_state state_arg, ulong id_arg)
:Query_arena(mem_root_arg, state_arg),
id(id_arg),
- mark_used_columns(MARK_COLUMNS_READ),
+ column_usage(MARK_COLUMNS_READ),
lex(lex_arg),
- db(NULL),
- db_length(0)
+ db(null_clex_str)
{
- name.str= NULL;
+ name= null_clex_str;
}
@@ -3743,8 +3826,8 @@ Query_arena::Type Statement::type() const
void Statement::set_statement(Statement *stmt)
{
id= stmt->id;
- mark_used_columns= stmt->mark_used_columns;
- lex= stmt->lex;
+ column_usage= stmt->column_usage;
+ stmt_lex= lex= stmt->lex;
query_string= stmt->query_string;
}
@@ -4067,7 +4150,7 @@ bool
select_materialize_with_stats::
create_result_table(THD *thd_arg, List<Item> *column_types,
bool is_union_distinct, ulonglong options,
- const char *table_alias, bool bit_fields_as_long,
+ const LEX_CSTRING *table_alias, bool bit_fields_as_long,
bool create_table,
bool keep_row_order,
uint hidden)
@@ -4078,7 +4161,7 @@ create_result_table(THD *thd_arg, List<Item> *column_types,
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
(ORDER*) 0, is_union_distinct, 1,
- options, HA_POS_ERROR, (char*) table_alias,
+ options, HA_POS_ERROR, table_alias,
!create_table, keep_row_order)))
return TRUE;
@@ -4179,7 +4262,7 @@ void TMP_TABLE_PARAM::init()
}
-void thd_increment_bytes_sent(void *thd, ulong length)
+void thd_increment_bytes_sent(void *thd, size_t length)
{
/* thd == 0 when close_connection() calls net_send_error() */
if (likely(thd != 0))
@@ -4195,15 +4278,10 @@ my_bool thd_net_is_killed()
}
-void thd_increment_bytes_received(void *thd, ulong length)
+void thd_increment_bytes_received(void *thd, size_t length)
{
- ((THD*) thd)->status_var.bytes_received+= length;
-}
-
-
-void thd_increment_net_big_packet_count(void *thd, ulong length)
-{
- ((THD*) thd)->status_var.net_big_packet_count+= length;
+ if (thd != NULL) // MDEV-13073 Ack collector having NULL
+ ((THD*) thd)->status_var.bytes_received+= length;
}
@@ -4211,6 +4289,12 @@ void THD::set_status_var_init()
{
bzero((char*) &status_var, offsetof(STATUS_VAR,
last_cleared_system_status_var));
+ /*
+ Session status for Threads_running is always 1. It can only be queried
+ by thread itself via INFORMATION_SCHEMA.SESSION_STATUS or SHOW [SESSION]
+ STATUS. And at this point thread is guaranteed to be running.
+ */
+ status_var.threads_running= 1;
}
@@ -4646,8 +4730,10 @@ TABLE *open_purge_table(THD *thd, const char *db, size_t dblen,
Open_table_context ot_ctx(thd, 0);
TABLE_LIST *tl= (TABLE_LIST*)thd->alloc(sizeof(TABLE_LIST));
+ LEX_CSTRING db_name= {db, dblen };
+ LEX_CSTRING table_name= { tb, tblen };
- tl->init_one_table(db, dblen, tb, tblen, tb, TL_READ);
+ tl->init_one_table(&db_name, &table_name, 0, TL_READ);
tl->i_s_requested_object= OPEN_TABLE_ONLY;
bool error= open_table(thd, tl, &ot_ctx);
@@ -4684,7 +4770,7 @@ TABLE *find_fk_open_table(THD *thd, const char *db, size_t db_len,
{
if (t->s->db.length == db_len && t->s->table_name.length == table_len &&
!strcmp(t->s->db.str, db) && !strcmp(t->s->table_name.str, table) &&
- t->pos_in_table_list->prelocking_placeholder == TABLE_LIST::FK)
+ t->pos_in_table_list->prelocking_placeholder == TABLE_LIST::PRELOCK_FK)
return t;
}
return NULL;
@@ -4775,18 +4861,11 @@ extern "C" int thd_slave_thread(const MYSQL_THD thd)
return(thd->slave_thread);
}
-/* Returns true for a worker thread in parallel replication. */
-extern "C" int thd_rpl_is_parallel(const MYSQL_THD thd)
-{
- return thd->rgi_slave && thd->rgi_slave->is_parallel_exec;
-}
-
-
/* Returns high resolution timestamp for the start
of the current query. */
extern "C" unsigned long long thd_start_utime(const MYSQL_THD thd)
{
- return thd->start_utime;
+ return thd->start_time * 1000000 + thd->start_time_sec_part;
}
@@ -5029,17 +5108,14 @@ extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
extern "C" int thd_binlog_format(const MYSQL_THD thd)
{
-#ifdef WITH_WSREP
if (WSREP(thd))
{
/* for wsrep binlog format is meaningful also when binlogging is off */
- return (int) WSREP_BINLOG_FORMAT(thd->variables.binlog_format);
+ return (int) thd->wsrep_binlog_format();
}
-#endif /* WITH_WSREP */
if (mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG))
return (int) thd->variables.binlog_format;
- else
- return BINLOG_FORMAT_UNSPEC;
+ return BINLOG_FORMAT_UNSPEC;
}
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
@@ -5050,7 +5126,7 @@ extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
extern "C" bool thd_binlog_filter_ok(const MYSQL_THD thd)
{
- return binlog_filter->db_ok(thd->db);
+ return binlog_filter->db_ok(thd->db.str);
}
/*
@@ -5510,9 +5586,9 @@ void THD::set_query_and_id(char *query_arg, uint32 query_length_arg,
/** Assign a new value to thd->mysys_var. */
void THD::set_mysys_var(struct st_my_thread_var *new_mysys_var)
{
- mysql_mutex_lock(&LOCK_thd_data);
+ mysql_mutex_lock(&LOCK_thd_kill);
mysys_var= new_mysys_var;
- mysql_mutex_unlock(&LOCK_thd_data);
+ mysql_mutex_unlock(&LOCK_thd_kill);
}
/**
@@ -5645,7 +5721,7 @@ public:
MY_MEMORY_ORDER_RELAXED))
{
old&= ACQUIRED | RECOVERED;
- (void) LF_BACKOFF;
+ (void) LF_BACKOFF();
}
}
bool acquire_recovered()
@@ -5658,7 +5734,7 @@ public:
if (!(old & RECOVERED) || (old & ACQUIRED))
return false;
old= RECOVERED;
- (void) LF_BACKOFF;
+ (void) LF_BACKOFF();
}
return true;
}
@@ -5952,7 +6028,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
*/
if (mysql_bin_log.is_open() && (variables.option_bits & OPTION_BIN_LOG) &&
!(wsrep_binlog_format() == BINLOG_FORMAT_STMT &&
- !binlog_filter->db_ok(db)))
+ !binlog_filter->db_ok(db.str)))
{
if (is_bulk_op())
@@ -6055,7 +6131,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
handler::Table_flags const flags= table->table->file->ha_table_flags();
DBUG_PRINT("info", ("table: %s; ha_table_flags: 0x%llx",
- table->table_name, flags));
+ table->table_name.str, flags));
if (table->table->s->no_replicate)
{
@@ -6087,7 +6163,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
replicated_tables_count++;
if (table->lock_type <= TL_READ_NO_INSERT &&
- table->prelocking_placeholder != TABLE_LIST::FK)
+ table->prelocking_placeholder != TABLE_LIST::PRELOCK_FK)
has_read_tables= true;
else if (table->table->found_next_number_field &&
(table->lock_type >= TL_WRITE_ALLOW_WRITE))
@@ -6359,7 +6435,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
if (table->table->file->ht->db_type == DB_TYPE_BLACKHOLE_DB &&
table->lock_type >= TL_WRITE_ALLOW_WRITE)
{
- table_names.append(table->table_name);
+ table_names.append(&table->table_name);
table_names.append(",");
}
}
@@ -6391,7 +6467,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
mysql_bin_log.is_open(),
(variables.option_bits & OPTION_BIN_LOG),
(uint) wsrep_binlog_format(),
- binlog_filter->db_ok(db)));
+ binlog_filter->db_ok(db.str)));
#endif
DBUG_RETURN(0);
@@ -7060,6 +7136,15 @@ static bool protect_against_unsafe_warning_flood(int unsafe_type)
DBUG_RETURN(unsafe_warning_suppression_active[unsafe_type]);
}
+MYSQL_TIME THD::query_start_TIME()
+{
+ MYSQL_TIME res;
+ variables.time_zone->gmt_sec_to_TIME(&res, query_start());
+ res.second_part= query_start_sec_part();
+ time_zone_used= 1;
+ return res;
+}
+
/**
Auxiliary method used by @c binlog_query() to raise warnings.
@@ -7679,3 +7764,16 @@ void Database_qualified_name::copy(MEM_ROOT *mem_root,
#endif /* !defined(MYSQL_CLIENT) */
+
+
+Query_arena_stmt::Query_arena_stmt(THD *_thd) :
+ thd(_thd)
+{
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+}
+
+Query_arena_stmt::~Query_arena_stmt()
+{
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 1358fe09f4c..e5f9328703f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -92,8 +92,25 @@ enum enum_slave_run_triggers_for_rbr { SLAVE_RUN_TRIGGERS_FOR_RBR_NO,
SLAVE_RUN_TRIGGERS_FOR_RBR_LOGGING};
enum enum_slave_type_conversions { SLAVE_TYPE_CONVERSIONS_ALL_LOSSY,
SLAVE_TYPE_CONVERSIONS_ALL_NON_LOSSY};
-enum enum_mark_columns
-{ MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE};
+
+/*
+ MARK_COLUMNS_READ: A column is goind to be read.
+ MARK_COLUMNS_WRITE: A column is going to be written to.
+ MARK_COLUMNS_READ: A column is goind to be read.
+ A bit in read set is set to inform handler that the field
+ is to be read. If field list contains duplicates, then
+ thd->dup_field is set to point to the last found
+ duplicate.
+ MARK_COLUMNS_WRITE: A column is going to be written to.
+ A bit is set in write set to inform handler that it needs
+ to update this field in write_row and update_row.
+*/
+enum enum_column_usage
+{ COLUMNS_READ, COLUMNS_WRITE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE};
+
+static inline bool should_mark_column(enum_column_usage column_usage)
+{ return column_usage >= MARK_COLUMNS_READ; }
+
enum enum_filetype { FILETYPE_CSV, FILETYPE_XML };
enum enum_binlog_row_image {
@@ -140,6 +157,7 @@ enum enum_binlog_row_image {
#define MODE_NO_ENGINE_SUBSTITUTION (1ULL << 30)
#define MODE_PAD_CHAR_TO_FULL_LENGTH (1ULL << 31)
#define MODE_EMPTY_STRING_IS_NULL (1ULL << 32)
+#define MODE_SIMULTANEOUS_ASSIGNMENT (1ULL << 33)
/* Bits for different old style modes */
#define OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE (1 << 0)
@@ -148,7 +166,6 @@ enum enum_binlog_row_image {
extern char internal_table_name[2];
extern char empty_c_string[1];
-extern LEX_STRING EMPTY_STR;
extern MYSQL_PLUGIN_IMPORT const char **errmesg;
extern bool volatile shutdown_in_progress;
@@ -195,7 +212,7 @@ typedef struct st_user_var_events
{
user_var_entry *user_var_event;
char *value;
- ulong length;
+ size_t length;
Item_result type;
uint charset_number;
bool unsigned_flag;
@@ -284,8 +301,9 @@ class Alter_column :public Sql_alloc {
public:
const char *name;
Virtual_column_info *default_value;
- Alter_column(const char *par_name, Virtual_column_info *expr)
- :name(par_name), default_value(expr) {}
+ bool alter_if_exists;
+ Alter_column(const char *par_name, Virtual_column_info *expr, bool par_exists)
+ :name(par_name), default_value(expr), alter_if_exists(par_exists) {}
/**
Used to make a clone of this object for ALTER/CREATE TABLE
@sa comment for Key_part_spec::clone
@@ -304,22 +322,25 @@ public:
LEX_CSTRING name;
engine_option_value *option_list;
bool generated;
+ bool invisible;
Key(enum Keytype type_par, const LEX_CSTRING *name_arg,
ha_key_alg algorithm_arg, bool generated_arg, DDL_options_st ddl_options)
:DDL_options(ddl_options),
type(type_par), key_create_info(default_key_create_info),
- name(*name_arg), option_list(NULL), generated(generated_arg)
+ name(*name_arg), option_list(NULL), generated(generated_arg),
+ invisible(false)
{
key_create_info.algorithm= algorithm_arg;
- }
+ }
Key(enum Keytype type_par, const LEX_CSTRING *name_arg,
KEY_CREATE_INFO *key_info_arg,
bool generated_arg, List<Key_part_spec> *cols,
engine_option_value *create_opt, DDL_options_st ddl_options)
:DDL_options(ddl_options),
type(type_par), key_create_info(*key_info_arg), columns(*cols),
- name(*name_arg), option_list(create_opt), generated(generated_arg)
+ name(*name_arg), option_list(create_opt), generated(generated_arg),
+ invisible(false)
{}
Key(const Key &rhs, MEM_ROOT *mem_root);
virtual ~Key() {}
@@ -341,11 +362,13 @@ public:
LEX_CSTRING ref_db;
LEX_CSTRING ref_table;
List<Key_part_spec> ref_columns;
- uint delete_opt, update_opt, match_opt;
+ enum enum_fk_option delete_opt, update_opt;
+ enum fk_match_opt match_opt;
Foreign_key(const LEX_CSTRING *name_arg, List<Key_part_spec> *cols,
const LEX_CSTRING *ref_db_arg, const LEX_CSTRING *ref_table_arg,
List<Key_part_spec> *ref_cols,
- uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg,
+ enum_fk_option delete_opt_arg, enum_fk_option update_opt_arg,
+ fk_match_opt match_opt_arg,
DDL_options ddl_options)
:Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL,
ddl_options),
@@ -370,8 +393,9 @@ public:
typedef struct st_mysql_lock
{
TABLE **table;
- uint table_count,lock_count;
THR_LOCK_DATA **locks;
+ uint table_count,lock_count;
+ uint flags;
} MYSQL_LOCK;
@@ -439,7 +463,7 @@ typedef enum enum_diag_condition_item_name
Name of each diagnostic condition item.
This array is indexed by Diag_condition_item_name.
*/
-extern const LEX_STRING Diag_condition_item_names[];
+extern const LEX_CSTRING Diag_condition_item_names[];
/**
These states are bit coded with HARD. For each state there must be a pair
@@ -701,7 +725,10 @@ typedef struct system_variables
uint idle_write_transaction_timeout;
uint column_compression_threshold;
uint column_compression_zlib_level;
- ulong in_subquery_conversion_threshold;
+ uint in_subquery_conversion_threshold;
+
+ vers_asof_timestamp_t vers_asof_timestamp;
+ ulong vers_alter_history;
} SV;
/**
@@ -767,7 +794,6 @@ typedef struct system_status_var
ulong ha_savepoint_rollback_count;
ulong ha_external_lock_count;
- ulong net_big_packet_count;
ulong opened_tables;
ulong opened_shares;
ulong opened_views; /* +1 opening a view */
@@ -791,6 +817,7 @@ typedef struct system_status_var
ulong feature_dynamic_columns; /* +1 when creating a dynamic column */
ulong feature_fulltext; /* +1 when MATCH is used */
ulong feature_gis; /* +1 opening a table with GIS features */
+ ulong feature_invisible_columns; /* +1 opening a table with invisible column */
ulong feature_locale; /* +1 when LOCALE is set */
ulong feature_subquery; /* +1 when subqueries are used */
ulong feature_timezone; /* +1 when XPATH is used */
@@ -828,6 +855,7 @@ typedef struct system_status_var
ulonglong table_open_cache_overflows;
double last_query_cost;
double cpu_time, busy_time;
+ uint32 threads_running;
/* Don't initialize */
/* Memory used for thread local storage */
int64 max_local_memory_used;
@@ -942,6 +970,11 @@ public:
enum_state state;
+protected:
+ friend class sp_head;
+ bool is_stored_procedure;
+
+public:
/* We build without RTTI, so dynamic_cast can't be used. */
enum Type
{
@@ -949,7 +982,8 @@ public:
};
Query_arena(MEM_ROOT *mem_root_arg, enum enum_state state_arg) :
- free_list(0), mem_root(mem_root_arg), state(state_arg)
+ free_list(0), mem_root(mem_root_arg), state(state_arg),
+ is_stored_procedure(state_arg == STMT_INITIALIZED_FOR_SP ? true : false)
{ INIT_ARENA_DBUG_INFO; }
/*
This constructor is used only when Query_arena is created as
@@ -969,6 +1003,8 @@ public:
{ return state == STMT_PREPARED || state == STMT_EXECUTED; }
inline bool is_conventional() const
{ return state == STMT_CONVENTIONAL_EXECUTION; }
+ inline bool is_sp_execute() const
+ { return is_stored_procedure; }
inline void* alloc(size_t size) { return alloc_root(mem_root,size); }
inline void* calloc(size_t size)
@@ -984,7 +1020,7 @@ public:
{ return strmake_root(mem_root,str,size); }
inline void *memdup(const void *str, size_t size)
{ return memdup_root(mem_root,str,size); }
- inline void *memdup_w_gap(const void *str, size_t size, uint gap)
+ inline void *memdup_w_gap(const void *str, size_t size, size_t gap)
{
void *ptr;
if ((ptr= alloc_root(mem_root,size+gap)))
@@ -1013,6 +1049,22 @@ public:
};
+class Query_arena_stmt
+{
+ THD *thd;
+ Query_arena backup;
+ Query_arena *arena;
+
+public:
+ Query_arena_stmt(THD *_thd);
+ ~Query_arena_stmt();
+ bool arena_replaced()
+ {
+ return arena != NULL;
+ }
+};
+
+
class Server_side_cursor;
/**
@@ -1042,22 +1094,26 @@ public:
*/
ulong id;
- /*
- MARK_COLUMNS_NONE: Means mark_used_colums is not set and no indicator to
- handler of fields used is set
- MARK_COLUMNS_READ: Means a bit in read set is set to inform handler
- that the field is to be read. If field list contains
- duplicates, then thd->dup_field is set to point
- to the last found duplicate.
- MARK_COLUMNS_WRITE: Means a bit is set in write set to inform handler
- that it needs to update this field in write_row
- and update_row.
- */
- enum enum_mark_columns mark_used_columns;
+ enum enum_column_usage column_usage;
LEX_CSTRING name; /* name for named prepared statements */
LEX *lex; // parse tree descriptor
/*
+ LEX which represents current statement (conventional, SP or PS)
+
+ For example during view parsing THD::lex will point to the views LEX and
+ THD::stmt_lex will point to LEX of the statement where the view will be
+ included
+
+ Currently it is used to have always correct select numbering inside
+ statement (LEX::current_select_number) without storing and restoring a
+ global counter which was THD::select_number.
+
+ TODO: make some unified statement representation (now SP has different)
+ to store such data like LEX::current_select_number.
+ */
+ LEX *stmt_lex;
+ /*
Points to the query associated with this statement. It's const, but
we need to declare it char * because all table handlers are written
in C and need to point to it.
@@ -1107,18 +1163,13 @@ public:
/**
Name of the current (default) database.
- If there is the current (default) database, "db" contains its name. If
- there is no current (default) database, "db" is NULL and "db_length" is
- 0. In other words, "db", "db_length" must either be NULL, or contain a
+ If there is the current (default) database, "db.str" contains its name. If
+ there is no current (default) database, "db.str" is NULL and "db.length" is
+ 0. In other words, db must either be NULL, or contain a
valid database name.
-
- @note this attribute is set and alloced by the slave SQL thread (for
- the THD of that thread); that thread is (and must remain, for now) the
- only responsible for freeing this member.
*/
- char *db;
- size_t db_length;
+ LEX_CSTRING db;
/* This is set to 1 of last call to send_result_to_client() was ok */
my_bool query_cache_is_applicable;
@@ -1214,6 +1265,29 @@ typedef struct st_xid_state {
/* Error reported by the Resource Manager (RM) to the Transaction Manager. */
uint rm_error;
XID_cache_element *xid_cache_element;
+
+ /**
+ Check that XA transaction has an uncommitted work. Report an error
+ to the user in case when there is an uncommitted work for XA transaction.
+
+ @return result of check
+ @retval false XA transaction is NOT in state IDLE, PREPARED
+ or ROLLBACK_ONLY.
+ @retval true XA transaction is in state IDLE or PREPARED
+ or ROLLBACK_ONLY.
+ */
+
+ bool check_has_uncommitted_xa() const
+ {
+ if (xa_state == XA_IDLE ||
+ xa_state == XA_PREPARED ||
+ xa_state == XA_ROLLBACK_ONLY)
+ {
+ my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]);
+ return true;
+ }
+ return false;
+ }
} XID_STATE;
void xid_cache_init(void);
@@ -1287,7 +1361,40 @@ public:
*/
struct Item_change_record;
-typedef I_List<Item_change_record> Item_change_list;
+class Item_change_list
+{
+ I_List<Item_change_record> change_list;
+public:
+ void nocheck_register_item_tree_change(Item **place, Item *old_value,
+ MEM_ROOT *runtime_memroot);
+ void check_and_register_item_tree_change(Item **place, Item **new_value,
+ MEM_ROOT *runtime_memroot);
+ void rollback_item_tree_changes();
+ void move_elements_to(Item_change_list *to)
+ {
+ change_list.move_elements_to(&to->change_list);
+ }
+ bool is_empty() { return change_list.is_empty(); }
+};
+
+
+class Item_change_list_savepoint: public Item_change_list
+{
+public:
+ Item_change_list_savepoint(Item_change_list *list)
+ {
+ list->move_elements_to(this);
+ }
+ void rollback(Item_change_list *list)
+ {
+ list->rollback_item_tree_changes();
+ move_elements_to(list);
+ }
+ ~Item_change_list_savepoint()
+ {
+ DBUG_ASSERT(is_empty());
+ }
+};
/**
@@ -1564,7 +1671,8 @@ enum enum_thread_type
SYSTEM_THREAD_EVENT_WORKER= 16,
SYSTEM_THREAD_BINLOG_BACKGROUND= 32,
SYSTEM_THREAD_SLAVE_BACKGROUND= 64,
- SYSTEM_THREAD_GENERIC= 128
+ SYSTEM_THREAD_GENERIC= 128,
+ SYSTEM_THREAD_SEMISYNC_MASTER_BACKGROUND= 256
};
inline char const *
@@ -1580,6 +1688,7 @@ show_system_thread(enum_thread_type thread)
RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_SCHEDULER);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_WORKER);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_SLAVE_BACKGROUND);
+ RETURN_NAME_AS_STRING(SYSTEM_THREAD_SEMISYNC_MASTER_BACKGROUND);
default:
sprintf(buf, "<UNKNOWN SYSTEM THREAD: %d>", thread);
return buf;
@@ -1760,8 +1869,9 @@ private:
class Locked_tables_list
{
-private:
+public:
MEM_ROOT m_locked_tables_root;
+private:
TABLE_LIST *m_locked_tables;
TABLE_LIST **m_locked_tables_last;
/** An auxiliary array used only in reopen_tables(). */
@@ -1780,7 +1890,8 @@ public:
m_reopen_array(NULL),
m_locked_tables_count(0)
{
- init_sql_alloc(&m_locked_tables_root, MEM_ROOT_BLOCK_SIZE, 0,
+ init_sql_alloc(&m_locked_tables_root, "Locked_tables_list",
+ MEM_ROOT_BLOCK_SIZE, 0,
MYF(MY_THREAD_SPECIFIC));
}
void unlock_locked_tables(THD *thd);
@@ -2043,19 +2154,23 @@ struct wait_for_commit
Structure to store the start time for a query
*/
-typedef struct
+struct QUERY_START_TIME_INFO
{
my_time_t start_time;
- ulong start_time_sec_part;
+ ulong start_time_sec_part;
ulonglong start_utime, utime_after_lock;
-} QUERY_START_TIME_INFO;
-extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
+ void backup_query_start_time(QUERY_START_TIME_INFO *backup)
+ {
+ *backup= *this;
+ }
+ void restore_query_start_time(QUERY_START_TIME_INFO *backup)
+ {
+ *this= *backup;
+ }
+};
-class THD;
-#ifndef DBUG_OFF
-void dbug_serve_apcs(THD *thd, int n_calls);
-#endif
+extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
/**
@class THD
@@ -2064,8 +2179,17 @@ void dbug_serve_apcs(THD *thd, int n_calls);
*/
class THD :public Statement,
+ /*
+ This is to track items changed during execution of a prepared
+ statement/stored procedure. It's created by
+ nocheck_register_item_tree_change() in memory root of THD,
+ and freed in rollback_item_tree_changes().
+ For conventional execution it's always empty.
+ */
+ public Item_change_list,
public MDL_context_owner,
- public Open_tables_state
+ public Open_tables_state,
+ public QUERY_START_TIME_INFO
{
private:
inline bool is_stmt_prepare() const
@@ -2158,12 +2282,16 @@ public:
Protects THD data accessed from other threads:
- thd->query and thd->query_length (used by SHOW ENGINE
INNODB STATUS and SHOW PROCESSLIST
- - thd->db and thd->db_length (used in SHOW PROCESSLIST)
- - thd->mysys_var (used by KILL statement and shutdown).
+ - thd->db (used in SHOW PROCESSLIST)
Is locked when THD is deleted.
*/
mysql_mutex_t LOCK_thd_data;
- /* Protect kill information */
+ /*
+ Protects:
+ - kill information
+ - mysys_var (used by KILL statement and shutdown).
+ - Also ensures that THD is not deleted while mutex is hold
+ */
mysql_mutex_t LOCK_thd_kill;
/* all prepared statements and cursors of this connection */
@@ -2257,7 +2385,8 @@ public:
/* Needed by MariaDB semi sync replication */
Trans_binlog_info *semisync_info;
-
+ /* If this is a semisync slave connection. */
+ bool semi_sync_slave;
ulonglong client_capabilities; /* What the client supports */
ulong max_client_packet_length;
@@ -2285,12 +2414,12 @@ public:
uint32 file_id; // for LOAD DATA INFILE
/* remote (peer) port */
uint16 peer_port;
- my_time_t start_time; // start_time and its sec_part
- ulong start_time_sec_part; // are almost always used separately
my_hrtime_t user_time;
// track down slow pthread_create
ulonglong prior_thr_create_utime, thr_create_utime;
- ulonglong start_utime, utime_after_lock, utime_after_query;
+ ulonglong utime_after_query;
+ my_time_t system_time;
+ ulong system_time_sec_part;
// Process indicator
struct {
@@ -2527,7 +2656,8 @@ public:
{
bzero((char*)this, sizeof(*this));
xid_state.xid.null();
- init_sql_alloc(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0,
+ init_sql_alloc(&mem_root, "THD::transactions",
+ ALLOC_ROOT_MIN_BLOCK_SIZE, 0,
MYF(MY_THREAD_SPECIFIC));
}
} transaction;
@@ -2539,14 +2669,6 @@ public:
#ifdef SIGNAL_WITH_VIO_CLOSE
Vio* active_vio;
#endif
- /*
- This is to track items changed during execution of a prepared
- statement/stored procedure. It's created by
- nocheck_register_item_tree_change() in memory root of THD, and freed in
- rollback_item_tree_changes(). For conventional execution it's always
- empty.
- */
- Item_change_list change_list;
/*
A permanent memory area of the statement. For conventional
@@ -2884,7 +3006,6 @@ public:
uint tmp_table, global_disable_checkpoint;
uint server_status,open_options;
enum enum_thread_type system_thread;
- uint select_number; //number of select (used for EXPLAIN)
/*
Current or next transaction isolation level.
When a connection is established, the value is taken from
@@ -3143,11 +3264,20 @@ public:
/* Debug Sync facility. See debug_sync.cc. */
struct st_debug_sync_control *debug_sync_control;
#endif /* defined(ENABLED_DEBUG_SYNC) */
- THD(my_thread_id id, bool is_wsrep_applier= false);
+ /**
+ @param id thread identifier
+ @param is_wsrep_applier thread type
+ @param skip_lock instruct whether @c LOCK_global_system_variables
+ is already locked, to not acquire it then.
+ */
+ THD(my_thread_id id, bool is_wsrep_applier= false, bool skip_lock= false);
~THD();
-
- void init(void);
+ /**
+ @param skip_lock instruct whether @c LOCK_global_system_variables
+ is already locked, to not acquire it then.
+ */
+ void init(bool skip_lock= false);
/*
Initialize memory roots necessary for query processing and (!)
pre-allocate memory for it. We can't do that in THD constructor because
@@ -3182,7 +3312,13 @@ public:
}
void close_active_vio();
#endif
- void awake(killed_state state_to_set);
+ void awake_no_mutex(killed_state state_to_set);
+ void awake(killed_state state_to_set)
+ {
+ mysql_mutex_lock(&LOCK_thd_kill);
+ awake_no_mutex(state_to_set);
+ mysql_mutex_unlock(&LOCK_thd_kill);
+ }
/** Disconnect the associated communication endpoint. */
void disconnect();
@@ -3292,27 +3428,50 @@ public:
inline my_time_t query_start() { query_start_used=1; return start_time; }
inline ulong query_start_sec_part()
{ query_start_sec_part_used=1; return start_time_sec_part; }
- inline void set_current_time()
+ MYSQL_TIME query_start_TIME();
+
+private:
+ bool system_time_ge(my_time_t secs, ulong usecs)
+ {
+ return (system_time == secs && system_time_sec_part >= usecs) ||
+ system_time > secs;
+ }
+
+ void set_system_time()
{
my_hrtime_t hrtime= my_hrtime();
- start_time= hrtime_to_my_time(hrtime);
- start_time_sec_part= hrtime_sec_part(hrtime);
-#ifdef HAVE_PSI_THREAD_INTERFACE
- PSI_THREAD_CALL(set_thread_start_time)(start_time);
-#endif
+ my_time_t secs= hrtime_to_my_time(hrtime);
+ ulong usecs= hrtime_sec_part(hrtime);
+ if (system_time_ge(secs, usecs))
+ {
+ if (++system_time_sec_part == HRTIME_RESOLUTION)
+ {
+ ++system_time;
+ system_time_sec_part= 0;
+ }
+ }
+ else
+ {
+ system_time= secs;
+ system_time_sec_part= usecs;
+ }
}
+
+public:
inline void set_start_time()
{
+ set_system_time();
if (user_time.val)
{
start_time= hrtime_to_my_time(user_time);
start_time_sec_part= hrtime_sec_part(user_time);
-#ifdef HAVE_PSI_THREAD_INTERFACE
- PSI_THREAD_CALL(set_thread_start_time)(start_time);
-#endif
}
else
- set_current_time();
+ {
+ start_time= system_time;
+ start_time_sec_part= system_time_sec_part;
+ }
+ PSI_CALL_set_thread_start_time(start_time);
}
inline void set_time()
{
@@ -3335,20 +3494,6 @@ public:
MYSQL_SET_STATEMENT_LOCK_TIME(m_statement_psi,
(utime_after_lock - start_utime));
}
- void get_time(QUERY_START_TIME_INFO *time_info)
- {
- time_info->start_time= start_time;
- time_info->start_time_sec_part= start_time_sec_part;
- time_info->start_utime= start_utime;
- time_info->utime_after_lock= utime_after_lock;
- }
- void set_time(QUERY_START_TIME_INFO *time_info)
- {
- start_time= time_info->start_time;
- start_time_sec_part= time_info->start_time_sec_part;
- start_utime= time_info->start_utime;
- utime_after_lock= time_info->utime_after_lock;
- }
ulonglong current_utime() { return microsecond_interval_timer(); }
/* Tell SHOW PROCESSLIST to show time from this point */
@@ -3446,12 +3591,12 @@ public:
{
return !stmt_arena->is_stmt_prepare();
}
- inline void* trans_alloc(unsigned int size)
+ inline void* trans_alloc(size_t size)
{
return alloc_root(&transaction.mem_root,size);
}
- LEX_STRING *make_lex_string(LEX_STRING *lex_str, const char* str, uint length)
+ LEX_STRING *make_lex_string(LEX_STRING *lex_str, const char* str, size_t length)
{
if (!(lex_str->str= strmake_root(mem_root, str, length)))
{
@@ -3461,7 +3606,7 @@ public:
lex_str->length= length;
return lex_str;
}
- LEX_CSTRING *make_lex_string(LEX_CSTRING *lex_str, const char* str, uint length)
+ LEX_CSTRING *make_lex_string(LEX_CSTRING *lex_str, const char* str, size_t length)
{
if (!(lex_str->str= strmake_root(mem_root, str, length)))
{
@@ -3472,22 +3617,7 @@ public:
return lex_str;
}
- LEX_STRING *make_lex_string(const char* str, uint length)
- {
- LEX_STRING *lex_str;
- char *tmp;
- if (!(lex_str= (LEX_STRING *) alloc_root(mem_root, sizeof(LEX_STRING) +
- length+1)))
- return 0;
- tmp= (char*) (lex_str+1);
- lex_str->str= tmp;
- memcpy(tmp, str, length);
- tmp[length]= 0;
- lex_str->length= length;
- return lex_str;
- }
-
- LEX_CSTRING *make_clex_string(const char* str, uint length)
+ LEX_CSTRING *make_clex_string(const char* str, size_t length)
{
LEX_CSTRING *lex_str;
char *tmp;
@@ -3503,7 +3633,7 @@ public:
}
// Allocate LEX_STRING for character set conversion
- bool alloc_lex_string(LEX_STRING *dst, uint length)
+ bool alloc_lex_string(LEX_STRING *dst, size_t length)
{
if ((dst->str= (char*) alloc(length)))
return false;
@@ -3511,7 +3641,7 @@ public:
return true; // EOM
}
bool convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
- const char *from, uint from_length,
+ const char *from, size_t from_length,
CHARSET_INFO *from_cs);
/*
Convert a strings between character sets.
@@ -3519,7 +3649,7 @@ public:
dstcs and srccs cannot be &my_charset_bin.
*/
bool convert_fix(CHARSET_INFO *dstcs, LEX_STRING *dst,
- CHARSET_INFO *srccs, const char *src, uint src_length,
+ CHARSET_INFO *srccs, const char *src, size_t src_length,
String_copier *status);
/*
@@ -3528,7 +3658,7 @@ public:
*/
bool convert_with_error(CHARSET_INFO *dstcs, LEX_STRING *dst,
CHARSET_INFO *srccs,
- const char *src, uint src_length);
+ const char *src, size_t src_length);
/*
If either "dstcs" or "srccs" is &my_charset_bin,
@@ -3536,7 +3666,7 @@ public:
Otherwise, performs Unicode conversion using convert_fix().
*/
bool copy_fix(CHARSET_INFO *dstcs, LEX_STRING *dst,
- CHARSET_INFO *srccs, const char *src, uint src_length,
+ CHARSET_INFO *srccs, const char *src, size_t src_length,
String_copier *status);
/*
@@ -3544,7 +3674,7 @@ public:
in case of bad byte sequences or Unicode conversion problems.
*/
bool copy_with_error(CHARSET_INFO *dstcs, LEX_STRING *dst,
- CHARSET_INFO *srccs, const char *src, uint src_length);
+ CHARSET_INFO *srccs, const char *src, size_t src_length);
bool convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs);
@@ -3566,8 +3696,8 @@ public:
CHARSET_INFO *cs);
Item *make_string_literal_concat(Item *item1, const LEX_CSTRING &str);
void add_changed_table(TABLE *table);
- void add_changed_table(const char *key, long key_length);
- CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length);
+ void add_changed_table(const char *key, size_t key_length);
+ CHANGED_TABLE_LIST * changed_table_dup(const char *key, size_t key_length);
int send_explain_fields(select_result *result, uint8 explain_flags,
bool is_analyze);
void make_explain_field_list(List<Item> &field_list, uint8 explain_flags,
@@ -3689,10 +3819,14 @@ public:
void change_item_tree(Item **place, Item *new_value)
{
+ DBUG_ENTER("THD::change_item_tree");
+ DBUG_PRINT("enter", ("Register: %p (%p) <- %p",
+ *place, place, new_value));
/* TODO: check for OOM condition here */
if (!stmt_arena->is_conventional())
nocheck_register_item_tree_change(place, *place, mem_root);
*place= new_value;
+ DBUG_VOID_RETURN;
}
/**
Make change in item tree after checking whether it needs registering
@@ -3714,11 +3848,6 @@ public:
*/
memcpy((char*) place, new_value, sizeof(*new_value));
}
- void nocheck_register_item_tree_change(Item **place, Item *old_value,
- MEM_ROOT *runtime_memroot);
- void check_and_register_item_tree_change(Item **place, Item **new_value,
- MEM_ROOT *runtime_memroot);
- void rollback_item_tree_changes();
/*
Cleanup statement parse state (parse tree, lex) and execution
@@ -3934,74 +4063,33 @@ public:
@retval FALSE Success
@retval TRUE Out-of-memory error
*/
- bool set_db(const char *new_db, size_t new_db_len)
- {
- /*
- Acquiring mutex LOCK_thd_data as we either free the memory allocated
- for the database and reallocating the memory for the new db or memcpy
- the new_db to the db.
- */
- mysql_mutex_lock(&LOCK_thd_data);
- /* Do not reallocate memory if current chunk is big enough. */
- if (db && new_db && db_length >= new_db_len)
- memcpy(db, new_db, new_db_len+1);
- else
- {
- my_free(db);
- if (new_db)
- db= my_strndup(new_db, new_db_len, MYF(MY_WME | ME_FATALERROR));
- else
- db= NULL;
- }
- db_length= db ? new_db_len : 0;
- bool result= new_db && !db;
- mysql_mutex_unlock(&LOCK_thd_data);
-#ifdef HAVE_PSI_THREAD_INTERFACE
- if (result)
- PSI_THREAD_CALL(set_thread_db)(new_db, (int) new_db_len);
-#endif
- return result;
- }
+ bool set_db(const LEX_CSTRING *new_db);
- /**
- Set the current database; use shallow copy of C-string.
-
- @param new_db a pointer to the new database name.
- @param new_db_len length of the new database name.
+ /** Set the current database, without copying */
+ void reset_db(const LEX_CSTRING *new_db);
- @note This operation just sets {db, db_length}. Switching the current
- database usually involves other actions, like switching other database
- attributes including security context. In the future, this operation
- will be made private and more convenient interface will be provided.
- */
- void reset_db(char *new_db, size_t new_db_len)
- {
- if (new_db != db || new_db_len != db_length)
- {
- mysql_mutex_lock(&LOCK_thd_data);
- db= new_db;
- db_length= new_db_len;
- mysql_mutex_unlock(&LOCK_thd_data);
-#ifdef HAVE_PSI_THREAD_INTERFACE
- PSI_THREAD_CALL(set_thread_db)(new_db, (int) new_db_len);
-#endif
- }
- }
/*
Copy the current database to the argument. Use the current arena to
allocate memory for a deep copy: current database may be freed after
a statement is parsed but before it's executed.
+
+ Can only be called by owner of thd (no mutex protection)
*/
- bool copy_db_to(const char **p_db, size_t *p_db_length)
+ bool copy_db_to(LEX_CSTRING *to)
{
- if (db == NULL)
+ if (db.str == NULL)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
return TRUE;
}
- *p_db= strmake(db, db_length);
- *p_db_length= db_length;
- return FALSE;
+ to->str= strmake(db.str, db.length);
+ to->length= db.length;
+ return to->str == NULL; /* True on error */
+ }
+ /* Get db name or "". Use for printing current db */
+ const char *get_db()
+ {
+ return db.str ? db.str : "";
}
thd_scheduler event_scheduler;
@@ -4088,7 +4176,12 @@ public:
Lex_input_stream *lip= &m_parser_state->m_lip;
if (!yytext)
{
- if (!(yytext= lip->get_tok_start()))
+ if (lip->lookahead_token >= 0)
+ yytext= lip->get_tok_start_prev();
+ else
+ yytext= lip->get_tok_start();
+
+ if (!yytext)
yytext= "";
}
/* Push an error into the error stack */
@@ -4104,6 +4197,11 @@ public:
{
parse_error(ER_SYNTAX_ERROR);
}
+#ifdef mysqld_error_find_printf_error_used
+ void parse_error(const char *t)
+ {
+ }
+#endif
private:
/*
Only the implementation of the SIGNAL and RESIGNAL statements
@@ -4183,12 +4281,12 @@ public:
Assign a new value to thd->query and thd->query_id and mysys_var.
Protected with LOCK_thd_data mutex.
*/
- void set_query(char *query_arg, uint32 query_length_arg,
+ void set_query(char *query_arg, size_t query_length_arg,
CHARSET_INFO *cs_arg)
{
set_query(CSET_STRING(query_arg, query_length_arg, cs_arg));
}
- void set_query(char *query_arg, uint32 query_length_arg) /*Mutex protected*/
+ void set_query(char *query_arg, size_t query_length_arg) /*Mutex protected*/
{
set_query(CSET_STRING(query_arg, query_length_arg, charset()));
}
@@ -4198,9 +4296,7 @@ public:
set_query_inner(string_arg);
mysql_mutex_unlock(&LOCK_thd_data);
-#ifdef HAVE_PSI_THREAD_INTERFACE
- PSI_THREAD_CALL(set_thread_info)(query(), query_length());
-#endif
+ PSI_CALL_set_thread_info(query(), query_length());
}
void reset_query() /* Mutex protected */
{ set_query(CSET_STRING()); }
@@ -4258,7 +4354,7 @@ public:
{
Security_context *sctx= &main_security_ctx;
sql_print_warning(ER_THD(this, ER_NEW_ABORTING_CONNECTION),
- thread_id, (db ? db : "unconnected"),
+ thread_id, (db.str ? db.str : "unconnected"),
sctx->user ? sctx->user : "unauthenticated",
sctx->host_or_ip, reason);
}
@@ -4384,7 +4480,8 @@ public:
const char *path,
const char *db,
const char *table_name,
- bool open_in_engine);
+ bool open_in_engine,
+ bool open_internal_tables);
TABLE *find_temporary_table(const char *db, const char *table_name);
TABLE *find_temporary_table(const TABLE_LIST *tl);
@@ -4394,14 +4491,14 @@ public:
TMP_TABLE_SHARE *find_tmp_table_share(const char *db,
const char *table_name);
TMP_TABLE_SHARE *find_tmp_table_share(const TABLE_LIST *tl);
- TMP_TABLE_SHARE *find_tmp_table_share(const char *key, uint key_length);
+ TMP_TABLE_SHARE *find_tmp_table_share(const char *key, size_t key_length);
bool open_temporary_table(TABLE_LIST *tl);
bool open_temporary_tables(TABLE_LIST *tl);
bool close_temporary_tables();
- bool rename_temporary_table(TABLE *table, const char *db,
- const char *table_name);
+ bool rename_temporary_table(TABLE *table, const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name);
bool drop_temporary_table(TABLE *table, bool *is_trans, bool delete_table);
bool rm_temporary_table(handlerton *hton, const char *path);
void mark_tmp_tables_as_free_for_reuse();
@@ -4506,6 +4603,7 @@ public:
/* Handling of timeouts for commands */
thr_timer_t query_timer;
+
public:
void set_query_timer()
{
@@ -4589,7 +4687,7 @@ public:
void set_local_lex(sp_lex_local *sublex)
{
DBUG_ASSERT(lex->sphead);
- lex= sublex;
+ lex= stmt_lex= sublex;
/* Reset part of parser state which needs this. */
m_parser_state->m_yacc.reset_before_substatement();
}
@@ -4607,6 +4705,10 @@ public:
*/
bool restore_from_local_lex_to_old_lex(LEX *oldlex);
+ Item *sp_fix_func_item(Item **it_addr);
+ Item *sp_prepare_func_item(Item **it_addr, uint cols= 1);
+ bool sp_eval_expr(Field *result_field, Item **expr_item_ptr);
+
inline void prepare_logs_for_admin_command()
{
enable_slow_log&= !MY_TEST(variables.log_slow_disabled_statements &
@@ -5003,6 +5105,7 @@ class select_insert :public select_result_interceptor {
ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not
COPY_INFO info;
bool insert_into_view;
+ bool versioned_write;
select_insert(THD *thd_arg, TABLE_LIST *table_list_par,
TABLE *table_par, List<Item> *fields_par,
List<Item> *update_fields, List<Item> *update_values,
@@ -5023,7 +5126,6 @@ class select_insert :public select_result_interceptor {
class select_create: public select_insert {
- ORDER *group;
TABLE_LIST *create_table;
Table_specification_st *create_info;
TABLE_LIST *select_tables;
@@ -5063,6 +5165,12 @@ public:
const THD *get_thd(void) { return thd; }
const HA_CREATE_INFO *get_create_info() { return create_info; };
int prepare2(void) { return 0; }
+
+private:
+ TABLE *create_table_from_items(THD *thd,
+ List<Item> *items,
+ MYSQL_LOCK **lock,
+ TABLEOP_HOOKS *hooks);
};
#include <myisam.h>
@@ -5203,10 +5311,11 @@ public:
select_unit(THD *thd_arg):
select_result_interceptor(thd_arg),
- curr_step(0), prev_step(0), curr_sel(UINT_MAX),
- step(UNION_TYPE), intersect_mark(0), write_err(0), table(0),
- records(0)
- { tmp_table_param.init(); }
+ intersect_mark(0), table(0)
+ {
+ init();
+ tmp_table_param.init();
+ }
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
/**
Do prepare() and prepare2() if they have been postponed until
@@ -5224,12 +5333,20 @@ public:
void cleanup();
virtual bool create_result_table(THD *thd, List<Item> *column_types,
bool is_distinct, ulonglong options,
- const char *alias,
+ const LEX_CSTRING *alias,
bool bit_fields_as_long,
bool create_table,
bool keep_row_order,
uint hidden);
TMP_TABLE_PARAM *get_tmp_table_param() { return &tmp_table_param; }
+ void init()
+ {
+ curr_step= prev_step= 0;
+ curr_sel= UINT_MAX;
+ step= UNION_TYPE;
+ write_err= 0;
+ records= 0;
+ }
void change_select();
};
@@ -5250,7 +5367,7 @@ class select_union_recursive :public select_unit
int send_data(List<Item> &items);
bool create_result_table(THD *thd, List<Item> *column_types,
bool is_distinct, ulonglong options,
- const char *alias,
+ const LEX_CSTRING *alias,
bool bit_fields_as_long,
bool create_table,
bool keep_row_order,
@@ -5417,7 +5534,7 @@ public:
{ tmp_table_param.init(); }
bool create_result_table(THD *thd, List<Item> *column_types,
bool is_distinct, ulonglong options,
- const char *alias,
+ const LEX_CSTRING *alias,
bool bit_fields_as_long,
bool create_table,
bool keep_row_order,
@@ -5474,8 +5591,6 @@ public:
};
-
-
/*
Optimizer and executor structure for the materialized semi-join info. This
structure contains
@@ -5636,7 +5751,7 @@ class user_var_entry
user_var_entry() {} /* Remove gcc warning */
LEX_CSTRING name;
char *value;
- ulong length;
+ size_t length;
query_id_t update_query_id, used_query_id;
Item_result type;
bool unsigned_flag;
@@ -5691,7 +5806,7 @@ class multi_update :public select_result_interceptor
{
TABLE_LIST *all_tables; /* query/update command tables */
List<TABLE_LIST> *leaves; /* list of leves of join table tree */
- TABLE_LIST *update_tables, *table_being_updated;
+ TABLE_LIST *update_tables;
TABLE **tmp_tables, *main_table, *table_to_update;
TMP_TABLE_PARAM *tmp_table_param;
ha_rows updated, found;
@@ -5717,6 +5832,12 @@ class multi_update :public select_result_interceptor
/* Need this to protect against multiple prepare() calls */
bool prepared;
+
+ // For System Versioning (may need to insert new fields to a table).
+ ha_rows updated_sys_ver;
+
+ bool has_vers_fields;
+
public:
multi_update(THD *thd_arg, TABLE_LIST *ut, List<TABLE_LIST> *leaves_list,
List<Item> *fields, List<Item> *values,
@@ -6113,7 +6234,7 @@ void thd_exit_cond(MYSQL_THD thd, const PSI_stage_info *stage,
#define THD_EXIT_COND(P1, P2) \
thd_exit_cond(P1, P2, __func__, __FILE__, __LINE__)
-inline bool binlog_should_compress(ulong len)
+inline bool binlog_should_compress(size_t len)
{
return opt_bin_log_compress &&
len >= opt_bin_log_compress_min_len;
@@ -6214,26 +6335,6 @@ public:
}
};
-/* Functions to compare if two lex strings are equal */
-inline bool lex_string_cmp(CHARSET_INFO *charset,
- const LEX_CSTRING *a,
- const LEX_CSTRING *b)
-{
- return my_strcasecmp(charset, a->str, b->str);
-}
-
-/*
- Compare if two LEX_CSTRING are equal. Assumption is that
- character set is ASCII (like for plugin names)
-*/
-inline bool lex_string_eq(const LEX_CSTRING *a,
- const LEX_CSTRING *b)
-{
- if (a->length != b->length)
- return 1; /* Different */
- return strcasecmp(a->str, b->str) != 0;
-}
-
class Type_holder: public Sql_alloc,
public Item_args,
public Type_handler_hybrid_field_type,
@@ -6292,6 +6393,70 @@ public:
};
-#endif /* MYSQL_SERVER */
+/*
+ A helper class to set THD flags to emit warnings/errors in case of
+ overflow/type errors during assigning values into the SP variable fields.
+ Saves original flags values in constructor.
+ Restores original flags in destructor.
+*/
+class Sp_eval_expr_state
+{
+ THD *m_thd;
+ enum_check_fields m_count_cuted_fields;
+ bool m_abort_on_warning;
+ bool m_stmt_modified_non_trans_table;
+ void start()
+ {
+ m_thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
+ m_thd->abort_on_warning= m_thd->is_strict_mode();
+ m_thd->transaction.stmt.modified_non_trans_table= false;
+ }
+ void stop()
+ {
+ m_thd->count_cuted_fields= m_count_cuted_fields;
+ m_thd->abort_on_warning= m_abort_on_warning;
+ m_thd->transaction.stmt.modified_non_trans_table=
+ m_stmt_modified_non_trans_table;
+ }
+public:
+ Sp_eval_expr_state(THD *thd)
+ :m_thd(thd),
+ m_count_cuted_fields(thd->count_cuted_fields),
+ m_abort_on_warning(thd->abort_on_warning),
+ m_stmt_modified_non_trans_table(thd->transaction.stmt.
+ modified_non_trans_table)
+ {
+ start();
+ }
+ ~Sp_eval_expr_state()
+ {
+ stop();
+ }
+};
+
+#ifndef DBUG_OFF
+void dbug_serve_apcs(THD *thd, int n_calls);
+#endif
+
+class ScopedStatementReplication
+{
+public:
+ ScopedStatementReplication(THD *thd) : thd(thd)
+ {
+ if (thd)
+ saved_binlog_format= thd->set_current_stmt_binlog_format_stmt();
+ }
+ ~ScopedStatementReplication()
+ {
+ if (thd)
+ thd->restore_stmt_binlog_format(saved_binlog_format);
+ }
+
+private:
+ enum_binlog_format saved_binlog_format;
+ THD *thd;
+};
+
+#endif /* MYSQL_SERVER */
#endif /* SQL_CLASS_INCLUDED */
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index e428d969db0..558d11eca8c 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -21,6 +21,7 @@
*/
#include "mariadb.h"
+#include "mysqld.h"
#include "sql_priv.h"
#ifndef __WIN__
#include <netdb.h> // getservbyname, servent
@@ -85,7 +86,7 @@ int get_or_create_user_conn(THD *thd, const char *user,
uc->user=(char*) (uc+1);
memcpy(uc->user,temp_user,temp_len+1);
uc->host= uc->user + user_len + 1;
- uc->len= temp_len;
+ uc->len= (uint)temp_len;
uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0;
uc->user_resources= *mqh;
uc->reset_utime= thd->thr_create_utime;
@@ -316,13 +317,9 @@ extern "C" void free_user(struct user_conn *uc)
void init_max_user_conn(void)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (my_hash_init(&hash_user_connections,system_charset_info,max_connections,
- 0,0, (my_hash_get_key) get_key_conn,
- (my_hash_free_key) free_user, 0))
- {
- sql_print_error("Initializing hash_user_connections failed.");
- exit(1);
- }
+ my_hash_init(&hash_user_connections, system_charset_info, max_connections,
+ 0, 0, (my_hash_get_key) get_key_conn,
+ (my_hash_free_key) free_user, 0);
#endif
}
@@ -342,7 +339,7 @@ void reset_mqh(LEX_USER *lu, bool get_them= 0)
if (lu) // for GRANT
{
USER_CONN *uc;
- uint temp_len=lu->user.length+lu->host.length+2;
+ size_t temp_len=lu->user.length+lu->host.length+2;
char temp_user[USER_HOST_BUFF_SIZE];
memcpy(temp_user,lu->user.str,lu->user.length);
@@ -448,7 +445,7 @@ void init_user_stats(USER_STATS *user_stats,
user_length= MY_MIN(user_length, sizeof(user_stats->user)-1);
memcpy(user_stats->user, user, user_length);
user_stats->user[user_length]= 0;
- user_stats->user_name_length= user_length;
+ user_stats->user_name_length= (uint)user_length;
strmake_buf(user_stats->priv_user, priv_user);
user_stats->total_connections= total_connections;
@@ -481,24 +478,16 @@ void init_user_stats(USER_STATS *user_stats,
void init_global_user_stats(void)
{
- if (my_hash_init(&global_user_stats, system_charset_info, max_connections,
- 0, 0, (my_hash_get_key) get_key_user_stats,
- (my_hash_free_key)free_user_stats, 0))
- {
- sql_print_error("Initializing global_user_stats failed.");
- exit(1);
- }
+ my_hash_init(&global_user_stats, system_charset_info, max_connections,
+ 0, 0, (my_hash_get_key) get_key_user_stats,
+ (my_hash_free_key) free_user_stats, 0);
}
void init_global_client_stats(void)
{
- if (my_hash_init(&global_client_stats, system_charset_info, max_connections,
- 0, 0, (my_hash_get_key) get_key_user_stats,
- (my_hash_free_key)free_user_stats, 0))
- {
- sql_print_error("Initializing global_client_stats failed.");
- exit(1);
- }
+ my_hash_init(&global_client_stats, system_charset_info, max_connections,
+ 0, 0, (my_hash_get_key) get_key_user_stats,
+ (my_hash_free_key) free_user_stats, 0);
}
extern "C" uchar *get_key_table_stats(TABLE_STATS *table_stats, size_t *length,
@@ -515,12 +504,9 @@ extern "C" void free_table_stats(TABLE_STATS* table_stats)
void init_global_table_stats(void)
{
- if (my_hash_init(&global_table_stats, system_charset_info, max_connections,
- 0, 0, (my_hash_get_key) get_key_table_stats,
- (my_hash_free_key)free_table_stats, 0)) {
- sql_print_error("Initializing global_table_stats failed.");
- exit(1);
- }
+ my_hash_init(&global_table_stats, system_charset_info, max_connections,
+ 0, 0, (my_hash_get_key) get_key_table_stats,
+ (my_hash_free_key) free_table_stats, 0);
}
extern "C" uchar *get_key_index_stats(INDEX_STATS *index_stats, size_t *length,
@@ -537,13 +523,9 @@ extern "C" void free_index_stats(INDEX_STATS* index_stats)
void init_global_index_stats(void)
{
- if (my_hash_init(&global_index_stats, system_charset_info, max_connections,
- 0, 0, (my_hash_get_key) get_key_index_stats,
- (my_hash_free_key)free_index_stats, 0))
- {
- sql_print_error("Initializing global_index_stats failed.");
- exit(1);
- }
+ my_hash_init(&global_index_stats, system_charset_info, max_connections,
+ 0, 0, (my_hash_get_key) get_key_index_stats,
+ (my_hash_free_key) free_index_stats, 0);
}
@@ -997,7 +979,7 @@ static int check_connection(THD *thd)
struct in_addr *ip4= &((struct sockaddr_in *) sa)->sin_addr;
/* See RFC 5737, 192.0.2.0/24 is reserved. */
const char* fake= "192.0.2.4";
- ip4->s_addr= inet_addr(fake);
+ inet_pton(AF_INET,fake, ip4);
strcpy(ip, fake);
peer_rc= 0;
}
@@ -1283,7 +1265,7 @@ void prepare_new_connection_state(THD* thd)
if (packet_length != packet_error)
my_error(ER_NEW_ABORTING_CONNECTION, MYF(0),
thd->thread_id,
- thd->db ? thd->db : "unconnected",
+ thd->db.str ? thd->db.str : "unconnected",
sctx->user ? sctx->user : "unauthenticated",
sctx->host_or_ip, "init_connect command failed");
thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
diff --git a/sql/sql_const.h b/sql/sql_const.h
index 007b7faeebb..65742235bee 100644
--- a/sql/sql_const.h
+++ b/sql/sql_const.h
@@ -231,6 +231,7 @@
*/
#define HEAP_TEMPTABLE_LOOKUP_COST 0.05
#define DISK_TEMPTABLE_LOOKUP_COST 1.0
+#define SORT_INDEX_CMP_COST 0.02
#define MY_CHARSET_BIN_MB_MAXLEN 1
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index 487c2b3a0bb..a58a9254a82 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -240,7 +240,8 @@ With_element *With_clause::find_table_def(TABLE_LIST *table,
with_elem= with_elem->next)
{
if (my_strcasecmp(system_charset_info, with_elem->query_name->str,
- table->table_name) == 0)
+ table->table_name.str) == 0 &&
+ !table->is_fqtn)
{
table->set_derived();
return with_elem;
@@ -681,7 +682,7 @@ void With_element::move_anchors_ahead()
{
st_select_lex *next_sl;
st_select_lex *new_pos= spec->first_select();
- st_select_lex *last_sl;
+ st_select_lex *UNINIT_VAR(last_sl);
new_pos->linkage= UNION_TYPE;
for (st_select_lex *sl= new_pos; sl; sl= next_sl)
{
@@ -825,23 +826,31 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
TABLE_LIST *spec_tables_tail;
st_select_lex *with_select;
- if (parser_state.init(thd, (char*) unparsed_spec.str, unparsed_spec.length))
+ if (parser_state.init(thd, (char*) unparsed_spec.str, (unsigned int)unparsed_spec.length))
goto err;
lex_start(thd);
with_select= &lex->select_lex;
- with_select->select_number= ++thd->select_number;
+ with_select->select_number= ++thd->stmt_lex->current_select_number;
parse_status= parse_sql(thd, &parser_state, 0);
if (parse_status)
goto err;
+
+ if (check_dependencies_in_with_clauses(lex->with_clauses_list))
+ goto err;
+
spec_tables= lex->query_tables;
spec_tables_tail= 0;
for (TABLE_LIST *tbl= spec_tables;
tbl;
tbl= tbl->next_global)
{
- tbl->grant.privilege= with_table->grant.privilege;
+ if (!tbl->derived && !tbl->schema_table &&
+ thd->open_temporary_table(tbl))
+ goto err;
spec_tables_tail= tbl;
}
+ if (check_table_access(thd, SELECT_ACL, spec_tables, FALSE, UINT_MAX, FALSE))
+ goto err;
if (spec_tables)
{
if (with_table->next_global)
@@ -917,12 +926,19 @@ With_element::rename_columns_of_derived_unit(THD *thd,
my_error(ER_WITH_COL_WRONG_LIST, MYF(0));
return true;
}
+
+ Query_arena *arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+
/* Rename the columns of the first select in the unit */
while ((item= it++, name= nm++))
{
item->set_name(thd, name->str, (uint) name->length, system_charset_info);
item->is_autogenerated_name= false;
}
+
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
}
else
make_valid_column_names(thd, select->item_list);
@@ -997,23 +1013,24 @@ bool With_element::is_anchor(st_select_lex *sel)
With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
{
- st_select_lex_unit *master_unit= NULL;
With_element *found= NULL;
- for (st_select_lex *sl= this;
- sl;
- sl= master_unit->outer_select())
+ st_select_lex_unit *master_unit;
+ st_select_lex *outer_sl;
+ for (st_select_lex *sl= this; sl; sl= outer_sl)
{
- With_element *with_elem= sl->get_with_element();
/*
If sl->master_unit() is the spec of a with element then the search for
a definition was already done by With_element::check_dependencies_in_spec
and it was unsuccesful. Yet for units cloned from the spec it has not
been done yet.
*/
- With_clause *attached_with_clause=sl->get_with_clause();
+ With_clause *attached_with_clause= sl->get_with_clause();
if (attached_with_clause &&
(found= attached_with_clause->find_table_def(table, NULL)))
break;
+ master_unit= sl->master_unit();
+ outer_sl= master_unit->outer_select();
+ With_element *with_elem= sl->get_with_element();
if (with_elem)
{
With_clause *containing_with_clause= with_elem->get_owner();
@@ -1021,9 +1038,9 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
NULL : with_elem;
if ((found= containing_with_clause->find_table_def(table, barrier)))
break;
- sl= sl->master_unit()->outer_select();
+ if (outer_sl && !outer_sl->get_with_element())
+ break;
}
- master_unit= sl->master_unit();
/* Do not look for the table's definition beyond the scope of the view */
if (master_unit->is_view)
break;
@@ -1065,7 +1082,7 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
if (!with_elem->is_referenced() || with_elem->is_recursive)
{
derived= with_elem->spec;
- if (derived->get_master() != select_lex &&
+ if (derived != select_lex->master_unit() &&
!is_with_table_recursive_reference())
{
derived->move_as_slave(select_lex);
@@ -1075,7 +1092,6 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
{
if(!(derived= with_elem->clone_parsed_spec(thd, this)))
return true;
- derived->with_element= with_elem;
}
derived->first_select()->linkage= DERIVED_TABLE_TYPE;
with_elem->inc_references();
@@ -1305,32 +1321,29 @@ bool With_element::check_unrestricted_recursive(st_select_lex *sel,
bool st_select_lex::check_subqueries_with_recursive_references()
{
- st_select_lex_unit *sl_master= master_unit();
List_iterator<TABLE_LIST> ti(leaf_tables);
TABLE_LIST *tbl;
while ((tbl= ti++))
{
- if (!(tbl->is_with_table_recursive_reference() && sl_master->item))
+ if (!(tbl->is_with_table_recursive_reference()))
continue;
- With_element *with_elem= tbl->with;
- bool check_embedding_materialized_derived= true;
+ With_element *rec_elem= tbl->with;
+ st_select_lex_unit *sl_master;
for (st_select_lex *sl= this; sl; sl= sl_master->outer_select())
- {
+ {
sl_master= sl->master_unit();
- if (with_elem->get_owner() == sl_master->with_clause)
- check_embedding_materialized_derived= false;
- if (check_embedding_materialized_derived && !sl_master->with_element &&
- sl_master->derived && sl_master->derived->is_materialized_derived())
+ if (sl_master->with_element &&
+ sl_master->with_element->get_owner() == rec_elem->get_owner())
+ break;
+ sl->uncacheable|= UNCACHEABLE_DEPENDENT;
+ sl_master->uncacheable|= UNCACHEABLE_DEPENDENT;
+ if (sl_master->derived)
+ sl_master->derived->register_as_derived_with_rec_ref(rec_elem);
+ if (sl_master->item)
{
- my_error(ER_REF_TO_RECURSIVE_WITH_TABLE_IN_DERIVED,
- MYF(0), with_elem->query_name->str);
- return true;
+ Item_subselect *subq= (Item_subselect *) (sl_master->item);
+ subq->register_as_with_rec_ref(rec_elem);
}
- if (!sl_master->item)
- continue;
- Item_subselect *subq= (Item_subselect *) sl_master->item;
- subq->with_recursive_reference= true;
- subq->register_as_with_rec_ref(tbl->with);
}
}
return false;
diff --git a/sql/sql_cte.h b/sql/sql_cte.h
index 036f0335c10..16b473f0665 100644
--- a/sql/sql_cte.h
+++ b/sql/sql_cte.h
@@ -146,7 +146,9 @@ public:
select_union_recursive *rec_result;
/* List of Item_subselects containing recursive references to this CTE */
- SQL_I_List<Item_subselect> sq_with_rec_ref;
+ SQL_I_List<Item_subselect> sq_with_rec_ref;
+ /* List of derived tables containing recursive references to this CTE */
+ SQL_I_List<TABLE_LIST> derived_with_rec_ref;
With_element(LEX_CSTRING *name,
List <LEX_CSTRING> list,
@@ -158,7 +160,7 @@ public:
query_name(name), column_list(list), spec(unit),
is_recursive(false), with_anchor(false),
level(0), rec_result(NULL)
- {}
+ { unit->with_element= this; }
bool check_dependencies_in_spec();
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 864b64a9f28..bb6bcd253f7 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -132,7 +132,7 @@ int mysql_open_cursor(THD *thd, select_result *result,
MYSQL_QUERY_EXEC_START(thd->query(),
thd->thread_id,
- (char *) (thd->db ? thd->db : ""),
+ thd->get_db(),
&thd->security_ctx->priv_user[0],
(char *) thd->security_ctx->host_or_ip,
2);
@@ -215,7 +215,7 @@ void Server_side_cursor::operator delete(void *ptr, size_t size)
MEM_ROOT own_root= *cursor->mem_root;
DBUG_ENTER("Server_side_cursor::operator delete");
- TRASH(ptr, size);
+ TRASH_FREE(ptr, size);
/*
If this cursor has never been opened mem_root is empty. Otherwise
mem_root points to the memory the cursor object was allocated in.
@@ -440,7 +440,7 @@ bool Select_materialize::send_result_set_metadata(List<Item> &list, uint flags)
if (create_result_table(unit->thd, unit->get_column_types(true),
FALSE,
thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS,
- "", FALSE, TRUE, TRUE, 0))
+ &empty_clex_str, FALSE, TRUE, TRUE, 0))
return TRUE;
materialized_cursor= new (&table->mem_root)
diff --git a/sql/sql_cursor.h b/sql/sql_cursor.h
index 6fa72a2005d..740a658b7c0 100644
--- a/sql/sql_cursor.h
+++ b/sql/sql_cursor.h
@@ -62,6 +62,7 @@ public:
virtual ~Server_side_cursor();
static void operator delete(void *ptr, size_t size);
+ static void operator delete(void *, MEM_ROOT *){}
};
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index f568db51b9c..67910a3b618 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -62,7 +62,7 @@ static void mysql_change_db_impl(THD *thd,
LEX_CSTRING *new_db_name,
ulong new_db_access,
CHARSET_INFO *new_db_charset);
-static bool mysql_rm_db_internal(THD *thd, const char *db,
+static bool mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db,
bool if_exists, bool silent);
@@ -94,12 +94,12 @@ typedef struct my_dbopt_st
*/
static inline bool
-cmp_db_names(const char *db1_name,
- const char *db2_name)
+cmp_db_names(LEX_CSTRING *db1_name, const LEX_CSTRING *db2_name)
{
- return ((!db1_name && !db2_name) ||
- (db1_name && db2_name &&
- my_strcasecmp(table_alias_charset, db1_name, db2_name) == 0));
+ return (db1_name->length == db2_name->length &&
+ (db1_name->length == 0 ||
+ my_strcasecmp(table_alias_charset,
+ db1_name->str, db2_name->str) == 0));
}
@@ -122,12 +122,12 @@ uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
Helper function to write a query to binlog used by mysql_rm_db()
*/
-static inline int write_to_binlog(THD *thd, const char *query, uint q_len,
- const char *db, uint db_len)
+static inline int write_to_binlog(THD *thd, const char *query, size_t q_len,
+ const char *db, size_t db_len)
{
Query_log_event qinfo(thd, query, q_len, FALSE, TRUE, FALSE, 0);
qinfo.db= db;
- qinfo.db_len= db_len;
+ qinfo.db_len= (uint32)db_len;
return mysql_bin_log.write(&qinfo);
}
@@ -388,7 +388,7 @@ bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create)
char buf[256];
DBUG_ENTER("load_db_opt");
bool error=1;
- uint nbytes;
+ size_t nbytes;
bzero((char*) create,sizeof(*create));
create->default_table_charset= thd->variables.collation_server;
@@ -523,7 +523,7 @@ CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
{
Schema_specification_st db_info;
- if (thd->db != NULL && strcmp(db_name, thd->db) == 0)
+ if (thd->db.str != NULL && strcmp(db_name, thd->db.str) == 0)
return thd->db_charset;
load_db_opt_by_name(thd, db_name, &db_info);
@@ -566,7 +566,7 @@ CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
*/
static int
-mysql_create_db_internal(THD *thd, const char *db,
+mysql_create_db_internal(THD *thd, const LEX_CSTRING *db,
const DDL_options_st &options,
Schema_specification_st *create_info,
bool silent)
@@ -579,18 +579,18 @@ mysql_create_db_internal(THD *thd, const char *db,
/* do not create 'information_schema' db */
if (is_infoschema_db(db))
{
- my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
+ my_error(ER_DB_CREATE_EXISTS, MYF(0), db->str);
DBUG_RETURN(-1);
}
- char db_tmp[SAFE_NAME_LEN];
- const char *dbnorm= normalize_db_name(db, db_tmp, sizeof(db_tmp));
+ char db_tmp[SAFE_NAME_LEN+1];
+ const char *dbnorm= normalize_db_name(db->str, db_tmp, sizeof(db_tmp));
if (lock_schema_name(thd, dbnorm))
DBUG_RETURN(-1);
/* Check directory */
- path_len= build_table_filename(path, sizeof(path) - 1, db, "", "", 0);
+ path_len= build_table_filename(path, sizeof(path) - 1, db->str, "", "", 0);
path[path_len-1]= 0; // Remove last '/' from path
long affected_rows= 1;
@@ -618,20 +618,20 @@ mysql_create_db_internal(THD *thd, const char *db,
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_DB_CREATE_EXISTS, ER_THD(thd, ER_DB_CREATE_EXISTS),
- db);
+ db->str);
affected_rows= 0;
goto not_silent;
}
else
{
- my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
+ my_error(ER_DB_CREATE_EXISTS, MYF(0), db->str);
DBUG_RETURN(-1);
}
if (my_mkdir(path, 0777, MYF(0)) < 0)
{
- my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
+ my_error(ER_CANT_CREATE_DB, MYF(0), db->str, my_errno);
DBUG_RETURN(-1);
}
@@ -687,8 +687,8 @@ not_silent:
USE sisyfos; # Will give error on slave since
# database does not exist.
*/
- qinfo.db = db;
- qinfo.db_len = strlen(db);
+ qinfo.db = db->str;
+ qinfo.db_len = (uint32)db->length;
/*
These DDL methods and logging are protected with the exclusive
@@ -707,7 +707,7 @@ not_silent:
/* db-name is already validated when we come here */
static bool
-mysql_alter_db_internal(THD *thd, const char *db,
+mysql_alter_db_internal(THD *thd, const LEX_CSTRING *db,
Schema_specification_st *create_info)
{
char path[FN_REFLEN+16];
@@ -715,7 +715,7 @@ mysql_alter_db_internal(THD *thd, const char *db,
int error= 0;
DBUG_ENTER("mysql_alter_db");
- if (lock_schema_name(thd, db))
+ if (lock_schema_name(thd, db->str))
DBUG_RETURN(TRUE);
/*
@@ -723,13 +723,13 @@ mysql_alter_db_internal(THD *thd, const char *db,
We pass MY_DB_OPT_FILE as "extension" to avoid
"table name to file name" encoding.
*/
- build_table_filename(path, sizeof(path) - 1, db, "", MY_DB_OPT_FILE, 0);
+ build_table_filename(path, sizeof(path) - 1, db->str, "", MY_DB_OPT_FILE, 0);
if ((error=write_db_opt(thd, path, create_info)))
goto exit;
/* Change options if current database is being altered. */
- if (thd->db && !strcmp(thd->db,db))
+ if (thd->db.str && !cmp(&thd->db, db))
{
thd->db_charset= create_info->default_table_charset ?
create_info->default_table_charset :
@@ -747,8 +747,8 @@ mysql_alter_db_internal(THD *thd, const char *db,
database" and not the threads current database, which is the
default.
*/
- qinfo.db = db;
- qinfo.db_len = strlen(db);
+ qinfo.db= db->str;
+ qinfo.db_len= (uint)db->length;
/*
These DDL methods and logging are protected with the exclusive
@@ -764,7 +764,7 @@ exit:
}
-int mysql_create_db(THD *thd, const char *db,
+int mysql_create_db(THD *thd, const LEX_CSTRING *db,
const DDL_options_st &options,
const Schema_specification_st *create_info)
{
@@ -777,7 +777,7 @@ int mysql_create_db(THD *thd, const char *db,
}
-bool mysql_alter_db(THD *thd, const char *db,
+bool mysql_alter_db(THD *thd, const LEX_CSTRING *db,
const Schema_specification_st *create_info)
{
/*
@@ -805,7 +805,7 @@ bool mysql_alter_db(THD *thd, const char *db,
*/
static bool
-mysql_rm_db_internal(THD *thd, const char *db, bool if_exists, bool silent)
+mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists, bool silent)
{
ulong deleted_tables= 0;
bool error= true, rm_mysql_schema;
@@ -817,13 +817,13 @@ mysql_rm_db_internal(THD *thd, const char *db, bool if_exists, bool silent)
Drop_table_error_handler err_handler;
DBUG_ENTER("mysql_rm_db");
- char db_tmp[SAFE_NAME_LEN];
- const char *dbnorm= normalize_db_name(db, db_tmp, sizeof(db_tmp));
+ char db_tmp[SAFE_NAME_LEN+1];
+ const char *dbnorm= normalize_db_name(db->str, db_tmp, sizeof(db_tmp));
if (lock_schema_name(thd, dbnorm))
DBUG_RETURN(true);
- length= build_table_filename(path, sizeof(path) - 1, db, "", "", 0);
+ length= build_table_filename(path, sizeof(path) - 1, db->str, "", "", 0);
strmov(path+length, MY_DB_OPT_FILE); // Append db option file name
del_dbopt(path); // Remove dboption hash entry
/*
@@ -846,14 +846,14 @@ mysql_rm_db_internal(THD *thd, const char *db, bool if_exists, bool silent)
{
if (!if_exists)
{
- my_error(ER_DB_DROP_EXISTS, MYF(0), db);
+ my_error(ER_DB_DROP_EXISTS, MYF(0), db->str);
DBUG_RETURN(true);
}
else
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_DB_DROP_EXISTS, ER_THD(thd, ER_DB_DROP_EXISTS),
- db);
+ db->str);
error= false;
goto update_binlog;
}
@@ -867,7 +867,7 @@ mysql_rm_db_internal(THD *thd, const char *db, bool if_exists, bool silent)
This check is only needed if we are dropping the "mysql" database.
*/
if ((rm_mysql_schema=
- (my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db) == 0)))
+ (my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db->str) == 0)))
{
for (table= tables; table; table= table->next_local)
if (check_if_log_table(table, TRUE, "DROP"))
@@ -884,11 +884,9 @@ mysql_rm_db_internal(THD *thd, const char *db, bool if_exists, bool silent)
{
for (table= tables; table; table= table->next_local)
{
- LEX_CSTRING db_name= { table->db, table->db_length };
- LEX_CSTRING table_name= { table->table_name, table->table_name_length };
if (table->open_type == OT_BASE_ONLY ||
!thd->find_temporary_table(table))
- (void) delete_statistics_for_table(thd, &db_name, &table_name);
+ (void) delete_statistics_for_table(thd, &table->db, &table->table_name);
}
}
@@ -959,8 +957,8 @@ update_binlog:
database" and not the threads current database, which is the
default.
*/
- qinfo.db = db;
- qinfo.db_len = strlen(db);
+ qinfo.db = db->str;
+ qinfo.db_len = (uint32)db->length;
/*
These DDL methods and logging are protected with the exclusive
@@ -980,33 +978,32 @@ update_binlog:
{
char *query, *query_pos, *query_end, *query_data_start;
TABLE_LIST *tbl;
- uint db_len;
if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
goto exit; /* not much else we can do */
query_pos= query_data_start= strmov(query,"DROP TABLE IF EXISTS ");
query_end= query + MAX_DROP_TABLE_Q_LEN;
- db_len= strlen(db);
for (tbl= tables; tbl; tbl= tbl->next_local)
{
- uint tbl_name_len;
+ size_t tbl_name_len;
char quoted_name[FN_REFLEN+3];
// Only write drop table to the binlog for tables that no longer exist.
- if (ha_table_exists(thd, tbl->db, tbl->table_name))
+ if (ha_table_exists(thd, &tbl->db, &tbl->table_name))
continue;
- my_snprintf(quoted_name, sizeof(quoted_name), quoted_string,
- tbl->table_name);
- tbl_name_len= strlen(quoted_name) + 1; /* +1 for the comma */
+ tbl_name_len= my_snprintf(quoted_name, sizeof(quoted_name),
+ quoted_string,
+ tbl->table_name.str);
+ tbl_name_len++; /* +1 for the comma */
if (query_pos + tbl_name_len + 1 >= query_end)
{
/*
These DDL methods and logging are protected with the exclusive
metadata lock on the schema.
*/
- if (write_to_binlog(thd, query, (uint)(query_pos -1 - query), db, db_len))
+ if (write_to_binlog(thd, query, (uint)(query_pos -1 - query), db->str, db->length))
{
error= true;
goto exit;
@@ -1024,7 +1021,7 @@ update_binlog:
These DDL methods and logging are protected with the exclusive
metadata lock on the schema.
*/
- if (write_to_binlog(thd, query, (uint)(query_pos -1 - query), db, db_len))
+ if (write_to_binlog(thd, query, (uint)(query_pos -1 - query), db->str, db->length))
{
error= true;
goto exit;
@@ -1039,7 +1036,7 @@ exit:
SELECT DATABASE() in the future). For this we free() thd->db and set
it to 0.
*/
- if (thd->db && cmp_db_names(thd->db, db) && !error)
+ if (thd->db.str && cmp_db_names(&thd->db, db) && !error)
{
mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
SESSION_TRACKER_CHANGED(thd, CURRENT_SCHEMA_TRACKER, NULL);
@@ -1049,7 +1046,7 @@ exit:
}
-bool mysql_rm_db(THD *thd, const char *db, bool if_exists)
+bool mysql_rm_db(THD *thd, const LEX_CSTRING *db, bool if_exists)
{
return mysql_rm_db_internal(thd, db, if_exists, false);
}
@@ -1084,20 +1081,18 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp,
if (!table_list)
DBUG_RETURN(true);
- table_list->db= db.str;
- table_list->db_length= db.length;
- table_list->table_name= table->str;
- table_list->table_name_length= table->length;
+ table_list->db= db;
+ table_list->table_name= *table;
table_list->open_type= OT_BASE_ONLY;
/* To be able to correctly look up the table in the table cache. */
if (lower_case_table_names)
- table_list->table_name_length= my_casedn_str(files_charset_info,
- (char*) table_list->table_name);
+ table_list->table_name.length= my_casedn_str(files_charset_info,
+ (char*) table_list->table_name.str);
table_list->alias= table_list->table_name; // If lower_case_table_names=2
- table_list->mdl_request.init(MDL_key::TABLE, table_list->db,
- table_list->table_name, MDL_EXCLUSIVE,
+ table_list->mdl_request.init(MDL_key::TABLE, table_list->db.str,
+ table_list->table_name.str, MDL_EXCLUSIVE,
MDL_TRANSACTION);
/* Link into list */
(*tot_list_next_local)= table_list;
@@ -1312,16 +1307,16 @@ static void mysql_change_db_impl(THD *thd,
sets the new one.
*/
- thd->set_db(NULL, 0);
+ thd->set_db(&null_clex_str);
}
- else if (new_db_name == &INFORMATION_SCHEMA_NAME)
+ else if (new_db_name->str == INFORMATION_SCHEMA_NAME.str)
{
/*
Here we must use THD::set_db(), because we want to copy
INFORMATION_SCHEMA_NAME constant.
*/
- thd->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
+ thd->set_db(&INFORMATION_SCHEMA_NAME);
}
else
{
@@ -1330,8 +1325,8 @@ static void mysql_change_db_impl(THD *thd,
we just call THD::reset_db(). Since THD::reset_db() does not releases
the previous database name, we should do it explicitly.
*/
- thd->set_db(NULL, 0);
- thd->reset_db(const_cast<char*>(new_db_name->str), new_db_name->length);
+ thd->set_db(&null_clex_str);
+ thd->reset_db(new_db_name);
}
/* 2. Update security context. */
@@ -1366,17 +1361,17 @@ static void mysql_change_db_impl(THD *thd,
static void backup_current_db_name(THD *thd,
LEX_STRING *saved_db_name)
{
- if (!thd->db)
+ DBUG_ASSERT(saved_db_name->length >= SAFE_NAME_LEN +1);
+ if (!thd->db.str)
{
/* No current (default) database selected. */
-
- saved_db_name->str= NULL;
+ saved_db_name->str= 0;
saved_db_name->length= 0;
}
else
{
- strmake(saved_db_name->str, thd->db, saved_db_name->length - 1);
- saved_db_name->length= thd->db_length;
+ memcpy(saved_db_name->str, thd->db.str, thd->db.length + 1);
+ saved_db_name->length= thd->db.length;
}
}
@@ -1479,7 +1474,7 @@ bool mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name,
}
DBUG_PRINT("enter",("name: '%s'", new_db_name->str));
- if (is_infoschema_db(new_db_name->str, new_db_name->length))
+ if (is_infoschema_db(new_db_name))
{
/* Switch the current database to INFORMATION_SCHEMA. */
@@ -1630,7 +1625,7 @@ bool mysql_opt_change_db(THD *thd,
bool force_switch,
bool *cur_db_changed)
{
- *cur_db_changed= !cmp_db_names(thd->db, new_db_name->str);
+ *cur_db_changed= !cmp_db_names(&thd->db, new_db_name);
if (!*cur_db_changed)
return FALSE;
@@ -1656,9 +1651,9 @@ bool mysql_opt_change_db(THD *thd,
@return 0 on success, 1 on error
*/
-bool mysql_upgrade_db(THD *thd, LEX_CSTRING *old_db)
+bool mysql_upgrade_db(THD *thd, const LEX_CSTRING *old_db)
{
- int error= 0, change_to_newdb= 0;
+ bool error= 0, change_to_newdb= 0;
char path[FN_REFLEN+16];
uint length;
Schema_specification_st create_info;
@@ -1691,7 +1686,7 @@ bool mysql_upgrade_db(THD *thd, LEX_CSTRING *old_db)
Let's remember if we should do "USE newdb" afterwards.
thd->db will be cleared in mysql_rename_db()
*/
- if (thd->db && !strcmp(thd->db, old_db->str))
+ if (thd->db.str && !cmp(&thd->db, old_db))
change_to_newdb= 1;
build_table_filename(path, sizeof(path)-1,
@@ -1709,7 +1704,7 @@ bool mysql_upgrade_db(THD *thd, LEX_CSTRING *old_db)
}
/* Step1: Create the new database */
- if ((error= mysql_create_db_internal(thd, new_db.str,
+ if ((error= mysql_create_db_internal(thd, &new_db,
DDL_options(), &create_info, 1)))
goto exit;
@@ -1833,7 +1828,7 @@ bool mysql_upgrade_db(THD *thd, LEX_CSTRING *old_db)
to execute them again.
mysql_rm_db() also "unuses" if we drop the current database.
*/
- error= mysql_rm_db_internal(thd, old_db->str, 0, true);
+ error= mysql_rm_db_internal(thd, old_db, 0, true);
/* Step8: logging */
if (mysql_bin_log.is_open())
diff --git a/sql/sql_db.h b/sql/sql_db.h
index a4ada7de6a2..7de6c2a9c99 100644
--- a/sql/sql_db.h
+++ b/sql/sql_db.h
@@ -20,13 +20,13 @@
class THD;
-int mysql_create_db(THD *thd, const char *db,
+int mysql_create_db(THD *thd, const LEX_CSTRING *db,
const DDL_options_st &options,
const Schema_specification_st *create);
-bool mysql_alter_db(THD *thd, const char *db,
+bool mysql_alter_db(THD *thd, const LEX_CSTRING *db,
const Schema_specification_st *create);
-bool mysql_rm_db(THD *thd, const char *db, bool if_exists);
-bool mysql_upgrade_db(THD *thd, LEX_CSTRING *old_db);
+bool mysql_rm_db(THD *thd, const LEX_CSTRING *db, bool if_exists);
+bool mysql_upgrade_db(THD *thd, const LEX_CSTRING *old_db);
bool mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name,
bool force_switch);
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 0d4bed836b8..b92dd4139b2 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -103,7 +103,7 @@ bool Update_plan::save_explain_data_intern(MEM_ROOT *mem_root,
bool is_analyze)
{
explain->select_type= "SIMPLE";
- explain->table_name.append(table->pos_in_table_list->alias);
+ explain->table_name.append(&table->pos_in_table_list->alias);
explain->impossible_where= false;
explain->no_partitions= false;
@@ -223,13 +223,21 @@ bool Update_plan::save_explain_data_intern(MEM_ROOT *mem_root,
static bool record_should_be_deleted(THD *thd, TABLE *table, SQL_SELECT *sel,
- Explain_delete *explain)
+ Explain_delete *explain, bool truncate_history)
{
+ bool check_delete= true;
+
+ if (table->versioned())
+ {
+ bool historical= !table->vers_end_field()->is_max();
+ check_delete= truncate_history ? historical : !historical;
+ }
+
explain->tracker.on_record_read();
thd->inc_examined_row_count(1);
if (table->vfield)
(void) table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_DELETE);
- if (!sel || sel->skip_record(thd) > 0)
+ if (check_delete && (!sel || sel->skip_record(thd) > 0))
{
explain->tracker.on_record_after_where();
return true;
@@ -238,6 +246,18 @@ static bool record_should_be_deleted(THD *thd, TABLE *table, SQL_SELECT *sel,
}
+inline
+int TABLE::delete_row()
+{
+ if (!versioned(VERS_TIMESTAMP) || !vers_end_field()->is_max())
+ return file->ha_delete_row(record[0]);
+
+ store_record(this, record[1]);
+ vers_update_end();
+ return file->ha_update_row(record[1], record[0]);
+}
+
+
/**
Implement DELETE SQL word.
@@ -250,7 +270,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
SQL_I_List<ORDER> *order_list, ha_rows limit,
ulonglong options, select_result *result)
{
- bool will_batch;
+ bool will_batch= FALSE;
int error, loc_error;
TABLE *table;
SQL_SELECT *select=0;
@@ -262,11 +282,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
bool return_error= 0;
ha_rows deleted= 0;
bool reverse= FALSE;
+ bool has_triggers;
ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
order_list->first : NULL);
SELECT_LEX *select_lex= &thd->lex->select_lex;
killed_state killed_status= NOT_KILLED;
THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE;
+ bool binlog_is_row;
bool with_select= !select_lex->item_list.is_empty();
Explain_delete *explain;
Delete_plan query_plan(thd->mem_root);
@@ -282,6 +304,31 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_RETURN(TRUE);
THD_STAGE_INFO(thd, stage_init_update);
+
+ bool truncate_history= table_list->vers_conditions;
+ if (truncate_history)
+ {
+ if (table_list->is_view_or_derived())
+ {
+ my_error(ER_IT_IS_A_VIEW, MYF(0), table_list->table_name.str);
+ DBUG_RETURN(true);
+ }
+
+ TABLE *table= table_list->table;
+ DBUG_ASSERT(table);
+
+ DBUG_ASSERT(!conds || thd->stmt_arena->is_stmt_execute());
+ if (select_lex->vers_setup_conds(thd, table_list, &conds))
+ DBUG_RETURN(TRUE);
+
+ // trx_sees() in InnoDB reads row_start
+ if (!table->versioned(VERS_TIMESTAMP))
+ {
+ DBUG_ASSERT(table_list->vers_conditions.type == SYSTEM_TIME_BEFORE);
+ bitmap_set_bit(table->read_set, table->vers_end_field()->field_index);
+ }
+ }
+
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT))
DBUG_RETURN(TRUE);
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
@@ -289,7 +336,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (!table_list->single_table_updatable())
{
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE");
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "DELETE");
DBUG_RETURN(TRUE);
}
if (!(table= table_list->table) || !table->is_created())
@@ -371,9 +418,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
- We should not be binlogging this statement in row-based, and
- there should be no delete triggers associated with the table.
*/
+
+ has_triggers= (table->triggers &&
+ table->triggers->has_delete_triggers());
if (!with_select && !using_limit && const_cond_result &&
(!thd->is_current_stmt_binlog_format_row() &&
- !(table->triggers && table->triggers->has_delete_triggers())))
+ !has_triggers)
+ && !table->versioned(VERS_TIMESTAMP))
{
/* Update the table->file->stats.records number */
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
@@ -522,14 +573,59 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (!(select && select->quick))
status_var_increment(thd->status_var.delete_scan_count);
- if (query_plan.using_filesort)
+ binlog_is_row= thd->is_current_stmt_binlog_format_row();
+ DBUG_PRINT("info", ("binlog_is_row: %s", binlog_is_row ? "TRUE" : "FALSE"));
+
+ /*
+ We can use direct delete (delete that is done silently in the handler)
+ if none of the following conditions are true:
+ - There are triggers
+ - There is binary logging
+ - There is a virtual not stored column in the WHERE clause
+ - ORDER BY or LIMIT
+ - As this requires the rows to be deleted in a specific order
+ - Note that Spider can handle ORDER BY and LIMIT in a cluster with
+ one data node. These conditions are therefore checked in
+ direct_delete_rows_init().
+
+ Direct delete does not require a WHERE clause
+
+ Later we also ensure that we are only using one table (no sub queries)
+ */
+
+ if ((table->file->ha_table_flags() & HA_CAN_DIRECT_UPDATE_AND_DELETE) &&
+ !has_triggers && !binlog_is_row && !with_select)
{
+ table->mark_columns_needed_for_delete();
+ if (!table->check_virtual_columns_marked_for_read())
+ {
+ DBUG_PRINT("info", ("Trying direct delete"));
+ if (select && select->cond &&
+ (select->cond->used_tables() == table->map))
+ {
+ DBUG_ASSERT(!table->file->pushed_cond);
+ if (!table->file->cond_push(select->cond))
+ table->file->pushed_cond= select->cond;
+ }
+ if (!table->file->direct_delete_rows_init())
+ {
+ /* Direct deleting is supported */
+ DBUG_PRINT("info", ("Using direct delete"));
+ THD_STAGE_INFO(thd, stage_updating);
+ if (!(error= table->file->ha_direct_delete_rows(&deleted)))
+ error= -1;
+ goto terminate_delete;
+ }
+ }
+ }
+ if (query_plan.using_filesort)
+ {
{
Filesort fsort(order, HA_POS_ERROR, true, select);
DBUG_ASSERT(query_plan.index == MAX_KEY);
- Filesort_tracker *fs_tracker=
+ Filesort_tracker *fs_tracker=
thd->lex->explain->get_upd_del_plan()->filesort_tracker;
if (!(file_sort= filesort(thd, table, &fsort, fs_tracker)))
@@ -568,15 +664,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (init_ftfuncs(thd, select_lex, 1))
goto got_error;
- if (table->prepare_triggers_for_delete_stmt_or_event())
- {
- will_batch= FALSE;
- }
- else
- will_batch= !table->file->start_bulk_delete();
-
table->mark_columns_needed_for_delete();
+ if ((table->file->ha_table_flags() & HA_CAN_FORCE_BULK_DELETE) &&
+ !table->prepare_triggers_for_delete_stmt_or_event())
+ will_batch= !table->file->start_bulk_delete();
+
if (with_select)
{
if (result->send_result_set_metadata(select_lex->item_list,
@@ -603,7 +696,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
while (!(error=info.read_record()) && !thd->killed &&
! thd->is_error())
{
- if (record_should_be_deleted(thd, table, select, explain))
+ if (record_should_be_deleted(thd, table, select, explain, truncate_history))
{
table->file->position(table->record[0]);
if ((error= deltempfile->unique_add((char*) table->file->ref)))
@@ -630,10 +723,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
! thd->is_error())
{
if (delete_while_scanning)
- delete_record= record_should_be_deleted(thd, table, select, explain);
+ delete_record= record_should_be_deleted(thd, table, select, explain,
+ truncate_history);
if (delete_record)
{
- if (table->triggers &&
+ if (!truncate_history && table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE))
{
@@ -647,10 +741,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
break;
}
- if (!(error= table->file->ha_delete_row(table->record[0])))
+ error= table->delete_row();
+ if (!error)
{
deleted++;
- if (table->triggers &&
+ if (!truncate_history && table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE))
{
@@ -683,6 +778,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
else
break;
}
+
terminate_delete:
killed_status= thd->killed;
if (killed_status != NOT_KILLED || thd->is_error())
@@ -736,6 +832,8 @@ cleanup:
else
errcode= query_error_code(thd, killed_status == NOT_KILLED);
+ ScopedStatementReplication scoped_stmt_rpl(
+ table->versioned(VERS_TRX_ID) ? thd : NULL);
/*
[binlog]: If 'handler::delete_all_rows()' was called and the
storage engine does not inject the rows itself, we replicate
@@ -769,6 +867,8 @@ cleanup:
}
delete file_sort;
free_underlaid_joins(thd, select_lex);
+ if (table->file->pushed_cond)
+ table->file->cond_pop();
DBUG_RETURN(error >= 0 || thd->is_error());
/* Special exits */
@@ -790,7 +890,8 @@ send_nothing_and_leave:
delete select;
delete file_sort;
free_underlaid_joins(thd, select_lex);
- //table->set_keyread(false);
+ if (table->file->pushed_cond)
+ table->file->cond_pop();
DBUG_ASSERT(!return_error || thd->is_error() || thd->killed);
DBUG_RETURN((return_error || thd->is_error() || thd->killed) ? 1 : 0);
@@ -811,14 +912,14 @@ got_error:
wild_num - number of wildcards used in optional SELECT clause
field_list - list of items in optional SELECT clause
conds - conditions
-l
+
RETURN VALUE
FALSE OK
TRUE error
*/
- int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
- uint wild_num, List<Item> &field_list, Item **conds,
- bool *delete_while_scanning)
+int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
+ uint wild_num, List<Item> &field_list, Item **conds,
+ bool *delete_while_scanning)
{
Item *fake_conds= 0;
SELECT_LEX *select_lex= &thd->lex->select_lex;
@@ -833,6 +934,16 @@ l
select_lex->leaf_tables, FALSE,
DELETE_ACL, SELECT_ACL, TRUE))
DBUG_RETURN(TRUE);
+ if (table_list->vers_conditions)
+ {
+ if (table_list->is_view())
+ {
+ my_error(ER_IT_IS_A_VIEW, MYF(0), table_list->table_name.str);
+ DBUG_RETURN(true);
+ }
+ if (select_lex->vers_setup_conds(thd, table_list, conds))
+ DBUG_RETURN(true);
+ }
if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num)) ||
setup_fields(thd, Ref_ptr_array(),
field_list, MARK_COLUMNS_READ, NULL, NULL, 0) ||
@@ -842,7 +953,7 @@ l
if (!table_list->single_table_updatable() ||
check_key_in_view(thd, table_list))
{
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE");
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "DELETE");
DBUG_RETURN(TRUE);
}
@@ -934,7 +1045,7 @@ int mysql_multi_delete_prepare(THD *thd)
check_key_in_view(thd, target_tbl->correspondent_table))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
- target_tbl->table_name, "DELETE");
+ target_tbl->table_name.str, "DELETE");
DBUG_RETURN(TRUE);
}
/*
@@ -1118,6 +1229,11 @@ int multi_delete::send_data(List<Item> &values)
if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
continue;
+ if (table->versioned() && !table->vers_end_field()->is_max())
+ {
+ continue;
+ }
+
table->file->position(table->record[0]);
found++;
@@ -1130,7 +1246,9 @@ int multi_delete::send_data(List<Item> &values)
TRG_ACTION_BEFORE, FALSE))
DBUG_RETURN(1);
table->status|= STATUS_DELETED;
- if (!(error=table->file->ha_delete_row(table->record[0])))
+
+ error= table->delete_row();
+ if (!error)
{
deleted++;
if (!table->file->has_transactions())
@@ -1309,8 +1427,8 @@ int multi_delete::do_table_deletes(TABLE *table, SORT_INFO *sort_info,
local_error= 1;
break;
}
-
- local_error= table->file->ha_delete_row(table->record[0]);
+
+ local_error= table->delete_row();
if (local_error && !ignore)
{
table->file->print_error(local_error, MYF(0));
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 6eb6466427d..ab66384c6cb 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -174,7 +174,7 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
DBUG_ENTER("mysql_handle_single_derived");
DBUG_PRINT("enter", ("phases: 0x%x allowed: 0x%x alias: '%s'",
phases, allowed_phases,
- (derived->alias ? derived->alias : "<NULL>")));
+ (derived->alias.str ? derived->alias.str : "<NULL>")));
if (!lex->derived_tables)
DBUG_RETURN(FALSE);
@@ -364,9 +364,16 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
SELECT_LEX *parent_lex= derived->select_lex;
Query_arena *arena, backup;
DBUG_ENTER("mysql_derived_merge");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (derived->alias.str ? derived->alias.str : "<NULL>"),
+ derived->get_unit()));
if (derived->merged)
+ {
+
+ DBUG_PRINT("info", ("Irreversibly merged: exit"));
DBUG_RETURN(FALSE);
+ }
if (dt_select->uncacheable & UNCACHEABLE_RAND)
{
@@ -381,7 +388,6 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
thd->save_prep_leaf_list= TRUE;
arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
- derived->merged= TRUE;
if (!derived->merged_for_insert ||
(derived->is_multitable() &&
@@ -445,6 +451,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
if (parent_lex->join)
parent_lex->join->table_count+= dt_select->join->table_count - 1;
}
+ derived->merged= TRUE;
if (derived->get_unit()->prepared)
{
Item *expr= derived->on_expr;
@@ -510,7 +517,9 @@ unconditional_materialization:
bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
{
DBUG_ENTER("mysql_derived_merge_for_insert");
- DBUG_PRINT("enter", ("derived: %p", derived));
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (derived->alias.str ? derived->alias.str : "<NULL>"),
+ derived->get_unit()));
DBUG_PRINT("info", ("merged_for_insert: %d is_materialized_derived: %d "
"is_multitable: %d single_table_updatable: %d "
"merge_underlying_list: %d",
@@ -566,7 +575,9 @@ bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived)
{
SELECT_LEX_UNIT *unit= derived->get_unit();
DBUG_ENTER("mysql_derived_init");
- DBUG_PRINT("enter", ("derived: %p", derived));
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (derived->alias.str ? derived->alias.str : "<NULL>"),
+ derived->get_unit()));
// Skip already prepared views/DT
if (!unit || unit->prepared)
@@ -640,10 +651,10 @@ bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived)
bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
{
SELECT_LEX_UNIT *unit= derived->get_unit();
- DBUG_ENTER("mysql_derived_prepare");
bool res= FALSE;
- DBUG_PRINT("enter", ("unit: %p table_list: %p Alias '%s'",
- unit, derived, derived->alias));
+ DBUG_ENTER("mysql_derived_prepare");
+ DBUG_PRINT("enter", ("unit: %p table_list: %p alias: '%s'",
+ unit, derived, derived->alias.str));
if (!unit)
DBUG_RETURN(FALSE);
@@ -684,7 +695,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
(first_select->options |
thd->variables.option_bits |
TMP_TABLE_ALL_COLUMNS),
- derived->alias, FALSE, FALSE, FALSE, 0);
+ &derived->alias, FALSE, FALSE, FALSE, 0);
thd->create_tmp_table_for_derived= FALSE;
if (!res && !derived->table)
@@ -737,6 +748,17 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
}
unit->derived= derived;
+
+ /*
+ Above cascade call of prepare is important for PS protocol, but after it
+ is called we can check if we really need prepare for this derived
+ */
+ if (derived->merged)
+ {
+ DBUG_PRINT("info", ("Irreversibly merged: exit"));
+ DBUG_RETURN(FALSE);
+ }
+
derived->fill_me= FALSE;
if (!(derived->derived_result= new (thd->mem_root) select_unit(thd)))
@@ -777,7 +799,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
(first_select->options |
thd->variables.option_bits |
TMP_TABLE_ALL_COLUMNS),
- derived->alias,
+ &derived->alias,
FALSE, FALSE, FALSE,
0))
{
@@ -802,8 +824,8 @@ exit:
thd->get_stmt_da()->sql_errno() == ER_SP_DOES_NOT_EXIST))
{
thd->clear_error();
- my_error(ER_VIEW_INVALID, MYF(0), derived->db,
- derived->table_name);
+ my_error(ER_VIEW_INVALID, MYF(0), derived->db.str,
+ derived->table_name.str);
}
}
@@ -873,9 +895,16 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
SELECT_LEX_UNIT *unit= derived->get_unit();
SELECT_LEX *first_select= unit->first_select();
SELECT_LEX *save_current_select= lex->current_select;
-
bool res= FALSE;
DBUG_ENTER("mysql_derived_optimize");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (derived->alias.str ? derived->alias.str : "<NULL>"),
+ derived->get_unit()));
+ if (derived->merged)
+ {
+ DBUG_PRINT("info", ("Irreversibly merged: exit"));
+ DBUG_RETURN(FALSE);
+ }
lex->current_select= first_select;
@@ -954,6 +983,9 @@ err:
bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
{
DBUG_ENTER("mysql_derived_create");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (derived->alias.str ? derived->alias.str : "<NULL>"),
+ derived->get_unit()));
TABLE *table= derived->table;
SELECT_LEX_UNIT *unit= derived->get_unit();
@@ -978,6 +1010,20 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
}
+void TABLE_LIST::register_as_derived_with_rec_ref(With_element *rec_elem)
+{
+ rec_elem->derived_with_rec_ref.link_in_list(this, &this->next_with_rec_ref);
+ is_derived_with_recursive_reference= true;
+ get_unit()->uncacheable|= UNCACHEABLE_DEPENDENT;
+}
+
+
+bool TABLE_LIST::is_nonrecursive_derived_with_rec_ref()
+{
+ return is_derived_with_recursive_reference;
+}
+
+
/**
@brief
Fill the recursive with table
@@ -1047,10 +1093,14 @@ bool TABLE_LIST::fill_recursive(THD *thd)
bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
{
- DBUG_ENTER("mysql_derived_fill");
+ Field_iterator_table field_iterator;
SELECT_LEX_UNIT *unit= derived->get_unit();
bool derived_is_recursive= derived->is_recursive_with_table();
bool res= FALSE;
+ DBUG_ENTER("mysql_derived_fill");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (derived->alias.str ? derived->alias.str : "<NULL>"),
+ derived->get_unit()));
if (unit->executed && !unit->uncacheable && !unit->describe &&
!derived_is_recursive)
@@ -1121,9 +1171,28 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
if (derived_result->flush())
res= TRUE;
unit->executed= TRUE;
+
+ if (derived->field_translation)
+ {
+ /* reset translation table to materialized table */
+ field_iterator.set_table(derived->table);
+ for (uint i= 0;
+ !field_iterator.end_of_fields();
+ field_iterator.next(), i= i + 1)
+ {
+ Item *item;
+
+ if (!(item= field_iterator.create_item(thd)))
+ {
+ res= TRUE;
+ break;
+ }
+ thd->change_item_tree(&derived->field_translation[i].item, item);
+ }
+ }
}
err:
- if (res || (!lex->describe && !derived_is_recursive && !unit->uncacheable))
+ if (res || (!lex->describe && !derived_is_recursive && !unit->uncacheable))
unit->cleanup();
lex->current_select= save_current_select;
@@ -1151,6 +1220,9 @@ err:
bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
{
DBUG_ENTER("mysql_derived_reinit");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (derived->alias.str ? derived->alias.str : "<NULL>"),
+ derived->get_unit()));
st_select_lex_unit *unit= derived->get_unit();
derived->merged_for_insert= FALSE;
@@ -1261,7 +1333,7 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
continue;
extracted_cond_copy= !sl->next_select() ?
extracted_cond :
- extracted_cond->build_clone(thd, thd->mem_root);
+ extracted_cond->build_clone(thd);
if (!extracted_cond_copy)
continue;
@@ -1291,7 +1363,7 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
*/
extracted_cond_copy= !sl->next_select() ?
extracted_cond :
- extracted_cond->build_clone(thd, thd->mem_root);
+ extracted_cond->build_clone(thd);
if (!extracted_cond_copy)
continue;
diff --git a/sql/sql_digest.cc b/sql/sql_digest.cc
index 65edcc122f1..54ed1c3f225 100644
--- a/sql/sql_digest.cc
+++ b/sql/sql_digest.cc
@@ -20,7 +20,7 @@
#include "mariadb.h"
#include "my_md5.h"
-#include "mysqld_error.h"
+#include "unireg.h"
#include "sql_string.h"
#include "sql_class.h"
@@ -149,7 +149,7 @@ inline void store_token_identifier(sql_digest_storage* digest_storage,
/* Write the string data */
if (id_length > 0)
memcpy((char *)(dest + 4), id_name, id_length);
- digest_storage->m_byte_count+= bytes_needed;
+ digest_storage->m_byte_count+= (uint)bytes_needed;
}
else
{
diff --git a/sql/sql_digest.h b/sql/sql_digest.h
index eaf74b9542e..81fe809b59d 100644
--- a/sql/sql_digest.h
+++ b/sql/sql_digest.h
@@ -54,10 +54,10 @@ struct sql_digest_storage
reset(NULL, 0);
}
- inline void reset(unsigned char *token_array, uint length)
+ inline void reset(unsigned char *token_array, size_t length)
{
m_token_array= token_array;
- m_token_array_length= length;
+ m_token_array_length= (uint)length;
reset();
}
diff --git a/sql/sql_do.cc b/sql/sql_do.cc
index f556dc282ed..20a7aa75590 100644
--- a/sql/sql_do.cc
+++ b/sql/sql_do.cc
@@ -29,7 +29,7 @@ bool mysql_do(THD *thd, List<Item> &values)
List_iterator<Item> li(values);
Item *value;
DBUG_ENTER("mysql_do");
- if (setup_fields(thd, Ref_ptr_array(), values, MARK_COLUMNS_NONE, 0, NULL, 0))
+ if (setup_fields(thd, Ref_ptr_array(), values, COLUMNS_READ, 0, NULL, 0))
DBUG_RETURN(TRUE);
while ((value = li++))
(void) value->is_null();
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index b1c7481bb8c..67440aeed33 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -506,7 +506,7 @@ void Warning_info::init()
{
/* Initialize sub structures */
DBUG_ASSERT(initialized == 0);
- init_sql_alloc(&m_warn_root, WARN_ALLOC_BLOCK_SIZE,
+ init_sql_alloc(&m_warn_root, "Warning_info", WARN_ALLOC_BLOCK_SIZE,
WARN_ALLOC_PREALLOC_SIZE, MYF(MY_THREAD_SPECIFIC));
initialized= 1;
}
@@ -523,8 +523,7 @@ Warning_info::~Warning_info()
}
-bool Warning_info::has_sql_condition(const char *message_str,
- ulong message_length) const
+bool Warning_info::has_sql_condition(const char *message_str, size_t message_length) const
{
Diagnostics_area::Sql_condition_iterator it(m_warn_list);
const Sql_condition *err;
@@ -769,12 +768,12 @@ void push_warning_printf(THD *thd, Sql_condition::enum_warning_level level,
TRUE Error sending data to client
*/
-const LEX_STRING warning_level_names[]=
+const LEX_CSTRING warning_level_names[]=
{
- { C_STRING_WITH_LEN("Note") },
- { C_STRING_WITH_LEN("Warning") },
- { C_STRING_WITH_LEN("Error") },
- { C_STRING_WITH_LEN("?") }
+ { STRING_WITH_LEN("Note") },
+ { STRING_WITH_LEN("Warning") },
+ { STRING_WITH_LEN("Error") },
+ { STRING_WITH_LEN("?") }
};
bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
@@ -918,11 +917,11 @@ char *err_conv(char *buff, uint to_length, const char *from,
length of converted string
*/
-uint32 convert_error_message(char *to, uint32 to_length, CHARSET_INFO *to_cs,
- const char *from, uint32 from_length,
+size_t convert_error_message(char *to, size_t to_length, CHARSET_INFO *to_cs,
+ const char *from, size_t from_length,
CHARSET_INFO *from_cs, uint *errors)
{
- int cnvres;
+ int cnvres;
my_wc_t wc;
const uchar *from_end= (const uchar*) from+from_length;
char *to_start= to;
@@ -930,7 +929,7 @@ uint32 convert_error_message(char *to, uint32 to_length, CHARSET_INFO *to_cs,
my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc;
my_charset_conv_wc_mb wc_mb;
uint error_count= 0;
- uint length;
+ size_t length;
DBUG_ASSERT(to_length > 0);
/* Make room for the null terminator. */
@@ -969,7 +968,7 @@ uint32 convert_error_message(char *to, uint32 to_length, CHARSET_INFO *to_cs,
length= (wc <= 0xFFFF) ? 6/* '\1234' format*/ : 9 /* '\+123456' format*/;
if ((uchar*)(to + length) >= to_end)
break;
- cnvres= my_snprintf(to, 9,
+ cnvres= (int)my_snprintf(to, 9,
(wc <= 0xFFFF) ? "\\%04X" : "\\+%06X", (uint) wc);
to+= cnvres;
}
@@ -979,7 +978,7 @@ uint32 convert_error_message(char *to, uint32 to_length, CHARSET_INFO *to_cs,
*to= 0;
*errors= error_count;
- return (uint32) (to - to_start);
+ return (size_t) (to - to_start);
}
diff --git a/sql/sql_error.h b/sql/sql_error.h
index f8b8adc805a..67c6e50d283 100644
--- a/sql/sql_error.h
+++ b/sql/sql_error.h
@@ -591,7 +591,7 @@ private:
@return true if the Warning_info contains an SQL-condition with the given
message.
*/
- bool has_sql_condition(const char *message_str, ulong message_length) const;
+ bool has_sql_condition(const char *message_str, size_t message_length) const;
/**
Reset the warning information. Clear all warnings,
@@ -1089,7 +1089,7 @@ public:
ulong current_statement_warn_count() const
{ return get_warning_info()->current_statement_warn_count(); }
- bool has_sql_condition(const char *message_str, ulong message_length) const
+ bool has_sql_condition(const char *message_str, size_t message_length) const
{ return get_warning_info()->has_sql_condition(message_str, message_length); }
void reset_for_next_command()
@@ -1174,7 +1174,7 @@ public:
void copy_non_errors_from_wi(THD *thd, const Warning_info *src_wi);
-private:
+protected:
Warning_info *get_warning_info() { return m_wi_stack.front(); }
const Warning_info *get_warning_info() const { return m_wi_stack.front(); }
@@ -1240,12 +1240,12 @@ void push_warning_printf(THD *thd, Sql_condition::enum_warning_level level,
bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
-uint32 convert_error_message(char *to, uint32 to_length,
+size_t convert_error_message(char *to, size_t to_length,
CHARSET_INFO *to_cs,
- const char *from, uint32 from_length,
+ const char *from, size_t from_length,
CHARSET_INFO *from_cs, uint *errors);
-extern const LEX_STRING warning_level_names[];
+extern const LEX_CSTRING warning_level_names[];
bool is_sqlstate_valid(const LEX_CSTRING *sqlstate);
/**
diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc
index 660d68427d1..5d977c6d5c2 100644
--- a/sql/sql_explain.cc
+++ b/sql/sql_explain.cc
@@ -445,13 +445,13 @@ uint Explain_union::make_union_table_name(char *buf)
default:
DBUG_ASSERT(0);
}
- memcpy(buf, type.str, (len= type.length));
+ memcpy(buf, type.str, (len= (uint)type.length));
for (; childno < union_members.elements() && len + lastop + 5 < NAME_LEN;
childno++)
{
len+= lastop;
- lastop= my_snprintf(buf + len, NAME_LEN - len,
+ lastop= (uint)my_snprintf(buf + len, NAME_LEN - len,
"%u,", union_members.at(childno));
}
@@ -974,6 +974,7 @@ Explain_aggr_filesort::Explain_aggr_filesort(MEM_ROOT *mem_root,
for (ORDER *ord= filesort->order; ord; ord= ord->next)
{
sort_items.push_back(ord->item[0], mem_root);
+ sort_directions.push_back(&ord->direction, mem_root);
}
filesort->tracker= &tracker;
}
@@ -987,10 +988,13 @@ void Explain_aggr_filesort::print_json_members(Json_writer *writer,
str.length(0);
List_iterator_fast<Item> it(sort_items);
- Item *item;
+ List_iterator_fast<ORDER::enum_order> it_dir(sort_directions);
+ Item* item;
+ ORDER::enum_order *direction;
bool first= true;
while ((item= it++))
{
+ direction= it_dir++;
if (first)
first= false;
else
@@ -998,6 +1002,8 @@ void Explain_aggr_filesort::print_json_members(Json_writer *writer,
str.append(", ");
}
append_item_to_str(&str, item);
+ if (*direction == ORDER::ORDER_DESC)
+ str.append(" desc");
}
writer->add_member("sort_key").add_str(str.c_ptr_safe());
@@ -1813,9 +1819,9 @@ const char * extra_tag_text[]=
"Using join buffer", // special handling
- "const row not found",
- "unique row not found",
- "Impossible ON condition"
+ "Const row not found",
+ "Unique row not found",
+ "Impossible ON condition",
};
diff --git a/sql/sql_explain.h b/sql/sql_explain.h
index 895c059f1b0..38250cc40ce 100644
--- a/sql/sql_explain.h
+++ b/sql/sql_explain.h
@@ -207,6 +207,9 @@ public:
Explain_select(MEM_ROOT *root, bool is_analyze) :
Explain_basic_join(root),
+#ifndef DBUG_OFF
+ select_lex(NULL),
+#endif
linkage(UNSPECIFIED_TYPE),
message(NULL),
having(NULL), having_value(Item::COND_UNDEF),
@@ -218,6 +221,9 @@ public:
void add_linkage(Json_writer *writer);
public:
+#ifndef DBUG_OFF
+ SELECT_LEX *select_lex;
+#endif
const char *select_type;
enum sub_select_type linkage;
@@ -286,6 +292,7 @@ public:
class Explain_aggr_filesort : public Explain_aggr_node
{
List<Item> sort_items;
+ List<ORDER::enum_order> sort_directions;
public:
enum_explain_aggr_node_type get_type() { return AGGR_OP_FILESORT; }
Filesort_tracker tracker;
diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc
index 00f5bfd792f..15c6cc57efb 100644
--- a/sql/sql_expression_cache.cc
+++ b/sql/sql_expression_cache.cc
@@ -97,6 +97,7 @@ void Expression_cache_tmptable::init()
List_iterator<Item> li(items);
Item_iterator_list it(li);
uint field_counter;
+ LEX_CSTRING cache_table_name= { STRING_WITH_LEN("subquery-cache-table") };
DBUG_ENTER("Expression_cache_tmptable::init");
DBUG_ASSERT(!inited);
inited= TRUE;
@@ -124,7 +125,7 @@ void Expression_cache_tmptable::init()
TMP_TABLE_ALL_COLUMNS) &
~TMP_TABLE_FORCE_MYISAM),
HA_POS_ERROR,
- (char *)"subquery-cache-table",
+ &cache_table_name,
TRUE)))
{
DBUG_PRINT("error", ("create_tmp_table failed, caching switched off"));
diff --git a/sql/sql_get_diagnostics.cc b/sql/sql_get_diagnostics.cc
index 76973b4daa2..e7ab6cc3c75 100644
--- a/sql/sql_get_diagnostics.cc
+++ b/sql/sql_get_diagnostics.cc
@@ -110,6 +110,9 @@ Diagnostics_information_item::set_value(THD *thd, Item **value)
DBUG_ASSERT(srp);
+ /* GET DIAGNOSTICS is not allowed in prepared statements */
+ DBUG_ASSERT(srp->get_item_param() == NULL);
+
/* Set variable/parameter value. */
rv= srp->set_value(thd, thd->spcont, value);
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 947c41e461e..ddc9c4a99d7 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -116,7 +116,7 @@ static char *mysql_ha_hash_get_key(SQL_HANDLER *table, size_t *key_len,
my_bool first __attribute__((unused)))
{
*key_len= table->handler_name.length + 1 ; /* include '\0' in comparisons */
- return table->handler_name.str;
+ return (char*) table->handler_name.str;
}
@@ -139,6 +139,48 @@ static void mysql_ha_hash_free(SQL_HANDLER *table)
delete table;
}
+static void mysql_ha_close_childs(THD *thd, TABLE_LIST *current_table_list,
+ TABLE_LIST **next_global)
+{
+ TABLE_LIST *table_list;
+ DBUG_ENTER("mysql_ha_close_childs");
+ DBUG_PRINT("info",("current_table_list: %p", current_table_list));
+ DBUG_PRINT("info",("next_global: %p", *next_global));
+ for (table_list = *next_global; table_list; table_list = *next_global)
+ {
+ *next_global = table_list->next_global;
+ DBUG_PRINT("info",("table_name: %s.%s", table_list->table->s->db.str,
+ table_list->table->s->table_name.str));
+ DBUG_PRINT("info",("parent_l: %p", table_list->parent_l));
+ if (table_list->parent_l == current_table_list)
+ {
+ DBUG_PRINT("info",("found child"));
+ TABLE *table = table_list->table;
+ if (table)
+ {
+ table->open_by_handler= 0;
+ if (!table->s->tmp_table)
+ {
+ (void) close_thread_table(thd, &table);
+ thd->mdl_context.release_lock(table_list->mdl_request.ticket);
+ }
+ else
+ {
+ thd->mark_tmp_table_as_free_for_reuse(table);
+ }
+ }
+ mysql_ha_close_childs(thd, table_list, next_global);
+ }
+ else
+ {
+ /* the end of child tables */
+ *next_global = table_list;
+ break;
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
/**
Close a HANDLER table.
@@ -155,11 +197,16 @@ static void mysql_ha_close_table(SQL_HANDLER *handler)
{
THD *thd= handler->thd;
TABLE *table= handler->table;
+ TABLE_LIST *current_table_list= NULL, *next_global;
/* check if table was already closed */
if (!table)
return;
+ if ((next_global= table->file->get_next_global_for_child()))
+ current_table_list= next_global->parent_l;
+
+ table->open_by_handler= 0;
if (!table->s->tmp_table)
{
/* Non temporary table. */
@@ -170,15 +217,17 @@ static void mysql_ha_close_table(SQL_HANDLER *handler)
}
table->file->ha_index_or_rnd_end();
- table->open_by_handler= 0;
close_thread_table(thd, &table);
+ if (current_table_list)
+ mysql_ha_close_childs(thd, current_table_list, &next_global);
thd->mdl_context.release_lock(handler->mdl_request.ticket);
}
else
{
/* Must be a temporary table */
table->file->ha_index_or_rnd_end();
- table->open_by_handler= 0;
+ if (current_table_list)
+ mysql_ha_close_childs(thd, current_table_list, &next_global);
thd->mark_tmp_table_as_free_for_reuse(table);
}
my_free(handler->lock);
@@ -217,7 +266,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
Query_arena backup_arena;
DBUG_ENTER("mysql_ha_open");
DBUG_PRINT("enter",("'%s'.'%s' as '%s' reopen: %d",
- tables->db, tables->table_name, tables->alias,
+ tables->db.str, tables->table_name.str, tables->alias.str,
reopen != 0));
if (thd->locked_tables_mode)
@@ -249,12 +298,12 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
}
else if (! reopen) /* Otherwise we have 'tables' already. */
{
- if (my_hash_search(&thd->handler_tables_hash, (uchar*) tables->alias,
- strlen(tables->alias) + 1))
+ if (my_hash_search(&thd->handler_tables_hash, (uchar*) tables->alias.str,
+ tables->alias.length + 1))
{
- DBUG_PRINT("info",("duplicate '%s'", tables->alias));
+ DBUG_PRINT("info",("duplicate '%s'", tables->alias.str));
DBUG_PRINT("exit",("ERROR"));
- my_error(ER_NONUNIQ_TABLE, MYF(0), tables->alias);
+ my_error(ER_NONUNIQ_TABLE, MYF(0), tables->alias.str);
DBUG_RETURN(TRUE);
}
}
@@ -281,7 +330,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
right from the start as open_tables() can't handle properly
back-off for such locks.
*/
- tables->mdl_request.init(MDL_key::TABLE, tables->db, tables->table_name,
+ tables->mdl_request.init(MDL_key::TABLE, tables->db.str, tables->table_name.str,
MDL_SHARED_READ, MDL_TRANSACTION);
mdl_savepoint= thd->mdl_context.mdl_savepoint();
@@ -309,29 +358,39 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
goto err;
}
- if (tables->mdl_request.ticket &&
- thd->mdl_context.has_lock(mdl_savepoint, tables->mdl_request.ticket))
+ DBUG_PRINT("info",("clone_tickets start"));
+ for (TABLE_LIST *table_list= tables; table_list;
+ table_list= table_list->next_global)
+ {
+ DBUG_PRINT("info",("table_list %s.%s", table_list->table->s->db.str,
+ table_list->table->s->table_name.str));
+ if (table_list->mdl_request.ticket &&
+ thd->mdl_context.has_lock(mdl_savepoint, table_list->mdl_request.ticket))
{
+ DBUG_PRINT("info",("clone_tickets"));
/* The ticket returned is within a savepoint. Make a copy. */
- error= thd->mdl_context.clone_ticket(&tables->mdl_request);
- tables->table->mdl_ticket= tables->mdl_request.ticket;
+ error= thd->mdl_context.clone_ticket(&table_list->mdl_request);
+ table_list->table->mdl_ticket= table_list->mdl_request.ticket;
if (error)
goto err;
}
+ }
+ DBUG_PRINT("info",("clone_tickets end"));
if (! reopen)
{
/* copy data to sql_handler */
if (!(sql_handler= new SQL_HANDLER(thd)))
goto err;
- init_alloc_root(&sql_handler->mem_root, 1024, 0, MYF(MY_THREAD_SPECIFIC));
+ init_alloc_root(&sql_handler->mem_root, "sql_handler", 1024, 0,
+ MYF(MY_THREAD_SPECIFIC));
- sql_handler->db.length= strlen(tables->db);
- sql_handler->table_name.length= strlen(tables->table_name);
- sql_handler->handler_name.length= strlen(tables->alias);
+ sql_handler->db.length= tables->db.length;
+ sql_handler->table_name.length= tables->table_name.length;
+ sql_handler->handler_name.length= tables->alias.length;
if (!(my_multi_malloc(MY_WME,
- &sql_handler->db.str,
+ &sql_handler->base_data,
(uint) sql_handler->db.length + 1,
&sql_handler->table_name.str,
(uint) sql_handler->table_name.length + 1,
@@ -339,12 +398,12 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
(uint) sql_handler->handler_name.length + 1,
NullS)))
goto err;
- sql_handler->base_data= sql_handler->db.str; // Free this
- memcpy(sql_handler->db.str, tables->db, sql_handler->db.length +1);
- memcpy(sql_handler->table_name.str, tables->table_name,
- sql_handler->table_name.length+1);
- memcpy(sql_handler->handler_name.str, tables->alias,
- sql_handler->handler_name.length +1);
+ sql_handler->db.str= sql_handler->base_data;
+ memcpy((char*) sql_handler->db.str, tables->db.str, tables->db.length +1);
+ memcpy((char*) sql_handler->table_name.str, tables->table_name.str,
+ tables->table_name.length+1);
+ memcpy((char*) sql_handler->handler_name.str, tables->alias.str,
+ tables->alias.length +1);
/* add to hash */
if (my_hash_insert(&thd->handler_tables_hash, (uchar*) sql_handler))
@@ -378,26 +437,37 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
/* Restore the state. */
thd->set_open_tables(backup_open_tables);
+ DBUG_PRINT("info",("set_lock_duration start"));
if (sql_handler->mdl_request.ticket)
{
thd->mdl_context.set_lock_duration(sql_handler->mdl_request.ticket,
MDL_EXPLICIT);
thd->mdl_context.set_needs_thr_lock_abort(TRUE);
}
+ for (TABLE_LIST *table_list= tables->next_global; table_list;
+ table_list= table_list->next_global)
+ {
+ DBUG_PRINT("info",("table_list %s.%s", table_list->table->s->db.str,
+ table_list->table->s->table_name.str));
+ if (table_list->mdl_request.ticket)
+ {
+ thd->mdl_context.set_lock_duration(table_list->mdl_request.ticket,
+ MDL_EXPLICIT);
+ thd->mdl_context.set_needs_thr_lock_abort(TRUE);
+ }
+ }
+ DBUG_PRINT("info",("set_lock_duration end"));
/*
- Assert that the above check prevents opening of views and merge tables.
- For temporary tables, TABLE::next can be set even if only one table
- was opened for HANDLER as it is used to link them together.
- */
- DBUG_ASSERT(sql_handler->table->next == NULL ||
- sql_handler->table->s->tmp_table);
- /*
If it's a temp table, don't reset table->query_id as the table is
being used by this handler. For non-temp tables we use this flag
in asserts.
*/
- table->open_by_handler= 1;
+ for (TABLE_LIST *table_list= tables; table_list;
+ table_list= table_list->next_global)
+ {
+ table_list->table->open_by_handler= 1;
+ }
/* Safety, cleanup the pointer to satisfy MDL assertions. */
tables->mdl_request.ticket= NULL;
@@ -451,7 +521,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
SQL_HANDLER *handler;
DBUG_ENTER("mysql_ha_close");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
- tables->db, tables->table_name, tables->alias));
+ tables->db.str, tables->table_name.str, tables->alias.str));
if (thd->locked_tables_mode)
{
@@ -460,15 +530,15 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
}
if ((my_hash_inited(&thd->handler_tables_hash)) &&
(handler= (SQL_HANDLER*) my_hash_search(&thd->handler_tables_hash,
- (uchar*) tables->alias,
- strlen(tables->alias) + 1)))
+ (const uchar*) tables->alias.str,
+ tables->alias.length + 1)))
{
mysql_ha_close_table(handler);
my_hash_delete(&thd->handler_tables_hash, (uchar*) handler);
}
else
{
- my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias, "HANDLER");
+ my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias.str, "HANDLER");
DBUG_PRINT("exit",("ERROR"));
DBUG_RETURN(TRUE);
}
@@ -495,13 +565,13 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
@return handler
*/
-SQL_HANDLER *mysql_ha_find_handler(THD *thd, const char *name)
+static SQL_HANDLER *mysql_ha_find_handler(THD *thd, const LEX_CSTRING *name)
{
SQL_HANDLER *handler;
if ((my_hash_inited(&thd->handler_tables_hash)) &&
(handler= (SQL_HANDLER*) my_hash_search(&thd->handler_tables_hash,
- (uchar*) name,
- strlen(name) + 1)))
+ (const uchar*) name->str,
+ name->length + 1)))
{
DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' table: %p",
handler->db.str,
@@ -511,9 +581,8 @@ SQL_HANDLER *mysql_ha_find_handler(THD *thd, const char *name)
{
/* The handler table has been closed. Re-open it. */
TABLE_LIST tmp;
- tmp.init_one_table(handler->db.str, handler->db.length,
- handler->table_name.str, handler->table_name.length,
- handler->handler_name.str, TL_READ);
+ tmp.init_one_table(&handler->db, &handler->table_name,
+ &handler->handler_name, TL_READ);
if (mysql_ha_open(thd, &tmp, handler))
{
@@ -524,7 +593,7 @@ SQL_HANDLER *mysql_ha_find_handler(THD *thd, const char *name)
}
else
{
- my_error(ER_UNKNOWN_TABLE, MYF(0), name, "HANDLER");
+ my_error(ER_UNKNOWN_TABLE, MYF(0), name->str, "HANDLER");
return 0;
}
return handler;
@@ -687,7 +756,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
MDL_deadlock_and_lock_abort_error_handler sql_handler_lock_error;
DBUG_ENTER("mysql_ha_read");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
- tables->db, tables->table_name, tables->alias));
+ tables->db.str, tables->table_name.str, tables->alias.str));
if (thd->locked_tables_mode)
{
@@ -696,7 +765,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
}
retry:
- if (!(handler= mysql_ha_find_handler(thd, tables->alias)))
+ if (!(handler= mysql_ha_find_handler(thd, &tables->alias)))
goto err0;
table= handler->table;
@@ -707,8 +776,14 @@ retry:
{
int lock_error;
- if (handler->lock->lock_count > 0)
- handler->lock->locks[0]->type= handler->lock->locks[0]->org_type;
+ THR_LOCK_DATA **pos,**end;
+ for (pos= handler->lock->locks,
+ end= handler->lock->locks + handler->lock->lock_count;
+ pos < end;
+ pos++)
+ {
+ pos[0]->type= pos[0]->org_type;
+ }
/* save open_tables state */
TABLE* backup_open_tables= thd->open_tables;
@@ -875,7 +950,7 @@ retry:
if (error != HA_ERR_RECORD_CHANGED && error != HA_ERR_WRONG_COMMAND)
sql_print_error("mysql_ha_read: Got error %d when reading "
"table '%s'",
- error, tables->table_name);
+ error, tables->table_name.str);
table->file->print_error(error,MYF(0));
table->file->ha_index_or_rnd_end();
goto err;
@@ -932,7 +1007,7 @@ SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables,
{
SQL_HANDLER *handler;
DBUG_ENTER("mysql_ha_read_prepare");
- if (!(handler= mysql_ha_find_handler(thd, tables->alias)))
+ if (!(handler= mysql_ha_find_handler(thd, &tables->alias)))
DBUG_RETURN(0);
tables->table= handler->table; // This is used by fix_fields
if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 1))
@@ -968,7 +1043,7 @@ static SQL_HANDLER *mysql_ha_find_match(THD *thd, TABLE_LIST *tables)
{
if (tables->is_anonymous_derived_table())
continue;
- if ((! *tables->db ||
+ if ((! tables->db.str[0] ||
! my_strcasecmp(&my_charset_latin1, hash_tables->db.str,
tables->get_db_name())) &&
! my_strcasecmp(&my_charset_latin1, hash_tables->table_name.str,
diff --git a/sql/sql_handler.h b/sql/sql_handler.h
index cb1aff1d727..ffefec91fad 100644
--- a/sql/sql_handler.h
+++ b/sql/sql_handler.h
@@ -31,9 +31,9 @@ public:
TABLE *table;
List<Item> fields; /* Fields, set on open */
THD *thd;
- LEX_STRING handler_name;
- LEX_STRING db;
- LEX_STRING table_name;
+ LEX_CSTRING handler_name;
+ LEX_CSTRING db;
+ LEX_CSTRING table_name;
MEM_ROOT mem_root;
MYSQL_LOCK *lock;
MDL_request mdl_request;
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index 4ccaa6a055f..da38a2caf94 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -645,7 +645,7 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond,
# created SQL_SELECT
*/
-SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen,
+SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, size_t mlen,
TABLE_LIST *tables, TABLE *table,
Field *pfname, int *error)
{
@@ -654,7 +654,7 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen,
Item_func_like(thd,
new (mem_root)
Item_field(thd, pfname),
- new (mem_root) Item_string(thd, mask, mlen,
+ new (mem_root) Item_string(thd, mask, (uint)mlen,
pfname->charset()),
new (mem_root) Item_string_ascii(thd, "\\"),
FALSE);
@@ -686,23 +686,19 @@ static bool mysqld_help_internal(THD *thd, const char *mask)
List<String> topics_list, categories_list, subcategories_list;
String name, description, example;
int count_topics, count_categories, error;
- uint mlen= strlen(mask);
+ size_t mlen= strlen(mask);
size_t i;
MEM_ROOT *mem_root= thd->mem_root;
+ LEX_CSTRING MYSQL_HELP_TOPIC_NAME= {STRING_WITH_LEN("help_topic") };
+ LEX_CSTRING MYSQL_HELP_CATEGORY_NAME= {STRING_WITH_LEN("help_category") };
+ LEX_CSTRING MYSQL_HELP_RELATION_NAME= {STRING_WITH_LEN("help_relation") };
+ LEX_CSTRING MYSQL_HELP_KEYWORD_NAME= {STRING_WITH_LEN("help_keyword") };
DBUG_ENTER("mysqld_help");
- tables[0].init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("help_topic"),
- "help_topic", TL_READ);
- tables[1].init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("help_category"),
- "help_category", TL_READ);
- tables[2].init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("help_relation"),
- "help_relation", TL_READ);
- tables[3].init_one_table(C_STRING_WITH_LEN("mysql"),
- C_STRING_WITH_LEN("help_keyword"),
- "help_keyword", TL_READ);
+ tables[0].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_TOPIC_NAME, 0, TL_READ);
+ tables[1].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_CATEGORY_NAME, 0, TL_READ);
+ tables[2].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_RELATION_NAME, 0, TL_READ);
+ tables[3].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_KEYWORD_NAME, 0, TL_READ);
tables[0].next_global= tables[0].next_local=
tables[0].next_name_resolution_table= &tables[1];
tables[1].next_global= tables[1].next_local=
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 32695a450c4..809c649a5d1 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2017, MariaDB
+ Copyright (c) 2010, 2018, 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
@@ -168,9 +168,9 @@ static bool check_view_single_update(List<Item> &fields, List<Item> *values,
if (!tbl->single_table_updatable())
{
if (insert)
- my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT");
+ my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias.str, "INSERT");
else
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "UPDATE");
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias.str, "UPDATE");
return TRUE;
}
*map= tables;
@@ -210,7 +210,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
if (!table_list->single_table_updatable())
{
- my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT");
+ my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias.str, "INSERT");
DBUG_RETURN(-1);
}
@@ -222,7 +222,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
table_list->view_db.str, table_list->view_name.str);
DBUG_RETURN(-1);
}
- if (values.elements != table->s->fields)
+ if (values.elements != table->s->visible_fields)
{
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
DBUG_RETURN(-1);
@@ -304,7 +304,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
(table_list->view &&
check_view_insertability(thd, table_list)))
{
- my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT");
+ my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias.str, "INSERT");
DBUG_RETURN(-1);
}
@@ -676,6 +676,12 @@ static void save_insert_query_plan(THD* thd, TABLE_LIST *table_list)
}
+Field **TABLE::field_to_fill()
+{
+ return triggers && triggers->nullable_fields() ? triggers->nullable_fields() : field;
+}
+
+
/**
INSERT statement implementation
@@ -736,11 +742,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
*/
if (table_list->lock_type == TL_WRITE_DELAYED &&
thd->locked_tables_mode &&
- find_locked_table(thd->open_tables, table_list->db,
- table_list->table_name))
+ find_locked_table(thd->open_tables, table_list->db.str,
+ table_list->table_name.str))
{
my_error(ER_DELAYED_INSERT_TABLE_LOCKED, MYF(0),
- table_list->table_name);
+ table_list->table_name.str);
DBUG_RETURN(TRUE);
}
/*
@@ -980,7 +986,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
No field list, all fields are set explicitly:
INSERT INTO t1 VALUES (values)
*/
- if (thd->lex->used_tables) // Column used in values()
+ if (thd->lex->used_tables || // Column used in values()
+ table->s->visible_fields != table->s->fields)
restore_record(table,s->default_values); // Get empty record
else
{
@@ -1138,8 +1145,10 @@ values_loop_end:
}
else
errcode= query_error_code(thd, thd->killed == NOT_KILLED);
-
- /* bug#22725:
+
+ ScopedStatementReplication scoped_stmt_rpl(
+ table->versioned(VERS_TRX_ID) ? thd : NULL);
+ /* bug#22725:
A query which per-row-loop can not be interrupted with
KILLED, like INSERT, and that does not invoke stored
@@ -1290,7 +1299,7 @@ static bool check_view_insertability(THD * thd, TABLE_LIST *view)
uint used_fields_buff_size= bitmap_buffer_size(table->s->fields);
uint32 *used_fields_buff= (uint32*)thd->alloc(used_fields_buff_size);
MY_BITMAP used_fields;
- enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
+ enum_column_usage saved_column_usage= thd->column_usage;
DBUG_ENTER("check_key_in_view");
if (!used_fields_buff)
@@ -1306,20 +1315,20 @@ static bool check_view_insertability(THD * thd, TABLE_LIST *view)
we must not set query_id for fields as they're not
really used in this context
*/
- thd->mark_used_columns= MARK_COLUMNS_NONE;
+ thd->column_usage= COLUMNS_WRITE;
/* check simplicity and prepare unique test of view */
for (trans= trans_start; trans != trans_end; trans++)
{
if (!trans->item->fixed && trans->item->fix_fields(thd, &trans->item))
{
- thd->mark_used_columns= save_mark_used_columns;
+ thd->column_usage= saved_column_usage;
DBUG_RETURN(TRUE);
}
Item_field *field;
/* simple SELECT list entry (field without expression) */
if (!(field= trans->item->field_for_view_update()))
{
- thd->mark_used_columns= save_mark_used_columns;
+ thd->column_usage= saved_column_usage;
DBUG_RETURN(TRUE);
}
if (field->field->unireg_check == Field::NEXT_NUMBER)
@@ -1331,7 +1340,7 @@ static bool check_view_insertability(THD * thd, TABLE_LIST *view)
*/
trans->item= field;
}
- thd->mark_used_columns= save_mark_used_columns;
+ thd->column_usage= saved_column_usage;
/* unique test */
for (trans= trans_start; trans != trans_end; trans++)
{
@@ -1372,7 +1381,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
if (!table_list->single_table_updatable())
{
- my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT");
+ my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias.str, "INSERT");
DBUG_RETURN(TRUE);
}
/*
@@ -1559,6 +1568,13 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
if (!table)
table= table_list->table;
+ if (table->versioned(VERS_TIMESTAMP) && duplic == DUP_REPLACE)
+ {
+ // Additional memory may be required to create historical items.
+ if (table_list->set_insert_values(thd->mem_root))
+ DBUG_RETURN(TRUE);
+ }
+
if (!select_insert)
{
Item *fake_conds= 0;
@@ -1610,6 +1626,29 @@ static int last_uniq_key(TABLE *table,uint keynr)
/*
+ Inserts one historical row to a table.
+
+ Copies content of the row from table->record[1] to table->record[0],
+ sets Sys_end to now() and calls ha_write_row() .
+*/
+
+int vers_insert_history_row(TABLE *table)
+{
+ DBUG_ASSERT(table->versioned(VERS_TIMESTAMP));
+ restore_record(table,record[1]);
+
+ // Set Sys_end to now()
+ table->vers_update_end();
+
+ Field *row_start= table->vers_start_field();
+ Field *row_end= table->vers_end_field();
+ if (row_start->cmp(row_start->ptr, row_end->ptr) >= 0)
+ return 0;
+
+ return table->file->ha_write_row(table->record[0]);
+}
+
+/*
Write a record to table with optional deleting of conflicting records,
invoke proper triggers if needed.
@@ -1813,7 +1852,26 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
}
if (error != HA_ERR_RECORD_IS_THE_SAME)
+ {
info->updated++;
+ if (table->versioned())
+ {
+ if (table->versioned(VERS_TIMESTAMP))
+ {
+ store_record(table, record[2]);
+ if ((error= vers_insert_history_row(table)))
+ {
+ info->last_errno= error;
+ table->file->print_error(error, MYF(0));
+ trg_error= 1;
+ restore_record(table, record[2]);
+ goto ok_or_after_trg_err;
+ }
+ restore_record(table, record[2]);
+ }
+ info->copied++;
+ }
+ }
else
error= 0;
/*
@@ -1865,17 +1923,35 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
tables which have ON UPDATE but have no ON DELETE triggers,
we just should not expose this fact to users by invoking
ON UPDATE triggers.
- */
- if (last_uniq_key(table,key_nr) &&
- !table->file->referenced_by_foreign_key() &&
+ For system versioning wa also use path through delete since we would
+ save nothing through this cheating.
+ */
+ if (last_uniq_key(table,key_nr) &&
+ !table->file->referenced_by_foreign_key() &&
(!table->triggers || !table->triggers->has_delete_triggers()))
{
+ if (table->versioned(VERS_TRX_ID))
+ {
+ bitmap_set_bit(table->write_set, table->vers_start_field()->field_index);
+ table->vers_start_field()->set_notnull();
+ table->vers_start_field()->store(0, false);
+ }
if ((error=table->file->ha_update_row(table->record[1],
- table->record[0])) &&
+ table->record[0])) &&
error != HA_ERR_RECORD_IS_THE_SAME)
goto err;
if (error != HA_ERR_RECORD_IS_THE_SAME)
+ {
info->deleted++;
+ if (table->versioned(VERS_TIMESTAMP))
+ {
+ store_record(table, record[2]);
+ error= vers_insert_history_row(table);
+ restore_record(table, record[2]);
+ if (error)
+ goto err;
+ }
+ }
else
error= 0;
thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row);
@@ -1891,9 +1967,25 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, TRUE))
goto before_trg_err;
- if ((error=table->file->ha_delete_row(table->record[1])))
+
+ if (!table->versioned(VERS_TIMESTAMP))
+ error= table->file->ha_delete_row(table->record[1]);
+ else
+ {
+ DBUG_ASSERT(table->insert_values);
+ store_record(table,insert_values);
+ restore_record(table,record[1]);
+ table->vers_update_end();
+ error= table->file->ha_update_row(table->record[1],
+ table->record[0]);
+ restore_record(table,insert_values);
+ }
+ if (error)
goto err;
- info->deleted++;
+ if (!table->versioned(VERS_TIMESTAMP))
+ info->deleted++;
+ else
+ info->updated++;
if (!table->file->has_transactions())
thd->transaction.stmt.modified_non_trans_table= TRUE;
if (table->triggers &&
@@ -1981,7 +2073,9 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry, TABLE_LIST *t
for (Field **field=entry->field ; *field ; field++)
{
if (!bitmap_is_set(write_set, (*field)->field_index) &&
- has_no_default_value(thd, *field, table_list))
+ !(*field)->vers_sys_field() &&
+ has_no_default_value(thd, *field, table_list) &&
+ ((*field)->real_type() != MYSQL_TYPE_ENUM))
err=1;
}
return thd->abort_on_warning ? err : 0;
@@ -2173,8 +2267,8 @@ Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list)
Delayed_insert *di;
while ((di= it++))
{
- if (!strcmp(table_list->db, di->table_list.db) &&
- !strcmp(table_list->table_name, di->table_list.table_name))
+ if (!cmp(&table_list->db, &di->table_list.db) &&
+ !cmp(&table_list->table_name, &di->table_list.table_name))
{
di->lock();
break;
@@ -2238,7 +2332,7 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
DBUG_ENTER("delayed_get_table");
/* Must be set in the parser */
- DBUG_ASSERT(table_list->db);
+ DBUG_ASSERT(table_list->db.str);
/* Find the thread which handles this table. */
if (!(di= find_handler(thd, table_list)))
@@ -2265,11 +2359,12 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
*/
di->thd.variables.binlog_annotate_row_events= 0;
- di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
- di->thd.set_query(my_strdup(table_list->table_name,
- MYF(MY_WME | ME_FATALERROR)),
- 0, system_charset_info);
- if (di->thd.db == NULL || di->thd.query() == NULL)
+ di->thd.set_db(&table_list->db);
+ di->thd.set_query(my_strndup(table_list->table_name.str,
+ table_list->table_name.length,
+ MYF(MY_WME | ME_FATALERROR)),
+ table_list->table_name.length, system_charset_info);
+ if (di->thd.db.str == NULL || di->thd.query() == NULL)
{
/* The error is reported */
delete di;
@@ -2277,7 +2372,8 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
}
di->table_list= *table_list; // Needed to open table
/* Replace volatile strings with local copies */
- di->table_list.alias= di->table_list.table_name= di->thd.query();
+ di->table_list.alias.str= di->table_list.table_name.str= di->thd.query();
+ di->table_list.alias.length= di->table_list.table_name.length= di->thd.query_length();
di->table_list.db= di->thd.db;
/* We need the tickets so that they can be cloned in handle_delayed_insert */
di->grl_protection.init(MDL_key::GLOBAL, "", "",
@@ -2423,8 +2519,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
The thread could be killed with an error message if
di->handle_inserts() or di->open_and_lock_table() fails.
The thread could be killed without an error message if
- killed using mysql_notify_thread_having_shared_lock() or
- kill_delayed_threads_for_table().
+ killed using kill_delayed_threads_for_table().
*/
if (!thd.is_error())
my_message(ER_QUERY_INTERRUPTED, ER_THD(&thd, ER_QUERY_INTERRUPTED),
@@ -2702,9 +2797,9 @@ void kill_delayed_threads(void)
Delayed_insert *di;
while ((di= it++))
{
- mysql_mutex_lock(&di->thd.LOCK_thd_data);
+ mysql_mutex_lock(&di->thd.LOCK_thd_kill);
if (di->thd.killed < KILL_CONNECTION)
- di->thd.set_killed(KILL_CONNECTION);
+ di->thd.set_killed_no_mutex(KILL_CONNECTION);
if (di->thd.mysys_var)
{
mysql_mutex_lock(&di->thd.mysys_var->mutex);
@@ -2722,7 +2817,7 @@ void kill_delayed_threads(void)
}
mysql_mutex_unlock(&di->thd.mysys_var->mutex);
}
- mysql_mutex_unlock(&di->thd.LOCK_thd_data);
+ mysql_mutex_unlock(&di->thd.LOCK_thd_kill);
}
mysql_mutex_unlock(&LOCK_delayed_insert); // For unlink from list
DBUG_VOID_RETURN;
@@ -2760,7 +2855,7 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx,
if (!(table_list->table->file->ha_table_flags() & HA_CAN_INSERT_DELAYED))
{
- my_error(ER_DELAYED_NOT_SUPPORTED, MYF(0), table_list->table_name);
+ my_error(ER_DELAYED_NOT_SUPPORTED, MYF(0), table_list->table_name.str);
return TRUE;
}
return FALSE;
@@ -2845,7 +2940,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
pthread_detach_this_thread();
/* Add thread to THD list so that's it's visible in 'show processlist' */
- thd->set_current_time();
+ thd->set_start_time();
add_to_active_threads(thd);
if (abort_loop)
thd->set_killed(KILL_CONNECTION);
@@ -3076,9 +3171,9 @@ pthread_handler_t handle_delayed_insert(void *arg)
this.
*/
mysql_mutex_lock(&thd->LOCK_thd_data);
- thd->set_killed(KILL_CONNECTION_HARD); // If error
thd->mdl_context.set_needs_thr_lock_abort(0);
mysql_mutex_unlock(&thd->LOCK_thd_data);
+ thd->set_killed(KILL_CONNECTION_HARD); // If error
close_thread_tables(thd); // Free the table
thd->mdl_context.release_transactional_locks();
@@ -3499,7 +3594,8 @@ select_insert::select_insert(THD *thd_arg, TABLE_LIST *table_list_par,
select_result_interceptor(thd_arg),
table_list(table_list_par), table(table_par), fields(fields_par),
autoinc_value_of_last_inserted_row(0),
- insert_into_view(table_list_par && table_list_par->view != 0)
+ insert_into_view(table_list_par && table_list_par->view != 0),
+ versioned_write(false)
{
bzero((char*) &info,sizeof(info));
info.handle_duplicates= duplic;
@@ -3534,6 +3630,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
check_insert_fields(thd, table_list, *fields, values,
!insert_into_view, 1, &map));
+ versioned_write= table_list->table->versioned();
+
if (!res && fields->elements)
{
bool saved_abort_on_warning= thd->abort_on_warning;
@@ -3746,6 +3844,7 @@ int select_insert::send_data(List<Item> &values)
table->auto_increment_field_not_null= FALSE;
DBUG_RETURN(1);
}
+ table->vers_write= versioned_write;
if (table_list) // Not CREATE ... SELECT
{
switch (table_list->view_check_option(thd, info.ignore)) {
@@ -3757,6 +3856,7 @@ int select_insert::send_data(List<Item> &values)
}
error= write_record(thd, table, &info);
+ table->vers_write= table->versioned();
table->auto_increment_field_not_null= FALSE;
if (!error)
@@ -3795,12 +3895,16 @@ int select_insert::send_data(List<Item> &values)
void select_insert::store_values(List<Item> &values)
{
+ DBUG_ENTER("select_insert::store_values");
+
if (fields->elements)
fill_record_n_invoke_before_triggers(thd, table, *fields, values, 1,
TRG_EVENT_INSERT);
else
fill_record_n_invoke_before_triggers(thd, table, table->field_to_fill(),
values, 1, TRG_EVENT_INSERT);
+
+ DBUG_VOID_RETURN;
}
bool select_insert::prepare_eof()
@@ -4026,10 +4130,7 @@ Field *Item::create_field_for_create_select(TABLE *table)
@retval 0 Error
*/
-static TABLE *create_table_from_items(THD *thd,
- Table_specification_st *create_info,
- TABLE_LIST *create_table,
- Alter_info *alter_info,
+TABLE *select_create::create_table_from_items(THD *thd,
List<Item> *items,
MYSQL_LOCK **lock,
TABLEOP_HOOKS *hooks)
@@ -4090,6 +4191,12 @@ static TABLE *create_table_from_items(THD *thd,
alter_info->create_list.push_back(cr_field, thd->mem_root);
}
+ if (create_info->vers_fix_system_fields(thd, alter_info, *create_table,
+ select_tables, items, &versioned_write))
+ {
+ DBUG_RETURN(NULL);
+ }
+
DEBUG_SYNC(thd,"create_table_select_before_create");
/* Check if LOCK TABLES + CREATE OR REPLACE of existing normal table*/
@@ -4119,8 +4226,8 @@ static TABLE *create_table_from_items(THD *thd,
open_table().
*/
- if (!mysql_create_table_no_lock(thd, create_table->db,
- create_table->table_name,
+ if (!mysql_create_table_no_lock(thd, &create_table->db,
+ &create_table->table_name,
create_info, alter_info, NULL,
select_field_count, create_table))
{
@@ -4146,8 +4253,8 @@ static TABLE *create_table_from_items(THD *thd,
*/
if (open_table(thd, create_table, &ot_ctx))
{
- quick_rm_table(thd, create_info->db_type, create_table->db,
- table_case_name(create_info, create_table->table_name),
+ quick_rm_table(thd, create_info->db_type, &create_table->db,
+ table_case_name(create_info, &create_table->table_name),
0);
}
/* Restore */
@@ -4204,7 +4311,7 @@ static TABLE *create_table_from_items(THD *thd,
mysql_unlock_tables(thd, *lock);
*lock= 0;
}
- drop_open_table(thd, table, create_table->db, create_table->table_name);
+ drop_open_table(thd, table, &create_table->db, &create_table->table_name);
DBUG_RETURN(0);
/* purecov: end */
}
@@ -4213,8 +4320,9 @@ static TABLE *create_table_from_items(THD *thd,
int
-select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
+select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
{
+ List<Item> values(_values, thd->mem_root);
MYSQL_LOCK *extra_lock= NULL;
DBUG_ENTER("select_create::prepare");
@@ -4296,10 +4404,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
DEBUG_SYNC(thd,"create_table_select_before_check_if_exists");
- if (!(table= create_table_from_items(thd, create_info,
- create_table,
- alter_info, &values,
- &extra_lock, hook_ptr)))
+ if (!(table= create_table_from_items(thd, &values, &extra_lock, hook_ptr)))
/* abort() deletes table */
DBUG_RETURN(-1);
@@ -4594,16 +4699,14 @@ void select_create::abort_result_set()
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
table->auto_increment_field_not_null= FALSE;
- drop_open_table(thd, table, create_table->db, create_table->table_name);
+ drop_open_table(thd, table, &create_table->db, &create_table->table_name);
table=0; // Safety
if (thd->log_current_statement && mysql_bin_log.is_open())
{
/* Remove logging of drop, create + insert rows */
binlog_reset_cache(thd);
/* Original table was deleted. We have to log it */
- log_drop_table(thd, create_table->db, create_table->db_length,
- create_table->table_name, create_table->table_name_length,
- tmp_table);
+ log_drop_table(thd, &create_table->db, &create_table->table_name, tmp_table);
}
}
DBUG_VOID_RETURN;
diff --git a/sql/sql_insert.h b/sql/sql_insert.h
index aea0dac6b0d..6efd680d188 100644
--- a/sql/sql_insert.h
+++ b/sql/sql_insert.h
@@ -37,6 +37,7 @@ void upgrade_lock_type_for_insert(THD *thd, thr_lock_type *lock_type,
bool is_multi_insert);
int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
TABLE_LIST *table_list);
+int vers_insert_history_row(TABLE *table);
int write_record(THD *thd, TABLE *table, COPY_INFO *info);
void kill_delayed_threads(void);
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index 6df92f13585..fb8660aa79d 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -394,7 +394,7 @@ void JOIN_CACHE::create_flag_fields()
TABLE *table= tab->table;
/* Create a field for the null bitmap from table if needed */
- if (tab->used_null_fields || tab->used_uneven_bit_fields)
+ if (tab->used_null_fields || tab->used_uneven_bit_fields)
length+= add_flag_field_to_join_cache(table->null_flags,
table->s->null_bytes,
&copy);
@@ -765,7 +765,7 @@ uint JOIN_CACHE::get_record_max_affix_length()
The minimal possible size of the join buffer of this cache
*/
-ulong JOIN_CACHE::get_min_join_buffer_size()
+size_t JOIN_CACHE::get_min_join_buffer_size()
{
if (!min_buff_size)
{
@@ -824,7 +824,7 @@ ulong JOIN_CACHE::get_min_join_buffer_size()
The maximum possible size of the join buffer of this cache
*/
-ulong JOIN_CACHE::get_max_join_buffer_size(bool optimize_buff_size)
+size_t JOIN_CACHE::get_max_join_buffer_size(bool optimize_buff_size)
{
if (!max_buff_size)
{
@@ -933,9 +933,9 @@ int JOIN_CACHE::alloc_buffer()
if (for_explain_only)
return 0;
- for (ulong buff_size_decr= (buff_size-min_buff_size)/4 + 1; ; )
+ for (size_t buff_size_decr= (buff_size-min_buff_size)/4 + 1; ; )
{
- ulong next_buff_size;
+ size_t next_buff_size;
if ((buff= (uchar*) my_malloc(buff_size, MYF(MY_THREAD_SPECIFIC))))
break;
@@ -1701,7 +1701,7 @@ enum JOIN_CACHE::Match_flag JOIN_CACHE::get_match_flag_by_pos(uchar *rec_ptr)
the number of bytes in the increment
*/
-uint JOIN_CACHE::aux_buffer_incr(ulong recno)
+uint JOIN_CACHE::aux_buffer_incr(size_t recno)
{
return join_tab_scan->aux_buffer_incr(recno);
}
@@ -2759,22 +2759,22 @@ int JOIN_CACHE_HASHED::init_hash_table()
size_of_key_ofs + // reference to the next key
(use_emb_key ? get_size_of_rec_offset() : key_length);
- ulong space_per_rec= avg_record_length +
+ size_t space_per_rec= avg_record_length +
avg_aux_buffer_incr +
key_entry_length+size_of_key_ofs;
- uint n= buff_size / space_per_rec;
+ size_t n= buff_size / space_per_rec;
/*
TODO: Make a better estimate for this upper bound of
the number of records in in the join buffer.
*/
- uint max_n= buff_size / (pack_length-length+
+ size_t max_n= buff_size / (pack_length-length+
key_entry_length+size_of_key_ofs);
hash_entries= (uint) (n / 0.7);
set_if_bigger(hash_entries, 1);
- if (offset_size(max_n*key_entry_length) <=
+ if (offset_size((uint)(max_n*key_entry_length)) <=
size_of_key_ofs)
break;
}
@@ -3501,7 +3501,7 @@ bool JOIN_CACHE_BNL::prepare_look_for_matches(bool skip_last)
if (!records)
return TRUE;
reset(FALSE);
- rem_records= records - MY_TEST(skip_last);
+ rem_records= (uint)records - MY_TEST(skip_last);
return rem_records == 0;
}
@@ -3829,7 +3829,7 @@ int JOIN_CACHE_BNLH::init(bool for_explain)
the increment of the size of the MRR buffer for the next record
*/
-uint JOIN_TAB_SCAN_MRR::aux_buffer_incr(ulong recno)
+uint JOIN_TAB_SCAN_MRR::aux_buffer_incr(size_t recno)
{
uint incr= 0;
TABLE_REF *ref= &join_tab->ref;
diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h
index f6894c6727d..c4ba08496d0 100644
--- a/sql/sql_join_cache.h
+++ b/sql/sql_join_cache.h
@@ -107,7 +107,7 @@ protected:
/* 3 functions below actually do not use the hidden parameter 'this' */
/* Calculate the number of bytes used to store an offset value */
- uint offset_size(uint len)
+ uint offset_size(size_t len)
{ return (len < 256 ? 1 : len < 256*256 ? 2 : 4); }
/* Get the offset value that takes ofs_sz bytes at the position ptr */
@@ -420,7 +420,7 @@ protected:
incremented when a new record is added to the join buffer.
If no auxiliary buffer is needed the function should return 0.
*/
- virtual uint aux_buffer_incr(ulong recno);
+ virtual uint aux_buffer_incr(size_t recno);
/* Shall calculate how much space is remaining in the join buffer */
virtual size_t rem_space()
@@ -606,9 +606,9 @@ public:
void set_join_buffer_size(size_t sz) { buff_size= sz; }
/* Get the minimum possible size of the cache join buffer */
- virtual ulong get_min_join_buffer_size();
+ virtual size_t get_min_join_buffer_size();
/* Get the maximum possible size of the cache join buffer */
- virtual ulong get_max_join_buffer_size(bool optimize_buff_size);
+ virtual size_t get_max_join_buffer_size(bool optimize_buff_size);
/* Shrink the size if the cache join buffer in a given ratio */
bool shrink_join_buffer_in_ratio(ulonglong n, ulonglong d);
@@ -1069,7 +1069,7 @@ public:
Shall calculate the increment of the auxiliary buffer for a record
write if such a buffer is used by the table scan object
*/
- virtual uint aux_buffer_incr(ulong recno) { return 0; }
+ virtual uint aux_buffer_incr(size_t recno) { return 0; }
/* Initiate the process of iteration over the joined table */
virtual int open();
@@ -1244,7 +1244,7 @@ public:
JOIN_TAB_SCAN_MRR(JOIN *j, JOIN_TAB *tab, uint flags, RANGE_SEQ_IF rs_funcs)
:JOIN_TAB_SCAN(j, tab), range_seq_funcs(rs_funcs), mrr_mode(flags) {}
- uint aux_buffer_incr(ulong recno);
+ uint aux_buffer_incr(size_t recno);
int open();
@@ -1325,6 +1325,10 @@ public:
JOIN_CACHE_BKA(JOIN *j, JOIN_TAB *tab, uint flags, JOIN_CACHE *prev)
:JOIN_CACHE(j, tab, prev), mrr_mode(flags) {}
+ JOIN_CACHE_BKA(JOIN_CACHE_BKA *bka)
+ :JOIN_CACHE(bka->join, bka->join_tab, bka->prev_cache),
+ mrr_mode(bka->mrr_mode) {}
+
uchar **get_curr_association_ptr() { return &curr_association; }
/* Initialize the BKA cache */
@@ -1421,6 +1425,10 @@ public:
JOIN_CACHE_BKAH(JOIN *j, JOIN_TAB *tab, uint flags, JOIN_CACHE *prev)
:JOIN_CACHE_BNLH(j, tab, prev), mrr_mode(flags) {}
+ JOIN_CACHE_BKAH(JOIN_CACHE_BKAH *bkah)
+ :JOIN_CACHE_BNLH(bkah->join, bkah->join_tab, bkah->prev_cache),
+ mrr_mode(bkah->mrr_mode) {}
+
uchar **get_curr_association_ptr() { return &curr_matching_chain; }
/* Initialize the BKAH cache */
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 3070f2a860b..a2a9e5b2f16 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, MariaDB
+ Copyright (c) 2009, 2018, 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
@@ -33,9 +33,9 @@
#include "sql_signal.h"
-void LEX::parse_error()
+void LEX::parse_error(uint err_number)
{
- thd->parse_error();
+ thd->parse_error(err_number);
}
@@ -196,8 +196,9 @@ init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex)
lex_start(thd);
context->init();
if ((!(table_ident= new Table_ident(thd,
+ &table->s->db,
&table->s->table_name,
- &table->s->db, TRUE))) ||
+ TRUE))) ||
(!(table_list= select_lex->add_table_to_list(thd,
table_ident,
NULL,
@@ -257,7 +258,7 @@ st_parsing_options::reset()
bool Lex_input_stream::init(THD *thd,
char* buff,
- unsigned int length)
+ size_t length)
{
DBUG_EXECUTE_IF("bug42064_simulate_oom",
DBUG_SET("+d,simulate_out_of_memory"););
@@ -268,12 +269,12 @@ bool Lex_input_stream::init(THD *thd,
DBUG_SET("-d,bug42064_simulate_oom"););
if (m_cpp_buf == NULL)
- return TRUE;
+ return true;
m_thd= thd;
reset(buff, length);
- return FALSE;
+ return false;
}
@@ -286,7 +287,7 @@ bool Lex_input_stream::init(THD *thd,
*/
void
-Lex_input_stream::reset(char *buffer, unsigned int length)
+Lex_input_stream::reset(char *buffer, size_t length)
{
yylineno= 1;
yylval= NULL;
@@ -333,7 +334,7 @@ void Lex_input_stream::body_utf8_start(THD *thd, const char *begin_ptr)
DBUG_ASSERT(begin_ptr);
DBUG_ASSERT(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
- uint body_utf8_length= get_body_utf8_maximum_length(thd);
+ size_t body_utf8_length= get_body_utf8_maximum_length(thd);
m_body_utf8= (char *) thd->alloc(body_utf8_length + 1);
m_body_utf8_ptr= m_body_utf8;
@@ -343,7 +344,7 @@ void Lex_input_stream::body_utf8_start(THD *thd, const char *begin_ptr)
}
-uint Lex_input_stream::get_body_utf8_maximum_length(THD *thd)
+size_t Lex_input_stream::get_body_utf8_maximum_length(THD *thd)
{
/*
String literals can grow during escaping:
@@ -674,6 +675,8 @@ void lex_start(THD *thd)
void LEX::start(THD *thd_arg)
{
DBUG_ENTER("LEX::start");
+ DBUG_PRINT("info", ("This: %p thd_arg->lex: %p thd_arg->stmt_lex: %p",
+ this, thd_arg->lex, thd_arg->stmt_lex));
thd= unit.thd= thd_arg;
@@ -681,6 +684,7 @@ void LEX::start(THD *thd_arg)
context_stack.empty();
unit.init_query();
+ current_select_number= 1;
select_lex.linkage= UNSPECIFIED_TYPE;
/* 'parent_lex' is used in init_query() so it must be before it. */
select_lex.parent_lex= this;
@@ -737,6 +741,7 @@ void LEX::start(THD *thd_arg)
spcont= NULL;
proc_list.first= 0;
escape_used= FALSE;
+ default_used= FALSE;
query_tables= 0;
reset_query_tables_list(FALSE);
expr_allows_subselect= TRUE;
@@ -771,6 +776,8 @@ void LEX::start(THD *thd_arg)
frame_bottom_bound= NULL;
win_spec= NULL;
+ vers_conditions.empty();
+
is_lex_started= TRUE;
DBUG_VOID_RETURN;
}
@@ -827,6 +834,7 @@ void lex_end_stage2(LEX *lex)
/* Reset LEX_MASTER_INFO */
lex->mi.reset(lex->sql_command == SQLCOM_CHANGE_MASTER);
+ delete_dynamic(&lex->delete_gtid_domain);
DBUG_VOID_RETURN;
}
@@ -1339,6 +1347,8 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd)
return WITH_CUBE_SYM;
case ROLLUP_SYM:
return WITH_ROLLUP_SYM;
+ case SYSTEM:
+ return WITH_SYSTEM_SYM;
default:
/*
Save the token following 'WITH'
@@ -1349,6 +1359,27 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd)
return WITH;
}
break;
+ case FOR_SYM:
+ /*
+ * Additional look-ahead to resolve doubtful cases like:
+ * SELECT ... FOR UPDATE
+ * SELECT ... FOR SYSTEM_TIME ... .
+ */
+ token= lex_one_token(yylval, thd);
+ lip->add_digest_token(token, yylval);
+ switch(token) {
+ case SYSTEM_TIME_SYM:
+ return FOR_SYSTEM_TIME_SYM;
+ default:
+ /*
+ Save the token following 'FOR_SYM'
+ */
+ lip->lookahead_yylval= lip->yylval;
+ lip->yylval= NULL;
+ lip->lookahead_token= token;
+ return FOR_SYM;
+ }
+ break;
case VALUES:
if (thd->lex->current_select->parsing_place == IN_UPDATE_ON_DUP_KEY ||
thd->lex->current_select->parsing_place == IN_PART_FUNC)
@@ -2123,7 +2154,7 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd)
}
-void trim_whitespace(CHARSET_INFO *cs, LEX_CSTRING *str, uint *prefix_length)
+void trim_whitespace(CHARSET_INFO *cs, LEX_CSTRING *str, size_t * prefix_length)
{
/*
TODO:
@@ -2131,14 +2162,15 @@ void trim_whitespace(CHARSET_INFO *cs, LEX_CSTRING *str, uint *prefix_length)
that can be considered white-space.
*/
- *prefix_length= 0;
+ size_t plen= 0;
while ((str->length > 0) && (my_isspace(cs, str->str[0])))
{
- (*prefix_length)++;
+ plen++;
str->length --;
str->str ++;
}
-
+ if (prefix_length)
+ *prefix_length= plen;
/*
FIXME:
Also, parsing backward is not safe with multi bytes characters
@@ -2244,6 +2276,7 @@ void st_select_lex::init_query()
window_funcs.empty();
tvc= 0;
in_tvc= false;
+ versioned_tables= 0;
}
void st_select_lex::init_select()
@@ -2253,7 +2286,8 @@ void st_select_lex::init_select()
group_list.empty();
if (group_list_ptrs)
group_list_ptrs->clear();
- type= db= 0;
+ type= 0;
+ db= null_clex_str;
having= 0;
table_join_options= 0;
in_sum_expr= with_wild= 0;
@@ -2285,6 +2319,7 @@ void st_select_lex::init_select()
in_funcs.empty();
curr_tvc_name= 0;
in_tvc= false;
+ versioned_tables= 0;
}
/*
@@ -2425,10 +2460,8 @@ void st_select_lex_node::move_as_slave(st_select_lex_node *new_master)
prev= &curr->next;
}
else
- {
prev= &new_master->slave;
- new_master->slave= this;
- }
+ *prev= this;
next= 0;
master= new_master;
}
@@ -3021,10 +3054,9 @@ void Query_tables_list::destroy_query_tables_list()
*/
LEX::LEX()
- : explain(NULL),
- result(0), arena_for_set_stmt(0), mem_root_for_set_stmt(0),
+ : explain(NULL), result(0), arena_for_set_stmt(0), mem_root_for_set_stmt(0),
option_type(OPT_DEFAULT), context_analysis_only(0), sphead(0),
- is_lex_started(0), limit_rows_examined_cnt(ULONGLONG_MAX)
+ default_used(0), is_lex_started(0), limit_rows_examined_cnt(ULONGLONG_MAX)
{
init_dynamic_array2(&plugins, sizeof(plugin_ref), plugins_static_buffer,
@@ -3032,6 +3064,10 @@ LEX::LEX()
INITIAL_LEX_PLUGIN_LIST_SIZE, 0);
reset_query_tables_list(TRUE);
mi.init();
+ init_dynamic_array2(&delete_gtid_domain, sizeof(ulong*),
+ gtid_domain_static_buffer,
+ initial_gtid_domain_buffer_size,
+ initial_gtid_domain_buffer_size, 0);
}
@@ -3257,8 +3293,7 @@ uint8 LEX::get_effective_with_check(TABLE_LIST *view)
case of success
*/
-bool
-LEX::copy_db_to(const char **p_db, size_t *p_db_length) const
+bool LEX::copy_db_to(LEX_CSTRING *to)
{
if (sphead && sphead->m_name.str)
{
@@ -3267,12 +3302,10 @@ LEX::copy_db_to(const char **p_db, size_t *p_db_length) const
It is safe to assign the string by-pointer, both sphead and
its statements reside in the same memory root.
*/
- *p_db= sphead->m_db.str;
- if (p_db_length)
- *p_db_length= sphead->m_db.length;
+ *to= sphead->m_db;
return FALSE;
}
- return thd->copy_db_to(p_db, p_db_length);
+ return thd->copy_db_to(to);
}
/**
@@ -3748,6 +3781,7 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
DBUG_ENTER("st_select_lex::fix_prepare_information");
if (!thd->stmt_arena->is_conventional() && first_execution)
{
+ Query_arena_stmt on_stmt_arena(thd);
first_execution= 0;
if (group_list.first)
{
@@ -3841,7 +3875,7 @@ void st_select_lex::alloc_index_hints (THD *thd)
RETURN VALUE
0 on success, non-zero otherwise
*/
-bool st_select_lex::add_index_hint (THD *thd, const char *str, uint length)
+bool st_select_lex::add_index_hint (THD *thd, const char *str, size_t length)
{
return index_hints->push_front(new (thd->mem_root)
Index_hint(current_index_hint_type,
@@ -4821,8 +4855,8 @@ bool LEX::set_arena_for_set_stmt(Query_arena *backup)
mem_root_for_set_stmt= new MEM_ROOT();
if (!(mem_root_for_set_stmt))
DBUG_RETURN(1);
- init_sql_alloc(mem_root_for_set_stmt, ALLOC_ROOT_SET, ALLOC_ROOT_SET,
- MYF(MY_THREAD_SPECIFIC));
+ init_sql_alloc(mem_root_for_set_stmt, "set_stmt",
+ ALLOC_ROOT_SET, ALLOC_ROOT_SET, MYF(MY_THREAD_SPECIFIC));
}
if (!(arena_for_set_stmt= new(mem_root_for_set_stmt)
Query_arena_memroot(mem_root_for_set_stmt,
@@ -5594,6 +5628,35 @@ sp_variable *LEX::sp_add_for_loop_variable(THD *thd, const LEX_CSTRING *name,
}
+bool LEX::sp_for_loop_implicit_cursor_statement(THD *thd,
+ Lex_for_loop_bounds_st *bounds,
+ sp_lex_cursor *cur)
+{
+ Item *item;
+ DBUG_ASSERT(sphead);
+ LEX_CSTRING name= {STRING_WITH_LEN("[implicit_cursor]") };
+ if (sp_declare_cursor(thd, &name, cur, NULL, true))
+ return true;
+ DBUG_ASSERT(thd->lex == this);
+ if (!(bounds->m_index= new (thd->mem_root) sp_assignment_lex(thd, this)))
+ return true;
+ bounds->m_index->sp_lex_in_use= true;
+ sphead->reset_lex(thd, bounds->m_index);
+ DBUG_ASSERT(thd->lex != this);
+ if (!(item= new (thd->mem_root) Item_field(thd,
+ thd->lex->current_context(),
+ NullS, NullS, &name)))
+ return true;
+ bounds->m_index->set_item_and_free_list(item, NULL);
+ if (thd->lex->sphead->restore_lex(thd))
+ return true;
+ DBUG_ASSERT(thd->lex == this);
+ bounds->m_direction= 1;
+ bounds->m_upper_bound= NULL;
+ bounds->m_implicit_cursor= true;
+ return false;
+}
+
sp_variable *
LEX::sp_add_for_loop_cursor_variable(THD *thd,
const LEX_CSTRING *name,
@@ -5805,7 +5868,7 @@ bool LEX::sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &loop)
{
sp_instr_cfetch *instr=
new (thd->mem_root) sp_instr_cfetch(sphead->instructions(),
- spcont, loop.m_cursor_offset);
+ spcont, loop.m_cursor_offset, false);
if (instr == NULL || sphead->add_instr(instr))
return true;
instr->add_to_varlist(loop.m_index);
@@ -5972,7 +6035,7 @@ sp_name *LEX::make_sp_name(THD *thd, const LEX_CSTRING *name)
sp_name *res;
LEX_CSTRING db;
if (check_routine_name(name) ||
- copy_db_to(&db.str, &db.length) ||
+ copy_db_to(&db) ||
(!(res= new (thd->mem_root) sp_name(&db, name, false))))
return NULL;
return res;
@@ -6452,6 +6515,11 @@ Item *LEX::create_and_link_Item_trigger_field(THD *thd,
Item_param *LEX::add_placeholder(THD *thd, const LEX_CSTRING *name,
const char *start, const char *end)
{
+ if (!thd->m_parser_state->m_lip.stmt_prepare_mode)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, start);
+ return NULL;
+ }
if (!parsing_options.allows_variable)
{
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
@@ -7181,7 +7249,7 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond,
if (no_top_clones)
return cond;
cond->clear_extraction_flag();
- return cond->build_clone(thd, thd->mem_root);
+ return cond->build_clone(thd);
}
if (cond->type() == Item::COND_ITEM)
{
@@ -7267,6 +7335,20 @@ int set_statement_var_if_exists(THD *thd, const char *var_name,
}
+Query_tables_backup::Query_tables_backup(THD* _thd) :
+ thd(_thd)
+{
+ thd->lex->reset_n_backup_query_tables_list(&backup);
+ thd->lex->sql_command= backup.sql_command;
+}
+
+
+Query_tables_backup::~Query_tables_backup()
+{
+ thd->lex->restore_backup_query_tables_list(&backup);
+}
+
+
bool LEX::sp_add_cfetch(THD *thd, const LEX_CSTRING *name)
{
uint offset;
@@ -7278,7 +7360,8 @@ bool LEX::sp_add_cfetch(THD *thd, const LEX_CSTRING *name)
return true;
}
i= new (thd->mem_root)
- sp_instr_cfetch(sphead->instructions(), spcont, offset);
+ sp_instr_cfetch(sphead->instructions(), spcont, offset,
+ !(thd->variables.sql_mode & MODE_ORACLE));
if (i == NULL || sphead->add_instr(i))
return true;
return false;
@@ -7397,3 +7480,24 @@ Item *LEX::make_item_func_replace(THD *thd,
new (thd->mem_root) Item_func_replace_oracle(thd, org, find, replace) :
new (thd->mem_root) Item_func_replace(thd, org, find, replace);
}
+
+
+bool SELECT_LEX::vers_push_field(THD *thd, TABLE_LIST *table, const LEX_CSTRING field_name)
+{
+ DBUG_ASSERT(field_name.str);
+ Item_field *fld= new (thd->mem_root) Item_field(thd, &context,
+ table->db.str, table->alias.str, &field_name);
+ if (!fld || item_list.push_back(fld))
+ return true;
+
+ if (thd->lex->view_list.elements)
+ {
+ LEX_CSTRING *l;
+ if (!(l= thd->make_clex_string(field_name.str, field_name.length)))
+ return true;
+ thd->lex->view_list.push_back(l);
+ }
+
+ return false;
+}
+
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index d4e438ab98c..45fbe38e974 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2010, 2017, MariaDB Corporation.
+ Copyright (c) 2010, 2018, 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
@@ -31,6 +31,7 @@
#include "sql_trigger.h"
#include "sp.h" // enum stored_procedure_type
#include "sql_tvc.h"
+#include "item.h"
/* YACC and LEX Definitions */
@@ -205,7 +206,7 @@ struct LEX_TYPE
#ifdef MYSQL_SERVER
extern const LEX_STRING empty_lex_str;
-extern const LEX_CSTRING empty_clex_str;
+extern MYSQL_PLUGIN_IMPORT const LEX_CSTRING empty_clex_str;
extern const LEX_CSTRING star_clex_str;
extern const LEX_CSTRING param_clex_str;
@@ -225,6 +226,13 @@ enum enum_sp_data_access
SP_MODIFIES_SQL_DATA
};
+enum enum_sp_aggregate_type
+{
+ DEFAULT_AGGREGATE= 0,
+ NOT_AGGREGATE,
+ GROUP_AGGREGATE
+};
+
const LEX_STRING sp_data_access_name[]=
{
{ C_STRING_WITH_LEN("") },
@@ -412,7 +420,7 @@ public:
LEX_CSTRING key_name;
Index_hint (enum index_hint_type type_arg, index_clause_map clause_arg,
- const char *str, uint length) :
+ const char *str, size_t length) :
type(type_arg), clause(clause_arg)
{
key_name.str= str;
@@ -574,11 +582,15 @@ public:
*/
uint8 uncacheable;
enum sub_select_type linkage;
+ bool is_linkage_set() const
+ {
+ return linkage == UNION_TYPE || linkage == INTERSECT_TYPE || linkage == EXCEPT_TYPE;
+ }
bool no_table_names_allowed; /* used for global order by */
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return (void*) alloc_root(mem_root, (uint) size); }
- static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
+ static void operator delete(void *ptr,size_t size) { TRASH_FREE(ptr, size); }
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
// Ensures that at least all members used during cleanup() are initialized.
@@ -734,7 +746,7 @@ public:
/* thread handler */
THD *thd;
/*
- SELECT_LEX for hidden SELECT in onion which process global
+ SELECT_LEX for hidden SELECT in union which process global
ORDER BY and LIMIT
*/
st_select_lex *fake_select_lex;
@@ -825,7 +837,7 @@ class st_select_lex: public st_select_lex_node
{
public:
Name_resolution_context context;
- const char *db;
+ LEX_CSTRING db;
Item *where, *having; /* WHERE & HAVING clauses */
Item *prep_where; /* saved WHERE clause for prepared statement processing */
Item *prep_having;/* saved HAVING clause for prepared statement processing */
@@ -833,7 +845,13 @@ public:
Item *cond_pushed_into_having; /* condition pushed into the select's HAVING */
/* Saved values of the WHERE and HAVING clauses*/
Item::cond_result cond_value, having_value;
- /* point on lex in which it was created, used in view subquery detection */
+ /*
+ Point to the LEX in which it was created, used in view subquery detection.
+
+ TODO: make also st_select_lex::parent_stmt_lex (see THD::stmt_lex)
+ and use st_select_lex::parent_lex & st_select_lex::parent_stmt_lex
+ instead of global (from THD) references where it is possible.
+ */
LEX *parent_lex;
enum olap_type olap;
/* FROM clause - points to the beginning of the TABLE_LIST::next_local list. */
@@ -1032,6 +1050,13 @@ public:
table_value_constr *tvc;
bool in_tvc;
+ /** System Versioning */
+public:
+ uint versioned_tables;
+ int vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr);
+ /* push new Item_field into item_list */
+ bool vers_push_field(THD *thd, TABLE_LIST *table, const LEX_CSTRING field_name);
+
void init_query();
void init_select();
st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; }
@@ -1150,7 +1175,7 @@ public:
Add a index hint to the tagged list of hints. The type and clause of the
hint will be the current ones (set by set_index_hint())
*/
- bool add_index_hint (THD *thd, const char *str, uint length);
+ bool add_index_hint (THD *thd, const char *str, size_t length);
/* make a list to hold index hints */
void alloc_index_hints (THD *thd);
@@ -1289,6 +1314,7 @@ struct st_sp_chistics
enum enum_sp_suid_behaviour suid;
bool detistic;
enum enum_sp_data_access daccess;
+ enum enum_sp_aggregate_type agg_type;
void init() { bzero(this, sizeof(*this)); }
void set(const st_sp_chistics &other) { *this= other; }
bool read_from_mysql_proc_row(THD *thd, TABLE *table);
@@ -1965,6 +1991,18 @@ private:
};
+class Query_tables_backup
+{
+ THD *thd;
+ Query_tables_list backup;
+
+public:
+ Query_tables_backup(THD *_thd);
+ ~Query_tables_backup();
+ const Query_tables_list& get() const { return backup; }
+};
+
+
/*
st_parsing_options contains the flags for constructions that are
allowed in the current statement.
@@ -2037,9 +2075,9 @@ public:
@retval FALSE OK
@retval TRUE Error
*/
- bool init(THD *thd, char *buff, unsigned int length);
+ bool init(THD *thd, char *buff, size_t length);
- void reset(char *buff, unsigned int length);
+ void reset(char *buff, size_t length);
/**
Set the echo mode.
@@ -2312,16 +2350,16 @@ public:
}
/** Get the utf8-body length. */
- uint get_body_utf8_length()
+ size_t get_body_utf8_length()
{
- return (uint) (m_body_utf8_ptr - m_body_utf8);
+ return (size_t) (m_body_utf8_ptr - m_body_utf8);
}
/**
Get the maximum length of the utf8-body buffer.
The utf8 body can grow because of the character set conversion and escaping.
*/
- uint get_body_utf8_maximum_length(THD *thd);
+ size_t get_body_utf8_maximum_length(THD *thd);
void body_utf8_start(THD *thd, const char *begin_ptr);
void body_utf8_append(const char *ptr);
@@ -2381,7 +2419,7 @@ private:
const char *m_buf;
/** Length of the raw buffer. */
- uint m_buf_length;
+ size_t m_buf_length;
/** Echo the parsed stream to the pre-processed buffer. */
bool m_echo;
@@ -2673,7 +2711,10 @@ struct LEX: public Query_tables_list
DYNAMIC_ARRAY plugins;
plugin_ref plugins_static_buffer[INITIAL_LEX_PLUGIN_LIST_SIZE];
- uint number_of_selects; // valid only for view
+ /** SELECT of CREATE VIEW statement */
+ LEX_STRING create_view_select;
+
+ uint current_select_number; // valid for statment LEX (not view)
/** Start of 'ON table', in trigger statements. */
const char* raw_trg_on_table_name_begin;
@@ -2701,7 +2742,6 @@ struct LEX: public Query_tables_list
private:
Query_arena_memroot *arena_for_set_stmt;
MEM_ROOT *mem_root_for_set_stmt;
- void parse_error();
bool sp_block_finalize(THD *thd, const Lex_spblock_st spblock,
class sp_label **splabel);
bool sp_change_context(THD *thd, const sp_pcontext *ctx, bool exclusive);
@@ -2715,6 +2755,7 @@ private:
bool sp_for_loop_increment(THD *thd, const Lex_for_loop_st &loop);
public:
+ void parse_error(uint err_number= ER_SYNTAX_ERROR);
inline bool is_arena_for_set_stmt() {return arena_for_set_stmt != 0;}
bool set_arena_for_set_stmt(Query_arena *backup);
void reset_arena_for_set_stmt(Query_arena *backup);
@@ -2722,7 +2763,7 @@ public:
List<Item_func_set_user_var> set_var_list; // in-query assignment list
List<Item_param> param_list;
- List<LEX_STRING> view_list; // view list (list of field names in view)
+ List<LEX_CSTRING> view_list; // view list (list of field names in view)
List<LEX_CSTRING> with_column_list; // list of column names in with_list_element
List<LEX_STRING> *column_list; // list of column names (in ANALYZE)
List<LEX_STRING> *index_list; // list of index names (in ANALYZE)
@@ -2928,6 +2969,7 @@ public:
st_alter_tablespace *alter_tablespace_info;
bool escape_used;
+ bool default_used; /* using default() function */
bool is_lex_started; /* If lex_start() did run. For debugging. */
/*
@@ -2948,6 +2990,13 @@ public:
*/
Item *limit_rows_examined;
ulonglong limit_rows_examined_cnt;
+ /**
+ Holds a set of domain_ids for deletion at FLUSH..DELETE_DOMAIN_ID
+ */
+ DYNAMIC_ARRAY delete_gtid_domain;
+ static const ulong initial_gtid_domain_buffer_size= 16;
+ ulong gtid_domain_static_buffer[initial_gtid_domain_buffer_size];
+
inline void set_limit_rows_examined()
{
if (limit_rows_examined)
@@ -2965,6 +3014,9 @@ public:
Window_frame_bound *frame_bottom_bound;
Window_spec *win_spec;
+ /* System Versioning */
+ vers_select_conds_t vers_conditions;
+
inline void free_set_stmt_mem_root()
{
DBUG_ASSERT(!is_arena_for_set_stmt());
@@ -3081,7 +3133,7 @@ public:
context_stack.pop();
}
- bool copy_db_to(const char **p_db, size_t *p_db_length) const;
+ bool copy_db_to(LEX_CSTRING *to);
Name_resolution_context *current_context()
{
@@ -3472,6 +3524,9 @@ public:
uint coffset,
sp_assignment_lex *param_lex,
Item_args *parameters);
+ bool sp_for_loop_implicit_cursor_statement(THD *thd,
+ Lex_for_loop_bounds_st *bounds,
+ sp_lex_cursor *cur);
bool sp_for_loop_cursor_condition_test(THD *thd, const Lex_for_loop_st &loop);
bool sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &);
@@ -3599,6 +3654,8 @@ public:
alter_info.check_constraint_list.push_back(constr);
return false;
}
+ bool add_alter_list(const char *par_name, Virtual_column_info *expr,
+ bool par_exists);
void set_command(enum_sql_command command,
DDL_options_st options)
{
@@ -3666,6 +3723,11 @@ public:
bool add_grant_command(THD *thd, enum_sql_command sql_command_arg,
stored_procedure_type type_arg);
+
+ Vers_parse_info &vers_get_info()
+ {
+ return create_info.vers_info;
+ }
};
@@ -3812,7 +3874,7 @@ public:
@retval FALSE OK
@retval TRUE Error
*/
- bool init(THD *thd, char *buff, unsigned int length)
+ bool init(THD *thd, char *buff, size_t length)
{
return m_lip.init(thd, buff, length);
}
@@ -3944,10 +4006,9 @@ int init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex);
extern int MYSQLlex(union YYSTYPE *yylval, THD *thd);
extern int ORAlex(union YYSTYPE *yylval, THD *thd);
-extern void trim_whitespace(CHARSET_INFO *cs, LEX_CSTRING *str,
- uint *prefix_removed);
+extern void trim_whitespace(CHARSET_INFO *cs, LEX_CSTRING *str, size_t * prefix_length = 0);
-extern bool is_lex_native_function(const LEX_CSTRING *name);
+extern bool is_lex_native_function(const LEX_CSTRING *name);
extern bool is_native_function(THD *thd, const LEX_CSTRING *name);
extern bool is_native_function_with_warn(THD *thd, const LEX_CSTRING *name);
diff --git a/sql/sql_lifo_buffer.h b/sql/sql_lifo_buffer.h
index 8fa13c66dd9..17024d15beb 100644
--- a/sql/sql_lifo_buffer.h
+++ b/sql/sql_lifo_buffer.h
@@ -84,7 +84,7 @@ public:
start= start_arg;
end= end_arg;
if (end != start)
- TRASH(start, end - start);
+ TRASH_ALLOC(start, end - start);
reset();
}
@@ -224,7 +224,7 @@ public:
{
DBUG_ASSERT(unused_end >= unused_start);
DBUG_ASSERT(end == unused_start);
- TRASH(unused_start, unused_end - unused_start);
+ TRASH_ALLOC(unused_start, unused_end - unused_start);
end= unused_end;
}
/* Return pointer to start of the memory area that is occupied by the data */
diff --git a/sql/sql_list.cc b/sql/sql_list.cc
index e938d5515c9..3512c7fc2ef 100644
--- a/sql/sql_list.cc
+++ b/sql/sql_list.cc
@@ -39,21 +39,21 @@ void free_list(I_List <i_string> *list)
}
-base_list::base_list(const base_list &rhs, MEM_ROOT *mem_root)
+bool base_list::copy(const base_list *rhs, MEM_ROOT *mem_root)
{
- if (rhs.elements)
+ bool error= 0;
+ if (rhs->elements)
{
/*
It's okay to allocate an array of nodes at once: we never
call a destructor for list_node objects anyway.
*/
- first= (list_node*) alloc_root(mem_root,
- sizeof(list_node) * rhs.elements);
- if (first)
+ if ((first= (list_node*) alloc_root(mem_root,
+ sizeof(list_node) * rhs->elements)))
{
- elements= rhs.elements;
+ elements= rhs->elements;
list_node *dst= first;
- list_node *src= rhs.first;
+ list_node *src= rhs->first;
for (; dst < first + elements - 1; dst++, src= src->next)
{
dst->info= src->info;
@@ -64,10 +64,12 @@ base_list::base_list(const base_list &rhs, MEM_ROOT *mem_root)
dst->next= &end_of_list;
/* Setup 'last' member */
last= &dst->next;
- return;
+ return 0;
}
+ error= 1;
}
elements= 0;
first= &end_of_list;
last= &first;
+ return error;
}
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 422b7943aa9..311e601490b 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -162,7 +162,8 @@ public:
need to copy elements by value, you should employ
list_copy_and_replace_each_value after creating a copy.
*/
- base_list(const base_list &rhs, MEM_ROOT *mem_root);
+ bool copy(const base_list *rhs, MEM_ROOT *mem_root);
+ base_list(const base_list &rhs, MEM_ROOT *mem_root) { copy(&rhs, mem_root); }
inline base_list(bool error) { }
inline bool push_back(void *info)
{
@@ -496,6 +497,8 @@ public:
inline void disjoin(List<T> *list) { base_list::disjoin(list); }
inline bool add_unique(T *a, bool (*eq)(T *a, T *b))
{ return base_list::add_unique(a, (List_eq *)eq); }
+ inline bool copy(const List<T> *list, MEM_ROOT *root)
+ { return base_list::copy(list, root); }
void delete_elements(void)
{
list_node *element,*next;
@@ -622,6 +625,10 @@ struct ilink
{
DBUG_ASSERT(prev != 0 && next != 0);
}
+ inline void assert_not_linked()
+ {
+ DBUG_ASSERT(prev == 0 && next == 0);
+ }
virtual ~ilink() { unlink(); } /*lint -e1740 */
};
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index d972947c718..9d367149eaa 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2017, MariaDB Corporation
+ Copyright (c) 2010, 2018, 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
@@ -97,18 +97,57 @@ public:
#define GET (stack_pos != stack ? *--stack_pos : my_b_get(&cache))
#define PUSH(A) *(stack_pos++)=(A)
+#ifdef WITH_WSREP
+/** If requested by wsrep_load_data_splitting, commit and restart
+the transaction after every 10,000 inserted rows. */
+
+static bool wsrep_load_data_split(THD *thd, const TABLE *table,
+ const COPY_INFO &info)
+{
+ DBUG_ENTER("wsrep_load_data_split");
+
+ if (!wsrep_load_data_splitting || !wsrep_on(thd)
+ || !info.records || (info.records % 10000)
+ || !thd->transaction.stmt.ha_list
+ || thd->transaction.stmt.ha_list->ht() != binlog_hton
+ || !thd->transaction.stmt.ha_list->next()
+ || thd->transaction.stmt.ha_list->next()->next())
+ DBUG_RETURN(false);
+
+ if (handlerton* hton= thd->transaction.stmt.ha_list->next()->ht())
+ {
+ if (hton->db_type != DB_TYPE_INNODB)
+ DBUG_RETURN(false);
+ WSREP_DEBUG("intermediate transaction commit in LOAD DATA");
+ if (wsrep_run_wsrep_commit(thd, true) != WSREP_TRX_OK) DBUG_RETURN(true);
+ if (binlog_hton->commit(binlog_hton, thd, true)) DBUG_RETURN(true);
+ wsrep_post_commit(thd, true);
+ hton->commit(hton, thd, true);
+ table->file->extra(HA_EXTRA_FAKE_START_STMT);
+ }
+
+ DBUG_RETURN(false);
+}
+# define WSREP_LOAD_DATA_SPLIT(thd,table,info) \
+ if (wsrep_load_data_split(thd,table,info)) \
+ { \
+ table->auto_increment_field_not_null= FALSE; \
+ DBUG_RETURN(1); \
+ }
+#else /* WITH_WSREP */
+#define WSREP_LOAD_DATA_SPLIT(thd,table,info) /* empty */
+#endif /* WITH_WSREP */
+
class READ_INFO {
File file;
String data; /* Read buffer */
uint fixed_length; /* Length of the fixed length record */
- uint max_length; /* Max length of row */
Term_string m_field_term; /* FIELDS TERMINATED BY 'string' */
Term_string m_line_term; /* LINES TERMINATED BY 'string' */
Term_string m_line_start; /* LINES STARTING BY 'string' */
int enclosed_char,escape_char;
int *stack,*stack_pos;
bool found_end_of_line,start_of_line,eof;
- NET *io_net;
int level; /* for load xml */
bool getbyte(char *to)
@@ -283,13 +322,13 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
killed_state killed_status;
bool is_concurrent;
#endif
- const char *db = table_list->db; // This is never null
+ const char *db= table_list->db.str; // This is never null
/*
If path for file is not defined, we will use the current database.
If this is not set, we will use the directory where the table to be
loaded is located
*/
- const char *tdb= thd->db ? thd->db : db; // Result is never null
+ const char *tdb= thd->db.str ? thd->db.str : db; // Result is never null
ulong skip_lines= ex->skip_lines;
bool transactional_table __attribute__((unused));
DBUG_ENTER("mysql_load");
@@ -340,7 +379,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
!table_list->single_table_updatable() || // and derived tables
check_key_in_view(thd, table_list))
{
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD");
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "LOAD");
DBUG_RETURN(TRUE);
}
if (table_list->prepare_where(thd, 0, TRUE) ||
@@ -359,7 +398,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
*/
if (unique_table(thd, table_list, table_list->next_global, 0))
{
- my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name,
+ my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name.str,
"LOAD DATA");
DBUG_RETURN(TRUE);
}
@@ -370,6 +409,13 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
is_concurrent= (table_list->lock_type == TL_WRITE_CONCURRENT_INSERT);
#endif
+ if (table->versioned(VERS_TIMESTAMP) && handle_duplicates == DUP_REPLACE)
+ {
+ // Additional memory may be required to create historical items.
+ if (table_list->set_insert_values(thd->mem_root))
+ DBUG_RETURN(TRUE);
+ }
+
if (!fields_vars.elements)
{
Field_iterator_table_ref field_iterator;
@@ -671,8 +717,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
writing binary log will be ignored */
if (thd->transaction.stmt.modified_non_trans_table)
(void) write_execute_load_query_log_event(thd, ex,
- table_list->db,
- table_list->table_name,
+ table_list->db.str,
+ table_list->table_name.str,
is_concurrent,
handle_duplicates, ignore,
transactional_table,
@@ -722,7 +768,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
{
int errcode= query_error_code(thd, killed_status == NOT_KILLED);
error= write_execute_load_query_log_event(thd, ex,
- table_list->db, table_list->table_name,
+ table_list->db.str,
+ table_list->table_name.str,
is_concurrent,
handle_duplicates, ignore,
transactional_table,
@@ -771,7 +818,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
List<Item> fv;
Item *item, *val;
int n;
- const char *tdb= (thd->db != NULL ? thd->db : db_arg);
+ const char *tdb= (thd->db.str != NULL ? thd->db.str : db_arg);
const char *qualify_db= NULL;
char command_buffer[1024];
String query_str(command_buffer, sizeof(command_buffer),
@@ -787,7 +834,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
query_str.length(0);
- if (!thd->db || strcmp(db_arg, thd->db))
+ if (!thd->db.str || strcmp(db_arg, thd->db.str))
{
/*
If used database differs from table's database,
@@ -814,7 +861,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
if (n++)
query_str.append(", ");
if (item->real_type() == Item::FIELD_ITEM)
- append_identifier(thd, &query_str, item->name.str, item->name.length);
+ append_identifier(thd, &query_str, &item->name);
else
{
/* Actually Item_user_var_as_out_param despite claiming STRING_ITEM. */
@@ -838,7 +885,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
val= lv++;
if (n++)
query_str.append(STRING_WITH_LEN(", "));
- append_identifier(thd, &query_str, item->name.str, item->name.length);
+ append_identifier(thd, &query_str, &item->name);
query_str.append(&val->name);
}
}
@@ -927,7 +974,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
*/
while ((sql_field= (Item_field*) it++))
{
- Field *field= sql_field->field;
+ Field *field= sql_field->field;
table->auto_increment_field_not_null= auto_increment_field_not_null;
/*
No fields specified in fields_vars list can be null in this format.
@@ -989,6 +1036,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(-1);
}
+ WSREP_LOAD_DATA_SPLIT(thd, table, info);
err= write_record(thd, table, &info);
table->auto_increment_field_not_null= FALSE;
if (err)
@@ -1015,7 +1063,6 @@ continue_loop:;
}
-
static int
read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields_vars, List<Item> &set_fields,
@@ -1094,28 +1141,9 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
else
{
- Field *field= real_item->field;
- if (field->reset())
- {
- my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name.str,
- thd->get_stmt_da()->current_row_for_warning());
+ DBUG_ASSERT(real_item->field->table == table);
+ if (real_item->field->load_data_set_null(thd))
DBUG_RETURN(1);
- }
- field->set_null();
- if (!field->maybe_null())
- {
- /*
- Timestamp fields that are NOT NULL are autoupdated if there is no
- corresponding value in the data file.
- */
- if (field->type() == MYSQL_TYPE_TIMESTAMP)
- field->set_time();
- else if (field != table->next_number_field)
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
- ER_WARN_NULL_TO_NOTNULL, 1);
- }
- /* Do not auto-update this field. */
- field->set_has_explicit_value();
}
continue;
@@ -1214,6 +1242,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(-1);
}
+ WSREP_LOAD_DATA_SPLIT(thd, table, info);
err= write_record(thd, table, &info);
table->auto_increment_field_not_null= FALSE;
if (err)
@@ -1262,6 +1291,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
for ( ; ; it.rewind())
{
+ bool err;
if (thd->killed)
{
thd->send_kill_message();
@@ -1313,21 +1343,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
else
{
- Field *field= real_item->field;
- field->reset();
- field->set_null();
- if (field == table->next_number_field)
- table->auto_increment_field_not_null= TRUE;
- if (!field->maybe_null())
- {
- if (field->type() == FIELD_TYPE_TIMESTAMP)
- field->set_time();
- else if (field != table->next_number_field)
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
- ER_WARN_NULL_TO_NOTNULL, 1);
- }
- /* Do not auto-update this field. */
- field->set_has_explicit_value();
+ DBUG_ASSERT(real_item->field->table == table);
+ if (real_item->field->load_data_set_null(thd))
+ DBUG_RETURN(1);
}
continue;
}
@@ -1361,39 +1379,8 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
skip_lines--;
continue;
}
-
- if (item)
- {
- /* Have not read any field, thus input file is simply ended */
- if (item == fields_vars.head())
- break;
-
- for ( ; item; item= it++)
- {
- Item_field *real_item= item->field_for_view_update();
- if (item->type() == Item::STRING_ITEM)
- ((Item_user_var_as_out_param *)item)->set_null_value(cs);
- else if (!real_item)
- {
- my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name.str);
- DBUG_RETURN(1);
- }
- else
- {
- /*
- QQ: We probably should not throw warning for each field.
- But how about intention to always have the same number
- of warnings in THD::cuted_fields (and get rid of cuted_fields
- in the end ?)
- */
- thd->cuted_fields++;
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_WARN_TOO_FEW_RECORDS,
- ER_THD(thd, ER_WARN_TOO_FEW_RECORDS),
- thd->get_stmt_da()->current_row_for_warning());
- }
- }
- }
+
+ DBUG_ASSERT(!item);
if (thd->killed ||
fill_record_n_invoke_before_triggers(thd, table, set_fields, set_values,
@@ -1410,7 +1397,10 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(-1);
}
- if (write_record(thd, table, &info))
+ WSREP_LOAD_DATA_SPLIT(thd, table, info);
+ err= write_record(thd, table, &info);
+ table->auto_increment_field_not_null= false;
+ if (err)
DBUG_RETURN(1);
/*
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index b3a9ad144d5..67181c6eb5e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -82,7 +82,6 @@
#include <m_ctype.h>
#include <myisam.h>
#include <my_dir.h>
-#include "rpl_handler.h"
#include "rpl_mi.h"
#include "sql_digest.h"
@@ -112,6 +111,7 @@
#include "wsrep_mysqld.h"
#include "wsrep_thd.h"
+#include "vtmd.h"
static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
Parser_state *parser_state,
@@ -132,39 +132,39 @@ static bool check_rename_table(THD *, TABLE_LIST *, TABLE_LIST *);
const char *any_db="*any*"; // Special symbol for check_access
-const LEX_STRING command_name[257]={
- { C_STRING_WITH_LEN("Sleep") }, //0
- { C_STRING_WITH_LEN("Quit") }, //1
- { C_STRING_WITH_LEN("Init DB") }, //2
- { C_STRING_WITH_LEN("Query") }, //3
- { C_STRING_WITH_LEN("Field List") }, //4
- { C_STRING_WITH_LEN("Create DB") }, //5
- { C_STRING_WITH_LEN("Drop DB") }, //6
- { C_STRING_WITH_LEN("Refresh") }, //7
- { C_STRING_WITH_LEN("Shutdown") }, //8
- { C_STRING_WITH_LEN("Statistics") }, //9
- { C_STRING_WITH_LEN("Processlist") }, //10
- { C_STRING_WITH_LEN("Connect") }, //11
- { C_STRING_WITH_LEN("Kill") }, //12
- { C_STRING_WITH_LEN("Debug") }, //13
- { C_STRING_WITH_LEN("Ping") }, //14
- { C_STRING_WITH_LEN("Time") }, //15
- { C_STRING_WITH_LEN("Delayed insert") }, //16
- { C_STRING_WITH_LEN("Change user") }, //17
- { C_STRING_WITH_LEN("Binlog Dump") }, //18
- { C_STRING_WITH_LEN("Table Dump") }, //19
- { C_STRING_WITH_LEN("Connect Out") }, //20
- { C_STRING_WITH_LEN("Register Slave") }, //21
- { C_STRING_WITH_LEN("Prepare") }, //22
- { C_STRING_WITH_LEN("Execute") }, //23
- { C_STRING_WITH_LEN("Long Data") }, //24
- { C_STRING_WITH_LEN("Close stmt") }, //25
- { C_STRING_WITH_LEN("Reset stmt") }, //26
- { C_STRING_WITH_LEN("Set option") }, //27
- { C_STRING_WITH_LEN("Fetch") }, //28
- { C_STRING_WITH_LEN("Daemon") }, //29
- { C_STRING_WITH_LEN("Unimpl get tid") }, //30
- { C_STRING_WITH_LEN("Reset connection") },//31
+const LEX_CSTRING command_name[257]={
+ { STRING_WITH_LEN("Sleep") }, //0
+ { STRING_WITH_LEN("Quit") }, //1
+ { STRING_WITH_LEN("Init DB") }, //2
+ { STRING_WITH_LEN("Query") }, //3
+ { STRING_WITH_LEN("Field List") }, //4
+ { STRING_WITH_LEN("Create DB") }, //5
+ { STRING_WITH_LEN("Drop DB") }, //6
+ { STRING_WITH_LEN("Refresh") }, //7
+ { STRING_WITH_LEN("Shutdown") }, //8
+ { STRING_WITH_LEN("Statistics") }, //9
+ { STRING_WITH_LEN("Processlist") }, //10
+ { STRING_WITH_LEN("Connect") }, //11
+ { STRING_WITH_LEN("Kill") }, //12
+ { STRING_WITH_LEN("Debug") }, //13
+ { STRING_WITH_LEN("Ping") }, //14
+ { STRING_WITH_LEN("Time") }, //15
+ { STRING_WITH_LEN("Delayed insert") }, //16
+ { STRING_WITH_LEN("Change user") }, //17
+ { STRING_WITH_LEN("Binlog Dump") }, //18
+ { STRING_WITH_LEN("Table Dump") }, //19
+ { STRING_WITH_LEN("Connect Out") }, //20
+ { STRING_WITH_LEN("Register Slave") }, //21
+ { STRING_WITH_LEN("Prepare") }, //22
+ { STRING_WITH_LEN("Execute") }, //23
+ { STRING_WITH_LEN("Long Data") }, //24
+ { STRING_WITH_LEN("Close stmt") }, //25
+ { STRING_WITH_LEN("Reset stmt") }, //26
+ { STRING_WITH_LEN("Set option") }, //27
+ { STRING_WITH_LEN("Fetch") }, //28
+ { STRING_WITH_LEN("Daemon") }, //29
+ { STRING_WITH_LEN("Unimpl get tid") }, //30
+ { STRING_WITH_LEN("Reset connection") },//31
{ 0, 0 }, //32
{ 0, 0 }, //33
{ 0, 0 }, //34
@@ -383,12 +383,12 @@ const LEX_STRING command_name[257]={
{ 0, 0 }, //247
{ 0, 0 }, //248
{ 0, 0 }, //249
- { C_STRING_WITH_LEN("Bulk_execute") }, //250
- { C_STRING_WITH_LEN("Slave_worker") }, //251
- { C_STRING_WITH_LEN("Slave_IO") }, //252
- { C_STRING_WITH_LEN("Slave_SQL") }, //253
- { C_STRING_WITH_LEN("Com_multi") }, //254
- { C_STRING_WITH_LEN("Error") } // Last command number 255
+ { STRING_WITH_LEN("Bulk_execute") }, //250
+ { STRING_WITH_LEN("Slave_worker") }, //251
+ { STRING_WITH_LEN("Slave_IO") }, //252
+ { STRING_WITH_LEN("Slave_SQL") }, //253
+ { STRING_WITH_LEN("Com_multi") }, //254
+ { STRING_WITH_LEN("Error") } // Last command number 255
};
const char *xa_state_names[]={
@@ -403,7 +403,7 @@ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
{
Rpl_filter *rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
return rpl_filter->is_on() && tables && !thd->spcont &&
- !rpl_filter->tables_ok(thd->db, tables);
+ !rpl_filter->tables_ok(thd->db.str, tables);
}
#endif
@@ -412,7 +412,7 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
{
for (TABLE_LIST *table= tables; table; table= table->next_global)
{
- DBUG_ASSERT(table->db && table->table_name);
+ DBUG_ASSERT(table->db.str && table->table_name.str);
if (table->updating && !thd->find_tmp_table_share(table))
return 1;
}
@@ -923,7 +923,7 @@ void execute_init_command(THD *thd, LEX_STRING *init_command,
save_vio= thd->net.vio;
thd->net.vio= 0;
thd->clear_error(1);
- dispatch_command(COM_QUERY, thd, buf, len, FALSE, FALSE);
+ dispatch_command(COM_QUERY, thd, buf, (uint)len, FALSE, FALSE);
thd->client_capabilities= save_client_capabilities;
thd->net.vio= save_vio;
@@ -936,7 +936,7 @@ void execute_init_command(THD *thd, LEX_STRING *init_command,
static char *fgets_fn(char *buffer, size_t size, fgets_input_t input, int *error)
{
MYSQL_FILE *in= static_cast<MYSQL_FILE*> (input);
- char *line= mysql_file_fgets(buffer, size, in);
+ char *line= mysql_file_fgets(buffer, (int)size, in);
if (error)
*error= (line == NULL) ? ferror(in->m_file) : 0;
return line;
@@ -1015,7 +1015,7 @@ static void handle_bootstrap_impl(THD *thd)
}
query= (char *) thd->memdup_w_gap(buffer, length + 1,
- thd->db_length + 1 +
+ thd->db.length + 1 +
QUERY_CACHE_DB_LENGTH_SIZE +
QUERY_CACHE_FLAGS_SIZE);
size_t db_len= 0;
@@ -1483,7 +1483,7 @@ static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables)
@retval # - Number of commands in the batch
*/
-uint maria_multi_check(THD *thd, char *packet, uint packet_length)
+uint maria_multi_check(THD *thd, char *packet, size_t packet_length)
{
uint counter= 0;
DBUG_ENTER("maria_multi_check");
@@ -1550,9 +1550,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
"<?>")));
bool drop_more_results= 0;
- if (!is_com_multi)
- inc_thread_running();
-
/* keep it withing 1 byte */
compile_time_assert(COM_END == 255);
@@ -1578,7 +1575,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (thd->wsrep_conflict_state == ABORTED &&
command != COM_STMT_CLOSE && command != COM_QUIT)
{
- my_message(ER_LOCK_DEADLOCK, "wsrep aborted transaction", MYF(0));
+ my_message(ER_LOCK_DEADLOCK, "Deadlock: wsrep aborted transaction",
+ MYF(0));
WSREP_DEBUG("Deadlock error for: %s", thd->query());
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
thd->reset_killed();
@@ -1672,7 +1670,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
if (!mysql_change_db(thd, &tmp, FALSE))
{
- general_log_write(thd, command, thd->db, thd->db_length);
+ general_log_write(thd, command, thd->db.str, thd->db.length);
my_ok(thd);
}
break;
@@ -1705,8 +1703,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* acl_authenticate() takes the data from net->read_pos */
net->read_pos= (uchar*)packet;
- uint save_db_length= thd->db_length;
- char *save_db= thd->db;
+ LEX_CSTRING save_db= thd->db;
USER_CONN *save_user_connect= thd->user_connect;
Security_context save_security_ctx= *thd->security_ctx;
CHARSET_INFO *save_character_set_client=
@@ -1742,7 +1739,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (thd->user_connect)
decrease_user_connections(thd->user_connect);
thd->user_connect= save_user_connect;
- thd->reset_db(save_db, save_db_length);
+ thd->reset_db(&save_db);
thd->update_charset(save_character_set_client, save_collation_connection,
save_character_set_results);
thd->failed_com_change_user++;
@@ -1755,7 +1752,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (save_user_connect)
decrease_user_connections(save_user_connect);
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
- my_free(save_db);
+ my_free((char*) save_db.str);
my_free(const_cast<char*>(save_security_ctx.user));
}
break;
@@ -1804,7 +1801,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (alloc_query(thd, packet, packet_length))
break; // fatal error is set
MYSQL_QUERY_START(thd->query(), thd->thread_id,
- (char *) (thd->db ? thd->db : ""),
+ thd->get_db(),
&thd->security_ctx->priv_user[0],
(char *) thd->security_ctx->host_or_ip);
char *packet_end= thd->query() + thd->query_length();
@@ -1882,7 +1879,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* DTRACE begin */
MYSQL_QUERY_START(beginning_of_next_stmt, thd->thread_id,
- (char *) (thd->db ? thd->db : ""),
+ thd->get_db(),
&thd->security_ctx->priv_user[0],
(char *) thd->security_ctx->host_or_ip);
@@ -1891,7 +1888,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
com_statement_info[command].m_key,
- thd->db, thd->db_length,
+ thd->db.str, thd->db.length,
thd->charset());
THD_STAGE_INFO(thd, stage_init);
MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, beginning_of_next_stmt,
@@ -1941,7 +1938,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
- if (thd->copy_db_to(&db.str, &db.length))
+ if (thd->copy_db_to(&db))
break;
/*
We have name + wildcard in packet, separated by endzero
@@ -1981,8 +1978,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
table_name.length= my_casedn_str(files_charset_info, table_name.str);
db.length= my_casedn_str(files_charset_info, (char*) db.str);
}
- table_list.init_one_table(db.str, db.length, table_name.str,
- table_name.length, table_name.str, TL_READ);
+ table_list.init_one_table(&db, (LEX_CSTRING*) &table_name, 0, TL_READ);
/*
Init TABLE_LIST members necessary when the undelrying
table is view.
@@ -1993,9 +1989,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
&table_list.next_local);
thd->lex->add_to_query_tables(&table_list);
- if (is_infoschema_db(table_list.db, table_list.db_length))
+ if (is_infoschema_db(&table_list.db))
{
- ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
+ ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, &table_list.alias);
if (schema_table)
table_list.schema_table= schema_table;
}
@@ -2004,7 +2000,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
break;
thd->set_query(fields, query_length);
- general_log_print(thd, command, "%s %s", table_list.table_name, fields);
+ general_log_print(thd, command, "%s %s", table_list.table_name.str,
+ fields);
if (thd->open_temporary_tables(&table_list))
break;
@@ -2169,7 +2166,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
STATUS_VAR *current_global_status_var; // Big; Don't allocate on stack
ulong uptime;
- uint length __attribute__((unused));
ulonglong queries_per_second1000;
char buff[250];
uint buff_len= sizeof(buff);
@@ -2184,8 +2180,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
queries_per_second1000= 0;
else
queries_per_second1000= thd->query_id * 1000 / uptime;
-
- length= my_snprintf(buff, buff_len - 1,
+#ifndef EMBEDDED_LIBRARY
+ size_t length=
+#endif
+ my_snprintf(buff, buff_len - 1,
"Uptime: %lu Threads: %d Questions: %lu "
"Slow queries: %lu Opens: %lu Flush tables: %lld "
"Open tables: %u Queries per second avg: %u.%03u",
@@ -2312,7 +2310,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
if (dispatch_command(subcommand, thd, packet + (1 + length_length),
- subpacket_length - (1 + length_length), TRUE,
+ (uint)(subpacket_length - (1 + length_length)), TRUE,
(current_com != counter)))
{
DBUG_ASSERT(thd->is_error());
@@ -2321,7 +2319,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
DBUG_ASSERT(subpacket_length <= packet_length);
packet+= subpacket_length;
- packet_length-= subpacket_length;
+ packet_length-= (uint)subpacket_length;
}
com_multi_end:
@@ -2401,19 +2399,18 @@ com_multi_end:
THD_STAGE_INFO(thd, stage_cleaning_up);
thd->reset_query();
- thd->set_examined_row_count(0); // For processlist
- thd->set_command(COM_SLEEP);
/* Performance Schema Interface instrumentation, end */
MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
+ thd->set_examined_row_count(0); // For processlist
+ thd->set_command(COM_SLEEP);
+
thd->m_statement_psi= NULL;
thd->m_digest= NULL;
if (!is_com_multi)
- {
- dec_thread_running();
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
- }
+
thd->reset_kill_query(); /* Ensure that killed_errmsg is released */
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
@@ -2552,27 +2549,23 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
DBUG_RETURN(1);
#else
{
- LEX_STRING db;
- size_t dummy;
- if (lex->select_lex.db == NULL &&
- lex->copy_db_to(&lex->select_lex.db, &dummy))
+ if (lex->select_lex.db.str == NULL &&
+ lex->copy_db_to(&lex->select_lex.db))
{
DBUG_RETURN(1);
}
schema_select_lex= new (thd->mem_root) SELECT_LEX();
schema_select_lex->table_list.first= NULL;
if (lower_case_table_names == 1)
- lex->select_lex.db= thd->strdup(lex->select_lex.db);
+ lex->select_lex.db.str= thd->strdup(lex->select_lex.db.str);
schema_select_lex->db= lex->select_lex.db;
/*
check_db_name() may change db.str if lower_case_table_names == 1,
but that's ok as the db is allocted above in this case.
*/
- db.str= (char*) lex->select_lex.db;
- db.length= strlen(db.str);
- if (check_db_name(&db))
+ if (check_db_name((LEX_STRING*) &lex->select_lex.db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->select_lex.db.str);
DBUG_RETURN(1);
}
break;
@@ -2635,7 +2628,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
TRUE error; In this case thd->fatal_error is set
*/
-bool alloc_query(THD *thd, const char *packet, uint packet_length)
+bool alloc_query(THD *thd, const char *packet, size_t packet_length)
{
char *query;
/* Remove garbage at start and end of query */
@@ -2663,7 +2656,7 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length)
*/
if (! (query= (char*) thd->memdup_w_gap(packet,
packet_length,
- 1 + thd->db_length +
+ 1 + thd->db.length +
QUERY_CACHE_DB_LENGTH_SIZE +
QUERY_CACHE_FLAGS_SIZE)))
return TRUE;
@@ -2673,7 +2666,7 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length)
also store this length, in case current database is changed during
execution. We might need to reallocate the 'query' buffer
*/
- int2store(query + packet_length + 1, thd->db_length);
+ int2store(query + packet_length + 1, thd->db.length);
thd->set_query(query, packet_length);
@@ -2913,6 +2906,13 @@ static bool do_execute_sp(THD *thd, sp_head *sp)
thd->variables.select_limit= HA_POS_ERROR;
/*
+ Reset current_select as it may point to random data as a
+ result of previous parsing.
+ */
+ thd->lex->current_select= NULL;
+ thd->lex->in_sum_func= 0; // For Item_field::fix_fields()
+
+ /*
We never write CALL statements into binlog:
- If the mode is non-prelocked, each statement will be logged
separately.
@@ -2959,8 +2959,8 @@ static int mysql_create_routine(THD *thd, LEX *lex)
/* Checking the drop permissions if CREATE OR REPLACE is used */
if (lex->create_info.or_replace())
{
- if (check_routine_access(thd, ALTER_PROC_ACL, lex->sphead->m_db.str,
- lex->sphead->m_name.str,
+ if (check_routine_access(thd, ALTER_PROC_ACL, &lex->sphead->m_db,
+ &lex->sphead->m_name,
Sp_handler::handler(lex->sql_command), 0))
return true;
}
@@ -3029,7 +3029,7 @@ static int mysql_create_routine(THD *thd, LEX *lex)
if (sp_automatic_privileges && !opt_noacl &&
check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
- lex->sphead->m_db.str, name->str,
+ &lex->sphead->m_db, name,
Sp_handler::handler(lex->sql_command), 1))
{
if (sp_grant_privileges(thd, lex->sphead->m_db.str, name->str,
@@ -3130,8 +3130,8 @@ bool Sql_cmd_call::execute(THD *thd)
If the routine is not found, let's still check EXECUTE_ACL to decide
whether to return "Access denied" or "Routine does not exist".
*/
- if (check_routine_access(thd, EXECUTE_ACL, m_name->m_db.str,
- m_name->m_name.str,
+ if (check_routine_access(thd, EXECUTE_ACL, &m_name->m_db,
+ &m_name->m_name,
&sp_handler_procedure,
false))
return true;
@@ -3165,6 +3165,11 @@ bool Sql_cmd_call::execute(THD *thd)
if (do_execute_sp(thd, sp))
return true;
+ if (sp->sp_cache_version() == 0)
+ {
+ sp_cache_flush(thd->sp_proc_cache, sp);
+ }
+
/*
Disable slow log for the above call(), if calls are disabled.
Instead we will log the executed statements to the slow log.
@@ -3272,6 +3277,9 @@ mysql_execute_command(THD *thd)
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
}
+ if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
+ DBUG_RETURN(1);
+
#ifdef HAVE_REPLICATION
if (unlikely(thd->slave_thread))
{
@@ -3857,7 +3865,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_ASSIGN_TO_KEYCACHE:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (check_access(thd, INDEX_ACL, first_table->db,
+ if (check_access(thd, INDEX_ACL, first_table->db.str,
&first_table->grant.privilege,
&first_table->grant.m_internal,
0, 0))
@@ -3868,7 +3876,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_PRELOAD_KEYS:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (check_access(thd, INDEX_ACL, first_table->db,
+ if (check_access(thd, INDEX_ACL, first_table->db.str,
&first_table->grant.privilege,
&first_table->grant.m_internal,
0, 0))
@@ -4015,7 +4023,6 @@ mysql_execute_command(THD *thd)
copy.
*/
Alter_info alter_info(lex->alter_info, thd->mem_root);
-
if (thd->is_fatal_error)
{
/* If out of memory when creating a copy of alter_info. */
@@ -4032,9 +4039,9 @@ mysql_execute_command(THD *thd)
/* Fix names if symlinked or relocated tables */
if (append_file_to_dir(thd, &create_info.data_file_name,
- create_table->table_name) ||
+ &create_table->table_name) ||
append_file_to_dir(thd, &create_info.index_file_name,
- create_table->table_name))
+ &create_table->table_name))
goto end_with_restore_list;
/*
@@ -4043,6 +4050,7 @@ mysql_execute_command(THD *thd)
*/
if (!(create_info.used_fields & HA_CREATE_USED_ENGINE))
create_info.use_default_db_type(thd);
+
/*
If we are using SET CHARSET without DEFAULT, add an implicit
DEFAULT to not confuse old users. (This may change).
@@ -4146,8 +4154,8 @@ mysql_execute_command(THD *thd)
*/
if (create_info.used_fields & HA_CREATE_USED_UNION)
{
- my_error(ER_WRONG_OBJECT, MYF(0), create_table->db,
- create_table->table_name, "BASE TABLE");
+ my_error(ER_WRONG_OBJECT, MYF(0), create_table->db.str,
+ create_table->table_name.str, "BASE TABLE");
res= 1;
goto end_with_restore_list;
}
@@ -4155,8 +4163,7 @@ mysql_execute_command(THD *thd)
/* Copy temporarily the statement flags to thd for lock_table_names() */
uint save_thd_create_info_options= thd->lex->create_info.options;
thd->lex->create_info.options|= create_info.options;
- if (!(res= check_dependencies_in_with_clauses(lex->with_clauses_list)))
- res= open_and_lock_tables(thd, create_info, lex->query_tables, TRUE, 0);
+ res= open_and_lock_tables(thd, create_info, lex->query_tables, TRUE, 0);
thd->lex->create_info.options= save_thd_create_info_options;
if (res)
{
@@ -4229,18 +4236,22 @@ mysql_execute_command(THD *thd)
}
else
{
+ if (create_info.vers_fix_system_fields(thd, &alter_info, *create_table))
+ {
+ goto end_with_restore_list;
+ }
/*
In STATEMENT format, we probably have to replicate also temporary
tables, like mysql replication does. Also check if the requested
engine is allowed/supported.
*/
if (WSREP(thd) &&
- !check_engine(thd, create_table->db, create_table->table_name,
+ !check_engine(thd, create_table->db.str, create_table->table_name.str,
&create_info) &&
(!thd->is_current_stmt_binlog_format_row() ||
!create_info.tmp_table()))
{
- WSREP_TO_ISOLATION_BEGIN(create_table->db, create_table->table_name, NULL);
+ WSREP_TO_ISOLATION_BEGIN(create_table->db.str, create_table->table_name.str, NULL);
}
/* Regular CREATE TABLE */
res= mysql_create_table(thd, create_table, &create_info, &alter_info);
@@ -4285,7 +4296,7 @@ end_with_restore_list:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (check_one_table_access(thd, INDEX_ACL, all_tables))
goto error; /* purecov: inspected */
- WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name, NULL);
+ WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL);
/*
Currently CREATE INDEX or DROP INDEX cause a full table rebuild
and thus classify as slow administrative statements just like
@@ -4298,7 +4309,7 @@ end_with_restore_list:
create_info.row_type= ROW_TYPE_NOT_USED;
create_info.default_table_charset= thd->variables.collation_database;
- res= mysql_alter_table(thd, first_table->db, first_table->table_name,
+ res= mysql_alter_table(thd, &first_table->db, &first_table->table_name,
&create_info, first_table, &alter_info,
0, (ORDER*) 0, 0);
break;
@@ -4453,7 +4464,7 @@ end_with_restore_list:
DBUG_PRINT("debug", ("lex->only_view: %d, table: %s.%s",
lex->table_type == TABLE_TYPE_VIEW,
- first_table->db, first_table->table_name));
+ first_table->db.str, first_table->table_name.str));
if (lex->table_type == TABLE_TYPE_VIEW)
{
if (check_table_access(thd, SELECT_ACL, first_table, FALSE, 1, FALSE))
@@ -4461,7 +4472,7 @@ end_with_restore_list:
DBUG_PRINT("debug", ("check_table_access failed"));
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
"SHOW", thd->security_ctx->priv_user,
- thd->security_ctx->host_or_ip, first_table->alias);
+ thd->security_ctx->host_or_ip, first_table->alias.str);
goto error;
}
DBUG_PRINT("debug", ("check_table_access succeeded"));
@@ -4490,7 +4501,7 @@ end_with_restore_list:
{
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
"SHOW", thd->security_ctx->priv_user,
- thd->security_ctx->host_or_ip, first_table->alias);
+ thd->security_ctx->host_or_ip, first_table->alias.str);
goto error;
}
}
@@ -4738,7 +4749,7 @@ end_with_restore_list:
if (WSREP(thd) && thd->wsrep_consistency_check == CONSISTENCY_CHECK_DECLARED)
{
thd->wsrep_consistency_check = CONSISTENCY_CHECK_RUNNING;
- WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name, NULL);
+ WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL);
}
#endif /* WITH_WSREP */
@@ -4769,8 +4780,7 @@ end_with_restore_list:
unit->set_limit(select_lex);
- if (!(res= check_dependencies_in_with_clauses(lex->with_clauses_list)) &&
- !(res=open_and_lock_tables(thd, all_tables, TRUE, 0)))
+ if (!(res=open_and_lock_tables(thd, all_tables, TRUE, 0)))
{
MYSQL_INSERT_SELECT_START(thd->query());
/*
@@ -4954,7 +4964,7 @@ end_with_restore_list:
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
result, unit, select_lex);
- res|= thd->is_error();
+ res|= (int)(thd->is_error());
MYSQL_MULTI_DELETE_DONE(res, result->num_deleted());
if (res)
@@ -5063,9 +5073,7 @@ end_with_restore_list:
#endif
case SQLCOM_CHANGE_DB:
{
- LEX_CSTRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
-
- if (!mysql_change_db(thd, &db_str, FALSE))
+ if (!mysql_change_db(thd, &select_lex->db, FALSE))
my_ok(thd);
break;
@@ -5192,7 +5200,7 @@ end_with_restore_list:
&lex->name))
break;
WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL);
- res= mysql_create_db(thd, lex->name.str,
+ res= mysql_create_db(thd, &lex->name,
lex->create_info, &lex->create_info);
break;
}
@@ -5201,7 +5209,7 @@ end_with_restore_list:
if (prepare_db_action(thd, DROP_ACL, &lex->name))
break;
WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL);
- res= mysql_rm_db(thd, lex->name.str, lex->if_exists());
+ res= mysql_rm_db(thd, &lex->name, lex->if_exists());
break;
}
case SQLCOM_ALTER_DB_UPGRADE:
@@ -5244,7 +5252,7 @@ end_with_restore_list:
if (prepare_db_action(thd, ALTER_ACL, db))
break;
WSREP_TO_ISOLATION_BEGIN(db->str, NULL, NULL);
- res= mysql_alter_db(thd, db->str, &lex->create_info);
+ res= mysql_alter_db(thd, db, &lex->create_info);
break;
}
case SQLCOM_SHOW_CREATE_DB:
@@ -5404,7 +5412,7 @@ end_with_restore_list:
{
if (lex->type != TYPE_ENUM_PROXY &&
check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
- first_table ? first_table->db : select_lex->db,
+ first_table ? first_table->db.str : select_lex->db.str,
first_table ? &first_table->grant.privilege : NULL,
first_table ? &first_table->grant.m_internal : NULL,
first_table ? 0 : 1, 0))
@@ -5485,7 +5493,7 @@ end_with_restore_list:
{
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
/* Conditionally writes to binlog */
- res= mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
+ res= mysql_grant(thd, select_lex->db.str, lex->users_list, lex->grant,
lex->sql_command == SQLCOM_REVOKE,
lex->type == TYPE_ENUM_PROXY);
}
@@ -5773,14 +5781,19 @@ end_with_restore_list:
thd->print_aborted_warning(3, "RELEASE");
}
#ifdef WITH_WSREP
- if (WSREP(thd) && (thd->wsrep_conflict_state != NO_CONFLICT &&
- thd->wsrep_conflict_state != REPLAYING))
- {
- DBUG_ASSERT(thd->is_error()); // the error is already issued
+ if (WSREP(thd)) {
+
+ if (thd->wsrep_conflict_state == NO_CONFLICT ||
+ thd->wsrep_conflict_state == REPLAYING)
+ {
+ my_ok(thd);
+ }
+ } else {
+#endif /* WITH_WSREP */
+ my_ok(thd);
+#ifdef WITH_WSREP
}
- else
#endif /* WITH_WSREP */
- my_ok(thd);
break;
}
case SQLCOM_ROLLBACK:
@@ -5817,13 +5830,16 @@ end_with_restore_list:
if (tx_release)
thd->set_killed(KILL_CONNECTION);
#ifdef WITH_WSREP
- if (WSREP(thd) && thd->wsrep_conflict_state != NO_CONFLICT)
- {
- DBUG_ASSERT(thd->is_error()); // the error is already issued
+ if (WSREP(thd)) {
+ if (thd->wsrep_conflict_state == NO_CONFLICT) {
+ my_ok(thd);
+ }
+ } else {
+#endif /* WITH_WSREP */
+ my_ok(thd);
+#ifdef WITH_WSREP
}
- else
#endif /* WITH_WSREP */
- my_ok(thd);
break;
}
case SQLCOM_RELEASE_SAVEPOINT:
@@ -5862,8 +5878,8 @@ end_with_restore_list:
{
int sp_result;
const Sp_handler *sph= Sp_handler::handler(lex->sql_command);
- if (check_routine_access(thd, ALTER_PROC_ACL, lex->spname->m_db.str,
- lex->spname->m_name.str, sph, 0))
+ if (check_routine_access(thd, ALTER_PROC_ACL, &lex->spname->m_db,
+ &lex->spname->m_name, sph, 0))
goto error;
/*
@@ -5936,10 +5952,8 @@ end_with_restore_list:
int sp_result;
const Sp_handler *sph= Sp_handler::handler(lex->sql_command);
- const char *db= lex->spname->m_db.str;
- const char *name= lex->spname->m_name.str;
- if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
+ if (check_routine_access(thd, ALTER_PROC_ACL, &lex->spname->m_db, &lex->spname->m_name,
Sp_handler::handler(lex->sql_command), 0))
goto error;
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
@@ -5968,7 +5982,7 @@ end_with_restore_list:
if (sp_result != SP_KEY_NOT_FOUND &&
sp_automatic_privileges && !opt_noacl &&
- sp_revoke_privileges(thd, db, name,
+ sp_revoke_privileges(thd, lex->spname->m_db.str, lex->spname->m_name.str,
Sp_handler::handler(lex->sql_command)))
{
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
@@ -6279,6 +6293,25 @@ finish:
THD_STAGE_INFO(thd, stage_rollback);
trans_rollback_stmt(thd);
}
+#ifdef WITH_WSREP
+ if (thd->spcont &&
+ (thd->wsrep_conflict_state == MUST_ABORT ||
+ thd->wsrep_conflict_state == ABORTED ||
+ thd->wsrep_conflict_state == CERT_FAILURE))
+ {
+ /*
+ The error was cleared, but THD was aborted by wsrep and
+ wsrep_conflict_state is still set accordingly. This
+ situation is expected if we are running a stored procedure
+ that declares a handler that catches ER_LOCK_DEADLOCK error.
+ In which case the error may have been cleared in method
+ sp_rcontext::handle_sql_condition().
+ */
+ trans_rollback_stmt(thd);
+ thd->wsrep_conflict_state= NO_CONFLICT;
+ thd->killed= NOT_KILLED;
+ }
+#endif /* WITH_WSREP */
else
{
/* If commit fails, we should be able to reset the OK status. */
@@ -6392,8 +6425,21 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
new (thd->mem_root) Item_int(thd,
(ulonglong) thd->variables.select_limit);
}
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- return 1;
+
+ if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
+ {
+ for (TABLE_LIST *table= all_tables; table; table= table->next_local)
+ {
+ if (table->vers_conditions)
+ {
+ VTMD_exists vtmd(*table);
+ if (vtmd.check_exists(thd))
+ return 1;
+ if (vtmd.exists && vtmd.setup_select(thd))
+ return 1;
+ }
+ }
+ }
if (!(res= open_and_lock_tables(thd, all_tables, TRUE, 0)))
{
@@ -6533,11 +6579,11 @@ static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
TABLE_LIST *table;
for (table= first_table; table; table= table->next_local->next_local)
{
- if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
+ if (check_access(thd, ALTER_ACL | DROP_ACL, table->db.str,
&table->grant.privilege,
&table->grant.m_internal,
0, 0) ||
- check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
+ check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db.str,
&table->next_local->grant.privilege,
&table->next_local->grant.m_internal,
0, 0))
@@ -6627,7 +6673,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
/* check access may be called twice in a row. Don't change to same stage */
if (thd->proc_info != stage_checking_permissions.m_name)
THD_STAGE_INFO(thd, stage_checking_permissions);
- if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
+ if ((!db || !db[0]) && !thd->db.str && !dont_check_global_grants)
{
DBUG_PRINT("error",("No database"));
if (!no_errors)
@@ -6683,7 +6729,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
*/
if (!(sctx->master_access & SELECT_ACL))
{
- if (db && (!thd->db || db_is_pattern || strcmp(db, thd->db)))
+ if (db && (!thd->db.str || db_is_pattern || strcmp(db, thd->db.str)))
{
db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
db_is_pattern);
@@ -6732,7 +6778,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
DBUG_RETURN(FALSE);
}
- if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
+ if (db && (!thd->db.str || db_is_pattern || strcmp(db, thd->db.str)))
{
db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
db_is_pattern);
@@ -6787,8 +6833,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
status_var_increment(thd->status_var.access_denied_errors);
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->priv_host,
- (db ? db : (thd->db ?
- thd->db :
+ (db ? db : (thd->db.str ?
+ thd->db.str :
"unknown")));
}
DBUG_RETURN(TRUE);
@@ -6826,7 +6872,7 @@ bool check_single_table_access(THD *thd, ulong privilege,
!all_tables->schema_table)
db_name= all_tables->view_db.str;
else
- db_name= all_tables->db;
+ db_name= all_tables->db.str;
if (check_access(thd, privilege, db_name,
&all_tables->grant.privilege,
@@ -6915,7 +6961,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
case SCH_TRIGGERS:
case SCH_EVENTS:
{
- const char *dst_db_name= table->schema_select_lex->db;
+ const char *dst_db_name= table->schema_select_lex->db.str;
DBUG_ASSERT(dst_db_name);
@@ -6950,7 +6996,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
if (thd->open_temporary_tables(dst_table))
return TRUE;
- if (check_access(thd, SELECT_ACL, dst_table->db,
+ if (check_access(thd, SELECT_ACL, dst_table->db.str,
&dst_table->grant.privilege,
&dst_table->grant.m_internal,
FALSE, FALSE))
@@ -7086,15 +7132,15 @@ deny:
bool
-check_routine_access(THD *thd, ulong want_access, const char *db,
- const char *name,
+check_routine_access(THD *thd, ulong want_access, const LEX_CSTRING *db,
+ const LEX_CSTRING *name,
const Sp_handler *sph, bool no_errors)
{
TABLE_LIST tables[1];
bzero((char *)tables, sizeof(TABLE_LIST));
- tables->db= db;
- tables->table_name= tables->alias= name;
+ tables->db= *db;
+ tables->table_name= tables->alias= *name;
/*
The following test is just a shortcut for check_access() (to avoid
@@ -7111,7 +7157,7 @@ check_routine_access(THD *thd, ulong want_access, const char *db,
DBUG_ASSERT((want_access & CREATE_PROC_ACL) == 0);
if ((thd->security_ctx->master_access & want_access) == want_access)
tables->grant.privilege= want_access;
- else if (check_access(thd, want_access, db,
+ else if (check_access(thd, want_access, db->str,
&tables->grant.privilege,
&tables->grant.m_internal,
0, no_errors))
@@ -7178,7 +7224,7 @@ bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
{
if (access & want_access)
{
- if (!check_access(thd, access, table->db,
+ if (!check_access(thd, access, table->db.str,
&table->grant.privilege,
&table->grant.m_internal,
0, 1) &&
@@ -7291,7 +7337,7 @@ bool check_fk_parent_table_access(THD *thd,
}
else
{
- if (!thd->db)
+ if (!thd->db.str)
{
DBUG_ASSERT(create_db);
db_name.length= strlen(create_db);
@@ -7308,7 +7354,7 @@ bool check_fk_parent_table_access(THD *thd,
}
else
{
- if (thd->lex->copy_db_to(&db_name.str, &db_name.length))
+ if (thd->lex->copy_db_to(&db_name))
return true;
else
is_qualified_table_name= false;
@@ -7325,9 +7371,7 @@ bool check_fk_parent_table_access(THD *thd,
db_name.length= my_casedn_str(files_charset_info, (char*) db_name.str);
}
- parent_table.init_one_table(db_name.str, db_name.length,
- table_name.str, table_name.length,
- table_name.str, TL_IGNORE);
+ parent_table.init_one_table(&db_name, &table_name, 0, TL_IGNORE);
/*
Check if user has any of the "privileges" at table level on
@@ -7412,16 +7456,16 @@ bool check_stack_overrun(THD *thd, long margin,
#define MY_YACC_INIT 1000 // Start with big alloc
#define MY_YACC_MAX 32000 // Because of 'short'
-bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
+bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, size_t *yystacksize)
{
Yacc_state *state= & current_thd->m_parser_state->m_yacc;
- ulong old_info=0;
+ size_t old_info=0;
DBUG_ASSERT(state);
- if ((uint) *yystacksize >= MY_YACC_MAX)
+ if ( *yystacksize >= MY_YACC_MAX)
return 1;
if (!state->yacc_yyvs)
old_info= *yystacksize;
- *yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
+ *yystacksize= set_zone((int)(*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
if (!(state->yacc_yyvs= (uchar*)
my_realloc(state->yacc_yyvs,
*yystacksize*sizeof(**yyvs),
@@ -7462,22 +7506,26 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
void THD::reset_for_next_command(bool do_clear_error)
{
- THD *thd= this;
DBUG_ENTER("THD::reset_for_next_command");
- DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
- DBUG_ASSERT(! thd->in_sub_stmt);
+ DBUG_ASSERT(!spcont); /* not for substatements of routines */
+ DBUG_ASSERT(!in_sub_stmt);
if (do_clear_error)
clear_error(1);
- thd->free_list= 0;
- thd->select_number= 1;
+ free_list= 0;
+ /*
+ We also assign stmt_lex in lex_start(), but during bootstrap this
+ code is executed first.
+ */
+ stmt_lex= &main_lex; stmt_lex->current_select_number= 1;
+ DBUG_PRINT("info", ("Lex %p stmt_lex: %p", lex, stmt_lex));
/*
Those two lines below are theoretically unneeded as
THD::cleanup_after_query() should take care of this already.
*/
- thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
- thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
+ auto_inc_intervals_in_cur_stmt_for_binlog.empty();
+ stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
#ifdef WITH_WSREP
/*
@@ -7488,59 +7536,57 @@ void THD::reset_for_next_command(bool do_clear_error)
use autoinc values passed in binlog events, not the values forced by
the cluster.
*/
- if (WSREP(thd) && thd->wsrep_exec_mode == LOCAL_STATE &&
- !thd->slave_thread && wsrep_auto_increment_control)
+ if (WSREP(this) && wsrep_exec_mode == LOCAL_STATE &&
+ !slave_thread && wsrep_auto_increment_control)
{
- thd->variables.auto_increment_offset=
+ variables.auto_increment_offset=
global_system_variables.auto_increment_offset;
- thd->variables.auto_increment_increment=
+ variables.auto_increment_increment=
global_system_variables.auto_increment_increment;
}
#endif /* WITH_WSREP */
- thd->query_start_used= 0;
- thd->query_start_sec_part_used= 0;
- thd->is_fatal_error= thd->time_zone_used= 0;
- thd->log_current_statement= 0;
+ query_start_used= 0;
+ query_start_sec_part_used= 0;
+ is_fatal_error= time_zone_used= 0;
+ log_current_statement= 0;
/*
Clear the status flag that are expected to be cleared at the
beginning of each SQL statement.
*/
- thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
+ server_status&= ~SERVER_STATUS_CLEAR_SET;
/*
If in autocommit mode and not in a transaction, reset
OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
in ha_rollback_trans() about some tables couldn't be rolled back.
*/
- if (!thd->in_multi_stmt_transaction_mode())
+ if (!in_multi_stmt_transaction_mode())
{
- thd->variables.option_bits&= ~OPTION_KEEP_LOG;
- thd->transaction.all.reset();
+ variables.option_bits&= ~OPTION_KEEP_LOG;
+ transaction.all.reset();
}
- DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
- thd->thread_specific_used= FALSE;
+ DBUG_ASSERT(security_ctx== &main_security_ctx);
+ thread_specific_used= FALSE;
if (opt_bin_log)
- {
- reset_dynamic(&thd->user_var_events);
- thd->user_var_events_alloc= thd->mem_root;
- }
- thd->enable_slow_log= thd->variables.sql_log_slow;
- thd->get_stmt_da()->reset_for_next_command();
- thd->rand_used= 0;
- thd->m_sent_row_count= thd->m_examined_row_count= 0;
- thd->accessed_rows_and_keys= 0;
+ reset_dynamic(&user_var_events);
+ DBUG_ASSERT(user_var_events_alloc == &main_mem_root);
+ enable_slow_log= variables.sql_log_slow;
+ get_stmt_da()->reset_for_next_command();
+ rand_used= 0;
+ m_sent_row_count= m_examined_row_count= 0;
+ accessed_rows_and_keys= 0;
reset_slow_query_state();
- thd->reset_current_stmt_binlog_format_row();
- thd->binlog_unsafe_warning_flags= 0;
+ reset_current_stmt_binlog_format_row();
+ binlog_unsafe_warning_flags= 0;
- thd->save_prep_leaf_list= false;
+ save_prep_leaf_list= false;
DBUG_PRINT("debug",
("is_current_stmt_binlog_format_row(): %d",
- thd->is_current_stmt_binlog_format_row()));
+ is_current_stmt_binlog_format_row()));
DBUG_VOID_RETURN;
}
@@ -7591,7 +7637,7 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex)
{
if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
DBUG_RETURN(1);
- select_lex->select_number= ++thd->select_number;
+ select_lex->select_number= ++thd->stmt_lex->current_select_number;
select_lex->parent_lex= lex; /* Used in init_query. */
select_lex->init_query();
select_lex->init_select();
@@ -7793,7 +7839,8 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
(longlong) thd->thread_id, is_autocommit,
thd->wsrep_retry_counter,
thd->variables.wsrep_retry_autocommit, thd->query());
- my_message(ER_LOCK_DEADLOCK, "wsrep aborted transaction", MYF(0));
+ my_message(ER_LOCK_DEADLOCK, "Deadlock: wsrep aborted transaction",
+ MYF(0));
thd->reset_killed();
thd->wsrep_conflict_state= NO_CONFLICT;
if (thd->wsrep_conflict_state != REPLAYING)
@@ -7925,7 +7972,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length,
lex->set_trg_event_type_for_tables();
MYSQL_QUERY_EXEC_START(thd->query(),
thd->thread_id,
- (char *) (thd->db ? thd->db : ""),
+ thd->get_db(),
&thd->security_ctx->priv_user[0],
(char *) thd->security_ctx->host_or_ip,
0);
@@ -7952,7 +7999,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length,
sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
thd->end_statement();
thd->cleanup_after_query();
- DBUG_ASSERT(thd->change_list.is_empty());
+ DBUG_ASSERT(thd->Item_change_list::is_empty());
}
else
{
@@ -8077,13 +8124,14 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
{
register TABLE_LIST *ptr;
TABLE_LIST *UNINIT_VAR(previous_table_ref); /* The table preceding the current one. */
- const char *alias_str;
+ LEX_CSTRING alias_str;
LEX *lex= thd->lex;
DBUG_ENTER("add_table_to_list");
if (!table)
DBUG_RETURN(0); // End of memory
- alias_str= alias ? alias->str : table->table.str;
+ alias_str= alias ? *alias : table->table;
+ DBUG_ASSERT(alias_str.str);
if (!MY_TEST(table_options & TL_OPTION_ALIAS) &&
check_table_name(table->table.str, table->table.length, FALSE))
{
@@ -8098,7 +8146,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
DBUG_RETURN(0);
}
- if (!alias) /* Alias is case sensitive */
+ if (!alias) /* Alias is case sensitive */
{
if (table->sel)
{
@@ -8106,7 +8154,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ER_THD(thd, ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
DBUG_RETURN(0);
}
- if (!(alias_str= (char*) thd->memdup(alias_str,table->table.length+1)))
+ /* alias_str points to table->table; Let's make a copy */
+ if (!(alias_str.str= (char*) thd->memdup(alias_str.str, alias_str.length+1)))
DBUG_RETURN(0);
}
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
@@ -8114,10 +8163,9 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
if (table->db.str)
{
ptr->is_fqtn= TRUE;
- ptr->db= table->db.str;
- ptr->db_length= table->db.length;
+ ptr->db= table->db;
}
- else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
+ else if (lex->copy_db_to(&ptr->db))
DBUG_RETURN(0);
else
ptr->is_fqtn= FALSE;
@@ -8129,12 +8177,11 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
if (table->table.length)
table->table.length= my_casedn_str(files_charset_info,
(char*) table->table.str);
- if (ptr->db_length && ptr->db != any_db)
- ptr->db_length= my_casedn_str(files_charset_info, (char*) ptr->db);
+ if (ptr->db.length && ptr->db.str != any_db)
+ ptr->db.length= my_casedn_str(files_charset_info, (char*) ptr->db.str);
}
- ptr->table_name=table->table.str;
- ptr->table_name_length=table->table.length;
+ ptr->table_name= table->table;
ptr->lock_type= lock_type;
ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING);
/* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
@@ -8142,7 +8189,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->ignore_leaves= MY_TEST(table_options & TL_OPTION_IGNORE_LEAVES);
ptr->sequence= MY_TEST(table_options & TL_OPTION_SEQUENCE);
ptr->derived= table->sel;
- if (!ptr->derived && is_infoschema_db(ptr->db, ptr->db_length))
+ if (!ptr->derived && is_infoschema_db(&ptr->db))
{
ST_SCHEMA_TABLE *schema_table;
if (ptr->updating &&
@@ -8156,7 +8203,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
INFORMATION_SCHEMA_NAME.str);
DBUG_RETURN(0);
}
- schema_table= find_schema_table(thd, ptr->table_name);
+ schema_table= find_schema_table(thd, &ptr->table_name);
if (!schema_table ||
(schema_table->hidden &&
((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 ||
@@ -8167,7 +8214,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
lex->sql_command == SQLCOM_SHOW_KEYS)))
{
my_error(ER_UNKNOWN_TABLE, MYF(0),
- ptr->table_name, INFORMATION_SCHEMA_NAME.str);
+ ptr->table_name.str, INFORMATION_SCHEMA_NAME.str);
DBUG_RETURN(0);
}
ptr->schema_table_name= ptr->table_name;
@@ -8191,10 +8238,10 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
tables ;
tables=tables->next_local)
{
- if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
- !strcmp(ptr->db, tables->db) && ! tables->sequence)
+ if (!my_strcasecmp(table_alias_charset, alias_str.str, tables->alias.str) &&
+ !cmp(&ptr->db, &tables->db) && ! tables->sequence)
{
- my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
+ my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str.str); /* purecov: tested */
DBUG_RETURN(0); /* purecov: tested */
}
}
@@ -8240,7 +8287,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
// Pure table aliases do not need to be locked:
if (!MY_TEST(table_options & TL_OPTION_ALIAS))
{
- ptr->mdl_request.init(MDL_key::TABLE, ptr->db, ptr->table_name, mdl_type,
+ ptr->mdl_request.init(MDL_key::TABLE, ptr->db.str, ptr->table_name.str,
+ mdl_type,
MDL_TRANSACTION);
}
DBUG_RETURN(ptr);
@@ -8281,7 +8329,8 @@ bool st_select_lex::init_nested_join(THD *thd)
join_list->push_front(ptr, thd->mem_root);
ptr->embedding= embedding;
ptr->join_list= join_list;
- ptr->alias= (char*) "(nested_join)";
+ ptr->alias.str="(nested_join)";
+ ptr->alias.length= sizeof("(nested_join)")-1;
embedding= ptr;
join_list= &nested_join->join_list;
join_list->empty();
@@ -8361,7 +8410,8 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
ptr->embedding= embedding;
ptr->join_list= join_list;
- ptr->alias= (char*) "(nest_last_join)";
+ ptr->alias.str= "(nest_last_join)";
+ ptr->alias.length= sizeof("(nest_last_join)")-1;
embedded_list= &nested_join->join_list;
embedded_list->empty();
@@ -8747,13 +8797,13 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
/**
- Find a thread by id and return it, locking it LOCK_thd_data
+ Find a thread by id and return it, locking it LOCK_thd_kill
@param id Identifier of the thread we're looking for
@param query_id If true, search by query_id instead of thread_id
@return NULL - not found
- pointer - thread found, and its LOCK_thd_data is locked.
+ pointer - thread found, and its LOCK_thd_kill is locked.
*/
THD *find_thread_by_id(longlong id, bool query_id)
@@ -8767,7 +8817,7 @@ THD *find_thread_by_id(longlong id, bool query_id)
continue;
if (id == (query_id ? tmp->query_id : (longlong) tmp->thread_id))
{
- mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
+ mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete
break;
}
}
@@ -8823,13 +8873,13 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
thd->security_ctx->user_matches(tmp->security_ctx)) &&
!wsrep_thd_is_BF(tmp, true))
{
- tmp->awake(kill_signal);
+ tmp->awake_no_mutex(kill_signal);
error=0;
}
else
error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
ER_KILL_DENIED_ERROR);
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
}
DBUG_PRINT("exit", ("%d", error));
DBUG_RETURN(error);
@@ -8887,7 +8937,7 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user,
DBUG_RETURN(ER_KILL_DENIED_ERROR);
}
if (!threads_to_kill.push_back(tmp, thd->mem_root))
- mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
+ mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete
}
}
mysql_mutex_unlock(&LOCK_thread_count);
@@ -8898,17 +8948,17 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user,
THD *ptr= it2++;
do
{
- ptr->awake(kill_signal);
+ ptr->awake_no_mutex(kill_signal);
/*
Careful here: The list nodes are allocated on the memroots of the
THDs to be awakened.
But those THDs may be terminated and deleted as soon as we release
- LOCK_thd_data, which will make the list nodes invalid.
+ LOCK_thd_kill, which will make the list nodes invalid.
Since the operation "it++" dereferences the "next" pointer of the
- previous list node, we need to do this while holding LOCK_thd_data.
+ previous list node, we need to do this while holding LOCK_thd_kill.
*/
next_ptr= it2++;
- mysql_mutex_unlock(&ptr->LOCK_thd_data);
+ mysql_mutex_unlock(&ptr->LOCK_thd_kill);
(*rows)++;
} while ((ptr= next_ptr));
}
@@ -8962,14 +9012,14 @@ void sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
/** If pointer is not a null pointer, append filename to it. */
bool append_file_to_dir(THD *thd, const char **filename_ptr,
- const char *table_name)
+ const LEX_CSTRING *table_name)
{
char buff[FN_REFLEN],*ptr, *end;
if (!*filename_ptr)
return 0; // nothing to do
/* Check that the filename is not too long and it's a hard path */
- if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
+ if (strlen(*filename_ptr)+table_name->length >= FN_REFLEN-1 ||
!test_if_hard_path(*filename_ptr))
{
my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
@@ -8978,10 +9028,10 @@ bool append_file_to_dir(THD *thd, const char **filename_ptr,
/* Fix is using unix filename format on dos */
strmov(buff,*filename_ptr);
end=convert_dirname(buff, *filename_ptr, NullS);
- if (!(ptr= (char*) thd->alloc((size_t) (end-buff) + strlen(table_name)+1)))
+ if (!(ptr= (char*) thd->alloc((size_t) (end-buff) + table_name->length + 1)))
return 1; // End of memory
*filename_ptr=ptr;
- strxmov(ptr,buff,table_name,NullS);
+ strxmov(ptr,buff,table_name->str,NullS);
return 0;
}
@@ -9116,12 +9166,12 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
continue;
if (table->derived)
table->grant.privilege= SELECT_ACL;
- else if ((check_access(thd, UPDATE_ACL, table->db,
+ else if ((check_access(thd, UPDATE_ACL, table->db.str,
&table->grant.privilege,
&table->grant.m_internal,
0, 1) ||
check_grant(thd, UPDATE_ACL, table, FALSE, 1, TRUE)) &&
- (check_access(thd, SELECT_ACL, table->db,
+ (check_access(thd, SELECT_ACL, table->db.str,
&table->grant.privilege,
&table->grant.m_internal,
0, 0) ||
@@ -9141,7 +9191,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
{
if (!table->table_in_first_from_clause)
{
- if (check_access(thd, SELECT_ACL, table->db,
+ if (check_access(thd, SELECT_ACL, table->db.str,
&table->grant.privilege,
&table->grant.m_internal,
0, 0) ||
@@ -9239,25 +9289,25 @@ static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl,
for (TABLE_LIST *elem= tables; elem; elem= elem->next_local)
{
- int cmp;
+ int res;
if (tbl->is_fqtn && elem->is_alias)
continue; /* no match */
if (tbl->is_fqtn && elem->is_fqtn)
- cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
- strcmp(tbl->db, elem->db);
+ res= (my_strcasecmp(table_alias_charset, tbl->table_name.str, elem->table_name.str) ||
+ cmp(&tbl->db, &elem->db));
else if (elem->is_alias)
- cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
+ res= my_strcasecmp(table_alias_charset, tbl->alias.str, elem->alias.str);
else
- cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
- strcmp(tbl->db, elem->db);
+ res= (my_strcasecmp(table_alias_charset, tbl->table_name.str, elem->table_name.str) ||
+ cmp(&tbl->db, &elem->db));
- if (cmp)
+ if (res)
continue;
if (match)
{
- my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
+ my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias.str);
DBUG_RETURN(NULL);
}
@@ -9265,7 +9315,7 @@ static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl,
}
if (!match)
- my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
+ my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name.str, "MULTI DELETE");
DBUG_RETURN(match);
}
@@ -9300,10 +9350,7 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
if (!walk)
DBUG_RETURN(TRUE);
if (!walk->derived)
- {
target_tbl->table_name= walk->table_name;
- target_tbl->table_name_length= walk->table_name_length;
- }
walk->updating= target_tbl->updating;
walk->lock_type= target_tbl->lock_type;
/* We can assume that tables to be deleted from are locked for write. */
@@ -9354,10 +9401,18 @@ bool update_precheck(THD *thd, TABLE_LIST *tables)
bool delete_precheck(THD *thd, TABLE_LIST *tables)
{
DBUG_ENTER("delete_precheck");
- if (check_one_table_access(thd, DELETE_ACL, tables))
- DBUG_RETURN(TRUE);
- /* Set privilege for the WHERE clause */
- tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
+ if (tables->vers_conditions)
+ {
+ if (check_one_table_access(thd, DELETE_HISTORY_ACL, tables))
+ DBUG_RETURN(TRUE);
+ }
+ else
+ {
+ if (check_one_table_access(thd, DELETE_ACL, tables))
+ DBUG_RETURN(TRUE);
+ /* Set privilege for the WHERE clause */
+ tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
+ }
DBUG_RETURN(FALSE);
}
@@ -9461,7 +9516,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
if (lex->create_info.or_replace() && !lex->tmp_table())
want_priv|= DROP_ACL;
- if (check_access(thd, want_priv, create_table->db,
+ if (check_access(thd, want_priv, create_table->db.str,
&create_table->grant.privilege,
&create_table->grant.m_internal,
0, 0))
@@ -9528,7 +9583,8 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
goto err;
}
- if (check_fk_parent_table_access(thd, &lex->create_info, &lex->alter_info, create_table->db))
+ if (check_fk_parent_table_access(thd, &lex->create_info, &lex->alter_info,
+ create_table->db.str))
goto err;
error= FALSE;
@@ -9708,7 +9764,7 @@ LEX_USER *create_definer(THD *thd, LEX_CSTRING *user_name,
*/
bool check_string_byte_length(const LEX_CSTRING *str, uint err_msg,
- uint max_byte_length)
+ size_t max_byte_length)
{
if (str->length <= max_byte_length)
return FALSE;
@@ -9738,7 +9794,7 @@ bool check_string_byte_length(const LEX_CSTRING *str, uint err_msg,
bool check_string_char_length(const LEX_CSTRING *str, uint err_msg,
- uint max_char_length, CHARSET_INFO *cs,
+ size_t max_char_length, CHARSET_INFO *cs,
bool no_error)
{
Well_formed_prefix prefix(cs, str->str, str->length, max_char_length);
@@ -9782,7 +9838,7 @@ extern "C" {
int path_starts_from_data_home_dir(const char *path)
{
- int dir_len= strlen(path);
+ size_t dir_len= strlen(path);
DBUG_ENTER("path_starts_from_data_home_dir");
if (mysql_unpacked_real_data_home_len<= dir_len)
diff --git a/sql/sql_parse.h b/sql/sql_parse.h
index b0371a2cb81..d23da6f1b68 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -73,9 +73,9 @@ LEX_USER *create_definer(THD *thd, LEX_CSTRING *user_name, LEX_CSTRING *host_nam
LEX_USER *get_current_user(THD *thd, LEX_USER *user, bool lock=true);
bool sp_process_definer(THD *thd);
bool check_string_byte_length(const LEX_CSTRING *str, uint err_msg,
- uint max_byte_length);
+ size_t max_byte_length);
bool check_string_char_length(const LEX_CSTRING *str, uint err_msg,
- uint max_char_length, CHARSET_INFO *cs,
+ size_t max_char_length, CHARSET_INFO *cs,
bool no_error);
bool check_ident_length(const LEX_CSTRING *ident);
CHARSET_INFO* merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl);
@@ -87,7 +87,7 @@ bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
bool sqlcom_can_generate_row_events(const THD *thd);
bool is_update_query(enum enum_sql_command command);
bool is_log_table_write_query(enum enum_sql_command command);
-bool alloc_query(THD *thd, const char *packet, uint packet_length);
+bool alloc_query(THD *thd, const char *packet, size_t packet_length);
void mysql_init_select(LEX *lex);
void mysql_parse(THD *thd, char *rawbuf, uint length,
Parser_state *parser_state, bool is_com_multi,
@@ -107,9 +107,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
bool is_com_multi, bool is_next_command);
void log_slow_statement(THD *thd);
bool append_file_to_dir(THD *thd, const char **filename_ptr,
- const char *table_name);
-bool append_file_to_dir(THD *thd, const char **filename_ptr,
- const char *table_name);
+ const LEX_CSTRING *table_name);
void execute_init_command(THD *thd, LEX_STRING *init_command,
mysql_rwlock_t *var_lock);
bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *group, bool asc);
@@ -131,7 +129,7 @@ bool check_stack_overrun(THD *thd, long margin, uchar *dummy);
extern const char* any_db;
extern uint sql_command_flags[];
extern uint server_command_flags[];
-extern const LEX_STRING command_name[];
+extern const LEX_CSTRING command_name[];
extern uint server_command_flags[];
/* Inline functions */
@@ -149,8 +147,9 @@ inline bool check_identifier_name(LEX_CSTRING *str)
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables);
bool check_single_table_access(THD *thd, ulong privilege,
TABLE_LIST *tables, bool no_errors);
-bool check_routine_access(THD *thd,ulong want_access,const char *db,
- const char *name,
+bool check_routine_access(THD *thd,ulong want_access,
+ const LEX_CSTRING *db,
+ const LEX_CSTRING *name,
const Sp_handler *sph, bool no_errors);
bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);
bool check_some_routine_access(THD *thd, const char *db, const char *name,
@@ -165,8 +164,9 @@ inline bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables
inline bool check_single_table_access(THD *thd, ulong privilege,
TABLE_LIST *tables, bool no_errors)
{ return false; }
-inline bool check_routine_access(THD *thd,ulong want_access, const char *db,
- const char *name,
+inline bool check_routine_access(THD *thd,ulong want_access,
+ const LEX_CSTRING *db,
+ const LEX_CSTRING *name,
const Sp_handler *sph, bool no_errors)
{ return false; }
inline bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index fadd7009822..239e8098ffd 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -67,6 +67,8 @@
#include "opt_range.h" // store_key_image_to_rec
#include "sql_alter.h" // Alter_table_ctx
#include "sql_select.h"
+#include "sql_tablespace.h" // check_tablespace_name
+#include "tztime.h" // my_tz_OFFSET0
#include <algorithm>
using std::max;
@@ -87,6 +89,7 @@ static int get_partition_id_list_col(partition_info *, uint32 *, longlong *);
static int get_partition_id_list(partition_info *, uint32 *, longlong *);
static int get_partition_id_range_col(partition_info *, uint32 *, longlong *);
static int get_partition_id_range(partition_info *, uint32 *, longlong *);
+static int vers_get_partition_id(partition_info *, uint32 *, longlong *);
static int get_part_id_charset_func_part(partition_info *, uint32 *, longlong *);
static int get_part_id_charset_func_subpart(partition_info *, uint32 *);
static int get_partition_id_hash_nosub(partition_info *, uint32 *, longlong *);
@@ -105,27 +108,12 @@ static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR*);
uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter);
uint32 get_next_partition_id_list(PARTITION_ITERATOR* part_iter);
-int get_part_iter_for_interval_via_mapping(partition_info *part_info,
- bool is_subpart,
- uint32 *store_length_array,
- uchar *min_value, uchar *max_value,
- uint min_len, uint max_len,
- uint flags,
- PARTITION_ITERATOR *part_iter);
-int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
- bool is_subpart,
- uint32 *store_length_array,
- uchar *min_value, uchar *max_value,
- uint min_len, uint max_len,
- uint flags,
- PARTITION_ITERATOR *part_iter);
-int get_part_iter_for_interval_via_walking(partition_info *part_info,
- bool is_subpart,
- uint32 *store_length_array,
- uchar *min_value, uchar *max_value,
- uint min_len, uint max_len,
- uint flags,
- PARTITION_ITERATOR *part_iter);
+static int get_part_iter_for_interval_via_mapping(partition_info *, bool,
+ uint32 *, uchar *, uchar *, uint, uint, uint, PARTITION_ITERATOR *);
+static int get_part_iter_for_interval_cols_via_map(partition_info *, bool,
+ uint32 *, uchar *, uchar *, uint, uint, uint, PARTITION_ITERATOR *);
+static int get_part_iter_for_interval_via_walking(partition_info *, bool,
+ uint32 *, uchar *, uchar *, uint, uint, uint, PARTITION_ITERATOR *);
#ifdef WITH_PARTITION_STORAGE_ENGINE
static int cmp_rec_and_tuple(part_column_list_val *val, uint32 nvals_in_rec);
@@ -244,82 +232,11 @@ bool partition_default_handling(THD *thd, TABLE *table, partition_info *part_inf
/*
- A useful routine used by update_row for partition handlers to calculate
- the partition ids of the old and the new record.
+ A useful routine used by update/delete_row for partition handlers to
+ calculate the partition id.
SYNOPSIS
- get_part_for_update()
- old_data Buffer of old record
- new_data Buffer of new record
- rec0 Reference to table->record[0]
- part_info Reference to partition information
- out:old_part_id The returned partition id of old record
- out:new_part_id The returned partition id of new record
-
- RETURN VALUE
- 0 Success
- > 0 Error code
-*/
-
-int get_parts_for_update(const uchar *old_data, const uchar *new_data,
- const uchar *rec0, partition_info *part_info,
- uint32 *old_part_id, uint32 *new_part_id,
- longlong *new_func_value)
-{
- Field **part_field_array= part_info->full_part_field_array;
- int error;
- longlong old_func_value;
- DBUG_ENTER("get_parts_for_update");
-
- DBUG_ASSERT(new_data == rec0); // table->record[0]
- part_info->table->move_fields(part_field_array, old_data, rec0);
- error= part_info->get_partition_id(part_info, old_part_id,
- &old_func_value);
- part_info->table->move_fields(part_field_array, rec0, old_data);
- if (unlikely(error)) // Should never happen
- {
- DBUG_ASSERT(0);
- DBUG_RETURN(error);
- }
-#ifdef NOT_NEEDED
- if (new_data == rec0)
-#endif
- {
- if (unlikely(error= part_info->get_partition_id(part_info,
- new_part_id,
- new_func_value)))
- {
- DBUG_RETURN(error);
- }
- }
-#ifdef NOT_NEEDED
- else
- {
- /*
- This branch should never execute but it is written anyways for
- future use. It will be tested by ensuring that the above
- condition is false in one test situation before pushing the code.
- */
- part_info->table->move_fields(part_field_array, new_data, rec0);
- error= part_info->get_partition_id(part_info, new_part_id,
- new_func_value);
- part_info->table->move_fields(part_field_array, rec0, new_data);
- if (unlikely(error))
- {
- DBUG_RETURN(error);
- }
- }
-#endif
- DBUG_RETURN(0);
-}
-
-
-/*
- A useful routine used by delete_row for partition handlers to calculate
- the partition id.
-
- SYNOPSIS
- get_part_for_delete()
+ get_part_for_buf()
buf Buffer of old record
rec0 Reference to table->record[0]
part_info Reference to partition information
@@ -335,21 +252,19 @@ int get_parts_for_update(const uchar *old_data, const uchar *new_data,
calculate the partition id.
*/
-int get_part_for_delete(const uchar *buf, const uchar *rec0,
- partition_info *part_info, uint32 *part_id)
+int get_part_for_buf(const uchar *buf, const uchar *rec0,
+ partition_info *part_info, uint32 *part_id)
{
int error;
longlong func_value;
- DBUG_ENTER("get_part_for_delete");
+ DBUG_ENTER("get_part_for_buf");
- if (likely(buf == rec0))
+ if (buf == rec0)
{
- if (unlikely((error= part_info->get_partition_id(part_info, part_id,
- &func_value))))
- {
- DBUG_RETURN(error);
- }
- DBUG_PRINT("info", ("Delete from partition %d", *part_id));
+ error= part_info->get_partition_id(part_info, part_id, &func_value);
+ if (unlikely((error)))
+ goto err;
+ DBUG_PRINT("info", ("Partition %d", *part_id));
}
else
{
@@ -358,12 +273,13 @@ int get_part_for_delete(const uchar *buf, const uchar *rec0,
error= part_info->get_partition_id(part_info, part_id, &func_value);
part_info->table->move_fields(part_field_array, rec0, buf);
if (unlikely(error))
- {
- DBUG_RETURN(error);
- }
- DBUG_PRINT("info", ("Delete from partition %d (path2)", *part_id));
+ goto err;
+ DBUG_PRINT("info", ("Partition %d (path2)", *part_id));
}
DBUG_RETURN(0);
+err:
+ part_info->err_value= func_value;
+ DBUG_RETURN(error);
}
@@ -1249,6 +1165,424 @@ static void set_up_partition_key_maps(TABLE *table,
DBUG_VOID_RETURN;
}
+static bool check_no_constants(THD *, partition_info*)
+{
+ return FALSE;
+}
+
+/*
+ Support routines for check_list_constants used by qsort to sort the
+ constant list expressions. One routine for integers and one for
+ column lists.
+
+ SYNOPSIS
+ list_part_cmp()
+ a First list constant to compare with
+ b Second list constant to compare with
+
+ RETURN VALUE
+ +1 a > b
+ 0 a == b
+ -1 a < b
+*/
+
+extern "C"
+int partition_info_list_part_cmp(const void* a, const void* b)
+{
+ longlong a1= ((LIST_PART_ENTRY*)a)->list_value;
+ longlong b1= ((LIST_PART_ENTRY*)b)->list_value;
+ if (a1 < b1)
+ return -1;
+ else if (a1 > b1)
+ return +1;
+ else
+ return 0;
+}
+
+
+/*
+ Compare two lists of column values in RANGE/LIST partitioning
+ SYNOPSIS
+ partition_info_compare_column_values()
+ first First column list argument
+ second Second column list argument
+ RETURN VALUES
+ 0 Equal
+ -1 First argument is smaller
+ +1 First argument is larger
+*/
+
+extern "C"
+int partition_info_compare_column_values(const void *first_arg,
+ const void *second_arg)
+{
+ const part_column_list_val *first= (part_column_list_val*)first_arg;
+ const part_column_list_val *second= (part_column_list_val*)second_arg;
+ partition_info *part_info= first->part_info;
+ Field **field;
+
+ for (field= part_info->part_field_array; *field;
+ field++, first++, second++)
+ {
+ if (first->max_value || second->max_value)
+ {
+ if (first->max_value && second->max_value)
+ return 0;
+ if (second->max_value)
+ return -1;
+ else
+ return +1;
+ }
+ if (first->null_value || second->null_value)
+ {
+ if (first->null_value && second->null_value)
+ continue;
+ if (second->null_value)
+ return +1;
+ else
+ return -1;
+ }
+ int res= (*field)->cmp((const uchar*)first->column_value,
+ (const uchar*)second->column_value);
+ if (res)
+ return res;
+ }
+ return 0;
+}
+
+
+/*
+ This routine allocates an array for all range constants to achieve a fast
+ check what partition a certain value belongs to. At the same time it does
+ also check that the range constants are defined in increasing order and
+ that the expressions are constant integer expressions.
+
+ SYNOPSIS
+ check_range_constants()
+ thd Thread object
+
+ RETURN VALUE
+ TRUE An error occurred during creation of range constants
+ FALSE Successful creation of range constant mapping
+
+ DESCRIPTION
+ This routine is called from check_partition_info to get a quick error
+ before we came too far into the CREATE TABLE process. It is also called
+ from fix_partition_func every time we open the .frm file. It is only
+ called for RANGE PARTITIONed tables.
+*/
+
+static bool check_range_constants(THD *thd, partition_info *part_info)
+{
+ partition_element* part_def;
+ bool first= TRUE;
+ uint i;
+ List_iterator<partition_element> it(part_info->partitions);
+ bool result= TRUE;
+ DBUG_ENTER("check_range_constants");
+ DBUG_PRINT("enter", ("RANGE with %d parts, column_list = %u",
+ part_info->num_parts, part_info->column_list));
+
+ if (part_info->column_list)
+ {
+ part_column_list_val *loc_range_col_array;
+ part_column_list_val *UNINIT_VAR(current_largest_col_val);
+ uint num_column_values= part_info->part_field_list.elements;
+ uint size_entries= sizeof(part_column_list_val) * num_column_values;
+ part_info->range_col_array= (part_column_list_val*)
+ thd->calloc(part_info->num_parts * size_entries);
+ if (part_info->range_col_array == NULL)
+ {
+ mem_alloc_error(part_info->num_parts * size_entries);
+ goto end;
+ }
+ loc_range_col_array= part_info->range_col_array;
+ i= 0;
+ do
+ {
+ part_def= it++;
+ {
+ List_iterator<part_elem_value> list_val_it(part_def->list_val_list);
+ part_elem_value *range_val= list_val_it++;
+ part_column_list_val *col_val= range_val->col_val_array;
+
+ if (part_info->fix_column_value_functions(thd, range_val, i))
+ goto end;
+ memcpy(loc_range_col_array, (const void*)col_val, size_entries);
+ loc_range_col_array+= num_column_values;
+ if (!first)
+ {
+ if (partition_info_compare_column_values(current_largest_col_val,
+ col_val) >= 0)
+ goto range_not_increasing_error;
+ }
+ current_largest_col_val= col_val;
+ }
+ first= FALSE;
+ } while (++i < part_info->num_parts);
+ }
+ else
+ {
+ longlong UNINIT_VAR(current_largest);
+ longlong part_range_value;
+ bool signed_flag= !part_info->part_expr->unsigned_flag;
+
+ part_info->range_int_array= (longlong*)
+ thd->alloc(part_info->num_parts * sizeof(longlong));
+ if (part_info->range_int_array == NULL)
+ {
+ mem_alloc_error(part_info->num_parts * sizeof(longlong));
+ goto end;
+ }
+ i= 0;
+ do
+ {
+ part_def= it++;
+ if ((i != part_info->num_parts - 1) || !part_info->defined_max_value)
+ {
+ part_range_value= part_def->range_value;
+ if (!signed_flag)
+ part_range_value-= 0x8000000000000000ULL;
+ }
+ else
+ part_range_value= LONGLONG_MAX;
+
+ if (!first)
+ {
+ if (current_largest > part_range_value ||
+ (current_largest == part_range_value &&
+ (part_range_value < LONGLONG_MAX ||
+ i != part_info->num_parts - 1 ||
+ !part_info->defined_max_value)))
+ goto range_not_increasing_error;
+ }
+ part_info->range_int_array[i]= part_range_value;
+ current_largest= part_range_value;
+ first= FALSE;
+ } while (++i < part_info->num_parts);
+ }
+ result= FALSE;
+end:
+ DBUG_RETURN(result);
+
+range_not_increasing_error:
+ my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
+ goto end;
+}
+
+
+/*
+ This routine allocates an array for all list constants to achieve a fast
+ check what partition a certain value belongs to. At the same time it does
+ also check that there are no duplicates among the list constants and that
+ that the list expressions are constant integer expressions.
+
+ SYNOPSIS
+ check_list_constants()
+ thd Thread object
+
+ RETURN VALUE
+ TRUE An error occurred during creation of list constants
+ FALSE Successful creation of list constant mapping
+
+ DESCRIPTION
+ This routine is called from check_partition_info to get a quick error
+ before we came too far into the CREATE TABLE process. It is also called
+ from fix_partition_func every time we open the .frm file. It is only
+ called for LIST PARTITIONed tables.
+*/
+
+static bool check_list_constants(THD *thd, partition_info *part_info)
+{
+ uint i, size_entries, num_column_values;
+ uint list_index= 0;
+ part_elem_value *list_value;
+ bool result= TRUE;
+ longlong type_add, calc_value;
+ void *curr_value;
+ void *UNINIT_VAR(prev_value);
+ partition_element* part_def;
+ bool found_null= FALSE;
+ qsort_cmp compare_func;
+ void *ptr;
+ List_iterator<partition_element> list_func_it(part_info->partitions);
+ DBUG_ENTER("check_list_constants");
+
+ DBUG_ASSERT(part_info->part_type == LIST_PARTITION);
+
+ part_info->num_list_values= 0;
+ /*
+ We begin by calculating the number of list values that have been
+ defined in the first step.
+
+ We use this number to allocate a properly sized array of structs
+ to keep the partition id and the value to use in that partition.
+ In the second traversal we assign them values in the struct array.
+
+ Finally we sort the array of structs in order of values to enable
+ a quick binary search for the proper value to discover the
+ partition id.
+ After sorting the array we check that there are no duplicates in the
+ list.
+ */
+
+ i= 0;
+ do
+ {
+ part_def= list_func_it++;
+ if (part_def->has_null_value)
+ {
+ if (found_null)
+ {
+ my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
+ goto end;
+ }
+ part_info->has_null_value= TRUE;
+ part_info->has_null_part_id= i;
+ found_null= TRUE;
+ }
+ part_info->num_list_values+= part_def->list_val_list.elements;
+ } while (++i < part_info->num_parts);
+ list_func_it.rewind();
+ num_column_values= part_info->part_field_list.elements;
+ size_entries= part_info->column_list ?
+ (num_column_values * sizeof(part_column_list_val)) :
+ sizeof(LIST_PART_ENTRY);
+ if (!(ptr= thd->calloc((part_info->num_list_values+1) * size_entries)))
+ goto end;
+ if (part_info->column_list)
+ {
+ part_column_list_val *loc_list_col_array;
+ loc_list_col_array= (part_column_list_val*)ptr;
+ part_info->list_col_array= (part_column_list_val*)ptr;
+ compare_func= partition_info_compare_column_values;
+ i= 0;
+ do
+ {
+ part_def= list_func_it++;
+ if (part_def->max_value)
+ {
+ // DEFAULT is not a real value so let's exclude it from sorting.
+ DBUG_ASSERT(part_info->num_list_values);
+ part_info->num_list_values--;
+ continue;
+ }
+ List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
+ while ((list_value= list_val_it2++))
+ {
+ part_column_list_val *col_val= list_value->col_val_array;
+ if (part_info->fix_column_value_functions(thd, list_value, i))
+ DBUG_RETURN(result);
+ memcpy(loc_list_col_array, (const void*)col_val, size_entries);
+ loc_list_col_array+= num_column_values;
+ }
+ } while (++i < part_info->num_parts);
+ }
+ else
+ {
+ compare_func= partition_info_list_part_cmp;
+ part_info->list_array= (LIST_PART_ENTRY*)ptr;
+ i= 0;
+ /*
+ Fix to be able to reuse signed sort functions also for unsigned
+ partition functions.
+ */
+ type_add= (longlong)(part_info->part_expr->unsigned_flag ?
+ 0x8000000000000000ULL :
+ 0ULL);
+
+ do
+ {
+ part_def= list_func_it++;
+ if (part_def->max_value)
+ {
+ // DEFAULT is not a real value so let's exclude it from sorting.
+ DBUG_ASSERT(part_info->num_list_values);
+ part_info->num_list_values--;
+ continue;
+ }
+ List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
+ while ((list_value= list_val_it2++))
+ {
+ calc_value= list_value->value - type_add;
+ part_info->list_array[list_index].list_value= calc_value;
+ part_info->list_array[list_index++].partition_id= i;
+ }
+ } while (++i < part_info->num_parts);
+ }
+ DBUG_ASSERT(part_info->fixed);
+ if (part_info->num_list_values)
+ {
+ bool first= TRUE;
+ /*
+ list_array and list_col_array are unions, so this works for both
+ variants of LIST partitioning.
+ */
+ my_qsort(part_info->list_array, part_info->num_list_values, size_entries,
+ compare_func);
+
+ i= 0;
+ do
+ {
+ DBUG_ASSERT(i < part_info->num_list_values);
+ curr_value= part_info->column_list
+ ? (void*)&part_info->list_col_array[num_column_values * i]
+ : (void*)&part_info->list_array[i];
+ if (likely(first || compare_func(curr_value, prev_value)))
+ {
+ prev_value= curr_value;
+ first= FALSE;
+ }
+ else
+ {
+ my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
+ goto end;
+ }
+ } while (++i < part_info->num_list_values);
+ }
+ result= FALSE;
+end:
+ DBUG_RETURN(result);
+}
+
+
+/* Set partition boundaries when rotating by INTERVAL */
+static bool check_vers_constants(THD *thd, partition_info *part_info)
+{
+ uint hist_parts= part_info->num_parts - 1;
+ Vers_part_info *vers_info= part_info->vers_info;
+ vers_info->hist_part= part_info->partitions.head();
+ vers_info->now_part= part_info->partitions.elem(hist_parts);
+
+ if (!vers_info->interval.is_set())
+ return 0;
+
+ part_info->range_int_array=
+ (longlong*) thd->alloc(hist_parts * sizeof(longlong));
+
+ MYSQL_TIME ltime;
+ List_iterator<partition_element> it(part_info->partitions);
+ partition_element *el;
+ my_tz_OFFSET0->gmt_sec_to_TIME(&ltime, vers_info->interval.start);
+ while ((el= it++)->id < hist_parts)
+ {
+ if (date_add_interval(&ltime, vers_info->interval.type,
+ vers_info->interval.step))
+ goto err;
+ uint error= 0;
+ part_info->range_int_array[el->id]= el->range_value=
+ my_tz_OFFSET0->TIME_to_gmt_sec(&ltime, &error);
+ if (error)
+ goto err;
+ if (vers_info->hist_part->range_value <= thd->system_time)
+ vers_info->hist_part= el;
+ }
+ return 0;
+err:
+ my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "TIMESTAMP", "INTERVAL");
+ return 1;
+}
+
/*
Set up function pointers for partition function
@@ -1295,6 +1629,24 @@ static void set_up_partition_func_pointers(partition_info *part_info)
part_info->get_subpartition_id= get_partition_id_hash_sub;
}
}
+ else if (part_info->part_type == VERSIONING_PARTITION)
+ {
+ part_info->get_part_partition_id= vers_get_partition_id;
+ if (part_info->list_of_subpart_fields)
+ {
+ if (part_info->linear_hash_ind)
+ part_info->get_subpartition_id= get_partition_id_linear_key_sub;
+ else
+ part_info->get_subpartition_id= get_partition_id_key_sub;
+ }
+ else
+ {
+ if (part_info->linear_hash_ind)
+ part_info->get_subpartition_id= get_partition_id_linear_hash_sub;
+ else
+ part_info->get_subpartition_id= get_partition_id_hash_sub;
+ }
+ }
else /* LIST Partitioning */
{
if (part_info->column_list)
@@ -1335,6 +1687,10 @@ static void set_up_partition_func_pointers(partition_info *part_info)
else
part_info->get_partition_id= get_partition_id_list;
}
+ else if (part_info->part_type == VERSIONING_PARTITION)
+ {
+ part_info->get_partition_id= vers_get_partition_id;
+ }
else /* HASH partitioning */
{
if (part_info->list_of_part_fields)
@@ -1391,6 +1747,14 @@ static void set_up_partition_func_pointers(partition_info *part_info)
part_info->get_subpartition_id;
part_info->get_subpartition_id= get_part_id_charset_func_subpart;
}
+ if (part_info->part_type == RANGE_PARTITION)
+ part_info->check_constants= check_range_constants;
+ else if (part_info->part_type == LIST_PARTITION)
+ part_info->check_constants= check_list_constants;
+ else if (part_info->part_type == VERSIONING_PARTITION)
+ part_info->check_constants= check_vers_constants;
+ else
+ part_info->check_constants= check_no_constants;
DBUG_VOID_RETURN;
}
@@ -1554,20 +1918,19 @@ NOTES
of an error that is not discovered until here.
*/
-bool fix_partition_func(THD *thd, TABLE *table,
- bool is_create_table_ind)
+bool fix_partition_func(THD *thd, TABLE *table, bool is_create_table_ind)
{
bool result= TRUE;
partition_info *part_info= table->part_info;
- enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
+ enum_column_usage saved_column_usage= thd->column_usage;
DBUG_ENTER("fix_partition_func");
if (part_info->fixed)
{
DBUG_RETURN(FALSE);
}
- thd->mark_used_columns= MARK_COLUMNS_NONE;
- DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
+ thd->column_usage= COLUMNS_WRITE;
+ DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
if (!is_create_table_ind ||
thd->lex->sql_command != SQLCOM_CREATE_TABLE)
@@ -1607,10 +1970,12 @@ bool fix_partition_func(THD *thd, TABLE *table,
}
}
DBUG_ASSERT(part_info->part_type != NOT_A_PARTITION);
+ DBUG_ASSERT(part_info->part_type != VERSIONING_PARTITION || part_info->column_list);
/*
Partition is defined. We need to verify that partitioning
function is correct.
*/
+ set_up_partition_func_pointers(part_info);
if (part_info->part_type == HASH_PARTITION)
{
if (part_info->linear_hash_ind)
@@ -1636,9 +2001,11 @@ bool fix_partition_func(THD *thd, TABLE *table,
}
else
{
- const char *error_str;
if (part_info->column_list)
{
+ if (part_info->part_type == VERSIONING_PARTITION &&
+ part_info->vers_setup_expression(thd))
+ goto end;
List_iterator<const char> it(part_info->part_field_list);
if (unlikely(handle_list_of_fields(thd, it, table, part_info, FALSE)))
goto end;
@@ -1650,26 +2017,12 @@ bool fix_partition_func(THD *thd, TABLE *table,
goto end;
}
part_info->fixed= TRUE;
- if (part_info->part_type == RANGE_PARTITION)
- {
- error_str= "HASH";
- if (unlikely(part_info->check_range_constants(thd)))
- goto end;
- }
- else if (part_info->part_type == LIST_PARTITION)
- {
- error_str= "LIST";
- if (unlikely(part_info->check_list_constants(thd)))
- goto end;
- }
- else
- {
- DBUG_ASSERT(0);
- my_error(ER_INCONSISTENT_PARTITION_INFO_ERROR, MYF(0));
+ if (part_info->check_constants(thd, part_info))
goto end;
- }
if (unlikely(part_info->num_parts < 1))
{
+ const char *error_str= part_info->part_type == LIST_PARTITION
+ ? "LIST" : "RANGE";
my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), error_str);
goto end;
}
@@ -1717,13 +2070,12 @@ bool fix_partition_func(THD *thd, TABLE *table,
}
check_range_capable_PF(table);
set_up_partition_key_maps(table, part_info);
- set_up_partition_func_pointers(part_info);
set_up_range_analysis_info(part_info);
table->file->set_part_info(part_info);
result= FALSE;
end:
- thd->mark_used_columns= save_mark_used_columns;
- DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
+ thd->column_usage= saved_column_usage;
+ DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
DBUG_RETURN(result);
}
@@ -1829,7 +2181,7 @@ static int add_keyword_path(String *str, const char *keyword,
#ifdef __WIN__
/* Convert \ to / to be able to create table on unix */
char *pos, *end;
- uint length= strlen(temp_path);
+ size_t length= strlen(temp_path);
for (pos= temp_path, end= pos+length ; pos < end ; pos++)
{
if (*pos == '\\')
@@ -2182,6 +2534,20 @@ static int add_partition_values(String *str, partition_info *part_info,
} while (++i < num_items);
err+= str->append(')');
}
+ else if (part_info->part_type == VERSIONING_PARTITION)
+ {
+ switch (p_elem->type())
+ {
+ case partition_element::CURRENT:
+ err+= str->append(STRING_WITH_LEN(" CURRENT"));
+ break;
+ case partition_element::HISTORY:
+ err+= str->append(STRING_WITH_LEN(" HISTORY"));
+ break;
+ default:
+ DBUG_ASSERT(0 && "wrong p_elem->type");
+ }
+ }
end:
return err;
}
@@ -2275,13 +2641,37 @@ char *generate_partition_syntax(THD *thd, partition_info *part_info,
else
err+= str.append(STRING_WITH_LEN("HASH "));
break;
+ case VERSIONING_PARTITION:
+ err+= str.append(STRING_WITH_LEN("SYSTEM_TIME "));
+ break;
default:
DBUG_ASSERT(0);
/* We really shouldn't get here, no use in continuing from here */
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
DBUG_RETURN(NULL);
}
- if (part_info->part_expr)
+ if (part_info->part_type == VERSIONING_PARTITION)
+ {
+ Vers_part_info *vers_info= part_info->vers_info;
+ DBUG_ASSERT(vers_info);
+ if (vers_info->interval.is_set())
+ {
+ err+= str.append(STRING_WITH_LEN("INTERVAL "));
+ err+= append_interval(&str, vers_info->interval.type,
+ vers_info->interval.step);
+ if (create_info) // not SHOW CREATE
+ {
+ err+= str.append(STRING_WITH_LEN(" STARTS "));
+ err+= str.append_ulonglong(vers_info->interval.start);
+ }
+ }
+ if (vers_info->limit)
+ {
+ err+= str.append(STRING_WITH_LEN("LIMIT "));
+ err+= str.append_ulonglong(vers_info->limit);
+ }
+ }
+ else if (part_info->part_expr)
{
err+= str.append('(');
part_info->part_expr->print_for_table_def(&str);
@@ -3088,6 +3478,48 @@ int get_partition_id_range_col(partition_info *part_info,
}
+int vers_get_partition_id(partition_info *part_info, uint32 *part_id,
+ longlong *func_value)
+{
+ DBUG_ENTER("vers_get_partition_id");
+ Field *row_end= part_info->part_field_array[STAT_TRX_END];
+ Vers_part_info *vers_info= part_info->vers_info;
+
+ if (row_end->is_max() || row_end->is_null())
+ *part_id= vers_info->now_part->id;
+ else // row is historical
+ {
+ longlong *range_value= part_info->range_int_array;
+ uint max_hist_id= part_info->num_parts - 2;
+ uint min_hist_id= 0, loc_hist_id= vers_info->hist_part->id;
+ ulong unused;
+ my_time_t ts;
+
+ if (!range_value)
+ goto done; // fastpath
+
+ ts= row_end->get_timestamp(&unused);
+ if ((loc_hist_id == 0 || range_value[loc_hist_id - 1] < ts) &&
+ (loc_hist_id == max_hist_id || range_value[loc_hist_id] >= ts))
+ goto done; // fastpath
+
+ while (max_hist_id > min_hist_id)
+ {
+ loc_hist_id= (max_hist_id + min_hist_id) / 2;
+ if (range_value[loc_hist_id] <= ts)
+ min_hist_id= loc_hist_id + 1;
+ else
+ max_hist_id= loc_hist_id;
+ }
+ loc_hist_id= max_hist_id;
+done:
+ *part_id= (uint32)loc_hist_id;
+ }
+ DBUG_PRINT("exit",("partition: %d", *part_id));
+ DBUG_RETURN(0);
+}
+
+
int get_partition_id_range(partition_info *part_info,
uint32 *part_id,
longlong *func_value)
@@ -4020,8 +4452,7 @@ bool mysql_unpack_partition(THD *thd,
{
bool result= TRUE;
partition_info *part_info;
- CHARSET_INFO *old_character_set_client=
- thd->variables.character_set_client;
+ CHARSET_INFO *old_character_set_client= thd->variables.character_set_client;
LEX *old_lex= thd->lex;
LEX lex;
PSI_statement_locker *parent_locker= thd->m_statement_psi;
@@ -4036,17 +4467,9 @@ bool mysql_unpack_partition(THD *thd,
if (init_lex_with_single_table(thd, table, &lex))
goto end;
- /*
- All Items created is put into a free list on the THD object. This list
- is used to free all Item objects after completing a query. We don't
- want that to happen with the Item tree created as part of the partition
- info. This should be attached to the table object and remain so until
- the table object is released.
- Thus we move away the current list temporarily and start a new list that
- we then save in the partition info structure.
- */
*work_part_info_used= FALSE;
- lex.part_info= new partition_info();/* Indicates MYSQLparse from this place */
+ lex.part_info= new partition_info();
+ lex.part_info->table= table; /* Indicates MYSQLparse from this place */
if (!lex.part_info)
{
mem_alloc_error(sizeof(partition_info));
@@ -4431,13 +4854,21 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
!thd->lex->part_info->num_columns)
thd->lex->part_info->num_columns= 1; // to make correct clone
- if ((thd->work_part_info= thd->lex->part_info) &&
- !(thd->work_part_info= thd->lex->part_info->get_clone(thd)))
+ /*
+ One of these is done in handle_if_exists_option():
+ thd->work_part_info= thd->lex->part_info;
+ or
+ thd->work_part_info= NULL;
+ */
+ if (thd->work_part_info &&
+ !(thd->work_part_info= thd->work_part_info->get_clone(thd)))
DBUG_RETURN(TRUE);
/* ALTER_ADMIN_PARTITION is handled in mysql_admin_table */
DBUG_ASSERT(!(alter_info->flags & Alter_info::ALTER_ADMIN_PARTITION));
+ partition_info *saved_part_info= NULL;
+
if (alter_info->flags &
(Alter_info::ALTER_ADD_PARTITION |
Alter_info::ALTER_DROP_PARTITION |
@@ -4447,7 +4878,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
Alter_info::ALTER_REBUILD_PARTITION))
{
partition_info *tab_part_info;
- uint flags= 0;
+ ulonglong flags= 0;
bool is_last_partition_reorged= FALSE;
part_elem_value *tab_max_elem_val= NULL;
part_elem_value *alt_max_elem_val= NULL;
@@ -4467,8 +4898,8 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
object to allow fast_alter_partition_table to perform the changes.
*/
DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE,
- alter_ctx->db,
- alter_ctx->table_name,
+ alter_ctx->db.str,
+ alter_ctx->table_name.str,
MDL_INTENTION_EXCLUSIVE));
tab_part_info= table->part_info;
@@ -4566,7 +4997,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
if (!(tab_part_info= tab_part_info->get_clone(thd)))
DBUG_RETURN(TRUE);
}
- DBUG_PRINT("info", ("*fast_alter_table flags: 0x%x", flags));
+ DBUG_PRINT("info", ("*fast_alter_table flags: 0x%llx", flags));
if ((alter_info->flags & Alter_info::ALTER_ADD_PARTITION) ||
(alter_info->flags & Alter_info::ALTER_REORGANIZE_PARTITION))
{
@@ -4602,16 +5033,15 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
"LIST", "IN");
}
- else if (tab_part_info->part_type == RANGE_PARTITION)
+ else if (thd->work_part_info->part_type == VERSIONING_PARTITION)
{
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "RANGE", "LESS THAN");
+ my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME");
}
else
{
- DBUG_ASSERT(tab_part_info->part_type == LIST_PARTITION);
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "LIST", "IN");
+ DBUG_ASSERT(tab_part_info->part_type == RANGE_PARTITION ||
+ tab_part_info->part_type == LIST_PARTITION);
+ (void) tab_part_info->error_if_requires_values();
}
goto err;
}
@@ -4639,6 +5069,16 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
}
if (alter_info->flags & Alter_info::ALTER_ADD_PARTITION)
{
+ if (*fast_alter_table && thd->locked_tables_mode)
+ {
+ MEM_ROOT *old_root= thd->mem_root;
+ thd->mem_root= &thd->locked_tables_list.m_locked_tables_root;
+ saved_part_info= tab_part_info->get_clone(thd);
+ thd->mem_root= old_root;
+ saved_part_info->read_partitions= tab_part_info->read_partitions;
+ saved_part_info->lock_partitions= tab_part_info->lock_partitions;
+ saved_part_info->bitmaps_are_initialized= tab_part_info->bitmaps_are_initialized;
+ }
/*
We start by moving the new partitions to the list of temporary
partitions. We will then check that the new partitions fit in the
@@ -4654,7 +5094,8 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
must know the number of new partitions in this case.
*/
if (thd->lex->no_write_to_binlog &&
- tab_part_info->part_type != HASH_PARTITION)
+ tab_part_info->part_type != HASH_PARTITION &&
+ tab_part_info->part_type != VERSIONING_PARTITION)
{
my_error(ER_NO_BINLOG_ERROR, MYF(0));
goto err;
@@ -4759,16 +5200,14 @@ adding and copying partitions, the second after completing the adding
and copying and finally the third line after also dropping the partitions
that are reorganised.
*/
- if (*fast_alter_table &&
- tab_part_info->part_type == HASH_PARTITION)
+ if (*fast_alter_table && tab_part_info->part_type == HASH_PARTITION)
{
uint part_no= 0, start_part= 1, start_sec_part= 1;
uint end_part= 0, end_sec_part= 0;
uint upper_2n= tab_part_info->linear_hash_mask + 1;
uint lower_2n= upper_2n >> 1;
bool all_parts= TRUE;
- if (tab_part_info->linear_hash_ind &&
- num_new_partitions < upper_2n)
+ if (tab_part_info->linear_hash_ind && num_new_partitions < upper_2n)
{
/*
An analysis of which parts needs reorganisation shows that it is
@@ -4859,6 +5298,26 @@ that are reorganised.
partition configuration is made.
*/
{
+ partition_element *now_part= NULL;
+ if (tab_part_info->part_type == VERSIONING_PARTITION)
+ {
+ List_iterator<partition_element> it(tab_part_info->partitions);
+ partition_element *el;
+ while ((el= it++))
+ {
+ if (el->type() == partition_element::CURRENT)
+ {
+ it.remove();
+ now_part= el;
+ }
+ }
+ if (*fast_alter_table && tab_part_info->vers_info->interval.is_set())
+ {
+ partition_element *hist_part= tab_part_info->vers_info->hist_part;
+ if (hist_part->range_value <= thd->system_time)
+ hist_part->part_state= PART_CHANGED;
+ }
+ }
List_iterator<partition_element> alt_it(alt_part_info->partitions);
uint part_count= 0;
do
@@ -4873,6 +5332,15 @@ that are reorganised.
}
} while (++part_count < num_new_partitions);
tab_part_info->num_parts+= num_new_partitions;
+ if (tab_part_info->part_type == VERSIONING_PARTITION)
+ {
+ DBUG_ASSERT(now_part);
+ if (tab_part_info->partitions.push_back(now_part, thd->mem_root))
+ {
+ mem_alloc_error(1);
+ goto err;
+ }
+ }
}
/*
If we specify partitions explicitly we don't use defaults anymore.
@@ -4906,16 +5374,28 @@ that are reorganised.
List_iterator<partition_element> part_it(tab_part_info->partitions);
tab_part_info->is_auto_partitioned= FALSE;
- if (!(tab_part_info->part_type == RANGE_PARTITION ||
- tab_part_info->part_type == LIST_PARTITION))
+ if (tab_part_info->part_type == VERSIONING_PARTITION)
{
- my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "DROP");
- goto err;
+ if (num_parts_dropped >= tab_part_info->num_parts - 1)
+ {
+ DBUG_ASSERT(table && table->s && table->s->table_name.str);
+ my_error(ER_VERS_WRONG_PARTS, MYF(0), table->s->table_name.str);
+ goto err;
+ }
}
- if (num_parts_dropped >= tab_part_info->num_parts)
+ else
{
- my_error(ER_DROP_LAST_PARTITION, MYF(0));
- goto err;
+ if (!(tab_part_info->part_type == RANGE_PARTITION ||
+ tab_part_info->part_type == LIST_PARTITION))
+ {
+ my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "DROP");
+ goto err;
+ }
+ if (num_parts_dropped >= tab_part_info->num_parts)
+ {
+ my_error(ER_DROP_LAST_PARTITION, MYF(0));
+ goto err;
+ }
}
do
{
@@ -4923,6 +5403,24 @@ that are reorganised.
if (is_name_in_list(part_elem->partition_name,
alter_info->partition_names))
{
+ if (tab_part_info->part_type == VERSIONING_PARTITION)
+ {
+ if (part_elem->type() == partition_element::CURRENT)
+ {
+ my_error(ER_VERS_WRONG_PARTS, MYF(0), table->s->table_name.str);
+ goto err;
+ }
+ if (tab_part_info->vers_info->interval.is_set())
+ {
+ if (num_parts_found < part_count)
+ {
+ my_error(ER_VERS_DROP_PARTITION_INTERVAL, MYF(0));
+ goto err;
+ }
+ tab_part_info->vers_info->interval.start=
+ (my_time_t)part_elem->range_value;
+ }
+ }
/*
Set state to indicate that the partition is to be dropped.
*/
@@ -5245,8 +5743,9 @@ the generated partition syntax in a correct manner.
tab_part_info->use_default_subpartitions= FALSE;
tab_part_info->use_default_num_subpartitions= FALSE;
}
+
if (tab_part_info->check_partition_info(thd, (handlerton**)NULL,
- table->file, 0, TRUE))
+ table->file, 0, alt_part_info))
{
goto err;
}
@@ -5259,13 +5758,13 @@ the generated partition syntax in a correct manner.
tab_part_info->part_type == RANGE_PARTITION &&
((is_last_partition_reorged &&
(tab_part_info->column_list ?
- (tab_part_info->compare_column_values(
+ (partition_info_compare_column_values(
alt_max_elem_val->col_val_array,
tab_max_elem_val->col_val_array) < 0) :
alt_max_range < tab_max_range)) ||
(!is_last_partition_reorged &&
(tab_part_info->column_list ?
- (tab_part_info->compare_column_values(
+ (partition_info_compare_column_values(
alt_max_elem_val->col_val_array,
tab_max_elem_val->col_val_array) != 0) :
alt_max_range != tab_max_range))))
@@ -5283,7 +5782,7 @@ the generated partition syntax in a correct manner.
goto err;
}
}
- }
+ } // ADD, DROP, COALESCE, REORGANIZE, TABLE_REORG, REBUILD
else
{
/*
@@ -5449,6 +5948,8 @@ the generated partition syntax in a correct manner.
DBUG_RETURN(FALSE);
err:
*fast_alter_table= false;
+ if (saved_part_info)
+ table->part_info= saved_part_info;
DBUG_RETURN(TRUE);
}
@@ -5487,7 +5988,7 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
THD *thd= lpt->thd;
DBUG_ENTER("mysql_change_partitions");
- build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0);
+ build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0);
if(mysql_trans_prepare_alter_copy_data(thd))
DBUG_RETURN(TRUE);
@@ -5533,7 +6034,7 @@ static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
int error;
DBUG_ENTER("mysql_rename_partitions");
- build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0);
+ build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0);
if ((error= lpt->table->file->ha_rename_partitions(path)))
{
if (error != 1)
@@ -5579,7 +6080,7 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
lpt->table->s->table_name.str,
MDL_EXCLUSIVE));
- build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0);
+ build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0);
if ((error= lpt->table->file->ha_drop_partitions(path)))
{
lpt->table->file->print_error(error, MYF(0));
@@ -5976,8 +6477,7 @@ static bool write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ENTER("write_log_rename_frm");
part_info->first_log_entry= NULL;
- build_table_filename(path, sizeof(path) - 1, lpt->db,
- lpt->table_name, "", 0);
+ build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0);
build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt);
mysql_mutex_lock(&LOCK_gdl);
if (write_log_replace_delete_frm(lpt, 0UL, shadow_path, path, TRUE))
@@ -6028,8 +6528,7 @@ static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ENTER("write_log_drop_partition");
part_info->first_log_entry= NULL;
- build_table_filename(path, sizeof(path) - 1, lpt->db,
- lpt->table_name, "", 0);
+ build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0);
build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt);
mysql_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
@@ -6087,8 +6586,7 @@ static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ASSERT(old_first_log_entry);
DBUG_ENTER("write_log_add_change_partition");
- build_table_filename(path, sizeof(path) - 1, lpt->db,
- lpt->table_name, "", 0);
+ build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0);
build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt);
mysql_mutex_lock(&LOCK_gdl);
@@ -6156,8 +6654,7 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
Replace the revert operations with forced retry operations.
*/
part_info->first_log_entry= NULL;
- build_table_filename(path, sizeof(path) - 1, lpt->db,
- lpt->table_name, "", 0);
+ build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0);
build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt);
mysql_mutex_lock(&LOCK_gdl);
if (write_log_changed_partitions(lpt, &next_entry, (const char*)path))
@@ -6342,8 +6839,8 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
Better to do that here, than leave the cleaning up to others.
Aquire EXCLUSIVE mdl lock if not already aquired.
*/
- if (!thd->mdl_context.is_lock_owner(MDL_key::TABLE, lpt->db,
- lpt->table_name,
+ if (!thd->mdl_context.is_lock_owner(MDL_key::TABLE, lpt->db.str,
+ lpt->table_name.str,
MDL_EXCLUSIVE))
{
if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
@@ -6540,8 +7037,8 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
Alter_info *alter_info,
HA_CREATE_INFO *create_info,
TABLE_LIST *table_list,
- const char *db,
- const char *table_name)
+ const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name)
{
/* Set-up struct used to write frm files */
partition_info *part_info;
@@ -6560,15 +7057,12 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
lpt->part_info= part_info;
lpt->alter_info= alter_info;
lpt->create_info= create_info;
- lpt->db_options= create_info->table_options;
- if (create_info->row_type != ROW_TYPE_FIXED &&
- create_info->row_type != ROW_TYPE_DEFAULT)
- lpt->db_options|= HA_OPTION_PACK_RECORD;
+ lpt->db_options= create_info->table_options_with_row_type();
lpt->table= table;
lpt->key_info_buffer= 0;
lpt->key_count= 0;
- lpt->db= db;
- lpt->table_name= table_name;
+ lpt->db= *db;
+ lpt->table_name= *table_name;
lpt->copied= 0;
lpt->deleted= 0;
lpt->pack_frm_data= NULL;
@@ -6916,6 +7410,39 @@ err:
}
#endif
+
+/*
+ Prepare for calling val_int on partition function by setting fields to
+ point to the record where the values of the PF-fields are stored.
+
+ SYNOPSIS
+ set_field_ptr()
+ ptr Array of fields to change ptr
+ new_buf New record pointer
+ old_buf Old record pointer
+
+ DESCRIPTION
+ Set ptr in field objects of field array to refer to new_buf record
+ instead of previously old_buf. Used before calling val_int and after
+ it is used to restore pointers to table->record[0].
+ This routine is placed outside of partition code since it can be useful
+ also for other programs.
+*/
+
+void set_field_ptr(Field **ptr, const uchar *new_buf,
+ const uchar *old_buf)
+{
+ my_ptrdiff_t diff= (new_buf - old_buf);
+ DBUG_ENTER("set_field_ptr");
+
+ do
+ {
+ (*ptr)->move_field_offset(diff);
+ } while (*(++ptr));
+ DBUG_VOID_RETURN;
+}
+
+
/*
Prepare for calling val_int on partition function by setting fields to
point to the record where the values of the PF-fields are stored.
@@ -6954,6 +7481,61 @@ void set_key_field_ptr(KEY *key_info, const uchar *new_buf,
}
+/**
+ Append all fields in read_set to string
+
+ @param[in,out] str String to append to.
+ @param[in] row Row to append.
+ @param[in] table Table containing read_set and fields for the row.
+*/
+void append_row_to_str(String &str, const uchar *row, TABLE *table)
+{
+ Field **fields, **field_ptr;
+ const uchar *rec;
+ uint num_fields= bitmap_bits_set(table->read_set);
+ uint curr_field_index= 0;
+ bool is_rec0= !row || row == table->record[0];
+ if (!row)
+ rec= table->record[0];
+ else
+ rec= row;
+
+ /* Create a new array of all read fields. */
+ fields= (Field**) my_malloc(sizeof(void*) * (num_fields + 1),
+ MYF(0));
+ if (!fields)
+ return;
+ fields[num_fields]= NULL;
+ for (field_ptr= table->field;
+ *field_ptr;
+ field_ptr++)
+ {
+ if (!bitmap_is_set(table->read_set, (*field_ptr)->field_index))
+ continue;
+ fields[curr_field_index++]= *field_ptr;
+ }
+
+
+ if (!is_rec0)
+ set_field_ptr(fields, rec, table->record[0]);
+
+ for (field_ptr= fields;
+ *field_ptr;
+ field_ptr++)
+ {
+ Field *field= *field_ptr;
+ str.append(" ");
+ str.append(&field->field_name);
+ str.append(":");
+ field_unpack(&str, field, rec, 0, false);
+ }
+
+ if (!is_rec0)
+ set_field_ptr(fields, table->record[0], rec);
+ my_free(fields);
+}
+
+
/*
SYNOPSIS
mem_alloc_error()
@@ -7386,13 +7968,11 @@ uint32 get_partition_id_cols_range_for_endpoint(partition_info *part_info,
}
-int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
- bool is_subpart,
- uint32 *store_length_array,
- uchar *min_value, uchar *max_value,
- uint min_len, uint max_len,
- uint flags,
- PARTITION_ITERATOR *part_iter)
+static int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
+ bool is_subpart, uint32 *store_length_array,
+ uchar *min_value, uchar *max_value,
+ uint min_len, uint max_len,
+ uint flags, PARTITION_ITERATOR *part_iter)
{
bool can_match_multiple_values;
uint32 nparts;
@@ -7400,7 +7980,7 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
uint full_length= 0;
DBUG_ENTER("get_part_iter_for_interval_cols_via_map");
- if (part_info->part_type == RANGE_PARTITION)
+ if (part_info->part_type == RANGE_PARTITION || part_info->part_type == VERSIONING_PARTITION)
{
get_col_endpoint= get_partition_id_cols_range_for_endpoint;
part_iter->get_next= get_next_partition_id_range;
@@ -7446,7 +8026,7 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
}
if (flags & NO_MAX_RANGE)
{
- if (part_info->part_type == RANGE_PARTITION)
+ if (part_info->part_type == RANGE_PARTITION || part_info->part_type == VERSIONING_PARTITION)
part_iter->part_nums.end= part_info->num_parts;
else /* LIST_PARTITION */
{
@@ -7513,13 +8093,12 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
@retval -1 All partitions would match (iterator not initialized)
*/
-int get_part_iter_for_interval_via_mapping(partition_info *part_info,
- bool is_subpart,
- uint32 *store_length_array, /* ignored */
- uchar *min_value, uchar *max_value,
- uint min_len, uint max_len, /* ignored */
- uint flags,
- PARTITION_ITERATOR *part_iter)
+static int get_part_iter_for_interval_via_mapping(partition_info *part_info,
+ bool is_subpart,
+ uint32 *store_length_array, /* ignored */
+ uchar *min_value, uchar *max_value,
+ uint min_len, uint max_len, /* ignored */
+ uint flags, PARTITION_ITERATOR *part_iter)
{
Field *field= part_info->part_field_array[0];
uint32 UNINIT_VAR(max_endpoint_val);
@@ -7760,13 +8339,12 @@ not_found:
-1 - All partitions would match, iterator not initialized
*/
-int get_part_iter_for_interval_via_walking(partition_info *part_info,
- bool is_subpart,
- uint32 *store_length_array, /* ignored */
- uchar *min_value, uchar *max_value,
- uint min_len, uint max_len, /* ignored */
- uint flags,
- PARTITION_ITERATOR *part_iter)
+static int get_part_iter_for_interval_via_walking(partition_info *part_info,
+ bool is_subpart,
+ uint32 *store_length_array, /* ignored */
+ uchar *min_value, uchar *max_value,
+ uint min_len, uint max_len, /* ignored */
+ uint flags, PARTITION_ITERATOR *part_iter)
{
Field *field;
uint total_parts;
@@ -8079,8 +8657,11 @@ int create_partition_name(char *out, size_t outlen, const char *in1,
end= strxnmov(out, outlen-1, in1, "#P#", transl_part, NullS);
else if (name_variant == TEMP_PART_NAME)
end= strxnmov(out, outlen-1, in1, "#P#", transl_part, "#TMP#", NullS);
- else if (name_variant == RENAMED_PART_NAME)
+ else
+ {
+ DBUG_ASSERT(name_variant == RENAMED_PART_NAME);
end= strxnmov(out, outlen-1, in1, "#P#", transl_part, "#REN#", NullS);
+ }
if (end - out == static_cast<ptrdiff_t>(outlen-1))
{
my_error(ER_PATH_LENGTH, MYF(0), longest_str(in1, transl_part));
@@ -8120,9 +8701,12 @@ int create_subpartition_name(char *out, size_t outlen,
else if (name_variant == TEMP_PART_NAME)
end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
"#SP#", transl_subpart_name, "#TMP#", NullS);
- else if (name_variant == RENAMED_PART_NAME)
+ else
+ {
+ DBUG_ASSERT(name_variant == RENAMED_PART_NAME);
end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
"#SP#", transl_subpart_name, "#REN#", NullS);
+ }
if (end - out == static_cast<ptrdiff_t>(outlen-1))
{
my_error(ER_PATH_LENGTH, MYF(0),
@@ -8143,4 +8727,5 @@ uint get_partition_field_store_length(Field *field)
store_length+= HA_KEY_BLOB_LENGTH;
return store_length;
}
+
#endif
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index 992229afb05..4315c84e4f0 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -41,6 +41,7 @@ typedef struct st_key_range key_range;
#define HA_CAN_UPDATE_PARTITION_KEY (1 << 1)
#define HA_CAN_PARTITION_UNIQUE (1 << 2)
#define HA_USE_AUTO_PARTITION (1 << 3)
+#define HA_ONLY_VERS_PARTITION (1 << 4)
#define NORMAL_PART_NAME 0
#define TEMP_PART_NAME 1
@@ -56,8 +57,8 @@ typedef struct st_lock_param_type
Alter_info *alter_info;
TABLE *table;
KEY *key_info_buffer;
- const char *db;
- const char *table_name;
+ LEX_CSTRING db;
+ LEX_CSTRING table_name;
uchar *pack_frm_data;
uint key_count;
uint db_options;
@@ -86,12 +87,8 @@ bool check_reorganise_list(partition_info *new_part_info,
partition_info *old_part_info,
List<char> list_part_names);
handler *get_ha_partition(partition_info *part_info);
-int get_parts_for_update(const uchar *old_data, const uchar *new_data,
- const uchar *rec0, partition_info *part_info,
- uint32 *old_part_id, uint32 *new_part_id,
- longlong *func_value);
-int get_part_for_delete(const uchar *buf, const uchar *rec0,
- partition_info *part_info, uint32 *part_id);
+int get_part_for_buf(const uchar *buf, const uchar *rec0,
+ partition_info *part_info, uint32 *part_id);
void prune_partition_set(const TABLE *table, part_id_range *part_spec);
bool check_partition_info(partition_info *part_info,handlerton **eng_type,
TABLE *table, handler *file, HA_CREATE_INFO *info);
@@ -128,6 +125,14 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
bool check_part_func_fields(Field **ptr, bool ok_with_charsets);
bool field_is_partition_charset(Field *field);
Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs);
+/**
+ Append all fields in read_set to string
+
+ @param[in,out] str String to append to.
+ @param[in] row Row to append.
+ @param[in] table Table containing read_set and fields for the row.
+*/
+void append_row_to_str(String &str, const uchar *row, TABLE *table);
void mem_alloc_error(size_t size);
void truncate_partition_filename(char *path);
@@ -258,8 +263,8 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
Alter_info *alter_info,
HA_CREATE_INFO *create_info,
TABLE_LIST *table_list,
- const char *db,
- const char *table_name);
+ const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name);
bool set_part_state(Alter_info *alter_info, partition_info *tab_part_info,
enum partition_state part_state);
uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
@@ -291,4 +296,30 @@ int __attribute__((warn_unused_result))
void set_key_field_ptr(KEY *key_info, const uchar *new_buf,
const uchar *old_buf);
+/** Set up table for creating a partition.
+Copy info from partition to the table share so the created partition
+has the correct info.
+ @param thd THD object
+ @param share Table share to be updated.
+ @param info Create info to be updated.
+ @param part_elem partition_element containing the info.
+
+ @return status
+ @retval TRUE Error
+ @retval FALSE Success
+
+ @details
+ Set up
+ 1) Comment on partition
+ 2) MAX_ROWS, MIN_ROWS on partition
+ 3) Index file name on partition
+ 4) Data file name on partition
+*/
+bool set_up_table_before_create(THD *thd,
+ TABLE_SHARE *share,
+ const char *partition_name_with_path,
+ HA_CREATE_INFO *info,
+ partition_element *part_elem);
+
#endif /* SQL_PARTITION_INCLUDED */
+
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index efddcbf3857..2e998878351 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -71,15 +71,15 @@ bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd)
DBUG_RETURN(TRUE);
/* Must be set in the parser */
- DBUG_ASSERT(select_lex->db);
+ DBUG_ASSERT(select_lex->db.str);
/* also check the table to be exchanged with the partition */
DBUG_ASSERT(alter_info.flags & Alter_info::ALTER_EXCHANGE_PARTITION);
- if (check_access(thd, priv_needed, first_table->db,
+ if (check_access(thd, priv_needed, first_table->db.str,
&first_table->grant.privilege,
&first_table->grant.m_internal,
0, 0) ||
- check_access(thd, priv_needed, first_table->next_local->db,
+ check_access(thd, priv_needed, first_table->next_local->db.str,
&first_table->next_local->grant.privilege,
&first_table->next_local->grant.m_internal,
0, 0))
@@ -379,15 +379,13 @@ static bool exchange_name_with_ddl_log(THD *thd,
*/
/* call rename table from table to tmp-name */
DBUG_EXECUTE_IF("exchange_partition_fail_3",
- my_error(ER_ERROR_ON_RENAME, MYF(0),
- name, tmp_name, 0);
+ my_error(ER_ERROR_ON_RENAME, MYF(0), name, tmp_name, 0);
error_set= TRUE;
goto err_rename;);
DBUG_EXECUTE_IF("exchange_partition_abort_3", DBUG_SUICIDE(););
if (file->ha_rename_table(name, tmp_name))
{
- my_error(ER_ERROR_ON_RENAME, MYF(0), name, tmp_name,
- my_errno);
+ my_error(ER_ERROR_ON_RENAME, MYF(0), name, tmp_name, my_errno);
error_set= TRUE;
goto err_rename;
}
@@ -398,8 +396,7 @@ static bool exchange_name_with_ddl_log(THD *thd,
/* call rename table from partition to table */
DBUG_EXECUTE_IF("exchange_partition_fail_5",
- my_error(ER_ERROR_ON_RENAME, MYF(0),
- from_name, name, 0);
+ my_error(ER_ERROR_ON_RENAME, MYF(0), from_name, name, 0);
error_set= TRUE;
goto err_rename;);
DBUG_EXECUTE_IF("exchange_partition_abort_5", DBUG_SUICIDE(););
@@ -416,8 +413,7 @@ static bool exchange_name_with_ddl_log(THD *thd,
/* call rename table from tmp-nam to partition */
DBUG_EXECUTE_IF("exchange_partition_fail_7",
- my_error(ER_ERROR_ON_RENAME, MYF(0),
- tmp_name, from_name, 0);
+ my_error(ER_ERROR_ON_RENAME, MYF(0), tmp_name, from_name, 0);
error_set= TRUE;
goto err_rename;);
DBUG_EXECUTE_IF("exchange_partition_abort_7", DBUG_SUICIDE(););
@@ -556,13 +552,13 @@ bool Sql_cmd_alter_table_exchange_partition::
/* Will append the partition name later in part_info->get_part_elem() */
part_file_name_len= build_table_filename(part_file_name,
sizeof(part_file_name),
- table_list->db,
- table_list->table_name,
+ table_list->db.str,
+ table_list->table_name.str,
"", 0);
build_table_filename(swap_file_name,
sizeof(swap_file_name),
- swap_table_list->db,
- swap_table_list->table_name,
+ swap_table_list->db.str,
+ swap_table_list->table_name.str,
"", 0);
/* create a unique temp name #sqlx-nnnn_nnnn, x for eXchange */
my_snprintf(temp_name, sizeof(temp_name), "%sx-%lx_%llx",
@@ -570,7 +566,7 @@ bool Sql_cmd_alter_table_exchange_partition::
if (lower_case_table_names)
my_casedn_str(files_charset_info, temp_name);
build_table_filename(temp_file_name, sizeof(temp_file_name),
- table_list->next_local->db,
+ table_list->next_local->db.str,
temp_name, "", FN_IS_TMP);
if (!(part_elem= part_table->part_info->get_part_elem(partition_name,
@@ -772,7 +768,7 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
(!thd->is_current_stmt_binlog_format_row() ||
!thd->find_temporary_table(first_table)) &&
wsrep_to_isolation_begin(
- thd, first_table->db, first_table->table_name, NULL)
+ thd, first_table->db.str, first_table->table_name.str, NULL)
)
{
WSREP_WARN("ALTER TABLE TRUNCATE PARTITION isolation failure");
@@ -806,8 +802,8 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
DBUG_RETURN(true);
partition_names_list.push_back(str_partition_name, thd->mem_root);
}
- first_table->partition_names= &partition_names_list;
- if (first_table->table->part_info->set_partition_bitmaps(first_table))
+ if (first_table->table->
+ part_info->set_partition_bitmaps(&partition_names_list))
DBUG_RETURN(true);
if (lock_tables(thd, first_table, table_counter, 0))
@@ -822,8 +818,8 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
if (thd->mdl_context.upgrade_shared_lock(ticket, MDL_EXCLUSIVE, timeout))
DBUG_RETURN(TRUE);
- tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN, first_table->db,
- first_table->table_name, FALSE);
+ tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN, first_table->db.str,
+ first_table->table_name.str, FALSE);
partition= (ha_partition*) first_table->table->file;
/* Invoke the handler method responsible for truncating the partition. */
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 9478db8e6d5..605f96293d3 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -66,6 +66,8 @@ char *opt_plugin_dir_ptr;
char opt_plugin_dir[FN_REFLEN];
ulong plugin_maturity;
+static LEX_CSTRING MYSQL_PLUGIN_NAME= {STRING_WITH_LEN("plugin") };
+
/*
not really needed now, this map will become essential when we add more
maturity levels. We cannot change existing maturity constants,
@@ -80,18 +82,18 @@ uint plugin_maturity_map[]=
When you ad a new plugin type, add both a string and make sure that the
init and deinit array are correctly updated.
*/
-const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
+const LEX_CSTRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
- { C_STRING_WITH_LEN("UDF") },
- { C_STRING_WITH_LEN("STORAGE ENGINE") },
- { C_STRING_WITH_LEN("FTPARSER") },
- { C_STRING_WITH_LEN("DAEMON") },
- { C_STRING_WITH_LEN("INFORMATION SCHEMA") },
- { C_STRING_WITH_LEN("AUDIT") },
- { C_STRING_WITH_LEN("REPLICATION") },
- { C_STRING_WITH_LEN("AUTHENTICATION") },
- { C_STRING_WITH_LEN("PASSWORD VALIDATION") },
- { C_STRING_WITH_LEN("ENCRYPTION") }
+ { STRING_WITH_LEN("UDF") },
+ { STRING_WITH_LEN("STORAGE ENGINE") },
+ { STRING_WITH_LEN("FTPARSER") },
+ { STRING_WITH_LEN("DAEMON") },
+ { STRING_WITH_LEN("INFORMATION SCHEMA") },
+ { STRING_WITH_LEN("AUDIT") },
+ { STRING_WITH_LEN("REPLICATION") },
+ { STRING_WITH_LEN("AUTHENTICATION") },
+ { STRING_WITH_LEN("PASSWORD VALIDATION") },
+ { STRING_WITH_LEN("ENCRYPTION") }
};
extern int initialize_schema_table(st_plugin_int *plugin);
@@ -238,7 +240,7 @@ ulong dlopen_count;
the following variables/structures
*/
static MEM_ROOT plugin_vars_mem_root;
-static uint global_variables_dynamic_size= 0;
+static size_t global_variables_dynamic_size= 0;
static HASH bookmark_hash;
@@ -488,6 +490,11 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl)
sizeof(struct st_plugin_dl));
DBUG_RETURN(tmp);
}
+#else
+static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *)
+{
+ return 0;
+}
#endif /* HAVE_DLOPEN */
@@ -728,7 +735,8 @@ static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, int report)
{
#ifdef HAVE_DLOPEN
char dlpath[FN_REFLEN];
- uint plugin_dir_len, dummy_errors, i;
+ size_t plugin_dir_len,i;
+ uint dummy_errors;
struct st_plugin_dl *tmp= 0, plugin_dl;
void *sym;
st_ptr_backup tmp_backup[array_elements(list_of_services)];
@@ -1155,6 +1163,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, ENOEXEC, buf);
goto err;
}
+
if (plugin_maturity_map[plugin->maturity] < plugin_maturity)
{
char buf[256];
@@ -1167,6 +1176,14 @@ static bool plugin_add(MEM_ROOT *tmp_root,
report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, EPERM, buf);
goto err;
}
+ else if (plugin_maturity_map[plugin->maturity] < SERVER_MATURITY_LEVEL)
+ {
+ sql_print_warning("Plugin '%s' is of maturity level %s while the server is %s",
+ tmp.name.str,
+ plugin_maturity_names[plugin->maturity],
+ plugin_maturity_names[SERVER_MATURITY_LEVEL]);
+ }
+
tmp.plugin= plugin;
tmp.ref_count= 0;
tmp.state= PLUGIN_IS_UNINITIALIZED;
@@ -1176,7 +1193,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
goto err;
if (my_hash_insert(&plugin_hash[plugin->type], (uchar*)tmp_plugin_ptr))
tmp_plugin_ptr->state= PLUGIN_IS_FREED;
- init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096, MYF(0));
+ init_alloc_root(&tmp_plugin_ptr->mem_root, "plugin", 4096, 4096, MYF(0));
if (name->str)
DBUG_RETURN(FALSE); // all done
@@ -1421,10 +1438,10 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin,
mysql_mutex_unlock(&LOCK_plugin);
- mysql_rwlock_wrlock(&LOCK_system_variables_hash);
+ mysql_prlock_wrlock(&LOCK_system_variables_hash);
if (test_plugin_options(tmp_root, plugin, argc, argv))
state= PLUGIN_IS_DISABLED;
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
if (options_only || state == PLUGIN_IS_DISABLED)
{
@@ -1507,14 +1524,14 @@ uchar *get_bookmark_hash_key(const uchar *buff, size_t *length,
return (uchar*) var->key;
}
-static inline void convert_dash_to_underscore(char *str, int len)
+static inline void convert_dash_to_underscore(char *str, size_t len)
{
for (char *p= str; p <= str+len; p++)
if (*p == '-')
*p= '_';
}
-static inline void convert_underscore_to_dash(char *str, int len)
+static inline void convert_underscore_to_dash(char *str, size_t len)
{
for (char *p= str; p <= str+len; p++)
if (*p == '_')
@@ -1566,9 +1583,9 @@ int plugin_init(int *argc, char **argv, int flags)
dlopen_count =0;
- init_alloc_root(&plugin_mem_root, 4096, 4096, MYF(0));
- init_alloc_root(&plugin_vars_mem_root, 4096, 4096, MYF(0));
- init_alloc_root(&tmp_root, 4096, 4096, MYF(0));
+ init_alloc_root(&plugin_mem_root, "plugin", 4096, 4096, MYF(0));
+ init_alloc_root(&plugin_vars_mem_root, "plugin_vars", 4096, 4096, MYF(0));
+ init_alloc_root(&tmp_root, "plugin_tmp", 4096, 4096, MYF(0));
if (my_hash_init(&bookmark_hash, &my_charset_bin, 32, 0, 0,
get_bookmark_hash_key, NULL, HASH_UNIQUE))
@@ -1808,11 +1825,9 @@ static void plugin_load(MEM_ROOT *tmp_root)
new_thd->thread_stack= (char*) &tables;
new_thd->store_globals();
- new_thd->db= my_strdup("mysql", MYF(0));
- new_thd->db_length= 5;
+ new_thd->db= MYSQL_SCHEMA_NAME;
bzero((char*) &new_thd->net, sizeof(new_thd->net));
- tables.init_one_table(STRING_WITH_LEN("mysql"), STRING_WITH_LEN("plugin"),
- "plugin", TL_READ);
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PLUGIN_NAME, 0, TL_READ);
tables.open_strategy= TABLE_LIST::OPEN_NORMAL;
result= open_and_lock_tables(new_thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT);
@@ -1866,6 +1881,7 @@ static void plugin_load(MEM_ROOT *tmp_root)
table->m_needs_reopen= TRUE; // Force close to free memory
close_mysql_tables(new_thd);
end:
+ new_thd->db= null_clex_str; // Avoid free on thd->db
delete new_thd;
DBUG_VOID_RETURN;
}
@@ -2160,7 +2176,7 @@ bool mysql_install_plugin(THD *thd, const LEX_CSTRING *name,
{ MYSQL_AUDIT_GENERAL_CLASSMASK };
DBUG_ENTER("mysql_install_plugin");
- tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PLUGIN_NAME, 0, TL_WRITE);
if (!opt_noacl && check_table_access(thd, INSERT_ACL, &tables, FALSE, 1, FALSE))
DBUG_RETURN(TRUE);
@@ -2303,7 +2319,7 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_CSTRING *name,
{ MYSQL_AUDIT_GENERAL_CLASSMASK };
DBUG_ENTER("mysql_uninstall_plugin");
- tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PLUGIN_NAME, 0, TL_WRITE);
if (!opt_noacl && check_table_access(thd, DELETE_ACL, &tables, FALSE, 1, FALSE))
DBUG_RETURN(TRUE);
@@ -2833,11 +2849,11 @@ sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length,
if (!locked)
mysql_mutex_lock(&LOCK_plugin);
- mysql_rwlock_rdlock(&LOCK_system_variables_hash);
+ mysql_prlock_rdlock(&LOCK_system_variables_hash);
if ((var= intern_find_sys_var(str, length)) &&
(pi= var->cast_pluginvar()))
{
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
LEX *lex= thd ? thd->lex : 0;
if (!(plugin= intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
var= NULL; /* failed to lock it, it must be uninstalling */
@@ -2850,7 +2866,7 @@ sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length,
}
}
else
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
if (!locked)
mysql_mutex_unlock(&LOCK_plugin);
@@ -2875,7 +2891,7 @@ static st_bookmark *find_bookmark(const char *plugin, const char *name,
int flags)
{
st_bookmark *result= NULL;
- uint namelen, length, pluginlen= 0;
+ size_t namelen, length, pluginlen= 0;
char *varname, *p;
if (!(flags & PLUGIN_VAR_THDLOCAL))
@@ -2931,7 +2947,7 @@ static size_t var_storage_size(int flags)
static st_bookmark *register_var(const char *plugin, const char *name,
int flags)
{
- uint length= strlen(plugin) + strlen(name) + 3, size, offset, new_size;
+ size_t length= strlen(plugin) + strlen(name) + 3, size, offset, new_size;
st_bookmark *result;
char *varname, *p;
@@ -2950,7 +2966,7 @@ static st_bookmark *register_var(const char *plugin, const char *name,
sizeof(struct st_bookmark) + length-1);
varname[0]= plugin_var_bookmark_key(flags);
memcpy(result->key, varname, length);
- result->name_len= length - 2;
+ result->name_len= (uint)(length - 2);
result->offset= -1;
DBUG_ASSERT(size && !(size & (size-1))); /* must be power of 2 */
@@ -2983,10 +2999,10 @@ static st_bookmark *register_var(const char *plugin, const char *name,
global_variables_dynamic_size= new_size;
}
- global_system_variables.dynamic_variables_head= offset;
- max_system_variables.dynamic_variables_head= offset;
- global_system_variables.dynamic_variables_size= offset + size;
- max_system_variables.dynamic_variables_size= offset + size;
+ global_system_variables.dynamic_variables_head= (uint)offset;
+ max_system_variables.dynamic_variables_head= (uint)offset;
+ global_system_variables.dynamic_variables_size= (uint)(offset + size);
+ max_system_variables.dynamic_variables_size= (uint)(offset + size);
global_system_variables.dynamic_variables_version++;
max_system_variables.dynamic_variables_version++;
@@ -3080,9 +3096,9 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
if (!thd->variables.dynamic_variables_ptr ||
(uint)offset > thd->variables.dynamic_variables_head)
{
- mysql_rwlock_rdlock(&LOCK_system_variables_hash);
+ mysql_prlock_rdlock(&LOCK_system_variables_hash);
sync_dynamic_session_variables(thd, global_lock);
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
}
DBUG_RETURN((uchar*)thd->variables.dynamic_variables_ptr + offset);
}
@@ -3197,7 +3213,7 @@ static void cleanup_variables(struct system_variables *vars)
st_bookmark *v;
uint idx;
- mysql_rwlock_rdlock(&LOCK_system_variables_hash);
+ mysql_prlock_rdlock(&LOCK_system_variables_hash);
for (idx= 0; idx < bookmark_hash.records; idx++)
{
v= (st_bookmark*) my_hash_element(&bookmark_hash, idx);
@@ -3216,7 +3232,7 @@ static void cleanup_variables(struct system_variables *vars)
*ptr= NULL;
}
}
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
DBUG_ASSERT(vars->table_plugin == NULL);
DBUG_ASSERT(vars->tmp_table_plugin == NULL);
@@ -3683,9 +3699,9 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
my_option *options)
{
const char *plugin_name= tmp->plugin->name;
- const LEX_STRING plugin_dash = { C_STRING_WITH_LEN("plugin-") };
- uint plugin_name_len= strlen(plugin_name);
- uint optnamelen;
+ const LEX_CSTRING plugin_dash = { STRING_WITH_LEN("plugin-") };
+ size_t plugin_name_len= strlen(plugin_name);
+ size_t optnamelen;
const int max_comment_len= 180;
char *comment= (char *) alloc_root(mem_root, max_comment_len + 1);
char *optname;
@@ -4010,7 +4026,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
my_option *opts= NULL;
int error= 1;
struct st_bookmark *var;
- uint len=0, count= EXTRA_OPTIONS;
+ size_t len=0, count= EXTRA_OPTIONS;
st_ptr_backup *tmp_backup= 0;
DBUG_ENTER("test_plugin_options");
DBUG_ASSERT(tmp->plugin && tmp->name.str);
@@ -4271,10 +4287,10 @@ int thd_key_create(MYSQL_THD_KEY_T *key)
PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT;
char namebuf[256];
snprintf(namebuf, sizeof(namebuf), "%u", thd_key_no++);
- mysql_rwlock_wrlock(&LOCK_system_variables_hash);
+ mysql_prlock_wrlock(&LOCK_system_variables_hash);
// non-letters in the name as an extra safety
st_bookmark *bookmark= register_var("\a\v\a\t\a\r", namebuf, flags);
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
if (bookmark)
{
*key= bookmark->offset;
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index f100e8a232a..4e899e18f9b 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -24,7 +24,8 @@
#define SHOW_always_last SHOW_KEY_CACHE_LONG, \
SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, \
SHOW_HAVE, SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, \
- SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS, SHOW_LEX_STRING
+ SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS, SHOW_UINT32_STATUS, \
+ SHOW_LEX_STRING
#include "mariadb.h"
#undef SHOW_always_last
@@ -155,7 +156,7 @@ typedef int (*plugin_type_init)(struct st_plugin_int *);
extern I_List<i_string> *opt_plugin_load_list_ptr;
extern char *opt_plugin_dir_ptr;
extern MYSQL_PLUGIN_IMPORT char opt_plugin_dir[FN_REFLEN];
-extern const LEX_STRING plugin_type_names[];
+extern const LEX_CSTRING plugin_type_names[];
extern ulong plugin_maturity;
extern TYPELIB plugin_maturity_values;
extern const char *plugin_maturity_names[];
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 775717fe62b..dbc03234c44 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -167,20 +167,6 @@ public:
uint param_count;
uint last_errno;
uint flags;
- /*
- The value of thd->select_number at the end of the PREPARE phase.
-
- The issue is: each statement execution opens VIEWs, which may cause
- select_lex objects to be created, and select_number values to be assigned.
-
- On the other hand, PREPARE assigns select_number values for triggers and
- subqueries.
-
- In order for select_number values from EXECUTE not to conflict with
- select_number values from PREPARE, we keep the number and set it at each
- execution.
- */
- uint select_number_after_prepare;
char last_error[MYSQL_ERRMSG_SIZE];
my_bool iterations;
my_bool start_param;
@@ -229,7 +215,7 @@ private:
MEM_ROOT main_mem_root;
sql_mode_t m_sql_mode;
private:
- bool set_db(const char *db, uint db_length);
+ bool set_db(const LEX_CSTRING *db);
bool set_parameters(String *expanded_query,
uchar *packet, uchar *packet_end);
bool execute(String *expanded_query, bool open_cursor);
@@ -489,24 +475,23 @@ static ulong get_param_length(uchar **packet, ulong len)
(i.e. when input types altered) and for all subsequent executions
we don't read any values for this.
- @param param parameter item
@param pos input data buffer
@param len length of data in the buffer
*/
-static void set_param_tiny(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_tiny(uchar **pos, ulong len)
{
#ifndef EMBEDDED_LIBRARY
if (len < 1)
return;
#endif
int8 value= (int8) **pos;
- param->set_int(param->unsigned_flag ? (longlong) ((uint8) value) :
- (longlong) value, 4);
+ set_int(unsigned_flag ? (longlong) ((uint8) value) :
+ (longlong) value, 4);
*pos+= 1;
}
-static void set_param_short(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_short(uchar **pos, ulong len)
{
int16 value;
#ifndef EMBEDDED_LIBRARY
@@ -516,12 +501,12 @@ static void set_param_short(Item_param *param, uchar **pos, ulong len)
#else
shortget(value, *pos);
#endif
- param->set_int(param->unsigned_flag ? (longlong) ((uint16) value) :
- (longlong) value, 6);
+ set_int(unsigned_flag ? (longlong) ((uint16) value) :
+ (longlong) value, 6);
*pos+= 2;
}
-static void set_param_int32(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_int32(uchar **pos, ulong len)
{
int32 value;
#ifndef EMBEDDED_LIBRARY
@@ -531,12 +516,12 @@ static void set_param_int32(Item_param *param, uchar **pos, ulong len)
#else
longget(value, *pos);
#endif
- param->set_int(param->unsigned_flag ? (longlong) ((uint32) value) :
- (longlong) value, 11);
+ set_int(unsigned_flag ? (longlong) ((uint32) value) :
+ (longlong) value, 11);
*pos+= 4;
}
-static void set_param_int64(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_int64(uchar **pos, ulong len)
{
longlong value;
#ifndef EMBEDDED_LIBRARY
@@ -546,11 +531,11 @@ static void set_param_int64(Item_param *param, uchar **pos, ulong len)
#else
longlongget(value, *pos);
#endif
- param->set_int(value, 21);
+ set_int(value, 21);
*pos+= 8;
}
-static void set_param_float(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_float(uchar **pos, ulong len)
{
float data;
#ifndef EMBEDDED_LIBRARY
@@ -560,11 +545,11 @@ static void set_param_float(Item_param *param, uchar **pos, ulong len)
#else
floatget(data, *pos);
#endif
- param->set_double((double) data);
+ set_double((double) data);
*pos+= 4;
}
-static void set_param_double(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_double(uchar **pos, ulong len)
{
double data;
#ifndef EMBEDDED_LIBRARY
@@ -574,14 +559,14 @@ static void set_param_double(Item_param *param, uchar **pos, ulong len)
#else
doubleget(data, *pos);
#endif
- param->set_double((double) data);
+ set_double((double) data);
*pos+= 8;
}
-static void set_param_decimal(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_decimal(uchar **pos, ulong len)
{
ulong length= get_param_length(pos, len);
- param->set_decimal((char*)*pos, length);
+ set_decimal((char*)*pos, length);
*pos+= length;
}
@@ -597,7 +582,7 @@ static void set_param_decimal(Item_param *param, uchar **pos, ulong len)
@todo
Add warning 'Data truncated' here
*/
-static void set_param_time(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_time(uchar **pos, ulong len)
{
MYSQL_TIME tm;
ulong length= get_param_length(pos, len);
@@ -624,11 +609,11 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
}
else
set_zero_time(&tm, MYSQL_TIMESTAMP_TIME);
- param->set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_FULL_WIDTH);
+ set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_FULL_WIDTH);
*pos+= length;
}
-static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_datetime(uchar **pos, ulong len)
{
MYSQL_TIME tm;
ulong length= get_param_length(pos, len);
@@ -654,13 +639,12 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
}
else
set_zero_time(&tm, MYSQL_TIMESTAMP_DATETIME);
- param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
- MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
+ set_time(&tm, MYSQL_TIMESTAMP_DATETIME, MAX_DATETIME_WIDTH);
*pos+= length;
}
-static void set_param_date(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_date(uchar **pos, ulong len)
{
MYSQL_TIME tm;
ulong length= get_param_length(pos, len);
@@ -679,8 +663,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
}
else
set_zero_time(&tm, MYSQL_TIMESTAMP_DATE);
- param->set_time(&tm, MYSQL_TIMESTAMP_DATE,
- MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
+ set_time(&tm, MYSQL_TIMESTAMP_DATE, MAX_DATE_WIDTH);
*pos+= length;
}
@@ -689,7 +672,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
@todo
Add warning 'Data truncated' here
*/
-void set_param_time(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_time(uchar **pos, ulong len)
{
MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
tm.hour+= tm.day * 24;
@@ -701,145 +684,81 @@ void set_param_time(Item_param *param, uchar **pos, ulong len)
tm.minute= 59;
tm.second= 59;
}
- param->set_time(&tm, MYSQL_TIMESTAMP_TIME,
- MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
-
+ set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_WIDTH);
}
-void set_param_datetime(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_datetime(uchar **pos, ulong len)
{
MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
tm.neg= 0;
-
- param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
- MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
+ set_time(&tm, MYSQL_TIMESTAMP_DATETIME, MAX_DATETIME_WIDTH);
}
-void set_param_date(Item_param *param, uchar **pos, ulong len)
+void Item_param::set_param_date(uchar **pos, ulong len)
{
MYSQL_TIME *to= (MYSQL_TIME*)*pos;
-
- param->set_time(to, MYSQL_TIMESTAMP_DATE,
- MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
+ set_time(to, MYSQL_TIMESTAMP_DATE, MAX_DATE_WIDTH);
}
#endif /*!EMBEDDED_LIBRARY*/
-static void set_param_str_or_null(Item_param *param, uchar **pos, ulong len,
- bool empty_string_is_null)
+void Item_param::set_param_str(uchar **pos, ulong len)
{
ulong length= get_param_length(pos, len);
- if (length == 0 && empty_string_is_null)
- param->set_null();
+ if (length == 0 && m_empty_string_is_null)
+ set_null();
else
{
if (length > len)
length= len;
- param->set_str((const char *) *pos, length);
+ /*
+ We use &my_charset_bin here. Conversion and setting real character
+ sets will be done in Item_param::convert_str_value(), after the
+ original value is appended to the query used for logging.
+ */
+ set_str((const char *) *pos, length, &my_charset_bin, &my_charset_bin);
*pos+= length;
}
}
-static void set_param_str(Item_param *param, uchar **pos, ulong len)
-{
- set_param_str_or_null(param, pos, len, false);
-}
+#undef get_param_length
-/*
- set_param_str_empty_is_null : bind empty string as null value
- when sql_mode=MODE_EMPTY_STRING_IS_NULL
-*/
-static void set_param_str_empty_is_null(Item_param *param, uchar **pos,
- ulong len)
+void Item_param::setup_conversion(THD *thd, uchar param_type)
{
- set_param_str_or_null(param, pos, len, true);
+ const Type_handler *h=
+ Type_handler::get_handler_by_field_type((enum_field_types) param_type);
+ /*
+ The client library ensures that we won't get any unexpected typecodes
+ in the bound parameter. Translating unknown typecodes to
+ &type_handler_string lets us to handle malformed packets as well.
+ */
+ if (!h)
+ h= &type_handler_string;
+ set_handler(h);
+ h->Item_param_setup_conversion(thd, this);
}
-#undef get_param_length
-
-static void setup_one_conversion_function(THD *thd, Item_param *param,
- uchar param_type)
+void Item_param::setup_conversion_blob(THD *thd)
{
- switch (param_type) {
- case MYSQL_TYPE_TINY:
- param->set_param_func= set_param_tiny;
- break;
- case MYSQL_TYPE_SHORT:
- param->set_param_func= set_param_short;
- break;
- case MYSQL_TYPE_LONG:
- param->set_param_func= set_param_int32;
- break;
- case MYSQL_TYPE_LONGLONG:
- param->set_param_func= set_param_int64;
- break;
- case MYSQL_TYPE_FLOAT:
- param->set_param_func= set_param_float;
- break;
- case MYSQL_TYPE_DOUBLE:
- param->set_param_func= set_param_double;
- break;
- case MYSQL_TYPE_DECIMAL:
- case MYSQL_TYPE_NEWDECIMAL:
- param->set_param_func= set_param_decimal;
- break;
- case MYSQL_TYPE_TIME:
- param->set_param_func= set_param_time;
- break;
- case MYSQL_TYPE_DATE:
- param->set_param_func= set_param_date;
- break;
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_TIMESTAMP:
- param->set_param_func= set_param_datetime;
- break;
- case MYSQL_TYPE_TINY_BLOB:
- case MYSQL_TYPE_MEDIUM_BLOB:
- case MYSQL_TYPE_LONG_BLOB:
- case MYSQL_TYPE_BLOB:
- param->set_param_func= set_param_str;
- param->value.cs_info.character_set_of_placeholder= &my_charset_bin;
- param->value.cs_info.character_set_client=
- thd->variables.character_set_client;
- DBUG_ASSERT(thd->variables.character_set_client);
- param->value.cs_info.final_character_set_of_str_value= &my_charset_bin;
- break;
- default:
- /*
- The client library ensures that we won't get any other typecodes
- except typecodes above and typecodes for string types. Marking
- label as 'default' lets us to handle malformed packets as well.
- */
- {
- CHARSET_INFO *fromcs= thd->variables.character_set_client;
- CHARSET_INFO *tocs= thd->variables.collation_connection;
- uint32 dummy_offset;
-
- param->value.cs_info.character_set_of_placeholder= fromcs;
- param->value.cs_info.character_set_client= fromcs;
+ value.cs_info.character_set_of_placeholder= &my_charset_bin;
+ value.cs_info.character_set_client= thd->variables.character_set_client;
+ DBUG_ASSERT(thd->variables.character_set_client);
+ value.cs_info.final_character_set_of_str_value= &my_charset_bin;
+ m_empty_string_is_null= thd->variables.sql_mode & MODE_EMPTY_STRING_IS_NULL;
+}
- /*
- Setup source and destination character sets so that they
- are different only if conversion is necessary: this will
- make later checks easier.
- */
- param->value.cs_info.final_character_set_of_str_value=
- String::needs_conversion(0, fromcs, tocs, &dummy_offset) ?
- tocs : fromcs;
- param->set_param_func=
- (thd->variables.sql_mode & MODE_EMPTY_STRING_IS_NULL) ?
- set_param_str_empty_is_null : set_param_str;
- /*
- Exact value of max_length is not known unless data is converted to
- charset of connection, so we have to set it later.
- */
- }
- }
- param->set_handler_by_field_type((enum enum_field_types) param_type);
+void Item_param::setup_conversion_string(THD *thd, CHARSET_INFO *fromcs)
+{
+ value.cs_info.set(thd, fromcs);
+ m_empty_string_is_null= thd->variables.sql_mode & MODE_EMPTY_STRING_IS_NULL;
+ /*
+ Exact value of max_length is not known unless data is converted to
+ charset of connection, so we have to set it later.
+ */
}
#ifndef EMBEDDED_LIBRARY
@@ -903,14 +822,13 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
{
if (read_pos >= data_end)
DBUG_RETURN(1);
- param->set_param_func(param, &read_pos, (uint) (data_end - read_pos));
+ param->set_param_func(&read_pos, (uint) (data_end - read_pos));
if (param->has_no_value())
DBUG_RETURN(1);
if (param->limit_clause_param && !param->has_int_value())
{
- param->set_int(param->val_int(), MY_INT64_NUM_DECIMAL_DIGITS);
- if (!param->unsigned_flag && param->value.integer < 0)
+ if (param->set_limit_clause_param(param->val_int()))
DBUG_RETURN(1);
}
}
@@ -958,7 +876,7 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
{
if (read_pos >= data_end)
DBUG_RETURN(1);
- param->set_param_func(param, &read_pos, (uint) (data_end - read_pos));
+ param->set_param_func(&read_pos, (uint) (data_end - read_pos));
if (param->has_no_value())
DBUG_RETURN(1);
}
@@ -1002,7 +920,7 @@ static bool insert_bulk_params(Prepared_statement *stmt,
case STMT_INDICATOR_NONE:
if ((*read_pos) >= data_end)
DBUG_RETURN(1);
- param->set_param_func(param, read_pos, (uint) (data_end - (*read_pos)));
+ param->set_param_func(read_pos, (uint) (data_end - (*read_pos)));
if (param->has_no_value())
DBUG_RETURN(1);
if (param->convert_str_value(stmt->thd))
@@ -1048,7 +966,7 @@ static bool set_conversion_functions(Prepared_statement *stmt,
typecode= sint2korr(read_pos);
read_pos+= 2;
(**it).unsigned_flag= MY_TEST(typecode & signed_bit);
- setup_one_conversion_function(thd, *it, (uchar) (typecode & 0xff));
+ (*it)->setup_conversion(thd, (uchar) (typecode & 0xff));
}
*data= read_pos;
DBUG_RETURN(0);
@@ -1103,7 +1021,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query)
for (; it < end; ++it, ++client_param)
{
Item_param *param= *it;
- setup_one_conversion_function(thd, param, client_param->buffer_type);
+ param->setup_conversion(thd, client_param->buffer_type);
if (!param->has_long_data_value())
{
if (*client_param->is_null)
@@ -1112,7 +1030,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query)
{
uchar *buff= (uchar*) client_param->buffer;
param->unsigned_flag= client_param->is_unsigned;
- param->set_param_func(param, &buff,
+ param->set_param_func(&buff,
client_param->length ?
*client_param->length :
client_param->buffer_length);
@@ -1139,7 +1057,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt, String *query)
for (; it < end; ++it, ++client_param)
{
Item_param *param= *it;
- setup_one_conversion_function(thd, param, client_param->buffer_type);
+ param->setup_conversion(thd, client_param->buffer_type);
if (!param->has_long_data_value())
{
if (*client_param->is_null)
@@ -1148,7 +1066,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt, String *query)
{
uchar *buff= (uchar*)client_param->buffer;
param->unsigned_flag= client_param->is_unsigned;
- param->set_param_func(param, &buff,
+ param->set_param_func(&buff,
client_param->length ?
*client_param->length :
client_param->buffer_length);
@@ -1281,12 +1199,6 @@ insert_params_from_actual_params_with_log(Prepared_statement *stmt,
{
Item_param *param= *it;
Item *ps_param= param_it++;
- /*
- We have to call the setup_one_conversion_function() here to set
- the parameter's members that might be needed further
- (e.g. value.cs_info.character_set_client is used in the query_val_str()).
- */
- setup_one_conversion_function(thd, param, param->field_type());
if (ps_param->save_in_param(thd, param))
DBUG_RETURN(1);
@@ -1380,7 +1292,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
{
my_error(ER_DELAYED_NOT_SUPPORTED, MYF(0), (table_list->view ?
table_list->view_name.str :
- table_list->table_name));
+ table_list->table_name.str));
goto error;
}
while ((values= its++))
@@ -1392,7 +1304,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
goto error;
}
if (setup_fields(thd, Ref_ptr_array(),
- *values, MARK_COLUMNS_NONE, 0, NULL, 0))
+ *values, COLUMNS_READ, 0, NULL, 0))
goto error;
}
}
@@ -1464,7 +1376,7 @@ static int mysql_test_update(Prepared_statement *stmt,
if (!table_list->single_table_updatable())
{
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "UPDATE");
goto error;
}
@@ -1498,7 +1410,7 @@ static int mysql_test_update(Prepared_statement *stmt,
table_list->register_want_access(SELECT_ACL);
#endif
if (setup_fields(thd, Ref_ptr_array(),
- stmt->lex->value_list, MARK_COLUMNS_NONE, 0, NULL, 0) ||
+ stmt->lex->value_list, COLUMNS_READ, 0, NULL, 0) ||
check_unique_table(thd, table_list))
goto error;
/* TODO: here we should send types of placeholders to the client. */
@@ -1542,7 +1454,7 @@ static bool mysql_test_delete(Prepared_statement *stmt,
if (!table_list->single_table_updatable())
{
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE");
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "DELETE");
goto error;
}
if (!table_list->table || !table_list->table->is_created())
@@ -1590,8 +1502,6 @@ static int mysql_test_select(Prepared_statement *stmt,
lex->select_lex.context.resolve_in_select_list= TRUE;
ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL;
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- goto error;
if (tables)
{
if (check_table_access(thd, privilege, tables, FALSE, UINT_MAX, FALSE))
@@ -1673,7 +1583,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt,
DT_PREPARE | DT_CREATE))
DBUG_RETURN(TRUE);
DBUG_RETURN(setup_fields(thd, Ref_ptr_array(),
- *values, MARK_COLUMNS_NONE, 0, NULL, 0));
+ *values, COLUMNS_READ, 0, NULL, 0));
}
@@ -1858,9 +1768,6 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
if (create_table_precheck(thd, tables, create_table))
DBUG_RETURN(TRUE);
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- DBUG_RETURN(TRUE);
-
if (select_lex->item_list.elements)
{
/* Base table and temporary table are not in the same name space. */
@@ -2251,9 +2158,6 @@ static bool mysql_test_insert_select(Prepared_statement *stmt,
if (insert_precheck(stmt->thd, tables))
return 1;
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- return 1;
-
/* store it, because mysql_insert_select_prepare_tester change it */
first_local_table= lex->select_lex.table_list.first;
DBUG_ASSERT(first_local_table != 0);
@@ -2304,10 +2208,8 @@ static int mysql_test_handler_read(Prepared_statement *stmt,
if (!stmt->is_sql_prepare())
{
if (!lex->result && !(lex->result= new (stmt->mem_root) select_send(thd)))
- {
- my_error(ER_OUTOFMEMORY, MYF(0), (int) sizeof(select_send));
DBUG_RETURN(1);
- }
+
if (send_prep_stmt(stmt, ha_table->fields.elements) ||
lex->result->send_result_set_metadata(ha_table->fields, Protocol::SEND_EOF) ||
thd->protocol->flush())
@@ -2358,6 +2260,9 @@ static bool check_prepared_statement(Prepared_statement *stmt)
if (tables)
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
+ if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
+ goto error;
+
if (sql_command_flags[sql_command] & CF_HA_CLOSE)
mysql_ha_rm_tables(thd, tables);
@@ -2850,6 +2755,25 @@ void mysql_sql_stmt_prepare(THD *thd)
DBUG_VOID_RETURN;
}
+ /*
+ Make sure we call Prepared_statement::prepare() with an empty
+ THD::change_list. It can be non-empty as LEX::get_dynamic_sql_string()
+ calls fix_fields() for the Item containing the PS source,
+ e.g. on character set conversion:
+
+ SET NAMES utf8;
+ DELIMITER $$
+ CREATE PROCEDURE p1()
+ BEGIN
+ PREPARE stmt FROM CONCAT('SELECT ',CONVERT(RAND() USING latin1));
+ EXECUTE stmt;
+ END;
+ $$
+ DELIMITER ;
+ CALL p1();
+ */
+ Item_change_list_savepoint change_list_savepoint(thd);
+
if (stmt->prepare(query.str, (uint) query.length))
{
/* Statement map deletes the statement on erase */
@@ -2860,6 +2784,7 @@ void mysql_sql_stmt_prepare(THD *thd)
SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL);
my_ok(thd, 0L, 0L, "Statement prepared");
}
+ change_list_savepoint.rollback(thd);
DBUG_VOID_RETURN;
}
@@ -2891,7 +2816,28 @@ void mysql_sql_stmt_execute_immediate(THD *thd)
// See comments on thd->free_list in mysql_sql_stmt_execute()
Item *free_list_backup= thd->free_list;
thd->free_list= NULL;
+ /*
+ Make sure we call Prepared_statement::execute_immediate()
+ with an empty THD::change_list. It can be non empty as the above
+ LEX::prepared_stmt_params_fix_fields() and LEX::get_dynamic_str_string()
+ call fix_fields() for the PS source and PS parameter Items and
+ can do Item tree changes, e.g. on character set conversion:
+
+ - Example #1: Item tree changes in get_dynamic_str_string()
+ SET NAMES utf8;
+ CREATE PROCEDURE p1()
+ EXECUTE IMMEDIATE CONCAT('SELECT ',CONVERT(RAND() USING latin1));
+ CALL p1();
+
+ - Example #2: Item tree changes in prepared_stmt_param_fix_fields():
+ SET NAMES utf8;
+ CREATE PROCEDURE p1(a VARCHAR(10) CHARACTER SET utf8)
+ EXECUTE IMMEDIATE 'SELECT ?' USING CONCAT(a, CONVERT(RAND() USING latin1));
+ CALL p1('x');
+ */
+ Item_change_list_savepoint change_list_savepoint(thd);
(void) stmt->execute_immediate(query.str, (uint) query.length);
+ change_list_savepoint.rollback(thd);
thd->free_items();
thd->free_list= free_list_backup;
@@ -3289,7 +3235,27 @@ void mysql_sql_stmt_execute(THD *thd)
*/
Item *free_list_backup= thd->free_list;
thd->free_list= NULL; // Hide the external (e.g. "SET STATEMENT") Items
+ /*
+ Make sure we call Prepared_statement::execute_loop() with an empty
+ THD::change_list. It can be non-empty because the above
+ LEX::prepared_stmt_params_fix_fields() calls fix_fields() for
+ the PS parameter Items and can do some Item tree changes,
+ e.g. on character set conversion:
+
+ SET NAMES utf8;
+ DELIMITER $$
+ CREATE PROCEDURE p1(a VARCHAR(10) CHARACTER SET utf8)
+ BEGIN
+ PREPARE stmt FROM 'SELECT ?';
+ EXECUTE stmt USING CONCAT(a, CONVERT(RAND() USING latin1));
+ END;
+ $$
+ DELIMITER ;
+ CALL p1('x');
+ */
+ Item_change_list_savepoint change_list_savepoint(thd);
(void) stmt->execute_loop(&expanded_query, FALSE, NULL, NULL);
+ change_list_savepoint.rollback(thd);
thd->free_items(); // Free items created by execute_loop()
/*
Now restore the "external" (e.g. "SET STATEMENT") Item list.
@@ -3719,8 +3685,10 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
read_types(0),
m_sql_mode(thd->variables.sql_mode)
{
- init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size,
- thd_arg->variables.query_prealloc_size, MYF(MY_THREAD_SPECIFIC));
+ init_sql_alloc(&main_mem_root, "Prepared_statement",
+ thd_arg->variables.query_alloc_block_size,
+ thd_arg->variables.query_prealloc_size,
+ MYF(MY_THREAD_SPECIFIC));
*last_error= '\0';
}
@@ -3814,9 +3782,9 @@ void Prepared_statement::cleanup_stmt()
DBUG_ENTER("Prepared_statement::cleanup_stmt");
DBUG_PRINT("enter",("stmt: %p", this));
lex->restore_set_statement_var();
+ thd->rollback_item_tree_changes();
cleanup_items(free_list);
thd->cleanup_after_query();
- thd->rollback_item_tree_changes();
DBUG_VOID_RETURN;
}
@@ -3837,24 +3805,22 @@ bool Prepared_statement::set_name(LEX_CSTRING *name_arg)
a prepared statement since it affects execution environment:
privileges, @@character_set_database, and other.
- @return Returns an error if out of memory.
+ @return 1 if out of memory.
*/
bool
-Prepared_statement::set_db(const char *db_arg, uint db_length_arg)
+Prepared_statement::set_db(const LEX_CSTRING *db_arg)
{
/* Remember the current database. */
- if (db_arg && db_length_arg)
+ if (db_arg->length)
{
- db= this->strmake(db_arg, db_length_arg);
- db_length= db_length_arg;
+ if (!(db.str= this->strmake(db_arg->str, db_arg->length)))
+ return 1;
+ db.length= db_arg->length;
}
else
- {
- db= NULL;
- db_length= 0;
- }
- return db_arg != NULL && db == NULL;
+ db= null_clex_str;
+ return 0;
}
/**************************************************************************
@@ -3901,8 +3867,9 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
if (! (lex= new (mem_root) st_lex_local))
DBUG_RETURN(TRUE);
+ stmt_lex= lex;
- if (set_db(thd->db, thd->db_length))
+ if (set_db(&thd->db))
DBUG_RETURN(TRUE);
/*
@@ -3957,7 +3924,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
If called from a stored procedure, ensure that we won't rollback
external changes when cleaning up after validation.
*/
- DBUG_ASSERT(thd->change_list.is_empty());
+ DBUG_ASSERT(thd->Item_change_list::is_empty());
/*
Marker used to release metadata locks acquired while the prepared
@@ -4006,8 +3973,6 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
trans_rollback_implicit(thd);
thd->mdl_context.release_transactional_locks();
}
-
- select_number_after_prepare= thd->select_number;
/* Preserve CHANGE MASTER attributes */
lex_end_stage1(lex);
@@ -4144,7 +4109,6 @@ Prepared_statement::execute_loop(String *expanded_query,
*/
DBUG_ASSERT(thd->free_list == NULL);
- thd->select_number= select_number_after_prepare;
/* Check if we got an error when sending long data */
if (state == Query_arena::STMT_ERROR)
{
@@ -4287,7 +4251,6 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
#ifdef DBUG_ASSERT_EXISTS
Item *free_list_state= thd->free_list;
#endif
- thd->select_number= select_number_after_prepare;
thd->set_bulk_execution((void *)this);
/* Check if we got an error when sending long data */
if (state == Query_arena::STMT_ERROR)
@@ -4434,7 +4397,7 @@ Prepared_statement::execute_server_runnable(Server_runnable *server_runnable)
bool error;
Query_arena *save_stmt_arena= thd->stmt_arena;
Item_change_list save_change_list;
- thd->change_list.move_elements_to(&save_change_list);
+ thd->Item_change_list::move_elements_to(&save_change_list);
state= STMT_CONVENTIONAL_EXECUTION;
@@ -4453,7 +4416,7 @@ Prepared_statement::execute_server_runnable(Server_runnable *server_runnable)
thd->restore_backup_statement(this, &stmt_backup);
thd->stmt_arena= save_stmt_arena;
- save_change_list.move_elements_to(&thd->change_list);
+ save_change_list.move_elements_to(thd);
/* Items and memory will freed in destructor */
@@ -4480,7 +4443,7 @@ Prepared_statement::reprepare()
char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
LEX_STRING saved_cur_db_name=
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
- LEX_CSTRING stmt_db_name= { db, db_length };
+ LEX_CSTRING stmt_db_name= db;
bool cur_db_changed;
bool error;
@@ -4603,8 +4566,7 @@ Prepared_statement::swap_prepared_statement(Prepared_statement *copy)
/* Swap names, the old name is allocated in the wrong memory root */
swap_variables(LEX_CSTRING, name, copy->name);
/* Ditto */
- swap_variables(char *, db, copy->db);
- swap_variables(size_t, db_length, copy->db_length);
+ swap_variables(LEX_CSTRING, db, copy->db);
DBUG_ASSERT(param_count == copy->param_count);
DBUG_ASSERT(thd == copy->thd);
@@ -4646,7 +4608,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
bool cur_db_changed;
- LEX_CSTRING stmt_db_name= { db, db_length };
+ LEX_CSTRING stmt_db_name= db;
status_var_increment(thd->status_var.com_stmt_execute);
@@ -4681,7 +4643,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
If the free_list is not empty, we'll wrongly free some externally
allocated items when cleaning up after execution of this statement.
*/
- DBUG_ASSERT(thd->change_list.is_empty());
+ DBUG_ASSERT(thd->Item_change_list::is_empty());
/*
The only case where we should have items in the thd->free_list is
@@ -4747,7 +4709,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
PSI_statement_locker *parent_locker;
MYSQL_QUERY_EXEC_START(thd->query(),
thd->thread_id,
- (char *) (thd->db ? thd->db : ""),
+ thd->get_db(),
&thd->security_ctx->priv_user[0],
(char *) thd->security_ctx->host_or_ip,
1);
@@ -4806,7 +4768,19 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
if (error == 0 && this->lex->sql_command == SQLCOM_CALL)
{
if (is_sql_prepare())
+ {
+ /*
+ Here we have the diagnostics area status already set to DA_OK.
+ sent_out_parameters() can raise errors when assigning OUT parameters:
+ DECLARE a DATETIME;
+ EXECUTE IMMEDIATE 'CALL p1(?)' USING a;
+ when the procedure p1 assigns a DATETIME-incompatible value (e.g. 10)
+ to the out parameter. Allow to overwrite status (to DA_ERROR).
+ */
+ thd->get_stmt_da()->set_overwrite_status(true);
thd->protocol_text.send_out_parameters(&this->lex->param_list);
+ thd->get_stmt_da()->set_overwrite_status(false);
+ }
else
thd->protocol->send_out_parameters(&this->lex->param_list);
}
@@ -5370,7 +5344,8 @@ bool Protocol_local::send_result_set_metadata(List<Item> *columns, uint)
{
DBUG_ASSERT(m_rset == 0 && !alloc_root_inited(&m_rset_root));
- init_sql_alloc(&m_rset_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
+ init_sql_alloc(&m_rset_root, "send_result_set_metadata",
+ MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
if (! (m_rset= new (&m_rset_root) List<Ed_row>))
return TRUE;
diff --git a/sql/sql_prepare.h b/sql/sql_prepare.h
index 203b37b3b26..ca040da341f 100644
--- a/sql/sql_prepare.h
+++ b/sql/sql_prepare.h
@@ -130,6 +130,7 @@ public:
size_t get_field_count() const { return m_column_count; }
static void operator delete(void *ptr, size_t size) throw ();
+ static void operator delete(void *, MEM_ROOT *){}
private:
Ed_result_set(const Ed_result_set &); /* not implemented */
Ed_result_set &operator=(Ed_result_set &); /* not implemented */
@@ -215,21 +216,6 @@ public:
bool execute_direct(Server_runnable *server_runnable);
/**
- Get the number of result set fields.
-
- This method is valid only if we have a result:
- execute_direct() has been called. Otherwise
- the returned value is undefined.
-
- @sa Documentation for C API function
- mysql_field_count()
- */
- ulong get_field_count() const
- {
- return m_current_rset ? m_current_rset->get_field_count() : 0;
- }
-
- /**
Get the number of affected (deleted, updated)
rows for the current statement. Can be
used for statements with get_field_count() == 0.
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index b3b041a3602..ba37d933f12 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -227,7 +227,7 @@
#define OPTIMIZER_SWITCH_EXISTS_TO_IN (1ULL << 28)
#define OPTIMIZER_SWITCH_ORDERBY_EQ_PROP (1ULL << 29)
#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED (1ULL << 30)
-#define OPTIMIZER_SWITCH_SPLIT_GROUPING_DERIVED (1ULL << 31)
+#define OPTIMIZER_SWITCH_SPLIT_MATERIALIZED (1ULL << 31)
#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
@@ -254,7 +254,7 @@
OPTIMIZER_SWITCH_EXISTS_TO_IN | \
OPTIMIZER_SWITCH_ORDERBY_EQ_PROP | \
OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED | \
- OPTIMIZER_SWITCH_SPLIT_GROUPING_DERIVED)
+ OPTIMIZER_SWITCH_SPLIT_MATERIALIZED)
/*
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
@@ -327,6 +327,8 @@
/* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */
#define UNDEF_POS (-1)
+#define IN_SUBQUERY_CONVERSION_THRESHOLD 1000
+
#endif /* !MYSQL_CLIENT */
/* BINLOG_DUMP options */
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index c1a13ebd210..13f03fed5f3 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -284,11 +284,10 @@ QUERY_PROFILE::~QUERY_PROFILE()
/**
@todo Provide a way to include the full text, as in SHOW PROCESSLIST.
*/
-void QUERY_PROFILE::set_query_source(char *query_source_arg,
- uint query_length_arg)
+void QUERY_PROFILE::set_query_source(char *query_source_arg, size_t query_length_arg)
{
/* Truncate to avoid DoS attacks. */
- uint length= MY_MIN(MAX_QUERY_LENGTH, query_length_arg);
+ size_t length= MY_MIN(MAX_QUERY_LENGTH, query_length_arg);
DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
if (query_source_arg != NULL)
diff --git a/sql/sql_profile.h b/sql/sql_profile.h
index c96828fc678..cb553d2f757 100644
--- a/sql/sql_profile.h
+++ b/sql/sql_profile.h
@@ -227,7 +227,7 @@ private:
QUERY_PROFILE(PROFILING *profiling_arg, const char *status_arg);
~QUERY_PROFILE();
- void set_query_source(char *query_source_arg, uint query_length_arg);
+ void set_query_source(char *query_source_arg, size_t query_length_arg);
/* Add a profile status change to the current profile. */
void new_status(const char *status_arg,
@@ -275,7 +275,7 @@ public:
This must be called exactly once per descrete statement.
*/
- void set_query_source(char *query_source_arg, uint query_length_arg)
+ void set_query_source(char *query_source_arg, size_t query_length_arg)
{
if (unlikely(current))
current->set_query_source(query_source_arg, query_length_arg);
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index 057d1a9f46c..b8f0023eefb 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -153,7 +153,10 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
tmp_write_to_binlog= 0;
if (mysql_bin_log.is_open())
{
- if (mysql_bin_log.rotate_and_purge(true))
+ DYNAMIC_ARRAY *drop_gtid_domain=
+ (thd && (thd->lex->delete_gtid_domain.elements > 0)) ?
+ &thd->lex->delete_gtid_domain : NULL;
+ if (mysql_bin_log.rotate_and_purge(true, drop_gtid_domain))
*write_to_binlog= -1;
if (WSREP_ON)
@@ -286,7 +289,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
if (tables)
{
for (TABLE_LIST *t= tables; t; t= t->next_local)
- if (!find_table_for_mdl_upgrade(thd, t->db, t->table_name, false))
+ if (!find_table_for_mdl_upgrade(thd, t->db.str, t->table_name.str, false))
return 1;
}
else
@@ -409,11 +412,11 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */
if (options & REFRESH_GENERIC)
{
- List_iterator_fast<LEX_STRING> li(thd->lex->view_list);
- LEX_STRING *ls;
+ List_iterator_fast<LEX_CSTRING> li(thd->lex->view_list);
+ LEX_CSTRING *ls;
while ((ls= li++))
{
- ST_SCHEMA_TABLE *table= find_schema_table(thd, ls->str);
+ ST_SCHEMA_TABLE *table= find_schema_table(thd, ls);
if (table->reset_table())
result= 1;
}
@@ -537,8 +540,8 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
{
/* Request removal of table from cache. */
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
- table_list->db,
- table_list->table_name, FALSE);
+ table_list->db.str,
+ table_list->table_name.str, FALSE);
/* Reset ticket to satisfy asserts in open_tables(). */
table_list->mdl_request.ticket= NULL;
}
@@ -570,7 +573,7 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
if (!(table_list->table->file->ha_table_flags() & HA_CAN_EXPORT))
{
my_error(ER_ILLEGAL_HA, MYF(0),table_list->table->file->table_type(),
- table_list->db, table_list->table_name);
+ table_list->db.str, table_list->table_name.str);
goto error_reset_bits;
}
}
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 61e312646da..fa0fa3f0ea5 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -30,11 +30,12 @@
#include "sql_base.h" // tdc_remove_table, lock_table_names,
#include "sql_handler.h" // mysql_ha_rm_tables
#include "sql_statistics.h"
+#include "vtmd.h"
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
bool skip_error);
-static bool do_rename(THD *thd, TABLE_LIST *ren_table, const char *new_db,
- const char *new_table_name, const char *new_table_alias,
+static bool do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db,
+ const LEX_CSTRING *new_table_name, const LEX_CSTRING *new_table_alias,
bool skip_error);
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);
@@ -103,8 +104,9 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
Two renames of "log_table TO" w/o rename "TO log_table" in
between.
*/
- my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name,
- ren_table->table_name);
+ my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0),
+ ren_table->table_name.str,
+ ren_table->table_name.str);
goto err;
}
}
@@ -116,14 +118,15 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
Attempt to rename a table TO log_table w/o renaming
log_table TO some table.
*/
- my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name,
- ren_table->table_name);
+ my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0),
+ ren_table->table_name.str,
+ ren_table->table_name.str);
goto err;
}
else
{
/* save the name of the log table to report an error */
- rename_log_table[log_table_rename]= ren_table->table_name;
+ rename_log_table[log_table_rename]= ren_table->table_name.str;
}
}
}
@@ -215,21 +218,21 @@ static bool
do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table,
bool skip_error)
{
- const char *new_alias;
+ LEX_CSTRING *new_alias;
DBUG_ENTER("do_rename_temporary");
- new_alias= (lower_case_table_names == 2) ? new_table->alias :
- new_table->table_name;
+ new_alias= (lower_case_table_names == 2) ? &new_table->alias :
+ &new_table->table_name;
if (is_temporary_table(new_table))
{
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias->str);
DBUG_RETURN(1); // This can't be skipped
}
DBUG_RETURN(thd->rename_temporary_table(ren_table->table,
- new_table->db, new_alias));
+ &new_table->db, new_alias));
}
@@ -254,65 +257,71 @@ do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table,
*/
static bool
-do_rename(THD *thd, TABLE_LIST *ren_table, const char *new_db,
- const char *new_table_name, const char *new_table_alias,
+do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db,
+ const LEX_CSTRING *new_table_name, const LEX_CSTRING *new_table_alias,
bool skip_error)
{
int rc= 1;
handlerton *hton;
- const char *new_alias, *old_alias;
+ LEX_CSTRING old_alias, new_alias;
DBUG_ENTER("do_rename");
if (lower_case_table_names == 2)
{
old_alias= ren_table->alias;
- new_alias= new_table_alias;
+ new_alias= *new_table_alias;
}
else
{
old_alias= ren_table->table_name;
- new_alias= new_table_name;
+ new_alias= *new_table_name;
}
- DBUG_ASSERT(new_alias);
+ DBUG_ASSERT(new_alias.str);
- if (ha_table_exists(thd, new_db, new_alias))
+ if (ha_table_exists(thd, new_db, &new_alias))
{
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias.str);
DBUG_RETURN(1); // This can't be skipped
}
- if (ha_table_exists(thd, ren_table->db, old_alias, &hton) && hton)
+ if (ha_table_exists(thd, &ren_table->db, &old_alias, &hton) && hton)
{
DBUG_ASSERT(!thd->locked_tables_mode);
tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
- ren_table->db, ren_table->table_name, false);
+ ren_table->db.str, ren_table->table_name.str, false);
if (hton != view_pseudo_hton)
{
- if (!(rc= mysql_rename_table(hton, ren_table->db, old_alias,
- new_db, new_alias, 0)))
+ if (!(rc= mysql_rename_table(hton, &ren_table->db, &old_alias,
+ new_db, &new_alias, 0)))
{
- LEX_CSTRING db_name= { ren_table->db, ren_table->db_length };
- LEX_CSTRING table_name= { ren_table->table_name,
- ren_table->table_name_length };
- LEX_CSTRING new_table= { new_alias, strlen(new_alias) };
- LEX_CSTRING new_db_name= { new_db, strlen(new_db)};
- (void) rename_table_in_stat_tables(thd, &db_name, &table_name,
- &new_db_name, &new_table);
- if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
- old_alias,
- ren_table->table_name,
+ (void) rename_table_in_stat_tables(thd, &ren_table->db,
+ &ren_table->table_name,
+ new_db, &new_alias);
+ VTMD_rename vtmd(*ren_table);
+ if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
+ {
+ rc= vtmd.try_rename(thd, new_db->str, new_alias.str);
+ if (rc)
+ goto revert_table_name;
+ }
+ if ((rc= Table_triggers_list::change_table_name(thd, &ren_table->db,
+ &old_alias,
+ &ren_table->table_name,
new_db,
- new_alias)))
+ &new_alias)))
{
+ if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
+ vtmd.revert_rename(thd, new_db->str);
+revert_table_name:
/*
We've succeeded in renaming table's .frm and in updating
corresponding handler data, but have failed to update table's
triggers appropriately. So let us revert operations on .frm
and handler's data and report about failure to rename table.
*/
- (void) mysql_rename_table(hton, new_db, new_alias,
- ren_table->db, old_alias, NO_FK_CHECKS);
+ (void) mysql_rename_table(hton, new_db, &new_alias,
+ &ren_table->db, &old_alias, NO_FK_CHECKS);
}
}
}
@@ -324,15 +333,15 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const char *new_db,
because a view has valid internal db&table names in this case.
*/
if (thd->lex->sql_command != SQLCOM_ALTER_DB_UPGRADE &&
- strcmp(ren_table->db, new_db))
- my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, new_db);
+ cmp(&ren_table->db, new_db))
+ my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db.str, new_db->str);
else
- rc= mysql_rename_view(thd, new_db, new_alias, ren_table);
+ rc= mysql_rename_view(thd, new_db, &new_alias, ren_table);
}
}
else
{
- my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
+ my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db.str, old_alias.str);
}
if (rc && !skip_error)
DBUG_RETURN(1);
@@ -378,8 +387,8 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
if (is_temporary_table(ren_table) ?
do_rename_temporary(thd, ren_table, new_table, skip_error) :
- do_rename(thd, ren_table, new_table->db, new_table->table_name,
- new_table->alias, skip_error))
+ do_rename(thd, ren_table, &new_table->db, &new_table->table_name,
+ &new_table->alias, skip_error))
DBUG_RETURN(ren_table);
}
DBUG_RETURN(0);
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 839b98dc785..e1d1190e58f 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -28,9 +28,9 @@
#include "log_event.h"
#include "rpl_filter.h"
#include <my_dir.h>
-#include "rpl_handler.h"
#include "debug_sync.h"
-
+#include "semisync_master.h"
+#include "semisync_slave.h"
enum enum_gtid_until_state {
GTID_UNTIL_NOT_DONE,
@@ -160,6 +160,7 @@ struct binlog_send_info {
bool clear_initial_log_pos;
bool should_stop;
+ size_t dirlen;
binlog_send_info(THD *thd_arg, String *packet_arg, ushort flags_arg,
char *lfn)
@@ -313,16 +314,43 @@ static int reset_transmit_packet(binlog_send_info *info, ushort flags,
packet->length(0);
packet->set("\0", 1, &my_charset_bin);
- if (RUN_HOOK(binlog_transmit, reserve_header, (info->thd, flags, packet)))
+ if (info->thd->semi_sync_slave)
{
- info->error= ER_UNKNOWN_ERROR;
- *errmsg= "Failed to run hook 'reserve_header'";
- ret= 1;
+ if (repl_semisync_master.reserve_sync_header(packet))
+ {
+ info->error= ER_UNKNOWN_ERROR;
+ *errmsg= "Failed to run hook 'reserve_header'";
+ ret= 1;
+ }
}
+
*ev_offset= packet->length();
return ret;
}
+int get_user_var_int(const char *name,
+ long long int *value, int *null_value)
+{
+ bool null_val;
+ user_var_entry *entry=
+ (user_var_entry*) my_hash_search(&current_thd->user_vars,
+ (uchar*) name, strlen(name));
+ if (!entry)
+ return 1;
+ *value= entry->val_int(&null_val);
+ if (null_value)
+ *null_value= null_val;
+ return 0;
+}
+
+inline bool is_semi_sync_slave()
+{
+ int null_value;
+ long long val= 0;
+ get_user_var_int("rpl_semi_sync_slave", &val, &null_value);
+ return val;
+}
+
static int send_file(THD *thd)
{
NET* net = &thd->net;
@@ -417,7 +445,7 @@ inline void fix_checksum(String *packet, ulong ev_offset)
static user_var_entry * get_binlog_checksum_uservar(THD * thd)
{
- LEX_STRING name= { C_STRING_WITH_LEN("master_binlog_checksum")};
+ LEX_CSTRING name= { STRING_WITH_LEN("master_binlog_checksum")};
user_var_entry *entry=
(user_var_entry*) my_hash_search(&thd->user_vars, (uchar*) name.str,
name.length);
@@ -667,7 +695,7 @@ void set_read_error(binlog_send_info *info, int error)
static ulonglong get_heartbeat_period(THD * thd)
{
bool null_value;
- LEX_STRING name= { C_STRING_WITH_LEN("master_heartbeat_period")};
+ LEX_CSTRING name= { STRING_WITH_LEN("master_heartbeat_period")};
user_var_entry *entry=
(user_var_entry*) my_hash_search(&thd->user_vars, (uchar*) name.str,
name.length);
@@ -686,7 +714,7 @@ static int
get_mariadb_slave_capability(THD *thd)
{
bool null_value;
- const LEX_STRING name= { C_STRING_WITH_LEN("mariadb_slave_capability") };
+ const LEX_CSTRING name= { STRING_WITH_LEN("mariadb_slave_capability") };
const user_var_entry *entry=
(user_var_entry*) my_hash_search(&thd->user_vars, (uchar*) name.str,
name.length);
@@ -707,7 +735,7 @@ get_slave_connect_state(THD *thd, String *out_str)
{
bool null_value;
- const LEX_STRING name= { C_STRING_WITH_LEN("slave_connect_state") };
+ const LEX_CSTRING name= { STRING_WITH_LEN("slave_connect_state") };
user_var_entry *entry=
(user_var_entry*) my_hash_search(&thd->user_vars, (uchar*) name.str,
name.length);
@@ -720,7 +748,7 @@ get_slave_gtid_strict_mode(THD *thd)
{
bool null_value;
- const LEX_STRING name= { C_STRING_WITH_LEN("slave_gtid_strict_mode") };
+ const LEX_CSTRING name= { STRING_WITH_LEN("slave_gtid_strict_mode") };
user_var_entry *entry=
(user_var_entry*) my_hash_search(&thd->user_vars, (uchar*) name.str,
name.length);
@@ -733,7 +761,7 @@ get_slave_gtid_ignore_duplicates(THD *thd)
{
bool null_value;
- const LEX_STRING name= { C_STRING_WITH_LEN("slave_gtid_ignore_duplicates") };
+ const LEX_CSTRING name= { STRING_WITH_LEN("slave_gtid_ignore_duplicates") };
user_var_entry *entry=
(user_var_entry*) my_hash_search(&thd->user_vars, (uchar*) name.str,
name.length);
@@ -754,7 +782,7 @@ get_slave_until_gtid(THD *thd, String *out_str)
{
bool null_value;
- const LEX_STRING name= { C_STRING_WITH_LEN("slave_until_gtid") };
+ const LEX_CSTRING name= { STRING_WITH_LEN("slave_until_gtid") };
user_var_entry *entry=
(user_var_entry*) my_hash_search(&thd->user_vars, (uchar*) name.str,
name.length);
@@ -800,8 +828,8 @@ static int send_heartbeat_event(binlog_send_info *info,
char* p= coord->file_name + dirname_length(coord->file_name);
- uint ident_len = strlen(p);
- ulong event_len = ident_len + LOG_EVENT_HEADER_LEN +
+ size_t ident_len = strlen(p);
+ size_t event_len = ident_len + LOG_EVENT_HEADER_LEN +
(do_checksum ? BINLOG_CHECKSUM_LEN : 0);
int4store(header + SERVER_ID_OFFSET, global_system_variables.server_id);
int4store(header + EVENT_LEN_OFFSET, event_len);
@@ -875,72 +903,6 @@ get_binlog_list(MEM_ROOT *memroot)
DBUG_RETURN(current_list);
}
-/*
- Find the Gtid_list_log_event at the start of a binlog.
-
- NULL for ok, non-NULL error message for error.
-
- If ok, then the event is returned in *out_gtid_list. This can be NULL if we
- get back to binlogs written by old server version without GTID support. If
- so, it means we have reached the point to start from, as no GTID events can
- exist in earlier binlogs.
-*/
-static const char *
-get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list)
-{
- Format_description_log_event init_fdle(BINLOG_VERSION);
- Format_description_log_event *fdle;
- Log_event *ev;
- const char *errormsg = NULL;
-
- *out_gtid_list= NULL;
-
- if (!(ev= Log_event::read_log_event(cache, 0, &init_fdle,
- opt_master_verify_checksum)) ||
- ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
- {
- if (ev)
- delete ev;
- return "Could not read format description log event while looking for "
- "GTID position in binlog";
- }
-
- fdle= static_cast<Format_description_log_event *>(ev);
-
- for (;;)
- {
- Log_event_type typ;
-
- ev= Log_event::read_log_event(cache, 0, fdle, opt_master_verify_checksum);
- if (!ev)
- {
- errormsg= "Could not read GTID list event while looking for GTID "
- "position in binlog";
- break;
- }
- typ= ev->get_type_code();
- if (typ == GTID_LIST_EVENT)
- break; /* Done, found it */
- if (typ == START_ENCRYPTION_EVENT)
- {
- if (fdle->start_decryption((Start_encryption_log_event*) ev))
- errormsg= "Could not set up decryption for binlog.";
- }
- delete ev;
- if (typ == ROTATE_EVENT || typ == STOP_EVENT ||
- typ == FORMAT_DESCRIPTION_EVENT || typ == START_ENCRYPTION_EVENT)
- continue; /* Continue looking */
-
- /* We did not find any Gtid_list_log_event, must be old binlog. */
- ev= NULL;
- break;
- }
-
- delete fdle;
- *out_gtid_list= static_cast<Gtid_list_log_event *>(ev);
- return errormsg;
-}
-
/*
Check if every GTID requested by the slave is contained in this (or a later)
@@ -1262,8 +1224,9 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name,
const char *errormsg= NULL;
char buf[FN_REFLEN];
- init_alloc_root(&memroot, 10*(FN_REFLEN+sizeof(binlog_file_entry)), 0,
- MYF(MY_THREAD_SPECIFIC));
+ init_alloc_root(&memroot, "gtid_find_binlog_file",
+ 10*(FN_REFLEN+sizeof(binlog_file_entry)),
+ 0, MYF(MY_THREAD_SPECIFIC));
if (!(list= get_binlog_list(&memroot)))
{
errormsg= "Out of memory while looking for GTID position in binlog";
@@ -1672,6 +1635,7 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type,
enum enum_binlog_checksum_alg current_checksum_alg= info->current_checksum_alg;
slave_connection_state *gtid_state= &info->gtid_state;
slave_connection_state *until_gtid_state= info->until_gtid_state;
+ bool need_sync= false;
if (event_type == GTID_LIST_EVENT &&
info->using_gtid_state && until_gtid_state)
@@ -1970,11 +1934,8 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type,
*/
if (info->thd->variables.option_bits & OPTION_SKIP_REPLICATION)
{
- /*
- The first byte of the packet is a '\0' to distinguish it from an error
- packet. So the actual event starts at offset +1.
- */
- uint16 event_flags= uint2korr(&((*packet)[FLAGS_OFFSET+1]));
+ uint16 event_flags= uint2korr(&((*packet)[FLAGS_OFFSET + ev_offset]));
+
if (event_flags & LOG_EVENT_SKIP_REPLICATION_F)
return NULL;
}
@@ -1982,8 +1943,10 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type,
THD_STAGE_INFO(info->thd, stage_sending_binlog_event_to_slave);
pos= my_b_tell(log);
- if (RUN_HOOK(binlog_transmit, before_send_event,
- (info->thd, info->flags, packet, info->log_file_name, pos)))
+ if (repl_semisync_master.update_sync_header(info->thd,
+ (uchar*) packet->c_ptr(),
+ info->log_file_name + info->dirlen,
+ pos, &need_sync))
{
info->error= ER_UNKNOWN_ERROR;
return "run 'before_send_event' hook failed";
@@ -2005,8 +1968,7 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type,
}
}
- if (RUN_HOOK(binlog_transmit, after_send_event,
- (info->thd, info->flags, packet)))
+ if (need_sync && repl_semisync_master.flush_net(info->thd, packet->c_ptr()))
{
info->error= ER_UNKNOWN_ERROR;
return "Failed to run hook 'after_send_event'";
@@ -2436,7 +2398,7 @@ static int wait_new_events(binlog_send_info *info, /* in */
PSI_stage_info old_stage;
mysql_bin_log.lock_binlog_end_pos();
- info->thd->ENTER_COND(mysql_bin_log.get_log_cond(),
+ info->thd->ENTER_COND(mysql_bin_log.get_bin_log_cond(),
mysql_bin_log.get_binlog_end_pos_lock(),
&stage_master_has_sent_all_binlog_to_slave,
&old_stage);
@@ -2747,7 +2709,7 @@ static int send_one_binlog_file(binlog_send_info *info,
/** end of file or error */
return (int)end_pos;
}
-
+ info->dirlen= dirname_length(info->log_file_name);
/**
* send events from current position up to end_pos
*/
@@ -2769,6 +2731,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
binlog_send_info infoobj(thd, packet, flags, linfo.log_file_name);
binlog_send_info *info= &infoobj;
+ bool has_transmit_started= false;
int old_max_allowed_packet= thd->variables.max_allowed_packet;
thd->variables.max_allowed_packet= MAX_MAX_ALLOWED_PACKET;
@@ -2781,11 +2744,11 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
if (init_binlog_sender(info, &linfo, log_ident, &pos))
goto err;
- /*
- run hook first when all check has been made that slave seems to
- be requesting a reasonable position. i.e when transmit actually starts
- */
- if (RUN_HOOK(binlog_transmit, transmit_start, (thd, flags, log_ident, pos)))
+ has_transmit_started= true;
+
+ /* Check if the dump thread is created by a slave with semisync enabled. */
+ thd->semi_sync_slave = is_semi_sync_slave();
+ if (repl_semisync_master.dump_start(thd, log_ident, pos))
{
info->errmsg= "Failed to run hook 'transmit_start'";
info->error= ER_UNKNOWN_ERROR;
@@ -2907,7 +2870,10 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
err:
THD_STAGE_INFO(thd, stage_waiting_to_finalize_termination);
- RUN_HOOK(binlog_transmit, transmit_stop, (thd, flags));
+ if (has_transmit_started)
+ {
+ repl_semisync_master.dump_end(thd);
+ }
if (info->thd->killed == KILL_SLAVE_SAME_ID)
{
@@ -3373,7 +3339,8 @@ int reset_slave(THD *thd, Master_info* mi)
else if (global_system_variables.log_warnings > 1)
sql_print_information("Deleted Master_info file '%s'.", fname);
- RUN_HOOK(binlog_relay_io, after_reset_slave, (thd, mi));
+ if (rpl_semi_sync_slave_enabled)
+ repl_semisync_slave.reset_slave(mi);
err:
mi->unlock_slave_threads();
if (error)
@@ -3410,7 +3377,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
if (tmp->get_command() == COM_BINLOG_DUMP &&
tmp->variables.server_id == slave_server_id)
{
- mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
+ mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete
break;
}
}
@@ -3422,8 +3389,8 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
it will be slow because it will iterate through the list
again. We just to do kill the thread ourselves.
*/
- tmp->awake(KILL_SLAVE_SAME_ID);
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ tmp->awake_no_mutex(KILL_SLAVE_SAME_ID);
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
}
}
@@ -3442,10 +3409,11 @@ static bool get_string_parameter(char *to, const char *from, size_t length,
if (from) // Empty paramaters allowed
{
size_t from_length= strlen(from);
- uint from_numchars= cs->cset->numchars(cs, from, from + from_length);
+ size_t from_numchars= cs->cset->numchars(cs, from, from + from_length);
if (from_numchars > length / cs->mbmaxlen)
{
- my_error(ER_WRONG_STRING_LENGTH, MYF(0), from, name, (int) (length / cs->mbmaxlen));
+ my_error(ER_WRONG_STRING_LENGTH, MYF(0), from, name,
+ (int) (length / cs->mbmaxlen));
return 1;
}
memcpy(to, from, from_length+1);
@@ -3875,11 +3843,13 @@ int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len,
return 1;
}
- if (mysql_bin_log.reset_logs(thd, 1, init_state, init_state_len,
- next_log_number))
- return 1;
- RUN_HOOK(binlog_transmit, after_reset_master, (thd, 0 /* flags */));
- return 0;
+ bool ret= 0;
+ /* Temporarily disable master semisync before reseting master. */
+ repl_semisync_master.before_reset_master();
+ ret= mysql_bin_log.reset_logs(thd, 1, init_state, init_state_len,
+ next_log_number);
+ repl_semisync_master.after_reset_master();
+ return ret;
}
@@ -3996,7 +3966,7 @@ bool mysql_show_binlog_events(THD* thd)
my_off_t scan_pos = BIN_LOG_HEADER_SIZE;
while (scan_pos < pos)
{
- ev= Log_event::read_log_event(&log, (mysql_mutex_t*)0, description_event,
+ ev= Log_event::read_log_event(&log, description_event,
opt_master_verify_checksum);
scan_pos = my_b_tell(&log);
if (ev == NULL || !ev->is_valid())
@@ -4030,7 +4000,7 @@ bool mysql_show_binlog_events(THD* thd)
my_b_seek(&log, pos);
for (event_count = 0;
- (ev = Log_event::read_log_event(&log, (mysql_mutex_t*) 0,
+ (ev = Log_event::read_log_event(&log,
description_event,
opt_master_verify_checksum)); )
{
@@ -4154,7 +4124,7 @@ bool show_binlog_info(THD* thd)
{
LOG_INFO li;
mysql_bin_log.get_current_log(&li);
- int dir_len = dirname_length(li.log_file_name);
+ size_t dir_len = dirname_length(li.log_file_name);
protocol->store(li.log_file_name + dir_len, &my_charset_bin);
protocol->store((ulonglong) li.pos);
protocol->store(binlog_filter->get_do_db());
@@ -4196,8 +4166,8 @@ bool show_binlogs(THD* thd)
File file;
char fname[FN_REFLEN];
List<Item> field_list;
- uint length;
- int cur_dir_len;
+ size_t length;
+ size_t cur_dir_len;
Protocol *protocol= thd->protocol;
DBUG_ENTER("show_binlogs");
@@ -4227,7 +4197,7 @@ bool show_binlogs(THD* thd)
/* The file ends with EOF or empty line */
while ((length=my_b_gets(index_file, fname, sizeof(fname))) > 1)
{
- int dir_len;
+ size_t dir_len;
ulonglong file_length= 0; // Length if open fails
fname[--length] = '\0'; // remove the newline
@@ -4296,7 +4266,7 @@ int log_loaded_block(IO_CACHE* file, uchar *Buffer, size_t Count)
lf_info->last_pos_in_file= my_b_get_pos_in_file(file);
if (lf_info->wrote_create_file)
{
- Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
+ Append_block_log_event a(lf_info->thd, lf_info->thd->db.str, buffer,
MY_MIN(block_len, max_event_size),
lf_info->log_delayed);
if (mysql_bin_log.write(&a))
@@ -4304,7 +4274,7 @@ int log_loaded_block(IO_CACHE* file, uchar *Buffer, size_t Count)
}
else
{
- Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
+ Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db.str,
buffer,
MY_MIN(block_len, max_event_size),
lf_info->log_delayed);
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index 4105bdddf4e..8d9a127bca7 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -81,7 +81,6 @@ int rpl_append_gtid_state(String *dest, bool use_binlog);
int rpl_load_gtid_state(slave_connection_state *state, bool use_binlog);
bool rpl_gtid_pos_check(THD *thd, char *str, size_t len);
bool rpl_gtid_pos_update(THD *thd, char *str, size_t len);
-
#else
struct LOAD_FILE_IO_CACHE : public IO_CACHE { };
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 28600088153..0fb3275ceea 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016 Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, 2017 MariaDB
+ Copyright (c) 2009, 2018 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
@@ -54,12 +54,16 @@
#include "sql_statistics.h"
#include "sql_cte.h"
#include "sql_window.h"
+#include "tztime.h"
#include "debug_sync.h" // DEBUG_SYNC
#include <m_ctype.h>
#include <my_bit.h>
#include <hash.h>
#include <ft_global.h>
+#include "sys_vars_shared.h"
+#include "sp_head.h"
+#include "sp_rcontext.h"
/*
A key part number that means we're using a fulltext scan.
@@ -85,7 +89,6 @@ LEX_CSTRING distinct_key= {STRING_WITH_LEN("distinct_key")};
struct st_sargable_param;
-static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
static bool make_join_statistics(JOIN *join, List<TABLE_LIST> &leaves,
DYNAMIC_ARRAY *keyuse);
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
@@ -93,8 +96,6 @@ static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
uint tables, COND *conds,
table_map table_map, SELECT_LEX *select_lex,
SARGABLE_PARAM **sargables);
-static bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
- bool skip_unprefixed_keyparts);
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables);
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
@@ -285,6 +286,9 @@ JOIN_TAB *next_depth_first_tab(JOIN* join, JOIN_TAB* tab);
static JOIN_TAB *next_breadth_first_tab(JOIN_TAB *first_top_tab,
uint n_top_tabs_count, JOIN_TAB *tab);
+static bool find_order_in_list(THD *, Ref_ptr_array, TABLE_LIST *, ORDER *,
+ List<Item> &, List<Item> &, bool, bool, bool);
+
static double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
table_map rem_tables);
void set_postjoin_aggr_write_func(JOIN_TAB *tab);
@@ -336,7 +340,7 @@ bool dbug_user_var_equals_int(THD *thd, const char *name, int value)
}
return FALSE;
}
-#endif
+#endif
/**
@@ -669,6 +673,312 @@ setup_without_group(THD *thd, Ref_ptr_array ref_pointer_array,
DBUG_RETURN(res);
}
+bool vers_select_conds_t::init_from_sysvar(THD *thd)
+{
+ vers_asof_timestamp_t &in= thd->variables.vers_asof_timestamp;
+ type= (vers_system_time_t) in.type;
+ start.unit= VERS_TIMESTAMP;
+ from_query= false;
+ if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL)
+ {
+ DBUG_ASSERT(type == SYSTEM_TIME_AS_OF);
+ start.item= new (thd->mem_root)
+ Item_datetime_literal(thd, &in.ltime, TIME_SECOND_PART_DIGITS);
+ if (!start.item)
+ return true;
+ }
+ else
+ start.item= NULL;
+ end.empty();
+ return false;
+}
+
+void vers_select_conds_t::print(String *str, enum_query_type query_type)
+{
+ switch (type) {
+ case SYSTEM_TIME_UNSPECIFIED:
+ break;
+ case SYSTEM_TIME_AS_OF:
+ start.print(str, query_type, STRING_WITH_LEN(" FOR SYSTEM_TIME AS OF "));
+ break;
+ case SYSTEM_TIME_FROM_TO:
+ start.print(str, query_type, STRING_WITH_LEN(" FOR SYSTEM_TIME FROM "));
+ end.print(str, query_type, STRING_WITH_LEN(" TO "));
+ break;
+ case SYSTEM_TIME_BETWEEN:
+ start.print(str, query_type, STRING_WITH_LEN(" FOR SYSTEM_TIME BETWEEN "));
+ end.print(str, query_type, STRING_WITH_LEN(" AND "));
+ break;
+ case SYSTEM_TIME_BEFORE:
+ DBUG_ASSERT(0);
+ break;
+ case SYSTEM_TIME_ALL:
+ str->append(" FOR SYSTEM_TIME ALL");
+ break;
+ }
+}
+
+int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr)
+{
+ DBUG_ENTER("SELECT_LEX::vers_setup_cond");
+#define newx new (thd->mem_root)
+
+ TABLE_LIST *table;
+
+ if (!thd->stmt_arena->is_conventional() &&
+ !thd->stmt_arena->is_stmt_prepare() && !thd->stmt_arena->is_sp_execute())
+ {
+ // statement is already prepared
+ DBUG_RETURN(0);
+ }
+
+ if (thd->lex->is_view_context_analysis())
+ DBUG_RETURN(0);
+
+ if (!versioned_tables)
+ {
+ for (table= tables; table; table= table->next_local)
+ {
+ if (table->table && table->table->versioned())
+ versioned_tables++;
+ else if (table->vers_conditions.user_defined() &&
+ (table->is_non_derived() || !table->vers_conditions.used))
+ {
+ my_error(ER_VERS_NOT_VERSIONED, MYF(0), table->alias.str);
+ DBUG_RETURN(-1);
+ }
+ }
+ }
+
+ if (versioned_tables == 0)
+ DBUG_RETURN(0);
+
+ /* For prepared statements we create items on statement arena,
+ because they must outlive execution phase for multiple executions. */
+ Query_arena_stmt on_stmt_arena(thd);
+
+ // find outer system_time
+ SELECT_LEX *outer_slex= outer_select();
+ TABLE_LIST* outer_table= NULL;
+
+ if (outer_slex)
+ {
+ TABLE_LIST* derived= master_unit()->derived;
+ // inner SELECT may not be a derived table (derived == NULL)
+ while (derived && outer_slex && !derived->vers_conditions)
+ {
+ derived= outer_slex->master_unit()->derived;
+ outer_slex= outer_slex->outer_select();
+ }
+ if (derived && outer_slex)
+ {
+ DBUG_ASSERT(derived->vers_conditions);
+ outer_table= derived;
+ }
+ }
+
+ COND** dst_cond= where_expr;
+ COND* vers_cond= NULL;
+
+ for (table= tables; table; table= table->next_local)
+ {
+ if (!table->table || !table->table->versioned())
+ continue;
+
+ vers_select_conds_t &vers_conditions= table->vers_conditions;
+
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ /*
+ if the history is stored in partitions, then partitions
+ themselves are not versioned
+ */
+ if (table->partition_names && table->table->part_info->vers_info)
+ {
+ if (vers_conditions)
+ {
+#define PART_VERS_ERR_MSG "%s PARTITION (%s)"
+ char buf[NAME_LEN*2 + sizeof(PART_VERS_ERR_MSG)];
+ my_snprintf(buf, sizeof(buf), PART_VERS_ERR_MSG, table->alias.str,
+ table->partition_names->head()->c_ptr());
+ my_error(ER_VERS_NOT_VERSIONED, MYF(0), buf);
+ DBUG_RETURN(-1);
+ }
+ else
+ vers_conditions.init(SYSTEM_TIME_ALL);
+ }
+#endif
+
+ if (outer_table && !vers_conditions)
+ {
+ // propagate system_time from nearest outer SELECT_LEX
+ vers_conditions= outer_table->vers_conditions;
+ outer_table->vers_conditions.used= true;
+ }
+
+ // propagate system_time from sysvar
+ if (!vers_conditions)
+ {
+ if (vers_conditions.init_from_sysvar(thd))
+ DBUG_RETURN(-1);
+ }
+
+ if (vers_conditions)
+ {
+ if (vers_conditions == SYSTEM_TIME_ALL)
+ continue;
+
+ lock_type= TL_READ; // ignore TL_WRITE, history is immutable anyway
+ }
+
+ if (table->on_expr)
+ {
+ dst_cond= &table->on_expr;
+ }
+
+ const LEX_CSTRING *fstart= &table->table->vers_start_field()->field_name;
+ const LEX_CSTRING *fend= &table->table->vers_end_field()->field_name;
+
+ Item *row_start=
+ newx Item_field(thd, &this->context, table->db.str, table->alias.str, fstart);
+ Item *row_end=
+ newx Item_field(thd, &this->context, table->db.str, table->alias.str, fend);
+
+ bool timestamps_only= table->table->versioned(VERS_TIMESTAMP);
+
+ if (vers_conditions)
+ {
+ /* TODO: do resolve fix_length_and_dec(), fix_fields(). This requires
+ storing vers_conditions as Item and make some magic related to
+ vers_system_time_t/VERS_TRX_ID at stage of fix_fields()
+ (this is large refactoring). */
+ vers_conditions.resolve_units(timestamps_only);
+ if (timestamps_only && (vers_conditions.start.unit == VERS_TRX_ID ||
+ vers_conditions.end.unit == VERS_TRX_ID))
+ {
+ my_error(ER_VERS_ENGINE_UNSUPPORTED, MYF(0), table->table_name.str);
+ DBUG_RETURN(-1);
+ }
+ }
+
+ Item *cond1= 0, *cond2= 0, *curr= 0;
+ // Temporary tables of can be created from INNODB tables and thus will
+ // have uint64 type of sys_trx_(start|end) field.
+ // They need special handling.
+ TABLE *t= table->table;
+ if (t->versioned(VERS_TIMESTAMP))
+ {
+ MYSQL_TIME max_time;
+ switch (vers_conditions.type)
+ {
+ case SYSTEM_TIME_UNSPECIFIED:
+ thd->variables.time_zone->gmt_sec_to_TIME(&max_time, TIMESTAMP_MAX_VALUE);
+ max_time.second_part= TIME_MAX_SECOND_PART;
+ curr= newx Item_datetime_literal(thd, &max_time, TIME_SECOND_PART_DIGITS);
+ cond1= newx Item_func_eq(thd, row_end, curr);
+ cond1= or_items(thd, cond1, newx Item_func_isnull(thd, row_end));
+ break;
+ case SYSTEM_TIME_AS_OF:
+ cond1= newx Item_func_le(thd, row_start, vers_conditions.start.item);
+ cond2= newx Item_func_gt(thd, row_end, vers_conditions.start.item);
+ break;
+ case SYSTEM_TIME_FROM_TO:
+ cond1= newx Item_func_lt(thd, row_start, vers_conditions.end.item);
+ cond2= newx Item_func_ge(thd, row_end, vers_conditions.start.item);
+ break;
+ case SYSTEM_TIME_BETWEEN:
+ cond1= newx Item_func_le(thd, row_start, vers_conditions.end.item);
+ cond2= newx Item_func_ge(thd, row_end, vers_conditions.start.item);
+ break;
+ case SYSTEM_TIME_BEFORE:
+ cond1= newx Item_func_lt(thd, row_end, vers_conditions.start.item);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+ }
+ else
+ {
+ DBUG_ASSERT(table->table->s && table->table->s->db_plugin);
+
+ Item *trx_id0, *trx_id1;
+
+ switch (vers_conditions.type)
+ {
+ case SYSTEM_TIME_UNSPECIFIED:
+ curr= newx Item_int(thd, ULONGLONG_MAX);
+ cond1= newx Item_func_eq(thd, row_end, curr);
+ break;
+ case SYSTEM_TIME_AS_OF:
+ trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP
+ ? newx Item_func_vtq_id(thd, vers_conditions.start.item, TR_table::FLD_TRX_ID)
+ : vers_conditions.start.item;
+ cond1= newx Item_func_vtq_trx_sees_eq(thd, trx_id0, row_start);
+ cond2= newx Item_func_vtq_trx_sees(thd, row_end, trx_id0);
+ break;
+ case SYSTEM_TIME_FROM_TO:
+ case SYSTEM_TIME_BETWEEN:
+ trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP
+ ? newx Item_func_vtq_id(thd, vers_conditions.start.item, TR_table::FLD_TRX_ID, true)
+ : vers_conditions.start.item;
+ trx_id1= vers_conditions.end.unit == VERS_TIMESTAMP
+ ? newx Item_func_vtq_id(thd, vers_conditions.end.item, TR_table::FLD_TRX_ID, false)
+ : vers_conditions.end.item;
+ cond1= vers_conditions.type == SYSTEM_TIME_FROM_TO
+ ? newx Item_func_vtq_trx_sees(thd, trx_id1, row_start)
+ : newx Item_func_vtq_trx_sees_eq(thd, trx_id1, row_start);
+ cond2= newx Item_func_vtq_trx_sees_eq(thd, row_end, trx_id0);
+ break;
+ case SYSTEM_TIME_BEFORE:
+ trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP
+ ? newx Item_func_vtq_id(thd, vers_conditions.start.item, TR_table::FLD_TRX_ID)
+ : vers_conditions.start.item;
+ cond1= newx Item_func_lt(thd, row_end, trx_id0);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+ }
+ vers_conditions.type= SYSTEM_TIME_ALL;
+
+ if (cond1)
+ {
+ vers_cond= and_items(thd,
+ vers_cond,
+ and_items(thd,
+ cond2,
+ cond1));
+ if (table->is_view_or_derived())
+ vers_cond= or_items(thd, vers_cond, newx Item_func_isnull(thd, row_end));
+ }
+ } // for (table= tables; ...)
+
+ if (vers_cond)
+ {
+ COND *all_cond= and_items(thd, *dst_cond, vers_cond);
+ bool from_where= dst_cond == where_expr;
+ if (on_stmt_arena.arena_replaced())
+ *dst_cond= all_cond;
+ else
+ thd->change_item_tree(dst_cond, all_cond);
+
+ if (from_where)
+ {
+ this->where= *dst_cond;
+ this->where->top_level_item();
+ }
+
+ // Invalidate current SP [#52, #422]
+ if (thd->spcont)
+ {
+ DBUG_ASSERT(thd->spcont->m_sp);
+ thd->spcont->m_sp->set_sp_cache_version(0);
+ }
+ }
+
+ DBUG_RETURN(0);
+#undef newx
+}
+
/*****************************************************************************
Check fields, find best join, do the select and output fields.
mysql_select assumes that all tables are already opened
@@ -712,6 +1022,9 @@ JOIN::prepare(TABLE_LIST *tables_init,
join_list= &select_lex->top_join_list;
union_part= unit_arg->is_unit_op();
+ // simple check that we got usable conds
+ dbug_print_item(conds);
+
if (select_lex->handle_derived(thd->lex, DT_PREPARE))
DBUG_RETURN(-1);
@@ -744,11 +1057,15 @@ JOIN::prepare(TABLE_LIST *tables_init,
{
remove_redundant_subquery_clauses(select_lex);
}
-
+
+ /* System Versioning: handle FOR SYSTEM_TIME clause. */
+ if (select_lex->vers_setup_conds(thd, tables_list, &conds) < 0)
+ DBUG_RETURN(-1);
+
/*
TRUE if the SELECT list mixes elements with and without grouping,
and there is no GROUP BY clause. Mixing non-aggregated fields with
- aggregate functions in the SELECT list is a MySQL exptenstion that
+ aggregate functions in the SELECT list is a MySQL extenstion that
is allowed only if the ONLY_FULL_GROUP_BY sql mode is not set.
*/
mixed_implicit_grouping= false;
@@ -827,9 +1144,15 @@ JOIN::prepare(TABLE_LIST *tables_init,
{
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
thd->lex->allow_sum_func|= (nesting_map)1 << select_lex->nest_level;
- if (setup_order(thd, ref_ptrs, tables_list, fields_list,
- all_fields, select_lex->order_list.first))
- DBUG_RETURN(-1);
+ thd->where= "order clause";
+ for (ORDER *order= select_lex->order_list.first; order; order= order->next)
+ {
+ /* Don't add the order items to all fields. Just resolve them to ensure
+ the query is valid, we'll drop them immediately after. */
+ if (find_order_in_list(thd, ref_ptrs, tables_list, order,
+ fields_list, all_fields, false, false, false))
+ DBUG_RETURN(-1);
+ }
thd->lex->allow_sum_func= save_allow_sum_func;
select_lex->order_list.empty();
}
@@ -864,6 +1187,22 @@ JOIN::prepare(TABLE_LIST *tables_init,
}
}
+ /*
+ After setting up window functions, we may have discovered additional
+ used tables from the PARTITION BY and ORDER BY list. Update all items
+ that contain window functions.
+ */
+ if (select_lex->have_window_funcs())
+ {
+ List_iterator_fast<Item> it(select_lex->item_list);
+ Item *item;
+ while ((item= it++))
+ {
+ if (item->with_window_func)
+ item->update_used_tables();
+ }
+ }
+
With_clause *with_clause=select_lex->get_with_clause();
if (with_clause && with_clause->prepare_unreferenced_elements(thd))
DBUG_RETURN(1);
@@ -1125,7 +1464,6 @@ int JOIN::optimize()
if (optimization_state != JOIN::NOT_OPTIMIZED)
return FALSE;
optimization_state= JOIN::OPTIMIZATION_IN_PROGRESS;
- is_for_splittable_grouping_derived= false;
res= optimize_inner();
}
if (!with_two_phase_optimization ||
@@ -1197,7 +1535,7 @@ JOIN::optimize_inner()
/*
Needed in case optimizer short-cuts,
- set properly in make_tmp_tables_info()
+ set properly in make_aggr_tables_info()
*/
fields= &select_lex->item_list;
@@ -1571,9 +1909,6 @@ int JOIN::optimize_stage2()
if (subq_exit_fl)
goto setup_subq_exit;
- if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE))
- DBUG_RETURN(1);
-
if (thd->check_killed())
DBUG_RETURN(1);
@@ -1581,6 +1916,9 @@ int JOIN::optimize_stage2()
if (get_best_combination())
DBUG_RETURN(1);
+ if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE))
+ DBUG_RETURN(1);
+
if (optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_WITH_KEYS))
drop_unused_derived_keys();
@@ -2403,20 +2741,22 @@ bool JOIN::make_aggr_tables_info()
/*
All optimization is done. Check if we can use the storage engines
- group by handler to evaluate the group by
+ group by handler to evaluate the group by.
+ Some storage engines, like spider can also do joins, group by and
+ distinct in the engine, so we do this for all queries, not only
+ GROUP BY queries.
*/
- if (tables_list && (tmp_table_param.sum_func_count || group_list) &&
- !procedure)
+ if (tables_list && !procedure)
{
/*
At the moment we only support push down for queries where
all tables are in the same storage engine
*/
TABLE_LIST *tbl= tables_list;
- handlerton *ht= tbl && tbl->table ? tbl->table->file->ht : 0;
+ handlerton *ht= tbl && tbl->table ? tbl->table->file->partition_ht() : 0;
for (tbl= tbl->next_local; ht && tbl; tbl= tbl->next_local)
{
- if (!tbl->table || tbl->table->file->ht != ht)
+ if (!tbl->table || tbl->table->file->partition_ht() != ht)
ht= 0;
}
@@ -2453,7 +2793,7 @@ bool JOIN::make_aggr_tables_info()
all_fields,
NULL, query.distinct,
TRUE, select_options, HA_POS_ERROR,
- "", !need_tmp,
+ &empty_clex_str, !need_tmp,
query.order_by || query.group_by);
if (!table)
DBUG_RETURN(1);
@@ -2737,7 +3077,15 @@ bool JOIN::make_aggr_tables_info()
curr_tab->having= having;
having->update_used_tables();
}
- curr_tab->distinct= true;
+ /*
+ We only need DISTINCT operation if the join is not degenerate.
+ If it is, we must not request DISTINCT processing, because
+ remove_duplicates() assumes there is a preceding computation step (and
+ in the degenerate join, there's none)
+ */
+ if (top_join_tab_count)
+ curr_tab->distinct= true;
+
having= NULL;
select_distinct= false;
}
@@ -2948,7 +3296,7 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields,
TABLE* table= create_tmp_table(thd, tab->tmp_table_param, *table_fields,
table_group, distinct,
save_sum_fields, select_options, table_rows_limit,
- "", true, keep_row_order);
+ &empty_clex_str, true, keep_row_order);
if (!table)
DBUG_RETURN(true);
tmp_table_param.using_outer_summary_function=
@@ -2970,6 +3318,7 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields,
THD_STAGE_INFO(thd, stage_sorting_for_group);
if (ordered_index_usage != ordered_index_group_by &&
+ !only_const_tables() &&
(join_tab + const_tables)->type != JT_CONST && // Don't sort 1 row
!implicit_grouping &&
add_sorting_to_table(join_tab + const_tables, group_list))
@@ -3003,6 +3352,7 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields,
THD_STAGE_INFO(thd, stage_sorting_for_order);
if (ordered_index_usage != ordered_index_order_by &&
+ !only_const_tables() &&
add_sorting_to_table(join_tab + const_tables, order))
goto err;
order= NULL;
@@ -3213,8 +3563,11 @@ bool JOIN::shrink_join_buffers(JOIN_TAB *jt,
ulonglong curr_space,
ulonglong needed_space)
{
+ JOIN_TAB *tab;
JOIN_CACHE *cache;
- for (JOIN_TAB *tab= join_tab+const_tables; tab < jt; tab++)
+ for (tab= first_linear_tab(this, WITHOUT_BUSH_ROOTS, WITHOUT_CONST_TABLES);
+ tab != jt;
+ tab= next_linear_tab(this, tab, WITHOUT_BUSH_ROOTS))
{
cache= tab->cache;
if (cache)
@@ -3359,6 +3712,17 @@ bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
bool need_tmp_table, bool need_order,
bool distinct)
{
+ /*
+ If there is SELECT in this statemet with the same number it must be the
+ same SELECT
+ */
+ DBUG_ASSERT(select_lex->select_number == UINT_MAX ||
+ select_lex->select_number == INT_MAX ||
+ !output ||
+ !output->get_select(select_lex->select_number) ||
+ output->get_select(select_lex->select_number)->select_lex ==
+ select_lex);
+
if (select_lex->select_number != UINT_MAX &&
select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ &&
have_query_plan != JOIN::QEP_NOT_PRESENT_YET &&
@@ -3619,6 +3983,7 @@ void JOIN::exec_inner()
result->send_result_set_metadata(
procedure ? procedure_fields_list : *fields,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
+
error= do_select(this, procedure);
/* Accumulate the counts from all join iterations of all join parts. */
thd->inc_examined_row_count(join_examined_rows);
@@ -3668,7 +4033,11 @@ JOIN::destroy()
cleanup_item_list(tmp_all_fields1);
cleanup_item_list(tmp_all_fields3);
destroy_sj_tmp_tables(this);
- delete_dynamic(&keyuse);
+ delete_dynamic(&keyuse);
+ if (save_qep)
+ delete(save_qep);
+ if (ext_keyuses_for_splitting)
+ delete(ext_keyuses_for_splitting);
delete procedure;
DBUG_RETURN(error);
}
@@ -3826,7 +4195,7 @@ err:
if (free_join)
{
THD_STAGE_INFO(thd, stage_end);
- err|= select_lex->cleanup();
+ err|= (int)(select_lex->cleanup());
DBUG_RETURN(err || thd->is_error());
}
DBUG_RETURN(join->error ? join->error: err);
@@ -4198,6 +4567,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
keyuse->val->is_null() && keyuse->null_rejecting)
{
s->type= JT_CONST;
+ s->table->const_table= 1;
mark_as_null_row(table);
found_const_table_map|= table->map;
join->const_table_map|= table->map;
@@ -4303,6 +4673,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
s->type= JT_CONST;
join->const_table_map|=table->map;
set_position(join,const_count++,s,start_keyuse);
+ /* create_ref_for_key will set s->table->const_table */
if (create_ref_for_key(join, s, start_keyuse, FALSE,
found_const_table_map))
goto error;
@@ -4426,6 +4797,9 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
s->scan_time();
}
+ if (s->table->is_splittable())
+ s->add_keyuses_for_splitting();
+
/*
Set a max range of how many seeks we can expect when using keys
This is can't be to high as otherwise we are likely to use
@@ -4508,12 +4882,12 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
join->const_table_map|= s->table->map;
set_position(join,const_count++,s,(KEYUSE*) 0);
s->type= JT_CONST;
+ s->table->const_table= 1;
if (*s->on_expr_ref)
{
/* Generate empty row */
s->info= ET_IMPOSSIBLE_ON_CONDITION;
found_const_table_map|= s->table->map;
- s->type= JT_CONST;
mark_as_null_row(s->table); // All fields are NULL
}
}
@@ -4593,9 +4967,6 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
if (join->choose_subquery_plan(all_table_map & ~join->const_table_map))
goto error;
- if (join->improve_chosen_plan(join->thd))
- goto error;
-
DEBUG_SYNC(join->thd, "inside_make_join_statistics");
DBUG_RETURN(0);
@@ -4625,23 +4996,6 @@ error:
keyuse Pointer to possible keys
*****************************************************************************/
-/// Used when finding key fields
-struct KEY_FIELD {
- Field *field;
- Item_bool_func *cond;
- Item *val; ///< May be empty if diff constant
- uint level;
- uint optimize;
- bool eq_func;
- /**
- If true, the condition this struct represents will not be satisfied
- when val IS NULL.
- */
- bool null_rejecting;
- bool *cond_guard; /* See KEYUSE::cond_guard */
- uint sj_pred_no; /* See KEYUSE::sj_pred_no */
-};
-
/**
Merge new key definitions to old ones, remove those not used in both.
@@ -5292,7 +5646,7 @@ Item_func_ne::add_key_fields(JOIN *join, KEY_FIELD **key_fields,
/*
QQ: perhaps test for !is_local_field(args[1]) is not really needed here.
Other comparison functions, e.g. Item_func_le, Item_func_gt, etc,
- do not have this test. See Item_bool_func2::add_key_field_optimize_op().
+ do not have this test. See Item_bool_func2::add_key_fieldoptimize_op().
Check with the optimizer team.
*/
if (is_local_field(args[0]) && !is_local_field(args[1]))
@@ -5475,6 +5829,7 @@ add_keyuse(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field,
keyuse.null_rejecting= key_field->null_rejecting;
keyuse.cond_guard= key_field->cond_guard;
keyuse.sj_pred_no= key_field->sj_pred_no;
+ keyuse.validity_ref= 0;
return (insert_dynamic(keyuse_array,(uchar*) &keyuse));
}
@@ -5520,7 +5875,9 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field)
key_field->val->used_tables())
{
if (!field->can_optimize_hash_join(key_field->cond, key_field->val))
- return false;
+ return false;
+ if (form->is_splittable())
+ form->add_splitting_info_for_key_field(key_field);
/*
If a key use is extracted from an equi-join predicate then it is
added not only as a key use for every index whose component can
@@ -5534,7 +5891,6 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field)
return FALSE;
}
-
static bool
add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
JOIN_TAB *stat,COND *cond,table_map usable_tables)
@@ -5596,6 +5952,7 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
keyuse.optimize= 0;
keyuse.keypart_map= 0;
keyuse.sj_pred_no= UINT_MAX;
+ keyuse.validity_ref= 0;
return insert_dynamic(keyuse_array,(uchar*) &keyuse);
}
@@ -5883,8 +6240,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
Special treatment for ft-keys.
*/
-static bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
- bool skip_unprefixed_keyparts)
+bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
+ bool skip_unprefixed_keyparts)
{
KEYUSE key_end, *prev, *save_pos, *use;
uint found_eq_constant, i;
@@ -5952,7 +6309,7 @@ static bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
Update some values in keyuse for faster choose_plan() loop.
*/
-static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
+void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
{
KEYUSE *end,*keyuse= dynamic_element(keyuse_array, 0, KEYUSE*);
@@ -5993,7 +6350,6 @@ static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
}
-
/**
Check for the presence of AGGFN(DISTINCT a) queries that may be subject
to loose index scan.
@@ -6301,6 +6657,7 @@ best_access_path(JOIN *join,
bool best_uses_jbuf= FALSE;
MY_BITMAP *eq_join_set= &s->table->eq_join_set;
KEYUSE *hj_start_key= 0;
+ SplM_plan_info *spl_plan= 0;
disable_jbuf= disable_jbuf || idx == join->const_tables;
@@ -6310,7 +6667,10 @@ best_access_path(JOIN *join,
bitmap_clear_all(eq_join_set);
loose_scan_opt.init(join, s, remaining_tables);
-
+
+ if (s->table->is_splittable())
+ spl_plan= s->choose_best_splitting(record_count, remaining_tables);
+
if (s->keyuse)
{ /* Use key if possible */
KEYUSE *keyuse;
@@ -6375,6 +6735,7 @@ best_access_path(JOIN *join,
2. we won't get two ref-or-null's
*/
if (!(remaining_tables & keyuse->used_tables) &&
+ (!keyuse->validity_ref || *keyuse->validity_ref) &&
s->access_from_tables_is_allowed(keyuse->used_tables,
join->sjm_lookup_tables) &&
!(ref_or_null_part && (keyuse->optimize &
@@ -6687,6 +7048,7 @@ best_access_path(JOIN *join,
tmp += s->startup_cost;
loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp);
} /* not ft_key */
+
if (tmp + 0.0001 < best_time - records/(double) TIME_FOR_COMPARE)
{
best_time= tmp + records/(double) TIME_FOR_COMPARE;
@@ -6874,6 +7236,7 @@ best_access_path(JOIN *join,
pos->ref_depend_map= best_ref_depends_map;
pos->loosescan_picker.loosescan_key= MAX_KEY;
pos->use_join_buffer= best_uses_jbuf;
+ pos->spl_plan= spl_plan;
loose_scan_opt.save_to_position(s, loose_scan_pos);
@@ -8928,192 +9291,15 @@ JOIN_TAB *next_depth_first_tab(JOIN* join, JOIN_TAB* tab)
return tab;
}
-static
-bool key_can_be_used_to_split_by_fields(KEY *key_info, uint used_key_parts,
- List<Field> &fields)
-{
- if (used_key_parts < fields.elements)
- return false;
- List_iterator_fast<Field> li(fields);
- Field *fld;
- KEY_PART_INFO *start= key_info->key_part;
- KEY_PART_INFO *end= start + fields.elements;
- while ((fld= li++))
- {
- KEY_PART_INFO *key_part;
- for (key_part= start; key_part < end; key_part++)
- {
- if (key_part->fieldnr == fld->field_index + 1)
- break;
- }
- if (key_part == end)
- return false;
- }
- return true;
-}
-
-bool JOIN::check_for_splittable_grouping_derived(THD *thd)
-{
- partition_list= 0;
- st_select_lex_unit *unit= select_lex->master_unit();
- TABLE_LIST *derived= unit->derived;
- if (!optimizer_flag(thd, OPTIMIZER_SWITCH_SPLIT_GROUPING_DERIVED))
- return false;
- if (!(derived && derived->is_materialized_derived()))
- return false;
- if (unit->first_select()->next_select())
- return false;
- if (derived->prohibit_cond_pushdown)
- return false;
- if (derived->is_recursive_with_table())
- return false;
- if (group_list)
- {
- if (!select_lex->have_window_funcs())
- partition_list= group_list;
- }
- else if (select_lex->have_window_funcs() &&
- select_lex->window_specs.elements == 1)
- {
- partition_list=
- select_lex->window_specs.head()->partition_list->first;
- }
- if (!partition_list)
- return false;
-
- ORDER *ord;
- TABLE *table= 0;
- key_map ref_keys;
- uint group_fields= 0;
- ref_keys.set_all();
- for (ord= partition_list; ord; ord= ord->next, group_fields++)
- {
- Item *ord_item= *ord->item;
- if (ord_item->real_item()->type() != Item::FIELD_ITEM)
- return false;
- Field *ord_field= ((Item_field *) (ord_item->real_item()))->field;
- if (!table)
- table= ord_field->table;
- else if (table != ord_field->table)
- return false;
- ref_keys.intersect(ord_field->part_of_key);
- }
- if (ref_keys.is_clear_all())
- return false;
-
- uint i;
- List<Field> grouping_fields;
- List<Field> splitting_fields;
- List_iterator<Item> li(fields_list);
- for (ord= partition_list; ord; ord= ord->next)
- {
- Item *item;
- i= 0;
- while ((item= li++))
- {
- if ((*ord->item)->eq(item, 0))
- break;
- i++;
- }
- if (!item)
- return false;
- if (splitting_fields.push_back(derived->table->field[i], thd->mem_root))
- return false;
- Item_field *ord_field= (Item_field *)(item->real_item());
- if (grouping_fields.push_back(ord_field->field, thd->mem_root))
- return false;
- li.rewind();
- }
-
- for (i= 0; i < table->s->keys; i++)
- {
- if (!(ref_keys.is_set(i)))
- continue;
- KEY *key_info= table->key_info + i;
- if (key_can_be_used_to_split_by_fields(key_info,
- table->actual_n_key_parts(key_info),
- grouping_fields))
- break;
- }
- if (i == table->s->keys)
- return false;
-
- derived->table->splitting_fields= splitting_fields;
- is_for_splittable_grouping_derived= true;
- return true;
-}
-
bool JOIN::check_two_phase_optimization(THD *thd)
{
- if (!check_for_splittable_grouping_derived(thd))
- return false;
- return true;
+ if (check_for_splittable_materialized())
+ return true;
+ return false;
}
-Item *JOIN_TAB::get_splitting_cond_for_grouping_derived(THD *thd)
-{
- /* this is a stub */
- TABLE_LIST *derived= table->pos_in_table_list;
- st_select_lex *sel= derived->get_unit()->first_select();
- Item *cond= 0;
- table_map used_tables= OUTER_REF_TABLE_BIT;
- POSITION *pos= join->best_positions;
- for (; pos->table != this; pos++)
- {
- used_tables|= pos->table->table->map;
- }
-
- if (!pos->key)
- return 0;
-
- KEY *key_info= table->key_info + pos->key->key;
- if (!key_can_be_used_to_split_by_fields(key_info,
- key_info->user_defined_key_parts,
- table->splitting_fields))
- return 0;
-
- create_ref_for_key(join, this, pos->key,
- false, used_tables);
- List<Item> cond_list;
- KEY_PART_INFO *start= key_info->key_part;
- KEY_PART_INFO *end= start + table->splitting_fields.elements;
- List_iterator_fast<Field> li(table->splitting_fields);
- Field *fld= li++;
- for (ORDER *ord= sel->join->partition_list; ord;
- ord= ord->next, fld= li++)
- {
- Item *left_item= (*ord->item)->build_clone(thd, thd->mem_root);
- uint i= 0;
- for (KEY_PART_INFO *key_part= start; key_part < end; key_part++, i++)
- {
- if (key_part->fieldnr == fld->field_index + 1)
- break;
- }
- Item *right_item= ref.items[i]->build_clone(thd, thd->mem_root);
- Item_func_eq *eq_item= 0;
- right_item= right_item->build_clone(thd, thd->mem_root);
- if (left_item && right_item)
- {
- right_item->walk(&Item::set_fields_as_dependent_processor,
- false, join->select_lex);
- right_item->update_used_tables();
- eq_item= new (thd->mem_root) Item_func_eq(thd, left_item, right_item);
- }
- if (!eq_item || cond_list.push_back(eq_item, thd->mem_root))
- return 0;
- }
- switch (cond_list.elements) {
- case 0: break;
- case 1: cond= cond_list.head(); break;
- default: cond= new (thd->mem_root) Item_cond_and(thd, cond_list);
- }
- if (cond)
- cond->fix_fields(thd,0);
- return cond;
-}
-
bool JOIN::inject_cond_into_where(Item *injected_cond)
{
Item *where_item= injected_cond;
@@ -9148,48 +9334,6 @@ bool JOIN::inject_cond_into_where(Item *injected_cond)
}
-bool JOIN::push_splitting_cond_into_derived(THD *thd, Item *cond)
-{
- enum_reopt_result reopt_result= REOPT_NONE;
- table_map all_table_map= 0;
- for (JOIN_TAB *tab= join_tab;
- tab < join_tab + top_join_tab_count; tab++)
- all_table_map|= tab->table->map;
- reopt_result= reoptimize(cond, all_table_map & ~const_table_map, NULL);
- if (reopt_result == REOPT_ERROR)
- return true;
- if (inject_cond_into_where(cond))
- return true;
- if (cond->used_tables() & OUTER_REF_TABLE_BIT)
- {
- select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
- st_select_lex_unit *unit= select_lex->master_unit();
- unit->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
- }
- return false;
-}
-
-bool JOIN::improve_chosen_plan(THD *thd)
-{
- for (JOIN_TAB *tab= join_tab + const_tables;
- tab < join_tab + table_count; tab++)
- {
- TABLE_LIST *tbl= tab->table->pos_in_table_list;
- if (tbl->is_materialized_derived())
- {
- st_select_lex *sel= tbl->get_unit()->first_select();
- JOIN *derived_join= sel->join;
- if (derived_join && derived_join->is_for_splittable_grouping_derived)
- {
- Item *cond= tab->get_splitting_cond_for_grouping_derived(thd);
- if (cond && derived_join->push_splitting_cond_into_derived(thd, cond))
- return true;
- }
- }
- }
- return false;
-}
-
static Item * const null_ptr= NULL;
@@ -9258,6 +9402,9 @@ bool JOIN::get_best_combination()
full_join=0;
hash_join= FALSE;
+ if (fix_all_splittings_in_plan())
+ DBUG_RETURN(TRUE);
+
fix_semijoin_strategies_for_picked_join_order(this);
JOIN_TAB_RANGE *root_range;
@@ -9598,6 +9745,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
do
{
if (!(~used_tables & keyuse->used_tables) &&
+ (!keyuse->validity_ref || *keyuse->validity_ref) &&
j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse))
{
if (are_tables_local(j, keyuse->val->used_tables()))
@@ -9668,6 +9816,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
for (i=0 ; i < keyparts ; keyuse++,i++)
{
while (((~used_tables) & keyuse->used_tables) ||
+ (keyuse->validity_ref && !(*keyuse->validity_ref)) ||
!j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) ||
keyuse->keypart == NO_KEYPART ||
(keyuse->keypart !=
@@ -10900,7 +11049,7 @@ void JOIN::drop_unused_derived_keys()
tmp_tbl->use_index(tab->ref.key);
if (tmp_tbl->s->keys)
{
- if (tab->ref.key >= 0)
+ if (tab->ref.key >= 0 && tab->ref.key < MAX_KEY)
tab->ref.key= 0;
else
tmp_tbl->s->keys= 0;
@@ -12265,7 +12414,8 @@ bool JOIN_TAB::preread_init()
derived, DT_CREATE | DT_FILL))
return TRUE;
- if (!(derived->get_unit()->uncacheable & UNCACHEABLE_DEPENDENT))
+ if (!(derived->get_unit()->uncacheable & UNCACHEABLE_DEPENDENT) ||
+ derived->is_nonrecursive_derived_with_rec_ref())
preread_init_done= TRUE;
if (select && select->quick)
select->quick->replace_handler(table->file);
@@ -12725,8 +12875,8 @@ static void update_depend_map(JOIN *join)
uint i;
for (i=0 ; i < ref->key_parts ; i++,item++)
depend_map|=(*item)->used_tables();
- ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
depend_map&= ~OUTER_REF_TABLE_BIT;
+ ref->depend_map= depend_map;
for (JOIN_TAB **tab=join->map2table;
depend_map ;
tab++,depend_map>>=1 )
@@ -12857,7 +13007,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
*simple_order=0; // Must do a temp table to sort
else if (!(order_tables & not_const_tables))
{
- if (order->item[0]->has_subquery())
+ if (order->item[0]->with_subquery())
{
/*
Delay the evaluation of constant ORDER and/or GROUP expressions that
@@ -12895,8 +13045,37 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
can be used without tmp. table.
*/
bool can_subst_to_first_table= false;
+ bool first_is_in_sjm_nest= false;
+ if (first_is_base_table)
+ {
+ TABLE_LIST *tbl_for_first=
+ join->join_tab[join->const_tables].table->pos_in_table_list;
+ first_is_in_sjm_nest= tbl_for_first->sj_mat_info &&
+ tbl_for_first->sj_mat_info->is_used;
+ }
+ /*
+ Currently we do not employ the optimization that uses multiple
+ equalities for ORDER BY to remove tmp table in the case when
+ the first table happens to be the result of materialization of
+ a semi-join nest ( <=> first_is_in_sjm_nest == true).
+
+ When a semi-join nest is materialized and scanned to look for
+ possible matches in the remaining tables for every its row
+ the fields from the result of materialization are copied
+ into the record buffers of tables from the semi-join nest.
+ So these copies are used to access the remaining tables rather
+ than the fields from the result of materialization.
+
+ Unfortunately now this so-called 'copy back' technique is
+ supported only if the rows are scanned with the rr_sequential
+ function, but not with other rr_* functions that are employed
+ when the result of materialization is required to be sorted.
+
+ TODO: either to support 'copy back' technique for the above case,
+ or to get rid of this technique altogether.
+ */
if (optimizer_flag(join->thd, OPTIMIZER_SWITCH_ORDERBY_EQ_PROP) &&
- first_is_base_table &&
+ first_is_base_table && !first_is_in_sjm_nest &&
order->item[0]->real_item()->type() == Item::FIELD_ITEM &&
join->cond_equal)
{
@@ -13101,7 +13280,9 @@ public:
}
static void operator delete(void *ptr __attribute__((unused)),
size_t size __attribute__((unused)))
- { TRASH(ptr, size); }
+ { TRASH_FREE(ptr, size); }
+
+ static void operator delete(void *, MEM_ROOT*) {}
Item *and_level;
Item_bool_func2 *cmp_func;
@@ -16081,9 +16262,10 @@ COND *
Item_func_isnull::remove_eq_conds(THD *thd, Item::cond_result *cond_value,
bool top_level_arg)
{
- if (args[0]->type() == Item::FIELD_ITEM)
+ Item *real_item= args[0]->real_item();
+ if (real_item->type() == Item::FIELD_ITEM)
{
- Field *field= ((Item_field*) args[0])->field;
+ Field *field= ((Item_field*) real_item)->field;
if (((field->type() == MYSQL_TYPE_DATE) ||
(field->type() == MYSQL_TYPE_DATETIME)) &&
@@ -16369,7 +16551,11 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field,
item->result_field= new_field;
else
new_field->field_name= *name;
- new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG);
+ new_field->flags|= (org_field->flags & (
+ NO_DEFAULT_VALUE_FLAG |
+ VERS_SYS_START_FLAG |
+ VERS_SYS_END_FLAG |
+ VERS_UPDATE_UNVERSIONED_FLAG));
if (org_field->maybe_null() || (item && item->maybe_null))
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
@@ -16629,6 +16815,10 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
modify_item ? field :
NULL);
}
+
+ if (field->field->vers_sys_field())
+ result->invisible= field->field->invisible;
+
if (orig_type == Item::REF_ITEM && orig_modify)
((Item_ref*)orig_item)->set_result_field(result);
/*
@@ -16779,7 +16969,7 @@ TABLE *
create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit,
- const char *table_alias, bool do_not_open,
+ const LEX_CSTRING *table_alias, bool do_not_open,
bool keep_row_order)
{
MEM_ROOT *mem_root_save, own_root;
@@ -16816,7 +17006,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
DBUG_ENTER("create_tmp_table");
DBUG_PRINT("enter",
("table_alias: '%s' distinct: %d save_sum_fields: %d "
- "rows_limit: %lu group: %d", table_alias,
+ "rows_limit: %lu group: %d", table_alias->str,
(int) distinct, (int) save_sum_fields,
(ulong) rows_limit, MY_TEST(group)));
@@ -16885,7 +17075,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
if (param->precomputed_group_by)
copy_func_count+= param->sum_func_count;
- init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
+ init_sql_alloc(&own_root, "tmp_table", TABLE_ALLOC_BLOCK_SIZE, 0,
+ MYF(MY_THREAD_SPECIFIC));
if (!multi_alloc_root(&own_root,
&table, sizeof(*table),
@@ -16932,7 +17123,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
thd->mem_root= &table->mem_root;
table->field=reg_field;
- table->alias.set(table_alias, strlen(table_alias), table_alias_charset);
+ table->alias.set(table_alias->str, table_alias->length, table_alias_charset);
table->reginfo.lock_type=TL_WRITE; /* Will be updated */
table->map=1;
@@ -17311,7 +17502,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
field->set_notnull();
memcpy(field->ptr,
orig_field->ptr_in_record(orig_field->table->s->default_values),
- field->pack_length());
+ field->pack_length_in_rec());
}
}
@@ -17627,7 +17818,6 @@ err:
}
-
/****************************************************************************/
void *Virtual_tmp_table::operator new(size_t size, THD *thd) throw()
@@ -17640,18 +17830,19 @@ bool Virtual_tmp_table::init(uint field_count)
{
uint *blob_field;
uchar *bitmaps;
+ DBUG_ENTER("Virtual_tmp_table::init");
if (!multi_alloc_root(in_use->mem_root,
&s, sizeof(*s),
&field, (field_count + 1) * sizeof(Field*),
&blob_field, (field_count + 1) * sizeof(uint),
&bitmaps, bitmap_buffer_size(field_count) * 6,
NullS))
- return true;
+ DBUG_RETURN(true);
bzero(s, sizeof(*s));
s->blob_field= blob_field;
setup_tmp_table_column_bitmaps(this, bitmaps, field_count);
m_alloced_field_count= field_count;
- return false;
+ DBUG_RETURN(false);
};
@@ -17660,17 +17851,18 @@ bool Virtual_tmp_table::add(List<Spvar_definition> &field_list)
/* Create all fields and calculate the total length of record */
Spvar_definition *cdef; /* column definition */
List_iterator_fast<Spvar_definition> it(field_list);
- for ( ; (cdef= it++); )
+ DBUG_ENTER("Virtual_tmp_table::add");
+ while ((cdef= it++))
{
Field *tmp;
if (!(tmp= cdef->make_field(s, in_use->mem_root, 0,
(uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
f_maybe_null(cdef->pack_flag) ? 1 : 0,
&cdef->field_name)))
- return true;
- add(tmp);
+ DBUG_RETURN(true);
+ add(tmp);
}
- return false;
+ DBUG_RETURN(false);
}
@@ -17735,6 +17927,70 @@ bool Virtual_tmp_table::open()
}
+bool Virtual_tmp_table::sp_find_field_by_name(uint *idx,
+ const LEX_CSTRING &name) const
+{
+ Field *f;
+ for (uint i= 0; (f= field[i]); i++)
+ {
+ // Use the same comparison style with sp_context::find_variable()
+ if (!my_strnncoll(system_charset_info,
+ (const uchar *) f->field_name.str,
+ f->field_name.length,
+ (const uchar *) name.str, name.length))
+ {
+ *idx= i;
+ return false;
+ }
+ }
+ return true;
+}
+
+
+bool
+Virtual_tmp_table::sp_find_field_by_name_or_error(uint *idx,
+ const LEX_CSTRING &var_name,
+ const LEX_CSTRING &field_name)
+ const
+{
+ if (sp_find_field_by_name(idx, field_name))
+ {
+ my_error(ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD, MYF(0),
+ var_name.str, field_name.str);
+ return true;
+ }
+ return false;
+}
+
+
+bool Virtual_tmp_table::sp_set_all_fields_from_item_list(THD *thd,
+ List<Item> &items)
+{
+ DBUG_ASSERT(s->fields == items.elements);
+ List_iterator<Item> it(items);
+ Item *item;
+ for (uint i= 0 ; (item= it++) ; i++)
+ {
+ if (field[i]->sp_prepare_and_store_item(thd, &item))
+ return true;
+ }
+ return false;
+}
+
+
+bool Virtual_tmp_table::sp_set_all_fields_from_item(THD *thd, Item *value)
+{
+ DBUG_ASSERT(value->fixed);
+ DBUG_ASSERT(value->cols() == s->fields);
+ for (uint i= 0; i < value->cols(); i++)
+ {
+ if (field[i]->sp_prepare_and_store_item(thd, value->addr(i)))
+ return true;
+ }
+ return false;
+}
+
+
bool open_tmp_table(TABLE *table)
{
int error;
@@ -18106,7 +18362,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
table->in_use->inc_status_created_tmp_disk_tables();
table->in_use->inc_status_created_tmp_tables();
share->db_record_offset= 1;
- table->created= TRUE;
+ table->set_created();
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
@@ -18292,6 +18548,12 @@ free_tmp_table(THD *thd, TABLE *entry)
plugin_unlock(0, entry->s->db_plugin);
entry->alias.free();
+ if (entry->pos_in_table_list && entry->pos_in_table_list->table)
+ {
+ DBUG_ASSERT(entry->pos_in_table_list->table == entry);
+ entry->pos_in_table_list->table= NULL;
+ }
+
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
thd_proc_info(thd, save_proc_info);
@@ -18611,8 +18873,8 @@ int rr_sequential_and_unpack(READ_RECORD *info)
*/
bool instantiate_tmp_table(TABLE *table, KEY *keyinfo,
- MARIA_COLUMNDEF *start_recinfo,
- MARIA_COLUMNDEF **recinfo,
+ TMP_ENGINE_COLUMNDEF *start_recinfo,
+ TMP_ENGINE_COLUMNDEF **recinfo,
ulonglong options)
{
if (table->s->db_type() == TMP_ENGINE_HTON)
@@ -19504,6 +19766,7 @@ join_read_system(JOIN_TAB *tab)
{
if (error != HA_ERR_END_OF_FILE)
return report_error(table, error);
+ table->const_table= 1;
mark_as_null_row(tab->table);
empty_record(table); // Make empty record
return -1;
@@ -22112,7 +22375,7 @@ create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort)
table->file->ha_end_keyread();
if (tab->type == JT_FT)
- table->file->ft_end();
+ table->file->ha_ft_end();
else
table->file->ha_index_or_rnd_end();
@@ -22542,7 +22805,10 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
SELECT list)
@param[in,out] all_fields All select, group and order by fields
@param[in] is_group_field True if order is a GROUP field, false if
- ORDER by field
+ ORDER by field
+ @param[in] add_to_all_fields If the item is to be added to all_fields and
+ ref_pointer_array, this flag can be set to
+ false to stop the automatic insertion.
@param[in] from_window_spec If true then order is from a window spec
@retval
@@ -22552,9 +22818,11 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
*/
static bool
-find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
+find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array,
+ TABLE_LIST *tables,
ORDER *order, List<Item> &fields, List<Item> &all_fields,
- bool is_group_field, bool from_window_spec)
+ bool is_group_field, bool add_to_all_fields,
+ bool from_window_spec)
{
Item *order_item= *order->item; /* The item from the GROUP/ORDER caluse. */
Item::Type order_item_type;
@@ -22691,6 +22959,9 @@ find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables
thd->is_error()))
return TRUE; /* Wrong field. */
+ if (!add_to_all_fields)
+ return FALSE;
+
uint el= all_fields.elements;
/* Add new field to field list. */
all_fields.push_front(order_item, thd->mem_root);
@@ -22719,7 +22990,7 @@ find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables
*/
int setup_order(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
- List<Item> &fields, List<Item> &all_fields, ORDER *order,
+ List<Item> &fields, List<Item> &all_fields, ORDER *order,
bool from_window_spec)
{
enum_parsing_place context_analysis_place=
@@ -22728,7 +22999,7 @@ int setup_order(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
for (; order; order=order->next)
{
if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
- all_fields, FALSE, from_window_spec))
+ all_fields, false, true, from_window_spec))
return 1;
if ((*order->item)->with_window_func &&
context_analysis_place != IN_ORDER_BY)
@@ -22787,7 +23058,7 @@ setup_group(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
for (ord= order; ord; ord= ord->next)
{
if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
- all_fields, TRUE, from_window_spec))
+ all_fields, true, true, from_window_spec))
return 1;
(*ord->item)->marker= UNDEF_POS; /* Mark found */
if ((*ord->item)->with_sum_func && context_analysis_place == IN_GROUP_BY)
@@ -22884,7 +23155,7 @@ setup_new_fields(THD *thd, List<Item> &fields,
enum_resolution_type not_used;
DBUG_ENTER("setup_new_fields");
- thd->mark_used_columns= MARK_COLUMNS_READ; // Not really needed, but...
+ thd->column_usage= MARK_COLUMNS_READ; // Not really needed, but...
for (; new_field ; new_field= new_field->next)
{
if ((item= find_item_in_list(*new_field->item, fields, &counter,
@@ -23118,6 +23389,7 @@ get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables,
if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT)))
DBUG_RETURN(0);
+ map&= ~const_tables;
while ((table= ti++) && !(map & table->table->map)) ;
if (map != table->table->map)
DBUG_RETURN(0); // More than one table
@@ -24639,7 +24911,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta,
if (table->derived_select_number)
{
/* Derived table name generation */
- int len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
+ size_t len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
"<derived%u>",
table->derived_select_number);
eta->table_name.copy(table_name_buffer, len, cs);
@@ -24648,7 +24920,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta,
{
JOIN_TAB *ctab= bush_children->start;
/* table */
- int len= my_snprintf(table_name_buffer,
+ size_t len= my_snprintf(table_name_buffer,
sizeof(table_name_buffer)-1,
"<subquery%d>",
ctab->emb_sj_nest->sj_subq_pred->get_identifier());
@@ -24677,7 +24949,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta,
}
}
}
- eta->table_name.copy(real_table->alias, strlen(real_table->alias), cs);
+ eta->table_name.copy(real_table->alias.str, real_table->alias.length, cs);
}
/* "partitions" column */
@@ -24997,13 +25269,13 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta,
{
char namebuf[NAME_LEN];
/* Derived table name generation */
- int len= my_snprintf(namebuf, sizeof(namebuf)-1,
+ size_t len= my_snprintf(namebuf, sizeof(namebuf)-1,
"<derived%u>",
prev_table->derived_select_number);
eta->firstmatch_table_name.append(namebuf, len);
}
else
- eta->firstmatch_table_name.append(prev_table->pos_in_table_list->alias);
+ eta->firstmatch_table_name.append(&prev_table->pos_in_table_list->alias);
}
}
@@ -25140,7 +25412,9 @@ int JOIN::save_explain_data_intern(Explain_query *output,
Explain_select(output->mem_root,
thd->lex->analyze_stmt)))
DBUG_RETURN(1);
-
+#ifndef DBUG_OFF
+ explain->select_lex= select_lex;
+#endif
join->select_lex->set_explain_type(true);
explain->select_id= join->select_lex->select_number;
@@ -25602,8 +25876,8 @@ Index_hint::print(THD *thd, String *str)
strlen(primary_key_name)))
str->append(primary_key_name);
else
- append_identifier(thd, str, key_name.str, key_name.length);
- }
+ append_identifier(thd, str, &key_name);
+}
str->append(')');
}
@@ -25659,10 +25933,10 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
if (!(belong_to_view &&
belong_to_view->compact_view_format))
{
- append_identifier(thd, str, view_db.str, view_db.length);
+ append_identifier(thd, str, &view_db);
str->append('.');
}
- append_identifier(thd, str, view_name.str, view_name.length);
+ append_identifier(thd, str, &view_name);
cmp_name= view_name.str;
}
else if (derived)
@@ -25677,8 +25951,8 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
}
else
{
- append_identifier(thd, str, table_name, table_name_length);
- cmp_name= table_name;
+ append_identifier(thd, str, &table_name);
+ cmp_name= table_name.str;
}
}
else
@@ -25688,19 +25962,18 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
if (!(belong_to_view &&
belong_to_view->compact_view_format))
{
- append_identifier(thd, str, db, db_length);
+ append_identifier(thd, str, &db);
str->append('.');
}
if (schema_table)
{
- append_identifier(thd, str, schema_table_name,
- strlen(schema_table_name));
- cmp_name= schema_table_name;
+ append_identifier(thd, str, &schema_table_name);
+ cmp_name= schema_table_name.str;
}
else
{
- append_identifier(thd, str, table_name, table_name_length);
- cmp_name= table_name;
+ append_identifier(thd, str, &table_name);
+ cmp_name= table_name.str;
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (partition_names && partition_names->elements)
@@ -25719,23 +25992,26 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
}
#endif /* WITH_PARTITION_STORAGE_ENGINE */
}
- if (my_strcasecmp(table_alias_charset, cmp_name, alias))
+ if (table && table->versioned())
+ vers_conditions.print(str, query_type);
+
+ if (my_strcasecmp(table_alias_charset, cmp_name, alias.str))
{
char t_alias_buff[MAX_ALIAS_NAME];
- const char *t_alias= alias;
+ LEX_CSTRING t_alias= alias;
str->append(' ');
if (lower_case_table_names== 1)
{
- if (alias && alias[0])
+ if (alias.str && alias.str[0])
{
- strmov(t_alias_buff, alias);
- my_casedn_str(files_charset_info, t_alias_buff);
- t_alias= t_alias_buff;
+ strmov(t_alias_buff, alias.str);
+ t_alias.length= my_casedn_str(files_charset_info, t_alias_buff);
+ t_alias.str= t_alias_buff;
}
}
- append_identifier(thd, str, t_alias, strlen(t_alias));
+ append_identifier(thd, str, &t_alias);
}
if (index_hints)
diff --git a/sql/sql_select.h b/sql/sql_select.h
index c1e5a9f95ce..f8911fbba01 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -73,9 +73,45 @@ typedef struct keyuse_t {
*/
uint sj_pred_no;
+ /*
+ If this is NULL than KEYUSE is always enabled.
+ Otherwise it points to the enabling flag for this keyuse (true <=> enabled)
+ */
+ bool *validity_ref;
+
bool is_for_hash_join() { return is_hash_join_key_no(key); }
} KEYUSE;
+
+struct KEYUSE_EXT: public KEYUSE
+{
+ /*
+ This keyuse can be used only when the partial join being extended
+ contains the tables from this table map
+ */
+ table_map needed_in_prefix;
+ /* The enabling flag for keyuses usable for splitting */
+ bool validity_var;
+};
+
+/// Used when finding key fields
+struct KEY_FIELD {
+ Field *field;
+ Item_bool_func *cond;
+ Item *val; ///< May be empty if diff constant
+ uint level;
+ uint optimize;
+ bool eq_func;
+ /**
+ If true, the condition this struct represents will not be satisfied
+ when val IS NULL.
+ */
+ bool null_rejecting;
+ bool *cond_guard; /* See KEYUSE::cond_guard */
+ uint sj_pred_no; /* See KEYUSE::sj_pred_no */
+};
+
+
#define NO_KEYPART ((uint)(-1))
class store_key;
@@ -201,6 +237,8 @@ class SJ_TMP_TABLE;
class JOIN_TAB_RANGE;
class AGGR_OP;
class Filesort;
+struct SplM_plan_info;
+class SplM_opt_info;
typedef struct st_join_table {
st_join_table() {}
@@ -438,7 +476,7 @@ typedef struct st_join_table {
will be turned to fields. These variables are pointing to
tmp_fields_list[123]. Valid only for tmp tables and the last non-tmp
table in the query plan.
- @see JOIN::make_tmp_tables_info()
+ @see JOIN::make_aggr_tables_info()
*/
List<Item> *fields;
/** List of all expressions in the select list */
@@ -614,8 +652,10 @@ typedef struct st_join_table {
bool use_order() const; ///< Use ordering provided by chosen index?
bool sort_table();
bool remove_duplicates();
- Item *get_splitting_cond_for_grouping_derived(THD *thd);
-
+ void add_keyuses_for_splitting();
+ SplM_plan_info *choose_best_splitting(double record_count,
+ table_map remaining_tables);
+ bool fix_splitting(SplM_plan_info *spl_plan, table_map remaining_tables);
} JOIN_TAB;
@@ -920,6 +960,9 @@ typedef struct st_position
Firstmatch_picker firstmatch_picker;
LooseScan_picker loosescan_picker;
Sj_materialization_picker sjmat_picker;
+
+ /* Info on splitting plan used at this position */
+ SplM_plan_info *spl_plan;
} POSITION;
typedef Bounds_checked_array<Item_null_result*> Item_null_array;
@@ -1053,11 +1096,13 @@ protected:
/* Support for plan reoptimization with rewritten conditions. */
enum_reopt_result reoptimize(Item *added_where, table_map join_tables,
Join_plan_state *save_to);
+ /* Choose a subquery plan for a table-less subquery. */
+ bool choose_tableless_subquery_plan();
+
+public:
void save_query_plan(Join_plan_state *save_to);
void reset_query_plan();
void restore_query_plan(Join_plan_state *restore_from);
- /* Choose a subquery plan for a table-less subquery. */
- bool choose_tableless_subquery_plan();
public:
JOIN_TAB *join_tab, **best_ref;
@@ -1415,9 +1460,14 @@ public:
*/
bool implicit_grouping;
- bool is_for_splittable_grouping_derived;
bool with_two_phase_optimization;
- ORDER *partition_list;
+
+ /* Saved execution plan for this join */
+ Join_plan_state *save_qep;
+ /* Info on splittability of the table materialized by this plan*/
+ SplM_opt_info *spl_opt_info;
+ /* Contains info on keyuses usable for splitting */
+ Dynamic_array<KEYUSE_EXT> *ext_keyuses_for_splitting;
JOIN_TAB *sort_and_group_aggr_tab;
@@ -1436,7 +1486,7 @@ public:
table_count= 0;
top_join_tab_count= 0;
const_tables= 0;
- const_table_map= 0;
+ const_table_map= found_const_table_map= 0;
aggr_tables= 0;
eliminated_tables= 0;
join_list= 0;
@@ -1465,7 +1515,10 @@ public:
need_distinct= 0;
skip_sort_order= 0;
with_two_phase_optimization= 0;
- is_for_splittable_grouping_derived= 0;
+ save_qep= 0;
+ spl_opt_info= 0;
+ ext_keyuses_for_splitting= 0;
+ spl_opt_info= 0;
need_tmp= 0;
hidden_group_fields= 0; /*safety*/
error= 0;
@@ -1674,10 +1727,12 @@ public:
const char *message);
JOIN_TAB *first_breadth_first_tab() { return join_tab; }
bool check_two_phase_optimization(THD *thd);
- bool check_for_splittable_grouping_derived(THD *thd);
bool inject_cond_into_where(Item *injected_cond);
- bool push_splitting_cond_into_derived(THD *thd, Item *cond);
- bool improve_chosen_plan(THD *thd);
+ bool check_for_splittable_materialized();
+ void add_keyuses_for_splitting();
+ bool inject_best_splitting_cond(table_map remaining_tables);
+ bool fix_all_splittings_in_plan();
+
bool transform_in_predicates_into_in_subq(THD *thd);
private:
/**
@@ -1712,7 +1767,6 @@ private:
void cleanup_item_list(List<Item> &items) const;
bool add_having_as_table_cond(JOIN_TAB *tab);
bool make_aggr_tables_info();
-
};
enum enum_with_bush_roots { WITH_BUSH_ROOTS, WITHOUT_BUSH_ROOTS};
@@ -1977,7 +2031,7 @@ int report_error(TABLE *table, int error);
int safe_index_read(JOIN_TAB *tab);
int get_quick_record(SQL_SELECT *select);
int setup_order(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
- List<Item> &fields, List <Item> &all_fields, ORDER *order,
+ List<Item> &fields, List <Item> &all_fields, ORDER *order,
bool from_window_spec= false);
int setup_group(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
List<Item> &fields, List<Item> &all_fields, ORDER *order,
@@ -2058,7 +2112,8 @@ public:
@param thd - Current thread.
*/
static void *operator new(size_t size, THD *thd) throw();
- static void operator delete(void *ptr, size_t size) { TRASH(ptr, size); }
+ static void operator delete(void *ptr, size_t size) { TRASH_FREE(ptr, size); }
+ static void operator delete(void *, THD *) throw(){}
Virtual_tmp_table(THD *thd)
{
@@ -2105,7 +2160,7 @@ public:
DBUG_ASSERT(s->blob_fields <= m_alloced_field_count);
s->blob_field[s->blob_fields - 1]= s->fields;
}
- s->fields++;
+ new_field->field_index= s->fields++;
return false;
}
@@ -2128,6 +2183,48 @@ public:
@return true - on error (e.g. could not allocate the record buffer).
*/
bool open();
+
+ void set_all_fields_to_null()
+ {
+ for (uint i= 0; i < s->fields; i++)
+ field[i]->set_null();
+ }
+ /**
+ Set all fields from a compatible item list.
+ The number of fields in "this" must be equal to the number
+ of elements in "value".
+ */
+ bool sp_set_all_fields_from_item_list(THD *thd, List<Item> &items);
+
+ /**
+ Set all fields from a compatible item.
+ The number of fields in "this" must be the same with the number
+ of elements in "value".
+ */
+ bool sp_set_all_fields_from_item(THD *thd, Item *value);
+
+ /**
+ Find a ROW element index by its name
+ Assumes that "this" is used as a storage for a ROW-type SP variable.
+ @param [OUT] idx - the index of the found field is returned here
+ @param [IN] field_name - find a field with this name
+ @return true - on error (the field was not found)
+ @return false - on success (idx[0] was set to the field index)
+ */
+ bool sp_find_field_by_name(uint *idx, const LEX_CSTRING &name) const;
+
+ /**
+ Find a ROW element index by its name.
+ If the element is not found, and error is issued.
+ @param [OUT] idx - the index of the found field is returned here
+ @param [IN] var_name - the name of the ROW variable (for error reporting)
+ @param [IN] field_name - find a field with this name
+ @return true - on error (the field was not found)
+ @return false - on success (idx[0] was set to the field index)
+ */
+ bool sp_find_field_by_name_or_error(uint *idx,
+ const LEX_CSTRING &var_name,
+ const LEX_CSTRING &field_name) const;
};
@@ -2214,6 +2311,10 @@ inline Item * and_items(THD *thd, Item* cond, Item *item)
{
return (cond ? (new (thd->mem_root) Item_cond_and(thd, cond, item)) : item);
}
+inline Item * or_items(THD *thd, Item* cond, Item *item)
+{
+ return (cond ? (new (thd->mem_root) Item_cond_or(thd, cond, item)) : item);
+}
bool choose_plan(JOIN *join, table_map join_tables);
void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab,
table_map last_remaining_tables,
@@ -2275,7 +2376,7 @@ int append_possible_keys(MEM_ROOT *alloc, String_list &list, TABLE *table,
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit,
- const char* alias, bool do_not_open=FALSE,
+ const LEX_CSTRING *alias, bool do_not_open=FALSE,
bool keep_row_order= FALSE);
void free_tmp_table(THD *thd, TABLE *entry);
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
@@ -2288,13 +2389,18 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
TMP_ENGINE_COLUMNDEF **recinfo,
ulonglong options);
bool instantiate_tmp_table(TABLE *table, KEY *keyinfo,
- MARIA_COLUMNDEF *start_recinfo,
- MARIA_COLUMNDEF **recinfo,
+ TMP_ENGINE_COLUMNDEF *start_recinfo,
+ TMP_ENGINE_COLUMNDEF **recinfo,
ulonglong options);
bool open_tmp_table(TABLE *table);
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps);
double prev_record_reads(POSITION *positions, uint idx, table_map found_ref);
void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist);
+double get_tmp_table_lookup_cost(THD *thd, double row_count, uint row_size);
+double get_tmp_table_write_cost(THD *thd, double row_count, uint row_size);
+void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
+bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
+ bool skip_unprefixed_keyparts);
struct st_cond_statistic
{
diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc
index 1af37fe1fad..cc0691f92cf 100644
--- a/sql/sql_sequence.cc
+++ b/sql/sql_sequence.cc
@@ -50,12 +50,12 @@ static Field_definition sequence_structure[]=
{
{"next_not_cached_value", 21, &type_handler_longlong,
{STRING_WITH_LEN("")}, FL},
- {"minimum_value", 21, &type_handler_longlong, STRING_WITH_LEN(""), FL},
- {"maximum_value", 21, &type_handler_longlong, STRING_WITH_LEN(""), FL},
+ {"minimum_value", 21, &type_handler_longlong, {STRING_WITH_LEN("")}, FL},
+ {"maximum_value", 21, &type_handler_longlong, {STRING_WITH_LEN("")}, FL},
{"start_value", 21, &type_handler_longlong, {STRING_WITH_LEN("start value when sequences is created or value if RESTART is used")}, FL},
{"increment", 21, &type_handler_longlong,
- {C_STRING_WITH_LEN("increment value")}, FL},
- {"cache_size", 21, &type_handler_longlong, STRING_WITH_LEN(""),
+ {STRING_WITH_LEN("increment value")}, FL},
+ {"cache_size", 21, &type_handler_longlong, {STRING_WITH_LEN("")},
FL | UNSIGNED_FLAG},
{"cycle_option", 1, &type_handler_tiny, {STRING_WITH_LEN("0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed")},
FL | UNSIGNED_FLAG },
@@ -113,7 +113,7 @@ bool sequence_definition::check_and_adjust(bool set_reserved_until)
/* To ensure that cache * real_increment will never overflow */
max_increment= (real_increment ?
- labs(real_increment) :
+ llabs(real_increment) :
MAX_AUTO_INCREMENT_VALUE);
if (max_value >= start &&
@@ -220,8 +220,8 @@ bool check_sequence_fields(LEX *lex, List<Create_field> *fields)
err:
my_error(ER_SEQUENCE_INVALID_TABLE_STRUCTURE, MYF(0),
- lex->select_lex.table_list.first->db,
- lex->select_lex.table_list.first->table_name, reason);
+ lex->select_lex.table_list.first->db.str,
+ lex->select_lex.table_list.first->table_name.str, reason);
DBUG_RETURN(TRUE);
}
@@ -440,7 +440,7 @@ int SEQUENCE::read_initial_values(TABLE *table)
DBUG_ASSERT(table->reginfo.lock_type == TL_READ);
if (!(error= read_stored_values(table)))
initialized= SEQ_READY_TO_USE;
- mysql_unlock_tables(thd, lock, 0);
+ mysql_unlock_tables(thd, lock);
if (mdl_lock_used)
thd->mdl_context.release_lock(mdl_request.ticket);
@@ -843,7 +843,7 @@ bool Sql_cmd_alter_sequence::execute(THD *thd)
No_such_table_error_handler no_such_table_handler;
DBUG_ENTER("Sql_cmd_alter_sequence::execute");
- if (check_access(thd, ALTER_ACL, first_table->db,
+ if (check_access(thd, ALTER_ACL, first_table->db.str,
&first_table->grant.privilege,
&first_table->grant.m_internal,
0, 0))
@@ -852,10 +852,10 @@ bool Sql_cmd_alter_sequence::execute(THD *thd)
if (check_grant(thd, ALTER_ACL, first_table, FALSE, 1, FALSE))
DBUG_RETURN(TRUE); /* purecov: inspected */
- if (lex->check_exists)
+ if (if_exists())
thd->push_internal_handler(&no_such_table_handler);
error= open_and_lock_tables(thd, first_table, FALSE, 0);
- if (lex->check_exists)
+ if (if_exists())
{
trapped_errors= no_such_table_handler.safely_trapped_errors();
thd->pop_internal_handler();
@@ -865,9 +865,9 @@ bool Sql_cmd_alter_sequence::execute(THD *thd)
if (trapped_errors)
{
StringBuffer<FN_REFLEN> tbl_name;
- tbl_name.append(first_table->db);
+ tbl_name.append(&first_table->db);
tbl_name.append('.');
- tbl_name.append(first_table->table_name);
+ tbl_name.append(&first_table->table_name);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_UNKNOWN_SEQUENCES,
ER_THD(thd, ER_UNKNOWN_SEQUENCES),
@@ -909,8 +909,8 @@ bool Sql_cmd_alter_sequence::execute(THD *thd)
if (new_seq->check_and_adjust(0))
{
my_error(ER_SEQUENCE_INVALID_DATA, MYF(0),
- first_table->db,
- first_table->table_name);
+ first_table->db.str,
+ first_table->table_name.str);
error= 1;
goto end;
}
diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc
index 30b2e11139b..353d1f551a5 100644
--- a/sql/sql_servers.cc
+++ b/sql/sql_servers.cc
@@ -54,6 +54,8 @@
static HASH servers_cache;
static MEM_ROOT mem;
static mysql_rwlock_t THR_LOCK_servers;
+static LEX_CSTRING MYSQL_SERVERS_NAME= {STRING_WITH_LEN("servers") };
+
static bool get_server_from_table_to_cache(TABLE *table);
@@ -83,7 +85,7 @@ static uchar *servers_cache_get_key(FOREIGN_SERVER *server, size_t *length,
my_bool not_used __attribute__((unused)))
{
DBUG_ENTER("servers_cache_get_key");
- DBUG_PRINT("info", ("server_name_length %d server_name %s",
+ DBUG_PRINT("info", ("server_name_length %zd server_name %s",
server->server_name_length,
server->server_name));
@@ -154,7 +156,8 @@ bool servers_init(bool dont_read_servers_table)
}
/* Initialize the mem root for data */
- init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
+ init_sql_alloc(&mem, "servers", ACL_ALLOC_BLOCK_SIZE, 0,
+ MYF(MY_THREAD_SPECIFIC));
if (dont_read_servers_table)
goto end;
@@ -203,7 +206,7 @@ static bool servers_load(THD *thd, TABLE_LIST *tables)
my_hash_reset(&servers_cache);
free_root(&mem, MYF(0));
- init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(&mem, "servers_load", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
if (init_read_record(&read_record_info,thd,table=tables[0].table, NULL, NULL,
1,0, FALSE))
@@ -251,7 +254,7 @@ bool servers_reload(THD *thd)
DBUG_PRINT("info", ("locking servers_cache"));
mysql_rwlock_wrlock(&THR_LOCK_servers);
- tables[0].init_one_table("mysql", 5, "servers", 7, "servers", TL_READ);
+ tables[0].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_SERVERS_NAME, 0, TL_READ);
if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{
@@ -383,10 +386,9 @@ insert_server(THD *thd, FOREIGN_SERVER *server)
int error= -1;
TABLE_LIST tables;
TABLE *table;
-
DBUG_ENTER("insert_server");
- tables.init_one_table("mysql", 5, "servers", 7, "servers", TL_WRITE);
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_SERVERS_NAME, 0, TL_WRITE);
/* need to open before acquiring THR_LOCK_plugin or it will deadlock */
if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
@@ -431,7 +433,7 @@ insert_server_record_into_cache(FOREIGN_SERVER *server)
We succeded in insertion of the server to the table, now insert
the server to the cache
*/
- DBUG_PRINT("info", ("inserting server %s at %p, length %d",
+ DBUG_PRINT("info", ("inserting server %s at %p, length %zd",
server->server_name, server,
server->server_name_length));
if (my_hash_insert(&servers_cache, (uchar*) server))
@@ -603,7 +605,7 @@ static int drop_server_internal(THD *thd, LEX_SERVER_OPTIONS *server_options)
DBUG_PRINT("info", ("server name server->server_name %s",
server_options->server_name.str));
- tables.init_one_table("mysql", 5, "servers", 7, "servers", TL_WRITE);
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_SERVERS_NAME, 0, TL_WRITE);
/* hit the memory hit first */
if ((error= delete_server_record_in_cache(server_options)))
@@ -687,7 +689,7 @@ delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options)
We succeded in deletion of the server to the table, now delete
the server from the cache
*/
- DBUG_PRINT("info",("deleting server %s length %d",
+ DBUG_PRINT("info",("deleting server %s length %zd",
server->server_name,
server->server_name_length));
@@ -734,8 +736,7 @@ int update_server(THD *thd, FOREIGN_SERVER *existing, FOREIGN_SERVER *altered)
TABLE_LIST tables;
DBUG_ENTER("update_server");
- tables.init_one_table("mysql", 5, "servers", 7, "servers",
- TL_WRITE);
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_SERVERS_NAME, 0, TL_WRITE);
if (!(table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
{
diff --git a/sql/sql_servers.h b/sql/sql_servers.h
index 1cb05416c63..b2fa40cef27 100644
--- a/sql/sql_servers.h
+++ b/sql/sql_servers.h
@@ -27,7 +27,7 @@ typedef struct st_federated_server
{
const char *server_name;
long port;
- uint server_name_length;
+ size_t server_name_length;
const char *db, *scheme, *username, *password, *socket, *owner, *host, *sport;
} FOREIGN_SERVER;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 2df84b473b8..2b1b765a5be 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -62,6 +62,8 @@
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
#endif
+#include "vtmd.h"
+#include "transaction.h"
enum enum_i_s_events_fields
{
@@ -137,6 +139,29 @@ static const LEX_CSTRING *view_algorithm(TABLE_LIST *table);
bool get_lookup_field_values(THD *, COND *, TABLE_LIST *, LOOKUP_FIELD_VALUES *);
+/**
+ Try to lock a mutex, but give up after a short while to not cause deadlocks
+
+ The loop is short, as the mutex we are trying to lock are mutex the should
+ never be locked a long time, just over a few instructions.
+
+ @return 0 ok
+ @return 1 error
+*/
+
+static bool trylock_short(mysql_mutex_t *mutex)
+{
+ uint i;
+ for (i= 0 ; i < 100 ; i++)
+ {
+ if (!mysql_mutex_trylock(mutex))
+ return 0;
+ LF_BACKOFF();
+ }
+ return 1;
+}
+
+
/***************************************************************************
** List all table types supported
***************************************************************************/
@@ -149,7 +174,7 @@ static bool is_show_command(THD *thd)
static int make_version_string(char *buf, int buf_length, uint version)
{
- return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
+ return (int)my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
}
@@ -568,6 +593,7 @@ static struct show_privileges_st sys_privileges[]=
{"Create view", "Tables", "To create new views"},
{"Create user", "Server Admin", "To create new users"},
{"Delete", "Tables", "To delete existing rows"},
+ {"Delete versioning rows", "Tables", "To delete versioning table historical rows"},
{"Drop", "Databases,Tables", "To drop databases, tables, and views"},
#ifdef HAVE_EVENT_SCHEDULER
{"Event","Server Admin","To create, alter, drop and execute events"},
@@ -790,6 +816,57 @@ static void dispose_db_dir(void *ptr)
}
+/*
+ Append an element into @@ignore_db_dirs
+
+ This is a function to be called after regular option processing has been
+ finalized.
+*/
+
+void ignore_db_dirs_append(const char *dirname_arg)
+{
+ char *new_entry_buf;
+ LEX_STRING *new_entry;
+ size_t len= strlen(dirname_arg);
+
+ if (!my_multi_malloc(0,
+ &new_entry, sizeof(LEX_STRING),
+ &new_entry_buf, len + 1,
+ NullS))
+ return;
+
+ memcpy(new_entry_buf, dirname_arg, len+1);
+ new_entry->str = new_entry_buf;
+ new_entry->length= len;
+
+ if (my_hash_insert(&ignore_db_dirs_hash, (uchar *)new_entry))
+ {
+ // Either the name is already there or out-of-memory.
+ my_free(new_entry);
+ return;
+ }
+
+ // Append the name to the option string.
+ size_t curlen= strlen(opt_ignore_db_dirs);
+ // Add one for comma and one for \0.
+ size_t newlen= curlen + len + 1 + 1;
+ char *new_db_dirs;
+ if (!(new_db_dirs= (char*)my_malloc(newlen ,MYF(0))))
+ {
+ // This is not a critical condition
+ return;
+ }
+
+ memcpy(new_db_dirs, opt_ignore_db_dirs, curlen);
+ if (curlen != 0)
+ new_db_dirs[curlen]=',';
+ memcpy(new_db_dirs + (curlen + ((curlen!=0)?1:0)), dirname_arg, len+1);
+
+ if (opt_ignore_db_dirs)
+ my_free(opt_ignore_db_dirs);
+ opt_ignore_db_dirs= new_db_dirs;
+}
+
bool
ignore_db_dirs_process_additions()
{
@@ -1170,8 +1247,8 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list,
bool error= TRUE;
MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysqld_show_create_get_fields");
- DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
- table_list->table_name));
+ DBUG_PRINT("enter",("db: %s table: %s",table_list->db.str,
+ table_list->table_name.str));
/* We want to preserve the tree for views. */
thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
@@ -1199,14 +1276,14 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list,
if (thd->lex->table_type == TABLE_TYPE_VIEW && !table_list->view)
{
my_error(ER_WRONG_OBJECT, MYF(0),
- table_list->db, table_list->table_name, "VIEW");
+ table_list->db.str, table_list->table_name.str, "VIEW");
goto exit;
}
else if (thd->lex->table_type == TABLE_TYPE_SEQUENCE &&
table_list->table->s->table_type != TABLE_TYPE_SEQUENCE)
{
my_error(ER_NOT_SEQUENCE, MYF(0),
- table_list->db, table_list->table_name);
+ table_list->db.str, table_list->table_name.str);
goto exit;
}
@@ -1282,8 +1359,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
List<Item> field_list;
bool error= TRUE;
DBUG_ENTER("mysqld_show_create");
- DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
- table_list->table_name));
+ DBUG_PRINT("enter",("db: %s table: %s",table_list->db.str,
+ table_list->table_name.str));
/*
Metadata locks taken during SHOW CREATE should be released when
@@ -1291,6 +1368,15 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
*/
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
+ TABLE_LIST archive;
+ bool versioned= table_list->vers_conditions;
+ if (versioned)
+ {
+ DBUG_ASSERT(table_list->vers_conditions == SYSTEM_TIME_AS_OF);
+ VTMD_table vtmd(*table_list);
+ if (vtmd.setup_select(thd))
+ goto exit;
+ }
if (mysqld_show_create_get_fields(thd, table_list, &field_list, &buffer))
goto exit;
@@ -1306,8 +1392,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
else
{
if (table_list->schema_table)
- protocol->store(table_list->schema_table->table_name,
- system_charset_info);
+ protocol->store(table_list->schema_table->table_name, system_charset_info);
else
protocol->store(table_list->table->alias.c_ptr(), system_charset_info);
}
@@ -1333,6 +1418,13 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
my_eof(thd);
exit:
+ if (versioned)
+ {
+ /* If commit fails, we should be able to reset the OK status. */
+ thd->get_stmt_da()->set_overwrite_status(true);
+ trans_commit_stmt(thd);
+ thd->get_stmt_da()->set_overwrite_status(false);
+ }
close_thread_tables(thd);
/* Release any metadata locks taken during SHOW CREATE. */
thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
@@ -1388,7 +1480,7 @@ bool mysqld_show_create_db(THD *thd, LEX_CSTRING *dbname,
DBUG_RETURN(TRUE);
}
#endif
- if (is_infoschema_db(dbname->str))
+ if (is_infoschema_db(dbname))
{
*dbname= INFORMATION_SCHEMA_NAME;
create.default_table_charset= system_charset_info;
@@ -1417,7 +1509,7 @@ bool mysqld_show_create_db(THD *thd, LEX_CSTRING *dbname,
buffer.append(STRING_WITH_LEN("CREATE DATABASE "));
if (options.if_not_exists())
buffer.append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
- append_identifier(thd, &buffer, dbname->str, dbname->length);
+ append_identifier(thd, &buffer, dbname);
if (create.default_table_charset)
{
@@ -1452,7 +1544,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
TABLE *table;
MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysqld_list_fields");
- DBUG_PRINT("enter",("table: %s",table_list->table_name));
+ DBUG_PRINT("enter",("table: %s", table_list->table_name.str));
if (open_normal_and_derived_tables(thd, table_list,
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL,
@@ -1535,7 +1627,7 @@ static const char *require_quotes(const char *name, uint name_length)
*/
bool
-append_identifier(THD *thd, String *packet, const char *name, uint length)
+append_identifier(THD *thd, String *packet, const char *name, size_t length)
{
const char *name_end;
char quote_char;
@@ -1614,11 +1706,11 @@ append_identifier(THD *thd, String *packet, const char *name, uint length)
# Quote character
*/
-int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
+int get_quote_char_for_identifier(THD *thd, const char *name, size_t length)
{
if (length &&
- !is_keyword(name,length) &&
- !require_quotes(name, length) &&
+ !is_keyword(name,(uint)length) &&
+ !require_quotes(name, (uint)length) &&
!(thd->variables.option_bits & OPTION_QUOTE_SHOW_CREATE))
return EOF;
if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
@@ -1634,7 +1726,7 @@ static void append_directory(THD *thd, String *packet, const char *dir_type,
{
if (filename && !(thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
{
- uint length= dirname_length(filename);
+ size_t length= dirname_length(filename);
packet->append(' ');
packet->append(dir_type);
packet->append(STRING_WITH_LEN(" DIRECTORY='"));
@@ -1695,6 +1787,7 @@ static bool get_field_default_value(THD *thd, Field *field, String *def_value,
has_default= (field->default_value ||
(!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
+ !field->vers_sys_field() &&
field->unireg_check != Field::NEXT_NUMBER));
def_value->length(0);
@@ -1791,7 +1884,7 @@ static void append_create_options(THD *thd, String *packet,
DBUG_ASSERT(opt->value.str);
packet->append(' ');
- append_identifier(thd, packet, opt->name.str, opt->name.length);
+ append_identifier(thd, packet, &opt->name);
packet->append('=');
if (opt->quoted_value)
append_unescaped(packet, opt->value.str, opt->value.length);
@@ -2005,7 +2098,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
{
List<Item> field_list;
char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH];
- const char *alias;
+ LEX_CSTRING alias;
String type;
String def_value;
Field **ptr,*field;
@@ -2014,6 +2107,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
TABLE *table= table_list->table;
TABLE_SHARE *share= table->s;
sql_mode_t sql_mode= thd->variables.sql_mode;
+ bool explicit_fields= false;
bool foreign_db_mode= sql_mode & (MODE_POSTGRESQL | MODE_ORACLE |
MODE_MSSQL | MODE_DB2 |
MODE_MAXDB | MODE_ANSI);
@@ -2050,15 +2144,19 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
if (create_info_arg && create_info_arg->if_not_exists())
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
if (table_list->schema_table)
- alias= table_list->schema_table->table_name;
+ {
+ alias.str= table_list->schema_table->table_name;
+ alias.length= strlen(alias.str);
+ }
else
{
- if (lower_case_table_names == 2)
- alias= table->alias.c_ptr();
- else
+ if (lower_case_table_names == 2 || table_list->vers_force_alias)
{
- alias= share->table_name.str;
+ alias.str= table->alias.c_ptr();
+ alias.length= table->alias.length();
}
+ else
+ alias= share->table_name;
}
/*
@@ -2072,14 +2170,14 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
{
const LEX_CSTRING *const db=
table_list->schema_table ? &INFORMATION_SCHEMA_NAME : &table->s->db;
- if (!thd->db || strcmp(db->str, thd->db))
+ if (!thd->db.str || cmp(db, &thd->db))
{
- append_identifier(thd, packet, db->str, db->length);
+ append_identifier(thd, packet, db);
packet->append(STRING_WITH_LEN("."));
}
}
- append_identifier(thd, packet, alias, strlen(alias));
+ append_identifier(thd, packet, &alias);
packet->append(STRING_WITH_LEN(" (\n"));
/*
We need this to get default values from the table
@@ -2088,16 +2186,20 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
*/
old_map= tmp_use_all_columns(table, table->read_set);
+ bool not_the_first_field= false;
for (ptr=table->field ; (field= *ptr); ptr++)
{
+
uint flags = field->flags;
- if (ptr != table->field)
+ if (field->invisible > INVISIBLE_USER)
+ continue;
+ if (not_the_first_field)
packet->append(STRING_WITH_LEN(",\n"));
+ not_the_first_field= true;
packet->append(STRING_WITH_LEN(" "));
- append_identifier(thd,packet,field->field_name.str,
- field->field_name.length);
+ append_identifier(thd, packet, &field->field_name);
packet->append(' ');
type.set(tmp, sizeof(tmp), system_charset_info);
@@ -2136,7 +2238,15 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
}
else
{
- if (flags & NOT_NULL_FLAG)
+ if (field->flags & VERS_SYS_START_FLAG)
+ {
+ packet->append(STRING_WITH_LEN(" GENERATED ALWAYS AS ROW START"));
+ }
+ else if (field->flags & VERS_SYS_END_FLAG)
+ {
+ packet->append(STRING_WITH_LEN(" GENERATED ALWAYS AS ROW END"));
+ }
+ else if (flags & NOT_NULL_FLAG)
packet->append(STRING_WITH_LEN(" NOT NULL"));
else if (field->type() == MYSQL_TYPE_TIMESTAMP)
{
@@ -2147,6 +2257,10 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" NULL"));
}
+ if (field->invisible == INVISIBLE_USER)
+ {
+ packet->append(STRING_WITH_LEN(" INVISIBLE"));
+ }
def_value.set(def_value_buf, sizeof(def_value_buf), system_charset_info);
if (get_field_default_value(thd, field, &def_value, 1))
{
@@ -2154,6 +2268,11 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
}
+ if (field->vers_update_unversioned())
+ {
+ packet->append(STRING_WITH_LEN(" WITHOUT SYSTEM VERSIONING"));
+ }
+
if (!limited_mysql_mode &&
print_on_update_clause(field, &def_value, false))
{
@@ -2188,6 +2307,8 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
for (uint i=0 ; i < share->keys ; i++,key_info++)
{
+ if (key_info->flags & HA_INVISIBLE_KEY)
+ continue;
KEY_PART_INFO *key_part= key_info->key_part;
bool found_primary=0;
packet->append(STRING_WITH_LEN(",\n "));
@@ -2211,18 +2332,21 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN("KEY "));
if (!found_primary)
- append_identifier(thd, packet, key_info->name.str, key_info->name.length);
+ append_identifier(thd, packet, &key_info->name);
packet->append(STRING_WITH_LEN(" ("));
for (uint j=0 ; j < key_info->user_defined_key_parts ; j++,key_part++)
{
+ Field *field= key_part->field;
+ if (field->invisible > INVISIBLE_USER)
+ continue;
+
if (j)
packet->append(',');
if (key_part->field)
- append_identifier(thd,packet, key_part->field->field_name.str,
- key_part->field->field_name.length);
+ append_identifier(thd, packet, &key_part->field->field_name);
if (key_part->field &&
(key_part->length !=
table->field[key_part->fieldnr-1]->key_length() &&
@@ -2238,13 +2362,36 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
{
LEX_CSTRING *parser_name= plugin_name(key_info->parser);
packet->append(STRING_WITH_LEN(" /*!50100 WITH PARSER "));
- append_identifier(thd, packet, parser_name->str, parser_name->length);
+ append_identifier(thd, packet, parser_name);
packet->append(STRING_WITH_LEN(" */ "));
}
append_create_options(thd, packet, key_info->option_list, check_options,
hton->index_options);
}
+ if (table->versioned())
+ {
+ const Field *fs = table->vers_start_field();
+ const Field *fe = table->vers_end_field();
+ DBUG_ASSERT(fs);
+ DBUG_ASSERT(fe);
+ explicit_fields= fs->invisible < INVISIBLE_SYSTEM;
+ DBUG_ASSERT(!explicit_fields || fe->invisible < INVISIBLE_SYSTEM);
+ if (explicit_fields)
+ {
+ packet->append(STRING_WITH_LEN(",\n PERIOD FOR SYSTEM_TIME ("));
+ append_identifier(thd,packet,fs->field_name.str, fs->field_name.length);
+ packet->append(STRING_WITH_LEN(", "));
+ append_identifier(thd,packet,fe->field_name.str, fe->field_name.length);
+ packet->append(STRING_WITH_LEN(")"));
+ }
+ else
+ {
+ DBUG_ASSERT(fs->invisible == INVISIBLE_SYSTEM);
+ DBUG_ASSERT(fe->invisible == INVISIBLE_SYSTEM);
+ }
+ }
+
/*
Get possible foreign key definitions stored in InnoDB and append them
to the CREATE TABLE statement
@@ -2267,10 +2414,10 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
check->print(&str);
packet->append(STRING_WITH_LEN(",\n "));
- if (check->name.length)
+ if (check->name.str)
{
packet->append(STRING_WITH_LEN("CONSTRAINT "));
- append_identifier(thd, packet, check->name.str, check->name.length);
+ append_identifier(thd, packet, &check->name);
}
packet->append(STRING_WITH_LEN(" CHECK ("));
packet->append(str);
@@ -2283,6 +2430,9 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
add_table_options(thd, table, create_info_arg,
table_list->schema_table != 0, 0, packet);
+ if (table->versioned())
+ packet->append(STRING_WITH_LEN(" WITH SYSTEM VERSIONING"));
+
#ifdef WITH_PARTITION_STORAGE_ENGINE
{
if (table->part_info &&
@@ -2411,11 +2561,11 @@ void append_definer(THD *thd, String *buffer, const LEX_CSTRING *definer_user,
const LEX_CSTRING *definer_host)
{
buffer->append(STRING_WITH_LEN("DEFINER="));
- append_identifier(thd, buffer, definer_user->str, definer_user->length);
+ append_identifier(thd, buffer, definer_user);
if (definer_host->str && definer_host->str[0])
{
buffer->append('@');
- append_identifier(thd, buffer, definer_host->str, definer_host->length);
+ append_identifier(thd, buffer, definer_host);
}
buffer->append(' ');
}
@@ -2431,7 +2581,7 @@ static int show_create_view(THD *thd, TABLE_LIST *table, String *buff)
MODE_MAXDB |
MODE_ANSI)) != 0;
- if (!thd->db || strcmp(thd->db, table->view_db.str))
+ if (!thd->db.str || cmp(&thd->db, &table->view_db))
/*
print compact view name if the view belongs to the current database
*/
@@ -2448,7 +2598,7 @@ static int show_create_view(THD *thd, TABLE_LIST *table, String *buff)
tbl;
tbl= tbl->next_global)
{
- if (strcmp(table->view_db.str, tbl->view ? tbl->view_db.str :tbl->db)!= 0)
+ if (cmp(&table->view_db, tbl->view ? &tbl->view_db : &tbl->db))
{
table->compact_view_format= FALSE;
break;
@@ -2464,10 +2614,10 @@ static int show_create_view(THD *thd, TABLE_LIST *table, String *buff)
buff->append(STRING_WITH_LEN("VIEW "));
if (!compact_view_name)
{
- append_identifier(thd, buff, table->view_db.str, table->view_db.length);
+ append_identifier(thd, buff, &table->view_db);
buff->append('.');
}
- append_identifier(thd, buff, table->view_name.str, table->view_name.length);
+ append_identifier(thd, buff, &table->view_name);
buff->append(STRING_WITH_LEN(" AS "));
/*
@@ -2510,7 +2660,7 @@ static int show_create_sequence(THD *thd, TABLE_LIST *table_list,
alias= table->s->table_name;
packet->append(STRING_WITH_LEN("CREATE SEQUENCE "));
- append_identifier(thd, packet, alias.str, alias.length);
+ append_identifier(thd, packet, &alias);
packet->append(STRING_WITH_LEN(" start with "));
packet->append_longlong(seq->start);
packet->append(STRING_WITH_LEN(" minvalue "));
@@ -2548,7 +2698,8 @@ public:
{ return alloc_root(mem_root, size); }
static void operator delete(void *ptr __attribute__((unused)),
size_t size __attribute__((unused)))
- { TRASH(ptr, size); }
+ { TRASH_FREE(ptr, size); }
+ static void operator delete(void *, MEM_ROOT *){}
my_thread_id thread_id;
uint32 os_thread_id;
@@ -2566,23 +2717,28 @@ static const char *thread_state_info(THD *tmp)
{
if (tmp->net.reading_or_writing == 2)
return "Writing to net";
- else if (tmp->get_command() == COM_SLEEP)
+ if (tmp->get_command() == COM_SLEEP)
return "";
- else
- return "Reading from net";
+ return "Reading from net";
}
- else
#endif
+
+ if (tmp->proc_info)
+ return tmp->proc_info;
+
+ /* Check if we are waiting on a condition */
+ if (!trylock_short(&tmp->LOCK_thd_kill))
{
- if (tmp->proc_info)
- return tmp->proc_info;
- else if (tmp->mysys_var && tmp->mysys_var->current_cond)
+ /* mysys_var is protected by above mutex */
+ bool cond= tmp->mysys_var && tmp->mysys_var->current_cond;
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
+ if (cond)
return "Waiting on cond";
- else
- return NULL;
}
+ return NULL;
}
+
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
{
Item *field;
@@ -2645,7 +2801,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
while ((tmp=it++))
{
Security_context *tmp_sctx= tmp->security_ctx;
- struct st_my_thread_var *mysys_var;
+ bool got_thd_data;
if ((tmp->vio_ok() || tmp->system_thread) &&
(!user || (!tmp->system_thread &&
tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
@@ -2669,48 +2825,61 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
tmp_sctx->host_or_ip :
tmp_sctx->host ? tmp_sctx->host : "");
thd_info->command=(int) tmp->get_command();
- mysql_mutex_lock(&tmp->LOCK_thd_data);
- if ((thd_info->db= tmp->db)) // Safe test
- thd_info->db= thd->strdup(thd_info->db);
- if ((mysys_var= tmp->mysys_var))
- mysql_mutex_lock(&mysys_var->mutex);
- thd_info->proc_info= (char*) (tmp->killed >= KILL_QUERY ?
- "Killed" : 0);
- thd_info->state_info= thread_state_info(tmp);
- if (mysys_var)
- mysql_mutex_unlock(&mysys_var->mutex);
- /* Lock THD mutex that protects its data when looking at it. */
- if (tmp->query())
+ if ((got_thd_data= !trylock_short(&tmp->LOCK_thd_data)))
{
- uint length= MY_MIN(max_query_length, tmp->query_length());
- char *q= thd->strmake(tmp->query(),length);
- /* Safety: in case strmake failed, we set length to 0. */
- thd_info->query_string=
- CSET_STRING(q, q ? length : 0, tmp->query_charset());
- }
+ /* This is an approximation */
+ thd_info->proc_info= (char*) (tmp->killed >= KILL_QUERY ?
+ "Killed" : 0);
+ /*
+ The following variables are only safe to access under a lock
+ */
- /*
- Progress report. We need to do this under a lock to ensure that all
- is from the same stage.
- */
- if (tmp->progress.max_counter)
- {
- uint max_stage= MY_MAX(tmp->progress.max_stage, 1);
- thd_info->progress= (((tmp->progress.stage / (double) max_stage) +
- ((tmp->progress.counter /
- (double) tmp->progress.max_counter) /
- (double) max_stage)) *
- 100.0);
- set_if_smaller(thd_info->progress, 100);
+ thd_info->db= 0;
+ if (tmp->db.str)
+ thd_info->db= thd->strmake(tmp->db.str, tmp->db.length);
+
+ if (tmp->query())
+ {
+ uint length= MY_MIN(max_query_length, tmp->query_length());
+ char *q= thd->strmake(tmp->query(),length);
+ /* Safety: in case strmake failed, we set length to 0. */
+ thd_info->query_string=
+ CSET_STRING(q, q ? length : 0, tmp->query_charset());
+ }
+
+ /*
+ Progress report. We need to do this under a lock to ensure that all
+ is from the same stage.
+ */
+ if (tmp->progress.max_counter)
+ {
+ uint max_stage= MY_MAX(tmp->progress.max_stage, 1);
+ thd_info->progress= (((tmp->progress.stage / (double) max_stage) +
+ ((tmp->progress.counter /
+ (double) tmp->progress.max_counter) /
+ (double) max_stage)) *
+ 100.0);
+ set_if_smaller(thd_info->progress, 100);
+ }
+ else
+ thd_info->progress= 0.0;
}
else
+ {
+ thd_info->proc_info= "Busy";
thd_info->progress= 0.0;
+ thd_info->db= "";
+ }
+
+ thd_info->state_info= thread_state_info(tmp);
thd_info->start_time= tmp->start_utime;
ulonglong utime_after_query_snapshot= tmp->utime_after_query;
if (thd_info->start_time < utime_after_query_snapshot)
thd_info->start_time= utime_after_query_snapshot; // COM_SLEEP
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+
+ if (got_thd_data)
+ mysql_mutex_unlock(&tmp->LOCK_thd_data);
thread_infos.append(thd_info);
}
}
@@ -2921,13 +3090,13 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
tmp_sctx->user)))
{
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "PROCESS");
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
DBUG_RETURN(1);
}
if (tmp == thd)
{
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
my_error(ER_TARGET_NOT_EXPLAINABLE, MYF(0));
DBUG_RETURN(1);
}
@@ -2935,7 +3104,7 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
bool bres;
/*
Ok we've found the thread of interest and it won't go away because
- we're holding its LOCK_thd data. Post it a SHOW EXPLAIN request.
+ we're holding its LOCK_thd_kill. Post it a SHOW EXPLAIN request.
*/
bool timed_out;
int timeout_sec= 30;
@@ -2949,7 +3118,7 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
explain_req.request_thd= thd;
explain_req.failed_to_produce= FALSE;
- /* Ok, we have a lock on target->LOCK_thd_data, can call: */
+ /* Ok, we have a lock on target->LOCK_thd_kill, can call: */
bres= tmp->apc_target.make_apc_call(thd, &explain_req, timeout_sec, &timed_out);
if (bres || explain_req.failed_to_produce)
@@ -3028,9 +3197,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
while ((tmp= it++))
{
Security_context *tmp_sctx= tmp->security_ctx;
- struct st_my_thread_var *mysys_var;
- const char *val, *db;
+ const char *val;
ulonglong max_counter;
+ bool got_thd_data;
if ((!tmp->vio_ok() && !tmp->system_thread) ||
(user && (tmp->system_thread || !tmp_sctx->user ||
@@ -3056,23 +3225,26 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
else
table->field[2]->store(tmp_sctx->host_or_ip,
strlen(tmp_sctx->host_or_ip), cs);
- /* DB */
- mysql_mutex_lock(&tmp->LOCK_thd_data);
- if ((db= tmp->db))
+
+ if ((got_thd_data= !trylock_short(&tmp->LOCK_thd_data)))
{
- table->field[3]->store(db, strlen(db), cs);
- table->field[3]->set_notnull();
+ /* DB */
+ if (tmp->db.str)
+ {
+ table->field[3]->store(tmp->db.str, tmp->db.length, cs);
+ table->field[3]->set_notnull();
+ }
}
- if ((mysys_var= tmp->mysys_var))
- mysql_mutex_lock(&mysys_var->mutex);
/* COMMAND */
- if ((val= (char *) ((tmp->killed >= KILL_QUERY ?
+ if ((val= (char *) (!got_thd_data ? "Busy" :
+ (tmp->killed >= KILL_QUERY ?
"Killed" : 0))))
table->field[4]->store(val, strlen(val), cs);
else
table->field[4]->store(command_name[tmp->get_command()].str,
command_name[tmp->get_command()].length, cs);
+
/* MYSQL_TIME */
ulonglong utime= tmp->start_utime;
ulonglong utime_after_query_snapshot= tmp->utime_after_query;
@@ -3081,6 +3253,38 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
utime= utime && utime < unow ? unow - utime : 0;
table->field[5]->store(utime / HRTIME_RESOLUTION, TRUE);
+
+ if (got_thd_data)
+ {
+ if (tmp->query())
+ {
+ table->field[7]->store(tmp->query(),
+ MY_MIN(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length()), cs);
+ table->field[7]->set_notnull();
+
+ /* INFO_BINARY */
+ table->field[16]->store(tmp->query(),
+ MY_MIN(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length()),
+ &my_charset_bin);
+ table->field[16]->set_notnull();
+ }
+
+ /*
+ Progress report. We need to do this under a lock to ensure that all
+ is from the same stage.
+ */
+ if ((max_counter= tmp->progress.max_counter))
+ {
+ table->field[9]->store((longlong) tmp->progress.stage + 1, 1);
+ table->field[10]->store((longlong) tmp->progress.max_stage, 1);
+ table->field[11]->store((double) tmp->progress.counter /
+ (double) max_counter*100.0);
+ }
+ mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ }
+
/* STATE */
if ((val= thread_state_info(tmp)))
{
@@ -3088,46 +3292,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[6]->set_notnull();
}
- if (mysys_var)
- mysql_mutex_unlock(&mysys_var->mutex);
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
-
/* TIME_MS */
table->field[8]->store((double)(utime / (HRTIME_RESOLUTION / 1000.0)));
- /* INFO */
- /* Lock THD mutex that protects its data when looking at it. */
- mysql_mutex_lock(&tmp->LOCK_thd_data);
- if (tmp->query())
- {
- table->field[7]->store(tmp->query(),
- MY_MIN(PROCESS_LIST_INFO_WIDTH,
- tmp->query_length()), cs);
- table->field[7]->set_notnull();
- }
-
- /* INFO_BINARY */
- if (tmp->query())
- {
- table->field[16]->store(tmp->query(),
- MY_MIN(PROCESS_LIST_INFO_WIDTH,
- tmp->query_length()), &my_charset_bin);
- table->field[16]->set_notnull();
- }
-
- /*
- Progress report. We need to do this under a lock to ensure that all
- is from the same stage.
- */
- if ((max_counter= tmp->progress.max_counter))
- {
- table->field[9]->store((longlong) tmp->progress.stage + 1, 1);
- table->field[10]->store((longlong) tmp->progress.max_stage, 1);
- table->field[11]->store((double) tmp->progress.counter /
- (double) max_counter*100.0);
- }
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
-
/*
This may become negative if we free a memory allocated by another
thread in this thread. However it's better that we notice it eventually
@@ -3403,6 +3570,9 @@ const char* get_one_variable(THD *thd,
case SHOW_MY_BOOL:
end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
break;
+ case SHOW_UINT32_STATUS:
+ value= ((char *) status_var + (intptr) value);
+ /* fall through */
case SHOW_UINT:
end= int10_to_str((long) *(uint*) value, buff, 10);
break;
@@ -3629,6 +3799,8 @@ uint calc_sum_of_all_status(STATUS_VAR *to)
add_to_status(to, &tmp->status_var);
to->local_memory_used+= tmp->status_var.local_memory_used;
}
+ if (tmp->get_command() != COM_SLEEP)
+ to->threads_running++;
}
mysql_mutex_unlock(&LOCK_thread_count);
@@ -3974,7 +4146,7 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
case SQLCOM_SHOW_TRIGGERS:
case SQLCOM_SHOW_EVENTS:
thd->make_lex_string(&lookup_field_values->db_value,
- lex->select_lex.db, strlen(lex->select_lex.db));
+ lex->select_lex.db.str, lex->select_lex.db.length);
if (wild)
{
thd->make_lex_string(&lookup_field_values->table_value,
@@ -4072,8 +4244,7 @@ static int make_db_list(THD *thd, Dynamic_array<LEX_CSTRING*> *files,
return 0;
}
- if (is_infoschema_db(lookup_field_vals->db_value.str,
- lookup_field_vals->db_value.length))
+ if (is_infoschema_db(&lookup_field_vals->db_value))
{
if (files->append_val(&INFORMATION_SCHEMA_NAME))
return 1;
@@ -4194,7 +4365,7 @@ int schema_tables_add(THD *thd, Dynamic_array<LEX_CSTRING*> *files,
@retval 2 Not fatal error; Safe to ignore this file list
*/
-static int
+int
make_table_name_list(THD *thd, Dynamic_array<LEX_CSTRING*> *table_names,
LEX *lex, LOOKUP_FIELD_VALUES *lookup_field_vals,
LEX_CSTRING *db_name)
@@ -4216,7 +4387,7 @@ make_table_name_list(THD *thd, Dynamic_array<LEX_CSTRING*> *table_names,
{
LEX_CSTRING *name;
ST_SCHEMA_TABLE *schema_table=
- find_schema_table(thd, lookup_field_vals->table_value.str);
+ find_schema_table(thd, &lookup_field_vals->table_value);
if (schema_table && !schema_table->hidden)
{
if (!(name= thd->make_clex_string(schema_table->table_name,
@@ -4496,8 +4667,7 @@ static int fill_schema_table_names(THD *thd, TABLE_LIST *tables,
CHARSET_INFO *cs= system_charset_info;
handlerton *hton;
bool is_sequence;
- if (ha_table_exists(thd, db_name->str, table_name->str, &hton,
- &is_sequence))
+ if (ha_table_exists(thd, db_name, table_name, &hton, &is_sequence))
{
if (hton == view_pseudo_hton)
table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
@@ -4599,7 +4769,7 @@ try_acquire_high_prio_shared_mdl_lock(THD *thd, TABLE_LIST *table,
bool can_deadlock)
{
bool error;
- table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name,
+ table->mdl_request.init(MDL_key::TABLE, table->db.str, table->table_name.str,
MDL_SHARED_HIGH_PRIO, MDL_TRANSACTION);
if (can_deadlock)
@@ -4678,15 +4848,15 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table,
*/
strmov(db_name_buff, db_name->str);
strmov(table_name_buff, table_name->str);
- my_casedn_str(files_charset_info, db_name_buff);
- my_casedn_str(files_charset_info, table_name_buff);
- table_list.db= db_name_buff;
- table_list.table_name= table_name_buff;
+ table_list.db.length= my_casedn_str(files_charset_info, db_name_buff);
+ table_list.table_name.length= my_casedn_str(files_charset_info, table_name_buff);
+ table_list.db.str= db_name_buff;
+ table_list.table_name.str= table_name_buff;
}
else
{
- table_list.table_name= table_name->str;
- table_list.db= db_name->str;
+ table_list.table_name= *table_name;
+ table_list.db= *db_name;
}
/*
@@ -4716,15 +4886,16 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table,
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_I_S_SKIPPED_TABLE,
ER_THD(thd, ER_WARN_I_S_SKIPPED_TABLE),
- table_list.db, table_list.table_name);
+ table_list.db.str, table_list.table_name.str);
return 0;
}
if (schema_table->i_s_requested_object & OPEN_TRIGGER_ONLY)
{
- init_sql_alloc(&tbl.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
- if (!Table_triggers_list::check_n_load(thd, db_name->str,
- table_name->str, &tbl, 1))
+ init_sql_alloc(&tbl.mem_root, "fill_schema_table_from_frm",
+ TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ if (!Table_triggers_list::check_n_load(thd, db_name,
+ table_name, &tbl, 1))
{
table_list.table= &tbl;
res= schema_table->process_table(thd, &table_list, table,
@@ -4781,7 +4952,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table,
goto end_share;
}
- if (!open_table_from_share(thd, share, table_name->str, 0,
+ if (!open_table_from_share(thd, share, table_name, 0,
(EXTRA_RECORD | OPEN_FRM_FILE_ONLY),
thd->open_options, &tbl, FALSE))
{
@@ -4846,6 +5017,59 @@ public:
}
};
+static bool get_all_archive_tables(THD *thd,
+ Dynamic_array<String> &all_archive_tables)
+{
+ if (thd->variables.vers_alter_history != VERS_ALTER_HISTORY_SURVIVE)
+ return false;
+
+ Dynamic_array<LEX_CSTRING *> all_db;
+ LOOKUP_FIELD_VALUES lookup_field_values= {
+ {C_STRING_WITH_LEN("%")}, {NULL, 0}, true, false};
+ if (make_db_list(thd, &all_db, &lookup_field_values))
+ return true;
+
+ LEX_STRING information_schema= {C_STRING_WITH_LEN("information_schema")};
+ for (size_t i= 0; i < all_db.elements(); i++)
+ {
+ LEX_CSTRING db= *all_db.at(i);
+ if (db.length == information_schema.length &&
+ !memcmp(db.str, information_schema.str, db.length))
+ {
+ all_db.del(i);
+ break;
+ }
+ }
+
+ for (size_t i= 0; i < all_db.elements(); i++)
+ {
+ LEX_CSTRING db_name= *all_db.at(i);
+ Dynamic_array<String> archive_tables;
+ if (VTMD_table::get_archive_tables(thd, db_name.str, db_name.length,
+ archive_tables))
+ return true;
+ for (size_t i= 0; i < archive_tables.elements(); i++)
+ if (all_archive_tables.push(archive_tables.at(i)))
+ return true;
+ }
+
+ return false;
+}
+
+static bool is_archive_table(const Dynamic_array<String> &all_archive_tables,
+ const LEX_CSTRING candidate)
+{
+ for (size_t i= 0; i < all_archive_tables.elements(); i++)
+ {
+ const String &archive_table= all_archive_tables.at(i);
+ if (candidate.length == archive_table.length() &&
+ !memcmp(candidate.str, archive_table.ptr(), candidate.length))
+ {
+ return true;
+ }
+ }
+ return false;
+}
/**
@brief Fill I_S tables whose data are retrieved
@@ -4888,6 +5112,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
#endif
uint table_open_method= tables->table_open_method;
bool can_deadlock;
+ Dynamic_array<String> all_archive_tables;
MEM_ROOT tmp_mem_root;
DBUG_ENTER("get_all_tables");
@@ -4920,17 +5145,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
*/
if (lsel && lsel->table_list.first)
{
- LEX_CSTRING db_name, table_name;
-
- db_name.str= lsel->table_list.first->db;
- db_name.length= lsel->table_list.first->db_length;
-
- table_name.str= lsel->table_list.first->table_name;
- table_name.length= lsel->table_list.first->table_name_length;
-
error= fill_schema_table_by_open(thd, thd->mem_root, TRUE,
table, schema_table,
- &db_name, &table_name,
+ &lsel->table_list.first->db,
+ &lsel->table_list.first->table_name,
&open_tables_state_backup,
can_deadlock);
goto err;
@@ -4954,9 +5172,12 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
if (make_db_list(thd, &db_names, &plan->lookup_field_vals))
goto err;
+ if (get_all_archive_tables(thd, all_archive_tables))
+ goto err;
+
/* Use tmp_mem_root to allocate data for opened tables */
- init_alloc_root(&tmp_mem_root, SHOW_ALLOC_BLOCK_SIZE, SHOW_ALLOC_BLOCK_SIZE,
- MY_THREAD_SPECIFIC);
+ init_alloc_root(&tmp_mem_root, "get_all_tables", SHOW_ALLOC_BLOCK_SIZE,
+ SHOW_ALLOC_BLOCK_SIZE, MY_THREAD_SPECIFIC);
for (size_t i=0; i < db_names.elements(); i++)
{
@@ -4983,13 +5204,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
LEX_CSTRING *table_name= table_names.at(i);
DBUG_ASSERT(table_name->length <= NAME_LEN);
+ if (is_archive_table(all_archive_tables, *table_name))
+ continue;
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!(thd->col_access & TABLE_ACLS))
{
- table_acl_check.db= db_name->str;
- table_acl_check.db_length= db_name->length;
- table_acl_check.table_name= table_name->str;
- table_acl_check.table_name_length= table_name->length;
+ table_acl_check.db= *db_name;
+ table_acl_check.table_name= *table_name;
table_acl_check.grant.privilege= thd->col_access;
if (check_grant(thd, TABLE_ACLS, &table_acl_check, TRUE, 1, TRUE))
continue;
@@ -5201,14 +5423,18 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
if (share->tmp_table == SYSTEM_TMP_TABLE)
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
- else if (share->tmp_table)
- table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
else if (share->table_type == TABLE_TYPE_SEQUENCE)
table->field[3]->store(STRING_WITH_LEN("SEQUENCE"), cs);
else
- table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
+ {
+ DBUG_ASSERT(share->tmp_table == NO_TMP_TABLE);
+ if (share->versioned)
+ table->field[3]->store(STRING_WITH_LEN("SYSTEM VERSIONED"), cs);
+ else
+ table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
+ }
- for (int i= 4; i < 20; i++)
+ for (uint i= 4; i < table->s->fields; i++)
{
if (i == 7 || (i > 12 && i < 17) || i == 18)
continue;
@@ -5386,8 +5612,15 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
{
table->field[10]->store((longlong) file->stats.max_data_file_length,
TRUE);
+ table->field[10]->set_notnull();
}
table->field[11]->store((longlong) file->stats.index_file_length, TRUE);
+ if (file->stats.max_index_file_length)
+ {
+ table->field[21]->store((longlong) file->stats.max_index_file_length,
+ TRUE);
+ table->field[21]->set_notnull();
+ }
table->field[12]->store((longlong) file->stats.delete_length, TRUE);
if (show_table->found_next_number_field)
{
@@ -5422,6 +5655,11 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
table->field[18]->set_notnull();
}
}
+ /* If table is a temporary table */
+ LEX_CSTRING tmp= { STRING_WITH_LEN("N") };
+ if (show_table->s->tmp_table != NO_TMP_TABLE)
+ tmp.str= "Y";
+ table->field[22]->store(tmp.str, tmp.length, cs);
}
err:
@@ -5616,6 +5854,8 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
for (; (field= *ptr) ; ptr++)
{
+ if(field->invisible > INVISIBLE_USER)
+ continue;
uchar *pos;
char tmp[MAX_FIELD_WIDTH];
String type(tmp,sizeof(tmp), system_charset_info);
@@ -5673,11 +5913,11 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
table->field[16]->store((const char*) pos,
strlen((const char*) pos), cs);
+ StringBuffer<256> buf;
if (field->unireg_check == Field::NEXT_NUMBER)
- table->field[17]->store(STRING_WITH_LEN("auto_increment"), cs);
+ buf.set(STRING_WITH_LEN("auto_increment"),cs);
if (print_on_update_clause(field, &type, true))
- table->field[17]->store(type.ptr(), type.length(), cs);
-
+ buf.set(type.ptr(), type.length(),cs);
if (field->vcol_info)
{
String gen_s(tmp,sizeof(tmp), system_charset_info);
@@ -5688,13 +5928,29 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
table->field[20]->store(STRING_WITH_LEN("ALWAYS"), cs);
if (field->vcol_info->stored_in_db)
- table->field[17]->store(STRING_WITH_LEN("STORED GENERATED"), cs);
+ buf.set(STRING_WITH_LEN("STORED GENERATED"), cs);
else
- table->field[17]->store(STRING_WITH_LEN("VIRTUAL GENERATED"), cs);
+ buf.set(STRING_WITH_LEN("VIRTUAL GENERATED"), cs);
+ }
+ else if (field->flags & VERS_SYSTEM_FIELD)
+ {
+ if (field->flags & VERS_SYS_START_FLAG)
+ table->field[21]->store(STRING_WITH_LEN("ROW START"), cs);
+ else
+ table->field[21]->store(STRING_WITH_LEN("ROW END"), cs);
+ table->field[21]->set_notnull();
+ table->field[20]->store(STRING_WITH_LEN("ALWAYS"), cs);
}
else
table->field[20]->store(STRING_WITH_LEN("NEVER"), cs);
-
+ /*Invisible can coexist with auto_increment and virtual */
+ if (field->invisible == INVISIBLE_USER)
+ {
+ if (buf.length())
+ buf.append(STRING_WITH_LEN(", "));
+ buf.append(STRING_WITH_LEN("INVISIBLE"),cs);
+ }
+ table->field[17]->store(buf.ptr(), buf.length(), cs);
table->field[19]->store(field->comment.str, field->comment.length, cs);
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
@@ -5757,7 +6013,7 @@ static my_bool iter_schema_engines(THD *thd, plugin_ref plugin,
{
restore_record(table, s->default_values);
table->field[0]->store(plug->name, strlen(plug->name), scs);
- table->field[1]->store(C_STRING_WITH_LEN("NO"), scs);
+ table->field[1]->store(STRING_WITH_LEN("NO"), scs);
table->field[2]->store(plug->descr, strlen(plug->descr), scs);
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
@@ -6181,10 +6437,9 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
thd->security_ctx->priv_host, NullS);
/* We use this TABLE_LIST instance only for checking of privileges. */
bzero((char*) &proc_tables,sizeof(proc_tables));
- proc_tables.db= (char*) "mysql";
- proc_tables.db_length= 5;
- proc_tables.table_name= proc_tables.alias= (char*) "proc";
- proc_tables.table_name_length= 4;
+ proc_tables.db= MYSQL_SCHEMA_NAME;
+ proc_tables.table_name= MYSQL_PROC_NAME;
+ proc_tables.alias= MYSQL_PROC_NAME;
proc_tables.lock_type= TL_READ;
full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, FALSE,
1, TRUE);
@@ -6274,6 +6529,9 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
}
for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
{
+ if ((key_info->flags & HA_INVISIBLE_KEY) &&
+ DBUG_EVALUATE_IF("test_invisible_index", 0, 1))
+ continue;
KEY_PART_INFO *key_part= key_info->key_part;
LEX_CSTRING *str;
LEX_CSTRING unknown= {STRING_WITH_LEN("?unknown field?") };
@@ -6491,7 +6749,7 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
static bool
store_constraints(THD *thd, TABLE *table, const LEX_CSTRING *db_name,
const LEX_CSTRING *table_name, const char *key_name,
- uint key_len, const char *con_type, uint con_len)
+ size_t key_len, const char *con_type, size_t con_len)
{
CHARSET_INFO *cs= system_charset_info;
restore_record(table, s->default_values);
@@ -6687,7 +6945,7 @@ ret:
static void
store_key_column_usage(TABLE *table, const LEX_CSTRING *db_name,
const LEX_CSTRING *table_name, const char *key_name,
- uint key_len, const char *con_type, uint con_len,
+ size_t key_len, const char *con_type, size_t con_len,
longlong idx)
{
CHARSET_INFO *cs= system_charset_info;
@@ -6938,11 +7196,8 @@ static void store_schema_partitions_record(THD *thd, TABLE *schema_table,
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
-static int
-get_partition_column_description(THD *thd,
- partition_info *part_info,
- part_elem_value *list_value,
- String &tmp_str)
+static int get_partition_column_description(THD *thd, partition_info *part_info,
+ part_elem_value *list_value, String &tmp_str)
{
uint num_elements= part_info->part_field_list.elements;
uint i;
@@ -7046,6 +7301,9 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
tmp_res.append(STRING_WITH_LEN("HASH"));
table->field[7]->store(tmp_res.ptr(), tmp_res.length(), cs);
break;
+ case VERSIONING_PARTITION:
+ table->field[7]->store(STRING_WITH_LEN("SYSTEM_TIME"), cs);
+ break;
default:
DBUG_ASSERT(0);
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
@@ -7112,13 +7370,9 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
part_elem_value *list_value= list_val_it++;
tmp_str.length(0);
- if (get_partition_column_description(thd,
- part_info,
- list_value,
+ if (get_partition_column_description(thd, part_info, list_value,
tmp_str))
- {
DBUG_RETURN(1);
- }
table->field[11]->store(tmp_str.ptr(), tmp_str.length(), cs);
}
else
@@ -7149,13 +7403,9 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
{
if (part_info->part_field_list.elements > 1U)
tmp_str.append(STRING_WITH_LEN("("));
- if (get_partition_column_description(thd,
- part_info,
- list_value,
+ if (get_partition_column_description(thd, part_info, list_value,
tmp_str))
- {
DBUG_RETURN(1);
- }
if (part_info->part_field_list.elements > 1U)
tmp_str.append(")");
}
@@ -7173,6 +7423,19 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
table->field[11]->store(tmp_str.ptr(), tmp_str.length(), cs);
table->field[11]->set_notnull();
}
+ else if (part_info->part_type == VERSIONING_PARTITION)
+ {
+ if (part_elem == part_info->vers_info->now_part)
+ {
+ table->field[11]->store(STRING_WITH_LEN("CURRENT"), cs);
+ table->field[11]->set_notnull();
+ }
+ else if (part_info->vers_info->interval.is_set())
+ {
+ table->field[11]->store_timestamp((my_time_t)part_elem->range_value, 0);
+ table->field[11]->set_notnull();
+ }
+ }
if (part_elem->subpartitions.elements)
{
@@ -7405,7 +7668,7 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
TABLE *table= tables->table;
CHARSET_INFO *cs= system_charset_info;
OPEN_TABLE_LIST *open_list;
- if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
+ if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db.str, wild))
&& thd->is_fatal_error)
DBUG_RETURN(1);
@@ -7441,7 +7704,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
COND *partial_cond= make_cond_for_info_schema(thd, cond, tables);
- mysql_rwlock_rdlock(&LOCK_system_variables_hash);
+ mysql_prlock_rdlock(&LOCK_system_variables_hash);
/*
Avoid recursive LOCK_system_variables_hash acquisition in
@@ -7456,7 +7719,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, scope),
scope, NULL, "", tables->table,
upper_case_names, partial_cond);
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
DBUG_RETURN(res);
}
@@ -7625,7 +7888,8 @@ static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin,
if (!my_strcasecmp(system_charset_info,
schema_table->table_name,
- table_name)) {
+ table_name))
+ {
my_plugin_lock(thd, plugin);
p_schema_table->schema_table= schema_table;
DBUG_RETURN(1);
@@ -7636,7 +7900,7 @@ static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin,
/*
- Find schema_tables elment by name
+ Find schema_tables element by name
SYNOPSIS
find_schema_table()
@@ -7648,7 +7912,7 @@ static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin,
# pointer to 'schema_tables' element
*/
-ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name,
+ST_SCHEMA_TABLE *find_schema_table(THD *thd, const LEX_CSTRING *table_name,
bool *in_plugin)
{
schema_table_ref schema_table_a;
@@ -7660,12 +7924,12 @@ ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name,
{
if (!my_strcasecmp(system_charset_info,
schema_table->table_name,
- table_name))
+ table_name->str))
DBUG_RETURN(schema_table);
}
*in_plugin= true;
- schema_table_a.table_name= table_name;
+ schema_table_a.table_name= table_name->str;
if (plugin_foreach(thd, find_schema_table_in_plugin,
MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
DBUG_RETURN(schema_table_a.schema_table);
@@ -7715,7 +7979,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
for (; fields_info->field_name; fields_info++)
{
- uint field_name_length= strlen(fields_info->field_name);
+ size_t field_name_length= strlen(fields_info->field_name);
switch (fields_info->field_type) {
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_LONG:
@@ -7735,14 +7999,14 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
case MYSQL_TYPE_DATE:
if (!(item=new (mem_root)
Item_return_date_time(thd, fields_info->field_name,
- field_name_length,
+ (uint)field_name_length,
fields_info->field_type)))
DBUG_RETURN(0);
break;
case MYSQL_TYPE_TIME:
if (!(item=new (mem_root)
Item_return_date_time(thd, fields_info->field_name,
- field_name_length,
+ (uint)field_name_length,
fields_info->field_type)))
DBUG_RETURN(0);
break;
@@ -7750,8 +8014,9 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
case MYSQL_TYPE_DATETIME:
if (!(item=new (mem_root)
Item_return_date_time(thd, fields_info->field_name,
- field_name_length,
- fields_info->field_type)))
+ (uint)field_name_length,
+ fields_info->field_type,
+ fields_info->field_length)))
DBUG_RETURN(0);
item->decimals= fields_info->field_length;
break;
@@ -7825,7 +8090,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
field_list, (ORDER*) 0, 0, 0,
(select_lex->options | thd->variables.option_bits |
TMP_TABLE_ALL_COLUMNS), HA_POS_ERROR,
- table_list->alias, false, keep_row_order)))
+ &table_list->alias, false, keep_row_order)))
DBUG_RETURN(0);
my_bitmap_map* bitmaps=
(my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
@@ -7923,7 +8188,7 @@ int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
buffer.length(0);
buffer.append(field_info->old_name);
- buffer.append(lex->select_lex.db);
+ buffer.append(&lex->select_lex.db);
if (lex->wild && lex->wild->ptr())
{
buffer.append(STRING_WITH_LEN(" ("));
@@ -8065,12 +8330,11 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
views
working correctly
*/
- if (table_list->schema_table_name)
+ if (table_list->schema_table_name.str)
table->alias_name_used= my_strcasecmp(table_alias_charset,
- table_list->schema_table_name,
- table_list->alias);
- table_list->table_name= table->s->table_name.str;
- table_list->table_name_length= table->s->table_name.length;
+ table_list->schema_table_name.str,
+ table_list->alias.str);
+ table_list->table_name= table->s->table_name;
table_list->table= table;
table->next= thd->derived_tables;
thd->derived_tables= table;
@@ -8471,7 +8735,7 @@ int hton_fill_schema_table(THD *thd, TABLE_LIST *tables, COND *cond)
static
int store_key_cache_table_record(THD *thd, TABLE *table,
- const char *name, uint name_length,
+ const char *name, size_t name_length,
KEY_CACHE *key_cache,
uint partitions, uint partition_no)
{
@@ -8604,6 +8868,9 @@ ST_FIELD_INFO tables_fields_info[]=
OPEN_FULL_TABLE},
{"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0,
"Comment", OPEN_FRM_ONLY},
+ {"MAX_INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_index_length", OPEN_FULL_TABLE},
+ {"TEMPORARY", 1, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, "Temporary", OPEN_FRM_ONLY},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
@@ -9566,7 +9833,7 @@ static bool show_create_trigger_impl(THD *thd, Trigger *trigger)
fields.push_back(new (mem_root) Item_empty_string(thd, "Trigger", NAME_LEN),
mem_root);
fields.push_back(new (mem_root)
- Item_empty_string(thd, "sql_mode", trg_sql_mode_str.length),
+ Item_empty_string(thd, "sql_mode", (uint)trg_sql_mode_str.length),
mem_root);
{
@@ -9577,7 +9844,7 @@ static bool show_create_trigger_impl(THD *thd, Trigger *trigger)
Item_empty_string *stmt_fld=
new (mem_root) Item_empty_string(thd, "SQL Original Statement",
- MY_MAX(trg_sql_original_stmt.length,
+ (uint)MY_MAX(trg_sql_original_stmt.length,
1024));
stmt_fld->maybe_null= TRUE;
@@ -9687,12 +9954,12 @@ static
TABLE_LIST *get_trigger_table(THD *thd, const sp_name *trg_name)
{
char trn_path_buff[FN_REFLEN];
- LEX_STRING trn_path= { trn_path_buff, 0 };
+ LEX_CSTRING trn_path= { trn_path_buff, 0 };
LEX_CSTRING db;
LEX_CSTRING tbl_name;
TABLE_LIST *table;
- build_trn_path(thd, trg_name, &trn_path);
+ build_trn_path(thd, trg_name, (LEX_STRING*) &trn_path);
if (check_trn_exists(&trn_path))
{
@@ -9700,8 +9967,7 @@ TABLE_LIST *get_trigger_table(THD *thd, const sp_name *trg_name)
return NULL;
}
- if (load_table_name_for_trigger(thd, trg_name, (LEX_CSTRING*) &trn_path,
- &tbl_name))
+ if (load_table_name_for_trigger(thd, trg_name, &trn_path, &tbl_name))
return NULL;
/* We need to reset statement table list to be PS/SP friendly. */
@@ -9719,8 +9985,7 @@ TABLE_LIST *get_trigger_table(THD *thd, const sp_name *trg_name)
if (db.str == NULL || tbl_name.str == NULL)
return NULL;
- table->init_one_table(db.str, db.length, tbl_name.str, tbl_name.length,
- tbl_name.str, TL_IGNORE);
+ table->init_one_table(&db, &tbl_name, 0, TL_IGNORE);
return table;
}
@@ -9768,7 +10033,7 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name)
{
my_error(ER_TRG_CANT_OPEN_TABLE, MYF(0),
(const char *) trg_name->m_db.str,
- (const char *) lst->table_name);
+ (const char *) lst->table_name.str);
goto exit;
@@ -9789,8 +10054,7 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name)
{
my_error(ER_TRG_CORRUPTED_FILE, MYF(0),
(const char *) trg_name->m_db.str,
- (const char *) lst->table_name);
-
+ (const char *) lst->table_name.str);
goto exit;
}
diff --git a/sql/sql_show.h b/sql/sql_show.h
index dc2fe9738fe..f6d5d4d2c3c 100644
--- a/sql/sql_show.h
+++ b/sql/sql_show.h
@@ -82,8 +82,11 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
int copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table);
-bool append_identifier(THD *thd, String *packet, const char *name,
- uint length);
+bool append_identifier(THD *thd, String *packet, const char *name, size_t length);
+static inline bool append_identifier(THD *thd, String *packet, const LEX_CSTRING *name)
+{
+ return append_identifier(thd, packet, name->str, name->length);
+}
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd);
bool mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list,
@@ -118,8 +121,9 @@ bool schema_table_store_record(THD *thd, TABLE *table);
void initialize_information_schema_acl();
COND *make_cond_for_info_schema(THD *thd, COND *cond, TABLE_LIST *table);
-ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name, bool *in_plugin);
-static inline ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
+ST_SCHEMA_TABLE *find_schema_table(THD *thd, const LEX_CSTRING *table_name,
+ bool *in_plugin);
+static inline ST_SCHEMA_TABLE *find_schema_table(THD *thd, const LEX_CSTRING *table_name)
{ bool unused; return find_schema_table(thd, table_name, &unused); }
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx);
@@ -138,7 +142,7 @@ const char* get_one_variable(THD *thd, const SHOW_VAR *variable,
size_t *length);
/* These functions were under INNODB_COMPATIBILITY_HOOKS */
-int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
+int get_quote_char_for_identifier(THD *thd, const char *name, size_t length);
THD *find_thread_by_id(longlong id, bool query_id= false);
class select_result_explain_buffer;
@@ -199,6 +203,9 @@ typedef struct st_lookup_field_values
bool wild_table_value;
} LOOKUP_FIELD_VALUES;
+int make_table_name_list(THD *thd, Dynamic_array<LEX_CSTRING *> *table_names,
+ LEX *lex, LOOKUP_FIELD_VALUES *lookup_field_vals,
+ LEX_CSTRING *db_name);
/*
INFORMATION_SCHEMA: Execution plan for get_all_tables() call
diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc
index 1e1c2c1d624..1da8b145151 100644
--- a/sql/sql_signal.cc
+++ b/sql/sql_signal.cc
@@ -29,38 +29,38 @@
*/
#define MAX_MYSQL_ERRNO 65534
-const LEX_STRING Diag_condition_item_names[]=
+const LEX_CSTRING Diag_condition_item_names[]=
{
- { C_STRING_WITH_LEN("CLASS_ORIGIN") },
- { C_STRING_WITH_LEN("SUBCLASS_ORIGIN") },
- { C_STRING_WITH_LEN("CONSTRAINT_CATALOG") },
- { C_STRING_WITH_LEN("CONSTRAINT_SCHEMA") },
- { C_STRING_WITH_LEN("CONSTRAINT_NAME") },
- { C_STRING_WITH_LEN("CATALOG_NAME") },
- { C_STRING_WITH_LEN("SCHEMA_NAME") },
- { C_STRING_WITH_LEN("TABLE_NAME") },
- { C_STRING_WITH_LEN("COLUMN_NAME") },
- { C_STRING_WITH_LEN("CURSOR_NAME") },
- { C_STRING_WITH_LEN("MESSAGE_TEXT") },
- { C_STRING_WITH_LEN("MYSQL_ERRNO") },
-
- { C_STRING_WITH_LEN("CONDITION_IDENTIFIER") },
- { C_STRING_WITH_LEN("CONDITION_NUMBER") },
- { C_STRING_WITH_LEN("CONNECTION_NAME") },
- { C_STRING_WITH_LEN("MESSAGE_LENGTH") },
- { C_STRING_WITH_LEN("MESSAGE_OCTET_LENGTH") },
- { C_STRING_WITH_LEN("PARAMETER_MODE") },
- { C_STRING_WITH_LEN("PARAMETER_NAME") },
- { C_STRING_WITH_LEN("PARAMETER_ORDINAL_POSITION") },
- { C_STRING_WITH_LEN("RETURNED_SQLSTATE") },
- { C_STRING_WITH_LEN("ROUTINE_CATALOG") },
- { C_STRING_WITH_LEN("ROUTINE_NAME") },
- { C_STRING_WITH_LEN("ROUTINE_SCHEMA") },
- { C_STRING_WITH_LEN("SERVER_NAME") },
- { C_STRING_WITH_LEN("SPECIFIC_NAME") },
- { C_STRING_WITH_LEN("TRIGGER_CATALOG") },
- { C_STRING_WITH_LEN("TRIGGER_NAME") },
- { C_STRING_WITH_LEN("TRIGGER_SCHEMA") }
+ { STRING_WITH_LEN("CLASS_ORIGIN") },
+ { STRING_WITH_LEN("SUBCLASS_ORIGIN") },
+ { STRING_WITH_LEN("CONSTRAINT_CATALOG") },
+ { STRING_WITH_LEN("CONSTRAINT_SCHEMA") },
+ { STRING_WITH_LEN("CONSTRAINT_NAME") },
+ { STRING_WITH_LEN("CATALOG_NAME") },
+ { STRING_WITH_LEN("SCHEMA_NAME") },
+ { STRING_WITH_LEN("TABLE_NAME") },
+ { STRING_WITH_LEN("COLUMN_NAME") },
+ { STRING_WITH_LEN("CURSOR_NAME") },
+ { STRING_WITH_LEN("MESSAGE_TEXT") },
+ { STRING_WITH_LEN("MYSQL_ERRNO") },
+
+ { STRING_WITH_LEN("CONDITION_IDENTIFIER") },
+ { STRING_WITH_LEN("CONDITION_NUMBER") },
+ { STRING_WITH_LEN("CONNECTION_NAME") },
+ { STRING_WITH_LEN("MESSAGE_LENGTH") },
+ { STRING_WITH_LEN("MESSAGE_OCTET_LENGTH") },
+ { STRING_WITH_LEN("PARAMETER_MODE") },
+ { STRING_WITH_LEN("PARAMETER_NAME") },
+ { STRING_WITH_LEN("PARAMETER_ORDINAL_POSITION") },
+ { STRING_WITH_LEN("RETURNED_SQLSTATE") },
+ { STRING_WITH_LEN("ROUTINE_CATALOG") },
+ { STRING_WITH_LEN("ROUTINE_NAME") },
+ { STRING_WITH_LEN("ROUTINE_SCHEMA") },
+ { STRING_WITH_LEN("SERVER_NAME") },
+ { STRING_WITH_LEN("SPECIFIC_NAME") },
+ { STRING_WITH_LEN("TRIGGER_CATALOG") },
+ { STRING_WITH_LEN("TRIGGER_NAME") },
+ { STRING_WITH_LEN("TRIGGER_SCHEMA") }
};
@@ -210,7 +210,7 @@ int Sql_cmd_common_signal::eval_signal_informations(THD *thd, Sql_condition *con
int result= 1;
enum enum_diag_condition_item_name item_enum;
String *member;
- const LEX_STRING *name;
+ const LEX_CSTRING *name;
DBUG_ENTER("Sql_cmd_common_signal::eval_signal_informations");
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 2cb47634fe4..26fdce12e7f 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -65,16 +65,13 @@ static const uint STATISTICS_TABLES= 3;
The names of the statistical tables in this array must correspond the
definitions of the tables in the file ../scripts/mysql_system_tables.sql
*/
-static const LEX_STRING stat_table_name[STATISTICS_TABLES]=
+static const LEX_CSTRING stat_table_name[STATISTICS_TABLES]=
{
- { C_STRING_WITH_LEN("table_stats") },
- { C_STRING_WITH_LEN("column_stats") },
- { C_STRING_WITH_LEN("index_stats") }
+ { STRING_WITH_LEN("table_stats") },
+ { STRING_WITH_LEN("column_stats") },
+ { STRING_WITH_LEN("index_stats") }
};
-/* Name of database to which the statistical tables belong */
-static const LEX_STRING stat_tables_db_name= { C_STRING_WITH_LEN("mysql") };
-
/**
@details
@@ -93,10 +90,9 @@ inline void init_table_list_for_stat_tables(TABLE_LIST *tables, bool for_write)
for (i= 0; i < STATISTICS_TABLES; i++)
{
- tables[i].db= stat_tables_db_name.str;
- tables[i].db_length= stat_tables_db_name.length;
- tables[i].alias= tables[i].table_name= stat_table_name[i].str;
- tables[i].table_name_length= stat_table_name[i].length;
+ tables[i].db= MYSQL_SCHEMA_NAME;
+ tables[i].table_name= stat_table_name[i];
+ tables[i].alias= stat_table_name[i];
tables[i].lock_type= for_write ? TL_WRITE : TL_READ;
if (i < STATISTICS_TABLES - 1)
tables[i].next_global= tables[i].next_local=
@@ -115,17 +111,16 @@ inline void init_table_list_for_stat_tables(TABLE_LIST *tables, bool for_write)
otherwise it is set to TL_WRITE.
*/
-static
-inline void init_table_list_for_single_stat_table(TABLE_LIST *tbl,
- const LEX_STRING *stat_tab_name,
- bool for_write)
+static inline
+void init_table_list_for_single_stat_table(TABLE_LIST *tbl,
+ const LEX_CSTRING *stat_tab_name,
+ bool for_write)
{
memset((char *) tbl, 0, sizeof(TABLE_LIST));
- tbl->db= stat_tables_db_name.str;
- tbl->db_length= stat_tables_db_name.length;
- tbl->alias= tbl->table_name= stat_tab_name->str;
- tbl->table_name_length= stat_tab_name->length;
+ tbl->db= MYSQL_SCHEMA_NAME;
+ tbl->table_name= *stat_tab_name;
+ tbl->alias= *stat_tab_name;
tbl->lock_type= for_write ? TL_WRITE : TL_READ;
}
@@ -136,18 +131,18 @@ static const
TABLE_FIELD_TYPE table_stat_fields[TABLE_STAT_N_FIELDS] =
{
{
- { C_STRING_WITH_LEN("db_name") },
- { C_STRING_WITH_LEN("varchar(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("db_name") },
+ { STRING_WITH_LEN("varchar(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("table_name") },
- { C_STRING_WITH_LEN("varchar(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("table_name") },
+ { STRING_WITH_LEN("varchar(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("cardinality") },
- { C_STRING_WITH_LEN("bigint(21)") },
+ { STRING_WITH_LEN("cardinality") },
+ { STRING_WITH_LEN("bigint(21)") },
{ NULL, 0 }
},
};
@@ -159,58 +154,58 @@ static const
TABLE_FIELD_TYPE column_stat_fields[COLUMN_STAT_N_FIELDS] =
{
{
- { C_STRING_WITH_LEN("db_name") },
- { C_STRING_WITH_LEN("varchar(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("db_name") },
+ { STRING_WITH_LEN("varchar(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("table_name") },
- { C_STRING_WITH_LEN("varchar(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("table_name") },
+ { STRING_WITH_LEN("varchar(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("column_name") },
- { C_STRING_WITH_LEN("varchar(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("column_name") },
+ { STRING_WITH_LEN("varchar(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("min_value") },
- { C_STRING_WITH_LEN("varbinary(255)") },
+ { STRING_WITH_LEN("min_value") },
+ { STRING_WITH_LEN("varbinary(255)") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("max_value") },
- { C_STRING_WITH_LEN("varbinary(255)") },
+ { STRING_WITH_LEN("max_value") },
+ { STRING_WITH_LEN("varbinary(255)") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("nulls_ratio") },
- { C_STRING_WITH_LEN("decimal(12,4)") },
+ { STRING_WITH_LEN("nulls_ratio") },
+ { STRING_WITH_LEN("decimal(12,4)") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("avg_length") },
- { C_STRING_WITH_LEN("decimal(12,4)") },
+ { STRING_WITH_LEN("avg_length") },
+ { STRING_WITH_LEN("decimal(12,4)") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("avg_frequency") },
- { C_STRING_WITH_LEN("decimal(12,4)") },
+ { STRING_WITH_LEN("avg_frequency") },
+ { STRING_WITH_LEN("decimal(12,4)") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("hist_size") },
- { C_STRING_WITH_LEN("tinyint(3)") },
+ { STRING_WITH_LEN("hist_size") },
+ { STRING_WITH_LEN("tinyint(3)") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("hist_type") },
- { C_STRING_WITH_LEN("enum('SINGLE_PREC_HB','DOUBLE_PREC_HB')") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("hist_type") },
+ { STRING_WITH_LEN("enum('SINGLE_PREC_HB','DOUBLE_PREC_HB')") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("histogram") },
- { C_STRING_WITH_LEN("varbinary(255)") },
+ { STRING_WITH_LEN("histogram") },
+ { STRING_WITH_LEN("varbinary(255)") },
{ NULL, 0 }
}
};
@@ -222,28 +217,28 @@ static const
TABLE_FIELD_TYPE index_stat_fields[INDEX_STAT_N_FIELDS] =
{
{
- { C_STRING_WITH_LEN("db_name") },
- { C_STRING_WITH_LEN("varchar(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("db_name") },
+ { STRING_WITH_LEN("varchar(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("table_name") },
- { C_STRING_WITH_LEN("varchar(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("table_name") },
+ { STRING_WITH_LEN("varchar(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("index") },
- { C_STRING_WITH_LEN("varchar(64)") },
- { C_STRING_WITH_LEN("utf8") }
+ { STRING_WITH_LEN("index") },
+ { STRING_WITH_LEN("varchar(64)") },
+ { STRING_WITH_LEN("utf8") }
},
{
- { C_STRING_WITH_LEN("prefix_arity") },
- { C_STRING_WITH_LEN("int(11)") },
+ { STRING_WITH_LEN("prefix_arity") },
+ { STRING_WITH_LEN("int(11)") },
{ NULL, 0 }
},
{
- { C_STRING_WITH_LEN("avg_frequency") },
- { C_STRING_WITH_LEN("decimal(12,4)") },
+ { STRING_WITH_LEN("avg_frequency") },
+ { STRING_WITH_LEN("decimal(12,4)") },
{ NULL, 0 }
}
};
@@ -294,7 +289,7 @@ inline int open_stat_tables(THD *thd, TABLE_LIST *tables,
*/
static
inline int open_single_stat_table(THD *thd, TABLE_LIST *table,
- const LEX_STRING *stat_tab_name,
+ const LEX_CSTRING *stat_tab_name,
Open_tables_backup *backup,
bool for_write)
{
@@ -472,8 +467,8 @@ protected:
/* Table for which statistical data is read / updated */
TABLE *table;
TABLE_SHARE *table_share; /* Table share for 'table */
- LEX_CSTRING *db_name; /* Name of the database containing 'table' */
- LEX_CSTRING *table_name; /* Name of the table 'table' */
+ const LEX_CSTRING *db_name; /* Name of the database containing 'table' */
+ const LEX_CSTRING *table_name; /* Name of the table 'table' */
void store_record_for_update()
{
@@ -528,12 +523,10 @@ public:
by the database name 'db' and the table name 'tab'.
*/
- Stat_table(TABLE *stat, LEX_CSTRING *db, LEX_CSTRING *tab)
- :stat_table(stat), table_share(NULL)
+ Stat_table(TABLE *stat, const LEX_CSTRING *db, const LEX_CSTRING *tab)
+ :stat_table(stat), table_share(NULL),db_name(db), table_name(tab)
{
common_init_stat_table();
- db_name= db;
- table_name= tab;
}
@@ -553,7 +546,7 @@ public:
The method is called by the update_table_name_key_parts function.
*/
- virtual void change_full_table_name(LEX_CSTRING *db, LEX_CSTRING *tab)= 0;
+ virtual void change_full_table_name(const LEX_CSTRING *db, const LEX_CSTRING *tab)= 0;
/**
@@ -709,7 +702,7 @@ public:
to store the new names in the record buffer used for updates.
*/
- bool update_table_name_key_parts(LEX_CSTRING *db, LEX_CSTRING *tab)
+ bool update_table_name_key_parts(const LEX_CSTRING *db, const LEX_CSTRING *tab)
{
store_record_for_update();
change_full_table_name(db, tab);
@@ -771,7 +764,7 @@ private:
table_name_field= stat_table->field[TABLE_STAT_TABLE_NAME];
}
- void change_full_table_name(LEX_CSTRING *db, LEX_CSTRING *tab)
+ void change_full_table_name(const LEX_CSTRING *db, const LEX_CSTRING *tab)
{
db_name_field->store(db->str, db->length, system_charset_info);
table_name_field->store(tab->str, tab->length, system_charset_info);
@@ -801,7 +794,7 @@ public:
from the database 'db'.
*/
- Table_stat(TABLE *stat, LEX_CSTRING *db, LEX_CSTRING *tab)
+ Table_stat(TABLE *stat, const LEX_CSTRING *db, const LEX_CSTRING *tab)
:Stat_table(stat, db, tab)
{
common_init_table_stat();
@@ -915,7 +908,7 @@ private:
column_name_field= stat_table->field[COLUMN_STAT_COLUMN_NAME];
}
- void change_full_table_name(LEX_CSTRING *db, LEX_CSTRING *tab)
+ void change_full_table_name(const LEX_CSTRING *db, const LEX_CSTRING *tab)
{
db_name_field->store(db->str, db->length, system_charset_info);
table_name_field->store(tab->str, tab->length, system_charset_info);
@@ -945,7 +938,7 @@ public:
from the database 'db'.
*/
- Column_stat(TABLE *stat, LEX_CSTRING *db, LEX_CSTRING *tab)
+ Column_stat(TABLE *stat, const LEX_CSTRING *db, const LEX_CSTRING *tab)
:Stat_table(stat, db, tab)
{
common_init_column_stat_table();
@@ -1250,7 +1243,7 @@ private:
prefix_arity_field= stat_table->field[INDEX_STAT_PREFIX_ARITY];
}
- void change_full_table_name(LEX_CSTRING *db, LEX_CSTRING *tab)
+ void change_full_table_name(const LEX_CSTRING *db, const LEX_CSTRING *tab)
{
db_name_field->store(db->str, db->length, system_charset_info);
table_name_field->store(tab->str, tab->length, system_charset_info);
@@ -1282,7 +1275,7 @@ public:
from the database 'db'.
*/
- Index_stat(TABLE *stat, LEX_CSTRING *db, LEX_CSTRING *tab)
+ Index_stat(TABLE *stat, const LEX_CSTRING *db, const LEX_CSTRING *tab)
:Stat_table(stat, db, tab)
{
common_init_index_stat_table();
@@ -3526,8 +3519,8 @@ int delete_statistics_for_index(THD *thd, TABLE *tab, KEY *key_info,
The function is called when executing any statement that renames a table
*/
-int rename_table_in_stat_tables(THD *thd, LEX_CSTRING *db, LEX_CSTRING *tab,
- LEX_CSTRING *new_db, LEX_CSTRING *new_tab)
+int rename_table_in_stat_tables(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *tab,
+ const LEX_CSTRING *new_db, const LEX_CSTRING *new_tab)
{
int err;
enum_binlog_format save_binlog_format;
@@ -3535,7 +3528,6 @@ int rename_table_in_stat_tables(THD *thd, LEX_CSTRING *db, LEX_CSTRING *tab,
TABLE_LIST tables[STATISTICS_TABLES];
Open_tables_backup open_tables_backup;
int rc= 0;
-
DBUG_ENTER("rename_table_in_stat_tables");
if (open_stat_tables(thd, tables, &open_tables_backup, TRUE))
@@ -3984,18 +3976,17 @@ double Histogram::point_selectivity(double pos, double avg_sel)
/*
Check whether the table is one of the persistent statistical tables.
*/
-bool is_stat_table(const char *db, const char *table)
+bool is_stat_table(const LEX_CSTRING *db, LEX_CSTRING *table)
{
- DBUG_ASSERT(db && table);
+ DBUG_ASSERT(db->str && table->str);
- if (!memcmp(db, stat_tables_db_name.str, stat_tables_db_name.length))
+ if (!cmp(db, &MYSQL_SCHEMA_NAME))
{
for (uint i= 0; i < STATISTICS_TABLES; i ++)
{
- if (!memcmp(table, stat_table_name[i].str, stat_table_name[i].length))
+ if (cmp(table, &stat_table_name[i]) == 0)
return true;
}
}
return false;
}
-
diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h
index eb59b149753..7ec742b70db 100644
--- a/sql/sql_statistics.h
+++ b/sql/sql_statistics.h
@@ -98,8 +98,8 @@ int delete_statistics_for_table(THD *thd, LEX_CSTRING *db, LEX_CSTRING *tab);
int delete_statistics_for_column(THD *thd, TABLE *tab, Field *col);
int delete_statistics_for_index(THD *thd, TABLE *tab, KEY *key_info,
bool ext_prefixes_only);
-int rename_table_in_stat_tables(THD *thd, LEX_CSTRING *db, LEX_CSTRING *tab,
- LEX_CSTRING *new_db, LEX_CSTRING *new_tab);
+int rename_table_in_stat_tables(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *tab,
+ const LEX_CSTRING *new_db, const LEX_CSTRING *new_tab);
int rename_column_in_stat_tables(THD *thd, TABLE *tab, Field *col,
const char *new_name);
void set_statistics_for_table(THD *thd, TABLE *table);
@@ -110,7 +110,7 @@ double get_column_range_cardinality(Field *field,
key_range *min_endp,
key_range *max_endp,
uint range_flag);
-bool is_stat_table(const char *db, const char *table);
+bool is_stat_table(const LEX_CSTRING *db, LEX_CSTRING *table);
class Histogram
{
@@ -255,18 +255,6 @@ public:
class Columns_statistics;
class Index_statistics;
-static inline
-int rename_table_in_stat_tables(THD *thd, const char *db, const char *tab,
- const char *new_db, const char *new_tab)
-{
- LEX_CSTRING od= { db, strlen(db) };
- LEX_CSTRING ot= { tab, strlen(tab) };
- LEX_CSTRING nd= { new_db, strlen(new_db) };
- LEX_CSTRING nt= { new_tab, strlen(new_tab) };
- return rename_table_in_stat_tables(thd, &od, &ot, &nd, &nt);
-}
-
-
/* Statistical data on a table */
class Table_statistics
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 70ddf7b1241..390abe36b6c 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -240,8 +240,8 @@ bool String::copy(const char *str,size_t arg_length, CHARSET_INFO *cs)
{
if (alloc(arg_length))
return TRUE;
- DBUG_ASSERT(arg_length < UINT_MAX32);
- if ((str_length=arg_length))
+ DBUG_ASSERT(arg_length <= UINT_MAX32);
+ if ((str_length=(uint32)arg_length))
memcpy(Ptr,str,arg_length);
Ptr[arg_length]=0;
str_charset=cs;
@@ -271,7 +271,7 @@ bool String::copy(const char *str,size_t arg_length, CHARSET_INFO *cs)
character_set_results is NULL.
*/
-bool String::needs_conversion(uint32 arg_length,
+bool String::needs_conversion(size_t arg_length,
CHARSET_INFO *from_cs,
CHARSET_INFO *to_cs,
uint32 *offset)
@@ -282,7 +282,7 @@ bool String::needs_conversion(uint32 arg_length,
(to_cs == from_cs) ||
my_charset_same(from_cs, to_cs) ||
((from_cs == &my_charset_bin) &&
- (!(*offset=(arg_length % to_cs->mbminlen)))))
+ (!(*offset=(uint32)(arg_length % to_cs->mbminlen)))))
return FALSE;
return TRUE;
}
@@ -300,7 +300,7 @@ bool String::needs_conversion(uint32 arg_length,
@return conversion needed
*/
-bool String::needs_conversion_on_storage(uint32 arg_length,
+bool String::needs_conversion_on_storage(size_t arg_length,
CHARSET_INFO *cs_from,
CHARSET_INFO *cs_to)
{
@@ -349,14 +349,14 @@ bool String::needs_conversion_on_storage(uint32 arg_length,
1 error
*/
-bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset,
+bool String::copy_aligned(const char *str, size_t arg_length, size_t offset,
CHARSET_INFO *cs)
{
/* How many bytes are in incomplete character */
offset= cs->mbminlen - offset; /* How many zeros we should prepend */
DBUG_ASSERT(offset && offset != cs->mbminlen);
- uint32 aligned_length= arg_length + offset;
+ size_t aligned_length= arg_length + offset;
if (alloc(aligned_length))
return TRUE;
@@ -369,17 +369,17 @@ bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset,
memcpy(Ptr + offset, str, arg_length);
Ptr[aligned_length]=0;
/* str_length is always >= 0 as arg_length is != 0 */
- str_length= aligned_length;
+ str_length= (uint32)aligned_length;
str_charset= cs;
return FALSE;
}
-bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
+bool String::set_or_copy_aligned(const char *str, size_t arg_length,
CHARSET_INFO *cs)
{
/* How many bytes are in incomplete character */
- uint32 offset= (arg_length % cs->mbminlen);
+ size_t offset= (arg_length % cs->mbminlen);
if (!offset) /* All characters are complete, just copy */
{
@@ -400,7 +400,7 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
*/
-bool String::copy(const char *str, uint32 arg_length,
+bool String::copy(const char *str, size_t arg_length,
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors)
{
uint32 offset;
@@ -417,7 +417,7 @@ bool String::copy(const char *str, uint32 arg_length,
*errors= 0;
return copy_aligned(str, arg_length, offset, to_cs);
}
- uint32 new_length= to_cs->mbmaxlen*arg_length;
+ size_t new_length= to_cs->mbmaxlen*arg_length;
if (alloc(new_length))
return TRUE;
str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
@@ -446,7 +446,7 @@ bool String::copy(const char *str, uint32 arg_length,
*/
-bool String::set_ascii(const char *str, uint32 arg_length)
+bool String::set_ascii(const char *str, size_t arg_length)
{
if (str_charset->mbminlen == 1)
{
@@ -454,7 +454,7 @@ bool String::set_ascii(const char *str, uint32 arg_length)
return 0;
}
uint dummy_errors;
- return copy(str, arg_length, &my_charset_latin1, str_charset, &dummy_errors);
+ return copy(str, (uint32)arg_length, &my_charset_latin1, str_charset, &dummy_errors);
}
@@ -563,13 +563,13 @@ bool String::append_ulonglong(ulonglong val)
with character set recoding
*/
-bool String::append(const char *s, uint arg_length, CHARSET_INFO *cs)
+bool String::append(const char *s, size_t arg_length, CHARSET_INFO *cs)
{
uint32 offset;
- if (needs_conversion(arg_length, cs, str_charset, &offset))
+ if (needs_conversion((uint32)arg_length, cs, str_charset, &offset))
{
- uint32 add_length;
+ size_t add_length;
if ((cs == &my_charset_bin) && offset)
{
DBUG_ASSERT(str_charset->mbminlen > offset);
@@ -579,7 +579,7 @@ bool String::append(const char *s, uint arg_length, CHARSET_INFO *cs)
return TRUE;
bzero((char*) Ptr + str_length, offset);
memcpy(Ptr + str_length + offset, s, arg_length);
- str_length+= add_length;
+ str_length+= (uint32)add_length;
return FALSE;
}
@@ -587,15 +587,15 @@ bool String::append(const char *s, uint arg_length, CHARSET_INFO *cs)
uint dummy_errors;
if (realloc_with_extra_if_needed(str_length + add_length))
return TRUE;
- str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
- s, arg_length, cs, &dummy_errors);
+ str_length+= copy_and_convert(Ptr+str_length, (uint32)add_length, str_charset,
+ s, (uint32)arg_length, cs, &dummy_errors);
}
else
{
if (realloc_with_extra_if_needed(str_length + arg_length))
return TRUE;
memcpy(Ptr + str_length, s, arg_length);
- str_length+= arg_length;
+ str_length+= (uint32)arg_length;
}
return FALSE;
}
@@ -606,7 +606,7 @@ bool String::append(IO_CACHE* file, uint32 arg_length)
return TRUE;
if (my_b_read(file, (uchar*) Ptr + str_length, arg_length))
{
- shrink(str_length);
+ shrink(str_length ? str_length : 1);
return TRUE;
}
str_length+=arg_length;
@@ -760,7 +760,7 @@ bool String::replace(uint32 offset,uint32 arg_length,
// added by Holyfoot for "geometry" needs
-int String::reserve(uint32 space_needed, uint32 grow_by)
+int String::reserve(size_t space_needed, size_t grow_by)
{
if (Alloced_length < str_length + space_needed)
{
@@ -770,10 +770,10 @@ int String::reserve(uint32 space_needed, uint32 grow_by)
return FALSE;
}
-void String::qs_append(const char *str, uint32 len)
+void String::qs_append(const char *str, size_t len)
{
memcpy(Ptr + str_length, str, len + 1);
- str_length += len;
+ str_length += (uint32)len;
}
void String::qs_append(double d)
@@ -1072,10 +1072,9 @@ my_copy_with_hex_escaping(CHARSET_INFO *cs,
*/
uint
String_copier::well_formed_copy(CHARSET_INFO *to_cs,
- char *to, uint to_length,
+ char *to, size_t to_length,
CHARSET_INFO *from_cs,
- const char *from, uint from_length,
- uint nchars)
+ const char *from, size_t from_length, size_t nchars)
{
if ((to_cs == &my_charset_bin) ||
(from_cs == &my_charset_bin) ||
@@ -1098,7 +1097,7 @@ String_copier::well_formed_copy(CHARSET_INFO *to_cs,
Does not add the enclosing quotes, this is left up to caller.
*/
#define APPEND(X) if (append(X)) return 1; else break
-bool String::append_for_single_quote(const char *st, uint len)
+bool String::append_for_single_quote(const char *st, size_t len)
{
const char *end= st+len;
for (; st < end; st++)
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 41d31dc33c2..5cabcc02aae 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -3,7 +3,7 @@
/*
Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2017, MariaDB Corporation.
+ Copyright (c) 2008, 2018, 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
@@ -35,12 +35,12 @@ typedef struct st_mem_root MEM_ROOT;
#include "pack.h"
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
-inline uint32 copy_and_convert(char *to, uint32 to_length,
+inline uint32 copy_and_convert(char *to, size_t to_length,
CHARSET_INFO *to_cs,
- const char *from, uint32 from_length,
+ const char *from, size_t from_length,
CHARSET_INFO *from_cs, uint *errors)
{
- return my_convert(to, to_length, to_cs, from, from_length, from_cs, errors);
+ return my_convert(to, (uint)to_length, to_cs, from, (uint)from_length, from_cs, errors);
}
@@ -97,9 +97,8 @@ public:
Convert a string between character sets.
"dstcs" and "srccs" cannot be &my_charset_bin.
*/
- size_t convert_fix(CHARSET_INFO *dstcs, char *dst, uint dst_length,
- CHARSET_INFO *srccs, const char *src, uint src_length,
- uint nchars)
+ size_t convert_fix(CHARSET_INFO *dstcs, char *dst, size_t dst_length,
+ CHARSET_INFO *srccs, const char *src, size_t src_length, size_t nchars)
{
return my_convert_fix(dstcs, dst, dst_length,
srccs, src, src_length, nchars, this, this);
@@ -107,13 +106,11 @@ public:
/*
Copy a string. Fix bad bytes/characters to '?'.
*/
- uint well_formed_copy(CHARSET_INFO *to_cs, char *to, uint to_length,
- CHARSET_INFO *from_cs, const char *from,
- uint from_length, uint nchars);
+ uint well_formed_copy(CHARSET_INFO *to_cs, char *to, size_t to_length,
+ CHARSET_INFO *from_cs, const char *from, size_t from_length, size_t nchars);
// Same as above, but without the "nchars" limit.
- uint well_formed_copy(CHARSET_INFO *to_cs, char *to, uint to_length,
- CHARSET_INFO *from_cs, const char *from,
- uint from_length)
+ uint well_formed_copy(CHARSET_INFO *to_cs, char *to, size_t to_length,
+ CHARSET_INFO *from_cs, const char *from, size_t from_length)
{
return well_formed_copy(to_cs, to, to_length,
from_cs, from, from_length,
@@ -142,7 +139,7 @@ public:
alloced= thread_specific= 0;
str_charset= &my_charset_bin;
}
- String(uint32 length_arg)
+ String(size_t length_arg)
{
alloced= thread_specific= 0;
Alloced_length= extra_alloc= 0; (void) real_alloc(length_arg);
@@ -160,15 +157,15 @@ public:
contructors need the size of memory for STR to be at least LEN+1 (to make
room for zero termination).
*/
- String(const char *str,uint32 len, CHARSET_INFO *cs)
+ String(const char *str,size_t len, CHARSET_INFO *cs)
{
- Ptr=(char*) str; str_length=len; Alloced_length= extra_alloc=0;
+ Ptr=(char*) str; str_length=(uint32)len; Alloced_length= extra_alloc=0;
alloced= thread_specific= 0;
str_charset=cs;
}
- String(char *str,uint32 len, CHARSET_INFO *cs)
+ String(char *str,size_t len, CHARSET_INFO *cs)
{
- Ptr=(char*) str; Alloced_length=str_length=len; extra_alloc= 0;
+ Ptr=(char*) str; Alloced_length=str_length=(uint32)len; extra_alloc= 0;
alloced= thread_specific= 0;
str_charset=cs;
}
@@ -180,18 +177,19 @@ public:
str_charset=str.str_charset;
}
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
- { return (void*) alloc_root(mem_root, (uint) size); }
+ { return (void*) alloc_root(mem_root, size); }
static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
{ return alloc_root(mem_root, size); }
static void operator delete(void *ptr_arg, size_t size)
{
(void) ptr_arg;
(void) size;
- TRASH(ptr_arg, size);
+ TRASH_FREE(ptr_arg, size);
}
static void operator delete(void *, MEM_ROOT *)
{ /* never called */ }
- static void operator delete[](void *ptr, size_t size) { TRASH(ptr, size); }
+ static void operator delete[](void *ptr, size_t size)
+ { TRASH_FREE(ptr, size); }
static void operator delete[](void *ptr, MEM_ROOT *mem_root)
{ /* never called */ }
@@ -209,9 +207,9 @@ public:
inline uint32 length() const { return str_length;}
inline uint32 alloced_length() const { return Alloced_length;}
inline uint32 extra_allocation() const { return extra_alloc;}
- inline char& operator [] (uint32 i) const { return Ptr[i]; }
- inline void length(uint32 len) { str_length=len ; }
- inline void extra_allocation(uint32 len) { extra_alloc= len; }
+ inline char& operator [] (size_t i) const { return Ptr[i]; }
+ inline void length(size_t len) { str_length=(uint32)len ; }
+ inline void extra_allocation(size_t len) { extra_alloc= (uint32)len; }
inline bool is_empty() const { return (str_length == 0); }
inline void mark_as_const() { Alloced_length= 0;}
inline const char *ptr() const { return Ptr; }
@@ -250,13 +248,13 @@ public:
return skr;
}
- void set(String &str,uint32 offset,uint32 arg_length)
+ void set(String &str,size_t offset,size_t arg_length)
{
DBUG_ASSERT(&str != this);
free();
- Ptr=(char*) str.ptr()+offset; str_length=arg_length;
+ Ptr=(char*) str.ptr()+offset; str_length=(uint32)arg_length;
if (str.Alloced_length)
- Alloced_length=str.Alloced_length-offset;
+ Alloced_length=(uint32)(str.Alloced_length-offset);
str_charset=str.str_charset;
}
@@ -269,24 +267,24 @@ public:
@param cs Character set to use for interpreting string data.
@note The new buffer will not be null terminated.
*/
- inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs)
+ inline void set(char *str,size_t arg_length, CHARSET_INFO *cs)
{
free();
- Ptr=(char*) str; str_length=Alloced_length=arg_length;
+ Ptr=(char*) str; str_length=Alloced_length=(uint32)arg_length;
str_charset=cs;
}
- inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs)
+ inline void set(const char *str,size_t arg_length, CHARSET_INFO *cs)
{
free();
- Ptr=(char*) str; str_length=arg_length;
+ Ptr=(char*) str; str_length=(uint32)arg_length;
str_charset=cs;
}
- bool set_ascii(const char *str, uint32 arg_length);
- inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs)
+ bool set_ascii(const char *str, size_t arg_length);
+ inline void set_quick(char *str,size_t arg_length, CHARSET_INFO *cs)
{
if (!alloced)
{
- Ptr=(char*) str; str_length=Alloced_length=arg_length;
+ Ptr=(char*) str; str_length=Alloced_length=(uint32)arg_length;
}
str_charset=cs;
}
@@ -303,13 +301,13 @@ public:
bool set_hex(const char *str, uint32 len);
/* Take over handling of buffer from some other object */
- void reset(char *ptr_arg, uint32 length_arg, uint32 alloced_length_arg,
+ void reset(char *ptr_arg, size_t length_arg, size_t alloced_length_arg,
CHARSET_INFO *cs)
{
free();
Ptr= ptr_arg;
- str_length= length_arg;
- Alloced_length= alloced_length_arg;
+ str_length= (uint32)length_arg;
+ Alloced_length= (uint32)alloced_length_arg;
str_charset= cs;
alloced= ptr_arg != 0;
}
@@ -438,29 +436,29 @@ public:
bool copy(); // Alloc string if not alloced
bool copy(const String &s); // Allocate new string
bool copy(const char *s,size_t arg_length, CHARSET_INFO *cs); // Allocate new string
- static bool needs_conversion(uint32 arg_length,
+ static bool needs_conversion(size_t arg_length,
CHARSET_INFO *cs_from, CHARSET_INFO *cs_to,
uint32 *offset);
- static bool needs_conversion_on_storage(uint32 arg_length,
+ static bool needs_conversion_on_storage(size_t arg_length,
CHARSET_INFO *cs_from,
CHARSET_INFO *cs_to);
- bool copy_aligned(const char *s, uint32 arg_length, uint32 offset,
+ bool copy_aligned(const char *s, size_t arg_length, size_t offset,
CHARSET_INFO *cs);
- bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
- bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom,
+ bool set_or_copy_aligned(const char *s, size_t arg_length, CHARSET_INFO *cs);
+ bool copy(const char*s, size_t arg_length, CHARSET_INFO *csfrom,
CHARSET_INFO *csto, uint *errors);
bool copy(const String *str, CHARSET_INFO *tocs, uint *errors)
{
return copy(str->ptr(), str->length(), str->charset(), tocs, errors);
}
bool copy(CHARSET_INFO *tocs,
- CHARSET_INFO *fromcs, const char *src, uint32 src_length,
- uint32 nchars, String_copier *copier)
+ CHARSET_INFO *fromcs, const char *src, size_t src_length,
+ size_t nchars, String_copier *copier)
{
if (alloc(tocs->mbmaxlen * src_length))
return true;
str_length= copier->well_formed_copy(tocs, Ptr, Alloced_length,
- fromcs, src, src_length, nchars);
+ fromcs, src, (uint)src_length, (uint)nchars);
str_charset= tocs;
return false;
}
@@ -477,21 +475,20 @@ public:
bool append(const char *s);
bool append(const LEX_STRING *ls)
{
- DBUG_ASSERT(ls->length < UINT_MAX32);
+ DBUG_ASSERT(ls->length < UINT_MAX32 &&
+ ((ls->length == 0 && !ls->str) ||
+ ls->length == strlen(ls->str)));
return append(ls->str, (uint32) ls->length);
}
bool append(const LEX_CSTRING *ls)
{
- DBUG_ASSERT(ls->length < UINT_MAX32);
+ DBUG_ASSERT(ls->length < UINT_MAX32 &&
+ ((ls->length == 0 && !ls->str) ||
+ ls->length == strlen(ls->str)));
return append(ls->str, (uint32) ls->length);
}
- bool append(const LEX_CSTRING &ls)
- {
- DBUG_ASSERT(ls.length < UINT_MAX32);
- return append(ls.str, (uint32) ls.length);
- }
bool append(const char *s, size_t size);
- bool append(const char *s, uint arg_length, CHARSET_INFO *cs);
+ bool append(const char *s, size_t arg_length, CHARSET_INFO *cs);
bool append_ulonglong(ulonglong val);
bool append_longlong(longlong val);
bool append(IO_CACHE* file, uint32 arg_length);
@@ -539,11 +536,11 @@ public:
uint32 numchars() const;
int charpos(longlong i,uint32 offset=0);
- int reserve(uint32 space_needed)
+ int reserve(size_t space_needed)
{
return realloc(str_length + space_needed);
}
- int reserve(uint32 space_needed, uint32 grow_by);
+ int reserve(size_t space_needed, size_t grow_by);
/*
The following append operations do NOT check alloced memory
@@ -582,7 +579,9 @@ public:
}
void q_append(const LEX_CSTRING *ls)
{
- DBUG_ASSERT(ls->length < UINT_MAX32);
+ DBUG_ASSERT(ls->length < UINT_MAX32 &&
+ ((ls->length == 0 && !ls->str) ||
+ ls->length == strlen(ls->str)));
q_append(ls->str, (uint32) ls->length);
}
@@ -595,11 +594,14 @@ public:
{
qs_append(str, (uint32)strlen(str));
}
- void qs_append(const LEX_CSTRING *str)
+ void qs_append(const LEX_CSTRING *ls)
{
- qs_append(str->str, str->length);
+ DBUG_ASSERT(ls->length < UINT_MAX32 &&
+ ((ls->length == 0 && !ls->str) ||
+ ls->length == strlen(ls->str)));
+ qs_append(ls->str, (uint32)ls->length);
}
- void qs_append(const char *str, uint32 len);
+ 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);
@@ -660,7 +662,7 @@ public:
print_with_conversion(to, cs);
}
- bool append_for_single_quote(const char *st, uint len);
+ bool append_for_single_quote(const char *st, size_t len);
bool append_for_single_quote(const String *s)
{
return append_for_single_quote(s->ptr(), s->length());
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index dbf198d722a..0201a904058 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -55,6 +55,9 @@
#include "transaction.h"
#include "sql_audit.h"
#include "sql_sequence.h"
+#include "tztime.h"
+#include "vtmd.h" // System Versioning
+
#ifdef __WIN__
#include <io.h>
@@ -62,12 +65,16 @@
const char *primary_key_name="PRIMARY";
-static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
+static int check_if_keyname_exists(const char *name,KEY *start, KEY *end);
static char *make_unique_key_name(THD *thd, const char *field_name, KEY *start,
KEY *end);
static void make_unique_constraint_name(THD *thd, LEX_CSTRING *name,
List<Virtual_column_info> *vcol,
uint *nr);
+static const
+char * make_unique_invisible_field_name(THD *thd, const char *field_name,
+ List<Create_field> *fields);
+
static int copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
List<Create_field> &create, bool ignore,
uint order_num, ORDER *order,
@@ -88,7 +95,7 @@ static uint blob_length_by_type(enum_field_types type);
@param name_len Length of the name, in bytes
*/
static char* add_identifier(THD* thd, char *to_p, const char * end_p,
- const char* name, uint name_len)
+ const char* name, size_t name_len)
{
uint res;
uint errors;
@@ -208,13 +215,13 @@ uint explain_filename(THD* thd,
char *to_p= to;
char *end_p= to_p + to_length;
const char *db_name= NULL;
- int db_name_len= 0;
+ size_t db_name_len= 0;
const char *table_name;
- int table_name_len= 0;
+ size_t table_name_len= 0;
const char *part_name= NULL;
- int part_name_len= 0;
+ size_t part_name_len= 0;
const char *subpart_name= NULL;
- int subpart_name_len= 0;
+ size_t subpart_name_len= 0;
uint part_type= NORMAL_PART_NAME;
const char *tmp_p;
@@ -374,7 +381,7 @@ uint explain_filename(THD* thd,
Table name length.
*/
-uint filename_to_tablename(const char *from, char *to, uint to_length,
+uint filename_to_tablename(const char *from, char *to, size_t to_length,
bool stay_quiet)
{
uint errors;
@@ -393,7 +400,7 @@ uint filename_to_tablename(const char *from, char *to, uint to_length,
}
DBUG_PRINT("exit", ("to '%s'", to));
- DBUG_RETURN(res);
+ DBUG_RETURN((uint)res);
}
@@ -429,7 +436,7 @@ bool check_mysql50_prefix(const char *name)
non-0 result string length
*/
-uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length)
+uint check_n_cut_mysql50_prefix(const char *from, char *to, size_t to_length)
{
if (check_mysql50_prefix(from))
return (uint) (strmake(to, from + MYSQL50_TABLE_NAME_PREFIX_LENGTH,
@@ -458,7 +465,7 @@ static bool check_if_frm_exists(char *path, const char *db, const char *table)
File name length.
*/
-uint tablename_to_filename(const char *from, char *to, uint to_length)
+uint tablename_to_filename(const char *from, char *to, size_t to_length)
{
uint errors, length;
DBUG_ENTER("tablename_to_filename");
@@ -601,7 +608,7 @@ uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
size_t length= unpack_filename(buff, buff);
DBUG_PRINT("exit", ("buff: '%s'", buff));
- DBUG_RETURN(length);
+ DBUG_RETURN((uint)length);
}
/*
@@ -1124,7 +1131,8 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
ddl_log_entry->tmp_name));
handler_name.str= (char*)ddl_log_entry->handler_name;
handler_name.length= strlen(ddl_log_entry->handler_name);
- init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
+ init_sql_alloc(&mem_root, "execute_ddl_log_action", TABLE_ALLOC_BLOCK_SIZE,
+ 0, MYF(MY_THREAD_SPECIFIC));
if (!strcmp(ddl_log_entry->handler_name, reg_ext))
frm_action= TRUE;
else
@@ -1761,9 +1769,10 @@ uint build_table_shadow_filename(char *buff, size_t bufflen,
ALTER_PARTITION_PARAM_TYPE *lpt)
{
char tmp_name[FN_REFLEN];
- my_snprintf (tmp_name, sizeof (tmp_name), "%s-%s", tmp_file_prefix,
- lpt->table_name);
- return build_table_filename(buff, bufflen, lpt->db, tmp_name, "", FN_IS_TMP);
+ my_snprintf(tmp_name, sizeof (tmp_name), "%s-%s", tmp_file_prefix,
+ lpt->table_name.str);
+ return build_table_filename(buff, bufflen, lpt->db.str, tmp_name, "",
+ FN_IS_TMP);
}
@@ -1845,7 +1854,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
#endif
/* Write shadow frm file */
lpt->create_info->table_options= lpt->db_options;
- LEX_CUSTRING frm= build_frm_image(lpt->thd, lpt->table_name,
+ LEX_CUSTRING frm= build_frm_image(lpt->thd, &lpt->table_name,
lpt->create_info,
lpt->alter_info->create_list,
lpt->key_count, lpt->key_info_buffer,
@@ -1856,7 +1865,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
goto end;
}
- int error= writefrm(shadow_path, lpt->db, lpt->table_name,
+ int error= writefrm(shadow_path, lpt->db.str, lpt->table_name.str,
lpt->create_info->tmp_table(), frm.str, frm.length);
my_free(const_cast<uchar*>(frm.str));
@@ -1876,8 +1885,8 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
/*
Build frm file name
*/
- build_table_filename(path, sizeof(path) - 1, lpt->db,
- lpt->table_name, "", 0);
+ build_table_filename(path, sizeof(path) - 1, lpt->db.str,
+ lpt->table_name.str, "", 0);
strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS);
/*
When we are changing to use new frm file we need to ensure that we
@@ -2040,8 +2049,8 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists,
{
for (table= tables; table; table= table->next_local)
{
- LEX_CSTRING db_name= { table->db, table->db_length };
- LEX_CSTRING table_name= { table->table_name, table->table_name_length };
+ LEX_CSTRING db_name= table->db;
+ LEX_CSTRING table_name= table->table_name;
if (table->open_type == OT_BASE_ONLY ||
!thd->find_temporary_table(table))
(void) delete_statistics_for_table(thd, &db_name, &table_name);
@@ -2103,8 +2112,8 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists,
by parser) it is safe to cache pointer to the TABLE instances
in its elements.
*/
- table->table= find_table_for_mdl_upgrade(thd, table->db,
- table->table_name, false);
+ table->table= find_table_for_mdl_upgrade(thd, table->db.str,
+ table->table_name.str, false);
if (!table->table)
DBUG_RETURN(true);
table->mdl_request.ticket= table->table->mdl_ticket;
@@ -2211,7 +2220,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
{
TABLE_LIST *table;
char path[FN_REFLEN + 1], wrong_tables_buff[160];
- const char *alias= NULL;
+ LEX_CSTRING alias= null_clex_str;
String wrong_tables(wrong_tables_buff, sizeof(wrong_tables_buff)-1,
system_charset_info);
uint path_length= 0, errors= 0;
@@ -2302,12 +2311,12 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
{
bool is_trans= 0;
bool table_creation_was_logged= 1;
- const char *db= table->db;
- size_t db_length= table->db_length;
+ LEX_CSTRING db= table->db;
handlerton *table_type= 0;
+ VTMD_drop vtmd(*table);
DBUG_PRINT("table", ("table_l: '%s'.'%s' table: %p s: %p",
- table->db, table->table_name, table->table,
+ table->db.str, table->table_name.str, table->table,
table->table ? table->table->s : NULL));
/*
@@ -2366,14 +2375,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
thd->db is NULL or 'IF EXISTS' clause is present in 'DROP TEMPORARY'
query.
*/
- if (thd->db == NULL || strcmp(db,thd->db) != 0
- || is_drop_tmp_if_exists_added )
+ if (thd->db.str == NULL || cmp(&db, &thd->db) ||
+ is_drop_tmp_if_exists_added )
{
- append_identifier(thd, built_ptr_query, db, db_length);
+ append_identifier(thd, built_ptr_query, &db);
built_ptr_query->append(".");
}
- append_identifier(thd, built_ptr_query, table->table_name,
- table->table_name_length);
+ append_identifier(thd, built_ptr_query, &table->table_name);
built_ptr_query->append(",");
}
/*
@@ -2387,13 +2395,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
{
non_temp_tables_count++;
- DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
- table->table_name,
+ DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db.str,
+ table->table_name.str,
MDL_SHARED));
alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
/* remove .frm file and engine files */
- path_length= build_table_filename(path, sizeof(path) - 1, db, alias,
+ path_length= build_table_filename(path, sizeof(path) - 1, db.str, alias.str,
reg_ext, 0);
/*
@@ -2415,21 +2423,20 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
Don't write the database name if it is the current one (or if
thd->db is NULL).
*/
- if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ if (thd->db.str == NULL || cmp(&db, &thd->db) != 0)
{
- append_identifier(thd, &built_query, db, db_length);
+ append_identifier(thd, &built_query, &db);
built_query.append(".");
}
- append_identifier(thd, &built_query, table->table_name,
- table->table_name_length);
+ append_identifier(thd, &built_query, &table->table_name);
built_query.append(",");
}
}
DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
error= 0;
if (drop_temporary ||
- (ha_table_exists(thd, db, alias, &table_type, &is_sequence) == 0 &&
+ (ha_table_exists(thd, &db, &alias, &table_type, &is_sequence) == 0 &&
table_type == 0) ||
(!drop_view && (was_view= (table_type == view_pseudo_hton))) ||
(drop_sequence && !is_sequence))
@@ -2449,9 +2456,9 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
ER_BAD_TABLE_ERROR);
String tbl_name(buff, sizeof(buff), system_charset_info);
tbl_name.length(0);
- tbl_name.append(db);
+ tbl_name.append(&db);
tbl_name.append('.');
- tbl_name.append(table->table_name);
+ tbl_name.append(&table->table_name);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
err, ER_THD(thd, err),
tbl_name.c_ptr_safe());
@@ -2465,6 +2472,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
else
{
char *end;
+ int frm_delete_error= 0;
/*
It could happen that table's share in the table definition cache
is the only thing that keeps the engine plugin loaded
@@ -2492,45 +2500,70 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
table->table= 0;
}
else
- tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name,
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db.str, table->table_name.str,
false);
/* Check that we have an exclusive lock on the table to be dropped. */
- DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
- table->table_name,
+ DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db.str,
+ table->table_name.str,
MDL_EXCLUSIVE));
// Remove extension for delete
*(end= path + path_length - reg_ext_length)= '\0';
- error= ha_delete_table(thd, table_type, path, db, table->table_name,
- !dont_log_query);
-
- if (!error)
+ if ((thd->lex->sql_command == SQLCOM_DROP_TABLE ||
+ thd->lex->sql_command == SQLCOM_CREATE_TABLE) &&
+ thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE &&
+ table_type && table_type != view_pseudo_hton)
{
- int frm_delete_error, trigger_drop_error= 0;
- /* Delete the table definition file */
- strmov(end,reg_ext);
- if (table_type && table_type != view_pseudo_hton &&
- table_type->discover_table)
+ error= vtmd.check_exists(thd);
+ if (error)
+ goto non_tmp_err;
+ if (!vtmd.exists)
+ goto drop_table;
{
- /*
- Table type is using discovery and may not need a .frm file.
- Delete it silently if it exists
- */
- (void) mysql_file_delete(key_file_frm, path, MYF(0));
- frm_delete_error= 0;
+ const char *name= vtmd.archive_name(thd);
+ LEX_CSTRING new_name= { name, strlen(name) };
+ error= mysql_rename_table(table_type, &table->db, &table->table_name,
+ &table->db, &new_name, NO_FK_CHECKS);
}
- else
- frm_delete_error= mysql_file_delete(key_file_frm, path,
- MYF(MY_WME));
- if (frm_delete_error)
- frm_delete_error= my_errno;
- else
+ }
+ else
+ {
+ drop_table:
+ error= ha_delete_table(thd, table_type, path, &db, &table->table_name,
+ !dont_log_query);
+ if (!error)
+ {
+ /* Delete the table definition file */
+ strmov(end,reg_ext);
+ if (table_type && table_type != view_pseudo_hton &&
+ table_type->discover_table)
+ {
+ /*
+ Table type is using discovery and may not need a .frm file.
+ Delete it silently if it exists
+ */
+ (void) mysql_file_delete(key_file_frm, path, MYF(0));
+ }
+ else if (mysql_file_delete(key_file_frm, path,
+ MYF(MY_WME)))
+ {
+ frm_delete_error= my_errno;
+ DBUG_ASSERT(frm_delete_error);
+ }
+ }
+ }
+
+ if (!error)
+ {
+ int trigger_drop_error= 0;
+
+ if (!frm_delete_error)
{
non_tmp_table_deleted= TRUE;
trigger_drop_error=
- Table_triggers_list::drop_all_triggers(thd, db, table->table_name);
+ Table_triggers_list::drop_all_triggers(thd, &db, &table->table_name);
}
if (trigger_drop_error ||
@@ -2539,21 +2572,39 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
else if (frm_delete_error && if_exists)
thd->clear_error();
}
+ non_tmp_err:
non_tmp_error|= MY_TEST(error);
}
+
+ if (!error && vtmd.exists)
+ {
+ enum_sql_command sql_command= thd->lex->sql_command;
+ thd->lex->sql_command= SQLCOM_DROP_TABLE;
+ error= vtmd.update(thd);
+ thd->lex->sql_command= sql_command;
+ if (error)
+ {
+ LEX_CSTRING archive_name;
+ archive_name.str= vtmd.archive_name();
+ archive_name.length= strlen(archive_name.str);
+ mysql_rename_table(table_type, &table->db, &archive_name,
+ &table->db, &table->table_name, NO_FK_CHECKS);
+ }
+ }
+
if (error)
{
if (wrong_tables.length())
wrong_tables.append(',');
- wrong_tables.append(db);
+ wrong_tables.append(&db);
wrong_tables.append('.');
- wrong_tables.append(table->table_name);
+ wrong_tables.append(&table->table_name);
errors++;
}
else
{
- PSI_CALL_drop_table_share(false, table->db, table->db_length,
- table->table_name, table->table_name_length);
+ PSI_CALL_drop_table_share(false, table->db.str, (uint)table->db.length,
+ table->table_name.str, (uint)table->table_name.length);
mysql_audit_drop_table(thd, table);
}
@@ -2706,8 +2757,8 @@ end:
when the original table was dropped but we could not create the new one.
*/
-bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length,
- const char *table_name, size_t table_name_length,
+bool log_drop_table(THD *thd, const LEX_CSTRING *db_name,
+ const LEX_CSTRING *table_name,
bool temporary_table)
{
char buff[NAME_LEN*2 + 80];
@@ -2723,9 +2774,9 @@ bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length,
if (temporary_table)
query.append(STRING_WITH_LEN("TEMPORARY "));
query.append(STRING_WITH_LEN("TABLE IF EXISTS "));
- append_identifier(thd, &query, db_name, db_name_length);
+ append_identifier(thd, &query, db_name);
query.append(".");
- append_identifier(thd, &query, table_name, table_name_length);
+ append_identifier(thd, &query, table_name);
query.append(STRING_WITH_LEN("/* Generated to handle "
"failed CREATE OR REPLACE */"));
error= thd->binlog_query(THD::STMT_QUERY_TYPE,
@@ -2748,16 +2799,16 @@ bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length,
@return False in case of success, True otherwise.
*/
-bool quick_rm_table(THD *thd, handlerton *base, const char *db,
- const char *table_name, uint flags, const char *table_path)
+bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name, uint flags, const char *table_path)
{
char path[FN_REFLEN + 1];
- bool error= 0;
+ int error= 0;
DBUG_ENTER("quick_rm_table");
size_t path_length= table_path ?
(strxnmov(path, sizeof(path) - 1, table_path, reg_ext, NullS) - path) :
- build_table_filename(path, sizeof(path)-1, db, table_name, reg_ext, flags);
+ build_table_filename(path, sizeof(path)-1, db->str, table_name->str, reg_ext, flags);
if (mysql_file_delete(key_file_frm, path, MYF(0)))
error= 1; /* purecov: inspected */
path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
@@ -2774,8 +2825,8 @@ bool quick_rm_table(THD *thd, handlerton *base, const char *db,
if (likely(error == 0))
{
- PSI_CALL_drop_table_share(flags & FN_IS_TMP, db, strlen(db),
- table_name, strlen(table_name));
+ PSI_CALL_drop_table_share(flags & FN_IS_TMP, db->str, (uint)db->length,
+ table_name->str, (uint)table_name->length);
}
DBUG_RETURN(error);
@@ -3034,10 +3085,12 @@ void promote_first_timestamp_column(List<Create_field> *column_definitions)
if (column_definition->is_timestamp_type() || // TIMESTAMP
column_definition->unireg_check == Field::TIMESTAMP_OLD_FIELD) // Legacy
{
+ DBUG_PRINT("info", ("field-ptr:%p", column_definition->field));
if ((column_definition->flags & NOT_NULL_FLAG) != 0 && // NOT NULL,
column_definition->default_value == NULL && // no constant default,
column_definition->unireg_check == Field::NONE && // no function default
- column_definition->vcol_info == NULL)
+ column_definition->vcol_info == NULL &&
+ !(column_definition->flags & VERS_SYSTEM_FIELD)) // column isn't generated
{
DBUG_PRINT("info", ("First TIMESTAMP column '%s' was promoted to "
"DEFAULT CURRENT_TIMESTAMP ON UPDATE "
@@ -3263,8 +3316,70 @@ bool Column_definition::prepare_stage1_check_typelib_default()
}
return false;
}
+/*
+ This function adds a invisible field to field_list
+ SYNOPSIS
+ mysql_add_invisible_field()
+ thd Thread Object
+ field_list list of all table fields
+ field_name name/prefix of invisible field
+ ( Prefix in the case when it is
+ *INVISIBLE_FULL*
+ and given name is duplicate)
+ type_handler field data type
+ invisible
+ default value
+ RETURN VALUE
+ Create_field pointer
+*/
+int mysql_add_invisible_field(THD *thd, List<Create_field> * field_list,
+ const char *field_name, Type_handler *type_handler,
+ field_visibility_t invisible, Item* default_value)
+{
+ Create_field *fld= new(thd->mem_root)Create_field();
+ const char *new_name= NULL;
+ /* Get unique field name if invisible == INVISIBLE_FULL */
+ if (invisible == INVISIBLE_FULL)
+ {
+ if ((new_name= make_unique_invisible_field_name(thd, field_name,
+ field_list)))
+ {
+ fld->field_name.str= new_name;
+ fld->field_name.length= strlen(new_name);
+ }
+ else
+ return 1; //Should not happen
+ }
+ else
+ {
+ fld->field_name.str= thd->strmake(field_name, strlen(field_name));
+ fld->field_name.length= strlen(field_name);
+ }
+ fld->set_handler(type_handler);
+ fld->invisible= invisible;
+ if (default_value)
+ {
+ Virtual_column_info *v= new (thd->mem_root) Virtual_column_info();
+ v->expr= default_value;
+ v->utf8= 0;
+ fld->default_value= v;
+ }
+ field_list->push_front(fld, thd->mem_root);
+ return 0;
+}
-
+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),
+ thd->mem_root);
+ key_list->push_back(key, thd->mem_root);
+ return key;
+}
/*
Preparation for table creation
@@ -3312,6 +3427,23 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
bool tmp_table= create_table_mode == C_ALTER_TABLE;
DBUG_ENTER("mysql_prepare_create_table");
+ DBUG_EXECUTE_IF("test_pseudo_invisible",{
+ mysql_add_invisible_field(thd, &alter_info->create_list,
+ "invisible", &type_handler_long, INVISIBLE_SYSTEM,
+ new (thd->mem_root)Item_int(thd, 9));
+ });
+ DBUG_EXECUTE_IF("test_completely_invisible",{
+ mysql_add_invisible_field(thd, &alter_info->create_list,
+ "invisible", &type_handler_long, INVISIBLE_FULL,
+ new (thd->mem_root)Item_int(thd, 9));
+ });
+ DBUG_EXECUTE_IF("test_invisible_index",{
+ LEX_CSTRING temp;
+ temp.str= "invisible";
+ temp.length= strlen("invisible");
+ mysql_add_invisible_index(thd, &alter_info->key_list
+ , &temp, Key::MULTIPLE);
+ });
LEX_CSTRING* connect_string = &create_info->connect_string;
if (connect_string->length != 0 &&
connect_string->length > CONNECT_STRING_MAXLEN &&
@@ -3348,6 +3480,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
select_field_pos= alter_info->create_list.elements - select_field_count;
+
for (field_no=0; (sql_field=it++) ; field_no++)
{
/*
@@ -3440,7 +3573,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
while ((sql_field=it++))
{
DBUG_ASSERT(sql_field->charset != 0);
-
if (sql_field->prepare_stage2(file, file->ha_table_flags()))
DBUG_RETURN(TRUE);
if (sql_field->real_field_type() == MYSQL_TYPE_VARCHAR)
@@ -3460,8 +3592,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
*/
if (sql_field->stored_in_db())
record_offset+= sql_field->pack_length;
+ if (sql_field->flags & VERS_SYSTEM_FIELD)
+ continue;
}
- /* Update virtual fields' offset*/
+ /* Update virtual fields' offset and give error if
+ All fields are invisible */
+ bool is_all_invisible= true;
it.rewind();
while ((sql_field=it++))
{
@@ -3470,6 +3606,13 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field->offset= record_offset;
record_offset+= sql_field->pack_length;
}
+ if (sql_field->invisible == VISIBLE)
+ is_all_invisible= false;
+ }
+ if (is_all_invisible)
+ {
+ my_error(ER_TABLE_MUST_HAVE_COLUMNS, MYF(0));
+ DBUG_RETURN(TRUE);
}
if (auto_increment > 1)
{
@@ -3513,9 +3656,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (key->type == Key::FOREIGN_KEY)
{
fk_key_count++;
- if (((Foreign_key *)key)->validate(alter_info->create_list))
- DBUG_RETURN(TRUE);
Foreign_key *fk_key= (Foreign_key*) key;
+ if (fk_key->validate(alter_info->create_list))
+ DBUG_RETURN(TRUE);
if (fk_key->ref_columns.elements &&
fk_key->ref_columns.elements != fk_key->columns.elements)
{
@@ -3720,11 +3863,21 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
&column->field_name,
&sql_field->field_name))
field++;
+ /*
+ Either field is not present or field visibility is > INVISIBLE_USER
+ */
if (!sql_field)
{
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
+ if (sql_field->invisible > INVISIBLE_USER &&
+ !(sql_field->flags & VERS_SYSTEM_FIELD) &&
+ !key->invisible && DBUG_EVALUATE_IF("test_invisible_index", 0, 1))
+ {
+ my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
+ DBUG_RETURN(TRUE);
+ }
while ((dup_column= cols2++) != column)
{
if (!lex_string_cmp(system_charset_info,
@@ -4054,7 +4207,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
!sql_field->has_default_function() &&
(sql_field->flags & NOT_NULL_FLAG) &&
(!sql_field->is_timestamp_type() ||
- opt_explicit_defaults_for_timestamp))
+ opt_explicit_defaults_for_timestamp)&&
+ !sql_field->vers_sys_field())
{
sql_field->flags|= NO_DEFAULT_VALUE_FLAG;
sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
@@ -4084,6 +4238,14 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name.str);
DBUG_RETURN(TRUE);
}
+ if (sql_field->invisible == INVISIBLE_USER &&
+ sql_field->flags & NOT_NULL_FLAG &&
+ sql_field->flags & NO_DEFAULT_VALUE_FLAG)
+ {
+ my_error(ER_INVISIBLE_NOT_NULL_WITHOUT_DEFAULT, MYF(0),
+ sql_field->field_name.str);
+ DBUG_RETURN(TRUE);
+ }
}
/* Check table level constraints */
@@ -4128,7 +4290,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
/* Give warnings for not supported table options */
#if defined(WITH_ARIA_STORAGE_ENGINE)
extern handlerton *maria_hton;
- if (file->ht != maria_hton)
+ if (file->partition_ht() != maria_hton)
#endif
if (create_info->transactional)
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
@@ -4167,7 +4329,7 @@ bool validate_comment_length(THD *thd, LEX_CSTRING *comment, size_t max_len,
uint err_code, const char *name)
{
DBUG_ENTER("validate_comment_length");
- uint tmp_len= my_charpos(system_charset_info, comment->str,
+ size_t tmp_len= my_charpos(system_charset_info, comment->str,
comment->str + comment->length, max_len);
if (tmp_len < comment->length)
{
@@ -4200,7 +4362,7 @@ bool validate_comment_length(THD *thd, LEX_CSTRING *comment, size_t max_len,
static void set_table_default_charset(THD *thd,
HA_CREATE_INFO *create_info,
- const char *db)
+ const LEX_CSTRING *db)
{
/*
If the table character set was not given explicitly,
@@ -4211,7 +4373,7 @@ static void set_table_default_charset(THD *thd,
{
Schema_specification_st db_info;
- load_db_opt_by_name(thd, db, &db_info);
+ load_db_opt_by_name(thd, db->str, &db_info);
create_info->default_table_charset= db_info.default_table_charset;
}
@@ -4293,8 +4455,62 @@ bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root)
}
+static bool vers_prepare_keys(THD *thd, HA_CREATE_INFO *create_info,
+ Alter_info *alter_info, KEY **key_info, uint key_count)
+{
+ DBUG_ASSERT(create_info->versioned());
+
+ const char *row_start_field= create_info->vers_info.as_row.start;
+ DBUG_ASSERT(row_start_field);
+ const char *row_end_field= create_info->vers_info.as_row.end;
+ DBUG_ASSERT(row_end_field);
+
+ List_iterator<Key> key_it(alter_info->key_list);
+ Key *key= NULL;
+ while ((key=key_it++))
+ {
+ if (key->type == Key::FOREIGN_KEY &&
+ create_info->vers_info.check_unit == VERS_TIMESTAMP)
+ {
+ Foreign_key *fk_key= (Foreign_key*) key;
+ enum enum_fk_option op;
+ if (fk_modifies_child(op=fk_key->update_opt) ||
+ fk_modifies_child(op=fk_key->delete_opt))
+ {
+ my_error(ER_VERS_NOT_SUPPORTED, MYF(0), fk_option_name(op)->str,
+ "TIMESTAMP(6) AS ROW START/END");
+ return true;
+ }
+ }
+ 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 (!my_strcasecmp(system_charset_info,
+ row_start_field,
+ key_part->field_name.str) ||
+
+ !my_strcasecmp(system_charset_info,
+ row_end_field,
+ key_part->field_name.str))
+ break;
+ }
+ if (key_part)
+ continue; // Key already contains Sys_start or Sys_end
+
+ Key_part_spec *key_part_sys_end_col=
+ new (thd->mem_root) Key_part_spec(&create_info->vers_info.as_row.end, 0);
+ key->columns.push_back(key_part_sys_end_col);
+ }
+
+ return false;
+}
+
handler *mysql_create_frm_image(THD *thd,
- const char *db, const char *table_name,
+ const LEX_CSTRING *db, const LEX_CSTRING *table_name,
HA_CREATE_INFO *create_info,
Alter_info *alter_info, int create_table_mode,
KEY **key_info,
@@ -4311,12 +4527,9 @@ handler *mysql_create_frm_image(THD *thd,
DBUG_RETURN(NULL);
}
- set_table_default_charset(thd, create_info, (char*) db);
+ set_table_default_charset(thd, create_info, db);
- db_options= create_info->table_options;
- if (create_info->row_type == ROW_TYPE_DYNAMIC ||
- create_info->row_type == ROW_TYPE_PAGE)
- db_options|= HA_OPTION_PACK_RECORD;
+ db_options= create_info->table_options_with_row_type();
if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
create_info->db_type)))
@@ -4437,6 +4650,12 @@ handler *mysql_create_frm_image(THD *thd,
goto err;
part_info->default_engine_type= engine_type;
+ if (part_info->vers_info && !create_info->versioned())
+ {
+ my_error(ER_VERS_NOT_VERSIONED, MYF(0), table_name->str);
+ goto err;
+ }
+
/*
We reverse the partitioning parser and generate a standard format
for syntax stored in frm file.
@@ -4451,7 +4670,10 @@ handler *mysql_create_frm_image(THD *thd,
part_info->part_info_string= part_syntax_buf;
part_info->part_info_len= syntax_len;
if ((!(engine_type->partition_flags &&
- engine_type->partition_flags() & HA_CAN_PARTITION)) ||
+ ((engine_type->partition_flags() & HA_CAN_PARTITION) ||
+ (part_info->part_type == VERSIONING_PARTITION &&
+ engine_type->partition_flags() & HA_ONLY_VERS_PARTITION))
+ )) ||
create_info->db_type == partition_hton)
{
/*
@@ -4532,6 +4754,13 @@ handler *mysql_create_frm_image(THD *thd,
}
#endif
+ if (create_info->versioned())
+ {
+ if(vers_prepare_keys(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))
@@ -4587,8 +4816,9 @@ err:
static
int create_table_impl(THD *thd,
- const char *orig_db, const char *orig_table_name,
- const char *db, const char *table_name,
+ const LEX_CSTRING *orig_db,
+ const LEX_CSTRING *orig_table_name,
+ const LEX_CSTRING *db, const LEX_CSTRING *table_name,
const char *path,
const DDL_options_st options,
HA_CREATE_INFO *create_info,
@@ -4599,14 +4829,14 @@ int create_table_impl(THD *thd,
uint *key_count,
LEX_CUSTRING *frm)
{
- const char *alias;
+ LEX_CSTRING *alias;
handler *file= 0;
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;
DBUG_ENTER("mysql_create_table_no_lock");
DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d path: %s",
- db, table_name, internal_tmp_table, path));
+ db->str, table_name->str, internal_tmp_table, path));
if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)
{
@@ -4628,7 +4858,7 @@ int create_table_impl(THD *thd,
check_partition_dirs(thd->lex->part_info))
goto err;
- alias= table_case_name(create_info, table_name);
+ alias= const_cast<LEX_CSTRING*>(table_case_name(create_info, table_name));
/* Check if table exists */
if (create_info->tmp_table())
@@ -4637,7 +4867,7 @@ int create_table_impl(THD *thd,
If a table exists, it must have been pre-opened. Try looking for one
in-use in THD::all_temp_tables list of TABLE_SHAREs.
*/
- TABLE *tmp_table= thd->find_temporary_table(db, table_name);
+ TABLE *tmp_table= thd->find_temporary_table(db->str, table_name->str);
if (tmp_table)
{
@@ -4655,7 +4885,7 @@ int create_table_impl(THD *thd,
goto warn;
else
{
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias->str);
goto err;
}
/*
@@ -4677,9 +4907,7 @@ int create_table_impl(THD *thd,
if (options.or_replace())
{
TABLE_LIST table_list;
- table_list.init_one_table(db, strlen(db), table_name,
- strlen(table_name), table_name,
- TL_WRITE_ALLOW_WRITE);
+ table_list.init_one_table(db, table_name, 0, TL_WRITE_ALLOW_WRITE);
table_list.table= create_info->table;
if (check_if_log_table(&table_list, TRUE, "CREATE OR REPLACE"))
@@ -4714,7 +4942,7 @@ int create_table_impl(THD *thd,
goto warn;
else
{
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name->str);
goto err;
}
}
@@ -4722,7 +4950,7 @@ int create_table_impl(THD *thd,
THD_STAGE_INFO(thd, stage_creating_table);
- if (check_engine(thd, orig_db, orig_table_name, create_info))
+ if (check_engine(thd, orig_db->str, orig_table_name->str, create_info))
goto err;
if (create_table_mode == C_ASSISTED_DISCOVERY)
@@ -4742,7 +4970,7 @@ int create_table_impl(THD *thd,
goto err;
}
- init_tmp_table_share(thd, &share, db, 0, table_name, path);
+ init_tmp_table_share(thd, &share, db->str, 0, table_name->str, path);
/* prepare everything for discovery */
share.field= &no_fields;
@@ -4779,7 +5007,7 @@ int create_table_impl(THD *thd,
key_count, frm);
if (!file)
goto err;
- if (rea_create_table(thd, frm, path, db, table_name, create_info,
+ if (rea_create_table(thd, frm, path, db->str, table_name->str, create_info,
file, frm_only))
goto err;
}
@@ -4788,7 +5016,9 @@ int create_table_impl(THD *thd,
if (!frm_only && create_info->tmp_table())
{
TABLE *table= thd->create_and_open_tmp_table(create_info->db_type, frm,
- path, db, table_name, true);
+ path, db->str,
+ table_name->str, true,
+ false);
if (!table)
{
@@ -4818,11 +5048,11 @@ int create_table_impl(THD *thd,
TABLE table;
TABLE_SHARE share;
- init_tmp_table_share(thd, &share, db, 0, table_name, path);
+ init_tmp_table_share(thd, &share, db->str, 0, table_name->str, path);
bool result= (open_table_def(thd, &share, GTS_TABLE) ||
- open_table_from_share(thd, &share, "", 0, (uint) READ_ALL,
- 0, &table, true));
+ open_table_from_share(thd, &share, &empty_clex_str, 0,
+ (uint) READ_ALL, 0, &table, true));
if (!result)
(void) closefrm(&table);
@@ -4851,7 +5081,7 @@ warn:
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_TABLE_EXISTS_ERROR,
ER_THD(thd, ER_TABLE_EXISTS_ERROR),
- alias);
+ alias->str);
goto err;
}
@@ -4861,7 +5091,8 @@ warn:
*/
int mysql_create_table_no_lock(THD *thd,
- const char *db, const char *table_name,
+ const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name,
Table_specification_st *create_info,
Alter_info *alter_info, bool *is_trans,
int create_table_mode,
@@ -4878,13 +5109,13 @@ int mysql_create_table_no_lock(THD *thd,
else
{
int length;
- const char *alias= table_case_name(create_info, table_name);
- length= build_table_filename(path, sizeof(path) - 1, db, alias,
- "", 0);
+ const LEX_CSTRING *alias= table_case_name(create_info, table_name);
+ length= build_table_filename(path, sizeof(path) - 1, db->str, alias->str, "", 0);
// Check if we hit FN_REFLEN bytes along with file extension.
if (length+reg_ext_length > FN_REFLEN)
{
- my_error(ER_IDENT_CAUSES_TOO_LONG_PATH, MYF(0), (int) sizeof(path)-1, path);
+ my_error(ER_IDENT_CAUSES_TOO_LONG_PATH, MYF(0), (int) sizeof(path)-1,
+ path);
return true;
}
}
@@ -4922,8 +5153,6 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
Table_specification_st *create_info,
Alter_info *alter_info)
{
- const char *db= create_table->db;
- const char *table_name= create_table->table_name;
bool is_trans= FALSE;
bool result;
int create_table_mode;
@@ -4965,7 +5194,9 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
if (!opt_explicit_defaults_for_timestamp)
promote_first_timestamp_column(&alter_info->create_list);
- if (mysql_create_table_no_lock(thd, db, table_name, create_info, alter_info,
+ if (mysql_create_table_no_lock(thd, &create_table->db,
+ &create_table->table_name, create_info,
+ alter_info,
&is_trans, create_table_mode,
create_table) > 0)
{
@@ -4989,6 +5220,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
{
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
result= 1;
+ goto err;
}
else
{
@@ -4997,6 +5229,20 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
}
}
+ if (create_info->versioned() &&
+ thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
+ {
+ VTMD_table vtmd(*create_table);
+ if (vtmd.update(thd))
+ {
+ thd->variables.vers_alter_history = VERS_ALTER_HISTORY_KEEP;
+ mysql_rm_table_no_locks(thd, create_table, 0, 0, 0, 0, 1, 1);
+ thd->variables.vers_alter_history = VERS_ALTER_HISTORY_SURVIVE;
+ result= 1;
+ goto err;
+ }
+ }
+
err:
/* In RBR we don't need to log CREATE TEMPORARY TABLE */
if (thd->is_current_stmt_binlog_format_row() && create_info->tmp_table())
@@ -5008,7 +5254,7 @@ err:
/* Write log if no error or if we already deleted a table */
if (!result || thd->log_current_statement)
{
- if (result && create_info->table_was_deleted)
+ if (result && create_info->table_was_deleted && pos_in_locked_tables)
{
/*
Possible locked table was dropped. We should remove meta data locks
@@ -5034,17 +5280,36 @@ err:
/*
** Give the key name after the first field with an optional '_#' after
+ @returns
+ 0 if keyname does not exists
+ [1..) index + 1 of duplicate key name
**/
-static bool
+static int
check_if_keyname_exists(const char *name, KEY *start, KEY *end)
{
- for (KEY *key=start ; key != end ; key++)
+ uint i= 1;
+ for (KEY *key=start; key != end ; key++, i++)
if (!my_strcasecmp(system_charset_info, name, key->name.str))
- return 1;
+ return i;
return 0;
}
+/**
+ Returns 1 if field name exists otherwise 0
+*/
+static bool
+check_if_field_name_exists(const char *name, List<Create_field> * fields)
+{
+ Create_field *fld;
+ List_iterator<Create_field>it(*fields);
+ while ((fld = it++))
+ {
+ if (!my_strcasecmp(system_charset_info, fld->field_name.str, name))
+ return 1;
+ }
+ return 0;
+}
static char *
make_unique_key_name(THD *thd, const char *field_name,KEY *start,KEY *end)
@@ -5102,11 +5367,98 @@ static void make_unique_constraint_name(THD *thd, LEX_CSTRING *name,
}
}
+/**
+ INVISIBLE_FULL are internally created. They are completely invisible
+ to Alter command (Opposite of SYSTEM_INVISIBLE which throws an
+ error when same name column is added by Alter). So in the case of when
+ user added a same column name as of INVISIBLE_FULL , we change
+ INVISIBLE_FULL column name.
+*/
+static const
+char * make_unique_invisible_field_name(THD *thd, const char *field_name,
+ List<Create_field> *fields)
+{
+ if (!check_if_field_name_exists(field_name, fields))
+ return field_name;
+ char buff[MAX_FIELD_NAME], *buff_end;
+ buff_end= strmake_buf(buff, field_name);
+ if (buff_end - buff < 5)
+ return NULL; // Should not happen
+
+ for (uint i=1 ; i < 10000; i++)
+ {
+ char *real_end= int10_to_str(i, buff_end, 10);
+ if (check_if_field_name_exists(buff, fields))
+ continue;
+ return (const char *)thd->strmake(buff, real_end - buff);
+ }
+ return NULL; //Should not happen
+}
/****************************************************************************
** Alter a table definition
****************************************************************************/
+bool operator!=(const MYSQL_TIME &lhs, const MYSQL_TIME &rhs)
+{
+ return lhs.year != rhs.year || lhs.month != rhs.month || lhs.day != rhs.day ||
+ lhs.hour != rhs.hour || lhs.minute != rhs.minute ||
+ lhs.second_part != rhs.second_part || lhs.neg != rhs.neg ||
+ lhs.time_type != rhs.time_type;
+}
+
+// Sets row_end=MAX for rows with row_end=now(6)
+static bool vers_reset_alter_copy(THD *thd, TABLE *table)
+{
+ const MYSQL_TIME query_start= thd->query_start_TIME();
+
+ READ_RECORD info;
+ int error= 0;
+ bool will_batch= false;
+ ha_rows dup_key_found= 0;
+ if (init_read_record(&info, thd, table, NULL, NULL, 0, 1, true))
+ goto err;
+
+ will_batch= !table->file->start_bulk_update();
+
+ while (!(error= info.read_record()))
+ {
+ MYSQL_TIME current;
+ if (table->vers_end_field()->get_date(&current, 0))
+ goto err_read_record;
+ if (current != query_start)
+ {
+ continue;
+ }
+
+ store_record(table, record[1]);
+ table->vers_end_field()->set_max();
+ if (will_batch)
+ error= table->file->ha_bulk_update_row(table->record[1], table->record[0],
+ &dup_key_found);
+ else
+ error= table->file->ha_update_row(table->record[1], table->record[0]);
+ if (error && table->file->is_fatal_error(error, HA_CHECK_ALL))
+ {
+ table->file->print_error(error, MYF(ME_FATALERROR));
+ goto err_read_record;
+ }
+ }
+
+ if (will_batch && (error= table->file->exec_bulk_update(&dup_key_found)))
+ table->file->print_error(error, MYF(ME_FATALERROR));
+ if (will_batch)
+ table->file->end_bulk_update();
+
+err_read_record:
+ end_read_record(&info);
+
+err:
+ if (table->file->ha_external_lock(thd, F_UNLCK))
+ return true;
+
+ return error ? true : false;
+}
/**
Rename a table.
@@ -5129,9 +5481,9 @@ static void make_unique_constraint_name(THD *thd, LEX_CSTRING *name,
*/
bool
-mysql_rename_table(handlerton *base, const char *old_db,
- const char *old_name, const char *new_db,
- const char *new_name, uint flags)
+mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db,
+ const LEX_CSTRING *old_name, const LEX_CSTRING *new_db,
+ const LEX_CSTRING *new_name, uint flags)
{
THD *thd= current_thd;
char from[FN_REFLEN + 1], to[FN_REFLEN + 1],
@@ -5145,7 +5497,7 @@ mysql_rename_table(handlerton *base, const char *old_db,
DBUG_ENTER("mysql_rename_table");
DBUG_ASSERT(base);
DBUG_PRINT("enter", ("old: '%s'.'%s' new: '%s'.'%s'",
- old_db, old_name, new_db, new_name));
+ old_db->str, old_name->str, new_db->str, new_name->str));
// Temporarily disable foreign key checks
if (flags & NO_FK_CHECKS)
@@ -5153,9 +5505,9 @@ mysql_rename_table(handlerton *base, const char *old_db,
file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base);
- build_table_filename(from, sizeof(from) - 1, old_db, old_name, "",
+ 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, new_name, "",
+ 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)
@@ -5172,18 +5524,18 @@ mysql_rename_table(handlerton *base, const char *old_db,
if (lower_case_table_names == 2 && file &&
!(file->ha_table_flags() & HA_FILE_BASED))
{
- strmov(tmp_name, old_name);
+ strmov(tmp_name, old_name->str);
my_casedn_str(files_charset_info, tmp_name);
- strmov(tmp_db_name, old_db);
+ strmov(tmp_db_name, old_db->str);
my_casedn_str(files_charset_info, tmp_db_name);
build_table_filename(lc_from, sizeof(lc_from) - 1, tmp_db_name, tmp_name,
"", flags & FN_FROM_IS_TMP);
from_base= lc_from;
- strmov(tmp_name, new_name);
+ strmov(tmp_name, new_name->str);
my_casedn_str(files_charset_info, tmp_name);
- strmov(tmp_db_name, new_db);
+ strmov(tmp_db_name, new_db->str);
my_casedn_str(files_charset_info, tmp_db_name);
build_table_filename(lc_to, sizeof(lc_to) - 1, tmp_db_name, tmp_name, "",
@@ -5226,8 +5578,8 @@ mysql_rename_table(handlerton *base, const char *old_db,
if (likely(error == 0))
{
PSI_CALL_drop_table_share(flags & FN_FROM_IS_TMP,
- old_db, strlen(old_db),
- old_name, strlen(old_name));
+ old_db->str, (uint)old_db->length,
+ old_name->str, (uint)old_name->length);
}
// Restore options bits to the original value
@@ -5341,7 +5693,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
local_create_info.max_rows= 0;
/* Replace type of source table with one specified in the statement. */
local_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
- local_create_info.options|= create_info->tmp_table();
+ local_create_info.options|= create_info->options;
/* Reset auto-increment counter for the new table. */
local_create_info.auto_increment_value= 0;
/*
@@ -5350,12 +5702,19 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
*/
local_create_info.data_file_name= local_create_info.index_file_name= NULL;
+ if (src_table->table->versioned() &&
+ local_create_info.vers_info.fix_create_like(local_alter_info, local_create_info,
+ *src_table, *table))
+ {
+ goto err;
+ }
+
/* The following is needed only in case of lock tables */
if ((local_create_info.table= thd->lex->query_tables->table))
pos_in_locked_tables= local_create_info.table->pos_in_locked_tables;
res= ((create_res=
- mysql_create_table_no_lock(thd, table->db, table->table_name,
+ mysql_create_table_no_lock(thd, &table->db, &table->table_name,
&local_create_info, &local_alter_info,
&is_trans, C_ORDINARY_CREATE,
table)) > 0);
@@ -5398,8 +5757,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
non-temporary table.
*/
DBUG_ASSERT((create_info->tmp_table()) ||
- thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
- table->table_name,
+ thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db.str,
+ table->table_name.str,
MDL_EXCLUSIVE));
}
@@ -5556,9 +5915,7 @@ err:
Table was not deleted. Original table was deleted.
We have to log it.
*/
- log_drop_table(thd, table->db, table->db_length,
- table->table_name, table->table_name_length,
- create_info->tmp_table());
+ log_drop_table(thd, &table->db, &table->table_name, create_info->tmp_table());
}
else if (write_bin_log(thd, res ? FALSE : TRUE, thd->query(),
thd->query_length(), is_trans))
@@ -5779,6 +6136,40 @@ drop_create_field:
}
}
+ /* Handle ALTER COLUMN IF EXISTS SET/DROP DEFAULT. */
+ {
+ List_iterator<Alter_column> it(alter_info->alter_list);
+ Alter_column *acol;
+
+ while ((acol=it++))
+ {
+ if (!acol->alter_if_exists)
+ continue;
+ /*
+ If there is NO field with the same name in the table already,
+ remove the acol from the list.
+ */
+ for (f_ptr=table->field; *f_ptr; f_ptr++)
+ {
+ if (my_strcasecmp(system_charset_info,
+ acol->name, (*f_ptr)->field_name.str) == 0)
+ break;
+ }
+ if (*f_ptr == NULL)
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_BAD_FIELD_ERROR,
+ ER_THD(thd, ER_BAD_FIELD_ERROR),
+ acol->name, table->s->table_name.str);
+ it.remove();
+ if (alter_info->alter_list.is_empty())
+ {
+ alter_info->flags&= ~(Alter_info::ALTER_CHANGE_COLUMN_DEFAULT);
+ }
+ }
+ }
+ }
+
/* Handle DROP COLUMN/KEY IF EXISTS. */
{
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
@@ -5807,7 +6198,9 @@ drop_create_field:
}
else if (drop->type == Alter_drop::CHECK_CONSTRAINT)
{
- for (uint i=table->s->field_check_constraints; i < table->s->table_check_constraints; i++)
+ for (uint i=table->s->field_check_constraints;
+ i < table->s->table_check_constraints;
+ i++)
{
if (my_strcasecmp(system_charset_info, drop->name,
table->check_constraints[i]->name.str) == 0)
@@ -6000,6 +6393,7 @@ remove_key:
#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *tab_part_info= table->part_info;
+ thd->work_part_info= thd->lex->part_info;
if (tab_part_info)
{
/* ALTER TABLE ADD PARTITION IF NOT EXISTS */
@@ -6020,7 +6414,7 @@ remove_key:
ER_THD(thd, ER_SAME_NAME_PARTITION),
pe->partition_name);
alter_info->flags&= ~Alter_info::ALTER_ADD_PARTITION;
- thd->lex->part_info= NULL;
+ thd->work_part_info= NULL;
break;
}
}
@@ -6226,6 +6620,14 @@ static bool fill_alter_inplace_info(THD *thd,
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_ADD_CHECK_CONSTRAINT;
if (alter_info->flags & Alter_info::ALTER_DROP_CHECK_CONSTRAINT)
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_DROP_CHECK_CONSTRAINT;
+ if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_DROP)
+ ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_DROP_HISTORICAL;
+ if (alter_info->flags & Alter_info::ALTER_COLUMN_UNVERSIONED)
+ ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_UNVERSIONED;
+ if (alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING)
+ ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_ADD_SYSTEM_VERSIONING;
+ if (alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING)
+ ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_DROP_SYSTEM_VERSIONING;
/*
If we altering table with old VARCHAR fields we will be automatically
@@ -7258,11 +7660,34 @@ static bool mysql_inplace_alter_table(THD *thd,
DEBUG_SYNC(thd, "alter_table_inplace_before_commit");
THD_STAGE_INFO(thd, stage_alter_inplace_commit);
- if (table->file->ha_commit_inplace_alter_table(altered_table,
- ha_alter_info,
- true))
{
- goto rollback;
+ TR_table trt(thd, true);
+ if (trt != *table_list && table->file->ht->prepare_commit_versioned)
+ {
+ ulonglong trx_start_id= 0;
+ ulonglong trx_end_id= table->file->ht->prepare_commit_versioned(thd, &trx_start_id);
+ if (trx_end_id)
+ {
+ if (!TR_table::use_transaction_registry)
+ {
+ my_error(ER_VERS_TRT_IS_DISABLED, MYF(0));
+ goto rollback;
+ }
+ if (trt.update(trx_start_id, trx_end_id))
+ {
+ goto rollback;
+ }
+ }
+ }
+
+ if (table->file->ha_commit_inplace_alter_table(altered_table,
+ ha_alter_info,
+ true))
+ {
+ goto rollback;
+ }
+
+ thd->drop_temporary_table(altered_table, NULL, false);
}
close_all_tables_for_name(thd, table->s,
@@ -7272,19 +7697,17 @@ static bool mysql_inplace_alter_table(THD *thd,
NULL);
table_list->table= table= NULL;
- thd->drop_temporary_table(altered_table, NULL, false);
-
/*
Replace the old .FRM with the new .FRM, but keep the old name for now.
Rename to the new name (if needed) will be handled separately below.
*/
- if (mysql_rename_table(db_type, alter_ctx->new_db, alter_ctx->tmp_name,
- alter_ctx->db, alter_ctx->alias,
+ if (mysql_rename_table(db_type, &alter_ctx->new_db, &alter_ctx->tmp_name,
+ &alter_ctx->db, &alter_ctx->alias,
FN_FROM_IS_TMP | NO_HA_TABLE))
{
// Since changes were done in-place, we can't revert them.
(void) quick_rm_table(thd, db_type,
- alter_ctx->new_db, alter_ctx->tmp_name,
+ &alter_ctx->new_db, &alter_ctx->tmp_name,
FN_IS_TMP | NO_HA_TABLE);
DBUG_RETURN(true);
}
@@ -7312,10 +7735,10 @@ static bool mysql_inplace_alter_table(THD *thd,
{
// Remove TABLE and TABLE_SHARE for old name from TDC.
tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
- alter_ctx->db, alter_ctx->table_name, false);
+ alter_ctx->db.str, alter_ctx->table_name.str, false);
- if (mysql_rename_table(db_type, alter_ctx->db, alter_ctx->table_name,
- alter_ctx->new_db, alter_ctx->new_alias, 0))
+ if (mysql_rename_table(db_type, &alter_ctx->db, &alter_ctx->table_name,
+ &alter_ctx->new_db, &alter_ctx->new_alias, 0))
{
/*
If the rename fails we will still have a working table
@@ -7324,23 +7747,23 @@ static bool mysql_inplace_alter_table(THD *thd,
DBUG_RETURN(true);
}
if (Table_triggers_list::change_table_name(thd,
- alter_ctx->db,
- alter_ctx->alias,
- alter_ctx->table_name,
- alter_ctx->new_db,
- alter_ctx->new_alias))
+ &alter_ctx->db,
+ &alter_ctx->alias,
+ &alter_ctx->table_name,
+ &alter_ctx->new_db,
+ &alter_ctx->new_alias))
{
/*
If the rename of trigger files fails, try to rename the table
back so we at least have matching table and trigger files.
*/
(void) mysql_rename_table(db_type,
- alter_ctx->new_db, alter_ctx->new_alias,
- alter_ctx->db, alter_ctx->alias, NO_FK_CHECKS);
+ &alter_ctx->new_db, &alter_ctx->new_alias,
+ &alter_ctx->db, &alter_ctx->alias, NO_FK_CHECKS);
DBUG_RETURN(true);
}
- rename_table_in_stat_tables(thd, alter_ctx->db,alter_ctx->alias,
- alter_ctx->new_db, alter_ctx->new_alias);
+ rename_table_in_stat_tables(thd, &alter_ctx->db, &alter_ctx->alias,
+ &alter_ctx->new_db, &alter_ctx->new_alias);
}
DBUG_RETURN(false);
@@ -7364,8 +7787,8 @@ static bool mysql_inplace_alter_table(THD *thd,
}
thd->drop_temporary_table(altered_table, NULL, false);
// Delete temporary .frm/.par
- (void) quick_rm_table(thd, create_info->db_type, alter_ctx->new_db,
- alter_ctx->tmp_name, FN_IS_TMP | NO_HA_TABLE);
+ (void) quick_rm_table(thd, create_info->db_type, &alter_ctx->new_db,
+ &alter_ctx->tmp_name, FN_IS_TMP | NO_HA_TABLE);
DBUG_RETURN(true);
}
@@ -7398,6 +7821,19 @@ blob_length_by_type(enum_field_types type)
}
+static void append_drop_column(THD *thd, bool dont, String *str,
+ Field *field)
+{
+ if (!dont)
+ {
+ if (str->length())
+ str->append(STRING_WITH_LEN(", "));
+ str->append(STRING_WITH_LEN("DROP COLUMN "));
+ append_identifier(thd, str, &field->field_name);
+ }
+}
+
+
/**
Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
@@ -7461,7 +7897,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
List<Virtual_column_info> new_constraint_list;
uint db_create_options= (table->s->db_create_options
& ~(HA_OPTION_PACK_RECORD));
- uint used_fields;
+ Item::func_processor_rename column_rename_param;
+ uint used_fields, dropped_sys_vers_fields= 0;
KEY *key_info=table->key_info;
bool rc= TRUE;
bool modified_primary_key= FALSE;
@@ -7513,6 +7950,11 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (!(used_fields & HA_CREATE_USED_SEQUENCE))
create_info->sequence= table->s->table_type == TABLE_TYPE_SEQUENCE;
+ column_rename_param.db_name= table->s->db;
+ column_rename_param.table_name= table->s->table_name;
+ if (column_rename_param.fields.copy(&alter_info->create_list, thd->mem_root))
+ DBUG_RETURN(1); // OOM
+
restore_record(table, s->default_values); // Empty record for DEFAULT
if ((create_info->fields_option_struct= (ha_field_option_struct**)
@@ -7530,6 +7972,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
bitmap_clear_all(&table->tmp_set);
for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
{
+ if (field->invisible == INVISIBLE_FULL)
+ continue;
Alter_drop *drop;
if (field->type() == MYSQL_TYPE_VARCHAR)
create_info->varchar= TRUE;
@@ -7541,7 +7985,15 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
!my_strcasecmp(system_charset_info,field->field_name.str, drop->name))
break;
}
- if (drop)
+ /*
+ DROP COLULMN xxx
+ 1. it does not see INVISIBLE_SYSTEM columns
+ 2. otherwise, normally a column is dropped
+ 3. unless it's a system versioning column (but see below).
+ */
+ if (drop && field->invisible < INVISIBLE_SYSTEM &&
+ !(field->flags & VERS_SYSTEM_FIELD &&
+ !(alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING)))
{
/* Reset auto_increment value if it was dropped */
if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
@@ -7552,11 +8004,40 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
if (table->s->tmp_table == NO_TMP_TABLE)
(void) delete_statistics_for_column(thd, table, field);
+ dropped_sys_vers_fields|= field->flags;
drop_it.remove();
dropped_fields= &table->tmp_set;
bitmap_set_bit(dropped_fields, field->field_index);
continue;
}
+
+ /* invisible versioning column is dropped automatically on DROP SYSTEM VERSIONING */
+ if (!drop && field->invisible >= INVISIBLE_SYSTEM &&
+ field->flags & VERS_SYSTEM_FIELD &&
+ alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING)
+ {
+ if (table->s->tmp_table == NO_TMP_TABLE)
+ (void) delete_statistics_for_column(thd, table, field);
+ continue;
+ }
+
+ /*
+ If we are doing a rename of a column, update all references in virtual
+ column expressions, constraints and defaults to use the new column name
+ */
+ if (alter_info->flags & Alter_info::ALTER_RENAME_COLUMN)
+ {
+ if (field->vcol_info)
+ field->vcol_info->expr->walk(&Item::rename_fields_processor, 1,
+ &column_rename_param);
+ if (field->check_constraint)
+ field->check_constraint->expr->walk(&Item::rename_fields_processor, 1,
+ &column_rename_param);
+ if (field->default_value)
+ field->default_value->expr->walk(&Item::rename_fields_processor, 1,
+ &column_rename_param);
+ }
+
/* Check if field is changed */
def_it.rewind();
while ((def=def_it++))
@@ -7566,7 +8047,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
&def->change))
break;
}
- if (def)
+ if (def && field->invisible < INVISIBLE_SYSTEM)
{ // Field is changed
def->field=field;
/*
@@ -7592,6 +8073,31 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
def_it.remove();
}
}
+ else if (alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING &&
+ field->flags & VERS_SYSTEM_FIELD &&
+ field->invisible < INVISIBLE_SYSTEM)
+ {
+ StringBuffer<NAME_LEN*3> tmp;
+ append_drop_column(thd, false, &tmp, field);
+ my_error(ER_MISSING, MYF(0), table->s->table_name.str, tmp.c_ptr());
+ goto err;
+ }
+ else if (drop && field->invisible < INVISIBLE_SYSTEM &&
+ field->flags & VERS_SYSTEM_FIELD &&
+ !(alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING))
+ {
+ /* "dropping" a versioning field only hides it from the user */
+ def= new (thd->mem_root) Create_field(thd, field, field);
+ def->invisible= INVISIBLE_SYSTEM;
+ alter_info->flags|= Alter_info::ALTER_CHANGE_COLUMN;
+ if (field->flags & VERS_SYS_START_FLAG)
+ create_info->vers_info.as_row.start= def->field_name= Vers_parse_info::default_start;
+ else
+ create_info->vers_info.as_row.end= def->field_name= Vers_parse_info::default_end;
+ new_create_list.push_back(def, thd->mem_root);
+ dropped_sys_vers_fields|= field->flags;
+ drop_it.remove();
+ }
else
{
/*
@@ -7618,15 +8124,30 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
}
}
+ dropped_sys_vers_fields &= VERS_SYSTEM_FIELD;
+ if ((dropped_sys_vers_fields ||
+ alter_info->flags & Alter_info::ALTER_DROP_PERIOD) &&
+ dropped_sys_vers_fields != VERS_SYSTEM_FIELD)
+ {
+ StringBuffer<NAME_LEN*3> tmp;
+ append_drop_column(thd, dropped_sys_vers_fields & VERS_SYS_START_FLAG,
+ &tmp, table->vers_start_field());
+ append_drop_column(thd, dropped_sys_vers_fields & VERS_SYS_END_FLAG,
+ &tmp, table->vers_end_field());
+ my_error(ER_MISSING, MYF(0), table->s->table_name.str, tmp.c_ptr());
+ goto err;
+ }
+ alter_info->flags &=
+ ~(Alter_info::ALTER_DROP_PERIOD | Alter_info::ALTER_ADD_PERIOD);
def_it.rewind();
while ((def=def_it++)) // Add new columns
{
+ Create_field *find;
if (def->change.str && ! def->field)
{
/*
Check if there is modify for newly added field.
*/
- Create_field *find;
find_it.rewind();
while((find=find_it++))
{
@@ -7662,11 +8183,16 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
alter_ctx->datetime_field= def;
alter_ctx->error_if_not_empty= TRUE;
}
+ if (def->flags & VERS_SYSTEM_FIELD &&
+ !(alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING))
+ {
+ my_error(ER_VERS_NOT_VERSIONED, MYF(0), table->s->table_name.str);
+ goto err;
+ }
if (!def->after.str)
new_create_list.push_back(def, thd->mem_root);
else
{
- Create_field *find;
if (def->change.str)
{
find_it.rewind();
@@ -7725,7 +8251,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
{
if (def->real_field_type() == MYSQL_TYPE_BLOB)
{
- my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
+ my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change.str);
goto err;
}
if ((def->default_value= alter->default_value)) // Use new default
@@ -7753,9 +8279,11 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
Collect all keys which isn't in drop list. Add only those
for which some fields exists.
*/
-
+
for (uint i=0 ; i < table->s->keys ; i++,key_info++)
{
+ if (key_info->flags & HA_INVISIBLE_KEY)
+ continue;
const char *key_name= key_info->name.str;
Alter_drop *drop;
drop_it.rewind();
@@ -7792,9 +8320,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
bool delete_index_stat= FALSE;
for (uint j=0 ; j < key_info->user_defined_key_parts ; j++,key_part++)
{
- if (!key_part->field)
+ Field *kfield= key_part->field;
+ if (!kfield)
continue; // Wrong field (from UNIREG)
- const char *key_part_name=key_part->field->field_name.str;
+ const char *key_part_name=kfield->field_name.str;
Create_field *cfield;
uint key_part_length;
@@ -7816,7 +8345,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (table->s->primary_key == i)
modified_primary_key= TRUE;
delete_index_stat= TRUE;
- dropped_key_part= key_part_name;
+ if (!(kfield->flags & VERS_SYSTEM_FIELD))
+ dropped_key_part= key_part_name;
continue; // Field is removed
}
key_part_length= key_part->length;
@@ -7853,10 +8383,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
cfield->real_field_type() <= MYSQL_TYPE_BLOB) ?
blob_length_by_type(cfield->real_field_type()) :
cfield->length) <
- key_part_length / key_part->field->charset()->mbmaxlen)))
+ key_part_length / kfield->charset()->mbmaxlen)))
key_part_length= 0; // Use whole field
}
- key_part_length /= key_part->field->charset()->mbmaxlen;
+ key_part_length /= kfield->charset()->mbmaxlen;
key_parts.push_back(new Key_part_spec(&cfield->field_name,
key_part_length),
thd->mem_root);
@@ -7973,7 +8503,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
}
if (!drop)
+ {
+ check->expr->walk(&Item::rename_fields_processor, 1, &column_rename_param);
new_constraint_list.push_back(check, thd->mem_root);
+ }
}
}
/* Add new constraints */
@@ -7998,6 +8531,13 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
}
+ if (table->versioned() && !(alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING) &&
+ new_create_list.elements == VERSIONING_FIELDS)
+ {
+ my_error(ER_VERS_TABLE_MUST_HAVE_COLUMNS, MYF(0), table->s->table_name.str);
+ goto err;
+ }
+
if (!create_info->comment.str)
{
create_info->comment.str= table->s->comment.str;
@@ -8279,9 +8819,9 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
StringBuffer<NAME_LEN*2+2> buff(system_charset_info);
LEX_CSTRING *db= f_key->foreign_db, *tbl= f_key->foreign_table;
- append_identifier(thd, &buff, db->str, db->length);
+ append_identifier(thd, &buff, db);
buff.append('.');
- append_identifier(thd, &buff, tbl->str,tbl->length);
+ append_identifier(thd, &buff, tbl);
my_error(ER_FK_COLUMN_CANNOT_DROP_CHILD, MYF(0), bad_column_name,
f_key->foreign_id->str, buff.c_ptr());
DBUG_RETURN(true);
@@ -8397,8 +8937,8 @@ simple_tmp_rename_or_index_change(THD *thd, TABLE_LIST *table_list,
back to the original name (unlike the case for non-temporary tables),
as it was an allocation error and the table was not renamed.
*/
- error= thd->rename_temporary_table(table, alter_ctx->new_db,
- alter_ctx->new_alias);
+ error= thd->rename_temporary_table(table, &alter_ctx->new_db,
+ &alter_ctx->new_alias);
}
if (!error)
@@ -8477,32 +9017,40 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list,
*/
if (wait_while_table_is_used(thd, table, extra_func))
DBUG_RETURN(true);
- close_all_tables_for_name(thd, table->s, HA_EXTRA_PREPARE_FOR_RENAME, NULL);
-
- LEX_CSTRING old_db_name= { alter_ctx->db, strlen(alter_ctx->db) };
- LEX_CSTRING old_table_name=
- { alter_ctx->table_name, strlen(alter_ctx->table_name) };
- LEX_CSTRING new_db_name= { alter_ctx->new_db, strlen(alter_ctx->new_db) };
- LEX_CSTRING new_table_name=
- { alter_ctx->new_alias, strlen(alter_ctx->new_alias) };
- (void) rename_table_in_stat_tables(thd, &old_db_name, &old_table_name,
- &new_db_name, &new_table_name);
-
- if (mysql_rename_table(old_db_type, alter_ctx->db, alter_ctx->table_name,
- alter_ctx->new_db, alter_ctx->new_alias, 0))
- error= -1;
- else if (Table_triggers_list::change_table_name(thd,
- alter_ctx->db,
- alter_ctx->alias,
- alter_ctx->table_name,
- alter_ctx->new_db,
- alter_ctx->new_alias))
- {
- (void) mysql_rename_table(old_db_type,
- alter_ctx->new_db, alter_ctx->new_alias,
- alter_ctx->db, alter_ctx->table_name,
- NO_FK_CHECKS);
+ close_all_tables_for_name(thd, table->s, HA_EXTRA_PREPARE_FOR_RENAME,
+ NULL);
+
+ (void) rename_table_in_stat_tables(thd, &alter_ctx->db,
+ &alter_ctx->table_name,
+ &alter_ctx->new_db,
+ &alter_ctx->new_alias);
+
+ if (mysql_rename_table(old_db_type, &alter_ctx->db, &alter_ctx->table_name,
+ &alter_ctx->new_db, &alter_ctx->new_alias, 0))
error= -1;
+ else
+ {
+ VTMD_rename vtmd(*table_list);
+ if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE &&
+ vtmd.try_rename(thd, alter_ctx->new_db.str, alter_ctx->new_alias.str))
+ goto revert_table_name;
+
+ if (Table_triggers_list::change_table_name(thd,
+ &alter_ctx->db,
+ &alter_ctx->alias,
+ &alter_ctx->table_name,
+ &alter_ctx->new_db,
+ &alter_ctx->new_alias))
+ {
+ if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
+ vtmd.revert_rename(thd, alter_ctx->new_db.str);
+ revert_table_name:
+ (void) mysql_rename_table(old_db_type,
+ &alter_ctx->new_db, &alter_ctx->new_alias,
+ &alter_ctx->db, &alter_ctx->table_name,
+ NO_FK_CHECKS);
+ error= -1;
+ }
}
}
@@ -8571,7 +9119,7 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list,
based on information about the table changes from fill_alter_inplace_info().
*/
-bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
+bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *new_name,
HA_CREATE_INFO *create_info,
TABLE_LIST *table_list,
Alter_info *alter_info,
@@ -8634,6 +9182,58 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
&alter_prelocking_strategy);
thd->open_options&= ~HA_OPEN_FOR_ALTER;
+ TABLE *table= table_list->table;
+ bool versioned= table && table->versioned();
+ bool vers_survival_mod= false;
+
+ if (versioned)
+ {
+ if (handlerton *hton1= create_info->db_type)
+ {
+ handlerton *hton2= table->file->partition_ht();
+ if (hton1 != hton2 &&
+ (ha_check_storage_engine_flag(hton1, HTON_NATIVE_SYS_VERSIONING) ||
+ ha_check_storage_engine_flag(hton2, HTON_NATIVE_SYS_VERSIONING)))
+ {
+ my_error(ER_VERS_ALTER_ENGINE_PROHIBITED, MYF(0), table_list->db.str,
+ table_list->table_name.str);
+ DBUG_RETURN(true);
+ }
+ }
+ bool vers_data_mod= alter_info->data_modifying();
+ if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
+ {
+ vers_survival_mod= alter_info->data_modifying() || alter_info->partition_modifying();
+ }
+ else if (vers_data_mod && !thd->slave_thread &&
+ thd->variables.vers_alter_history == VERS_ALTER_HISTORY_ERROR)
+ {
+ my_error(ER_VERS_ALTER_NOT_ALLOWED, MYF(0),
+ table_list->db.str, table_list->table_name.str);
+ DBUG_RETURN(true);
+ }
+ }
+
+ if (vers_survival_mod)
+ {
+ table_list->set_lock_type(thd, TL_WRITE);
+ if (thd->mdl_context.upgrade_shared_lock(table_list->table->mdl_ticket,
+ MDL_EXCLUSIVE,
+ thd->variables.lock_wait_timeout))
+ {
+ DBUG_RETURN(true);
+ }
+
+ if (table_list->table->versioned(VERS_TRX_ID) &&
+ alter_info->requested_algorithm ==
+ Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT &&
+ !table_list->table->s->partition_info_str)
+ {
+ // Changle default ALGORITHM to COPY for INNODB
+ alter_info->requested_algorithm= Alter_info::ALTER_TABLE_ALGORITHM_COPY;
+ }
+ }
+
DEBUG_SYNC(thd, "alter_opened_table");
#ifdef WITH_WSREP
@@ -8650,7 +9250,6 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
if (error)
DBUG_RETURN(true);
- TABLE *table= table_list->table;
table->use_all_columns();
MDL_ticket *mdl_ticket= table->mdl_ticket;
@@ -8683,9 +9282,9 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
If such table exists, there must be a corresponding TABLE_SHARE in
THD::all_temp_tables list.
*/
- if (thd->find_tmp_table_share(alter_ctx.new_db, alter_ctx.new_name))
+ if (thd->find_tmp_table_share(alter_ctx.new_db.str, alter_ctx.new_name.str))
{
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias.str);
DBUG_RETURN(true);
}
}
@@ -8695,7 +9294,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
MDL_request target_db_mdl_request;
target_mdl_request.init(MDL_key::TABLE,
- alter_ctx.new_db, alter_ctx.new_name,
+ alter_ctx.new_db.str, alter_ctx.new_name.str,
MDL_EXCLUSIVE, MDL_TRANSACTION);
mdl_requests.push_front(&target_mdl_request);
@@ -8706,7 +9305,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
*/
if (alter_ctx.is_database_changed())
{
- target_db_mdl_request.init(MDL_key::SCHEMA, alter_ctx.new_db, "",
+ target_db_mdl_request.init(MDL_key::SCHEMA, alter_ctx.new_db.str, "",
MDL_INTENTION_EXCLUSIVE,
MDL_TRANSACTION);
mdl_requests.push_front(&target_db_mdl_request);
@@ -8729,10 +9328,10 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
Table maybe does not exist, but we got an exclusive lock
on the name, now we can safely try to find out for sure.
*/
- if (ha_table_exists(thd, alter_ctx.new_db, alter_ctx.new_name))
+ if (ha_table_exists(thd, &alter_ctx.new_db, &alter_ctx.new_name))
{
/* Table will be closed in do_command() */
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias.str);
DBUG_RETURN(true);
}
}
@@ -8758,9 +9357,14 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
create_info->db_type= table->s->db_type();
}
- if (check_engine(thd, alter_ctx.new_db, alter_ctx.new_name, create_info))
+ if (check_engine(thd, alter_ctx.new_db.str, alter_ctx.new_name.str, create_info))
DBUG_RETURN(true);
+ if (create_info->vers_info.fix_alter_info(thd, alter_info, create_info, table))
+ {
+ DBUG_RETURN(true);
+ }
+
if ((create_info->db_type != table->s->db_type() ||
alter_info->flags & Alter_info::ALTER_PARTITION) &&
!table->file->can_switch_engines())
@@ -8778,7 +9382,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
till this point for the alter operation.
*/
if ((alter_info->flags & Alter_info::ADD_FOREIGN_KEY) &&
- check_fk_parent_table_access(thd, create_info, alter_info, new_db))
+ check_fk_parent_table_access(thd, create_info, alter_info, new_db->str))
DBUG_RETURN(true);
/*
@@ -8804,7 +9408,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
{
DBUG_PRINT("info", ("doesn't support alter"));
my_error(ER_ILLEGAL_HA, MYF(0), hton_name(table->s->db_type())->str,
- alter_ctx.db, alter_ctx.table_name);
+ alter_ctx.db.str, alter_ctx.table_name.str);
DBUG_RETURN(true);
}
@@ -8813,7 +9417,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
{
DBUG_PRINT("info", ("doesn't support alter"));
my_error(ER_ILLEGAL_HA, MYF(0), hton_name(create_info->db_type)->str,
- alter_ctx.new_db, alter_ctx.new_name);
+ alter_ctx.new_db.str, alter_ctx.new_name.str);
DBUG_RETURN(true);
}
@@ -8831,10 +9435,10 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
*/
if (alter_info->flags == 0)
{
- my_snprintf(alter_ctx.tmp_name, sizeof(alter_ctx.tmp_name),
+ my_snprintf(alter_ctx.tmp_buff, sizeof(alter_ctx.tmp_buff),
ER_THD(thd, ER_INSERT_INFO), 0L, 0L,
thd->get_stmt_da()->current_statement_warn_count());
- my_ok(thd, 0L, 0L, alter_ctx.tmp_name);
+ my_ok(thd, 0L, 0L, alter_ctx.tmp_buff);
/* We don't replicate alter table statement on temporary tables */
if (table->s->tmp_table == NO_TMP_TABLE ||
@@ -8902,7 +9506,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
DBUG_RETURN(true);
}
- set_table_default_charset(thd, create_info, alter_ctx.db);
+ set_table_default_charset(thd, create_info, &alter_ctx.db);
if (!opt_explicit_defaults_for_timestamp)
promote_first_timestamp_column(&alter_info->create_list);
@@ -8939,9 +9543,11 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
Upgrade from MDL_SHARED_UPGRADABLE to MDL_SHARED_NO_WRITE.
Afterwards it's safe to take the table level lock.
*/
- if (thd->mdl_context.upgrade_shared_lock(mdl_ticket, MDL_SHARED_NO_WRITE,
- thd->variables.lock_wait_timeout)
- || lock_tables(thd, table_list, alter_ctx.tables_opened, 0))
+ if ((!vers_survival_mod &&
+ thd->mdl_context.upgrade_shared_lock(
+ mdl_ticket, MDL_SHARED_NO_WRITE,
+ thd->variables.lock_wait_timeout)) ||
+ lock_tables(thd, table_list, alter_ctx.tables_opened, 0))
{
DBUG_RETURN(true);
}
@@ -8949,8 +9555,8 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
// In-place execution of ALTER TABLE for partitioning.
DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info,
create_info, table_list,
- alter_ctx.db,
- alter_ctx.table_name));
+ &alter_ctx.db,
+ &alter_ctx.table_name));
}
#endif
@@ -9003,6 +9609,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
handlerton *new_db_type= create_info->db_type;
handlerton *old_db_type= table->s->db_type();
TABLE *new_table= NULL;
+ bool new_versioned= false;
ha_rows copied=0,deleted=0;
/*
@@ -9036,7 +9643,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
if (create_info->index_file_name)
{
/* Fix index_file_name to have 'tmp_name' as basename */
- strmov(index_file, alter_ctx.tmp_name);
+ strmov(index_file, alter_ctx.tmp_name.str);
create_info->index_file_name=fn_same(index_file,
create_info->index_file_name,
1);
@@ -9044,7 +9651,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
if (create_info->data_file_name)
{
/* Fix data_file_name to have 'tmp_name' as basename */
- strmov(data_file, alter_ctx.tmp_name);
+ strmov(data_file, alter_ctx.tmp_name.str);
create_info->data_file_name=fn_same(data_file,
create_info->data_file_name,
1);
@@ -9081,8 +9688,8 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
tmp_disable_binlog(thd);
create_info->options|=HA_CREATE_TMP_ALTER;
error= create_table_impl(thd,
- alter_ctx.db, alter_ctx.table_name,
- alter_ctx.new_db, alter_ctx.tmp_name,
+ &alter_ctx.db, &alter_ctx.table_name,
+ &alter_ctx.new_db, &alter_ctx.tmp_name,
alter_ctx.get_tmp_path(),
thd->lex->create_info, create_info, alter_info,
C_ALTER_TABLE_FRM_ONLY, NULL,
@@ -9140,8 +9747,9 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
if (!(altered_table=
thd->create_and_open_tmp_table(new_db_type, &frm,
alter_ctx.get_tmp_path(),
- alter_ctx.new_db, alter_ctx.tmp_name,
- false)))
+ alter_ctx.new_db.str,
+ alter_ctx.tmp_name.str,
+ false, true)))
goto err_new_table_cleanup;
/* Set markers for fields in TABLE object for altered table. */
@@ -9156,10 +9764,12 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
&altered_table->s->all_set);
restore_record(altered_table, s->default_values); // Create empty record
/* Check that we can call default functions with default field values */
+ thd->count_cuted_fields= CHECK_FIELD_EXPRESSION;
altered_table->reset_default_fields();
if (altered_table->default_field &&
altered_table->update_default_fields(0, 1))
goto err_new_table_cleanup;
+ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
// Ask storage engine whether to use copy or in-place
enum_alter_inplace_result inplace_supported=
@@ -9284,11 +9894,12 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
}
// It's now safe to take the table level lock.
- if (lock_tables(thd, table_list, alter_ctx.tables_opened, 0))
+ if (lock_tables(thd, table_list, alter_ctx.tables_opened,
+ MYSQL_LOCK_USE_MALLOC))
goto err_new_table_cleanup;
if (ha_create_table(thd, alter_ctx.get_tmp_path(),
- alter_ctx.new_db, alter_ctx.tmp_name,
+ alter_ctx.new_db.str, alter_ctx.tmp_name.str,
create_info, &frm))
goto err_new_table_cleanup;
@@ -9300,8 +9911,9 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
TABLE *tmp_table=
thd->create_and_open_tmp_table(new_db_type, &frm,
alter_ctx.get_tmp_path(),
- alter_ctx.new_db, alter_ctx.tmp_name,
- true);
+ alter_ctx.new_db.str,
+ alter_ctx.tmp_name.str,
+ true, true);
if (!tmp_table)
{
goto err_new_table_cleanup;
@@ -9315,9 +9927,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
if (table->s->tmp_table != NO_TMP_TABLE)
{
TABLE_LIST tbl;
- tbl.init_one_table(alter_ctx.new_db, strlen(alter_ctx.new_db),
- alter_ctx.tmp_name, strlen(alter_ctx.tmp_name),
- alter_ctx.tmp_name, TL_READ_NO_INSERT);
+ tbl.init_one_table(&alter_ctx.new_db, &alter_ctx.tmp_name, 0, TL_READ_NO_INSERT);
/*
Table can be found in the list of open tables in THD::all_temp_tables
list.
@@ -9334,11 +9944,14 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
new_table=
thd->create_and_open_tmp_table(new_db_type, &frm,
alter_ctx.get_tmp_path(),
- alter_ctx.new_db, alter_ctx.tmp_name,
- true);
+ alter_ctx.new_db.str,
+ alter_ctx.tmp_name.str,
+ true, true);
}
if (!new_table)
goto err_new_table_cleanup;
+ new_table->s->orig_table_name= table->s->table_name.str;
+ new_versioned= new_table->versioned();
/*
Note: In case of MERGE table, we do not attach children. We do not
copy data for MERGE tables. Only the children have data.
@@ -9365,7 +9978,14 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
order_num, order, &copied, &deleted,
alter_info->keys_onoff,
&alter_ctx))
+ {
+ if (vers_survival_mod && new_versioned && table->versioned(VERS_TIMESTAMP))
+ {
+ // Failure of this function may result in corruption of an original table.
+ vers_reset_alter_copy(thd, table);
+ }
goto err_new_table_cleanup;
+ }
}
else
{
@@ -9405,8 +10025,8 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
/* Remove link to old table and rename the new one */
thd->drop_temporary_table(table, NULL, true);
/* Should pass the 'new_name' as we store table name in the cache */
- if (thd->rename_temporary_table(new_table, alter_ctx.new_db,
- alter_ctx.new_name))
+ if (thd->rename_temporary_table(new_table, &alter_ctx.new_db,
+ &alter_ctx.new_name))
goto err_new_table_cleanup;
/* We don't replicate alter table statement on temporary tables */
if (!thd->is_current_stmt_binlog_format_row() &&
@@ -9460,61 +10080,85 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
Rename the old table to temporary name to have a backup in case
anything goes wrong while renaming the new table.
*/
- char backup_name[32];
- my_snprintf(backup_name, sizeof(backup_name), "%s2-%lx-%lx", tmp_file_prefix,
- current_pid, (long) thd->thread_id);
+ char backup_name_buff[FN_LEN];
+ LEX_CSTRING backup_name;
+ backup_name.str= backup_name_buff;
+
+ if (vers_survival_mod)
+ {
+ VTMD_table::archive_name(thd, alter_ctx.table_name.str, backup_name_buff,
+ sizeof(backup_name_buff));
+ backup_name.length= strlen(backup_name_buff);
+ }
+ else
+ backup_name.length= my_snprintf(backup_name_buff, sizeof(backup_name_buff),
+ "%s2-%lx-%lx", tmp_file_prefix,
+ current_pid, (long) thd->thread_id);
if (lower_case_table_names)
- my_casedn_str(files_charset_info, backup_name);
- if (mysql_rename_table(old_db_type, alter_ctx.db, alter_ctx.table_name,
- alter_ctx.db, backup_name, FN_TO_IS_TMP))
+ my_casedn_str(files_charset_info, backup_name_buff);
+ if (mysql_rename_table(old_db_type, &alter_ctx.db, &alter_ctx.table_name,
+ &alter_ctx.db, &backup_name, FN_TO_IS_TMP))
{
// Rename to temporary name failed, delete the new table, abort ALTER.
- (void) quick_rm_table(thd, new_db_type, alter_ctx.new_db,
- alter_ctx.tmp_name, FN_IS_TMP);
+ (void) quick_rm_table(thd, new_db_type, &alter_ctx.new_db,
+ &alter_ctx.tmp_name, FN_IS_TMP);
goto err_with_mdl;
}
// Rename the new table to the correct name.
- if (mysql_rename_table(new_db_type, alter_ctx.new_db, alter_ctx.tmp_name,
- alter_ctx.new_db, alter_ctx.new_alias,
+ if (mysql_rename_table(new_db_type, &alter_ctx.new_db, &alter_ctx.tmp_name,
+ &alter_ctx.new_db, &alter_ctx.new_alias,
FN_FROM_IS_TMP))
{
// Rename failed, delete the temporary table.
- (void) quick_rm_table(thd, new_db_type, alter_ctx.new_db,
- alter_ctx.tmp_name, FN_IS_TMP);
+ (void) quick_rm_table(thd, new_db_type, &alter_ctx.new_db,
+ &alter_ctx.tmp_name, FN_IS_TMP);
// Restore the backup of the original table to the old name.
- (void) mysql_rename_table(old_db_type, alter_ctx.db, backup_name,
- alter_ctx.db, alter_ctx.alias,
+ (void) mysql_rename_table(old_db_type, &alter_ctx.db, &backup_name,
+ &alter_ctx.db, &alter_ctx.alias,
FN_FROM_IS_TMP | NO_FK_CHECKS);
goto err_with_mdl;
}
+ if (vers_survival_mod && new_versioned)
+ {
+ DBUG_ASSERT(alter_info && table_list);
+ VTMD_rename vtmd(*table_list);
+ bool rc= alter_info->flags & Alter_info::ALTER_RENAME ?
+ vtmd.try_rename(thd, alter_ctx.new_db.str, alter_ctx.new_alias.str, backup_name.str) :
+ vtmd.update(thd, backup_name.str);
+ if (rc)
+ goto err_after_rename;
+ }
+
// Check if we renamed the table and if so update trigger files.
if (alter_ctx.is_table_renamed())
{
if (Table_triggers_list::change_table_name(thd,
- alter_ctx.db,
- alter_ctx.alias,
- alter_ctx.table_name,
- alter_ctx.new_db,
- alter_ctx.new_alias))
+ &alter_ctx.db,
+ &alter_ctx.alias,
+ &alter_ctx.table_name,
+ &alter_ctx.new_db,
+ &alter_ctx.new_alias))
{
+err_after_rename:
// Rename succeeded, delete the new table.
(void) quick_rm_table(thd, new_db_type,
- alter_ctx.new_db, alter_ctx.new_alias, 0);
+ &alter_ctx.new_db, &alter_ctx.new_alias, 0);
// Restore the backup of the original table to the old name.
- (void) mysql_rename_table(old_db_type, alter_ctx.db, backup_name,
- alter_ctx.db, alter_ctx.alias,
+ (void) mysql_rename_table(old_db_type, &alter_ctx.db, &backup_name,
+ &alter_ctx.db, &alter_ctx.alias,
FN_FROM_IS_TMP | NO_FK_CHECKS);
goto err_with_mdl;
}
- rename_table_in_stat_tables(thd, alter_ctx.db,alter_ctx.alias,
- alter_ctx.new_db, alter_ctx.new_alias);
+ rename_table_in_stat_tables(thd, &alter_ctx.db, &alter_ctx.alias,
+ &alter_ctx.new_db, &alter_ctx.new_alias);
}
// ALTER TABLE succeeded, delete the backup of the old table.
- if (quick_rm_table(thd, old_db_type, alter_ctx.db, backup_name, FN_IS_TMP))
+ if (!(vers_survival_mod && new_versioned) &&
+ quick_rm_table(thd, old_db_type, &alter_ctx.db, &backup_name, FN_IS_TMP))
{
/*
The fact that deletion of the backup failed is not critical
@@ -9552,11 +10196,11 @@ end_inplace:
}
end_temporary:
- my_snprintf(alter_ctx.tmp_name, sizeof(alter_ctx.tmp_name),
+ my_snprintf(alter_ctx.tmp_buff, sizeof(alter_ctx.tmp_buff),
ER_THD(thd, ER_INSERT_INFO),
(ulong) (copied + deleted), (ulong) deleted,
(ulong) thd->get_stmt_da()->current_statement_warn_count());
- my_ok(thd, copied + deleted, 0L, alter_ctx.tmp_name);
+ my_ok(thd, copied + deleted, 0L, alter_ctx.tmp_buff);
DBUG_RETURN(false);
err_new_table_cleanup:
@@ -9567,7 +10211,7 @@ err_new_table_cleanup:
}
else
(void) quick_rm_table(thd, new_db_type,
- alter_ctx.new_db, alter_ctx.tmp_name,
+ &alter_ctx.new_db, &alter_ctx.tmp_name,
(FN_IS_TMP | (no_ha_table ? NO_HA_TABLE : 0)),
alter_ctx.get_tmp_path());
@@ -9701,6 +10345,11 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
sql_mode_t save_sql_mode= thd->variables.sql_mode;
ulonglong prev_insert_id, time_to_report_progress;
Field **dfield_ptr= to->default_field;
+ bool make_versioned= !from->versioned() && to->versioned();
+ bool make_unversioned= from->versioned() && !to->versioned();
+ bool keep_versioned= from->versioned() && to->versioned();
+ Field *to_row_start= NULL, *to_row_end= NULL, *from_row_end= NULL;
+ MYSQL_TIME query_start;
DBUG_ENTER("copy_data_between_tables");
/* Two or 3 stages; Sorting, copying data and update indexes */
@@ -9783,8 +10432,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
{
bzero((char *) &tables, sizeof(tables));
tables.table= from;
- tables.alias= tables.table_name= from->s->table_name.str;
- tables.db= from->s->db.str;
+ tables.alias= tables.table_name= from->s->table_name;
+ tables.db= from->s->db;
THD_STAGE_INFO(thd, stage_sorting);
Filesort_tracker dummy_tracker(false);
@@ -9801,6 +10450,29 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
thd_progress_next_stage(thd);
}
+ if (make_versioned)
+ {
+ query_start= thd->query_start_TIME();
+ to_row_start= to->vers_start_field();
+ to_row_end= to->vers_end_field();
+ }
+ else if (make_unversioned)
+ {
+ from_row_end= from->vers_end_field();
+ }
+ else if (keep_versioned)
+ {
+ if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
+ {
+ query_start= thd->query_start_TIME();
+ from_row_end= from->vers_end_field();
+ to_row_start= to->vers_start_field();
+ } else if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_DROP)
+ {
+ from_row_end= from->vers_end_field();
+ }
+ }
+
THD_STAGE_INFO(thd, stage_copy_to_tmp_table);
/* Tell handler that we have values for all columns in the to table */
to->use_all_columns();
@@ -9820,6 +10492,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
thd->progress.max_counter= from->file->records();
time_to_report_progress= MY_HOW_OFTEN_TO_WRITE/10;
+ if (!ignore) /* for now, InnoDB needs the undo log for ALTER IGNORE */
+ to->file->extra(HA_EXTRA_BEGIN_ALTER_COPY);
while (!(error= info.read_record()))
{
@@ -9854,6 +10528,36 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
{
copy_ptr->do_copy(copy_ptr);
}
+
+ if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_DROP &&
+ from_row_end && !from_row_end->is_max())
+ {
+ continue;
+ }
+
+ if (make_versioned)
+ {
+ to_row_start->set_notnull();
+ to_row_start->store_time(&query_start);
+ to_row_end->set_max();
+ }
+ else if (make_unversioned)
+ {
+ if (!from_row_end->is_max())
+ continue; // Drop history rows.
+ }
+ else if (keep_versioned &&
+ thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
+ {
+ if (!from_row_end->is_max())
+ continue; // Do not copy history rows.
+
+ store_record(from, record[1]);
+ from->vers_end_field()->store_time(&query_start);
+ from->file->ha_update_row(from->record[1], from->record[0]);
+ to_row_start->store_time(&query_start);
+ }
+
prev_insert_id= to->file->next_insert_id;
if (to->default_field)
to->update_default_fields(0, ignore);
@@ -9868,7 +10572,12 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
error= 1;
break;
}
- error=to->file->ha_write_row(to->record[0]);
+ if (keep_versioned && to->versioned(VERS_TRX_ID) &&
+ thd->variables.vers_alter_history != VERS_ALTER_HISTORY_SURVIVE)
+ {
+ to->vers_write= false;
+ }
+ error= to->file->ha_write_row(to->record[0]);
to->auto_increment_field_not_null= FALSE;
if (error)
{
@@ -9910,11 +10619,12 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
if ((int) key_nr >= 0)
{
const char *err_msg= ER_THD(thd, ER_DUP_ENTRY_WITH_KEY_NAME);
- if (key_nr == 0 &&
+ if (key_nr == 0 && to->s->keys > 0 &&
(to->key_info[0].key_part[0].field->flags &
AUTO_INCREMENT_FLAG))
err_msg= ER_THD(thd, ER_DUP_ENTRY_AUTOINCREMENT_CASE);
- print_keydup_error(to, key_nr == MAX_KEY ? NULL :
+ print_keydup_error(to,
+ key_nr >= to->s->keys ? NULL :
&to->key_info[key_nr],
err_msg, MYF(0));
}
@@ -9944,6 +10654,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
to->file->print_error(my_errno,MYF(0));
error= 1;
}
+ if (!ignore)
+ to->file->extra(HA_EXTRA_END_ALTER_COPY);
to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
if (mysql_trans_commit_alter_copy_data(thd))
@@ -10011,7 +10723,7 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool table_copy)
thd->prepare_logs_for_admin_command();
- bool res= mysql_alter_table(thd, NullS, NullS, &create_info,
+ bool res= mysql_alter_table(thd, &null_clex_str, &null_clex_str, &create_info,
table_list, &alter_info, 0,
(ORDER *) 0, 0);
table_list->next_global= next_table;
@@ -10074,7 +10786,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
TABLE *t;
TABLE_LIST *save_next_global;
- strxmov(table_name, table->db ,".", table->table_name, NullS);
+ strxmov(table_name, table->db.str ,".", table->table_name.str, NullS);
/* Remember old 'next' pointer and break the list. */
save_next_global= table->next_global;
diff --git a/sql/sql_table.h b/sql/sql_table.h
index e45ddef6548..9958a56958e 100644
--- a/sql/sql_table.h
+++ b/sql/sql_table.h
@@ -141,10 +141,10 @@ static const uint SKIP_SYMDIR_ACCESS= 1 << 5;
/** Don't check foreign key constraints while renaming table */
static const uint NO_FK_CHECKS= 1 << 6;
-uint filename_to_tablename(const char *from, char *to, uint to_length,
+uint filename_to_tablename(const char *from, char *to, size_t to_length,
bool stay_quiet = false);
-uint tablename_to_filename(const char *from, char *to, uint to_length);
-uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length);
+uint tablename_to_filename(const char *from, char *to, size_t to_length);
+uint check_n_cut_mysql50_prefix(const char *from, char *to, size_t to_length);
bool check_mysql50_prefix(const char *name);
uint build_table_filename(char *buff, size_t bufflen, const char *db,
const char *table, const char *ext, uint flags);
@@ -191,14 +191,15 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
#define C_ALTER_TABLE_FRM_ONLY -2
#define C_ASSISTED_DISCOVERY -3
-int mysql_create_table_no_lock(THD *thd, const char *db,
- const char *table_name,
+int mysql_create_table_no_lock(THD *thd, const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name,
Table_specification_st *create_info,
Alter_info *alter_info, bool *is_trans,
int create_table_mode, TABLE_LIST *table);
handler *mysql_create_frm_image(THD *thd,
- const char *db, const char *table_name,
+ const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name,
HA_CREATE_INFO *create_info,
Alter_info *alter_info,
int create_table_mode,
@@ -216,7 +217,7 @@ bool mysql_prepare_alter_table(THD *thd, TABLE *table,
Alter_table_ctx *alter_ctx);
bool mysql_trans_prepare_alter_copy_data(THD *thd);
bool mysql_trans_commit_alter_copy_data(THD *thd);
-bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
+bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *new_name,
HA_CREATE_INFO *create_info,
TABLE_LIST *table_list,
Alter_info *alter_info,
@@ -229,9 +230,9 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool table_copy);
bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
TABLE_LIST *src_table,
Table_specification_st *create_info);
-bool mysql_rename_table(handlerton *base, const char *old_db,
- const char * old_name, const char *new_db,
- const char * new_name, uint flags);
+bool mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db,
+ const LEX_CSTRING *old_name, const LEX_CSTRING *new_db,
+ const LEX_CSTRING *new_name, uint flags);
bool mysql_backup_table(THD* thd, TABLE_LIST* table_list);
bool mysql_restore_table(THD* thd, TABLE_LIST* table_list);
@@ -244,11 +245,10 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
bool drop_temporary, bool drop_view,
bool drop_sequence,
bool log_query, bool dont_free_locks);
-bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length,
- const char *table_name, size_t table_name_length,
- bool temporary_table);
-bool quick_rm_table(THD *thd, handlerton *base, const char *db,
- const char *table_name, uint flags,
+bool log_drop_table(THD *thd, const LEX_CSTRING *db_name,
+ const LEX_CSTRING *table_name, bool temporary_table);
+bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name, uint flags,
const char *table_path=0);
void close_cached_table(THD *thd, TABLE *table);
void sp_prepare_create_field(THD *thd, Column_definition *sql_field);
diff --git a/sql/sql_time.cc b/sql/sql_time.cc
index 309ede45ecc..02731914d52 100644
--- a/sql/sql_time.cc
+++ b/sql/sql_time.cc
@@ -37,7 +37,7 @@
Order of elements in 'interval_type_to_name' should correspond to
the order of elements in 'interval_type' enum
- See also interval_type, interval_names
+ See also interval_type, interval_names, append_interval
*/
LEX_CSTRING interval_type_to_name[INTERVAL_LAST] = {
@@ -61,10 +61,84 @@ LEX_CSTRING interval_type_to_name[INTERVAL_LAST] = {
{ STRING_WITH_LEN("HOUR_MICROSECOND")},
{ STRING_WITH_LEN("MINUTE_MICROSECOND")},
{ STRING_WITH_LEN("SECOND_MICROSECOND")}
-};
+};
+
+int append_interval(String *str, interval_type int_type, const INTERVAL &interval)
+{
+ char buf[64];
+ size_t len;
+ switch (int_type) {
+ case INTERVAL_YEAR:
+ len= my_snprintf(buf,sizeof(buf),"%u", interval.year);
+ break;
+ case INTERVAL_QUARTER:
+ case INTERVAL_MONTH:
+ len= my_snprintf(buf,sizeof(buf),"%u", interval.month);
+ int_type=INTERVAL_MONTH;
+ break;
+ case INTERVAL_WEEK:
+ case INTERVAL_DAY:
+ len= my_snprintf(buf,sizeof(buf),"%u", interval.day);
+ int_type=INTERVAL_DAY;
+ break;
+ case INTERVAL_HOUR:
+ len= my_snprintf(buf,sizeof(buf),"%u", interval.hour);
+ break;
+ case INTERVAL_MINUTE:
+ len= my_snprintf(buf,sizeof(buf),"%u", interval.minute);
+ break;
+ case INTERVAL_SECOND:
+ len= my_snprintf(buf,sizeof(buf),"%u", interval.second);
+ break;
+ case INTERVAL_MICROSECOND:
+ len= my_snprintf(buf,sizeof(buf),"%u", interval.second_part);
+ break;
+ case INTERVAL_YEAR_MONTH:
+ len= my_snprintf(buf,sizeof(buf),"%u-%02u", interval.day, interval.month);
+ break;
+ case INTERVAL_DAY_HOUR:
+ len= my_snprintf(buf,sizeof(buf),"%u %u", interval.day, interval.hour);
+ break;
+ case INTERVAL_DAY_MINUTE:
+ len= my_snprintf(buf,sizeof(buf),"%u %u:%02u", interval.day, interval.hour, interval.minute);
+ break;
+ case INTERVAL_DAY_SECOND:
+ len= my_snprintf(buf,sizeof(buf),"%u %u:%02u:%02u", interval.day, interval.hour, interval.minute, interval.second);
+ break;
+ case INTERVAL_HOUR_MINUTE:
+ len= my_snprintf(buf,sizeof(buf),"%u:%02u", interval.hour, interval.minute);
+ break;
+ case INTERVAL_HOUR_SECOND:
+ len= my_snprintf(buf,sizeof(buf),"%u:%02u:%02u", interval.hour, interval.minute, interval.second);
+ break;
+ case INTERVAL_MINUTE_SECOND:
+ len= my_snprintf(buf,sizeof(buf),"%u:%02u", interval.minute, interval.second);
+ break;
+ case INTERVAL_DAY_MICROSECOND:
+ len= my_snprintf(buf,sizeof(buf),"%u %u:%02u:%02u.%06u", interval.day, interval.hour, interval.minute, interval.second, interval.second_part);
+ break;
+ case INTERVAL_HOUR_MICROSECOND:
+ len= my_snprintf(buf,sizeof(buf),"%u:%02u:%02u.%06u", interval.hour, interval.minute, interval.second, interval.second_part);
+ break;
+ case INTERVAL_MINUTE_MICROSECOND:
+ len= my_snprintf(buf,sizeof(buf),"%u:%02u.%06u", interval.minute, interval.second, interval.second_part);
+ break;
+ case INTERVAL_SECOND_MICROSECOND:
+ len= my_snprintf(buf,sizeof(buf),"%u.%06u", interval.second, interval.second_part);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ len= 0;
+ }
+ return str->append(buf, len) || str->append(' ') ||
+ str->append(interval_type_to_name + int_type);
+}
- /* Calc weekday from daynr */
- /* Returns 0 for monday, 1 for tuesday .... */
+
+/*
+ Calc weekday from daynr
+ Returns 0 for monday, 1 for tuesday ...
+*/
int calc_weekday(long daynr,bool sunday_first_day_of_week)
{
@@ -256,8 +330,8 @@ adjust_time_range_with_warn(MYSQL_TIME *ltime, uint dec)
*/
static uint
to_ascii(CHARSET_INFO *cs,
- const char *src, uint src_length,
- char *dst, uint dst_length)
+ const char *src, size_t src_length,
+ char *dst, size_t dst_length)
{
int cnvres;
@@ -280,7 +354,7 @@ to_ascii(CHARSET_INFO *cs,
/* Character set-aware version of str_to_time() */
bool
-str_to_time(CHARSET_INFO *cs, const char *str,uint length,
+str_to_time(CHARSET_INFO *cs, const char *str, size_t length,
MYSQL_TIME *l_time, ulonglong fuzzydate, MYSQL_TIME_STATUS *status)
{
char cnv[32];
@@ -294,7 +368,7 @@ str_to_time(CHARSET_INFO *cs, const char *str,uint length,
/* Character set-aware version of str_to_datetime() */
-bool str_to_datetime(CHARSET_INFO *cs, const char *str, uint length,
+bool str_to_datetime(CHARSET_INFO *cs, const char *str, size_t length,
MYSQL_TIME *l_time, ulonglong flags,
MYSQL_TIME_STATUS *status)
{
@@ -318,7 +392,7 @@ bool str_to_datetime(CHARSET_INFO *cs, const char *str, uint length,
bool
str_to_datetime_with_warn(CHARSET_INFO *cs,
- const char *str, uint length, MYSQL_TIME *l_time,
+ const char *str, size_t length, MYSQL_TIME *l_time,
ulonglong flags)
{
MYSQL_TIME_STATUS status;
@@ -357,19 +431,19 @@ static bool number_to_time_with_warn(bool neg, ulonglong nr, ulong sec_part,
{
int was_cut;
longlong res;
- enum_field_types f_type;
+ enum_mysql_timestamp_type ts_type;
bool have_warnings;
if (fuzzydate & TIME_TIME_ONLY)
{
fuzzydate= TIME_TIME_ONLY; // clear other flags
- f_type= MYSQL_TYPE_TIME;
+ ts_type= MYSQL_TIMESTAMP_TIME;
res= number_to_time(neg, nr, sec_part, ltime, &was_cut);
have_warnings= MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut);
}
else
{
- f_type= MYSQL_TYPE_DATETIME;
+ ts_type= MYSQL_TIMESTAMP_DATETIME;
if (neg)
{
res= -1;
@@ -385,8 +459,7 @@ static bool number_to_time_with_warn(bool neg, ulonglong nr, ulong sec_part,
{
make_truncated_value_warning(current_thd,
Sql_condition::WARN_LEVEL_WARN, str,
- res < 0 ? MYSQL_TIMESTAMP_ERROR
- : mysql_type_to_time_type(f_type),
+ res < 0 ? MYSQL_TIMESTAMP_ERROR : ts_type,
field_name);
}
return res < 0;
@@ -475,6 +548,7 @@ void localtime_to_TIME(MYSQL_TIME *to, struct tm *from)
to->second= (int) from->tm_sec;
}
+
void calc_time_from_sec(MYSQL_TIME *to, long seconds, long microseconds)
{
long t_seconds;
@@ -758,7 +832,7 @@ DATE_TIME_FORMAT
!parse_date_time_format(format_type, format_str,
format_length, &tmp))
{
- tmp.format.str= (char*) format_str;
+ tmp.format.str= format_str;
tmp.format.length= format_length;
return date_time_format_copy((THD *)0, &tmp);
}
@@ -785,7 +859,8 @@ DATE_TIME_FORMAT
DATE_TIME_FORMAT *date_time_format_copy(THD *thd, DATE_TIME_FORMAT *format)
{
DATE_TIME_FORMAT *new_format;
- ulong length= sizeof(*format) + format->format.length + 1;
+ size_t length= sizeof(*format) + format->format.length + 1;
+ char *format_pos;
if (thd)
new_format= (DATE_TIME_FORMAT *) thd->alloc(length);
@@ -794,14 +869,13 @@ DATE_TIME_FORMAT *date_time_format_copy(THD *thd, DATE_TIME_FORMAT *format)
if (new_format)
{
/* Put format string after current pos */
- new_format->format.str= (char*) (new_format+1);
+ new_format->format.str= format_pos= (char*) (new_format+1);
memcpy((char*) new_format->positions, (char*) format->positions,
sizeof(format->positions));
new_format->time_separator= format->time_separator;
/* We make the string null terminated for easy printf in SHOW VARIABLES */
- memcpy((char*) new_format->format.str, format->format.str,
- format->format.length);
- new_format->format.str[format->format.length]= 0;
+ memcpy(format_pos, format->format.str, format->format.length);
+ format_pos[format->format.length]= 0;
new_format->format.length= format->format.length;
}
return new_format;
@@ -902,11 +976,11 @@ void make_truncated_value_warning(THD *thd,
#define GET_PART(X, N) X % N ## LL; X/= N ## LL
bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type,
- INTERVAL interval)
+ const INTERVAL &interval)
{
long period, sign;
- sign= (interval.neg == ltime->neg ? 1 : -1);
+ sign= (interval.neg == (bool)ltime->neg ? 1 : -1);
switch (int_type) {
case INTERVAL_SECOND:
@@ -1392,3 +1466,46 @@ bool datetime_to_time_with_warn(THD *thd, const MYSQL_TIME *dt,
int warnings= 0;
return check_time_range(tm, dec, &warnings);
}
+
+
+longlong pack_time(const MYSQL_TIME *my_time)
+{
+ return ((((((my_time->year * 13ULL +
+ my_time->month) * 32ULL +
+ my_time->day) * 24ULL +
+ my_time->hour) * 60ULL +
+ my_time->minute) * 60ULL +
+ my_time->second) * 1000000ULL +
+ my_time->second_part) * (my_time->neg ? -1 : 1);
+}
+
+#define get_one(WHERE, FACTOR) WHERE= (ulong)(packed % FACTOR); packed/= FACTOR
+
+void unpack_time(longlong packed, MYSQL_TIME *my_time,
+ enum_mysql_timestamp_type ts_type)
+{
+ if ((my_time->neg= packed < 0))
+ packed= -packed;
+ get_one(my_time->second_part, 1000000ULL);
+ get_one(my_time->second, 60U);
+ get_one(my_time->minute, 60U);
+ get_one(my_time->hour, 24U);
+ get_one(my_time->day, 32U);
+ get_one(my_time->month, 13U);
+ my_time->year= (uint)packed;
+ my_time->time_type= ts_type;
+ switch (ts_type) {
+ case MYSQL_TIMESTAMP_TIME:
+ my_time->hour+= (my_time->month * 32 + my_time->day) * 24;
+ my_time->month= my_time->day= 0;
+ break;
+ case MYSQL_TIMESTAMP_DATE:
+ my_time->hour= my_time->minute= my_time->second= my_time->second_part= 0;
+ break;
+ case MYSQL_TIMESTAMP_NONE:
+ case MYSQL_TIMESTAMP_ERROR:
+ DBUG_ASSERT(0);
+ case MYSQL_TIMESTAMP_DATETIME:
+ break;
+ }
+}
diff --git a/sql/sql_time.h b/sql/sql_time.h
index 1832e4501ed..d3607a28a76 100644
--- a/sql/sql_time.h
+++ b/sql/sql_time.h
@@ -38,8 +38,7 @@ bool time_to_datetime(MYSQL_TIME *ltime);
void time_to_daytime_interval(MYSQL_TIME *l_time);
bool get_date_from_daynr(long daynr,uint *year, uint *month, uint *day);
my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, uint *error_code);
-bool str_to_datetime_with_warn(CHARSET_INFO *cs, const char *str,
- uint length, MYSQL_TIME *l_time,
+bool str_to_datetime_with_warn(CHARSET_INFO *cs, const char *str, size_t length, MYSQL_TIME *l_time,
ulonglong flags);
bool double_to_datetime_with_warn(double value, MYSQL_TIME *ltime,
ulonglong fuzzydate,
@@ -122,8 +121,7 @@ void make_truncated_value_warning(THD *thd,
const char *field_name);
static inline void make_truncated_value_warning(THD *thd,
- Sql_condition::enum_warning_level level, const char *str_val,
- uint str_length, timestamp_type time_type,
+ Sql_condition::enum_warning_level level, const char *str_val, size_t str_length, timestamp_type time_type,
const char *field_name)
{
const ErrConvString str(str_val, str_length, &my_charset_bin);
@@ -141,9 +139,11 @@ bool my_TIME_to_str(const MYSQL_TIME *ltime, String *str, uint dec);
/* MYSQL_TIME operations */
bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type,
- INTERVAL interval);
+ const INTERVAL &interval);
bool calc_time_diff(const MYSQL_TIME *l_time1, const MYSQL_TIME *l_time2,
int l_sign, longlong *seconds_out, long *microseconds_out);
+int append_interval(String *str, interval_type int_type,
+ const INTERVAL &interval);
/**
Calculate time difference between two MYSQL_TIME values and
store the result as an out MYSQL_TIME value in MYSQL_TIMESTAMP_TIME format.
@@ -170,6 +170,7 @@ bool calc_time_diff(const MYSQL_TIME *l_time1, const MYSQL_TIME *l_time2,
int lsign, MYSQL_TIME *l_time3, ulonglong fuzzydate);
int my_time_compare(const MYSQL_TIME *a, const MYSQL_TIME *b);
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
+
void calc_time_from_sec(MYSQL_TIME *to, long seconds, long microseconds);
uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year);
@@ -178,12 +179,12 @@ bool parse_date_time_format(timestamp_type format_type,
const char *format, uint format_length,
DATE_TIME_FORMAT *date_time_format);
/* Character set-aware version of str_to_time() */
-bool str_to_time(CHARSET_INFO *cs, const char *str,uint length,
+bool str_to_time(CHARSET_INFO *cs, const char *str,size_t length,
MYSQL_TIME *l_time, ulonglong fuzzydate,
MYSQL_TIME_STATUS *status);
/* Character set-aware version of str_to_datetime() */
bool str_to_datetime(CHARSET_INFO *cs,
- const char *str, uint length,
+ const char *str, size_t length,
MYSQL_TIME *l_time, ulonglong flags,
MYSQL_TIME_STATUS *status);
@@ -232,4 +233,8 @@ bool make_date_with_warn(MYSQL_TIME *ltime,
ulonglong fuzzy_date, timestamp_type ts_type);
bool adjust_time_range_with_warn(MYSQL_TIME *ltime, uint dec);
+longlong pack_time(const MYSQL_TIME *my_time);
+void unpack_time(longlong packed, MYSQL_TIME *my_time,
+ enum_mysql_timestamp_type ts_type);
+
#endif /* SQL_TIME_INCLUDED */
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index d6c722246e7..29bf7aeb205 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -35,7 +35,7 @@
#include <mysys_err.h>
LEX_CSTRING *make_lex_string(LEX_CSTRING *lex_str,
- const char* str, uint length,
+ const char* str, size_t length,
MEM_ROOT *mem_root)
{
if (!(lex_str->str= strmake_root(mem_root, str, length)))
@@ -164,7 +164,7 @@ Trigger_creation_ctx::create(THD *thd,
/*************************************************************************/
static const LEX_CSTRING triggers_file_type=
- { C_STRING_WITH_LEN("TRIGGERS") };
+ { STRING_WITH_LEN("TRIGGERS") };
const char * const TRG_EXT= ".TRG";
@@ -421,7 +421,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
need second part of condition below, since check_access() function also
checks that db is specified.
*/
- if (!thd->lex->spname->m_db.length || (create && !tables->db_length))
+ if (!thd->lex->spname->m_db.length || (create && !tables->db.length))
{
my_error(ER_NO_DB_ERROR, MYF(0));
DBUG_RETURN(TRUE);
@@ -430,7 +430,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
/*
We don't allow creating triggers on tables in the 'mysql' schema
*/
- if (create && !my_strcasecmp(system_charset_info, "mysql", tables->db))
+ if (create && !my_strcasecmp(system_charset_info, "mysql", tables->db.str))
{
my_error(ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA, MYF(0));
DBUG_RETURN(TRUE);
@@ -522,7 +522,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
/* We do not allow creation of triggers on temporary tables. */
if (create && thd->find_tmp_table_share(tables))
{
- my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias);
+ my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias.str);
goto end;
}
@@ -540,8 +540,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
if (thd->locked_tables_mode)
{
/* Under LOCK TABLES we must only accept write locked tables. */
- if (!(tables->table= find_table_for_mdl_upgrade(thd, tables->db,
- tables->table_name,
+ if (!(tables->table= find_table_for_mdl_upgrade(thd, tables->db.str,
+ tables->table_name.str,
FALSE)))
goto end;
}
@@ -654,7 +654,7 @@ static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables,
{
LEX_CSTRING stmt_definition;
LEX *lex= thd->lex;
- uint prefix_trimmed, suffix_trimmed;
+ size_t prefix_trimmed, suffix_trimmed;
size_t original_length;
/*
@@ -682,7 +682,7 @@ static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables,
/* Create statement for binary logging */
- stmt_definition.str= (char*) lex->stmt_definition_begin;
+ stmt_definition.str= lex->stmt_definition_begin;
stmt_definition.length= (lex->stmt_definition_end -
lex->stmt_definition_begin);
original_length= stmt_definition.length;
@@ -693,7 +693,13 @@ static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables,
/* Create statement for storing trigger (without trigger order) */
if (lex->trg_chistics.ordering_clause == TRG_ORDER_NONE)
- trigger_def->append(&stmt_definition);
+ {
+ /*
+ Not that here stmt_definition doesn't end with a \0, which is
+ normally expected from a LEX_CSTRING
+ */
+ trigger_def->append(stmt_definition.str, stmt_definition.length);
+ }
else
{
/* Copy data before FOLLOWS/PRECEDES trigger_name */
@@ -755,8 +761,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
DBUG_RETURN(true);
/* Trigger must be in the same schema as target table. */
- if (lex_string_cmp(table_alias_charset, &table->s->db,
- &lex->spname->m_db))
+ if (lex_string_cmp(table_alias_charset, &table->s->db, &lex->spname->m_db))
{
my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0));
DBUG_RETURN(true);
@@ -814,11 +819,11 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
versions
*/
file.length= build_table_filename(file_buff, FN_REFLEN - 1,
- tables->db, tables->table_name,
+ tables->db.str, tables->table_name.str,
TRG_EXT, 0);
file.str= file_buff;
trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1,
- tables->db,
+ tables->db.str,
lex->spname->m_name.str,
TRN_EXT, 0);
trigname_file.str= trigname_buff;
@@ -839,7 +844,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
}
else if (lex->create_info.if_not_exists())
{
- strxnmov(trigname_buff, sizeof(trigname_buff) - 1, tables->db, ".",
+ strxnmov(trigname_buff, sizeof(trigname_buff) - 1, tables->db.str, ".",
lex->spname->m_name.str, NullS);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_TRG_ALREADY_EXISTS,
@@ -858,15 +863,14 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
}
else
{
- strxnmov(trigname_buff, sizeof(trigname_buff) - 1, tables->db, ".",
+ strxnmov(trigname_buff, sizeof(trigname_buff) - 1, tables->db.str, ".",
lex->spname->m_name.str, NullS);
my_error(ER_TRG_ALREADY_EXISTS, MYF(0), trigname_buff);
DBUG_RETURN(true);
}
}
- trigname.trigger_table.str= tables->table_name;
- trigname.trigger_table.length= tables->table_name_length;
+ trigname.trigger_table= tables->table_name;
/*
We are not using lex->sphead here as an argument to Trigger() as we are
@@ -901,7 +905,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
lex_string_set(&trigger->connection_cl_name,
thd->variables.collation_connection->name);
lex_string_set(&trigger->db_cl_name,
- get_default_db_collation(thd, tables->db)->name);
+ get_default_db_collation(thd, tables->db.str)->name);
/* Add trigger in it's correct place */
add_trigger(lex->trg_chistics.event,
@@ -1009,10 +1013,10 @@ bool Trigger::add_to_file_list(void* param_arg)
True error
*/
-static bool rm_trigger_file(char *path, const char *db,
- const char *table_name)
+static bool rm_trigger_file(char *path, const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name)
{
- build_table_filename(path, FN_REFLEN-1, db, table_name, TRG_EXT, 0);
+ build_table_filename(path, FN_REFLEN-1, db->str, table_name->str, TRG_EXT, 0);
return mysql_file_delete(key_file_trg, path, MYF(MY_WME));
}
@@ -1031,10 +1035,10 @@ static bool rm_trigger_file(char *path, const char *db,
True error
*/
-static bool rm_trigname_file(char *path, const char *db,
- const char *trigger_name)
+static bool rm_trigname_file(char *path, const LEX_CSTRING *db,
+ const LEX_CSTRING *trigger_name)
{
- build_table_filename(path, FN_REFLEN - 1, db, trigger_name, TRN_EXT, 0);
+ build_table_filename(path, FN_REFLEN - 1, db->str, trigger_name->str, TRN_EXT, 0);
return mysql_file_delete(key_file_trn, path, MYF(MY_WME));
}
@@ -1052,8 +1056,8 @@ static bool rm_trigname_file(char *path, const char *db,
TRUE Error
*/
-bool Table_triggers_list::save_trigger_file(THD *thd, const char *db,
- const char *table_name)
+bool Table_triggers_list::save_trigger_file(THD *thd, const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name)
{
char file_buff[FN_REFLEN];
LEX_CSTRING file;
@@ -1061,7 +1065,7 @@ bool Table_triggers_list::save_trigger_file(THD *thd, const char *db,
if (create_lists_needed_for_files(thd->mem_root))
return true;
- file.length= build_table_filename(file_buff, FN_REFLEN - 1, db, table_name,
+ file.length= build_table_filename(file_buff, FN_REFLEN - 1, db->str, table_name->str,
TRG_EXT, 0);
file.str= file_buff;
return sql_create_definition_file(NULL, &file, &triggers_file_type,
@@ -1153,16 +1157,16 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
parse_file.cc functionality (because we will need it
elsewhere).
*/
- if (rm_trigger_file(path, tables->db, tables->table_name))
+ if (rm_trigger_file(path, &tables->db, &tables->table_name))
return 1;
}
else
{
- if (save_trigger_file(thd, tables->db, tables->table_name))
+ if (save_trigger_file(thd, &tables->db, &tables->table_name))
return 1;
}
- if (rm_trigname_file(path, tables->db, sp_name->str))
+ if (rm_trigname_file(path, &tables->db, sp_name))
return 1;
delete trigger;
@@ -1228,7 +1232,7 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table)
uchar null_bit= 1;
for (fld= table->field, trg_fld= record0_field; *fld; fld++, trg_fld++)
{
- if (!(*fld)->null_ptr && !(*fld)->vcol_info)
+ if (!(*fld)->null_ptr && !(*fld)->vcol_info && !(*fld)->vers_sys_field())
{
Field *f;
if (!(f= *trg_fld= (*fld)->make_new_field(&table->mem_root, table,
@@ -1251,7 +1255,9 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table)
bzero(extra_null_bitmap, null_bytes);
}
else
+ {
record0_field= table->field;
+ }
if (has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_BEFORE) ||
has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_AFTER) ||
@@ -1299,18 +1305,18 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table)
True error
*/
-bool Table_triggers_list::check_n_load(THD *thd, const char *db,
- const char *table_name, TABLE *table,
+bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name, TABLE *table,
bool names_only)
{
char path_buff[FN_REFLEN];
LEX_CSTRING path;
File_parser *parser;
- LEX_STRING save_db;
+ LEX_CSTRING save_db;
DBUG_ENTER("Table_triggers_list::check_n_load");
path.length= build_table_filename(path_buff, FN_REFLEN - 1,
- db, table_name, TRG_EXT, 0);
+ db->str, table_name->str, TRG_EXT, 0);
path.str= path_buff;
// QQ: should we analyze errno somehow ?
@@ -1349,8 +1355,8 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_TRG_NO_CREATION_CTX,
ER_THD(thd, ER_TRG_NO_CREATION_CTX),
- (const char*) db,
- (const char*) table_name);
+ db->str,
+ table_name->str);
}
table->triggers= trigger_list;
@@ -1362,15 +1368,15 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
List_iterator_fast<LEX_CSTRING> it_connection_cl_name(trigger_list->connection_cl_names);
List_iterator_fast<LEX_CSTRING> it_db_cl_name(trigger_list->db_cl_names);
List_iterator_fast<ulonglong> it_create_times(trigger_list->create_times);
- LEX *old_lex= thd->lex, lex;
+ LEX *old_lex= thd->lex, *old_stmt_lex= thd->stmt_lex;
+ LEX lex;
sp_rcontext *save_spcont= thd->spcont;
sql_mode_t save_sql_mode= thd->variables.sql_mode;
- thd->lex= &lex;
+ thd->lex= thd->stmt_lex= &lex;
- save_db.str= thd->db;
- save_db.length= thd->db_length;
- thd->reset_db((char*) db, strlen(db));
+ save_db= thd->db;
+ thd->reset_db(db);
while ((trg_create_str= it++))
{
sp_head *sp;
@@ -1398,8 +1404,8 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
if (!trigger_list->client_cs_names.is_empty())
creation_ctx= Trigger_creation_ctx::create(thd,
- db,
- table_name,
+ db->str,
+ table_name->str,
it_client_cs_name++,
it_connection_cl_name++,
it_db_cl_name++);
@@ -1508,8 +1514,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_TRG_NO_DEFINER,
ER_THD(thd, ER_TRG_NO_DEFINER),
- (const char*) db,
- (const char*) sp->m_name.str);
+ db->str, sp->m_name.str);
/*
Set definer to the '' to correct displaying in the information
@@ -1545,12 +1550,12 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
*/
char fname[SAFE_NAME_LEN + 1];
- DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) ||
- (check_n_cut_mysql50_prefix(db, fname, sizeof(fname)) &&
- !my_strcasecmp(table_alias_charset, lex.query_tables->db, fname))));
- DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->table_name, table_name) ||
- (check_n_cut_mysql50_prefix(table_name, fname, sizeof(fname)) &&
- !my_strcasecmp(table_alias_charset, lex.query_tables->table_name, fname))));
+ DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->db.str, db->str) ||
+ (check_n_cut_mysql50_prefix(db->str, fname, sizeof(fname)) &&
+ !my_strcasecmp(table_alias_charset, lex.query_tables->db.str, fname))));
+ DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->table_name.str, table_name->str) ||
+ (check_n_cut_mysql50_prefix(table_name->str, fname, sizeof(fname)) &&
+ !my_strcasecmp(table_alias_charset, lex.query_tables->table_name.str, fname))));
#endif
if (names_only)
{
@@ -1583,8 +1588,9 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
lex_end(&lex);
}
- thd->reset_db(save_db.str, save_db.length);
+ thd->reset_db(&save_db);
thd->lex= old_lex;
+ thd->stmt_lex= old_stmt_lex;
thd->spcont= save_spcont;
thd->variables.sql_mode= save_sql_mode;
@@ -1598,9 +1604,10 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
err_with_lex_cleanup:
lex_end(&lex);
thd->lex= old_lex;
+ thd->stmt_lex= old_stmt_lex;
thd->spcont= save_spcont;
thd->variables.sql_mode= save_sql_mode;
- thd->reset_db(save_db.str, save_db.length);
+ thd->reset_db(&save_db);
/* Fall trough to error */
}
}
@@ -1613,7 +1620,7 @@ error:
be merged into .FRM anyway.
*/
my_error(ER_WRONG_OBJECT, MYF(0),
- table_name, TRG_EXT + 1, "TRIGGER");
+ table_name->str, TRG_EXT + 1, "TRIGGER");
}
DBUG_RETURN(1);
}
@@ -1668,8 +1675,8 @@ void Table_triggers_list::add_trigger(trg_event_type event,
/**
Obtains and returns trigger metadata.
- @param thd current thread context
@param trigger_stmt returns statement of trigger
+ @param body returns body of trigger
@param definer returns definer/creator of trigger. The caller is
responsible to allocate enough space for storing
definer information.
@@ -1733,12 +1740,12 @@ bool add_table_for_trigger(THD *thd,
{
LEX *lex= thd->lex;
char trn_path_buff[FN_REFLEN];
- LEX_STRING trn_path= { trn_path_buff, 0 };
+ LEX_CSTRING trn_path= { trn_path_buff, 0 };
LEX_CSTRING tbl_name= null_clex_str;
DBUG_ENTER("add_table_for_trigger");
- build_trn_path(thd, trg_name, &trn_path);
+ build_trn_path(thd, trg_name, (LEX_STRING*) &trn_path);
if (check_trn_exists(&trn_path))
{
@@ -1758,12 +1765,11 @@ bool add_table_for_trigger(THD *thd,
DBUG_RETURN(TRUE);
}
- if (load_table_name_for_trigger(thd, trg_name, (LEX_CSTRING*) &trn_path,
- &tbl_name))
+ if (load_table_name_for_trigger(thd, trg_name, &trn_path, &tbl_name))
DBUG_RETURN(TRUE);
- *table= sp_add_to_query_tables(thd, lex, trg_name->m_db.str,
- tbl_name.str, TL_IGNORE,
+ *table= sp_add_to_query_tables(thd, lex, &trg_name->m_db,
+ &tbl_name, TL_IGNORE,
MDL_SHARED_NO_WRITE);
DBUG_RETURN(*table ? FALSE : TRUE);
@@ -1783,16 +1789,17 @@ bool add_table_for_trigger(THD *thd,
True error
*/
-bool Table_triggers_list::drop_all_triggers(THD *thd, const char *db,
- const char *name)
+bool Table_triggers_list::drop_all_triggers(THD *thd, const LEX_CSTRING *db,
+ const LEX_CSTRING *name)
{
TABLE table;
char path[FN_REFLEN];
bool result= 0;
- DBUG_ENTER("drop_all_triggers");
+ DBUG_ENTER("Triggers::drop_all_triggers");
bzero(&table, sizeof(table));
- init_sql_alloc(&table.mem_root, 8192, 0, MYF(0));
+ init_sql_alloc(&table.mem_root, "Triggers::drop_all_triggers", 8192, 0,
+ MYF(0));
if (Table_triggers_list::check_n_load(thd, db, name, &table, 1))
{
@@ -1816,7 +1823,7 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, const char *db,
Such triggers have zero-length name and are skipped here.
*/
if (trigger->name.length &&
- rm_trigname_file(path, db, trigger->name.str))
+ rm_trigname_file(path, db, &trigger->name))
{
/*
Instead of immediately bailing out with error if we were unable
@@ -1856,26 +1863,27 @@ end:
struct change_table_name_param
{
THD *thd;
- const char *old_db_name;
- const char *new_db_name;
+ LEX_CSTRING *old_db_name;
+ LEX_CSTRING *new_db_name;
LEX_CSTRING *new_table_name;
Trigger *stopper;
};
bool
-Table_triggers_list::change_table_name_in_triggers(THD *thd,
- const char *old_db_name,
- const char *new_db_name,
- LEX_CSTRING *old_table_name,
- LEX_CSTRING *new_table_name)
+Table_triggers_list::
+change_table_name_in_triggers(THD *thd,
+ const LEX_CSTRING *old_db_name,
+ const LEX_CSTRING *new_db_name,
+ const LEX_CSTRING *old_table_name,
+ const LEX_CSTRING *new_table_name)
{
struct change_table_name_param param;
sql_mode_t save_sql_mode= thd->variables.sql_mode;
char path_buff[FN_REFLEN];
param.thd= thd;
- param.new_table_name= new_table_name;
+ param.new_table_name= const_cast<LEX_CSTRING*>(new_table_name);
for_all_triggers(&Trigger::change_table_name, &param);
@@ -1884,12 +1892,12 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd,
if (thd->is_fatal_error)
return TRUE; /* OOM */
- if (save_trigger_file(thd, new_db_name, new_table_name->str))
+ if (save_trigger_file(thd, new_db_name, new_table_name))
return TRUE;
- if (rm_trigger_file(path_buff, old_db_name, old_table_name->str))
+ if (rm_trigger_file(path_buff, old_db_name, old_table_name))
{
- (void) rm_trigger_file(path_buff, new_db_name, new_table_name->str);
+ (void) rm_trigger_file(path_buff, new_db_name, new_table_name);
return TRUE;
}
return FALSE;
@@ -1917,7 +1925,7 @@ bool Trigger::change_table_name(void* param_arg)
buff.append(def->str, before_on_len);
buff.append(STRING_WITH_LEN("ON "));
- append_identifier(thd, &buff, new_table_name->str, new_table_name->length);
+ append_identifier(thd, &buff, new_table_name);
buff.append(STRING_WITH_LEN(" "));
on_q_table_name_len= buff.length() - before_on_len;
buff.append(on_table_name.str + on_table_name.length,
@@ -1954,15 +1962,16 @@ bool Trigger::change_table_name(void* param_arg)
*/
Trigger *
-Table_triggers_list::change_table_name_in_trignames(const char *old_db_name,
- const char *new_db_name,
- LEX_CSTRING *new_table_name,
- Trigger *trigger)
+Table_triggers_list::
+change_table_name_in_trignames(const LEX_CSTRING *old_db_name,
+ const LEX_CSTRING *new_db_name,
+ const LEX_CSTRING *new_table_name,
+ Trigger *trigger)
{
struct change_table_name_param param;
- param.old_db_name= old_db_name;
- param.new_db_name= new_db_name;
- param.new_table_name= new_table_name;
+ param.old_db_name= const_cast<LEX_CSTRING*>(old_db_name);
+ param.new_db_name= const_cast<LEX_CSTRING*>(new_db_name);
+ param.new_table_name= const_cast<LEX_CSTRING*>(new_table_name);
param.stopper= trigger;
return for_all_triggers(&Trigger::change_on_table_name, &param);
@@ -1981,7 +1990,7 @@ bool Trigger::change_on_table_name(void* param_arg)
return 0; // Stop processing
trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1,
- param->new_db_name, name.str,
+ param->new_db_name->str, name.str,
TRN_EXT, 0);
trigname_file.str= trigname_buff;
@@ -1997,9 +2006,9 @@ bool Trigger::change_on_table_name(void* param_arg)
/* Remove stale .TRN file in case of database upgrade */
if (param->old_db_name)
{
- if (rm_trigname_file(trigname_buff, param->old_db_name, name.str))
+ if (rm_trigname_file(trigname_buff, param->old_db_name, &name))
{
- (void) rm_trigname_file(trigname_buff, param->new_db_name, name.str);
+ (void) rm_trigname_file(trigname_buff, param->new_db_name, &name);
return 1;
}
}
@@ -2028,30 +2037,32 @@ bool Trigger::change_on_table_name(void* param_arg)
@retval TRUE Error
*/
-bool Table_triggers_list::change_table_name(THD *thd, const char *db,
- const char *old_alias,
- const char *old_table,
- const char *new_db,
- const char *new_table)
+bool Table_triggers_list::change_table_name(THD *thd, const LEX_CSTRING *db,
+ const LEX_CSTRING *old_alias,
+ const LEX_CSTRING *old_table,
+ const LEX_CSTRING *new_db,
+ const LEX_CSTRING *new_table)
{
TABLE table;
bool result= 0;
bool upgrading50to51= FALSE;
Trigger *err_trigger;
- DBUG_ENTER("change_table_name");
+ DBUG_ENTER("Triggers::change_table_name");
bzero(&table, sizeof(table));
- init_sql_alloc(&table.mem_root, 8192, 0, MYF(0));
+ init_sql_alloc(&table.mem_root, "Triggers::change_table_name", 8192, 0,
+ MYF(0));
/*
This method interfaces the mysql server code protected by
an exclusive metadata lock.
*/
- DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, old_table,
+ DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db->str,
+ old_table->str,
MDL_EXCLUSIVE));
- DBUG_ASSERT(my_strcasecmp(table_alias_charset, db, new_db) ||
- my_strcasecmp(table_alias_charset, old_alias, new_table));
+ DBUG_ASSERT(my_strcasecmp(table_alias_charset, db->str, new_db->str) ||
+ my_strcasecmp(table_alias_charset, old_alias->str, new_table->str));
if (Table_triggers_list::check_n_load(thd, db, old_table, &table, TRUE))
{
@@ -2065,8 +2076,6 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
result= 1;
goto end;
}
- LEX_CSTRING old_table_name= { (char *) old_alias, strlen(old_alias) };
- LEX_CSTRING new_table_name= { (char *) new_table, strlen(new_table) };
/*
Since triggers should be in the same schema as their subject tables
moving table with them between two schemas raises too many questions.
@@ -2077,11 +2086,11 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
we will be given table name with "#mysql50#" prefix
To remove this prefix we use check_n_cut_mysql50_prefix().
*/
- if (my_strcasecmp(table_alias_charset, db, new_db))
+ if (my_strcasecmp(table_alias_charset, db->str, new_db->str))
{
char dbname[SAFE_NAME_LEN + 1];
- if (check_n_cut_mysql50_prefix(db, dbname, sizeof(dbname)) &&
- !my_strcasecmp(table_alias_charset, dbname, new_db))
+ if (check_n_cut_mysql50_prefix(db->str, dbname, sizeof(dbname)) &&
+ !my_strcasecmp(table_alias_charset, dbname, new_db->str))
{
upgrading50to51= TRUE;
}
@@ -2093,15 +2102,15 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
}
}
if (table.triggers->change_table_name_in_triggers(thd, db, new_db,
- &old_table_name,
- &new_table_name))
+ old_alias,
+ new_table))
{
result= 1;
goto end;
}
if ((err_trigger= table.triggers->
change_table_name_in_trignames( upgrading50to51 ? db : NULL,
- new_db, &new_table_name, 0)))
+ new_db, new_table, 0)))
{
/*
If we were unable to update one of .TRN files properly we will
@@ -2111,10 +2120,10 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
*/
(void) table.triggers->change_table_name_in_trignames(
upgrading50to51 ? new_db : NULL, db,
- &old_table_name, err_trigger);
+ old_alias, err_trigger);
(void) table.triggers->change_table_name_in_triggers(
thd, db, new_db,
- &new_table_name, &old_table_name);
+ new_table, old_alias);
result= 1;
goto end;
}
@@ -2456,7 +2465,7 @@ void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path)
@retval FALSE if TRN-file exists.
*/
-bool check_trn_exists(const LEX_STRING *trn_path)
+bool check_trn_exists(const LEX_CSTRING *trn_path)
{
return access(trn_path->str, F_OK) != 0;
}
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index 8847680c7b2..0fddb94fde1 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -223,17 +223,17 @@ public:
bool old_row_is_record1);
void empty_lists();
bool create_lists_needed_for_files(MEM_ROOT *root);
- bool save_trigger_file(THD *thd, const char *db, const char *table_name);
+ bool save_trigger_file(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name);
- static bool check_n_load(THD *thd, const char *db, const char *table_name,
+ static bool check_n_load(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name,
TABLE *table, bool names_only);
- static bool drop_all_triggers(THD *thd, const char *db,
- const char *table_name);
- static bool change_table_name(THD *thd, const char *db,
- const char *old_alias,
- const char *old_table,
- const char *new_db,
- const char *new_table);
+ static bool drop_all_triggers(THD *thd, const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name);
+ static bool change_table_name(THD *thd, const LEX_CSTRING *db,
+ const LEX_CSTRING *old_alias,
+ const LEX_CSTRING *old_table,
+ const LEX_CSTRING *new_db,
+ const LEX_CSTRING *new_table);
void add_trigger(trg_event_type event_type,
trg_action_time_type action_time,
trigger_order_type ordering_clause,
@@ -286,15 +286,15 @@ public:
private:
bool prepare_record_accessors(TABLE *table);
- Trigger *change_table_name_in_trignames(const char *old_db_name,
- const char *new_db_name,
- LEX_CSTRING *new_table_name,
+ Trigger *change_table_name_in_trignames(const LEX_CSTRING *old_db_name,
+ const LEX_CSTRING *new_db_name,
+ const LEX_CSTRING *new_table_name,
Trigger *trigger);
bool change_table_name_in_triggers(THD *thd,
- const char *old_db_name,
- const char *new_db_name,
- LEX_CSTRING *old_table_name,
- LEX_CSTRING *new_table_name);
+ const LEX_CSTRING *old_db_name,
+ const LEX_CSTRING *new_db_name,
+ const LEX_CSTRING *old_table_name,
+ const LEX_CSTRING *new_table_name);
bool check_for_broken_triggers()
{
@@ -307,13 +307,6 @@ private:
}
};
-inline Field **TABLE::field_to_fill()
-{
- return triggers && triggers->nullable_fields() ? triggers->nullable_fields()
- : field;
-}
-
-
bool add_table_for_trigger(THD *thd,
const sp_name *trg_name,
bool continue_if_not_exist,
@@ -321,7 +314,7 @@ bool add_table_for_trigger(THD *thd,
void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path);
-bool check_trn_exists(const LEX_STRING *trn_path);
+bool check_trn_exists(const LEX_CSTRING *trn_path);
bool load_table_name_for_trigger(THD *thd,
const sp_name *trg_name,
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index 1d6edbc5fc9..2ddb4bc042c 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -27,7 +27,8 @@
#include "sql_truncate.h"
#include "wsrep_mysqld.h"
#include "sql_show.h" //append_identifier()
-
+#include "sql_select.h"
+#include "sql_delete.h"
/**
Append a list of field names to a string.
@@ -47,7 +48,7 @@ static bool fk_info_append_fields(THD *thd, String *str,
while ((field= it++))
{
- res|= append_identifier(thd, str, field->str, field->length);
+ res|= append_identifier(thd, str, field);
res|= str->append(", ");
}
@@ -79,22 +80,17 @@ static const char *fk_info_str(THD *thd, FOREIGN_KEY_INFO *fk_info)
`db`.`tbl`, CONSTRAINT `id` FOREIGN KEY (`fk`) REFERENCES `db`.`tbl` (`fk`)
*/
- res|= append_identifier(thd, &str, fk_info->foreign_db->str,
- fk_info->foreign_db->length);
+ res|= append_identifier(thd, &str, fk_info->foreign_db);
res|= str.append(".");
- res|= append_identifier(thd, &str, fk_info->foreign_table->str,
- fk_info->foreign_table->length);
+ res|= append_identifier(thd, &str, fk_info->foreign_table);
res|= str.append(", CONSTRAINT ");
- res|= append_identifier(thd, &str, fk_info->foreign_id->str,
- fk_info->foreign_id->length);
+ res|= append_identifier(thd, &str, fk_info->foreign_id);
res|= str.append(" FOREIGN KEY (");
res|= fk_info_append_fields(thd, &str, &fk_info->foreign_fields);
res|= str.append(") REFERENCES ");
- res|= append_identifier(thd, &str, fk_info->referenced_db->str,
- fk_info->referenced_db->length);
+ res|= append_identifier(thd, &str, fk_info->referenced_db);
res|= str.append(".");
- res|= append_identifier(thd, &str, fk_info->referenced_table->str,
- fk_info->referenced_table->length);
+ res|= append_identifier(thd, &str, fk_info->referenced_table);
res|= str.append(" (");
res|= fk_info_append_fields(thd, &str, &fk_info->referenced_fields);
res|= str.append(')');
@@ -302,8 +298,8 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref,
*/
if (thd->locked_tables_mode)
{
- if (!(table= find_table_for_mdl_upgrade(thd, table_ref->db,
- table_ref->table_name, FALSE)))
+ if (!(table= find_table_for_mdl_upgrade(thd, table_ref->db.str,
+ table_ref->table_name.str, FALSE)))
DBUG_RETURN(TRUE);
*hton_can_recreate= ha_check_storage_engine_flag(table->s->db_type(),
@@ -321,11 +317,12 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref,
thd->variables.lock_wait_timeout, 0))
DBUG_RETURN(TRUE);
- if (!ha_table_exists(thd, table_ref->db, table_ref->table_name,
+ if (!ha_table_exists(thd, &table_ref->db, &table_ref->table_name,
&hton, &is_sequence) ||
hton == view_pseudo_hton)
{
- my_error(ER_NO_SUCH_TABLE, MYF(0), table_ref->db, table_ref->table_name);
+ my_error(ER_NO_SUCH_TABLE, MYF(0), table_ref->db.str,
+ table_ref->table_name.str);
DBUG_RETURN(TRUE);
}
@@ -363,8 +360,8 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref,
else
{
/* Table is already locked exclusively. Remove cached instances. */
- tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_ref->db,
- table_ref->table_name, FALSE);
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_ref->db.str,
+ table_ref->table_name.str, FALSE);
}
DBUG_RETURN(FALSE);
@@ -417,7 +414,7 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
bool hton_can_recreate;
if (WSREP(thd) &&
- wsrep_to_isolation_begin(thd, table_ref->db, table_ref->table_name, 0))
+ wsrep_to_isolation_begin(thd, table_ref->db.str, table_ref->table_name.str, 0))
DBUG_RETURN(TRUE);
if (lock_table(thd, table_ref, &hton_can_recreate))
DBUG_RETURN(TRUE);
@@ -428,7 +425,7 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
The storage engine can truncate the table by creating an
empty table with the same structure.
*/
- error= dd_recreate_table(thd, table_ref->db, table_ref->table_name);
+ error= dd_recreate_table(thd, table_ref->db.str, table_ref->table_name.str);
if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd))
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
@@ -481,7 +478,6 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
DBUG_RETURN(error);
}
-
/**
Execute a TRUNCATE statement at runtime.
@@ -493,13 +489,13 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
bool Sql_cmd_truncate_table::execute(THD *thd)
{
bool res= TRUE;
- TABLE_LIST *first_table= thd->lex->select_lex.table_list.first;
+ TABLE_LIST *table= thd->lex->select_lex.table_list.first;
DBUG_ENTER("Sql_cmd_truncate_table::execute");
- if (check_one_table_access(thd, DROP_ACL, first_table))
+ if (check_one_table_access(thd, DROP_ACL, table))
DBUG_RETURN(res);
- if (! (res= truncate_table(thd, first_table)))
+ if (! (res= truncate_table(thd, table)))
my_ok(thd);
DBUG_RETURN(res);
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc
index 79e894f5a7f..7004c32e602 100644
--- a/sql/sql_tvc.cc
+++ b/sql/sql_tvc.cc
@@ -241,7 +241,7 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl,
/* Error's in 'new' will be detected after loop */
Item_type_holder *new_holder= new (thd->mem_root)
Item_type_holder(thd,
- &item->name,
+ item,
holders[pos].type_handler(),
&holders[pos]/*Type_all_attributes*/,
holders[pos].get_maybe_null());
@@ -291,8 +291,8 @@ int table_value_constr::save_explain_data_intern(THD *thd,
explain->select_id= select_lex->select_number;
explain->select_type= select_lex->type;
explain->linkage= select_lex->linkage;
- explain->using_temporary= NULL;
- explain->using_filesort= NULL;
+ explain->using_temporary= false;
+ explain->using_filesort= false;
/* Setting explain->message means that all other members are invalid */
explain->message= message;
@@ -479,7 +479,7 @@ bool Item_func_in::create_value_list_for_tvc(THD *thd,
return true;
}
}
- else if (tvc_value->push_back(args[i]))
+ else if (tvc_value->push_back(args[i]->real_item()))
return true;
if (values->push_back(tvc_value, thd->mem_root))
diff --git a/sql/sql_tvc.h b/sql/sql_tvc.h
index 7861f6fd16b..420311cccb2 100644
--- a/sql/sql_tvc.h
+++ b/sql/sql_tvc.h
@@ -16,14 +16,14 @@
#ifndef SQL_TVC_INCLUDED
#define SQL_TVC_INCLUDED
#include "sql_type.h"
-#include "item.h"
typedef List<Item> List_item;
class select_result;
-
class Explain_select;
class Explain_query;
class Item_func_in;
+class st_select_lex_unit;
+typedef class st_select_lex SELECT_LEX;
/**
@class table_value_constr
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 62dcff33f1d..09daca0806e 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -32,6 +32,7 @@ Type_handler_long type_handler_long;
Type_handler_int24 type_handler_int24;
Type_handler_longlong type_handler_longlong;
Type_handler_longlong type_handler_ulonglong; // Only used for CAST() for now
+Type_handler_vers_trx_id type_handler_vers_trx_id;
Type_handler_float type_handler_float;
Type_handler_double type_handler_double;
Type_handler_bit type_handler_bit;
@@ -124,6 +125,41 @@ bool Type_handler_data::init()
Type_handler_data *type_handler_data= NULL;
+void Time::make_from_item(Item *item, const Options opt)
+{
+ if (item->get_date(this, opt.get_date_flags()))
+ time_type= MYSQL_TIMESTAMP_NONE;
+ else
+ valid_MYSQL_TIME_to_valid_value(opt);
+}
+
+
+void Temporal_with_date::make_from_item(THD *thd, Item *item, sql_mode_t flags)
+{
+ flags&= ~TIME_TIME_ONLY;
+ /*
+ Some TIME type items return error when trying to do get_date()
+ without TIME_TIME_ONLY set (e.g. Item_field for Field_time).
+ In the SQL standard time->datetime conversion mode we add TIME_TIME_ONLY.
+ In the legacy time->datetime conversion mode we do not add TIME_TIME_ONLY
+ and leave it to get_date() to check date.
+ */
+ ulonglong time_flag= (item->field_type() == MYSQL_TYPE_TIME &&
+ !(thd->variables.old_behavior & OLD_MODE_ZERO_DATE_TIME_CAST)) ?
+ TIME_TIME_ONLY : 0;
+ if (item->get_date(this, flags | time_flag))
+ time_type= MYSQL_TIMESTAMP_NONE;
+ else if (time_type == MYSQL_TIMESTAMP_TIME)
+ {
+ MYSQL_TIME tmp;
+ if (time_to_datetime_with_warn(thd, this, &tmp, flags))
+ time_type= MYSQL_TIMESTAMP_NONE;
+ else
+ *(static_cast<MYSQL_TIME*>(this))= tmp;
+ }
+}
+
+
void Type_std_attributes::set(const Field *field)
{
decimals= field->decimals();
@@ -398,45 +434,45 @@ uint Type_handler_time::m_hires_bytes[MAX_DATETIME_PRECISION + 1]=
{ 3, 4, 4, 5, 5, 5, 6 };
/***************************************************************************/
-const Name Type_handler_row::m_name_row(C_STRING_WITH_LEN("row"));
+const Name Type_handler_row::m_name_row(STRING_WITH_LEN("row"));
-const Name Type_handler_null::m_name_null(C_STRING_WITH_LEN("null"));
+const Name Type_handler_null::m_name_null(STRING_WITH_LEN("null"));
const Name
- Type_handler_string::m_name_char(C_STRING_WITH_LEN("char")),
- Type_handler_var_string::m_name_var_string(C_STRING_WITH_LEN("varchar")),
- Type_handler_varchar::m_name_varchar(C_STRING_WITH_LEN("varchar")),
- Type_handler_tiny_blob::m_name_tinyblob(C_STRING_WITH_LEN("tinyblob")),
- Type_handler_medium_blob::m_name_mediumblob(C_STRING_WITH_LEN("mediumblob")),
- Type_handler_long_blob::m_name_longblob(C_STRING_WITH_LEN("longblob")),
- Type_handler_blob::m_name_blob(C_STRING_WITH_LEN("blob"));
+ Type_handler_string::m_name_char(STRING_WITH_LEN("char")),
+ Type_handler_var_string::m_name_var_string(STRING_WITH_LEN("varchar")),
+ Type_handler_varchar::m_name_varchar(STRING_WITH_LEN("varchar")),
+ Type_handler_tiny_blob::m_name_tinyblob(STRING_WITH_LEN("tinyblob")),
+ Type_handler_medium_blob::m_name_mediumblob(STRING_WITH_LEN("mediumblob")),
+ Type_handler_long_blob::m_name_longblob(STRING_WITH_LEN("longblob")),
+ Type_handler_blob::m_name_blob(STRING_WITH_LEN("blob"));
const Name
- Type_handler_enum::m_name_enum(C_STRING_WITH_LEN("enum")),
- Type_handler_set::m_name_set(C_STRING_WITH_LEN("set"));
+ Type_handler_enum::m_name_enum(STRING_WITH_LEN("enum")),
+ Type_handler_set::m_name_set(STRING_WITH_LEN("set"));
const Name
- Type_handler_tiny::m_name_tiny(C_STRING_WITH_LEN("tinyint")),
- Type_handler_short::m_name_short(C_STRING_WITH_LEN("smallint")),
- Type_handler_long::m_name_int(C_STRING_WITH_LEN("int")),
- Type_handler_longlong::m_name_longlong(C_STRING_WITH_LEN("bigint")),
- Type_handler_int24::m_name_mediumint(C_STRING_WITH_LEN("mediumint")),
- Type_handler_year::m_name_year(C_STRING_WITH_LEN("year")),
- Type_handler_bit::m_name_bit(C_STRING_WITH_LEN("bit"));
+ Type_handler_tiny::m_name_tiny(STRING_WITH_LEN("tinyint")),
+ Type_handler_short::m_name_short(STRING_WITH_LEN("smallint")),
+ Type_handler_long::m_name_int(STRING_WITH_LEN("int")),
+ Type_handler_longlong::m_name_longlong(STRING_WITH_LEN("bigint")),
+ Type_handler_int24::m_name_mediumint(STRING_WITH_LEN("mediumint")),
+ Type_handler_year::m_name_year(STRING_WITH_LEN("year")),
+ Type_handler_bit::m_name_bit(STRING_WITH_LEN("bit"));
const Name
- Type_handler_float::m_name_float(C_STRING_WITH_LEN("float")),
- Type_handler_double::m_name_double(C_STRING_WITH_LEN("double"));
+ Type_handler_float::m_name_float(STRING_WITH_LEN("float")),
+ Type_handler_double::m_name_double(STRING_WITH_LEN("double"));
const Name
- Type_handler_olddecimal::m_name_decimal(C_STRING_WITH_LEN("decimal")),
- Type_handler_newdecimal::m_name_decimal(C_STRING_WITH_LEN("decimal"));
+ Type_handler_olddecimal::m_name_decimal(STRING_WITH_LEN("decimal")),
+ Type_handler_newdecimal::m_name_decimal(STRING_WITH_LEN("decimal"));
const Name
- Type_handler_time_common::m_name_time(C_STRING_WITH_LEN("time")),
- Type_handler_date_common::m_name_date(C_STRING_WITH_LEN("date")),
- Type_handler_datetime_common::m_name_datetime(C_STRING_WITH_LEN("datetime")),
- Type_handler_timestamp_common::m_name_timestamp(C_STRING_WITH_LEN("timestamp"));
+ Type_handler_time_common::m_name_time(STRING_WITH_LEN("time")),
+ Type_handler_date_common::m_name_date(STRING_WITH_LEN("date")),
+ Type_handler_datetime_common::m_name_datetime(STRING_WITH_LEN("datetime")),
+ Type_handler_timestamp_common::m_name_timestamp(STRING_WITH_LEN("timestamp"));
/***************************************************************************/
@@ -658,7 +694,9 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler *h)
Item_result a= cmp_type();
Item_result b= h->cmp_type();
- if (a == STRING_RESULT && b == STRING_RESULT)
+ if (m_vers_trx_id && (a == STRING_RESULT || b == STRING_RESULT))
+ m_type_handler= &type_handler_datetime;
+ else if (a == STRING_RESULT && b == STRING_RESULT)
m_type_handler= &type_handler_long_blob;
else if (a == INT_RESULT && b == INT_RESULT)
m_type_handler= &type_handler_longlong;
@@ -1385,7 +1423,7 @@ Field *Type_handler_long_blob::make_conversion_table_field(TABLE *table,
#ifdef HAVE_SPATIAL
-const Name Type_handler_geometry::m_name_geometry(C_STRING_WITH_LEN("geometry"));
+const Name Type_handler_geometry::m_name_geometry(STRING_WITH_LEN("geometry"));
const Type_handler *Type_handler_geometry::type_handler_for_comparison() const
@@ -2063,6 +2101,19 @@ Field *Type_handler_longlong::make_table_field(const LEX_CSTRING *name,
}
+Field *Type_handler_vers_trx_id::make_table_field(const LEX_CSTRING *name,
+ const Record_addr &addr,
+ const Type_all_attributes &attr,
+ TABLE *table) const
+{
+ return new (table->in_use->mem_root)
+ Field_vers_trx_id(addr.ptr, attr.max_char_length(),
+ addr.null_ptr, addr.null_bit,
+ Field::NONE, name,
+ 0/*zerofill*/, attr.unsigned_flag);
+}
+
+
Field *Type_handler_float::make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -2680,6 +2731,12 @@ Type_handler_int_result::Item_get_cache(THD *thd, const Item *item) const
}
Item_cache *
+Type_handler_year::Item_get_cache(THD *thd, const Item *item) const
+{
+ return new (thd->mem_root) Item_cache_year(thd);
+}
+
+Item_cache *
Type_handler_real_result::Item_get_cache(THD *thd, const Item *item) const
{
return new (thd->mem_root) Item_cache_real(thd);
@@ -2730,7 +2787,7 @@ bool Type_handler_int_result::
Type_all_attributes *func,
Item **items, uint nitems) const
{
- uint unsigned_flag= items[0]->unsigned_flag;
+ bool unsigned_flag= items[0]->unsigned_flag;
for (uint i= 1; i < nitems; i++)
{
if (unsigned_flag != items[i]->unsigned_flag)
@@ -3205,6 +3262,53 @@ bool Type_handler_string_result::Item_val_bool(Item *item) const
/*************************************************************************/
+bool Type_handler_int_result::Item_get_date(Item *item, MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return item->get_date_from_int(ltime, fuzzydate);
+}
+
+
+bool Type_handler_year::Item_get_date(Item *item, MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return item->get_date_from_year(ltime, fuzzydate);
+}
+
+
+bool Type_handler_real_result::Item_get_date(Item *item, MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return item->get_date_from_real(ltime, fuzzydate);
+}
+
+
+bool Type_handler_decimal_result::Item_get_date(Item *item, MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return item->get_date_from_decimal(ltime, fuzzydate);
+}
+
+
+bool Type_handler_string_result::Item_get_date(Item *item, MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return item->get_date_from_string(ltime, fuzzydate);
+}
+
+
+bool Type_handler_temporal_result::Item_get_date(Item *item, MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ DBUG_ASSERT(0); // Temporal type items must implement native get_date()
+ item->null_value= true;
+ set_zero_time(ltime, mysql_timestamp_type());
+ return true;
+}
+
+
+/*************************************************************************/
+
longlong Type_handler_real_result::
Item_val_int_signed_typecast(Item *item) const
{
@@ -3498,7 +3602,55 @@ Type_handler_temporal_result::Item_func_hybrid_field_type_get_date(
MYSQL_TIME *ltime,
ulonglong fuzzydate) const
{
- return item->get_date_from_date_op(ltime, fuzzydate);
+ return item->date_op(ltime, fuzzydate);
+}
+
+
+/***************************************************************************/
+
+String *
+Type_handler_time_common::Item_func_hybrid_field_type_val_str(
+ Item_func_hybrid_field_type *item,
+ String *str) const
+{
+ return item->val_str_from_time_op(str);
+}
+
+
+double
+Type_handler_time_common::Item_func_hybrid_field_type_val_real(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return item->val_real_from_time_op();
+}
+
+
+longlong
+Type_handler_time_common::Item_func_hybrid_field_type_val_int(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return item->val_int_from_time_op();
+}
+
+
+my_decimal *
+Type_handler_time_common::Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *item,
+ my_decimal *dec) const
+{
+ return item->val_decimal_from_time_op(dec);
+}
+
+
+bool
+Type_handler_time_common::Item_func_hybrid_field_type_get_date(
+ Item_func_hybrid_field_type *item,
+ MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return item->time_op(ltime);
}
@@ -3920,7 +4072,7 @@ bool Type_handler_string_result::
::get_date() can be called for non-temporal values,
for example, SELECT MONTH(GREATEST("2011-11-21", "2010-10-09"))
*/
- return func->Item::get_date(ltime, fuzzydate);
+ return func->get_date_from_string(ltime, fuzzydate);
}
@@ -3928,7 +4080,7 @@ bool Type_handler_numeric::
Item_func_min_max_get_date(Item_func_min_max *func,
MYSQL_TIME *ltime, ulonglong fuzzydate) const
{
- return func->Item::get_date(ltime, fuzzydate);
+ return Item_get_date(func, ltime, fuzzydate);
}
@@ -3939,6 +4091,13 @@ bool Type_handler_temporal_result::
return func->get_date_native(ltime, fuzzydate);
}
+bool Type_handler_time_common::
+ Item_func_min_max_get_date(Item_func_min_max *func,
+ MYSQL_TIME *ltime, ulonglong fuzzydate) const
+{
+ return func->get_time_native(ltime);
+}
+
/***************************************************************************/
/**
@@ -3950,7 +4109,7 @@ String *Type_handler_row::
{
CHARSET_INFO *cs= thd->variables.character_set_client;
StringBuffer<STRING_BUFFER_USUAL_SIZE> val(cs);
- str->append(C_STRING_WITH_LEN("ROW("));
+ str->append(STRING_WITH_LEN("ROW("));
for (uint i= 0 ; i < item->cols(); i++)
{
if (i > 0)
@@ -3962,7 +4121,7 @@ String *Type_handler_row::
else
str->append(STRING_WITH_LEN("NULL"));
}
- str->append(C_STRING_WITH_LEN(")"));
+ str->append(STRING_WITH_LEN(")"));
return str;
}
@@ -4026,7 +4185,7 @@ String *Type_handler_time_common::
{
StringBuffer<MAX_TIME_FULL_WIDTH+1> buf;
return print_item_value_temporal(thd, item, str,
- Name(C_STRING_WITH_LEN("TIME")), &buf);
+ Name(STRING_WITH_LEN("TIME")), &buf);
}
@@ -4035,7 +4194,7 @@ String *Type_handler_date_common::
{
StringBuffer<MAX_DATE_WIDTH+1> buf;
return print_item_value_temporal(thd, item, str,
- Name(C_STRING_WITH_LEN("DATE")), &buf);
+ Name(STRING_WITH_LEN("DATE")), &buf);
}
@@ -4044,7 +4203,7 @@ String *Type_handler_datetime_common::
{
StringBuffer<MAX_DATETIME_FULL_WIDTH+1> buf;
return print_item_value_temporal(thd, item, str,
- Name(C_STRING_WITH_LEN("TIMESTAMP")), &buf);
+ Name(STRING_WITH_LEN("TIMESTAMP")), &buf);
}
@@ -4053,7 +4212,7 @@ String *Type_handler_timestamp_common::
{
StringBuffer<MAX_DATETIME_FULL_WIDTH+1> buf;
return print_item_value_temporal(thd, item, str,
- Name(C_STRING_WITH_LEN("TIMESTAMP")), &buf);
+ Name(STRING_WITH_LEN("TIMESTAMP")), &buf);
}
@@ -4376,7 +4535,7 @@ bool Type_handler::
bool Type_handler::
Item_char_typecast_fix_length_and_dec(Item_char_typecast *item) const
{
- item->fix_length_and_dec_str();
+ item->fix_length_and_dec_generic();
return false;
}
@@ -4389,6 +4548,14 @@ bool Type_handler_numeric::
}
+bool Type_handler_string_result::
+ Item_char_typecast_fix_length_and_dec(Item_char_typecast *item) const
+{
+ item->fix_length_and_dec_str();
+ return false;
+}
+
+
bool Type_handler::
Item_time_typecast_fix_length_and_dec(Item_time_typecast *item) const
{
@@ -5044,7 +5211,6 @@ bool Type_handler_real_result::
{
param->unsigned_flag= attr->unsigned_flag;
param->set_double(val->value.m_double);
- param->set_handler(&type_handler_double);
return false;
}
@@ -5056,8 +5222,7 @@ bool Type_handler_int_result::
const st_value *val) const
{
param->unsigned_flag= attr->unsigned_flag;
- param->set_int(val->value.m_longlong, MY_INT64_NUM_DECIMAL_DIGITS);
- param->set_handler(&type_handler_longlong);
+ param->set_int(val->value.m_longlong, attr->max_length);
return false;
}
@@ -5070,7 +5235,6 @@ bool Type_handler_decimal_result::
{
param->unsigned_flag= attr->unsigned_flag;
param->set_decimal(&val->m_decimal, attr->unsigned_flag);
- param->set_handler(&type_handler_newdecimal);
return false;
}
@@ -5082,13 +5246,14 @@ bool Type_handler_string_result::
const st_value *val) const
{
param->unsigned_flag= false;
- param->value.cs_info.set(thd, attr->collation.collation);
+ param->setup_conversion_string(thd, attr->collation.collation);
/*
Exact value of max_length is not known unless data is converted to
charset of connection, so we have to set it later.
*/
- param->set_handler(&type_handler_varchar);
- return param->set_str(val->m_string.ptr(), val->m_string.length());
+ return param->set_str(val->m_string.ptr(), val->m_string.length(),
+ attr->collation.collation,
+ attr->collation.collation);
}
@@ -5100,7 +5265,6 @@ bool Type_handler_temporal_result::
{
param->unsigned_flag= attr->unsigned_flag;
param->set_time(&val->value.m_time, attr->max_length, attr->decimals);
- param->set_handler(this);
return false;
}
@@ -5113,10 +5277,10 @@ bool Type_handler_geometry::
const st_value *val) const
{
param->unsigned_flag= false;
- param->value.cs_info.set(thd, &my_charset_bin);
- param->set_handler(&type_handler_geometry);
+ param->setup_conversion_blob(thd);
param->set_geometry_type(attr->uint_geometry_type());
- return param->set_str(val->m_string.ptr(), val->m_string.length());
+ return param->set_str(val->m_string.ptr(), val->m_string.length(),
+ &my_charset_bin, &my_charset_bin);
}
#endif
@@ -5502,3 +5666,139 @@ Item *Type_handler_long_blob::
}
/***************************************************************************/
+
+void Type_handler_string_result::Item_param_setup_conversion(THD *thd,
+ Item_param *param)
+ const
+{
+ param->setup_conversion_string(thd, thd->variables.character_set_client);
+}
+
+
+void Type_handler_blob_common::Item_param_setup_conversion(THD *thd,
+ Item_param *param)
+ const
+{
+ param->setup_conversion_blob(thd);
+}
+
+
+void Type_handler_tiny::Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const
+{
+ param->set_param_tiny(pos, len);
+}
+
+
+void Type_handler_short::Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const
+{
+ param->set_param_short(pos, len);
+}
+
+
+void Type_handler_long::Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const
+{
+ param->set_param_int32(pos, len);
+}
+
+
+void Type_handler_longlong::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_param_int64(pos, len);
+}
+
+
+void Type_handler_float::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_param_float(pos, len);
+}
+
+
+void Type_handler_double::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_param_double(pos, len);
+}
+
+
+void Type_handler_decimal_result::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_param_decimal(pos, len);
+}
+
+
+void Type_handler_string_result::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_param_str(pos, len);
+}
+
+
+void Type_handler_time_common::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_param_time(pos, len);
+}
+
+
+void Type_handler_date_common::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_param_date(pos, len);
+}
+
+
+void Type_handler_datetime_common::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_param_datetime(pos, len);
+}
+
+
+void Type_handler_timestamp_common::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_param_datetime(pos, len);
+}
+
+
+void Type_handler::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_null(); // Not possible type code in the client-server protocol
+}
+
+
+void Type_handler_typelib::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_null(); // Not possible type code in the client-server protocol
+}
+
+
+#ifdef HAVE_SPATIAL
+void Type_handler_geometry::Item_param_set_param_func(Item_param *param,
+ uchar **pos,
+ ulong len) const
+{
+ param->set_null(); // Not possible type code in the client-server protocol
+}
+#endif
+
+/***************************************************************************/
diff --git a/sql/sql_type.h b/sql/sql_type.h
index d94c5a87811..db03b77d48f 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -24,7 +24,7 @@
#include "mysqld.h"
#include "sql_array.h"
#include "sql_const.h"
-#include "my_time.h"
+#include "sql_time.h"
class Field;
class Column_definition;
@@ -74,6 +74,351 @@ struct TABLE;
struct SORT_FIELD_ATTR;
+/**
+ Class Time is designed to store valid TIME values.
+
+ 1. Valid value:
+ a. MYSQL_TIMESTAMP_TIME - a valid TIME within the supported TIME range
+ b. MYSQL_TIMESTAMP_NONE - an undefined value
+
+ 2. Invalid value (internally only):
+ a. MYSQL_TIMESTAMP_TIME outside of the supported TIME range
+ a. MYSQL_TIMESTAMP_{DATE|DATETIME|ERROR}
+
+ Temporarily Time is allowed to have an invalid value, but only internally,
+ during initialization time. All constructors and modification methods must
+ leave the Time value as described above (see "Valid values").
+
+ Time derives from MYSQL_TIME privately to make sure it is accessed
+ externally only in the valid state.
+*/
+class Time: private MYSQL_TIME
+{
+public:
+ enum datetime_to_time_mode_t
+ {
+ DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS,
+ DATETIME_TO_TIME_YYYYMMDD_TRUNCATE
+ };
+ class Options
+ {
+ sql_mode_t m_get_date_flags;
+ datetime_to_time_mode_t m_datetime_to_time_mode;
+ public:
+ Options()
+ :m_get_date_flags(flags_for_get_date()),
+ m_datetime_to_time_mode(DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
+ { }
+ Options(sql_mode_t flags)
+ :m_get_date_flags(flags),
+ m_datetime_to_time_mode(DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
+ { }
+ Options(sql_mode_t flags, datetime_to_time_mode_t dtmode)
+ :m_get_date_flags(flags),
+ m_datetime_to_time_mode(dtmode)
+ { }
+ sql_mode_t get_date_flags() const
+ { return m_get_date_flags; }
+ datetime_to_time_mode_t datetime_to_time_mode() const
+ { return m_datetime_to_time_mode; }
+ };
+ /*
+ CAST(AS TIME) historically does not mix days to hours.
+ This is different comparing to how implicit conversion
+ in Field::store_time_dec() works (e.g. on INSERT).
+ */
+ class Options_for_cast: public Options
+ {
+ public:
+ Options_for_cast()
+ :Options(flags_for_get_date(), DATETIME_TO_TIME_YYYYMMDD_TRUNCATE)
+ { }
+ };
+private:
+ bool is_valid_value_slow() const
+ {
+ return time_type == MYSQL_TIMESTAMP_NONE || is_valid_time_slow();
+ }
+ bool is_valid_time_slow() const
+ {
+ return time_type == MYSQL_TIMESTAMP_TIME &&
+ year == 0 && month == 0 && day == 0 &&
+ minute <= TIME_MAX_MINUTE &&
+ second <= TIME_MAX_SECOND &&
+ second_part <= TIME_MAX_SECOND_PART;
+ }
+
+ /*
+ Convert a valid DATE or DATETIME to TIME.
+ Before this call, "this" must be a valid DATE or DATETIME value,
+ e.g. returned from Item::get_date().
+ After this call, "this" is a valid TIME value.
+ */
+ void valid_datetime_to_valid_time(const Options opt)
+ {
+ DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATE ||
+ time_type == MYSQL_TIMESTAMP_DATETIME);
+ /*
+ Make sure that day and hour are valid, so the result hour value
+ after mixing days to hours does not go out of the valid TIME range.
+ */
+ DBUG_ASSERT(day < 32);
+ DBUG_ASSERT(hour < 24);
+ if (year == 0 && month == 0 &&
+ opt.datetime_to_time_mode() ==
+ DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
+ {
+ /*
+ The maximum hour value after mixing days will be 31*24+23=767,
+ which is within the supported TIME range.
+ Thus no adjust_time_range_or_invalidate() is needed here.
+ */
+ hour+= day * 24;
+ }
+ year= month= day= 0;
+ time_type= MYSQL_TIMESTAMP_TIME;
+ DBUG_ASSERT(is_valid_time_slow());
+ }
+ /**
+ Convert valid DATE/DATETIME to valid TIME if needed.
+ This method is called after Item::get_date(),
+ which can return only valid TIME/DATE/DATETIME values.
+ Before this call, "this" is:
+ - either a valid TIME/DATE/DATETIME value
+ (within the supported range for the corresponding type),
+ - or MYSQL_TIMESTAMP_NONE
+ After this call, "this" is:
+ - either a valid TIME (within the supported TIME range),
+ - or MYSQL_TIMESTAMP_NONE
+ */
+ void valid_MYSQL_TIME_to_valid_value(const Options opt)
+ {
+ switch (time_type) {
+ case MYSQL_TIMESTAMP_DATE:
+ case MYSQL_TIMESTAMP_DATETIME:
+ valid_datetime_to_valid_time(opt);
+ break;
+ case MYSQL_TIMESTAMP_NONE:
+ break;
+ case MYSQL_TIMESTAMP_ERROR:
+ set_zero_time(this, MYSQL_TIMESTAMP_TIME);
+ break;
+ case MYSQL_TIMESTAMP_TIME:
+ DBUG_ASSERT(is_valid_time_slow());
+ break;
+ }
+ }
+ void make_from_item(class Item *item, const Options opt);
+public:
+ Time() { time_type= MYSQL_TIMESTAMP_NONE; }
+ Time(Item *item) { make_from_item(item, Options()); }
+ Time(Item *item, const Options opt) { make_from_item(item, opt); }
+ static sql_mode_t flags_for_get_date()
+ { return TIME_TIME_ONLY | TIME_INVALID_DATES; }
+ static sql_mode_t comparison_flags_for_get_date()
+ { return TIME_TIME_ONLY | TIME_INVALID_DATES | TIME_FUZZY_DATES; }
+ bool is_valid_time() const
+ {
+ DBUG_ASSERT(is_valid_value_slow());
+ return time_type == MYSQL_TIMESTAMP_TIME;
+ }
+ const MYSQL_TIME *get_mysql_time() const
+ {
+ DBUG_ASSERT(is_valid_time_slow());
+ return this;
+ }
+ bool copy_to_mysql_time(MYSQL_TIME *ltime) const
+ {
+ if (time_type == MYSQL_TIMESTAMP_NONE)
+ {
+ ltime->time_type= MYSQL_TIMESTAMP_NONE;
+ return true;
+ }
+ DBUG_ASSERT(is_valid_time_slow());
+ *ltime= *this;
+ return false;
+ }
+ int cmp(const Time *other) const
+ {
+ DBUG_ASSERT(is_valid_time_slow());
+ DBUG_ASSERT(other->is_valid_time_slow());
+ longlong p0= pack_time(this);
+ longlong p1= pack_time(other);
+ if (p0 < p1)
+ return -1;
+ if (p0 > p1)
+ return 1;
+ return 0;
+ }
+ longlong to_seconds_abs() const
+ {
+ DBUG_ASSERT(is_valid_time_slow());
+ return hour * 3600L + minute * 60 + second;
+ }
+ longlong to_seconds() const
+ {
+ return neg ? -to_seconds_abs() : to_seconds_abs();
+ }
+};
+
+
+/**
+ Class Temporal_with_date is designed to store valid DATE or DATETIME values.
+ See also class Time.
+
+ 1. Valid value:
+ a. MYSQL_TIMESTAMP_{DATE|DATETIME} - a valid DATE or DATETIME value
+ b. MYSQL_TIMESTAMP_NONE - an undefined value
+
+ 2. Invalid value (internally only):
+ a. MYSQL_TIMESTAMP_{DATE|DATETIME} - a DATE or DATETIME value, but with
+ MYSQL_TIME members outside of the
+ valid/supported range
+ b. MYSQL_TIMESTAMP_TIME - a TIME value
+ c. MYSQL_TIMESTAMP_ERROR - error
+
+ Temporarily is allowed to have an invalid value, but only internally,
+ during initialization time. All constructors and modification methods must
+ leave the value as described above (see "Valid value").
+
+ Derives from MYSQL_TIME using "protected" inheritance to make sure
+ it is accessed externally only in the valid state.
+*/
+
+class Temporal_with_date: protected MYSQL_TIME
+{
+protected:
+ void make_from_item(THD *thd, Item *item, sql_mode_t flags);
+ Temporal_with_date(THD *thd, Item *item, sql_mode_t flags)
+ {
+ make_from_item(thd, item, flags);
+ }
+};
+
+
+/**
+ Class Date is designed to store valid DATE values.
+ All constructors and modification methods leave instances
+ of this class in one of the following valid states:
+ a. MYSQL_TIMESTAMP_DATE - a DATE with all MYSQL_TIME members properly set
+ b. MYSQL_TIMESTAMP_NONE - an undefined value.
+ Other MYSQL_TIMESTAMP_XXX are not possible.
+ MYSQL_TIMESTAMP_DATE with MYSQL_TIME members improperly set is not possible.
+*/
+class Date: public Temporal_with_date
+{
+ bool is_valid_value_slow() const
+ {
+ return time_type == MYSQL_TIMESTAMP_NONE || is_valid_date_slow();
+ }
+ bool is_valid_date_slow() const
+ {
+ DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATE);
+ return !check_datetime_range(this);
+ }
+public:
+ Date(THD *thd, Item *item, sql_mode_t flags)
+ :Temporal_with_date(thd, item, flags)
+ {
+ if (time_type == MYSQL_TIMESTAMP_DATETIME)
+ datetime_to_date(this);
+ DBUG_ASSERT(is_valid_value_slow());
+ }
+ Date(const Temporal_with_date *d)
+ :Temporal_with_date(*d)
+ {
+ datetime_to_date(this);
+ DBUG_ASSERT(is_valid_date_slow());
+ }
+ bool is_valid_date() const
+ {
+ DBUG_ASSERT(is_valid_value_slow());
+ return time_type == MYSQL_TIMESTAMP_DATE;
+ }
+ const MYSQL_TIME *get_mysql_time() const
+ {
+ DBUG_ASSERT(is_valid_date_slow());
+ return this;
+ }
+};
+
+
+/**
+ Class Datetime is designed to store valid DATETIME values.
+ All constructors and modification methods leave instances
+ of this class in one of the following valid states:
+ a. MYSQL_TIMESTAMP_DATETIME - a DATETIME with all members properly set
+ b. MYSQL_TIMESTAMP_NONE - an undefined value.
+ Other MYSQL_TIMESTAMP_XXX are not possible.
+ MYSQL_TIMESTAMP_DATETIME with MYSQL_TIME members
+ improperly set is not possible.
+*/
+class Datetime: public Temporal_with_date
+{
+ bool is_valid_value_slow() const
+ {
+ return time_type == MYSQL_TIMESTAMP_NONE || is_valid_datetime_slow();
+ }
+ bool is_valid_datetime_slow() const
+ {
+ DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATETIME);
+ return !check_datetime_range(this);
+ }
+public:
+ Datetime(THD *thd, Item *item, sql_mode_t flags)
+ :Temporal_with_date(thd, item, flags)
+ {
+ if (time_type == MYSQL_TIMESTAMP_DATE)
+ date_to_datetime(this);
+ DBUG_ASSERT(is_valid_value_slow());
+ }
+ bool is_valid_datetime() const
+ {
+ /*
+ Here we quickly check for the type only.
+ If the type is valid, the rest of value must also be valid.
+ */
+ DBUG_ASSERT(is_valid_value_slow());
+ return time_type == MYSQL_TIMESTAMP_DATETIME;
+ }
+ bool hhmmssff_is_zero() const
+ {
+ DBUG_ASSERT(is_valid_datetime_slow());
+ return hour == 0 && minute == 0 && second == 0 && second_part == 0;
+ }
+ const MYSQL_TIME *get_mysql_time() const
+ {
+ DBUG_ASSERT(is_valid_datetime_slow());
+ return this;
+ }
+ bool copy_to_mysql_time(MYSQL_TIME *ltime) const
+ {
+ if (time_type == MYSQL_TIMESTAMP_NONE)
+ {
+ ltime->time_type= MYSQL_TIMESTAMP_NONE;
+ return true;
+ }
+ DBUG_ASSERT(is_valid_datetime_slow());
+ *ltime= *this;
+ return false;
+ }
+ /**
+ Copy without data loss, with an optional DATETIME to DATE conversion.
+ If the value of the "type" argument is MYSQL_TIMESTAMP_DATE,
+ then "this" must be a datetime with a zero hhmmssff part.
+ */
+ bool copy_to_mysql_time(MYSQL_TIME *ltime, timestamp_type type)
+ {
+ DBUG_ASSERT(type == MYSQL_TIMESTAMP_DATE ||
+ type == MYSQL_TIMESTAMP_DATETIME);
+ if (copy_to_mysql_time(ltime))
+ return true;
+ DBUG_ASSERT(type != MYSQL_TIMESTAMP_DATE || hhmmssff_is_zero());
+ ltime->time_type= type;
+ return false;
+ }
+};
+
/*
Flags for collation aggregation modes, used in TDCollation::agg():
@@ -805,6 +1150,9 @@ public:
virtual uint32 max_display_length(const Item *item) const= 0;
virtual uint32 calc_pack_length(uint32 length) const= 0;
virtual bool Item_save_in_value(Item *item, st_value *value) const= 0;
+ virtual void Item_param_setup_conversion(THD *thd, Item_param *) const {}
+ virtual void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
virtual bool Item_param_set_from_value(THD *thd,
Item_param *param,
const Type_all_attributes *attr,
@@ -903,6 +1251,8 @@ public:
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const= 0;
virtual bool Item_val_bool(Item *item) const= 0;
+ virtual bool Item_get_date(Item *item, MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const= 0;
virtual longlong Item_val_int_signed_typecast(Item *item) const= 0;
virtual longlong Item_val_int_unsigned_typecast(Item *item) const= 0;
@@ -1163,6 +1513,11 @@ public:
DBUG_ASSERT(0);
return false;
}
+ bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const
+ {
+ DBUG_ASSERT(0);
+ return true;
+ }
longlong Item_val_int_signed_typecast(Item *item) const
{
DBUG_ASSERT(0);
@@ -1369,6 +1724,7 @@ public:
bool Item_func_signed_fix_length_and_dec(Item_func_signed *item) const;
bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const;
bool Item_val_bool(Item *item) const;
+ bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
longlong Item_val_int_signed_typecast(Item *item) const;
longlong Item_val_int_unsigned_typecast(Item *item) const;
String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
@@ -1423,6 +1779,8 @@ public:
const Type_cast_attributes &attr) const;
uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
bool Item_param_set_from_value(THD *thd,
Item_param *param,
const Type_all_attributes *attr,
@@ -1445,6 +1803,7 @@ public:
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
bool Item_val_bool(Item *item) const;
+ bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
longlong Item_val_int_signed_typecast(Item *item) const;
longlong Item_val_int_unsigned_typecast(Item *item) const;
String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
@@ -1513,6 +1872,7 @@ public:
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
bool Item_val_bool(Item *item) const;
+ bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
longlong Item_val_int_signed_typecast(Item *item) const;
longlong Item_val_int_unsigned_typecast(Item *item) const;
String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
@@ -1583,6 +1943,7 @@ public:
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
bool Item_val_bool(Item *item) const;
+ bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
longlong Item_val_int_signed_typecast(Item *item) const;
longlong Item_val_int_unsigned_typecast(Item *item) const;
String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
@@ -1659,6 +2020,9 @@ public:
}
uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const;
+ void Item_param_setup_conversion(THD *thd, Item_param *) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
bool Item_param_set_from_value(THD *thd,
Item_param *param,
const Type_all_attributes *attr,
@@ -1693,6 +2057,7 @@ public:
bool Item_func_signed_fix_length_and_dec(Item_func_signed *item) const;
bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const;
bool Item_val_bool(Item *item) const;
+ bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
longlong Item_val_int_signed_typecast(Item *item) const;
longlong Item_val_int_unsigned_typecast(Item *item) const;
String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
@@ -1717,6 +2082,7 @@ public:
MYSQL_TIME *, ulonglong fuzzydate) const;
bool Item_func_between_fix_length_and_dec(Item_func_between *func) const;
longlong Item_func_between_val_int(Item_func_between *func) const;
+ bool Item_char_typecast_fix_length_and_dec(Item_char_typecast *) const;
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
bool Item_func_in_fix_comparator_compatible_types(THD *thd,
@@ -1784,6 +2150,8 @@ public:
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
};
@@ -1811,6 +2179,8 @@ public:
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
};
@@ -1841,6 +2211,8 @@ public:
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
};
@@ -1872,6 +2244,19 @@ public:
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
+};
+
+
+class Type_handler_vers_trx_id: public Type_handler_longlong
+{
+public:
+ virtual ~Type_handler_vers_trx_id() {}
+ Field *make_table_field(const LEX_CSTRING *name,
+ const Record_addr &addr,
+ const Type_all_attributes &attr,
+ TABLE *table) const;
};
@@ -1926,6 +2311,8 @@ public:
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
+ Item_cache *Item_get_cache(THD *thd, const Item *item) const;
+ bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
};
@@ -1995,6 +2382,8 @@ public:
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
};
@@ -2025,6 +2414,8 @@ public:
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
};
@@ -2065,10 +2456,26 @@ public:
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
+ String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
+ String *) const;
+ double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
+ const;
+ longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
+ const;
+ my_decimal *Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *,
+ my_decimal *) const;
+ bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
+ MYSQL_TIME *,
+ ulonglong fuzzydate) const;
+ bool Item_func_min_max_get_date(Item_func_min_max*,
+ MYSQL_TIME *, ulonglong fuzzydate) const;
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
bool set_comparator_func(Arg_comparator *cmp) const;
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
};
@@ -2152,6 +2559,8 @@ public:
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
};
class Type_handler_date: public Type_handler_date_common
@@ -2226,6 +2635,8 @@ public:
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
};
@@ -2306,6 +2717,8 @@ public:
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
};
@@ -2574,6 +2987,7 @@ public:
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
+ void Item_param_setup_conversion(THD *thd, Item_param *) const;
};
@@ -2675,6 +3089,8 @@ public:
{
return false; // Materialization does not work with GEOMETRY columns
}
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
bool Item_param_set_from_value(THD *thd,
Item_param *param,
const Type_all_attributes *attr,
@@ -2754,6 +3170,8 @@ public:
const handler *file,
const Schema_specification_st *schema)
const;
+ void Item_param_set_param_func(Item_param *param,
+ uchar **pos, ulong len) const;
};
@@ -2811,15 +3229,21 @@ public:
class Type_handler_hybrid_field_type
{
const Type_handler *m_type_handler;
+ bool m_vers_trx_id;
bool aggregate_for_min_max(const Type_handler *other);
+
public:
Type_handler_hybrid_field_type();
Type_handler_hybrid_field_type(const Type_handler *handler)
- :m_type_handler(handler)
+ :m_type_handler(handler), m_vers_trx_id(false)
{ }
Type_handler_hybrid_field_type(const Type_handler_hybrid_field_type *other)
- :m_type_handler(other->m_type_handler)
+ :m_type_handler(other->m_type_handler), m_vers_trx_id(other->m_vers_trx_id)
{ }
+ void swap(Type_handler_hybrid_field_type &other)
+ {
+ swap_variables(const Type_handler *, m_type_handler, other.m_type_handler);
+ }
const Type_handler *type_handler() const { return m_type_handler; }
enum_field_types real_field_type() const
{
@@ -2903,6 +3327,7 @@ extern MYSQL_PLUGIN_IMPORT Type_handler_int24 type_handler_int24;
extern MYSQL_PLUGIN_IMPORT Type_handler_long type_handler_long;
extern MYSQL_PLUGIN_IMPORT Type_handler_longlong type_handler_longlong;
extern MYSQL_PLUGIN_IMPORT Type_handler_longlong type_handler_ulonglong;
+extern MYSQL_PLUGIN_IMPORT Type_handler_vers_trx_id type_handler_vers_trx_id;
extern MYSQL_PLUGIN_IMPORT Type_handler_newdecimal type_handler_newdecimal;
extern MYSQL_PLUGIN_IMPORT Type_handler_olddecimal type_handler_olddecimal;
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 7b2d041a094..3eb50d45b42 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -52,7 +52,7 @@ static bool initialized = 0;
static MEM_ROOT mem;
static HASH udf_hash;
static mysql_rwlock_t THR_LOCK_udf;
-
+static LEX_CSTRING MYSQL_FUNC_NAME= {STRING_WITH_LEN("func") };
static udf_func *add_udf(LEX_CSTRING *name, Item_result ret,
const char *dl, Item_udftype typ);
@@ -142,7 +142,6 @@ void udf_init()
TABLE *table;
int error;
DBUG_ENTER("ufd_init");
- char db[]= "mysql"; /* A subject to casednstr, can't be constant */
if (initialized || opt_noacl)
DBUG_VOID_RETURN;
@@ -153,7 +152,7 @@ void udf_init()
mysql_rwlock_init(key_rwlock_THR_LOCK_udf, &THR_LOCK_udf);
- init_sql_alloc(&mem, UDF_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(&mem, "udf", UDF_ALLOC_BLOCK_SIZE, 0, MYF(0));
THD *new_thd = new THD(0);
if (!new_thd ||
my_hash_init(&udf_hash,system_charset_info,32,0,0,get_hash_key, NULL, 0))
@@ -167,9 +166,9 @@ void udf_init()
initialized = 1;
new_thd->thread_stack= (char*) &new_thd;
new_thd->store_globals();
- new_thd->set_db(db, sizeof(db)-1);
+ new_thd->set_db(&MYSQL_SCHEMA_NAME);
- tables.init_one_table(db, sizeof(db)-1, "func", 4, "func", TL_READ);
+ tables.init_one_table(&new_thd->db, &MYSQL_FUNC_NAME, 0, TL_READ);
if (open_and_lock_tables(new_thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{
@@ -313,7 +312,7 @@ static void del_udf(udf_func *udf)
doesn't use it anymore
*/
const char *name= udf->name.str;
- uint name_length=udf->name.length;
+ size_t name_length=udf->name.length;
udf->name.str= "*";
udf->name.length=1;
my_hash_update(&udf_hash,(uchar*) udf,(uchar*) name,name_length);
@@ -348,7 +347,7 @@ void free_udf(udf_func *udf)
/* This is only called if using_udf_functions != 0 */
-udf_func *find_udf(const char *name,uint length,bool mark_used)
+udf_func *find_udf(const char *name,size_t length,bool mark_used)
{
udf_func *udf=0;
DBUG_ENTER("find_udf");
@@ -433,7 +432,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;
- uint exact_name_len= udf->name.length;
+ size_t exact_name_len= udf->name.length;
del_udf(udf);
/*
@@ -504,8 +503,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
if (check_ident_length(&udf->name))
DBUG_RETURN(1);
- tables.init_one_table(STRING_WITH_LEN("mysql"), STRING_WITH_LEN("func"),
- "func", TL_WRITE);
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_FUNC_NAME, 0, TL_WRITE);
table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT);
mysql_rwlock_wrlock(&THR_LOCK_udf);
@@ -623,8 +621,7 @@ int mysql_drop_function(THD *thd, const LEX_CSTRING *udf_name)
DBUG_RETURN(1);
}
- tables.init_one_table(STRING_WITH_LEN("mysql"), STRING_WITH_LEN("func"),
- "func", TL_WRITE);
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_FUNC_NAME, 0, TL_WRITE);
table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT);
mysql_rwlock_wrlock(&THR_LOCK_udf);
diff --git a/sql/sql_udf.h b/sql/sql_udf.h
index 1c805227f97..6e6fed2a81a 100644
--- a/sql/sql_udf.h
+++ b/sql/sql_udf.h
@@ -137,7 +137,7 @@ class udf_handler :public Sql_alloc
#ifdef HAVE_DLOPEN
void udf_init(void),udf_free(void);
-udf_func *find_udf(const char *name, uint len, bool mark_used=0);
+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);
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 40f4f984e0a..857c9a117f5 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -68,14 +68,14 @@ void select_unit::change_select()
curr_sel= current_select_number;
/* New SELECT processing starts */
DBUG_ASSERT(table->file->inited == 0);
- switch (thd->lex->current_select->linkage)
+ step= thd->lex->current_select->linkage;
+ switch (step)
{
case INTERSECT_TYPE:
intersect_mark->value= prev_step= curr_step;
curr_step= current_select_number;
- /* fall through */
+ break;
case EXCEPT_TYPE:
- step= thd->lex->current_select->linkage;
break;
default:
step= UNION_TYPE;
@@ -303,7 +303,8 @@ int select_union_recursive::send_data(List<Item> &values)
{
int rc= select_unit::send_data(values);
- if (write_err != HA_ERR_FOUND_DUPP_KEY &&
+ if (rc == 0 &&
+ write_err != HA_ERR_FOUND_DUPP_KEY &&
write_err != HA_ERR_FOUND_DUPP_UNIQUE)
{
int err;
@@ -362,7 +363,7 @@ bool select_unit::flush()
bool
select_unit::create_result_table(THD *thd_arg, List<Item> *column_types,
bool is_union_distinct, ulonglong options,
- const char *alias,
+ const LEX_CSTRING *alias,
bool bit_fields_as_long, bool create_table,
bool keep_row_order,
uint hidden)
@@ -396,7 +397,7 @@ select_union_recursive::create_result_table(THD *thd_arg,
List<Item> *column_types,
bool is_union_distinct,
ulonglong options,
- const char *alias,
+ const LEX_CSTRING *alias,
bool bit_fields_as_long,
bool create_table,
bool keep_row_order,
@@ -404,14 +405,14 @@ select_union_recursive::create_result_table(THD *thd_arg,
{
if (select_unit::create_result_table(thd_arg, column_types,
is_union_distinct, options,
- "", bit_fields_as_long,
+ &empty_clex_str, bit_fields_as_long,
create_table, keep_row_order,
hidden))
return true;
if (! (incr_table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
(ORDER*) 0, false, 1,
- options, HA_POS_ERROR, "",
+ options, HA_POS_ERROR, &empty_clex_str,
!create_table, keep_row_order)))
return true;
@@ -644,6 +645,7 @@ bool st_select_lex_unit::prepare_join(THD *thd_arg, SELECT_LEX *sl,
bool is_union_select)
{
DBUG_ENTER("st_select_lex_unit::prepare_join");
+ TABLE_LIST *derived= sl->master_unit()->derived;
bool can_skip_order_by;
sl->options|= SELECT_NO_UNLOCK;
JOIN *join= new JOIN(thd_arg, sl->item_list,
@@ -659,7 +661,7 @@ bool st_select_lex_unit::prepare_join(THD *thd_arg, SELECT_LEX *sl,
saved_error= join->prepare(sl->table_list.first,
sl->with_wild,
- sl->where,
+ (derived && derived->merged ? NULL : sl->where),
(can_skip_order_by ? 0 :
sl->order_list.elements) +
sl->group_list.elements,
@@ -802,7 +804,7 @@ bool st_select_lex_unit::join_union_item_types(THD *thd_arg,
/* Error's in 'new' will be detected after loop */
types.push_back(new (thd_arg->mem_root)
Item_type_holder(thd_arg,
- &item_tmp->name,
+ item_tmp,
holders[pos].type_handler(),
&holders[pos]/*Type_all_attributes*/,
holders[pos].get_maybe_null()));
@@ -1008,7 +1010,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
goto err;
if (union_result->create_result_table(thd, &types,
MY_TEST(union_distinct),
- create_options, derived->alias,
+ create_options, &derived->alias,
false,
instantiate_tmp_table, false,
0))
@@ -1130,7 +1132,7 @@ cont:
bool error=
union_result->create_result_table(thd, &types,
MY_TEST(union_distinct),
- create_options, "", false,
+ create_options, &empty_clex_str, false,
instantiate_tmp_table, false,
hidden);
if (intersect_mark)
@@ -1145,8 +1147,10 @@ cont:
save_maybe_null= result_table_list.maybe_null_exec;
}
bzero((char*) &result_table_list, sizeof(result_table_list));
- result_table_list.db= (char*) "";
- result_table_list.table_name= result_table_list.alias= (char*) "union";
+ result_table_list.db.str= (char*) "";
+ result_table_list.db.length= 0;
+ result_table_list.table_name.str= result_table_list.alias.str= "union";
+ result_table_list.table_name.length= result_table_list.alias.length= sizeof("union")-1;
result_table_list.table= table= union_result->table;
if (fake_select_lex && !fake_select_lex->first_cond_optimization)
{
@@ -1360,6 +1364,17 @@ bool st_select_lex_unit::exec()
if (saved_error)
DBUG_RETURN(saved_error);
+ if (union_result)
+ {
+ union_result->init();
+ if (uncacheable & UNCACHEABLE_DEPENDENT &&
+ union_result->table && union_result->table->is_created())
+ {
+ union_result->table->file->ha_delete_all_rows();
+ union_result->table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL);
+ }
+ }
+
if (uncacheable || !item || !item->assigned() || describe)
{
if (!fake_select_lex && !(with_element && with_element->is_recursive))
@@ -1656,6 +1671,20 @@ bool st_select_lex_unit::exec_recursive()
for (st_select_lex *sl= start ; sl != end; sl= sl->next_select())
{
+ if (with_element->level)
+ {
+ for (TABLE_LIST *derived= with_element->derived_with_rec_ref.first;
+ derived;
+ derived= derived->next_with_rec_ref)
+ {
+ if (derived->is_materialized_derived())
+ {
+ if (derived->table->is_created())
+ derived->table->file->ha_delete_all_rows();
+ derived->table->reginfo.join_tab->preread_init_done= false;
+ }
+ }
+ }
thd->lex->current_select= sl;
if (sl->tvc)
sl->tvc->exec(sl);
@@ -1699,12 +1728,13 @@ bool st_select_lex_unit::exec_recursive()
if (!with_element->rec_result->first_rec_table_to_update)
with_element->rec_result->first_rec_table_to_update= rec_table;
if (with_element->level == 1 && rec_table->reginfo.join_tab)
- rec_table->reginfo.join_tab->preread_init_done= true;
+ rec_table->reginfo.join_tab->preread_init_done= true;
}
for (Item_subselect *sq= with_element->sq_with_rec_ref.first;
sq;
sq= sq->next_with_rec_ref)
{
+ sq->reset();
sq->engine->force_reexecution();
}
@@ -1717,7 +1747,7 @@ err:
bool st_select_lex_unit::cleanup()
{
- int error= 0;
+ bool error= 0;
DBUG_ENTER("st_select_lex_unit::cleanup");
if (cleaned)
@@ -1782,22 +1812,6 @@ void st_select_lex_unit::reinit_exec_mechanism()
{
prepared= optimized= optimized_2= executed= 0;
optimize_started= 0;
-#ifndef DBUG_OFF
- if (is_unit_op())
- {
- List_iterator_fast<Item> it(item_list);
- Item *field;
- while ((field= it++))
- {
- /*
- we can't cleanup here, because it broke link to temporary table field,
- but have to drop fixed flag to allow next fix_field of this field
- during re-executing
- */
- field->fixed= 0;
- }
- }
-#endif
if (with_element && with_element->is_recursive)
with_element->reset_recursive_for_exec();
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index bd577426483..38638d3aa1d 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -44,6 +44,9 @@
// mysql_derived_filling
+#include "sql_insert.h" // For vers_insert_history_row() that may be
+ // needed for System Versioning.
+
/**
True if the table's input and output record buffers are comparable using
compare_record(TABLE*).
@@ -129,29 +132,71 @@ bool compare_record(const TABLE *table)
FALSE Items are OK
*/
-static bool check_fields(THD *thd, List<Item> &items)
+static bool check_fields(THD *thd, List<Item> &items, bool update_view)
{
- List_iterator<Item> it(items);
Item *item;
- Item_field *field;
+ if (update_view)
+ {
+ List_iterator<Item> it(items);
+ Item_field *field;
+ while ((item= it++))
+ {
+ if (!(field= item->field_for_view_update()))
+ {
+ /* item has name, because it comes from VIEW SELECT list */
+ my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name.str);
+ return TRUE;
+ }
+ /*
+ we make temporary copy of Item_field, to avoid influence of changing
+ result_field on Item_ref which refer on this field
+ */
+ thd->change_item_tree(it.ref(),
+ new (thd->mem_root) Item_field(thd, field));
+ }
+ }
- while ((item= it++))
+ if (thd->variables.sql_mode & MODE_SIMULTANEOUS_ASSIGNMENT)
{
- if (!(field= item->field_for_view_update()))
+ // Make sure that a column is updated only once
+ List_iterator_fast<Item> it(items);
+ while ((item= it++))
{
- /* item has name, because it comes from VIEW SELECT list */
- my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name.str);
- return TRUE;
+ item->field_for_view_update()->field->clear_has_explicit_value();
+ }
+ it.rewind();
+ while ((item= it++))
+ {
+ Field *f= item->field_for_view_update()->field;
+ if (f->has_explicit_value())
+ {
+ my_error(ER_UPDATED_COLUMN_ONLY_ONCE, MYF(0),
+ *(f->table_name), f->field_name.str);
+ return TRUE;
+ }
+ f->set_has_explicit_value();
}
- /*
- we make temporary copy of Item_field, to avoid influence of changing
- result_field on Item_ref which refer on this field
- */
- thd->change_item_tree(it.ref(), new (thd->mem_root) Item_field(thd, field));
}
return FALSE;
}
+static bool check_has_vers_fields(TABLE *table, List<Item> &items)
+{
+ List_iterator<Item> it(items);
+ if (!table->versioned())
+ return false;
+
+ while (Item *item= it++)
+ {
+ if (Item_field *item_field= item->field_for_view_update())
+ {
+ Field *field= item_field->field;
+ if (field->table == table && !field->vers_update_unversioned())
+ return true;
+ }
+ }
+ return false;
+}
/**
Re-read record if more columns are needed for error message.
@@ -255,11 +300,12 @@ int mysql_update(THD *thd,
{
bool using_limit= limit != HA_POS_ERROR;
bool safe_update= thd->variables.option_bits & OPTION_SAFE_UPDATES;
- bool used_key_is_modified= FALSE, transactional_table, will_batch;
+ bool used_key_is_modified= FALSE, transactional_table;
+ bool will_batch= FALSE;
bool can_compare_record;
int res;
int error, loc_error;
- uint dup_key_found;
+ ha_rows dup_key_found;
bool need_sort= TRUE;
bool reverse= FALSE;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -276,18 +322,23 @@ int mysql_update(THD *thd,
ulonglong id;
List<Item> all_fields;
killed_state killed_status= NOT_KILLED;
+ bool has_triggers, binlog_is_row, do_direct_update= FALSE;
Update_plan query_plan(thd->mem_root);
Explain_update *explain;
TABLE_LIST *update_source_table;
query_plan.index= MAX_KEY;
query_plan.using_filesort= FALSE;
+
+ // For System Versioning (may need to insert new fields to a table).
+ ha_rows updated_sys_ver= 0;
+
DBUG_ENTER("mysql_update");
create_explain_query(thd->lex, thd->mem_root);
if (open_tables(thd, &table_list, &table_count, 0))
DBUG_RETURN(1);
- //Prepare views so they are handled correctly.
+ /* Prepare views so they are handled correctly */
if (mysql_handle_derived(thd->lex, DT_INIT))
DBUG_RETURN(1);
@@ -315,7 +366,7 @@ int mysql_update(THD *thd,
if (!table_list->single_table_updatable())
{
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "UPDATE");
DBUG_RETURN(1);
}
query_plan.updating_a_view= MY_TEST(table_list->view);
@@ -347,16 +398,20 @@ int mysql_update(THD *thd,
if (setup_fields_with_no_wrap(thd, Ref_ptr_array(),
fields, MARK_COLUMNS_WRITE, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
- if (table_list->view && check_fields(thd, fields))
+ if (check_fields(thd, fields, table_list->view))
{
DBUG_RETURN(1);
}
+ bool has_vers_fields= check_has_vers_fields(table, fields);
if (check_key_in_view(thd, table_list))
{
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "UPDATE");
DBUG_RETURN(1);
}
+ if (table->default_field)
+ table->mark_default_fields_for_write(false);
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Check values */
table_list->grant.want_privilege= table->grant.want_privilege=
@@ -515,7 +570,6 @@ int mysql_update(THD *thd,
query_plan.using_io_buffer= true;
}
-
/*
Ok, we have generated a query plan for the UPDATE.
- if we're running EXPLAIN UPDATE, goto produce explain output
@@ -530,10 +584,68 @@ int mysql_update(THD *thd,
DBUG_EXECUTE_IF("show_explain_probe_update_exec_start",
dbug_serve_apcs(thd, 1););
-
+
+ has_triggers= (table->triggers &&
+ (table->triggers->has_triggers(TRG_EVENT_UPDATE,
+ TRG_ACTION_BEFORE) ||
+ table->triggers->has_triggers(TRG_EVENT_UPDATE,
+ TRG_ACTION_AFTER)));
+ DBUG_PRINT("info", ("has_triggers: %s", has_triggers ? "TRUE" : "FALSE"));
+ binlog_is_row= thd->is_current_stmt_binlog_format_row();
+ DBUG_PRINT("info", ("binlog_is_row: %s", binlog_is_row ? "TRUE" : "FALSE"));
+
if (!(select && select->quick))
status_var_increment(thd->status_var.update_scan_count);
+ /*
+ We can use direct update (update that is done silently in the handler)
+ if none of the following conditions are true:
+ - There are triggers
+ - There is binary logging
+ - using_io_buffer
+ - This means that the partition changed or the key we want
+ to use for scanning the table is changed
+ - ignore is set
+ - Direct updates don't return the number of ignored rows
+ - There is a virtual not stored column in the WHERE clause
+ - Changing a field used by a stored virtual column, which
+ would require the column to be recalculated.
+ - ORDER BY or LIMIT
+ - As this requires the rows to be updated in a specific order
+ - Note that Spider can handle ORDER BY and LIMIT in a cluster with
+ one data node. These conditions are therefore checked in
+ direct_update_rows_init().
+
+ Direct update does not require a WHERE clause
+
+ Later we also ensure that we are only using one table (no sub queries)
+ */
+ if ((table->file->ha_table_flags() & HA_CAN_DIRECT_UPDATE_AND_DELETE) &&
+ !has_triggers && !binlog_is_row &&
+ !query_plan.using_io_buffer && !ignore &&
+ !table->check_virtual_columns_marked_for_read() &&
+ !table->check_virtual_columns_marked_for_write())
+ {
+ DBUG_PRINT("info", ("Trying direct update"));
+ if (select && select->cond &&
+ (select->cond->used_tables() == table->map))
+ {
+ DBUG_ASSERT(!table->file->pushed_cond);
+ if (!table->file->cond_push(select->cond))
+ table->file->pushed_cond= select->cond;
+ }
+
+ if (!table->file->info_push(INFO_KIND_UPDATE_FIELDS, &fields) &&
+ !table->file->info_push(INFO_KIND_UPDATE_VALUES, &values) &&
+ !table->file->direct_update_rows_init())
+ {
+ do_direct_update= TRUE;
+
+ /* Direct update is not using_filesort and is not using_io_buffer */
+ goto update_begin;
+ }
+ }
+
if (query_plan.using_filesort || query_plan.using_io_buffer)
{
/*
@@ -693,6 +805,7 @@ int mysql_update(THD *thd,
}
}
+update_begin:
if (ignore)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
@@ -712,11 +825,20 @@ int mysql_update(THD *thd,
transactional_table= table->file->has_transactions();
thd->abort_on_warning= !ignore && thd->is_strict_mode();
- if (table->prepare_triggers_for_update_stmt_or_event())
+
+ if (do_direct_update)
{
- will_batch= FALSE;
+ /* Direct updating is supported */
+ DBUG_PRINT("info", ("Using direct update"));
+ table->reset_default_fields();
+ if (!(error= table->file->ha_direct_update_rows(&updated)))
+ error= -1;
+ found= updated;
+ goto update_end;
}
- else
+
+ if ((table->file->ha_table_flags() & HA_CAN_FORCE_BULK_UPDATE) &&
+ !table->prepare_triggers_for_update_stmt_or_event())
will_batch= !table->file->start_bulk_update();
/*
@@ -739,6 +861,11 @@ int mysql_update(THD *thd,
THD_STAGE_INFO(thd, stage_updating);
while (!(error=info.read_record()) && !thd->killed)
{
+ if (table->versioned() && !table->vers_end_field()->is_max())
+ {
+ continue;
+ }
+
explain->tracker.on_record_read();
thd->inc_examined_row_count(1);
if (!select || select->skip_record(thd) > 0)
@@ -748,6 +875,7 @@ int mysql_update(THD *thd,
explain->tracker.on_record_after_where();
store_record(table,record[1]);
+
if (fill_record_n_invoke_before_triggers(thd, table, fields, values, 0,
TRG_EVENT_UPDATE))
break; /* purecov: inspected */
@@ -801,6 +929,7 @@ int mysql_update(THD *thd,
call then it should be included in the count of dup_key_found
and error should be set to 0 (only if these errors are ignored).
*/
+ DBUG_PRINT("info", ("Batched update"));
error= table->file->ha_bulk_update_row(table->record[1],
table->record[0],
&dup_key_found);
@@ -810,19 +939,32 @@ int mysql_update(THD *thd,
else
{
/* Non-batched update */
- error= table->file->ha_update_row(table->record[1],
+ error= table->file->ha_update_row(table->record[1],
table->record[0]);
}
- if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
- {
- if (error != HA_ERR_RECORD_IS_THE_SAME)
+ if (error == HA_ERR_RECORD_IS_THE_SAME)
+ {
+ error= 0;
+ }
+ else if (!error)
+ {
+ if (has_vers_fields && table->versioned())
+ {
+ if (table->versioned(VERS_TIMESTAMP))
+ {
+ store_record(table, record[2]);
+ error= vers_insert_history_row(table);
+ restore_record(table, record[2]);
+ }
+ if (!error)
+ updated_sys_ver++;
+ }
+ if (!error)
updated++;
- else
- error= 0;
- }
- else if (!ignore ||
- table->file->is_fatal_error(error, HA_CHECK_ALL))
- {
+ }
+
+ if (error && (!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL)))
+ {
/*
If (ignore && error is ignorable) we don't have to
do anything; otherwise...
@@ -949,6 +1091,8 @@ int mysql_update(THD *thd,
updated-= dup_key_found;
if (will_batch)
table->file->end_bulk_update();
+
+update_end:
table->file->try_semi_consistent_read(0);
if (!transactional_table && updated > 0)
@@ -993,6 +1137,9 @@ int mysql_update(THD *thd,
else
errcode= query_error_code(thd, killed_status == NOT_KILLED);
+ ScopedStatementReplication scoped_stmt_rpl(
+ table->versioned(VERS_TRX_ID) ? thd : NULL);
+
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
transactional_table, FALSE, FALSE, errcode))
@@ -1004,6 +1151,11 @@ int mysql_update(THD *thd,
DBUG_ASSERT(transactional_table || !updated || thd->transaction.stmt.modified_non_trans_table);
free_underlaid_joins(thd, select_lex);
delete file_sort;
+ if (table->file->pushed_cond)
+ {
+ table->file->pushed_cond= 0;
+ table->file->cond_pop();
+ }
/* If LAST_INSERT_ID(X) was used, report X */
id= thd->arg_of_last_insert_id_function ?
@@ -1012,9 +1164,15 @@ int mysql_update(THD *thd,
if (error < 0 && !thd->lex->analyze_stmt)
{
char buff[MYSQL_ERRMSG_SIZE];
- my_snprintf(buff, sizeof(buff), ER_THD(thd, ER_UPDATE_INFO), (ulong) found,
- (ulong) updated,
- (ulong) thd->get_stmt_da()->current_statement_warn_count());
+ if (!table->versioned(VERS_TIMESTAMP))
+ my_snprintf(buff, sizeof(buff), ER_THD(thd, ER_UPDATE_INFO), (ulong) found,
+ (ulong) updated,
+ (ulong) thd->get_stmt_da()->current_statement_warn_count());
+ else
+ my_snprintf(buff, sizeof(buff),
+ ER_THD(thd, ER_UPDATE_INFO_WITH_SYSTEM_VERSIONING),
+ (ulong) found, (ulong) updated, (ulong) updated_sys_ver,
+ (ulong) thd->get_stmt_da()->current_statement_warn_count());
my_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
id, buff);
DBUG_PRINT("info",("%ld records updated", (long) updated));
@@ -1029,7 +1187,6 @@ int mysql_update(THD *thd,
*found_return= found;
*updated_return= updated;
-
if (thd->lex->analyze_stmt)
goto emit_explain_and_leave;
@@ -1040,6 +1197,8 @@ err:
delete file_sort;
free_underlaid_joins(thd, select_lex);
table->file->ha_end_keyread();
+ if (table->file->pushed_cond)
+ table->file->cond_pop();
thd->abort_on_warning= 0;
DBUG_RETURN(1);
@@ -1228,8 +1387,8 @@ bool unsafe_key_update(List<TABLE_LIST> leaves, table_map tables_for_update)
{
// Partitioned key is updated
my_error(ER_MULTI_UPDATE_KEY_CONFLICT, MYF(0),
- tl->top_table()->alias,
- tl2->top_table()->alias);
+ tl->top_table()->alias.str,
+ tl2->top_table()->alias.str);
return true;
}
@@ -1247,8 +1406,8 @@ bool unsafe_key_update(List<TABLE_LIST> leaves, table_map tables_for_update)
{
// Clustered primary key is updated
my_error(ER_MULTI_UPDATE_KEY_CONFLICT, MYF(0),
- tl->top_table()->alias,
- tl2->top_table()->alias);
+ tl->top_table()->alias.str,
+ tl2->top_table()->alias.str);
return true;
}
}
@@ -1397,6 +1556,7 @@ int mysql_multi_update_prepare(THD *thd)
//We need to merge for insert prior to prepare.
if (mysql_handle_derived(lex, DT_MERGE_FOR_INSERT))
DBUG_RETURN(TRUE);
+
if (mysql_handle_derived(lex, DT_PREPARE))
DBUG_RETURN(TRUE);
@@ -1423,7 +1583,7 @@ int mysql_multi_update_prepare(THD *thd)
}
}
- if (update_view && check_fields(thd, *fields))
+ if (check_fields(thd, *fields, update_view))
{
DBUG_RETURN(TRUE);
}
@@ -1450,12 +1610,12 @@ int mysql_multi_update_prepare(THD *thd)
if (!tl->single_table_updatable() || check_key_in_view(thd, tl))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
- tl->top_table()->alias, "UPDATE");
+ tl->top_table()->alias.str, "UPDATE");
DBUG_RETURN(TRUE);
}
DBUG_PRINT("info",("setting table `%s` for update",
- tl->top_table()->alias));
+ tl->top_table()->alias.str));
/*
If table will be updated we should not downgrade lock for it and
leave it as is.
@@ -1463,7 +1623,7 @@ int mysql_multi_update_prepare(THD *thd)
}
else
{
- DBUG_PRINT("info",("setting table `%s` for read-only", tl->alias));
+ DBUG_PRINT("info",("setting table `%s` for read-only", tl->alias.str));
/*
If we are using the binary log, we need TL_READ_NO_INSERT to get
correct order of statements. Otherwise, we use a TL_READ lock to
@@ -1544,7 +1704,7 @@ int mysql_multi_update_prepare(THD *thd)
(SELECT_ACL & ~tlist->grant.privilege);
table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege);
}
- DBUG_PRINT("info", ("table: %s want_privilege: %u", tl->alias,
+ DBUG_PRINT("info", ("table: %s want_privilege: %u", tl->alias.str,
(uint) table->grant.want_privilege));
}
/*
@@ -1622,8 +1782,10 @@ multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list,
tmp_tables(0), updated(0), found(0), fields(field_list),
values(value_list), table_count(0), copy_field(0),
handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1),
- transactional_tables(0), ignore(ignore_arg), error_handled(0), prepared(0)
-{}
+ transactional_tables(0), ignore(ignore_arg), error_handled(0), prepared(0),
+ updated_sys_ver(0)
+{
+}
/*
@@ -1874,7 +2036,7 @@ static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
return !is_key_used(table, table->s->primary_key, table->write_set);
return TRUE;
default:
- break; // Avoid compler warning
+ break; // Avoid compiler warning
}
return FALSE;
@@ -1927,6 +2089,7 @@ multi_update::initialize_tables(JOIN *join)
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
{
table_to_update= table; // Update table on the fly
+ has_vers_fields= check_has_vers_fields(table, *fields);
continue;
}
}
@@ -2036,7 +2199,7 @@ loop_end:
thd->variables.big_tables= FALSE;
tmp_tables[cnt]=create_tmp_table(thd, tmp_param, temp_fields,
(ORDER*) &group, 0, 0,
- TMP_TABLE_ALL_COLUMNS, HA_POS_ERROR, "");
+ TMP_TABLE_ALL_COLUMNS, HA_POS_ERROR, &empty_clex_str);
thd->variables.big_tables= save_big_tables;
if (!tmp_tables[cnt])
DBUG_RETURN(1);
@@ -2099,6 +2262,11 @@ int multi_update::send_data(List<Item> &not_used_values)
if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
continue;
+ if (table->versioned() && !table->vers_end_field()->is_max())
+ {
+ continue;
+ }
+
if (table == table_to_update)
{
/*
@@ -2111,6 +2279,7 @@ int multi_update::send_data(List<Item> &not_used_values)
table->status|= STATUS_UPDATED;
store_record(table,record[1]);
+
if (fill_record_n_invoke_before_triggers(thd, table,
*fields_for_table[offset],
*values_for_table[offset], 0,
@@ -2176,6 +2345,21 @@ int multi_update::send_data(List<Item> &not_used_values)
error= 0;
updated--;
}
+ else if (has_vers_fields && table->versioned())
+ {
+ if (table->versioned(VERS_TIMESTAMP))
+ {
+ store_record(table, record[2]);
+ if (vers_insert_history_row(table))
+ {
+ restore_record(table, record[2]);
+ error= 1;
+ break;
+ }
+ restore_record(table, record[2]);
+ }
+ updated_sys_ver++;
+ }
/* non-transactional or transactional table got modified */
/* either multi_update class' flag is raised in its branch */
if (table->file->has_transactions())
@@ -2202,6 +2386,7 @@ int multi_update::send_data(List<Item> &not_used_values)
*/
uint field_num= 0;
List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
+ /* Set first tbl = table and then tbl to tables from tbl_it */
TABLE *tbl= table;
do
{
@@ -2264,10 +2449,6 @@ void multi_update::abort_result_set()
if (do_update && table_count > 1)
{
/* Add warning here */
- /*
- todo/fixme: do_update() is never called with the arg 1.
- should it change the signature to become argless?
- */
(void) do_updates();
}
}
@@ -2359,6 +2540,8 @@ int multi_update::do_updates()
if (table->vfield)
empty_record(table);
+ has_vers_fields= check_has_vers_fields(table, *fields);
+
check_opt_it.rewind();
while(TABLE *tbl= check_opt_it++)
{
@@ -2469,19 +2652,40 @@ int multi_update::do_updates()
goto err2;
}
}
- if ((local_error=table->file->ha_update_row(table->record[1],
- table->record[0])) &&
+ if (has_vers_fields && table->versioned())
+ table->vers_update_fields();
+
+ if ((local_error=table->file->ha_update_row(table->record[1],
+ table->record[0])) &&
local_error != HA_ERR_RECORD_IS_THE_SAME)
{
if (!ignore ||
table->file->is_fatal_error(local_error, HA_CHECK_ALL))
{
err_table= table;
- goto err;
+ goto err;
}
- }
+ }
if (local_error != HA_ERR_RECORD_IS_THE_SAME)
+ {
updated++;
+
+ if (has_vers_fields && table->versioned())
+ {
+ if (table->versioned(VERS_TIMESTAMP))
+ {
+ store_record(table, record[2]);
+ if ((local_error= vers_insert_history_row(table)))
+ {
+ restore_record(table, record[2]);
+ err_table = table;
+ goto err;
+ }
+ restore_record(table, record[2]);
+ }
+ updated_sys_ver++;
+ }
+ }
else
local_error= 0;
}
@@ -2597,9 +2801,21 @@ bool multi_update::send_eof()
thd->clear_error();
else
errcode= query_error_code(thd, killed_status == NOT_KILLED);
- if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query(), thd->query_length(),
- transactional_tables, FALSE, FALSE, errcode))
+
+ bool force_stmt= false;
+ for (TABLE *table= all_tables->table; table; table= table->next)
+ {
+ if (table->versioned(VERS_TRX_ID))
+ {
+ force_stmt= true;
+ break;
+ }
+ }
+ ScopedStatementReplication scoped_stmt_rpl(force_stmt ? thd : NULL);
+
+ if (thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
+ thd->query_length(), transactional_tables, FALSE,
+ FALSE, errcode))
{
local_error= 1; // Rollback update
}
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index dd8c6b70446..b84dc46cae6 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -171,7 +171,7 @@ err:
void make_valid_column_names(THD *thd, List<Item> &item_list)
{
Item *item;
- uint name_len;
+ size_t name_len;
List_iterator_fast<Item> it(item_list);
char buff[NAME_LEN];
DBUG_ENTER("make_valid_column_names");
@@ -273,13 +273,13 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
checked that we have not more privileges on correspondent column of view
table (i.e. user will not get some privileges by view creation)
*/
- if ((check_access(thd, CREATE_VIEW_ACL, view->db,
+ if ((check_access(thd, CREATE_VIEW_ACL, view->db.str,
&view->grant.privilege,
&view->grant.m_internal,
0, 0) ||
check_grant(thd, CREATE_VIEW_ACL, view, FALSE, 1, FALSE)) ||
(mode != VIEW_CREATE_NEW &&
- (check_access(thd, DROP_ACL, view->db,
+ (check_access(thd, DROP_ACL, view->db.str,
&view->grant.privilege,
&view->grant.m_internal,
0, 0) ||
@@ -298,7 +298,7 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
{
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
"ANY", thd->security_ctx->priv_user,
- thd->security_ctx->priv_host, tbl->table_name);
+ thd->security_ctx->priv_host, tbl->table_name.str);
goto err;
}
/*
@@ -319,8 +319,7 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
tbl->table_name will be correct name of table because VIEWs are
not opened yet.
*/
- fill_effective_table_privileges(thd, &tbl->grant, tbl->db,
- tbl->table_name);
+ fill_effective_table_privileges(thd, &tbl->grant, tbl->db.str, tbl->table_name.str);
}
}
@@ -331,7 +330,7 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
{
if (!tbl->table_in_first_from_clause)
{
- if (check_access(thd, SELECT_ACL, tbl->db,
+ if (check_access(thd, SELECT_ACL, tbl->db.str,
&tbl->grant.privilege,
&tbl->grant.m_internal,
0, 0) ||
@@ -430,14 +429,14 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
lex->link_first_table_back(view, link_to_local);
view->open_type= OT_BASE_ONLY;
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
-
if (check_dependencies_in_with_clauses(lex->with_clauses_list))
{
res= TRUE;
goto err;
}
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
+
/*
ignore lock specs for CREATE statement
*/
@@ -457,9 +456,9 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
view= lex->unlink_first_table(&link_to_local);
- if (check_db_dir_existence(view->db))
+ if (check_db_dir_existence(view->db.str))
{
- my_error(ER_BAD_DB_ERROR, MYF(0), view->db);
+ my_error(ER_BAD_DB_ERROR, MYF(0), view->db.str);
res= TRUE;
goto err;
}
@@ -495,8 +494,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
{
/* is this table view and the same view which we creates now? */
if (tbl->view &&
- strcmp(tbl->view_db.str, view->db) == 0 &&
- strcmp(tbl->view_name.str, view->table_name) == 0)
+ cmp(&tbl->view_db, &view->db) == 0 &&
+ cmp(&tbl->view_name, &view->table_name) == 0)
{
my_error(ER_NO_SUCH_TABLE, MYF(0), tbl->view_db.str, tbl->view_name.str);
res= TRUE;
@@ -516,7 +515,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
if (tbl->table->s->tmp_table != NO_TMP_TABLE && !tbl->view &&
!tbl->schema_table)
{
- my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias);
+ my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias.str);
res= TRUE;
goto err;
}
@@ -545,9 +544,9 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
if (lex->view_list.elements)
{
List_iterator_fast<Item> it(select_lex->item_list);
- List_iterator_fast<LEX_STRING> nm(lex->view_list);
+ List_iterator_fast<LEX_CSTRING> nm(lex->view_list);
Item *item;
- LEX_STRING *name;
+ LEX_CSTRING *name;
if (lex->view_list.elements != select_lex->item_list.elements)
{
@@ -577,8 +576,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
Compare/check grants on view with grants of underlying tables
*/
- fill_effective_table_privileges(thd, &view->grant, view->db,
- view->table_name);
+ fill_effective_table_privileges(thd, &view->grant, view->db.str,
+ view->table_name.str);
/*
Make sure that the current user does not have more column-level privileges
@@ -597,24 +596,32 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
for (sl= select_lex; sl; sl= sl->next_select())
{
- DBUG_ASSERT(view->db); /* Must be set in the parser */
+ DBUG_ASSERT(view->db.str); /* Must be set in the parser */
List_iterator_fast<Item> it(sl->item_list);
Item *item;
while ((item= it++))
{
Item_field *fld= item->field_for_view_update();
- uint priv= (get_column_grant(thd, &view->grant, view->db,
- view->table_name, item->name.str) &
+ uint priv= (get_column_grant(thd, &view->grant, view->db.str,
+ view->table_name.str, item->name.str) &
VIEW_ANY_ACL);
- if (fld && !fld->field->table->s->tmp_table)
+ if (!fld)
+ continue;
+ TABLE_SHARE *s= fld->field->table->s;
+ const LString_i field_name= fld->field->field_name;
+ if (s->tmp_table ||
+ (s->versioned &&
+ (field_name == s->vers_start_field()->field_name ||
+ field_name == s->vers_end_field()->field_name)))
{
+ continue;
+ }
- final_priv&= fld->have_privileges;
+ final_priv&= fld->have_privileges;
- if (~fld->have_privileges & priv)
- report_item= item;
- }
+ if (~fld->have_privileges & priv)
+ report_item= item;
}
}
@@ -623,7 +630,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
"create view", thd->security_ctx->priv_user,
thd->security_ctx->priv_host, report_item->name.str,
- view->table_name);
+ view->table_name.str);
res= TRUE;
goto err;
}
@@ -639,15 +646,16 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
*/
if (!res)
- tdc_remove_table(thd, TDC_RT_REMOVE_ALL, view->db, view->table_name, false);
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, view->db.str, view->table_name.str, false);
if (!res && mysql_bin_log.is_open())
{
- String buff;
- const LEX_STRING command[3]=
- {{ C_STRING_WITH_LEN("CREATE ") },
- { C_STRING_WITH_LEN("ALTER ") },
- { C_STRING_WITH_LEN("CREATE OR REPLACE ") }};
+ StringBuffer<128> buff(thd->variables.character_set_client);
+ DBUG_ASSERT(buff.charset()->mbminlen == 1);
+ const LEX_CSTRING command[3]=
+ {{ STRING_WITH_LEN("CREATE ") },
+ { STRING_WITH_LEN("ALTER ") },
+ { STRING_WITH_LEN("CREATE OR REPLACE ") }};
buff.append(&command[thd->lex->create_view->mode]);
view_store_options(thd, views, &buff);
@@ -658,30 +666,29 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
buff.append(STRING_WITH_LEN("IF NOT EXISTS "));
/* Test if user supplied a db (ie: we did not use thd->db) */
- if (views->db && views->db[0] &&
- (thd->db == NULL || strcmp(views->db, thd->db)))
+ if (views->db.str && views->db.str[0] &&
+ (thd->db.str == NULL || cmp(&views->db, &thd->db)))
{
- append_identifier(thd, &buff, views->db,
- views->db_length);
+ append_identifier(thd, &buff, &views->db);
buff.append('.');
}
- append_identifier(thd, &buff, views->table_name,
- views->table_name_length);
+ append_identifier(thd, &buff, &views->table_name);
if (lex->view_list.elements)
{
- List_iterator_fast<LEX_STRING> names(lex->view_list);
- LEX_STRING *name;
+ List_iterator_fast<LEX_CSTRING> names(lex->view_list);
+ LEX_CSTRING *name;
int i;
for (i= 0; (name= names++); i++)
{
buff.append(i ? ", " : "(");
- append_identifier(thd, &buff, name->str, name->length);
+ append_identifier(thd, &buff, name);
}
buff.append(')');
}
buff.append(STRING_WITH_LEN(" AS "));
- buff.append(&views->source);
+ /* views->source doesn't end with \0 */
+ buff.append(views->source.str, views->source.length);
int errcode= query_error_code(thd, TRUE);
/*
@@ -724,11 +731,11 @@ static void make_view_filename(LEX_CSTRING *dir, char *dir_buff,
{
/* print file name */
dir->length= build_table_filename(dir_buff, dir_buff_len - 1,
- view->db, "", "", 0);
+ view->db.str, "", "", 0);
dir->str= dir_buff;
path->length= build_table_filename(path_buff, path_buff_len - 1,
- view->db, view->table_name, reg_ext, 0);
+ view->db.str, view->table_name.str, reg_ext, 0);
path->str= path_buff;
file->str= path->str + dir->length;
@@ -841,11 +848,12 @@ int mariadb_fix_view(THD *thd, TABLE_LIST *view, bool wrong_checksum,
(uchar*)view, view_parameters))
{
sql_print_error("View '%-.192s'.'%-.192s': algorithm swap error.",
- view->db, view->table_name);
+ view->db.str, view->table_name.str);
DBUG_RETURN(HA_ADMIN_INTERNAL_ERROR);
}
sql_print_information("View %`s.%`s: the version is set to %llu%s%s",
- view->db, view->table_name, view->mariadb_version,
+ view->db.str, view->table_name.str,
+ view->mariadb_version,
(wrong_checksum ? ", checksum corrected" : ""),
(swap_alg ?
((view->algorithm == VIEW_ALGORITHM_MERGE) ?
@@ -1025,19 +1033,19 @@ loop_out:
fn_format(path_buff, file.str, dir.str, "", MY_UNPACK_FILENAME);
path.length= strlen(path_buff);
- if (ha_table_exists(thd, view->db, view->table_name))
+ if (ha_table_exists(thd, &view->db, &view->table_name))
{
if (lex->create_info.if_not_exists())
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_TABLE_EXISTS_ERROR,
ER_THD(thd, ER_TABLE_EXISTS_ERROR),
- view->table_name);
+ view->table_name.str);
DBUG_RETURN(0);
}
else if (mode == VIEW_CREATE_NEW)
{
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias.str);
error= -1;
goto err;
}
@@ -1050,7 +1058,8 @@ loop_out:
if (!parser->ok() || !is_equal(&view_type, parser->type()))
{
- my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW");
+ my_error(ER_WRONG_OBJECT, MYF(0), view->db.str, view->table_name.str,
+ "VIEW");
error= -1;
goto err;
}
@@ -1064,7 +1073,7 @@ loop_out:
{
if (mode == VIEW_ALTER)
{
- my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias);
+ my_error(ER_NO_SUCH_TABLE, MYF(0), view->db.str, view->alias.str);
error= -1;
goto err;
}
@@ -1108,8 +1117,8 @@ loop_out:
!lex->select_lex.master_unit()->is_unit_op() &&
!(lex->select_lex.table_list.first)->next_local &&
find_table_in_global_list(lex->query_tables->next_global,
- lex->query_tables->db,
- lex->query_tables->table_name))
+ &lex->query_tables->db,
+ &lex->query_tables->table_name))
{
view->updatable_view= 0;
}
@@ -1117,7 +1126,7 @@ loop_out:
if (view->with_check != VIEW_CHECK_NONE &&
!view->updatable_view)
{
- my_error(ER_VIEW_NONUPD_CHECK, MYF(0), view->db, view->table_name);
+ my_error(ER_VIEW_NONUPD_CHECK, MYF(0), view->db.str, view->table_name.str);
error= -1;
goto err;
}
@@ -1161,7 +1170,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
bool result, view_is_mergeable;
TABLE_LIST *UNINIT_VAR(view_main_select_tables);
DBUG_ENTER("mysql_make_view");
- DBUG_PRINT("info", ("table: %p (%s)", table, table->table_name));
+ DBUG_PRINT("info", ("table: %p (%s)", table, table->table_name.str));
if (table->required_type == TABLE_TYPE_NORMAL)
{
@@ -1198,8 +1207,6 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
*/
mysql_derived_reinit(thd, NULL, table);
- thd->select_number+= table->view->number_of_selects;
-
DEBUG_SYNC(thd, "after_cached_view_opened");
DBUG_RETURN(0);
}
@@ -1207,7 +1214,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
if (table->index_hints && table->index_hints->elements)
{
my_error(ER_KEY_DOES_NOT_EXITS, MYF(0),
- table->index_hints->head()->key_name.str, table->table_name);
+ table->index_hints->head()->key_name.str, table->table_name.str);
DBUG_RETURN(TRUE);
}
@@ -1216,12 +1223,12 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
precedent;
precedent= precedent->referencing_view)
{
- if (precedent->view_name.length == table->table_name_length &&
- precedent->view_db.length == table->db_length &&
+ if (precedent->view_name.length == table->table_name.length &&
+ precedent->view_db.length == table->db.length &&
my_strcasecmp(system_charset_info,
- precedent->view_name.str, table->table_name) == 0 &&
+ precedent->view_name.str, table->table_name.str) == 0 &&
my_strcasecmp(system_charset_info,
- precedent->view_db.str, table->db) == 0)
+ precedent->view_db.str, table->db.str) == 0)
{
my_error(ER_VIEW_RECURSIVE, MYF(0),
top_view->view_db.str, top_view->view_name.str);
@@ -1265,7 +1272,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
!table->definer.host.length);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_VIEW_FRM_NO_USER, ER_THD(thd, ER_VIEW_FRM_NO_USER),
- table->db, table->table_name);
+ table->db.str, table->table_name.str);
get_default_definer(thd, &table->definer, false);
}
@@ -1295,10 +1302,8 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
Save VIEW parameters, which will be wiped out by derived table
processing
*/
- table->view_db.str= table->db;
- table->view_db.length= table->db_length;
- table->view_name.str= table->table_name;
- table->view_name.length= table->table_name_length;
+ table->view_db= table->db;
+ table->view_name= table->table_name;
/*
We don't invalidate a prepared statement when a view changes,
or when someone creates a temporary table.
@@ -1341,7 +1346,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
bool dbchanged;
Parser_state parser_state;
if (parser_state.init(thd, table->select_stmt.str,
- table->select_stmt.length))
+ (uint)table->select_stmt.length))
goto err;
/*
@@ -1355,7 +1360,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
lex_start(thd);
view_select= &lex->select_lex;
- view_select->select_number= ++thd->select_number;
+ view_select->select_number= ++thd->stmt_lex->current_select_number;
sql_mode_t saved_mode= thd->variables.sql_mode;
/* switch off modes which can prevent normal parsing of VIEW
@@ -1390,9 +1395,6 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
parse_status= parse_sql(thd, & parser_state, table->view_creation_ctx);
- lex->number_of_selects=
- (thd->select_number - view_select->select_number) + 1;
-
/* Restore environment. */
if ((old_lex->sql_command == SQLCOM_SHOW_FIELDS) ||
@@ -1699,7 +1701,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_VIEW_ORDERBY_IGNORED,
ER_THD(thd, ER_VIEW_ORDERBY_IGNORED),
- table->db, table->table_name);
+ table->db.str, table->table_name.str);
}
}
/*
@@ -1802,12 +1804,13 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
{
bool not_exist;
build_table_filename(path, sizeof(path) - 1,
- view->db, view->table_name, reg_ext, 0);
+ view->db.str, view->table_name.str, reg_ext, 0);
if ((not_exist= my_access(path, F_OK)) || !dd_frm_is_view(thd, path))
{
char name[FN_REFLEN];
- my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name);
+ my_snprintf(name, sizeof(name), "%s.%s", view->db.str,
+ view->table_name.str);
if (thd->lex->if_exists())
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
@@ -1826,8 +1829,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
{
if (!wrong_object_name)
{
- wrong_object_db= view->db;
- wrong_object_name= view->table_name;
+ wrong_object_db= view->db.str;
+ wrong_object_name= view->table_name.str;
}
}
continue;
@@ -1841,7 +1844,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
For a view, there is a TABLE_SHARE object.
Remove it from the table definition cache, in case the view was cached.
*/
- tdc_remove_table(thd, TDC_RT_REMOVE_ALL, view->db, view->table_name,
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, view->db.str, view->table_name.str,
FALSE);
query_cache_invalidate3(thd, view, 0);
sp_cache_invalidate();
@@ -1926,19 +1929,19 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
this operation should not have influence on Field::query_id, to avoid
marking as used fields which are not used
*/
- enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
- thd->mark_used_columns= MARK_COLUMNS_NONE;
- DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
+ enum_column_usage saved_column_usage= thd->column_usage;
+ thd->column_usage= COLUMNS_WRITE;
+ DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
for (Field_translator *fld= trans; fld < end_of_trans; fld++)
{
if (!fld->item->fixed && fld->item->fix_fields(thd, &fld->item))
{
- thd->mark_used_columns= save_mark_used_columns;
+ thd->column_usage= saved_column_usage;
DBUG_RETURN(TRUE);
}
}
- thd->mark_used_columns= save_mark_used_columns;
- DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
+ thd->column_usage= saved_column_usage;
+ DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
}
/* Loop over all keys to see if a unique-not-null key is used */
for (;key_info != key_info_end ; key_info++)
@@ -2016,7 +2019,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
RETURN
FALSE OK
- TRUE error (is not sent to cliet)
+ TRUE error (is not sent to client)
*/
bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
@@ -2033,10 +2036,18 @@ bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
{
Item_field *fld;
if ((fld= entry->item->field_for_view_update()))
+ {
+ TABLE_SHARE *s= fld->context->table_list->table->s;
+ LString_i field_name= fld->field_name;
+ if (s->versioned &&
+ (field_name == s->vers_start_field()->field_name ||
+ field_name == s->vers_end_field()->field_name))
+ continue;
list->push_back(fld, thd->mem_root);
+ }
else
{
- my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT");
+ my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias.str, "INSERT");
DBUG_RETURN(TRUE);
}
}
@@ -2044,7 +2055,7 @@ bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
}
/*
- checking view md5 check suum
+ checking view md5 check sum
SINOPSYS
view_checksum()
@@ -2138,8 +2149,8 @@ int view_repair(THD *thd, TABLE_LIST *view, HA_CHECK_OPT *check_opt)
*/
bool
mysql_rename_view(THD *thd,
- const char *new_db,
- const char *new_name,
+ const LEX_CSTRING *new_db,
+ const LEX_CSTRING *new_name,
TABLE_LIST *view)
{
LEX_CSTRING pathstr;
@@ -2150,7 +2161,7 @@ mysql_rename_view(THD *thd,
pathstr.str= (char *) path_buff;
pathstr.length= build_table_filename(path_buff, sizeof(path_buff) - 1,
- view->db, view->table_name,
+ view->db.str, view->table_name.str,
reg_ext, 0);
if ((parser= sql_parse_prepare(&pathstr, thd->mem_root, 1)) &&
@@ -2177,16 +2188,17 @@ mysql_rename_view(THD *thd,
goto err;
/* rename view and it's backups */
- if (rename_in_schema_file(thd, view->db, view->table_name, new_db, new_name))
+ if (rename_in_schema_file(thd, view->db.str, view->table_name.str,
+ new_db->str, new_name->str))
goto err;
dir.str= dir_buff;
dir.length= build_table_filename(dir_buff, sizeof(dir_buff) - 1,
- new_db, "", "", 0);
+ new_db->str, "", "", 0);
pathstr.str= path_buff;
pathstr.length= build_table_filename(path_buff, sizeof(path_buff) - 1,
- new_db, new_name, reg_ext, 0);
+ new_db->str, new_name->str, reg_ext, 0);
file.str= pathstr.str + dir.length;
file.length= pathstr.length - dir.length;
@@ -2195,7 +2207,8 @@ mysql_rename_view(THD *thd,
(uchar*)&view_def, view_parameters))
{
/* restore renamed view in case of error */
- rename_in_schema_file(thd, new_db, new_name, view->db, view->table_name);
+ rename_in_schema_file(thd, new_db->str, new_name->str, view->db.str,
+ view->table_name.str);
goto err;
}
} else
diff --git a/sql/sql_view.h b/sql/sql_view.h
index ff94d2de935..08d79b8e4a5 100644
--- a/sql/sql_view.h
+++ b/sql/sql_view.h
@@ -53,7 +53,7 @@ extern TYPELIB updatable_views_with_limit_typelib;
bool check_duplicate_names(THD *thd, List<Item>& item_list,
bool gen_unique_view_names);
-bool mysql_rename_view(THD *thd, const char *new_db, const char *new_name,
+bool mysql_rename_view(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *new_name,
TABLE_LIST *view);
void make_valid_column_names(THD *thd, List<Item> &item_list);
diff --git a/sql/sql_window.cc b/sql/sql_window.cc
index bf393ab1c4d..db34b77ddcb 100644
--- a/sql/sql_window.cc
+++ b/sql/sql_window.cc
@@ -315,14 +315,7 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
}
List_iterator_fast<Item_window_func> li(win_funcs);
- Item_window_func *win_func_item;
- while ((win_func_item= li++))
- {
- win_func_item->update_used_tables();
- }
-
- li.rewind();
- while ((win_func_item= li++))
+ while (Item_window_func * win_func_item= li++)
{
if (win_func_item->check_result_type_of_order_item())
DBUG_RETURN(1);
diff --git a/sql/sql_window.h b/sql/sql_window.h
index 4cb9c1362f5..392f89e8f03 100644
--- a/sql/sql_window.h
+++ b/sql/sql_window.h
@@ -17,7 +17,6 @@
#ifndef SQL_WINDOW_INCLUDED
#define SQL_WINDOW_INCLUDED
-#include "item.h"
#include "filesort.h"
#include "records.h"
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 6ee99a9b29a..fa9dc2d5c6c 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -68,6 +68,7 @@
#include "sql_lex.h"
#include "sql_sequence.h"
#include "sql_tvc.h"
+#include "vers_utils.h"
/* this is to get the bison compilation windows warnings out */
#ifdef _MSC_VER
@@ -79,7 +80,7 @@ int yylex(void *yylval, void *yythd);
#define yyoverflow(A,B,C,D,E,F) \
{ \
- ulong val= *(F); \
+ size_t val= *(F); \
if (my_yyoverflow((B), (D), &val)) \
{ \
yyerror(thd, (char*) (A)); \
@@ -698,6 +699,18 @@ void LEX::add_key_to_list(LEX_CSTRING *field_name,
alter_info.key_list.push_back(key, mem_root);
}
+bool LEX::add_alter_list(const char *name, Virtual_column_info *expr,
+ bool exists)
+{
+ MEM_ROOT *mem_root= thd->mem_root;
+ Alter_column *ac= new (mem_root) Alter_column(name, expr, exists);
+ if (ac == NULL)
+ return true;
+ alter_info.alter_list.push_back(ac, mem_root);
+ alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
+ return false;
+}
+
void LEX::init_last_field(Column_definition *field,
const LEX_CSTRING *field_name,
const CHARSET_INFO *cs)
@@ -738,6 +751,7 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
MYSQL_YYABORT; \
} while(0)
+
Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
{
Virtual_column_info *v= new (thd->mem_root) Virtual_column_info();
@@ -778,6 +792,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
LEX_CSTRING name;
uint offset;
} sp_cursor_name_and_offset;
+ vers_history_point_t vers_history_point;
/* pointers */
Create_field *create_field;
@@ -857,25 +872,28 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
enum Window_frame::Frame_exclusion frame_exclusion;
enum trigger_order_type trigger_action_order_type;
DDL_options_st object_ddl_options;
+ enum vers_sys_type_t vers_range_unit;
+ enum Column_definition::enum_column_versioning vers_column_versioning;
}
%{
-bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
+bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%}
%pure-parser /* We have threads */
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
- Currently there are 102 shift/reduce conflicts.
+ Currently there are 139 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 102
+%expect 139
/*
Comments for TOKENS.
For each token, please include in the same line a comment that contains
the following tags:
+ SQL-2011-R : Reserved keyword as per SQL-2011
SQL-2011-N : Non Reserved keyword as per SQL-2011
SQL-2003-R : Reserved keyword as per SQL-2003
SQL-2003-N : Non Reserved keyword as per SQL-2003
@@ -1028,6 +1046,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token DEFINER_SYM
%token DELAYED_SYM
%token DELAY_KEY_WRITE_SYM
+%token DELETE_DOMAIN_ID_SYM
%token DELETE_SYM /* SQL-2003-R */
%token DENSE_RANK_SYM
%token DESC /* SQL-2003-N */
@@ -1099,6 +1118,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token FORCE_SYM
%token FOREIGN /* SQL-2003-R */
%token FOR_SYM /* SQL-2003-R */
+%token FOR_SYSTEM_TIME_SYM /* INTERNAL */
%token FORMAT_SYM
%token FOUND_SYM /* SQL-2003-R */
%token FROM
@@ -1128,6 +1148,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token HEX_NUM
%token HEX_STRING
%token HIGH_PRIORITY
+%token HISTORY_SYM /* MYSQL */
%token HOST_SYM
%token HOSTS_SYM
%token HOUR_MICROSECOND_SYM
@@ -1168,6 +1189,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ISOPEN_SYM /* Oracle-N */
%token ISSUER_SYM
%token ITERATE_SYM
+%token INVISIBLE_SYM
%token JOIN_SYM /* SQL-2003-R */
%token JSON_SYM
%token KEYS
@@ -1332,6 +1354,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token PERCENT_RANK_SYM
%token PERCENTILE_CONT_SYM
%token PERCENTILE_DISC_SYM
+%token PERIOD_SYM /* SQL-2011-R */
%token PERSISTENT_SYM
%token PHASE_SYM
%token PLUGINS_SYM
@@ -1498,6 +1521,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SWAPS_SYM
%token SWITCHES_SYM
%token SYSDATE
+%token SYSTEM /* SQL-2011-R */
+%token SYSTEM_TIME_SYM /* SQL-2011-R */
%token TABLES
%token TABLESPACE
%token TABLE_REF_PRIORITY
@@ -1568,6 +1593,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token VARIANCE_SYM
%token VARYING /* SQL-2003-R */
%token VAR_SAMP_SYM
+%token VERSIONING_SYM /* SQL-2011-R */
%token VIA_SYM
%token VIEW_SYM /* SQL-2003-N */
%token VIRTUAL_SYM
@@ -1581,8 +1607,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token WHILE_SYM
%token WITH /* SQL-2003-R */
%token WITHIN
+%token WITHOUT /* SQL-2003-R */
%token WITH_CUBE_SYM /* INTERNAL */
%token WITH_ROLLUP_SYM /* INTERNAL */
+%token WITH_SYSTEM_SYM /* INTERNAL */
%token WORK_SYM /* SQL-2003-N */
%token WRAPPER_SYM
%token WRITE_SYM /* SQL-2003-N */
@@ -1622,11 +1650,15 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident_or_text
IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
opt_component key_cache_name
- sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
- opt_constraint constraint opt_ident
+ sp_opt_label BIN_NUM TEXT_STRING_filesystem ident_or_empty
+ opt_constraint constraint opt_ident ident_table_alias
sp_decl_ident
sp_block_label opt_place opt_db
+%type <lex_str>
+ label_ident
+ sp_label
+
%type <lex_string_with_metadata>
TEXT_STRING
NCHAR_STRING
@@ -1674,7 +1706,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <num>
order_dir lock_option
udf_type opt_local opt_no_write_to_binlog
- opt_temporary all_or_any opt_distinct
+ opt_temporary all_or_any opt_distinct opt_glimit_clause
opt_ignore_leaves fulltext_options union_option
opt_not
select_derived_init transaction_access_mode_types
@@ -1684,9 +1716,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
optional_flush_tables_arguments
opt_time_precision kill_type kill_option int_num
opt_default_time_precision
- case_stmt_body opt_bin_mod
+ case_stmt_body opt_bin_mod opt_for_system_time_clause
opt_if_exists_table_element opt_if_not_exists_table_element
- opt_recursive
+ opt_recursive opt_format_xid
%type <object_ddl_options>
create_or_replace
@@ -1708,7 +1740,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <ulong_num>
ulong_num real_ulong_num merge_insert_types
- ws_nweights
+ ws_nweights opt_versioning_interval_start
ws_level_flag_desc ws_level_flag_reverse ws_level_flags
opt_ws_levels ws_level_list ws_level_list_item ws_level_number
ws_level_range ws_level_list_or_range bool
@@ -1744,6 +1776,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
percentile_function
inverse_distribution_function_def
function_call_keyword
+ function_call_keyword_timestamp
function_call_nonkeyword
function_call_generic
function_call_conflict kill_expr
@@ -1767,6 +1800,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <assignment_lex>
assignment_source_lex
assignment_source_expr
+ for_loop_bound_expr
%type <sp_assignment_lex_list>
cursor_actual_parameters
@@ -1813,7 +1847,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <Lex_length_and_dec> precision opt_precision float_options
-%type <symbol> keyword keyword_sp
+%type <symbol> keyword keyword_sp keyword_alias
keyword_sp_data_type
keyword_sp_not_data_type
@@ -1905,7 +1939,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
view_list_opt view_list view_select
trigger_tail sp_tail sf_tail event_tail
- udf_tail create_function_tail
+ udf_tail create_function_tail create_aggregate_function_tail
install uninstall partition_entry binlog_base64_event
normal_key_options normal_key_opts all_key_opt
spatial_key_options fulltext_key_options normal_key_opt
@@ -1913,12 +1947,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
keep_gcc_happy
key_using_alg
part_column_list
+ period_for_system_time
server_def server_options_list server_option
definer_opt no_definer definer get_diagnostics
parse_vcol_expr vcol_opt_specifier vcol_opt_attribute
vcol_opt_attribute_list vcol_attribute
opt_serial_attribute opt_serial_attribute_list serial_attribute
- explainable_command opt_lock_wait_timeout
+ explainable_command
+ opt_lock_wait_timeout
+ opt_delete_gtid_domain
+ asrow_attribute
END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@@ -1939,10 +1977,14 @@ END_OF_INPUT
%type <num> sp_decl_idents sp_decl_idents_init_vars
%type <num> sp_handler_type sp_hcond_list
+%type <num> start_or_end
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
%type <spblock> sp_decls sp_decl sp_decl_body sp_decl_variable_list
%type <spname> sp_name
%type <spvar> sp_param_name sp_param_name_and_type
+%type <for_loop> sp_for_loop_index_and_bounds
+%type <for_loop_bounds> sp_for_loop_bounds
+%type <num> opt_sp_for_loop_direction
%type <spvar_mode> sp_opt_inout
%type <index_hint> index_hint_type
%type <num> index_hint_clause normal_join inner_join
@@ -1973,7 +2015,6 @@ END_OF_INPUT
%type <frame_exclusion> opt_window_frame_exclusion;
%type <window_frame_bound> window_frame_start window_frame_bound;
-
%type <NONE>
'-' '+' '*' '/' '%' '(' ')'
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
@@ -1986,6 +2027,9 @@ END_OF_INPUT
%type <lex_str_list> opt_with_column_list
+%type <vers_range_unit> opt_history_unit
+%type <vers_history_point> history_point
+%type <vers_column_versioning> with_or_without_system
%%
@@ -2528,8 +2572,8 @@ create:
if (lex->create_info.seq_create_info->check_and_adjust(1))
{
my_error(ER_SEQUENCE_INVALID_DATA, MYF(0),
- lex->select_lex.table_list.first->db,
- lex->select_lex.table_list.first->table_name);
+ lex->select_lex.table_list.first->db.str,
+ lex->select_lex.table_list.first->table_name.str);
MYSQL_YYABORT;
}
@@ -2627,8 +2671,16 @@ create:
event_tail
{ }
| create_or_replace definer FUNCTION_SYM
- { Lex->create_info.set($1); }
- sf_tail
+ {
+ Lex->create_info.set($1);
+ }
+ sf_tail_not_aggregate
+ { }
+ | create_or_replace definer AGGREGATE_SYM FUNCTION_SYM
+ {
+ Lex->create_info.set($1);
+ }
+ sf_tail_aggregate
{ }
| create_or_replace no_definer FUNCTION_SYM
{ Lex->create_info.set($1); }
@@ -2637,9 +2689,8 @@ create:
| create_or_replace no_definer AGGREGATE_SYM FUNCTION_SYM
{
Lex->create_info.set($1);
- Lex->udf.type= UDFTYPE_AGGREGATE;
}
- udf_tail
+ create_aggregate_function_tail
{ }
| create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list
opt_require_clause opt_resource_options
@@ -2666,11 +2717,36 @@ create:
{ }
;
+sf_tail_not_aggregate:
+ sf_tail
+ {
+ if (Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR)
+ {
+ my_yyabort_error((ER_NOT_AGGREGATE_FUNCTION, MYF(0)));
+ }
+ Lex->sphead->set_chistics_agg_type(NOT_AGGREGATE);
+ }
+
+sf_tail_aggregate:
+ sf_tail
+ {
+ if (!(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR))
+ {
+ my_yyabort_error((ER_INVALID_AGGREGATE_FUNCTION, MYF(0)));
+ }
+ Lex->sphead->set_chistics_agg_type(GROUP_AGGREGATE);
+ }
+
create_function_tail:
- sf_tail { }
+ sf_tail_not_aggregate { }
| udf_tail { Lex->udf.type= UDFTYPE_FUNCTION; }
;
+create_aggregate_function_tail:
+ sf_tail_aggregate
+ { }
+ | udf_tail { Lex->udf.type= UDFTYPE_AGGREGATE; }
+ ;
opt_sequence:
/* empty */ { }
| sequence_defs
@@ -2690,59 +2766,80 @@ sequence_def:
| NO_SYM MINVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)
- MYSQL_YYABORT;
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value;
}
| NOMINVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)
- MYSQL_YYABORT;
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value;
}
| MAXVALUE_SYM opt_equal longlong_num
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_max_value)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
Lex->create_info.seq_create_info->max_value= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| NO_SYM MAXVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)
- MYSQL_YYABORT;
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| NOMAXVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)
- MYSQL_YYABORT;
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| START_SYM opt_with longlong_num
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_start)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "START"));
Lex->create_info.seq_create_info->start= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_start;
}
| INCREMENT_SYM opt_by longlong_num
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_increment)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "INCREMENT"));
Lex->create_info.seq_create_info->increment= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_increment;
}
| CACHE_SYM opt_equal longlong_num
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_cache)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CACHE"));
Lex->create_info.seq_create_info->cache= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache;
}
| NOCACHE_SYM
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_cache)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CACHE"));
Lex->create_info.seq_create_info->cache= 0;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache;
}
| CYCLE_SYM
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_cycle)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CYCLE"));
Lex->create_info.seq_create_info->cycle= 1;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle;
}
| NOCYCLE_SYM
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_cycle)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CYCLE"));
Lex->create_info.seq_create_info->cycle= 0;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle;
}
@@ -2753,6 +2850,9 @@ sequence_def:
thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
YYABORT;
}
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_restart)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart;
}
| RESTART_SYM opt_with longlong_num
@@ -2762,6 +2862,9 @@ sequence_def:
thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
YYABORT;
}
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_restart)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART"));
Lex->create_info.seq_create_info->restart= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart | seq_field_used_restart_value;
}
@@ -2987,7 +3090,7 @@ clear_privileges:
lex->columns.empty();
lex->grant= lex->grant_tot_col= 0;
lex->all_privileges= 0;
- lex->select_lex.db= 0;
+ lex->select_lex.db= null_clex_str;
lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
bzero((char *)&(lex->mqh),sizeof(lex->mqh));
@@ -3938,6 +4041,22 @@ assignment_source_expr:
}
;
+for_loop_bound_expr:
+ assignment_source_lex
+ {
+ Lex->sphead->reset_lex(thd, $1);
+ }
+ expr
+ {
+ DBUG_ASSERT($1 == thd->lex);
+ $$= $1;
+ $$->sp_lex_in_use= true;
+ $$->set_item_and_free_list($3, NULL);
+ if ($$->sphead->restore_lex(thd))
+ MYSQL_YYABORT;
+ }
+ ;
+
cursor_actual_parameters:
assignment_source_expr
{
@@ -3984,7 +4103,19 @@ sp_proc_stmt_fetch_head:
;
sp_proc_stmt_fetch:
- sp_proc_stmt_fetch_head sp_fetch_list { }
+ sp_proc_stmt_fetch_head sp_fetch_list { }
+ | FETCH_SYM GROUP_SYM NEXT_SYM ROW_SYM
+ {
+ LEX *lex= Lex;
+ sp_head *sp= lex->sphead;
+ lex->sphead->m_flags|= sp_head::HAS_AGGREGATE_INSTR;
+ sp_instr_agg_cfetch *i=
+ new (thd->mem_root) sp_instr_agg_cfetch(sp->instructions(),
+ lex->spcont);
+ if (i == NULL ||
+ sp->add_instr(i))
+ MYSQL_YYABORT;
+ }
;
sp_proc_stmt_close:
@@ -4237,13 +4368,17 @@ else_clause_opt:
| ELSE sp_proc_stmts1
;
+sp_label:
+ label_ident ':' { $$= $1; }
+ ;
+
sp_opt_label:
/* Empty */ { $$= null_clex_str; }
| label_ident { $$= $1; }
;
sp_block_label:
- label_ident ':'
+ sp_label
{
if (Lex->spcont->block_label_declare(&$1))
MYSQL_YYABORT;
@@ -4297,6 +4432,43 @@ sp_unlabeled_block_not_atomic:
}
;
+/* This adds one shift/reduce conflict */
+opt_sp_for_loop_direction:
+ /* Empty */ { $$= 1; }
+ | REVERSE_SYM { $$= -1; }
+ ;
+
+sp_for_loop_index_and_bounds:
+ ident sp_for_loop_bounds
+ {
+ if (Lex->sp_for_loop_declarations(thd, &$$, &$1, $2))
+ MYSQL_YYABORT;
+ }
+ ;
+
+sp_for_loop_bounds:
+ IN_SYM opt_sp_for_loop_direction for_loop_bound_expr
+ DOT_DOT_SYM for_loop_bound_expr
+ {
+ $$.m_direction= $2;
+ $$.m_index= $3;
+ $$.m_upper_bound= $5;
+ $$.m_implicit_cursor= false;
+ }
+ | IN_SYM opt_sp_for_loop_direction for_loop_bound_expr
+ {
+ $$.m_direction= $2;
+ $$.m_index= $3;
+ $$.m_upper_bound= NULL;
+ $$.m_implicit_cursor= false;
+ }
+ | IN_SYM opt_sp_for_loop_direction '(' sp_cursor_stmt ')'
+ {
+ if (Lex->sp_for_loop_implicit_cursor_statement(thd, &$$, $4))
+ MYSQL_YYABORT;
+ }
+ ;
+
loop_body:
sp_proc_stmts1 END LOOP_SYM
{
@@ -4356,14 +4528,14 @@ pop_sp_loop_label:
;
sp_labeled_control:
- label_ident ':' LOOP_SYM
+ sp_label LOOP_SYM
{
if (Lex->sp_push_loop_label(thd, &$1))
MYSQL_YYABORT;
}
loop_body pop_sp_loop_label
{ }
- | label_ident ':' WHILE_SYM
+ | sp_label WHILE_SYM
{
if (Lex->sp_push_loop_label(thd, &$1))
MYSQL_YYABORT;
@@ -4371,7 +4543,33 @@ sp_labeled_control:
}
while_body pop_sp_loop_label
{ }
- | label_ident ':' REPEAT_SYM
+ | sp_label FOR_SYM
+ {
+ // See "The FOR LOOP statement" comments in sql_lex.cc
+ Lex->sp_block_init(thd); // The outer DECLARE..BEGIN..END block
+ }
+ sp_for_loop_index_and_bounds
+ {
+ if (Lex->sp_push_loop_label(thd, &$1)) // The inner WHILE block
+ MYSQL_YYABORT;
+ if (Lex->sp_for_loop_condition_test(thd, $4))
+ MYSQL_YYABORT;
+ }
+ DO_SYM
+ sp_proc_stmts1
+ END FOR_SYM
+ {
+ if (Lex->sp_for_loop_finalize(thd, $4))
+ MYSQL_YYABORT;
+ }
+ pop_sp_loop_label // The inner WHILE block
+ {
+ Lex_spblock tmp;
+ tmp.curs= MY_TEST($4.m_implicit_cursor);
+ if (Lex->sp_block_finalize(thd, tmp)) // The outer DECLARE..BEGIN..END
+ MYSQL_YYABORT;
+ }
+ | sp_label REPEAT_SYM
{
if (Lex->sp_push_loop_label(thd, &$1))
MYSQL_YYABORT;
@@ -4400,6 +4598,32 @@ sp_unlabeled_control:
{
Lex->sp_pop_loop_empty_label(thd);
}
+ | FOR_SYM
+ {
+ // See "The FOR LOOP statement" comments in sql_lex.cc
+ if (Lex->maybe_start_compound_statement(thd))
+ MYSQL_YYABORT;
+ Lex->sp_block_init(thd); // The outer DECLARE..BEGIN..END block
+ }
+ sp_for_loop_index_and_bounds
+ {
+ if (Lex->sp_push_loop_empty_label(thd)) // The inner WHILE block
+ MYSQL_YYABORT;
+ if (Lex->sp_for_loop_condition_test(thd, $3))
+ MYSQL_YYABORT;
+ }
+ DO_SYM
+ sp_proc_stmts1
+ END FOR_SYM
+ {
+ Lex_spblock tmp;
+ tmp.curs= MY_TEST($3.m_implicit_cursor);
+ if (Lex->sp_for_loop_finalize(thd, $3))
+ MYSQL_YYABORT;
+ Lex->sp_pop_loop_empty_label(thd); // The inner WHILE block
+ if (Lex->sp_block_finalize(thd, tmp)) // The outer DECLARE..BEGIN..END
+ MYSQL_YYABORT;
+ }
| REPEAT_SYM
{
if (Lex->sp_push_loop_empty_label(thd))
@@ -4766,7 +4990,7 @@ size_number:
uint text_shift_number= 0;
longlong prefix_number;
const char *start_ptr= $1.str;
- uint str_len= $1.length;
+ size_t str_len= $1.length;
const char *end_ptr= start_ptr + str_len;
int error;
prefix_number= my_strtoll10(start_ptr, (char**) &end_ptr, &error);
@@ -4832,7 +5056,7 @@ create_like:
opt_create_select:
/* empty */ {}
- | opt_duplicate opt_as create_select_query_expression
+ | opt_duplicate opt_as create_select_query_expression opt_versioning_option
;
create_select_query_expression:
@@ -4933,12 +5157,12 @@ have_partitioning:
partition_entry:
PARTITION_SYM
{
- LEX *lex= Lex;
- if (!lex->part_info)
+ if (!Lex->part_info)
{
thd->parse_error(ER_PARTITION_ENTRY_ERROR);
MYSQL_YYABORT;
}
+ DBUG_ASSERT(Lex->part_info->table);
/*
We enter here when opening the frm file to translate
partition info string into part_info data structure.
@@ -4979,6 +5203,9 @@ part_type_def:
}
| LIST_SYM part_column_list
{ Lex->part_info->part_type= LIST_PARTITION; }
+ | SYSTEM_TIME_SYM
+ { if (Lex->part_info->vers_init_info(thd)) MYSQL_YYABORT; }
+ opt_versioning_rotation
;
opt_linear:
@@ -5186,6 +5413,7 @@ part_definition:
MYSQL_YYABORT;
}
p_elem->part_state= PART_NORMAL;
+ p_elem->id= part_info->partitions.elements - 1;
part_info->curr_part_elem= p_elem;
part_info->current_partition= p_elem;
part_info->use_default_partitions= FALSE;
@@ -5216,12 +5444,12 @@ opt_part_values:
partition_info *part_info= lex->part_info;
if (! lex->is_partition_management())
{
- if (part_info->part_type == RANGE_PARTITION)
- my_yyabort_error((ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "RANGE", "LESS THAN"));
- if (part_info->part_type == LIST_PARTITION)
- my_yyabort_error((ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "LIST", "IN"));
+ if (part_info->error_if_requires_values())
+ MYSQL_YYABORT;
+ if (part_info->part_type == VERSIONING_PARTITION)
+ my_yyabort_error((ER_VERS_WRONG_PARTS, MYF(0),
+ lex->create_last_non_select_table->
+ table_name.str));
}
else
part_info->part_type= HASH_PARTITION;
@@ -5254,6 +5482,63 @@ opt_part_values:
part_info->part_type= LIST_PARTITION;
}
part_values_in {}
+ | CURRENT_SYM
+ {
+ LEX *lex= Lex;
+ partition_info *part_info= lex->part_info;
+ partition_element *elem= part_info->curr_part_elem;
+ if (! lex->is_partition_management())
+ {
+ if (part_info->part_type != VERSIONING_PARTITION)
+ my_yyabort_error((ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"));
+ }
+ else
+ {
+ DBUG_ASSERT(Lex->create_last_non_select_table);
+ DBUG_ASSERT(Lex->create_last_non_select_table->table_name.str);
+ // FIXME: other ALTER commands?
+ my_yyabort_error((ER_VERS_WRONG_PARTS, MYF(0),
+ Lex->create_last_non_select_table->
+ table_name.str));
+ }
+ elem->type(partition_element::CURRENT);
+ DBUG_ASSERT(part_info->vers_info);
+ part_info->vers_info->now_part= elem;
+ if (part_info->init_column_part(thd))
+ {
+ MYSQL_YYABORT;
+ }
+ }
+ | HISTORY_SYM
+ {
+ LEX *lex= Lex;
+ partition_info *part_info= lex->part_info;
+ partition_element *elem= part_info->curr_part_elem;
+ if (! lex->is_partition_management())
+ {
+ if (part_info->part_type != VERSIONING_PARTITION)
+ my_yyabort_error((ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"));
+ }
+ else
+ {
+ part_info->vers_init_info(thd);
+ elem->id= UINT_MAX32;
+ }
+ DBUG_ASSERT(part_info->vers_info);
+ if (part_info->vers_info->now_part)
+ {
+ DBUG_ASSERT(Lex->create_last_non_select_table);
+ DBUG_ASSERT(Lex->create_last_non_select_table->table_name.str);
+ my_yyabort_error((ER_VERS_WRONG_PARTS, MYF(0),
+ Lex->create_last_non_select_table->
+ table_name.str));
+ }
+ elem->type(partition_element::HISTORY);
+ if (part_info->init_column_part(thd))
+ {
+ MYSQL_YYABORT;
+ }
+ }
| DEFAULT
{
LEX *lex= Lex;
@@ -5499,6 +5784,7 @@ sub_part_definition:
mem_alloc_error(sizeof(partition_element));
MYSQL_YYABORT;
}
+ sub_p_elem->id= curr_part->subpartitions.elements - 1;
part_info->curr_part_elem= sub_p_elem;
part_info->use_default_subpartitions= FALSE;
part_info->use_default_num_subpartitions= FALSE;
@@ -5555,6 +5841,51 @@ opt_part_option:
{ Lex->part_info->curr_part_elem->part_comment= $3.str; }
;
+opt_versioning_rotation:
+ /* empty */ {}
+ | INTERVAL_SYM expr interval opt_versioning_interval_start
+ {
+ partition_info *part_info= Lex->part_info;
+ if (part_info->vers_set_interval($2, $3, $4))
+ {
+ my_error(ER_PART_WRONG_VALUE, MYF(0),
+ Lex->create_last_non_select_table->table_name.str,
+ "INTERVAL");
+ MYSQL_YYABORT;
+ }
+ }
+ | LIMIT ulonglong_num
+ {
+ partition_info *part_info= Lex->part_info;
+ if (part_info->vers_set_limit($2))
+ {
+ my_error(ER_PART_WRONG_VALUE, MYF(0),
+ Lex->create_last_non_select_table->table_name.str,
+ "LIMIT");
+ MYSQL_YYABORT;
+ }
+ }
+ ;
+
+ ;
+
+opt_versioning_interval_start:
+ /* empty */
+ {
+ $$= thd->system_time;
+ }
+ | remember_tok_start STARTS_SYM ulong_num
+ {
+ /* only allowed from mysql_unpack_partition() */
+ if (!Lex->part_info->table)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, $1);
+ MYSQL_YYABORT;
+ }
+ $$= (ulong)$3;
+ }
+ ;
+
/*
End of partition parser part
*/
@@ -5921,6 +6252,31 @@ create_table_option:
{
Lex->create_info.used_fields|= HA_CREATE_USED_SEQUENCE;
Lex->create_info.sequence= ($3 == HA_CHOICE_YES);
+ }
+ | versioning_option
+ ;
+
+opt_versioning_option:
+ /* empty */
+ | versioning_option
+ ;
+
+versioning_option:
+ WITH_SYSTEM_SYM VERSIONING_SYM
+ {
+ if (Lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
+ {
+ if (DBUG_EVALUATE_IF("sysvers_force", 0, 1))
+ {
+ my_error(ER_VERS_TEMPORARY, MYF(0));
+ MYSQL_YYABORT;
+ }
+ }
+ else
+ {
+ Lex->alter_info.flags|= Alter_info::ALTER_ADD_SYSTEM_VERSIONING;
+ Lex->create_info.options|= HA_VERSIONED_TABLE;
+ }
}
;
@@ -6021,6 +6377,7 @@ field_list_item:
column_def { }
| key_def
| constraint_def
+ | period_for_system_time
;
column_def:
@@ -6120,6 +6477,15 @@ constraint_def:
}
;
+period_for_system_time:
+ // If FOR_SYM is followed by SYSTEM_TIME_SYM then they are merged to: FOR_SYSTEM_TIME_SYM .
+ PERIOD_SYM FOR_SYSTEM_TIME_SYM '(' ident ',' ident ')'
+ {
+ Vers_parse_info &info= Lex->vers_get_info();
+ info.set_system_time($4, $6);
+ }
+ ;
+
opt_check_constraint:
/* empty */ { $$= (Virtual_column_info*) 0; }
| check_constraint { $$= $1;}
@@ -6205,6 +6571,15 @@ opt_serial_attribute_list:
| serial_attribute
;
+opt_asrow_attribute:
+ /* empty */ {}
+ | opt_asrow_attribute_list {}
+ ;
+
+opt_asrow_attribute_list:
+ opt_asrow_attribute_list asrow_attribute {}
+ | asrow_attribute
+ ;
field_def:
opt_attribute
@@ -6214,6 +6589,46 @@ field_def:
Lex->last_field->flags&= ~NOT_NULL_FLAG; // undo automatic NOT NULL for timestamps
}
vcol_opt_specifier vcol_opt_attribute
+ | opt_generated_always AS ROW_SYM start_or_end opt_asrow_attribute
+ {
+ LEX *lex= Lex;
+ Vers_parse_info &info= lex->vers_get_info();
+ const LEX_CSTRING &field_name= lex->last_field->field_name;
+
+ LString_i *p;
+ switch ($4)
+ {
+ case 1:
+ p= &info.as_row.start;
+ if (*p)
+ {
+ my_yyabort_error((ER_VERS_DUPLICATE_ROW_START_END, MYF(0),
+ "START", field_name.str));
+ }
+ lex->last_field->flags|= VERS_SYS_START_FLAG | NOT_NULL_FLAG;
+ break;
+ case 0:
+ p= &info.as_row.end;
+ if (*p)
+ {
+ my_yyabort_error((ER_VERS_DUPLICATE_ROW_START_END, MYF(0),
+ "END", field_name.str));
+ }
+ lex->last_field->flags|= VERS_SYS_END_FLAG | NOT_NULL_FLAG;
+ break;
+ default:
+ /* Not Reachable */
+ MYSQL_YYABORT;
+ break;
+ }
+ DBUG_ASSERT(p);
+ *p= field_name;
+ }
+ ;
+
+start_or_end:
+ START_SYM { $$ = 1; }
+ | END { $$ = 0; }
;
opt_generated_always:
@@ -6264,6 +6679,10 @@ vcol_attribute:
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
}
| COMMENT_SYM TEXT_STRING_sys { Lex->last_field->comment= $2; }
+ | INVISIBLE_SYM
+ {
+ Lex->last_field->invisible= INVISIBLE_USER;
+ }
;
parse_vcol_expr:
@@ -6648,7 +7067,7 @@ attribute:
}
| AUTO_INC { Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
| SERIAL_SYM DEFAULT VALUE_SYM
- {
+ {
LEX *lex=Lex;
lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_KEY_FLAG;
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
@@ -6673,8 +7092,11 @@ opt_compression_method:
| equal ident { $$= $2.str; }
;
-serial_attribute:
- not NULL_SYM { Lex->last_field->flags|= NOT_NULL_FLAG; }
+asrow_attribute:
+ not NULL_SYM
+ {
+ Lex->last_field->flags|= NOT_NULL_FLAG;
+ }
| opt_primary KEY_SYM
{
LEX *lex=Lex;
@@ -6682,6 +7104,10 @@ serial_attribute:
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
}
| vcol_attribute
+ ;
+
+serial_attribute:
+ asrow_attribute
| IDENT_sys equal TEXT_STRING_sys
{
if ($3.length > ENGINE_OPTION_MAX_LENGTH)
@@ -6709,6 +7135,26 @@ serial_attribute:
new (thd->mem_root)
engine_option_value($1, &Lex->last_field->option_list, &Lex->option_list_last);
}
+ | with_or_without_system VERSIONING_SYM
+ {
+ Lex->last_field->versioning= $1;
+ Lex->create_info.options|= HA_VERSIONED_TABLE;
+ }
+ ;
+
+with_or_without_system:
+ WITH_SYSTEM_SYM
+ {
+ Lex->alter_info.flags|= Alter_info::ALTER_COLUMN_UNVERSIONED;
+ Lex->create_info.vers_info.versioned_fields= true;
+ $$= Column_definition::WITH_VERSIONING;
+ }
+ | WITHOUT SYSTEM
+ {
+ Lex->alter_info.flags|= Alter_info::ALTER_COLUMN_UNVERSIONED;
+ Lex->create_info.vers_info.unversioned_fields= true;
+ $$= Column_definition::WITHOUT_VERSIONING;
+ }
;
@@ -7217,8 +7663,7 @@ alter:
LEX *lex=Lex;
lex->sql_command=SQLCOM_ALTER_DB;
lex->name= $3;
- if (lex->name.str == NULL &&
- lex->copy_db_to(&lex->name.str, &lex->name.length))
+ if (lex->name.str == NULL && lex->copy_db_to(&lex->name))
MYSQL_YYABORT;
}
| ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
@@ -7346,7 +7791,7 @@ alter:
Lex->create_info.set($2);
Lex->sql_command= SQLCOM_ALTER_USER;
}
- | ALTER SEQUENCE_SYM opt_if_exists_table_element
+ | ALTER SEQUENCE_SYM opt_if_exists
{
LEX *lex= Lex;
lex->name= null_clex_str;
@@ -7369,7 +7814,7 @@ alter:
sequence_defs
{
/* Create a generic ALTER SEQUENCE statment. */
- Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence();
+ Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence($3);
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
}
@@ -7521,10 +7966,9 @@ alter_commands:
WITH TABLE_SYM table_ident have_partitioning
{
LEX *lex= thd->lex;
- size_t dummy;
- lex->select_lex.db=$6->db.str;
- if (lex->select_lex.db == NULL &&
- lex->copy_db_to(&lex->select_lex.db, &dummy))
+ lex->select_lex.db= $6->db;
+ if (lex->select_lex.db.str == NULL &&
+ lex->copy_db_to(&lex->select_lex.db))
{
MYSQL_YYABORT;
}
@@ -7667,6 +8111,10 @@ alter_list_item:
Lex->create_last_non_select_table= Lex->last_table();
Lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
}
+ | ADD period_for_system_time
+ {
+ Lex->alter_info.flags|= Alter_info::ALTER_ADD_PERIOD;
+ }
| add_column '(' create_field_list ')'
{
Lex->alter_info.flags|= Alter_info::ALTER_ADD_COLUMN |
@@ -7684,7 +8132,8 @@ alter_list_item:
| CHANGE opt_column opt_if_exists_table_element field_ident
field_spec opt_place
{
- Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
+ Lex->alter_info.flags|= (Alter_info::ALTER_CHANGE_COLUMN |
+ Alter_info::ALTER_RENAME_COLUMN);
Lex->create_last_non_select_table= Lex->last_table();
$5->change= $4;
$5->after= $6;
@@ -7761,32 +8210,22 @@ alter_list_item:
lex->alter_info.keys_onoff= Alter_info::ENABLE;
lex->alter_info.flags|= Alter_info::ALTER_KEYS_ONOFF;
}
- | ALTER opt_column field_ident SET DEFAULT column_default_expr
+ | ALTER opt_column opt_if_exists_table_element field_ident SET DEFAULT column_default_expr
{
- LEX *lex=Lex;
- Alter_column *ac= new (thd->mem_root) Alter_column($3.str,$6);
- if (ac == NULL)
+ if (Lex->add_alter_list($4.str, $7, $3))
MYSQL_YYABORT;
- lex->alter_info.alter_list.push_back(ac, thd->mem_root);
- lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
}
- | ALTER opt_column field_ident DROP DEFAULT
+ | ALTER opt_column opt_if_exists_table_element field_ident DROP DEFAULT
{
- LEX *lex=Lex;
- Alter_column *ac= (new (thd->mem_root)
- Alter_column($3.str, (Virtual_column_info*) 0));
- if (ac == NULL)
+ if (Lex->add_alter_list($4.str, (Virtual_column_info*) 0, $3))
MYSQL_YYABORT;
- lex->alter_info.alter_list.push_back(ac, thd->mem_root);
- lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
}
| RENAME opt_to table_ident
{
LEX *lex=Lex;
- size_t dummy;
- lex->select_lex.db=$3->db.str;
- if (lex->select_lex.db == NULL &&
- lex->copy_db_to(&lex->select_lex.db, &dummy))
+ lex->select_lex.db= $3->db;
+ if (lex->select_lex.db.str == NULL &&
+ lex->copy_db_to(&lex->select_lex.db))
{
MYSQL_YYABORT;
}
@@ -7831,6 +8270,19 @@ alter_list_item:
}
| alter_algorithm_option
| alter_lock_option
+ | ADD SYSTEM VERSIONING_SYM
+ {
+ Lex->alter_info.flags|= Alter_info::ALTER_ADD_SYSTEM_VERSIONING;
+ Lex->create_info.options|= HA_VERSIONED_TABLE;
+ }
+ | DROP SYSTEM VERSIONING_SYM
+ {
+ Lex->alter_info.flags|= Alter_info::ALTER_DROP_SYSTEM_VERSIONING;
+ }
+ | DROP PERIOD_SYM FOR_SYSTEM_TIME_SYM
+ {
+ Lex->alter_info.flags|= Alter_info::ALTER_DROP_PERIOD;
+ }
;
opt_index_lock_algorithm:
@@ -8743,6 +9195,68 @@ select_options:
}
;
+opt_history_unit:
+ /* empty*/
+ {
+ $$= VERS_UNDEFINED;
+ }
+ | TRANSACTION_SYM
+ {
+ $$= VERS_TRX_ID;
+ }
+ | TIMESTAMP
+ {
+ $$= VERS_TIMESTAMP;
+ }
+ ;
+
+history_point:
+ temporal_literal
+ {
+ $$= Vers_history_point(VERS_TIMESTAMP, $1);
+ }
+ | function_call_keyword_timestamp
+ {
+ $$= Vers_history_point(VERS_TIMESTAMP, $1);
+ }
+ | opt_history_unit simple_expr
+ {
+ $$= Vers_history_point($1, $2);
+ }
+ ;
+
+opt_for_system_time_clause:
+ /* empty */
+ {
+ $$= false;
+ }
+ | FOR_SYSTEM_TIME_SYM system_time_expr
+ {
+ $$= true;
+ }
+ ;
+
+system_time_expr:
+ AS OF_SYM history_point
+ {
+ Lex->vers_conditions.init(SYSTEM_TIME_AS_OF, $3);
+ }
+ | ALL
+ {
+ Lex->vers_conditions.init(SYSTEM_TIME_ALL);
+ }
+ | FROM history_point
+ TO_SYM history_point
+ {
+ Lex->vers_conditions.init(SYSTEM_TIME_FROM_TO, $2, $4);
+ }
+ | BETWEEN_SYM history_point
+ AND_SYM history_point
+ {
+ Lex->vers_conditions.init(SYSTEM_TIME_BETWEEN, $2, $4);
+ }
+ ;
+
select_option_list:
select_option_list select_option
| select_option
@@ -9501,6 +10015,7 @@ column_default_non_parenthesized_expr:
$3);
if ($$ == NULL)
MYSQL_YYABORT;
+ Lex->default_used= TRUE;
}
| VALUE_SYM '(' simple_ident_nospvar ')'
{
@@ -9603,6 +10118,21 @@ simple_expr:
}
;
+function_call_keyword_timestamp:
+ TIMESTAMP '(' expr ')'
+ {
+ $$= new (thd->mem_root) Item_datetime_typecast(thd, $3,
+ AUTO_SEC_PART_DIGITS);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | TIMESTAMP '(' expr ',' expr ')'
+ {
+ $$= new (thd->mem_root) Item_func_add_time(thd, $3, $5, 1, 0);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ ;
/*
Function call syntax using official SQL 2003 keywords.
Because the function name is an official token,
@@ -9726,18 +10256,9 @@ function_call_keyword:
if ($$ == NULL)
MYSQL_YYABORT;
}
- | TIMESTAMP '(' expr ')'
- {
- $$= new (thd->mem_root) Item_datetime_typecast(thd, $3,
- AUTO_SEC_PART_DIGITS);
- if ($$ == NULL)
- MYSQL_YYABORT;
- }
- | TIMESTAMP '(' expr ',' expr ')'
+ | function_call_keyword_timestamp
{
- $$= new (thd->mem_root) Item_func_add_time(thd, $3, $5, 1, 0);
- if ($$ == NULL)
- MYSQL_YYABORT;
+ $$= $1;
}
| TRIM '(' expr ')'
{
@@ -10590,16 +11111,22 @@ sum_expr:
| GROUP_CONCAT_SYM '(' opt_distinct
{ Select->in_sum_expr++; }
expr_list opt_gorder_clause
- opt_gconcat_separator
+ opt_gconcat_separator opt_glimit_clause
')'
{
SELECT_LEX *sel= Select;
sel->in_sum_expr--;
$$= new (thd->mem_root)
- Item_func_group_concat(thd, Lex->current_context(), $3, $5,
- sel->gorder_list, $7);
+ Item_func_group_concat(thd, Lex->current_context(),
+ $3, $5,
+ sel->gorder_list, $7, $8,
+ sel->select_limit,
+ sel->offset_limit);
if ($$ == NULL)
MYSQL_YYABORT;
+ sel->select_limit= NULL;
+ sel->offset_limit= NULL;
+ sel->explicit_limit= 0;
$5->empty();
sel->gorder_list.empty();
}
@@ -10889,6 +11416,48 @@ gorder_list:
{ if (add_gorder_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
;
+opt_glimit_clause:
+ /* empty */ { $$ = 0; }
+ | glimit_clause { $$ = 1; }
+ ;
+
+glimit_clause_init:
+ LIMIT{}
+ ;
+
+glimit_clause:
+ glimit_clause_init glimit_options
+ {
+ Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
+ }
+ ;
+
+glimit_options:
+ limit_option
+ {
+ SELECT_LEX *sel= Select;
+ sel->select_limit= $1;
+ sel->offset_limit= 0;
+ sel->explicit_limit= 1;
+ }
+ | limit_option ',' limit_option
+ {
+ SELECT_LEX *sel= Select;
+ sel->select_limit= $3;
+ sel->offset_limit= $1;
+ sel->explicit_limit= 1;
+ }
+ | limit_option OFFSET_SYM limit_option
+ {
+ SELECT_LEX *sel= Select;
+ sel->select_limit= $1;
+ sel->offset_limit= $3;
+ sel->explicit_limit= 1;
+ }
+ ;
+
+
+
in_sum_expr:
opt_all
{
@@ -11214,12 +11783,13 @@ table_factor:
table_primary_ident:
{
+ DBUG_ASSERT(Select);
SELECT_LEX *sel= Select;
sel->table_join_options= 0;
}
- table_ident opt_use_partition opt_table_alias opt_key_definition
+ table_ident opt_use_partition opt_for_system_time_clause opt_table_alias opt_key_definition
{
- if (!($$= Select->add_table_to_list(thd, $2, $4,
+ if (!($$= Select->add_table_to_list(thd, $2, $5,
Select->get_table_join_options(),
YYPS->m_lock_type,
YYPS->m_mdl_type,
@@ -11227,6 +11797,8 @@ table_primary_ident:
$3)))
MYSQL_YYABORT;
Select->add_joined_table($$);
+ if ($4)
+ $$->vers_conditions= Lex->vers_conditions;
}
;
@@ -11249,11 +11821,11 @@ table_primary_ident:
*/
table_primary_derived:
- '(' get_select_lex select_derived_union ')' opt_table_alias
+ '(' get_select_lex select_derived_union ')' opt_for_system_time_clause opt_table_alias
{
/* Use $2 instead of Lex->current_select as derived table will
alter value of Lex->current_select. */
- if (!($3 || $5) && $2->embedding &&
+ if (!($3 || $6) && $2->embedding &&
!$2->embedding->nested_join->join_list.elements)
{
/* we have a derived table ($3 == NULL) but no alias,
@@ -11276,7 +11848,7 @@ table_primary_derived:
if (ti == NULL)
MYSQL_YYABORT;
if (!($$= sel->add_table_to_list(thd,
- ti, $5, 0,
+ ti, $6, 0,
TL_READ, MDL_SHARED_READ)))
MYSQL_YYABORT;
@@ -11284,7 +11856,7 @@ table_primary_derived:
lex->pop_context();
lex->nest_level--;
}
- else if ($5 != NULL)
+ else if ($6 != NULL)
{
/*
Tables with or without joins within parentheses cannot
@@ -11308,11 +11880,16 @@ table_primary_derived:
if ($$ && $$->derived &&
!$$->derived->first_select()->next_select())
$$->select_lex->add_where_field($$->derived->first_select());
+ if ($5)
+ {
+ MYSQL_YYABORT_UNLESS(!$3);
+ $$->vers_conditions= Lex->vers_conditions;
+ }
}
/* Represents derived table with WITH clause */
| '(' get_select_lex subselect_start
with_clause query_expression_body
- subselect_end ')' opt_table_alias
+ subselect_end ')' opt_for_system_time_clause opt_table_alias
{
LEX *lex=Lex;
SELECT_LEX *sel= $2;
@@ -11323,10 +11900,12 @@ table_primary_derived:
$5->set_with_clause($4);
lex->current_select= sel;
if (!($$= sel->add_table_to_list(lex->thd,
- ti, $8, 0,
+ ti, $9, 0,
TL_READ, MDL_SHARED_READ)))
MYSQL_YYABORT;
sel->add_joined_table($$);
+ if ($8)
+ $$->vers_conditions= Lex->vers_conditions;
}
;
@@ -11657,7 +12236,7 @@ table_alias:
opt_table_alias:
/* empty */ { $$=0; }
- | table_alias ident
+ | table_alias ident_table_alias
{
$$= (LEX_CSTRING*) thd->memdup(&$2,sizeof(LEX_STRING));
if ($$ == NULL)
@@ -12434,7 +13013,7 @@ drop:
sp_name *spname;
if (lex->sphead)
my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"));
- if (thd->db && lex->copy_db_to(&db.str, &db.length))
+ if (thd->db.str && lex->copy_db_to(&db))
MYSQL_YYABORT;
lex->set_command(SQLCOM_DROP_FUNCTION, $3);
spname= new (thd->mem_root) sp_name(&db, &$4, false);
@@ -12813,7 +13392,7 @@ update:
{
/* it is single table update and it is update of derived table */
my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
- lex->select_lex.get_table_list()->alias, "UPDATE");
+ lex->select_lex.get_table_list()->alias.str, "UPDATE");
MYSQL_YYABORT;
}
/*
@@ -12873,10 +13452,29 @@ delete:
lex->ignore= 0;
lex->select_lex.init_order();
}
- opt_delete_options single_multi
+ delete_part2
+ ;
+
+opt_delete_system_time:
+ /* empty */
+ {
+ Lex->vers_conditions.init(SYSTEM_TIME_ALL);
+ }
+ | BEFORE_SYM SYSTEM_TIME_SYM history_point
+ {
+ Lex->vers_conditions.init(SYSTEM_TIME_BEFORE, $3);
+ }
+ ;
+
+delete_part2:
+ opt_delete_options single_multi {}
+ | HISTORY_SYM delete_single_table opt_delete_system_time
+ {
+ Lex->last_table()->vers_conditions= Lex->vers_conditions;
+ }
;
-single_multi:
+delete_single_table:
FROM table_ident opt_use_partition
{
if (!Select->add_table_to_list(thd, $2, NULL, TL_OPTION_UPDATING,
@@ -12888,8 +13486,13 @@ single_multi:
YYPS->m_lock_type= TL_READ_DEFAULT;
YYPS->m_mdl_type= MDL_SHARED_READ;
}
- opt_where_clause opt_order_clause
- delete_limit_clause {}
+ ;
+
+single_multi:
+ delete_single_table
+ opt_where_clause
+ opt_order_clause
+ delete_limit_clause
opt_select_expressions {}
| table_wild_list
{
@@ -12971,7 +13574,7 @@ opt_delete_option:
;
truncate:
- TRUNCATE_SYM opt_table_sym
+ TRUNCATE_SYM
{
LEX* lex= Lex;
lex->sql_command= SQLCOM_TRUNCATE;
@@ -12982,7 +13585,7 @@ truncate:
YYPS->m_lock_type= TL_WRITE;
YYPS->m_mdl_type= MDL_EXCLUSIVE;
}
- table_name opt_lock_wait_timeout
+ opt_table_sym table_name opt_lock_wait_timeout
{
LEX* lex= thd->lex;
DBUG_ASSERT(!lex->m_sql_cmd);
@@ -13085,7 +13688,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLES;
- lex->select_lex.db= $3.str;
+ lex->select_lex.db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))
MYSQL_YYABORT;
}
@@ -13093,7 +13696,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TRIGGERS;
- lex->select_lex.db= $3.str;
+ lex->select_lex.db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))
MYSQL_YYABORT;
}
@@ -13101,7 +13704,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_EVENTS;
- lex->select_lex.db= $2.str;
+ lex->select_lex.db= $2;
if (prepare_schema_table(thd, lex, 0, SCH_EVENTS))
MYSQL_YYABORT;
}
@@ -13109,7 +13712,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
- lex->select_lex.db= $3.str;
+ lex->select_lex.db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLES))
MYSQL_YYABORT;
}
@@ -13117,7 +13720,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
- lex->select_lex.db= $3.str;
+ lex->select_lex.db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))
MYSQL_YYABORT;
}
@@ -13277,13 +13880,21 @@ show_param:
Lex->set_command(SQLCOM_SHOW_CREATE_DB, $3);
Lex->name= $4;
}
- | CREATE TABLE_SYM table_ident
+ | CREATE TABLE_SYM table_ident opt_for_system_time_clause
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_SHOW_CREATE;
if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0))
MYSQL_YYABORT;
lex->create_info.storage_media= HA_SM_DEFAULT;
+
+ if (lex->vers_conditions.type != SYSTEM_TIME_UNSPECIFIED &&
+ lex->vers_conditions.type != SYSTEM_TIME_AS_OF)
+ {
+ my_yyabort_error((ER_VERS_RANGE_PROHIBITED, MYF(0)));
+ }
+ if ($4)
+ Lex->last_table()->vers_conditions= Lex->vers_conditions;
}
| CREATE VIEW_SYM table_ident
{
@@ -13395,7 +14006,7 @@ show_param:
LEX *lex= Lex;
bool in_plugin;
lex->sql_command= SQLCOM_SHOW_GENERIC;
- ST_SCHEMA_TABLE *table= find_schema_table(thd, $1.str, &in_plugin);
+ ST_SCHEMA_TABLE *table= find_schema_table(thd, &$1, &in_plugin);
if (!table || !table->old_format || !in_plugin)
{
thd->parse_error(ER_SYNTAX_ERROR, $2);
@@ -13482,7 +14093,7 @@ describe:
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
lex->sql_command= SQLCOM_SHOW_FIELDS;
- lex->select_lex.db= 0;
+ lex->select_lex.db= null_clex_str;
lex->verbose= 0;
if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS))
MYSQL_YYABORT;
@@ -13535,7 +14146,8 @@ opt_format_json:
else if (!my_strcasecmp(system_charset_info, $3.str, "TRADITIONAL"))
DBUG_ASSERT(Lex->explain_json==false);
else
- my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), $3.str));
+ my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), "EXPLAIN",
+ $3.str));
}
;
@@ -13628,7 +14240,7 @@ flush_option:
{ Lex->type|= REFRESH_GENERAL_LOG; }
| SLOW LOGS_SYM
{ Lex->type|= REFRESH_SLOW_LOG; }
- | BINARY LOGS_SYM
+ | BINARY LOGS_SYM opt_delete_gtid_domain
{ Lex->type|= REFRESH_BINARY_LOG; }
| RELAY LOGS_SYM optional_connection_name
{
@@ -13668,14 +14280,14 @@ flush_option:
| IDENT_sys remember_tok_start
{
Lex->type|= REFRESH_GENERIC;
- ST_SCHEMA_TABLE *table= find_schema_table(thd, $1.str);
+ ST_SCHEMA_TABLE *table= find_schema_table(thd, &$1);
if (!table || !table->reset_table)
{
thd->parse_error(ER_SYNTAX_ERROR, $2);
MYSQL_YYABORT;
}
- Lex->view_list.push_back((LEX_STRING*)
- thd->memdup(&$1, sizeof(LEX_STRING)),
+ Lex->view_list.push_back((LEX_CSTRING*)
+ thd->memdup(&$1, sizeof(LEX_CSTRING)),
thd->mem_root);
}
;
@@ -13685,6 +14297,24 @@ opt_table_list:
| table_list {}
;
+opt_delete_gtid_domain:
+ /* empty */ {}
+ | DELETE_DOMAIN_ID_SYM '=' '(' delete_domain_id_list ')'
+ {}
+ ;
+delete_domain_id_list:
+ /* Empty */
+ | delete_domain_id
+ | delete_domain_id_list ',' delete_domain_id
+ ;
+
+delete_domain_id:
+ ulong_num
+ {
+ insert_dynamic(&Lex->delete_gtid_domain, (uchar*) &($1));
+ }
+ ;
+
optional_flush_tables_arguments:
/* empty */ {$$= 0;}
| AND_SYM DISABLE_SYM CHECKPOINT_SYM {$$= REFRESH_CHECKPOINT; }
@@ -13816,7 +14446,7 @@ use:
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_CHANGE_DB;
- lex->select_lex.db= $2.str;
+ lex->select_lex.db= $2;
}
;
@@ -14426,17 +15056,17 @@ field_ident:
| ident '.' ident '.' ident
{
TABLE_LIST *table= Select->table_list.first;
- if (my_strcasecmp(table_alias_charset, $1.str, table->db))
+ if (my_strcasecmp(table_alias_charset, $1.str, table->db.str))
my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $1.str));
if (my_strcasecmp(table_alias_charset, $3.str,
- table->table_name))
+ table->table_name.str))
my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $3.str));
$$=$5;
}
| ident '.' ident
{
TABLE_LIST *table= Select->table_list.first;
- if (my_strcasecmp(table_alias_charset, $1.str, table->alias))
+ if (my_strcasecmp(table_alias_charset, $1.str, table->alias.str))
my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $1.str));
$$=$3;
}
@@ -14497,7 +15127,7 @@ IDENT_sys:
if (thd->charset_is_system_charset)
{
CHARSET_INFO *cs= system_charset_info;
- uint wlen= Well_formed_prefix(cs, $1.str, $1.length).length();
+ size_t wlen= Well_formed_prefix(cs, $1.str, $1.length).length();
if (wlen < $1.length)
{
ErrConvString err($1.str, $1.length, &my_charset_bin);
@@ -14569,6 +15199,16 @@ TEXT_STRING_filesystem:
$$.length= to.length;
}
}
+
+ident_table_alias:
+ IDENT_sys { $$= $1; }
+ | keyword_alias
+ {
+ $$.str= thd->strmake($1.str, $1.length);
+ if ($$.str == NULL)
+ MYSQL_YYABORT;
+ $$.length= $1.length;
+ }
;
ident:
@@ -14683,8 +15323,8 @@ user: user_maybe_role
}
;
-/* Keyword that we allow for identifiers (except SP labels) */
-keyword:
+/* Keywords which we allow as table aliases. */
+keyword_alias:
keyword_sp {}
| keyword_sp_verb_clause{}
| ASCII_SYM {}
@@ -14721,6 +15361,7 @@ keyword:
| OTHERS_SYM {}
| OWNER_SYM {}
| PARSER_SYM {}
+ | PERIOD_SYM {}
| PORT_SYM {}
| PRECEDES_SYM {}
| PRECEDING_SYM {}
@@ -14748,6 +15389,10 @@ keyword:
| UPGRADE_SYM {}
;
+
+/* Keyword that we allow for identifiers (except SP labels) */
+keyword: keyword_alias | WINDOW_SYM {};
+
/*
* Keywords that we allow for labels in SPs.
* Anything that's the beginning of a statement or characteristics
@@ -14922,6 +15567,7 @@ keyword_sp_not_data_type:
| GOTO_SYM {}
| HASH_SYM {}
| HARD_SYM {}
+ | HISTORY_SYM {}
| HOSTS_SYM {}
| HOUR_SYM {}
| ID_SYM {}
@@ -14939,6 +15585,7 @@ keyword_sp_not_data_type:
| ISOPEN_SYM {}
| ISSUER_SYM {}
| INSERT_METHOD {}
+ | INVISIBLE_SYM {}
| KEY_BLOCK_SIZE {}
| LAST_VALUE {}
| LAST_SYM {}
@@ -15099,6 +15746,8 @@ keyword_sp_not_data_type:
| SUSPEND_SYM {}
| SWAPS_SYM {}
| SWITCHES_SYM {}
+ | SYSTEM {}
+ | SYSTEM_TIME_SYM {}
| TABLE_NAME_SYM {}
| TABLES {}
| TABLE_CHECKSUM_SYM {}
@@ -15124,6 +15773,7 @@ keyword_sp_not_data_type:
| USER_SYM {}
| USE_FRM {}
| VARIABLES {}
+ | VERSIONING_SYM {}
| VIEW_SYM {}
| VIRTUAL_SYM {}
| VALUE_SYM {}
@@ -15131,6 +15781,7 @@ keyword_sp_not_data_type:
| WAIT_SYM {}
| WEEK_SYM {}
| WEIGHT_STRING_SYM {}
+ | WITHOUT {}
| WORK_SYM {}
| X509_SYM {}
| XML_SYM {}
@@ -15582,14 +16233,14 @@ opt_lock_wait_timeout:
{}
| WAIT_SYM ulong_num
{
- if (set_statement_var_if_exists(thd, C_STRING_WITH_LEN("lock_wait_timeout"), $2) ||
- set_statement_var_if_exists(thd, C_STRING_WITH_LEN("innodb_lock_wait_timeout"), $2))
+ if (set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), $2) ||
+ set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), $2))
MYSQL_YYABORT;
}
| NOWAIT_SYM
{
- if (set_statement_var_if_exists(thd, C_STRING_WITH_LEN("lock_wait_timeout"), 0) ||
- set_statement_var_if_exists(thd, C_STRING_WITH_LEN("innodb_lock_wait_timeout"), 0))
+ if (set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), 0) ||
+ set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), 0))
MYSQL_YYABORT;
}
;
@@ -15942,6 +16593,7 @@ object_privilege:
| EVENT_SYM { Lex->grant |= EVENT_ACL;}
| TRIGGER_SYM { Lex->grant |= TRIGGER_ACL; }
| CREATE TABLESPACE { Lex->grant |= CREATE_TABLESPACE_ACL; }
+ | DELETE_SYM HISTORY_SYM { Lex->grant |= DELETE_HISTORY_ACL; }
;
opt_and:
@@ -15982,8 +16634,7 @@ grant_ident:
'*'
{
LEX *lex= Lex;
- size_t dummy;
- if (lex->copy_db_to(&lex->current_select->db, &dummy))
+ if (lex->copy_db_to(&lex->current_select->db))
MYSQL_YYABORT;
if (lex->grant == GLOBAL_ACLS)
lex->grant = DB_ACLS & ~GRANT_ACL;
@@ -15993,7 +16644,7 @@ grant_ident:
| ident '.' '*'
{
LEX *lex= Lex;
- lex->current_select->db = $1.str;
+ lex->current_select->db= $1;
if (lex->grant == GLOBAL_ACLS)
lex->grant = DB_ACLS & ~GRANT_ACL;
else if (lex->columns.elements)
@@ -16002,7 +16653,7 @@ grant_ident:
| '*' '.' '*'
{
LEX *lex= Lex;
- lex->current_select->db = NULL;
+ lex->current_select->db= null_clex_str;
if (lex->grant == GLOBAL_ACLS)
lex->grant= GLOBAL_ACLS & ~GRANT_ACL;
else if (lex->columns.elements)
@@ -16620,14 +17271,14 @@ view_list_opt:
view_list:
ident
{
- Lex->view_list.push_back((LEX_STRING*)
- thd->memdup(&$1, sizeof(LEX_STRING)),
+ Lex->view_list.push_back((LEX_CSTRING*)
+ thd->memdup(&$1, sizeof(LEX_CSTRING)),
thd->mem_root);
}
| view_list ',' ident
{
- Lex->view_list.push_back((LEX_STRING*)
- thd->memdup(&$3, sizeof(LEX_STRING)),
+ Lex->view_list.push_back((LEX_CSTRING*)
+ thd->memdup(&$3, sizeof(LEX_CSTRING)),
thd->mem_root);
}
;
@@ -16642,13 +17293,11 @@ view_select:
{
LEX *lex= Lex;
size_t len= YYLIP->get_cpp_ptr() - lex->create_view->select.str;
- uint not_used;
void *create_view_select= thd->memdup(lex->create_view->select.str, len);
lex->create_view->select.length= len;
lex->create_view->select.str= (char *) create_view_select;
trim_whitespace(thd->charset(),
- &lex->create_view->select,
- &not_used);
+ &lex->create_view->select);
lex->create_view->check= $4;
lex->parsing_options.allows_variable= TRUE;
lex->current_select->set_with_clause($2);
@@ -16721,9 +17370,14 @@ trigger_tail:
}
table_ident /* $10 */
FOR_SYM
- remember_name /* $12 */
- { /* $13 */
- Lex->raw_trg_on_table_name_end= YYLIP->get_tok_start();
+ remember_name /* $13 */
+ { /* $14 */
+ /*
+ FOR token is already passed through (see 'case FOR_SYM' in sql_lex.cc),
+ so we use _prev() to get it back.
+ */
+ DBUG_ASSERT(YYLIP->lookahead_token >= 0);
+ Lex->raw_trg_on_table_name_end= YYLIP->get_tok_start_prev();
}
EACH_SYM
ROW_SYM
@@ -16884,9 +17538,27 @@ xa:
{
Lex->sql_command = SQLCOM_XA_ROLLBACK;
}
- | XA_SYM RECOVER_SYM
+ | XA_SYM RECOVER_SYM opt_format_xid
{
Lex->sql_command = SQLCOM_XA_RECOVER;
+ Lex->verbose= $3;
+ }
+ ;
+
+opt_format_xid:
+ /* empty */ { $$= false; }
+ | FORMAT_SYM '=' ident_or_text
+ {
+ if (!my_strcasecmp(system_charset_info, $3.str, "SQL"))
+ $$= true;
+ else if (!my_strcasecmp(system_charset_info, $3.str, "RAW"))
+ $$= false;
+ else
+ {
+ my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0),
+ "XA RECOVER", $3.str));
+ $$= false;
+ }
}
;
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 0c5c0f85f9b..1a2b1630d38 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -78,7 +78,7 @@ int yylex(void *yylval, void *yythd);
#define yyoverflow(A,B,C,D,E,F) \
{ \
- ulong val= *(F); \
+ size_t val= *(F); \
if (my_yyoverflow((B), (D), &val)) \
{ \
yyerror(thd, (char*) (A)); \
@@ -268,7 +268,7 @@ void ORAerror(THD *thd, const char *s)
}
%{
-bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
+bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%}
%pure-parser /* We have threads */
@@ -284,6 +284,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
Comments for TOKENS.
For each token, please include in the same line a comment that contains
the following tags:
+ SQL-2011-R : Reserved keyword as per SQL-2011
SQL-2011-N : Non Reserved keyword as per SQL-2011
SQL-2003-R : Reserved keyword as per SQL-2003
SQL-2003-N : Non Reserved keyword as per SQL-2003
@@ -436,6 +437,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token DEFINER_SYM
%token DELAYED_SYM
%token DELAY_KEY_WRITE_SYM
+%token DELETE_DOMAIN_ID_SYM
%token DELETE_SYM /* SQL-2003-R */
%token DENSE_RANK_SYM
%token DESC /* SQL-2003-N */
@@ -507,6 +509,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token FORCE_SYM
%token FOREIGN /* SQL-2003-R */
%token FOR_SYM /* SQL-2003-R */
+%token FOR_SYSTEM_TIME_SYM /* INTERNAL */
%token FORMAT_SYM
%token FOUND_SYM /* SQL-2003-R */
%token FROM
@@ -536,6 +539,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token HEX_NUM
%token HEX_STRING
%token HIGH_PRIORITY
+%token HISTORY_SYM /* MYSQL */
%token HOST_SYM
%token HOSTS_SYM
%token HOUR_MICROSECOND_SYM
@@ -576,6 +580,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ISOPEN_SYM /* Oracle-N */
%token ISSUER_SYM
%token ITERATE_SYM
+%token INVISIBLE_SYM
%token JOIN_SYM /* SQL-2003-R */
%token JSON_SYM
%token KEYS
@@ -740,6 +745,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token PERCENT_RANK_SYM
%token PERCENTILE_CONT_SYM
%token PERCENTILE_DISC_SYM
+%token PERIOD_SYM /* SQL-2011-R */
%token PERSISTENT_SYM
%token PHASE_SYM
%token PLUGINS_SYM
@@ -906,6 +912,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SWAPS_SYM
%token SWITCHES_SYM
%token SYSDATE
+%token SYSTEM /* SQL-2011-R */
+%token SYSTEM_TIME_SYM /* SQL-2011-R */
%token TABLES
%token TABLESPACE
%token TABLE_REF_PRIORITY
@@ -976,6 +984,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token VARIANCE_SYM
%token VARYING /* SQL-2003-R */
%token VAR_SAMP_SYM
+%token VERSIONING_SYM /* SQL-2011-R */
%token VIA_SYM
%token VIEW_SYM /* SQL-2003-N */
%token VIRTUAL_SYM
@@ -989,8 +998,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token WHILE_SYM
%token WITH /* SQL-2003-R */
%token WITHIN
+%token WITHOUT /* SQL-2003-R */
%token WITH_CUBE_SYM /* INTERNAL */
%token WITH_ROLLUP_SYM /* INTERNAL */
+%token WITH_SYSTEM_SYM /* INTERNAL */
%token WORK_SYM /* SQL-2003-N */
%token WRAPPER_SYM
%token WRITE_SYM /* SQL-2003-N */
@@ -1030,13 +1041,17 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident_or_text
IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
opt_component key_cache_name
- sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
+ sp_opt_label BIN_NUM TEXT_STRING_filesystem ident_or_empty
opt_constraint constraint opt_ident
- label_declaration_oracle labels_declaration_oracle
ident_directly_assignable
sp_decl_ident
sp_block_label opt_place opt_db
+%type <lex_str>
+ label_ident
+ label_declaration_oracle
+ labels_declaration_oracle
+
%type <lex_string_with_metadata>
TEXT_STRING
NCHAR_STRING
@@ -1087,7 +1102,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <num>
order_dir lock_option
udf_type opt_local opt_no_write_to_binlog
- opt_temporary all_or_any opt_distinct
+ opt_temporary all_or_any opt_distinct opt_glimit_clause
opt_ignore_leaves fulltext_options union_option
opt_not
select_derived_init transaction_access_mode_types
@@ -1099,7 +1114,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_default_time_precision
case_stmt_body opt_bin_mod
opt_if_exists_table_element opt_if_not_exists_table_element
- opt_recursive
+ opt_recursive opt_format_xid
%type <object_ddl_options>
create_or_replace
@@ -1964,8 +1979,8 @@ create:
if (lex->create_info.seq_create_info->check_and_adjust(1))
{
my_error(ER_SEQUENCE_INVALID_DATA, MYF(0),
- lex->select_lex.table_list.first->db,
- lex->select_lex.table_list.first->table_name);
+ lex->select_lex.table_list.first->db.str,
+ lex->select_lex.table_list.first->table_name.str);
MYSQL_YYABORT;
}
@@ -2126,59 +2141,80 @@ sequence_def:
| NO_SYM MINVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)
- MYSQL_YYABORT;
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value;
}
| NOMINVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)
- MYSQL_YYABORT;
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value;
}
| MAXVALUE_SYM opt_equal longlong_num
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_max_value)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
Lex->create_info.seq_create_info->max_value= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| NO_SYM MAXVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)
- MYSQL_YYABORT;
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| NOMAXVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)
- MYSQL_YYABORT;
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| START_SYM opt_with longlong_num
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_start)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "START"));
Lex->create_info.seq_create_info->start= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_start;
}
| INCREMENT_SYM opt_by longlong_num
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_increment)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "INCREMENT"));
Lex->create_info.seq_create_info->increment= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_increment;
}
| CACHE_SYM opt_equal longlong_num
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_cache)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CACHE"));
Lex->create_info.seq_create_info->cache= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache;
}
| NOCACHE_SYM
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_cache)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CACHE"));
Lex->create_info.seq_create_info->cache= 0;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache;
}
| CYCLE_SYM
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_cycle)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CYCLE"));
Lex->create_info.seq_create_info->cycle= 1;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle;
}
| NOCYCLE_SYM
{
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_cycle)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CYCLE"));
Lex->create_info.seq_create_info->cycle= 0;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle;
}
@@ -2189,6 +2225,9 @@ sequence_def:
thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
YYABORT;
}
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_restart)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart;
}
| RESTART_SYM opt_with longlong_num
@@ -2198,6 +2237,9 @@ sequence_def:
thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
YYABORT;
}
+ if (Lex->create_info.seq_create_info->used_fields &
+ seq_field_used_restart)
+ my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART"));
Lex->create_info.seq_create_info->restart= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart | seq_field_used_restart_value;
}
@@ -2423,7 +2465,7 @@ clear_privileges:
lex->columns.empty();
lex->grant= lex->grant_tot_col= 0;
lex->all_privileges= 0;
- lex->select_lex.db= 0;
+ lex->select_lex.db= null_clex_str;
lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
bzero((char *)&(lex->mqh),sizeof(lex->mqh));
@@ -4090,25 +4132,8 @@ sp_for_loop_bounds:
}
| IN_SYM opt_sp_for_loop_direction '(' sp_cursor_stmt ')'
{
- Item *item;
- DBUG_ASSERT(Lex->sphead);
- LEX_CSTRING name= {STRING_WITH_LEN("[implicit_cursor]") };
- if (Lex->sp_declare_cursor(thd, &name, $4, NULL, true))
- MYSQL_YYABORT;
- if (!($$.m_index= new (thd->mem_root) sp_assignment_lex(thd, thd->lex)))
+ if (Lex->sp_for_loop_implicit_cursor_statement(thd, &$$, $4))
MYSQL_YYABORT;
- $$.m_index->sp_lex_in_use= true;
- Lex->sphead->reset_lex(thd, $$.m_index);
- if (!(item= new (thd->mem_root) Item_field(thd,
- Lex->current_context(),
- NullS, NullS, &name)))
- MYSQL_YYABORT;
- $$.m_index->set_item_and_free_list(item, NULL);
- if (Lex->sphead->restore_lex(thd))
- MYSQL_YYABORT;
- $$.m_direction= 1;
- $$.m_upper_bound= NULL;
- $$.m_implicit_cursor= true;
}
;
@@ -4633,7 +4658,7 @@ size_number:
uint text_shift_number= 0;
longlong prefix_number;
const char *start_ptr= $1.str;
- uint str_len= $1.length;
+ size_t str_len= $1.length;
const char *end_ptr= start_ptr + str_len;
int error;
prefix_number= my_strtoll10(start_ptr, (char**) &end_ptr, &error);
@@ -6137,6 +6162,10 @@ vcol_attribute:
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
}
| COMMENT_SYM TEXT_STRING_sys { Lex->last_field->comment= $2; }
+ | INVISIBLE_SYM
+ {
+ Lex->last_field->invisible= INVISIBLE_USER;
+ }
;
parse_vcol_expr:
@@ -7189,8 +7218,7 @@ alter:
LEX *lex=Lex;
lex->sql_command=SQLCOM_ALTER_DB;
lex->name= $3;
- if (lex->name.str == NULL &&
- lex->copy_db_to(&lex->name.str, &lex->name.length))
+ if (lex->name.str == NULL && lex->copy_db_to(&lex->name))
MYSQL_YYABORT;
}
| ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
@@ -7318,7 +7346,7 @@ alter:
Lex->create_info.set($2);
Lex->sql_command= SQLCOM_ALTER_USER;
}
- | ALTER SEQUENCE_SYM opt_if_exists_table_element
+ | ALTER SEQUENCE_SYM opt_if_exists
{
LEX *lex= Lex;
lex->name= null_clex_str;
@@ -7341,7 +7369,7 @@ alter:
sequence_defs
{
/* Create a generic ALTER SEQUENCE statment. */
- Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence();
+ Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence($3);
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
}
@@ -7493,10 +7521,9 @@ alter_commands:
WITH TABLE_SYM table_ident have_partitioning
{
LEX *lex= thd->lex;
- size_t dummy;
- lex->select_lex.db=$6->db.str;
- if (lex->select_lex.db == NULL &&
- lex->copy_db_to(&lex->select_lex.db, &dummy))
+ lex->select_lex.db= $6->db;
+ if (lex->select_lex.db.str == NULL &&
+ lex->copy_db_to(&lex->select_lex.db))
{
MYSQL_YYABORT;
}
@@ -7656,7 +7683,8 @@ alter_list_item:
| CHANGE opt_column opt_if_exists_table_element field_ident
field_spec opt_place
{
- Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
+ Lex->alter_info.flags|= (Alter_info::ALTER_CHANGE_COLUMN |
+ Alter_info::ALTER_RENAME_COLUMN);
Lex->create_last_non_select_table= Lex->last_table();
$5->change= $4;
$5->after= $6;
@@ -7733,32 +7761,22 @@ alter_list_item:
lex->alter_info.keys_onoff= Alter_info::ENABLE;
lex->alter_info.flags|= Alter_info::ALTER_KEYS_ONOFF;
}
- | ALTER opt_column field_ident SET DEFAULT column_default_expr
+ | ALTER opt_column opt_if_exists_table_element field_ident SET DEFAULT column_default_expr
{
- LEX *lex=Lex;
- Alter_column *ac= new (thd->mem_root) Alter_column($3.str,$6);
- if (ac == NULL)
+ if (Lex->add_alter_list($4.str, $7, $3))
MYSQL_YYABORT;
- lex->alter_info.alter_list.push_back(ac, thd->mem_root);
- lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
}
- | ALTER opt_column field_ident DROP DEFAULT
+ | ALTER opt_column opt_if_exists_table_element field_ident DROP DEFAULT
{
- LEX *lex=Lex;
- Alter_column *ac= (new (thd->mem_root)
- Alter_column($3.str, (Virtual_column_info*) 0));
- if (ac == NULL)
+ if (Lex->add_alter_list($4.str, (Virtual_column_info*) 0, $3))
MYSQL_YYABORT;
- lex->alter_info.alter_list.push_back(ac, thd->mem_root);
- lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
}
| RENAME opt_to table_ident
{
LEX *lex=Lex;
- size_t dummy;
- lex->select_lex.db=$3->db.str;
- if (lex->select_lex.db == NULL &&
- lex->copy_db_to(&lex->select_lex.db, &dummy))
+ lex->select_lex.db= $3->db;
+ if (lex->select_lex.db.str == NULL &&
+ lex->copy_db_to(&lex->select_lex.db))
{
MYSQL_YYABORT;
}
@@ -9507,6 +9525,7 @@ column_default_non_parenthesized_expr:
$3);
if ($$ == NULL)
MYSQL_YYABORT;
+ Lex->default_used= TRUE;
}
| VALUE_SYM '(' simple_ident_nospvar ')'
{
@@ -10583,16 +10602,22 @@ sum_expr:
| GROUP_CONCAT_SYM '(' opt_distinct
{ Select->in_sum_expr++; }
expr_list opt_gorder_clause
- opt_gconcat_separator
+ opt_gconcat_separator opt_glimit_clause
')'
{
SELECT_LEX *sel= Select;
sel->in_sum_expr--;
$$= new (thd->mem_root)
- Item_func_group_concat(thd, Lex->current_context(), $3, $5,
- sel->gorder_list, $7);
+ Item_func_group_concat(thd, Lex->current_context(),
+ $3, $5,
+ sel->gorder_list, $7, $8,
+ sel->select_limit,
+ sel->offset_limit);
if ($$ == NULL)
MYSQL_YYABORT;
+ sel->select_limit= NULL;
+ sel->offset_limit= NULL;
+ sel->explicit_limit= 0;
$5->empty();
sel->gorder_list.empty();
}
@@ -10878,6 +10903,46 @@ gorder_list:
{ if (add_gorder_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
;
+opt_glimit_clause:
+ /* empty */ { $$ = 0; }
+ | glimit_clause { $$ = 1; }
+ ;
+
+glimit_clause_init:
+ LIMIT{}
+ ;
+
+glimit_clause:
+ glimit_clause_init glimit_options
+ {
+ Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
+ }
+ ;
+
+glimit_options:
+ limit_option
+ {
+ SELECT_LEX *sel= Select;
+ sel->select_limit= $1;
+ sel->offset_limit= 0;
+ sel->explicit_limit= 1;
+ }
+ | limit_option ',' limit_option
+ {
+ SELECT_LEX *sel= Select;
+ sel->select_limit= $3;
+ sel->offset_limit= $1;
+ sel->explicit_limit= 1;
+ }
+ | limit_option OFFSET_SYM limit_option
+ {
+ SELECT_LEX *sel= Select;
+ sel->select_limit= $1;
+ sel->offset_limit= $3;
+ sel->explicit_limit= 1;
+ }
+ ;
+
in_sum_expr:
opt_all
{
@@ -12410,7 +12475,7 @@ drop:
sp_name *spname;
if (lex->sphead)
my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"));
- if (thd->db && lex->copy_db_to(&db.str, &db.length))
+ if (thd->db.str && lex->copy_db_to(&db))
MYSQL_YYABORT;
lex->set_command(SQLCOM_DROP_FUNCTION, $3);
spname= new (thd->mem_root) sp_name(&db, &$4, false);
@@ -12789,7 +12854,7 @@ update:
{
/* it is single table update and it is update of derived table */
my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
- lex->select_lex.get_table_list()->alias, "UPDATE");
+ lex->select_lex.get_table_list()->alias.str, "UPDATE");
MYSQL_YYABORT;
}
/*
@@ -13068,7 +13133,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLES;
- lex->select_lex.db= $3.str;
+ lex->select_lex.db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))
MYSQL_YYABORT;
}
@@ -13076,7 +13141,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TRIGGERS;
- lex->select_lex.db= $3.str;
+ lex->select_lex.db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))
MYSQL_YYABORT;
}
@@ -13084,7 +13149,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_EVENTS;
- lex->select_lex.db= $2.str;
+ lex->select_lex.db= $2;
if (prepare_schema_table(thd, lex, 0, SCH_EVENTS))
MYSQL_YYABORT;
}
@@ -13092,7 +13157,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
- lex->select_lex.db= $3.str;
+ lex->select_lex.db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLES))
MYSQL_YYABORT;
}
@@ -13100,7 +13165,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
- lex->select_lex.db= $3.str;
+ lex->select_lex.db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))
MYSQL_YYABORT;
}
@@ -13378,7 +13443,7 @@ show_param:
LEX *lex= Lex;
bool in_plugin;
lex->sql_command= SQLCOM_SHOW_GENERIC;
- ST_SCHEMA_TABLE *table= find_schema_table(thd, $1.str, &in_plugin);
+ ST_SCHEMA_TABLE *table= find_schema_table(thd, &$1, &in_plugin);
if (!table || !table->old_format || !in_plugin)
{
thd->parse_error(ER_SYNTAX_ERROR, $2);
@@ -13465,7 +13530,7 @@ describe:
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
lex->sql_command= SQLCOM_SHOW_FIELDS;
- lex->select_lex.db= 0;
+ lex->select_lex.db= null_clex_str;
lex->verbose= 0;
if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS))
MYSQL_YYABORT;
@@ -13518,7 +13583,8 @@ opt_format_json:
else if (!my_strcasecmp(system_charset_info, $3.str, "TRADITIONAL"))
DBUG_ASSERT(Lex->explain_json==false);
else
- my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), $3.str));
+ my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), "EXPLAIN",
+ $3.str));
}
;
@@ -13651,14 +13717,14 @@ flush_option:
| IDENT_sys remember_tok_start
{
Lex->type|= REFRESH_GENERIC;
- ST_SCHEMA_TABLE *table= find_schema_table(thd, $1.str);
+ ST_SCHEMA_TABLE *table= find_schema_table(thd, &$1);
if (!table || !table->reset_table)
{
thd->parse_error(ER_SYNTAX_ERROR, $2);
MYSQL_YYABORT;
}
- Lex->view_list.push_back((LEX_STRING*)
- thd->memdup(&$1, sizeof(LEX_STRING)),
+ Lex->view_list.push_back((LEX_CSTRING*)
+ thd->memdup(&$1, sizeof(LEX_CSTRING)),
thd->mem_root);
}
;
@@ -13799,7 +13865,7 @@ use:
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_CHANGE_DB;
- lex->select_lex.db= $2.str;
+ lex->select_lex.db= $2;
}
;
@@ -14438,17 +14504,17 @@ field_ident:
| ident '.' ident '.' ident
{
TABLE_LIST *table= Select->table_list.first;
- if (my_strcasecmp(table_alias_charset, $1.str, table->db))
+ if (my_strcasecmp(table_alias_charset, $1.str, table->db.str))
my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $1.str));
if (my_strcasecmp(table_alias_charset, $3.str,
- table->table_name))
+ table->table_name.str))
my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $3.str));
$$=$5;
}
| ident '.' ident
{
TABLE_LIST *table= Select->table_list.first;
- if (my_strcasecmp(table_alias_charset, $1.str, table->alias))
+ if (my_strcasecmp(table_alias_charset, $1.str, table->alias.str))
my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $1.str));
$$=$3;
}
@@ -14509,7 +14575,7 @@ IDENT_sys:
if (thd->charset_is_system_charset)
{
CHARSET_INFO *cs= system_charset_info;
- uint wlen= Well_formed_prefix(cs, $1.str, $1.length).length();
+ size_t wlen= Well_formed_prefix(cs, $1.str, $1.length).length();
if (wlen < $1.length)
{
ErrConvString err($1.str, $1.length, &my_charset_bin);
@@ -15012,6 +15078,7 @@ keyword_sp_not_data_type:
| GLOBAL_SYM {}
| HASH_SYM {}
| HARD_SYM {}
+ | INVISIBLE_SYM {}
| HOSTS_SYM {}
| HOUR_SYM {}
| ID_SYM {}
@@ -15725,14 +15792,14 @@ opt_lock_wait_timeout:
{}
| WAIT_SYM ulong_num
{
- if (set_statement_var_if_exists(thd, C_STRING_WITH_LEN("lock_wait_timeout"), $2) ||
- set_statement_var_if_exists(thd, C_STRING_WITH_LEN("innodb_lock_wait_timeout"), $2))
+ if (set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), $2) ||
+ set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), $2))
MYSQL_YYABORT;
}
| NOWAIT_SYM
{
- if (set_statement_var_if_exists(thd, C_STRING_WITH_LEN("lock_wait_timeout"), 0) ||
- set_statement_var_if_exists(thd, C_STRING_WITH_LEN("innodb_lock_wait_timeout"), 0))
+ if (set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), 0) ||
+ set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), 0))
MYSQL_YYABORT;
}
;
@@ -16125,8 +16192,7 @@ grant_ident:
'*'
{
LEX *lex= Lex;
- size_t dummy;
- if (lex->copy_db_to(&lex->current_select->db, &dummy))
+ if (lex->copy_db_to(&lex->current_select->db))
MYSQL_YYABORT;
if (lex->grant == GLOBAL_ACLS)
lex->grant = DB_ACLS & ~GRANT_ACL;
@@ -16136,7 +16202,7 @@ grant_ident:
| ident '.' '*'
{
LEX *lex= Lex;
- lex->current_select->db = $1.str;
+ lex->current_select->db= $1;
if (lex->grant == GLOBAL_ACLS)
lex->grant = DB_ACLS & ~GRANT_ACL;
else if (lex->columns.elements)
@@ -16145,7 +16211,7 @@ grant_ident:
| '*' '.' '*'
{
LEX *lex= Lex;
- lex->current_select->db = NULL;
+ lex->current_select->db= null_clex_str;
if (lex->grant == GLOBAL_ACLS)
lex->grant= GLOBAL_ACLS & ~GRANT_ACL;
else if (lex->columns.elements)
@@ -16729,14 +16795,14 @@ view_list_opt:
view_list:
ident
{
- Lex->view_list.push_back((LEX_STRING*)
- thd->memdup(&$1, sizeof(LEX_STRING)),
+ Lex->view_list.push_back((LEX_CSTRING*)
+ thd->memdup(&$1, sizeof(LEX_CSTRING)),
thd->mem_root);
}
| view_list ',' ident
{
- Lex->view_list.push_back((LEX_STRING*)
- thd->memdup(&$3, sizeof(LEX_STRING)),
+ Lex->view_list.push_back((LEX_CSTRING*)
+ thd->memdup(&$3, sizeof(LEX_CSTRING)),
thd->mem_root);
}
;
@@ -16751,13 +16817,11 @@ view_select:
{
LEX *lex= Lex;
size_t len= YYLIP->get_cpp_ptr() - lex->create_view->select.str;
- uint not_used;
void *create_view_select= thd->memdup(lex->create_view->select.str, len);
lex->create_view->select.length= len;
lex->create_view->select.str= (char *) create_view_select;
trim_whitespace(thd->charset(),
- &lex->create_view->select,
- &not_used);
+ &lex->create_view->select);
lex->create_view->check= $4;
lex->parsing_options.allows_variable= TRUE;
lex->current_select->set_with_clause($2);
@@ -17019,12 +17083,29 @@ xa:
{
Lex->sql_command = SQLCOM_XA_ROLLBACK;
}
- | XA_SYM RECOVER_SYM
+ | XA_SYM RECOVER_SYM opt_format_xid
{
Lex->sql_command = SQLCOM_XA_RECOVER;
+ Lex->verbose= $3;
}
;
+opt_format_xid:
+ /* empty */ { $$= false; }
+ | FORMAT_SYM '=' ident_or_text
+ {
+ if (!my_strcasecmp(system_charset_info, $3.str, "SQL"))
+ $$= true;
+ else if (!my_strcasecmp(system_charset_info, $3.str, "RAW"))
+ $$= false;
+ else
+ {
+ my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), "XA RECOVER", $3.str));
+ $$= false;
+ }
+ }
+ ;
+
xid:
text_string
{
diff --git a/sql/strfunc.cc b/sql/strfunc.cc
index 45a0f8f6558..f701c4a09ed 100644
--- a/sql/strfunc.cc
+++ b/sql/strfunc.cc
@@ -45,7 +45,7 @@
static const char field_separator=',';
-ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
+ulonglong find_set(TYPELIB *lib, const char *str, size_t length, CHARSET_INFO *cs,
char **err_pos, uint *err_len, bool *set_warning)
{
CHARSET_INFO *strip= cs ? cs : &my_charset_latin1;
@@ -111,7 +111,7 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
> 0 position in TYPELIB->type_names +1
*/
-uint find_type(const TYPELIB *lib, const char *find, uint length,
+uint find_type(const TYPELIB *lib, const char *find, size_t length,
bool part_match)
{
uint found_count=0, found_pos=0;
@@ -152,13 +152,13 @@ uint find_type(const TYPELIB *lib, const char *find, uint length,
>0 Offset+1 in typelib for matched string
*/
-uint find_type2(const TYPELIB *typelib, const char *x, uint length,
+uint find_type2(const TYPELIB *typelib, const char *x, size_t length,
CHARSET_INFO *cs)
{
int pos;
const char *j;
DBUG_ENTER("find_type2");
- DBUG_PRINT("enter",("x: '%.*s' lib: %p", length, x, typelib));
+ DBUG_PRINT("enter",("x: '%.*s' lib: %p", (int)length, x, typelib));
if (!typelib->count)
{
@@ -265,8 +265,8 @@ uint check_word(TYPELIB *lib, const char *val, const char *end,
*/
-uint strconvert(CHARSET_INFO *from_cs, const char *from, uint from_length,
- CHARSET_INFO *to_cs, char *to, uint to_length, uint *errors)
+uint strconvert(CHARSET_INFO *from_cs, const char *from, size_t from_length,
+ CHARSET_INFO *to_cs, char *to, size_t to_length, uint *errors)
{
int cnvres;
my_wc_t wc;
diff --git a/sql/strfunc.h b/sql/strfunc.h
index 1aba0bff422..1bf3cbf47b3 100644
--- a/sql/strfunc.h
+++ b/sql/strfunc.h
@@ -18,15 +18,15 @@
typedef struct st_typelib TYPELIB;
-ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
+ulonglong find_set(TYPELIB *lib, const char *x, size_t length, CHARSET_INFO *cs,
char **err_pos, uint *err_len, bool *set_warning);
ulonglong find_set_from_flags(TYPELIB *lib, uint default_name,
ulonglong cur_set, ulonglong default_set,
const char *str, uint length, CHARSET_INFO *cs,
char **err_pos, uint *err_len, bool *set_warning);
-uint find_type(const TYPELIB *lib, const char *find, uint length,
+uint find_type(const TYPELIB *lib, const char *find, size_t length,
bool part_match);
-uint find_type2(const TYPELIB *lib, const char *find, uint length,
+uint find_type2(const TYPELIB *lib, const char *find, size_t length,
CHARSET_INFO *cs);
void unhex_type2(TYPELIB *lib);
uint check_word(TYPELIB *lib, const char *val, const char *end,
@@ -42,7 +42,7 @@ const char *set_to_string(THD *thd, LEX_CSTRING *result, ulonglong set,
/*
These functions were protected by INNODB_COMPATIBILITY_HOOKS
*/
-uint strconvert(CHARSET_INFO *from_cs, const char *from, uint from_length,
- CHARSET_INFO *to_cs, char *to, uint to_length, uint *errors);
+uint strconvert(CHARSET_INFO *from_cs, const char *from, size_t from_length,
+ CHARSET_INFO *to_cs, char *to, size_t to_length, uint *errors);
#endif /* STRFUNC_INCLUDED */
diff --git a/sql/structs.h b/sql/structs.h
index 793be462b26..4d05a2433cc 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -39,7 +39,7 @@ typedef struct st_date_time_format {
uchar positions[8];
char time_separator; /* Separator between hour and minute */
uint flag; /* For future */
- LEX_STRING format;
+ LEX_CSTRING format;
} DATE_TIME_FORMAT;
@@ -330,7 +330,7 @@ typedef struct st_user_stats
typedef struct st_table_stats
{
char table[NAME_LEN * 2 + 2]; // [db] + '\0' + [table] + '\0'
- uint table_name_length;
+ size_t table_name_length;
ulonglong rows_read, rows_changed;
ulonglong rows_changed_x_indexes;
/* Stores enum db_type, but forward declarations cannot be done */
@@ -341,7 +341,7 @@ typedef struct st_index_stats
{
// [db] + '\0' + [table] + '\0' + [index] + '\0'
char index[NAME_LEN * 3 + 3];
- uint index_name_length; /* Length of 'index' */
+ size_t index_name_length; /* Length of 'index' */
ulonglong rows_read;
} INDEX_STATS;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 80f05ef02d4..ce2d41f009b 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -35,6 +35,7 @@
#include "sql_priv.h"
#include "sql_class.h" // set_var.h: THD
#include "sys_vars.ic"
+#include "my_sys.h"
#include "events.h"
#include <thr_alarm.h>
@@ -61,6 +62,8 @@
#include "sql_repl.h"
#include "opt_range.h"
#include "rpl_parallel.h"
+#include "semisync_master.h"
+#include "semisync_slave.h"
#include <ssl_compat.h>
/*
@@ -387,6 +390,22 @@ static Sys_var_charptr Sys_my_bind_addr(
READ_ONLY GLOBAL_VAR(my_bind_addr_str), CMD_LINE(REQUIRED_ARG),
IN_FS_CHARSET, DEFAULT(0));
+const char *Sys_var_vers_asof::asof_keywords[]= {"DEFAULT", NULL};
+static Sys_var_vers_asof Sys_vers_asof_timestamp(
+ "system_versioning_asof", "Default value for the FOR SYSTEM_TIME AS OF clause",
+ SESSION_VAR(vers_asof_timestamp.type), NO_CMD_LINE,
+ Sys_var_vers_asof::asof_keywords, DEFAULT(SYSTEM_TIME_UNSPECIFIED));
+
+static const char *vers_alter_history_keywords[]= {"ERROR", "KEEP",/* "SURVIVE", "DROP",*/ NULL};
+static Sys_var_enum Sys_vers_alter_history(
+ "system_versioning_alter_history", "Versioning ALTER TABLE mode. "
+ "ERROR: Fail ALTER with error; " /* TODO: fail only when history non-empty */
+ "KEEP: Keep historical system rows and subject them to ALTER; "
+ /*"SURVIVE: Keep historical system rows intact; "
+ "DROP: Drop historical system rows while processing ALTER"*/,
+ SESSION_VAR(vers_alter_history), CMD_LINE(REQUIRED_ARG),
+ vers_alter_history_keywords, DEFAULT(VERS_ALTER_HISTORY_ERROR));
+
static Sys_var_ulonglong Sys_binlog_cache_size(
"binlog_cache_size", "The size of the transactional cache for "
"updates to transactional engines for the binary log. "
@@ -573,8 +592,7 @@ static Sys_var_mybool Sys_explicit_defaults_for_timestamp(
"explicit_defaults_for_timestamp",
"This option causes CREATE TABLE to create all TIMESTAMP columns "
"as NULL with DEFAULT NULL attribute, Without this option, "
- "TIMESTAMP columns are NOT NULL and have implicit DEFAULT clauses. "
- "The old behavior is deprecated.",
+ "TIMESTAMP columns are NOT NULL and have implicit DEFAULT clauses.",
READ_ONLY GLOBAL_VAR(opt_explicit_defaults_for_timestamp),
CMD_LINE(OPT_ARG), DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG);
@@ -2455,7 +2473,7 @@ export const char *optimizer_switch_names[]=
"exists_to_in",
"orderby_uses_equalities",
"condition_pushdown_for_derived",
- "split_grouping_derived",
+ "split_materialized",
"default",
NullS
};
@@ -2795,7 +2813,7 @@ static Sys_var_enum Sys_thread_handling(
#ifdef HAVE_QUERY_CACHE
static bool fix_query_cache_size(sys_var *self, THD *thd, enum_var_type type)
{
- ulong new_cache_size= query_cache.resize((ulong)query_cache_size);
+ size_t new_cache_size= query_cache.resize((size_t)query_cache_size);
/*
Note: query_cache_size is a global variable reflecting the
requested cache size. See also query_cache_size_arg
@@ -2803,7 +2821,7 @@ static bool fix_query_cache_size(sys_var *self, THD *thd, enum_var_type type)
if (query_cache_size != new_cache_size)
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_QC_RESIZE, ER_THD(thd, ER_WARN_QC_RESIZE),
- query_cache_size, new_cache_size);
+ query_cache_size, (ulong)new_cache_size);
query_cache_size= new_cache_size;
@@ -2834,7 +2852,7 @@ static Sys_var_ulong Sys_query_cache_limit(
static bool fix_qcache_min_res_unit(sys_var *self, THD *thd, enum_var_type type)
{
query_cache_min_res_unit=
- query_cache.set_min_res_unit(query_cache_min_res_unit);
+ (ulong)query_cache.set_min_res_unit(query_cache_min_res_unit);
return false;
}
static Sys_var_ulong Sys_query_cache_min_res_unit(
@@ -3040,8 +3058,174 @@ static Sys_var_replicate_events_marked_for_skip Replicate_events_marked_for_skip
"the slave).",
GLOBAL_VAR(opt_replicate_events_marked_for_skip), CMD_LINE(REQUIRED_ARG),
replicate_events_marked_for_skip_names, DEFAULT(RPL_SKIP_REPLICATE));
-#endif
+/* new options for semisync */
+
+static bool fix_rpl_semi_sync_master_enabled(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ if (rpl_semi_sync_master_enabled)
+ {
+ if (repl_semisync_master.enable_master() != 0)
+ rpl_semi_sync_master_enabled= false;
+ else if (ack_receiver.start())
+ {
+ repl_semisync_master.disable_master();
+ rpl_semi_sync_master_enabled= false;
+ }
+ }
+ else
+ {
+ if (repl_semisync_master.disable_master() != 0)
+ rpl_semi_sync_master_enabled= true;
+ if (!rpl_semi_sync_master_enabled)
+ ack_receiver.stop();
+ }
+ return false;
+}
+
+static bool fix_rpl_semi_sync_master_timeout(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_master.set_wait_timeout(rpl_semi_sync_master_timeout);
+ return false;
+}
+
+static bool fix_rpl_semi_sync_master_trace_level(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_master.set_trace_level(rpl_semi_sync_master_trace_level);
+ ack_receiver.set_trace_level(rpl_semi_sync_master_trace_level);
+ return false;
+}
+
+static bool fix_rpl_semi_sync_master_wait_point(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_master.set_wait_point(rpl_semi_sync_master_wait_point);
+ return false;
+}
+
+static bool fix_rpl_semi_sync_master_wait_no_slave(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_master.check_and_switch();
+ return false;
+}
+
+static Sys_var_mybool Sys_semisync_master_enabled(
+ "rpl_semi_sync_master_enabled",
+ "Enable semi-synchronous replication master (disabled by default).",
+ GLOBAL_VAR(rpl_semi_sync_master_enabled),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_master_enabled));
+
+static Sys_var_ulong Sys_semisync_master_timeout(
+ "rpl_semi_sync_master_timeout",
+ "The timeout value (in ms) for semi-synchronous replication in the "
+ "master",
+ GLOBAL_VAR(rpl_semi_sync_master_timeout),
+ CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0,~0L),DEFAULT(10000),BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_master_timeout));
+
+static Sys_var_mybool Sys_semisync_master_wait_no_slave(
+ "rpl_semi_sync_master_wait_no_slave",
+ "Wait until timeout when no semi-synchronous replication slave "
+ "available (enabled by default).",
+ GLOBAL_VAR(rpl_semi_sync_master_wait_no_slave),
+ CMD_LINE(OPT_ARG), DEFAULT(TRUE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_master_wait_no_slave));
+
+static Sys_var_ulong Sys_semisync_master_trace_level(
+ "rpl_semi_sync_master_trace_level",
+ "The tracing level for semi-sync replication.",
+ GLOBAL_VAR(rpl_semi_sync_master_trace_level),
+ CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0,~0L),DEFAULT(32),BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_master_trace_level));
+
+static const char *repl_semisync_wait_point[]=
+{"AFTER_SYNC", "AFTER_COMMIT", NullS};
+
+static Sys_var_enum Sys_semisync_master_wait_point(
+ "rpl_semi_sync_master_wait_point",
+ "Should transaction wait for semi-sync ack after having synced binlog, "
+ "or after having committed in storage engine.",
+ GLOBAL_VAR(rpl_semi_sync_master_wait_point), CMD_LINE(REQUIRED_ARG),
+ repl_semisync_wait_point, DEFAULT(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG,ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_master_wait_point));
+
+static bool fix_rpl_semi_sync_slave_enabled(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_slave.set_slave_enabled(rpl_semi_sync_slave_enabled != 0);
+ return false;
+}
+
+static bool fix_rpl_semi_sync_slave_trace_level(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_slave.set_trace_level(rpl_semi_sync_slave_trace_level);
+ return false;
+}
+
+static bool fix_rpl_semi_sync_slave_delay_master(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_slave.set_delay_master(rpl_semi_sync_slave_delay_master);
+ return false;
+}
+
+static bool fix_rpl_semi_sync_slave_kill_conn_timeout(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_slave.
+ set_kill_conn_timeout(rpl_semi_sync_slave_kill_conn_timeout);
+ return false;
+}
+
+static Sys_var_mybool Sys_semisync_slave_enabled(
+ "rpl_semi_sync_slave_enabled",
+ "Enable semi-synchronous replication slave (disabled by default).",
+ GLOBAL_VAR(rpl_semi_sync_slave_enabled),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_slave_enabled));
+
+static Sys_var_ulong Sys_semisync_slave_trace_level(
+ "rpl_semi_sync_slave_trace_level",
+ "The tracing level for semi-sync replication.",
+ GLOBAL_VAR(rpl_semi_sync_slave_trace_level),
+ CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0,~0L),DEFAULT(32),BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_slave_trace_level));
+
+static Sys_var_mybool Sys_semisync_slave_delay_master(
+ "rpl_semi_sync_slave_delay_master",
+ "Only write master info file when ack is needed.",
+ GLOBAL_VAR(rpl_semi_sync_slave_delay_master),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_slave_delay_master));
+
+static Sys_var_uint Sys_semisync_slave_kill_conn_timeout(
+ "rpl_semi_sync_slave_kill_conn_timeout",
+ "Timeout for the mysql connection used to kill the slave io_thread's "
+ "connection on master. This timeout comes into play when stop slave "
+ "is executed.",
+ GLOBAL_VAR(rpl_semi_sync_slave_kill_conn_timeout),
+ CMD_LINE(OPT_ARG),
+ VALID_RANGE(0, UINT_MAX), DEFAULT(5), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_slave_kill_conn_timeout));
+#endif /* HAVE_REPLICATION */
static Sys_var_ulong Sys_slow_launch_time(
"slow_launch_time",
@@ -3076,7 +3260,8 @@ export sql_mode_t expand_sql_mode(sql_mode_t sql_mode)
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
MODE_IGNORE_SPACE |
MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
- MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
+ MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER |
+ MODE_SIMULTANEOUS_ASSIGNMENT);
if (sql_mode & MODE_MSSQL)
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
MODE_IGNORE_SPACE |
@@ -3145,7 +3330,7 @@ static const char *sql_mode_names[]=
"STRICT_ALL_TABLES", "NO_ZERO_IN_DATE", "NO_ZERO_DATE",
"ALLOW_INVALID_DATES", "ERROR_FOR_DIVISION_BY_ZERO", "TRADITIONAL",
"NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE", "NO_ENGINE_SUBSTITUTION",
- "PAD_CHAR_TO_FULL_LENGTH", "EMPTY_STRING_IS_NULL",
+ "PAD_CHAR_TO_FULL_LENGTH", "EMPTY_STRING_IS_NULL", "SIMULTANEOUS_ASSIGNMENT",
0
};
@@ -3572,27 +3757,6 @@ static Sys_var_charptr Sys_version_source_revision(
CMD_LINE_HELP_ONLY,
IN_SYSTEM_CHARSET, DEFAULT(SOURCE_REVISION));
-static char *guess_malloc_library()
-{
- if (strcmp(MALLOC_LIBRARY, "system") == 0)
- {
-#ifdef HAVE_DLOPEN
- typedef int (*mallctl_type)(const char*, void*, size_t*, void*, size_t);
- mallctl_type mallctl_func;
- mallctl_func= (mallctl_type)dlsym(RTLD_DEFAULT, "mallctl");
- if (mallctl_func)
- {
- static char buf[128];
- char *ver;
- size_t len = sizeof(ver);
- mallctl_func("version", &ver, &len, NULL, 0);
- strxnmov(buf, sizeof(buf)-1, "jemalloc ", ver, NULL);
- return buf;
- }
-#endif
- }
- return const_cast<char*>(MALLOC_LIBRARY);
-}
static char *malloc_library;
static Sys_var_charptr Sys_malloc_library(
"version_malloc_library", "Version of the used malloc library",
@@ -4472,14 +4636,13 @@ static bool fix_log_state(sys_var *self, THD *thd, enum_var_type type)
oldval= logger.get_log_file_handler()->is_open();
log_type= QUERY_LOG_GENERAL;
}
- else if (self == &Sys_slow_query_log)
+ else
{
+ DBUG_ASSERT(self == &Sys_slow_query_log);
newvalptr= &global_system_variables.sql_log_slow;
oldval= logger.get_slow_log_file_handler()->is_open();
log_type= QUERY_LOG_SLOW;
}
- else
- DBUG_ASSERT(FALSE);
newval= *newvalptr;
if (oldval == newval)
@@ -4873,6 +5036,14 @@ static Sys_var_ulonglong Sys_read_binlog_speed_limit(
GLOBAL_VAR(opt_read_binlog_speed_limit), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+static Sys_var_charptr Sys_slave_transaction_retry_errors(
+ "slave_transaction_retry_errors", "Tells the slave thread to retry "
+ "transaction for replication when a query event returns an error from "
+ "the provided list. Deadlock and elapsed lock wait timeout errors are "
+ "automatically added to this list",
+ READ_ONLY GLOBAL_VAR(opt_slave_transaction_retry_errors), CMD_LINE(REQUIRED_ARG),
+ IN_SYSTEM_CHARSET, DEFAULT(0));
+
static Sys_var_ulonglong Sys_relay_log_space_limit(
"relay_log_space_limit", "Maximum space to use for all relay logs",
READ_ONLY GLOBAL_VAR(relay_log_space_limit), CMD_LINE(REQUIRED_ARG),
@@ -4907,10 +5078,19 @@ static Sys_var_uint Sys_sync_masterinfo_period(
#ifdef HAVE_REPLICATION
static Sys_var_ulong Sys_slave_trans_retries(
"slave_transaction_retries", "Number of times the slave SQL "
- "thread will retry a transaction in case it failed with a deadlock "
- "or elapsed lock wait timeout, before giving up and stopping",
+ "thread will retry a transaction in case it failed with a deadlock, "
+ "elapsed lock wait timeout or listed in "
+ "slave_transaction_retry_errors, before giving up and stopping",
GLOBAL_VAR(slave_trans_retries), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, UINT_MAX), DEFAULT(10), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_slave_trans_retry_interval(
+ "slave_transaction_retry_interval", "Interval of the slave SQL "
+ "thread will retry a transaction in case it failed with a deadlock "
+ "or elapsed lock wait timeout or listed in "
+ "slave_transaction_retry_errors",
+ GLOBAL_VAR(slave_trans_retry_interval), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, 3600), DEFAULT(0), BLOCK_SIZE(1));
#endif
static bool check_locale(sys_var *self, THD *thd, set_var *var)
@@ -5147,7 +5327,8 @@ static Sys_var_mybool Sys_wsrep_on (
"wsrep_on", "To enable wsrep replication ",
SESSION_VAR(wsrep_on),
CMD_LINE(OPT_ARG), DEFAULT(FALSE),
- NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(wsrep_on_check),
ON_UPDATE(wsrep_on_update));
static Sys_var_charptr Sys_wsrep_start_position (
@@ -5366,7 +5547,9 @@ static Sys_var_enum Sys_plugin_maturity(
"The lowest desirable plugin maturity. "
"Plugins less mature than that will not be installed or loaded",
READ_ONLY GLOBAL_VAR(plugin_maturity), CMD_LINE(REQUIRED_ARG),
- plugin_maturity_names, DEFAULT(MariaDB_PLUGIN_MATURITY_UNKNOWN));
+ plugin_maturity_names,
+ DEFAULT(SERVER_MATURITY_LEVEL > 0 ?
+ SERVER_MATURITY_LEVEL - 1 : SERVER_MATURITY_LEVEL));
static Sys_var_ulong Sys_deadlock_search_depth_short(
"deadlock_search_depth_short",
@@ -5831,10 +6014,11 @@ static Sys_var_mybool Sys_session_track_state_change(
#endif //EMBEDDED_LIBRARY
-static Sys_var_ulong Sys_in_subquery_conversion_threshold(
- "in_subquery_conversion_threshold",
+#ifndef DBUG_OFF
+static Sys_var_uint Sys_in_subquery_conversion_threshold(
+ "in_predicate_conversion_threshold",
"The minimum number of scalar elements in the value list of "
"IN predicate that triggers its conversion to IN subquery",
SESSION_VAR(in_subquery_conversion_threshold), CMD_LINE(OPT_ARG),
- VALID_RANGE(0, ULONG_MAX), DEFAULT(1000), BLOCK_SIZE(1));
-
+ VALID_RANGE(0, UINT_MAX), DEFAULT(IN_SUBQUERY_CONVERSION_THRESHOLD), BLOCK_SIZE(1));
+#endif
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic
index 706240727c5..e04e09e9bc6 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.ic
@@ -77,6 +77,11 @@
#define GET_HA_ROWS GET_ULONG
#endif
+// Disable warning caused by SESSION_VAR() macro
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Winvalid-offsetof"
+#endif
+
/*
special assert for sysvars. Tells the name of the variable,
and fails even in non-debug builds.
@@ -1562,7 +1567,6 @@ public:
*/
class Sys_var_pluginlist: public sys_var
{
- int plugin_type;
public:
Sys_var_pluginlist(const char *name_arg,
const char *comment, int flag_args, ptrdiff_t off, size_t size,
@@ -2597,3 +2601,96 @@ public:
bool global_update(THD *thd, set_var *var);
uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base);
};
+
+
+class Sys_var_vers_asof: public Sys_var_enum
+{
+public:
+ static const char *asof_keywords[];
+
+public:
+ Sys_var_vers_asof(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt, const char *values[],
+ uint def_val)
+ : Sys_var_enum(name_arg, comment, flag_args, off, size,
+ getopt, values, def_val)
+ {
+ // setval() accepts string rather enum
+ option.var_type= GET_STR;
+ }
+ virtual bool do_check(THD *thd, set_var *var)
+ {
+ if (!Sys_var_enum::do_check(thd, var))
+ return false;
+ MYSQL_TIME ltime;
+ bool res= var->value->get_date(&ltime, 0);
+ if (!res)
+ {
+ var->save_result.ulonglong_value= SYSTEM_TIME_AS_OF;
+ }
+ return res;
+ }
+
+private:
+ bool update(set_var *var, vers_asof_timestamp_t &out)
+ {
+ bool res= false;
+ out.type= static_cast<enum_var_type>(var->save_result.ulonglong_value);
+ if (out.type == SYSTEM_TIME_AS_OF)
+ {
+ if (var->value)
+ {
+ res= var->value->get_date(&out.ltime, 0);
+ }
+ else // set DEFAULT from global var
+ {
+ out= global_var(vers_asof_timestamp_t);
+ res= false;
+ }
+ }
+ return res;
+ }
+
+public:
+ virtual bool global_update(THD *thd, set_var *var)
+ {
+ return update(var, global_var(vers_asof_timestamp_t));
+ }
+ virtual bool session_update(THD *thd, set_var *var)
+ {
+ return update(var, session_var(thd, vers_asof_timestamp_t));
+ }
+
+private:
+ uchar *value_ptr(THD *thd, vers_asof_timestamp_t &val)
+ {
+ switch (val.type)
+ {
+ case SYSTEM_TIME_UNSPECIFIED:
+ case SYSTEM_TIME_ALL:
+ return (uchar*) thd->strdup(asof_keywords[val.type]);
+ case SYSTEM_TIME_AS_OF:
+ {
+ uchar *buf= (uchar*) thd->alloc(MAX_DATE_STRING_REP_LENGTH);
+ if (buf &&!my_datetime_to_str(&val.ltime, (char*) buf, 6))
+ {
+ // TODO: figure out variable name
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "system_versioning_asof_timestamp", "NULL (wrong datetime)");
+ return (uchar*) thd->strdup("Error: wrong datetime");
+ }
+ return buf;
+ }
+ default:
+ break;
+ }
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "system_versioning_asof_timestamp", "NULL (wrong range type)");
+ return (uchar*) thd->strdup("Error: wrong range type");
+ }
+
+public:
+ virtual uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base)
+ { return value_ptr(thd, session_var(thd, vers_asof_timestamp_t)); }
+ virtual uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base)
+ { return value_ptr(thd, global_var(vers_asof_timestamp_t)); }
+};
diff --git a/sql/sys_vars_shared.h b/sql/sys_vars_shared.h
index ff050f63064..48154c95a72 100644
--- a/sql/sys_vars_shared.h
+++ b/sql/sys_vars_shared.h
@@ -32,7 +32,7 @@ extern bool throw_bounds_warning(THD *thd, const char *name,
bool fixed, bool is_unsigned, longlong v);
extern bool throw_bounds_warning(THD *thd, const char *name, bool fixed,
double v);
-extern sys_var *intern_find_sys_var(const char *str, uint length);
+extern sys_var *intern_find_sys_var(const char *str, size_t length);
extern sys_var_chain all_sys_vars;
diff --git a/sql/table.cc b/sql/table.cc
index fee76721b9f..b39ead6d8a8 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -43,6 +43,7 @@
#include "rpl_filter.h"
#include "sql_cte.h"
#include "ha_sequence.h"
+#include "sql_show.h"
/* For MySQL 5.7 virtual fields */
#define MYSQL57_GENERATED_FIELD 128
@@ -67,6 +68,11 @@ LEX_CSTRING GENERAL_LOG_NAME= {STRING_WITH_LEN("general_log")};
/* SLOW_LOG name */
LEX_CSTRING SLOW_LOG_NAME= {STRING_WITH_LEN("slow_log")};
+LEX_CSTRING TRANSACTION_REG_NAME= {STRING_WITH_LEN("transaction_registry")};
+LEX_CSTRING MYSQL_USER_NAME= {STRING_WITH_LEN("user")};
+LEX_CSTRING MYSQL_DB_NAME= {STRING_WITH_LEN("db")};
+LEX_CSTRING MYSQL_PROC_NAME= {STRING_WITH_LEN("proc")};
+
/*
Keyword added as a prefix when parsing the defining expression for a
virtual column read from the column definition saved in the frm file
@@ -81,7 +87,7 @@ static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
uint types, char **names);
static uint find_field(Field **fields, uchar *record, uint start, uint length);
-inline bool is_system_table_name(const char *name, uint length);
+inline bool is_system_table_name(const char *name, size_t length);
/**************************************************************************
Object_creation_ctx implementation.
@@ -160,8 +166,8 @@ View_creation_ctx * View_creation_ctx::create(THD *thd,
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_VIEW_NO_CREATION_CTX,
ER_THD(thd, ER_VIEW_NO_CREATION_CTX),
- (const char *) view->db,
- (const char *) view->table_name);
+ view->db.str,
+ view->table_name.str);
ctx->m_client_cs= system_charset_info;
ctx->m_connection_cl= system_charset_info;
@@ -186,16 +192,16 @@ View_creation_ctx * View_creation_ctx::create(THD *thd,
{
sql_print_warning("View '%s'.'%s': there is unknown charset/collation "
"names (client: '%s'; connection: '%s').",
- (const char *) view->db,
- (const char *) view->table_name,
+ view->db.str,
+ view->table_name.str,
(const char *) view->view_client_cs_name.str,
(const char *) view->view_connection_cl_name.str);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_VIEW_INVALID_CREATION_CTX,
ER_THD(thd, ER_VIEW_INVALID_CREATION_CTX),
- (const char *) view->db,
- (const char *) view->table_name);
+ view->db.str,
+ view->table_name.str);
}
return ctx;
@@ -243,7 +249,7 @@ TABLE_CATEGORY get_table_category(const LEX_CSTRING *db,
DBUG_ASSERT(db != NULL);
DBUG_ASSERT(name != NULL);
- if (is_infoschema_db(db->str, db->length))
+ if (is_infoschema_db(db))
return TABLE_CATEGORY_INFORMATION;
if (lex_string_eq(&PERFORMANCE_SCHEMA_DB_NAME, db) == 0)
@@ -259,6 +265,9 @@ TABLE_CATEGORY get_table_category(const LEX_CSTRING *db,
if (lex_string_eq(&SLOW_LOG_NAME, name) == 0)
return TABLE_CATEGORY_LOG;
+
+ if (lex_string_eq(&TRANSACTION_REG_NAME, name) == 0)
+ return TABLE_CATEGORY_LOG;
}
return TABLE_CATEGORY_USER;
@@ -293,7 +302,7 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name,
path_length= build_table_filename(path, sizeof(path) - 1,
db, table_name, "", 0);
- init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(&mem_root, "table_share", TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
if (multi_alloc_root(&mem_root,
&share, sizeof(*share),
&key_buff, key_length,
@@ -319,7 +328,8 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name,
(const uchar*) "mysql", 6) == 0)
share->not_usable_by_query_cache= 1;
- init_sql_alloc(&share->stats_cb.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(&share->stats_cb.mem_root, "share_stats",
+ TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
memcpy((char*) &share->mem_root, (char*) &mem_root, sizeof(mem_root));
mysql_mutex_init(key_TABLE_SHARE_LOCK_share,
@@ -376,8 +386,8 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
This can't be MY_THREAD_SPECIFIC for slaves as they are freed
during cleanup() from Relay_log_info::close_temporary_tables()
*/
- init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0,
- MYF(thd->slave_thread ? 0 : MY_THREAD_SPECIFIC));
+ init_sql_alloc(&share->mem_root, "tmp_table_share", TABLE_ALLOC_BLOCK_SIZE,
+ 0, MYF(thd->slave_thread ? 0 : MY_THREAD_SPECIFIC));
share->table_category= TABLE_CATEGORY_TEMPORARY;
share->tmp_table= INTERNAL_TMP_TABLE;
share->db.str= (char*) key;
@@ -496,7 +506,7 @@ void free_table_share(TABLE_SHARE *share)
and should not contain user tables.
*/
-inline bool is_system_table_name(const char *name, uint length)
+inline bool is_system_table_name(const char *name, size_t length)
{
CHARSET_INFO *ci= system_charset_info;
@@ -988,7 +998,7 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
Virtual_column_info **check_constraint_ptr= table->check_constraints;
sql_mode_t saved_mode= thd->variables.sql_mode;
Query_arena backup_arena;
- Virtual_column_info *vcol;
+ Virtual_column_info *vcol= 0;
StringBuffer<MAX_FIELD_WIDTH> expr_str;
bool res= 1;
DBUG_ENTER("parse_vcol_defs");
@@ -1159,15 +1169,15 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
uint new_frm_ver, field_pack_length, new_field_pack_flag;
uint interval_count, interval_parts, read_length, int_length;
uint db_create_options, keys, key_parts, n_length;
- uint com_length, null_bit_pos, mysql57_vcol_null_bit_pos, bitmap_count;
+ uint com_length, null_bit_pos, UNINIT_VAR(mysql57_vcol_null_bit_pos), bitmap_count;
uint i;
bool use_hash, mysql57_null_bits= 0;
char *keynames, *names, *comment_pos;
const uchar *forminfo, *extra2;
const uchar *frm_image_end = frm_image + frm_length;
- uchar *record, *null_flags, *null_pos, *mysql57_vcol_null_pos= 0;
+ uchar *record, *null_flags, *null_pos, *UNINIT_VAR(mysql57_vcol_null_pos);
const uchar *disk_buff, *strpos;
- ulong pos, record_offset;
+ ulong pos, record_offset;
ulong rec_buff_length;
handler *handler_file= 0;
KEY *keyinfo;
@@ -1177,15 +1187,23 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
enum legacy_db_type legacy_db_type;
my_bitmap_map *bitmaps;
bool null_bits_are_used;
- uint vcol_screen_length, UNINIT_VAR(options_len);
+ uint vcol_screen_length;
+ size_t UNINIT_VAR(options_len);
uchar *vcol_screen_pos;
const uchar *options= 0;
- uint UNINIT_VAR(gis_options_len);
+ size_t UNINIT_VAR(gis_options_len);
const uchar *gis_options= 0;
KEY first_keyinfo;
uint len;
uint ext_key_parts= 0;
plugin_ref se_plugin= 0;
+ const uchar *system_period= 0;
+ bool vtmd_used= false;
+ share->vtmd= false;
+ bool vers_can_native= false;
+ const uchar *extra2_field_flags= 0;
+ size_t extra2_field_flags_length= 0;
+
MEM_ROOT *old_root= thd->mem_root;
Virtual_column_info **table_check_constraints;
DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
@@ -1221,7 +1239,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (*extra2 != '/') // old frm had '/' there
{
const uchar *e2end= extra2 + len;
- while (extra2 + 3 < e2end)
+ while (extra2 + 3 <= e2end)
{
uchar type= *extra2++;
size_t length= *extra2++;
@@ -1279,6 +1297,28 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
#endif /*HAVE_SPATIAL*/
break;
+ case EXTRA2_PERIOD_FOR_SYSTEM_TIME:
+ if (system_period || length != 2 * sizeof(uint16))
+ goto err;
+ system_period = extra2;
+ break;
+ case EXTRA2_VTMD:
+ if (vtmd_used)
+ goto err;
+ share->vtmd= *extra2;
+ if (share->vtmd)
+ {
+ share->table_category= TABLE_CATEGORY_LOG;
+ share->no_replicate= true;
+ }
+ vtmd_used= true;
+ break;
+ case EXTRA2_FIELD_FLAGS:
+ if (extra2_field_flags)
+ goto err;
+ extra2_field_flags= extra2;
+ extra2_field_flags_length= length;
+ break;
default:
/* abort frm parsing if it's an unknown but important extra2 value */
if (type >= EXTRA2_ENGINE_IMPORTANT)
@@ -1588,15 +1628,17 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
share->rec_buff_length= rec_buff_length;
- if (!(record= (uchar *) alloc_root(&share->mem_root,
- rec_buff_length)))
+ if (!(record= (uchar *) alloc_root(&share->mem_root, rec_buff_length)))
goto err; /* purecov: inspected */
+ MEM_NOACCESS(record, rec_buff_length);
+ MEM_UNDEFINED(record, share->reclength);
share->default_values= record;
memcpy(record, frm_image + record_offset, share->reclength);
disk_buff= frm_image + pos + FRM_FORMINFO_SIZE;
-
share->fields= uint2korr(forminfo+258);
+ if (extra2_field_flags && extra2_field_flags_length != share->fields)
+ goto err;
pos= uint2korr(forminfo+260); /* Length of all screens */
n_length= uint2korr(forminfo+268);
interval_count= uint2korr(forminfo+270);
@@ -1607,6 +1649,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
vcol_screen_length= uint2korr(forminfo+286);
share->virtual_fields= share->default_expressions=
share->field_check_constraints= share->default_fields= 0;
+ share->visible_fields= 0;
share->stored_fields= share->fields;
if (forminfo[46] != (uchar)255)
{
@@ -1667,7 +1710,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
for (count= 0; count < interval->count; count++)
{
char *val= (char*) interval->type_names[count];
- interval->type_lengths[count]= strlen(val);
+ interval->type_lengths[count]= (uint)strlen(val);
}
interval->type_lengths[count]= 0;
}
@@ -1728,6 +1771,27 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
strpos, vcol_screen_pos);
}
+ /* Set system versioning information. */
+ if (system_period == NULL)
+ {
+ versioned= VERS_UNDEFINED;
+ row_start_field= 0;
+ row_end_field= 0;
+ }
+ else
+ {
+ DBUG_PRINT("info", ("Setting system versioning informations"));
+ uint16 row_start= uint2korr(system_period);
+ uint16 row_end= uint2korr(system_period + sizeof(uint16));
+ if (row_start >= share->fields || row_end >= share->fields)
+ goto err;
+ DBUG_PRINT("info", ("Columns with system versioning: [%d, %d]", row_start, row_end));
+ versioned= VERS_TIMESTAMP;
+ vers_can_native= plugin_hton(se_plugin)->flags & HTON_NATIVE_SYS_VERSIONING;
+ row_start_field= row_start;
+ row_end_field= row_end;
+ } // if (system_period == NULL)
+
for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
{
uint pack_flag, interval_nr, unireg_type, recpos, field_length;
@@ -1742,6 +1806,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
uint gis_length, gis_decimals, srid= 0;
Field::utype unireg_check;
const Type_handler *handler;
+ uint32 flags= 0;
if (new_frm_ver >= 3)
{
@@ -1784,7 +1849,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
char tmp[10];
if (!csname || csname[0] =='?')
{
- my_snprintf(tmp, sizeof(tmp), "#%d", cs_new);
+ my_snprintf(tmp, sizeof(tmp), "#%u", cs_new);
csname= tmp;
}
my_printf_error(ER_UNKNOWN_COLLATION,
@@ -1951,6 +2016,36 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
swap_variables(uint, null_bit_pos, mysql57_vcol_null_bit_pos);
}
+ if (versioned)
+ {
+ if (i == row_start_field)
+ flags|= VERS_SYS_START_FLAG;
+ else if (i == row_end_field)
+ flags|= VERS_SYS_END_FLAG;
+
+ if (flags & VERS_SYSTEM_FIELD)
+ {
+ switch (field_type)
+ {
+ case MYSQL_TYPE_TIMESTAMP2:
+ case MYSQL_TYPE_DATETIME2:
+ break;
+ case MYSQL_TYPE_LONGLONG:
+ if (vers_can_native)
+ {
+ versioned= VERS_TRX_ID;
+ break;
+ }
+ /* Fallthrough */
+ default:
+ my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), fieldnames.type_names[i],
+ versioned == VERS_TIMESTAMP ? "TIMESTAMP(6)" : "BIGINT(20) UNSIGNED",
+ table_name.str);
+ goto err;
+ }
+ }
+ }
+
/* Convert pre-10.2.2 timestamps to use Field::default_value */
unireg_check= (Field::utype) MTYP_TYPENR(unireg_type);
name.str= fieldnames.type_names[i];
@@ -1962,7 +2057,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
null_pos, null_bit_pos, pack_flag, handler, charset,
geom_type, srid, unireg_check,
(interval_nr ? share->intervals+interval_nr-1 : NULL),
- &name);
+ &name, flags);
if (!reg_field) // Not supported field type
goto err;
@@ -1978,6 +2073,19 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
reg_field->field_index= i;
reg_field->comment=comment;
reg_field->vcol_info= vcol_info;
+ reg_field->flags|= flags;
+ if (extra2_field_flags)
+ {
+ uchar flags= *extra2_field_flags++;
+ if (flags & VERS_OPTIMIZED_UPDATE)
+ reg_field->flags|= VERS_UPDATE_UNVERSIONED_FLAG;
+
+ reg_field->invisible= f_visibility(flags);
+ }
+ if (reg_field->invisible == INVISIBLE_USER)
+ status_var_increment(thd->status_var.feature_invisible_columns);
+ if (!reg_field->invisible)
+ share->visible_fields++;
if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag))
{
null_bits_are_used= 1;
@@ -2109,6 +2217,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
}
+ key_first_info= keyinfo;
for (uint key=0 ; key < keys ; key++,keyinfo++)
{
uint usable_parts= 0;
@@ -2126,9 +2235,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
keyinfo->name.length+1);
}
- if (!key)
- key_first_info= keyinfo;
-
if (ext_key_parts > share->key_parts && key)
{
KEY_PART_INFO *new_key_part= (keyinfo-1)->key_part +
@@ -2229,6 +2335,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
field= key_part->field= share->field[key_part->fieldnr-1];
key_part->type= field->key_type();
+ if (field->invisible > INVISIBLE_USER && !field->vers_sys_field())
+ keyinfo->flags |= HA_INVISIBLE_KEY;
if (field->null_ptr)
{
key_part->null_offset=(uint) ((uchar*) field->null_ptr -
@@ -2415,7 +2523,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
reg_field= share->field[field_nr];
}
else
- reg_field= 0; // Safety
+ {
+ reg_field= 0;
+ DBUG_ASSERT(name_length);
+ }
vcol_screen_pos+= FRM_VCOL_NEW_HEADER_SIZE;
vcol_info->set_vcol_type((enum_vcol_info_type) type);
@@ -2548,19 +2659,21 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
bitmap_clear_all(share->check_set);
}
- delete handler_file;
#ifndef DBUG_OFF
if (use_hash)
(void) my_hash_check(&share->name_hash);
#endif
share->db_plugin= se_plugin;
+ delete handler_file;
+
share->error= OPEN_FRM_OK;
thd->status_var.opened_shares++;
thd->mem_root= old_root;
DBUG_RETURN(0);
- err:
+err:
+ share->db_plugin= NULL;
share->error= OPEN_FRM_CORRUPTED;
share->open_errno= my_errno;
delete handler_file;
@@ -2611,6 +2724,9 @@ static bool sql_unusable_for_discovery(THD *thd, handlerton *engine,
// ... engine
if (create_info->db_type && create_info->db_type != engine)
return 1;
+ // ... WITH SYSTEM VERSIONING
+ if (create_info->versioned())
+ return 1;
return 0;
}
@@ -2631,7 +2747,7 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
uint unused2;
handlerton *hton= plugin_hton(db_plugin);
LEX_CUSTRING frm= {0,0};
- LEX_STRING db_backup= { thd->db, thd->db_length };
+ LEX_CSTRING db_backup= thd->db;
DBUG_ENTER("TABLE_SHARE::init_from_sql_statement_string");
/*
@@ -2658,7 +2774,7 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
else
thd->set_n_backup_active_arena(arena, &backup);
- thd->reset_db((char*) db.str, db.length);
+ thd->reset_db(&db);
lex_start(thd);
if ((error= parse_sql(thd, & parser_state, NULL) ||
@@ -2671,7 +2787,7 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
thd->lex->create_info.tabledef_version= tabledef_version;
promote_first_timestamp_column(&thd->lex->alter_info.create_list);
- file= mysql_create_frm_image(thd, db.str, table_name.str,
+ file= mysql_create_frm_image(thd, &db, &table_name,
&thd->lex->create_info, &thd->lex->alter_info,
C_ORDINARY_CREATE, &unused1, &unused2, &frm);
error|= file == 0;
@@ -2687,7 +2803,7 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
ret:
my_free(const_cast<uchar*>(frm.str));
lex_end(thd->lex);
- thd->reset_db(db_backup.str, db_backup.length);
+ thd->reset_db(&db_backup);
thd->lex= old_lex;
if (arena)
thd->restore_active_arena(arena, &backup);
@@ -2742,12 +2858,12 @@ static bool fix_vcol_expr(THD *thd, Virtual_column_info *vcol)
{
DBUG_ENTER("fix_vcol_expr");
- const enum enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
- thd->mark_used_columns= MARK_COLUMNS_NONE;
+ const enum enum_column_usage saved_column_usage= thd->column_usage;
+ thd->column_usage= COLUMNS_WRITE;
int error= vcol->expr->fix_fields(thd, &vcol->expr);
- thd->mark_used_columns= save_mark_used_columns;
+ thd->column_usage= saved_column_usage;
if (unlikely(error))
{
@@ -2945,6 +3061,14 @@ unpack_vcol_info_from_frm(THD *thd, MEM_ROOT *mem_root, TABLE *table,
if (error)
goto end;
+ if (lex.current_select->table_list.first[0].next_global)
+ {
+ /* We are using NEXT VALUE FOR sequence. Remember table name for open */
+ TABLE_LIST *sequence= lex.current_select->table_list.first[0].next_global;
+ sequence->next_global= table->internal_tables;
+ table->internal_tables= sequence;
+ }
+
vcol_storage.vcol_info->set_vcol_type(vcol->get_vcol_type());
vcol_storage.vcol_info->stored_in_db= vcol->stored_in_db;
vcol_storage.vcol_info->name= vcol->name;
@@ -2985,6 +3109,7 @@ static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol)
prgflag READ_ALL etc..
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
outparam result table
+ partitions_to_open open only these partitions.
RETURN VALUES
0 ok
@@ -2997,9 +3122,9 @@ static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol)
*/
enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
- const char *alias, uint db_stat, uint prgflag,
+ const LEX_CSTRING *alias, uint db_stat, uint prgflag,
uint ha_open_flags, TABLE *outparam,
- bool is_create_table)
+ bool is_create_table, List<String> *partitions_to_open)
{
enum open_frm_error error;
uint records, i, bitmap_size, bitmap_count;
@@ -3027,9 +3152,10 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
error= OPEN_FRM_NEEDS_REBUILD;
goto err;
}
- init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(&outparam->mem_root, "table", TABLE_ALLOC_BLOCK_SIZE, 0,
+ MYF(0));
- if (outparam->alias.copy(alias, strlen(alias), table_alias_charset))
+ if (outparam->alias.copy(alias->str, alias->length, table_alias_charset))
goto err;
outparam->quick_keys.init();
outparam->covering_keys.init();
@@ -3068,26 +3194,34 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
records=0;
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
records=1;
- if (prgflag & (READ_ALL+EXTRA_RECORD))
+ if (prgflag & (READ_ALL + EXTRA_RECORD))
+ {
records++;
-
- if (!(record= (uchar*) alloc_root(&outparam->mem_root,
- share->rec_buff_length * records)))
- goto err; /* purecov: inspected */
+ if (share->versioned)
+ records++;
+ }
if (records == 0)
{
/* We are probably in hard repair, and the buffers should not be used */
- outparam->record[0]= outparam->record[1]= share->default_values;
+ record= share->default_values;
}
else
{
- outparam->record[0]= record;
- if (records > 1)
- outparam->record[1]= record+ share->rec_buff_length;
- else
- outparam->record[1]= outparam->record[0]; // Safety
+ if (!(record= (uchar*) alloc_root(&outparam->mem_root,
+ share->rec_buff_length * records)))
+ goto err; /* purecov: inspected */
+ MEM_NOACCESS(record, share->rec_buff_length * records);
+ }
+
+ for (i= 0; i < 3;)
+ {
+ outparam->record[i]= record;
+ if (++i < records)
+ record+= share->rec_buff_length;
}
+ for (i= 0; i < records; i++)
+ MEM_UNDEFINED(outparam->record[i], share->reclength);
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
(uint) ((share->fields+1)*
@@ -3111,6 +3245,8 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
}
(*field_ptr)= 0; // End marker
+ outparam->vers_write= share->versioned;
+
if (share->found_next_number_field)
outparam->found_next_number_field=
outparam->field[(uint) (share->found_next_number_field - share->field)];
@@ -3202,6 +3338,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
+ bool work_part_info_used;
if (share->partition_info_str_len && outparam->file)
{
/*
@@ -3222,7 +3359,6 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
thd->set_n_backup_active_arena(&part_func_arena, &backup_arena);
thd->stmt_arena= &part_func_arena;
bool tmp;
- bool work_part_info_used;
tmp= mysql_unpack_partition(thd, share->partition_info_str,
share->partition_info_str_len,
@@ -3336,7 +3472,7 @@ partititon_err:
int ha_err= outparam->file->ha_open(outparam, share->normalized_path.str,
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
- ha_open_flags);
+ ha_open_flags, 0, partitions_to_open);
if (ha_err)
{
share->open_errno= ha_err;
@@ -3640,7 +3776,7 @@ static uint find_field(Field **fields, uchar *record, uint start, uint length)
May fail with some multibyte charsets though.
*/
-void append_unescaped(String *res, const char *pos, uint length)
+void append_unescaped(String *res, const char *pos, size_t length)
{
const char *end= pos+length;
res->append('\'');
@@ -3691,7 +3827,7 @@ void append_unescaped(String *res, const char *pos, uint length)
void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo,
HA_CREATE_INFO *create_info, uint keys, KEY *key_info)
{
- ulong key_comment_total_bytes= 0;
+ size_t key_comment_total_bytes= 0;
uint i;
DBUG_ENTER("prepare_frm_header");
@@ -3701,7 +3837,7 @@ void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo,
if (create_info->min_rows > UINT_MAX32)
create_info->min_rows= UINT_MAX32;
- uint key_length, tmp_key_length, tmp, csid;
+ size_t key_length, tmp_key_length, tmp, csid;
bzero((char*) fileinfo, FRM_HEADER_SIZE);
/* header */
fileinfo[0]=(uchar) 254;
@@ -3927,7 +4063,7 @@ bool ok_for_lower_case_names(const char *name)
bool check_db_name(LEX_STRING *org_name)
{
char *name= org_name->str;
- uint name_length= org_name->length;
+ size_t name_length= org_name->length;
bool check_for_path_chars;
if ((check_for_path_chars= check_mysql50_prefix(name)))
@@ -4449,10 +4585,10 @@ void TABLE::init(THD *thd, TABLE_LIST *tl)
if (thd->lex->need_correct_ident())
alias_name_used= my_strcasecmp(table_alias_charset,
s->table_name.str,
- tl->alias);
+ tl->alias.str);
/* Fix alias if table name changes. */
- if (strcmp(alias.c_ptr(), tl->alias))
- alias.copy(tl->alias, strlen(tl->alias), alias.charset());
+ if (strcmp(alias.c_ptr(), tl->alias.str))
+ alias.copy(tl->alias.str, tl->alias.length, alias.charset());
tablenr= thd->current_tablenr++;
used_fields= 0;
@@ -4603,6 +4739,9 @@ bool TABLE_LIST::create_field_translation(THD *thd)
Query_arena *arena, backup;
bool res= FALSE;
DBUG_ENTER("TABLE_LIST::create_field_translation");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (alias.str ? alias.str : "<NULL>"),
+ get_unit()));
if (thd->stmt_arena->is_conventional() ||
thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
@@ -4629,16 +4768,20 @@ bool TABLE_LIST::create_field_translation(THD *thd)
*/
if (is_view() && get_unit()->prepared && !field_translation_updated)
{
+ field_translation_updated= TRUE;
+ if (static_cast<uint>(field_translation_end - field_translation) <
+ select->item_list.elements)
+ goto allocate;
while ((item= it++))
{
field_translation[field_count++].item= item;
}
- field_translation_updated= TRUE;
}
DBUG_RETURN(FALSE);
}
+allocate:
arena= thd->activate_stmt_arena_if_needed(&backup);
/* Create view fields translation table */
@@ -4846,7 +4989,7 @@ merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
DBUG_ENTER("merge_on_conds");
Item *cond= NULL;
- DBUG_PRINT("info", ("alias: %s", table->alias));
+ DBUG_PRINT("info", ("alias: %s", table->alias.str));
if (table->on_expr)
cond= table->on_expr->copy_andor_structure(thd);
if (!table->view)
@@ -5074,9 +5217,9 @@ int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure)
{
TABLE_LIST *main_view= top_table();
const char *name_db= (main_view->view ? main_view->view_db.str :
- main_view->db);
+ main_view->db.str);
const char *name_table= (main_view->view ? main_view->view_name.str :
- main_view->table_name);
+ main_view->table_name.str);
my_error(ER_VIEW_CHECK_FAILED, MYF(ignore_failure ? ME_JUST_WARNING : 0),
name_db, name_table);
return ignore_failure ? VIEW_CHECK_SKIP : VIEW_CHECK_ERROR;
@@ -5107,7 +5250,6 @@ int TABLE::verify_constraints(bool ignore_failure)
return(VIEW_CHECK_OK);
}
-
/*
Find table in underlying tables by mask and check that only this
table belong to given mask
@@ -5377,7 +5519,7 @@ void TABLE_LIST::register_want_access(ulong want_access)
bool TABLE_LIST::prepare_view_security_context(THD *thd)
{
DBUG_ENTER("TABLE_LIST::prepare_view_security_context");
- DBUG_PRINT("enter", ("table: %s", alias));
+ DBUG_PRINT("enter", ("table: %s", alias.str));
DBUG_ASSERT(!prelocking_placeholder && view);
if (view_suid)
@@ -5385,7 +5527,7 @@ bool TABLE_LIST::prepare_view_security_context(THD *thd)
DBUG_PRINT("info", ("This table is suid view => load contest"));
DBUG_ASSERT(view && view_sctx);
if (acl_getroot(view_sctx, definer.user.str, definer.host.str,
- definer.host.str, thd->db))
+ definer.host.str, thd->db.str))
{
if ((thd->lex->sql_command == SQLCOM_SHOW_CREATE) ||
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS))
@@ -5450,7 +5592,7 @@ Security_context *TABLE_LIST::find_view_security_context(THD *thd)
if (upper_view)
{
DBUG_PRINT("info", ("Securety context of view %s will be used",
- upper_view->alias));
+ upper_view->alias.str));
sctx= upper_view->view_sctx;
DBUG_ASSERT(sctx);
}
@@ -5499,8 +5641,8 @@ bool TABLE_LIST::prepare_security(THD *thd)
}
else
{
- local_db= tbl->db;
- local_table_name= tbl->table_name;
+ local_db= tbl->db.str;
+ local_table_name= tbl->table_name.str;
}
fill_effective_table_privileges(thd, &tbl->grant, local_db,
local_table_name);
@@ -5651,30 +5793,29 @@ Field *Natural_join_column::field()
}
-const char *Natural_join_column::table_name()
+const char *Natural_join_column::safe_table_name()
{
DBUG_ASSERT(table_ref);
- return table_ref->alias;
+ return table_ref->alias.str ? table_ref->alias.str : "";
}
-const char *Natural_join_column::db_name()
+const char *Natural_join_column::safe_db_name()
{
if (view_field)
- return table_ref->view_db.str;
+ return table_ref->view_db.str ? table_ref->view_db.str : "";
/*
Test that TABLE_LIST::db is the same as TABLE_SHARE::db to
ensure consistency. An exception are I_S schema tables, which
are inconsistent in this respect.
*/
- DBUG_ASSERT(!strcmp(table_ref->db,
- table_ref->table->s->db.str) ||
+ DBUG_ASSERT(!cmp(&table_ref->db,
+ &table_ref->table->s->db) ||
(table_ref->schema_table &&
- is_infoschema_db(table_ref->table->s->db.str,
- table_ref->table->s->db.length)) ||
- table_ref->is_materialized_derived());
- return table_ref->db;
+ is_infoschema_db(&table_ref->table->s->db)) ||
+ table_ref->is_materialized_derived());
+ return table_ref->db.str ? table_ref->db.str : "";
}
@@ -5775,7 +5916,7 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
Name_resolution_context *context= view->view ? &view->view->select_lex.context :
&thd->lex->select_lex.context;
Item *item= (new (thd->mem_root)
- Item_direct_view_ref(thd, context, field_ref, view->alias,
+ Item_direct_view_ref(thd, context, field_ref, view->alias.str,
name, view));
/*
Force creation of nullable item for the result tmp table for outer joined
@@ -5839,7 +5980,7 @@ void Field_iterator_table_ref::set_field_iterator()
table_ref->table->s->fields))));
field_it= &natural_join_it;
DBUG_PRINT("info",("field_it for '%s' is Field_iterator_natural_join",
- table_ref->alias));
+ table_ref->alias.str));
}
/* This is a merge view, so use field_translation. */
else if (table_ref->field_translation)
@@ -5847,7 +5988,7 @@ void Field_iterator_table_ref::set_field_iterator()
DBUG_ASSERT(table_ref->is_merged_derived());
field_it= &view_field_it;
DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_view",
- table_ref->alias));
+ table_ref->alias.str));
}
/* This is a base table or stored view. */
else
@@ -5855,7 +5996,7 @@ void Field_iterator_table_ref::set_field_iterator()
DBUG_ASSERT(table_ref->table || table_ref->view);
field_it= &table_field_it;
DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_table",
- table_ref->alias));
+ table_ref->alias.str));
}
field_it->set(table_ref);
DBUG_VOID_RETURN;
@@ -5897,11 +6038,11 @@ const char *Field_iterator_table_ref::get_table_name()
if (table_ref->is_derived())
return table_ref->table->s->table_name.str;
else if (table_ref->is_natural_join)
- return natural_join_it.column_ref()->table_name();
+ return natural_join_it.column_ref()->safe_table_name();
- DBUG_ASSERT(!strcmp(table_ref->table_name,
+ DBUG_ASSERT(!strcmp(table_ref->table_name.str,
table_ref->table->s->table_name.str));
- return table_ref->table_name;
+ return table_ref->table_name.str;
}
@@ -5910,19 +6051,18 @@ const char *Field_iterator_table_ref::get_db_name()
if (table_ref->view)
return table_ref->view_db.str;
else if (table_ref->is_natural_join)
- return natural_join_it.column_ref()->db_name();
+ return natural_join_it.column_ref()->safe_db_name();
/*
Test that TABLE_LIST::db is the same as TABLE_SHARE::db to
ensure consistency. An exception are I_S schema tables, which
are inconsistent in this respect.
*/
- DBUG_ASSERT(!strcmp(table_ref->db, table_ref->table->s->db.str) ||
+ DBUG_ASSERT(!cmp(&table_ref->db, &table_ref->table->s->db) ||
(table_ref->schema_table &&
- is_infoschema_db(table_ref->table->s->db.str,
- table_ref->table->s->db.length)));
+ is_infoschema_db(&table_ref->table->s->db)));
- return table_ref->db;
+ return table_ref->db.str;
}
@@ -6275,6 +6415,15 @@ void TABLE::mark_columns_needed_for_delete()
if (need_signal)
file->column_bitmaps_signal();
+
+ /*
+ For System Versioning we have to write and read Sys_end.
+ */
+ if (s->versioned)
+ {
+ bitmap_set_bit(read_set, s->vers_end_field()->field_index);
+ bitmap_set_bit(write_set, s->vers_end_field()->field_index);
+ }
}
@@ -6315,7 +6464,7 @@ void TABLE::mark_columns_needed_for_update()
for (KEY *k= key_info; k < end; k++)
{
KEY_PART_INFO *kpend= k->key_part + k->ext_key_parts;
- bool any_written= false, all_read= true;
+ int any_written= 0, all_read= 1;
for (KEY_PART_INFO *kp= k->key_part; kp < kpend; kp++)
{
int idx= kp->fieldnr - 1;
@@ -6351,6 +6500,15 @@ void TABLE::mark_columns_needed_for_update()
need_signal= true;
}
}
+ /*
+ For System Versioning we have to read all columns since we will store
+ a copy of previous row with modified Sys_end column back to a table.
+ */
+ if (s->versioned)
+ {
+ // We will copy old columns to a new row.
+ use_all_columns();
+ }
if (check_constraints)
{
mark_check_constraint_columns_for_read();
@@ -6631,6 +6789,58 @@ bool TABLE::mark_virtual_columns_for_write(bool insert_fl)
DBUG_RETURN(bitmap_updated);
}
+
+/**
+ Check if a virtual not stored column field is in read set
+
+ @retval FALSE No virtual not stored column is used
+ @retval TRUE At least one virtual not stored column is used
+*/
+
+bool TABLE::check_virtual_columns_marked_for_read()
+{
+ if (vfield)
+ {
+ Field **vfield_ptr;
+ for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
+ {
+ Field *tmp_vfield= *vfield_ptr;
+ if (bitmap_is_set(read_set, tmp_vfield->field_index) &&
+ !tmp_vfield->vcol_info->stored_in_db)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+/**
+ Check if a stored virtual column field is marked for write
+
+ This can be used to check if any column that is part of a virtual
+ stored column is changed
+
+ @retval FALSE No stored virtual column is used
+ @retval TRUE At least one stored virtual column is used
+*/
+
+bool TABLE::check_virtual_columns_marked_for_write()
+{
+ if (vfield)
+ {
+ Field **vfield_ptr;
+ for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
+ {
+ Field *tmp_vfield= *vfield_ptr;
+ if (bitmap_is_set(write_set, tmp_vfield->field_index) &&
+ tmp_vfield->vcol_info->stored_in_db)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
/*
Mark fields used by check constraints.
This is done once for the TABLE_SHARE the first time the table is opened.
@@ -6688,6 +6898,7 @@ void TABLE::mark_default_fields_for_write(bool is_insert)
DBUG_VOID_RETURN;
}
+
void TABLE::move_fields(Field **ptr, const uchar *to, const uchar *from)
{
my_ptrdiff_t diff= to - from;
@@ -6763,6 +6974,14 @@ void TABLE::create_key_part_by_field(KEY_PART_INFO *key_part_info,
might be reused.
*/
key_part_info->store_length= key_part_info->length;
+ /*
+ For BIT fields null_bit is not set to 0 even if the field is defined
+ as NOT NULL, look at Field_bit::Field_bit
+ */
+ if (!field->real_maybe_null())
+ {
+ key_part_info->null_bit= 0;
+ }
/*
The total store length of the key part is the raw length of the field +
@@ -7166,7 +7385,7 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl)
(pos= find_type(&tbl->s->keynames, hint->key_name.str,
hint->key_name.length, 1)) <= 0)
{
- my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
+ my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias.str);
return 1;
}
@@ -7266,7 +7485,7 @@ void init_mdl_requests(TABLE_LIST *table_list)
{
for ( ; table_list ; table_list= table_list->next_global)
table_list->mdl_request.init(MDL_key::TABLE,
- table_list->db, table_list->table_name,
+ table_list->db.str, table_list->table_name.str,
table_list->lock_type >= TL_WRITE_ALLOW_WRITE ?
MDL_SHARED_WRITE : MDL_SHARED_READ,
MDL_TRANSACTION);
@@ -7402,7 +7621,6 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
swap_values= 1;
break;
case VCOL_UPDATE_FOR_DELETE:
- /* Fall trough */
case VCOL_UPDATE_FOR_WRITE:
update= bitmap_is_set(vcol_set, vf->field_index);
break;
@@ -7536,6 +7754,62 @@ int TABLE::update_default_fields(bool update_command, bool ignore_errors)
DBUG_RETURN(res);
}
+
+void TABLE::vers_update_fields()
+{
+ bitmap_set_bit(write_set, vers_start_field()->field_index);
+ bitmap_set_bit(write_set, vers_end_field()->field_index);
+
+ if (versioned(VERS_TIMESTAMP))
+ {
+ if (!vers_write)
+ return;
+ vers_start_field()->set_notnull();
+ if (vers_start_field()->store_timestamp(in_use->system_time,
+ in_use->system_time_sec_part))
+ DBUG_ASSERT(0);
+ }
+ else
+ {
+ vers_start_field()->set_notnull();
+ if (!vers_write)
+ return;
+ }
+
+ vers_end_field()->set_max();
+}
+
+
+void TABLE::vers_update_end()
+{
+ vers_end_field()->set_notnull();
+ if (vers_end_field()->store_timestamp(in_use->system_time,
+ in_use->system_time_sec_part))
+ DBUG_ASSERT(0);
+}
+
+
+bool TABLE_LIST::vers_vtmd_name(String& out) const
+{
+ static const char *vtmd_suffix= "_vtmd";
+ static const size_t vtmd_suffix_len= strlen(vtmd_suffix);
+ if (table_name.length > NAME_CHAR_LEN - vtmd_suffix_len)
+ {
+ my_printf_error(ER_VERS_VTMD_ERROR, "Table name is longer than %d characters", MYF(0),
+ int(NAME_CHAR_LEN - vtmd_suffix_len));
+ return true;
+ }
+ out.set(table_name.str, table_name.length, table_alias_charset);
+ if (out.append(vtmd_suffix, vtmd_suffix_len + 1))
+ {
+ my_message(ER_VERS_VTMD_ERROR, "Failed allocate VTMD name", MYF(0));
+ return true;
+ }
+ out.length(out.length() - 1);
+ return false;
+}
+
+
/**
Reset markers that fields are being updated
*/
@@ -8064,7 +8338,6 @@ bool TABLE_LIST::is_with_table()
return derived && derived->with_element;
}
-
uint TABLE_SHARE::actual_n_key_parts(THD *thd)
{
return use_ext_keys &&
@@ -8232,8 +8505,8 @@ Item* TABLE_LIST::build_pushable_cond_for_table(THD *thd, Item *cond)
if (!(item->used_tables() == tab_map))
continue;
Item_func_eq *eq= 0;
- Item *left_item_clone= left_item->build_clone(thd, thd->mem_root);
- Item *right_item_clone= item->build_clone(thd, thd->mem_root);
+ Item *left_item_clone= left_item->build_clone(thd);
+ Item *right_item_clone= item->build_clone(thd);
if (left_item_clone && right_item_clone)
{
left_item_clone->set_item_equal(NULL);
@@ -8263,7 +8536,7 @@ Item* TABLE_LIST::build_pushable_cond_for_table(THD *thd, Item *cond)
return new_cond;
}
else if (cond->get_extraction_flag() != NO_EXTRACTION_FL)
- return cond->build_clone(thd, thd->mem_root);
+ return cond->build_clone(thd);
return 0;
}
@@ -8281,15 +8554,399 @@ LEX_CSTRING *fk_option_name(enum_fk_option opt)
return names + opt;
}
+bool fk_modifies_child(enum_fk_option opt)
+{
+ static bool can_write[]= { false, false, true, true, false, true };
+ return can_write[opt];
+}
+
+enum TR_table::enabled TR_table::use_transaction_registry= TR_table::MAYBE;
+
+TR_table::TR_table(THD* _thd, bool rw) :
+ thd(_thd), open_tables_backup(NULL)
+{
+ init_one_table(&MYSQL_SCHEMA_NAME, &TRANSACTION_REG_NAME,
+ NULL, rw ? TL_WRITE : TL_READ);
+}
+
+bool TR_table::open()
+{
+ DBUG_ASSERT(!table);
+ open_tables_backup= new Open_tables_backup;
+ if (!open_tables_backup)
+ {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
+ return true;
+ }
+
+ All_tmp_tables_list *temporary_tables= thd->temporary_tables;
+ bool error= !open_log_table(thd, this, open_tables_backup);
+ thd->temporary_tables= temporary_tables;
+
+ if (use_transaction_registry == MAYBE)
+ error= check(error);
+
+ use_transaction_registry= error ? NO : YES;
+
+ return error;
+}
+
+TR_table::~TR_table()
+{
+ if (table)
+ {
+ thd->temporary_tables= NULL;
+ close_log_table(thd, open_tables_backup);
+ }
+ delete open_tables_backup;
+}
+
+void TR_table::store(uint field_id, ulonglong val)
+{
+ table->field[field_id]->store(val, true);
+ table->field[field_id]->set_notnull();
+}
+
+void TR_table::store(uint field_id, timeval ts)
+{
+ table->field[field_id]->store_timestamp(ts.tv_sec, ts.tv_usec);
+ table->field[field_id]->set_notnull();
+}
+
+enum_tx_isolation TR_table::iso_level() const
+{
+ enum_tx_isolation res= (enum_tx_isolation) ((*this)[FLD_ISO_LEVEL]->val_int() - 1);
+ DBUG_ASSERT(res <= ISO_SERIALIZABLE);
+ return res;
+}
+
+bool TR_table::update(ulonglong start_id, ulonglong end_id)
+{
+ if (!table && open())
+ return true;
+
+ timeval start_time= {thd->system_time, long(thd->system_time_sec_part)};
+ thd->set_start_time();
+ timeval end_time= {thd->system_time, long(thd->system_time_sec_part)};
+ store(FLD_TRX_ID, start_id);
+ store(FLD_COMMIT_ID, end_id);
+ store(FLD_BEGIN_TS, start_time);
+ store(FLD_COMMIT_TS, end_time);
+ store_iso_level(thd->tx_isolation);
+
+ int error= table->file->ha_write_row(table->record[0]);
+ if (error)
+ table->file->print_error(error, MYF(0));
+ return error;
+}
+
+#define newx new (thd->mem_root)
+bool TR_table::query(ulonglong trx_id)
+{
+ if (!table && open())
+ return false;
+ SQL_SELECT_auto select;
+ READ_RECORD info;
+ int error;
+ List<TABLE_LIST> dummy;
+ SELECT_LEX &slex= thd->lex->select_lex;
+ Name_resolution_context_backup backup(slex.context, *this);
+ Item *field= newx Item_field(thd, &slex.context, (*this)[FLD_TRX_ID]);
+ Item *value= newx Item_int(thd, trx_id);
+ COND *conds= newx Item_func_eq(thd, field, value);
+ if ((error= setup_conds(thd, this, dummy, &conds)))
+ return false;
+ select= make_select(table, 0, 0, conds, NULL, 0, &error);
+ if (error || !select)
+ return false;
+ // FIXME: (performance) force index 'transaction_id'
+ error= init_read_record(&info, thd, table, select, NULL,
+ 1 /* use_record_cache */, true /* print_error */,
+ false /* disable_rr_cache */);
+ while (!(error= info.read_record()) && !thd->killed && !thd->is_error())
+ {
+ if (select->skip_record(thd) > 0)
+ return true;
+ }
+ return false;
+}
+
+bool TR_table::query(MYSQL_TIME &commit_time, bool backwards)
+{
+ if (!table && open())
+ return false;
+ SQL_SELECT_auto select;
+ READ_RECORD info;
+ int error;
+ List<TABLE_LIST> dummy;
+ SELECT_LEX &slex= thd->lex->select_lex;
+ Name_resolution_context_backup backup(slex.context, *this);
+ Item *field= newx Item_field(thd, &slex.context, (*this)[FLD_COMMIT_TS]);
+ Item *value= newx Item_datetime_literal(thd, &commit_time, 6);
+ COND *conds;
+ if (backwards)
+ conds= newx Item_func_ge(thd, field, value);
+ else
+ conds= newx Item_func_le(thd, field, value);
+ if ((error= setup_conds(thd, this, dummy, &conds)))
+ return false;
+ // FIXME: (performance) force index 'commit_timestamp'
+ select= make_select(table, 0, 0, conds, NULL, 0, &error);
+ if (error || !select)
+ return false;
+ error= init_read_record(&info, thd, table, select, NULL,
+ 1 /* use_record_cache */, true /* print_error */,
+ false /* disable_rr_cache */);
+
+ // With PK by transaction_id the records are ordered by PK, so we have to
+ // scan TRT fully and collect min (backwards == true)
+ // or max (backwards == false) stats.
+ bool found= false;
+ MYSQL_TIME found_ts;
+ while (!(error= info.read_record()) && !thd->killed && !thd->is_error())
+ {
+ int res= select->skip_record(thd);
+ if (res > 0)
+ {
+ MYSQL_TIME commit_ts;
+ if ((*this)[FLD_COMMIT_TS]->get_date(&commit_ts, 0))
+ {
+ found= false;
+ break;
+ }
+ int c;
+ if (!found || ((c= my_time_compare(&commit_ts, &found_ts)) &&
+ (backwards ? c < 0 : c > 0)))
+ {
+ found_ts= commit_ts;
+ found= true;
+ // TODO: (performance) make ORDER DESC and break after first found.
+ // Otherwise it is O(n) scan (+copy)!
+ store_record(table, record[1]);
+ }
+ }
+ else if (res < 0)
+ {
+ found= false;
+ break;
+ }
+ }
+ if (found)
+ restore_record(table, record[1]);
+ return found;
+}
+#undef newx
+
+bool TR_table::query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0,
+ ulonglong commit_id1, enum_tx_isolation iso_level1,
+ ulonglong commit_id0)
+{
+ if (trx_id1 == trx_id0)
+ {
+ return false;
+ }
+
+ if (trx_id1 == ULONGLONG_MAX || trx_id0 == 0)
+ {
+ result= true;
+ return false;
+ }
+
+ if (!commit_id1)
+ {
+ if (!query(trx_id1))
+ return true;
+
+ commit_id1= (*this)[FLD_COMMIT_ID]->val_int();
+ iso_level1= iso_level();
+ }
+
+ if (!commit_id0)
+ {
+ if (!query(trx_id0))
+ return true;
+
+ commit_id0= (*this)[FLD_COMMIT_ID]->val_int();
+ }
+
+ // Trivial case: TX1 started after TX0 committed
+ if (trx_id1 > commit_id0
+ // Concurrent transactions: TX1 committed after TX0 and TX1 is read (un)committed
+ || (commit_id1 > commit_id0 && iso_level1 < ISO_REPEATABLE_READ))
+ {
+ result= true;
+ }
+ else // All other cases: TX1 does not see TX0
+ {
+ result= false;
+ }
+
+ return false;
+}
+
+void TR_table::warn_schema_incorrect(const char *reason)
+{
+ if (MYSQL_VERSION_ID == table->s->mysql_version)
+ {
+ sql_print_error("%`s.%`s schema is incorrect: %s.",
+ db.str, table_name.str, reason);
+ }
+ else
+ {
+ sql_print_error("%`s.%`s schema is incorrect: %s. Created with MariaDB %d, "
+ "now running %d.",
+ db.str, table_name.str, reason, MYSQL_VERSION_ID,
+ static_cast<int>(table->s->mysql_version));
+ }
+}
+
+bool TR_table::check(bool error)
+{
+ if (error)
+ {
+ sql_print_warning("%`s.%`s does not exist (open failed).", db.str,
+ table_name.str);
+ return true;
+ }
+
+ if (table->file->ht->db_type != DB_TYPE_INNODB)
+ {
+ warn_schema_incorrect("Wrong table engine (expected InnoDB)");
+ return true;
+ }
+
+#define WARN_SCHEMA(...) \
+ char reason[128]; \
+ snprintf(reason, 128, __VA_ARGS__); \
+ warn_schema_incorrect(reason);
+
+ if (table->s->fields != FIELD_COUNT)
+ {
+ WARN_SCHEMA("Wrong field count (expected %d)", FIELD_COUNT);
+ return true;
+ }
+
+ if (table->field[FLD_TRX_ID]->type() != MYSQL_TYPE_LONGLONG)
+ {
+ WARN_SCHEMA("Wrong field %d type (expected BIGINT UNSIGNED)", FLD_TRX_ID);
+ return true;
+ }
+
+ if (table->field[FLD_COMMIT_ID]->type() != MYSQL_TYPE_LONGLONG)
+ {
+ WARN_SCHEMA("Wrong field %d type (expected BIGINT UNSIGNED)", FLD_COMMIT_ID);
+ return true;
+ }
+
+ if (table->field[FLD_BEGIN_TS]->type() != MYSQL_TYPE_TIMESTAMP)
+ {
+ WARN_SCHEMA("Wrong field %d type (expected TIMESTAMP(6))", FLD_BEGIN_TS);
+ return true;
+ }
+
+ if (table->field[FLD_COMMIT_TS]->type() != MYSQL_TYPE_TIMESTAMP)
+ {
+ WARN_SCHEMA("Wrong field %d type (expected TIMESTAMP(6))", FLD_COMMIT_TS);
+ return true;
+ }
+
+ if (table->field[FLD_ISO_LEVEL]->type() != MYSQL_TYPE_STRING ||
+ !(table->field[FLD_ISO_LEVEL]->flags & ENUM_FLAG))
+ {
+ wrong_enum:
+ WARN_SCHEMA("Wrong field %d type (expected ENUM('READ-UNCOMMITTED', "
+ "'READ-COMMITTED', 'REPEATABLE-READ', 'SERIALIZABLE'))",
+ FLD_ISO_LEVEL);
+ return true;
+ }
+
+ Field_enum *iso_level= static_cast<Field_enum *>(table->field[FLD_ISO_LEVEL]);
+ st_typelib *typelib= iso_level->typelib;
+
+ if (typelib->count != 4)
+ goto wrong_enum;
+
+ if (strcmp(typelib->type_names[0], "READ-UNCOMMITTED") ||
+ strcmp(typelib->type_names[1], "READ-COMMITTED") ||
+ strcmp(typelib->type_names[2], "REPEATABLE-READ") ||
+ strcmp(typelib->type_names[3], "SERIALIZABLE"))
+ {
+ goto wrong_enum;
+ }
+
+ if (!table->key_info || !table->key_info->key_part)
+ goto wrong_pk;
+
+ if (strcmp(table->key_info->key_part->field->field_name.str, "transaction_id"))
+ {
+ wrong_pk:
+ WARN_SCHEMA("Wrong PRIMARY KEY (expected `transaction_id`)");
+ return true;
+ }
+
+ return false;
+}
+
+void vers_select_conds_t::resolve_units(bool timestamps_only)
+{
+ DBUG_ASSERT(type != SYSTEM_TIME_UNSPECIFIED);
+ DBUG_ASSERT(start.item);
+ start.resolve_unit(timestamps_only);
+ end.resolve_unit(timestamps_only);
+}
+
+void Vers_history_point::resolve_unit(bool timestamps_only)
+{
+ if (item && unit == VERS_UNDEFINED)
+ {
+ if (item->type() == Item::FIELD_ITEM || timestamps_only)
+ unit= VERS_TIMESTAMP;
+ else if (item->result_type() == INT_RESULT ||
+ item->result_type() == REAL_RESULT)
+ unit= VERS_TRX_ID;
+ else
+ unit= VERS_TIMESTAMP;
+ }
+}
+
+void Vers_history_point::fix_item()
+{
+ if (item && item->decimals == 0 && item->type() == Item::FUNC_ITEM &&
+ ((Item_func*)item)->functype() == Item_func::NOW_FUNC)
+ item->decimals= 6;
+}
+
+void Vers_history_point::print(String *str, enum_query_type query_type,
+ const char *prefix, size_t plen)
+{
+ const static LEX_CSTRING unit_type[]=
+ {
+ { STRING_WITH_LEN("") },
+ { STRING_WITH_LEN("TIMESTAMP ") },
+ { STRING_WITH_LEN("TRANSACTION ") }
+ };
+ str->append(prefix, plen);
+ str->append(unit_type + unit);
+ item->print(str, query_type);
+}
Field *TABLE::find_field_by_name(LEX_CSTRING *str) const
{
- uint length= str->length;
- for (Field **tmp= field; *tmp; tmp++)
+ Field **tmp;
+ size_t length= str->length;
+ if (s->name_hash.records)
{
- if ((*tmp)->field_name.length == length &&
- !lex_string_cmp(system_charset_info, &(*tmp)->field_name, str))
- return *tmp;
+ tmp= (Field**) my_hash_search(&s->name_hash, (uchar*) str->str, length);
+ return tmp ? field[tmp - s->field] : NULL;
+ }
+ else
+ {
+ for (tmp= field; *tmp; tmp++)
+ {
+ if ((*tmp)->field_name.length == length &&
+ !lex_string_cmp(system_charset_info, &(*tmp)->field_name, str))
+ return *tmp;
+ }
}
return NULL;
}
diff --git a/sql/table.h b/sql/table.h
index 19845efe40d..a180903d499 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -22,6 +22,7 @@
#include "mdl.h"
#include "datadict.h"
#include "sql_string.h" /* String */
+#include "lex_string.h"
#ifndef MYSQL_CLIENT
@@ -335,6 +336,19 @@ enum enum_vcol_update_mode
VCOL_UPDATE_FOR_REPLACE
};
+/* Field visibility enums */
+
+enum field_visibility_t {
+ VISIBLE= 0,
+ INVISIBLE_USER,
+ /* automatically added by the server. Can be queried explicitly
+ in SELECT, otherwise invisible from anything" */
+ INVISIBLE_SYSTEM,
+ INVISIBLE_FULL
+};
+
+#define INVISIBLE_MAX_BITS 3
+
/**
Category of table found in the table share.
@@ -561,7 +575,6 @@ struct TABLE_STATISTICS_CB
bool histograms_are_read;
};
-
/**
This structure is shared between different table objects. There is one
instance of table share per one table in the database.
@@ -623,6 +636,16 @@ struct TABLE_SHARE
LEX_CSTRING normalized_path; /* unpack_filename(path) */
LEX_CSTRING connect_string;
+ const char* orig_table_name; /* Original table name for this tmp table */
+ const char* error_table_name() const /* Get table name for error messages */
+ {
+ return tmp_table ? (
+ orig_table_name ?
+ orig_table_name :
+ "(temporary)") :
+ table_name.str;
+ }
+
/*
Set of keys in use, implemented as a Bitmap.
Excludes keys disabled by ALTER TABLE ... DISABLE KEYS.
@@ -668,6 +691,7 @@ struct TABLE_SHARE
uint blob_fields; /* number of blob fields */
uint varchar_fields; /* number of varchar fields */
uint default_fields; /* number of default fields */
+ uint visible_fields; /* number of visible fields */
uint default_expressions;
uint table_check_constraints, field_check_constraints;
@@ -737,6 +761,25 @@ struct TABLE_SHARE
#endif
/**
+ System versioning support.
+ */
+
+ vers_sys_type_t versioned;
+ bool vtmd;
+ uint16 row_start_field;
+ uint16 row_end_field;
+
+ Field *vers_start_field()
+ {
+ return field[row_start_field];
+ }
+
+ Field *vers_end_field()
+ {
+ return field[row_end_field];
+ }
+
+ /**
Cache the checked structure of this table.
The pointer data is used to describe the structure that
@@ -973,7 +1016,8 @@ private:
public:
Blob_mem_storage() :truncated_value(false)
{
- init_alloc_root(&storage, MAX_FIELD_VARCHARLENGTH, 0, MYF(0));
+ init_alloc_root(&storage, "Blob_mem_storage", MAX_FIELD_VARCHARLENGTH, 0,
+ MYF(0));
}
~ Blob_mem_storage()
{
@@ -994,7 +1038,7 @@ public:
@retval Pointer to the copied string.
@retval 0 if an error occurred.
*/
- char *store(const char *from, uint length)
+ char *store(const char *from, size_t length)
{
return (char*) memdup_root(&storage, from, length);
}
@@ -1022,6 +1066,8 @@ struct st_cond_statistic;
/* Bitmap of table's fields */
typedef Bitmap<MAX_FIELDS> Field_map;
+class SplM_opt_info;
+
struct TABLE
{
TABLE() {} /* Remove gcc warning */
@@ -1046,7 +1092,7 @@ public:
uint32 instance; /** Table cache instance this TABLE is belonging to */
THD *in_use; /* Which thread uses this */
- uchar *record[2]; /* Pointer to records */
+ uchar *record[3]; /* Pointer to records */
uchar *write_row_record; /* Used as optimisation in
THD::write_row */
uchar *insert_values; /* used by INSERT ... UPDATE */
@@ -1086,6 +1132,8 @@ public:
TABLE_LIST *pos_in_table_list;/* Element referring to this table */
/* Position in thd->locked_table_list under LOCK TABLES */
TABLE_LIST *pos_in_locked_tables;
+ /* Tables used in DEFAULT and CHECK CONSTRAINT (normally sequence tables) */
+ TABLE_LIST *internal_tables;
/*
Not-null for temporary tables only. Non-null values means this table is
@@ -1299,7 +1347,13 @@ public:
bool stats_is_read; /* Persistent statistics is read for the table */
bool histograms_are_read;
MDL_ticket *mdl_ticket;
- List<Field> splitting_fields;
+
+ /*
+ This is used only for potentially splittable materialized tables and it
+ points to the info used by the optimizer to apply splitting optimization
+ */
+ SplM_opt_info *spl_opt_info;
+ key_map keys_usable_for_splitting;
void init(THD *thd, TABLE_LIST *tl);
bool fill_item_list(List<Item> *item_list) const;
@@ -1319,6 +1373,8 @@ public:
void mark_columns_per_binlog_row_image(void);
bool mark_virtual_col(Field *field);
bool mark_virtual_columns_for_write(bool insert_fl);
+ bool check_virtual_columns_marked_for_read();
+ bool check_virtual_columns_marked_for_write();
void mark_default_fields_for_write(bool insert_fl);
void mark_columns_used_by_check_constraints(void);
void mark_check_constraint_columns_for_read(void);
@@ -1433,7 +1489,7 @@ public:
bool prepare_triggers_for_delete_stmt_or_event();
bool prepare_triggers_for_update_stmt_or_event();
- inline Field **field_to_fill();
+ Field **field_to_fill();
bool validate_default_values_of_unset_fields(THD *thd) const;
bool insert_all_rows_into_tmp_table(THD *thd,
@@ -1442,6 +1498,62 @@ public:
bool with_cleanup);
Field *find_field_by_name(LEX_CSTRING *str) const;
bool export_structure(THD *thd, class Row_definition_list *defs);
+ bool is_splittable() { return spl_opt_info != NULL; }
+ void set_spl_opt_info(SplM_opt_info *spl_info);
+ void deny_splitting();
+ void add_splitting_info_for_key_field(struct KEY_FIELD *key_field);
+
+ /**
+ System Versioning support
+ */
+ bool vers_write;
+
+ bool versioned() const
+ {
+ DBUG_ASSERT(s);
+ return s->versioned;
+ }
+
+ bool versioned(vers_sys_type_t type) const
+ {
+ DBUG_ASSERT(s);
+ DBUG_ASSERT(type);
+ return s->versioned == type;
+ }
+
+ bool versioned_write(vers_sys_type_t type= VERS_UNDEFINED) const
+ {
+ DBUG_ASSERT(versioned() || !vers_write);
+ return versioned(type) ? vers_write : false;
+ }
+
+ bool vers_vtmd() const
+ {
+ DBUG_ASSERT(s);
+ return s->versioned && s->vtmd;
+ }
+
+ Field *vers_start_field() const
+ {
+ DBUG_ASSERT(s && s->versioned);
+ return field[s->row_start_field];
+ }
+
+ Field *vers_end_field() const
+ {
+ DBUG_ASSERT(s && s->versioned);
+ return field[s->row_end_field];
+ }
+
+ ulonglong vers_start_id() const;
+ ulonglong vers_end_id() const;
+
+ int delete_row();
+ void vers_update_fields();
+ void vers_update_end();
+
+/** Number of additional fields used in versioned tables */
+#define VERSIONING_FIELDS 2
};
@@ -1501,6 +1613,7 @@ typedef struct st_foreign_key_info
} FOREIGN_KEY_INFO;
LEX_CSTRING *fk_option_name(enum_fk_option opt);
+bool fk_modifies_child(enum_fk_option opt);
#define MY_I_S_MAYBE_NULL 1U
#define MY_I_S_UNSIGNED 2U
@@ -1551,7 +1664,7 @@ typedef class Item COND;
typedef struct st_schema_table
{
- const char* table_name;
+ const char *table_name;
ST_FIELD_INFO *fields_info;
/* for FLUSH table_name */
int (*reset_table) ();
@@ -1673,8 +1786,8 @@ public:
LEX_CSTRING *name();
Item *create_item(THD *thd);
Field *field();
- const char *table_name();
- const char *db_name();
+ const char *safe_table_name();
+ const char *safe_db_name();
GRANT_INFO *grant();
};
@@ -1693,6 +1806,84 @@ class SJ_MATERIALIZATION_INFO;
class Index_hint;
class Item_in_subselect;
+/* trivial class, for %union in sql_yacc.yy */
+struct vers_history_point_t
+{
+ vers_sys_type_t unit;
+ Item *item;
+};
+
+class Vers_history_point : public vers_history_point_t
+{
+ void fix_item();
+
+public:
+ Vers_history_point() { empty(); }
+ Vers_history_point(vers_sys_type_t unit_arg, Item *item_arg)
+ {
+ unit= unit_arg;
+ item= item_arg;
+ fix_item();
+ }
+ Vers_history_point(vers_history_point_t p)
+ {
+ unit= p.unit;
+ item= p.item;
+ fix_item();
+ }
+ void empty() { unit= VERS_UNDEFINED; item= NULL; }
+ void print(String *str, enum_query_type, const char *prefix, size_t plen);
+ void resolve_unit(bool timestamps_only);
+};
+
+struct vers_select_conds_t
+{
+ vers_system_time_t type;
+ bool from_query:1;
+ bool used:1;
+ Vers_history_point start;
+ Vers_history_point end;
+
+ void empty()
+ {
+ type= SYSTEM_TIME_UNSPECIFIED;
+ used= from_query= false;
+ start.empty();
+ end.empty();
+ }
+
+ void init(vers_system_time_t _type,
+ Vers_history_point _start= Vers_history_point(),
+ Vers_history_point _end= Vers_history_point())
+ {
+ type= _type;
+ used= from_query= false;
+ start= _start;
+ end= _end;
+ }
+
+ void print(String *str, enum_query_type query_type);
+
+ bool init_from_sysvar(THD *thd);
+
+ bool operator== (vers_system_time_t b)
+ {
+ return type == b;
+ }
+ bool operator!= (vers_system_time_t b)
+ {
+ return type != b;
+ }
+ operator bool() const
+ {
+ return type != SYSTEM_TIME_UNSPECIFIED;
+ }
+ void resolve_units(bool timestamps_only);
+ bool user_defined() const
+ {
+ return !from_query && type != SYSTEM_TIME_UNSPECIFIED;
+ }
+};
/*
Table reference in the FROM clause.
@@ -1729,52 +1920,66 @@ class Item_in_subselect;
4) jtbm semi-join (jtbm_subselect != NULL)
*/
+/** last_leaf_for_name_resolutioning support. */
+
struct LEX;
class Index_hint;
struct TABLE_LIST
{
TABLE_LIST() {} /* Remove gcc warning */
+ enum prelocking_types
+ {
+ PRELOCK_NONE, PRELOCK_ROUTINE, PRELOCK_FK
+ };
+
/**
Prepare TABLE_LIST that consists of one table instance to use in
open_and_lock_tables
*/
- inline void init_one_table(const char *db_name_arg,
- size_t db_length_arg,
- const char *table_name_arg,
- size_t table_name_length_arg,
- const char *alias_arg,
+ inline void init_one_table(const LEX_CSTRING *db_arg,
+ const LEX_CSTRING *table_name_arg,
+ const LEX_CSTRING *alias_arg,
enum thr_lock_type lock_type_arg)
{
bzero((char*) this, sizeof(*this));
- db= (char*) db_name_arg;
- db_length= db_length_arg;
- table_name= (char*) table_name_arg;
- table_name_length= table_name_length_arg;
- alias= (char*) (alias_arg ? alias_arg : table_name_arg);
+ DBUG_ASSERT(!db_arg->str || strlen(db_arg->str) == db_arg->length);
+ DBUG_ASSERT(!table_name_arg->str || strlen(table_name_arg->str) == table_name_arg->length);
+ DBUG_ASSERT(!alias_arg || strlen(alias_arg->str) == alias_arg->length);
+ db= *db_arg;
+ table_name= *table_name_arg;
+ alias= (alias_arg ? *alias_arg : *table_name_arg);
lock_type= lock_type_arg;
- mdl_request.init(MDL_key::TABLE, db, table_name,
+ mdl_request.init(MDL_key::TABLE, db.str, table_name.str,
(lock_type >= TL_WRITE_ALLOW_WRITE) ?
MDL_SHARED_WRITE : MDL_SHARED_READ,
MDL_TRANSACTION);
}
- inline void init_one_table_for_prelocking(const char *db_name_arg,
- size_t db_length_arg,
- const char *table_name_arg,
- size_t table_name_length_arg,
- const char *alias_arg,
- enum thr_lock_type lock_type_arg,
- bool routine,
- TABLE_LIST *belong_to_view_arg,
- uint8 trg_event_map_arg,
- TABLE_LIST ***last_ptr)
+ TABLE_LIST(TABLE *table_arg, thr_lock_type lock_type)
{
- init_one_table(db_name_arg, db_length_arg, table_name_arg,
- table_name_length_arg, alias_arg, lock_type_arg);
+ DBUG_ASSERT(table_arg->s);
+ init_one_table(&table_arg->s->db, &table_arg->s->table_name,
+ NULL, lock_type);
+ table= table_arg;
+ }
+
+ inline void init_one_table_for_prelocking(const LEX_CSTRING *db_arg,
+ const LEX_CSTRING *table_name_arg,
+ const LEX_CSTRING *alias_arg,
+ enum thr_lock_type lock_type_arg,
+ prelocking_types prelocking_type,
+ TABLE_LIST *belong_to_view_arg,
+ uint8 trg_event_map_arg,
+ TABLE_LIST ***last_ptr)
+
+ {
+ init_one_table(db_arg, table_name_arg, alias_arg, lock_type_arg);
cacheable_table= 1;
- prelocking_placeholder= routine ? ROUTINE : FK;
- open_type= routine ? OT_TEMPORARY_OR_BASE : OT_BASE_ONLY;
+ prelocking_placeholder= prelocking_type;
+ open_type= (prelocking_type == PRELOCK_ROUTINE ?
+ OT_TEMPORARY_OR_BASE :
+ OT_BASE_ONLY);
belong_to_view= belong_to_view_arg;
trg_event_map= trg_event_map_arg;
@@ -1791,7 +1996,10 @@ struct TABLE_LIST
TABLE_LIST *next_local;
/* link in a global list of all queries tables */
TABLE_LIST *next_global, **prev_global;
- const char *db, *alias, *table_name, *schema_table_name;
+ LEX_CSTRING db;
+ LEX_CSTRING table_name;
+ LEX_CSTRING schema_table_name;
+ LEX_CSTRING alias;
const char *option; /* Used by cache index */
Item *on_expr; /* Used with outer join */
@@ -1922,7 +2130,9 @@ struct TABLE_LIST
st_select_lex_unit *derived; /* SELECT_LEX_UNIT of derived table */
With_element *with; /* With element defining this table (if any) */
/* Bitmap of the defining with element */
- table_map with_internal_reference_map;
+ table_map with_internal_reference_map;
+ TABLE_LIST * next_with_rec_ref;
+ bool is_derived_with_recursive_reference;
bool block_handle_derived;
ST_SCHEMA_TABLE *schema_table; /* Information_schema table */
st_select_lex *schema_select_lex;
@@ -2025,8 +2235,6 @@ struct TABLE_LIST
thr_lock_type lock_type;
uint outer_join; /* Which join type */
uint shared; /* Used in multi-upd */
- size_t db_length;
- size_t table_name_length;
bool updatable; /* VIEW/TABLE can be updated now */
bool straight; /* optimize with prev table */
bool updating; /* for replicate-do/ignore table */
@@ -2063,7 +2271,7 @@ struct TABLE_LIST
This TABLE_LIST object is just placeholder for prelocking, it will be
used for implicit LOCK TABLES only and won't be used in real statement.
*/
- enum { USER, ROUTINE, FK } prelocking_placeholder;
+ prelocking_types prelocking_placeholder;
/**
Indicates that if TABLE_LIST object corresponds to the table/view
which requires special handling.
@@ -2124,7 +2332,7 @@ struct TABLE_LIST
View definition (SELECT-statement) in the UTF-form.
*/
- LEX_STRING view_body_utf8;
+ LEX_CSTRING view_body_utf8;
/* End of view definition context. */
@@ -2186,6 +2394,12 @@ struct TABLE_LIST
TABLE_LIST *find_underlying_table(TABLE *table);
TABLE_LIST *first_leaf_for_name_resolution();
TABLE_LIST *last_leaf_for_name_resolution();
+
+ /* System Versioning */
+ vers_select_conds_t vers_conditions;
+ bool vers_vtmd_name(String &out) const;
+ bool vers_force_alias;
+
/**
@brief
Find the bottom in the chain of embedded table VIEWs.
@@ -2295,6 +2509,8 @@ struct TABLE_LIST
bool is_with_table();
bool is_recursive_with_table();
bool is_with_table_recursive_reference();
+ void register_as_derived_with_rec_ref(With_element *rec_elem);
+ bool is_nonrecursive_derived_with_rec_ref();
bool fill_recursive(THD *thd);
inline void set_view()
@@ -2312,6 +2528,9 @@ struct TABLE_LIST
inline void set_merged_derived()
{
DBUG_ENTER("set_merged_derived");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (alias.str ? alias.str : "<NULL>"),
+ get_unit()));
derived_type= ((derived_type & DTYPE_MASK) |
DTYPE_TABLE | DTYPE_MERGE);
set_check_merged();
@@ -2324,6 +2543,9 @@ struct TABLE_LIST
void set_materialized_derived()
{
DBUG_ENTER("set_materialized_derived");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (alias.str ? alias.str : "<NULL>"),
+ get_unit()));
derived_type= ((derived_type & (derived ? DTYPE_MASK : DTYPE_VIEW)) |
DTYPE_TABLE | DTYPE_MATERIALIZE);
set_check_materialized();
@@ -2351,7 +2573,7 @@ struct TABLE_LIST
@brief Returns the name of the database that the referenced table belongs
to.
*/
- const char *get_db_name() const { return view != NULL ? view_db.str : db; }
+ const char *get_db_name() const { return view != NULL ? view_db.str : db.str; }
/**
@brief Returns the name of the table that this TABLE_LIST represents.
@@ -2359,7 +2581,7 @@ struct TABLE_LIST
@details The unqualified table name or view name for a table or view,
respectively.
*/
- const char *get_table_name() const { return view != NULL ? view_name.str : table_name; }
+ const char *get_table_name() const { return view != NULL ? view_name.str : table_name.str; }
bool is_active_sjm();
bool is_jtbm() { return MY_TEST(jtbm_subselect != NULL); }
st_select_lex_unit *get_unit();
@@ -2574,7 +2796,7 @@ typedef struct st_changed_table_list
{
struct st_changed_table_list *next;
char *key;
- uint32 key_length;
+ size_t key_length;
} CHANGED_TABLE_LIST;
@@ -2664,9 +2886,10 @@ size_t max_row_length(TABLE *table, const uchar *data);
void init_mdl_requests(TABLE_LIST *table_list);
enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
- const char *alias, uint db_stat, uint prgflag,
+ const LEX_CSTRING *alias, uint db_stat, uint prgflag,
uint ha_open_flags, TABLE *outparam,
- bool is_create_table);
+ bool is_create_table,
+ List<String> *partitions_to_open= NULL);
bool fix_session_vcol_expr(THD *thd, Virtual_column_info *vcol);
bool fix_session_vcol_expr_for_read(THD *thd, Field *field,
Virtual_column_info *vcol);
@@ -2684,7 +2907,6 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share,
void open_table_error(TABLE_SHARE *share, enum open_frm_error error,
int db_errno);
void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);
-bool check_and_convert_db_name(LEX_STRING *db, bool preserve_lettercase);
bool check_db_name(LEX_STRING *db);
bool check_column_name(const char *name);
bool check_table_name(const char *name, size_t length, bool check_for_path_chars);
@@ -2699,7 +2921,7 @@ int closefrm(TABLE *table);
void free_blobs(TABLE *table);
void free_field_buffers_larger_than(TABLE *table, uint32 size);
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names);
-void append_unescaped(String *res, const char *pos, uint length);
+void append_unescaped(String *res, const char *pos, size_t length);
void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo,
HA_CREATE_INFO *create_info, uint keys, KEY *key_info);
const char *fn_frm_ext(const char *name);
@@ -2719,25 +2941,22 @@ extern LEX_CSTRING PERFORMANCE_SCHEMA_DB_NAME;
extern LEX_CSTRING GENERAL_LOG_NAME;
extern LEX_CSTRING SLOW_LOG_NAME;
+extern LEX_CSTRING TRANSACTION_REG_NAME;
/* information schema */
extern LEX_CSTRING INFORMATION_SCHEMA_NAME;
extern LEX_CSTRING MYSQL_SCHEMA_NAME;
-inline bool is_infoschema_db(const char *name, size_t len)
-{
- return (INFORMATION_SCHEMA_NAME.length == len &&
- !my_strcasecmp(system_charset_info,
- INFORMATION_SCHEMA_NAME.str, name));
-}
+/* table names */
+extern LEX_CSTRING MYSQL_USER_NAME, MYSQL_DB_NAME, MYSQL_PROC_NAME;
-inline bool is_infoschema_db(const char *name)
+inline bool is_infoschema_db(const LEX_CSTRING *name)
{
- return !my_strcasecmp(system_charset_info,
- INFORMATION_SCHEMA_NAME.str, name);
+ return (INFORMATION_SCHEMA_NAME.length == name->length &&
+ !my_strcasecmp(system_charset_info,
+ INFORMATION_SCHEMA_NAME.str, name->str));
}
-
inline void mark_as_null_row(TABLE *table)
{
table->null_row=1;
@@ -2747,6 +2966,150 @@ inline void mark_as_null_row(TABLE *table)
bool is_simple_order(ORDER *order);
+class Open_tables_backup;
+
+/** Transaction Registry Table (TRT)
+
+ This table holds transaction IDs, their corresponding times and other
+ transaction-related data which is used for transaction order resolution.
+ When versioned table marks its records lifetime with transaction IDs,
+ TRT is used to get their actual timestamps. */
+
+class TR_table: public TABLE_LIST
+{
+ THD *thd;
+ Open_tables_backup *open_tables_backup;
+
+public:
+ enum field_id_t {
+ FLD_TRX_ID= 0,
+ FLD_COMMIT_ID,
+ FLD_BEGIN_TS,
+ FLD_COMMIT_TS,
+ FLD_ISO_LEVEL,
+ FIELD_COUNT
+ };
+
+ enum enabled {NO, MAYBE, YES};
+ static enum enabled use_transaction_registry;
+
+ /**
+ @param[in,out] Thread handle
+ @param[in] Current transaction is read-write.
+ */
+ TR_table(THD *_thd, bool rw= false);
+ /**
+ Opens a transaction_registry table.
+
+ @retval true on error, false otherwise.
+ */
+ bool open();
+ ~TR_table();
+ /**
+ @retval current thd
+ */
+ THD *get_thd() const { return thd; }
+ /**
+ Stores value to internal transaction_registry TABLE object.
+
+ @param[in] field number in a TABLE
+ @param[in] value to store
+ */
+ void store(uint field_id, ulonglong val);
+ /**
+ Stores value to internal transaction_registry TABLE object.
+
+ @param[in] field number in a TABLE
+ @param[in] value to store
+ */
+ void store(uint field_id, timeval ts);
+ /**
+ Update the transaction_registry right before commit.
+ @param start_id transaction identifier at start
+ @param end_id transaction identifier at commit
+
+ @retval false on success
+ @retval true on error (the transaction must be rolled back)
+ */
+ bool update(ulonglong start_id, ulonglong end_id);
+ // return true if found; false if not found or error
+ bool query(ulonglong trx_id);
+ /**
+ Gets a row from transaction_registry with the closest commit_timestamp to
+ first argument. We can search for a value which a lesser or greater than
+ first argument. Also loads a row into an internal TABLE object.
+
+ @param[in] timestamp
+ @param[in] true if we search for a lesser timestamp, false if greater
+ @retval true if exists, false it not exists or an error occured
+ */
+ bool query(MYSQL_TIME &commit_time, bool backwards);
+ /**
+ Checks whether transaction1 sees transaction0.
+
+ @param[out] true if transaction1 sees transaction0, undefined on error and
+ when transaction1=transaction0 and false otherwise
+ @param[in] transaction_id of transaction1
+ @param[in] transaction_id of transaction0
+ @param[in] commit time of transaction1 or 0 if we want it to be queried
+ @param[in] isolation level (from handler.h) of transaction1
+ @param[in] commit time of transaction0 or 0 if we want it to be queried
+ @retval true on error, false otherwise
+ */
+ bool query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0,
+ ulonglong commit_id1= 0,
+ enum_tx_isolation iso_level1= ISO_READ_UNCOMMITTED,
+ ulonglong commit_id0= 0);
+
+ /**
+ @retval transaction isolation level of a row from internal TABLE object.
+ */
+ enum_tx_isolation iso_level() const;
+ /**
+ Stores transactioin isolation level to internal TABLE object.
+ */
+ void store_iso_level(enum_tx_isolation iso_level)
+ {
+ DBUG_ASSERT(iso_level <= ISO_SERIALIZABLE);
+ store(FLD_ISO_LEVEL, iso_level + 1);
+ }
+
+ /**
+ Writes a message to MariaDB log about incorrect transaction_registry schema.
+
+ @param[in] a message explained what's incorrect in schema
+ */
+ void warn_schema_incorrect(const char *reason);
+ /**
+ Checks whether transaction_registry table has a correct schema.
+
+ @retval true if schema is incorrect and false otherwise
+ */
+ bool check(bool error);
+
+ TABLE * operator-> () const
+ {
+ return table;
+ }
+ Field * operator[] (uint field_id) const
+ {
+ DBUG_ASSERT(field_id < FIELD_COUNT);
+ return table->field[field_id];
+ }
+ operator bool () const
+ {
+ return table;
+ }
+ bool operator== (const TABLE_LIST &subj) const
+ {
+ return (!cmp(&db, &subj.db) && !cmp(&table_name, &subj.table_name));
+ }
+ bool operator!= (const TABLE_LIST &subj) const
+ {
+ return !(*this == subj);
+ }
+};
+
#endif /* MYSQL_CLIENT */
#endif /* TABLE_INCLUDED */
diff --git a/sql/table_cache.cc b/sql/table_cache.cc
index f55e24f3b04..18ea7f83964 100644
--- a/sql/table_cache.cc
+++ b/sql/table_cache.cc
@@ -587,17 +587,17 @@ static void lf_alloc_destructor(uchar *arg)
}
-static void tdc_hash_initializer(LF_HASH *hash __attribute__((unused)),
+static void tdc_hash_initializer(LF_HASH *,
TDC_element *element, LEX_STRING *key)
{
memcpy(element->m_key, key->str, key->length);
- element->m_key_length= key->length;
+ element->m_key_length= (uint)key->length;
tdc_assert_clean_share(element);
}
static uchar *tdc_hash_key(const TDC_element *element, size_t *length,
- my_bool not_used __attribute__((unused)))
+ my_bool)
{
*length= element->m_key_length;
return (uchar*) element->m_key;
@@ -827,7 +827,7 @@ retry:
lf_hash_search_unpin(thd->tdc_hash_pins);
DBUG_ASSERT(element);
- if (!(share= alloc_table_share(tl->db, tl->table_name, key, key_length)))
+ if (!(share= alloc_table_share(tl->db.str, tl->table_name.str, key, key_length)))
{
lf_hash_delete(&tdc_hash, thd->tdc_hash_pins, key, key_length);
DBUG_RETURN(0);
@@ -1301,7 +1301,8 @@ int tdc_iterate(THD *thd, my_hash_walk_action action, void *argument,
if (no_dups)
{
- init_alloc_root(&no_dups_argument.root, 4096, 4096, MYF(alloc_flags));
+ init_alloc_root(&no_dups_argument.root, "no_dups", 4096, 4096,
+ MYF(alloc_flags));
my_hash_init(&no_dups_argument.hash, &my_charset_bin, tdc_records(), 0, 0,
eliminate_duplicates_get_key, 0, hash_flags);
no_dups_argument.action= action;
diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc
index 2c3cd0fe24e..4c6671cc2ae 100644
--- a/sql/temporary_tables.cc
+++ b/sql/temporary_tables.cc
@@ -65,7 +65,8 @@ TABLE *THD::create_and_open_tmp_table(handlerton *hton,
const char *path,
const char *db,
const char *table_name,
- bool open_in_engine)
+ bool open_in_engine,
+ bool open_internal_tables)
{
DBUG_ENTER("THD::create_and_open_tmp_table");
@@ -90,6 +91,15 @@ TABLE *THD::create_and_open_tmp_table(handlerton *hton,
/* Free the TMP_TABLE_SHARE. */
free_tmp_table_share(share, false);
+ DBUG_RETURN(0);
+ }
+
+ /* Open any related tables */
+ if (open_internal_tables && table->internal_tables &&
+ open_and_lock_internal_tables(table, open_in_engine))
+ {
+ drop_temporary_table(table, NULL, false);
+ DBUG_RETURN(0);
}
}
@@ -253,7 +263,7 @@ TMP_TABLE_SHARE *THD::find_tmp_table_share(const TABLE_LIST *tl)
@return Success A pointer to table share object
Failure NULL
*/
-TMP_TABLE_SHARE *THD::find_tmp_table_share(const char *key, uint key_length)
+TMP_TABLE_SHARE *THD::find_tmp_table_share(const char *key, size_t key_length)
{
DBUG_ENTER("THD::find_tmp_table_share");
@@ -318,7 +328,7 @@ TMP_TABLE_SHARE *THD::find_tmp_table_share(const char *key, uint key_length)
bool THD::open_temporary_table(TABLE_LIST *tl)
{
DBUG_ENTER("THD::open_temporary_table");
- DBUG_PRINT("enter", ("table: '%s'.'%s'", tl->db, tl->table_name));
+ DBUG_PRINT("enter", ("table: '%s'.'%s'", tl->db.str, tl->table_name.str));
TMP_TABLE_SHARE *share;
TABLE *table= NULL;
@@ -381,7 +391,7 @@ bool THD::open_temporary_table(TABLE_LIST *tl)
if (tl->open_type == OT_TEMPORARY_ONLY &&
tl->open_strategy == TABLE_LIST::OPEN_NORMAL)
{
- my_error(ER_NO_SUCH_TABLE, MYF(0), tl->db, tl->table_name);
+ my_error(ER_NO_SUCH_TABLE, MYF(0), tl->db.str, tl->table_name.str);
DBUG_RETURN(true);
}
DBUG_RETURN(false);
@@ -534,25 +544,21 @@ bool THD::close_temporary_tables()
true Error
*/
bool THD::rename_temporary_table(TABLE *table,
- const char *db,
- const char *table_name)
+ const LEX_CSTRING *db,
+ const LEX_CSTRING *table_name)
{
- DBUG_ENTER("THD::rename_temporary_table");
-
char *key;
uint key_length;
-
TABLE_SHARE *share= table->s;
+ DBUG_ENTER("THD::rename_temporary_table");
if (!(key= (char *) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
- {
DBUG_RETURN(true);
- }
/*
Temporary tables are renamed by simply changing their table definition key.
*/
- key_length= create_tmp_table_def_key(key, db, table_name);
+ key_length= create_tmp_table_def_key(key, db->str, table_name->str);
share->set_table_cache_key(key, key_length);
DBUG_RETURN(false);
@@ -1092,19 +1098,20 @@ done:
Failure NULL
*/
TABLE *THD::open_temporary_table(TMP_TABLE_SHARE *share,
- const char *alias,
+ const char *alias_arg,
bool open_in_engine)
{
+ TABLE *table;
+ LEX_CSTRING alias= {alias_arg, strlen(alias_arg) };
DBUG_ENTER("THD::open_temporary_table");
- TABLE *table;
if (!(table= (TABLE *) my_malloc(sizeof(TABLE), MYF(MY_WME))))
{
DBUG_RETURN(NULL); /* Out of memory */
}
- if (open_table_from_share(this, share, alias,
+ if (open_table_from_share(this, share, &alias,
open_in_engine ? (uint)HA_OPEN_KEYFILE : 0,
EXTRA_RECORD,
(ha_open_options |
@@ -1369,8 +1376,7 @@ bool THD::log_events_and_free_tmp_shares()
We are going to add ` around the table names and possible more
due to special characters.
*/
- append_identifier(this, &s_query, share->table_name.str,
- share->table_name.length);
+ append_identifier(this, &s_query, &share->table_name);
s_query.append(',');
rm_temporary_table(share->db_type(), share->path.str);
free_table_share(share);
diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc
index 74763e81b15..e0385c33fd8 100644
--- a/sql/thr_malloc.cc
+++ b/sql/thr_malloc.cc
@@ -58,10 +58,11 @@ extern "C" {
}
}
-void init_sql_alloc(MEM_ROOT *mem_root, uint block_size, uint pre_alloc,
- myf my_flags)
+void init_sql_alloc(MEM_ROOT *mem_root,
+ const char *area_name __attribute__((unused)),
+ uint block_size, uint pre_alloc, myf my_flags)
{
- init_alloc_root(mem_root, block_size, pre_alloc, my_flags);
+ init_alloc_root(mem_root, area_name, block_size, pre_alloc, my_flags);
mem_root->error_handler=sql_alloc_error_handler;
}
diff --git a/sql/thr_malloc.h b/sql/thr_malloc.h
index 574dc7966b0..b56b7175ed1 100644
--- a/sql/thr_malloc.h
+++ b/sql/thr_malloc.h
@@ -18,8 +18,8 @@
typedef struct st_mem_root MEM_ROOT;
-void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size,
- myf my_flags);
+void init_sql_alloc(MEM_ROOT *root, const char *area_name, uint block_size,
+ uint pre_alloc_size, myf my_flags);
char *sql_strmake_with_convert(THD *thd, const char *str, size_t arg_length,
CHARSET_INFO *from_cs,
size_t max_res_length,
diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc
index 486a829c645..a0d1532e31a 100644
--- a/sql/threadpool_common.cc
+++ b/sql/threadpool_common.cc
@@ -84,17 +84,13 @@ struct Worker_thread_context
void save()
{
-#ifdef HAVE_PSI_THREAD_INTERFACE
- psi_thread = PSI_THREAD_CALL(get_thread)();
-#endif
+ psi_thread = PSI_CALL_get_thread();
mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
}
void restore()
{
-#ifdef HAVE_PSI_THREAD_INTERFACE
- PSI_THREAD_CALL(set_thread)(psi_thread);
-#endif
+ PSI_CALL_set_thread(psi_thread);
pthread_setspecific(THR_KEY_mysys,mysys_var);
pthread_setspecific(THR_THD, 0);
}
@@ -144,9 +140,7 @@ static void thread_attach(THD* thd)
pthread_setspecific(THR_KEY_mysys,thd->mysys_var);
thd->thread_stack=(char*)&thd;
thd->store_globals();
-#ifdef HAVE_PSI_THREAD_INTERFACE
- PSI_THREAD_CALL(set_thread)(thd->event_scheduler.m_psi);
-#endif
+ PSI_CALL_set_thread(thd->event_scheduler.m_psi);
mysql_socket_set_thread_owner(thd->net.vio->mysql_socket);
}
@@ -250,14 +244,12 @@ static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data)
}
delete connect;
add_to_active_threads(thd);
- thd->mysys_var= mysys_var;
+ thd->set_mysys_var(mysys_var);
thd->event_scheduler.data= scheduler_data;
/* Create new PSI thread for use with the THD. */
-#ifdef HAVE_PSI_THREAD_INTERFACE
thd->event_scheduler.m_psi=
- PSI_THREAD_CALL(new_thread)(key_thread_one_connection, thd, thd->thread_id);
-#endif
+ PSI_CALL_new_thread(key_thread_one_connection, thd, thd->thread_id);
/* Login. */
@@ -477,11 +469,11 @@ void tp_timeout_handler(TP_connection *c)
if (c->state != TP_STATE_IDLE)
return;
THD *thd=c->thd;
- mysql_mutex_lock(&thd->LOCK_thd_data);
- thd->set_killed(KILL_WAIT_TIMEOUT);
+ mysql_mutex_lock(&thd->LOCK_thd_kill);
+ thd->set_killed_no_mutex(KILL_WAIT_TIMEOUT);
c->priority= TP_PRIORITY_HIGH;
post_kill_notification(thd);
- mysql_mutex_unlock(&thd->LOCK_thd_data);
+ mysql_mutex_unlock(&thd->LOCK_thd_kill);
}
diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc
index 3fdaff0504f..a306822b1f1 100644
--- a/sql/threadpool_generic.cc
+++ b/sql/threadpool_generic.cc
@@ -28,11 +28,19 @@
#endif
#ifdef HAVE_IOCP
-#define OPTIONAL_IO_POLL_READ_PARAM &overlapped
+#define OPTIONAL_IO_POLL_READ_PARAM this
#else
#define OPTIONAL_IO_POLL_READ_PARAM 0
#endif
+#ifdef _WIN32
+typedef HANDLE TP_file_handle;
+#else
+typedef int TP_file_handle;
+#define INVALID_HANDLE_VALUE -1
+#endif
+
+
#include <sql_connect.h>
#include <mysqld.h>
#include <debug_sync.h>
@@ -55,14 +63,11 @@ typedef OVERLAPPED_ENTRY native_event;
#error threadpool is not available on this platform
#endif
-#ifdef _MSC_VER
-#pragma warning (disable : 4312)
-#endif
-static void io_poll_close(int fd)
+static void io_poll_close(TP_file_handle fd)
{
#ifdef _WIN32
- CloseHandle((HANDLE)fd);
+ CloseHandle(fd);
#else
close(fd);
#endif
@@ -151,14 +156,17 @@ struct TP_connection_generic:public TP_connection
TP_connection_generic **prev_in_queue;
ulonglong abs_wait_timeout;
ulonglong dequeue_time;
+ TP_file_handle fd;
bool bound_to_poll_descriptor;
int waiting;
#ifdef HAVE_IOCP
OVERLAPPED overlapped;
#endif
+#ifdef _WIN32
+ enum_vio_type vio_type;
+#endif
};
-typedef TP_connection_generic TP_connection_generic;
typedef I_P_List<TP_connection_generic,
I_P_List_adapter<TP_connection_generic,
@@ -170,14 +178,14 @@ connection_queue_t;
const int NQUEUES=2; /* We have high and low priority queues*/
-struct thread_group_t
+struct MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) thread_group_t
{
mysql_mutex_t mutex;
connection_queue_t queues[NQUEUES];
worker_list_t waiting_threads;
worker_thread_t *listener;
pthread_attr_t *pthread_attr;
- int pollfd;
+ TP_file_handle pollfd;
int thread_count;
int active_thread_count;
int connection_count;
@@ -188,7 +196,7 @@ struct thread_group_t
int shutdown_pipe[2];
bool shutdown;
bool stalled;
-} MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE);
+};
static thread_group_t *all_groups;
static uint group_count;
@@ -245,11 +253,11 @@ static void print_pool_blocked_message(bool);
Creates an io_poll descriptor
On Linux: epoll_create()
- - io_poll_associate_fd(int poll_fd, int fd, void *data, void *opt)
+ - io_poll_associate_fd(int poll_fd, TP_file_handle fd, void *data, void *opt)
Associate file descriptor with io poll descriptor
On Linux : epoll_ctl(..EPOLL_CTL_ADD))
- - io_poll_disassociate_fd(int pollfd, int fd)
+ - io_poll_disassociate_fd(TP_file_handle pollfd, TP_file_handle fd)
Associate file descriptor with io poll descriptor
On Linux: epoll_ctl(..EPOLL_CTL_DEL)
@@ -259,7 +267,7 @@ static void print_pool_blocked_message(bool);
io_poll_associate_fd() was called.
On Linux : epoll_ctl(..EPOLL_CTL_MOD)
- - io_poll_wait (int pollfd, native_event *native_events, int maxevents,
+ - io_poll_wait (TP_file_handle pollfd, native_event *native_events, int maxevents,
int timeout_ms)
wait until one or more descriptors added with io_poll_associate_fd()
@@ -276,13 +284,13 @@ static void print_pool_blocked_message(bool);
/* Early 2.6 kernel did not have EPOLLRDHUP */
#define EPOLLRDHUP 0
#endif
-static int io_poll_create()
+static TP_file_handle io_poll_create()
{
return epoll_create(1);
}
-int io_poll_associate_fd(int pollfd, int fd, void *data, void*)
+int io_poll_associate_fd(TP_file_handle pollfd, TP_file_handle fd, void *data, void*)
{
struct epoll_event ev;
ev.data.u64= 0; /* Keep valgrind happy */
@@ -293,7 +301,7 @@ int io_poll_associate_fd(int pollfd, int fd, void *data, void*)
-int io_poll_start_read(int pollfd, int fd, void *data, void *)
+int io_poll_start_read(TP_file_handle pollfd, TP_file_handle fd, void *data, void *)
{
struct epoll_event ev;
ev.data.u64= 0; /* Keep valgrind happy */
@@ -302,7 +310,7 @@ int io_poll_start_read(int pollfd, int fd, void *data, void *)
return epoll_ctl(pollfd, EPOLL_CTL_MOD, fd, &ev);
}
-int io_poll_disassociate_fd(int pollfd, int fd)
+int io_poll_disassociate_fd(TP_file_handle pollfd, TP_file_handle fd)
{
struct epoll_event ev;
return epoll_ctl(pollfd, EPOLL_CTL_DEL, fd, &ev);
@@ -314,7 +322,7 @@ int io_poll_disassociate_fd(int pollfd, int fd)
NOTE - in case of EINTR, it restarts with original timeout. Since we use
either infinite or 0 timeouts, this is not critical
*/
-int io_poll_wait(int pollfd, native_event *native_events, int maxevents,
+int io_poll_wait(TP_file_handle pollfd, native_event *native_events, int maxevents,
int timeout_ms)
{
int ret;
@@ -347,12 +355,12 @@ static void *native_event_get_userdata(native_event *event)
#endif
-int io_poll_create()
+TP_file_handle io_poll_create()
{
return kqueue();
}
-int io_poll_start_read(int pollfd, int fd, void *data,void *)
+int io_poll_start_read(TP_file_handle pollfd, TP_file_handle fd, void *data,void *)
{
struct kevent ke;
MY_EV_SET(&ke, fd, EVFILT_READ, EV_ADD|EV_ONESHOT,
@@ -361,7 +369,7 @@ int io_poll_start_read(int pollfd, int fd, void *data,void *)
}
-int io_poll_associate_fd(int pollfd, int fd, void *data,void *)
+int io_poll_associate_fd(TP_file_handle pollfd, TP_file_handle fd, void *data,void *)
{
struct kevent ke;
MY_EV_SET(&ke, fd, EVFILT_READ, EV_ADD|EV_ONESHOT,
@@ -370,7 +378,7 @@ int io_poll_associate_fd(int pollfd, int fd, void *data,void *)
}
-int io_poll_disassociate_fd(int pollfd, int fd)
+int io_poll_disassociate_fd(TP_file_handle pollfd, TP_file_handle fd)
{
struct kevent ke;
MY_EV_SET(&ke,fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
@@ -378,7 +386,7 @@ int io_poll_disassociate_fd(int pollfd, int fd)
}
-int io_poll_wait(int pollfd, struct kevent *events, int maxevents, int timeout_ms)
+int io_poll_wait(TP_file_handle pollfd, struct kevent *events, int maxevents, int timeout_ms)
{
struct timespec ts;
int ret;
@@ -403,27 +411,27 @@ static void* native_event_get_userdata(native_event *event)
#elif defined (__sun)
-static int io_poll_create()
+static TP_file_handle io_poll_create()
{
return port_create();
}
-int io_poll_start_read(int pollfd, int fd, void *data, void *)
+int io_poll_start_read(TP_file_handle pollfd, TP_file_handle fd, void *data, void *)
{
return port_associate(pollfd, PORT_SOURCE_FD, fd, POLLIN, data);
}
-static int io_poll_associate_fd(int pollfd, int fd, void *data, void *)
+static int io_poll_associate_fd(TP_file_handle pollfd, TP_file_handle fd, void *data, void *)
{
return io_poll_start_read(pollfd, fd, data, 0);
}
-int io_poll_disassociate_fd(int pollfd, int fd)
+int io_poll_disassociate_fd(TP_file_handle pollfd, TP_file_handle fd)
{
return port_dissociate(pollfd, PORT_SOURCE_FD, fd);
}
-int io_poll_wait(int pollfd, native_event *events, int maxevents, int timeout_ms)
+int io_poll_wait(TP_file_handle pollfd, native_event *events, int maxevents, int timeout_ms)
{
struct timespec ts;
int ret;
@@ -451,25 +459,32 @@ static void* native_event_get_userdata(native_event *event)
#elif defined(HAVE_IOCP)
-static int io_poll_create()
+static TP_file_handle io_poll_create()
{
- HANDLE h= CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
- return PtrToInt(h);
+ return CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
}
-int io_poll_start_read(int pollfd, int fd, void *, void *opt)
+int io_poll_start_read(TP_file_handle pollfd, TP_file_handle fd, void *, void *opt)
{
- DWORD num_bytes = 0;
static char c;
+ TP_connection_generic *con= (TP_connection_generic *)opt;
+ OVERLAPPED *overlapped= &con->overlapped;
+ if (con->vio_type == VIO_TYPE_NAMEDPIPE)
+ {
+ if (ReadFile(fd, &c, 0, NULL, overlapped))
+ return 0;
+ }
+ else
+ {
+ WSABUF buf;
+ buf.buf= &c;
+ buf.len= 0;
+ DWORD flags=0;
- WSABUF buf;
- buf.buf= &c;
- buf.len= 0;
- DWORD flags=0;
-
- if (WSARecv((SOCKET)fd, &buf, 1, &num_bytes, &flags, (OVERLAPPED *)opt, NULL) == 0)
- return 0;
+ if (WSARecv((SOCKET)fd, &buf, 1,NULL, &flags,overlapped, NULL) == 0)
+ return 0;
+ }
if (GetLastError() == ERROR_IO_PENDING)
return 0;
@@ -478,26 +493,26 @@ int io_poll_start_read(int pollfd, int fd, void *, void *opt)
}
-static int io_poll_associate_fd(int pollfd, int fd, void *data, void *opt)
+static int io_poll_associate_fd(TP_file_handle pollfd, TP_file_handle fd, void *data, void *opt)
{
- HANDLE h= CreateIoCompletionPort(IntToPtr(fd), IntToPtr(pollfd), (ULONG_PTR)data, 0);
+ HANDLE h= CreateIoCompletionPort(fd, pollfd, (ULONG_PTR)data, 0);
if (!h)
return -1;
return io_poll_start_read(pollfd,fd, 0, opt);
}
-int io_poll_disassociate_fd(int pollfd, int fd)
+int io_poll_disassociate_fd(TP_file_handle pollfd, TP_file_handle fd)
{
/* Not possible to unbind/rebind file descriptor in IOCP. */
return 0;
}
-int io_poll_wait(int pollfd, native_event *events, int maxevents, int timeout_ms)
+int io_poll_wait(TP_file_handle pollfd, native_event *events, int maxevents, int timeout_ms)
{
ULONG n;
- BOOL ok = GetQueuedCompletionStatusEx((HANDLE)pollfd, events,
+ BOOL ok = GetQueuedCompletionStatusEx(pollfd, events,
maxevents, &n, timeout_ms, FALSE);
return ok ? (int)n : -1;
@@ -1038,7 +1053,7 @@ int thread_group_init(thread_group_t *thread_group, pthread_attr_t* thread_attr)
DBUG_ENTER("thread_group_init");
thread_group->pthread_attr = thread_attr;
mysql_mutex_init(key_group_mutex, &thread_group->mutex, NULL);
- thread_group->pollfd= -1;
+ thread_group->pollfd= INVALID_HANDLE_VALUE;
thread_group->shutdown_pipe[0]= -1;
thread_group->shutdown_pipe[1]= -1;
queue_init(thread_group);
@@ -1049,10 +1064,10 @@ int thread_group_init(thread_group_t *thread_group, pthread_attr_t* thread_attr)
void thread_group_destroy(thread_group_t *thread_group)
{
mysql_mutex_destroy(&thread_group->mutex);
- if (thread_group->pollfd != -1)
+ if (thread_group->pollfd != INVALID_HANDLE_VALUE)
{
io_poll_close(thread_group->pollfd);
- thread_group->pollfd= -1;
+ thread_group->pollfd= INVALID_HANDLE_VALUE;
}
#ifndef HAVE_IOCP
for(int i=0; i < 2; i++)
@@ -1109,7 +1124,7 @@ static int wake_listener(thread_group_t *thread_group)
if (write(thread_group->shutdown_pipe[1], &c, 1) < 0)
return -1;
#else
- PostQueuedCompletionStatus((HANDLE)thread_group->pollfd, 0, 0, 0);
+ PostQueuedCompletionStatus(thread_group->pollfd, 0, 0, 0);
#endif
return 0;
}
@@ -1432,6 +1447,16 @@ TP_connection_generic::TP_connection_generic(CONNECT *c):
, overlapped()
#endif
{
+ DBUG_ASSERT(c->vio);
+
+#ifdef _WIN32
+ vio_type= c->vio->type;
+ fd= (vio_type == VIO_TYPE_NAMEDPIPE) ?
+ c->vio->hPipe: (TP_file_handle)mysql_socket_getfd(c->vio->mysql_socket);
+#else
+ fd= mysql_socket_getfd(c->vio->mysql_socket);
+#endif
+
/* Assign connection to a group. */
thread_group_t *group=
&all_groups[c->thread_id%group_count];
@@ -1474,7 +1499,7 @@ void TP_connection_generic::set_io_timeout(int timeout_sec)
}
-
+#ifndef HAVE_IOCP
/**
Handle a (rare) special case,where connection needs to
migrate to a different group because group_count has changed
@@ -1486,7 +1511,6 @@ static int change_group(TP_connection_generic *c,
thread_group_t *new_group)
{
int ret= 0;
- int fd= (int)mysql_socket_getfd(c->thd->net.vio->mysql_socket);
DBUG_ASSERT(c->thread_group == old_group);
@@ -1494,7 +1518,7 @@ static int change_group(TP_connection_generic *c,
mysql_mutex_lock(&old_group->mutex);
if (c->bound_to_poll_descriptor)
{
- io_poll_disassociate_fd(old_group->pollfd,fd);
+ io_poll_disassociate_fd(old_group->pollfd,c->fd);
c->bound_to_poll_descriptor= false;
}
c->thread_group->connection_count--;
@@ -1510,12 +1534,10 @@ static int change_group(TP_connection_generic *c,
mysql_mutex_unlock(&new_group->mutex);
return ret;
}
-
+#endif
int TP_connection_generic::start_io()
-{
- int fd= (int)mysql_socket_getfd(thd->net.vio->mysql_socket);
-
+{
#ifndef HAVE_IOCP
/*
Usually, connection will stay in the same group for the entire
@@ -1666,17 +1688,16 @@ int TP_pool_generic::set_pool_size(uint size)
{
thread_group_t *group= &all_groups[i];
mysql_mutex_lock(&group->mutex);
- if (group->pollfd == -1)
+ if (group->pollfd == INVALID_HANDLE_VALUE)
{
group->pollfd= io_poll_create();
- success= (group->pollfd >= 0);
+ success= (group->pollfd != INVALID_HANDLE_VALUE);
if(!success)
{
sql_print_error("io_poll_create() failed, errno=%d\n", errno);
- break;
}
}
- mysql_mutex_unlock(&all_groups[i].mutex);
+ mysql_mutex_unlock(&group->mutex);
if (!success)
{
group_count= i;
@@ -1707,7 +1728,7 @@ int TP_pool_generic::set_stall_limit(uint limit)
int TP_pool_generic::get_idle_thread_count()
{
int sum=0;
- for (uint i= 0; i < threadpool_max_size && all_groups[i].pollfd >= 0; i++)
+ for (uint i= 0; i < threadpool_max_size && all_groups[i].pollfd != INVALID_HANDLE_VALUE; i++)
{
sum+= (all_groups[i].thread_count - all_groups[i].active_thread_count);
}
diff --git a/sql/threadpool_win.cc b/sql/threadpool_win.cc
index adaca08982f..012f7c5a439 100644
--- a/sql/threadpool_win.cc
+++ b/sql/threadpool_win.cc
@@ -92,9 +92,6 @@ static void CALLBACK work_callback(PTP_CALLBACK_INSTANCE instance, PVOID context
static void CALLBACK shm_read_callback(PTP_CALLBACK_INSTANCE instance,
PVOID Context, PTP_WAIT wait,TP_WAIT_RESULT wait_result);
-static void CALLBACK shm_close_callback(PTP_CALLBACK_INSTANCE instance,
- PVOID Context, PTP_WAIT wait,TP_WAIT_RESULT wait_result);
-
static void pre_callback(PVOID context, PTP_CALLBACK_INSTANCE instance);
/* Get current time as Windows time */
@@ -151,8 +148,8 @@ TP_connection_win::TP_connection_win(CONNECT *c) :
timeout(ULONGLONG_MAX),
callback_instance(0),
io(0),
- shm_read(0),
timer(0),
+ shm_read(0),
work(0)
{
}
diff --git a/sql/transaction.cc b/sql/transaction.cc
index cbd875e3114..d8d435e826a 100644
--- a/sql/transaction.cc
+++ b/sql/transaction.cc
@@ -21,10 +21,9 @@
#include "mariadb.h"
#include "sql_priv.h"
#include "transaction.h"
-#include "rpl_handler.h"
#include "debug_sync.h" // DEBUG_SYNC
#include "sql_acl.h"
-
+#include "semisync_master.h"
#ifndef EMBEDDED_LIBRARY
/**
@@ -318,9 +317,17 @@ bool trans_commit(THD *thd)
transaction, so the hooks for rollback will be called.
*/
if (res)
- (void) RUN_HOOK(transaction, after_rollback, (thd, FALSE));
+ {
+#ifdef HAVE_REPLICATION
+ repl_semisync_master.wait_after_rollback(thd, FALSE);
+#endif
+ }
else
- (void) RUN_HOOK(transaction, after_commit, (thd, FALSE));
+ {
+#ifdef HAVE_REPLICATION
+ repl_semisync_master.wait_after_commit(thd, FALSE);
+#endif
+ }
thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
thd->transaction.all.reset();
thd->lex->start_transaction_opt= 0;
@@ -413,7 +420,9 @@ bool trans_rollback(THD *thd)
~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY);
DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS"));
res= ha_rollback_trans(thd, TRUE);
- (void) RUN_HOOK(transaction, after_rollback, (thd, FALSE));
+#ifdef HAVE_REPLICATION
+ repl_semisync_master.wait_after_rollback(thd, FALSE);
+#endif
thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
/* Reset the binlog transaction marker */
thd->variables.option_bits&= ~OPTION_GTID_BEGIN;
@@ -526,9 +535,17 @@ bool trans_commit_stmt(THD *thd)
transaction, so the hooks for rollback will be called.
*/
if (res)
- (void) RUN_HOOK(transaction, after_rollback, (thd, FALSE));
+ {
+#ifdef HAVE_REPLICATION
+ repl_semisync_master.wait_after_rollback(thd, FALSE);
+#endif
+ }
else
- (void) RUN_HOOK(transaction, after_commit, (thd, FALSE));
+ {
+#ifdef HAVE_REPLICATION
+ repl_semisync_master.wait_after_commit(thd, FALSE);
+#endif
+ }
thd->transaction.stmt.reset();
@@ -567,7 +584,9 @@ bool trans_rollback_stmt(THD *thd)
trans_reset_one_shot_chistics(thd);
}
- (void) RUN_HOOK(transaction, after_rollback, (thd, FALSE));
+#ifdef HAVE_REPLICATION
+ repl_semisync_master.wait_after_rollback(thd, FALSE);
+#endif
thd->transaction.stmt.reset();
@@ -611,12 +630,8 @@ bool trans_savepoint(THD *thd, LEX_CSTRING name)
!opt_using_transactions)
DBUG_RETURN(FALSE);
- enum xa_states xa_state= thd->transaction.xid_state.xa_state;
- if (xa_state != XA_NOTR && xa_state != XA_ACTIVE)
- {
- my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]);
+ if (thd->transaction.xid_state.check_has_uncommitted_xa())
DBUG_RETURN(TRUE);
- }
sv= find_savepoint(thd, name);
@@ -634,7 +649,7 @@ bool trans_savepoint(THD *thd, LEX_CSTRING name)
}
newsv->name= strmake_root(&thd->transaction.mem_root, name.str, name.length);
- newsv->length= name.length;
+ newsv->length= (uint)name.length;
/*
if we'll get an error here, don't add new savepoint to the list.
@@ -691,12 +706,8 @@ bool trans_rollback_to_savepoint(THD *thd, LEX_CSTRING name)
DBUG_RETURN(TRUE);
}
- enum xa_states xa_state= thd->transaction.xid_state.xa_state;
- if (xa_state != XA_NOTR)
- {
- my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]);
+ if (thd->transaction.xid_state.check_has_uncommitted_xa())
DBUG_RETURN(TRUE);
- }
/**
Checking whether it is safe to release metadata locks acquired after
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 4581461f8b3..f7e2dcbefb8 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -166,7 +166,7 @@ static my_bool
tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage)
{
uchar *p;
- int read_from_file;
+ ssize_t read_from_file;
uint i;
MYSQL_FILE *file;
@@ -187,7 +187,7 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage)
uint ttisgmtcnt;
char *tzinfo_buf;
- read_from_file= mysql_file_fread(file, u.buf, sizeof(u.buf), MYF(MY_WME));
+ read_from_file= (ssize_t)mysql_file_fread(file, u.buf, sizeof(u.buf), MYF(MY_WME));
if (mysql_file_fclose(file, MYF(MY_WME)) != 0)
return 1;
@@ -1333,7 +1333,7 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg):
{
uint hours= abs((int)(offset / SECS_PER_HOUR));
uint minutes= abs((int)(offset % SECS_PER_HOUR / SECS_PER_MIN));
- ulong length= my_snprintf(name_buff, sizeof(name_buff), "%s%02d:%02d",
+ size_t length= my_snprintf(name_buff, sizeof(name_buff), "%s%02d:%02d",
(offset>=0) ? "+" : "-", hours, minutes);
name.set(name_buff, length, &my_charset_latin1);
}
@@ -1476,19 +1476,14 @@ static bool time_zone_tables_exist= 1;
for dynamical loading of time zone descriptions.
*/
-static const LEX_STRING tz_tables_names[MY_TZ_TABLES_COUNT]=
+static const LEX_CSTRING tz_tables_names[MY_TZ_TABLES_COUNT]=
{
- { C_STRING_WITH_LEN("time_zone_name")},
- { C_STRING_WITH_LEN("time_zone")},
- { C_STRING_WITH_LEN("time_zone_transition_type")},
- { C_STRING_WITH_LEN("time_zone_transition")}
+ { STRING_WITH_LEN("time_zone_name")},
+ { STRING_WITH_LEN("time_zone")},
+ { STRING_WITH_LEN("time_zone_transition_type")},
+ { STRING_WITH_LEN("time_zone_transition")}
};
-/* Name of database to which those tables belong. */
-
-static const LEX_STRING tz_tables_db_name= { C_STRING_WITH_LEN("mysql")};
-
-
class Tz_names_entry: public Sql_alloc
{
public:
@@ -1540,10 +1535,8 @@ tz_init_table_list(TABLE_LIST *tz_tabs)
for (int i= 0; i < MY_TZ_TABLES_COUNT; i++)
{
- tz_tabs[i].alias= tz_tabs[i].table_name= tz_tables_names[i].str;
- tz_tabs[i].table_name_length= tz_tables_names[i].length;
- tz_tabs[i].db= tz_tables_db_name.str;
- tz_tabs[i].db_length= tz_tables_db_name.length;
+ tz_tabs[i].alias= tz_tabs[i].table_name= tz_tables_names[i];
+ tz_tabs[i].db= MYSQL_SCHEMA_NAME;
tz_tabs[i].lock_type= TL_READ;
if (i != MY_TZ_TABLES_COUNT - 1)
@@ -1606,9 +1599,9 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
THD *thd;
TABLE_LIST tz_tables[1+MY_TZ_TABLES_COUNT];
TABLE *table;
+ const LEX_CSTRING tmp_table_name= { STRING_WITH_LEN("time_zone_leap_second") };
Tz_names_entry *tmp_tzname;
my_bool return_val= 1;
- char db[]= "mysql";
int res;
DBUG_ENTER("my_tz_init");
@@ -1638,7 +1631,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
my_hash_free(&tz_names);
goto end;
}
- init_sql_alloc(&tz_storage, 32 * 1024, 0, MYF(0));
+ init_sql_alloc(&tz_storage, "timezone_storage", 32 * 1024, 0, MYF(0));
mysql_mutex_init(key_tz_LOCK, &tz_LOCK, MY_MUTEX_INIT_FAST);
tz_inited= 1;
@@ -1669,13 +1662,10 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
leap seconds shared by all time zones.
*/
- thd->set_db(db, sizeof(db)-1);
+ thd->set_db(&MYSQL_SCHEMA_NAME);
bzero((char*) &tz_tables[0], sizeof(TABLE_LIST));
- tz_tables[0].alias= tz_tables[0].table_name=
- (char*)"time_zone_leap_second";
- tz_tables[0].table_name_length= 21;
- tz_tables[0].db= db;
- tz_tables[0].db_length= sizeof(db)-1;
+ tz_tables[0].alias= tz_tables[0].table_name= tmp_table_name;
+ tz_tables[0].db= MYSQL_SCHEMA_NAME;
tz_tables[0].lock_type= TL_READ;
tz_init_table_list(tz_tables+1);
@@ -2564,7 +2554,8 @@ scan_tz_dir(char * name_end, uint symlink_recursion_level, uint verbose)
}
else if (MY_S_ISREG(cur_dir->dir_entry[i].mystat->st_mode))
{
- init_alloc_root(&tz_storage, 32768, 0, MYF(MY_THREAD_SPECIFIC));
+ init_alloc_root(&tz_storage, "timezone_storage", 32768, 0,
+ MYF(MY_THREAD_SPECIFIC));
if (!tz_load(fullname, &tz_info, &tz_storage))
print_tz_as_sql(root_name_end + 1, &tz_info);
else
@@ -2738,7 +2729,7 @@ main(int argc, char **argv)
First argument is timezonefile.
The second is timezonename if opt_leap is not given
*/
- init_alloc_root(&tz_storage, 32768, 0, MYF(0));
+ init_alloc_root(&tz_storage, "timezone_storage", 32768, 0, MYF(0));
if (tz_load(argv[0], &tz_info, &tz_storage))
{
@@ -2812,7 +2803,7 @@ main(int argc, char **argv)
MY_INIT(argv[0]);
- init_alloc_root(&tz_storage, 32768, MYF(0));
+ init_alloc_root(&tz_storage, "timezone_storage", 32768, MYF(0));
/* let us set some well known timezone */
setenv("TZ", "MET", 1);
diff --git a/sql/tztime.h b/sql/tztime.h
index eb7d85c48b2..7ffc36011e1 100644
--- a/sql/tztime.h
+++ b/sql/tztime.h
@@ -89,6 +89,5 @@ extern my_time_t sec_since_epoch_TIME(MYSQL_TIME *t);
static const int MY_TZ_TABLES_COUNT= 4;
-
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */
#endif /* TZTIME_INCLUDED */
diff --git a/sql/udf_example.c b/sql/udf_example.c
index cc9a703373c..6db2b5e737a 100644
--- a/sql/udf_example.c
+++ b/sql/udf_example.c
@@ -112,6 +112,11 @@
**
*/
+#ifdef _WIN32
+/* Silence warning about deprecated functions , gethostbyname etc*/
+#define _WINSOCK_DEPRECATED_NO_WARNINGS
+#endif
+
#ifdef STANDARD
/* STANDARD is defined, don't use any mysql functions */
#include <stdlib.h>
@@ -139,10 +144,6 @@ typedef long long longlong;
#include <mysql.h>
#include <ctype.h>
-#ifdef _WIN32
-/* inet_aton needs winsock library */
-#pragma comment(lib, "ws2_32")
-#endif
#ifdef HAVE_DLOPEN
diff --git a/sql/uniques.cc b/sql/uniques.cc
index 894e959cace..8ed1ceda6a1 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -312,7 +312,7 @@ double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size,
{
size_t max_elements_in_tree;
size_t last_tree_elems;
- int n_full_trees; /* number of trees in unique - 1 */
+ size_t n_full_trees; /* number of trees in unique - 1 */
double result;
max_elements_in_tree= ((size_t) max_in_memory_size /
@@ -350,9 +350,9 @@ double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size,
/* Cost of merge */
if (intersect_fl)
key_size+= sizeof(element_count);
- double merge_cost= get_merge_many_buffs_cost(buffer, n_full_trees,
- max_elements_in_tree,
- last_tree_elems, key_size,
+ double merge_cost= get_merge_many_buffs_cost(buffer, (uint)n_full_trees,
+ (uint)max_elements_in_tree,
+ (uint)last_tree_elems, key_size,
compare_factor);
result += merge_cost;
/*
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 1ca0233552e..7bb08cfbf7b 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009, 2013, Monty Program Ab.
+ Copyright (c) 2009, 2018, 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
@@ -87,6 +87,68 @@ static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type,
return extra2_write(pos, type, reinterpret_cast<LEX_CSTRING *>(str));
}
+static uchar *extra2_write_field_properties(uchar *pos,
+ List<Create_field> &create_fields)
+{
+ List_iterator<Create_field> it(create_fields);
+ *pos++= EXTRA2_FIELD_FLAGS;
+ /*
+ always first 2 for field visibility
+ */
+ pos= extra2_write_len(pos, create_fields.elements);
+ while (Create_field *cf= it++)
+ {
+ uchar flags= cf->invisible;
+ if (cf->flags & VERS_UPDATE_UNVERSIONED_FLAG)
+ flags|= VERS_OPTIMIZED_UPDATE;
+ *pos++= flags;
+ }
+ return pos;
+}
+
+static const bool ROW_START = true;
+static const bool ROW_END = false;
+
+static inline
+uint16
+vers_get_field(HA_CREATE_INFO *create_info, List<Create_field> &create_fields, bool row_start)
+{
+ DBUG_ASSERT(create_info->versioned());
+
+ List_iterator<Create_field> it(create_fields);
+ Create_field *sql_field = NULL;
+
+ const LString_i row_field= row_start ? create_info->vers_info.as_row.start
+ : create_info->vers_info.as_row.end;
+ DBUG_ASSERT(row_field);
+
+ for (unsigned field_no = 0; (sql_field = it++); ++field_no)
+ {
+ if (row_field == sql_field->field_name)
+ {
+ DBUG_ASSERT(field_no <= uint16(~0U));
+ return uint16(field_no);
+ }
+ }
+
+ DBUG_ASSERT(0); /* Not Reachable */
+ return 0;
+}
+
+static inline
+bool has_extra2_field_flags(List<Create_field> &create_fields)
+{
+ List_iterator<Create_field> it(create_fields);
+ while (Create_field *f= it++)
+ {
+ if (f->invisible)
+ return true;
+ if (f->flags & VERS_UPDATE_UNVERSIONED_FLAG)
+ return true;
+ }
+ return false;
+}
+
/**
Create a frm (table definition) file
@@ -102,7 +164,7 @@ static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type,
or null LEX_CUSTRING (str==0) in case of an error.
*/
-LEX_CUSTRING build_frm_image(THD *thd, const char *table,
+LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING *table,
HA_CREATE_INFO *create_info,
List<Create_field> &create_fields,
uint keys, KEY *key_info, handler *db_file)
@@ -110,12 +172,13 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
LEX_CSTRING str_db_type;
uint reclength, key_info_length, i;
ulong key_buff_length;
- ulong filepos, data_offset;
+ size_t filepos;
+ ulong data_offset;
uint options_len;
uint gis_extra2_len= 0;
uchar fileinfo[FRM_HEADER_SIZE],forminfo[FRM_FORMINFO_SIZE];
const partition_info *part_info= IF_PARTITIONING(thd->work_part_info, 0);
- int error;
+ bool error;
uchar *frm_ptr, *pos;
LEX_CUSTRING frm= {0,0};
StringBuffer<MAX_FIELD_WIDTH> vcols;
@@ -138,7 +201,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
create_info->expression_length= vcols.length() + FRM_VCOL_NEW_BASE_SIZE;
error= pack_header(thd, forminfo, create_fields, create_info,
- data_offset, db_file);
+ (ulong)data_offset, db_file);
if (error)
DBUG_RETURN(frm);
@@ -147,7 +210,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
/* Calculate extra data segment length */
str_db_type= *hton_name(create_info->db_type);
/* str_db_type */
- create_info->extra_size= (2 + str_db_type.length +
+ create_info->extra_size= (uint)(2 + str_db_type.length +
2 + create_info->connect_string.length);
/*
Partition:
@@ -158,12 +221,12 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
*/
create_info->extra_size+= 6;
if (part_info)
- create_info->extra_size+= part_info->part_info_len;
+ create_info->extra_size+= (uint)part_info->part_info_len;
for (i= 0; i < keys; i++)
{
if (key_info[i].parser_name)
- create_info->extra_size+= key_info[i].parser_name->length + 1;
+ create_info->extra_size+= (uint)key_info[i].parser_name->length + 1;
}
options_len= engine_table_options_frm_length(create_info->option_list,
@@ -175,7 +238,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
DBUG_PRINT("info", ("Options length: %u", options_len));
if (validate_comment_length(thd, &create_info->comment, TABLE_COMMENT_MAXLEN,
- ER_TOO_LONG_TABLE_COMMENT, table))
+ ER_TOO_LONG_TABLE_COMMENT, table->str))
DBUG_RETURN(frm);
/*
If table comment is longer than TABLE_COMMENT_INLINE_MAXLEN bytes,
@@ -185,7 +248,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
if (create_info->comment.length > TABLE_COMMENT_INLINE_MAXLEN)
{
forminfo[46]=255;
- create_info->extra_size+= 2 + create_info->comment.length;
+ create_info->extra_size+= 2 + (uint)create_info->comment.length;
}
else
{
@@ -209,7 +272,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
prepare_frm_header(thd, reclength, fileinfo, create_info, keys, key_info);
/* one byte for a type, one or three for a length */
- uint extra2_size= 1 + 1 + create_info->tabledef_version.length;
+ size_t extra2_size= 1 + 1 + create_info->tabledef_version.length;
if (options_len)
extra2_size+= 1 + (options_len > 255 ? 3 : 1) + options_len;
@@ -219,6 +282,22 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
if (gis_extra2_len)
extra2_size+= 1 + (gis_extra2_len > 255 ? 3 : 1) + gis_extra2_len;
+ if (create_info->versioned())
+ {
+ extra2_size+= 1 + 1 + 2 * sizeof(uint16);
+ }
+
+ if (create_info->vtmd())
+ {
+ extra2_size+= 1 + 1 + 1;
+ }
+
+ bool has_extra2_field_flags_= has_extra2_field_flags(create_fields);
+ if (has_extra2_field_flags_)
+ {
+ extra2_size+= 1 + (create_fields.elements > 255 ? 3 : 1) +
+ create_fields.elements;
+ }
key_buff_length= uint4korr(fileinfo+47);
@@ -239,7 +318,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
if (frm.length > FRM_MAX_SIZE ||
create_info->expression_length > UINT_MAX32)
{
- my_error(ER_TABLE_DEFINITION_TOO_BIG, MYF(0), table);
+ my_error(ER_TABLE_DEFINITION_TOO_BIG, MYF(0), table->str);
DBUG_RETURN(frm);
}
@@ -275,11 +354,39 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
}
#endif /*HAVE_SPATIAL*/
+ if (create_info->versioned())
+ {
+ *pos++= EXTRA2_PERIOD_FOR_SYSTEM_TIME;
+ *pos++= 2 * sizeof(uint16);
+ int2store(pos, vers_get_field(create_info, create_fields, ROW_START));
+ pos+= sizeof(uint16);
+ int2store(pos, vers_get_field(create_info, create_fields, ROW_END));
+ pos+= sizeof(uint16);
+ }
+
+ if (create_info->vtmd())
+ {
+ *pos++= EXTRA2_VTMD;
+ *pos++= 1;
+ *pos++= 1;
+ }
+
+ if (has_extra2_field_flags_)
+ pos= extra2_write_field_properties(pos, create_fields);
+
int4store(pos, filepos); // end of the extra2 segment
pos+= 4;
DBUG_ASSERT(pos == frm_ptr + uint2korr(fileinfo+6));
key_info_length= pack_keys(pos, keys, key_info, data_offset);
+ if (key_info_length > UINT_MAX16)
+ {
+ my_printf_error(ER_CANT_CREATE_TABLE,
+ "Cannot create table %`s: index information is too long. "
+ "Decrease number of indexes or use shorter index names or shorter comments.",
+ MYF(0), table->str);
+ goto err;
+ }
int2store(forminfo+2, frm.length - filepos);
int4store(fileinfo+10, frm.length);
@@ -664,10 +771,10 @@ static bool pack_header(THD *thd, uchar *forminfo,
{
char *dst;
const char *src= field->save_interval->type_names[pos];
- uint hex_length;
+ size_t hex_length;
length= field->save_interval->type_lengths[pos];
hex_length= length * 2;
- field->interval->type_lengths[pos]= hex_length;
+ field->interval->type_lengths[pos]= (uint)hex_length;
field->interval->type_names[pos]= dst=
(char*) thd->alloc(hex_length + 1);
octet2hex(dst, src, length);
@@ -791,7 +898,8 @@ static bool pack_fields(uchar **buff_arg, List<Create_field> &create_fields,
ulong data_offset)
{
uchar *buff= *buff_arg;
- uint int_count, comment_length= 0;
+ uint int_count;
+ size_t comment_length= 0;
Create_field *field;
DBUG_ENTER("pack_fields");
@@ -960,7 +1068,8 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
field->unireg_check,
field->save_interval ? field->save_interval
: field->interval,
- &field->field_name);
+ &field->field_name,
+ field->flags);
if (!regfield)
{
error= 1;
diff --git a/sql/unireg.h b/sql/unireg.h
index b0cfb3841ef..277a1e3fb40 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -49,11 +49,14 @@
#define DEFAULT_ERRMSGS my_default_lc_messages->errmsgs->errmsgs
#define CURRENT_THD_ERRMSGS (current_thd)->variables.errmsgs
+#ifndef mysqld_error_find_printf_error_used
#define ER_DEFAULT(X) DEFAULT_ERRMSGS[((X)-ER_ERROR_FIRST) / ERRORS_PER_RANGE][(X)% ERRORS_PER_RANGE]
#define ER_THD(thd,X) ((thd)->variables.errmsgs[((X)-ER_ERROR_FIRST) / ERRORS_PER_RANGE][(X) % ERRORS_PER_RANGE])
#define ER(X) ER_THD(current_thd, (X))
+#endif
#define ER_THD_OR_DEFAULT(thd,X) ((thd) ? ER_THD(thd, (X)) : ER_DEFAULT(X))
+
#define ME_INFO (ME_HOLDTANG | ME_NOREFRESH)
#define ME_ERROR (ME_BELL | ME_NOREFRESH)
#define MYF_RW MYF(MY_WME+MY_NABP) /* Vid my_read & my_write */
@@ -172,17 +175,25 @@ enum extra2_frm_value_type {
EXTRA2_TABLEDEF_VERSION=0,
EXTRA2_DEFAULT_PART_ENGINE=1,
EXTRA2_GIS=2,
+ EXTRA2_PERIOD_FOR_SYSTEM_TIME=4,
+ EXTRA2_VTMD=8,
#define EXTRA2_ENGINE_IMPORTANT 128
EXTRA2_ENGINE_TABLEOPTS=128,
+ EXTRA2_FIELD_FLAGS=129
+};
+
+enum extra2_field_flags {
+ VERS_OPTIMIZED_UPDATE= 1 << INVISIBLE_MAX_BITS,
+ VERS_HIDDEN= 1 << (INVISIBLE_MAX_BITS + 1),
};
int rea_create_table(THD *thd, LEX_CUSTRING *frm,
const char *path, const char *db, const char *table_name,
HA_CREATE_INFO *create_info, handler *file,
bool no_ha_create_table);
-LEX_CUSTRING build_frm_image(THD *thd, const char *table,
+LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING *table,
HA_CREATE_INFO *create_info,
List<Create_field> &create_fields,
uint keys, KEY *key_info, handler *db_file);
diff --git a/sql/vers_string.h b/sql/vers_string.h
new file mode 100644
index 00000000000..0760613cd89
--- /dev/null
+++ b/sql/vers_string.h
@@ -0,0 +1,148 @@
+/*
+ Copyright (c) 2018, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef VERS_STRING_INCLUDED
+#define VERS_STRING_INCLUDED
+
+struct Compare_strncmp
+{
+ int operator()(const LEX_CSTRING& a, const LEX_CSTRING& b) const
+ {
+ return strncmp(a.str, b.str, a.length);
+ }
+ static CHARSET_INFO* charset()
+ {
+ return system_charset_info;
+ }
+};
+
+template <CHARSET_INFO* &CS= system_charset_info>
+struct Compare_my_strcasecmp
+{
+ int operator()(const LEX_CSTRING& a, const LEX_CSTRING& b) const
+ {
+ DBUG_ASSERT(a.str[a.length] == 0 && b.str[b.length] == 0);
+ return my_strcasecmp(CS, a.str, b.str);
+ }
+ static CHARSET_INFO* charset()
+ {
+ return CS;
+ }
+};
+
+typedef Compare_my_strcasecmp<files_charset_info> Compare_fs;
+typedef Compare_my_strcasecmp<table_alias_charset> Compare_t;
+
+template <class Storage= LEX_CSTRING>
+struct LEX_STRING_u : public Storage
+{
+ LEX_STRING_u()
+ {
+ Storage::str= NULL;
+ Storage::length= 0;
+ }
+ LEX_STRING_u(const char *_str, size_t _len, CHARSET_INFO *)
+ {
+ Storage::str= _str;
+ Storage::length= _len;
+ }
+ uint32 length() const
+ {
+ return (uint32)Storage::length;
+ }
+ const char *ptr() const
+ {
+ return Storage::str;
+ }
+ void set(const char *_str, size_t _len, CHARSET_INFO *)
+ {
+ Storage::str= _str;
+ Storage::length= _len;
+ }
+ const LEX_CSTRING& lex_cstring() const
+ {
+ return *this;
+ }
+ const LEX_STRING& lex_string() const
+ {
+ return *(LEX_STRING *)this;
+ }
+};
+
+template <class Compare= Compare_strncmp, class Storage= LEX_STRING_u<> >
+struct XString : public Storage
+{
+public:
+ XString() {}
+ XString(const char *_str, size_t _len) :
+ Storage(_str, _len, Compare::charset())
+ {
+ }
+ XString(const LEX_STRING src) :
+ Storage(src.str, src.length, Compare::charset())
+ {
+ }
+ XString(const LEX_CSTRING src) :
+ Storage(src.str, src.length, Compare::charset())
+ {
+ }
+ XString(const char *_str) :
+ Storage(_str, strlen(_str), Compare::charset())
+ {
+ }
+ bool operator== (const XString& b) const
+ {
+ return Storage::length() == b.length() && 0 == Compare()(this->lex_cstring(), b.lex_cstring());
+ }
+ bool operator!= (const XString& b) const
+ {
+ return !(*this == b);
+ }
+ operator const char* () const
+ {
+ return Storage::ptr();
+ }
+ operator LEX_CSTRING& () const
+ {
+ return this->lex_cstring();
+ }
+ operator LEX_STRING () const
+ {
+ LEX_STRING res;
+ res.str= const_cast<char *>(this->ptr());
+ res.length= this->length();
+ return res;
+ }
+ operator bool () const
+ {
+ return Storage::ptr() != NULL;
+ }
+};
+
+typedef XString<> LString;
+typedef XString<Compare_fs> LString_fs;
+typedef XString<Compare_my_strcasecmp<> > LString_i;
+
+typedef XString<Compare_strncmp, String> SString;
+typedef XString<Compare_fs, String> SString_fs;
+typedef XString<Compare_t, String> SString_t;
+
+
+#define XSTRING_WITH_LEN(X) (X).ptr(), (X).length()
+#define DB_WITH_LEN(X) (X).db.str, (X).db.length
+#define TABLE_NAME_WITH_LEN(X) (X).table_name.str, (X).table_name.length
+
+#endif // VERS_STRING_INCLUDED
diff --git a/sql/vers_utils.h b/sql/vers_utils.h
new file mode 100644
index 00000000000..52d01e36e8c
--- /dev/null
+++ b/sql/vers_utils.h
@@ -0,0 +1,81 @@
+#ifndef VERS_UTILS_INCLUDED
+#define VERS_UTILS_INCLUDED
+
+#include "table.h"
+#include "sql_class.h"
+#include "vers_string.h"
+
+class MDL_auto_lock
+{
+ THD *thd;
+ TABLE_LIST &table;
+ bool error;
+
+public:
+ MDL_auto_lock(THD *_thd, TABLE_LIST &_table) :
+ thd(_thd), table(_table)
+ {
+ DBUG_ASSERT(thd);
+ MDL_request protection_request;
+ if (thd->global_read_lock.can_acquire_protection())
+ {
+ error= true;
+ return;
+ }
+ protection_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE,
+ MDL_EXPLICIT);
+ error= thd->mdl_context.acquire_lock(&protection_request, thd->variables.lock_wait_timeout);
+ if (error)
+ return;
+
+ table.mdl_request.init(MDL_key::TABLE, table.db.str, table.table_name.str, MDL_EXCLUSIVE, MDL_EXPLICIT);
+ error= thd->mdl_context.acquire_lock(&table.mdl_request, thd->variables.lock_wait_timeout);
+ thd->mdl_context.release_lock(protection_request.ticket);
+ }
+ ~MDL_auto_lock()
+ {
+ if (!error)
+ {
+ DBUG_ASSERT(table.mdl_request.ticket);
+ thd->mdl_context.release_lock(table.mdl_request.ticket);
+ table.mdl_request.ticket= NULL;
+ }
+ }
+ bool acquire_error() const { return error; }
+};
+
+
+class Local_da : public Diagnostics_area
+{
+ THD *thd;
+ uint sql_error;
+ Diagnostics_area *saved_da;
+
+public:
+ Local_da(THD *_thd, uint _sql_error= 0) :
+ Diagnostics_area(_thd->query_id, false, true),
+ thd(_thd),
+ sql_error(_sql_error),
+ saved_da(_thd->get_stmt_da())
+ {
+ thd->set_stmt_da(this);
+ }
+ ~Local_da()
+ {
+ if (saved_da)
+ finish();
+ }
+ void finish()
+ {
+ DBUG_ASSERT(saved_da && thd);
+ thd->set_stmt_da(saved_da);
+ if (is_error())
+ my_error(sql_error ? sql_error : sql_errno(), MYF(0), message());
+ if (warn_count() > error_count())
+ saved_da->copy_non_errors_from_wi(thd, get_warning_info());
+ saved_da= NULL;
+ }
+};
+
+
+#endif // VERS_UTILS_INCLUDED
diff --git a/sql/vtmd.cc b/sql/vtmd.cc
new file mode 100644
index 00000000000..4ee43d61111
--- /dev/null
+++ b/sql/vtmd.cc
@@ -0,0 +1,683 @@
+#include "vtmd.h"
+#include "sql_base.h"
+#include "sql_class.h"
+#include "sql_handler.h" // mysql_ha_rm_tables()
+#include "sql_table.h"
+#include "sql_select.h"
+#include "table_cache.h" // tdc_remove_table()
+#include "key.h"
+#include "sql_show.h"
+#include "sql_parse.h"
+#include "sql_lex.h"
+#include "sp_head.h"
+#include "sp_rcontext.h"
+
+LString VERS_VTMD_TEMPLATE(C_STRING_WITH_LEN("vtmd_template"));
+
+bool
+VTMD_table::create(THD *thd)
+{
+ Table_specification_st create_info;
+ TABLE_LIST src_table, table;
+ create_info.init(DDL_options_st::OPT_LIKE);
+ create_info.options|= HA_VTMD;
+ create_info.alias.str= vtmd_name.ptr();
+ create_info.alias.length= vtmd_name.length();
+ table.init_one_table(&about.db, &create_info.alias, NULL, TL_READ);
+ src_table.init_one_table(&MYSQL_SCHEMA_NAME, &VERS_VTMD_TEMPLATE,
+ &VERS_VTMD_TEMPLATE, TL_READ);
+
+ Query_tables_backup backup(thd);
+ thd->lex->add_to_query_tables(&src_table);
+
+ MDL_auto_lock mdl_lock(thd, table);
+ if (mdl_lock.acquire_error())
+ return true;
+
+ Reprepare_observer *reprepare_observer= thd->m_reprepare_observer;
+ partition_info *work_part_info= thd->work_part_info;
+ thd->m_reprepare_observer= NULL;
+ thd->work_part_info= NULL;
+ bool rc= mysql_create_like_table(thd, &table, &src_table, &create_info);
+ thd->m_reprepare_observer= reprepare_observer;
+ thd->work_part_info= work_part_info;
+ return rc;
+}
+
+bool
+VTMD_table::find_record(ulonglong row_end, bool &found)
+{
+ int error;
+ key_buf_t key;
+ found= false;
+
+ DBUG_ASSERT(vtmd.table);
+
+ if (key.allocate(vtmd.table->s->max_unique_length))
+ return true;
+
+ DBUG_ASSERT(row_end);
+ vtmd.table->vers_end_field()->set_notnull();
+ vtmd.table->vers_end_field()->store(row_end, true);
+ key_copy(key, vtmd.table->record[0], vtmd.table->key_info + IDX_TRX_END, 0);
+
+ error= vtmd.table->file->ha_index_read_idx_map(vtmd.table->record[1], IDX_TRX_END,
+ key,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT);
+ if (error)
+ {
+ if (error == HA_ERR_RECORD_DELETED || error == HA_ERR_KEY_NOT_FOUND)
+ return false;
+ vtmd.table->file->print_error(error, MYF(0));
+ return true;
+ }
+
+ restore_record(vtmd.table, record[1]);
+
+ found= true;
+ return false;
+}
+
+
+bool
+VTMD_table::open(THD *thd, Local_da &local_da, bool *created)
+{
+ if (created)
+ *created= false;
+
+ if (0 == vtmd_name.length() && about.vers_vtmd_name(vtmd_name))
+ return true;
+
+ while (true) // max 2 iterations
+ {
+ LEX_CSTRING table_name= { vtmd_name.ptr(), vtmd_name.length() };
+ vtmd.init_one_table(&about.db, &table_name, NULL,
+ TL_WRITE_CONCURRENT_INSERT);
+
+ TABLE *res= open_log_table(thd, &vtmd, &open_tables_backup);
+ if (res)
+ return false;
+
+ if (created && !*created && local_da.is_error() &&
+ local_da.sql_errno() == ER_NO_SUCH_TABLE)
+ {
+ local_da.reset_diagnostics_area();
+ if (create(thd))
+ break;
+ *created= true;
+ }
+ else
+ break;
+ }
+ return true;
+}
+
+bool
+VTMD_table::update(THD *thd, const char* archive_name)
+{
+ bool result= true;
+ bool found= false;
+ bool created;
+ int error;
+ size_t an_len= 0;
+ ulonglong save_thd_options;
+ {
+ Local_da local_da(thd, ER_VERS_VTMD_ERROR);
+
+ save_thd_options= thd->variables.option_bits;
+ thd->variables.option_bits&= ~OPTION_BIN_LOG;
+
+ if (open(thd, local_da, &created))
+ goto open_error;
+
+ if (!vtmd.table->versioned())
+ {
+ my_message(ER_VERS_VTMD_ERROR, "VTMD is not versioned", MYF(0));
+ goto quit;
+ }
+
+ if (!created && find_record(ULONGLONG_MAX, found))
+ goto quit;
+
+ if ((error= vtmd.table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE)))
+ {
+ vtmd.table->file->print_error(error, MYF(0));
+ goto quit;
+ }
+
+ /* Honor next number columns if present */
+ vtmd.table->next_number_field= vtmd.table->found_next_number_field;
+
+ if (vtmd.table->s->fields != FIELD_COUNT)
+ {
+ my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` unexpected fields count: %d", MYF(0),
+ vtmd.table->s->db.str, vtmd.table->s->table_name.str, vtmd.table->s->fields);
+ goto quit;
+ }
+
+ if (archive_name)
+ {
+ an_len= strlen(archive_name);
+ vtmd.table->field[FLD_ARCHIVE_NAME]->store(archive_name, an_len, table_alias_charset);
+ vtmd.table->field[FLD_ARCHIVE_NAME]->set_notnull();
+ }
+ else
+ {
+ vtmd.table->field[FLD_ARCHIVE_NAME]->set_null();
+ }
+ vtmd.table->field[FLD_COL_RENAMES]->set_null();
+
+ if (found)
+ {
+ if (thd->lex->sql_command == SQLCOM_CREATE_TABLE)
+ {
+ my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` exists and not empty!", MYF(0),
+ vtmd.table->s->db.str, vtmd.table->s->table_name.str);
+ goto quit;
+ }
+ vtmd.table->mark_columns_needed_for_update(); // not needed?
+ if (archive_name)
+ {
+ vtmd.table->vers_write= false;
+ error= vtmd.table->file->ha_update_row(vtmd.table->record[1], vtmd.table->record[0]);
+ vtmd.table->vers_write= true;
+
+ if (!error)
+ {
+ if (thd->lex->sql_command == SQLCOM_DROP_TABLE)
+ {
+ error= vtmd.table->file->ha_delete_row(vtmd.table->record[0]);
+ }
+ else
+ {
+ DBUG_ASSERT(thd->lex->sql_command == SQLCOM_ALTER_TABLE);
+ ulonglong row_end= (ulonglong) vtmd.table->vers_start_field()->val_int();
+ store_record(vtmd.table, record[1]);
+ vtmd.table->field[FLD_NAME]->store(about.table_name.str, about.table_name.length, system_charset_info);
+ vtmd.table->field[FLD_NAME]->set_notnull();
+ vtmd.table->field[FLD_ARCHIVE_NAME]->set_null();
+ error= vtmd.table->file->ha_update_row(vtmd.table->record[1], vtmd.table->record[0]);
+ if (error)
+ goto err;
+
+ DBUG_ASSERT(an_len);
+ while (true)
+ { // fill archive_name of last sequential renames
+ bool found;
+ if (find_record(row_end, found))
+ goto quit;
+ if (!found || !vtmd.table->field[FLD_ARCHIVE_NAME]->is_null())
+ break;
+
+ store_record(vtmd.table, record[1]);
+ vtmd.table->field[FLD_ARCHIVE_NAME]->store(archive_name, an_len, table_alias_charset);
+ vtmd.table->field[FLD_ARCHIVE_NAME]->set_notnull();
+ vtmd.table->vers_write= false;
+ error= vtmd.table->file->ha_update_row(vtmd.table->record[1], vtmd.table->record[0]);
+ vtmd.table->vers_write= true;
+ if (error)
+ goto err;
+ row_end= (ulonglong) vtmd.table->vers_start_field()->val_int();
+ } // while (true)
+ } // else (thd->lex->sql_command != SQLCOM_DROP_TABLE)
+ } // if (!error)
+ } // if (archive_name)
+ else
+ {
+ vtmd.table->field[FLD_NAME]->store(about.table_name.str,
+ about.table_name.length,
+ system_charset_info);
+ vtmd.table->field[FLD_NAME]->set_notnull();
+ error= vtmd.table->file->ha_update_row(vtmd.table->record[1],
+ vtmd.table->record[0]);
+ }
+ } // if (found)
+ else
+ {
+ vtmd.table->field[FLD_NAME]->store(about.table_name.str,
+ about.table_name.length,
+ system_charset_info);
+ vtmd.table->field[FLD_NAME]->set_notnull();
+ vtmd.table->mark_columns_needed_for_insert(); // not needed?
+ error= vtmd.table->file->ha_write_row(vtmd.table->record[0]);
+ }
+
+ if (error)
+ {
+err:
+ vtmd.table->file->print_error(error, MYF(0));
+ }
+ else
+ result= local_da.is_error();
+ }
+
+quit:
+ if (!result && vtmd.table->file->ht->prepare_commit_versioned)
+ {
+ DBUG_ASSERT(TR_table::use_transaction_registry); // FIXME: disable survival mode while TRT is disabled
+ TR_table trt(thd, true);
+ ulonglong trx_start_id= 0;
+ ulonglong trx_end_id= vtmd.table->file->ht->prepare_commit_versioned(thd, &trx_start_id);
+ result= trx_end_id && trt.update(trx_start_id, trx_end_id);
+ }
+
+ close_log_table(thd, &open_tables_backup);
+
+open_error:
+ thd->variables.option_bits= save_thd_options;
+ return result;
+}
+
+bool
+VTMD_rename::move_archives(THD *thd, LString &new_db)
+{
+ int error;
+ bool rc= false;
+ SString_fs archive;
+ bool end_keyread= false;
+ bool index_end= false;
+ Open_tables_backup open_tables_backup;
+ key_buf_t key;
+
+ LEX_CSTRING table_name= { vtmd_name.ptr(), vtmd_name.length() };
+ vtmd.init_one_table(&about.db, &table_name, NULL, TL_READ);
+
+ TABLE *res= open_log_table(thd, &vtmd, &open_tables_backup);
+ if (!res)
+ return true;
+
+ if (key.allocate(vtmd.table->key_info[IDX_ARCHIVE_NAME].key_length))
+ {
+ close_log_table(thd, &open_tables_backup);
+ return true;
+ }
+
+ if ((error= vtmd.table->file->ha_start_keyread(IDX_ARCHIVE_NAME)))
+ goto err;
+ end_keyread= true;
+
+ if ((error= vtmd.table->file->ha_index_init(IDX_ARCHIVE_NAME, true)))
+ goto err;
+ index_end= true;
+
+ error= vtmd.table->file->ha_index_first(vtmd.table->record[0]);
+ while (!error)
+ {
+ if (!vtmd.table->field[FLD_ARCHIVE_NAME]->is_null())
+ {
+ vtmd.table->field[FLD_ARCHIVE_NAME]->val_str(&archive);
+ key_copy(key,
+ vtmd.table->record[0],
+ &vtmd.table->key_info[IDX_ARCHIVE_NAME],
+ vtmd.table->key_info[IDX_ARCHIVE_NAME].key_length,
+ false);
+ error= vtmd.table->file->ha_index_read_map(
+ vtmd.table->record[0],
+ key,
+ vtmd.table->key_info[IDX_ARCHIVE_NAME].ext_key_part_map,
+ HA_READ_PREFIX_LAST);
+ if (!error)
+ {
+ if ((rc= move_table(thd, archive, new_db)))
+ break;
+
+ error= vtmd.table->file->ha_index_next(vtmd.table->record[0]);
+ }
+ }
+ else
+ {
+ archive.length(0);
+ error= vtmd.table->file->ha_index_next(vtmd.table->record[0]);
+ }
+ }
+
+ if (error && error != HA_ERR_END_OF_FILE)
+ {
+err:
+ vtmd.table->file->print_error(error, MYF(0));
+ rc= true;
+ }
+
+ if (index_end)
+ vtmd.table->file->ha_index_end();
+ if (end_keyread)
+ vtmd.table->file->ha_end_keyread();
+
+ close_log_table(thd, &open_tables_backup);
+ return rc;
+}
+
+bool
+VTMD_rename::move_table(THD *thd, SString_fs &table_name, LString &new_db)
+{
+ handlerton *table_hton= NULL;
+ LEX_CSTRING tbl_name= { table_name.ptr(), table_name.length() };
+ LEX_CSTRING db_name= { new_db.ptr(), new_db.length() };
+ if (!ha_table_exists(thd, &about.db, &tbl_name, &table_hton) || !table_hton)
+ {
+ push_warning_printf( thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_VERS_VTMD_ERROR,
+ "`%s.%s` archive doesn't exist",
+ about.db.str, tbl_name.str);
+ return false;
+ }
+
+ if (ha_table_exists(thd, &db_name, &tbl_name))
+ {
+ my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` archive already exists!",
+ MYF(0),
+ db_name.str, tbl_name.str);
+ return true;
+ }
+
+ TABLE_LIST tl;
+ tl.init_one_table(&about.db, &tbl_name, NULL, TL_WRITE_ONLY);
+ tl.mdl_request.set_type(MDL_EXCLUSIVE);
+
+ mysql_ha_rm_tables(thd, &tl);
+ if (lock_table_names(thd, &tl, 0, thd->variables.lock_wait_timeout, 0))
+ return true;
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, about.db.str, table_name, false);
+
+ bool rc= mysql_rename_table(table_hton,
+ &about.db, &tbl_name, &db_name, &tbl_name,
+ NO_FK_CHECKS);
+ if (!rc)
+ query_cache_invalidate3(thd, &tl, 0);
+
+ return rc;
+}
+
+bool
+VTMD_rename::try_rename(THD *thd, LString new_db, LString new_alias, const char *archive_name)
+{
+ Local_da local_da(thd, ER_VERS_VTMD_ERROR);
+ TABLE_LIST new_table;
+
+ if (check_exists(thd))
+ return true;
+
+ LEX_CSTRING new_db_name= { XSTRING_WITH_LEN(new_db) };
+ LEX_CSTRING new_tbl_name= { XSTRING_WITH_LEN(new_alias) };
+
+ new_table.init_one_table(&new_db_name, &new_tbl_name, NULL, TL_READ);
+
+ if (new_table.vers_vtmd_name(vtmd_new_name))
+ return true;
+
+ LEX_CSTRING new_name= { vtmd_new_name.ptr(), vtmd_new_name.length() };
+
+ if (ha_table_exists(thd, &new_db_name, &new_name))
+ {
+ if (exists)
+ {
+ my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` table already exists!",
+ MYF(0),
+ new_db_name.str, new_name.str);
+ return true;
+ }
+ push_warning_printf( thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_VERS_VTMD_ERROR,
+ "`%s.%s` table already exists!",
+ new_db_name.str, new_name.str);
+ return false;
+ }
+
+ if (!exists)
+ return false;
+
+ bool same_db= true;
+ if (LString_fs(DB_WITH_LEN(about)) != LString_fs(new_db))
+ {
+ // Move archives before VTMD so if the operation is interrupted, it could be continued.
+ if (move_archives(thd, new_db))
+ return true;
+ same_db= false;
+ }
+
+ TABLE_LIST vtmd_tl;
+ LEX_CSTRING table_name= { vtmd_name.ptr(), vtmd_name.length() };
+ vtmd_tl.init_one_table(&about.db, &table_name, NULL, TL_WRITE_ONLY);
+ vtmd_tl.mdl_request.set_type(MDL_EXCLUSIVE);
+
+ mysql_ha_rm_tables(thd, &vtmd_tl);
+ if (lock_table_names(thd, &vtmd_tl, 0, thd->variables.lock_wait_timeout, 0))
+ return true;
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, about.db.str, vtmd_name, false);
+ if (local_da.is_error()) // just safety check
+ return true;
+ bool rc= mysql_rename_table(hton, &about.db, &table_name,
+ &new_db_name, &new_name,
+ NO_FK_CHECKS);
+ if (!rc)
+ {
+ query_cache_invalidate3(thd, &vtmd_tl, 0);
+ if (same_db || archive_name ||
+ new_alias != LString(TABLE_NAME_WITH_LEN(about)))
+ {
+ local_da.finish();
+ VTMD_table new_vtmd(new_table);
+ rc= new_vtmd.update(thd, archive_name);
+ }
+ }
+ return rc;
+}
+
+bool
+VTMD_rename::revert_rename(THD *thd, LString new_db)
+{
+ DBUG_ASSERT(hton);
+ Local_da local_da(thd, ER_VERS_VTMD_ERROR);
+
+ TABLE_LIST vtmd_tl;
+ LEX_CSTRING new_name= { XSTRING_WITH_LEN(vtmd_new_name) };
+ LEX_CSTRING v_name= { XSTRING_WITH_LEN(vtmd_name) };
+ LEX_CSTRING new_db_name= { XSTRING_WITH_LEN(new_db) };
+
+ vtmd_tl.init_one_table(&about.db, &new_name, NULL, TL_WRITE_ONLY);
+ vtmd_tl.mdl_request.set_type(MDL_EXCLUSIVE);
+ mysql_ha_rm_tables(thd, &vtmd_tl);
+ if (lock_table_names(thd, &vtmd_tl, 0, thd->variables.lock_wait_timeout, 0))
+ return true;
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, new_db, vtmd_new_name, false);
+
+ bool rc= mysql_rename_table(hton, &new_db_name, &new_name,
+ &new_db_name, &v_name,
+ NO_FK_CHECKS);
+
+ if (!rc)
+ query_cache_invalidate3(thd, &vtmd_tl, 0);
+
+ return rc;
+}
+
+void
+VTMD_table::archive_name(
+ THD* thd,
+ const char* table_name,
+ char* new_name,
+ size_t new_name_size)
+{
+ const MYSQL_TIME now= thd->query_start_TIME();
+ my_snprintf(new_name, new_name_size, "%s_%04d%02d%02d_%02d%02d%02d_%06lu",
+ table_name, now.year, now.month, now.day, now.hour, now.minute,
+ now.second, (ulong) now.second_part);
+}
+
+bool
+VTMD_table::find_archive_name(THD *thd, String &out)
+{
+ READ_RECORD info;
+ int error;
+ SQL_SELECT *select= NULL;
+ COND *conds= NULL;
+ List<TABLE_LIST> dummy;
+ SELECT_LEX &select_lex= thd->lex->select_lex;
+
+ Local_da local_da(thd, ER_VERS_VTMD_ERROR);
+ if (open(thd, local_da))
+ return true;
+
+ Name_resolution_context &ctx= thd->lex->select_lex.context;
+ TABLE_LIST *table_list= ctx.table_list;
+ TABLE_LIST *first_name_resolution_table= ctx.first_name_resolution_table;
+ table_map map = vtmd.table->map;
+ ctx.table_list= &vtmd;
+ ctx.first_name_resolution_table= &vtmd;
+ vtmd.table->map= 1;
+
+ vtmd.vers_conditions= about.vers_conditions;
+ if ((error= select_lex.vers_setup_conds(thd, &vtmd, &conds)) ||
+ (error= setup_conds(thd, &vtmd, dummy, &conds)))
+ goto err;
+
+ select= make_select(vtmd.table, 0, 0, conds, NULL, 0, &error);
+ if (error)
+ goto loc_err;
+
+ error= init_read_record(&info, thd, vtmd.table, select, NULL,
+ 1 /* use_record_cache */, true /* print_error */,
+ false /* disable_rr_cache */);
+ if (error)
+ goto loc_err;
+
+ while (!(error= info.read_record()) && !thd->killed && !thd->is_error())
+ {
+ if (!select || select->skip_record(thd) > 0)
+ {
+ vtmd.table->field[FLD_ARCHIVE_NAME]->val_str(&out);
+ break;
+ }
+ }
+
+ if (error < 0)
+ my_error(ER_NO_SUCH_TABLE, MYF(0), about.db.str, about.alias.str);
+
+loc_err:
+ end_read_record(&info);
+err:
+ delete select;
+ ctx.table_list= table_list;
+ ctx.first_name_resolution_table= first_name_resolution_table;
+ vtmd.table->map= map;
+ close_log_table(thd, &open_tables_backup);
+ DBUG_ASSERT(!error || local_da.is_error());
+ return error;
+}
+
+static
+bool
+get_vtmd_tables(THD *thd, const char *db,
+ size_t db_length, Dynamic_array<LEX_CSTRING *> &table_names)
+{
+ LOOKUP_FIELD_VALUES lookup_field_values= {
+ {db, db_length}, {C_STRING_WITH_LEN("%_vtmd")}, false, true};
+
+ int res= make_table_name_list(thd, &table_names, thd->lex, &lookup_field_values,
+ &lookup_field_values.db_value);
+
+ return res;
+}
+
+bool
+VTMD_table::get_archive_tables(THD *thd, const char *db, size_t db_length,
+ Dynamic_array<String> &result)
+{
+ Dynamic_array<LEX_CSTRING *> vtmd_tables;
+ if (get_vtmd_tables(thd, db, db_length, vtmd_tables))
+ return true;
+
+ Local_da local_da(thd, ER_VERS_VTMD_ERROR);
+ for (uint i= 0; i < vtmd_tables.elements(); i++)
+ {
+ LEX_CSTRING table_name= *vtmd_tables.at(i);
+ Open_tables_backup open_tables_backup;
+ TABLE_LIST table_list;
+ LEX_CSTRING db_name= {db, db_length};
+ table_list.init_one_table(&db_name, &table_name, NULL, TL_READ);
+
+ TABLE *table= open_log_table(thd, &table_list, &open_tables_backup);
+ if (!table || !table->vers_vtmd())
+ {
+ if (table)
+ close_log_table(thd, &open_tables_backup);
+ else
+ {
+ if (local_da.is_error() && local_da.sql_errno() == ER_NOT_LOG_TABLE)
+ local_da.reset_diagnostics_area();
+ else
+ return true;
+ }
+ push_warning_printf(
+ thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_VERS_VTMD_ERROR,
+ "Table `%s.%s` is not a VTMD table",
+ db, table_name.str);
+ continue;
+ }
+
+ READ_RECORD read_record;
+ int error= 0;
+ SQL_SELECT *sql_select= make_select(table, 0, 0, NULL, NULL, 0, &error);
+ if (error)
+ {
+ close_log_table(thd, &open_tables_backup);
+ return true;
+ }
+ error= init_read_record(&read_record, thd, table, sql_select, NULL, 1, 1, false);
+ if (error)
+ {
+ delete sql_select;
+ close_log_table(thd, &open_tables_backup);
+ return true;
+ }
+
+ while (!(error= read_record.read_record()))
+ {
+ Field *field= table->field[FLD_ARCHIVE_NAME];
+ if (field->is_null())
+ continue;
+
+ String archive_name;
+ field->val_str(&archive_name);
+ archive_name.set_ascii(strmake_root(thd->mem_root, archive_name.c_ptr(),
+ archive_name.length()),
+ archive_name.length());
+ result.push(archive_name);
+ }
+ // check for EOF
+ if (!thd->is_error())
+ error= 0;
+
+ end_read_record(&read_record);
+ delete sql_select;
+ close_log_table(thd, &open_tables_backup);
+ }
+
+ return false;
+}
+
+bool VTMD_table::setup_select(THD* thd)
+{
+ SString archive_name;
+ if (find_archive_name(thd, archive_name))
+ return true;
+
+ if (archive_name.length() == 0)
+ return false;
+
+ thd->make_lex_string(&about.table_name, archive_name.ptr(),
+ archive_name.length());
+ DBUG_ASSERT(!about.mdl_request.ticket);
+ about.mdl_request.init(MDL_key::TABLE, about.db.str, about.table_name.str,
+ about.mdl_request.type, about.mdl_request.duration);
+ about.vers_force_alias= true;
+ // Since we modified SELECT_LEX::table_list, we need to invalidate current SP
+ if (thd->spcont)
+ {
+ DBUG_ASSERT(thd->spcont->m_sp);
+ thd->spcont->m_sp->set_sp_cache_version(0);
+ }
+ return false;
+}
diff --git a/sql/vtmd.h b/sql/vtmd.h
new file mode 100644
index 00000000000..ea5450a8841
--- /dev/null
+++ b/sql/vtmd.h
@@ -0,0 +1,190 @@
+#ifndef VTMD_INCLUDED
+#define VTMD_INCLUDED
+
+#include <mysqld_error.h>
+
+#include "mariadb.h"
+#include "sql_priv.h"
+
+#include "my_sys.h"
+#include "table.h"
+#include "unireg.h"
+
+#include "vers_utils.h"
+
+class key_buf_t
+{
+ uchar* buf;
+
+ key_buf_t(const key_buf_t&); // disabled
+ key_buf_t& operator= (const key_buf_t&); // disabled
+
+public:
+ key_buf_t() : buf(NULL)
+ {}
+
+ ~key_buf_t()
+ {
+ if (buf)
+ my_free(buf);
+ }
+
+ bool allocate(size_t alloc_size)
+ {
+ DBUG_ASSERT(!buf);
+ buf= static_cast<uchar *>(my_malloc(alloc_size, MYF(0)));
+ if (!buf)
+ {
+ my_message(ER_VERS_VTMD_ERROR, "failed to allocate key buffer", MYF(0));
+ return true;
+ }
+ return false;
+ }
+
+ operator uchar* ()
+ {
+ DBUG_ASSERT(buf);
+ return reinterpret_cast<uchar *>(buf);
+ }
+};
+
+class THD;
+
+class VTMD_table
+{
+ Open_tables_backup open_tables_backup;
+
+protected:
+ TABLE_LIST vtmd;
+ TABLE_LIST &about;
+ SString_t vtmd_name;
+
+private:
+ VTMD_table(const VTMD_table&); // prohibit copying references
+
+public:
+ enum {
+ FLD_START= 0,
+ FLD_END,
+ FLD_NAME,
+ FLD_ARCHIVE_NAME,
+ FLD_COL_RENAMES,
+ FIELD_COUNT
+ };
+
+ enum {
+ IDX_TRX_END= 0,
+ IDX_ARCHIVE_NAME
+ };
+
+ VTMD_table(TABLE_LIST &_about) :
+ about(_about)
+ {
+ vtmd.table= NULL;
+ }
+
+ bool create(THD *thd);
+ bool find_record(ulonglong row_end, bool &found);
+ bool open(THD *thd, Local_da &local_da, bool *created= NULL);
+ bool update(THD *thd, const char* archive_name= NULL);
+ bool setup_select(THD *thd);
+
+ static void archive_name(THD *thd, const char *table_name, char *new_name, size_t new_name_size);
+ void archive_name(THD *thd, char *new_name, size_t new_name_size)
+ {
+ archive_name(thd, about.table_name.str, new_name, new_name_size);
+ }
+
+ bool find_archive_name(THD *thd, String &out);
+ static bool get_archive_tables(THD *thd, const char *db, size_t db_length,
+ Dynamic_array<String> &result);
+};
+
+class VTMD_exists : public VTMD_table
+{
+protected:
+ handlerton *hton;
+
+public:
+ bool exists;
+
+public:
+ VTMD_exists(TABLE_LIST &_about) :
+ VTMD_table(_about),
+ hton(NULL),
+ exists(false)
+ {}
+
+ bool check_exists(THD *thd); // returns error status
+};
+
+class VTMD_rename : public VTMD_exists
+{
+ SString_t vtmd_new_name;
+
+public:
+ VTMD_rename(TABLE_LIST &_about) :
+ VTMD_exists(_about)
+ {}
+
+ bool try_rename(THD *thd, LString new_db, LString new_alias, const char* archive_name= NULL);
+ bool revert_rename(THD *thd, LString new_db);
+
+private:
+ bool move_archives(THD *thd, LString &new_db);
+ bool move_table(THD *thd, SString_fs &table_name, LString &new_db);
+};
+
+class VTMD_drop : public VTMD_exists
+{
+ char archive_name_[NAME_CHAR_LEN];
+
+public:
+ VTMD_drop(TABLE_LIST &_about) :
+ VTMD_exists(_about)
+ {
+ *archive_name_= 0;
+ }
+
+ const char* archive_name(THD *thd)
+ {
+ VTMD_table::archive_name(thd, archive_name_, sizeof(archive_name_));
+ return archive_name_;
+ }
+
+ const char* archive_name() const
+ {
+ DBUG_ASSERT(*archive_name_);
+ return archive_name_;
+ }
+
+ bool update(THD *thd)
+ {
+ DBUG_ASSERT(*archive_name_);
+ return VTMD_exists::update(thd, archive_name_);
+ }
+};
+
+
+inline
+bool
+VTMD_exists::check_exists(THD *thd)
+{
+ LEX_CSTRING name;
+ if (about.vers_vtmd_name(vtmd_name))
+ return true;
+
+ name.str= vtmd_name.ptr();
+ name.length= vtmd_name.length();
+ exists= ha_table_exists(thd, &about.db, &name, &hton);
+
+ if (exists && !hton)
+ {
+ my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` handlerton empty!", MYF(0),
+ about.db.str, vtmd_name.ptr());
+ return true;
+ }
+ return false;
+}
+
+#endif // VTMD_INCLUDED
diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc
index bddbbb95f4d..4efd6703d03 100644
--- a/sql/wsrep_binlog.cc
+++ b/sql/wsrep_binlog.cc
@@ -31,13 +31,13 @@ int wsrep_write_cache_buf(IO_CACHE *cache, uchar **buf, size_t *buf_len)
{
*buf= NULL;
*buf_len= 0;
-
my_off_t const saved_pos(my_b_tell(cache));
+ DBUG_ENTER("wsrep_write_cache_buf");
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
{
WSREP_ERROR("failed to initialize io-cache");
- return ER_ERROR_ON_WRITE;
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
}
uint length = my_b_bytes_in_cache(cache);
@@ -86,7 +86,7 @@ int wsrep_write_cache_buf(IO_CACHE *cache, uchar **buf, size_t *buf_len)
goto cleanup;
}
- return 0;
+ DBUG_RETURN(0);
error:
if (reinit_io_cache(cache, WRITE_CACHE, saved_pos, 0, 0))
@@ -97,7 +97,7 @@ cleanup:
my_free(*buf);
*buf= NULL;
*buf_len= 0;
- return ER_ERROR_ON_WRITE;
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
}
#define STACK_SIZE 4096 /* 4K - for buffer preallocated on the stack:
@@ -121,6 +121,7 @@ wsrep_append_data(wsrep_t* const wsrep,
struct wsrep_buf const buff = { data, len };
wsrep_status_t const rc(wsrep->append_data(wsrep, ws, &buff, 1,
WSREP_DATA_ORDERED, true));
+ DBUG_DUMP("buff", (uchar*) data, len);
if (rc != WSREP_OK)
{
WSREP_WARN("append_data() returned %d", rc);
@@ -144,11 +145,12 @@ static int wsrep_write_cache_once(wsrep_t* const wsrep,
size_t* const len)
{
my_off_t const saved_pos(my_b_tell(cache));
+ DBUG_ENTER("wsrep_write_cache_once");
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
{
WSREP_ERROR("failed to initialize io-cache");
- return ER_ERROR_ON_WRITE;
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
}
int err(WSREP_OK);
@@ -230,7 +232,7 @@ cleanup:
}
my_free(heap_buf);
- return err;
+ DBUG_RETURN(err);
}
/*
@@ -247,11 +249,12 @@ static int wsrep_write_cache_inc(wsrep_t* const wsrep,
size_t* const len)
{
my_off_t const saved_pos(my_b_tell(cache));
+ DBUG_ENTER("wsrep_write_cache_inc");
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
{
WSREP_ERROR("failed to initialize io-cache");
- return WSREP_TRX_ERROR;
+ DBUG_RETURN(WSREP_TRX_ERROR);
}
int err(WSREP_OK);
@@ -295,7 +298,7 @@ cleanup:
WSREP_ERROR("failed to reinitialize io-cache");
}
- return err;
+ DBUG_RETURN(err);
}
/*
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index 50ecacd9960..8044b7a3548 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -122,7 +122,7 @@ void wsrep_post_commit(THD* thd, bool all)
case LOCAL_COMMIT:
{
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno != WSREP_SEQNO_UNDEFINED);
- if (wsrep->post_commit(wsrep, &thd->wsrep_ws_handle))
+ if (wsrep && wsrep->post_commit(wsrep, &thd->wsrep_ws_handle))
{
DBUG_PRINT("wsrep", ("set committed fail"));
WSREP_WARN("set committed fail: %llu %d",
@@ -254,12 +254,11 @@ static int wsrep_rollback(handlerton *hton, THD *thd, bool all)
if ((all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
(thd->variables.wsrep_on && thd->wsrep_conflict_state != MUST_REPLAY))
{
- if (wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle))
+ if (wsrep && wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle))
{
DBUG_PRINT("wsrep", ("setting rollback fail"));
WSREP_ERROR("settting rollback fail: thd: %llu, schema: %s, SQL: %s",
- (long long)thd->real_id, (thd->db ? thd->db : "(null)"),
- thd->query());
+ (long long)thd->real_id, thd->get_db(), thd->query());
}
wsrep_cleanup_transaction(thd);
}
@@ -296,11 +295,11 @@ int wsrep_commit(handlerton *hton, THD *thd, bool all)
possible changes to clean state.
*/
if (WSREP_PROVIDER_EXISTS) {
- if (wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle))
+ if (wsrep && wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle))
{
DBUG_PRINT("wsrep", ("setting rollback fail"));
WSREP_ERROR("settting rollback fail: thd: %llu, schema: %s, SQL: %s",
- (long long)thd->real_id, (thd->db ? thd->db : "(null)"),
+ (long long)thd->real_id, thd->get_db(),
thd->query());
}
}
@@ -374,6 +373,11 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
mysql_mutex_lock(&LOCK_wsrep_replaying);
+ DBUG_PRINT("info", ("wsrep_replaying: %d wsrep_conflict_state: %d killed: %d shutdown_in_progress: %d",
+ (int) wsrep_replaying, (int) thd->wsrep_conflict_state,
+ (int) thd->killed,
+ (int) shutdown_in_progress));
+
while (wsrep_replaying > 0 &&
thd->wsrep_conflict_state == NO_CONFLICT &&
thd->killed == NOT_KILLED &&
@@ -437,6 +441,9 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
}
}
+ DBUG_PRINT("info", ("rcode: %d wsrep_conflict_state: %d",
+ rcode, thd->wsrep_conflict_state));
+
if (data_len == 0)
{
if (thd->get_stmt_da()->is_ok() &&
@@ -468,12 +475,12 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
"QUERY: %s\n"
" => Skipping replication",
(longlong) thd->thread_id, data_len,
- (thd->db ? thd->db : "(null)"), thd->query());
+ thd->get_db(), thd->query());
rcode = WSREP_TRX_FAIL;
}
else if (!rcode)
{
- if (WSREP_OK == rcode)
+ if (WSREP_OK == rcode && wsrep)
rcode = wsrep->pre_commit(wsrep,
(wsrep_conn_id_t)thd->thread_id,
&thd->wsrep_ws_handle,
@@ -482,10 +489,12 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
0ULL : WSREP_FLAG_PA_UNSAFE),
&thd->wsrep_trx_meta);
+ DBUG_PRINT("info", ("rcode after pre_commit: %d", rcode));
+
if (rcode == WSREP_TRX_MISSING) {
WSREP_WARN("Transaction missing in provider, thd: %lld schema: %s SQL: %s",
(longlong) thd->thread_id,
- (thd->db ? thd->db : "(null)"), thd->query());
+ thd->get_db(), thd->query());
rcode = WSREP_TRX_FAIL;
} else if (rcode == WSREP_BF_ABORT) {
WSREP_DEBUG("thd: %lld seqno: %lld BF aborted by provider, will replay",
@@ -509,6 +518,12 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
}
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
+
+ DEBUG_SYNC(thd, "wsrep_after_replication");
+
+ DBUG_PRINT("info", ("rcode: %d wsrep_conflict_state: %d",
+ rcode, thd->wsrep_conflict_state));
+
switch(rcode) {
case 0:
/*
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index fd759717aaf..91a77c65604 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1176,7 +1176,7 @@ static bool wsrep_prepare_keys_for_isolation(THD* thd,
}
ka->keys[ka->keys_len].key_parts_num= 2;
++ka->keys_len;
- if (!wsrep_prepare_key_for_isolation(table->db, table->table_name,
+ if (!wsrep_prepare_key_for_isolation(table->db.str, table->table_name.str,
(wsrep_buf_t*)ka->keys[ka->keys_len - 1].key_parts,
&ka->keys[ka->keys_len - 1].key_parts_num))
{
@@ -1264,6 +1264,16 @@ int wsrep_to_buf_helper(
if (!ret && writer.write(&gtid_ev)) ret= 1;
}
#endif /* GTID_SUPPORT */
+ if (wsrep_gtid_mode && thd->variables.gtid_seq_no)
+ {
+ Gtid_log_event gtid_event(thd, thd->variables.gtid_seq_no,
+ thd->variables.gtid_domain_id,
+ true, LOG_EVENT_SUPPRESS_USE_F,
+ true, 0);
+ gtid_event.server_id= thd->variables.server_id;
+ if (!gtid_event.is_valid()) ret= 0;
+ ret= writer.write(&gtid_event);
+ }
/* if there is prepare query, add event for it */
if (!ret && thd->wsrep_TOI_pre_query)
@@ -1308,7 +1318,7 @@ static int wsrep_alter_event_query(THD *thd, uchar** buf, size_t* buf_len)
if (wsrep_alter_query_string(thd, &log_query))
{
WSREP_WARN("events alter string failed: schema: %s, query: %s",
- (thd->db ? thd->db : "(null)"), thd->query());
+ thd->get_db(), thd->query());
return 1;
}
return wsrep_to_buf_helper(thd, log_query.ptr(), log_query.length(), buf, buf_len);
@@ -1324,10 +1334,10 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len)
TABLE_LIST *views = first_table;
LEX_USER *definer;
String buff;
- const LEX_STRING command[3]=
- {{ C_STRING_WITH_LEN("CREATE ") },
- { C_STRING_WITH_LEN("ALTER ") },
- { C_STRING_WITH_LEN("CREATE OR REPLACE ") }};
+ const LEX_CSTRING command[3]=
+ {{ STRING_WITH_LEN("CREATE ") },
+ { STRING_WITH_LEN("ALTER ") },
+ { STRING_WITH_LEN("CREATE OR REPLACE ") }};
buff.append(&command[thd->lex->create_view->mode]);
@@ -1360,25 +1370,23 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len)
view_store_options(thd, views, &buff);
buff.append(STRING_WITH_LEN("VIEW "));
/* Test if user supplied a db (ie: we did not use thd->db) */
- if (views->db && views->db[0] &&
- (thd->db == NULL || strcmp(views->db, thd->db)))
+ if (views->db.str && views->db.str[0] &&
+ (thd->db.str == NULL || cmp(&views->db, &thd->db)))
{
- append_identifier(thd, &buff, views->db,
- views->db_length);
+ append_identifier(thd, &buff, &views->db);
buff.append('.');
}
- append_identifier(thd, &buff, views->table_name,
- views->table_name_length);
+ append_identifier(thd, &buff, &views->table_name);
if (lex->view_list.elements)
{
- List_iterator_fast<LEX_STRING> names(lex->view_list);
- LEX_STRING *name;
+ List_iterator_fast<LEX_CSTRING> names(lex->view_list);
+ LEX_CSTRING *name;
int i;
for (i= 0; (name= names++); i++)
{
buff.append(i ? ", " : "(");
- append_identifier(thd, &buff, name->str, name->length);
+ append_identifier(thd, &buff, name);
}
buff.append(')');
}
@@ -1464,7 +1472,7 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
{
for (TABLE_LIST* table= first_table; table; table= table->next_global)
{
- if (!thd->find_temporary_table(table->db, table->table_name))
+ if (!thd->find_temporary_table(table->db.str, table->table_name.str))
{
return true;
}
@@ -1548,7 +1556,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db_, const char *table_,
WSREP_WARN("TO isolation failed for: %d, schema: %s, sql: %s. Check wsrep "
"connection state and retry the query.",
ret,
- (thd->db ? thd->db : "(null)"),
+ thd->get_db(),
(thd->query()) ? thd->query() : "void");
my_message(ER_LOCK_DEADLOCK, "WSREP replication failed. Check "
"your wsrep connection state and retry the query.", MYF(0));
@@ -1584,7 +1592,7 @@ static void wsrep_TOI_end(THD *thd) {
else {
WSREP_WARN("TO isolation end failed for: %d, schema: %s, sql: %s",
ret,
- (thd->db ? thd->db : "(null)"),
+ thd->get_db(),
(thd->query()) ? thd->query() : "void");
}
}
@@ -1599,7 +1607,7 @@ static int wsrep_RSU_begin(THD *thd, const char *db_, const char *table_)
if (ret != WSREP_OK)
{
WSREP_WARN("RSU desync failed %d for schema: %s, query: %s",
- ret, (thd->db ? thd->db : "(null)"), thd->query());
+ ret, thd->get_db(), thd->query());
my_error(ER_LOCK_DEADLOCK, MYF(0));
return(ret);
}
@@ -1612,8 +1620,7 @@ static int wsrep_RSU_begin(THD *thd, const char *db_, const char *table_)
{
/* no can do, bail out from DDL */
WSREP_WARN("RSU failed due to pending transactions, schema: %s, query %s",
- (thd->db ? thd->db : "(null)"),
- thd->query());
+ thd->get_db(), thd->query());
mysql_mutex_lock(&LOCK_wsrep_replaying);
wsrep_replaying--;
mysql_mutex_unlock(&LOCK_wsrep_replaying);
@@ -1622,7 +1629,7 @@ static int wsrep_RSU_begin(THD *thd, const char *db_, const char *table_)
if (ret != WSREP_OK)
{
WSREP_WARN("resync failed %d for schema: %s, query: %s",
- ret, (thd->db ? thd->db : "(null)"), thd->query());
+ ret, thd->get_db(), thd->query());
}
my_error(ER_LOCK_DEADLOCK, MYF(0));
@@ -1633,8 +1640,7 @@ static int wsrep_RSU_begin(THD *thd, const char *db_, const char *table_)
if (seqno == WSREP_SEQNO_UNDEFINED)
{
WSREP_WARN("pause failed %lld for schema: %s, query: %s", (long long)seqno,
- (thd->db ? thd->db : "(null)"),
- thd->query());
+ thd->get_db(), thd->query());
return(1);
}
WSREP_DEBUG("paused at %lld", (long long)seqno);
@@ -1657,15 +1663,14 @@ static void wsrep_RSU_end(THD *thd)
if (ret != WSREP_OK)
{
WSREP_WARN("resume failed %d for schema: %s, query: %s", ret,
- (thd->db ? thd->db : "(null)"),
- thd->query());
+ thd->get_db(), thd->query());
}
ret = wsrep->resync(wsrep);
if (ret != WSREP_OK)
{
WSREP_WARN("resync failed %d for schema: %s, query: %s", ret,
- (thd->db ? thd->db : "(null)"), thd->query());
+ thd->get_db(), thd->query());
return;
}
@@ -1688,9 +1693,7 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
if (thd->wsrep_conflict_state == MUST_ABORT)
{
WSREP_INFO("thread: %lld schema: %s query: %s has been aborted due to multi-master conflict",
- (longlong) thd->thread_id,
- (thd->db ? thd->db : "(null)"),
- thd->query());
+ (longlong) thd->thread_id, thd->get_db(), thd->query());
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
return WSREP_TRX_FAIL;
}
@@ -2022,7 +2025,7 @@ static bool abort_replicated(THD *thd)
bool ret_code= false;
if (thd->wsrep_query_state== QUERY_COMMITTING)
{
- WSREP_DEBUG("aborting replicated trx: %lu", (ulong) thd->real_id);
+ WSREP_DEBUG("aborting replicated trx: %llu", (ulonglong)(thd->real_id));
(void)wsrep_abort_thd(thd, thd, TRUE);
ret_code= true;
@@ -2329,7 +2332,7 @@ static int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len)
saved_mode))
{
WSREP_WARN("SP create string failed: schema: %s, query: %s",
- (thd->db ? thd->db : "(null)"), thd->query());
+ thd->get_db(), thd->query());
return 1;
}
@@ -2492,9 +2495,7 @@ extern "C" void wsrep_thd_awake(THD *thd, my_bool signal)
{
if (signal)
{
- mysql_mutex_lock(&thd->LOCK_thd_data);
thd->awake(KILL_QUERY);
- mysql_mutex_unlock(&thd->LOCK_thd_data);
}
else
{
@@ -2577,8 +2578,8 @@ bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
}
else if (!(thd->find_temporary_table(src_table)))
{
- /* this is straight CREATE TABLE LIKE... eith no tmp tables */
- WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL);
+ /* this is straight CREATE TABLE LIKE... with no tmp tables */
+ WSREP_TO_ISOLATION_BEGIN(table->db.str, table->table_name.str, NULL);
}
else
{
@@ -2601,7 +2602,7 @@ bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
thd->wsrep_TOI_pre_query= query.ptr();
thd->wsrep_TOI_pre_query_len= query.length();
- WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL);
+ WSREP_TO_ISOLATION_BEGIN(table->db.str, table->table_name.str, NULL);
thd->wsrep_TOI_pre_query= NULL;
thd->wsrep_TOI_pre_query_len= 0;
@@ -2659,11 +2660,10 @@ static int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len)
append_definer(thd, &stmt_query, &definer_user, &definer_host);
LEX_CSTRING stmt_definition;
- uint not_used;
stmt_definition.str= (char*) thd->lex->stmt_definition_begin;
stmt_definition.length= thd->lex->stmt_definition_end
- thd->lex->stmt_definition_begin;
- trim_whitespace(thd->charset(), &stmt_definition, &not_used);
+ trim_whitespace(thd->charset(), &stmt_definition);
stmt_query.append(stmt_definition.str, stmt_definition.length);
@@ -2739,6 +2739,7 @@ my_bool wsrep_aborting_thd_contains(THD *thd)
void wsrep_aborting_thd_enqueue(THD *thd)
{
+ mysql_mutex_assert_owner(&LOCK_wsrep_rollback);
wsrep_aborting_thd_t aborting = (wsrep_aborting_thd_t)
my_malloc(sizeof(struct wsrep_aborting_thd), MYF(0));
aborting->aborting_thd = thd;
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index bed9b0dca48..6ad13cd6f6a 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -48,7 +48,7 @@ struct wsrep_thd_shadow {
enum wsrep_exec_mode wsrep_exec_mode;
Vio *vio;
ulong tx_isolation;
- char *db;
+ const char *db;
size_t db_length;
my_hrtime_t user_time;
longlong row_count_func;
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 9c00f9fdaf6..41044085625 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -29,9 +29,10 @@
#include <cstdio>
#include <cstdlib>
-char wsrep_defaults_file[FN_REFLEN * 2 + 10 +
- sizeof(WSREP_SST_OPT_CONF) +
- sizeof(WSREP_SST_OPT_EXTRA_CONF)] = {0};
+static char wsrep_defaults_file[FN_REFLEN * 2 + 10 + 30 +
+ sizeof(WSREP_SST_OPT_CONF) +
+ sizeof(WSREP_SST_OPT_CONF_SUFFIX) +
+ sizeof(WSREP_SST_OPT_CONF_EXTRA)] = {0};
// container for real auth string
static const char* sst_auth_real = NULL;
@@ -68,7 +69,11 @@ static void make_wsrep_defaults_file()
if (my_defaults_extra_file)
ptr= strxnmov(ptr, end - ptr,
- WSREP_SST_OPT_EXTRA_CONF, " '", my_defaults_extra_file, "' ", NULL);
+ WSREP_SST_OPT_CONF_EXTRA, " '", my_defaults_extra_file, "' ", NULL);
+
+ if (my_defaults_group_suffix)
+ ptr= strxnmov(ptr, end - ptr,
+ WSREP_SST_OPT_CONF_SUFFIX, " '", my_defaults_group_suffix, "' ", NULL);
}
}
@@ -629,8 +634,8 @@ static ssize_t sst_prepare_other (const char* method,
WSREP_SST_OPT_PARENT" '%d'"
" %s '%s' ",
method, addr_in, mysql_real_data_home,
- wsrep_defaults_file, (int)getpid(),
- binlog_opt, binlog_opt_val);
+ wsrep_defaults_file,
+ (int)getpid(), binlog_opt, binlog_opt_val);
my_free(binlog_opt_val);
if (ret < 0 || ret >= cmd_len)
@@ -912,7 +917,7 @@ static int sst_donate_mysqldump (const char* addr,
WSREP_SST_OPT_PORT" '%d' "
WSREP_SST_OPT_LPORT" '%u' "
WSREP_SST_OPT_SOCKET" '%s' "
- " %s "
+ " '%s' "
WSREP_SST_OPT_GTID" '%s:%lld' "
WSREP_SST_OPT_GTID_DOMAIN_ID" '%d'"
"%s",
diff --git a/sql/wsrep_sst.h b/sql/wsrep_sst.h
index 460046bc4ad..8bf6dc31464 100644
--- a/sql/wsrep_sst.h
+++ b/sql/wsrep_sst.h
@@ -27,7 +27,8 @@
#define WSREP_SST_OPT_AUTH "--auth"
#define WSREP_SST_OPT_DATA "--datadir"
#define WSREP_SST_OPT_CONF "--defaults-file"
-#define WSREP_SST_OPT_EXTRA_CONF "--defaults-extra-file"
+#define WSREP_SST_OPT_CONF_SUFFIX "--defaults-group-suffix"
+#define WSREP_SST_OPT_CONF_EXTRA "--defaults-extra-file"
#define WSREP_SST_OPT_PARENT "--parent"
#define WSREP_SST_OPT_BINLOG "--binlog"
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index 32b812a9bb2..e8dda53c95f 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -164,22 +164,23 @@ static void wsrep_prepare_bf_thd(THD *thd, struct wsrep_thd_shadow* shadow)
thd->variables.tx_isolation = ISO_READ_COMMITTED;
thd->tx_isolation = ISO_READ_COMMITTED;
- shadow->db = thd->db;
- shadow->db_length = thd->db_length;
+ shadow->db = thd->db.str;
+ shadow->db_length = thd->db.length;
shadow->user_time = thd->user_time;
shadow->row_count_func= thd->get_row_count_func();
- thd->reset_db(NULL, 0);
+ thd->reset_db(&null_clex_str);
}
static void wsrep_return_from_bf_mode(THD *thd, struct wsrep_thd_shadow* shadow)
{
+ LEX_CSTRING db= {shadow->db, shadow->db_length };
thd->variables.option_bits = shadow->options;
thd->server_status = shadow->server_status;
thd->wsrep_exec_mode = shadow->wsrep_exec_mode;
thd->net.vio = shadow->vio;
thd->variables.tx_isolation = shadow->tx_isolation;
thd->user_time = shadow->user_time;
- thd->reset_db(shadow->db, shadow->db_length);
+ thd->reset_db(&db);
delete thd->system_thread_info.rpl_sql_info;
delete thd->wsrep_rgi->rli->mi;
@@ -322,8 +323,7 @@ void wsrep_replay_transaction(THD *thd)
break;
default:
WSREP_ERROR("trx_replay failed for: %d, schema: %s, query: %s",
- rcode,
- (thd->db ? thd->db : "(null)"),
+ rcode, thd->get_db(),
thd->query() ? thd->query() : "void");
/* we're now in inconsistent state, must abort */
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index 8107ab12c6b..ffa969a811c 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -42,12 +42,31 @@ int wsrep_init_vars()
return 0;
}
+/* This is intentionally declared as a weak global symbol, so that
+linking will succeed even if the server is built with a dynamically
+linked InnoDB. */
+ulong innodb_lock_schedule_algorithm __attribute__((weak));
+
bool wsrep_on_update (sys_var *self, THD* thd, enum_var_type var_type)
{
if (var_type == OPT_GLOBAL) {
// FIXME: this variable probably should be changed only per session
thd->variables.wsrep_on = global_system_variables.wsrep_on;
}
+
+ return false;
+}
+
+bool wsrep_on_check(sys_var *self, THD* thd, set_var* var)
+{
+ bool new_wsrep_on= (bool)var->save_result.ulonglong_value;
+
+ if (new_wsrep_on && innodb_lock_schedule_algorithm != 0) {
+ my_message(ER_WRONG_ARGUMENTS, " WSREP (galera) can't be enabled "
+ "if innodb_lock_schedule_algorithm=VATS. Please configure"
+ " innodb_lock_schedule_algorithm=FCFS and restart.", MYF(0));
+ return true;
+ }
return false;
}
@@ -327,8 +346,9 @@ bool wsrep_provider_update (sys_var *self, THD* thd, enum_var_type type)
if (wsrep_inited == 1)
wsrep_deinit(false);
- char* tmp= strdup(wsrep_provider); // wsrep_init() rewrites provider
+ char* tmp= strdup(wsrep_provider); // wsrep_init() rewrites provider
//when fails
+
if (wsrep_init())
{
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), tmp, my_error, "wsrep_init failed");
@@ -588,9 +608,8 @@ bool wsrep_desync_check (sys_var *self, THD* thd, set_var* var)
if (new_wsrep_desync) {
ret = wsrep->desync (wsrep);
if (ret != WSREP_OK) {
- WSREP_WARN ("SET desync failed %d for schema: %s, query: %s", ret,
- (thd->db ? thd->db : "(null)"),
- thd->query());
+ WSREP_WARN ("SET desync failed %d for schema: %s, query: %s",
+ ret, thd->get_db(), thd->query());
my_error (ER_CANNOT_USER, MYF(0), "'desync'", thd->query());
return true;
}
@@ -598,8 +617,7 @@ bool wsrep_desync_check (sys_var *self, THD* thd, set_var* var)
ret = wsrep->resync (wsrep);
if (ret != WSREP_OK) {
WSREP_WARN ("SET resync failed %d for schema: %s, query: %s", ret,
- (thd->db ? thd->db : "(null)"),
- thd->query());
+ thd->get_db(), thd->query());
my_error (ER_CANNOT_USER, MYF(0), "'resync'", thd->query());
return true;
}
diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h
index dde59d1503f..b9051b29843 100644
--- a/sql/wsrep_var.h
+++ b/sql/wsrep_var.h
@@ -41,7 +41,8 @@ int wsrep_init_vars();
#define DEFAULT_ARGS (THD* thd, enum_var_type var_type)
#define INIT_ARGS (const char* opt)
-extern bool wsrep_causal_reads_update UPDATE_ARGS;
+extern bool wsrep_causal_reads_update UPDATE_ARGS;
+extern bool wsrep_on_check CHECK_ARGS;
extern bool wsrep_on_update UPDATE_ARGS;
extern bool wsrep_sync_wait_update UPDATE_ARGS;
extern bool wsrep_start_position_check CHECK_ARGS;
diff --git a/storage/archive/azio.c b/storage/archive/azio.c
index 8bf90e700d4..0f66b999c94 100644
--- a/storage/archive/azio.c
+++ b/storage/archive/azio.c
@@ -479,7 +479,7 @@ unsigned int ZEXPORT azread ( azio_stream *s, voidp buf, size_t len, int *error)
next_out = (Byte*)buf;
s->stream.next_out = (Bytef*)buf;
- s->stream.avail_out = len;
+ s->stream.avail_out = (uInt)len;
if (s->stream.avail_out && s->back != EOF) {
*next_out++ = s->back;
@@ -521,7 +521,7 @@ unsigned int ZEXPORT azread ( azio_stream *s, voidp buf, size_t len, int *error)
s->out += len;
if (len == 0) s->z_eof = 1;
{
- return len;
+ return (uint)len;
}
}
if (s->stream.avail_in == 0 && !s->z_eof) {
@@ -574,7 +574,7 @@ unsigned int ZEXPORT azread ( azio_stream *s, voidp buf, size_t len, int *error)
return 0;
}
- return (len - s->stream.avail_out);
+ return (uint)(len - s->stream.avail_out);
}
@@ -882,7 +882,7 @@ int azclose (azio_stream *s)
Though this was added to support MySQL's FRM file, anything can be
stored in this location.
*/
-int azwrite_frm(azio_stream *s, const uchar *blob, unsigned int length)
+int azwrite_frm(azio_stream *s, const uchar *blob, size_t length)
{
if (s->mode == 'r')
return 1;
@@ -891,7 +891,7 @@ int azwrite_frm(azio_stream *s, const uchar *blob, unsigned int length)
return 1;
s->frm_start_pos= (uint) s->start;
- s->frm_length= length;
+ s->frm_length= (uint)length;
s->start+= length;
if (my_pwrite(s->file, blob, s->frm_length,
@@ -913,7 +913,7 @@ int azread_frm(azio_stream *s, uchar *blob)
/*
Simple comment field
*/
-int azwrite_comment(azio_stream *s, const char *blob, unsigned int length)
+int azwrite_comment(azio_stream *s, const char *blob, size_t length)
{
if (s->mode == 'r')
return 1;
@@ -922,7 +922,7 @@ int azwrite_comment(azio_stream *s, const char *blob, unsigned int length)
return 1;
s->comment_start_pos= (uint) s->start;
- s->comment_length= length;
+ s->comment_length= (uint)length;
s->start+= length;
my_pwrite(s->file, (uchar*) blob, s->comment_length, s->comment_start_pos,
diff --git a/storage/archive/azlib.h b/storage/archive/azlib.h
index d9318002901..20725aac304 100644
--- a/storage/archive/azlib.h
+++ b/storage/archive/azlib.h
@@ -334,10 +334,10 @@ extern int azclose(azio_stream *file);
error number (see function gzerror below).
*/
-extern int azwrite_frm (azio_stream *s, const uchar *blob, unsigned int length);
+extern int azwrite_frm (azio_stream *s, const uchar *blob,size_t length);
extern int azread_frm (azio_stream *s, uchar *blob);
extern int azwrite_comment (azio_stream *s, const char *blob,
- unsigned int length);
+ size_t length);
extern int azread_comment (azio_stream *s, char *blob);
#ifdef __cplusplus
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index e478058c7fd..08d5220cfca 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -1361,7 +1361,7 @@ int ha_archive::get_row_version2(azio_stream *file_to_read, uchar *buf)
if ((size_t) read != size)
DBUG_RETURN(HA_ERR_END_OF_FILE);
- ((Field_blob*) table->field[*ptr])->set_ptr(size, (uchar*) last);
+ ((Field_blob*) table->field[*ptr])->set_ptr(read, (uchar*) last);
last += size;
}
else
diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc
index ff758a57872..c55e9976ede 100644
--- a/storage/cassandra/ha_cassandra.cc
+++ b/storage/cassandra/ha_cassandra.cc
@@ -866,7 +866,7 @@ static void alloc_strings_memroot(MEM_ROOT *mem_root)
The mem_root used to allocate UUID (of length 36 + \0) so make
appropriate allocated size
*/
- init_alloc_root(mem_root,
+ init_alloc_root(mem_root, "cassandra",
(36 + 1 + ALIGN_SIZE(sizeof(USED_MEM))) * 10 +
ALLOC_ROOT_MIN_BLOCK_SIZE,
(36 + 1 + ALIGN_SIZE(sizeof(USED_MEM))) * 10 +
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 2cf6c0528c0..33b0477842d 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -61,7 +61,7 @@ IF(UNIX)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -fexceptions -fPIC ")
get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
- SET(CONNECT_SOURCES ${CONNECT_SOURCES} inihandl.c)
+ SET(CONNECT_SOURCES ${CONNECT_SOURCES} inihandl.cpp)
SET(IPHLPAPI_LIBRARY "")
ELSE(NOT UNIX)
SET(CONNECT_SOURCES ${CONNECT_SOURCES}
@@ -69,6 +69,10 @@ ELSE(NOT UNIX)
# Add exception handling to the CONNECT project)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
SET(IPHLPAPI_LIBRARY iphlpapi.lib)
+ IF(MSVC AND (CMAKE_CXX_COMPILER_ID MATCHES Clang))
+ # Connect does not work with clang-cl
+ RETURN()
+ ENDIF()
ENDIF(UNIX)
@@ -326,6 +330,16 @@ IF(NOT TARGET connect)
RETURN()
ENDIF()
+
+IF(MSVC)
+ # Temporarily disable "conversion from size_t .."
+ IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267")
+ ENDIF()
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996")
+ string(REPLACE "/permissive-" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ENDIF()
+
# Install some extra files that belong to connect engine
IF(WIN32)
# install ha_connect.lib
diff --git a/storage/connect/domdoc.cpp b/storage/connect/domdoc.cpp
index ba8eb829abd..4502530cf82 100644
--- a/storage/connect/domdoc.cpp
+++ b/storage/connect/domdoc.cpp
@@ -84,7 +84,7 @@ DOMDOC::DOMDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
: XMLDOCUMENT(nsl, nsdf, enc)
{
assert (!fp || fp->Type == TYPE_FB_XML);
- Docp = (fp) ? ((PXBLOCK)fp)->Docp : NULL;
+ Docp = (fp) ? ((PXBLOCK)fp)->Docp : (MSXML2::IXMLDOMDocumentPtr)NULL;
Nlist = NULL;
Hr = 0;
} // end of DOMDOC constructor
diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp
index 871613cb4b4..871613cb4b4 100755..100644
--- a/storage/connect/filamvct.cpp
+++ b/storage/connect/filamvct.cpp
diff --git a/storage/connect/global.h b/storage/connect/global.h
index de7a9fb3c03..e4b00786efa 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -217,7 +217,8 @@ 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 void *PlugAllocMem(PGLOBAL, uint);
+DllExport bool AllocSarea(PGLOBAL, uint);
+DllExport void FreeSarea(PGLOBAL);
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
DllExport char *PlugDup(PGLOBAL g, const char *str);
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 51fcf87470c..4d62efd8988 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -1755,11 +1755,13 @@ bool ha_connect::CheckVirtualIndex(TABLE_SHARE *s)
bool ha_connect::IsPartitioned(void)
{
+#ifdef WITH_PARTITION_STORAGE_ENGINE
if (tshp)
return tshp->partition_info_str_len > 0;
else if (table && table->part_info)
return true;
else
+#endif
return false;
} // end of IsPartitioned
@@ -3010,7 +3012,9 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
return NULL;
if (!x) {
+ const char *p;
char *s = (ishav) ? havg : body;
+ uint j, k, n;
// Append the value to the filter
switch (args[i]->field_type()) {
@@ -3066,16 +3070,38 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
strcat(s, "'}");
break;
default:
- strcat(s, "'");
- strncat(s, res->ptr(), res->length());
- strcat(s, "'");
- } // endswitch field type
+ j = strlen(s);
+ s[j++] = '\'';
+ p = res->ptr();
+ n = res->length();
+
+ for (k = 0; k < n; k++) {
+ if (p[k] == '\'')
+ s[j++] = '\'';
+
+ s[j++] = p[k];
+ } // endfor k
+
+ s[j++] = '\'';
+ s[j] = 0;
+ } // endswitch field type
} else {
- strcat(s, "'");
- strncat(s, res->ptr(), res->length());
- strcat(s, "'");
- } // endif tty
+ j = strlen(s);
+ s[j++] = '\'';
+ p = res->ptr();
+ n = res->length();
+
+ for (k = 0; k < n; k++) {
+ if (p[k] == '\'')
+ s[j++] = '\'';
+
+ s[j++] = p[k];
+ } // endfor k
+
+ s[j++] = '\'';
+ s[j] = 0;
+ } // endif tty
break;
default:
@@ -5560,7 +5586,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
int rc;
PJDBCDEF jdef = new(g) JDBCDEF();
- jdef->SetName(create_info->alias);
+ jdef->SetName(create_info->alias.str);
sjp = (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM));
sjp->Driver = driver;
// sjp->Properties = prop;
@@ -5604,7 +5630,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
PMYDEF mydef = new(g) MYSQLDEF();
dsn = strz(g, create_info->connect_string);
- mydef->SetName(create_info->alias);
+ mydef->SetName(create_info->alias.str);
if (!mydef->ParseURL(g, dsn, false)) {
if (mydef->GetHostname())
@@ -5646,7 +5672,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case TAB_TBL:
case TAB_XCL:
case TAB_OCCUR:
- if (!src && !stricmp(tab, create_info->alias) &&
+ if (!src && !stricmp(tab, create_info->alias.str) &&
(!db || !stricmp(db, table_s->db.str)))
sprintf(g->Message, "A %s table cannot refer to itself", topt->type);
else
@@ -6142,8 +6168,10 @@ int ha_connect::create(const char *name, TABLE *table_arg,
TABLE *st= table; // Probably unuseful
THD *thd= ha_thd();
LEX_CSTRING cnc = table_arg->s->connect_string;
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
+#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *part_info= table_arg->part_info;
+#else
+#define part_info 0
#endif // WITH_PARTITION_STORAGE_ENGINE
xp= GetUser(thd, xp);
PGLOBAL g= xp->g;
@@ -6217,7 +6245,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
dbf= (GetTypeID(options->type) == TAB_DBF && !options->catfunc);
// Can be null in ALTER TABLE
- if (create_info->alias)
+ if (create_info->alias.str)
// Check whether a table is defined on itself
switch (type) {
case TAB_PRX:
@@ -6228,7 +6256,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
strcpy(g->Message, "Cannot check looping reference");
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
} else if (options->tabname) {
- if (!stricmp(options->tabname, create_info->alias) &&
+ if (!stricmp(options->tabname, create_info->alias.str) &&
(!options->dbname ||
!stricmp(options->dbname, table_arg->s->db.str))) {
sprintf(g->Message, "A %s table cannot refer to itself",
@@ -6245,9 +6273,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
// fall through
case TAB_MYSQL:
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (!part_info)
-#endif // WITH_PARTITION_STORAGE_ENGINE
{const char *src= options->srcdef;
PCSZ host, db, tab= options->tabname;
int port;
@@ -6261,7 +6287,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
char *dsn= strz(g, create_info->connect_string);
PMYDEF mydef= new(g) MYSQLDEF();
- mydef->SetName(create_info->alias);
+ mydef->SetName(create_info->alias.str);
if (!mydef->ParseURL(g, dsn, false)) {
if (mydef->GetHostname())
@@ -6511,7 +6537,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} else
lwt[i]= tolower(options->type[i]);
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (part_info) {
char *p;
@@ -6521,7 +6546,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
strcat(strcat(strcpy(buf, p), "."), lwt);
*p= 0;
} else {
-#endif // WITH_PARTITION_STORAGE_ENGINE
strcat(strcat(strcpy(buf, GetTableName()), "."), lwt);
sprintf(g->Message, "No file name. Table will use %s", buf);
@@ -6529,9 +6553,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/");
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
} // endif part_info
-#endif // WITH_PARTITION_STORAGE_ENGINE
PlugSetPath(fn, buf, dbpath);
@@ -6596,11 +6618,9 @@ int ha_connect::create(const char *name, TABLE *table_arg,
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Unexpected command in create, please contact CONNECT team");
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (part_info && !inward)
strncpy(partname, decode(g, strrchr(name, '#') + 1), sizeof(partname) - 1);
// strcpy(partname, part_info->curr_part_elem->partition_name);
-#endif // WITH_PARTITION_STORAGE_ENGINE
if (g->Alchecked == 0 &&
(!IsFileType(type) || FileExists(options->filename, false))) {
@@ -6636,12 +6656,10 @@ int ha_connect::create(const char *name, TABLE *table_arg,
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
rc = HA_ERR_INTERNAL_ERROR;
} else if (cat) {
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (part_info)
strncpy(partname,
decode(g, strrchr(name, (inward ? slash : '#')) + 1),
sizeof(partname) - 1);
-#endif // WITH_PARTITION_STORAGE_ENGINE
if ((rc= optimize(table->in_use, NULL))) {
htrc("Create rc=%d %s\n", rc, g->Message);
diff --git a/storage/connect/inihandl.c b/storage/connect/inihandl.cpp
index 0ce0eb9fa0d..96ae0a67a6b 100644
--- a/storage/connect/inihandl.c
+++ b/storage/connect/inihandl.cpp
@@ -37,7 +37,7 @@
// The types and variables used locally
//typedef int bool;
typedef unsigned int uint;
-#define SVP(S) ((S) ? S : "<null>")
+//#define SVP(S) ((S) ? S : "<null>")
#define _strlwr(P) strlwr(P) //OB: changed this line
#define MAX_PATHNAME_LEN 256
#define N_CACHED_PROFILES 10
@@ -61,8 +61,8 @@ void htrc(char const *fmt, ...)
} /* end of htrc */
#else // !TEST_MODULE
// Normal included functions
-extern int trace;
-void htrc(char const *fmt, ...);
+//extern int trace;
+//void htrc(char const *fmt, ...);
#endif // !TEST MODULE
@@ -112,10 +112,11 @@ static PROFILE *MRUProfile[N_CACHED_PROFILES] = {NULL};
//static CRITICAL_SECTION PROFILE_CritSect = CRITICAL_SECTION_INIT("PROFILE_CritSect");
-static const char hex[16] = "0123456789ABCDEF";
+static const char hex[17] = "0123456789ABCDEF";
BOOL WritePrivateProfileString(LPCSTR section, LPCSTR entry,
- LPCSTR string, LPCSTR filename );
+ LPCSTR string, LPCSTR filename);
+
/***********************************************************************
* PROFILE_CopyEntry
*
@@ -254,7 +255,7 @@ static PROFILESECTION *PROFILE_Load( FILE *file )
PROFILESECTION* *next_section;
PROFILEKEY *key, *prev_key, **next_key;
- first_section = malloc(sizeof(*section));
+ first_section = (PROFILESECTION*)malloc(sizeof(*section));
if (first_section == NULL)
return NULL;
@@ -281,7 +282,7 @@ static PROFILESECTION *PROFILE_Load( FILE *file )
*p2 = '\0';
p++;
- if (!(section = malloc(sizeof(*section) + strlen(p))))
+ if (!(section = (PROFILESECTION*)malloc(sizeof(*section) + strlen(p))))
break;
strcpy(section->name, p);
@@ -319,13 +320,13 @@ static PROFILESECTION *PROFILE_Load( FILE *file )
} // endif p2
if (*p || !prev_key || *prev_key->name) {
- if (!(key = malloc(sizeof(*key) + strlen(p))))
+ if (!(key = (PROFILEKEY*)malloc(sizeof(*key) + strlen(p))))
break;
strcpy(key->name, p);
if (p2) {
- key->value = malloc(strlen(p2)+1);
+ key->value = (char*)malloc(strlen(p2)+1);
strcpy(key->value, p2);
} else
key->value = NULL;
@@ -452,7 +453,7 @@ static BOOL PROFILE_Open(LPCSTR filename)
/* First time around */
if (!CurProfile)
for (i = 0; i < N_CACHED_PROFILES; i++) {
- MRUProfile[i] = malloc(sizeof(PROFILE));
+ MRUProfile[i] = (PROFILE*)malloc(sizeof(PROFILE));
if (MRUProfile[i] == NULL)
break;
@@ -520,7 +521,7 @@ static BOOL PROFILE_Open(LPCSTR filename)
// strcpy(newdos_name, filename);
// CurProfile->dos_name = newdos_name;
- CurProfile->filename = malloc(strlen(filename) + 1);
+ CurProfile->filename = (char*)malloc(strlen(filename) + 1);
strcpy(CurProfile->filename, filename);
/* Try to open the profile file, first in $HOME/.wine */
@@ -783,7 +784,7 @@ static PROFILEKEY *PROFILE_Find(PROFILESECTION* *section,
if (!create)
return NULL;
- if (!(*key = malloc(sizeof(PROFILEKEY) + strlen(key_name))))
+ if (!(*key = (PROFILEKEY*)malloc(sizeof(PROFILEKEY) + strlen(key_name))))
return NULL;
strcpy((*key)->name, key_name);
@@ -798,7 +799,7 @@ static PROFILEKEY *PROFILE_Find(PROFILESECTION* *section,
if (!create)
return NULL;
- *section = malloc(sizeof(PROFILESECTION) + strlen(section_name));
+ *section = (PROFILESECTION*)malloc(sizeof(PROFILESECTION) + strlen(section_name));
if (*section == NULL)
return NULL;
@@ -806,7 +807,7 @@ static PROFILEKEY *PROFILE_Find(PROFILESECTION* *section,
strcpy((*section)->name, section_name);
(*section)->next = NULL;
- if (!((*section)->key = malloc(sizeof(PROFILEKEY) + strlen(key_name)))) {
+ if (!((*section)->key = (tagPROFILEKEY*)malloc(sizeof(PROFILEKEY) + strlen(key_name)))) {
free(*section);
return NULL;
} // endif malloc
@@ -1052,7 +1053,7 @@ static BOOL PROFILE_SetString(LPCSTR section_name, LPCSTR key_name,
} else if (trace > 1)
htrc(" creating key\n" );
- key->value = malloc(strlen(value) + 1);
+ key->value = (char*)malloc(strlen(value) + 1);
strcpy(key->value, value);
CurProfile->changed = TRUE;
} // endelse
@@ -1125,7 +1126,7 @@ static int PROFILE_GetPrivateProfileString(LPCSTR section, LPCSTR entry,
if (*p == ' ') { /* ouch, contained trailing ' ' */
int len = p - (LPSTR)def_val;
- pDefVal = malloc(len + 1);
+ pDefVal = (LPSTR)malloc(len + 1);
strncpy(pDefVal, def_val, len);
pDefVal[len] = '\0';
} // endif *p
@@ -1277,7 +1278,7 @@ BOOL WritePrivateProfileSection(LPCSTR section,
ret = TRUE;
while (*string) {
- LPSTR buf = malloc(strlen(string) + 1);
+ LPSTR buf = (LPSTR)malloc(strlen(string) + 1);
strcpy(buf, string);
if ((p = strchr(buf, '='))) {
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index a79fd0a7124..91917b48a23 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -1507,23 +1507,16 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n,
ml += g->More;
if (ml > g->Sarea_Size) {
-#if !defined(DEVELOPMENT)
- if (trace)
-#endif
- htrc("Freeing Sarea at %p size=%d\n", g->Sarea, g->Sarea_Size);
-
- free(g->Sarea);
+ FreeSarea(g);
- if (!(g->Sarea = PlugAllocMem(g, ml))) {
+ if (AllocSarea(g, ml)) {
char errmsg[MAX_STR];
snprintf(errmsg, sizeof(errmsg)-1, MSG(WORK_AREA), g->Message);
strcpy(g->Message, errmsg);
- g->Sarea_Size = 0;
return true;
- } // endif Alloc
+ } // endif SareaAlloc
- g->Sarea_Size = ml;
g->Createas = 0;
g->Xchk = NULL;
initid->max_length = rl;
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index 28e6f076e77..e99e089d940 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -933,8 +933,9 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
crp->Prec = (crp->Type == TYPE_DOUBLE || crp->Type == TYPE_DECIM)
? fld->decimals : 0;
- crp->Length = MY_MAX(fld->length, fld->max_length);
- crp->Clen = GetTypeSize(crp->Type, crp->Length);
+ CHARSET_INFO *cs= get_charset(fld->charsetnr, MYF(0));
+ crp->Clen = GetTypeSize(crp->Type, fld->length);
+ crp->Length = fld->length / (cs ? cs->mbmaxlen : 1);
uns = (fld->flags & (UNSIGNED_FLAG | ZEROFILL_FLAG)) ? true : false;
if (!(crp->Kdata = AllocValBlock(g, NULL, crp->Type, m_Rows,
diff --git a/storage/connect/mysql-test/connect/disabled.def b/storage/connect/mysql-test/connect/disabled.def
index 6d59369a4df..0dcf030613d 100644
--- a/storage/connect/mysql-test/connect/disabled.def
+++ b/storage/connect/mysql-test/connect/disabled.def
@@ -19,3 +19,4 @@ json_java_3 : Need MongoDB running and its Java Driver installed
mongo_c : Need MongoDB running and its C Driver installed
mongo_java_2 : Need MongoDB running and its Java Driver installed
mongo_java_3 : Need MongoDB running and its Java Driver installed
+tbl_thread : Bug MDEV-9844,10179,14214 03/01/2018 OB Option THREAD removed
diff --git a/storage/connect/mysql-test/connect/r/infoschema-9739.result b/storage/connect/mysql-test/connect/r/infoschema-9739.result
index 2d54b578521..4840e981552 100644
--- a/storage/connect/mysql-test/connect/r/infoschema-9739.result
+++ b/storage/connect/mysql-test/connect/r/infoschema-9739.result
@@ -2,7 +2,7 @@ create table t1 (i int) engine=Connect table_type=XML option_list='xmlsup=domdoc
Warnings:
Warning 1105 No file name. Table will use t1.xml
select * from information_schema.tables where table_schema='test' and create_options like '%table_type=XML%';
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
Warnings:
Warning 1296 Got error 174 'File t1.xml not found' from CONNECT
drop table t1;
diff --git a/storage/connect/mysql-test/connect/r/infoschema2-9739.result b/storage/connect/mysql-test/connect/r/infoschema2-9739.result
index 0372874862d..32ca77dc71d 100644
--- a/storage/connect/mysql-test/connect/r/infoschema2-9739.result
+++ b/storage/connect/mysql-test/connect/r/infoschema2-9739.result
@@ -4,7 +4,7 @@ create table t1 (i int) engine=Connect table_type=XML option_list='xmlsup=libxml
Warnings:
Warning 1105 No file name. Table will use t1.xml
select * from information_schema.tables where table_schema='test' and create_options like '%table_type=XML%';
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
Warnings:
Warning 1296 Got error 174 'File t1.xml not found' from CONNECT
drop table t1;
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index 3b0cb562672..45662779b81 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -2250,10 +2250,10 @@ public:
return (SQLCHAR *) (m_part[i].length ? m_part[i].str : NULL);
} // end of ptr
- size_t length(uint i)
+ SQLSMALLINT length(uint i)
{
DBUG_ASSERT(i < max_parts);
- return m_part[i].length;
+ return (SQLSMALLINT)m_part[i].length;
} // end of length
}; // end of class SQLQualifiedName
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index 5602861df59..8c2842f8e41 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -334,7 +334,7 @@ PDBUSER PlgMakeUser(PGLOBAL g)
{
PDBUSER dbuserp;
- if (!(dbuserp = (PDBUSER)PlugAllocMem(g, (uint)sizeof(DBUSERBLK)))) {
+ if (!(dbuserp = (PDBUSER)malloc(sizeof(DBUSERBLK)))) {
sprintf(g->Message, MSG(MALLOC_ERROR), "PlgMakeUser");
return NULL;
} // endif dbuserp
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp
index 0367aacd050..57215b2f745 100644
--- a/storage/connect/plugutil.cpp
+++ b/storage/connect/plugutil.cpp
@@ -138,7 +138,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
if (trace > 1)
htrc("PlugInit: Language='%s'\n",
- ((!Language) ? "Null" : (char*)Language));
+ ((!Language) ? "Null" : (char*)Language));
try {
g = new GLOBAL;
@@ -160,13 +160,11 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
/*******************************************************************/
/* Allocate the main work segment. */
/*******************************************************************/
- if (worksize && !(g->Sarea = PlugAllocMem(g, worksize))) {
+ if (worksize && AllocSarea(g, worksize)) {
char errmsg[MAX_STR];
snprintf(errmsg, sizeof(errmsg) - 1, MSG(WORK_AREA), g->Message);
strcpy(g->Message, errmsg);
- g->Sarea_Size = 0;
- } else
- g->Sarea_Size = worksize;
+ } // endif Sarea
g->jump_level = -1; /* New setting to allow recursive call of Plug */
return(g);
@@ -183,15 +181,7 @@ int PlugExit(PGLOBAL g)
if (dup)
free(dup);
- if (g->Sarea) {
-#if !defined(DEVELOPMENT)
- if (trace)
-#endif
- htrc("Freeing Sarea at %p size=%d\n", g->Sarea, g->Sarea_Size);
-
- free(g->Sarea);
- } // endif Sarea
-
+ FreeSarea(g);
delete g;
} // endif g
@@ -459,30 +449,65 @@ short GetLineLength(PGLOBAL g)
/***********************************************************************/
/* Program for memory allocation of work and language areas. */
/***********************************************************************/
-void *PlugAllocMem(PGLOBAL g, uint size)
+bool AllocSarea(PGLOBAL g, uint size)
{
- void *areap; /* Pointer to allocated area */
-
/*********************************************************************/
/* This is the allocation routine for the WIN32/UNIX/AIX version. */
/*********************************************************************/
- if (!(areap = malloc(size)))
- sprintf(g->Message, MSG(MALLOC_ERROR), "malloc");
+#if defined(__WIN__)
+ if (size >= 1048576) // 1M
+ g->Sarea = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+ else
+#endif
+ g->Sarea = malloc(size);
+
+ if (!g->Sarea) {
+ sprintf(g->Message, MSG(MALLOC_ERROR), "malloc");
+ g->Sarea_Size = 0;
+ } else
+ g->Sarea_Size = size;
#if defined(DEVELOPMENT)
if (true) {
#else
if (trace) {
#endif
- if (areap)
- htrc("Memory of %u allocated at %p\n", size, areap);
+ if (g->Sarea)
+ htrc("Work area of %u allocated at %p\n", size, g->Sarea);
else
- htrc("PlugAllocMem: %s\n", g->Message);
+ htrc("SareaAlloc: %s\n", g->Message);
} // endif trace
- return (areap);
-} // end of PlugAllocMem
+ return (!g->Sarea);
+} // end of AllocSarea
+
+/***********************************************************************/
+/* Program for memory freeing the work area. */
+/***********************************************************************/
+void FreeSarea(PGLOBAL g)
+{
+ if (g->Sarea) {
+#if defined(__WIN__)
+ if (g->Sarea_Size >= 1048576) // 1M
+ VirtualFree(g->Sarea, 0, MEM_RELEASE);
+ else
+#endif
+ free(g->Sarea);
+
+#if defined(DEVELOPMENT)
+ if (true)
+#else
+ if (trace)
+#endif
+ htrc("Freeing Sarea at %p size = %d\n", g->Sarea, g->Sarea_Size);
+
+ g->Sarea = NULL;
+ g->Sarea_Size = 0;
+ } // endif Sarea
+
+ return;
+} // end of FreeSarea
/***********************************************************************/
/* Program for SubSet initialization of memory pools. */
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 031fdebe650..0fb24baa785 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -547,14 +547,12 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
} // endif dladdr
#endif // 0
- // Is the library already loaded?
- if (!Hdll && !(Hdll = dlopen(soname, RTLD_NOLOAD)))
- // Load the desired shared library
- if (!(Hdll = dlopen(soname, RTLD_LAZY))) {
- error = dlerror();
- sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
- return NULL;
- } // endif Hdll
+ // Load the desired shared library
+ if (!Hdll && !(Hdll = dlopen(soname, RTLD_LAZY))) {
+ error = dlerror();
+ sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
+ return NULL;
+ } // endif Hdll
// The exported name is always in uppercase
for (int i = 0; ; i++) {
diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp
index 9b83a1c93a5..aa7cf4e41b4 100644
--- a/storage/connect/tabtbl.cpp
+++ b/storage/connect/tabtbl.cpp
@@ -1,12 +1,9 @@
/************* TabTbl C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABTBL */
/* ------------- */
-/* Version 1.8 */
+/* Version 1.9 */
/* */
-/* COPYRIGHT: */
-/* ---------- */
-/* (C) Copyright to PlugDB Software Development 2008-2017 */
-/* Author: Olivier BERTRAND */
+/* Author: Olivier BERTRAND 2008-2018 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -168,9 +165,14 @@ PTDB TBLDEF::GetTable(PGLOBAL g, MODE)
{
if (Catfunc == FNC_COL)
return new(g) TDBTBC(this);
- else if (Thread)
- return new(g) TDBTBM(this);
- else
+ else if (Thread) {
+#if defined(DEVELOPMENT)
+ return new(g) TDBTBM(this);
+#else
+ strcpy(g->Message, "Option THREAD is no more supported");
+ return NULL;
+#endif // DEVELOPMENT
+ } else
return new(g) TDBTBL(this);
} // end of GetTable
@@ -560,6 +562,7 @@ void TBTBLK::ReadColumn(PGLOBAL)
} // end of ReadColumn
+#if defined(DEVELOPMENT)
/* ------------------------- Class TDBTBM ---------------------------- */
/***********************************************************************/
@@ -865,5 +868,6 @@ int TDBTBM::ReadNextRemote(PGLOBAL g)
return RC_OK;
} // end of ReadNextRemote
+#endif // DEVELOPMENT
/* ------------------------------------------------------------------- */
diff --git a/storage/connect/tabtbl.h b/storage/connect/tabtbl.h
index f02bf620aae..e7a84395787 100644
--- a/storage/connect/tabtbl.h
+++ b/storage/connect/tabtbl.h
@@ -11,30 +11,9 @@
typedef class TBLDEF *PTBLDEF;
typedef class TDBTBL *PTDBTBL;
-typedef class TDBTBM *PTDBTBM;
typedef class MYSQLC *PMYC;
/***********************************************************************/
-/* Defines the structures used for distributed TBM tables. */
-/***********************************************************************/
-typedef struct _TBMtable *PTBMT;
-
-typedef struct _TBMtable {
- PTBMT Next; // Points to next data table struct
- PTABLE Tap; // Points to the sub table
- PGLOBAL G; // Needed in thread routine
- bool Complete; // TRUE when all results are read
- bool Ready; // TRUE when results are there
- int Rows; // Total number of rows read so far
- int ProgCur; // Current pos
- int ProgMax; // Max pos
- int Rc; // Return code
- THD *Thd;
- pthread_attr_t attr; // ???
- pthread_t Tid; // CheckOpen thread ID
- } TBMT;
-
-/***********************************************************************/
/* TBL table. */
/***********************************************************************/
class DllExport TBLDEF : public PRXDEF { /* Logical table description */
@@ -123,7 +102,33 @@ class TBTBLK : public TIDBLK {
protected:
// Must not have additional members
- }; // end of class TBTBLK
+}; // end of class TBTBLK
+
+#if defined(DEVELOPMENT)
+/***********************************************************************/
+/* This table type is buggy and removed until a fix is found. */
+/***********************************************************************/
+typedef class TDBTBM *PTDBTBM;
+
+/***********************************************************************/
+/* Defines the structures used for distributed TBM tables. */
+/***********************************************************************/
+typedef struct _TBMtable *PTBMT;
+
+typedef struct _TBMtable {
+ PTBMT Next; // Points to next data table struct
+ PTABLE Tap; // Points to the sub table
+ PGLOBAL G; // Needed in thread routine
+ bool Complete; // TRUE when all results are read
+ bool Ready; // TRUE when results are there
+ int Rows; // Total number of rows read so far
+ int ProgCur; // Current pos
+ int ProgMax; // Max pos
+ int Rc; // Return code
+ THD *Thd;
+ pthread_attr_t attr; // ???
+ pthread_t Tid; // CheckOpen thread ID
+} TBMT;
/***********************************************************************/
/* This is the TBM Access Method class declaration. */
@@ -160,3 +165,4 @@ class DllExport TDBTBM : public TDBTBL {
}; // end of class TDBTBM
pthread_handler_t ThreadOpen(void *p);
+#endif // DEVELOPMENT
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
index 36436931d59..ad7c21a6b40 100644
--- a/storage/connect/user_connect.cc
+++ b/storage/connect/user_connect.cc
@@ -157,29 +157,20 @@ void user_connect::SetHandler(ha_connect *hc)
bool user_connect::CheckCleanup(bool force)
{
if (thdp->query_id > last_query_id || force) {
- uint worksize= GetWorkSize();
+ uint worksize= GetWorkSize(), size = g->Sarea_Size;
PlugCleanup(g, true);
- if (g->Sarea_Size != worksize) {
- if (g->Sarea) {
-#if !defined(DEVELOPMENT)
- if (trace)
-#endif
- htrc("CheckCleanup: Free Sarea at %p size=%d\n",
- g->Sarea, g->Sarea_Size);
-
- free(g->Sarea);
- } // endif Size
+ if (size != worksize) {
+ FreeSarea(g);
// Check whether the work area could be allocated
- if (!(g->Sarea = PlugAllocMem(g, worksize))) {
- g->Sarea = PlugAllocMem(g, g->Sarea_Size);
+ if (AllocSarea(g, worksize)) {
+ AllocSarea(g, size);
SetWorkSize(g->Sarea_Size); // Was too big
- } else
- g->Sarea_Size = worksize; // Ok
+ } // endif sarea
- } // endif worksize
+ } // endif worksize
PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index 30dce3b7fef..30dce3b7fef 100755..100644
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index f00fe0e201f..f465ee2e947 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -514,7 +514,7 @@ ha_tina::ha_tina(handlerton *hton, TABLE_SHARE *table_arg)
buffer.set((char*)byte_buffer, IO_SIZE, &my_charset_bin);
chain= chain_buffer;
file_buff= new Transparent_file();
- init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0, MYF(0));
+ init_alloc_root(&blobroot, "ha_tina", BLOB_MEMROOT_ALLOC_SIZE, 0, MYF(0));
}
@@ -976,7 +976,7 @@ int ha_tina::open(const char *name, int mode, uint open_options)
*/
thr_lock_data_init(&share->lock, &lock, (void*) this);
ref_length= sizeof(my_off_t);
- init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0, MYF(0));
+ init_alloc_root(&blobroot, "ha_tina", BLOB_MEMROOT_ALLOC_SIZE, 0, MYF(0));
share->lock.get_status= tina_get_status;
share->lock.update_status= tina_update_status;
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index e6fbceb4af2..98d4ef4d7f9 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -1517,7 +1517,7 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
*/
query.length(0);
- init_alloc_root(&mem_root, 256, 0, MYF(0));
+ init_alloc_root(&mem_root, "federated_share", 256, 0, MYF(0));
mysql_mutex_lock(&federated_mutex);
diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h
index e264258a63a..8fe42bd2b08 100644
--- a/storage/federated/ha_federated.h
+++ b/storage/federated/ha_federated.h
@@ -89,7 +89,6 @@ class ha_federated: public handler
*/
DYNAMIC_ARRAY results;
bool position_called, table_will_be_deleted;
- uint fetch_num; // stores the fetch num
MYSQL_ROW_OFFSET current_position; // Current position used by ::position()
int remote_error_number;
char remote_error_buf[FEDERATED_QUERY_BUFFER_SIZE];
diff --git a/storage/federatedx/federatedx_io_mysql.cc b/storage/federatedx/federatedx_io_mysql.cc
index 2068716eeba..a83e54513d3 100644
--- a/storage/federatedx/federatedx_io_mysql.cc
+++ b/storage/federatedx/federatedx_io_mysql.cc
@@ -69,14 +69,14 @@ class federatedx_io_mysql :public federatedx_io
bool requested_autocommit;
bool actual_autocommit;
- int actual_query(const char *buffer, uint length);
+ int actual_query(const char *buffer, size_t length);
bool test_all_restrict() const;
public:
federatedx_io_mysql(FEDERATEDX_SERVER *);
~federatedx_io_mysql();
int simple_query(const char *fmt, ...);
- int query(const char *buffer, uint length);
+ int query(const char *buffer, size_t length);
virtual FEDERATEDX_IO_RESULT *store_result();
virtual size_t max_query_size() const;
@@ -273,7 +273,7 @@ ulong federatedx_io_mysql::savepoint_release(ulong sp)
if (last)
{
char buffer[STRING_BUFFER_USUAL_SIZE];
- int length= my_snprintf(buffer, sizeof(buffer),
+ size_t length= my_snprintf(buffer, sizeof(buffer),
"RELEASE SAVEPOINT save%lu", last->level);
actual_query(buffer, length);
}
@@ -308,7 +308,7 @@ ulong federatedx_io_mysql::savepoint_rollback(ulong sp)
if (savept && !(savept->flags & SAVEPOINT_RESTRICT))
{
char buffer[STRING_BUFFER_USUAL_SIZE];
- int length= my_snprintf(buffer, sizeof(buffer),
+ size_t length= my_snprintf(buffer, sizeof(buffer),
"ROLLBACK TO SAVEPOINT save%lu", savept->level);
actual_query(buffer, length);
}
@@ -341,7 +341,8 @@ void federatedx_io_mysql::savepoint_restrict(ulong sp)
int federatedx_io_mysql::simple_query(const char *fmt, ...)
{
char buffer[STRING_BUFFER_USUAL_SIZE];
- int length, error;
+ size_t length;
+ int error;
va_list arg;
DBUG_ENTER("federatedx_io_mysql::simple_query");
@@ -377,7 +378,7 @@ bool federatedx_io_mysql::test_all_restrict() const
}
-int federatedx_io_mysql::query(const char *buffer, uint length)
+int federatedx_io_mysql::query(const char *buffer, size_t length)
{
int error;
bool wants_autocommit= requested_autocommit | is_readonly();
@@ -402,7 +403,7 @@ int federatedx_io_mysql::query(const char *buffer, uint length)
if (!(savept->flags & SAVEPOINT_RESTRICT))
{
char buf[STRING_BUFFER_USUAL_SIZE];
- int len= my_snprintf(buf, sizeof(buf),
+ size_t len= my_snprintf(buf, sizeof(buf),
"SAVEPOINT save%lu", savept->level);
if ((error= actual_query(buf, len)))
DBUG_RETURN(error);
@@ -419,7 +420,7 @@ int federatedx_io_mysql::query(const char *buffer, uint length)
}
-int federatedx_io_mysql::actual_query(const char *buffer, uint length)
+int federatedx_io_mysql::actual_query(const char *buffer, size_t length)
{
int error;
DBUG_ENTER("federatedx_io_mysql::actual_query");
@@ -452,7 +453,7 @@ int federatedx_io_mysql::actual_query(const char *buffer, uint length)
mysql.reconnect= 1;
}
- error= mysql_real_query(&mysql, buffer, length);
+ error= mysql_real_query(&mysql, buffer, (ulong)length);
DBUG_RETURN(error);
}
diff --git a/storage/federatedx/federatedx_io_null.cc b/storage/federatedx/federatedx_io_null.cc
index aa35d4bdecc..1976f22124a 100644
--- a/storage/federatedx/federatedx_io_null.cc
+++ b/storage/federatedx/federatedx_io_null.cc
@@ -58,7 +58,7 @@ public:
federatedx_io_null(FEDERATEDX_SERVER *);
~federatedx_io_null();
- int query(const char *buffer, uint length);
+ int query(const char *buffer, size_t length);
virtual FEDERATEDX_IO_RESULT *store_result();
virtual size_t max_query_size() const;
@@ -178,7 +178,7 @@ void federatedx_io_null::savepoint_restrict(ulong sp)
}
-int federatedx_io_null::query(const char *buffer, uint length)
+int federatedx_io_null::query(const char *buffer, size_t length)
{
return 0;
}
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index a761c635305..8c21906fe84 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -482,7 +482,7 @@ int federatedx_done(void *p)
in sql_show.cc except that quoting always occurs.
*/
-bool append_ident(String *string, const char *name, uint length,
+bool append_ident(String *string, const char *name, size_t length,
const char quote_char)
{
bool result;
@@ -520,7 +520,7 @@ static int parse_url_error(FEDERATEDX_SHARE *share, TABLE_SHARE *table_s,
int error_num)
{
char buf[FEDERATEDX_QUERY_BUFFER_SIZE];
- int buf_len;
+ size_t buf_len;
DBUG_ENTER("ha_federatedx parse_url_error");
buf_len= MY_MIN(table_s->connect_string.length,
@@ -1520,7 +1520,7 @@ static FEDERATEDX_SERVER *get_server(FEDERATEDX_SHARE *share, TABLE *table)
mysql_mutex_assert_owner(&federatedx_mutex);
- init_alloc_root(&mem_root, 4096, 4096, MYF(0));
+ init_alloc_root(&mem_root, "federated", 4096, 4096, MYF(0));
fill_server(&mem_root, &tmp_server, share, table ? table->s->table_charset : 0);
@@ -1578,12 +1578,12 @@ static FEDERATEDX_SHARE *get_share(const char *table_name, TABLE *table)
query.length(0);
bzero(&tmp_share, sizeof(tmp_share));
- init_alloc_root(&mem_root, 256, 0, MYF(0));
+ init_alloc_root(&mem_root, "federated", 256, 0, MYF(0));
mysql_mutex_lock(&federatedx_mutex);
tmp_share.share_key= table_name;
- tmp_share.share_key_length= strlen(table_name);
+ tmp_share.share_key_length= (int)strlen(table_name);
if (parse_url(&mem_root, &tmp_share, table->s, 0))
goto error;
@@ -1768,7 +1768,7 @@ int ha_federatedx::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(error);
}
- ref_length= io->get_ref_length();
+ ref_length= (uint)io->get_ref_length();
txn->release(&io);
@@ -3066,7 +3066,7 @@ int ha_federatedx::info(uint flag)
stats.block_size= 4096;
if ((*iop)->table_metadata(&stats, share->table_name,
- share->table_name_length, flag))
+ (uint)share->table_name_length, flag))
goto error;
}
diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h
index 02b622b15af..16a1944b172 100644
--- a/storage/federatedx/ha_federatedx.h
+++ b/storage/federatedx/ha_federatedx.h
@@ -120,7 +120,7 @@ typedef struct st_federatedx_share {
int share_key_length;
ushort port;
- uint table_name_length, server_name_length, connect_string_length;
+ size_t table_name_length, server_name_length, connect_string_length;
uint use_count;
THR_LOCK lock;
FEDERATEDX_SERVER *s;
@@ -169,9 +169,11 @@ public:
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return alloc_root(mem_root, size); }
static void operator delete(void *ptr, size_t size)
- { TRASH(ptr, size); }
+ { TRASH_FREE(ptr, size); }
+ static void operator delete(void *, MEM_ROOT *)
+ { }
- virtual int query(const char *buffer, uint length)=0;
+ virtual int query(const char *buffer, size_t length)=0;
virtual FEDERATEDX_IO_RESULT *store_result()=0;
virtual size_t max_query_size() const=0;
@@ -450,7 +452,7 @@ extern const char ident_quote_char; // Character for quoting
extern const char value_quote_char; // Character for quoting
// literals
-extern bool append_ident(String *string, const char *name, uint length,
+extern bool append_ident(String *string, const char *name, size_t length,
const char quote_char);
diff --git a/storage/heap/_check.c b/storage/heap/_check.c
index 910a0d20256..fd8652d6a2a 100644
--- a/storage/heap/_check.c
+++ b/storage/heap/_check.c
@@ -79,7 +79,7 @@ int heap_check_heap(HP_INFO *info, my_bool print_status)
}
hp_find_record(info,pos);
- if (!info->current_ptr[share->reclength])
+ if (!info->current_ptr[share->visible])
deleted++;
else
records++;
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index a75efb7fb62..dc7b225f592 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -704,7 +704,7 @@ heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
}
}
}
- mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*));
+ mem_per_row+= MY_ALIGN(MY_MAX(share->reclength, sizeof(char*)) + 1, sizeof(char*));
if (table_arg->found_next_number_field)
{
keydef[share->next_number_index].flag|= HA_AUTO_KEY;
diff --git a/storage/heap/heapdef.h b/storage/heap/heapdef.h
index 8d9d1f81c53..a20fe6836a2 100644
--- a/storage/heap/heapdef.h
+++ b/storage/heap/heapdef.h
@@ -83,7 +83,6 @@ extern uchar *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo,
const uchar *key, HASH_INFO *pos);
extern ulong hp_hashnr(HP_KEYDEF *keyinfo,const uchar *key);
extern ulong hp_rec_hashnr(HP_KEYDEF *keyinfo,const uchar *rec);
-extern ulong hp_mask(ulong hashnr,ulong buffmax,ulong maxlength);
extern void hp_movelink(HASH_INFO *pos,HASH_INFO *next_link,
HASH_INFO *newlink);
extern int hp_rec_key_cmp(HP_KEYDEF *keydef,const uchar *rec1,
@@ -111,3 +110,22 @@ void init_heap_psi_keys();
#endif /* HAVE_PSI_INTERFACE */
C_MODE_END
+
+/*
+ Calculate position number for hash value.
+ SYNOPSIS
+ hp_mask()
+ hashnr Hash value
+ buffmax Value such that
+ 2^(n-1) < maxlength <= 2^n = buffmax
+ maxlength
+
+ RETURN
+ Array index, in [0..maxlength)
+*/
+
+static inline ulong hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
+{
+ if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
+ return (hashnr & ((buffmax >> 1) -1));
+}
diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c
index 431e992e75b..ed669069b96 100644
--- a/storage/heap/hp_create.c
+++ b/storage/heap/hp_create.c
@@ -33,6 +33,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
uint keys= create_info->keys;
ulong min_records= create_info->min_records;
ulong max_records= create_info->max_records;
+ uint visible_offset;
DBUG_ENTER("heap_create");
if (!create_info->internal_table)
@@ -58,9 +59,9 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
/*
We have to store sometimes uchar* del_link in records,
- so the record length should be at least sizeof(uchar*)
+ so the visible_offset must be least at sizeof(uchar*)
*/
- set_if_bigger(reclength, sizeof (uchar*));
+ visible_offset= MY_MAX(reclength, sizeof (char*));
for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
{
@@ -154,7 +155,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
share->keydef= (HP_KEYDEF*) (share + 1);
share->key_stat_version= 1;
keyseg= (HA_KEYSEG*) (share->keydef + keys);
- init_block(&share->block, reclength + 1, min_records, max_records);
+ init_block(&share->block, visible_offset + 1, min_records, max_records);
/* Fix keys */
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
@@ -196,6 +197,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
share->max_table_size= create_info->max_table_size;
share->data_length= share->index_length= 0;
share->reclength= reclength;
+ share->visible= visible_offset;
share->blength= 1;
share->keys= keys;
share->max_key_length= max_length;
diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c
index 12f2c65f00b..62f21497f29 100644
--- a/storage/heap/hp_delete.c
+++ b/storage/heap/hp_delete.c
@@ -45,7 +45,7 @@ int heap_delete(HP_INFO *info, const uchar *record)
info->update=HA_STATE_DELETED;
*((uchar**) pos)=share->del_link;
share->del_link=pos;
- pos[share->reclength]=0; /* Record deleted */
+ pos[share->visible]=0; /* Record deleted */
share->deleted++;
share->key_version++;
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
@@ -68,7 +68,7 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
const uchar *record, uchar *recpos, int flag)
{
heap_rb_param custom_arg;
- ulong old_allocated;
+ size_t old_allocated;
int res;
if (flag)
diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c
index eaf284c2015..35a3cd20ee8 100644
--- a/storage/heap/hp_hash.c
+++ b/storage/heap/hp_hash.c
@@ -100,18 +100,20 @@ uchar *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key,
uint nextflag)
{
reg1 HASH_INFO *pos,*prev_ptr;
- int flag;
uint old_nextflag;
HP_SHARE *share=info->s;
DBUG_ENTER("hp_search");
old_nextflag=nextflag;
- flag=1;
prev_ptr=0;
if (share->records)
{
- pos=hp_find_hash(&keyinfo->block, hp_mask(hp_hashnr(keyinfo, key),
- share->blength, share->records));
+ ulong search_pos=
+ hp_mask(hp_hashnr(keyinfo, key), share->blength, share->records);
+ pos=hp_find_hash(&keyinfo->block, search_pos);
+ if (search_pos !=
+ hp_mask(pos->hash_of_key, share->blength, share->records))
+ goto not_found; /* Wrong link */
do
{
if (!hp_key_cmp(keyinfo, pos->ptr_to_rec, key))
@@ -142,17 +144,11 @@ uchar *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key,
}
}
}
- if (flag)
- {
- flag=0; /* Reset flag */
- if (hp_find_hash(&keyinfo->block,
- hp_mask(pos->hash_of_key,
- share->blength, share->records)) != pos)
- break; /* Wrong link */
- }
}
while ((pos=pos->next_key));
}
+
+not_found:
my_errno=HA_ERR_KEY_NOT_FOUND;
if (nextflag == 2 && ! info->current_ptr)
{
@@ -195,26 +191,6 @@ uchar *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key,
/*
- Calculate position number for hash value.
- SYNOPSIS
- hp_mask()
- hashnr Hash value
- buffmax Value such that
- 2^(n-1) < maxlength <= 2^n = buffmax
- maxlength
-
- RETURN
- Array index, in [0..maxlength)
-*/
-
-ulong hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
-{
- if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
- return (hashnr & ((buffmax >> 1) -1));
-}
-
-
-/*
Change
next_link -> ... -> X -> pos
to
@@ -263,10 +239,10 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key)
if (seg->type == HA_KEYTYPE_TEXT)
{
CHARSET_INFO *cs= seg->charset;
- uint length= seg->length;
+ size_t length= seg->length;
if (cs->mbmaxlen > 1)
{
- uint char_length;
+ size_t char_length;
char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen);
set_if_smaller(length, char_length);
}
@@ -275,11 +251,11 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key)
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
{
CHARSET_INFO *cs= seg->charset;
- uint pack_length= 2; /* Key packing is constant */
- uint length= uint2korr(pos);
+ size_t pack_length= 2; /* Key packing is constant */
+ size_t length= uint2korr(pos);
if (cs->mbmaxlen > 1)
{
- uint char_length;
+ size_t char_length;
char_length= my_charpos(cs, pos +pack_length,
pos +pack_length + length,
seg->length/cs->mbmaxlen);
@@ -324,7 +300,7 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
if (seg->type == HA_KEYTYPE_TEXT)
{
CHARSET_INFO *cs= seg->charset;
- uint char_length= seg->length;
+ size_t char_length= seg->length;
if (cs->mbmaxlen > 1)
{
char_length= my_charpos(cs, pos, pos + char_length,
@@ -336,11 +312,11 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
{
CHARSET_INFO *cs= seg->charset;
- uint pack_length= seg->bit_start;
- uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
+ size_t pack_length= seg->bit_start;
+ size_t length= (pack_length == 1 ? (size_t) *(uchar*) pos : uint2korr(pos));
if (cs->mbmaxlen > 1)
{
- uint char_length;
+ size_t char_length;
char_length= my_charpos(cs, pos + pack_length,
pos + pack_length + length,
seg->length/cs->mbmaxlen);
@@ -540,13 +516,13 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2)
if (seg->type == HA_KEYTYPE_TEXT)
{
CHARSET_INFO *cs= seg->charset;
- uint char_length1;
- uint char_length2;
+ size_t char_length1;
+ size_t char_length2;
uchar *pos1= (uchar*)rec1 + seg->start;
uchar *pos2= (uchar*)rec2 + seg->start;
if (cs->mbmaxlen > 1)
{
- uint char_length= seg->length / cs->mbmaxlen;
+ size_t char_length= seg->length / cs->mbmaxlen;
char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length);
set_if_smaller(char_length1, seg->length);
char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length);
@@ -565,13 +541,13 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2)
{
uchar *pos1= (uchar*) rec1 + seg->start;
uchar *pos2= (uchar*) rec2 + seg->start;
- uint char_length1, char_length2;
- uint pack_length= seg->bit_start;
+ size_t char_length1, char_length2;
+ size_t pack_length= seg->bit_start;
CHARSET_INFO *cs= seg->charset;
if (pack_length == 1)
{
- char_length1= (uint) *(uchar*) pos1++;
- char_length2= (uint) *(uchar*) pos2++;
+ char_length1= (size_t) *(uchar*) pos1++;
+ char_length2= (size_t) *(uchar*) pos2++;
}
else
{
@@ -582,9 +558,9 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2)
}
if (cs->mbmaxlen > 1)
{
- uint safe_length1= char_length1;
- uint safe_length2= char_length2;
- uint char_length= seg->length / cs->mbmaxlen;
+ size_t safe_length1= char_length1;
+ size_t safe_length2= char_length2;
+ size_t char_length= seg->length / cs->mbmaxlen;
char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length);
set_if_smaller(char_length1, safe_length1);
char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length);
@@ -647,12 +623,12 @@ int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key)
if (seg->type == HA_KEYTYPE_TEXT)
{
CHARSET_INFO *cs= seg->charset;
- uint char_length_key;
- uint char_length_rec;
+ size_t char_length_key;
+ size_t char_length_rec;
uchar *pos= (uchar*) rec + seg->start;
if (cs->mbmaxlen > 1)
{
- uint char_length= seg->length / cs->mbmaxlen;
+ size_t char_length= seg->length / cs->mbmaxlen;
char_length_key= my_charpos(cs, key, key + seg->length, char_length);
set_if_smaller(char_length_key, seg->length);
char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length);
@@ -673,16 +649,16 @@ int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key)
{
uchar *pos= (uchar*) rec + seg->start;
CHARSET_INFO *cs= seg->charset;
- uint pack_length= seg->bit_start;
- uint char_length_rec= (pack_length == 1 ? (uint) *(uchar*) pos :
+ size_t pack_length= seg->bit_start;
+ size_t char_length_rec= (pack_length == 1 ? (size_t) *(uchar*) pos :
uint2korr(pos));
/* Key segments are always packed with 2 bytes */
- uint char_length_key= uint2korr(key);
+ size_t char_length_key= uint2korr(key);
pos+= pack_length;
key+= 2; /* skip key pack length */
if (cs->mbmaxlen > 1)
{
- uint char_length1, char_length2;
+ size_t char_length1, char_length2;
char_length1= char_length2= seg->length / cs->mbmaxlen;
char_length1= my_charpos(cs, key, key + char_length_key, char_length1);
set_if_smaller(char_length_key, char_length1);
@@ -727,7 +703,7 @@ void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{
CHARSET_INFO *cs= seg->charset;
- uint char_length= seg->length;
+ size_t char_length= seg->length;
uchar *pos= (uchar*) rec + seg->start;
if (seg->null_bit)
*key++= MY_TEST(rec[seg->null_pos] & seg->null_bit);
@@ -766,7 +742,7 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
{
- uint char_length;
+ size_t char_length;
if (seg->null_bit)
{
if (!(*key++= 1 - MY_TEST(rec[seg->null_pos] & seg->null_bit)))
@@ -814,9 +790,9 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
if (seg->flag & HA_VAR_LENGTH_PART)
{
uchar *pos= (uchar*) rec + seg->start;
- uint length= seg->length;
- uint pack_length= seg->bit_start;
- uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
+ size_t length= seg->length;
+ size_t pack_length= seg->bit_start;
+ size_t tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
uint2korr(pos));
CHARSET_INFO *cs= seg->charset;
char_length= length/cs->mbmaxlen;
@@ -864,7 +840,7 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
for (seg= keydef->seg, endseg= seg + keydef->keysegs;
seg < endseg && keypart_map; old+= seg->length, seg++)
{
- uint char_length;
+ size_t char_length;
keypart_map>>= 1;
if (seg->null_bit)
{
@@ -891,8 +867,8 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
{
/* Length of key-part used with heap_rkey() always 2 */
- uint tmp_length=uint2korr(old);
- uint length= seg->length;
+ size_t tmp_length=uint2korr(old);
+ size_t length= seg->length;
CHARSET_INFO *cs= seg->charset;
char_length= length/cs->mbmaxlen;
diff --git a/storage/heap/hp_rrnd.c b/storage/heap/hp_rrnd.c
index 6bf1888275e..1f2a26cb3ed 100644
--- a/storage/heap/hp_rrnd.c
+++ b/storage/heap/hp_rrnd.c
@@ -37,7 +37,7 @@ int heap_rrnd(register HP_INFO *info, uchar *record, uchar *pos)
info->update= 0;
DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
}
- if (!info->current_ptr[share->reclength])
+ if (!info->current_ptr[share->visible])
{
info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
diff --git a/storage/heap/hp_rsame.c b/storage/heap/hp_rsame.c
index 40c5a18f974..19767fd752b 100644
--- a/storage/heap/hp_rsame.c
+++ b/storage/heap/hp_rsame.c
@@ -32,7 +32,7 @@ int heap_rsame(register HP_INFO *info, uchar *record, int inx)
DBUG_ENTER("heap_rsame");
test_active(info);
- if (info->current_ptr[share->reclength])
+ if (info->current_ptr[share->visible])
{
if (inx < -1 || inx >= (int) share->keys)
{
diff --git a/storage/heap/hp_scan.c b/storage/heap/hp_scan.c
index 39a6f2082a3..65726c37e1f 100644
--- a/storage/heap/hp_scan.c
+++ b/storage/heap/hp_scan.c
@@ -62,7 +62,7 @@ int heap_scan(register HP_INFO *info, uchar *record)
}
hp_find_record(info, pos);
}
- if (!info->current_ptr[share->reclength])
+ if (!info->current_ptr[share->visible])
{
DBUG_PRINT("warning",("Found deleted record"));
info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
diff --git a/storage/heap/hp_write.c b/storage/heap/hp_write.c
index 392662f69ae..a1e4de446d0 100644
--- a/storage/heap/hp_write.c
+++ b/storage/heap/hp_write.c
@@ -54,7 +54,7 @@ int heap_write(HP_INFO *info, const uchar *record)
}
memcpy(pos,record,(size_t) share->reclength);
- pos[share->reclength]=1; /* Mark record as not deleted */
+ pos[share->visible]= 1; /* Mark record as not deleted */
if (++share->records == share->blength)
share->blength+= share->blength;
info->s->key_version++;
@@ -92,7 +92,7 @@ err:
share->deleted++;
*((uchar**) pos)=share->del_link;
share->del_link=pos;
- pos[share->reclength]=0; /* Record deleted */
+ pos[share->visible]= 0; /* Record deleted */
DBUG_RETURN(my_errno);
} /* heap_write */
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index 0a9a1a68458..dc61f773e96 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -1,5 +1,5 @@
-# Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
-# Copyright (c) 2014, 2017, MariaDB Corporation
+# Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2018, 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
@@ -136,7 +136,6 @@ SET(INNOBASE_SOURCES
trx/trx0sys.cc
trx/trx0trx.cc
trx/trx0undo.cc
- usr/usr0sess.cc
ut/ut0crc32.cc
ut/ut0dbg.cc
ut/ut0list.cc
@@ -150,6 +149,7 @@ SET(INNOBASE_SOURCES
ut/ut0timer.cc)
MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE
+ MODULE_OUTPUT_NAME ha_innodb
DEFAULT RECOMPILE_FOR_EMBEDDED
LINK_LIBRARIES
${ZLIB_LIBRARY}
@@ -174,15 +174,30 @@ IF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
btr/btr0btr.cc
btr/btr0cur.cc
buf/buf0buf.cc
+ fts/fts0fts.cc
gis/gis0sea.cc
+ handler/handler0alter.cc
+ mtr/mtr0mtr.cc
+ row/row0merge.cc
+ row/row0mysql.cc
+ srv/srv0srv.cc
COMPILE_FLAGS "-O0"
)
ENDIF()
ENDIF()
IF(MSVC)
+ IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ ADD_COMPILE_FLAGS(
+ pars/lexyy.cc
+ COMPILE_FLAGS "/wd4267")
+ ENDIF()
# silence "switch statement contains 'default' but no 'case' label
# on generated file.
TARGET_COMPILE_OPTIONS(innobase PRIVATE "/wd4065")
ENDIF()
ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/extra/mariabackup ${CMAKE_BINARY_DIR}/extra/mariabackup)
+
+IF(TARGET innobase)
+ ADD_DEPENDENCIES(innobase GenError)
+ENDIF()
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index 0fe807ceb00..5bd6ffb77f3 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2014, 2018, 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
@@ -307,7 +307,7 @@ btr_height_get(
root_block = btr_root_block_get(index, RW_S_LATCH, mtr);
if (root_block) {
- height = btr_page_get_level(buf_block_get_frame(root_block), mtr);
+ height = btr_page_get_level(buf_block_get_frame(root_block));
/* Release the S latch on the root page. */
mtr->memo_release(root_block, MTR_MEMO_PAGE_S_FIX);
@@ -872,7 +872,7 @@ btr_page_free(
mtr_t* mtr) /*!< in: mtr */
{
const page_t* page = buf_block_get_frame(block);
- ulint level = btr_page_get_level(page, mtr);
+ ulint level = btr_page_get_level(page);
ut_ad(fil_page_index_page_check(block->frame));
ut_ad(level != ULINT_UNDEFINED);
@@ -976,7 +976,7 @@ btr_page_get_father_node_ptr_func(
ut_ad(dict_index_get_page(index) != page_no);
- level = btr_page_get_level(btr_cur_get_page(cursor), mtr);
+ level = btr_page_get_level(btr_cur_get_page(cursor));
user_rec = btr_cur_get_rec(cursor);
ut_a(page_rec_is_user_rec(user_rec));
@@ -2018,7 +2018,7 @@ btr_root_raise_and_insert(
moving the root records to the new page, emptying the root, putting
a node pointer to the new page, and then splitting the new page. */
- level = btr_page_get_level(root, mtr);
+ level = btr_page_get_level(root);
new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, mtr, mtr);
@@ -2149,7 +2149,7 @@ btr_root_raise_and_insert(
they should already have been set. The previous node field
must be FIL_NULL if root_page_zip != NULL, because the
REC_INFO_MIN_REC_FLAG (of the first user record) will be
- set if and only if btr_page_get_prev() == FIL_NULL. */
+ set if and only if !page_has_prev(). */
btr_page_set_next(root, root_page_zip, FIL_NULL, mtr);
btr_page_set_prev(root, root_page_zip, FIL_NULL, mtr);
@@ -2684,9 +2684,8 @@ btr_attach_half_pages(
}
/* Get the level of the split pages */
- level = btr_page_get_level(buf_block_get_frame(block), mtr);
- ut_ad(level
- == btr_page_get_level(buf_block_get_frame(new_block), mtr));
+ level = btr_page_get_level(buf_block_get_frame(block));
+ ut_ad(level == btr_page_get_level(buf_block_get_frame(new_block)));
/* Build the node pointer (= node key and page address) for the upper
half */
@@ -2870,7 +2869,7 @@ btr_insert_into_right_sibling(
ibool compressed;
dberr_t err;
- ulint level = btr_page_get_level(next_page, mtr);
+ ulint level = btr_page_get_level(next_page);
/* adjust cursor position */
*btr_cur_get_page_cur(cursor) = next_page_cursor;
@@ -3056,7 +3055,7 @@ func_start:
/* 2. Allocate a new page to the index */
new_block = btr_page_alloc(cursor->index, hint_page_no, direction,
- btr_page_get_level(page, mtr), mtr, mtr);
+ btr_page_get_level(page), mtr, mtr);
if (new_block == NULL && os_has_said_disk_full) {
return(NULL);
@@ -3065,7 +3064,7 @@ func_start:
new_page = buf_block_get_frame(new_block);
new_page_zip = buf_block_get_page_zip(new_block);
btr_page_create(new_block, new_page_zip, cursor->index,
- btr_page_get_level(page, mtr), mtr);
+ btr_page_get_level(page), mtr);
/* Only record the leaf level page splits. */
if (page_is_leaf(page)) {
cursor->index->stat_defrag_n_page_split ++;
@@ -3542,11 +3541,10 @@ btr_lift_page_up(
bool lift_father_up;
buf_block_t* block_orig = block;
- ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
- ut_ad(btr_page_get_next(page, mtr) == FIL_NULL);
+ ut_ad(!page_has_siblings(page));
ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table));
- page_level = btr_page_get_level(page, mtr);
+ page_level = btr_page_get_level(page);
root_page_no = dict_index_get_page(index);
{
@@ -3608,10 +3606,9 @@ btr_lift_page_up(
block = father_block;
page = buf_block_get_frame(block);
- page_level = btr_page_get_level(page, mtr);
+ page_level = btr_page_get_level(page);
- ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
- ut_ad(btr_page_get_next(page, mtr) == FIL_NULL);
+ ut_ad(!page_has_siblings(page));
ut_ad(mtr_is_block_fix(
mtr, block, MTR_MEMO_PAGE_X_FIX, index->table));
@@ -3678,7 +3675,7 @@ btr_lift_page_up(
if (dict_index_is_spatial(index)) {
lock_mutex_enter();
lock_prdt_page_free_from_discard(
- block, lock_sys->prdt_page_hash);
+ block, lock_sys.prdt_page_hash);
lock_mutex_exit();
}
lock_update_copy_and_discard(father_block, block);
@@ -3689,7 +3686,7 @@ btr_lift_page_up(
page_t* page = buf_block_get_frame(blocks[i]);
page_zip_des_t* page_zip= buf_block_get_page_zip(blocks[i]);
- ut_ad(btr_page_get_level(page, mtr) == page_level + 1);
+ ut_ad(btr_page_get_level(page) == page_level + 1);
btr_page_set_level(page, page_zip, page_level, mtr);
#ifdef UNIV_ZIP_DEBUG
@@ -3971,7 +3968,7 @@ retry:
/* No GAP lock needs to be worrying about */
lock_mutex_enter();
lock_prdt_page_free_from_discard(
- block, lock_sys->prdt_page_hash);
+ block, lock_sys.prdt_page_hash);
lock_rec_free_all_from_discard_page(block);
lock_mutex_exit();
} else {
@@ -4129,7 +4126,7 @@ retry:
}
lock_mutex_enter();
lock_prdt_page_free_from_discard(
- block, lock_sys->prdt_page_hash);
+ block, lock_sys.prdt_page_hash);
lock_rec_free_all_from_discard_page(block);
lock_mutex_exit();
} else {
@@ -4275,9 +4272,8 @@ btr_discard_only_page_on_level(
const page_t* page = buf_block_get_frame(block);
ut_a(page_get_n_recs(page) == 1);
- ut_a(page_level == btr_page_get_level(page, mtr));
- ut_a(btr_page_get_prev(page, mtr) == FIL_NULL);
- ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
+ ut_a(page_level == btr_page_get_level(page));
+ ut_a(!page_has_siblings(page));
ut_ad(mtr_is_block_fix(
mtr, block, MTR_MEMO_PAGE_X_FIX, index->table));
@@ -4324,7 +4320,7 @@ btr_discard_only_page_on_level(
/* btr_page_empty() is supposed to zero-initialize the field. */
ut_ad(!page_get_instant(block->frame));
- if (index->is_clust()) {
+ if (index->is_primary()) {
/* Concurrent access is prevented by the root_block->lock
X-latch, so this should be safe. */
index->remove_instant();
@@ -4556,7 +4552,7 @@ btr_print_recursive(
ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_SX_FIX, index->table));
- ib::info() << "NODE ON LEVEL " << btr_page_get_level(page, mtr)
+ ib::info() << "NODE ON LEVEL " << btr_page_get_level(page)
<< " page " << block->page.id;
page_print(block, index, width, width);
@@ -4672,7 +4668,7 @@ btr_check_node_ptr(
tuple = dict_index_build_node_ptr(
index, page_rec_get_next(page_get_infimum_rec(page)), 0, heap,
- btr_page_get_level(page, mtr));
+ btr_page_get_level(page));
/* For spatial index, the MBR in the parent rec could be different
with that of first rec of child, their relationship should be
@@ -5003,7 +4999,7 @@ btr_validate_level(
return(false);
}
- while (level != btr_page_get_level(page, &mtr)) {
+ while (level != btr_page_get_level(page)) {
const rec_t* node_ptr;
if (fseg_page_is_free(space, block->page.id.page_no())) {
@@ -5111,7 +5107,7 @@ loop:
ret = false;
}
- ut_a(btr_page_get_level(page, &mtr) == level);
+ ut_a(btr_page_get_level(page) == level);
right_page_no = btr_page_get_next(page, &mtr);
left_page_no = btr_page_get_prev(page, &mtr);
@@ -5256,7 +5252,7 @@ loop:
node_ptr_tuple = dict_index_build_node_ptr(
index,
page_rec_get_next(page_get_infimum_rec(page)),
- 0, heap, btr_page_get_level(page, &mtr));
+ 0, heap, btr_page_get_level(page));
if (cmp_dtuple_rec(node_ptr_tuple, node_ptr,
offsets)) {
@@ -5281,13 +5277,13 @@ loop:
if (left_page_no == FIL_NULL) {
ut_a(node_ptr == page_rec_get_next(
page_get_infimum_rec(father_page)));
- ut_a(btr_page_get_prev(father_page, &mtr) == FIL_NULL);
+ ut_a(!page_has_prev(father_page));
}
if (right_page_no == FIL_NULL) {
ut_a(node_ptr == page_rec_get_prev(
page_get_supremum_rec(father_page)));
- ut_a(btr_page_get_next(father_page, &mtr) == FIL_NULL);
+ ut_a(!page_has_next(father_page));
} else {
const rec_t* right_node_ptr;
@@ -5434,7 +5430,7 @@ btr_validate_spatial_index(
mtr_x_lock(dict_index_get_lock(index), &mtr);
page_t* root = btr_root_get(index, &mtr);
- ulint n = btr_page_get_level(root, &mtr);
+ ulint n = btr_page_get_level(root);
#ifdef UNIV_RTR_DEBUG
fprintf(stderr, "R-tree level is %lu\n", n);
@@ -5501,7 +5497,7 @@ btr_validate_index(
return err;
}
- ulint n = btr_page_get_level(root, &mtr);
+ ulint n = btr_page_get_level(root);
for (ulint i = 0; i <= n; ++i) {
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index e3ac8fb7605..c5463e50b48 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -3,7 +3,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -404,7 +404,7 @@ static
dberr_t
btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
{
- ut_ad(index->is_clust());
+ ut_ad(index->is_primary());
ut_ad(index->n_core_null_bytes == dict_index_t::NO_CORE_NULL_BYTES);
ut_ad(index->table->supports_instant());
ut_ad(index->table->is_readable());
@@ -482,10 +482,11 @@ inconsistent:
/* In fact, because we only ever append fields to the 'default
value' record, it is also OK to perform READ UNCOMMITTED and
then ignore any extra fields, provided that
- trx_rw_is_active(DB_TRX_ID). */
+ trx_sys.is_registered(DB_TRX_ID). */
if (rec_offs_n_fields(offsets) > index->n_fields
- && !trx_rw_is_active(row_get_rec_trx_id(rec, index, offsets),
- NULL, false)) {
+ && !trx_sys.is_registered(current_trx(),
+ row_get_rec_trx_id(rec, index,
+ offsets))) {
goto inconsistent;
}
@@ -553,7 +554,7 @@ btr_cur_instant_root_init(dict_index_t* index, const page_t* page)
{
ut_ad(page_is_root(page));
ut_ad(!page_is_comp(page) == !dict_table_is_comp(index->table));
- ut_ad(index->is_clust());
+ ut_ad(index->is_primary());
ut_ad(!index->is_instant());
ut_ad(index->table->supports_instant());
/* This is normally executed as part of btr_cur_instant_init()
@@ -803,10 +804,10 @@ btr_cur_will_modify_tree(
/* is first, 2nd or last record */
if (page_rec_is_first(rec, page)
- || (mach_read_from_4(page + FIL_PAGE_NEXT) != FIL_NULL
+ || (page_has_next(page)
&& (page_rec_is_last(rec, page)
|| page_rec_is_second_last(rec, page)))
- || (mach_read_from_4(page + FIL_PAGE_PREV) != FIL_NULL
+ || (page_has_prev(page)
&& page_rec_is_second(rec, page))) {
return(true);
}
@@ -891,13 +892,10 @@ btr_cur_need_opposite_intention(
{
switch (lock_intention) {
case BTR_INTENTION_DELETE:
- return((mach_read_from_4(page + FIL_PAGE_PREV) != FIL_NULL
- && page_rec_is_first(rec, page))
- || (mach_read_from_4(page + FIL_PAGE_NEXT) != FIL_NULL
- && page_rec_is_last(rec, page)));
+ return (page_has_prev(page) && page_rec_is_first(rec, page)) ||
+ (page_has_next(page) && page_rec_is_last(rec, page));
case BTR_INTENTION_INSERT:
- return(mach_read_from_4(page + FIL_PAGE_NEXT) != FIL_NULL
- && page_rec_is_last(rec, page));
+ return page_has_next(page) && page_rec_is_last(rec, page);
case BTR_INTENTION_BOTH:
return(false);
}
@@ -919,8 +917,7 @@ search tuple should be performed in the B-tree. InnoDB does an insert
immediately after the cursor. Thus, the cursor may end up on a user record,
or on a page infimum record. */
dberr_t
-btr_cur_search_to_nth_level(
-/*========================*/
+btr_cur_search_to_nth_level_func(
dict_index_t* index, /*!< in: index */
ulint level, /*!< in: the tree level of search */
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
@@ -935,17 +932,16 @@ btr_cur_search_to_nth_level(
cursor->left_block is used to store a pointer
to the left neighbor page, in the cases
BTR_SEARCH_PREV and BTR_MODIFY_PREV;
- NOTE that if has_search_latch
- is != 0, we maybe do not have a latch set
- on the cursor page, we assume
- the caller uses his search latch
- to protect the record! */
+ NOTE that if ahi_latch, we might not have a
+ cursor page latch, we assume that ahi_latch
+ protects the record! */
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
- ulint has_search_latch,
- /*!< in: info on the latch mode the
- caller currently has on search system:
- RW_S_LATCH, or 0 */
+#ifdef BTR_CUR_HASH_ADAPT
+ rw_lock_t* ahi_latch,
+ /*!< in: currently held btr_search_latch
+ (in RW_S_LATCH mode), or NULL */
+#endif /* BTR_CUR_HASH_ADAPT */
const char* file, /*!< in: file name */
unsigned line, /*!< in: line where called */
mtr_t* mtr, /*!< in: mtr */
@@ -1123,17 +1119,15 @@ btr_cur_search_to_nth_level(
&& mode != PAGE_CUR_LE_OR_EXTENDS
# endif /* PAGE_CUR_LE_OR_EXTENDS */
&& !dict_index_is_spatial(index)
- /* If !has_search_latch, we do a dirty read of
+ /* If !ahi_latch, we do a dirty read of
btr_search_enabled below, and btr_search_guess_on_hash()
will have to check it again. */
&& btr_search_enabled
&& !modify_external
&& !(tuple->info_bits & REC_INFO_MIN_REC_FLAG)
- && rw_lock_get_writer(btr_get_search_latch(index))
- == RW_LOCK_NOT_LOCKED
&& btr_search_guess_on_hash(index, info, tuple, mode,
latch_mode, cursor,
- has_search_latch, mtr)) {
+ ahi_latch, mtr)) {
/* Search using the hash index succeeded */
@@ -1154,10 +1148,12 @@ btr_cur_search_to_nth_level(
/* If the hash search did not succeed, do binary search down the
tree */
- if (has_search_latch) {
+#ifdef BTR_CUR_HASH_ADAPT
+ if (ahi_latch) {
/* Release possible search latch to obey latching order */
- btr_search_s_unlock(index);
+ rw_lock_s_unlock(ahi_latch);
}
+#endif /* BTR_CUR_HASH_ADAPT */
/* Store the position of the tree latch we push to mtr so that we
know how to release it when we have latched leaf node(s) */
@@ -1170,7 +1166,7 @@ btr_cur_search_to_nth_level(
Free blocks and read IO bandwidth should be prior
for them, when the history list is glowing huge. */
if (lock_intention == BTR_INTENTION_DELETE
- && trx_sys->rseg_history_len > BTR_CUR_FINE_HISTORY_LENGTH
+ && trx_sys.history_size() > BTR_CUR_FINE_HISTORY_LENGTH
&& buf_get_n_pending_read_ios()) {
mtr_x_lock(dict_index_get_lock(index), mtr);
} else if (dict_index_is_spatial(index)
@@ -1517,7 +1513,7 @@ retry_page_get:
if (height == ULINT_UNDEFINED) {
/* We are in the root node */
- height = btr_page_get_level(page, mtr);
+ height = btr_page_get_level(page);
root_height = height;
cursor->tree_height = root_height + 1;
@@ -1711,8 +1707,7 @@ retry_page_get:
/* If this is the desired level, leave the loop */
- ut_ad(height == btr_page_get_level(page_cur_get_page(page_cursor),
- mtr));
+ ut_ad(height == btr_page_get_level(page_cur_get_page(page_cursor)));
/* Add Predicate lock if it is serializable isolation
and only if it is in the search case */
@@ -1971,7 +1966,7 @@ need_opposite_intention:
MTR_MEMO_PAGE_S_FIX
| MTR_MEMO_PAGE_X_FIX));
- if (btr_page_get_prev(page, mtr) != FIL_NULL
+ if (page_has_prev(page)
&& page_rec_is_first(node_ptr, page)) {
if (leftmost_from_level == 0) {
@@ -2088,7 +2083,7 @@ need_opposite_intention:
} else if (!dict_index_is_spatial(index)
&& latch_mode == BTR_MODIFY_TREE
&& lock_intention == BTR_INTENTION_INSERT
- && mach_read_from_4(page + FIL_PAGE_NEXT) != FIL_NULL
+ && page_has_next(page)
&& page_rec_is_last(page_cur_get_rec(page_cursor), page)) {
/* btr_insert_into_right_sibling() might cause
@@ -2224,15 +2219,17 @@ func_exit:
ut_free(prev_tree_savepoints);
}
- if (has_search_latch) {
- btr_search_s_lock(index);
- }
-
if (mbr_adj) {
/* remember that we will need to adjust parent MBR */
cursor->rtr_info->mbr_adj = true;
}
+#ifdef BTR_CUR_HASH_ADAPT
+ if (ahi_latch) {
+ rw_lock_s_lock(ahi_latch);
+ }
+#endif /* BTR_CUR_HASH_ADAPT */
+
DBUG_RETURN(err);
}
@@ -2308,7 +2305,7 @@ btr_cur_open_at_index_side_func(
Free blocks and read IO bandwidth should be prior
for them, when the history list is glowing huge. */
if (lock_intention == BTR_INTENTION_DELETE
- && trx_sys->rseg_history_len > BTR_CUR_FINE_HISTORY_LENGTH
+ && trx_sys.history_size() > BTR_CUR_FINE_HISTORY_LENGTH
&& buf_get_n_pending_read_ios()) {
mtr_x_lock(dict_index_get_lock(index), mtr);
} else {
@@ -2410,12 +2407,12 @@ btr_cur_open_at_index_side_func(
if (height == ULINT_UNDEFINED) {
/* We are in the root node */
- height = btr_page_get_level(page, mtr);
+ height = btr_page_get_level(page);
root_height = height;
ut_a(height >= level);
} else {
/* TODO: flag the index corrupted if this fails */
- ut_ad(height == btr_page_get_level(page, mtr));
+ ut_ad(height == btr_page_get_level(page));
}
if (height == level) {
@@ -2654,7 +2651,7 @@ btr_cur_open_at_rnd_pos_func(
Free blocks and read IO bandwidth should be prior
for them, when the history list is glowing huge. */
if (lock_intention == BTR_INTENTION_DELETE
- && trx_sys->rseg_history_len > BTR_CUR_FINE_HISTORY_LENGTH
+ && trx_sys.history_size() > BTR_CUR_FINE_HISTORY_LENGTH
&& buf_get_n_pending_read_ios()) {
mtr_x_lock(dict_index_get_lock(index), mtr);
} else {
@@ -2770,7 +2767,7 @@ btr_cur_open_at_rnd_pos_func(
if (height == ULINT_UNDEFINED) {
/* We are in the root node */
- height = btr_page_get_level(page, mtr);
+ height = btr_page_get_level(page);
}
if (height == 0) {
@@ -2975,7 +2972,7 @@ btr_cur_ins_lock_and_undo(
dtuple_t* entry, /*!< in/out: entry to insert */
que_thr_t* thr, /*!< in: query thread or NULL */
mtr_t* mtr, /*!< in/out: mini-transaction */
- ibool* inherit)/*!< out: TRUE if the inserted new record maybe
+ bool* inherit)/*!< out: true if the inserted new record maybe
should inherit LOCK_GAP type locks from the
successor record */
{
@@ -3028,24 +3025,22 @@ btr_cur_ins_lock_and_undo(
}
if (flags & BTR_NO_UNDO_LOG_FLAG) {
- roll_ptr = 0;
+ roll_ptr = roll_ptr_t(1) << ROLL_PTR_INSERT_FLAG_POS;
+ if (!(flags & BTR_KEEP_SYS_FLAG)) {
+upd_sys:
+ row_upd_index_entry_sys_field(entry, index,
+ DATA_ROLL_PTR, roll_ptr);
+ }
} else {
err = trx_undo_report_row_operation(thr, index, entry,
NULL, 0, NULL, NULL,
&roll_ptr);
- if (err != DB_SUCCESS) {
- return(err);
+ if (err == DB_SUCCESS) {
+ goto upd_sys;
}
}
- /* Now we can fill in the roll ptr field in entry */
- if (!(flags & BTR_KEEP_SYS_FLAG)) {
-
- row_upd_index_entry_sys_field(entry, index,
- DATA_ROLL_PTR, roll_ptr);
- }
-
- return(DB_SUCCESS);
+ return(err);
}
/**
@@ -3119,9 +3114,9 @@ btr_cur_optimistic_insert(
buf_block_t* block;
page_t* page;
rec_t* dummy;
- ibool leaf;
- ibool reorg;
- ibool inherit = TRUE;
+ bool leaf;
+ bool reorg;
+ bool inherit = true;
ulint rec_size;
dberr_t err;
@@ -3233,7 +3228,7 @@ fail_err:
DBUG_LOG("ib_cur",
"insert " << index->name << " (" << index->id << ") by "
- << ib::hex(thr ? trx_get_id_for_print(thr_get_trx(thr)) : 0)
+ << ib::hex(thr ? thr->graph->trx->id : 0)
<< ' ' << rec_printer(entry).str());
DBUG_EXECUTE_IF("do_page_reorganize",
btr_page_reorganize(page_cursor, index, mtr););
@@ -3250,6 +3245,32 @@ fail_err:
goto fail_err;
}
+#ifdef UNIV_DEBUG
+ if (!(flags & BTR_CREATE_FLAG)
+ && index->is_primary() && page_is_leaf(page)) {
+ const dfield_t* trx_id = dtuple_get_nth_field(
+ entry, dict_col_get_clust_pos(
+ dict_table_get_sys_col(index->table,
+ DATA_TRX_ID),
+ index));
+
+ ut_ad(trx_id->len == DATA_TRX_ID_LEN);
+ ut_ad(trx_id[1].len == DATA_ROLL_PTR_LEN);
+ ut_ad(*static_cast<const byte*>
+ (trx_id[1].data) & 0x80);
+ if (flags & BTR_NO_UNDO_LOG_FLAG) {
+ ut_ad(!memcmp(trx_id->data, reset_trx_id,
+ DATA_TRX_ID_LEN));
+ } else {
+ ut_ad(thr->graph->trx->id);
+ ut_ad(thr->graph->trx->id
+ == trx_read_trx_id(
+ static_cast<const byte*>(
+ trx_id->data)));
+ }
+ }
+#endif
+
*rec = page_cur_tuple_insert(
page_cursor, entry, index, offsets, heap,
n_ext, mtr);
@@ -3302,10 +3323,14 @@ fail_err:
ut_ad(entry->info_bits == REC_INFO_DEFAULT_ROW);
ut_ad(index->is_instant());
ut_ad(flags == BTR_NO_LOCKING_FLAG);
- } else if (!reorg && cursor->flag == BTR_CUR_HASH) {
- btr_search_update_hash_node_on_insert(cursor);
} else {
- btr_search_update_hash_on_insert(cursor);
+ rw_lock_t* ahi_latch = btr_get_search_latch(index);
+ if (!reorg && cursor->flag == BTR_CUR_HASH) {
+ btr_search_update_hash_node_on_insert(
+ cursor, ahi_latch);
+ } else {
+ btr_search_update_hash_on_insert(cursor, ahi_latch);
+ }
}
#endif /* BTR_CUR_HASH_ADAPT */
@@ -3382,7 +3407,7 @@ btr_cur_pessimistic_insert(
dict_index_t* index = cursor->index;
big_rec_t* big_rec_vec = NULL;
dberr_t err;
- ibool inherit = FALSE;
+ bool inherit = false;
bool success;
ulint n_reserved = 0;
@@ -3493,7 +3518,7 @@ btr_cur_pessimistic_insert(
== FIL_NULL) {
/* split and inserted need to call
lock_update_insert() always. */
- inherit = TRUE;
+ inherit = true;
}
}
}
@@ -3511,7 +3536,8 @@ btr_cur_pessimistic_insert(
ut_ad((flags & ~BTR_KEEP_IBUF_BITMAP)
== BTR_NO_LOCKING_FLAG);
} else {
- btr_search_update_hash_on_insert(cursor);
+ btr_search_update_hash_on_insert(
+ cursor, btr_get_search_latch(index));
}
#endif /* BTR_CUR_HASH_ADAPT */
if (inherit && !(flags & BTR_NO_LOCKING_FLAG)) {
@@ -3713,7 +3739,15 @@ btr_cur_parse_update_in_place(
/* We do not need to reserve search latch, as the page is only
being recovered, and there cannot be a hash index to it. */
- offsets = rec_get_offsets(rec, index, NULL, true,
+ /* The function rtr_update_mbr_field_in_place() is generating
+ these records on node pointer pages; therefore we have to
+ check if this is a leaf page. */
+
+ offsets = rec_get_offsets(rec, index, NULL,
+ flags != (BTR_NO_UNDO_LOG_FLAG
+ | BTR_NO_LOCKING_FLAG
+ | BTR_KEEP_SYS_FLAG)
+ || page_is_leaf(page),
ULINT_UNDEFINED, &heap);
if (!(flags & BTR_KEEP_SYS_FLAG)) {
@@ -3849,6 +3883,7 @@ btr_cur_update_in_place(
roll_ptr_t roll_ptr = 0;
ulint was_delete_marked;
+ ut_ad(page_is_leaf(cursor->page_cur.block->frame));
rec = btr_cur_get_rec(cursor);
index = cursor->index;
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -3913,34 +3948,39 @@ btr_cur_update_in_place(
|| row_get_rec_trx_id(rec, index, offsets));
#ifdef BTR_CUR_HASH_ADAPT
- if (block->index) {
- /* TO DO: Can we skip this if none of the fields
- index->search_info->curr_n_fields
- are being updated? */
-
- /* The function row_upd_changes_ord_field_binary works only
- if the update vector was built for a clustered index, we must
- NOT call it if index is secondary */
+ {
+ rw_lock_t* ahi_latch = block->index
+ ? btr_get_search_latch(index) : NULL;
+ if (ahi_latch) {
+ /* TO DO: Can we skip this if none of the fields
+ index->search_info->curr_n_fields
+ are being updated? */
+
+ /* The function row_upd_changes_ord_field_binary
+ does not work on a secondary index. */
+
+ if (!dict_index_is_clust(index)
+ || row_upd_changes_ord_field_binary(
+ index, update, thr, NULL, NULL)) {
+ ut_ad(!(update->info_bits
+ & REC_INFO_MIN_REC_FLAG));
+ /* Remove possible hash index pointer
+ to this record */
+ btr_search_update_hash_on_delete(cursor);
+ }
- if (!dict_index_is_clust(index)
- || row_upd_changes_ord_field_binary(index, update, thr,
- NULL, NULL)) {
- ut_ad(!(update->info_bits & REC_INFO_MIN_REC_FLAG));
- /* Remove possible hash index pointer to this record */
- btr_search_update_hash_on_delete(cursor);
+ rw_lock_x_lock(ahi_latch);
}
- btr_search_x_lock(index);
- }
-
- assert_block_ahi_valid(block);
+ assert_block_ahi_valid(block);
#endif /* BTR_CUR_HASH_ADAPT */
- row_upd_rec_in_place(rec, index, offsets, update, page_zip);
+ row_upd_rec_in_place(rec, index, offsets, update, page_zip);
#ifdef BTR_CUR_HASH_ADAPT
- if (block->index) {
- btr_search_x_unlock(index);
+ if (ahi_latch) {
+ rw_lock_x_unlock(ahi_latch);
+ }
}
#endif /* BTR_CUR_HASH_ADAPT */
@@ -5315,7 +5355,7 @@ btr_cur_optimistic_delete_func(
index->is_instant() will hold until the
insert into SYS_COLUMNS is rolled back. */
ut_ad(index->table->supports_instant());
- ut_ad(index->is_clust());
+ ut_ad(index->is_primary());
} else {
lock_update_delete(block, rec);
}
@@ -5323,7 +5363,7 @@ btr_cur_optimistic_delete_func(
index, 0, mtr);
page_cur_set_after_last(block, btr_cur_get_page_cur(cursor));
- if (index->is_clust()) {
+ if (index->is_primary()) {
/* Concurrent access is prevented by
root_block->lock X-latch, so this should be
safe. */
@@ -5352,7 +5392,7 @@ btr_cur_optimistic_delete_func(
index->is_instant() will hold until the
insert into SYS_COLUMNS is rolled back. */
ut_ad(cursor->index->table->supports_instant());
- ut_ad(cursor->index->is_clust());
+ ut_ad(cursor->index->is_primary());
ut_ad(!page_zip);
page_cur_delete_rec(btr_cur_get_page_cur(cursor),
cursor->index, offsets, mtr);
@@ -5519,7 +5559,7 @@ btr_cur_pessimistic_delete(
insert into SYS_COLUMNS is rolled back. */
ut_ad(rollback);
ut_ad(index->table->supports_instant());
- ut_ad(index->is_clust());
+ ut_ad(index->is_primary());
} else if (flags == 0) {
lock_update_delete(block, rec);
}
@@ -5545,7 +5585,7 @@ btr_cur_pessimistic_delete(
btr_page_empty(block, page_zip, index, 0, mtr);
page_cur_set_after_last(block,
btr_cur_get_page_cur(cursor));
- if (index->is_clust()) {
+ if (index->is_primary()) {
/* Concurrent access is prevented by
index->lock and root_block->lock
X-latch, so this should be safe. */
@@ -5584,7 +5624,7 @@ discard_page:
rec_t* next_rec = page_rec_get_next(rec);
- if (btr_page_get_prev(page, mtr) == FIL_NULL) {
+ if (!page_has_prev(page)) {
/* If we delete the leftmost node pointer on a
non-leaf level, we must mark the new leftmost node
@@ -5636,7 +5676,7 @@ discard_page:
on the page */
btr_node_ptr_delete(index, block, mtr);
- const ulint level = btr_page_get_level(page, mtr);
+ const ulint level = btr_page_get_level(page);
dtuple_t* node_ptr = dict_index_build_node_ptr(
index, next_rec, block->page.id.page_no(),
@@ -5726,7 +5766,7 @@ btr_cur_add_path_info(
slot->nth_rec = page_rec_get_n_recs_before(rec);
slot->n_recs = page_get_n_recs(page);
slot->page_no = page_get_page_no(page);
- slot->page_level = btr_page_get_level_low(page);
+ slot->page_level = btr_page_get_level(page);
}
/*******************************************************************//**
@@ -5843,7 +5883,7 @@ btr_estimate_n_rows_in_range_on_level(
reuses them. */
if (!fil_page_index_page_check(page)
|| btr_page_get_index_id(page) != index->id
- || btr_page_get_level_low(page) != level) {
+ || btr_page_get_level(page) != level) {
/* The page got reused for something else */
mtr_commit(&mtr);
@@ -6566,7 +6606,8 @@ btr_estimate_number_of_different_key_vals(
}
}
- if (n_cols == dict_index_get_n_unique_in_tree(index)) {
+ if (n_cols == dict_index_get_n_unique_in_tree(index)
+ && page_has_siblings(page)) {
/* If there is more than one leaf page in the tree,
we add one because we know that the first record
@@ -6577,11 +6618,7 @@ btr_estimate_number_of_different_key_vals(
algorithm grossly underestimated the number of rows
in the table. */
- if (btr_page_get_prev(page, &mtr) != FIL_NULL
- || btr_page_get_next(page, &mtr) != FIL_NULL) {
-
- n_diff[n_cols - 1]++;
- }
+ n_diff[n_cols - 1]++;
}
mtr_commit(&mtr);
@@ -7763,7 +7800,7 @@ btr_free_externally_stored_field(
MLOG_4BYTES, &mtr);
/* Zero out the BLOB length. If the server
crashes during the execution of this function,
- trx_rollback_or_clean_all_recovered() could
+ trx_rollback_all_recovered() could
dereference the half-deleted BLOB, fetching a
wrong prefix for the BLOB. */
mlog_write_ulint(field_ref + BTR_EXTERN_LEN + 4,
diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc
index 70444ca1830..31f03fe5d3e 100644
--- a/storage/innobase/btr/btr0defragment.cc
+++ b/storage/innobase/btr/btr0defragment.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2014 Facebook, Inc. All Rights Reserved.
-Copyright (C) 2014, 2017, MariaDB Corporation.
+Copyright (C) 2014, 2018, 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
@@ -438,7 +438,7 @@ btr_defragment_merge_pages(
page_t* from_page = buf_block_get_frame(from_block);
page_t* to_page = buf_block_get_frame(to_block);
ulint space = dict_index_get_space(index);
- ulint level = btr_page_get_level(from_page, mtr);
+ ulint level = btr_page_get_level(from_page);
ulint n_recs = page_get_n_recs(from_page);
ulint new_data_size = page_get_data_size(to_page);
ulint max_ins_size =
@@ -623,7 +623,7 @@ btr_defragment_n_pages(
}
first_page = buf_block_get_frame(block);
- level = btr_page_get_level(first_page, mtr);
+ level = btr_page_get_level(first_page);
const page_size_t page_size(dict_table_page_size(index->table));
if (level != 0) {
@@ -650,7 +650,7 @@ btr_defragment_n_pages(
}
if (n_pages == 1) {
- if (btr_page_get_prev(first_page, mtr) == FIL_NULL) {
+ if (!page_has_prev(first_page)) {
/* last page in the index */
if (dict_index_get_page(index)
== page_get_page_no(first_page))
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index 2b85c764a3b..c29f96b1125 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -132,8 +132,7 @@ btr_pcur_store_position(
we do not store the modify_clock, but always do a search
if we restore the cursor position */
- ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
- ut_a(btr_page_get_prev(page, mtr) == FIL_NULL);
+ ut_a(!page_has_siblings(page));
ut_ad(page_is_leaf(page));
ut_ad(page_get_page_no(page) == index->page);
@@ -353,7 +352,11 @@ btr_pcur_restore_position_func(
}
btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode,
- cursor, 0, file, line, mtr);
+ cursor,
+#ifdef BTR_CUR_HASH_ADAPT
+ NULL,
+#endif /* BTR_CUR_HASH_ADAPT */
+ file, line, mtr);
/* Restore the old search mode */
cursor->search_mode = old_mode;
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 6613e4c59f8..ccd3e2f129f 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -45,10 +45,10 @@ Created 2/17/1996 Heikki Tuuri
/** Is search system enabled.
Search system is protected by array of latches. */
-char btr_search_enabled = true;
+char btr_search_enabled;
/** Number of adaptive hash index partition. */
-ulong btr_ahi_parts = 8;
+ulong btr_ahi_parts;
#ifdef UNIV_SEARCH_PERF_STAT
/** Number of successful adaptive hash index lookups */
@@ -177,23 +177,6 @@ btr_search_get_n_fields(
return(btr_search_get_n_fields(cursor->n_fields, cursor->n_bytes));
}
-/********************************************************************//**
-Builds a hash index on a page with the given parameters. If the page already
-has a hash index with different parameters, the old hash index is removed.
-If index is non-NULL, this function checks if n_fields and n_bytes are
-sensible values, and does not build a hash index if not. */
-static
-void
-btr_search_build_page_hash_index(
-/*=============================*/
- dict_index_t* index, /*!< in: index for which to build, or NULL if
- not known */
- buf_block_t* block, /*!< in: index page, s- or x-latched */
- ulint n_fields,/*!< in: hash this many full fields */
- ulint n_bytes,/*!< in: hash this many bytes from the next
- field */
- ibool left_side);/*!< in: hash for searches from left side? */
-
/** This function should be called before reserving any btr search mutex, if
the intended operation might add nodes to the search system hash table.
Because of the latching order, once we have reserved the btr search system
@@ -206,13 +189,13 @@ will not guarantee success.
@param[in] index index handler */
static
void
-btr_search_check_free_space_in_heap(dict_index_t* index)
+btr_search_check_free_space_in_heap(const dict_index_t* index)
{
hash_table_t* table;
mem_heap_t* heap;
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
+ ut_ad(!btr_search_own_any(RW_LOCK_S));
+ ut_ad(!btr_search_own_any(RW_LOCK_X));
table = btr_get_search_table(index);
@@ -224,8 +207,9 @@ btr_search_check_free_space_in_heap(dict_index_t* index)
if (heap->free_block == NULL) {
buf_block_t* block = buf_block_alloc(NULL);
+ rw_lock_t* ahi_latch = btr_get_search_latch(index);
- btr_search_x_lock(index);
+ rw_lock_x_lock(ahi_latch);
if (btr_search_enabled
&& heap->free_block == NULL) {
@@ -234,7 +218,7 @@ btr_search_check_free_space_in_heap(dict_index_t* index)
buf_block_free(block);
}
- btr_search_x_unlock(index);
+ rw_lock_x_unlock(ahi_latch);
}
}
@@ -361,9 +345,6 @@ btr_search_disable_ref_count(
for (index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
-
- ut_ad(rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
-
index->search_info->ref_count = 0;
}
}
@@ -457,12 +438,10 @@ btr_search_info_get_ref_count(
ut_ad(info);
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
-
- btr_search_s_lock(index);
+ rw_lock_t* ahi_latch = btr_get_search_latch(index);
+ rw_lock_s_lock(ahi_latch);
ret = info->ref_count;
- btr_search_s_unlock(index);
+ rw_lock_s_unlock(ahi_latch);
return(ret);
}
@@ -482,8 +461,8 @@ btr_search_info_update_hash(
ulint n_unique;
int cmp;
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
+ ut_ad(!btr_search_own_any(RW_LOCK_S));
+ ut_ad(!btr_search_own_any(RW_LOCK_X));
if (dict_index_is_ibuf(index)) {
/* So many deletes are performed on an insert buffer tree
@@ -590,14 +569,14 @@ semaphore, to save CPU time! Do not assume the fields are consistent.
@param[in,out] block buffer block
@param[in] cursor cursor */
static
-ibool
+bool
btr_search_update_block_hash_info(
btr_search_t* info,
buf_block_t* block,
const btr_cur_t* cursor)
{
- ut_ad(!rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_S));
- ut_ad(!rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_X));
+ ut_ad(!btr_search_own_any(RW_LOCK_S));
+ ut_ad(!btr_search_own_any(RW_LOCK_X));
ut_ad(rw_lock_own(&block->lock, RW_LOCK_S)
|| rw_lock_own(&block->lock, RW_LOCK_X));
@@ -644,11 +623,11 @@ btr_search_update_block_hash_info(
/* Build a new hash index on the page */
- return(TRUE);
+ return(true);
}
}
- return(FALSE);
+ return(false);
}
/** Updates a hash node reference when it has been unsuccessfully used in a
@@ -688,8 +667,8 @@ btr_search_update_hash_ref(
}
ut_ad(block->page.id.space() == index->space);
- ut_a(index == cursor->index);
- ut_a(!dict_index_is_ibuf(index));
+ ut_ad(index == cursor->index);
+ ut_ad(!dict_index_is_ibuf(index));
if ((info->n_hash_potential > 0)
&& (block->curr_n_fields == info->n_fields)
@@ -714,7 +693,6 @@ btr_search_update_hash_ref(
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
- ut_ad(rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
ha_insert_for_fold(btr_get_search_table(index), fold,
block, rec);
@@ -723,61 +701,6 @@ btr_search_update_hash_ref(
}
}
-/** Updates the search info.
-@param[in,out] info search info
-@param[in] cursor cursor which was just positioned */
-void
-btr_search_info_update_slow(
- btr_search_t* info,
- btr_cur_t* cursor)
-{
- buf_block_t* block;
- ibool build_index;
-
- ut_ad(!rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_S));
- ut_ad(!rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_X));
-
- block = btr_cur_get_block(cursor);
-
- /* NOTE that the following two function calls do NOT protect
- info or block->n_fields etc. with any semaphore, to save CPU time!
- We cannot assume the fields are consistent when we return from
- those functions! */
-
- btr_search_info_update_hash(info, cursor);
-
- build_index = btr_search_update_block_hash_info(info, block, cursor);
-
- if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {
-
- btr_search_check_free_space_in_heap(cursor->index);
- }
-
- if (cursor->flag == BTR_CUR_HASH_FAIL) {
- /* Update the hash node reference, if appropriate */
-
-#ifdef UNIV_SEARCH_PERF_STAT
- btr_search_n_hash_fail++;
-#endif /* UNIV_SEARCH_PERF_STAT */
-
- btr_search_x_lock(cursor->index);
-
- btr_search_update_hash_ref(info, block, cursor);
-
- btr_search_x_unlock(cursor->index);
- }
-
- if (build_index) {
- /* Note that since we did not protect block->n_fields etc.
- with any semaphore, the values can be inconsistent. We have
- to check inside the function call that they make sense. */
- btr_search_build_page_hash_index(cursor->index, block,
- block->n_fields,
- block->n_bytes,
- block->left_side);
- }
-}
-
/** Checks if a guessed position for a tree cursor is right. Note that if
mode is PAGE_CUR_LE, which is used in inserts, and the function returns
TRUE, then cursor->up_match and cursor->low_match both have sensible values.
@@ -791,16 +714,14 @@ TRUE, then cursor->up_match and cursor->low_match both have sensible values.
previous record to check our guess!
@param[in] tuple data tuple
@param[in] mode PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G, PAGE_CUR_GE
-@param[in] mtr mini transaction
-@return TRUE if success */
+@return whether a match was found */
static
-ibool
+bool
btr_search_check_guess(
btr_cur_t* cursor,
- ibool can_only_compare_to_cursor_rec,
+ bool can_only_compare_to_cursor_rec,
const dtuple_t* tuple,
- ulint mode,
- mtr_t* mtr)
+ ulint mode)
{
rec_t* rec;
ulint n_unique;
@@ -862,14 +783,13 @@ btr_search_check_guess(
match = 0;
if ((mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)) {
- rec_t* prev_rec;
-
ut_ad(!page_rec_is_infimum(rec));
- prev_rec = page_rec_get_prev(rec);
+ const rec_t* prev_rec = page_rec_get_prev(rec);
if (page_rec_is_infimum(prev_rec)) {
- success = btr_page_get_prev(page_align(prev_rec), mtr)
+ success = *reinterpret_cast<const uint32_t*>(
+ page_align(prev_rec) + FIL_PAGE_PREV)
== FIL_NULL;
goto exit_func;
@@ -884,17 +804,14 @@ btr_search_check_guess(
} else {
success = cmp >= 0;
}
-
- goto exit_func;
} else {
- rec_t* next_rec;
-
ut_ad(!page_rec_is_supremum(rec));
- next_rec = page_rec_get_next(rec);
+ const rec_t* next_rec = page_rec_get_next(rec);
if (page_rec_is_supremum(next_rec)) {
- if (btr_page_get_next(page_align(next_rec), mtr)
+ if (*reinterpret_cast<const uint32_t*>(
+ page_align(next_rec) + FIL_PAGE_NEXT)
== FIL_NULL) {
cursor->up_match = 0;
@@ -953,12 +870,11 @@ both have sensible values.
we assume the caller uses his search latch
to protect the record!
@param[out] cursor tree cursor
-@param[in] has_search_latch
- latch mode the caller currently has on
- search system: RW_S/X_LATCH or 0
+@param[in] ahi_latch the adaptive hash index latch being held,
+ or NULL
@param[in] mtr mini transaction
-@return TRUE if succeeded */
-ibool
+@return whether the search succeeded */
+bool
btr_search_guess_on_hash(
dict_index_t* index,
btr_search_t* info,
@@ -966,7 +882,7 @@ btr_search_guess_on_hash(
ulint mode,
ulint latch_mode,
btr_cur_t* cursor,
- ulint has_search_latch,
+ rw_lock_t* ahi_latch,
mtr_t* mtr)
{
const rec_t* rec;
@@ -976,6 +892,8 @@ btr_search_guess_on_hash(
btr_cur_t cursor2;
btr_pcur_t pcur;
#endif
+ ut_ad(!ahi_latch || rw_lock_own(ahi_latch, RW_LOCK_S)
+ || rw_lock_own(ahi_latch, RW_LOCK_X));
if (!btr_search_enabled) {
return(FALSE);
@@ -983,6 +901,7 @@ btr_search_guess_on_hash(
ut_ad(index && info && tuple && cursor && mtr);
ut_ad(!dict_index_is_ibuf(index));
+ ut_ad(!ahi_latch || ahi_latch == btr_get_search_latch(index));
ut_ad((latch_mode == BTR_SEARCH_LEAF)
|| (latch_mode == BTR_MODIFY_LEAF));
@@ -1015,28 +934,26 @@ btr_search_guess_on_hash(
cursor->fold = fold;
cursor->flag = BTR_CUR_HASH;
- if (!has_search_latch) {
- btr_search_s_lock(index);
+ rw_lock_t* use_latch = ahi_latch ? NULL : btr_get_search_latch(index);
- if (!btr_search_enabled) {
- btr_search_s_unlock(index);
+ if (use_latch) {
+ rw_lock_s_lock(use_latch);
- btr_search_failure(info, cursor);
-
- return(FALSE);
+ if (!btr_search_enabled) {
+ goto fail;
}
+ } else {
+ ut_ad(btr_search_enabled);
+ ut_ad(rw_lock_own(ahi_latch, RW_LOCK_S));
}
- ut_ad(rw_lock_get_writer(btr_get_search_latch(index)) != RW_LOCK_X);
- ut_ad(rw_lock_get_reader_count(btr_get_search_latch(index)) > 0);
-
rec = (rec_t*) ha_search_and_get_data(
- btr_get_search_table(index), fold);
+ btr_get_search_table(index), fold);
if (rec == NULL) {
-
- if (!has_search_latch) {
- btr_search_s_unlock(index);
+ if (use_latch) {
+fail:
+ rw_lock_s_unlock(use_latch);
}
btr_search_failure(info, cursor);
@@ -1046,22 +963,15 @@ btr_search_guess_on_hash(
buf_block_t* block = buf_block_from_ahi(rec);
- if (!has_search_latch) {
+ if (use_latch) {
if (!buf_page_get_known_nowait(
latch_mode, block, BUF_MAKE_YOUNG,
__FILE__, __LINE__, mtr)) {
-
- if (!has_search_latch) {
- btr_search_s_unlock(index);
- }
-
- btr_search_failure(info, cursor);
-
- return(FALSE);
+ goto fail;
}
- btr_search_s_unlock(index);
+ rw_lock_s_unlock(use_latch);
buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
}
@@ -1070,7 +980,7 @@ btr_search_guess_on_hash(
ut_ad(buf_block_get_state(block) == BUF_BLOCK_REMOVE_HASH);
- if (!has_search_latch) {
+ if (!ahi_latch) {
btr_leaf_page_release(block, latch_mode, mtr);
}
@@ -1092,11 +1002,9 @@ btr_search_guess_on_hash(
record to determine if our guess for the cursor position is
right. */
if (index_id != btr_page_get_index_id(block->frame)
- || !btr_search_check_guess(cursor,
- has_search_latch,
- tuple, mode, mtr)) {
+ || !btr_search_check_guess(cursor, !!ahi_latch, tuple, mode)) {
- if (!has_search_latch) {
+ if (!ahi_latch) {
btr_leaf_page_release(block, latch_mode, mtr);
}
@@ -1117,7 +1025,7 @@ btr_search_guess_on_hash(
info->last_hash_succ = FALSE;
/* Currently, does not work if the following fails: */
- ut_ad(!has_search_latch);
+ ut_ad(!ahi_latch);
btr_leaf_page_release(block, latch_mode, mtr);
@@ -1150,7 +1058,7 @@ btr_search_guess_on_hash(
#ifdef UNIV_SEARCH_PERF_STAT
btr_search_n_succ++;
#endif
- if (!has_search_latch && buf_page_peek_if_too_old(&block->page)) {
+ if (!ahi_latch && buf_page_peek_if_too_old(&block->page)) {
buf_page_make_young(&block->page);
}
@@ -1198,6 +1106,8 @@ retry:
/* This debug check uses a dirty read that could theoretically cause
false positives while buf_pool_clear_hash_index() is executing. */
assert_block_ahi_valid(block);
+ ut_ad(!btr_search_own_any(RW_LOCK_S));
+ ut_ad(!btr_search_own_any(RW_LOCK_X));
if (index == NULL) {
return;
@@ -1221,9 +1131,6 @@ retry:
% btr_ahi_parts;
latch = btr_search_latches[ahi_slot];
- ut_ad(!btr_search_own_any(RW_LOCK_S));
- ut_ad(!btr_search_own_any(RW_LOCK_X));
-
rw_lock_s_lock(latch);
assert_block_ahi_valid(block);
@@ -1426,6 +1333,7 @@ If index is non-NULL, this function checks if n_fields and n_bytes are
sensible, and does not build a hash index if not.
@param[in,out] index index for which to build.
@param[in,out] block index page, s-/x- latched.
+@param[in,out] ahi_latch the adaptive search latch
@param[in] n_fields hash this many full fields
@param[in] n_bytes hash this many bytes of the next field
@param[in] left_side hash for searches from left side */
@@ -1434,12 +1342,11 @@ void
btr_search_build_page_hash_index(
dict_index_t* index,
buf_block_t* block,
+ rw_lock_t* ahi_latch,
ulint n_fields,
ulint n_bytes,
ibool left_side)
{
- hash_table_t* table;
- page_t* page;
const rec_t* rec;
const rec_t* next_rec;
ulint fold;
@@ -1461,29 +1368,26 @@ btr_search_build_page_hash_index(
}
rec_offs_init(offsets_);
+ ut_ad(ahi_latch == btr_get_search_latch(index));
ut_ad(index);
ut_ad(block->page.id.space() == index->space);
ut_a(!dict_index_is_ibuf(index));
ut_ad(page_is_leaf(block->frame));
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_S)
|| rw_lock_own(&(block->lock), RW_LOCK_X));
- btr_search_s_lock(index);
+ rw_lock_s_lock(ahi_latch);
- table = btr_get_search_table(index);
- page = buf_block_get_frame(block);
-
- if (block->index && ((block->curr_n_fields != n_fields)
- || (block->curr_n_bytes != n_bytes)
- || (block->curr_left_side != left_side))) {
+ const bool rebuild = block->index
+ && (block->curr_n_fields != n_fields
+ || block->curr_n_bytes != n_bytes
+ || block->curr_left_side != left_side);
- btr_search_s_unlock(index);
+ rw_lock_s_unlock(ahi_latch);
+ if (rebuild) {
btr_search_drop_page_hash_index(block);
- } else {
- btr_search_s_unlock(index);
}
/* Check that the values for hash index build are sensible */
@@ -1498,6 +1402,7 @@ btr_search_build_page_hash_index(
return;
}
+ page_t* page = buf_block_get_frame(block);
n_recs = page_get_n_recs(page);
if (n_recs == 0) {
@@ -1580,7 +1485,8 @@ btr_search_build_page_hash_index(
btr_search_check_free_space_in_heap(index);
- btr_search_x_lock(index);
+ hash_table_t* table = btr_get_search_table(index);
+ rw_lock_x_lock(ahi_latch);
if (!btr_search_enabled) {
goto exit_func;
@@ -1618,7 +1524,7 @@ btr_search_build_page_hash_index(
MONITOR_INC_VALUE(MONITOR_ADAPTIVE_HASH_ROW_ADDED, n_cached);
exit_func:
assert_block_ahi_valid(block);
- btr_search_x_unlock(index);
+ rw_lock_x_unlock(ahi_latch);
ut_free(folds);
ut_free(recs);
@@ -1627,6 +1533,60 @@ exit_func:
}
}
+/** Updates the search info.
+@param[in,out] info search info
+@param[in,out] cursor cursor which was just positioned */
+void
+btr_search_info_update_slow(btr_search_t* info, btr_cur_t* cursor)
+{
+ rw_lock_t* ahi_latch = btr_get_search_latch(cursor->index);
+
+ ut_ad(!rw_lock_own(ahi_latch, RW_LOCK_S));
+ ut_ad(!rw_lock_own(ahi_latch, RW_LOCK_X));
+
+ buf_block_t* block = btr_cur_get_block(cursor);
+
+ /* NOTE that the following two function calls do NOT protect
+ info or block->n_fields etc. with any semaphore, to save CPU time!
+ We cannot assume the fields are consistent when we return from
+ those functions! */
+
+ btr_search_info_update_hash(info, cursor);
+
+ bool build_index = btr_search_update_block_hash_info(
+ info, block, cursor);
+
+ if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {
+
+ btr_search_check_free_space_in_heap(cursor->index);
+ }
+
+ if (cursor->flag == BTR_CUR_HASH_FAIL) {
+ /* Update the hash node reference, if appropriate */
+
+#ifdef UNIV_SEARCH_PERF_STAT
+ btr_search_n_hash_fail++;
+#endif /* UNIV_SEARCH_PERF_STAT */
+
+ rw_lock_x_lock(ahi_latch);
+
+ btr_search_update_hash_ref(info, block, cursor);
+
+ rw_lock_x_unlock(ahi_latch);
+ }
+
+ if (build_index) {
+ /* Note that since we did not protect block->n_fields etc.
+ with any semaphore, the values can be inconsistent. We have
+ to check inside the function call that they make sense. */
+ btr_search_build_page_hash_index(cursor->index, block,
+ ahi_latch,
+ block->n_fields,
+ block->n_bytes,
+ block->left_side);
+ }
+}
+
/** Move or delete hash entries for moved records, usually in a page split.
If new_block is already hashed, then any hash index for block is dropped.
If new_block is not hashed, and block is hashed, then a new hash index is
@@ -1645,19 +1605,27 @@ btr_search_move_or_delete_hash_entries(
return;
}
+ dict_index_t* index = block->index;
+ if (!index) {
+ index = new_block->index;
+ } else {
+ ut_ad(!new_block->index || index == new_block->index);
+ }
assert_block_ahi_valid(block);
assert_block_ahi_valid(new_block);
+ rw_lock_t* ahi_latch = index ? btr_get_search_latch(index) : NULL;
+
if (new_block->index) {
btr_search_drop_page_hash_index(block);
return;
}
- dict_index_t* index = block->index;
if (!index) {
return;
}
- btr_search_s_lock(index);
+
+ rw_lock_s_lock(ahi_latch);
if (block->index) {
ulint n_fields = block->curr_n_fields;
@@ -1668,19 +1636,20 @@ btr_search_move_or_delete_hash_entries(
new_block->n_bytes = block->curr_n_bytes;
new_block->left_side = left_side;
- btr_search_s_unlock(index);
+ rw_lock_s_unlock(ahi_latch);
ut_a(n_fields > 0 || n_bytes > 0);
btr_search_build_page_hash_index(
- index, new_block, n_fields, n_bytes, left_side);
+ index, new_block, ahi_latch,
+ n_fields, n_bytes, left_side);
ut_ad(n_fields == block->curr_n_fields);
ut_ad(n_bytes == block->curr_n_bytes);
ut_ad(left_side == block->curr_left_side);
return;
}
- btr_search_s_unlock(index);
+ rw_lock_s_unlock(ahi_latch);
}
/** Updates the page hash index when a single record is deleted from a page.
@@ -1735,7 +1704,9 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
mem_heap_free(heap);
}
- btr_search_x_lock(index);
+ rw_lock_t* ahi_latch = btr_get_search_latch(index);
+
+ rw_lock_x_lock(ahi_latch);
assert_block_ahi_valid(block);
if (block->index) {
@@ -1751,21 +1722,25 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
assert_block_ahi_valid(block);
}
- btr_search_x_unlock(index);
+ rw_lock_x_unlock(ahi_latch);
}
/** Updates the page hash index when a single record is inserted on a page.
@param[in] cursor cursor which was positioned to the place to insert
using btr_cur_search_, and the new record has been
- inserted next to the cursor. */
+ inserted next to the cursor.
+@param[in] ahi_latch the adaptive hash index latch */
void
-btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
+btr_search_update_hash_node_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
{
hash_table_t* table;
buf_block_t* block;
dict_index_t* index;
rec_t* rec;
+ ut_ad(ahi_latch == btr_get_search_latch(cursor->index));
+ ut_ad(!btr_search_own_any(RW_LOCK_S));
+ ut_ad(!btr_search_own_any(RW_LOCK_X));
#ifdef MYSQL_INDEX_DISABLE_AHI
if (cursor->index->disable_ahi) return;
#endif
@@ -1788,8 +1763,7 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
ut_a(cursor->index == index);
ut_a(!dict_index_is_ibuf(index));
-
- btr_search_x_lock(index);
+ rw_lock_x_lock(ahi_latch);
if (!block->index) {
@@ -1813,11 +1787,11 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
func_exit:
assert_block_ahi_valid(block);
- btr_search_x_unlock(index);
+ rw_lock_x_unlock(ahi_latch);
} else {
- btr_search_x_unlock(index);
+ rw_lock_x_unlock(ahi_latch);
- btr_search_update_hash_on_insert(cursor);
+ btr_search_update_hash_on_insert(cursor, ahi_latch);
}
}
@@ -1825,9 +1799,10 @@ func_exit:
@param[in,out] cursor cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
- to the cursor */
+ to the cursor
+@param[in] ahi_latch the adaptive hash index latch */
void
-btr_search_update_hash_on_insert(btr_cur_t* cursor)
+btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
{
hash_table_t* table;
buf_block_t* block;
@@ -1841,13 +1816,16 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
ulint n_fields;
ulint n_bytes;
ibool left_side;
- ibool locked = FALSE;
+ bool locked = false;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
rec_offs_init(offsets_);
+ ut_ad(ahi_latch == btr_get_search_latch(cursor->index));
ut_ad(page_is_leaf(btr_cur_get_page(cursor)));
+ ut_ad(!btr_search_own_any(RW_LOCK_S));
+ ut_ad(!btr_search_own_any(RW_LOCK_X));
#ifdef MYSQL_INDEX_DISABLE_AHI
if (cursor->index->disable_ahi) return;
#endif
@@ -1906,10 +1884,8 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id);
} else {
if (left_side) {
-
- btr_search_x_lock(index);
-
- locked = TRUE;
+ locked = true;
+ rw_lock_x_lock(ahi_latch);
if (!btr_search_enabled) {
goto function_exit;
@@ -1924,10 +1900,8 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
if (fold != ins_fold) {
if (!locked) {
-
- btr_search_x_lock(index);
-
- locked = TRUE;
+ locked = true;
+ rw_lock_x_lock(ahi_latch);
if (!btr_search_enabled) {
goto function_exit;
@@ -1945,11 +1919,9 @@ check_next_rec:
if (page_rec_is_supremum(next_rec)) {
if (!left_side) {
-
if (!locked) {
- btr_search_x_lock(index);
-
- locked = TRUE;
+ locked = true;
+ rw_lock_x_lock(ahi_latch);
if (!btr_search_enabled) {
goto function_exit;
@@ -1965,10 +1937,8 @@ check_next_rec:
if (ins_fold != next_fold) {
if (!locked) {
-
- btr_search_x_lock(index);
-
- locked = TRUE;
+ locked = true;
+ rw_lock_x_lock(ahi_latch);
if (!btr_search_enabled) {
goto function_exit;
@@ -1987,8 +1957,9 @@ function_exit:
mem_heap_free(heap);
}
if (locked) {
- btr_search_x_unlock(index);
+ rw_lock_x_unlock(ahi_latch);
}
+ ut_ad(!rw_lock_own(ahi_latch, RW_LOCK_X));
}
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index d75fc41376d..a1457956767 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -687,7 +688,7 @@ buf_buddy_free_low(
buf_pool->buddy_stat[i].used--;
recombine:
- UNIV_MEM_ASSERT_AND_ALLOC(buf, BUF_BUDDY_LOW << i);
+ UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i);
if (i == BUF_BUDDY_SIZES) {
buf_buddy_block_free(buf_pool, buf);
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 53f92927b28..437e3390b86 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -138,10 +138,13 @@ inline void* aligned_malloc(size_t size, size_t align) {
void *result;
#ifdef _MSC_VER
result = _aligned_malloc(size, align);
-#else
+#elif defined (HAVE_POSIX_MEMALIGN)
if(posix_memalign(&result, align, size)) {
result = 0;
}
+#else
+ /* Use unaligned malloc as fallback */
+ result = malloc(size);
#endif
return result;
}
@@ -440,9 +443,6 @@ bool
buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space)
MY_ATTRIBUTE((nonnull));
-/* prototypes for new functions added to ha_innodb.cc */
-trx_t* innobase_get_trx();
-
/********************************************************************//**
Gets the smallest oldest_modification lsn for any page in the pool. Returns
zero if all modified pages have been flushed to disk.
@@ -1173,6 +1173,57 @@ buf_page_is_corrupted(
}
#ifndef UNIV_INNOCHECKSUM
+
+#if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DODUMP)
+/** Enable buffers to be dumped to core files
+
+A convience function, not called anyhwere directly however
+it is left available for gdb or any debugger to call
+in the event that you want all of the memory to be dumped
+to a core file.
+
+Returns number of errors found in madvise calls. */
+int
+buf_madvise_do_dump()
+{
+ int ret= 0;
+ buf_pool_t* buf_pool;
+ ulint n;
+ buf_chunk_t* chunk;
+
+ /* mirrors allocation in log_sys_init() */
+ if (log_sys->buf)
+ {
+ ret+= madvise(log_sys->first_in_use ? log_sys->buf
+ : log_sys->buf - log_sys->buf_size,
+ log_sys->buf_size,
+ MADV_DODUMP);
+ }
+ /* mirrors recv_sys_init() */
+ if (recv_sys->buf)
+ {
+ ret+= madvise(recv_sys->buf, recv_sys->len, MADV_DODUMP);
+ }
+
+ buf_pool_mutex_enter_all();
+
+ for (int i= 0; i < srv_buf_pool_instances; i++)
+ {
+ buf_pool = buf_pool_from_array(i);
+ chunk = buf_pool->chunks;
+
+ for (int n = buf_pool->n_chunks; n--; chunk++)
+ {
+ ret+= madvise(chunk->mem, chunk->mem_size(), MADV_DODUMP);
+ }
+ }
+
+ buf_pool_mutex_exit_all();
+
+ return ret;
+}
+#endif
+
/** Dump a page to stderr.
@param[in] read_buf database page
@param[in] page_size page size */
@@ -1502,7 +1553,7 @@ buf_chunk_init(
DBUG_EXECUTE_IF("ib_buf_chunk_init_fails", return(NULL););
chunk->mem = buf_pool->allocator.allocate_large(mem_size,
- &chunk->mem_pfx);
+ &chunk->mem_pfx, true);
if (UNIV_UNLIKELY(chunk->mem == NULL)) {
@@ -1796,7 +1847,8 @@ buf_pool_init_instance(
}
buf_pool->allocator.deallocate_large(
- chunk->mem, &chunk->mem_pfx);
+ chunk->mem, &chunk->mem_pfx, chunk->mem_size(),
+ true);
}
ut_free(buf_pool->chunks);
buf_pool_mutex_exit(buf_pool);
@@ -1943,7 +1995,7 @@ buf_pool_free_instance(
}
buf_pool->allocator.deallocate_large(
- chunk->mem, &chunk->mem_pfx);
+ chunk->mem, &chunk->mem_pfx, true);
}
for (ulint i = BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; ++i) {
@@ -2205,7 +2257,7 @@ buf_resize_status(
va_start(ap, fmt);
- ut_vsnprintf(
+ vsnprintf(
export_vars.innodb_buffer_pool_resize_status,
sizeof(export_vars.innodb_buffer_pool_resize_status),
fmt, ap);
@@ -2706,9 +2758,9 @@ withdraw_retry:
}
lock_mutex_enter();
- trx_sys_mutex_enter();
+ mutex_enter(&trx_sys.mutex);
bool found = false;
- for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list);
+ for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys.mysql_trx_list);
trx != NULL;
trx = UT_LIST_GET_NEXT(mysql_trx_list, trx)) {
if (trx->state != TRX_STATE_NOT_STARTED
@@ -2730,7 +2782,7 @@ withdraw_retry:
stderr, trx);
}
}
- trx_sys_mutex_exit();
+ mutex_exit(&trx_sys.mutex);
lock_mutex_exit();
withdraw_started = ut_time();
@@ -2819,7 +2871,7 @@ withdraw_retry:
}
buf_pool->allocator.deallocate_large(
- chunk->mem, &chunk->mem_pfx);
+ chunk->mem, &chunk->mem_pfx, true);
sum_freed += chunk->size;
@@ -3006,7 +3058,7 @@ calc_buf_pool_size:
/* normalize lock_sys */
srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
- lock_sys_resize(srv_lock_table_size);
+ lock_sys.resize(srv_lock_table_size);
/* normalize btr_search_sys */
btr_search_sys_resize(
@@ -3131,11 +3183,26 @@ buf_pool_clear_hash_index()
see the comments in buf0buf.h */
if (!index) {
+# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+ ut_a(!block->n_pointers);
+# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
continue;
}
- ut_ad(buf_block_get_state(block)
- == BUF_BLOCK_FILE_PAGE);
+ ut_d(buf_page_state state
+ = buf_block_get_state(block));
+ /* Another thread may have set the
+ state to BUF_BLOCK_REMOVE_HASH in
+ buf_LRU_block_remove_hashed().
+
+ The state change in buf_page_realloc()
+ is not observable here, because in
+ that case we would have !block->index.
+
+ In the end, the entire adaptive hash
+ index will be removed. */
+ ut_ad(state == BUF_BLOCK_FILE_PAGE
+ || state == BUF_BLOCK_REMOVE_HASH);
# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
block->n_pointers = 0;
# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -4291,10 +4358,8 @@ loop:
case BUF_GET_IF_IN_POOL_OR_WATCH:
case BUF_PEEK_IF_IN_POOL:
case BUF_EVICT_IF_IN_POOL:
-#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_X));
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_S));
-#endif /* UNIV_SYNC_DEBUG */
return(NULL);
}
@@ -4352,11 +4417,7 @@ loop:
<< ". The most probable cause"
" of this error may be that the"
" table has been corrupted."
- " You can try to fix this"
- " problem by using"
- " innodb_force_recovery."
- " Please see " REFMAN " for more"
- " details. Aborting...";
+ " See https://mariadb.com/kb/en/library/xtradbinnodb-recovery-modes/";
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
@@ -4584,6 +4645,8 @@ evict_from_pool:
buf_block_unfix(fix_block);
buf_pool_mutex_exit(buf_pool);
rw_lock_x_unlock(&fix_block->lock);
+
+ *err = DB_PAGE_CORRUPTED;
return NULL;
}
}
@@ -5657,7 +5720,7 @@ buf_page_monitor(
case FIL_PAGE_TYPE_INSTANT:
case FIL_PAGE_INDEX:
case FIL_PAGE_RTREE:
- level = btr_page_get_level_low(frame);
+ level = btr_page_get_level(frame);
/* Check if it is an index page for insert buffer */
if (fil_page_get_type(frame) == FIL_PAGE_INDEX
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index 945a1543b72..ea660ad3a50 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -47,7 +47,6 @@ Created April 08, 2011 Vasil Dimov
#include "mysql/service_wsrep.h" /* wsrep_recovery */
enum status_severity {
- STATUS_VERBOSE,
STATUS_INFO,
STATUS_ERR
};
@@ -120,7 +119,7 @@ buf_dump_status(
va_start(ap, fmt);
- ut_vsnprintf(
+ vsnprintf(
export_vars.innodb_buffer_pool_dump_status,
sizeof(export_vars.innodb_buffer_pool_dump_status),
fmt, ap);
@@ -133,9 +132,6 @@ buf_dump_status(
case STATUS_ERR:
ib::error() << export_vars.innodb_buffer_pool_dump_status;
break;
-
- case STATUS_VERBOSE:
- break;
}
va_end(ap);
@@ -162,7 +158,7 @@ buf_load_status(
va_start(ap, fmt);
- ut_vsnprintf(
+ vsnprintf(
export_vars.innodb_buffer_pool_load_status,
sizeof(export_vars.innodb_buffer_pool_load_status),
fmt, ap);
@@ -175,9 +171,6 @@ buf_load_status(
case STATUS_ERR:
ib::error() << export_vars.innodb_buffer_pool_load_status;
break;
-
- case STATUS_VERBOSE:
- break;
}
va_end(ap);
@@ -213,8 +206,8 @@ buf_dump_generate_path(
{
char buf[FN_REFLEN];
- ut_snprintf(buf, sizeof(buf), "%s%c%s", get_buf_dump_dir(),
- OS_PATH_SEPARATOR, srv_buf_dump_filename);
+ snprintf(buf, sizeof(buf), "%s%c%s", get_buf_dump_dir(),
+ OS_PATH_SEPARATOR, srv_buf_dump_filename);
os_file_type_t type;
bool exists = false;
@@ -240,14 +233,14 @@ buf_dump_generate_path(
if (srv_data_home_full[strlen(srv_data_home_full) - 1]
== OS_PATH_SEPARATOR) {
- ut_snprintf(path, path_size, "%s%s",
- srv_data_home_full,
- srv_buf_dump_filename);
+ snprintf(path, path_size, "%s%s",
+ srv_data_home_full,
+ srv_buf_dump_filename);
} else {
- ut_snprintf(path, path_size, "%s%c%s",
- srv_data_home_full,
- OS_PATH_SEPARATOR,
- srv_buf_dump_filename);
+ snprintf(path, path_size, "%s%c%s",
+ srv_data_home_full,
+ OS_PATH_SEPARATOR,
+ srv_buf_dump_filename);
}
}
}
@@ -276,8 +269,8 @@ buf_dump(
buf_dump_generate_path(full_filename, sizeof(full_filename));
- ut_snprintf(tmp_filename, sizeof(tmp_filename),
- "%s.incomplete", full_filename);
+ snprintf(tmp_filename, sizeof(tmp_filename),
+ "%s.incomplete", full_filename);
buf_dump_status(STATUS_INFO, "Dumping buffer pool(s) to %s",
full_filename);
@@ -298,8 +291,6 @@ buf_dump(
buf_dump_t* dump;
ulint n_pages;
ulint j;
- ulint limit;
- ulint counter;
buf_pool = buf_pool_from_array(i);
@@ -368,9 +359,6 @@ buf_dump(
buf_pool_mutex_exit(buf_pool);
- limit = (ulint)((double)n_pages * ((double)srv_buf_dump_status_frequency / (double)100));
- counter = 0;
-
for (j = 0; j < n_pages && !SHOULD_QUIT(); j++) {
ret = fprintf(f, ULINTPF "," ULINTPF "\n",
BUF_DUMP_SPACE(dump[j]),
@@ -384,23 +372,6 @@ buf_dump(
/* leave tmp_filename to exist */
return;
}
-
- counter++;
-
- /* Print buffer pool dump status only if
- srv_buf_dump_status_frequency is > 0 and
- we have processed that amount of pages. */
- if (srv_buf_dump_status_frequency &&
- counter == limit) {
- counter = 0;
- buf_dump_status(
- STATUS_VERBOSE,
- "Dumping buffer pool"
- " " ULINTPF "/%lu,"
- " page " ULINTPF "/" ULINTPF,
- i + 1, srv_buf_pool_instances,
- j + 1, n_pages);
- }
}
ut_free(dump);
@@ -442,6 +413,11 @@ buf_dump(
buf_dump_status(STATUS_INFO,
"Buffer pool(s) dump completed at %s", now);
+
+ /* Though dumping doesn't related to an incomplete load,
+ we reset this to 0 here to indicate that a shutdown can also perform
+ a dump */
+ export_vars.innodb_buffer_pool_load_incomplete = 0;
}
/*****************************************************************//**
@@ -605,6 +581,8 @@ buf_load()
rewind(f);
+ 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);
@@ -653,7 +631,7 @@ buf_load()
ut_sprintf_timestamp(now);
buf_load_status(STATUS_INFO,
"Buffer pool(s) load completed at %s"
- " (%s was empty)", now, full_filename);
+ " (%s was empty or had errors)", now, full_filename);
return;
}
@@ -718,21 +696,6 @@ buf_load()
os_aio_simulated_wake_handler_threads();
}
- /* Update the progress every 32 MiB, which is every Nth page,
- where N = 32*1024^2 / page_size. */
- static const ulint update_status_every_n_mb = 32;
- static const ulint update_status_every_n_pages
- = update_status_every_n_mb * 1024 * 1024
- / page_size.physical();
-
- if (i % update_status_every_n_pages == 0) {
- buf_load_status(STATUS_VERBOSE,
- "Loaded " ULINTPF "/" ULINTPF " pages",
- i + 1, dump_n);
- /* mysql_stage_set_work_completed(pfs_stage_progress,
- i); */
- }
-
if (buf_load_abort_flag) {
if (space != NULL) {
fil_space_release(space);
@@ -757,6 +720,12 @@ buf_load()
buf_load_throttle_if_needed(
&last_check_time, &last_activity_cnt, i);
+
+#ifdef UNIV_DEBUG
+ if ((i+1) >= srv_buf_pool_load_pages_abort) {
+ buf_load_abort_flag = 1;
+ }
+#endif
}
if (space != NULL) {
@@ -767,8 +736,23 @@ buf_load()
ut_sprintf_timestamp(now);
- buf_load_status(STATUS_INFO,
+ if (i == dump_n) {
+ buf_load_status(STATUS_INFO,
"Buffer pool(s) load completed at %s", now);
+ export_vars.innodb_buffer_pool_load_incomplete = 0;
+ } else if (!buf_load_abort_flag) {
+ buf_load_status(STATUS_INFO,
+ "Buffer pool(s) load aborted due to user instigated abort at %s",
+ now);
+ /* intentionally don't reset innodb_buffer_pool_load_incomplete
+ as we don't want a shutdown to save the buffer pool */
+ } else {
+ buf_load_status(STATUS_INFO,
+ "Buffer pool(s) load aborted due to shutdown at %s",
+ now);
+ /* intentionally don't reset innodb_buffer_pool_load_incomplete
+ as we want to abort without saving the buffer pool */
+ }
/* Make sure that estimated = completed when we end. */
/* mysql_stage_set_work_completed(pfs_stage_progress, dump_n); */
@@ -805,9 +789,6 @@ DECLARE_THREAD(buf_dump_thread)(void*)
pfs_register_thread(buf_dump_thread_key);
#endif */ /* UNIV_PFS_THREAD */
- buf_dump_status(STATUS_VERBOSE, "Dumping of buffer pool not started");
- buf_load_status(STATUS_VERBOSE, "Loading of buffer pool not started");
-
if (srv_buffer_pool_load_at_startup) {
#ifdef WITH_WSREP
@@ -840,15 +821,16 @@ DECLARE_THREAD(buf_dump_thread)(void*)
}
if (srv_buffer_pool_dump_at_shutdown && srv_fast_shutdown != 2) {
+ if (export_vars.innodb_buffer_pool_load_incomplete) {
+ buf_dump_status(STATUS_INFO,
+ "Dumping of buffer pool not started"
+ " as load was incomplete");
#ifdef WITH_WSREP
- if (!wsrep_recovery) {
+ } else if (wsrep_recovery) {
#endif /* WITH_WSREP */
-
- buf_dump(FALSE /* ignore shutdown down flag,
- keep going even if we are in a shutdown state */);
-#ifdef WITH_WSREP
+ } else {
+ buf_dump(FALSE/* do complete dump at shutdown */);
}
-#endif /* WITH_WSREP */
}
srv_buf_dump_thread_active = false;
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 043328902ee..5413f324127 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, MariaDB Corporation.
Copyright (c) 2013, 2014, Fusion-io
This program is free software; you can redistribute it and/or modify it under
@@ -28,6 +28,7 @@ Created 11/11/1995 Heikki Tuuri
#include "ha_prototypes.h"
#include <mysql/service_thd_wait.h>
#include <my_dbug.h>
+#include <sql_class.h>
#include "buf0flu.h"
#include "buf0buf.h"
@@ -174,7 +175,7 @@ struct page_cleaner_t {
requests for all slots */
ulint flush_pass; /*!< count to finish to flush
requests for all slots */
- page_cleaner_slot_t* slots; /*!< pointer to the slots */
+ page_cleaner_slot_t slots[MAX_BUFFER_POOLS];
bool is_running; /*!< false if attempt
to shutdown */
@@ -185,7 +186,7 @@ struct page_cleaner_t {
#endif /* UNIV_DEBUG */
};
-static page_cleaner_t* page_cleaner = NULL;
+static page_cleaner_t page_cleaner;
#ifdef UNIV_DEBUG
my_bool innodb_page_cleaner_disabled_debug;
@@ -2506,23 +2507,23 @@ page_cleaner_flush_pages_recommendation(
lsn_avg_rate = (lsn_avg_rate + lsn_rate) / 2;
/* aggregate stats of all slots */
- mutex_enter(&page_cleaner->mutex);
+ mutex_enter(&page_cleaner.mutex);
- ulint flush_tm = page_cleaner->flush_time;
- ulint flush_pass = page_cleaner->flush_pass;
+ ulint flush_tm = page_cleaner.flush_time;
+ ulint flush_pass = page_cleaner.flush_pass;
- page_cleaner->flush_time = 0;
- page_cleaner->flush_pass = 0;
+ page_cleaner.flush_time = 0;
+ page_cleaner.flush_pass = 0;
ulint lru_tm = 0;
ulint list_tm = 0;
ulint lru_pass = 0;
ulint list_pass = 0;
- for (ulint i = 0; i < page_cleaner->n_slots; i++) {
+ for (ulint i = 0; i < page_cleaner.n_slots; i++) {
page_cleaner_slot_t* slot;
- slot = &page_cleaner->slots[i];
+ slot = &page_cleaner.slots[i];
lru_tm += slot->flush_lru_time;
lru_pass += slot->flush_lru_pass;
@@ -2535,7 +2536,7 @@ page_cleaner_flush_pages_recommendation(
slot->flush_list_pass = 0;
}
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
/* minimum values are 1, to avoid dividing by zero. */
if (lru_tm < 1) {
@@ -2576,9 +2577,9 @@ page_cleaner_flush_pages_recommendation(
MONITOR_SET(MONITOR_FLUSH_AVG_TIME, flush_tm / flush_pass);
MONITOR_SET(MONITOR_FLUSH_ADAPTIVE_AVG_PASS,
- list_pass / page_cleaner->n_slots);
+ list_pass / page_cleaner.n_slots);
MONITOR_SET(MONITOR_LRU_BATCH_FLUSH_AVG_PASS,
- lru_pass / page_cleaner->n_slots);
+ lru_pass / page_cleaner.n_slots);
MONITOR_SET(MONITOR_FLUSH_AVG_PASS, flush_pass);
prev_lsn = cur_lsn;
@@ -2622,12 +2623,12 @@ page_cleaner_flush_pages_recommendation(
sum_pages_for_lsn += pages_for_lsn;
- mutex_enter(&page_cleaner->mutex);
- ut_ad(page_cleaner->slots[i].state
+ mutex_enter(&page_cleaner.mutex);
+ ut_ad(page_cleaner.slots[i].state
== PAGE_CLEANER_STATE_NONE);
- page_cleaner->slots[i].n_pages_requested
+ page_cleaner.slots[i].n_pages_requested
= pages_for_lsn / buf_flush_lsn_scan_factor + 1;
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
}
sum_pages_for_lsn /= buf_flush_lsn_scan_factor;
@@ -2647,20 +2648,20 @@ page_cleaner_flush_pages_recommendation(
}
/* Normalize request for each instance */
- 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);
+ 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);
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
/* if REDO has enough of free space,
don't care about age distribution of pages */
- page_cleaner->slots[i].n_pages_requested = pct_for_lsn > 30 ?
- page_cleaner->slots[i].n_pages_requested
+ page_cleaner.slots[i].n_pages_requested = pct_for_lsn > 30 ?
+ page_cleaner.slots[i].n_pages_requested
* n_pages / sum_pages_for_lsn + 1
: n_pages / srv_buf_pool_instances;
}
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
MONITOR_SET(MONITOR_FLUSH_N_TO_FLUSH_REQUESTED, n_pages);
@@ -2683,21 +2684,21 @@ than a second
@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() */
+ 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)
+ 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;
- ulint cur_time = ut_time_ms();
-
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. */
@@ -2719,26 +2720,18 @@ void
buf_flush_page_cleaner_init(void)
/*=============================*/
{
- ut_ad(page_cleaner == NULL);
-
- page_cleaner = static_cast<page_cleaner_t*>(
- ut_zalloc_nokey(sizeof(*page_cleaner)));
-
- mutex_create(LATCH_ID_PAGE_CLEANER, &page_cleaner->mutex);
-
- page_cleaner->is_requested = os_event_create("pc_is_requested");
- page_cleaner->is_finished = os_event_create("pc_is_finished");
- page_cleaner->is_started = os_event_create("pc_is_started");
+ ut_ad(!page_cleaner.is_running);
- page_cleaner->n_slots = static_cast<ulint>(srv_buf_pool_instances);
+ mutex_create(LATCH_ID_PAGE_CLEANER, &page_cleaner.mutex);
- page_cleaner->slots = static_cast<page_cleaner_slot_t*>(
- ut_zalloc_nokey(page_cleaner->n_slots
- * sizeof(*page_cleaner->slots)));
+ page_cleaner.is_requested = os_event_create("pc_is_requested");
+ page_cleaner.is_finished = os_event_create("pc_is_finished");
+ page_cleaner.is_started = os_event_create("pc_is_started");
+ page_cleaner.n_slots = static_cast<ulint>(srv_buf_pool_instances);
- ut_d(page_cleaner->n_disabled_debug = 0);
+ ut_d(page_cleaner.n_disabled_debug = 0);
- page_cleaner->is_running = true;
+ page_cleaner.is_running = true;
}
/**
@@ -2747,22 +2740,18 @@ static
void
buf_flush_page_cleaner_close(void)
{
+ ut_ad(!page_cleaner.is_running);
+
/* waiting for all worker threads exit */
- while (page_cleaner->n_workers > 0) {
+ while (page_cleaner.n_workers) {
os_thread_sleep(10000);
}
- mutex_destroy(&page_cleaner->mutex);
-
- ut_free(page_cleaner->slots);
-
- os_event_destroy(page_cleaner->is_finished);
- os_event_destroy(page_cleaner->is_requested);
- os_event_destroy(page_cleaner->is_started);
+ mutex_destroy(&page_cleaner.mutex);
- ut_free(page_cleaner);
-
- page_cleaner = NULL;
+ os_event_destroy(page_cleaner.is_finished);
+ os_event_destroy(page_cleaner.is_requested);
+ os_event_destroy(page_cleaner.is_started);
}
/**
@@ -2788,17 +2777,17 @@ pc_request(
/ srv_buf_pool_instances;
}
- mutex_enter(&page_cleaner->mutex);
+ 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);
+ 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;
+ page_cleaner.requested = (min_n > 0);
+ page_cleaner.lsn_limit = lsn_limit;
- for (ulint i = 0; i < page_cleaner->n_slots; i++) {
- page_cleaner_slot_t* slot = &page_cleaner->slots[i];
+ for (ulint i = 0; i < page_cleaner.n_slots; i++) {
+ page_cleaner_slot_t* slot = &page_cleaner.slots[i];
ut_ad(slot->state == PAGE_CLEANER_STATE_NONE);
@@ -2814,13 +2803,13 @@ pc_request(
slot->state = PAGE_CLEANER_STATE_REQUESTED;
}
- page_cleaner->n_slots_requested = page_cleaner->n_slots;
- page_cleaner->n_slots_flushing = 0;
- page_cleaner->n_slots_finished = 0;
+ page_cleaner.n_slots_requested = page_cleaner.n_slots;
+ page_cleaner.n_slots_flushing = 0;
+ page_cleaner.n_slots_finished = 0;
- os_event_set(page_cleaner->is_requested);
+ os_event_set(page_cleaner.is_requested);
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
}
/**
@@ -2835,14 +2824,16 @@ pc_flush_slot(void)
int lru_pass = 0;
int list_pass = 0;
- mutex_enter(&page_cleaner->mutex);
+ mutex_enter(&page_cleaner.mutex);
- if (page_cleaner->n_slots_requested > 0) {
+ if (!page_cleaner.n_slots_requested) {
+ os_event_reset(page_cleaner.is_requested);
+ } else {
page_cleaner_slot_t* slot = NULL;
ulint i;
- for (i = 0; i < page_cleaner->n_slots; i++) {
- slot = &page_cleaner->slots[i];
+ for (i = 0; i < page_cleaner.n_slots; i++) {
+ slot = &page_cleaner.slots[i];
if (slot->state == PAGE_CLEANER_STATE_REQUESTED) {
break;
@@ -2850,26 +2841,26 @@ pc_flush_slot(void)
}
/* slot should be found because
- page_cleaner->n_slots_requested > 0 */
- ut_a(i < page_cleaner->n_slots);
+ page_cleaner.n_slots_requested > 0 */
+ ut_a(i < page_cleaner.n_slots);
buf_pool_t* buf_pool = buf_pool_from_array(i);
- page_cleaner->n_slots_requested--;
- page_cleaner->n_slots_flushing++;
+ page_cleaner.n_slots_requested--;
+ page_cleaner.n_slots_flushing++;
slot->state = PAGE_CLEANER_STATE_FLUSHING;
- if (page_cleaner->n_slots_requested == 0) {
- os_event_reset(page_cleaner->is_requested);
- }
-
- if (!page_cleaner->is_running) {
+ if (UNIV_UNLIKELY(!page_cleaner.is_running)) {
slot->n_flushed_lru = 0;
slot->n_flushed_list = 0;
goto finish_mutex;
}
- mutex_exit(&page_cleaner->mutex);
+ if (page_cleaner.n_slots_requested == 0) {
+ os_event_reset(page_cleaner.is_requested);
+ }
+
+ mutex_exit(&page_cleaner.mutex);
lru_tm = ut_time_ms();
@@ -2879,13 +2870,13 @@ pc_flush_slot(void)
lru_tm = ut_time_ms() - lru_tm;
lru_pass++;
- if (!page_cleaner->is_running) {
+ if (UNIV_UNLIKELY(!page_cleaner.is_running)) {
slot->n_flushed_list = 0;
goto finish;
}
/* Flush pages from flush_list if required */
- if (page_cleaner->requested) {
+ if (page_cleaner.requested) {
flush_counters_t n;
memset(&n, 0, sizeof(flush_counters_t));
list_tm = ut_time_ms();
@@ -2893,7 +2884,7 @@ pc_flush_slot(void)
slot->succeeded_list = buf_flush_do_batch(
buf_pool, BUF_FLUSH_LIST,
slot->n_pages_requested,
- page_cleaner->lsn_limit,
+ page_cleaner.lsn_limit,
&n);
slot->n_flushed_list = n.flushed;
@@ -2905,10 +2896,10 @@ pc_flush_slot(void)
slot->succeeded_list = true;
}
finish:
- mutex_enter(&page_cleaner->mutex);
+ mutex_enter(&page_cleaner.mutex);
finish_mutex:
- page_cleaner->n_slots_flushing--;
- page_cleaner->n_slots_finished++;
+ page_cleaner.n_slots_flushing--;
+ page_cleaner.n_slots_finished++;
slot->state = PAGE_CLEANER_STATE_FINISHED;
slot->flush_lru_time += lru_tm;
@@ -2916,15 +2907,15 @@ finish_mutex:
slot->flush_lru_pass += lru_pass;
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);
+ 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;
+ ulint ret = page_cleaner.n_slots_requested;
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
return(ret);
}
@@ -2946,16 +2937,16 @@ pc_wait_finished(
*n_flushed_lru = 0;
*n_flushed_list = 0;
- os_event_wait(page_cleaner->is_finished);
+ os_event_wait(page_cleaner.is_finished);
- mutex_enter(&page_cleaner->mutex);
+ 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 == page_cleaner->n_slots);
+ ut_ad(page_cleaner.n_slots_requested == 0);
+ ut_ad(page_cleaner.n_slots_flushing == 0);
+ ut_ad(page_cleaner.n_slots_finished == page_cleaner.n_slots);
- for (ulint i = 0; i < page_cleaner->n_slots; i++) {
- page_cleaner_slot_t* slot = &page_cleaner->slots[i];
+ for (ulint i = 0; i < page_cleaner.n_slots; i++) {
+ page_cleaner_slot_t* slot = &page_cleaner.slots[i];
ut_ad(slot->state == PAGE_CLEANER_STATE_FINISHED);
@@ -2968,11 +2959,11 @@ pc_wait_finished(
slot->n_pages_requested = 0;
}
- page_cleaner->n_slots_finished = 0;
+ page_cleaner.n_slots_finished = 0;
- os_event_reset(page_cleaner->is_finished);
+ os_event_reset(page_cleaner.is_finished);
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
return(all_succeeded);
}
@@ -3000,20 +2991,18 @@ static
void
buf_flush_page_cleaner_disabled_loop(void)
{
- ut_ad(page_cleaner != NULL);
-
if (!innodb_page_cleaner_disabled_debug) {
/* We return to avoid entering and exiting mutex. */
return;
}
- mutex_enter(&page_cleaner->mutex);
- page_cleaner->n_disabled_debug++;
- mutex_exit(&page_cleaner->mutex);
+ mutex_enter(&page_cleaner.mutex);
+ page_cleaner.n_disabled_debug++;
+ mutex_exit(&page_cleaner.mutex);
while (innodb_page_cleaner_disabled_debug
&& srv_shutdown_state == SRV_SHUTDOWN_NONE
- && page_cleaner->is_running) {
+ && page_cleaner.is_running) {
os_thread_sleep(100000); /* [A] */
}
@@ -3031,9 +3020,9 @@ buf_flush_page_cleaner_disabled_loop(void)
Therefore we are waiting in step 2 for this thread exiting here. */
- mutex_enter(&page_cleaner->mutex);
- page_cleaner->n_disabled_debug--;
- mutex_exit(&page_cleaner->mutex);
+ mutex_enter(&page_cleaner.mutex);
+ page_cleaner.n_disabled_debug--;
+ mutex_exit(&page_cleaner.mutex);
}
/** Disables page cleaner threads (coordinator and workers).
@@ -3049,7 +3038,7 @@ buf_flush_page_cleaner_disabled_debug_update(
void* var_ptr,
const void* save)
{
- if (page_cleaner == NULL) {
+ if (!page_cleaner.is_running) {
return;
}
@@ -3062,9 +3051,9 @@ buf_flush_page_cleaner_disabled_debug_update(
/* Enable page cleaner threads. */
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
- mutex_enter(&page_cleaner->mutex);
- const ulint n = page_cleaner->n_disabled_debug;
- mutex_exit(&page_cleaner->mutex);
+ mutex_enter(&page_cleaner.mutex);
+ const ulint n = page_cleaner.n_disabled_debug;
+ mutex_exit(&page_cleaner.mutex);
/* Check if all threads have been enabled, to avoid
problem when we decide to re-disable them soon. */
if (n == 0) {
@@ -3089,21 +3078,21 @@ buf_flush_page_cleaner_disabled_debug_update(
That's why we have sleep-loop instead of simply
waiting on some disabled_debug_event. */
- os_event_set(page_cleaner->is_requested);
+ os_event_set(page_cleaner.is_requested);
- mutex_enter(&page_cleaner->mutex);
+ mutex_enter(&page_cleaner.mutex);
- ut_ad(page_cleaner->n_disabled_debug
+ ut_ad(page_cleaner.n_disabled_debug
<= srv_n_page_cleaners);
- if (page_cleaner->n_disabled_debug
+ if (page_cleaner.n_disabled_debug
== srv_n_page_cleaners) {
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
break;
}
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
os_thread_sleep(100000);
}
@@ -3195,6 +3184,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
ulint last_pages = 0;
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
+ 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
@@ -3204,23 +3194,22 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
|| n_flushed == 0) {
ret_sleep = pc_sleep_if_needed(
- next_loop_time, sig_count);
-
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
- break;
- }
- } else if (ut_time_ms() > next_loop_time) {
+ 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_NONE) {
+ break;
+ }
+
sig_count = os_event_reset(buf_flush_event);
if (ret_sleep == OS_SYNC_TIME_EXCEEDED) {
- ulint curr_time = ut_time_ms();
-
- if (curr_time > next_loop_time + 3000
+ 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"
@@ -3257,10 +3246,10 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
&& srv_flush_sync
&& buf_flush_sync_lsn > 0) {
/* woke up for flush_sync */
- mutex_enter(&page_cleaner->mutex);
+ mutex_enter(&page_cleaner.mutex);
lsn_t lsn_limit = buf_flush_sync_lsn;
buf_flush_sync_lsn = 0;
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
/* Request flushing for threads */
pc_request(ULINT_MAX, lsn_limit);
@@ -3272,8 +3261,8 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
/* 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++;
+ page_cleaner.flush_time += ut_time_ms() - tm;
+ page_cleaner.flush_pass++;
/* Wait for all slots to be finished */
ulint n_flushed_lru = 0;
@@ -3318,8 +3307,8 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
/* 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++ ;
+ page_cleaner.flush_time += ut_time_ms() - tm;
+ page_cleaner.flush_pass++ ;
/* Wait for all slots to be finished */
ulint n_flushed_lru = 0;
@@ -3465,8 +3454,8 @@ thread_exit:
/* All worker threads are waiting for the event here,
and no more access to page_cleaner structure by them.
Wakes worker threads up just to make them exit. */
- page_cleaner->is_running = false;
- os_event_set(page_cleaner->is_requested);
+ page_cleaner.is_running = false;
+ os_event_set(page_cleaner.is_requested);
buf_flush_page_cleaner_close();
@@ -3485,31 +3474,27 @@ thread_exit:
void
buf_flush_set_page_cleaner_thread_cnt(ulong new_cnt)
{
- mutex_enter(&page_cleaner->mutex);
+ mutex_enter(&page_cleaner.mutex);
- if (new_cnt > srv_n_page_cleaners) {
+ srv_n_page_cleaners = new_cnt;
+ if (new_cnt > page_cleaner.n_workers) {
/* User has increased the number of page
cleaner threads. */
- uint add = new_cnt - srv_n_page_cleaners;
- srv_n_page_cleaners = new_cnt;
- for (uint i = 0; i < add; i++) {
+ ulint add = new_cnt - page_cleaner.n_workers;
+ for (ulint i = 0; i < add; i++) {
os_thread_id_t cleaner_thread_id;
os_thread_create(buf_flush_page_cleaner_worker, NULL, &cleaner_thread_id);
}
- } else if (new_cnt < srv_n_page_cleaners) {
- /* User has decreased the number of page
- cleaner threads. */
- srv_n_page_cleaners = new_cnt;
}
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
/* Wait until defined number of workers has started. */
- while (page_cleaner->is_running &&
- page_cleaner->n_workers != (srv_n_page_cleaners - 1)) {
- os_event_set(page_cleaner->is_requested);
- os_event_reset(page_cleaner->is_started);
- os_event_wait_time(page_cleaner->is_started, 1000000);
+ while (page_cleaner.is_running &&
+ page_cleaner.n_workers != (srv_n_page_cleaners - 1)) {
+ os_event_set(page_cleaner.is_requested);
+ os_event_reset(page_cleaner.is_started);
+ os_event_wait_time(page_cleaner.is_started, 1000000);
}
}
@@ -3525,20 +3510,19 @@ DECLARE_THREAD(buf_flush_page_cleaner_worker)(
os_thread_create */
{
my_thread_init();
+#ifndef DBUG_OFF
os_thread_id_t cleaner_thread_id = os_thread_get_curr_id();
+#endif
- mutex_enter(&page_cleaner->mutex);
- ulint thread_no = page_cleaner->n_workers;
- page_cleaner->n_workers++;
+ mutex_enter(&page_cleaner.mutex);
+ ulint thread_no = page_cleaner.n_workers++;
- DBUG_LOG("ib_buf", "Thread "
- << cleaner_thread_id
- << " started n_workers "
- << page_cleaner->n_workers << ".");
+ DBUG_LOG("ib_buf", "Thread " << cleaner_thread_id
+ << " started; n_workers=" << page_cleaner.n_workers);
/* Signal that we have started */
- os_event_set(page_cleaner->is_started);
- mutex_exit(&page_cleaner->mutex);
+ os_event_set(page_cleaner.is_started);
+ mutex_exit(&page_cleaner.mutex);
#ifdef UNIV_LINUX
/* linux might be able to set different setting for each thread
@@ -3552,11 +3536,11 @@ DECLARE_THREAD(buf_flush_page_cleaner_worker)(
#endif /* UNIV_LINUX */
while (true) {
- os_event_wait(page_cleaner->is_requested);
+ os_event_wait(page_cleaner.is_requested);
ut_d(buf_flush_page_cleaner_disabled_loop());
- if (!page_cleaner->is_running) {
+ if (!page_cleaner.is_running) {
break;
}
@@ -3577,15 +3561,15 @@ DECLARE_THREAD(buf_flush_page_cleaner_worker)(
pc_flush_slot();
}
- mutex_enter(&page_cleaner->mutex);
- page_cleaner->n_workers--;
+ mutex_enter(&page_cleaner.mutex);
+ page_cleaner.n_workers--;
DBUG_LOG("ib_buf", "Thread " << cleaner_thread_id
- << " exiting n_workers " << page_cleaner->n_workers<< ".");
+ << " exiting; n_workers=" << page_cleaner.n_workers);
/* Signal that we have stopped */
- os_event_set(page_cleaner->is_started);
- mutex_exit(&page_cleaner->mutex);
+ os_event_set(page_cleaner.is_started);
+ mutex_exit(&page_cleaner.mutex);
my_thread_end();
@@ -3620,11 +3604,11 @@ buf_flush_request_force(
/* 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);
+ mutex_enter(&page_cleaner.mutex);
if (lsn_target > buf_flush_sync_lsn) {
buf_flush_sync_lsn = lsn_target;
}
- mutex_exit(&page_cleaner->mutex);
+ mutex_exit(&page_cleaner.mutex);
os_event_set(buf_flush_event);
}
@@ -3879,16 +3863,14 @@ FlushObserver::notify_remove(
void
FlushObserver::flush()
{
+ ut_ad(m_trx);
+
if (!m_interrupted && m_stage) {
m_stage->begin_phase_flush(buf_flush_get_dirty_pages_count(
m_space_id, this));
}
- /* MDEV-14317 FIXME: Discard all changes to only those pages
- that will be freed by the clean-up of the ALTER operation.
- (Maybe, instead of buf_pool->flush_list, use a dedicated list
- for pages on which redo logging has been disabled.) */
- buf_LRU_flush_or_remove_pages(m_space_id, m_trx);
+ buf_LRU_flush_or_remove_pages(m_space_id, this);
/* Wait for all dirty pages were flushed. */
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 9d0d9627d26..cdea41ff191 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -80,6 +80,10 @@ static const ulint BUF_LRU_SEARCH_SCAN_THRESHOLD = 100;
frames in the buffer pool, we set this to TRUE */
static bool buf_lru_switched_on_innodb_mon = false;
+/** True if diagnostic message about difficult to find free blocks
+in the buffer bool has already printed. */
+static bool buf_lru_free_blocks_error_printed;
+
/******************************************************************//**
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics,
@@ -542,27 +546,21 @@ buf_flush_or_remove_page(
return(processed);
}
-/******************************************************************//**
-Remove all dirty pages belonging to a given tablespace inside a specific
+/** Remove all dirty pages belonging to a given tablespace inside a specific
buffer pool instance when we are deleting the data file(s) of that
tablespace. The pages still remain a part of LRU and are evicted from
the list as they age towards the tail of the LRU.
-@retval DB_SUCCESS if all freed
-@retval DB_FAIL if not all freed
-@retval DB_INTERRUPTED if the transaction was interrupted */
+@param[in,out] buf_pool buffer pool
+@param[in] id tablespace identifier
+@param[in] observer flush observer (to check for interrupt),
+ or NULL if the files should not be written to
+@return whether all dirty pages were freed */
static MY_ATTRIBUTE((warn_unused_result))
-dberr_t
+bool
buf_flush_or_remove_pages(
-/*======================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id, /*!< in: target space id for which
- to remove or flush pages */
- FlushObserver* observer, /*!< in: flush observer */
- bool flush, /*!< in: flush to disk if true but
- don't remove else remove without
- flushing to disk */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted, can be 0 */
+ buf_pool_t* buf_pool,
+ ulint id,
+ FlushObserver* observer)
{
buf_page_t* prev;
buf_page_t* bpage;
@@ -584,15 +582,27 @@ rescan:
prev = UT_LIST_GET_PREV(list, bpage);
- /* If flush observer is NULL, flush page for space id,
- or flush page for flush observer. */
- if (observer ? (observer != bpage->flush_observer)
- : (id != bpage->id.space())) {
-
- /* Skip this block, as it does not belong to
- the target space. */
-
- } else if (!buf_flush_or_remove_page(buf_pool, bpage, flush)) {
+ /* Flush the pages matching space id,
+ or pages matching the flush observer. */
+ if (observer && observer->is_partial_flush()) {
+ if (observer != bpage->flush_observer) {
+ /* Skip this block. */
+ } else if (!buf_flush_or_remove_page(
+ buf_pool, bpage,
+ !observer->is_interrupted())) {
+ all_freed = false;
+ } else if (!observer->is_interrupted()) {
+ /* 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;
+ }
+ } else if (id != bpage->id.space()) {
+ /* Skip this block, because it is for a
+ different tablespace. */
+ } else if (!buf_flush_or_remove_page(
+ buf_pool, bpage, observer != NULL)) {
/* Remove was unsuccessful, we have to try again
by scanning the entire list from the end.
@@ -615,7 +625,7 @@ rescan:
iteration. */
all_freed = false;
- } else if (flush) {
+ } else if (observer) {
/* The processing was successful. And during the
processing we have released the buf_pool mutex
@@ -636,25 +646,14 @@ rescan:
/* The check for trx is interrupted is expensive, we want
to check every N iterations. */
- if (!processed && trx && trx_is_interrupted(trx)) {
- if (trx->flush_observer != NULL) {
- if (flush) {
- trx->flush_observer->interrupted();
- } else {
- /* We should remove all pages with the
- the flush observer. */
- continue;
- }
- }
-
- buf_flush_list_mutex_exit(buf_pool);
- return(DB_INTERRUPTED);
+ if (!processed && observer) {
+ observer->check_interrupted();
}
}
buf_flush_list_mutex_exit(buf_pool);
- return(all_freed ? DB_SUCCESS : DB_FAIL);
+ return(all_freed);
}
/** Remove or flush all the dirty pages that belong to a given tablespace
@@ -665,73 +664,62 @@ the tail of the LRU list.
@param[in] id tablespace identifier
@param[in] observer flush observer,
or NULL if the files should not be written to
-@param[in] trx transaction (to check for interrupt),
- or NULL if the files should not be written to
*/
static
void
buf_flush_dirty_pages(
buf_pool_t* buf_pool,
ulint id,
- FlushObserver* observer,
- const trx_t* trx)
+ FlushObserver* observer)
{
- dberr_t err;
- bool flush = trx != NULL;
-
- do {
+ for (;;) {
buf_pool_mutex_enter(buf_pool);
- err = buf_flush_or_remove_pages(
- buf_pool, id, observer, flush, trx);
+ bool freed = buf_flush_or_remove_pages(buf_pool, id, observer);
buf_pool_mutex_exit(buf_pool);
ut_ad(buf_flush_validate(buf_pool));
- if (err == DB_FAIL) {
- os_thread_sleep(2000);
- }
-
- if (err == DB_INTERRUPTED && observer != NULL) {
- ut_a(flush);
-
- flush = false;
- err = DB_FAIL;
+ if (freed) {
+ break;
}
- /* DB_FAIL is a soft error, it means that the task wasn't
- completed, needs to be retried. */
-
+ os_thread_sleep(2000);
ut_ad(buf_flush_validate(buf_pool));
+ }
- } while (err == DB_FAIL);
-
- ut_ad(err == DB_INTERRUPTED
+ ut_ad((observer && observer->is_interrupted())
|| buf_pool_get_dirty_pages_count(buf_pool, id, observer) == 0);
}
/** Empty the flush list for all pages belonging to a tablespace.
@param[in] id tablespace identifier
-@param[in] trx transaction, for checking for user interrupt;
- or NULL if nothing is to be written
-@param[in] drop_ahi whether to drop the adaptive hash index */
+@param[in] observer flush observer,
+ or NULL if nothing is to be written */
void
-buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi)
+buf_LRU_flush_or_remove_pages(
+ ulint id,
+ FlushObserver* observer
+#ifdef BTR_CUR_HASH_ADAPT
+ , bool drop_ahi /*!< whether to drop the adaptive hash index */
+#endif /* BTR_CUR_HASH_ADAPT */
+ )
{
- FlushObserver* observer = (trx == NULL) ? NULL : trx->flush_observer;
/* Pages in the system tablespace must never be discarded. */
- ut_ad(id || trx);
+ ut_ad(id || observer);
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
buf_pool_t* buf_pool = buf_pool_from_array(i);
+#ifdef BTR_CUR_HASH_ADAPT
if (drop_ahi) {
buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
}
- buf_flush_dirty_pages(buf_pool, id, observer, trx);
+#endif /* BTR_CUR_HASH_ADAPT */
+ buf_flush_dirty_pages(buf_pool, id, observer);
}
- if (trx && !observer && !trx_is_interrupted(trx)) {
+ if (observer && !observer->is_interrupted()) {
/* Ensure that all asynchronous IO is completed. */
os_aio_wait_until_no_pending_writes();
fil_flush(id);
@@ -1099,8 +1087,6 @@ buf_LRU_get_free_block(
bool freed = false;
ulint n_iterations = 0;
ulint flush_failures = 0;
- bool mon_value_was = false;
- bool started_monitor = false;
MONITOR_INC(MONITOR_LRU_GET_FREE_SEARCH);
loop:
@@ -1108,6 +1094,11 @@ loop:
buf_LRU_check_size_of_non_data_objects(buf_pool);
+ DBUG_EXECUTE_IF("ib_lru_force_no_free_page",
+ if (!buf_lru_free_blocks_error_printed) {
+ n_iterations = 21;
+ goto not_found;});
+
/* If there is a block in the free list, take it */
block = buf_LRU_get_free_only(buf_pool);
@@ -1117,11 +1108,6 @@ loop:
ut_ad(buf_pool_from_block(block) == buf_pool);
memset(&block->page.zip, 0, sizeof block->page.zip);
- if (started_monitor) {
- srv_print_innodb_monitor =
- static_cast<my_bool>(mon_value_was);
- }
-
block->skip_flush_check = false;
block->page.flush_observer = NULL;
return(block);
@@ -1151,24 +1137,24 @@ loop:
}
}
+#ifndef DBUG_OFF
+not_found:
+#endif
+
buf_pool_mutex_exit(buf_pool);
if (freed) {
goto loop;
}
- if (n_iterations > 20
+ if (n_iterations > 20 && !buf_lru_free_blocks_error_printed
&& srv_buf_pool_old_size == srv_buf_pool_size) {
ib::warn() << "Difficult to find free blocks in the buffer pool"
" (" << n_iterations << " search iterations)! "
<< flush_failures << " failed attempts to"
- " flush a page! Consider increasing the buffer pool"
- " size. It is also possible that in your Unix version"
- " fsync is very slow, or completely frozen inside"
- " the OS kernel. Then upgrading to a newer version"
- " of your operating system may help. Look at the"
- " number of fsyncs in diagnostic info below."
+ " flush a page!"
+ " Consider increasing innodb_buffer_pool_size."
" Pending flushes (fsync) log: "
<< fil_n_pending_log_flushes
<< "; buffer pool: "
@@ -1176,13 +1162,9 @@ loop:
<< ". " << os_n_file_reads << " OS file reads, "
<< os_n_file_writes << " OS file writes, "
<< os_n_fsyncs
- << " OS fsyncs. Starting InnoDB Monitor to print"
- " further diagnostics to the standard output.";
+ << " OS fsyncs.";
- mon_value_was = srv_print_innodb_monitor;
- started_monitor = true;
- srv_print_innodb_monitor = true;
- os_event_set(srv_monitor_event);
+ buf_lru_free_blocks_error_printed = true;
}
/* If we have scanned the whole LRU and still are unable to
@@ -1901,7 +1883,7 @@ buf_LRU_block_free_non_file_page(
ut_d(block->page.in_free_list = TRUE);
}
- UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
+ UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE);
}
/******************************************************************//**
diff --git a/storage/innobase/data/data0type.cc b/storage/innobase/data/data0type.cc
index 61537fb5aa5..7c0539b3537 100644
--- a/storage/innobase/data/data0type.cc
+++ b/storage/innobase/data/data0type.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -28,6 +28,12 @@ Created 1/16/1996 Heikki Tuuri
#include "data0type.h"
+/** The DB_TRX_ID,DB_ROLL_PTR values for "no history is available" */
+const byte reset_trx_id[DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN] = {
+ 0, 0, 0, 0, 0, 0,
+ 0x80, 0, 0, 0, 0, 0, 0
+};
+
/* At the database startup we store the default-charset collation number of
this MySQL installation to this global variable. If we have < 4.1.2 format
column definitions, or records in the insert buffer, we use this
@@ -44,8 +50,10 @@ ulint
dtype_get_at_most_n_mbchars(
/*========================*/
ulint prtype, /*!< in: precise type */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of
+ a multi-byte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of
+ a multi-byte character, in bytes */
ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
@@ -53,9 +61,6 @@ dtype_get_at_most_n_mbchars(
const char* str) /*!< in: the string whose prefix
length is being determined */
{
- ulint mbminlen = DATA_MBMINLEN(mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen);
-
ut_a(len_is_stored(data_len));
ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen));
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index 77a79e32605..5fc9ba3d6e0 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -38,7 +38,6 @@ Created 1/8/1996 Heikki Tuuri
#include "row0mysql.h"
#include "pars0pars.h"
#include "trx0roll.h"
-#include "usr0sess.h"
#include "ut0vec.h"
#include "dict0priv.h"
#include "fts0priv.h"
diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc
index 3d1ee3f76e9..7b9a0373c48 100644
--- a/storage/innobase/dict/dict0defrag_bg.cc
+++ b/storage/innobase/dict/dict0defrag_bg.cc
@@ -207,11 +207,9 @@ stats and eventually save its stats. */
static
void
dict_stats_process_entry_from_defrag_pool()
-/*=======================================*/
{
table_id_t table_id;
index_id_t index_id;
- dberr_t err = DB_SUCCESS;
ut_ad(!srv_read_only_mode);
@@ -230,40 +228,20 @@ dict_stats_process_entry_from_defrag_pool()
table = dict_table_open_on_id(table_id, TRUE,
DICT_TABLE_OP_OPEN_ONLY_IF_CACHED);
- if (table == NULL) {
- mutex_exit(&dict_sys->mutex);
- return;
- }
+ dict_index_t* index = table && !table->corrupted
+ ? dict_table_find_index_on_id(table, index_id)
+ : NULL;
- /* Check whether table is corrupted */
- if (table->corrupted) {
- dict_table_close(table, TRUE, FALSE);
+ if (!index || dict_index_is_corrupted(index)) {
+ if (table) {
+ dict_table_close(table, TRUE, FALSE);
+ }
mutex_exit(&dict_sys->mutex);
return;
}
- mutex_exit(&dict_sys->mutex);
-
- dict_index_t* index = dict_table_find_index_on_id(table, index_id);
-
- if (index == NULL) {
- return;
- }
-
- /* Check whether index is corrupted */
- if (dict_index_is_corrupted(index)) {
- dict_table_close(table, FALSE, FALSE);
- return;
- }
-
- err = dict_stats_save_defrag_stats(index);
-
- if (err != DB_SUCCESS) {
- ib::error() << "Saving defragmentation status for table "
- << index->table->name.m_name
- << " index " << index->name()
- << " failed " << err;
- }
+ mutex_exit(&dict_sys->mutex);
+ dict_stats_save_defrag_stats(index);
dict_table_close(table, FALSE, FALSE);
}
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index b07140b8dd7..4309ead2feb 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -895,7 +895,7 @@ dict_index_get_nth_col_or_prefix_pos(
@param[in] n column number
@param[in] is_virtual whether it is a virtual col
@return TRUE if contains the column or its prefix */
-ibool
+bool
dict_index_contains_col_or_prefix(
const dict_index_t* index,
ulint n,
@@ -926,11 +926,11 @@ dict_index_contains_col_or_prefix(
if (col == field->col) {
- return(TRUE);
+ return(true);
}
}
- return(FALSE);
+ return(false);
}
/********************************************************************//**
@@ -1630,7 +1630,11 @@ dict_table_rename_in_cache(
return(DB_OUT_OF_MEMORY);
}
- fil_delete_tablespace(table->space, true);
+ fil_delete_tablespace(table->space
+#ifdef BTR_CUR_HASH_ADAPT
+ , true
+#endif /* BTR_CUR_HASH_ADAPT */
+ );
/* Delete any temp file hanging around. */
if (os_file_status(filepath, &exists, &ftype)
@@ -1673,6 +1677,8 @@ dict_table_rename_in_cache(
return(err);
}
+ fil_name_write_rename(table->space, old_path, new_path);
+
bool success = fil_rename_tablespace(
table->space, old_path, new_name, new_path);
@@ -3432,6 +3438,7 @@ dict_foreign_find_index(
&& !(index->type & DICT_FTS)
&& !dict_index_is_spatial(index)
&& !index->to_be_dropped
+ && !dict_index_is_online_ddl(index)
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
index, types_idx,
@@ -6498,7 +6505,7 @@ dict_table_schema_check(
}
if (should_print) {
- ut_snprintf(errstr, errstr_sz,
+ snprintf(errstr, errstr_sz,
"Table %s not found.",
ut_format_name(req_schema->table_name,
buf, sizeof(buf)));
@@ -6512,7 +6519,7 @@ dict_table_schema_check(
fil_space_get(table->space) == NULL) {
/* missing tablespace */
- ut_snprintf(errstr, errstr_sz,
+ snprintf(errstr, errstr_sz,
"Tablespace for table %s is missing.",
ut_format_name(req_schema->table_name,
buf, sizeof(buf)));
@@ -6522,12 +6529,12 @@ dict_table_schema_check(
if (ulint(table->n_def - DATA_N_SYS_COLS) != req_schema->n_cols) {
/* the table has a different number of columns than required */
- ut_snprintf(errstr, errstr_sz,
- "%s has %d columns but should have " ULINTPF ".",
- ut_format_name(req_schema->table_name,
- buf, sizeof(buf)),
- table->n_def - DATA_N_SYS_COLS,
- req_schema->n_cols);
+ snprintf(errstr, errstr_sz,
+ "%s has %d columns but should have " ULINTPF ".",
+ ut_format_name(req_schema->table_name, buf,
+ sizeof buf),
+ table->n_def - DATA_N_SYS_COLS,
+ req_schema->n_cols);
return(DB_ERROR);
}
@@ -6543,7 +6550,7 @@ dict_table_schema_check(
if (j == table->n_def) {
- ut_snprintf(errstr, errstr_sz,
+ snprintf(errstr, errstr_sz,
"required column %s"
" not found in table %s.",
req_schema->columns[i].name,
@@ -6562,7 +6569,7 @@ dict_table_schema_check(
CREATE_TYPES_NAMES();
- ut_snprintf(errstr, errstr_sz,
+ snprintf(errstr, errstr_sz,
"Column %s in table %s is %s"
" but should be %s (length mismatch).",
req_schema->columns[i].name,
@@ -6586,7 +6593,7 @@ dict_table_schema_check(
{
CREATE_TYPES_NAMES();
- ut_snprintf(errstr, errstr_sz,
+ snprintf(errstr, errstr_sz,
"Column %s in table %s is %s"
" but should be %s (type mismatch).",
req_schema->columns[i].name,
@@ -6605,7 +6612,7 @@ dict_table_schema_check(
CREATE_TYPES_NAMES();
- ut_snprintf(errstr, errstr_sz,
+ snprintf(errstr, errstr_sz,
"Column %s in table %s is %s"
" but should be %s (flags mismatch).",
req_schema->columns[i].name,
@@ -6618,7 +6625,7 @@ dict_table_schema_check(
}
if (req_schema->n_foreign != table->foreign_set.size()) {
- ut_snprintf(
+ snprintf(
errstr, errstr_sz,
"Table %s has " ULINTPF " foreign key(s) pointing"
" to other tables, but it must have " ULINTPF ".",
@@ -6630,7 +6637,7 @@ dict_table_schema_check(
}
if (req_schema->n_referenced != table->referenced_set.size()) {
- ut_snprintf(
+ snprintf(
errstr, errstr_sz,
"There are " ULINTPF " foreign key(s) pointing to %s, "
"but there must be " ULINTPF ".",
@@ -6704,7 +6711,7 @@ dict_fs2utf8(
&errors);
if (errors != 0) {
- ut_snprintf(table_utf8, table_utf8_size, "%s%s",
+ snprintf(table_utf8, table_utf8_size, "%s%s",
srv_mysql50_table_name_prefix, table);
}
}
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 0e55e353837..b50e0c81015 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -377,8 +377,7 @@ dict_getnext_system(
/********************************************************************//**
This function processes one SYS_TABLES record and populate the dict_table_t
-struct for the table. Extracted out of dict_print() to be used by
-both monitor table output and information schema innodb_sys_tables output.
+struct for the table.
@return error message, or NULL on success */
const char*
dict_process_sys_tables_rec_and_mtr_commit(
@@ -1445,7 +1444,7 @@ dict_check_sys_tables(
look to see if it is already in the tablespace cache. */
if (fil_space_for_table_exists_in_mem(
space_id, table_name.m_name,
- false, true, NULL, 0, flags)) {
+ false, NULL, flags)) {
/* Recovery can open a datafile that does not
match SYS_DATAFILES. If they don't match, update
SYS_DATAFILES. */
@@ -1469,8 +1468,6 @@ dict_check_sys_tables(
char* filepath = dict_get_first_path(space_id);
/* Check that the .ibd file exists. */
- validate = true; /* Encryption */
-
dberr_t err = fil_ibd_open(
validate,
!srv_read_only_mode && srv_log_file_size != 0,
@@ -2853,8 +2850,7 @@ dict_load_tablespace(
/* The tablespace may already be open. */
if (fil_space_for_table_exists_in_mem(
- table->space, space_name, false,
- true, heap, table->id, table->flags)) {
+ table->space, space_name, false, heap, table->flags)) {
return;
}
@@ -3051,9 +3047,13 @@ err_exit:
}
}
- if (err == DB_SUCCESS && cached && table->is_readable()
- && table->supports_instant()) {
- err = btr_cur_instant_init(table);
+ if (err == DB_SUCCESS && cached && table->is_readable()) {
+ if (table->space && !fil_space_get_size(table->space)) {
+ table->corrupted = true;
+ table->file_unreadable = true;
+ } else if (table->supports_instant()) {
+ err = btr_cur_instant_init(table);
+ }
}
/* Initialize table foreign_child value. Its value could be
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index e7a1d9c9b77..2e175731d5f 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -311,6 +311,16 @@ dict_mem_table_add_col(
col = dict_table_get_nth_col(table, i);
dict_mem_fill_column_struct(col, i, mtype, prtype, len);
+
+ switch (prtype & DATA_VERSIONED) {
+ case DATA_VERS_START:
+ ut_ad(!table->vers_start);
+ table->vers_start = i;
+ break;
+ case DATA_VERS_END:
+ ut_ad(!table->vers_end);
+ table->vers_end = i;
+ }
}
/** Adds a virtual column definition to a table.
@@ -446,8 +456,8 @@ dict_mem_table_col_rename_low(
ut_ad(from_len <= NAME_LEN);
ut_ad(to_len <= NAME_LEN);
- char from[NAME_LEN];
- strncpy(from, s, NAME_LEN);
+ char from[NAME_LEN + 1];
+ strncpy(from, s, NAME_LEN + 1);
if (from_len == to_len) {
/* The easy case: simply replace the column name in
@@ -674,11 +684,11 @@ dict_mem_fill_column_struct(
column->mtype = (unsigned int) mtype;
column->prtype = (unsigned int) prtype;
column->len = (unsigned int) col_len;
+ dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
+ column->mbminlen = mbminlen;
+ column->mbmaxlen = mbmaxlen;
column->def_val.data = NULL;
column->def_val.len = UNIV_SQL_DEFAULT;
-
- dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
- dict_col_set_mbminmaxlen(column, mbminlen, mbmaxlen);
}
/**********************************************************************//**
@@ -1076,7 +1086,7 @@ dict_mem_create_temporary_tablename(
size = dblen + (sizeof(TEMP_FILE_PREFIX) + 3 + 20 + 1 + 10);
name = static_cast<char*>(mem_heap_alloc(heap, size));
memcpy(name, dbtab, dblen);
- ut_snprintf(name + dblen, size - dblen,
+ snprintf(name + dblen, size - dblen,
TEMP_FILE_PREFIX_INNODB UINT64PF "-" UINT32PF,
id, dict_temp_file_num);
@@ -1189,8 +1199,8 @@ dict_mem_table_is_system(
@param[in] clustered index definition after instant ADD COLUMN */
inline void dict_index_t::instant_add_field(const dict_index_t& instant)
{
- DBUG_ASSERT(is_clust());
- DBUG_ASSERT(instant.is_clust());
+ DBUG_ASSERT(is_primary());
+ DBUG_ASSERT(instant.is_primary());
DBUG_ASSERT(!instant.is_instant());
DBUG_ASSERT(n_def == n_fields);
DBUG_ASSERT(instant.n_def == instant.n_fields);
@@ -1464,3 +1474,73 @@ void dict_table_t::rollback_instant(unsigned n)
field->name = sys + sizeof "DB_ROW_ID\0DB_TRX_ID";
field->col = dict_table_get_sys_col(this, DATA_ROLL_PTR);
}
+
+
+/** Check if record in clustered index is historical row.
+@param[in] rec clustered row
+@param[in] offsets offsets
+@return true if row is historical */
+bool
+dict_index_t::vers_history_row(
+ const rec_t* rec,
+ const ulint* offsets)
+{
+ ut_ad(is_primary());
+
+ ulint len;
+ dict_col_t& col= table->cols[table->vers_end];
+ ut_ad(col.vers_sys_end());
+ ulint nfield = dict_col_get_clust_pos(&col, this);
+ const byte *data = rec_get_nth_field(rec, offsets, nfield, &len);
+ if (col.mtype == DATA_FIXBINARY) {
+ ut_ad(len == sizeof timestamp_max_bytes);
+ return 0 != memcmp(data, timestamp_max_bytes, len);
+ } else {
+ ut_ad(col.mtype == DATA_INT);
+ ut_ad(len == sizeof trx_id_max_bytes);
+ return 0 != memcmp(data, trx_id_max_bytes, len);
+ }
+ ut_ad(0);
+ return false;
+}
+
+/** Check if record in secondary index is historical row.
+@param[in] rec record in a secondary index
+@param[out] history_row true if row is historical
+@return true on error */
+bool
+dict_index_t::vers_history_row(
+ const rec_t* rec,
+ bool &history_row)
+{
+ ut_ad(!is_primary());
+
+ bool error = false;
+ mem_heap_t* heap = NULL;
+ dict_index_t* clust_index = NULL;
+ ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ ulint* offsets = offsets_;
+ rec_offs_init(offsets_);
+
+ mtr_t mtr;
+ mtr.start();
+
+ rec_t* clust_rec =
+ row_get_clust_rec(BTR_SEARCH_LEAF, rec, this, &clust_index, &mtr);
+ if (clust_rec) {
+ offsets = rec_get_offsets(clust_rec, clust_index, offsets, true,
+ ULINT_UNDEFINED, &heap);
+
+ history_row = clust_index->vers_history_row(clust_rec, offsets);
+ } else {
+ ib::error() << "foreign constraints: secondary index is out of "
+ "sync";
+ ut_ad(!"secondary index is out of sync");
+ error = true;
+ }
+ mtr.commit();
+ if (heap) {
+ mem_heap_free(heap);
+ }
+ return(error);
+}
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index e3d0effb5ac..c5ead3c1913 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2009, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2009, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2018, 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
@@ -543,29 +543,6 @@ dict_stats_empty_index(
}
}
-/**********************************************************************//**
-Clear defragmentation summary. */
-UNIV_INTERN
-void
-dict_stats_empty_defrag_summary(
-/*==================*/
- dict_index_t* index) /*!< in: index to clear defragmentation stats */
-{
- index->stat_defrag_n_pages_freed = 0;
-}
-
-/**********************************************************************//**
-Clear defragmentation related index stats. */
-UNIV_INTERN
-void
-dict_stats_empty_defrag_stats(
-/*==================*/
- dict_index_t* index) /*!< in: index to clear defragmentation stats */
-{
- index->stat_defrag_modified_counter = 0;
- index->stat_defrag_n_page_split = 0;
-}
-
/*********************************************************************//**
Write all zeros (or 1 where it makes sense) into a table and its indexes'
statistics members. The resulting stats correspond to an empty table. */
@@ -1103,10 +1080,10 @@ dict_stats_analyze_index_level(
== page_rec_get_next_const(page_get_infimum_rec(page)));
/* check that we are indeed on the desired level */
- ut_a(btr_page_get_level(page, mtr) == level);
+ ut_a(btr_page_get_level(page) == level);
/* there should not be any pages on the left */
- ut_a(btr_page_get_prev(page, mtr) == FIL_NULL);
+ ut_a(!page_has_prev(page));
if (REC_INFO_MIN_REC_FLAG & rec_get_info_bits(
btr_pcur_get_rec(&pcur), page_is_comp(page))) {
@@ -1724,10 +1701,10 @@ dict_stats_analyze_index_for_n_prefix(
ut_ad(first_rec == page_rec_get_next_const(page_get_infimum_rec(page)));
/* check that we are indeed on the desired level */
- ut_a(btr_page_get_level(page, mtr) == n_diff_data->level);
+ ut_a(btr_page_get_level(page) == n_diff_data->level);
/* there should not be any pages on the left */
- ut_a(btr_page_get_prev(page, mtr) == FIL_NULL);
+ ut_a(!page_has_prev(page));
/* check whether the first record on the leftmost page is marked
as such; we are on a non-leaf level */
@@ -1781,11 +1758,8 @@ dict_stats_analyze_index_for_n_prefix(
ut_a(left <= right);
ut_a(right <= last_idx_on_level);
- /* we do not pass (left, right) because we do not want to ask
- ut_rnd_interval() to work with too big numbers since
- ib_uint64_t could be bigger than ulint */
- const ulint rnd = ut_rnd_interval(
- 0, static_cast<ulint>(right - left));
+ const ulint rnd = right == left ? 0 :
+ ut_rnd_gen_ulint() % (right - left);
const ib_uint64_t dive_below_idx
= boundaries->at(static_cast<unsigned>(left + rnd));
@@ -2336,7 +2310,7 @@ rolled back only in the case of error, but not freed.
dberr_t
dict_stats_save_index_stat(
dict_index_t* index,
- lint last_update,
+ ib_time_t last_update,
const char* stat_name,
ib_uint64_t stat_value,
ib_uint64_t* sample_size,
@@ -2348,6 +2322,7 @@ dict_stats_save_index_stat(
char db_utf8[MAX_DB_UTF8_LEN];
char table_utf8[MAX_TABLE_UTF8_LEN];
+ ut_ad(!trx || trx->internal || trx->in_mysql_trx_list);
ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
ut_ad(mutex_own(&dict_sys->mutex));
@@ -2359,7 +2334,7 @@ dict_stats_save_index_stat(
pars_info_add_str_literal(pinfo, "table_name", table_utf8);
pars_info_add_str_literal(pinfo, "index_name", index->name);
UNIV_MEM_ASSERT_RW_ABORT(&last_update, 4);
- pars_info_add_int4_literal(pinfo, "last_update", last_update);
+ pars_info_add_int4_literal(pinfo, "last_update", (lint)last_update);
UNIV_MEM_ASSERT_RW_ABORT(stat_name, strlen(stat_name));
pars_info_add_str_literal(pinfo, "stat_name", stat_name);
UNIV_MEM_ASSERT_RW_ABORT(&stat_value, 8);
@@ -2464,14 +2439,17 @@ dict_stats_save(
const index_id_t* only_for_index)
{
pars_info_t* pinfo;
- lint now;
+ ib_time_t now;
dberr_t ret;
dict_table_t* table;
char db_utf8[MAX_DB_UTF8_LEN];
char table_utf8[MAX_TABLE_UTF8_LEN];
- if (table_orig->is_readable()) {
- } else {
+ if (high_level_read_only) {
+ return DB_READ_ONLY;
+ }
+
+ if (!table_orig->is_readable()) {
return (dict_stats_report_error(table_orig));
}
@@ -2480,19 +2458,15 @@ dict_stats_save(
dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8),
table_utf8, sizeof(table_utf8));
+ now = ut_time();
rw_lock_x_lock(dict_operation_lock);
mutex_enter(&dict_sys->mutex);
- /* MySQL's timestamp is 4 byte, so we use
- pars_info_add_int4_literal() which takes a lint arg, so "now" is
- lint */
- now = (lint) ut_time();
-
pinfo = pars_info_create();
pars_info_add_str_literal(pinfo, "database_name", db_utf8);
pars_info_add_str_literal(pinfo, "table_name", table_utf8);
- pars_info_add_int4_literal(pinfo, "last_update", now);
+ pars_info_add_int4_literal(pinfo, "last_update", (lint)now);
pars_info_add_ull_literal(pinfo, "n_rows", table->stat_n_rows);
pars_info_add_ull_literal(pinfo, "clustered_index_size",
table->stat_clustered_index_size);
@@ -2534,12 +2508,7 @@ dict_stats_save(
}
trx_t* trx = trx_allocate_for_background();
-
- if (srv_read_only_mode) {
- trx_start_internal_read_only(trx);
- } else {
- trx_start_internal(trx);
- }
+ trx_start_internal(trx);
dict_index_t* index;
index_map_t indexes(
@@ -2586,21 +2555,20 @@ dict_stats_save(
char stat_name[16];
char stat_description[1024];
- ut_snprintf(stat_name, sizeof(stat_name),
- "n_diff_pfx%02u", i + 1);
+ snprintf(stat_name, sizeof(stat_name),
+ "n_diff_pfx%02u", i + 1);
/* craft a string that contains the column names */
- ut_snprintf(stat_description,
- sizeof(stat_description),
- "%s", index->fields[0].name());
+ snprintf(stat_description, sizeof(stat_description),
+ "%s", index->fields[0].name());
for (unsigned j = 1; j <= i; j++) {
size_t len;
len = strlen(stat_description);
- ut_snprintf(stat_description + len,
- sizeof(stat_description) - len,
- ",%s", index->fields[j].name());
+ snprintf(stat_description + len,
+ sizeof(stat_description) - len,
+ ",%s", index->fields[j].name());
}
ret = dict_stats_save_index_stat(
@@ -3469,23 +3437,23 @@ dict_stats_drop_index(
}
if (ret != DB_SUCCESS) {
- ut_snprintf(errstr, errstr_sz,
- "Unable to delete statistics for index %s"
- " from %s%s: %s. They can be deleted later using"
- " DELETE FROM %s WHERE"
- " database_name = '%s' AND"
- " table_name = '%s' AND"
- " index_name = '%s';",
- iname,
- INDEX_STATS_NAME_PRINT,
- (ret == DB_LOCK_WAIT_TIMEOUT
- ? " because the rows are locked"
- : ""),
- ut_strerr(ret),
- INDEX_STATS_NAME_PRINT,
- db_utf8,
- table_utf8,
- iname);
+ snprintf(errstr, errstr_sz,
+ "Unable to delete statistics for index %s"
+ " from %s%s: %s. They can be deleted later using"
+ " DELETE FROM %s WHERE"
+ " database_name = '%s' AND"
+ " table_name = '%s' AND"
+ " index_name = '%s';",
+ iname,
+ INDEX_STATS_NAME_PRINT,
+ (ret == DB_LOCK_WAIT_TIMEOUT
+ ? " because the rows are locked"
+ : ""),
+ ut_strerr(ret),
+ INDEX_STATS_NAME_PRINT,
+ db_utf8,
+ table_utf8,
+ iname);
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: %s\n", errstr);
@@ -3615,26 +3583,26 @@ dict_stats_drop_table(
if (ret != DB_SUCCESS) {
- ut_snprintf(errstr, errstr_sz,
- "Unable to delete statistics for table %s.%s: %s."
- " They can be deleted later using"
+ snprintf(errstr, errstr_sz,
+ "Unable to delete statistics for table %s.%s: %s."
+ " They can be deleted later using"
- " DELETE FROM %s WHERE"
- " database_name = '%s' AND"
- " table_name = '%s';"
+ " DELETE FROM %s WHERE"
+ " database_name = '%s' AND"
+ " table_name = '%s';"
- " DELETE FROM %s WHERE"
- " database_name = '%s' AND"
- " table_name = '%s';",
+ " DELETE FROM %s WHERE"
+ " database_name = '%s' AND"
+ " table_name = '%s';",
- db_utf8, table_utf8,
- ut_strerr(ret),
+ db_utf8, table_utf8,
+ ut_strerr(ret),
- INDEX_STATS_NAME_PRINT,
- db_utf8, table_utf8,
+ INDEX_STATS_NAME_PRINT,
+ db_utf8, table_utf8,
- TABLE_STATS_NAME_PRINT,
- db_utf8, table_utf8);
+ TABLE_STATS_NAME_PRINT,
+ db_utf8, table_utf8);
}
return(ret);
@@ -3798,26 +3766,26 @@ dict_stats_rename_table(
&& n_attempts < 5);
if (ret != DB_SUCCESS) {
- ut_snprintf(errstr, errstr_sz,
- "Unable to rename statistics from"
- " %s.%s to %s.%s in %s: %s."
- " They can be renamed later using"
-
- " UPDATE %s SET"
- " database_name = '%s',"
- " table_name = '%s'"
- " WHERE"
- " database_name = '%s' AND"
- " table_name = '%s';",
-
- old_db_utf8, old_table_utf8,
- new_db_utf8, new_table_utf8,
- TABLE_STATS_NAME_PRINT,
- ut_strerr(ret),
-
- TABLE_STATS_NAME_PRINT,
- new_db_utf8, new_table_utf8,
- old_db_utf8, old_table_utf8);
+ snprintf(errstr, errstr_sz,
+ "Unable to rename statistics from"
+ " %s.%s to %s.%s in %s: %s."
+ " They can be renamed later using"
+
+ " UPDATE %s SET"
+ " database_name = '%s',"
+ " table_name = '%s'"
+ " WHERE"
+ " database_name = '%s' AND"
+ " table_name = '%s';",
+
+ old_db_utf8, old_table_utf8,
+ new_db_utf8, new_table_utf8,
+ TABLE_STATS_NAME_PRINT,
+ ut_strerr(ret),
+
+ TABLE_STATS_NAME_PRINT,
+ new_db_utf8, new_table_utf8,
+ old_db_utf8, old_table_utf8);
mutex_exit(&dict_sys->mutex);
rw_lock_x_unlock(dict_operation_lock);
return(ret);
@@ -3857,31 +3825,32 @@ dict_stats_rename_table(
rw_lock_x_unlock(dict_operation_lock);
if (ret != DB_SUCCESS) {
- ut_snprintf(errstr, errstr_sz,
- "Unable to rename statistics from"
- " %s.%s to %s.%s in %s: %s."
- " They can be renamed later using"
-
- " UPDATE %s SET"
- " database_name = '%s',"
- " table_name = '%s'"
- " WHERE"
- " database_name = '%s' AND"
- " table_name = '%s';",
-
- old_db_utf8, old_table_utf8,
- new_db_utf8, new_table_utf8,
- INDEX_STATS_NAME_PRINT,
- ut_strerr(ret),
-
- INDEX_STATS_NAME_PRINT,
- new_db_utf8, new_table_utf8,
- old_db_utf8, old_table_utf8);
+ snprintf(errstr, errstr_sz,
+ "Unable to rename statistics from"
+ " %s.%s to %s.%s in %s: %s."
+ " They can be renamed later using"
+
+ " UPDATE %s SET"
+ " database_name = '%s',"
+ " table_name = '%s'"
+ " WHERE"
+ " database_name = '%s' AND"
+ " table_name = '%s';",
+
+ old_db_utf8, old_table_utf8,
+ new_db_utf8, new_table_utf8,
+ INDEX_STATS_NAME_PRINT,
+ ut_strerr(ret),
+
+ INDEX_STATS_NAME_PRINT,
+ new_db_utf8, new_table_utf8,
+ old_db_utf8, old_table_utf8);
}
return(ret);
}
+#ifdef MYSQL_RENAME_INDEX
/*********************************************************************//**
Renames an index in InnoDB persistent stats storage.
This function creates its own transaction and commits it.
@@ -3938,6 +3907,7 @@ dict_stats_rename_index(
return(ret);
}
+#endif /* MYSQL_RENAME_INDEX */
/* tests @{ */
#ifdef UNIV_ENABLE_UNIT_TEST_DICT_STATS
@@ -3979,7 +3949,7 @@ test_dict_table_schema_check()
};
char errstr[512];
- ut_snprintf(errstr, sizeof(errstr), "Table not found");
+ snprintf(errstr, sizeof(errstr), "Table not found");
/* prevent any data dictionary modifications while we are checking
the tables' structure */
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index 133e7904c94..6c9a17c8a7c 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -280,10 +280,10 @@ dict_stats_thread_init()
1) the background stats gathering thread before any other latch
and released without latching anything else in between (thus
any level would do here)
- 2) from row_update_statistics_if_needed()
+ 2) from dict_stats_update_if_needed()
and released without latching anything else in between. We know
that dict_sys->mutex (SYNC_DICT) is not acquired when
- row_update_statistics_if_needed() is called and it may be acquired
+ dict_stats_update_if_needed() is called and it may be acquired
inside that function (thus a level <=SYNC_DICT would do).
3) from row_drop_table_for_mysql() after dict_sys->mutex (SYNC_DICT)
and dict_operation_lock (SYNC_DICT_OPERATION) have been locked
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 08a832a4cd5..63f48613896 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -589,7 +589,7 @@ fil_encrypt_buf(
int rc = encryption_scheme_encrypt(src, srclen, dst, &dstlen,
crypt_data, key_version,
- space, offset, lsn);
+ (uint32)space, (uint32)offset, lsn);
ut_a(rc == MY_AES_OK);
ut_a(dstlen == srclen);
@@ -1715,7 +1715,7 @@ btr_scrub_get_block_and_allocation_status(
mtr_start(&local_mtr);
- *allocation_status = fseg_page_is_free(space, offset) ?
+ *allocation_status = fseg_page_is_free(space, (uint32_t)offset) ?
BTR_SCRUB_PAGE_FREE :
BTR_SCRUB_PAGE_ALLOCATED;
@@ -1779,7 +1779,7 @@ fil_crypt_rotate_page(
return;
}
- ut_d(const bool was_free = fseg_page_is_free(space, offset));
+ ut_d(const bool was_free = fseg_page_is_free(space, (uint32_t)offset));
mtr_t mtr;
mtr.start();
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 90a3baa6f83..b66ad9a86cf 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2014, 2018, 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
@@ -188,19 +188,19 @@ bool
fil_validate_skip(void)
/*===================*/
{
- /** The fil_validate() call skip counter. Use a signed type
- because of the race condition below. */
+ /** The fil_validate() call skip counter. */
static int fil_validate_count = FIL_VALIDATE_SKIP;
- /* There is a race condition below, but it does not matter,
- because this call is only for heuristic purposes. We want to
- reduce the call frequency of the costly fil_validate() check
- in debug builds. */
- if (--fil_validate_count > 0) {
+ /* We want to reduce the call frequency of the costly fil_validate()
+ check in debug builds. */
+ int count = my_atomic_add32_explicit(&fil_validate_count, -1,
+ MY_MEMORY_ORDER_RELAXED);
+ if (count > 0) {
return(true);
}
- fil_validate_count = FIL_VALIDATE_SKIP;
+ my_atomic_store32_explicit(&fil_validate_count, FIL_VALIDATE_SKIP,
+ MY_MEMORY_ORDER_RELAXED);
return(fil_validate());
}
#endif /* UNIV_DEBUG */
@@ -566,7 +566,6 @@ bool
fil_node_open_file(
fil_node_t* node)
{
- os_offset_t size_bytes;
bool success;
bool read_only_mode;
fil_space_t* space = node->space;
@@ -611,7 +610,7 @@ retry:
return(false);
}
- size_bytes = os_file_get_size(node->handle);
+ os_offset_t size_bytes = os_file_get_size(node->handle);
ut_a(size_bytes != (os_offset_t) -1);
ut_a(space->purpose != FIL_TYPE_LOG);
@@ -625,6 +624,7 @@ retry:
<< " is only " << size_bytes
<< " bytes, should be at least " << min_size;
os_file_close(node->handle);
+ node->handle = OS_FILE_CLOSED;
return(false);
}
@@ -662,10 +662,12 @@ retry:
ut_free(buf2);
os_file_close(node->handle);
+ node->handle = OS_FILE_CLOSED;
if (!fsp_flags_is_valid(flags, space->id)) {
ulint cflags = fsp_flags_convert_from_101(flags);
- if (cflags == ULINT_UNDEFINED) {
+ if (cflags == ULINT_UNDEFINED
+ || (cflags ^ space->flags) & ~FSP_FLAGS_MEM_MASK) {
ib::error()
<< "Expected tablespace flags "
<< ib::hex(space->flags)
@@ -694,20 +696,17 @@ retry:
space->free_len = free_len;
if (first_time_open) {
- ulint extent_size;
-
- extent_size = psize * FSP_EXTENT_SIZE;
-
- /* After apply-incremental, tablespaces are not extended
- to a whole megabyte. Do not cut off valid data. */
-
/* Truncate the size to a multiple of extent size. */
- if (size_bytes >= extent_size) {
- size_bytes = ut_2pow_round(size_bytes,
- 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);
}
- node->size = static_cast<ulint>(size_bytes / psize);
+ node->size = ulint(size_bytes / psize);
space->size += node->size;
}
}
@@ -2113,7 +2112,7 @@ fil_write_flushed_lsn(
{
byte* buf1;
byte* buf;
- dberr_t err;
+ dberr_t err = DB_TABLESPACE_NOT_FOUND;
buf1 = static_cast<byte*>(ut_malloc_nokey(2 * UNIV_PAGE_SIZE));
buf = static_cast<byte*>(ut_align(buf1, UNIV_PAGE_SIZE));
@@ -2331,7 +2330,7 @@ fil_op_write_log(
@param[in,out] mtr mini-transaction */
static
void
-fil_name_write_rename(
+fil_name_write_rename_low(
ulint space_id,
ulint first_page_no,
const char* old_name,
@@ -2345,6 +2344,23 @@ fil_name_write_rename(
space_id, first_page_no, old_name, new_name, 0, mtr);
}
+/** Write redo log for renaming a file.
+@param[in] space_id tablespace id
+@param[in] old_name tablespace file name
+@param[in] new_name tablespace file name after renaming */
+void
+fil_name_write_rename(
+ ulint space_id,
+ const char* old_name,
+ const char* new_name)
+{
+ mtr_t mtr;
+ mtr.start();
+ fil_name_write_rename_low(space_id, 0, old_name, new_name, &mtr);
+ mtr.commit();
+ log_write_up_to(mtr.commit_lsn(), true);
+}
+
/** Write MLOG_FILE_NAME for a file.
@param[in] space_id tablespace id
@param[in] first_page_no first page number in the file
@@ -2907,7 +2923,10 @@ fil_close_tablespace(
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, trx);
+ {
+ FlushObserver observer(id, trx, NULL);
+ buf_LRU_flush_or_remove_pages(id, &observer);
+ }
/* If the free is successful, the X lock will be released before
the space memory data structure is freed. */
@@ -2961,10 +2980,14 @@ fil_table_accessible(const dict_table_t* table)
/** Delete a tablespace and associated .ibd file.
@param[in] id tablespace identifier
-@param[in] drop_ahi whether to drop the adaptive hash index
@return DB_SUCCESS or error */
dberr_t
-fil_delete_tablespace(ulint id, bool drop_ahi)
+fil_delete_tablespace(
+ ulint id
+#ifdef BTR_CUR_HASH_ADAPT
+ , bool drop_ahi /*!< whether to drop the adaptive hash index */
+#endif /* BTR_CUR_HASH_ADAPT */
+ )
{
char* path = 0;
fil_space_t* space = 0;
@@ -3007,7 +3030,11 @@ fil_delete_tablespace(ulint id, bool drop_ahi)
To deal with potential read requests, we will check the
::stop_new_ops flag in fil_io(). */
- buf_LRU_flush_or_remove_pages(id, NULL, drop_ahi);
+ buf_LRU_flush_or_remove_pages(id, NULL
+#ifdef BTR_CUR_HASH_ADAPT
+ , drop_ahi
+#endif /* BTR_CUR_HASH_ADAPT */
+ );
/* If it is a delete then also delete any generated files, otherwise
when we drop the database the remove directory will fail. */
@@ -3287,7 +3314,11 @@ fil_discard_tablespace(
{
dberr_t err;
- switch (err = fil_delete_tablespace(id, true)) {
+ switch (err = fil_delete_tablespace(id
+#ifdef BTR_CUR_HASH_ADAPT
+ , true
+#endif /* BTR_CUR_HASH_ADAPT */
+ )) {
case DB_SUCCESS:
break;
@@ -3580,12 +3611,7 @@ func_exit:
ut_ad(strchr(new_file_name, OS_PATH_SEPARATOR) != NULL);
if (!recv_recovery_on) {
- mtr_t mtr;
-
- mtr.start();
- fil_name_write_rename(
- id, 0, old_file_name, new_file_name, &mtr);
- mtr.commit();
+ fil_name_write_rename(id, old_file_name, new_file_name);
log_mutex_enter();
}
@@ -4201,7 +4227,8 @@ skip_validate:
err = DB_ERROR;
}
- if (purpose != FIL_TYPE_IMPORT && !srv_read_only_mode) {
+ if (err == DB_SUCCESS && validate
+ && purpose != FIL_TYPE_IMPORT && !srv_read_only_mode) {
df_remote.close();
df_dict.close();
df_default.close();
@@ -4615,7 +4642,9 @@ fsp_flags_try_adjust(ulint space_id, ulint flags)
{
ut_ad(!srv_read_only_mode);
ut_ad(fsp_flags_is_valid(flags, space_id));
-
+ if (!fil_space_get_size(space_id)) {
+ return;
+ }
mtr_t mtr;
mtr.start();
if (buf_block_t* b = buf_page_get(
@@ -4648,9 +4677,7 @@ startup, there may be many tablespaces which are not yet in the memory cache.
@param[in] print_error_if_does_not_exist
Print detailed error information to the
error log if a matching tablespace is not found from memory.
-@param[in] adjust_space Whether to adjust space id on mismatch
@param[in] heap Heap memory
-@param[in] table_id table id
@param[in] table_flags table flags
@return true if a matching tablespace exists in the memory cache */
bool
@@ -4658,9 +4685,7 @@ fil_space_for_table_exists_in_mem(
ulint id,
const char* name,
bool print_error_if_does_not_exist,
- bool adjust_space,
mem_heap_t* heap,
- table_id_t table_id,
ulint table_flags)
{
fil_space_t* fnamespace;
@@ -4685,41 +4710,6 @@ fil_space_for_table_exists_in_mem(
} else if (!valid || space == fnamespace) {
/* Found with the same file name, or got a flag mismatch. */
goto func_exit;
- } else if (adjust_space
- && row_is_mysql_tmp_table_name(space->name)
- && !row_is_mysql_tmp_table_name(name)) {
- /* Info from fnamespace comes from the ibd file
- itself, it can be different from data obtained from
- System tables since renaming files is not
- transactional. We shall adjust the ibd file name
- according to system table info. */
- mutex_exit(&fil_system->mutex);
-
- DBUG_EXECUTE_IF("ib_crash_before_adjust_fil_space",
- DBUG_SUICIDE(););
-
- const char* tmp_name = dict_mem_create_temporary_tablename(
- heap, name, table_id);
-
- fil_rename_tablespace(
- fnamespace->id,
- UT_LIST_GET_FIRST(fnamespace->chain)->name,
- tmp_name, NULL);
-
- DBUG_EXECUTE_IF("ib_crash_after_adjust_one_fil_space",
- DBUG_SUICIDE(););
-
- fil_rename_tablespace(
- id, UT_LIST_GET_FIRST(space->chain)->name,
- name, NULL);
-
- DBUG_EXECUTE_IF("ib_crash_after_adjust_fil_space",
- DBUG_SUICIDE(););
-
- mutex_enter(&fil_system->mutex);
- fnamespace = fil_space_get_by_name(name);
- ut_ad(space == fnamespace);
- goto func_exit;
}
if (!print_error_if_does_not_exist) {
@@ -5994,17 +5984,6 @@ fil_tablespace_iterate(
innodb_data_file_key, filepath,
OS_FILE_OPEN, OS_FILE_READ_WRITE, srv_read_only_mode, &success);
- DBUG_EXECUTE_IF("fil_tablespace_iterate_failure",
- {
- static bool once;
-
- if (!once || ut_rnd_interval(0, 10) == 5) {
- once = true;
- success = false;
- os_file_close(file);
- }
- });
-
if (!success) {
/* The following call prints an error message */
os_file_get_last_error(true);
@@ -6157,51 +6136,6 @@ fil_delete_file(
}
}
-/**
-Iterate over all the spaces in the space list and fetch the
-tablespace names. It will return a copy of the name that must be
-freed by the caller using: delete[].
-@return DB_SUCCESS if all OK. */
-dberr_t
-fil_get_space_names(
-/*================*/
- space_name_list_t& space_name_list)
- /*!< in/out: List to append to */
-{
- fil_space_t* space;
- dberr_t err = DB_SUCCESS;
-
- 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)) {
-
- if (space->purpose == FIL_TYPE_TABLESPACE) {
- ulint len;
- char* name;
-
- len = ::strlen(space->name);
- name = UT_NEW_ARRAY_NOKEY(char, len + 1);
-
- if (name == 0) {
- /* Caller to free elements allocated so far. */
- err = DB_OUT_OF_MEMORY;
- break;
- }
-
- memcpy(name, space->name, len);
- name[len] = 0;
-
- space_name_list.push_back(name);
- }
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(err);
-}
-
/** Generate redo log for swapping two .ibd files
@param[in] old_table old table
@param[in] new_table new table
@@ -6257,7 +6191,7 @@ fil_mtr_rename_log(
return(err);
}
- fil_name_write_rename(
+ fil_name_write_rename_low(
old_table->space, 0, old_path, tmp_path, mtr);
ut_free(tmp_path);
@@ -6288,7 +6222,7 @@ fil_mtr_rename_log(
}
}
- fil_name_write_rename(
+ fil_name_write_rename_low(
new_table->space, 0, new_path, old_path, mtr);
ut_free(new_path);
diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc
index c21c9497735..6e9f307ebc8 100644
--- a/storage/innobase/fsp/fsp0file.cc
+++ b/storage/innobase/fsp/fsp0file.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -516,8 +516,18 @@ Datafile::validate_first_page(lsn_t* flush_lsn)
}
}
+ if (error_txt != NULL) {
+err_exit:
+ ib::error() << error_txt << " in datafile: " << m_filepath
+ << ", Space ID:" << m_space_id << ", Flags: "
+ << m_flags << ". " << TROUBLESHOOT_DATADICT_MSG;
+ m_is_valid = false;
+ free_first_page();
+ return(DB_CORRUPTION);
+ }
+
/* Check if the whole page is blank. */
- if (error_txt == NULL && !m_space_id && !m_flags) {
+ if (!m_space_id && !m_flags) {
const byte* b = m_first_page;
ulint nonzero_bytes = UNIV_PAGE_SIZE;
@@ -528,56 +538,45 @@ Datafile::validate_first_page(lsn_t* flush_lsn)
if (nonzero_bytes == 0) {
error_txt = "Header page consists of zero bytes";
+ goto err_exit;
}
}
- const page_size_t page_size(m_flags);
-
- if (error_txt != NULL) {
+ if (!fsp_flags_is_valid(m_flags, m_space_id)) {
+ /* Tablespace flags must be valid. */
+ error_txt = "Tablespace flags are invalid";
+ goto err_exit;
+ }
- /* skip the next few tests */
- } else if (univ_page_size.logical() != page_size.logical()) {
+ const page_size_t page_size(m_flags);
+ if (univ_page_size.logical() != page_size.logical()) {
/* Page size must be univ_page_size. */
-
ib::error()
<< "Data file '" << m_filepath << "' uses page size "
<< page_size.logical() << ", but the innodb_page_size"
" start-up parameter is "
<< univ_page_size.logical();
-
free_first_page();
-
return(DB_ERROR);
- } else if (!fsp_flags_is_valid(m_flags, m_space_id)) {
- /* Tablespace flags must be valid. */
- error_txt = "Tablespace flags are invalid";
- } else if (page_get_page_no(m_first_page) != 0) {
+ }
+ if (page_get_page_no(m_first_page) != 0) {
/* First page must be number 0 */
error_txt = "Header page contains inconsistent data";
+ goto err_exit;
+ }
- } else if (m_space_id == ULINT_UNDEFINED) {
-
+ if (m_space_id == ULINT_UNDEFINED) {
/* The space_id can be most anything, except -1. */
error_txt = "A bad Space ID was found";
+ goto err_exit;
+ }
- } else if (buf_page_is_corrupted(false, m_first_page, page_size)) {
-
+ if (buf_page_is_corrupted(false, m_first_page, page_size)) {
/* Look for checksum and other corruptions. */
error_txt = "Checksum mismatch";
- }
-
- if (error_txt != NULL) {
- ib::error() << error_txt << " in datafile: " << m_filepath
- << ", Space ID:" << m_space_id << ", Flags: "
- << m_flags << ". " << TROUBLESHOOT_DATADICT_MSG;
- m_is_valid = false;
-
- free_first_page();
-
- return(DB_CORRUPTION);
-
+ goto err_exit;
}
if (fil_space_read_name_and_filepath(
@@ -770,6 +769,10 @@ the double write buffer.
bool
Datafile::restore_from_doublewrite()
{
+ if (srv_operation != SRV_OPERATION_NORMAL) {
+ return true;
+ }
+
/* Find if double write buffer contains page_no of given space id. */
const byte* page = recv_sys->dblwr.find_page(m_space_id, 0);
const page_id_t page_id(m_space_id, 0);
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 80303314d9f..dd0148a3275 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -1108,7 +1108,7 @@ fsp_fill_free_list(
skip_resize = !srv_sys_space.can_auto_extend_last_file();
break;
case SRV_TMP_SPACE_ID:
- skip_resize = srv_tmp_space.can_auto_extend_last_file();
+ skip_resize = !srv_tmp_space.can_auto_extend_last_file();
break;
}
@@ -2446,8 +2446,6 @@ fseg_alloc_free_page_low(
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
- ut_ad(space->purpose == FIL_TYPE_TEMPORARY
- || space->purpose == FIL_TYPE_TABLESPACE);
seg_id = mach_read_from_8(seg_inode + FSEG_ID);
ut_ad(seg_id);
diff --git a/storage/innobase/fsp/fsp0sysspace.cc b/storage/innobase/fsp/fsp0sysspace.cc
index c459c8296e0..e9f04cbd6c5 100644
--- a/storage/innobase/fsp/fsp0sysspace.cc
+++ b/storage/innobase/fsp/fsp0sysspace.cc
@@ -567,8 +567,9 @@ SysTablespace::read_lsn_and_check_flags(lsn_t* flushed_lsn)
ut_a(it->order() == 0);
-
- buf_dblwr_init_or_load_pages(it->handle(), it->filepath());
+ if (srv_operation == SRV_OPERATION_NORMAL) {
+ buf_dblwr_init_or_load_pages(it->handle(), it->filepath());
+ }
/* Check the contents of the first page of the
first datafile. */
diff --git a/storage/innobase/fts/fts0config.cc b/storage/innobase/fts/fts0config.cc
index 4d41df1abf9..7ad7459ea6a 100644
--- a/storage/innobase/fts/fts0config.cc
+++ b/storage/innobase/fts/fts0config.cc
@@ -349,7 +349,7 @@ fts_config_set_index_ulint(
// FIXME: Get rid of snprintf
ut_a(FTS_MAX_INT_LEN < FTS_MAX_CONFIG_VALUE_LEN);
- value.f_len = ut_snprintf(
+ value.f_len = snprintf(
(char*) value.f_str, FTS_MAX_INT_LEN, ULINTPF, int_value);
error = fts_config_set_index_value(trx, index, name, &value);
@@ -422,7 +422,7 @@ fts_config_set_ulint(
ut_a(FTS_MAX_INT_LEN < FTS_MAX_CONFIG_VALUE_LEN);
- value.f_len = my_snprintf(
+ value.f_len = snprintf(
(char*) value.f_str, FTS_MAX_INT_LEN, ULINTPF, int_value);
error = fts_config_set_value(trx, fts_table, name, &value);
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 8e9c897274b..d1c3d004456 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -2008,7 +2008,7 @@ fts_create_one_index_table(
? DATA_VARCHAR : DATA_VARMYSQL,
field->col->prtype,
FTS_MAX_WORD_LEN_IN_CHAR
- * DATA_MBMAXLEN(field->col->mbminmaxlen));
+ * field->col->mbmaxlen);
dict_mem_table_add_col(new_table, heap, "first_doc_id", DATA_INT,
DATA_NOT_NULL | DATA_UNSIGNED,
@@ -2309,7 +2309,6 @@ fts_savepoint_create(
/******************************************************************//**
Create an FTS trx.
@return FTS trx */
-static
fts_trx_t*
fts_trx_create(
/*===========*/
@@ -2706,6 +2705,11 @@ retry:
fts_table.parent = table->name.m_name;
trx = trx_allocate_for_background();
+ if (srv_read_only_mode) {
+ trx_start_internal_read_only(trx);
+ } else {
+ trx_start_internal(trx);
+ }
trx->op_info = "update the next FTS document id";
@@ -2814,6 +2818,10 @@ fts_update_sync_doc_id(
fts_cache_t* cache = table->fts->cache;
char fts_name[MAX_FULL_NAME_LEN];
+ if (srv_read_only_mode) {
+ return DB_READ_ONLY;
+ }
+
fts_table.suffix = "CONFIG";
fts_table.table_id = table->id;
fts_table.type = FTS_COMMON_TABLE;
@@ -2826,6 +2834,7 @@ fts_update_sync_doc_id(
if (!trx) {
trx = trx_allocate_for_background();
+ trx_start_internal(trx);
trx->op_info = "setting last FTS document id";
local_trx = TRUE;
@@ -2833,7 +2842,7 @@ fts_update_sync_doc_id(
info = pars_info_create();
- id_len = ut_snprintf(
+ id_len = snprintf(
(char*) id, sizeof(id), FTS_DOC_ID_FORMAT, doc_id + 1);
pars_info_bind_varchar_literal(info, "doc_id", id, id_len);
@@ -3057,12 +3066,18 @@ fts_commit_table(
/*=============*/
fts_trx_table_t* ftt) /*!< in: FTS table to commit*/
{
+ if (srv_read_only_mode) {
+ return DB_READ_ONLY;
+ }
+
const ib_rbt_node_t* node;
ib_rbt_t* rows;
dberr_t error = DB_SUCCESS;
fts_cache_t* cache = ftt->table->fts->cache;
trx_t* trx = trx_allocate_for_background();
+ trx_start_internal(trx);
+
rows = ftt->rows;
ftt->fts_trx->trx = trx;
@@ -3340,6 +3355,144 @@ fts_fetch_doc_from_rec(
}
}
+/** Fetch the data from tuple and tokenize the document.
+@param[in] get_doc FTS index's get_doc struct
+@param[in] tuple tuple should be arranged in table schema order
+@param[out] doc fts doc to hold parsed documents. */
+static
+void
+fts_fetch_doc_from_tuple(
+ fts_get_doc_t* get_doc,
+ const dtuple_t* tuple,
+ fts_doc_t* doc)
+{
+ dict_index_t* index;
+ st_mysql_ftparser* parser;
+ ulint doc_len = 0;
+ ulint processed_doc = 0;
+ ulint num_field;
+
+ if (get_doc == NULL) {
+ return;
+ }
+
+ index = get_doc->index_cache->index;
+ parser = get_doc->index_cache->index->parser;
+ num_field = dict_index_get_n_fields(index);
+
+ for (ulint i = 0; i < num_field; i++) {
+ const dict_field_t* ifield;
+ const dict_col_t* col;
+ ulint pos;
+ dfield_t* field;
+
+ ifield = dict_index_get_nth_field(index, i);
+ col = dict_field_get_col(ifield);
+ pos = dict_col_get_no(col);
+ field = dtuple_get_nth_field(tuple, pos);
+
+ if (!get_doc->index_cache->charset) {
+ get_doc->index_cache->charset = fts_get_charset(
+ ifield->col->prtype);
+ }
+
+ ut_ad(!dfield_is_ext(field));
+
+ doc->text.f_str = (byte*) dfield_get_data(field);
+ doc->text.f_len = dfield_get_len(field);
+ doc->found = TRUE;
+ doc->charset = get_doc->index_cache->charset;
+
+ /* field data is NULL. */
+ if (doc->text.f_len == UNIV_SQL_NULL || doc->text.f_len == 0) {
+ continue;
+ }
+
+ if (processed_doc == 0) {
+ fts_tokenize_document(doc, NULL, parser);
+ } else {
+ fts_tokenize_document_next(doc, doc_len, NULL, parser);
+ }
+
+ processed_doc++;
+ doc_len += doc->text.f_len + 1;
+ }
+}
+
+/** Fetch the document from tuple, tokenize the text data and
+insert the text data into fts auxiliary table and
+its cache. Moreover this tuple fields doesn't contain any information
+about externally stored field. This tuple contains data directly
+converted from mysql.
+@param[in] ftt FTS transaction table
+@param[in] doc_id doc id
+@param[in] tuple tuple from where data can be retrieved
+ and tuple should be arranged in table
+ schema order. */
+void
+fts_add_doc_from_tuple(
+ fts_trx_table_t*ftt,
+ doc_id_t doc_id,
+ const dtuple_t* tuple)
+{
+ mtr_t mtr;
+ fts_cache_t* cache = ftt->table->fts->cache;
+
+ ut_ad(cache->get_docs);
+
+ if (!(ftt->table->fts->fts_status & ADDED_TABLE_SYNCED)) {
+ fts_init_index(ftt->table, FALSE);
+ }
+
+ mtr_start(&mtr);
+
+ ulint num_idx = ib_vector_size(cache->get_docs);
+
+ for (ulint i = 0; i < num_idx; ++i) {
+ fts_doc_t doc;
+ dict_table_t* table;
+ fts_get_doc_t* get_doc;
+
+ get_doc = static_cast<fts_get_doc_t*>(
+ ib_vector_get(cache->get_docs, i));
+ table = get_doc->index_cache->index->table;
+
+ fts_doc_init(&doc);
+ fts_fetch_doc_from_tuple(
+ get_doc, tuple, &doc);
+
+ if (doc.found) {
+ mtr_commit(&mtr);
+ rw_lock_x_lock(&table->fts->cache->lock);
+
+ if (table->fts->cache->stopword_info.status
+ & STOPWORD_NOT_INIT) {
+ fts_load_stopword(table, NULL, NULL,
+ NULL, TRUE, TRUE);
+ }
+
+ fts_cache_add_doc(
+ table->fts->cache,
+ get_doc->index_cache,
+ doc_id, doc.tokens);
+
+ rw_lock_x_unlock(&table->fts->cache->lock);
+
+ if (cache->total_size > fts_max_cache_size / 5
+ || fts_need_sync) {
+ fts_sync(cache->sync, true, false, false);
+ }
+
+ mtr_start(&mtr);
+
+ }
+
+ fts_doc_free(&doc);
+ }
+
+ mtr_commit(&mtr);
+}
+
/*********************************************************************//**
This function fetches the document inserted during the committing
transaction, and tokenize the inserted text data and insert into
@@ -3753,13 +3906,7 @@ fts_doc_fetch_by_doc_id(
}
error = fts_eval_sql(trx, graph);
-
- if (error == DB_SUCCESS) {
- fts_sql_commit(trx);
- } else {
- fts_sql_rollback(trx);
- }
-
+ fts_sql_commit(trx);
trx_free_for_background(trx);
if (!get_doc) {
@@ -4012,6 +4159,7 @@ fts_sync_begin(
sync->start_time = ut_time();
sync->trx = trx_allocate_for_background();
+ trx_start_internal(sync->trx);
if (fts_enable_diag_print) {
ib::info() << "FTS SYNC for table " << sync->table->name
@@ -4227,6 +4375,10 @@ fts_sync(
bool wait,
bool has_dict)
{
+ if (srv_read_only_mode) {
+ return DB_READ_ONLY;
+ }
+
ulint i;
dberr_t error = DB_SUCCESS;
fts_cache_t* cache = sync->table->fts->cache;
@@ -4430,10 +4582,17 @@ fts_add_token(
t_str.f_str = static_cast<byte*>(
mem_heap_alloc(heap, t_str.f_len));
- newlen = innobase_fts_casedn_str(
- result_doc->charset,
- reinterpret_cast<char*>(str.f_str), str.f_len,
- reinterpret_cast<char*>(t_str.f_str), t_str.f_len);
+ /* For binary collations, a case sensitive search is
+ performed. Hence don't convert to lower case. */
+ if (my_binary_compare(result_doc->charset)) {
+ memcpy(t_str.f_str, str.f_str, str.f_len);
+ t_str.f_str[str.f_len]= 0;
+ newlen= str.f_len;
+ } else {
+ newlen = innobase_fts_casedn_str(
+ result_doc->charset, (char*) str.f_str, str.f_len,
+ (char*) t_str.f_str, t_str.f_len);
+ }
t_str.f_len = newlen;
t_str.f_str[newlen] = 0;
@@ -4875,7 +5034,6 @@ fts_get_rows_count(
char table_name[MAX_FULL_NAME_LEN];
trx = trx_allocate_for_background();
-
trx->op_info = "fetching FT table rows count";
info = pars_info_create();
@@ -7002,15 +7160,6 @@ fts_drop_orphaned_tables(void)
que_t* graph;
ib_vector_t* tables;
ib_alloc_t* heap_alloc;
- space_name_list_t space_name_list;
- dberr_t error = DB_SUCCESS;
-
- /* Note: We have to free the memory after we are done with the list. */
- error = fil_get_space_names(space_name_list);
-
- if (error == DB_OUT_OF_MEMORY) {
- ib::fatal() << "Out of memory";
- }
heap = mem_heap_create(1024);
heap_alloc = ib_heap_allocator_create(heap);
@@ -7023,35 +7172,32 @@ fts_drop_orphaned_tables(void)
users can't map them back to table names and this will create
unnecessary clutter. */
- for (space_name_list_t::iterator it = space_name_list.begin();
- it != space_name_list.end();
- ++it) {
-
- fts_aux_table_t* fts_aux_table;
+ mutex_enter(&fil_system->mutex);
- fts_aux_table = static_cast<fts_aux_table_t*>(
- ib_vector_push(tables, NULL));
+ for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system->space_list);
+ space != NULL;
+ space = UT_LIST_GET_NEXT(space_list, space)) {
- memset(fts_aux_table, 0x0, sizeof(*fts_aux_table));
-
- if (!fts_is_aux_table_name(fts_aux_table, *it, strlen(*it))) {
- ib_vector_pop(tables);
- } else {
- ulint len = strlen(*it);
-
- fts_aux_table->id = fil_space_get_id_by_name(*it);
+ if (space->purpose != FIL_TYPE_TABLESPACE) {
+ continue;
+ }
- /* We got this list from fil0fil.cc. The tablespace
- with this name must exist. */
- ut_a(fts_aux_table->id != ULINT_UNDEFINED);
+ fts_aux_table_t fts_aux_table;
+ memset(&fts_aux_table, 0x0, sizeof fts_aux_table);
- fts_aux_table->name = static_cast<char*>(
- mem_heap_dup(heap, *it, len + 1));
+ size_t len = strlen(space->name);
- fts_aux_table->name[len] = 0;
+ if (!fts_is_aux_table_name(&fts_aux_table, space->name, len)) {
+ continue;
}
+
+ fts_aux_table.id = space->id;
+ fts_aux_table.name = mem_heap_strdupl(heap, space->name, len);
+ ib_vector_push(tables, &fts_aux_table);
}
+ mutex_exit(&fil_system->mutex);
+
trx = trx_allocate_for_background();
trx->op_info = "dropping orphaned FTS tables";
row_mysql_lock_data_dictionary(trx);
@@ -7079,7 +7225,7 @@ fts_drop_orphaned_tables(void)
"CLOSE c;");
for (;;) {
- error = fts_eval_sql(trx, graph);
+ dberr_t error = fts_eval_sql(trx, graph);
if (error == DB_SUCCESS) {
fts_check_and_drop_orphaned_tables(trx, tables);
@@ -7112,14 +7258,6 @@ fts_drop_orphaned_tables(void)
if (heap != NULL) {
mem_heap_free(heap);
}
-
- /** Free the memory allocated to store the .ibd names. */
- for (space_name_list_t::iterator it = space_name_list.begin();
- it != space_name_list.end();
- ++it) {
-
- UT_DELETE_ARRAY(*it);
- }
}
/**********************************************************************//**
@@ -7217,6 +7355,11 @@ fts_load_stopword(
if (!trx) {
trx = trx_allocate_for_background();
+ if (srv_read_only_mode) {
+ trx_start_internal_read_only(trx);
+ } else {
+ trx_start_internal(trx);
+ }
trx->op_info = "upload FTS stopword";
new_trx = TRUE;
}
@@ -7408,8 +7551,7 @@ fts_init_recover_doc(
&doc.text.f_len,
static_cast<byte*>(dfield_get_data(dfield)),
dict_table_page_size(table), len,
- static_cast<mem_heap_t*>(doc.self_heap->arg)
- );
+ static_cast<mem_heap_t*>(doc.self_heap->arg));
} else {
doc.text.f_str = static_cast<byte*>(
dfield_get_data(dfield));
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index d7e434320a3..296494f6a63 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, MariaDB Corporation. All Rights reserved.
+Copyright (c) 2016, 2018, 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
@@ -1017,17 +1017,14 @@ fts_table_fetch_doc_ids(
"CLOSE c;");
error = fts_eval_sql(trx, graph);
+ fts_sql_commit(trx);
mutex_enter(&dict_sys->mutex);
que_graph_free(graph);
mutex_exit(&dict_sys->mutex);
if (error == DB_SUCCESS) {
- fts_sql_commit(trx);
-
ib_vector_sort(doc_ids->doc_ids, fts_update_doc_id_cmp);
- } else {
- fts_sql_rollback(trx);
}
if (alloc_bk_trx) {
@@ -1619,6 +1616,7 @@ fts_optimize_create(
optim->table = table;
optim->trx = trx_allocate_for_background();
+ trx_start_internal(optim->trx);
optim->fts_common_table.parent = table->name.m_name;
optim->fts_common_table.table_id = table->id;
@@ -1741,6 +1739,7 @@ fts_optimize_free(
{
mem_heap_t* heap = static_cast<mem_heap_t*>(optim->self_heap->arg);
+ trx_commit_for_mysql(optim->trx);
trx_free_for_background(optim->trx);
fts_doc_ids_free(optim->to_delete);
@@ -2439,6 +2438,10 @@ fts_optimize_table(
/*===============*/
dict_table_t* table) /*!< in: table to optimiza */
{
+ if (srv_read_only_mode) {
+ return DB_READ_ONLY;
+ }
+
dberr_t error = DB_SUCCESS;
fts_optimize_t* optim = NULL;
fts_t* fts = table->fts;
@@ -2969,7 +2972,7 @@ Optimize all FTS tables.
@return Dummy return */
static
os_thread_ret_t
-fts_optimize_thread(
+DECLARE_THREAD(fts_optimize_thread)(
/*================*/
void* arg) /*!< in: work queue*/
{
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index 1b03e041871..b9977bd31e5 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -2017,8 +2017,7 @@ fts_query_fetch_document(
if (dfield_is_ext(dfield)) {
data = btr_copy_externally_stored_field(
&cur_len, data, phrase->page_size,
- dfield_get_len(dfield), phrase->heap
- );
+ dfield_get_len(dfield), phrase->heap);
} else {
cur_len = dfield_get_len(dfield);
}
@@ -4030,9 +4029,17 @@ fts_query(
lc_query_str_len = query_len * charset->casedn_multiply + 1;
lc_query_str = static_cast<byte*>(ut_malloc_nokey(lc_query_str_len));
+ /* For binary collations, a case sensitive search is
+ performed. Hence don't convert to lower case. */
+ if (my_binary_compare(charset)) {
+ memcpy(lc_query_str, query_str, query_len);
+ lc_query_str[query_len]= 0;
+ result_len= query_len;
+ } else {
result_len = innobase_fts_casedn_str(
- charset, (char*) query_str, query_len,
- (char*) lc_query_str, lc_query_str_len);
+ charset, (char*)( query_str), query_len,
+ (char*)(lc_query_str), lc_query_str_len);
+ }
ut_ad(result_len < lc_query_str_len);
diff --git a/storage/innobase/fut/fut0lst.cc b/storage/innobase/fut/fut0lst.cc
index 9f79ac8df2b..3e77165ac31 100644
--- a/storage/innobase/fut/fut0lst.cc
+++ b/storage/innobase/fut/fut0lst.cc
@@ -40,7 +40,6 @@ flst_add_to_empty(
{
ulint space;
fil_addr_t node_addr;
- ulint len;
ut_ad(mtr && base && node);
ut_ad(base != node);
@@ -50,8 +49,7 @@ flst_add_to_empty(
ut_ad(mtr_memo_contains_page_flagged(mtr, node,
MTR_MEMO_PAGE_X_FIX
| MTR_MEMO_PAGE_SX_FIX));
- len = flst_get_len(base);
- ut_a(len == 0);
+ ut_a(!flst_get_len(base));
buf_ptr_get_fsp_addr(node, &space, &node_addr);
@@ -64,7 +62,7 @@ flst_add_to_empty(
flst_write_addr(node + FLST_NEXT, fil_addr_null, mtr);
/* Update len of base node */
- mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
+ mlog_write_ulint(base + FLST_LEN, 1, MLOG_4BYTES, mtr);
}
/********************************************************************//**
diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc
index 0061f57c539..fe98ac4f846 100644
--- a/storage/innobase/gis/gis0rtree.cc
+++ b/storage/innobase/gis/gis0rtree.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -309,7 +310,7 @@ rtr_update_mbr_field(
page_zip = buf_block_get_page_zip(block);
child = btr_node_ptr_get_child_page_no(rec, offsets);
- level = btr_page_get_level(buf_block_get_frame(block), mtr);
+ level = btr_page_get_level(buf_block_get_frame(block));
if (new_rec) {
child_rec = new_rec;
@@ -667,9 +668,8 @@ rtr_adjust_upper_level(
cursor.thr = sea_cur->thr;
/* Get the level of the split pages */
- level = btr_page_get_level(buf_block_get_frame(block), mtr);
- ut_ad(level
- == btr_page_get_level(buf_block_get_frame(new_block), mtr));
+ level = btr_page_get_level(buf_block_get_frame(block));
+ ut_ad(level == btr_page_get_level(buf_block_get_frame(new_block)));
page = buf_block_get_frame(block);
page_no = block->page.id.page_no();
@@ -1047,7 +1047,7 @@ func_start:
block = btr_cur_get_block(cursor);
page = buf_block_get_frame(block);
page_zip = buf_block_get_page_zip(block);
- page_level = btr_page_get_level(page, mtr);
+ page_level = btr_page_get_level(page);
current_ssn = page_get_ssn_id(page);
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
@@ -1055,7 +1055,7 @@ func_start:
page_no = block->page.id.page_no();
- if (btr_page_get_prev(page, mtr) == FIL_NULL && !page_is_leaf(page)) {
+ if (!page_has_prev(page) && !page_is_leaf(page)) {
first_rec = page_rec_get_next(
page_get_infimum_rec(buf_block_get_frame(block)));
}
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index 87ebd9ad34a..65c346d6d36 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -718,7 +718,7 @@ rtr_page_get_father_node_ptr(
ut_ad(dict_index_get_page(index) != page_no);
- level = btr_page_get_level(btr_cur_get_page(cursor), mtr);
+ level = btr_page_get_level(btr_cur_get_page(cursor));
user_rec = btr_cur_get_rec(cursor);
ut_a(page_rec_is_user_rec(user_rec));
@@ -773,8 +773,9 @@ rtr_page_get_father_node_ptr(
error << ". You should dump + drop + reimport the table to"
" fix the corruption. If the crash happens at"
- " database startup, see " REFMAN
- "forcing-innodb-recovery.html about forcing"
+ " database startup, see "
+ "https://mariadb.com/kb/en/library/xtradbinnodb-recovery-modes/"
+ " about forcing"
" recovery. Then dump + drop + reimport.";
}
@@ -1254,8 +1255,8 @@ rtr_check_discard_page(
mutex_exit(&index->rtr_track->rtr_active_mutex);
lock_mutex_enter();
- lock_prdt_page_free_from_discard(block, lock_sys->prdt_hash);
- lock_prdt_page_free_from_discard(block, lock_sys->prdt_page_hash);
+ lock_prdt_page_free_from_discard(block, lock_sys.prdt_hash);
+ lock_prdt_page_free_from_discard(block, lock_sys.prdt_page_hash);
lock_mutex_exit();
}
@@ -1679,7 +1680,7 @@ rtr_cur_search_with_match(
page = buf_block_get_frame(block);
- const ulint level = btr_page_get_level(page, mtr);
+ const ulint level = btr_page_get_level(page);
const bool is_leaf = !level;
if (mode == PAGE_CUR_RTREE_LOCATE) {
@@ -1715,7 +1716,7 @@ rtr_cur_search_with_match(
first page as much as possible, as there will be problem
when update MIN_REC rec in compress table */
if (buf_block_get_page_zip(block)
- && mach_read_from_4(page + FIL_PAGE_PREV) == FIL_NULL
+ && !page_has_prev(page)
&& page_get_n_recs(page) >= 2) {
rec = page_rec_get_next_const(rec);
diff --git a/storage/innobase/ha/ha0ha.cc b/storage/innobase/ha/ha0ha.cc
index f620db6f62e..da542d4f742 100644
--- a/storage/innobase/ha/ha0ha.cc
+++ b/storage/innobase/ha/ha0ha.cc
@@ -489,62 +489,4 @@ ha_validate(
return(ok);
}
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
-
-/*************************************************************//**
-Prints info of a hash table. */
-void
-ha_print_info(
-/*==========*/
- FILE* file, /*!< in: file where to print */
- hash_table_t* table) /*!< in: hash table */
-{
-#ifdef UNIV_DEBUG
-/* Some of the code here is disabled for performance reasons in production
-builds, see http://bugs.mysql.com/36941 */
-#define PRINT_USED_CELLS
-#endif /* UNIV_DEBUG */
-
-#ifdef PRINT_USED_CELLS
- hash_cell_t* cell;
- ulint cells = 0;
- ulint i;
-#endif /* PRINT_USED_CELLS */
- ulint n_bufs;
-
- ut_ad(table);
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
-#ifdef PRINT_USED_CELLS
- for (i = 0; i < hash_get_n_cells(table); i++) {
-
- cell = hash_get_nth_cell(table, i);
-
- if (cell->node) {
-
- cells++;
- }
- }
-#endif /* PRINT_USED_CELLS */
-
- fprintf(file, "Hash table size %lu",
- (ulong) hash_get_n_cells(table));
-
-#ifdef PRINT_USED_CELLS
- fprintf(file, ", used cells %lu", (ulong) cells);
-#endif /* PRINT_USED_CELLS */
-
- if (table->heaps == NULL && table->heap != NULL) {
-
- /* This calculation is intended for the adaptive hash
- index: how many buffer frames we have reserved? */
-
- n_bufs = UT_LIST_GET_LEN(table->heap->base) - 1;
-
- if (table->heap->free_block) {
- n_bufs++;
- }
-
- fprintf(file, ", node heap has %lu buffer(s)\n",
- (ulong) n_bufs);
- }
-}
#endif /* BTR_CUR_HASH_ADAPT */
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index ebbe32219c4..e14463ca909 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, MariaDB Corporation.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
@@ -111,10 +111,9 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "trx0purge.h"
#endif /* UNIV_DEBUG */
#include "trx0roll.h"
-#include "trx0sys.h"
+#include "trx0rseg.h"
#include "trx0trx.h"
#include "fil0pagecompress.h"
-#include "trx0xa.h"
#include "ut0mem.h"
#include "row0ext.h"
@@ -148,12 +147,9 @@ TABLE *get_purge_table(THD *thd);
#ifdef WITH_WSREP
#include "dict0priv.h"
-#include "../storage/innobase/include/ut0byte.h"
+#include "ut0byte.h"
#include <mysql/service_md5.h>
-class binlog_trx_data;
-extern handlerton *binlog_hton;
-
extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG mysql_bin_log;
static inline wsrep_ws_handle_t*
@@ -185,7 +181,7 @@ static mysql_mutex_t pending_checkpoint_mutex;
#define EQ_CURRENT_THD(thd) ((thd) == current_thd)
-static struct handlerton* innodb_hton_ptr;
+struct handlerton* innodb_hton_ptr;
static const long AUTOINC_OLD_STYLE_LOCKING = 0;
static const long AUTOINC_NEW_STYLE_LOCKING = 1;
@@ -319,7 +315,7 @@ thd_destructor_proxy(void *)
srv_running = NULL;
while (srv_fast_shutdown == 0 &&
- (trx_sys_any_active_transactions() ||
+ (trx_sys.any_active_transactions() ||
(uint)thread_count > srv_n_purge_threads + 1)) {
thd_proc_info(thd, "InnoDB slow shutdown wait");
os_thread_sleep(1000);
@@ -601,9 +597,6 @@ static PSI_mutex_info all_innodb_mutexes[] = {
PSI_KEY(srv_innodb_monitor_mutex),
PSI_KEY(srv_misc_tmpfile_mutex),
PSI_KEY(srv_monitor_file_mutex),
-# ifdef UNIV_DEBUG
- PSI_KEY(sync_thread_mutex),
-# endif /* UNIV_DEBUG */
PSI_KEY(buf_dblwr_mutex),
PSI_KEY(trx_undo_mutex),
PSI_KEY(trx_pool_mutex),
@@ -937,6 +930,8 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_buffer_pool_load_status, SHOW_CHAR},
{"buffer_pool_resize_status",
(char*) &export_vars.innodb_buffer_pool_resize_status, SHOW_CHAR},
+ {"buffer_pool_load_incomplete",
+ &export_vars.innodb_buffer_pool_load_incomplete, SHOW_BOOL},
{"buffer_pool_pages_data",
(char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG},
{"buffer_pool_bytes_data",
@@ -1048,10 +1043,6 @@ static SHOW_VAR innodb_status_variables[]= {
{"available_undo_logs",
(char*) &export_vars.innodb_available_undo_logs, SHOW_LONG},
#ifdef UNIV_DEBUG
- {"purge_trx_id_age",
- (char*) &export_vars.innodb_purge_trx_id_age, SHOW_LONG},
- {"purge_view_trx_id_age",
- (char*) &export_vars.innodb_purge_view_trx_id_age, SHOW_LONG},
{"ahi_drop_lookups",
(char*) &export_vars.innodb_ahi_drop_lookups, SHOW_LONG},
#endif /* UNIV_DEBUG */
@@ -1887,14 +1878,11 @@ thd_innodb_tmpdir(
}
/** Obtain the InnoDB transaction of a MySQL thread.
-@param[in,out] thd MySQL thread handler.
+@param[in,out] thd thread handle
@return reference to transaction pointer */
-MY_ATTRIBUTE((warn_unused_result))
-trx_t*&
-thd_to_trx(
- THD* thd)
+static trx_t* thd_to_trx(THD* thd)
{
- return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr));
+ return *reinterpret_cast<trx_t**>(thd_ha_data(thd, innodb_hton_ptr));
}
#ifdef WITH_WSREP
@@ -2089,7 +2077,7 @@ convert_error_code_to_mysql(
case DB_TOO_BIG_INDEX_COL:
my_error(ER_INDEX_COLUMN_TOO_LONG, MYF(0),
- DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags));
+ (ulong) DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags));
return(HA_ERR_INDEX_COL_TOO_LONG);
case DB_NO_SAVEPOINT:
@@ -2803,31 +2791,33 @@ check_trx_exists(
/*=============*/
THD* thd) /*!< in: user thread handle */
{
- trx_t*& trx = thd_to_trx(thd);
-
- if (trx == NULL) {
+ if (trx_t* trx = thd_to_trx(thd)) {
+ ut_a(trx->magic_n == TRX_MAGIC_N);
+ innobase_trx_init(thd, trx);
+ return trx;
+ } else {
trx = innobase_trx_allocate(thd);
/* User trx can be forced to rollback,
so we unset the disable flag. */
ut_ad(trx->in_innodb & TRX_FORCE_ROLLBACK_DISABLE);
trx->in_innodb &= TRX_FORCE_ROLLBACK_MASK;
- } else {
- ut_a(trx->magic_n == TRX_MAGIC_N);
- innobase_trx_init(thd, trx);
+ thd_set_ha_data(thd, innodb_hton_ptr, trx);
+ return trx;
}
-
- return(trx);
}
-/*************************************************************************
-Gets current trx. */
-trx_t*
-innobase_get_trx()
+/**
+ Gets current trx.
+
+ This function may be called during InnoDB initialisation, when
+ innodb_hton_ptr->slot is not yet set to meaningful value.
+*/
+
+trx_t *current_trx()
{
THD *thd=current_thd;
- if (likely(thd != 0)) {
- trx_t*& trx = thd_to_trx(thd);
- return(trx);
+ if (likely(thd != 0) && innodb_hton_ptr->slot != HA_SLOT_UNDEF) {
+ return thd_to_trx(thd);
} else {
return(NULL);
}
@@ -2999,7 +2989,6 @@ ha_innobase::ha_innobase(
| (srv_force_primary_key ? HA_REQUIRE_PRIMARY_KEY : 0)
),
m_start_of_scan(),
- m_num_write_row(),
m_mysql_has_locked()
{}
@@ -3156,9 +3145,9 @@ read view to it if there is no read view yet.
Why a deadlock of threads is not possible: the query cache calls this function
at the start of a SELECT processing. Then the calling thread cannot be
holding any InnoDB semaphores. The calling thread is holding the
-query cache mutex, and this function will reserve the InnoDB trx_sys->mutex.
+query cache mutex, and this function will reserve the InnoDB trx_sys.mutex.
Thus, the 'rank' in sync0mutex.h of the MySQL query cache mutex is above
-the InnoDB trx_sys->mutex.
+the InnoDB trx_sys.mutex.
@return TRUE if permitted, FALSE if not; note that the value FALSE
does not mean we should invalidate the query cache: invalidation is
called explicitly */
@@ -3264,7 +3253,7 @@ innobase_invalidate_query_cache(
/* Argument TRUE below means we are using transactions */
mysql_query_cache_invalidate4(trx->mysql_thd,
qcache_key_name,
- (dbname_len + tabname_len + 2),
+ uint(dbname_len + tabname_len + 2),
TRUE);
#endif
}
@@ -3503,7 +3492,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
/* Assign a read view if the transaction does not have it yet */
- trx_assign_read_view(m_prebuilt->trx);
+ m_prebuilt->trx->read_view.open(m_prebuilt->trx);
innobase_register_trx(ht, m_user_thd, m_prebuilt->trx);
@@ -3623,6 +3612,34 @@ static const char* ha_innobase_exts[] = {
NullS
};
+/** Determine if system-versioned data was modified by the transaction.
+@param[in,out] thd current session
+@param[out] trx_id transaction start ID
+@return transaction commit ID
+@retval 0 if no system-versioned data was affected by the transaction */
+static ulonglong innodb_prepare_commit_versioned(THD* thd, ulonglong *trx_id)
+{
+ if (const trx_t* trx = thd_to_trx(thd)) {
+ *trx_id = trx->id;
+
+ for (trx_mod_tables_t::const_iterator t
+ = trx->mod_tables.begin();
+ t != trx->mod_tables.end(); t++) {
+ if (t->second.is_versioned()) {
+ DBUG_ASSERT(t->first->versioned_by_id());
+ DBUG_ASSERT(trx->rsegs.m_redo.rseg);
+
+ return trx_sys.get_new_trx_id();
+ }
+ }
+
+ return 0;
+ }
+
+ *trx_id = 0;
+ return 0;
+}
+
/*********************************************************************//**
Opens an InnoDB database.
@return 0 on success, 1 on failure */
@@ -3675,7 +3692,7 @@ innobase_init(
innobase_hton->flush_logs = innobase_flush_logs;
innobase_hton->show_status = innobase_show_status;
innobase_hton->flags =
- HTON_SUPPORTS_EXTENDED_KEYS | HTON_SUPPORTS_FOREIGN_KEYS;
+ HTON_SUPPORTS_EXTENDED_KEYS | HTON_SUPPORTS_FOREIGN_KEYS | HTON_NATIVE_SYS_VERSIONING;
#ifdef WITH_WSREP
innobase_hton->abort_transaction=wsrep_abort_transaction;
@@ -3690,6 +3707,10 @@ innobase_init(
innobase_hton->table_options = innodb_table_option_list;
+ /* System Versioning */
+ innobase_hton->prepare_commit_versioned
+ = innodb_prepare_commit_versioned;
+
innodb_remember_check_sysvar_funcs();
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
@@ -3742,6 +3763,15 @@ innobase_init(
goto error;
}
+#ifdef WITH_WSREP
+ /* Currently, Galera does not support VATS lock schedule algorithm. */
+ if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
+ && global_system_variables.wsrep_on) {
+ ib::info() << "For Galera, using innodb_lock_schedule_algorithm=fcfs";
+ innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS;
+ }
+#endif /* WITH_WSREP */
+
#ifndef HAVE_LZ4
if (innodb_compression_algorithm == PAGE_LZ4_ALGORITHM) {
sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
@@ -4349,7 +4379,7 @@ innobase_start_trx_and_assign_read_view(
thd_get_trx_isolation(thd));
if (trx->isolation_level == TRX_ISO_REPEATABLE_READ) {
- trx_assign_read_view(trx);
+ trx->read_view.open(trx);
} else {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
HA_ERR_UNSUPPORTED,
@@ -5060,7 +5090,6 @@ innobase_close_connection(
"MariaDB is closing a connection that has an active "
"InnoDB transaction. " TRX_ID_FMT " row modifications "
"will roll back.",
- " row modifications will roll back.",
trx->undo_no);
ut_d(ib::warn()
<< "trx: " << trx << " started on: "
@@ -5133,7 +5162,7 @@ innobase_kill_query(
wsrep_thd_is_BF(current_thd, FALSE));
}
- if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && trx->abort_type != TRX_WSREP_ABORT) {
lock_mutex_enter();
lock_mutex_taken = true;
}
@@ -5993,7 +6022,7 @@ innobase_build_index_translation(
if (index_mapping[count] == 0) {
sql_print_error("Cannot find index %s in InnoDB"
" index dictionary.",
- table->key_info[count].name);
+ table->key_info[count].name.str);
ret = false;
goto func_exit;
}
@@ -6004,7 +6033,7 @@ innobase_build_index_translation(
index_mapping[count])) {
sql_print_error("Found index %s whose column info"
" does not match that of MariaDB.",
- table->key_info[count].name);
+ table->key_info[count].name.str);
ret = false;
goto func_exit;
}
@@ -6218,8 +6247,8 @@ no_such_table:
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
}
- uint n_fields = mysql_fields(table);
- uint n_cols = dict_table_get_n_user_cols(ib_table)
+ size_t n_fields = mysql_fields(table);
+ size_t n_cols = dict_table_get_n_user_cols(ib_table)
+ dict_table_get_n_v_cols(ib_table)
- !!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID);
@@ -6496,7 +6525,11 @@ no_such_table:
}
}
- info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
+ if (table && m_prebuilt->table) {
+ ut_ad(table->versioned() == m_prebuilt->table->versioned());
+ }
+
+ info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_OPEN);
DBUG_RETURN(0);
}
@@ -7717,6 +7750,7 @@ ha_innobase::build_template(
index = whole_row ? clust_index : m_prebuilt->index;
+ m_prebuilt->versioned_write = table->versioned_write(VERS_TRX_ID);
m_prebuilt->need_to_access_clustered = (index == clust_index);
/* Either m_prebuilt->index should be a secondary index, or it
@@ -8131,7 +8165,6 @@ ha_innobase::write_row(
#ifdef WITH_WSREP
ibool auto_inc_inserted= FALSE; /* if NULL was inserted */
#endif
- ulint sql_command;
int error_result = 0;
bool auto_inc_used = false;
@@ -8139,6 +8172,7 @@ ha_innobase::write_row(
trx_t* trx = thd_to_trx(m_user_thd);
TrxInInnoDB trx_in_innodb(trx);
+ ins_mode_t vers_set_fields;
if (trx_in_innodb.is_aborted()) {
@@ -8148,7 +8182,7 @@ ha_innobase::write_row(
DB_FORCED_ABORT, 0, m_user_thd));
}
- /* Step-1: Validation checks before we commence write_row operation. */
+ /* Validation checks before we commence write_row operation. */
if (high_level_read_only) {
ib_senderrf(ha_thd(), IB_LOG_LEVEL_WARN, ER_READ_ONLY_MODE);
DBUG_RETURN(HA_ERR_TABLE_READONLY);
@@ -8169,131 +8203,7 @@ ha_innobase::write_row(
++trx->will_lock;
}
- /* Step-2: Intermediate commit if original operation involves ALTER
- table with algorithm = copy. Intermediate commit ease pressure on
- recovery if server crashes while ALTER is active. */
- sql_command = thd_sql_command(m_user_thd);
-
- if ((sql_command == SQLCOM_ALTER_TABLE
- || sql_command == SQLCOM_OPTIMIZE
- || sql_command == SQLCOM_CREATE_INDEX
-#ifdef WITH_WSREP
- || (sql_command == SQLCOM_LOAD
- && wsrep_load_data_splitting && wsrep_on(m_user_thd)
- && !thd_test_options(
- m_user_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
-#endif /* WITH_WSREP */
- || sql_command == SQLCOM_DROP_INDEX)
- && m_num_write_row >= 10000) {
-#ifdef WITH_WSREP
- if (sql_command == SQLCOM_LOAD && wsrep_on(m_user_thd)) {
- WSREP_DEBUG("forced trx split for LOAD: %s",
- wsrep_thd_query(m_user_thd));
- }
-#endif /* WITH_WSREP */
- /* ALTER TABLE is COMMITted at every 10000 copied rows.
- The IX table lock for the original table has to be re-issued.
- As this method will be called on a temporary table where the
- contents of the original table is being copied to, it is
- a bit tricky to determine the source table. The cursor
- position in the source table need not be adjusted after the
- intermediate COMMIT, since writes by other transactions are
- being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
-
- dict_table_t* src_table;
- enum lock_mode mode;
-
- m_num_write_row = 0;
-
- /* Commit the transaction. This will release the table
- locks, so they have to be acquired again. */
-
- /* Altering an InnoDB table */
- /* Get the source table. */
- src_table = lock_get_src_table(
- m_prebuilt->trx, m_prebuilt->table, &mode);
- if (!src_table) {
-no_commit:
- /* Unknown situation: do not commit */
- ;
- } else if (src_table == m_prebuilt->table) {
-#ifdef WITH_WSREP
- if (wsrep_on(m_user_thd) &&
- wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
- !thd_test_options(m_user_thd,
- OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
- {
- switch (wsrep_run_wsrep_commit(m_user_thd, 1)) {
- case WSREP_TRX_OK:
- break;
- case WSREP_TRX_SIZE_EXCEEDED:
- case WSREP_TRX_CERT_FAIL:
- case WSREP_TRX_ERROR:
- DBUG_RETURN(1);
- }
-
- if (binlog_hton->commit(binlog_hton, m_user_thd, 1)) {
- DBUG_RETURN(1);
- }
- wsrep_post_commit(m_user_thd, TRUE);
- }
-#endif /* WITH_WSREP */
- /* Source table is not in InnoDB format:
- no need to re-acquire locks on it. */
-
- /* Altering to InnoDB format */
- innobase_commit(ht, m_user_thd, 1);
- /* Note that this transaction is still active. */
- trx_register_for_2pc(m_prebuilt->trx);
- /* We will need an IX lock on the destination table. */
- m_prebuilt->sql_stat_start = TRUE;
- } else {
-#ifdef WITH_WSREP
- if (wsrep_on(m_user_thd) &&
- wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
- !thd_test_options(m_user_thd,
- OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
- switch (wsrep_run_wsrep_commit(m_user_thd, 1)) {
- case WSREP_TRX_OK:
- break;
- case WSREP_TRX_SIZE_EXCEEDED:
- case WSREP_TRX_CERT_FAIL:
- case WSREP_TRX_ERROR:
- DBUG_RETURN(1);
- }
-
- if (binlog_hton->commit(binlog_hton, m_user_thd, 1)) {
- DBUG_RETURN(1);
- }
-
- wsrep_post_commit(m_user_thd, TRUE);
- }
-#endif /* WITH_WSREP */
- /* Ensure that there are no other table locks than
- LOCK_IX and LOCK_AUTO_INC on the destination table. */
-
- if (!lock_is_table_exclusive(m_prebuilt->table,
- m_prebuilt->trx)) {
- goto no_commit;
- }
-
- /* Commit the transaction. This will release the table
- locks, so they have to be acquired again. */
- innobase_commit(ht, m_user_thd, 1);
- /* Note that this transaction is still active. */
- trx_register_for_2pc(m_prebuilt->trx);
- /* Re-acquire the table lock on the source table. */
- row_lock_table_for_mysql(m_prebuilt, src_table, mode);
- /* We will need an IX lock on the destination table. */
- m_prebuilt->sql_stat_start = TRUE;
- }
- }
-
- m_num_write_row++;
-
- /* Step-3: Handling of Auto-Increment Columns. */
+ /* Handling of Auto-Increment Columns. */
if (table->next_number_field && record == table->record[0]) {
/* Reset the error code before calling
@@ -8326,7 +8236,7 @@ no_commit:
auto_inc_used = true;
}
- /* Step-4: Prepare INSERT graph that will be executed for actual INSERT
+ /* Prepare INSERT graph that will be executed for actual INSERT
(This is a one time operation) */
if (m_prebuilt->mysql_template == NULL
|| m_prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) {
@@ -8339,12 +8249,15 @@ no_commit:
innobase_srv_conc_enter_innodb(m_prebuilt);
- /* Step-5: Execute insert graph that will result in actual insert. */
- error = row_insert_for_mysql((byte*) record, m_prebuilt);
+ vers_set_fields = table->versioned_write(VERS_TRX_ID) ?
+ ROW_INS_VERSIONED : ROW_INS_NORMAL;
+
+ /* Execute insert graph that will result in actual insert. */
+ error = row_insert_for_mysql((byte*) record, m_prebuilt, vers_set_fields);
DEBUG_SYNC(m_user_thd, "ib_after_row_insert");
- /* Step-6: Handling of errors related to auto-increment. */
+ /* Handling of errors related to auto-increment. */
if (auto_inc_used) {
ulonglong auto_inc;
ulonglong col_max_value;
@@ -8361,8 +8274,8 @@ no_commit:
whether we update the table autoinc counter or not. */
col_max_value = innobase_get_int_col_max_value(table->next_number_field);
- /* Get the value that MySQL attempted to store in the table. */
- auto_inc = table->next_number_field->val_int();
+ /* Get the value that MySQL attempted to store in the table.*/
+ auto_inc = table->next_number_field->val_uint();
switch (error) {
case DB_DUPLICATE_KEY:
@@ -8372,13 +8285,11 @@ no_commit:
must update the autoinc counter if we are performing
those statements. */
- switch (sql_command) {
+ switch (thd_sql_command(m_user_thd)) {
case SQLCOM_LOAD:
- if (trx->duplicates) {
-
- goto set_max_autoinc;
+ if (!trx->duplicates) {
+ break;
}
- break;
case SQLCOM_REPLACE:
case SQLCOM_INSERT_SELECT:
@@ -8467,7 +8378,7 @@ set_max_autoinc:
innobase_srv_conc_exit_innodb(m_prebuilt);
report_error:
- /* Step-7: Cleanup and exit. */
+ /* Cleanup and exit. */
if (error == DB_TABLESPACE_DELETED) {
ib_senderrf(
trx->mysql_thd, IB_LOG_LEVEL_ERROR,
@@ -8828,12 +8739,7 @@ calc_row_difference(
if (field != table->found_next_number_field
|| dfield_is_null(&ufield->new_val)) {
} else {
- auto_inc = row_parse_int(
- static_cast<const byte*>(
- ufield->new_val.data),
- ufield->new_val.len,
- col->mtype,
- col->prtype & DATA_UNSIGNED);
+ auto_inc = field->val_uint();
}
}
n_changed++;
@@ -9118,12 +9024,34 @@ ha_innobase::update_row(
DB_FORCED_ABORT, 0, m_user_thd));
}
- /* This is not a delete */
- m_prebuilt->upd_node->is_delete = FALSE;
+ {
+ const bool vers_set_fields = m_prebuilt->versioned_write
+ && m_prebuilt->upd_node->update->affects_versioned();
+ const bool vers_ins_row = vers_set_fields
+ && (table->s->vtmd
+ || thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE);
+
+ /* This is not a delete */
+ m_prebuilt->upd_node->is_delete =
+ (vers_set_fields && !vers_ins_row) ||
+ (thd_sql_command(m_user_thd) == SQLCOM_DELETE &&
+ table->versioned(VERS_TIMESTAMP))
+ ? VERSIONED_DELETE
+ : NO_DELETE;
- innobase_srv_conc_enter_innodb(m_prebuilt);
+ innobase_srv_conc_enter_innodb(m_prebuilt);
- error = row_update_for_mysql(m_prebuilt);
+ error = row_update_for_mysql(m_prebuilt);
+
+ if (error == DB_SUCCESS && vers_ins_row
+ /* Multiple UPDATE of same rows in single transaction create
+ historical rows only once. */
+ && trx->id != table->vers_start_id()) {
+ error = row_insert_for_mysql((byte*) old_row,
+ m_prebuilt,
+ ROW_INS_HISTORICAL);
+ }
+ }
if (error == DB_SUCCESS && autoinc) {
/* A value for an AUTO_INCREMENT column
@@ -9233,8 +9161,10 @@ ha_innobase::delete_row(
}
/* This is a delete */
-
- m_prebuilt->upd_node->is_delete = TRUE;
+ m_prebuilt->upd_node->is_delete = table->versioned_write(VERS_TRX_ID)
+ && table->vers_end_field()->is_max()
+ ? VERSIONED_DELETE
+ : PLAIN_DELETE;
innobase_srv_conc_enter_innodb(m_prebuilt);
@@ -10161,7 +10091,7 @@ ha_innobase::rnd_pos(
/* Note that we assume the length of the row reference is fixed
for the table, and it is == ref_length */
- int error = index_read(buf, pos, ref_length, HA_READ_KEY_EXACT);
+ int error = index_read(buf, pos, (uint)ref_length, HA_READ_KEY_EXACT);
if (error != 0) {
DBUG_PRINT("error", ("Got error: %d", error));
@@ -11328,6 +11258,18 @@ create_table_info_t::create_table_def()
bool is_stored = false;
Field* field = m_form->field[i];
+ ulint vers_row = 0;
+
+ if (m_form->versioned()) {
+ if (i == m_form->s->row_start_field) {
+ vers_row = DATA_VERS_START;
+ } else if (i == m_form->s->row_end_field) {
+ vers_row = DATA_VERS_END;
+ } else if (!(field->flags
+ & VERS_UPDATE_UNVERSIONED_FLAG)) {
+ vers_row = DATA_VERSIONED;
+ }
+ }
col_type = get_innobase_type_from_mysql_type(
&unsigned_type, field);
@@ -11418,7 +11360,8 @@ err_col:
dtype_form_prtype(
(ulint) field->type()
| nulls_allowed | unsigned_type
- | binary_type | long_true_varchar,
+ | binary_type | long_true_varchar
+ | vers_row,
charset_no),
col_len);
} else {
@@ -11428,6 +11371,7 @@ err_col:
(ulint) field->type()
| nulls_allowed | unsigned_type
| binary_type | long_true_varchar
+ | vers_row
| is_virtual,
charset_no),
col_len, i, 0);
@@ -11870,7 +11814,7 @@ create_table_info_t::create_options_are_invalid()
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: invalid KEY_BLOCK_SIZE = %u."
" Valid values are [1, 2, 4, 8, 16]",
- m_create_info->key_block_size);
+ (uint) m_create_info->key_block_size);
ret = "KEY_BLOCK_SIZE";
break;
}
@@ -12319,7 +12263,7 @@ index_bad:
m_thd, Sql_condition::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ignoring KEY_BLOCK_SIZE=%u.",
- m_create_info->key_block_size);
+ (uint) m_create_info->key_block_size);
}
}
@@ -12342,7 +12286,7 @@ index_bad:
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ignoring KEY_BLOCK_SIZE=%u"
" unless ROW_FORMAT=COMPRESSED.",
- m_create_info->key_block_size);
+ (uint) m_create_info->key_block_size);
zip_allowed = false;
}
} else {
@@ -13262,18 +13206,26 @@ ha_innobase::truncate()
TrxInInnoDB trx_in_innodb(m_prebuilt->trx);
- if (!trx_is_started(m_prebuilt->trx)) {
- ++m_prebuilt->trx->will_lock;
- }
-
- dberr_t err;
-
- /* Truncate the table in InnoDB */
- err = row_truncate_table_for_mysql(m_prebuilt->table, m_prebuilt->trx);
+ m_prebuilt->trx->ddl = true;
+ trx_start_if_not_started(m_prebuilt->trx, true);
- int error;
+ dberr_t err = row_mysql_lock_table(m_prebuilt->trx, m_prebuilt->table,
+ LOCK_X, "truncate table");
+ if (err == DB_SUCCESS) {
+ err = row_truncate_table_for_mysql(m_prebuilt->table,
+ m_prebuilt->trx);
+ }
switch (err) {
+ case DB_FORCED_ABORT:
+ case DB_DEADLOCK:
+ thd_mark_transaction_to_rollback(m_user_thd, 1);
+ DBUG_RETURN(HA_ERR_LOCK_DEADLOCK);
+ case DB_LOCK_TABLE_FULL:
+ thd_mark_transaction_to_rollback(m_user_thd, 1);
+ DBUG_RETURN(HA_ERR_LOCK_TABLE_FULL);
+ case DB_LOCK_WAIT_TIMEOUT:
+ DBUG_RETURN(HA_ERR_LOCK_WAIT_TIMEOUT);
case DB_TABLESPACE_DELETED:
case DB_TABLESPACE_NOT_FOUND:
ib_senderrf(
@@ -13282,19 +13234,13 @@ ha_innobase::truncate()
ER_TABLESPACE_DISCARDED : ER_TABLESPACE_MISSING),
table->s->table_name.str);
table->status = STATUS_NOT_FOUND;
- error = HA_ERR_TABLESPACE_MISSING;
- break;
-
+ DBUG_RETURN(HA_ERR_TABLESPACE_MISSING);
default:
- error = convert_error_code_to_mysql(
- err, m_prebuilt->table->flags,
- m_prebuilt->trx->mysql_thd);
-
table->status = STATUS_NOT_FOUND;
- break;
+ DBUG_RETURN(convert_error_code_to_mysql(
+ err, m_prebuilt->table->flags,
+ m_user_thd));
}
-
- DBUG_RETURN(error);
}
/*****************************************************************//**
@@ -13350,7 +13296,7 @@ ha_innobase::delete_table(
iter != parent_trx->mod_tables.end();
++iter) {
- dict_table_t* table_to_drop = *iter;
+ dict_table_t* table_to_drop = iter->first;
if (strcmp(norm_name, table_to_drop->name.m_name) == 0) {
parent_trx->mod_tables.erase(table_to_drop);
@@ -13584,39 +13530,15 @@ innobase_rename_table(
TrxInInnoDB trx_in_innodb(trx);
trx_start_if_not_started(trx, true);
+ ut_ad(trx->will_lock > 0);
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations. */
row_mysql_lock_data_dictionary(trx);
- /* Transaction must be flagged as a locking transaction or it hasn't
- been started yet. */
-
- ut_a(trx->will_lock > 0);
-
error = row_rename_table_for_mysql(norm_from, norm_to, trx, TRUE);
- if (error == DB_TABLE_NOT_FOUND) {
- /* May be partitioned table, which consists of partitions
- named table_name#P#partition_name[#SP#subpartition_name].
-
- We are doing a DDL operation. */
- ++trx->will_lock;
- trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
- trx_start_if_not_started(trx, true);
- error = row_rename_partitions_for_mysql(norm_from, norm_to,
- trx);
- if (error == DB_TABLE_NOT_FOUND) {
- ib::error() << "Table " << ut_get_name(trx, norm_from)
- << " does not exist in the InnoDB internal"
- " data dictionary though MariaDB is trying to"
- " rename the table. Have you copied the .frm"
- " file of the table to the MariaDB database"
- " directory from another database? "
- << TROUBLESHOOTING_MSG;
- }
- }
if (error != DB_SUCCESS) {
if (error == DB_TABLE_NOT_FOUND
&& innobase_get_lower_case_table_names() == 1) {
@@ -13875,7 +13797,8 @@ ha_innobase::records_in_range(
push_warning_printf(
ha_thd(), Sql_condition::WARN_LEVEL_WARN,
ER_NO_DEFAULT,
- "btr_estimate_n_rows_in_range(): %f", n_rows);
+ "btr_estimate_n_rows_in_range(): %lld",
+ (longlong) n_rows);
);
func_exit:
@@ -14319,7 +14242,7 @@ ha_innobase::info_low(
set. That way SHOW TABLE STATUS will show the best estimate,
while the optimizer never sees the table empty. */
- if (n_rows == 0 && !(flag & HA_STATUS_TIME)) {
+ if (n_rows == 0 && !(flag & (HA_STATUS_TIME | HA_STATUS_OPEN))) {
n_rows++;
}
@@ -14402,7 +14325,7 @@ ha_innobase::info_low(
}
stats.check_time = 0;
- stats.mrr_length_per_rec= ref_length + 8; // 8 = max(sizeof(void *));
+ stats.mrr_length_per_rec= (uint)ref_length + 8; // 8 = max(sizeof(void *));
if (stats.records == 0) {
stats.mean_rec_length = 0;
@@ -14547,9 +14470,9 @@ ha_innobase::info_low(
dict_table_stats_unlock(ib_table, RW_S_LATCH);
}
- my_snprintf(path, sizeof(path), "%s/%s%s",
- mysql_data_home, table->s->normalized_path.str,
- reg_ext);
+ snprintf(path, sizeof(path), "%s/%s%s",
+ mysql_data_home, table->s->normalized_path.str,
+ reg_ext);
unpack_filename(path,path);
@@ -14712,7 +14635,7 @@ ha_innobase::defragment_table(
"Table %s is encrypted but encryption service or"
" used key_id is not available. "
" Can't continue checking table.",
- index->table->name);
+ index->table->name.m_name);
ret = convert_error_code_to_mysql(err, 0, current_thd);
break;
@@ -14908,7 +14831,7 @@ ha_innobase::check(
&& !dict_index_is_corrupted(index)) {
/* Enlarge the fatal lock wait timeout during
CHECK TABLE. */
- my_atomic_addlint(
+ my_atomic_addlong(
&srv_fatal_semaphore_wait_threshold,
SRV_SEMAPHORE_WAIT_EXTENSION);
@@ -14917,7 +14840,7 @@ ha_innobase::check(
/* Restore the fatal lock wait timeout after
CHECK TABLE. */
- my_atomic_addlint(
+ my_atomic_addlong(
&srv_fatal_semaphore_wait_threshold,
-SRV_SEMAPHORE_WAIT_EXTENSION);
@@ -14932,7 +14855,7 @@ ha_innobase::check(
"Table %s is encrypted but encryption service or"
" used key_id is not available. "
" Can't continue checking table.",
- index->table->name);
+ index->table->name.m_name);
} else {
push_warning_printf(
thd,
@@ -15671,6 +15594,26 @@ ha_innobase::extra(
case HA_EXTRA_WRITE_CANNOT_REPLACE:
thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_REPLACE;
break;
+ case HA_EXTRA_BEGIN_ALTER_COPY:
+ m_prebuilt->table->skip_alter_undo = 1;
+ if (m_prebuilt->table->is_temporary()
+ || !m_prebuilt->table->versioned_by_id()) {
+ break;
+ }
+ trx_start_if_not_started(m_prebuilt->trx, true);
+ m_prebuilt->trx->mod_tables.insert(
+ trx_mod_tables_t::value_type(
+ const_cast<dict_table_t*>(m_prebuilt->table),
+ 0))
+ .first->second.set_versioned(0);
+ break;
+ case HA_EXTRA_END_ALTER_COPY:
+ m_prebuilt->table->skip_alter_undo = 0;
+ break;
+ case HA_EXTRA_FAKE_START_STMT:
+ trx_register_for_2pc(m_prebuilt->trx);
+ m_prebuilt->sql_stat_start = true;
+ break;
default:/* Do nothing */
;
}
@@ -15773,7 +15716,7 @@ ha_innobase::start_stmt(
init_table_handle_for_HANDLER();
m_prebuilt->select_lock_type = LOCK_X;
m_prebuilt->stored_select_lock_type = LOCK_X;
- error = row_lock_table_for_mysql(m_prebuilt, NULL, 1);
+ error = row_lock_table(m_prebuilt);
if (error != DB_SUCCESS) {
int st = convert_error_code_to_mysql(
@@ -16037,8 +15980,7 @@ ha_innobase::external_lock(
&& thd_test_options(thd, OPTION_NOT_AUTOCOMMIT)
&& thd_in_lock_tables(thd)) {
- dberr_t error = row_lock_table_for_mysql(
- m_prebuilt, NULL, 0);
+ dberr_t error = row_lock_table(m_prebuilt);
if (error != DB_SUCCESS) {
@@ -16094,14 +16036,8 @@ ha_innobase::external_lock(
innobase_commit(ht, thd, TRUE);
}
- } else if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
- && MVCC::is_view_active(trx->read_view)) {
-
- mutex_enter(&trx_sys->mutex);
-
- trx_sys->mvcc->view_close(trx->read_view, true);
-
- mutex_exit(&trx_sys->mutex);
+ } else if (trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
+ trx->read_view.close();
}
}
@@ -16400,13 +16336,13 @@ ShowStatus::to_string(
int name_len;
char name_buf[IO_SIZE];
- name_len = ut_snprintf(
+ name_len = snprintf(
name_buf, sizeof(name_buf), "%s", it->m_name.c_str());
int status_len;
char status_buf[IO_SIZE];
- status_len = ut_snprintf(
+ status_len = snprintf(
status_buf, sizeof(status_buf),
"spins=%lu,waits=%lu,calls=%llu",
static_cast<ulong>(it->m_spins),
@@ -16443,7 +16379,7 @@ innodb_show_mutex_status(
DBUG_ASSERT(hton == innodb_hton_ptr);
- mutex_monitor->iterate(collector);
+ mutex_monitor.iterate(collector);
if (!collector.to_string(hton, thd, stat_print)) {
DBUG_RETURN(1);
@@ -16493,7 +16429,7 @@ innodb_show_rwlock_status(
continue;
}
- buf1len = ut_snprintf(
+ buf1len = snprintf(
buf1, sizeof buf1, "rwlock: %s:%u",
innobase_basename(rw_lock->cfile_name),
rw_lock->cline);
@@ -16501,7 +16437,7 @@ innodb_show_rwlock_status(
int buf2len;
char buf2[IO_SIZE];
- buf2len = ut_snprintf(
+ buf2len = snprintf(
buf2, sizeof buf2, "waits=%u",
rw_lock->count_os_wait);
@@ -16521,7 +16457,7 @@ innodb_show_rwlock_status(
int buf1len;
char buf1[IO_SIZE];
- buf1len = ut_snprintf(
+ buf1len = snprintf(
buf1, sizeof buf1, "sum rwlock: %s:%u",
innobase_basename(block_rwlock->cfile_name),
block_rwlock->cline);
@@ -16529,7 +16465,7 @@ innodb_show_rwlock_status(
int buf2len;
char buf2[IO_SIZE];
- buf2len = ut_snprintf(
+ buf2len = snprintf(
buf2, sizeof buf2, "waits=" ULINTPF,
block_rwlock_oswait_count);
@@ -16762,17 +16698,11 @@ ha_innobase::store_lock(
trx->isolation_level = innobase_map_isolation_level(
(enum_tx_isolation) thd_tx_isolation(thd));
- if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
- && MVCC::is_view_active(trx->read_view)) {
+ if (trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
/* At low transaction isolation levels we let
each consistent read set its own snapshot */
-
- mutex_enter(&trx_sys->mutex);
-
- trx_sys->mvcc->view_close(trx->read_view, true);
-
- mutex_exit(&trx_sys->mutex);
+ trx->read_view.close();
}
}
@@ -17282,7 +17212,7 @@ ha_innobase::get_foreign_dup_key(
child_table_name[len] = '\0';
/* copy index name */
- ut_snprintf(child_key_name, child_key_name_len, "%s",
+ snprintf(child_key_name, child_key_name_len, "%s",
err_index->name());
return(true);
@@ -17589,12 +17519,14 @@ innobase_commit_by_xid(
}
if (trx_t* trx = trx_get_trx_by_xid(xid)) {
- TrxInInnoDB trx_in_innodb(trx);
-
- innobase_commit_low(trx);
- ut_ad(trx->mysql_thd == NULL);
+ ut_ad(trx->in_innodb & TRX_FORCE_ROLLBACK_DISABLE);
/* use cases are: disconnected xa, slave xa, recovery */
- trx_deregister_from_2pc(trx);
+ {
+ TrxInInnoDB trx_in_innodb(trx);
+ innobase_commit_low(trx);
+ ut_ad(trx->mysql_thd == NULL);
+ trx_deregister_from_2pc(trx);
+ }
ut_ad(!trx->will_lock); /* trx cache requirement */
trx_free_for_background(trx);
@@ -17623,12 +17555,14 @@ innobase_rollback_by_xid(
}
if (trx_t* trx = trx_get_trx_by_xid(xid)) {
- TrxInInnoDB trx_in_innodb(trx);
-
- int ret = innobase_rollback_trx(trx);
-
- trx_deregister_from_2pc(trx);
- ut_ad(!trx->will_lock);
+ int ret;
+ ut_ad(trx->in_innodb & TRX_FORCE_ROLLBACK_DISABLE);
+ {
+ TrxInInnoDB trx_in_innodb(trx);
+ ret = innobase_rollback_trx(trx);
+ trx_deregister_from_2pc(trx);
+ ut_ad(!trx->will_lock);
+ }
trx_free_for_background(trx);
return(ret);
@@ -17909,7 +17843,7 @@ innodb_buffer_pool_size_update(
{
longlong in_val = *static_cast<const longlong*>(save);
- ut_snprintf(export_vars.innodb_buffer_pool_resize_status,
+ snprintf(export_vars.innodb_buffer_pool_resize_status,
sizeof(export_vars.innodb_buffer_pool_resize_status),
"Requested to resize buffer pool.");
@@ -18140,7 +18074,7 @@ innodb_make_page_dirty(
return;
}
- if (srv_saved_page_number_debug > space->size) {
+ if (srv_saved_page_number_debug >= space->size) {
fil_space_release(space);
return;
}
@@ -18334,7 +18268,7 @@ innodb_monitor_set_option(
if (MONITOR_IS_ON(MONITOR_LATCHES)) {
- mutex_monitor->enable();
+ mutex_monitor.enable();
}
break;
@@ -18349,7 +18283,7 @@ innodb_monitor_set_option(
if (!MONITOR_IS_ON(MONITOR_LATCHES)) {
- mutex_monitor->disable();
+ mutex_monitor.disable();
}
break;
@@ -18358,13 +18292,13 @@ innodb_monitor_set_option(
if (monitor_id == (MONITOR_LATCHES)) {
- mutex_monitor->reset();
+ mutex_monitor.reset();
}
break;
case MONITOR_RESET_ALL_VALUE:
srv_mon_reset_all(monitor_id);
- mutex_monitor->reset();
+ mutex_monitor.reset();
break;
default:
@@ -19745,17 +19679,14 @@ innobase_wsrep_set_checkpoint(
{
DBUG_ASSERT(hton == innodb_hton_ptr);
- if (wsrep_is_wsrep_xid(xid)) {
- mtr_t mtr;
- mtr_start(&mtr);
- trx_sysf_t* sys_header = trx_sysf_get(&mtr);
- trx_sys_update_wsrep_checkpoint(xid, sys_header, &mtr);
- mtr_commit(&mtr);
- innobase_flush_logs(hton, false);
- return 0;
- } else {
- return 1;
- }
+ if (wsrep_is_wsrep_xid(xid)) {
+
+ trx_rseg_update_wsrep_checkpoint(xid);
+ innobase_flush_logs(hton, false);
+ return 0;
+ } else {
+ return 1;
+ }
}
static
@@ -19766,7 +19697,7 @@ innobase_wsrep_get_checkpoint(
XID* xid)
{
DBUG_ASSERT(hton == innodb_hton_ptr);
- trx_sys_read_wsrep_checkpoint(xid);
+ trx_rseg_read_wsrep_checkpoint(*xid);
return 0;
}
@@ -19777,9 +19708,7 @@ wsrep_fake_trx_id(
handlerton *hton,
THD *thd) /*!< in: user thread handle */
{
- mutex_enter(&trx_sys->mutex);
- trx_id_t trx_id = trx_sys_get_new_trx_id();
- mutex_exit(&trx_sys->mutex);
+ trx_id_t trx_id = trx_sys.get_new_trx_id();
WSREP_DEBUG("innodb fake trx id: " TRX_ID_FMT " thd: %s",
trx_id, wsrep_thd_query(thd));
wsrep_ws_handle_for_trx(wsrep_thd_ws_handle(thd), trx_id);
@@ -20193,7 +20122,7 @@ static MYSQL_SYSVAR_ULONG(doublewrite_batch_size, srv_doublewrite_batch_size,
#endif /* defined UNIV_DEBUG || defined UNIV_PERF_DEBUG */
static MYSQL_SYSVAR_ENUM(lock_schedule_algorithm, innodb_lock_schedule_algorithm,
- PLUGIN_VAR_RQCMDARG,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The algorithm Innodb uses for deciding which locks to grant next when"
" a lock is released. Possible values are"
" FCFS"
@@ -20230,6 +20159,12 @@ static MYSQL_SYSVAR_ULONG(buffer_pool_dump_pct, srv_buf_pool_dump_pct,
NULL, NULL, 25, 1, 100, 0);
#ifdef UNIV_DEBUG
+/* Added to test the innodb_buffer_pool_load_incomplete status variable. */
+static MYSQL_SYSVAR_ULONG(buffer_pool_load_pages_abort, srv_buf_pool_load_pages_abort,
+ PLUGIN_VAR_RQCMDARG,
+ "Number of pages during a buffer pool load to process before signaling innodb_buffer_pool_load_abort=1",
+ NULL, NULL, LONG_MAX, 1, LONG_MAX, 0);
+
static MYSQL_SYSVAR_STR(buffer_pool_evict, srv_buffer_pool_evict,
PLUGIN_VAR_RQCMDARG,
"Evict pages from the buffer pool",
@@ -20476,8 +20411,8 @@ static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
static MYSQL_SYSVAR_UINT(spin_wait_delay, srv_spin_wait_delay,
PLUGIN_VAR_OPCMDARG,
- "Maximum delay between polling for a spin lock (6 by default)",
- NULL, NULL, 6, 0, 6000, 0);
+ "Maximum delay between polling for a spin lock (4 by default)",
+ NULL, NULL, 4, 0, 6000, 0);
static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
PLUGIN_VAR_RQCMDARG,
@@ -20974,6 +20909,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
#endif /* UNIV_DEBUG */
MYSQL_SYSVAR(buffer_pool_load_now),
MYSQL_SYSVAR(buffer_pool_load_abort),
+#ifdef UNIV_DEBUG
+ MYSQL_SYSVAR(buffer_pool_load_pages_abort),
+#endif /* UNIV_DEBUG */
MYSQL_SYSVAR(buffer_pool_load_at_startup),
MYSQL_SYSVAR(defragment),
MYSQL_SYSVAR(defragment_n_pages),
@@ -21672,7 +21610,7 @@ innobase_get_computed_value(
if (max_prefix) {
len = dtype_get_at_most_n_mbchars(
col->m_col.prtype,
- col->m_col.mbminmaxlen,
+ col->m_col.mbminlen, col->m_col.mbmaxlen,
max_prefix,
field->len,
static_cast<char*>(dfield_get_data(field)));
@@ -21824,7 +21762,7 @@ ib_errf(
if (vasprintf(&str, format, args) == -1) {
/* In case of failure use a fixed length string */
str = static_cast<char*>(malloc(BUFSIZ));
- my_vsnprintf(str, BUFSIZ, format, args);
+ vsnprintf(str, BUFSIZ, format, args);
}
#else
/* Use a fixed length string. */
@@ -21833,7 +21771,7 @@ ib_errf(
va_end(args);
return; /* Watch for Out-Of-Memory */
}
- my_vsnprintf(str, BUFSIZ, format, args);
+ vsnprintf(str, BUFSIZ, format, args);
#endif /* _WIN32 */
ib_senderrf(thd, level, code, str);
@@ -21856,7 +21794,8 @@ const char* BUG_REPORT_MSG =
"Submit a detailed bug report to https://jira.mariadb.org/";
const char* FORCE_RECOVERY_MSG =
- "Please refer to " REFMAN "forcing-innodb-recovery.html"
+ "Please refer to "
+ "https://mariadb.com/kb/en/library/xtradbinnodb-recovery-modes/"
" for information about forcing recovery.";
const char* ERROR_CREATING_MSG =
@@ -21864,17 +21803,17 @@ const char* ERROR_CREATING_MSG =
const char* OPERATING_SYSTEM_ERROR_MSG =
"Some operating system error numbers are described at"
- " " REFMAN "operating-system-error-codes.html";
+ " https://mariadb.com/kb/en/library/operating-system-error-codes/";
const char* FOREIGN_KEY_CONSTRAINTS_MSG =
- "Please refer to " REFMAN "innodb-foreign-key-constraints.html"
+ "Please refer to https://mariadb.com/kb/en/library/foreign-keys/"
" for correct foreign key definition.";
const char* SET_TRANSACTION_MSG =
- "Please refer to " REFMAN "set-transaction.html";
+ "Please refer to https://mariadb.com/kb/en/library/set-transaction/";
const char* INNODB_PARAMETERS_MSG =
- "Please refer to " REFMAN "innodb-parameters.html";
+ "Please refer to https://mariadb.com/kb/en/library/xtradbinnodb-server-system-variables/";
/**********************************************************************
Converts an identifier from my_charset_filename to UTF-8 charset.
@@ -21891,7 +21830,7 @@ innobase_convert_to_filename_charset(
CHARSET_INFO* cs_from = system_charset_info;
return(static_cast<uint>(strconvert(
- cs_from, from, strlen(from),
+ cs_from, from, uint(strlen(from)),
cs_to, to, static_cast<uint>(len), &errors)));
}
@@ -21910,7 +21849,7 @@ innobase_convert_to_system_charset(
CHARSET_INFO* cs2 = system_charset_info;
return(static_cast<uint>(strconvert(
- cs1, from, strlen(from),
+ cs1, from, static_cast<uint>(strlen(from)),
cs2, to, static_cast<uint>(len), errors)));
}
@@ -22008,8 +21947,19 @@ innodb_buffer_pool_size_validate(
*static_cast<longlong*>(save) = requested_buf_pool_size;
+ if (srv_buf_pool_size == static_cast<ulint>(intbuf)) {
+ buf_pool_mutex_exit_all();
+ /* nothing to do */
+ return(0);
+ }
+
if (srv_buf_pool_size == requested_buf_pool_size) {
buf_pool_mutex_exit_all();
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "innodb_buffer_pool_size must be at least"
+ " innodb_buffer_pool_chunk_size=%lu",
+ srv_buf_pool_chunk_unit);
/* nothing to do */
return(0);
}
@@ -22244,7 +22194,7 @@ ib_push_frm_error(
"installations? See "
REFMAN
"innodb-troubleshooting.html\n",
- ib_table->name);
+ ib_table->name.m_name);
if (push_warning) {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
@@ -22252,7 +22202,7 @@ ib_push_frm_error(
"InnoDB: Table %s has a "
"primary key in InnoDB data "
"dictionary, but not in "
- "MariaDB!", ib_table->name);
+ "MariaDB!", ib_table->name.m_name);
}
break;
case DICT_NO_PK_FRM_HAS:
@@ -22265,7 +22215,7 @@ ib_push_frm_error(
"columns, then MariaDB internally treats that "
"key as the primary key. You can fix this "
"error by dump + DROP + CREATE + reimport "
- "of the table.", ib_table->name);
+ "of the table.", ib_table->name.m_name);
if (push_warning) {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
@@ -22274,7 +22224,7 @@ ib_push_frm_error(
"primary key in InnoDB data "
"dictionary, but has one in "
"MariaDB!",
- ib_table->name);
+ ib_table->name.m_name);
}
break;
@@ -22288,7 +22238,7 @@ ib_push_frm_error(
"installations? See "
REFMAN
"innodb-troubleshooting.html\n",
- ib_table->name, n_keys,
+ ib_table->name.m_name, n_keys,
table->s->keys);
if (push_warning) {
@@ -22298,7 +22248,7 @@ ib_push_frm_error(
"indexes inside InnoDB, which "
"is different from the number of "
"indexes %u defined in the MariaDB ",
- ib_table->name, n_keys,
+ ib_table->name.m_name, n_keys,
table->s->keys);
}
break;
@@ -22308,7 +22258,7 @@ ib_push_frm_error(
sql_print_error("InnoDB: Table %s is consistent "
"on InnoDB data dictionary and MariaDB "
" FRM file.",
- ib_table->name);
+ ib_table->name.m_name);
ut_error;
break;
}
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index d7f5d36a680..34c01929a56 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -515,9 +515,6 @@ protected:
ROW_SEL_EXACT_PREFIX, or undefined */
uint m_last_match_mode;
- /** number of write_row() calls */
- uint m_num_write_row;
-
/** If mysql has locked with external_lock() */
bool m_mysql_has_locked;
};
@@ -914,11 +911,6 @@ innodb_base_col_setup_for_stored(
create_table_info_t::normalize_table_name_low(norm_name, name, FALSE)
#endif /* _WIN32 */
-/** Obtain the InnoDB transaction of a MySQL thread.
-@param[in,out] thd MySQL thread handler.
-@return reference to transaction pointer */
-trx_t*& thd_to_trx(THD* thd);
-
/** Converts an InnoDB error code to a MySQL error code.
Also tells to MySQL about a possible transaction rollback inside InnoDB caused
by a lock wait timeout or a deadlock.
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 517f2ee7631..b775bfa40ee 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -87,6 +87,9 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_REBUILD
/*
| Alter_inplace_info::ALTER_STORED_COLUMN_TYPE
*/
+ | Alter_inplace_info::ALTER_COLUMN_UNVERSIONED
+ | Alter_inplace_info::ALTER_ADD_SYSTEM_VERSIONING
+ | Alter_inplace_info::ALTER_DROP_SYSTEM_VERSIONING
;
/** Operations that require changes to data */
@@ -355,7 +358,7 @@ my_error_innodb(
break;
case DB_TOO_BIG_INDEX_COL:
my_error(ER_INDEX_COLUMN_TOO_LONG, MYF(0),
- DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags));
+ (ulong) DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags));
break;
case DB_TOO_MANY_CONCURRENT_TRXS:
my_error(ER_TOO_MANY_CONCURRENT_TRXS, MYF(0));
@@ -631,6 +634,11 @@ instant_alter_column_possible(
const Alter_inplace_info* ha_alter_info,
const TABLE* table)
{
+ // Making table system-versioned instantly is not implemented yet.
+ if (ha_alter_info->handler_flags & Alter_inplace_info::ALTER_ADD_SYSTEM_VERSIONING) {
+ return false;
+ }
+
if (~ha_alter_info->handler_flags
& Alter_inplace_info::ADD_STORED_BASE_COLUMN) {
return false;
@@ -688,6 +696,13 @@ ha_innobase::check_if_supported_inplace_alter(
{
DBUG_ENTER("check_if_supported_inplace_alter");
+ if ((table->versioned(VERS_TIMESTAMP) || altered_table->versioned(VERS_TIMESTAMP))
+ && innobase_need_rebuild(ha_alter_info, table)) {
+ ha_alter_info->unsupported_reason =
+ "Not implemented for system-versioned tables";
+ DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
+ }
+
/* Before 10.2.2 information about virtual columns was not stored in
system tables. We need to do a full alter to rebuild proper 10.2.2+
metadata with the information about virtual columns */
@@ -1162,6 +1177,7 @@ next_column:
/* If the table already contains fulltext indexes,
refuse to rebuild the table natively altogether. */
if (m_prebuilt->table->fts) {
+cannot_create_many_fulltext_index:
ha_alter_info->unsupported_reason = innobase_get_err_msg(
ER_INNODB_FT_LIMIT);
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
@@ -1191,6 +1207,7 @@ next_column:
We could also do ADD SPATIAL INDEX by implementing
row_log_apply() for it. */
+ bool add_fulltext = false;
for (uint i = 0; i < ha_alter_info->index_add_count; i++) {
const KEY* key =
@@ -1202,20 +1219,30 @@ next_column:
| HA_PACK_KEY
| HA_GENERATED_KEY
| HA_BINARY_PACK_KEY)));
+ if (add_fulltext) {
+ goto cannot_create_many_fulltext_index;
+ }
+ add_fulltext = true;
ha_alter_info->unsupported_reason = innobase_get_err_msg(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS);
online = false;
- break;
}
- if (key->flags & HA_SPATIAL) {
+ if (online && (key->flags & HA_SPATIAL)) {
ha_alter_info->unsupported_reason = innobase_get_err_msg(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS);
online = false;
- break;
}
}
}
+ // FIXME: implement Online DDL for system-versioned tables
+ if ((table->versioned(VERS_TRX_ID) || altered_table->versioned(VERS_TRX_ID))
+ && innobase_need_rebuild(ha_alter_info, table)) {
+ ha_alter_info->unsupported_reason =
+ "Not implemented for system-versioned tables";
+ online = false;
+ }
+
DBUG_RETURN(online
? HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE
: HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE);
@@ -1356,7 +1383,6 @@ innobase_set_foreign_key_option(
ut_ad(!foreign->type);
switch (fk_key->delete_opt) {
- // JAN: TODO: ? MySQL 5.7 used enum fk_option directly from sql_lex.h
case FK_OPTION_NO_ACTION:
case FK_OPTION_RESTRICT:
case FK_OPTION_SET_DEFAULT:
@@ -1368,6 +1394,8 @@ innobase_set_foreign_key_option(
case FK_OPTION_SET_NULL:
foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL;
break;
+ case FK_OPTION_UNDEF:
+ break;
}
switch (fk_key->update_opt) {
@@ -1382,6 +1410,8 @@ innobase_set_foreign_key_option(
case FK_OPTION_SET_NULL:
foreign->type |= DICT_FOREIGN_ON_UPDATE_SET_NULL;
break;
+ case FK_OPTION_UNDEF:
+ break;
}
return(innobase_check_fk_option(foreign));
@@ -1892,8 +1922,7 @@ innobase_col_to_mysql(
#ifdef UNIV_DEBUG
case DATA_MYSQL:
ut_ad(flen >= len);
- ut_ad(DATA_MBMAXLEN(col->mbminmaxlen)
- >= DATA_MBMINLEN(col->mbminmaxlen));
+ ut_ad(col->mbmaxlen >= col->mbminlen);
memcpy(dest, data, len);
break;
@@ -2109,7 +2138,7 @@ innobase_check_index_keys(
if (0 == strcmp(key.name.str, key2.name.str)) {
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
- key.name);
+ key.name.str);
return(ER_WRONG_NAME_FOR_INDEX);
}
@@ -2172,8 +2201,8 @@ innobase_check_index_keys(
}
#endif /* MYSQL_RENAME_INDEX */
- my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key.name);
-
+ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
+ key.name.str);
return(ER_WRONG_NAME_FOR_INDEX);
}
@@ -4251,6 +4280,7 @@ innobase_add_instant_try(
buf_block_t* block = btr_pcur_get_block(&pcur);
ut_ad(page_is_leaf(block->frame));
+ ut_ad(!page_has_prev(block->frame));
ut_ad(!buf_block_get_page_zip(block));
const rec_t* rec = btr_pcur_get_rec(&pcur);
que_thr_t* thr = pars_complete_graph_for_exec(
@@ -4258,7 +4288,8 @@ innobase_add_instant_try(
if (rec_is_default_row(rec, index)) {
ut_ad(page_rec_is_user_rec(rec));
- if (page_rec_is_last(rec, block->frame)) {
+ if (!page_has_next(block->frame)
+ && page_rec_is_last(rec, block->frame)) {
goto empty_table;
}
/* Extend the record with the instantly added columns. */
@@ -4715,7 +4746,7 @@ prepare_inplace_alter_table_dict(
index_def_t* index_defs; /* index definitions */
dict_table_t* user_table;
dict_index_t* fts_index = NULL;
- ulint new_clustered = 0;
+ bool new_clustered = false;
dberr_t error;
ulint num_fts_index;
dict_add_v_col_t* add_v = NULL;
@@ -4792,7 +4823,7 @@ prepare_inplace_alter_table_dict(
fts_doc_id_col, add_fts_doc_id, add_fts_doc_id_idx,
old_table);
- new_clustered = DICT_CLUSTERED & index_defs[0].ind_type;
+ new_clustered = (DICT_CLUSTERED & index_defs[0].ind_type) != 0;
/* The primary index would be rebuilt if a FTS Doc ID
column is to be added, and the primary index definition
@@ -4972,6 +5003,18 @@ new_clustered_failed:
field_type |= DATA_UNSIGNED;
}
+ if (altered_table->versioned()) {
+ if (i == altered_table->s->row_start_field) {
+ field_type |= DATA_VERS_START;
+ } else if (i ==
+ altered_table->s->row_end_field) {
+ field_type |= DATA_VERS_END;
+ } else if (!(field->flags
+ & VERS_UPDATE_UNVERSIONED_FLAG)) {
+ field_type |= DATA_VERSIONED;
+ }
+ }
+
if (dtype_is_string_type(col_type)) {
charset_no = (ulint) field->charset()->number;
@@ -5214,8 +5257,10 @@ new_clustered_failed:
= user_table->indexes.start);
DBUG_ASSERT(col->mtype == old_col->mtype);
DBUG_ASSERT(col->prtype == old_col->prtype);
- DBUG_ASSERT(col->mbminmaxlen
- == old_col->mbminmaxlen);
+ DBUG_ASSERT(col->mbminlen
+ == old_col->mbminlen);
+ DBUG_ASSERT(col->mbmaxlen
+ == old_col->mbmaxlen);
DBUG_ASSERT(col->len >= old_col->len);
DBUG_ASSERT(old_col->is_instant()
== (dict_col_get_clust_pos(
@@ -5291,35 +5336,18 @@ new_clustered_failed:
ctx->prepare_instant();
}
- if (!ctx->is_instant()) {
- if (num_fts_index > 1) {
- my_error(ER_INNODB_FT_LIMIT, MYF(0));
- goto error_handled;
- }
-
- if (!ctx->online) {
- /* This is not an online operation (LOCK=NONE). */
- } else if (ctx->add_autoinc == ULINT_UNDEFINED
- && num_fts_index == 0
- && (!innobase_need_rebuild(ha_alter_info, old_table)
- || !innobase_fulltext_exist(altered_table))) {
- /* InnoDB can perform an online operation
- (LOCK=NONE). */
- } else {
- size_t query_length;
- /* This should have been blocked in
- check_if_supported_inplace_alter(). */
- ut_ad(0);
- my_error(ER_NOT_SUPPORTED_YET, MYF(0),
- innobase_get_stmt_unsafe(
- ctx->prebuilt->trx->mysql_thd,
- &query_length));
- goto error_handled;
- }
- }
-
if (ctx->need_rebuild()) {
not_instant_add_column:
+ DBUG_ASSERT(ctx->need_rebuild());
+ DBUG_ASSERT(!ctx->is_instant());
+ DBUG_ASSERT(num_fts_index <= 1);
+ DBUG_ASSERT(!ctx->online || num_fts_index == 0);
+ DBUG_ASSERT(!ctx->online
+ || ctx->add_autoinc == ULINT_UNDEFINED);
+ DBUG_ASSERT(!ctx->online
+ || !innobase_need_rebuild(ha_alter_info, old_table)
+ || !innobase_fulltext_exist(altered_table));
+
uint32_t key_id = FIL_DEFAULT_ENCRYPTION_KEY;
fil_encryption_t mode = FIL_ENCRYPTION_DEFAULT;
@@ -5419,7 +5447,7 @@ new_table_failed:
ut_ad(index->trx_id == ctx->trx->id);
if (index->type & DICT_FTS) {
- DBUG_ASSERT(num_fts_index);
+ DBUG_ASSERT(num_fts_index == 1);
DBUG_ASSERT(!fts_index);
DBUG_ASSERT(index->type == DICT_FTS);
fts_index = ctx->add_index[a];
@@ -5504,7 +5532,7 @@ error_handling_drop_uncached:
/* If ADD INDEX with LOCK=NONE has been
requested, allocate a modification log. */
if (index->type & DICT_FTS) {
- DBUG_ASSERT(num_fts_index);
+ DBUG_ASSERT(num_fts_index == 1);
DBUG_ASSERT(!fts_index);
DBUG_ASSERT(index->type == DICT_FTS);
fts_index = ctx->add_index[a];
@@ -5540,7 +5568,7 @@ error_handling_drop_uncached:
if (ctx->online && ctx->num_to_add_index) {
/* Assign a consistent read view for
row_merge_read_clustered_index(). */
- trx_assign_read_view(ctx->prebuilt->trx);
+ ctx->prebuilt->trx->read_view.open(ctx->prebuilt->trx);
}
if (fts_index) {
@@ -7070,7 +7098,8 @@ ok_exit:
ctx->add_index, ctx->add_key_numbers, ctx->num_to_add_index,
altered_table, ctx->add_cols, ctx->col_map,
ctx->add_autoinc, ctx->sequence, ctx->skip_pk_sort,
- ctx->m_stage, add_v, eval_table);
+ ctx->m_stage, add_v, eval_table,
+ ha_alter_info->handler_flags & Alter_inplace_info::ALTER_DROP_HISTORICAL);
#ifndef DBUG_OFF
oom:
@@ -8972,7 +9001,7 @@ alter_stats_rebuild(
# define DBUG_INJECT_CRASH(prefix, count) \
do { \
char buf[32]; \
- ut_snprintf(buf, sizeof buf, prefix "_%u", count); \
+ snprintf(buf, sizeof buf, prefix "_%u", count); \
DBUG_EXECUTE_IF(buf, DBUG_SUICIDE();); \
} while (0)
#else
@@ -9254,7 +9283,7 @@ ha_innobase::commit_inplace_alter_table(
/* Generate a dynamic dbug text. */
char buf[32];
- ut_snprintf(buf, sizeof buf,
+ snprintf(buf, sizeof buf,
"ib_commit_inplace_fail_%u",
failure_inject_count++);
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index b597b9224fa..857b2d3acef 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -586,7 +586,7 @@ fill_innodb_trx_from_cache(
cache, I_S_INNODB_TRX, i);
/* trx_id */
- ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, row->trx_id);
+ snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, row->trx_id);
OK(field_store_string(fields[IDX_TRX_ID], trx_id));
/* trx_state */
@@ -915,8 +915,8 @@ fill_innodb_locks_from_cache(
lock_id));
/* lock_trx_id */
- ut_snprintf(lock_trx_id, sizeof(lock_trx_id),
- TRX_ID_FMT, row->lock_trx_id);
+ snprintf(lock_trx_id, sizeof(lock_trx_id),
+ TRX_ID_FMT, row->lock_trx_id);
OK(field_store_string(fields[IDX_LOCK_TRX_ID], lock_trx_id));
/* lock_mode */
@@ -1115,8 +1115,8 @@ fill_innodb_lock_waits_from_cache(
cache, I_S_INNODB_LOCK_WAITS, i);
/* requesting_trx_id */
- ut_snprintf(requesting_trx_id, sizeof(requesting_trx_id),
- TRX_ID_FMT, row->requested_lock_row->lock_trx_id);
+ snprintf(requesting_trx_id, sizeof(requesting_trx_id),
+ TRX_ID_FMT, row->requested_lock_row->lock_trx_id);
OK(field_store_string(fields[IDX_REQUESTING_TRX_ID],
requesting_trx_id));
@@ -1129,8 +1129,8 @@ fill_innodb_lock_waits_from_cache(
sizeof(requested_lock_id))));
/* blocking_trx_id */
- ut_snprintf(blocking_trx_id, sizeof(blocking_trx_id),
- TRX_ID_FMT, row->blocking_lock_row->lock_trx_id);
+ snprintf(blocking_trx_id, sizeof(blocking_trx_id),
+ TRX_ID_FMT, row->blocking_lock_row->lock_trx_id);
OK(field_store_string(fields[IDX_BLOCKING_TRX_ID],
blocking_trx_id));
@@ -1232,7 +1232,7 @@ trx_i_s_common_fill_table(
TABLE_LIST* tables, /*!< in/out: tables to fill */
Item* ) /*!< in: condition (not used) */
{
- const char* table_name;
+ LEX_CSTRING table_name;
int ret;
trx_i_s_cache_t* cache;
@@ -1252,7 +1252,7 @@ trx_i_s_common_fill_table(
table_name = tables->schema_table_name;
/* or table_name = tables->schema_table->table_name; */
- RETURN_IF_INNODB_NOT_STARTED(table_name);
+ RETURN_IF_INNODB_NOT_STARTED(table_name.str);
/* update the cache */
trx_i_s_cache_start_write(cache);
@@ -1261,7 +1261,7 @@ trx_i_s_common_fill_table(
if (trx_i_s_cache_is_truncated(cache)) {
- ib::warn() << "Data in " << table_name << " truncated due to"
+ ib::warn() << "Data in " << table_name.str << " truncated due to"
" memory limit of " << TRX_I_S_MEM_LIMIT << " bytes";
}
@@ -1269,7 +1269,7 @@ trx_i_s_common_fill_table(
trx_i_s_cache_start_read(cache);
- if (innobase_strcasecmp(table_name, "innodb_trx") == 0) {
+ if (innobase_strcasecmp(table_name.str, "innodb_trx") == 0) {
if (fill_innodb_trx_from_cache(
cache, thd, tables->table) != 0) {
@@ -1277,7 +1277,7 @@ trx_i_s_common_fill_table(
ret = 1;
}
- } else if (innobase_strcasecmp(table_name, "innodb_locks") == 0) {
+ } else if (innobase_strcasecmp(table_name.str, "innodb_locks") == 0) {
if (fill_innodb_locks_from_cache(
cache, thd, tables->table) != 0) {
@@ -1285,7 +1285,7 @@ trx_i_s_common_fill_table(
ret = 1;
}
- } else if (innobase_strcasecmp(table_name, "innodb_lock_waits") == 0) {
+ } else if (innobase_strcasecmp(table_name.str, "innodb_lock_waits") == 0) {
if (fill_innodb_lock_waits_from_cache(
cache, thd, tables->table) != 0) {
@@ -1295,7 +1295,7 @@ trx_i_s_common_fill_table(
} else {
ib::error() << "trx_i_s_common_fill_table() was"
- " called to fill unknown table: " << table_name << "."
+ " called to fill unknown table: " << table_name.str << "."
" This function only knows how to fill"
" innodb_trx, innodb_locks and"
" innodb_lock_waits tables.";
@@ -1399,7 +1399,7 @@ i_s_cmp_fill_low(
DBUG_RETURN(0);
}
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
for (uint i = 0; i < PAGE_ZIP_SSIZE_MAX; i++) {
page_zip_stat_t* zip_stat = &page_zip_stat[i];
@@ -1700,7 +1700,7 @@ i_s_cmp_per_index_fill_low(
DBUG_RETURN(0);
}
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* Create a snapshot of the stats so we do not bump into lock
order violations with dict_sys->mutex below. */
@@ -1732,8 +1732,8 @@ i_s_cmp_per_index_fill_low(
index->name);
} else {
/* index not found */
- ut_snprintf(name, sizeof(name),
- "index_id:" IB_ID_FMT, iter->first);
+ snprintf(name, sizeof(name),
+ "index_id:" IB_ID_FMT, iter->first);
field_store_string(fields[IDX_DATABASE_NAME],
"unknown");
field_store_string(fields[IDX_TABLE_NAME],
@@ -2022,7 +2022,7 @@ i_s_cmpmem_fill_low(
DBUG_RETURN(0);
}
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
buf_pool_t* buf_pool;
@@ -4543,7 +4543,7 @@ i_s_innodb_buffer_stats_fill_table(
buf_pool_info_t* pool_info;
DBUG_ENTER("i_s_innodb_buffer_fill_general");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* Only allow the PROCESS privilege holder to access the stats */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -5273,7 +5273,7 @@ i_s_innodb_buffer_page_fill_table(
DBUG_ENTER("i_s_innodb_buffer_page_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -5817,7 +5817,7 @@ i_s_innodb_buf_page_lru_fill_table(
DBUG_ENTER("i_s_innodb_buf_page_lru_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to any users that do not hold PROCESS_ACL */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -6089,7 +6089,7 @@ i_s_sys_tables_fill_table(
mtr_t mtr;
DBUG_ENTER("i_s_sys_tables_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -6389,7 +6389,7 @@ i_s_sys_tables_fill_table_stats(
mtr_t mtr;
DBUG_ENTER("i_s_sys_tables_fill_table_stats");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -6663,7 +6663,7 @@ i_s_sys_indexes_fill_table(
mtr_t mtr;
DBUG_ENTER("i_s_sys_indexes_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -6908,7 +6908,7 @@ i_s_sys_columns_fill_table(
mtr_t mtr;
DBUG_ENTER("i_s_sys_columns_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -7119,7 +7119,7 @@ i_s_sys_virtual_fill_table(
mtr_t mtr;
DBUG_ENTER("i_s_sys_virtual_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -7321,7 +7321,7 @@ i_s_sys_fields_fill_table(
mtr_t mtr;
DBUG_ENTER("i_s_sys_fields_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -7553,7 +7553,7 @@ i_s_sys_foreign_fill_table(
mtr_t mtr;
DBUG_ENTER("i_s_sys_foreign_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -7768,7 +7768,7 @@ i_s_sys_foreign_cols_fill_table(
mtr_t mtr;
DBUG_ENTER("i_s_sys_foreign_cols_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -8132,7 +8132,7 @@ i_s_sys_tablespaces_fill_table(
mtr_t mtr;
DBUG_ENTER("i_s_sys_tablespaces_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -8323,7 +8323,7 @@ i_s_sys_datafiles_fill_table(
mtr_t mtr;
DBUG_ENTER("i_s_sys_datafiles_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -8624,7 +8624,7 @@ i_s_tablespaces_encryption_fill_table(
bool found_space_0 = false;
DBUG_ENTER("i_s_tablespaces_encryption_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, SUPER_ACL)) {
@@ -8945,7 +8945,7 @@ i_s_tablespaces_scrubbing_fill_table(
bool found_space_0 = false;
DBUG_ENTER("i_s_tablespaces_scrubbing_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without SUPER_ACL privilege */
if (check_global_access(thd, SUPER_ACL)) {
@@ -9144,7 +9144,7 @@ i_s_innodb_mutexes_fill_table(
Field** fields = tables->table->field;
DBUG_ENTER("i_s_innodb_mutexes_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -9180,8 +9180,8 @@ i_s_innodb_mutexes_fill_table(
if (block_mutex) {
char buf1[IO_SIZE];
- my_snprintf(buf1, sizeof buf1, "combined %s",
- innobase_basename(block_mutex->cfile_name));
+ snprintf(buf1, sizeof buf1, "combined %s",
+ innobase_basename(block_mutex->cfile_name));
OK(field_store_string(fields[MUTEXES_NAME], block_mutex->cmutex_name));
OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1));
@@ -9219,8 +9219,8 @@ i_s_innodb_mutexes_fill_table(
if (block_lock) {
char buf1[IO_SIZE];
- my_snprintf(buf1, sizeof buf1, "combined %s",
- innobase_basename(block_lock->cfile_name));
+ snprintf(buf1, sizeof buf1, "combined %s",
+ innobase_basename(block_lock->cfile_name));
//OK(field_store_string(fields[MUTEXES_NAME], block_lock->lock_name));
OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1));
@@ -9462,25 +9462,7 @@ static ST_FIELD_INFO innodb_sys_semaphore_waits_fields_info[] =
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
- // SYS_SEMAPHORE_WAITS_LAST_READER_FILE 17
- {STRUCT_FLD(field_name, "LAST_READER_FILE"),
- STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
- STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
- STRUCT_FLD(value, 0),
- STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
- STRUCT_FLD(old_name, ""),
- STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
-
- // SYS_SEMAPHORE_WAITS_LAST_READER_LINE 18
- {STRUCT_FLD(field_name, "LAST_READER_LINE"),
- STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
- STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
- STRUCT_FLD(value, 0),
- STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
- STRUCT_FLD(old_name, ""),
- STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
-
- // SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 19
+ // SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 17
{STRUCT_FLD(field_name, "LAST_WRITER_FILE"),
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
@@ -9489,7 +9471,7 @@ static ST_FIELD_INFO innodb_sys_semaphore_waits_fields_info[] =
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
- // SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 20
+ // SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 18
{STRUCT_FLD(field_name, "LAST_WRITER_LINE"),
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
@@ -9498,7 +9480,7 @@ static ST_FIELD_INFO innodb_sys_semaphore_waits_fields_info[] =
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
- // SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 21
+ // SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 19
{STRUCT_FLD(field_name, "OS_WAIT_COUNT"),
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
diff --git a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
index e07fe49f7fa..4ff2248c28e 100644
--- a/storage/innobase/handler/i_s.h
+++ b/storage/innobase/handler/i_s.h
@@ -127,11 +127,9 @@ HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
#define SYS_SEMAPHORE_WAITS_READERS 14
#define SYS_SEMAPHORE_WAITS_WAITERS_FLAG 15
#define SYS_SEMAPHORE_WAITS_LOCK_WORD 16
-#define SYS_SEMAPHORE_WAITS_LAST_READER_FILE 17
-#define SYS_SEMAPHORE_WAITS_LAST_READER_LINE 18
-#define SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 19
-#define SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 20
-#define SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 21
+#define SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 17
+#define SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 18
+#define SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 19
/*******************************************************************//**
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index b0d9ccbde7d..8b132b62255 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -483,7 +483,7 @@ ibuf_size_update(
ibuf->free_list_len = flst_get_len(root + PAGE_HEADER
+ PAGE_BTR_IBUF_FREE_LIST);
- ibuf->height = 1 + btr_page_get_level_low(root);
+ ibuf->height = 1 + btr_page_get_level(root);
/* the '1 +' is the ibuf header page */
ibuf->size = ibuf->seg_size - (1 + ibuf->free_list_len);
@@ -3323,8 +3323,7 @@ ibuf_get_entry_counter_func(
return(ULINT_UNDEFINED);
} else if (!page_rec_is_infimum(rec)) {
return(ibuf_get_entry_counter_low(mtr, rec, space, page_no));
- } else if (only_leaf
- || fil_page_get_prev(page_align(rec)) == FIL_NULL) {
+ } else if (only_leaf || !page_has_prev(page_align(rec))) {
/* The parent node pointer did not contain the
searched for (space, page_no), which means that the
search ended on the correct page regardless of the
@@ -4494,7 +4493,7 @@ ibuf_merge_or_delete_for_page(
return;
}
- space = fil_space_acquire(page_id.space());
+ space = fil_space_acquire_silent(page_id.space());
if (UNIV_UNLIKELY(!space)) {
/* Do not try to read the bitmap page from the
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
index cff8bc7cbc9..336ee68ee59 100644
--- a/storage/innobase/include/btr0btr.h
+++ b/storage/innobase/include/btr0btr.h
@@ -37,6 +37,12 @@ Created 6/2/1994 Heikki Tuuri
#include "btr0types.h"
#include "gis0type.h"
+#define BTR_MAX_NODE_LEVEL 50 /*!< Maximum B-tree page level
+ (not really a hard limit).
+ Used in debug assertions
+ in btr_page_set_level and
+ btr_page_get_level */
+
/** Maximum record size which can be stored on a page, without using the
special big record storage structure */
#define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200)
@@ -285,14 +291,22 @@ btr_page_get_index_id(
MY_ATTRIBUTE((warn_unused_result));
/********************************************************//**
Gets the node level field in an index page.
+@param[in] page index page
@return level, leaf level == 0 */
UNIV_INLINE
ulint
-btr_page_get_level_low(
-/*===================*/
- const page_t* page) /*!< in: index page */
- MY_ATTRIBUTE((warn_unused_result));
-#define btr_page_get_level(page, mtr) btr_page_get_level_low(page)
+btr_page_get_level(const page_t* page)
+{
+ ulint level;
+
+ ut_ad(page);
+
+ level = mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL);
+
+ ut_ad(level <= BTR_MAX_NODE_LEVEL);
+
+ return(level);
+} MY_ATTRIBUTE((warn_unused_result))
/********************************************************//**
Gets the next index page number.
@return next page number */
diff --git a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic
index bd4f2a40267..d24458beace 100644
--- a/storage/innobase/include/btr0btr.ic
+++ b/storage/innobase/include/btr0btr.ic
@@ -29,12 +29,6 @@ Created 6/2/1994 Heikki Tuuri
#include "mtr0log.h"
#include "page0zip.h"
-#define BTR_MAX_NODE_LEVEL 50 /*!< Maximum B-tree page level
- (not really a hard limit).
- Used in debug assertions
- in btr_page_set_level and
- btr_page_get_level_low */
-
/** Gets a buffer page and declares its latching order level.
@param[in] page_id page id
@param[in] mode latch mode
@@ -144,26 +138,6 @@ btr_page_get_index_id(
}
/********************************************************//**
-Gets the node level field in an index page.
-@return level, leaf level == 0 */
-UNIV_INLINE
-ulint
-btr_page_get_level_low(
-/*===================*/
- const page_t* page) /*!< in: index page */
-{
- ulint level;
-
- ut_ad(page);
-
- level = mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL);
-
- ut_ad(level <= BTR_MAX_NODE_LEVEL);
-
- return(level);
-}
-
-/********************************************************//**
Sets the node level field in an index page. */
UNIV_INLINE
void
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 76f13325e2a..8d8fe0bc236 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -177,8 +177,7 @@ Note that if mode is PAGE_CUR_LE, which is used in inserts, then
cursor->up_match and cursor->low_match both will have sensible values.
If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
dberr_t
-btr_cur_search_to_nth_level(
-/*========================*/
+btr_cur_search_to_nth_level_func(
dict_index_t* index, /*!< in: index */
ulint level, /*!< in: the tree level of search */
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
@@ -197,23 +196,29 @@ btr_cur_search_to_nth_level(
cursor->left_block is used to store a pointer
to the left neighbor page, in the cases
BTR_SEARCH_PREV and BTR_MODIFY_PREV;
- NOTE that if has_search_latch
- is != 0, we maybe do not have a latch set
- on the cursor page, we assume
- the caller uses his search latch
- to protect the record! */
+ NOTE that if ahi_latch, we might not have a
+ cursor page latch, we assume that ahi_latch
+ protects the record! */
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
- ulint has_search_latch,
- /*!< in: latch mode the caller
- currently has on search system:
- RW_S_LATCH, or 0 */
+#ifdef BTR_CUR_HASH_ADAPT
+ rw_lock_t* ahi_latch,
+ /*!< in: currently held btr_search_latch
+ (in RW_S_LATCH mode), or NULL */
+#endif /* BTR_CUR_HASH_ADAPT */
const char* file, /*!< in: file name */
unsigned line, /*!< in: line where called */
mtr_t* mtr, /*!< in/out: mini-transaction */
ib_uint64_t autoinc = 0);
/*!< in: PAGE_ROOT_AUTO_INC to be written
(0 if none) */
+#ifdef BTR_CUR_HASH_ADAPT
+# define btr_cur_search_to_nth_level(i,l,t,m,lm,c,a,fi,li,mtr) \
+ btr_cur_search_to_nth_level_func(i,l,t,m,lm,c,a,fi,li,mtr)
+#else /* BTR_CUR_HASH_ADAPT */
+# define btr_cur_search_to_nth_level(i,l,t,m,lm,c,a,fi,li,mtr) \
+ btr_cur_search_to_nth_level_func(i,l,t,m,lm,c,fi,li,mtr)
+#endif /* BTR_CUR_HASH_ADAPT */
/*****************************************************************//**
Opens a cursor at either end of an index.
diff --git a/storage/innobase/include/btr0cur.ic b/storage/innobase/include/btr0cur.ic
index 56868cca336..4ab3819ad75 100644
--- a/storage/innobase/include/btr0cur.ic
+++ b/storage/innobase/include/btr0cur.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2015, 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
the terms of the GNU General Public License as published by the Free Software
@@ -137,10 +138,9 @@ btr_cur_compress_recommendation(
LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page) * 2U,
return(FALSE));
- if ((page_get_data_size(page)
- < BTR_CUR_PAGE_COMPRESS_LIMIT(cursor->index))
- || ((btr_page_get_next(page, mtr) == FIL_NULL)
- && (btr_page_get_prev(page, mtr) == FIL_NULL))) {
+ if (page_get_data_size(page)
+ < BTR_CUR_PAGE_COMPRESS_LIMIT(cursor->index)
+ || !page_has_siblings(page)) {
/* The page fillfactor has dropped below a predefined
minimum value OR the level in the B-tree contains just
@@ -173,11 +173,9 @@ btr_cur_can_delete_without_compress(
page = btr_cur_get_page(cursor);
- if ((page_get_data_size(page) - rec_size
- < BTR_CUR_PAGE_COMPRESS_LIMIT(cursor->index))
- || ((btr_page_get_next(page, mtr) == FIL_NULL)
- && (btr_page_get_prev(page, mtr) == FIL_NULL))
- || (page_get_n_recs(page) < 2)) {
+ if (page_get_data_size(page) - rec_size
+ < BTR_CUR_PAGE_COMPRESS_LIMIT(cursor->index)
+ || !page_has_siblings(page) || page_get_n_recs(page) < 2) {
/* The page fillfactor will drop below a predefined
minimum value, OR the level in the B-tree contains just
diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h
index fab934ca0ee..1d8690a3c90 100644
--- a/storage/innobase/include/btr0pcur.h
+++ b/storage/innobase/include/btr0pcur.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -136,20 +136,25 @@ btr_pcur_open_with_no_init_func(
may end up on the previous page of the
record! */
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
- NOTE that if has_search_latch != 0 then
- we maybe do not acquire a latch on the cursor
- page, but assume that the caller uses his
- btr search latch to protect the record! */
+ NOTE that if ahi_latch then we might not
+ acquire a cursor page latch, but assume
+ that the ahi_latch protects the record! */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
- ulint has_search_latch,
- /*!< in: latch mode the caller
- currently has on search system:
- RW_S_LATCH, or 0 */
+#ifdef BTR_CUR_HASH_ADAPT
+ rw_lock_t* ahi_latch,
+ /*!< in: adaptive hash index latch held
+ by the caller, or NULL if none */
+#endif /* BTR_CUR_HASH_ADAPT */
const char* file, /*!< in: file name */
unsigned line, /*!< in: line where called */
mtr_t* mtr); /*!< in: mtr */
-#define btr_pcur_open_with_no_init(ix,t,md,l,cur,has,m) \
- btr_pcur_open_with_no_init_func(ix,t,md,l,cur,has,__FILE__,__LINE__,m)
+#ifdef BTR_CUR_HASH_ADAPT
+# define btr_pcur_open_with_no_init(ix,t,md,l,cur,ahi,m) \
+ btr_pcur_open_with_no_init_func(ix,t,md,l,cur,ahi,__FILE__,__LINE__,m)
+#else /* BTR_CUR_HASH_ADAPT */
+# define btr_pcur_open_with_no_init(ix,t,md,l,cur,ahi,m) \
+ btr_pcur_open_with_no_init_func(ix,t,md,l,cur,__FILE__,__LINE__,m)
+#endif /* BTR_CUR_HASH_ADAPT */
/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
diff --git a/storage/innobase/include/btr0pcur.ic b/storage/innobase/include/btr0pcur.ic
index 4490942a2bb..e12564fe547 100644
--- a/storage/innobase/include/btr0pcur.ic
+++ b/storage/innobase/include/btr0pcur.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -219,12 +219,8 @@ btr_pcur_is_before_first_in_tree(
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
- if (btr_page_get_prev(btr_pcur_get_page(cursor), mtr) != FIL_NULL) {
-
- return(FALSE);
- }
-
- return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor)));
+ return !page_has_prev(btr_pcur_get_page(cursor))
+ && page_cur_is_before_first(btr_pcur_get_page_cur(cursor));
}
/*********************************************************//**
@@ -240,12 +236,8 @@ btr_pcur_is_after_last_in_tree(
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
- if (btr_page_get_next(btr_pcur_get_page(cursor), mtr) != FIL_NULL) {
-
- return(FALSE);
- }
-
- return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor)));
+ return !page_has_next(btr_pcur_get_page(cursor))
+ && page_cur_is_after_last(btr_pcur_get_page_cur(cursor));
}
/*********************************************************//**
@@ -454,9 +446,12 @@ btr_pcur_open_low(
ut_ad(!dict_index_is_spatial(index));
- err = btr_cur_search_to_nth_level(
- index, level, tuple, mode, latch_mode,
- btr_cursor, 0, file, line, mtr, autoinc);
+ err = btr_cur_search_to_nth_level_func(
+ index, level, tuple, mode, latch_mode, btr_cursor,
+#ifdef BTR_CUR_HASH_ADAPT
+ NULL,
+#endif /* BTR_CUR_HASH_ADAPT */
+ file, line, mtr, autoinc);
if (err != DB_SUCCESS) {
ib::warn() << " Error code: " << err
@@ -491,15 +486,15 @@ btr_pcur_open_with_no_init_func(
may end up on the previous page of the
record! */
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
- NOTE that if has_search_latch != 0 then
- we maybe do not acquire a latch on the cursor
- page, but assume that the caller uses his
- btr search latch to protect the record! */
+ NOTE that if ahi_latch then we might not
+ acquire a cursor page latch, but assume
+ that the ahi_latch protects the record! */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
- ulint has_search_latch,
- /*!< in: latch mode the caller
- currently has on search system:
- RW_S_LATCH, or 0 */
+#ifdef BTR_CUR_HASH_ADAPT
+ rw_lock_t* ahi_latch,
+ /*!< in: adaptive hash index latch held
+ by the caller, or NULL if none */
+#endif /* BTR_CUR_HASH_ADAPT */
const char* file, /*!< in: file name */
unsigned line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */
@@ -514,9 +509,12 @@ btr_pcur_open_with_no_init_func(
btr_cursor = btr_pcur_get_btr_cur(cursor);
- err = btr_cur_search_to_nth_level(
+ err = btr_cur_search_to_nth_level_func(
index, 0, tuple, mode, latch_mode, btr_cursor,
- has_search_latch, file, line, mtr);
+#ifdef BTR_CUR_HASH_ADAPT
+ ahi_latch,
+#endif /* BTR_CUR_HASH_ADAPT */
+ file, line, mtr);
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
index bd1a72fc3ac..f32429800f8 100644
--- a/storage/innobase/include/btr0sea.h
+++ b/storage/innobase/include/btr0sea.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -91,12 +91,11 @@ both have sensible values.
we assume the caller uses his search latch
to protect the record!
@param[out] cursor tree cursor
-@param[in] has_search_latch
- latch mode the caller currently has on
- search system: RW_S/X_LATCH or 0
+@param[in] ahi_latch the adaptive hash index latch being held,
+ or NULL
@param[in] mtr mini transaction
-@return TRUE if succeeded */
-ibool
+@return whether the search succeeded */
+bool
btr_search_guess_on_hash(
dict_index_t* index,
btr_search_t* info,
@@ -104,7 +103,7 @@ btr_search_guess_on_hash(
ulint mode,
ulint latch_mode,
btr_cur_t* cursor,
- ulint has_search_latch,
+ rw_lock_t* ahi_latch,
mtr_t* mtr);
/** Move or delete hash entries for moved records, usually in a page split.
@@ -140,17 +139,19 @@ btr_search_drop_page_hash_when_freed(
/** Updates the page hash index when a single record is inserted on a page.
@param[in] cursor cursor which was positioned to the place to insert
using btr_cur_search_, and the new record has been
- inserted next to the cursor. */
+ inserted next to the cursor.
+@param[in] ahi_latch the adaptive hash index latch */
void
-btr_search_update_hash_node_on_insert(btr_cur_t* cursor);
+btr_search_update_hash_node_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch);
/** Updates the page hash index when a single record is inserted on a page.
-@param[in] cursor cursor which was positioned to the
+@param[in,out] cursor cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
- to the cursor */
+ to the cursor
+@param[in] ahi_latch the adaptive hash index latch */
void
-btr_search_update_hash_on_insert(btr_cur_t* cursor);
+btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch);
/** Updates the page hash index when a single record is deleted from a page.
@param[in] cursor cursor which was positioned on the record to delete
@@ -163,18 +164,6 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor);
bool
btr_search_validate();
-/** X-Lock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_x_lock(const dict_index_t* index);
-
-/** X-Unlock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_x_unlock(const dict_index_t* index);
-
/** Lock all search latches in exclusive mode. */
UNIV_INLINE
void
@@ -185,18 +174,6 @@ UNIV_INLINE
void
btr_search_x_unlock_all();
-/** S-Lock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_s_lock(const dict_index_t* index);
-
-/** S-Unlock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_s_unlock(const dict_index_t* index);
-
/** Lock all search latches in shared mode. */
UNIV_INLINE
void
@@ -243,15 +220,11 @@ btr_get_search_table(const dict_index_t* index);
#else /* BTR_CUR_HASH_ADAPT */
# define btr_search_sys_create(size)
# define btr_search_drop_page_hash_index(block)
-# define btr_search_s_lock(index)
-# define btr_search_s_unlock(index)
# define btr_search_s_lock_all(index)
# define btr_search_s_unlock_all(index)
-# define btr_search_x_lock(index)
-# define btr_search_x_unlock(index)
# define btr_search_info_update(index, cursor)
# define btr_search_move_or_delete_hash_entries(new_block, block)
-# define btr_search_update_hash_on_insert(cursor)
+# define btr_search_update_hash_on_insert(cursor, ahi_latch)
# define btr_search_update_hash_on_delete(cursor)
# define btr_search_sys_resize(hash_size)
#endif /* BTR_CUR_HASH_ADAPT */
@@ -312,7 +285,7 @@ struct btr_search_t{
ulint n_bytes; /*!< recommended prefix: number of bytes in
an incomplete field
@see BTR_PAGE_MAX_REC_SIZE */
- ibool left_side; /*!< TRUE or FALSE, depending on whether
+ bool left_side; /*!< true or false, depending on whether
the leftmost record of several records with
the same prefix should be indexed in the
hash index */
diff --git a/storage/innobase/include/btr0sea.ic b/storage/innobase/include/btr0sea.ic
index b5a7536a2b4..e0052a98639 100644
--- a/storage/innobase/include/btr0sea.ic
+++ b/storage/innobase/include/btr0sea.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, 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
the terms of the GNU General Public License as published by the Free Software
@@ -45,13 +46,11 @@ btr_search_info_create(mem_heap_t* heap)
}
#ifdef BTR_CUR_HASH_ADAPT
-/*********************************************************************//**
-Updates the search info. */
+/** Updates the search info.
+@param[in,out] info search info
+@param[in,out] cursor cursor which was just positioned */
void
-btr_search_info_update_slow(
-/*========================*/
- btr_search_t* info, /*!< in/out: search info */
- btr_cur_t* cursor);/*!< in: cursor which was just positioned */
+btr_search_info_update_slow(btr_search_t* info, btr_cur_t* cursor);
/*********************************************************************//**
Updates the search info. */
@@ -62,8 +61,8 @@ btr_search_info_update(
dict_index_t* index, /*!< in: index of the cursor */
btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
- ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
+ ut_ad(!btr_search_own_any(RW_LOCK_S));
+ ut_ad(!btr_search_own_any(RW_LOCK_X));
if (dict_index_is_spatial(index) || !btr_search_enabled) {
return;
@@ -87,24 +86,6 @@ btr_search_info_update(
btr_search_info_update_slow(info, cursor);
}
-/** X-Lock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_x_lock(const dict_index_t* index)
-{
- rw_lock_x_lock(btr_get_search_latch(index));
-}
-
-/** X-Unlock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_x_unlock(const dict_index_t* index)
-{
- rw_lock_x_unlock(btr_get_search_latch(index));
-}
-
/** Lock all search latches in exclusive mode. */
UNIV_INLINE
void
@@ -125,24 +106,6 @@ btr_search_x_unlock_all()
}
}
-/** S-Lock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_s_lock(const dict_index_t* index)
-{
- rw_lock_s_lock(btr_get_search_latch(index));
-}
-
-/** S-Unlock the search latch (corresponding to given index)
-@param[in] index index handler */
-UNIV_INLINE
-void
-btr_search_s_unlock(const dict_index_t* index)
-{
- rw_lock_s_unlock(btr_get_search_latch(index));
-}
-
/** Lock all search latches in shared mode. */
UNIV_INLINE
void
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 4a54c30629b..0cef7862332 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1738,7 +1738,7 @@ struct buf_block_t{
used in debugging */
ibool in_withdraw_list;
#endif /* UNIV_DEBUG */
- unsigned lock_hash_val:32;/*!< hashed value of the page address
+ uint32_t lock_hash_val; /*!< hashed value of the page address
in the record lock hash table;
protected by buf_block_t::lock
(or buf_block_t::mutex, buf_pool->mutex
@@ -1827,7 +1827,7 @@ struct buf_block_t{
} while (0)
# define assert_block_ahi_valid(block) \
ut_a((block)->index \
- || my_atomic_addlint(&(block)->n_pointers, 0) == 0)
+ || my_atomic_loadlint(&(block)->n_pointers) == 0)
# else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
# define assert_block_ahi_empty(block) /* nothing */
# define assert_block_ahi_empty_on_init(block) /* nothing */
@@ -2351,8 +2351,12 @@ Use these instead of accessing buf_pool->mutex directly. */
/** Get appropriate page_hash_lock. */
-# define buf_page_hash_lock_get(buf_pool, page_id) \
- hash_get_lock((buf_pool)->page_hash, (page_id).fold())
+UNIV_INLINE
+rw_lock_t*
+buf_page_hash_lock_get(const buf_pool_t* buf_pool, const page_id_t& page_id)
+{
+ return hash_get_lock(buf_pool->page_hash, page_id.fold());
+}
/** If not appropriate page_hash_lock, relock until appropriate. */
# define buf_page_hash_lock_s_confirm(hash_lock, buf_pool, page_id)\
diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h
index 44cd5b5f772..81a1fb757c7 100644
--- a/storage/innobase/include/buf0flu.h
+++ b/storage/innobase/include/buf0flu.h
@@ -369,6 +369,12 @@ public:
|| m_interrupted);
}
+ /** @return whether to flush only some pages of the tablespace */
+ bool is_partial_flush() const { return m_stage != NULL; }
+
+ /** @return whether the operation was interrupted */
+ bool is_interrupted() const { return m_interrupted; }
+
/** Interrupt observer not to wait. */
void interrupted()
{
@@ -381,7 +387,6 @@ public:
/** Flush dirty pages. */
void flush();
-
/** Notify observer of flushing a page
@param[in] buf_pool buffer pool instance
@param[in] bpage buffer page to flush */
@@ -397,10 +402,10 @@ public:
buf_page_t* bpage);
private:
/** Table space id */
- ulint m_space_id;
+ const ulint m_space_id;
/** Trx instance */
- trx_t* m_trx;
+ trx_t* const m_trx;
/** Performance schema accounting object, used by ALTER TABLE.
If not NULL, then stage->begin_phase_flush() will be called initially,
diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
index 54c001ce478..f6a7695a2b5 100644
--- a/storage/innobase/include/buf0lru.h
+++ b/storage/innobase/include/buf0lru.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, 2018, 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
@@ -52,12 +52,16 @@ These are low-level functions
/** Empty the flush list for all pages belonging to a tablespace.
@param[in] id tablespace identifier
-@param[in] trx transaction, for checking for user interrupt;
- or NULL if nothing is to be written
-@param[in] drop_ahi whether to drop the adaptive hash index */
-UNIV_INTERN
+@param[in,out] observer flush observer,
+ or NULL if nothing is to be written */
void
-buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi=false);
+buf_LRU_flush_or_remove_pages(
+ ulint id,
+ FlushObserver* observer
+#ifdef BTR_CUR_HASH_ADAPT
+ , bool drop_ahi = false /*!< whether to drop the adaptive hash index */
+#endif /* BTR_CUR_HASH_ADAPT */
+ );
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h
index a0b3059ad40..d3361ad8b3b 100644
--- a/storage/innobase/include/data0data.h
+++ b/storage/innobase/include/data0data.h
@@ -591,6 +591,22 @@ struct dfield_t{
@param[in,out] heap memory heap in which the clone will be created
@return the cloned object */
dfield_t* clone(mem_heap_t* heap) const;
+
+ /** @return system field indicates history row */
+ bool vers_history_row() const
+ {
+ ut_ad(type.vers_sys_end());
+ if (type.mtype == DATA_FIXBINARY) {
+ ut_ad(len == sizeof timestamp_max_bytes);
+ return 0 != memcmp(data, timestamp_max_bytes, len);
+ } else {
+ ut_ad(type.mtype == DATA_INT);
+ ut_ad(len == sizeof trx_id_max_bytes);
+ return 0 != memcmp(data, trx_id_max_bytes, len);
+ }
+ ut_ad(0);
+ return false;
+ }
};
/** Structure for an SQL data tuple of fields (logical record) */
diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h
index bd2a15fe881..7e1c362cf8d 100644
--- a/storage/innobase/include/data0type.h
+++ b/storage/innobase/include/data0type.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -189,6 +189,12 @@ be less than 256 */
for shorter VARCHARs MySQL uses only 1 byte */
#define DATA_VIRTUAL 8192U /* Virtual column */
+/** System Versioning */
+#define DATA_VERS_START 16384U /* start system field */
+#define DATA_VERS_END 32768U /* end system field */
+/** system-versioned user data column */
+#define DATA_VERSIONED (DATA_VERS_START|DATA_VERS_END)
+
/** Check whether locking is disabled (never). */
#define dict_table_is_locking_disabled(table) false
@@ -203,16 +209,7 @@ store the charset-collation number; one byte is left unused, though */
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
/* Maximum multi-byte character length in bytes, plus 1 */
-#define DATA_MBMAX 5
-
-/* Pack mbminlen, mbmaxlen to mbminmaxlen. */
-#define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \
- unsigned((mbmaxlen) * DATA_MBMAX + (mbminlen))
-/* Get mbminlen from mbminmaxlen. */
-#define DATA_MBMINLEN(mbminmaxlen) \
- unsigned(UNIV_EXPECT((mbminmaxlen) % DATA_MBMAX, 1))
-/* Get mbmaxlen from mbminmaxlen. */
-#define DATA_MBMAXLEN(mbminmaxlen) unsigned((mbminmaxlen) / DATA_MBMAX)
+#define DATA_MBMAX 8
/* For checking if mtype is GEOMETRY datatype */
#define DATA_GEOMETRY_MTYPE(mtype) ((mtype) == DATA_GEOMETRY)
@@ -255,8 +252,10 @@ ulint
dtype_get_at_most_n_mbchars(
/*========================*/
ulint prtype, /*!< in: precise type */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of
+ a multi-byte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of
+ a multi-byte character, in bytes */
ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
@@ -399,19 +398,6 @@ ulint
dtype_get_mbmaxlen(
/*===============*/
const dtype_t* type); /*!< in: type */
-/*********************************************************************//**
-Sets the minimum and maximum length of a character, in bytes. */
-UNIV_INLINE
-void
-dtype_set_mbminmaxlen(
-/*==================*/
- dtype_t* type, /*!< in/out: type */
- ulint mbminlen, /*!< in: minimum length of a char,
- in bytes, or 0 if this is not
- a character type */
- ulint mbmaxlen); /*!< in: maximum length of a char,
- in bytes, or 0 if this is not
- a character type */
/***********************************************************************//**
Returns the size of a fixed size data type, 0 if not a fixed size type.
@return fixed size, or 0 */
@@ -422,7 +408,9 @@ dtype_get_fixed_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of a
+ ulint mbminlen, /*!< in: minimum length of a
+ multibyte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of a
multibyte character, in bytes */
ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
@@ -436,8 +424,8 @@ dtype_get_min_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen); /*!< in: minimum and maximum length of a
- multibyte character */
+ ulint mbminlen, /*!< in: minimum length of a character */
+ ulint mbmaxlen); /*!< in: maximum length of a character */
/***********************************************************************//**
Returns the maximum size of a data type. Note: types in system tables may be
incomplete and return incorrect information.
@@ -549,13 +537,30 @@ struct dtype_t{
string data (in addition to
the string, MySQL uses 1 or 2
bytes to store the string length) */
- unsigned mbminmaxlen:5; /*!< minimum and maximum length of a
- character, in bytes;
- DATA_MBMINMAXLEN(mbminlen,mbmaxlen);
- mbminlen=DATA_MBMINLEN(mbminmaxlen);
- mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */
+ unsigned mbminlen:3; /*!< minimum length of a character,
+ in bytes */
+ unsigned mbmaxlen:3; /*!< maximum length of a character,
+ in bytes */
+
+ /** @return whether this is system field */
+ bool vers_sys_field() const { return prtype & DATA_VERSIONED; }
+ /** @return whether this is system versioned user field */
+ bool is_versioned() const { return !(~prtype & DATA_VERSIONED); }
+ /** @return whether this is the system field start */
+ bool vers_sys_start() const
+ {
+ return (prtype & DATA_VERSIONED) == DATA_VERS_START;
+ }
+ /** @return whether this is the system field end */
+ bool vers_sys_end() const
+ {
+ return (prtype & DATA_VERSIONED) == DATA_VERS_END;
+ }
};
+/** The DB_TRX_ID,DB_ROLL_PTR values for "no history is available" */
+extern const byte reset_trx_id[DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN];
+
#include "data0type.ic"
#endif
diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic
index a68f4829561..c0b32953cff 100644
--- a/storage/innobase/include/data0type.ic
+++ b/storage/innobase/include/data0type.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -101,27 +101,6 @@ dtype_get_mblen(
}
/*********************************************************************//**
-Sets the minimum and maximum length of a character, in bytes. */
-UNIV_INLINE
-void
-dtype_set_mbminmaxlen(
-/*==================*/
- dtype_t* type, /*!< in/out: type */
- ulint mbminlen, /*!< in: minimum length of a char,
- in bytes, or 0 if this is not
- a character type */
- ulint mbmaxlen) /*!< in: maximum length of a char,
- in bytes, or 0 if this is not
- a character type */
-{
- ut_ad(mbminlen < DATA_MBMAX);
- ut_ad(mbmaxlen < DATA_MBMAX);
- ut_ad(mbminlen <= mbmaxlen);
-
- type->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen);
-}
-
-/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
@@ -133,7 +112,8 @@ dtype_set_mblen(
ulint mbmaxlen;
dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen);
- dtype_set_mbminmaxlen(type, mbminlen, mbmaxlen);
+ type->mbminlen = mbminlen;
+ type->mbmaxlen = mbmaxlen;
ut_ad(dtype_validate(type));
}
@@ -225,8 +205,7 @@ dtype_get_mbminlen(
/*===============*/
const dtype_t* type) /*!< in: type */
{
- ut_ad(type);
- return(DATA_MBMINLEN(type->mbminmaxlen));
+ return type->mbminlen;
}
/*********************************************************************//**
Gets the maximum length of a character, in bytes.
@@ -238,8 +217,7 @@ dtype_get_mbmaxlen(
/*===============*/
const dtype_t* type) /*!< in: type */
{
- ut_ad(type);
- return(DATA_MBMAXLEN(type->mbminmaxlen));
+ return type->mbmaxlen;
}
/**********************************************************************//**
@@ -387,79 +365,79 @@ dtype_sql_name(
#define APPEND_UNSIGNED() \
do { \
if (prtype & DATA_UNSIGNED) { \
- ut_snprintf(name + strlen(name), \
+ snprintf(name + strlen(name), \
name_sz - strlen(name), \
" UNSIGNED"); \
} \
} while (0)
- ut_snprintf(name, name_sz, "UNKNOWN");
+ snprintf(name, name_sz, "UNKNOWN");
switch (mtype) {
case DATA_INT:
switch (len) {
case 1:
- ut_snprintf(name, name_sz, "TINYINT");
+ snprintf(name, name_sz, "TINYINT");
break;
case 2:
- ut_snprintf(name, name_sz, "SMALLINT");
+ snprintf(name, name_sz, "SMALLINT");
break;
case 3:
- ut_snprintf(name, name_sz, "MEDIUMINT");
+ snprintf(name, name_sz, "MEDIUMINT");
break;
case 4:
- ut_snprintf(name, name_sz, "INT");
+ snprintf(name, name_sz, "INT");
break;
case 8:
- ut_snprintf(name, name_sz, "BIGINT");
+ snprintf(name, name_sz, "BIGINT");
break;
}
APPEND_UNSIGNED();
break;
case DATA_FLOAT:
- ut_snprintf(name, name_sz, "FLOAT");
+ snprintf(name, name_sz, "FLOAT");
APPEND_UNSIGNED();
break;
case DATA_DOUBLE:
- ut_snprintf(name, name_sz, "DOUBLE");
+ snprintf(name, name_sz, "DOUBLE");
APPEND_UNSIGNED();
break;
case DATA_FIXBINARY:
- ut_snprintf(name, name_sz, "BINARY(%u)", len);
+ snprintf(name, name_sz, "BINARY(%u)", len);
break;
case DATA_CHAR:
case DATA_MYSQL:
- ut_snprintf(name, name_sz, "CHAR(%u)", len);
+ snprintf(name, name_sz, "CHAR(%u)", len);
break;
case DATA_VARCHAR:
case DATA_VARMYSQL:
- ut_snprintf(name, name_sz, "VARCHAR(%u)", len);
+ snprintf(name, name_sz, "VARCHAR(%u)", len);
break;
case DATA_BINARY:
- ut_snprintf(name, name_sz, "VARBINARY(%u)", len);
+ snprintf(name, name_sz, "VARBINARY(%u)", len);
break;
case DATA_GEOMETRY:
- ut_snprintf(name, name_sz, "GEOMETRY");
+ snprintf(name, name_sz, "GEOMETRY");
break;
case DATA_BLOB:
switch (len) {
case 9:
- ut_snprintf(name, name_sz, "TINYBLOB");
+ snprintf(name, name_sz, "TINYBLOB");
break;
case 10:
- ut_snprintf(name, name_sz, "BLOB");
+ snprintf(name, name_sz, "BLOB");
break;
case 11:
- ut_snprintf(name, name_sz, "MEDIUMBLOB");
+ snprintf(name, name_sz, "MEDIUMBLOB");
break;
case 12:
- ut_snprintf(name, name_sz, "LONGBLOB");
+ snprintf(name, name_sz, "LONGBLOB");
break;
}
}
if (prtype & DATA_NOT_NULL) {
- ut_snprintf(name + strlen(name),
+ snprintf(name + strlen(name),
name_sz - strlen(name),
" NOT NULL");
}
@@ -477,8 +455,10 @@ dtype_get_fixed_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multibyte character, in bytes */
+ ulint mbminlen, /*!< in: minimum length of a
+ multibyte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of a
+ multibyte character, in bytes */
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
switch (mtype) {
@@ -518,11 +498,10 @@ dtype_get_fixed_size_low(
dtype_get_charset_coll(prtype),
&i_mbminlen, &i_mbmaxlen);
- ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen)
- == mbminmaxlen);
+ ut_ad(i_mbminlen == mbminlen);
+ ut_ad(i_mbmaxlen == mbmaxlen);
#endif /* UNIV_DEBUG */
- if (DATA_MBMINLEN(mbminmaxlen)
- == DATA_MBMAXLEN(mbminmaxlen)) {
+ if (mbminlen == mbmaxlen) {
return(len);
}
}
@@ -552,8 +531,8 @@ dtype_get_min_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen) /*!< in: minimum and maximum length of a
- multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of a character */
+ ulint mbmaxlen) /*!< in: maximum length of a character */
{
switch (mtype) {
case DATA_SYS:
@@ -583,9 +562,6 @@ dtype_get_min_size_low(
if (prtype & DATA_BINARY_TYPE) {
return(len);
} else {
- ulint mbminlen = DATA_MBMINLEN(mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen);
-
if (mbminlen == mbmaxlen) {
return(len);
}
@@ -656,5 +632,5 @@ dtype_get_sql_null_size(
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- type->mbminmaxlen, comp));
+ type->mbminlen, type->mbmaxlen, comp));
}
diff --git a/storage/innobase/include/dict0defrag_bg.h b/storage/innobase/include/dict0defrag_bg.h
index eb2a6e6824f..8d77a461dc9 100644
--- a/storage/innobase/include/dict0defrag_bg.h
+++ b/storage/innobase/include/dict0defrag_bg.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2016, MariaDB Corporation. All rights Reserved.
+Copyright (c) 2016, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -88,6 +88,5 @@ Save defragmentation stats for a given index.
dberr_t
dict_stats_save_defrag_stats(
/*============================*/
- dict_index_t* index) /*!< in: index */
- MY_ATTRIBUTE((warn_unused_result));
+ dict_index_t* index); /*!< in: index */
#endif /* dict0defrag_bg_h */
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index f14487f09d0..4356ee113de 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -182,18 +182,6 @@ dict_col_get_mbmaxlen(
const dict_col_t* col) /*!< in: column */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
-Sets the minimum and maximum number of bytes per character. */
-UNIV_INLINE
-void
-dict_col_set_mbminmaxlen(
-/*=====================*/
- dict_col_t* col, /*!< in/out: column */
- ulint mbminlen, /*!< in: minimum multi-byte
- character size, in bytes */
- ulint mbmaxlen) /*!< in: minimum multi-byte
- character size, in bytes */
- MY_ATTRIBUTE((nonnull));
-/*********************************************************************//**
Gets the column data type. */
UNIV_INLINE
void
@@ -414,7 +402,7 @@ dict_table_rename_in_cache(
/*!< in: in ALTER TABLE we want
to preserve the original table name
in constraints which reference it */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((nonnull));
/** Removes an index from the dictionary cache.
@param[in,out] table table whose index to remove
@@ -929,7 +917,7 @@ dict_index_get_min_size(
Check whether the table uses the compact page format.
@return TRUE if table uses the compact page format */
UNIV_INLINE
-ibool
+bool
dict_table_is_comp(
/*===============*/
const dict_table_t* table) /*!< in: table */
@@ -1275,7 +1263,7 @@ Returns TRUE if the index contains a column or a prefix of that column.
@param[in] n column number
@param[in] is_virtual whether it is a virtual col
@return TRUE if contains the column or its prefix */
-ibool
+bool
dict_index_contains_col_or_prefix(
/*==============================*/
const dict_index_t* index, /*!< in: index */
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index 26918251d8b..e1c2c71bc0a 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -41,7 +41,7 @@ dict_col_get_mbminlen(
/*==================*/
const dict_col_t* col) /*!< in: column */
{
- return(DATA_MBMINLEN(col->mbminmaxlen));
+ return col->mbminlen;
}
/*********************************************************************//**
Gets the maximum number of bytes per character.
@@ -52,25 +52,7 @@ dict_col_get_mbmaxlen(
/*==================*/
const dict_col_t* col) /*!< in: column */
{
- return(DATA_MBMAXLEN(col->mbminmaxlen));
-}
-/*********************************************************************//**
-Sets the minimum and maximum number of bytes per character. */
-UNIV_INLINE
-void
-dict_col_set_mbminmaxlen(
-/*=====================*/
- dict_col_t* col, /*!< in/out: column */
- ulint mbminlen, /*!< in: minimum multi-byte
- character size, in bytes */
- ulint mbmaxlen) /*!< in: minimum multi-byte
- character size, in bytes */
-{
- ut_ad(mbminlen < DATA_MBMAX);
- ut_ad(mbmaxlen < DATA_MBMAX);
- ut_ad(mbminlen <= mbmaxlen);
-
- col->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen);
+ return col->mbmaxlen;
}
/*********************************************************************//**
Gets the column data type. */
@@ -87,7 +69,8 @@ dict_col_copy_type(
type->mtype = col->mtype;
type->prtype = col->prtype;
type->len = col->len;
- type->mbminmaxlen = col->mbminmaxlen;
+ type->mbminlen = col->mbminlen;
+ type->mbmaxlen = col->mbmaxlen;
}
#ifdef UNIV_DEBUG
@@ -107,7 +90,8 @@ dict_col_type_assert_equal(
ut_ad(col->mtype == type->mtype);
ut_ad(col->prtype == type->prtype);
//ut_ad(col->len == type->len);
- ut_ad(col->mbminmaxlen == type->mbminmaxlen);
+ ut_ad(col->mbminlen == type->mbminlen);
+ ut_ad(col->mbmaxlen == type->mbmaxlen);
return(TRUE);
}
@@ -123,7 +107,7 @@ dict_col_get_min_size(
const dict_col_t* col) /*!< in: column */
{
return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
- col->mbminmaxlen));
+ col->mbminlen, col->mbmaxlen));
}
/***********************************************************************//**
Returns the maximum size of the column.
@@ -147,7 +131,7 @@ dict_col_get_fixed_size(
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
- col->mbminmaxlen, comp));
+ col->mbminlen, col->mbmaxlen, comp));
}
/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
@@ -286,7 +270,7 @@ dict_index_is_clust(
const dict_index_t* index) /*!< in: index */
{
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
- return(index->is_clust());
+ return(index->type & DICT_CLUSTERED);
}
/** Check if index is auto-generated clustered index.
@@ -570,7 +554,7 @@ dict_table_get_sys_col_no(
Check whether the table uses the compact page format.
@return TRUE if table uses the compact page format */
UNIV_INLINE
-ibool
+bool
dict_table_is_comp(
/*===============*/
const dict_table_t* table) /*!< in: table */
@@ -581,7 +565,7 @@ dict_table_is_comp(
#error "DICT_TF_COMPACT must be 1"
#endif
- return(table->flags & DICT_TF_COMPACT);
+ return (table->flags & DICT_TF_COMPACT) != 0;
}
/************************************************************************
@@ -657,7 +641,7 @@ dict_tf_is_valid(
bit. For ROW_FORMAT=REDUNDANT, only the DATA_DIR flag
(which we cleared above) can be set. If any other flags
are set, the flags are invalid. */
- return(flags == 0);
+ return(flags == 0 || flags == DICT_TF_MASK_NO_ROLLBACK);
}
return(dict_tf_is_valid_not_redundant(flags));
diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h
index 22fd27c2484..9ba42007568 100644
--- a/storage/innobase/include/dict0load.h
+++ b/storage/innobase/include/dict0load.h
@@ -193,8 +193,7 @@ dict_getnext_system(
mtr_t* mtr); /*!< in: the mini-transaction */
/********************************************************************//**
This function processes one SYS_TABLES record and populate the dict_table_t
-struct for the table. Extracted out of dict_print() to be used by
-both monitor table output and information schema innodb_sys_tables output.
+struct for the table.
@return error message, or NULL on success */
const char*
dict_process_sys_tables_rec_and_mtr_commit(
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 8dcd6bf2606..0bab513d051 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -298,7 +298,7 @@ result in recursive cascading calls. This defines the maximum number of
such cascading deletes/updates allowed. When exceeded, the delete from
parent table will fail, and user has to drop excessive foreign constraint
before proceeds. */
-#define FK_MAX_CASCADE_DEL 255
+#define FK_MAX_CASCADE_DEL 15
/**********************************************************************//**
Creates a table memory object.
@@ -617,11 +617,10 @@ struct dict_col_t{
the string, MySQL uses 1 or 2
bytes to store the string length) */
- unsigned mbminmaxlen:5; /*!< minimum and maximum length of a
- character, in bytes;
- DATA_MBMINMAXLEN(mbminlen,mbmaxlen);
- mbminlen=DATA_MBMINLEN(mbminmaxlen);
- mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */
+ unsigned mbminlen:3; /*!< minimum length of a
+ character, in bytes */
+ unsigned mbmaxlen:3; /*!< maximum length of a
+ character, in bytes */
/*----------------------*/
/* End of definitions copied from dtype_t */
/* @} */
@@ -652,6 +651,22 @@ struct dict_col_t{
bool is_virtual() const { return prtype & DATA_VIRTUAL; }
/** @return whether NULL is an allowed value for this column */
bool is_nullable() const { return !(prtype & DATA_NOT_NULL); }
+
+ /** @return whether this is system field */
+ bool vers_sys_field() const { return prtype & DATA_VERSIONED; }
+ /** @return whether this is system versioned */
+ bool is_versioned() const { return !(~prtype & DATA_VERSIONED); }
+ /** @return whether this is the system version start */
+ bool vers_sys_start() const
+ {
+ return (prtype & DATA_VERSIONED) == DATA_VERS_START;
+ }
+ /** @return whether this is the system version end */
+ bool vers_sys_end() const
+ {
+ return (prtype & DATA_VERSIONED) == DATA_VERS_END;
+ }
+
/** @return whether this is an instantly-added column */
bool is_instant() const
{
@@ -1064,8 +1079,12 @@ struct dict_index_t{
/** @return whether instant ADD COLUMN is in effect */
inline bool is_instant() const;
- /** @return whether the index is the clustered index */
- bool is_clust() const { return type & DICT_CLUSTERED; }
+ /** @return whether the index is the primary key index
+ (not the clustered index of the change buffer) */
+ bool is_primary() const
+ {
+ return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF));
+ }
/** Determine how many fields of a given prefix can be set NULL.
@param[in] n_prefix number of fields in the prefix
@@ -1091,7 +1110,7 @@ struct dict_index_t{
@param[out] len value length (in bytes), or UNIV_SQL_NULL
@return default value
@retval NULL if the default value is SQL NULL (len=UNIV_SQL_NULL) */
- const byte* instant_field_value(uint n, ulint* len) const
+ const byte* instant_field_value(ulint n, ulint* len) const
{
DBUG_ASSERT(is_instant() || id == DICT_INDEXES_ID);
DBUG_ASSERT(n + (id == DICT_INDEXES_ID) >= n_core_fields);
@@ -1107,7 +1126,7 @@ struct dict_index_t{
Protected by index root page x-latch or table X-lock. */
void remove_instant()
{
- DBUG_ASSERT(is_clust());
+ DBUG_ASSERT(is_primary());
if (!is_instant()) {
return;
}
@@ -1117,6 +1136,20 @@ struct dict_index_t{
n_core_fields = n_fields;
n_core_null_bytes = UT_BITS_IN_BYTES(n_nullable);
}
+
+ /** Check if record in clustered index is historical row.
+ @param[in] rec clustered row
+ @param[in] offsets offsets
+ @return true if row is historical */
+ bool
+ vers_history_row(const rec_t* rec, const ulint* offsets);
+
+ /** Check if record in secondary index is historical row.
+ @param[in] rec record in a secondary index
+ @param[out] history_row true if row is historical
+ @return true on error */
+ bool
+ vers_history_row(const rec_t* rec, bool &history_row);
};
/** The status of online index creation */
@@ -1512,6 +1545,29 @@ struct dict_table_t {
/** Add the table definition to the data dictionary cache */
void add_to_cache();
+ bool versioned() const { return vers_start || vers_end; }
+ bool versioned_by_id() const
+ {
+ return vers_start && cols[vers_start].mtype == DATA_INT;
+ }
+
+ void inc_fk_checks()
+ {
+#ifdef UNIV_DEBUG
+ lint fk_checks=
+#endif
+ my_atomic_addlint(&n_foreign_key_checks_running, 1);
+ ut_ad(fk_checks >= 0);
+ }
+ void dec_fk_checks()
+ {
+#ifdef UNIV_DEBUG
+ lint fk_checks=
+#endif
+ my_atomic_addlint(&n_foreign_key_checks_running, -1);
+ ut_ad(fk_checks > 0);
+ }
+
/** Id of the table. */
table_id_t id;
@@ -1556,6 +1612,13 @@ struct dict_table_t {
Use DICT_TF2_FLAG_IS_SET() to parse this flag. */
unsigned flags2:DICT_TF2_BITS;
+ /** TRUE if the table is an intermediate table during copy alter
+ operation or a partition/subpartition which is required for copying
+ data and skip the undo log for insertion of row in the table.
+ This variable will be set and unset during extra(), or during the
+ process of altering partitions */
+ unsigned skip_alter_undo:1;
+
/*!< whether this is in a single-table tablespace and the .ibd
file is missing or page decryption failed and page is corrupted */
unsigned file_unreadable:1;
@@ -1625,7 +1688,10 @@ struct dict_table_t {
/** Virtual column names */
const char* v_col_names;
-
+ unsigned vers_start:10;
+ /*!< System Versioning: row start col index */
+ unsigned vers_end:10;
+ /*!< System Versioning: row end col index */
bool is_system_db;
/*!< True if the table belongs to a system
database (mysql, information_schema or
@@ -1762,7 +1828,7 @@ struct dict_table_t {
/** How many rows are modified since last stats recalc. When a row is
inserted, updated, or deleted, we add 1 to this number; we calculate
new estimates for the table and the indexes if the table has changed
- too much, see row_update_statistics_if_needed(). The counter is reset
+ too much, see dict_stats_update_if_needed(). The counter is reset
to zero at statistics calculation. This counter is not protected by
any latch, because this is only used for heuristics. */
ib_uint64_t stat_modified_counter;
@@ -1842,7 +1908,7 @@ struct dict_table_t {
ulong n_waiting_or_granted_auto_inc_locks;
/** The transaction that currently holds the the AUTOINC lock on this
- table. Protected by lock_sys->mutex. */
+ table. Protected by lock_sys.mutex. */
const trx_t* autoinc_trx;
/* @} */
@@ -1857,7 +1923,7 @@ struct dict_table_t {
/** Count of the number of record locks on this table. We use this to
determine whether we can evict the table from the dictionary cache.
- It is protected by lock_sys->mutex. */
+ It is protected by lock_sys.mutex. */
ulint n_rec_locks;
#ifndef DBUG_ASSERT_EXISTS
@@ -1869,7 +1935,7 @@ private:
ulint n_ref_count;
public:
- /** List of locks on the table. Protected by lock_sys->mutex. */
+ /** List of locks on the table. Protected by lock_sys.mutex. */
table_lock_list_t locks;
/** Timestamp of the last modification of this table. */
@@ -2032,6 +2098,19 @@ dict_col_get_spatial_status(
return(spatial_status);
}
+/** Clear defragmentation summary. */
+inline void dict_stats_empty_defrag_summary(dict_index_t* index)
+{
+ index->stat_defrag_n_pages_freed = 0;
+}
+
+/** Clear defragmentation related index stats. */
+inline void dict_stats_empty_defrag_stats(dict_index_t* index)
+{
+ index->stat_defrag_modified_counter = 0;
+ index->stat_defrag_n_page_split = 0;
+}
+
#include "dict0mem.ic"
#endif /* dict0mem_h */
diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h
index 8846aeda7fd..5dd53c46d1b 100644
--- a/storage/innobase/include/dict0stats.h
+++ b/storage/innobase/include/dict0stats.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2009, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -177,6 +177,7 @@ dict_stats_rename_table(
char* errstr, /*!< out: error string if != DB_SUCCESS
is returned */
size_t errstr_sz); /*!< in: errstr size */
+#ifdef MYSQL_RENAME_INDEX
/*********************************************************************//**
Renames an index in InnoDB persistent stats storage.
This function creates its own transaction and commits it.
@@ -190,52 +191,7 @@ dict_stats_rename_index(
const char* old_index_name, /*!< in: old index name */
const char* new_index_name) /*!< in: new index name */
__attribute__((warn_unused_result));
-/*********************************************************************//**
-Save defragmentation result.
-@return DB_SUCCESS or error code */
-UNIV_INTERN
-dberr_t
-dict_stats_save_defrag_summary(
- dict_index_t* index); /*!< in: index */
-
-/*********************************************************************//**
-Save defragmentation stats for a given index.
-@return DB_SUCCESS or error code */
-UNIV_INTERN
-dberr_t
-dict_stats_save_defrag_stats(
- dict_index_t* index); /*!< in: index */
-
-/**********************************************************************//**
-Clear defragmentation summary. */
-UNIV_INTERN
-void
-dict_stats_empty_defrag_summary(
-/*==================*/
- dict_index_t* index); /*!< in: index to clear defragmentation stats */
-
-/**********************************************************************//**
-Clear defragmentation related index stats. */
-UNIV_INTERN
-void
-dict_stats_empty_defrag_stats(
-/*==================*/
- dict_index_t* index); /*!< in: index to clear defragmentation stats */
-
-
-/*********************************************************************//**
-Renames an index in InnoDB persistent stats storage.
-This function creates its own transaction and commits it.
-@return DB_SUCCESS or error code. DB_STATS_DO_NOT_EXIST will be returned
-if the persistent stats do not exist. */
-dberr_t
-dict_stats_rename_index(
-/*====================*/
- const dict_table_t* table, /*!< in: table whose index
- is renamed */
- const char* old_index_name, /*!< in: old index name */
- const char* new_index_name) /*!< in: new index name */
- MY_ATTRIBUTE((warn_unused_result));
+#endif /* MYSQL_RENAME_INDEX */
/** Save an individual index's statistic into the persistent statistics
storage.
@@ -252,7 +208,7 @@ rolled back only in the case of error, but not freed.
dberr_t
dict_stats_save_index_stat(
dict_index_t* index,
- lint last_update,
+ ib_time_t last_update,
const char* stat_name,
ib_uint64_t stat_value,
ib_uint64_t* sample_size,
diff --git a/storage/innobase/include/dict0stats.ic b/storage/innobase/include/dict0stats.ic
index 1efe5780b58..0d187ed90c7 100644
--- a/storage/innobase/include/dict0stats.ic
+++ b/storage/innobase/include/dict0stats.ic
@@ -79,7 +79,7 @@ dict_stats_is_persistent_enabled(const dict_table_t* table)
protect the ::stat_persistent with dict_table_stats_lock() like the
other ::stat_ members which would be too big performance penalty,
especially when this function is called from
- row_update_statistics_if_needed(). */
+ dict_stats_update_if_needed(). */
/* we rely on this read to be atomic */
ib_uint32_t stat_persistent = table->stat_persistent;
diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h
index 27b4cc0e694..6984351cc06 100644
--- a/storage/innobase/include/dict0types.h
+++ b/storage/innobase/include/dict0types.h
@@ -52,6 +52,13 @@ DICT_IBUF_ID_MIN plus the space id */
typedef ib_id_t table_id_t;
typedef ib_id_t index_id_t;
+/** Maximum transaction identifier */
+#define TRX_ID_MAX IB_ID_MAX
+
+/** The bit pattern corresponding to TRX_ID_MAX */
+extern const byte trx_id_max_bytes[8];
+extern const byte timestamp_max_bytes[7];
+
/** Error to ignore when we load table dictionary into memory. However,
the table and index will be marked as "corrupted", and caller will
be responsible to deal with corrupted table or index.
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 695c490ea94..724deb4e6bc 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -35,16 +35,11 @@ Created 10/25/1995 Heikki Tuuri
#include "page0size.h"
#include "ibuf0types.h"
-#include <list>
-#include <vector>
-
// Forward declaration
struct trx_t;
class page_id_t;
class truncate_t;
-typedef std::list<char*, ut_allocator<char*> > space_name_list_t;
-
/** Structure containing encryption specification */
struct fil_space_crypt_t;
@@ -885,6 +880,15 @@ fil_create_directory_for_tablename(
/*===============================*/
const char* name); /*!< in: name in the standard
'databasename/tablename' format */
+/** Write redo log for renaming a file.
+@param[in] space_id tablespace id
+@param[in] old_name tablespace file name
+@param[in] new_name tablespace file name after renaming */
+void
+fil_name_write_rename(
+ ulint space_id,
+ const char* old_name,
+ const char* new_name);
/********************************************************//**
Recreates table indexes by applying
TRUNCATE log record during recovery.
@@ -942,10 +946,14 @@ fil_table_accessible(const dict_table_t* table)
/** Delete a tablespace and associated .ibd file.
@param[in] id tablespace identifier
-@param[in] drop_ahi whether to drop the adaptive hash index
@return DB_SUCCESS or error */
dberr_t
-fil_delete_tablespace(ulint id, bool drop_ahi = false);
+fil_delete_tablespace(
+ ulint id
+#ifdef BTR_CUR_HASH_ADAPT
+ , bool drop_ahi = false /*!< whether to drop the adaptive hash index */
+#endif /* BTR_CUR_HASH_ADAPT */
+ );
/** Truncate the tablespace to needed size.
@param[in] space_id id of tablespace to truncate
@@ -1160,27 +1168,24 @@ fil_file_readdir_next_file(
os_file_dir_t dir, /*!< in: directory stream */
os_file_stat_t* info); /*!< in/out: buffer where the
info is returned */
-/*******************************************************************//**
-Returns true if a matching tablespace exists in the InnoDB tablespace 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.
+/** Determine if a matching tablespace exists in the InnoDB tablespace
+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] print_error_if_does_not_exist
+ Print detailed error information to the
+error log if a matching tablespace is not found from memory.
+@param[in] heap Heap memory
+@param[in] table_flags table flags
@return true if a matching tablespace exists in the memory cache */
bool
fil_space_for_table_exists_in_mem(
-/*==============================*/
- ulint id, /*!< in: space id */
- const char* name, /*!< in: table name in the standard
- 'databasename/tablename' format */
+ ulint id,
+ const char* name,
bool print_error_if_does_not_exist,
- /*!< in: print detailed error
- information to the .err log if a
- matching tablespace is not found from
- memory */
- bool adjust_space, /*!< in: whether to adjust space id
- when find table space mismatch */
- mem_heap_t* heap, /*!< in: heap memory */
- table_id_t table_id, /*!< in: table id */
- ulint table_flags); /*!< in: table flags */
+ mem_heap_t* heap,
+ ulint table_flags);
/** Try to extend a tablespace if it is smaller than the specified size.
@param[in,out] space tablespace
@@ -1503,18 +1508,6 @@ ulint
fil_space_get_id_by_name(
const char* tablespace);
-/**
-Iterate over all the spaces in the space list and fetch the
-tablespace names. It will return a copy of the name that must be
-freed by the caller using: delete[].
-@return DB_SUCCESS if all OK. */
-dberr_t
-fil_get_space_names(
-/*================*/
- space_name_list_t& space_name_list)
- /*!< in/out: Vector for collecting the names. */
- MY_ATTRIBUTE((warn_unused_result));
-
/** Generate redo log for swapping two .ibd files
@param[in] old_table old table
@param[in] new_table new table
diff --git a/storage/innobase/include/fsp0file.h b/storage/innobase/include/fsp0file.h
index 1f057be0877..68e9f687fcd 100644
--- a/storage/innobase/include/fsp0file.h
+++ b/storage/innobase/include/fsp0file.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -363,7 +364,7 @@ private:
@param[in] read_only_mode if true, then readonly mode checks
are enforced.
@return DB_SUCCESS or DB_IO_ERROR if page cannot be read */
- dberr_t read_first_page(bool read_first_page)
+ dberr_t read_first_page(bool read_only_mode)
MY_ATTRIBUTE((warn_unused_result));
/** Free the first page from memory when it is no longer needed. */
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index 813e34b43d3..362bdcb7fe6 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -1015,5 +1015,27 @@ fts_check_corrupt(
dict_table_t* base_table,
trx_t* trx);
+/** Fetch the document from tuple, tokenize the text data and
+insert the text data into fts auxiliary table and
+its cache. Moreover this tuple fields doesn't contain any information
+about externally stored field. This tuple contains data directly
+converted from mysql.
+@param[in] ftt FTS transaction table
+@param[in] doc_id doc id
+@param[in] tuple tuple from where data can be retrieved
+ and tuple should be arranged in table
+ schema order. */
+void
+fts_add_doc_from_tuple(
+ fts_trx_table_t*ftt,
+ doc_id_t doc_id,
+ const dtuple_t* tuple);
+
+/** Create an FTS trx.
+@param[in,out] trx InnoDB Transaction
+@return FTS transaction. */
+fts_trx_t*
+fts_trx_create(
+ trx_t* trx);
#endif /*!< fts0fts.h */
diff --git a/storage/innobase/include/ha0ha.h b/storage/innobase/include/ha0ha.h
index db53b6c6580..f5be654f490 100644
--- a/storage/innobase/include/ha0ha.h
+++ b/storage/innobase/include/ha0ha.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -198,13 +199,6 @@ ha_validate(
ulint start_index, /*!< in: start index */
ulint end_index); /*!< in: end index */
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
-/*************************************************************//**
-Prints info of a hash table. */
-void
-ha_print_info(
-/*==========*/
- FILE* file, /*!< in: file where to print */
- hash_table_t* table); /*!< in: hash table */
/** The hash table external chain node */
struct ha_node_t {
@@ -217,7 +211,7 @@ struct ha_node_t {
};
#endif /* BTR_CUR_HASH_ADAPT */
-#ifdef UNIV_DEBUG
+#if defined UNIV_DEBUG && defined BTR_CUR_HASH_ADAPT
/********************************************************************//**
Assert that the synchronization object in a hash operation involving
possible change in the hash table is held.
diff --git a/storage/innobase/include/ib0mutex.h b/storage/innobase/include/ib0mutex.h
index 76f02cc1521..20703a4a933 100644
--- a/storage/innobase/include/ib0mutex.h
+++ b/storage/innobase/include/ib0mutex.h
@@ -225,7 +225,7 @@ struct TTASFutexMutex {
return;
}
- ut_delay(ut_rnd_interval(0, max_delay));
+ ut_delay(max_delay);
}
for (n_waits= 0;; n_waits++) {
@@ -362,7 +362,7 @@ struct TTASMutex {
uint32_t n_spins = 0;
while (!try_lock()) {
- ut_delay(ut_rnd_interval(0, max_delay));
+ ut_delay(max_delay);
if (++n_spins == max_spins) {
os_thread_yield();
max_spins+= step;
@@ -516,7 +516,7 @@ struct TTASEventMutex {
sync_array_wait_event(sync_arr, cell);
}
} else {
- ut_delay(ut_rnd_interval(0, max_delay));
+ ut_delay(max_delay);
}
}
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 60b07f2fe72..462d0cd4051 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -65,23 +65,6 @@ ulint
lock_get_size(void);
/*===============*/
/*********************************************************************//**
-Creates the lock system at database start. */
-void
-lock_sys_create(
-/*============*/
- ulint n_cells); /*!< in: number of slots in lock hash table */
-/** Resize the lock hash table.
-@param[in] n_cells number of slots in lock hash table */
-void
-lock_sys_resize(
- ulint n_cells);
-
-/*********************************************************************//**
-Closes the lock system at database shutdown. */
-void
-lock_sys_close(void);
-/*================*/
-/*********************************************************************//**
Gets the heap_no of the smallest user record on a page.
@return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
UNIV_INLINE
@@ -296,7 +279,7 @@ lock_rec_insert_check_and_lock(
dict_index_t* index, /*!< in: index */
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr, /*!< in/out: mini-transaction */
- ibool* inherit)/*!< out: set to TRUE if the new
+ bool* inherit)/*!< out: set to true if the new
inserted record maybe should inherit
LOCK_GAP type locks from the successor
record */
@@ -511,18 +494,6 @@ void
lock_trx_release_locks(
/*===================*/
trx_t* trx); /*!< in/out: transaction */
-/*********************************************************************//**
-Removes locks on a table to be dropped or truncated.
-If remove_also_table_sx_locks is TRUE then table-level S and X locks are
-also removed in addition to other table-level and record-level locks.
-No lock, that is going to be removed, is allowed to be a wait lock. */
-void
-lock_remove_all_on_table(
-/*=====================*/
- dict_table_t* table, /*!< in: table to be dropped
- or truncated */
- ibool remove_also_table_sx_locks);/*!< in: also removes
- table S and X locks */
/*********************************************************************//**
Calculates the fold value of a page file address: used in inserting or
@@ -566,33 +537,9 @@ lock_rec_find_set_bit(
bit set */
/*********************************************************************//**
-Gets the source table of an ALTER TABLE transaction. The table must be
-covered by an IX or IS table lock.
-@return the source table of transaction, if it is covered by an IX or
-IS table lock; dest if there is no source table, and NULL if the
-transaction is locking more than two tables or an inconsistency is
-found */
-dict_table_t*
-lock_get_src_table(
-/*===============*/
- trx_t* trx, /*!< in: transaction */
- dict_table_t* dest, /*!< in: destination of ALTER TABLE */
- lock_mode* mode); /*!< out: lock mode of the source table */
-/*********************************************************************//**
-Determine if the given table is exclusively "owned" by the given
-transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
-on the table.
-@return TRUE if table is only locked by trx, with LOCK_IX, and
-possibly LOCK_AUTO_INC */
-ibool
-lock_is_table_exclusive(
-/*====================*/
- const dict_table_t* table, /*!< in: table */
- const trx_t* trx); /*!< in: transaction */
-/*********************************************************************//**
Checks if a lock request lock1 has to wait for request lock2.
-@return TRUE if lock1 has to wait for lock2 to be removed */
-ibool
+@return whether lock1 has to wait for lock2 to be removed */
+bool
lock_has_to_wait(
/*=============*/
const lock_t* lock1, /*!< in: waiting lock */
@@ -609,7 +556,7 @@ lock_report_trx_id_insanity(
const rec_t* rec, /*!< in: user record */
dict_index_t* index, /*!< in: index */
const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
- trx_id_t max_trx_id); /*!< in: trx_sys_get_max_trx_id() */
+ trx_id_t max_trx_id); /*!< in: trx_sys.get_max_trx_id() */
/*********************************************************************//**
Prints info of locks for all transactions.
@return FALSE if not able to obtain lock mutex and exits without
@@ -641,7 +588,7 @@ lock_print_info_all_transactions(
Return approximate number or record locks (bits set in the bitmap) for
this transaction. Since delete-marked records may be removed, the
record count will not be precise.
-The caller must be holding lock_sys->mutex. */
+The caller must be holding lock_sys.mutex. */
ulint
lock_number_of_rows_locked(
/*=======================*/
@@ -650,7 +597,7 @@ lock_number_of_rows_locked(
/*********************************************************************//**
Return the number of table locks for a transaction.
-The caller must be holding lock_sys->mutex. */
+The caller must be holding lock_sys.mutex. */
ulint
lock_number_of_tables_locked(
/*=========================*/
@@ -827,7 +774,6 @@ Set the lock system timeout event. */
void
lock_set_timeout_event();
/*====================*/
-#ifdef UNIV_DEBUG
/*********************************************************************//**
Checks that a transaction id is sensible, i.e., not in the future.
@return true if ok */
@@ -837,8 +783,8 @@ lock_check_trx_id_sanity(
trx_id_t trx_id, /*!< in: trx id */
const rec_t* rec, /*!< in: user record */
dict_index_t* index, /*!< in: index */
- const ulint* offsets) /*!< in: rec_get_offsets(rec, index) */
- MY_ATTRIBUTE((warn_unused_result));
+ const ulint* offsets); /*!< in: rec_get_offsets(rec, index) */
+#ifdef UNIV_DEBUG
/*******************************************************************//**
Check if the transaction holds any locks on the sys tables
or its records.
@@ -934,11 +880,12 @@ struct lock_op_t{
typedef ib_mutex_t LockMutex;
/** The lock system struct */
-struct lock_sys_t{
- char pad1[CACHE_LINE_SIZE]; /*!< padding to prevent other
- memory update hotspots from
- residing on the same memory
- cache line */
+class lock_sys_t
+{
+ bool m_initialised;
+
+public:
+ MY_ALIGNED(CACHE_LINE_SIZE)
LockMutex mutex; /*!< Mutex protecting the
locks */
hash_table_t* rec_hash; /*!< hash table of the record
@@ -948,13 +895,13 @@ struct lock_sys_t{
hash_table_t* prdt_page_hash; /*!< hash table of the page
lock */
- char pad2[CACHE_LINE_SIZE]; /*!< Padding */
+ MY_ALIGNED(CACHE_LINE_SIZE)
LockMutex wait_mutex; /*!< Mutex protecting the
next two fields */
srv_slot_t* waiting_threads; /*!< Array of user threads
suspended while waiting for
locks within InnoDB, protected
- by the lock_sys->wait_mutex;
+ by the lock_sys.wait_mutex;
os_event_set() and
os_event_reset() on
waiting_threads[]->event
@@ -963,12 +910,7 @@ struct lock_sys_t{
srv_slot_t* last_slot; /*!< highest slot ever used
in the waiting_threads array,
protected by
- lock_sys->wait_mutex */
- ibool rollback_complete;
- /*!< TRUE if rollback of all
- recovered transactions is
- complete. Protected by
- lock_sys->mutex */
+ lock_sys.wait_mutex */
ulint n_lock_max_wait_time; /*!< Max wait time */
@@ -980,6 +922,38 @@ struct lock_sys_t{
bool timeout_thread_active; /*!< True if the timeout thread
is running */
+
+
+ /**
+ Constructor.
+
+ Some members may require late initialisation, thus we just mark object as
+ uninitialised. Real initialisation happens in create().
+ */
+ lock_sys_t(): m_initialised(false) {}
+
+
+ bool is_initialised() { return m_initialised; }
+
+
+ /**
+ Creates the lock system at database start.
+
+ @param[in] n_cells number of slots in lock hash table
+ */
+ void create(ulint n_cells);
+
+
+ /**
+ Resize the lock hash table.
+
+ @param[in] n_cells number of slots in lock hash table
+ */
+ void resize(ulint n_cells);
+
+
+ /** Closes the lock system at database shutdown. */
+ void close();
};
/*************************************************************//**
@@ -1024,36 +998,36 @@ lock_rec_trx_wait(
ulint type);
/** The lock system */
-extern lock_sys_t* lock_sys;
+extern lock_sys_t lock_sys;
-/** Test if lock_sys->mutex can be acquired without waiting. */
+/** Test if lock_sys.mutex can be acquired without waiting. */
#define lock_mutex_enter_nowait() \
- (lock_sys->mutex.trylock(__FILE__, __LINE__))
+ (lock_sys.mutex.trylock(__FILE__, __LINE__))
-/** Test if lock_sys->mutex is owned. */
-#define lock_mutex_own() (lock_sys->mutex.is_owned())
+/** Test if lock_sys.mutex is owned. */
+#define lock_mutex_own() (lock_sys.mutex.is_owned())
-/** Acquire the lock_sys->mutex. */
+/** Acquire the lock_sys.mutex. */
#define lock_mutex_enter() do { \
- mutex_enter(&lock_sys->mutex); \
+ mutex_enter(&lock_sys.mutex); \
} while (0)
-/** Release the lock_sys->mutex. */
+/** Release the lock_sys.mutex. */
#define lock_mutex_exit() do { \
- lock_sys->mutex.exit(); \
+ lock_sys.mutex.exit(); \
} while (0)
-/** Test if lock_sys->wait_mutex is owned. */
-#define lock_wait_mutex_own() (lock_sys->wait_mutex.is_owned())
+/** Test if lock_sys.wait_mutex is owned. */
+#define lock_wait_mutex_own() (lock_sys.wait_mutex.is_owned())
-/** Acquire the lock_sys->wait_mutex. */
+/** Acquire the lock_sys.wait_mutex. */
#define lock_wait_mutex_enter() do { \
- mutex_enter(&lock_sys->wait_mutex); \
+ mutex_enter(&lock_sys.wait_mutex); \
} while (0)
-/** Release the lock_sys->wait_mutex. */
+/** Release the lock_sys.wait_mutex. */
#define lock_wait_mutex_exit() do { \
- lock_sys->wait_mutex.exit(); \
+ lock_sys.wait_mutex.exit(); \
} while (0)
#ifdef WITH_WSREP
diff --git a/storage/innobase/include/lock0lock.ic b/storage/innobase/include/lock0lock.ic
index b73843e7a1f..dad62c9685c 100644
--- a/storage/innobase/include/lock0lock.ic
+++ b/storage/innobase/include/lock0lock.ic
@@ -35,7 +35,6 @@ Created 5/7/1996 Heikki Tuuri
#include "row0vers.h"
#include "que0que.h"
#include "btr0cur.h"
-#include "read0read.h"
#include "log0recv.h"
/*********************************************************************//**
@@ -64,7 +63,7 @@ lock_rec_hash(
ulint page_no)/*!< in: page number */
{
return(unsigned(hash_calc_hash(lock_rec_fold(space, page_no),
- lock_sys->rec_hash)));
+ lock_sys.rec_hash)));
}
/*********************************************************************//**
@@ -100,11 +99,11 @@ lock_hash_get(
ulint mode) /*!< in: lock mode */
{
if (mode & LOCK_PREDICATE) {
- return(lock_sys->prdt_hash);
+ return(lock_sys.prdt_hash);
} else if (mode & LOCK_PRDT_PAGE) {
- return(lock_sys->prdt_page_hash);
+ return(lock_sys.prdt_page_hash);
} else {
- return(lock_sys->rec_hash);
+ return(lock_sys.rec_hash);
}
}
diff --git a/storage/innobase/include/lock0priv.h b/storage/innobase/include/lock0priv.h
index 6bb75817ad6..ec596f6ca5b 100644
--- a/storage/innobase/include/lock0priv.h
+++ b/storage/innobase/include/lock0priv.h
@@ -111,7 +111,7 @@ operator<<(std::ostream& out, const lock_rec_t& lock)
return(lock.print(out));
}
-/** Lock struct; protected by lock_sys->mutex */
+/** Lock struct; protected by lock_sys.mutex */
struct lock_t {
trx_t* trx; /*!< transaction owning the
lock */
@@ -721,7 +721,7 @@ public:
as a victim, and we got the lock immediately: no need to
wait then */
dberr_t add_to_waitq(
- const lock_t* wait_for,
+ lock_t* wait_for,
const lock_prdt_t*
prdt = NULL);
@@ -731,21 +731,22 @@ public:
@param[in] owns_trx_mutex true if caller owns the trx_t::mutex
@param[in] add_to_hash add the lock to hash table
@param[in] prdt Predicate lock (optional)
+ @param[in,out] c_lock Conflicting lock request or NULL
+ in Galera conflicting lock is selected
+ as deadlock victim if requester
+ is BF transaction.
@return new lock instance */
lock_t* create(
trx_t* trx,
bool owns_trx_mutex,
bool add_to_hash,
const lock_prdt_t*
- prdt = NULL);
+ prdt = NULL
+#ifdef WITH_WSREP
+ ,lock_t* c_lock = NULL
+#endif /* WITH_WSREP */
+ ) const;
- lock_t* create(
- lock_t* const c_lock,
- trx_t* trx,
- bool owns_trx_mutex,
- bool add_to_hash,
- const lock_prdt_t*
- prdt = NULL);
/**
Check of the lock is on m_rec_id.
@param[in] lock Lock to compare with
@@ -837,7 +838,7 @@ private:
@param[in,out] lock Newly created record lock to add to the
rec hash and the transaction lock list
@param[in] add_to_hash If the lock should be added to the hash table */
- void lock_add(lock_t* lock, bool add_to_hash);
+ void lock_add(lock_t* lock, bool add_to_hash) const;
/**
Check and resolve any deadlocks
diff --git a/storage/innobase/include/lock0types.h b/storage/innobase/include/lock0types.h
index d08eaabfb1e..792a5f21acb 100644
--- a/storage/innobase/include/lock0types.h
+++ b/storage/innobase/include/lock0types.h
@@ -31,7 +31,6 @@ Created 5/7/1996 Heikki Tuuri
#define lock_t ib_lock_t
struct lock_t;
-struct lock_sys_t;
struct lock_table_t;
/* Basic lock modes */
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index 6a13d1d9640..716ca34b928 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, Google Inc.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -514,9 +514,11 @@ or the MySQL version that created the redo log file. */
#define LOG_HEADER_FORMAT_3_23 0
/** The MySQL 5.7.9/MariaDB 10.2.2 log format */
#define LOG_HEADER_FORMAT_10_2 1
+/** The MariaDB 10.3.2 log format */
+#define LOG_HEADER_FORMAT_10_3 103
/** The redo log format identifier corresponding to the current format version.
Stored in LOG_HEADER_FORMAT. */
-#define LOG_HEADER_FORMAT_CURRENT 103
+#define LOG_HEADER_FORMAT_CURRENT LOG_HEADER_FORMAT_10_3
/** Encrypted MariaDB redo log */
#define LOG_HEADER_FORMAT_ENCRYPTED (1U<<31)
@@ -612,15 +614,15 @@ struct log_t{
mtr_commit and still ensure that
insertions in the flush_list happen
in the LSN order. */
- byte* buf_ptr; /*!< unaligned log buffer, which should
- be of double of buf_size */
- byte* buf; /*!< log buffer currently in use;
- this could point to either the first
- half of the aligned(buf_ptr) or the
+ byte* buf; /*!< Memory of double the buf_size is
+ allocated here. This pointer will change
+ however to either the first half or the
second half in turns, so that log
write/flush to disk don't block
concurrent mtrs which will write
- log to this buffer */
+ log to this buffer. Care to switch back
+ to the first half before freeing/resizing
+ must be undertaken. */
bool first_in_use; /*!< true if buf points to the first
half of the aligned(buf_ptr), false
if the second half */
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index 4bfbbb4bb7d..8bab2408605 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -99,14 +99,15 @@ recv_sys_debug_free(void);
/** Read a log segment to a buffer.
@param[out] buf buffer
@param[in] group redo log files
-@param[in] start_lsn read area start
+@param[in, out] start_lsn in : read area start, out: the last read valid lsn
@param[in] end_lsn read area end
-@return valid end_lsn */
-lsn_t
+@param[out] invalid_block - invalid, (maybe incompletely written) block encountered
+@return false, if invalid block encountered (e.g checksum mismatch), true otherwise */
+bool
log_group_read_log_seg(
byte* buf,
const log_group_t* group,
- lsn_t start_lsn,
+ lsn_t* start_lsn,
lsn_t end_lsn);
/********************************************************//**
@@ -216,6 +217,7 @@ struct recv_sys_t{
/*!< this is TRUE when a log rec application
batch is running */
byte* buf; /*!< buffer for parsing log records */
+ size_t buf_size; /*!< size of buf */
ulint len; /*!< amount of data in buf */
lsn_t parse_start_lsn;
/*!< this is the lsn from which we were able to
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index 9c996b375d5..dbad7cb6950 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -280,8 +280,7 @@ mem_heap_free_heap_top(
mem_block_set_free(block, old_top - (byte*) block);
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
- UNIV_MEM_ASSERT_W(old_top, (byte*) block + block->len - old_top);
- UNIV_MEM_ALLOC(old_top, (byte*) block + block->len - old_top);
+ UNIV_MEM_FREE(old_top, (byte*) block + block->len - old_top);
/* If free == start, we may free the block if it is not the first
one */
@@ -445,7 +444,6 @@ mem_heap_free_top(
/* Subtract the free field of block */
mem_block_set_free(block, mem_block_get_free(block)
- MEM_SPACE_NEEDED(n));
- UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n);
/* If free == start, we may free the block if it is not the first
one */
@@ -454,11 +452,7 @@ mem_heap_free_top(
== mem_block_get_start(block))) {
mem_heap_block_free(heap, block);
} else {
- /* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a
- subsequent invocation of mem_heap_free_top().
- Originally, this was UNIV_MEM_FREE(), to catch writes
- to freed memory. */
- UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
+ UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n);
}
}
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 045a14221a3..6639a3448ea 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -32,13 +32,10 @@ Created 11/26/1995 Heikki Tuuri
#include "log0types.h"
#include "mtr0types.h"
#include "buf0types.h"
-#include "trx0types.h"
#include "dyn0buf.h"
/** Start a mini-transaction. */
#define mtr_start(m) (m)->start()
-/** Start a mini-transaction. */
-#define mtr_start_trx(m, t) (m)->start((t))
/** Start a synchronous mini-transaction */
#define mtr_start_sync(m) (m)->start(true)
@@ -217,9 +214,6 @@ struct mtr_t {
/** Owning mini-transaction */
mtr_t* m_mtr;
-
- /* Transaction handle */
- trx_t* m_trx;
};
mtr_t()
@@ -239,15 +233,7 @@ struct mtr_t {
/** Start a mini-transaction.
@param sync true if it is a synchronous mini-transaction
@param read_only true if read only mini-transaction */
- void start(bool sync = true, bool read_only = false)
- {
- start(NULL, sync, read_only);
- }
-
- /** Start a mini-transaction.
- @param sync true if it is a synchronous mini-transaction
- @param read_only true if read only mini-transaction */
- void start(trx_t* trx, bool sync = true, bool read_only = false);
+ void start(bool sync = true, bool read_only = false);
/** @return whether this is an asynchronous mini-transaction. */
bool is_async() const
@@ -333,7 +319,7 @@ struct mtr_t {
the same set of tablespaces as this one */
void set_spaces(const mtr_t& mtr)
{
- ut_ad(m_impl.m_user_space_id == TRX_SYS_SPACE);
+ ut_ad(!m_impl.m_user_space_id);
ut_ad(!m_impl.m_user_space);
ut_ad(!m_impl.m_undo_space);
ut_ad(!m_impl.m_sys_space);
@@ -350,9 +336,9 @@ struct mtr_t {
@return the tablespace */
fil_space_t* set_named_space(ulint space_id)
{
- ut_ad(m_impl.m_user_space_id == TRX_SYS_SPACE);
+ ut_ad(!m_impl.m_user_space_id);
ut_d(m_impl.m_user_space_id = space_id);
- if (space_id == TRX_SYS_SPACE) {
+ if (!space_id) {
return(set_sys_modified());
} else {
lookup_user_space(space_id);
diff --git a/storage/innobase/include/mtr0types.h b/storage/innobase/include/mtr0types.h
index ac24812cdfc..94d904e8efd 100644
--- a/storage/innobase/include/mtr0types.h
+++ b/storage/innobase/include/mtr0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -100,15 +100,18 @@ enum mlog_id_t {
/** Create an index page */
MLOG_PAGE_CREATE = 19,
- /** Insert entry in an undo log */
+ /** insert an undo log record (used in MariaDB 10.2) */
MLOG_UNDO_INSERT = 20,
- /** erase an undo log page end */
+ /** erase an undo log page end (used in MariaDB 10.2) */
MLOG_UNDO_ERASE_END = 21,
- /** initialize a page in an undo log */
+ /** initialize a page in an undo log (used in MariaDB 10.2) */
MLOG_UNDO_INIT = 22,
+ /** reuse an insert undo log header (used in MariaDB 10.2) */
+ MLOG_UNDO_HDR_REUSE = 24,
+
/** create an undo log header */
MLOG_UNDO_HDR_CREATE = 25,
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index 064430cbf4b..13de798280a 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -1195,11 +1195,12 @@ to original un-instrumented file I/O APIs */
# define os_file_read_no_error_handling(type, file, buf, offset, n, o) \
os_file_read_no_error_handling_func(type, file, buf, offset, n, o)
# define os_file_read_no_error_handling_int_fd(type, file, buf, offset, n) \
- os_file_read_no_error_handling_func(type, file, buf, offset, n, NULL)
+ os_file_read_no_error_handling_func(type, OS_FILE_FROM_FD(file), buf, offset, n, NULL)
# define os_file_write(type, name, file, buf, offset, n) \
os_file_write_func(type, name, file, buf, offset, n)
-# define os_file_write_int_fd os_file_write_func
+# define os_file_write_int_fd(type, name, file, buf, offset, n) \
+ os_file_write_func(type, name, OS_FILE_FROM_FD(file), buf, offset, n)
# define os_file_flush(file) os_file_flush_func(file)
diff --git a/storage/innobase/include/os0once.h b/storage/innobase/include/os0once.h
index 05a45a69f33..551e78d24ba 100644
--- a/storage/innobase/include/os0once.h
+++ b/storage/innobase/include/os0once.h
@@ -30,6 +30,7 @@ Created Feb 20, 2014 Vasil Dimov
#include "univ.i"
#include "ut0ut.h"
+#include "my_cpu.h"
/** Execute a given function exactly once in a multi-threaded environment
or wait for the function to be executed by another thread.
@@ -110,7 +111,7 @@ public:
ut_error;
}
- UT_RELAX_CPU();
+ MY_RELAX_CPU();
}
}
}
diff --git a/storage/innobase/include/os0thread.h b/storage/innobase/include/os0thread.h
index c240f5dacdd..c1b96ef7a1f 100644
--- a/storage/innobase/include/os0thread.h
+++ b/storage/innobase/include/os0thread.h
@@ -53,12 +53,8 @@ typedef LPTHREAD_START_ROUTINE os_thread_func_t;
/** Macro for specifying a Windows thread start function. */
#define DECLARE_THREAD(func) WINAPI func
-/** Required to get around a build error on Windows. Even though our functions
-are defined/declared as WINAPI f(LPVOID a); the compiler complains that they
-are defined as: os_thread_ret_t (__cdecl*)(void*). Because our functions
-don't access the arguments and don't return any value, we should be safe. */
#define os_thread_create(f,a,i) \
- os_thread_create_func(reinterpret_cast<os_thread_func_t>(f), a, i)
+ os_thread_create_func(f, a, i)
#else
diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
index c2b9a833bda..dee08605e58 100644
--- a/storage/innobase/include/page0page.h
+++ b/storage/innobase/include/page0page.h
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -733,14 +733,52 @@ ulint
page_rec_get_heap_no(
/*=================*/
const rec_t* rec); /*!< in: the physical record */
+/** Determine whether a page has any siblings.
+@param[in] page page frame
+@return true if the page has any siblings */
+inline
+bool
+page_has_siblings(const page_t* page)
+{
+ compile_time_assert(!(FIL_PAGE_PREV % 8));
+ compile_time_assert(FIL_PAGE_NEXT == FIL_PAGE_PREV + 4);
+ compile_time_assert(FIL_NULL == 0xffffffff);
+ return *reinterpret_cast<const uint64_t*>(page + FIL_PAGE_PREV)
+ != ~uint64_t(0);
+}
+
/** Determine whether a page is an index root page.
@param[in] page page frame
@return true if the page is a root page of an index */
-UNIV_INLINE
+inline
bool
-page_is_root(
- const page_t* page)
- MY_ATTRIBUTE((warn_unused_result));
+page_is_root(const page_t* page)
+{
+ return fil_page_index_page_check(page) && !page_has_siblings(page);
+}
+
+/** Determine whether a page has a predecessor.
+@param[in] page page frame
+@return true if the page has a predecessor */
+inline
+bool
+page_has_prev(const page_t* page)
+{
+ return *reinterpret_cast<const uint32_t*>(page + FIL_PAGE_PREV)
+ != FIL_NULL;
+}
+
+/** Determine whether a page has a successor.
+@param[in] page page frame
+@return true if the page has a successor */
+inline
+bool
+page_has_next(const page_t* page)
+{
+ return *reinterpret_cast<const uint32_t*>(page + FIL_PAGE_NEXT)
+ != FIL_NULL;
+}
+
/************************************************************//**
Gets the pointer to the next record on the page.
@return pointer to next record */
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index ee908896050..da0cd8511af 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -192,13 +192,11 @@ page_header_get_offs(
const page_t* page, /*!< in: page */
ulint field) /*!< in: PAGE_FREE, ... */
{
- ulint offs;
-
ut_ad((field == PAGE_FREE)
|| (field == PAGE_LAST_INSERT)
|| (field == PAGE_HEAP_TOP));
- offs = page_header_get_field(page, field);
+ uint16_t offs = page_header_get_field(page, field);
ut_ad((field != PAGE_HEAP_TOP) || offs);
@@ -277,31 +275,6 @@ page_rec_get_heap_no(
}
}
-/** Determine whether a page is an index root page.
-@param[in] page page frame
-@return true if the page is a root page of an index */
-UNIV_INLINE
-bool
-page_is_root(
- const page_t* page)
-{
-#if FIL_PAGE_PREV % 8
-# error FIL_PAGE_PREV must be 64-bit aligned
-#endif
-#if FIL_PAGE_NEXT != FIL_PAGE_PREV + 4
-# error FIL_PAGE_NEXT must be adjacent to FIL_PAGE_PREV
-#endif
-#if FIL_NULL != 0xffffffff
-# error FIL_NULL != 0xffffffff
-#endif
- /* Check that this is an index page and both the PREV and NEXT
- pointers are FIL_NULL, because the root page does not have any
- siblings. */
- return(fil_page_index_page_check(page)
- && *reinterpret_cast<const ib_uint64_t*>(page + FIL_PAGE_PREV)
- == IB_UINT64_MAX);
-}
-
/** Determine whether an index page record is a user record.
@param[in] rec record in an index page
@return true if a user record */
@@ -1116,7 +1089,7 @@ page_get_instant(const page_t* page)
ut_ad(i <= PAGE_NO_DIRECTION || !page_is_comp(page));
break;
case FIL_PAGE_RTREE:
- ut_ad(i == PAGE_NO_DIRECTION || i == 0);
+ ut_ad(i <= PAGE_NO_DIRECTION);
break;
default:
ut_ad(!"invalid page type");
diff --git a/storage/innobase/include/pars0opt.h b/storage/innobase/include/pars0opt.h
index 13ea38cc385..d9debcf325e 100644
--- a/storage/innobase/include/pars0opt.h
+++ b/storage/innobase/include/pars0opt.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -29,7 +29,6 @@ Created 12/21/1997 Heikki Tuuri
#include "univ.i"
#include "que0types.h"
-#include "usr0types.h"
#include "pars0sym.h"
#include "dict0types.h"
#include "row0sel.h"
diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h
index dad7953424c..37498c1c638 100644
--- a/storage/innobase/include/pars0pars.h
+++ b/storage/innobase/include/pars0pars.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -29,7 +29,6 @@ Created 11/19/1996 Heikki Tuuri
#include "univ.i"
#include "que0types.h"
-#include "usr0types.h"
#include "pars0types.h"
#include "row0types.h"
#include "trx0types.h"
diff --git a/storage/innobase/include/pars0sym.h b/storage/innobase/include/pars0sym.h
index 4e511719639..920087b96c2 100644
--- a/storage/innobase/include/pars0sym.h
+++ b/storage/innobase/include/pars0sym.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -29,7 +29,6 @@ Created 12/15/1997 Heikki Tuuri
#include "univ.i"
#include "que0types.h"
-#include "usr0types.h"
#include "dict0types.h"
#include "pars0types.h"
#include "row0types.h"
diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h
index 763b16820d8..ca06f5b09ba 100644
--- a/storage/innobase/include/que0que.h
+++ b/storage/innobase/include/que0que.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -33,7 +33,6 @@ Created 5/27/1996 Heikki Tuuri
#include "trx0trx.h"
#include "trx0roll.h"
#include "srv0srv.h"
-#include "usr0types.h"
#include "que0types.h"
#include "row0types.h"
#include "pars0types.h"
@@ -336,13 +335,6 @@ enum que_thr_lock_t {
QUE_THR_LOCK_TABLE
};
-/** From where the cursor position is counted */
-enum que_cur_t {
- QUE_CUR_NOT_DEFINED,
- QUE_CUR_START,
- QUE_CUR_END
-};
-
/* Query graph query thread node: the fields are protected by the
trx_t::mutex with the exceptions named below */
@@ -381,9 +373,6 @@ struct que_thr_t{
thrs; /*!< list of thread nodes of the fork
node */
UT_LIST_NODE_T(que_thr_t)
- trx_thrs; /*!< lists of threads in wait list of
- the trx */
- UT_LIST_NODE_T(que_thr_t)
queue; /*!< list of runnable thread nodes in
the server task queue */
ulint fk_cascade_depth; /*!< maximum cascading call depth
@@ -419,18 +408,7 @@ struct que_fork_t{
generated by the parser, or NULL
if the graph was created 'by hand' */
pars_info_t* info; /*!< info struct, or NULL */
- /* The following cur_... fields are relevant only in a select graph */
- ulint cur_end; /*!< QUE_CUR_NOT_DEFINED, QUE_CUR_START,
- QUE_CUR_END */
- ulint cur_pos; /*!< if there are n rows in the result
- set, values 0 and n + 1 mean before
- first row, or after last row, depending
- on cur_end; values 1...n mean a row
- index */
- ibool cur_on_row; /*!< TRUE if cursor is on a row, i.e.,
- it is not before the first row or
- after the last row */
sel_node_t* last_sel_node; /*!< last executed select node, or NULL
if none */
UT_LIST_NODE_T(que_fork_t)
diff --git a/storage/innobase/include/que0que.ic b/storage/innobase/include/que0que.ic
index ec61081cfe2..545d5288298 100644
--- a/storage/innobase/include/que0que.ic
+++ b/storage/innobase/include/que0que.ic
@@ -23,8 +23,6 @@ Query graph
Created 5/27/1996 Heikki Tuuri
*******************************************************/
-#include "usr0sess.h"
-
/***********************************************************************//**
Gets the trx of a query thread. */
UNIV_INLINE
diff --git a/storage/innobase/include/read0read.h b/storage/innobase/include/read0read.h
deleted file mode 100644
index 129341be77c..00000000000
--- a/storage/innobase/include/read0read.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-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, Suite 500, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/read0read.h
-Cursor read
-
-Created 2/16/1997 Heikki Tuuri
-*******************************************************/
-
-#ifndef read0read_h
-#define read0read_h
-
-#include "univ.i"
-
-#include "read0types.h"
-
-#include <algorithm>
-
-/** The MVCC read view manager */
-class MVCC {
-public:
- /** Constructor
- @param size Number of views to pre-allocate */
- explicit MVCC(ulint size);
-
- /** Destructor.
- Free all the views in the m_free list */
- ~MVCC();
-
- /**
- Allocate and create a view.
- @param view view owned by this class created for the
- caller. Must be freed by calling close()
- @param trx transaction creating the view */
- void view_open(ReadView*& view, trx_t* trx);
-
- /**
- Close a view created by the above function.
- @para view view allocated by trx_open.
- @param own_mutex true if caller owns trx_sys_t::mutex */
- void view_close(ReadView*& view, bool own_mutex);
-
- /**
- Release a view that is inactive but not closed. Caller must own
- the trx_sys_t::mutex.
- @param view View to release */
- void view_release(ReadView*& view);
-
- /** Clones the oldest view and stores it in view. No need to
- call view_close(). The caller owns the view that is passed in.
- It will also move the closed views from the m_views list to the
- m_free list. This function is called by Purge to create it view.
- @param view Preallocated view, owned by the caller */
- void clone_oldest_view(ReadView* view);
-
- /**
- @return the number of active views */
- ulint size() const;
-
- /**
- @return true if the view is active and valid */
- static bool is_view_active(ReadView* view)
- {
- ut_a(view != reinterpret_cast<ReadView*>(0x1));
-
- return(view != NULL && !(intptr_t(view) & 0x1));
- }
-
- /**
- Set the view creator transaction id. Note: This shouldbe set only
- for views created by RW transactions. */
- static void set_view_creator_trx_id(ReadView* view, trx_id_t id);
-
-private:
-
- /**
- Validates a read view list. */
- bool validate() const;
-
- /**
- Find a free view from the active list, if none found then allocate
- a new view. This function will also attempt to move delete marked
- views from the active list to the freed list.
- @return a view to use */
- inline ReadView* get_view();
-
- /**
- Get the oldest view in the system. It will also move the delete
- marked read views from the views list to the freed list.
- @return oldest view if found or NULL */
- inline ReadView* get_oldest_view() const;
-
-private:
- // Prevent copying
- MVCC(const MVCC&);
- MVCC& operator=(const MVCC&);
-
-private:
- typedef UT_LIST_BASE_NODE_T(ReadView) view_list_t;
-
- /** Free views ready for reuse. */
- view_list_t m_free;
-
- /** Active and closed views, the closed views will have the
- creator trx id set to TRX_ID_MAX */
- view_list_t m_views;
-};
-
-#endif /* read0read_h */
diff --git a/storage/innobase/include/read0types.h b/storage/innobase/include/read0types.h
index 8056dbf437f..3a06190b61d 100644
--- a/storage/innobase/include/read0types.h
+++ b/storage/innobase/include/read0types.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -31,122 +32,185 @@ Created 2/16/1997 Heikki Tuuri
#include "trx0types.h"
-// Friend declaration
-class MVCC;
-/** Read view lists the trx ids of those transactions for which a consistent
-read should not see the modifications to the database. */
+/** View is not in MVCC and not visible to purge thread. */
+#define READ_VIEW_STATE_CLOSED 0
-class ReadView {
- /** This is similar to a std::vector but it is not a drop
- in replacement. It is specific to ReadView. */
- class ids_t {
- typedef trx_ids_t::value_type value_type;
+/** View is in MVCC, but not visible to purge thread. */
+#define READ_VIEW_STATE_REGISTERED 1
- /**
- Constructor */
- ids_t() : m_ptr(), m_size(), m_reserved() { }
+/** View is in MVCC, purge thread must wait for READ_VIEW_STATE_OPEN. */
+#define READ_VIEW_STATE_SNAPSHOT 2
- /**
- Destructor */
- ~ids_t() { UT_DELETE_ARRAY(m_ptr); }
+/** View is in MVCC and is visible to purge thread. */
+#define READ_VIEW_STATE_OPEN 3
- /**
- Try and increase the size of the array. Old elements are
- copied across. It is a no-op if n is < current size.
- @param n Make space for n elements */
- void reserve(ulint n);
+/**
+ Read view lists the trx ids of those transactions for which a consistent read
+ should not see the modifications to the database.
+*/
+class ReadView
+{
+ /**
+ View state.
- /**
- Resize the array, sets the current element count.
- @param n new size of the array, in elements */
- void resize(ulint n)
- {
- ut_ad(n <= capacity());
+ It is not defined as enum as it has to be updated using atomic operations.
+ Possible values are READ_VIEW_STATE_CLOSED, READ_VIEW_STATE_REGISTERED,
+ READ_VIEW_STATE_SNAPSHOT and READ_VIEW_STATE_OPEN.
- m_size = n;
- }
-
- /**
- Reset the size to 0 */
- void clear() { resize(0); }
-
- /**
- @return the capacity of the array in elements */
- ulint capacity() const { return(m_reserved); }
-
- /**
- Copy and overwrite the current array contents
-
- @param start Source array
- @param end Pointer to end of array */
- void assign(const value_type* start, const value_type* end);
-
- /**
- Insert the value in the correct slot, preserving the order.
- Doesn't check for duplicates. */
- void insert(value_type value);
-
- /**
- @return the value of the first element in the array */
- value_type front() const
- {
- ut_ad(!empty());
+ Possible state transfers...
- return(m_ptr[0]);
- }
-
- /**
- @return the value of the last element in the array */
- value_type back() const
- {
- ut_ad(!empty());
-
- return(m_ptr[m_size - 1]);
- }
+ Opening view for the first time:
+ READ_VIEW_STATE_CLOSED -> READ_VIEW_STATE_SNAPSHOT (non-atomic)
- /**
- Append a value to the array.
- @param value the value to append */
- void push_back(value_type value);
+ Complete first time open or reopen:
+ READ_VIEW_STATE_SNAPSHOT -> READ_VIEW_STATE_OPEN (atomic)
- /**
- @return a pointer to the start of the array */
- trx_id_t* data() { return(m_ptr); };
+ Close view but keep it in list:
+ READ_VIEW_STATE_OPEN -> READ_VIEW_STATE_REGISTERED (atomic)
- /**
- @return a const pointer to the start of the array */
- const trx_id_t* data() const { return(m_ptr); };
+ Close view and remove it from list:
+ READ_VIEW_STATE_OPEN -> READ_VIEW_STATE_CLOSED (non-atomic)
- /**
- @return the number of elements in the array */
- ulint size() const { return(m_size); }
+ Reusing view:
+ READ_VIEW_STATE_REGISTERED -> READ_VIEW_STATE_SNAPSHOT (atomic)
- /**
- @return true if size() == 0 */
- bool empty() const { return(size() == 0); }
+ Removing closed view from list:
+ READ_VIEW_STATE_REGISTERED -> READ_VIEW_STATE_CLOSED (non-atomic)
+ */
+ int32_t m_state;
- private:
- // Prevent copying
- ids_t(const ids_t&);
- ids_t& operator=(const ids_t&);
- private:
- /** Memory for the array */
- value_type* m_ptr;
-
- /** Number of active elements in the array */
- ulint m_size;
+public:
+ ReadView(): m_state(READ_VIEW_STATE_CLOSED) {}
+
+
+ /**
+ Copy state from another view.
+
+ This method is used to find min(m_low_limit_no), min(m_low_limit_id) and
+ all transaction ids below min(m_low_limit_id). These values effectively
+ form oldest view.
+
+ @param other view to copy from
+ */
+ void copy(const ReadView &other)
+ {
+ ut_ad(&other != this);
+ if (m_low_limit_no > other.m_low_limit_no)
+ m_low_limit_no= other.m_low_limit_no;
+ if (m_low_limit_id > other.m_low_limit_id)
+ m_low_limit_id= other.m_low_limit_id;
+
+ trx_ids_t::iterator dst= m_ids.begin();
+ for (trx_ids_t::const_iterator src= other.m_ids.begin();
+ src != other.m_ids.end(); src++)
+ {
+ if (*src >= m_low_limit_id)
+ break;
+loop:
+ if (dst == m_ids.end())
+ {
+ m_ids.push_back(*src);
+ dst= m_ids.end();
+ continue;
+ }
+ if (*dst < *src)
+ {
+ dst++;
+ goto loop;
+ }
+ else if (*dst > *src)
+ dst= m_ids.insert(dst, *src) + 1;
+ }
+ m_ids.erase(std::lower_bound(dst, m_ids.end(), m_low_limit_id),
+ m_ids.end());
+
+ m_up_limit_id= m_ids.empty() ? m_low_limit_id : m_ids.front();
+ ut_ad(m_up_limit_id <= m_low_limit_id);
+ }
+
+
+ /**
+ Opens a read view where exactly the transactions serialized before this
+ point in time are seen in the view.
+
+ View becomes visible to purge thread via trx_sys.m_views.
+
+ @param[in,out] trx transaction
+ */
+ void open(trx_t *trx);
+
+
+ /**
+ Closes the view.
+
+ View becomes not visible to purge thread via trx_sys.m_views.
+ */
+ void close();
+
+
+ /**
+ Marks view unused.
+
+ View is still in trx_sys.m_views list, but is not visible to purge threads.
+ */
+ void unuse()
+ {
+ ut_ad(m_state == READ_VIEW_STATE_CLOSED ||
+ m_state == READ_VIEW_STATE_REGISTERED ||
+ m_state == READ_VIEW_STATE_OPEN);
+ if (m_state == READ_VIEW_STATE_OPEN)
+ my_atomic_store32_explicit(&m_state, READ_VIEW_STATE_REGISTERED,
+ MY_MEMORY_ORDER_RELAXED);
+ }
+
+
+ /** m_state getter for trx_sys::clone_oldest_view() trx_sys::size(). */
+ int32_t get_state() const
+ {
+ return my_atomic_load32_explicit(const_cast<int32*>(&m_state),
+ MY_MEMORY_ORDER_ACQUIRE);
+ }
+
+
+ /**
+ Returns true if view is open.
+
+ Only used by view owner thread, thus we can omit atomic operations.
+ */
+ bool is_open() const
+ {
+ ut_ad(m_state == READ_VIEW_STATE_OPEN ||
+ m_state == READ_VIEW_STATE_CLOSED ||
+ m_state == READ_VIEW_STATE_REGISTERED);
+ return m_state == READ_VIEW_STATE_OPEN;
+ }
+
+
+ /**
+ Creates a snapshot where exactly the transactions serialized before this
+ point in time are seen in the view.
+
+ @param[in,out] trx transaction
+ */
+ void snapshot(trx_t *trx);
+
+
+ /**
+ Sets the creator transaction id.
+
+ This should be set only for views created by RW transactions.
+ */
+ void set_creator_trx_id(trx_id_t id)
+ {
+ ut_ad(id > 0);
+ ut_ad(m_creator_trx_id == 0);
+ m_creator_trx_id= id;
+ }
- /** Size of m_ptr in elements */
- ulint m_reserved;
- friend class ReadView;
- };
-public:
- ReadView();
- ~ReadView();
/** Check whether transaction id is valid.
@param[in] id transaction id to check
@param[in] name table name */
@@ -179,9 +243,7 @@ public:
return(true);
}
- const ids_t::value_type* p = m_ids.data();
-
- return(!std::binary_search(p, p + m_ids.size(), id));
+ return(!std::binary_search(m_ids.begin(), m_ids.end(), id));
}
/**
@@ -193,21 +255,6 @@ public:
}
/**
- Mark the view as closed */
- void close()
- {
- ut_ad(m_creator_trx_id != TRX_ID_MAX);
- m_creator_trx_id = TRX_ID_MAX;
- }
-
- /**
- @return true if the view is closed */
- bool is_closed() const
- {
- return(m_closed);
- }
-
- /**
Write the limits to the file.
@param file file to write to */
void print_limits(FILE* file) const
@@ -232,66 +279,6 @@ public:
return(m_low_limit_id);
}
- /**
- @return true if there are no transaction ids in the snapshot */
- bool empty() const
- {
- return(m_ids.empty());
- }
-
-#ifdef UNIV_DEBUG
- /**
- @param rhs view to compare with
- @return truen if this view is less than or equal rhs */
- bool le(const ReadView* rhs) const
- {
- return(m_low_limit_no <= rhs->m_low_limit_no);
- }
-
- trx_id_t up_limit_id() const
- {
- return(m_up_limit_id);
- }
-#endif /* UNIV_DEBUG */
-private:
- /**
- Copy the transaction ids from the source vector */
- inline void copy_trx_ids(const trx_ids_t& trx_ids);
-
- /**
- Opens a read view where exactly the transactions serialized before this
- point in time are seen in the view.
- @param id Creator transaction id */
- inline void prepare(trx_id_t id);
-
- /**
- Complete the read view creation */
- inline void complete();
-
- /**
- Copy state from another view. Must call copy_complete() to finish.
- @param other view to copy from */
- inline void copy_prepare(const ReadView& other);
-
- /**
- Complete the copy, insert the creator transaction id into the
- m_trx_ids too and adjust the m_up_limit_id *, if required */
- inline void copy_complete();
-
- /**
- Set the creator transaction id, existing id must be 0 */
- void creator_trx_id(trx_id_t id)
- {
- ut_ad(m_creator_trx_id == 0);
- m_creator_trx_id = id;
- }
-
- friend class MVCC;
-
-private:
- // Disable copying
- ReadView(const ReadView&);
- ReadView& operator=(const ReadView&);
private:
/** The read should not see any transaction with trx id >= this
@@ -309,21 +296,16 @@ private:
/** Set of RW transactions that was active when this snapshot
was taken */
- ids_t m_ids;
+ trx_ids_t m_ids;
/** The view does not need to see the undo logs for transactions
whose transaction number is strictly smaller (<) than this value:
they can be removed in purge if not needed by other views */
trx_id_t m_low_limit_no;
- /** AC-NL-RO transaction view that has been "closed". */
- bool m_closed;
-
- typedef UT_LIST_NODE_T(ReadView) node_t;
-
- /** List of read views in trx_sys */
- byte pad1[64 - sizeof(node_t)];
- node_t m_view_list;
+ byte pad1[CACHE_LINE_SIZE];
+public:
+ UT_LIST_NODE_T(ReadView) m_view_list;
};
#endif
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index 062e4f8d8ab..da82361875c 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -367,7 +367,7 @@ rec_set_deleted_flag_new(
The following function tells if a new-style record is a node pointer.
@return TRUE if node pointer */
UNIV_INLINE
-ibool
+bool
rec_get_node_ptr_flag(
/*==================*/
const rec_t* rec) /*!< in: physical record */
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
index cc66149945c..bc9006a66e8 100644
--- a/storage/innobase/include/rem0rec.ic
+++ b/storage/innobase/include/rem0rec.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -731,7 +731,7 @@ rec_set_deleted_flag_new(
The following function tells if a new-style record is a node pointer.
@return TRUE if node pointer */
UNIV_INLINE
-ibool
+bool
rec_get_node_ptr_flag(
/*==================*/
const rec_t* rec) /*!< in: physical record */
@@ -895,7 +895,7 @@ rec_offs_set_n_alloc(
{
ut_ad(offsets);
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
- UNIV_MEM_ASSERT_AND_ALLOC(offsets, n_alloc * sizeof *offsets);
+ UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets);
offsets[0] = n_alloc;
}
diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h
index 8cb3a2f16cd..ed425390ed2 100644
--- a/storage/innobase/include/row0ins.h
+++ b/storage/innobase/include/row0ins.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -198,10 +198,13 @@ struct ins_node_t{
this should be reset to NULL */
UT_LIST_BASE_NODE_T(dtuple_t)
entry_list;/* list of entries, one for each index */
- byte* row_id_buf;/* buffer for the row id sys field in row */
+ /** buffer for the system columns */
+ byte sys_buf[DATA_ROW_ID_LEN
+ + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN];
trx_id_t trx_id; /*!< trx id or the last trx which executed the
node */
- byte* trx_id_buf;/* buffer for the trx id sys field in row */
+ byte vers_start_buf[8]; /* Buffers for System Versioning */
+ byte vers_end_buf[8]; /* system fields. */
mem_heap_t* entry_sys_heap;
/* memory heap used as auxiliary storage;
entry_list and sys fields are stored here;
@@ -227,5 +230,4 @@ struct ins_node_t{
#define INS_NODE_ALLOC_ROW_ID 2 /* row id should be allocated */
#define INS_NODE_INSERT_ENTRIES 3 /* index entries should be built and
inserted */
-
#endif
diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h
index ca620cbef59..eb4da62164b 100644
--- a/storage/innobase/include/row0merge.h
+++ b/storage/innobase/include/row0merge.h
@@ -59,9 +59,6 @@ Created 13/06/2005 Jan Lindstrom
// Forward declaration
struct ib_sequence_t;
-/** The DB_TRX_ID,DB_ROLL_PTR values for "no history is available" */
-extern const byte reset_trx_id[DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN];
-
/** @brief Block size for I/O operations in merge sort.
The minimum is UNIV_PAGE_SIZE, or page_get_free_space_of_empty()
@@ -325,6 +322,7 @@ this function and it will be passed to other functions for further accounting.
@param[in] add_v new virtual columns added along with indexes
@param[in] eval_table mysql table used to evaluate virtual column
value, see innobase_get_computed_value().
+@param[in] drop_historical whether to drop historical system rows
@return DB_SUCCESS or error code */
dberr_t
row_merge_build_indexes(
@@ -343,7 +341,8 @@ row_merge_build_indexes(
bool skip_pk_sort,
ut_stage_alter_t* stage,
const dict_add_v_col_t* add_v,
- struct TABLE* eval_table)
+ struct TABLE* eval_table,
+ bool drop_historical)
MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index a7a55d202e8..61a363d6de8 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -219,30 +219,32 @@ row_lock_table_autoinc_for_mysql(
table handle */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*********************************************************************//**
-Sets a table lock on the table mentioned in prebuilt.
+/** Lock a table.
+@param[in,out] prebuilt table handle
@return error code or DB_SUCCESS */
dberr_t
-row_lock_table_for_mysql(
-/*=====================*/
- row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in the MySQL
- table handle */
- dict_table_t* table, /*!< in: table to lock, or NULL
- if prebuilt->table should be
- locked as
- prebuilt->select_lock_type */
- ulint mode) /*!< in: lock mode of table
- (ignored if table==NULL) */
- MY_ATTRIBUTE((nonnull(1)));
+row_lock_table(row_prebuilt_t* prebuilt);
+
+/** System Versioning: row_insert_for_mysql() modes */
+enum ins_mode_t {
+ /* plain row (without versioning) */
+ ROW_INS_NORMAL = 0,
+ /* row_start = TRX_ID, row_end = MAX */
+ ROW_INS_VERSIONED,
+ /* row_end = TRX_ID */
+ ROW_INS_HISTORICAL
+};
/** Does an insert for MySQL.
@param[in] mysql_rec row in the MySQL format
@param[in,out] prebuilt prebuilt struct in MySQL handle
+@param[in] ins_mode what row type we're inserting
@return error code or DB_SUCCESS*/
dberr_t
row_insert_for_mysql(
const byte* mysql_rec,
- row_prebuilt_t* prebuilt)
+ row_prebuilt_t* prebuilt,
+ ins_mode_t ins_mode)
MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
@@ -266,7 +268,8 @@ row_get_prebuilt_update_vector(
@param[in,out] prebuilt prebuilt struct in MySQL handle
@return error code or DB_SUCCESS */
dberr_t
-row_update_for_mysql(row_prebuilt_t* prebuilt)
+row_update_for_mysql(
+ row_prebuilt_t* prebuilt)
MY_ATTRIBUTE((warn_unused_result));
/** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
@@ -307,6 +310,18 @@ row_create_update_node_for_mysql(
/*=============================*/
dict_table_t* table, /*!< in: table to update */
mem_heap_t* heap); /*!< in: mem heap from which allocated */
+
+/**********************************************************************//**
+Does a cascaded delete or set null in a foreign key operation.
+@return error code or DB_SUCCESS */
+dberr_t
+row_update_cascade_for_mysql(
+/*=========================*/
+ que_thr_t* thr, /*!< in: query thread */
+ upd_node_t* node, /*!< in: update node used in the cascade
+ or set null operation */
+ dict_table_t* table) /*!< in: table where we do the operation */
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Locks the data dictionary exclusively for performing a table create or other
data dictionary modification operation. */
@@ -420,6 +435,10 @@ ulint
row_get_background_drop_list_len_low(void);
/*======================================*/
+/** Drop garbage tables during recovery. */
+void
+row_mysql_drop_garbage_tables();
+
/*********************************************************************//**
Sets an exclusive lock on a table.
@return error code or DB_SUCCESS */
@@ -504,18 +523,6 @@ row_rename_table_for_mysql(
bool commit) /*!< in: whether to commit trx */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/** Renames a partitioned table for MySQL.
-@param[in] old_name Old table name.
-@param[in] new_name New table name.
-@param[in,out] trx Transaction.
-@return error code or DB_SUCCESS */
-dberr_t
-row_rename_partitions_for_mysql(
- const char* old_name,
- const char* new_name,
- trx_t* trx)
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-
/*********************************************************************//**
Scans an index for either COOUNT(*) or CHECK TABLE.
If CHECK TABLE; Checks that the index contains entries in an ascending order,
@@ -668,6 +675,8 @@ struct row_prebuilt_t {
not to be confused with InnoDB
externally stored columns
(VARCHAR can be off-page too) */
+ unsigned versioned_write:1;/*!< whether this is
+ a versioned write */
mysql_row_templ_t* mysql_template;/*!< template used to transform
rows fast between MySQL and Innobase
formats; memory for this template
@@ -844,6 +853,20 @@ struct row_prebuilt_t {
/** The MySQL table object */
TABLE* m_mysql_table;
+
+ /** Get template by dict_table_t::cols[] number */
+ const mysql_row_templ_t* get_template_by_col(ulint col) const
+ {
+ ut_ad(col < n_template);
+ ut_ad(mysql_template);
+ for (ulint i = col; i < n_template; ++i) {
+ const mysql_row_templ_t* templ = &mysql_template[i];
+ if (!templ->is_virtual && templ->col_no == col) {
+ return templ;
+ }
+ }
+ return NULL;
+ }
};
/** Callback for row_mysql_sys_index_iterate() */
diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h
index 92b5942966b..01fc6cda6ae 100644
--- a/storage/innobase/include/row0upd.h
+++ b/storage/innobase/include/row0upd.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -32,20 +32,10 @@ Created 12/27/1996 Heikki Tuuri
#include "btr0types.h"
#include "dict0types.h"
#include "trx0types.h"
-#include <stack>
#include "btr0pcur.h"
#include "que0types.h"
#include "pars0types.h"
-/** The std::deque to store cascade update nodes, that uses mem_heap_t
-as allocator. */
-typedef std::deque<upd_node_t*, mem_heap_allocator<upd_node_t*> >
- deque_mem_heap_t;
-
-/** Double-ended queue of update nodes to be processed for cascade
-operations */
-typedef deque_mem_heap_t upd_cascade_t;
-
/*********************************************************************//**
Creates an update vector object.
@return own: update vector object */
@@ -136,8 +126,7 @@ row_upd_rec_sys_fields(
dict_index_t* index, /*!< in: clustered index */
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
const trx_t* trx, /*!< in: transaction */
- roll_ptr_t roll_ptr);/*!< in: roll ptr of the undo log record,
- can be 0 during IMPORT */
+ roll_ptr_t roll_ptr);/*!< in: DB_ROLL_PTR to the undo log */
/*********************************************************************//**
Sets the trx id or roll ptr field of a clustered index entry. */
void
@@ -464,6 +453,7 @@ struct upd_t{
virtual column update now */
ulint n_fields; /*!< number of update fields */
upd_field_t* fields; /*!< array of update fields */
+ byte vers_sys_value[8]; /*!< buffer for updating system fields */
/** Append an update field to the end of array
@param[in] field an update field */
@@ -484,6 +474,17 @@ struct upd_t{
return(false);
}
+ /** Determine if the update affects a system versioned column. */
+ bool affects_versioned() const
+ {
+ for (ulint i = 0; i < n_fields; i++) {
+ if (fields[i].new_val.type.vers_sys_field()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
#ifdef UNIV_DEBUG
bool validate() const
{
@@ -500,12 +501,19 @@ struct upd_t{
};
+/** Kinds of update operation */
+enum delete_mode_t {
+ NO_DELETE = 0, /*!< this operation does not delete */
+ PLAIN_DELETE, /*!< ordinary delete */
+ VERSIONED_DELETE /*!< update old and insert a new row */
+};
+
/* Update node structure which also implements the delete operation
of a row */
struct upd_node_t{
que_common_t common; /*!< node type: QUE_NODE_UPDATE */
- ibool is_delete;/* TRUE if delete, FALSE if update */
+ delete_mode_t is_delete; /*!< kind of DELETE */
ibool searched_update;
/* TRUE if searched update, FALSE if
positioned */
@@ -515,38 +523,12 @@ struct upd_node_t{
dict_foreign_t* foreign;/* NULL or pointer to a foreign key
constraint if this update node is used in
doing an ON DELETE or ON UPDATE operation */
-
- bool cascade_top;
- /*!< true if top level in cascade */
-
- upd_cascade_t* cascade_upd_nodes;
- /*!< Queue of update nodes to handle the
- cascade of update and delete operations in an
- iterative manner. Their parent/child
- relations are properly maintained. All update
- nodes point to this same queue. All these
- nodes are allocated in heap pointed to by
- upd_node_t::cascade_heap. */
-
- upd_cascade_t* new_upd_nodes;
- /*!< Intermediate list of update nodes in a
- cascading update/delete operation. After
- processing one update node, this will be
- concatenated to cascade_upd_nodes. This extra
- list is needed so that retry because of
- DB_LOCK_WAIT works corrrectly. */
-
- upd_cascade_t* processed_cascades;
- /*!< List of processed update nodes in a
- cascading update/delete operation. All the
- cascade nodes are stored here, so that memory
- can be freed. */
-
+ upd_node_t* cascade_node;/* NULL or an update node template which
+ is used to implement ON DELETE/UPDATE CASCADE
+ or ... SET NULL for foreign keys */
mem_heap_t* cascade_heap;
- /*!< NULL or a mem heap where cascade_upd_nodes
- are created. This heap is owned by the node
- that has cascade_top=true. */
-
+ /*!< NULL or a mem heap where cascade
+ node is created.*/
sel_node_t* select; /*!< query graph subtree implementing a base
table cursor: the rows returned will be
updated */
@@ -593,25 +575,8 @@ struct upd_node_t{
sym_node_t* table_sym;/* table node in symbol table */
que_node_t* col_assign_list;
/* column assignment list */
-
- doc_id_t fts_doc_id;
- /* The FTS doc id of the row that is now
- pointed to by the pcur. */
-
- doc_id_t fts_next_doc_id;
- /* The new fts doc id that will be used
- in update operation */
-
ulint magic_n;
-#ifndef DBUG_OFF
- /** Print information about this object into the trace log file. */
- void dbug_trace();
-
- /** Ensure that the member cascade_upd_nodes has only one update node
- for each of the tables. This is useful for testing purposes. */
- void check_cascade_only_once();
-#endif /* !DBUG_OFF */
};
#define UPD_NODE_MAGIC_N 1579975
diff --git a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic
index 11271d6e9af..364c876ecc7 100644
--- a/storage/innobase/include/row0upd.ic
+++ b/storage/innobase/include/row0upd.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -165,8 +165,7 @@ row_upd_rec_sys_fields(
dict_index_t* index, /*!< in: clustered index */
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
const trx_t* trx, /*!< in: transaction */
- roll_ptr_t roll_ptr)/*!< in: roll ptr of the undo log record,
- can be 0 during IMPORT */
+ roll_ptr_t roll_ptr)/*!< in: DB_ROLL_PTR to the undo log */
{
ut_ad(dict_index_is_clust(index));
ut_ad(rec_offs_validate(rec, index, offsets));
diff --git a/storage/innobase/include/row0vers.h b/storage/innobase/include/row0vers.h
index b28533578e1..645f11faaad 100644
--- a/storage/innobase/include/row0vers.h
+++ b/storage/innobase/include/row0vers.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 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
@@ -38,19 +39,20 @@ Created 2/6/1997 Heikki Tuuri
// Forward declaration
class ReadView;
-/*****************************************************************//**
-Finds out if an active transaction has inserted or modified a secondary
+/** Determine if an active transaction has inserted or modified a secondary
index record.
-@return 0 if committed, else the active transaction id;
-NOTE that this function can return false positives but never false
-negatives. The caller must confirm all positive results by calling
-trx_is_active() while holding lock_sys->mutex. */
+@param[in,out] caller_trx trx of current thread
+@param[in] rec secondary index record
+@param[in] index secondary index
+@param[in] offsets rec_get_offsets(rec, index)
+@return the active transaction; trx->release_reference() must be invoked
+@retval NULL if the record was committed */
trx_t*
row_vers_impl_x_locked(
-/*===================*/
- const rec_t* rec, /*!< in: record in a secondary index */
- dict_index_t* index, /*!< in: the secondary index */
- const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+ trx_t* caller_trx,
+ const rec_t* rec,
+ dict_index_t* index,
+ const ulint* offsets);
/*****************************************************************//**
Finds out if we must preserve a delete marked earlier version of a clustered
@@ -126,6 +128,7 @@ which should be seen by a semi-consistent read. */
void
row_vers_build_for_semi_consistent_read(
/*====================================*/
+ trx_t* caller_trx,/*!<in/out: trx of current thread */
const rec_t* rec, /*!< in: record in a clustered index; the
caller must have a latch on the page; this
latch locks the top of the stack of versions
diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h
index e4034f3a6ff..b91f7c1103b 100644
--- a/storage/innobase/include/srv0mon.h
+++ b/storage/innobase/include/srv0mon.h
@@ -608,8 +608,9 @@ Use MONITOR_INC if appropriate mutex protection exists.
#define MONITOR_ATOMIC_INC_LOW(monitor, enabled) \
if (enabled) { \
ib_uint64_t value; \
- value = my_atomic_add64( \
- (int64*) &MONITOR_VALUE(monitor), 1) + 1; \
+ value = my_atomic_add64_explicit( \
+ (int64*) &MONITOR_VALUE(monitor), 1, \
+ MY_MEMORY_ORDER_RELAXED) + 1; \
/* Note: This is not 100% accurate because of the \
inherent race, we ignore it due to performance. */ \
if (value > (ib_uint64_t) MONITOR_MAX_VALUE(monitor)) { \
@@ -624,8 +625,9 @@ Use MONITOR_DEC if appropriate mutex protection exists.
#define MONITOR_ATOMIC_DEC_LOW(monitor, enabled) \
if (enabled) { \
ib_uint64_t value; \
- value = my_atomic_add64( \
- (int64*) &MONITOR_VALUE(monitor), -1) - 1; \
+ value = my_atomic_add64_explicit( \
+ (int64*) &MONITOR_VALUE(monitor), -1, \
+ MY_MEMORY_ORDER_RELAXED) - 1; \
/* Note: This is not 100% accurate because of the \
inherent race, we ignore it due to performance. */ \
if (value < (ib_uint64_t) MONITOR_MIN_VALUE(monitor)) { \
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 580a660cedc..be29b184387 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -381,8 +381,6 @@ extern ulong srv_n_page_hash_locks;
/** Scan depth for LRU flush batch i.e.: number of blocks scanned*/
extern ulong srv_LRU_scan_depth;
/** Whether or not to flush neighbors of a block */
-extern ulong srv_buf_pool_dump_pct; /*!< dump that may % of each buffer
- pool during BP dump */
extern ulong srv_flush_neighbors;
/** Previously requested size */
extern ulint srv_buf_pool_old_size;
@@ -392,6 +390,10 @@ extern ulint srv_buf_pool_base_size;
extern ulint srv_buf_pool_curr_size;
/** Dump this % of each buffer pool during BP dump */
extern ulong srv_buf_pool_dump_pct;
+#ifdef UNIV_DEBUG
+/** Abort load after this amount of pages */
+extern ulong srv_buf_pool_load_pages_abort;
+#endif
/** Lock table size in bytes */
extern ulint srv_lock_table_size;
@@ -611,16 +613,16 @@ extern mysql_pfs_key_t trx_rollback_clean_thread_key;
schema */
# define pfs_register_thread(key) \
do { \
- struct PSI_thread* psi = PSI_THREAD_CALL(new_thread)(key, NULL, 0);\
+ struct PSI_thread* psi = PSI_CALL_new_thread(key, NULL, 0);\
/* JAN: TODO: MYSQL 5.7 PSI \
- PSI_THREAD_CALL(set_thread_os_id)(psi); */ \
- PSI_THREAD_CALL(set_thread)(psi); \
+ PSI_CALL_set_thread_os_id(psi); */ \
+ PSI_CALL_set_thread(psi); \
} while (0)
/* This macro delist the current thread from performance schema */
# define pfs_delete_thread() \
do { \
- PSI_THREAD_CALL(delete_current_thread)(); \
+ PSI_CALL_delete_current_thread(); \
} while (0)
# else
# define pfs_register_thread(key)
@@ -946,6 +948,7 @@ struct export_var_t{
char innodb_buffer_pool_dump_status[OS_FILE_MAX_PATH + 128];/*!< Buf pool dump status */
char innodb_buffer_pool_load_status[OS_FILE_MAX_PATH + 128];/*!< Buf pool load status */
char innodb_buffer_pool_resize_status[512];/*!< Buf pool resize status */
+ my_bool innodb_buffer_pool_load_incomplete;/*!< Buf pool load incomplete */
ulint innodb_buffer_pool_pages_total; /*!< Buffer pool size */
ulint innodb_buffer_pool_pages_data; /*!< Data pages */
ulint innodb_buffer_pool_bytes_data; /*!< File bytes used */
@@ -1018,9 +1021,6 @@ struct export_var_t{
ulint innodb_onlineddl_pct_progress; /*!< Online alter progress */
#ifdef UNIV_DEBUG
- ulint innodb_purge_trx_id_age; /*!< rw_max_trx_id - purged trx_id */
- ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id
- - purged view's min trx_id */
ulint innodb_ahi_drop_lookups; /*!< number of adaptive hash
index lookups when freeing
file pages */
diff --git a/storage/innobase/include/sync0policy.h b/storage/innobase/include/sync0policy.h
index a91270bde58..78e77f93269 100644
--- a/storage/innobase/include/sync0policy.h
+++ b/storage/innobase/include/sync0policy.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, 2018, 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
@@ -105,7 +105,7 @@ public:
msg << m_mutex->policy().to_string();
- if (os_thread_pf(m_thread_id) != ULINT_UNDEFINED) {
+ if (m_thread_id != ULINT_UNDEFINED) {
msg << " addr: " << m_mutex
<< " acquired: " << locked_from().c_str();
@@ -454,14 +454,7 @@ public:
void destroy()
UNIV_NOTHROW
{
- latch_meta_t& meta = sync_latch_get_meta(m_id);
-
- ut_ad(meta.get_id() == m_id);
-
- meta.get_counter()->sum_deregister(m_count);
-
m_count = NULL;
-
ut_d(MutexDebug<MutexType>::destroy());
}
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index 888a32007ce..b61553fc380 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -501,13 +501,13 @@ bool
rw_lock_lock_word_decr(
/*===================*/
rw_lock_t* lock, /*!< in/out: rw-lock */
- ulint amount, /*!< in: amount to decrement */
- lint threshold); /*!< in: threshold of judgement */
+ int32_t amount, /*!< in: amount to decrement */
+ int32_t threshold); /*!< in: threshold of judgement */
#ifdef UNIV_DEBUG
/******************************************************************//**
Checks if the thread has locked the rw-lock in the specified mode, with
the pass value == 0. */
-ibool
+bool
rw_lock_own(
/*========*/
rw_lock_t* lock, /*!< in: rw-lock */
@@ -571,10 +571,10 @@ struct rw_lock_t
#endif /* UNIV_DEBUG */
{
/** Holds the state of the lock. */
- volatile lint lock_word;
+ int32_t lock_word;
/** 1: there are waiters */
- volatile uint32_t waiters;
+ int32_t waiters;
/** number of granted SX locks. */
volatile ulint sx_recursive;
@@ -603,9 +603,6 @@ struct rw_lock_t
/** File name where lock created */
const char* cfile_name;
- /** last s-lock file/line is not guaranteed to be correct */
- const char* last_s_file_name;
-
/** File name where last x-locked */
const char* last_x_file_name;
@@ -615,9 +612,6 @@ struct rw_lock_t
/** If 1 then the rw-lock is a block lock */
unsigned is_block_lock:1;
- /** Line number where last time s-locked */
- unsigned last_s_line:14;
-
/** Line number where last time x-locked */
unsigned last_x_line:14;
diff --git a/storage/innobase/include/sync0rw.ic b/storage/innobase/include/sync0rw.ic
index a048476d0e8..8a1a3741b47 100644
--- a/storage/innobase/include/sync0rw.ic
+++ b/storage/innobase/include/sync0rw.ic
@@ -77,7 +77,8 @@ rw_lock_get_writer(
/*===============*/
const rw_lock_t* lock) /*!< in: rw-lock */
{
- lint lock_word = lock->lock_word;
+ int32_t lock_word = my_atomic_load32_explicit(const_cast<int32_t*>(&lock->lock_word),
+ MY_MEMORY_ORDER_RELAXED);
ut_ad(lock_word <= X_LOCK_DECR);
if (lock_word > X_LOCK_HALF_DECR) {
@@ -109,7 +110,8 @@ rw_lock_get_reader_count(
/*=====================*/
const rw_lock_t* lock) /*!< in: rw-lock */
{
- lint lock_word = lock->lock_word;
+ int32_t lock_word = my_atomic_load32_explicit(const_cast<int32_t*>(&lock->lock_word),
+ MY_MEMORY_ORDER_RELAXED);
ut_ad(lock_word <= X_LOCK_DECR);
if (lock_word > X_LOCK_HALF_DECR) {
@@ -145,7 +147,8 @@ rw_lock_get_x_lock_count(
/*=====================*/
const rw_lock_t* lock) /*!< in: rw-lock */
{
- lint lock_copy = lock->lock_word;
+ int32_t lock_copy = my_atomic_load32_explicit(const_cast<int32_t*>(&lock->lock_word),
+ MY_MEMORY_ORDER_RELAXED);
ut_ad(lock_copy <= X_LOCK_DECR);
if (lock_copy == 0 || lock_copy == -X_LOCK_HALF_DECR) {
@@ -178,7 +181,8 @@ rw_lock_get_sx_lock_count(
const rw_lock_t* lock) /*!< in: rw-lock */
{
#ifdef UNIV_DEBUG
- lint lock_copy = lock->lock_word;
+ int32_t lock_copy = my_atomic_load32_explicit(const_cast<int32_t*>(&lock->lock_word),
+ MY_MEMORY_ORDER_RELAXED);
ut_ad(lock_copy <= X_LOCK_DECR);
@@ -197,9 +201,7 @@ rw_lock_get_sx_lock_count(
}
/******************************************************************//**
-Two different implementations for decrementing the lock_word of a rw_lock:
-one for systems supporting atomic operations, one for others. This does
-does not support recusive x-locks: they should be handled by the caller and
+Recursive x-locks are not supported: they should be handled by the caller and
need not be atomic since they are performed by the current lock holder.
Returns true if the decrement was made, false if not.
@return true if decr occurs */
@@ -208,17 +210,17 @@ bool
rw_lock_lock_word_decr(
/*===================*/
rw_lock_t* lock, /*!< in/out: rw-lock */
- ulint amount, /*!< in: amount to decrement */
- lint threshold) /*!< in: threshold of judgement */
+ int32_t amount, /*!< in: amount to decrement */
+ int32_t threshold) /*!< in: threshold of judgement */
{
- lint local_lock_word;
-
- local_lock_word = my_atomic_loadlint_explicit(&lock->lock_word,
+ int32_t lock_copy = my_atomic_load32_explicit(&lock->lock_word,
MY_MEMORY_ORDER_RELAXED);
- while (local_lock_word > threshold) {
- if (my_atomic_caslint(&lock->lock_word,
- &local_lock_word,
- local_lock_word - amount)) {
+ while (lock_copy > threshold) {
+ if (my_atomic_cas32_strong_explicit(&lock->lock_word,
+ &lock_copy,
+ lock_copy - amount,
+ MY_MEMORY_ORDER_ACQUIRE,
+ MY_MEMORY_ORDER_RELAXED)) {
return(true);
}
}
@@ -247,11 +249,6 @@ rw_lock_s_lock_low(
ut_d(rw_lock_add_debug_info(lock, pass, RW_LOCK_S, file_name, line));
- /* These debugging values are not set safely: they may be incorrect
- or even refer to a line that is invalid for the file name. */
- lock->last_s_file_name = file_name;
- lock->last_s_line = line;
-
return(TRUE); /* locking succeeded */
}
@@ -306,29 +303,32 @@ rw_lock_x_lock_func_nowait(
const char* file_name,/*!< in: file name where lock requested */
unsigned line) /*!< in: line where requested */
{
- lint oldval = X_LOCK_DECR;
+ int32_t oldval = X_LOCK_DECR;
- if (my_atomic_caslint(&lock->lock_word, &oldval, 0)) {
+ if (my_atomic_cas32_strong_explicit(&lock->lock_word, &oldval, 0,
+ MY_MEMORY_ORDER_ACQUIRE,
+ MY_MEMORY_ORDER_RELAXED)) {
lock->writer_thread = os_thread_get_curr_id();
} else if (os_thread_eq(lock->writer_thread, os_thread_get_curr_id())) {
- /* Relock: this lock_word modification is safe since no other
- threads can modify (lock, unlock, or reserve) lock_word while
- there is an exclusive writer and this is the writer thread. */
- if (lock->lock_word == 0 || lock->lock_word == -X_LOCK_HALF_DECR) {
+ /* Relock: even though no other thread can modify (lock, unlock
+ or reserve) lock_word while there is an exclusive writer and
+ this is the writer thread, we still want concurrent threads to
+ observe consistent values. */
+ if (oldval == 0 || oldval == -X_LOCK_HALF_DECR) {
/* There are 1 x-locks */
- lock->lock_word -= X_LOCK_DECR;
- } else if (lock->lock_word <= -X_LOCK_DECR) {
+ my_atomic_add32_explicit(&lock->lock_word, -X_LOCK_DECR,
+ MY_MEMORY_ORDER_RELAXED);
+ } else if (oldval <= -X_LOCK_DECR) {
/* There are 2 or more x-locks */
- lock->lock_word--;
+ my_atomic_add32_explicit(&lock->lock_word, -1,
+ MY_MEMORY_ORDER_RELAXED);
+ /* Watch for too many recursive locks */
+ ut_ad(oldval < 1);
} else {
/* Failure */
return(FALSE);
}
-
- /* Watch for too many recursive locks */
- ut_ad(lock->lock_word < 0);
-
} else {
/* Failure */
return(FALSE);
@@ -357,8 +357,8 @@ rw_lock_s_unlock_func(
rw_lock_t* lock) /*!< in/out: rw-lock */
{
#ifdef UNIV_DEBUG
- lint dbg_lock_word = my_atomic_loadlint_explicit(
- &lock->lock_word, MY_MEMORY_ORDER_RELAXED);
+ int32_t dbg_lock_word = my_atomic_load32_explicit(&lock->lock_word,
+ MY_MEMORY_ORDER_RELAXED);
ut_ad(dbg_lock_word > -X_LOCK_DECR);
ut_ad(dbg_lock_word != 0);
ut_ad(dbg_lock_word < X_LOCK_DECR);
@@ -367,7 +367,8 @@ rw_lock_s_unlock_func(
ut_d(rw_lock_remove_debug_info(lock, pass, RW_LOCK_S));
/* Increment lock_word to indicate 1 less reader */
- lint lock_word = my_atomic_addlint(&lock->lock_word, 1) + 1;
+ int32_t lock_word = my_atomic_add32_explicit(&lock->lock_word, 1,
+ MY_MEMORY_ORDER_RELEASE) + 1;
if (lock_word == 0 || lock_word == -X_LOCK_HALF_DECR) {
/* wait_ex waiter exists. It may not be asleep, but we signal
@@ -393,9 +394,8 @@ rw_lock_x_unlock_func(
#endif /* UNIV_DEBUG */
rw_lock_t* lock) /*!< in/out: rw-lock */
{
- lint lock_word;
- lock_word = my_atomic_loadlint_explicit(&lock->lock_word,
- MY_MEMORY_ORDER_RELAXED);
+ int32_t lock_word = my_atomic_load32_explicit(&lock->lock_word,
+ MY_MEMORY_ORDER_RELAXED);
ut_ad(lock_word == 0 || lock_word == -X_LOCK_HALF_DECR
|| lock_word <= -X_LOCK_DECR);
@@ -408,31 +408,35 @@ rw_lock_x_unlock_func(
ut_d(rw_lock_remove_debug_info(lock, pass, RW_LOCK_X));
if (lock_word == 0 || lock_word == -X_LOCK_HALF_DECR) {
- /* There is 1 x-lock */
- /* atomic increment is needed, because it is last */
- if (my_atomic_addlint(&lock->lock_word, X_LOCK_DECR) <= -X_LOCK_DECR) {
- ut_error;
- }
+ /* Last X-lock owned by this thread, it may still hold SX-locks.
+ ACQ_REL due to...
+ RELEASE: we release rw-lock
+ ACQUIRE: we want waiters to be loaded after lock_word is stored */
+ my_atomic_add32_explicit(&lock->lock_word, X_LOCK_DECR,
+ MY_MEMORY_ORDER_ACQ_REL);
/* This no longer has an X-lock but it may still have
an SX-lock. So it is now free for S-locks by other threads.
We need to signal read/write waiters.
We do not need to signal wait_ex waiters, since they cannot
exist when there is a writer. */
- if (my_atomic_load32_explicit((int32*) &lock->waiters,
+ if (my_atomic_load32_explicit(&lock->waiters,
MY_MEMORY_ORDER_RELAXED)) {
- my_atomic_store32((int32*) &lock->waiters, 0);
+ my_atomic_store32_explicit(&lock->waiters, 0,
+ MY_MEMORY_ORDER_RELAXED);
os_event_set(lock->event);
sync_array_object_signalled();
}
} else if (lock_word == -X_LOCK_DECR
|| lock_word == -(X_LOCK_DECR + X_LOCK_HALF_DECR)) {
/* There are 2 x-locks */
- lock->lock_word += X_LOCK_DECR;
+ my_atomic_add32_explicit(&lock->lock_word, X_LOCK_DECR,
+ MY_MEMORY_ORDER_RELAXED);
} else {
/* There are more than 2 x-locks. */
ut_ad(lock_word < -X_LOCK_DECR);
- lock->lock_word += 1;
+ my_atomic_add32_explicit(&lock->lock_word, 1,
+ MY_MEMORY_ORDER_RELAXED);
}
ut_ad(rw_lock_validate(lock));
@@ -458,28 +462,37 @@ rw_lock_sx_unlock_func(
ut_d(rw_lock_remove_debug_info(lock, pass, RW_LOCK_SX));
if (lock->sx_recursive == 0) {
+ int32_t lock_word = my_atomic_load32_explicit(&lock->lock_word,
+ MY_MEMORY_ORDER_RELAXED);
/* Last caller in a possible recursive chain. */
- if (lock->lock_word > 0) {
+ if (lock_word > 0) {
lock->writer_thread = 0;
+ ut_ad(lock_word <= INT_MAX32 - X_LOCK_HALF_DECR);
+
+ /* Last SX-lock owned by this thread, doesn't own X-lock.
+ ACQ_REL due to...
+ RELEASE: we release rw-lock
+ ACQUIRE: we want waiters to be loaded after lock_word is stored */
+ my_atomic_add32_explicit(&lock->lock_word, X_LOCK_HALF_DECR,
+ MY_MEMORY_ORDER_ACQ_REL);
- if (my_atomic_addlint(&lock->lock_word, X_LOCK_HALF_DECR) <= 0) {
- ut_error;
- }
/* Lock is now free. May have to signal read/write
waiters. We do not need to signal wait_ex waiters,
since they cannot exist when there is an sx-lock
holder. */
- if (lock->waiters) {
- my_atomic_store32((int32*) &lock->waiters, 0);
+ if (my_atomic_load32_explicit(&lock->waiters,
+ MY_MEMORY_ORDER_RELAXED)) {
+ my_atomic_store32_explicit(&lock->waiters, 0,
+ MY_MEMORY_ORDER_RELAXED);
os_event_set(lock->event);
sync_array_object_signalled();
}
} else {
/* still has x-lock */
- ut_ad(lock->lock_word == -X_LOCK_HALF_DECR
- || lock->lock_word <= -(X_LOCK_DECR
- + X_LOCK_HALF_DECR));
- lock->lock_word += X_LOCK_HALF_DECR;
+ ut_ad(lock_word == -X_LOCK_HALF_DECR ||
+ lock_word <= -(X_LOCK_DECR + X_LOCK_HALF_DECR));
+ my_atomic_add32_explicit(&lock->lock_word, X_LOCK_HALF_DECR,
+ MY_MEMORY_ORDER_RELAXED);
}
}
diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
index aed8f769716..0d813b6bd87 100644
--- a/storage/innobase/include/sync0sync.h
+++ b/storage/innobase/include/sync0sync.h
@@ -93,9 +93,6 @@ 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;
-# ifdef UNIV_DEBUG
-extern mysql_pfs_key_t sync_thread_mutex_key;
-# endif /* UNIV_DEBUG */
extern mysql_pfs_key_t buf_dblwr_mutex_key;
extern mysql_pfs_key_t trx_undo_mutex_key;
extern mysql_pfs_key_t trx_mutex_key;
@@ -112,6 +109,7 @@ extern mysql_pfs_key_t sync_array_mutex_key;
extern mysql_pfs_key_t thread_mutex_key;
extern mysql_pfs_key_t zip_pad_mutex_key;
extern mysql_pfs_key_t row_drop_list_mutex_key;
+extern mysql_pfs_key_t rw_trx_hash_element_mutex_key;
#endif /* UNIV_PFS_MUTEX */
#ifdef UNIV_PFS_RWLOCK
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
index 1f8e245569e..e4fc24a7ede 100644
--- a/storage/innobase/include/sync0types.h
+++ b/storage/innobase/include/sync0types.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, 2018, 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
@@ -160,7 +160,7 @@ V
lock_sys_mutex Mutex protecting lock_sys_t
|
V
-trx_sys->mutex Mutex protecting trx_sys_t
+trx_sys.mutex Mutex protecting trx_sys_t
|
V
Threads mutex Background thread scheduling mutex
@@ -233,6 +233,7 @@ enum latch_level_t {
SYNC_REC_LOCK,
SYNC_THREADS,
SYNC_TRX,
+ SYNC_RW_TRX_HASH_ELEMENT,
SYNC_TRX_SYS,
SYNC_LOCK_SYS,
SYNC_LOCK_WAIT_SYS,
@@ -336,7 +337,6 @@ enum latch_id_t {
LATCH_ID_SRV_INNODB_MONITOR,
LATCH_ID_SRV_MISC_TMPFILE,
LATCH_ID_SRV_MONITOR_FILE,
- LATCH_ID_SYNC_THREAD,
LATCH_ID_BUF_DBLWR,
LATCH_ID_TRX_UNDO,
LATCH_ID_TRX_POOL,
@@ -383,6 +383,7 @@ enum latch_id_t {
LATCH_ID_FIL_CRYPT_STAT_MUTEX,
LATCH_ID_FIL_CRYPT_DATA_MUTEX,
LATCH_ID_FIL_CRYPT_THREADS_MUTEX,
+ LATCH_ID_RW_TRX_HASH_ELEMENT,
LATCH_ID_TEST_MUTEX,
LATCH_ID_MAX = LATCH_ID_TEST_MUTEX
};
@@ -636,14 +637,6 @@ public:
return(count);
}
- /** Deregister the count. We don't do anything
- @param[in] count The count instance to deregister */
- void sum_deregister(Count* count)
- UNIV_NOTHROW
- {
- /* Do nothing */
- }
-
/** Register a single instance counter */
void single_register(Count* count)
UNIV_NOTHROW
@@ -1161,17 +1154,34 @@ enum rw_lock_flag_t {
#endif /* UNIV_INNOCHECKSUM */
#ifdef _WIN64
-#define my_atomic_addlint(A,B) my_atomic_add64((int64*) (A), (B))
-#define my_atomic_loadlint(A) my_atomic_load64((int64*) (A))
-#define my_atomic_loadlint_explicit(A,O) my_atomic_load64_explicit((int64*) (A), (O))
-#define my_atomic_storelint(A,B) my_atomic_store64((int64*) (A), (B))
-#define my_atomic_caslint(A,B,C) my_atomic_cas64((int64*) (A), (int64*) (B), (C))
+static inline ulint my_atomic_addlint(ulint *A, ulint B)
+{
+ return ulint(my_atomic_add64((volatile int64*)A, B));
+}
+
+static inline ulint my_atomic_loadlint(const ulint *A)
+{
+ return ulint(my_atomic_load64((volatile int64*)A));
+}
+
+static inline lint my_atomic_addlint(volatile lint *A, lint B)
+{
+ return my_atomic_add64((volatile int64*)A, B);
+}
+
+static inline lint my_atomic_loadlint(const lint *A)
+{
+ return lint(my_atomic_load64((volatile int64*)A));
+}
+
+static inline void my_atomic_storelint(ulint *A, ulint B)
+{
+ my_atomic_store64((volatile int64*)A, B);
+}
#else
#define my_atomic_addlint my_atomic_addlong
#define my_atomic_loadlint my_atomic_loadlong
-#define my_atomic_loadlint_explicit my_atomic_loadlong_explicit
#define my_atomic_storelint my_atomic_storelong
-#define my_atomic_caslint my_atomic_caslong
#endif
/** Simple counter aligned to CACHE_LINE_SIZE
@@ -1197,7 +1207,7 @@ struct MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) simple_counter
#pragma warning (push)
#pragma warning (disable : 4244)
#endif
- return Type(my_atomic_addlint(reinterpret_cast<lint*>
+ return Type(my_atomic_addlint(reinterpret_cast<ulint*>
(&m_counter), i));
#ifdef _MSC_VER
#pragma warning (pop)
diff --git a/storage/innobase/include/trx0i_s.h b/storage/innobase/include/trx0i_s.h
index e02c5d88a29..ee7da7b74dc 100644
--- a/storage/innobase/include/trx0i_s.h
+++ b/storage/innobase/include/trx0i_s.h
@@ -264,10 +264,10 @@ trx_i_s_possibly_fetch_data_into_cache(
trx_i_s_cache_t* cache); /*!< in/out: cache */
/*******************************************************************//**
-Returns TRUE if the data in the cache is truncated due to the memory
+Returns true, if the data in the cache is truncated due to the memory
limit posed by TRX_I_S_MEM_LIMIT.
@return TRUE if truncated */
-ibool
+bool
trx_i_s_cache_is_truncated(
/*=======================*/
trx_i_s_cache_t* cache); /*!< in: cache */
diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h
index 0b42479cc21..2efcfc75a06 100644
--- a/storage/innobase/include/trx0purge.h
+++ b/storage/innobase/include/trx0purge.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2017, 2018, 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,15 +27,8 @@ Created 3/26/1996 Heikki Tuuri
#ifndef trx0purge_h
#define trx0purge_h
-#include "univ.i"
-#include "trx0types.h"
-#include "mtr0mtr.h"
-#include "trx0sys.h"
+#include "trx0rseg.h"
#include "que0types.h"
-#include "page0page.h"
-#include "usr0sess.h"
-#include "fil0fil.h"
-#include "read0types.h"
/** A dummy undo record used as a return value when we have a whole undo log
which needs no purge */
@@ -66,8 +59,6 @@ trx_purge(
/*======*/
ulint n_purge_threads, /*!< in: number of purge tasks to
submit to task queue. */
- ulint limit, /*!< in: the maximum number of
- records to purge in one batch */
bool truncate); /*!< in: truncate history if true */
/*******************************************************************//**
Stop purge and wait for it to stop, move to PURGE_STATE_STOP. */
@@ -104,69 +95,28 @@ private:
trx_rsegs_t;
public:
typedef trx_rsegs_t::iterator iterator;
+ typedef trx_rsegs_t::const_iterator const_iterator;
/** Default constructor */
- TrxUndoRsegs() : m_trx_no() { }
-
- explicit TrxUndoRsegs(trx_id_t trx_no)
- :
- m_trx_no(trx_no)
- {
- // Do nothing
- }
-
- /** Get transaction number
- @return trx_id_t - get transaction number. */
- trx_id_t get_trx_no() const
- {
- return(m_trx_no);
- }
-
- /** Add rollback segment.
- @param rseg rollback segment to add. */
- void push_back(trx_rseg_t* rseg)
- {
- m_rsegs.push_back(rseg);
- }
-
- /** Erase the element pointed by given iterator.
- @param[in] iterator iterator */
- void erase(iterator& it)
- {
- m_rsegs.erase(it);
- }
-
- /** Number of registered rsegs.
- @return size of rseg list. */
- ulint size() const
- {
- return(m_rsegs.size());
- }
-
- /**
- @return an iterator to the first element */
- iterator begin()
- {
- return(m_rsegs.begin());
- }
-
- /**
- @return an iterator to the end */
- iterator end()
- {
- return(m_rsegs.end());
- }
+ TrxUndoRsegs() {}
+ /** Constructor */
+ TrxUndoRsegs(trx_rseg_t& rseg)
+ : m_commit(rseg.last_commit), m_rsegs(1, &rseg) {}
+ /** Constructor */
+ TrxUndoRsegs(trx_id_t trx_no, trx_rseg_t& rseg)
+ : m_commit(trx_no << 1), m_rsegs(1, &rseg) {}
- /** Append rollback segments from referred instance to current
- instance. */
- void append(const TrxUndoRsegs& append_from)
- {
- ut_ad(get_trx_no() == append_from.get_trx_no());
+ /** @return the transaction commit identifier */
+ trx_id_t trx_no() const { return m_commit >> 1; }
- m_rsegs.insert(m_rsegs.end(),
- append_from.m_rsegs.begin(),
- append_from.m_rsegs.end());
- }
+ bool operator!=(const TrxUndoRsegs& other) const
+ { return m_commit != other.m_commit; }
+ bool empty() const { return m_rsegs.empty(); }
+ void erase(iterator& it) { m_rsegs.erase(it); }
+ iterator begin() { return(m_rsegs.begin()); }
+ iterator end() { return(m_rsegs.end()); }
+ const_iterator begin() const { return m_rsegs.begin(); }
+ const_iterator end() const { return m_rsegs.end(); }
/** Compare two TrxUndoRsegs based on trx_no.
@param elem1 first element to compare
@@ -174,17 +124,12 @@ public:
@return true if elem1 > elem2 else false.*/
bool operator()(const TrxUndoRsegs& lhs, const TrxUndoRsegs& rhs)
{
- return(lhs.m_trx_no > rhs.m_trx_no);
+ return(lhs.m_commit > rhs.m_commit);
}
- /** Compiler defined copy-constructor/assignment operator
- should be fine given that there is no reference to a memory
- object outside scope of class object.*/
-
private:
- /** The rollback segments transaction number. */
- trx_id_t m_trx_no;
-
+ /** Copy trx_rseg_t::last_commit */
+ trx_id_t m_commit;
/** Rollback segments of a transaction, scheduled for purge. */
trx_rsegs_t m_rsegs;
};
@@ -194,16 +139,14 @@ typedef std::priority_queue<
std::vector<TrxUndoRsegs, ut_allocator<TrxUndoRsegs> >,
TrxUndoRsegs> purge_pq_t;
-/**
-Chooses the rollback segment with the smallest trx_no. */
+/** Chooses the rollback segment with the oldest committed transaction */
struct TrxUndoRsegsIterator {
-
/** Constructor */
TrxUndoRsegsIterator();
-
/** Sets the next rseg to purge in purge_sys.
+ Executed in the purge coordinator thread.
@return whether anything is to be purged */
- bool set_next();
+ inline bool set_next();
private:
// Disable copying
@@ -211,38 +154,11 @@ private:
TrxUndoRsegsIterator& operator=(const TrxUndoRsegsIterator&);
/** The current element to process */
- TrxUndoRsegs m_trx_undo_rsegs;
-
- /** Track the current element in m_trx_undo_rseg */
- TrxUndoRsegs::iterator m_iter;
-
- /** Sentinel value */
- static const TrxUndoRsegs NullElement;
-};
-
-/** This is the purge pointer/iterator. We need both the undo no and the
-transaction no up to which purge has parsed and applied the records. */
-struct purge_iter_t {
- purge_iter_t()
- :
- trx_no(),
- undo_no(),
- undo_rseg_space(ULINT_UNDEFINED)
- {
- // Do nothing
- }
-
- trx_id_t trx_no; /*!< Purge has advanced past all
- transactions whose number is less
- than this */
- undo_no_t undo_no; /*!< Purge has advanced past all records
- whose undo number is less than this */
- ulint undo_rseg_space;
- /*!< Last undo record resided in this
- space id. */
+ TrxUndoRsegs m_rsegs;
+ /** Track the current element in m_rsegs */
+ TrxUndoRsegs::const_iterator m_iter;
};
-
/* Namespace to hold all the related functions and variables need for truncate
of undo tablespace. */
namespace undo {
@@ -288,17 +204,12 @@ namespace undo {
/** Track UNDO tablespace mark for truncate. */
class Truncate {
public:
-
- Truncate()
- :
- m_undo_for_trunc(ULINT_UNDEFINED),
- m_rseg_for_trunc(),
- m_scan_start(1),
- m_purge_rseg_truncate_frequency(
- static_cast<ulint>(
- srv_purge_rseg_truncate_frequency))
+ void create()
{
- /* Do Nothing. */
+ m_undo_for_trunc = ULINT_UNDEFINED;
+ m_scan_start = 1;
+ m_purge_rseg_truncate_frequency =
+ ulint(srv_purge_rseg_truncate_frequency);
}
/** Clear the cached rollback segment. Normally done
@@ -485,14 +396,9 @@ namespace undo {
/** The control structure used in the purge operation */
class purge_sys_t
{
+ bool m_initialised;
public:
- /** Construct the purge system. */
- purge_sys_t();
- /** Destruct the purge system. */
- ~purge_sys_t();
-
- sess_t* sess; /*!< System session running the purge
- query */
+ MY_ALIGNED(CACHE_LINE_SIZE)
rw_lock_t latch; /*!< The latch protecting the purge
view. A purge operation must acquire an
x-latch here for the instant at which
@@ -500,11 +406,14 @@ public:
log operation can prevent this by
obtaining an s-latch here. It also
protects state and running */
+ MY_ALIGNED(CACHE_LINE_SIZE)
os_event_t event; /*!< State signal event;
os_event_set() and os_event_reset()
are protected by purge_sys_t::latch
X-lock */
+ MY_ALIGNED(CACHE_LINE_SIZE)
ulint n_stop; /*!< Counter to track number stops */
+
volatile bool running; /*!< true, if purge is active,
we check this without the latch too */
volatile purge_state_t state; /*!< Purge coordinator thread states,
@@ -512,29 +421,40 @@ public:
without holding the latch. */
que_t* query; /*!< The query graph which will do the
parallelized purge operation */
+ MY_ALIGNED(CACHE_LINE_SIZE)
ReadView view; /*!< The purge will not remove undo logs
which are >= this view (purge view) */
- volatile ulint n_submitted; /*!< Count of total tasks submitted
+ ulint n_submitted; /*!< Count of total tasks submitted
to the task queue */
- volatile ulint n_completed; /*!< Count of total tasks completed */
-
- /*------------------------------*/
- /* The following two fields form the 'purge pointer' which advances
- during a purge, and which is used in history list truncation */
-
- purge_iter_t iter; /* Limit up to which we have read and
- parsed the UNDO log records. Not
- necessarily purged from the indexes.
- Note that this can never be less than
- the limit below, we check for this
- invariant in trx0purge.cc */
- purge_iter_t limit; /* The 'purge pointer' which advances
- during a purge, and which is used in
- history list truncation */
-#ifdef UNIV_DEBUG
- purge_iter_t done; /* Indicate 'purge pointer' which have
- purged already accurately. */
-#endif /* UNIV_DEBUG */
+ ulint n_completed; /*!< Count of total tasks completed */
+
+ /** Iterator to the undo log records of committed transactions */
+ struct iterator
+ {
+ bool operator<=(const iterator& other) const
+ {
+ if (commit < other.commit) return true;
+ if (commit > other.commit) return false;
+ return undo_no <= other.undo_no;
+ }
+
+ /** @return the commit number of the transaction */
+ trx_id_t trx_no() const { return commit >> 1; }
+ void reset_trx_no(trx_id_t trx_no) { commit = trx_no << 1; }
+
+ /** 2 * trx_t::no + old_insert of the committed transaction */
+ trx_id_t commit;
+ /** The record number within the committed transaction's undo
+ log, increasing, purged from from 0 onwards */
+ undo_no_t undo_no;
+ };
+
+ /** The tail of the purge queue; the last parsed undo log of a
+ committed transaction. */
+ iterator tail;
+ /** The head of the purge queue; any older undo logs of committed
+ transactions may be discarded (history list truncation). */
+ iterator head;
/*-----------------------------*/
bool next_stored; /*!< whether rseg holds the next record
to purge */
@@ -562,10 +482,30 @@ public:
undo::Truncate undo_trunc; /*!< Track UNDO tablespace marked
for truncate. */
+
+
+ /**
+ Constructor.
+
+ Some members may require late initialisation, thus we just mark object as
+ uninitialised. Real initialisation happens in create().
+ */
+
+ purge_sys_t() : m_initialised(false) {}
+
+
+ bool is_initialised() const { return m_initialised; }
+
+
+ /** Create the instance */
+ void create();
+
+ /** Close the purge system on shutdown */
+ void close();
};
/** The global data structure coordinating a purge */
-extern purge_sys_t* purge_sys;
+extern purge_sys_t purge_sys;
/** Info required to purge a record */
struct trx_purge_rec_t {
diff --git a/storage/innobase/include/trx0purge.ic b/storage/innobase/include/trx0purge.ic
index c32651b7a00..cd519a8e64d 100644
--- a/storage/innobase/include/trx0purge.ic
+++ b/storage/innobase/include/trx0purge.ic
@@ -40,24 +40,3 @@ trx_purge_get_log_from_hist(
return(node_addr);
}
-
-/********************************************************************//**
-address of its history list node.
-@return true if purge_sys_t::limit <= purge_sys_t::iter */
-UNIV_INLINE
-bool
-trx_purge_check_limit(void)
-/*=======================*/
-{
- /* limit is used to track till what point purge element has been
- processed and so limit <= iter.
- undo_no ordering is enforced only within the same rollback segment.
- If a transaction uses multiple rollback segments then we need to
- consider the rollback segment space id too. */
- return(purge_sys->iter.trx_no > purge_sys->limit.trx_no
- || (purge_sys->iter.trx_no == purge_sys->limit.trx_no
- && ((purge_sys->iter.undo_no >= purge_sys->limit.undo_no)
- || (purge_sys->iter.undo_rseg_space
- != purge_sys->limit.undo_rseg_space))));
-}
-
diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h
index ed45e1de82e..955a726eb50 100644
--- a/storage/innobase/include/trx0rec.h
+++ b/storage/innobase/include/trx0rec.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -155,6 +155,7 @@ trx_undo_rec_get_partial_row(
used, as we do NOT copy the data in the
record! */
dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: updated columns */
dtuple_t** row, /*!< out, own: partial row */
ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
@@ -162,6 +163,13 @@ trx_undo_rec_get_partial_row(
mem_heap_t* heap) /*!< in: memory heap from which the memory
needed is allocated */
MY_ATTRIBUTE((nonnull, warn_unused_result));
+/** Report a RENAME TABLE operation.
+@param[in,out] trx transaction
+@param[in] table table that is being renamed
+@return DB_SUCCESS or error code */
+dberr_t
+trx_undo_report_rename(trx_t* trx, const dict_table_t* table)
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/***********************************************************************//**
Writes information to an undo log about an insert, update, or a delete marking
of a clustered index record. This information is used in a rollback of the
@@ -188,10 +196,8 @@ trx_undo_report_row_operation(
marking, the record in the clustered
index; NULL if insert */
const ulint* offsets, /*!< in: rec_get_offsets(rec) */
- roll_ptr_t* roll_ptr) /*!< out: rollback pointer to the
- inserted undo log record,
- 0 if BTR_NO_UNDO_LOG
- flag was specified */
+ roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the
+ undo log record */
MY_ATTRIBUTE((nonnull(1,2,8), warn_unused_result));
/** status bit used for trx_undo_prev_version_build() */
@@ -238,25 +244,22 @@ trx_undo_prev_version_build(
into this function by purge thread or not.
And if we read "after image" of undo log */
-/***********************************************************//**
-Parses a redo log record of adding an undo log record.
-@return end of log record or NULL */
+/** Parse MLOG_UNDO_INSERT for crash-upgrade from MariaDB 10.2.
+@param[in] ptr log record
+@param[in] end_ptr end of log record buffer
+@param[in,out] page page or NULL
+@return end of log record
+@retval NULL if the log record is incomplete */
byte*
trx_undo_parse_add_undo_rec(
-/*========================*/
- byte* ptr, /*!< in: buffer */
- byte* end_ptr,/*!< in: buffer end */
- page_t* page); /*!< in: page or NULL */
-/***********************************************************//**
-Parses a redo log record of erasing of an undo page end.
-@return end of log record or NULL */
-byte*
-trx_undo_parse_erase_page_end(
-/*==========================*/
- byte* ptr, /*!< in: buffer */
- byte* end_ptr,/*!< in: buffer end */
- page_t* page, /*!< in: page or NULL */
- mtr_t* mtr); /*!< in: mtr or NULL */
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* page);
+/** Erase the unused undo log page end.
+@param[in,out] undo_page undo log page
+@return whether the page contained something */
+bool
+trx_undo_erase_page_end(page_t* undo_page);
/** Read from an undo log record a non-virtual column value.
@param[in,out] ptr pointer to remaining part of the undo record
@@ -307,7 +310,8 @@ trx_undo_read_v_idx(
compilation info multiplied by 16 is ORed to this value in an undo log
record */
-#define TRX_UNDO_INSERT_DEFAULT 10 /* insert a "default value"
+#define TRX_UNDO_RENAME_TABLE 9 /*!< RENAME TABLE */
+#define TRX_UNDO_INSERT_DEFAULT 10 /*!< insert a "default value"
pseudo-record for instant ALTER */
#define TRX_UNDO_INSERT_REC 11 /* fresh insert into clustered index */
#define TRX_UNDO_UPD_EXIST_REC 12 /* update of a non-delete-marked
diff --git a/storage/innobase/include/trx0rec.ic b/storage/innobase/include/trx0rec.ic
index 136e0edb468..5ae34c486cc 100644
--- a/storage/innobase/include/trx0rec.ic
+++ b/storage/innobase/include/trx0rec.ic
@@ -66,5 +66,8 @@ trx_undo_rec_copy(
len = mach_read_from_2(undo_rec)
- ut_align_offset(undo_rec, UNIV_PAGE_SIZE);
ut_ad(len < UNIV_PAGE_SIZE);
- return((trx_undo_rec_t*) mem_heap_dup(heap, undo_rec, len));
+ trx_undo_rec_t* rec = static_cast<trx_undo_rec_t*>(
+ mem_heap_dup(heap, undo_rec, len));
+ mach_write_to_2(rec, len);
+ return rec;
}
diff --git a/storage/innobase/include/trx0roll.h b/storage/innobase/include/trx0roll.h
index 8908376bff1..ba9c901d4f7 100644
--- a/storage/innobase/include/trx0roll.h
+++ b/storage/innobase/include/trx0roll.h
@@ -33,7 +33,8 @@ Created 3/26/1996 Heikki Tuuri
#include "mtr0mtr.h"
#include "trx0sys.h"
-extern bool trx_rollback_or_clean_is_active;
+extern bool trx_rollback_is_active;
+extern const trx_t* trx_roll_crash_recv_trx;
/*******************************************************************//**
Determines if this transaction is rolling back an incomplete transaction
@@ -62,16 +63,19 @@ trx_undo_rec_t*
trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap)
MY_ATTRIBUTE((nonnull, warn_unused_result));
+/** Report progress when rolling back a row of a recovered transaction.
+@return whether the rollback should be aborted due to pending shutdown */
+bool
+trx_roll_must_shutdown();
/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
-transaction was not yet committed, then we roll it back. */
+transaction was not yet committed, then we roll it back.
+@param all true=roll back all recovered active transactions;
+false=roll back any incomplete dictionary transaction */
void
-trx_rollback_or_clean_recovered(
-/*============================*/
- ibool all); /*!< in: FALSE=roll back dictionary transactions;
- TRUE=roll back all non-PREPARED transactions */
+trx_rollback_recovered(bool all);
/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
@@ -81,11 +85,7 @@ Note: this is done in a background thread.
@return a dummy parameter */
extern "C"
os_thread_ret_t
-DECLARE_THREAD(trx_rollback_or_clean_all_recovered)(
-/*================================================*/
- void* arg MY_ATTRIBUTE((unused)));
- /*!< in: a dummy parameter required by
- os_thread_create */
+DECLARE_THREAD(trx_rollback_all_recovered)(void*);
/*********************************************************************//**
Creates a rollback command node struct.
@return own: rollback node struct */
diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h
index c1961bb4169..d68ece39911 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, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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,10 +27,8 @@ Created 3/26/1996 Heikki Tuuri
#ifndef trx0rseg_h
#define trx0rseg_h
-#include "trx0types.h"
#include "trx0sys.h"
#include "fut0lst.h"
-#include <vector>
/** Gets a rollback segment header.
@param[in] space space where placed
@@ -57,16 +55,6 @@ trx_rsegf_get_new(
mtr_t* mtr);
/***************************************************************//**
-Gets the file page number of the nth undo log slot.
-@return page number of the undo log segment */
-UNIV_INLINE
-ulint
-trx_rsegf_get_nth_undo(
-/*===================*/
- trx_rsegf_t* rsegf, /*!< in: rollback segment header */
- ulint n, /*!< in: index of slot */
- mtr_t* mtr); /*!< in: mtr */
-/***************************************************************//**
Sets the file page number of the nth undo log slot. */
UNIV_INLINE
void
@@ -81,24 +69,21 @@ Looks for a free slot for an undo log segment.
@return slot index or ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
-trx_rsegf_undo_find_free(
-/*=====================*/
- trx_rsegf_t* rsegf, /*!< in: rollback segment header */
- mtr_t* mtr); /*!< in: mtr */
+trx_rsegf_undo_find_free(const trx_rsegf_t* rsegf);
/** Creates a rollback segment header.
This function is called only when a new rollback segment is created in
the database.
@param[in] space space id
-@param[in] max_size max size in pages
-@param[in] rseg_slot_no rseg id == slot number in trx sys
+@param[in] rseg_id rollback segment identifier
+@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
@param[in,out] mtr mini-transaction
@return page number of the created segment, FIL_NULL if fail */
ulint
trx_rseg_header_create(
ulint space,
- ulint max_size,
- ulint rseg_slot_no,
+ ulint rseg_id,
+ buf_block_t* sys_header,
mtr_t* mtr);
/** Initialize the rollback segments in memory at database startup. */
@@ -155,9 +140,6 @@ struct trx_rseg_t {
/** page number of the rollback segment header */
ulint page_no;
- /** maximum allowed size in pages */
- ulint max_size;
-
/** current size in pages */
ulint curr_size;
@@ -182,8 +164,8 @@ struct trx_rseg_t {
/** Byte offset of the last not yet purged log header */
ulint last_offset;
- /** Transaction number of the last not yet purged log */
- trx_id_t last_trx_no;
+ /** trx_t::no * 2 + old_insert of the last not yet purged log */
+ trx_id_t last_commit;
/** Whether the log segment needs purge */
bool needs_purge;
@@ -195,6 +177,14 @@ struct trx_rseg_t {
UNDO-tablespace marked for truncate. */
bool skip_allocation;
+ /** @return the commit ID of the last committed transaction */
+ trx_id_t last_trx_no() const { return last_commit >> 1; }
+
+ void set_last_trx_no(trx_id_t trx_no, bool is_update)
+ {
+ last_commit = trx_no << 1 | trx_id_t(is_update);
+ }
+
/** @return whether the rollback segment is persistent */
bool is_persistent() const
{
@@ -228,19 +218,100 @@ struct trx_rseg_t {
/* Transaction rollback segment header */
/*-------------------------------------------------------------*/
-#define TRX_RSEG_MAX_SIZE 0 /* Maximum allowed size for rollback
- segment in pages */
-#define TRX_RSEG_HISTORY_SIZE 4 /* Number of file pages occupied
- by the logs in the history list */
-#define TRX_RSEG_HISTORY 8 /* The update undo logs for committed
- transactions */
+/** 0xfffffffe = pre-MariaDB 10.3.5 format; 0=MariaDB 10.3.5 or later */
+#define TRX_RSEG_FORMAT 0
+/** Number of pages in the TRX_RSEG_HISTORY list */
+#define TRX_RSEG_HISTORY_SIZE 4
+/** Committed transaction logs that have not been purged yet */
+#define TRX_RSEG_HISTORY 8
#define TRX_RSEG_FSEG_HEADER (8 + FLST_BASE_NODE_SIZE)
/* Header for the file segment where
this page is placed */
#define TRX_RSEG_UNDO_SLOTS (8 + FLST_BASE_NODE_SIZE + FSEG_HEADER_SIZE)
/* Undo log segment slots */
+/** Maximum transaction ID (valid only if TRX_RSEG_FORMAT is 0) */
+#define TRX_RSEG_MAX_TRX_ID (TRX_RSEG_UNDO_SLOTS + TRX_RSEG_N_SLOTS \
+ * TRX_RSEG_SLOT_SIZE)
+
+/** 8 bytes offset within the binlog file */
+#define TRX_RSEG_BINLOG_OFFSET TRX_RSEG_MAX_TRX_ID + 8
+/** MySQL log file name, 512 bytes, including terminating NUL
+(valid only if TRX_RSEG_FORMAT is 0).
+If no binlog information is present, the first byte is NUL. */
+#define TRX_RSEG_BINLOG_NAME TRX_RSEG_MAX_TRX_ID + 16
+/** Maximum length of binlog file name, including terminating NUL, in bytes */
+#define TRX_RSEG_BINLOG_NAME_LEN 512
+
+#ifdef WITH_WSREP
+/** The offset to WSREP XID headers */
+#define TRX_RSEG_WSREP_XID_INFO TRX_RSEG_MAX_TRX_ID + 16 + 512
+
+/** WSREP XID format (1 if present and valid, 0 if not present) */
+#define TRX_RSEG_WSREP_XID_FORMAT TRX_RSEG_WSREP_XID_INFO
+/** WSREP XID GTRID length */
+#define TRX_RSEG_WSREP_XID_GTRID_LEN TRX_RSEG_WSREP_XID_INFO + 4
+/** WSREP XID bqual length */
+#define TRX_RSEG_WSREP_XID_BQUAL_LEN TRX_RSEG_WSREP_XID_INFO + 8
+/** WSREP XID data (XIDDATASIZE bytes) */
+#define TRX_RSEG_WSREP_XID_DATA TRX_RSEG_WSREP_XID_INFO + 12
+#endif /* WITH_WSREP*/
+
/*-------------------------------------------------------------*/
+/** Read the page number of an undo log slot.
+@param[in] rsegf rollback segment header
+@param[in] n slot number */
+inline
+uint32_t
+trx_rsegf_get_nth_undo(const trx_rsegf_t* rsegf, ulint n)
+{
+ ut_ad(n < TRX_RSEG_N_SLOTS);
+ return mach_read_from_4(rsegf + TRX_RSEG_UNDO_SLOTS
+ + n * TRX_RSEG_SLOT_SIZE);
+}
+
+#ifdef WITH_WSREP
+/** Update the WSREP XID information in rollback segment header.
+@param[in,out] rseg_header rollback segment header
+@param[in] xid WSREP XID
+@param[in,out] mtr mini-transaction */
+void
+trx_rseg_update_wsrep_checkpoint(
+ trx_rsegf_t* rseg_header,
+ const XID* xid,
+ mtr_t* mtr);
+
+/** Update WSREP checkpoint XID in first rollback segment header.
+@param[in] xid WSREP XID */
+void trx_rseg_update_wsrep_checkpoint(const XID* xid);
+
+/** Read the WSREP XID information in rollback segment header.
+@param[in] rseg_header Rollback segment header
+@param[out] xid Transaction XID
+@return whether the WSREP XID was present */
+bool trx_rseg_read_wsrep_checkpoint(const trx_rsegf_t* rseg_header, XID& xid);
+
+/** Recover the latest WSREP checkpoint XID.
+@param[out] xid WSREP XID
+@return whether the WSREP XID was found */
+bool trx_rseg_read_wsrep_checkpoint(XID& xid);
+#endif /* WITH_WSREP */
+
+/** Upgrade a rollback segment header page to MariaDB 10.3 format.
+@param[in,out] rseg_header rollback segment header page
+@param[in,out] mtr mini-transaction */
+void trx_rseg_format_upgrade(trx_rsegf_t* rseg_header, mtr_t* mtr);
+
+/** Update the offset information about the end of the binlog entry
+which corresponds to the transaction just being committed.
+In a replication slave, this updates the master binlog position
+up to which replication has proceeded.
+@param[in,out] rseg_header rollback segment header
+@param[in] trx committing transaction
+@param[in,out] mtr mini-transaction */
+void
+trx_rseg_update_binlog_offset(byte* rseg_header, const trx_t* trx, mtr_t* mtr);
+
#include "trx0rseg.ic"
#endif
diff --git a/storage/innobase/include/trx0rseg.ic b/storage/innobase/include/trx0rseg.ic
index 45ee3ef8d66..dd0ce8b3719 100644
--- a/storage/innobase/include/trx0rseg.ic
+++ b/storage/innobase/include/trx0rseg.ic
@@ -86,23 +86,6 @@ trx_rsegf_get_new(
}
/***************************************************************//**
-Gets the file page number of the nth undo log slot.
-@return page number of the undo log segment */
-UNIV_INLINE
-ulint
-trx_rsegf_get_nth_undo(
-/*===================*/
- trx_rsegf_t* rsegf, /*!< in: rollback segment header */
- ulint n, /*!< in: index of slot */
- mtr_t* mtr) /*!< in: mtr */
-{
- ut_a(n < TRX_RSEG_N_SLOTS);
-
- return(mtr_read_ulint(rsegf + TRX_RSEG_UNDO_SLOTS
- + n * TRX_RSEG_SLOT_SIZE, MLOG_4BYTES, mtr));
-}
-
-/***************************************************************//**
Sets the file page number of the nth undo log slot. */
UNIV_INLINE
void
@@ -124,10 +107,7 @@ Looks for a free slot for an undo log segment.
@return slot index or ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
-trx_rsegf_undo_find_free(
-/*=====================*/
- trx_rsegf_t* rsegf, /*!< in: rollback segment header */
- mtr_t* mtr) /*!< in: mtr */
+trx_rsegf_undo_find_free(const trx_rsegf_t* rsegf)
{
ulint i;
ulint page_no;
@@ -141,7 +121,7 @@ trx_rsegf_undo_find_free(
#endif
for (i = 0; i < max_slots; i++) {
- page_no = trx_rsegf_get_nth_undo(rsegf, i, mtr);
+ page_no = trx_rsegf_get_nth_undo(rsegf, i);
if (page_no == FIL_NULL) {
return(i);
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index dd8929911c6..00f245a05c0 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, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -35,7 +35,6 @@ Created 3/26/1996 Heikki Tuuri
#include "mem0mem.h"
#include "mtr0mtr.h"
#include "ut0byte.h"
-#include "mem0mem.h"
#include "ut0lst.h"
#include "read0types.h"
#include "page0types.h"
@@ -47,122 +46,61 @@ Created 3/26/1996 Heikki Tuuri
typedef UT_LIST_BASE_NODE_T(trx_t) trx_ut_list_t;
-// Forward declaration
-class MVCC;
-class ReadView;
-
-/** The transaction system */
-extern trx_sys_t* trx_sys;
-
/** Checks if a page address is the trx sys header page.
@param[in] page_id page id
@return true if trx sys header page */
-UNIV_INLINE
+inline
bool
-trx_sys_hdr_page(
- const page_id_t& page_id);
-
-/** Initialize the transaction system main-memory data structures. */
-void trx_sys_init_at_db_start();
+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);
+}
/*****************************************************************//**
-Creates the trx_sys instance and initializes purge_queue and mutex. */
-void
-trx_sys_create(void);
-/*================*/
-/*****************************************************************//**
Creates and initializes the transaction system at the database creation. */
void
trx_sys_create_sys_pages(void);
/*==========================*/
-/** @return an unallocated rollback segment slot in the TRX_SYS header
+/** Find an available rollback segment.
+@param[in] sys_header
+@return an unallocated rollback segment slot in the TRX_SYS header
@retval ULINT_UNDEFINED if not found */
ulint
-trx_sysf_rseg_find_free(mtr_t* mtr);
-/**********************************************************************//**
-Gets a pointer to the transaction system file copy and x-locks its page.
-@return pointer to system file copy, page x-locked */
-UNIV_INLINE
-trx_sysf_t*
-trx_sysf_get(
-/*=========*/
- mtr_t* mtr); /*!< in: mtr */
-/*****************************************************************//**
-Gets the space of the nth rollback segment slot in the trx system
-file copy.
-@return space id */
-UNIV_INLINE
-ulint
-trx_sysf_rseg_get_space(
-/*====================*/
- trx_sysf_t* sys_header, /*!< in: trx sys file copy */
- ulint i, /*!< in: slot index == rseg id */
- mtr_t* mtr); /*!< in: mtr */
-/*****************************************************************//**
-Gets the page number of the nth rollback segment slot in the trx system
-file copy.
-@return page number, FIL_NULL if slot unused */
-UNIV_INLINE
-ulint
-trx_sysf_rseg_get_page_no(
-/*======================*/
- trx_sysf_t* sys_header, /*!< in: trx sys file copy */
- ulint i, /*!< in: slot index == rseg id */
- mtr_t* mtr); /*!< in: mtr */
-/*****************************************************************//**
-Sets the space id of the nth rollback segment slot in the trx system
-file copy. */
-UNIV_INLINE
-void
-trx_sysf_rseg_set_space(
-/*====================*/
- trx_sysf_t* sys_header, /*!< in: trx sys file copy */
- ulint i, /*!< in: slot index == rseg id */
- ulint space, /*!< in: space id */
- mtr_t* mtr); /*!< in: mtr */
-/*****************************************************************//**
-Sets the page number of the nth rollback segment slot in the trx system
-file copy. */
-UNIV_INLINE
-void
-trx_sysf_rseg_set_page_no(
-/*======================*/
- trx_sysf_t* sys_header, /*!< in: trx sys file copy */
- ulint i, /*!< in: slot index == rseg id */
- ulint page_no, /*!< in: page number, FIL_NULL if
- the slot is reset to unused */
- mtr_t* mtr); /*!< in: mtr */
-/*****************************************************************//**
-Allocates a new transaction id.
-@return new, allocated trx id */
-UNIV_INLINE
-trx_id_t
-trx_sys_get_new_trx_id();
-/*===================*/
-/*****************************************************************//**
-Determines the maximum transaction id.
-@return maximum currently allocated trx id; will be stale after the
-next call to trx_sys_get_new_trx_id() */
-UNIV_INLINE
-trx_id_t
-trx_sys_get_max_trx_id(void);
-/*========================*/
+trx_sys_rseg_find_free(const buf_block_t* sys_header);
+/** Request the TRX_SYS page.
+@param[in] rw whether to lock the page for writing
+@return the TRX_SYS page
+@retval NULL if the page cannot be read */
+inline
+buf_block_t*
+trx_sysf_get(mtr_t* mtr, bool rw = true)
+{
+ buf_block_t* block = buf_page_get(
+ page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO),
+ univ_page_size, rw ? RW_X_LATCH : RW_S_LATCH, mtr);
+ if (block) {
+ buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
+ }
+ return block;
+}
#ifdef UNIV_DEBUG
/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
extern uint trx_rseg_n_slots_debug;
#endif
-/*****************************************************************//**
-Writes a trx id to an index page. In case that the id size changes in
-some future version, this function should be used instead of
-mach_write_... */
+/** Write DB_TRX_ID.
+@param[out] db_trx_id the DB_TRX_ID field to be written to
+@param[in] id transaction ID */
UNIV_INLINE
void
-trx_write_trx_id(
-/*=============*/
- byte* ptr, /*!< in: pointer to memory where written */
- trx_id_t id); /*!< in: id */
+trx_write_trx_id(byte* db_trx_id, trx_id_t id)
+{
+ compile_time_assert(DATA_TRX_ID_LEN == 6);
+ ut_ad(id);
+ mach_write_to_6(db_trx_id, id);
+}
/** Read a transaction identifier.
@return id */
@@ -170,9 +108,7 @@ inline
trx_id_t
trx_read_trx_id(const byte* ptr)
{
-#if DATA_TRX_ID_LEN != 6
-# error "DATA_TRX_ID_LEN != 6"
-#endif
+ compile_time_assert(DATA_TRX_ID_LEN == 6);
return(mach_read_from_6(ptr));
}
@@ -188,59 +124,6 @@ inline bool trx_id_check(const void* db_trx_id, trx_id_t trx_id)
}
#endif
-/****************************************************************//**
-Looks for the trx instance with the given id in the rw trx_list.
-@return the trx handle or NULL if not found */
-UNIV_INLINE
-trx_t*
-trx_get_rw_trx_by_id(
-/*=================*/
- trx_id_t trx_id);/*!< in: trx id to search for */
-/****************************************************************//**
-Returns the minimum trx id in rw trx list. This is the smallest id for which
-the trx can possibly be active. (But, you must look at the trx->state to
-find out if the minimum trx id transaction itself is active, or already
-committed.)
-@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
-UNIV_INLINE
-trx_id_t
-trx_rw_min_trx_id(void);
-/*===================*/
-/****************************************************************//**
-Checks if a rw transaction with the given id is active.
-@return transaction instance if active, or NULL */
-UNIV_INLINE
-trx_t*
-trx_rw_is_active_low(
-/*=================*/
- trx_id_t trx_id, /*!< in: trx id of the transaction */
- ibool* corrupt); /*!< in: NULL or pointer to a flag
- that will be set if corrupt */
-/****************************************************************//**
-Checks if a rw transaction with the given id is active. If the caller is
-not holding trx_sys->mutex, the transaction may already have been
-committed.
-@return transaction instance if active, or NULL; */
-UNIV_INLINE
-trx_t*
-trx_rw_is_active(
-/*=============*/
- trx_id_t trx_id, /*!< in: trx id of the transaction */
- ibool* corrupt, /*!< in: NULL or pointer to a flag
- that will be set if corrupt */
- bool do_ref_count); /*!< in: if true then increment the
- trx_t::n_ref_count */
-#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
-/***********************************************************//**
-Assert that a transaction has been recovered.
-@return TRUE */
-UNIV_INLINE
-ibool
-trx_assert_recovered(
-/*=================*/
- trx_id_t trx_id) /*!< in: transaction identifier */
- MY_ATTRIBUTE((warn_unused_result));
-#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
/*****************************************************************//**
Updates the offset information about the end of the MySQL binlog entry
which corresponds to the transaction just being committed. In a MySQL
@@ -251,72 +134,17 @@ trx_sys_update_mysql_binlog_offset(
/*===============================*/
const char* file_name,/*!< in: MySQL log file name */
int64_t offset, /*!< in: position in that log file */
- trx_sysf_t* sys_header, /*!< in: trx sys header */
- mtr_t* mtr); /*!< in: mtr */
+ buf_block_t* sys_header, /*!< in,out: trx sys header */
+ mtr_t* mtr); /*!< in,out: mini-transaction */
/** Display the MySQL binlog offset info if it is present in the trx
system header. */
void
trx_sys_print_mysql_binlog_offset();
-#ifdef WITH_WSREP
-/** Update WSREP XID info in sys_header of TRX_SYS_PAGE_NO = 5.
-@param[in] xid Transaction XID
-@param[in,out] sys_header sys_header
-@param[in] mtr minitransaction */
-UNIV_INTERN
-void
-trx_sys_update_wsrep_checkpoint(
- const XID* xid,
- trx_sysf_t* sys_header,
- mtr_t* mtr);
-
-/** Read WSREP checkpoint XID from sys header.
-@param[out] xid WSREP XID
-@return whether the checkpoint was present */
-UNIV_INTERN
-bool
-trx_sys_read_wsrep_checkpoint(XID* xid);
-#endif /* WITH_WSREP */
-
-/*****************************************************************//**
-Shutdown/Close the transaction system. */
-void
-trx_sys_close(void);
-/*===============*/
/** Create the rollback segments.
@return whether the creation succeeded */
bool
trx_sys_create_rsegs();
-/*****************************************************************//**
-Get the number of transaction in the system, independent of their state.
-@return count of transactions in trx_sys_t::trx_list */
-UNIV_INLINE
-ulint
-trx_sys_get_n_rw_trx(void);
-/*======================*/
-
-/*********************************************************************
-Check if there are any active (non-prepared) transactions.
-@return total number of active transactions or 0 if none */
-ulint
-trx_sys_any_active_transactions(void);
-/*=================================*/
-
-/**
-Add the transaction to the RW transaction set
-@param trx transaction instance to add */
-UNIV_INLINE
-void
-trx_sys_rw_trx_add(trx_t* trx);
-
-#ifdef UNIV_DEBUG
-/*************************************************************//**
-Validate the trx_sys_t::rw_trx_list.
-@return true if the list is valid */
-bool
-trx_sys_validate_trx_list();
-/*========================*/
-#endif /* UNIV_DEBUG */
/** The automatically created system rollback segment has this id */
#define TRX_SYS_SYSTEM_RSEG_ID 0
@@ -326,18 +154,13 @@ trx_sys_validate_trx_list();
/** Transaction system header */
/*------------------------------------------------------------- @{ */
-#define TRX_SYS_TRX_ID_STORE 0 /*!< the maximum trx id or trx
- number modulo
- TRX_SYS_TRX_ID_UPDATE_MARGIN
- written to a file page by any
- transaction; the assignment of
- transaction ids continues from
- this number rounded up by
- TRX_SYS_TRX_ID_UPDATE_MARGIN
- plus
- TRX_SYS_TRX_ID_UPDATE_MARGIN
- when the database is
- started */
+/** In old versions of InnoDB, this persisted the value of
+trx_sys.get_max_trx_id(). Starting with MariaDB 10.3.5,
+the field TRX_RSEG_MAX_TRX_ID in rollback segment header pages
+and the fields TRX_UNDO_TRX_ID, TRX_UNDO_TRX_NO in undo log pages
+are used instead. The field only exists for the purpose of upgrading
+from older MySQL or MariaDB versions. */
+#define TRX_SYS_TRX_ID_STORE 0
#define TRX_SYS_FSEG_HEADER 8 /*!< segment header for the
tablespace segment the trx
system is created into */
@@ -347,16 +170,52 @@ trx_sys_validate_trx_list();
slots */
/*------------------------------------------------------------- @} */
-/* Max number of rollback segments: the number of segment specification slots
-in the transaction system array; rollback segment id must fit in one (signed)
-byte, therefore 128; each slot is currently 8 bytes in size. If you want
-to raise the level to 256 then you will need to fix some assertions that
-impose the 7 bit restriction. e.g., mach_write_to_3() */
+/** The number of rollback segments; rollback segment id must fit in
+the 7 bits reserved for it in DB_ROLL_PTR. */
#define TRX_SYS_N_RSEGS 128
/** Maximum number of undo tablespaces (not counting the system tablespace) */
#define TRX_SYS_MAX_UNDO_SPACES (TRX_SYS_N_RSEGS - 1)
-/** Maximum length of MySQL binlog file name, in bytes. */
+/* Rollback segment specification slot offsets */
+
+/** the tablespace ID of an undo log header; starting with
+MySQL/InnoDB 5.1.7, this is FIL_NULL if the slot is unused */
+#define TRX_SYS_RSEG_SPACE 0
+/** the page number of an undo log header, or FIL_NULL if unused */
+#define TRX_SYS_RSEG_PAGE_NO 4
+/** Size of a rollback segment specification slot */
+#define TRX_SYS_RSEG_SLOT_SIZE 8
+
+/** Read the tablespace ID of a rollback segment slot.
+@param[in] sys_header TRX_SYS page
+@param[in] rseg_id rollback segment identifier
+@return undo tablespace id */
+inline
+uint32_t
+trx_sysf_rseg_get_space(const buf_block_t* sys_header, ulint rseg_id)
+{
+ ut_ad(rseg_id < TRX_SYS_N_RSEGS);
+ return mach_read_from_4(TRX_SYS + TRX_SYS_RSEGS + TRX_SYS_RSEG_SPACE
+ + rseg_id * TRX_SYS_RSEG_SLOT_SIZE
+ + sys_header->frame);
+}
+
+/** Read the page number of a rollback segment slot.
+@param[in] sys_header TRX_SYS page
+@param[in] rseg_id rollback segment identifier
+@return undo page number */
+inline
+uint32_t
+trx_sysf_rseg_get_page_no(const buf_block_t* sys_header, ulint rseg_id)
+{
+ ut_ad(rseg_id < TRX_SYS_N_RSEGS);
+ return mach_read_from_4(TRX_SYS + TRX_SYS_RSEGS + TRX_SYS_RSEG_PAGE_NO
+ + rseg_id * TRX_SYS_RSEG_SLOT_SIZE
+ + sys_header->frame);
+}
+
+/** Maximum length of MySQL binlog file name, in bytes.
+(Used before MariaDB 10.3.5.) */
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512
/** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
@@ -433,7 +292,7 @@ FIXED WSREP XID info offsets for 4k page size 10.0.32-galera
*/
#ifdef WITH_WSREP
-/** The offset to WSREP XID headers */
+/** The offset to WSREP XID headers (used before MariaDB 10.3.5) */
#define TRX_SYS_WSREP_XID_INFO std::max(srv_page_size - 3500, 1596UL)
#define TRX_SYS_WSREP_XID_MAGIC_N_FLD 0
#define TRX_SYS_WSREP_XID_MAGIC_N 0x77737265
@@ -497,42 +356,466 @@ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID. */
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
/* @} */
+trx_t* current_trx();
+
+struct rw_trx_hash_element_t
+{
+ rw_trx_hash_element_t(): trx(0)
+ {
+ mutex_create(LATCH_ID_RW_TRX_HASH_ELEMENT, &mutex);
+ }
+
+
+ ~rw_trx_hash_element_t()
+ {
+ mutex_free(&mutex);
+ }
+
+
+ trx_id_t id; /* lf_hash_init() relies on this to be first in the struct */
+ trx_id_t no;
+ trx_t *trx;
+ ib_mutex_t mutex;
+};
+
+
+/**
+ Wrapper around LF_HASH to store set of in memory read-write transactions.
+*/
+
+class rw_trx_hash_t
+{
+ LF_HASH hash;
+
+
+ /**
+ Constructor callback for lock-free allocator.
+
+ Object is just allocated and is not yet accessible via rw_trx_hash by
+ concurrent threads. Object can be reused multiple times before it is freed.
+ Every time object is being reused initializer() callback is called.
+ */
+
+ static void rw_trx_hash_constructor(uchar *arg)
+ {
+ new(arg + LF_HASH_OVERHEAD) rw_trx_hash_element_t();
+ }
+
+
+ /**
+ Destructor callback for lock-free allocator.
+
+ Object is about to be freed and is not accessible via rw_trx_hash by
+ concurrent threads.
+ */
+
+ static void rw_trx_hash_destructor(uchar *arg)
+ {
+ reinterpret_cast<rw_trx_hash_element_t*>
+ (arg + LF_HASH_OVERHEAD)->~rw_trx_hash_element_t();
+ }
+
+
+ /**
+ Destructor callback for lock-free allocator.
+
+ This destructor is used at shutdown. It frees remaining transaction
+ objects.
+
+ XA PREPARED transactions may remain if they haven't been committed or
+ rolled back. ACTIVE transactions may remain if startup was interrupted or
+ server is running in read-only mode or for certain srv_force_recovery
+ levels.
+ */
+
+ static void rw_trx_hash_shutdown_destructor(uchar *arg)
+ {
+ rw_trx_hash_element_t *element=
+ reinterpret_cast<rw_trx_hash_element_t*>(arg + LF_HASH_OVERHEAD);
+ if (trx_t *trx= element->trx)
+ {
+ ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED) ||
+ (trx_state_eq(trx, TRX_STATE_ACTIVE) &&
+ (!srv_was_started ||
+ srv_read_only_mode ||
+ srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO)));
+ trx_free_at_shutdown(trx);
+ }
+ element->~rw_trx_hash_element_t();
+ }
+
+
+ /**
+ Initializer callback for lock-free hash.
+
+ Object is not yet accessible via rw_trx_hash by concurrent threads, but is
+ about to become such. Object id can be changed only by this callback and
+ remains the same until all pins to this object are released.
+
+ Object trx can be changed to 0 by erase() under object mutex protection,
+ which indicates it is about to be removed from lock-free hash and become
+ not accessible by concurrent threads.
+ */
+
+ static void rw_trx_hash_initializer(LF_HASH *,
+ rw_trx_hash_element_t *element,
+ trx_t *trx)
+ {
+ ut_ad(element->trx == 0);
+ element->trx= trx;
+ element->id= trx->id;
+ element->no= TRX_ID_MAX;
+ trx->rw_trx_hash_element= element;
+ }
+
+
+ /**
+ Gets LF_HASH pins.
+
+ Pins are used to protect object from being destroyed or reused. They are
+ normally stored in trx object for quick access. If caller doesn't have trx
+ available, we try to get it using currnet_trx(). If caller doesn't have trx
+ at all, temporary pins are allocated.
+ */
+
+ LF_PINS *get_pins(trx_t *trx)
+ {
+ if (!trx->rw_trx_hash_pins)
+ {
+ trx->rw_trx_hash_pins= lf_hash_get_pins(&hash);
+ ut_a(trx->rw_trx_hash_pins);
+ }
+ return trx->rw_trx_hash_pins;
+ }
+
+
+ struct eliminate_duplicates_arg
+ {
+ trx_ids_t ids;
+ my_hash_walk_action action;
+ void *argument;
+ eliminate_duplicates_arg(size_t size, my_hash_walk_action act, void* arg):
+ action(act), argument(arg) { ids.reserve(size); }
+ };
+
+
+ static my_bool eliminate_duplicates(rw_trx_hash_element_t *element,
+ eliminate_duplicates_arg *arg)
+ {
+ for (trx_ids_t::iterator it= arg->ids.begin(); it != arg->ids.end(); it++)
+ {
+ if (*it == element->id)
+ return 0;
+ }
+ arg->ids.push_back(element->id);
+ return arg->action(element, arg->argument);
+ }
+
+
+#ifdef UNIV_DEBUG
+ static void validate_element(trx_t *trx)
+ {
+ ut_ad(!trx->read_only || !trx->rsegs.m_redo.rseg);
+ ut_ad(!trx_is_autocommit_non_locking(trx));
+ mutex_enter(&trx->mutex);
+ ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) ||
+ trx_state_eq(trx, TRX_STATE_PREPARED));
+ mutex_exit(&trx->mutex);
+ }
+
+
+ struct debug_iterator_arg
+ {
+ my_hash_walk_action action;
+ void *argument;
+ };
+
+
+ static my_bool debug_iterator(rw_trx_hash_element_t *element,
+ debug_iterator_arg *arg)
+ {
+ mutex_enter(&element->mutex);
+ if (element->trx)
+ validate_element(element->trx);
+ mutex_exit(&element->mutex);
+ return arg->action(element, arg->argument);
+ }
+#endif
+
+
+public:
+ void init()
+ {
+ lf_hash_init(&hash, sizeof(rw_trx_hash_element_t), LF_HASH_UNIQUE, 0,
+ sizeof(trx_id_t), 0, &my_charset_bin);
+ hash.alloc.constructor= rw_trx_hash_constructor;
+ hash.alloc.destructor= rw_trx_hash_destructor;
+ hash.initializer=
+ reinterpret_cast<lf_hash_initializer>(rw_trx_hash_initializer);
+ }
+
+
+ void destroy()
+ {
+ hash.alloc.destructor= rw_trx_hash_shutdown_destructor;
+ lf_hash_destroy(&hash);
+ }
+
+
+ /**
+ Releases LF_HASH pins.
+
+ Must be called by thread that owns trx_t object when the latter is being
+ "detached" from thread (e.g. released to the pool by trx_free()). Can be
+ called earlier if thread is expected not to use rw_trx_hash.
+
+ Since pins are not allowed to be transferred to another thread,
+ initialisation thread calls this for recovered transactions.
+ */
+
+ void put_pins(trx_t *trx)
+ {
+ if (trx->rw_trx_hash_pins)
+ {
+ lf_hash_put_pins(trx->rw_trx_hash_pins);
+ trx->rw_trx_hash_pins= 0;
+ }
+ }
+
+
+ /**
+ Finds trx object in lock-free hash with given id.
+
+ Only ACTIVE or PREPARED trx objects may participate in hash. Nevertheless
+ the transaction may get committed before this method returns.
+
+ With do_ref_count == false the caller may dereference returned trx pointer
+ only if lock_sys.mutex was acquired before calling find().
+
+ With do_ref_count == true caller may dereference trx even if it is not
+ holding lock_sys.mutex. Caller is responsible for calling
+ trx->release_reference() when it is done playing with trx.
+
+ Ideally this method should get caller rw_trx_hash_pins along with trx
+ object as a parameter, similar to insert() and erase(). However most
+ callers lose trx early in their call chains and it is not that easy to pass
+ them through.
+
+ So we take more expensive approach: get trx through current_thd()->ha_data.
+ Some threads don't have trx attached to THD, and at least server
+ initialisation thread, fts_optimize_thread, srv_master_thread,
+ dict_stats_thread, srv_monitor_thread, btr_defragment_thread don't even
+ have THD at all. For such cases we allocate pins only for duration of
+ search and free them immediately.
+
+ This has negative performance impact and should be fixed eventually (by
+ passing caller_trx as a parameter). Still stream of DML is more or less Ok.
+
+ @return
+ @retval 0 not found
+ @retval pointer to trx
+ */
+
+ trx_t *find(trx_t *caller_trx, trx_id_t trx_id, bool do_ref_count= false)
+ {
+ /*
+ In MariaDB 10.3, purge will reset DB_TRX_ID to 0
+ when the history is lost. Read/write transactions will
+ always have a nonzero trx_t::id; there the value 0 is
+ reserved for transactions that did not write or lock
+ anything yet.
+ */
+ if (!trx_id)
+ return NULL;
+
+ trx_t *trx= 0;
+ LF_PINS *pins= caller_trx ? get_pins(caller_trx) : lf_hash_get_pins(&hash);
+ ut_a(pins);
+
+ rw_trx_hash_element_t *element= reinterpret_cast<rw_trx_hash_element_t*>
+ (lf_hash_search(&hash, pins, reinterpret_cast<const void*>(&trx_id),
+ sizeof(trx_id_t)));
+ if (element)
+ {
+ mutex_enter(&element->mutex);
+ lf_hash_search_unpin(pins);
+ if ((trx= element->trx))
+ {
+ if (do_ref_count)
+ trx->reference();
+ ut_d(validate_element(trx));
+ }
+ mutex_exit(&element->mutex);
+ }
+ if (!caller_trx)
+ lf_hash_put_pins(pins);
+ return trx;
+ }
+
+
+ /**
+ Inserts trx to lock-free hash.
+
+ Object becomes accessible via rw_trx_hash.
+ */
+
+ void insert(trx_t *trx)
+ {
+ ut_d(validate_element(trx));
+ int res= lf_hash_insert(&hash, get_pins(trx),
+ reinterpret_cast<void*>(trx));
+ ut_a(res == 0);
+ }
+
+
+ /**
+ Removes trx from lock-free hash.
+
+ Object becomes not accessible via rw_trx_hash. But it still can be pinned
+ by concurrent find(), which is supposed to release it immediately after
+ it sees object trx is 0.
+ */
+
+ void erase(trx_t *trx)
+ {
+ ut_d(validate_element(trx));
+ mutex_enter(&trx->rw_trx_hash_element->mutex);
+ trx->rw_trx_hash_element->trx= 0;
+ mutex_exit(&trx->rw_trx_hash_element->mutex);
+ int res= lf_hash_delete(&hash, get_pins(trx),
+ reinterpret_cast<const void*>(&trx->id),
+ sizeof(trx_id_t));
+ ut_a(res == 0);
+ }
+
+
+ /**
+ Returns the number of elements in the hash.
+
+ The number is exact only if hash is protected against concurrent
+ modifications (e.g. single threaded startup or hash is protected
+ by some mutex). Otherwise the number may be used as a hint only,
+ because it may change even before this method returns.
+ */
+
+ int32_t size()
+ {
+ return my_atomic_load32_explicit(&hash.count, MY_MEMORY_ORDER_RELAXED);
+ }
+
+
+ /**
+ Iterates the hash.
+
+ @param caller_trx used to get/set pins
+ @param action called for every element in hash
+ @param argument opque argument passed to action
+
+ May return the same element multiple times if hash is under contention.
+ If caller doesn't like to see the same transaction multiple times, it has
+ to call iterate_no_dups() instead.
+
+ May return element with committed transaction. If caller doesn't like to
+ see committed transactions, it has to skip those under element mutex:
+
+ mutex_enter(&element->mutex);
+ if (trx_t trx= element->trx)
+ {
+ // trx is protected against commit in this branch
+ }
+ mutex_exit(&element->mutex);
+
+ May miss concurrently inserted transactions.
+
+ @return
+ @retval 0 iteration completed successfully
+ @retval 1 iteration was interrupted (action returned 1)
+ */
+
+ int iterate(trx_t *caller_trx, my_hash_walk_action action, void *argument)
+ {
+ LF_PINS *pins= caller_trx ? get_pins(caller_trx) : lf_hash_get_pins(&hash);
+ ut_a(pins);
+#ifdef UNIV_DEBUG
+ debug_iterator_arg debug_arg= { action, argument };
+ action= reinterpret_cast<my_hash_walk_action>(debug_iterator);
+ argument= &debug_arg;
+#endif
+ int res= lf_hash_iterate(&hash, pins, action, argument);
+ if (!caller_trx)
+ lf_hash_put_pins(pins);
+ return res;
+ }
+
+
+ int iterate(my_hash_walk_action action, void *argument)
+ {
+ return iterate(current_trx(), action, argument);
+ }
+
+
+ /**
+ Iterates the hash and eliminates duplicate elements.
+
+ @sa iterate()
+ */
+
+ int iterate_no_dups(trx_t *caller_trx, my_hash_walk_action action,
+ void *argument)
+ {
+ eliminate_duplicates_arg arg(size() + 32, action, argument);
+ return iterate(caller_trx, reinterpret_cast<my_hash_walk_action>
+ (eliminate_duplicates), &arg);
+ }
+
+
+ int iterate_no_dups(my_hash_walk_action action, void *argument)
+ {
+ return iterate_no_dups(current_trx(), action, argument);
+ }
+};
+
+
/** The transaction system central memory data structure. */
-struct trx_sys_t {
+class trx_sys_t
+{
+ /**
+ The smallest number not yet assigned as a transaction id or transaction
+ number. Accessed and updated with atomic operations.
+ */
+ MY_ALIGNED(CACHE_LINE_SIZE) trx_id_t m_max_trx_id;
+
+
+ /**
+ Solves race conditions between register_rw() and snapshot_ids() as well as
+ race condition between assign_new_trx_no() and snapshot_ids().
+
+ @sa register_rw()
+ @sa assign_new_trx_no()
+ @sa snapshot_ids()
+ */
+ MY_ALIGNED(CACHE_LINE_SIZE) trx_id_t m_rw_trx_hash_version;
+
+
+ /**
+ TRX_RSEG_HISTORY list length (number of committed transactions to purge)
+ */
+ MY_ALIGNED(CACHE_LINE_SIZE) int32 rseg_history_len;
+
+ /** Active views. */
+ MY_ALIGNED(CACHE_LINE_SIZE) UT_LIST_BASE_NODE_T(ReadView) m_views;
+ bool m_initialised;
+
+public:
+ MY_ALIGNED(CACHE_LINE_SIZE) mutable
TrxSysMutex mutex; /*!< mutex protecting most fields in
this structure except when noted
otherwise */
-
- MVCC* mvcc; /*!< Multi version concurrency control
- manager */
- volatile trx_id_t
- max_trx_id; /*!< The smallest number not yet
- assigned as a transaction id or
- transaction number. This is declared
- volatile because it can be accessed
- without holding any mutex during
- AC-NL-RO view creation. */
- trx_ut_list_t serialisation_list;
- /*!< Ordered on trx_t::no of all the
- currenrtly active RW transactions */
-#ifdef UNIV_DEBUG
- trx_id_t rw_max_trx_id; /*!< Max trx id of read-write
- transactions which exist or existed */
-#endif /* UNIV_DEBUG */
-
- /** Avoid false sharing */
- const char pad1[CACHE_LINE_SIZE];
- trx_ut_list_t rw_trx_list; /*!< List of active and committed in
- memory read-write transactions, sorted
- on trx id, biggest first. Recovered
- transactions are always on this list. */
-
- /** Avoid false sharing */
- const char pad2[CACHE_LINE_SIZE];
+ MY_ALIGNED(CACHE_LINE_SIZE)
trx_ut_list_t mysql_trx_list; /*!< List of transactions created
for MySQL. All user transactions are
- on mysql_trx_list. The rw_trx_list
+ on mysql_trx_list. The rw_trx_hash
can contain system transactions and
recovered transactions that will not
be in the mysql_trx_list.
@@ -540,22 +823,11 @@ struct trx_sys_t {
transactions that have not yet been
started in InnoDB. */
- trx_ids_t rw_trx_ids; /*!< Array of Read write transaction IDs
- for MVCC snapshot. A ReadView would take
- a snapshot of these transactions whose
- changes are not visible to it. We should
- remove transactions from the list before
- committing in memory and releasing locks
- to ensure right order of removal and
- consistent snapshot. */
-
- /** Avoid false sharing */
- const char pad3[CACHE_LINE_SIZE];
+ MY_ALIGNED(CACHE_LINE_SIZE)
/** Temporary rollback segments */
trx_rseg_t* temp_rsegs[TRX_SYS_N_RSEGS];
- /** Avoid false sharing */
- const char pad4[CACHE_LINE_SIZE];
+ MY_ALIGNED(CACHE_LINE_SIZE)
trx_rseg_t* rseg_array[TRX_SYS_N_RSEGS];
/*!< Pointer array to rollback
segments; NULL if slot not in use;
@@ -563,46 +835,378 @@ struct trx_sys_t {
single-threaded mode; not protected
by any mutex, because it is read-only
during multi-threaded operation */
- ulint rseg_history_len;
- /*!< Length of the TRX_RSEG_HISTORY
- list (update undo logs for committed
- transactions), protected by
- rseg->mutex */
-
- TrxIdSet rw_trx_set; /*!< Mapping from transaction id
- to transaction instance */
-
- ulint n_prepared_trx; /*!< Number of transactions currently
- in the XA PREPARED state */
-
- ulint n_prepared_recovered_trx; /*!< Number of transactions
- currently in XA PREPARED state that are
- also recovered. Such transactions cannot
- be added during runtime. They can only
- occur after recovery if mysqld crashed
- while there were XA PREPARED
- transactions. We disable query cache
- if such transactions exist. */
-};
-/** When a trx id which is zero modulo this number (which must be a power of
-two) is assigned, the field TRX_SYS_TRX_ID_STORE on the transaction system
-page is updated */
-#define TRX_SYS_TRX_ID_WRITE_MARGIN ((trx_id_t) 256)
+ /**
+ Lock-free hash of in memory read-write transactions.
+ Works faster when it is on it's own cache line (tested).
+ */
+
+ MY_ALIGNED(CACHE_LINE_SIZE) rw_trx_hash_t rw_trx_hash;
+
+
+#ifdef WITH_WSREP
+ /** Latest recovered XID during startup */
+ XID recovered_wsrep_xid;
+#endif
+ /** Latest recovered binlog offset */
+ int64_t recovered_binlog_offset;
+ /** Latest recovred binlog file name */
+ char recovered_binlog_filename[TRX_SYS_MYSQL_LOG_NAME_LEN];
+
+
+ /**
+ Constructor.
+
+ Some members may require late initialisation, thus we just mark object as
+ uninitialised. Real initialisation happens in create().
+ */
+
+ trx_sys_t(): m_initialised(false) {}
+
+
+ /**
+ Returns the minimum trx id in rw trx list.
+
+ This is the smallest id for which the trx can possibly be active. (But, you
+ must look at the trx->state to find out if the minimum trx id transaction
+ itself is active, or already committed.)
+
+ @return the minimum trx id, or m_max_trx_id if the trx list is empty
+ */
+
+ trx_id_t get_min_trx_id()
+ {
+ trx_id_t id= get_max_trx_id();
+ rw_trx_hash.iterate(reinterpret_cast<my_hash_walk_action>
+ (get_min_trx_id_callback), &id);
+ return id;
+ }
+
+
+ /**
+ Determines the maximum transaction id.
+
+ @return maximum currently allocated trx id; will be stale after the
+ next call to trx_sys.get_new_trx_id()
+ */
+
+ trx_id_t get_max_trx_id()
+ {
+ return static_cast<trx_id_t>
+ (my_atomic_load64_explicit(reinterpret_cast<int64*>(&m_max_trx_id),
+ MY_MEMORY_ORDER_RELAXED));
+ }
+
+
+ /**
+ Allocates a new transaction id.
+ @return new, allocated trx id
+ */
+
+ trx_id_t get_new_trx_id()
+ {
+ trx_id_t id= get_new_trx_id_no_refresh();
+ refresh_rw_trx_hash_version();
+ return id;
+ }
-/** Test if trx_sys->mutex is owned. */
-#define trx_sys_mutex_own() (trx_sys->mutex.is_owned())
-/** Acquire the trx_sys->mutex. */
-#define trx_sys_mutex_enter() do { \
- mutex_enter(&trx_sys->mutex); \
-} while (0)
+ /**
+ Allocates and assigns new transaction serialisation number.
-/** Release the trx_sys->mutex. */
-#define trx_sys_mutex_exit() do { \
- trx_sys->mutex.exit(); \
-} while (0)
+ There's a gap between m_max_trx_id increment and transaction serialisation
+ number becoming visible through rw_trx_hash. While we're in this gap
+ concurrent thread may come and do MVCC snapshot without seeing allocated
+ but not yet assigned serialisation number. Then at some point purge thread
+ may clone this view. As a result it won't see newly allocated serialisation
+ number and may remove "unnecessary" history data of this transaction from
+ rollback segments.
-#include "trx0sys.ic"
+ m_rw_trx_hash_version is intended to solve this problem. MVCC snapshot has
+ to wait until m_max_trx_id == m_rw_trx_hash_version, which effectively
+ means that all transaction serialisation numbers up to m_max_trx_id are
+ available through rw_trx_hash.
+
+ We rely on refresh_rw_trx_hash_version() to issue RELEASE memory barrier so
+ that m_rw_trx_hash_version increment happens after
+ trx->rw_trx_hash_element->no becomes visible through rw_trx_hash.
+
+ @param trx transaction
+ */
+ void assign_new_trx_no(trx_t *trx)
+ {
+ trx->no= get_new_trx_id_no_refresh();
+ my_atomic_store64_explicit(reinterpret_cast<int64*>
+ (&trx->rw_trx_hash_element->no),
+ trx->no, MY_MEMORY_ORDER_RELAXED);
+ refresh_rw_trx_hash_version();
+ }
+
+
+ /**
+ Takes MVCC snapshot.
+
+ To reduce malloc probablility we reserver rw_trx_hash.size() + 32 elements
+ in ids.
+
+ For details about get_rw_trx_hash_version() != get_max_trx_id() spin
+ @sa register_rw() and @sa assign_new_trx_no().
+
+ We rely on get_rw_trx_hash_version() to issue ACQUIRE memory barrier so
+ that loading of m_rw_trx_hash_version happens before accessing rw_trx_hash.
+
+ To optimise snapshot creation rw_trx_hash.iterate() is being used instead
+ of rw_trx_hash.iterate_no_dups(). It means that some transaction
+ identifiers may appear multiple times in ids.
+
+ @param[in,out] caller_trx used to get access to rw_trx_hash_pins
+ @param[out] ids array to store registered transaction identifiers
+ @param[out] max_trx_id variable to store m_max_trx_id value
+ @param[out] mix_trx_no variable to store min(trx->no) value
+ */
+
+ void snapshot_ids(trx_t *caller_trx, trx_ids_t *ids, trx_id_t *max_trx_id,
+ trx_id_t *min_trx_no)
+ {
+ ut_ad(!mutex_own(&mutex));
+ snapshot_ids_arg arg(ids);
+
+ while ((arg.m_id= get_rw_trx_hash_version()) != get_max_trx_id())
+ ut_delay(1);
+ arg.m_no= arg.m_id;
+
+ ids->clear();
+ ids->reserve(rw_trx_hash.size() + 32);
+ rw_trx_hash.iterate(caller_trx,
+ reinterpret_cast<my_hash_walk_action>(copy_one_id),
+ &arg);
+
+ *max_trx_id= arg.m_id;
+ *min_trx_no= arg.m_no;
+ }
+
+
+ /** Initialiser for m_max_trx_id and m_rw_trx_hash_version. */
+ void init_max_trx_id(trx_id_t value)
+ {
+ m_max_trx_id= m_rw_trx_hash_version= value;
+ }
+
+
+ bool is_initialised() { return m_initialised; }
+
+
+ /** Initialise the purge subsystem. */
+ void create();
+
+ /** Close the purge subsystem on shutdown. */
+ void close();
+
+ /** @return total number of active (non-prepared) transactions */
+ ulint any_active_transactions();
+
+
+ /**
+ Registers read-write transaction.
+
+ Transaction becomes visible to MVCC.
+
+ There's a gap between m_max_trx_id increment and transaction becoming
+ visible through rw_trx_hash. While we're in this gap concurrent thread may
+ come and do MVCC snapshot. As a result concurrent read view will be able to
+ observe records owned by this transaction even before it was committed.
+
+ m_rw_trx_hash_version is intended to solve this problem. MVCC snapshot has
+ to wait until m_max_trx_id == m_rw_trx_hash_version, which effectively
+ means that all transactions up to m_max_trx_id are available through
+ rw_trx_hash.
+
+ We rely on refresh_rw_trx_hash_version() to issue RELEASE memory barrier so
+ that m_rw_trx_hash_version increment happens after transaction becomes
+ visible through rw_trx_hash.
+ */
+
+ void register_rw(trx_t *trx)
+ {
+ trx->id= get_new_trx_id_no_refresh();
+ rw_trx_hash.insert(trx);
+ refresh_rw_trx_hash_version();
+ }
+
+
+ /**
+ Deregisters read-write transaction.
+
+ Transaction is removed from rw_trx_hash, which releases all implicit locks.
+ MVCC snapshot won't see this transaction anymore.
+ */
+
+ void deregister_rw(trx_t *trx)
+ {
+ rw_trx_hash.erase(trx);
+ }
+
+
+ bool is_registered(trx_t *caller_trx, trx_id_t id)
+ {
+ return rw_trx_hash.find(caller_trx, id);
+ }
+
+
+ trx_t *find(trx_t *caller_trx, trx_id_t id)
+ {
+ return rw_trx_hash.find(caller_trx, id, true);
+ }
+
+
+ /**
+ Registers view in MVCC.
+
+ @param view view owned by the caller
+ */
+ void register_view(ReadView *view)
+ {
+ mutex_enter(&mutex);
+ UT_LIST_ADD_FIRST(m_views, view);
+ mutex_exit(&mutex);
+ }
+
+
+ /**
+ Deregisters view in MVCC.
+
+ @param view view owned by the caller
+ */
+ void deregister_view(ReadView *view)
+ {
+ mutex_enter(&mutex);
+ UT_LIST_REMOVE(m_views, view);
+ mutex_exit(&mutex);
+ }
+
+
+ /**
+ Clones the oldest view and stores it in view.
+
+ No need to call ReadView::close(). The caller owns the view that is passed
+ in. This function is called by purge thread to determine whether it should
+ purge the delete marked record or not.
+ */
+ void clone_oldest_view();
+
+
+ /** @return the number of active views */
+ size_t view_count() const
+ {
+ size_t count= 0;
+
+ mutex_enter(&mutex);
+ for (const ReadView* view= UT_LIST_GET_FIRST(m_views); view;
+ view= UT_LIST_GET_NEXT(m_view_list, view))
+ {
+ if (view->get_state() == READ_VIEW_STATE_OPEN)
+ ++count;
+ }
+ mutex_exit(&mutex);
+ return count;
+ }
+
+ /** @return number of committed transactions waiting for purge */
+ ulint history_size() const
+ {
+ return uint32(my_atomic_load32(&const_cast<trx_sys_t*>(this)
+ ->rseg_history_len));
+ }
+ /** Add to the TRX_RSEG_HISTORY length (on database startup). */
+ void history_add(int32 len)
+ {
+ my_atomic_add32(&rseg_history_len, len);
+ }
+ /** Register a committed transaction. */
+ void history_insert() { history_add(1); }
+ /** Note that a committed transaction was purged. */
+ void history_remove() { history_add(-1); }
+
+private:
+ static my_bool get_min_trx_id_callback(rw_trx_hash_element_t *element,
+ trx_id_t *id)
+ {
+ if (element->id < *id)
+ {
+ mutex_enter(&element->mutex);
+ /* We don't care about read-only transactions here. */
+ if (element->trx && element->trx->rsegs.m_redo.rseg)
+ *id= element->id;
+ mutex_exit(&element->mutex);
+ }
+ return 0;
+ }
+
+
+ struct snapshot_ids_arg
+ {
+ snapshot_ids_arg(trx_ids_t *ids): m_ids(ids) {}
+ trx_ids_t *m_ids;
+ trx_id_t m_id;
+ trx_id_t m_no;
+ };
+
+
+ static my_bool copy_one_id(rw_trx_hash_element_t *element,
+ snapshot_ids_arg *arg)
+ {
+ if (element->id < arg->m_id)
+ {
+ trx_id_t no= static_cast<trx_id_t>(my_atomic_load64_explicit(
+ reinterpret_cast<int64*>(&element->no), MY_MEMORY_ORDER_RELAXED));
+ arg->m_ids->push_back(element->id);
+ if (no < arg->m_no)
+ arg->m_no= no;
+ }
+ return 0;
+ }
+
+
+ /** Getter for m_rw_trx_hash_version, must issue ACQUIRE memory barrier. */
+ trx_id_t get_rw_trx_hash_version()
+ {
+ return static_cast<trx_id_t>
+ (my_atomic_load64_explicit(reinterpret_cast<int64*>
+ (&m_rw_trx_hash_version),
+ MY_MEMORY_ORDER_ACQUIRE));
+ }
+
+
+ /** Increments m_rw_trx_hash_version, must issue RELEASE memory barrier. */
+ void refresh_rw_trx_hash_version()
+ {
+ my_atomic_add64_explicit(reinterpret_cast<int64*>(&m_rw_trx_hash_version),
+ 1, MY_MEMORY_ORDER_RELEASE);
+ }
+
+
+ /**
+ Allocates new transaction id without refreshing rw_trx_hash version.
+
+ This method is extracted for exclusive use by register_rw() and
+ assign_new_trx_no() where new id must be allocated atomically with
+ payload of these methods from MVCC snapshot point of view.
+
+ @sa get_new_trx_id()
+ @sa assign_new_trx_no()
+
+ @return new transaction id
+ */
+
+ trx_id_t get_new_trx_id_no_refresh()
+ {
+ return static_cast<trx_id_t>(my_atomic_add64_explicit(
+ reinterpret_cast<int64*>(&m_max_trx_id), 1, MY_MEMORY_ORDER_RELAXED));
+ }
+};
+
+
+/** The transaction system */
+extern trx_sys_t trx_sys;
#endif
diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic
deleted file mode 100644
index e8efc1525c4..00000000000
--- a/storage/innobase/include/trx0sys.ic
+++ /dev/null
@@ -1,448 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-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, Suite 500, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/trx0sys.ic
-Transaction system
-
-Created 3/26/1996 Heikki Tuuri
-*******************************************************/
-
-#include "trx0trx.h"
-#include "data0type.h"
-#include "srv0srv.h"
-#include "mtr0log.h"
-
-/* The typedef for rseg slot in the file copy */
-typedef byte trx_sysf_rseg_t;
-
-/* Rollback segment specification slot offsets */
-/*-------------------------------------------------------------*/
-#define TRX_SYS_RSEG_SPACE 0 /* space where the segment
- header is placed; starting with
- MySQL/InnoDB 5.1.7, this is
- UNIV_UNDEFINED if the slot is unused */
-#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the segment
- header is placed; this is FIL_NULL
- if the slot is unused */
-/*-------------------------------------------------------------*/
-/* Size of a rollback segment specification slot */
-#define TRX_SYS_RSEG_SLOT_SIZE 8
-
-/*****************************************************************//**
-Writes the value of max_trx_id to the file based trx system header. */
-void
-trx_sys_flush_max_trx_id(void);
-/*==========================*/
-
-/** Checks if a page address is the trx sys header page.
-@param[in] page_id page id
-@return true if trx sys header page */
-UNIV_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);
-}
-
-/**********************************************************************//**
-Gets a pointer to the transaction system header and x-latches its page.
-@return pointer to system header, page x-latched. */
-UNIV_INLINE
-trx_sysf_t*
-trx_sysf_get(
-/*=========*/
- mtr_t* mtr) /*!< in: mtr */
-{
- buf_block_t* block = NULL;
- trx_sysf_t* header = NULL;
-
- ut_ad(mtr);
-
- block = buf_page_get(page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO),
- univ_page_size, RW_X_LATCH, mtr);
-
- if (block) {
- buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
-
- header = TRX_SYS + buf_block_get_frame(block);
- }
-
- return(header);
-}
-
-/*****************************************************************//**
-Gets the space of the nth rollback segment slot in the trx system
-file copy.
-@return space id */
-UNIV_INLINE
-ulint
-trx_sysf_rseg_get_space(
-/*====================*/
- trx_sysf_t* sys_header, /*!< in: trx sys header */
- ulint i, /*!< in: slot index == rseg id */
- mtr_t* mtr) /*!< in: mtr */
-{
- ut_ad(sys_header);
- ut_ad(i < TRX_SYS_N_RSEGS);
-
- return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
- + i * TRX_SYS_RSEG_SLOT_SIZE
- + TRX_SYS_RSEG_SPACE, MLOG_4BYTES, mtr));
-}
-
-/*****************************************************************//**
-Gets the page number of the nth rollback segment slot in the trx system
-header.
-@return page number, FIL_NULL if slot unused */
-UNIV_INLINE
-ulint
-trx_sysf_rseg_get_page_no(
-/*======================*/
- trx_sysf_t* sys_header, /*!< in: trx system header */
- ulint i, /*!< in: slot index == rseg id */
- mtr_t* mtr) /*!< in: mtr */
-{
- ut_ad(sys_header);
- ut_ad(i < TRX_SYS_N_RSEGS);
-
- return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
- + i * TRX_SYS_RSEG_SLOT_SIZE
- + TRX_SYS_RSEG_PAGE_NO, MLOG_4BYTES, mtr));
-}
-
-/*****************************************************************//**
-Sets the space id of the nth rollback segment slot in the trx system
-file copy. */
-UNIV_INLINE
-void
-trx_sysf_rseg_set_space(
-/*====================*/
- trx_sysf_t* sys_header, /*!< in: trx sys file copy */
- ulint i, /*!< in: slot index == rseg id */
- ulint space, /*!< in: space id */
- mtr_t* mtr) /*!< in: mtr */
-{
- ut_ad(sys_header);
- ut_ad(i < TRX_SYS_N_RSEGS);
-
- mlog_write_ulint(sys_header + TRX_SYS_RSEGS
- + i * TRX_SYS_RSEG_SLOT_SIZE
- + TRX_SYS_RSEG_SPACE,
- space,
- MLOG_4BYTES, mtr);
-}
-
-/*****************************************************************//**
-Sets the page number of the nth rollback segment slot in the trx system
-header. */
-UNIV_INLINE
-void
-trx_sysf_rseg_set_page_no(
-/*======================*/
- trx_sysf_t* sys_header, /*!< in: trx sys header */
- ulint i, /*!< in: slot index == rseg id */
- ulint page_no, /*!< in: page number, FIL_NULL if the
- slot is reset to unused */
- mtr_t* mtr) /*!< in: mtr */
-{
- ut_ad(sys_header);
- ut_ad(i < TRX_SYS_N_RSEGS);
-
- mlog_write_ulint(sys_header + TRX_SYS_RSEGS
- + i * TRX_SYS_RSEG_SLOT_SIZE
- + TRX_SYS_RSEG_PAGE_NO,
- page_no,
- MLOG_4BYTES, mtr);
-}
-
-/*****************************************************************//**
-Writes a trx id to an index page. In case that the id size changes in
-some future version, this function should be used instead of
-mach_write_... */
-UNIV_INLINE
-void
-trx_write_trx_id(
-/*=============*/
- byte* ptr, /*!< in: pointer to memory where written */
- trx_id_t id) /*!< in: id */
-{
-#if DATA_TRX_ID_LEN != 6
-# error "DATA_TRX_ID_LEN != 6"
-#endif
- ut_ad(id > 0);
- mach_write_to_6(ptr, id);
-}
-
-/****************************************************************//**
-Looks for the trx handle with the given id in rw_trx_list.
-The caller must be holding trx_sys->mutex.
-@return the trx handle or NULL if not found;
-the pointer must not be dereferenced unless lock_sys->mutex was
-acquired before calling this function and is still being held */
-UNIV_INLINE
-trx_t*
-trx_get_rw_trx_by_id(
-/*=================*/
- trx_id_t trx_id) /*!< in: trx id to search for */
-{
- ut_ad(trx_id > 0);
- ut_ad(trx_sys_mutex_own());
-
- if (trx_sys->rw_trx_set.empty()) {
- return(NULL);
- }
-
- TrxIdSet::iterator it;
-
- it = trx_sys->rw_trx_set.find(TrxTrack(trx_id));
-
- return(it == trx_sys->rw_trx_set.end() ? NULL : it->m_trx);
-}
-
-/****************************************************************//**
-Returns the minimum trx id in trx list. This is the smallest id for which
-the trx can possibly be active. (But, you must look at the trx->state
-to find out if the minimum trx id transaction itself is active, or already
-committed.). The caller must be holding the trx_sys_t::mutex in shared mode.
-@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
-UNIV_INLINE
-trx_id_t
-trx_rw_min_trx_id_low(void)
-/*=======================*/
-{
- trx_id_t id;
-
- ut_ad(trx_sys_mutex_own());
-
- const trx_t* trx = UT_LIST_GET_LAST(trx_sys->rw_trx_list);
-
- if (trx == NULL) {
- id = trx_sys->max_trx_id;
- } else {
- assert_trx_in_rw_list(trx);
- id = trx->id;
- }
-
- return(id);
-}
-
-#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
-/***********************************************************//**
-Assert that a transaction has been recovered.
-@return TRUE */
-UNIV_INLINE
-ibool
-trx_assert_recovered(
-/*=================*/
- trx_id_t trx_id) /*!< in: transaction identifier */
-{
- const trx_t* trx;
-
- trx_sys_mutex_enter();
-
- trx = trx_get_rw_trx_by_id(trx_id);
- ut_a(trx->is_recovered);
-
- trx_sys_mutex_exit();
-
- return(TRUE);
-}
-#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
-
-/****************************************************************//**
-Returns the minimum trx id in rw trx list. This is the smallest id for which
-the rw trx can possibly be active. (But, you must look at the trx->state
-to find out if the minimum trx id transaction itself is active, or already
-committed.)
-@return the minimum trx id, or trx_sys->max_trx_id if rw trx list is empty */
-UNIV_INLINE
-trx_id_t
-trx_rw_min_trx_id(void)
-/*===================*/
-{
- trx_sys_mutex_enter();
-
- trx_id_t id = trx_rw_min_trx_id_low();
-
- trx_sys_mutex_exit();
-
- return(id);
-}
-
-/****************************************************************//**
-Checks if a rw transaction with the given id is active. If the caller is
-not holding lock_sys->mutex, the transaction may already have been committed.
-@return transaction instance if active, or NULL */
-UNIV_INLINE
-trx_t*
-trx_rw_is_active_low(
-/*=================*/
- trx_id_t trx_id, /*!< in: trx id of the transaction */
- ibool* corrupt) /*!< in: NULL or pointer to a flag
- that will be set if corrupt */
-{
- trx_t* trx;
-
- ut_ad(trx_sys_mutex_own());
-
- if (trx_id < trx_rw_min_trx_id_low()) {
-
- trx = NULL;
- } else if (trx_id >= trx_sys->max_trx_id) {
-
- /* There must be corruption: we let the caller handle the
- diagnostic prints in this case. */
-
- trx = NULL;
- if (corrupt != NULL) {
- *corrupt = TRUE;
- }
- } else {
- trx = trx_get_rw_trx_by_id(trx_id);
-
- if (trx != NULL
- && trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) {
-
- trx = NULL;
- }
- }
-
- return(trx);
-}
-
-/****************************************************************//**
-Checks if a rw transaction with the given id is active. If the caller is
-not holding lock_sys->mutex, the transaction may already have been
-committed.
-@return transaction instance if active, or NULL; */
-UNIV_INLINE
-trx_t*
-trx_rw_is_active(
-/*=============*/
- trx_id_t trx_id, /*!< in: trx id of the transaction */
- ibool* corrupt, /*!< in: NULL or pointer to a flag
- that will be set if corrupt */
- bool do_ref_count) /*!< in: if true then increment the
- trx_t::n_ref_count */
-{
- trx_t* trx;
-
- trx_sys_mutex_enter();
-
- trx = trx_rw_is_active_low(trx_id, corrupt);
-
- if (trx != 0) {
- trx = trx_reference(trx, do_ref_count);
- }
-
- trx_sys_mutex_exit();
-
- return(trx);
-}
-
-/*****************************************************************//**
-Allocates a new transaction id.
-@return new, allocated trx id */
-UNIV_INLINE
-trx_id_t
-trx_sys_get_new_trx_id()
-/*====================*/
-{
-#ifndef WITH_WSREP
- /* wsrep_fake_trx_id violates this assert */
- ut_ad(trx_sys_mutex_own());
-#endif /* WITH_WSREP */
-
- /* VERY important: after the database is started, max_trx_id value is
- divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the following if
- will evaluate to TRUE when this function is first time called,
- and the value for trx id will be written to disk-based header!
- Thus trx id values will not overlap when the database is
- repeatedly started! */
-
- if (!(trx_sys->max_trx_id % TRX_SYS_TRX_ID_WRITE_MARGIN)) {
-
- trx_sys_flush_max_trx_id();
- }
-
- return(trx_sys->max_trx_id++);
-}
-
-/*****************************************************************//**
-Determines the maximum transaction id.
-@return maximum currently allocated trx id; will be stale after the
-next call to trx_sys_get_new_trx_id() */
-UNIV_INLINE
-trx_id_t
-trx_sys_get_max_trx_id(void)
-/*========================*/
-{
- ut_ad(!trx_sys_mutex_own());
-
-#if UNIV_WORD_SIZE < DATA_TRX_ID_LEN
- /* Avoid torn reads. */
-
- trx_sys_mutex_enter();
-
- trx_id_t max_trx_id = trx_sys->max_trx_id;
-
- trx_sys_mutex_exit();
-
- return(max_trx_id);
-#else
- /* Perform a dirty read. Callers should be prepared for stale
- values, and we know that the value fits in a machine word, so
- that it will be read and written atomically. */
- return(trx_sys->max_trx_id);
-#endif /* UNIV_WORD_SIZE < DATA_TRX_ID_LEN */
-}
-
-/*****************************************************************//**
-Get the number of transaction in the system, independent of their state.
-@return count of transactions in trx_sys_t::rw_trx_list */
-UNIV_INLINE
-ulint
-trx_sys_get_n_rw_trx(void)
-/*======================*/
-{
- ulint n_trx;
-
- trx_sys_mutex_enter();
-
- n_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list);
-
- trx_sys_mutex_exit();
-
- return(n_trx);
-}
-
-/**
-Add the transaction to the RW transaction set
-@param trx transaction instance to add */
-UNIV_INLINE
-void
-trx_sys_rw_trx_add(trx_t* trx)
-{
- ut_ad(trx->id != 0);
-
- trx_sys->rw_trx_set.insert(TrxTrack(trx->id, trx));
- ut_d(trx->in_rw_trx_list = true);
-}
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 133f23081a0..685208853ee 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -38,25 +38,21 @@ Created 3/26/1996 Heikki Tuuri
#include "lock0types.h"
#include "log0log.h"
-#include "usr0types.h"
#include "que0types.h"
#include "mem0mem.h"
#include "trx0xa.h"
#include "ut0vec.h"
#include "fts0fts.h"
#include "srv0srv.h"
+#include "read0types.h"
// Forward declaration
struct mtr_t;
// Forward declaration
-class ReadView;
-
-// Forward declaration
class FlushObserver;
-/** Dummy session used currently in MySQL interface */
-extern sess_t* trx_dummy_sess;
+struct rw_trx_hash_element_t;
/** Set flush observer for the transaction
@param[in/out] trx transaction struct
@@ -112,12 +108,9 @@ trx_free_resurrected(trx_t* trx);
void
trx_free_for_background(trx_t* trx);
-/********************************************************************//**
-At shutdown, frees a transaction object that is in the PREPARED state. */
+/** At shutdown, frees a transaction object. */
void
-trx_free_prepared(
-/*==============*/
- trx_t* trx); /*!< in, own: trx object */
+trx_free_at_shutdown(trx_t *trx);
/** Free a transaction object for MySQL.
@param[in,out] trx transaction */
@@ -244,14 +237,6 @@ trx_commit_low(
trx_t* trx, /*!< in/out: transaction */
mtr_t* mtr); /*!< in/out: mini-transaction (will be committed),
or NULL if trx made no modifications */
-/****************************************************************//**
-Cleans up a transaction at database startup. The cleanup is needed if
-the transaction already got to the middle of a commit when the database
-crashed, and we cannot roll it back. */
-void
-trx_cleanup_at_db_startup(
-/*======================*/
- trx_t* trx); /*!< in: transaction */
/**********************************************************************//**
Does the transaction commit for MySQL.
@return DB_SUCCESS or error number */
@@ -275,13 +260,13 @@ int
trx_recover_for_mysql(
/*==================*/
XID* xid_list, /*!< in/out: prepared transactions */
- ulint len); /*!< in: number of slots in xid_list */
+ uint len); /*!< in: number of slots in xid_list */
/*******************************************************************//**
This function is used to find one X/Open XA distributed transaction
which is in the prepared state
@return trx or NULL; on match, the trx->xid will be invalidated;
note that the trx may have been committed, unless the caller is
-holding lock_sys->mutex */
+holding lock_sys.mutex */
trx_t *
trx_get_trx_by_xid(
/*===============*/
@@ -299,31 +284,6 @@ void
trx_mark_sql_stat_end(
/*==================*/
trx_t* trx); /*!< in: trx handle */
-/********************************************************************//**
-Assigns a read view for a consistent read query. All the consistent reads
-within the same transaction will get the same read view, which is created
-when this function is first called for a new started transaction. */
-ReadView*
-trx_assign_read_view(
-/*=================*/
- trx_t* trx); /*!< in: active transaction */
-
-/****************************************************************//**
-@return the transaction's read view or NULL if one not assigned. */
-UNIV_INLINE
-ReadView*
-trx_get_read_view(
-/*==============*/
- trx_t* trx);
-
-/****************************************************************//**
-@return the transaction's read view or NULL if one not assigned. */
-UNIV_INLINE
-const ReadView*
-trx_get_read_view(
-/*==============*/
- const trx_t* trx);
-
/****************************************************************//**
Prepares a transaction for commit/rollback. */
void
@@ -347,7 +307,7 @@ trx_commit_step(
/**********************************************************************//**
Prints info about a transaction.
-Caller must hold trx_sys->mutex. */
+Caller must hold trx_sys.mutex. */
void
trx_print_low(
/*==========*/
@@ -367,7 +327,7 @@ trx_print_low(
/**********************************************************************//**
Prints info about a transaction.
-The caller must hold lock_sys->mutex and trx_sys->mutex.
+The caller must hold lock_sys.mutex and trx_sys.mutex.
When possible, use trx_print() instead. */
void
trx_print_latched(
@@ -377,25 +337,9 @@ trx_print_latched(
ulint max_query_len); /*!< in: max query length to print,
or 0 to use the default max length */
-#ifdef WITH_WSREP
-/**********************************************************************//**
-Prints info about a transaction.
-Transaction information may be retrieved without having trx_sys->mutex acquired
-so it may not be completely accurate. The caller must own lock_sys->mutex
-and the trx must have some locks to make sure that it does not escape
-without locking lock_sys->mutex. */
-UNIV_INTERN
-void
-wsrep_trx_print_locking(
- FILE* f, /*!< in: output stream */
- const trx_t* trx, /*!< in: transaction */
- ulint max_query_len) /*!< in: max query length to print,
- or 0 to use the default max length */
- MY_ATTRIBUTE((nonnull));
-#endif /* WITH_WSREP */
/**********************************************************************//**
Prints info about a transaction.
-Acquires and releases lock_sys->mutex and trx_sys->mutex. */
+Acquires and releases lock_sys.mutex. */
void
trx_print(
/*======*/
@@ -425,9 +369,9 @@ trx_set_dict_operation(
/**********************************************************************//**
Determines if a transaction is in the given state.
-The caller must hold trx_sys->mutex, or it must be the thread
+The caller must hold trx_sys.mutex, or it must be the thread
that is serving a running transaction.
-A running RW transaction must be in trx_sys->rw_trx_list.
+A running RW transaction must be in trx_sys.rw_trx_hash.
@return TRUE if trx->state == state */
UNIV_INLINE
bool
@@ -446,7 +390,7 @@ trx_state_eq(
# ifdef UNIV_DEBUG
/**********************************************************************//**
Asserts that a transaction has been started.
-The caller must hold trx_sys->mutex.
+The caller must hold trx_sys.mutex.
@return TRUE if started */
ibool
trx_assert_started(
@@ -531,31 +475,6 @@ trx_set_rw_mode(
trx_t* trx);
/**
-Increase the reference count. If the transaction is in state
-TRX_STATE_COMMITTED_IN_MEMORY then the transaction is considered
-committed and the reference count is not incremented.
-@param trx Transaction that is being referenced
-@param do_ref_count Increment the reference iff this is true
-@return transaction instance if it is not committed */
-UNIV_INLINE
-trx_t*
-trx_reference(
- trx_t* trx,
- bool do_ref_count);
-
-/**
-Release the transaction. Decrease the reference count.
-@param trx Transaction that is being released */
-UNIV_INLINE
-void
-trx_release_reference(
- trx_t* trx);
-
-/**
-Check if the transaction is being referenced. */
-#define trx_is_referenced(t) ((t)->n_ref > 0)
-
-/**
@param[in] requestor Transaction requesting the lock
@param[in] holder Transaction holding the lock
@return the transaction that will be rolled back, null don't care */
@@ -607,15 +526,6 @@ with an explicit check for the read-only status.
((t)->read_only && trx_is_autocommit_non_locking((t)))
/**
-Assert that the transaction is in the trx_sys_t::rw_trx_list */
-#define assert_trx_in_rw_list(t) do { \
- ut_ad(!(t)->read_only); \
- ut_ad((t)->in_rw_trx_list \
- == !((t)->read_only || !(t)->rsegs.m_redo.rseg)); \
- check_trx_state(t); \
-} while (0)
-
-/**
Check transaction state */
#define check_trx_state(t) do { \
ut_ad(!trx_is_autocommit_non_locking((t))); \
@@ -638,7 +548,7 @@ Check transaction state */
ut_ad(trx_state_eq((t), TRX_STATE_NOT_STARTED) \
|| trx_state_eq((t), TRX_STATE_FORCED_ROLLBACK)); \
ut_ad(!trx->has_logged()); \
- ut_ad(!MVCC::is_view_active((t)->read_view)); \
+ ut_ad(!(t)->read_view.is_open()); \
ut_ad((t)->lock.wait_thr == NULL); \
ut_ad(UT_LIST_GET_LEN((t)->lock.trx_locks) == 0); \
ut_ad((t)->dict_operation == TRX_DICT_OP_NONE); \
@@ -655,7 +565,7 @@ transaction pool.
#ifdef UNIV_DEBUG
/*******************************************************************//**
Assert that an autocommit non-locking select cannot be in the
-rw_trx_list and that it is a read-only transaction.
+rw_trx_hash and that it is a read-only transaction.
The tranasction must be in the mysql_trx_list. */
# define assert_trx_nonlocking_or_in_list(t) \
do { \
@@ -663,7 +573,6 @@ The tranasction must be in the mysql_trx_list. */
trx_state_t t_state = (t)->state; \
ut_ad((t)->read_only); \
ut_ad(!(t)->is_recovered); \
- ut_ad(!(t)->in_rw_trx_list); \
ut_ad((t)->in_mysql_trx_list); \
ut_ad(t_state == TRX_STATE_NOT_STARTED \
|| t_state == TRX_STATE_FORCED_ROLLBACK \
@@ -675,7 +584,7 @@ The tranasction must be in the mysql_trx_list. */
#else /* UNIV_DEBUG */
/*******************************************************************//**
Assert that an autocommit non-locking slect cannot be in the
-rw_trx_list and that it is a read-only transaction.
+rw_trx_hash and that it is a read-only transaction.
The tranasction must be in the mysql_trx_list. */
# define assert_trx_nonlocking_or_in_list(trx) ((void)0)
#endif /* UNIV_DEBUG */
@@ -703,7 +612,7 @@ To query the state either of the mutexes is sufficient within the locking
code and no mutex is required when the query thread is no longer waiting. */
/** The locks and state of an active transaction. Protected by
-lock_sys->mutex, trx->mutex or both. */
+lock_sys.mutex, trx->mutex or both. */
struct trx_lock_t {
ulint n_active_thrs; /*!< number of active query threads */
@@ -715,10 +624,10 @@ struct trx_lock_t {
TRX_QUE_LOCK_WAIT, this points to
the lock request, otherwise this is
NULL; set to non-NULL when holding
- both trx->mutex and lock_sys->mutex;
+ both trx->mutex and lock_sys.mutex;
set to NULL when holding
- lock_sys->mutex; readers should
- hold lock_sys->mutex, except when
+ lock_sys.mutex; readers should
+ hold lock_sys.mutex, except when
they are holding trx->mutex and
wait_lock==NULL */
ib_uint64_t deadlock_mark; /*!< A mark field that is initialized
@@ -732,13 +641,13 @@ struct trx_lock_t {
resolution, it sets this to true.
Protected by trx->mutex. */
time_t wait_started; /*!< lock wait started at this time,
- protected only by lock_sys->mutex */
+ protected only by lock_sys.mutex */
que_thr_t* wait_thr; /*!< query thread belonging to this
trx that is in QUE_THR_LOCK_WAIT
state. For threads suspended in a
lock wait, this is protected by
- lock_sys->mutex. Otherwise, this may
+ lock_sys.mutex. Otherwise, this may
only be modified by the thread that is
serving the running transaction. */
@@ -751,12 +660,12 @@ struct trx_lock_t {
ulint table_cached; /*!< Next free table lock in pool */
mem_heap_t* lock_heap; /*!< memory heap for trx_locks;
- protected by lock_sys->mutex */
+ protected by lock_sys.mutex */
trx_lock_list_t trx_locks; /*!< locks requested by the transaction;
insertions are protected by trx->mutex
- and lock_sys->mutex; removals are
- protected by lock_sys->mutex */
+ and lock_sys.mutex; removals are
+ protected by lock_sys.mutex */
lock_pool_t table_locks; /*!< All table locks requested by this
transaction, including AUTOINC locks */
@@ -779,14 +688,73 @@ struct trx_lock_t {
bool start_stmt;
};
-/** Type used to store the list of tables that are modified by a given
-transaction. We store pointers to the table objects in memory because
+/** Logical first modification time of a table in a transaction */
+class trx_mod_table_time_t
+{
+ /** First modification of the table */
+ undo_no_t first;
+ /** First modification of a system versioned column */
+ undo_no_t first_versioned;
+
+ /** Magic value signifying that a system versioned column of a
+ table was never modified in a transaction. */
+ static const undo_no_t UNVERSIONED = IB_ID_MAX;
+
+public:
+ /** Constructor
+ @param[in] rows number of modified rows so far */
+ trx_mod_table_time_t(undo_no_t rows)
+ : first(rows), first_versioned(UNVERSIONED) {}
+
+#ifdef UNIV_DEBUG
+ /** Validation
+ @param[in] rows number of modified rows so far
+ @return whether the object is valid */
+ bool valid(undo_no_t rows = UNVERSIONED) const
+ {
+ return first <= first_versioned && first <= rows;
+ }
+#endif /* UNIV_DEBUG */
+ /** @return if versioned columns were modified */
+ bool is_versioned() const { return first_versioned != UNVERSIONED; }
+
+ /** After writing an undo log record, set is_versioned() if needed
+ @param[in] rows number of modified rows so far */
+ void set_versioned(undo_no_t rows)
+ {
+ ut_ad(!is_versioned());
+ first_versioned = rows;
+ ut_ad(valid());
+ }
+
+ /** Invoked after partial rollback
+ @param[in] limit number of surviving modified rows
+ @return whether this should be erased from trx_t::mod_tables */
+ bool rollback(undo_no_t limit)
+ {
+ ut_ad(valid());
+ if (first >= limit) {
+ return true;
+ }
+
+ if (first_versioned < limit && is_versioned()) {
+ first_versioned = UNVERSIONED;
+ }
+
+ return false;
+ }
+};
+
+/** Collection of persistent tables and their first modification
+in a transaction.
+We store pointers to the table objects in memory because
we know that a table object will not be destroyed while a transaction
that modified it is running. */
-typedef std::set<
- dict_table_t*,
+typedef std::map<
+ dict_table_t*, trx_mod_table_time_t,
std::less<dict_table_t*>,
- ut_allocator<dict_table_t*> > trx_mod_tables_t;
+ ut_allocator<std::pair<dict_table_t* const, trx_mod_table_time_t> > >
+ trx_mod_tables_t;
/** The transaction handle
@@ -816,27 +784,26 @@ so without holding any mutex. The following are exceptions to this:
* trx_rollback_resurrected() may access resurrected (connectionless)
transactions while the system is already processing new user
-transactions. The trx_sys->mutex prevents a race condition between it
+transactions. The trx_sys.mutex prevents a race condition between it
and lock_trx_release_locks() [invoked by trx_commit()].
* trx_print_low() may access transactions not associated with the current
-thread. The caller must be holding trx_sys->mutex and lock_sys->mutex.
+thread. The caller must be holding lock_sys.mutex.
-* When a transaction handle is in the trx_sys->mysql_trx_list or
-trx_sys->trx_list, some of its fields must not be modified without
-holding trx_sys->mutex exclusively.
+* When a transaction handle is in the trx_sys.mysql_trx_list or
+trx_sys.trx_list, some of its fields must not be modified without
+holding trx_sys.mutex exclusively.
* The locking code (in particular, lock_deadlock_recursive() and
lock_rec_convert_impl_to_expl()) will access transactions associated
to other connections. The locks of transactions are protected by
-lock_sys->mutex and sometimes by trx->mutex. */
+lock_sys.mutex and sometimes by trx->mutex. */
typedef enum {
TRX_SERVER_ABORT = 0,
TRX_WSREP_ABORT = 1
} trx_abort_t;
-
/** Represents an instance of rollback segment along with its state variables.*/
struct trx_undo_ptr_t {
trx_rseg_t* rseg; /*!< rollback segment assigned to the
@@ -887,10 +854,23 @@ struct TrxVersion {
typedef std::list<TrxVersion, ut_allocator<TrxVersion> > hit_list_t;
struct trx_t {
+private:
+ /**
+ Count of references.
+
+ We can't release the locks nor commit the transaction until this reference
+ is 0. We can change the state to TRX_STATE_COMMITTED_IN_MEMORY to signify
+ that it is no longer "active".
+ */
+
+ int32_t n_ref;
+
+
+public:
TrxMutex mutex; /*!< Mutex protecting the fields
state and lock (except some fields
of lock, which are protected by
- lock_sys->mutex) */
+ lock_sys.mutex) */
/* Note: in_depth was split from in_innodb for fixing a RO
performance issue. Acquiring the trx_t::mutex for each row
@@ -918,7 +898,7 @@ struct trx_t {
transaction is moved to
COMMITTED_IN_MEMORY state.
Protected by trx_sys_t::mutex
- when trx->in_rw_trx_list. Initially
+ when trx is in rw_trx_hash. Initially
set to TRX_ID_MAX. */
/** State of the trx from the point of view of concurrency control
@@ -946,6 +926,9 @@ struct trx_t {
Recovered XA:
* NOT_STARTED -> PREPARED -> COMMITTED -> (freed)
+ Recovered XA followed by XA ROLLBACK:
+ * NOT_STARTED -> PREPARED -> ACTIVE -> COMMITTED -> (freed)
+
XA (2PC) (shutdown or disconnect before ROLLBACK or COMMIT):
* NOT_STARTED -> PREPARED -> (freed)
@@ -956,11 +939,11 @@ struct trx_t {
XA (2PC) transactions are always treated as non-autocommit.
- Transitions to ACTIVE or NOT_STARTED occur when
- !in_rw_trx_list (no trx_sys->mutex needed).
+ Transitions to ACTIVE or NOT_STARTED occur when transaction
+ is not in rw_trx_hash (no trx_sys.mutex needed).
Autocommit non-locking read-only transactions move between states
- without holding any mutex. They are !in_rw_trx_list.
+ without holding any mutex. They are not in rw_trx_hash.
All transactions, unless they are determined to be ac-nl-ro,
explicitly tagged as read-only or read-write, will first be put
@@ -970,15 +953,15 @@ struct trx_t {
list. During this switch we assign it a rollback segment.
When a transaction is NOT_STARTED, it can be in_mysql_trx_list if
- it is a user transaction. It cannot be in rw_trx_list.
+ it is a user transaction. It cannot be in rw_trx_hash.
- ACTIVE->PREPARED->COMMITTED is only possible when trx->in_rw_trx_list.
- The transition ACTIVE->PREPARED is protected by trx_sys->mutex.
+ ACTIVE->PREPARED->COMMITTED is only possible when trx is in rw_trx_hash.
+ The transition ACTIVE->PREPARED is protected by trx_sys.mutex.
ACTIVE->COMMITTED is possible when the transaction is in
- rw_trx_list.
+ rw_trx_hash.
- Transitions to COMMITTED are protected by both lock_sys->mutex
+ Transitions to COMMITTED are protected by both lock_sys.mutex
and trx->mutex.
NOTE: Some of these state change constraints are an overkill,
@@ -987,25 +970,16 @@ struct trx_t {
trx_state_t state;
- ReadView* read_view; /*!< consistent read view used in the
+ ReadView read_view; /*!< consistent read view used in the
transaction, or NULL if not yet set */
-
- UT_LIST_NODE_T(trx_t)
- trx_list; /*!< list of transactions;
- protected by trx_sys->mutex. */
- UT_LIST_NODE_T(trx_t)
- no_list; /*!< Required during view creation
- to check for the view limit for
- transactions that are committing */
-
trx_lock_t lock; /*!< Information about the transaction
locks and state. Protected by
- trx->mutex or lock_sys->mutex
+ trx->mutex or lock_sys.mutex
or both */
bool is_recovered; /*!< 0=normal transaction,
1=recovered, must be rolled back,
- protected by trx_sys->mutex when
- trx->in_rw_trx_list holds */
+ protected by trx_sys.mutex when
+ trx is in rw_trx_hash */
hit_list_t hit_list; /*!< List of transactions to kill,
when a high priority transaction
@@ -1114,20 +1088,13 @@ struct trx_t {
statement uses, except those
in consistent read */
/*------------------------------*/
-#ifdef UNIV_DEBUG
- /** The following two fields are mutually exclusive. */
- /* @{ */
-
- bool in_rw_trx_list; /*!< true if in trx_sys->rw_trx_list */
- /* @} */
-#endif /* UNIV_DEBUG */
UT_LIST_NODE_T(trx_t)
mysql_trx_list; /*!< list of transactions created for
- MySQL; protected by trx_sys->mutex */
+ MySQL; protected by trx_sys.mutex */
#ifdef UNIV_DEBUG
bool in_mysql_trx_list;
/*!< true if in
- trx_sys->mysql_trx_list */
+ trx_sys.mysql_trx_list */
#endif /* UNIV_DEBUG */
/*------------------------------*/
dberr_t error_state; /*!< 0 if no error, otherwise error
@@ -1141,7 +1108,6 @@ struct trx_t {
ulint error_key_num; /*!< if the index creation fails to a
duplicate key error, a mysql key
number of that index is stored here */
- sess_t* sess; /*!< session of the trx, NULL if none */
que_t* graph; /*!< query currently run in the session,
or NULL if none; NOTE that the query
belongs to the session, and it can
@@ -1190,7 +1156,7 @@ struct trx_t {
also in the lock list trx_locks. This
vector needs to be freed explicitly
when the trx instance is destroyed.
- Protected by lock_sys->mutex. */
+ Protected by lock_sys.mutex. */
/*------------------------------*/
bool read_only; /*!< true if transaction is flagged
as a READ-ONLY transaction.
@@ -1227,14 +1193,6 @@ struct trx_t {
const char* start_file; /*!< Filename where it was started */
#endif /* UNIV_DEBUG */
- lint n_ref; /*!< Count of references, protected
- by trx_t::mutex. We can't release the
- locks nor commit the transaction until
- this reference is 0. We can change
- the state to COMMITTED_IN_MEMORY to
- signify that it is no longer
- "active". */
-
/** Version of this instance. It is incremented each time the
instance is re-used in trx_start_low(). It is used to track
whether a transaction has been restarted since it was tagged
@@ -1269,6 +1227,8 @@ struct trx_t {
os_event_t wsrep_event; /* event waited for in srv_conc_slot */
#endif /* WITH_WSREP */
+ rw_trx_hash_element_t *rw_trx_hash_element;
+ LF_PINS *rw_trx_hash_pins;
ulint magic_n;
/** @return whether any persistent undo log has been generated */
@@ -1301,6 +1261,33 @@ struct trx_t {
return(assign_temp_rseg());
}
+
+ bool is_referenced()
+ {
+ return my_atomic_load32_explicit(&n_ref, MY_MEMORY_ORDER_RELAXED) > 0;
+ }
+
+
+ void reference()
+ {
+#ifdef UNIV_DEBUG
+ int32_t old_n_ref=
+#endif
+ my_atomic_add32_explicit(&n_ref, 1, MY_MEMORY_ORDER_RELAXED);
+ ut_ad(old_n_ref >= 0);
+ }
+
+
+ void release_reference()
+ {
+#ifdef UNIV_DEBUG
+ int32_t old_n_ref=
+#endif
+ my_atomic_add32_explicit(&n_ref, -1, MY_MEMORY_ORDER_RELAXED);
+ ut_ad(old_n_ref > 0);
+ }
+
+
private:
/** Assign a rollback segment for modifying temporary tables.
@return the assigned rollback segment */
diff --git a/storage/innobase/include/trx0trx.ic b/storage/innobase/include/trx0trx.ic
index 6fa00c5333f..6372a02db17 100644
--- a/storage/innobase/include/trx0trx.ic
+++ b/storage/innobase/include/trx0trx.ic
@@ -24,13 +24,11 @@ The transaction
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-#include "read0read.h"
-
/**********************************************************************//**
Determines if a transaction is in the given state.
-The caller must hold trx_sys->mutex, or it must be the thread
+The caller must hold trx_sys.mutex, or it must be the thread
that is serving a running transaction.
-A running RW transaction must be in trx_sys->rw_trx_list.
+A running RW transaction must be in trx_sys.rw_trx_hash.
@return TRUE if trx->state == state */
UNIV_INLINE
bool
@@ -72,8 +70,6 @@ trx_state_eq(
|| (relaxed
&& thd_get_error_number(trx->mysql_thd)));
- ut_ad(!trx->in_rw_trx_list);
-
return(true);
}
ut_error;
@@ -214,74 +210,6 @@ ok:
}
/**
-Increase the reference count. If the transaction is in state
-TRX_STATE_COMMITTED_IN_MEMORY then the transaction is considered
-committed and the reference count is not incremented.
-@param trx Transaction that is being referenced
-@param do_ref_count Increment the reference iff this is true
-@return transaction instance if it is not committed */
-UNIV_INLINE
-trx_t*
-trx_reference(
- trx_t* trx,
- bool do_ref_count)
-{
- trx_mutex_enter(trx);
-
- if (trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) {
- trx_mutex_exit(trx);
- trx = NULL;
- } else if (do_ref_count) {
- ut_ad(trx->n_ref >= 0);
- ++trx->n_ref;
- trx_mutex_exit(trx);
- } else {
- trx_mutex_exit(trx);
- }
-
- return(trx);
-}
-
-/**
-Release the transaction. Decrease the reference count.
-@param trx Transaction that is being released */
-UNIV_INLINE
-void
-trx_release_reference(
- trx_t* trx)
-{
- trx_mutex_enter(trx);
-
- ut_ad(trx->n_ref > 0);
- --trx->n_ref;
-
- trx_mutex_exit(trx);
-}
-
-
-/**
-@param trx Get the active view for this transaction, if one exists
-@return the transaction's read view or NULL if one not assigned. */
-UNIV_INLINE
-ReadView*
-trx_get_read_view(
- trx_t* trx)
-{
- return(!MVCC::is_view_active(trx->read_view) ? NULL : trx->read_view);
-}
-
-/**
-@param trx Get the active view for this transaction, if one exists
-@return the transaction's read view or NULL if one not assigned. */
-UNIV_INLINE
-const ReadView*
-trx_get_read_view(
- const trx_t* trx)
-{
- return(!MVCC::is_view_active(trx->read_view) ? NULL : trx->read_view);
-}
-
-/**
@param[in] trx Transaction to check
@return true if the transaction is a high priority transaction.*/
UNIV_INLINE
diff --git a/storage/innobase/include/trx0types.h b/storage/innobase/include/trx0types.h
index 8092246c7fa..29139172c92 100644
--- a/storage/innobase/include/trx0types.h
+++ b/storage/innobase/include/trx0types.h
@@ -31,12 +31,9 @@ Created 3/26/1996 Heikki Tuuri
#include "ut0mutex.h"
#include "ut0new.h"
-#include <set>
#include <queue>
#include <vector>
-//#include <unordered_set>
-
/** printf(3) format used for printing DB_TRX_ID and other system fields */
#define TRX_ID_FMT IB_ID_FMT
@@ -115,8 +112,6 @@ enum trx_dict_op_t {
struct trx_t;
/** The locks and state of an active transaction */
struct trx_lock_t;
-/** Transaction system */
-struct trx_sys_t;
/** Signal */
struct trx_sig_t;
/** Rollback segment */
@@ -140,9 +135,6 @@ typedef ib_id_t roll_ptr_t;
/** Undo number */
typedef ib_id_t undo_no_t;
-/** Maximum transaction identifier */
-#define TRX_ID_MAX IB_ID_MAX
-
/** Transaction savepoint */
struct trx_savept_t{
undo_no_t least_undo_no; /*!< least undo number to undo */
@@ -150,8 +142,6 @@ struct trx_savept_t{
/** File objects */
/* @{ */
-/** Transaction system header */
-typedef byte trx_sysf_t;
/** Rollback segment header */
typedef byte trx_rsegf_t;
/** Undo segment header */
@@ -173,51 +163,4 @@ typedef ib_mutex_t PQMutex;
typedef ib_mutex_t TrxSysMutex;
typedef std::vector<trx_id_t, ut_allocator<trx_id_t> > trx_ids_t;
-
-/** Mapping read-write transactions from id to transaction instance, for
-creating read views and during trx id lookup for MVCC and locking. */
-struct TrxTrack {
- explicit TrxTrack(trx_id_t id, trx_t* trx = NULL)
- :
- m_id(id),
- m_trx(trx)
- {
- // Do nothing
- }
-
- trx_id_t m_id;
- trx_t* m_trx;
-};
-
-struct TrxTrackHash {
- size_t operator()(const TrxTrack& key) const
- {
- return(size_t(key.m_id));
- }
-};
-
-/**
-Comparator for TrxMap */
-struct TrxTrackHashCmp {
-
- bool operator() (const TrxTrack& lhs, const TrxTrack& rhs) const
- {
- return(lhs.m_id == rhs.m_id);
- }
-};
-
-/**
-Comparator for TrxMap */
-struct TrxTrackCmp {
-
- bool operator() (const TrxTrack& lhs, const TrxTrack& rhs) const
- {
- return(lhs.m_id < rhs.m_id);
- }
-};
-
-//typedef std::unordered_set<TrxTrack, TrxTrackHash, TrxTrackHashCmp> TrxIdSet;
-typedef std::set<TrxTrack, TrxTrackCmp, ut_allocator<TrxTrack> >
- TrxIdSet;
-
#endif /* trx0types_h */
diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h
index 51f8035d886..b9e5d72866b 100644
--- a/storage/innobase/include/trx0undo.h
+++ b/storage/innobase/include/trx0undo.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -123,17 +123,6 @@ page_t*
trx_undo_page_get_s_latched(const page_id_t& page_id, mtr_t* mtr);
/******************************************************************//**
-Returns the previous undo record on the page in the specified log, or
-NULL if none exists.
-@return pointer to record, NULL if none */
-UNIV_INLINE
-trx_undo_rec_t*
-trx_undo_page_get_prev_rec(
-/*=======================*/
- trx_undo_rec_t* rec, /*!< in: undo log record */
- ulint page_no,/*!< in: undo log header page number */
- ulint offset);/*!< in: undo log header offset on page */
-/******************************************************************//**
Returns the next undo log record on the page in the specified log, or
NULL if none exists.
@return pointer to record, NULL if none */
@@ -144,28 +133,6 @@ trx_undo_page_get_next_rec(
trx_undo_rec_t* rec, /*!< in: undo log record */
ulint page_no,/*!< in: undo log header page number */
ulint offset);/*!< in: undo log header offset on page */
-/******************************************************************//**
-Returns the last undo record on the page in the specified undo log, or
-NULL if none exists.
-@return pointer to record, NULL if none */
-UNIV_INLINE
-trx_undo_rec_t*
-trx_undo_page_get_last_rec(
-/*=======================*/
- page_t* undo_page,/*!< in: undo log page */
- ulint page_no,/*!< in: undo log header page number */
- ulint offset); /*!< in: undo log header offset on page */
-/******************************************************************//**
-Returns the first undo record on the page in the specified undo log, or
-NULL if none exists.
-@return pointer to record, NULL if none */
-UNIV_INLINE
-trx_undo_rec_t*
-trx_undo_page_get_first_rec(
-/*========================*/
- page_t* undo_page,/*!< in: undo log page */
- ulint page_no,/*!< in: undo log header page number */
- ulint offset);/*!< in: undo log header offset on page */
/***********************************************************************//**
Gets the previous record in an undo log.
@return undo log record, the page s-latched, NULL if none */
@@ -243,27 +210,28 @@ trx_undo_truncate_start(
ulint hdr_page_no,
ulint hdr_offset,
undo_no_t limit);
-/********************************************************************//**
-Initializes the undo log lists for a rollback segment memory copy.
-This function is only called when the database is started or a new
-rollback segment created.
-@return the combined size of undo log segments in pages */
-ulint
-trx_undo_lists_init(
-/*================*/
- trx_rseg_t* rseg); /*!< in: rollback segment memory object */
+/** Assign an undo log for a persistent transaction.
+A new undo log is created or a cached undo log reused.
+@param[in,out] trx transaction
+@param[out] err error code
+@param[in,out] mtr mini-transaction
+@return the undo log block
+@retval NULL on error */
+buf_block_t*
+trx_undo_assign(trx_t* trx, dberr_t* err, mtr_t* mtr)
+ MY_ATTRIBUTE((nonnull));
/** Assign an undo log for a transaction.
A new undo log is created or a cached undo log reused.
@param[in,out] trx transaction
@param[in] rseg rollback segment
@param[out] undo the undo log
-@retval DB_SUCCESS on success
-@retval DB_TOO_MANY_CONCURRENT_TRXS
-@retval DB_OUT_OF_FILE_SPACE
-@retval DB_READ_ONLY
-@retval DB_OUT_OF_MEMORY */
-dberr_t
-trx_undo_assign_undo(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo)
+@param[out] err error code
+@param[in,out] mtr mini-transaction
+@return the undo log block
+@retval NULL on error */
+buf_block_t*
+trx_undo_assign_low(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo,
+ dberr_t* err, mtr_t* mtr)
MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Sets the state of the undo log segment at a transaction finish.
@@ -295,13 +263,9 @@ the data can be discarded.
void
trx_undo_commit_cleanup(trx_undo_t* undo, bool is_temp);
-/********************************************************************//**
-At shutdown, frees the undo logs of a PREPARED transaction. */
+/** At shutdown, frees the undo logs of a transaction. */
void
-trx_undo_free_prepared(
-/*===================*/
- trx_t* trx) /*!< in/out: PREPARED transaction */
- ATTRIBUTE_COLD __attribute__((nonnull));
+trx_undo_free_at_shutdown(trx_t *trx);
/* Forward declaration. */
namespace undo {
@@ -315,16 +279,32 @@ bool
trx_undo_truncate_tablespace(
undo::Truncate* undo_trunc);
-/***********************************************************//**
-Parses the redo log entry of an undo log page initialization.
-@return end of log record or NULL */
+/** Parse MLOG_UNDO_INIT for crash-upgrade from MariaDB 10.2.
+@param[in] ptr log record
+@param[in] end_ptr end of log record buffer
+@param[in,out] page page or NULL
+@param[in,out] mtr mini-transaction
+@return end of log record
+@retval NULL if the log record is incomplete */
byte*
trx_undo_parse_page_init(
-/*=====================*/
- const byte* ptr, /*!< in: buffer */
- const byte* end_ptr,/*!< in: buffer end */
- page_t* page, /*!< in: page or NULL */
- mtr_t* mtr); /*!< in: mtr or NULL */
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* page,
+ mtr_t* mtr);
+/** Parse MLOG_UNDO_HDR_REUSE for crash-upgrade from MariaDB 10.2.
+@param[in] ptr redo log record
+@param[in] end_ptr end of log buffer
+@param[in,out] page undo page or NULL
+@param[in,out] mtr mini-transaction
+@return end of log record or NULL */
+byte*
+trx_undo_parse_page_header_reuse(
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* page,
+ mtr_t* mtr);
+
/** Parse the redo log entry of an undo log page header create.
@param[in] ptr redo log record
@param[in] end_ptr end of log buffer
@@ -337,12 +317,15 @@ trx_undo_parse_page_header(
const byte* end_ptr,
page_t* page,
mtr_t* mtr);
-/************************************************************************
-Frees an undo log memory copy. */
-void
-trx_undo_mem_free(
-/*==============*/
- trx_undo_t* undo); /* in: the undo object to be freed */
+/** Read an undo log when starting up the database.
+@param[in,out] rseg rollback segment
+@param[in] id rollback segment slot
+@param[in] page_no undo log segment page number
+@param[in,out] max_trx_id the largest observed transaction ID
+@return size of the undo log in pages */
+ulint
+trx_undo_mem_create_at_db_start(trx_rseg_t* rseg, ulint id, ulint page_no,
+ trx_id_t& max_trx_id);
#endif /* !UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/include/trx0undo.ic b/storage/innobase/include/trx0undo.ic
index 6e76ba205ae..407bc9ff484 100644
--- a/storage/innobase/include/trx0undo.ic
+++ b/storage/innobase/include/trx0undo.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -184,89 +184,24 @@ trx_undo_page_get_s_latched(const page_id_t& page_id, mtr_t* mtr)
return(buf_block_get_frame(block));
}
-/******************************************************************//**
-Returns the start offset of the undo log records of the specified undo
-log on the page.
-@return start offset */
-UNIV_INLINE
-ulint
-trx_undo_page_get_start(
-/*====================*/
- page_t* undo_page,/*!< in: undo log page */
- ulint page_no,/*!< in: undo log header page number */
- ulint offset) /*!< in: undo log header offset on page */
-{
- ulint start;
-
- if (page_no == page_get_page_no(undo_page)) {
-
- start = mach_read_from_2(offset + undo_page
- + TRX_UNDO_LOG_START);
- } else {
- start = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE;
- }
-
- return(start);
-}
-
-/******************************************************************//**
-Returns the end offset of the undo log records of the specified undo
-log on the page.
+/** Determine the end offset of undo log records of an undo log page.
+@param[in] undo_page undo log page
+@param[in] page_no undo log header page number
+@param[in] offset undo log header offset
@return end offset */
-UNIV_INLINE
-ulint
-trx_undo_page_get_end(
-/*==================*/
- page_t* undo_page,/*!< in: undo log page */
- ulint page_no,/*!< in: undo log header page number */
- ulint offset) /*!< in: undo log header offset on page */
+inline
+uint16_t
+trx_undo_page_get_end(const page_t* undo_page, ulint page_no, ulint offset)
{
- trx_ulogf_t* log_hdr;
- ulint end;
-
if (page_no == page_get_page_no(undo_page)) {
-
- log_hdr = undo_page + offset;
-
- end = mach_read_from_2(log_hdr + TRX_UNDO_NEXT_LOG);
-
- if (end == 0) {
- end = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
- + TRX_UNDO_PAGE_FREE);
+ if (uint16_t end = mach_read_from_2(TRX_UNDO_NEXT_LOG
+ + offset + undo_page)) {
+ return end;
}
- } else {
- end = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
- + TRX_UNDO_PAGE_FREE);
- }
-
- return(end);
-}
-
-/******************************************************************//**
-Returns the previous undo record on the page in the specified log, or
-NULL if none exists.
-@return pointer to record, NULL if none */
-UNIV_INLINE
-trx_undo_rec_t*
-trx_undo_page_get_prev_rec(
-/*=======================*/
- trx_undo_rec_t* rec, /*!< in: undo log record */
- ulint page_no,/*!< in: undo log header page number */
- ulint offset) /*!< in: undo log header offset on page */
-{
- page_t* undo_page;
- ulint start;
-
- undo_page = (page_t*) ut_align_down(rec, UNIV_PAGE_SIZE);
-
- start = trx_undo_page_get_start(undo_page, page_no, offset);
-
- if (start + undo_page == rec) {
-
- return(NULL);
}
- return(undo_page + mach_read_from_2(rec - 2));
+ return mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
+ + undo_page);
}
/******************************************************************//**
@@ -298,55 +233,3 @@ trx_undo_page_get_next_rec(
return(undo_page + next);
}
-
-/******************************************************************//**
-Returns the last undo record on the page in the specified undo log, or
-NULL if none exists.
-@return pointer to record, NULL if none */
-UNIV_INLINE
-trx_undo_rec_t*
-trx_undo_page_get_last_rec(
-/*=======================*/
- page_t* undo_page,/*!< in: undo log page */
- ulint page_no,/*!< in: undo log header page number */
- ulint offset) /*!< in: undo log header offset on page */
-{
- ulint start;
- ulint end;
-
- start = trx_undo_page_get_start(undo_page, page_no, offset);
- end = trx_undo_page_get_end(undo_page, page_no, offset);
-
- if (start == end) {
-
- return(NULL);
- }
-
- return(undo_page + mach_read_from_2(undo_page + end - 2));
-}
-
-/******************************************************************//**
-Returns the first undo record on the page in the specified undo log, or
-NULL if none exists.
-@return pointer to record, NULL if none */
-UNIV_INLINE
-trx_undo_rec_t*
-trx_undo_page_get_first_rec(
-/*========================*/
- page_t* undo_page,/*!< in: undo log page */
- ulint page_no,/*!< in: undo log header page number */
- ulint offset) /*!< in: undo log header offset on page */
-{
- ulint start;
- ulint end;
-
- start = trx_undo_page_get_start(undo_page, page_no, offset);
- end = trx_undo_page_get_end(undo_page, page_no, offset);
-
- if (start == end) {
-
- return(NULL);
- }
-
- return(undo_page + start);
-}
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 80c0b5476b0..ba1256feac2 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, MariaDB Corporation.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -41,7 +41,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 7
-#define INNODB_VERSION_BUGFIX 20
+#define INNODB_VERSION_BUGFIX 21
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
@@ -647,14 +647,6 @@ typedef void* os_thread_ret_t;
# define UNIV_MEM_ASSERT_W(addr, size) do {} while(0)
# define UNIV_MEM_TRASH(addr, c, size) do {} while(0)
#endif
-#define UNIV_MEM_ASSERT_AND_FREE(addr, size) do { \
- UNIV_MEM_ASSERT_W(addr, size); \
- UNIV_MEM_FREE(addr, size); \
-} while (0)
-#define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) do { \
- UNIV_MEM_ASSERT_W(addr, size); \
- UNIV_MEM_ALLOC(addr, size); \
-} while (0)
extern ulong srv_page_size_shift;
extern ulong srv_page_size;
diff --git a/storage/innobase/include/usr0sess.h b/storage/innobase/include/usr0sess.h
deleted file mode 100644
index 8e9497a85c5..00000000000
--- a/storage/innobase/include/usr0sess.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 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, Suite 500, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/usr0sess.h
-Sessions
-
-Created 6/25/1996 Heikki Tuuri
-*******************************************************/
-
-#ifndef usr0sess_h
-#define usr0sess_h
-
-#include "univ.i"
-#include "ut0byte.h"
-#include "trx0types.h"
-#include "srv0srv.h"
-#include "trx0types.h"
-#include "usr0types.h"
-#include "que0types.h"
-#include "data0data.h"
-#include "rem0rec.h"
-
-/*********************************************************************//**
-Opens a session.
-@return own: session object */
-sess_t*
-sess_open(void);
-/*============*/
-/*********************************************************************//**
-Closes a session, freeing the memory occupied by it. */
-void
-sess_close(
-/*=======*/
- sess_t* sess); /* in, own: session object */
-
-/* The session handle. This data structure is only used by purge and is
-not really necessary. We should get rid of it. */
-struct sess_t{
- ulint state; /*!< state of the session */
- trx_t* trx; /*!< transaction object permanently
- assigned for the session: the
- transaction instance designated by the
- trx id changes, but the memory
- structure is preserved */
-};
-
-/* Session states */
-#define SESS_ACTIVE 1
-#define SESS_ERROR 2 /* session contains an error message
- which has not yet been communicated
- to the client */
-#endif
diff --git a/storage/innobase/include/usr0types.h b/storage/innobase/include/usr0types.h
deleted file mode 100644
index 6ba937cacc8..00000000000
--- a/storage/innobase/include/usr0types.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1996, 2009, Oracle and/or its affiliates. All Rights Reserved.
-
-This program is free 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, Suite 500, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/usr0types.h
-Users and sessions global types
-
-Created 6/25/1996 Heikki Tuuri
-*******************************************************/
-
-#ifndef usr0types_h
-#define usr0types_h
-
-struct sess_t;
-
-#endif
diff --git a/storage/innobase/include/ut0crc32.h b/storage/innobase/include/ut0crc32.h
index 36b389b5bd2..32ad066f85a 100644
--- a/storage/innobase/include/ut0crc32.h
+++ b/storage/innobase/include/ut0crc32.h
@@ -47,14 +47,11 @@ typedef uint32_t (*ut_crc32_func_t)(const byte* ptr, ulint len);
/** Pointer to CRC32 calculation function. */
extern ut_crc32_func_t ut_crc32;
-/** Pointer to CRC32 calculation function, which uses big-endian byte order
+/** CRC32 calculation function, which uses big-endian byte order
when converting byte strings to integers internally. */
-extern ut_crc32_func_t ut_crc32_legacy_big_endian;
-
-/** Pointer to CRC32-byte-by-byte calculation function (byte order agnostic,
-but very slow). */
-extern ut_crc32_func_t ut_crc32_byte_by_byte;
+extern uint32_t ut_crc32_legacy_big_endian(const byte* buf, ulint len);
+/** Text description of CRC32 implementation */
extern const char* ut_crc32_implementation;
#endif /* ut0crc32_h */
diff --git a/storage/innobase/include/ut0mutex.h b/storage/innobase/include/ut0mutex.h
index bd3603ad4d0..dc387dadbdc 100644
--- a/storage/innobase/include/ut0mutex.h
+++ b/storage/innobase/include/ut0mutex.h
@@ -164,7 +164,7 @@ public:
};
/** Defined in sync0sync.cc */
-extern MutexMonitor* mutex_monitor;
+extern MutexMonitor mutex_monitor;
/**
Creates, or rather, initializes a mutex object in a specified memory
diff --git a/storage/innobase/include/ut0new.h b/storage/innobase/include/ut0new.h
index 955e7b026c7..d61d3072d3d 100644
--- a/storage/innobase/include/ut0new.h
+++ b/storage/innobase/include/ut0new.h
@@ -129,6 +129,10 @@ InnoDB:
#include <string.h> /* strlen(), strrchr(), strncmp() */
#include "my_global.h" /* needed for headers from mysql/psi/ */
+#if !defined(DBUG_OFF) && defined(HAVE_MADVISE)
+#include <sys/mman.h>
+#endif
+
/* JAN: TODO: missing 5.7 header */
#ifdef HAVE_MYSQL_MEMORY_H
#include "mysql/psi/mysql_memory.h" /* PSI_MEMORY_CALL() */
@@ -172,7 +176,6 @@ extern PSI_memory_key mem_key_other;
extern PSI_memory_key mem_key_row_log_buf;
extern PSI_memory_key mem_key_row_merge_sort;
extern PSI_memory_key mem_key_std;
-extern PSI_memory_key mem_key_trx_sys_t_rw_trx_ids;
extern PSI_memory_key mem_key_partitioning;
/** Setup the internal objects needed for UT_NEW() to operate.
@@ -235,6 +238,42 @@ struct ut_new_pfx_t {
#endif
};
+static void ut_allocate_trace_dontdump(void * ptr,
+ size_t bytes,
+ bool dontdump,
+ ut_new_pfx_t* pfx,
+ const char* file)
+{
+ ut_a(ptr != NULL);
+
+#if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DONTDUMP)
+ if (dontdump && madvise(ptr, bytes, MADV_DONTDUMP)) {
+ ib::warn() << "Failed to set memory to DONTDUMP: "
+ << strerror(errno)
+ << " ptr " << ptr
+ << " size " << bytes;
+ }
+#endif
+ if (pfx != NULL) {
+#ifdef UNIV_PFS_MEMORY
+ allocate_trace(bytes, file, pfx);
+#endif /* UNIV_PFS_MEMORY */
+ pfx->m_size = bytes;
+ }
+}
+
+static void ut_dodump(void* ptr, size_t m_size)
+{
+#if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DODUMP)
+ if (ptr && madvise(ptr, m_size, MADV_DODUMP)) {
+ ib::warn() << "Failed to set memory to DODUMP: "
+ << strerror(errno)
+ << " ptr " << ptr
+ << " size " << m_size;
+ }
+#endif
+}
+
/** Allocator class for allocating memory from inside std::* containers.
@tparam T type of allocated object
@tparam oom_fatal whether to commit suicide when running out of memory */
@@ -295,6 +334,7 @@ public:
@param[in] file file name of the caller
@param[in] set_to_zero if true, then the returned memory is
initialized with 0x0 bytes.
+ @param[in] throw_on_error if true, raize exception if too big
@return pointer to the allocated memory */
pointer
allocate(
@@ -567,6 +607,8 @@ public:
/** Allocate a large chunk of memory that can hold 'n_elements'
objects of type 'T' and trace the allocation.
@param[in] n_elements number of elements
+ @param[in] dontdump if true, advise the OS is not to core
+ dump this memory.
@param[out] pfx storage for the description of the
allocated memory. The caller must provide space for this one and keep
it until the memory is no longer needed and then pass it to
@@ -575,7 +617,8 @@ public:
pointer
allocate_large(
size_type n_elements,
- ut_new_pfx_t* pfx)
+ ut_new_pfx_t* pfx,
+ bool dontdump = false)
{
if (n_elements == 0 || n_elements > max_size()) {
return(NULL);
@@ -586,13 +629,11 @@ public:
pointer ptr = reinterpret_cast<pointer>(
os_mem_alloc_large(&n_bytes));
-#ifdef UNIV_PFS_MEMORY
- if (ptr != NULL) {
- allocate_trace(n_bytes, NULL, pfx);
+ if (ptr == NULL) {
+ return NULL;
}
-#else
- pfx->m_size = n_bytes;
-#endif /* UNIV_PFS_MEMORY */
+
+ ut_allocate_trace_dontdump(ptr, n_bytes, dontdump, pfx, NULL);
return(ptr);
}
@@ -601,17 +642,26 @@ public:
deallocation.
@param[in,out] ptr pointer to memory to free
@param[in] pfx descriptor of the memory, as returned by
- allocate_large(). */
+ allocate_large().
+ @param[in] dodump if true, advise the OS to include this
+ memory again if a core dump occurs. */
void
deallocate_large(
pointer ptr,
- const ut_new_pfx_t* pfx)
+ const ut_new_pfx_t* pfx,
+ size_t size,
+ bool dodump = false)
{
+ if (dodump) {
+ ut_dodump(ptr, size);
+ }
#ifdef UNIV_PFS_MEMORY
- deallocate_trace(pfx);
+ if (pfx) {
+ deallocate_trace(pfx);
+ }
#endif /* UNIV_PFS_MEMORY */
- os_mem_free_large(ptr, pfx->m_size);
+ os_mem_free_large(ptr, size);
}
#ifdef UNIV_PFS_MEMORY
@@ -843,6 +893,10 @@ ut_delete_array(
ut_allocator<byte>(key).allocate( \
n_bytes, NULL, __FILE__, false, false))
+#define ut_malloc_dontdump(n_bytes) static_cast<void*>( \
+ ut_allocator<byte>(PSI_NOT_INSTRUMENTED).allocate_large( \
+ n_bytes, true))
+
#define ut_zalloc(n_bytes, key) static_cast<void*>( \
ut_allocator<byte>(key).allocate( \
n_bytes, NULL, __FILE__, true, false))
@@ -866,6 +920,10 @@ ut_delete_array(
#define ut_free(ptr) ut_allocator<byte>(PSI_NOT_INSTRUMENTED).deallocate( \
reinterpret_cast<byte*>(ptr))
+#define ut_free_dodump(ptr, size) static_cast<void*>( \
+ ut_allocator<byte>(PSI_NOT_INSTRUMENTED).deallocate_large( \
+ ptr, NULL, size, true))
+
#else /* UNIV_PFS_MEMORY */
/* Fallbacks when memory tracing is disabled at compile time. */
@@ -888,6 +946,14 @@ ut_delete_array(
#define ut_malloc_nokey(n_bytes) ::malloc(n_bytes)
+static inline void *ut_malloc_dontdump(size_t n_bytes)
+{
+ void *ptr = os_mem_alloc_large(&n_bytes);
+
+ ut_allocate_trace_dontdump(ptr, n_bytes, true, NULL, NULL);
+ return ptr;
+}
+
#define ut_zalloc_nokey(n_bytes) ::calloc(1, n_bytes)
#define ut_zalloc_nokey_nofatal(n_bytes) ::calloc(1, n_bytes)
@@ -896,6 +962,12 @@ ut_delete_array(
#define ut_free(ptr) ::free(ptr)
+static inline void ut_free_dodump(void *ptr, size_t size)
+{
+ ut_dodump(ptr, size);
+ os_mem_free_large(ptr, size);
+}
+
#endif /* UNIV_PFS_MEMORY */
#endif /* ut0new_h */
diff --git a/storage/innobase/include/ut0rnd.h b/storage/innobase/include/ut0rnd.h
index 49ae3c81356..5baf8684d23 100644
--- a/storage/innobase/include/ut0rnd.h
+++ b/storage/innobase/include/ut0rnd.h
@@ -61,16 +61,6 @@ UNIV_INLINE
ulint
ut_rnd_gen_ulint(void);
/*==================*/
-/********************************************************//**
-Generates a random integer from a given interval.
-@return the 'random' number */
-UNIV_INLINE
-ulint
-ut_rnd_interval(
-/*============*/
- ulint low, /*!< in: low limit; can generate also this value */
- ulint high); /*!< in: high limit; can generate also this value */
-
/*******************************************************//**
The following function generates a hash value for a ulint integer
to a hash table of size table_size, which should be a prime or some
diff --git a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic
index 16dccb545d8..1e4915dd0f9 100644
--- a/storage/innobase/include/ut0rnd.ic
+++ b/storage/innobase/include/ut0rnd.ic
@@ -97,30 +97,6 @@ ut_rnd_gen_ulint(void)
return(rnd);
}
-/********************************************************//**
-Generates a random integer from a given interval.
-@return the 'random' number */
-UNIV_INLINE
-ulint
-ut_rnd_interval(
-/*============*/
- ulint low, /*!< in: low limit; can generate also this value */
- ulint high) /*!< in: high limit; can generate also this value */
-{
- ulint rnd;
-
- ut_ad(high >= low);
-
- if (low == high) {
-
- return(low);
- }
-
- rnd = ut_rnd_gen_ulint();
-
- return(low + (rnd % (high - low)));
-}
-
/*******************************************************//**
The following function generates a hash value for a ulint integer
to a hash table of size table_size, which should be a prime
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index b8282b7d0de..1614d3ead6d 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -45,6 +45,7 @@ Created 1/20/1994 Heikki Tuuri
#include <stdarg.h>
#include <string>
+#include <my_atomic.h>
/** Index name prefix in fast index creation, as a string constant */
#define TEMP_INDEX_PREFIX_STR "\377"
@@ -52,35 +53,6 @@ Created 1/20/1994 Heikki Tuuri
/** Time stamp */
typedef time_t ib_time_t;
-#ifdef HAVE_PAUSE_INSTRUCTION
- /* According to the gcc info page, asm volatile means that the
- instruction has important side-effects and must not be removed.
- Also asm volatile may trigger a memory barrier (spilling all registers
- to memory). */
-# ifdef __SUNPRO_CC
-# define UT_RELAX_CPU() asm ("pause" )
-# else
-# define UT_RELAX_CPU() __asm__ __volatile__ ("pause")
-# endif /* __SUNPRO_CC */
-
-#elif defined(HAVE_FAKE_PAUSE_INSTRUCTION)
-# define UT_RELAX_CPU() __asm__ __volatile__ ("rep; nop")
-#elif defined _WIN32
- /* In the Win32 API, the x86 PAUSE instruction is executed by calling
- the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
- independent way by using YieldProcessor. */
-# define UT_RELAX_CPU() YieldProcessor()
-#elif defined(__powerpc__) && defined __GLIBC__
-# include <sys/platform/ppc.h>
-# define UT_RELAX_CPU() __ppc_get_timebase()
-#else
-# define UT_RELAX_CPU() do { \
- volatile int32 volatile_var; \
- int32 oldval= 0; \
- my_atomic_cas32(&volatile_var, &oldval, 1); \
- } while (0)
-#endif
-
#if defined (__GNUC__)
# define UT_COMPILER_BARRIER() __asm__ __volatile__ ("":::"memory")
#elif defined (_MSC_VER)
@@ -89,15 +61,6 @@ typedef time_t ib_time_t;
# define UT_COMPILER_BARRIER()
#endif
-#if defined(HAVE_HMT_PRIORITY_INSTRUCTION)
-# include <sys/platform/ppc.h>
-# define UT_LOW_PRIORITY_CPU() __ppc_set_ppr_low()
-# define UT_RESUME_PRIORITY_CPU() __ppc_set_ppr_med()
-#else
-# define UT_LOW_PRIORITY_CPU() ((void)0)
-# define UT_RESUME_PRIORITY_CPU() ((void)0)
-#endif
-
/*********************************************************************//**
Delays execution for at most max_wait_us microseconds or returns earlier
if cond becomes true.
@@ -395,50 +358,6 @@ ut_copy_file(
FILE* dest, /*!< in: output file */
FILE* src); /*!< in: input file to be appended to output */
-#ifdef _WIN32
-/**********************************************************************//**
-A substitute for vsnprintf(3), formatted output conversion into
-a limited buffer. Note: this function DOES NOT return the number of
-characters that would have been printed if the buffer was unlimited because
-VC's _vsnprintf() returns -1 in this case and we would need to call
-_vscprintf() in addition to estimate that but we would need another copy
-of "ap" for that and VC does not provide va_copy(). */
-void
-ut_vsnprintf(
-/*=========*/
- char* str, /*!< out: string */
- size_t size, /*!< in: str size */
- const char* fmt, /*!< in: format */
- va_list ap); /*!< in: format values */
-
-/**********************************************************************//**
-A substitute for snprintf(3), formatted output conversion into
-a limited buffer.
-@return number of characters that would have been printed if the size
-were unlimited, not including the terminating '\0'. */
-int
-ut_snprintf(
-/*========*/
- char* str, /*!< out: string */
- size_t size, /*!< in: str size */
- const char* fmt, /*!< in: format */
- ...); /*!< in: format values */
-#else
-/**********************************************************************//**
-A wrapper for vsnprintf(3), formatted output conversion into
-a limited buffer. Note: this function DOES NOT return the number of
-characters that would have been printed if the buffer was unlimited because
-VC's _vsnprintf() returns -1 in this case and we would need to call
-_vscprintf() in addition to estimate that but we would need another copy
-of "ap" for that and VC does not provide va_copy(). */
-# define ut_vsnprintf(buf, size, fmt, ap) \
- ((void) vsnprintf(buf, size, fmt, ap))
-/**********************************************************************//**
-A wrapper for snprintf(3), formatted output conversion into
-a limited buffer. */
-# define ut_snprintf snprintf
-#endif /* _WIN32 */
-
/*************************************************************//**
Convert an error number to a human readable text message. The
returned string is static and should not be freed or modified.
diff --git a/storage/innobase/innodb.cmake b/storage/innobase/innodb.cmake
index b3e52fa10b1..71c9cc8594b 100644
--- a/storage/innobase/innodb.cmake
+++ b/storage/innobase/innodb.cmake
@@ -110,7 +110,7 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
ENDIF()
# Enable InnoDB's UNIV_DEBUG in debug builds
-SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUNIV_DEBUG -DUNIV_SYNC_DEBUG")
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUNIV_DEBUG")
OPTION(WITH_INNODB_AHI "Include innodb_adaptive_hash_index" ON)
OPTION(WITH_INNODB_ROOT_GUESS "Cache index root block descriptors" ON)
@@ -156,6 +156,11 @@ IF(HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE)
ENDIF()
IF(NOT MSVC)
+ CHECK_FUNCTION_EXISTS(posix_memalign HAVE_POSIX_MEMALIGN)
+ IF(HAVE_POSIX_MEMALIGN)
+ ADD_DEFINITIONS(-DHAVE_POSIX_MEMALIGN)
+ ENDIF()
+
# Only use futexes on Linux if GCC atomics are available
IF(NOT MSVC AND NOT CMAKE_CROSSCOMPILING)
CHECK_C_SOURCE_RUNS(
@@ -228,13 +233,6 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "SunPro"
PROPERTIES COMPILE_FLAGS -xO3)
ENDIF()
-# Removing compiler optimizations for innodb/mem/* files on 64-bit Windows
-# due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297
-IF (MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
- SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.cc mem/mem0pool.cc
- PROPERTIES COMPILE_FLAGS -Od)
-ENDIF()
-
# Avoid generating Hardware Capabilities due to crc32 instructions
IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_SYSTEM_PROCESSOR MATCHES "i386")
INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/compile_flags.cmake)
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index ed3281e1453..32648e2bdbf 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2014, 2018, 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
@@ -35,7 +35,6 @@ Created 5/7/1996 Heikki Tuuri
#include "lock0lock.h"
#include "lock0priv.h"
#include "dict0mem.h"
-#include "usr0sess.h"
#include "trx0purge.h"
#include "trx0sys.h"
#include "srv0mon.h"
@@ -54,7 +53,7 @@ Created 5/7/1996 Heikki Tuuri
#endif /* WITH_WSREP */
/** Lock scheduling algorithm */
-ulong innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS;
+ulong innodb_lock_schedule_algorithm;
/** The value of innodb_deadlock_detect */
my_bool innobase_deadlock_detect;
@@ -82,7 +81,7 @@ lock_rec_has_to_wait_in_queue(
/*************************************************************//**
Grants a lock to a waiting lock request and releases the waiting transaction.
-The caller must hold lock_sys->mutex. */
+The caller must hold lock_sys.mutex. */
static
void
lock_grant(
@@ -280,7 +279,7 @@ private:
ulint m_heap_no; /*!< heap number if rec lock */
};
- /** Used in deadlock tracking. Protected by lock_sys->mutex. */
+ /** Used in deadlock tracking. Protected by lock_sys.mutex. */
static ib_uint64_t s_lock_mark_counter;
/** Calculation steps thus far. It is the count of the nodes visited. */
@@ -336,7 +335,7 @@ lock_rec_validate_page(
#endif /* UNIV_DEBUG */
/* The lock system */
-lock_sys_t* lock_sys = NULL;
+lock_sys_t lock_sys;
/** We store info on the latest deadlock error to this buffer. InnoDB
Monitor will then fetch it and print */
@@ -354,7 +353,7 @@ lock_report_trx_id_insanity(
const rec_t* rec, /*!< in: user record */
dict_index_t* index, /*!< in: index */
const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
- trx_id_t max_trx_id) /*!< in: trx_sys_get_max_trx_id() */
+ trx_id_t max_trx_id) /*!< in: trx_sys.get_max_trx_id() */
{
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!rec_is_default_row(rec, index));
@@ -371,11 +370,6 @@ lock_report_trx_id_insanity(
/*********************************************************************//**
Checks that a transaction id is sensible, i.e., not in the future.
@return true if ok */
-#ifdef UNIV_DEBUG
-
-#else
-static MY_ATTRIBUTE((warn_unused_result))
-#endif
bool
lock_check_trx_id_sanity(
/*=====================*/
@@ -387,15 +381,15 @@ lock_check_trx_id_sanity(
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!rec_is_default_row(rec, index));
- trx_id_t max_trx_id = trx_sys_get_max_trx_id();
- bool is_ok = trx_id < max_trx_id;
+ trx_id_t max_trx_id = trx_sys.get_max_trx_id();
+ ut_ad(max_trx_id || srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN);
- if (!is_ok) {
+ if (max_trx_id && trx_id >= max_trx_id) {
lock_report_trx_id_insanity(
trx_id, rec, index, offsets, max_trx_id);
+ return false;
}
-
- return(is_ok);
+ return(true);
}
/*********************************************************************//**
@@ -421,7 +415,8 @@ lock_clust_rec_cons_read_sees(
operate on same temp-table and so read of temp-table is
always consistent read. */
if (srv_read_only_mode || dict_table_is_temporary(index->table)) {
- ut_ad(view == 0 || dict_table_is_temporary(index->table));
+ ut_ad(!view->is_open()
+ || dict_table_is_temporary(index->table));
return(true);
}
@@ -453,17 +448,13 @@ lock_sec_rec_cons_read_sees(
const ReadView* view) /*!< in: consistent read view */
{
ut_ad(page_rec_is_user_rec(rec));
- ut_ad(!index->is_clust());
+ ut_ad(!index->is_primary());
ut_ad(!rec_is_default_row(rec, index));
/* NOTE that we might call this function while holding the search
system latch. */
- if (recv_recovery_is_on()) {
-
- return(false);
-
- } else if (dict_table_is_temporary(index->table)) {
+ if (dict_table_is_temporary(index->table)) {
/* Temp-tables are not shared across connections and multiple
transactions from different connections cannot simultaneously
@@ -480,34 +471,31 @@ lock_sec_rec_cons_read_sees(
return(view->sees(max_trx_id));
}
-/*********************************************************************//**
-Creates the lock system at database start. */
-void
-lock_sys_create(
-/*============*/
- ulint n_cells) /*!< in: number of slots in lock hash table */
-{
- ulint lock_sys_sz;
-
- lock_sys_sz = sizeof(*lock_sys) + OS_THREAD_MAX_N * sizeof(srv_slot_t);
- lock_sys = static_cast<lock_sys_t*>(ut_zalloc_nokey(lock_sys_sz));
+/**
+ Creates the lock system at database start.
- void* ptr = &lock_sys[1];
+ @param[in] n_cells number of slots in lock hash table
+*/
+void lock_sys_t::create(ulint n_cells)
+{
+ ut_ad(this == &lock_sys);
- lock_sys->waiting_threads = static_cast<srv_slot_t*>(ptr);
+ m_initialised= true;
- lock_sys->last_slot = lock_sys->waiting_threads;
+ waiting_threads = static_cast<srv_slot_t*>
+ (ut_zalloc_nokey(srv_max_n_threads * sizeof *waiting_threads));
+ last_slot = waiting_threads;
- mutex_create(LATCH_ID_LOCK_SYS, &lock_sys->mutex);
+ mutex_create(LATCH_ID_LOCK_SYS, &mutex);
- mutex_create(LATCH_ID_LOCK_SYS_WAIT, &lock_sys->wait_mutex);
+ mutex_create(LATCH_ID_LOCK_SYS_WAIT, &wait_mutex);
- lock_sys->timeout_event = os_event_create(0);
+ timeout_event = os_event_create(0);
- lock_sys->rec_hash = hash_create(n_cells);
- lock_sys->prdt_hash = hash_create(n_cells);
- lock_sys->prdt_page_hash = hash_create(n_cells);
+ rec_hash = hash_create(n_cells);
+ prdt_hash = hash_create(n_cells);
+ prdt_page_hash = hash_create(n_cells);
if (!srv_read_only_mode) {
lock_latest_err_file = os_file_create_tmpfile(NULL);
@@ -527,31 +515,33 @@ lock_rec_lock_fold(
lock->un_member.rec_lock.page_no));
}
-/** Resize the lock hash tables.
-@param[in] n_cells number of slots in lock hash table */
-void
-lock_sys_resize(
- ulint n_cells)
+
+/**
+ Resize the lock hash table.
+
+ @param[in] n_cells number of slots in lock hash table
+*/
+void lock_sys_t::resize(ulint n_cells)
{
- hash_table_t* old_hash;
+ ut_ad(this == &lock_sys);
- lock_mutex_enter();
+ mutex_enter(&mutex);
- old_hash = lock_sys->rec_hash;
- lock_sys->rec_hash = hash_create(n_cells);
- HASH_MIGRATE(old_hash, lock_sys->rec_hash, lock_t, hash,
+ hash_table_t* old_hash = rec_hash;
+ rec_hash = hash_create(n_cells);
+ HASH_MIGRATE(old_hash, rec_hash, lock_t, hash,
lock_rec_lock_fold);
hash_table_free(old_hash);
- old_hash = lock_sys->prdt_hash;
- lock_sys->prdt_hash = hash_create(n_cells);
- HASH_MIGRATE(old_hash, lock_sys->prdt_hash, lock_t, hash,
+ old_hash = prdt_hash;
+ prdt_hash = hash_create(n_cells);
+ HASH_MIGRATE(old_hash, prdt_hash, lock_t, hash,
lock_rec_lock_fold);
hash_table_free(old_hash);
- old_hash = lock_sys->prdt_page_hash;
- lock_sys->prdt_page_hash = hash_create(n_cells);
- HASH_MIGRATE(old_hash, lock_sys->prdt_page_hash, lock_t, hash,
+ old_hash = prdt_page_hash;
+ prdt_page_hash = hash_create(n_cells);
+ HASH_MIGRATE(old_hash, prdt_page_hash, lock_t, hash,
lock_rec_lock_fold);
hash_table_free(old_hash);
@@ -580,40 +570,39 @@ lock_sys_resize(
buf_pool_mutex_exit(buf_pool);
}
- lock_mutex_exit();
+ mutex_exit(&mutex);
}
-/*********************************************************************//**
-Closes the lock system at database shutdown. */
-void
-lock_sys_close(void)
-/*================*/
+
+/** Closes the lock system at database shutdown. */
+void lock_sys_t::close()
{
+ ut_ad(this == &lock_sys);
+
+ if (!m_initialised) return;
+
if (lock_latest_err_file != NULL) {
fclose(lock_latest_err_file);
lock_latest_err_file = NULL;
}
- hash_table_free(lock_sys->rec_hash);
- hash_table_free(lock_sys->prdt_hash);
- hash_table_free(lock_sys->prdt_page_hash);
-
- os_event_destroy(lock_sys->timeout_event);
+ hash_table_free(rec_hash);
+ hash_table_free(prdt_hash);
+ hash_table_free(prdt_page_hash);
- mutex_destroy(&lock_sys->mutex);
- mutex_destroy(&lock_sys->wait_mutex);
+ os_event_destroy(timeout_event);
- srv_slot_t* slot = lock_sys->waiting_threads;
+ mutex_destroy(&mutex);
+ mutex_destroy(&wait_mutex);
- for (ulint i = 0; i < OS_THREAD_MAX_N; i++, ++slot) {
- if (slot->event != NULL) {
- os_event_destroy(slot->event);
+ for (ulint i = srv_max_n_threads; i--; ) {
+ if (os_event_t& event = waiting_threads[i].event) {
+ os_event_destroy(event);
}
}
- ut_free(lock_sys);
-
- lock_sys = NULL;
+ ut_free(waiting_threads);
+ m_initialised= false;
}
/*********************************************************************//**
@@ -627,145 +616,6 @@ lock_get_size(void)
}
/*********************************************************************//**
-Gets the source table of an ALTER TABLE transaction. The table must be
-covered by an IX or IS table lock.
-@return the source table of transaction, if it is covered by an IX or
-IS table lock; dest if there is no source table, and NULL if the
-transaction is locking more than two tables or an inconsistency is
-found */
-dict_table_t*
-lock_get_src_table(
-/*===============*/
- trx_t* trx, /*!< in: transaction */
- dict_table_t* dest, /*!< in: destination of ALTER TABLE */
- lock_mode* mode) /*!< out: lock mode of the source table */
-{
- dict_table_t* src;
- lock_t* lock;
-
- ut_ad(!lock_mutex_own());
-
- src = NULL;
- *mode = LOCK_NONE;
-
- /* The trx mutex protects the trx_locks for our purposes.
- Other transactions could want to convert one of our implicit
- record locks to an explicit one. For that, they would need our
- trx mutex. Waiting locks can be removed while only holding
- lock_sys->mutex, but this is a running transaction and cannot
- thus be holding any waiting locks. */
- trx_mutex_enter(trx);
-
- for (lock = UT_LIST_GET_FIRST(trx->lock.trx_locks);
- lock != NULL;
- lock = UT_LIST_GET_NEXT(trx_locks, lock)) {
- lock_table_t* tab_lock;
- lock_mode lock_mode;
- if (!(lock_get_type_low(lock) & LOCK_TABLE)) {
- /* We are only interested in table locks. */
- continue;
- }
- tab_lock = &lock->un_member.tab_lock;
- if (dest == tab_lock->table) {
- /* We are not interested in the destination table. */
- continue;
- } else if (!src) {
- /* This presumably is the source table. */
- src = tab_lock->table;
- if (UT_LIST_GET_LEN(src->locks) != 1
- || UT_LIST_GET_FIRST(src->locks) != lock) {
- /* We only support the case when
- there is only one lock on this table. */
- src = NULL;
- goto func_exit;
- }
- } else if (src != tab_lock->table) {
- /* The transaction is locking more than
- two tables (src and dest): abort */
- src = NULL;
- goto func_exit;
- }
-
- /* Check that the source table is locked by
- LOCK_IX or LOCK_IS. */
- lock_mode = lock_get_mode(lock);
- if (lock_mode == LOCK_IX || lock_mode == LOCK_IS) {
- if (*mode != LOCK_NONE && *mode != lock_mode) {
- /* There are multiple locks on src. */
- src = NULL;
- goto func_exit;
- }
- *mode = lock_mode;
- }
- }
-
- if (!src) {
- /* No source table lock found: flag the situation to caller */
- src = dest;
- }
-
-func_exit:
- trx_mutex_exit(trx);
- return(src);
-}
-
-/*********************************************************************//**
-Determine if the given table is exclusively "owned" by the given
-transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
-on the table.
-@return TRUE if table is only locked by trx, with LOCK_IX, and
-possibly LOCK_AUTO_INC */
-ibool
-lock_is_table_exclusive(
-/*====================*/
- const dict_table_t* table, /*!< in: table */
- const trx_t* trx) /*!< in: transaction */
-{
- const lock_t* lock;
- ibool ok = FALSE;
-
- ut_ad(table);
- ut_ad(trx);
-
- lock_mutex_enter();
-
- for (lock = UT_LIST_GET_FIRST(table->locks);
- lock != NULL;
- lock = UT_LIST_GET_NEXT(locks, &lock->un_member.tab_lock)) {
- if (lock->trx != trx) {
- /* A lock on the table is held
- by some other transaction. */
- goto not_ok;
- }
-
- if (!(lock_get_type_low(lock) & LOCK_TABLE)) {
- /* We are interested in table locks only. */
- continue;
- }
-
- switch (lock_get_mode(lock)) {
- case LOCK_IX:
- ok = TRUE;
- break;
- case LOCK_AUTO_INC:
- /* It is allowed for trx to hold an
- auto_increment lock. */
- break;
- default:
-not_ok:
- /* Other table locks than LOCK_IX are not allowed. */
- ok = FALSE;
- goto func_exit;
- }
- }
-
-func_exit:
- lock_mutex_exit();
-
- return(ok);
-}
-
-/*********************************************************************//**
Sets the wait flag of a lock and the back pointer in trx to lock. */
UNIV_INLINE
void
@@ -818,13 +668,18 @@ lock_reset_lock_and_trx_wait(
}
ib::error() <<
- "Trx id " << lock->trx->id
- << " is waiting a lock in statement "
- << (stmt ? stmt : "NULL")
- << " for this trx id " << trx_id
- << " and statement "
- << (stmt2 ? stmt2 : "NULL")
- << "wait_lock " << lock->trx->lock.wait_lock;
+ "Trx id " << ib::hex(lock->trx->id)
+ << " is waiting a lock "
+ << " for this trx id " << ib::hex(trx_id)
+ << " wait_lock " << lock->trx->lock.wait_lock;
+ if (stmt) {
+ ib::info() << " SQL1: " << stmt;
+ }
+
+ if (stmt2) {
+ ib::info() << " SQL2: " << stmt2;
+ }
+
ut_ad(0);
}
@@ -881,7 +736,7 @@ lock_rec_get_insert_intention(
Checks if a lock request for a new lock has to wait for request lock2.
@return TRUE if new lock has to wait for lock2 to be removed */
UNIV_INLINE
-ibool
+bool
lock_rec_has_to_wait(
/*=================*/
bool for_locking,
@@ -904,160 +759,162 @@ lock_rec_has_to_wait(
ut_ad(trx && lock2);
ut_ad(lock_get_type_low(lock2) == LOCK_REC);
- if (trx != lock2->trx
- && !lock_mode_compatible(static_cast<lock_mode>(
- LOCK_MODE_MASK & type_mode),
- lock_get_mode(lock2))) {
+ if (trx == lock2->trx
+ || lock_mode_compatible(
+ static_cast<lock_mode>(LOCK_MODE_MASK & type_mode),
+ lock_get_mode(lock2))) {
+ return false;
+ }
- /* We have somewhat complex rules when gap type record locks
- cause waits */
+ /* We have somewhat complex rules when gap type record locks
+ cause waits */
- if ((lock_is_on_supremum || (type_mode & LOCK_GAP))
- && !(type_mode & LOCK_INSERT_INTENTION)) {
+ if ((lock_is_on_supremum || (type_mode & LOCK_GAP))
+ && !(type_mode & LOCK_INSERT_INTENTION)) {
- /* Gap type locks without LOCK_INSERT_INTENTION flag
- do not need to wait for anything. This is because
- different users can have conflicting lock types
- on gaps. */
+ /* Gap type locks without LOCK_INSERT_INTENTION flag
+ do not need to wait for anything. This is because
+ different users can have conflicting lock types
+ on gaps. */
- return(FALSE);
- }
+ return false;
+ }
- if (!(type_mode & LOCK_INSERT_INTENTION)
- && lock_rec_get_gap(lock2)) {
+ if (!(type_mode & LOCK_INSERT_INTENTION) && lock_rec_get_gap(lock2)) {
- /* Record lock (LOCK_ORDINARY or LOCK_REC_NOT_GAP
- does not need to wait for a gap type lock */
+ /* Record lock (LOCK_ORDINARY or LOCK_REC_NOT_GAP
+ does not need to wait for a gap type lock */
- return(FALSE);
- }
+ return false;
+ }
- if ((type_mode & LOCK_GAP)
- && lock_rec_get_rec_not_gap(lock2)) {
+ if ((type_mode & LOCK_GAP) && lock_rec_get_rec_not_gap(lock2)) {
- /* Lock on gap does not need to wait for
- a LOCK_REC_NOT_GAP type lock */
+ /* Lock on gap does not need to wait for
+ a LOCK_REC_NOT_GAP type lock */
- return(FALSE);
- }
+ return false;
+ }
- if (lock_rec_get_insert_intention(lock2)) {
+ if (lock_rec_get_insert_intention(lock2)) {
- /* No lock request needs to wait for an insert
- intention lock to be removed. This is ok since our
- rules allow conflicting locks on gaps. This eliminates
- a spurious deadlock caused by a next-key lock waiting
- for an insert intention lock; when the insert
- intention lock was granted, the insert deadlocked on
- the waiting next-key lock.
+ /* No lock request needs to wait for an insert
+ intention lock to be removed. This is ok since our
+ rules allow conflicting locks on gaps. This eliminates
+ a spurious deadlock caused by a next-key lock waiting
+ for an insert intention lock; when the insert
+ intention lock was granted, the insert deadlocked on
+ the waiting next-key lock.
- Also, insert intention locks do not disturb each
- other. */
+ Also, insert intention locks do not disturb each
+ other. */
- return(FALSE);
- }
+ return false;
+ }
- if ((type_mode & LOCK_GAP || lock_rec_get_gap(lock2)) &&
- !thd_need_ordering_with(trx->mysql_thd,
- lock2->trx->mysql_thd)) {
- /* If the upper server layer has already decided on the
- commit order between the transaction requesting the
- lock and the transaction owning the lock, we do not
- need to wait for gap locks. Such ordeering by the upper
- server layer happens in parallel replication, where the
- commit order is fixed to match the original order on the
- master.
-
- Such gap locks are mainly needed to get serialisability
- between transactions so that they will be binlogged in
- the correct order so that statement-based replication
- will give the correct results. Since the right order
- was already determined on the master, we do not need
- to enforce it again here.
-
- Skipping the locks is not essential for correctness,
- since in case of deadlock we will just kill the later
- transaction and retry it. But it can save some
- unnecessary rollbacks and retries. */
-
- return (FALSE);
- }
+ if ((type_mode & LOCK_GAP || lock_rec_get_gap(lock2))
+ && !thd_need_ordering_with(trx->mysql_thd, lock2->trx->mysql_thd)) {
+ /* If the upper server layer has already decided on the
+ commit order between the transaction requesting the
+ lock and the transaction owning the lock, we do not
+ need to wait for gap locks. Such ordeering by the upper
+ server layer happens in parallel replication, where the
+ commit order is fixed to match the original order on the
+ master.
+
+ Such gap locks are mainly needed to get serialisability
+ between transactions so that they will be binlogged in
+ the correct order so that statement-based replication
+ will give the correct results. Since the right order
+ was already determined on the master, we do not need
+ to enforce it again here.
+
+ Skipping the locks is not essential for correctness,
+ since in case of deadlock we will just kill the later
+ transaction and retry it. But it can save some
+ unnecessary rollbacks and retries. */
+
+ return false;
+ }
#ifdef WITH_WSREP
- /* if BF thread is locking and has conflict with another BF
- thread, we need to look at trx ordering and lock types */
- if (wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) {
+ /* if BF thread is locking and has conflict with another BF
+ thread, we need to look at trx ordering and lock types */
+ if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)
+ && wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) {
- if (wsrep_debug) {
- ib::info() <<
- "BF-BF lock conflict, locking: " << for_locking;
+ if (wsrep_debug) {
+ ib::info() << "BF-BF lock conflict, locking: "
+ << for_locking;
+ lock_rec_print(stderr, lock2);
+ ib::info()
+ << " SQL1: " << wsrep_thd_query(trx->mysql_thd)
+ << " SQL2: "
+ << wsrep_thd_query(lock2->trx->mysql_thd);
+ }
+
+ if (wsrep_trx_order_before(trx->mysql_thd,
+ lock2->trx->mysql_thd)
+ && (type_mode & LOCK_MODE_MASK) == LOCK_X
+ && (lock2->type_mode & LOCK_MODE_MASK) == LOCK_X) {
+ if (for_locking || wsrep_debug) {
+ /* exclusive lock conflicts are not
+ accepted */
+ ib::info()
+ << "BF-BF X lock conflict,mode: "
+ << type_mode
+ << " supremum: " << lock_is_on_supremum
+ << "conflicts states: my "
+ << wsrep_thd_conflict_state(
+ trx->mysql_thd, FALSE)
+ << " locked "
+ << wsrep_thd_conflict_state(
+ lock2->trx->mysql_thd,
+ FALSE);
lock_rec_print(stderr, lock2);
ib::info() << " SQL1: "
- << wsrep_thd_query(trx->mysql_thd);
- ib::info() << " SQL2: "
- << wsrep_thd_query(lock2->trx->mysql_thd);
- }
+ << wsrep_thd_query(trx->mysql_thd)
+ << " SQL2: "
+ << wsrep_thd_query(
+ lock2->trx->mysql_thd);
- if (wsrep_trx_order_before(trx->mysql_thd,
- lock2->trx->mysql_thd) &&
- (type_mode & LOCK_MODE_MASK) == LOCK_X &&
- (lock2->type_mode & LOCK_MODE_MASK) == LOCK_X) {
- if (for_locking || wsrep_debug) {
- /* exclusive lock conflicts are not
- accepted */
- ib::info() <<
- "BF-BF X lock conflict,"
- "mode: " << type_mode <<
- " supremum: " << lock_is_on_supremum;
- ib::info() <<
- "conflicts states: my "
- << wsrep_thd_conflict_state(trx->mysql_thd, FALSE)
- << " locked "
- << wsrep_thd_conflict_state(lock2->trx->mysql_thd, FALSE);
- lock_rec_print(stderr, lock2);
- ib::info() << " SQL1: "
- << wsrep_thd_query(trx->mysql_thd);
- ib::info() << " SQL2: "
- << wsrep_thd_query(lock2->trx->mysql_thd);
-
- if (for_locking) {
- return FALSE;
- }
+ if (for_locking) {
+ return false;
}
- } else {
- /* if lock2->index->n_uniq <=
- lock2->index->n_user_defined_cols
- operation is on uniq index
- */
- if (wsrep_debug) {
- ib::info() <<
- "BF conflict, modes: "
- << type_mode << ":" << lock2->type_mode
- << " idx: " << lock2->index->name()
- << " table: " << lock2->index->table->name.m_name
- << " n_uniq: " << lock2->index->n_uniq
- << " n_user: " << lock2->index->n_user_defined_cols;
- ib::info() << " SQL1: "
- << wsrep_thd_query(trx->mysql_thd);
- ib::info() << " SQL2: "
- << wsrep_thd_query(lock2->trx->mysql_thd);
- }
- return FALSE;
}
+ } else {
+ /* if lock2->index->n_uniq <=
+ lock2->index->n_user_defined_cols
+ operation is on uniq index
+ */
+ if (wsrep_debug) {
+ ib::info()
+ << "BF conflict, modes: " << type_mode
+ << ":" << lock2->type_mode
+ << " idx: " << lock2->index->name()
+ << " table: "
+ << lock2->index->table->name.m_name
+ << " n_uniq: " << lock2->index->n_uniq
+ << " n_user: "
+ << lock2->index->n_user_defined_cols
+ << " SQL1: "
+ << wsrep_thd_query(trx->mysql_thd)
+ << " SQL2: "
+ << wsrep_thd_query(
+ lock2->trx->mysql_thd);
+ }
+ return false;
}
-#endif /* WITH_WSREP */
-
- return(TRUE);
}
+#endif /* WITH_WSREP */
- return(FALSE);
+ return true;
}
/*********************************************************************//**
Checks if a lock request lock1 has to wait for request lock2.
@return TRUE if lock1 has to wait for lock2 to be removed */
-ibool
+bool
lock_has_to_wait(
/*=============*/
const lock_t* lock1, /*!< in: waiting lock */
@@ -1068,32 +925,27 @@ lock_has_to_wait(
{
ut_ad(lock1 && lock2);
- if (lock1->trx != lock2->trx
- && !lock_mode_compatible(lock_get_mode(lock1),
- lock_get_mode(lock2))) {
- if (lock_get_type_low(lock1) == LOCK_REC) {
- ut_ad(lock_get_type_low(lock2) == LOCK_REC);
-
- /* If this lock request is for a supremum record
- then the second bit on the lock bitmap is set */
-
- if (lock1->type_mode
- & (LOCK_PREDICATE | LOCK_PRDT_PAGE)) {
- return(lock_prdt_has_to_wait(
- lock1->trx, lock1->type_mode,
- lock_get_prdt_from_lock(lock1),
- lock2));
- } else {
- return(lock_rec_has_to_wait(false,
- lock1->trx, lock1->type_mode, lock2,
- lock_rec_get_nth_bit(lock1, true)));
- }
- }
+ if (lock1->trx == lock2->trx
+ || lock_mode_compatible(lock_get_mode(lock1),
+ lock_get_mode(lock2))) {
+ return false;
+ }
+
+ if (lock_get_type_low(lock1) != LOCK_REC) {
+ return true;
+ }
- return(TRUE);
+ ut_ad(lock_get_type_low(lock2) == LOCK_REC);
+
+ if (lock1->type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE)) {
+ return lock_prdt_has_to_wait(lock1->trx, lock1->type_mode,
+ lock_get_prdt_from_lock(lock1),
+ lock2);
}
- return(FALSE);
+ return lock_rec_has_to_wait(
+ false, lock1->trx, lock1->type_mode, lock2,
+ lock_rec_get_nth_bit(lock1, PAGE_HEAP_NO_SUPREMUM));
}
/*============== RECORD LOCK BASIC FUNCTIONS ============================*/
@@ -1175,7 +1027,7 @@ lock_rec_expl_exist_on_page(
lock_mutex_enter();
/* Only used in ibuf pages, so rec_hash is good enough */
- lock = lock_rec_get_first_on_page_addr(lock_sys->rec_hash,
+ lock = lock_rec_get_first_on_page_addr(lock_sys.rec_hash,
space, page_no);
lock_mutex_exit();
@@ -1293,7 +1145,7 @@ lock_rec_has_expl(
|| (precise_mode & LOCK_MODE_MASK) == LOCK_X);
ut_ad(!(precise_mode & LOCK_INSERT_INTENTION));
- for (lock = lock_rec_get_first(lock_sys->rec_hash, block, heap_no);
+ for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
lock != NULL;
lock = lock_rec_get_next(heap_no, lock)) {
@@ -1323,7 +1175,7 @@ lock_rec_has_expl(
Checks if some other transaction has a lock request in the queue.
@return lock or NULL */
static
-const lock_t*
+lock_t*
lock_rec_other_has_expl_req(
/*========================*/
lock_mode mode, /*!< in: LOCK_S or LOCK_X */
@@ -1346,10 +1198,10 @@ lock_rec_other_has_expl_req(
return(NULL);
}
- for (const lock_t* lock = lock_rec_get_first(lock_sys->rec_hash,
+ for (lock_t* lock = lock_rec_get_first(lock_sys.rec_hash,
block, heap_no);
lock != NULL;
- lock = lock_rec_get_next_const(heap_no, lock)) {
+ lock = lock_rec_get_next(heap_no, lock)) {
if (lock->trx != trx
&& !lock_rec_get_gap(lock)
@@ -1401,14 +1253,14 @@ wsrep_kill_victim(
ib::info() << "*** Victim TRANSACTION:";
}
- wsrep_trx_print_locking(stderr, trx, 3000);
+ trx_print_latched(stderr, trx, 3000);
if (bf_other) {
ib::info() << "*** Priority TRANSACTION:";
} else {
ib::info() << "*** Victim TRANSACTION:";
}
- wsrep_trx_print_locking(stderr, lock->trx, 3000);
+ trx_print_latched(stderr, lock->trx, 3000);
ib::info() << "*** WAITING FOR THIS LOCK TO BE GRANTED:";
@@ -1438,7 +1290,7 @@ Checks if some other transaction has a conflicting explicit lock request
in the queue, so that we have to wait.
@return lock or NULL */
static
-const lock_t*
+lock_t*
lock_rec_other_has_conflicting(
/*===========================*/
ulint mode, /*!< in: LOCK_S or LOCK_X,
@@ -1450,21 +1302,24 @@ lock_rec_other_has_conflicting(
ulint heap_no,/*!< in: heap number of the record */
const trx_t* trx) /*!< in: our transaction */
{
- const lock_t* lock;
+ lock_t* lock;
ut_ad(lock_mutex_own());
bool is_supremum = (heap_no == PAGE_HEAP_NO_SUPREMUM);
- for (lock = lock_rec_get_first(lock_sys->rec_hash, block, heap_no);
+ for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
lock != NULL;
- lock = lock_rec_get_next_const(heap_no, lock)) {
+ lock = lock_rec_get_next(heap_no, lock)) {
if (lock_rec_has_to_wait(true, trx, mode, lock, is_supremum)) {
#ifdef WITH_WSREP
if (wsrep_on_trx(trx)) {
trx_mutex_enter(lock->trx);
- wsrep_kill_victim((trx_t *)trx, (lock_t *)lock);
+ /* Below function will roll back either trx
+ or lock->trx depending on priority of the
+ transaction. */
+ wsrep_kill_victim(const_cast<trx_t*>(trx), lock);
trx_mutex_exit(lock->trx);
}
#endif /* WITH_WSREP */
@@ -1486,6 +1341,7 @@ static
trx_t*
lock_sec_rec_some_has_impl(
/*=======================*/
+ trx_t* caller_trx,/*!<in/out: trx of current thread */
const rec_t* rec, /*!< in: user record */
dict_index_t* index, /*!< in: secondary index */
const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
@@ -1495,7 +1351,7 @@ lock_sec_rec_some_has_impl(
const page_t* page = page_align(rec);
ut_ad(!lock_mutex_own());
- ut_ad(!trx_sys_mutex_own());
+ ut_ad(!mutex_own(&trx_sys.mutex));
ut_ad(!dict_index_is_clust(index));
ut_ad(page_rec_is_user_rec(rec));
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -1509,7 +1365,7 @@ lock_sec_rec_some_has_impl(
max trx id to the log, and therefore during recovery, this value
for a page may be incorrect. */
- if (max_trx_id < trx_rw_min_trx_id() && !recv_recovery_is_on()) {
+ if (max_trx_id < trx_sys.get_min_trx_id()) {
trx = 0;
@@ -1522,70 +1378,17 @@ lock_sec_rec_some_has_impl(
x-lock. We have to look in the clustered index. */
} else {
- trx = row_vers_impl_x_locked(rec, index, offsets);
+ trx = row_vers_impl_x_locked(caller_trx, rec, index, offsets);
}
return(trx);
}
-#ifdef UNIV_DEBUG
-/*********************************************************************//**
-Checks if some transaction, other than given trx_id, has an explicit
-lock on the given rec, in the given precise_mode.
-@return the transaction, whose id is not equal to trx_id, that has an
-explicit lock on the given rec, in the given precise_mode or NULL.*/
-static
-trx_t*
-lock_rec_other_trx_holds_expl(
-/*==========================*/
- ulint precise_mode, /*!< in: LOCK_S or LOCK_X
- possibly ORed to LOCK_GAP or
- LOCK_REC_NOT_GAP. */
- trx_t* trx, /*!< in: trx holding implicit
- lock on rec */
- const rec_t* rec, /*!< in: user record */
- const buf_block_t* block) /*!< in: buffer block
- containing the record */
-{
- ut_ad(!page_rec_is_default_row(rec));
-
- trx_t* holds = NULL;
-
- lock_mutex_enter();
-
- if (trx_t* impl_trx = trx_rw_is_active(trx->id, NULL, false)) {
- ulint heap_no = page_rec_get_heap_no(rec);
- mutex_enter(&trx_sys->mutex);
-
- for (trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
- t != NULL;
- t = UT_LIST_GET_NEXT(trx_list, t)) {
-
- lock_t* expl_lock = lock_rec_has_expl(
- precise_mode, block, heap_no, t);
-
- if (expl_lock && expl_lock->trx != impl_trx) {
- /* An explicit lock is held by trx other than
- the trx holding the implicit lock. */
- holds = expl_lock->trx;
- break;
- }
- }
-
- mutex_exit(&trx_sys->mutex);
- }
-
- lock_mutex_exit();
-
- return(holds);
-}
-#endif /* UNIV_DEBUG */
-
/*********************************************************************//**
Return approximate number or record locks (bits set in the bitmap) for
this transaction. Since delete-marked records may be removed, the
record count will not be precise.
-The caller must be holding lock_sys->mutex. */
+The caller must be holding lock_sys.mutex. */
ulint
lock_number_of_rows_locked(
/*=======================*/
@@ -1598,7 +1401,7 @@ lock_number_of_rows_locked(
/*********************************************************************//**
Return the number of table locks for a transaction.
-The caller must be holding lock_sys->mutex. */
+The caller must be holding lock_sys.mutex. */
ulint
lock_number_of_tables_locked(
/*=========================*/
@@ -1930,7 +1733,7 @@ Add the lock to the record lock hash and the transaction's lock list
@param[in,out] lock Newly created record lock to add to the rec hash
@param[in] add_to_hash If the lock should be added to the hash table */
void
-RecLock::lock_add(lock_t* lock, bool add_to_hash)
+RecLock::lock_add(lock_t* lock, bool add_to_hash) const
{
ut_ad(lock_mutex_own());
ut_ad(trx_mutex_own(lock->trx));
@@ -1968,19 +1771,21 @@ Create a new lock.
@param[in] owns_trx_mutex true if caller owns the trx_t::mutex
@param[in] add_to_hash add the lock to hash table
@param[in] prdt Predicate lock (optional)
+@param[in,out] c_lock Conflicting lock request or NULL
+ in Galera conflicting lock is selected
+ as deadlock victim if requester
+ is BF transaction.
@return a new lock instance */
lock_t*
-RecLock::create(trx_t* trx, bool owns_trx_mutex, bool add_to_hash, const lock_prdt_t* prdt)
-{
- return create(NULL, trx, owns_trx_mutex, add_to_hash, prdt);
-}
-lock_t*
RecLock::create(
- lock_t* const c_lock,
trx_t* trx,
bool owns_trx_mutex,
bool add_to_hash,
- const lock_prdt_t* prdt)
+ const lock_prdt_t* prdt
+#ifdef WITH_WSREP
+ ,lock_t* c_lock
+#endif /* WITH_WSREP */
+) const
{
ut_ad(lock_mutex_own());
ut_ad(owns_trx_mutex == trx_mutex_own(trx));
@@ -2066,7 +1871,7 @@ RecLock::create(
trx_mutex_exit(c_lock->trx);
if (wsrep_debug) {
- ib::info() << "WSREP: c_lock canceled " << c_lock->trx->id;
+ ib::info() << "WSREP: c_lock canceled " << ib::hex(c_lock->trx->id);
ib::info() << " SQL1: "
<< wsrep_thd_query(c_lock->trx->mysql_thd);
ib::info() << " SQL2: "
@@ -2203,8 +2008,8 @@ RecLock::mark_trx_for_rollback(trx_t* trx)
if (thd != NULL) {
char buffer[1024];
- ib::info() << "Blocking transaction: ID: " << trx->id << " - "
- << " Blocked transaction ID: "<< m_trx->id << " - "
+ ib::info() << "Blocking transaction: ID: " << ib::hex(trx->id) << " - "
+ << " Blocked transaction ID: "<< ib::hex(m_trx->id) << " - "
<< thd_get_error_context_description(thd, buffer, sizeof(buffer),
512);
}
@@ -2245,7 +2050,7 @@ queue is itself waiting roll it back, also do a deadlock check and resolve.
as a victim, and we got the lock immediately: no need to wait then;
DB_LOCK_WAIT_TIMEOUT means no need to wait */
dberr_t
-RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt)
+RecLock::add_to_waitq(lock_t* wait_for, const lock_prdt_t* prdt)
{
ut_ad(lock_mutex_own());
ut_ad(m_trx == thr_get_trx(m_thr));
@@ -2267,7 +2072,12 @@ RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt)
bool high_priority = trx_is_high_priority(m_trx);
/* Don't queue the lock to hash table, if high priority transaction. */
- lock_t* lock = create(m_trx, true, !high_priority, prdt);
+ lock_t* lock = create(
+ m_trx, true, !high_priority, prdt
+#ifdef WITH_WSREP
+ ,wait_for
+#endif /* WITH_WSREP */
+ );
/* Attempt to jump over the low priority waiting locks. */
if (high_priority && jump_queue(lock, wait_for)) {
@@ -2276,10 +2086,18 @@ RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt)
return(DB_SUCCESS);
}
+#ifdef WITH_WSREP
+ if (!lock_get_wait(lock) && wsrep_thd_is_BF(m_trx->mysql_thd, FALSE)) {
+ if (wsrep_debug) {
+ ib::info() << "WSREP: BF thread got lock granted early, ID " << ib::hex(lock->trx->id)
+ << " query: " << wsrep_thd_query(m_trx->mysql_thd);
+ }
+ return(DB_SUCCESS);
+ }
+#endif /* WITH_WSREP */
ut_ad(lock_get_wait(lock));
- dberr_t err = deadlock_check(lock);
-
+ dberr_t err = deadlock_check(lock);
ut_ad(trx_mutex_own(m_trx));
// Move it only when it does not cause a deadlock.
@@ -2428,175 +2246,6 @@ lock_rec_add_to_queue(
}
/*********************************************************************//**
-This is a fast routine for locking a record in the most common cases:
-there are no explicit locks on the page, or there is just one lock, owned
-by this transaction, and of the right type_mode. This is a low-level function
-which does NOT look at implicit locks! Checks lock compatibility within
-explicit locks. This function sets a normal next-key lock, or in the case of
-a page supremum record, a gap type lock.
-@return whether the locking succeeded */
-UNIV_INLINE
-lock_rec_req_status
-lock_rec_lock_fast(
-/*===============*/
- bool impl, /*!< in: if TRUE, no lock is set
- if no wait is necessary: we
- assume that the caller will
- set an implicit lock */
- ulint mode, /*!< in: lock mode: LOCK_X or
- LOCK_S possibly ORed to either
- LOCK_GAP or LOCK_REC_NOT_GAP */
- const buf_block_t* block, /*!< in: buffer block containing
- the record */
- ulint heap_no,/*!< in: heap number of record */
- dict_index_t* index, /*!< in: index of record */
- que_thr_t* thr) /*!< in: query thread */
-{
- ut_ad(lock_mutex_own());
- ut_ad(!srv_read_only_mode);
- ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
- || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS));
- ut_ad((LOCK_MODE_MASK & mode) != LOCK_X
- || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)
- || srv_read_only_mode);
- ut_ad((LOCK_MODE_MASK & mode) == LOCK_S
- || (LOCK_MODE_MASK & mode) == LOCK_X);
- ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
- || mode - (LOCK_MODE_MASK & mode) == 0
- || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
- ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
-
- DBUG_EXECUTE_IF("innodb_report_deadlock", return(LOCK_REC_FAIL););
-
- lock_t* lock = lock_rec_get_first_on_page(lock_sys->rec_hash, block);
-
- trx_t* trx = thr_get_trx(thr);
-
- lock_rec_req_status status = LOCK_REC_SUCCESS;
-
- if (lock == NULL) {
-
- if (!impl) {
- RecLock rec_lock(index, block, heap_no, mode);
-
- /* Note that we don't own the trx mutex. */
- rec_lock.create(trx, false, true);
- }
-
- status = LOCK_REC_SUCCESS_CREATED;
- } else {
- trx_mutex_enter(trx);
-
- if (lock_rec_get_next_on_page(lock)
- || lock->trx != trx
- || lock->type_mode != (mode | LOCK_REC)
- || lock_rec_get_n_bits(lock) <= heap_no) {
-
- status = LOCK_REC_FAIL;
- } else if (!impl) {
- /* If the nth bit of the record lock is already set
- then we do not set a new lock bit, otherwise we do
- set */
- if (!lock_rec_get_nth_bit(lock, heap_no)) {
- lock_rec_set_nth_bit(lock, heap_no);
- status = LOCK_REC_SUCCESS_CREATED;
- }
- }
-
- trx_mutex_exit(trx);
- }
-
- return(status);
-}
-
-/*********************************************************************//**
-This is the general, and slower, routine for locking a record. This is a
-low-level function which does NOT look at implicit locks! Checks lock
-compatibility within explicit locks. This function sets a normal next-key
-lock, or in the case of a page supremum record, a gap type lock.
-@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
-or DB_QUE_THR_SUSPENDED */
-static
-dberr_t
-lock_rec_lock_slow(
-/*===============*/
- ibool impl, /*!< in: if TRUE, no lock is set
- if no wait is necessary: we
- assume that the caller will
- set an implicit lock */
- ulint mode, /*!< in: lock mode: LOCK_X or
- LOCK_S possibly ORed to either
- LOCK_GAP or LOCK_REC_NOT_GAP */
- const buf_block_t* block, /*!< in: buffer block containing
- the record */
- ulint heap_no,/*!< in: heap number of record */
- dict_index_t* index, /*!< in: index of record */
- que_thr_t* thr) /*!< in: query thread */
-{
- ut_ad(lock_mutex_own());
- ut_ad(!srv_read_only_mode);
- ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
- || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS));
- ut_ad((LOCK_MODE_MASK & mode) != LOCK_X
- || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
- ut_ad((LOCK_MODE_MASK & mode) == LOCK_S
- || (LOCK_MODE_MASK & mode) == LOCK_X);
- ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
- || mode - (LOCK_MODE_MASK & mode) == 0
- || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
- ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
-
- DBUG_EXECUTE_IF("innodb_report_deadlock", return(DB_DEADLOCK););
-
- dberr_t err;
- trx_t* trx = thr_get_trx(thr);
-
- trx_mutex_enter(trx);
-
- if (lock_rec_has_expl(mode, block, heap_no, trx)) {
-
- /* The trx already has a strong enough lock on rec: do
- nothing */
-
- err = DB_SUCCESS;
-
- } else {
-
- const lock_t* wait_for = lock_rec_other_has_conflicting(
- mode, block, heap_no, trx);
-
- if (wait_for != NULL) {
-
- /* If another transaction has a non-gap conflicting
- request in the queue, as this transaction does not
- have a lock strong enough already granted on the
- record, we may have to wait. */
-
- RecLock rec_lock(thr, index, block, heap_no, mode);
-
- err = rec_lock.add_to_waitq(wait_for);
-
- } else if (!impl) {
-
- /* Set the requested lock on the record, note that
- we already own the transaction mutex. */
-
- lock_rec_add_to_queue(
- LOCK_REC | mode, block, heap_no, index, trx,
- true);
-
- err = DB_SUCCESS_LOCKED_REC;
- } else {
- err = DB_SUCCESS;
- }
- }
-
- trx_mutex_exit(trx);
-
- return(err);
-}
-
-/*********************************************************************//**
Tries to lock the specified record in the mode requested. If not immediately
possible, enqueues a waiting lock request. This is a low-level function
which does NOT look at implicit locks! Checks lock compatibility within
@@ -2621,33 +2270,83 @@ lock_rec_lock(
dict_index_t* index, /*!< in: index of record */
que_thr_t* thr) /*!< in: query thread */
{
- ut_ad(lock_mutex_own());
- ut_ad(!srv_read_only_mode);
- ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
- || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS));
- ut_ad((LOCK_MODE_MASK & mode) != LOCK_X
- || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
- ut_ad((LOCK_MODE_MASK & mode) == LOCK_S
- || (LOCK_MODE_MASK & mode) == LOCK_X);
- ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
- || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP
- || mode - (LOCK_MODE_MASK & mode) == 0);
- ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
-
- /* We try a simplified and faster subroutine for the most
- common cases */
- switch (lock_rec_lock_fast(impl, mode, block, heap_no, index, thr)) {
- case LOCK_REC_SUCCESS:
- return(DB_SUCCESS);
- case LOCK_REC_SUCCESS_CREATED:
- return(DB_SUCCESS_LOCKED_REC);
- case LOCK_REC_FAIL:
- return(lock_rec_lock_slow(impl, mode, block,
- heap_no, index, thr));
- }
-
- ut_error;
- return(DB_ERROR);
+ trx_t *trx= thr_get_trx(thr);
+ dberr_t err= DB_SUCCESS;
+
+ ut_ad(!srv_read_only_mode);
+ ut_ad((LOCK_MODE_MASK & mode) == LOCK_S ||
+ (LOCK_MODE_MASK & mode) == LOCK_X);
+ ut_ad((mode & LOCK_TYPE_MASK) == LOCK_GAP ||
+ (mode & LOCK_TYPE_MASK) == LOCK_REC_NOT_GAP ||
+ (mode & LOCK_TYPE_MASK) == 0);
+ ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
+ DBUG_EXECUTE_IF("innodb_report_deadlock", return DB_DEADLOCK;);
+
+ lock_mutex_enter();
+ ut_ad((LOCK_MODE_MASK & mode) != LOCK_S ||
+ lock_table_has(trx, index->table, LOCK_IS));
+ ut_ad((LOCK_MODE_MASK & mode) != LOCK_X ||
+ lock_table_has(trx, index->table, LOCK_IX));
+
+ if (lock_t *lock= lock_rec_get_first_on_page(lock_sys.rec_hash, block))
+ {
+ trx_mutex_enter(trx);
+ if (lock_rec_get_next_on_page(lock) ||
+ lock->trx != trx ||
+ lock->type_mode != (mode | LOCK_REC) ||
+ lock_rec_get_n_bits(lock) <= heap_no)
+ {
+ /* Do nothing if the trx already has a strong enough lock on rec */
+ if (!lock_rec_has_expl(mode, block, heap_no, trx))
+ {
+ if (lock_t *wait_for= lock_rec_other_has_conflicting(mode, block,
+ heap_no, trx))
+ {
+ /*
+ If another transaction has a non-gap conflicting
+ request in the queue, as this transaction does not
+ have a lock strong enough already granted on the
+ record, we may have to wait.
+ */
+ RecLock rec_lock(thr, index, block, heap_no, mode);
+ err= rec_lock.add_to_waitq(wait_for);
+ }
+ else if (!impl)
+ {
+ /* Set the requested lock on the record. */
+ lock_rec_add_to_queue(LOCK_REC | mode, block, heap_no, index, trx,
+ true);
+ err= DB_SUCCESS_LOCKED_REC;
+ }
+ }
+ }
+ else if (!impl)
+ {
+ /*
+ If the nth bit of the record lock is already set then we do not set
+ a new lock bit, otherwise we do set
+ */
+ if (!lock_rec_get_nth_bit(lock, heap_no))
+ {
+ lock_rec_set_nth_bit(lock, heap_no);
+ err= DB_SUCCESS_LOCKED_REC;
+ }
+ }
+ trx_mutex_exit(trx);
+ }
+ else
+ {
+ /*
+ Simplified and faster path for the most common cases
+ Note that we don't own the trx mutex.
+ */
+ if (!impl)
+ RecLock(index, block, heap_no, mode).create(trx, false, true);
+ err= DB_SUCCESS_LOCKED_REC;
+ }
+ lock_mutex_exit();
+ MONITOR_ATOMIC_INC(MONITOR_NUM_RECLOCK_REQ);
+ return err;
}
/*********************************************************************//**
@@ -2692,6 +2391,14 @@ lock_rec_has_to_wait_in_queue(
#ifdef WITH_WSREP
if (wsrep_thd_is_BF(wait_lock->trx->mysql_thd, FALSE) &&
wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE)) {
+ if (wsrep_debug) {
+ ib::info() << "WSREP: waiting BF trx: " << ib::hex(wait_lock->trx->id)
+ << " query: " << wsrep_thd_query(wait_lock->trx->mysql_thd);
+ lock_rec_print(stderr, wait_lock);
+ ib::info() << "WSREP: do not wait another BF trx: " << ib::hex(lock->trx->id)
+ << " query: " << wsrep_thd_query(lock->trx->mysql_thd);
+ lock_rec_print(stderr, lock);
+ }
/* don't wait for another BF lock */
continue;
}
@@ -2706,7 +2413,7 @@ lock_rec_has_to_wait_in_queue(
/*************************************************************//**
Grants a lock to a waiting lock request and releases the waiting transaction.
-The caller must hold lock_sys->mutex but not lock->trx->mutex. */
+The caller must hold lock_sys.mutex but not lock->trx->mutex. */
static
void
lock_grant(
@@ -2794,8 +2501,8 @@ RecLock::jump_queue(
DBUG_LOG("trx",
"Granting High Priority Transaction "
- << lock->trx->id << " a lock jumping over"
- << " waiting Transaction " << conflict_lock->trx->id);
+ << ib::hex(lock->trx->id) << " a lock jumping over"
+ << " waiting Transaction " << ib::hex(conflict_lock->trx->id));
lock_reset_lock_and_trx_wait(lock);
return(true);
@@ -2852,7 +2559,10 @@ RecLock::lock_add_priority(
lock_t* grant_position = NULL;
lock_t* add_position = NULL;
- HASH_SEARCH(hash, lock_sys->rec_hash, m_rec_id.fold(), lock_t*,
+ /* Different lock (such as predicate lock) are on different hash */
+ hash_table_t* lock_hash = lock_hash_get(m_mode);
+
+ HASH_SEARCH(hash, lock_hash, m_rec_id.fold(), lock_t*,
lock_head, ut_ad(lock_head->is_record_lock()), true);
ut_ad(lock_head);
@@ -2966,9 +2676,9 @@ RecLock::make_trx_hit_list(
ut_ad(trx->lock.wait_lock != next);
DBUG_LOG("trx", "High Priority Transaction "
- << lock->trx->id
+ << ib::hex(lock->trx->id)
<< " waking up blocking transaction "
- << trx->id);
+ << ib::hex(trx->id));
trx->lock.was_chosen_as_deadlock_victim = true;
lock_cancel_waiting_and_release(trx->lock.wait_lock);
@@ -3058,22 +2768,21 @@ lock_grant_and_move_on_page(
&& lock_get_wait(lock)
&& !lock_rec_has_to_wait_in_queue(lock)) {
-
bool exit_trx_mutex = false;
-
+
if (lock->trx->abort_type != TRX_SERVER_ABORT) {
ut_ad(trx_mutex_own(lock->trx));
trx_mutex_exit(lock->trx);
exit_trx_mutex = true;
}
-
+
lock_grant(lock, false);
-
+
if (exit_trx_mutex) {
ut_ad(!trx_mutex_own(lock->trx));
trx_mutex_enter(lock->trx);
}
-
+
if (previous != NULL) {
/* Move the lock to the head of the list. */
HASH_GET_NEXT(hash, previous) = HASH_GET_NEXT(hash, lock);
@@ -3169,9 +2878,9 @@ lock_rec_dequeue_from_page(
}
}
}
- } else {
- lock_grant_and_move_on_page(lock_hash, space, page_no);
- }
+ } else {
+ lock_grant_and_move_on_page(lock_hash, space, page_no);
+ }
}
/*************************************************************//**
@@ -3254,11 +2963,11 @@ lock_rec_free_all_from_discard_page(
page_no = block->page.id.page_no();
lock_rec_free_all_from_discard_page_low(
- space, page_no, lock_sys->rec_hash);
+ space, page_no, lock_sys.rec_hash);
lock_rec_free_all_from_discard_page_low(
- space, page_no, lock_sys->prdt_hash);
+ space, page_no, lock_sys.prdt_hash);
lock_rec_free_all_from_discard_page_low(
- space, page_no, lock_sys->prdt_page_hash);
+ space, page_no, lock_sys.prdt_page_hash);
}
/*============= RECORD LOCK MOVING AND INHERITING ===================*/
@@ -3303,12 +3012,12 @@ lock_rec_reset_and_release_wait(
ulint heap_no)/*!< in: heap number of record */
{
lock_rec_reset_and_release_wait_low(
- lock_sys->rec_hash, block, heap_no);
+ lock_sys.rec_hash, block, heap_no);
lock_rec_reset_and_release_wait_low(
- lock_sys->prdt_hash, block, PAGE_HEAP_NO_INFIMUM);
+ lock_sys.prdt_hash, block, PAGE_HEAP_NO_INFIMUM);
lock_rec_reset_and_release_wait_low(
- lock_sys->prdt_page_hash, block, PAGE_HEAP_NO_INFIMUM);
+ lock_sys.prdt_page_hash, block, PAGE_HEAP_NO_INFIMUM);
}
/*************************************************************//**
@@ -3341,7 +3050,7 @@ lock_rec_inherit_to_gap(
DO want S-locks/X-locks(taken for replace) set by a consistency
constraint to be inherited also then. */
- for (lock = lock_rec_get_first(lock_sys->rec_hash, block, heap_no);
+ for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
lock != NULL;
lock = lock_rec_get_next(heap_no, lock)) {
@@ -3379,7 +3088,7 @@ lock_rec_inherit_to_gap_if_gap_lock(
lock_mutex_enter();
- for (lock = lock_rec_get_first(lock_sys->rec_hash, block, heap_no);
+ for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
lock != NULL;
lock = lock_rec_get_next(heap_no, lock)) {
@@ -3423,8 +3132,8 @@ lock_rec_move_low(
/* If the lock is predicate lock, it resides on INFIMUM record */
ut_ad(lock_rec_get_first(
lock_hash, receiver, receiver_heap_no) == NULL
- || lock_hash == lock_sys->prdt_hash
- || lock_hash == lock_sys->prdt_page_hash);
+ || lock_hash == lock_sys.prdt_hash
+ || lock_hash == lock_sys.prdt_page_hash);
for (lock = lock_rec_get_first(lock_hash,
donator, donator_heap_no);
@@ -3447,7 +3156,7 @@ lock_rec_move_low(
lock->index, lock->trx, FALSE);
}
- ut_ad(lock_rec_get_first(lock_sys->rec_hash,
+ ut_ad(lock_rec_get_first(lock_sys.rec_hash,
donator, donator_heap_no) == NULL);
}
@@ -3502,7 +3211,7 @@ lock_rec_move(
ulint donator_heap_no)/*!< in: heap_no of the record
which gives the locks */
{
- lock_rec_move_low(lock_sys->rec_hash, receiver, donator,
+ lock_rec_move_low(lock_sys.rec_hash, receiver, donator,
receiver_heap_no, donator_heap_no);
}
@@ -3527,7 +3236,7 @@ lock_move_reorganize_page(
lock_mutex_enter();
/* FIXME: This needs to deal with predicate lock too */
- lock = lock_rec_get_first_on_page(lock_sys->rec_hash, block);
+ lock = lock_rec_get_first_on_page(lock_sys.rec_hash, block);
if (lock == NULL) {
lock_mutex_exit();
@@ -3660,7 +3369,7 @@ lock_move_rec_list_end(
table to the end of the hash chain, and lock_rec_add_to_queue
does not reuse locks if there are waiters in the queue. */
- for (lock = lock_rec_get_first_on_page(lock_sys->rec_hash, block); lock;
+ for (lock = lock_rec_get_first_on_page(lock_sys.rec_hash, block); lock;
lock = lock_rec_get_next_on_page(lock)) {
const rec_t* rec1 = rec;
const rec_t* rec2;
@@ -3775,7 +3484,7 @@ lock_move_rec_list_start(
lock_mutex_enter();
- for (lock = lock_rec_get_first_on_page(lock_sys->rec_hash, block); lock;
+ for (lock = lock_rec_get_first_on_page(lock_sys.rec_hash, block); lock;
lock = lock_rec_get_next_on_page(lock)) {
const rec_t* rec1;
const rec_t* rec2;
@@ -3797,8 +3506,9 @@ lock_move_rec_list_start(
reset the lock bits on the old */
while (rec1 != rec) {
- ut_ad(!page_rec_is_default_row(rec1));
- ut_ad(!page_rec_is_default_row(rec2));
+ ut_ad(page_rec_is_default_row(rec1)
+ == page_rec_is_default_row(rec2));
+ ut_d(const rec_t* const prev = rec1);
ulint rec1_heap_no;
ulint rec2_heap_no;
@@ -3822,6 +3532,8 @@ lock_move_rec_list_start(
if (rec1_heap_no < lock->un_member.rec_lock.n_bits
&& lock_rec_reset_nth_bit(lock, rec1_heap_no)) {
+ ut_ad(!page_rec_is_default_row(prev));
+
if (type_mode & LOCK_WAIT) {
lock_reset_lock_and_trx_wait(lock);
}
@@ -3884,7 +3596,7 @@ lock_rtr_move_rec_list(
lock_mutex_enter();
- for (lock = lock_rec_get_first_on_page(lock_sys->rec_hash, block); lock;
+ for (lock = lock_rec_get_first_on_page(lock_sys.rec_hash, block); lock;
lock = lock_rec_get_next_on_page(lock)) {
ulint moved = 0;
const rec_t* rec1;
@@ -3996,7 +3708,7 @@ lock_update_merge_right(
waiting transactions */
lock_rec_reset_and_release_wait_low(
- lock_sys->rec_hash, left_block, PAGE_HEAP_NO_SUPREMUM);
+ lock_sys.rec_hash, left_block, PAGE_HEAP_NO_SUPREMUM);
#ifdef UNIV_DEBUG
/* there should exist no page lock on the left page,
@@ -4004,7 +3716,7 @@ lock_update_merge_right(
ulint space = left_block->page.id.space();
ulint page_no = left_block->page.id.page_no();
ut_ad(lock_rec_get_first_on_page_addr(
- lock_sys->prdt_page_hash, space, page_no) == NULL);
+ lock_sys.prdt_page_hash, space, page_no) == NULL);
#endif /* UNIV_DEBUG */
lock_rec_free_all_from_discard_page(left_block);
@@ -4114,7 +3826,7 @@ lock_update_merge_left(
releasing waiting transactions */
lock_rec_reset_and_release_wait_low(
- lock_sys->rec_hash, left_block, PAGE_HEAP_NO_SUPREMUM);
+ lock_sys.rec_hash, left_block, PAGE_HEAP_NO_SUPREMUM);
}
/* Move the locks from the supremum of right page to the supremum
@@ -4129,7 +3841,7 @@ lock_update_merge_left(
ulint space = right_block->page.id.space();
ulint page_no = right_block->page.id.page_no();
lock_t* lock_test = lock_rec_get_first_on_page_addr(
- lock_sys->prdt_page_hash, space, page_no);
+ lock_sys.prdt_page_hash, space, page_no);
ut_ad(!lock_test);
#endif /* UNIV_DEBUG */
@@ -4182,8 +3894,8 @@ lock_update_discard(
lock_mutex_enter();
- if (!lock_rec_get_first_on_page(lock_sys->rec_hash, block)
- && (!lock_rec_get_first_on_page(lock_sys->prdt_hash, block))) {
+ if (!lock_rec_get_first_on_page(lock_sys.rec_hash, block)
+ && (!lock_rec_get_first_on_page(lock_sys.prdt_hash, block))) {
/* No locks exist on page, nothing to do */
lock_mutex_exit();
@@ -4421,7 +4133,7 @@ lock_table_create(
ut_list_insert(table->locks, c_lock, lock, TableLockGetNode());
if (wsrep_debug) {
ib::info() << "table lock BF conflict for " <<
- c_lock->trx->id;
+ ib::hex(c_lock->trx->id);
ib::info() << " SQL: "
<< wsrep_thd_query(c_lock->trx->mysql_thd);
}
@@ -4457,7 +4169,7 @@ lock_table_create(
}
if (wsrep_debug) {
- ib::info() << "WSREP: c_lock canceled " << c_lock->trx->id;
+ ib::info() << "WSREP: c_lock canceled " << ib::hex(c_lock->trx->id);
ib::info() << " SQL: "
<< wsrep_thd_query(c_lock->trx->mysql_thd);
}
@@ -4719,7 +4431,7 @@ Checks if other transactions have an incompatible mode lock request in
the lock queue.
@return lock or NULL */
UNIV_INLINE
-const lock_t*
+lock_t*
lock_table_other_has_incompatible(
/*==============================*/
const trx_t* trx, /*!< in: transaction, or NULL if all
@@ -4730,7 +4442,7 @@ lock_table_other_has_incompatible(
const dict_table_t* table, /*!< in: table */
lock_mode mode) /*!< in: lock mode */
{
- const lock_t* lock;
+ lock_t* lock;
ut_ad(lock_mutex_own());
@@ -4779,7 +4491,7 @@ lock_table(
{
trx_t* trx;
dberr_t err;
- const lock_t* wait_for;
+ lock_t* wait_for;
ut_ad(table && thr);
@@ -4835,9 +4547,9 @@ lock_table(
mode: this trx may have to wait */
if (wait_for != NULL) {
- err = lock_table_enqueue_waiting((lock_t*)wait_for, mode | flags, table, thr);
+ err = lock_table_enqueue_waiting(wait_for, mode | flags, table, thr);
} else {
- lock_table_create(table, mode | flags, trx);
+ lock_table_create(wait_for, table, mode | flags, trx);
ut_a(!flags || mode == LOCK_S || mode == LOCK_X);
@@ -5114,7 +4826,7 @@ lock_rec_unlock(
lock_mutex_enter();
trx_mutex_enter(trx);
- first_lock = lock_rec_get_first(lock_sys->rec_hash, block, heap_no);
+ first_lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
/* Find the last lock with the same lock_mode and transaction
on the record. */
@@ -5163,7 +4875,7 @@ released:
}
}
} else {
- lock_grant_and_move_on_rec(lock_sys->rec_hash, first_lock, heap_no);
+ lock_grant_and_move_on_rec(lock_sys.rec_hash, first_lock, heap_no);
}
lock_mutex_exit();
@@ -5222,7 +4934,7 @@ lock_release(
{
lock_t* lock;
ulint count = 0;
- trx_id_t max_trx_id = trx_sys_get_max_trx_id();
+ trx_id_t max_trx_id = trx_sys.get_max_trx_id();
ut_ad(lock_mutex_own());
ut_ad(!trx_mutex_own(trx));
@@ -5329,195 +5041,6 @@ lock_trx_table_locks_remove(
ut_error;
}
-/*********************************************************************//**
-Removes locks of a transaction on a table to be dropped.
-If remove_also_table_sx_locks is TRUE then table-level S and X locks are
-also removed in addition to other table-level and record-level locks.
-No lock that is going to be removed is allowed to be a wait lock. */
-static
-void
-lock_remove_all_on_table_for_trx(
-/*=============================*/
- dict_table_t* table, /*!< in: table to be dropped */
- trx_t* trx, /*!< in: a transaction */
- ibool remove_also_table_sx_locks)/*!< in: also removes
- table S and X locks */
-{
- lock_t* lock;
- lock_t* prev_lock;
-
- ut_ad(lock_mutex_own());
-
- for (lock = UT_LIST_GET_LAST(trx->lock.trx_locks);
- lock != NULL;
- lock = prev_lock) {
-
- prev_lock = UT_LIST_GET_PREV(trx_locks, lock);
-
- if (lock_get_type_low(lock) == LOCK_REC
- && lock->index->table == table) {
- ut_a(!lock_get_wait(lock));
-
- lock_rec_discard(lock);
- } else if (lock_get_type_low(lock) & LOCK_TABLE
- && lock->un_member.tab_lock.table == table
- && (remove_also_table_sx_locks
- || !IS_LOCK_S_OR_X(lock))) {
-
- ut_a(!lock_get_wait(lock));
-
- lock_trx_table_locks_remove(lock);
- lock_table_remove_low(lock);
- }
- }
-}
-
-/*******************************************************************//**
-Remove any explicit record locks held by recovering transactions on
-the table.
-@return number of recovered transactions examined */
-static
-ulint
-lock_remove_recovered_trx_record_locks(
-/*===================================*/
- dict_table_t* table) /*!< in: check if there are any locks
- held on records in this table or on the
- table itself */
-{
- ut_a(table != NULL);
- ut_ad(lock_mutex_own());
-
- ulint n_recovered_trx = 0;
-
- mutex_enter(&trx_sys->mutex);
-
- for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
- trx != NULL;
- trx = UT_LIST_GET_NEXT(trx_list, trx)) {
-
- assert_trx_in_rw_list(trx);
-
- if (!trx->is_recovered) {
- continue;
- }
-
- /* Because we are holding the lock_sys->mutex,
- implicit locks cannot be converted to explicit ones
- while we are scanning the explicit locks. */
-
- lock_t* next_lock;
-
- for (lock_t* lock = UT_LIST_GET_FIRST(trx->lock.trx_locks);
- lock != NULL;
- lock = next_lock) {
-
- ut_a(lock->trx == trx);
-
- /* Recovered transactions can't wait on a lock. */
-
- ut_a(!lock_get_wait(lock));
-
- next_lock = UT_LIST_GET_NEXT(trx_locks, lock);
-
- switch (lock_get_type_low(lock)) {
- default:
- ut_error;
- case LOCK_TABLE:
- if (lock->un_member.tab_lock.table == table) {
- lock_trx_table_locks_remove(lock);
- lock_table_remove_low(lock);
- }
- break;
- case LOCK_REC:
- if (lock->index->table == table) {
- lock_rec_discard(lock);
- }
- }
- }
-
- ++n_recovered_trx;
- }
-
- mutex_exit(&trx_sys->mutex);
-
- return(n_recovered_trx);
-}
-
-/*********************************************************************//**
-Removes locks on a table to be dropped or truncated.
-If remove_also_table_sx_locks is TRUE then table-level S and X locks are
-also removed in addition to other table-level and record-level locks.
-No lock, that is going to be removed, is allowed to be a wait lock. */
-void
-lock_remove_all_on_table(
-/*=====================*/
- dict_table_t* table, /*!< in: table to be dropped
- or truncated */
- ibool remove_also_table_sx_locks)/*!< in: also removes
- table S and X locks */
-{
- lock_t* lock;
-
- lock_mutex_enter();
-
- for (lock = UT_LIST_GET_FIRST(table->locks);
- lock != NULL;
- /* No op */) {
-
- lock_t* prev_lock;
-
- prev_lock = UT_LIST_GET_PREV(un_member.tab_lock.locks, lock);
-
- /* If we should remove all locks (remove_also_table_sx_locks
- is TRUE), or if the lock is not table-level S or X lock,
- then check we are not going to remove a wait lock. */
- if (remove_also_table_sx_locks
- || !(lock_get_type(lock) == LOCK_TABLE
- && IS_LOCK_S_OR_X(lock))) {
-
- ut_a(!lock_get_wait(lock));
- }
-
- lock_remove_all_on_table_for_trx(
- table, lock->trx, remove_also_table_sx_locks);
-
- if (prev_lock == NULL) {
- if (lock == UT_LIST_GET_FIRST(table->locks)) {
- /* lock was not removed, pick its successor */
- lock = UT_LIST_GET_NEXT(
- un_member.tab_lock.locks, lock);
- } else {
- /* lock was removed, pick the first one */
- lock = UT_LIST_GET_FIRST(table->locks);
- }
- } else if (UT_LIST_GET_NEXT(un_member.tab_lock.locks,
- prev_lock) != lock) {
- /* If lock was removed by
- lock_remove_all_on_table_for_trx() then pick the
- successor of prev_lock ... */
- lock = UT_LIST_GET_NEXT(
- un_member.tab_lock.locks, prev_lock);
- } else {
- /* ... otherwise pick the successor of lock. */
- lock = UT_LIST_GET_NEXT(
- un_member.tab_lock.locks, lock);
- }
- }
-
- /* Note: Recovered transactions don't have table level IX or IS locks
- but can have implicit record locks that have been converted to explicit
- record locks. Such record locks cannot be freed by traversing the
- transaction lock list in dict_table_t (as above). */
-
- if (!lock_sys->rollback_complete
- && lock_remove_recovered_trx_record_locks(table) == 0) {
-
- lock_sys->rollback_complete = TRUE;
- }
-
- lock_mutex_exit();
-}
-
/*===================== VALIDATION AND DEBUGGING ====================*/
/** Print info of a table lock.
@@ -5675,11 +5198,11 @@ lock_get_n_rec_locks(void)
ut_ad(lock_mutex_own());
- for (i = 0; i < hash_get_n_cells(lock_sys->rec_hash); i++) {
+ for (i = 0; i < hash_get_n_cells(lock_sys.rec_hash); i++) {
const lock_t* lock;
for (lock = static_cast<const lock_t*>(
- HASH_GET_FIRST(lock_sys->rec_hash, i));
+ HASH_GET_FIRST(lock_sys.rec_hash, i));
lock != 0;
lock = static_cast<const lock_t*>(
HASH_GET_NEXT(hash, lock))) {
@@ -5728,19 +5251,19 @@ lock_print_info_summary(
"------------\n", file);
fprintf(file, "Trx id counter " TRX_ID_FMT "\n",
- trx_sys_get_max_trx_id());
+ trx_sys.get_max_trx_id());
fprintf(file,
"Purge done for trx's n:o < " TRX_ID_FMT
" undo n:o < " TRX_ID_FMT " state: ",
- purge_sys->iter.trx_no,
- purge_sys->iter.undo_no);
+ purge_sys.tail.trx_no(),
+ purge_sys.tail.undo_no);
/* Note: We are reading the state without the latch. One because it
will violate the latching order and two because we are merely querying
the state of the variable for display. */
- switch (purge_sys->state){
+ switch (purge_sys.state){
case PURGE_STATE_INIT:
/* Should never be in this state while the system is running. */
ut_error;
@@ -5756,7 +5279,7 @@ lock_print_info_summary(
case PURGE_STATE_RUN:
fprintf(file, "running");
/* Check if it is waiting for more data to arrive. */
- if (!purge_sys->running) {
+ if (!purge_sys.running) {
fprintf(file, " but idle");
}
break;
@@ -5769,8 +5292,7 @@ lock_print_info_summary(
fprintf(file, "\n");
fprintf(file,
- "History list length %lu\n",
- (ulong) trx_sys->rseg_history_len);
+ "History list length " ULINTPF "\n", trx_sys.history_size());
#ifdef PRINT_NUM_OF_LOCK_STRUCTS
fprintf(file,
@@ -5789,7 +5311,7 @@ struct PrintNotStarted {
void operator()(const trx_t* trx)
{
ut_ad(trx->in_mysql_trx_list);
- ut_ad(mutex_own(&trx_sys->mutex));
+ ut_ad(mutex_own(&trx_sys.mutex));
/* See state transitions and locking rules in trx0trx.h */
@@ -5803,116 +5325,6 @@ struct PrintNotStarted {
FILE* m_file;
};
-/** Iterate over a transaction's locks. Keeping track of the
-iterator using an ordinal value. */
-
-class TrxLockIterator {
-public:
- TrxLockIterator() { rewind(); }
-
- /** Get the m_index(th) lock of a transaction.
- @return current lock or 0 */
- const lock_t* current(const trx_t* trx) const
- {
- lock_t* lock;
- ulint i = 0;
-
- for (lock = UT_LIST_GET_FIRST(trx->lock.trx_locks);
- lock != NULL && i < m_index;
- lock = UT_LIST_GET_NEXT(trx_locks, lock), ++i) {
-
- /* No op */
- }
-
- return(lock);
- }
-
- /** Set the ordinal value to 0 */
- void rewind()
- {
- m_index = 0;
- }
-
- /** Increment the ordinal value.
- @retun the current index value */
- ulint next()
- {
- return(++m_index);
- }
-
-private:
- /** Current iterator position */
- ulint m_index;
-};
-
-/** This iterates over both the RW and RO trx_sys lists. We need to keep
-track where the iterator was up to and we do that using an ordinal value. */
-
-class TrxListIterator {
-public:
- TrxListIterator() : m_index()
- {
- /* We iterate over the RW trx list first. */
-
- m_trx_list = &trx_sys->rw_trx_list;
- }
-
- /** Get the current transaction whose ordinality is m_index.
- @return current transaction or 0 */
-
- const trx_t* current()
- {
- return(reposition());
- }
-
- /** Advance the transaction current ordinal value and reset the
- transaction lock ordinal value */
-
- void next()
- {
- ++m_index;
- m_lock_iter.rewind();
- }
-
- TrxLockIterator& lock_iter()
- {
- return(m_lock_iter);
- }
-
-private:
- /** Reposition the "cursor" on the current transaction. If it
- is the first time then the "cursor" will be positioned on the
- first transaction.
-
- @return transaction instance or 0 */
- const trx_t* reposition() const
- {
- ulint i;
- trx_t* trx;
-
- /* Make the transaction at the ordinal value of m_index
- the current transaction. ie. reposition/restore */
-
- for (i = 0, trx = UT_LIST_GET_FIRST(*m_trx_list);
- trx != NULL && (i < m_index);
- trx = UT_LIST_GET_NEXT(trx_list, trx), ++i) {
-
- check_trx_state(trx);
- }
-
- return(trx);
- }
-
- /** Ordinal value of the transaction in the current transaction list */
- ulint m_index;
-
- /** Current transaction list */
- trx_ut_list_t* m_trx_list;
-
- /** For iterating over a transaction's locks */
- TrxLockIterator m_lock_iter;
-};
-
/** Prints transaction lock wait and MVCC state.
@param[in,out] file file where to print
@param[in] trx transaction */
@@ -5925,10 +5337,13 @@ lock_trx_print_wait_and_mvcc_state(
trx_print_latched(file, trx, 600);
- const ReadView* read_view = trx_get_read_view(trx);
+ /* Note: read_view->get_state() check is race condition. But it
+ should "kind of work" because read_view is freed only at shutdown.
+ Worst thing that may happen is that it'll get transferred to
+ another thread and print wrong values. */
- if (read_view != NULL) {
- read_view->print_limits(file);
+ if (trx->read_view.get_state() == READ_VIEW_STATE_OPEN) {
+ trx->read_view.print_limits(file);
}
if (trx->lock.que_state == TRX_QUE_LOCK_WAIT) {
@@ -5949,119 +5364,29 @@ lock_trx_print_wait_and_mvcc_state(
}
/*********************************************************************//**
-Prints info of locks for a transaction. This function will release the
-lock mutex and the trx_sys_t::mutex if the page was read from disk.
-@return true if page was read from the tablespace */
-static
-bool
-lock_rec_fetch_page(
-/*================*/
- const lock_t* lock) /*!< in: record lock */
-{
- ut_ad(lock_get_type_low(lock) == LOCK_REC);
-
- ulint space_id = lock->un_member.rec_lock.space;
- fil_space_t* space;
- bool found;
- const page_size_t& page_size = fil_space_get_page_size(space_id,
- &found);
- ulint page_no = lock->un_member.rec_lock.page_no;
-
- /* Check if the .ibd file exists. */
- if (found) {
- mtr_t mtr;
-
- lock_mutex_exit();
-
- mutex_exit(&trx_sys->mutex);
-
- DEBUG_SYNC_C("innodb_monitor_before_lock_page_read");
-
- /* Check if the space is exists or not. only
- when the space is valid, try to get the page. */
- space = fil_space_acquire(space_id);
- if (space) {
- dberr_t err = DB_SUCCESS;
- mtr_start(&mtr);
- buf_page_get_gen(
- page_id_t(space_id, page_no), page_size,
- RW_NO_LATCH, NULL,
- BUF_GET_POSSIBLY_FREED,
- __FILE__, __LINE__, &mtr, &err);
- mtr_commit(&mtr);
- fil_space_release(space);
- }
-
- lock_mutex_enter();
-
- mutex_enter(&trx_sys->mutex);
-
- return(true);
- }
-
- return(false);
-}
-
-/*********************************************************************//**
-Prints info of locks for a transaction.
-@return true if all printed, false if latches were released. */
+Prints info of locks for a transaction. */
static
-bool
+void
lock_trx_print_locks(
/*=================*/
FILE* file, /*!< in/out: File to write */
- const trx_t* trx, /*!< in: current transaction */
- TrxLockIterator&iter, /*!< in: transaction lock iterator */
- bool load_block) /*!< in: if true then read block
- from disk */
+ const trx_t* trx) /*!< in: current transaction */
{
- const lock_t* lock;
-
+ uint32_t i= 0;
/* Iterate over the transaction's locks. */
- while ((lock = iter.current(trx)) != 0) {
-
+ for (lock_t *lock = UT_LIST_GET_FIRST(trx->lock.trx_locks);
+ lock != NULL;
+ lock = UT_LIST_GET_NEXT(trx_locks, lock)) {
if (lock_get_type_low(lock) == LOCK_REC) {
- if (load_block) {
-
- /* Note: lock_rec_fetch_page() will
- release both the lock mutex and the
- trx_sys_t::mutex if it does a read
- from disk. */
-
- if (lock_rec_fetch_page(lock)) {
- /* We need to resync the
- current transaction. */
- return(false);
- }
-
- /* It is a single table tablespace
- and the .ibd file is missing
- (TRUNCATE TABLE probably stole the
- locks): just print the lock without
- attempting to load the page in the
- buffer pool. */
-
- fprintf(file,
- "RECORD LOCKS on non-existing"
- " space %u\n",
- lock->un_member.rec_lock.space);
- }
-
- /* Print all the record locks on the page from
- the record lock bitmap */
-
lock_rec_print(file, lock);
-
- load_block = true;
-
} else {
ut_ad(lock_get_type_low(lock) & LOCK_TABLE);
lock_table_print(file, lock);
}
- if (iter.next() >= 10) {
+ if (++i == 10) {
fprintf(file,
"10 LOCKS PRINTED FOR THIS TRX:"
@@ -6070,10 +5395,32 @@ lock_trx_print_locks(
break;
}
}
+}
- return(true);
+
+static my_bool lock_print_info_all_transactions_callback(
+ rw_trx_hash_element_t *element, FILE *file)
+{
+ mutex_enter(&element->mutex);
+ if (trx_t *trx= element->trx)
+ {
+ check_trx_state(trx);
+ lock_trx_print_wait_and_mvcc_state(file, trx);
+
+ if (srv_print_innodb_lock_monitor)
+ {
+ trx->reference();
+ mutex_exit(&element->mutex);
+ lock_trx_print_locks(file, trx);
+ trx->release_reference();
+ return 0;
+ }
+ }
+ mutex_exit(&element->mutex);
+ return 0;
}
+
/*********************************************************************//**
Prints info of locks for each transaction. This function assumes that the
caller holds the lock mutex and more importantly it will release the lock
@@ -6087,8 +5434,6 @@ lock_print_info_all_transactions(
fprintf(file, "LIST OF TRANSACTIONS FOR EACH SESSION:\n");
- mutex_enter(&trx_sys->mutex);
-
/* First print info on non-active transactions */
/* NOTE: information of auto-commit non-locking read-only
@@ -6096,62 +5441,14 @@ lock_print_info_all_transactions(
available from INFORMATION_SCHEMA.INNODB_TRX. */
PrintNotStarted print_not_started(file);
- ut_list_map(trx_sys->mysql_trx_list, print_not_started);
-
- const trx_t* trx;
- TrxListIterator trx_iter;
- const trx_t* prev_trx = 0;
-
- /* Control whether a block should be fetched from the buffer pool. */
- bool load_block = true;
- bool monitor = srv_print_innodb_lock_monitor;
-
- while ((trx = trx_iter.current()) != 0) {
-
- check_trx_state(trx);
-
- if (trx != prev_trx) {
- lock_trx_print_wait_and_mvcc_state(file, trx);
- prev_trx = trx;
-
- /* The transaction that read in the page is no
- longer the one that read the page in. We need to
- force a page read. */
- load_block = true;
- }
-
- /* If we need to print the locked record contents then we
- need to fetch the containing block from the buffer pool. */
- if (monitor) {
-
- /* Print the locks owned by the current transaction. */
- TrxLockIterator& lock_iter = trx_iter.lock_iter();
-
- if (!lock_trx_print_locks(
- file, trx, lock_iter, load_block)) {
-
- /* Resync trx_iter, the trx_sys->mutex and
- the lock mutex were released. A page was
- successfully read in. We need to print its
- contents on the next call to
- lock_trx_print_locks(). On the next call to
- lock_trx_print_locks() we should simply print
- the contents of the page just read in.*/
- load_block = false;
-
- continue;
- }
- }
-
- load_block = true;
-
- /* All record lock details were printed without fetching
- a page from disk, or we didn't need to print the detail. */
- trx_iter.next();
- }
+ mutex_enter(&trx_sys.mutex);
+ ut_list_map(trx_sys.mysql_trx_list, print_not_started);
+ mutex_exit(&trx_sys.mutex);
+ trx_sys.rw_trx_hash.iterate_no_dups(
+ reinterpret_cast<my_hash_walk_action>
+ (lock_print_info_all_transactions_callback), file);
lock_mutex_exit();
- mutex_exit(&trx_sys->mutex);
ut_ad(lock_validate());
}
@@ -6212,16 +5509,16 @@ lock_table_queue_validate(
const lock_t* lock;
ut_ad(lock_mutex_own());
- ut_ad(trx_sys_mutex_own());
+ ut_ad(mutex_own(&trx_sys.mutex));
for (lock = UT_LIST_GET_FIRST(table->locks);
lock != NULL;
lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock)) {
/* lock->trx->state cannot change from or to NOT_STARTED
- while we are holding the trx_sys->mutex. It may change
+ while we are holding the trx_sys.mutex. It may change
from ACTIVE to PREPARED, but it may not change to
- COMMITTED, because we are holding the lock_sys->mutex. */
+ COMMITTED, because we are holding the lock_sys.mutex. */
ut_ad(trx_assert_started(lock->trx));
if (!lock_get_wait(lock)) {
@@ -6244,10 +5541,10 @@ lock_table_queue_validate(
Validates the lock queue on a single record.
@return TRUE if ok */
static
-ibool
+bool
lock_rec_queue_validate(
/*====================*/
- ibool locked_lock_trx_sys,
+ bool locked_lock_trx_sys,
/*!< in: if the caller holds
both the lock mutex and
trx_sys_t->lock. */
@@ -6256,7 +5553,6 @@ lock_rec_queue_validate(
const dict_index_t* index, /*!< in: index, or NULL if not known */
const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
- const trx_t* impl_trx;
const lock_t* lock;
ulint heap_no;
@@ -6273,12 +5569,12 @@ lock_rec_queue_validate(
if (!locked_lock_trx_sys) {
lock_mutex_enter();
- mutex_enter(&trx_sys->mutex);
+ mutex_enter(&trx_sys.mutex);
}
if (!page_rec_is_user_rec(rec)) {
- for (lock = lock_rec_get_first(lock_sys->rec_hash,
+ for (lock = lock_rec_get_first(lock_sys.rec_hash,
block, heap_no);
lock != NULL;
lock = lock_rec_get_next_const(heap_no, lock)) {
@@ -6302,17 +5598,15 @@ lock_rec_queue_validate(
/* Nothing we can do */
} else if (dict_index_is_clust(index)) {
- trx_id_t trx_id;
-
/* Unlike the non-debug code, this invariant can only succeed
if the check and assertion are covered by the lock mutex. */
- trx_id = lock_clust_rec_some_has_impl(rec, index, offsets);
- impl_trx = trx_rw_is_active_low(trx_id, NULL);
+ const trx_t *impl_trx = trx_sys.rw_trx_hash.find(current_trx(),
+ lock_clust_rec_some_has_impl(rec, index, offsets));
ut_ad(lock_mutex_own());
/* impl_trx cannot be committed until lock_mutex_exit()
- because lock_trx_release_locks() acquires lock_sys->mutex */
+ because lock_trx_release_locks() acquires lock_sys.mutex */
if (impl_trx != NULL) {
const lock_t* other_lock
@@ -6362,7 +5656,7 @@ lock_rec_queue_validate(
}
}
- for (lock = lock_rec_get_first(lock_sys->rec_hash, block, heap_no);
+ for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
lock != NULL;
lock = lock_rec_get_next_const(heap_no, lock)) {
@@ -6407,7 +5701,7 @@ lock_rec_queue_validate(
func_exit:
if (!locked_lock_trx_sys) {
lock_mutex_exit();
- mutex_exit(&trx_sys->mutex);
+ mutex_exit(&trx_sys.mutex);
}
return(TRUE);
@@ -6435,10 +5729,10 @@ lock_rec_validate_page(
ut_ad(!lock_mutex_own());
lock_mutex_enter();
- mutex_enter(&trx_sys->mutex);
+ mutex_enter(&trx_sys.mutex);
loop:
lock = lock_rec_get_first_on_page_addr(
- lock_sys->rec_hash,
+ lock_sys.rec_hash,
block->page.id.space(), block->page.id.page_no());
if (!lock) {
@@ -6458,13 +5752,9 @@ loop:
ut_ad(!trx_is_ac_nl_ro(lock->trx));
-# ifdef UNIV_DEBUG
/* Only validate the record queues when this thread is not
- holding a space->latch. Deadlocks are possible due to
- latching order violation when UNIV_DEBUG is defined while
- UNIV_DEBUG is not. */
+ holding a space->latch. */
if (!sync_check_find(SYNC_FSP))
-# endif /* UNIV_DEBUG */
for (i = nth_bit; i < lock_rec_get_n_bits(lock); i++) {
if (i == 1 || lock_rec_get_nth_bit(lock, i)) {
@@ -6497,7 +5787,7 @@ loop:
function_exit:
lock_mutex_exit();
- mutex_exit(&trx_sys->mutex);
+ mutex_exit(&trx_sys.mutex);
if (heap != NULL) {
mem_heap_free(heap);
@@ -6506,61 +5796,22 @@ function_exit:
}
/*********************************************************************//**
-Validates the table locks.
-@return TRUE if ok */
-static
-ibool
-lock_validate_table_locks(
-/*======================*/
- const trx_ut_list_t* trx_list) /*!< in: trx list */
-{
- const trx_t* trx;
-
- ut_ad(lock_mutex_own());
- ut_ad(trx_sys_mutex_own());
-
- ut_ad(trx_list == &trx_sys->rw_trx_list);
-
- for (trx = UT_LIST_GET_FIRST(*trx_list);
- trx != NULL;
- trx = UT_LIST_GET_NEXT(trx_list, trx)) {
-
- const lock_t* lock;
-
- check_trx_state(trx);
-
- for (lock = UT_LIST_GET_FIRST(trx->lock.trx_locks);
- lock != NULL;
- lock = UT_LIST_GET_NEXT(trx_locks, lock)) {
-
- if (lock_get_type_low(lock) & LOCK_TABLE) {
-
- lock_table_queue_validate(
- lock->un_member.tab_lock.table);
- }
- }
- }
-
- return(TRUE);
-}
-
-/*********************************************************************//**
Validate record locks up to a limit.
@return lock at limit or NULL if no more locks in the hash bucket */
static MY_ATTRIBUTE((warn_unused_result))
const lock_t*
lock_rec_validate(
/*==============*/
- ulint start, /*!< in: lock_sys->rec_hash
+ ulint start, /*!< in: lock_sys.rec_hash
bucket */
ib_uint64_t* limit) /*!< in/out: upper limit of
(space, page_no) */
{
ut_ad(lock_mutex_own());
- ut_ad(trx_sys_mutex_own());
+ ut_ad(mutex_own(&trx_sys.mutex));
for (const lock_t* lock = static_cast<const lock_t*>(
- HASH_GET_FIRST(lock_sys->rec_hash, start));
+ HASH_GET_FIRST(lock_sys.rec_hash, start));
lock != NULL;
lock = static_cast<const lock_t*>(HASH_GET_NEXT(hash, lock))) {
@@ -6599,8 +5850,11 @@ lock_rec_block_validate(
buf_block_t* block;
mtr_t mtr;
- /* Make sure that the tablespace is not deleted while we are
- trying to access the page. */
+ /* Transactional locks should never refer to dropped
+ tablespaces, because all DDL operations that would drop or
+ 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(space_id)) {
dberr_t err = DB_SUCCESS;
mtr_start(&mtr);
@@ -6631,6 +5885,29 @@ lock_rec_block_validate(
}
}
+
+static my_bool lock_validate_table_locks(rw_trx_hash_element_t *element,
+ void *arg)
+{
+ ut_ad(lock_mutex_own());
+ ut_ad(mutex_own(&trx_sys.mutex)); /* Do we really need this. */
+ mutex_enter(&element->mutex);
+ if (element->trx)
+ {
+ check_trx_state(element->trx);
+ for (const lock_t *lock= UT_LIST_GET_FIRST(element->trx->lock.trx_locks);
+ lock != NULL;
+ lock= UT_LIST_GET_NEXT(trx_locks, lock))
+ {
+ if (lock_get_type_low(lock) & LOCK_TABLE)
+ lock_table_queue_validate(lock->un_member.tab_lock.table);
+ }
+ }
+ mutex_exit(&element->mutex);
+ return 0;
+}
+
+
/*********************************************************************//**
Validates the lock system.
@return TRUE if ok */
@@ -6648,15 +5925,17 @@ lock_validate()
page_addr_set pages;
lock_mutex_enter();
- mutex_enter(&trx_sys->mutex);
+ mutex_enter(&trx_sys.mutex);
- ut_a(lock_validate_table_locks(&trx_sys->rw_trx_list));
+ /* Validate table locks */
+ trx_sys.rw_trx_hash.iterate(reinterpret_cast<my_hash_walk_action>
+ (lock_validate_table_locks), 0);
/* Iterate over all the record locks and validate the locks. We
don't want to hog the lock_sys_t::mutex and the trx_sys_t::mutex.
Release both mutexes during the validation check. */
- for (ulint i = 0; i < hash_get_n_cells(lock_sys->rec_hash); i++) {
+ for (ulint i = 0; i < hash_get_n_cells(lock_sys.rec_hash); i++) {
ib_uint64_t limit = 0;
while (const lock_t* lock = lock_rec_validate(i, &limit)) {
@@ -6669,7 +5948,7 @@ lock_validate()
}
}
- mutex_exit(&trx_sys->mutex);
+ mutex_exit(&trx_sys.mutex);
lock_mutex_exit();
for (page_addr_set::const_iterator it = pages.begin();
@@ -6700,7 +5979,7 @@ lock_rec_insert_check_and_lock(
dict_index_t* index, /*!< in: index */
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr, /*!< in/out: mini-transaction */
- ibool* inherit)/*!< out: set to TRUE if the new
+ bool* inherit)/*!< out: set to true if the new
inserted record maybe should inherit
LOCK_GAP type locks from the successor
record */
@@ -6721,7 +6000,7 @@ lock_rec_insert_check_and_lock(
dberr_t err;
lock_t* lock;
- ibool inherit_in = *inherit;
+ bool inherit_in = *inherit;
trx_t* trx = thr_get_trx(thr);
const rec_t* next_rec = page_rec_get_next_const(rec);
ulint heap_no = page_rec_get_heap_no(next_rec);
@@ -6737,7 +6016,7 @@ lock_rec_insert_check_and_lock(
BTR_NO_LOCKING_FLAG and skip the locking altogether. */
ut_ad(lock_table_has(trx, index->table, LOCK_IX));
- lock = lock_rec_get_first(lock_sys->rec_hash, block, heap_no);
+ lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
if (lock == NULL) {
/* We optimize CPU time usage in the simplest case */
@@ -6751,7 +6030,7 @@ lock_rec_insert_check_and_lock(
trx->id, mtr);
}
- *inherit = FALSE;
+ *inherit = false;
return(DB_SUCCESS);
}
@@ -6762,7 +6041,7 @@ lock_rec_insert_check_and_lock(
return(DB_SUCCESS);
}
- *inherit = TRUE;
+ *inherit = true;
/* If another transaction has an explicit lock request which locks
the gap, waiting or granted, on the successor, the insert has to wait.
@@ -6776,7 +6055,7 @@ lock_rec_insert_check_and_lock(
const ulint type_mode = LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION;
- const lock_t* wait_for = lock_rec_other_has_conflicting(
+ lock_t* wait_for = lock_rec_other_has_conflicting(
type_mode, block, heap_no, trx);
if (wait_for != NULL) {
@@ -6850,7 +6129,7 @@ lock_rec_convert_impl_to_expl_for_trx(
trx_t* trx, /*!< in/out: active transaction */
ulint heap_no)/*!< in: rec heap number to lock */
{
- ut_ad(trx_is_referenced(trx));
+ ut_ad(trx->is_referenced());
ut_ad(page_rec_is_leaf(rec));
ut_ad(!rec_is_default_row(rec, index));
@@ -6874,11 +6153,75 @@ lock_rec_convert_impl_to_expl_for_trx(
lock_mutex_exit();
- trx_release_reference(trx);
+ trx->release_reference();
DEBUG_SYNC_C("after_lock_rec_convert_impl_to_expl_for_trx");
}
+
+#ifdef UNIV_DEBUG
+struct lock_rec_other_trx_holds_expl_arg
+{
+ const ulint heap_no;
+ const buf_block_t * const block;
+ const trx_t *impl_trx;
+};
+
+
+static my_bool lock_rec_other_trx_holds_expl_callback(
+ rw_trx_hash_element_t *element,
+ lock_rec_other_trx_holds_expl_arg *arg)
+{
+ mutex_enter(&element->mutex);
+ if (element->trx)
+ {
+ lock_t *expl_lock= lock_rec_has_expl(LOCK_S | LOCK_REC_NOT_GAP, arg->block,
+ arg->heap_no, element->trx);
+ /*
+ An explicit lock is held by trx other than the trx holding the implicit
+ lock.
+ */
+ ut_ad(!expl_lock || expl_lock->trx == arg->impl_trx);
+ }
+ mutex_exit(&element->mutex);
+ return 0;
+}
+
+
+/**
+ Checks if some transaction, other than given trx_id, has an explicit
+ lock on the given rec.
+
+ FIXME: if the current transaction holds implicit lock from INSERT, a
+ subsequent locking read should not convert it to explicit. See also
+ MDEV-11215.
+
+ @param caller_trx trx of current thread
+ @param[in] trx trx holding implicit lock on rec
+ @param[in] rec user record
+ @param[in] block buffer block containing the record
+*/
+
+static void lock_rec_other_trx_holds_expl(trx_t *caller_trx, trx_t *trx,
+ const rec_t *rec,
+ const buf_block_t *block)
+{
+ if (trx)
+ {
+ ut_ad(!page_rec_is_default_row(rec));
+ lock_mutex_enter();
+ lock_rec_other_trx_holds_expl_arg arg= { page_rec_get_heap_no(rec), block,
+ trx };
+ trx_sys.rw_trx_hash.iterate(caller_trx,
+ reinterpret_cast<my_hash_walk_action>
+ (lock_rec_other_trx_holds_expl_callback),
+ &arg);
+ lock_mutex_exit();
+ }
+}
+#endif /* UNIV_DEBUG */
+
+
/*********************************************************************//**
If a transaction has an implicit x-lock on a record, but no explicit x-lock
set on the record, sets one for it. */
@@ -6886,6 +6229,7 @@ static
void
lock_rec_convert_impl_to_expl(
/*==========================*/
+ trx_t* caller_trx,/*!<in/out: trx of current thread */
const buf_block_t* block, /*!< in: buffer block of rec */
const rec_t* rec, /*!< in: user record on page */
dict_index_t* index, /*!< in: index of record */
@@ -6905,20 +6249,21 @@ lock_rec_convert_impl_to_expl(
trx_id = lock_clust_rec_some_has_impl(rec, index, offsets);
- trx = trx_rw_is_active(trx_id, NULL, true);
+ trx = trx_sys.find(caller_trx, trx_id);
} else {
ut_ad(!dict_index_is_online_ddl(index));
- trx = lock_sec_rec_some_has_impl(rec, index, offsets);
+ trx = lock_sec_rec_some_has_impl(caller_trx, rec, index,
+ offsets);
- ut_ad(!trx || !lock_rec_other_trx_holds_expl(
- LOCK_S | LOCK_REC_NOT_GAP, trx, rec, block));
+ ut_d(lock_rec_other_trx_holds_expl(caller_trx, trx, rec,
+ block));
}
if (trx != 0) {
ulint heap_no = page_rec_get_heap_no(rec);
- ut_ad(trx_is_referenced(trx));
+ ut_ad(trx->is_referenced());
/* If the transaction is still active and has no
explicit x-lock set on the record, set one for it.
@@ -6971,19 +6316,12 @@ lock_clust_rec_modify_check_and_lock(
/* If a transaction has no explicit x-lock set on the record, set one
for it */
- lock_rec_convert_impl_to_expl(block, rec, index, offsets);
-
- lock_mutex_enter();
-
- ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
+ lock_rec_convert_impl_to_expl(thr_get_trx(thr), block, rec, index,
+ offsets);
err = lock_rec_lock(TRUE, LOCK_X | LOCK_REC_NOT_GAP,
block, heap_no, index, thr);
- MONITOR_INC(MONITOR_NUM_RECLOCK_REQ);
-
- lock_mutex_exit();
-
ut_ad(lock_rec_queue_validate(FALSE, block, rec, index, offsets));
if (err == DB_SUCCESS_LOCKED_REC) {
@@ -7036,17 +6374,9 @@ lock_sec_rec_modify_check_and_lock(
index record, and this would not have been possible if another active
transaction had modified this secondary index record. */
- lock_mutex_enter();
-
- ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
-
err = lock_rec_lock(TRUE, LOCK_X | LOCK_REC_NOT_GAP,
block, heap_no, index, thr);
- MONITOR_INC(MONITOR_NUM_RECLOCK_REQ);
-
- lock_mutex_exit();
-
#ifdef UNIV_DEBUG
{
mem_heap_t* heap = NULL;
@@ -7131,27 +6461,16 @@ lock_sec_rec_read_check_and_lock(
if the max trx id for the page >= min trx id for the trx list or a
database recovery is running. */
- if ((page_get_max_trx_id(block->frame) >= trx_rw_min_trx_id()
- || recv_recovery_is_on())
- && !page_rec_is_supremum(rec)) {
+ if (!page_rec_is_supremum(rec)
+ && page_get_max_trx_id(block->frame) >= trx_sys.get_min_trx_id()) {
- lock_rec_convert_impl_to_expl(block, rec, index, offsets);
+ lock_rec_convert_impl_to_expl(thr_get_trx(thr), block, rec,
+ index, offsets);
}
- lock_mutex_enter();
-
- ut_ad(mode != LOCK_X
- || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
- ut_ad(mode != LOCK_S
- || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS));
-
err = lock_rec_lock(FALSE, mode | gap_mode,
block, heap_no, index, thr);
- MONITOR_INC(MONITOR_NUM_RECLOCK_REQ);
-
- lock_mutex_exit();
-
ut_ad(lock_rec_queue_validate(FALSE, block, rec, index, offsets));
return(err);
@@ -7210,22 +6529,12 @@ lock_clust_rec_read_check_and_lock(
if (heap_no != PAGE_HEAP_NO_SUPREMUM) {
- lock_rec_convert_impl_to_expl(block, rec, index, offsets);
+ lock_rec_convert_impl_to_expl(thr_get_trx(thr), block, rec,
+ index, offsets);
}
- lock_mutex_enter();
-
- ut_ad(mode != LOCK_X
- || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
- ut_ad(mode != LOCK_S
- || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS));
-
err = lock_rec_lock(FALSE, mode | gap_mode, block, heap_no, index, thr);
- MONITOR_INC(MONITOR_NUM_RECLOCK_REQ);
-
- lock_mutex_exit();
-
ut_ad(lock_rec_queue_validate(FALSE, block, rec, index, offsets));
DEBUG_SYNC_C("after_lock_clust_rec_read_check_and_lock");
@@ -7637,38 +6946,19 @@ lock_trx_release_locks(
trx_t* trx) /*!< in/out: transaction */
{
check_trx_state(trx);
+ ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED)
+ || trx_state_eq(trx, TRX_STATE_ACTIVE));
- if (trx_state_eq(trx, TRX_STATE_PREPARED)) {
-
- mutex_enter(&trx_sys->mutex);
-
- ut_a(trx_sys->n_prepared_trx > 0);
- --trx_sys->n_prepared_trx;
-
- if (trx->is_recovered) {
- ut_a(trx_sys->n_prepared_recovered_trx > 0);
- trx_sys->n_prepared_recovered_trx--;
- }
-
- mutex_exit(&trx_sys->mutex);
- } else {
- ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
- }
-
- bool release_lock;
-
- release_lock = (UT_LIST_GET_LEN(trx->lock.trx_locks) > 0);
+ bool release_lock = UT_LIST_GET_LEN(trx->lock.trx_locks) > 0;
- /* Don't take lock_sys mutex if trx didn't acquire any lock. */
+ /* Don't take lock_sys.mutex if trx didn't acquire any lock. */
if (release_lock) {
/* The transition of trx->state to TRX_STATE_COMMITTED_IN_MEMORY
- is protected by both the lock_sys->mutex and the trx->mutex. */
+ is protected by both the lock_sys.mutex and the trx->mutex. */
lock_mutex_enter();
}
- trx_mutex_enter(trx);
-
/* The following assignment makes the transaction committed in memory
and makes its changes to data visible to other transactions.
NOTE that there is a small discrepancy from the strict formal
@@ -7684,51 +6974,30 @@ lock_trx_release_locks(
committed. */
/*--------------------------------------*/
+ trx_mutex_enter(trx);
trx->state = TRX_STATE_COMMITTED_IN_MEMORY;
+ trx_mutex_exit(trx);
/*--------------------------------------*/
- if (trx_is_referenced(trx)) {
+ if (trx->is_referenced()) {
ut_a(release_lock);
lock_mutex_exit();
- while (trx_is_referenced(trx)) {
-
- trx_mutex_exit(trx);
+ while (trx->is_referenced()) {
DEBUG_SYNC_C("waiting_trx_is_not_referenced");
/** Doing an implicit to explicit conversion
should not be expensive. */
- ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
-
- trx_mutex_enter(trx);
+ ut_delay(srv_spin_wait_delay);
}
- trx_mutex_exit(trx);
-
lock_mutex_enter();
-
- trx_mutex_enter(trx);
}
- ut_ad(!trx_is_referenced(trx));
-
- /* If the background thread trx_rollback_or_clean_recovered()
- is still active then there is a chance that the rollback
- thread may see this trx as COMMITTED_IN_MEMORY and goes ahead
- to clean it up calling trx_cleanup_at_db_startup(). This can
- happen in the case we are committing a trx here that is left
- in PREPARED state during the crash. Note that commit of the
- rollback of a PREPARED trx happens in the recovery thread
- while the rollback of other transactions happen in the
- background thread. To avoid this race we unconditionally unset
- the is_recovered flag. */
-
- trx->is_recovered = false;
-
- trx_mutex_exit(trx);
+ ut_ad(!trx->is_referenced());
if (release_lock) {
@@ -7847,52 +7116,38 @@ lock_table_get_n_locks(
}
#ifdef UNIV_DEBUG
-/*******************************************************************//**
-Do an exhaustive check for any locks (table or rec) against the table.
-@return lock if found */
-static
-const lock_t*
-lock_table_locks_lookup(
-/*====================*/
- const dict_table_t* table, /*!< in: check if there are
- any locks held on records in
- this table or on the table
- itself */
- const trx_ut_list_t* trx_list) /*!< in: trx list to check */
-{
- trx_t* trx;
-
- ut_a(table != NULL);
- ut_ad(lock_mutex_own());
- ut_ad(trx_sys_mutex_own());
-
- for (trx = UT_LIST_GET_FIRST(*trx_list);
- trx != NULL;
- trx = UT_LIST_GET_NEXT(trx_list, trx)) {
-
- const lock_t* lock;
-
- check_trx_state(trx);
-
- for (lock = UT_LIST_GET_FIRST(trx->lock.trx_locks);
- lock != NULL;
- lock = UT_LIST_GET_NEXT(trx_locks, lock)) {
-
- ut_a(lock->trx == trx);
-
- if (lock_get_type_low(lock) == LOCK_REC) {
- ut_ad(!dict_index_is_online_ddl(lock->index)
- || dict_index_is_clust(lock->index));
- if (lock->index->table == table) {
- return(lock);
- }
- } else if (lock->un_member.tab_lock.table == table) {
- return(lock);
- }
- }
- }
-
- return(NULL);
+/**
+ Do an exhaustive check for any locks (table or rec) against the table.
+
+ @param[in] table check if there are any locks held on records in this table
+ or on the table itself
+*/
+
+static my_bool lock_table_locks_lookup(rw_trx_hash_element_t *element,
+ const dict_table_t *table)
+{
+ ut_ad(lock_mutex_own());
+ mutex_enter(&element->mutex);
+ if (element->trx)
+ {
+ check_trx_state(element->trx);
+ for (const lock_t *lock= UT_LIST_GET_FIRST(element->trx->lock.trx_locks);
+ lock != NULL;
+ lock= UT_LIST_GET_NEXT(trx_locks, lock))
+ {
+ ut_ad(lock->trx == element->trx);
+ if (lock_get_type_low(lock) == LOCK_REC)
+ {
+ ut_ad(!dict_index_is_online_ddl(lock->index) ||
+ dict_index_is_clust(lock->index));
+ ut_ad(lock->index->table != table);
+ }
+ else
+ ut_ad(lock->un_member.tab_lock.table != table);
+ }
+ }
+ mutex_exit(&element->mutex);
+ return 0;
}
#endif /* UNIV_DEBUG */
@@ -7908,17 +7163,17 @@ lock_table_has_locks(
{
ibool has_locks;
+ ut_ad(table != NULL);
lock_mutex_enter();
has_locks = UT_LIST_GET_LEN(table->locks) > 0 || table->n_rec_locks > 0;
#ifdef UNIV_DEBUG
if (!has_locks) {
- mutex_enter(&trx_sys->mutex);
-
- ut_ad(!lock_table_locks_lookup(table, &trx_sys->rw_trx_list));
-
- mutex_exit(&trx_sys->mutex);
+ trx_sys.rw_trx_hash.iterate(
+ reinterpret_cast<my_hash_walk_action>
+ (lock_table_locks_lookup),
+ const_cast<dict_table_t*>(table));
}
#endif /* UNIV_DEBUG */
@@ -7953,7 +7208,7 @@ void
lock_set_timeout_event()
/*====================*/
{
- os_event_set(lock_sys->timeout_event);
+ os_event_set(lock_sys.timeout_event);
}
#ifdef UNIV_DEBUG
@@ -8087,8 +7342,6 @@ DeadlockChecker::print(const trx_t* trx, ulint max_query_len)
ulint n_trx_locks = UT_LIST_GET_LEN(trx->lock.trx_locks);
ulint heap_size = mem_heap_get_size(trx->lock.lock_heap);
- mutex_enter(&trx_sys->mutex);
-
trx_print_low(lock_latest_err_file, trx, max_query_len,
n_rec_locks, n_trx_locks, heap_size);
@@ -8096,8 +7349,6 @@ DeadlockChecker::print(const trx_t* trx, ulint max_query_len)
trx_print_low(stderr, trx, max_query_len,
n_rec_locks, n_trx_locks, heap_size);
}
-
- mutex_exit(&trx_sys->mutex);
}
/** Print lock data to the deadlock file and possibly to stderr.
@@ -8181,8 +7432,8 @@ DeadlockChecker::get_first_lock(ulint* heap_no) const
hash_table_t* lock_hash;
lock_hash = lock->type_mode & LOCK_PREDICATE
- ? lock_sys->prdt_hash
- : lock_sys->rec_hash;
+ ? lock_sys.prdt_hash
+ : lock_sys.rec_hash;
/* We are only interested in records that match the heap_no. */
*heap_no = lock_rec_find_set_bit(lock);
@@ -8530,16 +7781,7 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx)
ut_ad(trx == checker.m_start);
ut_ad(trx == victim_trx);
-#ifdef WITH_WSREP
- if (!wsrep_thd_is_BF(victim_trx->mysql_thd, TRUE))
- {
-#endif /* WITH_WSREP */
- rollback_print(victim_trx, lock);
-#ifdef WITH_WSREP
- } else {
- /* BF processor */;
- }
-#endif /* WITH_WSREP */
+ rollback_print(victim_trx, lock);
MONITOR_INC(MONITOR_DEADLOCK);
diff --git a/storage/innobase/lock/lock0prdt.cc b/storage/innobase/lock/lock0prdt.cc
index 88573b8a71a..6f677347eeb 100644
--- a/storage/innobase/lock/lock0prdt.cc
+++ b/storage/innobase/lock/lock0prdt.cc
@@ -29,7 +29,6 @@ Created 9/7/2013 Jimmy Yang
#include "lock0priv.h"
#include "lock0prdt.h"
#include "ha_prototypes.h"
-#include "usr0sess.h"
#include "trx0purge.h"
#include "dict0mem.h"
#include "dict0boot.h"
@@ -290,7 +289,7 @@ Checks if some other transaction has a conflicting predicate
lock request in the queue, so that we have to wait.
@return lock or NULL */
static
-const lock_t*
+lock_t*
lock_prdt_other_has_conflicting(
/*============================*/
ulint mode, /*!< in: LOCK_S or LOCK_X,
@@ -305,10 +304,10 @@ lock_prdt_other_has_conflicting(
{
ut_ad(lock_mutex_own());
- for (const lock_t* lock = lock_rec_get_first(
+ for (lock_t* lock = lock_rec_get_first(
lock_hash_get(mode), block, PRDT_HEAPNO);
lock != NULL;
- lock = lock_rec_get_next_const(PRDT_HEAPNO, lock)) {
+ lock = lock_rec_get_next(PRDT_HEAPNO, lock)) {
if (lock->trx == trx) {
continue;
@@ -540,7 +539,7 @@ lock_prdt_insert_check_and_lock(
lock_t* lock;
/* Only need to check locks on prdt_hash */
- lock = lock_rec_get_first(lock_sys->prdt_hash, block, PRDT_HEAPNO);
+ lock = lock_rec_get_first(lock_sys.prdt_hash, block, PRDT_HEAPNO);
if (lock == NULL) {
lock_mutex_exit();
@@ -565,7 +564,7 @@ lock_prdt_insert_check_and_lock(
const ulint mode = LOCK_X | LOCK_PREDICATE | LOCK_INSERT_INTENTION;
- const lock_t* wait_for = lock_prdt_other_has_conflicting(
+ lock_t* wait_for = lock_prdt_other_has_conflicting(
mode, block, prdt, trx);
if (wait_for != NULL) {
@@ -627,7 +626,7 @@ lock_prdt_update_parent(
/* Get all locks in parent */
for (lock = lock_rec_get_first_on_page_addr(
- lock_sys->prdt_hash, space, page_no);
+ lock_sys.prdt_hash, space, page_no);
lock;
lock = lock_rec_get_next_on_page(lock)) {
lock_prdt_t* lock_prdt;
@@ -817,8 +816,8 @@ lock_prdt_lock(
ut_ad(type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE));
hash_table_t* hash = type_mode == LOCK_PREDICATE
- ? lock_sys->prdt_hash
- : lock_sys->prdt_page_hash;
+ ? lock_sys.prdt_hash
+ : lock_sys.prdt_page_hash;
/* Another transaction cannot have an implicit lock on the record,
because when we come here, we already have modified the clustered
@@ -854,7 +853,7 @@ lock_prdt_lock(
if (lock == NULL) {
- const lock_t* wait_for;
+ lock_t* wait_for;
wait_for = lock_prdt_other_has_conflicting(
prdt_mode, block, prdt, trx);
@@ -924,7 +923,7 @@ lock_place_prdt_page_lock(
lock_mutex_enter();
const lock_t* lock = lock_rec_get_first_on_page_addr(
- lock_sys->prdt_page_hash, space, page_no);
+ lock_sys.prdt_page_hash, space, page_no);
const ulint mode = LOCK_S | LOCK_PRDT_PAGE;
trx_t* trx = thr_get_trx(thr);
@@ -978,7 +977,7 @@ lock_test_prdt_page_lock(
lock_mutex_enter();
lock = lock_rec_get_first_on_page_addr(
- lock_sys->prdt_page_hash, space, page_no);
+ lock_sys.prdt_page_hash, space, page_no);
lock_mutex_exit();
@@ -998,13 +997,13 @@ lock_prdt_rec_move(
{
lock_t* lock;
- if (!lock_sys->prdt_hash) {
+ if (!lock_sys.prdt_hash) {
return;
}
lock_mutex_enter();
- for (lock = lock_rec_get_first(lock_sys->prdt_hash,
+ for (lock = lock_rec_get_first(lock_sys.prdt_hash,
donator, PRDT_HEAPNO);
lock != NULL;
lock = lock_rec_get_next(PRDT_HEAPNO, lock)) {
diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc
index 0ed55558dc4..b2ed634e2a4 100644
--- a/storage/innobase/lock/lock0wait.cc
+++ b/storage/innobase/lock/lock0wait.cc
@@ -46,7 +46,7 @@ lock_wait_table_print(void)
{
ut_ad(lock_wait_mutex_own());
- const srv_slot_t* slot = lock_sys->waiting_threads;
+ const srv_slot_t* slot = lock_sys.waiting_threads;
for (ulint i = 0; i < OS_THREAD_MAX_N; i++, ++slot) {
@@ -72,7 +72,7 @@ lock_wait_table_release_slot(
srv_slot_t* slot) /*!< in: slot to release */
{
#ifdef UNIV_DEBUG
- srv_slot_t* upper = lock_sys->waiting_threads + OS_THREAD_MAX_N;
+ srv_slot_t* upper = lock_sys.waiting_threads + OS_THREAD_MAX_N;
#endif /* UNIV_DEBUG */
lock_wait_mutex_enter();
@@ -83,7 +83,7 @@ lock_wait_table_release_slot(
ut_ad(slot->thr->slot == slot);
/* Must be within the array boundaries. */
- ut_ad(slot >= lock_sys->waiting_threads);
+ ut_ad(slot >= lock_sys.waiting_threads);
ut_ad(slot < upper);
/* Note: When we reserve the slot we use the trx_t::mutex to update
@@ -102,23 +102,23 @@ lock_wait_table_release_slot(
lock_mutex_exit();
/* Scan backwards and adjust the last free slot pointer. */
- for (slot = lock_sys->last_slot;
- slot > lock_sys->waiting_threads && !slot->in_use;
+ for (slot = lock_sys.last_slot;
+ slot > lock_sys.waiting_threads && !slot->in_use;
--slot) {
/* No op */
}
/* Either the array is empty or the last scanned slot is in use. */
- ut_ad(slot->in_use || slot == lock_sys->waiting_threads);
+ ut_ad(slot->in_use || slot == lock_sys.waiting_threads);
- lock_sys->last_slot = slot + 1;
+ lock_sys.last_slot = slot + 1;
/* The last slot is either outside of the array boundary or it's
on an empty slot. */
- ut_ad(lock_sys->last_slot == upper || !lock_sys->last_slot->in_use);
+ ut_ad(lock_sys.last_slot == upper || !lock_sys.last_slot->in_use);
- ut_ad(lock_sys->last_slot >= lock_sys->waiting_threads);
- ut_ad(lock_sys->last_slot <= upper);
+ ut_ad(lock_sys.last_slot >= lock_sys.waiting_threads);
+ ut_ad(lock_sys.last_slot <= upper);
lock_wait_mutex_exit();
}
@@ -140,7 +140,7 @@ lock_wait_table_reserve_slot(
ut_ad(lock_wait_mutex_own());
ut_ad(trx_mutex_own(thr_get_trx(thr)));
- slot = lock_sys->waiting_threads;
+ slot = lock_sys.waiting_threads;
for (i = OS_THREAD_MAX_N; i--; ++slot) {
if (!slot->in_use) {
@@ -158,12 +158,12 @@ lock_wait_table_reserve_slot(
slot->suspend_time = ut_time();
slot->wait_timeout = wait_timeout;
- if (slot == lock_sys->last_slot) {
- ++lock_sys->last_slot;
+ if (slot == lock_sys.last_slot) {
+ ++lock_sys.last_slot;
}
- ut_ad(lock_sys->last_slot
- <= lock_sys->waiting_threads + OS_THREAD_MAX_N);
+ ut_ad(lock_sys.last_slot
+ <= lock_sys.waiting_threads + OS_THREAD_MAX_N);
return(slot);
}
@@ -183,20 +183,38 @@ lock_wait_table_reserve_slot(
/*********************************************************************//**
check if lock timeout was for priority thread,
as a side effect trigger lock monitor
+@param[in] trx transaction owning the lock
+@param[in] locked true if trx and lock_sys.mutex is ownd
@return false for regular lock timeout */
-static ibool
+static
+bool
wsrep_is_BF_lock_timeout(
-/*====================*/
- trx_t* trx) /* in: trx to check for lock priority */
+ const trx_t* trx,
+ bool locked = true)
{
- if (wsrep_on_trx(trx) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
- fprintf(stderr, "WSREP: BF lock wait long\n");
+ if (wsrep_on_trx(trx)
+ && wsrep_thd_is_BF(trx->mysql_thd, FALSE)
+ && trx->error_state != DB_DEADLOCK) {
+ ib::info() << "WSREP: BF lock wait long for trx:" << ib::hex(trx->id)
+ << " query: " << wsrep_thd_query(trx->mysql_thd);
+ if (!locked) {
+ lock_mutex_enter();
+ }
+
+ ut_ad(lock_mutex_own());
+
+ trx_print_latched(stderr, trx, 3000);
+
+ if (!locked) {
+ lock_mutex_exit();
+ }
+
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
os_event_set(srv_monitor_event);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
#endif /* WITH_WSREP */
@@ -376,11 +394,11 @@ lock_wait_suspend_thread(
/* Only update the variable if we successfully
retrieved the start and finish times. See Bug#36819. */
- if (diff_time > lock_sys->n_lock_max_wait_time
+ if (diff_time > lock_sys.n_lock_max_wait_time
&& start_time != -1
&& finish_time != -1) {
- lock_sys->n_lock_max_wait_time = diff_time;
+ lock_sys.n_lock_max_wait_time = diff_time;
}
/* Record the lock wait time for this thread */
@@ -399,7 +417,7 @@ lock_wait_suspend_thread(
&& wait_time > (double) lock_wait_timeout
#ifdef WITH_WSREP
&& (!wsrep_on_trx(trx) ||
- (!wsrep_is_BF_lock_timeout(trx) && trx->error_state != DB_DEADLOCK))
+ (!wsrep_is_BF_lock_timeout(trx, false) && trx->error_state != DB_DEADLOCK))
#endif /* WITH_WSREP */
&& !trx_is_high_priority(trx)) {
@@ -512,7 +530,7 @@ os_thread_ret_t
DECLARE_THREAD(lock_wait_timeout_thread)(void*)
{
int64_t sig_count = 0;
- os_event_t event = lock_sys->timeout_event;
+ os_event_t event = lock_sys.timeout_event;
ut_ad(!srv_read_only_mode);
@@ -538,8 +556,8 @@ DECLARE_THREAD(lock_wait_timeout_thread)(void*)
/* Check all slots for user threads that are waiting
on locks, and if they have exceeded the time limit. */
- for (slot = lock_sys->waiting_threads;
- slot < lock_sys->last_slot;
+ for (slot = lock_sys.waiting_threads;
+ slot < lock_sys.last_slot;
++slot) {
/* We are doing a read without the lock mutex
@@ -558,7 +576,7 @@ DECLARE_THREAD(lock_wait_timeout_thread)(void*)
} while (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP);
- lock_sys->timeout_thread_active = false;
+ lock_sys.timeout_thread_active = false;
/* 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. */
diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc
index e7d8e69a9c7..9cd06bc0c6f 100644
--- a/storage/innobase/log/log0crypt.cc
+++ b/storage/innobase/log/log0crypt.cc
@@ -393,9 +393,9 @@ log_tmp_block_encrypt(
aes_ctr_iv[1] = offs;
int rc = encryption_crypt(
- src, size, dst, &dst_len,
- const_cast<byte*>(info.crypt_key.bytes), sizeof info.crypt_key,
- reinterpret_cast<byte*>(aes_ctr_iv), sizeof aes_ctr_iv,
+ src, (uint)size, dst, &dst_len,
+ const_cast<byte*>(info.crypt_key.bytes), (uint)(sizeof info.crypt_key),
+ reinterpret_cast<byte*>(aes_ctr_iv), (uint)(sizeof aes_ctr_iv),
encrypt
? ENCRYPTION_FLAG_ENCRYPT|ENCRYPTION_FLAG_NOPAD
: ENCRYPTION_FLAG_DECRYPT|ENCRYPTION_FLAG_NOPAD,
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 9ae5eb4f42e..28717a22982 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Google Inc.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2014, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -226,16 +226,18 @@ log_buffer_extend(
log_sys->buf_free -= move_start;
log_sys->buf_next_to_write -= move_start;
+ /* free previous after getting the right address */
+ if (!log_sys->first_in_use) {
+ log_sys->buf -= log_sys->buf_size;
+ }
+ ut_free_dodump(log_sys->buf, log_sys->buf_size * 2);
+
/* reallocate log buffer */
srv_log_buffer_size = len / UNIV_PAGE_SIZE + 1;
- ut_free(log_sys->buf_ptr);
-
log_sys->buf_size = LOG_BUFFER_SIZE;
- log_sys->buf_ptr = static_cast<byte*>(
- ut_zalloc_nokey(log_sys->buf_size * 2 + OS_FILE_LOG_BLOCK_SIZE));
log_sys->buf = static_cast<byte*>(
- ut_align(log_sys->buf_ptr, OS_FILE_LOG_BLOCK_SIZE));
+ ut_malloc_dontdump(log_sys->buf_size * 2));
log_sys->first_in_use = true;
@@ -723,10 +725,8 @@ log_sys_init()
log_sys->buf_size = LOG_BUFFER_SIZE;
- log_sys->buf_ptr = static_cast<byte*>(
- ut_zalloc_nokey(log_sys->buf_size * 2 + OS_FILE_LOG_BLOCK_SIZE));
log_sys->buf = static_cast<byte*>(
- ut_align(log_sys->buf_ptr, OS_FILE_LOG_BLOCK_SIZE));
+ ut_malloc_dontdump(log_sys->buf_size * 2));
log_sys->first_in_use = true;
@@ -1085,12 +1085,12 @@ log_buffer_switch()
OS_FILE_LOG_BLOCK_SIZE);
if (log_sys->first_in_use) {
- ut_ad(log_sys->buf == ut_align(log_sys->buf_ptr,
+ ut_ad(log_sys->buf == ut_align(log_sys->buf,
OS_FILE_LOG_BLOCK_SIZE));
log_sys->buf += log_sys->buf_size;
} else {
log_sys->buf -= log_sys->buf_size;
- ut_ad(log_sys->buf == ut_align(log_sys->buf_ptr,
+ ut_ad(log_sys->buf == ut_align(log_sys->buf,
OS_FILE_LOG_BLOCK_SIZE));
}
@@ -1584,8 +1584,6 @@ log_write_checkpoint_info(bool sync, lsn_t end_lsn)
rw_lock_s_lock(&log_sys->checkpoint_lock);
rw_lock_s_unlock(&log_sys->checkpoint_lock);
- DEBUG_SYNC_C("checkpoint_completed");
-
DBUG_EXECUTE_IF(
"crash_after_checkpoint",
DBUG_SUICIDE(););
@@ -1883,7 +1881,7 @@ logs_empty_and_mark_files_at_shutdown(void)
srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
loop:
- ut_ad(lock_sys || !srv_was_started);
+ ut_ad(lock_sys.is_initialised() || !srv_was_started);
ut_ad(log_sys || !srv_was_started);
ut_ad(fil_system || !srv_was_started);
os_event_set(srv_buf_resize_event);
@@ -1892,8 +1890,8 @@ loop:
os_event_set(srv_error_event);
os_event_set(srv_monitor_event);
os_event_set(srv_buf_dump_event);
- if (lock_sys) {
- os_event_set(lock_sys->timeout_event);
+ if (lock_sys.timeout_thread_active) {
+ os_event_set(lock_sys.timeout_event);
}
if (dict_stats_event) {
os_event_set(dict_stats_event);
@@ -1918,7 +1916,7 @@ loop:
if (ulint total_trx = srv_was_started && !srv_read_only_mode
&& srv_force_recovery < SRV_FORCE_NO_TRX_UNDO
- ? trx_sys_any_active_transactions() : 0) {
+ ? trx_sys.any_active_transactions() : 0) {
if (srv_print_verbose_log && count > 600) {
ib::info() << "Waiting for " << total_trx << " active"
@@ -1942,14 +1940,14 @@ loop:
goto wait_suspend_loop;
} else if (srv_dict_stats_thread_active) {
thread_name = "dict_stats_thread";
- } else if (lock_sys && lock_sys->timeout_thread_active) {
+ } else if (lock_sys.timeout_thread_active) {
thread_name = "lock_wait_timeout_thread";
} else if (srv_buf_dump_thread_active) {
thread_name = "buf_dump_thread";
goto wait_suspend_loop;
} else if (btr_defragment_thread_active) {
thread_name = "btr_defragment_thread";
- } else if (srv_fast_shutdown != 2 && trx_rollback_or_clean_is_active) {
+ } else if (srv_fast_shutdown != 2 && trx_rollback_is_active) {
thread_name = "rollback of recovered transactions";
} else {
thread_name = NULL;
@@ -1979,6 +1977,7 @@ wait_suspend_loop:
goto wait_suspend_loop;
case SRV_PURGE:
case SRV_WORKER:
+ ut_ad(!"purge was not shut down");
srv_purge_wakeup();
thread_name = "purge thread";
goto wait_suspend_loop;
@@ -2255,8 +2254,10 @@ log_shutdown()
{
log_group_close_all();
- ut_free(log_sys->buf_ptr);
- log_sys->buf_ptr = NULL;
+ if (!log_sys->first_in_use) {
+ log_sys->buf -= log_sys->buf_size;
+ }
+ ut_free_dodump(log_sys->buf, log_sys->buf_size * 2);
log_sys->buf = NULL;
ut_free(log_sys->checkpoint_buf_ptr);
log_sys->checkpoint_buf_ptr = NULL;
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 21450767689..5be52ec0696 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -438,7 +438,9 @@ recv_sys_close()
os_event_destroy(recv_sys->flush_end);
}
- ut_free(recv_sys->buf);
+ if (recv_sys->buf != NULL) {
+ ut_free_dodump(recv_sys->buf, recv_sys->buf_size);
+ }
ut_ad(!recv_writer_thread_active);
mutex_free(&recv_sys->writer_mutex);
@@ -553,7 +555,8 @@ recv_sys_init()
}
recv_sys->buf = static_cast<byte*>(
- ut_malloc_nokey(RECV_PARSING_BUF_SIZE));
+ ut_malloc_dontdump(RECV_PARSING_BUF_SIZE));
+ recv_sys->buf_size = RECV_PARSING_BUF_SIZE;
recv_sys->addr_hash = hash_create(size / 512);
recv_sys->progress_time = ut_time();
@@ -588,8 +591,9 @@ recv_sys_debug_free(void)
hash_table_free(recv_sys->addr_hash);
mem_heap_free(recv_sys->heap);
- ut_free(recv_sys->buf);
+ ut_free_dodump(recv_sys->buf, recv_sys->buf_size);
+ recv_sys->buf_size = 0;
recv_sys->buf = NULL;
recv_sys->heap = NULL;
recv_sys->addr_hash = NULL;
@@ -608,26 +612,29 @@ recv_sys_debug_free(void)
/** Read a log segment to a buffer.
@param[out] buf buffer
@param[in] group redo log files
-@param[in] start_lsn read area start
+@param[in, out] start_lsn in : read area start, out: the last read valid lsn
@param[in] end_lsn read area end
-@return valid end_lsn */
-lsn_t
+@param[out] invalid_block - invalid, (maybe incompletely written) block encountered
+@return false, if invalid block encountered (e.g checksum mismatch), true otherwise */
+bool
log_group_read_log_seg(
byte* buf,
const log_group_t* group,
- lsn_t start_lsn,
+ lsn_t *start_lsn,
lsn_t end_lsn)
{
ulint len;
lsn_t source_offset;
-
+ bool success = true;
ut_ad(log_mutex_own());
+ ut_ad(!(*start_lsn % OS_FILE_LOG_BLOCK_SIZE));
+ ut_ad(!(end_lsn % OS_FILE_LOG_BLOCK_SIZE));
loop:
- source_offset = log_group_calc_lsn_offset(start_lsn, group);
+ source_offset = log_group_calc_lsn_offset(*start_lsn, group);
- ut_a(end_lsn - start_lsn <= ULINT_MAX);
- len = (ulint) (end_lsn - start_lsn);
+ ut_a(end_lsn - *start_lsn <= ULINT_MAX);
+ len = (ulint) (end_lsn - *start_lsn);
ut_ad(len != 0);
@@ -657,16 +664,16 @@ loop:
for (ulint l = 0; l < len; l += OS_FILE_LOG_BLOCK_SIZE,
buf += OS_FILE_LOG_BLOCK_SIZE,
- start_lsn += OS_FILE_LOG_BLOCK_SIZE) {
+ (*start_lsn) += OS_FILE_LOG_BLOCK_SIZE) {
const ulint block_number = log_block_get_hdr_no(buf);
- if (block_number != log_block_convert_lsn_to_no(start_lsn)) {
+ if (block_number != log_block_convert_lsn_to_no(*start_lsn)) {
/* Garbage or an incompletely written log block.
We will not report any error, because this can
happen when InnoDB was killed while it was
writing redo log. We simply treat this as an
abrupt end of the redo log. */
- end_lsn = start_lsn;
+ end_lsn = *start_lsn;
break;
}
@@ -674,6 +681,13 @@ loop:
ulint crc = log_block_calc_checksum_crc32(buf);
ulint cksum = log_block_get_checksum(buf);
+ DBUG_EXECUTE_IF("log_intermittent_checksum_mismatch", {
+ static int block_counter;
+ if (block_counter++ == 0) {
+ cksum = crc + 1;
+ }
+ });
+
if (crc != cksum) {
ib::error() << "Invalid log block checksum."
<< " block: " << block_number
@@ -681,30 +695,33 @@ loop:
<< log_block_get_checkpoint_no(buf)
<< " expected: " << crc
<< " found: " << cksum;
- end_lsn = start_lsn;
+ end_lsn = *start_lsn;
+ success = false;
break;
}
if (group->is_encrypted()) {
- log_crypt(buf, start_lsn,
+ log_crypt(buf, *start_lsn,
OS_FILE_LOG_BLOCK_SIZE, true);
}
}
}
if (recv_sys->report(ut_time())) {
- ib::info() << "Read redo log up to LSN=" << start_lsn;
+ ib::info() << "Read redo log up to LSN=" << *start_lsn;
sd_notifyf(0, "STATUS=Read redo log up to LSN=" LSN_PF,
- start_lsn);
+ *start_lsn);
}
- if (start_lsn != end_lsn) {
+ if (*start_lsn != end_lsn) {
goto loop;
}
- return(start_lsn);
+ return(success);
}
+
+
/********************************************************//**
Copies a log segment from the most up-to-date log group to the other log
groups, so that they all contain the latest log data. Also writes the info
@@ -719,10 +736,10 @@ recv_synchronize_groups()
/* Read the last recovered log block to the recovery system buffer:
the block is always incomplete */
- const lsn_t start_lsn = ut_uint64_align_down(recovered_lsn,
+ lsn_t start_lsn = ut_uint64_align_down(recovered_lsn,
OS_FILE_LOG_BLOCK_SIZE);
log_group_read_log_seg(log_sys->buf, &log_sys->log,
- start_lsn, start_lsn + OS_FILE_LOG_BLOCK_SIZE);
+ &start_lsn, start_lsn + OS_FILE_LOG_BLOCK_SIZE);
/* Update the fields in the group struct to correspond to
recovered_lsn */
@@ -829,7 +846,7 @@ recv_find_max_checkpoint_0(log_group_t** max_group, ulint* max_field)
" This redo log was created before MariaDB 10.2.2,"
" and we did not find a valid checkpoint."
" Please follow the instructions at"
- " " REFMAN "upgrading.html";
+ " https://mariadb.com/kb/en/library/upgrading/";
return(DB_ERROR);
}
@@ -889,58 +906,6 @@ recv_log_format_0_recover(lsn_t lsn)
return(DB_SUCCESS);
}
-/** Determine if a redo log from MySQL 5.7.9/MariaDB 10.2.2 is clean.
-@return error code
-@retval DB_SUCCESS if the redo log is clean
-@retval DB_CORRUPTION if the redo log is corrupted
-@retval DB_ERROR if the redo log is not empty */
-static
-dberr_t
-recv_log_recover_10_2()
-{
- log_group_t* group = &log_sys->log;
- const lsn_t lsn = group->lsn;
- const lsn_t source_offset = log_group_calc_lsn_offset(lsn, group);
- const ulint page_no
- = (ulint) (source_offset / univ_page_size.physical());
- byte* buf = log_sys->buf;
-
- fil_io(IORequestLogRead, true,
- page_id_t(SRV_LOG_SPACE_FIRST_ID, page_no),
- univ_page_size,
- (ulint) ((source_offset & ~(OS_FILE_LOG_BLOCK_SIZE - 1))
- % univ_page_size.physical()),
- OS_FILE_LOG_BLOCK_SIZE, buf, NULL);
-
- if (log_block_calc_checksum(buf) != log_block_get_checksum(buf)) {
- return(DB_CORRUPTION);
- }
-
- if (group->is_encrypted()) {
- log_crypt(buf, lsn, OS_FILE_LOG_BLOCK_SIZE, true);
- }
-
- /* On a clean shutdown, the redo log will be logically empty
- after the checkpoint lsn. */
-
- if (log_block_get_data_len(buf)
- != (source_offset & (OS_FILE_LOG_BLOCK_SIZE - 1))) {
- return(DB_ERROR);
- }
-
- /* Mark the redo log for upgrading. */
- srv_log_file_size = 0;
- recv_sys->parse_start_lsn = recv_sys->recovered_lsn
- = recv_sys->scanned_lsn
- = recv_sys->mlog_checkpoint_lsn = lsn;
- log_sys->last_checkpoint_lsn = log_sys->next_checkpoint_lsn
- = log_sys->lsn = log_sys->write_lsn
- = log_sys->current_flush_lsn = log_sys->flushed_to_disk_lsn
- = lsn;
- log_sys->next_checkpoint_no = 0;
- return(DB_SUCCESS);
-}
-
/** Find the latest checkpoint in the log header.
@param[out] max_field LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2
@return error code or DB_SUCCESS */
@@ -1050,20 +1015,6 @@ recv_find_max_checkpoint(ulint* max_field)
return(DB_ERROR);
}
- switch (group->format) {
- case LOG_HEADER_FORMAT_10_2:
- case LOG_HEADER_FORMAT_10_2 | LOG_HEADER_FORMAT_ENCRYPTED:
- dberr_t err = recv_log_recover_10_2();
- if (err != DB_SUCCESS) {
- ib::error()
- << "Upgrade after a crash is not supported."
- " The redo log was created with " << creator
- << (err == DB_ERROR
- ? "." : ", and it appears corrupted.");
- }
- return(err);
- }
-
return(DB_SUCCESS);
}
@@ -1212,6 +1163,8 @@ parse_log:
redo log been written with something
older than InnoDB Plugin 1.0.4. */
ut_ad(0
+ /* fil_crypt_rotate_page() writes this */
+ || offs == FIL_PAGE_SPACE_ID
|| offs == IBUF_TREE_SEG_HEADER
+ IBUF_HEADER + FSEG_HDR_SPACE
|| offs == IBUF_TREE_SEG_HEADER
@@ -1386,13 +1339,20 @@ parse_log:
ptr = trx_undo_parse_add_undo_rec(ptr, end_ptr, page);
break;
case MLOG_UNDO_ERASE_END:
- ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
- ptr = trx_undo_parse_erase_page_end(ptr, end_ptr, page, mtr);
+ if (page) {
+ ut_ad(page_type == FIL_PAGE_UNDO_LOG);
+ trx_undo_erase_page_end(page);
+ }
break;
case MLOG_UNDO_INIT:
/* Allow anything in page_type when creating a page. */
ptr = trx_undo_parse_page_init(ptr, end_ptr, page, mtr);
break;
+ case MLOG_UNDO_HDR_REUSE:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
+ ptr = trx_undo_parse_page_header_reuse(ptr, end_ptr, page,
+ mtr);
+ break;
case MLOG_UNDO_HDR_CREATE:
ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
ptr = trx_undo_parse_page_header(ptr, end_ptr, page, mtr);
@@ -2962,9 +2922,11 @@ recv_group_scan_log_recs(
recv_apply_hashed_log_recs(false);
}
- start_lsn = end_lsn;
- end_lsn = log_group_read_log_seg(
- log_sys->buf, group, start_lsn,
+ start_lsn = ut_uint64_align_down(end_lsn,
+ OS_FILE_LOG_BLOCK_SIZE);
+ end_lsn = start_lsn;
+ log_group_read_log_seg(
+ log_sys->buf, group, &end_lsn,
start_lsn + RECV_SCAN_SIZE);
} while (end_lsn != start_lsn
&& !recv_scan_log_recs(
@@ -3121,7 +3083,9 @@ recv_init_crash_recovery_spaces()
<< "', but there were no modifications either.";
}
- buf_dblwr_process();
+ if (srv_operation == SRV_OPERATION_NORMAL) {
+ buf_dblwr_process();
+ }
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
/* Spawn the background thread to flush dirty pages
@@ -3173,10 +3137,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
err = recv_find_max_checkpoint(&max_cp_field);
- if (err != DB_SUCCESS
- || (log_sys->log.format != LOG_HEADER_FORMAT_3_23
- && (log_sys->log.format & ~LOG_HEADER_FORMAT_ENCRYPTED)
- != LOG_HEADER_FORMAT_CURRENT)) {
+ if (err != DB_SUCCESS) {
srv_start_lsn = recv_sys->recovered_lsn = log_sys->lsn;
log_mutex_exit();
@@ -3459,6 +3420,8 @@ recv_recovery_rollback_active(void)
/* Drop partially created indexes. */
row_merge_drop_temp_indexes();
+ /* Drop garbage tables. */
+ row_mysql_drop_garbage_tables();
/* Drop any auxiliary tables that were not dropped when the
parent table was dropped. This can happen if the parent table
@@ -3469,8 +3432,8 @@ recv_recovery_rollback_active(void)
/* Rollback the uncommitted transactions which have no user
session */
- trx_rollback_or_clean_is_active = true;
- os_thread_create(trx_rollback_or_clean_all_recovered, 0, 0);
+ trx_rollback_is_active = true;
+ os_thread_create(trx_rollback_all_recovered, 0, 0);
}
}
@@ -3624,6 +3587,9 @@ get_mlog_string(mlog_id_t type)
case MLOG_UNDO_INIT:
return("MLOG_UNDO_INIT");
+ case MLOG_UNDO_HDR_REUSE:
+ return("MLOG_UNDO_HDR_REUSE");
+
case MLOG_UNDO_HDR_CREATE:
return("MLOG_UNDO_HDR_CREATE");
diff --git a/storage/innobase/mem/mem0mem.cc b/storage/innobase/mem/mem0mem.cc
index 0d655cdd6c8..b4a4e8eec4a 100644
--- a/storage/innobase/mem/mem0mem.cc
+++ b/storage/innobase/mem/mem0mem.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -407,15 +407,11 @@ mem_heap_block_free(
len = block->len;
block->magic_n = MEM_FREED_BLOCK_MAGIC_N;
- UNIV_MEM_ASSERT_W(block, len);
-
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
-
ut_ad(!buf_block);
ut_free(block);
} else {
ut_ad(type & MEM_HEAP_BUFFER);
-
buf_block_free(buf_block);
}
}
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index faa00b1518b..72b24b08871 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -492,7 +492,7 @@ mtr_write_log(
@param sync true if it is a synchronous mini-transaction
@param read_only true if read only mini-transaction */
void
-mtr_t::start(trx_t* trx, bool sync, bool read_only)
+mtr_t::start(bool sync, bool read_only)
{
UNIV_MEM_INVALID(this, sizeof(*this));
@@ -517,7 +517,6 @@ mtr_t::start(trx_t* trx, bool sync, bool read_only)
m_impl.m_undo_space = NULL;
m_impl.m_sys_space = NULL;
m_impl.m_flush_observer = NULL;
- m_impl.m_trx = trx;
ut_d(m_impl.m_magic_n = MTR_MAGIC_N);
}
diff --git a/storage/innobase/os/os0event.cc b/storage/innobase/os/os0event.cc
index b687af3e21c..98b474c0bda 100644
--- a/storage/innobase/os/os0event.cc
+++ b/storage/innobase/os/os0event.cc
@@ -35,9 +35,6 @@ Created 2012-09-23 Sunny Bains
#include <list>
-/** The number of microsecnds in a second. */
-static const ulint MICROSECS_IN_A_SECOND = 1000000;
-
#ifdef _WIN32
/** Native condition variable. */
typedef CONDITION_VARIABLE os_cond_t;
@@ -381,13 +378,8 @@ os_event::wait_time_low(
tv.tv_usec += time_in_usec;
- if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) {
- tv.tv_sec += tv.tv_usec / MICROSECS_IN_A_SECOND;
- tv.tv_usec %= MICROSECS_IN_A_SECOND;
- }
-
- abstime.tv_sec = tv.tv_sec;
- abstime.tv_nsec = tv.tv_usec * 1000;
+ abstime.tv_sec = tv.tv_sec + tv.tv_usec / 1000000;
+ abstime.tv_nsec = tv.tv_usec % 1000000 * 1000;
} else {
abstime.tv_nsec = 999999999;
abstime.tv_sec = (time_t) ULINT_MAX;
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index e556f6bef6d..b0f4b90b127 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted
by Percona Inc.. Those modifications are
@@ -814,7 +814,8 @@ os_file_get_block_size(
#ifdef _WIN32
fblock_size = 0;
-
+ BOOL result = false;
+ size_t len = 0;
// Open volume for this file, find out it "physical bytes per sector"
HANDLE volume_handle = INVALID_HANDLE_VALUE;
@@ -825,7 +826,7 @@ os_file_get_block_size(
goto end;
}
- size_t len = strlen(volume);
+ len = strlen(volume);
if (volume[len - 1] == '\\') {
// Trim trailing backslash from volume name.
volume[len - 1] = 0;
@@ -849,7 +850,7 @@ os_file_get_block_size(
storage_query.PropertyId = StorageAccessAlignmentProperty;
storage_query.QueryType = PropertyStandardQuery;
- BOOL result = os_win32_device_io_control(volume_handle,
+ result = os_win32_device_io_control(volume_handle,
IOCTL_STORAGE_QUERY_PROPERTY,
&storage_query,
sizeof(storage_query),
@@ -1305,11 +1306,8 @@ os_file_make_new_pathname(
new_path = static_cast<char*>(ut_malloc_nokey(new_path_len));
memcpy(new_path, old_path, dir_len);
- ut_snprintf(new_path + dir_len,
- new_path_len - dir_len,
- "%c%s.ibd",
- OS_PATH_SEPARATOR,
- base_name);
+ snprintf(new_path + dir_len, new_path_len - dir_len,
+ "%c%s.ibd", OS_PATH_SEPARATOR, base_name);
return(new_path);
}
@@ -3403,16 +3401,6 @@ static void __stdcall win_free_syncio_event(void *data) {
/*
-Initialize tls index.for event handle used for synchronized IO on files that
-might be opened with FILE_FLAG_OVERLAPPED.
-*/
-static void win_init_syncio_event() {
- fls_sync_io = FlsAlloc(win_free_syncio_event);
- ut_a(fls_sync_io != FLS_OUT_OF_INDEXES);
-}
-
-
-/*
Retrieve per-thread event for doing synchronous io on asyncronously opened files
*/
static HANDLE win_get_syncio_event()
@@ -3517,46 +3505,6 @@ struct WinIoInit
/* Ensures proper initialization and shutdown */
static WinIoInit win_io_init;
-/** Check if the file system supports sparse files.
-@param[in] name File name
-@return true if the file system supports sparse files */
-static
-bool
-os_is_sparse_file_supported_win32(const char* filename)
-{
- char volname[MAX_PATH];
- BOOL result = GetVolumePathName(filename, volname, MAX_PATH);
-
- if (!result) {
-
- ib::error()
- << "os_is_sparse_file_supported: "
- << "Failed to get the volume path name for: "
- << filename
- << "- OS error number " << GetLastError();
-
- return(false);
- }
-
- DWORD flags;
-
- result = GetVolumeInformation(
- volname, NULL, MAX_PATH, NULL, NULL,
- &flags, NULL, MAX_PATH);
-
-
- if (!result) {
- ib::error()
- << "os_is_sparse_file_supported: "
- << "Failed to get the volume info for: "
- << volname
- << "- OS error number " << GetLastError();
-
- return(false);
- }
-
- return(flags & FILE_SUPPORTS_SPARSE_FILES) ? true : false;
-}
/** Free storage space associated with a section of the file.
@param[in] fh Open file handle
@@ -3853,7 +3801,7 @@ os_file_create_simple_func(
ib::info()
<< "Read only mode set. Unable to"
" open file '" << name << "' in RW mode, "
- << "trying RO mode", name;
+ << "trying RO mode";
access = GENERIC_READ;
@@ -4548,7 +4496,7 @@ bool
os_file_close_func(
os_file_t file)
{
- ut_a(file > 0);
+ ut_a(file);
if (CloseHandle(file)) {
return(true);
@@ -4997,7 +4945,7 @@ os_file_write_func(
if ((ulint) n_bytes != n && !os_has_said_disk_full) {
ib::error()
- << "Write to file " << name << "failed at offset "
+ << "Write to file " << name << " failed at offset "
<< offset << ", " << n
<< " bytes should have been written,"
" only " << n_bytes << " were written."
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index 5ede7faf3ba..c4585dd7143 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2018, 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
@@ -520,7 +521,7 @@ up_rec_match:
ulint rec_info = rec_get_info_bits(mid_rec,
rec_offs_comp(offsets));
ut_ad(rec_info & REC_INFO_MIN_REC_FLAG);
- ut_ad(btr_page_get_prev(page, &mtr) == FIL_NULL);
+ ut_ad(!page_has_prev(page));
mtr_commit(&mtr);
#endif
@@ -734,9 +735,7 @@ up_slot_match:
mid_rec,
dict_table_is_comp(index->table))
& REC_INFO_MIN_REC_FLAG)) {
- ut_ad(mach_read_from_4(FIL_PAGE_PREV
- + page_align(mid_rec))
- == FIL_NULL);
+ ut_ad(!page_has_prev(page_align(mid_rec)));
ut_ad(!page_rec_is_leaf(mid_rec)
|| rec_is_default_row(mid_rec, index));
cmp = 1;
@@ -1279,7 +1278,7 @@ page_cur_insert_rec_low(
== (ibool) !!page_is_comp(page));
ut_ad(fil_page_index_page_check(page));
ut_ad(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID) == index->id
- || recv_recovery_is_on()
+ || index->is_dummy
|| (mtr ? mtr->is_inside_ibuf() : dict_index_is_ibuf(index)));
ut_ad(!page_rec_is_supremum(current_rec));
@@ -1506,8 +1505,8 @@ page_cur_insert_rec_zip(
ut_ad(page_is_comp(page));
ut_ad(fil_page_index_page_check(page));
ut_ad(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID) == index->id
- || (mtr ? mtr->is_inside_ibuf() : dict_index_is_ibuf(index))
- || recv_recovery_is_on());
+ || index->is_dummy
+ || (mtr ? mtr->is_inside_ibuf() : dict_index_is_ibuf(index)));
ut_ad(!page_get_instant(page));
ut_ad(!page_cur_is_after_last(cursor));
#ifdef UNIV_ZIP_DEBUG
@@ -1626,6 +1625,7 @@ page_cur_insert_rec_zip(
because the MLOG_COMP_REC_INSERT should only
be logged after a successful operation. */
ut_ad(!recv_recovery_is_on());
+ ut_ad(!index->is_dummy);
} else if (recv_recovery_is_on()) {
/* This should be followed by
MLOG_ZIP_PAGE_COMPRESS_NO_DATA,
@@ -1967,6 +1967,8 @@ page_parse_copy_rec_list_to_created_page(
page_t* page;
page_zip_des_t* page_zip;
+ ut_ad(index->is_dummy);
+
if (ptr + 4 > end_ptr) {
return(NULL);
@@ -1992,8 +1994,7 @@ page_parse_copy_rec_list_to_created_page(
page_copy_rec_list_end_to_created_page() which was logged by.
page_copy_rec_list_to_created_page_write_log().
For other pages, this field must be zero-initialized. */
- ut_ad(!page_get_instant(block->frame)
- || (page_is_root(block->frame) && index->is_dummy));
+ ut_ad(!page_get_instant(block->frame) || page_is_root(block->frame));
while (ptr < rec_end) {
ptr = page_cur_parse_insert_rec(TRUE, ptr, end_ptr,
@@ -2320,8 +2321,8 @@ page_cur_delete_rec(
ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table));
ut_ad(fil_page_index_page_check(page));
ut_ad(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID) == index->id
- || (mtr ? mtr->is_inside_ibuf() : dict_index_is_ibuf(index))
- || recv_recovery_is_on());
+ || index->is_dummy
+ || (mtr ? mtr->is_inside_ibuf() : dict_index_is_ibuf(index)));
ut_ad(mtr == NULL || mtr->is_named_space(index->space));
/* The record must not be the supremum or infimum record. */
diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc
index 624e31685fe..db85b09631e 100644
--- a/storage/innobase/page/page0page.cc
+++ b/storage/innobase/page/page0page.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -2427,18 +2427,19 @@ page_validate(
same temp-table in parallel.
max_trx_id is ignored for temp tables because it not required
for MVCC. */
- if (dict_index_is_sec_or_ibuf(index)
- && !dict_table_is_temporary(index->table)
- && page_is_leaf(page)
- && !page_is_empty(page)) {
+ if (!page_is_leaf(page) || page_is_empty(page)
+ || !dict_index_is_sec_or_ibuf(index)
+ || index->table->is_temporary()) {
+ } else if (trx_id_t sys_max_trx_id = trx_sys.get_max_trx_id()) {
trx_id_t max_trx_id = page_get_max_trx_id(page);
- trx_id_t sys_max_trx_id = trx_sys_get_max_trx_id();
if (max_trx_id == 0 || max_trx_id > sys_max_trx_id) {
ib::error() << "PAGE_MAX_TRX_ID out of bounds: "
<< max_trx_id << ", " << sys_max_trx_id;
goto func_exit2;
}
+ } else {
+ ut_ad(srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN);
}
heap = mem_heap_create(UNIV_PAGE_SIZE + 200);
@@ -2767,8 +2768,7 @@ page_delete_rec(
if (!rec_offs_any_extern(offsets)
&& ((page_get_data_size(page) - rec_offs_size(offsets)
< BTR_CUR_PAGE_COMPRESS_LIMIT(index))
- || (mach_read_from_4(page + FIL_PAGE_NEXT) == FIL_NULL
- && mach_read_from_4(page + FIL_PAGE_PREV) == FIL_NULL)
+ || !page_has_siblings(page)
|| (page_get_n_recs(page) < 2))) {
ulint root_page_no = dict_index_get_page(index);
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 9e3119bfd3a..4ef37b81c29 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -2,7 +2,7 @@
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2014, 2018, 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
@@ -669,8 +669,7 @@ page_zip_dir_encode(
status = REC_STATUS_ORDINARY;
} else {
status = REC_STATUS_NODE_PTR;
- if (UNIV_UNLIKELY
- (mach_read_from_4(page + FIL_PAGE_PREV) == FIL_NULL)) {
+ if (UNIV_UNLIKELY(!page_has_prev(page))) {
min_mark = REC_INFO_MIN_REC_FLAG;
}
}
@@ -1340,8 +1339,8 @@ page_zip_compress(
if (UNIV_UNLIKELY(page_zip_compress_log)) {
/* Create a log file for every compression attempt. */
char logfilename[9];
- ut_snprintf(logfilename, sizeof logfilename,
- "%08x", page_zip_compress_log++);
+ snprintf(logfilename, sizeof logfilename,
+ "%08x", page_zip_compress_log++);
logfile = fopen(logfilename, "wb");
if (logfile) {
@@ -3188,8 +3187,7 @@ zlib_error:
goto err_exit;
}
- info_bits = mach_read_from_4(page + FIL_PAGE_PREV) == FIL_NULL
- ? REC_INFO_MIN_REC_FLAG : 0;
+ info_bits = page_has_prev(page) ? 0 : REC_INFO_MIN_REC_FLAG;
if (UNIV_UNLIKELY(!page_zip_set_extra_bytes(page_zip, page,
info_bits))) {
@@ -3716,8 +3714,9 @@ page_zip_write_rec(
/* Copy the delete mark. */
if (rec_get_deleted_flag(rec, TRUE)) {
/* In delete-marked records, DB_TRX_ID must
- always refer to an existing undo log record. */
- ut_ad(!dict_index_is_clust(index)
+ always refer to an existing undo log record.
+ On non-leaf pages, the delete-mark flag is garbage. */
+ ut_ad(!index->is_primary() || !page_is_leaf(page)
|| row_get_rec_trx_id(rec, index, offsets));
*slot |= PAGE_ZIP_DIR_SLOT_DEL >> 8;
} else {
@@ -4907,9 +4906,8 @@ page_zip_copy_recs(
+ page_zip->m_end < page_zip_get_size(page_zip));
if (!page_is_leaf(src)
- && UNIV_UNLIKELY(mach_read_from_4(src + FIL_PAGE_PREV) == FIL_NULL)
- && UNIV_LIKELY(mach_read_from_4(page
- + FIL_PAGE_PREV) != FIL_NULL)) {
+ && UNIV_UNLIKELY(!page_has_prev(src))
+ && UNIV_LIKELY(page_has_prev(page))) {
/* Clear the REC_INFO_MIN_REC_FLAG of the first user record. */
ulint offs = rec_get_next_offs(page + PAGE_NEW_INFIMUM,
TRUE);
diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc
index d0696ab5cfc..11195287d8f 100644
--- a/storage/innobase/pars/pars0pars.cc
+++ b/storage/innobase/pars/pars0pars.cc
@@ -1085,7 +1085,7 @@ pars_update_statement_start(
node = upd_node_create(pars_sym_tab_global->heap);
- node->is_delete = is_delete;
+ node->is_delete = is_delete ? PLAIN_DELETE : NO_DELETE;
node->table_sym = table_sym;
node->col_assign_list = col_assign_list;
@@ -1250,9 +1250,9 @@ pars_update_statement(
node->select = sel_node;
ut_a(!node->is_delete || (node->col_assign_list == NULL));
- ut_a(node->is_delete || (node->col_assign_list != NULL));
+ ut_a(node->is_delete == PLAIN_DELETE || node->col_assign_list != NULL);
- if (node->is_delete) {
+ if (node->is_delete == PLAIN_DELETE) {
node->cmpl_info = 0;
} else {
pars_process_assign_list(node);
diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc
index 5a3af9dfaeb..937f215dc39 100644
--- a/storage/innobase/que/que0que.cc
+++ b/storage/innobase/que/que0que.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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,7 +27,6 @@ Created 5/27/1996 Heikki Tuuri
#include "ha_prototypes.h"
#include "que0que.h"
-#include "usr0sess.h"
#include "trx0trx.h"
#include "trx0roll.h"
#include "row0undo.h"
@@ -482,20 +481,17 @@ que_graph_free_recursive(
case QUE_NODE_UPDATE:
upd = static_cast<upd_node_t*>(node);
- DBUG_PRINT("que_graph_free_recursive",
- ("QUE_NODE_UPDATE: %p, processed_cascades: %p",
- upd, upd->processed_cascades));
-
if (upd->in_mysql_interface) {
btr_pcur_free_for_mysql(upd->pcur);
upd->in_mysql_interface = FALSE;
}
- if (upd->cascade_top) {
+ que_graph_free_recursive(upd->cascade_node);
+
+ if (upd->cascade_heap) {
mem_heap_free(upd->cascade_heap);
upd->cascade_heap = NULL;
- upd->cascade_top = false;
}
que_graph_free_recursive(upd->select);
@@ -1030,6 +1026,7 @@ que_thr_step(
} else if (type == QUE_NODE_SELECT) {
thr = row_sel_step(thr);
} else if (type == QUE_NODE_INSERT) {
+ trx_start_if_not_started_xa(thr_get_trx(thr), true);
thr = row_ins_step(thr);
} else if (type == QUE_NODE_UPDATE) {
trx_start_if_not_started_xa(thr_get_trx(thr), true);
diff --git a/storage/innobase/read/read0read.cc b/storage/innobase/read/read0read.cc
index 2fb7083b0b2..5083236d359 100644
--- a/storage/innobase/read/read0read.cc
+++ b/storage/innobase/read/read0read.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, 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
the terms of the GNU General Public License as published by the Free Software
@@ -23,10 +24,11 @@ Cursor read
Created 2/16/1997 Heikki Tuuri
*******************************************************/
-#include "read0read.h"
+#include "read0types.h"
#include "srv0srv.h"
#include "trx0sys.h"
+#include "trx0purge.h"
/*
-------------------------------------------------------------------------------
@@ -162,8 +164,8 @@ For details see: row_vers_old_has_index_entry() and row_purge_poss_sec()
Some additional issues:
-What if trx_sys->view_list == NULL and some transaction T1 and Purge both
-try to open read_view at same time. Only one can acquire trx_sys->mutex.
+What if trx_sys.view_list == NULL and some transaction T1 and Purge both
+try to open read_view at same time. Only one can acquire trx_sys.mutex.
In which order will the views be opened? Should it matter? If no, why?
The order does not matter. No new transactions can be created and no running
@@ -171,611 +173,165 @@ RW transaction can commit or rollback (or free views). AC-NL-RO transactions
will mark their views as closed but not actually free their views.
*/
-/** Minimum number of elements to reserve in ReadView::ids_t */
-static const ulint MIN_TRX_IDS = 32;
-
-#ifdef UNIV_DEBUG
-/** Functor to validate the view list. */
-struct ViewCheck {
-
- ViewCheck() : m_prev_view() { }
-
- void operator()(const ReadView* view)
- {
- ut_a(m_prev_view == NULL
- || view->is_closed()
- || view->le(m_prev_view));
-
- m_prev_view = view;
- }
-
- const ReadView* m_prev_view;
-};
-
-/**
-Validates a read view list. */
-
-bool
-MVCC::validate() const
-{
- ViewCheck check;
-
- ut_ad(mutex_own(&trx_sys->mutex));
-
- ut_list_map(m_views, check);
-
- return(true);
-}
-#endif /* UNIV_DEBUG */
/**
-Try and increase the size of the array. Old elements are
-copied across.
-@param n Make space for n elements */
+ Creates a snapshot where exactly the transactions serialized before this
+ point in time are seen in the view.
-void
-ReadView::ids_t::reserve(ulint n)
-{
- if (n <= capacity()) {
- return;
- }
-
- /** Keep a minimum threshold */
- if (n < MIN_TRX_IDS) {
- n = MIN_TRX_IDS;
- }
-
- value_type* p = m_ptr;
-
- m_ptr = UT_NEW_ARRAY_NOKEY(value_type, n);
-
- m_reserved = n;
-
- ut_ad(size() < capacity());
-
- if (p != NULL) {
-
- ::memmove(m_ptr, p, size() * sizeof(value_type));
-
- UT_DELETE_ARRAY(p);
- }
-}
-
-/**
-Copy and overwrite this array contents
-@param start Source array
-@param end Pointer to end of array */
-
-void
-ReadView::ids_t::assign(const value_type* start, const value_type* end)
-{
- ut_ad(end >= start);
-
- ulint n = end - start;
-
- /* No need to copy the old contents across during reserve(). */
- clear();
-
- /* Create extra space if required. */
- reserve(n);
-
- resize(n);
-
- ut_ad(size() == n);
-
- ::memmove(m_ptr, start, size() * sizeof(value_type));
-}
-
-/**
-Append a value to the array.
-@param value the value to append */
-
-void
-ReadView::ids_t::push_back(value_type value)
-{
- if (capacity() <= size()) {
- reserve(size() * 2);
- }
-
- m_ptr[m_size++] = value;
- ut_ad(size() <= capacity());
-}
-
-/**
-Insert the value in the correct slot, preserving the order. Doesn't
-check for duplicates. */
-
-void
-ReadView::ids_t::insert(value_type value)
-{
- ut_ad(value > 0);
-
- reserve(size() + 1);
-
- if (empty() || back() < value) {
- push_back(value);
- return;
- }
-
- value_type* end = data() + size();
- value_type* ub = std::upper_bound(data(), end, value);
-
- if (ub == end) {
- push_back(value);
- } else {
- ut_ad(ub < end);
-
- ulint n_elems = std::distance(ub, end);
- ulint n = n_elems * sizeof(value_type);
-
- /* Note: Copying overlapped memory locations. */
- ::memmove(ub + 1, ub, n);
-
- *ub = value;
-
- resize(size() + 1);
- }
-}
-
-/**
-ReadView constructor */
-ReadView::ReadView()
- :
- m_low_limit_id(),
- m_up_limit_id(),
- m_creator_trx_id(),
- m_ids(),
- m_low_limit_no()
-{
- ut_d(::memset(&m_view_list, 0x0, sizeof(m_view_list)));
-}
-
-/**
-ReadView destructor */
-ReadView::~ReadView()
-{
- // Do nothing
-}
-
-/** Constructor
-@param size Number of views to pre-allocate */
-MVCC::MVCC(ulint size)
-{
- UT_LIST_INIT(m_free, &ReadView::m_view_list);
- UT_LIST_INIT(m_views, &ReadView::m_view_list);
-
- for (ulint i = 0; i < size; ++i) {
- ReadView* view = UT_NEW_NOKEY(ReadView());
-
- UT_LIST_ADD_FIRST(m_free, view);
- }
-}
-
-MVCC::~MVCC()
-{
- for (ReadView* view = UT_LIST_GET_FIRST(m_free);
- view != NULL;
- view = UT_LIST_GET_FIRST(m_free)) {
-
- UT_LIST_REMOVE(m_free, view);
-
- UT_DELETE(view);
- }
-
- ut_a(UT_LIST_GET_LEN(m_views) == 0);
-}
-
-/**
-Copy the transaction ids from the source vector */
-
-void
-ReadView::copy_trx_ids(const trx_ids_t& trx_ids)
-{
- ulint size = trx_ids.size();
-
- if (m_creator_trx_id > 0) {
- ut_ad(size > 0);
- --size;
- }
-
- if (size == 0) {
- m_ids.clear();
- return;
- }
-
- m_ids.reserve(size);
- m_ids.resize(size);
-
- ids_t::value_type* p = m_ids.data();
-
- /* Copy all the trx_ids except the creator trx id */
-
- if (m_creator_trx_id > 0) {
-
- /* Note: We go through all this trouble because it is
- unclear whether std::vector::resize() will cause an
- overhead or not. We should test this extensively and
- if the vector to vector copy is fast enough then get
- rid of this code and replace it with more readable
- and obvious code. The code below does exactly one copy,
- and filters out the creator's trx id. */
-
- trx_ids_t::const_iterator it = std::lower_bound(
- trx_ids.begin(), trx_ids.end(), m_creator_trx_id);
-
- ut_ad(it != trx_ids.end() && *it == m_creator_trx_id);
-
- ulint i = std::distance(trx_ids.begin(), it);
- ulint n = i * sizeof(trx_ids_t::value_type);
-
- ::memmove(p, &trx_ids[0], n);
-
- n = (trx_ids.size() - i - 1) * sizeof(trx_ids_t::value_type);
-
- ut_ad(i + (n / sizeof(trx_ids_t::value_type)) == m_ids.size());
-
- if (n > 0) {
- ::memmove(p + i, &trx_ids[i + 1], n);
- }
- } else {
- ulint n = size * sizeof(trx_ids_t::value_type);
-
- ::memmove(p, &trx_ids[0], n);
- }
-
-#ifdef UNIV_DEBUG
- /* Assert that all transaction ids in list are active. */
- for (trx_ids_t::const_iterator it = trx_ids.begin();
- it != trx_ids.end(); ++it) {
-
- trx_t* trx = trx_get_rw_trx_by_id(*it);
- ut_ad(trx != NULL);
- ut_ad(trx->state == TRX_STATE_ACTIVE
- || trx->state == TRX_STATE_PREPARED);
- }
-#endif /* UNIV_DEBUG */
-}
-
-/**
-Opens a read view where exactly the transactions serialized before this
-point in time are seen in the view.
-@param id Creator transaction id */
-
-void
-ReadView::prepare(trx_id_t id)
-{
- ut_ad(mutex_own(&trx_sys->mutex));
-
- m_creator_trx_id = id;
-
- m_low_limit_no = m_low_limit_id = trx_sys->max_trx_id;
-
- if (!trx_sys->rw_trx_ids.empty()) {
- copy_trx_ids(trx_sys->rw_trx_ids);
- } else {
- m_ids.clear();
- }
-
- if (UT_LIST_GET_LEN(trx_sys->serialisation_list) > 0) {
- const trx_t* trx;
-
- trx = UT_LIST_GET_FIRST(trx_sys->serialisation_list);
-
- if (trx->no < m_low_limit_no) {
- m_low_limit_no = trx->no;
- }
- }
-}
-
-/**
-Complete the read view creation */
-
-void
-ReadView::complete()
-{
- /* The first active transaction has the smallest id. */
- m_up_limit_id = !m_ids.empty() ? m_ids.front() : m_low_limit_id;
-
- ut_ad(m_up_limit_id <= m_low_limit_id);
-
- m_closed = false;
-}
-
-/**
-Find a free view from the active list, if none found then allocate
-a new view.
-@return a view to use */
-
-ReadView*
-MVCC::get_view()
+ @param[in,out] trx transaction
+*/
+void ReadView::snapshot(trx_t *trx)
{
- ut_ad(mutex_own(&trx_sys->mutex));
-
- ReadView* view;
-
- if (UT_LIST_GET_LEN(m_free) > 0) {
- view = UT_LIST_GET_FIRST(m_free);
- UT_LIST_REMOVE(m_free, view);
- } else {
- view = UT_NEW_NOKEY(ReadView());
-
- if (view == NULL) {
- ib::error() << "Failed to allocate MVCC view";
- }
- }
-
- return(view);
+ trx_sys.snapshot_ids(trx, &m_ids, &m_low_limit_id, &m_low_limit_no);
+ std::sort(m_ids.begin(), m_ids.end());
+ m_up_limit_id= m_ids.empty() ? m_low_limit_id : m_ids.front();
+ ut_ad(m_up_limit_id <= m_low_limit_id);
}
-/**
-Release a view that is inactive but not closed. Caller must own
-the trx_sys_t::mutex.
-@param view View to release */
-void
-MVCC::view_release(ReadView*& view)
-{
- ut_ad(!srv_read_only_mode);
- ut_ad(trx_sys_mutex_own());
-
- uintptr_t p = reinterpret_cast<uintptr_t>(view);
-
- ut_a(p & 0x1);
-
- view = reinterpret_cast<ReadView*>(p & ~1);
-
- ut_ad(view->m_closed);
-
- /** RW transactions should not free their views here. Their views
- should freed using view_close_view() */
-
- ut_ad(view->m_creator_trx_id == 0);
-
- UT_LIST_REMOVE(m_views, view);
-
- UT_LIST_ADD_LAST(m_free, view);
-
- view = NULL;
-}
/**
-Allocate and create a view.
-@param view view owned by this class created for the
- caller. Must be freed by calling view_close()
-@param trx transaction instance of caller */
-void
-MVCC::view_open(ReadView*& view, trx_t* trx)
-{
- ut_ad(!srv_read_only_mode);
-
- /** If no new RW transaction has been started since the last view
- was created then reuse the the existing view. */
- if (view != NULL) {
-
- uintptr_t p = reinterpret_cast<uintptr_t>(view);
-
- view = reinterpret_cast<ReadView*>(p & ~1);
-
- ut_ad(view->m_closed);
-
- /* NOTE: This can be optimised further, for now we only
- resuse the view iff there are no active RW transactions.
-
- There is an inherent race here between purge and this
- thread. Purge will skip views that are marked as closed.
- Therefore we must set the low limit id after we reset the
- closed status after the check. */
-
- if (trx_is_autocommit_non_locking(trx) && view->empty()) {
-
- view->m_closed = false;
-
- if (view->m_low_limit_id == trx_sys_get_max_trx_id()) {
- return;
- } else {
- view->m_closed = true;
- }
- }
-
- mutex_enter(&trx_sys->mutex);
-
- UT_LIST_REMOVE(m_views, view);
+ Opens a read view where exactly the transactions serialized before this
+ point in time are seen in the view.
- } else {
- mutex_enter(&trx_sys->mutex);
+ View becomes visible to purge thread via trx_sys.m_views.
- view = get_view();
- }
-
- if (view != NULL) {
-
- view->prepare(trx->id);
-
- view->complete();
-
- UT_LIST_ADD_FIRST(m_views, view);
-
- ut_ad(!view->is_closed());
-
- ut_ad(validate());
- }
-
- trx_sys_mutex_exit();
-}
-
-/**
-Get the oldest (active) view in the system.
-@return oldest view if found or NULL */
-
-ReadView*
-MVCC::get_oldest_view() const
+ @param[in,out] trx transaction
+*/
+void ReadView::open(trx_t *trx)
{
- ReadView* view;
-
- ut_ad(mutex_own(&trx_sys->mutex));
-
- for (view = UT_LIST_GET_LAST(m_views);
- view != NULL;
- view = UT_LIST_GET_PREV(m_view_list, view)) {
-
- if (!view->is_closed()) {
- break;
- }
- }
-
- return(view);
+ ut_ad(this == &trx->read_view);
+ switch (m_state)
+ {
+ case READ_VIEW_STATE_OPEN:
+ ut_ad(!srv_read_only_mode);
+ return;
+ case READ_VIEW_STATE_REGISTERED:
+ ut_ad(!srv_read_only_mode);
+ /*
+ Reuse closed view if there were no read-write transactions since (and at)
+ its creation time.
+
+ Original comment states: there is an inherent race here between purge
+ and this thread.
+
+ To avoid this race we should've checked trx_sys.get_max_trx_id() and
+ set state to READ_VIEW_STATE_OPEN atomically under trx_sys.mutex
+ protection. But we're cutting edges to achieve great scalability.
+
+ There're at least two types of concurrent threads interested in this
+ value: purge coordinator thread (see trx_sys_t::clone_oldest_view()) and
+ InnoDB monitor thread (see lock_trx_print_wait_and_mvcc_state()).
+
+ What bad things can happen because we allow this race?
+
+ First, purge thread may be affected by this race condition only if this
+ view is the oldest open view. In other words this view is either last in
+ m_views list or there're no open views beyond.
+
+ In this case purge may not catch this view and clone some younger view
+ instead. It might be kind of alright, because there were no read-write
+ transactions and there should be nothing to purge. Besides younger view
+ must have exactly the same values.
+
+ Second, scary things start when there's a read-write transaction starting
+ concurrently.
+
+ Speculative execution may reorder state change before get_max_trx_id().
+ In this case purge thread has short gap to clone outdated view. Which is
+ probably not that bad: it just won't be able to purge things that it was
+ actually allowed to purge for a short while.
+
+ This thread may as well get suspended after trx_sys.get_max_trx_id() and
+ before state is set to READ_VIEW_STATE_OPEN. New read-write transaction
+ may get started, committed and purged meanwhile. It is acceptable as
+ well, since this view doesn't see it.
+ */
+ if (trx_is_autocommit_non_locking(trx) && m_ids.empty() &&
+ m_low_limit_id == trx_sys.get_max_trx_id())
+ goto reopen;
+
+ /*
+ Can't reuse view, take new snapshot.
+
+ Alas this empty critical section is simplest way to make sure concurrent
+ purge thread completed snapshot copy. Of course purge thread may come
+ again and try to copy once again after we release this mutex, but in
+ this case it is guaranteed to see READ_VIEW_STATE_REGISTERED and thus
+ it'll skip this view.
+
+ This critical section can be replaced with new state, which purge thread
+ would set to inform us to wait until it completes snapshot. However it'd
+ complicate m_state even further.
+ */
+ mutex_enter(&trx_sys.mutex);
+ mutex_exit(&trx_sys.mutex);
+ my_atomic_store32_explicit(&m_state, READ_VIEW_STATE_SNAPSHOT,
+ MY_MEMORY_ORDER_RELAXED);
+ break;
+ case READ_VIEW_STATE_CLOSED:
+ if (srv_read_only_mode)
+ return;
+ m_state= READ_VIEW_STATE_SNAPSHOT;
+ trx_sys.register_view(this);
+ break;
+ default:
+ ut_ad(0);
+ }
+
+ snapshot(trx);
+reopen:
+ m_creator_trx_id= trx->id;
+ my_atomic_store32_explicit(&m_state, READ_VIEW_STATE_OPEN,
+ MY_MEMORY_ORDER_RELEASE);
}
-/**
-Copy state from another view. Must call copy_complete() to finish.
-@param other view to copy from */
-
-void
-ReadView::copy_prepare(const ReadView& other)
-{
- ut_ad(&other != this);
-
- if (!other.m_ids.empty()) {
- const ids_t::value_type* p = other.m_ids.data();
-
- m_ids.assign(p, p + other.m_ids.size());
- } else {
- m_ids.clear();
- }
-
- m_up_limit_id = other.m_up_limit_id;
-
- m_low_limit_no = other.m_low_limit_no;
-
- m_low_limit_id = other.m_low_limit_id;
-
- m_creator_trx_id = other.m_creator_trx_id;
-}
/**
-Complete the copy, insert the creator transaction id into the
-m_ids too and adjust the m_up_limit_id, if required */
+ Closes the view.
-void
-ReadView::copy_complete()
-{
- ut_ad(!trx_sys_mutex_own());
-
- if (m_creator_trx_id > 0) {
- m_ids.insert(m_creator_trx_id);
- }
-
- if (!m_ids.empty()) {
- /* The last active transaction has the smallest id. */
- m_up_limit_id = std::min(m_ids.front(), m_up_limit_id);
- }
-
- ut_ad(m_up_limit_id <= m_low_limit_id);
-
- /* We added the creator transaction ID to the m_ids. */
- m_creator_trx_id = 0;
-}
-
-/** Clones the oldest view and stores it in view. No need to
-call view_close(). The caller owns the view that is passed in.
-This function is called by Purge to determine whether it should
-purge the delete marked record or not.
-@param view Preallocated view, owned by the caller */
-
-void
-MVCC::clone_oldest_view(ReadView* view)
+ The view will become invisible to purge (deregistered from trx_sys).
+*/
+void ReadView::close()
{
- mutex_enter(&trx_sys->mutex);
-
- ReadView* oldest_view = get_oldest_view();
-
- if (oldest_view == NULL) {
-
- view->prepare(0);
-
- trx_sys_mutex_exit();
-
- view->complete();
-
- } else {
- view->copy_prepare(*oldest_view);
-
- trx_sys_mutex_exit();
-
- view->copy_complete();
- }
+ ut_ad(m_state == READ_VIEW_STATE_OPEN ||
+ m_state == READ_VIEW_STATE_REGISTERED ||
+ m_state == READ_VIEW_STATE_CLOSED);
+ if (m_state != READ_VIEW_STATE_CLOSED)
+ {
+ trx_sys.deregister_view(this);
+ m_state= READ_VIEW_STATE_CLOSED;
+ }
}
-/**
-@return the number of active views */
-
-ulint
-MVCC::size() const
-{
- trx_sys_mutex_enter();
-
- ulint size = 0;
-
- for (const ReadView* view = UT_LIST_GET_FIRST(m_views);
- view != NULL;
- view = UT_LIST_GET_NEXT(m_view_list, view)) {
-
- if (!view->is_closed()) {
- ++size;
- }
- }
-
- trx_sys_mutex_exit();
-
- return(size);
-}
/**
-Close a view created by the above function.
-@para view view allocated by trx_open.
-@param own_mutex true if caller owns trx_sys_t::mutex */
+ Clones the oldest view and stores it in view.
-void
-MVCC::view_close(ReadView*& view, bool own_mutex)
-{
- uintptr_t p = reinterpret_cast<uintptr_t>(view);
-
- /* Note: The assumption here is that AC-NL-RO transactions will
- call this function with own_mutex == false. */
- if (!own_mutex) {
- /* Sanitise the pointer first. */
- ReadView* ptr = reinterpret_cast<ReadView*>(p & ~1);
-
- /* Note this can be called for a read view that
- was already closed. */
- ptr->m_closed = true;
-
- /* Set the view as closed. */
- view = reinterpret_cast<ReadView*>(p | 0x1);
- } else {
- view = reinterpret_cast<ReadView*>(p & ~1);
-
- view->close();
-
- UT_LIST_REMOVE(m_views, view);
- UT_LIST_ADD_LAST(m_free, view);
-
- ut_ad(validate());
+ No need to call ReadView::close(). The caller owns the view that is passed
+ in. This function is called by purge thread to determine whether it should
+ purge the delete marked record or not.
- view = NULL;
- }
-}
-
-/**
-Set the view creator transaction id. Note: This shouldbe set only
-for views created by RW transactions.
-@param view Set the creator trx id for this view
-@param id Transaction id to set */
-
-void
-MVCC::set_view_creator_trx_id(ReadView* view, trx_id_t id)
+ Since foreign views are accessed under the mutex protection, the only
+ possible state transfers are
+ READ_VIEW_STATE_SNAPSHOT -> READ_VIEW_STATE_OPEN
+ READ_VIEW_STATE_OPEN -> READ_VIEW_STATE_REGISTERED
+ All other state transfers are eliminated by the mutex.
+*/
+void trx_sys_t::clone_oldest_view()
{
- ut_ad(id > 0);
- ut_ad(mutex_own(&trx_sys->mutex));
-
- view->creator_trx_id(id);
+ purge_sys.view.snapshot(0);
+ mutex_enter(&mutex);
+ /* Find oldest view. */
+ for (const ReadView *v= UT_LIST_GET_FIRST(m_views); v;
+ v= UT_LIST_GET_NEXT(m_view_list, v))
+ {
+ int32_t state;
+
+ while ((state= v->get_state()) == READ_VIEW_STATE_SNAPSHOT)
+ ut_delay(1);
+
+ if (state == READ_VIEW_STATE_OPEN)
+ purge_sys.view.copy(*v);
+ }
+ mutex_exit(&mutex);
}
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index 8fb24855e97..dcc435c091f 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -240,7 +240,7 @@ rec_get_n_extern_new(
/** Get the length of added field count in a REC_STATUS_COLUMNS_ADDED record.
@param[in] n_add_field number of added fields, minus one
@return storage size of the field count, in bytes */
-static inline unsigned rec_get_n_add_field_len(unsigned n_add_field)
+static inline unsigned rec_get_n_add_field_len(ulint n_add_field)
{
ut_ad(n_add_field < REC_MAX_N_FIELDS);
return n_add_field < 0x80 ? 1 : 2;
@@ -268,7 +268,7 @@ static inline unsigned rec_get_n_add_field(const byte*& header)
@param[in,out] header variable header of a REC_STATUS_COLUMNS_ADDED record
@param[in] n_add number of added fields, minus 1
@return record header before the number of added fields */
-static inline void rec_set_n_add_field(byte*& header, unsigned n_add)
+static inline void rec_set_n_add_field(byte*& header, ulint n_add)
{
ut_ad(n_add < REC_MAX_N_FIELDS);
@@ -344,9 +344,6 @@ ordinary:
/* We would have !index->is_instant() when rolling back
an instant ADD COLUMN operation. */
nulls -= REC_N_NEW_EXTRA_BYTES;
- if (rec_offs_n_fields(offsets) <= n_fields) {
- goto ordinary;
- }
/* fall through */
case REC_LEAF_TEMP_COLUMNS_ADDED:
ut_ad(index->is_instant());
@@ -1157,21 +1154,18 @@ rec_get_converted_size_comp_prefix_low(
if (fixed_len) {
#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
-
ut_ad(len <= fixed_len);
if (dict_index_is_spatial(index)) {
ut_ad(type->mtype == DATA_SYS_CHILD
- || !mbmaxlen
- || len >= mbminlen * (fixed_len
- / mbmaxlen));
+ || !col->mbmaxlen
+ || len >= col->mbminlen
+ * fixed_len / col->mbmaxlen);
} else {
ut_ad(type->mtype != DATA_SYS_CHILD);
- ut_ad(!mbmaxlen
- || len >= mbminlen * (fixed_len
- / mbmaxlen));
+ ut_ad(!col->mbmaxlen
+ || len >= col->mbminlen
+ * fixed_len / col->mbmaxlen);
}
/* dict_index_add_col() should guarantee this */
@@ -1570,15 +1564,11 @@ rec_convert_dtuple_to_rec_comp(
0..127. The length will be encoded in two bytes when
it is 128 or more, or when the field is stored externally. */
if (fixed_len) {
-#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
-
ut_ad(len <= fixed_len);
- ut_ad(!mbmaxlen || len >= mbminlen
- * (fixed_len / mbmaxlen));
+ ut_ad(!col->mbmaxlen
+ || len >= col->mbminlen
+ * fixed_len / col->mbmaxlen);
ut_ad(!dfield_is_ext(field));
-#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(field)) {
ut_ad(DATA_BIG_COL(col));
ut_ad(len <= REC_ANTELOPE_MAX_INDEX_COL_LEN
@@ -1851,6 +1841,7 @@ rec_copy_prefix_to_buf(
ulint null_mask;
bool is_rtr_node_ptr = false;
+ ut_ad(n_fields <= index->n_fields || dict_index_is_ibuf(index));
ut_ad(index->n_core_null_bytes <= UT_BITS_IN_BYTES(index->n_nullable));
UNIV_PREFETCH_RW(*buf);
@@ -1863,21 +1854,11 @@ rec_copy_prefix_to_buf(
}
switch (rec_get_status(rec)) {
- case REC_STATUS_COLUMNS_ADDED:
- /* We would have !index->is_instant() when rolling back
- an instant ADD COLUMN operation. */
- ut_ad(index->is_instant() || page_rec_is_default_row(rec));
- if (n_fields >= index->n_core_fields) {
- ut_ad(index->is_instant());
- ut_ad(n_fields <= index->n_fields);
- nulls = &rec[-REC_N_NEW_EXTRA_BYTES];
- const ulint n_rec = n_fields + 1
- + rec_get_n_add_field(nulls);
- const uint n_nullable = index->get_n_nullable(n_rec);
- lens = --nulls - UT_BITS_IN_BYTES(n_nullable);
- break;
- }
- /* fall through */
+ case REC_STATUS_INFIMUM:
+ case REC_STATUS_SUPREMUM:
+ /* infimum or supremum record: no sense to copy anything */
+ ut_error;
+ return(NULL);
case REC_STATUS_ORDINARY:
ut_ad(n_fields <= index->n_core_fields);
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
@@ -1897,11 +1878,15 @@ rec_copy_prefix_to_buf(
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
lens = nulls - index->n_core_null_bytes;
break;
- case REC_STATUS_INFIMUM:
- case REC_STATUS_SUPREMUM:
- /* infimum or supremum record: no sense to copy anything */
- ut_error;
- return(NULL);
+ case REC_STATUS_COLUMNS_ADDED:
+ /* We would have !index->is_instant() when rolling back
+ an instant ADD COLUMN operation. */
+ ut_ad(index->is_instant() || page_rec_is_default_row(rec));
+ nulls = &rec[-REC_N_NEW_EXTRA_BYTES];
+ const ulint n_rec = index->n_core_fields + 1
+ + rec_get_n_add_field(nulls);
+ const uint n_nullable = index->get_n_nullable(n_rec);
+ lens = --nulls - UT_BITS_IN_BYTES(n_nullable);
}
UNIV_PREFETCH_R(lens);
@@ -2492,8 +2477,6 @@ rec_get_trx_id(
const rec_t* rec,
const dict_index_t* index)
{
- const page_t* page
- = page_align(rec);
ulint trx_id_col
= dict_index_get_sys_col_pos(index, DATA_TRX_ID);
const byte* trx_id;
@@ -2504,11 +2487,7 @@ rec_get_trx_id(
ulint* offsets = offsets_;
ut_ad(trx_id_col <= MAX_REF_PARTS);
- ut_ad(fil_page_index_page_check(page));
- ut_ad(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID)
- == index->id);
ut_ad(dict_index_is_clust(index));
- ut_ad(page_rec_is_leaf(rec));
ut_ad(trx_id_col > 0);
ut_ad(trx_id_col != ULINT_UNDEFINED);
diff --git a/storage/innobase/row/row0ext.cc b/storage/innobase/row/row0ext.cc
index 72c68940d11..503f7d0d3e7 100644
--- a/storage/innobase/row/row0ext.cc
+++ b/storage/innobase/row/row0ext.cc
@@ -70,7 +70,7 @@ row_ext_cache_fill(
} else {
/* Fetch at most ext->max_len of the column.
The column should be non-empty. However,
- trx_rollback_or_clean_all_recovered() may try to
+ trx_rollback_all_recovered() may try to
access a half-deleted BLOB if the server previously
crashed during the execution of
btr_free_externally_stored_field(). */
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 5d4824f0aae..ef7e92e3a23 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -108,8 +108,9 @@ row_merge_create_fts_sort_index(
field->col->prtype = idx_field->col->prtype | DATA_NOT_NULL;
field->col->mtype = charset == &my_charset_latin1
? DATA_VARCHAR : DATA_VARMYSQL;
- field->col->mbminmaxlen = idx_field->col->mbminmaxlen;
- field->col->len = HA_FT_MAXCHARLEN * DATA_MBMAXLEN(field->col->mbminmaxlen);
+ field->col->mbminlen = idx_field->col->mbminlen;
+ field->col->mbmaxlen = idx_field->col->mbmaxlen;
+ field->col->len = HA_FT_MAXCHARLEN * field->col->mbmaxlen;
field->fixed_len = 0;
@@ -152,7 +153,8 @@ row_merge_create_fts_sort_index(
field->col->prtype = DATA_NOT_NULL | DATA_BINARY_TYPE;
- field->col->mbminmaxlen = 0;
+ field->col->mbminlen = 0;
+ field->col->mbmaxlen = 0;
/* The third field is on the word's position in the original doc */
field = dict_index_get_nth_field(new_index, 2);
@@ -164,7 +166,8 @@ row_merge_create_fts_sort_index(
field->col->len = 4 ;
field->fixed_len = 4;
field->col->prtype = DATA_NOT_NULL;
- field->col->mbminmaxlen = 0;
+ field->col->mbminlen = 0;
+ field->col->mbmaxlen = 0;
return(new_index);
}
@@ -658,7 +661,8 @@ row_merge_fts_doc_tokenize(
field->type.mtype = DATA_INT;
field->type.prtype = DATA_NOT_NULL | DATA_BINARY_TYPE;
field->type.len = len;
- field->type.mbminmaxlen = 0;
+ field->type.mbminlen = 0;
+ field->type.mbmaxlen = 0;
cur_len += len;
dfield_dup(field, buf->heap);
@@ -669,7 +673,7 @@ row_merge_fts_doc_tokenize(
MySQL 5.7 changed the fulltext parser plugin interface
by adding MYSQL_FTPARSER_BOOLEAN_INFO::position.
Below we assume that the field is always 0. */
- unsigned pos = t_ctx->init_pos;
+ ulint pos = t_ctx->init_pos;
byte position[4];
if (parser == NULL) {
pos += t_ctx->processed_len + inc - str.f_len;
@@ -681,7 +685,8 @@ row_merge_fts_doc_tokenize(
field->type.mtype = DATA_INT;
field->type.prtype = DATA_NOT_NULL;
field->type.len = len;
- field->type.mbminmaxlen = 0;
+ field->type.mbminlen = 0;
+ field->type.mbmaxlen = 0;
cur_len += len;
dfield_dup(field, buf->heap);
@@ -761,7 +766,7 @@ It also performs the initial in memory sort of the parsed records.
@return OS_THREAD_DUMMY_RETURN */
static
os_thread_ret_t
-fts_parallel_tokenization(
+DECLARE_THREAD(fts_parallel_tokenization)(
/*======================*/
void* arg) /*!< in: psort_info for the thread */
{
@@ -1101,7 +1106,7 @@ Function performs the merge and insertion of the sorted records.
@return OS_THREAD_DUMMY_RETURN */
static
os_thread_ret_t
-fts_parallel_merge(
+DECLARE_THREAD(fts_parallel_merge)(
/*===============*/
void* arg) /*!< in: parallel merge info */
{
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 9ea0bdd949c..6caffb8f0ab 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -32,11 +32,11 @@ Created 2012-02-08 by Sunny Bains.
#include "dict0boot.h"
#include "ibuf0ibuf.h"
#include "pars0pars.h"
-#include "row0upd.h"
#include "row0sel.h"
#include "row0mysql.h"
#include "srv0start.h"
#include "row0quiesce.h"
+#include "trx0undo.h"
#include "ut0new.h"
#include <vector>
@@ -725,7 +725,7 @@ FetchIndexRootPages::build_row_import(row_import* cfg) const UNIV_NOTHROW
char name[BUFSIZ];
- ut_snprintf(name, sizeof(name), "index" IB_ID_FMT, it->m_id);
+ snprintf(name, sizeof(name), "index" IB_ID_FMT, it->m_id);
ulint len = strlen(name) + 1;
@@ -897,13 +897,11 @@ private:
@param index the index being converted
@param rec record to update
@param offsets column offsets for the record
- @param deleted true if row is delete marked
@return DB_SUCCESS or error code. */
dberr_t adjust_cluster_record(
const dict_index_t* index,
rec_t* rec,
- const ulint* offsets,
- bool deleted) UNIV_NOTHROW;
+ const ulint* offsets) UNIV_NOTHROW;
/** Find an index with the matching id.
@return row_index_t* instance or 0 */
@@ -1202,7 +1200,8 @@ row_import::match_table_columns(
err = DB_ERROR;
}
- if (cfg_col->mbminmaxlen != col->mbminmaxlen) {
+ if (cfg_col->mbminlen != col->mbminlen
+ || cfg_col->mbmaxlen != col->mbmaxlen) {
ib_errf(thd,
IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
@@ -1681,14 +1680,12 @@ PageConverter::purge(const ulint* offsets) UNIV_NOTHROW
/** Adjust the BLOB references and sys fields for the current record.
@param rec record to update
@param offsets column offsets for the record
-@param deleted true if row is delete marked
@return DB_SUCCESS or error code. */
dberr_t
PageConverter::adjust_cluster_record(
const dict_index_t* index,
rec_t* rec,
- const ulint* offsets,
- bool deleted) UNIV_NOTHROW
+ const ulint* offsets) UNIV_NOTHROW
{
dberr_t err;
@@ -1697,10 +1694,20 @@ PageConverter::adjust_cluster_record(
/* Reset DB_TRX_ID and DB_ROLL_PTR. Normally, these fields
are only written in conjunction with other changes to the
record. */
-
- row_upd_rec_sys_fields(
- rec, m_page_zip_ptr, m_cluster_index, m_offsets,
- m_trx, 0);
+ ulint trx_id_pos = m_cluster_index->n_uniq
+ ? m_cluster_index->n_uniq : 1;
+ if (m_page_zip_ptr) {
+ page_zip_write_trx_id_and_roll_ptr(
+ m_page_zip_ptr, rec, m_offsets, trx_id_pos,
+ 0, roll_ptr_t(1) << ROLL_PTR_INSERT_FLAG_POS,
+ NULL);
+ } else {
+ ulint len;
+ byte* ptr = rec_get_nth_field(
+ rec, m_offsets, trx_id_pos, &len);
+ ut_ad(len == DATA_TRX_ID_LEN);
+ memcpy(ptr, reset_trx_id, sizeof reset_trx_id);
+ }
}
return(err);
@@ -1743,8 +1750,7 @@ PageConverter::update_records(
if (clust_index) {
dberr_t err = adjust_cluster_record(
- m_index->m_srv_index, rec, m_offsets,
- deleted);
+ m_index->m_srv_index, rec, m_offsets);
if (err != DB_SUCCESS) {
return(err);
@@ -2483,7 +2489,7 @@ row_import_cfg_read_index_fields(
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while reading index fields.");
return(DB_IO_ERROR);
@@ -2519,7 +2525,7 @@ row_import_cfg_read_index_fields(
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while parsing table name.");
return(err);
@@ -2581,15 +2587,15 @@ row_import_read_index_data(
if (n_bytes != sizeof(row)) {
char msg[BUFSIZ];
- ut_snprintf(msg, sizeof(msg),
- "while reading index meta-data, expected "
- "to read " ULINTPF
- " bytes but read only " ULINTPF " bytes",
- sizeof(row), n_bytes);
+ snprintf(msg, sizeof(msg),
+ "while reading index meta-data, expected "
+ "to read " ULINTPF
+ " bytes but read only " ULINTPF " bytes",
+ sizeof(row), n_bytes);
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno), msg);
+ (ulong) errno, strerror(errno), msg);
ib::error() << "IO Error: " << msg;
@@ -2664,7 +2670,7 @@ row_import_read_index_data(
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while parsing index name.");
return(err);
@@ -2703,7 +2709,7 @@ row_import_read_indexes(
if (fread(row, 1, sizeof(row), file) != sizeof(row)) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while reading number of indexes.");
return(DB_IO_ERROR);
@@ -2789,7 +2795,7 @@ row_import_read_columns(
if (fread(row, 1, sizeof(row), file) != sizeof(row)) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while reading table column meta-data.");
return(DB_IO_ERROR);
@@ -2804,7 +2810,9 @@ row_import_read_columns(
col->len = mach_read_from_4(ptr);
ptr += sizeof(ib_uint32_t);
- col->mbminmaxlen = mach_read_from_4(ptr);
+ ulint mbminmaxlen = mach_read_from_4(ptr);
+ col->mbmaxlen = mbminmaxlen / 5;
+ col->mbminlen = mbminmaxlen % 5;
ptr += sizeof(ib_uint32_t);
col->ind = mach_read_from_4(ptr);
@@ -2853,7 +2861,7 @@ row_import_read_columns(
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while parsing table column name.");
return(err);
@@ -2884,7 +2892,7 @@ row_import_read_v1(
if (fread(value, 1, sizeof(value), file) != sizeof(value)) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while reading meta-data export hostname length.");
return(DB_IO_ERROR);
@@ -2912,7 +2920,7 @@ row_import_read_v1(
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while parsing export hostname.");
return(err);
@@ -2926,7 +2934,7 @@ row_import_read_v1(
if (fread(value, 1, sizeof(value), file) != sizeof(value)) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while reading meta-data table name length.");
return(DB_IO_ERROR);
@@ -2953,7 +2961,7 @@ row_import_read_v1(
if (err != DB_SUCCESS) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while parsing table name.");
return(err);
@@ -2972,7 +2980,7 @@ row_import_read_v1(
if (fread(row, 1, sizeof(ib_uint64_t), file) != sizeof(ib_uint64_t)) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while reading autoinc value.");
return(DB_IO_ERROR);
@@ -2988,7 +2996,7 @@ row_import_read_v1(
if (fread(row, 1, sizeof(row), file) != sizeof(row)) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while reading meta-data header.");
return(DB_IO_ERROR);
@@ -3059,7 +3067,7 @@ row_import_read_meta_data(
if (fread(&row, 1, sizeof(row), file) != sizeof(row)) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while reading meta-data version.");
return(DB_IO_ERROR);
@@ -3104,13 +3112,13 @@ row_import_read_cfg(
if (file == NULL) {
char msg[BUFSIZ];
- ut_snprintf(msg, sizeof(msg),
- "Error opening '%s', will attempt to import"
- " without schema verification", name);
+ snprintf(msg, sizeof(msg),
+ "Error opening '%s', will attempt to import"
+ " without schema verification", name);
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_READ_ERROR,
- errno, strerror(errno), msg);
+ (ulong) errno, strerror(errno), msg);
cfg.m_missing = true;
@@ -3400,8 +3408,12 @@ row_import_for_mysql(
mutex_enter(&trx->undo_mutex);
/* TODO: Do not write any undo log for the IMPORT cleanup. */
- err = trx_undo_assign_undo(trx, trx->rsegs.m_redo.rseg,
- &trx->rsegs.m_redo.undo);
+ {
+ mtr_t mtr;
+ mtr.start();
+ trx_undo_assign(trx, &err, &mtr);
+ mtr.commit();
+ }
mutex_exit(&trx->undo_mutex);
@@ -3672,11 +3684,16 @@ row_import_for_mysql(
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, trx);
-
- if (trx_is_interrupted(trx)) {
- ib::info() << "Phase III - Flush interrupted";
- return(row_import_error(prebuilt, trx, DB_INTERRUPTED));
+ {
+ FlushObserver observer(prebuilt->table->space, trx, NULL);
+ buf_LRU_flush_or_remove_pages(prebuilt->table->space,
+ &observer);
+
+ if (observer.is_interrupted()) {
+ ib::info() << "Phase III - Flush interrupted";
+ return(row_import_error(prebuilt, trx,
+ DB_INTERRUPTED));
+ }
}
ib::info() << "Phase IV - Flush complete";
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 2200a2092bd..e87e857c812 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -45,7 +45,6 @@ Created 4/20/1996 Heikki Tuuri
#include "log0log.h"
#include "eval0eval.h"
#include "data0data.h"
-#include "usr0sess.h"
#include "buf0lru.h"
#include "fts0fts.h"
#include "fts0types.h"
@@ -139,49 +138,46 @@ row_ins_alloc_sys_fields(
{
dtuple_t* row;
dict_table_t* table;
- mem_heap_t* heap;
const dict_col_t* col;
dfield_t* dfield;
- byte* ptr;
row = node->row;
table = node->table;
- heap = node->entry_sys_heap;
- ut_ad(row && table && heap);
ut_ad(dtuple_get_n_fields(row) == dict_table_get_n_cols(table));
/* allocate buffer to hold the needed system created hidden columns. */
- const uint len = DATA_ROW_ID_LEN + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
- ptr = static_cast<byte*>(mem_heap_zalloc(heap, len));
+ compile_time_assert(DATA_ROW_ID_LEN
+ + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN
+ == sizeof node->sys_buf);
+ memset(node->sys_buf, 0, sizeof node->sys_buf);
+ /* Assign DB_ROLL_PTR to 1 << ROLL_PTR_INSERT_FLAG_POS */
+ node->sys_buf[DATA_ROW_ID_LEN + DATA_TRX_ID_LEN] = 0x80;
+ ut_ad(!memcmp(node->sys_buf + DATA_ROW_ID_LEN, reset_trx_id,
+ sizeof reset_trx_id));
/* 1. Populate row-id */
col = dict_table_get_sys_col(table, DATA_ROW_ID);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- dfield_set_data(dfield, ptr, DATA_ROW_ID_LEN);
-
- node->row_id_buf = ptr;
-
- ptr += DATA_ROW_ID_LEN;
+ dfield_set_data(dfield, node->sys_buf, DATA_ROW_ID_LEN);
/* 2. Populate trx id */
col = dict_table_get_sys_col(table, DATA_TRX_ID);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- dfield_set_data(dfield, ptr, DATA_TRX_ID_LEN);
-
- node->trx_id_buf = ptr;
-
- ptr += DATA_TRX_ID_LEN;
+ dfield_set_data(dfield, &node->sys_buf[DATA_ROW_ID_LEN],
+ DATA_TRX_ID_LEN);
col = dict_table_get_sys_col(table, DATA_ROLL_PTR);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN);
+ dfield_set_data(dfield, &node->sys_buf[DATA_ROW_ID_LEN
+ + DATA_TRX_ID_LEN],
+ DATA_ROLL_PTR_LEN);
}
/*********************************************************************//**
@@ -429,7 +425,7 @@ row_ins_cascade_ancestor_updates_table(
upd_node = static_cast<upd_node_t*>(parent);
- if (upd_node->table == table && upd_node->is_delete == FALSE) {
+ if (upd_node->table == table && !upd_node->is_delete) {
return(TRUE);
}
@@ -464,12 +460,9 @@ row_ins_cascade_n_ancestors(
/******************************************************************//**
Calculates the update vector node->cascade->update for a child table in
a cascaded update.
-@return number of fields in the calculated update vector; the value
-can also be 0 if no foreign key fields changed; the returned value is
-ULINT_UNDEFINED if the column type in the child table is too short to
-fit the new value in the parent table: that means the update fails */
+@return whether any FULLTEXT INDEX is affected */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
-ulint
+bool
row_ins_cascade_calc_update_vec(
/*============================*/
upd_node_t* node, /*!< in: update node of the parent
@@ -478,11 +471,9 @@ row_ins_cascade_calc_update_vec(
type is != 0 */
mem_heap_t* heap, /*!< in: memory heap to use as
temporary storage */
- trx_t* trx, /*!< in: update transaction */
- ibool* fts_col_affected,
- /*!< out: is FTS column affected */
- upd_node_t* cascade) /*!< in: cascade update node */
+ trx_t* trx) /*!< in: update transaction */
{
+ upd_node_t* cascade = node->cascade_node;
dict_table_t* table = foreign->foreign_table;
dict_index_t* index = foreign->foreign_index;
upd_t* update;
@@ -493,7 +484,7 @@ row_ins_cascade_calc_update_vec(
ulint parent_field_no;
ulint i;
ulint j;
- ibool doc_id_updated = FALSE;
+ bool doc_id_updated = false;
ulint doc_id_pos = 0;
doc_id_t new_doc_id = FTS_NULL_DOC_ID;
ulint prefix_col;
@@ -520,7 +511,7 @@ row_ins_cascade_calc_update_vec(
n_fields_updated = 0;
- *fts_col_affected = FALSE;
+ bool affects_fulltext = false;
if (table->fts) {
doc_id_pos = dict_table_get_nth_col_pos(
@@ -572,8 +563,7 @@ row_ins_cascade_calc_update_vec(
if (dfield_is_null(&ufield->new_val)
&& (col->prtype & DATA_NOT_NULL)) {
-
- return(ULINT_UNDEFINED);
+ goto err_exit;
}
/* If the new value would not fit in the
@@ -581,15 +571,15 @@ row_ins_cascade_calc_update_vec(
if (!dfield_is_null(&ufield->new_val)
&& dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype,
+ col->mbminlen, col->mbmaxlen,
col->len,
ufield_len,
static_cast<char*>(
dfield_get_data(
&ufield->new_val)))
< ufield_len) {
-
- return(ULINT_UNDEFINED);
+ goto err_exit;
}
/* If the parent column type has a different
@@ -633,7 +623,7 @@ row_ins_cascade_calc_update_vec(
col->prtype)
== DATA_MYSQL_BINARY_CHARSET_COLL) {
/* Do not pad BINARY columns */
- return(ULINT_UNDEFINED);
+ goto err_exit;
}
row_mysql_pad_col(mbminlen,
@@ -650,7 +640,7 @@ row_ins_cascade_calc_update_vec(
dict_col_get_no(col),
dict_col_is_virtual(col))
!= ULINT_UNDEFINED) {
- *fts_col_affected = TRUE;
+ affects_fulltext = true;
}
/* If Doc ID is updated, check whether the
@@ -667,11 +657,14 @@ row_ins_cascade_calc_update_vec(
dfield_get_data(
&ufield->new_val)));
+ affects_fulltext = true;
+ doc_id_updated = true;
+
if (new_doc_id <= 0) {
ib::error() << "FTS Doc ID"
" must be larger than"
" 0";
- return(ULINT_UNDEFINED);
+ goto err_exit;
}
if (new_doc_id < n_doc_id) {
@@ -680,12 +673,8 @@ row_ins_cascade_calc_update_vec(
<< n_doc_id - 1
<< " for table "
<< table->name;
-
- return(ULINT_UNDEFINED);
+ goto err_exit;
}
-
- *fts_col_affected = TRUE;
- doc_id_updated = TRUE;
}
n_fields_updated++;
@@ -693,8 +682,9 @@ row_ins_cascade_calc_update_vec(
}
}
- /* Generate a new Doc ID if FTS index columns get updated */
- if (table->fts && *fts_col_affected) {
+ if (affects_fulltext) {
+ ut_ad(table->fts);
+
if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
doc_id_t doc_id;
doc_id_t* next_doc_id;
@@ -708,24 +698,25 @@ row_ins_cascade_calc_update_vec(
fts_get_next_doc_id(table, next_doc_id);
doc_id = fts_update_doc_id(table, ufield, next_doc_id);
n_fields_updated++;
- cascade->fts_next_doc_id = doc_id;
+ fts_trx_add_op(trx, table, doc_id, FTS_INSERT, NULL);
} else {
if (doc_id_updated) {
ut_ad(new_doc_id);
- cascade->fts_next_doc_id = new_doc_id;
+ fts_trx_add_op(trx, table, new_doc_id,
+ FTS_INSERT, NULL);
} else {
- cascade->fts_next_doc_id = FTS_NULL_DOC_ID;
ib::error() << "FTS Doc ID must be updated"
" along with FTS indexed column for"
" table " << table->name;
- return(ULINT_UNDEFINED);
+err_exit:
+ n_fields_updated = ULINT_UNDEFINED;
}
}
}
update->n_fields = n_fields_updated;
- return(n_fields_updated);
+ return affects_fulltext;
}
/*********************************************************************//**
@@ -779,8 +770,6 @@ row_ins_foreign_trx_print(
heap_size = mem_heap_get_size(trx->lock.lock_heap);
lock_mutex_exit();
- trx_sys_mutex_enter();
-
mutex_enter(&dict_foreign_err_mutex);
rewind(dict_foreign_err_file);
ut_print_timestamp(dict_foreign_err_file);
@@ -789,8 +778,6 @@ row_ins_foreign_trx_print(
trx_print_low(dict_foreign_err_file, trx, 600,
n_rec_locks, n_trx_locks, heap_size);
- trx_sys_mutex_exit();
-
ut_ad(mutex_own(&dict_foreign_err_mutex));
}
@@ -1079,13 +1066,10 @@ row_ins_foreign_check_on_constraint(
const rec_t* clust_rec;
const buf_block_t* clust_block;
upd_t* update;
- ulint n_to_update;
dberr_t err;
- ulint i;
trx_t* trx;
mem_heap_t* tmp_heap = NULL;
doc_id_t doc_id = FTS_NULL_DOC_ID;
- ibool fts_col_affacted = FALSE;
DBUG_ENTER("row_ins_foreign_check_on_constraint");
ut_a(thr);
@@ -1129,27 +1113,22 @@ row_ins_foreign_check_on_constraint(
DBUG_RETURN(DB_ROW_IS_REFERENCED);
}
- cascade = row_create_update_node_for_mysql(table, node->cascade_heap);
- que_node_set_parent(cascade, node);
-
- /* For the cascaded operation, all the update nodes are allocated in
- the same heap. All the update nodes will point to the same heap.
- This heap is owned by the first update node. And it must be freed
- only in the first update node */
- cascade->cascade_heap = node->cascade_heap;
- cascade->cascade_upd_nodes = node->cascade_upd_nodes;
- cascade->new_upd_nodes = node->new_upd_nodes;
- cascade->processed_cascades = node->processed_cascades;
+ if (node->cascade_node == NULL) {
+ node->cascade_heap = mem_heap_create(128);
+ node->cascade_node = row_create_update_node_for_mysql(
+ table, node->cascade_heap);
+ que_node_set_parent(node->cascade_node, node);
+ }
+ cascade = node->cascade_node;
cascade->table = table;
-
cascade->foreign = foreign;
if (node->is_delete
&& (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE)) {
- cascade->is_delete = TRUE;
+ cascade->is_delete = PLAIN_DELETE;
} else {
- cascade->is_delete = FALSE;
+ cascade->is_delete = NO_DELETE;
if (foreign->n_fields > cascade->update_n_fields) {
/* We have to make the update vector longer */
@@ -1158,31 +1137,32 @@ row_ins_foreign_check_on_constraint(
node->cascade_heap);
cascade->update_n_fields = foreign->n_fields;
}
- }
- /* We do not allow cyclic cascaded updating (DELETE is allowed,
- but not UPDATE) of the same table, as this can lead to an infinite
- cycle. Check that we are not updating the same table which is
- already being modified in this cascade chain. We have to check
- this also because the modification of the indexes of a 'parent'
- table may still be incomplete, and we must avoid seeing the indexes
- of the parent table in an inconsistent state! */
+ /* We do not allow cyclic cascaded updating (DELETE is
+ allowed, but not UPDATE) of the same table, as this
+ can lead to an infinite cycle. Check that we are not
+ updating the same table which is already being
+ modified in this cascade chain. We have to check this
+ also because the modification of the indexes of a
+ 'parent' table may still be incomplete, and we must
+ avoid seeing the indexes of the parent table in an
+ inconsistent state! */
- if (!cascade->is_delete
- && row_ins_cascade_ancestor_updates_table(cascade, table)) {
+ if (row_ins_cascade_ancestor_updates_table(cascade, table)) {
- /* We do not know if this would break foreign key
- constraints, but play safe and return an error */
+ /* We do not know if this would break foreign key
+ constraints, but play safe and return an error */
- err = DB_ROW_IS_REFERENCED;
+ err = DB_ROW_IS_REFERENCED;
- row_ins_foreign_report_err(
- "Trying an update, possibly causing a cyclic"
- " cascaded update\n"
- "in the child table,", thr, foreign,
- btr_pcur_get_rec(pcur), entry);
+ row_ins_foreign_report_err(
+ "Trying an update, possibly causing a cyclic"
+ " cascaded update\n"
+ "in the child table,", thr, foreign,
+ btr_pcur_get_rec(pcur), entry);
- goto nonstandard_exit_func;
+ goto nonstandard_exit_func;
+ }
}
if (row_ins_cascade_n_ancestors(cascade) >= FK_MAX_CASCADE_DEL) {
@@ -1287,17 +1267,8 @@ row_ins_foreign_check_on_constraint(
if (node->is_delete
? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
: (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)) {
-
/* Build the appropriate update vector which sets
foreign->n_fields first fields in rec to SQL NULL */
- if (table->fts) {
-
- /* For the clause ON DELETE SET NULL, the cascade
- operation is actually an update operation with the new
- values being null. For FTS, this means that the old
- values be deleted and no new values to be added.*/
- cascade->fts_next_doc_id = FTS_NULL_DOC_ID;
- }
update = cascade->update;
@@ -1306,7 +1277,9 @@ row_ins_foreign_check_on_constraint(
UNIV_MEM_INVALID(update->fields,
update->n_fields * sizeof *update->fields);
- for (i = 0; i < foreign->n_fields; i++) {
+ 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(
index, i);
@@ -1322,18 +1295,19 @@ row_ins_foreign_check_on_constraint(
ufield->exp = NULL;
dfield_set_null(&ufield->new_val);
- if (table->fts && dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col_no(index, i),
- dict_col_is_virtual(
- dict_index_get_nth_col(index, i)))
+ if (!affects_fulltext
+ && table->fts && dict_table_is_fts_column(
+ table->fts->indexes,
+ dict_index_get_nth_col_no(index, i),
+ dict_col_is_virtual(
+ dict_index_get_nth_col(index, i)))
!= ULINT_UNDEFINED) {
- fts_col_affacted = TRUE;
+ affects_fulltext = true;
}
}
- if (fts_col_affacted) {
- cascade->fts_doc_id = doc_id;
+ if (affects_fulltext) {
+ fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
if (foreign->v_cols != NULL
@@ -1346,21 +1320,24 @@ row_ins_foreign_check_on_constraint(
goto nonstandard_exit_func;
}
}
- } else if (table->fts && cascade->is_delete) {
+ } else if (table->fts && cascade->is_delete == PLAIN_DELETE) {
/* DICT_FOREIGN_ON_DELETE_CASCADE case */
- for (i = 0; i < foreign->n_fields; i++) {
- if (table->fts && dict_table_is_fts_column(
+ 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_no(index, i),
dict_col_is_virtual(
dict_index_get_nth_col(index, i)))
!= ULINT_UNDEFINED) {
- fts_col_affacted = TRUE;
+ affects_fulltext = true;
+ break;
}
}
- if (fts_col_affacted) {
- cascade->fts_doc_id = doc_id;
+ if (affects_fulltext) {
+ fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
}
@@ -1370,13 +1347,10 @@ row_ins_foreign_check_on_constraint(
/* Build the appropriate update vector which sets changing
foreign->n_fields first fields in rec to new values */
- n_to_update = row_ins_cascade_calc_update_vec(
- node, foreign, cascade->cascade_heap,
- trx, &fts_col_affacted, cascade);
+ bool affects_fulltext = row_ins_cascade_calc_update_vec(
+ node, foreign, tmp_heap, trx);
-
- if (foreign->v_cols != NULL
- && foreign->v_cols->size() > 0) {
+ if (foreign->v_cols && !foreign->v_cols->empty()) {
row_ins_foreign_fill_virtual(
cascade, clust_rec, clust_index,
node, foreign, &err);
@@ -1386,7 +1360,8 @@ row_ins_foreign_check_on_constraint(
}
}
- if (n_to_update == ULINT_UNDEFINED) {
+ switch (cascade->update->n_fields) {
+ case ULINT_UNDEFINED:
err = DB_ROW_IS_REFERENCED;
row_ins_foreign_report_err(
@@ -1399,10 +1374,7 @@ row_ins_foreign_check_on_constraint(
thr, foreign, btr_pcur_get_rec(pcur), entry);
goto nonstandard_exit_func;
- }
-
- if (cascade->update->n_fields == 0) {
-
+ case 0:
/* The update does not change any columns referred
to in this foreign key constraint: no need to do
anything */
@@ -1413,9 +1385,9 @@ row_ins_foreign_check_on_constraint(
}
/* Mark the old Doc ID as deleted */
- if (fts_col_affacted) {
+ if (affects_fulltext) {
ut_ad(table->fts);
- cascade->fts_doc_id = doc_id;
+ fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
}
@@ -1437,28 +1409,19 @@ row_ins_foreign_check_on_constraint(
cascade->state = UPD_NODE_UPDATE_CLUSTERED;
#ifdef WITH_WSREP
- err = wsrep_append_foreign_key(
- thr_get_trx(thr),
- foreign,
- clust_rec,
- clust_index,
- FALSE, FALSE);
+ err = wsrep_append_foreign_key(trx, foreign, clust_rec, clust_index,
+ FALSE, FALSE);
if (err != DB_SUCCESS) {
fprintf(stderr,
"WSREP: foreign key append failed: %d\n", err);
} else
#endif /* WITH_WSREP */
- node->new_upd_nodes->push_back(cascade);
-
- my_atomic_addlint(&table->n_foreign_key_checks_running, 1);
-
- ut_ad(foreign->foreign_table->n_foreign_key_checks_running > 0);
+ err = row_update_cascade_for_mysql(thr, cascade,
+ foreign->foreign_table);
/* Release the data dictionary latch for a while, so that we do not
starve other threads from doing CREATE TABLE etc. if we have a huge
- cascaded operation running. The counter n_foreign_key_checks_running
- will prevent other users from dropping or ALTERing the table when we
- release the latch. */
+ cascaded operation running. */
row_mysql_unfreeze_data_dictionary(thr_get_trx(thr));
@@ -1479,7 +1442,6 @@ row_ins_foreign_check_on_constraint(
DBUG_RETURN(err);
nonstandard_exit_func:
- que_graph_free_recursive(cascade);
if (tmp_heap) {
mem_heap_free(tmp_heap);
@@ -1557,17 +1519,6 @@ row_ins_set_exclusive_rec_lock(
return(err);
}
-/* Decrement a counter in the destructor. */
-class ib_dec_in_dtor {
-public:
- ib_dec_in_dtor(ulint& c): counter(c) {}
- ~ib_dec_in_dtor() {
- my_atomic_addlint(&counter, -1);
- }
-private:
- ulint& counter;
-};
-
/***************************************************************//**
Checks if foreign key constraint fails for an index entry. Sets shared locks
which lock either the success or the failure of the constraint. NOTE that
@@ -1625,8 +1576,14 @@ row_ins_check_foreign_constraint(
/* If any of the foreign key fields in entry is SQL NULL, we
suppress the foreign key check: this is compatible with Oracle,
for example */
- for (ulint i = 0; i < foreign->n_fields; i++) {
- if (dfield_is_null(dtuple_get_nth_field(entry, i))) {
+ for (ulint i = 0; i < entry->n_fields; i++) {
+ dfield_t* field = dtuple_get_nth_field(entry, i);
+ if (i < foreign->n_fields && dfield_is_null(field)) {
+ goto exit_func;
+ }
+ /* System Versioning: if row_end != Inf, we
+ suppress the foreign key check */
+ if (field->type.vers_sys_end() && field->vers_history_row()) {
goto exit_func;
}
}
@@ -1634,7 +1591,8 @@ row_ins_check_foreign_constraint(
if (que_node_get_type(thr->run_node) == QUE_NODE_UPDATE) {
upd_node = static_cast<upd_node_t*>(thr->run_node);
- if (!(upd_node->is_delete) && upd_node->foreign == foreign) {
+ if (upd_node->is_delete != PLAIN_DELETE
+ && upd_node->foreign == foreign) {
/* If a cascaded update is done as defined by a
foreign key constraint, do not check that
constraint for the child row. In ON UPDATE CASCADE
@@ -1757,6 +1715,23 @@ row_ins_check_foreign_constraint(
cmp = cmp_dtuple_rec(entry, rec, offsets);
if (cmp == 0) {
+ if (check_table->versioned()) {
+ bool history_row = false;
+
+ if (check_index->is_primary()) {
+ history_row = check_index->
+ vers_history_row(rec, offsets);
+ } else if (check_index->
+ vers_history_row(rec, history_row))
+ {
+ break;
+ }
+
+ if (history_row) {
+ continue;
+ }
+ }
+
if (rec_get_deleted_flag(rec,
rec_offs_comp(offsets))) {
/* In delete-marked records, DB_TRX_ID must
@@ -1892,19 +1867,13 @@ end_scan:
do_possible_lock_wait:
if (err == DB_LOCK_WAIT) {
- /* An object that will correctly decrement the FK check counter
- when it goes out of this scope. */
- ib_dec_in_dtor dec(check_table->n_foreign_key_checks_running);
-
trx->error_state = err;
que_thr_stop_for_mysql(thr);
thr->lock_state = QUE_THR_LOCK_ROW;
- /* To avoid check_table being dropped, increment counter */
- my_atomic_addlint(
- &check_table->n_foreign_key_checks_running, 1);
+ check_table->inc_fk_checks();
trx_kill_blocking(trx);
@@ -1912,9 +1881,12 @@ do_possible_lock_wait:
thr->lock_state = QUE_THR_LOCK_NOLOCK;
- err = check_table->to_be_dropped
- ? DB_LOCK_WAIT_TIMEOUT
- : trx->error_state;
+ if (check_table->to_be_dropped
+ || trx->error_state == DB_LOCK_WAIT_TIMEOUT) {
+ err = DB_LOCK_WAIT_TIMEOUT;
+ }
+
+ check_table->dec_fk_checks();
}
exit_func:
@@ -1975,6 +1947,10 @@ row_ins_check_foreign_constraints(
row_mysql_freeze_data_dictionary(trx);
}
+ if (referenced_table) {
+ foreign->foreign_table->inc_fk_checks();
+ }
+
/* NOTE that if the thread ends up waiting for a lock
we will release dict_operation_lock temporarily!
But the counter on the table protects the referenced
@@ -1983,6 +1959,10 @@ row_ins_check_foreign_constraints(
err = row_ins_check_foreign_constraint(
TRUE, foreign, table, entry, thr);
+ if (referenced_table) {
+ foreign->foreign_table->dec_fk_checks();
+ }
+
if (got_s_lock) {
row_mysql_unfreeze_data_dictionary(trx);
}
@@ -2898,21 +2878,18 @@ row_ins_sec_index_entry_low(
cursor.rtr_info = NULL;
ut_ad(thr_get_trx(thr)->id != 0);
- mtr_start(&mtr);
- mtr.set_named_space(index->space);
-
- if (dict_table_is_temporary(index->table)) {
- /* Disable REDO logging as the lifetime of temp-tables is
- limited to server or connection lifetime and so REDO
- information is not needed on restart for recovery.
- Disable locking as temp-tables are local to a connection. */
+ mtr.start();
+ if (index->table->is_temporary()) {
+ /* Disable locking, because temporary tables are never
+ shared between transactions or connections. */
ut_ad(flags & BTR_NO_LOCKING_FLAG);
mtr.set_log_mode(MTR_LOG_NO_REDO);
- } else if (!dict_index_is_spatial(index)) {
- /* Enable insert buffering if it's neither temp-table
- nor spatial index. */
- search_mode |= BTR_INSERT;
+ } else {
+ mtr.set_named_space(index->space);
+ if (!dict_index_is_spatial(index)) {
+ search_mode |= BTR_INSERT;
+ }
}
/* Ensure that we acquire index->lock when inserting into an
@@ -2984,10 +2961,8 @@ row_ins_sec_index_entry_low(
}
if (err != DB_SUCCESS) {
- trx_t* trx = thr_get_trx(thr);
-
if (err == DB_DECRYPTION_FAILED) {
- ib_push_warning(trx->mysql_thd,
+ ib_push_warning(thr_get_trx(thr)->mysql_thd,
DB_DECRYPTION_FAILED,
"Table %s is encrypted but encryption service or"
" used key_id is not available. "
@@ -3230,14 +3205,25 @@ row_ins_clust_index_entry(
n_uniq = dict_index_is_unique(index) ? index->n_uniq : 0;
- const ulint flags = index->table->is_temporary()
- ? BTR_NO_LOCKING_FLAG
- : index->table->no_rollback() ? BTR_NO_ROLLBACK : 0;
+ ulint flags = index->table->no_rollback() ? BTR_NO_ROLLBACK
+ : dict_table_is_temporary(index->table)
+ ? BTR_NO_LOCKING_FLAG : 0;
const ulint orig_n_fields = entry->n_fields;
/* Try first optimistic descent to the B-tree */
log_free_check();
+ /* For intermediate table during copy alter table,
+ skip the undo log and record lock checking for
+ insertion operation.
+ */
+ if (index->table->skip_alter_undo) {
+ flags |= BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG;
+ }
+
+ /* Try first optimistic descent to the B-tree */
+ log_free_check();
+
err = row_ins_clust_index_entry_low(
flags, BTR_MODIFY_LEAF, index, n_uniq, entry,
n_ext, thr, dup_chk_only);
@@ -3283,6 +3269,7 @@ row_ins_sec_index_entry(
dberr_t err;
mem_heap_t* offsets_heap;
mem_heap_t* heap;
+ trx_id_t trx_id = 0;
DBUG_EXECUTE_IF("row_ins_sec_index_entry_timeout", {
DBUG_SET("-d,row_ins_sec_index_entry_timeout");
@@ -3305,13 +3292,22 @@ row_ins_sec_index_entry(
/* Try first optimistic descent to the B-tree */
log_free_check();
- const ulint flags = dict_table_is_temporary(index->table)
+ ulint flags = dict_table_is_temporary(index->table)
? BTR_NO_LOCKING_FLAG
: 0;
+ /* For intermediate table during copy alter table,
+ skip the undo log and record lock checking for
+ insertion operation.
+ */
+ if (index->table->skip_alter_undo) {
+ trx_id = thr_get_trx(thr)->id;
+ flags |= BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG;
+ }
+
err = row_ins_sec_index_entry_low(
flags, BTR_MODIFY_LEAF, index, offsets_heap, heap, entry,
- 0, thr, dup_chk_only);
+ trx_id, thr, dup_chk_only);
if (err == DB_FAIL) {
mem_heap_empty(heap);
@@ -3348,13 +3344,13 @@ row_ins_index_entry(
dtuple_t* entry, /*!< in/out: index entry to insert */
que_thr_t* thr) /*!< in: query thread */
{
- ut_ad(thr_get_trx(thr)->id != 0);
+ ut_ad(thr_get_trx(thr)->id || index->table->no_rollback());
DBUG_EXECUTE_IF("row_ins_index_entry_timeout", {
DBUG_SET("-d,row_ins_index_entry_timeout");
return(DB_LOCK_WAIT);});
- if (index->is_clust()) {
+ if (index->is_primary()) {
return(row_ins_clust_index_entry(index, entry, thr, 0, false));
} else {
return(row_ins_sec_index_entry(index, entry, thr, false));
@@ -3449,7 +3445,7 @@ row_ins_index_entry_set_vals(
= dict_field_get_col(ind_field);
len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype, col->mbminlen, col->mbmaxlen,
ind_field->prefix_len,
len,
static_cast<const char*>(
@@ -3536,7 +3532,7 @@ row_ins_alloc_row_id_step(
row_id = dict_sys_get_new_row_id();
- dict_sys_write_row_id(node->row_id_buf, row_id);
+ dict_sys_write_row_id(node->sys_buf, row_id);
}
/***********************************************************//**
@@ -3652,6 +3648,11 @@ row_ins(
switch (err) {
case DB_SUCCESS:
break;
+ case DB_NO_REFERENCED_ROW:
+ if (!dict_index_is_unique(node->index)) {
+ DBUG_RETURN(err);
+ }
+ /* fall through */
case DB_DUPLICATE_KEY:
ut_ad(dict_index_is_unique(node->index));
@@ -3668,7 +3669,55 @@ row_ins(
secondary indexes to block concurrent
transactions from inserting the
searched records. */
- if (!node->duplicate) {
+ if (err == DB_NO_REFERENCED_ROW
+ && node->duplicate) {
+ /* A foreign key check on a
+ unique index may fail to
+ find the record.
+
+ Consider as a example
+ following:
+ create table child(a int not null
+ primary key, b int not null,
+ c int,
+ unique key (b),
+ foreign key (b) references
+ parent (id)) engine=innodb;
+
+ insert into child values
+ (1,1,2);
+
+ insert into child(a) values
+ (1) on duplicate key update
+ c = 3;
+
+ Now primary key value 1
+ naturally causes duplicate
+ key error that will be
+ stored on node->duplicate.
+ If there was no duplicate
+ key error, we should return
+ the actual no referenced
+ row error.
+
+ As value for
+ column b used in both unique
+ key and foreign key is not
+ provided, server uses 0 as a
+ search value. This is
+ naturally, not found leading
+ to DB_NO_REFERENCED_ROW.
+ But, we should update the
+ row with primay key value 1
+ anyway.
+
+ Return the
+ original DB_DUPLICATE_KEY
+ error after
+ placing all gaplocks. */
+ err = DB_DUPLICATE_KEY;
+ break;
+ } else if (!node->duplicate) {
/* Save 1st dup error. Ignore
subsequent dup errors. */
node->duplicate = node->index;
@@ -3755,8 +3804,6 @@ row_ins_step(
trx = thr_get_trx(thr);
- trx_start_if_not_started_xa(trx, true);
-
node = static_cast<ins_node_t*>(thr->run_node);
ut_ad(que_node_get_type(node) == QUE_NODE_INSERT);
@@ -3776,7 +3823,7 @@ row_ins_step(
This happens, for example, when a row update moves it to another
partition. In that case, we have already set the IX lock on the
table during the search operation, and there is no need to set
- it again here. But we must write trx->id to node->trx_id_buf. */
+ it again here. But we must write trx->id to node->sys_buf. */
if (node->table->no_rollback()) {
/* No-rollback tables should only be written to by a
@@ -3791,15 +3838,15 @@ row_ins_step(
restarting here. In theory, we could allow resumption
from the INS_NODE_INSERT_ENTRIES state here. */
DBUG_ASSERT(node->state == INS_NODE_SET_IX_LOCK);
- memset(node->trx_id_buf, 0, DATA_TRX_ID_LEN);
- memset(node->row_id_buf, 0, DATA_ROW_ID_LEN);
node->index = dict_table_get_first_index(node->table);
node->entry = UT_LIST_GET_FIRST(node->entry_list);
node->state = INS_NODE_INSERT_ENTRIES;
goto do_insert;
}
- trx_write_trx_id(node->trx_id_buf, trx->id);
+ if (UNIV_LIKELY(!node->table->skip_alter_undo)) {
+ trx_write_trx_id(&node->sys_buf[DATA_ROW_ID_LEN], trx->id);
+ }
if (node->state == INS_NODE_SET_IX_LOCK) {
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 76ca4e8b940..c0264d1953d 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -71,6 +71,7 @@ enum row_op {
/** Log block for modifications during online ALTER TABLE */
struct row_log_buf_t {
byte* block; /*!< file block buffer */
+ size_t size; /*!< length of block in bytes */
ut_new_pfx_t block_pfx; /*!< opaque descriptor of "block". Set
by ut_allocator::allocate_large() and fed to
ut_allocator::deallocate_large(). */
@@ -265,6 +266,7 @@ row_log_block_allocate(
if (log_buf.block == NULL) {
DBUG_RETURN(false);
}
+ log_buf.size = srv_sort_buf_size;
}
DBUG_RETURN(true);
}
@@ -279,7 +281,7 @@ row_log_block_free(
DBUG_ENTER("row_log_block_free");
if (log_buf.block != NULL) {
ut_allocator<byte>(mem_key_row_log_buf).deallocate_large(
- log_buf.block, &log_buf.block_pfx);
+ log_buf.block, &log_buf.block_pfx, log_buf.size);
log_buf.block = NULL;
}
DBUG_VOID_RETURN;
@@ -853,6 +855,18 @@ row_log_table_low_redundant(
}
}
+ dfield_t* db_trx_id = dtuple_get_nth_field(tuple, index->n_uniq);
+ ut_ad(dfield_get_len(db_trx_id) == DATA_TRX_ID_LEN);
+ ut_ad(dfield_get_len(db_trx_id + 1) == DATA_ROLL_PTR_LEN);
+
+ if (trx_read_trx_id(static_cast<const byte*>
+ (dfield_get_data(db_trx_id)))
+ < index->online_log->min_trx) {
+ dfield_set_data(db_trx_id, reset_trx_id, DATA_TRX_ID_LEN);
+ dfield_set_data(db_trx_id + 1, reset_trx_id + DATA_TRX_ID_LEN,
+ DATA_ROLL_PTR_LEN);
+ }
+
rec_comp_status_t status = index->is_instant()
? REC_STATUS_COLUMNS_ADDED : REC_STATUS_ORDINARY;
@@ -1057,7 +1071,16 @@ row_log_table_low(
memcpy(b, rec - rec_extra_size - omit_size, rec_extra_size);
b += rec_extra_size;
+ ulint len;
+ ulint trx_id_offs = rec_get_nth_field_offs(
+ offsets, index->n_uniq, &len);
+ ut_ad(len == DATA_TRX_ID_LEN);
memcpy(b, rec, rec_offs_data_size(offsets));
+ if (trx_read_trx_id(b + trx_id_offs)
+ < index->online_log->min_trx) {
+ memcpy(b + trx_id_offs,
+ reset_trx_id, sizeof reset_trx_id);
+ }
b += rec_offs_data_size(offsets);
row_log_table_close(index, b, mrec_size, avail_size);
@@ -1279,7 +1302,7 @@ row_log_table_get_pk(
dict_field_t* ifield;
dfield_t* dfield;
ulint prtype;
- ulint mbminmaxlen;
+ ulint mbminlen, mbmaxlen;
ifield = dict_index_get_nth_field(new_index, new_i);
dfield = dtuple_get_nth_field(tuple, new_i);
@@ -1308,7 +1331,8 @@ err_exit:
goto func_exit;
}
- mbminmaxlen = col->mbminmaxlen;
+ mbminlen = col->mbminlen;
+ mbmaxlen = col->mbmaxlen;
prtype = col->prtype;
} else {
/* No matching column was found in the old
@@ -1318,7 +1342,8 @@ err_exit:
dfield_copy(dfield, dtuple_get_nth_field(
log->add_cols, col_no));
- mbminmaxlen = dfield->type.mbminmaxlen;
+ mbminlen = dfield->type.mbminlen;
+ mbmaxlen = dfield->type.mbmaxlen;
prtype = dfield->type.prtype;
}
@@ -1327,7 +1352,7 @@ err_exit:
if (ifield->prefix_len) {
ulint len = dtype_get_at_most_n_mbchars(
- prtype, mbminmaxlen,
+ prtype, mbminlen, mbmaxlen,
ifield->prefix_len,
dfield_get_len(dfield),
static_cast<const char*>(
@@ -1674,13 +1699,10 @@ row_log_table_apply_insert_low(
return(error);
}
- do {
- n_index++;
-
- if (!(index = dict_table_get_next_index(index))) {
- break;
- }
+ ut_ad(dict_index_is_clust(index));
+ for (n_index += index->type != DICT_CLUSTERED;
+ (index = dict_table_get_next_index(index)); n_index++) {
if (index->type & DICT_FTS) {
continue;
}
@@ -1691,12 +1713,13 @@ row_log_table_apply_insert_low(
index, offsets_heap, heap, entry,
thr_get_trx(thr)->id, thr, false);
- /* Report correct index name for duplicate key error. */
- if (error == DB_DUPLICATE_KEY) {
- thr_get_trx(thr)->error_key_num = n_index;
+ if (error != DB_SUCCESS) {
+ if (error == DB_DUPLICATE_KEY) {
+ thr_get_trx(thr)->error_key_num = n_index;
+ }
+ break;
}
-
- } while (error == DB_SUCCESS);
+ }
return(error);
}
@@ -2276,17 +2299,16 @@ func_exit_committed:
dtuple_big_rec_free(big_rec);
}
- while ((index = dict_table_get_next_index(index)) != NULL) {
- if (error != DB_SUCCESS) {
- break;
- }
-
- n_index++;
-
+ for (n_index += index->type != DICT_CLUSTERED;
+ (index = dict_table_get_next_index(index)); n_index++) {
if (index->type & DICT_FTS) {
continue;
}
+ if (error != DB_SUCCESS) {
+ break;
+ }
+
if (!row_upd_changes_ord_field_binary(
index, update, thr, old_row, NULL)) {
continue;
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 6a6c65cd70c..2928ca51ddb 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2014, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -63,12 +63,6 @@ float my_log2f(float n)
# define posix_fadvise(fd, offset, len, advice) /* nothing */
#endif /* _WIN32 */
-/** The DB_TRX_ID,DB_ROLL_PTR values for "no history is available" */
-const byte reset_trx_id[DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN] = {
- 0, 0, 0, 0, 0, 0,
- 0x80, 0, 0, 0, 0, 0, 0
-};
-
/* Whether to disable file system cache */
char srv_disable_sort_file_cache;
@@ -456,8 +450,8 @@ row_merge_buf_redundant_convert(
const page_size_t& page_size,
mem_heap_t* heap)
{
- ut_ad(DATA_MBMINLEN(field->type.mbminmaxlen) == 1);
- ut_ad(DATA_MBMAXLEN(field->type.mbminmaxlen) > 1);
+ ut_ad(field->type.mbminlen == 1);
+ ut_ad(field->type.mbmaxlen > 1);
byte* buf = (byte*) mem_heap_alloc(heap, len);
ulint field_len = row_field->len;
@@ -599,7 +593,8 @@ row_merge_buf_add(
field->type.mtype = ifield->col->mtype;
field->type.prtype = ifield->col->prtype;
- field->type.mbminmaxlen = DATA_MBMINMAXLEN(0, 0);
+ field->type.mbminlen = 0;
+ field->type.mbmaxlen = 0;
field->type.len = ifield->col->len;
} else {
/* Use callback to get the virtual column value */
@@ -750,7 +745,7 @@ row_merge_buf_add(
if (ifield->prefix_len) {
len = dtype_get_at_most_n_mbchars(
col->prtype,
- col->mbminmaxlen,
+ col->mbminlen, col->mbmaxlen,
ifield->prefix_len,
len,
static_cast<char*>(dfield_get_data(field)));
@@ -762,8 +757,7 @@ row_merge_buf_add(
fixed_len = ifield->fixed_len;
if (fixed_len && !dict_table_is_comp(index->table)
- && DATA_MBMINLEN(col->mbminmaxlen)
- != DATA_MBMAXLEN(col->mbminmaxlen)) {
+ && col->mbminlen != col->mbmaxlen) {
/* CHAR in ROW_FORMAT=REDUNDANT is always
fixed-length, but in the temporary file it is
variable-length for variable-length character
@@ -773,14 +767,11 @@ row_merge_buf_add(
if (fixed_len) {
#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
-
/* len should be between size calcualted base on
mbmaxlen and mbminlen */
ut_ad(len <= fixed_len);
- ut_ad(!mbmaxlen || len >= mbminlen
- * (fixed_len / mbmaxlen));
+ ut_ad(!col->mbmaxlen || len >= col->mbminlen
+ * (fixed_len / col->mbmaxlen));
ut_ad(!dfield_is_ext(field));
#endif /* UNIV_DEBUG */
@@ -1707,7 +1698,8 @@ row_merge_read_clustered_index(
ut_stage_alter_t* stage,
double pct_cost,
row_merge_block_t* crypt_block,
- struct TABLE* eval_table)
+ struct TABLE* eval_table,
+ bool drop_historical)
{
dict_index_t* clust_index; /* Clustered index */
mem_heap_t* row_heap; /* Heap memory to create
@@ -1741,6 +1733,10 @@ row_merge_read_clustered_index(
double curr_progress = 0.0;
ib_uint64_t read_rows = 0;
ib_uint64_t table_total_rows = 0;
+ char new_sys_trx_start[8];
+ char new_sys_trx_end[8];
+ byte any_autoinc_data[8] = {0};
+ bool vers_update_trt = false;
DBUG_ENTER("row_merge_read_clustered_index");
@@ -1915,6 +1911,9 @@ row_merge_read_clustered_index(
prev_fields = NULL;
}
+ mach_write_to_8(new_sys_trx_start, trx->id);
+ mach_write_to_8(new_sys_trx_end, TRX_ID_MAX);
+
/* Scan the clustered index. */
for (;;) {
const rec_t* rec;
@@ -1984,7 +1983,8 @@ row_merge_read_clustered_index(
}
if (dbug_run_purge
- || dict_index_get_lock(clust_index)->waiters) {
+ || my_atomic_load32_explicit(&clust_index->lock.waiters,
+ MY_MEMORY_ORDER_RELAXED)) {
/* There are waiters on the clustered
index tree lock, likely the purge
thread. Store and restore the cursor
@@ -2092,16 +2092,16 @@ end_of_index:
ONLINE_INDEX_COMPLETE state between the time
the DML thread has updated the clustered index
but has not yet accessed secondary index. */
- ut_ad(MVCC::is_view_active(trx->read_view));
+ ut_ad(trx->read_view.is_open());
ut_ad(rec_trx_id != trx->id);
- if (!trx->read_view->changes_visible(
+ if (!trx->read_view.changes_visible(
rec_trx_id, old_table->name)) {
rec_t* old_vers;
row_vers_build_for_consistent_read(
rec, &mtr, clust_index, &offsets,
- trx->read_view, &row_heap,
+ &trx->read_view, &row_heap,
row_heap, &old_vers, NULL);
if (!old_vers) {
@@ -2238,9 +2238,33 @@ end_of_index:
ut_ad(add_autoinc
< dict_table_get_n_user_cols(new_table));
- const dfield_t* dfield;
+ bool history_row = false;
+ if (new_table->versioned()) {
+ const dfield_t* dfield = dtuple_get_nth_field(
+ row, new_table->vers_end);
+ history_row = dfield->vers_history_row();
+ }
+
+ dfield_t* dfield;
dfield = dtuple_get_nth_field(row, add_autoinc);
+
+ if (new_table->versioned()) {
+ if (history_row) {
+ if (dfield_get_type(dfield)->prtype & DATA_NOT_NULL) {
+ err = DB_UNSUPPORTED;
+ my_error(ER_UNSUPPORTED_EXTENSION, MYF(0),
+ old_table->name.m_name);
+ goto func_exit;
+ }
+ dfield_set_null(dfield);
+ } else {
+ // set not null
+ ulint len = dfield_get_type(dfield)->len;
+ dfield_set_data(dfield, any_autoinc_data, len);
+ }
+ }
+
if (dfield_is_null(dfield)) {
goto write_buffers;
}
@@ -2286,6 +2310,21 @@ end_of_index:
}
}
+ if (old_table->versioned()) {
+ if ((!new_table->versioned() || drop_historical)
+ && clust_index->vers_history_row(rec, offsets)) {
+ continue;
+ }
+ } else if (new_table->versioned()) {
+ dfield_t* start =
+ dtuple_get_nth_field(row, new_table->vers_start);
+ dfield_t* end =
+ dtuple_get_nth_field(row, new_table->vers_end);
+ dfield_set_data(start, new_sys_trx_start, 8);
+ dfield_set_data(end, new_sys_trx_end, 8);
+ vers_update_trt = true;
+ }
+
write_buffers:
/* Build all entries for all the indexes to be created
in a single scan of the clustered index. */
@@ -2827,6 +2866,15 @@ wait_again:
}
}
+ if (vers_update_trt) {
+ trx_mod_table_time_t& time =
+ trx->mod_tables
+ .insert(trx_mod_tables_t::value_type(
+ const_cast<dict_table_t*>(new_table), 0))
+ .first->second;
+ time.set_versioned(0);
+ }
+
trx->op_info = "";
DBUG_RETURN(err);
@@ -4469,8 +4517,8 @@ row_merge_is_index_usable(
return(!dict_index_is_corrupted(index)
&& (dict_table_is_temporary(index->table)
|| index->trx_id == 0
- || !MVCC::is_view_active(trx->read_view)
- || trx->read_view->changes_visible(
+ || !trx->read_view.is_open()
+ || trx->read_view.changes_visible(
index->trx_id,
index->table->name)));
}
@@ -4546,6 +4594,7 @@ this function and it will be passed to other functions for further accounting.
@param[in] add_v new virtual columns added along with indexes
@param[in] eval_table mysql table used to evaluate virtual column
value, see innobase_get_computed_value().
+@param[in] drop_historical whether to drop historical system rows
@return DB_SUCCESS or error code */
dberr_t
row_merge_build_indexes(
@@ -4564,11 +4613,13 @@ row_merge_build_indexes(
bool skip_pk_sort,
ut_stage_alter_t* stage,
const dict_add_v_col_t* add_v,
- struct TABLE* eval_table)
+ struct TABLE* eval_table,
+ bool drop_historical)
{
merge_file_t* merge_files;
row_merge_block_t* block;
ut_new_pfx_t block_pfx;
+ size_t block_size;
ut_new_pfx_t crypt_pfx;
row_merge_block_t* crypt_block = NULL;
ulint i;
@@ -4604,15 +4655,18 @@ row_merge_build_indexes(
/* This will allocate "3 * srv_sort_buf_size" elements of type
row_merge_block_t. The latter is defined as byte. */
- block = alloc.allocate_large(3 * srv_sort_buf_size, &block_pfx);
+ block_size = 3 * srv_sort_buf_size;
+ block = alloc.allocate_large(block_size, &block_pfx);
if (block == NULL) {
DBUG_RETURN(DB_OUT_OF_MEMORY);
}
+ TRASH_ALLOC(&crypt_pfx, sizeof crypt_pfx);
+
if (log_tmp_is_encrypted()) {
crypt_block = static_cast<row_merge_block_t*>(
- alloc.allocate_large(3 * srv_sort_buf_size,
+ alloc.allocate_large(block_size,
&crypt_pfx));
if (crypt_block == NULL) {
@@ -4712,8 +4766,8 @@ row_merge_build_indexes(
"Table %s is encrypted but encryption service or"
" used key_id is not available. "
" Can't continue reading table.",
- !old_table->is_readable() ? old_table->name :
- new_table->name);
+ !old_table->is_readable() ? old_table->name.m_name :
+ new_table->name.m_name);
goto func_exit;
}
@@ -4724,7 +4778,7 @@ row_merge_build_indexes(
fts_sort_idx, psort_info, merge_files, key_numbers,
n_indexes, add_cols, add_v, col_map, add_autoinc,
sequence, block, skip_pk_sort, &tmpfd, stage,
- pct_cost, crypt_block, eval_table);
+ pct_cost, crypt_block, eval_table, drop_historical);
stage->end_phase_read_pk();
@@ -4983,10 +5037,10 @@ func_exit:
ut_free(merge_files);
- alloc.deallocate_large(block, &block_pfx);
+ alloc.deallocate_large(block, &block_pfx, block_size);
if (crypt_block) {
- alloc.deallocate_large(crypt_block, &crypt_pfx);
+ alloc.deallocate_large(crypt_block, &crypt_pfx, block_size);
}
DICT_TF2_FLAG_UNSET(new_table, DICT_TF2_FTS_ADD_DOC_ID);
@@ -5034,7 +5088,7 @@ func_exit:
ut_ad(need_flush_observer);
DBUG_EXECUTE_IF("ib_index_build_fail_before_flush",
- error = DB_FAIL;
+ error = DB_INTERRUPTED;
);
if (error != DB_SUCCESS) {
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index f44c6586c4c..835ca2ec2d1 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -64,6 +64,7 @@ Created 9/17/2000 Heikki Tuuri
#include "trx0roll.h"
#include "trx0undo.h"
#include "row0ext.h"
+#include "srv0start.h"
#include "ut0new.h"
#include <algorithm>
@@ -75,7 +76,7 @@ ibool row_rollback_on_timeout = FALSE;
/** Chain node of the list of tables to drop in the background. */
struct row_mysql_drop_t{
- char* table_name; /*!< table name */
+ table_id_t table_id; /*!< table id */
UT_LIST_NODE_T(row_mysql_drop_t)row_mysql_drop_list;
/*!< list chain node */
};
@@ -93,27 +94,6 @@ static ib_mutex_t row_drop_list_mutex;
/** Flag: has row_mysql_drop_list been initialized? */
static ibool row_mysql_drop_list_inited = FALSE;
-/** Magic table names for invoking various monitor threads */
-/* @{ */
-static const char S_innodb_monitor[] = "innodb_monitor";
-static const char S_innodb_lock_monitor[] = "innodb_lock_monitor";
-static const char S_innodb_tablespace_monitor[] = "innodb_tablespace_monitor";
-static const char S_innodb_table_monitor[] = "innodb_table_monitor";
-#ifdef UNIV_MEM_DEBUG
-static const char S_innodb_mem_validate[] = "innodb_mem_validate";
-#endif /* UNIV_MEM_DEBUG */
-/* @} */
-
-/** Evaluates to true if str1 equals str2_onstack, used for comparing
-the magic table names.
-@param str1 in: string to compare
-@param str1_len in: length of str1, in bytes, including terminating NUL
-@param str2_onstack in: char[] array containing a NUL terminated string
-@return TRUE if str1 equals str2_onstack */
-#define STR_EQ(str1, str1_len, str2_onstack) \
- ((str1_len) == sizeof(str2_onstack) \
- && memcmp(str1, str2_onstack, sizeof(str2_onstack)) == 0)
-
/*******************************************************************//**
Determine if the given name is a name reserved for MySQL system tables.
@return TRUE if name is a MySQL system table name */
@@ -133,19 +113,6 @@ row_mysql_is_system_table(
|| 0 == strcmp(name + 6, "db"));
}
-/*********************************************************************//**
-If a table is not yet in the drop list, adds the table to the list of tables
-which the master thread drops in background. We need this on Unix because in
-ALTER TABLE MySQL may call drop table even if the table has running queries on
-it. Also, if there are running foreign key checks on the table, we drop the
-table lazily.
-@return TRUE if the table was not yet in the drop list, and was added there */
-static
-ibool
-row_add_table_to_background_drop_list(
-/*==================================*/
- const char* name); /*!< in: table name */
-
#ifdef UNIV_DEBUG
/** Wait for the background drop list to become empty. */
void
@@ -340,29 +307,6 @@ row_mysql_store_geometry(
mach_write_to_n_little_endian(dest, dest_len - 8, src_len);
memcpy(dest + dest_len - 8, &src, sizeof src);
-
- DBUG_EXECUTE_IF("row_print_geometry_data",
- {
- String res;
- Geometry_buffer buffer;
- String wkt;
-
- /** Show the meaning of geometry data. */
- Geometry* g = Geometry::construct(
- &buffer, (const char*)src, (uint32) src_len);
-
- if (g)
- {
- /*
- if (g->as_wkt(&wkt) == 0)
- {
- ib::info() << "Write geometry data to"
- " MySQL WKT format: "
- << wkt.c_ptr_safe() << ".";
- }
- */
- }
- });
}
/*******************************************************************//**
@@ -383,29 +327,6 @@ row_mysql_read_geometry(
memcpy(&data, ref + col_len - 8, sizeof data);
- DBUG_EXECUTE_IF("row_print_geometry_data",
- {
- String res;
- Geometry_buffer buffer;
- String wkt;
-
- /** Show the meaning of geometry data. */
- Geometry* g = Geometry::construct(
- &buffer, (const char*) data, (uint32) *len);
-
- if (g)
- {
- /*
- if (g->as_wkt(&wkt) == 0)
- {
- ib::info() << "Read geometry data in"
- " MySQL's WKT format: "
- << wkt.c_ptr_safe() << ".";
- }
- */
- }
- });
-
return(data);
}
@@ -854,6 +775,12 @@ handle_new_error:
<< FK_MAX_CASCADE_DEL << ". Please drop excessive"
" foreign constraints and try again";
break;
+ case DB_UNSUPPORTED:
+ ib::error() << "Cannot delete/update rows with cascading"
+ " foreign key constraints in timestamp-based temporal"
+ " table. Please drop excessive"
+ " foreign constraints and try again";
+ break;
default:
ib::fatal() << "Unknown error code " << err << ": "
<< ut_strerr(err);
@@ -1293,20 +1220,11 @@ run_again:
return(err);
}
-/*********************************************************************//**
-Sets a table lock on the table mentioned in prebuilt.
+/** Lock a table.
+@param[in,out] prebuilt table handle
@return error code or DB_SUCCESS */
dberr_t
-row_lock_table_for_mysql(
-/*=====================*/
- row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in the MySQL
- table handle */
- dict_table_t* table, /*!< in: table to lock, or NULL
- if prebuilt->table should be
- locked as
- prebuilt->select_lock_type */
- ulint mode) /*!< in: lock mode of table
- (ignored if table==NULL) */
+row_lock_table(row_prebuilt_t* prebuilt)
{
trx_t* trx = prebuilt->trx;
que_thr_t* thr;
@@ -1336,17 +1254,10 @@ run_again:
trx_start_if_not_started_xa(trx, false);
- if (table) {
- err = lock_table(
- 0, table,
- static_cast<enum lock_mode>(mode), thr);
- } else {
- err = lock_table(
- 0, prebuilt->table,
- static_cast<enum lock_mode>(
- prebuilt->select_lock_type),
- thr);
- }
+ err = lock_table(0, prebuilt->table,
+ static_cast<enum lock_mode>(
+ prebuilt->select_lock_type),
+ thr);
trx->error_state = err;
@@ -1420,6 +1331,23 @@ row_mysql_get_table_status(
return(err);
}
+/** Writes 8 bytes to nth tuple field
+@param[in] tuple where to write
+@param[in] nth index in tuple
+@param[in] data what to write
+@param[in] buf field data buffer */
+static
+void
+set_tuple_col_8(dtuple_t* tuple, int col, uint64_t data, byte* buf) {
+ dfield_t* dfield = dtuple_get_nth_field(tuple, col);
+ ut_ad(dfield->type.len == 8);
+ if (dfield->len == UNIV_SQL_NULL) {
+ dfield_set_data(dfield, buf, 8);
+ }
+ ut_ad(dfield->len == dfield->type.len && dfield->data);
+ mach_write_to_8(dfield->data, data);
+}
+
/** Does an insert for MySQL.
@param[in] mysql_rec row in the MySQL format
@param[in,out] prebuilt prebuilt struct in MySQL handle
@@ -1427,7 +1355,8 @@ row_mysql_get_table_status(
dberr_t
row_insert_for_mysql(
const byte* mysql_rec,
- row_prebuilt_t* prebuilt)
+ row_prebuilt_t* prebuilt,
+ ins_mode_t ins_mode)
{
trx_savept_t savept;
que_thr_t* thr;
@@ -1458,17 +1387,6 @@ row_insert_for_mysql(
} else if (high_level_read_only) {
return(DB_READ_ONLY);
}
- DBUG_EXECUTE_IF("mark_table_corrupted", {
- /* Mark the table corrupted for the clustered index */
- dict_index_t* index = dict_table_get_first_index(table);
- ut_ad(dict_index_is_clust(index));
- dict_set_corrupted(index, trx, "INSERT TABLE"); });
-
- if (dict_table_is_corrupted(table)) {
-
- ib::error() << "Table " << table->name << " is corrupt.";
- return(DB_TABLE_CORRUPT);
- }
DBUG_EXECUTE_IF("mark_table_corrupted", {
/* Mark the table corrupted for the clustered index */
@@ -1486,7 +1404,9 @@ row_insert_for_mysql(
row_mysql_delay_if_needed();
- trx_start_if_not_started_xa(trx, true);
+ if (!table->no_rollback()) {
+ trx_start_if_not_started_xa(trx, true);
+ }
row_get_prebuilt_insert_row(prebuilt);
node = prebuilt->ins_node;
@@ -1494,6 +1414,29 @@ row_insert_for_mysql(
row_mysql_convert_row_to_innobase(node->row, prebuilt, mysql_rec,
&blob_heap);
+ if (ins_mode != ROW_INS_NORMAL)
+ {
+ ut_ad(table->vers_start != table->vers_end);
+ /* Return back modified fields into mysql_rec, so that
+ upper logic may benefit from it (f.ex. 'on duplicate key'). */
+ const mysql_row_templ_t* t = prebuilt->get_template_by_col(table->vers_end);
+ ut_ad(t);
+ ut_ad(t->mysql_col_len == 8);
+
+ if (ins_mode == ROW_INS_HISTORICAL) {
+ set_tuple_col_8(node->row, table->vers_end, trx->id, node->vers_end_buf);
+ }
+ else /* ROW_INS_VERSIONED */ {
+ set_tuple_col_8(node->row, table->vers_end, TRX_ID_MAX, node->vers_end_buf);
+ int8store(&mysql_rec[t->mysql_col_offset], TRX_ID_MAX);
+ t = prebuilt->get_template_by_col(table->vers_start);
+ ut_ad(t);
+ ut_ad(t->mysql_col_len == 8);
+ set_tuple_col_8(node->row, table->vers_start, trx->id, node->vers_start_buf);
+ int8store(&mysql_rec[t->mysql_col_offset], trx->id);
+ }
+ }
+
savept = trx_savept_take(trx);
thr = que_fork_get_first_thr(prebuilt->ins_graph);
@@ -1594,9 +1537,21 @@ error_exit:
}
}
- /* Pass NULL for the columns affected, since an INSERT affects
- all FTS indexes. */
- fts_trx_add_op(trx, table, doc_id, FTS_INSERT, NULL);
+ if (table->skip_alter_undo) {
+ if (trx->fts_trx == NULL) {
+ trx->fts_trx = fts_trx_create(trx);
+ }
+
+ fts_trx_table_t ftt;
+ ftt.table = table;
+ ftt.fts_trx = trx->fts_trx;
+
+ fts_add_doc_from_tuple(&ftt, doc_id, node->row);
+ } else {
+ /* Pass NULL for the columns affected, since an INSERT affects
+ all FTS indexes. */
+ fts_trx_add_op(trx, table, doc_id, FTS_INSERT, NULL);
+ }
}
que_thr_stop_for_mysql_no_error(thr, trx);
@@ -1615,7 +1570,7 @@ error_exit:
if (prebuilt->clust_index_was_generated) {
/* set row id to prebuilt */
- ut_memcpy(prebuilt->row_id, node->row_id_buf, DATA_ROW_ID_LEN);
+ memcpy(prebuilt->row_id, node->sys_buf, DATA_ROW_ID_LEN);
}
dict_stats_update_if_needed(table);
@@ -1672,7 +1627,7 @@ row_create_update_node_for_mysql(
node = upd_node_create(heap);
node->in_mysql_interface = TRUE;
- node->is_delete = FALSE;
+ node->is_delete = NO_DELETE;
node->searched_update = FALSE;
node->select = NULL;
node->pcur = btr_pcur_create_for_mysql();
@@ -1693,8 +1648,6 @@ row_create_update_node_for_mysql(
node->table_sym = NULL;
node->col_assign_list = NULL;
- node->fts_doc_id = FTS_NULL_DOC_ID;
- node->fts_next_doc_id = UINT64_UNDEFINED;
DBUG_RETURN(node);
}
@@ -1742,9 +1695,9 @@ row_fts_do_update(
doc_id_t old_doc_id, /* in: old document id */
doc_id_t new_doc_id) /* in: new document id */
{
- fts_trx_add_op(trx, table, old_doc_id, FTS_DELETE, NULL);
-
- if (new_doc_id != FTS_NULL_DOC_ID) {
+ if(trx->fts_next_doc_id) {
+ fts_trx_add_op(trx, table, old_doc_id, FTS_DELETE, NULL);
+ if(new_doc_id != FTS_NULL_DOC_ID)
fts_trx_add_op(trx, table, new_doc_id, FTS_INSERT, NULL);
}
}
@@ -1756,24 +1709,30 @@ static
dberr_t
row_fts_update_or_delete(
/*=====================*/
- trx_t* trx,
- upd_node_t* node) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
handle */
{
- dict_table_t* table = node->table;
- doc_id_t old_doc_id = node->fts_doc_id;
+ trx_t* trx = prebuilt->trx;
+ dict_table_t* table = prebuilt->table;
+ upd_node_t* node = prebuilt->upd_node;
+ doc_id_t old_doc_id = prebuilt->fts_doc_id;
+
DBUG_ENTER("row_fts_update_or_delete");
- ut_a(dict_table_has_fts_index(node->table));
+ ut_a(dict_table_has_fts_index(prebuilt->table));
/* Deletes are simple; get them out of the way first. */
- if (node->is_delete) {
+ if (node->is_delete == PLAIN_DELETE) {
/* A delete affects all FTS indexes, so we pass NULL */
fts_trx_add_op(trx, table, old_doc_id, FTS_DELETE, NULL);
} else {
- doc_id_t new_doc_id = node->fts_next_doc_id;
- ut_ad(new_doc_id != UINT64_UNDEFINED);
+ doc_id_t new_doc_id;
+ new_doc_id = fts_read_doc_id((byte*) &trx->fts_next_doc_id);
+ if (new_doc_id == 0) {
+ ib::error() << "InnoDB FTS: Doc ID cannot be 0";
+ return(DB_FTS_INVALID_DOCID);
+ }
row_fts_do_update(trx, table, old_doc_id, new_doc_id);
}
@@ -1822,19 +1781,6 @@ init_fts_doc_id_for_ref(
}
}
-/* A functor for decrementing counters. */
-class ib_dec_counter {
-public:
- ib_dec_counter() {}
-
- void operator() (upd_node_t* node) {
- ut_ad(node->table->n_foreign_key_checks_running > 0);
- my_atomic_addlint(
- &node->table->n_foreign_key_checks_running, -1);
- }
-};
-
-
/** Does an update or delete of a row for MySQL.
@param[in,out] prebuilt prebuilt struct in MySQL handle
@return error code or DB_SUCCESS */
@@ -1844,15 +1790,11 @@ row_update_for_mysql(row_prebuilt_t* prebuilt)
trx_savept_t savept;
dberr_t err;
que_thr_t* thr;
- ibool was_lock_wait;
dict_index_t* clust_index;
upd_node_t* node;
dict_table_t* table = prebuilt->table;
trx_t* trx = prebuilt->trx;
ulint fk_depth = 0;
- upd_cascade_t* cascade_upd_nodes;
- upd_cascade_t* new_upd_nodes;
- upd_cascade_t* processed_cascades;
bool got_s_lock = false;
DBUG_ENTER("row_update_for_mysql");
@@ -1896,29 +1838,9 @@ row_update_for_mysql(row_prebuilt_t* prebuilt)
}
node = prebuilt->upd_node;
- const bool is_delete = node->is_delete;
+ const bool is_delete = node->is_delete == PLAIN_DELETE;
ut_ad(node->table == table);
- if (node->cascade_heap) {
- mem_heap_empty(node->cascade_heap);
- } else {
- node->cascade_heap = mem_heap_create(128);
- }
-
- mem_heap_allocator<upd_node_t*> mem_heap_ator(node->cascade_heap);
-
- cascade_upd_nodes = new
- (mem_heap_ator.allocate(sizeof(upd_cascade_t)))
- upd_cascade_t(deque_mem_heap_t(mem_heap_ator));
-
- new_upd_nodes = new
- (mem_heap_ator.allocate(sizeof(upd_cascade_t)))
- upd_cascade_t(deque_mem_heap_t(mem_heap_ator));
-
- processed_cascades = new
- (mem_heap_ator.allocate(sizeof(upd_cascade_t)))
- upd_cascade_t(deque_mem_heap_t(mem_heap_ator));
-
clust_index = dict_table_get_first_index(table);
if (prebuilt->pcur->btr_cur.index == clust_index) {
@@ -1943,121 +1865,97 @@ row_update_for_mysql(row_prebuilt_t* prebuilt)
node->state = UPD_NODE_UPDATE_CLUSTERED;
- node->cascade_top = true;
- node->cascade_upd_nodes = cascade_upd_nodes;
- node->new_upd_nodes = new_upd_nodes;
- node->processed_cascades = processed_cascades;
- node->fts_doc_id = prebuilt->fts_doc_id;
-
- if (trx->fts_next_doc_id != UINT64_UNDEFINED) {
- node->fts_next_doc_id = fts_read_doc_id(
- (byte*) &trx->fts_next_doc_id);
- } else {
- node->fts_next_doc_id = UINT64_UNDEFINED;
- }
-
ut_ad(!prebuilt->sql_stat_start);
que_thr_move_to_run_state_for_mysql(thr, trx);
- thr->fk_cascade_depth = 0;
+ ut_ad(!prebuilt->versioned_write || node->table->versioned());
+
+ bool vers_set_fields = prebuilt->versioned_write
+ && (node->is_delete ? node->is_delete == VERSIONED_DELETE
+ : node->update->affects_versioned());
+
+ for (;;) {
+ if (vers_set_fields) {
+ /* System Versioning: modify update vector to set
+ row_start (or row_end in case of DELETE)
+ to current trx_id. */
+ dict_table_t* table = node->table;
+ dict_index_t* clust_index = dict_table_get_first_index(table);
+ upd_t* uvect = node->update;
+ upd_field_t* ufield;
+ dict_col_t* col;
+ unsigned col_idx;
+ if (node->is_delete) {
+ ufield = &uvect->fields[0];
+ uvect->n_fields = 0;
+ node->is_delete = VERSIONED_DELETE;
+ col_idx = table->vers_end;
+ } else {
+ ut_ad(uvect->n_fields < table->n_cols);
+ ufield = &uvect->fields[uvect->n_fields];
+ col_idx = table->vers_start;
+ }
+ col = &table->cols[col_idx];
+ UNIV_MEM_INVALID(ufield, sizeof *ufield);
+ {
+ ulint field_no = dict_col_get_clust_pos(col, clust_index);
+ ut_ad(field_no != ULINT_UNDEFINED);
+ ufield->field_no = field_no;
+ }
+ ufield->orig_len = 0;
+ ufield->exp = NULL;
-run_again:
- if (thr->fk_cascade_depth == 1 && trx->dict_operation_lock_mode == 0) {
- got_s_lock = true;
- row_mysql_freeze_data_dictionary(trx);
- }
+ mach_write_to_8(node->update->vers_sys_value, trx->id);
+ dfield_t* dfield = &ufield->new_val;
+ dfield_set_data(dfield, node->update->vers_sys_value, 8);
+ dict_col_copy_type(col, &dfield->type);
- thr->run_node = node;
- thr->prev_node = node;
+ uvect->n_fields++;
+ ut_ad(node->in_mysql_interface); // otherwise needs to recalculate node->cmpl_info
+ }
- row_upd_step(thr);
+ thr->run_node = node;
+ thr->prev_node = node;
+ thr->fk_cascade_depth = 0;
- DBUG_EXECUTE_IF("dml_cascade_only_once", node->check_cascade_only_once(););
+ row_upd_step(thr);
- err = trx->error_state;
+ err = trx->error_state;
- if (err != DB_SUCCESS) {
+ if (err == DB_SUCCESS) {
+ break;
+ }
que_thr_stop_for_mysql(thr);
if (err == DB_RECORD_NOT_FOUND) {
trx->error_state = DB_SUCCESS;
- trx->op_info = "";
-
- if (thr->fk_cascade_depth > 0) {
- que_graph_free_recursive(node);
- }
goto error;
}
- /* Since reporting a plain "duplicate key" error message to
- the user in cases where a long CASCADE operation would lead
- to a duplicate key in some other table is very confusing,
- map duplicate key errors resulting from FK constraints to a
- separate error code. */
- if (err == DB_DUPLICATE_KEY && thr->fk_cascade_depth > 0) {
- err = DB_FOREIGN_DUPLICATE_KEY;
- trx->error_state = err;
- }
-
thr->lock_state= QUE_THR_LOCK_ROW;
DEBUG_SYNC(trx->mysql_thd, "row_update_for_mysql_error");
- was_lock_wait = row_mysql_handle_errors(&err, trx, thr,
- &savept);
+ bool was_lock_wait = row_mysql_handle_errors(
+ &err, trx, thr, &savept);
thr->lock_state= QUE_THR_LOCK_NOLOCK;
- if (was_lock_wait) {
- std::for_each(new_upd_nodes->begin(),
- new_upd_nodes->end(),
- ib_dec_counter());
- std::for_each(new_upd_nodes->begin(),
- new_upd_nodes->end(),
- que_graph_free_recursive);
- node->new_upd_nodes->clear();
- goto run_again;
- }
-
- trx->op_info = "";
-
- if (thr->fk_cascade_depth > 0) {
- que_graph_free_recursive(node);
+ if (!was_lock_wait) {
+ goto error;
}
- goto error;
- } else {
-
- std::copy(node->new_upd_nodes->begin(),
- node->new_upd_nodes->end(),
- std::back_inserter(*node->cascade_upd_nodes));
-
- node->new_upd_nodes->clear();
- }
-
- if (dict_table_has_fts_index(node->table)
- && node->fts_doc_id != FTS_NULL_DOC_ID
- && node->fts_next_doc_id != UINT64_UNDEFINED) {
- err = row_fts_update_or_delete(trx, node);
- ut_a(err == DB_SUCCESS);
}
- if (thr->fk_cascade_depth > 0) {
- /* Processing cascade operation */
- ut_ad(node->table->n_foreign_key_checks_running > 0);
- my_atomic_addlint(
- &node->table->n_foreign_key_checks_running, -1);
- node->processed_cascades->push_back(node);
- }
-
- if (!cascade_upd_nodes->empty()) {
- DEBUG_SYNC_C("foreign_constraint_update_cascade");
- node = cascade_upd_nodes->front();
- node->cascade_upd_nodes = cascade_upd_nodes;
- cascade_upd_nodes->pop_front();
- thr->fk_cascade_depth++;
+ que_thr_stop_for_mysql_no_error(thr, trx);
- goto run_again;
+ if (dict_table_has_fts_index(table)
+ && trx->fts_next_doc_id != UINT64_UNDEFINED) {
+ err = row_fts_update_or_delete(prebuilt);
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
+ ut_ad(!"unexpected error");
+ goto error;
+ }
}
/* Completed cascading operations (if any) */
@@ -2065,43 +1963,8 @@ run_again:
row_mysql_unfreeze_data_dictionary(trx);
}
- thr->fk_cascade_depth = 0;
-
- /* Update the statistics of each involved table
- only after completing all operations, including
- FOREIGN KEY...ON...CASCADE|SET NULL. */
bool update_statistics;
-
- for (upd_cascade_t::iterator i = processed_cascades->begin();
- i != processed_cascades->end();
- ++i) {
-
- node = *i;
-
- if (node->is_delete) {
- /* Not protected by dict_table_stats_lock() 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. */
- dict_table_n_rows_dec(node->table);
-
- update_statistics = !srv_stats_include_delete_marked;
- srv_stats.n_rows_deleted.inc(size_t(trx->id));
- } else {
- update_statistics
- = !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE);
- srv_stats.n_rows_updated.inc(size_t(trx->id));
- }
-
- if (update_statistics) {
- dict_stats_update_if_needed(node->table);
- } else {
- /* Always update the table modification counter. */
- node->table->stat_modified_counter++;
- }
-
- que_graph_free_recursive(node);
- }
+ ut_ad(is_delete == (node->is_delete == PLAIN_DELETE));
if (is_delete) {
/* Not protected by dict_table_stats_lock() for performance
@@ -2137,45 +2000,14 @@ run_again:
trx->op_info = "";
- que_thr_stop_for_mysql_no_error(thr, trx);
-
- DBUG_ASSERT(cascade_upd_nodes->empty());
-
DBUG_RETURN(err);
error:
+ trx->op_info = "";
if (got_s_lock) {
row_mysql_unfreeze_data_dictionary(trx);
}
- if (thr->fk_cascade_depth > 0) {
- ut_ad(node->table->n_foreign_key_checks_running > 0);
- my_atomic_addlint(
- &node->table->n_foreign_key_checks_running, -1);
- thr->fk_cascade_depth = 0;
- }
-
- /* Reset the table->n_foreign_key_checks_running counter */
- std::for_each(cascade_upd_nodes->begin(),
- cascade_upd_nodes->end(),
- ib_dec_counter());
-
- std::for_each(new_upd_nodes->begin(),
- new_upd_nodes->end(),
- ib_dec_counter());
-
- std::for_each(cascade_upd_nodes->begin(),
- cascade_upd_nodes->end(),
- que_graph_free_recursive);
-
- std::for_each(new_upd_nodes->begin(),
- new_upd_nodes->end(),
- que_graph_free_recursive);
-
- std::for_each(processed_cascades->begin(),
- processed_cascades->end(),
- que_graph_free_recursive);
-
DBUG_RETURN(err);
}
@@ -2342,6 +2174,133 @@ row_mysql_unfreeze_data_dictionary(
trx->dict_operation_lock_mode = 0;
}
+/**********************************************************************//**
+Does a cascaded delete or set null in a foreign key operation.
+@return error code or DB_SUCCESS */
+dberr_t
+row_update_cascade_for_mysql(
+/*=========================*/
+ que_thr_t* thr, /*!< in: query thread */
+ upd_node_t* node, /*!< in: update node used in the cascade
+ or set null operation */
+ dict_table_t* table) /*!< in: table where we do the operation */
+{
+ /* Increment fk_cascade_depth to record the recursive call depth on
+ a single update/delete that affects multiple tables chained
+ together with foreign key relations. */
+
+ if (++thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) {
+ return(DB_FOREIGN_EXCEED_MAX_CASCADE);
+ }
+
+ trx_t* trx = thr_get_trx(thr);
+
+ bool vers_set_fields = node->table->versioned()
+ && (node->is_delete == PLAIN_DELETE
+ || node->update->affects_versioned());
+
+ for (;;) {
+ if (vers_set_fields) {
+ // FIXME: code duplication with row_update_for_mysql()
+ /* System Versioning: modify update vector to set
+ row_start (or row_end in case of DELETE)
+ to current trx_id. */
+ dict_table_t* table = node->table;
+ dict_index_t* clust_index = dict_table_get_first_index(table);
+ upd_t* uvect = node->update;
+ upd_field_t* ufield;
+ dict_col_t* col;
+ unsigned col_idx;
+ if (node->is_delete) {
+ ufield = &uvect->fields[0];
+ uvect->n_fields = 0;
+ node->is_delete = VERSIONED_DELETE;
+ col_idx = table->vers_end;
+ } else {
+ ut_ad(uvect->n_fields < table->n_cols);
+ ufield = &uvect->fields[uvect->n_fields];
+ col_idx = table->vers_start;
+ }
+ col = &table->cols[col_idx];
+ UNIV_MEM_INVALID(ufield, sizeof *ufield);
+ {
+ ulint field_no = dict_col_get_clust_pos(col, clust_index);
+ ut_ad(field_no != ULINT_UNDEFINED);
+ ufield->field_no = field_no;
+ }
+ ufield->orig_len = 0;
+ ufield->exp = NULL;
+
+ mach_write_to_8(node->update->vers_sys_value, trx->id);
+ dfield_t* dfield = &ufield->new_val;
+ dfield_set_data(dfield, node->update->vers_sys_value, 8);
+ dict_col_copy_type(col, &dfield->type);
+
+ uvect->n_fields++;
+ ut_ad(node->in_mysql_interface); // otherwise needs to recalculate node->cmpl_info
+ }
+
+ thr->run_node = node;
+ thr->prev_node = node;
+
+ DEBUG_SYNC_C("foreign_constraint_update_cascade");
+ {
+ TABLE *mysql_table = thr->prebuilt->m_mysql_table;
+ thr->prebuilt->m_mysql_table = NULL;
+ row_upd_step(thr);
+ thr->prebuilt->m_mysql_table = mysql_table;
+ }
+
+ switch (trx->error_state) {
+ case DB_LOCK_WAIT:
+ que_thr_stop_for_mysql(thr);
+ lock_wait_suspend_thread(thr);
+
+ if (trx->error_state == DB_SUCCESS) {
+ continue;
+ }
+
+ /* fall through */
+ default:
+ /* Other errors are handled for the parent node. */
+ thr->fk_cascade_depth = 0;
+ return trx->error_state;
+
+ case DB_SUCCESS:
+ thr->fk_cascade_depth = 0;
+ bool stats;
+
+ if (node->is_delete == PLAIN_DELETE) {
+ /* Not protected by
+ dict_table_stats_lock() 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. */
+ dict_table_n_rows_dec(node->table);
+
+ stats = !srv_stats_include_delete_marked;
+ srv_stats.n_rows_deleted.inc(size_t(trx->id));
+ } else {
+ stats = !(node->cmpl_info
+ & UPD_NODE_NO_ORD_CHANGE);
+ srv_stats.n_rows_updated.inc(size_t(trx->id));
+ }
+
+ if (stats) {
+ dict_stats_update_if_needed(node->table);
+ } else {
+ /* Always update the table
+ modification counter. */
+ node->table->stat_modified_counter++;
+ }
+
+ return(DB_SUCCESS);
+ }
+ }
+}
+
/*********************************************************************//**
Locks the data dictionary exclusively for performing a table create or other
data dictionary modification operation. */
@@ -2812,12 +2771,6 @@ row_drop_table_for_mysql_in_background(
error = row_drop_table_for_mysql(name, trx, FALSE, FALSE);
- /* Flush the log to reduce probability that the .frm files and
- the InnoDB data dictionary get out-of-sync if the user runs
- with innodb_flush_log_at_trx_commit = 0 */
-
- log_buffer_flush_to_disk();
-
trx_commit_for_mysql(trx);
trx_free_for_background(trx);
@@ -2842,7 +2795,7 @@ loop:
mutex_enter(&row_drop_list_mutex);
ut_a(row_mysql_drop_list_inited);
-
+next:
drop = UT_LIST_GET_FIRST(row_mysql_drop_list);
n_tables = UT_LIST_GET_LEN(row_mysql_drop_list);
@@ -2855,61 +2808,41 @@ loop:
return(n_tables + n_tables_dropped);
}
- DBUG_EXECUTE_IF("row_drop_tables_in_background_sleep",
- os_thread_sleep(5000000);
- );
-
- table = dict_table_open_on_name(drop->table_name, FALSE, FALSE,
- DICT_ERR_IGNORE_NONE);
-
- if (table == NULL) {
- /* If for some reason the table has already been dropped
- through some other mechanism, do not try to drop it */
+ /* On fast shutdown, just empty the list without dropping tables. */
+ table = srv_shutdown_state == SRV_SHUTDOWN_NONE || !srv_fast_shutdown
+ ? dict_table_open_on_id(drop->table_id, FALSE,
+ DICT_TABLE_OP_OPEN_ONLY_IF_CACHED)
+ : NULL;
- goto already_dropped;
+ if (!table) {
+ n_tables_dropped++;
+ mutex_enter(&row_drop_list_mutex);
+ UT_LIST_REMOVE(row_mysql_drop_list, drop);
+ MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE);
+ ut_free(drop);
+ goto next;
}
+ ut_a(!table->can_be_evicted);
+
if (!table->to_be_dropped) {
- /* There is a scenario: the old table is dropped
- just after it's added into drop list, and new
- table with the same name is created, then we try
- to drop the new table in background. */
dict_table_close(table, FALSE, FALSE);
- goto already_dropped;
+ mutex_enter(&row_drop_list_mutex);
+ UT_LIST_REMOVE(row_mysql_drop_list, drop);
+ UT_LIST_ADD_LAST(row_mysql_drop_list, drop);
+ goto next;
}
- ut_a(!table->can_be_evicted);
-
dict_table_close(table, FALSE, FALSE);
if (DB_SUCCESS != row_drop_table_for_mysql_in_background(
- drop->table_name)) {
+ table->name.m_name)) {
/* If the DROP fails for some table, we return, and let the
main thread retry later */
-
return(n_tables + n_tables_dropped);
}
- n_tables_dropped++;
-
-already_dropped:
- mutex_enter(&row_drop_list_mutex);
-
- UT_LIST_REMOVE(row_mysql_drop_list, drop);
-
- MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE);
-
- ib::info() << "Dropped table "
- << ut_get_name(NULL, drop->table_name)
- << " in background drop queue.",
-
- ut_free(drop->table_name);
-
- ut_free(drop);
-
- mutex_exit(&row_drop_list_mutex);
-
goto loop;
}
@@ -2934,20 +2867,87 @@ row_get_background_drop_list_len_low(void)
return(len);
}
+/** Drop garbage tables during recovery. */
+void
+row_mysql_drop_garbage_tables()
+{
+ mem_heap_t* heap = mem_heap_create(FN_REFLEN);
+ btr_pcur_t pcur;
+ mtr_t mtr;
+ trx_t* trx = trx_allocate_for_background();
+ trx->op_info = "dropping garbage tables";
+ row_mysql_lock_data_dictionary(trx);
+
+ mtr.start();
+ btr_pcur_open_at_index_side(
+ true, dict_table_get_first_index(dict_sys->sys_tables),
+ BTR_SEARCH_LEAF, &pcur, true, 0, &mtr);
+
+ for (;;) {
+ const rec_t* rec;
+ const byte* field;
+ ulint len;
+ const char* table_name;
+
+ btr_pcur_move_to_next_user_rec(&pcur, &mtr);
+
+ if (!btr_pcur_is_on_user_rec(&pcur)) {
+ break;
+ }
+
+ rec = btr_pcur_get_rec(&pcur);
+ if (rec_get_deleted_flag(rec, 0)) {
+ continue;
+ }
+
+ field = rec_get_nth_field_old(rec, 0/*NAME*/, &len);
+ if (len == UNIV_SQL_NULL || len == 0) {
+ /* Corrupted SYS_TABLES.NAME */
+ continue;
+ }
+
+ table_name = mem_heap_strdupl(
+ heap,
+ reinterpret_cast<const char*>(field), len);
+ if (strstr(table_name, "/" TEMP_FILE_PREFIX "-")) {
+ btr_pcur_store_position(&pcur, &mtr);
+ btr_pcur_commit_specify_mtr(&pcur, &mtr);
+
+ if (dict_load_table(table_name, true,
+ DICT_ERR_IGNORE_ALL)) {
+ row_drop_table_for_mysql(
+ table_name, trx, FALSE, FALSE);
+ trx_commit_for_mysql(trx);
+ }
+
+ mtr.start();
+ btr_pcur_restore_position(BTR_SEARCH_LEAF,
+ &pcur, &mtr);
+ }
+
+ mem_heap_empty(heap);
+ }
+
+ btr_pcur_close(&pcur);
+ mtr.commit();
+ row_mysql_unlock_data_dictionary(trx);
+ trx_free_for_background(trx);
+ mem_heap_free(heap);
+}
+
/*********************************************************************//**
If a table is not yet in the drop list, adds the table to the list of tables
which the master thread drops in background. We need this on Unix because in
ALTER TABLE MySQL may call drop table even if the table has running queries on
it. Also, if there are running foreign key checks on the table, we drop the
table lazily.
-@return TRUE if the table was not yet in the drop list, and was added there */
+@return whether background DROP TABLE was scheduled for the first time */
static
-ibool
-row_add_table_to_background_drop_list(
-/*==================================*/
- const char* name) /*!< in: table name */
+bool
+row_add_table_to_background_drop_list(table_id_t table_id)
{
row_mysql_drop_t* drop;
+ bool added = true;
mutex_enter(&row_drop_list_mutex);
@@ -2958,27 +2958,21 @@ row_add_table_to_background_drop_list(
drop != NULL;
drop = UT_LIST_GET_NEXT(row_mysql_drop_list, drop)) {
- if (strcmp(drop->table_name, name) == 0) {
- /* Already in the list */
-
- mutex_exit(&row_drop_list_mutex);
-
- return(FALSE);
+ if (drop->table_id == table_id) {
+ added = false;
+ goto func_exit;
}
}
- drop = static_cast<row_mysql_drop_t*>(
- ut_malloc_nokey(sizeof(row_mysql_drop_t)));
-
- drop->table_name = mem_strdup(name);
+ drop = static_cast<row_mysql_drop_t*>(ut_malloc_nokey(sizeof *drop));
+ drop->table_id = table_id;
UT_LIST_ADD_LAST(row_mysql_drop_list, drop);
MONITOR_INC(MONITOR_BACKGROUND_DROP_TABLE);
-
+func_exit:
mutex_exit(&row_drop_list_mutex);
-
- return(TRUE);
+ return added;
}
/** Reassigns the table identifier of a table.
@@ -2997,9 +2991,6 @@ row_mysql_table_id_reassign(
dict_hdr_get_new_id(new_id, NULL, NULL, table, false);
- /* Remove all locks except the table-level S and X locks. */
- lock_remove_all_on_table(table, FALSE);
-
pars_info_add_ull_literal(info, "old_id", table->id);
pars_info_add_ull_literal(info, "new_id", *new_id);
@@ -3050,7 +3041,7 @@ row_discard_tablespace_begin(
if (table) {
dict_stats_wait_bg_to_stop_using_table(table, trx);
ut_a(!is_system_tablespace(table->space));
- ut_a(table->n_foreign_key_checks_running == 0);
+ ut_ad(!table->n_foreign_key_checks_running);
}
return(table);
@@ -3169,10 +3160,7 @@ row_discard_tablespace(
their operations.
3) Insert buffer: we remove all entries for the tablespace in
- the insert buffer tree.
-
- 4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0,
- we do not allow the discard. */
+ the insert buffer tree. */
ibuf_delete_for_discarded_space(table->space);
@@ -3296,19 +3284,9 @@ row_discard_tablespace_for_mysql(
err = DB_ERROR;
- } else if (table->n_foreign_key_checks_running > 0) {
- char table_name[MAX_FULL_NAME_LEN + 1];
-
- innobase_format_name(
- table_name, sizeof(table_name),
- table->name.m_name);
-
- ib_senderrf(trx->mysql_thd, IB_LOG_LEVEL_ERROR,
- ER_DISCARD_FK_CHECKS_RUNNING, table_name);
-
- err = DB_ERROR;
-
} else {
+ ut_ad(!table->n_foreign_key_checks_running);
+
/* Do foreign key constraint checks. */
err = row_discard_tablespace_foreign_key_checks(trx, table);
@@ -3531,7 +3509,7 @@ row_drop_single_table_tablespace(
/* If the tablespace is not in the cache, just delete the file. */
if (!fil_space_for_table_exists_in_mem(
- space_id, tablename, true, false, NULL, 0, table_flags)) {
+ space_id, tablename, true, NULL, table_flags)) {
/* Force a delete of any discarded or temporary files. */
fil_delete_file(filepath);
@@ -3745,11 +3723,7 @@ row_drop_table_for_mysql(
}
- DBUG_EXECUTE_IF("row_drop_table_add_to_background",
- row_add_table_to_background_drop_list(table->name.m_name);
- err = DB_SUCCESS;
- goto funct_exit;
- );
+ DBUG_EXECUTE_IF("row_drop_table_add_to_background", goto defer;);
/* TODO: could we replace the counter n_foreign_key_checks_running
with lock checks on the table? Acquire here an exclusive lock on the
@@ -3758,28 +3732,22 @@ row_drop_table_for_mysql(
checks take an IS or IX lock on the table. */
if (table->n_foreign_key_checks_running > 0) {
-
- const char* save_tablename = table->name.m_name;
- ibool added;
-
- added = row_add_table_to_background_drop_list(save_tablename);
-
- if (added) {
- ib::info() << "You are trying to drop table "
- << table->name
- << " though there is a foreign key check"
- " running on it. Adding the table to the"
- " background drop queue.";
-
- /* We return DB_SUCCESS to MySQL though the drop will
- happen lazily later */
-
- err = DB_SUCCESS;
+defer:
+ if (!strstr(table->name.m_name, "/" TEMP_FILE_PREFIX)) {
+ heap = mem_heap_create(FN_REFLEN);
+ const char* tmp_name
+ = dict_mem_create_temporary_tablename(
+ heap, table->name.m_name, table->id);
+ ib::info() << "Deferring DROP TABLE " << table->name
+ << "; renaming to " << tmp_name;
+ err = row_rename_table_for_mysql(
+ table->name.m_name, tmp_name, trx, false);
} else {
- /* The table is already in the background drop list */
- err = DB_ERROR;
+ err = DB_SUCCESS;
+ }
+ if (err == DB_SUCCESS) {
+ row_add_table_to_background_drop_list(table->id);
}
-
goto funct_exit;
}
@@ -3800,31 +3768,9 @@ row_drop_table_for_mysql(
/* Wait on background threads to stop using table */
fil_wait_crypt_bg_threads(table);
- if (table->get_ref_count() == 0) {
- lock_remove_all_on_table(table, TRUE);
- ut_a(table->n_rec_locks == 0);
- } else if (table->get_ref_count() > 0 || table->n_rec_locks > 0) {
- ibool added;
-
- added = row_add_table_to_background_drop_list(
- table->name.m_name);
-
- if (added) {
- ib::info() << "MySQL is trying to drop table "
- << table->name
- << " though there are still open handles to"
- " it. Adding the table to the background drop"
- " queue.";
-
- /* We return DB_SUCCESS to MySQL though the drop will
- happen lazily later */
- err = DB_SUCCESS;
- } else {
- /* The table is already in the background drop list */
- err = DB_ERROR;
- }
-
- goto funct_exit;
+ if (table->get_ref_count() > 0 || table->n_rec_locks > 0
+ || lock_table_has_locks(table)) {
+ goto defer;
}
/* The "to_be_dropped" marks table that is to be dropped, but
@@ -3834,11 +3780,6 @@ row_drop_table_for_mysql(
and it is free to be dropped */
table->to_be_dropped = false;
- /* If we get this far then the table to be dropped must not have
- any table or record locks on it. */
-
- ut_a(!lock_table_has_locks(table));
-
switch (trx_get_dict_operation(trx)) {
case TRX_DICT_OP_NONE:
trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
@@ -4022,9 +3963,11 @@ row_drop_table_for_mysql(
table_flags = table->flags;
ut_ad(!dict_table_is_temporary(table));
- err = row_drop_ancillary_fts_tables(table, trx);
- if (err != DB_SUCCESS) {
- break;
+ if (!table->no_rollback()) {
+ err = row_drop_ancillary_fts_tables(table, trx);
+ if (err != DB_SUCCESS) {
+ break;
+ }
}
/* Determine the tablespace filename before we drop
@@ -4548,7 +4491,7 @@ row_rename_table_for_mysql(
goto funct_exit;
- } else if (new_is_tmp) {
+ } else if (!old_is_tmp && new_is_tmp) {
/* MySQL is doing an ALTER TABLE command and it renames the
original table to a temporary table name. We want to preserve
the original foreign key constraint definitions despite the
@@ -4583,6 +4526,14 @@ row_rename_table_for_mysql(
goto funct_exit;
}
+ if (!table->is_temporary()) {
+ err = trx_undo_report_rename(trx, table);
+
+ if (err != DB_SUCCESS) {
+ goto funct_exit;
+ }
+ }
+
/* We use the private SQL parser of Innobase to generate the query
graphs needed in updating the dictionary data from system tables. */
@@ -4768,7 +4719,8 @@ row_rename_table_for_mysql(
}
}
- if (dict_table_has_fts_index(table)
+ if (err == DB_SUCCESS
+ && dict_table_has_fts_index(table)
&& !dict_tables_have_same_db(old_name, new_name)) {
err = fts_rename_aux_tables(table, new_name, trx);
if (err != DB_TABLE_NOT_FOUND) {
@@ -4884,6 +4836,8 @@ end:
DICT_ERR_IGNORE_NONE);
fk_tables.pop_front();
}
+
+ table->data_dir_path= NULL;
}
funct_exit:
@@ -4923,6 +4877,7 @@ funct_exit:
}
if (commit) {
+ DEBUG_SYNC(trx->mysql_thd, "before_rename_table_commit");
trx_commit_for_mysql(trx);
}
@@ -4935,59 +4890,6 @@ funct_exit:
return(err);
}
-/** Renames a partitioned table for MySQL.
-@param[in] old_name Old table name.
-@param[in] new_name New table name.
-@param[in,out] trx Transaction.
-@return error code or DB_SUCCESS */
-dberr_t
-row_rename_partitions_for_mysql(
- const char* old_name,
- const char* new_name,
- trx_t* trx)
-{
- char from_name[FN_REFLEN];
- char to_name[FN_REFLEN];
- ulint from_len = strlen(old_name);
- ulint to_len = strlen(new_name);
- char* table_name;
- dberr_t error = DB_TABLE_NOT_FOUND;
-
- ut_a(from_len < (FN_REFLEN - 4));
- ut_a(to_len < (FN_REFLEN - 4));
- memcpy(from_name, old_name, from_len);
- from_name[from_len] = '#';
- from_name[from_len + 1] = 0;
- while ((table_name = dict_get_first_table_name_in_db(from_name))) {
- ut_a(memcmp(table_name, from_name, from_len) == 0);
- /* Must match #[Pp]#<partition_name> */
- if (strlen(table_name) <= (from_len + 3)
- || table_name[from_len] != '#'
- || table_name[from_len + 2] != '#'
- || (table_name[from_len + 1] != 'P'
- && table_name[from_len + 1] != 'p')) {
-
- ut_ad(0);
- ut_free(table_name);
- continue;
- }
- memcpy(to_name, new_name, to_len);
- memcpy(to_name + to_len, table_name + from_len,
- strlen(table_name) - from_len + 1);
- error = row_rename_table_for_mysql(table_name, to_name,
- trx, false);
- if (error != DB_SUCCESS) {
- /* Rollback and return. */
- trx_rollback_for_mysql(trx);
- ut_free(table_name);
- return(error);
- }
- ut_free(table_name);
- }
- trx_commit_for_mysql(trx);
- return(error);
-}
-
/*********************************************************************//**
Scans an index for either COUNT(*) or CHECK TABLE.
If CHECK TABLE; Checks that the index contains entries in an ascending order,
@@ -5166,31 +5068,6 @@ not_ok:
goto loop;
}
-/*********************************************************************//**
-Determines if a table is a magic monitor table.
-@return true if monitor table */
-UNIV_INTERN
-bool
-row_is_magic_monitor_table(
-/*=======================*/
- const char* table_name) /*!< in: name of the table, in the
- form database/table_name */
-{
- const char* name; /* table_name without database/ */
- ulint len;
-
- name = dict_remove_db_name(table_name);
- len = strlen(name) + 1;
-
- return(STR_EQ(name, len, S_innodb_monitor)
- || STR_EQ(name, len, S_innodb_lock_monitor)
- || STR_EQ(name, len, S_innodb_tablespace_monitor)
- || STR_EQ(name, len, S_innodb_table_monitor)
-#ifdef UNIV_MEM_DEBUG
- || STR_EQ(name, len, S_innodb_mem_validate)
-#endif /* UNIV_MEM_DEBUG */
- );
-}
/*********************************************************************//**
Initialize this module */
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index f4f6d4cff9f..e84769e9d4e 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -705,6 +705,10 @@ row_purge_reset_trx_id(purge_node_t* node, mtr_t* mtr)
== row_get_rec_roll_ptr(rec, index, offsets)) {
ut_ad(!rec_get_deleted_flag(rec,
rec_offs_comp(offsets)));
+ DBUG_LOG("purge", "reset DB_TRX_ID="
+ << ib::hex(row_get_rec_trx_id(
+ rec, index, offsets)));
+
mtr->set_named_space(index->space);
if (page_zip_des_t* page_zip
= buf_block_get_page_zip(
@@ -718,13 +722,8 @@ row_purge_reset_trx_id(purge_node_t* node, mtr_t* mtr)
byte* ptr = rec_get_nth_field(
rec, offsets, trx_id_pos, &len);
ut_ad(len == DATA_TRX_ID_LEN);
- memset(ptr, 0, DATA_TRX_ID_LEN
- + DATA_ROLL_PTR_LEN);
- ptr[DATA_TRX_ID_LEN] = 1U
- << (ROLL_PTR_INSERT_FLAG_POS - CHAR_BIT
- * (DATA_ROLL_PTR_LEN - 1));
- mlog_log_string(ptr, DATA_TRX_ID_LEN
- + DATA_ROLL_PTR_LEN, mtr);
+ mlog_write_string(ptr, reset_trx_id,
+ sizeof reset_trx_id, mtr);
}
}
}
@@ -748,6 +747,7 @@ row_purge_upd_exist_or_extern_func(
mem_heap_t* heap;
ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_S));
+ ut_ad(!node->table->skip_alter_undo);
if (node->rec_type == TRX_UNDO_UPD_DEL_REC
|| (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
@@ -817,7 +817,7 @@ skip_secondaries:
&is_insert, &rseg_id,
&page_no, &offset);
- rseg = trx_sys->rseg_array[rseg_id];
+ rseg = trx_sys.rseg_array[rseg_id];
ut_a(rseg != NULL);
ut_ad(rseg->id == rseg_id);
@@ -905,12 +905,14 @@ row_purge_parse_undo_rec(
node->rec_type = type;
switch (type) {
+ case TRX_UNDO_RENAME_TABLE:
+ return false;
case TRX_UNDO_INSERT_DEFAULT:
case TRX_UNDO_INSERT_REC:
break;
default:
#ifdef UNIV_DEBUG
- ut_ad(0);
+ ut_ad(!"unknown undo log record type");
return false;
case TRX_UNDO_UPD_DEL_REC:
case TRX_UNDO_UPD_EXIST_REC:
@@ -1002,7 +1004,7 @@ err_exit:
if (!(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
ptr = trx_undo_rec_get_partial_row(
- ptr, clust_index, &node->row,
+ ptr, clust_index, node->update, &node->row,
type == TRX_UNDO_UPD_DEL_REC,
node->heap);
}
@@ -1029,6 +1031,7 @@ row_purge_record_func(
bool purged = true;
ut_ad(!node->found_clust);
+ ut_ad(!node->table->skip_alter_undo);
clust_index = dict_table_get_first_index(node->table);
diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc
index ccf58b9e73f..938f9156717 100644
--- a/storage/innobase/row/row0quiesce.cc
+++ b/storage/innobase/row/row0quiesce.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -67,7 +67,7 @@ row_quiesce_write_index_fields(
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing index fields.");
return(DB_IO_ERROR);
@@ -87,7 +87,7 @@ row_quiesce_write_index_fields(
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing index column.");
return(DB_IO_ERROR);
@@ -121,7 +121,7 @@ row_quiesce_write_indexes(
if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing index count.");
return(DB_IO_ERROR);
@@ -175,7 +175,7 @@ row_quiesce_write_indexes(
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing index meta-data.");
return(DB_IO_ERROR);
@@ -196,7 +196,7 @@ row_quiesce_write_indexes(
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing index name.");
return(DB_IO_ERROR);
@@ -239,7 +239,11 @@ row_quiesce_write_table(
mach_write_to_4(ptr, col->len);
ptr += sizeof(ib_uint32_t);
- mach_write_to_4(ptr, col->mbminmaxlen);
+ /* FIXME: This will not work if mbminlen>4.
+ This field is also redundant, because the lengths
+ are a property of the character set encoding, which
+ in turn is encodedin prtype above. */
+ mach_write_to_4(ptr, col->mbmaxlen * 5 + col->mbminlen);
ptr += sizeof(ib_uint32_t);
mach_write_to_4(ptr, col->ind);
@@ -256,7 +260,7 @@ row_quiesce_write_table(
if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing table column data.");
return(DB_IO_ERROR);
@@ -283,7 +287,7 @@ row_quiesce_write_table(
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing column name.");
return(DB_IO_ERROR);
@@ -315,7 +319,7 @@ row_quiesce_write_header(
if (fwrite(&value, 1, sizeof(value), file) != sizeof(value)) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing meta-data version number.");
return(DB_IO_ERROR);
@@ -345,7 +349,7 @@ row_quiesce_write_header(
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing hostname.");
return(DB_IO_ERROR);
@@ -365,7 +369,7 @@ row_quiesce_write_header(
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing table name.");
return(DB_IO_ERROR);
@@ -381,7 +385,7 @@ row_quiesce_write_header(
if (fwrite(row, 1, sizeof(ib_uint64_t), file) != sizeof(ib_uint64_t)) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing table autoinc value.");
return(DB_IO_ERROR);
@@ -405,7 +409,7 @@ row_quiesce_write_header(
if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno),
+ (ulong) errno, strerror(errno),
"while writing table meta-data.");
return(DB_IO_ERROR);
@@ -454,23 +458,21 @@ row_quiesce_write_cfg(
char msg[BUFSIZ];
- ut_snprintf(msg, sizeof(msg), "%s flush() failed",
- name);
+ snprintf(msg, sizeof(msg), "%s flush() failed", name);
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno), msg);
+ (ulong) errno, strerror(errno), msg);
}
if (fclose(file) != 0) {
char msg[BUFSIZ];
- ut_snprintf(msg, sizeof(msg), "%s flose() failed",
- name);
+ snprintf(msg, sizeof(msg), "%s flose() failed", name);
ib_senderrf(
thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
- errno, strerror(errno), msg);
+ (ulong) errno, strerror(errno), msg);
}
}
@@ -522,7 +524,7 @@ row_quiesce_table_start(
ut_ad(fil_space_get(table->space) != NULL);
ib::info() << "Sync to disk of " << table->name << " started.";
- if (trx_purge_state() != PURGE_STATE_DISABLED) {
+ if (srv_undo_sources) {
trx_purge_stop();
}
@@ -537,7 +539,10 @@ row_quiesce_table_start(
}
if (!trx_is_interrupted(trx)) {
- buf_LRU_flush_or_remove_pages(table->space, trx);
+ {
+ FlushObserver observer(table->space, trx, NULL);
+ buf_LRU_flush_or_remove_pages(table->space, &observer);
+ }
if (trx_is_interrupted(trx)) {
@@ -602,7 +607,7 @@ row_quiesce_table_complete(
ib::info() << "Deleting the meta-data file '" << cfg_name << "'";
}
- if (trx_purge_state() != PURGE_STATE_DISABLED) {
+ if (srv_undo_sources) {
trx_purge_run();
}
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index c9bd4533fd8..f9aa4fadacc 100644
--- a/storage/innobase/row/row0row.cc
+++ b/storage/innobase/row/row0row.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -41,7 +42,6 @@ Created 4/20/1996 Heikki Tuuri
#include "row0ext.h"
#include "row0upd.h"
#include "rem0cmp.h"
-#include "read0read.h"
#include "ut0mem.h"
#include "gis0geo.h"
#include "row0mysql.h"
@@ -195,13 +195,13 @@ row_build_index_entry_low(
dfield2);
break;
+ case SPATIAL_UNKNOWN:
+ ut_ad(0);
+ /* fall through */
case SPATIAL_NONE:
/* Undo record is logged before
spatial index is created.*/
return(NULL);
-
- case SPATIAL_UNKNOWN:
- ut_ad(0);
}
memcpy(mbr, ptr, DATA_MBR_LEN);
@@ -334,7 +334,7 @@ row_build_index_entry_low(
/* If a column prefix index, take only the prefix. */
if (ind_field->prefix_len) {
len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype, col->mbminlen, col->mbmaxlen,
ind_field->prefix_len, len,
static_cast<char*>(dfield_get_data(dfield)));
dfield_set_len(dfield, len);
@@ -396,7 +396,7 @@ row_build_low(
ut_ad(rec != NULL);
ut_ad(heap != NULL);
ut_ad(dict_index_is_clust(index));
- ut_ad(!trx_sys_mutex_own());
+ ut_ad(!mutex_own(&trx_sys.mutex));
ut_ad(!col_map || col_table);
if (!offsets) {
@@ -415,8 +415,9 @@ row_build_low(
times, and the cursor restore can happen multiple times for single
insert or update statement. */
ut_a(!rec_offs_any_null_extern(rec, offsets)
- || trx_rw_is_active(row_get_rec_trx_id(rec, index, offsets),
- NULL, false));
+ || trx_sys.is_registered(current_trx(),
+ row_get_rec_trx_id(rec, index,
+ offsets)));
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
if (type != ROW_COPY_POINTERS) {
@@ -876,7 +877,8 @@ row_build_row_ref(
dfield_set_len(dfield,
dtype_get_at_most_n_mbchars(
dtype->prtype,
- dtype->mbminmaxlen,
+ dtype->mbminlen,
+ dtype->mbmaxlen,
clust_col_prefix_len,
len, (char*) field));
}
@@ -977,7 +979,8 @@ row_build_row_ref_in_tuple(
dfield_set_len(dfield,
dtype_get_at_most_n_mbchars(
dtype->prtype,
- dtype->mbminmaxlen,
+ dtype->mbminlen,
+ dtype->mbmaxlen,
clust_col_prefix_len,
len, (char*) field));
}
@@ -1183,7 +1186,7 @@ row_raw_format_int(
value = mach_read_int_type(
(const byte*) data, data_len, unsigned_type);
- ret = ut_snprintf(
+ ret = snprintf(
buf, buf_size,
unsigned_type ? "%llu" : "%lld", (longlong) value)+1;
} else {
@@ -1282,7 +1285,7 @@ row_raw_format(
if (data_len == UNIV_SQL_NULL) {
- ret = ut_snprintf((char*) buf, buf_size, "NULL") + 1;
+ ret = snprintf((char*) buf, buf_size, "NULL") + 1;
return(ut_min(ret, buf_size));
}
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 11823087f1f..f8507443100 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -51,7 +51,6 @@ Created 12/19/1997 Heikki Tuuri
#include "pars0sym.h"
#include "pars0pars.h"
#include "row0mysql.h"
-#include "read0read.h"
#include "buf0lru.h"
#include "srv0srv.h"
#include "ha_prototypes.h"
@@ -88,8 +87,10 @@ row_sel_sec_rec_is_for_blob(
/*========================*/
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of
+ a character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of
+ a character, in bytes */
const byte* clust_field, /*!< in: the locally stored part of
the clustered index column, including
the BLOB pointer; the clustered
@@ -137,7 +138,7 @@ row_sel_sec_rec_is_for_blob(
return(FALSE);
}
- len = dtype_get_at_most_n_mbchars(prtype, mbminmaxlen,
+ len = dtype_get_at_most_n_mbchars(prtype, mbminlen, mbmaxlen,
prefix_len, len, (const char*) buf);
return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
@@ -259,14 +260,14 @@ row_sel_sec_rec_is_for_clust_rec(
}
len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype, col->mbminlen, col->mbmaxlen,
ifield->prefix_len, len, (char*) clust_field);
if (rec_offs_nth_extern(clust_offs, clust_pos)
&& len < sec_len) {
if (!row_sel_sec_rec_is_for_blob(
col->mtype, col->prtype,
- col->mbminmaxlen,
+ col->mbminlen, col->mbmaxlen,
clust_field, clust_len,
sec_field, sec_len,
ifield->prefix_len,
@@ -799,7 +800,7 @@ row_sel_build_committed_vers_for_mysql(
rec_offs_size(*offsets));
}
- row_vers_build_for_semi_consistent_read(
+ row_vers_build_for_semi_consistent_read(prebuilt->trx,
rec, mtr, clust_index, offsets, offset_heap,
prebuilt->old_vers_heap, old_vers, vrow);
}
@@ -1027,7 +1028,7 @@ row_sel_get_clust_rec(
/* Fetch the columns needed in test conditions. The clustered
index record is protected by a page latch that was acquired
when plan->clust_pcur was positioned. The latch will not be
- released until mtr_commit(mtr). */
+ released until mtr->commit(). */
ut_ad(!rec_get_deleted_flag(clust_rec, rec_offs_comp(offsets)));
row_sel_fetch_columns(index, clust_rec, offsets,
@@ -1094,14 +1095,14 @@ retry:
if (err == DB_LOCK_WAIT) {
re_scan:
- mtr_commit(mtr);
+ mtr->commit();
trx->error_state = err;
que_thr_stop_for_mysql(thr);
thr->lock_state = QUE_THR_LOCK_ROW;
if (row_mysql_handle_errors(
&err, trx, thr, NULL)) {
thr->lock_state = QUE_THR_LOCK_NOLOCK;
- mtr_start(mtr);
+ mtr->start();
mutex_enter(&match->rtr_match_mutex);
if (!match->valid && match->matched_recs->empty()) {
@@ -1121,7 +1122,7 @@ re_scan:
RW_X_LATCH, NULL, BUF_GET,
__FILE__, __LINE__, mtr, &err);
} else {
- mtr_start(mtr);
+ mtr->start();
goto func_end;
}
@@ -1129,8 +1130,8 @@ re_scan:
if (!match->valid) {
/* Page got deleted */
- mtr_commit(mtr);
- mtr_start(mtr);
+ mtr->commit();
+ mtr->start();
err = DB_RECORD_NOT_FOUND;
goto func_end;
}
@@ -1148,8 +1149,8 @@ re_scan:
/* Page got splitted and promoted (only for
root page it is possible). Release the
page and ask for a re-search */
- mtr_commit(mtr);
- mtr_start(mtr);
+ mtr->commit();
+ mtr->start();
err = DB_RECORD_NOT_FOUND;
goto func_end;
}
@@ -1161,8 +1162,8 @@ re_scan:
/* No match record */
if (page_rec_is_supremum(rec) || !match->valid) {
- mtr_commit(mtr);
- mtr_start(mtr);
+ mtr->commit();
+ mtr->start();
err = DB_RECORD_NOT_FOUND;
goto func_end;
}
@@ -1272,24 +1273,19 @@ static
void
row_sel_open_pcur(
/*==============*/
- plan_t* plan, /*!< in: table plan */
- ibool search_latch_locked,
- /*!< in: TRUE if the thread currently
- has the search latch locked in
- s-mode */
- mtr_t* mtr) /*!< in: mtr */
+ plan_t* plan, /*!< in: table plan */
+#ifdef BTR_CUR_HASH_ADAPT
+ rw_lock_t* ahi_latch,
+ /*!< in: the adaptive hash index latch */
+#endif /* BTR_CUR_HASH_ADAPT */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
{
dict_index_t* index;
func_node_t* cond;
que_node_t* exp;
ulint n_fields;
- ulint has_search_latch = 0; /* RW_S_LATCH or 0 */
ulint i;
- if (search_latch_locked) {
- has_search_latch = RW_S_LATCH;
- }
-
index = plan->index;
/* Calculate the value of the search tuple: the exact match columns
@@ -1325,7 +1321,7 @@ row_sel_open_pcur(
btr_pcur_open_with_no_init(index, plan->tuple, plan->mode,
BTR_SEARCH_LEAF, &plan->pcur,
- has_search_latch, mtr);
+ ahi_latch, mtr);
} else {
/* Open the cursor to the start or the end of the index
(FALSE: no init) */
@@ -1462,45 +1458,27 @@ row_sel_try_search_shortcut(
sel_node_t* node, /*!< in: select node for a consistent read */
plan_t* plan, /*!< in: plan for a unique search in clustered
index */
- ibool search_latch_locked,
- /*!< in: whether the search holds latch on
- search system. */
mtr_t* mtr) /*!< in: mtr */
{
- dict_index_t* index;
- rec_t* rec;
- mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
- ulint ret;
- rec_offs_init(offsets_);
-
- index = plan->index;
+ dict_index_t* index = plan->index;
ut_ad(node->read_view);
ut_ad(plan->unique_search);
ut_ad(!plan->must_get_clust);
- ut_ad(!search_latch_locked
- || rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
- row_sel_open_pcur(plan, search_latch_locked, mtr);
+ rw_lock_t* ahi_latch = btr_get_search_latch(index);
+ rw_lock_s_lock(ahi_latch);
- rec = btr_pcur_get_rec(&(plan->pcur));
+ row_sel_open_pcur(plan, ahi_latch, mtr);
- if (!page_rec_is_user_rec(rec)) {
+ const rec_t* rec = btr_pcur_get_rec(&(plan->pcur));
+ if (!page_rec_is_user_rec(rec) || rec_is_default_row(rec, index)) {
+retry:
+ rw_lock_s_unlock(ahi_latch);
return(SEL_RETRY);
}
- if (rec_is_default_row(rec, index)) {
- /* Skip the 'default row' pseudo-record. */
- if (!btr_pcur_move_to_next_user_rec(&plan->pcur, mtr)) {
- return(SEL_RETRY);
- }
-
- rec = btr_pcur_get_rec(&plan->pcur);
- }
-
ut_ad(plan->mode == PAGE_CUR_GE);
/* As the cursor is now placed on a user record after a search with
@@ -1508,42 +1486,40 @@ row_sel_try_search_shortcut(
fields in the user record matched to the search tuple */
if (btr_pcur_get_up_match(&(plan->pcur)) < plan->n_exact_match) {
-
+exhausted:
+ rw_lock_s_unlock(ahi_latch);
return(SEL_EXHAUSTED);
}
/* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */
+ mem_heap_t* heap = NULL;
+ ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ ulint* offsets = offsets_;
+ rec_offs_init(offsets_);
offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
if (dict_index_is_clust(index)) {
if (!lock_clust_rec_cons_read_sees(rec, index, offsets,
node->read_view)) {
- ret = SEL_RETRY;
- goto func_exit;
+ goto retry;
}
} else if (!srv_read_only_mode
&& !lock_sec_rec_cons_read_sees(
rec, index, node->read_view)) {
-
- ret = SEL_RETRY;
- goto func_exit;
+ goto retry;
}
- /* Test the deleted flag. */
-
if (rec_get_deleted_flag(rec, dict_table_is_comp(plan->table))) {
-
- ret = SEL_EXHAUSTED;
- goto func_exit;
+ goto exhausted;
}
/* Fetch the columns needed in test conditions. The index
record is protected by a page latch that was acquired when
plan->pcur was positioned. The latch will not be released
- until mtr_commit(mtr). */
+ until mtr->commit(). */
row_sel_fetch_columns(index, rec, offsets,
UT_LIST_GET_FIRST(plan->columns));
@@ -1551,20 +1527,18 @@ row_sel_try_search_shortcut(
/* Test the rest of search conditions */
if (!row_sel_test_other_conds(plan)) {
-
- ret = SEL_EXHAUSTED;
- goto func_exit;
+ goto exhausted;
}
ut_ad(plan->pcur.latch_mode == BTR_SEARCH_LEAF);
plan->n_rows_fetched++;
- ret = SEL_FOUND;
-func_exit:
+ rw_lock_s_unlock(ahi_latch);
+
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
- return(ret);
+ return(SEL_FOUND);
}
#endif /* BTR_CUR_HASH_ADAPT */
@@ -1611,12 +1585,6 @@ row_sel(
ut_ad(thr->run_node == node);
-#ifdef BTR_CUR_HASH_ADAPT
- ibool search_latch_locked = FALSE;
-#else /* BTR_CUR_HASH_ADAPT */
-# define search_latch_locked false
-#endif /* BTR_CUR_HASH_ADAPT */
-
if (node->read_view) {
/* In consistent reads, we try to do with the hash index and
not to use the buffer page get. This is to reduce memory bus
@@ -1660,60 +1628,38 @@ table_loop:
/* Open a cursor to index, or restore an open cursor position */
- mtr_start(&mtr);
+ mtr.start();
#ifdef BTR_CUR_HASH_ADAPT
if (consistent_read && plan->unique_search && !plan->pcur_is_open
&& !plan->must_get_clust) {
- if (!search_latch_locked) {
- btr_search_s_lock(index);
-
- search_latch_locked = TRUE;
- } else if (rw_lock_get_writer(btr_get_search_latch(index))
- == RW_LOCK_X_WAIT) {
-
- /* There is an x-latch request waiting: release the
- s-latch for a moment; as an s-latch here is often
- kept for some 10 searches before being released,
- a waiting x-latch request would block other threads
- from acquiring an s-latch for a long time, lowering
- performance significantly in multiprocessors. */
-
- btr_search_s_unlock(index);
- btr_search_s_lock(index);
- }
-
- switch (row_sel_try_search_shortcut(node, plan,
- search_latch_locked,
- &mtr)) {
+ switch (row_sel_try_search_shortcut(node, plan, &mtr)) {
case SEL_FOUND:
goto next_table;
case SEL_EXHAUSTED:
goto table_exhausted;
default:
ut_ad(0);
+ /* fall through */
case SEL_RETRY:
break;
}
plan_reset_cursor(plan);
- mtr_commit(&mtr);
- mtr_start(&mtr);
- }
-
- if (search_latch_locked) {
- btr_search_s_unlock(index);
-
- search_latch_locked = FALSE;
+ mtr.commit();
+ mtr.start();
}
#endif /* BTR_CUR_HASH_ADAPT */
if (!plan->pcur_is_open) {
/* Evaluate the expressions to build the search tuple and
open the cursor */
-
- row_sel_open_pcur(plan, search_latch_locked, &mtr);
+ row_sel_open_pcur(plan,
+#ifdef BTR_CUR_HASH_ADAPT
+ NULL,
+#endif /* BTR_CUR_HASH_ADAPT */
+ &mtr);
cursor_just_opened = TRUE;
@@ -1966,7 +1912,7 @@ skip_lock:
by row_sel_open_pcur() or
row_sel_restore_pcur_pos().
The latch will not be released
- until mtr_commit(mtr). */
+ until mtr.commit(). */
row_sel_fetch_columns(
index, rec, offsets,
@@ -1996,7 +1942,7 @@ skip_lock:
/* Fetch the columns needed in test conditions. The record is
protected by a page latch that was acquired by
row_sel_open_pcur() or row_sel_restore_pcur_pos(). The latch
- will not be released until mtr_commit(mtr). */
+ will not be released until mtr.commit(). */
row_sel_fetch_columns(index, rec, offsets,
UT_LIST_GET_FIRST(plan->columns));
@@ -2116,8 +2062,6 @@ skip_lock:
}
next_rec:
- ut_ad(!search_latch_locked);
-
if (mtr_has_extra_clust_latch) {
/* We must commit &mtr if we are moving to the next
@@ -2155,14 +2099,12 @@ next_table:
plan->cursor_at_end = TRUE;
} else {
- ut_ad(!search_latch_locked);
-
plan->stored_cursor_rec_processed = TRUE;
btr_pcur_store_position(&(plan->pcur), &mtr);
}
- mtr_commit(&mtr);
+ mtr.commit();
mtr_has_extra_clust_latch = FALSE;
@@ -2202,7 +2144,7 @@ table_exhausted:
plan->cursor_at_end = TRUE;
- mtr_commit(&mtr);
+ mtr.commit();
mtr_has_extra_clust_latch = FALSE;
@@ -2247,12 +2189,10 @@ stop_for_a_while:
inserted new records which should have appeared in the result set,
which would result in the phantom problem. */
- ut_ad(!search_latch_locked);
-
plan->stored_cursor_rec_processed = FALSE;
btr_pcur_store_position(&(plan->pcur), &mtr);
- mtr_commit(&mtr);
+ mtr.commit();
ut_ad(!sync_check_iterate(sync_check()));
err = DB_SUCCESS;
@@ -2265,10 +2205,9 @@ commit_mtr_for_a_while:
plan->stored_cursor_rec_processed = TRUE;
- ut_ad(!search_latch_locked);
btr_pcur_store_position(&(plan->pcur), &mtr);
- mtr_commit(&mtr);
+ mtr.commit();
mtr_has_extra_clust_latch = FALSE;
ut_ad(!sync_check_iterate(dict_sync_check()));
@@ -2279,19 +2218,13 @@ lock_wait_or_error:
/* See the note at stop_for_a_while: the same holds for this case */
ut_ad(!btr_pcur_is_before_first_on_page(&plan->pcur) || !node->asc);
- ut_ad(!search_latch_locked);
plan->stored_cursor_rec_processed = FALSE;
btr_pcur_store_position(&(plan->pcur), &mtr);
- mtr_commit(&mtr);
+ mtr.commit();
func_exit:
-#ifdef BTR_CUR_HASH_ADAPT
- if (search_latch_locked) {
- btr_search_s_unlock(index);
- }
-#endif /* BTR_CUR_HASH_ADAPT */
ut_ad(!sync_check_iterate(dict_sync_check()));
if (heap != NULL) {
@@ -2336,15 +2269,11 @@ row_sel_step(
plan_reset_cursor(sel_node_get_nth_plan(node, 0));
if (node->consistent_read) {
+ trx_t *trx = thr_get_trx(thr);
/* Assign a read view for the query */
- trx_assign_read_view(thr_get_trx(thr));
-
- if (thr_get_trx(thr)->read_view != NULL) {
- node->read_view = thr_get_trx(thr)->read_view;
- } else {
- node->read_view = NULL;
- }
-
+ trx->read_view.open(trx);
+ node->read_view = trx->read_view.is_open() ?
+ &trx->read_view : NULL;
} else {
sym_node_t* table_node;
lock_mode i_lock_mode;
@@ -3414,8 +3343,14 @@ row_sel_get_clust_rec_for_mysql(
goto func_exit;
}
- buf_block_t* block = btr_pcur_get_block(
- prebuilt->pcur);
+ /* FIXME: Why is this block not the
+ same as btr_pcur_get_block(prebuilt->pcur),
+ and is it not unsafe to use RW_NO_LATCH here? */
+ buf_block_t* block = buf_page_get_gen(
+ btr_pcur_get_block(prebuilt->pcur)->page.id,
+ dict_table_page_size(sec_index->table),
+ RW_NO_LATCH, NULL, BUF_GET,
+ __FILE__, __LINE__, mtr, &err);
mem_heap_t* heap = mem_heap_create(256);
dtuple_t* tuple = dict_index_build_data_tuple(
rec, sec_index, true,
@@ -3502,12 +3437,12 @@ row_sel_get_clust_rec_for_mysql(
if (trx->isolation_level > TRX_ISO_READ_UNCOMMITTED
&& !lock_clust_rec_cons_read_sees(
clust_rec, clust_index, *offsets,
- trx_get_read_view(trx))) {
+ &trx->read_view)) {
/* The following call returns 'offsets' associated with
'old_vers' */
err = row_sel_build_prev_vers_for_mysql(
- trx->read_view, clust_index, prebuilt,
+ &trx->read_view, clust_index, prebuilt,
clust_rec, offsets, offset_heap, &old_vers,
vrow, mtr);
@@ -3898,30 +3833,25 @@ row_sel_try_search_shortcut_for_mysql(
ut_ad(dict_index_is_clust(index));
ut_ad(!prebuilt->templ_contains_blob);
+ rw_lock_t* ahi_latch = btr_get_search_latch(index);
+ rw_lock_s_lock(ahi_latch);
btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
- BTR_SEARCH_LEAF, pcur, RW_S_LATCH, mtr);
+ BTR_SEARCH_LEAF, pcur, ahi_latch, mtr);
rec = btr_pcur_get_rec(pcur);
- if (!page_rec_is_user_rec(rec)) {
-
+ if (!page_rec_is_user_rec(rec) || rec_is_default_row(rec, index)) {
+retry:
+ rw_lock_s_unlock(ahi_latch);
return(SEL_RETRY);
}
- if (rec_is_default_row(rec, index)) {
- /* Skip the 'default row' pseudo-record. */
- if (!btr_pcur_move_to_next_user_rec(pcur, mtr)) {
- return(SEL_RETRY);
- }
-
- rec = btr_pcur_get_rec(pcur);
- }
-
/* As the cursor is now placed on a user record after a search with
the mode PAGE_CUR_GE, the up_match field in the cursor tells how many
fields in the user record matched to the search tuple */
if (btr_pcur_get_up_match(pcur) < dtuple_get_n_fields(search_tuple)) {
-
+exhausted:
+ rw_lock_s_unlock(ahi_latch);
return(SEL_EXHAUSTED);
}
@@ -3931,22 +3861,21 @@ row_sel_try_search_shortcut_for_mysql(
*offsets = rec_get_offsets(rec, index, *offsets, true,
ULINT_UNDEFINED, heap);
- if (!lock_clust_rec_cons_read_sees(
- rec, index, *offsets, trx_get_read_view(trx))) {
-
- return(SEL_RETRY);
+ if (!lock_clust_rec_cons_read_sees(rec, index, *offsets,
+ &trx->read_view)) {
+ goto retry;
}
if (rec_get_deleted_flag(rec, dict_table_is_comp(index->table))) {
/* In delete-marked records, DB_TRX_ID must
always refer to an existing undo log record. */
ut_ad(row_get_rec_trx_id(rec, index, *offsets));
-
- return(SEL_EXHAUSTED);
+ goto exhausted;
}
*out_rec = rec;
+ rw_lock_s_unlock(ahi_latch);
return(SEL_FOUND);
}
#endif /* BTR_CUR_HASH_ADAPT */
@@ -4313,7 +4242,7 @@ row_search_mvcc(
goto func_exit;
}
- mtr_start(&mtr);
+ mtr.start();
#ifdef BTR_CUR_HASH_ADAPT
/*-------------------------------------------------------------*/
@@ -4335,24 +4264,14 @@ row_search_mvcc(
mode = PAGE_CUR_GE;
- if (trx->mysql_n_tables_locked == 0
- && prebuilt->select_lock_type == LOCK_NONE
+ if (prebuilt->select_lock_type == LOCK_NONE
&& trx->isolation_level > TRX_ISO_READ_UNCOMMITTED
- && MVCC::is_view_active(trx->read_view)) {
+ && trx->read_view.is_open()) {
/* This is a SELECT query done as a consistent read,
and the read view has already been allocated:
let us try a search shortcut through the hash
- index.
- NOTE that we must also test that
- mysql_n_tables_locked == 0, because this might
- also be INSERT INTO ... SELECT ... or
- CREATE TABLE ... SELECT ... . Our algorithm is
- NOT prepared to inserts interleaved with the SELECT,
- and if we try that, we can deadlock on the adaptive
- hash index semaphore! */
-
- rw_lock_s_lock(btr_get_search_latch(index));
+ index. */
switch (row_sel_try_search_shortcut_for_mysql(
&rec, prebuilt, &offsets, &heap,
@@ -4362,7 +4281,7 @@ row_search_mvcc(
a page latch that was acquired by
row_sel_try_search_shortcut_for_mysql().
The latch will not be released until
- mtr_commit(&mtr). */
+ mtr.commit(). */
ut_ad(!rec_get_deleted_flag(rec, comp));
if (prebuilt->idx_cond) {
@@ -4399,28 +4318,19 @@ row_search_mvcc(
}
shortcut_match:
- mtr_commit(&mtr);
+ mtr.commit();
/* NOTE that we do NOT store the cursor
position */
-
err = DB_SUCCESS;
-
- rw_lock_s_unlock(btr_get_search_latch(index));
-
goto func_exit;
case SEL_EXHAUSTED:
shortcut_mismatch:
- mtr_commit(&mtr);
-
- err = DB_RECORD_NOT_FOUND;
-
- rw_lock_s_unlock(btr_get_search_latch(index));
-
+ mtr.commit();
/* NOTE that we do NOT store the cursor
position */
-
+ err = DB_RECORD_NOT_FOUND;
goto func_exit;
case SEL_RETRY:
@@ -4430,10 +4340,8 @@ row_search_mvcc(
ut_ad(0);
}
- mtr_commit(&mtr);
- mtr_start(&mtr);
-
- rw_lock_s_unlock(btr_get_search_latch(index));
+ mtr.commit();
+ mtr.start();
}
}
#endif /* BTR_CUR_HASH_ADAPT */
@@ -4457,7 +4365,7 @@ row_search_mvcc(
ut_ad(prebuilt->sql_stat_start
|| prebuilt->select_lock_type != LOCK_NONE
- || MVCC::is_view_active(trx->read_view)
+ || trx->read_view.is_open()
|| prebuilt->table->no_rollback()
|| srv_read_only_mode);
@@ -4504,7 +4412,7 @@ row_search_mvcc(
} else if (!prebuilt->sql_stat_start) {
/* No need to set an intention lock or assign a read view */
- if (!MVCC::is_view_active(trx->read_view)
+ if (!trx->read_view.is_open()
&& !srv_read_only_mode
&& prebuilt->select_lock_type == LOCK_NONE) {
@@ -4520,9 +4428,7 @@ row_search_mvcc(
/* Assign a read view for the query */
trx_start_if_not_started(trx, false);
- if (!srv_read_only_mode) {
- trx_assign_read_view(trx);
- }
+ trx->read_view.open(trx);
prebuilt->sql_stat_start = FALSE;
} else {
@@ -4952,9 +4858,44 @@ wrong_offs:
ulint lock_type;
+ if (srv_locks_unsafe_for_binlog
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
+ /* At READ COMMITTED or READ UNCOMMITTED
+ isolation levels, do not lock committed
+ delete-marked records. */
+ if (!rec_get_deleted_flag(rec, comp)) {
+ goto no_gap_lock;
+ }
+ if (index == clust_index) {
+ trx_id_t trx_id = row_get_rec_trx_id(
+ rec, index, offsets);
+ /* In delete-marked records, DB_TRX_ID must
+ always refer to an existing undo log record. */
+ ut_ad(trx_id);
+ if (!trx_sys.is_registered(trx, trx_id)) {
+ /* The clustered index record
+ was delete-marked in a committed
+ transaction. Ignore the record. */
+ goto locks_ok_del_marked;
+ }
+ } else if (trx_t* t = row_vers_impl_x_locked(
+ trx, rec, index, offsets)) {
+ /* The record belongs to an active
+ transaction. We must acquire a lock. */
+ t->release_reference();
+ } else {
+ /* The secondary index record does not
+ point to a delete-marked clustered index
+ record that belongs to an active transaction.
+ Ignore the secondary index record, because
+ it is not locked. */
+ goto next_rec;
+ }
+
+ goto no_gap_lock;
+ }
+
if (!set_also_gap_locks
- || srv_locks_unsafe_for_binlog
- || trx->isolation_level <= TRX_ISO_READ_COMMITTED
|| (unique_search && !rec_get_deleted_flag(rec, comp))
|| dict_index_is_spatial(index)) {
@@ -5091,14 +5032,13 @@ no_gap_lock:
if (srv_force_recovery < 5
&& !lock_clust_rec_cons_read_sees(
- rec, index, offsets,
- trx_get_read_view(trx))) {
+ rec, index, offsets, &trx->read_view)) {
rec_t* old_vers;
/* The following call returns 'offsets'
associated with 'old_vers' */
err = row_sel_build_prev_vers_for_mysql(
- trx->read_view, clust_index,
+ &trx->read_view, clust_index,
prebuilt, rec, &offsets, &heap,
&old_vers, need_vrow ? &vrow : NULL,
&mtr);
@@ -5128,7 +5068,7 @@ no_gap_lock:
if (!srv_read_only_mode
&& !lock_sec_rec_cons_read_sees(
- rec, index, trx->read_view)) {
+ rec, index, &trx->read_view)) {
/* We should look at the clustered index.
However, as this is a non-locking read,
we can skip the clustered index lookup if
@@ -5159,6 +5099,7 @@ locks_ok:
page_rec_is_comp() cannot be used! */
if (rec_get_deleted_flag(rec, comp)) {
+locks_ok_del_marked:
/* In delete-marked records, DB_TRX_ID must
always refer to an existing undo log record. */
ut_ad(index != clust_index
@@ -5166,17 +5107,6 @@ locks_ok:
/* The record is delete-marked: we can skip it */
- if ((srv_locks_unsafe_for_binlog
- || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
- && prebuilt->select_lock_type != LOCK_NONE
- && !did_semi_consistent_read) {
-
- /* No need to keep a lock on a delete-marked record
- if we do not want to use next-key locking. */
-
- row_unlock_for_mysql(prebuilt, TRUE);
- }
-
/* This is an optimization to skip setting the next key lock
on the record that follows this delete-marked record. This
optimization works because of the unique search criteria
@@ -5391,7 +5321,7 @@ requires_clust_rec:
/* Decide whether to prefetch extra rows.
At this point, the clustered index record is protected
by a page latch that was acquired when pcur was positioned.
- The latch will not be released until mtr_commit(&mtr). */
+ The latch will not be released until mtr.commit(). */
if ((match_mode == ROW_SEL_EXACT
|| prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD)
@@ -5583,10 +5513,10 @@ next_rec:
btr_pcur_store_position(pcur, &mtr);
}
- mtr_commit(&mtr);
+ mtr.commit();
mtr_has_extra_clust_latch = FALSE;
- mtr_start(&mtr);
+ mtr.start();
if (!spatial_search
&& sel_restore_position_for_mysql(&same_user_rec,
@@ -5644,7 +5574,7 @@ lock_wait_or_error:
}
lock_table_wait:
- mtr_commit(&mtr);
+ mtr.commit();
mtr_has_extra_clust_latch = FALSE;
trx->error_state = err;
@@ -5661,7 +5591,7 @@ lock_table_wait:
/* It was a lock wait, and it ended */
thr->lock_state = QUE_THR_LOCK_NOLOCK;
- mtr_start(&mtr);
+ mtr.start();
/* Table lock waited, go try to obtain table lock
again */
@@ -5711,9 +5641,16 @@ lock_table_wait:
normal_return:
/*-------------------------------------------------------------*/
- que_thr_stop_for_mysql_no_error(thr, trx);
+ {
+ /* handler_index_cond_check() may pull TR_table search
+ which initates another row_search_mvcc(). */
+ ulint n_active_thrs= trx->lock.n_active_thrs;
+ trx->lock.n_active_thrs= 1;
+ que_thr_stop_for_mysql_no_error(thr, trx);
+ trx->lock.n_active_thrs= n_active_thrs - 1;
+ }
- mtr_commit(&mtr);
+ mtr.commit();
/* Rollback blocking transactions from hit list for high priority
transaction, if any. We should not be holding latches here as
@@ -5935,18 +5872,15 @@ row_search_check_if_query_cache_permitted(
const bool ret = lock_table_get_n_locks(table) == 0
&& ((trx->id != 0 && trx->id >= table->query_cache_inv_id)
- || !MVCC::is_view_active(trx->read_view)
- || trx->read_view->low_limit_id()
+ || !trx->read_view.is_open()
+ || trx->read_view.low_limit_id()
>= table->query_cache_inv_id);
if (ret) {
/* If the isolation level is high, assign a read view for the
transaction if it does not yet have one */
- if (trx->isolation_level >= TRX_ISO_REPEATABLE_READ
- && !srv_read_only_mode
- && !MVCC::is_view_active(trx->read_view)) {
-
- trx_sys->mvcc->view_open(trx->read_view, trx);
+ if (trx->isolation_level >= TRX_ISO_REPEATABLE_READ) {
+ trx->read_view.open(trx);
}
}
diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc
index 8d371f67e72..d395dcc7e05 100644
--- a/storage/innobase/row/row0trunc.cc
+++ b/storage/innobase/row/row0trunc.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -293,13 +293,13 @@ public:
log_file_name_len = strlen(m_log_file_name);
}
- ut_snprintf(m_log_file_name + log_file_name_len,
- log_file_name_buf_sz - log_file_name_len,
- "%s%lu_%lu_%s",
- TruncateLogger::s_log_prefix,
- (ulong) m_table->space,
- (ulong) m_table->id,
- TruncateLogger::s_log_ext);
+ snprintf(m_log_file_name + log_file_name_len,
+ log_file_name_buf_sz - log_file_name_len,
+ "%s%lu_%lu_%s",
+ TruncateLogger::s_log_prefix,
+ (ulong) m_table->space,
+ (ulong) m_table->id,
+ TruncateLogger::s_log_ext);
return(DB_SUCCESS);
@@ -1651,19 +1651,7 @@ row_truncate_foreign_key_checks(
return(DB_ERROR);
}
- /* TODO: could we replace the counter n_foreign_key_checks_running
- with lock checks on the table? Acquire here an exclusive lock on the
- table, and rewrite lock0lock.cc and the lock wait in srv0srv.cc so that
- they can cope with the table having been truncated here? Foreign key
- checks take an IS or IX lock on the table. */
-
- if (table->n_foreign_key_checks_running > 0) {
- ib::warn() << "Cannot truncate table " << table->name
- << " because there is a foreign key check running on"
- " it.";
-
- return(DB_ERROR);
- }
+ ut_ad(!table->n_foreign_key_checks_running);
return(DB_SUCCESS);
}
@@ -1719,9 +1707,6 @@ row_truncate_table_for_mysql(
This would include check for tablespace discard status, ibd file
missing, etc ....
- Step-2: Start transaction (only for non-temp table as temp-table don't
- modify any data on disk doesn't need transaction object).
-
Step-3: Validate ownership of needed locks (Exclusive lock).
Ownership will also ensure there is no active SQL queries, INSERT,
SELECT, .....
@@ -1802,11 +1787,8 @@ row_truncate_table_for_mysql(
}
- /* Step-2: Start transaction (only for non-temp table as temp-table
- don't modify any data on disk doesn't need transaction object). */
if (!dict_table_is_temporary(table)) {
- /* Avoid transaction overhead for temporary table DDL. */
- trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
}
/* Step-3: Validate ownership of needed locks (Exclusive lock).
@@ -1832,17 +1814,17 @@ row_truncate_table_for_mysql(
table, trx, fsp_flags, logger, err));
}
- /* Remove all locks except the table-level X lock. */
- lock_remove_all_on_table(table, FALSE);
trx->table_id = table->id;
trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
/* Step-6: Truncate operation can be rolled back in case of error
till some point. Associate rollback segment to record undo log. */
- if (!dict_table_is_temporary(table)) {
+ if (!table->is_temporary()) {
mutex_enter(&trx->undo_mutex);
- err = trx_undo_assign_undo(trx, trx->rsegs.m_redo.rseg,
- &trx->rsegs.m_redo.undo);
+ mtr_t mtr;
+ mtr.start();
+ trx_undo_assign(trx, &err, &mtr);
+ mtr.commit();
mutex_exit(&trx->undo_mutex);
DBUG_EXECUTE_IF("ib_err_trunc_assigning_undo_log",
diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc
index 58707fb21c5..c14af408dda 100644
--- a/storage/innobase/row/row0uins.cc
+++ b/storage/innobase/row/row0uins.cc
@@ -403,16 +403,13 @@ row_undo_ins_parse_undo_rec(
byte* ptr;
undo_no_t undo_no;
table_id_t table_id;
- ulint type;
ulint dummy;
bool dummy_extern;
ut_ad(node);
- ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &dummy,
+ ptr = trx_undo_rec_get_pars(node->undo_rec, &node->rec_type, &dummy,
&dummy_extern, &undo_no, &table_id);
- ut_ad(type == TRX_UNDO_INSERT_REC || type == TRX_UNDO_INSERT_DEFAULT);
- node->rec_type = type;
node->update = NULL;
node->table = dict_table_open_on_id(
@@ -423,6 +420,28 @@ row_undo_ins_parse_undo_rec(
return;
}
+ switch (node->rec_type) {
+ default:
+ ut_ad(!"wrong undo record type");
+ goto close_table;
+ case TRX_UNDO_INSERT_DEFAULT:
+ case TRX_UNDO_INSERT_REC:
+ break;
+ case TRX_UNDO_RENAME_TABLE:
+ dict_table_t* table = node->table;
+ ut_ad(!table->is_temporary());
+ ut_ad(dict_table_is_file_per_table(table)
+ == (table->space != TRX_SYS_SPACE));
+ size_t len = mach_read_from_2(node->undo_rec)
+ + node->undo_rec - ptr - 2;
+ ptr[len] = 0;
+ const char* name = reinterpret_cast<char*>(ptr);
+ if (strcmp(table->name.m_name, name)) {
+ dict_table_rename_in_cache(table, name, false);
+ }
+ goto close_table;
+ }
+
if (UNIV_UNLIKELY(!fil_table_accessible(node->table))) {
close_table:
/* Normally, tables should not disappear or become
@@ -437,15 +456,15 @@ close_table:
dict_table_close(node->table, dict_locked, FALSE);
node->table = NULL;
} else {
+ ut_ad(!node->table->skip_alter_undo);
clust_index = dict_table_get_first_index(node->table);
if (clust_index != NULL) {
- if (type == TRX_UNDO_INSERT_REC) {
+ if (node->rec_type == TRX_UNDO_INSERT_REC) {
ptr = trx_undo_rec_get_row_ref(
ptr, clust_index, &node->ref,
node->heap);
} else {
- ut_ad(type == TRX_UNDO_INSERT_DEFAULT);
node->ref = &trx_undo_default_rec;
}
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index 0b1d800212f..1c2a97a3210 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -306,7 +306,7 @@ row_undo_mod_clust(
/* We may have to modify tree structure: do a pessimistic
descent down the index tree */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr.start();
if (index->table->is_temporary()) {
mtr.set_log_mode(MTR_LOG_NO_REDO);
} else {
@@ -366,7 +366,7 @@ row_undo_mod_clust(
if (err == DB_SUCCESS && node->rec_type == TRX_UNDO_UPD_DEL_REC) {
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr.start();
if (index->table->is_temporary()) {
mtr.set_log_mode(MTR_LOG_NO_REDO);
} else {
@@ -384,7 +384,7 @@ row_undo_mod_clust(
/* We may have to modify tree structure: do a
pessimistic descent down the index tree */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr.start();
if (index->table->is_temporary()) {
mtr.set_log_mode(MTR_LOG_NO_REDO);
} else {
@@ -498,7 +498,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
which cannot be purged yet, requires its existence. If some requires,
we should delete mark the record. */
- mtr_start_trx(&mtr_vers, thr_get_trx(thr));
+ mtr_vers.start();
success = btr_pcur_restore_position(BTR_SEARCH_LEAF, &(node->pcur),
&mtr_vers);
@@ -624,13 +624,13 @@ row_undo_mod_del_unmark_sec_and_undo_update(
ut_ad(trx->id != 0);
- /* FIXME: Currently we do a 2-pass search for the undo due to
- avoid undel-mark a wrong rec in rolling back in partial update.
- Later, we could log some info in secondary index updates to avoid
- this. */
if (dict_index_is_spatial(index)) {
+ /* FIXME: Currently we do a 2-pass search for the undo
+ due to avoid undel-mark a wrong rec in rolling back in
+ partial update. Later, we could log some info in
+ secondary index updates to avoid this. */
ut_ad(mode & BTR_MODIFY_LEAF);
- mode |= BTR_RTREE_DELETE_MARK;
+ mode |= BTR_RTREE_DELETE_MARK;
}
try_again:
@@ -1144,6 +1144,8 @@ row_undo_mod_parse_undo_rec(
return;
}
+ ut_ad(!node->table->skip_alter_undo);
+
if (UNIV_UNLIKELY(!fil_table_accessible(node->table))) {
close_table:
/* Normally, tables should not disappear or become
@@ -1192,7 +1194,16 @@ close_table:
if (!row_undo_search_clust_to_pcur(node)) {
/* As long as this rolling-back transaction exists,
the PRIMARY KEY value pointed to by the undo log
- record must exist. But, it is possible that the record
+ record should exist.
+
+ However, if InnoDB is killed during a rollback, or
+ shut down during the rollback of recovered
+ transactions, then after restart we may try to roll
+ back some of the same undo log records again, because
+ trx_roll_try_truncate() is not being invoked after
+ every undo log record.
+
+ It is also possible that the record
was not modified yet (the DB_ROLL_PTR does not match
node->roll_ptr) and thus there is nothing to roll back.
@@ -1200,8 +1211,11 @@ close_table:
record after successfully acquiring an exclusive lock
on the the clustered index record. That lock will not
be released before the transaction is committed or
- fully rolled back. */
- ut_ad(node->pcur.btr_cur.low_match == node->ref->n_fields);
+ fully rolled back. (Exception: if the server was
+ killed, restarted, and shut down again before the
+ rollback of the recovered transaction was completed,
+ it is possible that the transaction was partially
+ rolled back and locks released.) */
goto close_table;
}
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index a1bb4cb7dbd..2fcfecd5c11 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -172,6 +172,8 @@ row_undo_search_clust_to_pcur(
ulint* offsets = offsets_;
rec_offs_init(offsets_);
+ ut_ad(!node->table->skip_alter_undo);
+
mtr_start(&mtr);
clust_index = dict_table_get_first_index(node->table);
@@ -343,6 +345,13 @@ row_undo_step(
ut_ad(que_node_get_type(node) == QUE_NODE_UNDO);
+ if (UNIV_UNLIKELY(trx == trx_roll_crash_recv_trx)
+ && trx_roll_must_shutdown()) {
+ /* Shutdown has been initiated. */
+ trx->error_state = DB_INTERRUPTED;
+ return(NULL);
+ }
+
err = row_undo(node, thr);
trx->error_state = err;
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 8e59fe7f113..e9002d6b41d 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -248,7 +248,7 @@ row_upd_check_references_constraints(
DEBUG_SYNC_C("foreign_constraint_check_for_update");
- mtr_start_trx(mtr, trx);
+ mtr->start();
if (trx->dict_operation_lock_mode == 0) {
got_s_lock = TRUE;
@@ -319,9 +319,16 @@ row_upd_check_references_constraints(
But the counter on the table protects 'foreign' from
being dropped while the check is running. */
+ if (foreign_table) {
+ foreign_table->inc_fk_checks();
+ }
+
err = row_ins_check_foreign_constraint(
FALSE, foreign, table, entry, thr);
+ if (foreign_table) {
+ foreign_table->dec_fk_checks();
+ }
if (ref_table != NULL) {
dict_table_close(ref_table, FALSE, FALSE);
}
@@ -342,11 +349,6 @@ func_exit:
mem_heap_free(heap);
DEBUG_SYNC_C("foreign_constraint_check_for_update_done");
-
- DBUG_EXECUTE_IF("row_upd_cascade_lock_wait_err",
- err = DB_LOCK_WAIT;
- DBUG_SET("-d,row_upd_cascade_lock_wait_err"););
-
DBUG_RETURN(err);
}
@@ -469,9 +471,8 @@ wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
return false;
}
- const upd_node_t* parent = static_cast<const upd_node_t*>(node->common.parent);
-
- return parent->cascade_upd_nodes->empty();
+ return static_cast<upd_node_t*>(node->common.parent)->cascade_node
+ == node;
}
#endif /* WITH_WSREP */
@@ -581,6 +582,7 @@ row_upd_changes_field_size_or_external(
ulint i;
ut_ad(rec_offs_validate(NULL, index, offsets));
+ ut_ad(!index->table->skip_alter_undo);
n_fields = upd_get_n_fields(update);
for (i = 0; i < n_fields; i++) {
@@ -705,6 +707,7 @@ row_upd_rec_in_place(
ulint i;
ut_ad(rec_offs_validate(rec, index, offsets));
+ ut_ad(!index->table->skip_alter_undo);
if (rec_offs_comp(offsets)) {
#ifdef UNIV_DEBUG
@@ -714,9 +717,19 @@ row_upd_rec_in_place(
case REC_STATUS_COLUMNS_ADDED:
ut_ad(index->is_instant());
break;
+ case REC_STATUS_NODE_PTR:
+ if (index->is_dummy
+ && fil_page_get_type(page_align(rec))
+ == FIL_PAGE_RTREE) {
+ /* The function rtr_update_mbr_field_in_place()
+ is generating MLOG_COMP_REC_UPDATE_IN_PLACE
+ and MLOG_REC_UPDATE_IN_PLACE records for
+ node pointer pages. */
+ break;
+ }
+ /* fall through */
case REC_STATUS_INFIMUM:
case REC_STATUS_SUPREMUM:
- case REC_STATUS_NODE_PTR:
ut_ad(!"wrong record status in update");
}
#endif /* UNIV_DEBUG */
@@ -1003,6 +1016,7 @@ row_upd_build_sec_rec_difference_binary(
ut_ad(rec_offs_n_fields(offsets) == dtuple_get_n_fields(entry));
ut_ad(!rec_offs_any_extern(offsets));
ut_ad(!rec_offs_any_default(offsets));
+ ut_ad(!index->table->skip_alter_undo);
update = upd_create(dtuple_get_n_fields(entry), heap);
@@ -1084,6 +1098,7 @@ row_upd_build_difference_binary(
/* This function is used only for a clustered index */
ut_a(dict_index_is_clust(index));
+ ut_ad(!index->table->skip_alter_undo);
update = upd_create(n_fld + n_v_fld, heap);
@@ -1281,7 +1296,7 @@ row_upd_index_replace_new_col_val(
}
len = dtype_get_at_most_n_mbchars(col->prtype,
- col->mbminmaxlen,
+ col->mbminlen, col->mbmaxlen,
field->prefix_len, len,
(const char*) data);
@@ -1346,6 +1361,8 @@ row_upd_index_replace_new_col_vals_index_pos(
const upd_t* update,
mem_heap_t* heap)
{
+ ut_ad(!index->table->skip_alter_undo);
+
const page_size_t& page_size = dict_table_page_size(index->table);
dtuple_set_info_bits(entry, update->info_bits);
@@ -1400,6 +1417,8 @@ row_upd_index_replace_new_col_vals(
= dict_table_get_first_index(index->table);
const page_size_t& page_size = dict_table_page_size(index->table);
+ ut_ad(!index->table->skip_alter_undo);
+
dtuple_set_info_bits(entry, update->info_bits);
for (i = 0; i < dict_index_get_n_fields(index); i++) {
@@ -1474,6 +1493,8 @@ row_upd_replace_vcol(
ulint i;
ulint n_cols;
+ ut_ad(!table->skip_alter_undo);
+
n_cols = dtuple_get_n_v_fields(row);
for (col_no = 0; col_no < n_cols; col_no++) {
dfield_t* dfield;
@@ -1512,12 +1533,7 @@ row_upd_replace_vcol(
dfield_copy_data(dfield, upd_field->old_v_val);
}
- dfield_get_type(dfield)->mtype =
- upd_field->new_val.type.mtype;
- dfield_get_type(dfield)->prtype =
- upd_field->new_val.type.prtype;
- dfield_get_type(dfield)->mbminmaxlen =
- upd_field->new_val.type.mbminmaxlen;
+ dfield->type = upd_field->new_val.type;
break;
}
}
@@ -1695,6 +1711,7 @@ row_upd_changes_ord_field_binary_func(
ut_ad(thr);
ut_ad(thr->graph);
ut_ad(thr->graph->trx);
+ ut_ad(!index->table->skip_alter_undo);
n_unique = dict_index_get_n_unique(index);
@@ -1954,6 +1971,8 @@ row_upd_changes_doc_id(
dict_index_t* clust_index;
fts_t* fts = table->fts;
+ ut_ad(!table->skip_alter_undo);
+
clust_index = dict_table_get_first_index(table);
/* Convert from index-specific column number to table-global
@@ -1976,6 +1995,8 @@ row_upd_changes_fts_column(
dict_index_t* clust_index;
fts_t* fts = table->fts;
+ ut_ad(!table->skip_alter_undo);
+
if (upd_fld_is_virtual_col(upd_field)) {
col_no = upd_field->field_no;
return(dict_table_is_fts_column(fts->indexes, col_no, true));
@@ -2104,6 +2125,7 @@ row_upd_eval_new_vals(
@param[in] update an update vector if it is update
@param[in] thd mysql thread handle
@param[in,out] mysql_table mysql table object */
+static
void
row_upd_store_v_row(
upd_node_t* node,
@@ -2151,7 +2173,6 @@ row_upd_store_v_row(
cascade update. And virtual
column can't be affected,
so it is Ok to set it to NULL */
- ut_ad(!node->cascade_top);
dfield_set_null(dfield);
} else {
dfield_t* vfield
@@ -2231,7 +2252,7 @@ row_upd_store_row(
thd, mysql_table);
}
- if (node->is_delete) {
+ if (node->is_delete == PLAIN_DELETE) {
node->upd_row = NULL;
node->upd_ext = NULL;
} else {
@@ -2246,25 +2267,6 @@ row_upd_store_row(
}
/***********************************************************//**
-Print a MBR data from disk */
-static
-void
-srv_mbr_print(const byte* data)
-{
- double a, b, c, d;
- a = mach_double_read(data);
- data += sizeof(double);
- b = mach_double_read(data);
- data += sizeof(double);
- c = mach_double_read(data);
- data += sizeof(double);
- d = mach_double_read(data);
-
- ib::info() << "GIS MBR INFO: " << a << " and " << b << ", " << c
- << ", " << d << "\n";
-}
-
-/***********************************************************//**
Updates a secondary index entry of a row.
@return DB_SUCCESS if operation successfully completed, else error
code or DB_LOCK_WAIT */
@@ -2309,7 +2311,7 @@ row_upd_sec_index_entry(
DEBUG_SYNC_C_IF_THD(trx->mysql_thd,
"before_row_upd_sec_index_entry");
- mtr_start_trx(&mtr, trx);
+ mtr.start();
switch (index->space) {
case SRV_TMP_SPACE_ID:
@@ -2427,8 +2429,6 @@ row_upd_sec_index_entry(
<< " of table " << index->table->name
<< " was not found on update: " << *entry
<< " at: " << rec_index_print(rec, index);
- if (entry->fields[0].data)
- srv_mbr_print((unsigned char*)entry->fields[0].data);
#ifdef UNIV_DEBUG
mtr_commit(&mtr);
mtr_start(&mtr);
@@ -2506,7 +2506,7 @@ row_upd_sec_index_entry(
btr_pcur_close(&pcur);
mtr_commit(&mtr);
- if (node->is_delete || err != DB_SUCCESS) {
+ if (node->is_delete == PLAIN_DELETE || err != DB_SUCCESS) {
goto func_exit;
}
@@ -2659,7 +2659,9 @@ row_upd_clust_rec_by_insert(
que_thr_t* thr, /*!< in: query thread */
ibool referenced,/*!< in: TRUE if index may be referenced in
a foreign key constraint */
- ibool foreign, /*!< in: TRUE if index is foreign key index */
+#ifdef WITH_WSREP
+ bool foreign,/*!< in: whether this is a foreign key */
+#endif
mtr_t* mtr) /*!< in/out: mtr; gets committed here */
{
mem_heap_t* heap;
@@ -2826,6 +2828,7 @@ row_upd_clust_rec(
ut_ad(node);
ut_ad(dict_index_is_clust(index));
ut_ad(!thr_get_trx(thr)->in_rollback);
+ ut_ad(!node->table->skip_alter_undo);
pcur = node->pcur;
btr_cur = btr_pcur_get_btr_cur(pcur);
@@ -2870,16 +2873,15 @@ row_upd_clust_rec(
/* We may have to modify the tree structure: do a pessimistic descent
down the index tree */
- mtr_start_trx(mtr, thr_get_trx(thr));
- mtr->set_named_space(index->space);
+ mtr->start();
- /* Disable REDO logging as lifetime of temp-tables is limited to
- server or connection lifetime and so REDO information is not needed
- on restart for recovery.
- Disable locking as temp-tables are not shared across connection. */
- if (dict_table_is_temporary(index->table)) {
+ if (index->table->is_temporary()) {
+ /* Disable locking, because temporary tables are never
+ shared between transactions or connections. */
flags |= BTR_NO_LOCKING_FLAG;
mtr->set_log_mode(MTR_LOG_NO_REDO);
+ } else {
+ mtr->set_named_space(index->space);
}
/* NOTE: this transaction has an s-lock or x-lock on the record and
@@ -2948,7 +2950,9 @@ row_upd_del_mark_clust_rec(
ibool referenced,
/*!< in: TRUE if index may be referenced in
a foreign key constraint */
- ibool foreign,/*!< in: TRUE if index is foreign key index */
+#ifdef WITH_WSREP
+ bool foreign,/*!< in: whether this is a foreign key */
+#endif
mtr_t* mtr) /*!< in: mtr; gets committed here */
{
btr_pcur_t* pcur;
@@ -2959,7 +2963,7 @@ row_upd_del_mark_clust_rec(
ut_ad(node);
ut_ad(dict_index_is_clust(index));
- ut_ad(node->is_delete);
+ ut_ad(node->is_delete == PLAIN_DELETE);
pcur = node->pcur;
btr_cur = btr_pcur_get_btr_cur(pcur);
@@ -3040,7 +3044,6 @@ row_upd_clust_step(
ulint* offsets;
ibool referenced;
ulint flags;
- ibool foreign = FALSE;
trx_t* trx = thr_get_trx(thr);
rec_offs_init(offsets_);
@@ -3050,16 +3053,14 @@ row_upd_clust_step(
referenced = row_upd_index_is_referenced(index, trx);
#ifdef WITH_WSREP
- foreign = wsrep_row_upd_index_is_foreign(
- index, thr_get_trx(thr));
+ const bool foreign = wsrep_row_upd_index_is_foreign(index, trx);
#endif
pcur = node->pcur;
/* We have to restore the cursor to its position */
- mtr_start_trx(&mtr, thr_get_trx(thr));
- mtr.set_named_space(index->space);
+ mtr.start();
if (dict_table_is_temporary(node->table)) {
/* Disable locking, because temporary tables are
@@ -3071,6 +3072,7 @@ row_upd_clust_step(
mtr.set_log_mode(MTR_LOG_NO_REDO);
} else {
flags = node->table->no_rollback() ? BTR_NO_ROLLBACK : 0;
+ mtr.set_named_space(index->space);
}
/* If the restoration does not succeed, then the same
@@ -3111,16 +3113,17 @@ row_upd_clust_step(
then we have to free the file segments of the index tree associated
with the index */
- if (node->is_delete && node->table->id == DICT_INDEXES_ID) {
+ if (node->is_delete == PLAIN_DELETE
+ && node->table->id == DICT_INDEXES_ID) {
ut_ad(!dict_index_is_online_ddl(index));
dict_drop_index_tree(
btr_pcur_get_rec(pcur), pcur, &mtr);
- mtr_commit(&mtr);
+ mtr.commit();
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr.start();
mtr.set_named_space(index->space);
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur,
@@ -3128,7 +3131,7 @@ row_upd_clust_step(
if (!success) {
err = DB_ERROR;
- mtr_commit(&mtr);
+ mtr.commit();
return(err);
}
@@ -3143,7 +3146,7 @@ row_upd_clust_step(
0, btr_pcur_get_block(pcur),
rec, index, offsets, thr);
if (err != DB_SUCCESS) {
- mtr_commit(&mtr);
+ mtr.commit();
goto exit_func;
}
}
@@ -3155,9 +3158,13 @@ row_upd_clust_step(
/* NOTE: the following function calls will also commit mtr */
- if (node->is_delete) {
+ if (node->is_delete == PLAIN_DELETE) {
err = row_upd_del_mark_clust_rec(
- node, index, offsets, thr, referenced, foreign, &mtr);
+ node, index, offsets, thr, referenced,
+#ifdef WITH_WSREP
+ foreign,
+#endif
+ &mtr);
if (err == DB_SUCCESS) {
node->state = UPD_NODE_UPDATE_ALL_SEC;
@@ -3203,7 +3210,11 @@ row_upd_clust_step(
externally! */
err = row_upd_clust_rec_by_insert(
- node, index, thr, referenced, foreign, &mtr);
+ node, index, thr, referenced,
+#ifdef WITH_WSREP
+ foreign,
+#endif
+ &mtr);
if (err != DB_SUCCESS) {
goto exit_func;
@@ -3260,7 +3271,7 @@ row_upd(
/* We do not get the cmpl_info value from the MySQL
interpreter: we must calculate it on the fly: */
- if (node->is_delete
+ if (node->is_delete == PLAIN_DELETE
|| row_upd_changes_some_index_ord_field_binary(
node->table, node->update)) {
node->cmpl_info = 0;
@@ -3443,56 +3454,3 @@ error_handling:
DBUG_RETURN(thr);
}
-
-#ifndef DBUG_OFF
-
-/** Ensure that the member cascade_upd_nodes has only one update node
-for each of the tables. This is useful for testing purposes. */
-void upd_node_t::check_cascade_only_once()
-{
- DBUG_ENTER("upd_node_t::check_cascade_only_once");
-
- dbug_trace();
-
- for (upd_cascade_t::const_iterator i = cascade_upd_nodes->begin();
- i != cascade_upd_nodes->end(); ++i) {
-
- const upd_node_t* update_node = *i;
- std::string table_name(update_node->table->name.m_name);
- ulint count = 0;
-
- for (upd_cascade_t::const_iterator j
- = cascade_upd_nodes->begin();
- j != cascade_upd_nodes->end(); ++j) {
-
- const upd_node_t* node = *j;
-
- if (table_name == node->table->name.m_name) {
- DBUG_ASSERT(count++ == 0);
- }
- }
- }
-
- DBUG_VOID_RETURN;
-}
-
-/** Print information about this object into the trace log file. */
-void upd_node_t::dbug_trace()
-{
- DBUG_ENTER("upd_node_t::dbug_trace");
-
- for (upd_cascade_t::const_iterator i = cascade_upd_nodes->begin();
- i != cascade_upd_nodes->end(); ++i) {
- DBUG_LOG("upd_node_t", "cascade_upd_nodes: Cascade to table: "
- << (*i)->table->name);
- }
-
- for (upd_cascade_t::const_iterator j = new_upd_nodes->begin();
- j != new_upd_nodes->end(); ++j) {
- DBUG_LOG("upd_node_t", "new_upd_nodes: Cascade to table: "
- << (*j)->table->name);
- }
-
- DBUG_VOID_RETURN;
-}
-#endif /* !DBUG_OFF */
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index 8c9919511ad..eed40ec30df 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation
+Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 2018, 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
@@ -41,48 +41,57 @@ Created 2/6/1997 Heikki Tuuri
#include "row0row.h"
#include "row0upd.h"
#include "rem0cmp.h"
-#include "read0read.h"
#include "lock0lock.h"
#include "row0mysql.h"
-/** Check whether all non-virtual columns in a virtual index match that of in
-the cluster index
-@param[in] index the secondary index
-@param[in] row the cluster index row in dtuple form
-@param[in] ext externally stored column prefix or NULL
-@param[in] ientry the secondary index entry
-@param[in,out] heap heap used to build virtual dtuple
-@param[in,out] n_non_v_col number of non-virtual columns in the index
-@return true if all matches, false otherwise */
+/** Check whether all non-virtual index fields are equal.
+@param[in] index the secondary index
+@param[in] a first index entry to compare
+@param[in] b second index entry to compare
+@return whether all non-virtual fields are equal */
static
bool
-row_vers_non_vc_match(
- dict_index_t* index,
- const dtuple_t* row,
- const row_ext_t* ext,
- const dtuple_t* ientry,
- mem_heap_t* heap,
- ulint* n_non_v_col);
-/*****************************************************************//**
-Finds out if an active transaction has inserted or modified a secondary
+row_vers_non_virtual_fields_equal(
+ const dict_index_t* index,
+ const dfield_t* a,
+ const dfield_t* b)
+{
+ const dict_field_t* end = &index->fields[index->n_fields];
+
+ for (const dict_field_t* ifield = index->fields; ifield != end;
+ ifield++) {
+ if (!dict_col_is_virtual(ifield->col)
+ && cmp_dfield_dfield(a++, b++)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/** Determine if an active transaction has inserted or modified a secondary
index record.
-@return 0 if committed, else the active transaction id;
-NOTE that this function can return false positives but never false
-negatives. The caller must confirm all positive results by calling
-trx_is_active() while holding lock_sys->mutex. */
+@param[in,out] caller_trx trx of current thread
+@param[in] clust_rec clustered index record
+@param[in] clust_index clustered index
+@param[in] rec secondary index record
+@param[in] index secondary index
+@param[in] offsets rec_get_offsets(rec, index)
+@param[in,out] mtr mini-transaction
+@return the active transaction; trx->release_reference() must be invoked
+@retval NULL if the record was committed */
UNIV_INLINE
trx_t*
row_vers_impl_x_locked_low(
-/*=======================*/
- const rec_t* clust_rec, /*!< in: clustered index record */
- dict_index_t* clust_index, /*!< in: the clustered index */
- const rec_t* rec, /*!< in: secondary index record */
- dict_index_t* index, /*!< in: the secondary index */
- const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
- mtr_t* mtr) /*!< in/out: mini-transaction */
+ trx_t* caller_trx,
+ const rec_t* clust_rec,
+ dict_index_t* clust_index,
+ const rec_t* rec,
+ dict_index_t* index,
+ const ulint* offsets,
+ mtr_t* mtr)
{
trx_id_t trx_id;
- ibool corrupt;
ulint comp;
ulint rec_del;
const rec_t* version;
@@ -116,18 +125,13 @@ row_vers_impl_x_locked_low(
mem_heap_free(heap);
DBUG_RETURN(0);
}
- corrupt = FALSE;
- trx_t* trx = trx_rw_is_active(trx_id, &corrupt, true);
+ trx_t* trx = trx_sys.find(caller_trx, trx_id);
if (trx == 0) {
/* The transaction that modified or inserted clust_rec is no
longer active, or it is corrupt: no implicit lock on rec */
- if (corrupt) {
- lock_report_trx_id_insanity(
- trx_id, clust_rec, clust_index, clust_offsets,
- trx_sys_get_max_trx_id());
- }
+ lock_check_trx_id_sanity(trx_id, clust_rec, clust_index, clust_offsets);
mem_heap_free(heap);
DBUG_RETURN(0);
}
@@ -187,7 +191,7 @@ row_vers_impl_x_locked_low(
inserting a delete-marked record. */
ut_ad(prev_version
|| !rec_get_deleted_flag(version, comp)
- || !trx_rw_is_active(trx_id, NULL, false));
+ || !trx_sys.is_registered(caller_trx, trx_id));
/* Free version and clust_offsets. */
mem_heap_free(old_heap);
@@ -211,7 +215,7 @@ row_vers_impl_x_locked_low(
or updated, the leaf page record always is
created with a clear delete-mark flag.
(We never insert a delete-marked record.) */
- trx_release_reference(trx);
+ trx->release_reference();
trx = 0;
}
@@ -244,15 +248,29 @@ row_vers_impl_x_locked_low(
}
if (!cur_vrow) {
- ulint n_non_v_col = 0;
+ /* Build index entry out of row */
+ entry = row_build_index_entry(row, ext, index,
+ heap);
+
+ /* entry could only be NULL (the
+ clustered index record could contain
+ BLOB pointers that are NULL) if we
+ were accessing a freshly inserted
+ record before it was fully inserted.
+ prev_version cannot possibly be such
+ an incomplete record, because its
+ transaction would have to be committed
+ in order for later versions of the
+ record to be able to exist. */
+ ut_ad(entry);
/* If the indexed virtual columns has changed,
there must be log record to generate vrow.
Otherwise, it is not changed, so no need
to compare */
- if (row_vers_non_vc_match(
- index, row, ext, ientry, heap,
- &n_non_v_col) == 0) {
+ if (!row_vers_non_virtual_fields_equal(
+ index,
+ ientry->fields, entry->fields)) {
if (rec_del != vers_del) {
break;
}
@@ -269,12 +287,14 @@ row_vers_impl_x_locked_low(
entry = row_build_index_entry(row, ext, index, heap);
- /* entry may be NULL if a record was inserted in place
- of a deleted record, and the BLOB pointers of the new
- record were not initialized yet. But in that case,
- prev_version should be NULL. */
-
- ut_a(entry != NULL);
+ /* entry could only be NULL (the clustered index
+ record could contain BLOB pointers that are NULL) if
+ we were accessing a freshly inserted record before it
+ was fully inserted. prev_version cannot possibly be
+ such an incomplete record, because its transaction
+ would have to be committed in order for later versions
+ of the record to be able to exist. */
+ ut_ad(entry);
/* If we get here, we know that the trx_id transaction
modified prev_version. Let us check if prev_version
@@ -322,7 +342,7 @@ result_check:
/* prev_version was the first version modified by
the trx_id transaction: no implicit x-lock */
- trx_release_reference(trx);
+ trx->release_reference();
trx = 0;
break;
}
@@ -338,19 +358,20 @@ result_check:
DBUG_RETURN(trx);
}
-/*****************************************************************//**
-Finds out if an active transaction has inserted or modified a secondary
+/** Determine if an active transaction has inserted or modified a secondary
index record.
-@return 0 if committed, else the active transaction id;
-NOTE that this function can return false positives but never false
-negatives. The caller must confirm all positive results by calling
-trx_is_active() while holding lock_sys->mutex. */
+@param[in,out] caller_trx trx of current thread
+@param[in] rec secondary index record
+@param[in] index secondary index
+@param[in] offsets rec_get_offsets(rec, index)
+@return the active transaction; trx->release_reference() must be invoked
+@retval NULL if the record was committed */
trx_t*
row_vers_impl_x_locked(
-/*===================*/
- const rec_t* rec, /*!< in: record in a secondary index */
- dict_index_t* index, /*!< in: the secondary index */
- const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
+ trx_t* caller_trx,
+ const rec_t* rec,
+ dict_index_t* index,
+ const ulint* offsets)
{
mtr_t mtr;
trx_t* trx;
@@ -358,7 +379,7 @@ row_vers_impl_x_locked(
dict_index_t* clust_index;
ut_ad(!lock_mutex_own());
- ut_ad(!trx_sys_mutex_own());
+ ut_ad(!mutex_own(&trx_sys.mutex));
mtr_start(&mtr);
@@ -388,9 +409,10 @@ row_vers_impl_x_locked(
trx = 0;
} else {
trx = row_vers_impl_x_locked_low(
- clust_rec, clust_index, rec, index, offsets, &mtr);
+ caller_trx, clust_rec, clust_index, rec, index,
+ offsets, &mtr);
- ut_ad(trx == 0 || trx_is_referenced(trx));
+ ut_ad(trx == 0 || trx->is_referenced());
}
mtr_commit(&mtr);
@@ -414,66 +436,11 @@ row_vers_must_preserve_del_marked(
const table_name_t& name,
mtr_t* mtr)
{
- ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_S));
+ ut_ad(!rw_lock_own(&(purge_sys.latch), RW_LOCK_S));
- mtr_s_lock(&purge_sys->latch, mtr);
+ mtr_s_lock(&purge_sys.latch, mtr);
- return(!purge_sys->view.changes_visible(trx_id, name));
-}
-
-/** Check whether all non-virtual columns in a virtual index match that of in
-the cluster index
-@param[in] index the secondary index
-@param[in] row the cluster index row in dtuple form
-@param[in] ext externally stored column prefix or NULL
-@param[in] ientry the secondary index entry
-@param[in,out] heap heap used to build virtual dtuple
-@param[in,out] n_non_v_col number of non-virtual columns in the index
-@return true if all matches, false otherwise */
-static
-bool
-row_vers_non_vc_match(
- dict_index_t* index,
- const dtuple_t* row,
- const row_ext_t* ext,
- const dtuple_t* ientry,
- mem_heap_t* heap,
- ulint* n_non_v_col)
-{
- const dfield_t* field1;
- dfield_t* field2;
- ulint n_fields = dtuple_get_n_fields(ientry);
- ulint ret = true;
-
- *n_non_v_col = 0;
-
- /* Build index entry out of row */
- dtuple_t* nentry = row_build_index_entry(row, ext, index, heap);
-
- for (ulint i = 0; i < n_fields; i++) {
- const dict_field_t* ind_field = dict_index_get_nth_field(
- index, i);
-
- const dict_col_t* col = ind_field->col;
-
- /* Only check non-virtual columns */
- if (dict_col_is_virtual(col)) {
- continue;
- }
-
- if (ret) {
- field1 = dtuple_get_nth_field(ientry, i);
- field2 = dtuple_get_nth_field(nentry, i);
-
- if (cmp_dfield_dfield(field1, field2) != 0) {
- ret = false;
- }
- }
-
- (*n_non_v_col)++;
- }
-
- return(ret);
+ return(!purge_sys.view.changes_visible(trx_id, name));
}
/** build virtual column value from current cluster index record data
@@ -626,8 +593,7 @@ that of current cluster index record, which is recreated from information
stored in undo log
@param[in] in_purge called by purge thread
@param[in] rec record in the clustered index
-@param[in] row the cluster index row in dtuple form
-@param[in] ext externally stored column prefix or NULL
+@param[in] icentry the index entry built from a cluster row
@param[in] clust_index cluster index
@param[in] clust_offsets offsets on the cluster record
@param[in] index the secondary index
@@ -643,8 +609,7 @@ bool
row_vers_vc_matches_cluster(
bool in_purge,
const rec_t* rec,
- const dtuple_t* row,
- row_ext_t* ext,
+ const dtuple_t* icentry,
dict_index_t* clust_index,
ulint* clust_offsets,
dict_index_t* index,
@@ -669,15 +634,27 @@ row_vers_vc_matches_cluster(
dfield_t* field2;
ulint i;
- tuple_heap = mem_heap_create(1024);
-
/* First compare non-virtual columns (primary keys) */
- if (!row_vers_non_vc_match(index, row, ext, ientry, tuple_heap,
- &n_non_v_col)) {
- mem_heap_free(tuple_heap);
- return(false);
+ ut_ad(index->n_fields == n_fields);
+ ut_ad(n_fields == dtuple_get_n_fields(icentry));
+ {
+ const dfield_t* a = ientry->fields;
+ const dfield_t* b = icentry->fields;
+
+ for (const dict_field_t *ifield = index->fields,
+ *const end = &index->fields[index->n_fields];
+ ifield != end; ifield++, a++, b++) {
+ if (!dict_col_is_virtual(ifield->col)) {
+ if (cmp_dfield_dfield(a, b)) {
+ return false;
+ }
+ n_non_v_col++;
+ }
+ }
}
+ tuple_heap = mem_heap_create(1024);
+
ut_ad(n_fields > n_non_v_col);
*vrow = dtuple_create_with_vcol(v_heap ? v_heap : tuple_heap, 0, num_v);
@@ -889,7 +866,7 @@ row_vers_old_has_index_entry(
ut_ad(mtr_memo_contains_page_flagged(mtr, rec, MTR_MEMO_PAGE_X_FIX
| MTR_MEMO_PAGE_S_FIX));
- ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_S));
+ ut_ad(!rw_lock_own(&(purge_sys.latch), RW_LOCK_S));
clust_index = dict_table_get_first_index(index->table);
@@ -912,7 +889,7 @@ row_vers_old_has_index_entry(
/* The top of the stack of versions is locked by the
mtr holding a latch on the page containing the
clustered index record. The bottom of the stack is
- locked by the fact that the purge_sys->view must
+ locked by the fact that the purge_sys.view must
'overtake' any read view of an active transaction.
Thus, it is safe to fetch the prefixes for
externally stored columns. */
@@ -946,27 +923,28 @@ row_vers_old_has_index_entry(
entry = row_build_index_entry(
row, ext, index, heap);
if (entry && !dtuple_coll_cmp(ientry, entry)) {
-
- mem_heap_free(heap);
-
- if (v_heap) {
- mem_heap_free(v_heap);
- }
-
- return(TRUE);
+ goto safe_to_purge;
}
} else {
- if (row_vers_vc_matches_cluster(
- also_curr, rec, row, ext, clust_index,
- clust_offsets, index, ientry, roll_ptr,
- trx_id, NULL, &vrow, mtr)) {
- mem_heap_free(heap);
-
- if (v_heap) {
- mem_heap_free(v_heap);
- }
-
- return(TRUE);
+ /* Build index entry out of row */
+ entry = row_build_index_entry(row, ext, index, heap);
+ /* entry could only be NULL if
+ the clustered index record is an uncommitted
+ inserted record whose BLOBs have not been
+ written yet. The secondary index record
+ can be safely removed, because it cannot
+ possibly refer to this incomplete
+ clustered index record. (Insert would
+ always first be completed for the
+ clustered index record, then proceed to
+ secondary indexes.) */
+
+ if (entry && row_vers_vc_matches_cluster(
+ also_curr, rec, entry,
+ clust_index, clust_offsets,
+ index, ientry, roll_ptr,
+ trx_id, NULL, &vrow, mtr)) {
+ goto safe_to_purge;
}
}
clust_offsets = rec_get_offsets(rec, clust_index, NULL,
@@ -999,7 +977,7 @@ row_vers_old_has_index_entry(
a different binary value in a char field, but the
collation identifies the old and new value anyway! */
if (entry && !dtuple_coll_cmp(ientry, entry)) {
-
+safe_to_purge:
mem_heap_free(heap);
if (v_heap) {
@@ -1096,13 +1074,7 @@ row_vers_old_has_index_entry(
and new value anyway! */
if (entry && !dtuple_coll_cmp(ientry, entry)) {
-
- mem_heap_free(heap);
- if (v_heap) {
- mem_heap_free(v_heap);
- }
-
- return(TRUE);
+ goto safe_to_purge;
}
}
@@ -1149,7 +1121,7 @@ row_vers_build_for_consistent_read(
ut_ad(dict_index_is_clust(index));
ut_ad(mtr_memo_contains_page_flagged(mtr, rec, MTR_MEMO_PAGE_X_FIX
| MTR_MEMO_PAGE_S_FIX));
- ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_S));
+ ut_ad(!rw_lock_own(&(purge_sys.latch), RW_LOCK_S));
ut_ad(rec_offs_validate(rec, index, *offsets));
@@ -1233,6 +1205,7 @@ which should be seen by a semi-consistent read. */
void
row_vers_build_for_semi_consistent_read(
/*====================================*/
+ trx_t* caller_trx,/*!<in/out: trx of current thread */
const rec_t* rec, /*!< in: record in a clustered index; the
caller must have a latch on the page; this
latch locks the top of the stack of versions
@@ -1261,7 +1234,7 @@ row_vers_build_for_semi_consistent_read(
ut_ad(dict_index_is_clust(index));
ut_ad(mtr_memo_contains_page_flagged(mtr, rec, MTR_MEMO_PAGE_X_FIX
| MTR_MEMO_PAGE_S_FIX));
- ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_S));
+ ut_ad(!rw_lock_own(&(purge_sys.latch), RW_LOCK_S));
ut_ad(rec_offs_validate(rec, index, *offsets));
@@ -1269,7 +1242,6 @@ row_vers_build_for_semi_consistent_read(
ut_ad(!vrow || !(*vrow));
for (;;) {
- const trx_t* version_trx;
mem_heap_t* heap2;
rec_t* prev_version;
trx_id_t version_trx_id;
@@ -1279,24 +1251,7 @@ row_vers_build_for_semi_consistent_read(
rec_trx_id = version_trx_id;
}
- if (!version_trx_id) {
- goto committed_version_trx;
- }
-
- trx_sys_mutex_enter();
- version_trx = trx_get_rw_trx_by_id(version_trx_id);
- /* Because version_trx is a read-write transaction,
- its state cannot change from or to NOT_STARTED while
- we are holding the trx_sys->mutex. It may change from
- ACTIVE to PREPARED or COMMITTED. */
- if (version_trx
- && trx_state_eq(version_trx,
- TRX_STATE_COMMITTED_IN_MEMORY)) {
- version_trx = NULL;
- }
- trx_sys_mutex_exit();
-
- if (!version_trx) {
+ if (!trx_sys.is_registered(caller_trx, version_trx_id)) {
committed_version_trx:
/* We found a version that belongs to a
committed transaction: return it. */
diff --git a/storage/innobase/srv/srv0conc.cc b/storage/innobase/srv/srv0conc.cc
index 9f589b57d9c..a1ffa8986a8 100644
--- a/storage/innobase/srv/srv0conc.cc
+++ b/storage/innobase/srv/srv0conc.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2016, MariaDB Corporation.
+Copyright (c) 2015, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -73,16 +73,12 @@ ulong srv_thread_concurrency = 0;
struct srv_conc_t {
char pad[CACHE_LINE_SIZE - (sizeof(ulint) + sizeof(lint))];
- /** Number of transactions that have declared_to_be_inside_innodb set.
- It used to be a non-error for this value to drop below zero temporarily.
- This is no longer true. We'll, however, keep the lint datatype to add
- assertions to catch any corner cases that we may have missed. */
-
- volatile lint n_active;
+ /** Number of transactions that have declared_to_be_inside_innodb */
+ ulint n_active;
/** Number of OS threads waiting in the FIFO for permission to
enter InnoDB */
- volatile lint n_waiting;
+ ulint n_waiting;
};
/* Control variables for tracking concurrency. */
@@ -152,7 +148,7 @@ srv_conc_enter_innodb_with_atomics(
return;
}
- if (srv_conc.n_active < (lint) srv_thread_concurrency) {
+ if (srv_conc.n_active < srv_thread_concurrency) {
ulint n_active;
/* Check if there are any free tickets. */
@@ -273,8 +269,6 @@ srv_conc_force_enter_innodb(
return;
}
- ut_ad(srv_conc.n_active >= 0);
-
(void) my_atomic_addlint(&srv_conc.n_active, 1);
trx->n_tickets_to_enter_innodb = 1;
diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc
index f6c388f2dcf..569e476969f 100644
--- a/storage/innobase/srv/srv0mon.cc
+++ b/storage/innobase/srv/srv0mon.cc
@@ -2,7 +2,7 @@
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -1596,7 +1596,7 @@ srv_mon_get_rseg_size(void)
total rollback segment size and to avoid mutex contention we
don't acquire the rseg->mutex" */
for (i = 0; i < TRX_SYS_N_RSEGS; ++i) {
- const trx_rseg_t* rseg = trx_sys->rseg_array[i];
+ const trx_rseg_t* rseg = trx_sys.rseg_array[i];
if (rseg != NULL) {
value += rseg->curr_size;
@@ -1933,7 +1933,7 @@ srv_mon_process_existing_counter(
/* innodb_row_lock_time_max */
case MONITOR_OVLD_LOCK_MAX_WAIT_TIME:
- value = lock_sys->n_lock_max_wait_time / 1000;
+ value = lock_sys.n_lock_max_wait_time / 1000;
break;
/* innodb_row_lock_time_avg */
@@ -1952,7 +1952,7 @@ srv_mon_process_existing_counter(
break;
case MONITOR_RSEG_HISTORY_LEN:
- value = trx_sys->rseg_history_len;
+ value = trx_sys.history_size();
break;
case MONITOR_RSEG_CUR_SIZE:
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index e3a4eb05010..c94ff932651 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -3,7 +3,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -70,7 +70,6 @@ Created 10/8/1995 Heikki Tuuri
#include "sync0sync.h"
#include "trx0i_s.h"
#include "trx0purge.h"
-#include "usr0sess.h"
#include "ut0crc32.h"
#include "btr0defragment.h"
#include "ut0mem.h"
@@ -78,10 +77,7 @@ Created 10/8/1995 Heikki Tuuri
#include "fil0crypt.h"
#include "fil0pagecompress.h"
#include "btr0scrub.h"
-#ifdef WITH_WSREP
-extern int wsrep_debug;
-extern int wsrep_trx_is_aborting(void *thd_ptr);
-#endif
+
/* The following is the maximum allowed duration of a lock wait. */
UNIV_INTERN ulong srv_fatal_semaphore_wait_threshold = DEFAULT_SRV_FATAL_SEMAPHORE_TIMEOUT;
@@ -250,6 +246,10 @@ ulint srv_buf_pool_base_size;
ulint srv_buf_pool_curr_size;
/** Dump this % of each buffer pool during BP dump */
ulong srv_buf_pool_dump_pct;
+/** Abort load after this amount of pages */
+#ifdef UNIV_DEBUG
+ulong srv_buf_pool_load_pages_abort = LONG_MAX;
+#endif
/** Lock table size in bytes */
ulint srv_lock_table_size = ULINT_MAX;
@@ -437,8 +437,6 @@ stderr on startup/shutdown. Not enabled on the embedded server. */
ibool srv_print_verbose_log;
my_bool srv_print_innodb_monitor;
my_bool srv_print_innodb_lock_monitor;
-my_bool srv_print_innodb_tablespace_monitor;
-my_bool srv_print_innodb_table_monitor;
/** innodb_force_primary_key; whether to disallow CREATE TABLE without
PRIMARY KEY */
my_bool srv_force_primary_key;
@@ -866,7 +864,7 @@ srv_suspend_thread_low(
ut_a(!slot->suspended);
slot->suspended = TRUE;
- if (my_atomic_addlint(&srv_sys.n_threads_active[type], -1) < 0) {
+ if ((lint)my_atomic_addlint(&srv_sys.n_threads_active[type], -1) < 0) {
ut_error;
}
@@ -1303,9 +1301,28 @@ srv_printf_innodb_monitor(
#ifdef BTR_CUR_HASH_ADAPT
for (ulint i = 0; i < btr_ahi_parts; ++i) {
- rw_lock_s_lock(btr_search_latches[i]);
- ha_print_info(file, btr_search_sys->hash_tables[i]);
- rw_lock_s_unlock(btr_search_latches[i]);
+ const hash_table_t* table = btr_search_sys->hash_tables[i];
+
+ ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
+ /* this is only used for buf_pool->page_hash */
+ ut_ad(!table->heaps);
+ /* this is used for the adaptive hash index */
+ ut_ad(table->heap);
+
+ const mem_heap_t* heap = table->heap;
+ /* The heap may change during the following call,
+ so the data displayed may be garbage. We intentionally
+ avoid acquiring btr_search_latches[] so that the
+ diagnostic output will not stop here even in case another
+ thread hangs while holding btr_search_latches[].
+
+ This should be safe from crashes, because
+ table->heap will be pointing to the same object
+ for the full lifetime of the server. Even during
+ btr_search_disable() the heap will stay valid. */
+ fprintf(file, "Hash table size " ULINTPF
+ ", node heap has " ULINTPF " buffer(s)\n",
+ table->n_cells, heap->base.count - !heap->free_block);
}
fprintf(file,
@@ -1348,9 +1365,8 @@ srv_printf_innodb_monitor(
srv_conc_get_active_threads(),
srv_conc_get_waiting_threads());
- /* This is a dirty read, without holding trx_sys->mutex. */
fprintf(file, ULINTPF " read views open inside InnoDB\n",
- trx_sys->mvcc->size());
+ trx_sys.view_count());
n_reserved = fil_space_get_n_reserved_extents(0);
if (n_reserved > 0) {
@@ -1565,7 +1581,7 @@ srv_export_innodb_status(void)
}
export_vars.innodb_row_lock_time_max =
- lock_sys->n_lock_max_wait_time / 1000;
+ lock_sys.n_lock_max_wait_time / 1000;
export_vars.innodb_rows_read = srv_stats.n_rows_read;
@@ -1615,32 +1631,6 @@ srv_export_innodb_status(void)
export_vars.innodb_onlineddl_rowlog_pct_used = onlineddl_rowlog_pct_used;
export_vars.innodb_onlineddl_pct_progress = onlineddl_pct_progress;
-#ifdef UNIV_DEBUG
- rw_lock_s_lock(&purge_sys->latch);
- trx_id_t up_limit_id = purge_sys->view.up_limit_id();;
- trx_id_t done_trx_no = purge_sys->done.trx_no;
- rw_lock_s_unlock(&purge_sys->latch);
-
- mutex_enter(&trx_sys->mutex);
- trx_id_t max_trx_id = trx_sys->rw_max_trx_id;
- mutex_exit(&trx_sys->mutex);
-
- if (!done_trx_no || max_trx_id < done_trx_no - 1) {
- export_vars.innodb_purge_trx_id_age = 0;
- } else {
- export_vars.innodb_purge_trx_id_age =
- (ulint) (max_trx_id - done_trx_no + 1);
- }
-
- if (!up_limit_id
- || max_trx_id < up_limit_id) {
- export_vars.innodb_purge_view_trx_id_age = 0;
- } else {
- export_vars.innodb_purge_view_trx_id_age =
- (ulint) (max_trx_id - up_limit_id);
- }
-#endif /* UNIV_DEBUG */
-
export_vars.innodb_sec_rec_cluster_reads =
srv_stats.n_sec_rec_cluster_reads;
export_vars.innodb_sec_rec_cluster_reads_avoided =
@@ -1691,8 +1681,6 @@ DECLARE_THREAD(srv_monitor_thread)(void*)
double time_elapsed;
time_t current_time;
time_t last_monitor_time;
- time_t last_table_monitor_time;
- time_t last_tablespace_monitor_time;
ulint mutex_skipped;
ibool last_srv_print_monitor;
@@ -1708,8 +1696,6 @@ DECLARE_THREAD(srv_monitor_thread)(void*)
#endif /* UNIV_PFS_THREAD */
srv_last_monitor_time = ut_time();
- last_table_monitor_time = ut_time();
- last_tablespace_monitor_time = ut_time();
last_monitor_time = ut_time();
mutex_skipped = 0;
last_srv_print_monitor = srv_print_innodb_monitor;
@@ -1731,7 +1717,7 @@ loop:
if (srv_print_innodb_monitor) {
/* Reset mutex_skipped counter everytime
srv_print_innodb_monitor changes. This is to
- ensure we will not be blocked by lock_sys->mutex
+ ensure we will not be blocked by lock_sys.mutex
for short duration information printing,
such as requested by sync_array_print_long_waits() */
if (!last_srv_print_monitor) {
@@ -1769,60 +1755,6 @@ loop:
os_file_set_eof(srv_monitor_file);
mutex_exit(&srv_monitor_file_mutex);
}
-
- if (srv_print_innodb_tablespace_monitor
- && difftime(current_time,
- last_tablespace_monitor_time) > 60) {
- last_tablespace_monitor_time = ut_time();
-
- fputs("========================"
- "========================\n",
- stderr);
-
- ut_print_timestamp(stderr);
-
- fputs(" INNODB TABLESPACE MONITOR OUTPUT\n"
- "========================"
- "========================\n",
- stderr);
-
- // JAN: TODO: MySQL 5.7
- //fsp_print(0);
- //fputs("Validating tablespace\n", stderr);
- //fsp_validate(0);
- fputs("Validation ok\n"
- "---------------------------------------\n"
- "END OF INNODB TABLESPACE MONITOR OUTPUT\n"
- "=======================================\n",
- stderr);
- }
-
- if (srv_print_innodb_table_monitor
- && difftime(current_time, last_table_monitor_time) > 60) {
-
- last_table_monitor_time = ut_time();
-
- // fprintf(stderr, "Warning: %s\n",
- // DEPRECATED_MSG_INNODB_TABLE_MONITOR);
-
- fputs("===========================================\n",
- stderr);
-
- ut_print_timestamp(stderr);
-
- fputs(" INNODB TABLE MONITOR OUTPUT\n"
- "===========================================\n",
- stderr);
- // dict_print();
-
- fputs("-----------------------------------\n"
- "END OF INNODB TABLE MONITOR OUTPUT\n"
- "==================================\n",
- stderr);
-
- //fprintf(stderr, "Warning: %s\n",
- // DEPRECATED_MSG_INNODB_TABLE_MONITOR);
- }
}
if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
@@ -1830,9 +1762,7 @@ loop:
}
if (srv_print_innodb_monitor
- || srv_print_innodb_lock_monitor
- || srv_print_innodb_tablespace_monitor
- || srv_print_innodb_table_monitor) {
+ || srv_print_innodb_lock_monitor) {
goto loop;
}
@@ -1997,7 +1927,7 @@ srv_get_active_thread_type(void)
srv_sys_mutex_exit();
if (ret == SRV_NONE && srv_shutdown_state != SRV_SHUTDOWN_NONE
- && purge_sys != NULL) {
+ && purge_sys.is_initialised()) {
/* Check only on shutdown. */
switch (trx_purge_state()) {
case PURGE_STATE_RUN:
@@ -2047,9 +1977,9 @@ srv_wake_purge_thread_if_not_active()
{
ut_ad(!srv_sys_mutex_own());
- if (purge_sys->state == PURGE_STATE_RUN
+ if (purge_sys.state == PURGE_STATE_RUN
&& !my_atomic_loadlint(&srv_sys.n_threads_active[SRV_PURGE])
- && my_atomic_loadlint(&trx_sys->rseg_history_len)) {
+ && trx_sys.history_size()) {
srv_release_threads(SRV_PURGE, 1);
}
@@ -2546,7 +2476,7 @@ srv_purge_should_exit(ulint n_purged)
return(false);
}
/* Exit if there are no active transactions to roll back. */
- return(trx_sys_any_active_transactions() == 0);
+ return(trx_sys.any_active_transactions() == 0);
}
/*********************************************************************//**
@@ -2580,7 +2510,7 @@ srv_task_execute(void)
que_run_threads(thr);
my_atomic_addlint(
- &purge_sys->n_completed, 1);
+ &purge_sys.n_completed, 1);
}
return(thr != NULL);
@@ -2613,8 +2543,8 @@ DECLARE_THREAD(srv_worker_thread)(
slot = srv_reserve_slot(SRV_WORKER);
ut_a(srv_n_purge_threads > 1);
- ut_a(my_atomic_loadlint(&srv_sys.n_threads_active[SRV_WORKER])
- < static_cast<lint>(srv_n_purge_threads));
+ ut_a(ulong(my_atomic_loadlint(&srv_sys.n_threads_active[SRV_WORKER]))
+ < srv_n_purge_threads);
/* We need to ensure that the worker threads exit after the
purge coordinator thread. Otherwise the purge coordinator can
@@ -2633,17 +2563,17 @@ DECLARE_THREAD(srv_worker_thread)(
}
/* Note: we are checking the state without holding the
- purge_sys->latch here. */
- } while (purge_sys->state != PURGE_STATE_EXIT);
+ purge_sys.latch here. */
+ } while (purge_sys.state != PURGE_STATE_EXIT);
srv_free_slot(slot);
- rw_lock_x_lock(&purge_sys->latch);
+ rw_lock_x_lock(&purge_sys.latch);
- ut_a(!purge_sys->running);
- ut_a(purge_sys->state == PURGE_STATE_EXIT);
+ ut_a(!purge_sys.running);
+ ut_a(purge_sys.state == PURGE_STATE_EXIT);
- rw_lock_x_unlock(&purge_sys->latch);
+ rw_lock_x_unlock(&purge_sys.latch);
#ifdef UNIV_DEBUG_THREAD_CREATION
ib::info() << "Purge worker thread exiting, id "
@@ -2688,7 +2618,7 @@ srv_do_purge(ulint* n_total_purged)
}
do {
- if (trx_sys->rseg_history_len > rseg_history_len
+ if (trx_sys.history_size() > rseg_history_len
|| (srv_max_purge_lag > 0
&& rseg_history_len > srv_max_purge_lag)) {
@@ -2717,26 +2647,26 @@ srv_do_purge(ulint* n_total_purged)
ut_a(n_use_threads <= n_threads);
/* Take a snapshot of the history list before purge. */
- if ((rseg_history_len = trx_sys->rseg_history_len) == 0) {
+ if (!(rseg_history_len = trx_sys.history_size())) {
break;
}
ulint undo_trunc_freq =
- purge_sys->undo_trunc.get_rseg_truncate_frequency();
+ purge_sys.undo_trunc.get_rseg_truncate_frequency();
ulint rseg_truncate_frequency = ut_min(
static_cast<ulint>(srv_purge_rseg_truncate_frequency),
undo_trunc_freq);
n_pages_purged = trx_purge(
- n_use_threads, srv_purge_batch_size,
+ n_use_threads,
(++count % rseg_truncate_frequency) == 0);
*n_total_purged += n_pages_purged;
} while (!srv_purge_should_exit(n_pages_purged)
&& n_pages_purged > 0
- && purge_sys->state == PURGE_STATE_RUN);
+ && purge_sys.state == PURGE_STATE_RUN);
return(rseg_history_len);
}
@@ -2763,34 +2693,34 @@ srv_purge_coordinator_suspend(
int64_t sig_count = srv_suspend_thread(slot);
do {
- rw_lock_x_lock(&purge_sys->latch);
+ rw_lock_x_lock(&purge_sys.latch);
- purge_sys->running = false;
+ purge_sys.running = false;
- rw_lock_x_unlock(&purge_sys->latch);
+ rw_lock_x_unlock(&purge_sys.latch);
/* We don't wait right away on the the non-timed wait because
we want to signal the thread that wants to suspend purge. */
const bool wait = stop
- || rseg_history_len <= trx_sys->rseg_history_len;
+ || rseg_history_len <= trx_sys.history_size();
const bool timeout = srv_resume_thread(
slot, sig_count, wait,
stop ? 0 : SRV_PURGE_MAX_TIMEOUT);
sig_count = srv_suspend_thread(slot);
- rw_lock_x_lock(&purge_sys->latch);
+ rw_lock_x_lock(&purge_sys.latch);
stop = (srv_shutdown_state == SRV_SHUTDOWN_NONE
- && purge_sys->state == PURGE_STATE_STOP);
+ && purge_sys.state == PURGE_STATE_STOP);
if (!stop) {
- ut_a(purge_sys->n_stop == 0);
- purge_sys->running = true;
+ ut_a(purge_sys.n_stop == 0);
+ purge_sys.running = true;
if (timeout
- && rseg_history_len == trx_sys->rseg_history_len
- && trx_sys->rseg_history_len < 5000) {
+ && rseg_history_len < 5000
+ && rseg_history_len == trx_sys.history_size()) {
/* No new records were added since the
wait started. Simply wait for new
records. The magic number 5000 is an
@@ -2801,13 +2731,13 @@ srv_purge_coordinator_suspend(
stop = true;
}
} else {
- ut_a(purge_sys->n_stop > 0);
+ ut_a(purge_sys.n_stop > 0);
/* Signal that we are suspended. */
- os_event_set(purge_sys->event);
+ os_event_set(purge_sys.event);
}
- rw_lock_x_unlock(&purge_sys->latch);
+ rw_lock_x_unlock(&purge_sys.latch);
} while (stop && srv_undo_sources);
srv_resume_thread(slot, 0, false);
@@ -2833,12 +2763,12 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
ut_a(trx_purge_state() == PURGE_STATE_INIT);
ut_a(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);
- rw_lock_x_lock(&purge_sys->latch);
+ rw_lock_x_lock(&purge_sys.latch);
- purge_sys->running = true;
- purge_sys->state = PURGE_STATE_RUN;
+ purge_sys.running = true;
+ purge_sys.state = PURGE_STATE_RUN;
- rw_lock_x_unlock(&purge_sys->latch);
+ rw_lock_x_unlock(&purge_sys.latch);
#ifdef UNIV_PFS_THREAD
pfs_register_thread(srv_purge_thread_key);
@@ -2851,7 +2781,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
slot = srv_reserve_slot(SRV_PURGE);
- ulint rseg_history_len = trx_sys->rseg_history_len;
+ ulint rseg_history_len = trx_sys.history_size();
do {
/* If there are no records to purge or the last
@@ -2859,7 +2789,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
if (srv_shutdown_state == SRV_SHUTDOWN_NONE
&& srv_undo_sources
- && (purge_sys->state == PURGE_STATE_STOP
+ && (purge_sys.state == PURGE_STATE_STOP
|| n_total_purged == 0)) {
srv_purge_coordinator_suspend(slot, rseg_history_len);
@@ -2883,17 +2813,20 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
srv_free_slot(slot);
/* Note that we are shutting down. */
- rw_lock_x_lock(&purge_sys->latch);
+ rw_lock_x_lock(&purge_sys.latch);
- purge_sys->state = PURGE_STATE_EXIT;
+ purge_sys.state = PURGE_STATE_EXIT;
/* If there are any pending undo-tablespace truncate then clear
it off as we plan to shutdown the purge thread. */
- purge_sys->undo_trunc.clear();
+ purge_sys.undo_trunc.clear();
+
+ purge_sys.running = false;
- purge_sys->running = false;
+ /* Ensure that the wait in trx_purge_stop() will terminate. */
+ os_event_set(purge_sys.event);
- rw_lock_x_unlock(&purge_sys->latch);
+ rw_lock_x_unlock(&purge_sys.latch);
#ifdef UNIV_DEBUG_THREAD_CREATION
ib::info() << "Purge coordinator exiting, id "
@@ -2958,8 +2891,11 @@ srv_purge_wakeup()
{
ut_ad(!srv_read_only_mode);
- if (srv_force_recovery < SRV_FORCE_NO_BACKGROUND) {
+ if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) {
+ return;
+ }
+ do {
srv_release_threads(SRV_PURGE, 1);
if (srv_n_purge_threads > 1) {
@@ -2967,7 +2903,9 @@ srv_purge_wakeup()
srv_release_threads(SRV_WORKER, n_workers);
}
- }
+ } while (!srv_running
+ && (srv_sys.n_threads_active[SRV_WORKER]
+ || srv_sys.n_threads_active[SRV_PURGE]));
}
/** Check if tablespace is being truncated.
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 988ddf1a759..eb508409e58 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -3,7 +3,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -87,7 +87,6 @@ Created 2/16/1996 Heikki Tuuri
#include "dict0load.h"
#include "dict0stats_bg.h"
#include "que0que.h"
-#include "usr0sess.h"
#include "lock0lock.h"
#include "trx0roll.h"
#include "trx0purge.h"
@@ -684,8 +683,8 @@ srv_undo_tablespace_open(
dberr_t err = DB_ERROR;
char undo_name[sizeof "innodb_undo000"];
- ut_snprintf(undo_name, sizeof(undo_name),
- "innodb_undo%03u", static_cast<unsigned>(space_id));
+ snprintf(undo_name, sizeof(undo_name),
+ "innodb_undo%03u", static_cast<unsigned>(space_id));
if (!srv_file_check_mode(name)) {
ib::error() << "UNDO tablespaces must be " <<
@@ -763,7 +762,7 @@ srv_check_undo_redo_logs_exists()
/* Check if any undo tablespaces exist */
for (ulint i = 1; i <= srv_undo_tablespaces; ++i) {
- ut_snprintf(
+ snprintf(
name, sizeof(name),
"%s%cundo%03zu",
srv_undo_dir, OS_PATH_SEPARATOR,
@@ -860,7 +859,7 @@ srv_undo_tablespaces_init(bool create_new_db)
DBUG_EXECUTE_IF("innodb_undo_upgrade",
space_id = i + 3;);
- ut_snprintf(
+ snprintf(
name, sizeof(name),
"%s%cundo%03zu",
srv_undo_dir, OS_PATH_SEPARATOR, space_id);
@@ -922,10 +921,10 @@ srv_undo_tablespaces_init(bool create_new_db)
char name[OS_FILE_MAX_PATH];
- ut_snprintf(name, sizeof(name),
- "%s%cundo%03zu",
- srv_undo_dir, OS_PATH_SEPARATOR,
- undo_tablespace_ids[i]);
+ snprintf(name, sizeof(name),
+ "%s%cundo%03zu",
+ srv_undo_dir, OS_PATH_SEPARATOR,
+ undo_tablespace_ids[i]);
os_file_delete(innodb_data_file_key, name);
@@ -955,7 +954,7 @@ srv_undo_tablespaces_init(bool create_new_db)
for (i = 0; i < n_undo_tablespaces; ++i) {
char name[OS_FILE_MAX_PATH];
- ut_snprintf(
+ snprintf(
name, sizeof(name),
"%s%cundo%03zu",
srv_undo_dir, OS_PATH_SEPARATOR,
@@ -993,7 +992,7 @@ srv_undo_tablespaces_init(bool create_new_db)
for (i = prev_space_id + 1; i < TRX_SYS_N_RSEGS; ++i) {
char name[OS_FILE_MAX_PATH];
- ut_snprintf(
+ snprintf(
name, sizeof(name),
"%s%cundo%03zu", srv_undo_dir, OS_PATH_SEPARATOR, i);
@@ -1058,7 +1057,6 @@ srv_undo_tablespaces_init(bool create_new_db)
/* Step-1: Initialize the tablespace header and rsegs header. */
mtr_t mtr;
- trx_sysf_t* sys_header;
mtr_start(&mtr);
/* Turn off REDO logging. We are in server start mode and fixing
@@ -1067,7 +1065,11 @@ srv_undo_tablespaces_init(bool create_new_db)
as part of the current recovery process. We surely don't need
that as this is fix-up action parallel to REDO logging. */
mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
- sys_header = trx_sysf_get(&mtr);
+ buf_block_t* sys_header = trx_sysf_get(&mtr);
+ if (!sys_header) {
+ mtr.commit();
+ return DB_CORRUPTION;
+ }
for (undo::undo_spaces_t::const_iterator it
= undo::Truncate::s_fix_up_spaces.begin();
@@ -1082,13 +1084,10 @@ srv_undo_tablespaces_init(bool create_new_db)
mtr_x_lock(fil_space_get_latch(*it, NULL), &mtr);
for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) {
-
- ulint space_id = trx_sysf_rseg_get_space(
- sys_header, i, &mtr);
-
- if (space_id == *it) {
+ if (trx_sysf_rseg_get_space(sys_header, i)
+ == *it) {
trx_rseg_header_create(
- *it, ULINT_MAX, i, &mtr);
+ *it, i, sys_header, &mtr);
}
}
@@ -1097,22 +1096,19 @@ srv_undo_tablespaces_init(bool create_new_db)
mtr_commit(&mtr);
/* Step-2: Flush the dirty pages from the buffer pool. */
- trx_t* trx = trx_allocate_for_background();
-
for (undo::undo_spaces_t::const_iterator it
= undo::Truncate::s_fix_up_spaces.begin();
it != undo::Truncate::s_fix_up_spaces.end();
++it) {
-
- buf_LRU_flush_or_remove_pages(TRX_SYS_SPACE, trx);
-
- buf_LRU_flush_or_remove_pages(*it, trx);
+ FlushObserver dummy(TRX_SYS_SPACE, NULL, NULL);
+ buf_LRU_flush_or_remove_pages(TRX_SYS_SPACE, &dummy);
+ FlushObserver dummy2(*it, NULL, NULL);
+ buf_LRU_flush_or_remove_pages(*it, &dummy2);
/* Remove the truncate redo log file. */
undo::Truncate undo_trunc;
undo_trunc.done_logging(*it);
}
- trx_free_for_background(trx);
}
return(DB_SUCCESS);
@@ -1266,7 +1262,7 @@ srv_shutdown_all_bg_threads()
if (srv_start_state_is_set(SRV_START_STATE_LOCK_SYS)) {
/* a. Let the lock timeout thread exit */
- os_event_set(lock_sys->timeout_event);
+ os_event_set(lock_sys.timeout_event);
}
if (!srv_read_only_mode) {
@@ -1374,6 +1370,7 @@ srv_init_abort_low(
" with error " << ut_strerr(err);
}
+ srv_shutdown_bg_undo_sources();
srv_shutdown_all_bg_threads();
return(err);
}
@@ -1408,13 +1405,16 @@ srv_prepare_to_delete_redo_log_files(
{
ib::info info;
- if (srv_log_file_size == 0) {
+ if (srv_log_file_size == 0
+ || (log_sys->log.format
+ & ~LOG_HEADER_FORMAT_ENCRYPTED)
+ != LOG_HEADER_FORMAT_CURRENT) {
info << "Upgrading redo log: ";
} else if (n_files != srv_n_log_files
|| srv_log_file_size
!= srv_log_file_size_requested) {
if (srv_encrypt_log
- == log_sys->is_encrypted()) {
+ == (my_bool)log_sys->is_encrypted()) {
info << (srv_encrypt_log
? "Resizing encrypted"
: "Resizing");
@@ -1438,6 +1438,7 @@ srv_prepare_to_delete_redo_log_files(
<< " bytes; LSN=" << flushed_lsn;
}
+ srv_start_lsn = flushed_lsn;
/* Flush the old log files. */
log_mutex_exit();
@@ -1648,7 +1649,7 @@ innobase_start_or_create_for_mysql()
+ 1 /* dict_stats_thread */
+ 1 /* fts_optimize_thread */
+ 1 /* recv_writer_thread */
- + 1 /* trx_rollback_or_clean_all_recovered */
+ + 1 /* trx_rollback_all_recovered */
+ 128 /* added as margin, for use of
InnoDB Memcached etc. */
+ max_connections
@@ -1852,7 +1853,7 @@ innobase_start_or_create_for_mysql()
log_sys_init();
recv_sys_init();
- lock_sys_create(srv_lock_table_size);
+ lock_sys.create(srv_lock_table_size);
/* Create i/o-handler threads: */
@@ -2140,7 +2141,7 @@ files_checked:
dict_stats_thread_init();
}
- trx_sys_create();
+ trx_sys.create();
if (create_new_db) {
ut_a(!srv_read_only_mode);
@@ -2170,7 +2171,7 @@ files_checked:
All the remaining rollback segments will be created later,
after the double write buffer has been created. */
trx_sys_create_sys_pages();
- trx_sys_init_at_db_start();
+ trx_lists_init_at_db_start();
err = dict_create();
@@ -2217,17 +2218,28 @@ files_checked:
recv_sys->dblwr.pages.clear();
- if (err == DB_SUCCESS) {
- /* Initialize the change buffer. */
- err = dict_boot();
- }
-
if (err != DB_SUCCESS) {
return(srv_init_abort(err));
}
- /* This must precede recv_apply_hashed_log_recs(true). */
- trx_sys_init_at_db_start();
+ switch (srv_operation) {
+ case SRV_OPERATION_NORMAL:
+ case SRV_OPERATION_RESTORE_EXPORT:
+ /* Initialize the change buffer. */
+ err = dict_boot();
+ if (err != DB_SUCCESS) {
+ return(srv_init_abort(err));
+ }
+ /* fall through */
+ case SRV_OPERATION_RESTORE:
+ /* This must precede
+ recv_apply_hashed_log_recs(true). */
+ trx_lists_init_at_db_start();
+ break;
+ case SRV_OPERATION_RESTORE_DELTA:
+ case SRV_OPERATION_BACKUP:
+ ut_ad(!"wrong mariabackup mode");
+ }
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
/* Apply the hashed log records to the
@@ -2307,7 +2319,7 @@ files_checked:
}
/* recv_recovery_from_checkpoint_finish needs trx lists which
- are initialized in trx_sys_init_at_db_start(). */
+ are initialized in trx_lists_init_at_db_start(). */
recv_recovery_from_checkpoint_finish();
@@ -2331,7 +2343,7 @@ files_checked:
== SRV_OPERATION_RESTORE;
/* Delete subsequent log files. */
delete_log_files(logfilename, dirnamelen,
- srv_n_log_files_found, trunc);
+ (uint)srv_n_log_files_found, trunc);
if (trunc) {
/* Truncate the first log file. */
strcpy(logfilename + dirnamelen,
@@ -2353,7 +2365,11 @@ files_checked:
/* Leave the redo log alone. */
} else if (srv_log_file_size_requested == srv_log_file_size
&& srv_n_log_files_found == srv_n_log_files
- && log_sys->is_encrypted() == srv_encrypt_log) {
+ && log_sys->log.format
+ == (srv_encrypt_log
+ ? LOG_HEADER_FORMAT_CURRENT
+ | LOG_HEADER_FORMAT_ENCRYPTED
+ : LOG_HEADER_FORMAT_CURRENT)) {
/* No need to upgrade or resize the redo log. */
} else {
/* Prepare to delete the old redo log files */
@@ -2451,7 +2467,7 @@ files_checked:
The data dictionary latch should guarantee that there is at
most one data dictionary transaction active at a time. */
if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) {
- trx_rollback_or_clean_recovered(FALSE);
+ trx_rollback_recovered(false);
}
/* Fix-up truncate of tables in the system tablespace
@@ -2549,7 +2565,7 @@ files_checked:
lock_wait_timeout_thread,
NULL, thread_ids + 2 + SRV_MAX_N_IO_THREADS);
thread_started[2 + SRV_MAX_N_IO_THREADS] = true;
- lock_sys->timeout_thread_active = true;
+ lock_sys.timeout_thread_active = true;
/* Create the thread which warns of long semaphore waits */
srv_error_monitor_active = true;
@@ -2567,7 +2583,8 @@ files_checked:
srv_start_state |= SRV_START_STATE_LOCK_SYS
| SRV_START_STATE_MONITOR;
- ut_a(trx_purge_state() == PURGE_STATE_INIT);
+ ut_ad(srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN
+ || trx_purge_state() == PURGE_STATE_INIT);
if (srv_force_recovery < SRV_FORCE_NO_BACKGROUND) {
srv_undo_sources = true;
@@ -2621,8 +2638,6 @@ files_checked:
srv_start_state_set(SRV_START_STATE_MASTER);
}
- srv_is_being_started = false;
-
if (!srv_read_only_mode && srv_operation == SRV_OPERATION_NORMAL
&& srv_force_recovery < SRV_FORCE_NO_BACKGROUND) {
@@ -2647,9 +2662,11 @@ files_checked:
srv_start_state_set(SRV_START_STATE_PURGE);
} else {
- purge_sys->state = PURGE_STATE_DISABLED;
+ purge_sys.state = PURGE_STATE_DISABLED;
}
+ srv_is_being_started = false;
+
if (!srv_read_only_mode) {
/* wake main loop of page cleaner up */
os_event_set(buf_flush_event);
@@ -2657,8 +2674,9 @@ files_checked:
if (srv_print_verbose_log) {
ib::info() << INNODB_VERSION_STR
- << " started; log sequence number "
- << srv_start_lsn;
+ << " started; log sequence number "
+ << srv_start_lsn
+ << "; transaction id " << trx_sys.get_max_trx_id();
}
if (srv_force_recovery > 0) {
@@ -2815,10 +2833,10 @@ innodb_shutdown()
ut_ad(dict_stats_event || !srv_was_started || srv_read_only_mode);
ut_ad(dict_sys || !srv_was_started);
- ut_ad(trx_sys || !srv_was_started);
+ ut_ad(trx_sys.is_initialised() || !srv_was_started);
ut_ad(buf_dblwr || !srv_was_started || srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
- ut_ad(lock_sys || !srv_was_started);
+ ut_ad(lock_sys.is_initialised() || !srv_was_started);
#ifdef BTR_CUR_HASH_ADAPT
ut_ad(btr_search_sys || !srv_was_started);
#endif /* BTR_CUR_HASH_ADAPT */
@@ -2853,18 +2871,12 @@ innodb_shutdown()
if (log_sys) {
log_shutdown();
}
- if (trx_sys) {
- trx_sys_close();
- }
- UT_DELETE(purge_sys);
- purge_sys = NULL;
+ trx_sys.close();
+ purge_sys.close();
if (buf_dblwr) {
buf_dblwr_free();
}
- if (lock_sys) {
- lock_sys_close();
- }
-
+ lock_sys.close();
trx_pool_close();
/* We don't create these mutexes in RO mode because we don't create
@@ -2909,7 +2921,8 @@ innodb_shutdown()
if (srv_was_started && srv_print_verbose_log) {
ib::info() << "Shutdown completed; log sequence number "
- << srv_shutdown_lsn;
+ << srv_shutdown_lsn
+ << "; transaction id " << trx_sys.get_max_trx_id();
}
srv_start_state = SRV_START_STATE_NONE;
diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc
index f1589e1f3a7..b56a5c73a8d 100644
--- a/storage/innobase/sync/sync0arr.cc
+++ b/storage/innobase/sync/sync0arr.cc
@@ -588,9 +588,8 @@ sync_array_cell_print(
fprintf(file,
"number of readers " ULINTPF
- ", waiters flag %u, "
- "lock_word: " ULINTPFx "\n"
- "Last time read locked in file %s line %u\n"
+ ", waiters flag %d, "
+ "lock_word: %x\n"
"Last time write locked in file %s line %u"
#if 0 /* JAN: TODO: FIX LATER */
"\nHolder thread " ULINTPF
@@ -598,10 +597,8 @@ sync_array_cell_print(
#endif
"\n",
rw_lock_get_reader_count(rwlock),
- rwlock->waiters,
- rwlock->lock_word,
- innobase_basename(rwlock->last_s_file_name),
- rwlock->last_s_line,
+ my_atomic_load32_explicit(&rwlock->waiters, MY_MEMORY_ORDER_RELAXED),
+ my_atomic_load32_explicit(&rwlock->lock_word, MY_MEMORY_ORDER_RELAXED),
innobase_basename(rwlock->last_x_file_name),
rwlock->last_x_line
#if 0 /* JAN: TODO: FIX LATER */
@@ -1310,7 +1307,7 @@ sync_arr_fill_sys_semphore_waits_table(
ulint n_items;
DBUG_ENTER("i_s_sys_semaphore_waits_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -1397,11 +1394,10 @@ sync_arr_fill_sys_semphore_waits_table(
//OK(fields[SYS_SEMAPHORE_WAITS_HOLDER_LINE]->store(rwlock->line, true));
//fields[SYS_SEMAPHORE_WAITS_HOLDER_LINE]->set_notnull();
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_READERS], rw_lock_get_reader_count(rwlock)));
- OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAITERS_FLAG], (longlong)rwlock->waiters));
- OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LOCK_WORD], (longlong)rwlock->lock_word));
- OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_LAST_READER_FILE], innobase_basename(rwlock->last_s_file_name)));
- OK(fields[SYS_SEMAPHORE_WAITS_LAST_READER_LINE]->store(rwlock->last_s_line, true));
- fields[SYS_SEMAPHORE_WAITS_LAST_READER_LINE]->set_notnull();
+ OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAITERS_FLAG],
+ my_atomic_load32_explicit(&rwlock->waiters, MY_MEMORY_ORDER_RELAXED)));
+ OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LOCK_WORD],
+ my_atomic_load32_explicit(&rwlock->lock_word, MY_MEMORY_ORDER_RELAXED)));
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE], innobase_basename(rwlock->last_x_file_name)));
OK(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE]->store(rwlock->last_x_line, true));
fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE]->set_notnull();
diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc
index 76796f96913..75e6f0b39ca 100644
--- a/storage/innobase/sync/sync0debug.cc
+++ b/storage/innobase/sync/sync0debug.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -480,6 +480,7 @@ LatchDebug::LatchDebug()
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_TRX_SYS);
LEVEL_MAP_INSERT(SYNC_LOCK_SYS);
LEVEL_MAP_INSERT(SYNC_LOCK_WAIT_SYS);
@@ -761,6 +762,7 @@ LatchDebug::check_order(
case SYNC_THREADS:
case SYNC_LOCK_SYS:
case SYNC_LOCK_WAIT_SYS:
+ case SYNC_RW_TRX_HASH_ELEMENT:
case SYNC_TRX_SYS:
case SYNC_IBUF_BITMAP_MUTEX:
case SYNC_REDO_RSEG:
@@ -809,7 +811,7 @@ LatchDebug::check_order(
case SYNC_TRX:
- /* Either the thread must own the lock_sys->mutex, or
+ /* Either the thread must own the lock_sys.mutex, or
it is allowed to own only ONE trx_t::mutex. */
if (less(latches, level) != NULL) {
@@ -1396,11 +1398,6 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(SRV_MONITOR_FILE, SYNC_NO_ORDER_CHECK,
srv_monitor_file_mutex_key);
-#ifdef UNIV_DEBUG
- LATCH_ADD_MUTEX(SYNC_THREAD, SYNC_NO_ORDER_CHECK,
- sync_thread_mutex_key);
-#endif /* UNIV_DEBUG */
-
LATCH_ADD_MUTEX(BUF_DBLWR, SYNC_DOUBLEWRITE, buf_dblwr_mutex_key);
LATCH_ADD_MUTEX(TRX_UNDO, SYNC_TRX_UNDO, trx_undo_mutex_key);
@@ -1521,6 +1518,8 @@ sync_latch_meta_init()
PFS_NOT_INSTRUMENTED);
LATCH_ADD_MUTEX(FIL_CRYPT_THREADS_MUTEX, SYNC_NO_ORDER_CHECK,
PFS_NOT_INSTRUMENTED);
+ LATCH_ADD_MUTEX(RW_TRX_HASH_ELEMENT, SYNC_RW_TRX_HASH_ELEMENT,
+ rw_trx_hash_element_mutex_key);
latch_id_t id = LATCH_ID_NONE;
@@ -1696,7 +1695,7 @@ private:
};
/** Track latch creation location. For reducing the size of the latches */
-static CreateTracker* create_tracker;
+static CreateTracker create_tracker;
/** Register a latch, called when it is created
@param[in] ptr Latch instance that was created
@@ -1708,7 +1707,7 @@ sync_file_created_register(
const char* filename,
uint16_t line)
{
- create_tracker->register_latch(ptr, filename, line);
+ create_tracker.register_latch(ptr, filename, line);
}
/** Deregister a latch, called when it is destroyed
@@ -1716,7 +1715,7 @@ sync_file_created_register(
void
sync_file_created_deregister(const void* ptr)
{
- create_tracker->deregister_latch(ptr);
+ create_tracker.deregister_latch(ptr);
}
/** Get the string where the file was created. Its format is "name:line"
@@ -1725,7 +1724,7 @@ sync_file_created_deregister(const void* ptr)
std::string
sync_file_created_get(const void* ptr)
{
- return(create_tracker->get(ptr));
+ return(create_tracker.get(ptr));
}
/** Initializes the synchronization data structures. */
@@ -1735,12 +1734,6 @@ sync_check_init()
ut_ad(!LatchDebug::s_initialized);
ut_d(LatchDebug::s_initialized = true);
- /** For collecting latch statistic - SHOW ... MUTEX */
- mutex_monitor = UT_NEW_NOKEY(MutexMonitor());
-
- /** For trcking mutex creation location */
- create_tracker = UT_NEW_NOKEY(CreateTracker());
-
sync_latch_meta_init();
/* Init the rw-lock & mutex list and create the mutex to protect it. */
@@ -1764,14 +1757,6 @@ sync_check_close()
sync_array_close();
- UT_DELETE(mutex_monitor);
-
- mutex_monitor = NULL;
-
- UT_DELETE(create_tracker);
-
- create_tracker = NULL;
-
sync_latch_meta_destroy();
}
diff --git a/storage/innobase/sync/sync0rw.cc b/storage/innobase/sync/sync0rw.cc
index b7b68f98c19..c3a0ed2284b 100644
--- a/storage/innobase/sync/sync0rw.cc
+++ b/storage/innobase/sync/sync0rw.cc
@@ -239,9 +239,7 @@ rw_lock_create_func(
ut_ad(cline <= 8192);
lock->cline = cline;
lock->count_os_wait = 0;
- lock->last_s_file_name = "not yet reserved";
lock->last_x_file_name = "not yet reserved";
- lock->last_s_line = 0;
lock->last_x_line = 0;
lock->event = os_event_create(0);
lock->wait_ex_event = os_event_create(0);
@@ -268,7 +266,8 @@ rw_lock_free_func(
rw_lock_t* lock) /*!< in/out: rw-lock */
{
ut_ad(rw_lock_validate(lock));
- ut_a(lock->lock_word == X_LOCK_DECR);
+ ut_a(my_atomic_load32_explicit(&lock->lock_word,
+ MY_MEMORY_ORDER_RELAXED) == X_LOCK_DECR);
mutex_enter(&rw_lock_list_mutex);
@@ -316,12 +315,9 @@ lock_loop:
/* Spin waiting for the writer field to become free */
HMT_low();
while (i < srv_n_spin_wait_rounds &&
- my_atomic_loadlint_explicit(&lock->lock_word,
- MY_MEMORY_ORDER_RELAXED) <= 0) {
- if (srv_spin_wait_delay) {
- ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
- }
-
+ my_atomic_load32_explicit(&lock->lock_word,
+ MY_MEMORY_ORDER_RELAXED) <= 0) {
+ ut_delay(srv_spin_wait_delay);
i++;
}
@@ -360,7 +356,7 @@ lock_loop:
/* Set waiters before checking lock_word to ensure wake-up
signal is sent. This may lead to some unnecessary signals. */
- my_atomic_fas32((int32*) &lock->waiters, 1);
+ my_atomic_fas32_explicit(&lock->waiters, 1, MY_MEMORY_ORDER_ACQUIRE);
if (rw_lock_s_lock_low(lock, pass, file_name, line)) {
@@ -438,21 +434,16 @@ rw_lock_x_lock_wait_func(
sync_array_t* sync_arr;
uint64_t count_os_wait = 0;
- ut_ad(lock->lock_word <= threshold);
-
- while (lock->lock_word < threshold) {
+ ut_ad(my_atomic_load32_explicit(&lock->lock_word, MY_MEMORY_ORDER_RELAXED) <= threshold);
-
- HMT_low();
- if (srv_spin_wait_delay) {
- ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
- }
+ HMT_low();
+ while (my_atomic_load32_explicit(&lock->lock_word, MY_MEMORY_ORDER_RELAXED) < threshold) {
+ ut_delay(srv_spin_wait_delay);
if (i < srv_n_spin_wait_rounds) {
i++;
continue;
}
- HMT_medium();
/* If there is still a reader, then go to sleep.*/
++n_spins;
@@ -465,7 +456,7 @@ rw_lock_x_lock_wait_func(
i = 0;
/* Check lock_word to ensure wake-up isn't missed.*/
- if (lock->lock_word < threshold) {
+ if (my_atomic_load32_explicit(&lock->lock_word, MY_MEMORY_ORDER_RELAXED) < threshold) {
++count_os_wait;
@@ -488,7 +479,6 @@ rw_lock_x_lock_wait_func(
sync_array_free_cell(sync_arr, cell);
break;
}
- HMT_low();
}
HMT_medium();
rw_lock_stats.rw_x_spin_round_count.add(n_spins);
@@ -564,14 +554,18 @@ rw_lock_x_lock_low(
file_name, line);
} else {
+ int32_t lock_word = my_atomic_load32_explicit(&lock->lock_word,
+ MY_MEMORY_ORDER_RELAXED);
/* At least one X lock by this thread already
exists. Add another. */
- if (lock->lock_word == 0
- || lock->lock_word == -X_LOCK_HALF_DECR) {
- lock->lock_word -= X_LOCK_DECR;
+ if (lock_word == 0
+ || lock_word == -X_LOCK_HALF_DECR) {
+ my_atomic_add32_explicit(&lock->lock_word, -X_LOCK_DECR,
+ MY_MEMORY_ORDER_RELAXED);
} else {
- ut_ad(lock->lock_word <= -X_LOCK_DECR);
- --lock->lock_word;
+ ut_ad(lock_word <= -X_LOCK_DECR);
+ my_atomic_add32_explicit(&lock->lock_word, -1,
+ MY_MEMORY_ORDER_RELAXED);
}
}
@@ -642,12 +636,17 @@ rw_lock_sx_lock_low(
thread working on this lock and it is safe to
read and write to the lock_word. */
- ut_ad((lock->lock_word == 0)
- || ((lock->lock_word <= -X_LOCK_DECR)
- && (lock->lock_word
+#ifdef UNIV_DEBUG
+ int32_t lock_word =
+#endif
+ my_atomic_add32_explicit(&lock->lock_word, -X_LOCK_HALF_DECR,
+ MY_MEMORY_ORDER_RELAXED);
+
+ ut_ad((lock_word == 0)
+ || ((lock_word <= -X_LOCK_DECR)
+ && (lock_word
> -(X_LOCK_DECR
+ X_LOCK_HALF_DECR))));
- lock->lock_word -= X_LOCK_HALF_DECR;
}
} else {
/* Another thread locked before us */
@@ -709,13 +708,8 @@ lock_loop:
/* Spin waiting for the lock_word to become free */
HMT_low();
while (i < srv_n_spin_wait_rounds
- && lock->lock_word <= X_LOCK_HALF_DECR) {
-
- if (srv_spin_wait_delay) {
- ut_delay(ut_rnd_interval(
- 0, srv_spin_wait_delay));
- }
-
+ && my_atomic_load32_explicit(&lock->lock_word, MY_MEMORY_ORDER_RELAXED) <= X_LOCK_HALF_DECR) {
+ ut_delay(srv_spin_wait_delay);
i++;
}
@@ -739,7 +733,7 @@ lock_loop:
/* Waiters must be set before checking lock_word, to ensure signal
is sent. This could lead to a few unnecessary wake-up signals. */
- my_atomic_fas32((int32*) &lock->waiters, 1);
+ my_atomic_fas32_explicit(&lock->waiters, 1, MY_MEMORY_ORDER_ACQUIRE);
if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
sync_array_free_cell(sync_arr, cell);
@@ -815,13 +809,8 @@ lock_loop:
/* Spin waiting for the lock_word to become free */
while (i < srv_n_spin_wait_rounds
- && lock->lock_word <= X_LOCK_HALF_DECR) {
-
- if (srv_spin_wait_delay) {
- ut_delay(ut_rnd_interval(
- 0, srv_spin_wait_delay));
- }
-
+ && my_atomic_load32_explicit(&lock->lock_word, MY_MEMORY_ORDER_RELAXED) <= X_LOCK_HALF_DECR) {
+ ut_delay(srv_spin_wait_delay);
i++;
}
@@ -844,7 +833,7 @@ lock_loop:
/* Waiters must be set before checking lock_word, to ensure signal
is sent. This could lead to a few unnecessary wake-up signals. */
- my_atomic_fas32((int32*) &lock->waiters, 1);
+ my_atomic_fas32_explicit(&lock->waiters, 1, MY_MEMORY_ORDER_ACQUIRE);
if (rw_lock_sx_lock_low(lock, pass, file_name, line)) {
@@ -883,15 +872,15 @@ rw_lock_validate(
/*=============*/
const rw_lock_t* lock) /*!< in: rw-lock */
{
- lint lock_word;
+ int32_t lock_word;
ut_ad(lock);
- lock_word = my_atomic_loadlint_explicit(&lock->lock_word,
- MY_MEMORY_ORDER_RELAXED);
+ lock_word = my_atomic_load32_explicit(const_cast<int32_t*>(&lock->lock_word),
+ MY_MEMORY_ORDER_RELAXED);
ut_ad(lock->magic_n == RW_LOCK_MAGIC_N);
- ut_ad(my_atomic_load32_explicit((int32*) &lock->waiters,
+ ut_ad(my_atomic_load32_explicit(const_cast<int32_t*>(&lock->waiters),
MY_MEMORY_ORDER_RELAXED) < 2);
ut_ad(lock_word > -(2 * X_LOCK_DECR));
ut_ad(lock_word <= X_LOCK_DECR);
@@ -955,15 +944,17 @@ rw_lock_add_debug_info(
rw_lock_debug_mutex_exit();
if (pass == 0 && lock_type != RW_LOCK_X_WAIT) {
+ int32_t lock_word = my_atomic_load32_explicit(&lock->lock_word,
+ MY_MEMORY_ORDER_RELAXED);
/* Recursive x while holding SX
(lock_type == RW_LOCK_X && lock_word == -X_LOCK_HALF_DECR)
is treated as not-relock (new lock). */
if ((lock_type == RW_LOCK_X
- && lock->lock_word < -X_LOCK_HALF_DECR)
+ && lock_word < -X_LOCK_HALF_DECR)
|| (lock_type == RW_LOCK_SX
- && (lock->lock_word < 0 || lock->sx_recursive == 1))) {
+ && (lock_word < 0 || lock->sx_recursive == 1))) {
sync_check_lock_validate(lock);
sync_check_lock_granted(lock);
@@ -1020,7 +1011,7 @@ rw_lock_remove_debug_info(
Checks if the thread has locked the rw-lock in the specified mode, with
the pass value == 0.
@return TRUE if locked */
-ibool
+bool
rw_lock_own(
/*========*/
rw_lock_t* lock, /*!< in: rw-lock */
@@ -1043,12 +1034,12 @@ rw_lock_own(
rw_lock_debug_mutex_exit();
/* Found! */
- return(TRUE);
+ return(true);
}
}
rw_lock_debug_mutex_exit();
- return(FALSE);
+ return(false);
}
/** For collecting the debug information for a thread's rw-lock */
@@ -1154,12 +1145,12 @@ rw_lock_list_print_info(
count++;
- if (lock->lock_word != X_LOCK_DECR) {
+ if (my_atomic_load32_explicit(const_cast<int32_t*>(&lock->lock_word), MY_MEMORY_ORDER_RELAXED) != X_LOCK_DECR) {
fprintf(file, "RW-LOCK: %p ", (void*) lock);
- if (lock->waiters) {
- fputs(" Waiters for the lock exist\n", file);
+ if (int32_t waiters= my_atomic_load32_explicit(const_cast<int32_t*>(&lock->waiters), MY_MEMORY_ORDER_RELAXED)) {
+ fprintf(file, " (%d waiters)\n", waiters);
} else {
putc('\n', file);
}
diff --git a/storage/innobase/sync/sync0sync.cc b/storage/innobase/sync/sync0sync.cc
index 5d98e49fd6d..9716d573a63 100644
--- a/storage/innobase/sync/sync0sync.cc
+++ b/storage/innobase/sync/sync0sync.cc
@@ -68,7 +68,6 @@ 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;
# ifdef UNIV_DEBUG
-mysql_pfs_key_t sync_thread_mutex_key;
mysql_pfs_key_t rw_lock_debug_mutex_key;
# endif /* UNIV_DEBUG */
mysql_pfs_key_t rtr_active_mutex_key;
@@ -96,6 +95,7 @@ mysql_pfs_key_t sync_array_mutex_key;
mysql_pfs_key_t thread_mutex_key;
mysql_pfs_key_t zip_pad_mutex_key;
mysql_pfs_key_t row_drop_list_mutex_key;
+mysql_pfs_key_t rw_trx_hash_element_mutex_key;
#endif /* UNIV_PFS_MUTEX */
#ifdef UNIV_PFS_RWLOCK
mysql_pfs_key_t btr_search_latch_key;
@@ -117,7 +117,7 @@ mysql_pfs_key_t trx_purge_latch_key;
#endif /* UNIV_PFS_RWLOCK */
/** For monitoring active mutexes */
-MutexMonitor* mutex_monitor;
+MutexMonitor mutex_monitor;
/**
Prints wait info of the sync system.
@@ -148,13 +148,13 @@ sync_print_wait_info(FILE* file)
" %.2f RW-excl, %.2f RW-sx\n",
(double) rw_lock_stats.rw_s_spin_round_count /
(rw_lock_stats.rw_s_spin_wait_count
- ? rw_lock_stats.rw_s_spin_wait_count : 1),
+ ? rw_lock_stats.rw_s_spin_wait_count : 1LL),
(double) rw_lock_stats.rw_x_spin_round_count /
(rw_lock_stats.rw_x_spin_wait_count
- ? rw_lock_stats.rw_x_spin_wait_count : 1),
+ ? rw_lock_stats.rw_x_spin_wait_count : 1LL),
(double) rw_lock_stats.rw_sx_spin_round_count /
(rw_lock_stats.rw_sx_spin_wait_count
- ? rw_lock_stats.rw_sx_spin_wait_count : 1));
+ ? rw_lock_stats.rw_sx_spin_wait_count : 1LL));
}
/**
diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc
index 327ebf79211..65036b9f05c 100644
--- a/storage/innobase/trx/trx0i_s.cc
+++ b/storage/innobase/trx/trx0i_s.cc
@@ -172,10 +172,10 @@ struct trx_i_s_cache_t {
ha_storage_t* storage; /*!< storage for external volatile
data that may become unavailable
when we release
- lock_sys->mutex or trx_sys->mutex */
+ lock_sys.mutex or trx_sys.mutex */
ulint mem_allocd; /*!< the amount of memory
allocated with mem_alloc*() */
- ibool is_truncated; /*!< this is TRUE if the memory
+ bool is_truncated; /*!< this is true if the memory
limit was hit and thus the data
in the cache is truncated */
};
@@ -537,9 +537,9 @@ thd_done:
row->trx_tables_locked = lock_number_of_tables_locked(&trx->lock);
- /* These are protected by both trx->mutex or lock_sys->mutex,
- or just lock_sys->mutex. For reading, it suffices to hold
- lock_sys->mutex. */
+ /* These are protected by both trx->mutex or lock_sys.mutex,
+ or just lock_sys.mutex. For reading, it suffices to hold
+ lock_sys.mutex. */
row->trx_lock_structs = UT_LIST_GET_LEN(trx->lock.trx_locks);
@@ -1245,102 +1245,86 @@ trx_i_s_cache_clear(
ha_storage_empty(&cache->storage);
}
-/*******************************************************************//**
-Fetches the data needed to fill the 3 INFORMATION SCHEMA tables into the
-table cache buffer. Cache must be locked for write. */
-static
-void
-fetch_data_into_cache_low(
-/*======================*/
- trx_i_s_cache_t* cache, /*!< in/out: cache */
- bool read_write, /*!< in: only read-write
- transactions */
- trx_ut_list_t* trx_list) /*!< in: trx list */
-{
- const trx_t* trx;
- bool rw_trx_list = trx_list == &trx_sys->rw_trx_list;
-
- ut_ad(rw_trx_list || trx_list == &trx_sys->mysql_trx_list);
-
- /* Iterate over the transaction list and add each one
- to innodb_trx's cache. We also add all locks that are relevant
- to each transaction into innodb_locks' and innodb_lock_waits'
- caches. */
-
- for (trx = UT_LIST_GET_FIRST(*trx_list);
- trx != NULL;
- trx =
- (rw_trx_list
- ? UT_LIST_GET_NEXT(trx_list, trx)
- : UT_LIST_GET_NEXT(mysql_trx_list, trx))) {
-
- i_s_trx_row_t* trx_row;
- i_s_locks_row_t* requested_lock_row;
-
- /* Note: Read only transactions that modify temporary
- tables an have a transaction ID */
- if (!trx_is_started(trx)
- || (!rw_trx_list && trx->id != 0 && !trx->read_only)) {
- continue;
- }
-
- assert_trx_nonlocking_or_in_list(trx);
-
- ut_ad(trx->in_rw_trx_list == rw_trx_list);
-
- if (!add_trx_relevant_locks_to_cache(cache, trx,
- &requested_lock_row)) {
-
- cache->is_truncated = TRUE;
- return;
- }
-
- trx_row = reinterpret_cast<i_s_trx_row_t*>(
- table_cache_create_empty_row(
- &cache->innodb_trx, cache));
-
- /* memory could not be allocated */
- if (trx_row == NULL) {
-
- cache->is_truncated = TRUE;
- return;
- }
+/**
+ Add transactions to innodb_trx's cache.
- if (!fill_trx_row(trx_row, trx, requested_lock_row, cache)) {
+ We also add all locks that are relevant to each transaction into
+ innodb_locks' and innodb_lock_waits' caches.
+*/
- /* memory could not be allocated */
- --cache->innodb_trx.rows_used;
- cache->is_truncated = TRUE;
- return;
- }
- }
+static void fetch_data_into_cache_low(trx_i_s_cache_t *cache, const trx_t *trx)
+{
+ i_s_locks_row_t *requested_lock_row;
+
+ assert_trx_nonlocking_or_in_list(trx);
+
+ if (add_trx_relevant_locks_to_cache(cache, trx, &requested_lock_row))
+ {
+ if (i_s_trx_row_t *trx_row= reinterpret_cast<i_s_trx_row_t*>(
+ table_cache_create_empty_row(&cache->innodb_trx, cache)))
+ {
+ if (fill_trx_row(trx_row, trx, requested_lock_row, cache))
+ return;
+ --cache->innodb_trx.rows_used;
+ }
+ }
+
+ /* memory could not be allocated */
+ cache->is_truncated= true;
}
-/*******************************************************************//**
-Fetches the data needed to fill the 3 INFORMATION SCHEMA tables into the
-table cache buffer. Cache must be locked for write. */
-static
-void
-fetch_data_into_cache(
-/*==================*/
- trx_i_s_cache_t* cache) /*!< in/out: cache */
-{
- ut_ad(lock_mutex_own());
- ut_ad(trx_sys_mutex_own());
- trx_i_s_cache_clear(cache);
+static my_bool fetch_data_into_cache_callback(
+ rw_trx_hash_element_t *element, trx_i_s_cache_t *cache)
+{
+ mutex_enter(&element->mutex);
+ if (element->trx)
+ fetch_data_into_cache_low(cache, element->trx);
+ mutex_exit(&element->mutex);
+ return cache->is_truncated;
+}
- /* Capture the state of the read-write transactions. This includes
- internal transactions too. They are not on mysql_trx_list */
- fetch_data_into_cache_low(cache, true, &trx_sys->rw_trx_list);
- /* Capture the state of the read-only active transactions */
- fetch_data_into_cache_low(cache, false, &trx_sys->mysql_trx_list);
+/**
+ Fetches the data needed to fill the 3 INFORMATION SCHEMA tables into the
+ table cache buffer. Cache must be locked for write.
+*/
- cache->is_truncated = FALSE;
+static void fetch_data_into_cache(trx_i_s_cache_t *cache)
+{
+ ut_ad(lock_mutex_own());
+ trx_i_s_cache_clear(cache);
+
+ /*
+ Capture the state of the read-write transactions. This includes
+ internal transactions too. They are not on mysql_trx_list
+ */
+ trx_sys.rw_trx_hash.iterate_no_dups(reinterpret_cast<my_hash_walk_action>
+ (fetch_data_into_cache_callback), cache);
+
+ /* Capture the state of the read-only active transactions */
+ mutex_enter(&trx_sys.mutex);
+ for (const trx_t *trx= UT_LIST_GET_FIRST(trx_sys.mysql_trx_list);
+ trx != NULL;
+ trx= UT_LIST_GET_NEXT(mysql_trx_list, trx))
+ {
+ /*
+ Skip transactions that have trx->id > 0: they were added in previous
+ iteration. Although we may miss concurrently started transactions.
+ */
+ if (trx_is_started(trx) && trx->id == 0)
+ {
+ fetch_data_into_cache_low(cache, trx);
+ if (cache->is_truncated)
+ break;
+ }
+ }
+ mutex_exit(&trx_sys.mutex);
+ cache->is_truncated= false;
}
+
/*******************************************************************//**
Update the transactions cache if it has not been read for some time.
Called from handler/i_s.cc.
@@ -1358,13 +1342,7 @@ trx_i_s_possibly_fetch_data_into_cache(
/* We need to read trx_sys and record/table lock queues */
lock_mutex_enter();
-
- trx_sys_mutex_enter();
-
fetch_data_into_cache(cache);
-
- trx_sys_mutex_exit();
-
lock_mutex_exit();
/* update cache last read time */
@@ -1378,7 +1356,7 @@ trx_i_s_possibly_fetch_data_into_cache(
Returns TRUE if the data in the cache is truncated due to the memory
limit posed by TRX_I_S_MEM_LIMIT.
@return TRUE if truncated */
-ibool
+bool
trx_i_s_cache_is_truncated(
/*=======================*/
trx_i_s_cache_t* cache) /*!< in: cache */
@@ -1425,7 +1403,7 @@ trx_i_s_cache_init(
cache->mem_allocd = 0;
- cache->is_truncated = FALSE;
+ cache->is_truncated = false;
}
/*******************************************************************//**
@@ -1607,17 +1585,17 @@ trx_i_s_create_lock_id(
if (row->lock_space != ULINT_UNDEFINED) {
/* record lock */
- res_len = ut_snprintf(lock_id, lock_id_size,
- TRX_ID_FMT
- ":" ULINTPF ":" ULINTPF ":" ULINTPF,
- row->lock_trx_id, row->lock_space,
- row->lock_page, row->lock_rec);
+ res_len = snprintf(lock_id, lock_id_size,
+ TRX_ID_FMT
+ ":" ULINTPF ":" ULINTPF ":" ULINTPF,
+ row->lock_trx_id, row->lock_space,
+ row->lock_page, row->lock_rec);
} else {
/* table lock */
- res_len = ut_snprintf(lock_id, lock_id_size,
- TRX_ID_FMT":" UINT64PF,
- row->lock_trx_id,
- row->lock_table_id);
+ res_len = snprintf(lock_id, lock_id_size,
+ TRX_ID_FMT":" UINT64PF,
+ row->lock_trx_id,
+ row->lock_table_id);
}
/* the typecast is safe because snprintf(3) never returns
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 738f713298b..c2c9ffbd8a5 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -33,7 +33,6 @@ Created 3/26/1996 Heikki Tuuri
#include "mtr0log.h"
#include "os0thread.h"
#include "que0que.h"
-#include "read0read.h"
#include "row0purge.h"
#include "row0upd.h"
#include "srv0mon.h"
@@ -45,6 +44,7 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0roll.h"
#include "trx0rseg.h"
#include "trx0trx.h"
+#include <mysql/service_wsrep.h>
/** Maximum allowable purge history length. <=0 means 'infinite'. */
ulong srv_max_purge_lag = 0;
@@ -53,7 +53,7 @@ ulong srv_max_purge_lag = 0;
ulong srv_max_purge_lag_delay = 0;
/** The global data structure coordinating a purge */
-purge_sys_t* purge_sys;
+purge_sys_t purge_sys;
/** A dummy undo record used as a return value when we have a whole undo log
which needs no purge */
@@ -64,122 +64,82 @@ my_bool srv_purge_view_update_only_debug;
#endif /* UNIV_DEBUG */
/** Sentinel value */
-const TrxUndoRsegs TrxUndoRsegsIterator::NullElement(UINT64_UNDEFINED);
+static const TrxUndoRsegs NullElement;
-/** Constructor */
+/** Default constructor */
TrxUndoRsegsIterator::TrxUndoRsegsIterator()
- :
- m_trx_undo_rsegs(NullElement),
- m_iter(m_trx_undo_rsegs.end())
+ : m_rsegs(NullElement), m_iter(m_rsegs.begin())
{
}
/** Sets the next rseg to purge in purge_sys.
+Executed in the purge coordinator thread.
@return whether anything is to be purged */
-inline
-bool
-TrxUndoRsegsIterator::set_next()
+inline bool TrxUndoRsegsIterator::set_next()
{
- mutex_enter(&purge_sys->pq_mutex);
+ mutex_enter(&purge_sys.pq_mutex);
/* Only purge consumes events from the priority queue, user
threads only produce the events. */
/* Check if there are more rsegs to process in the
current element. */
- if (m_iter != m_trx_undo_rsegs.end()) {
-
+ if (m_iter != m_rsegs.end()) {
/* We are still processing rollback segment from
the same transaction and so expected transaction
- number shouldn't increase. Undo increment of
- expected trx_no done by caller assuming rollback
+ number shouldn't increase. Undo the increment of
+ expected commit done by caller assuming rollback
segments from given transaction are done. */
- purge_sys->iter.trx_no = (*m_iter)->last_trx_no;
-
- } else if (!purge_sys->purge_queue.empty()) {
-
- /* Read the next element from the queue.
- Combine elements if they have same transaction number.
- This can happen if a transaction shares redo rollback segment
- with another transaction that has already added it to purge
- queue and former transaction also needs to schedule non-redo
- rollback segment for purge. */
- m_trx_undo_rsegs = NullElement;
-
- purge_pq_t& purge_queue = purge_sys->purge_queue;
-
- while (!purge_queue.empty()) {
-
- if (m_trx_undo_rsegs.get_trx_no() == UINT64_UNDEFINED) {
- m_trx_undo_rsegs = purge_queue.top();
- } else if (purge_queue.top().get_trx_no() ==
- m_trx_undo_rsegs.get_trx_no()) {
- m_trx_undo_rsegs.append(
- purge_queue.top());
- } else {
- break;
- }
-
- purge_queue.pop();
- }
-
- m_iter = m_trx_undo_rsegs.begin();
-
+ purge_sys.tail.commit = (*m_iter)->last_commit;
+ } else if (!purge_sys.purge_queue.empty()) {
+ m_rsegs = purge_sys.purge_queue.top();
+ purge_sys.purge_queue.pop();
+ ut_ad(purge_sys.purge_queue.empty()
+ || purge_sys.purge_queue.top() != m_rsegs);
+ m_iter = m_rsegs.begin();
} else {
/* Queue is empty, reset iterator. */
- m_trx_undo_rsegs = NullElement;
- m_iter = m_trx_undo_rsegs.end();
-
- mutex_exit(&purge_sys->pq_mutex);
-
- purge_sys->rseg = NULL;
+ purge_sys.rseg = NULL;
+ mutex_exit(&purge_sys.pq_mutex);
+ m_rsegs = NullElement;
+ m_iter = m_rsegs.begin();
return false;
}
- purge_sys->rseg = *m_iter++;
-
- mutex_exit(&purge_sys->pq_mutex);
-
- ut_a(purge_sys->rseg != NULL);
-
- mutex_enter(&purge_sys->rseg->mutex);
+ purge_sys.rseg = *m_iter++;
+ mutex_exit(&purge_sys.pq_mutex);
+ mutex_enter(&purge_sys.rseg->mutex);
- ut_a(purge_sys->rseg->last_page_no != FIL_NULL);
- ut_ad(purge_sys->rseg->last_trx_no == m_trx_undo_rsegs.get_trx_no());
+ ut_a(purge_sys.rseg->last_page_no != FIL_NULL);
+ ut_ad(purge_sys.rseg->last_trx_no() == m_rsegs.trx_no());
/* We assume in purge of externally stored fields that space id is
in the range of UNDO tablespace space ids */
- ut_a(purge_sys->rseg->space == TRX_SYS_SPACE
- || srv_is_undo_tablespace(purge_sys->rseg->space));
+ ut_a(purge_sys.rseg->space == TRX_SYS_SPACE
+ || srv_is_undo_tablespace(purge_sys.rseg->space));
- ut_a(purge_sys->iter.trx_no <= purge_sys->rseg->last_trx_no);
+ ut_a(purge_sys.tail.commit <= purge_sys.rseg->last_commit);
- purge_sys->iter.trx_no = purge_sys->rseg->last_trx_no;
- purge_sys->hdr_offset = purge_sys->rseg->last_offset;
- purge_sys->hdr_page_no = purge_sys->rseg->last_page_no;
+ purge_sys.tail.commit = purge_sys.rseg->last_commit;
+ purge_sys.hdr_offset = purge_sys.rseg->last_offset;
+ purge_sys.hdr_page_no = purge_sys.rseg->last_page_no;
- mutex_exit(&purge_sys->rseg->mutex);
+ mutex_exit(&purge_sys.rseg->mutex);
return(true);
}
/** Build a purge 'query' graph. The actual purge is performed by executing
this query graph.
-@param[in,out] sess the purge session
@return own: the query graph */
static
que_t*
-trx_purge_graph_build(sess_t* sess)
+purge_graph_build()
{
ut_a(srv_n_purge_threads > 0);
- /* A purge transaction is not a real transaction, we use a transaction
- here only because the query threads code requires it. It is otherwise
- quite unnecessary. We should get rid of it eventually. */
- trx_t* trx = sess->trx;
- ut_ad(trx->sess == sess);
-
- trx->id = 0;
+ trx_t* trx = trx_allocate_for_background();
+ ut_ad(!trx->id);
trx->start_time = ut_time();
trx->state = TRX_STATE_ACTIVE;
trx->op_info = "purge trx";
@@ -197,35 +157,43 @@ trx_purge_graph_build(sess_t* sess)
return(fork);
}
-/** Construct the purge system. */
-purge_sys_t::purge_sys_t()
- : sess(sess_open()), latch(), event(os_event_create(0)),
- n_stop(0), running(false), state(PURGE_STATE_INIT),
- query(trx_purge_graph_build(sess)),
- view(), n_submitted(0), n_completed(0),
- iter(), limit(),
-#ifdef UNIV_DEBUG
- done(),
-#endif /* UNIV_DEBUG */
- next_stored(false), rseg(NULL),
- page_no(0), offset(0), hdr_page_no(0), hdr_offset(0),
- rseg_iter(), purge_queue(), pq_mutex(), undo_trunc()
+/** Initialise the purge system. */
+void purge_sys_t::create()
{
- ut_ad(!purge_sys);
- rw_lock_create(trx_purge_latch_key, &latch, SYNC_PURGE_LATCH);
- mutex_create(LATCH_ID_PURGE_SYS_PQ, &pq_mutex);
+ ut_ad(this == &purge_sys);
+ ut_ad(!is_initialised());
+ event= os_event_create(0);
+ n_stop= 0;
+ running= false;
+ state= PURGE_STATE_INIT;
+ query= purge_graph_build();
+ n_submitted= 0;
+ n_completed= 0;
+ next_stored= false;
+ rseg= NULL;
+ page_no= 0;
+ offset= 0;
+ hdr_page_no= 0;
+ hdr_offset= 0;
+ rw_lock_create(trx_purge_latch_key, &latch, SYNC_PURGE_LATCH);
+ mutex_create(LATCH_ID_PURGE_SYS_PQ, &pq_mutex);
+ undo_trunc.create();
+ m_initialised = true;
}
-/** Destruct the purge system. */
-purge_sys_t::~purge_sys_t()
+/** Close the purge subsystem on shutdown. */
+void purge_sys_t::close()
{
- ut_ad(this == purge_sys);
+ ut_ad(this == &purge_sys);
+ if (!is_initialised()) return;
+ m_initialised = false;
+ trx_t* trx = query->trx;
que_graph_free(query);
- ut_a(sess->trx->id == 0);
- sess->trx->state = TRX_STATE_NOT_STARTED;
- sess_close(sess);
- view.close();
+ ut_ad(!trx->id);
+ ut_ad(trx->state == TRX_STATE_ACTIVE);
+ trx->state = TRX_STATE_NOT_STARTED;
+ trx_free_for_background(trx);
rw_lock_free(&latch);
/* rw_lock_free() already called latch.~rw_lock_t(); tame the
debug assertions when the destructor will be called once more. */
@@ -245,6 +213,8 @@ Remove the undo log segment from the rseg slot if it is too big for reuse.
void
trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
{
+ DBUG_PRINT("trx", ("commit(" TRX_ID_FMT "," TRX_ID_FMT ")",
+ trx->id, trx->no));
ut_ad(undo == trx->rsegs.m_redo.undo
|| undo == trx->rsegs.m_redo.old_insert);
trx_rseg_t* rseg = trx->rsegs.m_redo.rseg;
@@ -257,6 +227,12 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
ut_ad(mach_read_from_2(undo_header + TRX_UNDO_NEEDS_PURGE) <= 1);
+ if (UNIV_UNLIKELY(mach_read_from_4(TRX_RSEG_FORMAT + rseg_header))) {
+ /* This database must have been upgraded from
+ before MariaDB 10.3.5. */
+ trx_rseg_format_upgrade(rseg_header, mtr);
+ }
+
if (undo->state != TRX_UNDO_CACHED) {
ulint hist_size;
#ifdef UNIV_DEBUG
@@ -264,11 +240,7 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
#endif /* UNIV_DEBUG */
/* The undo log segment will not be reused */
-
- if (UNIV_UNLIKELY(undo->id >= TRX_RSEG_N_SLOTS)) {
- ib::fatal() << "undo->id is " << undo->id;
- }
-
+ ut_a(undo->id < TRX_RSEG_N_SLOTS);
trx_rsegf_set_nth_undo(rseg_header, undo->id, FIL_NULL, mtr);
MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_USED);
@@ -284,6 +256,11 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
hist_size + undo->size, MLOG_4BYTES, mtr);
}
+ /* This field now also serves as an identifier for the latest
+ binlog and WSREP XID information. */
+ mlog_write_ull(rseg_header + TRX_RSEG_MAX_TRX_ID,
+ trx_sys.get_max_trx_id(), mtr);
+
/* Before any transaction-generating background threads or the
purge have been started, recv_recovery_rollback_active() can
start transactions in row_merge_drop_temp_indexes() and
@@ -300,19 +277,31 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
continue to execute user transactions. */
ut_ad(srv_undo_sources
|| ((srv_startup_is_before_trx_rollback_phase
- || trx_rollback_or_clean_is_active)
- && purge_sys->state == PURGE_STATE_INIT)
+ || trx_rollback_is_active)
+ && purge_sys.state == PURGE_STATE_INIT)
|| (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND
- && purge_sys->state == PURGE_STATE_DISABLED)
- || ((trx->undo_no == 0 || trx->in_mysql_trx_list)
+ && purge_sys.state == PURGE_STATE_DISABLED)
+ || ((trx->undo_no == 0 || trx->in_mysql_trx_list
+ || trx->internal)
&& srv_fast_shutdown));
+#ifdef WITH_WSREP
+ if (wsrep_is_wsrep_xid(trx->xid)) {
+ trx_rseg_update_wsrep_checkpoint(rseg_header, trx->xid, mtr);
+ }
+#endif
+
+ if (trx->mysql_log_file_name && *trx->mysql_log_file_name) {
+ /* Update the latest MySQL binlog name and offset info
+ in rollback segment header if MySQL binlogging is on
+ or the database server is a MySQL replication save. */
+ trx_rseg_update_binlog_offset(rseg_header, trx, mtr);
+ }
+
/* Add the log as the first in the history list */
flst_add_first(rseg_header + TRX_RSEG_HISTORY,
undo_header + TRX_UNDO_HISTORY_NODE, mtr);
- my_atomic_addlint(&trx_sys->rseg_history_len, 1);
-
mlog_write_ull(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr);
/* This is needed for upgrading old undo log pages from
before MariaDB 10.3.1. */
@@ -325,16 +314,18 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
if (rseg->last_page_no == FIL_NULL) {
rseg->last_page_no = undo->hdr_page_no;
rseg->last_offset = undo->hdr_offset;
- rseg->last_trx_no = trx->no;
+ rseg->set_last_trx_no(trx->no, undo == trx->rsegs.m_redo.undo);
rseg->needs_purge = true;
}
+ trx_sys.history_insert();
+
if (undo->state == TRX_UNDO_CACHED) {
UT_LIST_ADD_FIRST(rseg->undo_cached, undo);
MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED);
} else {
ut_ad(undo->state == TRX_UNDO_TO_PURGE);
- trx_undo_mem_free(undo);
+ ut_free(undo);
}
undo = NULL;
@@ -353,7 +344,7 @@ trx_purge_remove_log_hdr(
{
flst_remove(rseg_hdr + TRX_RSEG_HISTORY,
log_hdr + TRX_UNDO_HISTORY_NODE, mtr);
- my_atomic_addlint(&trx_sys->rseg_history_len, -1);
+ trx_sys.history_remove();
}
/** Free an undo log segment, and remove the header from the history list.
@@ -440,10 +431,12 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
/** Remove unnecessary history data from a rollback segment.
@param[in,out] rseg rollback segment
-@param[in] limit truncate offset */
+@param[in] limit truncate anything before this */
static
void
-trx_purge_truncate_rseg_history(trx_rseg_t* rseg, const purge_iter_t* limit)
+trx_purge_truncate_rseg_history(
+ trx_rseg_t& rseg,
+ const purge_sys_t::iterator& limit)
{
fil_addr_t hdr_addr;
fil_addr_t prev_hdr_addr;
@@ -454,48 +447,37 @@ trx_purge_truncate_rseg_history(trx_rseg_t* rseg, const purge_iter_t* limit)
mtr_t mtr;
trx_id_t undo_trx_no;
- mtr_start(&mtr);
- ut_ad(rseg->is_persistent());
- mutex_enter(&(rseg->mutex));
+ mtr.start();
+ ut_ad(rseg.is_persistent());
+ mutex_enter(&rseg.mutex);
- rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr);
+ rseg_hdr = trx_rsegf_get(rseg.space, rseg.page_no, &mtr);
hdr_addr = trx_purge_get_log_from_hist(
flst_get_last(rseg_hdr + TRX_RSEG_HISTORY, &mtr));
loop:
if (hdr_addr.page == FIL_NULL) {
-
- mutex_exit(&(rseg->mutex));
-
- mtr_commit(&mtr);
-
+func_exit:
+ mutex_exit(&rseg.mutex);
+ mtr.commit();
return;
}
- undo_page = trx_undo_page_get(page_id_t(rseg->space, hdr_addr.page),
+ undo_page = trx_undo_page_get(page_id_t(rseg.space, hdr_addr.page),
&mtr);
log_hdr = undo_page + hdr_addr.boffset;
undo_trx_no = mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO);
- if (undo_trx_no >= limit->trx_no) {
-
- /* limit space_id should match the rollback segment
- space id to avoid freeing of the page belongs to
- different rollback segment for the same trx_no. */
- if (undo_trx_no == limit->trx_no
- && rseg->space == limit->undo_rseg_space) {
-
+ if (undo_trx_no >= limit.trx_no()) {
+ if (undo_trx_no == limit.trx_no()) {
trx_undo_truncate_start(
- rseg, hdr_addr.page,
- hdr_addr.boffset, limit->undo_no);
+ &rseg, hdr_addr.page,
+ hdr_addr.boffset, limit.undo_no);
}
- mutex_exit(&(rseg->mutex));
- mtr_commit(&mtr);
-
- return;
+ goto func_exit;
}
prev_hdr_addr = trx_purge_get_log_from_hist(
@@ -508,24 +490,24 @@ loop:
/* We can free the whole log segment */
- mutex_exit(&(rseg->mutex));
- mtr_commit(&mtr);
+ mutex_exit(&rseg.mutex);
+ mtr.commit();
/* calls the trx_purge_remove_log_hdr()
inside trx_purge_free_segment(). */
- trx_purge_free_segment(rseg, hdr_addr);
+ trx_purge_free_segment(&rseg, hdr_addr);
} else {
/* Remove the log hdr from the rseg history. */
trx_purge_remove_log_hdr(rseg_hdr, log_hdr, &mtr);
- mutex_exit(&(rseg->mutex));
- mtr_commit(&mtr);
+ mutex_exit(&rseg.mutex);
+ mtr.commit();
}
- mtr_start(&mtr);
- mutex_enter(&(rseg->mutex));
+ mtr.start();
+ mutex_enter(&rseg.mutex);
- rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr);
+ rseg_hdr = trx_rsegf_get(rseg.space, rseg.page_no, &mtr);
hdr_addr = prev_hdr_addr;
@@ -569,10 +551,10 @@ namespace undo {
log_file_name_len = strlen(log_file_name);
}
- ut_snprintf(log_file_name + log_file_name_len,
- log_file_name_sz - log_file_name_len,
- "%s%lu_%s", undo::s_log_prefix,
- (ulong) space_id, s_log_ext);
+ snprintf(log_file_name + log_file_name_len,
+ log_file_name_sz - log_file_name_len,
+ "%s%lu_%s", undo::s_log_prefix,
+ (ulong) space_id, s_log_ext);
return(DB_SUCCESS);
}
@@ -846,7 +828,7 @@ trx_purge_mark_undo_for_truncate(
/* Step-3: Iterate over all the rsegs of selected UNDO tablespace
and mark them temporarily unavailable for allocation.*/
for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) {
- if (trx_rseg_t* rseg = trx_sys->rseg_array[i]) {
+ if (trx_rseg_t* rseg = trx_sys.rseg_array[i]) {
ut_ad(rseg->is_persistent());
if (rseg->space == undo_trunc->get_marked_space_id()) {
@@ -870,17 +852,17 @@ void
trx_purge_cleanse_purge_queue(
undo::Truncate* undo_trunc)
{
- mutex_enter(&purge_sys->pq_mutex);
+ mutex_enter(&purge_sys.pq_mutex);
typedef std::vector<TrxUndoRsegs> purge_elem_list_t;
purge_elem_list_t purge_elem_list;
/* Remove rseg instances that are in the purge queue before we start
truncate of corresponding UNDO truncate. */
- while (!purge_sys->purge_queue.empty()) {
- purge_elem_list.push_back(purge_sys->purge_queue.top());
- purge_sys->purge_queue.pop();
+ while (!purge_sys.purge_queue.empty()) {
+ purge_elem_list.push_back(purge_sys.purge_queue.top());
+ purge_sys.purge_queue.pop();
}
- ut_ad(purge_sys->purge_queue.empty());
+ ut_ad(purge_sys.purge_queue.empty());
for (purge_elem_list_t::iterator it = purge_elem_list.begin();
it != purge_elem_list.end();
@@ -897,14 +879,11 @@ trx_purge_cleanse_purge_queue(
}
}
- if (it->size()) {
- /* size != 0 suggest that there exist other rsegs that
- needs processing so add this element to purge queue.
- Note: Other rseg could be non-redo rsegs. */
- purge_sys->purge_queue.push(*it);
+ if (!it->empty()) {
+ purge_sys.purge_queue.push(*it);
}
}
- mutex_exit(&purge_sys->pq_mutex);
+ mutex_exit(&purge_sys.pq_mutex);
}
/** Iterate over selected UNDO tablespace and check if all the rsegs
@@ -914,7 +893,7 @@ that resides in the tablespace are free.
static
void
trx_purge_initiate_truncate(
- purge_iter_t* limit,
+ const purge_sys_t::iterator& limit,
undo::Truncate* undo_trunc)
{
/* Step-1: Early check to findout if any of the the UNDO tablespace
@@ -962,7 +941,7 @@ trx_purge_initiate_truncate(
undo != NULL && all_free;
undo = UT_LIST_GET_NEXT(undo_list, undo)) {
- if (limit->trx_no < undo->trx_id) {
+ if (limit.trx_no() < undo->trx_id) {
all_free = false;
} else {
cached_undo_size += undo->size;
@@ -1025,17 +1004,17 @@ trx_purge_initiate_truncate(
return;
}
- if (purge_sys->rseg != NULL
- && purge_sys->rseg->last_page_no == FIL_NULL) {
- /* If purge_sys->rseg is pointing to rseg that was recently
+ if (purge_sys.rseg != NULL
+ && purge_sys.rseg->last_page_no == FIL_NULL) {
+ /* If purge_sys.rseg is pointing to rseg that was recently
truncated then move to next rseg element.
- Note: Ideally purge_sys->rseg should be NULL because purge
+ Note: Ideally purge_sys.rseg should be NULL because purge
should complete processing of all the records but there is
purge_batch_size that can force the purge loop to exit before
- all the records are purged and in this case purge_sys->rseg
+ all the records are purged and in this case purge_sys.rseg
could point to a valid rseg waiting for next purge cycle. */
- purge_sys->next_stored = false;
- purge_sys->rseg = NULL;
+ purge_sys.next_stored = false;
+ purge_sys.rseg = NULL;
}
DBUG_EXECUTE_IF("ib_undo_trunc_before_ddl_log_end",
@@ -1062,35 +1041,26 @@ trx_purge_initiate_truncate(
DBUG_SUICIDE(););
}
-/********************************************************************//**
+/**
Removes unnecessary history data from rollback segments. NOTE that when this
-function is called, the caller must not have any latches on undo log pages! */
-static
-void
-trx_purge_truncate_history(
-/*========================*/
- purge_iter_t* limit, /*!< in: truncate limit */
- const ReadView* view) /*!< in: purge view */
+function is called, the caller must not have any latches on undo log pages!
+*/
+static void trx_purge_truncate_history()
{
- ut_ad(trx_purge_check_limit());
-
- /* We play safe and set the truncate limit at most to the purge view
- low_limit number, though this is not necessary */
-
- if (limit->trx_no >= view->low_limit_no()) {
- limit->trx_no = view->low_limit_no();
- limit->undo_no = 0;
- limit->undo_rseg_space = ULINT_UNDEFINED;
+ ut_ad(purge_sys.head <= purge_sys.tail);
+ purge_sys_t::iterator& head = purge_sys.head.commit
+ ? purge_sys.head : purge_sys.tail;
+
+ if (head.trx_no() >= purge_sys.view.low_limit_no()) {
+ /* This is sometimes necessary. TODO: find out why. */
+ head.reset_trx_no(purge_sys.view.low_limit_no());
+ head.undo_no = 0;
}
- ut_ad(limit->trx_no <= purge_sys->view.low_limit_no());
-
for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) {
- trx_rseg_t* rseg = trx_sys->rseg_array[i];
-
- if (rseg != NULL) {
- ut_a(rseg->id == i);
- trx_purge_truncate_rseg_history(rseg, limit);
+ if (trx_rseg_t* rseg = trx_sys.rseg_array[i]) {
+ ut_ad(rseg->id == i);
+ trx_purge_truncate_rseg_history(*rseg, head);
}
}
@@ -1098,14 +1068,14 @@ trx_purge_truncate_history(
can (greedy approach). This will ensure when the server is idle we
try and truncate all the UNDO tablespaces. */
for (ulint i = srv_undo_tablespaces_active; i--; ) {
- trx_purge_mark_undo_for_truncate(&purge_sys->undo_trunc);
- trx_purge_initiate_truncate(limit, &purge_sys->undo_trunc);
+ trx_purge_mark_undo_for_truncate(&purge_sys.undo_trunc);
+ trx_purge_initiate_truncate(head, &purge_sys.undo_trunc);
}
}
/***********************************************************************//**
Updates the last not yet purged history log info in rseg when we have purged
-a whole undo log. Advances also purge_sys->purge_trx_no past the purged log. */
+a whole undo log. Advances also purge_sys.purge_trx_no past the purged log. */
static
void
trx_purge_rseg_get_next_history_log(
@@ -1124,10 +1094,9 @@ trx_purge_rseg_get_next_history_log(
ut_a(rseg->last_page_no != FIL_NULL);
- purge_sys->iter.trx_no = rseg->last_trx_no + 1;
- purge_sys->iter.undo_no = 0;
- purge_sys->iter.undo_rseg_space = ULINT_UNDEFINED;
- purge_sys->next_stored = false;
+ purge_sys.tail.commit = rseg->last_commit + 1;
+ purge_sys.tail.undo_no = 0;
+ purge_sys.next_stored = false;
mtr_start(&mtr);
@@ -1150,28 +1119,6 @@ trx_purge_rseg_get_next_history_log(
mutex_exit(&(rseg->mutex));
mtr_commit(&mtr);
-
- trx_sys_mutex_enter();
-
- /* Add debug code to track history list corruption reported
- on the MySQL mailing list on Nov 9, 2004. The fut0lst.cc
- file-based list was corrupt. The prev node pointer was
- FIL_NULL, even though the list length was over 8 million nodes!
- We assume that purge truncates the history list in large
- size pieces, and if we here reach the head of the list, the
- list cannot be longer than 2000 000 undo logs now. */
-
- if (trx_sys->rseg_history_len > 2000000) {
- ib::warn() << "Purge reached the head of the history"
- " list, but its length is still reported as "
- << trx_sys->rseg_history_len << "! Make"
- " a detailed bug report, and submit it to"
- " https://jira.mariadb.org/";
- ut_ad(0);
- }
-
- trx_sys_mutex_exit();
-
return;
}
@@ -1197,22 +1144,19 @@ trx_purge_rseg_get_next_history_log(
rseg->last_page_no = prev_log_addr.page;
rseg->last_offset = prev_log_addr.boffset;
- rseg->last_trx_no = trx_no;
+ rseg->set_last_trx_no(trx_no, purge != 0);
rseg->needs_purge = purge != 0;
- TrxUndoRsegs elem(rseg->last_trx_no);
- elem.push_back(rseg);
-
/* Purge can also produce events, however these are already ordered
in the rollback segment and any user generated event will be greater
than the events that Purge produces. ie. Purge can never produce
events from an empty rollback segment. */
- mutex_enter(&purge_sys->pq_mutex);
+ mutex_enter(&purge_sys.pq_mutex);
- purge_sys->purge_queue.push(elem);
+ purge_sys.purge_queue.push(*rseg);
- mutex_exit(&purge_sys->pq_mutex);
+ mutex_exit(&purge_sys.pq_mutex);
mutex_exit(&rseg->mutex);
}
@@ -1225,41 +1169,36 @@ trx_purge_read_undo_rec()
ulint offset;
ulint page_no;
ib_uint64_t undo_no;
- ulint undo_rseg_space;
- purge_sys->hdr_offset = purge_sys->rseg->last_offset;
- page_no = purge_sys->hdr_page_no = purge_sys->rseg->last_page_no;
+ purge_sys.hdr_offset = purge_sys.rseg->last_offset;
+ page_no = purge_sys.hdr_page_no = purge_sys.rseg->last_page_no;
- if (purge_sys->rseg->needs_purge) {
+ if (purge_sys.rseg->needs_purge) {
mtr_t mtr;
mtr.start();
if (trx_undo_rec_t* undo_rec = trx_undo_get_first_rec(
- purge_sys->rseg->space, purge_sys->hdr_page_no,
- purge_sys->hdr_offset, RW_S_LATCH, &mtr)) {
+ purge_sys.rseg->space, purge_sys.hdr_page_no,
+ purge_sys.hdr_offset, RW_S_LATCH, &mtr)) {
offset = page_offset(undo_rec);
undo_no = trx_undo_rec_get_undo_no(undo_rec);
- undo_rseg_space = purge_sys->rseg->space;
page_no = page_get_page_no(page_align(undo_rec));
} else {
offset = 0;
undo_no = 0;
- undo_rseg_space = ULINT_UNDEFINED;
}
mtr.commit();
} else {
offset = 0;
undo_no = 0;
- undo_rseg_space = ULINT_UNDEFINED;
}
- purge_sys->offset = offset;
- purge_sys->page_no = page_no;
- purge_sys->iter.undo_no = undo_no;
- purge_sys->iter.undo_rseg_space = undo_rseg_space;
+ purge_sys.offset = offset;
+ purge_sys.page_no = page_no;
+ purge_sys.tail.undo_no = undo_no;
- purge_sys->next_stored = true;
+ purge_sys.next_stored = true;
}
/***********************************************************************//**
@@ -1272,9 +1211,9 @@ void
trx_purge_choose_next_log(void)
/*===========================*/
{
- ut_ad(!purge_sys->next_stored);
+ ut_ad(!purge_sys.next_stored);
- if (purge_sys->rseg_iter.set_next()) {
+ if (purge_sys.rseg_iter.set_next()) {
trx_purge_read_undo_rec();
} else {
/* There is nothing to do yet. */
@@ -1303,19 +1242,19 @@ trx_purge_get_next_rec(
ulint space;
mtr_t mtr;
- ut_ad(purge_sys->next_stored);
- ut_ad(purge_sys->iter.trx_no < purge_sys->view.low_limit_no());
+ ut_ad(purge_sys.next_stored);
+ ut_ad(purge_sys.tail.trx_no() < purge_sys.view.low_limit_no());
- space = purge_sys->rseg->space;
- page_no = purge_sys->page_no;
- offset = purge_sys->offset;
+ space = purge_sys.rseg->space;
+ page_no = purge_sys.page_no;
+ offset = purge_sys.offset;
if (offset == 0) {
/* It is the dummy undo log record, which means that there is
no need to purge this undo log */
trx_purge_rseg_get_next_history_log(
- purge_sys->rseg, n_pages_handled);
+ purge_sys.rseg, n_pages_handled);
/* Look for the next undo log and record to purge */
@@ -1331,19 +1270,19 @@ trx_purge_get_next_rec(
rec = undo_page + offset;
- rec2 = trx_undo_page_get_next_rec(rec, purge_sys->hdr_page_no,
- purge_sys->hdr_offset);
+ rec2 = trx_undo_page_get_next_rec(rec, purge_sys.hdr_page_no,
+ purge_sys.hdr_offset);
if (rec2 == NULL) {
- rec2 = trx_undo_get_next_rec(rec, purge_sys->hdr_page_no,
- purge_sys->hdr_offset, &mtr);
+ rec2 = trx_undo_get_next_rec(rec, purge_sys.hdr_page_no,
+ purge_sys.hdr_offset, &mtr);
}
if (rec2 == NULL) {
mtr_commit(&mtr);
trx_purge_rseg_get_next_history_log(
- purge_sys->rseg, n_pages_handled);
+ purge_sys.rseg, n_pages_handled);
/* Look for the next undo log and record to purge */
@@ -1358,10 +1297,9 @@ trx_purge_get_next_rec(
} else {
page = page_align(rec2);
- purge_sys->offset = rec2 - page;
- purge_sys->page_no = page_get_page_no(page);
- purge_sys->iter.undo_no = trx_undo_rec_get_undo_no(rec2);
- purge_sys->iter.undo_rseg_space = space;
+ purge_sys.offset = rec2 - page;
+ purge_sys.page_no = page_get_page_no(page);
+ purge_sys.tail.undo_no = trx_undo_rec_get_undo_no(rec2);
if (undo_page != page) {
/* We advance to a new page of the undo log: */
@@ -1390,17 +1328,17 @@ trx_purge_fetch_next_rec(
handled */
mem_heap_t* heap) /*!< in: memory heap where copied */
{
- if (!purge_sys->next_stored) {
+ if (!purge_sys.next_stored) {
trx_purge_choose_next_log();
- if (!purge_sys->next_stored) {
+ if (!purge_sys.next_stored) {
DBUG_PRINT("ib_purge",
("no logs left in the history list"));
return(NULL);
}
}
- if (purge_sys->iter.trx_no >= purge_sys->view.low_limit_no()) {
+ if (purge_sys.tail.trx_no() >= purge_sys.view.low_limit_no()) {
return(NULL);
}
@@ -1412,8 +1350,8 @@ trx_purge_fetch_next_rec(
/* row_purge_record_func() will later set
ROLL_PTR_INSERT_FLAG for TRX_UNDO_INSERT_REC */
false,
- purge_sys->rseg->id,
- purge_sys->page_no, purge_sys->offset);
+ purge_sys.rseg->id,
+ purge_sys.page_no, purge_sys.offset);
/* The following call will advance the stored values of the
purge iterator. */
@@ -1421,28 +1359,24 @@ trx_purge_fetch_next_rec(
return(trx_purge_get_next_rec(n_pages_handled, heap));
}
-/*******************************************************************//**
-This function runs a purge batch.
+/** Run a purge batch.
+@param n_purge_threads number of purge threads
@return number of undo log pages handled in the batch */
static
ulint
-trx_purge_attach_undo_recs(
-/*=======================*/
- ulint n_purge_threads,/*!< in: number of purge threads */
- purge_sys_t* purge_sys, /*!< in/out: purge instance */
- ulint batch_size) /*!< in: no. of pages to purge */
+trx_purge_attach_undo_recs(ulint n_purge_threads)
{
que_thr_t* thr;
ulint i = 0;
ulint n_pages_handled = 0;
- ulint n_thrs = UT_LIST_GET_LEN(purge_sys->query->thrs);
+ ulint n_thrs = UT_LIST_GET_LEN(purge_sys.query->thrs);
ut_a(n_purge_threads > 0);
- purge_sys->limit = purge_sys->iter;
+ purge_sys.head = purge_sys.tail;
/* Debug code to validate some pre-requisites and reset done flag. */
- for (thr = UT_LIST_GET_FIRST(purge_sys->query->thrs);
+ for (thr = UT_LIST_GET_FIRST(purge_sys.query->thrs);
thr != NULL && i < n_purge_threads;
thr = UT_LIST_GET_NEXT(thrs, thr), ++i) {
@@ -1464,13 +1398,15 @@ trx_purge_attach_undo_recs(
/* Fetch and parse the UNDO records. The UNDO records are added
to a per purge node vector. */
- thr = UT_LIST_GET_FIRST(purge_sys->query->thrs);
+ thr = UT_LIST_GET_FIRST(purge_sys.query->thrs);
ut_a(n_thrs > 0 && thr != NULL);
- ut_ad(trx_purge_check_limit());
+ ut_ad(purge_sys.head <= purge_sys.tail);
i = 0;
+ const ulint batch_size = srv_purge_batch_size;
+
for (;;) {
purge_node_t* node;
trx_purge_rec_t* purge_rec;
@@ -1487,11 +1423,11 @@ trx_purge_attach_undo_recs(
/* Track the max {trx_id, undo_no} for truncating the
UNDO logs once we have purged the records. */
- if (trx_purge_check_limit()) {
- purge_sys->limit = purge_sys->iter;
+ if (purge_sys.head <= purge_sys.tail) {
+ purge_sys.head = purge_sys.tail;
}
- /* Fetch the next record, and advance the purge_sys->iter. */
+ /* Fetch the next record, and advance the purge_sys.tail. */
purge_rec->undo_rec = trx_purge_fetch_next_rec(
&purge_rec->roll_ptr, &n_pages_handled, node->heap);
@@ -1519,13 +1455,13 @@ trx_purge_attach_undo_recs(
thr = UT_LIST_GET_NEXT(thrs, thr);
if (!(++i % n_purge_threads)) {
- thr = UT_LIST_GET_FIRST(purge_sys->query->thrs);
+ thr = UT_LIST_GET_FIRST(purge_sys.query->thrs);
}
ut_a(thr != NULL);
}
- ut_ad(trx_purge_check_limit());
+ ut_ad(purge_sys.head <= purge_sys.tail);
return(n_pages_handled);
}
@@ -1545,12 +1481,12 @@ trx_purge_dml_delay(void)
/* If purge lag is set (ie. > 0) then calculate the new DML delay.
Note: we do a dirty read of the trx_sys_t data structure here,
- without holding trx_sys->mutex. */
+ without holding trx_sys.mutex. */
if (srv_max_purge_lag > 0) {
float ratio;
- ratio = float(trx_sys->rseg_history_len) / srv_max_purge_lag;
+ ratio = float(trx_sys.history_size()) / srv_max_purge_lag;
if (ratio > 1.0) {
/* If the history list length exceeds the
@@ -1570,18 +1506,15 @@ trx_purge_dml_delay(void)
return(delay);
}
-/*******************************************************************//**
-Wait for pending purge jobs to complete. */
+/** Wait for pending purge jobs to complete. */
static
void
-trx_purge_wait_for_workers_to_complete(
-/*===================================*/
- purge_sys_t* purge_sys) /*!< in: purge instance */
+trx_purge_wait_for_workers_to_complete()
{
- ulint n_submitted = purge_sys->n_submitted;
+ ulint n_submitted = purge_sys.n_submitted;
/* Ensure that the work queue empties out. */
- while ((ulint) my_atomic_loadlint(&purge_sys->n_completed) != n_submitted) {
+ while ((ulint) my_atomic_loadlint(&purge_sys.n_completed) != n_submitted) {
if (srv_get_task_queue_length() > 0) {
srv_release_threads(SRV_WORKER, 1);
@@ -1591,7 +1524,7 @@ trx_purge_wait_for_workers_to_complete(
}
/* None of the worker threads should be doing any work. */
- ut_a(purge_sys->n_submitted == purge_sys->n_completed);
+ ut_a(purge_sys.n_submitted == purge_sys.n_completed);
/* There should be no outstanding tasks as long
as the worker threads are active. */
@@ -1606,8 +1539,6 @@ trx_purge(
/*======*/
ulint n_purge_threads, /*!< in: number of purge tasks
to submit to the work queue */
- ulint batch_size, /*!< in: the maximum number of records
- to purge in one batch */
bool truncate) /*!< in: truncate history if true */
{
que_thr_t* thr = NULL;
@@ -1618,11 +1549,11 @@ trx_purge(
srv_dml_needed_delay = trx_purge_dml_delay();
/* The number of tasks submitted should be completed. */
- ut_a(purge_sys->n_submitted == purge_sys->n_completed);
+ ut_a(purge_sys.n_submitted == purge_sys.n_completed);
- rw_lock_x_lock(&purge_sys->latch);
- trx_sys->mvcc->clone_oldest_view(&purge_sys->view);
- rw_lock_x_unlock(&purge_sys->latch);
+ rw_lock_x_lock(&purge_sys.latch);
+ trx_sys.clone_oldest_view();
+ rw_lock_x_unlock(&purge_sys.latch);
#ifdef UNIV_DEBUG
if (srv_purge_view_update_only_debug) {
@@ -1631,8 +1562,7 @@ trx_purge(
#endif /* UNIV_DEBUG */
/* Fetch the UNDO recs that need to be purged. */
- n_pages_handled = trx_purge_attach_undo_recs(
- n_purge_threads, purge_sys, batch_size);
+ n_pages_handled = trx_purge_attach_undo_recs(n_purge_threads);
/* Do we do an asynchronous purge or not ? */
if (n_purge_threads > 1) {
@@ -1641,56 +1571,41 @@ trx_purge(
/* Submit the tasks to the work queue. */
for (i = 0; i < n_purge_threads - 1; ++i) {
thr = que_fork_scheduler_round_robin(
- purge_sys->query, thr);
+ purge_sys.query, thr);
ut_a(thr != NULL);
srv_que_task_enqueue_low(thr);
}
- thr = que_fork_scheduler_round_robin(purge_sys->query, thr);
+ thr = que_fork_scheduler_round_robin(purge_sys.query, thr);
ut_a(thr != NULL);
- purge_sys->n_submitted += n_purge_threads - 1;
+ purge_sys.n_submitted += n_purge_threads - 1;
goto run_synchronously;
/* Do it synchronously. */
} else {
- thr = que_fork_scheduler_round_robin(purge_sys->query, NULL);
+ thr = que_fork_scheduler_round_robin(purge_sys.query, NULL);
ut_ad(thr);
run_synchronously:
- ++purge_sys->n_submitted;
+ ++purge_sys.n_submitted;
que_run_threads(thr);
- my_atomic_addlint(
- &purge_sys->n_completed, 1);
+ my_atomic_addlint(&purge_sys.n_completed, 1);
if (n_purge_threads > 1) {
- trx_purge_wait_for_workers_to_complete(purge_sys);
+ trx_purge_wait_for_workers_to_complete();
}
}
- ut_a(purge_sys->n_submitted == purge_sys->n_completed);
-
-#ifdef UNIV_DEBUG
- rw_lock_x_lock(&purge_sys->latch);
- if (purge_sys->limit.trx_no == 0) {
- purge_sys->done = purge_sys->iter;
- } else {
- purge_sys->done = purge_sys->limit;
- }
- rw_lock_x_unlock(&purge_sys->latch);
-#endif /* UNIV_DEBUG */
+ ut_a(purge_sys.n_submitted == purge_sys.n_completed);
if (truncate) {
- trx_purge_truncate_history(
- purge_sys->limit.trx_no
- ? &purge_sys->limit
- : &purge_sys->iter,
- &purge_sys->view);
+ trx_purge_truncate_history();
}
MONITOR_INC_VALUE(MONITOR_PURGE_INVOKED, 1);
@@ -1708,11 +1623,11 @@ trx_purge_state(void)
{
purge_state_t state;
- rw_lock_x_lock(&purge_sys->latch);
+ rw_lock_x_lock(&purge_sys.latch);
- state = purge_sys->state;
+ state = purge_sys.state;
- rw_lock_x_unlock(&purge_sys->latch);
+ rw_lock_x_unlock(&purge_sys.latch);
return(state);
}
@@ -1723,52 +1638,48 @@ void
trx_purge_stop(void)
/*================*/
{
- ut_a(srv_n_purge_threads > 0);
-
- rw_lock_x_lock(&purge_sys->latch);
-
- const int64_t sig_count = os_event_reset(purge_sys->event);
- const purge_state_t state = purge_sys->state;
+ rw_lock_x_lock(&purge_sys.latch);
- ut_a(state == PURGE_STATE_RUN || state == PURGE_STATE_STOP);
-
- ++purge_sys->n_stop;
-
- if (state == PURGE_STATE_RUN) {
+ switch (purge_sys.state) {
+ case PURGE_STATE_INIT:
+ case PURGE_STATE_DISABLED:
+ ut_error;
+ case PURGE_STATE_EXIT:
+ /* Shutdown must have been initiated during
+ FLUSH TABLES FOR EXPORT. */
+ ut_ad(!srv_undo_sources);
+unlock:
+ rw_lock_x_unlock(&purge_sys.latch);
+ break;
+ case PURGE_STATE_STOP:
+ ut_ad(srv_n_purge_threads > 0);
+ ++purge_sys.n_stop;
+ purge_sys.state = PURGE_STATE_STOP;
+ if (!purge_sys.running) {
+ goto unlock;
+ }
+ ib::info() << "Waiting for purge to stop";
+ do {
+ rw_lock_x_unlock(&purge_sys.latch);
+ os_thread_sleep(10000);
+ rw_lock_x_lock(&purge_sys.latch);
+ } while (purge_sys.running);
+ goto unlock;
+ case PURGE_STATE_RUN:
+ ut_ad(srv_n_purge_threads > 0);
+ ++purge_sys.n_stop;
ib::info() << "Stopping purge";
/* We need to wakeup the purge thread in case it is suspended,
so that it can acknowledge the state change. */
+ const int64_t sig_count = os_event_reset(purge_sys.event);
+ purge_sys.state = PURGE_STATE_STOP;
srv_purge_wakeup();
- }
-
- purge_sys->state = PURGE_STATE_STOP;
-
- if (state != PURGE_STATE_STOP) {
- rw_lock_x_unlock(&purge_sys->latch);
+ rw_lock_x_unlock(&purge_sys.latch);
/* Wait for purge coordinator to signal that it
is suspended. */
- os_event_wait_low(purge_sys->event, sig_count);
- } else {
- bool once = true;
-
- /* Wait for purge to signal that it has actually stopped. */
- while (purge_sys->running) {
-
- if (once) {
- ib::info() << "Waiting for purge to stop";
- once = false;
- }
-
- rw_lock_x_unlock(&purge_sys->latch);
-
- os_thread_sleep(10000);
-
- rw_lock_x_lock(&purge_sys->latch);
- }
-
- rw_lock_x_unlock(&purge_sys->latch);
+ os_event_wait_low(purge_sys.event, sig_count);
}
MONITOR_INC_VALUE(MONITOR_PURGE_STOP_COUNT, 1);
@@ -1780,30 +1691,34 @@ void
trx_purge_run(void)
/*===============*/
{
- rw_lock_x_lock(&purge_sys->latch);
+ rw_lock_x_lock(&purge_sys.latch);
- switch (purge_sys->state) {
- case PURGE_STATE_INIT:
+ switch (purge_sys.state) {
case PURGE_STATE_EXIT:
+ /* Shutdown must have been initiated during
+ FLUSH TABLES FOR EXPORT. */
+ ut_ad(!srv_undo_sources);
+ break;
+ case PURGE_STATE_INIT:
case PURGE_STATE_DISABLED:
ut_error;
case PURGE_STATE_RUN:
- ut_a(!purge_sys->n_stop);
+ ut_a(!purge_sys.n_stop);
break;
case PURGE_STATE_STOP:
- ut_a(purge_sys->n_stop);
- if (--purge_sys->n_stop == 0) {
+ ut_a(purge_sys.n_stop);
+ if (--purge_sys.n_stop == 0) {
ib::info() << "Resuming purge";
- purge_sys->state = PURGE_STATE_RUN;
+ purge_sys.state = PURGE_STATE_RUN;
}
MONITOR_INC_VALUE(MONITOR_PURGE_RESUME_COUNT, 1);
}
- rw_lock_x_unlock(&purge_sys->latch);
+ rw_lock_x_unlock(&purge_sys.latch);
srv_purge_wakeup();
}
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index 7f9476832ba..f3f04ab5e1c 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -31,7 +31,6 @@ Created 3/26/1996 Heikki Tuuri
#include "mtr0log.h"
#include "dict0dict.h"
#include "ut0mem.h"
-#include "read0read.h"
#include "row0ext.h"
#include "row0upd.h"
#include "que0que.h"
@@ -65,47 +64,30 @@ trx_undof_page_add_undo_rec_log(
ulint new_free, /*!< in: end offset of the entry */
mtr_t* mtr) /*!< in: mtr */
{
- byte* log_ptr;
- const byte* log_end;
- ulint len;
-
- log_ptr = mlog_open(mtr, 11 + 13 + MLOG_BUF_MARGIN);
-
- if (log_ptr == NULL) {
-
- return;
- }
-
- log_end = &log_ptr[11 + 13 + MLOG_BUF_MARGIN];
- log_ptr = mlog_write_initial_log_record_fast(
- undo_page, MLOG_UNDO_INSERT, log_ptr, mtr);
- len = new_free - old_free - 4;
-
- mach_write_to_2(log_ptr, len);
- log_ptr += 2;
-
- if (log_ptr + len <= log_end) {
- memcpy(log_ptr, undo_page + old_free + 2, len);
- mlog_close(mtr, log_ptr + len);
- } else {
- mlog_close(mtr, log_ptr);
- mlog_catenate_string(mtr, undo_page + old_free + 2, len);
- }
+ ut_ad(old_free >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
+ ut_ad(new_free >= old_free);
+ ut_ad(new_free < UNIV_PAGE_SIZE);
+ ut_ad(mach_read_from_2(undo_page
+ + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE)
+ == new_free);
+ mlog_write_ulint(undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE,
+ new_free, MLOG_2BYTES, mtr);
+ mlog_log_string(undo_page + old_free, new_free - old_free, mtr);
}
-/***********************************************************//**
-Parses a redo log record of adding an undo log record.
-@return end of log record or NULL */
+/** Parse MLOG_UNDO_INSERT for crash-upgrade from MariaDB 10.2.
+@param[in] ptr log record
+@param[in] end_ptr end of log record buffer
+@param[in,out] page page or NULL
+@return end of log record
+@retval NULL if the log record is incomplete */
byte*
trx_undo_parse_add_undo_rec(
-/*========================*/
- byte* ptr, /*!< in: buffer */
- byte* end_ptr,/*!< in: buffer end */
- page_t* page) /*!< in: page or NULL */
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* page)
{
ulint len;
- byte* rec;
- ulint first_free;
if (end_ptr < ptr + 2) {
@@ -120,23 +102,20 @@ trx_undo_parse_add_undo_rec(
return(NULL);
}
- if (page == NULL) {
-
- return(ptr + len);
- }
-
- first_free = mach_read_from_2(page + TRX_UNDO_PAGE_HDR
- + TRX_UNDO_PAGE_FREE);
- rec = page + first_free;
+ if (page) {
+ ulint first_free = mach_read_from_2(page + TRX_UNDO_PAGE_HDR
+ + TRX_UNDO_PAGE_FREE);
+ byte* rec = page + first_free;
- mach_write_to_2(rec, first_free + 4 + len);
- mach_write_to_2(rec + 2 + len, first_free);
+ mach_write_to_2(rec, first_free + 4 + len);
+ mach_write_to_2(rec + 2 + len, first_free);
- mach_write_to_2(page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE,
- first_free + 4 + len);
- ut_memcpy(rec + 2, ptr, len);
+ mach_write_to_2(page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE,
+ first_free + 4 + len);
+ memcpy(rec + 2, ptr, len);
+ }
- return(ptr + len);
+ return(const_cast<byte*>(ptr + len));
}
/**********************************************************************//**
@@ -975,6 +954,7 @@ trx_undo_page_report_modify(
dict_index_get_sys_col_pos(
index, DATA_ROLL_PTR), &flen);
ut_ad(flen == DATA_ROLL_PTR_LEN);
+ ut_ad(memcmp(field, field_ref_zero, DATA_ROLL_PTR_LEN));
ptr += mach_u64_write_compressed(ptr, trx_read_roll_ptr(field));
@@ -1211,14 +1191,43 @@ trx_undo_page_report_modify(
const dict_col_t* col
= dict_table_get_nth_col(table, col_no);
- const char* col_name = dict_table_get_col_name(table,
- col_no);
if (!col->ord_part) {
continue;
}
- if (update) {
+ const ulint pos = dict_index_get_nth_col_pos(
+ index, col_no, NULL);
+ /* All non-virtual columns must be present in
+ the clustered index. */
+ ut_ad(pos != ULINT_UNDEFINED);
+
+ const bool is_ext = rec_offs_nth_extern(offsets, pos);
+ const spatial_status_t spatial_status = is_ext
+ ? dict_col_get_spatial_status(col)
+ : SPATIAL_NONE;
+
+ switch (spatial_status) {
+ case SPATIAL_UNKNOWN:
+ ut_ad(0);
+ /* fall through */
+ case SPATIAL_MIXED:
+ case SPATIAL_ONLY:
+ /* Externally stored spatially indexed
+ columns will be (redundantly) logged
+ again, because we did not write the
+ MBR yet, that is, the previous call to
+ trx_undo_page_report_modify_ext()
+ was with SPATIAL_UNKNOWN. */
+ break;
+ case SPATIAL_NONE:
+ if (!update) {
+ /* This is a DELETE operation. */
+ break;
+ }
+ /* Avoid redundantly logging indexed
+ columns that were updated. */
+
for (i = 0; i < update->n_fields; i++) {
const ulint field_no
= upd_get_nth_field(update, i)
@@ -1233,37 +1242,19 @@ trx_undo_page_report_modify(
}
if (true) {
- ulint pos;
- spatial_status_t spatial_status;
-
- spatial_status = SPATIAL_NONE;
-
/* Write field number to undo log */
if (trx_undo_left(undo_page, ptr) < 5 + 15) {
return(0);
}
- pos = dict_index_get_nth_col_pos(index,
- col_no,
- NULL);
- if (pos == ULINT_UNDEFINED) {
- ib::error() << "Column " << col_no
- << " name " << col_name
- << " not found from index " << index->name
- << " table. " << table->name.m_name
- << " Table has " << dict_table_get_n_cols(table)
- << " and index has " << dict_index_get_n_fields(index)
- << " fields.";
- }
-
ptr += mach_write_compressed(ptr, pos);
/* Save the old value of field */
field = rec_get_nth_cfield(
rec, index, offsets, pos, &flen);
- if (rec_offs_nth_extern(offsets, pos)) {
+ if (is_ext) {
const dict_col_t* col =
dict_index_get_nth_col(
index, pos);
@@ -1273,10 +1264,6 @@ trx_undo_page_report_modify(
ut_a(prefix_len < sizeof ext_buf);
- spatial_status =
- dict_col_get_spatial_status(
- col);
-
/* If there is a spatial index on it,
log its MBR */
if (spatial_status != SPATIAL_NONE) {
@@ -1675,6 +1662,7 @@ trx_undo_rec_get_partial_row(
used, as we do NOT copy the data in the
record! */
dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: updated columns */
dtuple_t** row, /*!< out, own: partial row */
ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
@@ -1705,6 +1693,16 @@ trx_undo_rec_get_partial_row(
dtuple_init_v_fld(*row);
+ for (const upd_field_t* uf = update->fields, * const ue
+ = update->fields + update->n_fields;
+ uf != ue; uf++) {
+ if (uf->old_v_val) {
+ continue;
+ }
+ ulint c = dict_index_get_nth_col(index, uf->field_no)->ind;
+ *dtuple_get_nth_field(*row, c) = uf->new_val;
+ }
+
end_ptr = ptr + mach_read_from_2(ptr);
ptr += 2;
@@ -1750,6 +1748,13 @@ trx_undo_rec_get_partial_row(
col = dict_index_get_nth_col(index, field_no);
col_no = dict_col_get_no(col);
dfield = dtuple_get_nth_field(*row, col_no);
+ ut_ad(dfield->type.mtype == DATA_MISSING
+ || dict_col_type_assert_equal(col,
+ &dfield->type));
+ ut_ad(dfield->type.mtype == DATA_MISSING
+ || dfield->len == len
+ || (len != UNIV_SQL_NULL
+ && len >= UNIV_EXTERN_STORAGE_FIELD));
dict_col_copy_type(
dict_table_get_nth_col(index->table, col_no),
dfield_get_type(dfield));
@@ -1821,49 +1826,122 @@ trx_undo_rec_get_partial_row(
return(const_cast<byte*>(ptr));
}
-/***********************************************************************//**
-Erases the unused undo log page end.
-@return TRUE if the page contained something, FALSE if it was empty */
-static MY_ATTRIBUTE((nonnull))
-ibool
-trx_undo_erase_page_end(
-/*====================*/
- page_t* undo_page, /*!< in/out: undo page whose end to erase */
- mtr_t* mtr) /*!< in/out: mini-transaction */
+/** Erase the unused undo log page end.
+@param[in,out] undo_page undo log page
+@return whether the page contained something */
+bool
+trx_undo_erase_page_end(page_t* undo_page)
{
ulint first_free;
first_free = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
+ TRX_UNDO_PAGE_FREE);
- memset(undo_page + first_free, 0xff,
+ memset(undo_page + first_free, 0,
(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END) - first_free);
- mlog_write_initial_log_record(undo_page, MLOG_UNDO_ERASE_END, mtr);
return(first_free != TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
}
-/***********************************************************//**
-Parses a redo log record of erasing of an undo page end.
-@return end of log record or NULL */
-byte*
-trx_undo_parse_erase_page_end(
-/*==========================*/
- byte* ptr, /*!< in: buffer */
- byte* end_ptr MY_ATTRIBUTE((unused)), /*!< in: buffer end */
- page_t* page, /*!< in: page or NULL */
- mtr_t* mtr) /*!< in: mtr or NULL */
+/** Report a RENAME TABLE operation.
+@param[in,out] trx transaction
+@param[in] table table that is being renamed
+@param[in,out] block undo page
+@param[in,out] mtr mini-transaction
+@return byte offset of the undo log record
+@retval 0 in case of failure */
+static
+ulint
+trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
+ buf_block_t* block, mtr_t* mtr)
{
- ut_ad(ptr != NULL);
- ut_ad(end_ptr != NULL);
+ byte* ptr_first_free = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
+ + block->frame;
+ ulint first_free = mach_read_from_2(ptr_first_free);
+ ut_ad(first_free >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
+ ut_ad(first_free <= UNIV_PAGE_SIZE);
+ byte* start = block->frame + first_free;
+ size_t len = strlen(table->name.m_name);
+ const size_t fixed = 2 + 1 + 11 + 11 + 2;
+ ut_ad(len <= NAME_LEN * 2 + 1);
+ /* The -10 is used in trx_undo_left() */
+ compile_time_assert((NAME_LEN * 1) * 2 + fixed
+ + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE
+ < UNIV_PAGE_SIZE_MIN - 10 - FIL_PAGE_DATA_END);
+
+ if (trx_undo_left(block->frame, start) < fixed + len) {
+ ut_ad(first_free > TRX_UNDO_PAGE_HDR
+ + TRX_UNDO_PAGE_HDR_SIZE);
+ return 0;
+ }
- if (page == NULL) {
+ byte* ptr = start + 2;
+ *ptr++ = TRX_UNDO_RENAME_TABLE;
+ ptr += mach_u64_write_much_compressed(ptr, trx->undo_no);
+ ptr += mach_u64_write_much_compressed(ptr, table->id);
+ memcpy(ptr, table->name.m_name, len);
+ ptr += len;
+ mach_write_to_2(ptr, first_free);
+ ptr += 2;
+ ulint offset = page_offset(ptr);
+ mach_write_to_2(start, offset);
+ mach_write_to_2(ptr_first_free, offset);
- return(ptr);
- }
+ trx_undof_page_add_undo_rec_log(block->frame, first_free, offset, mtr);
+ return first_free;
+}
- trx_undo_erase_page_end(page, mtr);
+/** Report a RENAME TABLE operation.
+@param[in,out] trx transaction
+@param[in] table table that is being renamed
+@return DB_SUCCESS or error code */
+dberr_t
+trx_undo_report_rename(trx_t* trx, const dict_table_t* table)
+{
+ ut_ad(!trx->read_only);
+ ut_ad(trx->id);
+ ut_ad(!table->is_temporary());
- return(ptr);
+ mtr_t mtr;
+ dberr_t err;
+ mtr.start();
+ mutex_enter(&trx->undo_mutex);
+ if (buf_block_t* block = trx_undo_assign(trx, &err, &mtr)) {
+ trx_undo_t* undo = trx->rsegs.m_redo.undo;
+ ut_ad(err == DB_SUCCESS);
+ ut_ad(undo);
+ for (ut_d(int loop_count = 0);;) {
+ ut_ad(++loop_count < 2);
+ ut_ad(undo->last_page_no == block->page.id.page_no());
+
+ if (ulint offset = trx_undo_page_report_rename(
+ trx, table, block, &mtr)) {
+ undo->withdraw_clock = buf_withdraw_clock;
+ undo->empty = FALSE;
+ undo->top_page_no = undo->last_page_no;
+ undo->top_offset = offset;
+ undo->top_undo_no = trx->undo_no++;
+ undo->guess_block = block;
+
+ trx->undo_rseg_space
+ = trx->rsegs.m_redo.rseg->space;
+ err = DB_SUCCESS;
+ break;
+ } else {
+ mtr.commit();
+ mtr.start();
+ block = trx_undo_add_page(trx, undo, &mtr);
+ if (!block) {
+ err = DB_OUT_OF_FILE_SPACE;
+ break;
+ }
+ }
+ }
+
+ mtr.commit();
+ }
+
+ mutex_exit(&trx->undo_mutex);
+ return err;
}
/***********************************************************************//**
@@ -1892,14 +1970,10 @@ trx_undo_report_row_operation(
marking, the record in the clustered
index; NULL if insert */
const ulint* offsets, /*!< in: rec_get_offsets(rec) */
- roll_ptr_t* roll_ptr) /*!< out: rollback pointer to the
- inserted undo log record,
- 0 if BTR_NO_UNDO_LOG
- flag was specified */
+ roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the
+ undo log record */
{
trx_t* trx;
- ulint page_no;
- buf_block_t* undo_block;
mtr_t mtr;
#ifdef UNIV_DEBUG
int loop_count = 0;
@@ -1919,7 +1993,7 @@ trx_undo_report_row_operation(
mtr.start();
trx_undo_t** pundo;
trx_rseg_t* rseg;
- const bool is_temp = dict_table_is_temporary(index->table);
+ const bool is_temp = index->table->is_temporary();
if (is_temp) {
mtr.set_log_mode(MTR_LOG_NO_REDO);
@@ -1929,42 +2003,24 @@ trx_undo_report_row_operation(
} else {
ut_ad(!trx->read_only);
ut_ad(trx->id);
- if (UNIV_LIKELY(!clust_entry || clust_entry->info_bits
- != REC_INFO_DEFAULT_ROW)) {
- /* Keep INFORMATION_SCHEMA.TABLES.UPDATE_TIME
- up-to-date for persistent tables outside
- instant ADD COLUMN. */
- trx->mod_tables.insert(index->table);
- } else {
- ut_ad(index->is_instant());
- }
-
pundo = &trx->rsegs.m_redo.undo;
rseg = trx->rsegs.m_redo.rseg;
}
mutex_enter(&trx->undo_mutex);
- dberr_t err = *pundo ? DB_SUCCESS : trx_undo_assign_undo(
- trx, rseg, pundo);
- trx_undo_t* undo = *pundo;
+ dberr_t err;
+ buf_block_t* undo_block = trx_undo_assign_low(trx, rseg, pundo,
+ &err, &mtr);
+ trx_undo_t* undo = *pundo;
- ut_ad((err == DB_SUCCESS) == (undo != NULL));
- if (undo == NULL) {
+ ut_ad((err == DB_SUCCESS) == (undo_block != NULL));
+ if (undo_block == NULL) {
goto err_exit;
}
- page_no = undo->last_page_no;
-
- undo_block = buf_page_get_gen(
- page_id_t(undo->space, page_no), univ_page_size, RW_X_LATCH,
- buf_pool_is_obsolete(undo->withdraw_clock)
- ? NULL : undo->guess_block, BUF_GET, __FILE__, __LINE__,
- &mtr, &err);
-
- buf_block_dbg_add_level(undo_block, SYNC_TRX_UNDO_PAGE);
+ ut_ad(undo != NULL);
do {
- ut_ad(page_no == undo_block->page.id.page_no());
page_t* undo_page = buf_block_get_frame(undo_block);
ulint offset = !rec
? trx_undo_page_report_insert(
@@ -1974,13 +2030,7 @@ trx_undo_report_row_operation(
cmpl_info, clust_entry, &mtr);
if (UNIV_UNLIKELY(offset == 0)) {
- /* The record did not fit on the page. We erase the
- end segment of the undo log page and write a log
- record of it: this is to ensure that in the debug
- version the replicate page constructed using the log
- records stays identical to the original page */
-
- if (!trx_undo_erase_page_end(undo_page, &mtr)) {
+ if (!trx_undo_erase_page_end(undo_page)) {
/* The record did not fit on an empty
undo page. Discard the freshly allocated
page and return an error. */
@@ -1994,8 +2044,8 @@ trx_undo_report_row_operation(
first, because it may be holding lower-level
latches, such as SYNC_FSP and SYNC_FSP_PAGE. */
- mtr_commit(&mtr);
- mtr.start(trx);
+ mtr.commit();
+ mtr.start();
if (is_temp) {
mtr.set_log_mode(MTR_LOG_NO_REDO);
}
@@ -2015,7 +2065,7 @@ trx_undo_report_row_operation(
mtr_commit(&mtr);
undo->empty = FALSE;
- undo->top_page_no = page_no;
+ undo->top_page_no = undo_block->page.id.page_no();
undo->top_offset = offset;
undo->top_undo_no = trx->undo_no++;
undo->guess_block = undo_block;
@@ -2024,24 +2074,44 @@ trx_undo_report_row_operation(
mutex_exit(&trx->undo_mutex);
+ if (!is_temp) {
+ const undo_no_t limit = undo->top_undo_no;
+ /* Determine if this is the first time
+ when this transaction modifies a
+ system-versioned column in this table. */
+ trx_mod_table_time_t& time
+ = trx->mod_tables.insert(
+ trx_mod_tables_t::value_type(
+ index->table, limit))
+ .first->second;
+ ut_ad(time.valid(limit));
+
+ if (!time.is_versioned()
+ && index->table->versioned_by_id()
+ && (!rec /* INSERT */
+ || !update /* DELETE */
+ || update->affects_versioned())) {
+ time.set_versioned(limit);
+ }
+ }
+
*roll_ptr = trx_undo_build_roll_ptr(
- !rec, rseg->id, page_no, offset);
+ !rec, rseg->id, undo->top_page_no, offset);
return(DB_SUCCESS);
}
- ut_ad(page_no == undo->last_page_no);
+ ut_ad(undo_block->page.id.page_no() == undo->last_page_no);
/* We have to extend the undo log by one page */
ut_ad(++loop_count < 2);
- mtr.start(trx);
+ mtr.start();
if (is_temp) {
mtr.set_log_mode(MTR_LOG_NO_REDO);
}
undo_block = trx_undo_add_page(trx, undo, &mtr);
- page_no = undo->last_page_no;
DBUG_EXECUTE_IF("ib_err_ins_undo_page_add_failure",
undo_block = NULL;);
@@ -2090,9 +2160,11 @@ trx_undo_get_undo_rec_low(
trx_undo_decode_roll_ptr(roll_ptr, &is_insert, &rseg_id, &page_no,
&offset);
+ ut_ad(page_no > FSP_FIRST_INODE_PAGE_NO);
+ ut_ad(offset >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
rseg = is_temp
- ? trx_sys->temp_rsegs[rseg_id]
- : trx_sys->rseg_array[rseg_id];
+ ? trx_sys.temp_rsegs[rseg_id]
+ : trx_sys.rseg_array[rseg_id];
ut_ad(is_temp == !rseg->is_persistent());
mtr_start(&mtr);
@@ -2132,14 +2204,14 @@ trx_undo_get_undo_rec(
{
bool missing_history;
- rw_lock_s_lock(&purge_sys->latch);
+ rw_lock_s_lock(&purge_sys.latch);
- missing_history = purge_sys->view.changes_visible(trx_id, name);
+ missing_history = purge_sys.view.changes_visible(trx_id, name);
if (!missing_history) {
*undo_rec = trx_undo_get_undo_rec_low(roll_ptr, is_temp, heap);
}
- rw_lock_s_unlock(&purge_sys->latch);
+ rw_lock_s_unlock(&purge_sys.latch);
return(missing_history);
}
@@ -2201,7 +2273,7 @@ trx_undo_prev_version_build(
bool dummy_extern;
byte* buf;
- ut_ad(!rw_lock_own(&purge_sys->latch, RW_LOCK_S));
+ ut_ad(!rw_lock_own(&purge_sys.latch, RW_LOCK_S));
ut_ad(mtr_memo_contains_page_flagged(index_mtr, index_rec,
MTR_MEMO_PAGE_S_FIX
| MTR_MEMO_PAGE_X_FIX));
@@ -2220,6 +2292,8 @@ trx_undo_prev_version_build(
const bool is_temp = dict_table_is_temporary(index->table);
rec_trx_id = row_get_rec_trx_id(rec, index, offsets);
+ ut_ad(!index->table->skip_alter_undo);
+
if (trx_undo_get_undo_rec(
roll_ptr, is_temp, heap, rec_trx_id, index->table->name,
&undo_rec)) {
@@ -2249,12 +2323,12 @@ trx_undo_prev_version_build(
&info_bits);
/* (a) If a clustered index record version is such that the
- trx id stamp in it is bigger than purge_sys->view, then the
+ trx id stamp in it is bigger than purge_sys.view, then the
BLOBs in that version are known to exist (the purge has not
progressed that far);
(b) if the version is the first version such that trx id in it
- is less than purge_sys->view, and it is not delete-marked,
+ is less than purge_sys.view, and it is not delete-marked,
then the BLOBs in that version are known to exist (the purge
cannot have purged the BLOBs referenced by that version
yet).
@@ -2293,19 +2367,19 @@ trx_undo_prev_version_build(
the BLOB. */
/* the row_upd_changes_disowned_external(update) call could be
- omitted, but the synchronization on purge_sys->latch is likely
+ omitted, but the synchronization on purge_sys.latch is likely
more expensive. */
if ((update->info_bits & REC_INFO_DELETED_FLAG)
&& row_upd_changes_disowned_external(update)) {
bool missing_extern;
- rw_lock_s_lock(&purge_sys->latch);
+ rw_lock_s_lock(&purge_sys.latch);
- missing_extern = purge_sys->view.changes_visible(
+ missing_extern = purge_sys.view.changes_visible(
trx_id, index->table->name);
- rw_lock_s_unlock(&purge_sys->latch);
+ rw_lock_s_unlock(&purge_sys.latch);
if (missing_extern) {
/* treat as a fresh insert, not to
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index 0d2d6beac90..bf73759a499 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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,8 +24,10 @@ Transaction rollback
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-#include "ha_prototypes.h"
+#include "my_config.h"
+#include <my_systemd.h>
+#include "ha_prototypes.h"
#include "trx0roll.h"
#include <mysql/service_wsrep.h>
@@ -35,7 +37,6 @@ Created 3/26/1996 Heikki Tuuri
#include "mach0data.h"
#include "pars0pars.h"
#include "que0que.h"
-#include "read0read.h"
#include "row0mysql.h"
#include "row0undo.h"
#include "srv0mon.h"
@@ -45,25 +46,17 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0sys.h"
#include "trx0trx.h"
#include "trx0undo.h"
-#include "usr0sess.h"
#include "ha_prototypes.h"
/** This many pages must be undone before a truncate is tried within
rollback */
static const ulint TRX_ROLL_TRUNC_THRESHOLD = 1;
-/** true if trx_rollback_or_clean_all_recovered() thread is active */
-bool trx_rollback_or_clean_is_active;
+/** true if trx_rollback_all_recovered() thread is active */
+bool trx_rollback_is_active;
/** In crash recovery, the current trx to be rolled back; NULL otherwise */
-static const trx_t* trx_roll_crash_recv_trx = NULL;
-
-/** In crash recovery we set this to the undo n:o of the current trx to be
-rolled back. Then we can print how many % the rollback has progressed. */
-static undo_no_t trx_roll_max_undo_no;
-
-/** Auxiliary variable which tells the previous progress % we printed */
-static ulint trx_roll_progress_printed_pct;
+const trx_t* trx_roll_crash_recv_trx;
/****************************************************************//**
Finishes a transaction rollback. */
@@ -126,6 +119,15 @@ trx_rollback_to_savepoint_low(
trx_rollback_finish(trx);
MONITOR_INC(MONITOR_TRX_ROLLBACK);
} else {
+ const undo_no_t limit = savept->least_undo_no;
+ for (trx_mod_tables_t::iterator i = trx->mod_tables.begin();
+ i != trx->mod_tables.end(); ) {
+ trx_mod_tables_t::iterator j = i++;
+ ut_ad(j->second.valid());
+ if (j->second.rollback(limit)) {
+ trx->mod_tables.erase(j);
+ }
+ }
trx->lock.que_state = TRX_QUE_RUNNING;
MONITOR_INC(MONITOR_TRX_ROLLBACK_SAVEPOINT);
}
@@ -194,7 +196,7 @@ dberr_t
trx_rollback_low(
trx_t* trx)
{
- /* We are reading trx->state without holding trx_sys->mutex
+ /* We are reading trx->state without holding trx_sys.mutex
here, because the rollback should be invoked for a running
active MySQL transaction (or recovered prepared transaction)
that is associated with the current thread. */
@@ -302,7 +304,7 @@ trx_rollback_last_sql_stat_for_mysql(
{
dberr_t err;
- /* We are reading trx->state without holding trx_sys->mutex
+ /* We are reading trx->state without holding trx_sys.mutex
here, because the statement rollback should be invoked for a
running active MySQL transaction that is associated with the
current thread. */
@@ -482,7 +484,7 @@ trx_rollback_to_savepoint_for_mysql(
{
trx_named_savept_t* savep;
- /* We are reading trx->state without holding trx_sys->mutex
+ /* We are reading trx->state without holding trx_sys.mutex
here, because the savepoint rollback should be invoked for a
running active MySQL transaction that is associated with the
current thread. */
@@ -634,9 +636,10 @@ trx_rollback_active(
que_thr_t* thr;
roll_node_t* roll_node;
dict_table_t* table;
- int64_t rows_to_undo;
- const char* unit = "";
ibool dictionary_locked = FALSE;
+ const trx_id_t trx_id = trx->id;
+
+ ut_ad(trx_id);
heap = mem_heap_create(512);
@@ -654,28 +657,8 @@ trx_rollback_active(
ut_a(thr == que_fork_start_command(fork));
- trx_sys_mutex_enter();
-
trx_roll_crash_recv_trx = trx;
- trx_roll_max_undo_no = trx->undo_no;
-
- trx_roll_progress_printed_pct = 0;
-
- rows_to_undo = trx_roll_max_undo_no;
-
- trx_sys_mutex_exit();
-
- if (rows_to_undo > 1000000000) {
- rows_to_undo = rows_to_undo / 1000000;
- unit = "M";
- }
-
- const trx_id_t trx_id = trx_get_id_for_print(trx);
-
- ib::info() << "Rolling back trx with id " << trx_id << ", "
- << rows_to_undo << unit << " rows to undo";
-
if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
row_mysql_lock_data_dictionary(trx);
dictionary_locked = TRUE;
@@ -686,6 +669,17 @@ trx_rollback_active(
que_run_threads(roll_node->undo_thr);
+ if (trx->error_state != DB_SUCCESS) {
+ ut_ad(trx->error_state == DB_INTERRUPTED);
+ ut_ad(!srv_is_being_started);
+ ut_ad(!srv_undo_sources);
+ ut_ad(srv_fast_shutdown);
+ ut_ad(!dictionary_locked);
+ que_graph_free(static_cast<que_t*>(
+ roll_node->undo_thr->common.parent));
+ goto func_exit;
+ }
+
trx_rollback_finish(thr_get_trx(roll_node->undo_thr));
/* Free the memory reserved by the undo graph */
@@ -717,145 +711,164 @@ trx_rollback_active(
}
}
+ ib::info() << "Rolled back recovered transaction " << trx_id;
+
+func_exit:
if (dictionary_locked) {
row_mysql_unlock_data_dictionary(trx);
}
- ib::info() << "Rollback of trx with id " << trx_id << " completed";
-
mem_heap_free(heap);
trx_roll_crash_recv_trx = NULL;
}
-/*******************************************************************//**
-Rollback or clean up any resurrected incomplete transactions. It assumes
-that the caller holds the trx_sys_t::mutex and it will release the
-lock if it does a clean up or rollback.
-@return TRUE if the transaction was cleaned up or rolled back
-and trx_sys->mutex was released. */
-static
-ibool
-trx_rollback_resurrected(
-/*=====================*/
- trx_t* trx, /*!< in: transaction to rollback or clean */
- ibool all) /*!< in: FALSE=roll back dictionary transactions;
- TRUE=roll back all non-PREPARED transactions */
-{
- ut_ad(trx_sys_mutex_own());
-
- /* The trx->is_recovered flag and trx->state are set
- atomically under the protection of the trx->mutex (and
- lock_sys->mutex) in lock_trx_release_locks(). We do not want
- to accidentally clean up a non-recovered transaction here. */
-
- trx_mutex_enter(trx);
- bool is_recovered = trx->is_recovered;
- trx_state_t state = trx->state;
- trx_mutex_exit(trx);
-
- if (!is_recovered) {
- return(FALSE);
- }
-
- switch (state) {
- case TRX_STATE_COMMITTED_IN_MEMORY:
- trx_sys_mutex_exit();
- ib::info() << "Cleaning up trx with id "
- << trx_get_id_for_print(trx);
- trx_cleanup_at_db_startup(trx);
- trx_free_resurrected(trx);
- return(TRUE);
- case TRX_STATE_ACTIVE:
- if (all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
- trx_sys_mutex_exit();
- trx_rollback_active(trx);
- trx_free_for_background(trx);
- return(TRUE);
- }
- return(FALSE);
- case TRX_STATE_PREPARED:
- return(FALSE);
- case TRX_STATE_NOT_STARTED:
- case TRX_STATE_FORCED_ROLLBACK:
- break;
- }
+struct trx_roll_count_callback_arg
+{
+ uint32_t n_trx;
+ uint64_t n_rows;
+ trx_roll_count_callback_arg(): n_trx(0), n_rows(0) {}
+};
- ut_error;
- return(FALSE);
-}
-/*******************************************************************//**
-Rollback or clean up any incomplete transactions which were
-encountered in crash recovery. If the transaction already was
-committed, then we clean up a possible insert undo log. If the
-transaction was not yet committed, then we roll it back. */
-void
-trx_rollback_or_clean_recovered(
-/*============================*/
- ibool all) /*!< in: FALSE=roll back dictionary transactions;
- TRUE=roll back all non-PREPARED transactions */
+static my_bool trx_roll_count_callback(rw_trx_hash_element_t *element,
+ trx_roll_count_callback_arg *arg)
{
- trx_t* trx;
+ mutex_enter(&element->mutex);
+ if (trx_t *trx= element->trx)
+ {
+ if (trx->is_recovered && trx_state_eq(trx, TRX_STATE_ACTIVE))
+ {
+ arg->n_trx++;
+ arg->n_rows+= trx->undo_no;
+ }
+ }
+ mutex_exit(&element->mutex);
+ return 0;
+}
- ut_a(srv_force_recovery < SRV_FORCE_NO_TRX_UNDO);
- if (trx_sys_get_n_rw_trx() == 0) {
+/** Report progress when rolling back a row of a recovered transaction.
+@return whether the rollback should be aborted due to pending shutdown */
+bool
+trx_roll_must_shutdown()
+{
+ const trx_t* trx = trx_roll_crash_recv_trx;
+ ut_ad(trx);
+ ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
+ ut_ad(trx->in_rollback);
- return;
+ if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE
+ && !srv_is_being_started
+ && !srv_undo_sources && srv_fast_shutdown) {
+ return true;
}
- if (all) {
- ib::info() << "Starting in background the rollback"
- " of recovered transactions";
+ ib_time_t time = ut_time();
+ mutex_enter(&recv_sys->mutex);
+
+ if (recv_sys->report(time)) {
+ trx_roll_count_callback_arg arg;
+
+ /* Get number of recovered active transactions and number of
+ rows they modified. Numbers must be accurate, because only this
+ thread is allowed to touch recovered transactions. */
+ trx_sys.rw_trx_hash.iterate_no_dups(
+ reinterpret_cast<my_hash_walk_action>
+ (trx_roll_count_callback), &arg);
+ ib::info() << "To roll back: " << arg.n_trx
+ << " transactions, " << arg.n_rows << " rows";
+ sd_notifyf(0, "STATUS=To roll back: " UINT32PF " transactions,"
+ " " UINT64PF " rows", arg.n_trx, arg.n_rows);
}
- /* Note: For XA recovered transactions, we rely on MySQL to
- do rollback. They will be in TRX_STATE_PREPARED state. If the server
- is shutdown and they are still lingering in trx_sys_t::trx_list
- then the shutdown will hang. */
-
- /* Loop over the transaction list as long as there are
- recovered transactions to clean up or recover. */
-
- do {
- trx_sys_mutex_enter();
-
- for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
- trx != NULL;
- trx = UT_LIST_GET_NEXT(trx_list, trx)) {
+ mutex_exit(&recv_sys->mutex);
+ return false;
+}
- assert_trx_in_rw_list(trx);
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE
- && srv_fast_shutdown != 0) {
- all = FALSE;
- break;
- }
+static my_bool trx_rollback_recovered_callback(rw_trx_hash_element_t *element,
+ trx_ut_list_t *trx_list)
+{
+ mutex_enter(&element->mutex);
+ if (trx_t *trx= element->trx)
+ {
+ mutex_enter(&trx->mutex);
+ if (trx->is_recovered && trx_state_eq(trx, TRX_STATE_ACTIVE))
+ UT_LIST_ADD_FIRST(*trx_list, trx);
+ mutex_exit(&trx->mutex);
+ }
+ mutex_exit(&element->mutex);
+ return 0;
+}
- /* If this function does a cleanup or rollback
- then it will release the trx_sys->mutex, therefore
- we need to reacquire it before retrying the loop. */
- if (trx_rollback_resurrected(trx, all)) {
+/**
+ Rollback any incomplete transactions which were encountered in crash recovery.
- trx_sys_mutex_enter();
+ If the transaction already was committed, then we clean up a possible insert
+ undo log. If the transaction was not yet committed, then we roll it back.
- break;
- }
- }
+ Note: For XA recovered transactions, we rely on MySQL to
+ do rollback. They will be in TRX_STATE_PREPARED state. If the server
+ is shutdown and they are still lingering in trx_sys_t::trx_list
+ then the shutdown will hang.
- trx_sys_mutex_exit();
+ @param[in] all true=roll back all recovered active transactions;
+ false=roll back any incomplete dictionary transaction
+*/
- } while (trx != NULL);
+void trx_rollback_recovered(bool all)
+{
+ trx_ut_list_t trx_list;
+
+ ut_a(srv_force_recovery < SRV_FORCE_NO_TRX_UNDO);
+ UT_LIST_INIT(trx_list, &trx_t::mysql_trx_list);
+
+ /*
+ Collect list of recovered ACTIVE transaction ids first. Once collected, no
+ other thread is allowed to modify or remove these transactions from
+ rw_trx_hash.
+ */
+ trx_sys.rw_trx_hash.iterate_no_dups(reinterpret_cast<my_hash_walk_action>
+ (trx_rollback_recovered_callback),
+ &trx_list);
+
+ while (trx_t *trx= UT_LIST_GET_FIRST(trx_list))
+ {
+ UT_LIST_REMOVE(trx_list, trx);
+
+#ifdef UNIV_DEBUG
+ ut_ad(trx);
+ trx_mutex_enter(trx);
+ ut_ad(trx->is_recovered && trx_state_eq(trx, TRX_STATE_ACTIVE));
+ trx_mutex_exit(trx);
+#endif
- if (all) {
- ib::info() << "Rollback of non-prepared transactions"
- " completed";
- }
+ if (!srv_is_being_started && !srv_undo_sources && srv_fast_shutdown)
+ goto discard;
+
+ if (all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE)
+ {
+ trx_rollback_active(trx);
+ if (trx->error_state != DB_SUCCESS)
+ {
+ ut_ad(trx->error_state == DB_INTERRUPTED);
+ trx->error_state= DB_SUCCESS;
+ ut_ad(!srv_undo_sources);
+ ut_ad(srv_fast_shutdown);
+discard:
+ trx_sys.deregister_rw(trx);
+ trx_free_at_shutdown(trx);
+ }
+ else
+ trx_free_for_background(trx);
+ }
+ }
}
+
/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
@@ -865,11 +878,7 @@ Note: this is done in a background thread.
@return a dummy parameter */
extern "C"
os_thread_ret_t
-DECLARE_THREAD(trx_rollback_or_clean_all_recovered)(
-/*================================================*/
- void* arg MY_ATTRIBUTE((unused)))
- /*!< in: a dummy parameter required by
- os_thread_create */
+DECLARE_THREAD(trx_rollback_all_recovered)(void*)
{
my_thread_init();
ut_ad(!srv_read_only_mode);
@@ -878,9 +887,15 @@ DECLARE_THREAD(trx_rollback_or_clean_all_recovered)(
pfs_register_thread(trx_rollback_clean_thread_key);
#endif /* UNIV_PFS_THREAD */
- trx_rollback_or_clean_recovered(TRUE);
+ if (trx_sys.rw_trx_hash.size()) {
+ ib::info() << "Starting in background the rollback of"
+ " recovered transactions";
+ trx_rollback_recovered(true);
+ ib::info() << "Rollback of non-prepared transactions"
+ " completed";
+ }
- trx_rollback_or_clean_is_active = false;
+ trx_rollback_is_active = false;
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
@@ -1037,38 +1052,21 @@ trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap)
this record can only be present in the main undo log. */
ut_ad(undo == update);
/* fall through */
+ case TRX_UNDO_RENAME_TABLE:
+ ut_ad(undo == insert || undo == update);
+ /* fall through */
case TRX_UNDO_INSERT_REC:
ut_ad(undo == insert || undo == update || undo == temp);
*roll_ptr |= 1ULL << ROLL_PTR_INSERT_FLAG_POS;
break;
default:
ut_ad(undo == update || undo == temp);
+ break;
}
ut_ad(trx_roll_check_undo_rec_ordering(
undo_no, undo->rseg->space, trx));
- /* We print rollback progress info if we are in a crash recovery
- and the transaction has at least 1000 row operations to undo. */
-
- if (trx == trx_roll_crash_recv_trx && trx_roll_max_undo_no > 1000) {
-
- ulint progress_pct = 100 - (ulint)
- ((undo_no * 100) / trx_roll_max_undo_no);
- if (progress_pct != trx_roll_progress_printed_pct) {
- if (trx_roll_progress_printed_pct == 0) {
- fprintf(stderr,
- "\nInnoDB: Progress in percents:"
- " %lu", (ulong) progress_pct);
- } else {
- fprintf(stderr,
- " %lu", (ulong) progress_pct);
- }
- fflush(stderr);
- trx_roll_progress_printed_pct = progress_pct;
- }
- }
-
trx->undo_no = undo_no;
trx->undo_rseg_space = undo->rseg->space;
mutex_exit(&trx->undo_mutex);
@@ -1154,10 +1152,8 @@ trx_rollback_finish(
/*================*/
trx_t* trx) /*!< in: transaction */
{
- trx_commit(trx);
-
trx->mod_tables.clear();
-
+ trx_commit(trx);
trx->lock.que_state = TRX_QUE_RUNNING;
}
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index ad7bcdf2173..b9ca2481681 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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,30 +34,237 @@ Created 3/26/1996 Heikki Tuuri
#include <algorithm>
+#ifdef WITH_WSREP
+
+#ifdef UNIV_DEBUG
+static long long trx_sys_cur_xid_seqno = -1;
+static unsigned char trx_sys_cur_xid_uuid[16];
+
+/** Read WSREP XID seqno */
+static inline long long read_wsrep_xid_seqno(const XID* xid)
+{
+ long long seqno;
+ memcpy(&seqno, xid->data + 24, sizeof(long long));
+ return seqno;
+}
+
+/** Read WSREP XID UUID */
+static inline void read_wsrep_xid_uuid(const XID* xid, unsigned char* buf)
+{
+ memcpy(buf, xid->data + 8, 16);
+}
+
+#endif /* UNIV_DEBUG */
+
+/** Update the WSREP XID information in rollback segment header.
+@param[in,out] rseg_header rollback segment header
+@param[in] xid WSREP XID
+@param[in,out] mtr mini-transaction */
+void
+trx_rseg_update_wsrep_checkpoint(
+ trx_rsegf_t* rseg_header,
+ const XID* xid,
+ mtr_t* mtr)
+{
+ ut_ad(xid->formatID == 1);
+
+#ifdef UNIV_DEBUG
+ /* Check that seqno is monotonically increasing */
+ unsigned char xid_uuid[16];
+ long long xid_seqno = read_wsrep_xid_seqno(xid);
+ read_wsrep_xid_uuid(xid, xid_uuid);
+
+ if (!memcmp(xid_uuid, trx_sys_cur_xid_uuid, 8)) {
+ ut_ad(xid_seqno > trx_sys_cur_xid_seqno);
+ trx_sys_cur_xid_seqno = xid_seqno;
+ } else {
+ memcpy(trx_sys_cur_xid_uuid, xid_uuid, 16);
+ }
+ trx_sys_cur_xid_seqno = xid_seqno;
+#endif /* UNIV_DEBUG */
+
+ mlog_write_ulint(TRX_RSEG_WSREP_XID_FORMAT + rseg_header,
+ uint32_t(xid->formatID),
+ MLOG_4BYTES, mtr);
+
+ mlog_write_ulint(TRX_RSEG_WSREP_XID_GTRID_LEN + rseg_header,
+ uint32_t(xid->gtrid_length),
+ MLOG_4BYTES, mtr);
+
+ mlog_write_ulint(TRX_RSEG_WSREP_XID_BQUAL_LEN + rseg_header,
+ uint32_t(xid->bqual_length),
+ MLOG_4BYTES, mtr);
+
+ mlog_write_string(TRX_RSEG_WSREP_XID_DATA + rseg_header,
+ reinterpret_cast<const byte*>(xid->data),
+ XIDDATASIZE, mtr);
+}
+
+/** Update WSREP checkpoint XID in first rollback segment header.
+@param[in] xid WSREP XID */
+void trx_rseg_update_wsrep_checkpoint(const XID* xid)
+{
+ mtr_t mtr;
+ mtr.start();
+
+ const trx_rseg_t* rseg = trx_sys.rseg_array[0];
+
+ trx_rsegf_t* rseg_header = trx_rsegf_get(rseg->space, rseg->page_no,
+ &mtr);
+ if (UNIV_UNLIKELY(mach_read_from_4(rseg_header + TRX_RSEG_FORMAT))) {
+ trx_rseg_format_upgrade(rseg_header, &mtr);
+ }
+
+ mlog_write_ull(rseg_header + TRX_RSEG_MAX_TRX_ID,
+ trx_sys.get_max_trx_id(), &mtr);
+ trx_rseg_update_wsrep_checkpoint(rseg_header, xid, &mtr);
+ mtr.commit();
+}
+
+/** Read the WSREP XID information in rollback segment header.
+@param[in] rseg_header Rollback segment header
+@param[out] xid Transaction XID
+@return whether the WSREP XID was present */
+bool trx_rseg_read_wsrep_checkpoint(const trx_rsegf_t* rseg_header, XID& xid)
+{
+ xid.formatID = (int)mach_read_from_4(
+ TRX_RSEG_WSREP_XID_FORMAT + rseg_header);
+
+ if (xid.formatID == 0) {
+ memset(&xid, 0, sizeof(xid));
+ long long seqno= -1;
+ memcpy(xid.data + 24, &seqno, sizeof(long long));
+ xid.formatID = -1;
+ return false;
+ }
+
+ xid.gtrid_length = (int)mach_read_from_4(
+ TRX_RSEG_WSREP_XID_GTRID_LEN + rseg_header);
+
+ xid.bqual_length = (int)mach_read_from_4(
+ TRX_RSEG_WSREP_XID_BQUAL_LEN + rseg_header);
+
+ memcpy(xid.data, TRX_RSEG_WSREP_XID_DATA + rseg_header, XIDDATASIZE);
+
+ return true;
+}
+
+/** Read the WSREP XID from the TRX_SYS page (in case of upgrade).
+@param[in] page TRX_SYS page
+@param[out] xid WSREP XID (if present)
+@return whether the WSREP XID is present */
+static bool trx_rseg_init_wsrep_xid(const page_t* page, XID& xid)
+{
+ if (mach_read_from_4(TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ + TRX_SYS_WSREP_XID_MAGIC_N_FLD
+ + page)
+ != TRX_SYS_WSREP_XID_MAGIC_N) {
+ return false;
+ }
+
+ xid.formatID = (int)mach_read_from_4(
+ TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ + TRX_SYS_WSREP_XID_FORMAT + page);
+ xid.gtrid_length = (int)mach_read_from_4(
+ TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ + TRX_SYS_WSREP_XID_GTRID_LEN + page);
+ xid.bqual_length = (int)mach_read_from_4(
+ TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ + TRX_SYS_WSREP_XID_BQUAL_LEN + page);
+ memcpy(xid.data,
+ TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ + TRX_SYS_WSREP_XID_DATA + page, XIDDATASIZE);
+ return true;
+}
+
+/** Recover the latest WSREP checkpoint XID.
+@param[out] xid WSREP XID
+@return whether the WSREP XID was found */
+bool trx_rseg_read_wsrep_checkpoint(XID& xid)
+{
+ mtr_t mtr;
+ trx_id_t max_id = 0;
+ bool found = false;
+
+ for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS;
+ rseg_id++, mtr.commit()) {
+ mtr.start();
+ const buf_block_t* sys = trx_sysf_get(&mtr, false);
+ if (rseg_id == 0) {
+ found = trx_rseg_init_wsrep_xid(sys->frame, xid);
+ }
+
+ const uint32_t page_no = trx_sysf_rseg_get_page_no(
+ sys, rseg_id);
+
+ if (page_no == FIL_NULL) {
+ continue;
+ }
+
+ const trx_rsegf_t* rseg_header = trx_rsegf_get_new(
+ trx_sysf_rseg_get_space(sys, rseg_id), page_no, &mtr);
+
+ if (mach_read_from_4(rseg_header + TRX_RSEG_FORMAT)) {
+ continue;
+ }
+
+ trx_id_t id = mach_read_from_8(rseg_header
+ + TRX_RSEG_MAX_TRX_ID);
+
+ if (id < max_id) {
+ continue;
+ }
+
+ max_id = id;
+ found = trx_rseg_read_wsrep_checkpoint(rseg_header, xid)
+ || found;
+ }
+
+ return found;
+}
+#endif /* WITH_WSREP */
+
+/** Upgrade a rollback segment header page to MariaDB 10.3 format.
+@param[in,out] rseg_header rollback segment header page
+@param[in,out] mtr mini-transaction */
+void trx_rseg_format_upgrade(trx_rsegf_t* rseg_header, mtr_t* mtr)
+{
+ ut_ad(page_offset(rseg_header) == TRX_RSEG);
+ byte* rseg_format = TRX_RSEG_FORMAT + rseg_header;
+ mlog_write_ulint(rseg_format, 0, MLOG_4BYTES, mtr);
+ /* Clear also possible garbage at the end of the page. Old
+ InnoDB versions did not initialize unused parts of pages. */
+ byte* b = rseg_header + TRX_RSEG_MAX_TRX_ID + 8;
+ ulint len = UNIV_PAGE_SIZE
+ - (FIL_PAGE_DATA_END
+ + TRX_RSEG + TRX_RSEG_MAX_TRX_ID + 8);
+ memset(b, 0, len);
+ mlog_log_string(b, len, mtr);
+}
+
/** Creates a rollback segment header.
This function is called only when a new rollback segment is created in
the database.
@param[in] space space id
-@param[in] max_size max size in pages
-@param[in] rseg_slot_no rseg id == slot number in trx sys
+@param[in] rseg_id rollback segment identifier
+@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
@param[in,out] mtr mini-transaction
@return page number of the created segment, FIL_NULL if fail */
ulint
trx_rseg_header_create(
ulint space,
- ulint max_size,
- ulint rseg_slot_no,
+ ulint rseg_id,
+ buf_block_t* sys_header,
mtr_t* mtr)
{
ulint page_no;
trx_rsegf_t* rsegf;
- trx_sysf_t* sys_header;
- ulint i;
buf_block_t* block;
ut_ad(mtr);
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
MTR_MEMO_X_LOCK));
+ ut_ad(!sys_header == (space == SRV_TMP_SPACE_ID));
/* Allocate a new file segment for the rollback segment */
block = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
@@ -75,9 +282,7 @@ trx_rseg_header_create(
/* Get the rollback segment file page */
rsegf = trx_rsegf_get_new(space, page_no, mtr);
- /* Initialize max size field */
- mlog_write_ulint(rsegf + TRX_RSEG_MAX_SIZE, max_size,
- MLOG_4BYTES, mtr);
+ mlog_write_ulint(rsegf + TRX_RSEG_FORMAT, 0, MLOG_4BYTES, mtr);
/* Initialize the history list */
@@ -85,21 +290,25 @@ trx_rseg_header_create(
flst_init(rsegf + TRX_RSEG_HISTORY, mtr);
/* Reset the undo log slots */
- for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
+ for (ulint i = 0; i < TRX_RSEG_N_SLOTS; i++) {
trx_rsegf_set_nth_undo(rsegf, i, FIL_NULL, mtr);
}
- if (space != SRV_TMP_SPACE_ID) {
+ if (sys_header) {
/* Add the rollback segment info to the free slot in
the trx system header */
- sys_header = trx_sysf_get(mtr);
-
- trx_sysf_rseg_set_space(sys_header, rseg_slot_no, space, mtr);
-
- trx_sysf_rseg_set_page_no(
- sys_header, rseg_slot_no, page_no, mtr);
+ mlog_write_ulint(TRX_SYS + TRX_SYS_RSEGS
+ + TRX_SYS_RSEG_SPACE
+ + rseg_id * TRX_SYS_RSEG_SLOT_SIZE
+ + sys_header->frame,
+ space, MLOG_4BYTES, mtr);
+ mlog_write_ulint(TRX_SYS + TRX_SYS_RSEGS
+ + TRX_SYS_RSEG_PAGE_NO
+ + rseg_id * TRX_SYS_RSEG_SLOT_SIZE
+ + sys_header->frame,
+ page_no, MLOG_4BYTES, mtr);
}
return(page_no);
@@ -128,7 +337,7 @@ trx_rseg_mem_free(trx_rseg_t* rseg)
MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED);
- trx_undo_mem_free(undo);
+ ut_free(undo);
}
ut_free(rseg);
@@ -149,6 +358,7 @@ trx_rseg_mem_create(ulint id, ulint space, ulint page_no)
rseg->space = space;
rseg->page_no = page_no;
rseg->last_page_no = FIL_NULL;
+ rseg->curr_size = 1;
mutex_create(rseg->is_persistent()
? LATCH_ID_REDO_RSEG : LATCH_ID_NOREDO_RSEG,
@@ -161,92 +371,193 @@ trx_rseg_mem_create(ulint id, ulint space, ulint page_no)
return(rseg);
}
+/** Read the undo log lists.
+@param[in,out] rseg rollback segment
+@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 trx_rsegf_t* rseg_header)
+{
+ ut_ad(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN);
+
+ ulint size = 0;
+
+ for (ulint i = 0; i < TRX_RSEG_N_SLOTS; i++) {
+ ulint page_no = trx_rsegf_get_nth_undo(rseg_header, i);
+ if (page_no != FIL_NULL) {
+ size += trx_undo_mem_create_at_db_start(
+ rseg, i, page_no, max_trx_id);
+ MONITOR_INC(MONITOR_NUM_UNDO_SLOT_USED);
+ }
+ }
+
+ return(size);
+}
+
/** Restore the state of a persistent rollback segment.
-@param[in,out] rseg persistent rollback segment
-@param[in,out] mtr mini-transaction */
+@param[in,out] rseg persistent rollback segment
+@param[in,out] max_trx_id maximum observed transaction identifier
+@param[in,out] max_rseg_trx_id maximum observed TRX_RSEG_MAX_TRX_ID
+@param[in,out] mtr mini-transaction */
static
void
-trx_rseg_mem_restore(trx_rseg_t* rseg, mtr_t* mtr)
+trx_rseg_mem_restore(
+ trx_rseg_t* rseg,
+ trx_id_t& max_trx_id,
+ trx_id_t& max_rseg_trx_id,
+ mtr_t* mtr)
{
- ulint len;
- fil_addr_t node_addr;
- trx_rsegf_t* rseg_header;
- trx_ulogf_t* undo_log_hdr;
- ulint sum_of_undo_sizes;
+ trx_rsegf_t* rseg_header = trx_rsegf_get_new(
+ rseg->space, rseg->page_no, mtr);
- rseg_header = trx_rsegf_get_new(rseg->space, rseg->page_no, mtr);
+ if (mach_read_from_4(rseg_header + TRX_RSEG_FORMAT) == 0) {
+ trx_id_t id = mach_read_from_8(rseg_header
+ + TRX_RSEG_MAX_TRX_ID);
- rseg->max_size = mtr_read_ulint(
- rseg_header + TRX_RSEG_MAX_SIZE, MLOG_4BYTES, mtr);
+ if (id > max_trx_id) {
+ max_trx_id = id;
+ }
- /* Initialize the undo log lists according to the rseg header */
+ if (id > max_rseg_trx_id) {
+ max_rseg_trx_id = id;
- sum_of_undo_sizes = trx_undo_lists_init(rseg);
+ if (rseg_header[TRX_RSEG_BINLOG_NAME]) {
+ memcpy(trx_sys.recovered_binlog_filename,
+ rseg_header + TRX_RSEG_BINLOG_NAME,
+ TRX_RSEG_BINLOG_NAME_LEN);
+ trx_sys.recovered_binlog_offset = mach_read_from_8(
+ rseg_header
+ + TRX_RSEG_BINLOG_OFFSET);
+ }
- rseg->curr_size = mtr_read_ulint(
- rseg_header + TRX_RSEG_HISTORY_SIZE, MLOG_4BYTES, mtr)
- + 1 + sum_of_undo_sizes;
+#ifdef WITH_WSREP
+ trx_rseg_read_wsrep_checkpoint(
+ rseg_header, trx_sys.recovered_wsrep_xid);
+#endif
+ }
+ }
+
+ if (srv_operation == SRV_OPERATION_RESTORE) {
+ /* mariabackup --prepare only deals with
+ the redo log and the data files, not with
+ transactions or the data dictionary. */
+ return;
+ }
- len = flst_get_len(rseg_header + TRX_RSEG_HISTORY);
+ /* Initialize the undo log lists according to the rseg header */
- if (len > 0) {
- my_atomic_addlint(&trx_sys->rseg_history_len, len);
+ rseg->curr_size = mach_read_from_4(rseg_header + TRX_RSEG_HISTORY_SIZE)
+ + 1 + trx_undo_lists_init(rseg, max_trx_id, rseg_header);
- node_addr = trx_purge_get_log_from_hist(
+ if (ulint len = flst_get_len(rseg_header + TRX_RSEG_HISTORY)) {
+ trx_sys.history_add(int32(len));
+
+ fil_addr_t node_addr = trx_purge_get_log_from_hist(
flst_get_last(rseg_header + TRX_RSEG_HISTORY, mtr));
rseg->last_page_no = node_addr.page;
rseg->last_offset = node_addr.boffset;
- undo_log_hdr = trx_undo_page_get(
+ const trx_ulogf_t* undo_log_hdr = trx_undo_page_get(
page_id_t(rseg->space, node_addr.page), mtr)
+ node_addr.boffset;
- rseg->last_trx_no = mach_read_from_8(
- undo_log_hdr + TRX_UNDO_TRX_NO);
+ trx_id_t id = mach_read_from_8(undo_log_hdr + TRX_UNDO_TRX_ID);
+ if (id > max_trx_id) {
+ max_trx_id = id;
+ }
+ id = mach_read_from_8(undo_log_hdr + TRX_UNDO_TRX_NO);
+ if (id > max_trx_id) {
+ max_trx_id = id;
+ }
unsigned purge = mach_read_from_2(
undo_log_hdr + TRX_UNDO_NEEDS_PURGE);
ut_ad(purge <= 1);
+ rseg->set_last_trx_no(id, purge != 0);
rseg->needs_purge = purge != 0;
- TrxUndoRsegs elem(rseg->last_trx_no);
- elem.push_back(rseg);
-
if (rseg->last_page_no != FIL_NULL) {
/* There is no need to cover this operation by the purge
mutex because we are still bootstrapping. */
-
- purge_sys->purge_queue.push(elem);
+ purge_sys.purge_queue.push(*rseg);
}
}
}
+/** Read binlog metadata from the TRX_SYS page, in case we are upgrading
+from MySQL or a MariaDB version older than 10.3.5. */
+static void trx_rseg_init_binlog_info(const page_t* page)
+{
+ if (mach_read_from_4(TRX_SYS + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
+ + page)
+ == TRX_SYS_MYSQL_LOG_MAGIC_N) {
+ memcpy(trx_sys.recovered_binlog_filename,
+ TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME
+ + TRX_SYS + page, TRX_SYS_MYSQL_LOG_NAME_LEN);
+ trx_sys.recovered_binlog_offset = mach_read_from_8(
+ TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_OFFSET
+ + TRX_SYS + page);
+ }
+
+#ifdef WITH_WSREP
+ trx_rseg_init_wsrep_xid(page, trx_sys.recovered_wsrep_xid);
+#endif
+}
+
/** Initialize the rollback segments in memory at database startup. */
void
trx_rseg_array_init()
{
- mtr_t mtr;
-
- for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) {
+ trx_id_t max_trx_id = 0, max_rseg_trx_id = 0;
+
+ *trx_sys.recovered_binlog_filename = '\0';
+ trx_sys.recovered_binlog_offset = -1;
+#ifdef WITH_WSREP
+ memset(&trx_sys.recovered_wsrep_xid, 0,
+ sizeof trx_sys.recovered_wsrep_xid);
+ trx_sys.recovered_wsrep_xid.formatID = -1;
+#endif
+
+ for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
+ mtr_t mtr;
mtr.start();
- trx_sysf_t* sys_header = trx_sysf_get(&mtr);
- ulint page_no = trx_sysf_rseg_get_page_no(
- sys_header, i, &mtr);
+ if (const buf_block_t* sys = trx_sysf_get(&mtr, false)) {
+ if (rseg_id == 0) {
+ /* In case this is an upgrade from
+ before MariaDB 10.3.5, fetch the base
+ information from the TRX_SYS page. */
+ max_trx_id = mach_read_from_8(
+ TRX_SYS + TRX_SYS_TRX_ID_STORE
+ + sys->frame);
+ trx_rseg_init_binlog_info(sys->frame);
+ }
- if (page_no != FIL_NULL) {
- trx_rseg_t* rseg = trx_rseg_mem_create(
- i,
- trx_sysf_rseg_get_space(sys_header, i, &mtr),
- page_no);
- ut_ad(rseg->is_persistent());
- ut_ad(!trx_sys->rseg_array[rseg->id]);
- trx_sys->rseg_array[rseg->id] = rseg;
- trx_rseg_mem_restore(rseg, &mtr);
+ const uint32_t page_no = trx_sysf_rseg_get_page_no(
+ sys, rseg_id);
+ if (page_no != FIL_NULL) {
+ trx_rseg_t* rseg = trx_rseg_mem_create(
+ rseg_id, trx_sysf_rseg_get_space(
+ sys, rseg_id),
+ page_no);
+ ut_ad(rseg->is_persistent());
+ ut_ad(rseg->id == rseg_id);
+ ut_ad(!trx_sys.rseg_array[rseg_id]);
+ trx_sys.rseg_array[rseg_id] = rseg;
+ trx_rseg_mem_restore(
+ rseg, max_trx_id, max_rseg_trx_id,
+ &mtr);
+ }
}
mtr.commit();
}
+
+ trx_sys.init_max_trx_id(max_trx_id + 1);
}
/** Create a persistent rollback segment.
@@ -262,30 +573,28 @@ trx_rseg_create(ulint space_id)
mtr.start();
/* To obey the latching order, acquire the file space
- x-latch before the trx_sys->mutex. */
+ x-latch before the trx_sys.mutex. */
#ifdef UNIV_DEBUG
const fil_space_t* space =
#endif /* UNIV_DEBUG */
mtr_x_lock_space(space_id, &mtr);
ut_ad(space->purpose == FIL_TYPE_TABLESPACE);
- ulint slot_no = trx_sysf_rseg_find_free(&mtr);
- ulint page_no = slot_no == ULINT_UNDEFINED
- ? FIL_NULL
- : trx_rseg_header_create(space_id, ULINT_MAX, slot_no, &mtr);
-
- if (page_no != FIL_NULL) {
- trx_sysf_t* sys_header = trx_sysf_get(&mtr);
-
- ulint id = trx_sysf_rseg_get_space(
- sys_header, slot_no, &mtr);
- ut_a(id == space_id);
-
- rseg = trx_rseg_mem_create(slot_no, space_id, page_no);
- ut_ad(rseg->is_persistent());
- ut_ad(!trx_sys->rseg_array[rseg->id]);
- trx_sys->rseg_array[rseg->id] = rseg;
- trx_rseg_mem_restore(rseg, &mtr);
+ if (buf_block_t* sys_header = trx_sysf_get(&mtr)) {
+ ulint rseg_id = trx_sys_rseg_find_free(sys_header);
+ ulint page_no = rseg_id == ULINT_UNDEFINED
+ ? FIL_NULL
+ : trx_rseg_header_create(space_id, rseg_id, sys_header,
+ &mtr);
+ if (page_no != FIL_NULL) {
+ ut_ad(trx_sysf_rseg_get_space(sys_header, rseg_id)
+ == space_id);
+ rseg = trx_rseg_mem_create(rseg_id, space_id, page_no);
+ ut_ad(rseg->id == rseg_id);
+ ut_ad(rseg->is_persistent());
+ ut_ad(!trx_sys.rseg_array[rseg->id]);
+ trx_sys.rseg_array[rseg->id] = rseg;
+ }
}
mtr.commit();
@@ -309,13 +618,12 @@ trx_temp_rseg_create()
ut_ad(space->purpose == FIL_TYPE_TEMPORARY);
ulint page_no = trx_rseg_header_create(
- SRV_TMP_SPACE_ID, ULINT_MAX, i, &mtr);
+ SRV_TMP_SPACE_ID, i, NULL, &mtr);
trx_rseg_t* rseg = trx_rseg_mem_create(
i, SRV_TMP_SPACE_ID, page_no);
ut_ad(!rseg->is_persistent());
- ut_ad(!trx_sys->temp_rsegs[i]);
- trx_sys->temp_rsegs[i] = rseg;
- trx_rseg_mem_restore(rseg, &mtr);
+ ut_ad(!trx_sys.temp_rsegs[i]);
+ trx_sys.temp_rsegs[i] = rseg;
mtr.commit();
}
}
@@ -332,54 +640,70 @@ trx_rseg_get_n_undo_tablespaces(
ulint* space_ids) /*!< out: array of space ids of
UNDO tablespaces */
{
- ulint i;
- mtr_t mtr;
- trx_sysf_t* sys_header;
- ulint n_undo_tablespaces = 0;
-
- mtr_start(&mtr);
+ mtr_t mtr;
+ mtr.start();
- sys_header = trx_sysf_get(&mtr);
+ buf_block_t* sys_header = trx_sysf_get(&mtr, false);
+ if (!sys_header) {
+ mtr.commit();
+ return 0;
+ }
- for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
- ulint page_no;
- ulint space;
+ ulint* end = space_ids;
- page_no = trx_sysf_rseg_get_page_no(sys_header, i, &mtr);
+ for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
+ uint32_t page_no = trx_sysf_rseg_get_page_no(sys_header,
+ rseg_id);
if (page_no == FIL_NULL) {
continue;
}
- space = trx_sysf_rseg_get_space(sys_header, i, &mtr);
-
- if (space != 0) {
- ulint j;
- ibool found = FALSE;
-
- for (j = 0; j < n_undo_tablespaces; ++j) {
- if (space_ids[j] == space) {
- found = TRUE;
- break;
- }
- }
-
- if (!found) {
- ut_a(n_undo_tablespaces <= i);
- space_ids[n_undo_tablespaces++] = space;
+ if (ulint space = trx_sysf_rseg_get_space(sys_header,
+ rseg_id)) {
+ if (std::find(space_ids, end, space) == end) {
+ *end++ = space;
}
}
}
- mtr_commit(&mtr);
+ mtr.commit();
- ut_a(n_undo_tablespaces <= TRX_SYS_N_RSEGS);
+ ut_a(end - space_ids <= TRX_SYS_N_RSEGS);
+ *end = ULINT_UNDEFINED;
- space_ids[n_undo_tablespaces] = ULINT_UNDEFINED;
+ std::sort(space_ids, end);
- if (n_undo_tablespaces > 0) {
- std::sort(space_ids, space_ids + n_undo_tablespaces);
+ return ulint(end - space_ids);
+}
+
+/** Update the offset information about the end of the binlog entry
+which corresponds to the transaction just being committed.
+In a replication slave, this updates the master binlog position
+up to which replication has proceeded.
+@param[in,out] rseg_header rollback segment header
+@param[in] trx committing transaction
+@param[in,out] mtr mini-transaction */
+void
+trx_rseg_update_binlog_offset(byte* rseg_header, const trx_t* trx, mtr_t* mtr)
+{
+ DBUG_LOG("trx", "trx_mysql_binlog_offset: " << trx->mysql_log_offset);
+
+ const size_t len = strlen(trx->mysql_log_file_name) + 1;
+
+ ut_ad(len > 1);
+
+ if (UNIV_UNLIKELY(len > TRX_RSEG_BINLOG_NAME_LEN)) {
+ return;
}
- return(n_undo_tablespaces);
+ mlog_write_ull(rseg_header + TRX_RSEG_BINLOG_OFFSET,
+ trx->mysql_log_offset, mtr);
+ byte* p = rseg_header + TRX_RSEG_BINLOG_NAME;
+ const byte* binlog_name = reinterpret_cast<const byte*>
+ (trx->mysql_log_file_name);
+
+ if (memcmp(binlog_name, p, len)) {
+ mlog_write_string(p, binlog_name, len, mtr);
+ }
}
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index a332f6047d1..13ebe27f539 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -42,13 +42,12 @@ Created 3/26/1996 Heikki Tuuri
#include "log0log.h"
#include "log0recv.h"
#include "os0file.h"
-#include "read0read.h"
#include "fsp0sysspace.h"
#include <mysql/service_wsrep.h>
/** The transaction system */
-trx_sys_t* trx_sys;
+trx_sys_t trx_sys;
/** Check whether transaction id is valid.
@param[in] id transaction id to check
@@ -58,7 +57,7 @@ ReadView::check_trx_id_sanity(
trx_id_t id,
const table_name_t& name)
{
- if (id >= trx_sys->max_trx_id) {
+ if (id >= trx_sys.get_max_trx_id()) {
ib::warn() << "A transaction id"
<< " in a record of table "
@@ -89,245 +88,32 @@ ReadView::check_trx_id_sanity(
uint trx_rseg_n_slots_debug = 0;
#endif
-/*****************************************************************//**
-Writes the value of max_trx_id to the file based trx system header. */
-void
-trx_sys_flush_max_trx_id(void)
-/*==========================*/
-{
- mtr_t mtr;
- trx_sysf_t* sys_header;
-
-#ifndef WITH_WSREP
- /* wsrep_fake_trx_id violates this assert
- Copied from trx_sys_get_new_trx_id
- */
- ut_ad(trx_sys_mutex_own());
-#endif /* WITH_WSREP */
-
- if (!srv_read_only_mode) {
- mtr_start(&mtr);
-
- sys_header = trx_sysf_get(&mtr);
-
- mlog_write_ull(
- sys_header + TRX_SYS_TRX_ID_STORE,
- trx_sys->max_trx_id, &mtr);
-
- mtr_commit(&mtr);
- }
-}
-
-/*****************************************************************//**
-Updates the offset information about the end of the MySQL binlog entry
-which corresponds to the transaction just being committed. In a MySQL
-replication slave updates the latest master binlog position up to which
-replication has proceeded. */
-void
-trx_sys_update_mysql_binlog_offset(
-/*===============================*/
- const char* file_name,/*!< in: MySQL log file name */
- int64_t offset, /*!< in: position in that log file */
- trx_sysf_t* sys_header, /*!< in: trx sys header */
- mtr_t* mtr) /*!< in: mtr */
-{
- DBUG_PRINT("InnoDB",("trx_mysql_binlog_offset: %lld", (longlong) offset));
-
- const size_t len = strlen(file_name) + 1;
-
- if (len > TRX_SYS_MYSQL_LOG_NAME_LEN) {
-
- /* We cannot fit the name to the 512 bytes we have reserved */
-
- return;
- }
-
- if (mach_read_from_4(TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
- + TRX_SYS_MYSQL_LOG_INFO + sys_header)
- != TRX_SYS_MYSQL_LOG_MAGIC_N) {
-
- mlog_write_ulint(TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
- + TRX_SYS_MYSQL_LOG_INFO + sys_header,
- TRX_SYS_MYSQL_LOG_MAGIC_N,
- MLOG_4BYTES, mtr);
- }
-
- if (memcmp(file_name, TRX_SYS_MYSQL_LOG_NAME + TRX_SYS_MYSQL_LOG_INFO
- + sys_header, len)) {
- mlog_write_string(TRX_SYS_MYSQL_LOG_NAME
- + TRX_SYS_MYSQL_LOG_INFO
- + sys_header,
- reinterpret_cast<const byte*>(file_name),
- len, mtr);
- }
-
- mlog_write_ull(TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_OFFSET
- + sys_header, offset, mtr);
-}
-
/** Display the MySQL binlog offset info if it is present in the trx
system header. */
void
trx_sys_print_mysql_binlog_offset()
{
- mtr_t mtr;
-
- mtr.start();
-
- const trx_sysf_t* sys_header = trx_sysf_get(&mtr);
-
- if (mach_read_from_4(TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD + sys_header)
- == TRX_SYS_MYSQL_LOG_MAGIC_N) {
- ib::info() << "Last binlog file '"
- << TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME
- + sys_header
- << "', position "
- << mach_read_from_8(TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET
- + sys_header);
- }
-
- mtr.commit();
-}
-
-#ifdef WITH_WSREP
-
-#ifdef UNIV_DEBUG
-static long long trx_sys_cur_xid_seqno = -1;
-static unsigned char trx_sys_cur_xid_uuid[16];
-
-/** Read WSREP XID seqno */
-static inline long long read_wsrep_xid_seqno(const XID* xid)
-{
- long long seqno;
- memcpy(&seqno, xid->data + 24, sizeof(long long));
- return seqno;
-}
-
-/** Read WSREP XID UUID */
-static inline void read_wsrep_xid_uuid(const XID* xid, unsigned char* buf)
-{
- memcpy(buf, xid->data + 8, 16);
-}
-
-#endif /* UNIV_DEBUG */
-
-/** Update WSREP XID info in sys_header of TRX_SYS_PAGE_NO = 5.
-@param[in] xid Transaction XID
-@param[in,out] sys_header sys_header
-@param[in] mtr minitransaction */
-UNIV_INTERN
-void
-trx_sys_update_wsrep_checkpoint(
- const XID* xid,
- trx_sysf_t* sys_header,
- mtr_t* mtr)
-{
- ut_ad(xid->formatID == 1);
- ut_ad(wsrep_is_wsrep_xid(xid));
-
- if (mach_read_from_4(sys_header + TRX_SYS_WSREP_XID_INFO
- + TRX_SYS_WSREP_XID_MAGIC_N_FLD)
- != TRX_SYS_WSREP_XID_MAGIC_N) {
- mlog_write_ulint(sys_header + TRX_SYS_WSREP_XID_INFO
- + TRX_SYS_WSREP_XID_MAGIC_N_FLD,
- TRX_SYS_WSREP_XID_MAGIC_N,
- MLOG_4BYTES, mtr);
-#ifdef UNIV_DEBUG
- } else {
- /* Check that seqno is monotonically increasing */
- unsigned char xid_uuid[16];
- long long xid_seqno = read_wsrep_xid_seqno(xid);
- read_wsrep_xid_uuid(xid, xid_uuid);
-
- if (!memcmp(xid_uuid, trx_sys_cur_xid_uuid, 8)) {
- ut_ad(xid_seqno > trx_sys_cur_xid_seqno);
- trx_sys_cur_xid_seqno = xid_seqno;
- } else {
- memcpy(trx_sys_cur_xid_uuid, xid_uuid, 16);
- }
-
- trx_sys_cur_xid_seqno = xid_seqno;
-#endif /* UNIV_DEBUG */
- }
-
- mlog_write_ulint(sys_header + TRX_SYS_WSREP_XID_INFO
- + TRX_SYS_WSREP_XID_FORMAT,
- (int)xid->formatID,
- MLOG_4BYTES, mtr);
- mlog_write_ulint(sys_header + TRX_SYS_WSREP_XID_INFO
- + TRX_SYS_WSREP_XID_GTRID_LEN,
- (int)xid->gtrid_length,
- MLOG_4BYTES, mtr);
- mlog_write_ulint(sys_header + TRX_SYS_WSREP_XID_INFO
- + TRX_SYS_WSREP_XID_BQUAL_LEN,
- (int)xid->bqual_length,
- MLOG_4BYTES, mtr);
- mlog_write_string(sys_header + TRX_SYS_WSREP_XID_INFO
- + TRX_SYS_WSREP_XID_DATA,
- (const unsigned char*) xid->data,
- XIDDATASIZE, mtr);
-}
-
-/** Read WSREP checkpoint XID from sys header.
-@param[out] xid WSREP XID
-@return whether the checkpoint was present */
-UNIV_INTERN
-bool
-trx_sys_read_wsrep_checkpoint(XID* xid)
-{
- trx_sysf_t* sys_header;
- mtr_t mtr;
- ulint magic;
-
- ut_ad(xid);
-
- mtr_start(&mtr);
-
- sys_header = trx_sysf_get(&mtr);
-
- if ((magic = mach_read_from_4(sys_header + TRX_SYS_WSREP_XID_INFO
- + TRX_SYS_WSREP_XID_MAGIC_N_FLD))
- != TRX_SYS_WSREP_XID_MAGIC_N) {
- memset(xid, 0, sizeof(*xid));
- long long seqno= -1;
- memcpy(xid->data + 24, &seqno, sizeof(long long));
- xid->formatID = -1;
- mtr_commit(&mtr);
- return false;
+ if (!*trx_sys.recovered_binlog_filename) {
+ return;
}
- xid->formatID = (int)mach_read_from_4(
- sys_header
- + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_FORMAT);
- xid->gtrid_length = (int)mach_read_from_4(
- sys_header
- + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_GTRID_LEN);
- xid->bqual_length = (int)mach_read_from_4(
- sys_header
- + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_BQUAL_LEN);
- ut_memcpy(xid->data,
- sys_header + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_DATA,
- XIDDATASIZE);
-
- mtr_commit(&mtr);
- return true;
+ ib::info() << "Last binlog file '"
+ << trx_sys.recovered_binlog_filename
+ << "', position "
+ << trx_sys.recovered_binlog_offset;
}
-#endif /* WITH_WSREP */
-
-/** @return an unallocated rollback segment slot in the TRX_SYS header
+/** Find an available rollback segment.
+@param[in] sys_header
+@return an unallocated rollback segment slot in the TRX_SYS header
@retval ULINT_UNDEFINED if not found */
ulint
-trx_sysf_rseg_find_free(mtr_t* mtr)
+trx_sys_rseg_find_free(const buf_block_t* sys_header)
{
- trx_sysf_t* sys_header = trx_sysf_get(mtr);
-
- for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) {
- if (trx_sysf_rseg_get_page_no(sys_header, i, mtr)
+ for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
+ if (trx_sysf_rseg_get_page_no(sys_header, rseg_id)
== FIL_NULL) {
- return(i);
+ return rseg_id;
}
}
@@ -342,13 +128,14 @@ trx_sysf_get_n_rseg_slots()
mtr_t mtr;
mtr.start();
- trx_sysf_t* sys_header = trx_sysf_get(&mtr);
srv_available_undo_logs = 0;
-
- for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) {
- srv_available_undo_logs
- += trx_sysf_rseg_get_page_no(sys_header, i, &mtr)
- != FIL_NULL;
+ if (const buf_block_t* sys_header = trx_sysf_get(&mtr, false)) {
+ for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
+ srv_available_undo_logs
+ += trx_sysf_rseg_get_page_no(sys_header,
+ rseg_id)
+ != FIL_NULL;
+ }
}
mtr.commit();
@@ -363,7 +150,6 @@ trx_sysf_create(
/*============*/
mtr_t* mtr) /*!< in: mtr */
{
- trx_sysf_t* sys_header;
ulint slot_no;
buf_block_t* block;
page_t* page;
@@ -397,15 +183,10 @@ trx_sysf_create(
mlog_write_ulint(page + TRX_SYS_DOUBLEWRITE
+ TRX_SYS_DOUBLEWRITE_MAGIC, 0, MLOG_4BYTES, mtr);
- sys_header = trx_sysf_get(mtr);
-
- /* Start counting transaction ids from number 1 up */
- mach_write_to_8(sys_header + TRX_SYS_TRX_ID_STORE, 1);
-
/* Reset the rollback segment slots. Old versions of InnoDB
(before MySQL 5.5) define TRX_SYS_N_RSEGS as 256 and expect
that the whole array is initialized. */
- ptr = TRX_SYS_RSEGS + sys_header;
+ ptr = TRX_SYS + TRX_SYS_RSEGS + page;
compile_time_assert(256 >= TRX_SYS_N_RSEGS);
memset(ptr, 0xff, 256 * TRX_SYS_RSEG_SLOT_SIZE);
ptr += 256 * TRX_SYS_RSEG_SLOT_SIZE;
@@ -414,111 +195,30 @@ trx_sysf_create(
/* Initialize all of the page. This part used to be uninitialized. */
memset(ptr, 0, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page - ptr);
- mlog_log_string(sys_header, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END
- + page - sys_header, mtr);
+ mlog_log_string(TRX_SYS + page, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END
+ - TRX_SYS, mtr);
/* Create the first rollback segment in the SYSTEM tablespace */
- slot_no = trx_sysf_rseg_find_free(mtr);
- page_no = trx_rseg_header_create(TRX_SYS_SPACE,
- ULINT_MAX, slot_no, mtr);
+ slot_no = trx_sys_rseg_find_free(block);
+ page_no = trx_rseg_header_create(TRX_SYS_SPACE, slot_no, block, mtr);
ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
ut_a(page_no == FSP_FIRST_RSEG_PAGE_NO);
}
-/** Initialize the transaction system main-memory data structures. */
+/** Create the instance */
void
-trx_sys_init_at_db_start()
+trx_sys_t::create()
{
- trx_sysf_t* sys_header;
- ib_uint64_t rows_to_undo = 0;
- const char* unit = "";
-
- /* VERY important: after the database is started, max_trx_id value is
- divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the 'if' in
- trx_sys_get_new_trx_id will evaluate to TRUE when the function
- is first time called, and the value for trx id will be written
- to the disk-based header! Thus trx id values will not overlap when
- the database is repeatedly started! */
-
- mtr_t mtr;
- mtr.start();
-
- sys_header = trx_sysf_get(&mtr);
-
- trx_sys->max_trx_id = 2 * TRX_SYS_TRX_ID_WRITE_MARGIN
- + ut_uint64_align_up(mach_read_from_8(sys_header
- + TRX_SYS_TRX_ID_STORE),
- TRX_SYS_TRX_ID_WRITE_MARGIN);
-
- mtr.commit();
- ut_d(trx_sys->rw_max_trx_id = trx_sys->max_trx_id);
-
- trx_dummy_sess = sess_open();
-
- trx_lists_init_at_db_start();
-
- /* This mutex is not strictly required, it is here only to satisfy
- the debug code (assertions). We are still running in single threaded
- bootstrap mode. */
-
- trx_sys_mutex_enter();
-
- if (UT_LIST_GET_LEN(trx_sys->rw_trx_list) > 0) {
- const trx_t* trx;
-
- for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
- trx != NULL;
- trx = UT_LIST_GET_NEXT(trx_list, trx)) {
-
- ut_ad(trx->is_recovered);
- assert_trx_in_rw_list(trx);
-
- if (trx_state_eq(trx, TRX_STATE_ACTIVE)) {
- rows_to_undo += trx->undo_no;
- }
- }
-
- if (rows_to_undo > 1000000000) {
- unit = "M";
- rows_to_undo = rows_to_undo / 1000000;
- }
-
- ib::info() << UT_LIST_GET_LEN(trx_sys->rw_trx_list)
- << " transaction(s) which must be rolled back or"
- " cleaned up in total " << rows_to_undo << unit
- << " row operations to undo";
-
- ib::info() << "Trx id counter is " << trx_sys->max_trx_id;
- }
-
- trx_sys_mutex_exit();
-
- trx_sys->mvcc->clone_oldest_view(&purge_sys->view);
-}
-
-/*****************************************************************//**
-Creates the trx_sys instance and initializes purge_queue and mutex. */
-void
-trx_sys_create(void)
-/*================*/
-{
- ut_ad(trx_sys == NULL);
-
- trx_sys = static_cast<trx_sys_t*>(ut_zalloc_nokey(sizeof(*trx_sys)));
-
- mutex_create(LATCH_ID_TRX_SYS, &trx_sys->mutex);
-
- UT_LIST_INIT(trx_sys->serialisation_list, &trx_t::no_list);
- UT_LIST_INIT(trx_sys->rw_trx_list, &trx_t::trx_list);
- UT_LIST_INIT(trx_sys->mysql_trx_list, &trx_t::mysql_trx_list);
-
- trx_sys->mvcc = UT_NEW_NOKEY(MVCC(1024));
-
- new(&trx_sys->rw_trx_ids) trx_ids_t(ut_allocator<trx_id_t>(
- mem_key_trx_sys_t_rw_trx_ids));
-
- new(&trx_sys->rw_trx_set) TrxIdSet();
+ ut_ad(this == &trx_sys);
+ ut_ad(!is_initialised());
+ m_initialised = true;
+ mutex_create(LATCH_ID_TRX_SYS, &mutex);
+ UT_LIST_INIT(mysql_trx_list, &trx_t::mysql_trx_list);
+ UT_LIST_INIT(m_views, &ReadView::m_view_list);
+ my_atomic_store32(&rseg_history_len, 0);
+
+ rw_trx_hash.init();
}
/*****************************************************************//**
@@ -614,137 +314,75 @@ trx_sys_create_rsegs()
return(true);
}
-/*********************************************************************
-Shutdown/Close the transaction system. */
+/** Close the transaction system on shutdown */
void
-trx_sys_close(void)
-/*===============*/
+trx_sys_t::close()
{
- ut_ad(trx_sys != NULL);
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
+ if (!is_initialised()) {
+ return;
+ }
- if (ulint size = trx_sys->mvcc->size()) {
+ if (size_t size = view_count()) {
ib::error() << "All read views were not closed before"
" shutdown: " << size << " read views open";
}
- if (trx_dummy_sess) {
- sess_close(trx_dummy_sess);
- trx_dummy_sess = NULL;
- }
-
- /* Only prepared transactions may be left in the system. Free them. */
- ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == trx_sys->n_prepared_trx
- || !srv_was_started
- || srv_read_only_mode
- || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
-
- for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
- trx != NULL;
- trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list)) {
-
- trx_free_prepared(trx);
-
- UT_LIST_REMOVE(trx_sys->rw_trx_list, trx);
- }
+ rw_trx_hash.destroy();
/* There can't be any active transactions. */
for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) {
- if (trx_rseg_t* rseg = trx_sys->rseg_array[i]) {
+ if (trx_rseg_t* rseg = rseg_array[i]) {
trx_rseg_mem_free(rseg);
}
- if (trx_rseg_t* rseg = trx_sys->temp_rsegs[i]) {
+ if (trx_rseg_t* rseg = temp_rsegs[i]) {
trx_rseg_mem_free(rseg);
}
}
- UT_DELETE(trx_sys->mvcc);
-
- ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == 0);
- ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0);
- ut_a(UT_LIST_GET_LEN(trx_sys->serialisation_list) == 0);
-
- /* We used placement new to create this mutex. Call the destructor. */
- mutex_free(&trx_sys->mutex);
-
- trx_sys->rw_trx_ids.~trx_ids_t();
-
- trx_sys->rw_trx_set.~TrxIdSet();
+ ut_a(UT_LIST_GET_LEN(mysql_trx_list) == 0);
+ ut_ad(UT_LIST_GET_LEN(m_views) == 0);
+ mutex_free(&mutex);
+ m_initialised = false;
+}
- ut_free(trx_sys);
- trx_sys = NULL;
+static my_bool active_count_callback(rw_trx_hash_element_t *element,
+ uint32_t *count)
+{
+ mutex_enter(&element->mutex);
+ if (trx_t *trx= element->trx)
+ {
+ mutex_enter(&trx->mutex);
+ if (trx_state_eq(trx, TRX_STATE_ACTIVE))
+ ++*count;
+ mutex_exit(&trx->mutex);
+ }
+ mutex_exit(&element->mutex);
+ return 0;
}
-/*********************************************************************
-Check if there are any active (non-prepared) transactions.
-This is only used to check if it's safe to shutdown.
-@return total number of active transactions or 0 if none */
-ulint
-trx_sys_any_active_transactions(void)
-/*=================================*/
-{
- ulint total_trx = 0;
- trx_sys_mutex_enter();
+/** @return total number of active (non-prepared) transactions */
+ulint trx_sys_t::any_active_transactions()
+{
+ uint32_t total_trx = 0;
- total_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list);
+ trx_sys.rw_trx_hash.iterate_no_dups(
+ reinterpret_cast<my_hash_walk_action>
+ (active_count_callback), &total_trx);
- for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list);
+ mutex_enter(&mutex);
+ for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys.mysql_trx_list);
trx != NULL;
trx = UT_LIST_GET_NEXT(mysql_trx_list, trx)) {
- total_trx += trx->state != TRX_STATE_NOT_STARTED;
+ if (trx->state != TRX_STATE_NOT_STARTED && !trx->id) {
+ total_trx++;
+ }
}
-
- ut_a(total_trx >= trx_sys->n_prepared_trx);
- total_trx -= trx_sys->n_prepared_trx;
-
- trx_sys_mutex_exit();
+ mutex_exit(&mutex);
return(total_trx);
}
-
-#ifdef UNIV_DEBUG
-/*************************************************************//**
-Validate the trx_ut_list_t.
-@return true if valid. */
-static
-bool
-trx_sys_validate_trx_list_low(
-/*===========================*/
- trx_ut_list_t* trx_list) /*!< in: &trx_sys->rw_trx_list */
-{
- const trx_t* trx;
- const trx_t* prev_trx = NULL;
-
- ut_ad(trx_sys_mutex_own());
-
- ut_ad(trx_list == &trx_sys->rw_trx_list);
-
- for (trx = UT_LIST_GET_FIRST(*trx_list);
- trx != NULL;
- prev_trx = trx, trx = UT_LIST_GET_NEXT(trx_list, prev_trx)) {
-
- check_trx_state(trx);
- ut_a(prev_trx == NULL || prev_trx->id > trx->id);
- }
-
- return(true);
-}
-
-/*************************************************************//**
-Validate the trx_sys_t::rw_trx_list.
-@return true if the list is valid. */
-bool
-trx_sys_validate_trx_list()
-/*=======================*/
-{
- ut_ad(trx_sys_mutex_own());
-
- ut_a(trx_sys_validate_trx_list_low(&trx_sys->rw_trx_list));
-
- return(true);
-}
-#endif /* UNIV_DEBUG */
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 75131847da5..c76fa683d62 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -39,7 +39,6 @@ Created 3/26/1996 Heikki Tuuri
#include "log0log.h"
#include "os0proc.h"
#include "que0que.h"
-#include "read0read.h"
#include "srv0mon.h"
#include "srv0srv.h"
#include "fsp0sysspace.h"
@@ -51,7 +50,6 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0rseg.h"
#include "trx0undo.h"
#include "trx0xa.h"
-#include "usr0sess.h"
#include "ut0new.h"
#include "ut0pool.h"
#include "ut0vec.h"
@@ -62,6 +60,17 @@ Created 3/26/1996 Heikki Tuuri
extern "C"
int thd_deadlock_victim_preference(const MYSQL_THD thd1, const MYSQL_THD thd2);
+/** The bit pattern corresponding to TRX_ID_MAX */
+const byte trx_id_max_bytes[8] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+/** The bit pattern corresponding to max timestamp */
+const byte timestamp_max_bytes[7] = {
+ 0x7f, 0xff, 0xff, 0xff, 0x0f, 0x42, 0x3f
+};
+
+
static const ulint MAX_DETAILED_ERROR_LEN = 256;
/** Set of table_id */
@@ -70,9 +79,6 @@ typedef std::set<
std::less<table_id_t>,
ut_allocator<table_id_t> > table_id_set;
-/** Dummy session used currently in MySQL interface */
-sess_t* trx_dummy_sess = NULL;
-
/** Constructor */
TrxVersion::TrxVersion(trx_t* trx)
:
@@ -181,7 +187,7 @@ trx_init(
trx->last_sql_stat_start.least_undo_no = 0;
- ut_ad(!MVCC::is_view_active(trx->read_view));
+ ut_ad(!trx->read_view.is_open());
trx->lock.rec_cached = 0;
@@ -235,7 +241,9 @@ struct TrxFactory {
new(&trx->lock.table_locks) lock_pool_t();
new(&trx->hit_list) hit_list_t();
+ new(&trx->read_view) ReadView();
+ trx->rw_trx_hash_pins = 0;
trx_init(trx);
DBUG_LOG("trx", "Init: " << trx);
@@ -268,7 +276,6 @@ struct TrxFactory {
static void destroy(trx_t* trx)
{
ut_a(trx->magic_n == TRX_MAGIC_N);
- ut_ad(!trx->in_rw_trx_list);
ut_ad(!trx->in_mysql_trx_list);
ut_a(trx->lock.wait_lock == NULL);
@@ -290,7 +297,7 @@ struct TrxFactory {
trx->mod_tables.~trx_mod_tables_t();
- ut_ad(trx->read_view == NULL);
+ ut_ad(!trx->read_view.is_open());
if (!trx->lock.rec_pool.empty()) {
@@ -315,6 +322,7 @@ struct TrxFactory {
trx->lock.table_locks.~lock_pool_t();
trx->hit_list.~hit_list_t();
+ trx->read_view.~ReadView();
}
/** Enforce any invariants here, this is called before the transaction
@@ -335,7 +343,6 @@ struct TrxFactory {
ut_ad(trx->mysql_thd == 0);
- ut_ad(!trx->in_rw_trx_list);
ut_ad(!trx->in_mysql_trx_list);
ut_a(trx->lock.wait_thr == NULL);
@@ -446,6 +453,7 @@ trx_create_low()
/* We just got trx from pool, it should be non locking */
ut_ad(trx->will_lock == 0);
+ ut_ad(!trx->rw_trx_hash_pins);
/* Background trx should not be forced to rollback,
we will unset the flag for user trx. */
@@ -483,6 +491,7 @@ trx_free(trx_t*& trx)
{
assert_trx_is_free(trx);
+ trx_sys.rw_trx_hash.put_pins(trx);
trx->mysql_thd = 0;
trx->mysql_log_file_name = 0;
@@ -496,7 +505,8 @@ trx_free(trx_t*& trx)
trx->mod_tables.clear();
- ut_ad(trx->read_view == NULL);
+ ut_ad(!trx->read_view.is_open());
+ trx->read_view.close();
/* trx locking state should have been reset before returning trx
to pool */
@@ -518,8 +528,6 @@ trx_allocate_for_background(void)
trx = trx_create_low();
- trx->sess = trx_dummy_sess;
-
return(trx);
}
@@ -534,12 +542,12 @@ trx_allocate_for_mysql(void)
trx = trx_allocate_for_background();
- trx_sys_mutex_enter();
+ mutex_enter(&trx_sys.mutex);
ut_d(trx->in_mysql_trx_list = TRUE);
- UT_LIST_ADD_FIRST(trx_sys->mysql_trx_list, trx);
+ UT_LIST_ADD_FIRST(trx_sys.mysql_trx_list, trx);
- trx_sys_mutex_exit();
+ mutex_exit(&trx_sys.mutex);
return(trx);
}
@@ -553,6 +561,7 @@ trx_validate_state_before_free(trx_t* trx)
ut_ad(!trx->declared_to_be_inside_innodb);
ut_ad(!trx->n_mysql_tables_in_use);
ut_ad(!trx->mysql_n_tables_locked);
+ ut_ad(!trx->internal);
if (trx->declared_to_be_inside_innodb) {
@@ -608,33 +617,27 @@ trx_free_for_background(trx_t* trx)
trx_free(trx);
}
-/********************************************************************//**
-At shutdown, frees a transaction object that is in the PREPARED state. */
+/** At shutdown, frees a transaction object. */
void
-trx_free_prepared(
-/*==============*/
- trx_t* trx) /*!< in, own: trx object */
+trx_free_at_shutdown(trx_t *trx)
{
+ ut_ad(trx->is_recovered);
ut_a(trx_state_eq(trx, TRX_STATE_PREPARED)
- || (trx->is_recovered
- && (trx_state_eq(trx, TRX_STATE_ACTIVE)
- || trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY))
+ || (trx_state_eq(trx, TRX_STATE_ACTIVE)
&& (!srv_was_started
|| srv_operation == SRV_OPERATION_RESTORE
|| srv_operation == SRV_OPERATION_RESTORE_EXPORT
|| srv_read_only_mode
- || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO)));
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
+ || (!srv_is_being_started
+ && !srv_undo_sources && srv_fast_shutdown))));
ut_a(trx->magic_n == TRX_MAGIC_N);
lock_trx_release_locks(trx);
- trx_undo_free_prepared(trx);
-
- assert_trx_in_rw_list(trx);
+ trx_undo_free_at_shutdown(trx);
ut_a(!trx->read_only);
- ut_d(trx->in_rw_trx_list = FALSE);
-
DBUG_LOG("trx", "Free prepared: " << trx);
trx->state = TRX_STATE_NOT_STARTED;
@@ -663,31 +666,26 @@ trx_disconnect_from_mysql(
trx_t* trx,
bool prepared)
{
- trx_sys_mutex_enter();
+ trx->read_view.close();
+
+ mutex_enter(&trx_sys.mutex);
ut_ad(trx->in_mysql_trx_list);
ut_d(trx->in_mysql_trx_list = FALSE);
- UT_LIST_REMOVE(trx_sys->mysql_trx_list, trx);
-
- if (trx->read_view != NULL) {
- trx_sys->mvcc->view_close(trx->read_view, true);
- }
-
- ut_ad(trx_sys_validate_trx_list());
+ UT_LIST_REMOVE(trx_sys.mysql_trx_list, trx);
if (prepared) {
ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED));
trx->is_recovered = true;
- trx_sys->n_prepared_recovered_trx++;
trx->mysql_thd = NULL;
/* todo/fixme: suggest to do it at innodb prepare */
trx->will_lock = 0;
}
- trx_sys_mutex_exit();
+ mutex_exit(&trx_sys.mutex);
}
/** Disconnect a transaction from MySQL.
@@ -730,7 +728,9 @@ trx_resurrect_table_locks(
trx_undo_rec_t* undo_rec;
table_id_set tables;
- if (trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY) || undo->empty) {
+ ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) ||
+ trx_state_eq(trx, TRX_STATE_PREPARED));
+ if (undo->empty) {
return;
}
@@ -783,7 +783,9 @@ trx_resurrect_table_locks(
}
if (trx->state == TRX_STATE_PREPARED) {
- trx->mod_tables.insert(table);
+ trx->mod_tables.insert(
+ trx_mod_tables_t::value_type(table,
+ 0));
}
lock_table_ix_resurrect(table, trx);
@@ -796,166 +798,84 @@ trx_resurrect_table_locks(
}
}
-/****************************************************************//**
-Resurrect the transactions that were doing inserts the time of the
-crash, they need to be undone.
-@return trx_t instance */
-static
-trx_t*
-trx_resurrect_insert(
-/*=================*/
- trx_undo_t* undo, /*!< in: entry to UNDO */
- trx_rseg_t* rseg) /*!< in: rollback segment */
-{
- trx_t* trx;
-
- trx = trx_allocate_for_background();
-
- ut_d(trx->start_file = __FILE__);
- ut_d(trx->start_line = __LINE__);
-
- trx->rsegs.m_redo.rseg = rseg;
- /* For transactions with active data will not have rseg size = 1
- or will not qualify for purge limit criteria. So it is safe to increment
- this trx_ref_count w/o mutex protection. */
- ++trx->rsegs.m_redo.rseg->trx_ref_count;
- *trx->xid = undo->xid;
- trx->id = undo->trx_id;
- trx->rsegs.m_redo.old_insert = undo;
- trx->is_recovered = true;
- /* This is single-threaded startup code, we do not need the
- protection of trx->mutex or trx_sys->mutex here. */
-
- if (undo->state != TRX_UNDO_ACTIVE) {
-
- /* Prepared transactions are left in the prepared state
- waiting for a commit or abort decision from MySQL */
-
- if (undo->state == TRX_UNDO_PREPARED) {
-
- ib::info() << "Transaction "
- << trx_get_id_for_print(trx)
- << " was in the XA prepared state.";
-
- trx->state = TRX_STATE_PREPARED;
- trx_sys->n_prepared_trx++;
- trx_sys->n_prepared_recovered_trx++;
- } else {
- trx->state = TRX_STATE_COMMITTED_IN_MEMORY;
- }
-
- /* We give a dummy value for the trx no; this should have no
- relevance since purge is not interested in committed
- transaction numbers, unless they are in the history
- list, in which case it looks the number from the disk based
- undo log structure */
-
- trx->no = trx->id;
-
- } else {
- trx->state = TRX_STATE_ACTIVE;
-
- /* A running transaction always has the number
- field inited to TRX_ID_MAX */
-
- trx->no = TRX_ID_MAX;
- }
-
- if (undo->dict_operation) {
- trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
- trx->table_id = undo->table_id;
- }
-
- if (!undo->empty) {
- trx->undo_no = undo->top_undo_no + 1;
- trx->undo_rseg_space = undo->rseg->space;
- }
-
- return(trx);
-}
-
-/****************************************************************//**
-Prepared transactions are left in the prepared state waiting for a
-commit or abort decision from MySQL */
-static
-void
-trx_resurrect_update_in_prepared_state(
-/*===================================*/
- trx_t* trx, /*!< in,out: transaction */
- const trx_undo_t* undo) /*!< in: update UNDO record */
-{
- /* This is single-threaded startup code, we do not need the
- protection of trx->mutex or trx_sys->mutex here. */
-
- if (undo->state == TRX_UNDO_PREPARED) {
- ib::info() << "Transaction " << trx_get_id_for_print(trx)
- << " was in the XA prepared state.";
-
- if (trx_state_eq(trx, TRX_STATE_NOT_STARTED)) {
- trx_sys->n_prepared_trx++;
- trx_sys->n_prepared_recovered_trx++;
- } else {
- ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED));
- }
-
- trx->state = TRX_STATE_PREPARED;
- } else {
- trx->state = TRX_STATE_COMMITTED_IN_MEMORY;
- }
+/**
+ Resurrect the transactions that were doing inserts/updates the time of the
+ crash, they need to be undone.
+*/
+
+static void trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg,
+ ib_time_t start_time, uint64_t *rows_to_undo,
+ bool is_old_insert)
+{
+ trx_state_t state;
+ /*
+ This is single-threaded startup code, we do not need the
+ protection of trx->mutex or trx_sys.mutex here.
+ */
+ switch (undo->state)
+ {
+ case TRX_UNDO_ACTIVE:
+ state= TRX_STATE_ACTIVE;
+ break;
+ case TRX_UNDO_PREPARED:
+ /*
+ Prepared transactions are left in the prepared state
+ waiting for a commit or abort decision from MySQL
+ */
+ ib::info() << "Transaction " << undo->trx_id
+ << " was in the XA prepared state.";
+
+ state= TRX_STATE_PREPARED;
+ break;
+ default:
+ if (is_old_insert && srv_force_recovery < SRV_FORCE_NO_TRX_UNDO)
+ trx_undo_commit_cleanup(undo, false);
+ return;
+ }
+
+ trx_t *trx= trx_allocate_for_background();
+ trx->state= state;
+ ut_d(trx->start_file= __FILE__);
+ ut_d(trx->start_line= __LINE__);
+ ut_ad(trx->no == TRX_ID_MAX);
+
+ if (is_old_insert)
+ trx->rsegs.m_redo.old_insert= undo;
+ else
+ trx->rsegs.m_redo.undo= undo;
+
+ if (!undo->empty)
+ {
+ trx->undo_no= undo->top_undo_no + 1;
+ trx->undo_rseg_space= undo->rseg->space;
+ }
+
+ trx->rsegs.m_redo.rseg= rseg;
+ /*
+ For transactions with active data will not have rseg size = 1
+ or will not qualify for purge limit criteria. So it is safe to increment
+ this trx_ref_count w/o mutex protection.
+ */
+ ++trx->rsegs.m_redo.rseg->trx_ref_count;
+ *trx->xid= undo->xid;
+ trx->id= undo->trx_id;
+ trx->is_recovered= true;
+ trx->start_time= start_time;
+
+ if (undo->dict_operation)
+ {
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+ trx->table_id= undo->table_id;
+ }
+
+ trx_sys.rw_trx_hash.insert(trx);
+ trx_sys.rw_trx_hash.put_pins(trx);
+ trx_resurrect_table_locks(trx, undo);
+ if (trx_state_eq(trx, TRX_STATE_ACTIVE))
+ *rows_to_undo+= trx->undo_no;
}
-/****************************************************************//**
-Resurrect the transactions that were doing updates the time of the
-crash, they need to be undone. */
-static
-void
-trx_resurrect_update(
-/*=================*/
- trx_t* trx, /*!< in/out: transaction */
- trx_undo_t* undo, /*!< in/out: update UNDO record */
- trx_rseg_t* rseg) /*!< in/out: rollback segment */
-{
- trx->rsegs.m_redo.rseg = rseg;
- /* For transactions with active data will not have rseg size = 1
- or will not qualify for purge limit criteria. So it is safe to increment
- this trx_ref_count w/o mutex protection. */
- ++trx->rsegs.m_redo.rseg->trx_ref_count;
- *trx->xid = undo->xid;
- trx->id = undo->trx_id;
- trx->rsegs.m_redo.undo = undo;
- trx->is_recovered = true;
-
- /* This is single-threaded startup code, we do not need the
- protection of trx->mutex or trx_sys->mutex here. */
-
- if (undo->state != TRX_UNDO_ACTIVE) {
- trx_resurrect_update_in_prepared_state(trx, undo);
-
- /* We give a dummy value for the trx number */
-
- trx->no = trx->id;
-
- } else {
- trx->state = TRX_STATE_ACTIVE;
-
- /* A running transaction always has the number field inited to
- TRX_ID_MAX */
-
- trx->no = TRX_ID_MAX;
- }
-
- if (undo->dict_operation) {
- trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
- trx->table_id = undo->table_id;
- }
-
- if (!undo->empty && undo->top_undo_no >= trx->undo_no) {
-
- trx->undo_no = undo->top_undo_no + 1;
- trx->undo_rseg_space = undo->rseg->space;
- }
-}
/** Initialize (resurrect) transactions at startup. */
void
@@ -963,93 +883,94 @@ trx_lists_init_at_db_start()
{
ut_a(srv_is_being_started);
ut_ad(!srv_was_started);
- ut_ad(!purge_sys);
-
- purge_sys = UT_NEW_NOKEY(purge_sys_t());
+ ut_ad(!purge_sys.is_initialised());
- if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
+ if (srv_operation == SRV_OPERATION_RESTORE) {
+ /* mariabackup --prepare only deals with
+ the redo log and the data files, not with
+ transactions or the data dictionary. */
trx_rseg_array_init();
+ return;
+ }
+
+ if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) {
+ return;
}
+ purge_sys.create();
+ trx_rseg_array_init();
+
/* Look from the rollback segments if there exist undo logs for
transactions. */
- const ib_time_t start_time = ut_time();
+ const ib_time_t start_time = ut_time();
+ uint64_t rows_to_undo = 0;
for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) {
trx_undo_t* undo;
- trx_rseg_t* rseg = trx_sys->rseg_array[i];
+ trx_rseg_t* rseg = trx_sys.rseg_array[i];
- /* At this stage non-redo rseg slots are all NULL as they are
- re-created on server start and existing slots are not read. */
+ /* Some rollback segment may be unavailable,
+ especially if the server was previously run with a
+ non-default value of innodb_undo_logs. */
if (rseg == NULL) {
continue;
}
/* Resurrect transactions that were doing inserts
using the old separate insert_undo log. */
- for (undo = UT_LIST_GET_FIRST(rseg->old_insert_list);
- undo != NULL;
- undo = UT_LIST_GET_NEXT(undo_list, undo)) {
-
- trx_t* trx;
-
- trx = trx_resurrect_insert(undo, rseg);
- trx->start_time = start_time;
-
- trx_sys_rw_trx_add(trx);
-
- trx_resurrect_table_locks(trx, undo);
+ undo = UT_LIST_GET_FIRST(rseg->old_insert_list);
+ while (undo) {
+ trx_undo_t* next = UT_LIST_GET_NEXT(undo_list, undo);
+ trx_resurrect(undo, rseg, start_time, &rows_to_undo,
+ true);
+ undo = next;
}
/* Ressurrect other transactions. */
for (undo = UT_LIST_GET_FIRST(rseg->undo_list);
undo != NULL;
undo = UT_LIST_GET_NEXT(undo_list, undo)) {
-
- /* Check the trx_sys->rw_trx_set first. */
- trx_sys_mutex_enter();
-
- trx_t* trx = trx_get_rw_trx_by_id(undo->trx_id);
-
- trx_sys_mutex_exit();
-
- if (trx == NULL) {
- trx = trx_allocate_for_background();
- trx->start_time = start_time;
-
- ut_d(trx->start_file = __FILE__);
- ut_d(trx->start_line = __LINE__);
+ trx_t *trx = trx_sys.rw_trx_hash.find(0, undo->trx_id);
+ if (!trx) {
+ trx_resurrect(undo, rseg, start_time,
+ &rows_to_undo, false);
+ } else {
+ ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) ||
+ trx_state_eq(trx, TRX_STATE_PREPARED));
+ ut_ad(trx->start_time == start_time);
+ ut_ad(trx->is_recovered);
+ ut_ad(trx->rsegs.m_redo.rseg == rseg);
+ ut_ad(trx->rsegs.m_redo.rseg->trx_ref_count);
+
+ trx->rsegs.m_redo.undo = undo;
+ if (!undo->empty
+ && undo->top_undo_no >= trx->undo_no) {
+ if (trx_state_eq(trx,
+ TRX_STATE_ACTIVE)) {
+ rows_to_undo -= trx->undo_no;
+ rows_to_undo +=
+ undo->top_undo_no + 1;
+ }
+
+ trx->undo_no = undo->top_undo_no + 1;
+ trx->undo_rseg_space =
+ undo->rseg->space;
+ }
+ trx_resurrect_table_locks(trx, undo);
}
-
- trx_resurrect_update(trx, undo, rseg);
-
- trx_sys_rw_trx_add(trx);
-
- trx_resurrect_table_locks(trx, undo);
}
}
- TrxIdSet::iterator end = trx_sys->rw_trx_set.end();
+ if (trx_sys.rw_trx_hash.size()) {
- for (TrxIdSet::iterator it = trx_sys->rw_trx_set.begin();
- it != end;
- ++it) {
+ ib::info() << trx_sys.rw_trx_hash.size()
+ << " transaction(s) which must be rolled back or"
+ " cleaned up in total " << rows_to_undo
+ << " row operations to undo";
- ut_ad(it->m_trx->in_rw_trx_list);
-#ifdef UNIV_DEBUG
- if (it->m_trx->id > trx_sys->rw_max_trx_id) {
- trx_sys->rw_max_trx_id = it->m_trx->id;
- }
-#endif /* UNIV_DEBUG */
-
- if (it->m_trx->state == TRX_STATE_ACTIVE
- || it->m_trx->state == TRX_STATE_PREPARED) {
-
- trx_sys->rw_trx_ids.push_back(it->m_id);
- }
-
- UT_LIST_ADD_FIRST(trx_sys->rw_trx_list, it->m_trx);
+ ib::info() << "Trx id counter is " << trx_sys.get_max_trx_id();
}
+ trx_sys.clone_oldest_view();
}
/** Assign a persistent rollback segment in a round-robin fashion,
@@ -1066,7 +987,7 @@ trx_assign_rseg_low()
}
/* The first slot is always assigned to the system tablespace. */
- ut_ad(trx_sys->rseg_array[0]->space == TRX_SYS_SPACE);
+ ut_ad(trx_sys.rseg_array[0]->space == TRX_SYS_SPACE);
/* Choose a rollback segment evenly distributed between 0 and
innodb_undo_logs-1 in a round-robin fashion, skipping those
@@ -1089,7 +1010,7 @@ trx_assign_rseg_low()
do {
for (;;) {
- rseg = trx_sys->rseg_array[slot];
+ rseg = trx_sys.rseg_array[slot];
#ifdef UNIV_DEBUG
/* Ensure that we are not revisiting the same
@@ -1114,7 +1035,7 @@ trx_assign_rseg_low()
continue;
}
} else if (trx_rseg_t* next
- = trx_sys->rseg_array[slot]) {
+ = trx_sys.rseg_array[slot]) {
if (next->space != TRX_SYS_SPACE
&& srv_undo_tablespaces > 0) {
/** If dedicated
@@ -1159,17 +1080,13 @@ trx_t::assign_temp_rseg()
multiple transactions that start modifications concurrently
will write their undo log to the same rollback segment. */
static ulong rseg_slot;
- trx_rseg_t* rseg = trx_sys->temp_rsegs[
+ trx_rseg_t* rseg = trx_sys.temp_rsegs[
rseg_slot++ & (TRX_SYS_N_RSEGS - 1)];
ut_ad(!rseg->is_persistent());
rsegs.m_noredo.rseg = rseg;
if (id == 0) {
- mutex_enter(&trx_sys->mutex);
- id = trx_sys_get_new_trx_id();
- trx_sys->rw_trx_ids.push_back(id);
- trx_sys->rw_trx_set.insert(TrxTrack(id, this));
- mutex_exit(&trx_sys->mutex);
+ trx_sys.register_rw(this);
}
ut_ad(!rseg->is_persistent());
@@ -1229,15 +1146,17 @@ trx_start_low(
/* If this transaction came from trx_allocate_for_mysql(),
trx->in_mysql_trx_list would hold. In that case, the trx->state
- change must be protected by the trx_sys->mutex, so that
+ change must be protected by the trx_sys.mutex, so that
lock_print_info_all_transactions() will have a consistent view. */
- ut_ad(!trx->in_rw_trx_list);
+ /* No other thread can access this trx object through rw_trx_hash, thus
+ we don't need trx_sys.mutex protection for that purpose. Still this
+ trx can be found through trx_sys.mysql_trx_list, which means state
+ change must be protected by e.g. trx->mutex.
- /* We tend to over assert and that complicates the code somewhat.
- e.g., the transaction state can be set earlier but we are forced to
- set it under the protection of the trx_sys_t::mutex because some
- trx list assertions are triggered unnecessarily. */
+ For now we update it without mutex protection, because original code
+ did it this way. It has to be reviewed and fixed properly. */
+ trx->state = TRX_STATE_ACTIVE;
/* By default all transactions are in the read-only list unless they
are non-locking auto-commit read only transactions or background
@@ -1248,38 +1167,14 @@ trx_start_low(
if (!trx->read_only
&& (trx->mysql_thd == 0 || read_write || trx->ddl)) {
- trx->rsegs.m_redo.rseg = trx_assign_rseg_low();
-
/* Temporary rseg is assigned only if the transaction
updates a temporary table */
-
- trx_sys_mutex_enter();
-
- trx->id = trx_sys_get_new_trx_id();
-
- trx_sys->rw_trx_ids.push_back(trx->id);
-
- trx_sys_rw_trx_add(trx);
-
+ trx->rsegs.m_redo.rseg = trx_assign_rseg_low();
ut_ad(trx->rsegs.m_redo.rseg != 0
|| srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
- UT_LIST_ADD_FIRST(trx_sys->rw_trx_list, trx);
-
- ut_d(trx->in_rw_trx_list = true);
-#ifdef UNIV_DEBUG
- if (trx->id > trx_sys->rw_max_trx_id) {
- trx_sys->rw_max_trx_id = trx->id;
- }
-#endif /* UNIV_DEBUG */
-
- trx->state = TRX_STATE_ACTIVE;
-
- ut_ad(trx_sys_validate_trx_list());
-
- trx_sys_mutex_exit();
-
+ trx_sys.register_rw(trx);
} else {
trx->id = 0;
@@ -1290,26 +1185,11 @@ trx_start_low(
to write to the temporary table. */
if (read_write) {
-
- trx_sys_mutex_enter();
-
ut_ad(!srv_read_only_mode);
-
- trx->id = trx_sys_get_new_trx_id();
-
- trx_sys->rw_trx_ids.push_back(trx->id);
-
- trx_sys->rw_trx_set.insert(
- TrxTrack(trx->id, trx));
-
- trx_sys_mutex_exit();
+ trx_sys.register_rw(trx);
}
-
- trx->state = TRX_STATE_ACTIVE;
-
} else {
ut_ad(!read_write);
- trx->state = TRX_STATE_ACTIVE;
}
}
@@ -1328,52 +1208,36 @@ trx_start_low(
}
/** Set the serialisation number for a persistent committed transaction.
-@param[in,out] trx committed transaction with persistent changes
-@param[in,out] rseg rollback segment for undo, or NULL */
+@param[in,out] trx committed transaction with persistent changes */
static
void
-trx_serialise(trx_t* trx, trx_rseg_t* rseg)
+trx_serialise(trx_t* trx)
{
- ut_ad(!rseg || rseg == trx->rsegs.m_redo.rseg);
-
- trx_sys_mutex_enter();
+ trx_rseg_t *rseg = trx->rsegs.m_redo.rseg;
+ ut_ad(rseg);
+ ut_ad(mutex_own(&rseg->mutex));
- trx->no = trx_sys_get_new_trx_id();
+ if (rseg->last_page_no == FIL_NULL) {
+ mutex_enter(&purge_sys.pq_mutex);
+ }
- /* Track the minimum serialisation number. */
- UT_LIST_ADD_LAST(trx_sys->serialisation_list, trx);
+ trx_sys.assign_new_trx_no(trx);
- /* If the rollack segment is not empty then the
+ /* If the rollback segment is not empty then the
new trx_t::no can't be less than any trx_t::no
already in the rollback segment. User threads only
produce events when a rollback segment is empty. */
- if (rseg && rseg->last_page_no == FIL_NULL) {
- TrxUndoRsegs elem(trx->no);
- elem.push_back(rseg);
-
- mutex_enter(&purge_sys->pq_mutex);
-
- /* This is to reduce the pressure on the trx_sys_t::mutex
- though in reality it should make very little (read no)
- difference because this code path is only taken when the
- rbs is empty. */
-
- trx_sys_mutex_exit();
-
- purge_sys->purge_queue.push(elem);
-
- mutex_exit(&purge_sys->pq_mutex);
- } else {
- trx_sys_mutex_exit();
+ if (rseg->last_page_no == FIL_NULL) {
+ purge_sys.purge_queue.push(TrxUndoRsegs(trx->no, *rseg));
+ mutex_exit(&purge_sys.pq_mutex);
}
}
/****************************************************************//**
Assign the transaction its history serialisation number and write the
-update UNDO log record to the assigned rollback segment.
-@return true if a serialisation log was written */
+update UNDO log record to the assigned rollback segment. */
static
-bool
+void
trx_write_serialisation_history(
/*============================*/
trx_t* trx, /*!< in/out: transaction */
@@ -1408,26 +1272,24 @@ trx_write_serialisation_history(
if (!rseg) {
ut_ad(!trx->rsegs.m_redo.undo);
ut_ad(!trx->rsegs.m_redo.old_insert);
- return false;
+ return;
}
trx_undo_t*& undo = trx->rsegs.m_redo.undo;
trx_undo_t*& old_insert = trx->rsegs.m_redo.old_insert;
if (!undo && !old_insert) {
- return false;
+ return;
}
ut_ad(!trx->read_only);
- trx_rseg_t* undo_rseg
- = undo ? undo->rseg : old_insert ? old_insert->rseg : NULL;
ut_ad(!undo || undo->rseg == rseg);
ut_ad(!old_insert || old_insert->rseg == rseg);
mutex_enter(&rseg->mutex);
/* Assign the transaction serialisation number and add any
undo log to the purge queue. */
- trx_serialise(trx, undo_rseg);
+ trx_serialise(trx);
/* It is not necessary to acquire trx->undo_mutex here because
only a single OS thread is allowed to commit this transaction.
@@ -1445,31 +1307,7 @@ trx_write_serialisation_history(
MONITOR_INC(MONITOR_TRX_COMMIT_UNDO);
- trx_sysf_t* sys_header = trx_sysf_get(mtr);
-#ifdef WITH_WSREP
- /* Update latest MySQL wsrep XID in trx sys header. */
- if (wsrep_is_wsrep_xid(trx->xid)) {
- trx_sys_update_wsrep_checkpoint(trx->xid, sys_header, mtr);
- }
-#endif /* WITH_WSREP */
-
- /* Update the latest MySQL binlog name and offset info
- in trx sys header if MySQL binlogging is on or the database
- server is a MySQL replication slave */
-
- if (trx->mysql_log_file_name != NULL
- && trx->mysql_log_file_name[0] != '\0') {
-
- trx_sys_update_mysql_binlog_offset(
- trx->mysql_log_file_name,
- trx->mysql_log_offset,
- sys_header,
- mtr);
-
- trx->mysql_log_file_name = NULL;
- }
-
- return(true);
+ trx->mysql_log_file_name = NULL;
}
/********************************************************************
@@ -1619,58 +1457,12 @@ trx_update_mod_tables_timestamp(
"garbage" in table->update_time is justified because
protecting it with a latch here would be too performance
intrusive. */
- (*it)->update_time = now;
+ it->first->update_time = now;
}
trx->mod_tables.clear();
}
-/**
-Erase the transaction from running transaction lists and serialization
-list. Active RW transaction list of a MVCC snapshot(ReadView::prepare)
-won't include this transaction after this call. All implicit locks are
-also released by this call as trx is removed from rw_trx_list.
-@param[in] trx Transaction to erase, must have an ID > 0
-@param[in] serialised true if serialisation log was written */
-static
-void
-trx_erase_lists(
- trx_t* trx,
- bool serialised)
-{
- ut_ad(trx->id > 0);
- trx_sys_mutex_enter();
-
- if (serialised) {
- UT_LIST_REMOVE(trx_sys->serialisation_list, trx);
- }
-
- trx_ids_t::iterator it = std::lower_bound(
- trx_sys->rw_trx_ids.begin(),
- trx_sys->rw_trx_ids.end(),
- trx->id);
- ut_ad(*it == trx->id);
- trx_sys->rw_trx_ids.erase(it);
-
- if (trx->read_only || trx->rsegs.m_redo.rseg == NULL) {
-
- ut_ad(!trx->in_rw_trx_list);
- } else {
-
- UT_LIST_REMOVE(trx_sys->rw_trx_list, trx);
- ut_d(trx->in_rw_trx_list = false);
- ut_ad(trx_sys_validate_trx_list());
-
- if (trx->read_view != NULL) {
- trx_sys->mvcc->view_close(trx->read_view, true);
- }
- }
-
- trx_sys->rw_trx_set.erase(TrxTrack(trx->id));
-
- trx_sys_mutex_exit();
-}
-
/****************************************************************//**
Commits a transaction in memory. */
static
@@ -1678,21 +1470,18 @@ void
trx_commit_in_memory(
/*=================*/
trx_t* trx, /*!< in/out: transaction */
- const mtr_t* mtr, /*!< in: mini-transaction of
+ const mtr_t* mtr) /*!< in: mini-transaction of
trx_write_serialisation_history(), or NULL if
the transaction did not modify anything */
- bool serialised)
- /*!< in: true if serialisation log was
- written */
{
trx->must_flush_log_later = false;
+ trx->read_view.unuse();
if (trx_is_autocommit_non_locking(trx)) {
ut_ad(trx->id == 0);
ut_ad(trx->read_only);
ut_a(!trx->is_recovered);
ut_ad(trx->rsegs.m_redo.rseg == NULL);
- ut_ad(!trx->in_rw_trx_list);
/* Note: We are asserting without holding the lock mutex. But
that is OK because this transaction is not waiting and cannot
@@ -1710,10 +1499,6 @@ trx_commit_in_memory(
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
- if (trx->read_view != NULL) {
- trx_sys->mvcc->view_close(trx->read_view, false);
- }
-
MONITOR_INC(MONITOR_TRX_NL_RO_COMMIT);
/* AC-NL-RO transactions can't be rolled back asynchronously. */
@@ -1725,12 +1510,11 @@ trx_commit_in_memory(
trx->state = TRX_STATE_NOT_STARTED;
} else {
-
if (trx->id > 0) {
/* For consistent snapshot, we need to remove current
- transaction from running transaction id list for mvcc
- before doing commit and releasing locks. */
- trx_erase_lists(trx, serialised);
+ transaction from rw_trx_hash before doing commit and
+ releasing locks. */
+ trx_sys.deregister_rw(trx);
}
lock_trx_release_locks(trx);
@@ -1742,15 +1526,9 @@ trx_commit_in_memory(
DEBUG_SYNC_C("after_trx_committed_in_memory");
if (trx->read_only || trx->rsegs.m_redo.rseg == NULL) {
-
MONITOR_INC(MONITOR_TRX_RO_COMMIT);
- if (trx->read_view != NULL) {
- trx_sys->mvcc->view_close(
- trx->read_view, false);
- }
-
} else {
- ut_ad(trx->id > 0);
+ trx_update_mod_tables_timestamp(trx);
MONITOR_INC(MONITOR_TRX_RW_COMMIT);
}
}
@@ -1913,13 +1691,11 @@ trx_commit_low(
}
}
- bool serialised;
-
if (mtr != NULL) {
mtr->set_sync();
- serialised = trx_write_serialisation_history(trx, mtr);
+ trx_write_serialisation_history(trx, mtr);
/* The following call commits the mini-transaction, making the
whole transaction committed in the file-based world, at this
@@ -1947,9 +1723,6 @@ trx_commit_low(
DBUG_SUICIDE();
});
/*--------------*/
-
- } else {
- serialised = false;
}
#ifndef DBUG_OFF
/* In case of this function is called from a stack executing
@@ -1965,7 +1738,7 @@ trx_commit_low(
}
#endif
- trx_commit_in_memory(trx, mtr, serialised);
+ trx_commit_in_memory(trx, mtr);
}
/****************************************************************//**
@@ -1993,81 +1766,13 @@ trx_commit(
}
/****************************************************************//**
-Cleans up a transaction at database startup. The cleanup is needed if
-the transaction already got to the middle of a commit when the database
-crashed, and we cannot roll it back. */
-void
-trx_cleanup_at_db_startup(
-/*======================*/
- trx_t* trx) /*!< in: transaction */
-{
- ut_ad(trx->is_recovered);
- ut_ad(!trx->rsegs.m_noredo.undo);
- ut_ad(!trx->rsegs.m_redo.undo);
-
- if (trx_undo_t*& undo = trx->rsegs.m_redo.old_insert) {
- ut_ad(undo->rseg == trx->rsegs.m_redo.rseg);
- trx_undo_commit_cleanup(undo, false);
- undo = NULL;
- }
-
- memset(&trx->rsegs, 0x0, sizeof(trx->rsegs));
- trx->undo_no = 0;
- trx->undo_rseg_space = 0;
- trx->last_sql_stat_start.least_undo_no = 0;
-
- trx_sys_mutex_enter();
-
- ut_a(!trx->read_only);
-
- UT_LIST_REMOVE(trx_sys->rw_trx_list, trx);
-
- ut_d(trx->in_rw_trx_list = FALSE);
-
- trx_sys_mutex_exit();
-
- /* Change the transaction state without mutex protection, now
- that it no longer is in the trx_list. Recovered transactions
- are never placed in the mysql_trx_list. */
- ut_ad(trx->is_recovered);
- ut_ad(!trx->in_rw_trx_list);
- ut_ad(!trx->in_mysql_trx_list);
- DBUG_LOG("trx", "Cleanup at startup: " << trx);
- trx->state = TRX_STATE_NOT_STARTED;
-}
-
-/********************************************************************//**
-Assigns a read view for a consistent read query. All the consistent reads
-within the same transaction will get the same read view, which is created
-when this function is first called for a new started transaction.
-@return consistent read view */
-ReadView*
-trx_assign_read_view(
-/*=================*/
- trx_t* trx) /*!< in/out: active transaction */
-{
- ut_ad(trx->state == TRX_STATE_ACTIVE);
-
- if (srv_read_only_mode) {
-
- ut_ad(trx->read_view == NULL);
- return(NULL);
-
- } else if (!MVCC::is_view_active(trx->read_view)) {
- trx_sys->mvcc->view_open(trx->read_view, trx);
- }
-
- return(trx->read_view);
-}
-
-/****************************************************************//**
Prepares a transaction for commit/rollback. */
void
trx_commit_or_rollback_prepare(
/*===========================*/
trx_t* trx) /*!< in/out: transaction */
{
- /* We are reading trx->state without holding trx_sys->mutex
+ /* We are reading trx->state without holding trx_sys.mutex
here, because the commit or rollback should be invoked for a
running (or recovered prepared) transaction that is associated
with the current thread. */
@@ -2205,10 +1910,6 @@ trx_commit_for_mysql(
trx->op_info = "committing";
- if (trx->id != 0) {
- trx_update_mod_tables_timestamp(trx);
- }
-
trx_commit(trx);
MONITOR_DEC(MONITOR_TRX_ACTIVE);
@@ -2273,8 +1974,7 @@ trx_mark_sql_stat_end(
}
/**********************************************************************//**
-Prints info about a transaction.
-Caller must hold trx_sys->mutex. */
+Prints info about a transaction. */
void
trx_print_low(
/*==========*/
@@ -2295,12 +1995,10 @@ trx_print_low(
ibool newline;
const char* op_info;
- ut_ad(trx_sys_mutex_own());
-
fprintf(f, "TRANSACTION " TRX_ID_FMT, trx_get_id_for_print(trx));
/* trx->state cannot change from or to NOT_STARTED while we
- are holding the trx_sys->mutex. It may change from ACTIVE to
+ are holding the trx_sys.mutex. It may change from ACTIVE to
PREPARED or COMMITTED. */
switch (trx->state) {
case TRX_STATE_NOT_STARTED:
@@ -2396,7 +2094,7 @@ state_ok:
/**********************************************************************//**
Prints info about a transaction.
-The caller must hold lock_sys->mutex and trx_sys->mutex.
+The caller must hold lock_sys.mutex.
When possible, use trx_print() instead. */
void
trx_print_latched(
@@ -2407,7 +2105,6 @@ trx_print_latched(
or 0 to use the default max length */
{
ut_ad(lock_mutex_own());
- ut_ad(trx_sys_mutex_own());
trx_print_low(f, trx, max_query_len,
lock_number_of_rows_locked(&trx->lock),
@@ -2415,119 +2112,9 @@ trx_print_latched(
mem_heap_get_size(trx->lock.lock_heap));
}
-#ifdef WITH_WSREP
/**********************************************************************//**
Prints info about a transaction.
-Transaction information may be retrieved without having trx_sys->mutex acquired
-so it may not be completely accurate. The caller must own lock_sys->mutex
-and the trx must have some locks to make sure that it does not escape
-without locking lock_sys->mutex. */
-UNIV_INTERN
-void
-wsrep_trx_print_locking(
- FILE* f,
- /*!< in: output stream */
- const trx_t* trx,
- /*!< in: transaction */
- ulint max_query_len)
- /*!< in: max query length to print,
- or 0 to use the default max length */
-{
- ibool newline;
- const char* op_info;
-
- ut_ad(lock_mutex_own());
- ut_ad(trx->lock.trx_locks.count > 0);
-
- fprintf(f, "TRANSACTION " TRX_ID_FMT, trx->id);
-
- /* trx->state may change since trx_sys->mutex is not required */
- switch (trx->state) {
- case TRX_STATE_NOT_STARTED:
- fputs(", not started", f);
- goto state_ok;
- case TRX_STATE_ACTIVE:
- fprintf(f, ", ACTIVE %lu sec",
- (ulong) difftime(time(NULL), trx->start_time));
- goto state_ok;
- case TRX_STATE_FORCED_ROLLBACK:
- fprintf(f, ", FORCED ROLLBACK, %lu sec",
- (ulong) difftime(time(NULL), trx->start_time));
- goto state_ok;
- case TRX_STATE_PREPARED:
- fprintf(f, ", ACTIVE (PREPARED) %lu sec",
- (ulong) difftime(time(NULL), trx->start_time));
- goto state_ok;
- case TRX_STATE_COMMITTED_IN_MEMORY:
- fputs(", COMMITTED IN MEMORY", f);
- goto state_ok;
- }
- fprintf(f, ", state %lu", (ulong) trx->state);
- ut_ad(0);
-state_ok:
-
- /* prevent a race condition */
- op_info = trx->op_info;
-
- if (*op_info) {
- putc(' ', f);
- fputs(op_info, f);
- }
-
- if (trx->is_recovered) {
- fputs(" recovered trx", f);
- }
-
- if (trx->declared_to_be_inside_innodb) {
- fprintf(f, ", thread declared inside InnoDB %lu",
- (ulong) trx->n_tickets_to_enter_innodb);
- }
-
- putc('\n', f);
-
- if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) {
- fprintf(f, "mysql tables in use %lu, locked %lu\n",
- (ulong) trx->n_mysql_tables_in_use,
- (ulong) trx->mysql_n_tables_locked);
- }
-
- newline = TRUE;
-
- /* trx->lock.que_state of an ACTIVE transaction may change
- while we are not holding trx->mutex. We perform a dirty read
- for performance reasons. */
-
- switch (trx->lock.que_state) {
- case TRX_QUE_RUNNING:
- newline = FALSE; break;
- case TRX_QUE_LOCK_WAIT:
- fputs("LOCK WAIT ", f); break;
- case TRX_QUE_ROLLING_BACK:
- fputs("ROLLING BACK ", f); break;
- case TRX_QUE_COMMITTING:
- fputs("COMMITTING ", f); break;
- default:
- fprintf(f, "que state %lu ", (ulong) trx->lock.que_state);
- }
-
- if (trx->undo_no != 0) {
- newline = TRUE;
- fprintf(f, ", undo log entries " TRX_ID_FMT, trx->undo_no);
- }
-
- if (newline) {
- putc('\n', f);
- }
-
- if (trx->mysql_thd != NULL) {
- innobase_mysql_print_thd(
- f, trx->mysql_thd, static_cast<uint>(max_query_len));
- }
-}
-#endif /* WITH_WSREP */
-/**********************************************************************//**
-Prints info about a transaction.
-Acquires and releases lock_sys->mutex and trx_sys->mutex. */
+Acquires and releases lock_sys.mutex. */
void
trx_print(
/*======*/
@@ -2546,34 +2133,30 @@ trx_print(
heap_size = mem_heap_get_size(trx->lock.lock_heap);
lock_mutex_exit();
- mutex_enter(&trx_sys->mutex);
-
trx_print_low(f, trx, max_query_len,
n_rec_locks, n_trx_locks, heap_size);
-
- mutex_exit(&trx_sys->mutex);
}
#ifdef UNIV_DEBUG
/**********************************************************************//**
Asserts that a transaction has been started.
-The caller must hold trx_sys->mutex.
+The caller must hold trx_sys.mutex.
@return TRUE if started */
ibool
trx_assert_started(
/*===============*/
const trx_t* trx) /*!< in: transaction */
{
- ut_ad(trx_sys_mutex_own());
+ ut_ad(mutex_own(&trx_sys.mutex));
/* Non-locking autocommits should not hold any locks and this
function is only called from the locking code. */
check_trx_state(trx);
/* trx->state can change from or to NOT_STARTED while we are holding
- trx_sys->mutex for non-locking autocommit selects but not for other
+ trx_sys.mutex for non-locking autocommit selects but not for other
types of transactions. It may change from ACTIVE to PREPARED. Unless
- we are holding lock_sys->mutex, it may also change to COMMITTED. */
+ we are holding lock_sys.mutex, it may also change to COMMITTED. */
switch (trx->state) {
case TRX_STATE_PREPARED:
@@ -2704,13 +2287,10 @@ trx_prepare(
DBUG_EXECUTE_IF("ib_trx_crash_during_xa_prepare_step", DBUG_SUICIDE(););
- /*--------------------------------------*/
ut_a(trx->state == TRX_STATE_ACTIVE);
- trx_sys_mutex_enter();
+ trx_mutex_enter(trx);
trx->state = TRX_STATE_PREPARED;
- trx_sys->n_prepared_trx++;
- trx_sys_mutex_exit();
- /*--------------------------------------*/
+ trx_mutex_exit(trx);
if (lsn) {
/* Depending on the my.cnf options, we may now write the log
@@ -2758,141 +2338,118 @@ trx_prepare_for_mysql(trx_t* trx)
return(DB_SUCCESS);
}
-/**********************************************************************//**
-This function is used to find number of prepared transactions and
-their transaction objects for a recovery.
-@return number of prepared transactions stored in xid_list */
-int
-trx_recover_for_mysql(
-/*==================*/
- XID* xid_list, /*!< in/out: prepared transactions */
- ulint len) /*!< in: number of slots in xid_list */
-{
- const trx_t* trx;
- ulint count = 0;
-
- ut_ad(xid_list);
- ut_ad(len);
-
- /* We should set those transactions which are in the prepared state
- to the xid_list */
-
- trx_sys_mutex_enter();
-
- for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
- trx != NULL;
- trx = UT_LIST_GET_NEXT(trx_list, trx)) {
-
- assert_trx_in_rw_list(trx);
-
- /* The state of a read-write transaction cannot change
- from or to NOT_STARTED while we are holding the
- trx_sys->mutex. It may change to PREPARED, but not if
- trx->is_recovered. It may also change to COMMITTED. */
- if (trx_state_eq(trx, TRX_STATE_PREPARED)) {
- xid_list[count] = *trx->xid;
-
- if (count == 0) {
- ib::info() << "Starting recovery for"
- " XA transactions...";
- }
- ib::info() << "Transaction "
- << trx_get_id_for_print(trx)
- << " in prepared state after recovery";
+struct trx_recover_for_mysql_callback_arg
+{
+ XID *xid_list;
+ uint len;
+ uint count;
+};
- ib::info() << "Transaction contains changes to "
- << trx->undo_no << " rows";
- count++;
+static my_bool trx_recover_for_mysql_callback(rw_trx_hash_element_t *element,
+ trx_recover_for_mysql_callback_arg *arg)
+{
+ mutex_enter(&element->mutex);
+ if (trx_t *trx= element->trx)
+ {
+ /*
+ The state of a read-write transaction can only change from ACTIVE to
+ PREPARED while we are holding the element->mutex. But since it is
+ executed at startup no state change should occur.
+ */
+ if (trx_state_eq(trx, TRX_STATE_PREPARED))
+ {
+ ut_ad(trx->is_recovered);
+ if (arg->count == 0)
+ ib::info() << "Starting recovery for XA transactions...";
+ ib::info() << "Transaction " << trx_get_id_for_print(trx)
+ << " in prepared state after recovery";
+ ib::info() << "Transaction contains changes to " << trx->undo_no
+ << " rows";
+ arg->xid_list[arg->count++]= *trx->xid;
+ }
+ }
+ mutex_exit(&element->mutex);
+ return arg->count == arg->len;
+}
- if (count == len) {
- break;
- }
- }
- }
- trx_sys_mutex_exit();
+/**
+ Find prepared transaction objects for recovery.
- if (count > 0){
- ib::info() << count << " transactions in prepared state"
- " after recovery";
- }
+ @param[out] xid_list prepared transactions
+ @param[in] len number of slots in xid_list
- return(int (count));
-}
+ @return number of prepared transactions stored in xid_list
+*/
-/*******************************************************************//**
-This function is used to find one X/Open XA distributed transaction
-which is in the prepared state
-@return trx on match, the trx->xid will be invalidated;
-note that the trx may have been committed, unless the caller is
-holding lock_sys->mutex */
-static MY_ATTRIBUTE((warn_unused_result))
-trx_t*
-trx_get_trx_by_xid_low(
-/*===================*/
- XID* xid) /*!< in: X/Open XA transaction
- identifier */
+int trx_recover_for_mysql(XID *xid_list, uint len)
{
- trx_t* trx;
-
- ut_ad(trx_sys_mutex_own());
+ trx_recover_for_mysql_callback_arg arg= { xid_list, len, 0 };
- for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
- trx != NULL;
- trx = UT_LIST_GET_NEXT(trx_list, trx)) {
+ ut_ad(xid_list);
+ ut_ad(len);
- assert_trx_in_rw_list(trx);
+ /* Fill xid_list with PREPARED transactions. */
+ trx_sys.rw_trx_hash.iterate_no_dups(reinterpret_cast<my_hash_walk_action>
+ (trx_recover_for_mysql_callback), &arg);
+ if (arg.count)
+ ib::info() << arg.count
+ << " transactions in prepared state after recovery";
+ return(arg.count);
+}
- /* Compare two X/Open XA transaction id's: their
- length should be the same and binary comparison
- of gtrid_length+bqual_length bytes should be
- the same */
- if (trx->is_recovered
- && trx_state_eq(trx, TRX_STATE_PREPARED)
- && xid->eq((XID*)trx->xid)) {
+struct trx_get_trx_by_xid_callback_arg
+{
+ XID *xid;
+ trx_t *trx;
+};
- /* Invalidate the XID, so that subsequent calls
- will not find it. */
- trx->xid->null();
- break;
- }
- }
- return(trx);
+static my_bool trx_get_trx_by_xid_callback(rw_trx_hash_element_t *element,
+ trx_get_trx_by_xid_callback_arg *arg)
+{
+ my_bool found= 0;
+ mutex_enter(&element->mutex);
+ if (trx_t *trx= element->trx)
+ {
+ if (trx->is_recovered && trx_state_eq(trx, TRX_STATE_PREPARED) &&
+ arg->xid->eq(reinterpret_cast<XID*>(trx->xid)))
+ {
+ /* Invalidate the XID, so that subsequent calls will not find it. */
+ trx->xid->null();
+ arg->trx= trx;
+ found= 1;
+ }
+ }
+ mutex_exit(&element->mutex);
+ return found;
}
-/*******************************************************************//**
-This function is used to find one X/Open XA distributed transaction
-which is in the prepared state
-@return trx or NULL; on match, the trx->xid will be invalidated;
-note that the trx may have been committed, unless the caller is
-holding lock_sys->mutex */
-trx_t*
-trx_get_trx_by_xid(
-/*===============*/
- XID* xid) /*!< in: X/Open XA transaction identifier */
-{
- trx_t* trx;
- if (xid == NULL) {
+/**
+ Finds PREPARED XA transaction by xid.
- return(NULL);
- }
+ trx may have been committed, unless the caller is holding lock_sys.mutex.
- trx_sys_mutex_enter();
+ @param[in] xid X/Open XA transaction identifier
- /* Recovered/Resurrected transactions are always only on the
- trx_sys_t::rw_trx_list. */
- trx = trx_get_trx_by_xid_low((XID*)xid);
+ @return trx or NULL; on match, the trx->xid will be invalidated;
+*/
- trx_sys_mutex_exit();
+trx_t *trx_get_trx_by_xid(XID *xid)
+{
+ trx_get_trx_by_xid_callback_arg arg= { xid, 0 };
- return(trx);
+ if (xid)
+ trx_sys.rw_trx_hash.iterate(reinterpret_cast<my_hash_walk_action>
+ (trx_get_trx_by_xid_callback), &arg);
+ return arg.trx;
}
+
/*************************************************************//**
Starts the transaction if it is not yet started. */
void
@@ -2912,7 +2469,7 @@ trx_start_if_not_started_xa_low(
/* If the transaction is tagged as read-only then
it can only write to temp tables and for such
transactions we don't want to move them to the
- trx_sys_t::rw_trx_list. */
+ trx_sys_t::rw_trx_hash. */
if (!trx->read_only) {
trx_set_rw_mode(trx);
}
@@ -3037,51 +2594,30 @@ trx_set_rw_mode(
trx_t* trx) /*!< in/out: transaction that is RW */
{
ut_ad(trx->rsegs.m_redo.rseg == 0);
- ut_ad(!trx->in_rw_trx_list);
ut_ad(!trx_is_autocommit_non_locking(trx));
+ ut_ad(!trx->read_only);
+ ut_ad(trx->id == 0);
if (high_level_read_only) {
return;
}
/* Function is promoting existing trx from ro mode to rw mode.
- In this process it has acquired trx_sys->mutex as it plan to
+ In this process it has acquired trx_sys.mutex as it plan to
move trx from ro list to rw list. If in future, some other thread
looks at this trx object while it is being promoted then ensure
that both threads are synced by acquring trx->mutex to avoid decision
based on in-consistent view formed during promotion. */
trx->rsegs.m_redo.rseg = trx_assign_rseg_low();
-
ut_ad(trx->rsegs.m_redo.rseg != 0);
- mutex_enter(&trx_sys->mutex);
-
- ut_ad(trx->id == 0);
- trx->id = trx_sys_get_new_trx_id();
-
- trx_sys->rw_trx_ids.push_back(trx->id);
-
- trx_sys->rw_trx_set.insert(TrxTrack(trx->id, trx));
+ trx_sys.register_rw(trx);
/* So that we can see our own changes. */
- if (MVCC::is_view_active(trx->read_view)) {
- MVCC::set_view_creator_trx_id(trx->read_view, trx->id);
- }
-
-#ifdef UNIV_DEBUG
- if (trx->id > trx_sys->rw_max_trx_id) {
- trx_sys->rw_max_trx_id = trx->id;
- }
-#endif /* UNIV_DEBUG */
-
- if (!trx->read_only) {
- UT_LIST_ADD_FIRST(trx_sys->rw_trx_list, trx);
-
- ut_d(trx->in_rw_trx_list = true);
+ if (trx->read_view.is_open()) {
+ trx->read_view.set_creator_trx_id(trx->id);
}
-
- mutex_exit(&trx_sys->mutex);
}
/**
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index 9b0c43e4609..88ac0257540 100644
--- a/storage/innobase/trx/trx0undo.cc
+++ b/storage/innobase/trx/trx0undo.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2014, 2018, 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
@@ -117,6 +117,53 @@ trx_undo_mem_create(
ulint page_no,/*!< in: undo log header page number */
ulint offset);/*!< in: undo log header byte offset on page */
+/** Determine the start offset of undo log records of an undo log page.
+@param[in] undo_page undo log page
+@param[in] page_no undo log header page number
+@param[in] offset undo log header offset
+@return start offset */
+static
+uint16_t
+trx_undo_page_get_start(const page_t* undo_page, ulint page_no, ulint offset)
+{
+ return page_no == page_get_page_no(undo_page)
+ ? mach_read_from_2(offset + TRX_UNDO_LOG_START + undo_page)
+ : TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE;
+}
+
+/** Get the first undo log record on a page.
+@param[in] page undo log page
+@param[in] page_no undo log header page number
+@param[in] offset undo log header page offset
+@return pointer to first record
+@retval NULL if none exists */
+static
+trx_undo_rec_t*
+trx_undo_page_get_first_rec(page_t* page, ulint page_no, ulint offset)
+{
+ ulint start = trx_undo_page_get_start(page, page_no, offset);
+ return start == trx_undo_page_get_end(page, page_no, offset)
+ ? NULL
+ : page + start;
+}
+
+/** Get the last undo log record on a page.
+@param[in] page undo log page
+@param[in] page_no undo log header page number
+@param[in] offset undo log header page offset
+@return pointer to last record
+@retval NULL if none exists */
+static
+trx_undo_rec_t*
+trx_undo_page_get_last_rec(page_t* page, ulint page_no, ulint offset)
+{
+ ulint end = trx_undo_page_get_end(page, page_no, offset);
+
+ return trx_undo_page_get_start(page, page_no, offset) == end
+ ? NULL
+ : page + mach_read_from_2(page + end - 2);
+}
+
/***********************************************************************//**
Gets the previous record in an undo log from the previous page.
@return undo log record, the page s-latched, NULL if none */
@@ -159,6 +206,31 @@ trx_undo_get_prev_rec_from_prev_page(
return(trx_undo_page_get_last_rec(prev_page, page_no, offset));
}
+/** Get the previous undo log record.
+@param[in] rec undo log record
+@param[in] page_no undo log header page number
+@param[in] offset undo log header page offset
+@return pointer to record
+@retval NULL if none */
+static
+trx_undo_rec_t*
+trx_undo_page_get_prev_rec(trx_undo_rec_t* rec, ulint page_no, ulint offset)
+{
+ page_t* undo_page;
+ ulint start;
+
+ undo_page = (page_t*) ut_align_down(rec, UNIV_PAGE_SIZE);
+
+ start = trx_undo_page_get_start(undo_page, page_no, offset);
+
+ if (start + undo_page == rec) {
+
+ return(NULL);
+ }
+
+ return(undo_page + mach_read_from_2(rec - 2));
+}
+
/***********************************************************************//**
Gets the previous record in an undo log.
@return undo log record, the page s-latched, NULL if none */
@@ -309,43 +381,84 @@ trx_undo_get_first_rec(
/*============== UNDO LOG FILE COPY CREATION AND FREEING ==================*/
-/**********************************************************************//**
-Writes the mtr log entry of an undo log page initialization. */
-UNIV_INLINE
-void
-trx_undo_page_init_log(
-/*===================*/
- page_t* undo_page, /*!< in: undo log page */
- mtr_t* mtr) /*!< in: mtr */
+/** Parse MLOG_UNDO_INIT for crash-upgrade from MariaDB 10.2.
+@param[in] ptr log record
+@param[in] end_ptr end of log record buffer
+@param[in,out] page page or NULL
+@param[in,out] mtr mini-transaction
+@return end of log record
+@retval NULL if the log record is incomplete */
+byte*
+trx_undo_parse_page_init(
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* page,
+ mtr_t* mtr)
{
- mlog_write_initial_log_record(undo_page, MLOG_UNDO_INIT, mtr);
+ ulint type = mach_parse_compressed(&ptr, end_ptr);
- mlog_catenate_ulint_compressed(mtr, 0);
+ if (!ptr) {
+ } else if (type != 1 && type != 2) {
+ recv_sys->found_corrupt_log = true;
+ } else if (page) {
+ mach_write_to_2(FIL_PAGE_TYPE + page, FIL_PAGE_UNDO_LOG);
+ mach_write_to_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + page,
+ type);
+ mach_write_to_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_START + page,
+ TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
+ mach_write_to_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE + page,
+ TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
+ }
+
+ return(const_cast<byte*>(ptr));
}
-/***********************************************************//**
-Parses the redo log entry of an undo log page initialization.
+/** Parse MLOG_UNDO_HDR_REUSE for crash-upgrade from MariaDB 10.2.
+@param[in] ptr redo log record
+@param[in] end_ptr end of log buffer
+@param[in,out] page undo log page or NULL
+@param[in,out] mtr mini-transaction
@return end of log record or NULL */
byte*
-trx_undo_parse_page_init(
-/*=====================*/
- const byte* ptr, /*!< in: buffer */
- const byte* end_ptr,/*!< in: buffer end */
- page_t* page, /*!< in: page or NULL */
- mtr_t* mtr) /*!< in: mtr or NULL */
+trx_undo_parse_page_header_reuse(
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* undo_page,
+ mtr_t* mtr)
{
- if (mach_parse_compressed(&ptr, end_ptr)) {
- recv_sys->found_corrupt_log = true;
+ trx_id_t trx_id = mach_u64_parse_compressed(&ptr, end_ptr);
+
+ if (!ptr || !undo_page) {
+ return(const_cast<byte*>(ptr));
}
- if (ptr == NULL) {
+ compile_time_assert(TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE
+ + TRX_UNDO_LOG_XA_HDR_SIZE
+ < UNIV_PAGE_SIZE_MIN - 100);
- return(NULL);
- }
+ const ulint new_free = TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE
+ + TRX_UNDO_LOG_OLD_HDR_SIZE;
- if (page) {
- trx_undo_page_init(page, mtr);
- }
+ /* Insert undo data is not needed after commit: we may free all
+ the space on the page */
+
+ ut_ad(mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE
+ + undo_page)
+ == TRX_UNDO_INSERT);
+
+ byte* page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
+ mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START, new_free);
+ mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE, new_free);
+ mach_write_to_2(TRX_UNDO_SEG_HDR + TRX_UNDO_STATE + undo_page,
+ TRX_UNDO_ACTIVE);
+
+ byte* log_hdr = undo_page + TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE;
+
+ mach_write_to_8(log_hdr + TRX_UNDO_TRX_ID, trx_id);
+ mach_write_to_2(log_hdr + TRX_UNDO_LOG_START, new_free);
+
+ mach_write_to_1(log_hdr + TRX_UNDO_XID_EXISTS, FALSE);
+ mach_write_to_1(log_hdr + TRX_UNDO_DICT_TRANS, FALSE);
return(const_cast<byte*>(ptr));
}
@@ -361,59 +474,46 @@ trx_undo_page_init(
{
trx_upagef_t* page_hdr;
- page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
-
- *reinterpret_cast<uint16*>(page_hdr + TRX_UNDO_PAGE_TYPE) = 0;
-
- mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START,
- TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
- mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE,
- TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
+ mlog_write_ulint(undo_page + FIL_PAGE_TYPE,
+ FIL_PAGE_UNDO_LOG, MLOG_2BYTES, mtr);
+ compile_time_assert(TRX_UNDO_PAGE_TYPE == 0);
+ compile_time_assert(TRX_UNDO_PAGE_START == 2);
+ compile_time_assert(TRX_UNDO_PAGE_NODE == TRX_UNDO_PAGE_FREE + 2);
- fil_page_set_type(undo_page, FIL_PAGE_UNDO_LOG);
-
- trx_undo_page_init_log(undo_page, mtr);
+ page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
+ mlog_write_ulint(page_hdr, TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE,
+ MLOG_4BYTES, mtr);
+ mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_FREE,
+ TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE,
+ MLOG_2BYTES, mtr);
}
-/***************************************************************//**
-Creates a new undo log segment in file.
-@return DB_SUCCESS if page creation OK possible error codes are:
-DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE */
-static MY_ATTRIBUTE((warn_unused_result))
-dberr_t
-trx_undo_seg_create(
-/*================*/
- trx_rseg_t* rseg MY_ATTRIBUTE((unused)),/*!< in: rollback segment */
- trx_rsegf_t* rseg_hdr,/*!< in: rollback segment header, page
- x-latched */
- ulint* id, /*!< out: slot index within rseg header */
- page_t** undo_page,
- /*!< out: segment header page x-latched, NULL
- if there was an error */
- mtr_t* mtr) /*!< in: mtr */
+/** Create an undo log segment.
+@param[in,out] rseg_hdr rollback segment header (x-latched)
+@param[out] id undo slot number
+@param[out] err error code
+@param[in,out] mtr mini-transaction
+@return undo log block
+@retval NULL on failure */
+static MY_ATTRIBUTE((nonnull, warn_unused_result))
+buf_block_t*
+trx_undo_seg_create(trx_rsegf_t* rseg_hdr, ulint* id, dberr_t* err, mtr_t* mtr)
{
ulint slot_no;
ulint space;
buf_block_t* block;
- trx_upagef_t* page_hdr;
- trx_usegf_t* seg_hdr;
ulint n_reserved;
bool success;
- dberr_t err = DB_SUCCESS;
- ut_ad(mtr != NULL);
- ut_ad(id != NULL);
- ut_ad(rseg_hdr != NULL);
- ut_ad(mutex_own(&(rseg->mutex)));
-
- slot_no = trx_rsegf_undo_find_free(rseg_hdr, mtr);
+ slot_no = trx_rsegf_undo_find_free(rseg_hdr);
if (slot_no == ULINT_UNDEFINED) {
ib::warn() << "Cannot find a free slot for an undo log. Do"
" you have too many active transactions running"
" concurrently?";
- return(DB_TOO_MANY_CONCURRENT_TRXS);
+ *err = DB_TOO_MANY_CONCURRENT_TRXS;
+ return NULL;
}
space = page_get_space_id(page_align(rseg_hdr));
@@ -421,8 +521,8 @@ trx_undo_seg_create(
success = fsp_reserve_free_extents(&n_reserved, space, 2, FSP_UNDO,
mtr);
if (!success) {
-
- return(DB_OUT_OF_FILE_SPACE);
+ *err = DB_OUT_OF_FILE_SPACE;
+ return NULL;
}
/* Allocate a new file segment for the undo log */
@@ -433,38 +533,35 @@ trx_undo_seg_create(
fil_space_release_free_extents(space, n_reserved);
if (block == NULL) {
- /* No space left */
-
- return(DB_OUT_OF_FILE_SPACE);
+ *err = DB_OUT_OF_FILE_SPACE;
+ return NULL;
}
buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE);
- *undo_page = buf_block_get_frame(block);
+ trx_undo_page_init(block->frame, mtr);
- page_hdr = *undo_page + TRX_UNDO_PAGE_HDR;
- seg_hdr = *undo_page + TRX_UNDO_SEG_HDR;
-
- trx_undo_page_init(*undo_page, mtr);
-
- mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_FREE,
+ mlog_write_ulint(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE + block->frame,
TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE,
MLOG_2BYTES, mtr);
- mlog_write_ulint(seg_hdr + TRX_UNDO_LAST_LOG, 0, MLOG_2BYTES, mtr);
+ mlog_write_ulint(TRX_UNDO_SEG_HDR + TRX_UNDO_LAST_LOG + block->frame,
+ 0, MLOG_2BYTES, mtr);
- flst_init(seg_hdr + TRX_UNDO_PAGE_LIST, mtr);
+ flst_init(TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + block->frame, mtr);
- flst_add_last(seg_hdr + TRX_UNDO_PAGE_LIST,
- page_hdr + TRX_UNDO_PAGE_NODE, mtr);
+ flst_add_last(TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + block->frame,
+ TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE + block->frame,
+ mtr);
- trx_rsegf_set_nth_undo(rseg_hdr, slot_no,
- page_get_page_no(*undo_page), mtr);
*id = slot_no;
+ trx_rsegf_set_nth_undo(rseg_hdr, slot_no, block->page.id.page_no(),
+ mtr);
MONITOR_INC(MONITOR_NUM_UNDO_SLOT_USED);
- return(err);
+ *err = DB_SUCCESS;
+ return block;
}
/**********************************************************************//**
@@ -587,10 +684,7 @@ trx_undo_write_xid(
Read X/Open XA Transaction Identification (XID) from undo log header */
static
void
-trx_undo_read_xid(
-/*==============*/
- trx_ulogf_t* log_hdr,/*!< in: undo log header */
- XID* xid) /*!< out: X/Open XA Transaction Identification */
+trx_undo_read_xid(const trx_ulogf_t* log_hdr, XID* xid)
{
xid->formatID=static_cast<long>(mach_read_from_4(
log_hdr + TRX_UNDO_XA_FORMAT));
@@ -686,9 +780,6 @@ trx_undo_add_page(trx_t* trx, trx_undo_t* undo, mtr_t* mtr)
counterpart of the tree latch, which is the rseg mutex. */
mutex_enter(&rseg->mutex);
- if (rseg->curr_size == rseg->max_size) {
- goto func_exit;
- }
header_page = trx_undo_page_get(
page_id_t(undo->space, undo->hdr_page_no), mtr);
@@ -799,34 +890,6 @@ trx_undo_free_last_page(trx_undo_t* undo, mtr_t* mtr)
undo->size--;
}
-/** Empties an undo log header page of undo records for that undo log.
-Other undo logs may still have records on that page, if it is an update
-undo log.
-@param[in] space space
-@param[in] hdr_page_no header page number
-@param[in] hdr_offset header offset
-@param[in,out] mtr mini-transaction */
-static
-void
-trx_undo_empty_header_page(
- ulint space,
- ulint hdr_page_no,
- ulint hdr_offset,
- mtr_t* mtr)
-{
- page_t* header_page;
- trx_ulogf_t* log_hdr;
- ulint end;
-
- header_page = trx_undo_page_get(page_id_t(space, hdr_page_no), mtr);
-
- log_hdr = header_page + hdr_offset;
-
- end = trx_undo_page_get_end(header_page, hdr_page_no, hdr_offset);
-
- mlog_write_ulint(log_hdr + TRX_UNDO_LOG_START, end, MLOG_2BYTES, mtr);
-}
-
/** Truncate the tail of an undo log during rollback.
@param[in,out] undo undo log
@param[in] limit all undo logs after this limit will be discarded
@@ -938,9 +1001,16 @@ loop:
page_no = page_get_page_no(undo_page);
if (page_no == hdr_page_no) {
- trx_undo_empty_header_page(rseg->space,
- hdr_page_no, hdr_offset,
- &mtr);
+ uint16_t end = mach_read_from_2(hdr_offset + TRX_UNDO_NEXT_LOG
+ + undo_page);
+ if (end == 0) {
+ end = mach_read_from_2(TRX_UNDO_PAGE_HDR
+ + TRX_UNDO_PAGE_FREE
+ + undo_page);
+ }
+
+ mlog_write_ulint(undo_page + hdr_offset + TRX_UNDO_LOG_START,
+ end, MLOG_2BYTES, &mtr);
} else {
trx_undo_free_page(rseg, TRUE, rseg->space, hdr_page_no,
page_no, &mtr);
@@ -1005,66 +1075,58 @@ trx_undo_seg_free(
/*========== UNDO LOG MEMORY COPY INITIALIZATION =====================*/
-/********************************************************************//**
-Creates and initializes an undo log memory object according to the values
-in the header in file, when the database is started. The memory object is
-inserted in the appropriate list of rseg.
-@return own: the undo log memory object */
-static
-trx_undo_t*
-trx_undo_mem_create_at_db_start(
-/*============================*/
- trx_rseg_t* rseg, /*!< in: rollback segment memory object */
- ulint id, /*!< in: slot index within rseg */
- ulint page_no,/*!< in: undo log segment page number */
- mtr_t* mtr) /*!< in: mtr */
+/** Read an undo log when starting up the database.
+@param[in,out] rseg rollback segment
+@param[in] id rollback segment slot
+@param[in] page_no undo log segment page number
+@param[in,out] max_trx_id the largest observed transaction ID
+@return size of the undo log in pages */
+ulint
+trx_undo_mem_create_at_db_start(trx_rseg_t* rseg, ulint id, ulint page_no,
+ trx_id_t& max_trx_id)
{
- page_t* undo_page;
- trx_usegf_t* seg_header;
- trx_ulogf_t* undo_header;
- trx_undo_t* undo;
- ulint state;
- trx_id_t trx_id;
- ulint offset;
+ mtr_t mtr;
XID xid;
- ut_a(id < TRX_RSEG_N_SLOTS);
+ ut_ad(id < TRX_RSEG_N_SLOTS);
- undo_page = trx_undo_page_get(page_id_t(rseg->space, page_no), mtr);
+ mtr.start();
+ const page_t* undo_page = trx_undo_page_get(
+ page_id_t(rseg->space, page_no), &mtr);
const ulint type = mach_read_from_2(
TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + undo_page);
ut_ad(type == 0 || type == TRX_UNDO_INSERT || type == TRX_UNDO_UPDATE);
- seg_header = undo_page + TRX_UNDO_SEG_HDR;
-
- state = mach_read_from_2(seg_header + TRX_UNDO_STATE);
-
- offset = mach_read_from_2(seg_header + TRX_UNDO_LAST_LOG);
-
- undo_header = undo_page + offset;
- trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID);
+ uint state = mach_read_from_2(TRX_UNDO_SEG_HDR + TRX_UNDO_STATE
+ + undo_page);
+ uint offset = mach_read_from_2(TRX_UNDO_SEG_HDR + TRX_UNDO_LAST_LOG
+ + undo_page);
- const bool xid_exists = mtr_read_ulint(
- undo_header + TRX_UNDO_XID_EXISTS, MLOG_1BYTE, mtr);
+ const trx_ulogf_t* undo_header = undo_page + offset;
/* Read X/Open XA transaction identification if it exists, or
set it to NULL. */
- xid.null();
- if (xid_exists) {
+ if (undo_header[TRX_UNDO_XID_EXISTS]) {
trx_undo_read_xid(undo_header, &xid);
+ } else {
+ xid.null();
}
- mutex_enter(&(rseg->mutex));
-
- undo = trx_undo_mem_create(rseg, id, trx_id, &xid, page_no, offset);
- mutex_exit(&(rseg->mutex));
+ trx_id_t trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID);
+ if (trx_id > max_trx_id) {
+ max_trx_id = trx_id;
+ }
- undo->dict_operation = mtr_read_ulint(
- undo_header + TRX_UNDO_DICT_TRANS, MLOG_1BYTE, mtr);
+ mutex_enter(&rseg->mutex);
+ trx_undo_t* undo = trx_undo_mem_create(
+ rseg, id, trx_id, &xid, page_no, offset);
+ mutex_exit(&rseg->mutex);
+ undo->dict_operation = undo_header[TRX_UNDO_DICT_TRANS];
undo->table_id = mach_read_from_8(undo_header + TRX_UNDO_TABLE_ID);
- undo->size = flst_get_len(seg_header + TRX_UNDO_PAGE_LIST);
+ undo->size = flst_get_len(TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST
+ + undo_page);
if (UNIV_UNLIKELY(state == TRX_UNDO_TO_FREE)) {
/* This is an old-format insert_undo log segment that
@@ -1072,14 +1134,24 @@ trx_undo_mem_create_at_db_start(
ut_ad(type == TRX_UNDO_INSERT);
state = TRX_UNDO_TO_PURGE;
} else {
+ if (state == TRX_UNDO_TO_PURGE
+ || state == TRX_UNDO_CACHED) {
+ trx_id_t id = mach_read_from_8(TRX_UNDO_TRX_NO
+ + undo_header);
+ if (id > max_trx_id) {
+ max_trx_id = id;
+ }
+ }
+
fil_addr_t last_addr = flst_get_last(
- seg_header + TRX_UNDO_PAGE_LIST, mtr);
+ TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + undo_page,
+ &mtr);
undo->last_page_no = last_addr.page;
undo->top_page_no = last_addr.page;
page_t* last_page = trx_undo_page_get(
- page_id_t(rseg->space, undo->last_page_no), mtr);
+ page_id_t(rseg->space, undo->last_page_no), &mtr);
const trx_undo_rec_t* rec = trx_undo_page_get_last_rec(
last_page, page_no, offset);
@@ -1102,63 +1174,8 @@ trx_undo_mem_create_at_db_start(
MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED);
}
- return(undo);
-}
-
-/********************************************************************//**
-Initializes the undo log lists for a rollback segment memory copy. This
-function is only called when the database is started or a new rollback
-segment is created.
-@return the combined size of undo log segments in pages */
-ulint
-trx_undo_lists_init(
-/*================*/
- trx_rseg_t* rseg) /*!< in: rollback segment memory object */
-{
- ulint size = 0;
- trx_rsegf_t* rseg_header;
- ulint i;
- mtr_t mtr;
-
- mtr_start(&mtr);
-
- rseg_header = trx_rsegf_get_new(rseg->space, rseg->page_no, &mtr);
-
- for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
- ulint page_no;
-
- page_no = trx_rsegf_get_nth_undo(rseg_header, i, &mtr);
-
- /* In forced recovery: try to avoid operations which look
- at database pages; undo logs are rapidly changing data, and
- the probability that they are in an inconsistent state is
- high */
-
- if (page_no != FIL_NULL
- && srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
-
- trx_undo_t* undo;
-
- undo = trx_undo_mem_create_at_db_start(
- rseg, i, page_no, &mtr);
-
- size += undo->size;
-
- mtr_commit(&mtr);
-
- mtr_start(&mtr);
-
- rseg_header = trx_rsegf_get(
- rseg->space, rseg->page_no, &mtr);
-
- /* Found a used slot */
- MONITOR_INC(MONITOR_NUM_UNDO_SLOT_USED);
- }
- }
-
- mtr_commit(&mtr);
-
- return(size);
+ mtr.commit();
+ return undo->size;
}
/********************************************************************//**
@@ -1238,158 +1255,181 @@ trx_undo_mem_init_for_reuse(
undo->empty = TRUE;
}
-/********************************************************************//**
-Frees an undo log memory copy. */
-void
-trx_undo_mem_free(
-/*==============*/
- trx_undo_t* undo) /*!< in: the undo object to be freed */
-{
- ut_a(undo->id < TRX_RSEG_N_SLOTS);
-
- ut_free(undo);
-}
-
-/**********************************************************************//**
-Creates a new undo log.
-@return DB_SUCCESS if successful in creating the new undo lob object,
-possible error codes are: DB_TOO_MANY_CONCURRENT_TRXS
-DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY */
+/** Create an undo log.
+@param[in,out] trx transaction
+@param[in,out] rseg rollback segment
+@param[out] undo undo log object
+@param[out] err error code
+@param[in,out] mtr mini-transaction
+@return undo log block
+@retval NULL on failure */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
-dberr_t
-trx_undo_create(
-/*============*/
- trx_t* trx, /*!< in: transaction */
- trx_rseg_t* rseg, /*!< in: rollback segment memory copy */
- trx_id_t trx_id, /*!< in: id of the trx for which the undo log
- is created */
- const XID* xid, /*!< in: X/Open transaction identification*/
- trx_undo_t** undo, /*!< out: the new undo log object, undefined
- * if did not succeed */
- mtr_t* mtr) /*!< in: mtr */
+buf_block_t*
+trx_undo_create(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo,
+ dberr_t* err, mtr_t* mtr)
{
- trx_rsegf_t* rseg_header;
- ulint page_no;
- ulint offset;
ulint id;
- page_t* undo_page;
- dberr_t err;
ut_ad(mutex_own(&(rseg->mutex)));
- if (rseg->curr_size == rseg->max_size) {
+ buf_block_t* block = trx_undo_seg_create(
+ trx_rsegf_get(rseg->space, rseg->page_no, mtr), &id, err, mtr);
- return(DB_OUT_OF_FILE_SPACE);
+ if (!block) {
+ return block;
}
rseg->curr_size++;
- rseg_header = trx_rsegf_get(rseg->space, rseg->page_no, mtr);
-
- err = trx_undo_seg_create(rseg, rseg_header, &id, &undo_page, mtr);
+ ulint offset = trx_undo_header_create(block->frame, trx->id, mtr);
- if (err != DB_SUCCESS) {
- /* Did not succeed */
+ trx_undo_header_add_space_for_xid(block->frame, block->frame + offset,
+ mtr);
- rseg->curr_size--;
-
- return(err);
- }
-
- page_no = page_get_page_no(undo_page);
-
- offset = trx_undo_header_create(undo_page, trx_id, mtr);
-
- trx_undo_header_add_space_for_xid(undo_page, undo_page + offset, mtr);
-
- *undo = trx_undo_mem_create(rseg, id, trx_id, xid, page_no, offset);
+ *undo = trx_undo_mem_create(rseg, id, trx->id, trx->xid,
+ block->page.id.page_no(), offset);
if (*undo == NULL) {
+ *err = DB_OUT_OF_MEMORY;
+ /* FIXME: this will not free the undo block to the file */
+ return NULL;
+ } else if (rseg != trx->rsegs.m_redo.rseg) {
+ return block;
+ }
- err = DB_OUT_OF_MEMORY;
+ switch (trx_get_dict_operation(trx)) {
+ case TRX_DICT_OP_NONE:
+ break;
+ case TRX_DICT_OP_INDEX:
+ /* Do not discard the table on recovery. */
+ trx->table_id = 0;
+ /* fall through */
+ case TRX_DICT_OP_TABLE:
+ (*undo)->table_id = trx->table_id;
+ (*undo)->dict_operation = TRUE;
+ mlog_write_ulint(block->frame + offset + TRX_UNDO_DICT_TRANS,
+ TRUE, MLOG_1BYTE, mtr);
+ mlog_write_ull(block->frame + offset + TRX_UNDO_TABLE_ID,
+ trx->table_id, mtr);
}
- return(err);
+ *err = DB_SUCCESS;
+ return block;
}
/*================ UNDO LOG ASSIGNMENT AND CLEANUP =====================*/
-/********************************************************************//**
-Reuses a cached undo log.
-@return the undo log memory object, NULL if none cached */
+/** Reuse a cached undo log block.
+@param[in,out] trx transaction
+@param[in,out] rseg rollback segment
+@param[out] pundo the undo log memory object
+@param[in,out] mtr mini-transaction
+@return the undo log block
+@retval NULL if none cached */
static
-trx_undo_t*
-trx_undo_reuse_cached(
-/*==================*/
- trx_t* trx, /*!< in: transaction */
- trx_rseg_t* rseg, /*!< in: rollback segment memory object */
- trx_id_t trx_id, /*!< in: id of the trx for which the undo log
- is used */
- const XID* xid, /*!< in: X/Open XA transaction identification */
- mtr_t* mtr) /*!< in: mtr */
+buf_block_t*
+trx_undo_reuse_cached(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** pundo,
+ mtr_t* mtr)
{
- trx_undo_t* undo;
- page_t* undo_page;
- ulint offset;
+ ut_ad(mutex_own(&rseg->mutex));
- ut_ad(mutex_own(&(rseg->mutex)));
-
- undo = UT_LIST_GET_FIRST(rseg->undo_cached);
- if (undo == NULL) {
- return(NULL);
+ trx_undo_t* undo = UT_LIST_GET_FIRST(rseg->undo_cached);
+ if (!undo) {
+ return NULL;
}
- UT_LIST_REMOVE(rseg->undo_cached, undo);
- MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED);
ut_ad(undo->size == 1);
- ut_a(undo->id < TRX_RSEG_N_SLOTS);
+ ut_ad(undo->id < TRX_RSEG_N_SLOTS);
- undo_page = trx_undo_page_get(
- page_id_t(undo->space, undo->hdr_page_no), mtr);
+ buf_block_t* block = buf_page_get(page_id_t(undo->space,
+ undo->hdr_page_no),
+ univ_page_size, RW_X_LATCH, mtr);
+ if (!block) {
+ return NULL;
+ }
- offset = trx_undo_header_create(undo_page, trx_id, mtr);
+ buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE);
- trx_undo_header_add_space_for_xid(undo_page, undo_page + offset, mtr);
- trx_undo_mem_init_for_reuse(undo, trx_id, xid, offset);
+ UT_LIST_REMOVE(rseg->undo_cached, undo);
+ MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED);
- return(undo);
-}
+ *pundo = undo;
-/**********************************************************************//**
-Marks an undo log header as a header of a data dictionary operation
-transaction. */
-static
-void
-trx_undo_mark_as_dict_operation(
-/*============================*/
- trx_t* trx, /*!< in: dict op transaction */
- trx_undo_t* undo, /*!< in: assigned undo log */
- mtr_t* mtr) /*!< in: mtr */
-{
- page_t* hdr_page;
+ ulint offset = trx_undo_header_create(block->frame, trx->id, mtr);
- hdr_page = trx_undo_page_get(
- page_id_t(undo->space, undo->hdr_page_no), mtr);
+ trx_undo_header_add_space_for_xid(block->frame, block->frame + offset,
+ mtr);
+
+ trx_undo_mem_init_for_reuse(undo, trx->id, trx->xid, offset);
+
+ if (rseg != trx->rsegs.m_redo.rseg) {
+ return block;
+ }
switch (trx_get_dict_operation(trx)) {
case TRX_DICT_OP_NONE:
- ut_error;
+ return block;
case TRX_DICT_OP_INDEX:
/* Do not discard the table on recovery. */
- undo->table_id = 0;
- break;
+ trx->table_id = 0;
+ /* fall through */
case TRX_DICT_OP_TABLE:
undo->table_id = trx->table_id;
- break;
+ undo->dict_operation = TRUE;
+ mlog_write_ulint(block->frame + offset + TRX_UNDO_DICT_TRANS,
+ TRUE, MLOG_1BYTE, mtr);
+ mlog_write_ull(block->frame + offset + TRX_UNDO_TABLE_ID,
+ trx->table_id, mtr);
}
- mlog_write_ulint(hdr_page + undo->hdr_offset
- + TRX_UNDO_DICT_TRANS,
- TRUE, MLOG_1BYTE, mtr);
+ return block;
+}
- mlog_write_ull(hdr_page + undo->hdr_offset + TRX_UNDO_TABLE_ID,
- undo->table_id, mtr);
+/** Assign an undo log for a persistent transaction.
+A new undo log is created or a cached undo log reused.
+@param[in,out] trx transaction
+@param[out] err error code
+@param[in,out] mtr mini-transaction
+@return the undo log block
+@retval NULL on error */
+buf_block_t*
+trx_undo_assign(trx_t* trx, dberr_t* err, mtr_t* mtr)
+{
+ ut_ad(mutex_own(&trx->undo_mutex));
+ ut_ad(mtr->get_log_mode() == MTR_LOG_ALL);
+
+ trx_undo_t* undo = trx->rsegs.m_redo.undo;
+
+ if (undo) {
+ return buf_page_get_gen(
+ page_id_t(undo->space, undo->last_page_no),
+ univ_page_size, RW_X_LATCH,
+ buf_pool_is_obsolete(undo->withdraw_clock)
+ ? NULL : undo->guess_block,
+ BUF_GET, __FILE__, __LINE__, mtr, err);
+ }
+
+ trx_rseg_t* rseg = trx->rsegs.m_redo.rseg;
+
+ mutex_enter(&rseg->mutex);
+ buf_block_t* block = trx_undo_reuse_cached(
+ trx, rseg, &trx->rsegs.m_redo.undo, mtr);
+
+ if (!block) {
+ block = trx_undo_create(trx, rseg, &trx->rsegs.m_redo.undo,
+ err, mtr);
+ ut_ad(!block == (*err != DB_SUCCESS));
+ if (!block) {
+ goto func_exit;
+ }
+ } else {
+ *err = DB_SUCCESS;
+ }
+
+ UT_LIST_ADD_FIRST(rseg->undo_list, trx->rsegs.m_redo.undo);
- undo->dict_operation = TRUE;
+func_exit:
+ mutex_exit(&rseg->mutex);
+ return block;
}
/** Assign an undo log for a transaction.
@@ -1397,17 +1437,15 @@ A new undo log is created or a cached undo log reused.
@param[in,out] trx transaction
@param[in] rseg rollback segment
@param[out] undo the undo log
-@retval DB_SUCCESS on success
-@retval DB_TOO_MANY_CONCURRENT_TRXS
-@retval DB_OUT_OF_FILE_SPACE
-@retval DB_READ_ONLY
-@retval DB_OUT_OF_MEMORY */
-dberr_t
-trx_undo_assign_undo(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo)
+@param[out] err error code
+@param[in,out] mtr mini-transaction
+@return the undo log block
+@retval NULL on error */
+buf_block_t*
+trx_undo_assign_low(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo,
+ dberr_t* err, mtr_t* mtr)
{
const bool is_temp = rseg == trx->rsegs.m_noredo.rseg;
- mtr_t mtr;
- dberr_t err = DB_SUCCESS;
ut_ad(mutex_own(&trx->undo_mutex));
ut_ad(rseg == trx->rsegs.m_redo.rseg
@@ -1415,41 +1453,42 @@ trx_undo_assign_undo(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo)
ut_ad(undo == (is_temp
? &trx->rsegs.m_noredo.undo
: &trx->rsegs.m_redo.undo));
-
- mtr.start(trx);
-
- if (is_temp) {
- mtr.set_log_mode(MTR_LOG_NO_REDO);
+ ut_ad(mtr->get_log_mode()
+ == (is_temp ? MTR_LOG_NO_REDO : MTR_LOG_ALL));
+
+ if (*undo) {
+ return buf_page_get_gen(
+ page_id_t((*undo)->space, (*undo)->last_page_no),
+ univ_page_size, RW_X_LATCH,
+ buf_pool_is_obsolete((*undo)->withdraw_clock)
+ ? NULL : (*undo)->guess_block,
+ BUF_GET, __FILE__, __LINE__, mtr, err);
}
- mutex_enter(&rseg->mutex);
-
DBUG_EXECUTE_IF(
"ib_create_table_fail_too_many_trx",
- err = DB_TOO_MANY_CONCURRENT_TRXS;
- goto func_exit;
+ *err = DB_TOO_MANY_CONCURRENT_TRXS; return NULL;
);
- *undo = trx_undo_reuse_cached(trx, rseg, trx->id, trx->xid, &mtr);
- if (*undo == NULL) {
- err = trx_undo_create(trx, rseg, trx->id, trx->xid,
- undo, &mtr);
- if (err != DB_SUCCESS) {
+ mutex_enter(&rseg->mutex);
+
+ buf_block_t* block = trx_undo_reuse_cached(trx, rseg, undo, mtr);
+
+ if (!block) {
+ block = trx_undo_create(trx, rseg, undo, err, mtr);
+ ut_ad(!block == (*err != DB_SUCCESS));
+ if (!block) {
goto func_exit;
}
+ } else {
+ *err = DB_SUCCESS;
}
UT_LIST_ADD_FIRST(rseg->undo_list, *undo);
- if (!is_temp && trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
- trx_undo_mark_as_dict_operation(trx, *undo, &mtr);
- }
-
func_exit:
mutex_exit(&rseg->mutex);
- mtr.commit();
-
- return(err);
+ return block;
}
/******************************************************************//**
@@ -1575,21 +1614,16 @@ trx_undo_commit_cleanup(trx_undo_t* undo, bool is_temp)
ut_ad(rseg->curr_size > undo->size);
rseg->curr_size -= undo->size;
- trx_undo_mem_free(undo);
+ ut_free(undo);
}
mutex_exit(&rseg->mutex);
}
-/********************************************************************//**
-At shutdown, frees the undo logs of a PREPARED transaction. */
+/** At shutdown, frees the undo logs of a transaction. */
void
-trx_undo_free_prepared(
-/*===================*/
- trx_t* trx) /*!< in/out: PREPARED transaction */
+trx_undo_free_at_shutdown(trx_t *trx)
{
- ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
-
if (trx_undo_t*& undo = trx->rsegs.m_redo.undo) {
switch (undo->state) {
case TRX_UNDO_PREPARED:
@@ -1602,17 +1636,18 @@ trx_undo_free_prepared(
/* fall through */
case TRX_UNDO_ACTIVE:
/* lock_trx_release_locks() assigns
- trx->is_recovered=false */
+ trx->state = TRX_STATE_COMMITTED_IN_MEMORY. */
ut_a(!srv_was_started
|| srv_read_only_mode
- || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
+ || srv_fast_shutdown);
break;
default:
ut_error;
}
UT_LIST_REMOVE(trx->rsegs.m_redo.rseg->undo_list, undo);
- trx_undo_mem_free(undo);
+ ut_free(undo);
undo = NULL;
}
@@ -1628,17 +1663,18 @@ trx_undo_free_prepared(
/* fall through */
case TRX_UNDO_ACTIVE:
/* lock_trx_release_locks() assigns
- trx->is_recovered=false */
+ trx->state = TRX_STATE_COMMITTED_IN_MEMORY. */
ut_a(!srv_was_started
|| srv_read_only_mode
- || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
+ || srv_fast_shutdown);
break;
default:
ut_error;
}
UT_LIST_REMOVE(trx->rsegs.m_redo.rseg->old_insert_list, undo);
- trx_undo_mem_free(undo);
+ ut_free(undo);
undo = NULL;
}
@@ -1646,7 +1682,7 @@ trx_undo_free_prepared(
ut_a(undo->state == TRX_UNDO_PREPARED);
UT_LIST_REMOVE(trx->rsegs.m_noredo.rseg->undo_list, undo);
- trx_undo_mem_free(undo);
+ ut_free(undo);
undo = NULL;
}
}
@@ -1684,6 +1720,7 @@ trx_undo_truncate_tablespace(
mtr_start(&mtr);
mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
mtr_x_lock(fil_space_get_latch(space_id, NULL), &mtr);
+ buf_block_t* sys_header = trx_sysf_get(&mtr);
for (ulint i = 0; i < undo_trunc->rsegs_size(); ++i) {
trx_rsegf_t* rseg_header;
@@ -1691,7 +1728,7 @@ trx_undo_truncate_tablespace(
trx_rseg_t* rseg = undo_trunc->get_ith_rseg(i);
rseg->page_no = trx_rseg_header_create(
- space_id, ULINT_MAX, rseg->id, &mtr);
+ space_id, rseg->id, sys_header, &mtr);
rseg_header = trx_rsegf_get_new(space_id, rseg->page_no, &mtr);
@@ -1708,15 +1745,12 @@ trx_undo_truncate_tablespace(
next_undo = UT_LIST_GET_NEXT(undo_list, undo);
UT_LIST_REMOVE(rseg->undo_cached, undo);
MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED);
- trx_undo_mem_free(undo);
+ ut_free(undo);
}
UT_LIST_INIT(rseg->undo_list, &trx_undo_t::undo_list);
UT_LIST_INIT(rseg->undo_cached, &trx_undo_t::undo_list);
- rseg->max_size = mtr_read_ulint(
- rseg_header + TRX_RSEG_MAX_SIZE, MLOG_4BYTES, &mtr);
-
/* Initialize the undo log lists according to the rseg header */
rseg->curr_size = mtr_read_ulint(
rseg_header + TRX_RSEG_HISTORY_SIZE, MLOG_4BYTES, &mtr)
@@ -1727,7 +1761,7 @@ trx_undo_truncate_tablespace(
rseg->trx_ref_count = 0;
rseg->last_page_no = FIL_NULL;
rseg->last_offset = 0;
- rseg->last_trx_no = 0;
+ rseg->last_commit = 0;
rseg->needs_purge = false;
}
mtr_commit(&mtr);
diff --git a/storage/innobase/usr/usr0sess.cc b/storage/innobase/usr/usr0sess.cc
deleted file mode 100644
index 55ce9500e5c..00000000000
--- a/storage/innobase/usr/usr0sess.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 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, Suite 500, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file usr/usr0sess.cc
-Sessions
-
-Created 6/25/1996 Heikki Tuuri
-*******************************************************/
-
-#include "usr0sess.h"
-#include "trx0trx.h"
-
-/*********************************************************************//**
-Opens a session.
-@return own: session object */
-sess_t*
-sess_open(void)
-/*===========*/
-{
- sess_t* sess;
-
- sess = static_cast<sess_t*>(ut_zalloc_nokey(sizeof(*sess)));
-
- sess->state = SESS_ACTIVE;
-
- sess->trx = trx_allocate_for_background();
- sess->trx->sess = sess;
-
- return(sess);
-}
-
-/*********************************************************************//**
-Closes a session, freeing the memory occupied by it. */
-void
-sess_close(
-/*=======*/
- sess_t* sess) /*!< in, own: session object */
-{
- trx_free_for_background(sess->trx);
- ut_free(sess);
-}
diff --git a/storage/innobase/ut/ut0crc32.cc b/storage/innobase/ut/ut0crc32.cc
index 386d32f6a60..284ea859013 100644
--- a/storage/innobase/ut/ut0crc32.cc
+++ b/storage/innobase/ut/ut0crc32.cc
@@ -86,19 +86,9 @@ mysys/my_perf.c, contributed by Facebook under the following license.
#include "univ.i"
#include "ut0crc32.h"
-/** Pointer to CRC32 calculation function. */
-ut_crc32_func_t ut_crc32;
-
-/** Pointer to CRC32 calculation function, which uses big-endian byte order
-when converting byte strings to integers internally. */
-ut_crc32_func_t ut_crc32_legacy_big_endian;
-
-/** Pointer to CRC32-byte-by-byte calculation function (byte order agnostic,
-but very slow). */
-ut_crc32_func_t ut_crc32_byte_by_byte;
-
-/** Text description of CRC32 implementation */
-const char* ut_crc32_implementation;
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
/** Swap the byte order of an 8 byte integer.
@param[in] i 8-byte integer
@@ -133,9 +123,16 @@ ut_crc32_power8(
{
return crc32c_vpmsum(0, buf, len);
}
+
+ut_crc32_func_t ut_crc32 = ut_crc32_power8;
+const char* ut_crc32_implementation = "Using POWER8 crc32 instructions";
+#else
+uint32_t ut_crc32_sw(const byte* buf, ulint len);
+ut_crc32_func_t ut_crc32 = ut_crc32_sw;
+const char* ut_crc32_implementation = "Using generic crc32 instructions";
#endif
-#if defined(__GNUC__) && defined(__x86_64__)
+#if (defined(__GNUC__) && defined(__x86_64__)) || defined(_MSC_VER)
/********************************************************************//**
Fetches CPU info */
static
@@ -150,10 +147,29 @@ ut_cpuid(
uint32_t* features_edx) /*!< out: CPU features edx */
{
uint32_t sig;
+#ifdef _MSC_VER
+ int data[4];
+ __cpuid(data, 0);
+ /* ebx */
+ vend[0] = data[1];
+ /* edx */
+ vend[1] = data[3];
+ /* ecx */
+ vend[2] = data[2];
+
+ __cpuid(data, 1);
+ /* eax */
+ sig = data[0];
+ /* ecx */
+ *features_ecx = data[2];
+ /* edx */
+ *features_edx = data[3];
+#else
asm("cpuid" : "=b" (vend[0]), "=c" (vend[2]), "=d" (vend[1]) : "a" (0));
asm("cpuid" : "=a" (sig), "=c" (*features_ecx), "=d" (*features_edx)
: "a" (1)
: "ebx");
+#endif
*model = ((sig >> 4) & 0xF);
*family = ((sig >> 8) & 0xF);
@@ -180,11 +196,15 @@ ut_crc32_8_hw(
const byte** data,
ulint* len)
{
+#ifdef _MSC_VER
+ *crc = _mm_crc32_u8(*crc, (*data)[0]);
+#else
asm("crc32b %1, %0"
/* output operands */
: "+r" (*crc)
/* input operands */
: "rm" ((*data)[0]));
+#endif
(*data)++;
(*len)--;
@@ -201,12 +221,22 @@ ut_crc32_64_low_hw(
uint64_t data)
{
uint64_t crc_64bit = crc;
-
+#ifdef _MSC_VER
+#ifdef _M_X64
+ crc_64bit = _mm_crc32_u64(crc_64bit, data);
+#elif defined(_M_IX86)
+ crc = _mm_crc32_u32(crc, static_cast<uint32_t>(data));
+ crc_64bit = _mm_crc32_u32(crc, static_cast<uint32_t>(data >> 32));
+#else
+#error Not Supported processors type.
+#endif
+#else
asm("crc32q %1, %0"
/* output operands */
: "+r" (crc_64bit)
/* input operands */
: "rm" (data));
+#endif
return(static_cast<uint32_t>(crc_64bit));
}
@@ -242,37 +272,6 @@ ut_crc32_64_hw(
*len -= 8;
}
-/** Calculate CRC32 over 64-bit byte string using a hardware/CPU instruction.
-The byte string is converted to a 64-bit integer using big endian byte order.
-@param[in,out] crc crc32 checksum so far when this function is called,
-when the function ends it will contain the new checksum
-@param[in,out] data data to be checksummed, the pointer will be advanced
-with 8 bytes
-@param[in,out] len remaining bytes, it will be decremented with 8 */
-inline
-void
-ut_crc32_64_legacy_big_endian_hw(
- uint32_t* crc,
- const byte** data,
- ulint* len)
-{
- uint64_t data_int = *reinterpret_cast<const uint64_t*>(*data);
-
-#ifndef WORDS_BIGENDIAN
- data_int = ut_crc32_swap_byteorder(data_int);
-#else
- /* Currently we only support x86_64 (little endian) CPUs. In case
- some big endian CPU supports a CRC32 instruction, then maybe we will
- NOT need a byte order swap here. */
-#error Dont know how to handle big endian CPUs
-#endif /* WORDS_BIGENDIAN */
-
- *crc = ut_crc32_64_low_hw(*crc, data_int);
-
- *data += 8;
- *len -= 8;
-}
-
/** Calculates CRC32 using hardware/CPU instructions.
@param[in] buf data over which to calculate CRC32
@param[in] len data length
@@ -359,77 +358,7 @@ ut_crc32_hw(
return(~crc);
}
-
-/** Calculates CRC32 using hardware/CPU instructions.
-This function uses big endian byte ordering when converting byte sequence to
-integers.
-@param[in] buf data over which to calculate CRC32
-@param[in] len data length
-@return CRC-32C (polynomial 0x11EDC6F41) */
-uint32_t
-ut_crc32_legacy_big_endian_hw(
- const byte* buf,
- ulint len)
-{
- uint32_t crc = 0xFFFFFFFFU;
-
- /* Calculate byte-by-byte up to an 8-byte aligned address. After
- this consume the input 8-bytes at a time. */
- while (len > 0 && (reinterpret_cast<uintptr_t>(buf) & 7) != 0) {
- ut_crc32_8_hw(&crc, &buf, &len);
- }
-
- while (len >= 128) {
- /* This call is repeated 16 times. 16 * 8 = 128. */
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- }
-
- while (len >= 8) {
- ut_crc32_64_legacy_big_endian_hw(&crc, &buf, &len);
- }
-
- while (len > 0) {
- ut_crc32_8_hw(&crc, &buf, &len);
- }
-
- return(~crc);
-}
-
-/** Calculates CRC32 using hardware/CPU instructions.
-This function processes one byte at a time (very slow) and thus it does
-not depend on the byte order of the machine.
-@param[in] buf data over which to calculate CRC32
-@param[in] len data length
-@return CRC-32C (polynomial 0x11EDC6F41) */
-uint32_t
-ut_crc32_byte_by_byte_hw(
- const byte* buf,
- ulint len)
-{
- uint32_t crc = 0xFFFFFFFFU;
-
- while (len > 0) {
- ut_crc32_8_hw(&crc, &buf, &len);
- }
-
- return(~crc);
-}
-#endif /* defined(__GNUC__) && defined(__x86_64__) */
+#endif /* defined(__GNUC__) && defined(__x86_64__) || (_WIN64) */
/* CRC32 software implementation. */
@@ -624,7 +553,7 @@ integers.
@param[in] len data length
@return CRC-32C (polynomial 0x11EDC6F41) */
uint32_t
-ut_crc32_legacy_big_endian_sw(
+ut_crc32_legacy_big_endian(
const byte* buf,
ulint len)
{
@@ -669,28 +598,6 @@ ut_crc32_legacy_big_endian_sw(
return(~crc);
}
-/** Calculates CRC32 in software, without using CPU instructions.
-This function processes one byte at a time (very slow) and thus it does
-not depend on the byte order of the machine.
-@param[in] buf data over which to calculate CRC32
-@param[in] len data length
-@return CRC-32C (polynomial 0x11EDC6F41) */
-uint32_t
-ut_crc32_byte_by_byte_sw(
- const byte* buf,
- ulint len)
-{
- uint32_t crc = 0xFFFFFFFFU;
-
- ut_a(ut_crc32_slice8_table_initialized);
-
- while (len > 0) {
- ut_crc32_8_sw(&crc, &buf, &len);
- }
-
- return(~crc);
-}
-
/********************************************************************//**
Initializes the data structures used by ut_crc32*(). Does not do any
allocations, would not hurt if called twice, but would be pointless. */
@@ -699,12 +606,8 @@ ut_crc32_init()
/*===========*/
{
ut_crc32_slice8_table_init();
- ut_crc32 = ut_crc32_sw;
- ut_crc32_legacy_big_endian = ut_crc32_legacy_big_endian_sw;
- ut_crc32_byte_by_byte = ut_crc32_byte_by_byte_sw;
- ut_crc32_implementation = "Using generic crc32 instructions";
-#if defined(__GNUC__) && defined(__x86_64__)
+#if (defined(__GNUC__) && defined(__x86_64__)) || defined(_MSC_VER)
uint32_t vend[3];
uint32_t model;
uint32_t family;
@@ -734,14 +637,7 @@ ut_crc32_init()
if (features_ecx & 1 << 20) {
ut_crc32 = ut_crc32_hw;
- ut_crc32_legacy_big_endian = ut_crc32_legacy_big_endian_hw;
- ut_crc32_byte_by_byte = ut_crc32_byte_by_byte_hw;
ut_crc32_implementation = "Using SSE2 crc32 instructions";
}
-
-#elif defined(HAVE_CRC32_VPMSUM)
- ut_crc32 = ut_crc32_power8;
- ut_crc32_implementation = "Using POWER8 crc32 instructions";
#endif
-
}
diff --git a/storage/innobase/ut/ut0dbg.cc b/storage/innobase/ut/ut0dbg.cc
index 9e596dcda81..7df189ac560 100644
--- a/storage/innobase/ut/ut0dbg.cc
+++ b/storage/innobase/ut/ut0dbg.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -53,7 +53,7 @@ ut_dbg_assertion_failed(
" or crashes, even\n"
"InnoDB: immediately after the mysqld startup, there may be\n"
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
- "InnoDB: " REFMAN "forcing-innodb-recovery.html\n"
+ "InnoDB: https://mariadb.com/kb/en/library/xtradbinnodb-recovery-modes/\n"
"InnoDB: about forcing recovery.\n", stderr);
fflush(stderr);
diff --git a/storage/innobase/ut/ut0new.cc b/storage/innobase/ut/ut0new.cc
index bf5515f4de0..35d49073678 100644
--- a/storage/innobase/ut/ut0new.cc
+++ b/storage/innobase/ut/ut0new.cc
@@ -43,7 +43,6 @@ PSI_memory_key mem_key_other;
PSI_memory_key mem_key_row_log_buf;
PSI_memory_key mem_key_row_merge_sort;
PSI_memory_key mem_key_std;
-PSI_memory_key mem_key_trx_sys_t_rw_trx_ids;
PSI_memory_key mem_key_partitioning;
#ifdef UNIV_PFS_MEMORY
@@ -72,7 +71,6 @@ static PSI_memory_info pfs_info[] = {
{&mem_key_row_log_buf, "row_log_buf", 0},
{&mem_key_row_merge_sort, "row_merge_sort", 0},
{&mem_key_std, "std", 0},
- {&mem_key_trx_sys_t_rw_trx_ids, "trx_sys_t::rw_trx_ids", 0},
{&mem_key_partitioning, "partitioning", 0},
};
@@ -167,7 +165,6 @@ ut_new_boot()
"trx0sys",
"trx0trx",
"trx0undo",
- "usr0sess",
"ut0list",
"ut0mem",
"ut0mutex",
diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc
index 7ad80c3cd1f..a8ff700847a 100644
--- a/storage/innobase/ut/ut0ut.cc
+++ b/storage/innobase/ut/ut0ut.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -37,8 +37,12 @@ Created 5/11/1994 Heikki Tuuri
#include "trx0trx.h"
#include <string>
#include "log.h"
+#include "my_cpu.h"
#ifdef _WIN32
+typedef VOID(WINAPI *time_fn)(LPFILETIME);
+static time_fn ut_get_system_time_as_file_time = GetSystemTimeAsFileTime;
+
/*****************************************************************//**
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
epoch starts from 1970/1/1. For selection of constant see:
@@ -64,7 +68,7 @@ ut_gettimeofday(
return(-1);
}
- GetSystemTimeAsFileTime(&ft);
+ ut_get_system_time_as_file_time(&ft);
tm = (int64_t) ft.dwHighDateTime << 32;
tm |= ft.dwLowDateTime;
@@ -290,14 +294,14 @@ ut_delay(
{
ulint i;
- UT_LOW_PRIORITY_CPU();
+ HMT_low();
for (i = 0; i < delay * 50; i++) {
- UT_RELAX_CPU();
+ MY_RELAX_CPU();
UT_COMPILER_BARRIER();
}
- UT_RESUME_PRIORITY_CPU();
+ HMT_medium();
}
/*************************************************************//**
@@ -522,65 +526,6 @@ ut_copy_file(
} while (len > 0);
}
-#ifdef _WIN32
-# include <stdarg.h>
-/**********************************************************************//**
-A substitute for vsnprintf(3), formatted output conversion into
-a limited buffer. Note: this function DOES NOT return the number of
-characters that would have been printed if the buffer was unlimited because
-VC's _vsnprintf() returns -1 in this case and we would need to call
-_vscprintf() in addition to estimate that but we would need another copy
-of "ap" for that and VC does not provide va_copy(). */
-void
-ut_vsnprintf(
-/*=========*/
- char* str, /*!< out: string */
- size_t size, /*!< in: str size */
- const char* fmt, /*!< in: format */
- va_list ap) /*!< in: format values */
-{
- _vsnprintf(str, size, fmt, ap);
- str[size - 1] = '\0';
-}
-
-/**********************************************************************//**
-A substitute for snprintf(3), formatted output conversion into
-a limited buffer.
-@return number of characters that would have been printed if the size
-were unlimited, not including the terminating '\0'. */
-int
-ut_snprintf(
-/*========*/
- char* str, /*!< out: string */
- size_t size, /*!< in: str size */
- const char* fmt, /*!< in: format */
- ...) /*!< in: format values */
-{
- int res;
- va_list ap1;
- va_list ap2;
-
- va_start(ap1, fmt);
- va_start(ap2, fmt);
-
- res = _vscprintf(fmt, ap1);
- ut_a(res != -1);
-
- if (size > 0) {
- _vsnprintf(str, size, fmt, ap2);
-
- if ((size_t) res >= size) {
- str[size - 1] = '\0';
- }
- }
-
- va_end(ap1);
- va_end(ap2);
-
- return(res);
-}
-#endif /* _WIN32 */
-
/** Convert an error number to a human readable text message.
The returned string is static and should not be freed or modified.
@param[in] num InnoDB internal error number
diff --git a/storage/maria/ft_maria.c b/storage/maria/ft_maria.c
index 4a5c660af6d..b85a2ea797a 100644
--- a/storage/maria/ft_maria.c
+++ b/storage/maria/ft_maria.c
@@ -28,9 +28,9 @@ FT_INFO *maria_ft_init_search(uint flags, void *info, uint keynr,
FT_INFO *res;
if (flags & FT_BOOL)
res= maria_ft_init_boolean_search((MARIA_HA *) info, keynr, query,
- query_len, cs);
+ (uint)query_len, cs);
else
- res= maria_ft_init_nlq_search((MARIA_HA *) info, keynr, query, query_len,
+ res= maria_ft_init_nlq_search((MARIA_HA *) info, keynr, query, (uint)query_len,
flags, record);
return res;
}
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 321837bd425..17b56096114 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2149,11 +2149,16 @@ void ha_maria::start_bulk_insert(ha_rows rows, uint flags)
safety net for now, we don't remove the test of
file->state->records, because there is uncertainty on what will
happen during repair if the two states disagree.
+
+ We also have to check in case of transactional tables that the
+ user has not used LOCK TABLE on the table twice.
*/
if ((file->state->records == 0) &&
(share->state.state.records == 0) && can_enable_indexes &&
(!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES) &&
- (file->lock.type == TL_WRITE || file->lock.type == TL_UNLOCK))
+ (file->lock.type == TL_WRITE || file->lock.type == TL_UNLOCK) &&
+ (!share->have_versioning || !share->now_transactional ||
+ file->used_tables->use_count == 1))
{
/**
@todo for a single-row INSERT SELECT, we will go into repair, which
diff --git a/storage/maria/lockman.c b/storage/maria/lockman.c
index efdf7e1c4b8..fa0a3289106 100644
--- a/storage/maria/lockman.c
+++ b/storage/maria/lockman.c
@@ -268,7 +268,7 @@ retry:
do {
cursor->curr= PTR(*cursor->prev);
lf_pin(pins, 1, cursor->curr);
- } while(*cursor->prev != (intptr)cursor->curr && LF_BACKOFF);
+ } while(*cursor->prev != (intptr)cursor->curr && LF_BACKOFF());
for (;;)
{
if (!cursor->curr)
@@ -277,7 +277,7 @@ retry:
cur_link= cursor->curr->link;
cursor->next= PTR(cur_link);
lf_pin(pins, 0, cursor->next);
- } while (cur_link != cursor->curr->link && LF_BACKOFF);
+ } while (cur_link != cursor->curr->link && LF_BACKOFF());
cur_hashnr= cursor->curr->hashnr;
cur_resource= cursor->curr->resource;
cur_lock= cursor->curr->lock;
@@ -285,7 +285,7 @@ retry:
cur_flags= cursor->curr->flags;
if (*cursor->prev != (intptr)cursor->curr)
{
- (void)LF_BACKOFF;
+ (void)LF_BACKOFF();
goto retry;
}
if (!DELETED(cur_link))
@@ -362,7 +362,7 @@ retry:
lf_alloc_free(pins, cursor->curr);
else
{
- (void)LF_BACKOFF;
+ (void)LF_BACKOFF();
goto retry;
}
}
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index 4b0f03c66ed..4470b771ad3 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -145,6 +145,11 @@ static my_bool _ma_bitmap_create_missing(MARIA_HA *info,
MARIA_FILE_BITMAP *bitmap,
pgcache_page_no_t page);
static void _ma_bitmap_unpin_all(MARIA_SHARE *share);
+#ifndef DBUG_OFF
+static void _ma_check_bitmap(MARIA_FILE_BITMAP *bitmap);
+#else
+#define _ma_check_bitmap(A) do { } while(0)
+#endif
/* Write bitmap page to key cache */
@@ -267,6 +272,13 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file,
bitmap->sizes[6]= max_page_size - max_page_size * 80 / 100;
bitmap->sizes[7]= 0;
+ /*
+ If a record size will fit into the smallest empty page, return first
+ found page in find_head()
+ */
+ if (bitmap->sizes[3] >= share->base.max_pack_length)
+ bitmap->return_first_match= 1;
+
mysql_mutex_init(key_SHARE_BITMAP_lock,
&share->bitmap.bitmap_lock, MY_MUTEX_INIT_SLOW);
mysql_cond_init(key_SHARE_BITMAP_cond,
@@ -677,7 +689,8 @@ void _ma_bitmap_delete_all(MARIA_SHARE *share)
bzero(bitmap->map, bitmap->block_size);
bitmap->changed= 1;
bitmap->page= 0;
- bitmap->used_size= bitmap->total_size= bitmap->max_total_size;
+ bitmap->used_size= bitmap->full_tail_size= bitmap->full_head_size= 0;
+ bitmap->total_size= bitmap->max_total_size;
}
DBUG_VOID_RETURN;
}
@@ -715,6 +728,7 @@ void _ma_bitmap_reset_cache(MARIA_SHARE *share)
*/
bitmap->page= ((pgcache_page_no_t) 0) - bitmap->pages_covered;
bitmap->used_size= bitmap->total_size= bitmap->max_total_size;
+ bitmap->full_head_size= bitmap->full_tail_size= bitmap->max_total_size;
bfill(bitmap->map, share->block_size, 255);
#ifndef DBUG_OFF
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
@@ -1016,9 +1030,6 @@ static void adjust_total_size(MARIA_HA *info, pgcache_page_no_t page)
bitmap Bitmap handler
page Page to read
- TODO
- Update 'bitmap->used_size' to real size of used bitmap
-
NOTE
We don't always have share->bitmap.bitmap_lock here
(when called from_ma_check_bitmap_data() for example).
@@ -1035,6 +1046,9 @@ static my_bool _ma_read_bitmap_page(MARIA_HA *info,
MARIA_SHARE *share= info->s;
my_bool res;
DBUG_ENTER("_ma_read_bitmap_page");
+ DBUG_PRINT("enter", ("page: %lld data_file_length: %lld",
+ (longlong) page,
+ (longlong) share->state.state.data_file_length));
DBUG_ASSERT(page % bitmap->pages_covered == 0);
DBUG_ASSERT(!bitmap->changed);
@@ -1049,13 +1063,22 @@ static my_bool _ma_read_bitmap_page(MARIA_HA *info,
}
adjust_total_size(info, page);
- bitmap->used_size= bitmap->total_size;
+ bitmap->full_head_size= bitmap->full_tail_size= 0;
DBUG_ASSERT(share->pagecache->block_size == bitmap->block_size);
res= pagecache_read(share->pagecache,
&bitmap->file, page, 0,
bitmap->map, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == NULL;
+ if (!res)
+ {
+ /* Calculate used_size */
+ const uchar *data, *end= bitmap->map;
+ for (data= bitmap->map + bitmap->total_size; --data >= end && *data == 0; )
+ {}
+ bitmap->used_size= (uint) ((data + 1) - end);
+ DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
+ }
/*
We can't check maria_bitmap_marker here as if the bitmap page
previously had a true checksum and the user switched mode to not checksum
@@ -1067,7 +1090,10 @@ static my_bool _ma_read_bitmap_page(MARIA_HA *info,
#ifndef DBUG_OFF
if (!res)
+ {
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
+ _ma_check_bitmap(bitmap);
+ }
#endif
DBUG_RETURN(res);
}
@@ -1097,6 +1123,8 @@ static my_bool _ma_change_bitmap_page(MARIA_HA *info,
{
DBUG_ENTER("_ma_change_bitmap_page");
+ _ma_check_bitmap(bitmap);
+
/*
We have to mark the file changed here, as otherwise the following
read/write to pagecache may force a page out from this file, which would
@@ -1228,6 +1256,9 @@ static void fill_block(MARIA_FILE_BITMAP *bitmap,
This is defined as the first page of the set of pages
with the smallest free space that can hold 'size'.
+ NOTES
+ Updates bitmap->full_head_size while scanning data
+
RETURN
0 ok (block is updated)
1 error (no space in bitmap; block is not touched)
@@ -1238,10 +1269,11 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
MARIA_BITMAP_BLOCK *block)
{
uint min_bits= size_to_head_pattern(bitmap, size);
- uchar *data= bitmap->map, *end= data + bitmap->used_size;
+ uchar *data, *end;
uchar *best_data= 0;
uint best_bits= (uint) -1, UNINIT_VAR(best_pos);
- uint first_pattern= 0; /* if doing insert_order */
+ my_bool first_pattern= 0; /* if doing insert_order */
+ my_bool first_found= 1;
MARIA_SHARE *share= bitmap->share;
my_bool insert_order=
MY_TEST(share->base.extra_options & MA_EXTRA_OPTIONS_INSERT_ORDER);
@@ -1249,16 +1281,19 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
DBUG_ASSERT(size <= FULL_PAGE_SIZE(share));
+ end= bitmap->map + bitmap->used_size;
if (insert_order && bitmap->page == share->last_insert_bitmap)
{
uint last_insert_page= share->last_insert_page;
uint byte= 6 * (last_insert_page / 16);
first_pattern= last_insert_page % 16;
- DBUG_ASSERT(data + byte < end);
- data+= byte;
+ data= bitmap->map+byte;
+ DBUG_ASSERT(data <= end);
}
+ else
+ data= bitmap->map + (bitmap->full_head_size/6)*6;
- for (; data < end; data+= 6)
+ for (; data < end; data+= 6, first_pattern= 0)
{
ulonglong bits= uint6korr(data); /* 6 bytes = 6*8/3= 16 patterns */
uint i;
@@ -1271,17 +1306,24 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
*/
if ((!bits && best_data) ||
((bits & 04444444444444444LL) == 04444444444444444LL))
- {
- first_pattern= 0; // always restart from 0 when moving to new 6-byte
continue;
- }
+
for (i= first_pattern, bits >>= (3 * first_pattern); i < 16 ;
i++, bits >>= 3)
{
uint pattern= (uint) (bits & 7);
+
+ if (pattern <= 3) /* Room for more data */
+ {
+ if (first_found)
+ {
+ first_found= 0;
+ bitmap->full_head_size= (uint)(data - bitmap->map);
+ }
+ }
if (pattern <= min_bits)
{
- /* There is enough space here */
+ /* There is enough space here, check if we have found better */
if ((int) pattern > (int) best_bits)
{
/*
@@ -1292,23 +1334,32 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
best_bits= pattern;
best_data= data;
best_pos= i;
- if (pattern == min_bits)
+ if (pattern == min_bits || bitmap->return_first_match)
goto found; /* Best possible match */
}
}
}
- first_pattern= 0; // always restart from 0 when moving to new 6-byte
}
if (!best_data) /* Found no place */
{
if (data >= bitmap->map + bitmap->total_size)
DBUG_RETURN(1); /* No space in bitmap */
+ DBUG_ASSERT(uint6korr(data) == 0);
/* Allocate data at end of bitmap */
- bitmap->used_size+= 6;
- set_if_smaller(bitmap->used_size, bitmap->total_size);
+ bitmap->used_size= (uint) (data - bitmap->map) + 6;
best_data= data;
best_pos= best_bits= 0;
}
+ else
+ {
+ /*
+ This is not stricly needed as used_size should be alligned on 6,
+ but for easier debugging lets try to keep it more accurate
+ */
+ uint position= (uint) (best_data - bitmap->map) + 6;
+ set_if_bigger(bitmap->used_size, position);
+ }
+ DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
found:
if (insert_order)
@@ -1341,12 +1392,15 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
MARIA_BITMAP_BLOCK *block)
{
uint min_bits= size_to_tail_pattern(bitmap, size);
- uchar *data= bitmap->map, *end= data + bitmap->used_size;
- uchar *best_data= 0;
+ uchar *data, *end, *best_data= 0;
+ my_bool first_found= 1;
uint best_bits= (uint) -1, UNINIT_VAR(best_pos);
DBUG_ENTER("allocate_tail");
DBUG_PRINT("enter", ("size: %u", size));
+ data= bitmap->map + (bitmap->full_tail_size/6)*6;
+ end= bitmap->map + bitmap->used_size;
+
/*
We have to add DIR_ENTRY_SIZE here as this is not part of the data size
See call to allocate_tail() in find_tail().
@@ -1375,7 +1429,19 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
for (i= 0; i < 16; i++, bits >>= 3)
{
uint pattern= (uint) (bits & 7);
- if (pattern <= min_bits && (!pattern || pattern >= 5))
+
+ if (pattern == 0 ||
+ (pattern > FULL_HEAD_PAGE && pattern < FULL_TAIL_PAGE))
+ {
+ /* There is room for tail data */
+ if (first_found)
+ {
+ first_found= 0;
+ bitmap->full_tail_size= (uint)(data - bitmap->map);
+ }
+ }
+
+ if (pattern <= min_bits && (!pattern || pattern > FULL_HEAD_PAGE))
{
if ((int) pattern > (int) best_bits)
{
@@ -1392,10 +1458,11 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
{
if (data >= bitmap->map + bitmap->total_size)
DBUG_RETURN(1);
+ DBUG_ASSERT(uint6korr(data) == 0);
/* Allocate data at end of bitmap */
best_data= data;
- bitmap->used_size+= 6;
- set_if_smaller(bitmap->used_size, bitmap->total_size);
+ bitmap->used_size= (uint) (data - bitmap->map) + 6;
+ DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
best_pos= best_bits= 0;
}
@@ -1434,8 +1501,7 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
ulong pages_needed,
MARIA_BITMAP_BLOCK *block, my_bool full_page)
{
- uchar *data= bitmap->map, *data_end= data + bitmap->used_size;
- uchar *page_end= data + bitmap->total_size;
+ uchar *data, *data_end, *page_end;
uchar *best_data= 0;
uint min_size;
uint best_area_size, UNINIT_VAR(best_prefix_area_size);
@@ -1449,6 +1515,10 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
min_size= BLOB_SEGMENT_MIN_SIZE;
best_area_size= ~(uint) 0;
+ data= bitmap->map + (bitmap->full_head_size/6)*6;
+ data_end= bitmap->map + bitmap->used_size;
+ page_end= bitmap->map + bitmap->total_size;
+
for (; data < page_end; data+= 6)
{
ulonglong bits= uint6korr(data); /* 6 bytes = 6*8/3= 16 patterns */
@@ -1466,6 +1536,12 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
if ((bits= uint6korr(data)))
break;
}
+ /*
+ Check if we are end of bitmap. In this case we know that
+ the rest of the bitmap is usable
+ */
+ if (data >= data_end)
+ data= page_end;
area_size= (uint) (data - data_start) / 6 * 16;
if (area_size >= best_area_size)
continue;
@@ -1823,7 +1899,7 @@ static my_bool allocate_blobs(MARIA_HA *info, MARIA_ROW *row)
/*
- Store in the bitmap the new size for a head page
+ Reserve the current head page
SYNOPSIS
use_head()
@@ -2225,7 +2301,7 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
pgcache_page_no_t page, uint fill_pattern)
{
pgcache_page_no_t bitmap_page;
- uint offset_page, offset, tmp, org_tmp;
+ uint offset_page, offset, tmp, org_tmp, used_offset;
uchar *data;
DBUG_ENTER("set_page_bits");
DBUG_ASSERT(fill_pattern <= 7);
@@ -2237,6 +2313,7 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
/* Find page number from start of bitmap */
offset_page= (uint) (page - bitmap->page - 1);
+
/*
Mark place used by reading/writing 2 bytes at a time to handle
bitmaps in overlapping bytes
@@ -2248,11 +2325,37 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
tmp= (tmp & ~(7 << offset)) | (fill_pattern << offset);
if (tmp == org_tmp)
DBUG_RETURN(0); /* No changes */
- int2store(data, tmp);
+ /*
+ Take care to not write bytes outside of bitmap.
+ fill_pattern is 3 bits, so we need to write two bytes
+ if bit position we write to is > (8-3)
+ */
+ if (offset > 5)
+ int2store(data, tmp);
+ else
+ data[0]= tmp;
+
+ /*
+ Reset full_head_size or full_tail_size if we are releasing data before
+ it. Increase used_size if we are allocating data.
+ */
+ used_offset= (uint) (data - bitmap->map);
+ if (fill_pattern < 4)
+ set_if_smaller(bitmap->full_head_size, used_offset);
+ if (fill_pattern == 0 || (fill_pattern > 4 && fill_pattern < 7))
+ set_if_smaller(bitmap->full_tail_size, used_offset);
+ if (fill_pattern != 0)
+ {
+ /* Calulcate which was the last changed byte */
+ used_offset+= offset > 5 ? 2 : 1;
+ set_if_bigger(bitmap->used_size, used_offset);
+ }
+
+ _ma_check_bitmap(bitmap);
bitmap->changed= 1;
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
- if (fill_pattern != 3 && fill_pattern != 7)
+ if (fill_pattern != FULL_HEAD_PAGE && fill_pattern != FULL_TAIL_PAGE)
set_if_smaller(info->s->state.first_bitmap_with_space, bitmap_page);
/*
Note that if the condition above is false (page is full), and all pages of
@@ -2345,7 +2448,7 @@ my_bool _ma_bitmap_reset_full_page_bits(MARIA_HA *info,
uint page_count)
{
ulonglong bitmap_page;
- uint offset, bit_start, bit_count, tmp;
+ uint offset, bit_start, bit_count, tmp, byte_offset;
uchar *data;
DBUG_ENTER("_ma_bitmap_reset_full_page_bits");
DBUG_PRINT("enter", ("page: %lu page_count: %u", (ulong) page, page_count));
@@ -2365,7 +2468,8 @@ my_bool _ma_bitmap_reset_full_page_bits(MARIA_HA *info,
bit_start= offset * 3;
bit_count= page_count * 3;
- data= bitmap->map + bit_start / 8;
+ byte_offset= bit_start/8;
+ data= bitmap->map + byte_offset;
offset= bit_start & 7;
tmp= (255 << offset); /* Bits to keep */
@@ -2376,6 +2480,9 @@ my_bool _ma_bitmap_reset_full_page_bits(MARIA_HA *info,
}
*data&= ~tmp;
+ set_if_smaller(bitmap->full_head_size, byte_offset);
+ set_if_smaller(bitmap->full_tail_size, byte_offset);
+
if ((int) (bit_count-= (8 - offset)) > 0)
{
uint fill;
@@ -2477,6 +2584,8 @@ my_bool _ma_bitmap_set_full_page_bits(MARIA_HA *info,
tmp= (1 << bit_count) - 1;
*data|= tmp;
}
+ set_if_bigger(bitmap->used_size, (uint) (data - bitmap->map) + 1);
+ _ma_check_bitmap(bitmap);
bitmap->changed= 1;
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
DBUG_RETURN(0);
@@ -2835,6 +2944,72 @@ my_bool _ma_check_bitmap_data(MARIA_HA *info, enum en_page_type page_type,
return (bitmap_pattern != bits);
}
+/**
+ Check that bitmap looks correct
+
+ - All data before full_head_size and full_tail_size are allocated
+ - There is no allocated data after used_size
+ All of the above need to be correct only according to 6 byte
+ alignment as all loops reads 6 bytes at a time and we check both
+ start and end position according to the current 6 byte position.
+*/
+
+#ifndef DBUG_OFF
+static void _ma_check_bitmap(MARIA_FILE_BITMAP *bitmap)
+{
+ uchar *data= bitmap->map;
+ uchar *end= bitmap->map + bitmap->total_size;
+ uchar *full_head_end=0, *full_tail_end=0, *first_empty= bitmap->map;
+
+ for (; data < end; data+= 6)
+ {
+ ulonglong bits= uint6korr(data); /* 6 bytes = 6*8/3= 16 patterns */
+ uint i;
+
+ if (bits == 04444444444444444LL || bits == 0xffffffffffffLL)
+ {
+ first_empty= data + 6;
+ continue; /* block fully used */
+ }
+ if (bits == 0)
+ {
+ if (!full_head_end)
+ full_head_end= data;
+ if (!full_tail_end)
+ full_tail_end= data;
+ continue;
+ }
+
+ first_empty= data + 6;
+ if (!full_head_end || !full_tail_end)
+ {
+ for (i= 0, bits >>= 0; i < 16 ; i++, bits >>= 3)
+ {
+ uint pattern= (uint) (bits & 7);
+ if (pattern == FULL_HEAD_PAGE || pattern == FULL_TAIL_PAGE)
+ continue;
+
+ if (pattern < 4 && !full_head_end)
+ full_head_end= data;
+ if ((pattern == 0 || (pattern > 4 && pattern < 7)) && !full_tail_end)
+ full_tail_end= data;
+ }
+ }
+ }
+ if (!full_head_end)
+ full_head_end= data;
+ if (!full_tail_end)
+ full_tail_end= data;
+
+ /* used_size must point after the last byte that had some data) */
+ DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
+ DBUG_ASSERT((bitmap->map + (bitmap->used_size+5)/6*6) >= first_empty);
+ /* full_xxxx_size can't point after the first block that has free data */
+ DBUG_ASSERT((bitmap->map + (bitmap->full_head_size/6*6)) <= full_head_end);
+ DBUG_ASSERT((bitmap->map + (bitmap->full_tail_size/6*6)) <= full_tail_end);
+}
+#endif
+
/*
Check if the page type matches the one that we have in the bitmap
@@ -3072,6 +3247,7 @@ static my_bool _ma_bitmap_create_missing(MARIA_HA *info,
pgcache_page_no_t from, to;
my_off_t data_file_length= share->state.state.data_file_length;
DBUG_ENTER("_ma_bitmap_create_missing");
+ DBUG_PRINT("enter", ("page: %lld", (longlong) page));
/* First (in offset order) bitmap page to create */
if (data_file_length < block_size)
@@ -3124,7 +3300,8 @@ static my_bool _ma_bitmap_create_missing(MARIA_HA *info,
only later as we are going to modify it very soon.
*/
bzero(bitmap->map, bitmap->block_size);
- bitmap->used_size= 0;
+ bitmap->used_size= bitmap->full_head_size= bitmap->full_tail_size= 0;
+ bitmap->changed=1;
#ifndef DBUG_OFF
/*
Make a copy of the page to be able to print out bitmap changes during
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index fec8bf2d72d..8eaac990741 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -6166,7 +6166,7 @@ my_bool write_hook_for_undo_row_insert(enum translog_record_type type
/**
- @brief Upates "records" and calls the generic UNDO hook
+ @brief Updates "records" and calls the generic UNDO hook
@return Operation status, always 0 (success)
*/
@@ -6316,8 +6316,8 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
uchar *buff, *dir;
uint result;
MARIA_PINNED_PAGE page_link;
- enum pagecache_page_lock unlock_method;
- enum pagecache_page_pin unpin_method;
+ enum pagecache_page_lock lock_method;
+ enum pagecache_page_pin pin_method;
my_off_t end_of_page;
uint error;
DBUG_ENTER("_ma_apply_redo_insert_row_head_or_tail");
@@ -6345,8 +6345,8 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
fill it entirely with zeroes, then the REDO will put correct data on
it.
*/
- unlock_method= PAGECACHE_LOCK_WRITE;
- unpin_method= PAGECACHE_PIN;
+ lock_method= PAGECACHE_LOCK_WRITE;
+ pin_method= PAGECACHE_PIN;
DBUG_ASSERT(rownr == 0 && new_page);
if (rownr != 0 || !new_page)
@@ -6361,8 +6361,8 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
}
else
{
- unlock_method= PAGECACHE_LOCK_LEFT_WRITELOCKED;
- unpin_method= PAGECACHE_PIN_LEFT_PINNED;
+ lock_method= PAGECACHE_LOCK_LEFT_WRITELOCKED;
+ pin_method= PAGECACHE_PIN_LEFT_PINNED;
share->pagecache->readwrite_flags&= ~MY_WME;
buff= pagecache_read(share->pagecache, &info->dfile,
@@ -6463,11 +6463,11 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
this group, for this page, would be skipped) and unpin then.
*/
result= 0;
- if (unlock_method == PAGECACHE_LOCK_WRITE &&
+ if (lock_method == PAGECACHE_LOCK_WRITE &&
pagecache_write(share->pagecache,
&info->dfile, page, 0,
buff, PAGECACHE_PLAIN_PAGE,
- unlock_method, unpin_method,
+ lock_method, pin_method,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE))
result= my_errno;
@@ -6488,7 +6488,7 @@ crashed_file:
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
err:
error= my_errno;
- if (unlock_method == PAGECACHE_LOCK_LEFT_WRITELOCKED)
+ if (lock_method == PAGECACHE_LOCK_LEFT_WRITELOCKED)
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 2f638fb1065..316a1a06ccc 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -3202,7 +3202,7 @@ static int write_page(MARIA_SHARE *share, File file,
args.pageno= (pgcache_page_no_t) (pos / share->block_size);
args.data= (uchar*) share;
(* share->kfile.pre_write_hook)(&args);
- res= my_pwrite(file, args.page, block_size, pos, myf_rw);
+ res= (int)my_pwrite(file, args.page, block_size, pos, myf_rw);
(* share->kfile.post_write_hook)(res, &args);
return res;
}
@@ -3783,7 +3783,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
param->read_cache.end_of_file= sort_info.filelength;
sort_param.wordlist=NULL;
- init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0,
+ init_alloc_root(&sort_param.wordroot, "sort", FTPARSER_MEMROOT_ALLOC_SIZE, 0,
MYF(param->malloc_flags));
sort_param.key_cmp=sort_key_cmp;
@@ -4431,7 +4431,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
(FT_MAX_WORD_LEN_FOR_SORT *
sort_param[i].keyinfo->seg->charset->mbmaxlen);
sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
- init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0,
+ init_alloc_root(&sort_param[i].wordroot, "sort",
+ FTPARSER_MEMROOT_ALLOC_SIZE, 0,
MYF(param->malloc_flags));
}
}
diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c
index 0933ca7d736..7d70f6970e4 100644
--- a/storage/maria/ma_checkpoint.c
+++ b/storage/maria/ma_checkpoint.c
@@ -48,7 +48,7 @@ static mysql_cond_t COND_checkpoint;
static MA_SERVICE_THREAD_CONTROL checkpoint_control=
{0, FALSE, FALSE, &LOCK_checkpoint, &COND_checkpoint};
/* is ulong like pagecache->blocks_changed */
-static ulong pages_to_flush_before_next_checkpoint;
+static uint pages_to_flush_before_next_checkpoint;
static PAGECACHE_FILE *dfiles, /**< data files to flush in background */
*dfiles_end; /**< list of data files ends here */
static PAGECACHE_FILE *kfiles, /**< index files to flush in background */
@@ -265,7 +265,7 @@ static int really_execute_checkpoint(void)
ptr= record_pieces[3].str;
pages_to_flush_before_next_checkpoint= uint4korr(ptr);
DBUG_PRINT("checkpoint",("%u pages to flush before next checkpoint",
- (uint)pages_to_flush_before_next_checkpoint));
+ pages_to_flush_before_next_checkpoint));
/* compute log's low-water mark */
{
@@ -562,9 +562,7 @@ pthread_handler_t ma_checkpoint_background(void *arg)
DBUG_PRINT("info",("Maria background checkpoint thread starts"));
DBUG_ASSERT(interval > 0);
-#ifdef HAVE_PSI_THREAD_INTERFACE
- PSI_THREAD_CALL(set_thread_user_host)(0,0,0,0);
-#endif
+ PSI_CALL_set_thread_user_host(0,0,0,0);
/*
Recovery ended with all tables closed and a checkpoint: no need to take
@@ -640,7 +638,7 @@ pthread_handler_t ma_checkpoint_background(void *arg)
case 1:
/* set up parameters for background page flushing */
filter_param.up_to_lsn= last_checkpoint_lsn;
- pages_bunch_size= pages_to_flush_before_next_checkpoint / interval;
+ pages_bunch_size= pages_to_flush_before_next_checkpoint / (uint)interval;
dfile= dfiles;
kfile= kfiles;
/* fall through */
@@ -752,7 +750,7 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
char *ptr;
uint error= 1, sync_error= 0, nb, nb_stored, i;
my_bool unmark_tables= TRUE;
- uint total_names_length;
+ size_t total_names_length;
LIST *pos; /**< to iterate over open tables */
struct st_state_copy {
uint index;
@@ -983,7 +981,7 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
DBUG_PRINT("info", ("ignore_share: %d", ignore_share));
if (!ignore_share)
{
- uint open_file_name_len= share->open_file_name.length + 1;
+ size_t open_file_name_len= share->open_file_name.length + 1;
/* remember the descriptors for background flush */
*(dfiles_end++)= dfile;
*(kfiles_end++)= kfile;
diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c
index 1ccb67d5698..94f9ad46a48 100644
--- a/storage/maria/ma_control_file.c
+++ b/storage/maria/ma_control_file.c
@@ -217,7 +217,6 @@ static CONTROL_FILE_ERROR create_control_file(const char *name,
static int lock_control_file(const char *name)
{
- uint retry= 0;
/*
On Windows, my_lock() uses locking() which is mandatory locking and so
prevents maria-recovery.test from copying the control file. And in case of
@@ -228,6 +227,7 @@ static int lock_control_file(const char *name)
file under Windows.
*/
#ifndef __WIN__
+ uint retry= 0;
/*
We can't here use the automatic wait in my_lock() as the alarm thread
may not yet exists.
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 058b675d6a7..d7dcbf387c8 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -70,7 +70,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
myf create_flag;
uint length,max_key_length,packed,pack_bytes,pointer,real_length_diff,
key_length,info_length,key_segs,options,min_key_length,
- base_pos,long_varchar_count,varchar_length,
+ base_pos,long_varchar_count,
unique_key_parts,fulltext_keys,offset, not_block_record_extra_length;
uint max_field_lengths, extra_header_size, column_nr;
uint internal_table= flags & HA_CREATE_INTERNAL_TABLE;
@@ -144,9 +144,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
datafile_type= BLOCK_RECORD;
}
- if (ci->reloc_rows > ci->max_rows)
- ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */
-
if (!(rec_per_key_part=
(double*) my_malloc((keys + uniques)*HA_MAX_KEY_SEG*sizeof(double) +
(keys + uniques)*HA_MAX_KEY_SEG*sizeof(ulong) +
@@ -160,7 +157,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
/* Start by checking fields and field-types used */
- varchar_length=long_varchar_count=packed= not_block_record_extra_length=
+ long_varchar_count=packed= not_block_record_extra_length=
pack_reclength= max_field_lengths= 0;
reclength= min_pack_length= ci->null_bytes;
forced_packed= 0;
@@ -232,7 +229,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
}
else if (type == FIELD_VARCHAR)
{
- varchar_length+= column->length-1; /* Used for min_pack_length */
pack_reclength++;
not_block_record_extra_length++;
max_field_lengths++;
@@ -368,6 +364,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
pack_bytes);
if (!ci->data_file_length && ci->max_rows)
{
+ set_if_bigger(ci->max_rows, ci->reloc_rows);
if (pack_reclength == INT_MAX32 ||
(~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength)
ci->data_file_length= ~(ulonglong) 0;
@@ -401,13 +398,14 @@ int maria_create(const char *name, enum data_file_type datafile_type,
else
ci->max_rows= data_file_length / (min_pack_length +
extra_header_size +
- DIR_ENTRY_SIZE)+1;
+ DIR_ENTRY_SIZE);
}
else
ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length +
((options &
HA_OPTION_PACK_RECORD) ?
- 3 : 0)))+1;
+ 3 : 0)));
+ set_if_smaller(ci->reloc_rows, ci->max_rows);
}
max_rows= (ulonglong) ci->max_rows;
if (datafile_type == BLOCK_RECORD)
@@ -800,6 +798,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
share.state.state.data_file_length= maria_block_size;
/* Add length of packed fields + length */
share.base.pack_reclength+= share.base.max_field_lengths+3;
+ share.base.max_pack_length= share.base.pack_reclength;
/* Adjust max_pack_length, to be used if we have short rows */
if (share.base.max_pack_length < maria_block_size)
@@ -1198,7 +1197,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
{
fn_format(dfilename,name,"", MARIA_NAME_DEXT,
MY_UNPACK_FILENAME | MY_APPEND_EXT);
- dlinkname_ptr= NullS;
create_flag= (flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
}
if ((dfile=
@@ -1252,8 +1250,6 @@ err_no_lock:
switch (errpos) {
case 3:
mysql_file_close(dfile, MYF(0));
- /* fall through */
- case 2:
if (! (flags & HA_DONT_TOUCH_DATA))
{
mysql_file_delete(key_file_dfile, dfilename, MYF(sync_dir));
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index c5a2378dc2b..b4b02212a16 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -801,7 +801,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if ((keypos < anc_buff + anc_length && (info->state->records & 1)) ||
first_key)
{
- size_t tmp_length;
+ uint tmp_length;
uint next_page_flag;
/* Use page right of anc-page */
DBUG_PRINT("test",("use right page"));
@@ -968,7 +968,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
(uchar*) 0, (uchar*) 0,
&key_inserted);
/* t_length will always be > 0 for a new page !*/
- tmp_length= (size_t) ((next_page.buff + buff_length) - half_pos);
+ tmp_length= (uint) ((next_page.buff + buff_length) - half_pos);
bmove(next_page.buff + p_length + t_length, half_pos, tmp_length);
(*keyinfo->store_key)(keyinfo, next_page.buff + p_length, &key_inserted);
new_buff_length= tmp_length + t_length + p_length;
@@ -1207,7 +1207,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
DBUG_PRINT("info",("t_length: %d length: %d",t_length, (int) tmp_length));
bmove(leaf_buff+p_length+t_length, half_pos, tmp_length);
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length, &key_inserted);
- new_leaf_length= tmp_length + t_length + p_length;
+ new_leaf_length= (uint)(tmp_length + t_length + p_length);
DBUG_ASSERT(new_leaf_length <= share->max_index_block_size);
leaf_page->size= new_leaf_length;
diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c
index e5c108a18c6..6779516d557 100644
--- a/storage/maria/ma_dynrec.c
+++ b/storage/maria/ma_dynrec.c
@@ -275,7 +275,7 @@ my_bool _ma_update_blob_record(MARIA_HA *info, MARIA_RECORD_POS pos,
{
uchar *rec_buff;
int error;
- ulong reclength,extra;
+ ulong reclength,reclength2,extra;
extra= (ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER)+MARIA_SPLIT_LENGTH+
MARIA_DYN_DELETE_BLOCK_HEADER);
@@ -293,11 +293,12 @@ my_bool _ma_update_blob_record(MARIA_HA *info, MARIA_RECORD_POS pos,
my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */
return(1);
}
- reclength= _ma_rec_pack(info,rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
+ reclength2= _ma_rec_pack(info,rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
record);
+ DBUG_ASSERT(reclength2 <= reclength);
error=update_dynamic_record(info,pos,
rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
- reclength);
+ reclength2);
my_safe_afree(rec_buff, reclength);
return(error != 0);
}
@@ -1208,8 +1209,8 @@ err:
my_errno is set to HA_ERR_WRONG_IN_RECORD
*/
-ulong _ma_rec_unpack(register MARIA_HA *info, register uchar *to, uchar *from,
- ulong found_length)
+size_t _ma_rec_unpack(register MARIA_HA *info, register uchar *to, uchar *from,
+ size_t found_length)
{
uint flag,bit,length,min_pack_length, column_length;
enum en_fieldtype type;
diff --git a/storage/maria/ma_ft_boolean_search.c b/storage/maria/ma_ft_boolean_search.c
index 4f98bb3db41..4847429ed4b 100644
--- a/storage/maria/ma_ft_boolean_search.c
+++ b/storage/maria/ma_ft_boolean_search.c
@@ -574,7 +574,7 @@ FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr,
bzero(& ftb->no_dupes, sizeof(TREE));
ftb->last_word= 0;
- init_alloc_root(&ftb->mem_root, 1024, 1024, 0);
+ init_alloc_root(&ftb->mem_root, "fulltext", 1024, 1024, 0);
ftb->queue.max_elements= 0;
if (!(ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR))))
goto err;
diff --git a/storage/maria/ma_ft_parser.c b/storage/maria/ma_ft_parser.c
index 00d5baacaa1..cb12a8072d4 100644
--- a/storage/maria/ma_ft_parser.c
+++ b/storage/maria/ma_ft_parser.c
@@ -348,7 +348,8 @@ MYSQL_FTPARSER_PARAM* maria_ftparser_alloc_param(MARIA_HA *info)
info->ftparser_param= (MYSQL_FTPARSER_PARAM *)
my_malloc(MAX_PARAM_NR * sizeof(MYSQL_FTPARSER_PARAM) *
info->s->ftkeys, MYF(MY_WME | MY_ZEROFILL));
- init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(0));
+ init_alloc_root(&info->ft_memroot, "fulltext_parser",
+ FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(0));
}
return info->ftparser_param;
}
diff --git a/storage/maria/ma_keycache.c b/storage/maria/ma_keycache.c
index 39459c486fd..b63535a0897 100644
--- a/storage/maria/ma_keycache.c
+++ b/storage/maria/ma_keycache.c
@@ -106,7 +106,7 @@ int maria_assign_to_pagecache(MARIA_HA *info,
/* store the key cache in the global hash structure for future opens */
if (multi_pagecache_set((uchar*) share->unique_file_name.str,
- share->unique_file_name.length,
+ (uint)share->unique_file_name.length,
share->pagecache))
error= my_errno;
mysql_mutex_unlock(&share->intern_lock);
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index d3a0531c73d..c81c7735df5 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -5373,7 +5373,7 @@ static void translog_relative_LSN_encode(struct st_translog_parts *parts,
/* collect all LSN(s) in one chunk if it (they) is (are) divided */
if (part->length < lsns_len)
{
- uint copied= part->length;
+ size_t copied= part->length;
LEX_CUSTRING *next_part;
DBUG_PRINT("info", ("Using buffer:%p", compressed_LSNs));
memcpy(buffer, part->str, part->length);
@@ -5394,7 +5394,7 @@ static void translog_relative_LSN_encode(struct st_translog_parts *parts,
}
else
{
- uint len= lsns_len - copied;
+ size_t len= lsns_len - copied;
memcpy(buffer + copied, next_part->str, len);
copied= lsns_len;
next_part->str+= len;
@@ -5430,11 +5430,12 @@ static void translog_relative_LSN_encode(struct st_translog_parts *parts,
ref= lsn_korr(src_ptr);
dst_ptr= translog_put_LSN_diff(base_lsn, ref, dst_ptr);
}
- part->length= (uint)((compressed_LSNs +
+ part->length= (size_t)((compressed_LSNs +
(MAX_NUMBER_OF_LSNS_PER_RECORD *
COMPRESSED_LSN_MAX_STORE_SIZE)) -
dst_ptr);
- parts->record_length-= (economy= lsns_len - part->length);
+ economy= lsns_len - (uint)part->length;
+ parts->record_length-= economy;
DBUG_PRINT("info", ("new length of LSNs: %lu economy: %d",
(ulong)part->length, economy));
parts->total_record_length-= economy;
@@ -6302,7 +6303,7 @@ my_bool translog_write_record(LSN *lsn,
#ifndef DBUG_OFF
{
uint i;
- uint len= 0;
+ size_t len= 0;
#ifdef HAVE_valgrind
ha_checksum checksum= 0;
#endif
@@ -6342,7 +6343,6 @@ my_bool translog_write_record(LSN *lsn,
short_trid, &parts, trn, hook_arg);
break;
case LOGRECTYPE_NOT_ALLOWED:
- DBUG_ASSERT(0);
default:
DBUG_ASSERT(0);
rc= 1;
diff --git a/storage/maria/ma_norec.c b/storage/maria/ma_norec.c
index 8ed0ef68eb4..da26d0d6dbd 100644
--- a/storage/maria/ma_norec.c
+++ b/storage/maria/ma_norec.c
@@ -32,14 +32,14 @@ my_bool _ma_update_no_record(MARIA_HA *info __attribute__((unused)),
const uchar *oldrec __attribute__((unused)),
const uchar *record __attribute__((unused)))
{
- return HA_ERR_WRONG_COMMAND;
+ return (my_bool)HA_ERR_WRONG_COMMAND;
}
my_bool _ma_delete_no_record(MARIA_HA *info __attribute__((unused)),
const uchar *record __attribute__((unused)))
{
- return HA_ERR_WRONG_COMMAND;
+ return (my_bool)HA_ERR_WRONG_COMMAND;
}
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 2092e024e28..3febf879ec6 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -280,7 +280,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
size_t info_length;
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
data_name[FN_REFLEN];
- uchar *disk_cache, *disk_pos, *end_pos;
+ uchar *UNINIT_VAR(disk_cache), *disk_pos, *end_pos;
MARIA_HA info, *UNINIT_VAR(m_info), *old_info;
MARIA_SHARE share_buff,*share;
double *rec_per_key_part;
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index ccaba3b7a33..e41b7dd1177 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -224,17 +224,35 @@ my_bool _ma_write_keypage(MARIA_PAGE *page, enum pagecache_page_lock lock,
#endif
page_cleanup(share, page);
- res= pagecache_write(share->pagecache,
- &share->kfile,
- (pgcache_page_no_t) (page->pos / block_size),
- level, buff, share->page_type,
- lock,
- lock == PAGECACHE_LOCK_LEFT_WRITELOCKED ?
- PAGECACHE_PIN_LEFT_PINNED :
- (lock == PAGECACHE_LOCK_WRITE_UNLOCK ?
- PAGECACHE_UNPIN : PAGECACHE_PIN),
- PAGECACHE_WRITE_DELAY, &page_link.link,
- LSN_IMPOSSIBLE);
+ {
+ PAGECACHE_BLOCK_LINK **link;
+ enum pagecache_page_pin pin;
+ if (lock == PAGECACHE_LOCK_LEFT_WRITELOCKED)
+ {
+ pin= PAGECACHE_PIN_LEFT_PINNED;
+ link= &page_link.link;
+ }
+ else if (lock == PAGECACHE_LOCK_WRITE_UNLOCK)
+ {
+ pin= PAGECACHE_UNPIN;
+ /*
+ We unlock this page so link should be 0 to prevent it usage
+ even accidentally
+ */
+ link= NULL;
+ }
+ else
+ {
+ pin= PAGECACHE_PIN;
+ link= &page_link.link;
+ }
+ res= pagecache_write(share->pagecache,
+ &share->kfile,
+ (pgcache_page_no_t) (page->pos / block_size),
+ level, buff, share->page_type,
+ lock, pin, PAGECACHE_WRITE_DELAY, link,
+ LSN_IMPOSSIBLE);
+ }
if (lock == PAGECACHE_LOCK_WRITE)
{
@@ -493,8 +511,8 @@ static my_bool _ma_log_compact_keypage(MARIA_PAGE *ma_page,
if (translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
- log_array[TRANSLOG_INTERNAL_PARTS +
- 0].length + extra_length,
+ (translog_size_t)(log_array[TRANSLOG_INTERNAL_PARTS +
+ 0].length + extra_length),
TRANSLOG_INTERNAL_PARTS + translog_parts,
log_array, log_data, NULL))
DBUG_RETURN(1);
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index 8ed97d6eae4..fd5995515c1 100644
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -667,7 +667,7 @@ static my_bool pagecache_fwrite(PAGECACHE *pagecache,
DBUG_PRINT("error", ("write callback problem"));
DBUG_RETURN(1);
}
- res= my_pwrite(filedesc->file, args.page, pagecache->block_size,
+ res= (int)my_pwrite(filedesc->file, args.page, pagecache->block_size,
((my_off_t) pageno << pagecache->shift), flags);
(*filedesc->post_write_hook)(res, &args);
DBUG_RETURN(res);
@@ -810,7 +810,7 @@ size_t init_pagecache(PAGECACHE *pagecache, size_t use_mem,
goto err;
}
/* Set my_hash_entries to the next bigger 2 power */
- if ((pagecache->hash_entries= next_power(blocks)) <
+ if ((pagecache->hash_entries= next_power((uint)blocks)) <
(blocks) * 5/4)
pagecache->hash_entries<<= 1;
hash_links= 2 * blocks;
@@ -890,9 +890,9 @@ size_t init_pagecache(PAGECACHE *pagecache, size_t use_mem,
DBUG_PRINT("exit",
("disk_blocks: %zu block_root: %p hash_entries: %zu\
hash_root: %p hash_links: %zu hash_link_root: %p",
- pagecache->disk_blocks, pagecache->block_root,
+ (size_t)pagecache->disk_blocks, pagecache->block_root,
pagecache->hash_entries, pagecache->hash_root,
- pagecache->hash_links, pagecache->hash_link_root));
+ (size_t)pagecache->hash_links, pagecache->hash_link_root));
pagecache->blocks= pagecache->disk_blocks > 0 ? pagecache->disk_blocks : 0;
DBUG_RETURN((size_t)pagecache->disk_blocks);
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index ad1df75f19e..9f436f3d8e5 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -3295,7 +3295,7 @@ static LSN parse_checkpoint_record(LSN lsn)
{
char name[FN_REFLEN];
LSN first_log_write_lsn;
- uint name_len;
+ size_t name_len;
uint16 sid= uint2korr(ptr);
ptr+= 2;
DBUG_ASSERT(sid > 0);
diff --git a/storage/maria/ma_rename.c b/storage/maria/ma_rename.c
index 71e2dea9d7e..0650d9f6a56 100644
--- a/storage/maria/ma_rename.c
+++ b/storage/maria/ma_rename.c
@@ -68,7 +68,7 @@ int maria_rename(const char *old_name, const char *new_name)
{
LSN lsn;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
- uint old_name_len= strlen(old_name)+1, new_name_len= strlen(new_name)+1;
+ size_t old_name_len= strlen(old_name)+1, new_name_len= strlen(new_name)+1;
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (uchar*)old_name;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= old_name_len;
log_array[TRANSLOG_INTERNAL_PARTS + 1].str= (uchar*)new_name;
@@ -83,7 +83,7 @@ int maria_rename(const char *old_name, const char *new_name)
*/
if (unlikely(translog_write_record(&lsn, LOGREC_REDO_RENAME_TABLE,
&dummy_transaction_object, NULL,
- old_name_len + new_name_len,
+ (translog_size_t)(old_name_len + new_name_len),
sizeof(log_array)/sizeof(log_array[0]),
log_array, NULL, NULL) ||
translog_flush(lsn)))
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index 089e3fabdb2..31e1d0cb302 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -745,11 +745,11 @@ void _ma_kpointer(register MARIA_HA *info, register uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
@@ -881,13 +881,13 @@ void _ma_dpointer(MARIA_SHARE *share, uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 8: *buff++=0;
- /* fall trough */
+ /* fall through */
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
@@ -949,7 +949,7 @@ uint _ma_get_static_key(MARIA_KEY *key, uint page_flag, uint nod_flag,
register uchar **page)
{
register MARIA_KEYDEF *keyinfo= key->keyinfo;
- size_t key_length= keyinfo->keylength;
+ uint key_length= keyinfo->keylength;
key->ref_length= keyinfo->share->rec_reflength;
key->data_length= key_length - key->ref_length;
diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c
index fc79bbfac91..a3c2d50bdc6 100644
--- a/storage/maria/ma_state.c
+++ b/storage/maria/ma_state.c
@@ -58,6 +58,7 @@ my_bool _ma_setup_live_state(MARIA_HA *info)
MARIA_USED_TABLES *tables;
MARIA_STATE_HISTORY *history;
DBUG_ENTER("_ma_setup_live_state");
+ DBUG_PRINT("enter", ("info: %p", info));
DBUG_ASSERT(share->lock_key_trees);
@@ -110,6 +111,8 @@ my_bool _ma_setup_live_state(MARIA_HA *info)
end:
info->state_start= &tables->state_start;
info->state= &tables->state_current;
+ info->used_tables= tables;
+ tables->use_count++;
/*
Mark in transaction state if we are not using transid (versioning)
@@ -118,6 +121,7 @@ end:
*/
tables->state_current.no_transid|= !(info->row_flag & ROW_FLAG_TRANSID);
+ DBUG_PRINT("exit", ("tables: %p info->state: %p", tables, info->state));
DBUG_RETURN(0);
}
@@ -241,9 +245,10 @@ void _ma_reset_state(MARIA_HA *info)
DBUG_ENTER("_ma_reset_state");
/* Always true if share->now_transactional is set */
- if (history)
+ if (history && share->have_versioning)
{
MARIA_STATE_HISTORY *next;
+ DBUG_PRINT("info", ("resetting history"));
/* Set the current history to current state */
share->state_history->state= share->state.state;
@@ -255,7 +260,7 @@ void _ma_reset_state(MARIA_HA *info)
my_free(history);
}
share->state_history->next= 0;
- share->state_history->trid= 0; /* Visibile for all */
+ share->state_history->trid= 0; /* Visible for all */
}
DBUG_VOID_RETURN;
}
@@ -597,7 +602,7 @@ void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
SYNOPSIS
_ma_get_status()
- param Pointer to Myisam handler
+ param Pointer to Aria handler
concurrent_insert Set to 1 if we are going to do concurrent inserts
(THR_WRITE_CONCURRENT_INSERT was used)
*/
@@ -627,6 +632,8 @@ void _ma_block_get_status(void* param, my_bool concurrent_insert)
my_bool _ma_block_start_trans(void* param)
{
MARIA_HA *info=(MARIA_HA*) param;
+ DBUG_ENTER("_ma_block_start_trans");
+
if (info->s->lock_key_trees)
{
/*
@@ -634,7 +641,7 @@ my_bool _ma_block_start_trans(void* param)
out of memory conditions)
TODO: Fix this by having one extra state pre-allocated
*/
- return _ma_setup_live_state(info);
+ DBUG_RETURN(_ma_setup_live_state(info));
}
else
{
@@ -663,9 +670,9 @@ my_bool _ma_block_start_trans(void* param)
Assume for now that this doesn't fail (It can only fail in
out of memory conditions)
*/
- return maria_create_trn_hook(info) != 0;
+ DBUG_RETURN(maria_create_trn_hook(info) != 0);
}
- return 0;
+ DBUG_RETURN(0);
}
@@ -697,7 +704,7 @@ my_bool _ma_block_check_status(void *param __attribute__((unused)))
my_bool _ma_block_start_trans_no_versioning(void* param)
{
MARIA_HA *info=(MARIA_HA*) param;
- DBUG_ENTER("_ma_block_get_status_no_version");
+ DBUG_ENTER("_ma_block_start_trans_no_versioning");
DBUG_ASSERT(info->s->base.born_transactional && !info->s->lock_key_trees);
info->state->changed= 0; /* from _ma_reset_update_flag() */
@@ -722,6 +729,8 @@ my_bool _ma_block_start_trans_no_versioning(void* param)
void maria_versioning(MARIA_HA *info, my_bool versioning)
{
MARIA_SHARE *share= info->s;
+ DBUG_ENTER("maria_versioning");
+
/* For now, this is a hack */
if (share->have_versioning)
{
@@ -738,6 +747,7 @@ void maria_versioning(MARIA_HA *info, my_bool versioning)
info->state= &share->state.state; /* Change global values by default */
info->state_start= info->state; /* Initial values */
}
+ DBUG_VOID_RETURN;
}
diff --git a/storage/maria/ma_state.h b/storage/maria/ma_state.h
index 5ff6dc26337..a86aada94fd 100644
--- a/storage/maria/ma_state.h
+++ b/storage/maria/ma_state.h
@@ -34,6 +34,7 @@ typedef struct st_used_tables {
struct st_maria_share *share;
MARIA_STATUS_INFO state_current;
MARIA_STATUS_INFO state_start;
+ uint use_count;
} MARIA_USED_TABLES;
diff --git a/storage/maria/ma_test1.c b/storage/maria/ma_test1.c
index 07da313db8a..d7ee7136fb2 100644
--- a/storage/maria/ma_test1.c
+++ b/storage/maria/ma_test1.c
@@ -577,7 +577,7 @@ static void create_key(uchar *key,uint rownr)
}
if (keyinfo[0].seg[0].flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART))
{
- uint tmp;
+ size_t tmp;
create_key_part(key+2,rownr);
tmp=strlen((char*) key+2);
int2store(key,tmp);
@@ -602,7 +602,7 @@ static void create_record(uchar *record,uint rownr)
pos=record+1;
if (recinfo[0].type == FIELD_BLOB)
{
- uint tmp;
+ size_t tmp;
uchar *ptr;
create_key_part(blob_key,rownr);
tmp=strlen((char*) blob_key);
@@ -613,7 +613,7 @@ static void create_record(uchar *record,uint rownr)
}
else if (recinfo[0].type == FIELD_VARCHAR)
{
- uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[0].length-1);
+ size_t tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[0].length-1);
create_key_part(pos+pack_length,rownr);
tmp= strlen((char*) pos+pack_length);
if (pack_length == 1)
@@ -629,7 +629,7 @@ static void create_record(uchar *record,uint rownr)
}
if (recinfo[1].type == FIELD_BLOB)
{
- uint tmp;
+ size_t tmp;
uchar *ptr;;
sprintf((char*) blob_record,"... row: %d", rownr);
strappend((char*) blob_record,MY_MAX(MAX_REC_LENGTH-rownr,10),' ');
@@ -640,7 +640,7 @@ static void create_record(uchar *record,uint rownr)
}
else if (recinfo[1].type == FIELD_VARCHAR)
{
- uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
+ size_t tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
sprintf((char*) pos+pack_length, "... row: %d", rownr);
tmp= strlen((char*) pos+pack_length);
if (pack_length == 1)
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index ff68b4bb9a2..cfa62ffec58 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -341,7 +341,7 @@ err:
for (j=0 ; j < share->base.keys ; j++)
maria_flush_bulk_insert(info, j);
}
- info->errkey= (int) i;
+ info->errkey= i < share->base.keys ? (int) i : -1;
/*
We delete keys in the reverse order of insertion. This is the order that
a rollback would do and is important for CLR_ENDs generated by
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index cb8b374691e..01af4c0381f 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -857,7 +857,7 @@ get_one_option(int optid,
case 2:
method_conv= MI_STATS_METHOD_IGNORE_NULLS;
break;
- default: assert(0); /* Impossible */
+ default: abort(); /* Impossible */
}
check_param.stats_method= method_conv;
break;
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 5a8f6178ed6..51cb9574af2 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -332,7 +332,10 @@ typedef struct st_maria_file_bitmap
pgcache_page_no_t last_bitmap_page; /* Last possible bitmap page */
my_bool changed; /* 1 if page needs to be written */
my_bool changed_not_flushed; /* 1 if some bitmap is not flushed */
+ my_bool return_first_match; /* Shortcut find_head() */
uint used_size; /* Size of bitmap head that is not 0 */
+ uint full_head_size; /* Where to start search for head */
+ uint full_tail_size; /* Where to start search for tail */
uint flush_all_requested; /**< If _ma_bitmap_flush_all waiting */
uint waiting_for_flush_all_requested; /* If someone is waiting for above */
uint non_flushable; /**< 0 if bitmap and log are in sync */
@@ -601,6 +604,7 @@ struct st_maria_handler
struct st_ma_transaction *trn; /* Pointer to active transaction */
MARIA_STATUS_INFO *state, state_save;
MARIA_STATUS_INFO *state_start; /* State at start of transaction */
+ MARIA_USED_TABLES *used_tables;
MARIA_ROW cur_row; /* The active row that we just read */
MARIA_ROW new_row; /* Storage for a row during update */
MARIA_KEY last_key; /* Last found key */
@@ -1183,7 +1187,7 @@ extern ulonglong transid_get_packed(MARIA_SHARE *share, const uchar *from);
#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
void page_cleanup(MARIA_SHARE *share, MARIA_PAGE *page)
#else
-#define page_cleanup(A,B) while (0)
+#define page_cleanup(A,B) do { } while (0)
#endif
extern MARIA_KEY *_ma_make_key(MARIA_HA *info, MARIA_KEY *int_key, uint keynr,
@@ -1201,8 +1205,8 @@ extern my_bool _ma_read_cache(MARIA_HA *, IO_CACHE *info, uchar *buff,
extern ulonglong ma_retrieve_auto_increment(const uchar *key, uint8 key_type);
extern my_bool _ma_alloc_buffer(uchar **old_addr, size_t *old_size,
size_t new_size);
-extern ulong _ma_rec_unpack(MARIA_HA *info, uchar *to, uchar *from,
- ulong reclength);
+extern size_t _ma_rec_unpack(MARIA_HA *info, uchar *to, uchar *from,
+ size_t reclength);
extern my_bool _ma_rec_check(MARIA_HA *info, const uchar *record,
uchar *packpos, ulong packed_length,
my_bool with_checkum, ha_checksum checksum);
diff --git a/storage/maria/unittest/ma_control_file-t.c b/storage/maria/unittest/ma_control_file-t.c
index 25ec982133a..e68078d5230 100644
--- a/storage/maria/unittest/ma_control_file-t.c
+++ b/storage/maria/unittest/ma_control_file-t.c
@@ -123,7 +123,7 @@ static char *create_tmpdir(const char *progname)
{
static char test_dirname[FN_REFLEN];
char tmp_name[FN_REFLEN];
- uint length;
+ size_t length;
/* Create a temporary directory of name TMP-'executable', but without the -t extension */
fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT);
diff --git a/storage/maria/unittest/ma_maria_log_cleanup.c b/storage/maria/unittest/ma_maria_log_cleanup.c
index 23e5be739d1..9c1c916224b 100644
--- a/storage/maria/unittest/ma_maria_log_cleanup.c
+++ b/storage/maria/unittest/ma_maria_log_cleanup.c
@@ -70,7 +70,7 @@ char *create_tmpdir(const char *progname)
{
static char test_dirname[FN_REFLEN];
char tmp_name[FN_REFLEN];
- uint length;
+ size_t length;
/* Create a temporary directory of name TMP-'executable', but without the -t extension */
fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT);
diff --git a/storage/maria/unittest/ma_pagecache_consist.c b/storage/maria/unittest/ma_pagecache_consist.c
index a9223ca9f6f..5e51c3f29b5 100644
--- a/storage/maria/unittest/ma_pagecache_consist.c
+++ b/storage/maria/unittest/ma_pagecache_consist.c
@@ -311,7 +311,7 @@ static char *create_tmpdir(const char *progname)
{
static char test_dirname[FN_REFLEN];
char tmp_name[FN_REFLEN];
- uint length;
+ size_t length;
/* Create a temporary directory of name TMP-'executable', but without the -t extension */
fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT);
@@ -334,7 +334,8 @@ int main(int argc __attribute__((unused)),
{
pthread_t tid;
pthread_attr_t thr_attr;
- int *param, error, pagen;
+ int *param, error;
+ size_t pagen;
MY_INIT(argv[0]);
#ifndef DBUG_OFF
@@ -413,7 +414,7 @@ int main(int argc __attribute__((unused)),
errno);
exit(1);
}
- DBUG_PRINT("info", ("Page cache %d pages", pagen));
+ DBUG_PRINT("info", ("Page cache %zd pages", pagen));
{
unsigned char *buffr= malloc(TEST_PAGE_SIZE);
uint i;
diff --git a/storage/maria/unittest/ma_pagecache_rwconsist.c b/storage/maria/unittest/ma_pagecache_rwconsist.c
index 0b05d976516..985140091f9 100644
--- a/storage/maria/unittest/ma_pagecache_rwconsist.c
+++ b/storage/maria/unittest/ma_pagecache_rwconsist.c
@@ -181,7 +181,7 @@ char *create_tmpdir(const char *progname)
{
static char test_dirname[FN_REFLEN];
char tmp_name[FN_REFLEN];
- uint length;
+ size_t length;
/* Create a temporary directory of name TMP-'executable', but without the -t extension */
fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT);
@@ -204,7 +204,8 @@ int main(int argc __attribute__((unused)),
{
pthread_t tid;
pthread_attr_t thr_attr;
- int *param, error, pagen;
+ int *param, error;
+ size_t pagen;
MY_INIT(argv[0]);
@@ -282,7 +283,7 @@ int main(int argc __attribute__((unused)),
errno);
exit(1);
}
- DBUG_PRINT("info", ("Page cache %d pages", pagen));
+ DBUG_PRINT("info", ("Page cache %zu pages", pagen));
{
unsigned char *buffr= malloc(TEST_PAGE_SIZE);
memset(buffr, '\0', TEST_PAGE_SIZE);
diff --git a/storage/maria/unittest/ma_pagecache_rwconsist2.c b/storage/maria/unittest/ma_pagecache_rwconsist2.c
index cfc877d5556..9cc2ced2042 100644
--- a/storage/maria/unittest/ma_pagecache_rwconsist2.c
+++ b/storage/maria/unittest/ma_pagecache_rwconsist2.c
@@ -177,7 +177,7 @@ static char *create_tmpdir(const char *progname)
{
static char test_dirname[FN_REFLEN];
char tmp_name[FN_REFLEN];
- uint length;
+ size_t length;
/* Create a temporary directory of name TMP-'executable', but without the -t extension */
fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT);
@@ -200,7 +200,8 @@ int main(int argc __attribute__((unused)),
{
pthread_t tid;
pthread_attr_t thr_attr;
- int *param, error, pagen;
+ int *param, error;
+ size_t pagen;
MY_INIT(argv[0]);
@@ -278,7 +279,7 @@ int main(int argc __attribute__((unused)),
errno);
exit(1);
}
- DBUG_PRINT("info", ("Page cache %d pages", pagen));
+ DBUG_PRINT("info", ("Page cache %zd pages", pagen));
{
unsigned char *buffr= malloc(TEST_PAGE_SIZE);
memset(buffr, '\0', TEST_PAGE_SIZE);
diff --git a/storage/maria/unittest/ma_pagecache_single.c b/storage/maria/unittest/ma_pagecache_single.c
index e149af7cf5e..8de52ccf481 100644
--- a/storage/maria/unittest/ma_pagecache_single.c
+++ b/storage/maria/unittest/ma_pagecache_single.c
@@ -701,7 +701,7 @@ static char *create_tmpdir(const char *progname)
{
static char test_dirname[FN_REFLEN];
char tmp_name[FN_REFLEN];
- uint length;
+ size_t length;
/* Create a temporary directory of name TMP-'executable', but without the -t extension */
fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT);
@@ -724,7 +724,8 @@ int main(int argc __attribute__((unused)),
{
pthread_t tid;
pthread_attr_t thr_attr;
- int *param, error, pagen;
+ int *param, error;
+ size_t pagen;
File tmp_file;
MY_INIT(argv[0]);
@@ -809,7 +810,7 @@ int main(int argc __attribute__((unused)),
errno);
exit(1);
}
- DBUG_PRINT("info", ("Page cache %d pages", pagen));
+ DBUG_PRINT("info", ("Page cache %zd pages", pagen));
pthread_mutex_lock(&LOCK_thread_count);
param=(int*) malloc(sizeof(int));
diff --git a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c
index 69bc2f70f8c..cffe188e855 100644
--- a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c
@@ -233,7 +233,7 @@ int main(int argc __attribute__((unused)), char *argv[])
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55
};
- uchar *long_buffer= malloc(LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2);
+ uchar *long_buffer;
char **default_argv;
PAGECACHE pagecache;
LSN lsn, lsn_base, first_lsn;
@@ -255,6 +255,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
#endif
+ long_buffer= malloc(LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2);
load_defaults("my", load_default_groups, &argc, &argv);
default_argv= argv;
get_options(&argc, &argv);
@@ -758,9 +759,12 @@ err:
if (maria_log_remove(maria_data_root))
exit(1);
+ free(long_buffer);
+
my_uuid_end();
my_free_open_file_info();
my_end(0);
+
return (MY_TEST(exit_status()));
}
diff --git a/storage/maria/unittest/ma_test_loghandler_nologs-t.c b/storage/maria/unittest/ma_test_loghandler_nologs-t.c
index a6ccfd754de..310345f0885 100644
--- a/storage/maria/unittest/ma_test_loghandler_nologs-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_nologs-t.c
@@ -191,6 +191,8 @@ int main(int argc __attribute__((unused)), char *argv[])
if (maria_log_remove(maria_data_root))
exit(1);
+ free(long_buffer);
+
my_uuid_end();
my_free_open_file_info();
my_end(0);
diff --git a/storage/maria/unittest/ma_test_loghandler_purge-t.c b/storage/maria/unittest/ma_test_loghandler_purge-t.c
index ef31b47c9c5..a4eecd6bfdc 100644
--- a/storage/maria/unittest/ma_test_loghandler_purge-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_purge-t.c
@@ -36,7 +36,7 @@ static const char *default_dbug_option;
int main(int argc __attribute__((unused)), char *argv[])
{
ulong i;
- uint pagen;
+ size_t pagen;
uchar long_tr_id[6];
PAGECACHE pagecache;
LSN lsn;
diff --git a/storage/maria/unittest/test_file.c b/storage/maria/unittest/test_file.c
index 7ee38c57068..1f74790c565 100644
--- a/storage/maria/unittest/test_file.c
+++ b/storage/maria/unittest/test_file.c
@@ -54,7 +54,7 @@ int test_file(PAGECACHE_FILE file, char *file_name,
LARGE_INTEGER li;
if(GetFileAttributesEx(file_name, GetFileExInfoStandard, &file_attr) == 0)
{
- diag("Can't GetFileAttributesEx %s (errno: %d)\n", file_name,
+ diag("Can't GetFileAttributesEx %s (errno: %lu)\n", file_name,
GetLastError());
res= 0;
goto err;
diff --git a/storage/mroonga/CMakeLists.txt b/storage/mroonga/CMakeLists.txt
index a9f9d7cc8b2..5d8e8c1eeb8 100644
--- a/storage/mroonga/CMakeLists.txt
+++ b/storage/mroonga/CMakeLists.txt
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
cmake_minimum_required(VERSION 2.6)
project(mroonga)
@@ -51,6 +51,14 @@ if(MSVC)
endif()
endif()
+if(MRN_BUNDLED)
+ if(WITHOUT_MROONGA OR
+ WITHOUT_MROONGA_STORAGE_ENGINE OR
+ "${PLUGIN_MROONGA}" STREQUAL "NO")
+ return()
+ endif()
+endif()
+
set(MRN_BUNDLED_GROONGA_RELATIVE_DIR "vendor/groonga")
set(MRN_BUNDLED_GROONGA_DIR
"${CMAKE_CURRENT_SOURCE_DIR}/${MRN_BUNDLED_GROONGA_RELATIVE_DIR}")
@@ -79,6 +87,58 @@ file(READ ${MRN_SOURCE_DIR}/version_micro MRN_VERSION_MICRO)
file(READ ${MRN_SOURCE_DIR}/version_in_hex MRN_VERSION_IN_HEX)
file(READ ${MRN_SOURCE_DIR}/plugin_version MRN_PLUGIN_VERSION)
+if(MRN_GROONGA_BUNDLED)
+ option(MRN_GROONGA_EMBED
+ "Embed libgroonga"
+ ON)
+ if(MRN_GROONGA_EMBED)
+ set(GRN_EMBED ON)
+ endif()
+
+ set(MRN_BUNDLED_GROONGA_NORMALIZER_MYSQL_DIR
+ "${MRN_BUNDLED_GROONGA_DIR}/vendor/plugins/groonga-normalizer-mysql")
+ option(MRN_GROONGA_NORMALIZER_MYSQL_EMBED
+ "Embed groonga-normalizer-mysql Groonga plugin"
+ ON)
+ if(EXISTS ${MRN_BUNDLED_GROONGA_NORMALIZER_MYSQL_DIR})
+ set(GROONGA_NORMALIZER_MYSQL_FOUND ON)
+ else()
+ set(GROONGA_NORMALIZER_MYSQL_FOUND OFF)
+ set(MRN_GROONGA_NORMALIZER_MYSQL_EMBED OFF)
+ endif()
+ if(MRN_GROONGA_NORMALIZER_MYSQL_EMBED)
+ set(GROONGA_NORMALIZER_MYSQL_EMBED ON)
+ endif()
+
+ file(READ "${MRN_BUNDLED_GROONGA_DIR}/bundled_lz4_version"
+ MRN_BUNDLED_LZ4_VERSION)
+ string(STRIP
+ "${MRN_BUNDLED_LZ4_VERSION}"
+ MRN_BUNDLED_LZ4_VERSION)
+ set(MRN_BUNDLED_LZ4_DIR
+ "${MRN_BUNDLED_GROONGA_DIR}/vendor/lz4-${MRN_BUNDLED_LZ4_VERSION}")
+ if(EXISTS ${MRN_BUNDLED_LZ4_DIR})
+ set(GRN_WITH_BUNDLED_LZ4 ON)
+ set(GRN_WITH_LZ4 "yes")
+ else()
+ set(GRN_WITH_LZ4 "no")
+ endif()
+
+ add_subdirectory("${MRN_BUNDLED_GROONGA_RELATIVE_DIR}")
+else()
+ set(MRN_GROONGA_EMBED OFF)
+
+ file(READ ${MRN_SOURCE_DIR}/required_groonga_version REQUIRED_GROONGA_VERSION)
+ string(STRIP "${REQUIRED_GROONGA_VERSION}" REQUIRED_GROONGA_VERSION)
+
+ file(READ
+ ${MRN_SOURCE_DIR}/required_groonga_normalizer_mysql_version
+ REQUIRED_GROONGA_NORMALIZER_MYSQL_VERSION)
+ string(STRIP
+ "${REQUIRED_GROONGA_NORMALIZER_MYSQL_VERSION}"
+ REQUIRED_GROONGA_NORMALIZER_MYSQL_VERSION)
+endif()
+
set(MRN_PACKAGE_STRING "${PROJECT_NAME} ${MRN_VERSION}")
include(CheckCCompilerFlag)
@@ -107,18 +167,7 @@ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/udf/sources.am MRN_UDF_SOURCES)
string(REGEX REPLACE "([^;]+)" "${MRN_RELATIVE_DIR_PREFIX}udf/\\1"
MRN_UDF_SOURCES "${MRN_UDF_SOURCES}")
-set(MRN_ALL_SOURCES
- ${MRN_SOURCES}
- ${MRN_UDF_SOURCES}
- ${LIBMRN_NO_MYSQL_SOURCES}
- ${LIBMRN_NEED_MYSQL_SOURCES})
-
if(MRN_BUNDLED)
- mysql_add_plugin(mroonga ${MRN_ALL_SOURCES} STORAGE_ENGINE MODULE_ONLY)
- if(NOT TARGET mroonga)
- return()
- endif()
-
set(MYSQL_SOURCE_DIR ${CMAKE_SOURCE_DIR})
set(MYSQL_BUILD_DIR ${MYSQL_SOURCE_DIR})
set(MYSQL_CONFIG ${CMAKE_SOURCE_DIR}/scripts/mysql_config)
@@ -134,44 +183,6 @@ else()
endif()
find_path(MYSQL_CONFIG "${MYSQL_CONFIG}")
-if(MRN_GROONGA_BUNDLED)
- option(MRN_GROONGA_EMBED
- "Embed libgroonga"
- ON)
- if(MRN_GROONGA_EMBED)
- set(GRN_EMBED ON)
- endif()
-
- set(MRN_BUNDLED_GROONGA_NORMALIZER_MYSQL_DIR
- "${MRN_BUNDLED_GROONGA_DIR}/vendor/plugins/groonga-normalizer-mysql")
- option(MRN_GROONGA_NORMALIZER_MYSQL_EMBED
- "Embed groonga-normalizer-mysql Groonga plugin"
- ON)
- if(EXISTS ${MRN_BUNDLED_GROONGA_NORMALIZER_MYSQL_DIR})
- set(GROONGA_NORMALIZER_MYSQL_FOUND ON)
- else()
- set(GROONGA_NORMALIZER_MYSQL_FOUND OFF)
- set(MRN_GROONGA_NORMALIZER_MYSQL_EMBED OFF)
- endif()
- if(MRN_GROONGA_NORMALIZER_MYSQL_EMBED)
- set(GROONGA_NORMALIZER_MYSQL_EMBED ON)
- endif()
-
- add_subdirectory("${MRN_BUNDLED_GROONGA_RELATIVE_DIR}")
-else()
- set(MRN_GROONGA_EMBED OFF)
-
- file(READ ${MRN_SOURCE_DIR}/required_groonga_version REQUIRED_GROONGA_VERSION)
- string(STRIP "${REQUIRED_GROONGA_VERSION}" REQUIRED_GROONGA_VERSION)
-
- file(READ
- ${MRN_SOURCE_DIR}/required_groonga_normalizer_mysql_version
- REQUIRED_GROONGA_NORMALIZER_MYSQL_VERSION)
- string(STRIP
- "${REQUIRED_GROONGA_NORMALIZER_MYSQL_VERSION}"
- REQUIRED_GROONGA_NORMALIZER_MYSQL_VERSION)
-endif()
-
if(EXISTS "${MYSQL_SOURCE_DIR}/storage/maria")
set(MYSQL_VARIANT "MariaDB")
else()
@@ -194,6 +205,7 @@ if(EXISTS "${MYSQL_SOURCE_DIR}/libbinlogevents")
set(MYSQL_LIBBINLOGEVENTS_EXPORT_DIR
"${MYSQL_SOURCE_DIR}/libbinlogevents/export")
set(MYSQL_LIBBINLOGEVENTS_INCLUDE_DIR
+ "${MYSQL_BUILD_DIR}/libbinlogevents/include"
"${MYSQL_SOURCE_DIR}/libbinlogevents/include")
else()
set(MYSQL_LIBBINLOGEVENTS_EXPORT_DIR)
@@ -270,6 +282,7 @@ else()
set(MRN_LIBRARY_DIRS
${MRN_LIBRARY_DIRS}
${GROONGA_LIBRARY_DIRS})
+ set(MRN_LIBRARIES ${GROONGA_LIBRARIES})
endif()
include_directories(
@@ -291,11 +304,17 @@ link_directories(
${MRN_LIBRARY_DIRS}
${MYSQL_LIBRARY_DIRS})
+set(MRN_ALL_SOURCES
+ ${MRN_SOURCES}
+ ${MRN_UDF_SOURCES}
+ ${LIBMRN_NO_MYSQL_SOURCES}
+ ${LIBMRN_NEED_MYSQL_SOURCES})
+
if(MRN_BUNDLED)
- target_link_libraries(mroonga ${MRN_LIBRARIES})
- if(NOT TARGET mroonga)
- return()
- endif()
+ mysql_add_plugin(mroonga
+ ${MRN_ALL_SOURCES}
+ STORAGE_ENGINE MODULE_ONLY
+ LINK_LIBRARIES ${MRN_LIBRARIES})
else()
add_library(mroonga MODULE ${MRN_ALL_SOURCES})
@@ -340,8 +359,12 @@ else()
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-strict-aliasing")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-deprecated")
MY_CHECK_AND_SET_COMPILER_FLAG("-fno-implicit-templates")
- MY_CHECK_AND_SET_COMPILER_FLAG("-fno-exceptions")
- MY_CHECK_AND_SET_COMPILER_FLAG("-fno-rtti")
+ if(("${MYSQL_VARIANT}" STREQUAL "MariaDB") OR
+ ("${MYSQL_VARIANT}" STREQUAL "MySQL" AND
+ ${MYSQL_VERSION} VERSION_LESS "5.7.0"))
+ MY_CHECK_AND_SET_COMPILER_FLAG("-fno-exceptions")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-fno-rtti")
+ endif()
MY_CHECK_AND_SET_COMPILER_FLAG("-felide-constructors")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-implicit-fallthrough")
endif()
@@ -362,10 +385,20 @@ else()
install(TARGETS mroonga DESTINATION "${MYSQL_PLUGIN_DIR}")
endif()
+option(MRN_BUILD_FOR_EMBEDDED_SERVER
+ "Whether to build Mroonga for embedded server or not. You can't use Mroonga built for embedded server with non embedded server."
+ OFF)
+if(MRN_BUILD_FOR_EMBEDDED_SERVER)
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "EMBEDDED_LIBRARY")
+endif()
+
if(GROONGA_NORMALIZER_MYSQL_FOUND)
- add_definitions("-DWITH_GROONGA_NORMALIZER_MYSQL=1")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "WITH_GROONGA_NORMALIZER_MYSQL=1")
if(MRN_GROONGA_NORMALIZER_MYSQL_EMBED)
- add_definitions("-DMRN_GROONGA_NORMALIZER_MYSQL_EMBEDDED")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "MRN_GROONGA_NORMALIZER_MYSQL_EMBEDDED")
else()
set_property(TARGET mroonga APPEND PROPERTY
COMPILE_DEFINITIONS "GROONGA_NORMALIZER_MYSQL_PLUGIN_NAME=\"normalizers/mysql\"")
@@ -373,7 +406,8 @@ if(GROONGA_NORMALIZER_MYSQL_FOUND)
endif()
if(MRN_GROONGA_EMBED)
- add_definitions("-DMRN_GROONGA_EMBEDDED")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "MRN_GROONGA_EMBEDDED")
endif()
set(MRN_DEFAULT_PARSER "" CACHE STRING
@@ -419,6 +453,8 @@ else()
set(MRN_DATA_DIR "share/${PROJECT_NAME}")
endif()
install(FILES
+ "${PROJECT_SOURCE_DIR}/AUTHORS"
+ "${PROJECT_SOURCE_DIR}/COPYING"
"${PROJECT_BINARY_DIR}/data/install.sql"
"${PROJECT_SOURCE_DIR}/data/uninstall.sql"
DESTINATION "${MRN_DATA_DIR}/")
diff --git a/storage/mroonga/Makefile.am b/storage/mroonga/Makefile.am
index d783ec883f9..69349ea6a8d 100644
--- a/storage/mroonga/Makefile.am
+++ b/storage/mroonga/Makefile.am
@@ -1,9 +1,9 @@
+ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_ARGS}
AUTOMAKE_OPTIONS = 1.9.7
LOCALES = ja
AM_CPPFLAGS = $(MYSQL_INCLUDES) $(GROONGA_CFLAGS) -I$(top_srcdir)/lib
-ACLOCAL_AMFLAGS = $$ACLOCAL_ARGS
include sources.am
@@ -49,7 +49,13 @@ tag:
cd $(top_srcdir) && \
git tag v$(VERSION) -a -m 'Mroonga $(VERSION)!!!'
-update-latest-release: misc
+ensure-cutter-source-path:
+ @if test -z "$(CUTTER_SOURCE_PATH)"; then \
+ echo "\$$(CUTTER_SOURCE_PATH) is missing"; \
+ exit 1; \
+ fi
+
+update-latest-release: ensure-cutter-source-path
@if test -z "$(OLD_RELEASE)"; then \
echo "\$$(OLD_RELEASE) is missing"; \
exit 1; \
@@ -63,17 +69,40 @@ update-latest-release: misc
exit 1; \
fi
cd $(top_srcdir) && \
- misc/update-latest-release.rb \
+ "$(CUTTER_SOURCE_PATH)/misc/update-latest-release.rb" \
$(PACKAGE) $(OLD_RELEASE) $(OLD_RELEASE_DATE) \
$(VERSION) $(NEW_RELEASE_DATE) \
packages/rpm/centos/mariadb-mroonga.spec.in \
+ packages/rpm/centos/mariadb-10.1-mroonga.spec.in \
+ packages/rpm/centos/mariadb-10.2-mroonga.spec.in \
packages/rpm/centos/mysql55-mroonga.spec.in \
packages/rpm/centos/mysql56-community-mroonga.spec.in \
- packages/debian/changelog \
+ packages/rpm/centos/mysql57-community-mroonga.spec.in \
+ packages/rpm/centos/percona-server-56-mroonga.spec.in \
+ packages/rpm/centos/percona-server-57-mroonga.spec.in \
doc/source/install/*.rst \
doc/locale/*/LC_MESSAGES/install.po \
- $(MROONGA_GITHUB_COM_PATH)/index.html \
- $(MROONGA_GITHUB_COM_PATH)/ja/index.html
+ $(MROONGA_GITHUB_COM_PATH)/_config.yml
+ cd $(top_srcdir) && \
+ "$(CUTTER_SOURCE_PATH)/misc/update-latest-release.rb" \
+ $(PACKAGE)-5.5 $(OLD_RELEASE) $(OLD_RELEASE_DATE) \
+ $(VERSION) $(NEW_RELEASE_DATE) \
+ packages/debian-5.5/changelog
+ cd $(top_srcdir) && \
+ "$(CUTTER_SOURCE_PATH)/misc/update-latest-release.rb" \
+ $(PACKAGE)-5.6 $(OLD_RELEASE) $(OLD_RELEASE_DATE) \
+ $(VERSION) $(NEW_RELEASE_DATE) \
+ packages/debian-5.6/changelog
+ cd $(top_srcdir) && \
+ "$(CUTTER_SOURCE_PATH)/misc/update-latest-release.rb" \
+ $(PACKAGE)-5.7 $(OLD_RELEASE) $(OLD_RELEASE_DATE) \
+ $(VERSION) $(NEW_RELEASE_DATE) \
+ packages/debian-5.7/changelog
+ cd $(top_srcdir) && \
+ "$(CUTTER_SOURCE_PATH)/misc/update-latest-release.rb" \
+ $(PACKAGE)-mariadb-10.0 $(OLD_RELEASE) $(OLD_RELEASE_DATE) \
+ $(VERSION) $(NEW_RELEASE_DATE) \
+ packages/debian-mariadb-10.0/changelog
update-po:
@for lang in $(LOCALES); do \
@@ -144,10 +173,3 @@ upload-to-github:
echo-cutter:
echo $(CUTTER)
-
-misc:
- @if test -z "$(CUTTER_SOURCE_PATH)"; then \
- echo "\$$(CUTTER_SOURCE_PATH) is missing"; \
- exit 1; \
- fi
- ln -s "$(CUTTER_SOURCE_PATH)/misc" misc
diff --git a/storage/mroonga/appveyor.yml b/storage/mroonga/appveyor.yml
index 038d590054e..3cf8ff8d331 100644
--- a/storage/mroonga/appveyor.yml
+++ b/storage/mroonga/appveyor.yml
@@ -1,54 +1,63 @@
version: "{build}"
clone_depth: 10
+environment:
+ global:
+ MARIADB_VERSION: 10.1.26
+ matrix:
+ - CMAKE_GENERATOR_NAME: "Visual Studio 14 2015"
+ - CMAKE_GENERATOR_NAME: "Visual Studio 14 2015 Win64"
+
install:
- cd ..
- choco install -y curl 7zip.commandline
- - curl -O http://mirror.jmu.edu/pub/mariadb/mariadb-10.0.20/source/mariadb-10.0.20.tar.gz
- - 7z x mariadb-10.0.20.tar.gz
- - 7z x mariadb-10.0.20.tar > nul
- - cd mariadb-10.0.20
+ - curl -O http://mirror.jmu.edu/pub/mariadb/mariadb-%MARIADB_VERSION%/source/mariadb-%MARIADB_VERSION%.tar.gz
+ - 7z x mariadb-%MARIADB_VERSION%.tar.gz
+ - 7z x mariadb-%MARIADB_VERSION%.tar > nul
+ - cd mariadb-%MARIADB_VERSION%
- rmdir /S /Q storage\mroonga\
- move ..\mroonga storage\mroonga
- - git clone --quiet --depth 1 https://github.com/groonga/groonga.git ..\groonga
- - cd ..\groonga
- - git submodule update --init
- - cd ..\mariadb-10.0.20
+ - git clone --quiet --depth 1 --recursive https://github.com/groonga/groonga.git ..\groonga
- rmdir /S /Q ..\groonga\test\
+ - cd ..\groonga\vendor
+ - c:\Ruby22-x64\bin\ruby -v download_lz4.rb
+ - c:\Ruby22-x64\bin\ruby -v download_mecab.rb
+ - cd ..\..\mariadb-%MARIADB_VERSION%
- mkdir storage\mroonga\vendor
- move ..\groonga storage\mroonga\vendor\groonga
- git clone --quiet --depth 1 https://github.com/groonga/groonga-normalizer-mysql.git storage\mroonga\vendor\groonga\vendor\plugins\groonga-normalizer-mysql
build_script:
- "echo # > win\\packaging\\CMakeLists.txt"
- - cmake . -G "Visual Studio 12 Win64"
+ - cmake . -G "%CMAKE_GENERATOR_NAME%"
-DCMAKE_BUILD_TYPE=Debug
- -DWITHOUT_ARCHIVE=ON
- -DWITHOUT_BLACKHOLE=ON
- -DWITHOUT_CASSANDRA=ON
- -DWITHOUT_CONNECT=ON
- -DWITHOUT_CSV=ON
- -DWITHOUT_EXAMPLE=ON
- -DWITHOUT_FEDERATED=ON
- -DWITHOUT_FEDERATEDX=ON
- -DWITHOUT_HEAP=ON
- -DWITHOUT_INNOBASE=ON
- -DWITHOUT_MYISAM=ON
- -DWITHOUT_MYISAMMRG=ON
- -DWITHOUT_OQGRAPH=ON
- -DWITHOUT_PERFSCHEMA=OFF
- -DWITHOUT_SEQUENCE=ON
- -DWITHOUT_SPHINX=ON
- -DWITHOUT_SPIDER=ON
- -DWITHOUT_TEST_SQL_DISCOVERY=ON
- -DWITHOUT_TOKUDB=ON
- -DWITHOUT_XTRADB=ON
+ -DPLUGIN_ARCHIVE=NO
+ -DPLUGIN_BLACKHOLE=NO
+ -DPLUGIN_CASSANDRA=NO
+ -DPLUGIN_CONNECT=NO
+ -DPLUGIN_CSV=NO
+ -DPLUGIN_EXAMPLE=NO
+ -DPLUGIN_FEDERATED=NO
+ -DPLUGIN_FEDERATEDX=NO
+ -DPLUGIN_HEAP=NO
+ -DPLUGIN_INNOBASE=NO
+ -DPLUGIN_MYISAM=NO
+ -DPLUGIN_MYISAMMRG=NO
+ -DPLUGIN_OQGRAPH=NO
+ -DPLUGIN_PERFSCHEMA=NO
+ -DPLUGIN_SEQUENCE=NO
+ -DPLUGIN_SPHINX=NO
+ -DPLUGIN_SPIDER=NO
+ -DPLUGIN_TEST_SQL_DISCOVERY=NO
+ -DPLUGIN_TOKUDB=NO
+ -DPLUGIN_XTRADB=NO
-DWITH_UNIT_TESTS=OFF
+ -DWITH_MARIABACKUP=OFF
+ -DGRN_WITH_BUNDLED_MECAB=ON
- cmake --build . --config Debug
notifications:
- provider: Email
to:
- groonga-mysql-commit@lists.sourceforge.jp
- - kou@clear-code.com
on_build_status_changed: true
test: off
diff --git a/storage/mroonga/autogen.sh b/storage/mroonga/autogen.sh
index 7a1d38635d4..f795ad000ec 100755
--- a/storage/mroonga/autogen.sh
+++ b/storage/mroonga/autogen.sh
@@ -1,116 +1,11 @@
#!/bin/sh
-warn() {
- echo " WARNING: $@" 1>&2
-}
-
-# init
-
-LIBTOOLIZE=libtoolize
-ACLOCAL=aclocal
-AUTOCONF=autoconf
-AUTOHEADER=autoheader
-AUTOMAKE=automake
-
-case `uname -s` in
-Darwin)
- LIBTOOLIZE=glibtoolize
- ;;
+case $(uname -s) in
FreeBSD)
- ACLOCAL_ARGS="$ACLOCAL_ARGS -I /usr/local/share/aclocal/"
- ;;
+ ACLOCAL_ARGS="$ACLOCAL_ARGS -I /usr/local/share/aclocal/"
+ ;;
esac
+mkdir -p m4
-# libtoolize
-echo "Searching libtoolize..."
-if [ `which $LIBTOOLIZE` ] ; then
- echo " FOUND: libtoolize -> $LIBTOOLIZE"
-else
- warn "Cannot Found libtoolize... input libtool command"
- read LIBTOOLIZE
- LIBTOOLIZE=`which $LIBTOOLIZE`
- if [ `which $LIBTOOLIZE` ] ; then
- echo " SET: libtoolize -> $LIBTOOLIZE"
- else
- warn "$LIBTOOLIZE: Command not found."
- exit 1;
- fi
-fi
-
-# aclocal
-echo "Searching aclocal..."
-if [ `which $ACLOCAL` ] ; then
- echo " FOUND: aclocal -> $ACLOCAL"
-else
- warn "Cannot Found aclocal... input aclocal command"
- read ACLOCAL
- ACLOCAL=`which $ACLOCAL`
- if [ `which $ACLOCAL` ] ; then
- echo " SET: aclocal -> $ACLOCAL"
- else
- warn "$ACLOCAL: Command not found."
- exit 1;
- fi
-fi
-
-# automake
-echo "Searching automake..."
-if [ `which $AUTOMAKE` ] ; then
- echo " FOUND: automake -> $AUTOMAKE"
-else
- warn "Cannot Found automake... input automake command"
- read AUTOMAKE
- ACLOCAL=`which $AUTOMAKE`
- if [ `which $AUTOMAKE` ] ; then
- echo " SET: automake -> $AUTOMAKE"
- else
- warn "$AUTOMAKE: Command not found."
- exit 1;
- fi
-fi
-
-# autoheader
-echo "Searching autoheader..."
-if [ `which $AUTOHEADER` ] ; then
- echo " FOUND: autoheader -> $AUTOHEADER"
-else
- warn "Cannot Found autoheader... input autoheader command"
- read AUTOHEADER
- ACLOCAL=`which $AUTOHEADER`
- if [ `which $AUTOHEADER` ] ; then
- echo " SET: autoheader -> $AUTOHEADER"
- else
- warn "$AUTOHEADER: Command not found."
- exit 1;
- fi
-fi
-
-# autoconf
-echo "Searching autoconf..."
-if [ `which $AUTOCONF` ] ; then
- echo " FOUND: autoconf -> $AUTOCONF"
-else
- warn "Cannot Found autoconf... input autoconf command"
- read AUTOCONF
- ACLOCAL=`which $AUTOCONF`
- if [ `which $AUTOCONF` ] ; then
- echo " SET: autoconf -> $AUTOCONF"
- else
- warn "$AUTOCONF: Command not found."
- exit 1;
- fi
-fi
-
-set -e
-
-echo "Running libtoolize ..."
-$LIBTOOLIZE --force --copy
-echo "Running aclocal ..."
-$ACLOCAL ${ACLOCAL_ARGS}
-echo "Running autoheader..."
-$AUTOHEADER
-echo "Running automake ..."
-$AUTOMAKE --add-missing --copy
-echo "Running autoconf ..."
-$AUTOCONF
+${AUTORECONF:-autoreconf} --force --install "$@"
diff --git a/storage/mroonga/build/makefiles/sphinx-build.am b/storage/mroonga/build/makefiles/sphinx-build.am
index e237377ba80..57bbcd614e1 100644
--- a/storage/mroonga/build/makefiles/sphinx-build.am
+++ b/storage/mroonga/build/makefiles/sphinx-build.am
@@ -10,10 +10,8 @@ PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = $(PAPEROPT_$(PAPER)) -E $(SPHINXOPTS) $(SOURCE_DIR)
-SPHINX_DIR = $(abs_top_builddir)/doc/sphinx
SPHINX_BUILD_COMMAND = \
DOCUMENT_VERSION="$(DOCUMENT_VERSION)" \
DOCUMENT_VERSION_FULL="$(DOCUMENT_VERSION_FULL)" \
LOCALE="$(LOCALE)" \
- PYTHONPATH="$(SPHINX_DIR):$$PYTHONPATH" \
$(SPHINX_BUILD)
diff --git a/storage/mroonga/config.sh.in b/storage/mroonga/config.sh.in
index e86973bdf88..32e88fd5c3d 100644
--- a/storage/mroonga/config.sh.in
+++ b/storage/mroonga/config.sh.in
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
MYSQL_SOURCE_DIR="@MYSQL_SOURCE_DIR@"
MYSQL_BUILD_DIR="@MYSQL_BUILD_DIR@"
diff --git a/storage/mroonga/configure.ac b/storage/mroonga/configure.ac
index f60b481e0ea..b1e66904f75 100644
--- a/storage/mroonga/configure.ac
+++ b/storage/mroonga/configure.ac
@@ -8,6 +8,7 @@ m4_define([mrn_version_in_hex], m4_include(version_in_hex))
m4_define([mrn_plugin_version], m4_include(plugin_version))
AC_INIT([mroonga], [mrn_version], [groonga-talk@lists.sourceforge.net])
+AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([tar-pax foreign subdir-objects])
@@ -173,18 +174,27 @@ AC_DEFUN([CONFIG_OPTION_MYSQL],[
MYSQL_INCLUDES=""
MYSQL_INCLUDES="$MYSQL_INCLUDES -I$ac_mysql_build_dir/include"
MYSQL_INCLUDES="$MYSQL_INCLUDES -I$ac_mysql_source_dir/sql"
+ if test -d "$ac_mysql_source_dir/sql/auth"; then
+ MYSQL_INCLUDES="$MYSQL_INCLUDES -I$ac_mysql_source_dir/sql/auth"
+ fi
MYSQL_INCLUDES="$MYSQL_INCLUDES -I$ac_mysql_source_dir/include"
if test -d "$ac_mysql_source_dir/extra/rapidjson"; then
mysql_rapidjson_include_dir="$ac_mysql_source_dir/extra/rapidjson/include"
MYSQL_INCLUDES="$MYSQL_INCLUDES -I$mysql_rapidjson_include_dir"
fi
- if test -d "$ac_mysql_source_dir/pcre"; then
- mysql_regex_include_dir="$ac_mysql_source_dir/pcre"
+ if test -d "$ac_mysql_source_dir/extra/regex"; then
+ mysql_regex_include_dir="$ac_mysql_source_dir/extra/regex"
+ MYSQL_INCLUDES="$MYSQL_INCLUDES -I$mysql_regex_include_dir"
else
- mysql_regex_include_dir="$ac_mysql_source_dir/regex"
+ if test -d "$ac_mysql_source_dir/pcre"; then
+ mysql_regex_include_dir="$ac_mysql_source_dir/pcre"
+ else
+ mysql_regex_include_dir="$ac_mysql_source_dir/regex"
+ fi
+ MYSQL_INCLUDES="$MYSQL_INCLUDES -I$mysql_regex_include_dir"
fi
- MYSQL_INCLUDES="$MYSQL_INCLUDES -I$mysql_regex_include_dir"
if test -d "$ac_mysql_source_dir/libbinlogevents"; then
+ MYSQL_INCLUDES="$MYSQL_INCLUDES -I$ac_mysql_build_dir/libbinlogevents/include"
MYSQL_INCLUDES="$MYSQL_INCLUDES -I$ac_mysql_source_dir/libbinlogevents/export"
MYSQL_INCLUDES="$MYSQL_INCLUDES -I$ac_mysql_source_dir/libbinlogevents/include"
fi
@@ -199,7 +209,7 @@ AC_DEFUN([CONFIG_OPTION_MYSQL],[
MYSQL_CXXFLAGS="-fno-implicit-templates -felide-constructors"
case "$MYSQL_MAJOR_MINOR_VERSION" in
- 5.7)
+ 5.7|8.*)
:
;;
*)
@@ -381,6 +391,13 @@ AC_ARG_WITH(rsync-path,
[RSYNC_PATH="packages@packages.groonga.org:public"])
AC_SUBST(RSYNC_PATH)
+AC_ARG_WITH(launchpad-ppa,
+ [AS_HELP_STRING([--with-launchpad-ppa=PPA],
+ [specify Launchpad Personal Package Archive. [default=groonga-ppa]])],
+ [LAUNCHPAD_PPA="$withval"],
+ [LAUNCHPAD_PPA="groonga-ppa"])
+AC_SUBST(LAUNCHPAD_PPA)
+
AC_ARG_WITH(launchpad-uploader-pgp-key,
[AS_HELP_STRING([--with-launchpad-uploader-pgp-key=KEY],
[specify PGP key UID to upload Groonga packages to Launchpad.])],
@@ -429,7 +446,7 @@ if test x"$enable_document" != x"no"; then
AC_PATH_PROG(SPHINX_BUILD, sphinx-build, [])
if test -n "$SPHINX_BUILD"; then
sphinx_build_version=`"$SPHINX_BUILD" --version`
- if ! echo "$sphinx_build_version" | grep -q ' 1\.[[23]]'; then
+ if ! echo "$sphinx_build_version" | grep -q ' 1\.[[2-6]]'; then
AC_MSG_ERROR([
sphinx-build is old: $sphinx_build_version
Sphinx 1.2 or later is required.])
@@ -509,12 +526,19 @@ AC_OUTPUT([
mrn_version.h
mysql-test/mroonga/storage/information_schema/r/plugins.result
mysql-test/mroonga/storage/variable/r/version.result
- packages/debian/control
+ packages/debian-5.5/control
+ packages/debian-5.6/control
+ packages/debian-5.7/control
+ packages/debian-mariadb-10.0/control
packages/apt/env.sh
packages/rpm/centos/mysql55-mroonga.spec
packages/rpm/centos/mysql56-community-mroonga.spec
+ packages/rpm/centos/mysql57-community-mroonga.spec
packages/rpm/centos/mariadb-mroonga.spec
+ packages/rpm/centos/mariadb-10.1-mroonga.spec
+ packages/rpm/centos/mariadb-10.2-mroonga.spec
packages/rpm/centos/percona-server-56-mroonga.spec
+ packages/rpm/centos/percona-server-57-mroonga.spec
packages/yum/env.sh
data/install.sql
])
diff --git a/storage/mroonga/data/install.sql.in b/storage/mroonga/data/install.sql.in
index b0c930c8144..d7d5f3c4ad6 100644
--- a/storage/mroonga/data/install.sql.in
+++ b/storage/mroonga/data/install.sql.in
@@ -17,3 +17,19 @@ CREATE FUNCTION mroonga_command RETURNS STRING
DROP FUNCTION IF EXISTS mroonga_escape;
CREATE FUNCTION mroonga_escape RETURNS STRING
SONAME 'ha_mroonga@MRN_PLUGIN_SUFFIX@';
+
+DROP FUNCTION IF EXISTS mroonga_snippet_html;
+CREATE FUNCTION mroonga_snippet_html RETURNS STRING
+ SONAME 'ha_mroonga@MRN_PLUGIN_SUFFIX@';
+
+DROP FUNCTION IF EXISTS mroonga_normalize;
+CREATE FUNCTION mroonga_normalize RETURNS STRING
+ SONAME 'ha_mroonga@MRN_PLUGIN_SUFFIX@';
+
+DROP FUNCTION IF EXISTS mroonga_highlight_html;
+CREATE FUNCTION mroonga_highlight_html RETURNS STRING
+ SONAME 'ha_mroonga@MRN_PLUGIN_SUFFIX@';
+
+DROP FUNCTION IF EXISTS mroonga_query_expand;
+CREATE FUNCTION mroonga_query_expand RETURNS STRING
+ SONAME 'ha_mroonga@MRN_PLUGIN_SUFFIX@';
diff --git a/storage/mroonga/data/uninstall.sql b/storage/mroonga/data/uninstall.sql
index b79e6c03d18..5713e074224 100644
--- a/storage/mroonga/data/uninstall.sql
+++ b/storage/mroonga/data/uninstall.sql
@@ -2,6 +2,10 @@ DROP FUNCTION IF EXISTS last_insert_grn_id;
DROP FUNCTION IF EXISTS mroonga_snippet;
DROP FUNCTION IF EXISTS mroonga_command;
DROP FUNCTION IF EXISTS mroonga_escape;
+DROP FUNCTION IF EXISTS mroonga_snippet_html;
+DROP FUNCTION IF EXISTS mroonga_normalize;
+DROP FUNCTION IF EXISTS mroonga_highlight_html;
+DROP FUNCTION IF EXISTS mroonga_query_expand;
UNINSTALL PLUGIN Mroonga;
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index 96fe2b05ee7..e0d3fadba00 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -2,7 +2,7 @@
/*
Copyright(C) 2010 Tetsuro IKEDA
Copyright(C) 2010-2013 Kentoku SHIBA
- Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
Copyright(C) 2013 Kenji Maruyama <mmmaru777@gmail.com>
This library is free software; you can redistribute it and/or
@@ -66,14 +66,9 @@
# include <unistd.h>
#endif
-#define MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(type, variable_name, variable_size) \
- type *variable_name = \
- (type *)mrn_my_malloc(sizeof(type) * (variable_size), MYF(MY_WME))
-#define MRN_FREE_VARIABLE_LENGTH_ARRAYS(variable_name) \
- my_free(variable_name)
-
#include "mrn_err.h"
#include "mrn_table.hpp"
+#include <groonga/plugin.h>
#include "ha_mroonga.hpp"
#include <mrn_path_mapper.hpp>
#include <mrn_index_table_name.hpp>
@@ -91,9 +86,17 @@
#include <mrn_time_converter.hpp>
#include <mrn_smart_grn_obj.hpp>
#include <mrn_database_manager.hpp>
+#include <mrn_context_pool.hpp>
#include <mrn_grn.hpp>
#include <mrn_value_decoder.hpp>
#include <mrn_database_repairer.hpp>
+#include <mrn_operation.hpp>
+#include <mrn_column_name.hpp>
+#include <mrn_count_skip_checker.hpp>
+#include <mrn_variables.hpp>
+#include <mrn_query_parser.hpp>
+#include <mrn_smart_bitmap.hpp>
+#include <mrn_table_fields_offset_mover.hpp>
#ifdef MRN_SUPPORT_FOREIGN_KEYS
# include <sql_table.h>
@@ -143,10 +146,18 @@ static mysql_mutex_t *mrn_LOCK_open;
# define MRN_NEED_M_LOCK_TYPE_CHECK_FOR_WRAPPER_EXTERNAL_LOCK
#endif
-#if MYSQL_VERSION_ID >= 50603 || defined(MRN_MARIADB_P)
-# define MRN_ORDER_IS_ASC(order) ((order)->direction == ORDER::ORDER_ASC)
+#ifdef MRN_MARIADB_P
+# if MYSQL_VERSION_ID >= 100200
+# define MRN_ORDER_IS_ASC(order) ((order)->direction == ORDER::ORDER_ASC)
+# else
+# define MRN_ORDER_IS_ASC(order) ((order)->asc)
+# endif
#else
-# define MRN_ORDER_IS_ASC(order) ((order)->asc)
+# if MYSQL_VERSION_ID >= 50603
+# define MRN_ORDER_IS_ASC(order) ((order)->direction == ORDER::ORDER_ASC)
+# else
+# define MRN_ORDER_IS_ASC(order) ((order)->asc)
+# endif
#endif
#define MRN_STRINGIFY(macro_or_string) MRN_STRINGIFY_ARG(macro_or_string)
@@ -200,22 +211,6 @@ static mysql_mutex_t *mrn_LOCK_open;
#endif
#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
-# define MRN_SELECT_LEX_GET_WHERE_COND(select_lex) \
- ((select_lex)->where_cond())
-# define MRN_SELECT_LEX_GET_HAVING_COND(select_lex) \
- ((select_lex)->having_cond())
-# define MRN_SELECT_LEX_GET_ACTIVE_OPTIONS(select_lex) \
- ((select_lex)->active_options())
-#else
-# define MRN_SELECT_LEX_GET_WHERE_COND(select_lex) \
- ((select_lex)->where)
-# define MRN_SELECT_LEX_GET_HAVING_COND(select_lex) \
- ((select_lex)->having)
-# define MRN_SELECT_LEX_GET_ACTIVE_OPTIONS(select_lex) \
- ((select_lex)->options)
-#endif
-
-#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
# define MRN_TABLE_LIST_GET_DERIVED(table_list) NULL
#else
# define MRN_TABLE_LIST_GET_DERIVED(table_list) (table_list)->derived
@@ -249,10 +244,6 @@ static const char *MRN_PLUGIN_AUTHOR = "The Mroonga project";
extern "C" {
#endif
-/* groonga's internal functions */
-int grn_atoi(const char *nptr, const char *end, const char **rest);
-uint grn_atoui(const char *nptr, const char *end, const char **rest);
-
#ifdef HAVE_PSI_INTERFACE
# ifdef WIN32
# ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE
@@ -266,18 +257,41 @@ static PSI_mutex_key mrn_allocated_thds_mutex_key;
PSI_mutex_key mrn_share_mutex_key;
PSI_mutex_key mrn_long_term_share_auto_inc_mutex_key;
static PSI_mutex_key mrn_log_mutex_key;
+static PSI_mutex_key mrn_query_log_mutex_key;
static PSI_mutex_key mrn_db_manager_mutex_key;
+static PSI_mutex_key mrn_context_pool_mutex_key;
+static PSI_mutex_key mrn_operations_mutex_key;
+
+# if (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 80002)
+# define MRN_MUTEXT_INFO_ENTRY(key, name, flags, volatility) \
+ {key, name, flags, volatility}
+# else
+# define MRN_MUTEXT_INFO_ENTRY(key, name, flags, volatility) \
+ {key, name, flags}
+# endif
static PSI_mutex_info mrn_mutexes[] =
{
- {&mrn_open_tables_mutex_key, "open_tables", PSI_FLAG_GLOBAL},
- {&mrn_long_term_share_mutex_key, "long_term_share", PSI_FLAG_GLOBAL},
- {&mrn_allocated_thds_mutex_key, "allocated_thds", PSI_FLAG_GLOBAL},
- {&mrn_share_mutex_key, "share", 0},
- {&mrn_long_term_share_auto_inc_mutex_key,
- "long_term_share::auto_inc", 0},
- {&mrn_log_mutex_key, "log", PSI_FLAG_GLOBAL},
- {&mrn_db_manager_mutex_key, "DatabaseManager", PSI_FLAG_GLOBAL}
+ MRN_MUTEXT_INFO_ENTRY(&mrn_open_tables_mutex_key,
+ "mrn::open_tables", PSI_FLAG_GLOBAL, 0),
+ MRN_MUTEXT_INFO_ENTRY(&mrn_long_term_share_mutex_key,
+ "mrn::long_term_share", PSI_FLAG_GLOBAL, 0),
+ MRN_MUTEXT_INFO_ENTRY(&mrn_allocated_thds_mutex_key,
+ "mrn::allocated_thds", PSI_FLAG_GLOBAL, 0),
+ MRN_MUTEXT_INFO_ENTRY(&mrn_share_mutex_key,
+ "mrn::share", 0, 0),
+ MRN_MUTEXT_INFO_ENTRY(&mrn_long_term_share_auto_inc_mutex_key,
+ "mrn::long_term_share::auto_inc", 0, 0),
+ MRN_MUTEXT_INFO_ENTRY(&mrn_log_mutex_key,
+ "mrn::log", PSI_FLAG_GLOBAL, 0),
+ MRN_MUTEXT_INFO_ENTRY(&mrn_query_log_mutex_key,
+ "mrn::query_log", PSI_FLAG_GLOBAL, 0),
+ MRN_MUTEXT_INFO_ENTRY(&mrn_db_manager_mutex_key,
+ "mrn::DatabaseManager", PSI_FLAG_GLOBAL, 0),
+ MRN_MUTEXT_INFO_ENTRY(&mrn_context_pool_mutex_key,
+ "mrn::ContextPool", PSI_FLAG_GLOBAL, 0),
+ MRN_MUTEXT_INFO_ENTRY(&mrn_operations_mutex_key,
+ "mrn::Operations", PSI_FLAG_GLOBAL, 0)
};
#endif
@@ -294,10 +308,14 @@ mysql_mutex_t mrn_allocated_thds_mutex;
/* internal variables */
static grn_ctx mrn_ctx;
static mysql_mutex_t mrn_log_mutex;
+static mysql_mutex_t mrn_query_log_mutex;
static grn_obj *mrn_db;
static grn_ctx mrn_db_manager_ctx;
static mysql_mutex_t mrn_db_manager_mutex;
mrn::DatabaseManager *mrn_db_manager = NULL;
+static mysql_mutex_t mrn_context_pool_mutex;
+mrn::ContextPool *mrn_context_pool = NULL;
+static mysql_mutex_t mrn_operations_mutex;
#ifdef WIN32
@@ -523,6 +541,18 @@ static const char *mrn_inspect_extra_function(enum ha_extra_function operation)
case HA_EXTRA_DETACH_CHILDREN:
inspected = "HA_EXTRA_DETACH_CHILDREN";
break;
+ case HA_EXTRA_STARTING_ORDERED_INDEX_SCAN:
+ inspected = "HA_EXTRA_STARTING_ORDERED_INDEX_SCAN";
+ break;
+ case HA_EXTRA_BEGIN_ALTER_COPY:
+ inspected = "HA_EXTRA_BEGIN_ALTER_COPY";
+ break;
+ case HA_EXTRA_END_ALTER_COPY:
+ inspected = "HA_EXTRA_END_ALTER_COPY";
+ break;
+ case HA_EXTRA_FAKE_START_STMT:
+ inspected = "HA_EXTRA_FAKE_START_STMT";
+ break;
#ifdef MRN_HAVE_HA_EXTRA_EXPORT
case HA_EXTRA_EXPORT:
inspected = "HA_EXTRA_EXPORT";
@@ -543,6 +573,26 @@ static const char *mrn_inspect_extra_function(enum ha_extra_function operation)
inspected = "HA_EXTRA_PREPARE_FOR_FORCED_CLOSE";
break;
#endif
+#ifdef MRN_HAVE_HA_EXTRA_SKIP_SERIALIZABLE_DD_VIEW
+ case HA_EXTRA_SKIP_SERIALIZABLE_DD_VIEW:
+ inspected = "HA_EXTRA_SKIP_SERIALIZABLE_DD_VIEW";
+ break;
+#endif
+#ifdef MRN_HAVE_HA_EXTRA_BEGIN_ALTER_COPY
+ case HA_EXTRA_BEGIN_ALTER_COPY:
+ inspected = "HA_EXTRA_BEGIN_ALTER_COPY";
+ break;
+#endif
+#ifdef MRN_HAVE_HA_EXTRA_END_ALTER_COPY
+ case HA_EXTRA_END_ALTER_COPY:
+ inspected = "HA_EXTRA_END_ALTER_COPY";
+ break;
+#endif
+#ifdef MRN_HAVE_HA_EXTRA_NO_AUTOINC_LOCKING
+ case HA_EXTRA_NO_AUTOINC_LOCKING:
+ inspected = "HA_EXTRA_NO_AUTOINC_LOCKING";
+ break;
+#endif
}
return inspected;
}
@@ -579,6 +629,7 @@ static FILE *mrn_log_file = NULL;
static bool mrn_log_file_opened = false;
static grn_log_level mrn_log_level_default = GRN_LOG_DEFAULT_LEVEL;
static ulong mrn_log_level = mrn_log_level_default;
+static char *mrn_query_log_file_path = NULL;
char *mrn_default_tokenizer = NULL;
char *mrn_default_wrapper_engine = NULL;
@@ -586,16 +637,10 @@ static int mrn_lock_timeout = grn_get_lock_timeout();
static char *mrn_libgroonga_version = const_cast<char *>(grn_get_version());
static char *mrn_version = const_cast<char *>(MRN_VERSION);
static char *mrn_vector_column_delimiter = NULL;
-static my_bool mrn_libgroonga_support_zlib = FALSE;
-static my_bool mrn_libgroonga_support_lz4 = FALSE;
-typedef enum {
- MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT = (1 << 0),
- MRN_BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_QUERY = (1 << 1),
- MRN_BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_SCRIPT = (1 << 2),
- MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_COLUMN = (1 << 3),
- MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_UPDATE = (1 << 4),
- MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_LEADING_NOT = (1 << 5)
-} mrn_boolean_mode_syntax_flag;
+static mrn_bool mrn_libgroonga_support_zlib = false;
+static mrn_bool mrn_libgroonga_support_lz4 = false;
+static mrn_bool mrn_libgroonga_support_zstd = false;
+static mrn_bool mrn_enable_operations_recording = true;
#ifdef MRN_SUPPORT_THDVAR_SET
static const char *mrn_boolean_mode_sytnax_flag_names[] = {
"DEFAULT",
@@ -614,28 +659,13 @@ static TYPELIB mrn_boolean_mode_syntax_flags_typelib = {
};
#endif
#ifdef MRN_GROONGA_EMBEDDED
-static my_bool mrn_libgroonga_embedded = TRUE;
+static mrn_bool mrn_libgroonga_embedded = true;
#else
-static my_bool mrn_libgroonga_embedded = FALSE;
+static mrn_bool mrn_libgroonga_embedded = false;
#endif
-typedef enum {
- MRN_ACTION_ON_ERROR_ERROR,
- MRN_ACTION_ON_ERROR_ERROR_AND_LOG,
- MRN_ACTION_ON_ERROR_IGNORE,
- MRN_ACTION_ON_ERROR_IGNORE_AND_LOG,
-} mrn_action_on_error;
-
-static const char *mrn_action_on_error_names[] = {
- "ERROR",
- "ERROR_AND_LOG",
- "IGNORE",
- "IGNORE_AND_LOG",
- NullS,
-};
-
-static mrn_action_on_error mrn_action_on_fulltext_query_error_default =
- MRN_ACTION_ON_ERROR_ERROR_AND_LOG;
+static mrn::variables::ActionOnError mrn_action_on_fulltext_query_error_default =
+ mrn::variables::ACTION_ON_ERROR_ERROR_AND_LOG;
static void mrn_logger_log(grn_ctx *ctx, grn_log_level level,
const char *timestamp, const char *title,
@@ -752,20 +782,19 @@ static void mrn_log_file_update(THD *thd, struct st_mysql_sys_var *var,
const char *new_value = *((const char **)save);
char **old_value_ptr = (char **)var_ptr;
- grn_ctx ctx;
- grn_ctx_init(&ctx, 0);
- mrn_change_encoding(&ctx, system_charset_info);
+ grn_ctx *ctx = &mrn_ctx;
+ mrn_change_encoding(ctx, system_charset_info);
const char *new_log_file_name;
new_log_file_name = *old_value_ptr;
if (strcmp(*old_value_ptr, new_value) == 0) {
- GRN_LOG(&ctx, GRN_LOG_NOTICE,
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
"log file isn't changed "
"because the requested path isn't different: <%s>",
new_value);
} else {
- GRN_LOG(&ctx, GRN_LOG_NOTICE,
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
"log file is changed: <%s> -> <%s>",
*old_value_ptr, new_value);
@@ -786,18 +815,18 @@ static void mrn_log_file_update(THD *thd, struct st_mysql_sys_var *var,
}
if (log_file_open_errno == 0) {
- GRN_LOG(&ctx, GRN_LOG_NOTICE,
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
"log file is changed: <%s> -> <%s>",
*old_value_ptr, new_value);
new_log_file_name = new_value;
} else {
if (mrn_log_file) {
- GRN_LOG(&ctx, GRN_LOG_ERROR,
+ GRN_LOG(ctx, GRN_LOG_ERROR,
"log file isn't changed "
"because the requested path can't be opened: <%s>: <%s>",
new_value, strerror(log_file_open_errno));
} else {
- GRN_LOG(&ctx, GRN_LOG_ERROR,
+ GRN_LOG(ctx, GRN_LOG_ERROR,
"log file can't be opened: <%s>: <%s>",
new_value, strerror(log_file_open_errno));
}
@@ -812,8 +841,6 @@ static void mrn_log_file_update(THD *thd, struct st_mysql_sys_var *var,
*old_value_ptr = mrn_my_strdup(new_log_file_name, MYF(MY_WME));
#endif
- grn_ctx_fin(&ctx);
-
DBUG_VOID_RETURN;
}
@@ -824,23 +851,100 @@ static MYSQL_SYSVAR_STR(log_file, mrn_log_file_path,
mrn_log_file_update,
MRN_LOG_FILE_PATH);
+static void mrn_query_log_file_update(THD *thd, struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+ const char *new_value = *((const char **)save);
+ char **old_value_ptr = (char **)var_ptr;
+ const char *normalized_new_value = NULL;
+
+ grn_ctx *ctx = &mrn_ctx;
+ mrn_change_encoding(ctx, system_charset_info);
+
+ const char *new_query_log_file_name;
+ new_query_log_file_name = *old_value_ptr;
+
+ bool need_update = false;
+ if (!*old_value_ptr) {
+ if (new_value && new_value[0] != '\0') {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "query log is enabled: <%s>",
+ new_value);
+ need_update = true;
+ normalized_new_value = new_value;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "query log file is still disabled");
+ }
+ } else {
+ if (!new_value || new_value[0] == '\0') {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "query log file is disabled: <%s>",
+ *old_value_ptr);
+ need_update = true;
+ normalized_new_value = NULL;
+ } else if (strcmp(*old_value_ptr, new_value) == 0) {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "query log file isn't changed "
+ "because the requested path isn't different: <%s>",
+ new_value);
+ } else {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "query log file is changed: <%s> -> <%s>",
+ *old_value_ptr, new_value);
+ need_update = true;
+ normalized_new_value = new_value;
+ }
+ }
+
+ if (need_update) {
+ { // TODO: Remove me when Groonga 7.0.5 is released.
+ mrn::Lock lock(&mrn_query_log_mutex);
+ grn_default_query_logger_set_path(normalized_new_value);
+ }
+ grn_query_logger_reopen(ctx);
+ new_query_log_file_name = normalized_new_value;
+ }
+
+#ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR
+ char *old_query_log_file_name = *old_value_ptr;
+#endif
+ if (new_query_log_file_name) {
+ *old_value_ptr = mrn_my_strdup(new_query_log_file_name, MYF(0));
+ } else {
+ *old_value_ptr = NULL;
+ }
+#ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR
+ my_free(old_query_log_file_name);
+#endif
+
+ DBUG_VOID_RETURN;
+}
+
+static MYSQL_SYSVAR_STR(query_log_file, mrn_query_log_file_path,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
+ "query log file for " MRN_PLUGIN_NAME_STRING,
+ NULL,
+ mrn_query_log_file_update,
+ NULL);
+
static void mrn_default_tokenizer_update(THD *thd, struct st_mysql_sys_var *var,
void *var_ptr, const void *save)
{
MRN_DBUG_ENTER_FUNCTION();
const char *new_value = *((const char **)save);
char **old_value_ptr = (char **)var_ptr;
- grn_ctx ctx;
+ grn_ctx *ctx = &mrn_ctx;
- grn_ctx_init(&ctx, 0);
- mrn_change_encoding(&ctx, system_charset_info);
+ mrn_change_encoding(ctx, system_charset_info);
if (strcmp(*old_value_ptr, new_value) == 0) {
- GRN_LOG(&ctx, GRN_LOG_NOTICE,
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
"default tokenizer for fulltext index isn't changed "
"because the requested default tokenizer isn't different: <%s>",
new_value);
} else {
- GRN_LOG(&ctx, GRN_LOG_NOTICE,
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
"default tokenizer for fulltext index is changed: <%s> -> <%s>",
*old_value_ptr, new_value);
}
@@ -852,8 +956,6 @@ static void mrn_default_tokenizer_update(THD *thd, struct st_mysql_sys_var *var,
*old_value_ptr = (char *)new_value;
#endif
- grn_ctx_fin(&ctx);
-
DBUG_VOID_RETURN;
}
@@ -959,6 +1061,14 @@ static MYSQL_SYSVAR_STR(default_wrapper_engine, mrn_default_wrapper_engine,
NULL,
NULL);
+static const char *mrn_action_on_error_names[] = {
+ "ERROR",
+ "ERROR_AND_LOG",
+ "IGNORE",
+ "IGNORE_AND_LOG",
+ NullS,
+};
+
static TYPELIB mrn_action_on_error_typelib =
{
array_elements(mrn_action_on_error_names) - 1,
@@ -1013,7 +1123,7 @@ static MYSQL_SYSVAR_STR(version, mrn_version,
NULL,
MRN_VERSION);
-static my_bool grn_check_zlib_support()
+static mrn_bool grn_check_zlib_support()
{
bool is_zlib_support = false;
grn_obj grn_support_p;
@@ -1026,7 +1136,14 @@ static my_bool grn_check_zlib_support()
return is_zlib_support;
}
-static my_bool grn_check_lz4_support()
+static MYSQL_SYSVAR_BOOL(libgroonga_support_zlib, mrn_libgroonga_support_zlib,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "The status of libgroonga supports zlib",
+ NULL,
+ NULL,
+ grn_check_zlib_support());
+
+static mrn_bool grn_check_lz4_support()
{
bool is_lz4_support = false;
grn_obj grn_support_p;
@@ -1039,19 +1156,51 @@ static my_bool grn_check_lz4_support()
return is_lz4_support;
}
-static MYSQL_SYSVAR_BOOL(libgroonga_support_zlib, mrn_libgroonga_support_zlib,
+static MYSQL_SYSVAR_BOOL(libgroonga_support_lz4, mrn_libgroonga_support_lz4,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
- "The status of libgroonga supports zlib",
+ "The status of libgroonga supports LZ4",
NULL,
NULL,
- grn_check_zlib_support());
+ grn_check_lz4_support());
-static MYSQL_SYSVAR_BOOL(libgroonga_support_lz4, mrn_libgroonga_support_lz4,
+static mrn_bool grn_check_zstd_support()
+{
+ bool is_zstd_support = false;
+ grn_obj grn_support_p;
+
+ GRN_BOOL_INIT(&grn_support_p, 0);
+ grn_obj_get_info(&mrn_ctx, NULL, GRN_INFO_SUPPORT_ZSTD, &grn_support_p);
+ is_zstd_support = (GRN_BOOL_VALUE(&grn_support_p));
+ grn_obj_unlink(&mrn_ctx, &grn_support_p);
+
+ return is_zstd_support;
+}
+
+static MYSQL_SYSVAR_BOOL(libgroonga_support_zstd, mrn_libgroonga_support_zstd,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
- "The status of libgroonga supports LZ4",
+ "The status of libgroonga supports Zstandard",
NULL,
NULL,
- grn_check_lz4_support());
+ grn_check_zstd_support());
+
+static void mrn_enable_operations_recording_update(THD *thd, struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+ const bool new_value = *static_cast<const bool *>(save);
+ bool *old_value_ptr = static_cast<bool *>(var_ptr);
+
+ *old_value_ptr = new_value;
+
+ DBUG_VOID_RETURN;
+}
+
+static MYSQL_SYSVAR_BOOL(enable_operations_recording, mrn_enable_operations_recording,
+ PLUGIN_VAR_RQCMDARG,
+ "Whether recording operations for recovery is enabled or not",
+ NULL,
+ mrn_enable_operations_recording_update,
+ true);
#ifdef MRN_SUPPORT_THDVAR_SET
static MYSQL_THDVAR_SET(boolean_mode_syntax_flags,
@@ -1063,7 +1212,7 @@ static MYSQL_THDVAR_SET(boolean_mode_syntax_flags,
"ALLOW_COLUMN, ALLOW_UPDATE and ALLOW_LEADING_NOT",
NULL,
NULL,
- MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT,
+ mrn::variables::BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT,
&mrn_boolean_mode_syntax_flags_typelib);
#endif
@@ -1105,11 +1254,14 @@ static struct st_mysql_sys_var *mrn_system_variables[] =
MYSQL_SYSVAR(vector_column_delimiter),
MYSQL_SYSVAR(libgroonga_support_zlib),
MYSQL_SYSVAR(libgroonga_support_lz4),
+ MYSQL_SYSVAR(libgroonga_support_zstd),
#ifdef MRN_SUPPORT_THDVAR_SET
MYSQL_SYSVAR(boolean_mode_syntax_flags),
#endif
MYSQL_SYSVAR(max_n_records_for_estimate),
MYSQL_SYSVAR(libgroonga_embedded),
+ MYSQL_SYSVAR(query_log_file),
+ MYSQL_SYSVAR(enable_operations_recording),
NULL
};
@@ -1147,7 +1299,8 @@ static ST_FIELD_INFO i_s_mrn_stats_fields_info[] =
0,
"Rows read from Groonga",
SKIP_OPEN_TABLE
- }
+ },
+ { 0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0}
};
static int i_s_mrn_stats_deinit(void* p)
@@ -1191,6 +1344,9 @@ struct st_mysql_plugin i_s_mrn_stats =
"Statistics for " MRN_PLUGIN_NAME_STRING,
PLUGIN_LICENSE_GPL,
i_s_mrn_stats_init,
+#ifdef MRN_ST_MYSQL_PLUGIN_HAVE_CHECK_UNINSTALL
+ NULL,
+#endif
i_s_mrn_stats_deinit,
MRN_VERSION_IN_HEX,
NULL,
@@ -1199,7 +1355,12 @@ struct st_mysql_plugin i_s_mrn_stats =
};
/* End of mroonga information schema implementations */
-static handler *mrn_handler_create(handlerton *hton, TABLE_SHARE *share, MEM_ROOT *root)
+static handler *mrn_handler_create(handlerton *hton,
+ TABLE_SHARE *share,
+#ifdef MRN_HANDLERTON_CREATE_HAVE_PARTITIONED
+ bool partitioned,
+#endif
+ MEM_ROOT *root)
{
MRN_DBUG_ENTER_FUNCTION();
handler *new_handler = new (root) ha_mroonga(hton, share);
@@ -1413,6 +1574,11 @@ static grn_builtin_type mrn_grn_type_from_field(grn_ctx *ctx, Field *field,
case MYSQL_TYPE_VARCHAR_COMPRESSED:
case MYSQL_TYPE_BLOB_COMPRESSED:
DBUG_ASSERT(0);
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+ case MYSQL_TYPE_JSON:
+ type = GRN_DB_TEXT;
+ break;
+#endif
}
return type;
}
@@ -1463,6 +1629,17 @@ static bool mrn_parse_grn_column_create_flags(THD *thd,
"COMPRESS_LZ4");
}
flag_names += 12;
+ } else if (rest_length >= 13 && !memcmp(flag_names, "COMPRESS_ZSTD", 13)) {
+ if (mrn_libgroonga_support_zstd) {
+ *column_flags |= GRN_OBJ_COMPRESS_ZSTD;
+ found = true;
+ } else {
+ push_warning_printf(thd, MRN_SEVERITY_WARNING,
+ ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM,
+ ER_MRN_UNSUPPORTED_COLUMN_FLAG_STR,
+ "COMPRESS_ZSTD");
+ }
+ flag_names += 13;
} else {
char invalid_flag_name[MRN_MESSAGE_BUFFER_SIZE];
snprintf(invalid_flag_name, MRN_MESSAGE_BUFFER_SIZE,
@@ -1483,7 +1660,7 @@ static bool mrn_parse_grn_index_column_flags(THD *thd,
grn_ctx *ctx,
const char *flag_names,
uint flag_names_length,
- grn_obj_flags *index_column_flags)
+ grn_column_flags *index_column_flags)
{
const char *flag_names_end = flag_names + flag_names_length;
bool found = false;
@@ -1510,6 +1687,14 @@ static bool mrn_parse_grn_index_column_flags(THD *thd,
*index_column_flags |= GRN_OBJ_WITH_WEIGHT;
flag_names += 11;
found = true;
+ } else if (rest_length >= 11 && !memcmp(flag_names, "INDEX_SMALL", 11)) {
+ *index_column_flags |= GRN_OBJ_INDEX_SMALL;
+ flag_names += 11;
+ found = true;
+ } else if (rest_length >= 12 && !memcmp(flag_names, "INDEX_MEDIUM", 12)) {
+ *index_column_flags |= GRN_OBJ_INDEX_MEDIUM;
+ flag_names += 12;
+ found = true;
} else {
char invalid_flag_name[MRN_MESSAGE_BUFFER_SIZE];
snprintf(invalid_flag_name, MRN_MESSAGE_BUFFER_SIZE,
@@ -1569,9 +1754,9 @@ static int mrn_set_geometry(grn_ctx *ctx, grn_obj *buf,
#endif
#ifdef MRN_HAVE_HTON_ALTER_TABLE_FLAGS
-static uint mrn_alter_table_flags(uint flags)
+static ulonglong mrn_alter_table_flags(ulonglong flags)
{
- uint alter_flags = 0;
+ ulonglong alter_flags = 0;
#ifdef HA_INPLACE_ADD_INDEX_NO_READ_WRITE
bool is_inplace_index_change;
# ifdef MRN_HAVE_ALTER_INFO
@@ -1621,8 +1806,7 @@ static int mrn_init(void *p)
{
// init handlerton
grn_ctx *ctx = NULL;
- handlerton *hton;
- hton = (handlerton *)p;
+ handlerton *hton = static_cast<handlerton *>(p);
hton->state = SHOW_OPTION_YES;
hton->create = mrn_handler_create;
hton->flags = HTON_NO_FLAGS;
@@ -1677,7 +1861,7 @@ static int mrn_init(void *p)
# endif
#endif
-#ifdef HAVE_PSI_INTERFACE
+#ifdef MRN_HAVE_PSI_SERVER
if (PSI_server) {
const char *category = "mroonga";
int n_mutexes = array_elements(mrn_mutexes);
@@ -1685,6 +1869,8 @@ static int mrn_init(void *p)
}
#endif
+ grn_default_query_logger_set_path(mrn_query_log_file_path);
+
if (grn_init() != GRN_SUCCESS) {
goto err_grn_init;
}
@@ -1711,6 +1897,11 @@ static int mrn_init(void *p)
MY_MUTEX_INIT_FAST) != 0) {
goto err_log_mutex_init;
}
+ if (mysql_mutex_init(mrn_query_log_mutex_key,
+ &mrn_query_log_mutex,
+ MY_MUTEX_INIT_FAST) != 0) {
+ goto err_query_log_mutex_init;
+ }
mrn_logger.max_level = static_cast<grn_log_level>(mrn_log_level);
grn_logger_set(ctx, &mrn_logger);
@@ -1743,13 +1934,31 @@ static int mrn_init(void *p)
if (!mrn_db_manager->init()) {
goto err_db_manager_init;
}
+
+ if (mysql_mutex_init(mrn_context_pool_mutex_key,
+ &mrn_context_pool_mutex,
+ MY_MUTEX_INIT_FAST) != 0) {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to initialize mutex for context pool");
+ goto error_context_pool_mutex_init;
+ }
+ mrn_context_pool = new mrn::ContextPool(&mrn_context_pool_mutex);
+
+ if (mysql_mutex_init(mrn_operations_mutex_key,
+ &mrn_operations_mutex,
+ MY_MUTEX_INIT_FAST) != 0) {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to initialize mutex for operations");
+ goto error_operations_mutex_init;
+ }
+
if ((mysql_mutex_init(mrn_allocated_thds_mutex_key,
&mrn_allocated_thds_mutex,
MY_MUTEX_INIT_FAST) != 0)) {
goto err_allocated_thds_mutex_init;
}
- if (my_hash_init(&mrn_allocated_thds, system_charset_info, 32, 0, 0,
- mrn_allocated_thds_get_key, 0, 0)) {
+ if (mrn_my_hash_init(&mrn_allocated_thds, system_charset_info, 32, 0, 0,
+ mrn_allocated_thds_get_key, 0, 0)) {
goto error_allocated_thds_hash_init;
}
if ((mysql_mutex_init(mrn_open_tables_mutex_key,
@@ -1757,8 +1966,8 @@ static int mrn_init(void *p)
MY_MUTEX_INIT_FAST) != 0)) {
goto err_allocated_open_tables_mutex_init;
}
- if (my_hash_init(&mrn_open_tables, system_charset_info, 32, 0, 0,
- mrn_open_tables_get_key, 0, 0)) {
+ if (mrn_my_hash_init(&mrn_open_tables, system_charset_info, 32, 0, 0,
+ mrn_open_tables_get_key, 0, 0)) {
goto error_allocated_open_tables_hash_init;
}
if ((mysql_mutex_init(mrn_long_term_share_mutex_key,
@@ -1766,8 +1975,8 @@ static int mrn_init(void *p)
MY_MUTEX_INIT_FAST) != 0)) {
goto error_allocated_long_term_share_mutex_init;
}
- if (my_hash_init(&mrn_long_term_share, system_charset_info, 32, 0, 0,
- mrn_long_term_share_get_key, 0, 0)) {
+ if (mrn_my_hash_init(&mrn_long_term_share, system_charset_info, 32, 0, 0,
+ mrn_long_term_share_get_key, 0, 0)) {
goto error_allocated_long_term_share_hash_init;
}
@@ -1788,6 +1997,11 @@ err_allocated_open_tables_mutex_init:
error_allocated_thds_hash_init:
mysql_mutex_destroy(&mrn_allocated_thds_mutex);
err_allocated_thds_mutex_init:
+ mysql_mutex_destroy(&mrn_operations_mutex);
+error_operations_mutex_init:
+ delete mrn_context_pool;
+ mysql_mutex_destroy(&mrn_context_pool_mutex);
+error_context_pool_mutex_init:
err_db_manager_init:
delete mrn_db_manager;
mysql_mutex_destroy(&mrn_db_manager_mutex);
@@ -1800,6 +2014,8 @@ err_db_create:
mrn_log_file_opened = false;
}
err_log_file_open:
+ mysql_mutex_destroy(&mrn_query_log_mutex);
+err_query_log_mutex_init:
mysql_mutex_destroy(&mrn_log_mutex);
err_log_mutex_init:
err_mrn_change_encoding:
@@ -1844,6 +2060,9 @@ static int mrn_deinit(void *p)
mysql_mutex_destroy(&mrn_open_tables_mutex);
my_hash_free(&mrn_allocated_thds);
mysql_mutex_destroy(&mrn_allocated_thds_mutex);
+ mysql_mutex_destroy(&mrn_operations_mutex);
+ delete mrn_context_pool;
+ mysql_mutex_destroy(&mrn_context_pool_mutex);
delete mrn_db_manager;
mysql_mutex_destroy(&mrn_db_manager_mutex);
grn_ctx_fin(&mrn_db_manager_ctx);
@@ -1856,6 +2075,7 @@ static int mrn_deinit(void *p)
fclose(mrn_log_file);
mrn_log_file_opened = false;
}
+ mysql_mutex_destroy(&mrn_query_log_mutex);
mysql_mutex_destroy(&mrn_log_mutex);
return 0;
@@ -2342,7 +2562,8 @@ ha_mroonga::ha_mroonga(handlerton *hton, TABLE_SHARE *share_arg)
ignoring_no_key_columns(false),
replacing_(false),
written_by_row_based_binlog(0),
- current_ft_item(NULL)
+ current_ft_item(NULL),
+ operations_(NULL)
{
MRN_DBUG_ENTER_METHOD();
grn_ctx_init(ctx, 0);
@@ -2361,6 +2582,9 @@ ha_mroonga::ha_mroonga(handlerton *hton, TABLE_SHARE *share_arg)
ha_mroonga::~ha_mroonga()
{
MRN_DBUG_ENTER_METHOD();
+
+ delete operations_;
+
if (analyzed_for_create) {
if (wrap_handler_for_create) {
delete wrap_handler_for_create;
@@ -2626,6 +2850,12 @@ ulonglong ha_mroonga::wrapper_table_flags() const
#ifdef HA_CAN_FULLTEXT_EXT
table_flags |= HA_CAN_FULLTEXT_EXT;
#endif
+#ifdef HA_GENERATED_COLUMNS
+ table_flags |= HA_GENERATED_COLUMNS;
+#endif
+#ifdef HA_CAN_VIRTUAL_COLUMNS
+ table_flags |= HA_CAN_VIRTUAL_COLUMNS;
+#endif
DBUG_RETURN(table_flags);
}
@@ -2655,6 +2885,12 @@ ulonglong ha_mroonga::storage_table_flags() const
#ifdef HA_CAN_FULLTEXT_EXT
flags |= HA_CAN_FULLTEXT_EXT;
#endif
+#ifdef HA_GENERATED_COLUMNS
+ flags |= HA_GENERATED_COLUMNS;
+#endif
+#ifdef HA_CAN_VIRTUAL_COLUMNS
+ flags |= HA_CAN_VIRTUAL_COLUMNS;
+#endif
DBUG_RETURN(flags);
}
@@ -2719,7 +2955,7 @@ ulong ha_mroonga::storage_index_flags(uint idx, uint part, bool all_parts) const
part = 0;
}
Field *field = &(key->key_part[part].field[0]);
- if (field && should_normalize(field)) {
+ if (field && (have_custom_normalizer(key) || should_normalize(field))) {
need_normalize_p = true;
}
if (!need_normalize_p) {
@@ -2743,7 +2979,7 @@ ulong ha_mroonga::index_flags(uint idx, uint part, bool all_parts) const
DBUG_RETURN(HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
}
if (mrn_is_geo_key(key)) {
- DBUG_RETURN(HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
+ DBUG_RETURN(HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR | HA_READ_RANGE);
}
int error = 0;
@@ -2809,10 +3045,10 @@ int ha_mroonga::create_share_for_create() const
mrn_init_alloc_root(&mem_root_for_create, 1024, 0, MYF(0));
analyzed_for_create = true;
if (table_list) {
- share_for_create.table_name = mrn_my_strndup(table_list->table_name,
- table_list->table_name_length,
+ share_for_create.table_name = mrn_my_strndup(table_list->table_name.str,
+ table_list->table_name.length,
MYF(MY_WME));
- share_for_create.table_name_length = table_list->table_name_length;
+ share_for_create.table_name_length = table_list->table_name.length;
}
share_for_create.table_share = &table_share_for_create;
table_for_create.s = &table_share_for_create;
@@ -2860,9 +3096,11 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
DBUG_RETURN(ER_REQUIRES_PRIMARY_KEY);
}
- mrn::PathMapper mapper(name);
- error = wrapper_create_index(name, table, info, tmp_share,
- mapper.table_name());
+ error = ensure_database_open(name);
+ if (error)
+ DBUG_RETURN(error);
+
+ error = wrapper_create_index(name, table, tmp_share);
if (error)
DBUG_RETURN(error);
@@ -2910,6 +3148,7 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
delete hnd;
if (error) {
+ mrn::PathMapper mapper(name);
generic_delete_table(name, mapper.table_name());
}
@@ -2973,7 +3212,7 @@ int ha_mroonga::wrapper_create_index_fulltext(const char *grn_table_name,
GRN_OBJ_PERSISTENT;
grn_obj *index_table;
- grn_obj_flags index_column_flags = GRN_OBJ_COLUMN_INDEX | GRN_OBJ_PERSISTENT;
+ grn_column_flags index_column_flags = GRN_OBJ_COLUMN_INDEX | GRN_OBJ_PERSISTENT;
if (!find_index_column_flags(key_info, &index_column_flags)) {
index_column_flags |= GRN_OBJ_WITH_POSITION;
@@ -3020,7 +3259,8 @@ int ha_mroonga::wrapper_create_index_fulltext(const char *grn_table_name,
grn_obj_unlink(ctx, &token_filters);
}
- if (should_normalize(&key_info->key_part->field[0])) {
+ if (have_custom_normalizer(key_info) ||
+ should_normalize(&key_info->key_part->field[0])) {
grn_info_type info_type = GRN_INFO_NORMALIZER;
grn_obj *normalizer = find_normalizer(key_info);
if (normalizer) {
@@ -3109,22 +3349,18 @@ int ha_mroonga::wrapper_create_index_geo(const char *grn_table_name,
}
int ha_mroonga::wrapper_create_index(const char *name, TABLE *table,
- HA_CREATE_INFO *info,
- MRN_SHARE *tmp_share,
- const char *grn_table_name)
+ MRN_SHARE *tmp_share)
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
- error = ensure_database_open(name);
- if (error)
- DBUG_RETURN(error);
-
error = mrn_change_encoding(ctx, system_charset_info);
if (error)
DBUG_RETURN(error);
grn_obj *grn_index_table;
+ mrn::PathMapper mapper(name);
+ const char *grn_table_name = mapper.table_name();
char *grn_table_path = NULL; // we don't specify path
grn_obj *pkey_type = grn_ctx_at(ctx, GRN_DB_SHORT_TEXT);
grn_obj *pkey_value_type = NULL; // we don't use this
@@ -3313,10 +3549,9 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
uint n_columns = table->s->fields;
for (uint i = 0; i < n_columns; i++) {
Field *field = table->s->field[i];
- const char *column_name = field->field_name.str;
- int column_name_size = strlen(column_name);
+ mrn::ColumnName column_name(field->field_name);
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (strcmp(MRN_COLUMN_NAME_ID, column_name.mysql_name()) == 0) {
continue;
}
@@ -3331,6 +3566,12 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
}
#endif
+#ifdef MRN_SUPPORT_GENERATED_COLUMNS
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field)) {
+ continue;
+ }
+#endif
+
grn_obj_flags col_flags = GRN_OBJ_PERSISTENT;
if (!find_column_flags(field, tmp_share, i, &col_flags)) {
col_flags |= GRN_OBJ_COLUMN_SCALAR;
@@ -3347,12 +3588,13 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
}
char *col_path = NULL; // we don't specify path
- grn_column_create(ctx, table_obj, column_name, column_name_size,
+ grn_column_create(ctx, table_obj,
+ column_name.c_str(), column_name.length(),
col_path, col_flags, col_type);
if (ctx->rc) {
- grn_obj_remove(ctx, table_obj);
error = ER_CANT_CREATE_TABLE;
my_message(error, ctx->errbuf, MYF(0));
+ grn_obj_remove(ctx, table_obj);
DBUG_RETURN(error);
}
}
@@ -3490,17 +3732,15 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
if (!grn_table_ref) {
error = ER_CANT_CREATE_TABLE;
char err_msg[MRN_BUFFER_SIZE];
- sprintf(err_msg, "refference table [%s.%s] is not mroonga table",
+ sprintf(err_msg, "reference table [%s.%s] is not mroonga table",
table->s->db.str, ref_table_name.str);
my_message(error, err_msg, MYF(0));
DBUG_RETURN(false);
}
- table_list.init_one_table(mapper.db_name(),
- strlen(mapper.db_name()),
- mapper.mysql_table_name(),
- strlen(mapper.mysql_table_name()),
- mapper.mysql_table_name(), TL_WRITE);
+ LEX_CSTRING tmp_db_name= { mapper.db_name(), strlen(mapper.db_name()) };
+ LEX_CSTRING tmp_table_name= { mapper.mysql_table_name(), strlen(mapper.mysql_table_name()) };
+ table_list.init_one_table(&tmp_db_name, &tmp_table_name, 0, TL_WRITE);
mrn_open_mutex_lock(table->s);
tmp_ref_table_share =
mrn_create_tmp_table_share(&table_list, ref_path, &error);
@@ -3509,7 +3749,7 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
grn_obj_unlink(ctx, grn_table_ref);
error = ER_CANT_CREATE_TABLE;
char err_msg[MRN_BUFFER_SIZE];
- sprintf(err_msg, "refference table [%s.%s] is not found",
+ sprintf(err_msg, "reference table [%s.%s] is not found",
table->s->db.str, ref_table_name.str);
my_message(error, err_msg, MYF(0));
DBUG_RETURN(false);
@@ -3522,7 +3762,7 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
grn_obj_unlink(ctx, grn_table_ref);
error = ER_CANT_CREATE_TABLE;
char err_msg[MRN_BUFFER_SIZE];
- sprintf(err_msg, "refference table [%s.%s] has no primary key",
+ sprintf(err_msg, "reference table [%s.%s] has no primary key",
table->s->db.str, ref_table_name.str);
my_message(error, err_msg, MYF(0));
DBUG_RETURN(false);
@@ -3537,7 +3777,7 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
error = ER_CANT_CREATE_TABLE;
char err_msg[MRN_BUFFER_SIZE];
sprintf(err_msg,
- "refference table [%s.%s] primary key is multiple column",
+ "reference table [%s.%s] primary key is multiple column",
table->s->db.str, ref_table_name.str);
my_message(error, err_msg, MYF(0));
DBUG_RETURN(false);
@@ -3551,7 +3791,7 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
error = ER_CANT_CREATE_TABLE;
char err_msg[MRN_BUFFER_SIZE];
sprintf(err_msg,
- "refference column [%s.%s.%s] is not used for primary key",
+ "reference column [%s.%s.%s] is not used for primary key",
table->s->db.str, ref_table_name.str, ref_field_name.str);
my_message(error, err_msg, MYF(0));
DBUG_RETURN(false);
@@ -3727,11 +3967,14 @@ int ha_mroonga::storage_create_index_table(TABLE *table,
grn_obj *normalizer = NULL;
Field *field = &(key_info->key_part->field[0]);
if (key_info->flags & HA_FULLTEXT) {
- if (should_normalize(field)) {
+ if (have_custom_normalizer(key_info) ||
+ should_normalize(field)) {
normalizer = find_normalizer(key_info);
}
} else if (key_alg != HA_KEY_ALG_HASH) {
- if (!is_multiple_column_index && should_normalize(field)) {
+ if (!is_multiple_column_index &&
+ (have_custom_normalizer(key_info) ||
+ should_normalize(field))) {
normalizer = find_normalizer(key_info);
}
}
@@ -3754,19 +3997,48 @@ int ha_mroonga::storage_create_index(TABLE *table, const char *grn_table_name,
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
- grn_obj *index_table, *index_column;
- const char *column_name = NULL;
- int column_name_size = 0;
+ grn_obj *index_column;
bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1;
if (!is_multiple_column_index) {
Field *field = key_info->key_part[0].field;
- column_name = field->field_name.str;
- column_name_size = field->field_name.length;
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (strcmp(MRN_COLUMN_NAME_ID, field->field_name.str) == 0) {
// skipping _id virtual column
DBUG_RETURN(0);
}
+
+ if (is_foreign_key_field(table->s->table_name.str,
+ field->field_name.str)) {
+ DBUG_RETURN(0);
+ }
+
+#ifdef HA_CAN_VIRTUAL_COLUMNS
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field)) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: storage: failed to create index: "
+ ER_MRN_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN_STR,
+ field->field_name.str);
+ error = ER_MRN_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN_NUM;
+ my_message(error, error_message, MYF(0));
+ DBUG_RETURN(error);
+ }
+ } else {
+ int j, n_key_parts = KEY_N_KEY_PARTS(key_info);
+ for (j = 0; j < n_key_parts; j++) {
+ Field *field = key_info->key_part[j].field;
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field)) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: storage: failed to create index: "
+ ER_MRN_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN_STR,
+ field->field_name.str);
+ error = ER_MRN_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN_NUM;
+ my_message(error, error_message, MYF(0));
+ DBUG_RETURN(error);
+ }
+ }
+#endif
}
error = mrn_change_encoding(ctx, system_charset_info);
@@ -3779,16 +4051,21 @@ int ha_mroonga::storage_create_index(TABLE *table, const char *grn_table_name,
if (error)
DBUG_RETURN(error);
- grn_obj_flags index_column_flags = GRN_OBJ_COLUMN_INDEX | GRN_OBJ_PERSISTENT;
+ grn_obj *index_table = index_tables[i];
+
+ grn_column_flags index_column_flags = GRN_OBJ_COLUMN_INDEX | GRN_OBJ_PERSISTENT;
if (!find_index_column_flags(key_info, &index_column_flags)) {
- index_column_flags |= GRN_OBJ_WITH_POSITION;
- if (is_multiple_column_index) {
+ grn_obj *tokenizer = grn_obj_get_info(ctx, index_table,
+ GRN_INFO_DEFAULT_TOKENIZER, NULL);
+ if (tokenizer) {
+ index_column_flags |= GRN_OBJ_WITH_POSITION;
+ }
+ if (is_multiple_column_index && (key_info->flags & HA_FULLTEXT)) {
index_column_flags |= GRN_OBJ_WITH_SECTION;
}
}
- index_table = index_tables[i];
const char *index_column_name;
if (tmp_share->index_table && tmp_share->index_table[i]) {
index_column_name = key_info->name.str;
@@ -3819,10 +4096,11 @@ int ha_mroonga::storage_create_index(TABLE *table, const char *grn_table_name,
int j, n_key_parts = KEY_N_KEY_PARTS(key_info);
for (j = 0; j < n_key_parts; j++) {
Field *field = key_info->key_part[j].field;
- const char *column_name = field->field_name.str;
- int column_name_size = field->field_name.length;
- grn_obj *source_column = grn_obj_column(ctx, grn_table,
- column_name, column_name_size);
+ mrn::ColumnName column_name(field->field_name);
+ grn_obj *source_column = grn_obj_column(ctx,
+ grn_table,
+ column_name.c_str(),
+ column_name.length());
grn_id source_id = grn_obj_id(ctx, source_column);
GRN_UINT32_PUT(ctx, &source_ids, source_id);
grn_obj_unlink(ctx, source_column);
@@ -3832,8 +4110,13 @@ int ha_mroonga::storage_create_index(TABLE *table, const char *grn_table_name,
grn_obj_unlink(ctx, &source_ids);
}
} else {
+ Field *field = key_info->key_part[0].field;
+ mrn::ColumnName column_name(field->field_name);
grn_obj *column;
- column = grn_obj_column(ctx, grn_table, column_name, column_name_size);
+ column = grn_obj_column(ctx,
+ grn_table,
+ column_name.c_str(),
+ column_name.length());
if (column) {
grn_obj source_ids;
grn_id source_id = grn_obj_id(ctx, column);
@@ -3893,18 +4176,31 @@ int ha_mroonga::storage_create_indexes(TABLE *table, const char *grn_table_name,
DBUG_RETURN(error);
}
-int ha_mroonga::ensure_database_open(const char *name)
+int ha_mroonga::ensure_database_open(const char *name, mrn::Database **db)
{
int error;
MRN_DBUG_ENTER_METHOD();
- grn_obj *db;
- error = mrn_db_manager->open(name, &db);
+ if (db)
+ *db = NULL;
+
+ mrn::Database *local_db;
+ error = mrn_db_manager->open(name, &local_db);
if (error)
DBUG_RETURN(error);
- grn_ctx_use(ctx, db);
+ if (db)
+ *db = local_db;
+ grn_ctx_use(ctx, local_db->get());
+
+ delete operations_;
+ operations_ = new mrn::Operations(ctx);
+ if (mrn_enable_operations_recording) {
+ operations_->enable_recording();
+ } else {
+ operations_->disable_recording();
+ }
DBUG_RETURN(error);
}
@@ -3919,6 +4215,9 @@ int ha_mroonga::ensure_database_remove(const char *name)
if (error)
DBUG_RETURN(error);
+ delete operations_;
+ operations_ = NULL;
+
mrn_db_manager->close(name);
mrn::PathMapper mapper(name);
@@ -3928,7 +4227,14 @@ int ha_mroonga::ensure_database_remove(const char *name)
}
-int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
+int ha_mroonga::create(const char *name,
+ TABLE *table,
+ HA_CREATE_INFO *info
+#ifdef MRN_HANDLER_CREATE_HAVE_TABLE_DEFINITION
+ ,
+ dd::Table *table_def
+#endif
+ )
{
int error = 0;
MRN_SHARE *tmp_share;
@@ -3960,26 +4266,17 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
DBUG_RETURN(error);
}
-int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
+int ha_mroonga::wrapper_open(const char *name, int mode, uint open_options)
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- if (thd_sql_command(ha_thd()) == SQLCOM_REPAIR) {
- error = ensure_database_remove(name);
- if (error)
- DBUG_RETURN(error);
- error = ensure_database_open(name);
- if (error)
- DBUG_RETURN(error);
- grn_table = NULL;
- grn_index_tables = NULL;
- grn_index_columns = NULL;
- } else {
- error = ensure_database_open(name);
- if (error)
- DBUG_RETURN(error);
+ mrn::Database *db = NULL;
+ error = ensure_database_open(name, &db);
+ if (error)
+ DBUG_RETURN(error);
+ if (!(open_options & HA_OPEN_FOR_REPAIR)) {
error = open_table(name);
if (error)
DBUG_RETURN(error);
@@ -4018,7 +4315,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
#ifdef MRN_HANDLER_HAVE_SET_HA_SHARE_REF
wrap_handler->set_ha_share_ref(&table->s->ha_share);
#endif
- error = wrap_handler->ha_open(table, name, mode, test_if_locked);
+ error = wrap_handler->ha_open(table, name, mode, open_options);
} else {
if (!(wrap_handler = parent_for_clone->wrap_handler->clone(name,
mem_root_for_clone)))
@@ -4045,6 +4342,39 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
pk_keypart_map = make_prev_keypart_map(
KEY_N_KEY_PARTS(&(table->key_info[table_share->primary_key])));
+ if (!error) {
+ if (open_options & HA_OPEN_FOR_REPAIR) {
+ // TODO: How to check whether is DISABLE KEYS used or not?
+ error = wrapper_recreate_indexes(ha_thd());
+ } else if (db) {
+ mrn::Lock lock(&mrn_operations_mutex);
+ mrn::PathMapper mapper(name);
+ const char *table_name = mapper.table_name();
+ size_t table_name_size = strlen(table_name);
+ if (db->is_broken_table(table_name, table_name_size)) {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "Auto repair is started: <%s>",
+ name);
+ error = operations_->clear(table_name, table_name_size);
+ if (!error) {
+ db->mark_table_repaired(table_name, table_name_size);
+ if (!share->disable_keys) {
+ // TODO: implemented by "reindex" instead of "remove and recreate".
+ // Because "remove and recreate" invalidates opened indexes by
+ // other threads.
+ error = wrapper_disable_indexes_mroonga(HA_KEY_SWITCH_ALL);
+ if (!error) {
+ error = wrapper_enable_indexes_mroonga(HA_KEY_SWITCH_ALL);
+ }
+ }
+ }
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "Auto repair is done: <%s>: %s",
+ name, error == 0 ? "success" : "failure");
+ }
+ }
+ }
+
if (error)
{
grn_obj_unlink(ctx, grn_table);
@@ -4104,6 +4434,11 @@ int ha_mroonga::wrapper_open_indexes(const char *name)
grn_index_tables[i] = grn_ctx_get(ctx,
index_table_name.c_str(),
index_table_name.length());
+ if (ctx->rc == GRN_SUCCESS && !grn_index_tables[i]) {
+ grn_index_tables[i] = grn_ctx_get(ctx,
+ index_table_name.old_c_str(),
+ index_table_name.old_length());
+ }
if (ctx->rc) {
DBUG_PRINT("info",
("mroonga: sql_command=%u", thd_sql_command(ha_thd())));
@@ -4166,8 +4501,16 @@ void ha_mroonga::wrapper_overwrite_index_bits()
{
Field *field = table_share->field[i];
field->part_of_key.clear_all();
+#ifdef MRN_HAVE_MYSQL_FIELD_PART_OF_KEY_NOT_CLUSTERED
field->part_of_key_not_clustered.clear_all();
+#endif
field->part_of_sortkey.clear_all();
+ /*
+ TODO: We may need to update field->part_of_key_not_extended for
+ MySQL >= 5.7.18. If users report "raw InnoDB can use index for
+ this case but Mroonga wrapper mode for InnoDB can't use index
+ for the same case", we'll reconsider it again.
+ */
}
for (i = 0; i < table_share->keys; i++) {
KEY *key_info = &table->s->key_info[i];
@@ -4182,7 +4525,9 @@ void ha_mroonga::wrapper_overwrite_index_bits()
{
table_share->keys_for_keyread.set_bit(i);
field->part_of_key.set_bit(i);
+#ifdef MRN_HAVE_MYSQL_FIELD_PART_OF_KEY_NOT_CLUSTERED
field->part_of_key_not_clustered.set_bit(i);
+#endif
}
if (index_flags(i, j, 1) & HA_READ_ORDER)
field->part_of_sortkey.set_bit(i);
@@ -4201,12 +4546,93 @@ void ha_mroonga::wrapper_overwrite_index_bits()
DBUG_VOID_RETURN;
}
-int ha_mroonga::storage_open(const char *name, int mode, uint test_if_locked)
+int ha_mroonga::storage_reindex()
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- error = ensure_database_open(name);
+ uint n_keys = table_share->keys;
+ KEY *key_info = table->key_info;
+
+ bool have_multiple_column_index = false;
+ bitmap_clear_all(table->read_set);
+ for (uint i = 0; i < n_keys; ++i) {
+ if (!grn_index_columns[i])
+ continue;
+
+ grn_hash *columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY);
+ grn_table_columns(ctx, grn_index_tables[i], NULL, 0,
+ reinterpret_cast<grn_obj *>(columns));
+ unsigned int n_columns =
+ grn_table_size(ctx, reinterpret_cast<grn_obj *>(columns));
+ grn_hash_close(ctx, columns);
+
+ bool is_multiple_column_index =
+ (KEY_N_KEY_PARTS(&(key_info[i])) != 1 &&
+ !(key_info[i].flags & HA_FULLTEXT));
+
+ if (n_columns == 1 || is_multiple_column_index) {
+ grn_table_truncate(ctx, grn_index_tables[i]);
+ if (ctx->rc != GRN_SUCCESS) {
+ error = ER_ERROR_ON_WRITE;
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ char index_table_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_table_name_size;
+ index_table_name_size =
+ grn_obj_name(ctx, grn_index_tables[i],
+ index_table_name, GRN_TABLE_MAX_KEY_SIZE);
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: reindex: failed to truncate index table: "
+ "<%.*s>: <%s>(%d)",
+ index_table_name_size, index_table_name,
+ ctx->errbuf, ctx->rc);
+ my_message(error, error_message, MYF(0));
+ break;
+ }
+ }
+
+ if (is_multiple_column_index) {
+ mrn_set_bitmap_by_key(table->read_set, &key_info[i]);
+ have_multiple_column_index = true;
+ } else {
+ grn_obj_reindex(ctx, grn_index_columns[i]);
+ if (ctx->rc != GRN_SUCCESS) {
+ error = ER_ERROR_ON_WRITE;
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ char index_column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_column_name_size;
+ index_column_name_size =
+ grn_obj_name(ctx, grn_index_columns[i],
+ index_column_name, GRN_TABLE_MAX_KEY_SIZE);
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: reindex: failed to reindex: "
+ "<%.*s>: <%s>(%d)",
+ index_column_name_size, index_column_name,
+ ctx->errbuf, ctx->rc);
+ my_message(error, error_message, MYF(0));
+ break;
+ }
+ }
+ }
+
+ if (!error && have_multiple_column_index)
+ error = storage_add_index_multiple_columns(key_info, n_keys,
+ grn_index_tables,
+ grn_index_columns,
+ false);
+ bitmap_set_all(table->read_set);
+
+ DBUG_RETURN(error);
+}
+
+int ha_mroonga::storage_open(const char *name, int mode, uint open_options)
+{
+ int error = 0;
+ MRN_DBUG_ENTER_METHOD();
+
+ mrn::Database *db;
+ error = ensure_database_open(name, &db);
if (error)
DBUG_RETURN(error);
@@ -4221,19 +4647,38 @@ int ha_mroonga::storage_open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(error);
}
- if (!(ha_thd()->open_options & HA_OPEN_FOR_REPAIR)) {
+ if (!(open_options & HA_OPEN_FOR_REPAIR)) {
error = storage_open_indexes(name);
if (error) {
+ storage_close_columns();
grn_obj_unlink(ctx, grn_table);
grn_table = NULL;
- // TODO: unlink elements
- free(grn_columns);
- // TODO: unlink elements
- free(grn_column_ranges);
DBUG_RETURN(error);
}
storage_set_keys_in_use();
+
+ {
+ mrn::Lock lock(&mrn_operations_mutex);
+ mrn::PathMapper mapper(name);
+ const char *table_name = mapper.table_name();
+ size_t table_name_size = strlen(table_name);
+ if (db->is_broken_table(table_name, table_name_size)) {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "Auto repair is started: <%s>",
+ name);
+ error = operations_->repair(table_name, table_name_size);
+ if (!error)
+ db->mark_table_repaired(table_name, table_name_size);
+ if (!share->disable_keys) {
+ if (!error)
+ error = storage_reindex();
+ }
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "Auto repair is done: <%s>: %s",
+ name, error == 0 ? "success" : "failure");
+ }
+ }
}
ref_length = sizeof(grn_id);
@@ -4300,18 +4745,26 @@ int ha_mroonga::storage_open_columns(void)
for (int i = 0; i < n_columns; i++) {
Field *field = table->field[i];
- const char *column_name = field->field_name.str;
- int column_name_size = field->field_name.length;
+ mrn::ColumnName column_name(field->field_name);
if (table_share->blob_fields)
{
blob_buffers[i].set_charset(field->charset());
}
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (strcmp(MRN_COLUMN_NAME_ID, column_name.mysql_name()) == 0) {
+ continue;
+ }
+#ifdef MRN_SUPPORT_GENERATED_COLUMNS
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field)) {
+ grn_columns[i] = NULL;
+ grn_column_ranges[i] = NULL;
continue;
}
+#endif
- grn_columns[i] = grn_obj_column(ctx, grn_table,
- column_name, column_name_size);
+ grn_columns[i] = grn_obj_column(ctx,
+ grn_table,
+ column_name.c_str(),
+ column_name.length());
if (!grn_columns[i]) {
error = ER_CANT_OPEN_FILE;
my_message(error, ctx->errbuf, MYF(0));
@@ -4328,25 +4781,31 @@ int ha_mroonga::storage_open_columns(void)
}
if (error != 0) {
- for (int i = 0; i < n_columns; i++) {
- grn_obj *column = grn_columns[i];
- if (column) {
- grn_obj_unlink(ctx, column);
- }
+ storage_close_columns();
+ }
- grn_obj *range = grn_column_ranges[i];
- if (range) {
- grn_obj_unlink(ctx, range);
- }
+ DBUG_RETURN(error);
+}
+
+void ha_mroonga::storage_close_columns(void)
+{
+ int n_columns = table->s->fields;
+ for (int i = 0; i < n_columns; i++) {
+ grn_obj *column = grn_columns[i];
+ if (column) {
+ grn_obj_unlink(ctx, column);
}
- free(grn_columns);
- grn_columns = NULL;
- free(grn_column_ranges);
- grn_column_ranges = NULL;
+ grn_obj *range = grn_column_ranges[i];
+ if (range) {
+ grn_obj_unlink(ctx, range);
+ }
}
- DBUG_RETURN(error);
+ free(grn_columns);
+ grn_columns = NULL;
+ free(grn_column_ranges);
+ grn_column_ranges = NULL;
}
int ha_mroonga::storage_open_indexes(const char *name)
@@ -4407,6 +4866,11 @@ int ha_mroonga::storage_open_indexes(const char *name)
grn_index_tables[i] = grn_ctx_get(ctx,
index_table_name.c_str(),
index_table_name.length());
+ if (ctx->rc == GRN_SUCCESS && !grn_index_tables[i]) {
+ grn_index_tables[i] = grn_ctx_get(ctx,
+ index_table_name.old_c_str(),
+ index_table_name.old_length());
+ }
if (ctx->rc == GRN_SUCCESS) {
grn_index_columns[i] = grn_obj_column(ctx,
grn_index_tables[i],
@@ -4465,7 +4929,14 @@ error:
DBUG_RETURN(error);
}
-int ha_mroonga::open(const char *name, int mode, uint test_if_locked)
+int ha_mroonga::open(const char *name,
+ int mode,
+ uint open_options
+#ifdef MRN_HANDLER_OPEN_HAVE_TABLE_DEFINITION
+ ,
+ const dd::Table *table_def
+#endif
+ )
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
@@ -4483,9 +4954,9 @@ int ha_mroonga::open(const char *name, int mode, uint test_if_locked)
if (share->wrapper_mode)
{
- error = wrapper_open(name, mode, test_if_locked);
+ error = wrapper_open(name, mode, open_options);
} else {
- error = storage_open(name, mode, test_if_locked);
+ error = storage_open(name, mode, open_options);
}
if (error)
@@ -4553,7 +5024,10 @@ int ha_mroonga::close()
DBUG_RETURN(error);
}
- error = add_wrap_hton(share->table_name, share->hton);
+ if (thd)
+ {
+ error = add_wrap_hton(share->table_name, share->hton);
+ }
bitmap_free(&multiple_column_key_bitmap);
if (share->use_count == 1) {
mrn_free_long_term_share(share->long_term_share);
@@ -4612,7 +5086,7 @@ int ha_mroonga::generic_delete_table(const char *name, const char *table_name)
error = drop_indexes(table_name);
grn_obj *table_obj = grn_ctx_get(ctx, table_name, strlen(table_name));
- if (!ctx->rc) {
+ if (table_obj) {
grn_obj_remove(ctx, table_obj);
}
if (ctx->rc) {
@@ -4655,6 +5129,45 @@ int ha_mroonga::delete_table(const char *name)
}
}
+ if (!wrap_handlerton) {
+ bool open_table_to_get_wrap_handlerton = true;
+ if (mapper.is_internal_table_name()) {
+ open_table_to_get_wrap_handlerton = false;
+ }
+ if (open_table_to_get_wrap_handlerton) {
+ TABLE_LIST table_list;
+ LEX_CSTRING db_name= { mapper.db_name(), strlen(mapper.db_name()) };
+ LEX_CSTRING table_name= { mapper.mysql_table_name(), strlen(mapper.mysql_table_name()) };
+
+ table_list.init_one_table(&db_name, &table_name, 0, TL_WRITE);
+ mrn_open_mutex_lock(NULL);
+ TABLE_SHARE *tmp_table_share =
+ mrn_create_tmp_table_share(&table_list, name, &error);
+ error = 0;
+ mrn_open_mutex_unlock(NULL);
+ if (tmp_table_share) {
+ TABLE tmp_table;
+ tmp_table.s = tmp_table_share;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ tmp_table.part_info = NULL;
+#endif
+ MRN_SHARE *tmp_share = mrn_get_share(name, &tmp_table, &error);
+ if (tmp_share) {
+ wrap_handlerton = tmp_share->hton;
+ mrn_free_long_term_share(tmp_share->long_term_share);
+ tmp_share->long_term_share = NULL;
+ mrn_free_share(tmp_share);
+ }
+ mrn_open_mutex_lock(NULL);
+ mrn_free_tmp_table_share(tmp_table_share);
+ mrn_open_mutex_unlock(NULL);
+ if (error) {
+ DBUG_RETURN(error);
+ }
+ }
+ }
+ }
+
if (wrap_handlerton)
{
error = wrapper_delete_table(name, wrap_handlerton, mapper.table_name());
@@ -4665,8 +5178,8 @@ int ha_mroonga::delete_table(const char *name)
error = generic_delete_table(name, mapper.table_name());
}
- if (!error && is_temporary_table_name(name)) {
- mrn_db_manager->drop(name);
+ if (!error) {
+ error = operations_->clear(name, strlen(name));
}
DBUG_RETURN(error);
@@ -5039,6 +5552,70 @@ int ha_mroonga::rnd_end()
DBUG_RETURN(error);
}
+#ifdef MRN_HANDLER_RECORDS_RETURN_ERROR
+int ha_mroonga::wrapper_records(ha_rows *num_rows)
+{
+ int error = 0;
+ MRN_DBUG_ENTER_METHOD();
+ MRN_SET_WRAP_SHARE_KEY(share, table->s);
+ MRN_SET_WRAP_TABLE_KEY(this, table);
+ error = wrap_handler->ha_records(num_rows);
+ MRN_SET_BASE_SHARE_KEY(share, table->s);
+ MRN_SET_BASE_TABLE_KEY(this, table);
+ DBUG_RETURN(error);
+}
+
+int ha_mroonga::storage_records(ha_rows *num_rows)
+{
+ MRN_DBUG_ENTER_METHOD();
+ int error = handler::records(num_rows);
+ DBUG_RETURN(error);
+}
+
+int ha_mroonga::records(ha_rows *num_rows)
+{
+ MRN_DBUG_ENTER_METHOD();
+ int error = 0;
+ if (share->wrapper_mode) {
+ error = wrapper_records(num_rows);
+ } else {
+ error = storage_records(num_rows);
+ }
+ DBUG_RETURN(error);
+}
+#else
+ha_rows ha_mroonga::wrapper_records()
+{
+ ha_rows num_rows;
+ MRN_DBUG_ENTER_METHOD();
+ MRN_SET_WRAP_SHARE_KEY(share, table->s);
+ MRN_SET_WRAP_TABLE_KEY(this, table);
+ num_rows = wrap_handler->records();
+ MRN_SET_BASE_SHARE_KEY(share, table->s);
+ MRN_SET_BASE_TABLE_KEY(this, table);
+ DBUG_RETURN(num_rows);
+}
+
+ha_rows ha_mroonga::storage_records()
+{
+ MRN_DBUG_ENTER_METHOD();
+ ha_rows num_rows = handler::records();
+ DBUG_RETURN(num_rows);
+}
+
+ha_rows ha_mroonga::records()
+{
+ MRN_DBUG_ENTER_METHOD();
+ ha_rows num_rows;
+ if (share->wrapper_mode) {
+ num_rows = wrapper_records();
+ } else {
+ num_rows = storage_records();
+ }
+ DBUG_RETURN(num_rows);
+}
+#endif
+
int ha_mroonga::wrapper_rnd_next(uchar *buf)
{
int error = 0;
@@ -5280,7 +5857,15 @@ int ha_mroonga::wrapper_write_row(uchar *buf)
{
int error = 0;
THD *thd = ha_thd();
+
MRN_DBUG_ENTER_METHOD();
+
+ mrn::Operation operation(operations_,
+ "write",
+ table->s->table_name.str,
+ table->s->table_name.length);
+
+ operation.record_target(record_id);
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
tmp_disable_binlog(thd);
@@ -5395,6 +5980,11 @@ int ha_mroonga::storage_write_row(uchar *buf)
DBUG_RETURN(error);
}
+ mrn::Operation operation(operations_,
+ "write",
+ table->s->table_name.str,
+ table->s->table_name.length);
+
THD *thd = ha_thd();
int i;
int n_columns = table->s->fields;
@@ -5408,11 +5998,17 @@ int ha_mroonga::storage_write_row(uchar *buf)
mrn::DebugColumnAccess debug_column_access(table, table->read_set);
for (i = 0; i < n_columns; i++) {
Field *field = table->field[i];
- const char *column_name = field->field_name.str;
+
+#ifdef MRN_SUPPORT_GENERATED_COLUMNS
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field)) {
+ continue;
+ }
+#endif
if (field->is_null()) continue;
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ mrn::ColumnName column_name(field->field_name);
+ if (strcmp(MRN_COLUMN_NAME_ID, column_name.c_str()) == 0) {
push_warning_printf(thd, MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED,
MRN_GET_ERR_MSG(WARN_DATA_TRUNCATED),
@@ -5496,17 +6092,25 @@ int ha_mroonga::storage_write_row(uchar *buf)
}
DBUG_RETURN(error);
}
+ operation.record_target(record_id);
}
grn_obj colbuf;
GRN_VOID_INIT(&colbuf);
for (i = 0; i < n_columns; i++) {
Field *field = table->field[i];
- const char *column_name = field->field_name.str;
if (field->is_null())
continue;
+#ifdef MRN_SUPPORT_GENERATED_COLUMNS
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field)) {
+ continue;
+ }
+#endif
+
+ mrn::ColumnName column_name(field->field_name);
+
#ifdef MRN_HAVE_SPATIAL
bool is_null_geometry_value =
field->real_type() == MYSQL_TYPE_GEOMETRY &&
@@ -5516,39 +6120,63 @@ int ha_mroonga::storage_write_row(uchar *buf)
}
#endif
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (strcmp(MRN_COLUMN_NAME_ID, column_name.c_str()) == 0) {
continue;
}
error = mrn_change_encoding(ctx, field->charset());
if (error) {
- grn_obj_unlink(ctx, &colbuf);
+ GRN_OBJ_FIN(ctx, &colbuf);
goto err;
}
error = generic_store_bulk(field, &colbuf);
if (error) {
- grn_obj_unlink(ctx, &colbuf);
+ GRN_OBJ_FIN(ctx, &colbuf);
goto err;
}
- if (added && is_grn_zero_column_value(grn_columns[i], &colbuf)) {
- // WORKAROUND: groonga can't index newly added '0' value for
- // fix size column. So we add non-'0' value first then add
- // real '0' value again. It will be removed when groonga
- // supports 'null' value.
- char *bytes = GRN_BULK_HEAD(&colbuf);
- bytes[0] = '\1';
- grn_obj_set_value(ctx, grn_columns[i], record_id, &colbuf, GRN_OBJ_SET);
- bytes[0] = '\0';
+
+ grn_obj *column = grn_columns[i];
+ if (is_foreign_key_field(table->s->table_name.str, field->field_name.str)) {
+ grn_obj value;
+ GRN_RECORD_INIT(&value, 0, grn_obj_get_range(ctx, column));
+ grn_rc cast_rc = grn_obj_cast(ctx, &colbuf, &value, GRN_FALSE);
+ if (cast_rc != GRN_SUCCESS) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, &colbuf);
+ error = HA_ERR_NO_REFERENCED_ROW;
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "foreign record doesn't exist: <%s>:<%.*s>",
+ field->field_name.str,
+ static_cast<int>(GRN_TEXT_LEN(&inspected)),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &value);
+ GRN_OBJ_FIN(ctx, &colbuf);
+ GRN_OBJ_FIN(ctx, &inspected);
+ goto err;
+ }
+ grn_obj_set_value(ctx, column, record_id, &value, GRN_OBJ_SET);
+ } else {
+ if (added && is_grn_zero_column_value(column, &colbuf)) {
+ // WORKAROUND: groonga can't index newly added '0' value for
+ // fix size column. So we add non-'0' value first then add
+ // real '0' value again. It will be removed when groonga
+ // supports 'null' value.
+ char *bytes = GRN_BULK_HEAD(&colbuf);
+ bytes[0] = '\1';
+ grn_obj_set_value(ctx, column, record_id, &colbuf, GRN_OBJ_SET);
+ bytes[0] = '\0';
+ }
+ grn_obj_set_value(ctx, column, record_id, &colbuf, GRN_OBJ_SET);
}
- grn_obj_set_value(ctx, grn_columns[i], record_id, &colbuf, GRN_OBJ_SET);
if (ctx->rc) {
- grn_obj_unlink(ctx, &colbuf);
+ GRN_OBJ_FIN(ctx, &colbuf);
my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
error = ER_ERROR_ON_WRITE;
goto err;
}
}
- grn_obj_unlink(ctx, &colbuf);
+ GRN_OBJ_FIN(ctx, &colbuf);
error = storage_write_row_multiple_column_indexes(buf, record_id);
if (error) {
@@ -5870,6 +6498,12 @@ int ha_mroonga::wrapper_update_row(const uchar *old_data,
int error = 0;
THD *thd = ha_thd();
+
+ mrn::Operation operation(operations_,
+ "update",
+ table->s->table_name.str,
+ table->s->table_name.length);
+
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
tmp_disable_binlog(thd);
@@ -6009,6 +6643,12 @@ int ha_mroonga::storage_update_row(const uchar *old_data,
DBUG_RETURN(error);
}
+ mrn::Operation operation(operations_,
+ "update",
+ table->s->table_name.str,
+ table->s->table_name.length);
+ operation.record_target(record_id);
+
grn_obj colbuf;
int i;
uint j;
@@ -6017,11 +6657,22 @@ int ha_mroonga::storage_update_row(const uchar *old_data,
for (i = 0; i < n_columns; i++) {
Field *field = table->field[i];
- const char *column_name = field->field_name.str;
- if (bitmap_is_set(table->write_set, field->field_index)) {
- if (field->is_null()) continue;
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+#ifdef MRN_SUPPORT_GENERATED_COLUMNS
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field)) {
+ continue;
+ }
+#endif
+
+ if (!bitmap_is_set(table->write_set, field->field_index))
+ continue;
+
+ if (field->is_null())
+ continue;
+
+ {
+ mrn::ColumnName column_name(field->field_name);
+ if (strcmp(MRN_COLUMN_NAME_ID, column_name.c_str()) == 0) {
push_warning_printf(thd, MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, MRN_GET_ERR_MSG(WARN_DATA_TRUNCATED),
MRN_COLUMN_NAME_ID,
@@ -6031,6 +6682,38 @@ int ha_mroonga::storage_update_row(const uchar *old_data,
}
}
}
+
+ if (!is_foreign_key_field(table->s->table_name.str, field->field_name.str))
+ continue;
+
+ {
+ grn_obj *column = grn_columns[i];
+ grn_obj new_value;
+ GRN_VOID_INIT(&new_value);
+ {
+ mrn::DebugColumnAccess debug_column_access(table, table->read_set);
+ generic_store_bulk(field, &new_value);
+ }
+ grn_obj casted_value;
+ GRN_RECORD_INIT(&casted_value, 0, grn_obj_get_range(ctx, column));
+ grn_rc cast_rc = grn_obj_cast(ctx, &new_value, &casted_value, GRN_FALSE);
+ GRN_OBJ_FIN(ctx, &casted_value);
+ if (cast_rc != GRN_SUCCESS) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, &new_value);
+ GRN_OBJ_FIN(ctx, &new_value);
+ error = HA_ERR_NO_REFERENCED_ROW;
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "foreign record doesn't exist: <%s>:<%.*s>",
+ field->field_name.str,
+ static_cast<int>(GRN_TEXT_LEN(&inspected)),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ DBUG_RETURN(error);
+ }
+ GRN_OBJ_FIN(ctx, &new_value);
+ }
}
KEY *pkey_info = NULL;
@@ -6054,14 +6737,21 @@ int ha_mroonga::storage_update_row(const uchar *old_data,
GRN_VOID_INIT(&colbuf);
for (i = 0; i < n_columns; i++) {
Field *field = table->field[i];
- const char *column_name = field->field_name.str;
+
+#ifdef MRN_SUPPORT_GENERATED_COLUMNS
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field)) {
+ continue;
+ }
+#endif
+
if (bitmap_is_set(table->write_set, field->field_index)) {
mrn::DebugColumnAccess debug_column_access(table, table->read_set);
DBUG_PRINT("info", ("mroonga: update column %d(%d)",i,field->field_index));
if (field->is_null()) continue;
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ mrn::ColumnName column_name(field->field_name);
+ if (strcmp(MRN_COLUMN_NAME_ID, column_name.c_str()) == 0) {
continue;
}
@@ -6069,30 +6759,43 @@ int ha_mroonga::storage_update_row(const uchar *old_data,
if (error)
goto err;
+ bool is_pkey = false;
bool on_duplicate_key_update =
(inserting_with_update && ignoring_duplicated_key);
- if (!on_duplicate_key_update && pkey_info) {
- bool have_pkey = false;
+ if (pkey_info && !on_duplicate_key_update) {
for (j = 0; j < KEY_N_KEY_PARTS(pkey_info); j++) {
Field *pkey_field = pkey_info->key_part[j].field;
- if (strcmp(pkey_field->field_name.str, column_name) == 0) {
- if (!replacing_) {
- char message[MRN_BUFFER_SIZE];
- snprintf(message, MRN_BUFFER_SIZE,
- "data truncated for primary key column: <%s>",
- column_name);
- push_warning(thd, MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, message);
- }
- have_pkey = true;
+ if (strcmp(pkey_field->field_name.str, column_name.c_str()) == 0) {
+ is_pkey = true;
+ break;
}
}
- if (have_pkey) {
- continue;
- }
}
generic_store_bulk(field, &colbuf);
+ if (is_pkey) {
+ bool is_multiple_column_index = KEY_N_KEY_PARTS(pkey_info) > 1;
+ bool is_same_value;
+ if (is_multiple_column_index) {
+ is_same_value = false;
+ } else {
+ grn_id found_record_id = grn_table_get(ctx,
+ grn_table,
+ GRN_BULK_HEAD(&colbuf),
+ GRN_BULK_VSIZE(&colbuf));
+ is_same_value = (record_id == found_record_id);
+ }
+ if (!is_same_value && !replacing_) {
+ char message[MRN_BUFFER_SIZE];
+ snprintf(message, MRN_BUFFER_SIZE,
+ "data truncated for primary key column: <%s>",
+ column_name.c_str());
+ push_warning(thd, MRN_SEVERITY_WARNING,
+ WARN_DATA_TRUNCATED, message);
+ }
+ continue;
+ }
+
grn_obj_set_value(ctx, grn_columns[i], record_id, &colbuf, GRN_OBJ_SET);
if (ctx->rc) {
grn_obj_unlink(ctx, &colbuf);
@@ -6351,6 +7054,12 @@ int ha_mroonga::wrapper_delete_row(const uchar *buf)
int error = 0;
THD *thd= ha_thd();
+
+ mrn::Operation operation(operations_,
+ "delete",
+ table->s->table_name.str,
+ table->s->table_name.length);
+
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
tmp_disable_binlog(thd);
@@ -6440,6 +7149,69 @@ int ha_mroonga::storage_delete_row(const uchar *buf)
DBUG_RETURN(0);
}
+ mrn::Operation operation(operations_,
+ "delete",
+ table->s->table_name.str,
+ table->s->table_name.length);
+ operation.record_target(record_id);
+
+ {
+ grn_id referencing_child_table_id = GRN_ID_NIL;
+ grn_hash *columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ grn_table_columns(ctx, grn_table, "", 0,
+ reinterpret_cast<grn_obj *>(columns));
+ GRN_HASH_EACH_BEGIN(ctx, columns, cursor, id) {
+ void *key;
+ grn_hash_cursor_get_key(ctx, cursor, &key);
+ grn_id column_id = *static_cast<grn_id *>(key);
+ grn_obj *column = grn_ctx_at(ctx, column_id);
+ if (!column)
+ continue;
+
+ if (column->header.type != GRN_COLUMN_INDEX)
+ continue;
+
+ grn_ii_cursor *ii_cursor =
+ grn_ii_cursor_open(ctx,
+ reinterpret_cast<grn_ii *>(column),
+ record_id,
+ GRN_ID_NIL,
+ GRN_ID_MAX,
+ 0,
+ 0);
+ if (!ii_cursor)
+ continue;
+
+ if (grn_ii_cursor_next(ctx, ii_cursor)) {
+ referencing_child_table_id = grn_obj_get_range(ctx, column);
+ }
+
+ grn_ii_cursor_close(ctx, ii_cursor);
+
+ if (referencing_child_table_id != GRN_ID_NIL)
+ break;
+ } GRN_HASH_EACH_END(ctx, cursor);
+ grn_hash_close(ctx, columns);
+
+ if (referencing_child_table_id != GRN_ID_NIL) {
+ grn_obj *referencing_child_table =
+ grn_ctx_at(ctx, referencing_child_table_id);
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_obj_name(ctx,
+ referencing_child_table,
+ name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ error = HA_ERR_ROW_IS_REFERENCED;
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "one or more child rows exist in <%.*s>",
+ name_size,
+ name);
+ DBUG_RETURN(error);
+ }
+ }
+
storage_store_fields_for_prep_update(buf, NULL, record_id);
{
mrn::Lock lock(&(share->record_mutex), have_unique_index());
@@ -6810,6 +7582,13 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
grn_ii *ii = reinterpret_cast<grn_ii *>(index_column);
row_count = grn_ii_estimate_size_for_lexicon_cursor(ctx, ii, cursor);
grn_table_cursor_close(ctx, cursor);
+
+ unsigned int max_n_lexicon_records =
+ grn_table_size(ctx, grn_index_tables[key_nr]);
+ if (cursor_limit >= 0 &&
+ static_cast<unsigned int>(cursor_limit) < max_n_lexicon_records) {
+ row_count++;
+ }
}
DBUG_RETURN(row_count);
}
@@ -6971,7 +7750,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
enum ha_rkey_function find_flag)
{
MRN_DBUG_ENTER_METHOD();
- check_count_skip(keypart_map, 0, false);
+ check_count_skip(keypart_map);
int error = 0;
@@ -6987,6 +7766,29 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
clear_cursor_geo();
clear_empty_value_records();
+ switch (find_flag) {
+ case HA_READ_BEFORE_KEY:
+ flags |= GRN_CURSOR_LT | GRN_CURSOR_DESCENDING;
+ break;
+ case HA_READ_PREFIX_LAST:
+ flags |= GRN_CURSOR_PREFIX | GRN_CURSOR_DESCENDING;
+ break;
+ case HA_READ_PREFIX_LAST_OR_PREV:
+ flags |= GRN_CURSOR_LE | GRN_CURSOR_DESCENDING;
+ break;
+ case HA_READ_AFTER_KEY:
+ flags |= GRN_CURSOR_GT | GRN_CURSOR_ASCENDING;
+ break;
+ case HA_READ_KEY_OR_NEXT:
+ flags |= GRN_CURSOR_GE | GRN_CURSOR_ASCENDING;
+ break;
+ case HA_READ_KEY_EXACT:
+ flags |= GRN_CURSOR_LE | GRN_CURSOR_GE;
+ break;
+ default:
+ break;
+ }
+
bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1;
if (is_multiple_column_index) {
mrn_change_encoding(ctx, NULL);
@@ -6998,13 +7800,21 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
"multiple column index key length=<%u>",
key_length, key_info->key_length));
if (key_length == key_info->key_length) {
- if (find_flag == HA_READ_BEFORE_KEY ||
- find_flag == HA_READ_PREFIX_LAST_OR_PREV) {
+ switch (find_flag) {
+ case HA_READ_BEFORE_KEY:
+ case HA_READ_PREFIX_LAST_OR_PREV:
key_max = key_max_entity;
storage_encode_multiple_column_key(key_info,
key, key_length,
key_max, &size_max);
- } else {
+ break;
+ case HA_READ_PREFIX_LAST:
+ key_min = key_min_entity;
+ storage_encode_multiple_column_key(key_info,
+ key, key_length,
+ key_min, &size_min);
+ break;
+ default:
key_min = key_min_entity;
storage_encode_multiple_column_key(key_info,
key, key_length,
@@ -7013,13 +7823,102 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
key_max = key_min;
size_max = size_min;
}
+ break;
}
} else {
- flags |= GRN_CURSOR_PREFIX;
- key_min = key_min_entity;
- storage_encode_multiple_column_key(key_info,
- key, key_length,
- key_min, &size_min);
+ const uchar *prev_key = NULL;
+ uint prev_key_length = 0;
+ if ((keypart_map >> 1) > 0) {
+ prev_key = key;
+ prev_key_length =
+ mrn_calculate_key_len(table, active_index, key, keypart_map >> 1);
+ }
+ switch (find_flag) {
+ case HA_READ_BEFORE_KEY:
+ if (prev_key) {
+ flags |= GRN_CURSOR_GE;
+ key_min = key_min_entity;
+ storage_encode_multiple_column_key_range(key_info,
+ prev_key, prev_key_length,
+ NULL, 0,
+ key_min, &size_min,
+ NULL, NULL);
+ }
+ key_max = key_max_entity;
+ storage_encode_multiple_column_key_range(key_info,
+ key, key_length,
+ NULL, 0,
+ key_max, &size_max,
+ NULL, NULL);
+ break;
+ case HA_READ_PREFIX_LAST:
+ key_min = key_min_entity;
+ storage_encode_multiple_column_key(key_info,
+ key, key_length,
+ key_min, &size_min);
+ break;
+ case HA_READ_PREFIX_LAST_OR_PREV:
+ if (prev_key) {
+ flags |= GRN_CURSOR_GE;
+ key_min = key_min_entity;
+ storage_encode_multiple_column_key_range(key_info,
+ prev_key, prev_key_length,
+ NULL, 0,
+ key_min, &size_min,
+ NULL, NULL);
+ }
+ key_max = key_max_entity;
+ storage_encode_multiple_column_key_range(key_info,
+ NULL, 0,
+ key, key_length,
+ NULL, NULL,
+ key_max, &size_max);
+ break;
+ case HA_READ_AFTER_KEY:
+ key_min = key_min_entity;
+ storage_encode_multiple_column_key_range(key_info,
+ NULL, 0,
+ key, key_length,
+ NULL, NULL,
+ key_min, &size_min);
+ if (prev_key) {
+ flags |= GRN_CURSOR_LE;
+ key_max = key_max_entity;
+ storage_encode_multiple_column_key_range(key_info,
+ NULL, 0,
+ prev_key, prev_key_length,
+ NULL, NULL,
+ key_max, &size_max);
+ }
+ break;
+ case HA_READ_KEY_OR_NEXT:
+ key_min = key_min_entity;
+ storage_encode_multiple_column_key_range(key_info,
+ key, key_length,
+ NULL, 0,
+ key_min, &size_min,
+ NULL, NULL);
+ if (prev_key) {
+ flags |= GRN_CURSOR_LE;
+ key_max = key_max_entity;
+ storage_encode_multiple_column_key_range(key_info,
+ NULL, 0,
+ prev_key, prev_key_length,
+ NULL, NULL,
+ key_max, &size_max);
+ }
+ break;
+ case HA_READ_KEY_EXACT:
+ key_min = key_min_entity;
+ key_max = key_max_entity;
+ storage_encode_multiple_column_key_range(key_info,
+ key, key_length,
+ key, key_length,
+ key_min, &size_min,
+ key_max, &size_max);
+ default:
+ break;
+ }
}
} else if (mrn_is_geo_key(key_info)) {
error = mrn_change_encoding(ctx, key_info->key_part->field->charset());
@@ -7066,23 +7965,6 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
}
}
- switch (find_flag) {
- case HA_READ_BEFORE_KEY:
- flags |= GRN_CURSOR_LT | GRN_CURSOR_DESCENDING;
- break;
- case HA_READ_PREFIX_LAST_OR_PREV:
- flags |= GRN_CURSOR_LE | GRN_CURSOR_DESCENDING;
- break;
- case HA_READ_AFTER_KEY:
- flags |= GRN_CURSOR_GT | GRN_CURSOR_ASCENDING;
- break;
- case HA_READ_KEY_OR_NEXT:
- flags |= GRN_CURSOR_GE | GRN_CURSOR_ASCENDING;
- break;
- default:
- break;
- }
-
uint pkey_nr = table->s->primary_key;
if (key_nr == pkey_nr) {
DBUG_PRINT("info", ("mroonga: use primary key"));
@@ -7520,222 +8402,6 @@ int ha_mroonga::index_next_same(uchar *buf, const uchar *key, uint keylen)
DBUG_RETURN(error);
}
-int ha_mroonga::wrapper_read_range_first(const key_range *start_key,
- const key_range *end_key,
- bool eq_range, bool sorted)
-{
- int error = 0;
- MRN_DBUG_ENTER_METHOD();
- KEY *key_info = &(table->key_info[active_index]);
- if (mrn_is_geo_key(key_info)) {
- clear_cursor_geo();
- error = generic_geo_open_cursor(start_key->key, start_key->flag);
- if (!error) {
- error = wrapper_get_next_geo_record(table->record[0]);
- }
- DBUG_RETURN(error);
- }
- MRN_SET_WRAP_SHARE_KEY(share, table->s);
- MRN_SET_WRAP_TABLE_KEY(this, table);
- if (fulltext_searching)
- set_pk_bitmap();
- error = wrap_handler->read_range_first(start_key, end_key, eq_range,
- sorted);
- MRN_SET_BASE_SHARE_KEY(share, table->s);
- MRN_SET_BASE_TABLE_KEY(this, table);
- DBUG_RETURN(error);
-}
-
-int ha_mroonga::storage_read_range_first(const key_range *start_key,
- const key_range *end_key,
- bool eq_range, bool sorted)
-{
- MRN_DBUG_ENTER_METHOD();
- check_count_skip(start_key ? start_key->keypart_map : 0,
- end_key ? end_key->keypart_map : 0, false);
- int flags = 0, error;
- uint size_min = 0, size_max = 0;
- uchar *key_min = NULL, *key_max = NULL;
- uchar key_min_entity[MRN_MAX_KEY_SIZE];
- uchar key_max_entity[MRN_MAX_KEY_SIZE];
- KEY *key_info = &(table->s->key_info[active_index]);
-
- clear_cursor();
-
- bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1;
- if (is_multiple_column_index) {
- mrn_change_encoding(ctx, NULL);
- if (start_key && end_key &&
- start_key->length == end_key->length &&
- memcmp(start_key->key, end_key->key, start_key->length) == 0) {
- flags |= GRN_CURSOR_PREFIX;
- key_min = key_min_entity;
- storage_encode_multiple_column_key(key_info,
- start_key->key, start_key->length,
- key_min, &size_min);
- } else {
- key_min = key_min_entity;
- key_max = key_max_entity;
- storage_encode_multiple_column_key_range(key_info,
- start_key, end_key,
- key_min, &size_min,
- key_max, &size_max);
- if (size_min == 0) {
- key_min = NULL;
- }
- if (size_max == 0) {
- key_max = NULL;
- }
- }
- } else {
- Field *field = key_info->key_part[0].field;
- const char *column_name = field->field_name.str;
- error = mrn_change_encoding(ctx, field->charset());
- if (error)
- DBUG_RETURN(error);
- if (start_key) {
- key_min = key_min_entity;
- storage_encode_key(field, start_key->key, key_min_entity,
- &size_min);
- if (start_key->flag == HA_READ_KEY_EXACT) {
- // for _id
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
- grn_id found_record_id = *((grn_id *)key_min);
- if (grn_table_at(ctx, grn_table, found_record_id) != GRN_ID_NIL) { // found
- storage_store_fields(table->record[0], found_record_id);
- table->status = 0;
- cursor = NULL;
- record_id = found_record_id;
- DBUG_RETURN(0);
- } else {
- table->status = STATUS_NOT_FOUND;
- cursor = NULL;
- record_id = GRN_ID_NIL;
- DBUG_RETURN(HA_ERR_END_OF_FILE);
- }
- }
- }
- }
- if (end_key) {
- key_max = key_max_entity;
- storage_encode_key(field, end_key->key, key_max, &size_max);
- }
- }
-
- if (start_key) {
- switch (start_key->flag) {
- case HA_READ_AFTER_KEY:
- flags |= GRN_CURSOR_GT | GRN_CURSOR_ASCENDING;
- break;
- case HA_READ_KEY_OR_NEXT:
- flags |= GRN_CURSOR_GE | GRN_CURSOR_ASCENDING;
- break;
- default:
- break;
- }
- }
- if (end_key) {
- switch (end_key->flag) {
- case HA_READ_BEFORE_KEY:
- flags |= GRN_CURSOR_LT | GRN_CURSOR_ASCENDING;
- break;
- case HA_READ_AFTER_KEY:
- flags |= GRN_CURSOR_GE | GRN_CURSOR_ASCENDING;
- break;
- default:
- break;
- }
- }
-
- uint pkey_nr = table->s->primary_key;
- if (active_index == pkey_nr) {
- DBUG_PRINT("info", ("mroonga: use primary key"));
- cursor = grn_table_cursor_open(ctx, grn_table,
- key_min, size_min, key_max, size_max,
- 0, -1, flags);
- } else {
- if (is_multiple_column_index) {
- DBUG_PRINT("info", ("mroonga: use multiple column key%u", active_index));
- } else {
- DBUG_PRINT("info", ("mroonga: use key%u", active_index));
- }
- index_table_cursor = grn_table_cursor_open(ctx,
- grn_index_tables[active_index],
- key_min, size_min,
- key_max, size_max,
- 0, -1, flags);
- cursor = grn_index_cursor_open(ctx, index_table_cursor,
- grn_index_columns[active_index],
- 0, GRN_ID_MAX, 0);
- }
- if (ctx->rc) {
- my_message(ER_ERROR_ON_READ, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_ERROR_ON_READ);
- }
- error = storage_get_next_record(table->record[0]);
- DBUG_RETURN(error);
-}
-
-int ha_mroonga::read_range_first(const key_range *start_key,
- const key_range *end_key,
- bool eq_range, bool sorted)
-{
- MRN_DBUG_ENTER_METHOD();
- int error = 0;
- if (share->wrapper_mode)
- {
- error = wrapper_read_range_first(start_key, end_key, eq_range,
- sorted);
- } else {
- error = storage_read_range_first(start_key, end_key, eq_range, sorted);
- }
- DBUG_RETURN(error);
-}
-
-int ha_mroonga::wrapper_read_range_next()
-{
- int error = 0;
- MRN_DBUG_ENTER_METHOD();
- KEY *key_info = &(table->key_info[active_index]);
- if (mrn_is_geo_key(key_info)) {
- error = wrapper_get_next_geo_record(table->record[0]);
- DBUG_RETURN(error);
- }
- MRN_SET_WRAP_SHARE_KEY(share, table->s);
- MRN_SET_WRAP_TABLE_KEY(this, table);
- if (fulltext_searching)
- set_pk_bitmap();
- error = wrap_handler->read_range_next();
- MRN_SET_BASE_SHARE_KEY(share, table->s);
- MRN_SET_BASE_TABLE_KEY(this, table);
- DBUG_RETURN(error);
-}
-
-int ha_mroonga::storage_read_range_next()
-{
- MRN_DBUG_ENTER_METHOD();
-
- if (cursor == NULL) {
- DBUG_RETURN(HA_ERR_END_OF_FILE);
- }
- int error = storage_get_next_record(count_skip ? NULL : table->record[0]);
-
- DBUG_RETURN(error);
-}
-
-int ha_mroonga::read_range_next()
-{
- MRN_DBUG_ENTER_METHOD();
- int error = 0;
- if (share->wrapper_mode)
- {
- error = wrapper_read_range_next();
- } else {
- error = storage_read_range_next();
- }
- DBUG_RETURN(error);
-}
-
int ha_mroonga::generic_ft_init()
{
MRN_DBUG_ENTER_METHOD();
@@ -7819,306 +8485,22 @@ void ha_mroonga::generic_ft_init_ext_add_conditions_fast_order_limit(
DBUG_VOID_RETURN;
}
-bool ha_mroonga::generic_ft_init_ext_parse_pragma_d(struct st_mrn_ft_info *info,
- const char *keyword,
- uint keyword_length,
- grn_operator *default_operator,
- uint *consumed_keyword_length)
-{
- MRN_DBUG_ENTER_METHOD();
-
- grn_bool succeeded = true;
- if (keyword_length >= 1 && keyword[0] == '+') {
- *default_operator = GRN_OP_AND;
- *consumed_keyword_length = 1;
- } else if (keyword_length >= 1 && keyword[0] == '-') {
- *default_operator = GRN_OP_AND_NOT;
- *consumed_keyword_length = 1;
- } else if (keyword_length >= 2 && memcmp(keyword, "OR", 2) == 0) {
- *default_operator = GRN_OP_OR;
- *consumed_keyword_length = 2;
- } else {
- succeeded = false;
- }
-
- DBUG_RETURN(succeeded);
-}
-
-void ha_mroonga::generic_ft_init_ext_parse_pragma_w_append_section(
- struct st_mrn_ft_info *info,
- grn_obj *index_column,
- grn_obj *match_columns,
- uint section,
- grn_obj *section_value_buffer,
- int weight,
- uint n_weights)
-{
- MRN_DBUG_ENTER_METHOD();
-
- grn_expr_append_obj(info->ctx, match_columns, index_column, GRN_OP_PUSH, 1);
- GRN_UINT32_SET(info->ctx, section_value_buffer, section);
- grn_expr_append_const(info->ctx, match_columns, section_value_buffer,
- GRN_OP_PUSH, 1);
- grn_expr_append_op(info->ctx, match_columns, GRN_OP_GET_MEMBER, 2);
-
- if (weight != 1) {
- grn_expr_append_const_int(info->ctx, match_columns, weight,
- GRN_OP_PUSH, 1);
- grn_expr_append_op(info->ctx, match_columns, GRN_OP_STAR, 2);
- }
-
- if (n_weights >= 2) {
- grn_expr_append_op(info->ctx, match_columns, GRN_OP_OR, 2);
- }
-
- DBUG_VOID_RETURN;
-}
-
-bool ha_mroonga::generic_ft_init_ext_parse_pragma_w(struct st_mrn_ft_info *info,
- const char *keyword,
- uint keyword_length,
- grn_obj *index_column,
- grn_obj *match_columns,
- uint *consumed_keyword_length,
- grn_obj *tmp_objects)
-{
- MRN_DBUG_ENTER_METHOD();
-
- *consumed_keyword_length = 0;
-
- uint n_sections = KEY_N_KEY_PARTS(info->key_info);
-
- grn_obj section_value_buffer;
- GRN_UINT32_INIT(&section_value_buffer, 0);
-
- MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(bool, specified_sections, n_sections);
- for (uint i = 0; i < n_sections; ++i) {
- specified_sections[i] = false;
- }
-
- uint n_weights = 0;
- while (keyword_length >= 1) {
- if (n_weights >= 1) {
- if (keyword[0] != ',') {
- break;
- }
- uint n_used_keyword_length = 1;
- *consumed_keyword_length += n_used_keyword_length;
- keyword_length -= n_used_keyword_length;
- keyword += n_used_keyword_length;
- if (keyword_length == 0) {
- break;
- }
- }
-
- uint section = 0;
- if ('1' <= keyword[0] && keyword[0] <= '9') {
- const char *section_start = keyword;
- const char *keyword_end = keyword + keyword_length;
- const char *keyword_rest;
- section = grn_atoui(section_start, keyword_end, &keyword_rest);
- if (section_start == keyword_rest) {
- break;
- }
- if (!(0 < section && section <= n_sections)) {
- break;
- }
- section -= 1;
- specified_sections[section] = true;
- uint n_used_keyword_length = keyword_rest - keyword;
- *consumed_keyword_length += n_used_keyword_length;
- keyword_length -= n_used_keyword_length;
- keyword += n_used_keyword_length;
- } else {
- break;
- }
-
- int weight = 1;
- if (keyword_length >= 2 && keyword[0] == ':') {
- const char *weight_start = keyword + 1;
- const char *keyword_end = keyword + keyword_length;
- const char *keyword_rest;
- weight = grn_atoi(weight_start, keyword_end, &keyword_rest);
- if (weight_start == keyword_rest) {
- break;
- }
- uint n_used_keyword_length = keyword_rest - keyword;
- *consumed_keyword_length += n_used_keyword_length;
- keyword_length -= n_used_keyword_length;
- keyword += n_used_keyword_length;
- }
-
- n_weights++;
-
- generic_ft_init_ext_parse_pragma_w_append_section(info,
- index_column,
- match_columns,
- section,
- &section_value_buffer,
- weight,
- n_weights);
- }
-
- for (uint section = 0; section < n_sections; ++section) {
- if (specified_sections[section]) {
- continue;
- }
-
- ++n_weights;
-
- int default_weight = 1;
- generic_ft_init_ext_parse_pragma_w_append_section(info,
- index_column,
- match_columns,
- section,
- &section_value_buffer,
- default_weight,
- n_weights);
- }
- MRN_FREE_VARIABLE_LENGTH_ARRAYS(specified_sections);
-
- GRN_OBJ_FIN(info->ctx, &section_value_buffer);
-
- DBUG_RETURN(n_weights > 0);
-}
-
-grn_expr_flags ha_mroonga::expr_flags_in_boolean_mode()
-{
- MRN_DBUG_ENTER_METHOD();
-
- ulonglong syntax_flags = MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT;
-#ifdef MRN_SUPPORT_THDVAR_SET
- syntax_flags = THDVAR(ha_thd(), boolean_mode_syntax_flags);
-#endif
- grn_expr_flags expression_flags = 0;
- if (syntax_flags == MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT) {
- expression_flags = GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT;
- } else {
- if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_SCRIPT) {
- expression_flags |= GRN_EXPR_SYNTAX_SCRIPT;
- } else {
- expression_flags |= GRN_EXPR_SYNTAX_QUERY;
- }
- if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_COLUMN) {
- expression_flags |= GRN_EXPR_ALLOW_COLUMN;
- }
- if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_UPDATE) {
- expression_flags |= GRN_EXPR_ALLOW_UPDATE;
- }
- if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_LEADING_NOT) {
- expression_flags |= GRN_EXPR_ALLOW_LEADING_NOT;
- }
- }
-
- DBUG_RETURN(expression_flags);
-}
-
grn_rc ha_mroonga::generic_ft_init_ext_prepare_expression_in_boolean_mode(
struct st_mrn_ft_info *info,
String *key,
grn_obj *index_column,
grn_obj *match_columns,
- grn_obj *expression,
- grn_obj *tmp_objects)
+ grn_obj *expression)
{
MRN_DBUG_ENTER_METHOD();
- grn_rc rc = GRN_SUCCESS;
-
- const char *keyword, *keyword_original;
- uint keyword_length, keyword_length_original;
- grn_operator default_operator = GRN_OP_OR;
- grn_bool weight_specified = false;
- keyword = keyword_original = key->ptr();
- keyword_length = keyword_length_original = key->length();
- // WORKAROUND: support only "D" and "W" pragmas.
- if (keyword_length >= 2 && keyword[0] == '*') {
- bool parsed = false;
- bool done = false;
- keyword++;
- keyword_length--;
- while (!done) {
- uint consumed_keyword_length = 0;
- switch (keyword[0]) {
- case 'D':
- if (generic_ft_init_ext_parse_pragma_d(info,
- keyword + 1,
- keyword_length - 1,
- &default_operator,
- &consumed_keyword_length)) {
- parsed = true;
- consumed_keyword_length += 1;
- keyword += consumed_keyword_length;
- keyword_length -= consumed_keyword_length;
- } else {
- done = true;
- }
- break;
- case 'W':
- if (generic_ft_init_ext_parse_pragma_w(info,
- keyword + 1,
- keyword_length - 1,
- index_column,
- match_columns,
- &consumed_keyword_length,
- tmp_objects)) {
- parsed = true;
- weight_specified = true;
- consumed_keyword_length += 1;
- keyword += consumed_keyword_length;
- keyword_length -= consumed_keyword_length;
- } else {
- done = true;
- }
- break;
- default:
- done = true;
- break;
- }
- }
- if (!parsed) {
- keyword = keyword_original;
- keyword_length = keyword_length_original;
- }
- }
- // WORKAROUND: ignore the first '+' to support "+apple macintosh" pattern.
- while (keyword_length > 0 && keyword[0] == ' ') {
- keyword++;
- keyword_length--;
- }
- if (keyword_length > 0 && keyword[0] == '+') {
- keyword++;
- keyword_length--;
- }
- if (!weight_specified) {
- grn_expr_append_obj(info->ctx, match_columns, index_column, GRN_OP_PUSH, 1);
- }
- rc = grn_expr_parse(info->ctx, expression,
- keyword, keyword_length,
- match_columns, GRN_OP_MATCH, default_operator,
- expr_flags_in_boolean_mode());
- if (rc) {
- char error_message[MRN_MESSAGE_BUFFER_SIZE];
- snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
- "failed to parse fulltext search keyword: <%.*s>: <%s>",
- keyword_length_original, keyword_original,
- info->ctx->errbuf);
- ulong action = THDVAR(ha_thd(), action_on_fulltext_query_error);
- switch (static_cast<mrn_action_on_error>(action)) {
- case MRN_ACTION_ON_ERROR_ERROR:
- my_message(ER_PARSE_ERROR, error_message, MYF(0));
- break;
- case MRN_ACTION_ON_ERROR_ERROR_AND_LOG:
- my_message(ER_PARSE_ERROR, error_message, MYF(0));
- GRN_LOG(info->ctx, GRN_LOG_ERROR, "%s", error_message);
- break;
- case MRN_ACTION_ON_ERROR_IGNORE:
- break;
- case MRN_ACTION_ON_ERROR_IGNORE_AND_LOG:
- GRN_LOG(info->ctx, GRN_LOG_ERROR, "%s", error_message);
- break;
- }
- }
+ mrn::QueryParser query_parser(info->ctx,
+ ha_thd(),
+ expression,
+ index_column,
+ KEY_N_KEY_PARTS(info->key_info),
+ match_columns);
+ grn_rc rc = query_parser.parse(key->ptr(), key->length());
DBUG_RETURN(rc);
}
@@ -8128,8 +8510,7 @@ grn_rc ha_mroonga::generic_ft_init_ext_prepare_expression_in_normal_mode(
String *key,
grn_obj *index_column,
grn_obj *match_columns,
- grn_obj *expression,
- grn_obj *tmp_objects)
+ grn_obj *expression)
{
MRN_DBUG_ENTER_METHOD();
@@ -8163,6 +8544,18 @@ struct st_mrn_ft_info *ha_mroonga::generic_ft_init_ext_select(uint flags,
info->result = grn_table_create(info->ctx, NULL, 0, NULL,
GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
grn_table, 0);
+ if (!info->result) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "[mroonga][ft-init] failed to create a table "
+ "to store matched records for one search: <%s>",
+ ctx->errbuf);
+ my_message(ER_ERROR_ON_READ, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ delete info;
+ DBUG_RETURN(NULL);
+ }
+
info->score_column = grn_obj_column(info->ctx, info->result,
MRN_COLUMN_NAME_SCORE,
strlen(MRN_COLUMN_NAME_SCORE));
@@ -8188,8 +8581,6 @@ struct st_mrn_ft_info *ha_mroonga::generic_ft_init_ext_select(uint flags,
grn_obj *expression, *expression_variable;
GRN_EXPR_CREATE_FOR_QUERY(info->ctx, info->table,
expression, expression_variable);
- grn_obj tmp_objects;
- GRN_PTR_INIT(&tmp_objects, GRN_OBJ_VECTOR, GRN_ID_NIL);
grn_rc rc = GRN_SUCCESS;
if (flags & FT_BOOL) {
@@ -8197,15 +8588,13 @@ struct st_mrn_ft_info *ha_mroonga::generic_ft_init_ext_select(uint flags,
key,
index_column,
match_columns,
- expression,
- &tmp_objects);
+ expression);
} else {
rc = generic_ft_init_ext_prepare_expression_in_normal_mode(info,
key,
index_column,
match_columns,
- expression,
- &tmp_objects);
+ expression);
}
if (rc == GRN_SUCCESS) {
@@ -8221,12 +8610,6 @@ struct st_mrn_ft_info *ha_mroonga::generic_ft_init_ext_select(uint flags,
grn_obj_unlink(info->ctx, expression);
grn_obj_unlink(info->ctx, match_columns);
- uint n_tmp_objects = GRN_BULK_VSIZE(&tmp_objects) / sizeof(grn_obj *);
- for (uint i = 0; i < n_tmp_objects; ++i) {
- grn_obj_unlink(info->ctx, GRN_PTR_VALUE_AT(&tmp_objects, i));
- }
- grn_obj_unlink(info->ctx, &tmp_objects);
-
DBUG_RETURN(info);
}
@@ -8234,7 +8617,7 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
{
MRN_DBUG_ENTER_METHOD();
- check_count_skip(0, 0, true);
+ check_count_skip(0);
mrn_change_encoding(ctx, system_charset_info);
grn_operator operation = GRN_OP_OR;
@@ -8242,6 +8625,16 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
matched_record_keys = grn_table_create(ctx, NULL, 0, NULL,
GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
grn_table, 0);
+ if (!matched_record_keys) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "[mroonga][ft-init] "
+ "failed to create a table to store all matched records: <%s>",
+ ctx->errbuf);
+ my_message(ER_ERROR_ON_READ, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ DBUG_RETURN(NULL);
+ }
}
grn_table_sort_key *sort_keys = NULL;
@@ -8249,8 +8642,10 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
longlong limit = -1;
check_fast_order_limit(&sort_keys, &n_sort_keys, &limit);
- struct st_mrn_ft_info *info =
- generic_ft_init_ext_select(flags, key_nr, key);
+ struct st_mrn_ft_info *info = generic_ft_init_ext_select(flags, key_nr, key);
+ if (!info) {
+ DBUG_RETURN(NULL);
+ }
grn_rc rc;
rc = grn_table_setoperation(ctx, matched_record_keys, info->result,
@@ -8264,6 +8659,9 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
}
if (fast_order_limit) {
+ if (sorted_result) {
+ grn_obj_close(ctx, sorted_result);
+ }
sorted_result = grn_table_create(ctx, NULL,
0, NULL,
GRN_OBJ_TABLE_NO_KEY, NULL,
@@ -8302,20 +8700,31 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
FT_INFO *ha_mroonga::wrapper_ft_init_ext(uint flags, uint key_nr, String *key)
{
MRN_DBUG_ENTER_METHOD();
+
FT_INFO *info = generic_ft_init_ext(flags, key_nr, key);
+ if (!info) {
+ DBUG_RETURN(NULL);
+ }
+
struct st_mrn_ft_info *mrn_ft_info = (struct st_mrn_ft_info *)info;
mrn_ft_info->please = &mrn_wrapper_ft_vft;
#ifdef HA_CAN_FULLTEXT_EXT
mrn_ft_info->could_you = &mrn_wrapper_ft_vft_ext;
#endif
++wrap_ft_init_count;
+
DBUG_RETURN(info);
}
FT_INFO *ha_mroonga::storage_ft_init_ext(uint flags, uint key_nr, String *key)
{
MRN_DBUG_ENTER_METHOD();
+
FT_INFO *info = generic_ft_init_ext(flags, key_nr, key);
+ if (!info) {
+ DBUG_RETURN(NULL);
+ }
+
struct st_mrn_ft_info *mrn_ft_info = (struct st_mrn_ft_info *)info;
mrn_ft_info->please = &mrn_storage_ft_vft;
#ifdef HA_CAN_FULLTEXT_EXT
@@ -8464,7 +8873,8 @@ const Item *ha_mroonga::storage_cond_push(const Item *cond)
const Item *reminder_cond = cond;
if (!pushed_cond) {
mrn::ConditionConverter converter(ctx, grn_table, true);
- if (converter.find_match_against(cond) && converter.is_convertable(cond)) {
+ if (converter.count_match_against(cond) == 1 &&
+ converter.is_convertable(cond)) {
reminder_cond = NULL;
}
}
@@ -8577,6 +8987,47 @@ bool ha_mroonga::have_unique_index()
DBUG_RETURN(false);
}
+bool ha_mroonga::is_foreign_key_field(const char *table_name,
+ const char *field_name)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ grn_obj *table = grn_ctx_get(ctx, table_name, -1);
+ if (!table) {
+ DBUG_RETURN(false);
+ }
+
+ mrn::ColumnName column_name(field_name);
+ grn_obj *column = grn_obj_column(ctx,
+ table,
+ column_name.c_str(),
+ column_name.length());
+ if (!column) {
+ DBUG_RETURN(false);
+ }
+
+ grn_obj *range = grn_ctx_at(ctx, grn_obj_get_range(ctx, column));
+ if (!range) {
+ DBUG_RETURN(false);
+ }
+
+ if (!mrn::grn::is_table(range)) {
+ DBUG_RETURN(false);
+ }
+
+ grn_obj *foreign_index_column;
+ mrn::IndexColumnName index_column_name(table_name, field_name);
+ foreign_index_column = grn_obj_column(ctx, range,
+ index_column_name.c_str(),
+ index_column_name.length());
+ if (foreign_index_column) {
+ grn_obj_unlink(ctx, foreign_index_column);
+ DBUG_RETURN(true);
+ }
+
+ DBUG_RETURN(false);
+}
+
void ha_mroonga::push_warning_unsupported_spatial_index_search(enum ha_rkey_function flag)
{
char search_name[MRN_BUFFER_SIZE];
@@ -8756,7 +9207,7 @@ void ha_mroonga::remove_related_files(const char *base_path)
if (stat(entry->d_name, &file_status) != 0) {
continue;
}
- if (!((file_status.st_mode & S_IFMT) & S_IFREG)) {
+ if (!((file_status.st_mode & S_IFMT) && S_IFREG)) {
continue;
}
if (strncmp(entry->d_name, base_path, base_path_length) == 0) {
@@ -8817,6 +9268,11 @@ int ha_mroonga::drop_index(MRN_SHARE *target_share, uint key_index)
grn_obj *index_table = grn_ctx_get(ctx,
index_table_name.c_str(),
index_table_name.length());
+ if (!index_table) {
+ index_table = grn_ctx_get(ctx,
+ index_table_name.old_c_str(),
+ index_table_name.old_length());
+ }
if (index_table) {
target_name_length = grn_obj_name(ctx, index_table,
target_name, GRN_TABLE_MAX_KEY_SIZE);
@@ -8964,7 +9420,9 @@ int ha_mroonga::drop_indexes_normal(const char *table_name, grn_obj *table)
DBUG_RETURN(error);
}
-int ha_mroonga::drop_indexes_multiple(const char *table_name, grn_obj *table)
+int ha_mroonga::drop_indexes_multiple(const char *table_name,
+ grn_obj *table,
+ const char *index_table_name_separator)
{
MRN_DBUG_ENTER_METHOD();
@@ -8972,7 +9430,7 @@ int ha_mroonga::drop_indexes_multiple(const char *table_name, grn_obj *table)
char index_table_name_prefix[GRN_TABLE_MAX_KEY_SIZE];
snprintf(index_table_name_prefix, GRN_TABLE_MAX_KEY_SIZE,
- "%s%s", table_name, mrn::IndexTableName::SEPARATOR);
+ "%s%s", table_name, index_table_name_separator);
grn_table_cursor *cursor =
grn_table_cursor_open(ctx,
grn_ctx_db(ctx),
@@ -9061,7 +9519,12 @@ int ha_mroonga::drop_indexes(const char *table_name)
error = drop_indexes_normal(table_name, table.get());
if (error == 0) {
- error = drop_indexes_multiple(table_name, table.get());
+ error = drop_indexes_multiple(table_name, table.get(),
+ mrn::IndexTableName::SEPARATOR);
+ }
+ if (error == 0) {
+ error = drop_indexes_multiple(table_name, table.get(),
+ mrn::IndexTableName::OLD_SEPARATOR);
}
DBUG_RETURN(error);
@@ -9188,6 +9651,26 @@ grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length)
DBUG_RETURN(tokenizer);
}
+bool ha_mroonga::have_custom_normalizer(KEY *key) const
+{
+ MRN_DBUG_ENTER_METHOD();
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ if (key->option_struct && key->option_struct->normalizer) {
+ DBUG_RETURN(true);
+ }
+#endif
+
+ if (key->comment.length > 0) {
+ mrn::ParametersParser parser(key->comment.str,
+ key->comment.length);
+ parser.parse();
+ DBUG_RETURN(parser["normalizer"] != NULL);
+ }
+
+ DBUG_RETURN(false);
+}
+
grn_obj *ha_mroonga::find_normalizer(KEY *key)
{
MRN_DBUG_ENTER_METHOD();
@@ -9234,7 +9717,7 @@ grn_obj *ha_mroonga::find_normalizer(KEY *key, const char *name)
DBUG_RETURN(normalizer);
}
-bool ha_mroonga::find_index_column_flags(KEY *key, grn_obj_flags *index_column_flags)
+bool ha_mroonga::find_index_column_flags(KEY *key, grn_column_flags *index_column_flags)
{
MRN_DBUG_ENTER_METHOD();
bool found = false;
@@ -9615,154 +10098,51 @@ bool ha_mroonga::should_normalize(Field *field) const
DBUG_RETURN(need_normalize_p);
}
-bool ha_mroonga::is_temporary_table_name(const char *name) const
-{
- MRN_DBUG_ENTER_METHOD();
- DBUG_PRINT("info", ("mroonga: table name = %s", name));
-#ifdef MRN_USE_MYSQL_DATA_HOME
- bool temporary_table_name_p = false;
- if (name[0] != '.') {
- int len = strlen(name);
- int mysql_data_home_len = strlen(mysql_data_home);
- if (len < mysql_data_home_len ||
- strncmp(name, mysql_data_home, mysql_data_home_len) ||
- !strchr(&name[mysql_data_home_len], FN_LIBCHAR)) {
- temporary_table_name_p = true;
- }
- }
-#else
- bool temporary_table_name_p = (name[0] != '.');
-#endif
- DBUG_RETURN(temporary_table_name_p);
-}
-
-void ha_mroonga::check_count_skip(key_part_map start_key_part_map,
- key_part_map end_key_part_map, bool fulltext)
+void ha_mroonga::check_count_skip(key_part_map target_key_part_map)
{
MRN_DBUG_ENTER_METHOD();
if (!is_enable_optimization()) {
- DBUG_PRINT("info", ("mroonga: count skip: optimization is disabled"));
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] optimization is disabled");
count_skip = false;
DBUG_VOID_RETURN;
}
- st_select_lex *select_lex = table->pos_in_table_list->select_lex;
-
- if (
- thd_sql_command(ha_thd()) == SQLCOM_SELECT &&
- select_lex->item_list.elements == 1 &&
- !select_lex->group_list.elements &&
- !MRN_SELECT_LEX_GET_HAVING_COND(select_lex) &&
- select_lex->table_list.elements == 1
- ) {
- Item *info = (Item *) select_lex->item_list.first_node()->info;
- if (
- info->type() != Item::SUM_FUNC_ITEM ||
- ((Item_sum *) info)->sum_func() != Item_sum::COUNT_FUNC ||
- ((Item_sum *) info)->nest_level ||
- ((Item_sum *) info)->aggr_level ||
- ((Item_sum *) info)->max_arg_level != -1 ||
- ((Item_sum *) info)->max_sum_func_level != -1
- ) {
- DBUG_PRINT("info", ("mroonga: count skip: sum func is not match"));
- count_skip = false;
- DBUG_VOID_RETURN;
- }
+ if (thd_sql_command(ha_thd()) != SQLCOM_SELECT) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] not SELECT");
+ count_skip = false;
+ DBUG_VOID_RETURN;
+ }
- uint i = 0;
- Item *where;
- if (fulltext) {
- DBUG_PRINT("info", ("mroonga: count skip: fulltext"));
- where = MRN_SELECT_LEX_GET_WHERE_COND(select_lex);
- if (!where ||
- where->type() != Item::FUNC_ITEM ||
- ((Item_func *)where)->functype() != Item_func::FT_FUNC) {
- DBUG_PRINT("info", ("mroonga: count skip: ft func is not match"));
- count_skip = false;
- DBUG_VOID_RETURN;
- }
- if (select_lex->select_n_where_fields != 1) {
- DBUG_PRINT("info",
- ("mroonga: count skip: "
- "where clause is not fulltext search only"));
- count_skip = false;
- DBUG_VOID_RETURN;
- }
- if (share->wrapper_mode &&
- !(wrap_handler->ha_table_flags() & HA_NO_TRANSACTIONS)) {
- DBUG_PRINT("info", ("mroonga: count skip: transactional wrapper mode"));
- count_skip = false;
- DBUG_VOID_RETURN;
- }
- DBUG_PRINT("info", ("mroonga: count skip: skip enabled"));
- count_skip = true;
- mrn_count_skip++;
- DBUG_VOID_RETURN;
- } else if (share->wrapper_mode) {
- DBUG_PRINT("info", ("mroonga: count skip: wrapper mode"));
- count_skip = false;
- DBUG_VOID_RETURN;
- } else {
- DBUG_PRINT("info", ("mroonga: count skip: without fulltext"));
- uint key_nr = active_index;
- KEY *key_info = &(table->key_info[key_nr]);
- KEY_PART_INFO *key_part = key_info->key_part;
- for (where = MRN_SELECT_LEX_GET_WHERE_COND(select_lex);
- where;
- where = where->next) {
- Item *target = where;
-
- if (where->type() == Item::FUNC_ITEM) {
- Item_func *func_item = static_cast<Item_func *>(where);
- if (func_item->argument_count() == 0) {
- break;
- }
- target = func_item->key_item();
- where = where->next;
- if (func_item->arguments()[0] == where) {
- uint n_args = func_item->argument_count();
- for (; n_args > 0; --n_args) {
- where = where->next;
- }
- }
- }
+ if (share->wrapper_mode &&
+ !(wrap_handler->ha_table_flags() & HA_NO_TRANSACTIONS)) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] wrapped engine is transactional");
+ count_skip = false;
+ DBUG_VOID_RETURN;
+ }
- if (target->type() == Item::FIELD_ITEM)
- {
- Field *field = ((Item_field *)target)->field;
- if (!field)
- break;
- if (field->table != table)
- break;
- uint j;
- for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
- if (key_part[j].field == field)
- {
- if (!(start_key_part_map >> j) && !(end_key_part_map >> j))
- j = KEY_N_KEY_PARTS(key_info);
- else
- i++;
- break;
- }
- }
- if (j >= KEY_N_KEY_PARTS(key_info))
- break;
- }
- if (i >= select_lex->select_n_where_fields)
- {
- DBUG_PRINT("info", ("mroonga: count skip: skip enabled"));
- count_skip = true;
- mrn_count_skip++;
- DBUG_VOID_RETURN;
- }
- }
- DBUG_PRINT("info", ("mroonga: count skip: skip disabled"));
- }
+ st_select_lex *select_lex = table->pos_in_table_list->select_lex;
+ KEY *key_info = NULL;
+ if (active_index != MAX_KEY) {
+ key_info = &(table->key_info[active_index]);
+ }
+ mrn::CountSkipChecker checker(ctx,
+ table,
+ select_lex,
+ key_info,
+ target_key_part_map,
+ !share->wrapper_mode);
+ if (checker.check()) {
+ count_skip = true;
+ mrn_count_skip++;
+ DBUG_VOID_RETURN;
+ } else {
+ count_skip = false;
+ DBUG_VOID_RETURN;
}
- DBUG_PRINT("info", ("mroonga: count skip: select type is not match"));
- count_skip = false;
- DBUG_VOID_RETURN;
}
bool ha_mroonga::is_grn_zero_column_value(grn_obj *column, grn_obj *value)
@@ -9872,15 +10252,22 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
if (!converter.is_convertable(where)) {
DBUG_PRINT("info",
("mroonga: fast_order_limit = false: "
- "not groonga layer condition search"));
+ "not Groonga layer condition search"));
fast_order_limit = false;
DBUG_VOID_RETURN;
}
- match_against = converter.find_match_against(where);
- if (!match_against) {
+ unsigned int n_match_againsts = converter.count_match_against(where);
+ if (n_match_againsts == 0) {
DBUG_PRINT("info",
("mroonga: fast_order_limit = false: "
- "groonga layer condition but not fulltext search"));
+ "Groonga layer condition but not fulltext search"));
+ fast_order_limit = false;
+ DBUG_VOID_RETURN;
+ }
+ if (n_match_againsts > 1) {
+ DBUG_PRINT("info",
+ ("mroonga: fast_order_limit = false: "
+ "MATCH AGAINST must be only one"));
fast_order_limit = false;
DBUG_VOID_RETURN;
}
@@ -9901,8 +10288,7 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
if (item->type() == Item::FIELD_ITEM)
{
Field *field = static_cast<Item_field *>(item)->field;
- const char *column_name = field->field_name.str;
- int column_name_size = field->field_name.length;
+ mrn::ColumnName column_name(field->field_name);
if (should_normalize(field))
{
@@ -9917,7 +10303,8 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
if (is_storage_mode) {
(*sort_keys)[i].key = grn_obj_column(ctx, matched_record_keys,
- column_name, column_name_size);
+ column_name.c_str(),
+ column_name.length());
} else {
if (is_primary_key_field(field)) {
(*sort_keys)[i].key = grn_obj_column(ctx, matched_record_keys,
@@ -10376,6 +10763,20 @@ int ha_mroonga::generic_store_bulk_geometry(Field *field, grn_obj *buf)
DBUG_RETURN(error);
}
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+int ha_mroonga::generic_store_bulk_json(Field *field, grn_obj *buf)
+{
+ MRN_DBUG_ENTER_METHOD();
+ int error = 0;
+ String buffer;
+ Field_json *json = static_cast<Field_json *>(field);
+ String *value = json->val_str(&buffer, NULL);
+ grn_obj_reinit(ctx, buf, GRN_DB_TEXT, 0);
+ GRN_TEXT_SET(ctx, buf, value->ptr(), value->length());
+ DBUG_RETURN(error);
+}
+#endif
+
int ha_mroonga::generic_store_bulk(Field *field, grn_obj *buf)
{
MRN_DBUG_ENTER_METHOD();
@@ -10466,6 +10867,11 @@ int ha_mroonga::generic_store_bulk(Field *field, grn_obj *buf)
case MYSQL_TYPE_GEOMETRY:
error = generic_store_bulk_geometry(field, buf);
break;
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+ case MYSQL_TYPE_JSON:
+ error = generic_store_bulk_json(field, buf);
+ break;
+#endif
default:
error = HA_ERR_UNSUPPORTED;
break;
@@ -10826,6 +11232,18 @@ void ha_mroonga::storage_store_field_geometry(Field *field,
DBUG_VOID_RETURN;
}
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+void ha_mroonga::storage_store_field_json(Field *field,
+ const char *value,
+ uint value_length)
+{
+ MRN_DBUG_ENTER_METHOD();
+ Field_json *json = static_cast<Field_json *>(field);
+ json->store(value, value_length, field->charset());
+ DBUG_VOID_RETURN;
+}
+#endif
+
void ha_mroonga::storage_store_field(Field *field,
const char *value, uint value_length)
{
@@ -10912,6 +11330,11 @@ void ha_mroonga::storage_store_field(Field *field,
case MYSQL_TYPE_VARCHAR_COMPRESSED:
case MYSQL_TYPE_BLOB_COMPRESSED:
DBUG_ASSERT(0);
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+ case MYSQL_TYPE_JSON:
+ storage_store_field_json(field, value, value_length);
+ break;
+#endif
}
}
@@ -10920,6 +11343,10 @@ void ha_mroonga::storage_store_field_column(Field *field, bool is_primary_key,
{
MRN_DBUG_ENTER_METHOD();
+ if (!grn_columns[nth_column]) {
+ DBUG_VOID_RETURN;
+ }
+
grn_obj *column = grn_columns[nth_column];
grn_id range_id = grn_obj_get_range(ctx, column);
grn_obj *range = grn_column_ranges[nth_column];
@@ -11055,6 +11482,11 @@ void ha_mroonga::storage_store_fields_for_prep_update(const uchar *old_data,
for (i = 0; i < n_columns; i++) {
Field *field = table->field[i];
+#ifdef MRN_SUPPORT_GENERATED_COLUMNS
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field)) {
+ continue;
+ }
+#endif
if (
!bitmap_is_set(table->read_set, field->field_index) &&
!bitmap_is_set(table->write_set, field->field_index) &&
@@ -11673,8 +12105,10 @@ int ha_mroonga::storage_encode_multiple_column_key(KEY *key_info,
}
int ha_mroonga::storage_encode_multiple_column_key_range(KEY *key_info,
- const key_range *start,
- const key_range *end,
+ const uchar *start,
+ uint start_size,
+ const uchar *end,
+ uint end_size,
uchar *min_buffer,
uint *min_encoded_size,
uchar *max_buffer,
@@ -11686,14 +12120,14 @@ int ha_mroonga::storage_encode_multiple_column_key_range(KEY *key_info,
uint encoded_key_size = codec.size();
if (start) {
memset(min_buffer, 0, encoded_key_size);
- error = codec.encode(start->key, start->length,
+ error = codec.encode(start, start_size,
min_buffer, min_encoded_size);
// TODO: handle error?
*min_encoded_size = encoded_key_size;
}
if (end) {
memset(max_buffer, 0xff, encoded_key_size);
- error = codec.encode(end->key, end->length,
+ error = codec.encode(end, end_size,
max_buffer, max_encoded_size);
// TODO: handle error?
*max_encoded_size = encoded_key_size;
@@ -11701,6 +12135,40 @@ int ha_mroonga::storage_encode_multiple_column_key_range(KEY *key_info,
DBUG_RETURN(error);
}
+int ha_mroonga::storage_encode_multiple_column_key_range(KEY *key_info,
+ const key_range *start,
+ const key_range *end,
+ uchar *min_buffer,
+ uint *min_encoded_size,
+ uchar *max_buffer,
+ uint *max_encoded_size)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ const uchar *start_data = NULL;
+ uint start_size = 0;
+ const uchar *end_data = NULL;
+ uint end_size = 0;
+ if (start) {
+ start_data = start->key;
+ start_size = start->length;
+ }
+ if (end) {
+ end_data = end->key;
+ end_size = end->length;
+ }
+
+ int error = storage_encode_multiple_column_key_range(key_info,
+ start_data, start_size,
+ end_data, end_size,
+ min_buffer,
+ min_encoded_size,
+ max_buffer,
+ max_encoded_size);
+
+ DBUG_RETURN(error);
+}
+
int ha_mroonga::generic_reset()
{
MRN_DBUG_ENTER_METHOD();
@@ -12364,6 +12832,29 @@ int ha_mroonga::storage_delete_all_rows()
{
MRN_DBUG_ENTER_METHOD();
int error = generic_delete_all_rows(grn_table, __FUNCTION__);
+ if (!error) {
+ uint n_keys = table->s->keys;
+ for (uint i = 0; i < n_keys; i++) {
+ if (i == table->s->primary_key) {
+ continue;
+ }
+
+ KEY *key_info = &(table->key_info[i]);
+ if (!(key_info->flags & HA_NOSAME)) {
+ continue;
+ }
+
+ grn_obj *index_table = grn_index_tables[i];
+ if (!index_table) {
+ continue;
+ }
+
+ error = generic_delete_all_rows(index_table, __FUNCTION__);
+ if (error) {
+ break;
+ }
+ }
+ }
DBUG_RETURN(error);
}
@@ -12527,6 +13018,10 @@ int ha_mroonga::truncate()
} else {
error = storage_truncate();
}
+ if (!error) {
+ operations_->clear(table->s->table_name.str,
+ table->s->table_name.length);
+ }
DBUG_RETURN(error);
}
@@ -12607,6 +13102,7 @@ double ha_mroonga::read_time(uint index, uint ranges, ha_rows rows)
DBUG_RETURN(time);
}
+#ifdef MRN_HANDLER_HAVE_KEYS_TO_USE_FOR_SCANNING
const key_map *ha_mroonga::wrapper_keys_to_use_for_scanning()
{
const key_map *res;
@@ -12637,6 +13133,7 @@ const key_map *ha_mroonga::keys_to_use_for_scanning()
}
DBUG_RETURN(key_map);
}
+#endif
ha_rows ha_mroonga::wrapper_estimate_rows_upper_bound()
{
@@ -12791,11 +13288,16 @@ int ha_mroonga::wrapper_rename_index(const char *from, const char *to,
for (i = 0; i < tmp_table_share->keys; i++) {
const char *mysql_index_name = tmp_table_share->key_info[i].name.str;
mrn::IndexTableName from_index_table_name(from_table_name, mysql_index_name);
- mrn::IndexTableName to_index_table_name(to_table_name, mysql_index_name);
+ mrn::IndexTableName to_index_table_name(to_table_name, mysql_index_name);
grn_obj *index_table;
index_table = grn_ctx_get(ctx,
from_index_table_name.c_str(),
from_index_table_name.length());
+ if (!index_table) {
+ index_table = grn_ctx_get(ctx,
+ from_index_table_name.old_c_str(),
+ from_index_table_name.old_length());
+ }
if (index_table) {
rc = grn_table_rename(ctx, index_table,
to_index_table_name.c_str(),
@@ -12861,6 +13363,11 @@ int ha_mroonga::storage_rename_table(const char *from, const char *to,
index_table = grn_ctx_get(ctx,
from_index_table_name.c_str(),
from_index_table_name.length());
+ if (!index_table) {
+ index_table = grn_ctx_get(ctx,
+ from_index_table_name.old_c_str(),
+ from_index_table_name.old_length());
+ }
if (index_table) {
rc = grn_table_rename(ctx, index_table,
to_index_table_name.c_str(),
@@ -12914,34 +13421,32 @@ int ha_mroonga::storage_rename_foreign_key(MRN_SHARE *tmp_share,
MRN_DBUG_ENTER_METHOD();
for (i = 0; i < n_columns; ++i) {
Field *field = tmp_table_share->field[i];
- const char *column_name = field->field_name.str;
- uint column_name_size = field->field_name.length;
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (!is_foreign_key_field(from_table_name, field->field_name.str)) {
continue;
}
- column = grn_obj_column(ctx, grn_table,
- column_name, column_name_size);
+ grn_obj *grn_from_table = grn_ctx_get(ctx, from_table_name, -1);
+ mrn::ColumnName column_name(field->field_name);
+ column = grn_obj_column(ctx,
+ grn_from_table,
+ column_name.c_str(),
+ column_name.length());
if (!column) {
continue;
}
grn_id ref_table_id = grn_obj_get_range(ctx, column);
grn_obj *ref_table = grn_ctx_at(ctx, ref_table_id);
- if (ref_table->header.type != GRN_TABLE_NO_KEY &&
- ref_table->header.type != GRN_TABLE_HASH_KEY &&
- ref_table->header.type != GRN_TABLE_PAT_KEY &&
- ref_table->header.type != GRN_TABLE_DAT_KEY) {
- continue;
- }
- mrn::IndexColumnName from_index_column_name(from_table_name, column_name);
+ mrn::IndexColumnName from_index_column_name(from_table_name,
+ column_name.c_str());
ref_column = grn_obj_column(ctx, ref_table,
from_index_column_name.c_str(),
from_index_column_name.length());
if (!ref_column) {
continue;
}
- mrn::IndexColumnName to_index_column_name(to_table_name, column_name);
+ mrn::IndexColumnName to_index_column_name(to_table_name,
+ column_name.c_str());
rc = grn_column_rename(ctx, ref_column,
to_index_column_name.c_str(),
to_index_column_name.length());
@@ -12968,11 +13473,10 @@ int ha_mroonga::rename_table(const char *from, const char *to)
if (strcmp(from_mapper.db_name(), to_mapper.db_name()))
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
- table_list.init_one_table(from_mapper.db_name(),
- strlen(from_mapper.db_name()),
- from_mapper.mysql_table_name(),
- strlen(from_mapper.mysql_table_name()),
- from_mapper.mysql_table_name(), TL_WRITE);
+ LEX_CSTRING db_name= { from_mapper.db_name(), strlen(from_mapper.db_name()) };
+ LEX_CSTRING table_name= { from_mapper.mysql_table_name(),
+ strlen(from_mapper.mysql_table_name()) };
+ table_list.init_one_table(&db_name, &table_name, 0,TL_WRITE);
mrn_open_mutex_lock(NULL);
tmp_table_share = mrn_create_tmp_table_share(&table_list, from, &error);
mrn_open_mutex_unlock(NULL);
@@ -13124,6 +13628,11 @@ int ha_mroonga::generic_disable_index(int i, KEY *key_info)
grn_obj *index_table = grn_ctx_get(ctx,
index_table_name.c_str(),
index_table_name.length());
+ if (!index_table) {
+ index_table = grn_ctx_get(ctx,
+ index_table_name.old_c_str(),
+ index_table_name.old_length());
+ }
if (index_table) {
grn_obj_remove(ctx, index_table);
}
@@ -13140,6 +13649,42 @@ int ha_mroonga::generic_disable_index(int i, KEY *key_info)
DBUG_RETURN(error);
}
+int ha_mroonga::wrapper_disable_indexes_mroonga(uint mode)
+{
+ int error = 0;
+ MRN_DBUG_ENTER_METHOD();
+ if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE || mode == HA_KEY_SWITCH_ALL) {
+ uint i;
+ for (i = 0; i < table_share->keys; i++) {
+ if (i == table->s->primary_key) {
+ continue;
+ }
+ if (share->wrap_key_nr[i] < MAX_KEY) {
+ continue;
+ }
+ if (!grn_index_tables[i]) {
+ DBUG_PRINT("info", ("mroonga: keys are disabled already %u", i));
+ DBUG_RETURN(0);
+ }
+ }
+ KEY *key_info = table_share->key_info;
+ for (i = 0; i < table_share->keys; i++) {
+ if (!(key_info[i].flags & HA_FULLTEXT) &&
+ !mrn_is_geo_key(&key_info[i])) {
+ continue;
+ }
+
+ int sub_error = generic_disable_index(i, key_info);
+ if (error != 0 && sub_error != 0) {
+ error = sub_error;
+ }
+ }
+ } else {
+ error = HA_ERR_WRONG_COMMAND;
+ }
+ DBUG_RETURN(error);
+}
+
int ha_mroonga::wrapper_disable_indexes(uint mode)
{
int error = 0;
@@ -13153,35 +13698,7 @@ int ha_mroonga::wrapper_disable_indexes(uint mode)
error = 0;
}
if (!error) {
- if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE || mode == HA_KEY_SWITCH_ALL) {
- uint i;
- for (i = 0; i < table_share->keys; i++) {
- if (i == table->s->primary_key) {
- continue;
- }
- if (share->wrap_key_nr[i] < MAX_KEY) {
- continue;
- }
- if (!grn_index_tables[i]) {
- DBUG_PRINT("info", ("mroonga: keys are disabled already %u", i));
- DBUG_RETURN(0);
- }
- }
- KEY *key_info = table_share->key_info;
- for (i = 0; i < table_share->keys; i++) {
- if (!(key_info[i].flags & HA_FULLTEXT) &&
- !mrn_is_geo_key(&key_info[i])) {
- continue;
- }
-
- int sub_error = generic_disable_index(i, key_info);
- if (error != 0 && sub_error != 0) {
- error = sub_error;
- }
- }
- } else {
- error = HA_ERR_WRONG_COMMAND;
- }
+ error = wrapper_disable_indexes_mroonga(mode);
}
DBUG_RETURN(error);
}
@@ -13235,9 +13752,9 @@ int ha_mroonga::disable_indexes(uint mode)
DBUG_RETURN(error);
}
-int ha_mroonga::wrapper_enable_indexes(uint mode)
+int ha_mroonga::wrapper_enable_indexes_mroonga(uint mode)
{
- int error = 0, tmp_error = 0;
+ int error = 0;
MRN_DBUG_ENTER_METHOD();
if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE || mode == HA_KEY_SWITCH_ALL) {
uint i, j;
@@ -13308,8 +13825,17 @@ int ha_mroonga::wrapper_enable_indexes(uint mode)
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables);
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns);
} else {
- tmp_error = HA_ERR_WRONG_COMMAND;
+ error = HA_ERR_WRONG_COMMAND;
}
+ DBUG_RETURN(error);
+}
+
+int ha_mroonga::wrapper_enable_indexes(uint mode)
+{
+ int error = 0;
+ MRN_DBUG_ENTER_METHOD();
+
+ int mroonga_error = wrapper_enable_indexes_mroonga(mode);
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
@@ -13317,7 +13843,7 @@ int ha_mroonga::wrapper_enable_indexes(uint mode)
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
if (error == HA_ERR_WRONG_COMMAND) {
- error = tmp_error;
+ error = mroonga_error;
}
DBUG_RETURN(error);
}
@@ -13431,10 +13957,10 @@ int ha_mroonga::storage_check(THD* thd, HA_CHECK_OPT* check_opt)
{
MRN_DBUG_ENTER_METHOD();
mrn::DatabaseRepairer repairer(ctx, thd);
- if (repairer.repair()) {
- DBUG_RETURN(HA_ADMIN_OK);
- } else {
+ if (repairer.is_corrupt()) {
DBUG_RETURN(HA_ADMIN_CORRUPT);
+ } else {
+ DBUG_RETURN(HA_ADMIN_OK);
}
}
@@ -13590,10 +14116,16 @@ int ha_mroonga::wrapper_recreate_indexes(THD *thd)
"%s.%s", index_table_name.c_str(), INDEX_COLUMN_NAME);
remove_grn_obj_force(index_column_full_name);
remove_grn_obj_force(index_table_name.c_str());
+
+ char index_column_full_old_name[MRN_MAX_PATH_SIZE];
+ snprintf(index_column_full_old_name, MRN_MAX_PATH_SIZE,
+ "%s.%s", index_table_name.old_c_str(), INDEX_COLUMN_NAME);
+ remove_grn_obj_force(index_column_full_old_name);
+ remove_grn_obj_force(index_table_name.old_c_str());
+
mrn_set_bitmap_by_key(table->read_set, &key_info[i]);
}
- error = wrapper_create_index(table_share->normalized_path.str, table,
- NULL, share, mapper.table_name());
+ error = wrapper_create_index(table_share->normalized_path.str, table, share);
if (error)
DBUG_RETURN(error);
error = wrapper_open_indexes(table_share->normalized_path.str);
@@ -13642,6 +14174,12 @@ int ha_mroonga::storage_recreate_indexes(THD *thd)
"%s.%s", index_table_name.c_str(), INDEX_COLUMN_NAME);
remove_grn_obj_force(index_column_full_name);
remove_grn_obj_force(index_table_name.c_str());
+
+ char index_column_full_old_name[MRN_MAX_PATH_SIZE];
+ snprintf(index_column_full_old_name, MRN_MAX_PATH_SIZE,
+ "%s.%s", index_table_name.old_c_str(), INDEX_COLUMN_NAME);
+ remove_grn_obj_force(index_column_full_old_name);
+ remove_grn_obj_force(index_table_name.old_c_str());
}
int error;
@@ -13984,8 +14522,8 @@ enum_alter_inplace_result ha_mroonga::wrapper_check_if_supported_inplace_alter(
(
Alter_inplace_info::ADD_COLUMN |
Alter_inplace_info::DROP_COLUMN |
- Alter_inplace_info::ALTER_STORED_COLUMN_TYPE |
- Alter_inplace_info::ALTER_STORED_COLUMN_ORDER |
+ MRN_ALTER_INPLACE_INFO_ALTER_STORED_COLUMN_TYPE |
+ MRN_ALTER_INPLACE_INFO_ALTER_STORED_COLUMN_ORDER |
Alter_inplace_info::ALTER_COLUMN_NULLABLE |
Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE |
Alter_inplace_info::ALTER_COLUMN_STORAGE_TYPE |
@@ -14097,15 +14635,22 @@ enum_alter_inplace_result ha_mroonga::storage_check_if_supported_inplace_alter(
Alter_inplace_info *ha_alter_info)
{
MRN_DBUG_ENTER_METHOD();
+ Alter_inplace_info::HA_ALTER_FLAGS explicitly_unsupported_flags =
+ Alter_inplace_info::ADD_FOREIGN_KEY |
+ Alter_inplace_info::DROP_FOREIGN_KEY;
Alter_inplace_info::HA_ALTER_FLAGS supported_flags =
Alter_inplace_info::ADD_INDEX |
Alter_inplace_info::DROP_INDEX |
Alter_inplace_info::ADD_UNIQUE_INDEX |
Alter_inplace_info::DROP_UNIQUE_INDEX |
- Alter_inplace_info::ADD_COLUMN |
+ MRN_ALTER_INPLACE_INFO_ADD_VIRTUAL_COLUMN |
+ MRN_ALTER_INPLACE_INFO_ADD_STORED_BASE_COLUMN |
+ MRN_ALTER_INPLACE_INFO_ADD_STORED_GENERATED_COLUMN |
Alter_inplace_info::DROP_COLUMN |
Alter_inplace_info::ALTER_COLUMN_NAME;
- if (ha_alter_info->handler_flags & supported_flags) {
+ if (ha_alter_info->handler_flags & explicitly_unsupported_flags) {
+ DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
+ } else if (ha_alter_info->handler_flags & supported_flags) {
DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
} else {
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
@@ -14299,18 +14844,11 @@ bool ha_mroonga::wrapper_inplace_alter_table(
need_fill_index = true;
}
if (!error && need_fill_index) {
- my_ptrdiff_t ptr_diff = PTR_BYTE_DIFF(table->record[0], altered_table->record[0]);
- uint n_columns = altered_table->s->fields;
- for (i = 0; i < n_columns; ++i) {
- Field *field = altered_table->field[i];
- field->move_field_offset(ptr_diff);
- }
+ my_ptrdiff_t diff =
+ PTR_BYTE_DIFF(table->record[0], altered_table->record[0]);
+ mrn::TableFieldsOffsetMover mover(altered_table, diff);
error = wrapper_fill_indexes(ha_thd(), altered_table->key_info,
index_columns, ha_alter_info->key_count);
- for (i = 0; i < n_columns; ++i) {
- Field *field = altered_table->field[i];
- field->move_field_offset(-ptr_diff);
- }
}
bitmap_set_all(table->read_set);
@@ -14369,31 +14907,12 @@ bool ha_mroonga::wrapper_inplace_alter_table(
DBUG_RETURN(result);
}
-bool ha_mroonga::storage_inplace_alter_table_index(
+bool ha_mroonga::storage_inplace_alter_table_add_index(
TABLE *altered_table,
Alter_inplace_info *ha_alter_info)
{
MRN_DBUG_ENTER_METHOD();
- bool have_error = false;
- int error = 0;
- uint n_keys;
- uint i, j = 0;
- KEY *key_info = table_share->key_info;
- mrn::PathMapper mapper(share->table_name);
- n_keys = ha_alter_info->index_drop_count;
- for (i = 0; i < n_keys; ++i) {
- KEY *key = ha_alter_info->index_drop_buffer[i];
- while (strcmp(key_info[j].name.str, key->name.str)) {
- ++j;
- }
- error = drop_index(share, j);
- if (error)
- DBUG_RETURN(true);
- grn_index_tables[j] = NULL;
- grn_index_columns[j] = NULL;
- }
-
MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_tables,
ha_alter_info->key_count);
MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_columns,
@@ -14439,11 +14958,11 @@ bool ha_mroonga::storage_inplace_alter_table_index(
KEY *p_key_info = &table->key_info[table_share->primary_key];
mrn_set_bitmap_by_key(table->read_set, p_key_info);
}
- n_keys = ha_alter_info->index_add_count;
- for (i = 0; i < n_keys; ++i) {
+ int error = 0;
+ uint n_keys = ha_alter_info->index_add_count;
+ for (uint i = 0; i < n_keys; ++i) {
uint key_pos = ha_alter_info->index_add_buffer[i];
- KEY *key =
- &altered_table->key_info[key_pos];
+ KEY *key = &altered_table->key_info[key_pos];
if (share->disable_keys && !(key->flags & HA_NOSAME)) {
continue; // key is disabled
}
@@ -14452,6 +14971,7 @@ bool ha_mroonga::storage_inplace_alter_table_index(
break;
}
DBUG_PRINT("info", ("mroonga: add key pos=%u", key_pos));
+ mrn::PathMapper mapper(share->table_name);
if ((error = storage_create_index(table, mapper.table_name(), grn_table,
tmp_share, key, index_tables,
index_columns, key_pos)))
@@ -14479,12 +14999,9 @@ bool ha_mroonga::storage_inplace_alter_table_index(
}
}
if (!error && have_multiple_column_index) {
- my_ptrdiff_t ptr_diff = PTR_BYTE_DIFF(table->record[0], altered_table->record[0]);
- uint n_columns = altered_table->s->fields;
- for (i = 0; i < n_columns; ++i) {
- Field *field = altered_table->field[i];
- field->move_field_offset(ptr_diff);
- }
+ my_ptrdiff_t diff =
+ PTR_BYTE_DIFF(table->record[0], altered_table->record[0]);
+ mrn::TableFieldsOffsetMover mover(altered_table, diff);
error = storage_add_index_multiple_columns(altered_table->key_info,
ha_alter_info->key_count,
index_tables,
@@ -14495,17 +15012,14 @@ bool ha_mroonga::storage_inplace_alter_table_index(
} else if (error) {
my_message(error, "failed to create multiple column index", MYF(0));
}
- for (i = 0; i < n_columns; ++i) {
- Field *field = altered_table->field[i];
- field->move_field_offset(-ptr_diff);
- }
}
bitmap_set_all(table->read_set);
+ bool have_error = false;
if (error)
{
n_keys = ha_alter_info->index_add_count;
- for (i = 0; i < n_keys; ++i) {
+ for (uint i = 0; i < n_keys; ++i) {
uint key_pos = ha_alter_info->index_add_buffer[i];
KEY *key =
&altered_table->key_info[key_pos];
@@ -14528,6 +15042,33 @@ bool ha_mroonga::storage_inplace_alter_table_index(
DBUG_RETURN(have_error);
}
+bool ha_mroonga::storage_inplace_alter_table_drop_index(
+ TABLE *altered_table,
+ Alter_inplace_info *ha_alter_info)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ bool have_error = false;
+ uint n_keys;
+ uint i, j = 0;
+ KEY *key_info = table_share->key_info;
+ mrn::PathMapper mapper(share->table_name);
+ n_keys = ha_alter_info->index_drop_count;
+ for (i = 0; i < n_keys; ++i) {
+ KEY *key = ha_alter_info->index_drop_buffer[i];
+ while (strcmp(key_info[j].name.str, key->name.str) != 0) {
+ ++j;
+ }
+ int error = drop_index(share, j);
+ if (error != 0)
+ DBUG_RETURN(true);
+ grn_index_tables[j] = NULL;
+ grn_index_columns[j] = NULL;
+ }
+
+ DBUG_RETURN(have_error);
+}
+
bool ha_mroonga::storage_inplace_alter_table_add_column(
TABLE *altered_table,
Alter_inplace_info *ha_alter_info)
@@ -14581,9 +15122,14 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
}
Field *field = altered_table->s->field[i];
- const char *column_name = field->field_name.str;
- int column_name_size = field->field_name.length;
+#ifdef MRN_SUPPORT_GENERATED_COLUMNS
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field)) {
+ continue;
+ }
+#endif
+
+ mrn::ColumnName column_name(field->field_name);
int error = mrn_add_column_param(tmp_share, field, i);
if (error) {
have_error = true;
@@ -14608,20 +15154,114 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
char *col_path = NULL; // we don't specify path
grn_obj *column_obj =
- grn_column_create(ctx, table_obj, column_name, column_name_size,
+ grn_column_create(ctx, table_obj,
+ column_name.c_str(),
+ column_name.length(),
col_path, col_flags, col_type);
if (ctx->rc) {
error = ER_WRONG_COLUMN_NAME;
my_message(error, ctx->errbuf, MYF(0));
have_error = true;
- }
- if (column_obj) {
- grn_obj_unlink(ctx, column_obj);
+ break;
}
- if (have_error) {
- break;
+#ifdef MRN_SUPPORT_GENERATED_COLUMNS
+ if (MRN_GENERATED_COLUMNS_FIELD_IS_STORED(field)) {
+# ifndef MRN_MARIADB_P
+ MY_BITMAP generated_column_bitmap;
+ if (bitmap_init(&generated_column_bitmap, NULL,
+ altered_table->s->fields, false)) {
+ error = HA_ERR_OUT_OF_MEM;
+ my_message(ER_OUTOFMEMORY,
+ "mroonga: storage: "
+ "failed to allocate memory for getting generated value",
+ MYF(0));
+ have_error = true;
+ grn_obj_remove(ctx, column_obj);
+ break;
+ }
+ mrn::SmartBitmap smart_generated_column_bitmap(&generated_column_bitmap);
+ bitmap_set_bit(&generated_column_bitmap, field->field_index);
+# endif
+
+ my_ptrdiff_t diff =
+ PTR_BYTE_DIFF(table->record[0], altered_table->record[0]);
+ mrn::TableFieldsOffsetMover mover(altered_table, diff);
+
+ error = storage_rnd_init(true);
+ if (error) {
+ have_error = true;
+ grn_obj_remove(ctx, column_obj);
+ break;
+ }
+
+ Field *altered_field = altered_table->field[i];
+ grn_obj new_value;
+ GRN_VOID_INIT(&new_value);
+ mrn::SmartGrnObj smart_new_value(ctx, &new_value);
+ while (!have_error) {
+ int next_error = storage_rnd_next(table->record[0]);
+ if (next_error == HA_ERR_END_OF_FILE) {
+ break;
+ } else if (next_error != 0) {
+ error = next_error;
+ have_error = true;
+ grn_obj_remove(ctx, column_obj);
+ break;
+ }
+
+# ifdef MRN_MARIADB_P
+ MRN_GENERATED_COLUMNS_UPDATE_VIRTUAL_FIELD(altered_table, altered_field);
+# else
+ if (update_generated_write_fields(&generated_column_bitmap, altered_table)) {
+ error = ER_ERROR_ON_WRITE;
+ my_message(error,
+ "mroonga: storage: "
+ "failed to update generated value for updating column",
+ MYF(0));
+ have_error = true;
+ grn_obj_remove(ctx, column_obj);
+ break;
+ }
+# endif
+
+ error = mrn_change_encoding(ctx, altered_field->charset());
+ if (error) {
+ my_message(error,
+ "mroonga: storage: "
+ "failed to change encoding to store generated value",
+ MYF(0));
+ have_error = true;
+ grn_obj_remove(ctx, column_obj);
+ break;
+ }
+ error = generic_store_bulk(altered_field, &new_value);
+ if (error) {
+ my_message(error,
+ "mroonga: storage: "
+ "failed to get generated value for updating column",
+ MYF(0));
+ have_error = true;
+ grn_obj_remove(ctx, column_obj);
+ break;
+ }
+
+ grn_obj_set_value(ctx, column_obj, record_id, &new_value, GRN_OBJ_SET);
+ if (ctx->rc) {
+ error = ER_ERROR_ON_WRITE;
+ my_message(error, ctx->errbuf, MYF(0));
+ break;
+ }
+ }
+
+ int end_error = storage_rnd_end();
+ if (end_error != 0 && error == 0) {
+ error = end_error;
+ grn_obj_remove(ctx, column_obj);
+ break;
+ }
}
+#endif
}
grn_obj_unlink(ctx, table_obj);
@@ -14753,16 +15393,14 @@ bool ha_mroonga::storage_inplace_alter_table(
have_error = true;
}
- Alter_inplace_info::HA_ALTER_FLAGS index_related_flags =
- Alter_inplace_info::ADD_INDEX |
+ Alter_inplace_info::HA_ALTER_FLAGS drop_index_related_flags =
Alter_inplace_info::DROP_INDEX |
- Alter_inplace_info::ADD_UNIQUE_INDEX |
Alter_inplace_info::DROP_UNIQUE_INDEX |
- Alter_inplace_info::ADD_PK_INDEX |
Alter_inplace_info::DROP_PK_INDEX;
if (!have_error &&
- (ha_alter_info->handler_flags & index_related_flags)) {
- have_error = storage_inplace_alter_table_index(altered_table, ha_alter_info);
+ (ha_alter_info->handler_flags & drop_index_related_flags)) {
+ have_error = storage_inplace_alter_table_drop_index(altered_table,
+ ha_alter_info);
}
Alter_inplace_info::HA_ALTER_FLAGS add_column_related_flags =
@@ -14786,6 +15424,16 @@ bool ha_mroonga::storage_inplace_alter_table(
have_error = storage_inplace_alter_table_rename_column(altered_table, ha_alter_info);
}
+ Alter_inplace_info::HA_ALTER_FLAGS add_index_related_flags =
+ Alter_inplace_info::ADD_INDEX |
+ Alter_inplace_info::ADD_UNIQUE_INDEX |
+ Alter_inplace_info::ADD_PK_INDEX;
+ if (!have_error &&
+ (ha_alter_info->handler_flags & add_index_related_flags)) {
+ have_error = storage_inplace_alter_table_add_index(altered_table,
+ ha_alter_info);
+ }
+
DBUG_RETURN(have_error);
}
@@ -15891,26 +16539,22 @@ char *ha_mroonga::storage_get_foreign_key_create_info()
create_info_str.length(0);
for (i = 0; i < n_columns; ++i) {
Field *field = table_share->field[i];
- const char *column_name = field->field_name.str;
- uint column_name_size = field->field_name.length;
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (!is_foreign_key_field(table_share->table_name.str,
+ field->field_name.str)) {
continue;
}
- column = grn_obj_column(ctx, grn_table,
- column_name, column_name_size);
+ mrn::ColumnName column_name(field->field_name);
+ column = grn_obj_column(ctx,
+ grn_table,
+ column_name.c_str(),
+ column_name.length());
if (!column) {
continue;
}
grn_id ref_table_id = grn_obj_get_range(ctx, column);
grn_obj *ref_table = grn_ctx_at(ctx, ref_table_id);
- if (ref_table->header.type != GRN_TABLE_NO_KEY &&
- ref_table->header.type != GRN_TABLE_HASH_KEY &&
- ref_table->header.type != GRN_TABLE_PAT_KEY &&
- ref_table->header.type != GRN_TABLE_DAT_KEY) {
- continue;
- }
char ref_table_buff[NAME_LEN + 1];
int ref_table_name_length = grn_obj_name(ctx, ref_table, ref_table_buff,
NAME_LEN);
@@ -15920,14 +16564,18 @@ char *ha_mroonga::storage_get_foreign_key_create_info()
DBUG_RETURN(NULL);
}
create_info_str.q_append(",\n CONSTRAINT ", 15);
- append_identifier(ha_thd(), &create_info_str, column_name,
- column_name_size);
+ append_identifier(ha_thd(),
+ &create_info_str,
+ column_name.c_str(),
+ column_name.length());
if (create_info_str.reserve(14)) {
DBUG_RETURN(NULL);
}
create_info_str.q_append(" FOREIGN KEY (", 14);
- append_identifier(ha_thd(), &create_info_str, column_name,
- column_name_size);
+ append_identifier(ha_thd(),
+ &create_info_str,
+ column_name.c_str(),
+ column_name.length());
if (create_info_str.reserve(13)) {
DBUG_RETURN(NULL);
}
@@ -15951,11 +16599,9 @@ char *ha_mroonga::storage_get_foreign_key_create_info()
build_table_filename(ref_path, sizeof(ref_path) - 1,
table_share->db.str, ref_table_buff, "", 0);
DBUG_PRINT("info", ("mroonga: ref_path=%s", ref_path));
- table_list.init_one_table(table_share->db.str,
- table_share->db.length,
- ref_table_buff,
- ref_table_name_length,
- ref_table_buff, TL_WRITE);
+
+ LEX_CSTRING table_name= { ref_table_buff, (size_t) ref_table_name_length };
+ table_list.init_one_table(&table_share->db, &table_name, 0, TL_WRITE);
mrn_open_mutex_lock(table_share);
tmp_ref_table_share =
mrn_create_tmp_table_share(&table_list, ref_path, &error);
@@ -16098,37 +16744,36 @@ int ha_mroonga::storage_get_foreign_key_list(THD *thd,
MRN_DBUG_ENTER_METHOD();
for (i = 0; i < n_columns; ++i) {
Field *field = table_share->field[i];
- const char *column_name = field->field_name.str;
- uint column_name_size = field->field_name.length;
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (!is_foreign_key_field(table_share->table_name.str,
+ field->field_name.str)) {
continue;
}
- column = grn_obj_column(ctx, grn_table,
- column_name, column_name_size);
+ mrn::ColumnName column_name(field->field_name);
+ column = grn_obj_column(ctx,
+ grn_table,
+ column_name.c_str(),
+ column_name.length());
if (!column) {
continue;
}
grn_id ref_table_id = grn_obj_get_range(ctx, column);
grn_obj *ref_table = grn_ctx_at(ctx, ref_table_id);
- if (ref_table->header.type != GRN_TABLE_NO_KEY &&
- ref_table->header.type != GRN_TABLE_HASH_KEY &&
- ref_table->header.type != GRN_TABLE_PAT_KEY &&
- ref_table->header.type != GRN_TABLE_DAT_KEY) {
- continue;
- }
FOREIGN_KEY_INFO f_key_info;
- f_key_info.foreign_id = thd_make_lex_string(thd, NULL, column_name,
- column_name_size, TRUE);
+ f_key_info.foreign_id = thd_make_lex_string(thd,
+ NULL,
+ column_name.c_str(),
+ column_name.length(),
+ TRUE);
f_key_info.foreign_db = thd_make_lex_string(thd, NULL,
- table_share->db.str,
- table_share->db.length,
- TRUE);
+ table_share->db.str,
+ table_share->db.length,
+ TRUE);
f_key_info.foreign_table = thd_make_lex_string(thd, NULL,
- table_share->table_name.str,
- table_share->table_name.length,
- TRUE);
+ table_share->table_name.str,
+ table_share->table_name.length,
+ TRUE);
f_key_info.referenced_db = f_key_info.foreign_db;
char ref_table_buff[NAME_LEN + 1];
@@ -16141,12 +16786,22 @@ int ha_mroonga::storage_get_foreign_key_list(THD *thd,
ref_table_buff,
ref_table_name_length,
TRUE);
+#ifdef MRN_FOREIGN_KEY_USE_METHOD_ENUM
f_key_info.update_method = FK_OPTION_RESTRICT;
f_key_info.delete_method = FK_OPTION_RESTRICT;
+#else
+ f_key_info.update_method = thd_make_lex_string(thd, NULL, "RESTRICT",
+ 8, TRUE);
+ f_key_info.delete_method = thd_make_lex_string(thd, NULL, "RESTRICT",
+ 8, TRUE);
+#endif
f_key_info.referenced_key_name = thd_make_lex_string(thd, NULL, "PRIMARY",
7, TRUE);
- LEX_CSTRING *field_name = thd_make_lex_string(thd, NULL, column_name,
- column_name_size, TRUE);
+ LEX_CSTRING *field_name = thd_make_lex_string(thd,
+ NULL,
+ column_name.c_str(),
+ column_name.length(),
+ TRUE);
f_key_info.foreign_fields.push_back(field_name);
char ref_path[FN_REFLEN + 1];
@@ -16155,11 +16810,9 @@ int ha_mroonga::storage_get_foreign_key_list(THD *thd,
build_table_filename(ref_path, sizeof(ref_path) - 1,
table_share->db.str, ref_table_buff, "", 0);
DBUG_PRINT("info", ("mroonga: ref_path=%s", ref_path));
- table_list.init_one_table(table_share->db.str,
- table_share->db.length,
- ref_table_buff,
- ref_table_name_length,
- ref_table_buff, TL_WRITE);
+
+ LEX_CSTRING table_name= { ref_table_buff, (size_t) ref_table_name_length };
+ table_list.init_one_table(&table_share->db, &table_name, 0, TL_WRITE);
mrn_open_mutex_lock(table_share);
tmp_ref_table_share =
mrn_create_tmp_table_share(&table_list, ref_path, &error);
@@ -16348,6 +17001,7 @@ void ha_mroonga::free_foreign_key_create_info(char* str)
DBUG_VOID_RETURN;
}
+#ifdef MRN_RBR_UPDATE_NEED_ALL_COLUMNS
bool ha_mroonga::check_written_by_row_based_binlog()
{
MRN_DBUG_ENTER_METHOD();
@@ -16381,6 +17035,7 @@ bool ha_mroonga::check_written_by_row_based_binlog()
DBUG_RETURN(true);
}
+#endif
#ifdef MRN_HAVE_HA_REBIND_PSI
void ha_mroonga::wrapper_unbind_psi()
@@ -16510,3 +17165,20 @@ my_bool ha_mroonga::register_query_cache_table(THD *thd,
#ifdef __cplusplus
}
#endif
+
+namespace mrn {
+ namespace variables {
+ ulonglong get_boolean_mode_syntax_flags(THD *thd) {
+ ulonglong flags = BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT;
+#ifdef MRN_SUPPORT_THDVAR_SET
+ flags = THDVAR(thd, boolean_mode_syntax_flags);
+#endif
+ return flags;
+ }
+
+ ActionOnError get_action_on_fulltext_query_error(THD *thd) {
+ ulong action = THDVAR(thd, action_on_fulltext_query_error);
+ return static_cast<ActionOnError>(action);
+ }
+ }
+}
diff --git a/storage/mroonga/ha_mroonga.def b/storage/mroonga/ha_mroonga.def
index 5770cde72e7..7f8394fe4ca 100644
--- a/storage/mroonga/ha_mroonga.def
+++ b/storage/mroonga/ha_mroonga.def
@@ -13,3 +13,6 @@ EXPORTS
mroonga_escape
mroonga_escape_init
mroonga_escape_deinit
+ mroonga_normalize
+ mroonga_normalize_init
+ mroonga_normalize_deinit
diff --git a/storage/mroonga/ha_mroonga.hpp b/storage/mroonga/ha_mroonga.hpp
index 6416513f0eb..15497e70c59 100644
--- a/storage/mroonga/ha_mroonga.hpp
+++ b/storage/mroonga/ha_mroonga.hpp
@@ -32,6 +32,14 @@ extern "C" {
#include <groonga.h>
#include "mrn_mysql_compat.h"
+#include <mrn_operations.hpp>
+#include <mrn_database.hpp>
+
+#if __cplusplus >= 201402
+# define mrn_override override
+#else
+# define mrn_override
+#endif
#if (MYSQL_VERSION_ID >= 50514 && MYSQL_VERSION_ID < 50600)
# define MRN_HANDLER_HAVE_FINAL_ADD_INDEX 1
@@ -102,6 +110,13 @@ extern "C" {
# define MRN_HAVE_HA_EXTRA_PREPARE_FOR_FORCED_CLOSE
#endif
+#if (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 80002)
+#define MRN_HAVE_HA_EXTRA_SKIP_SERIALIZABLE_DD_VIEW
+#define MRN_HAVE_HA_EXTRA_BEGIN_ALTER_COPY
+#define MRN_HAVE_HA_EXTRA_END_ALTER_COPY
+#define MRN_HAVE_HA_EXTRA_NO_AUTOINC_LOCKING
+#endif
+
#if MYSQL_VERSION_ID >= 50607 && \
(!defined(MRN_MARIADB_P) || MYSQL_VERSION_ID < 100008)
# define MRN_HAVE_HA_EXTRA_EXPORT
@@ -196,6 +211,10 @@ extern "C" {
# define MRN_FOREIGN_KEY_USE_CONST_STRING
#endif
+#if MYSQL_VERSION_ID >= 100203 && defined(MRN_MARIADB_P)
+# define MRN_FOREIGN_KEY_USE_METHOD_ENUM
+#endif
+
#if MYSQL_VERSION_ID < 50706 || defined(MRN_MARIADB_P)
# define MRN_HANDLER_IS_FATAL_ERROR_HAVE_FLAGS
#endif
@@ -204,6 +223,45 @@ extern "C" {
# define MRN_HANDLER_HAVE_RESET_AUTO_INCREMENT
#endif
+#if (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50709) || \
+ (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100203)
+# define MRN_ALTER_INPLACE_INFO_ALTER_STORED_COLUMN_TYPE \
+ Alter_inplace_info::ALTER_STORED_COLUMN_TYPE
+# define MRN_ALTER_INPLACE_INFO_ALTER_STORED_COLUMN_ORDER \
+ Alter_inplace_info::ALTER_STORED_COLUMN_ORDER
+#else
+# define MRN_ALTER_INPLACE_INFO_ALTER_STORED_COLUMN_TYPE \
+ Alter_inplace_info::ALTER_COLUMN_TYPE
+# define MRN_ALTER_INPLACE_INFO_ALTER_STORED_COLUMN_ORDER \
+ Alter_inplace_info::ALTER_COLUMN_ORDER
+#endif
+
+#if MYSQL_VERSION_ID >= 50700 && !defined(MRN_MARIADB_P)
+# define MRN_HANDLER_RECORDS_RETURN_ERROR
+#endif
+
+#if MYSQL_VERSION_ID < 80002 || defined(MRN_MARIADB_P)
+# define MRN_HANDLER_HAVE_KEYS_TO_USE_FOR_SCANNING
+#endif
+
+#if (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 80002)
+# define MRN_ST_MYSQL_PLUGIN_HAVE_CHECK_UNINSTALL
+#endif
+
+#if (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 80002)
+# define MRN_HANDLER_OPEN_HAVE_TABLE_DEFINITION
+# define MRN_HANDLER_CREATE_HAVE_TABLE_DEFINITION
+#endif
+
+#if (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 80002)
+# define MRN_HANDLERTON_CREATE_HAVE_PARTITIONED
+#endif
+
+#if defined(HAVE_PSI_INTERFACE) && \
+ (MYSQL_VERSION_ID < 80002 || defined(MRN_MARIADB_P))
+# define MRN_HAVE_PSI_SERVER
+#endif
+
class ha_mroonga;
/* structs */
@@ -347,6 +405,8 @@ private:
// for ft in where clause test
Item_func_match *current_ft_item;
+ mrn::Operations *operations_;
+
public:
ha_mroonga(handlerton *hton, TABLE_SHARE *share_arg);
~ha_mroonga();
@@ -357,8 +417,20 @@ public:
ulonglong table_flags() const; // required
ulong index_flags(uint idx, uint part, bool all_parts) const; // required
- int create(const char *name, TABLE *form, HA_CREATE_INFO *info); // required
- int open(const char *name, int mode, uint test_if_locked); // required
+ // required
+ int create(const char *name, TABLE *form, HA_CREATE_INFO *info
+#ifdef MRN_HANDLER_CREATE_HAVE_TABLE_DEFINITION
+ ,
+ dd::Table *table_def
+#endif
+ ) mrn_override;
+ // required
+ int open(const char *name, int mode, uint open_options
+#ifdef MRN_HANDLER_OPEN_HAVE_TABLE_DEFINITION
+ ,
+ const dd::Table *table_def
+#endif
+ ) mrn_override;
#ifndef MRN_HANDLER_HAVE_HA_CLOSE
int close(); // required
#endif
@@ -419,11 +491,6 @@ public:
#endif
int index_next_same(uchar *buf, const uchar *key, uint keylen);
- int read_range_first(const key_range *start_key,
- const key_range *end_key,
- bool eq_range, bool sorted);
- int read_range_next();
-
int ft_init();
FT_INFO *ft_init_ext(uint flags, uint inx, String *key);
int ft_read(uchar *buf);
@@ -469,7 +536,9 @@ public:
int truncate();
double scan_time();
double read_time(uint index, uint ranges, ha_rows rows);
+#ifdef MRN_HANDLER_HAVE_KEYS_TO_USE_FOR_SCANNING
const key_map *keys_to_use_for_scanning();
+#endif
ha_rows estimate_rows_upper_bound();
void update_create_info(HA_CREATE_INFO* create_info);
int rename_table(const char *from, const char *to);
@@ -518,6 +587,11 @@ public:
int start_stmt(THD *thd, thr_lock_type lock_type);
protected:
+#ifdef MRN_HANDLER_RECORDS_RETURN_ERROR
+ int records(ha_rows *num_rows);
+#else
+ ha_rows records();
+#endif
#ifdef MRN_HANDLER_HAVE_HA_RND_NEXT
int rnd_next(uchar *buf);
#endif
@@ -580,6 +654,9 @@ private:
bool have_unique_index();
+ bool is_foreign_key_field(const char *table_name,
+ const char *field_name);
+
void push_warning_unsupported_spatial_index_search(enum ha_rkey_function flag);
void clear_cursor();
void clear_cursor_geo();
@@ -592,7 +669,8 @@ private:
void remove_grn_obj_force(const char *name);
int drop_index(MRN_SHARE *target_share, uint key_index);
int drop_indexes_normal(const char *table_name, grn_obj *table);
- int drop_indexes_multiple(const char *table_name, grn_obj *table);
+ int drop_indexes_multiple(const char *table_name, grn_obj *table,
+ const char *index_table_name_separator);
int drop_indexes(const char *table_name);
bool find_column_flags(Field *field, MRN_SHARE *mrn_share, int i,
grn_obj_flags *column_flags);
@@ -600,9 +678,10 @@ private:
int error_code);
grn_obj *find_tokenizer(KEY *key, MRN_SHARE *mrn_share, int i);
grn_obj *find_tokenizer(const char *name, int name_length);
+ bool have_custom_normalizer(KEY *key) const;
grn_obj *find_normalizer(KEY *key);
grn_obj *find_normalizer(KEY *key, const char *name);
- bool find_index_column_flags(KEY *key, grn_obj_flags *index_column_flags);
+ bool find_index_column_flags(KEY *key, grn_column_flags *index_column_flags);
bool find_token_filters(KEY *key, grn_obj *token_filters);
bool find_token_filters_put(grn_obj *token_filters,
const char *token_filter_name,
@@ -622,9 +701,7 @@ private:
bool is_dry_write();
bool is_enable_optimization();
bool should_normalize(Field *field) const;
- bool is_temporary_table_name(const char *name) const;
- void check_count_skip(key_part_map start_key_part_map,
- key_part_map end_key_part_map, bool fulltext);
+ void check_count_skip(key_part_map target_key_part_map);
bool is_grn_zero_column_value(grn_obj *column, grn_obj *value);
bool is_primary_key_field(Field *field) const;
void check_fast_order_limit(grn_table_sort_key **sort_keys, int *n_sort_keys,
@@ -652,6 +729,9 @@ private:
int generic_store_bulk_new_decimal(Field *field, grn_obj *buf);
int generic_store_bulk_blob(Field *field, grn_obj *buf);
int generic_store_bulk_geometry(Field *field, grn_obj *buf);
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+ int generic_store_bulk_json(Field *field, grn_obj *buf);
+#endif
int generic_store_bulk(Field *field, grn_obj *buf);
void storage_store_field_string(Field *field,
@@ -687,6 +767,10 @@ private:
const char *value, uint value_length);
void storage_store_field_geometry(Field *field,
const char *value, uint value_length);
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+ void storage_store_field_json(Field *field,
+ const char *value, uint value_length);
+#endif
void storage_store_field(Field *field, const char *value, uint value_length);
void storage_store_field_column(Field *field, bool is_primary_key,
int nth_column, grn_id record_id);
@@ -732,6 +816,15 @@ private:
const uchar *key, uint key_length,
uchar *buffer, uint *encoded_length);
int storage_encode_multiple_column_key_range(KEY *key_info,
+ const uchar *start,
+ uint start_size,
+ const uchar *end,
+ uint end_size,
+ uchar *min_buffer,
+ uint *min_encoded_size,
+ uchar *max_buffer,
+ uint *max_encoded_size);
+ int storage_encode_multiple_column_key_range(KEY *key_info,
const key_range *start,
const key_range *end,
uchar *min_buffer,
@@ -758,9 +851,7 @@ private:
grn_obj **index_tables,
grn_obj **index_columns,
MRN_SHARE *tmp_share);
- int wrapper_create_index(const char *name, TABLE *table,
- HA_CREATE_INFO *info, MRN_SHARE *tmp_share,
- const char *grn_table_name);
+ int wrapper_create_index(const char *name, TABLE *table, MRN_SHARE *tmp_share);
int storage_create_validate_pseudo_column(TABLE *table);
#ifdef MRN_SUPPORT_FOREIGN_KEYS
bool storage_create_foreign_key(TABLE *table, const char *grn_table_name,
@@ -778,16 +869,18 @@ private:
int storage_create_indexes(TABLE *table, const char *grn_table_name,
grn_obj *grn_table, MRN_SHARE *tmp_share);
int close_databases();
- int ensure_database_open(const char *name);
+ int ensure_database_open(const char *name, mrn::Database **db=NULL);
int ensure_database_remove(const char *name);
int wrapper_delete_table(const char *name, handlerton *wrap_handlerton,
const char *table_name);
int generic_delete_table(const char *name, const char *table_name);
- int wrapper_open(const char *name, int mode, uint test_if_locked);
+ int wrapper_open(const char *name, int mode, uint open_options);
int wrapper_open_indexes(const char *name);
- int storage_open(const char *name, int mode, uint test_if_locked);
+ int storage_reindex();
+ int storage_open(const char *name, int mode, uint open_options);
int open_table(const char *name);
int storage_open_columns(void);
+ void storage_close_columns(void);
int storage_open_indexes(const char *name);
void wrapper_overwrite_index_bits();
int wrapper_close();
@@ -875,6 +968,13 @@ private:
void storage_info_variable();
void storage_info_variable_records();
void storage_info_variable_data_file_length();
+#ifdef MRN_HANDLER_RECORDS_RETURN_ERROR
+ int wrapper_records(ha_rows *num_rows);
+ int storage_records(ha_rows *num_rows);
+#else
+ ha_rows wrapper_records();
+ ha_rows storage_records();
+#endif
int wrapper_rnd_init(bool scan);
int storage_rnd_init(bool scan);
int wrapper_rnd_end();
@@ -917,14 +1017,6 @@ private:
int storage_index_last(uchar *buf);
int wrapper_index_next_same(uchar *buf, const uchar *key, uint keylen);
int storage_index_next_same(uchar *buf, const uchar *key, uint keylen);
- int wrapper_read_range_first(const key_range *start_key,
- const key_range *end_key,
- bool eq_range, bool sorted);
- int storage_read_range_first(const key_range *start_key,
- const key_range *end_key,
- bool eq_range, bool sorted);
- int wrapper_read_range_next();
- int storage_read_range_next();
int generic_ft_init();
int wrapper_ft_init();
int storage_ft_init();
@@ -932,41 +1024,18 @@ private:
FT_INFO *storage_ft_init_ext(uint flags, uint key_nr, String *key);
void generic_ft_init_ext_add_conditions_fast_order_limit(
struct st_mrn_ft_info *info, grn_obj *expression);
- bool generic_ft_init_ext_parse_pragma_d(struct st_mrn_ft_info *info,
- const char *keyword,
- uint keyword_length,
- grn_operator *default_operator,
- uint *consumed_keyword_length);
- void generic_ft_init_ext_parse_pragma_w_append_section(
- struct st_mrn_ft_info *info,
- grn_obj *index_column,
- grn_obj *match_columns,
- uint section,
- grn_obj *section_value_buffer,
- int weight,
- uint n_weights);
- bool generic_ft_init_ext_parse_pragma_w(struct st_mrn_ft_info *info,
- const char *keyword,
- uint keyword_length,
- grn_obj *index_column,
- grn_obj *match_columns,
- uint *consumed_keyword_length,
- grn_obj *tmp_objects);
- grn_expr_flags expr_flags_in_boolean_mode();
grn_rc generic_ft_init_ext_prepare_expression_in_boolean_mode(
struct st_mrn_ft_info *info,
String *key,
grn_obj *index_column,
grn_obj *match_columns,
- grn_obj *expression,
- grn_obj *tmp_objects);
+ grn_obj *expression);
grn_rc generic_ft_init_ext_prepare_expression_in_normal_mode(
struct st_mrn_ft_info *info,
String *key,
grn_obj *index_column,
grn_obj *match_columns,
- grn_obj *expression,
- grn_obj *tmp_objects);
+ grn_obj *expression);
struct st_mrn_ft_info *generic_ft_init_ext_select(uint flags,
uint key_nr,
String *key);
@@ -1044,8 +1113,10 @@ private:
double storage_scan_time();
double wrapper_read_time(uint index, uint ranges, ha_rows rows);
double storage_read_time(uint index, uint ranges, ha_rows rows);
+#ifdef MRN_HANDLER_HAVE_KEYS_TO_USE_FOR_SCANNING
const key_map *wrapper_keys_to_use_for_scanning();
const key_map *storage_keys_to_use_for_scanning();
+#endif
ha_rows wrapper_estimate_rows_upper_bound();
ha_rows storage_estimate_rows_upper_bound();
void wrapper_update_create_info(HA_CREATE_INFO* create_info);
@@ -1072,8 +1143,10 @@ private:
bool wrapper_auto_repair(int error) const;
bool storage_auto_repair(int error) const;
int generic_disable_index(int i, KEY *key_info);
+ int wrapper_disable_indexes_mroonga(uint mode);
int wrapper_disable_indexes(uint mode);
int storage_disable_indexes(uint mode);
+ int wrapper_enable_indexes_mroonga(uint mode);
int wrapper_enable_indexes(uint mode);
int storage_enable_indexes(uint mode);
int wrapper_check(THD* thd, HA_CHECK_OPT* check_opt);
@@ -1114,8 +1187,10 @@ private:
Alter_inplace_info *ha_alter_info);
bool wrapper_inplace_alter_table(TABLE *altered_table,
Alter_inplace_info *ha_alter_info);
- bool storage_inplace_alter_table_index(TABLE *altered_table,
- Alter_inplace_info *ha_alter_info);
+ bool storage_inplace_alter_table_add_index(TABLE *altered_table,
+ Alter_inplace_info *ha_alter_info);
+ bool storage_inplace_alter_table_drop_index(TABLE *altered_table,
+ Alter_inplace_info *ha_alter_info);
bool storage_inplace_alter_table_add_column(TABLE *altered_table,
Alter_inplace_info *ha_alter_info);
bool storage_inplace_alter_table_drop_column(TABLE *altered_table,
@@ -1211,7 +1286,9 @@ private:
void storage_free_foreign_key_create_info(char* str);
void wrapper_set_keys_in_use();
void storage_set_keys_in_use();
+#ifdef MRN_RBR_UPDATE_NEED_ALL_COLUMNS
bool check_written_by_row_based_binlog();
+#endif
#ifdef MRN_HAVE_HA_REBIND_PSI
void wrapper_unbind_psi();
void storage_unbind_psi();
diff --git a/storage/mroonga/lib/libmrn_need_mysql_sources.am b/storage/mroonga/lib/libmrn_need_mysql_sources.am
index 575f38adbd1..e8c03c63a92 100644
--- a/storage/mroonga/lib/libmrn_need_mysql_sources.am
+++ b/storage/mroonga/lib/libmrn_need_mysql_sources.am
@@ -28,4 +28,23 @@ libmrn_need_mysql_la_SOURCES = \
mrn_value_decoder.cpp \
mrn_value_decoder.hpp \
mrn_database_repairer.cpp \
- mrn_database_repairer.hpp
+ mrn_database_repairer.hpp \
+ mrn_context_pool.cpp \
+ mrn_context_pool.hpp \
+ mrn_operations.cpp \
+ mrn_operations.hpp \
+ mrn_operation.cpp \
+ mrn_operation.hpp \
+ mrn_database.cpp \
+ mrn_database.hpp \
+ mrn_column_name.cpp \
+ mrn_column_name.hpp \
+ mrn_count_skip_checker.cpp \
+ mrn_count_skip_checker.hpp \
+ mrn_query_parser.cpp \
+ mrn_query_parser.hpp \
+ mrn_current_thread.hpp \
+ mrn_smart_bitmap.cpp \
+ mrn_smart_bitmap.hpp \
+ mrn_table_fields_offset_mover.cpp \
+ mrn_table_fields_offset_mover.hpp
diff --git a/storage/mroonga/lib/mrn_column_name.cpp b/storage/mroonga/lib/mrn_column_name.cpp
new file mode 100644
index 00000000000..e2e8f6d8f63
--- /dev/null
+++ b/storage/mroonga/lib/mrn_column_name.cpp
@@ -0,0 +1,69 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <mrn_mysql.h>
+#include <mrn_mysql_compat.h>
+
+#include "mrn_column_name.hpp"
+
+#include <strfunc.h>
+
+#include <string.h>
+
+// for debug
+#define MRN_CLASS_NAME "mrn::ColumnName"
+
+namespace mrn {
+ ColumnName::ColumnName(const char *mysql_name)
+ : mysql_name_(mysql_name) {
+ encode(mysql_name, strlen(mysql_name));
+ }
+
+ ColumnName::ColumnName(const LEX_CSTRING &mysql_name)
+ : mysql_name_(mysql_name.str) {
+ encode(mysql_name.str, mysql_name.length);
+ }
+
+ const char *ColumnName::mysql_name() {
+ return mysql_name_;
+ }
+
+ const char *ColumnName::c_str() {
+ return name_;
+ }
+
+ size_t ColumnName::length() {
+ return length_;
+ }
+
+ void ColumnName::encode(const char *mysql_name,
+ size_t mysql_name_length) {
+ MRN_DBUG_ENTER_METHOD();
+ uint errors;
+ length_ = mrn_strconvert(system_charset_info,
+ mysql_name,
+ mysql_name_length,
+ &my_charset_filename,
+ name_,
+ MRN_MAX_PATH_SIZE,
+ &errors);
+ name_[length_] = '\0';
+ DBUG_VOID_RETURN;
+ }
+}
diff --git a/storage/mroonga/lib/mrn_column_name.hpp b/storage/mroonga/lib/mrn_column_name.hpp
new file mode 100644
index 00000000000..e68e0182f5e
--- /dev/null
+++ b/storage/mroonga/lib/mrn_column_name.hpp
@@ -0,0 +1,39 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include <mrn_constants.hpp>
+
+namespace mrn {
+ class ColumnName {
+ public:
+ ColumnName(const char *mysql_name);
+ ColumnName(const LEX_CSTRING &mysql_name);
+ const char *mysql_name();
+ const char *c_str();
+ size_t length();
+ private:
+ const char *mysql_name_;
+ char name_[MRN_MAX_PATH_SIZE];
+ size_t length_;
+
+ void encode(const char *mysql_name, size_t mysql_name_length);
+ };
+}
diff --git a/storage/mroonga/lib/mrn_condition_converter.cpp b/storage/mroonga/lib/mrn_condition_converter.cpp
index d1f0fe21615..579292a7f89 100644
--- a/storage/mroonga/lib/mrn_condition_converter.cpp
+++ b/storage/mroonga/lib/mrn_condition_converter.cpp
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2014 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2013-2017 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -175,7 +175,7 @@ namespace mrn {
bool convertable = false;
- enum_field_types field_type = field_item->field_type();
+ enum_field_types field_type = field_item->field->real_type();
NormalizedType normalized_type = normalize_field_type(field_type);
switch (normalized_type) {
case STRING_TYPE:
@@ -185,7 +185,12 @@ namespace mrn {
}
break;
case INT_TYPE:
- convertable = value_item->type() == Item::INT_ITEM;
+ if (field_type == MYSQL_TYPE_ENUM) {
+ convertable = (value_item->type() == Item::STRING_ITEM ||
+ value_item->type() == Item::INT_ITEM);
+ } else {
+ convertable = value_item->type() == Item::INT_ITEM;
+ }
break;
case TIME_TYPE:
if (is_valid_time_value(field_item, value_item)) {
@@ -206,7 +211,7 @@ namespace mrn {
bool convertable = false;
- enum_field_types field_type = field_item->field_type();
+ enum_field_types field_type = field_item->field->type();
NormalizedType normalized_type = normalize_field_type(field_type);
switch (normalized_type) {
case STRING_TYPE:
@@ -251,7 +256,7 @@ namespace mrn {
bool error;
Item *real_value_item = value_item->real_item();
- switch (field_item->field_type()) {
+ switch (field_item->field->type()) {
case MYSQL_TYPE_TIME:
error = real_value_item->get_time(mysql_time);
break;
@@ -355,6 +360,11 @@ namespace mrn {
case MYSQL_TYPE_VARCHAR_COMPRESSED:
case MYSQL_TYPE_BLOB_COMPRESSED:
DBUG_ASSERT(0);
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+ case MYSQL_TYPE_JSON:
+ type = STRING_TYPE;
+ break;
+#endif
}
DBUG_RETURN(type);
@@ -407,11 +417,11 @@ namespace mrn {
DBUG_RETURN(have);
}
- const Item_func *ConditionConverter::find_match_against(const Item *item) {
+ unsigned int ConditionConverter::count_match_against(const Item *item) {
MRN_DBUG_ENTER_METHOD();
if (!item) {
- DBUG_RETURN(NULL);
+ DBUG_RETURN(0);
}
switch (item->type()) {
@@ -419,14 +429,13 @@ namespace mrn {
if (is_storage_mode_) {
Item_cond *cond_item = (Item_cond *)item;
if (cond_item->functype() == Item_func::COND_AND_FUNC) {
+ unsigned int n_match_againsts = 0;
List_iterator<Item> iterator(*((cond_item)->argument_list()));
const Item *sub_item;
while ((sub_item = iterator++)) {
- const Item_func *match_against = find_match_against(sub_item);
- if (match_against) {
- DBUG_RETURN(match_against);
- }
+ n_match_againsts += count_match_against(sub_item);
}
+ DBUG_RETURN(n_match_againsts);
}
}
break;
@@ -435,7 +444,7 @@ namespace mrn {
const Item_func *func_item = (const Item_func *)item;
switch (func_item->functype()) {
case Item_func::FT_FUNC:
- DBUG_RETURN(func_item);
+ DBUG_RETURN(1);
break;
default:
break;
@@ -446,7 +455,7 @@ namespace mrn {
break;
}
- DBUG_RETURN(NULL);
+ DBUG_RETURN(0);
}
void ConditionConverter::convert(const Item *where, grn_obj *expression) {
@@ -563,7 +572,7 @@ namespace mrn {
grn_obj *expression) {
MRN_DBUG_ENTER_METHOD();
- enum_field_types field_type = field_item->field_type();
+ enum_field_types field_type = field_item->field->real_type();
NormalizedType normalized_type = normalize_field_type(field_type);
switch (normalized_type) {
@@ -577,7 +586,21 @@ namespace mrn {
break;
case INT_TYPE:
grn_obj_reinit(ctx_, &value_, GRN_DB_INT64, 0);
- GRN_INT64_SET(ctx_, &value_, const_item->val_int());
+ if (field_type == MYSQL_TYPE_ENUM) {
+ if (const_item->type() == Item::STRING_ITEM) {
+ String *string;
+ string = const_item->val_str(NULL);
+ Field_enum *enum_field = static_cast<Field_enum *>(field_item->field);
+ int enum_value = find_type(string->c_ptr(),
+ enum_field->typelib,
+ FIND_TYPE_BASIC);
+ GRN_INT64_SET(ctx_, &value_, enum_value);
+ } else {
+ GRN_INT64_SET(ctx_, &value_, const_item->val_int());
+ }
+ } else {
+ GRN_INT64_SET(ctx_, &value_, const_item->val_int());
+ }
break;
case TIME_TYPE:
grn_obj_reinit(ctx_, &value_, GRN_DB_TIME, 0);
diff --git a/storage/mroonga/lib/mrn_condition_converter.hpp b/storage/mroonga/lib/mrn_condition_converter.hpp
index 3a7fbd048dc..f8a48b6209a 100644
--- a/storage/mroonga/lib/mrn_condition_converter.hpp
+++ b/storage/mroonga/lib/mrn_condition_converter.hpp
@@ -33,7 +33,7 @@ namespace mrn {
~ConditionConverter();
bool is_convertable(const Item *item);
- const Item_func *find_match_against(const Item *item);
+ unsigned int count_match_against(const Item *item);
// caller must check "where" can be convertable by
// is_convertable(). This method doesn't validate "where".
void convert(const Item *where, grn_obj *expression);
diff --git a/storage/mroonga/lib/mrn_context_pool.cpp b/storage/mroonga/lib/mrn_context_pool.cpp
new file mode 100644
index 00000000000..a6000df29e3
--- /dev/null
+++ b/storage/mroonga/lib/mrn_context_pool.cpp
@@ -0,0 +1,120 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "mrn_context_pool.hpp"
+#include "mrn_lock.hpp"
+
+#include <time.h>
+
+namespace mrn {
+ // for debug
+#define MRN_CLASS_NAME "mrn::ContextPool::Impl"
+
+ class ContextPool::Impl {
+ public:
+ Impl(mysql_mutex_t *mutex)
+ : mutex_(mutex),
+ pool_(NULL),
+ last_pull_time_(0) {
+ }
+
+ ~Impl(void) {
+ clear();
+ }
+
+ grn_ctx *pull(void) {
+ MRN_DBUG_ENTER_METHOD();
+ grn_ctx *ctx = NULL;
+
+ {
+ time_t now;
+ time(&now);
+
+ mrn::Lock lock(mutex_);
+ if (pool_) {
+ ctx = static_cast<grn_ctx *>(pool_->data);
+ list_pop(pool_);
+ if ((uint) (now - last_pull_time_) >= CLEAR_THREATHOLD_IN_SECONDS) {
+ clear();
+ }
+ }
+ last_pull_time_ = now;
+ }
+
+ if (!ctx) {
+ ctx = grn_ctx_open(0);
+ }
+
+ DBUG_RETURN(ctx);
+ }
+
+ void release(grn_ctx *ctx) {
+ MRN_DBUG_ENTER_METHOD();
+
+ {
+ mrn::Lock lock(mutex_);
+ list_push(pool_, ctx);
+ grn_ctx_use(ctx, NULL);
+ }
+
+ DBUG_VOID_RETURN;
+ }
+
+ private:
+ static const unsigned int CLEAR_THREATHOLD_IN_SECONDS = 60 * 5;
+
+ mysql_mutex_t *mutex_;
+ LIST *pool_;
+ time_t last_pull_time_;
+
+ void clear(void) {
+ MRN_DBUG_ENTER_METHOD();
+ while (pool_) {
+ grn_ctx *ctx = static_cast<grn_ctx *>(pool_->data);
+ grn_ctx_close(ctx);
+ list_pop(pool_);
+ }
+ DBUG_VOID_RETURN;
+ }
+ };
+
+ // For debug
+#undef MRN_CLASS_NAME
+#define MRN_CLASS_NAME "mrn::ContextPool"
+
+ ContextPool::ContextPool(mysql_mutex_t *mutex)
+ : impl_(new Impl(mutex)) {
+ }
+
+ ContextPool::~ContextPool(void) {
+ delete impl_;
+ }
+
+ grn_ctx *ContextPool::pull(void) {
+ MRN_DBUG_ENTER_METHOD();
+ grn_ctx *ctx = impl_->pull();
+ DBUG_RETURN(ctx);
+ }
+
+ void ContextPool::release(grn_ctx *ctx) {
+ MRN_DBUG_ENTER_METHOD();
+ impl_->release(ctx);
+ DBUG_VOID_RETURN;
+ }
+}
diff --git a/storage/mroonga/lib/mrn_context_pool.hpp b/storage/mroonga/lib/mrn_context_pool.hpp
new file mode 100644
index 00000000000..4c64933ac81
--- /dev/null
+++ b/storage/mroonga/lib/mrn_context_pool.hpp
@@ -0,0 +1,41 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef MRN_CONTEXT_POOL_HPP_
+#define MRN_CONTEXT_POOL_HPP_
+
+#include <mrn_mysql.h>
+
+#include <groonga.h>
+
+namespace mrn {
+ class ContextPool {
+ public:
+ ContextPool(mysql_mutex_t *mutex);
+ ~ContextPool(void);
+ grn_ctx *pull(void);
+ void release(grn_ctx *context);
+
+ private:
+ class Impl;
+ Impl *impl_;
+ };
+}
+
+#endif /* MRN_CONTEXT_POOL_HPP_ */
diff --git a/storage/mroonga/lib/mrn_count_skip_checker.cpp b/storage/mroonga/lib/mrn_count_skip_checker.cpp
new file mode 100644
index 00000000000..07852d9dda6
--- /dev/null
+++ b/storage/mroonga/lib/mrn_count_skip_checker.cpp
@@ -0,0 +1,303 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2010-2013 Kentoku SHIBA
+ Copyright(C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "mrn_count_skip_checker.hpp"
+
+#include <item_sum.h>
+
+// for debug
+#define MRN_CLASS_NAME "mrn::CountSkipChecker"
+
+namespace mrn {
+ CountSkipChecker::CountSkipChecker(grn_ctx *ctx,
+ TABLE *table,
+ SELECT_LEX *select_lex,
+ KEY *key_info,
+ key_part_map target_key_part_map,
+ bool is_storage_mode)
+ : ctx_(ctx),
+ table_(table),
+ select_lex_(select_lex),
+ key_info_(key_info),
+ target_key_part_map_(target_key_part_map),
+ is_storage_mode_(is_storage_mode) {
+ }
+
+ CountSkipChecker::~CountSkipChecker() {
+ }
+
+ bool CountSkipChecker::check() {
+ MRN_DBUG_ENTER_METHOD();
+
+ if (select_lex_->item_list.elements != 1) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] not only one item: %u",
+ select_lex_->item_list.elements);
+ DBUG_RETURN(false);
+ }
+ if (select_lex_->group_list.elements > 0) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] have groups: %u",
+ select_lex_->group_list.elements);
+ DBUG_RETURN(false);
+ }
+ if (MRN_SELECT_LEX_GET_HAVING_COND(select_lex_)) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] have HAVING");
+ DBUG_RETURN(false);
+ }
+ if (select_lex_->table_list.elements != 1) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] not only one table: %u",
+ select_lex_->table_list.elements);
+ DBUG_RETURN(false);
+ }
+
+ Item *info = static_cast<Item *>(select_lex_->item_list.first_node()->info);
+ if (info->type() != Item::SUM_FUNC_ITEM) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] item isn't sum function: %u",
+ info->type());
+ DBUG_RETURN(false);
+ }
+ Item_sum *sum_item = static_cast<Item_sum *>(info);
+ if (sum_item->sum_func() != Item_sum::COUNT_FUNC) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] not COUNT: %u",
+ sum_item->sum_func());
+ DBUG_RETURN(false);
+ }
+ if (ITEM_SUM_GET_NEST_LEVEL(sum_item) != 0 ||
+ ITEM_SUM_GET_AGGR_LEVEL(sum_item) != 0 ||
+ ITEM_SUM_GET_MAX_AGGR_LEVEL(sum_item) != -1 ||
+ sum_item->max_sum_func_level != -1) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] not simple COUNT(*): %d:%d:%d:%d",
+ ITEM_SUM_GET_NEST_LEVEL(sum_item),
+ ITEM_SUM_GET_AGGR_LEVEL(sum_item),
+ ITEM_SUM_GET_MAX_AGGR_LEVEL(sum_item),
+ sum_item->max_sum_func_level);
+ DBUG_RETURN(false);
+ }
+
+ Item *where = MRN_SELECT_LEX_GET_WHERE_COND(select_lex_);
+ if (!where) {
+ if (is_storage_mode_) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][true] no condition");
+ DBUG_RETURN(true);
+ } else {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] no condition with wrapper mode");
+ DBUG_RETURN(false);
+ }
+ }
+
+ bool skippable = is_skippable(where);
+ DBUG_RETURN(skippable);
+ }
+
+ bool CountSkipChecker::is_skippable(Item *where) {
+ MRN_DBUG_ENTER_METHOD();
+
+ bool skippable = false;
+ switch (where->type()) {
+ case Item::COND_ITEM:
+ {
+ Item_cond *cond_item = static_cast<Item_cond *>(where);
+ skippable = is_skippable(cond_item);
+ if (skippable) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][true] skippable multiple conditions");
+ }
+ }
+ break;
+ case Item::FUNC_ITEM:
+ {
+ Item_func *func_item = static_cast<Item_func *>(where);
+ if (func_item->functype() == Item_func::FT_FUNC) {
+ if (select_lex_->select_n_where_fields == 1) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][true] "
+ "only one full text search condition");
+ DBUG_RETURN(true);
+ } else {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] "
+ "full text search condition and more conditions: %u",
+ select_lex_->select_n_where_fields);
+ DBUG_RETURN(false);
+ }
+ } else {
+ skippable = is_skippable(func_item);
+ if (skippable) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][true] skippable condition");
+ }
+ }
+ }
+ break;
+ default:
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] unsupported top level item: %u",
+ where->type());
+ break;
+ }
+
+ DBUG_RETURN(skippable);
+ }
+
+ bool CountSkipChecker::is_skippable(Item_cond *cond_item) {
+ MRN_DBUG_ENTER_METHOD();
+
+ List_iterator<Item> iterator(*(cond_item->argument_list()));
+ Item *sub_item;
+ while ((sub_item = iterator++)) {
+ if (sub_item->type() != Item::FUNC_ITEM) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] "
+ "sub condition isn't function item: %u",
+ sub_item->type());
+ DBUG_RETURN(false);
+ }
+ if (!is_skippable(static_cast<Item_func *>(sub_item))) {
+ DBUG_RETURN(false);
+ }
+ }
+ DBUG_RETURN(true);
+ }
+
+ bool CountSkipChecker::is_skippable(Item_func *func_item) {
+ MRN_DBUG_ENTER_METHOD();
+
+ switch (func_item->functype()) {
+ case Item_func::EQ_FUNC:
+ case Item_func::EQUAL_FUNC:
+ case Item_func::NE_FUNC:
+ case Item_func::LT_FUNC:
+ case Item_func::LE_FUNC:
+ case Item_func::GE_FUNC:
+ case Item_func::GT_FUNC:
+ {
+ Item **arguments = func_item->arguments();
+ Item *left_item = arguments[0];
+ if (left_item->type() != Item::FIELD_ITEM) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] not field: %u:%u",
+ func_item->functype(),
+ left_item->type());
+ DBUG_RETURN(false);
+ }
+
+ bool skippable = is_skippable(static_cast<Item_field *>(left_item));
+ DBUG_RETURN(skippable);
+ }
+ break;
+ case Item_func::BETWEEN:
+ {
+ Item **arguments = func_item->arguments();
+ Item *target_item = arguments[0];
+ if (target_item->type() != Item::FIELD_ITEM) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] BETWEEN target isn't field: %u",
+ target_item->type());
+ DBUG_RETURN(false);
+ }
+
+ bool skippable = is_skippable(static_cast<Item_field *>(target_item));
+ DBUG_RETURN(skippable);
+ }
+ break;
+ case Item_func::MULT_EQUAL_FUNC:
+#ifdef MRN_HAVE_ITEM_EQUAL_FIELDS_ITERATOR
+ {
+ Item_equal *equal_item = static_cast<Item_equal *>(func_item);
+ Item_equal_fields_iterator iterator(*equal_item);
+ Item *field_item;
+ while ((field_item = iterator++)) {
+ bool skippable = is_skippable(static_cast<Item_field *>(field_item));
+ if (!skippable) {
+ DBUG_RETURN(skippable);
+ }
+ }
+ DBUG_RETURN(true);
+ }
+#endif
+ break;
+ default:
+ break;
+ }
+
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] unsupported function item: %u",
+ func_item->functype());
+ DBUG_RETURN(false);
+ }
+
+ bool CountSkipChecker::is_skippable(Item_field *field_item) {
+ MRN_DBUG_ENTER_METHOD();
+
+ Field *field = field_item->field;
+ if (!field) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] field is missing");
+ DBUG_RETURN(false);
+ }
+
+ if (field->table != table_) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] external table's field");
+ DBUG_RETURN(false);
+ }
+
+ if (!key_info_) {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] no active index: <%s>:<%s>",
+ *(field->table_name),
+ field->field_name.str);
+ DBUG_RETURN(false);
+ }
+
+ uint i;
+ KEY_PART_INFO *key_part = key_info_->key_part;
+ for (i = 0; i < KEY_N_KEY_PARTS(key_info_); i++) {
+ if (key_part[i].field == field) {
+ if ((target_key_part_map_ >> i) & 1) {
+ DBUG_RETURN(true);
+ } else {
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] "
+ "field's index are out of key part map: %u:%lu: <%s>:<%s>",
+ i,
+ target_key_part_map_,
+ *(field->table_name),
+ field->field_name.str);
+ DBUG_RETURN(false);
+ }
+ }
+ }
+
+ GRN_LOG(ctx_, GRN_LOG_DEBUG,
+ "[mroonga][count-skip][false] field isn't indexed: <%s>:<%s>",
+ *(field->table_name),
+ field->field_name.str);
+ DBUG_RETURN(false);
+ }
+}
diff --git a/storage/mroonga/lib/mrn_count_skip_checker.hpp b/storage/mroonga/lib/mrn_count_skip_checker.hpp
new file mode 100644
index 00000000000..b813ecdcc08
--- /dev/null
+++ b/storage/mroonga/lib/mrn_count_skip_checker.hpp
@@ -0,0 +1,57 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef MRN_COUNT_SKIP_CHECKER_HPP_
+#define MRN_COUNT_SKIP_CHECKER_HPP_
+
+#include <mrn_mysql_compat.h>
+
+#include <item_cmpfunc.h>
+
+#include <groonga.h>
+
+namespace mrn {
+ class CountSkipChecker {
+ public:
+ CountSkipChecker(grn_ctx *ctx,
+ TABLE *table,
+ SELECT_LEX *select_lex,
+ KEY *key_info,
+ key_part_map target_key_part_map,
+ bool is_storage_mode);
+ ~CountSkipChecker();
+
+ bool check();
+
+ private:
+ grn_ctx *ctx_;
+ TABLE *table_;
+ SELECT_LEX *select_lex_;
+ KEY *key_info_;
+ key_part_map target_key_part_map_;
+ bool is_storage_mode_;
+
+ bool is_skippable(Item *where);
+ bool is_skippable(Item_cond *cond_item);
+ bool is_skippable(Item_func *func_item);
+ bool is_skippable(Item_field *field_item);
+ };
+}
+
+#endif /* MRN_COUNT_SKIP_CHECKER_HPP_ */
diff --git a/storage/mroonga/lib/mrn_current_thread.hpp b/storage/mroonga/lib/mrn_current_thread.hpp
new file mode 100644
index 00000000000..367057fce66
--- /dev/null
+++ b/storage/mroonga/lib/mrn_current_thread.hpp
@@ -0,0 +1,27 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include <mrn_mysql.h>
+#include <mrn_mysql_compat.h>
+
+#if (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 80002)
+# include <current_thd.h>
+#endif
diff --git a/storage/mroonga/lib/mrn_database.cpp b/storage/mroonga/lib/mrn_database.cpp
new file mode 100644
index 00000000000..52e315e1b77
--- /dev/null
+++ b/storage/mroonga/lib/mrn_database.cpp
@@ -0,0 +1,89 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <mrn_mysql.h>
+
+#include "mrn_database.hpp"
+#include "mrn_operations.hpp"
+
+// for debug
+#define MRN_CLASS_NAME "mrn::Database"
+
+namespace mrn {
+ Database::Database(grn_ctx *ctx, grn_obj *db)
+ : ctx_(ctx),
+ db_(db),
+ broken_table_names_(NULL),
+ is_broken_(false) {
+ Operations operations(ctx_);
+ broken_table_names_ = operations.collect_processing_table_names();
+ is_broken_ = operations.is_locked();
+ }
+
+ Database::~Database(void) {
+ close();
+ }
+
+ void Database::close() {
+ MRN_DBUG_ENTER_METHOD();
+ if (db_) {
+ grn_hash_close(ctx_, broken_table_names_);
+ broken_table_names_ = NULL;
+ grn_obj_close(ctx_, db_);
+ db_ = NULL;
+ }
+ DBUG_VOID_RETURN;
+ }
+
+ grn_rc Database::remove() {
+ MRN_DBUG_ENTER_METHOD();
+ grn_rc rc = GRN_SUCCESS;
+ if (db_) {
+ grn_hash_close(ctx_, broken_table_names_);
+ broken_table_names_ = NULL;
+ rc = grn_obj_remove(ctx_, db_);
+ if (rc == GRN_SUCCESS) {
+ db_ = NULL;
+ }
+ }
+ DBUG_RETURN(rc);
+ }
+
+ grn_obj *Database::get() {
+ MRN_DBUG_ENTER_METHOD();
+ DBUG_RETURN(db_);
+ }
+
+ bool Database::is_broken() {
+ MRN_DBUG_ENTER_METHOD();
+ DBUG_RETURN(is_broken_);
+ }
+
+ bool Database::is_broken_table(const char *name, size_t name_size) {
+ MRN_DBUG_ENTER_METHOD();
+ grn_id id = grn_hash_get(ctx_, broken_table_names_, name, name_size, NULL);
+ DBUG_RETURN(id != GRN_ID_NIL);
+ }
+
+ void Database::mark_table_repaired(const char *name, size_t name_size) {
+ MRN_DBUG_ENTER_METHOD();
+ grn_hash_delete(ctx_, broken_table_names_, name, name_size, NULL);
+ DBUG_VOID_RETURN;
+ }
+}
diff --git a/storage/mroonga/lib/mrn_database.hpp b/storage/mroonga/lib/mrn_database.hpp
new file mode 100644
index 00000000000..c2c7e460b58
--- /dev/null
+++ b/storage/mroonga/lib/mrn_database.hpp
@@ -0,0 +1,47 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef MRN_DATABASE_HPP_
+#define MRN_DATABASE_HPP_
+
+#include <groonga.h>
+
+namespace mrn {
+ class Database {
+ public:
+ Database(grn_ctx *ctx, grn_obj *db);
+ ~Database(void);
+
+ void close();
+ grn_rc remove();
+ grn_obj *get();
+
+ bool is_broken();
+ bool is_broken_table(const char *name, size_t name_size);
+ void mark_table_repaired(const char *name, size_t name_size);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *db_;
+ grn_hash *broken_table_names_;
+ bool is_broken_;
+ };
+}
+
+#endif /* MRN_DATABASE_HPP_ */
diff --git a/storage/mroonga/lib/mrn_database_manager.cpp b/storage/mroonga/lib/mrn_database_manager.cpp
index 753d1551ff4..d52d2639d7d 100644
--- a/storage/mroonga/lib/mrn_database_manager.cpp
+++ b/storage/mroonga/lib/mrn_database_manager.cpp
@@ -56,9 +56,9 @@ namespace mrn {
if (cache_) {
void *db_address;
GRN_HASH_EACH(ctx_, cache_, id, NULL, 0, &db_address, {
- grn_obj *db;
+ Database *db;
memcpy(&db, db_address, sizeof(grn_obj *));
- grn_obj_unlink(ctx_, db);
+ delete db;
});
grn_hash_close(ctx_, cache_);
}
@@ -80,7 +80,7 @@ namespace mrn {
DBUG_RETURN(true);
}
- int DatabaseManager::open(const char *path, grn_obj **db) {
+ int DatabaseManager::open(const char *path, Database **db) {
MRN_DBUG_ENTER_METHOD();
int error = 0;
@@ -100,36 +100,54 @@ namespace mrn {
mapper.db_name(), strlen(mapper.db_name()),
&db_address);
if (id == GRN_ID_NIL) {
+ grn_obj *grn_db;
struct stat db_stat;
if (stat(mapper.db_path(), &db_stat)) {
GRN_LOG(ctx_, GRN_LOG_INFO,
"database not found. creating...: <%s>", mapper.db_path());
if (path[0] == FN_CURLIB &&
- (path[1] == FN_LIBCHAR || path[1] == FN_LIBCHAR2)) {
+ mrn_is_directory_separator(path[1])) {
ensure_database_directory();
}
- *db = grn_db_create(ctx_, mapper.db_path(), NULL);
+ grn_db = grn_db_create(ctx_, mapper.db_path(), NULL);
if (ctx_->rc) {
error = ER_CANT_CREATE_TABLE;
my_message(error, ctx_->errbuf, MYF(0));
DBUG_RETURN(error);
}
} else {
- *db = grn_db_open(ctx_, mapper.db_path());
+ grn_db = grn_db_open(ctx_, mapper.db_path());
if (ctx_->rc) {
error = ER_CANT_OPEN_FILE;
my_message(error, ctx_->errbuf, MYF(0));
DBUG_RETURN(error);
}
}
+ *db = new Database(ctx_, grn_db);
grn_hash_add(ctx_, cache_,
mapper.db_name(), strlen(mapper.db_name()),
&db_address, NULL);
- memcpy(db_address, db, sizeof(grn_obj *));
- error = ensure_normalizers_registered(*db);
+ memcpy(db_address, db, sizeof(Database *));
+ error = ensure_normalizers_registered((*db)->get());
+ if (!error) {
+ if ((*db)->is_broken()) {
+ error = ER_CANT_OPEN_FILE;
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: database: open: "
+ "The database maybe broken. "
+ "We recommend you to recreate the database. "
+ "If the database isn't broken, "
+ "you can remove this error by running "
+ "'groonga %s table_remove mroonga_operations' "
+ "on server. But the latter isn't recommended.",
+ mapper.db_path());
+ my_message(error, error_message, MYF(0));
+ }
+ }
} else {
- memcpy(db, db_address, sizeof(grn_obj *));
- grn_ctx_use(ctx_, *db);
+ memcpy(db, db_address, sizeof(Database *));
+ grn_ctx_use(ctx_, (*db)->get());
}
DBUG_RETURN(error);
@@ -150,10 +168,11 @@ namespace mrn {
DBUG_VOID_RETURN;
}
- grn_obj *db = NULL;
- memcpy(&db, db_address, sizeof(grn_obj *));
+ Database *db = NULL;
+ memcpy(&db, db_address, sizeof(Database *));
+ grn_ctx_use(ctx_, db->get());
if (db) {
- grn_obj_close(ctx_, db);
+ delete db;
}
grn_hash_delete_by_id(ctx_, cache_, id, NULL);
@@ -173,29 +192,35 @@ namespace mrn {
mapper.db_name(), strlen(mapper.db_name()),
&db_address);
- grn_obj *db = NULL;
+ Database *db = NULL;
if (id == GRN_ID_NIL) {
struct stat dummy;
if (stat(mapper.db_path(), &dummy) == 0) {
- db = grn_db_open(ctx_, mapper.db_path());
+ grn_obj *grn_db = grn_db_open(ctx_, mapper.db_path());
+ db = new Database(ctx_, grn_db);
}
} else {
- memcpy(&db, db_address, sizeof(grn_obj *));
+ memcpy(&db, db_address, sizeof(Database *));
+ grn_ctx_use(ctx_, db->get());
}
if (!db) {
DBUG_RETURN(false);
}
- if (grn_obj_remove(ctx_, db) == GRN_SUCCESS) {
+ if (db->remove() == GRN_SUCCESS) {
if (id != GRN_ID_NIL) {
grn_hash_delete_by_id(ctx_, cache_, id, NULL);
}
+ delete db;
DBUG_RETURN(true);
} else {
GRN_LOG(ctx_, GRN_LOG_ERROR,
"failed to drop database: <%s>: <%s>",
mapper.db_path(), ctx_->errbuf);
+ if (id == GRN_ID_NIL) {
+ delete db;
+ }
DBUG_RETURN(false);
}
}
@@ -223,22 +248,28 @@ namespace mrn {
break;
}
void *db_address;
- grn_obj *db;
+ Database *db;
grn_hash_cursor_get_value(ctx_, cursor, &db_address);
- memcpy(&db, db_address, sizeof(grn_obj *));
+ memcpy(&db, db_address, sizeof(Database *));
+ grn_ctx_use(ctx_, db->get());
grn_rc rc = grn_hash_cursor_delete(ctx_, cursor, NULL);
if (rc) {
error = ER_ERROR_ON_READ;
my_message(error, ctx_->errbuf, MYF(0));
break;
}
- grn_obj_close(ctx_, db);
+ delete db;
}
grn_hash_cursor_close(ctx_, cursor);
DBUG_RETURN(error);
}
+ const char *DatabaseManager::error_message() {
+ MRN_DBUG_ENTER_METHOD();
+ DBUG_RETURN(ctx_->errbuf);
+ }
+
void DatabaseManager::mkdir_p(const char *directory) {
MRN_DBUG_ENTER_METHOD();
@@ -246,8 +277,7 @@ namespace mrn {
char sub_directory[MRN_MAX_PATH_SIZE];
sub_directory[0] = '\0';
while (true) {
- if (directory[i] == FN_LIBCHAR ||
- directory[i] == FN_LIBCHAR2 ||
+ if (mrn_is_directory_separator(directory[i]) ||
directory[i] == '\0') {
sub_directory[i] = '\0';
struct stat directory_status;
@@ -290,8 +320,10 @@ namespace mrn {
const char *last_path_separator;
last_path_separator = strrchr(path_prefix, FN_LIBCHAR);
+#ifdef FN_LIBCHAR2
if (!last_path_separator)
last_path_separator = strrchr(path_prefix, FN_LIBCHAR2);
+#endif
if (!last_path_separator)
DBUG_VOID_RETURN;
if (path_prefix == last_path_separator)
diff --git a/storage/mroonga/lib/mrn_database_manager.hpp b/storage/mroonga/lib/mrn_database_manager.hpp
index 76c76dab6d5..877b7ca889a 100644
--- a/storage/mroonga/lib/mrn_database_manager.hpp
+++ b/storage/mroonga/lib/mrn_database_manager.hpp
@@ -22,6 +22,8 @@
#ifndef MRN_DATABASE_MANAGER_HPP_
#define MRN_DATABASE_MANAGER_HPP_
+#include "mrn_database.hpp"
+
#include <groonga.h>
namespace mrn {
@@ -30,10 +32,11 @@ namespace mrn {
DatabaseManager(grn_ctx *ctx, mysql_mutex_t *mutex);
~DatabaseManager(void);
bool init(void);
- int open(const char *path, grn_obj **db);
+ int open(const char *path, Database **db);
void close(const char *path);
bool drop(const char *path);
int clear(void);
+ const char *error_message();
private:
grn_ctx *ctx_;
diff --git a/storage/mroonga/lib/mrn_database_repairer.cpp b/storage/mroonga/lib/mrn_database_repairer.cpp
index f04c027f8bb..47badbd8b93 100644
--- a/storage/mroonga/lib/mrn_database_repairer.cpp
+++ b/storage/mroonga/lib/mrn_database_repairer.cpp
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -36,6 +36,16 @@
#endif
namespace mrn {
+ struct CheckResult {
+ CheckResult() :
+ is_crashed(false),
+ is_corrupt(false) {
+ }
+
+ bool is_crashed;
+ bool is_corrupt;
+ };
+
DatabaseRepairer::DatabaseRepairer(grn_ctx *ctx, THD *thd)
: ctx_(ctx),
thd_(thd),
@@ -53,10 +63,19 @@ namespace mrn {
bool DatabaseRepairer::is_crashed(void) {
MRN_DBUG_ENTER_METHOD();
- bool is_crashed = false;
- each_database(&DatabaseRepairer::is_crashed_body, &is_crashed);
+ CheckResult result;
+ each_database(&DatabaseRepairer::check_body, &result);
+
+ DBUG_RETURN(result.is_crashed);
+ }
+
+ bool DatabaseRepairer::is_corrupt(void) {
+ MRN_DBUG_ENTER_METHOD();
+
+ CheckResult result;
+ each_database(&DatabaseRepairer::check_body, &result);
- DBUG_RETURN(is_crashed);
+ DBUG_RETURN(result.is_corrupt);
}
bool DatabaseRepairer::repair(void) {
@@ -81,9 +100,19 @@ namespace mrn {
DBUG_VOID_RETURN;
}
- do {
- each_database_body(data.cFileName, each_body_func, user_data);
- } while (FindNextFile(finder, &data) != 0);
+ grn_ctx ctx;
+ grn_rc rc = grn_ctx_init(&ctx, 0);
+ if (rc == GRN_SUCCESS) {
+ do {
+ each_database_body(data.cFileName, &ctx, each_body_func, user_data);
+ } while (FindNextFile(finder, &data) != 0);
+ grn_ctx_fin(&ctx);
+ } else {
+ GRN_LOG(ctx_, GRN_LOG_WARNING,
+ "[mroonga][database][repairer][each] "
+ "failed to initialize grn_ctx: %d: %s",
+ rc, grn_rc_to_string(rc));
+ }
FindClose(finder);
#else
DIR *dir = opendir(base_directory_);
@@ -91,8 +120,18 @@ namespace mrn {
DBUG_VOID_RETURN;
}
- while (struct dirent *entry = readdir(dir)) {
- each_database_body(entry->d_name, each_body_func, user_data);
+ grn_ctx ctx;
+ grn_rc rc = grn_ctx_init(&ctx, 0);
+ if (rc == GRN_SUCCESS) {
+ while (struct dirent *entry = readdir(dir)) {
+ each_database_body(entry->d_name, &ctx, each_body_func, user_data);
+ }
+ grn_ctx_fin(&ctx);
+ } else {
+ GRN_LOG(ctx_, GRN_LOG_WARNING,
+ "[mroonga][database][repairer][each] "
+ "failed to initialize grn_ctx: %d: %s",
+ rc, grn_rc_to_string(rc));
}
closedir(dir);
#endif
@@ -101,6 +140,7 @@ namespace mrn {
}
void DatabaseRepairer::each_database_body(const char *base_path,
+ grn_ctx *ctx,
EachBodyFunc each_body_func,
void *user_data) {
MRN_DBUG_ENTER_METHOD();
@@ -123,14 +163,14 @@ namespace mrn {
char db_path[MRN_MAX_PATH_SIZE];
snprintf(db_path, MRN_MAX_PATH_SIZE,
"%s%c%s", base_directory_, FN_LIBCHAR, base_path);
- grn_obj *db = grn_db_open(ctx_, db_path);
+ grn_obj *db = grn_db_open(ctx, db_path);
if (!db) {
DBUG_VOID_RETURN;
}
- (this->*each_body_func)(db, db_path, user_data);
+ (this->*each_body_func)(ctx, db, db_path, user_data);
- grn_obj_close(ctx_, db);
+ grn_obj_close(ctx, db);
DBUG_VOID_RETURN;
}
@@ -150,8 +190,7 @@ namespace mrn {
size_t raw_path_prefix_length = strlen(raw_path_prefix);
size_t separator_position = raw_path_prefix_length;
for (; separator_position > 0; separator_position--) {
- if (base_directory_buffer_[separator_position] == FN_LIBCHAR ||
- base_directory_buffer_[separator_position] == FN_LIBCHAR2) {
+ if (mrn_is_directory_separator(base_directory_buffer_[separator_position])) {
break;
}
}
@@ -169,34 +208,46 @@ namespace mrn {
DBUG_VOID_RETURN;
}
- void DatabaseRepairer::is_crashed_body(grn_obj *db,
- const char *db_path,
- void *user_data) {
+ void DatabaseRepairer::check_body(grn_ctx *ctx,
+ grn_obj *db,
+ const char *db_path,
+ void *user_data) {
MRN_DBUG_ENTER_METHOD();
- bool *is_crashed = static_cast<bool *>(user_data);
+ CheckResult *result = static_cast<CheckResult *>(user_data);
- if (grn_obj_is_locked(ctx_, db)) {
- *is_crashed = true;
+ if (grn_obj_is_locked(ctx, db)) {
+ result->is_crashed = true;
+ result->is_corrupt = true;
DBUG_VOID_RETURN;
}
grn_table_cursor *cursor;
- cursor = grn_table_cursor_open(ctx_, db,
+ cursor = grn_table_cursor_open(ctx, db,
NULL, 0,
NULL, 0,
0, -1, GRN_CURSOR_BY_ID);
if (!cursor) {
- *is_crashed = true;
+ result->is_crashed = true;
+ result->is_corrupt = true;
DBUG_VOID_RETURN;
}
grn_id id;
- while ((id = grn_table_cursor_next(ctx_, cursor)) != GRN_ID_NIL) {
- grn_obj *object = grn_ctx_at(ctx_, id);
+ while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ if (grn_id_is_builtin(ctx, id)) {
+ continue;
+ }
+
+ grn_obj *object = grn_ctx_at(ctx, id);
if (!object) {
- continue;
+ if (ctx->rc == GRN_SUCCESS) {
+ continue;
+ } else {
+ result->is_corrupt = true;
+ break;
+ }
}
switch (object->header.type) {
@@ -207,37 +258,40 @@ namespace mrn {
case GRN_COLUMN_FIX_SIZE:
case GRN_COLUMN_VAR_SIZE:
case GRN_COLUMN_INDEX:
- grn_obj_is_locked(ctx_, object);
- *is_crashed = true;
+ if (grn_obj_is_locked(ctx_, object)) {
+ result->is_crashed = true;
+ result->is_corrupt = true;
+ }
break;
default:
break;
}
- grn_obj_unlink(ctx_, object);
+ grn_obj_unlink(ctx, object);
- if (*is_crashed) {
+ if (result->is_crashed || result->is_corrupt) {
break;
}
}
- grn_table_cursor_close(ctx_, cursor);
+ grn_table_cursor_close(ctx, cursor);
DBUG_VOID_RETURN;
}
- void DatabaseRepairer::repair_body(grn_obj *db,
+ void DatabaseRepairer::repair_body(grn_ctx *ctx,
+ grn_obj *db,
const char *db_path,
void *user_data) {
MRN_DBUG_ENTER_METHOD();
bool *succeeded = static_cast<bool *>(user_data);
- if (grn_db_recover(ctx_, db) != GRN_SUCCESS) {
+ if (grn_db_recover(ctx, db) != GRN_SUCCESS) {
push_warning_printf(thd_,
MRN_SEVERITY_WARNING,
ER_NOT_KEYFILE,
"mroonga: repair: "
"Failed to recover database: <%s>: <%s>",
- db_path, ctx_->errbuf);
+ db_path, ctx->errbuf);
*succeeded = false;
}
diff --git a/storage/mroonga/lib/mrn_database_repairer.hpp b/storage/mroonga/lib/mrn_database_repairer.hpp
index 12e2bbc9c79..d46ae838072 100644
--- a/storage/mroonga/lib/mrn_database_repairer.hpp
+++ b/storage/mroonga/lib/mrn_database_repairer.hpp
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,7 @@ namespace mrn {
DatabaseRepairer(grn_ctx *ctx, THD *thd);
~DatabaseRepairer(void);
bool is_crashed(void);
+ bool is_corrupt(void);
bool repair(void);
private:
@@ -40,18 +41,26 @@ namespace mrn {
size_t path_prefix_length_;
size_t mrn_db_file_suffix_length_;
- typedef void (DatabaseRepairer::*EachBodyFunc)(grn_obj *db,
+ typedef void (DatabaseRepairer::*EachBodyFunc)(grn_ctx *ctx,
+ grn_obj *db,
const char *db_path,
void *user_data);
void each_database(EachBodyFunc each_body_func, void *user_data);
void each_database_body(const char *base_path,
+ grn_ctx *ctx,
EachBodyFunc each_body_func,
void *user_data);
void detect_paths(void);
- void is_crashed_body(grn_obj *db, const char *db_path, void *user_data);
- void repair_body(grn_obj *db, const char *db_path, void *user_data);
+ void check_body(grn_ctx *ctx,
+ grn_obj *db,
+ const char *db_path,
+ void *user_data);
+ void repair_body(grn_ctx *ctx,
+ grn_obj *db,
+ const char *db_path,
+ void *user_data);
};
}
diff --git a/storage/mroonga/lib/mrn_index_table_name.cpp b/storage/mroonga/lib/mrn_index_table_name.cpp
index a4a687c7996..1cc510ad7db 100644
--- a/storage/mroonga/lib/mrn_index_table_name.cpp
+++ b/storage/mroonga/lib/mrn_index_table_name.cpp
@@ -1,7 +1,7 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2011 Kentoku SHIBA
- Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -26,7 +26,8 @@
#define MRN_CLASS_NAME "mrn::IndexTableName"
namespace mrn {
- const char *IndexTableName::SEPARATOR = "-";
+ const char *IndexTableName::SEPARATOR = "#";
+ const char *IndexTableName::OLD_SEPARATOR = "-";
bool IndexTableName::is_custom_name(const char *table_name,
size_t table_name_length,
@@ -43,9 +44,12 @@ namespace mrn {
DBUG_RETURN(true);
}
- if (strncmp(SEPARATOR,
- index_table_name + table_name_length,
- strlen(SEPARATOR)) != 0) {
+ if ((strncmp(OLD_SEPARATOR,
+ index_table_name + table_name_length,
+ strlen(OLD_SEPARATOR)) != 0) &&
+ (strncmp(SEPARATOR,
+ index_table_name + table_name_length,
+ strlen(SEPARATOR)) != 0)) {
DBUG_RETURN(true);
}
@@ -63,6 +67,12 @@ namespace mrn {
encoded_mysql_index_name_multibyte + MRN_MAX_KEY_SIZE,
mysql_index_name_multibyte,
mysql_index_name_multibyte + strlen(mysql_index_name_));
+ snprintf(old_name_, MRN_MAX_KEY_SIZE,
+ "%s%s%s",
+ table_name_,
+ OLD_SEPARATOR,
+ encoded_mysql_index_name_multibyte);
+ old_length_ = strlen(old_name_);
snprintf(name_, MRN_MAX_KEY_SIZE,
"%s%s%s",
table_name_,
@@ -79,6 +89,14 @@ namespace mrn {
return length_;
}
+ const char *IndexTableName::old_c_str() {
+ return old_name_;
+ }
+
+ size_t IndexTableName::old_length() {
+ return old_length_;
+ }
+
uint IndexTableName::encode(uchar *encoded_start,
uchar *encoded_end,
const uchar *mysql_string_start,
diff --git a/storage/mroonga/lib/mrn_index_table_name.hpp b/storage/mroonga/lib/mrn_index_table_name.hpp
index c4f16228610..abaccfae220 100644
--- a/storage/mroonga/lib/mrn_index_table_name.hpp
+++ b/storage/mroonga/lib/mrn_index_table_name.hpp
@@ -1,7 +1,7 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2011 Kentoku SHIBA
- Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -27,6 +27,7 @@ namespace mrn {
class IndexTableName {
public:
static const char *SEPARATOR;
+ static const char *OLD_SEPARATOR;
static bool is_custom_name(const char *table_name,
size_t table_name_length,
@@ -36,9 +37,13 @@ namespace mrn {
IndexTableName(const char *table_name, const char *mysql_index_name);
const char *c_str();
size_t length();
+ const char *old_c_str();
+ size_t old_length();
private:
const char *table_name_;
const char *mysql_index_name_;
+ char old_name_[MRN_MAX_KEY_SIZE];
+ size_t old_length_;
char name_[MRN_MAX_KEY_SIZE];
size_t length_;
diff --git a/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp b/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
index d189a31c5de..b2e0e0444b8 100644
--- a/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
+++ b/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
@@ -288,6 +288,7 @@ namespace mrn {
decode_long_long_int(current_grn_key, &grn_time);
TimeConverter time_converter;
MYSQL_TIME mysql_time;
+ mysql_time.neg = FALSE;
mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME;
time_converter.grn_time_to_mysql_time(grn_time, &mysql_time);
long long int mysql_datetime_packed =
@@ -521,6 +522,14 @@ namespace mrn {
case MYSQL_TYPE_VARCHAR_COMPRESSED:
case MYSQL_TYPE_BLOB_COMPRESSED:
DBUG_ASSERT(0);
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+ case MYSQL_TYPE_JSON:
+ // TODO
+ DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_JSON"));
+ *data_type = TYPE_BYTE_SEQUENCE;
+ *data_size = key_part->length;
+ break;
+#endif
}
DBUG_VOID_RETURN;
}
diff --git a/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp b/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp
index 2b3f935d4e4..14003cda9f5 100644
--- a/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp
+++ b/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp
@@ -20,11 +20,11 @@
#ifndef MRN_MULTIPLE_COLUMN_KEY_CODEC_HPP_
#define MRN_MULTIPLE_COLUMN_KEY_CODEC_HPP_
-#include <groonga.h>
-
#include <mrn_mysql.h>
#include <mrn_mysql_compat.h>
+#include <groonga.h>
+
namespace mrn {
class MultipleColumnKeyCodec {
public:
diff --git a/storage/mroonga/lib/mrn_operation.cpp b/storage/mroonga/lib/mrn_operation.cpp
new file mode 100644
index 00000000000..2dab41108a7
--- /dev/null
+++ b/storage/mroonga/lib/mrn_operation.cpp
@@ -0,0 +1,51 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <mrn_mysql.h>
+
+#include "mrn_operation.hpp"
+
+// for debug
+#define MRN_CLASS_NAME "mrn::Operation"
+
+namespace mrn {
+ Operation::Operation(mrn::Operations *operations,
+ const char *type,
+ const char *table_name,
+ size_t table_name_size)
+ : operations_(operations),
+ id_(operations_->start(type, table_name, table_name_size)) {
+ }
+
+ Operation::~Operation() {
+ MRN_DBUG_ENTER_METHOD();
+
+ operations_->finish(id_);
+
+ DBUG_VOID_RETURN;
+ }
+
+ void Operation::record_target(grn_id record_id) {
+ MRN_DBUG_ENTER_METHOD();
+
+ operations_->record_target(id_, record_id);
+
+ DBUG_VOID_RETURN;
+ }
+}
diff --git a/storage/mroonga/lib/mrn_operation.hpp b/storage/mroonga/lib/mrn_operation.hpp
new file mode 100644
index 00000000000..899c92e9508
--- /dev/null
+++ b/storage/mroonga/lib/mrn_operation.hpp
@@ -0,0 +1,42 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef MRN_OPERATION_HPP_
+#define MRN_OPERATION_HPP_
+
+#include <mrn_operations.hpp>
+
+namespace mrn {
+ class Operation {
+ public:
+ Operation(mrn::Operations *operations,
+ const char *type,
+ const char *table_name,
+ size_t table_name_size);
+ ~Operation();
+
+ void record_target(grn_id record_id);
+
+ private:
+ mrn::Operations *operations_;
+ grn_id id_;
+ };
+}
+
+#endif /* MRN_OPERATION_HPP_ */
diff --git a/storage/mroonga/lib/mrn_operations.cpp b/storage/mroonga/lib/mrn_operations.cpp
new file mode 100644
index 00000000000..572907cdc55
--- /dev/null
+++ b/storage/mroonga/lib/mrn_operations.cpp
@@ -0,0 +1,401 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <mrn_mysql.h>
+
+#include <string.h>
+
+#include "mrn_operations.hpp"
+
+// for debug
+#define MRN_CLASS_NAME "mrn::Operations"
+
+#define TABLE_NAME "mroonga_operations"
+#define COLUMN_TYPE_NAME "type"
+#define COLUMN_TABLE_NAME "table"
+#define COLUMN_RECORD_NAME "record"
+
+namespace mrn {
+ Operations::Operations(grn_ctx *ctx)
+ : ctx_(ctx) {
+ MRN_DBUG_ENTER_METHOD();
+
+ GRN_TEXT_INIT(&text_buffer_, GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_UINT32_INIT(&id_buffer_, 0);
+
+ table_ = grn_ctx_get(ctx_, TABLE_NAME, -1);
+ if (!table_) {
+ table_ = grn_table_create(ctx_,
+ TABLE_NAME, strlen(TABLE_NAME),
+ NULL,
+ GRN_OBJ_TABLE_NO_KEY | GRN_OBJ_PERSISTENT,
+ NULL, NULL);
+ columns_.type_ =
+ grn_column_create(ctx_, table_,
+ COLUMN_TYPE_NAME, strlen(COLUMN_TYPE_NAME),
+ NULL,
+ GRN_OBJ_COLUMN_SCALAR | GRN_OBJ_PERSISTENT,
+ grn_ctx_at(ctx_, GRN_DB_SHORT_TEXT));
+ columns_.table_ =
+ grn_column_create(ctx_, table_,
+ COLUMN_TABLE_NAME, strlen(COLUMN_TABLE_NAME),
+ NULL,
+ GRN_OBJ_COLUMN_SCALAR | GRN_OBJ_PERSISTENT,
+ grn_ctx_at(ctx_, GRN_DB_SHORT_TEXT));
+ columns_.record_ =
+ grn_column_create(ctx_, table_,
+ COLUMN_RECORD_NAME, strlen(COLUMN_RECORD_NAME),
+ NULL,
+ GRN_OBJ_COLUMN_SCALAR | GRN_OBJ_PERSISTENT,
+ grn_ctx_at(ctx_, GRN_DB_UINT32));
+ } else {
+ columns_.type_ = grn_ctx_get(ctx_, TABLE_NAME "." COLUMN_TYPE_NAME, -1);
+ columns_.table_ = grn_ctx_get(ctx_, TABLE_NAME "." COLUMN_TABLE_NAME, -1);
+ columns_.record_ = grn_ctx_get(ctx_, TABLE_NAME "." COLUMN_RECORD_NAME, -1);
+ }
+
+ is_enabled_recording_ = true;
+
+ DBUG_VOID_RETURN;
+ }
+
+ Operations::~Operations() {
+ MRN_DBUG_ENTER_METHOD();
+
+ GRN_OBJ_FIN(ctx_, &id_buffer_);
+ GRN_OBJ_FIN(ctx_, &text_buffer_);
+
+ DBUG_VOID_RETURN;
+ }
+
+ bool Operations::is_locked() {
+ MRN_DBUG_ENTER_METHOD();
+
+ if (grn_obj_is_locked(ctx_, table_) > 0)
+ DBUG_RETURN(true);
+
+ if (grn_obj_is_locked(ctx_, columns_.type_) > 0)
+ DBUG_RETURN(true);
+
+ if (grn_obj_is_locked(ctx_, columns_.table_) > 0)
+ DBUG_RETURN(true);
+
+ if (grn_obj_is_locked(ctx_, columns_.record_) > 0)
+ DBUG_RETURN(true);
+
+ DBUG_RETURN(false);
+ }
+
+ grn_id Operations::start(const char *type,
+ const char *table_name, size_t table_name_size) {
+ MRN_DBUG_ENTER_METHOD();
+
+ if (!is_enabled_recording_) {
+ DBUG_RETURN(GRN_ID_NIL);
+ }
+
+ grn_id id = grn_table_add(ctx_, table_, NULL, 0, NULL);
+
+ GRN_TEXT_SETS(ctx_, &text_buffer_, type);
+ grn_obj_set_value(ctx_, columns_.type_, id, &text_buffer_, GRN_OBJ_SET);
+
+ GRN_TEXT_SET(ctx_, &text_buffer_, table_name, table_name_size);
+ grn_obj_set_value(ctx_, columns_.table_, id, &text_buffer_, GRN_OBJ_SET);
+
+ DBUG_RETURN(id);
+ }
+
+ void Operations::record_target(grn_id id, grn_id record_id) {
+ MRN_DBUG_ENTER_METHOD();
+
+ if (!is_enabled_recording_) {
+ DBUG_VOID_RETURN;
+ }
+
+ GRN_UINT32_SET(ctx_, &id_buffer_, record_id);
+ grn_obj_set_value(ctx_, columns_.record_, id, &id_buffer_, GRN_OBJ_SET);
+
+ DBUG_VOID_RETURN;
+ }
+
+ void Operations::finish(grn_id id) {
+ MRN_DBUG_ENTER_METHOD();
+
+ if (!is_enabled_recording_) {
+ DBUG_VOID_RETURN;
+ }
+
+ grn_table_delete_by_id(ctx_, table_, id);
+
+ DBUG_VOID_RETURN;
+ }
+
+ void Operations::enable_recording() {
+ MRN_DBUG_ENTER_METHOD();
+
+ is_enabled_recording_ = true;
+
+ DBUG_VOID_RETURN;
+ }
+
+ void Operations::disable_recording() {
+ MRN_DBUG_ENTER_METHOD();
+
+ is_enabled_recording_ = false;
+
+ DBUG_VOID_RETURN;
+ }
+
+ grn_hash *Operations::collect_processing_table_names() {
+ MRN_DBUG_ENTER_METHOD();
+
+ grn_hash *table_names =
+ grn_hash_create(ctx_, NULL, GRN_TABLE_MAX_KEY_SIZE, 0,
+ GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_KEY_VAR_SIZE);
+
+ grn_table_cursor *cursor;
+ cursor = grn_table_cursor_open(ctx_, table_, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ GRN_LOG(ctx_, GRN_LOG_NOTICE,
+ "[operations] failed to open cursor: %s",
+ ctx_->errbuf);
+ DBUG_RETURN(table_names);
+ }
+
+ grn_id id;
+ while ((id = grn_table_cursor_next(ctx_, cursor))) {
+ GRN_BULK_REWIND(&text_buffer_);
+ grn_obj_get_value(ctx_, columns_.table_, id, &text_buffer_);
+ if (GRN_TEXT_LEN(&text_buffer_) > 0) {
+ grn_hash_add(ctx_, table_names,
+ GRN_TEXT_VALUE(&text_buffer_),
+ GRN_TEXT_LEN(&text_buffer_),
+ NULL,
+ NULL);
+ }
+ }
+ grn_table_cursor_close(ctx_, cursor);
+
+ DBUG_RETURN(table_names);
+ }
+
+ int Operations::repair(const char *table_name, size_t table_name_size) {
+ MRN_DBUG_ENTER_METHOD();
+
+ int error = 0;
+
+ grn_table_cursor *cursor;
+ cursor = grn_table_cursor_open(ctx_, table_, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ error = HA_ERR_CRASHED_ON_USAGE;
+ if (ctx_->rc) {
+ my_message(error, ctx_->errbuf, MYF(0));
+ } else {
+ my_message(error,
+ "mroonga: repair: "
+ "failed to open cursor for operations table",
+ MYF(0));
+ }
+ DBUG_RETURN(error);
+ }
+
+ grn_obj *target_table = grn_ctx_get(ctx_, table_name, table_name_size);
+ if (!target_table) {
+ GRN_LOG(ctx_, GRN_LOG_WARNING,
+ "table doesn't exist for auto repair: <%.*s>",
+ static_cast<int>(table_name_size), table_name);
+ }
+
+ grn_id id;
+ while ((id = grn_table_cursor_next(ctx_, cursor))) {
+ GRN_BULK_REWIND(&text_buffer_);
+ grn_obj_get_value(ctx_, columns_.table_, id, &text_buffer_);
+ if (!((static_cast<size_t>(GRN_TEXT_LEN(&text_buffer_)) ==
+ table_name_size) &&
+ memcmp(GRN_TEXT_VALUE(&text_buffer_),
+ table_name,
+ table_name_size) == 0)) {
+ continue;
+ }
+
+ if (!target_table) {
+ grn_rc rc = grn_table_cursor_delete(ctx_, cursor);
+ if (rc != GRN_SUCCESS) {
+ GRN_BULK_REWIND(&text_buffer_);
+ grn_obj_get_value(ctx_, columns_.type_, id, &text_buffer_);
+ GRN_TEXT_PUTC(ctx_, &text_buffer_, '\0');
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: repair: failed to delete an orphan operation: "
+ "[%u]: <%.*s>[%s]: <%s>(%d)",
+ id,
+ static_cast<int>(table_name_size), table_name,
+ GRN_TEXT_VALUE(&text_buffer_),
+ ctx_->errbuf,
+ rc);
+ my_message(error, error_message, MYF(0));
+ break;
+ }
+ continue;
+ }
+
+ GRN_BULK_REWIND(&id_buffer_);
+ grn_obj_get_value(ctx_, columns_.record_, id, &id_buffer_);
+ grn_id record_id = GRN_UINT32_VALUE(&id_buffer_);
+ if (record_id == GRN_ID_NIL) {
+ grn_rc rc = grn_table_cursor_delete(ctx_, cursor);
+ if (rc != GRN_SUCCESS) {
+ GRN_BULK_REWIND(&text_buffer_);
+ grn_obj_get_value(ctx_, columns_.type_, id, &text_buffer_);
+ GRN_TEXT_PUTC(ctx_, &text_buffer_, '\0');
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: repair: "
+ "failed to delete an operation that has no related record: "
+ "[%u]: <%.*s>[%s]: <%s>(%d)",
+ id,
+ static_cast<int>(table_name_size), table_name,
+ GRN_TEXT_VALUE(&text_buffer_),
+ ctx_->errbuf,
+ rc);
+ my_message(error, error_message, MYF(0));
+ break;
+ }
+ continue;
+ }
+
+ GRN_BULK_REWIND(&text_buffer_);
+ grn_obj_get_value(ctx_, columns_.type_, id, &text_buffer_);
+ GRN_TEXT_PUTC(ctx_, &text_buffer_, '\0');
+ if (strcmp(GRN_TEXT_VALUE(&text_buffer_), "write") == 0 ||
+ strcmp(GRN_TEXT_VALUE(&text_buffer_), "delete") == 0) {
+ grn_rc rc = grn_table_delete_by_id(ctx_, target_table, record_id);
+ if (rc != GRN_SUCCESS) {
+ error = HA_ERR_CRASHED_ON_USAGE;
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: repair: failed to delete an incomplete record: "
+ "[%u]: <%.*s>[%u]: <%s>(%d)",
+ id,
+ static_cast<int>(table_name_size), table_name,
+ record_id,
+ ctx_->errbuf,
+ rc);
+ my_message(error, error_message, MYF(0));
+ break;
+ }
+
+ rc = grn_table_cursor_delete(ctx_, cursor);
+ if (rc != GRN_SUCCESS) {
+ error = HA_ERR_CRASHED_ON_USAGE;
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: repair: failed to delete an incomplete operation: "
+ "[%u]: <%.*s>[%u][%s]: <%s>(%d)",
+ id,
+ static_cast<int>(table_name_size), table_name,
+ record_id,
+ GRN_TEXT_VALUE(&text_buffer_),
+ ctx_->errbuf,
+ rc);
+ my_message(error, error_message, MYF(0));
+ break;
+ }
+ } else if (strcmp(GRN_TEXT_VALUE(&text_buffer_), "update") == 0) {
+ error = HA_ERR_CRASHED_ON_USAGE;
+ my_message(error,
+ "mroonga: repair: can't recover from crash while updating",
+ MYF(0));
+ break;
+ } else {
+ error = HA_ERR_CRASHED_ON_USAGE;
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: repair: unknown operation type: "
+ "[%u]: <%.*s>[%u]: <%s>",
+ id,
+ static_cast<int>(table_name_size), table_name,
+ record_id,
+ GRN_TEXT_VALUE(&text_buffer_));
+ my_message(error, error_message, MYF(0));
+ break;
+ }
+ }
+ grn_table_cursor_close(ctx_, cursor);
+
+ DBUG_RETURN(error);
+ }
+
+ int Operations::clear(const char *table_name, size_t table_name_size) {
+ MRN_DBUG_ENTER_METHOD();
+
+ int error = 0;
+
+ grn_table_cursor *cursor;
+ cursor = grn_table_cursor_open(ctx_, table_, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ error = HA_ERR_CRASHED_ON_USAGE;
+ if (ctx_->rc) {
+ my_message(error, ctx_->errbuf, MYF(0));
+ } else {
+ my_message(error,
+ "mroonga: clear: "
+ "failed to open cursor for operations table",
+ MYF(0));
+ }
+ DBUG_RETURN(error);
+ }
+
+ grn_id id;
+ while ((id = grn_table_cursor_next(ctx_, cursor))) {
+ GRN_BULK_REWIND(&text_buffer_);
+ grn_obj_get_value(ctx_, columns_.table_, id, &text_buffer_);
+ if ((static_cast<size_t>(GRN_TEXT_LEN(&text_buffer_)) ==
+ table_name_size) &&
+ memcmp(GRN_TEXT_VALUE(&text_buffer_),
+ table_name,
+ table_name_size) == 0) {
+ grn_rc rc = grn_table_cursor_delete(ctx_, cursor);
+ if (rc != GRN_SUCCESS) {
+ error = HA_ERR_CRASHED_ON_USAGE;
+ GRN_BULK_REWIND(&id_buffer_);
+ grn_obj_get_value(ctx_, columns_.record_, id, &id_buffer_);
+ GRN_BULK_REWIND(&text_buffer_);
+ grn_obj_get_value(ctx_, columns_.type_, id, &text_buffer_);
+ GRN_TEXT_PUTC(ctx_, &text_buffer_, '\0');
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "mroonga: clear: failed to delete an operation: "
+ "[%u]: <%.*s>[%u][%s]: <%s>(%d)",
+ id,
+ static_cast<int>(table_name_size), table_name,
+ GRN_UINT32_VALUE(&id_buffer_),
+ GRN_TEXT_VALUE(&text_buffer_),
+ ctx_->errbuf,
+ rc);
+ my_message(error, error_message, MYF(0));
+ break;
+ }
+ }
+ }
+ grn_table_cursor_close(ctx_, cursor);
+
+ DBUG_RETURN(error);
+ }
+}
diff --git a/storage/mroonga/lib/mrn_operations.hpp b/storage/mroonga/lib/mrn_operations.hpp
new file mode 100644
index 00000000000..762a5ee9d43
--- /dev/null
+++ b/storage/mroonga/lib/mrn_operations.hpp
@@ -0,0 +1,60 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef MRN_OPERATIONS_HPP_
+#define MRN_OPERATIONS_HPP_
+
+#include <groonga.h>
+
+namespace mrn {
+ class Operations {
+ public:
+ Operations(grn_ctx *ctx);
+ ~Operations();
+
+ bool is_locked();
+
+ grn_id start(const char *type,
+ const char *table_name, size_t table_name_size);
+ void record_target(grn_id id, grn_id target_id);
+ void finish(grn_id id);
+
+ void enable_recording();
+ void disable_recording();
+
+ grn_hash *collect_processing_table_names();
+
+ int repair(const char *table_name, size_t table_name_size);
+ int clear(const char *table_name, size_t table_name_size);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj text_buffer_;
+ grn_obj id_buffer_;
+ grn_obj *table_;
+ struct {
+ grn_obj *type_;
+ grn_obj *table_;
+ grn_obj *record_;
+ } columns_;
+ bool is_enabled_recording_;
+ };
+}
+
+#endif /* MRN_OPERATIONS_HPP_ */
diff --git a/storage/mroonga/lib/mrn_path_mapper.cpp b/storage/mroonga/lib/mrn_path_mapper.cpp
index 7a595986f01..43f276f4e82 100644
--- a/storage/mroonga/lib/mrn_path_mapper.cpp
+++ b/storage/mroonga/lib/mrn_path_mapper.cpp
@@ -222,4 +222,8 @@ namespace mrn {
mysql_path_[i] = '\0';
return mysql_path_;
}
+
+ bool PathMapper::is_internal_table_name() {
+ return mysql_table_name()[0] == '#';
+ }
}
diff --git a/storage/mroonga/lib/mrn_path_mapper.hpp b/storage/mroonga/lib/mrn_path_mapper.hpp
index 607bfe4cdce..9849d5e28ef 100644
--- a/storage/mroonga/lib/mrn_path_mapper.hpp
+++ b/storage/mroonga/lib/mrn_path_mapper.hpp
@@ -38,6 +38,8 @@ namespace mrn {
const char *table_name();
const char *mysql_table_name();
const char *mysql_path();
+ bool is_internal_table_name();
+ bool is_temporary_table_name();
private:
const char *original_mysql_path_;
const char *path_prefix_;
diff --git a/storage/mroonga/lib/mrn_query_parser.cpp b/storage/mroonga/lib/mrn_query_parser.cpp
new file mode 100644
index 00000000000..4e05069a3a9
--- /dev/null
+++ b/storage/mroonga/lib/mrn_query_parser.cpp
@@ -0,0 +1,361 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "mrn_query_parser.hpp"
+
+#include <mrn_variables.hpp>
+
+extern "C" {
+ /* Groonga's internal functions */
+ int grn_atoi(const char *nptr, const char *end, const char **rest);
+ uint grn_atoui(const char *nptr, const char *end, const char **rest);
+}
+
+#define MRN_CLASS_NAME "mrn::QueryParser"
+
+namespace mrn {
+ QueryParser::QueryParser(grn_ctx *ctx,
+ THD *thd,
+ grn_obj *expression,
+ grn_obj *default_column,
+ uint n_sections,
+ grn_obj *match_columns)
+ : ctx_(ctx),
+ thd_(thd),
+ expression_(expression),
+ default_column_(default_column),
+ n_sections_(n_sections),
+ match_columns_(match_columns) {
+ }
+
+ QueryParser::~QueryParser() {
+ }
+
+ grn_rc QueryParser::parse(const char *query, size_t query_length) {
+ MRN_DBUG_ENTER_METHOD();
+
+ const char *raw_query = NULL;
+ size_t raw_query_length = 0;
+ grn_operator default_operator = GRN_OP_OR;
+ grn_expr_flags expression_flags = 0;
+ parse_pragma(query,
+ query_length,
+ &raw_query,
+ &raw_query_length,
+ &default_operator,
+ &expression_flags);
+
+ grn_obj *default_column = default_column_;
+ if (match_columns_) {
+ default_column = match_columns_;
+ }
+ grn_rc rc = grn_expr_parse(ctx_,
+ expression_,
+ raw_query,
+ raw_query_length,
+ default_column,
+ GRN_OP_MATCH,
+ default_operator,
+ expression_flags);
+ if (rc != GRN_SUCCESS) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to parse fulltext search keyword: <%.*s>: <%s>",
+ static_cast<int>(query_length),
+ query,
+ ctx_->errbuf);
+ variables::ActionOnError action =
+ variables::get_action_on_fulltext_query_error(thd_);
+ switch (action) {
+ case variables::ACTION_ON_ERROR_ERROR:
+ my_message(ER_PARSE_ERROR, error_message, MYF(0));
+ break;
+ case variables::ACTION_ON_ERROR_ERROR_AND_LOG:
+ my_message(ER_PARSE_ERROR, error_message, MYF(0));
+ GRN_LOG(ctx_, GRN_LOG_ERROR, "%s", error_message);
+ break;
+ case variables::ACTION_ON_ERROR_IGNORE:
+ break;
+ case variables::ACTION_ON_ERROR_IGNORE_AND_LOG:
+ GRN_LOG(ctx_, GRN_LOG_ERROR, "%s", error_message);
+ break;
+ }
+ }
+
+ DBUG_RETURN(rc);
+ }
+
+ void QueryParser::parse_pragma(const char *query,
+ size_t query_length,
+ const char **raw_query,
+ size_t *raw_query_length,
+ grn_operator *default_operator,
+ grn_expr_flags *flags) {
+ MRN_DBUG_ENTER_METHOD();
+
+ const char *current_query = query;
+ size_t current_query_length = query_length;
+
+ *default_operator = GRN_OP_OR;
+
+ if (current_query_length >= 4 && memcmp(current_query, "*SS ", 4) == 0) {
+ *raw_query = current_query + 4;
+ *raw_query_length = current_query_length - 4;
+ *flags = GRN_EXPR_SYNTAX_SCRIPT;
+ DBUG_VOID_RETURN;
+ }
+
+ bool weight_specified = false;
+ *raw_query = query;
+ *raw_query_length = query_length;
+ *flags = default_expression_flags();
+ if (current_query_length >= 2 && current_query[0] == '*') {
+ bool parsed = false;
+ bool done = false;
+ current_query++;
+ current_query_length--;
+ while (!done) {
+ size_t consumed_query_length = 0;
+ switch (current_query[0]) {
+ case 'D':
+ if (parse_pragma_d(current_query + 1,
+ current_query_length - 1,
+ default_operator,
+ &consumed_query_length)) {
+ parsed = true;
+ consumed_query_length += 1;
+ current_query += consumed_query_length;
+ current_query_length -= consumed_query_length;
+ } else {
+ done = true;
+ }
+ break;
+ case 'W':
+ if (parse_pragma_w(current_query + 1,
+ current_query_length - 1,
+ &consumed_query_length)) {
+ parsed = true;
+ weight_specified = true;
+ consumed_query_length += 1;
+ current_query += consumed_query_length;
+ current_query_length -= consumed_query_length;
+ } else {
+ done = true;
+ }
+ break;
+ default:
+ done = true;
+ break;
+ }
+ }
+ if (parsed) {
+ *raw_query = current_query;
+ *raw_query_length = current_query_length;
+ }
+ }
+
+ // WORKAROUND: ignore the first '+' to support "+apple macintosh" pattern.
+ while (*raw_query_length > 0 && (*raw_query)[0] == ' ') {
+ (*raw_query)++;
+ (*raw_query_length)--;
+ }
+ if (*raw_query_length > 0 && (*raw_query)[0] == '+') {
+ (*raw_query)++;
+ (*raw_query_length)--;
+ }
+ if (!weight_specified && match_columns_) {
+ grn_expr_append_obj(ctx_, match_columns_, default_column_, GRN_OP_PUSH, 1);
+ }
+
+ DBUG_VOID_RETURN;
+ }
+
+ bool QueryParser::parse_pragma_w(const char *query,
+ size_t query_length,
+ size_t *consumed_query_length) {
+ MRN_DBUG_ENTER_METHOD();
+
+ *consumed_query_length = 0;
+
+ grn_obj section_value_buffer;
+ GRN_UINT32_INIT(&section_value_buffer, 0);
+
+ MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(bool, specified_sections, n_sections_);
+ for (uint i = 0; i < n_sections_; ++i) {
+ specified_sections[i] = false;
+ }
+
+ uint n_weights = 0;
+ while (query_length >= 1) {
+ if (n_weights >= 1) {
+ if (query[0] != ',') {
+ break;
+ }
+ size_t n_used_query_length = 1;
+ *consumed_query_length += n_used_query_length;
+ query_length -= n_used_query_length;
+ query += n_used_query_length;
+ if (query_length == 0) {
+ break;
+ }
+ }
+
+ uint section = 0;
+ if ('1' <= query[0] && query[0] <= '9') {
+ const char *section_start = query;
+ const char *query_end = query + query_length;
+ const char *query_rest;
+ section = grn_atoui(section_start, query_end, &query_rest);
+ if (section_start == query_rest) {
+ break;
+ }
+ if (!(0 < section && section <= n_sections_)) {
+ break;
+ }
+ section -= 1;
+ specified_sections[section] = true;
+ size_t n_used_query_length = query_rest - query;
+ *consumed_query_length += n_used_query_length;
+ query_length -= n_used_query_length;
+ query += n_used_query_length;
+ } else {
+ break;
+ }
+
+ int weight = 1;
+ if (query_length >= 2 && query[0] == ':') {
+ const char *weight_start = query + 1;
+ const char *query_end = query + query_length;
+ const char *query_rest;
+ weight = grn_atoi(weight_start, query_end, &query_rest);
+ if (weight_start == query_rest) {
+ break;
+ }
+ size_t n_used_query_length = query_rest - query;
+ *consumed_query_length += n_used_query_length;
+ query_length -= n_used_query_length;
+ query += n_used_query_length;
+ }
+
+ n_weights++;
+
+ append_section(section,
+ &section_value_buffer,
+ weight,
+ n_weights);
+ }
+
+ for (uint section = 0; section < n_sections_; ++section) {
+ if (specified_sections[section]) {
+ continue;
+ }
+
+ ++n_weights;
+
+ int default_weight = 1;
+ append_section(section,
+ &section_value_buffer,
+ default_weight,
+ n_weights);
+ }
+ MRN_FREE_VARIABLE_LENGTH_ARRAYS(specified_sections);
+
+ GRN_OBJ_FIN(ctx_, &section_value_buffer);
+
+ DBUG_RETURN(n_weights > 0);
+ }
+
+ void QueryParser::append_section(uint section,
+ grn_obj *section_value_buffer,
+ int weight,
+ uint n_weights) {
+ MRN_DBUG_ENTER_METHOD();
+
+ if (!match_columns_) {
+ DBUG_VOID_RETURN;
+ }
+
+ grn_expr_append_obj(ctx_, match_columns_, default_column_, GRN_OP_PUSH, 1);
+ GRN_UINT32_SET(ctx_, section_value_buffer, section);
+ grn_expr_append_const(ctx_, match_columns_, section_value_buffer,
+ GRN_OP_PUSH, 1);
+ grn_expr_append_op(ctx_, match_columns_, GRN_OP_GET_MEMBER, 2);
+
+ if (weight != 1) {
+ grn_expr_append_const_int(ctx_, match_columns_, weight, GRN_OP_PUSH, 1);
+ grn_expr_append_op(ctx_, match_columns_, GRN_OP_STAR, 2);
+ }
+
+ if (n_weights >= 2) {
+ grn_expr_append_op(ctx_, match_columns_, GRN_OP_OR, 2);
+ }
+
+ DBUG_VOID_RETURN;
+ }
+
+ bool QueryParser::parse_pragma_d(const char *query,
+ size_t query_length,
+ grn_operator *default_operator,
+ size_t *consumed_query_length) {
+ MRN_DBUG_ENTER_METHOD();
+
+ bool succeeded = true;
+ if (query_length >= 1 && query[0] == '+') {
+ *default_operator = GRN_OP_AND;
+ *consumed_query_length = 1;
+ } else if (query_length >= 1 && query[0] == '-') {
+ *default_operator = GRN_OP_AND_NOT;
+ *consumed_query_length = 1;
+ } else if (query_length >= 2 && memcmp(query, "OR", 2) == 0) {
+ *default_operator = GRN_OP_OR;
+ *consumed_query_length = 2;
+ } else {
+ succeeded = false;
+ }
+
+ DBUG_RETURN(succeeded);
+ }
+
+ grn_expr_flags QueryParser::default_expression_flags() {
+ MRN_DBUG_ENTER_METHOD();
+
+ ulonglong syntax_flags = variables::get_boolean_mode_syntax_flags(thd_);
+ grn_expr_flags expression_flags = 0;
+ if (syntax_flags == variables::BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT) {
+ expression_flags = GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT;
+ } else {
+ if (syntax_flags & variables::BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_SCRIPT) {
+ expression_flags |= GRN_EXPR_SYNTAX_SCRIPT;
+ } else {
+ expression_flags |= GRN_EXPR_SYNTAX_QUERY;
+ }
+ if (syntax_flags & variables::BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_COLUMN) {
+ expression_flags |= GRN_EXPR_ALLOW_COLUMN;
+ }
+ if (syntax_flags & variables::BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_UPDATE) {
+ expression_flags |= GRN_EXPR_ALLOW_UPDATE;
+ }
+ if (syntax_flags & variables::BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_LEADING_NOT) {
+ expression_flags |= GRN_EXPR_ALLOW_LEADING_NOT;
+ }
+ }
+
+ DBUG_RETURN(expression_flags);
+ }
+}
diff --git a/storage/mroonga/lib/mrn_query_parser.hpp b/storage/mroonga/lib/mrn_query_parser.hpp
new file mode 100644
index 00000000000..8b3c4084c8d
--- /dev/null
+++ b/storage/mroonga/lib/mrn_query_parser.hpp
@@ -0,0 +1,67 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include <mrn_mysql.h>
+#include <mrn_mysql_compat.h>
+
+#include <groonga.h>
+
+namespace mrn {
+ class QueryParser {
+ public:
+ QueryParser(grn_ctx *ctx,
+ THD *thd,
+ grn_obj *expression,
+ grn_obj *default_column,
+ uint n_sections,
+ grn_obj *match_columns=NULL);
+ ~QueryParser();
+
+ grn_rc parse(const char *query, size_t query_length);
+ void parse_pragma(const char *query,
+ size_t query_length,
+ const char **raw_query,
+ size_t *raw_query_length,
+ grn_operator *default_operator,
+ grn_expr_flags *flags);
+
+ private:
+ grn_ctx *ctx_;
+ THD *thd_;
+ grn_obj *expression_;
+ grn_obj *default_column_;
+ uint n_sections_;
+ grn_obj *match_columns_;
+
+ bool parse_pragma_w(const char *query,
+ size_t query_length,
+ size_t *consumed_query_length);
+ void append_section(uint section,
+ grn_obj *section_value_buffer,
+ int weight,
+ uint n_weights);
+ bool parse_pragma_d(const char *query,
+ size_t query_length,
+ grn_operator *default_operator,
+ size_t *consumed_query_length);
+ grn_expr_flags default_expression_flags();
+ };
+}
diff --git a/storage/mroonga/lib/mrn_smart_bitmap.cpp b/storage/mroonga/lib/mrn_smart_bitmap.cpp
new file mode 100644
index 00000000000..9dc91ff29d5
--- /dev/null
+++ b/storage/mroonga/lib/mrn_smart_bitmap.cpp
@@ -0,0 +1,42 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "mrn_smart_bitmap.hpp"
+
+namespace mrn {
+ SmartBitmap::SmartBitmap(MY_BITMAP *bitmap)
+ : bitmap_(bitmap) {
+ }
+
+ SmartBitmap::~SmartBitmap() {
+ if (bitmap_) {
+ bitmap_free(bitmap_);
+ }
+ }
+
+ MY_BITMAP *SmartBitmap::get() {
+ return bitmap_;
+ }
+
+ MY_BITMAP *SmartBitmap::release() {
+ MY_BITMAP *bitmap = bitmap_;
+ bitmap_ = NULL;
+ return bitmap;
+ }
+}
diff --git a/storage/mroonga/lib/mrn_smart_bitmap.hpp b/storage/mroonga/lib/mrn_smart_bitmap.hpp
new file mode 100644
index 00000000000..dfb56956024
--- /dev/null
+++ b/storage/mroonga/lib/mrn_smart_bitmap.hpp
@@ -0,0 +1,36 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include <mrn_mysql.h>
+#include <my_bitmap.h>
+
+namespace mrn {
+ class SmartBitmap {
+ public:
+ SmartBitmap(MY_BITMAP *bitmap);
+ ~SmartBitmap();
+
+ MY_BITMAP *get();
+ MY_BITMAP *release();
+ private:
+ MY_BITMAP *bitmap_;
+ };
+}
diff --git a/storage/mroonga/lib/mrn_table_fields_offset_mover.cpp b/storage/mroonga/lib/mrn_table_fields_offset_mover.cpp
new file mode 100644
index 00000000000..7f1dae266c7
--- /dev/null
+++ b/storage/mroonga/lib/mrn_table_fields_offset_mover.cpp
@@ -0,0 +1,41 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "mrn_table_fields_offset_mover.hpp"
+
+namespace mrn {
+ TableFieldsOffsetMover::TableFieldsOffsetMover(TABLE *table,
+ my_ptrdiff_t diff)
+ : table_(table),
+ diff_(diff) {
+ uint n_columns = table_->s->fields;
+ for (uint i = 0; i < n_columns; ++i) {
+ Field *field = table_->field[i];
+ field->move_field_offset(diff_);
+ }
+ }
+
+ TableFieldsOffsetMover::~TableFieldsOffsetMover() {
+ uint n_columns = table_->s->fields;
+ for (uint i = 0; i < n_columns; ++i) {
+ Field *field = table_->field[i];
+ field->move_field_offset(-diff_);
+ }
+ }
+}
diff --git a/storage/mroonga/lib/mrn_table_fields_offset_mover.hpp b/storage/mroonga/lib/mrn_table_fields_offset_mover.hpp
new file mode 100644
index 00000000000..a8d12be19ed
--- /dev/null
+++ b/storage/mroonga/lib/mrn_table_fields_offset_mover.hpp
@@ -0,0 +1,33 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include <mrn_mysql.h>
+
+namespace mrn {
+ class TableFieldsOffsetMover {
+ public:
+ TableFieldsOffsetMover(TABLE *table, my_ptrdiff_t diff);
+ ~TableFieldsOffsetMover();
+ private:
+ TABLE *table_;
+ my_ptrdiff_t diff_;
+ };
+}
diff --git a/storage/mroonga/mrn_err.h b/storage/mroonga/mrn_err.h
index d109f87bb48..95b1b047c79 100644
--- a/storage/mroonga/mrn_err.h
+++ b/storage/mroonga/mrn_err.h
@@ -39,5 +39,8 @@
#define ER_MRN_INVALID_INDEX_FLAG_NUM 16508
#define ER_MRN_INVALID_INDEX_FLAG_STR \
"The index flag '%-.64s' is invalid. It is ignored"
+#define ER_MRN_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN_NUM 16509
+#define ER_MRN_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN_STR \
+ "Index for virtual generated column is not supported: %s"
#endif /* MRN_ERR_H_ */
diff --git a/storage/mroonga/mrn_mysql.h b/storage/mroonga/mrn_mysql.h
index 8a42637a8e4..60f535f791f 100644
--- a/storage/mroonga/mrn_mysql.h
+++ b/storage/mroonga/mrn_mysql.h
@@ -43,21 +43,18 @@
#define MYSQL_SERVER 1
#include <mysql_version.h>
-#if MYSQL_VERSION_ID < 50500
-# include <mysql_priv.h>
-# include <mysql/plugin.h>
-#else
-# include <sql_const.h>
-# include <sql_class.h>
-# include <probes_mysql.h>
-# include <sql_partition.h>
-#endif
-#include <rpl_filter.h>
-
#ifdef MARIADB_BASE_VERSION
# define MRN_MARIADB_P 1
#endif
+#include <sql_const.h>
+#include <sql_class.h>
+#if (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID < 80002)
+# include <probes_mysql.h>
+#endif
+#include <sql_partition.h>
+#include <rpl_filter.h>
+
#define MRN_MESSAGE_BUFFER_SIZE 1024
#define MRN_DBUG_ENTER_FUNCTION() DBUG_ENTER(__FUNCTION__)
diff --git a/storage/mroonga/mrn_mysql_compat.h b/storage/mroonga/mrn_mysql_compat.h
index 660c72b4d25..3bc19e5d8aa 100644
--- a/storage/mroonga/mrn_mysql_compat.h
+++ b/storage/mroonga/mrn_mysql_compat.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,10 @@
# define MRN_HAVE_MYSQL_TYPE_TIME2
#endif
+#if MYSQL_VERSION_ID >= 50709 && !defined(MRN_MARIADB_P)
+# define MRN_HAVE_MYSQL_TYPE_JSON
+#endif
+
#if MYSQL_VERSION_ID < 50603
typedef MYSQL_ERROR Sql_condition;
#endif
@@ -42,6 +46,10 @@
typedef char *range_id_t;
#endif
+#if defined(MRN_MARIADB_P) || MYSQL_VERSION_ID < 80002
+ typedef st_select_lex SELECT_LEX;
+#endif
+
#if MYSQL_VERSION_ID >= 50609
# define MRN_KEY_HAS_USER_DEFINED_KEYPARTS
#endif
@@ -52,7 +60,10 @@
# define KEY_N_KEY_PARTS(key) (key)->key_parts
#endif
-#if defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100000
+#if defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100213
+# define mrn_init_alloc_root(PTR, SZ1, SZ2, FLAG) \
+ init_alloc_root(PTR, "mroonga", SZ1, SZ2, FLAG)
+#elif defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100000
# define mrn_init_alloc_root(PTR, SZ1, SZ2, FLAG) \
init_alloc_root(PTR, SZ1, SZ2, FLAG)
#elif MYSQL_VERSION_ID >= 50706
@@ -99,6 +110,9 @@
#if defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100009
# define MRN_HAVE_TDC_ACQUIRE_SHARE
+# if MYSQL_VERSION_ID < 100200
+# define MRN_TDC_ACQUIRE_SHARE_REQUIRE_KEY
+# endif
#endif
#if MYSQL_VERSION_ID >= 50613
@@ -161,7 +175,7 @@
#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
# define MRN_THD_DB_PATH(thd) ((thd)->db().str)
#else
-# define MRN_THD_DB_PATH(thd) ((thd)->db)
+# define MRN_THD_DB_PATH(thd) ((thd)->db.str)
#endif
#ifndef INT_MAX64
@@ -206,8 +220,34 @@
# define MRN_SUPPORT_CUSTOM_OPTIONS
#endif
+#ifdef MRN_MARIADB_P
+# define MRN_HAVE_ITEM_EQUAL_FIELDS_ITERATOR
+#endif
+
+#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
+# define MRN_SELECT_LEX_GET_WHERE_COND(select_lex) \
+ ((select_lex)->where_cond())
+# define MRN_SELECT_LEX_GET_HAVING_COND(select_lex) \
+ ((select_lex)->having_cond())
+# define MRN_SELECT_LEX_GET_ACTIVE_OPTIONS(select_lex) \
+ ((select_lex)->active_options())
+#else
+# define MRN_SELECT_LEX_GET_WHERE_COND(select_lex) \
+ ((select_lex)->where)
+# define MRN_SELECT_LEX_GET_HAVING_COND(select_lex) \
+ ((select_lex)->having)
+# define MRN_SELECT_LEX_GET_ACTIVE_OPTIONS(select_lex) \
+ ((select_lex)->options)
+#endif
+
#if defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100000
-# if MYSQL_VERSION_ID >= 100104
+# if MYSQL_VERSION_ID >= 100213
+# define mrn_init_sql_alloc(thd, mem_root) \
+ init_sql_alloc(mem_root, "Mroonga", \
+ TABLE_ALLOC_BLOCK_SIZE, \
+ 0, \
+ MYF(thd->slave_thread ? 0 : MY_THREAD_SPECIFIC))
+#elif MYSQL_VERSION_ID >= 100104
# define mrn_init_sql_alloc(thd, mem_root) \
init_sql_alloc(mem_root, \
TABLE_ALLOC_BLOCK_SIZE, \
@@ -221,17 +261,25 @@
MYF(0))
# endif
#else
+# if MYSQL_VERSION_ID >= 50709
+# define mrn_init_sql_alloc(thd, mem_root) \
+ init_sql_alloc(mrn_memory_key, \
+ mem_root, \
+ TABLE_ALLOC_BLOCK_SIZE, \
+ 0)
+# else
# define mrn_init_sql_alloc(thd, mem_root) \
init_sql_alloc(mem_root, \
TABLE_ALLOC_BLOCK_SIZE, \
0)
+# endif
#endif
#ifdef MRN_MARIADB_P
# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
#else
# if MYSQL_VERSION_ID >= 50706
-# define MRN_ABORT_ON_WARNING(thd) false
+# define MRN_ABORT_ON_WARNING(thd) thd->is_strict_mode()
# else
# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
# endif
@@ -240,4 +288,204 @@
#define MRN_ERROR_CODE_DATA_TRUNCATE(thd) \
(MRN_ABORT_ON_WARNING(thd) ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED)
+#if MYSQL_VERSION_ID >= 50709 && !defined(MRN_MARIADB_P)
+# define mrn_my_hash_init(hash, \
+ charset, \
+ default_array_elements, \
+ key_offset, \
+ key_length, \
+ get_key, \
+ free_element, \
+ flags) \
+ my_hash_init(hash, \
+ charset, \
+ default_array_elements, \
+ key_offset, \
+ key_length, \
+ get_key, \
+ free_element, \
+ flags, \
+ mrn_memory_key)
+#else
+# define mrn_my_hash_init(hash, \
+ charset, \
+ default_array_elements, \
+ key_offset, \
+ key_length, \
+ get_key, \
+ free_element, \
+ flags) \
+ my_hash_init(hash, \
+ charset, \
+ default_array_elements, \
+ key_offset, \
+ key_length, \
+ get_key, \
+ free_element, \
+ flags)
+#endif
+
+#if defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100000
+# define mrn_strconvert(from_cs, \
+ from, \
+ from_length, \
+ to_cs, \
+ to, \
+ to_length, \
+ errors) \
+ strconvert((from_cs), \
+ (from), \
+ (from_length), \
+ (to_cs), \
+ (to), \
+ (to_length), \
+ (errors))
+#else
+# define mrn_strconvert(from_cs, \
+ from, \
+ from_length, \
+ to_cs, \
+ to, \
+ to_length, \
+ errors) \
+ strconvert((from_cs), \
+ (from), \
+ (to_cs), \
+ (to), \
+ (to_length), \
+ (errors))
+#endif
+
+#if MYSQL_VERSION_ID >= 50717 && !defined(MRN_MARIADB_P)
+# define mrn_is_directory_separator(c) \
+ is_directory_separator((c))
+#else
+# define mrn_is_directory_separator(c) \
+ (c == FN_LIBCHAR || c == FN_LIBCHAR2)
+#endif
+
+#if ((MYSQL_VERSION_ID < 50636) || \
+ (MYSQL_VERSION_ID >= 50700 && MYSQL_VERSION_ID < 50718)) && !defined(MRN_MARIADB_P)
+# define MRN_HAVE_MYSQL_FIELD_PART_OF_KEY_NOT_CLUSTERED
+#endif
+
+#if defined(MRN_MARIADB_P) && \
+ ((MYSQL_VERSION_ID >= 100207) || \
+ ((MYSQL_VERSION_ID >= 100126) && (MYSQL_VERSION_ID < 100200)) || \
+ ((MYSQL_VERSION_ID >= 100032) && (MYSQL_VERSION_ID < 100100)) || \
+ ((MYSQL_VERSION_ID >= 50557) && (MYSQL_VERSION_ID < 100000)))
+# define mrn_create_partition_name(out, \
+ out_length, \
+ in1, \
+ in2, \
+ name_variant, \
+ translate) \
+ create_partition_name(out, out_length, in1, in2, name_variant, translate)
+# define mrn_create_subpartition_name(out, \
+ out_length, \
+ in1, \
+ in2, \
+ in3, \
+ name_variant) \
+ create_subpartition_name(out, out_length, in1, in2, in3, name_variant)
+#else
+# define mrn_create_partition_name(out, \
+ out_length, \
+ in1, \
+ in2, \
+ name_variant, \
+ translate) \
+ (create_partition_name(out, in1, in2, name_variant, translate), 0)
+# define mrn_create_subpartition_name(out, \
+ out_length, \
+ in1, \
+ in2, \
+ in3, \
+ name_variant) \
+ (create_subpartition_name(out, in1, in2, in3, name_variant), 0)
+#endif
+
+#if (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 80002)
+# define ITEM_SUM_GET_NEST_LEVEL(sum_item) (sum_item)->base_select->nest_level
+# define ITEM_SUM_GET_AGGR_LEVEL(sum_item) (sum_item)->aggr_select->nest_level
+# define ITEM_SUM_GET_MAX_AGGR_LEVEL(sum_item) (sum_item)->max_aggr_level
+#else
+# define ITEM_SUM_GET_NEST_LEVEL(sum_item) (sum_item)->nest_level
+# define ITEM_SUM_GET_AGGR_LEVEL(sum_item) (sum_item)->aggr_level
+# define ITEM_SUM_GET_MAX_AGGR_LEVEL(sum_item) (sum_item)->max_arg_level
+#endif
+
+#if (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 80002)
+ typedef bool mrn_bool;
+#else
+ typedef my_bool mrn_bool;
+#endif
+
+#define MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(type, variable_name, variable_size) \
+ type *variable_name = \
+ (type *)mrn_my_malloc(sizeof(type) * (variable_size), MYF(MY_WME))
+#define MRN_FREE_VARIABLE_LENGTH_ARRAYS(variable_name) \
+ my_free(variable_name)
+
+#if ((defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100203)) || \
+ (!defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50711)
+# define MRN_ALTER_INPLACE_INFO_ADD_VIRTUAL_COLUMN \
+ Alter_inplace_info::ADD_VIRTUAL_COLUMN
+# define MRN_ALTER_INPLACE_INFO_ADD_STORED_BASE_COLUMN \
+ Alter_inplace_info::ADD_STORED_BASE_COLUMN
+# define MRN_ALTER_INPLACE_INFO_ADD_STORED_GENERATED_COLUMN \
+ Alter_inplace_info::ADD_STORED_GENERATED_COLUMN
+#else
+# define MRN_ALTER_INPLACE_INFO_ADD_VIRTUAL_COLUMN 0
+# define MRN_ALTER_INPLACE_INFO_ADD_STORED_BASE_COLUMN \
+ Alter_inplace_info::ADD_COLUMN
+# define MRN_ALTER_INPLACE_INFO_ADD_STORED_GENERATED_COLUMN 0
+#endif
+
+#if (defined(HA_CAN_VIRTUAL_COLUMNS) || defined(HA_GENERATED_COLUMNS))
+# define MRN_SUPPORT_GENERATED_COLUMNS
+#endif
+
+#ifdef MRN_MARIADB_P
+# if (MYSQL_VERSION_ID >= 100200)
+# define MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field) \
+ (!field->stored_in_db())
+# define MRN_GENERATED_COLUMNS_FIELD_IS_STORED(field) \
+ (field->vcol_info && field->vcol_info->is_stored())
+# elif (MYSQL_VERSION_ID >= 50500)
+# define MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field) \
+ (!field->stored_in_db)
+# define MRN_GENERATED_COLUMNS_FIELD_IS_STORED(field) \
+ (field->vcol_info && field->vcol_info->is_stored())
+# else
+# define MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field) false
+# define MRN_GENERATED_COLUMNS_FIELD_IS_STORED(field) false
+# endif
+#else
+# if (MYSQL_VERSION_ID >= 50708)
+# define MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field) \
+ (field->is_virtual_gcol())
+# define MRN_GENERATED_COLUMNS_FIELD_IS_STORED(field) \
+ (field->is_gcol() && !field->is_virtual_gcol())
+# elif (MYSQL_VERSION_ID >= 50706)
+# define MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field) \
+ (!field->stored_in_db)
+# define MRN_GENERATED_COLUMNS_FIELD_IS_STORED(field) \
+ (field->gcol_info && field->gcol_info->get_field_stored())
+# else
+# define MRN_GENERATED_COLUMNS_FIELD_IS_VIRTUAL(field) false
+# define MRN_GENERATED_COLUMNS_FIELD_IS_STORED(field) false
+# endif
+#endif
+
+#ifdef MRN_MARIADB_P
+# if (MYSQL_VERSION_ID >= 100203)
+# define MRN_GENERATED_COLUMNS_UPDATE_VIRTUAL_FIELD(table, field) \
+ (table->update_virtual_field(field))
+# else
+# define MRN_GENERATED_COLUMNS_UPDATE_VIRTUAL_FIELD(table, field) \
+ (field->vcol_info->expr_item->save_in_field(field, 0))
+# endif
+#endif
+
#endif /* MRN_MYSQL_COMPAT_H_ */
diff --git a/storage/mroonga/mrn_table.cpp b/storage/mroonga/mrn_table.cpp
index 8984db3bfbf..17831bbda61 100644
--- a/storage/mroonga/mrn_table.cpp
+++ b/storage/mroonga/mrn_table.cpp
@@ -1,7 +1,7 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2011-2013 Kentoku SHIBA
- Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -202,7 +202,6 @@ void mrn_get_partition_info(const char *table_name, uint table_name_length,
const TABLE *table, partition_element **part_elem,
partition_element **sub_elem)
{
- char tmp_name[FN_REFLEN + 1];
partition_info *part_info = table->part_info;
partition_element *tmp_part_elem = NULL, *tmp_sub_elem = NULL;
bool tmp_flg = FALSE, tmp_find_flg = FALSE;
@@ -224,18 +223,24 @@ void mrn_get_partition_info(const char *table_name, uint table_name_length,
List_iterator<partition_element> sub_it((*part_elem)->subpartitions);
while ((*sub_elem = sub_it++))
{
- if (create_subpartition_name(tmp_name, sizeof(tmp_name), table->s->path.str,
- (*part_elem)->partition_name, (*sub_elem)->partition_name,
- NORMAL_PART_NAME))
+ char subpartition_name[FN_REFLEN + 1];
+ int error = mrn_create_subpartition_name(subpartition_name,
+ sizeof(subpartition_name),
+ table->s->path.str,
+ (*part_elem)->partition_name,
+ (*sub_elem)->partition_name,
+ NORMAL_PART_NAME);
+ if (error != 0)
DBUG_VOID_RETURN;
- DBUG_PRINT("info", ("mroonga tmp_name=%s", tmp_name));
- if (table_name && !memcmp(table_name, tmp_name, table_name_length + 1))
+ DBUG_PRINT("info", ("mroonga subpartition name=%s", subpartition_name));
+ if (table_name &&
+ memcmp(table_name, subpartition_name, table_name_length + 1) == 0)
DBUG_VOID_RETURN;
if (
tmp_flg &&
table_name &&
- *(tmp_name + table_name_length - 5) == '\0' &&
- !memcmp(table_name, tmp_name, table_name_length - 5)
+ *(subpartition_name + table_name_length - 5) == '\0' &&
+ memcmp(table_name, subpartition_name, table_name_length - 5) == 0
) {
tmp_part_elem = *part_elem;
tmp_sub_elem = *sub_elem;
@@ -244,17 +249,24 @@ void mrn_get_partition_info(const char *table_name, uint table_name_length,
}
}
} else {
- if (create_partition_name(tmp_name, sizeof(tmp_name), table->s->path.str,
- (*part_elem)->partition_name, NORMAL_PART_NAME, TRUE))
+ char partition_name[FN_REFLEN + 1];
+ int error = mrn_create_partition_name(partition_name,
+ sizeof(partition_name),
+ table->s->path.str,
+ (*part_elem)->partition_name,
+ NORMAL_PART_NAME,
+ TRUE);
+ if (error != 0)
DBUG_VOID_RETURN;
- DBUG_PRINT("info", ("mroonga tmp_name=%s", tmp_name));
- if (table_name && !memcmp(table_name, tmp_name, table_name_length + 1))
+ DBUG_PRINT("info", ("mroonga partition name=%s", partition_name));
+ if (table_name &&
+ memcmp(table_name, partition_name, table_name_length + 1) == 0)
DBUG_VOID_RETURN;
if (
tmp_flg &&
table_name &&
- *(tmp_name + table_name_length - 5) == '\0' &&
- !memcmp(table_name, tmp_name, table_name_length - 5)
+ *(partition_name + table_name_length - 5) == '\0' &&
+ memcmp(table_name, partition_name, table_name_length - 5) == 0
) {
tmp_part_elem = *part_elem;
tmp_flg = FALSE;
@@ -518,6 +530,7 @@ int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i)
char *sprit_ptr[2];
char *tmp_ptr, *start_ptr;
#endif
+ THD *thd = current_thd;
MRN_DBUG_ENTER_FUNCTION();
#if MYSQL_VERSION_ID >= 50500
@@ -580,6 +593,10 @@ int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i)
MRN_PARAM_STR_LIST("table", index_table, i);
break;
case 6:
+ push_warning_printf(thd, MRN_SEVERITY_WARNING,
+ ER_WARN_DEPRECATED_SYNTAX,
+ ER(ER_WARN_DEPRECATED_SYNTAX),
+ "parser", "tokenizer");
MRN_PARAM_STR_LIST("parser", key_tokenizer, i);
break;
case 9:
@@ -1000,26 +1017,31 @@ int mrn_free_share(MRN_SHARE *share)
TABLE_SHARE *mrn_get_table_share(TABLE_LIST *table_list, int *error)
{
- uint key_length __attribute__((unused));
TABLE_SHARE *share;
THD *thd = current_thd;
MRN_DBUG_ENTER_FUNCTION();
-#ifdef MRN_HAVE_GET_TABLE_DEF_KEY
+#if defined(MRN_HAVE_TDC_ACQUIRE_SHARE) && \
+ !defined(MRN_TDC_ACQUIRE_SHARE_REQUIRE_KEY)
+ share = tdc_acquire_share(thd, table_list, GTS_TABLE);
+#else
+ uint key_length;
+# ifdef MRN_HAVE_GET_TABLE_DEF_KEY
const char *key;
key_length = get_table_def_key(table_list, &key);
-#else
+# else
char key[MAX_DBKEY_LENGTH];
key_length = create_table_def_key(thd, key, table_list, FALSE);
-#endif
-#ifdef MRN_HAVE_TABLE_DEF_CACHE
+# endif
+# ifdef MRN_HAVE_TABLE_DEF_CACHE
my_hash_value_type hash_value;
hash_value = my_calc_hash(mrn_table_def_cache, (uchar*) key, key_length);
share = get_table_share(thd, table_list, key, key_length, 0, error,
hash_value);
-#elif defined(MRN_HAVE_TDC_ACQUIRE_SHARE)
+# elif defined(MRN_HAVE_TDC_ACQUIRE_SHARE)
share = tdc_acquire_share(thd, table_list, GTS_TABLE);
-#else
+# else
share = get_table_share(thd, table_list, key, key_length, 0, error);
+# endif
#endif
DBUG_RETURN(share);
}
@@ -1040,7 +1062,7 @@ TABLE_SHARE *mrn_create_tmp_table_share(TABLE_LIST *table_list, const char *path
key_length = create_table_def_key(thd, key, table_list, FALSE);
#endif
#if MYSQL_VERSION_ID >= 100002 && defined(MRN_MARIADB_P)
- share = alloc_table_share(table_list->db, table_list->table_name, key,
+ share = alloc_table_share(table_list->db.str, table_list->table_name.str, key,
key_length);
#else
share = alloc_table_share(table_list, key, key_length);
@@ -1050,7 +1072,7 @@ TABLE_SHARE *mrn_create_tmp_table_share(TABLE_LIST *table_list, const char *path
*error = ER_CANT_OPEN_FILE;
DBUG_RETURN(NULL);
}
- share->tmp_table = INTERNAL_TMP_TABLE; // TODO: is this right?
+ share->tmp_table = NO_TMP_TABLE; // TODO: is this right?
share->path.str = (char *) path;
share->path.length = strlen(share->path.str);
share->normalized_path.str = mrn_my_strdup(path, MYF(MY_WME));
diff --git a/storage/mroonga/mrn_variables.hpp b/storage/mroonga/mrn_variables.hpp
index 6bc948a1cac..0866403e54c 100644
--- a/storage/mroonga/mrn_variables.hpp
+++ b/storage/mroonga/mrn_variables.hpp
@@ -26,4 +26,28 @@
extern PSI_memory_key mrn_memory_key;
#endif
+namespace mrn {
+ namespace variables {
+ enum BooleanModeSyntaxFlag {
+ BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT = (1 << 0),
+ BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_QUERY = (1 << 1),
+ BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_SCRIPT = (1 << 2),
+ BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_COLUMN = (1 << 3),
+ BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_UPDATE = (1 << 4),
+ BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_LEADING_NOT = (1 << 5)
+ };
+
+ ulonglong get_boolean_mode_syntax_flags(THD *thd);
+
+ enum ActionOnError {
+ ACTION_ON_ERROR_ERROR,
+ ACTION_ON_ERROR_ERROR_AND_LOG,
+ ACTION_ON_ERROR_IGNORE,
+ ACTION_ON_ERROR_IGNORE_AND_LOG,
+ };
+
+ ActionOnError get_action_on_fulltext_query_error(THD *thd);
+ }
+}
+
#endif /* MRN_VARIABLES_HPP_ */
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_64bit.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_64bit.inc
index 1b3cf9c0942..06b5361f3bd 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_64bit.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_64bit.inc
@@ -12,14 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
disable_query_log;
disable_warnings;
-let $VERSION_COMPILE_64BIT=
- `SELECT IF(@@version_compile_machine like '%64%', 1, 0)`;
+let $version_compile_64bit=
+ `SELECT IF(@@version_compile_machine LIKE '%64%', 1, 0)`;
enable_warnings;
enable_query_log;
-if (!$VERSION_COMPILE_64BIT) {
- skip Need a 64 binary;
-}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_freebsd.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_freebsd.inc
index 39503a9c68d..7449724b5de 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_freebsd.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_freebsd.inc
@@ -12,8 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--disable_query_log
-let $VERSION_COMPILE_OS_FREEBSD=`SELECT IF(@@version_compile_os like 'FREEBSD%', 1, 0);`;
+let $version_compile_os_freebsd=
+ `SELECT IF(@@version_compile_os LIKE '%freebsd%', 1, 0);`;
--enable_query_log
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_ha_mroonga_so.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_ha_mroonga_so.inc
index b2212fd94a8..7063c1d1b3d 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_ha_mroonga_so.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_ha_mroonga_so.inc
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_windows.inc
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc
index 6f89f05b869..f608f5f220f 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--disable_query_log
let $libgroonga_embedded = `SELECT @@mroonga_libgroonga_embedded;`;
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_lz4.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_lz4.inc
index 076be2582ba..a61058b92ff 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_lz4.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_lz4.inc
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--disable_query_log
let $libgroonga_support_lz4 =
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zlib.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zlib.inc
index 5d4862957ae..8f79d05af29 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zlib.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zlib.inc
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--disable_query_log
let $libgroonga_support_zlib =
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zstd.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zstd.inc
new file mode 100644
index 00000000000..1038fe9eea6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zstd.inc
@@ -0,0 +1,20 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--disable_query_log
+let $libgroonga_support_zstd =
+ `SELECT @@mroonga_libgroonga_support_zstd;`;
+--enable_query_log
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_mariadb.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_mariadb.inc
index 0ef2199b704..50ee66d64c6 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_mariadb.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_mariadb.inc
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--disable_query_log
let $mariadb = `SELECT LOCATE('MariaDB', @@global.version) > 0`;
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_osx.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_osx.inc
index a664a9c51f4..2808e107bc8 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_osx.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_osx.inc
@@ -1,4 +1,5 @@
# Copyright(C) 2014 Toshihisa Tashiro
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,8 +13,19 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--disable_query_log
-let $VERSION_COMPILE_OS_OSX=`SELECT IF(@@version_compile_os like 'osx%', 1, 0);`;
+let $version_compile_os_osx=`SELECT IF(@@version_compile_os like 'osx%', 1, 0);`;
+if ($version_compile_os_osx) {
+ let $version_compile_os_osx_10_8_or_later=
+ `SELECT IF(@@version_compile_os = 'osx10.6', 0, 1);`;
+ if ($version_compile_os_osx_10_8_or_later) {
+ let $version_compile_os_osx_10_8_or_later=
+ `SELECT IF(@@version_compile_os = 'osx10.7', 0, 1);`;
+ }
+}
+if (!$version_comiple_os_osx) {
+ let $version_compile_os_osx_10_8_or_later=0;
+}
--enable_query_log
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_56_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_solaris.inc
index 350f51616ba..cad909d022a 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_56_or_later.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_solaris.inc
@@ -1,4 +1,4 @@
-# Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,10 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/check_version.inc
-
-if (!$version_56_or_later) {
- skip This test is for MySQL version 5.6.x or later;
-}
+--disable_query_log
+let $version_compile_os_solaris=
+ `SELECT IF(@@version_compile_os LIKE 'sun-solaris%', 1, 0);`;
+--enable_query_log
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_strict_sql_mode.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_strict_sql_mode.inc
new file mode 100644
index 00000000000..88dfd6602e9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_strict_sql_mode.inc
@@ -0,0 +1,21 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--disable_query_log
+let $strict_sql_mode =
+ `SELECT @@sql_mode LIKE '%STRICT_TRANS_TABLES%' OR
+ @@sql_mode LIKE '%STRICT_ALL_TABLES%'`;
+--enable_query_log
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_version.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_version.inc
index cfa7c008e51..aaf4f8dacc8 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_version.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_version.inc
@@ -1,4 +1,4 @@
-# Copyright(C) 2012-2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,19 +12,22 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--disable_query_log
let $version_major_minor =
`SELECT CAST(SUBSTRING_INDEX(@@global.version, '.', 2) AS DECIMAL(4, 2))`;
-let $version_55 = `SELECT $version_major_minor = 5.5`;
-let $version_56 = `SELECT $version_major_minor = 5.6`;
-let $version_57 = `SELECT $version_major_minor = 5.7`;
-let $version_100 = `SELECT $version_major_minor = 10.0`;
+let $version_5_5 = `SELECT $version_major_minor = 5.5`;
+let $version_5_6 = `SELECT $version_major_minor = 5.6`;
+let $version_5_7 = `SELECT $version_major_minor = 5.7`;
+let $version_10_0 = `SELECT $version_major_minor = 10.0`;
+let $version_10_1 = `SELECT $version_major_minor = 10.1`;
+let $version_10_2 = `SELECT $version_major_minor = 10.2`;
-let $version_55_or_later = `SELECT $version_major_minor >= 5.5`;
-let $version_56_or_later = `SELECT $version_major_minor >= 5.6`;
-let $version_57_or_later = `SELECT $version_major_minor >= 5.7`;
-let $version_100_or_later = `SELECT $version_major_minor >= 10.0`;
+let $version_5_5_or_later = `SELECT $version_major_minor >= 5.5`;
+let $version_5_6_or_later = `SELECT $version_major_minor >= 5.6`;
+let $version_5_7_or_later = `SELECT $version_major_minor >= 5.7`;
+let $version_10_0_or_later = `SELECT $version_major_minor >= 10.0`;
+let $version_10_2_or_later = `SELECT $version_major_minor >= 10.2`;
--enable_query_log
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_windows.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_windows.inc
index b258225fa9f..179e0329600 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_windows.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_windows.inc
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--disable_query_log
let $VERSION_COMPILE_OS_WIN=`SELECT IF(@@version_compile_os like 'Win%', 1, 0)`;
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_32bit.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_32bit.inc
deleted file mode 100644
index ae44649df9e..00000000000
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_32bit.inc
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright(C) 2013 Kentoku SHIBA
-# Copyright(C) 2014 Toshihisa Tashiro
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library 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
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-
---source ../../include/mroonga/skip_osx.inc
-
-disable_query_log;
-disable_warnings;
-let $VERSION_COMPILE_64BIT=
- `SELECT IF(@@version_compile_machine like '%64%', 1, 0)`;
-enable_warnings;
-enable_query_log;
-if ($VERSION_COMPILE_64BIT) {
- skip Need a 32 bit machine/binary;
-}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_fractional_seconds.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_fractional_seconds.inc
index 90a203c91ef..88f8594c352 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_fractional_seconds.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_fractional_seconds.inc
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_mariadb.inc
--source ../../include/mroonga/check_version.inc
@@ -22,11 +22,11 @@ if ($mariadb) {
}
if (!$mariadb) {
- if ($version_56) {
+ if ($version_5_6) {
let $fractional_seconds = `SELECT @@global.version >= '5.6'`;
}
}
if (!$fractional_seconds) {
- skip fractional seconds in time values are available in MySQL version 5.6 or later or MariaDB;
+ --skip fractional seconds in time values are available in MySQL version 5.6 or later or MariaDB
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_freebsd.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_freebsd.inc
index fc6cddc5b14..3daf0e7c379 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_freebsd.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_freebsd.inc
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_freebsd.inc
-if (!$VERSION_COMPILE_OS_FREEBSD) {
- skip Need OS FreeBSD;
+if (!$version_compile_os_freebsd) {
+ --skip Need OS FreeBSD
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc
index dfd3ae12c93..19b52287cc1 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc
@@ -12,11 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_libgroonga_embedded.inc
if ($libgroonga_embedded) {
--source ../../include/mroonga/have_mroonga_deinit.inc
- skip "This test requires plugin_register of Groonga. libgroonga embedded build doesn't support it.";
+ --skip This test requires plugin_register of Groonga. libgroonga embedded build doesn't support it.
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb.inc
index 7f76ef05021..5f38c66c2c5 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb.inc
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_mariadb.inc
if (!$mariadb) {
- skip This test is for MariaDB;
+ --skip This test is for MariaDB
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb_10_2_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb_10_2_or_later.inc
new file mode 100644
index 00000000000..e11c15ec796
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb_10_2_or_later.inc
@@ -0,0 +1,26 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_version.inc
+--source ../../include/mroonga/check_mariadb.inc
+
+if (!$mariadb) {
+ --skip This test is for MariaDB version 10.2.x or later
+}
+
+if (!$version_10_2_or_later) {
+ --skip This test is for MariaDB version 10.2.x or later
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc
index 7bb3ca8b371..b88839e55fe 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_ha_mroonga_so.inc
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga_deinit.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga_deinit.inc
index bd5e4cf7f9f..bd5242c8d34 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga_deinit.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga_deinit.inc
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
disable_query_log;
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga_helper.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga_helper.inc
index f0bad1a490d..0d93ce03bd7 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga_helper.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga_helper.inc
@@ -12,6 +12,6 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-let $MYSQLD_DATADIR= `select @@datadir`;
+let MYSQLD_DATADIR= `select @@datadir`;
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mysql.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mysql.inc
index e2a791aff5e..f3c2129203e 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mysql.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mysql.inc
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_mariadb.inc
if ($mariadb) {
- skip This test is for MySQL;
+ --skip This test is for MySQL
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mysql_5_7_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mysql_5_7_or_later.inc
new file mode 100644
index 00000000000..cf638a9c73a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mysql_5_7_or_later.inc
@@ -0,0 +1,26 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_version.inc
+--source ../../include/mroonga/check_mariadb.inc
+
+if ($mariadb) {
+ --skip This test is for MySQL version 5.7.x or later
+}
+
+if (!$version_5_7_or_later) {
+ --skip This test is for MySQL version 5.7.x or later
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_signed_64bit_time_t.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_signed_64bit_time_t.inc
new file mode 100644
index 00000000000..90eca856e5e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_signed_64bit_time_t.inc
@@ -0,0 +1,28 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_64bit.inc
+--source ../../include/mroonga/check_osx.inc
+
+if (!$version_compile_64bit) {
+ --skip Need a 64 binary for signed 64bit time_t
+}
+
+if ($version_compile_os_osx) {
+ if (!$version_compile_os_osx_10_8_or_later) {
+ --skip Need OS X 10.8 or later for signed 64bit time_t
+ }
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_solaris.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_solaris.inc
new file mode 100644
index 00000000000..fc89e733f0e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_solaris.inc
@@ -0,0 +1,21 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_solaris.inc
+
+if (!$version_compile_os_solaris) {
+ --skip Need Solaris
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_strict_sql_mode.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_strict_sql_mode.inc
new file mode 100644
index 00000000000..678ba6ab460
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_strict_sql_mode.inc
@@ -0,0 +1,21 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_strict_sql_mode.inc
+
+if (!$strict_sql_mode) {
+ --skip This test is for STRICT_ALL_TABLES or STRICT_TRANS_TABLES
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0.inc
new file mode 100644
index 00000000000..356b2295743
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0.inc
@@ -0,0 +1,21 @@
+# Copyright(C) 2013-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_version.inc
+
+if (!$version_10_0) {
+ --skip This test is for MariaDB version 10.0.x
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_100_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0_or_later.inc
index 09e5acc0187..1a8883f0478 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_100_or_later.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0_or_later.inc
@@ -1,4 +1,4 @@
-# Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2013-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_version.inc
-if (!$version_100_or_later) {
- skip This test is for MariaDB version 10.0.x or later;
+if (!$version_10_0_or_later) {
+ --skip This test is for MariaDB version 10.0.x or later
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_56.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_5.inc
index fbb4152fc4a..b1708abe195 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_56.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_5.inc
@@ -1,4 +1,4 @@
-# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_version.inc
-if (!$version_56) {
- skip This test is for MySQL version 5.6.x;
+if (!$version_5_5) {
+ --skip This test is for MySQL version 5.5.x
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_55.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_6.inc
index a08d789d6f2..cfa3c7ac60d 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_55.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_6.inc
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_version.inc
-if (!$version_55) {
- skip This test is for MySQL version 5.5.x;
+if (!$version_5_6) {
+ --skip This test is for MySQL version 5.6.x
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_100.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_6_or_later.inc
index b48d4e9d1bb..b9481afdee8 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_100.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_6_or_later.inc
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_version.inc
-if (!$version_100) {
- skip This test is for MariaDB version 10.0.x;
+if (!$version_5_6_or_later) {
+ --skip This test is for MySQL version 5.6.x or later
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_57.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_7.inc
index ca2d06ae617..4b65def9463 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_57.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_7.inc
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_version.inc
-if (!$version_57) {
- skip This test is for MySQL version 5.7.x;
+if (!$version_5_7) {
+ --skip This test is for MySQL version 5.7.x
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_7_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_7_or_later.inc
new file mode 100644
index 00000000000..1b18b5749ca
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_7_or_later.inc
@@ -0,0 +1,21 @@
+# Copyright(C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_version.inc
+
+if (!$version_5_7_or_later) {
+ --skip This test is for MySQL version 5.7.x or later or MariaDB 10.0.x or later
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/load_mroonga_functions.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/load_mroonga_functions.inc
index 6e563721fc7..9ca1b0d1168 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/load_mroonga_functions.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/load_mroonga_functions.inc
@@ -1,4 +1,4 @@
-# Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2013-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_ha_mroonga_so.inc
@@ -21,4 +21,8 @@ eval CREATE FUNCTION last_insert_grn_id RETURNS INTEGER SONAME $ha_mroonga_so;
eval CREATE FUNCTION mroonga_snippet RETURNS STRING SONAME $ha_mroonga_so;
eval CREATE FUNCTION mroonga_command RETURNS STRING SONAME $ha_mroonga_so;
eval CREATE FUNCTION mroonga_escape RETURNS STRING SONAME $ha_mroonga_so;
+eval CREATE FUNCTION mroonga_snippet_html RETURNS STRING SONAME $ha_mroonga_so;
+eval CREATE FUNCTION mroonga_normalize RETURNS STRING SONAME $ha_mroonga_so;
+eval CREATE FUNCTION mroonga_highlight_html RETURNS STRING SONAME $ha_mroonga_so;
+eval CREATE FUNCTION mroonga_query_expand RETURNS STRING SONAME $ha_mroonga_so;
--enable_query_log
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/print_groonga_query_log.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/print_groonga_query_log.inc
new file mode 100644
index 00000000000..d5f8c1293d5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/print_groonga_query_log.inc
@@ -0,0 +1,8 @@
+SHOW GLOBAL VARIABLES LIKE "mroonga_query_log_file";
+perl;
+open(F, '<', $_="$ENV{MYSQLD_DATADIR}/groonga-query-log.log") or die "open(<$_): $!";
+while (<F>) {
+ s/^[^|]+\|[^|]+\|[^|]+\| *//;
+ print;
+}
+EOF
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_freebsd.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_freebsd.inc
index ed13b737fb5..bf0bed98480 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_freebsd.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_freebsd.inc
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_freebsd.inc
-if ($VERSION_COMPILE_OS_FREEBSD) {
- skip This test is not for FreeBSD;
+if ($version_compile_os_freebsd) {
+ --skip This test is not for FreeBSD
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_0_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_0_or_later.inc
new file mode 100644
index 00000000000..5fd84f1b2a8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_0_or_later.inc
@@ -0,0 +1,24 @@
+# Copyright(C) 2012-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_version.inc
+--source ../../include/mroonga/check_mariadb.inc
+
+if ($mariadb) {
+ if ($version_10_0_or_later) {
+ --skip This test is not for MariaDB 10.x
+ }
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_55.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_1.inc
index 93eead8791e..b954d1c75f7 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_55.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_1.inc
@@ -1,4 +1,4 @@
-# Copyright(C) 2012-2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,13 +12,13 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_version.inc
--source ../../include/mroonga/check_mariadb.inc
-if ($version_55) {
+if ($version_10_1) {
if ($mariadb) {
- skip This test is not for MariaDB 5.5.x;
+ --skip This test is not for MariaDB 10.1.x
}
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_1_or_earlier.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_1_or_earlier.inc
new file mode 100644
index 00000000000..2af6f2adb0d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_1_or_earlier.inc
@@ -0,0 +1,24 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_version.inc
+--source ../../include/mroonga/check_mariadb.inc
+
+if ($mariadb) {
+ if (!$version_10_2_or_later) {
+ --skip This test is not for MariaDB 5.x, MariaDB 10.0.x nor 10.1.x
+ }
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_2_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_2_or_later.inc
new file mode 100644
index 00000000000..5f67748a179
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_10_2_or_later.inc
@@ -0,0 +1,24 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_version.inc
+--source ../../include/mroonga/check_mariadb.inc
+
+if ($mariadb) {
+ if ($version_10_2_or_later) {
+ --skip This test is not for MariaDB 10.2.x or later
+ }
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_100_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_5_5.inc
index 9fbfd222df4..0695b96fa23 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_100_or_later.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mariadb_5_5.inc
@@ -1,4 +1,4 @@
-# Copyright(C) 2012-2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,13 +12,13 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_version.inc
--source ../../include/mroonga/check_mariadb.inc
-if ($version_100_or_later) {
+if ($version_5_5) {
if ($mariadb) {
- skip This test is not for MariaDB 10.x;
+ --skip This test is not for MariaDB 5.5.x
}
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_55.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_5_5.inc
index e29fae84d46..633450e9c0d 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_55.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_5_5.inc
@@ -1,4 +1,4 @@
-# Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2014-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,13 +12,13 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_version.inc
--source ../../include/mroonga/check_mariadb.inc
-if ($version_55) {
+if ($version_5_5) {
if (!$mariadb) {
- skip This test is not for MySQL 5.5.x;
+ --skip This test is not for MySQL 5.5.x
}
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_57.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_5_7.inc
index 39ee22834e7..e984d60f760 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_57.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_5_7.inc
@@ -12,13 +12,13 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_version.inc
--source ../../include/mroonga/check_mariadb.inc
-if ($version_57) {
+if ($version_5_7) {
if (!$mariadb) {
- skip This test is not for MySQL 5.7.x;
+ --skip This test is not for MySQL 5.7.x
}
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_5_7_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_5_7_or_later.inc
new file mode 100644
index 00000000000..075e6044197
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_mysql_5_7_or_later.inc
@@ -0,0 +1,24 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_version.inc
+--source ../../include/mroonga/check_mariadb.inc
+
+if ($version_5_7_or_later) {
+ if (!$mariadb) {
+ --skip This test is not for MySQL 5.7.x or later
+ }
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_osx.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_osx.inc
index 45a70d34ad7..c2979589211 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_osx.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_osx.inc
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_osx.inc
if ($VERSION_COMPILE_OS_OSX) {
- skip This test is not for OSX;
+ --skip This test is not for OSX
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_signed_64bit_time_t.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_signed_64bit_time_t.inc
new file mode 100644
index 00000000000..1ba1d09be60
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_signed_64bit_time_t.inc
@@ -0,0 +1,28 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_64bit.inc
+--source ../../include/mroonga/check_osx.inc
+
+if ($version_compile_64bit) {
+ --skip This test is for environment that doesn't have signed 64bit time_t
+}
+
+if ($version_compile_os_osx) {
+ if (!$version_compile_os_osx_10_8_or_later) {
+ --skip This test is not for OS X 10.7 or earlier that isn't detected signed 64bit time_t availability
+ }
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_solaris.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_solaris.inc
new file mode 100644
index 00000000000..6bf74224923
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_solaris.inc
@@ -0,0 +1,21 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_solaris.inc
+
+if ($version_compile_os_solaris) {
+ --skip This test is not for Solaris
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_solaris10.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_solaris10.inc
deleted file mode 100644
index 7cee5c38c53..00000000000
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_solaris10.inc
+++ /dev/null
@@ -1,3 +0,0 @@
-if (`SELECT @@version_compile_os='solaris10'`) {
- skip This test is not for Solaris 10;
-}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_strict_sql_mode.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_strict_sql_mode.inc
new file mode 100644
index 00000000000..fc0d665b302
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/skip_strict_sql_mode.inc
@@ -0,0 +1,21 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_strict_sql_mode.inc
+
+if ($strict_sql_mode) {
+ --skip This test is not for STRICT_ALL_TABLES nor STRICT_TRANS_TABLES
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_lz4.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_lz4.inc
index 5e21a446f1b..249c6b59b17 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_lz4.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_lz4.inc
@@ -12,11 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_libgroonga_support_lz4.inc
if (!$libgroonga_support_lz4) {
--source ../../include/mroonga/have_mroonga_deinit.inc
- skip "This test is for libgroonga supports lz4";
+ --skip This test is for libgroonga supports lz4
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zlib.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zlib.inc
index d04826aa7dd..fd8b9e998a0 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zlib.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zlib.inc
@@ -12,11 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_libgroonga_support_zlib.inc
if (!$libgroonga_support_zlib) {
--source ../../include/mroonga/have_mroonga_deinit.inc
- skip "This test is for libgroonga supports zlib";
+ --skip This test is for libgroonga supports zlib
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zstd.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zstd.inc
new file mode 100644
index 00000000000..0e7ca446020
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zstd.inc
@@ -0,0 +1,22 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_libgroonga_support_zstd.inc
+
+if (!$libgroonga_support_zstd) {
+ --source ../../include/mroonga/have_mroonga_deinit.inc
+ --skip This test is for libgroonga supports zstd
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/unload_mroonga_functions.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/unload_mroonga_functions.inc
index 8d0d13f9125..cbe345a7e04 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/unload_mroonga_functions.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/unload_mroonga_functions.inc
@@ -1,4 +1,4 @@
-# Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2013-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,11 +12,15 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--disable_query_log
DROP FUNCTION last_insert_grn_id;
DROP FUNCTION mroonga_snippet;
DROP FUNCTION mroonga_command;
DROP FUNCTION mroonga_escape;
+DROP FUNCTION mroonga_snippet_html;
+DROP FUNCTION mroonga_normalize;
+DROP FUNCTION mroonga_highlight_html;
+DROP FUNCTION mroonga_query_expand;
--enable_query_log
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_lz4.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_lz4.inc
index dcc049078f8..210058edc3c 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_lz4.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_lz4.inc
@@ -12,11 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_libgroonga_support_lz4.inc
if ($libgroonga_support_lz4) {
--source ../../include/mroonga/have_mroonga_deinit.inc
- skip "This test is for libgroonga doesn't support lz4";
+ --skip This test is for libgroonga doesn't support lz4
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zlib.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zlib.inc
index 7533f786f22..cb00da15a87 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zlib.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zlib.inc
@@ -12,11 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/check_libgroonga_support_zlib.inc
if ($libgroonga_support_zlib) {
--source ../../include/mroonga/have_mroonga_deinit.inc
- skip "This test is for libgroonga doesn't support zlib";
+ --skip This test is for libgroonga doesn't support zlib
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zstd.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zstd.inc
new file mode 100644
index 00000000000..037e66a9e7c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zstd.inc
@@ -0,0 +1,22 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/check_libgroonga_support_zstd.inc
+
+if ($libgroonga_support_zstd) {
+ --source ../../include/mroonga/have_mroonga_deinit.inc
+ --skip This test is for libgroonga doesn't support zstd
+}
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_after.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_after.result
index 16077d23155..15cd3499d4c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_after.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_after.result
@@ -1,22 +1,22 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-body TEXT
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
-ALTER TABLE diaries ADD title TEXT AFTER id;
+ALTER TABLE diaries ADD title VARCHAR(40) AFTER id;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) values ("groonga (1)", "starting groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_first.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_first.result
index 2e1e87ab722..8b3de1bf7de 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_first.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_first.result
@@ -1,22 +1,22 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-body TEXT
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
-ALTER TABLE diaries ADD title TEXT FIRST;
+ALTER TABLE diaries ADD title VARCHAR(40) FIRST;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
- `title` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) values ("groonga (1)", "starting groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_comment.result
index e441df32c92..de0482e626c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_comment.result
@@ -4,6 +4,11 @@ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
ALTER TABLE tags ADD COLUMN name VARCHAR(64) COMMENT 'flags "COLUMN_VECTOR"';
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
table_create tags TABLE_PAT_KEY UInt32
column_create tags id COLUMN_SCALAR UInt32
column_create tags name COLUMN_VECTOR ShortText
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result
index 6f2a1870ac7..b3c9875faeb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result
@@ -11,6 +11,11 @@ tags CREATE TABLE `tags` (
) ENGINE=Mroonga DEFAULT CHARSET=utf8
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
table_create tags TABLE_PAT_KEY UInt32
column_create tags id COLUMN_SCALAR UInt32
column_create tags name COLUMN_VECTOR ShortText
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result
index 0bd8985f2e8..8a1c18b731d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result
@@ -7,12 +7,17 @@ id INT UNSIGNED PRIMARY KEY
ALTER TABLE bugs ADD COLUMN name VARCHAR(64) COMMENT 'groonga_type "tags"';
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create tags TABLE_PAT_KEY UInt32
-column_create tags id COLUMN_SCALAR UInt32
-
table_create bugs TABLE_PAT_KEY UInt32
column_create bugs id COLUMN_SCALAR UInt32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create tags TABLE_PAT_KEY UInt32
+column_create tags id COLUMN_SCALAR UInt32
+
column_create bugs name COLUMN_SCALAR tags
DROP TABLE bugs;
DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result
index fe484372999..85330471c44 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result
@@ -10,17 +10,21 @@ Table Create Table
bugs CREATE TABLE `bugs` (
`id` int(10) unsigned NOT NULL,
`name` varchar(64) DEFAULT NULL `GROONGA_TYPE`='tags',
- PRIMARY KEY (`id`),
- CONSTRAINT `name` FOREIGN KEY (`name`) REFERENCES `test`.`tags` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
+ PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create tags TABLE_PAT_KEY UInt32
-column_create tags id COLUMN_SCALAR UInt32
-
table_create bugs TABLE_PAT_KEY UInt32
column_create bugs id COLUMN_SCALAR UInt32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create tags TABLE_PAT_KEY UInt32
+column_create tags id COLUMN_SCALAR UInt32
+
column_create bugs name COLUMN_SCALAR tags
DROP TABLE bugs;
DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multibyte_cp932.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multibyte_cp932.result
new file mode 100644
index 00000000000..6fb1a1071f8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multibyte_cp932.result
@@ -0,0 +1,35 @@
+DROP TABLE IF EXISTS users;
+SET NAMES cp932;
+CREATE TABLE users (
+id int PRIMARY KEY
+) DEFAULT CHARSET=cp932;
+ALTER TABLE users
+ADD COLUMN –¼‘O text,
+ADD FULLTEXT INDEX (–¼‘O);
+INSERT INTO users VALUES (1, "‚â‚Ü‚¾");
+INSERT INTO users VALUES (2, "‚½‚È‚©");
+INSERT INTO users VALUES (3, "‚·‚¸‚«");
+SELECT * FROM users;
+id –¼‘O
+1 ‚â‚Ü‚¾
+2 ‚½‚È‚©
+3 ‚·‚¸‚«
+SELECT * FROM users
+WHERE MATCH (–¼‘O) AGAINST ('+‚½‚È‚©' IN BOOLEAN MODE);
+id –¼‘O
+2 ‚½‚È‚©
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+mroonga_command("dump --dump_plugins no --dump_records no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create users TABLE_PAT_KEY Int32
+column_create users @540d@524d COLUMN_SCALAR LongText
+column_create users id COLUMN_SCALAR Int32
+
+table_create users#@540d@524d TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
+
+column_create users#@540d@524d index COLUMN_INDEX|WITH_POSITION users @540d@524d
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multibyte_utf8.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multibyte_utf8.result
new file mode 100644
index 00000000000..70c9ea0c546
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multibyte_utf8.result
@@ -0,0 +1,35 @@
+DROP TABLE IF EXISTS users;
+SET NAMES utf8;
+CREATE TABLE users (
+id int PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+ALTER TABLE users
+ADD COLUMN åå‰ text,
+ADD FULLTEXT INDEX (åå‰);
+INSERT INTO users VALUES (1, "ã‚„ã¾ã ");
+INSERT INTO users VALUES (2, "ãŸãªã‹");
+INSERT INTO users VALUES (3, "ã™ãšã");
+SELECT * FROM users;
+id åå‰
+1 ã‚„ã¾ã 
+2 ãŸãªã‹
+3 ã™ãšã
+SELECT * FROM users
+WHERE MATCH (åå‰) AGAINST ('+ãŸãªã‹' IN BOOLEAN MODE);
+id åå‰
+2 ãŸãªã‹
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+mroonga_command("dump --dump_plugins no --dump_records no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create users TABLE_PAT_KEY Int32
+column_create users @540d@524d COLUMN_SCALAR LongText
+column_create users id COLUMN_SCALAR Int32
+
+table_create users#@540d@524d TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI
+
+column_create users#@540d@524d index COLUMN_INDEX|WITH_POSITION users @540d@524d
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multiple.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multiple.result
index 2222334060c..6c6024e4773 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multiple.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_multiple.result
@@ -1,13 +1,13 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT
+title VARCHAR(40)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title) VALUES ("survey");
@@ -15,7 +15,7 @@ SELECT * FROM diaries;
id title
1 survey
ALTER TABLE diaries
-ADD COLUMN body TEXT FIRST,
+ADD COLUMN body VARCHAR(140) FIRST,
ADD COLUMN published BOOLEAN AFTER id,
ADD COLUMN created_at DATETIME;
UPDATE diaries SET body = "will start groonga!";
@@ -34,10 +34,10 @@ started groonga. 3 0 groonga (2) 2014-02-09 12:19:00
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
- `body` text DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`published` tinyint(1) DEFAULT NULL,
- `title` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_plain.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_plain.result
index a7bb15d5c84..5a5d3715621 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_plain.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_plain.result
@@ -1,20 +1,20 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT
+title VARCHAR(40)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title) VALUES ("survey");
SELECT * FROM diaries;
id title
1 survey
-ALTER TABLE diaries ADD COLUMN body TEXT;
+ALTER TABLE diaries ADD COLUMN body VARCHAR(140);
UPDATE diaries SET body = "will start groonga!";
SELECT * FROM diaries;
id title body
@@ -30,8 +30,8 @@ SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_type_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_type_comment.result
index b4c3044c7d5..5136282687c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_type_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_type_comment.result
@@ -7,12 +7,17 @@ id INT UNSIGNED PRIMARY KEY
ALTER TABLE bugs ADD COLUMN name VARCHAR(64) COMMENT 'type "tags"';
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create tags TABLE_PAT_KEY UInt32
-column_create tags id COLUMN_SCALAR UInt32
-
table_create bugs TABLE_PAT_KEY UInt32
column_create bugs id COLUMN_SCALAR UInt32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create tags TABLE_PAT_KEY UInt32
+column_create tags id COLUMN_SCALAR UInt32
+
column_create bugs name COLUMN_SCALAR tags
DROP TABLE bugs;
DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result
index 65e608dddeb..373c70e81be 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result
@@ -11,7 +11,12 @@ mroonga_command("dump --dump_plugins no")
table_create memos TABLE_NO_KEY
column_create memos content COLUMN_SCALAR ShortText
-table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord
+table_create memos#content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord
-column_create memos-content index COLUMN_INDEX|WITH_POSITION memos content
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create memos#content index COLUMN_INDEX|WITH_POSITION memos content
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_after.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_after.result
index 974cb125626..a9b192e999e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_after.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_after.result
@@ -1,24 +1,24 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
-body TEXT
+title VARCHAR(40),
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
-ALTER TABLE diaries CHANGE body description TEXT AFTER id;
+ALTER TABLE diaries CHANGE body description VARCHAR(140) AFTER id;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `description` text DEFAULT NULL,
- `title` text DEFAULT NULL,
+ `description` varchar(140) DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, description) values ("groonga (1)", "starting groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_first.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_first.result
index 5baf7cdb125..4faf39ad1ad 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_first.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_first.result
@@ -1,24 +1,24 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
-body TEXT
+title VARCHAR(40),
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
-ALTER TABLE diaries CHANGE body description TEXT FIRST;
+ALTER TABLE diaries CHANGE body description VARCHAR(140) FIRST;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
- `description` text DEFAULT NULL,
+ `description` varchar(140) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, description) values ("groonga (1)", "starting groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_multiple.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_multiple.result
index c8360f2fbfa..f640e8de23b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_multiple.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_multiple.result
@@ -1,34 +1,32 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
-body TEXT
+title VARCHAR(40),
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
ALTER TABLE diaries
-CHANGE body description TEXT FIRST,
-CHANGE title subject TEXT AFTER internal_id,
-CHANGE id internal_id INT;
+CHANGE body description VARCHAR(140) FIRST,
+CHANGE title subject VARCHAR(40) AFTER internal_id,
+CHANGE id internal_id INT AUTO_INCREMENT;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
- `description` text DEFAULT NULL,
- `internal_id` int(11) NOT NULL,
- `subject` text DEFAULT NULL,
+ `description` varchar(140) DEFAULT NULL,
+ `internal_id` int(11) NOT NULL AUTO_INCREMENT,
+ `subject` varchar(40) DEFAULT NULL,
PRIMARY KEY (`internal_id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT IGNORE INTO diaries (subject, description)
VALUES ("groonga (1)", "starting groonga.");
-Warnings:
-Warning 1364 Field 'internal_id' doesn't have a default value
SELECT * FROM diaries;
description internal_id subject
-starting groonga. 0 groonga (1)
+starting groonga. 1 groonga (1)
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_no_order.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_no_order.result
index de6f0e3abc0..d49acc52611 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_no_order.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_column_rename_no_order.result
@@ -1,24 +1,24 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
-body TEXT
+title VARCHAR(40),
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
-ALTER TABLE diaries CHANGE body description TEXT;
+ALTER TABLE diaries CHANGE body description VARCHAR(140);
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `description` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `description` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, description) values ("groonga (1)", "starting groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_engine_decimal.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_engine_decimal.result
index cf4fc866335..dc2ae025336 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_engine_decimal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_engine_decimal.result
@@ -1,37 +1,34 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
temperature DECIMAL(6, 3)
) ENGINE InnoDB DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
`temperature` decimal(6,3) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
-INSERT INTO diaries (title, temperature) VALUES ("clear day", 21.281);
+INSERT INTO diaries (temperature) VALUES (21.281);
SELECT * FROM diaries;
-id title temperature
-1 clear day 21.281
+id temperature
+1 21.281
ALTER TABLE diaries ENGINE = mroonga;
SELECT * FROM diaries;
-id title temperature
-1 clear day 21.281
-INSERT INTO diaries (title, temperature) VALUES ("rainy day", 14.213);
-INSERT INTO diaries (title, temperature) VALUES ("cloudy day", 17.821);
+id temperature
+1 21.281
+INSERT INTO diaries (temperature) VALUES (14.213);
+INSERT INTO diaries (temperature) VALUES (17.821);
SELECT * FROM diaries;
-id title temperature
-1 clear day 21.281
-2 rainy day 14.213
-3 cloudy day 17.821
+id temperature
+1 21.281
+2 14.213
+3 17.821
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
`temperature` decimal(6,3) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_engine.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_engine_fulltext_index.result
index fb1cb9b5a93..706764a5105 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_engine.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_engine_fulltext_index.result
@@ -6,16 +6,11 @@ body TEXT,
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) ENGINE MyISAM DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8
+SELECT table_name, engine
+FROM information_schema.tables
+WHERE table_name = 'diaries';
+table_name engine
+diaries MyISAM
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
SELECT * FROM diaries
@@ -24,16 +19,11 @@ MATCH(body) AGAINST("groonga" IN BOOLEAN MODE);
id title body
1 survey will start groonga!
ALTER TABLE diaries ENGINE = mroonga;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
+SELECT table_name, engine
+FROM information_schema.tables
+WHERE table_name = 'diaries';
+table_name engine
+diaries Mroonga
SELECT * FROM diaries
WHERE MATCH(title) AGAINST("survey" IN BOOLEAN MODE) AND
MATCH(body) AGAINST("groonga" IN BOOLEAN MODE);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result
index 60d302cc6a5..9fc3b408474 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result
@@ -12,14 +12,19 @@ FULLTEXT INDEX (content) COMMENT 'table "terms"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI
-column_create terms is_stop_word COLUMN_SCALAR Int8
-column_create terms term COLUMN_SCALAR ShortText
-
table_create memos TABLE_PAT_KEY Int32
column_create memos content COLUMN_SCALAR LongText
column_create memos id COLUMN_SCALAR Int32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI
+column_create terms is_stop_word COLUMN_SCALAR Int8
+column_create terms term COLUMN_SCALAR ShortText
+
column_create terms content COLUMN_INDEX|WITH_POSITION memos content
ALTER TABLE terms COMMENT='default_tokenizer "TokenBigram", token_filters "TokenFilterStopWord"';
SELECT mroonga_command("dump --dump_plugins no");
@@ -28,6 +33,11 @@ table_create memos TABLE_PAT_KEY Int32
column_create memos content COLUMN_SCALAR LongText
column_create memos id COLUMN_SCALAR Int32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord
column_create terms is_stop_word COLUMN_SCALAR Int8
column_create terms term COLUMN_SCALAR ShortText
@@ -39,6 +49,11 @@ table_create memos TABLE_PAT_KEY Int32
column_create memos content COLUMN_SCALAR LongText
column_create memos id COLUMN_SCALAR Int32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord
column_create terms is_stop_word COLUMN_SCALAR Int8
column_create terms term COLUMN_SCALAR ShortText
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_disable_keys_fulltext_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_disable_keys_fulltext_table.result
index ba6cf6c24ed..7416481e390 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_disable_keys_fulltext_table.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_disable_keys_fulltext_table.result
@@ -10,22 +10,32 @@ FULLTEXT INDEX content_index (content) COMMENT 'table "terms"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
-column_create terms term COLUMN_SCALAR ShortText
-
table_create memos TABLE_PAT_KEY Int32
column_create memos content COLUMN_SCALAR LongText
column_create memos id COLUMN_SCALAR Int32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
+column_create terms term COLUMN_SCALAR ShortText
+
column_create terms content_index COLUMN_INDEX|WITH_POSITION memos content
ALTER TABLE memos DISABLE KEYS;
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
-column_create terms term COLUMN_SCALAR ShortText
-
table_create memos TABLE_PAT_KEY Int32
column_create memos content COLUMN_SCALAR LongText
column_create memos id COLUMN_SCALAR Int32
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
+column_create terms term COLUMN_SCALAR ShortText
DROP TABLE memos;
DROP TABLE terms;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_drop_column_multiple.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_drop_column_multiple.result
index 26c429846ea..a8b8edf2f63 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_drop_column_multiple.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_drop_column_multiple.result
@@ -1,15 +1,15 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
-body TEXT
+title VARCHAR(40),
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_drop_column_one.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_drop_column_one.result
index c911eecda3a..569bba2f557 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_drop_column_one.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_drop_column_one.result
@@ -1,15 +1,15 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
-body TEXT
+title VARCHAR(40),
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
@@ -21,7 +21,7 @@ SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
SELECT * FROM diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_enable_keys_fulltext_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_enable_keys_fulltext_table.result
index 452caa574f9..7b3b2863e5f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_enable_keys_fulltext_table.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_enable_keys_fulltext_table.result
@@ -11,22 +11,32 @@ FULLTEXT INDEX content_index (content) COMMENT 'table "terms"'
ALTER TABLE memos DISABLE KEYS;
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
-column_create terms term COLUMN_SCALAR ShortText
-
table_create memos TABLE_PAT_KEY Int32
column_create memos content COLUMN_SCALAR LongText
column_create memos id COLUMN_SCALAR Int32
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
+column_create terms term COLUMN_SCALAR ShortText
ALTER TABLE memos ENABLE KEYS;
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
-column_create terms term COLUMN_SCALAR ShortText
-
table_create memos TABLE_PAT_KEY Int32
column_create memos content COLUMN_SCALAR LongText
column_create memos id COLUMN_SCALAR Int32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
+column_create terms term COLUMN_SCALAR ShortText
+
column_create terms content_index COLUMN_INDEX|WITH_POSITION memos content
DROP TABLE memos;
DROP TABLE terms;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_fulltext_add_normal.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_fulltext_add_normal.result
index 5910f28ddb3..cf6840a9897 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_fulltext_add_normal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_fulltext_add_normal.result
@@ -7,15 +7,7 @@ INSERT INTO memos (content) values ("Starting Groonga...");
INSERT INTO memos (content) values ("Started Groonga.");
INSERT INTO memos (content) values ("Starting Mroonga...");
ALTER TABLE memos ADD FULLTEXT INDEX content_index (content);
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `content_index` (`content`)
-) ENGINE=Mroonga AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
-SELECT * FROM memos WHERE MATCH(content) AGAINST("groonga");
+SELECT * FROM memos WHERE MATCH(content) AGAINST("+groonga" IN BOOLEAN MODE);
id content
1 Starting Groonga...
2 Started Groonga.
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_after.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_after.result
index 2893f417f41..9b7040bd5c8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_after.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_after.result
@@ -1,28 +1,28 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
-body TEXT
+title VARCHAR(40),
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) values ("groonga (1)", "starting groonga.");
SELECT * FROM diaries;
id title body
1 groonga (1) starting groonga.
-ALTER TABLE diaries MODIFY body TEXT AFTER id;
+ALTER TABLE diaries MODIFY body VARCHAR(140) AFTER id;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- `title` text DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) values ("groonga (2)", "started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_first.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_first.result
index a26249a81e7..f6b3df92c67 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_first.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_first.result
@@ -1,28 +1,28 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
-body TEXT
+title VARCHAR(40),
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) values ("groonga (1)", "starting groonga.");
SELECT * FROM diaries;
id title body
1 groonga (1) starting groonga.
-ALTER TABLE diaries MODIFY body TEXT FIRST;
+ALTER TABLE diaries MODIFY body VARCHAR(140) FIRST;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
- `body` text DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) values ("groonga (2)", "started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_no_order.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_no_order.result
index 6d3f4b83f37..e156a7fda03 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_no_order.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_modify_column_no_order.result
@@ -1,15 +1,15 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
-body TEXT
+title VARCHAR(40),
+body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) values ("groonga (1)", "starting groonga.");
@@ -22,7 +22,7 @@ Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(100) DEFAULT NULL,
- `body` text DEFAULT NULL,
+ `body` varchar(140) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) values ("groonga (2)", "started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_recreate_anonymous_index_at_once.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_recreate_anonymous_index_at_once.result
index b96bf53ee1c..6ee8f8bafc1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_recreate_anonymous_index_at_once.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_recreate_anonymous_index_at_once.result
@@ -5,15 +5,6 @@ title TEXT,
body TEXT,
FULLTEXT INDEX (body)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("survey", "will start mroonga!");
SELECT * FROM diaries;
@@ -35,13 +26,4 @@ SELECT * FROM diaries
WHERE MATCH (body) AGAINST ("+groonga" IN BOOLEAN MODE);
id title body
1 survey will start groonga!
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body` (`body`)
-) ENGINE=Mroonga AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_rename_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_rename_table.result
index 043ef2db430..84861ea7162 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_rename_table.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_rename_table.result
@@ -6,16 +6,11 @@ body TEXT,
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
+SELECT table_name, engine
+FROM information_schema.tables
+WHERE table_name = 'diaries';
+table_name engine
+diaries Mroonga
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
SELECT * FROM diaries;
id title body
@@ -32,14 +27,9 @@ SELECT * FROM memos
WHERE MATCH(title) AGAINST("groonga") AND
MATCH(body) AGAINST("starting");
id title body
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
+SELECT table_name, engine
+FROM information_schema.tables
+WHERE table_name = 'memos';
+table_name engine
+memos Mroonga
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_spatial.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_spatial.result
index 0ec5b2cebe8..ac1a096de4a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_spatial.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_spatial.result
@@ -1,7 +1,7 @@
DROP TABLE IF EXISTS shops;
CREATE TABLE shops (
id INT PRIMARY KEY AUTO_INCREMENT,
-name TEXT,
+name VARCHAR(40),
location GEOMETRY NOT NULL
);
INSERT INTO shops (name, location)
@@ -124,7 +124,7 @@ SHOW CREATE TABLE shops;
Table Create Table
shops CREATE TABLE `shops` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `name` text DEFAULT NULL,
+ `name` varchar(40) DEFAULT NULL,
`location` geometry NOT NULL,
PRIMARY KEY (`id`),
SPATIAL KEY `location_index` (`location`)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/check_table_broken.result b/storage/mroonga/mysql-test/mroonga/storage/r/check_table_broken.result
new file mode 100644
index 00000000000..4926a72a77a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/check_table_broken.result
@@ -0,0 +1,18 @@
+SET NAMES UTF8;
+CREATE DATABASE check_test;
+USE check_test;
+CREATE TABLE diaries (
+title TEXT,
+FULLTEXT INDEX (title)
+);
+INSERT INTO diaries VALUES ('Hello');
+FLUSH TABLES;
+CHECK TABLE diaries;
+Table Op Msg_type Msg_text
+check_test.diaries check error Corrupt
+REPAIR TABLE diaries;
+Table Op Msg_type Msg_text
+check_test.diaries repair status OK
+DROP TABLE diaries;
+DROP DATABASE check_test;
+USE test;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/check_table_not_broken.result b/storage/mroonga/mysql-test/mroonga/storage/r/check_table_not_broken.result
new file mode 100644
index 00000000000..def3368ecac
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/check_table_not_broken.result
@@ -0,0 +1,13 @@
+SET NAMES UTF8;
+DROP TABLE IF EXISTS diaries;
+CREATE TABLE diaries (
+title TEXT
+);
+INSERT INTO diaries VALUES ('Hello');
+CHECK TABLE diaries;
+Table Op Msg_type Msg_text
+test.diaries check status OK
+SELECT * FROM diaries;
+title
+Hello
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_date_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_date_with_index.result
index ab03fe97083..9aec8dd6e79 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_date_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_date_with_index.result
@@ -1,7 +1,7 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
+title VARCHAR(40),
created_at DATE,
KEY (created_at)
) DEFAULT CHARSET UTF8;
@@ -9,7 +9,7 @@ SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
`created_at` date DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `created_at` (`created_at`)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_date_without_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_date_without_index.result
index be5aba2020a..4d2166eca0a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_date_without_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_date_without_index.result
@@ -1,14 +1,14 @@
DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
-title TEXT,
+title VARCHAR(40),
created_at DATE
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
+ `title` varchar(40) DEFAULT NULL,
`created_at` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_2038.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_2038.result
index c5764cc110c..712d87ca251 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_2038.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_2038.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
VALUES ('2038-01-18 03:14:07', '2038-01-18 03:14:07');
INSERT IGNORE INTO diaries (title, created_at)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_before_unix_epoch.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_before_unix_epoch.result
index a85d60af383..85f091cca86 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_before_unix_epoch.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_before_unix_epoch.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT IGNORE INTO diaries (title, created_at)
VALUES ('1000-01-01 00:00:00', '1000-01-01 00:00:00');
Warnings:
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_max.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_max.result
index 71dfa08c762..9d9e2f610fa 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_max.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_max.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT IGNORE INTO diaries (title, created_at)
VALUES ('9999-12-31 23:59:59', '9999-12-31 23:59:59');
Warnings:
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_out_of_range.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_out_of_range.result
index 6044e24ad61..99611268724 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_out_of_range.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_out_of_range.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT IGNORE INTO diaries (title, created_at)
VALUES ('2012', '2012');
Warnings:
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_2038.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_2038.result
index f2bc6332be6..f0f03a82c98 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_2038.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_2038.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
VALUES ('2038-01-19 03:14:07', '2038-01-19 03:14:07');
INSERT INTO diaries (title, created_at)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_before_unix_epoch.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_before_unix_epoch.result
index 778ecf29dca..8a775960ef7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_before_unix_epoch.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_before_unix_epoch.result
@@ -4,17 +4,9 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
-VALUES ('1000-01-01 00:00:00', '1000-01-01 00:00:00');
+VALUES ('1000-01-02 00:00:00', '1000-01-02 00:00:00');
SELECT * FROM diaries;
id title created_at
-1 1000-01-01 00:00:00 1000-01-01 00:00:00
+1 1000-01-02 00:00:00 1000-01-02 00:00:00
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_max.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_max.result
index 1477f32ce67..44d20d972f2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_max.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_max.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
VALUES ('9999-12-31 23:59:59', '9999-12-31 23:59:59');
SELECT * FROM diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_strict_sql_mode_out_of_range.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_strict_sql_mode_out_of_range.result
new file mode 100644
index 00000000000..2d5e5e64147
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_strict_sql_mode_out_of_range.result
@@ -0,0 +1,12 @@
+DROP TABLE IF EXISTS diaries;
+CREATE TABLE diaries (
+id INT PRIMARY KEY AUTO_INCREMENT,
+title TEXT,
+created_at DATETIME
+) DEFAULT CHARSET UTF8;
+INSERT INTO diaries (title, created_at)
+VALUES ('2012', '2012');
+ERROR 22007: Incorrect datetime value: '2012' for column 'created_at' at row 1
+SELECT * FROM diaries;
+id title created_at
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_55_out_of_range.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_5_5_out_of_range.result
index 733217fda85..21e715e1f63 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_55_out_of_range.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_5_5_out_of_range.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
VALUES ('2012', '2012');
Warnings:
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_56_or_later_out_of_range.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_5_6_or_later_out_of_range.result
index db22d3d4c7c..3500d651765 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_56_or_later_out_of_range.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_version_5_6_or_later_out_of_range.result
@@ -4,16 +4,8 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
-SET STATEMENT sql_mode = '' FOR
-INSERT INTO diaries (title, created_at) VALUES ('2012', '2012');
+INSERT INTO diaries (title, created_at)
+VALUES ('2012', '2012');
Warnings:
Warning 1265 Data truncated for column 'created_at' at row 1
Warning 1265 Data truncated for column 'created_at' at row 1
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_with_index.result
index db44acf133c..e7094fd4e55 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_with_index.result
@@ -5,15 +5,6 @@ title TEXT,
created_at DATETIME(6),
KEY (created_at)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime(6) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `created_at` (`created_at`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
VALUES ("clear day", "2012-01-29 21:51:01.111111");
INSERT INTO diaries (title, created_at)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_without_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_without_index.result
index 21d18bcfe7d..028fb2577a2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_without_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_without_index.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME(6)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime(6) DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
VALUES ("clear day", "2012-01-29 21:51:01.111111");
INSERT INTO diaries (title, created_at)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_freebsd_before_unix_epoch.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_freebsd_before_unix_epoch.result
index 10824d7c28d..a48be4da873 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_freebsd_before_unix_epoch.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_freebsd_before_unix_epoch.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
VALUES ('1000-01-01 00:00:00', '1000-01-01 00:00:00');
Warnings:
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date_strict.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mariadb_10_2_or_later_zero_date.result
index c4d73e2f57d..ffd6a707605 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date_strict.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mariadb_10_2_or_later_zero_date.result
@@ -3,17 +3,8 @@ CREATE TABLE timestamps (
id INT PRIMARY KEY AUTO_INCREMENT,
create_dt DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE timestamps;
-Table Create Table
-timestamps CREATE TABLE `timestamps` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `create_dt` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
-SET sql_mode='STRICT_TRANS_TABLES';
INSERT INTO timestamps (create_dt) VALUES ("0000-00-00 00:00:00");
ERROR 22003: Out of range value for column 'create_dt' at row 1
-SET sql_mode=default;
SELECT * FROM timestamps;
id create_dt
INSERT INTO timestamps (create_dt) VALUES ("2015-06-17 00:00:00");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mariadb_10_2_or_later_zero_month_day.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mariadb_10_2_or_later_zero_month_day.result
new file mode 100644
index 00000000000..61d2ed8dfd3
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mariadb_10_2_or_later_zero_month_day.result
@@ -0,0 +1,12 @@
+DROP TABLE IF EXISTS timestamps;
+CREATE TABLE timestamps (
+id INT PRIMARY KEY AUTO_INCREMENT,
+create_dt DATETIME
+) DEFAULT CHARSET UTF8;
+INSERT INTO timestamps (create_dt) VALUES ("2012-00-01 00:00:00");
+ERROR 22003: Out of range value for column 'create_dt' at row 1
+INSERT INTO timestamps (create_dt) VALUES ("2012-01-00 00:00:00");
+ERROR 22003: Out of range value for column 'create_dt' at row 1
+SELECT * FROM timestamps;
+id create_dt
+DROP TABLE timestamps;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mysql_5_7_or_later_zero_date.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mysql_5_7_or_later_zero_date.result
new file mode 100644
index 00000000000..0ca19e548f3
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mysql_5_7_or_later_zero_date.result
@@ -0,0 +1,14 @@
+DROP TABLE IF EXISTS timestamps;
+CREATE TABLE timestamps (
+id INT PRIMARY KEY AUTO_INCREMENT,
+create_dt DATETIME
+) DEFAULT CHARSET UTF8;
+INSERT INTO timestamps (create_dt) VALUES ("0000-00-00 00:00:00");
+ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'create_dt' at row 1
+SELECT * FROM timestamps;
+id create_dt
+INSERT INTO timestamps (create_dt) VALUES ("2015-06-17 00:00:00");
+SELECT * FROM timestamps;
+id create_dt
+1 2015-06-17 00:00:00
+DROP TABLE timestamps;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mysql_5_7_or_later_zero_month_day.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mysql_5_7_or_later_zero_month_day.result
new file mode 100644
index 00000000000..94479c2307d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_mysql_5_7_or_later_zero_month_day.result
@@ -0,0 +1,12 @@
+DROP TABLE IF EXISTS timestamps;
+CREATE TABLE timestamps (
+id INT PRIMARY KEY AUTO_INCREMENT,
+create_dt DATETIME
+) DEFAULT CHARSET UTF8;
+INSERT INTO timestamps (create_dt) VALUES ("2012-00-01 00:00:00");
+ERROR 22007: Incorrect datetime value: '2012-00-01 00:00:00' for column 'create_dt' at row 1
+INSERT INTO timestamps (create_dt) VALUES ("2012-01-00 00:00:00");
+ERROR 22007: Incorrect datetime value: '2012-01-00 00:00:00' for column 'create_dt' at row 1
+SELECT * FROM timestamps;
+id create_dt
+DROP TABLE timestamps;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_null.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_null.result
index 849d7d833b4..510fa2dc061 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_null.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_null.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
VALUES ('NULL', NULL);
SELECT * FROM diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_with_index.result
index 9c460234261..6f79b31fe24 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_with_index.result
@@ -5,15 +5,6 @@ title TEXT,
created_at DATETIME,
KEY (created_at)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `created_at` (`created_at`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
VALUES ("clear day", "2012-01-29 21:51:01");
INSERT INTO diaries (title, created_at)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_without_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_without_index.result
index b6c2b882c8f..8a45ece7813 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_without_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_without_index.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at)
VALUES ("clear day", "2012-01-29 21:51:01");
INSERT INTO diaries (title, created_at)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date.result
index 4e05f0a2c52..659c574202a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date.result
@@ -3,27 +3,14 @@ CREATE TABLE timestamps (
id INT PRIMARY KEY AUTO_INCREMENT,
create_dt DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE timestamps;
-Table Create Table
-timestamps CREATE TABLE `timestamps` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `create_dt` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
-SET sql_mode='';
-INSERT INTO timestamps (create_dt) VALUES ("2012-00-01 00:00:00");
-Warnings:
-Warning 1265 Data truncated for column 'create_dt' at row 1
-INSERT INTO timestamps (create_dt) VALUES ("2012-01-00 00:00:00");
-Warnings:
-Warning 1265 Data truncated for column 'create_dt' at row 1
-SET sql_mode = DEFAULT;
+SET sql_mode='STRICT_TRANS_TABLES';
+INSERT INTO timestamps (create_dt) VALUES ("0000-00-00 00:00:00");
+ERROR 22003: Out of range value for column 'create_dt' at row 1
+SET sql_mode=default;
SELECT * FROM timestamps;
id create_dt
-1 2012-01-01 00:00:00
-2 2012-01-01 00:00:00
-SELECT * FROM timestamps WHERE create_dt = "2012-01-01 00:00:00";
+INSERT INTO timestamps (create_dt) VALUES ("2015-06-17 00:00:00");
+SELECT * FROM timestamps;
id create_dt
-1 2012-01-01 00:00:00
-2 2012-01-01 00:00:00
+2 2015-06-17 00:00:00
DROP TABLE timestamps;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_month_day.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_month_day.result
new file mode 100644
index 00000000000..03633a50b7a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_month_day.result
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS timestamps;
+CREATE TABLE timestamps (
+id INT PRIMARY KEY AUTO_INCREMENT,
+create_dt DATETIME
+) DEFAULT CHARSET UTF8;
+INSERT INTO timestamps (create_dt) VALUES ("2012-00-01 00:00:00");
+Warnings:
+Warning 1265 Data truncated for column 'create_dt' at row 1
+INSERT INTO timestamps (create_dt) VALUES ("2012-01-00 00:00:00");
+Warnings:
+Warning 1265 Data truncated for column 'create_dt' at row 1
+SELECT * FROM timestamps;
+id create_dt
+1 2012-01-01 00:00:00
+2 2012-01-01 00:00:00
+SELECT * FROM timestamps WHERE create_dt = "2012-01-01 00:00:00";
+id create_dt
+1 2012-01-01 00:00:00
+2 2012-01-01 00:00:00
+DROP TABLE timestamps;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_fractional_seconds_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_fractional_seconds_with_index.result
index 8dc2d847acc..196e4b80f60 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_fractional_seconds_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_fractional_seconds_with_index.result
@@ -5,15 +5,6 @@ title TEXT,
temperature DECIMAL(6, 3),
KEY (temperature)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `temperature` decimal(6,3) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `temperature` (`temperature`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, temperature) VALUES ("clear day", 21.281);
INSERT INTO diaries (title, temperature) VALUES ("rainy day", 14.213);
INSERT INTO diaries (title, temperature) VALUES ("cloudy day", 17.821);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_fractional_seconds_without_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_fractional_seconds_without_index.result
index 0b3fd4c53e1..b67846bb29c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_fractional_seconds_without_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_fractional_seconds_without_index.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
temperature DECIMAL(6, 3)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `temperature` decimal(6,3) DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, temperature) VALUES ("clear day", 21.281);
INSERT INTO diaries (title, temperature) VALUES ("rainy day", 14.213);
INSERT INTO diaries (title, temperature) VALUES ("cloudy day", 17.821);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_with_index.result
index 97eda9f237a..620e9b6906c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_with_index.result
@@ -5,15 +5,6 @@ title TEXT,
temperature DECIMAL,
KEY (temperature)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `temperature` decimal(10,0) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `temperature` (`temperature`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, temperature) VALUES ("clear day", 21);
INSERT INTO diaries (title, temperature) VALUES ("rainy day", 14);
INSERT INTO diaries (title, temperature) VALUES ("cloudy day", 17);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_without_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_without_index.result
index b635f4db2b7..1ba47b3494a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_without_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_decimal_without_index.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
temperature DECIMAL
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `temperature` decimal(10,0) DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, temperature) VALUES ("clear day", 21);
INSERT INTO diaries (title, temperature) VALUES ("rainy day", 14);
INSERT INTO diaries (title, temperature) VALUES ("cloudy day", 17);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_add_column.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_add_column.result
new file mode 100644
index 00000000000..20213f0cbf8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_add_column.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+ALTER TABLE logs ADD COLUMN message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED;
+ALTER TABLE logs ADD FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"';
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "restart"} "restart"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_delete.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_delete.result
new file mode 100644
index 00000000000..1ee7d8f6570
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_delete.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+DELETE FROM logs WHERE id = 1;
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+id record message
+2 {"level": "info", "message": "restart"} "restart"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_drop_column.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_drop_column.result
new file mode 100644
index 00000000000..5b51851660e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_drop_column.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+ALTER TABLE logs DROP COLUMN message;
+SELECT * FROM logs;
+id record
+1 {"level": "info", "message": "start"}
+2 {"level": "info", "message": "restart"}
+3 {"level": "warn", "message": "abort"}
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_insert.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_insert.result
new file mode 100644
index 00000000000..ff22175ec06
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_insert.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "restart"} "restart"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_reindex.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_reindex.result
new file mode 100644
index 00000000000..fac82467712
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_reindex.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+ALTER TABLE logs DISABLE KEYS;
+ALTER TABLE logs ENABLE KEYS;
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "restart"} "restart"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_update.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_update.result
new file mode 100644
index 00000000000..71fc442dd6f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_update.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+UPDATE logs SET record = '{"level": "info", "message": "shutdown"}' WHERE id = 2;
+SELECT * FROM logs WHERE MATCH(message) AGAINST("hut" IN BOOLEAN MODE);
+id record message
+2 {"level": "info", "message": "shutdown"} "shutdown"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_add_column.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_add_column.result
new file mode 100644
index 00000000000..27c9effc2ba
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_add_column.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+ALTER TABLE logs ADD COLUMN message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL;
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+SELECT * FROM logs;
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "restart"} "restart"
+3 {"level": "warn", "message": "abort"} "abort"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_delete.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_delete.result
new file mode 100644
index 00000000000..260c774e200
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_delete.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+DELETE FROM logs WHERE id = 1;
+SELECT * FROM logs;
+id record message
+2 {"level": "info", "message": "restart"} "restart"
+3 {"level": "warn", "message": "abort"} "abort"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_drop_column.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_drop_column.result
new file mode 100644
index 00000000000..bc9339ab074
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_drop_column.result
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+ALTER TABLE logs DROP COLUMN message;
+SELECT * FROM logs;
+id record
+1 {"level": "info", "message": "start"}
+2 {"level": "info", "message": "restart"}
+3 {"level": "warn", "message": "abort"}
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_insert.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_insert.result
new file mode 100644
index 00000000000..92463c94595
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_insert.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+SELECT * FROM logs;
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "restart"} "restart"
+3 {"level": "warn", "message": "abort"} "abort"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mariadb_10_2_or_later_add_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mariadb_10_2_or_later_add_index.result
new file mode 100644
index 00000000000..1a502edf29b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mariadb_10_2_or_later_add_index.result
@@ -0,0 +1,9 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+ALTER TABLE logs ADD INDEX (message);
+ERROR HY000: mroonga: storage: failed to create index: Index for virtual generated column is not supported: message
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mariadb_10_2_or_later_create_table_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mariadb_10_2_or_later_create_table_with_index.result
new file mode 100644
index 00000000000..16acc89bf09
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mariadb_10_2_or_later_create_table_with_index.result
@@ -0,0 +1,8 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL,
+FULLTEXT INDEX (message)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+ERROR HY000: mroonga: storage: failed to create index: Index for virtual generated column is not supported: message
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mysql_5_7_or_later_add_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mysql_5_7_or_later_add_index.result
new file mode 100644
index 00000000000..93046e39ba5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_mysql_5_7_or_later_add_index.result
@@ -0,0 +1,9 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+ALTER TABLE logs ADD INDEX (message);
+ERROR HY000: Table storage engine 'Mroonga' does not support the create option 'Index on virtual generated column'
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_update.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_update.result
new file mode 100644
index 00000000000..c4e46d0d4f3
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_virtual_update.result
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+UPDATE logs SET record = '{"level": "info", "message": "shutdown"}' WHERE id = 2;
+SELECT * FROM logs;
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "shutdown"} "shutdown"
+3 {"level": "warn", "message": "abort"} "abort"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_vector_other_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_vector_other_table.result
index 724d20edd62..f9fc8366270 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_vector_other_table.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_vector_other_table.result
@@ -14,12 +14,17 @@ FULLTEXT INDEX bugs_tags_index (tags) COMMENT 'table "tags"'
INSERT INTO bugs (id, tags) VALUES (1, "Linux MySQL groonga");
SELECT mroonga_command("dump --dump_plugins no --dump_records no");
mroonga_command("dump --dump_plugins no --dump_records no")
-table_create tags TABLE_PAT_KEY ShortText --default_tokenizer TokenDelimit
-column_create tags name COLUMN_SCALAR ShortText
-
table_create bugs TABLE_PAT_KEY UInt32
column_create bugs id COLUMN_SCALAR UInt32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create tags TABLE_PAT_KEY ShortText --default_tokenizer TokenDelimit
+column_create tags name COLUMN_SCALAR ShortText
+
column_create bugs tags COLUMN_VECTOR tags
column_create tags bugs_tags_index COLUMN_INDEX|WITH_POSITION bugs tags
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_int_other_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_int_other_table.result
index aa7735ef780..0f57885cdb9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_int_other_table.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_int_other_table.result
@@ -15,15 +15,20 @@ INSERT INTO bugs (id, priority) VALUES (2, 3);
INSERT INTO bugs (id, priority) VALUES (3, -2);
SELECT mroonga_command("dump --dump_plugins no --dump_records no");
mroonga_command("dump --dump_plugins no --dump_records no")
-table_create priorities TABLE_PAT_KEY Int32
-column_create priorities id COLUMN_SCALAR Int32
-
table_create bugs TABLE_PAT_KEY UInt32
column_create bugs id COLUMN_SCALAR UInt32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create priorities TABLE_PAT_KEY Int32
+column_create priorities id COLUMN_SCALAR Int32
+
column_create bugs priority COLUMN_SCALAR priorities
-column_create priorities bugs_priority_index COLUMN_INDEX|WITH_POSITION bugs priority
+column_create priorities bugs_priority_index COLUMN_INDEX bugs priority
SELECT *
FROM bugs
WHERE priority = 3;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_zstd.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_zstd.result
new file mode 100644
index 00000000000..a9c917f8c8f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_zstd.result
@@ -0,0 +1,10 @@
+DROP TABLE IF EXISTS entries;
+CREATE TABLE entries (
+id INT UNSIGNED PRIMARY KEY,
+content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZSTD"'
+) DEFAULT CHARSET=utf8;
+INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!");
+SELECT * FROM entries;
+id content
+1 I found Mroonga that is a MySQL storage engine to use Groonga!
+DROP TABLE entries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_zstd.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_zstd.result
new file mode 100644
index 00000000000..b2bb3b89c13
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_zstd.result
@@ -0,0 +1,12 @@
+DROP TABLE IF EXISTS entries;
+CREATE TABLE entries (
+id INT UNSIGNED PRIMARY KEY,
+content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZSTD"'
+) DEFAULT CHARSET=utf8;
+Warnings:
+Warning 16506 The column flag 'COMPRESS_ZSTD' is unsupported. It is ignored
+INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!");
+SELECT * FROM entries;
+id content
+1 I found Mroonga that is a MySQL storage engine to use Groonga!
+DROP TABLE entries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_vector_reference.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_vector_reference.result
index 515dad1da2e..a6afe72faff 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_vector_reference.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_vector_reference.result
@@ -6,8 +6,15 @@ COLLATE=utf8_bin
COMMENT='default_tokenizer "TokenDelimit"';
CREATE TABLE bugs (
id INT UNSIGNED PRIMARY KEY,
-tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "tags"'
+tags VARCHAR(128) DEFAULT '' COMMENT 'flags "COLUMN_VECTOR", type "tags"'
) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE bugs;
+Table Create Table
+bugs CREATE TABLE `bugs` (
+ `id` int(10) unsigned NOT NULL,
+ `tags` varchar(128) DEFAULT '' COMMENT 'flags "COLUMN_VECTOR", type "tags"',
+ PRIMARY KEY (`id`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO bugs (id, tags) VALUES (1, "Linux MySQL groonga");
SELECT * FROM bugs;
id tags
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_json_insert.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_json_insert.result
new file mode 100644
index 00000000000..e6a3aa5ea89
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_json_insert.result
@@ -0,0 +1,13 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+record JSON
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+INSERT INTO logs VALUES ('{"message": "start"}');
+INSERT INTO logs VALUES ('{"message": "restart"}');
+INSERT INTO logs VALUES ('{"message": "shutdown"}');
+SELECT * FROM logs;
+record
+{"message": "start"}
+{"message": "restart"}
+{"message": "shutdown"}
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_multibyte_cp932.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_multibyte_cp932.result
new file mode 100644
index 00000000000..eb1a08f2cd3
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_multibyte_cp932.result
@@ -0,0 +1,32 @@
+DROP TABLE IF EXISTS users;
+SET NAMES cp932;
+CREATE TABLE users (
+–¼‘O text,
+FULLTEXT INDEX (–¼‘O)
+) DEFAULT CHARSET=cp932;
+INSERT INTO users VALUES ("‚â‚Ü‚¾");
+INSERT INTO users VALUES ("‚½‚È‚©");
+INSERT INTO users VALUES ("‚·‚¸‚«");
+SELECT * FROM users;
+–¼‘O
+‚â‚Ü‚¾
+‚½‚È‚©
+‚·‚¸‚«
+SELECT * FROM users
+WHERE MATCH (–¼‘O) AGAINST ('+‚½‚È‚©' IN BOOLEAN MODE);
+–¼‘O
+‚½‚È‚©
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+mroonga_command("dump --dump_plugins no --dump_records no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create users TABLE_NO_KEY
+column_create users @540d@524d COLUMN_SCALAR LongText
+
+table_create users#@540d@524d TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
+
+column_create users#@540d@524d index COLUMN_INDEX|WITH_POSITION users @540d@524d
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_multibyte_utf8.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_multibyte_utf8.result
new file mode 100644
index 00000000000..6f63b5b3856
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_multibyte_utf8.result
@@ -0,0 +1,32 @@
+DROP TABLE IF EXISTS users;
+SET NAMES utf8;
+CREATE TABLE users (
+åå‰ text,
+FULLTEXT INDEX (åå‰)
+) DEFAULT CHARSET=utf8;
+INSERT INTO users VALUES ("ã‚„ã¾ã ");
+INSERT INTO users VALUES ("ãŸãªã‹");
+INSERT INTO users VALUES ("ã™ãšã");
+SELECT * FROM users;
+åå‰
+ã‚„ã¾ã 
+ãŸãªã‹
+ã™ãšã
+SELECT * FROM users
+WHERE MATCH (åå‰) AGAINST ('+ãŸãªã‹' IN BOOLEAN MODE);
+åå‰
+ãŸãªã‹
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+mroonga_command("dump --dump_plugins no --dump_records no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create users TABLE_NO_KEY
+column_create users @540d@524d COLUMN_SCALAR LongText
+
+table_create users#@540d@524d TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI
+
+column_create users#@540d@524d index COLUMN_INDEX|WITH_POSITION users @540d@524d
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_time_fractional_seconds_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_time_fractional_seconds_with_index.result
index fa631bc8471..35434a00160 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_time_fractional_seconds_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_time_fractional_seconds_with_index.result
@@ -6,16 +6,6 @@ average TIME(6),
max TIME(6),
KEY (average)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE running_records;
-Table Create Table
-running_records CREATE TABLE `running_records` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `average` time(6) DEFAULT NULL,
- `max` time(6) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `average` (`average`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO running_records (title, average, max)
VALUES ("normal condition", "01:00:00.000001", "01:05:00.000001");
INSERT INTO running_records (title, average, max)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_time_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_time_with_index.result
index 3f0b664d4fe..a0b0350a8e3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_time_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_time_with_index.result
@@ -6,16 +6,6 @@ average TIME,
max TIME,
KEY (average)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE running_records;
-Table Create Table
-running_records CREATE TABLE `running_records` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `average` time DEFAULT NULL,
- `max` time DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `average` (`average`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO running_records (title, average, max)
VALUES ("normal condition", "01:00:00", "01:05:00");
INSERT INTO running_records (title, average, max)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_timestamp_fractional_seconds_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_timestamp_fractional_seconds_with_index.result
index cd75598a7ee..7ccb1fa234b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_timestamp_fractional_seconds_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_timestamp_fractional_seconds_with_index.result
@@ -6,16 +6,6 @@ created_at TIMESTAMP(6),
updated_at TIMESTAMP(6),
KEY (updated_at)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6),
- `updated_at` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
- PRIMARY KEY (`id`),
- KEY `updated_at` (`updated_at`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at, updated_at)
VALUES ("clear day",
"2012-01-29 21:51:01.111111",
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_timestamp_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_timestamp_with_index.result
index 3f93ce03ca6..4c221d9ecb6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_timestamp_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_timestamp_with_index.result
@@ -2,20 +2,10 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
-created_at TIMESTAMP,
-updated_at TIMESTAMP,
+created_at TIMESTAMP DEFAULT '2016-04-21 00:00:00',
+updated_at TIMESTAMP DEFAULT '2016-04-21 00:00:00',
KEY (updated_at)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `created_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
- `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- PRIMARY KEY (`id`),
- KEY `updated_at` (`updated_at`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, created_at, updated_at)
VALUES ("clear day", "2012-01-29 21:51:01", "2012-01-29 21:51:02");
INSERT INTO diaries (title, created_at, updated_at)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_year_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_year_with_index.result
index 1fc8e146c17..be97d4fc9cb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_year_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_year_with_index.result
@@ -5,15 +5,6 @@ title TEXT,
party_year YEAR,
KEY (party_year)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE aniversary_memos;
-Table Create Table
-aniversary_memos CREATE TABLE `aniversary_memos` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `party_year` year(4) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `party_year` (`party_year`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO aniversary_memos (title, party_year)
VALUES ("We need a big cake!", "11");
INSERT INTO aniversary_memos (title, party_year)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_year_without_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_year_without_index.result
index c55bc4c6df5..a56271bccf1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/column_year_without_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_year_without_index.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
party_year YEAR
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE aniversary_memos;
-Table Create Table
-aniversary_memos CREATE TABLE `aniversary_memos` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `party_year` year(4) DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO aniversary_memos (title, party_year)
VALUES ("We need a big cake!", "11");
INSERT INTO aniversary_memos (title, party_year)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/count_star.result b/storage/mroonga/mysql-test/mroonga/storage/r/count_star.result
new file mode 100644
index 00000000000..ab6be3a7b77
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/count_star.result
@@ -0,0 +1,11 @@
+DROP TABLE IF EXISTS ids;
+CREATE TABLE ids (
+id int PRIMARY KEY
+);
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+SELECT COUNT(*) FROM ids;
+COUNT(*)
+3
+DROP TABLE ids;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_TODO_SPLIT_ME.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_TODO_SPLIT_ME.result
index 54a9a274835..d2a00b777ec 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_TODO_SPLIT_ME.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_TODO_SPLIT_ME.result
@@ -64,7 +64,7 @@ drop table t1;
create table t1 (c1 timestamp);
desc t1;
Field Type Null Key Default Extra
-c1 timestamp NO current_timestamp() on update current_timestamp()
+c1 timestamp NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
drop table t1;
create table t1 (c1 datetime);
desc t1;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_flags_comment.result
index af3c19e9bb0..e4c4ea059e7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_flags_comment.result
@@ -7,4 +7,9 @@ mroonga_command("dump --dump_plugins no")
table_create bugs TABLE_PAT_KEY UInt32
column_create bugs id COLUMN_SCALAR UInt32
column_create bugs tags COLUMN_VECTOR LongText
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
DROP TABLE bugs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_flags_parameter.result
index 63bf6f666e7..9923b91f477 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_parameter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_flags_parameter.result
@@ -2,16 +2,14 @@ CREATE TABLE bugs (
id INT UNSIGNED PRIMARY KEY,
tags TEXT FLAGS='COLUMN_VECTOR'
) DEFAULT CHARSET=utf8;
-SHOW CREATE TABLE bugs;
-Table Create Table
-bugs CREATE TABLE `bugs` (
- `id` int(10) unsigned NOT NULL,
- `tags` text DEFAULT NULL `FLAGS`='COLUMN_VECTOR',
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
table_create bugs TABLE_PAT_KEY UInt32
column_create bugs id COLUMN_SCALAR UInt32
column_create bugs tags COLUMN_VECTOR LongText
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
DROP TABLE bugs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_groonga_type_comment.result
index 5e5980ac62b..7dede867136 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_groonga_type_comment.result
@@ -7,12 +7,17 @@ tag VARCHAR(64) COMMENT 'groonga_type "tags"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create tags TABLE_PAT_KEY ShortText
-column_create tags name COLUMN_SCALAR ShortText
-
table_create bugs TABLE_PAT_KEY UInt32
column_create bugs id COLUMN_SCALAR UInt32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create tags TABLE_PAT_KEY ShortText
+column_create tags name COLUMN_SCALAR ShortText
+
column_create bugs tag COLUMN_SCALAR tags
DROP TABLE bugs;
DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_nonexistent.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_groonga_type_nonexistent.result
index 99dc30aaa02..99dc30aaa02 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_nonexistent.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_groonga_type_nonexistent.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_groonga_type_parameter.result
index 24941f043c7..89e28aea6cf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_parameter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_groonga_type_parameter.result
@@ -10,17 +10,21 @@ Table Create Table
bugs CREATE TABLE `bugs` (
`id` int(10) unsigned NOT NULL,
`tag` varchar(64) DEFAULT NULL `GROONGA_TYPE`='tags',
- PRIMARY KEY (`id`),
- CONSTRAINT `tag` FOREIGN KEY (`tag`) REFERENCES `test`.`tags` (`name`) ON DELETE RESTRICT ON UPDATE RESTRICT
+ PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create tags TABLE_PAT_KEY ShortText
-column_create tags name COLUMN_SCALAR ShortText
-
table_create bugs TABLE_PAT_KEY UInt32
column_create bugs id COLUMN_SCALAR UInt32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create tags TABLE_PAT_KEY ShortText
+column_create tags name COLUMN_SCALAR ShortText
+
column_create bugs tag COLUMN_SCALAR tags
DROP TABLE bugs;
DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_type_comment.result
index dc3f39d286e..357adfdfbd4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_type_comment.result
@@ -7,12 +7,17 @@ tag VARCHAR(64) COMMENT 'type "tags"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create tags TABLE_PAT_KEY ShortText
-column_create tags name COLUMN_SCALAR ShortText
-
table_create bugs TABLE_PAT_KEY UInt32
column_create bugs id COLUMN_SCALAR UInt32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create tags TABLE_PAT_KEY ShortText
+column_create tags name COLUMN_SCALAR ShortText
+
column_create bugs tag COLUMN_SCALAR tags
DROP TABLE bugs;
DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_nonexistent.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_type_nonexistent.result
index a66a2bd2185..a66a2bd2185 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_nonexistent.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_column_type_nonexistent.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_default_tokenizer.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_default_tokenizer.result
index 9302037b7e1..0c33fac1deb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_default_tokenizer.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_default_tokenizer.result
@@ -5,6 +5,11 @@ COLLATE=utf8_bin
COMMENT='default_tokenizer "TokenDelimit"';
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
table_create tags TABLE_PAT_KEY ShortText --default_tokenizer TokenDelimit
column_create tags name COLUMN_SCALAR ShortText
DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result
index 828de3ebbad..8d39cac4ee8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result
@@ -5,5 +5,5 @@ FULLTEXT INDEX (content) COMMENT 'flags "WITH_POSITION|WITH_WEIGHT"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
-column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos content
+column_create memos#content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos content
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_index_medium.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_index_medium.result
new file mode 100644
index 00000000000..e9d90b0bd48
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_index_medium.result
@@ -0,0 +1,10 @@
+SET NAMES utf8;
+CREATE TABLE memos (
+content VARCHAR(64) NOT NULL,
+content_size INT NOT NULL,
+KEY (content_size) COMMENT 'flags "INDEX_MEDIUM"'
+) DEFAULT CHARSET=utf8;
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+mroonga_command("dump --dump_plugins no --dump_schema no")
+column_create memos#content_size index COLUMN_INDEX|INDEX_MEDIUM memos content_size
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_index_small.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_index_small.result
new file mode 100644
index 00000000000..38a83b899a3
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_index_small.result
@@ -0,0 +1,10 @@
+SET NAMES utf8;
+CREATE TABLE memos (
+content VARCHAR(64) NOT NULL,
+is_read BOOL NOT NULL,
+KEY (is_read) COMMENT 'flags "INDEX_SMALL"'
+) DEFAULT CHARSET=utf8;
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+mroonga_command("dump --dump_plugins no --dump_schema no")
+column_create memos#is_read index COLUMN_INDEX|INDEX_SMALL memos is_read
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result
index b5368b433e6..e90fd833d17 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result
@@ -5,5 +5,5 @@ FULLTEXT INDEX (content) COMMENT 'flags "NONE"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
-column_create memos-content index COLUMN_INDEX memos content
+column_create memos#content index COLUMN_INDEX memos content
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result
index 7e0d29a1e1f..8fbbd197f6c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result
@@ -11,5 +11,5 @@ memos CREATE TABLE `memos` (
) ENGINE=Mroonga DEFAULT CHARSET=utf8
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
-column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos content
+column_create memos#content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos content
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result
index c9283db72bb..3d31400fbbe 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result
@@ -5,5 +5,5 @@ FULLTEXT INDEX (content) COMMENT 'index_flags "NONE"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
-column_create memos-content index COLUMN_INDEX memos content
+column_create memos#content index COLUMN_INDEX memos content
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_with_position_and_with_weight.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_with_position_and_with_weight.result
index 853845d5c15..8f0c4995343 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_with_position_and_with_weight.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_with_position_and_with_weight.result
@@ -5,5 +5,5 @@ FULLTEXT INDEX (content) COMMENT 'index_flags "WITH_POSITION|WITH_WEIGHT"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
-column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos content
+column_create memos#content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos content
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_fulltext_index_bin.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_fulltext_index_bin.result
new file mode 100644
index 00000000000..b6da79c72c9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_fulltext_index_bin.result
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS diaries;
+SET NAMES utf8;
+CREATE TABLE diaries (
+day DATE PRIMARY KEY,
+content VARCHAR(64) NOT NULL,
+FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+INSERT INTO diaries VALUES ("2013-04-23", "ブラックコーヒーを飲んã ã€‚");
+SELECT * FROM diaries
+WHERE MATCH (content) AGAINST ("+ãµã‚‰ã¤ã" IN BOOLEAN MODE);
+day content
+SELECT * FROM diaries
+WHERE MATCH (content) AGAINST ("+ブラック" IN BOOLEAN MODE);
+day content
+2013-04-23 ブラックコーヒーを飲んã ã€‚
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_index_bin.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_index_bin.result
new file mode 100644
index 00000000000..2a05ccdc62c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_index_bin.result
@@ -0,0 +1,22 @@
+DROP TABLE IF EXISTS diaries;
+SET NAMES utf8;
+CREATE TABLE diaries (
+day DATE PRIMARY KEY,
+content VARCHAR(64) NOT NULL,
+INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create diaries TABLE_PAT_KEY Time
+column_create diaries content COLUMN_SCALAR ShortText
+column_create diaries day COLUMN_SCALAR Time
+
+table_create diaries#content TABLE_PAT_KEY ShortText --normalizer NormalizerAuto
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create diaries#content index COLUMN_INDEX diaries content
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result
index 5b593ef0383..29f27d156f1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result
@@ -5,15 +5,11 @@ body text,
FULLTEXT INDEX body_index (body)
COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"'
) DEFAULT CHARSET utf8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`) COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
+Warnings:
+Warning 1287 'parser' is deprecated and will be removed in a future release. Please use tokenizer instead
INSERT INTO diaries (body) VALUES ("will start Groonga!");
+Warnings:
+Warning 1287 'parser' is deprecated and will be removed in a future release. Please use tokenizer instead
INSERT INTO diaries (body) VALUES ("starting Groonga...");
INSERT INTO diaries (body) VALUES ("started Groonga.");
SELECT * FROM diaries;
@@ -29,3 +25,5 @@ id body
2 starting Groonga...
3 started Groonga.
DROP TABLE diaries;
+Warnings:
+Warning 1287 'parser' is deprecated and will be removed in a future release. Please use tokenizer instead
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_default.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_default.result
index 284ecdb6184..7f9ddd50e92 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_default.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_default.result
@@ -6,14 +6,6 @@ id int primary key auto_increment,
body text,
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries (body) values ("will start Groonga!");
insert into diaries (body) values ("starting Groonga...");
insert into diaries (body) values ("started Groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_off.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_off.result
index c3791d10399..320fb9a5635 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_off.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_off.result
@@ -4,15 +4,11 @@ id INT PRIMARY KEY AUTO_INCREMENT,
name TEXT,
FULLTEXT INDEX (name) COMMENT 'parser "off"'
) DEFAULT CHARSET=utf8;
-SHOW CREATE TABLE variables;
-Table Create Table
-variables CREATE TABLE `variables` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `name` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `name` (`name`) COMMENT 'parser "off"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
+Warnings:
+Warning 1287 'parser' is deprecated and will be removed in a future release. Please use tokenizer instead
INSERT INTO variables (name) VALUES ("mroonga_database_path_prefix");
+Warnings:
+Warning 1287 'parser' is deprecated and will be removed in a future release. Please use tokenizer instead
INSERT INTO variables (name) VALUES ("mroonga_default_parser");
INSERT INTO variables (name) VALUES ("mroonga_default_wrapper_engine");
INSERT INTO variables (name) VALUES ("mroonga_dry_write");
@@ -40,3 +36,5 @@ id name
3 mroonga_default_wrapper_engine
2 mroonga_default_parser
DROP TABLE variables;
+Warnings:
+Warning 1287 'parser' is deprecated and will be removed in a future release. Please use tokenizer instead
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_multiple_token_filters.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_multiple_token_filters.result
index c730bafc8e3..ad68ca010cc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_multiple_token_filters.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_multiple_token_filters.result
@@ -11,7 +11,12 @@ mroonga_command("dump --dump_plugins no")
table_create memos TABLE_NO_KEY
column_create memos content COLUMN_SCALAR ShortText
-table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
+table_create memos#content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
-column_create memos-content index COLUMN_INDEX|WITH_POSITION memos content
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create memos#content index COLUMN_INDEX|WITH_POSITION memos content
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_one_token_filter.result
index e0809eb0f4b..2cbb5a6b2e7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_one_token_filter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_one_token_filter.result
@@ -11,7 +11,12 @@ mroonga_command("dump --dump_plugins no")
table_create memos TABLE_NO_KEY
column_create memos content COLUMN_SCALAR ShortText
-table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord
+table_create memos#content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord
-column_create memos-content index COLUMN_INDEX|WITH_POSITION memos content
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create memos#content index COLUMN_INDEX|WITH_POSITION memos content
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result
index df529282a91..333cf3d5d1f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result
@@ -17,7 +17,12 @@ mroonga_command("dump --dump_plugins no")
table_create memos TABLE_NO_KEY
column_create memos content COLUMN_SCALAR ShortText
-table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
+table_create memos#content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
-column_create memos-content index COLUMN_INDEX|WITH_POSITION memos content
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create memos#content index COLUMN_INDEX|WITH_POSITION memos content
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result
index 7c02b18d6a2..a390421684a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result
@@ -5,14 +5,6 @@ body text,
FULLTEXT INDEX body_index (body)
COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
) DEFAULT CHARSET utf8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`) COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (body) VALUES ("will start Groonga!");
INSERT INTO diaries (body) VALUES ("starting Groonga...");
INSERT INTO diaries (body) VALUES ("started Groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result
index b55a2ae52ee..34545ecc30a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result
@@ -6,14 +6,6 @@ id int primary key auto_increment,
body text,
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries (body) values ("will start Groonga!");
insert into diaries (body) values ("starting Groonga...");
insert into diaries (body) values ("started Groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result
index d332795199f..91a5b96d184 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
name TEXT,
FULLTEXT INDEX (name) COMMENT 'tokenizer "off"'
) DEFAULT CHARSET=utf8;
-SHOW CREATE TABLE variables;
-Table Create Table
-variables CREATE TABLE `variables` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `name` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `name` (`name`) COMMENT 'tokenizer "off"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO variables (name) VALUES ("mroonga_database_path_prefix");
INSERT INTO variables (name) VALUES ("mroonga_default_tokenizer");
INSERT INTO variables (name) VALUES ("mroonga_default_wrapper_engine");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result
index 0edc0a1b18e..c827abe2cf4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result
@@ -4,14 +4,6 @@ id int PRIMARY KEY AUTO_INCREMENT,
body text,
FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit'
) DEFAULT CHARSET utf8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`) `TOKENIZER`='TokenBigramSplitSymbolAlphaDigit'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (body) VALUES ("will start Groonga!");
INSERT INTO diaries (body) VALUES ("starting Groonga...");
INSERT INTO diaries (body) VALUES ("started Groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_multiple_token_filters.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_multiple_token_filters.result
index 6308b33d4cf..8934be78d47 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_multiple_token_filters.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_multiple_token_filters.result
@@ -12,14 +12,19 @@ FULLTEXT INDEX (content) COMMENT 'table "terms"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
-column_create terms is_stop_word COLUMN_SCALAR Int8
-column_create terms term COLUMN_SCALAR ShortText
-
table_create memos TABLE_PAT_KEY Int32
column_create memos content COLUMN_SCALAR LongText
column_create memos id COLUMN_SCALAR Int32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
+column_create terms is_stop_word COLUMN_SCALAR Int8
+column_create terms term COLUMN_SCALAR ShortText
+
column_create terms content COLUMN_INDEX|WITH_POSITION memos content
DROP TABLE memos;
DROP TABLE terms;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_one_token_filter.result
index 2f4a90d4086..e3df285093b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_one_token_filter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_one_token_filter.result
@@ -12,14 +12,19 @@ FULLTEXT INDEX (content) COMMENT 'table "terms"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
-table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord
-column_create terms is_stop_word COLUMN_SCALAR Int8
-column_create terms term COLUMN_SCALAR ShortText
-
table_create memos TABLE_PAT_KEY Int32
column_create memos content COLUMN_SCALAR LongText
column_create memos id COLUMN_SCALAR Int32
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord
+column_create terms is_stop_word COLUMN_SCALAR Int8
+column_create terms term COLUMN_SCALAR ShortText
+
column_create terms content COLUMN_INDEX|WITH_POSITION memos content
DROP TABLE memos;
DROP TABLE terms;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/drop_database_no_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/drop_database_no_table.result
new file mode 100644
index 00000000000..ebc7db1cf37
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/drop_database_no_table.result
@@ -0,0 +1,20 @@
+SET NAMES UTF8;
+DROP DATABASE IF EXISTS another;
+CREATE DATABASE another;
+USE another;
+CREATE TABLE diaries (
+title TEXT,
+FULLTEXT INDEX (title)
+);
+DROP TABLE diaries;
+USE test;
+DROP TABLE IF EXISTS diaries;
+CREATE TABLE diaries (
+title TEXT,
+FULLTEXT INDEX (title)
+);
+DROP DATABASE another;
+SELECT mroonga_command('object_exist mroonga_operations');
+mroonga_command('object_exist mroonga_operations')
+true
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_add.result b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_add.result
new file mode 100644
index 00000000000..e2e712af4b6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_add.result
@@ -0,0 +1,24 @@
+DROP TABLE IF EXISTS articles;
+DROP TABLE IF EXISTS comments;
+CREATE TABLE comments (
+comment int unsigned PRIMARY KEY,
+content text NOT NULL
+);
+CREATE TABLE articles (
+content text NOT NULL,
+comment int unsigned
+);
+ALTER TABLE articles ADD FOREIGN KEY (comment) REFERENCES comments (comment);
+SHOW CREATE TABLE articles;
+Table Create Table
+articles CREATE TABLE `articles` (
+ `content` text NOT NULL,
+ `comment` int(10) unsigned DEFAULT NULL,
+ KEY `comment` (`comment`),
+ CONSTRAINT `comment` FOREIGN KEY (`comment`) REFERENCES `test`.`comments` (`comment`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE=Mroonga DEFAULT CHARSET=latin1
+SELECT * FROM information_schema.referential_constraints;
+CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME UNIQUE_CONSTRAINT_CATALOG UNIQUE_CONSTRAINT_SCHEMA UNIQUE_CONSTRAINT_NAME MATCH_OPTION UPDATE_RULE DELETE_RULE TABLE_NAME REFERENCED_TABLE_NAME
+def test comment def test PRIMARY NONE RESTRICT RESTRICT articles comments
+DROP TABLE articles;
+DROP TABLE comments;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_drop.result b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_drop.result
new file mode 100644
index 00000000000..fc3cda00499
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_drop.result
@@ -0,0 +1,23 @@
+DROP TABLE IF EXISTS articles;
+DROP TABLE IF EXISTS comments;
+CREATE TABLE comments (
+comment int unsigned PRIMARY KEY,
+content text NOT NULL
+);
+CREATE TABLE articles (
+content text NOT NULL,
+comment int unsigned,
+FOREIGN KEY (comment) REFERENCES comments (comment)
+);
+ALTER TABLE articles DROP FOREIGN KEY comment;
+SHOW CREATE TABLE articles;
+Table Create Table
+articles CREATE TABLE `articles` (
+ `content` text NOT NULL,
+ `comment` int(10) unsigned DEFAULT NULL,
+ KEY `comment` (`comment`)
+) ENGINE=Mroonga DEFAULT CHARSET=latin1
+SELECT * FROM information_schema.referential_constraints;
+CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME UNIQUE_CONSTRAINT_CATALOG UNIQUE_CONSTRAINT_SCHEMA UNIQUE_CONSTRAINT_NAME MATCH_OPTION UPDATE_RULE DELETE_RULE TABLE_NAME REFERENCED_TABLE_NAME
+DROP TABLE articles;
+DROP TABLE comments;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_create.result b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_create.result
index fc550d97f87..c17780c0441 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_create.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_create.result
@@ -1,134 +1,15 @@
-drop table if exists articles2;
-drop table if exists articles;
-drop table if exists comments2;
-drop table if exists comments;
-create table comments(
-comment int unsigned,
-content text not null,
-primary key(comment)
-);
-create table articles(
-content text not null,
-comment int unsigned,
-FOREIGN KEY (comment) REFERENCES comments (comment)
-);
-insert into comments (comment, content) values
-(1, 'aaa bbb'),(2, 'ccc ddd'),(3, 'eee fff');
-insert into articles (content, comment) values
-('111aaa', 1),('222bbb', 2),('222ccc', 2);
-select comment, content from comments;
-comment content
-1 aaa bbb
-2 ccc ddd
-3 eee fff
-select content, comment from articles;
-content comment
-111aaa 1
-222bbb 2
-222ccc 2
-show create table comments;
-Table Create Table
-comments CREATE TABLE `comments` (
- `comment` int(10) unsigned NOT NULL DEFAULT '0',
- `content` text NOT NULL,
- PRIMARY KEY (`comment`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1
-show create table articles;
-Table Create Table
-articles CREATE TABLE `articles` (
- `content` text NOT NULL,
- `comment` int(10) unsigned DEFAULT NULL,
- KEY `comment` (`comment`),
- CONSTRAINT `comment` FOREIGN KEY (`comment`) REFERENCES `test`.`comments` (`comment`) ON DELETE RESTRICT ON UPDATE RESTRICT
-) ENGINE=Mroonga DEFAULT CHARSET=latin1
-select * from information_schema.referential_constraints;
-CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME UNIQUE_CONSTRAINT_CATALOG UNIQUE_CONSTRAINT_SCHEMA UNIQUE_CONSTRAINT_NAME MATCH_OPTION UPDATE_RULE DELETE_RULE TABLE_NAME REFERENCED_TABLE_NAME
-def test comment def test PRIMARY NONE RESTRICT RESTRICT articles comments
-rename table comments to comments2;
-rename table articles to articles2;
-create table comments(
-comment int unsigned,
-content text not null,
-primary key(comment)
+DROP TABLE IF EXISTS articles;
+DROP TABLE IF EXISTS comments;
+CREATE TABLE comments (
+comment int unsigned PRIMARY KEY,
+content text NOT NULL
);
-create table articles(
-content text not null,
+CREATE TABLE articles (
+content text NOT NULL,
comment int unsigned,
FOREIGN KEY (comment) REFERENCES comments (comment)
);
-insert into comments (comment, content) values
-(1, 'ab'),(2, 'cd'),(3, 'ef');
-insert into articles (content, comment) values
-('1a', 1),('2b', 2),('2c', 2);
-select comment, content from comments;
-comment content
-1 ab
-2 cd
-3 ef
-select content, comment from articles;
-content comment
-1a 1
-2b 2
-2c 2
-select comment, content from comments2;
-comment content
-1 aaa bbb
-2 ccc ddd
-3 eee fff
-select content, comment from articles2;
-content comment
-111aaa 1
-222bbb 2
-222ccc 2
-show create table comments;
-Table Create Table
-comments CREATE TABLE `comments` (
- `comment` int(10) unsigned NOT NULL DEFAULT '0',
- `content` text NOT NULL,
- PRIMARY KEY (`comment`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1
-show create table articles;
-Table Create Table
-articles CREATE TABLE `articles` (
- `content` text NOT NULL,
- `comment` int(10) unsigned DEFAULT NULL,
- KEY `comment` (`comment`),
- CONSTRAINT `comment` FOREIGN KEY (`comment`) REFERENCES `test`.`comments` (`comment`) ON DELETE RESTRICT ON UPDATE RESTRICT
-) ENGINE=Mroonga DEFAULT CHARSET=latin1
-show create table comments2;
-Table Create Table
-comments2 CREATE TABLE `comments2` (
- `comment` int(10) unsigned NOT NULL DEFAULT '0',
- `content` text NOT NULL,
- PRIMARY KEY (`comment`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1
-show create table articles2;
-Table Create Table
-articles2 CREATE TABLE `articles2` (
- `content` text NOT NULL,
- `comment` int(10) unsigned DEFAULT NULL,
- KEY `comment` (`comment`),
- CONSTRAINT `comment` FOREIGN KEY (`comment`) REFERENCES `test`.`comments2` (`comment`) ON DELETE RESTRICT ON UPDATE RESTRICT
-) ENGINE=Mroonga DEFAULT CHARSET=latin1
-select * from information_schema.referential_constraints;
-CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME UNIQUE_CONSTRAINT_CATALOG UNIQUE_CONSTRAINT_SCHEMA UNIQUE_CONSTRAINT_NAME MATCH_OPTION UPDATE_RULE DELETE_RULE TABLE_NAME REFERENCED_TABLE_NAME
-def test comment def test PRIMARY NONE RESTRICT RESTRICT articles comments
-def test comment def test PRIMARY NONE RESTRICT RESTRICT articles2 comments2
-alter table articles drop foreign key comment;
-show create table articles;
-Table Create Table
-articles CREATE TABLE `articles` (
- `content` text NOT NULL,
- `comment` int(10) unsigned DEFAULT NULL,
- KEY `comment` (`comment`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1
-select content, comment from articles;
-content comment
-1a 1
-2b 2
-2c 2
-alter table articles add FOREIGN KEY (comment) REFERENCES comments (comment);
-show create table articles;
+SHOW CREATE TABLE articles;
Table Create Table
articles CREATE TABLE `articles` (
`content` text NOT NULL,
@@ -136,12 +17,6 @@ articles CREATE TABLE `articles` (
KEY `comment` (`comment`),
CONSTRAINT `comment` FOREIGN KEY (`comment`) REFERENCES `test`.`comments` (`comment`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=Mroonga DEFAULT CHARSET=latin1
-select content, comment from articles;
-content comment
-1a 1
-2b 2
-2c 2
-drop table articles2;
-drop table articles;
-drop table comments2;
-drop table comments;
+SELECT * FROM information_schema.referential_constraints;
+DROP TABLE articles;
+DROP TABLE comments;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_delete_existent.result b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_delete_existent.result
new file mode 100644
index 00000000000..e16157b439f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_delete_existent.result
@@ -0,0 +1,53 @@
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+CREATE TABLE comments (
+id int unsigned PRIMARY KEY,
+content varchar(140) NOT NULL
+);
+CREATE TABLE entries (
+content varchar(140) NOT NULL,
+comment_id int unsigned,
+FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+INSERT INTO comments (id, content) VALUES (100, 'Good entry!');
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 100);
+DELETE FROM comments WHERE id = 100;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (one or more child rows exist in <entries>)
+SELECT * FROM entries;
+content comment_id
+Hello! 100
+SELECT * FROM comments;
+id content
+100 Good entry!
+SELECT mroonga_command('dump --dump_plugins no');
+mroonga_command('dump --dump_plugins no')
+table_create comments TABLE_PAT_KEY UInt32
+column_create comments content COLUMN_SCALAR ShortText
+column_create comments id COLUMN_SCALAR UInt32
+
+table_create entries TABLE_NO_KEY
+column_create entries content COLUMN_SCALAR ShortText
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create entries comment_id COLUMN_SCALAR comments
+
+load --table comments
+[
+["_key","content","id"],
+[100,"Good entry!",100]
+]
+
+load --table entries
+[
+["_id","comment_id","content"],
+[1,100,"Hello!"]
+]
+
+column_create comments entries-comment_id----------------------------------------------- COLUMN_INDEX entries comment_id
+DROP TABLE entries;
+DROP TABLE comments;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_delete_nonexistent.result b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_delete_nonexistent.result
new file mode 100644
index 00000000000..edaba25fad8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_delete_nonexistent.result
@@ -0,0 +1,53 @@
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+CREATE TABLE comments (
+id int unsigned PRIMARY KEY,
+content varchar(140) NOT NULL
+);
+CREATE TABLE entries (
+content varchar(140) NOT NULL,
+comment_id int unsigned,
+FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+INSERT INTO comments (id, content) VALUES (100, 'Good entry!');
+INSERT INTO comments (id, content) VALUES (200, 'Very good entry!');
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 100);
+DELETE FROM comments WHERE id = 200;
+SELECT * FROM entries;
+content comment_id
+Hello! 100
+SELECT * FROM comments;
+id content
+100 Good entry!
+SELECT mroonga_command('dump --dump_plugins no');
+mroonga_command('dump --dump_plugins no')
+table_create comments TABLE_PAT_KEY UInt32
+column_create comments content COLUMN_SCALAR ShortText
+column_create comments id COLUMN_SCALAR UInt32
+
+table_create entries TABLE_NO_KEY
+column_create entries content COLUMN_SCALAR ShortText
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create entries comment_id COLUMN_SCALAR comments
+
+load --table comments
+[
+["_key","content","id"],
+[100,"Good entry!",100]
+]
+
+load --table entries
+[
+["_id","comment_id","content"],
+[1,100,"Hello!"]
+]
+
+column_create comments entries-comment_id----------------------------------------------- COLUMN_INDEX entries comment_id
+DROP TABLE entries;
+DROP TABLE comments;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_insert_existent.result b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_insert_existent.result
new file mode 100644
index 00000000000..ddc54cb3f9e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_insert_existent.result
@@ -0,0 +1,51 @@
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+CREATE TABLE comments (
+id int unsigned PRIMARY KEY,
+content varchar(140) NOT NULL
+);
+CREATE TABLE entries (
+content varchar(140) NOT NULL,
+comment_id int unsigned,
+FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+INSERT INTO comments (id, content) VALUES (100, 'Good entry!');
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 100);
+SELECT * FROM entries;
+content comment_id
+Hello! 100
+SELECT * FROM comments;
+id content
+100 Good entry!
+SELECT mroonga_command('dump --dump_plugins no');
+mroonga_command('dump --dump_plugins no')
+table_create comments TABLE_PAT_KEY UInt32
+column_create comments content COLUMN_SCALAR ShortText
+column_create comments id COLUMN_SCALAR UInt32
+
+table_create entries TABLE_NO_KEY
+column_create entries content COLUMN_SCALAR ShortText
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create entries comment_id COLUMN_SCALAR comments
+
+load --table comments
+[
+["_key","content","id"],
+[100,"Good entry!",100]
+]
+
+load --table entries
+[
+["_id","comment_id","content"],
+[1,100,"Hello!"]
+]
+
+column_create comments entries-comment_id----------------------------------------------- COLUMN_INDEX entries comment_id
+DROP TABLE entries;
+DROP TABLE comments;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_insert_nonexistent.result b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_insert_nonexistent.result
new file mode 100644
index 00000000000..c220bb8970b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_insert_nonexistent.result
@@ -0,0 +1,37 @@
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+CREATE TABLE comments (
+id int unsigned PRIMARY KEY,
+content varchar(140) NOT NULL
+);
+CREATE TABLE entries (
+content varchar(140) NOT NULL,
+comment_id int unsigned,
+FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 1);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (foreign record doesn't exist: <comment_id>:<1>)
+SELECT * FROM entries;
+content comment_id
+SELECT * FROM comments;
+id content
+SELECT mroonga_command('dump --dump_plugins no');
+mroonga_command('dump --dump_plugins no')
+table_create comments TABLE_PAT_KEY UInt32
+column_create comments content COLUMN_SCALAR ShortText
+column_create comments id COLUMN_SCALAR UInt32
+
+table_create entries TABLE_NO_KEY
+column_create entries content COLUMN_SCALAR ShortText
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create entries comment_id COLUMN_SCALAR comments
+
+column_create comments entries-comment_id----------------------------------------------- COLUMN_INDEX entries comment_id
+DROP TABLE entries;
+DROP TABLE comments;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_rename.result b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_rename.result
new file mode 100644
index 00000000000..5ea0ae3e3ac
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_rename.result
@@ -0,0 +1,28 @@
+DROP TABLE IF EXISTS articles;
+DROP TABLE IF EXISTS comments;
+DROP TABLE IF EXISTS articles2;
+DROP TABLE IF EXISTS comments2;
+CREATE TABLE comments (
+comment int unsigned PRIMARY KEY,
+content text NOT NULL
+);
+CREATE TABLE articles (
+content text NOT NULL,
+comment int unsigned,
+FOREIGN KEY (comment) REFERENCES comments (comment)
+);
+RENAME TABLE comments TO comments2;
+RENAME TABLE articles TO articles2;
+SHOW CREATE TABLE articles2;
+Table Create Table
+articles2 CREATE TABLE `articles2` (
+ `content` text NOT NULL,
+ `comment` int(10) unsigned DEFAULT NULL,
+ KEY `comment` (`comment`),
+ CONSTRAINT `comment` FOREIGN KEY (`comment`) REFERENCES `test`.`comments2` (`comment`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE=Mroonga DEFAULT CHARSET=latin1
+SELECT * FROM information_schema.referential_constraints;
+CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME UNIQUE_CONSTRAINT_CATALOG UNIQUE_CONSTRAINT_SCHEMA UNIQUE_CONSTRAINT_NAME MATCH_OPTION UPDATE_RULE DELETE_RULE TABLE_NAME REFERENCED_TABLE_NAME
+def test comment def test PRIMARY NONE RESTRICT RESTRICT articles2 comments2
+DROP TABLE articles2;
+DROP TABLE comments2;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_update_existent.result b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_update_existent.result
new file mode 100644
index 00000000000..9db892d5d2d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_update_existent.result
@@ -0,0 +1,55 @@
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+CREATE TABLE comments (
+id int unsigned PRIMARY KEY,
+content varchar(140) NOT NULL
+);
+CREATE TABLE entries (
+content varchar(140) NOT NULL,
+comment_id int unsigned,
+FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+INSERT INTO comments (id, content) VALUES (100, 'Good entry!');
+INSERT INTO comments (id, content) VALUES (200, 'Very good entry!');
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 100);
+UPDATE entries SET comment_id = 200 WHERE content = 'Hello!';
+SELECT * FROM entries;
+content comment_id
+Hello! 200
+SELECT * FROM comments;
+id content
+100 Good entry!
+200 Very good entry!
+SELECT mroonga_command('dump --dump_plugins no');
+mroonga_command('dump --dump_plugins no')
+table_create comments TABLE_PAT_KEY UInt32
+column_create comments content COLUMN_SCALAR ShortText
+column_create comments id COLUMN_SCALAR UInt32
+
+table_create entries TABLE_NO_KEY
+column_create entries content COLUMN_SCALAR ShortText
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create entries comment_id COLUMN_SCALAR comments
+
+load --table comments
+[
+["_key","content","id"],
+[100,"Good entry!",100],
+[200,"Very good entry!",200]
+]
+
+load --table entries
+[
+["_id","comment_id","content"],
+[1,200,"Hello!"]
+]
+
+column_create comments entries-comment_id----------------------------------------------- COLUMN_INDEX entries comment_id
+DROP TABLE entries;
+DROP TABLE comments;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_update_nonexistent.result b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_update_nonexistent.result
new file mode 100644
index 00000000000..615c3a0903a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_update_nonexistent.result
@@ -0,0 +1,53 @@
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+CREATE TABLE comments (
+id int unsigned PRIMARY KEY,
+content varchar(140) NOT NULL
+);
+CREATE TABLE entries (
+content varchar(140) NOT NULL,
+comment_id int unsigned,
+FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+INSERT INTO comments (id, content) VALUES (100, 'Good entry!');
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 100);
+UPDATE entries SET comment_id = 200 WHERE content = 'Hello!';
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (foreign record doesn't exist: <comment_id>:<200>)
+SELECT * FROM entries;
+content comment_id
+Hello! 100
+SELECT * FROM comments;
+id content
+100 Good entry!
+SELECT mroonga_command('dump --dump_plugins no');
+mroonga_command('dump --dump_plugins no')
+table_create comments TABLE_PAT_KEY UInt32
+column_create comments content COLUMN_SCALAR ShortText
+column_create comments id COLUMN_SCALAR UInt32
+
+table_create entries TABLE_NO_KEY
+column_create entries content COLUMN_SCALAR ShortText
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create entries comment_id COLUMN_SCALAR comments
+
+load --table comments
+[
+["_key","content","id"],
+[100,"Good entry!",100]
+]
+
+load --table entries
+[
+["_id","comment_id","content"],
+[1,100,"Hello!"]
+]
+
+column_create comments entries-comment_id----------------------------------------------- COLUMN_INDEX entries comment_id
+DROP TABLE entries;
+DROP TABLE comments;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_escape.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_escape.result
index a48eb25dece..5beda03ceb6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_escape.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_escape.result
@@ -1,5 +1,5 @@
DROP TABLE IF EXISTS memos;
-SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET GLOBAL mroonga_default_tokenizer = TokenDelimit;
SET NAMES UTF8;
CREATE TABLE memos (
id INT PRIMARY KEY,
@@ -15,4 +15,4 @@ id content
1 (groonga) Installed!
3 (groonga) Upgraded!
DROP TABLE memos;
-SET GLOBAL mroonga_default_parser = TokenBigram;
+SET GLOBAL mroonga_default_tokenizer = TokenBigram;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_leading_not.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_leading_not.result
index 6452fe4398c..758f969feb8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_leading_not.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_leading_not.result
@@ -6,15 +6,6 @@ title VARCHAR(255),
content TEXT,
FULLTEXT INDEX (content)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_syntax_script_operator.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_syntax_script_operator.result
new file mode 100644
index 00000000000..deb4bd85385
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_syntax_script_operator.result
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS diaries;
+SET NAMES utf8;
+CREATE TABLE diaries (
+id INT PRIMARY KEY,
+title VARCHAR(255),
+content TEXT,
+FULLTEXT INDEX (title, content)
+) DEFAULT CHARSET=utf8;
+INSERT INTO diaries VALUES(1, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
+INSERT INTO diaries VALUES(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
+INSERT INTO diaries VALUES(3, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
+SELECT *, MATCH(title, content)
+AGAINST("*SS content @ '天気'" in BOOLEAN MODE) AS score
+FROM diaries
+WHERE MATCH(title, content)
+AGAINST("*SS content @ '天気'" in BOOLEAN MODE);
+id title content score
+2 天気 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„㦠1
+3 富士山 今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚ 1
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_syntax_script_selector.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_syntax_script_selector.result
new file mode 100644
index 00000000000..43b21bc1cd8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_syntax_script_selector.result
@@ -0,0 +1,25 @@
+DROP TABLE IF EXISTS items;
+DROP TABLE IF EXISTS readings;
+SET NAMES utf8;
+CREATE TABLE readings (
+reading VARCHAR(255) PRIMARY KEY
+) DEFAULT CHARSET=utf8
+COLLATE=utf8_bin
+COMMENT='default_tokenizer "TokenDelimit"';
+CREATE TABLE items (
+name VARCHAR(255) PRIMARY KEY,
+readings TEXT COMMENT 'flags "COLUMN_VECTOR", type "readings"',
+FULLTEXT INDEX items_index(readings) COMMENT 'table "readings"'
+) DEFAULT CHARSET=utf8;
+INSERT INTO items VALUES("日本", "ニホン ニッãƒãƒ³");
+INSERT INTO items VALUES("ローマ字", "ローマジ");
+INSERT INTO items VALUES("漢字", "カンジ");
+SELECT *, MATCH(readings)
+AGAINST("*SS sub_filter(readings, 'prefix_rk_search(_key, \"niho\")')" in BOOLEAN MODE) AS score
+FROM items
+WHERE MATCH(readings)
+AGAINST("*SS sub_filter(readings, 'prefix_rk_search(_key, \"niho\")')" in BOOLEAN MODE);
+name readings score
+日本 ニホン ニッãƒãƒ³ 1
+DROP TABLE items;
+DROP TABLE readings;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_error.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_error.result
index 5746ce89cb7..46dd3290565 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_error.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_error.result
@@ -1,5 +1,5 @@
DROP TABLE IF EXISTS memos;
-SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET GLOBAL mroonga_default_tokenizer = TokenDelimit;
SET mroonga_action_on_fulltext_query_error = ERROR;
SET NAMES UTF8;
CREATE TABLE memos (
@@ -14,4 +14,4 @@ SELECT * FROM memos
WHERE MATCH(content) AGAINST("(groonga" IN BOOLEAN MODE);
ERROR 42000: failed to parse fulltext search keyword: <(groonga>: <Syntax error: <(groonga||>>
DROP TABLE memos;
-SET GLOBAL mroonga_default_parser = TokenBigram;
+SET GLOBAL mroonga_default_tokenizer = TokenBigram;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_error_and_log.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_error_and_log.result
index 1811994b67e..d782357eef4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_error_and_log.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_error_and_log.result
@@ -1,5 +1,5 @@
DROP TABLE IF EXISTS memos;
-SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET GLOBAL mroonga_default_tokenizer = TokenDelimit;
SET mroonga_action_on_fulltext_query_error = ERROR_AND_LOG;
SET NAMES UTF8;
CREATE TABLE memos (
@@ -14,4 +14,4 @@ SELECT * FROM memos
WHERE MATCH(content) AGAINST("(groonga" IN BOOLEAN MODE);
ERROR 42000: failed to parse fulltext search keyword: <(groonga>: <Syntax error: <(groonga||>>
DROP TABLE memos;
-SET GLOBAL mroonga_default_parser = TokenBigram;
+SET GLOBAL mroonga_default_tokenizer = TokenBigram;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_ignore.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_ignore.result
index 6a4759963a3..fd5b8d1e0ea 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_ignore.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_ignore.result
@@ -1,5 +1,5 @@
DROP TABLE IF EXISTS memos;
-SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET GLOBAL mroonga_default_tokenizer = TokenDelimit;
SET mroonga_action_on_fulltext_query_error = "IGNORE";
SET NAMES UTF8;
CREATE TABLE memos (
@@ -14,4 +14,4 @@ SELECT * FROM memos
WHERE MATCH(content) AGAINST("(groonga" IN BOOLEAN MODE);
id content
DROP TABLE memos;
-SET GLOBAL mroonga_default_parser = TokenBigram;
+SET GLOBAL mroonga_default_tokenizer = TokenBigram;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_ignore_and_log.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_ignore_and_log.result
index 384d677c427..a485e1cad69 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_ignore_and_log.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_syntax_error_ignore_and_log.result
@@ -1,5 +1,5 @@
DROP TABLE IF EXISTS memos;
-SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET GLOBAL mroonga_default_tokenizer = TokenDelimit;
SET mroonga_action_on_fulltext_query_error = IGNORE_AND_LOG;
SET NAMES UTF8;
CREATE TABLE memos (
@@ -14,4 +14,4 @@ SELECT * FROM memos
WHERE MATCH(content) AGAINST("(groonga" IN BOOLEAN MODE);
id content
DROP TABLE memos;
-SET GLOBAL mroonga_default_parser = TokenBigram;
+SET GLOBAL mroonga_default_tokenizer = TokenBigram;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_charset_utf8mb4.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_charset_utf8mb4.result
index cc6c0131854..136585c38eb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_charset_utf8mb4.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_charset_utf8mb4.result
@@ -6,15 +6,6 @@ title VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
content TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
FULLTEXT INDEX (content)
) DEFAULT CHARSET utf8mb4;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4
INSERT INTO diaries VALUES(1, "Alphabet", "ABCDE");
INSERT INTO diaries VALUES(2, "Mathmatics", "ð€ðð‚ðƒð„ | U+1D400-U+1D405");
INSERT INTO diaries VALUES(3, "ã²ã‚‰ãŒãª", "ã‚ã„ã†ãˆãŠ");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_found_rows.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_found_rows.result
index ebaa41fcfb7..25da7011aa4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_found_rows.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_found_rows.result
@@ -10,19 +10,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_index_recreate.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_index_recreate.result
index faed6cffe54..e38913a63c1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_index_recreate.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_index_recreate.result
@@ -6,15 +6,6 @@ title varchar(255),
content text,
fulltext index (title)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_insert_values.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_insert_values.result
index f05ee7dccd9..5c48cadf568 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_insert_values.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_insert_values.result
@@ -1,13 +1,5 @@
drop table if exists t1, t2, t3;
create table t1 (c1 int primary key, c2 text, fulltext index ft (c2));
-show create table t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `c1` int(11) NOT NULL,
- `c2` text DEFAULT NULL,
- PRIMARY KEY (`c1`),
- FULLTEXT KEY `ft` (`c2`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1
insert into t1 values (1, "hoge hoge");
insert into t1 values (2, "fuga fuga");
insert into t1 values (3, "moge moge");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_delete.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_delete.result
index 14984ed623a..6475f9ec7e9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_delete.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_delete.result
@@ -8,17 +8,6 @@ fulltext index (title, content),
fulltext index (title),
fulltext index (content)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`,`content`),
- FULLTEXT KEY `title_2` (`title`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_insert.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_insert.result
index cc8881bf99a..4244af26901 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_insert.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_insert.result
@@ -8,17 +8,6 @@ fulltext index (title, content),
fulltext index (title),
fulltext index (content)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`,`content`),
- FULLTEXT KEY `title_2` (`title`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_recreate.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_recreate.result
index a3936cea11f..8d18efaa571 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_recreate.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_recreate.result
@@ -8,17 +8,6 @@ fulltext index (title, content),
fulltext index (title),
fulltext index (content)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`,`content`),
- FULLTEXT KEY `title_2` (`title`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_update.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_update.result
index 2706ff665d9..0e85b45ae59 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_update.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_column_index_update.result
@@ -8,17 +8,6 @@ fulltext index (title, content),
fulltext index (title),
fulltext index (content)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`,`content`),
- FULLTEXT KEY `title_2` (`title`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_index.result
index 450687fb3b7..37d7597b1f3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_multiple_index.result
@@ -6,16 +6,6 @@ body text,
fulltext index title_index (title),
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries (title, body) values ("survey", "will start groonga!");
insert into diaries (title, body) values ("groonga (1)", "starting groonga...");
insert into diaries (title, body) values ("groonga (2)", "started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_no_primary_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_no_primary_key.result
index bb3831ea6d9..db4afff0e91 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_no_primary_key.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_no_primary_key.result
@@ -5,13 +5,6 @@ title VARCHAR(255),
content TEXT,
FULLTEXT INDEX (content)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES("Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES("天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES("富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_100_no_such_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_10_0_no_such_key.result
index d3ac2387586..d3ac2387586 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_100_no_such_key.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_10_0_no_such_key.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_55_no_such_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_5_5_no_such_key.result
index 5f7bc98a3d3..5f7bc98a3d3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_55_no_such_key.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_5_5_no_such_key.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_56_no_such_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_5_6_no_such_key.result
index d3ac2387586..d3ac2387586 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_56_no_such_key.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_version_5_6_no_such_key.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_command_auto-escape.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_command_auto-escape.result
new file mode 100644
index 00000000000..e07eae11ecd
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_command_auto-escape.result
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS diaries;
+SET NAMES UTF8;
+CREATE TABLE diaries (
+title TEXT,
+FULLTEXT KEY (title)
+) DEFAULT CHARSET=utf8;
+INSERT INTO diaries VALUES('It is Groonga');
+INSERT INTO diaries VALUES('It is Mroonga');
+SELECT mroonga_command('select',
+'table', 'diaries',
+'filter', 'title @ "Groonga"');
+mroonga_command('select',
+'table', 'diaries',
+'filter', 'title @ "Groonga"')
+[[[1],[["_id","UInt32"],["title","LongText"]],[1,"It is Groonga"]]]
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_command_special-database-name.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_command_special-database-name.result
new file mode 100644
index 00000000000..e588408e9e2
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_command_special-database-name.result
@@ -0,0 +1,22 @@
+DROP DATABASE IF EXISTS `db-1`;
+CREATE DATABASE `db-1`;
+USE `db-1`;
+SET NAMES UTF8;
+CREATE TABLE diaries (
+title TEXT,
+FULLTEXT KEY (title)
+) DEFAULT CHARSET=utf8;
+SELECT mroonga_command('dump --dump_plugins no');
+mroonga_command('dump --dump_plugins no')
+table_create diaries TABLE_NO_KEY
+column_create diaries title COLUMN_SCALAR LongText
+
+table_create diaries#title TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create diaries#title index COLUMN_INDEX|WITH_POSITION diaries title
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_error_query_is_not_string.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_error_query_is_not_string.result
index c1762458199..bb68bbff1f5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_error_query_is_not_string.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_error_query_is_not_string.result
@@ -1,3 +1,3 @@
SET NAMES UTF8;
SELECT mroonga_escape(29) AS escaped_query;
-ERROR HY000: Can't initialize function 'mroonga_escape'; mroonga_escape(): The 1st argument must be query as string
+ERROR HY000: Can't initialize function 'mroonga_escape'; mroonga_escape(): The 1st query argument must be string
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_success_all.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_all.result
index b002262a83f..b002262a83f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_success_all.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_all.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_success_custom.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_custom.result
index c2e7d8f50ef..c2e7d8f50ef 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_success_custom.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_custom.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_join.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_join.result
new file mode 100644
index 00000000000..ec765b118ef
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_join.result
@@ -0,0 +1,26 @@
+SET NAMES UTF8;
+DROP TABLE IF EXISTS users;
+DROP TABLE IF EXISTS queries;
+CREATE TABLE users (
+id INT
+);
+CREATE TABLE queries (
+user_id INT,
+query TEXT
+);
+INSERT INTO users VALUES (1);
+INSERT INTO users VALUES (2);
+INSERT INTO users VALUES (3);
+INSERT INTO queries VALUES (1, '(a)');
+INSERT INTO queries VALUES (2, '(b)');
+INSERT INTO queries VALUES (3, '(c)');
+SELECT users.id, mroonga_escape(queries.query) AS escaped_query
+FROM queries
+LEFT JOIN users ON users.id = queries.user_id
+ORDER BY users.id;
+id escaped_query
+1 \(a\)
+2 \(b\)
+3 \(c\)
+DROP TABLE queries;
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_match_against.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_match_against.result
new file mode 100644
index 00000000000..8b92ec4137e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_match_against.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS memos;
+SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET NAMES utf8mb4;
+CREATE TABLE memos (
+id INT PRIMARY KEY,
+content TEXT,
+FULLTEXT INDEX (content)
+) DEFAULT CHARSET=utf8mb4;
+INSERT INTO memos VALUES(1, "(Groonga) Installed!");
+INSERT INTO memos VALUES(2, "(Mroonga) Installed!");
+INSERT INTO memos VALUES(3, "(Groonga) Upgraded!");
+SELECT * FROM memos
+WHERE MATCH(content) AGAINST(mroonga_escape("(groonga)") IN BOOLEAN MODE);
+id content
+1 (Groonga) Installed!
+3 (Groonga) Upgraded!
+DROP TABLE memos;
+SET GLOBAL mroonga_default_parser = TokenBigram;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_named.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_named.result
new file mode 100644
index 00000000000..c6c39fccb10
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_named.result
@@ -0,0 +1,4 @@
+SET NAMES UTF8;
+SELECT mroonga_escape('+-><~*()\"\\:' AS query) AS escaped_query;
+escaped_query
+\+\-\>\<\~\*\(\)\"\\\:
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_success_nested.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_nested.result
index 5a57c144891..5a57c144891 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_success_nested.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_query_nested.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_decimal.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_decimal.result
new file mode 100644
index 00000000000..246f280005c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_decimal.result
@@ -0,0 +1,11 @@
+SET NAMES UTF8;
+DROP TABLE IF EXISTS data;
+CREATE TABLE data (
+value DECIMAL(5, 3)
+);
+INSERT INTO data VALUES (2.9);
+SELECT mroonga_escape(value AS script)
+FROM data;
+mroonga_escape(value AS script)
+2.9
+DROP TABLE data;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_integer.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_integer.result
new file mode 100644
index 00000000000..902bbd31730
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_integer.result
@@ -0,0 +1,4 @@
+SET NAMES UTF8;
+SELECT mroonga_escape(-29 AS script) AS escaped_query;
+escaped_query
+-29
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_real.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_real.result
new file mode 100644
index 00000000000..178ff312332
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_real.result
@@ -0,0 +1,11 @@
+SET NAMES UTF8;
+DROP TABLE IF EXISTS data;
+CREATE TABLE data (
+value REAL
+);
+INSERT INTO data VALUES (2.9);
+SELECT mroonga_escape(value AS script)
+FROM data;
+mroonga_escape(value AS script)
+2.9
+DROP TABLE data;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_string.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_string.result
new file mode 100644
index 00000000000..6f5e9b2a2c4
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_escape_script_string.result
@@ -0,0 +1,4 @@
+SET NAMES UTF8;
+SELECT mroonga_escape('a\"\\\'z' AS script) AS escaped_query;
+escaped_query
+"a\"\\'z"
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_dynamic_keyword.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_dynamic_keyword.result
new file mode 100644
index 00000000000..96df65061d6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_dynamic_keyword.result
@@ -0,0 +1,11 @@
+CREATE TABLE keywords (
+keyword text
+);
+INSERT INTO keywords VALUES ('Mroonga');
+INSERT INTO keywords VALUES ('Groonga');
+SELECT mroonga_highlight_html('Mroonga is the Groonga based storage engine.',
+keyword) AS highlighted
+FROM keywords;
+highlighted
+<span class="keyword">Mroonga</span> is the Groonga based storage engine.
+Mroonga is the <span class="keyword">Groonga</span> based storage engine.
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_japanese.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_japanese.result
new file mode 100644
index 00000000000..ca7d796845d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_japanese.result
@@ -0,0 +1,13 @@
+SET NAMES utf8;
+SELECT mroonga_highlight_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+'ロック', '更新') AS highlighted;
+highlighted
+Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚ç…§<span class="keyword">ロック</span>フリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿<span class="keyword">æ›´æ–°</span>・全文検索・ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚ç…§<span class="keyword">ロック</span>フリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€<span class="keyword">æ›´æ–°</span>処ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_multiple_keywords.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_multiple_keywords.result
new file mode 100644
index 00000000000..9f4a3dffb5f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_multiple_keywords.result
@@ -0,0 +1,4 @@
+SELECT mroonga_highlight_html('Mroonga is the Groonga based storage engine.',
+'Mroonga', 'Groonga') AS highlighted;
+highlighted
+<span class="keyword">Mroonga</span> is the <span class="keyword">Groonga</span> based storage engine.
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_normalizer.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_normalizer.result
new file mode 100644
index 00000000000..bf280dba0ac
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_normalizer.result
@@ -0,0 +1,4 @@
+SELECT mroonga_highlight_html('Mroonga is the Groonga based storage engine.',
+'mroonga') AS highlighted;
+highlighted
+<span class="keyword">Mroonga</span> is the Groonga based storage engine.
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_query.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_query.result
new file mode 100644
index 00000000000..b2d0f509f8b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_query.result
@@ -0,0 +1,13 @@
+SET NAMES utf8;
+SELECT mroonga_highlight_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+'ロック æ›´æ–° -ボトルãƒãƒƒã‚¯' AS query) AS highlighted;
+highlighted
+Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚ç…§<span class="keyword">ロック</span>フリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿<span class="keyword">æ›´æ–°</span>・全文検索・ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚ç…§<span class="keyword">ロック</span>フリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€<span class="keyword">æ›´æ–°</span>処ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_query_pragma.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_query_pragma.result
new file mode 100644
index 00000000000..bd11a908bed
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_query_pragma.result
@@ -0,0 +1,13 @@
+SET NAMES utf8;
+SELECT mroonga_highlight_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+'*D- +ロック +æ›´æ–° ボトルãƒãƒƒã‚¯' AS query) AS highlighted;
+highlighted
+Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚ç…§<span class="keyword">ロック</span>フリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿<span class="keyword">æ›´æ–°</span>・全文検索・ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚ç…§<span class="keyword">ロック</span>フリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€<span class="keyword">æ›´æ–°</span>処ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_record.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_record.result
new file mode 100644
index 00000000000..fce13d9cd88
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_highlight_html_record.result
@@ -0,0 +1,32 @@
+CREATE TABLE memos (
+content text
+);
+INSERT INTO memos VALUES ('Mroonga is a MySQL storage engine based on Groonga, the full text search engine.
+
+In MySQL 5.1 or later, Pluggable Storage Engine interface is introduced, and we can use custom storage engines easily. So we implement Mroonga, so that we can use Groonga through MySQL.
+
+By using Mroonga, you can use Groonga with SQL.');
+INSERT INTO memos VALUES ('Since Tritonn was the modified version of MySQL, we need to build it by ourselves or use binary files provided by Tritonn project, thus we cannot use the official binary files provided by MySQL.
+
+On the other hand, Mroonga is an independent program (shared library) using Pluggable Storage Engine interface, and we can dynamically load it on MySQL''s official binary. So we can use it more easily than Tritonn.');
+INSERT INTO memos VALUES ('Mroonga has two running modes.
+
+One is "storage mode", that is the default mode, and we use Groonga for both storing data and searching. With this mode, you can have full benefits of Groonga described above, like fast data update, lock-free full text search and geolocation search. But it does not support transactions.
+
+Another one is "wrapper mode", that adds full text search function on other storage engines like MyISAM or InnoDB. With this mode, you can use Groonga''s fast full text search with having the benefits of the storage engine, ex. transaction in InnoDB. But you cannot have benefits from Groonga''s read-lock free characteristic. And you might have the performance bottle neck in the storage engine in updating data.');
+SELECT mroonga_highlight_html(content, 'Mroonga') AS highlighted
+FROM memos;
+highlighted
+<span class="keyword">Mroonga</span> is a MySQL storage engine based on Groonga, the full text search engine.
+
+In MySQL 5.1 or later, Pluggable Storage Engine interface is introduced, and we can use custom storage engines easily. So we implement <span class="keyword">Mroonga</span>, so that we can use Groonga through MySQL.
+
+By using <span class="keyword">Mroonga</span>, you can use Groonga with SQL.
+Since Tritonn was the modified version of MySQL, we need to build it by ourselves or use binary files provided by Tritonn project, thus we cannot use the official binary files provided by MySQL.
+
+On the other hand, <span class="keyword">Mroonga</span> is an independent program (shared library) using Pluggable Storage Engine interface, and we can dynamically load it on MySQL's official binary. So we can use it more easily than Tritonn.
+<span class="keyword">Mroonga</span> has two running modes.
+
+One is &quot;storage mode&quot;, that is the default mode, and we use Groonga for both storing data and searching. With this mode, you can have full benefits of Groonga described above, like fast data update, lock-free full text search and geolocation search. But it does not support transactions.
+
+Another one is &quot;wrapper mode&quot;, that adds full text search function on other storage engines like MyISAM or InnoDB. With this mode, you can use Groonga's fast full text search with having the benefits of the storage engine, ex. transaction in InnoDB. But you cannot have benefits from Groonga's read-lock free characteristic. And you might have the performance bottle neck in the storage engine in updating data.
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_default.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_default.result
new file mode 100644
index 00000000000..fe5cc885922
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_default.result
@@ -0,0 +1,3 @@
+SELECT mroonga_normalize('aBcAbCã‘');
+mroonga_normalize('aBcAbCã‘')
+abcabcリットル
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_normalizer.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_normalizer.result
new file mode 100644
index 00000000000..3d675fb0e27
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_normalizer.result
@@ -0,0 +1,3 @@
+SELECT mroonga_normalize('aBcAbCã‘', "NormalizerAuto");
+mroonga_normalize('aBcAbCã‘', "NormalizerAuto")
+abcabcリットル
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_record.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_record.result
new file mode 100644
index 00000000000..7d4192f620b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_normalize_record.result
@@ -0,0 +1,7 @@
+CREATE TABLE memos (
+content text
+);
+INSERT INTO memos VALUES ('aBcAbCã‘');
+SELECT mroonga_normalize(content) FROM memos;
+mroonga_normalize(content)
+abcabcリットル
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_multiple.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_multiple.result
new file mode 100644
index 00000000000..9160633c8fb
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_multiple.result
@@ -0,0 +1,18 @@
+SET NAMES UTF8;
+DROP TABLE IF EXISTS synonyms;
+CREATE TABLE synonyms (
+term varchar(255),
+synonym varchar(255),
+INDEX (term)
+);
+INSERT INTO synonyms VALUES ('Rroonga', 'Rroonga');
+INSERT INTO synonyms VALUES ('Rroonga', 'Groonga Ruby');
+INSERT INTO synonyms VALUES ('Mroonga', 'Mroonga');
+INSERT INTO synonyms VALUES ('Mroonga', 'Groonga MySQL');
+SELECT mroonga_query_expand('synonyms',
+'term',
+'synonym',
+'Mroonga Rroonga PGroonga') AS query;
+query
+((Mroonga) OR (Groonga MySQL)) ((Rroonga) OR (Groonga Ruby)) PGroonga
+DROP TABLE synonyms;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_no_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_no_index.result
new file mode 100644
index 00000000000..6a2b5d7a95a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_no_index.result
@@ -0,0 +1,15 @@
+SET NAMES UTF8;
+DROP TABLE IF EXISTS synonyms;
+CREATE TABLE synonyms (
+term varchar(255),
+synonym varchar(255)
+);
+INSERT INTO synonyms VALUES ('Rroonga', 'Rroonga');
+INSERT INTO synonyms VALUES ('Rroonga', 'Groonga Ruby');
+SELECT mroonga_query_expand('synonyms',
+'term',
+'synonym',
+'Mroonga Rroonga PGroonga') AS query;
+query
+Mroonga ((Rroonga) OR (Groonga Ruby)) PGroonga
+DROP TABLE synonyms;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_one.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_one.result
new file mode 100644
index 00000000000..5f7b0f73c57
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_one.result
@@ -0,0 +1,16 @@
+SET NAMES UTF8;
+DROP TABLE IF EXISTS synonyms;
+CREATE TABLE synonyms (
+term varchar(255),
+synonym varchar(255),
+INDEX (term)
+);
+INSERT INTO synonyms VALUES ('Rroonga', 'Rroonga');
+INSERT INTO synonyms VALUES ('Rroonga', 'Groonga Ruby');
+SELECT mroonga_query_expand('synonyms',
+'term',
+'synonym',
+'Mroonga Rroonga PGroonga') AS query;
+query
+Mroonga ((Rroonga) OR (Groonga Ruby)) PGroonga
+DROP TABLE synonyms;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_pragma.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_pragma.result
new file mode 100644
index 00000000000..4690cd013a5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_query_expand_pragma.result
@@ -0,0 +1,17 @@
+SET NAMES UTF8;
+DROP TABLE IF EXISTS synonyms;
+CREATE TABLE synonyms (
+term varchar(255),
+synonym varchar(255),
+INDEX (term)
+);
+INSERT INTO synonyms VALUES ('D+', '[D+]');
+INSERT INTO synonyms VALUES ('Rroonga', 'Rroonga');
+INSERT INTO synonyms VALUES ('Rroonga', 'Groonga Ruby');
+SELECT mroonga_query_expand('synonyms',
+'term',
+'synonym',
+'*D+ Mroonga Rroonga PGroonga') AS query;
+query
+*D+ Mroonga ((Rroonga) OR (Groonga Ruby)) PGroonga
+DROP TABLE synonyms;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_dynamic_keyword.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_dynamic_keyword.result
new file mode 100644
index 00000000000..24665fbfcfd
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_dynamic_keyword.result
@@ -0,0 +1,11 @@
+CREATE TABLE keywords (
+keyword text
+);
+INSERT INTO keywords VALUES ('Mroonga');
+INSERT INTO keywords VALUES ('Groonga');
+SELECT mroonga_snippet_html('Mroonga is the Groonga based storage engine.',
+keyword) as snippet
+FROM keywords;
+snippet
+<div class="snippet"><span class="keyword">Mroonga</span> is the Groonga based storage engine.</div>
+<div class="snippet">Mroonga is the <span class="keyword">Groonga</span> based storage engine.</div>
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_japanese.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_japanese.result
new file mode 100644
index 00000000000..f1efa42ccbd
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_japanese.result
@@ -0,0 +1,9 @@
+SET NAMES utf8;
+SELECT mroonga_snippet_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+'ロック', '更新') as snippet;
+snippet
+<div class="snippet">ãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚ç…§<span class="keyword">ロック</span>フリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿<span class="keyword">æ›´æ–°</span>・全文検索・ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚</div><div class="snippet">用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚ç…§<span class="keyword">ロック</span>フリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€<span class="keyword">æ›´æ–°</span>処ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒ</div>
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_multiple_keywords.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_multiple_keywords.result
new file mode 100644
index 00000000000..013ad5b1996
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_multiple_keywords.result
@@ -0,0 +1,4 @@
+SELECT mroonga_snippet_html('Mroonga is the Groonga based storage engine.',
+'Mroonga', 'Groonga') as snippet;
+snippet
+<div class="snippet"><span class="keyword">Mroonga</span> is the <span class="keyword">Groonga</span> based storage engine.</div>
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_multiple_snippets.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_multiple_snippets.result
new file mode 100644
index 00000000000..d3f790b3cff
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_multiple_snippets.result
@@ -0,0 +1,10 @@
+SELECT mroonga_snippet_html('Mroonga has two running modes.
+
+One is "storage mode", that is the default mode, and we use Groonga for both storing data and searching. With this mode, you can have full benefits of Groonga described above, like fast data update, lock-free full text search and geolocation search. But it does not support transactions.
+
+Another one is "wrapper mode", that adds full text search function on other storage engines like MyISAM or InnoDB. With this mode, you can use Groonga''s fast full text search with having the benefits of the storage engine, ex. transaction in InnoDB. But you cannot have benefits from Groonga''s read-lock free characteristic. And you might have the performance bottle neck in the storage engine in updating data.',
+'lock') as snippet;
+snippet
+<div class="snippet">ng. With this mode, you can have full benefits of Groonga described above, like fast data update, <span class="keyword">lock</span>-free full text search and geolocation search. But it does not support transactions.
+
+Another one </div><div class="snippet">f the storage engine, ex. transaction in InnoDB. But you cannot have benefits from Groonga's read-<span class="keyword">lock</span> free characteristic. And you might have the performance bottle neck in the storage engine in upda</div>
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_query.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_query.result
new file mode 100644
index 00000000000..d05c2323b68
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_query.result
@@ -0,0 +1,9 @@
+SET NAMES utf8;
+SELECT mroonga_snippet_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+'ロック æ›´æ–° -ボトルãƒãƒƒã‚¯' AS query) as snippet;
+snippet
+<div class="snippet">ãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚ç…§<span class="keyword">ロック</span>フリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿<span class="keyword">æ›´æ–°</span>・全文検索・ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚</div><div class="snippet">用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚ç…§<span class="keyword">ロック</span>フリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€<span class="keyword">æ›´æ–°</span>処ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒ</div>
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_query_pragma.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_query_pragma.result
new file mode 100644
index 00000000000..02ce9098543
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_query_pragma.result
@@ -0,0 +1,9 @@
+SET NAMES utf8;
+SELECT mroonga_snippet_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+'*D- +ロック +æ›´æ–° ボトルãƒãƒƒã‚¯' AS query) as snippet;
+snippet
+<div class="snippet">ãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚ç…§<span class="keyword">ロック</span>フリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿<span class="keyword">æ›´æ–°</span>・全文検索・ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚</div><div class="snippet">用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚ç…§<span class="keyword">ロック</span>フリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€<span class="keyword">æ›´æ–°</span>処ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒ</div>
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_record.result b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_record.result
new file mode 100644
index 00000000000..469defbcb71
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/function_snippet_html_record.result
@@ -0,0 +1,30 @@
+CREATE TABLE memos (
+content text
+);
+INSERT INTO memos VALUES ('Mroonga is a MySQL storage engine based on Groonga, the full text search engine.
+
+In MySQL 5.1 or later, Pluggable Storage Engine interface is introduced, and we can use custom storage engines easily. So we implement Mroonga, so that we can use Groonga through MySQL.
+
+By using Mroonga, you can use Groonga with SQL.');
+INSERT INTO memos VALUES ('Since Tritonn was the modified version of MySQL, we need to build it by ourselves or use binary files provided by Tritonn project, thus we cannot use the official binary files provided by MySQL.
+
+On the other hand, Mroonga is an independent program (shared library) using Pluggable Storage Engine interface, and we can dynamically load it on MySQL''s official binary. So we can use it more easily than Tritonn.');
+INSERT INTO memos VALUES ('Mroonga has two running modes.
+
+One is "storage mode", that is the default mode, and we use Groonga for both storing data and searching. With this mode, you can have full benefits of Groonga described above, like fast data update, lock-free full text search and geolocation search. But it does not support transactions.
+
+Another one is "wrapper mode", that adds full text search function on other storage engines like MyISAM or InnoDB. With this mode, you can use Groonga''s fast full text search with having the benefits of the storage engine, ex. transaction in InnoDB. But you cannot have benefits from Groonga''s read-lock free characteristic. And you might have the performance bottle neck in the storage engine in updating data.');
+SELECT mroonga_snippet_html(content, 'Mroonga') as snippet
+FROM memos;
+snippet
+<div class="snippet"><span class="keyword">Mroonga</span> is a MySQL storage engine based on Groonga, the full text search engine.
+
+In MySQL 5.1 or later, Pluggable Storage Engine interface is introduced, and we can use custom storage engines easily.</div><div class="snippet"> So we implement <span class="keyword">Mroonga</span>, so that we can use Groonga through MySQL.
+
+By using <span class="keyword">Mroonga</span>, you can use Groonga with SQL.</div>
+<div class="snippet">onn project, thus we cannot use the official binary files provided by MySQL.
+
+On the other hand, <span class="keyword">Mroonga</span> is an independent program (shared library) using Pluggable Storage Engine interface, and we can</div>
+<div class="snippet"><span class="keyword">Mroonga</span> has two running modes.
+
+One is &quot;storage mode&quot;, that is the default mode, and we use Groonga for both storing data and searching. With this mode, you can have full benefits of Groonga described</div>
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/geometry_contains.result b/storage/mroonga/mysql-test/mroonga/storage/r/geometry_contains.result
index e694166b930..5095232dfb2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/geometry_contains.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/geometry_contains.result
@@ -5,15 +5,6 @@ name TEXT,
location GEOMETRY NOT NULL,
SPATIAL KEY location_index (location)
);
-SHOW CREATE TABLE shops;
-Table Create Table
-shops CREATE TABLE `shops` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `name` text DEFAULT NULL,
- `location` geometry NOT NULL,
- PRIMARY KEY (`id`),
- SPATIAL KEY `location_index` (`location`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1
INSERT INTO shops (name, location)
VALUES ('nezu-no-taiyaki',
ST_GeomFromText('POINT(139.762573 35.720253)'));
@@ -167,4 +158,10 @@ id name location_text
14 tetsuji POINT(139.76857 35.680911944444446)
19 daruma POINT(139.7705988888889 35.68146111111111)
26 kazuya POINT(139.760895 35.67350805555556)
+EXPLAIN
+SELECT id, name, ST_AsText(location) AS location_text FROM shops
+WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location)
+ORDER BY id;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE shops range location_index location_index 34 NULL 36 Using where; Using filesort
DROP TABLE shops;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/geometry_bulk_insert_null_57.result b/storage/mroonga/mysql-test/mroonga/storage/r/geometry_strict_sql_mode_bulk_insert_null.result
index 271cf922fd5..73573355c00 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/geometry_bulk_insert_null_57.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/geometry_strict_sql_mode_bulk_insert_null.result
@@ -2,13 +2,8 @@ DROP TABLE IF EXISTS shops;
CREATE TABLE shops (
location GEOMETRY NOT NULL
);
-SET SESSION sql_mode = '';
INSERT INTO shops VALUES (NULL), (NULL);
-Warnings:
-Warning 1048 Column 'location' cannot be null
-SET SESSION sql_mode = default;
+ERROR 23000: Column 'location' cannot be null
SELECT ST_AsText(location) FROM shops;
ST_AsText(location)
-POINT(0 0)
-POINT(0 0)
DROP TABLE shops;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/geometry_strict_sql_mode_contains.result b/storage/mroonga/mysql-test/mroonga/storage/r/geometry_strict_sql_mode_contains.result
new file mode 100644
index 00000000000..2f432fc8e66
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/geometry_strict_sql_mode_contains.result
@@ -0,0 +1,169 @@
+DROP TABLE IF EXISTS shops;
+CREATE TABLE shops (
+id INT PRIMARY KEY AUTO_INCREMENT,
+name TEXT,
+location GEOMETRY NOT NULL,
+SPATIAL KEY location_index (location)
+);
+INSERT INTO shops (name, location)
+VALUES ('nezu-no-taiyaki',
+ST_GeomFromText('POINT(139.762573 35.720253)'));
+INSERT INTO shops (name, location)
+VALUES ('taiyaki-kataoka',
+ST_GeomFromText('POINT(139.715591 35.712521)'));
+INSERT INTO shops (name, location)
+VALUES ('soba-taiyaki-ku',
+ST_GeomFromText('POINT(139.659088 35.683712)'));
+INSERT INTO shops (name, location)
+VALUES ('kuruma',
+ST_GeomFromText('POINT(139.706207 35.721516)'));
+INSERT INTO shops (name, location)
+VALUES ('hirose-ya',
+ST_GeomFromText('POINT(139.685608 35.714844)'));
+INSERT INTO shops (name, location)
+VALUES ('sazare',
+ST_GeomFromText('POINT(139.685043 35.714653)'));
+INSERT INTO shops (name, location)
+VALUES ('omede-taiyaki',
+ST_GeomFromText('POINT(139.817154 35.700516)'));
+INSERT INTO shops (name, location)
+VALUES ('onaga-ya',
+ST_GeomFromText('POINT(139.81105 35.698254)'));
+INSERT INTO shops (name, location)
+VALUES ('shiro-ya',
+ST_GeomFromText('POINT(139.638611 35.705517)'));
+INSERT INTO shops (name, location)
+VALUES ('fuji-ya',
+ST_GeomFromText('POINT(139.637115 35.703938)'));
+INSERT INTO shops (name, location)
+VALUES ('miyoshi',
+ST_GeomFromText('POINT(139.537323 35.644539)'));
+INSERT INTO shops (name, location)
+VALUES ('juju-ya',
+ST_GeomFromText('POINT(139.695755 35.628922)'));
+INSERT INTO shops (name, location)
+VALUES ('tatsumi-ya',
+ST_GeomFromText('POINT(139.638657 35.665501)'));
+INSERT INTO shops (name, location)
+VALUES ('tetsuji',
+ST_GeomFromText('POINT(139.76857 35.680912)'));
+INSERT INTO shops (name, location)
+VALUES ('gazuma-ya',
+ST_GeomFromText('POINT(139.647598 35.700817)'));
+INSERT INTO shops (name, location)
+VALUES ('honma-mon',
+ST_GeomFromText('POINT(139.652573 35.722736)'));
+INSERT INTO shops (name, location)
+VALUES ('naniwa-ya',
+ST_GeomFromText('POINT(139.796234 35.730061)'));
+INSERT INTO shops (name, location)
+VALUES ('kuro-dai',
+ST_GeomFromText('POINT(139.704834 35.650345)'));
+INSERT INTO shops (name, location)
+VALUES ('daruma',
+ST_GeomFromText('POINT(139.770599 35.681461)'));
+INSERT INTO shops (name, location)
+VALUES ('yanagi-ya',
+ST_GeomFromText('POINT(139.783981 35.685341)'));
+INSERT INTO shops (name, location)
+VALUES ('sharaku',
+ST_GeomFromText('POINT(139.794846 35.716969)'));
+INSERT INTO shops (name, location)
+VALUES ('takane',
+ST_GeomFromText('POINT(139.560913 35.698601)'));
+INSERT INTO shops (name, location)
+VALUES ('chiyoda',
+ST_GeomFromText('POINT(139.652817 35.642601)'));
+INSERT INTO shops (name, location)
+VALUES ('da-ka-po',
+ST_GeomFromText('POINT(139.727356 35.627346)'));
+INSERT INTO shops (name, location)
+VALUES ('matsushima-ya',
+ST_GeomFromText('POINT(139.737381 35.640556)'));
+INSERT INTO shops (name, location)
+VALUES ('kazuya',
+ST_GeomFromText('POINT(139.760895 35.673508)'));
+INSERT INTO shops (name, location)
+VALUES ('furuya-kogane-an',
+ST_GeomFromText('POINT(139.676071 35.680603)'));
+INSERT INTO shops (name, location)
+VALUES ('hachi-no-ie',
+ST_GeomFromText('POINT(139.668106 35.608021)'));
+INSERT INTO shops (name, location)
+VALUES ('azuki-chan',
+ST_GeomFromText('POINT(139.673203 35.64151)'));
+INSERT INTO shops (name, location)
+VALUES ('kuriko-an',
+ST_GeomFromText('POINT(139.796829 35.712013)'));
+INSERT INTO shops (name, location)
+VALUES ('yume-no-aru-machi-no-taiyaki-ya-san',
+ST_GeomFromText('POINT(139.712524 35.616199)'));
+INSERT INTO shops (name, location)
+VALUES ('naze-ya',
+ST_GeomFromText('POINT(139.665833 35.609039)'));
+INSERT INTO shops (name, location)
+VALUES ('sanoki-ya',
+ST_GeomFromText('POINT(139.770721 35.66592)'));
+INSERT INTO shops (name, location)
+VALUES ('shigeta',
+ST_GeomFromText('POINT(139.780273 35.672626)'));
+INSERT INTO shops (name, location)
+VALUES ('nishimi-ya',
+ST_GeomFromText('POINT(139.774628 35.671825)'));
+INSERT INTO shops (name, location)
+VALUES ('hiiragi',
+ST_GeomFromText('POINT(139.711517 35.647701)'));
+SELECT id, name, ST_AsText(location) AS location_text FROM shops;
+id name location_text
+1 nezu-no-taiyaki POINT(139.76257305555555 35.72025305555556)
+2 taiyaki-kataoka POINT(139.7155911111111 35.712521111111116)
+3 soba-taiyaki-ku POINT(139.65908805555557 35.68371194444445)
+4 kuruma POINT(139.70620694444446 35.72151611111111)
+5 hirose-ya POINT(139.68560805555555 35.71484388888889)
+6 sazare POINT(139.68504305555555 35.71465305555556)
+7 omede-taiyaki POINT(139.8171538888889 35.70051611111111)
+8 onaga-ya POINT(139.81105 35.69825388888889)
+9 shiro-ya POINT(139.63861111111112 35.70551694444445)
+10 fuji-ya POINT(139.637115 35.703938055555554)
+11 miyoshi POINT(139.53732305555556 35.644538888888896)
+12 juju-ya POINT(139.69575500000002 35.62892194444445)
+13 tatsumi-ya POINT(139.63865694444445 35.66550111111111)
+14 tetsuji POINT(139.76857 35.680911944444446)
+15 gazuma-ya POINT(139.64759805555553 35.70081694444444)
+16 honma-mon POINT(139.65257305555556 35.72273611111111)
+17 naniwa-ya POINT(139.79623388888888 35.73006111111111)
+18 kuro-dai POINT(139.70483388888888 35.650345)
+19 daruma POINT(139.7705988888889 35.68146111111111)
+20 yanagi-ya POINT(139.78398111111113 35.685341111111114)
+21 sharaku POINT(139.79484611111113 35.71696888888889)
+22 takane POINT(139.56091305555555 35.69860111111112)
+23 chiyoda POINT(139.65281694444442 35.64260111111111)
+24 da-ka-po POINT(139.72735611111113 35.62734611111111)
+25 matsushima-ya POINT(139.73738111111112 35.64055611111111)
+26 kazuya POINT(139.760895 35.67350805555556)
+27 furuya-kogane-an POINT(139.67607111111113 35.68060305555556)
+28 hachi-no-ie POINT(139.66810611111111 35.608021111111114)
+29 azuki-chan POINT(139.67320305555555 35.641510000000004)
+30 kuriko-an POINT(139.79682888888888 35.71201305555556)
+31 yume-no-aru-machi-no-taiyaki-ya-san POINT(139.71252388888888 35.61619888888889)
+32 naze-ya POINT(139.66583305555557 35.60903888888889)
+33 sanoki-ya POINT(139.7707211111111 35.66592)
+34 shigeta POINT(139.78027305555557 35.67262611111111)
+35 nishimi-ya POINT(139.77462805555555 35.671825)
+36 hiiragi POINT(139.71151694444444 35.64770111111111)
+SELECT id, name, ST_AsText(location) AS location_text FROM shops
+WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location)
+ORDER BY id;
+id name location_text
+14 tetsuji POINT(139.76857 35.680911944444446)
+19 daruma POINT(139.7705988888889 35.68146111111111)
+26 kazuya POINT(139.760895 35.67350805555556)
+EXPLAIN
+SELECT id, name, ST_AsText(location) AS location_text FROM shops
+WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location)
+ORDER BY id;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE shops NULL range location_index location_index 34 NULL 36 100.00 Using where; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `test`.`shops`.`id` AS `id`,`test`.`shops`.`name` AS `name`,st_astext(`test`.`shops`.`location`) AS `location_text` from `test`.`shops` where mbrcontains(<cache>(st_geometryfromtext('LineString(139.7727 35.6684, 139.7038 35.7121)')),`test`.`shops`.`location`) order by `test`.`shops`.`id`
+DROP TABLE shops;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_hash_id_primary.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_hash_id_primary.result
index b27c0ee028c..b0bbaf09e4c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_hash_id_primary.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_hash_id_primary.result
@@ -1,28 +1,28 @@
-drop table if exists t1, t2, t3;
-create table t1 (_id int, a int, primary key (_id) using hash);
-insert into t1 values(null, 100);
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (_id int, a int, PRIMARY KEY (_id) USING HASH);
+INSERT INTO t1 VALUES(null, 100);
ERROR 23000: Column '_id' cannot be null
-insert ignore into t1 values(1,100);
+INSERT INTO t1 VALUES(1,100);
Warnings:
Warning 1265 Data truncated for column '_id' at row 1
-insert ignore into t1 values(1,100);
+INSERT INTO t1 VALUES(1,100);
Warnings:
Warning 1265 Data truncated for column '_id' at row 1
-insert ignore into t1 values(1,100);
+INSERT INTO t1 VALUES(1,100);
Warnings:
Warning 1265 Data truncated for column '_id' at row 1
-insert ignore into t1 values(1,100);
+INSERT INTO t1 VALUES(1,100);
Warnings:
Warning 1265 Data truncated for column '_id' at row 1
-select * from t1;
+SELECT * FROM t1;
_id a
1 100
2 100
3 100
4 100
-select * from t1 where _id = 2;
+SELECT * FROM t1 WHERE _id = 2;
_id a
2 100
-select * from t1 where _id = 20;
+SELECT * FROM t1 WHERE _id = 20;
_id a
-drop table t1;
+DROP TABLE t1;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_hash_strict_sql_mode_id_primary.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_hash_strict_sql_mode_id_primary.result
new file mode 100644
index 00000000000..8fb46156fb7
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_hash_strict_sql_mode_id_primary.result
@@ -0,0 +1,19 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (_id int, a int, PRIMARY KEY (_id) USING HASH);
+INSERT INTO t1 VALUES(null, 100);
+ERROR 23000: Column '_id' cannot be null
+INSERT INTO t1 VALUES(1,100);
+ERROR 01000: Data truncated for column '_id' at row 1
+INSERT INTO t1 VALUES(1,100);
+ERROR 01000: Data truncated for column '_id' at row 1
+INSERT INTO t1 VALUES(1,100);
+ERROR 01000: Data truncated for column '_id' at row 1
+INSERT INTO t1 VALUES(1,100);
+ERROR 01000: Data truncated for column '_id' at row 1
+SELECT * FROM t1;
+_id a
+SELECT * FROM t1 WHERE _id = 2;
+_id a
+SELECT * FROM t1 WHERE _id = 20;
+_id a
+DROP TABLE t1;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_order_by_where_equal_asc_asc.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_order_by_where_equal_asc_asc.result
new file mode 100644
index 00000000000..055ca69f884
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_order_by_where_equal_asc_asc.result
@@ -0,0 +1,40 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT,
+score2 INT,
+score3 INT,
+INDEX (score1, score2, score3)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+Table Create Table
+items CREATE TABLE `items` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `score1` int(11) DEFAULT NULL,
+ `score2` int(11) DEFAULT NULL,
+ `score3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `score1` (`score1`,`score2`,`score3`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO items (score1, score2, score3) VALUES(1, 10, -100);
+INSERT INTO items (score1, score2, score3) VALUES(1, 10, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 10, 100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, -100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, 100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, -100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, 100);
+SELECT *
+FROM items
+WHERE score1 = 2
+ORDER BY score2 ASC, score3 ASC;
+id score1 score2 score3
+3 2 10 100
+7 2 20 -100
+8 2 20 0
+9 2 20 100
+4 2 30 -100
+5 2 30 0
+6 2 30 100
+DROP TABLE items;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_order_by_where_equal_desc_desc.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_order_by_where_equal_desc_desc.result
new file mode 100644
index 00000000000..0d7faddcaa8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_order_by_where_equal_desc_desc.result
@@ -0,0 +1,40 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT,
+score2 INT,
+score3 INT,
+INDEX (score1, score2, score3)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+Table Create Table
+items CREATE TABLE `items` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `score1` int(11) DEFAULT NULL,
+ `score2` int(11) DEFAULT NULL,
+ `score3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `score1` (`score1`,`score2`,`score3`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO items (score1, score2, score3) VALUES(1, 10, -100);
+INSERT INTO items (score1, score2, score3) VALUES(1, 10, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 10, 100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, -100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, 100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, -100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, 100);
+SELECT *
+FROM items
+WHERE score1 = 2
+ORDER BY score2 DESC, score3 DESC;
+id score1 score2 score3
+6 2 30 100
+5 2 30 0
+4 2 30 -100
+9 2 20 100
+8 2 20 0
+7 2 20 -100
+3 2 10 100
+DROP TABLE items;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_primary_strict_sql_mode_update.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_primary_strict_sql_mode_update.result
new file mode 100644
index 00000000000..b390ca7a8cf
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_primary_strict_sql_mode_update.result
@@ -0,0 +1,26 @@
+DROP TABLE IF EXISTS scores;
+SET NAMES utf8;
+CREATE TABLE scores (
+name char(30) NOT NULL,
+score int NOT NULL,
+PRIMARY KEY (name, score)
+) DEFAULT CHARSET=utf8;
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", 29);
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", -12);
+INSERT INTO scores (name, score) VALUES ("Jiro Yamada", 27);
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", 10);
+SELECT * FROM scores;
+name score
+Jiro Yamada 27
+Taro Yamada -12
+Taro Yamada 10
+Taro Yamada 29
+UPDATE scores SET name = "Taro Yamada"
+ WHERE name = "Jiro Yamada" AND score = 27;
+ERROR 01000: data truncated for primary key column: <name>
+SELECT * FROM scores
+WHERE name = "Taro Yamada" AND (score >= -12 AND score < 29);
+name score
+Taro Yamada -12
+Taro Yamada 10
+DROP TABLE scores;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_primary_update.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_primary_update.result
index ff2f975f94f..a58a487a178 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_primary_update.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_primary_update.result
@@ -1,32 +1,27 @@
-drop table if exists listing;
-set names utf8;
-create table scores (
-name char(30) not null,
-score int not null,
-primary key (name, score)
-) default charset utf8;
-show create table scores;
-Table Create Table
-scores CREATE TABLE `scores` (
- `name` char(30) NOT NULL,
- `score` int(11) NOT NULL,
- PRIMARY KEY (`name`,`score`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
-insert into scores (name, score) values("Taro Yamada", 29);
-insert into scores (name, score) values("Taro Yamada", -12);
-insert into scores (name, score) values("Jiro Yamada", 27);
-insert into scores (name, score) values("Taro Yamada", 10);
-select * from scores;
+DROP TABLE IF EXISTS scores;
+SET NAMES utf8;
+CREATE TABLE scores (
+name char(30) NOT NULL,
+score int NOT NULL,
+PRIMARY KEY (name, score)
+) DEFAULT CHARSET=utf8;
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", 29);
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", -12);
+INSERT INTO scores (name, score) VALUES ("Jiro Yamada", 27);
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", 10);
+SELECT * FROM scores;
name score
Jiro Yamada 27
Taro Yamada -12
Taro Yamada 10
Taro Yamada 29
-update ignore scores set name = "Taro Yamada" where name = "Jiro Yamada" and score = 27;
+UPDATE scores SET name = "Taro Yamada"
+ WHERE name = "Jiro Yamada" AND score = 27;
Warnings:
Warning 1265 data truncated for primary key column: <name>
-select * from scores where name = "Taro Yamada" and (score >= -12 and score < 29);
+SELECT * FROM scores
+WHERE name = "Taro Yamada" AND (score >= -12 AND score < 29);
name score
Taro Yamada -12
Taro Yamada 10
-drop table scores;
+DROP TABLE scores;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_greater_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_greater_than.result
index 870c5ba73e5..870c5ba73e5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_greater_than.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_greater_than.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_greater_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_greater_than_or_equal.result
index 06661210817..06661210817 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_greater_than_or_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_greater_than_or_equal.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_less_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_less_than.result
index f528f90b7dc..f528f90b7dc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_less_than.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_less_than.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_less_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_less_than_or_equal.result
index 9250ecb8dbc..9250ecb8dbc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_not_used_in_order_by_less_than_or_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_all_used_less_than_or_equal.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_greater_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_greater_than.result
new file mode 100644
index 00000000000..8e5f4329a51
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_greater_than.result
@@ -0,0 +1,34 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT,
+score2 INT,
+created_at DATETIME,
+INDEX (score1, created_at, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+Table Create Table
+items CREATE TABLE `items` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `score1` int(11) DEFAULT NULL,
+ `score2` int(11) DEFAULT NULL,
+ `created_at` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `score1` (`score1`,`created_at`,`score2`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-02 00:00:00");
+SELECT *
+FROM items
+WHERE score1 = 2 AND created_at > "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+id score1 score2 created_at
+8 2 0 2015-07-02 00:00:00
+DROP TABLE items;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_greater_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_greater_than_or_equal.result
new file mode 100644
index 00000000000..1a3021e2815
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_greater_than_or_equal.result
@@ -0,0 +1,35 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT,
+score2 INT,
+created_at DATETIME,
+INDEX (score1, created_at, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+Table Create Table
+items CREATE TABLE `items` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `score1` int(11) DEFAULT NULL,
+ `score2` int(11) DEFAULT NULL,
+ `created_at` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `score1` (`score1`,`created_at`,`score2`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-02 00:00:00");
+SELECT *
+FROM items
+WHERE score1 = 2 AND created_at >= "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+id score1 score2 created_at
+8 2 0 2015-07-02 00:00:00
+5 2 0 2015-07-01 12:00:00
+DROP TABLE items;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_less_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_less_than.result
new file mode 100644
index 00000000000..6adaa9870dc
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_less_than.result
@@ -0,0 +1,34 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT,
+score2 INT,
+created_at DATETIME,
+INDEX (score1, created_at, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+Table Create Table
+items CREATE TABLE `items` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `score1` int(11) DEFAULT NULL,
+ `score2` int(11) DEFAULT NULL,
+ `created_at` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `score1` (`score1`,`created_at`,`score2`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-02 00:00:00");
+SELECT *
+FROM items
+WHERE score1 = 2 AND created_at < "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+id score1 score2 created_at
+2 2 0 2015-07-01 00:00:00
+DROP TABLE items;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_less_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_less_than_or_equal.result
new file mode 100644
index 00000000000..dfc7ef6fe43
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_have_prefix_less_than_or_equal.result
@@ -0,0 +1,35 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT,
+score2 INT,
+created_at DATETIME,
+INDEX (score1, created_at, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+Table Create Table
+items CREATE TABLE `items` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `score1` int(11) DEFAULT NULL,
+ `score2` int(11) DEFAULT NULL,
+ `created_at` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `score1` (`score1`,`created_at`,`score2`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-02 00:00:00");
+SELECT *
+FROM items
+WHERE score1 = 2 AND created_at <= "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+id score1 score2 created_at
+5 2 0 2015-07-01 12:00:00
+2 2 0 2015-07-01 00:00:00
+DROP TABLE items;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_greater_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_greater_than.result
new file mode 100644
index 00000000000..502c0c10447
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_greater_than.result
@@ -0,0 +1,29 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT,
+score2 INT,
+created_at DATETIME,
+INDEX (created_at, score1, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+Table Create Table
+items CREATE TABLE `items` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `score1` int(11) DEFAULT NULL,
+ `score2` int(11) DEFAULT NULL,
+ `created_at` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `created_at` (`created_at`,`score1`,`score2`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+SELECT *
+FROM items
+WHERE created_at > "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+id score1 score2 created_at
+4 2 0 2015-07-02 00:00:00
+DROP TABLE items;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_greater_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_greater_than_or_equal.result
new file mode 100644
index 00000000000..60ffa88b4b5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_greater_than_or_equal.result
@@ -0,0 +1,30 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT,
+score2 INT,
+created_at DATETIME,
+INDEX (created_at, score1, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+Table Create Table
+items CREATE TABLE `items` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `score1` int(11) DEFAULT NULL,
+ `score2` int(11) DEFAULT NULL,
+ `created_at` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `created_at` (`created_at`,`score1`,`score2`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+SELECT *
+FROM items
+WHERE created_at >= "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+id score1 score2 created_at
+4 2 0 2015-07-02 00:00:00
+3 2 0 2015-07-01 12:00:00
+DROP TABLE items;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_less_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_less_than.result
new file mode 100644
index 00000000000..2cdb3de3fb8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_less_than.result
@@ -0,0 +1,30 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT,
+score2 INT,
+created_at DATETIME,
+INDEX (created_at, score1, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+Table Create Table
+items CREATE TABLE `items` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `score1` int(11) DEFAULT NULL,
+ `score2` int(11) DEFAULT NULL,
+ `created_at` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `created_at` (`created_at`,`score1`,`score2`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+SELECT *
+FROM items
+WHERE created_at < "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+id score1 score2 created_at
+2 2 0 2015-07-01 00:00:00
+1 1 0 2015-07-01 00:00:00
+DROP TABLE items;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_less_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_less_than_or_equal.result
new file mode 100644
index 00000000000..3443bbc3ed1
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_range_partially_used_no_prefix_less_than_or_equal.result
@@ -0,0 +1,31 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT,
+score2 INT,
+created_at DATETIME,
+INDEX (created_at, score1, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+Table Create Table
+items CREATE TABLE `items` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `score1` int(11) DEFAULT NULL,
+ `score2` int(11) DEFAULT NULL,
+ `created_at` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `created_at` (`created_at`,`score1`,`score2`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+SELECT *
+FROM items
+WHERE created_at <= "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+id score1 score2 created_at
+3 2 0 2015-07-01 12:00:00
+2 2 0 2015-07-01 00:00:00
+1 1 0 2015-07-01 00:00:00
+DROP TABLE items;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_select_max.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_select_max.result
new file mode 100644
index 00000000000..b6091784805
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_select_max.result
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS listing;
+CREATE TABLE scores (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT NOT NULL,
+score2 INT NOT NULL,
+INDEX (score1, score2)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO scores (score1, score2) VALUES(1, 1);
+INSERT INTO scores (score1, score2) VALUES(1, 2);
+INSERT INTO scores (score1, score2) VALUES(2, 3);
+INSERT INTO scores (score1, score2) VALUES(2, 2);
+INSERT INTO scores (score1, score2) VALUES(2, 1);
+INSERT INTO scores (score1, score2) VALUES(2, 0);
+INSERT INTO scores (score1, score2) VALUES(2, -1);
+INSERT INTO scores (score1, score2) VALUES(2, -2);
+INSERT INTO scores (score1, score2) VALUES(2, -3);
+SELECT MAX(score2) FROM scores WHERE score1 = 2;
+MAX(score2)
+3
+DROP TABLE scores;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_select_min.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_select_min.result
new file mode 100644
index 00000000000..0792751ad02
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_select_min.result
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS listing;
+CREATE TABLE scores (
+id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+score1 INT NOT NULL,
+score2 INT NOT NULL,
+INDEX (score1, score2)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO scores (score1, score2) VALUES(1, 1);
+INSERT INTO scores (score1, score2) VALUES(1, 2);
+INSERT INTO scores (score1, score2) VALUES(2, 3);
+INSERT INTO scores (score1, score2) VALUES(2, 2);
+INSERT INTO scores (score1, score2) VALUES(2, 1);
+INSERT INTO scores (score1, score2) VALUES(2, 0);
+INSERT INTO scores (score1, score2) VALUES(2, -1);
+INSERT INTO scores (score1, score2) VALUES(2, -2);
+INSERT INTO scores (score1, score2) VALUES(2, -3);
+SELECT MIN(score2) FROM scores WHERE score1 = 2;
+MIN(score2)
+-3
+DROP TABLE scores;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_64bit_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_64bit_equal.result
index 869ced05d25..21168547286 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_64bit_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_64bit_equal.result
@@ -5,12 +5,12 @@ start DATE,
end DATE,
UNIQUE KEY range_key(start, end)
);
-INSERT INTO ranges VALUES (1, "1000-01-01", "2012-10-05");
-INSERT INTO ranges VALUES (2, "1000-01-01", "9999-12-31");
+INSERT INTO ranges VALUES (1, "1000-01-02", "2012-10-05");
+INSERT INTO ranges VALUES (2, "1000-01-02", "9999-12-31");
INSERT INTO ranges VALUES (3, "2012-10-25", "9999-12-31");
-INSERT INTO ranges VALUES (4, "9999-12-31", "1000-01-01");
+INSERT INTO ranges VALUES (4, "9999-12-31", "1000-01-02");
SELECT * FROM ranges FORCE INDEX(range_key)
-WHERE start = "1000-01-01" AND end = "9999-12-31";
+WHERE start = "1000-01-02" AND end = "9999-12-31";
id start end
-2 1000-01-01 9999-12-31
+2 1000-01-02 9999-12-31
DROP TABLE ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_index_read.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_index_read.result
index 8e480d4844a..93e34d88c2a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_index_read.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_index_read.result
@@ -5,16 +5,16 @@ start DATE,
end DATE,
UNIQUE KEY range_key(start, end)
);
-INSERT INTO ranges VALUES (1, "1000-01-01", "2012-10-05");
-INSERT INTO ranges VALUES (2, "1000-01-01", "9999-12-31");
+INSERT INTO ranges VALUES (1, "1000-01-02", "2012-10-05");
+INSERT INTO ranges VALUES (2, "1000-01-02", "9999-12-31");
INSERT INTO ranges VALUES (3, "2012-10-25", "9999-12-31");
-INSERT INTO ranges VALUES (4, "9999-12-31", "1000-01-01");
+INSERT INTO ranges VALUES (4, "9999-12-31", "1000-01-02");
SELECT start, end
FROM ranges FORCE INDEX(range_key)
ORDER BY start, end;
start end
-1000-01-01 2012-10-05
-1000-01-01 9999-12-31
+1000-01-02 2012-10-05
+1000-01-02 9999-12-31
2012-10-25 9999-12-31
-9999-12-31 1000-01-01
+9999-12-31 1000-01-02
DROP TABLE ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_order_64bit_asc.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_order_64bit_asc.result
index 92e7f51ff6e..c2a94a848a9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_order_64bit_asc.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_order_64bit_asc.result
@@ -6,14 +6,14 @@ end DATE,
UNIQUE KEY range_key(start, end)
);
INSERT INTO ranges VALUES (1, "2012-10-25", "9999-12-31");
-INSERT INTO ranges VALUES (2, "1000-01-01", "2012-10-05");
-INSERT INTO ranges VALUES (3, "9999-12-31", "1000-01-01");
-INSERT INTO ranges VALUES (4, "1000-01-01", "9999-12-31");
+INSERT INTO ranges VALUES (2, "1000-01-02", "2012-10-05");
+INSERT INTO ranges VALUES (3, "9999-12-31", "1000-01-02");
+INSERT INTO ranges VALUES (4, "1000-01-02", "9999-12-31");
SELECT * FROM ranges FORCE INDEX(range_key)
ORDER BY start, end;
id start end
-2 1000-01-01 2012-10-05
-4 1000-01-01 9999-12-31
+2 1000-01-02 2012-10-05
+4 1000-01-02 9999-12-31
1 2012-10-25 9999-12-31
-3 9999-12-31 1000-01-01
+3 9999-12-31 1000-01-02
DROP TABLE ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_order_64bit_desc.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_order_64bit_desc.result
index ddd694c3863..2d100156010 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_order_64bit_desc.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_date_order_64bit_desc.result
@@ -6,14 +6,14 @@ end DATE,
UNIQUE KEY range_key(start, end)
);
INSERT INTO ranges VALUES (1, "2012-10-25", "9999-12-31");
-INSERT INTO ranges VALUES (2, "1000-01-01", "2012-10-05");
-INSERT INTO ranges VALUES (3, "9999-12-31", "1000-01-01");
-INSERT INTO ranges VALUES (4, "1000-01-01", "9999-12-31");
+INSERT INTO ranges VALUES (2, "1000-01-02", "2012-10-05");
+INSERT INTO ranges VALUES (3, "9999-12-31", "1000-01-02");
+INSERT INTO ranges VALUES (4, "1000-01-02", "9999-12-31");
SELECT * FROM ranges FORCE INDEX(range_key)
ORDER BY start DESC, end DESC;
id start end
-3 9999-12-31 1000-01-01
+3 9999-12-31 1000-01-02
1 2012-10-25 9999-12-31
-4 1000-01-01 9999-12-31
-2 1000-01-01 2012-10-05
+4 1000-01-02 9999-12-31
+2 1000-01-02 2012-10-05
DROP TABLE ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_index_read.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_index_read.result
index 1aa710882cb..a8546c4bcbf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_index_read.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_index_read.result
@@ -5,16 +5,16 @@ start datetime,
end datetime,
UNIQUE KEY range_key(start, end)
);
-INSERT INTO ranges VALUES (1, "1000-01-01 00:00:00", "2012-10-05 16:18:29");
-INSERT INTO ranges VALUES (2, "1000-01-01 00:00:00", "9999-12-31 23:59:59");
+INSERT INTO ranges VALUES (1, "1000-01-02 00:00:00", "2012-10-05 16:18:29");
+INSERT INTO ranges VALUES (2, "1000-01-02 00:00:00", "9999-12-31 23:59:59");
INSERT INTO ranges VALUES (3, "2012-10-25 16:18:29", "9999-12-31 23:59:59");
-INSERT INTO ranges VALUES (4, "9999-12-31 23:59:59", "1000-01-01 00:00:00");
+INSERT INTO ranges VALUES (4, "9999-12-31 23:59:59", "1000-01-02 00:00:00");
SELECT start, end
FROM ranges FORCE INDEX(range_key)
ORDER BY start, end;
start end
-1000-01-01 00:00:00 2012-10-05 16:18:29
-1000-01-01 00:00:00 9999-12-31 23:59:59
+1000-01-02 00:00:00 2012-10-05 16:18:29
+1000-01-02 00:00:00 9999-12-31 23:59:59
2012-10-25 16:18:29 9999-12-31 23:59:59
-9999-12-31 23:59:59 1000-01-01 00:00:00
+9999-12-31 23:59:59 1000-01-02 00:00:00
DROP TABLE ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_order_asc.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_order_asc.result
index d18f1858932..5cffb71d644 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_order_asc.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_order_asc.result
@@ -6,14 +6,14 @@ end datetime,
UNIQUE KEY range_key(start, end)
);
INSERT INTO ranges VALUES (1, "2012-10-25 16:18:29", "9999-12-31 23:59:59");
-INSERT INTO ranges VALUES (2, "1000-01-01 00:00:00", "2012-10-05 16:18:29");
-INSERT INTO ranges VALUES (3, "9999-12-31 23:59:59", "1000-01-01 00:00:00");
-INSERT INTO ranges VALUES (4, "1000-01-01 00:00:00", "9999-12-31 23:59:59");
+INSERT INTO ranges VALUES (2, "1000-01-02 00:00:00", "2012-10-05 16:18:29");
+INSERT INTO ranges VALUES (3, "9999-12-31 23:59:59", "1000-01-02 00:00:00");
+INSERT INTO ranges VALUES (4, "1000-01-02 00:00:00", "9999-12-31 23:59:59");
SELECT * FROM ranges FORCE INDEX(range_key)
ORDER BY start, end;
id start end
-2 1000-01-01 00:00:00 2012-10-05 16:18:29
-4 1000-01-01 00:00:00 9999-12-31 23:59:59
+2 1000-01-02 00:00:00 2012-10-05 16:18:29
+4 1000-01-02 00:00:00 9999-12-31 23:59:59
1 2012-10-25 16:18:29 9999-12-31 23:59:59
-3 9999-12-31 23:59:59 1000-01-01 00:00:00
+3 9999-12-31 23:59:59 1000-01-02 00:00:00
DROP TABLE ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_order_desc.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_order_desc.result
index c159aeab4ce..4429f787b76 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_order_desc.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_order_desc.result
@@ -6,14 +6,14 @@ end datetime,
UNIQUE KEY range_key(start, end)
);
INSERT INTO ranges VALUES (1, "2012-10-25 16:18:29", "9999-12-31 23:59:59");
-INSERT INTO ranges VALUES (2, "1000-01-01 00:00:00", "2012-10-05 16:18:29");
-INSERT INTO ranges VALUES (3, "9999-12-31 23:59:59", "1000-01-01 00:00:00");
-INSERT INTO ranges VALUES (4, "1000-01-01 00:00:00", "9999-12-31 23:59:59");
+INSERT INTO ranges VALUES (2, "1000-01-02 00:00:00", "2012-10-05 16:18:29");
+INSERT INTO ranges VALUES (3, "9999-12-31 23:59:59", "1000-01-02 00:00:00");
+INSERT INTO ranges VALUES (4, "1000-01-02 00:00:00", "9999-12-31 23:59:59");
SELECT * FROM ranges FORCE INDEX(range_key)
ORDER BY start DESC, end DESC;
id start end
-3 9999-12-31 23:59:59 1000-01-01 00:00:00
+3 9999-12-31 23:59:59 1000-01-02 00:00:00
1 2012-10-25 16:18:29 9999-12-31 23:59:59
-4 1000-01-01 00:00:00 9999-12-31 23:59:59
-2 1000-01-01 00:00:00 2012-10-05 16:18:29
+4 1000-01-02 00:00:00 9999-12-31 23:59:59
+2 1000-01-02 00:00:00 2012-10-05 16:18:29
DROP TABLE ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_index_read.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_index_read.result
index d833fb44024..92e95d9276c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_index_read.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_index_read.result
@@ -1,8 +1,8 @@
DROP TABLE IF EXISTS ranges;
CREATE TABLE ranges (
id int PRIMARY KEY,
-start timestamp,
-end timestamp,
+start timestamp DEFAULT '2016-04-21 00:00:00',
+end timestamp DEFAULT '2016-04-22 00:00:00',
UNIQUE KEY range_key(start, end)
);
INSERT INTO ranges VALUES (1, "1970-01-01 12:00:00", "2012-10-05 16:18:29");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_order_asc.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_order_asc.result
index 1e4ee102c9e..35bc4123d65 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_order_asc.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_order_asc.result
@@ -1,8 +1,8 @@
DROP TABLE IF EXISTS ranges;
CREATE TABLE ranges (
id int PRIMARY KEY,
-start timestamp,
-end timestamp,
+start timestamp DEFAULT '2016-04-21 00:00:00',
+end timestamp DEFAULT '2016-04-22 00:00:00',
UNIQUE KEY range_key(start, end)
);
INSERT INTO ranges VALUES (1, "2012-10-25 16:18:29", "2038-01-18 15:14:07");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_order_desc.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_order_desc.result
index 23a5522320a..fbf88cf3d0a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_order_desc.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_order_desc.result
@@ -1,8 +1,8 @@
DROP TABLE IF EXISTS ranges;
CREATE TABLE ranges (
id int PRIMARY KEY,
-start timestamp,
-end timestamp,
+start timestamp DEFAULT '2016-04-21 00:00:00',
+end timestamp DEFAULT '2016-04-22 00:00:00',
UNIQUE KEY range_key(start, end)
);
INSERT INTO ranges VALUES (1, "2012-10-25 16:18:29", "2038-01-18 15:14:07");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_reinsert.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_reinsert.result
index 3f3277f5e64..b799cc278e1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_reinsert.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_timestamp_reinsert.result
@@ -1,8 +1,8 @@
DROP TABLE IF EXISTS ranges;
CREATE TABLE ranges (
id int PRIMARY KEY,
-start timestamp,
-end timestamp,
+start timestamp DEFAULT '2016-04-21 00:00:00',
+end timestamp DEFAULT '2016-04-22 00:00:00',
UNIQUE KEY range_key(start, end)
);
INSERT INTO ranges VALUES (1, "2010-01-01 00:00:00", "2012-10-05 23:59:59");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_date.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_date.result
index d6ce9873606..b1eafd2d048 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_date.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_date.result
@@ -3,13 +3,6 @@ CREATE TABLE diaries (
day DATE PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `day` date NOT NULL,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`day`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (day, title) VALUES ("2012-01-29", "clear day");
INSERT INTO diaries (day, title) VALUES ("2012-01-30", "rainy day");
INSERT INTO diaries (day, title) VALUES ("2012-01-31", "cloudy day");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_datetime_with_fractional_seconds.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_datetime_with_fractional_seconds.result
index 2cf83ae6aa5..0ae41c513dc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_datetime_with_fractional_seconds.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_datetime_with_fractional_seconds.result
@@ -3,13 +3,6 @@ CREATE TABLE diaries (
day DATETIME(6) PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `day` datetime(6) NOT NULL,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`day`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (day, title)
VALUES ("2012-01-29 21:51:01.111111", "clear day");
INSERT INTO diaries (day, title)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_datetime_without_fractional_seconds.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_datetime_without_fractional_seconds.result
index f605346130b..f5e743dc9e7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_datetime_without_fractional_seconds.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_datetime_without_fractional_seconds.result
@@ -3,13 +3,6 @@ CREATE TABLE diaries (
day DATETIME PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `day` datetime NOT NULL,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`day`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (day, title)
VALUES ("2012-01-29 21:51:01", "clear day");
INSERT INTO diaries (day, title)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_decimal_with_fractional_seconds.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_decimal_with_fractional_seconds.result
index 4e8386251e7..6a529b50692 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_decimal_with_fractional_seconds.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_decimal_with_fractional_seconds.result
@@ -3,13 +3,6 @@ CREATE TABLE releases (
version DECIMAL(6, 3) PRIMARY KEY,
message TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE releases;
-Table Create Table
-releases CREATE TABLE `releases` (
- `version` decimal(6,3) NOT NULL,
- `message` text DEFAULT NULL,
- PRIMARY KEY (`version`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO releases (version, message) VALUES (10.000, "10th release!");
INSERT INTO releases (version, message) VALUES (10.001, "minor fix.");
INSERT INTO releases (version, message) VALUES (999.999, "the last release!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_decimal_without_fractional_seconds.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_decimal_without_fractional_seconds.result
index c7d9f4db5c0..d36688bb13c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_decimal_without_fractional_seconds.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_decimal_without_fractional_seconds.result
@@ -3,13 +3,6 @@ CREATE TABLE releases (
version DECIMAL PRIMARY KEY,
message TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE releases;
-Table Create Table
-releases CREATE TABLE `releases` (
- `version` decimal(10,0) NOT NULL,
- `message` text DEFAULT NULL,
- PRIMARY KEY (`version`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO releases (version, message) VALUES (1, "the first release!!!");
INSERT INTO releases (version, message) VALUES (10, "10th release!");
INSERT INTO releases (version, message) VALUES (999, "the last release!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_time_with_fractional_seconds.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_time_with_fractional_seconds.result
index 705f311a5d8..5437c789791 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_time_with_fractional_seconds.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_time_with_fractional_seconds.result
@@ -3,13 +3,6 @@ CREATE TABLE running_records (
time TIME(6) PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE running_records;
-Table Create Table
-running_records CREATE TABLE `running_records` (
- `time` time(6) NOT NULL,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`time`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO running_records (time, title)
VALUES ("01:00:00.000001", "normal condition");
INSERT INTO running_records (time, title)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_time_without_fractional_seconds.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_time_without_fractional_seconds.result
index d8807f34257..e59dee4c688 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_time_without_fractional_seconds.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_time_without_fractional_seconds.result
@@ -3,13 +3,6 @@ CREATE TABLE running_records (
time TIME PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE running_records;
-Table Create Table
-running_records CREATE TABLE `running_records` (
- `time` time NOT NULL,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`time`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO running_records (time, title)
VALUES ("01:00:00", "normal condition");
INSERT INTO running_records (time, title)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_timestamp_with_fractional_seconds.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_timestamp_with_fractional_seconds.result
index bdffb91739b..0fba3da7533 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_timestamp_with_fractional_seconds.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_timestamp_with_fractional_seconds.result
@@ -3,13 +3,6 @@ CREATE TABLE diaries (
time TIMESTAMP(6) PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6),
- `title` text DEFAULT NULL,
- PRIMARY KEY (`time`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (time, title)
VALUES ("2012-01-29 21:51:01.111111", "clear day");
INSERT INTO diaries (time, title)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_timestamp_without_fractional_seconds.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_timestamp_without_fractional_seconds.result
index 6ad90fb4107..8116bda2d60 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_timestamp_without_fractional_seconds.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_timestamp_without_fractional_seconds.result
@@ -3,13 +3,6 @@ CREATE TABLE diaries (
time TIMESTAMP PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `time` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
- `title` text DEFAULT NULL,
- PRIMARY KEY (`time`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (time, title) VALUES ("2012-01-29 21:51:01", "clear day");
INSERT INTO diaries (time, title) VALUES ("2012-01-30 01:23:45", "rainy day");
INSERT INTO diaries (time, title) VALUES ("2012-01-31 08:32:10", "cloudy day");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_year.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_year.result
index 9bdf87dffcd..78c56f258f8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_year.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_primary_year.result
@@ -3,13 +3,6 @@ CREATE TABLE aniversary_memos (
party_year YEAR PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE aniversary_memos;
-Table Create Table
-aniversary_memos CREATE TABLE `aniversary_memos` (
- `party_year` year(4) NOT NULL,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`party_year`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO aniversary_memos (party_year, title)
VALUES ("11", "We need a big cake!");
INSERT INTO aniversary_memos (party_year, title)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_unique_delete_all.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_unique_delete_all.result
new file mode 100644
index 00000000000..f2a0b28b0b6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_unique_delete_all.result
@@ -0,0 +1,14 @@
+DROP TABLE IF EXISTS ids;
+CREATE TABLE ids (
+id int,
+UNIQUE KEY (id)
+);
+INSERT INTO ids VALUES (1);
+DELETE FROM ids;
+INSERT INTO ids VALUES (1);
+SELECT * FROM ids;
+id
+1
+INSERT INTO ids VALUES (1);
+ERROR 23000: Duplicate entry '1' for key 'id'
+DROP TABLE ids;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/information_schema_tables_data_length.result b/storage/mroonga/mysql-test/mroonga/storage/r/information_schema_tables_data_length.result
index 91850d9d871..3600c92082d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/information_schema_tables_data_length.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/information_schema_tables_data_length.result
@@ -6,15 +6,6 @@ title VARCHAR(255),
content TEXT,
FULLTEXT INDEX (content)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/insert_TODO_SPLIT_ME.result b/storage/mroonga/mysql-test/mroonga/storage/r/insert_TODO_SPLIT_ME.result
index 00466f19bb5..f8d41bb784e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/insert_TODO_SPLIT_ME.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/insert_TODO_SPLIT_ME.result
@@ -65,18 +65,6 @@ select * from t1;
c1
2010-03-26 11:22:33
drop table t1;
-create table t1 (c1 int, _id int);
-set sql_mode="";
-insert into t1 (c1,_id) values (1,1);
-Warnings:
-Warning 1265 Data truncated for column '_id' at row 1
-set sql_mode="strict_all_tables";
-insert into t1 (c1,_id) values (4,1);
-ERROR 01000: Data truncated for column '_id' at row 1
-select * from t1;
-c1 _id
-1 1
-drop table t1;
create table t1 (c1 int primary key, c2 int);
insert into t1 values(1,100);
select * from t1;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_primary_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_primary_key.result
index 595b3da00cd..94421a5c200 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_primary_key.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_primary_key.result
@@ -3,13 +3,6 @@ CREATE TABLE diaries (
day DATE PRIMARY KEY,
title TEXT
) DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `day` date NOT NULL,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`day`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (day, title)
VALUES ("2012-02-14", "clear day")
ON DUPLICATE KEY UPDATE title = "clear day (duplicated)";
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_unique_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_unique_key.result
index ff6925067e5..1ef6f1f2c37 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_unique_key.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_unique_key.result
@@ -5,15 +5,6 @@ day DATE,
title TEXT,
UNIQUE KEY day (day)
) DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `day` date DEFAULT NULL,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- UNIQUE KEY `day` (`day`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (day, title)
VALUES ("2012-02-14", "clear day1")
ON DUPLICATE KEY UPDATE title = "clear day1 (duplicated)";
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/insert_virtual_column.result b/storage/mroonga/mysql-test/mroonga/storage/r/insert_virtual_column.result
new file mode 100644
index 00000000000..624ac00d3fc
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/insert_virtual_column.result
@@ -0,0 +1,13 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 int, _id int);
+SET sql_mode="";
+INSERT INTO t1 (c1,_id) VALUES (1,1);
+Warnings:
+Warning 1265 Data truncated for column '_id' at row 1
+SET sql_mode="STRICT_ALL_TABLES";
+INSERT INTO t1 (c1,_id) VALUES (4,1);
+ERROR 01000: Data truncated for column '_id' at row 1
+SELECT * FROM t1;
+c1 _id
+1 1
+DROP TABLE t1;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_TODO_SPLIT_ME.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_TODO_SPLIT_ME.result
deleted file mode 100644
index b66801094bd..00000000000
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_TODO_SPLIT_ME.result
+++ /dev/null
@@ -1,106 +0,0 @@
-drop table if exists t1, t2, t3;
-flush status;
-create table t1 (c1 int primary key, c2 int, c3 text, key idx1(c2), fulltext index ft(c3));
-insert into t1 values(1,10,"aa ii uu ee oo");
-insert into t1 values(2,20,"ka ki ku ke ko");
-insert into t1 values(3,30,"sa si su se so");
-insert into t1 values(4,40,"ta ti tu te to");
-insert into t1 values(5,50,"aa ii uu ee oo");
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 0
-select * from t1;
-c1 c2 c3
-1 10 aa ii uu ee oo
-2 20 ka ki ku ke ko
-3 30 sa si su se so
-4 40 ta ti tu te to
-5 50 aa ii uu ee oo
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 0
-select count(*) from t1;
-count(*)
-5
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 0
-select * from t1 force index(primary) where c1 between 2 and 4;
-c1 c2 c3
-2 20 ka ki ku ke ko
-3 30 sa si su se so
-4 40 ta ti tu te to
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 0
-select count(*) from t1 force index(primary) where c1 between 2 and 4;
-count(*)
-3
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 1
-select c1 from t1 force index(primary) where c1 < 3;
-c1
-1
-2
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 1
-select count(c1) from t1 force index(primary) where c1 < 3;
-count(c1)
-2
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 1
-select 1 from t1 force index(primary) where c1 > 3;
-1
-1
-1
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 1
-select count(1) from t1 force index(primary) where c1 > 3;
-count(1)
-2
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 2
-select * from t1 where match(c3) against("su");
-c1 c2 c3
-3 30 sa si su se so
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 2
-select count(*) from t1 where match(c3) against("su");
-count(*)
-1
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 3
-select * from t1 where match(c3) against("+su" in boolean mode);
-c1 c2 c3
-3 30 sa si su se so
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 3
-select count(*) from t1 where match(c3) against("+su" in boolean mode);
-count(*)
-1
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 4
-select * from t1 force index(idx1) where c2 between 20 and 40;
-c1 c2 c3
-2 20 ka ki ku ke ko
-3 30 sa si su se so
-4 40 ta ti tu te to
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 4
-select count(*) from t1 force index(idx1) where c2 between 20 and 40;
-count(*)
-3
-show status like 'mroonga_count_skip';
-Variable_name Value
-Mroonga_count_skip 5
-drop table t1;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_after_insert_multithread.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_after_insert_multithread.result
index 412ae455898..c09ec340ccb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_after_insert_multithread.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_after_insert_multithread.result
@@ -6,11 +6,7 @@ FULLTEXT INDEX ft(title)
);
INSERT INTO diaries VALUES("Hello mroonga!");
INSERT INTO diaries VALUES("It's funny.");
-CONNECT thread2, localhost, root, ,;
-connection thread2;
INSERT INTO diaries VALUES("Happy birthday!");
-disconnect thread2;
-connection default;
SHOW STATUS LIKE 'mroonga_count_skip';
Variable_name Value
Mroonga_count_skip 0
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_disabled.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_disabled.result
index fd5f856d64c..8d29e0425cf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_disabled.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_disabled.result
@@ -7,14 +7,6 @@ title VARCHAR(255),
content TEXT,
FULLTEXT INDEX(content)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_and.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_and.result
new file mode 100644
index 00000000000..26ca6de7b28
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_and.result
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+id INT,
+age INT,
+INDEX (id, age)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (id, age) VALUES (1, 28);
+INSERT INTO users (id, age) VALUES (1, 28);
+INSERT INTO users (id, age) VALUES (1, 29);
+INSERT INTO users (id, age) VALUES (2, 29);
+INSERT INTO users (id, age) VALUES (2, 29);
+INSERT INTO users (id, age) VALUES (3, 29);
+SELECT COUNT(*) FROM users WHERE id = 2 AND age = 29;
+COUNT(*)
+2
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_between.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_between.result
new file mode 100644
index 00000000000..9af4a4fedcc
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_between.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+age INT,
+INDEX (age)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (age) VALUES (27);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (30);
+INSERT INTO users (age) VALUES (31);
+SELECT COUNT(*) FROM users WHERE age BETWEEN 28 AND 30;
+COUNT(*)
+3
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_equal.result
new file mode 100644
index 00000000000..2bbcfe7549c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_equal.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+age INT,
+INDEX (age)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (29);
+SELECT COUNT(*) FROM users WHERE age = 29;
+COUNT(*)
+3
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_full_text_search_in_boolean_mode.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_full_text_search_in_boolean_mode.result
new file mode 100644
index 00000000000..6ec4d774b28
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_full_text_search_in_boolean_mode.result
@@ -0,0 +1,19 @@
+DROP TABLE IF EXISTS memos;
+FLUSH STATUS;
+CREATE TABLE memos (
+content TEXT,
+FULLTEXT INDEX (content)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO memos (content) VALUES ('Groonga is good.');
+INSERT INTO memos (content) VALUES ('Groonga is very good.');
+INSERT INTO memos (content) VALUES ('Mroonga is good.');
+INSERT INTO memos (content) VALUES ('Mroonga is very good.');
+INSERT INTO memos (content) VALUES ('Mroonga uses Groonga.');
+SELECT COUNT(*) FROM memos
+WHERE MATCH(content) AGAINST('+Groonga' IN BOOLEAN MODE);
+COUNT(*)
+3
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_full_text_search_in_natural_language_mode.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_full_text_search_in_natural_language_mode.result
new file mode 100644
index 00000000000..36a1958955a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_full_text_search_in_natural_language_mode.result
@@ -0,0 +1,19 @@
+DROP TABLE IF EXISTS memos;
+FLUSH STATUS;
+CREATE TABLE memos (
+content TEXT,
+FULLTEXT INDEX (content)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO memos (content) VALUES ('Groonga is good.');
+INSERT INTO memos (content) VALUES ('Groonga is very good.');
+INSERT INTO memos (content) VALUES ('Mroonga is good.');
+INSERT INTO memos (content) VALUES ('Mroonga is very good.');
+INSERT INTO memos (content) VALUES ('Mroonga uses Groonga.');
+SELECT COUNT(*) FROM memos
+WHERE MATCH(content) AGAINST('Groonga');
+COUNT(*)
+3
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_greater.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_greater.result
new file mode 100644
index 00000000000..d5c033083cc
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_greater.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+age INT,
+INDEX (age)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (age) VALUES (27);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (30);
+INSERT INTO users (age) VALUES (31);
+SELECT COUNT(*) FROM users WHERE age > 29;
+COUNT(*)
+2
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_greater_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_greater_equal.result
new file mode 100644
index 00000000000..59b812d1484
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_greater_equal.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+age INT,
+INDEX (age)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (age) VALUES (27);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (30);
+INSERT INTO users (age) VALUES (31);
+SELECT COUNT(*) FROM users WHERE age >= 29;
+COUNT(*)
+3
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_less.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_less.result
new file mode 100644
index 00000000000..b5e4fc1c3de
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_less.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+age INT,
+INDEX (age)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (age) VALUES (27);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (30);
+INSERT INTO users (age) VALUES (31);
+SELECT COUNT(*) FROM users WHERE age < 29;
+COUNT(*)
+2
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_less_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_less_equal.result
new file mode 100644
index 00000000000..f062fe0092b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_less_equal.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+age INT,
+INDEX (age)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (age) VALUES (27);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (30);
+INSERT INTO users (age) VALUES (31);
+SELECT COUNT(*) FROM users WHERE age <= 29;
+COUNT(*)
+3
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_not_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_not_equal.result
new file mode 100644
index 00000000000..a1a123e7d5f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_not_equal.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+age INT,
+INDEX (age)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (29);
+SELECT COUNT(*) FROM users WHERE age <> 29;
+COUNT(*)
+2
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 2
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_multiple_conditions.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_multiple_conditions.result
new file mode 100644
index 00000000000..39a0f0bd785
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_multiple_conditions.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+id INT,
+age INT,
+INDEX (age)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (id, age) VALUES (1, 29);
+INSERT INTO users (id, age) VALUES (2, 29);
+INSERT INTO users (id, age) VALUES (3, 29);
+SELECT COUNT(*) FROM users WHERE id = 3 AND age = 29;
+COUNT(*)
+1
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 0
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_between.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_between.result
new file mode 100644
index 00000000000..68a0575ab97
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_between.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+SELECT COUNT(*) FROM users WHERE id BETWEEN 2 AND 4;
+COUNT(*)
+3
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_equal.result
new file mode 100644
index 00000000000..713a19dd184
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_equal.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+SELECT COUNT(*) FROM users WHERE id = 3;
+COUNT(*)
+1
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_greater.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_greater.result
new file mode 100644
index 00000000000..3ae04a0246f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_greater.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+SELECT COUNT(*) FROM users WHERE id > 3;
+COUNT(*)
+2
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_greater_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_greater_equal.result
new file mode 100644
index 00000000000..0f0643110f0
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_greater_equal.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+SELECT COUNT(*) FROM users WHERE id >= 3;
+COUNT(*)
+3
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_less.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_less.result
new file mode 100644
index 00000000000..05afd7e8d58
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_less.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+SELECT COUNT(*) FROM users WHERE id < 3;
+COUNT(*)
+2
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 0
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_less_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_less_equal.result
new file mode 100644
index 00000000000..200f89d3eb6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_less_equal.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+SELECT COUNT(*) FROM users WHERE id <= 3;
+COUNT(*)
+3
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 0
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_not_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_not_equal.result
new file mode 100644
index 00000000000..64761c9565d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_primary_key_not_equal.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS users;
+FLUSH STATUS;
+CREATE TABLE users (
+id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+SELECT COUNT(*) FROM users WHERE id <> 3;
+COUNT(*)
+4
+SHOW STATUS LIKE 'mroonga_count_skip';
+Variable_name Value
+Mroonga_count_skip 1
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_disabled.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_disabled.result
index e2391c03e06..dcf0f3eec66 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_disabled.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_disabled.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_multiple_match_againsts.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_multiple_match_againsts.result
new file mode 100644
index 00000000000..124a7750f5b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_multiple_match_againsts.result
@@ -0,0 +1,35 @@
+DROP TABLE IF EXISTS memos;
+FLUSH STATUS;
+SET NAMES UTF8;
+CREATE TABLE memos (
+id INT UNSIGNED NOT NULL,
+title VARCHAR(255),
+content TEXT,
+FULLTEXT INDEX(title),
+FULLTEXT INDEX(content)
+) DEFAULT CHARSET UTF8;
+INSERT INTO memos VALUES(5, "title 1", "content a");
+INSERT INTO memos VALUES(12, "title 1", "content a");
+INSERT INTO memos VALUES(10, "title 1", "content a");
+INSERT INTO memos VALUES(4, "title 2", "content b");
+INSERT INTO memos VALUES(6, "title 2", "content b");
+INSERT INTO memos VALUES(1, "title 2", "content b");
+INSERT INTO memos VALUES(11, "title 1-a", "content a-1");
+INSERT INTO memos VALUES(3, "title 2-b", "content a-2");
+INSERT INTO memos VALUES(2, "title 2-c", "content a-3");
+INSERT INTO memos VALUES(8, "title 1-a", "content b-1");
+INSERT INTO memos VALUES(9, "title 2-b", "content b-2");
+INSERT INTO memos VALUES(7, "title 2-c", "content b-3");
+SELECT * FROM memos
+WHERE MATCH(title) AGAINST("+1" IN BOOLEAN MODE) AND
+MATCH(content) AGAINST("+a" IN BOOLEAN MODE)
+ORDER BY id
+LIMIT 1,3;
+id title content
+10 title 1 content a
+11 title 1-a content a-1
+12 title 1 content a
+SHOW STATUS LIKE 'mroonga_fast_order_limit';
+Variable_name Value
+Mroonga_fast_order_limit 0
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_no_limit.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_no_limit.result
index 10d30798c89..5a0ea86cc93 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_no_limit.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_not_optimized_no_limit.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_cp932.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_cp932.result
new file mode 100644
index 00000000000..d58c3cf223a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_cp932.result
@@ -0,0 +1,22 @@
+DROP TABLE IF EXISTS memos;
+FLUSH STATUS;
+SET NAMES CP932;
+CREATE TABLE memos (
+Ž¯•ÊŽq INT UNSIGNED,
+“à—e TEXT,
+FULLTEXT INDEX(“à—e),
+KEY(Ž¯•ÊŽq)
+) DEFAULT CHARSET CP932;
+INSERT INTO memos VALUES(2, "–¾“ú‚ÍŽR“o‚èB");
+INSERT INTO memos VALUES(3, "¡“ú‚̓Tƒ{ƒeƒ“‚ð‚à‚ç‚Á‚½B");
+INSERT INTO memos VALUES(1, "¡“ú‚Í“V‹C‚ª‚æ‚­‚Ä‚æ‚©‚Á‚½B");
+SELECT * FROM memos
+WHERE MATCH(“à—e) AGAINST("¡“ú" IN BOOLEAN MODE)
+ORDER BY Ž¯•ÊŽq
+LIMIT 1;
+Ž¯•ÊŽq “à—e
+1 ¡“ú‚Í“V‹C‚ª‚æ‚­‚Ä‚æ‚©‚Á‚½B
+SHOW STATUS LIKE 'mroonga_fast_order_limit';
+Variable_name Value
+Mroonga_fast_order_limit 1
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_between.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_between.result
index 4ea3856d363..f1cc14b4963 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_between.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_between.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `date` datetime DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `date` (`date`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
INSERT INTO diaries VALUES(3, "2011-11-11 12:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_between_over.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_between_over.result
index 067e8bc7f61..0374f50030e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_between_over.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_between_over.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `date` datetime DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `date` (`date`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
INSERT INTO diaries VALUES(3, "2011-11-11 12:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_equal.result
index 41129e1945f..4bc3f9d5c73 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_equal.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `date` datetime DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `date` (`date`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:34", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:34", "Tomorrow will be fine.");
INSERT INTO diaries VALUES(3, "2011-11-11 12:23:34", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_greater_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_greater_than.result
index 3a99051643d..56629777889 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_greater_than.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_greater_than.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `date` datetime DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `date` (`date`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
INSERT INTO diaries VALUES(3, "2011-11-11 12:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_greater_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_greater_than_or_equal.result
index b6db34d113d..b03fe20f397 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_greater_than_or_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_greater_than_or_equal.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `date` datetime DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `date` (`date`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
INSERT INTO diaries VALUES(3, "2011-11-11 12:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_less_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_less_than.result
index 042e42ff36b..c25f2a56e90 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_less_than.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_less_than.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `date` datetime DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `date` (`date`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
INSERT INTO diaries VALUES(3, "2011-11-11 12:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_less_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_less_than_or_equal.result
index 1c06397c7ea..ef93bf8b879 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_less_than_or_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_datetime_less_than_or_equal.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `date` datetime DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `date` (`date`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
INSERT INTO diaries VALUES(3, "2011-11-11 12:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_enum_name.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_enum_name.result
new file mode 100644
index 00000000000..f20089f0074
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_enum_name.result
@@ -0,0 +1,25 @@
+DROP TABLE IF EXISTS memos;
+FLUSH STATUS;
+SET NAMES utf8;
+CREATE TABLE memos (
+id int PRIMARY KEY,
+tag ENUM('Groonga', 'Mroonga'),
+content TEXT,
+FULLTEXT INDEX(content),
+KEY(tag),
+KEY(id)
+) DEFAULT CHARSET=utf8;
+INSERT INTO memos VALUES(1, 'Groonga', 'Groonga is great!');
+INSERT INTO memos VALUES(2, 'Mroonga', 'Mroonga is great!');
+INSERT INTO memos VALUES(3, 'Mroonga', 'Mroonga is a MySQL storage engine.');
+INSERT INTO memos VALUES(4, 'Mroonga', 'Mroonga is based on Groonga.');
+SELECT * FROM memos
+WHERE MATCH(content) AGAINST("+Groonga" IN BOOLEAN MODE) AND
+tag = 'Mroonga'
+ ORDER BY id LIMIT 1;
+id tag content
+4 Mroonga Mroonga is based on Groonga.
+SHOW STATUS LIKE 'mroonga_fast_order_limit';
+Variable_name Value
+Mroonga_fast_order_limit 1
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_enum_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_enum_value.result
new file mode 100644
index 00000000000..88ec9dd81db
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_enum_value.result
@@ -0,0 +1,25 @@
+DROP TABLE IF EXISTS memos;
+FLUSH STATUS;
+SET NAMES utf8;
+CREATE TABLE memos (
+id int PRIMARY KEY,
+tag ENUM('Groonga', 'Mroonga'),
+content TEXT,
+FULLTEXT INDEX(content),
+KEY(tag),
+KEY(id)
+) DEFAULT CHARSET=utf8;
+INSERT INTO memos VALUES(1, 'Groonga', 'Groonga is great!');
+INSERT INTO memos VALUES(2, 'Mroonga', 'Mroonga is great!');
+INSERT INTO memos VALUES(3, 'Mroonga', 'Mroonga is a MySQL storage engine.');
+INSERT INTO memos VALUES(4, 'Mroonga', 'Mroonga is based on Groonga.');
+SELECT * FROM memos
+WHERE MATCH(content) AGAINST("+Groonga" IN BOOLEAN MODE) AND
+tag = 2
+ORDER BY id LIMIT 1;
+id tag content
+4 Mroonga Mroonga is based on Groonga.
+SHOW STATUS LIKE 'mroonga_fast_order_limit';
+Variable_name Value
+Mroonga_fast_order_limit 1
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_have_primary_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_have_primary_key.result
index be68e8771b2..5c18e22d1af 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_have_primary_key.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_have_primary_key.result
@@ -11,19 +11,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_equal.result
index 7e3c4293c50..634fe89cdd4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_equal.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_greater_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_greater_than.result
index 54bfcbc2b5c..22305c7045a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_greater_than.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_greater_than.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_greater_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_greater_than_or_equal.result
index c4644584b0d..439f453d184 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_greater_than_or_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_greater_than_or_equal.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_less_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_less_than.result
index a4af585cd57..51ec2fde5e6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_less_than.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_less_than.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_less_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_less_than_or_equal.result
index a11e9fc6e40..3c4f3973f84 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_less_than_or_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_int_less_than_or_equal.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_no_primary_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_no_primary_key.result
index 86f783b81f4..03364eb1017 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_no_primary_key.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_no_primary_key.result
@@ -11,18 +11,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_asc.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_asc.result
index acbb6af0be3..a284f4dd280 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_asc.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_asc.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_desc.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_desc.result
index 6b12587a14d..270d263966d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_desc.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_desc.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_id.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_id.result
index 30f4a08d1c9..eb19384eb63 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_id.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_id.result
@@ -13,20 +13,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `_id` int(11) DEFAULT NULL,
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(NULL, 1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(NULL, 2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(NULL, 3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_match_against.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_match_against.result
index abc2dbf06ce..80bd895a6e4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_match_against.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_order_by_match_against.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_select_match_against.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_select_match_against.result
index 52134fde180..b3ed4bf6b4d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_select_match_against.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_select_match_against.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_between.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_between.result
index 5b3ca0194e0..793423f5bc5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_between.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_between.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(10) unsigned NOT NULL,
- `writing_time` time DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `writing_time` (`writing_time`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!");
INSERT INTO memos VALUES(3, "1:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_between_over.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_between_over.result
index 98b92f3c021..f50417d1f29 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_between_over.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_between_over.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(10) unsigned NOT NULL,
- `writing_time` time DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `writing_time` (`writing_time`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!");
INSERT INTO memos VALUES(3, "1:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_equal.result
index 5a37d62785b..26da350050f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_equal.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(10) unsigned NOT NULL,
- `writing_time` time DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `writing_time` (`writing_time`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO memos VALUES(1, "1:23:34", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:34", "Tomorrow will be fine.");
INSERT INTO memos VALUES(3, "1:23:34", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_greater_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_greater_than.result
index 702f125c2b5..342947cc77e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_greater_than.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_greater_than.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(10) unsigned NOT NULL,
- `writing_time` time DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `writing_time` (`writing_time`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!" );
INSERT INTO memos VALUES(3, "1:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_greater_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_greater_than_or_equal.result
index df3ab968803..adc4ec6316e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_greater_than_or_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_greater_than_or_equal.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(10) unsigned NOT NULL,
- `writing_time` time DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `writing_time` (`writing_time`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!" );
INSERT INTO memos VALUES(3, "1:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_less_than.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_less_than.result
index da774b47b10..2881cc7724a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_less_than.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_less_than.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(10) unsigned NOT NULL,
- `writing_time` time DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `writing_time` (`writing_time`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!");
INSERT INTO memos VALUES(3, "1:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_less_than_or_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_less_than_or_equal.result
index 0895545a96d..d1a9fc2787a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_less_than_or_equal.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_time_less_than_or_equal.result
@@ -8,15 +8,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(10) unsigned NOT NULL,
- `writing_time` time DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `writing_time` (`writing_time`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!");
INSERT INTO memos VALUES(3, "1:23:32", "I will do something today!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_varchar_equal_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_varchar_equal_with_index.result
index 51a9c1d4f6e..bff0d993ef8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_varchar_equal_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_varchar_equal_with_index.result
@@ -13,20 +13,6 @@ KEY(title),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `title` (`title`),
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_varchar_equal_without_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_varchar_equal_without_index.result
index 0ebb303a96f..cc3173ecff2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_varchar_equal_without_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_order_limit_optimized_varchar_equal_without_index.result
@@ -12,19 +12,6 @@ FULLTEXT INDEX(content),
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- KEY `month` (`month`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/repair_table_no_index_file.result b/storage/mroonga/mysql-test/mroonga/storage/r/repair_table_no_index_file.result
index 54515edbd0e..24d427ed2ab 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/repair_table_no_index_file.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/repair_table_no_index_file.result
@@ -6,15 +6,6 @@ title TEXT,
body TEXT,
FULLTEXT INDEX body_index (body)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, body) VALUES ("survey", "will start Groonga!");
INSERT INTO diaries (title, body) VALUES ("Groonga (1)", "starting Groonga...");
INSERT INTO diaries (title, body) VALUES ("Groonga (2)", "started Groonga.");
@@ -23,7 +14,7 @@ id title body
2 Groonga (1) starting Groonga...
FLUSH TABLES;
SELECT * FROM diaries WHERE MATCH(body) AGAINST("+starting" IN BOOLEAN MODE);
-ERROR HY000: syscall error 'repair_test.mrn.000010A.c' (No such file or directory)
+ERROR HY000: system call error: No such file or directory: failed to open path: <repair_test.mrn.000010E.c>
REPAIR TABLE diaries;
Table Op Msg_type Msg_text
repair_test.diaries repair status OK
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/replace_text.result b/storage/mroonga/mysql-test/mroonga/storage/r/replace_text.result
index f7187258ddc..c70ce337447 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/replace_text.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/replace_text.result
@@ -5,14 +5,6 @@ id int primary key,
content text,
fulltext index (content)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries values(1, "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/replace_varchar.result b/storage/mroonga/mysql-test/mroonga/storage/r/replace_varchar.result
index 090ea9b84d6..fd2cb655eaa 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/replace_varchar.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/replace_varchar.result
@@ -5,14 +5,6 @@ id int primary key,
content varchar(256),
fulltext index (content)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `content` varchar(256) DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries values(1, "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/select_group_by_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/select_group_by_with_index.result
index 400156cec7b..a111880a904 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/select_group_by_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/select_group_by_with_index.result
@@ -8,8 +8,8 @@ KEY (age)
INSERT INTO users VALUES ("Alice", 20);
INSERT INTO users VALUES ("Bob", 20);
INSERT INTO users VALUES ("Charry", 29);
-SELECT *, COUNT(*) FROM users GROUP BY age;
-name age COUNT(*)
-Alice 20 2
-Charry 29 1
+SELECT age, COUNT(*) FROM users GROUP BY age;
+age COUNT(*)
+20 2
+29 1
DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/select_group_by_without_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/select_group_by_without_index.result
index 04f63d0e779..93d29c2d439 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/select_group_by_without_index.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/select_group_by_without_index.result
@@ -7,11 +7,8 @@ age int
INSERT INTO users VALUES ("Alice", 20);
INSERT INTO users VALUES ("Bob", 20);
INSERT INTO users VALUES ("Charry", 29);
-EXPLAIN SELECT *, COUNT(*) FROM users GROUP BY age;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE users ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
-SELECT *, COUNT(*) FROM users GROUP BY age;
-name age COUNT(*)
-Alice 20 2
-Charry 29 1
+SELECT age, COUNT(*) FROM users GROUP BY age;
+age COUNT(*)
+20 2
+29 1
DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/sub_query_fulltext.result b/storage/mroonga/mysql-test/mroonga/storage/r/sub_query_fulltext.result
index cd702ab7a02..87c9f4ef2b9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/sub_query_fulltext.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/sub_query_fulltext.result
@@ -9,15 +9,6 @@ user_id INT UNSIGNED NOT NULL,
title TEXT,
FULLTEXT INDEX (title)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(10) unsigned NOT NULL,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO users (name) VALUES ("alice");
INSERT INTO users (name) VALUES ("bob");
INSERT INTO users (name) VALUES ("carlos");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/temporary_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/temporary_table.result
index ff24e1b6102..0a18d817312 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/temporary_table.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/temporary_table.result
@@ -3,13 +3,6 @@ CREATE TEMPORARY TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT
) DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TEMPORARY TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title) VALUES ("clear day");
INSERT INTO diaries (title) VALUES ("rainy day");
INSERT INTO diaries (title) VALUES ("cloudy day");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result b/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result
index c59fc05ae2c..3525e2354d2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result
@@ -10,19 +10,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/update_binlog_row.result b/storage/mroonga/mysql-test/mroonga/storage/r/update_binlog_row.result
new file mode 100644
index 00000000000..72a913b402e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/update_binlog_row.result
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS memos;
+SET SESSION binlog_format = 'ROW';
+CREATE TABLE memos (
+title varchar(20) PRIMARY KEY,
+content varchar(140) NOT NULL
+) COLLATE=utf8mb4_general_ci
+DEFAULT CHARSET=utf8mb4;
+INSERT INTO memos (title, content) VALUES ('Mroonga', 'Mroonga is great!');
+SELECT * FROM memos;
+title content
+Mroonga Mroonga is great!
+UPDATE memos SET content = 'Mroonga is very great!' WHERE title = 'Mroonga';
+SELECT * FROM memos;
+title content
+Mroonga Mroonga is very great!
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/update_virtual_column.result b/storage/mroonga/mysql-test/mroonga/storage/r/update_virtual_column.result
index 11e6ee21949..e823e128c43 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/update_virtual_column.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/update_virtual_column.result
@@ -1,28 +1,29 @@
-drop table if exists t1, t2, t3;
-create table t1 (c1 int, _id int);
-insert into t1 values(1,null);
-insert into t1 values(2,null);
-insert into t1 values(3,null);
-select * from t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 int, _id int);
+INSERT INTO t1 VALUES(1,null);
+INSERT INTO t1 VALUES(2,null);
+INSERT INTO t1 VALUES(3,null);
+SELECT * FROM t1;
c1 _id
1 1
2 2
3 3
-set sql_mode="";
-update t1 set _id = 10 where c1 = 1;
+SET sql_mode="";
+UPDATE t1 SET _id = 10 WHERE c1 = 1;
Warnings:
Warning 1265 Data truncated for column '_id' at row 1
-select * from t1;
+SELECT * FROM t1;
c1 _id
1 1
2 2
3 3
-set sql_mode="strict_all_tables";
-update t1 set _id = 11 where c1 = 1;
+SET sql_mode="STRICT_ALL_TABLES";
+UPDATE t1 SET _id = 11 WHERE c1 = 1;
ERROR 01000: Data truncated for column '_id' at row 1
-select * from t1;
+SELECT * FROM t1;
c1 _id
1 1
2 2
3 3
-drop table t1;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_default_tokenizer_new_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_default_tokenizer_new_value.result
new file mode 100644
index 00000000000..1f457eb5e96
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_default_tokenizer_new_value.result
@@ -0,0 +1,6 @@
+SET @mroonga_default_tokenizer_backup = @@mroonga_default_tokenizer;
+SET GLOBAL mroonga_default_tokenizer = "TokenBigramSplitAlpha";
+SHOW GLOBAL VARIABLES LIKE 'mroonga_default_tokenizer';
+Variable_name Value
+mroonga_default_tokenizer TokenBigramSplitAlpha
+SET GLOBAL mroonga_default_tokenizer = @mroonga_default_tokenizer_backup;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_default_tokenizer_same_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_default_tokenizer_same_value.result
new file mode 100644
index 00000000000..9ad80e9a85a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_default_tokenizer_same_value.result
@@ -0,0 +1,4 @@
+SET GLOBAL mroonga_default_tokenizer = "TokenBigram";
+SHOW GLOBAL VARIABLES LIKE 'mroonga_default_tokenizer';
+Variable_name Value
+mroonga_default_tokenizer TokenBigram
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_delete.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_delete.result
index deac880d265..4238cb6320e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_delete.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_delete.result
@@ -4,14 +4,6 @@ id int primary key auto_increment,
body text,
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries (body) values ("will start groonga!");
select * from diaries;
id body
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_insert.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_insert.result
index 13db5ec65f7..429398f6b84 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_insert.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_insert.result
@@ -4,14 +4,6 @@ id int primary key auto_increment,
body text,
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries (body) values ("will start groonga!");
select * from diaries;
id body
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_update.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_update.result
index 7ba0c120a2c..9cd6f5c9b1d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_update.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_dry_write_update.result
@@ -4,14 +4,6 @@ id int primary key auto_increment,
body text,
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
insert into diaries (body) values ("will start groonga!");
set mroonga_dry_write=true;
update diaries set body = "starting groonga..." where id = 1;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_enable_operations_recording_insert.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_enable_operations_recording_insert.result
new file mode 100644
index 00000000000..5a19ab6fb44
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_enable_operations_recording_insert.result
@@ -0,0 +1,32 @@
+DROP TABLE IF EXISTS diaries;
+CREATE TABLE diaries (
+title TEXT
+) DEFAULT CHARSET=utf8;
+SELECT mroonga_command('truncate mroonga_operations');
+mroonga_command('truncate mroonga_operations')
+true
+INSERT INTO diaries VALUES("Unlogged: Research for Mroonga");
+SELECT mroonga_command('load --table mroonga_operations --values "[{}]"');
+mroonga_command('load --table mroonga_operations --values "[{}]"')
+1
+SELECT mroonga_command('select mroonga_operations --output_columns _id');
+mroonga_command('select mroonga_operations --output_columns _id')
+[[[1],[["_id","UInt32"]],[2]]]
+SET GLOBAL mroonga_enable_operations_recording = false;
+FLUSH TABLES;
+SELECT mroonga_command('truncate mroonga_operations');
+mroonga_command('truncate mroonga_operations')
+true
+INSERT INTO diaries VALUES("Logged: Research for Mroonga");
+SELECT mroonga_command('load --table mroonga_operations --values "[{}]"');
+mroonga_command('load --table mroonga_operations --values "[{}]"')
+1
+SELECT mroonga_command('select mroonga_operations --output_columns _id');
+mroonga_command('select mroonga_operations --output_columns _id')
+[[[1],[["_id","UInt32"]],[1]]]
+DROP TABLE diaries;
+SELECT mroonga_command('truncate mroonga_operations');
+mroonga_command('truncate mroonga_operations')
+true
+SET GLOBAL mroonga_enable_operations_recording = default;
+FLUSH TABLES;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_match_escalation_threshold_global.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_match_escalation_threshold_global.result
index 8abd41cece3..19abff382bf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/variable_match_escalation_threshold_global.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_match_escalation_threshold_global.result
@@ -4,30 +4,21 @@ CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
tags TEXT,
-FULLTEXT INDEX tags_index (tags) COMMENT 'parser "TokenDelimit"'
+FULLTEXT INDEX tags_index (tags) COMMENT 'tokenizer "TokenDelimit"'
) DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `tags` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `tags_index` (`tags`) COMMENT 'parser "TokenDelimit"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
-INSERT INTO diaries (title, tags) VALUES ("Hello groonga!", "groonga install");
-INSERT INTO diaries (title, tags) VALUES ("Hello mroonga!", "mroonga install");
-SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("install" IN BOOLEAN MODE);
+INSERT INTO diaries (title, tags) VALUES ("Hello Groonga!", "groonga install");
+INSERT INTO diaries (title, tags) VALUES ("Hello Mroonga!", "mroonga install");
+SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("+install" IN BOOLEAN MODE);
id title tags
-1 Hello groonga! groonga install
-2 Hello mroonga! mroonga install
-SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
+1 Hello Groonga! groonga install
+2 Hello Mroonga! mroonga install
+SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("+gr" IN BOOLEAN MODE);
id title tags
SET GLOBAL mroonga_match_escalation_threshold = 0;
-SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
+SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("+gr" IN BOOLEAN MODE);
id title tags
SET mroonga_match_escalation_threshold = 0;
-SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
+SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("+gr" IN BOOLEAN MODE);
id title tags
-1 Hello groonga! groonga install
+1 Hello Groonga! groonga install
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_match_escalation_threshold_session.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_match_escalation_threshold_session.result
index 37c2eeeb379..30e9262b5fc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/variable_match_escalation_threshold_session.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_match_escalation_threshold_session.result
@@ -3,17 +3,8 @@ CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
tags TEXT,
-FULLTEXT INDEX tags_index (tags) COMMENT 'parser "TokenDelimit"'
+FULLTEXT INDEX tags_index (tags) COMMENT 'tokenizer "TokenDelimit"'
) DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `tags` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `tags_index` (`tags`) COMMENT 'parser "TokenDelimit"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
INSERT INTO diaries (title, tags) VALUES ("Hello groonga!", "groonga install");
INSERT INTO diaries (title, tags) VALUES ("Hello mroonga!", "mroonga install");
SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("install" IN BOOLEAN MODE);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_global.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_global.result
index 9968abaf18c..0181fe02d84 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_global.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_global.result
@@ -13,12 +13,8 @@ INSERT INTO ids VALUES (8);
INSERT INTO ids VALUES (9);
INSERT INTO ids VALUES (10);
SET GLOBAL mroonga_max_n_records_for_estimate = 1;
-CONNECT new_connection, localhost, root, ,;
-connection new_connection;
EXPLAIN SELECT * FROM ids WHERE id > 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE ids range PRIMARY PRIMARY 4 NULL 1 Using where; Using index
-connection default;
-disconnect new_connection;
SET GLOBAL mroonga_max_n_records_for_estimate = DEFAULT;
DROP TABLE ids;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_global.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_global.result
index 0181fe02d84..ff574f7bcce 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_global.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_global.result
@@ -14,7 +14,9 @@ INSERT INTO ids VALUES (9);
INSERT INTO ids VALUES (10);
SET GLOBAL mroonga_max_n_records_for_estimate = 1;
EXPLAIN SELECT * FROM ids WHERE id > 5;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE ids range PRIMARY PRIMARY 4 NULL 1 Using where; Using index
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE ids NULL range PRIMARY PRIMARY 4 NULL 1 100.00 Using where; Using index
+Warnings:
+Note 1003 /* select#1 */ select `test`.`ids`.`id` AS `id` from `test`.`ids` where (`test`.`ids`.`id` > 5)
SET GLOBAL mroonga_max_n_records_for_estimate = DEFAULT;
DROP TABLE ids;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_not_found_in_limit.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_not_found_in_limit.result
new file mode 100644
index 00000000000..5ecf89694e4
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_not_found_in_limit.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS ids;
+CREATE TABLE ids (
+id INT,
+INDEX (id)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+DELETE FROM ids WHERE id < 2;
+SET mroonga_max_n_records_for_estimate = 1;
+EXPLAIN SELECT * FROM ids WHERE id > 0;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE ids NULL range id id 5 NULL 1 100.00 Using where; Using index
+Warnings:
+Note 1003 /* select#1 */ select `test`.`ids`.`id` AS `id` from `test`.`ids` where (`test`.`ids`.`id` > 0)
+SET mroonga_max_n_records_for_estimate = DEFAULT;
+DROP TABLE ids;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_session.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_session.result
new file mode 100644
index 00000000000..b28eac5a274
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_mysql_5_7_or_later_session.result
@@ -0,0 +1,22 @@
+DROP TABLE IF EXISTS ids;
+CREATE TABLE ids (
+id INT PRIMARY KEY AUTO_INCREMENT
+) DEFAULT CHARSET=UTF8;
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+INSERT INTO ids VALUES (4);
+INSERT INTO ids VALUES (5);
+INSERT INTO ids VALUES (6);
+INSERT INTO ids VALUES (7);
+INSERT INTO ids VALUES (8);
+INSERT INTO ids VALUES (9);
+INSERT INTO ids VALUES (10);
+SET mroonga_max_n_records_for_estimate = 1;
+EXPLAIN SELECT * FROM ids WHERE id > 5;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE ids NULL range PRIMARY PRIMARY 4 NULL 1 100.00 Using where; Using index
+Warnings:
+Note 1003 /* select#1 */ select `test`.`ids`.`id` AS `id` from `test`.`ids` where (`test`.`ids`.`id` > 5)
+SET mroonga_max_n_records_for_estimate = DEFAULT;
+DROP TABLE ids;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_not_found_in_limit.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_not_found_in_limit.result
new file mode 100644
index 00000000000..e2d8a8de493
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_max_n_records_for_estimate_not_found_in_limit.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS ids;
+CREATE TABLE ids (
+id INT,
+INDEX (id)
+) DEFAULT CHARSET=UTF8;
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+DELETE FROM ids WHERE id < 2;
+SET mroonga_max_n_records_for_estimate = 1;
+EXPLAIN SELECT * FROM ids WHERE id > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE ids range id id 5 NULL 1 Using where; Using index
+SET mroonga_max_n_records_for_estimate = DEFAULT;
+DROP TABLE ids;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_disabled_empty_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_disabled_empty_value.result
new file mode 100644
index 00000000000..3d7f36d1846
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_disabled_empty_value.result
@@ -0,0 +1,9 @@
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+SET GLOBAL mroonga_query_log_file = "";
+SHOW GLOBAL VARIABLES LIKE "mroonga_query_log_file";
+Variable_name Value
+mroonga_query_log_file
+log file is changed: <groonga.log> -> <groonga-query-log.log>
+query log file is still disabled
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_disabled_null_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_disabled_null_value.result
new file mode 100644
index 00000000000..aed9d91a9d5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_disabled_null_value.result
@@ -0,0 +1,9 @@
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+SET GLOBAL mroonga_query_log_file = NULL;
+SHOW GLOBAL VARIABLES LIKE "mroonga_query_log_file";
+Variable_name Value
+mroonga_query_log_file
+log file is changed: <groonga.log> -> <groonga-query-log.log>
+query log file is still disabled
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_enabled_empty_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_enabled_empty_value.result
new file mode 100644
index 00000000000..22ac271e552
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_enabled_empty_value.result
@@ -0,0 +1,10 @@
+SET GLOBAL mroonga_query_log_file = "groonga-query.log";
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+SET GLOBAL mroonga_query_log_file = "";
+SHOW GLOBAL VARIABLES LIKE "mroonga_query_log_file";
+Variable_name Value
+mroonga_query_log_file
+log file is changed: <groonga.log> -> <groonga-query-log.log>
+query log file is disabled: <groonga-query.log>
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_enabled_null_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_enabled_null_value.result
new file mode 100644
index 00000000000..3921fb16259
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_enabled_null_value.result
@@ -0,0 +1,10 @@
+SET GLOBAL mroonga_query_log_file = "groonga-query.log";
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+SET GLOBAL mroonga_query_log_file = NULL;
+SHOW GLOBAL VARIABLES LIKE "mroonga_query_log_file";
+Variable_name Value
+mroonga_query_log_file
+log file is changed: <groonga.log> -> <groonga-query-log.log>
+query log file is disabled: <groonga-query.log>
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_new_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_new_value.result
new file mode 100644
index 00000000000..7b1be1365b7
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_new_value.result
@@ -0,0 +1,9 @@
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+SET GLOBAL mroonga_query_log_file = "groonga-query.log";
+SHOW GLOBAL VARIABLES LIKE "mroonga_query_log_file";
+Variable_name Value
+mroonga_query_log_file groonga-query.log
+log file is changed: <groonga.log> -> <groonga-query-log.log>
+query log is enabled: <groonga-query.log>
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_same_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_same_value.result
new file mode 100644
index 00000000000..adf3d1bfbe8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_query_log_file_same_value.result
@@ -0,0 +1,10 @@
+SET GLOBAL mroonga_query_log_file = "groonga-query.log";
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+SET GLOBAL mroonga_query_log_file = "groonga-query.log";
+SHOW GLOBAL VARIABLES LIKE "mroonga_query_log_file";
+Variable_name Value
+mroonga_query_log_file groonga-query.log
+log file is changed: <groonga.log> -> <groonga-query-log.log>
+query log file isn't changed because the requested path isn't different: <groonga-query.log>
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_after.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_after.test
index 38d4f034daa..4e486b83cc0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_after.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_after.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,11 +23,11 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- body TEXT
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
-ALTER TABLE diaries ADD title TEXT AFTER id;
+ALTER TABLE diaries ADD title VARCHAR(40) AFTER id;
SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) values ("groonga (1)", "starting groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_first.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_first.test
index 0e82b3dd4b0..5912ed3fcf0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_first.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_first.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,11 +23,11 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- body TEXT
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
-ALTER TABLE diaries ADD title TEXT FIRST;
+ALTER TABLE diaries ADD title VARCHAR(40) FIRST;
SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) values ("groonga (1)", "starting groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_comment.test
index 1071faf0b81..18fa2f3ef1e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test
index 70fb61cc044..f84c931c010 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
--source include/not_embedded.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test
index 8a64fe00af0..d49e84cd5fa 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test
index f34cbcdcbf7..cc208a20872 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test
@@ -13,10 +13,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multibyte_cp932.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multibyte_cp932.test
new file mode 100644
index 00000000000..18836127238
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multibyte_cp932.test
@@ -0,0 +1,53 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES cp932;
+
+CREATE TABLE users (
+ id int PRIMARY KEY
+) DEFAULT CHARSET=cp932;
+ALTER TABLE users
+ ADD COLUMN –¼‘O text,
+ ADD FULLTEXT INDEX (–¼‘O);
+
+INSERT INTO users VALUES (1, "‚â‚Ü‚¾");
+INSERT INTO users VALUES (2, "‚½‚È‚©");
+INSERT INTO users VALUES (3, "‚·‚¸‚«");
+
+SELECT * FROM users;
+
+SELECT * FROM users
+ WHERE MATCH (–¼‘O) AGAINST ('+‚½‚È‚©' IN BOOLEAN MODE);
+
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+
+DROP TABLE users;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multibyte_utf8.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multibyte_utf8.test
new file mode 100644
index 00000000000..88ef12498a7
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multibyte_utf8.test
@@ -0,0 +1,53 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE users (
+ id int PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+ALTER TABLE users
+ ADD COLUMN åå‰ text,
+ ADD FULLTEXT INDEX (åå‰);
+
+INSERT INTO users VALUES (1, "ã‚„ã¾ã ");
+INSERT INTO users VALUES (2, "ãŸãªã‹");
+INSERT INTO users VALUES (3, "ã™ãšã");
+
+SELECT * FROM users;
+
+SELECT * FROM users
+ WHERE MATCH (åå‰) AGAINST ('+ãŸãªã‹' IN BOOLEAN MODE);
+
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+
+DROP TABLE users;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multiple.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multiple.test
index 568deea9e29..1f4fa4663b1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multiple.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_multiple.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,7 +23,7 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT
+ title VARCHAR(40)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
@@ -31,7 +31,7 @@ INSERT INTO diaries (title) VALUES ("survey");
SELECT * FROM diaries;
ALTER TABLE diaries
- ADD COLUMN body TEXT FIRST,
+ ADD COLUMN body VARCHAR(140) FIRST,
ADD COLUMN published BOOLEAN AFTER id,
ADD COLUMN created_at DATETIME;
UPDATE diaries SET body = "will start groonga!";
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_plain.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_plain.test
index 8c4d76a5868..fac1f045db1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_plain.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_plain.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,14 +23,14 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT
+ title VARCHAR(40)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
INSERT INTO diaries (title) VALUES ("survey");
SELECT * FROM diaries;
-ALTER TABLE diaries ADD COLUMN body TEXT;
+ALTER TABLE diaries ADD COLUMN body VARCHAR(140);
UPDATE diaries SET body = "will start groonga!";
SELECT * FROM diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_type_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_type_comment.test
index 037e81c7906..c198358146b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_type_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_type_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test
index 83b8aef1c5a..1440c0b78aa 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_groonga_plugin_register.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_duplicated.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_duplicated.test
index 4476decec78..53d4b21ff53 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_duplicated.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_duplicated.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_multiple_column_duplicated.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_multiple_column_duplicated.test
index 424ae89b4a6..7bb65327f79 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_multiple_column_duplicated.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_multiple_column_duplicated.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_key_multiple_column_with_data.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_key_multiple_column_with_data.test
index 94db5d40b60..7e584131b3d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_key_multiple_column_with_data.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_key_multiple_column_with_data.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_primary_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_primary_key.test
index 5bc12edadc4..7ae72d672f6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_primary_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_primary_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_comment_not_for_mroonga.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_comment_not_for_mroonga.test
index 98d26966bd0..119099c4350 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_comment_not_for_mroonga.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_comment_not_for_mroonga.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_have_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_have_index.test
index 575d65e44a2..c01f7a95754 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_have_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_have_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_after.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_after.test
index 295bb91e0a9..e680e6e2008 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_after.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_after.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,12 +23,12 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
- body TEXT
+ title VARCHAR(40),
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
-ALTER TABLE diaries CHANGE body description TEXT AFTER id;
+ALTER TABLE diaries CHANGE body description VARCHAR(140) AFTER id;
SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, description) values ("groonga (1)", "starting groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_first.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_first.test
index 01682688a74..20624ad9537 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_first.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_first.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,12 +23,12 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
- body TEXT
+ title VARCHAR(40),
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
-ALTER TABLE diaries CHANGE body description TEXT FIRST;
+ALTER TABLE diaries CHANGE body description VARCHAR(140) FIRST;
SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, description) values ("groonga (1)", "starting groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_multiple.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_multiple.test
index b30486d080a..20f7853fb7c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_multiple.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_multiple.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,15 +23,15 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
- body TEXT
+ title VARCHAR(40),
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
ALTER TABLE diaries
- CHANGE body description TEXT FIRST,
- CHANGE title subject TEXT AFTER internal_id,
- CHANGE id internal_id INT;
+ CHANGE body description VARCHAR(140) FIRST,
+ CHANGE title subject VARCHAR(40) AFTER internal_id,
+ CHANGE id internal_id INT AUTO_INCREMENT;
SHOW CREATE TABLE diaries;
INSERT IGNORE INTO diaries (subject, description)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_no_order.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_no_order.test
index 88a69111f65..2394be86333 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_no_order.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_column_rename_no_order.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,12 +23,12 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
- body TEXT
+ title VARCHAR(40),
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
-ALTER TABLE diaries CHANGE body description TEXT;
+ALTER TABLE diaries CHANGE body description VARCHAR(140);
SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, description) values ("groonga (1)", "starting groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_engine_decimal.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_engine_decimal.test
index 71e0fda3825..e8e0bd416f9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_engine_decimal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_engine_decimal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/not_embedded.inc
@@ -24,19 +24,18 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
temperature DECIMAL(6, 3)
) ENGINE InnoDB DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
-INSERT INTO diaries (title, temperature) VALUES ("clear day", 21.281);
+INSERT INTO diaries (temperature) VALUES (21.281);
SELECT * FROM diaries;
ALTER TABLE diaries ENGINE = mroonga;
SELECT * FROM diaries;
-INSERT INTO diaries (title, temperature) VALUES ("rainy day", 14.213);
-INSERT INTO diaries (title, temperature) VALUES ("cloudy day", 17.821);
+INSERT INTO diaries (temperature) VALUES (14.213);
+INSERT INTO diaries (temperature) VALUES (17.821);
SELECT * FROM diaries;
SHOW CREATE TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_engine.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_engine_fulltext_index.test
index a477d091946..f8c4dfa3400 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_engine.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_engine_fulltext_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,9 @@ CREATE TABLE diaries (
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) ENGINE MyISAM DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
+SELECT table_name, engine
+ FROM information_schema.tables
+ WHERE table_name = 'diaries';
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
@@ -37,7 +39,9 @@ SELECT * FROM diaries
MATCH(body) AGAINST("groonga" IN BOOLEAN MODE);
ALTER TABLE diaries ENGINE = mroonga;
-SHOW CREATE TABLE diaries;
+SELECT table_name, engine
+ FROM information_schema.tables
+ WHERE table_name = 'diaries';
SELECT * FROM diaries
WHERE MATCH(title) AGAINST("survey" IN BOOLEAN MODE) AND
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test
index 92380fdb8ec..c1bf17ba439 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_groonga_plugin_register.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_create_fulltext.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_create_fulltext.test
index 1f6980cc04b..d1f8308268a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_create_fulltext.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_create_fulltext.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_table.test
index 5cba17d2072..17b86b47389 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_table.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_table.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_ujis.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_ujis.test
index d7f7f446459..028fb33f1e3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_ujis.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_ujis.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_utf8.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_utf8.test
index 626a1bc80a8..00015dcfaca 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_utf8.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_utf8.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_multiple_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_multiple_column.test
index ea424df2e57..5760887e782 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_multiple_column.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_multiple_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_normal.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_normal.test
index 186e1f5095c..69dbe23cc24 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_normal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_normal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_primary.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_primary.test
index 4348efeb066..dce2ea51397 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_primary.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_primary.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_truncate.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_truncate.test
index 49d9f0b8da2..00f6d30a572 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_truncate.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_truncate.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_updating.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_updating.test
index 58e53cb06f2..020579106e1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_updating.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_updating.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_column_multiple.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_column_multiple.test
index fc3acad9000..32da1b3a547 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_column_multiple.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_column_multiple.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,8 +23,8 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
- body TEXT
+ title VARCHAR(40),
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_column_one.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_column_one.test
index 6b790e5d621..ec5735f0672 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_column_one.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_column_one.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,8 +23,8 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
- body TEXT
+ title VARCHAR(40),
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_key_multiple_column_with_data.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_key_multiple_column_with_data.test
index 956f397b965..eb80d3036d3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_key_multiple_column_with_data.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_key_multiple_column_with_data.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_primary_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_primary_key.test
index 95f683f1df5..da06f680d68 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_primary_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_drop_primary_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext.test
index 62bbe4a4dc2..08d84f7b552 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_table.test
index d87078e7e9c..3309f60a3d9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_table.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_table.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_ujis.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_ujis.test
index cb6ade7a418..2f3b61efcf3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_ujis.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_ujis.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_utf8.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_utf8.test
index 62bbe4a4dc2..08d84f7b552 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_utf8.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_utf8.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_multiple_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_multiple_column.test
index 13afdcfe0e6..1d073dc641f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_multiple_column.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_multiple_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_normal.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_normal.test
index bf2cc8bd6e2..870b1bb6098 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_normal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_normal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_primary.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_primary.test
index 3d9523ab537..34ee3fcd275 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_primary.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_primary.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_no_primary_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_no_primary_key.test
index 193680296dc..b349411849f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_no_primary_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_no_primary_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_normal.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_normal.test
index bf7e7501741..6316eac4fe1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_normal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_normal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -31,9 +31,8 @@ INSERT INTO memos (content) values ("Started Groonga.");
INSERT INTO memos (content) values ("Starting Mroonga...");
ALTER TABLE memos ADD FULLTEXT INDEX content_index (content);
-SHOW CREATE TABLE memos;
-SELECT * FROM memos WHERE MATCH(content) AGAINST("groonga");
+SELECT * FROM memos WHERE MATCH(content) AGAINST("+groonga" IN BOOLEAN MODE);
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_table.test
index c719318d847..f4facdcb72f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_table.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_add_table.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_drop_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_drop_table.test
index 11799a51a65..165b71a86c9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_drop_table.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_fulltext_drop_table.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_after.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_after.test
index 8bdfd10024e..ce1e52efa31 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_after.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_after.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,15 +23,15 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
- body TEXT
+ title VARCHAR(40),
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) values ("groonga (1)", "starting groonga.");
SELECT * FROM diaries;
-ALTER TABLE diaries MODIFY body TEXT AFTER id;
+ALTER TABLE diaries MODIFY body VARCHAR(140) AFTER id;
SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) values ("groonga (2)", "started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_first.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_first.test
index a4dd52d9fac..22c6b59e022 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_first.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_first.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,15 +23,15 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
- body TEXT
+ title VARCHAR(40),
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) values ("groonga (1)", "starting groonga.");
SELECT * FROM diaries;
-ALTER TABLE diaries MODIFY body TEXT FIRST;
+ALTER TABLE diaries MODIFY body VARCHAR(140) FIRST;
SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) values ("groonga (2)", "started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_no_order.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_no_order.test
index 45f4748e98d..eed22d06690 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_no_order.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_modify_column_no_order.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,8 +23,8 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
- body TEXT
+ title VARCHAR(40),
+ body VARCHAR(140)
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_recreate_anonymous_index_at_once.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_recreate_anonymous_index_at_once.test
index c44937b3f84..77d0bc741e2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_recreate_anonymous_index_at_once.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_recreate_anonymous_index_at_once.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ CREATE TABLE diaries (
body TEXT,
FULLTEXT INDEX (body)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("survey", "will start mroonga!");
@@ -44,8 +43,6 @@ SELECT * FROM diaries;
SELECT * FROM diaries
WHERE MATCH (body) AGAINST ("+groonga" IN BOOLEAN MODE);
-SHOW CREATE TABLE diaries;
-
DROP TABLE diaries;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_rename_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_rename_table.test
index 91898b5bb44..6c15161ed22 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_rename_table.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_rename_table.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,9 @@ CREATE TABLE diaries (
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
+SELECT table_name, engine
+ FROM information_schema.tables
+ WHERE table_name = 'diaries';
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
SELECT * FROM diaries;
@@ -42,7 +44,9 @@ SELECT * FROM memos
WHERE MATCH(title) AGAINST("groonga") AND
MATCH(body) AGAINST("starting");
-SHOW CREATE TABLE memos;
+SELECT table_name, engine
+ FROM information_schema.tables
+ WHERE table_name = 'memos';
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_spatial.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_spatial.test
index e696d12f128..09e0ea8a118 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_spatial.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_spatial.test
@@ -12,11 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source include/have_geometry.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -25,7 +25,7 @@ DROP TABLE IF EXISTS shops;
CREATE TABLE shops (
id INT PRIMARY KEY AUTO_INCREMENT,
- name TEXT,
+ name VARCHAR(40),
location GEOMETRY NOT NULL
);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_TODO_SPLIT_ME.test
index db018023af0..f452e402d81 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_TODO_SPLIT_ME.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_table_param.test b/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_table_param.test
index 169260cc808..2d0840ce990 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_table_param.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_table_param.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_text.test b/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_text.test
index ee4db71722c..2d854ec35b4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_text.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/auto_increment_text.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/binlog_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/storage/t/binlog_TODO_SPLIT_ME.test
index c67aff06674..eff9259a7ba 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/binlog_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/binlog_TODO_SPLIT_ME.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_log_bin.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/check_table_broken.test b/storage/mroonga/mysql-test/mroonga/storage/t/check_table_broken.test
new file mode 100644
index 00000000000..77271b4f169
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/check_table_broken.test
@@ -0,0 +1,45 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_mroonga_helper.inc
+
+SET NAMES UTF8;
+
+CREATE DATABASE check_test;
+USE check_test;
+
+CREATE TABLE diaries (
+ title TEXT,
+ FULLTEXT INDEX (title)
+);
+
+INSERT INTO diaries VALUES ('Hello');
+
+--remove_file $MYSQLD_DATADIR/check_test.mrn.000010C
+
+FLUSH TABLES;
+
+CHECK TABLE diaries;
+
+REPAIR TABLE diaries;
+DROP TABLE diaries;
+
+DROP DATABASE check_test;
+USE test;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/check_table_not_broken.test b/storage/mroonga/mysql-test/mroonga/storage/t/check_table_not_broken.test
new file mode 100644
index 00000000000..1460732b29a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/check_table_not_broken.test
@@ -0,0 +1,38 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+SET NAMES UTF8;
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+CREATE TABLE diaries (
+ title TEXT
+);
+
+INSERT INTO diaries VALUES ('Hello');
+
+CHECK TABLE diaries;
+
+SELECT * FROM diaries;
+
+DROP TABLE diaries;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_general_ci_french.test b/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_general_ci_french.test
index d0df707162b..101c16e9675 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_general_ci_french.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_general_ci_french.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_520_ci_french.test b/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_520_ci_french.test
index f9e9a817a08..2c28edb3327 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_520_ci_french.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_520_ci_french.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_520_ci_japanese.test b/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_520_ci_japanese.test
index 4beec67b468..1d9998eeed3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_520_ci_japanese.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_520_ci_japanese.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_ci_french.test b/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_ci_french.test
index 045c9ef2a4e..f69e5594ebd 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_ci_french.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_ci_french.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_ci_japanese.test b/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_ci_japanese.test
index 199e2904d94..5d48a1a6201 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_ci_japanese.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/collation_utf8_unicode_ci_japanese.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_comment_index_not_for_mroonga.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_comment_index_not_for_mroonga.test
index 4c63dedfc60..42c5e1d2284 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_comment_index_not_for_mroonga.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_comment_index_not_for_mroonga.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_comment_normal_not_for_mroonga.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_comment_normal_not_for_mroonga.test
index 0fcc806883d..6761869d4ff 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_comment_normal_not_for_mroonga.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_comment_normal_not_for_mroonga.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_date_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_date_with_index.test
index cc713a80e5a..8645a2d7e5f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_date_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_date_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -22,7 +22,7 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
+ title VARCHAR(40),
created_at DATE,
KEY (created_at)
) DEFAULT CHARSET UTF8;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_date_without_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_date_without_index.test
index d5587876c3c..21dcf156e43 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_date_without_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_date_without_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -22,7 +22,7 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
- title TEXT,
+ title VARCHAR(40),
created_at DATE
) DEFAULT CHARSET UTF8;
SHOW CREATE TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_date_zero_date.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_date_zero_date.test
index 762b78ec0fc..6bd99b86915 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_date_zero_date.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_date_zero_date.test
@@ -1,4 +1,5 @@
# Copyright(C) 2013 Kentoku SHIBA
+# Copyright(C) 2016-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,8 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source ../../include/mroonga/skip_strict_sql_mode.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_2038.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_2038.test
index 8cbf9309538..0c215080313 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_2038.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_2038.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_32bit.inc
+--source ../../include/mroonga/skip_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
VALUES ('2038-01-18 03:14:07', '2038-01-18 03:14:07');
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_before_unix_epoch.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_before_unix_epoch.test
index df656eca797..b93af8ffa25 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_before_unix_epoch.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_before_unix_epoch.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_32bit.inc
+--source ../../include/mroonga/skip_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT IGNORE INTO diaries (title, created_at)
VALUES ('1000-01-01 00:00:00', '1000-01-01 00:00:00');
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_max.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_max.test
index 12c2a312afe..c1cf1a341de 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_max.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_max.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_32bit.inc
+--source ../../include/mroonga/skip_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT IGNORE INTO diaries (title, created_at)
VALUES ('9999-12-31 23:59:59', '9999-12-31 23:59:59');
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_out_of_range.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_out_of_range.test
index 337e5baa955..43439de0e89 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_out_of_range.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_32bit_out_of_range.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_32bit.inc
+--source ../../include/mroonga/skip_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT IGNORE INTO diaries (title, created_at)
VALUES ('2012', '2012');
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_2038.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_2038.test
index 3abf611a839..af04133ef2c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_2038.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_2038.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
VALUES ('2038-01-19 03:14:07', '2038-01-19 03:14:07');
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_before_unix_epoch.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_before_unix_epoch.test
index 586367147cc..a3e355cc1ea 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_before_unix_epoch.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_before_unix_epoch.test
@@ -13,12 +13,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/skip_freebsd.inc
---source ../../include/mroonga/skip_osx.inc
---source ../../include/mroonga/skip_solaris10.inc
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -30,10 +28,9 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
- VALUES ('1000-01-01 00:00:00', '1000-01-01 00:00:00');
+ VALUES ('1000-01-02 00:00:00', '1000-01-02 00:00:00');
SELECT * FROM diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_max.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_max.test
index 6599a554efd..3f4bb7b1e23 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_max.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_max.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
VALUES ('9999-12-31 23:59:59', '9999-12-31 23:59:59');
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_56_or_later_out_of_range.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_strict_sql_mode_out_of_range.test
index 94c9cab1373..47266e017d7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_56_or_later_out_of_range.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_strict_sql_mode_out_of_range.test
@@ -13,12 +13,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/skip_freebsd.inc
---source ../../include/mroonga/skip_osx.inc
---source ../../include/mroonga/have_64bit.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
+--source ../../include/mroonga/have_strict_sql_mode.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -30,12 +29,10 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-SET STATEMENT sql_mode = '' FOR
-INSERT INTO diaries (title, created_at) VALUES ('2012', '2012');
--error ER_TRUNCATED_WRONG_VALUE
-INSERT INTO diaries (title, created_at) VALUES ('2012', '2012');
+INSERT INTO diaries (title, created_at)
+ VALUES ('2012', '2012');
SELECT * FROM diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_55_out_of_range.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_5_5_out_of_range.test
index bdc21cccf52..23ddc373ab2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_55_out_of_range.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_5_5_out_of_range.test
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
---source ../../include/mroonga/have_version_55.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
+--source ../../include/mroonga/have_version_5_5.inc
--source ../../include/mroonga/have_mysql.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
VALUES ('2012', '2012');
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_5_6_or_later_out_of_range.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_5_6_or_later_out_of_range.test
new file mode 100644
index 00000000000..55457c167fa
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_64bit_version_5_6_or_later_out_of_range.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2012 Kentoku SHIBA
+# Copyright(C) 2014 Kenji Maruyama <mmmaru777@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_freebsd.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
+--source ../../include/mroonga/skip_strict_sql_mode.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+CREATE TABLE diaries (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ title TEXT,
+ created_at DATETIME
+) DEFAULT CHARSET UTF8;
+
+INSERT INTO diaries (title, created_at)
+ VALUES ('2012', '2012');
+
+SELECT * FROM diaries;
+
+DROP TABLE diaries;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_fractional_seconds_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_fractional_seconds_with_index.test
index efa54b1e094..94eb237f1a2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_fractional_seconds_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_fractional_seconds_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_fractional_seconds.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ CREATE TABLE diaries (
created_at DATETIME(6),
KEY (created_at)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
VALUES ("clear day", "2012-01-29 21:51:01.111111");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_fractional_seconds_without_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_fractional_seconds_without_index.test
index f0f51fba53e..5dc033f1c53 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_fractional_seconds_without_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_fractional_seconds_without_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_fractional_seconds.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME(6)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
VALUES ("clear day", "2012-01-29 21:51:01.111111");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_freebsd_before_unix_epoch.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_freebsd_before_unix_epoch.test
index e75539d4ae2..d66ed5617b8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_freebsd_before_unix_epoch.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_freebsd_before_unix_epoch.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_freebsd.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
VALUES ('1000-01-01 00:00:00', '1000-01-01 00:00:00');
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date_strict.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mariadb_10_2_or_later_zero_date.test
index 808313da930..3382a1c1e68 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date_strict.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mariadb_10_2_or_later_zero_date.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,8 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source ../../include/mroonga/have_mariadb_10_2_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -24,12 +25,9 @@ CREATE TABLE timestamps (
id INT PRIMARY KEY AUTO_INCREMENT,
create_dt DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE timestamps;
-SET sql_mode='STRICT_TRANS_TABLES';
--error ER_WARN_DATA_OUT_OF_RANGE
INSERT INTO timestamps (create_dt) VALUES ("0000-00-00 00:00:00");
-SET sql_mode=default;
SELECT * FROM timestamps;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mariadb_10_2_or_later_zero_month_day.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mariadb_10_2_or_later_zero_month_day.test
new file mode 100644
index 00000000000..f95b0947fc2
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mariadb_10_2_or_later_zero_month_day.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2013 Kentoku SHIBA
+# Copyright(C) 2016-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mariadb_10_2_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS timestamps;
+--enable_warnings
+
+CREATE TABLE timestamps (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ create_dt DATETIME
+) DEFAULT CHARSET UTF8;
+
+--error ER_WARN_DATA_OUT_OF_RANGE
+INSERT INTO timestamps (create_dt) VALUES ("2012-00-01 00:00:00");
+--error ER_WARN_DATA_OUT_OF_RANGE
+INSERT INTO timestamps (create_dt) VALUES ("2012-01-00 00:00:00");
+
+SELECT * FROM timestamps;
+
+DROP TABLE timestamps;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mysql_5_7_or_later_zero_date.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mysql_5_7_or_later_zero_date.test
new file mode 100644
index 00000000000..2b6a05915d7
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mysql_5_7_or_later_zero_date.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS timestamps;
+--enable_warnings
+
+CREATE TABLE timestamps (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ create_dt DATETIME
+) DEFAULT CHARSET UTF8;
+
+--error ER_TRUNCATED_WRONG_VALUE
+INSERT INTO timestamps (create_dt) VALUES ("0000-00-00 00:00:00");
+
+SELECT * FROM timestamps;
+
+INSERT INTO timestamps (create_dt) VALUES ("2015-06-17 00:00:00");
+SELECT * FROM timestamps;
+
+DROP TABLE timestamps;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mysql_5_7_or_later_zero_month_day.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mysql_5_7_or_later_zero_month_day.test
new file mode 100644
index 00000000000..4419231a93e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_mysql_5_7_or_later_zero_month_day.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2013 Kentoku SHIBA
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS timestamps;
+--enable_warnings
+
+CREATE TABLE timestamps (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ create_dt DATETIME
+) DEFAULT CHARSET UTF8;
+
+--error ER_TRUNCATED_WRONG_VALUE
+INSERT INTO timestamps (create_dt) VALUES ("2012-00-01 00:00:00");
+--error ER_TRUNCATED_WRONG_VALUE
+INSERT INTO timestamps (create_dt) VALUES ("2012-01-00 00:00:00");
+
+SELECT * FROM timestamps;
+
+DROP TABLE timestamps;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_null.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_null.test
index 8c30509037f..fcea5431330 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_null.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_null.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -25,7 +25,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
VALUES ('NULL', NULL);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_with_index.test
index b49897800a0..bf415b177f8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
created_at DATETIME,
KEY (created_at)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
VALUES ("clear day", "2012-01-29 21:51:01");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_without_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_without_index.test
index b1168f63330..c6c9edec5de 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_without_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_without_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -25,7 +25,6 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at)
VALUES ("clear day", "2012-01-29 21:51:01");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date.test
index 66ba81d79e5..c5107e6c885 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2013 Kentoku SHIBA
+# Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,8 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source include/not_embedded.inc
+--source ../../include/mroonga/skip_strict_sql_mode.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -24,16 +26,16 @@ CREATE TABLE timestamps (
id INT PRIMARY KEY AUTO_INCREMENT,
create_dt DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE timestamps;
-SET sql_mode='';
-INSERT INTO timestamps (create_dt) VALUES ("2012-00-01 00:00:00");
-INSERT INTO timestamps (create_dt) VALUES ("2012-01-00 00:00:00");
-SET sql_mode = DEFAULT;
+SET sql_mode='STRICT_TRANS_TABLES';
+--error ER_WARN_DATA_OUT_OF_RANGE
+INSERT INTO timestamps (create_dt) VALUES ("0000-00-00 00:00:00");
+SET sql_mode=default;
SELECT * FROM timestamps;
-SELECT * FROM timestamps WHERE create_dt = "2012-01-01 00:00:00";
+INSERT INTO timestamps (create_dt) VALUES ("2015-06-17 00:00:00");
+SELECT * FROM timestamps;
DROP TABLE timestamps;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_month_day.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_month_day.test
new file mode 100644
index 00000000000..12b5862412e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_month_day.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2013 Kentoku SHIBA
+# Copyright(C) 2016-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_strict_sql_mode.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS timestamps;
+--enable_warnings
+
+CREATE TABLE timestamps (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ create_dt DATETIME
+) DEFAULT CHARSET UTF8;
+
+INSERT INTO timestamps (create_dt) VALUES ("2012-00-01 00:00:00");
+INSERT INTO timestamps (create_dt) VALUES ("2012-01-00 00:00:00");
+
+SELECT * FROM timestamps;
+
+SELECT * FROM timestamps WHERE create_dt = "2012-01-01 00:00:00";
+
+DROP TABLE timestamps;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_fractional_seconds_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_fractional_seconds_with_index.test
index 9213379336f..03cb6b64d2f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_fractional_seconds_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_fractional_seconds_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
temperature DECIMAL(6, 3),
KEY (temperature)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, temperature) VALUES ("clear day", 21.281);
INSERT INTO diaries (title, temperature) VALUES ("rainy day", 14.213);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_fractional_seconds_without_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_fractional_seconds_without_index.test
index 91e4b789aea..ca59d052e78 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_fractional_seconds_without_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_fractional_seconds_without_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -25,7 +25,6 @@ CREATE TABLE diaries (
title TEXT,
temperature DECIMAL(6, 3)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, temperature) VALUES ("clear day", 21.281);
INSERT INTO diaries (title, temperature) VALUES ("rainy day", 14.213);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_with_index.test
index 46d9ea37470..14303454af2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
temperature DECIMAL,
KEY (temperature)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, temperature) VALUES ("clear day", 21);
INSERT INTO diaries (title, temperature) VALUES ("rainy day", 14);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_without_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_without_index.test
index acda07ab954..ef8609a78ad 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_without_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_decimal_without_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -25,7 +25,6 @@ CREATE TABLE diaries (
title TEXT,
temperature DECIMAL
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, temperature) VALUES ("clear day", 21);
INSERT INTO diaries (title, temperature) VALUES ("rainy day", 14);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_enum_less_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_enum_less_with_index.test
index 2b7fd7de818..6a7a5bcc37b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_enum_less_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_enum_less_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_enum_many_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_enum_many_with_index.test
index f4b3175764c..92eabc11d61 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_enum_many_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_enum_many_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_add_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_add_column.test
new file mode 100644
index 00000000000..8561688db3a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_add_column.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+
+ALTER TABLE logs ADD COLUMN message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED;
+ALTER TABLE logs ADD FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"';
+
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_delete.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_delete.test
new file mode 100644
index 00000000000..a54ee0e26a9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_delete.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+ FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+DELETE FROM logs WHERE id = 1;
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_drop_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_drop_column.test
new file mode 100644
index 00000000000..0bd96387469
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_drop_column.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+ FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+ALTER TABLE logs DROP COLUMN message;
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_insert.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_insert.test
new file mode 100644
index 00000000000..841c2f44452
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_insert.test
@@ -0,0 +1,40 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+ FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_reindex.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_reindex.test
new file mode 100644
index 00000000000..725c32384df
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_reindex.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+ FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+ALTER TABLE logs DISABLE KEYS;
+ALTER TABLE logs ENABLE KEYS;
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_update.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_update.test
new file mode 100644
index 00000000000..08969fa5716
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_update.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+ FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+UPDATE logs SET record = '{"level": "info", "message": "shutdown"}' WHERE id = 2;
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST("hut" IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_add_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_add_column.test
new file mode 100644
index 00000000000..80437aa0e29
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_add_column.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+
+ALTER TABLE logs ADD COLUMN message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL;
+
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_delete.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_delete.test
new file mode 100644
index 00000000000..c36913cecca
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_delete.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+DELETE FROM logs WHERE id = 1;
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_drop_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_drop_column.test
new file mode 100644
index 00000000000..0946b1f30ec
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_drop_column.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+ALTER TABLE logs DROP COLUMN message;
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_insert.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_insert.test
new file mode 100644
index 00000000000..90cb5247693
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_insert.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mariadb_10_2_or_later_add_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mariadb_10_2_or_later_add_index.test
new file mode 100644
index 00000000000..340c5e70fcd
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mariadb_10_2_or_later_add_index.test
@@ -0,0 +1,35 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mariadb_10_2_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+--error 16509
+ALTER TABLE logs ADD INDEX (message);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mariadb_10_2_or_later_create_table_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mariadb_10_2_or_later_create_table_with_index.test
new file mode 100644
index 00000000000..480cc1f7b94
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mariadb_10_2_or_later_create_table_with_index.test
@@ -0,0 +1,32 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mariadb_10_2_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+--error 16509
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL,
+ FULLTEXT INDEX (message)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mysql_5_7_or_later_add_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mysql_5_7_or_later_add_index.test
new file mode 100644
index 00000000000..7c953d30d14
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_mysql_5_7_or_later_add_index.test
@@ -0,0 +1,35 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+--error ER_ILLEGAL_HA_CREATE_OPTION
+ALTER TABLE logs ADD INDEX (message);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_update.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_update.test
new file mode 100644
index 00000000000..68d97f990dc
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_virtual_update.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+UPDATE logs SET record = '{"level": "info", "message": "shutdown"}' WHERE id = 2;
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga__id__id.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga__id__id.test
index ca4f154d402..39031cabf15 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga__id__id.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga__id__id.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga__id_invalid_id.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga__id_invalid_id.test
index c1c16d3affc..6b4c637a359 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga__id_invalid_id.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga__id_invalid_id.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_other_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_other_table.test
index 9c83c94b417..4d4a0f5a673 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_other_table.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_other_table.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_vector_other_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_vector_other_table.test
index 5143f06a21a..b96fa9b03b3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_vector_other_table.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_vector_other_table.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_int_other_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_int_other_table.test
index 9be02c2a1a2..d3caeba70bf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_int_other_table.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_int_other_table.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_reference.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_reference.test
index b7e85909399..59471f7e97b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_reference.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_reference.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_lz4.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_lz4.test
index 432aab88629..e0ab1ad4c1b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_lz4.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_lz4.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/support_libgroonga_lz4.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zlib.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zlib.test
index 0f21e37c201..7d5665b04f5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zlib.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zlib.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/support_libgroonga_zlib.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zstd.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zstd.test
new file mode 100644
index 00000000000..99ac2cdbb6b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zstd.test
@@ -0,0 +1,37 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/support_libgroonga_zstd.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS entries;
+--enable_warnings
+
+CREATE TABLE entries (
+ id INT UNSIGNED PRIMARY KEY,
+ content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZSTD"'
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!");
+
+SELECT * FROM entries;
+
+DROP TABLE entries;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_lz4.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_lz4.test
index d057e0bcfbd..4d0a80ad5d5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_lz4.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_lz4.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/unsupport_libgroonga_lz4.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zlib.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zlib.test
index 1066270e48d..bbaaa51be40 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zlib.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zlib.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/unsupport_libgroonga_zlib.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zstd.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zstd.test
new file mode 100644
index 00000000000..6b5eb5cd86f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zstd.test
@@ -0,0 +1,37 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/unsupport_libgroonga_zstd.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS entries;
+--enable_warnings
+
+CREATE TABLE entries (
+ id INT UNSIGNED PRIMARY KEY,
+ content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZSTD"'
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!");
+
+SELECT * FROM entries;
+
+DROP TABLE entries;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_with_not_for_mroonga_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_with_not_for_mroonga_comment.test
index b168716ed94..e18f17b7c95 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_with_not_for_mroonga_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_with_not_for_mroonga_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_vector_order_by_with_function.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_vector_order_by_with_function.test
index 2098e878ecb..3675db38c48 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_vector_order_by_with_function.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_vector_order_by_with_function.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_vector_reference.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_vector_reference.test
index 995fafefeeb..9b6c8d3016f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_vector_reference.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_vector_reference.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2013-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
@@ -29,8 +29,9 @@ CREATE TABLE tags (
CREATE TABLE bugs (
id INT UNSIGNED PRIMARY KEY,
- tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "tags"'
+ tags VARCHAR(128) DEFAULT '' COMMENT 'flags "COLUMN_VECTOR", type "tags"'
) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE bugs;
INSERT INTO bugs (id, tags) VALUES (1, "Linux MySQL groonga");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_int_with_index_zero_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_int_with_index_zero_value.test
index d8d181228bb..038d29c9e66 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_int_with_index_zero_value.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_int_with_index_zero_value.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_json_insert.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_json_insert.test
new file mode 100644
index 00000000000..9bba55b0b92
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_json_insert.test
@@ -0,0 +1,37 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_0_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ record JSON
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO logs VALUES ('{"message": "start"}');
+INSERT INTO logs VALUES ('{"message": "restart"}');
+INSERT INTO logs VALUES ('{"message": "shutdown"}');
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_multibyte_cp932.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_multibyte_cp932.test
new file mode 100644
index 00000000000..f7eae384dcf
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_multibyte_cp932.test
@@ -0,0 +1,51 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES cp932;
+
+CREATE TABLE users (
+ –¼‘O text,
+ FULLTEXT INDEX (–¼‘O)
+) DEFAULT CHARSET=cp932;
+
+INSERT INTO users VALUES ("‚â‚Ü‚¾");
+INSERT INTO users VALUES ("‚½‚È‚©");
+INSERT INTO users VALUES ("‚·‚¸‚«");
+
+SELECT * FROM users;
+
+SELECT * FROM users
+ WHERE MATCH (–¼‘O) AGAINST ('+‚½‚È‚©' IN BOOLEAN MODE);
+
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+
+DROP TABLE users;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_multibyte_utf8.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_multibyte_utf8.test
new file mode 100644
index 00000000000..6d6c44ceba1
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_multibyte_utf8.test
@@ -0,0 +1,51 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE users (
+ åå‰ text,
+ FULLTEXT INDEX (åå‰)
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO users VALUES ("ã‚„ã¾ã ");
+INSERT INTO users VALUES ("ãŸãªã‹");
+INSERT INTO users VALUES ("ã™ãšã");
+
+SELECT * FROM users;
+
+SELECT * FROM users
+ WHERE MATCH (åå‰) AGAINST ('+ãŸãªã‹' IN BOOLEAN MODE);
+
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+
+DROP TABLE users;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_set_16_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_set_16_with_index.test
index ede3a07f542..a4e229dd17a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_set_16_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_set_16_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_set_24_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_set_24_with_index.test
index c43f5c70e13..5d7b8c4dff8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_set_24_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_set_24_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_set_32_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_set_32_with_index.test
index ccddec38fa0..3391fb7b740 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_set_32_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_set_32_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_set_64_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_set_64_with_index.test
index c041a3f9ea9..219bb085c84 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_set_64_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_set_64_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_set_8_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_set_8_with_index.test
index d8a6a0ac36c..79d56f4e8e6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_set_8_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_set_8_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_bigint_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_bigint_with_index.test
index 0a2f9d30749..a031cab8767 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_bigint_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_bigint_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_int_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_int_with_index.test
index b64d97fd24e..287d0407bdf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_int_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_int_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_mediumint_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_mediumint_with_index.test
index f2252055c10..704cc4d41e3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_mediumint_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_mediumint_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_smallint_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_smallint_with_index.test
index ff2eeef6a7b..2200efc71c4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_smallint_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_smallint_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_tinyint_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_tinyint_with_index.test
index 50824bb2cba..33f07c47470 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_tinyint_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_signed_tinyint_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_time_fractional_seconds_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_time_fractional_seconds_with_index.test
index 54d127c734d..c8e6dddf4bd 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_time_fractional_seconds_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_time_fractional_seconds_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_fractional_seconds.inc
@@ -28,7 +28,6 @@ CREATE TABLE running_records (
max TIME(6),
KEY (average)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE running_records;
INSERT INTO running_records (title, average, max)
VALUES ("normal condition", "01:00:00.000001", "01:05:00.000001");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_time_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_time_with_index.test
index cfa760bcae5..e950411cba6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_time_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_time_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ CREATE TABLE running_records (
max TIME,
KEY (average)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE running_records;
INSERT INTO running_records (title, average, max)
VALUES ("normal condition", "01:00:00", "01:05:00");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_timestamp_fractional_seconds_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_timestamp_fractional_seconds_with_index.test
index c2407cb1b0b..19dadc2c285 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_timestamp_fractional_seconds_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_timestamp_fractional_seconds_with_index.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/skip_mariadb_55.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
--source ../../include/mroonga/have_fractional_seconds.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -29,7 +29,6 @@ CREATE TABLE diaries (
updated_at TIMESTAMP(6),
KEY (updated_at)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at, updated_at)
VALUES ("clear day",
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_timestamp_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_timestamp_with_index.test
index f398fb9b9e2..cc063faa674 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_timestamp_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_timestamp_with_index.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -23,11 +23,10 @@ DROP TABLE IF EXISTS diaries;
CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
- created_at TIMESTAMP,
- updated_at TIMESTAMP,
+ created_at TIMESTAMP DEFAULT '2016-04-21 00:00:00',
+ updated_at TIMESTAMP DEFAULT '2016-04-21 00:00:00',
KEY (updated_at)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, created_at, updated_at)
VALUES ("clear day", "2012-01-29 21:51:01", "2012-01-29 21:51:02");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_tinyint_without_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_tinyint_without_index.test
index 9cf9cb631ec..de0cbedf0ab 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_tinyint_without_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_tinyint_without_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_bigint_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_bigint_with_index.test
index 2da118e27a5..b7cb8694301 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_bigint_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_bigint_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_bigint_without_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_bigint_without_index.test
index dea56970414..912f86fb71c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_bigint_without_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_bigint_without_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_int_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_int_with_index.test
index a2eb99b1dce..f20348bee6c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_int_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_int_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_mediumint_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_mediumint_with_index.test
index e219fc0757b..44fb656a93b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_mediumint_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_mediumint_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_smallint_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_smallint_with_index.test
index e9dcd7e1e06..c98569d1974 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_smallint_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_smallint_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_tinyint_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_tinyint_with_index.test
index d90c71df988..9414eee1f02 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_tinyint_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_unsigned_tinyint_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_year_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_year_with_index.test
index e7cb3f69610..82004e1971d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_year_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_year_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE aniversary_memos (
party_year YEAR,
KEY (party_year)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE aniversary_memos;
INSERT INTO aniversary_memos (title, party_year)
VALUES ("We need a big cake!", "11");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_year_without_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_year_without_index.test
index 8b798a71837..e7530cec034 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/column_year_without_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_year_without_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -25,7 +25,6 @@ CREATE TABLE aniversary_memos (
title TEXT,
party_year YEAR
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE aniversary_memos;
INSERT INTO aniversary_memos (title, party_year)
VALUES ("We need a big cake!", "11");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/count_star.test b/storage/mroonga/mysql-test/mroonga/storage/t/count_star.test
new file mode 100644
index 00000000000..f57d40fd57b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/count_star.test
@@ -0,0 +1,35 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS ids;
+--enable_warnings
+
+CREATE TABLE ids (
+ id int PRIMARY KEY
+);
+
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+
+SELECT COUNT(*) FROM ids;
+
+DROP TABLE ids;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_database_name_slash.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_database_name_slash.test
index 28262bb4b7d..1913469353f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_database_name_slash.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_database_name_slash.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_TODO_SPLIT_ME.test
index f02e4ddcb25..1f7bbf12bde 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_TODO_SPLIT_ME.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -64,6 +64,8 @@ create table t1 (c1 time);
desc t1;
drop table t1;
create table t1 (c1 timestamp);
+# For MariaDB 10.2.3
+-- replace_result current_timestamp() CURRENT_TIMESTAMP
desc t1;
drop table t1;
create table t1 (c1 datetime);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_flags_comment.test
index c01d80a209b..908a2fcbdbb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_flags_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_flags_parameter.test
index cb86cddcbe7..fc66ae12fa0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_flags_parameter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
--source include/not_embedded.inc
@@ -29,7 +29,6 @@ CREATE TABLE bugs (
id INT UNSIGNED PRIMARY KEY,
tags TEXT FLAGS='COLUMN_VECTOR'
) DEFAULT CHARSET=utf8;
-SHOW CREATE TABLE bugs;
SELECT mroonga_command("dump --dump_plugins no");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_groonga_type_comment.test
index d7514512b5c..b39da499d5e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_groonga_type_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_nonexistent.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_groonga_type_nonexistent.test
index 10d00bfcbb0..0350a299b08 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_nonexistent.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_groonga_type_nonexistent.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_groonga_type_parameter.test
index 4b820f7b88e..d208e62e839 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_groonga_type_parameter.test
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_type_comment.test
index 18cfbb33da5..77965a70c99 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_type_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_nonexistent.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_type_nonexistent.test
index 1c3b89be67f..46becfdc2cc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_nonexistent.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_column_type_nonexistent.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_comment_normal.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_comment_normal.test
index 18a68fb1f94..aecfab1f6c3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_comment_normal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_comment_normal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_default_tokenizer.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_default_tokenizer.test
index 054d311bd44..c5fa91c5c9c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_default_tokenizer.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_default_tokenizer.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test
index 9a22c1b09ea..568c9ac78cf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_index_medium.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_index_medium.test
new file mode 100644
index 00000000000..df509ed0dcd
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_index_medium.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ content VARCHAR(64) NOT NULL,
+ content_size INT NOT NULL,
+ KEY (content_size) COMMENT 'flags "INDEX_MEDIUM"'
+) DEFAULT CHARSET=utf8;
+
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_index_small.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_index_small.test
new file mode 100644
index 00000000000..fc37e28eb76
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_index_small.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ content VARCHAR(64) NOT NULL,
+ is_read BOOL NOT NULL,
+ KEY (is_read) COMMENT 'flags "INDEX_SMALL"'
+) DEFAULT CHARSET=utf8;
+
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test
index 470283e94d8..cc54ab34ad7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test
index 77a7683bc35..0c87494e3c7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test
index e3680ad3471..7005643546f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_with_position_and_with_weight.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_with_position_and_with_weight.test
index 7add6db7831..4700c280d80 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_with_position_and_with_weight.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_with_position_and_with_weight.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_comment.test
index 42a91ecfc15..5251bf9842a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_fulltext_index_bin.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_fulltext_index_bin.test
new file mode 100644
index 00000000000..2815b285096
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_fulltext_index_bin.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+SET NAMES utf8;
+
+CREATE TABLE diaries (
+ day DATE PRIMARY KEY,
+ content VARCHAR(64) NOT NULL,
+ FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+INSERT INTO diaries VALUES ("2013-04-23", "ブラックコーヒーを飲んã ã€‚");
+
+SELECT * FROM diaries
+ WHERE MATCH (content) AGAINST ("+ãµã‚‰ã¤ã" IN BOOLEAN MODE);
+SELECT * FROM diaries
+ WHERE MATCH (content) AGAINST ("+ブラック" IN BOOLEAN MODE);
+
+DROP TABLE diaries;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_index_bin.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_index_bin.test
new file mode 100644
index 00000000000..5270372e332
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_index_bin.test
@@ -0,0 +1,37 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+SET NAMES utf8;
+
+CREATE TABLE diaries (
+ day DATE PRIMARY KEY,
+ content VARCHAR(64) NOT NULL,
+ INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+SELECT mroonga_command("dump --dump_plugins no");
+
+DROP TABLE diaries;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.test
index c35c7dc15ce..2d7ff664335 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_none.test
index fe9037843bf..15045b5466c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_none.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_none.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test
index 5739e118ae3..16b76e0ec09 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test
index 7048ab6e764..c712c2ed018 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test
@@ -12,8 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -26,7 +27,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX body_index (body)
COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"'
) DEFAULT CHARSET utf8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (body) VALUES ("will start Groonga!");
INSERT INTO diaries (body) VALUES ("starting Groonga...");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_default.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_default.test
index e163201e859..e247e3d17f0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_default.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_default.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,6 @@ create table diaries (
body text,
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
insert into diaries (body) values ("will start Groonga!");
insert into diaries (body) values ("starting Groonga...");
insert into diaries (body) values ("started Groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_off.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_off.test
index 69a48eb7851..a2484a90a6e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_off.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_off.test
@@ -12,8 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -25,7 +26,6 @@ CREATE TABLE variables (
name TEXT,
FULLTEXT INDEX (name) COMMENT 'parser "off"'
) DEFAULT CHARSET=utf8;
-SHOW CREATE TABLE variables;
INSERT INTO variables (name) VALUES ("mroonga_database_path_prefix");
INSERT INTO variables (name) VALUES ("mroonga_default_parser");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_multiple_token_filters.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_multiple_token_filters.test
index a58a408cf59..b91819e9940 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_multiple_token_filters.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_multiple_token_filters.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_groonga_plugin_register.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_one_token_filter.test
index 0d560582184..4fe85314d1c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_one_token_filter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_one_token_filter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_groonga_plugin_register.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test
index 956044c7618..ba5f9a969ef 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test
index 688783b9743..1066ffebbff 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX body_index (body)
COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
) DEFAULT CHARSET utf8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (body) VALUES ("will start Groonga!");
INSERT INTO diaries (body) VALUES ("starting Groonga...");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test
index c7acf23cb31..e7902c7b214 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,6 @@ create table diaries (
body text,
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
insert into diaries (body) values ("will start Groonga!");
insert into diaries (body) values ("starting Groonga...");
insert into diaries (body) values ("started Groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test
index e9c1fdf473c..1fc724f5117 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -25,7 +25,6 @@ CREATE TABLE variables (
name TEXT,
FULLTEXT INDEX (name) COMMENT 'tokenizer "off"'
) DEFAULT CHARSET=utf8;
-SHOW CREATE TABLE variables;
INSERT INTO variables (name) VALUES ("mroonga_database_path_prefix");
INSERT INTO variables (name) VALUES ("mroonga_default_tokenizer");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test
index 222cc59e402..7ffedeaea5b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
body text,
FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit'
) DEFAULT CHARSET utf8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (body) VALUES ("will start Groonga!");
INSERT INTO diaries (body) VALUES ("starting Groonga...");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_default.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_default.test
index c161c50626d..1eaf8fa615f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_default.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_default.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_hash.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_hash.test
index 22b3061ced2..626172020aa 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_hash.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_hash.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_multiple_token_filters.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_multiple_token_filters.test
index 0c0fb1394cc..2120efe0f96 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_multiple_token_filters.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_multiple_token_filters.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_groonga_plugin_register.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_one_token_filter.test
index 74d40a1adc3..317730f205f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_one_token_filter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_one_token_filter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_groonga_plugin_register.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_stop_word.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_stop_word.test
index 62cc9ed172f..2639f32517c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_stop_word.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_stop_word.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_groonga_plugin_register.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/delete_fulltext_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/delete_fulltext_column.test
index 89e6c347c8c..6c2c628224f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/delete_fulltext_column.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/delete_fulltext_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_btree_many_records.test b/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_btree_many_records.test
index aa38839f9ca..36f98483789 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_btree_many_records.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_btree_many_records.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_hash_id_no_unique.test b/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_hash_id_no_unique.test
index 44f6bba6adc..00f9336c160 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_hash_id_no_unique.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_hash_id_no_unique.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_hash_id_unique.test b/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_hash_id_unique.test
index 7c562842a95..be309e71b8f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_hash_id_unique.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/delete_index_hash_id_unique.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/delete_normal_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/delete_normal_column.test
index 513c56f074d..3598a17f72e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/delete_normal_column.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/delete_normal_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/delete_unsigned_bigint.test b/storage/mroonga/mysql-test/mroonga/storage/t/delete_unsigned_bigint.test
index 0199dd14a5d..1bd21b65881 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/delete_unsigned_bigint.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/delete_unsigned_bigint.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/drop_database_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/storage/t/drop_database_TODO_SPLIT_ME.test
index 3d8430703a2..383ada185e5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/drop_database_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/drop_database_TODO_SPLIT_ME.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/drop_database_no_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/drop_database_no_table.test
new file mode 100644
index 00000000000..764db3d6fe9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/drop_database_no_table.test
@@ -0,0 +1,57 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+--disable_warnings
+DROP DATABASE IF EXISTS another;
+--enable_warnings
+
+CREATE DATABASE another;
+USE another;
+
+CREATE TABLE diaries (
+ title TEXT,
+ FULLTEXT INDEX (title)
+);
+
+DROP TABLE diaries;
+
+
+USE test;
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+CREATE TABLE diaries (
+ title TEXT,
+ FULLTEXT INDEX (title)
+);
+
+
+DROP DATABASE another;
+
+SELECT mroonga_command('object_exist mroonga_operations');
+
+DROP TABLE diaries;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/drop_table_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/storage/t/drop_table_TODO_SPLIT_ME.test
index 39aff4e4b23..b27fda75e95 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/drop_table_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/drop_table_TODO_SPLIT_ME.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/flush_logs.test b/storage/mroonga/mysql-test/mroonga/storage/t/flush_logs.test
index 887b204c7ae..44d6438bbaf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/flush_logs.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/flush_logs.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_alter_add.test b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_alter_add.test
new file mode 100644
index 00000000000..57947bb39b8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_alter_add.test
@@ -0,0 +1,47 @@
+# Copyright(C) 2013 Kentoku SHIBA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_mysql_5_5.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
+--source ../../include/mroonga/skip_mariadb_10_1.inc
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS articles;
+DROP TABLE IF EXISTS comments;
+--enable_warnings
+
+CREATE TABLE comments (
+ comment int unsigned PRIMARY KEY,
+ content text NOT NULL
+);
+
+CREATE TABLE articles (
+ content text NOT NULL,
+ comment int unsigned
+);
+
+ALTER TABLE articles ADD FOREIGN KEY (comment) REFERENCES comments (comment);
+
+SHOW CREATE TABLE articles;
+
+SELECT * FROM information_schema.referential_constraints;
+
+DROP TABLE articles;
+DROP TABLE comments;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_alter_drop.test b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_alter_drop.test
new file mode 100644
index 00000000000..9be7cc7d2ea
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_alter_drop.test
@@ -0,0 +1,48 @@
+# Copyright(C) 2013 Kentoku SHIBA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_mysql_5_5.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
+--source ../../include/mroonga/skip_mariadb_10_1.inc
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS articles;
+DROP TABLE IF EXISTS comments;
+--enable_warnings
+
+CREATE TABLE comments (
+ comment int unsigned PRIMARY KEY,
+ content text NOT NULL
+);
+
+CREATE TABLE articles (
+ content text NOT NULL,
+ comment int unsigned,
+ FOREIGN KEY (comment) REFERENCES comments (comment)
+);
+
+ALTER TABLE articles DROP FOREIGN KEY comment;
+
+SHOW CREATE TABLE articles;
+
+SELECT * FROM information_schema.referential_constraints;
+
+DROP TABLE articles;
+DROP TABLE comments;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_create.test b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_create.test
index 7f02c81dbcd..e8c8540be03 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_create.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_create.test
@@ -12,102 +12,35 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/skip_mysql_55.inc
---source ../../include/mroonga/skip_mariadb_55.inc
+--source ../../include/mroonga/skip_mysql_5_5.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
+--source ../../include/mroonga/skip_mariadb_10_1.inc
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
-drop table if exists articles2;
-drop table if exists articles;
-drop table if exists comments2;
-drop table if exists comments;
+DROP TABLE IF EXISTS articles;
+DROP TABLE IF EXISTS comments;
--enable_warnings
-create table comments(
- comment int unsigned,
- content text not null,
- primary key(comment)
-);
-
-create table articles(
- content text not null,
- comment int unsigned,
- FOREIGN KEY (comment) REFERENCES comments (comment)
-);
-
-insert into comments (comment, content) values
-(1, 'aaa bbb'),(2, 'ccc ddd'),(3, 'eee fff');
-
-insert into articles (content, comment) values
-('111aaa', 1),('222bbb', 2),('222ccc', 2);
-
-select comment, content from comments;
-
-select content, comment from articles;
-
-show create table comments;
-
-show create table articles;
-
-select * from information_schema.referential_constraints;
-
-rename table comments to comments2;
-rename table articles to articles2;
-
-create table comments(
- comment int unsigned,
- content text not null,
- primary key(comment)
+CREATE TABLE comments (
+ comment int unsigned PRIMARY KEY,
+ content text NOT NULL
);
-create table articles(
- content text not null,
+CREATE TABLE articles (
+ content text NOT NULL,
comment int unsigned,
FOREIGN KEY (comment) REFERENCES comments (comment)
);
-insert into comments (comment, content) values
-(1, 'ab'),(2, 'cd'),(3, 'ef');
-
-insert into articles (content, comment) values
-('1a', 1),('2b', 2),('2c', 2);
-
-select comment, content from comments;
-
-select content, comment from articles;
-
-select comment, content from comments2;
-
-select content, comment from articles2;
-
-show create table comments;
-
-show create table articles;
-
-show create table comments2;
-
-show create table articles2;
-
-select * from information_schema.referential_constraints;
-
-alter table articles drop foreign key comment;
-
-show create table articles;
-
-select content, comment from articles;
-
-alter table articles add FOREIGN KEY (comment) REFERENCES comments (comment);
-
-show create table articles;
+SHOW CREATE TABLE articles;
-select content, comment from articles;
+SELECT * FROM information_schema.referential_constraints;
-drop table articles2;
-drop table articles;
-drop table comments2;
-drop table comments;
+DROP TABLE articles;
+DROP TABLE comments;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_delete_existent.test b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_delete_existent.test
new file mode 100644
index 00000000000..29453f6916c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_delete_existent.test
@@ -0,0 +1,53 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_mysql_5_5.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_warnings
+
+CREATE TABLE comments (
+ id int unsigned PRIMARY KEY,
+ content varchar(140) NOT NULL
+);
+
+CREATE TABLE entries (
+ content varchar(140) NOT NULL,
+ comment_id int unsigned,
+ FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+
+INSERT INTO comments (id, content) VALUES (100, 'Good entry!');
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 100);
+--error ER_ROW_IS_REFERENCED_2
+DELETE FROM comments WHERE id = 100;
+
+SELECT * FROM entries;
+SELECT * FROM comments;
+
+SELECT mroonga_command('dump --dump_plugins no');
+
+DROP TABLE entries;
+DROP TABLE comments;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_delete_nonexistent.test b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_delete_nonexistent.test
new file mode 100644
index 00000000000..e2635efc56c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_delete_nonexistent.test
@@ -0,0 +1,53 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_mysql_5_5.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_warnings
+
+CREATE TABLE comments (
+ id int unsigned PRIMARY KEY,
+ content varchar(140) NOT NULL
+);
+
+CREATE TABLE entries (
+ content varchar(140) NOT NULL,
+ comment_id int unsigned,
+ FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+
+INSERT INTO comments (id, content) VALUES (100, 'Good entry!');
+INSERT INTO comments (id, content) VALUES (200, 'Very good entry!');
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 100);
+DELETE FROM comments WHERE id = 200;
+
+SELECT * FROM entries;
+SELECT * FROM comments;
+
+SELECT mroonga_command('dump --dump_plugins no');
+
+DROP TABLE entries;
+DROP TABLE comments;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_insert_existent.test b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_insert_existent.test
new file mode 100644
index 00000000000..0b859c8342f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_insert_existent.test
@@ -0,0 +1,51 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_mysql_5_5.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_warnings
+
+CREATE TABLE comments (
+ id int unsigned PRIMARY KEY,
+ content varchar(140) NOT NULL
+);
+
+CREATE TABLE entries (
+ content varchar(140) NOT NULL,
+ comment_id int unsigned,
+ FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+
+INSERT INTO comments (id, content) VALUES (100, 'Good entry!');
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 100);
+
+SELECT * FROM entries;
+SELECT * FROM comments;
+
+SELECT mroonga_command('dump --dump_plugins no');
+
+DROP TABLE entries;
+DROP TABLE comments;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_insert_nonexistent.test b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_insert_nonexistent.test
new file mode 100644
index 00000000000..0ed29655d38
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_insert_nonexistent.test
@@ -0,0 +1,51 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_mysql_5_5.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_warnings
+
+CREATE TABLE comments (
+ id int unsigned PRIMARY KEY,
+ content varchar(140) NOT NULL
+);
+
+CREATE TABLE entries (
+ content varchar(140) NOT NULL,
+ comment_id int unsigned,
+ FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+
+--error ER_NO_REFERENCED_ROW_2
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 1);
+
+SELECT * FROM entries;
+SELECT * FROM comments;
+
+SELECT mroonga_command('dump --dump_plugins no');
+
+DROP TABLE entries;
+DROP TABLE comments;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_rename.test b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_rename.test
new file mode 100644
index 00000000000..e93958bab83
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_rename.test
@@ -0,0 +1,51 @@
+# Copyright(C) 2013 Kentoku SHIBA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_mysql_5_5.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
+--source ../../include/mroonga/skip_mariadb_10_1.inc
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS articles;
+DROP TABLE IF EXISTS comments;
+DROP TABLE IF EXISTS articles2;
+DROP TABLE IF EXISTS comments2;
+--enable_warnings
+
+CREATE TABLE comments (
+ comment int unsigned PRIMARY KEY,
+ content text NOT NULL
+);
+
+CREATE TABLE articles (
+ content text NOT NULL,
+ comment int unsigned,
+ FOREIGN KEY (comment) REFERENCES comments (comment)
+);
+
+RENAME TABLE comments TO comments2;
+RENAME TABLE articles TO articles2;
+
+SHOW CREATE TABLE articles2;
+
+SELECT * FROM information_schema.referential_constraints;
+
+DROP TABLE articles2;
+DROP TABLE comments2;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_update_existent.test b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_update_existent.test
new file mode 100644
index 00000000000..9b5ee9b9e63
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_update_existent.test
@@ -0,0 +1,53 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_mysql_5_5.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_warnings
+
+CREATE TABLE comments (
+ id int unsigned PRIMARY KEY,
+ content varchar(140) NOT NULL
+);
+
+CREATE TABLE entries (
+ content varchar(140) NOT NULL,
+ comment_id int unsigned,
+ FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+
+INSERT INTO comments (id, content) VALUES (100, 'Good entry!');
+INSERT INTO comments (id, content) VALUES (200, 'Very good entry!');
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 100);
+UPDATE entries SET comment_id = 200 WHERE content = 'Hello!';
+
+SELECT * FROM entries;
+SELECT * FROM comments;
+
+SELECT mroonga_command('dump --dump_plugins no');
+
+DROP TABLE entries;
+DROP TABLE comments;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_update_nonexistent.test b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_update_nonexistent.test
new file mode 100644
index 00000000000..3e0f074828e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/foreign_key_update_nonexistent.test
@@ -0,0 +1,53 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_mysql_5_5.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_warnings
+
+CREATE TABLE comments (
+ id int unsigned PRIMARY KEY,
+ content varchar(140) NOT NULL
+);
+
+CREATE TABLE entries (
+ content varchar(140) NOT NULL,
+ comment_id int unsigned,
+ FOREIGN KEY (comment_id) REFERENCES comments (id)
+);
+
+INSERT INTO comments (id, content) VALUES (100, 'Good entry!');
+INSERT INTO entries (content, comment_id) VALUES ('Hello!', 100);
+--error ER_NO_REFERENCED_ROW_2
+UPDATE entries SET comment_id = 200 WHERE content = 'Hello!';
+
+SELECT * FROM entries;
+SELECT * FROM comments;
+
+SELECT mroonga_command('dump --dump_plugins no');
+
+DROP TABLE entries;
+DROP TABLE comments;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_empty_query.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_empty_query.test
index 6a97baa362e..4bd9ff2db9c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_empty_query.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_empty_query.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_escape.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_escape.test
index 6fedec6810c..89507f0901d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_escape.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_escape.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -20,7 +20,7 @@
DROP TABLE IF EXISTS memos;
--enable_warnings
-SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET GLOBAL mroonga_default_tokenizer = TokenDelimit;
SET NAMES UTF8;
CREATE TABLE memos (
@@ -38,6 +38,6 @@ SELECT * FROM memos
DROP TABLE memos;
-SET GLOBAL mroonga_default_parser = TokenBigram;
+SET GLOBAL mroonga_default_tokenizer = TokenBigram;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_leading_not.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_leading_not.test
index 3e3c517bee6..a39cfebd285 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_leading_not.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_leading_not.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ CREATE TABLE diaries (
content TEXT,
FULLTEXT INDEX (content)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_all.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_all.test
index f927b45fbc6..b8d1c0b9cdb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_all.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_all.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_no_operator.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_no_operator.test
index 1ead74d0354..c59bc9d7b1f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_no_operator.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_no_operator.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_with_or.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_with_or.test
index ba8f1c1eda1..bcbc4963a56 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_with_or.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_with_or.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_with_plus.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_with_plus.test
index 655bf1e8fa0..de10774d83d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_with_plus.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_minus_with_plus.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
index 9c4e92ce55d..d99628494de 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
index 5f1efdb796d..bbebb5b5fe5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
index b720dcf6f71..f4d2112b35a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_no_operator.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_no_operator.test
index 82d0718d1e8..e6f2a7ce6b6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_no_operator.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_no_operator.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test
index c2efa7a8575..d2258a399d1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_minus.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_minus.test
index 29107188c35..03a2ff8744a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_minus.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_minus.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_or.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_or.test
index c5b5f2f795b..97cc2623ebc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_or.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_or.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_syntax_script_operator.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_syntax_script_operator.test
new file mode 100644
index 00000000000..00bd029dee3
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_syntax_script_operator.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2016 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+SET NAMES utf8;
+CREATE TABLE diaries (
+ id INT PRIMARY KEY,
+ title VARCHAR(255),
+ content TEXT,
+ FULLTEXT INDEX (title, content)
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO diaries VALUES(1, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
+INSERT INTO diaries VALUES(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
+INSERT INTO diaries VALUES(3, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
+
+SELECT *, MATCH(title, content)
+ AGAINST("*SS content @ '天気'" in BOOLEAN MODE) AS score
+ FROM diaries
+ WHERE MATCH(title, content)
+ AGAINST("*SS content @ '天気'" in BOOLEAN MODE);
+
+DROP TABLE diaries;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_syntax_script_selector.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_syntax_script_selector.test
new file mode 100644
index 00000000000..e6034ac2af5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_syntax_script_selector.test
@@ -0,0 +1,50 @@
+# Copyright(C) 2016 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+DROP TABLE IF EXISTS readings;
+--enable_warnings
+
+SET NAMES utf8;
+CREATE TABLE readings (
+ reading VARCHAR(255) PRIMARY KEY
+) DEFAULT CHARSET=utf8
+ COLLATE=utf8_bin
+ COMMENT='default_tokenizer "TokenDelimit"';
+
+CREATE TABLE items (
+ name VARCHAR(255) PRIMARY KEY,
+ readings TEXT COMMENT 'flags "COLUMN_VECTOR", type "readings"',
+ FULLTEXT INDEX items_index(readings) COMMENT 'table "readings"'
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO items VALUES("日本", "ニホン ニッãƒãƒ³");
+INSERT INTO items VALUES("ローマ字", "ローマジ");
+INSERT INTO items VALUES("漢字", "カンジ");
+
+SELECT *, MATCH(readings)
+ AGAINST("*SS sub_filter(readings, 'prefix_rk_search(_key, \"niho\")')" in BOOLEAN MODE) AS score
+ FROM items
+ WHERE MATCH(readings)
+ AGAINST("*SS sub_filter(readings, 'prefix_rk_search(_key, \"niho\")')" in BOOLEAN MODE);
+
+DROP TABLE items;
+DROP TABLE readings;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_full_spec.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_full_spec.test
index e8ad55ab4c6..bee227664cb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_full_spec.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_full_spec.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_no_weight.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_no_weight.test
index 5cc8f4154c4..b84eb91129c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_no_weight.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_no_weight.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_omit_section.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_omit_section.test
index b85580dba01..2edac1599f1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_omit_section.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_omit_section.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_ten_or_more_sections.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_ten_or_more_sections.test
index 642b438ebf6..583ede590e8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_ten_or_more_sections.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_ten_or_more_sections.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_three_or_more_sections.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_three_or_more_sections.test
index 5ea8c21797f..8c4cdb79e20 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_three_or_more_sections.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_weight_three_or_more_sections.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_error.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_error.test
index b9beffa2ef7..a972cc6f474 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_error.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_error.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -20,7 +20,7 @@
DROP TABLE IF EXISTS memos;
--enable_warnings
-SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET GLOBAL mroonga_default_tokenizer = TokenDelimit;
SET mroonga_action_on_fulltext_query_error = ERROR;
SET NAMES UTF8;
@@ -40,6 +40,6 @@ SELECT * FROM memos
DROP TABLE memos;
-SET GLOBAL mroonga_default_parser = TokenBigram;
+SET GLOBAL mroonga_default_tokenizer = TokenBigram;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_error_and_log.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_error_and_log.test
index c4195f2a541..4703fa7df10 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_error_and_log.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_error_and_log.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -20,7 +20,7 @@
DROP TABLE IF EXISTS memos;
--enable_warnings
-SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET GLOBAL mroonga_default_tokenizer = TokenDelimit;
SET mroonga_action_on_fulltext_query_error = ERROR_AND_LOG;
SET NAMES UTF8;
@@ -40,6 +40,6 @@ SELECT * FROM memos
DROP TABLE memos;
-SET GLOBAL mroonga_default_parser = TokenBigram;
+SET GLOBAL mroonga_default_tokenizer = TokenBigram;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_ignore.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_ignore.test
index 9a45d479d30..86803c72451 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_ignore.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_ignore.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -20,7 +20,7 @@
DROP TABLE IF EXISTS memos;
--enable_warnings
-SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET GLOBAL mroonga_default_tokenizer = TokenDelimit;
SET mroonga_action_on_fulltext_query_error = "IGNORE";
SET NAMES UTF8;
@@ -39,6 +39,6 @@ SELECT * FROM memos
DROP TABLE memos;
-SET GLOBAL mroonga_default_parser = TokenBigram;
+SET GLOBAL mroonga_default_tokenizer = TokenBigram;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_ignore_and_log.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_ignore_and_log.test
index cf2cd503b28..0080632324f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_ignore_and_log.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_syntax_error_ignore_and_log.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -20,7 +20,7 @@
DROP TABLE IF EXISTS memos;
--enable_warnings
-SET GLOBAL mroonga_default_parser = TokenDelimit;
+SET GLOBAL mroonga_default_tokenizer = TokenDelimit;
SET mroonga_action_on_fulltext_query_error = IGNORE_AND_LOG;
SET NAMES UTF8;
@@ -39,6 +39,6 @@ SELECT * FROM memos
DROP TABLE memos;
-SET GLOBAL mroonga_default_parser = TokenBigram;
+SET GLOBAL mroonga_default_tokenizer = TokenBigram;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_ascii.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_ascii.test
index 4032ca9e669..d080d70d4d8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_ascii.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_ascii.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_cp932.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_cp932.test
index b6ac95da232..db8fa2b4ccb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_cp932.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_cp932.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_cp932.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_eucjpms.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_eucjpms.test
index c990b288552..39c89dbd7a3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_eucjpms.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_eucjpms.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_eucjpms.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_japanese.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_japanese.test
index 2e457aa768c..0de940534f1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_japanese.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_japanese.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_utf8mb4.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_utf8mb4.test
index 8fc97821563..503b96106c3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_utf8mb4.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_charset_utf8mb4.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ CREATE TABLE diaries (
content TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
FULLTEXT INDEX (content)
) DEFAULT CHARSET utf8mb4;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "Alphabet", "ABCDE");
INSERT INTO diaries VALUES(2, "Mathmatics", "ð€ðð‚ðƒð„ | U+1D400-U+1D405");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_empty_query.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_empty_query.test
index 619363f0fed..d97e75fef51 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_empty_query.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_empty_query.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_found_rows.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_found_rows.test
index 41d1ab91660..38fbc8bb302 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_found_rows.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_found_rows.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -31,7 +31,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_groonga_varchar_vector.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_groonga_varchar_vector.test
index e346fb1d3bc..e1fea8b07e7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_groonga_varchar_vector.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_groonga_varchar_vector.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/load_mroonga_functions.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_index_recreate.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_index_recreate.test
index 0ac152703c9..5aa812fcb04 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_index_recreate.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_index_recreate.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ create table diaries (
content text,
fulltext index (title)
) default charset utf8;
-show create table diaries;
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_insert_select.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_insert_select.test
index 4f932d5ac2a..2bad02c0991 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_insert_select.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_insert_select.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_insert_values.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_insert_values.test
index ef610b983df..5c1ec53c573 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_insert_values.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_insert_values.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -21,7 +21,6 @@ drop table if exists t1, t2, t3;
--enable_warnings
create table t1 (c1 int primary key, c2 text, fulltext index ft (c2));
-show create table t1;
insert into t1 values (1, "hoge hoge");
insert into t1 values (2, "fuga fuga");
insert into t1 values (3, "moge moge");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_delete.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_delete.test
index ab9522f6fa2..718d78732c6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_delete.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_delete.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -29,7 +29,6 @@ create table diaries (
fulltext index (title),
fulltext index (content)
) default charset utf8;
-show create table diaries;
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_insert.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_insert.test
index 2881d3cf160..7a4bd9b8cb7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_insert.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_insert.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -29,7 +29,6 @@ create table diaries (
fulltext index (title),
fulltext index (content)
) default charset utf8;
-show create table diaries;
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_recreate.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_recreate.test
index 353e19804e5..174374711b9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_recreate.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_recreate.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -29,7 +29,6 @@ create table diaries (
fulltext index (title),
fulltext index (content)
) default charset utf8;
-show create table diaries;
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_update.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_update.test
index 949cc61a442..8ccef3d68e3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_update.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_column_index_update.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -29,7 +29,6 @@ create table diaries (
fulltext index (title),
fulltext index (content)
) default charset utf8;
-show create table diaries;
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_index.test
index 97319b71176..72b617812e9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_multiple_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ create table diaries (
fulltext index title_index (title),
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
insert into diaries (title, body) values ("survey", "will start groonga!");
insert into diaries (title, body) values ("groonga (1)", "starting groonga...");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_no_primary_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_no_primary_key.test
index 419224d4fc0..3487f704d90 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_no_primary_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_no_primary_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
content TEXT,
FULLTEXT INDEX (content)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES("Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES("天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test
index 3f7377d9c6e..416b61b7cc9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_or.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_or.test
index 5c94603c07f..995f92aa413 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_or.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_or.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_different_against.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_different_against.test
index 06afa3ce9cd..dc5901ef777 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_different_against.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_different_against.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_different_match.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_different_match.test
index c90fdf6f88a..73424524fc4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_different_match.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_different_match.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_no_where.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_no_where.test
index a230111ba16..0d2963af7fe 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_no_where.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_no_where.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_same_match_against.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_same_match_against.test
index 601ffcb73bb..0d13720a54e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_same_match_against.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_boolean_mode_same_match_against.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_asc.test
index 7c0156ffd33..aaef394ebda 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_asc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_desc.test
index c422a6a6750..aa1a1a2c160 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_desc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_different_against.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_different_against.test
index cdb4b9f27ae..fd9ea74d86a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_different_against.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_different_against.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_different_match.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_different_match.test
index 54206e43843..c690f92e2ac 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_different_match.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_different_match.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_no_where.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_no_where.test
index 1e84064b122..2919ad86288 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_no_where.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_no_where.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_same_match_against.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_same_match_against.test
index a5040dd80a6..485e2d84cfb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_same_match_against.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_order_natural_language_mode_same_match_against.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_two_inner_join.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_two_inner_join.test
index 17957ab8284..bad8e8bc9c3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_two_inner_join.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_two_inner_join.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_56_no_such_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_10_0_no_such_key.test
index 7dbc8fca2b7..c1d2c6c4cef 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_56_no_such_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_10_0_no_such_key.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_version_56.inc
+--source ../../include/mroonga/have_version_10_0.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_55_no_such_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_5_5_no_such_key.test
index da9de22217c..7c00c29bc47 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_55_no_such_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_5_5_no_such_key.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_version_55.inc
+--source ../../include/mroonga/have_version_5_5.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_100_no_such_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_5_6_no_such_key.test
index cf4c9b60230..a102b4acc72 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_100_no_such_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_version_5_6_no_such_key.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_version_100.inc
+--source ../../include/mroonga/have_version_5_6.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_command_auto-escape.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_command_auto-escape.test
new file mode 100644
index 00000000000..091abbc911a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_command_auto-escape.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+SET NAMES UTF8;
+CREATE TABLE diaries (
+ title TEXT,
+ FULLTEXT KEY (title)
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO diaries VALUES('It is Groonga');
+INSERT INTO diaries VALUES('It is Mroonga');
+
+SELECT mroonga_command('select',
+ 'table', 'diaries',
+ 'filter', 'title @ "Groonga"');
+
+DROP TABLE diaries;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_command_select.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_command_select.test
index 892b24c5a7a..501c2ac86ab 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_command_select.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_command_select.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_command_special-database-name.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_command_special-database-name.test
new file mode 100644
index 00000000000..a74acf89ed8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_command_special-database-name.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP DATABASE IF EXISTS `db-1`;
+CREATE DATABASE `db-1`;
+USE `db-1`;
+--enable_warnings
+
+SET NAMES UTF8;
+CREATE TABLE diaries (
+ title TEXT,
+ FULLTEXT KEY (title)
+) DEFAULT CHARSET=utf8;
+
+SELECT mroonga_command('dump --dump_plugins no');
+
+DROP TABLE diaries;
+
+--disable_query_log
+USE test;
+DROP DATABASE `db-1`;
+--enable_query_log
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_query_is_missing.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_query_is_missing.test
index 2712aab2218..7eb3bba1f3f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_query_is_missing.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_query_is_missing.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_query_is_not_string.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_query_is_not_string.test
index 862e98c5a8c..ca18a93e15c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_query_is_not_string.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_query_is_not_string.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_target_characters_is_not_string.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_target_characters_is_not_string.test
index 39f99a7c2d4..13adc1956d1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_target_characters_is_not_string.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_error_target_characters_is_not_string.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_success_all.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_all.test
index 1dca7076512..993d0b1a413 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_success_all.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_all.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_success_custom.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_custom.test
index e70bb3f367d..5b99a0ebeb6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_success_custom.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_custom.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_join.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_join.test
new file mode 100644
index 00000000000..63cb2b320d5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_join.test
@@ -0,0 +1,54 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+DROP TABLE IF EXISTS queries;
+--enable_warnings
+
+CREATE TABLE users (
+ id INT
+);
+
+CREATE TABLE queries (
+ user_id INT,
+ query TEXT
+);
+
+INSERT INTO users VALUES (1);
+INSERT INTO users VALUES (2);
+INSERT INTO users VALUES (3);
+
+INSERT INTO queries VALUES (1, '(a)');
+INSERT INTO queries VALUES (2, '(b)');
+INSERT INTO queries VALUES (3, '(c)');
+
+SELECT users.id, mroonga_escape(queries.query) AS escaped_query
+ FROM queries
+ LEFT JOIN users ON users.id = queries.user_id
+ ORDER BY users.id;
+
+DROP TABLE queries;
+DROP TABLE users;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_match_against.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_match_against.test
new file mode 100644
index 00000000000..3f93ab18282
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_match_against.test
@@ -0,0 +1,46 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+SET GLOBAL mroonga_default_parser = TokenDelimit;
+
+SET NAMES utf8mb4;
+CREATE TABLE memos (
+ id INT PRIMARY KEY,
+ content TEXT,
+ FULLTEXT INDEX (content)
+) DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO memos VALUES(1, "(Groonga) Installed!");
+INSERT INTO memos VALUES(2, "(Mroonga) Installed!");
+INSERT INTO memos VALUES(3, "(Groonga) Upgraded!");
+
+SELECT * FROM memos
+ WHERE MATCH(content) AGAINST(mroonga_escape("(groonga)") IN BOOLEAN MODE);
+
+DROP TABLE memos;
+
+SET GLOBAL mroonga_default_parser = TokenBigram;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_named.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_named.test
new file mode 100644
index 00000000000..cdd431cfad0
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_named.test
@@ -0,0 +1,26 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+SELECT mroonga_escape('+-><~*()\"\\:' AS query) AS escaped_query;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_success_nested.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_nested.test
index 503e2000b10..f98c4303ef6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_success_nested.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_query_nested.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_decimal.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_decimal.test
new file mode 100644
index 00000000000..10041ef8360
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_decimal.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+--disable_warnings
+DROP TABLE IF EXISTS data;
+--enable_warnings
+
+CREATE TABLE data (
+ value DECIMAL(5, 3)
+);
+
+INSERT INTO data VALUES (2.9);
+
+SELECT mroonga_escape(value AS script)
+ FROM data;
+
+DROP TABLE data;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_integer.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_integer.test
new file mode 100644
index 00000000000..141def4f879
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_integer.test
@@ -0,0 +1,26 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+SELECT mroonga_escape(-29 AS script) AS escaped_query;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_real.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_real.test
new file mode 100644
index 00000000000..663fa69aba9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_real.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+--disable_warnings
+DROP TABLE IF EXISTS data;
+--enable_warnings
+
+CREATE TABLE data (
+ value REAL
+);
+
+INSERT INTO data VALUES (2.9);
+
+SELECT mroonga_escape(value AS script)
+ FROM data;
+
+DROP TABLE data;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_string.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_string.test
new file mode 100644
index 00000000000..864cef60703
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_escape_script_string.test
@@ -0,0 +1,26 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+SELECT mroonga_escape('a\"\\\'z' AS script) AS escaped_query;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_dynamic_keyword.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_dynamic_keyword.test
new file mode 100644
index 00000000000..09bdde1c382
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_dynamic_keyword.test
@@ -0,0 +1,45 @@
+# Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+
+--disable_warnings
+--disable_query_log
+DROP TABLE IF EXISTS keywords;
+--enable_query_log
+--enable_warnings
+
+CREATE TABLE keywords (
+ keyword text
+);
+
+INSERT INTO keywords VALUES ('Mroonga');
+INSERT INTO keywords VALUES ('Groonga');
+
+SELECT mroonga_highlight_html('Mroonga is the Groonga based storage engine.',
+ keyword) AS highlighted
+ FROM keywords;
+
+--disable_query_log
+DROP TABLE keywords;
+--enable_query_log
+
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_japanese.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_japanese.test
new file mode 100644
index 00000000000..10f44e44618
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_japanese.test
@@ -0,0 +1,31 @@
+# Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES utf8;
+
+SELECT mroonga_highlight_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+ 'ロック', '更新') AS highlighted;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_multiple_keywords.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_multiple_keywords.test
new file mode 100644
index 00000000000..185842e77e5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_multiple_keywords.test
@@ -0,0 +1,25 @@
+# Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SELECT mroonga_highlight_html('Mroonga is the Groonga based storage engine.',
+ 'Mroonga', 'Groonga') AS highlighted;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_normalizer.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_normalizer.test
new file mode 100644
index 00000000000..19c1ae826e7
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_normalizer.test
@@ -0,0 +1,25 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SELECT mroonga_highlight_html('Mroonga is the Groonga based storage engine.',
+ 'mroonga') AS highlighted;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_query.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_query.test
new file mode 100644
index 00000000000..089a1d4eba9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_query.test
@@ -0,0 +1,31 @@
+# Copyright(C) 2016-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES utf8;
+
+SELECT mroonga_highlight_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+ 'ロック æ›´æ–° -ボトルãƒãƒƒã‚¯' AS query) AS highlighted;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_query_pragma.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_query_pragma.test
new file mode 100644
index 00000000000..3ba38c0b8d0
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_query_pragma.test
@@ -0,0 +1,31 @@
+# Copyright(C) 2017-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES utf8;
+
+SELECT mroonga_highlight_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+ '*D- +ロック +æ›´æ–° ボトルãƒãƒƒã‚¯' AS query) AS highlighted;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_record.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_record.test
new file mode 100644
index 00000000000..db5b06ecd85
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_highlight_html_record.test
@@ -0,0 +1,55 @@
+# Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+--disable_query_log
+DROP TABLE IF EXISTS memos;
+--enable_query_log
+--enable_warnings
+
+CREATE TABLE memos (
+ content text
+);
+
+INSERT INTO memos VALUES ('Mroonga is a MySQL storage engine based on Groonga, the full text search engine.
+
+In MySQL 5.1 or later, Pluggable Storage Engine interface is introduced, and we can use custom storage engines easily. So we implement Mroonga, so that we can use Groonga through MySQL.
+
+By using Mroonga, you can use Groonga with SQL.');
+
+INSERT INTO memos VALUES ('Since Tritonn was the modified version of MySQL, we need to build it by ourselves or use binary files provided by Tritonn project, thus we cannot use the official binary files provided by MySQL.
+
+On the other hand, Mroonga is an independent program (shared library) using Pluggable Storage Engine interface, and we can dynamically load it on MySQL''s official binary. So we can use it more easily than Tritonn.');
+
+INSERT INTO memos VALUES ('Mroonga has two running modes.
+
+One is "storage mode", that is the default mode, and we use Groonga for both storing data and searching. With this mode, you can have full benefits of Groonga described above, like fast data update, lock-free full text search and geolocation search. But it does not support transactions.
+
+Another one is "wrapper mode", that adds full text search function on other storage engines like MyISAM or InnoDB. With this mode, you can use Groonga''s fast full text search with having the benefits of the storage engine, ex. transaction in InnoDB. But you cannot have benefits from Groonga''s read-lock free characteristic. And you might have the performance bottle neck in the storage engine in updating data.');
+
+SELECT mroonga_highlight_html(content, 'Mroonga') AS highlighted
+ FROM memos;
+
+--disable_query_log
+DROP TABLE memos;
+--enable_query_log
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_grn_id.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_grn_id.test
index 5d80d5230ef..da116a4a508 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_grn_id.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_grn_id.test
@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_id_reference.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_id_reference.test
index 98e8d9dab2f..1ba332c4d86 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_id_reference.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_id_reference.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_id_set.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_id_set.test
index 41f9d3684bf..1fdd0a60511 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_id_set.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_last_insert_id_set.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_default.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_default.test
new file mode 100644
index 00000000000..d5159b88ce1
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_default.test
@@ -0,0 +1,24 @@
+# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SELECT mroonga_normalize('aBcAbCã‘');
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_normalizer.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_normalizer.test
new file mode 100644
index 00000000000..9631313d79b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_normalizer.test
@@ -0,0 +1,24 @@
+# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SELECT mroonga_normalize('aBcAbCã‘', "NormalizerAuto");
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_record.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_record.test
new file mode 100644
index 00000000000..88ee40fc6ca
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_normalize_record.test
@@ -0,0 +1,40 @@
+# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+--disable_query_log
+DROP TABLE IF EXISTS memos;
+--enable_query_log
+--enable_warnings
+
+CREATE TABLE memos (
+ content text
+);
+
+INSERT INTO memos VALUES ('aBcAbCã‘');
+
+SELECT mroonga_normalize(content) FROM memos;
+
+--disable_query_log
+DROP TABLE memos;
+--enable_query_log
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_multiple.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_multiple.test
new file mode 100644
index 00000000000..ee80cd8b914
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_multiple.test
@@ -0,0 +1,46 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+--disable_warnings
+DROP TABLE IF EXISTS synonyms;
+--enable_warnings
+
+CREATE TABLE synonyms (
+ term varchar(255),
+ synonym varchar(255),
+ INDEX (term)
+);
+
+INSERT INTO synonyms VALUES ('Rroonga', 'Rroonga');
+INSERT INTO synonyms VALUES ('Rroonga', 'Groonga Ruby');
+INSERT INTO synonyms VALUES ('Mroonga', 'Mroonga');
+INSERT INTO synonyms VALUES ('Mroonga', 'Groonga MySQL');
+
+SELECT mroonga_query_expand('synonyms',
+ 'term',
+ 'synonym',
+ 'Mroonga Rroonga PGroonga') AS query;
+
+DROP TABLE synonyms;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_no_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_no_index.test
new file mode 100644
index 00000000000..1a2c9d84404
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_no_index.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+--disable_warnings
+DROP TABLE IF EXISTS synonyms;
+--enable_warnings
+
+CREATE TABLE synonyms (
+ term varchar(255),
+ synonym varchar(255)
+);
+
+INSERT INTO synonyms VALUES ('Rroonga', 'Rroonga');
+INSERT INTO synonyms VALUES ('Rroonga', 'Groonga Ruby');
+
+SELECT mroonga_query_expand('synonyms',
+ 'term',
+ 'synonym',
+ 'Mroonga Rroonga PGroonga') AS query;
+
+DROP TABLE synonyms;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_one.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_one.test
new file mode 100644
index 00000000000..50e4fc558bc
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_one.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+--disable_warnings
+DROP TABLE IF EXISTS synonyms;
+--enable_warnings
+
+CREATE TABLE synonyms (
+ term varchar(255),
+ synonym varchar(255),
+ INDEX (term)
+);
+
+INSERT INTO synonyms VALUES ('Rroonga', 'Rroonga');
+INSERT INTO synonyms VALUES ('Rroonga', 'Groonga Ruby');
+
+SELECT mroonga_query_expand('synonyms',
+ 'term',
+ 'synonym',
+ 'Mroonga Rroonga PGroonga') AS query;
+
+DROP TABLE synonyms;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_pragma.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_pragma.test
new file mode 100644
index 00000000000..2a8aad83d29
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_query_expand_pragma.test
@@ -0,0 +1,45 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES UTF8;
+
+--disable_warnings
+DROP TABLE IF EXISTS synonyms;
+--enable_warnings
+
+CREATE TABLE synonyms (
+ term varchar(255),
+ synonym varchar(255),
+ INDEX (term)
+);
+
+INSERT INTO synonyms VALUES ('D+', '[D+]');
+INSERT INTO synonyms VALUES ('Rroonga', 'Rroonga');
+INSERT INTO synonyms VALUES ('Rroonga', 'Groonga Ruby');
+
+SELECT mroonga_query_expand('synonyms',
+ 'term',
+ 'synonym',
+ '*D+ Mroonga Rroonga PGroonga') AS query;
+
+DROP TABLE synonyms;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_ascii.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_ascii.test
index 0cb551dbc69..028bdb750ea 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_ascii.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_ascii.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_cp932.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_cp932.test
index 338417021c8..2d85633ab94 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_cp932.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_cp932.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source include/have_cp932.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_eucjpms.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_eucjpms.test
index fa8dbb20e93..525c14a3004 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_eucjpms.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_eucjpms.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source include/have_eucjpms.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_dynamic_keyword.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_dynamic_keyword.test
new file mode 100644
index 00000000000..5faed518891
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_dynamic_keyword.test
@@ -0,0 +1,45 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+
+--disable_warnings
+--disable_query_log
+DROP TABLE IF EXISTS keywords;
+--enable_query_log
+--enable_warnings
+
+CREATE TABLE keywords (
+ keyword text
+);
+
+INSERT INTO keywords VALUES ('Mroonga');
+INSERT INTO keywords VALUES ('Groonga');
+
+SELECT mroonga_snippet_html('Mroonga is the Groonga based storage engine.',
+ keyword) as snippet
+ FROM keywords;
+
+--disable_query_log
+DROP TABLE keywords;
+--enable_query_log
+
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_japanese.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_japanese.test
new file mode 100644
index 00000000000..c01d298853f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_japanese.test
@@ -0,0 +1,31 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES utf8;
+
+SELECT mroonga_snippet_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+ 'ロック', '更新') as snippet;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_multiple_keywords.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_multiple_keywords.test
new file mode 100644
index 00000000000..60d206d2b40
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_multiple_keywords.test
@@ -0,0 +1,25 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SELECT mroonga_snippet_html('Mroonga is the Groonga based storage engine.',
+ 'Mroonga', 'Groonga') as snippet;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_multiple_snippets.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_multiple_snippets.test
new file mode 100644
index 00000000000..b4dfd0c5f5f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_multiple_snippets.test
@@ -0,0 +1,29 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SELECT mroonga_snippet_html('Mroonga has two running modes.
+
+One is "storage mode", that is the default mode, and we use Groonga for both storing data and searching. With this mode, you can have full benefits of Groonga described above, like fast data update, lock-free full text search and geolocation search. But it does not support transactions.
+
+Another one is "wrapper mode", that adds full text search function on other storage engines like MyISAM or InnoDB. With this mode, you can use Groonga''s fast full text search with having the benefits of the storage engine, ex. transaction in InnoDB. But you cannot have benefits from Groonga''s read-lock free characteristic. And you might have the performance bottle neck in the storage engine in updating data.',
+ 'lock') as snippet;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_query.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_query.test
new file mode 100644
index 00000000000..998a080c7f8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_query.test
@@ -0,0 +1,31 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES utf8;
+
+SELECT mroonga_snippet_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+ 'ロック æ›´æ–° -ボトルãƒãƒƒã‚¯' AS query) as snippet;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_query_pragma.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_query_pragma.test
new file mode 100644
index 00000000000..b01dcbcd54c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_query_pragma.test
@@ -0,0 +1,31 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+SET NAMES utf8;
+
+SELECT mroonga_snippet_html('Mroongaã«ã¯2ã¤ã®å‹•ä½œãƒ¢ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™ã€‚
+
+1ã¤ãŒã€Œã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ¢ãƒ¼ãƒ‰ã€ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆã‚¢ã‚‚検索機能もã™ã¹ã¦Groongaを使ã†ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚上述ã®å‚照ロックフリーãªGroongaã®æ€§èƒ½ç‰¹æ€§ã‚’フルã«æ´»ã‹ã—ãŸé«˜é€Ÿãªãƒ‡ãƒ¼ã‚¿æ›´æ–°ãƒ»å…¨æ–‡æ¤œç´¢ãƒ»ä½ç½®æƒ…報検索ãŒç‰¹é•·ã§ã™ã€‚一方ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ã®æ©Ÿèƒ½ã¯æä¾›ã•ã‚Œã¾ã›ã‚“。
+
+ã‚‚ã†1ã¤ãŒã€Œãƒ©ãƒƒãƒ‘ーモードã€ã§ã€MyISAMã‚„InnoDBã¨ã„ã£ãŸä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã« 全文検索機能ã ã‘ を追加ã™ã‚‹ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãªã©ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„る機能ã«åŠ ãˆã¦Groongaã®é«˜é€Ÿãªå…¨æ–‡æ¤œç´¢æ©Ÿèƒ½ã‚’利用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚一方ã€Groongaã®å‚照ロックフリーãªç‰¹æ€§ã¯æ´»ã‹ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。ã¾ãŸã€æ›´æ–°å‡¦ç†ã¯ä»–ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ãŒãƒœãƒˆãƒ«ãƒãƒƒã‚¯ã«ãªã‚‹ã“ã¨ãŒå¤šã„ã§ã—ょã†ã€‚',
+ '*D- +ロック +æ›´æ–° ボトルãƒãƒƒã‚¯' AS query) as snippet;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_record.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_record.test
new file mode 100644
index 00000000000..59163fe4597
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_html_record.test
@@ -0,0 +1,55 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+--disable_query_log
+DROP TABLE IF EXISTS memos;
+--enable_query_log
+--enable_warnings
+
+CREATE TABLE memos (
+ content text
+);
+
+INSERT INTO memos VALUES ('Mroonga is a MySQL storage engine based on Groonga, the full text search engine.
+
+In MySQL 5.1 or later, Pluggable Storage Engine interface is introduced, and we can use custom storage engines easily. So we implement Mroonga, so that we can use Groonga through MySQL.
+
+By using Mroonga, you can use Groonga with SQL.');
+
+INSERT INTO memos VALUES ('Since Tritonn was the modified version of MySQL, we need to build it by ourselves or use binary files provided by Tritonn project, thus we cannot use the official binary files provided by MySQL.
+
+On the other hand, Mroonga is an independent program (shared library) using Pluggable Storage Engine interface, and we can dynamically load it on MySQL''s official binary. So we can use it more easily than Tritonn.');
+
+INSERT INTO memos VALUES ('Mroonga has two running modes.
+
+One is "storage mode", that is the default mode, and we use Groonga for both storing data and searching. With this mode, you can have full benefits of Groonga described above, like fast data update, lock-free full text search and geolocation search. But it does not support transactions.
+
+Another one is "wrapper mode", that adds full text search function on other storage engines like MyISAM or InnoDB. With this mode, you can use Groonga''s fast full text search with having the benefits of the storage engine, ex. transaction in InnoDB. But you cannot have benefits from Groonga''s read-lock free characteristic. And you might have the performance bottle neck in the storage engine in updating data.');
+
+SELECT mroonga_snippet_html(content, 'Mroonga') as snippet
+ FROM memos;
+
+--disable_query_log
+DROP TABLE memos;
+--enable_query_log
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_invalid_nonexistent_charset.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_invalid_nonexistent_charset.test
index a4e24ce030e..2547000aa95 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_invalid_nonexistent_charset.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_invalid_nonexistent_charset.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_invalid_unsupported_charset.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_invalid_unsupported_charset.test
index 4df02c14e7b..e8805b492d6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_invalid_unsupported_charset.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_invalid_unsupported_charset.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_japanese.test b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_japanese.test
index 3d41de6a93e..1678a3ed29d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_japanese.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/function_snippet_japanese.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/geometry_bulk_insert_null.test b/storage/mroonga/mysql-test/mroonga/storage/t/geometry_bulk_insert_null.test
index f0ce4e81ddb..6f779f610f3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/geometry_bulk_insert_null.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/geometry_bulk_insert_null.test
@@ -12,11 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_geometry.inc
---source ../../include/mroonga/have_version_56_or_later.inc
---source ../../include/mroonga/skip_mysql_57.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
+--source ../../include/mroonga/skip_strict_sql_mode.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/geometry_contains.test b/storage/mroonga/mysql-test/mroonga/storage/t/geometry_contains.test
index 4aed7b24729..94d8024071f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/geometry_contains.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/geometry_contains.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,10 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_geometry.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
+--source ../../include/mroonga/skip_mysql_5_7.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -28,7 +29,6 @@ CREATE TABLE shops (
location GEOMETRY NOT NULL,
SPATIAL KEY location_index (location)
);
-SHOW CREATE TABLE shops;
INSERT INTO shops (name, location)
VALUES ('nezu-no-taiyaki',
@@ -144,6 +144,11 @@ SELECT id, name, ST_AsText(location) AS location_text FROM shops
WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location)
ORDER BY id;
+EXPLAIN
+SELECT id, name, ST_AsText(location) AS location_text FROM shops
+ WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location)
+ ORDER BY id;
+
DROP TABLE shops;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/geometry_bulk_insert_null_57.test b/storage/mroonga/mysql-test/mroonga/storage/t/geometry_strict_sql_mode_bulk_insert_null.test
index 00efe1e4ac7..2fd4fad68e7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/geometry_bulk_insert_null_57.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/geometry_strict_sql_mode_bulk_insert_null.test
@@ -1,5 +1,5 @@
# Copyright(C) 2014 Kenji Maruyama <mmmaru777@gmail.com>
-# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,10 +13,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_geometry.inc
---source ../../include/mroonga/have_version_57.inc
+--source ../../include/mroonga/have_strict_sql_mode.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -27,9 +27,8 @@ CREATE TABLE shops (
location GEOMETRY NOT NULL
);
-SET SESSION sql_mode = '';
+--error ER_BAD_NULL_ERROR
INSERT INTO shops VALUES (NULL), (NULL);
-SET SESSION sql_mode = default;
SELECT ST_AsText(location) FROM shops;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/geometry_strict_sql_mode_contains.test b/storage/mroonga/mysql-test/mroonga/storage/t/geometry_strict_sql_mode_contains.test
new file mode 100644
index 00000000000..605e03833da
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/geometry_strict_sql_mode_contains.test
@@ -0,0 +1,152 @@
+# Copyright(C) 2011-2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS shops;
+--enable_warnings
+
+CREATE TABLE shops (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ name TEXT,
+ location GEOMETRY NOT NULL,
+ SPATIAL KEY location_index (location)
+);
+
+INSERT INTO shops (name, location)
+ VALUES ('nezu-no-taiyaki',
+ ST_GeomFromText('POINT(139.762573 35.720253)'));
+INSERT INTO shops (name, location)
+ VALUES ('taiyaki-kataoka',
+ ST_GeomFromText('POINT(139.715591 35.712521)'));
+INSERT INTO shops (name, location)
+ VALUES ('soba-taiyaki-ku',
+ ST_GeomFromText('POINT(139.659088 35.683712)'));
+INSERT INTO shops (name, location)
+ VALUES ('kuruma',
+ ST_GeomFromText('POINT(139.706207 35.721516)'));
+INSERT INTO shops (name, location)
+ VALUES ('hirose-ya',
+ ST_GeomFromText('POINT(139.685608 35.714844)'));
+INSERT INTO shops (name, location)
+ VALUES ('sazare',
+ ST_GeomFromText('POINT(139.685043 35.714653)'));
+INSERT INTO shops (name, location)
+ VALUES ('omede-taiyaki',
+ ST_GeomFromText('POINT(139.817154 35.700516)'));
+INSERT INTO shops (name, location)
+ VALUES ('onaga-ya',
+ ST_GeomFromText('POINT(139.81105 35.698254)'));
+INSERT INTO shops (name, location)
+ VALUES ('shiro-ya',
+ ST_GeomFromText('POINT(139.638611 35.705517)'));
+INSERT INTO shops (name, location)
+ VALUES ('fuji-ya',
+ ST_GeomFromText('POINT(139.637115 35.703938)'));
+INSERT INTO shops (name, location)
+ VALUES ('miyoshi',
+ ST_GeomFromText('POINT(139.537323 35.644539)'));
+INSERT INTO shops (name, location)
+ VALUES ('juju-ya',
+ ST_GeomFromText('POINT(139.695755 35.628922)'));
+INSERT INTO shops (name, location)
+ VALUES ('tatsumi-ya',
+ ST_GeomFromText('POINT(139.638657 35.665501)'));
+INSERT INTO shops (name, location)
+ VALUES ('tetsuji',
+ ST_GeomFromText('POINT(139.76857 35.680912)'));
+INSERT INTO shops (name, location)
+ VALUES ('gazuma-ya',
+ ST_GeomFromText('POINT(139.647598 35.700817)'));
+INSERT INTO shops (name, location)
+ VALUES ('honma-mon',
+ ST_GeomFromText('POINT(139.652573 35.722736)'));
+INSERT INTO shops (name, location)
+ VALUES ('naniwa-ya',
+ ST_GeomFromText('POINT(139.796234 35.730061)'));
+INSERT INTO shops (name, location)
+ VALUES ('kuro-dai',
+ ST_GeomFromText('POINT(139.704834 35.650345)'));
+INSERT INTO shops (name, location)
+ VALUES ('daruma',
+ ST_GeomFromText('POINT(139.770599 35.681461)'));
+INSERT INTO shops (name, location)
+ VALUES ('yanagi-ya',
+ ST_GeomFromText('POINT(139.783981 35.685341)'));
+INSERT INTO shops (name, location)
+ VALUES ('sharaku',
+ ST_GeomFromText('POINT(139.794846 35.716969)'));
+INSERT INTO shops (name, location)
+ VALUES ('takane',
+ ST_GeomFromText('POINT(139.560913 35.698601)'));
+INSERT INTO shops (name, location)
+ VALUES ('chiyoda',
+ ST_GeomFromText('POINT(139.652817 35.642601)'));
+INSERT INTO shops (name, location)
+ VALUES ('da-ka-po',
+ ST_GeomFromText('POINT(139.727356 35.627346)'));
+INSERT INTO shops (name, location)
+ VALUES ('matsushima-ya',
+ ST_GeomFromText('POINT(139.737381 35.640556)'));
+INSERT INTO shops (name, location)
+ VALUES ('kazuya',
+ ST_GeomFromText('POINT(139.760895 35.673508)'));
+INSERT INTO shops (name, location)
+ VALUES ('furuya-kogane-an',
+ ST_GeomFromText('POINT(139.676071 35.680603)'));
+INSERT INTO shops (name, location)
+ VALUES ('hachi-no-ie',
+ ST_GeomFromText('POINT(139.668106 35.608021)'));
+INSERT INTO shops (name, location)
+ VALUES ('azuki-chan',
+ ST_GeomFromText('POINT(139.673203 35.64151)'));
+INSERT INTO shops (name, location)
+ VALUES ('kuriko-an',
+ ST_GeomFromText('POINT(139.796829 35.712013)'));
+INSERT INTO shops (name, location)
+ VALUES ('yume-no-aru-machi-no-taiyaki-ya-san',
+ ST_GeomFromText('POINT(139.712524 35.616199)'));
+INSERT INTO shops (name, location)
+ VALUES ('naze-ya',
+ ST_GeomFromText('POINT(139.665833 35.609039)'));
+INSERT INTO shops (name, location)
+ VALUES ('sanoki-ya',
+ ST_GeomFromText('POINT(139.770721 35.66592)'));
+INSERT INTO shops (name, location)
+ VALUES ('shigeta',
+ ST_GeomFromText('POINT(139.780273 35.672626)'));
+INSERT INTO shops (name, location)
+ VALUES ('nishimi-ya',
+ ST_GeomFromText('POINT(139.774628 35.671825)'));
+INSERT INTO shops (name, location)
+ VALUES ('hiiragi',
+ ST_GeomFromText('POINT(139.711517 35.647701)'));
+
+SELECT id, name, ST_AsText(location) AS location_text FROM shops;
+SELECT id, name, ST_AsText(location) AS location_text FROM shops
+ WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location)
+ ORDER BY id;
+
+EXPLAIN
+SELECT id, name, ST_AsText(location) AS location_text FROM shops
+ WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location)
+ ORDER BY id;
+
+DROP TABLE shops;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_datetime.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_datetime.test
index 0354e9b7e4b..ccc51b79e68 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_datetime.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_datetime.test
@@ -14,11 +14,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
--source ../../include/mroonga/skip_freebsd.inc
---source ../../include/mroonga/skip_osx.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_time.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_time.test
index a1429859a33..478ae97ba9f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_time.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_time.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_timestamp.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_timestamp.test
index 0f63eed4b52..a1c43cc417e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_timestamp.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_equal_timestamp.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_normal_column_insert.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_normal_column_insert.test
index dcf029593fd..f342c049fd5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_normal_column_insert.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_btree_normal_column_insert.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_normal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_normal.test
index a28a912e23d..bfb3f456360 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_normal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_normal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_primary.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_primary.test
index d622aade72d..7925f4ffc16 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_primary.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_primary.test
@@ -1,4 +1,5 @@
# Copyright(C) 2010 Tetsuro IKEDA
+# Copyright(C) 2016-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,24 +13,28 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source ../../include/mroonga/skip_strict_sql_mode.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
-drop table if exists t1, t2, t3;
+DROP TABLE IF EXISTS t1;
--enable_warnings
-create table t1 (_id int, a int, primary key (_id) using hash);
+CREATE TABLE t1 (_id int, a int, PRIMARY KEY (_id) USING HASH);
+
--error ER_BAD_NULL_ERROR
-insert into t1 values(null, 100);
-insert ignore into t1 values(1,100);
-insert ignore into t1 values(1,100);
-insert ignore into t1 values(1,100);
-insert ignore into t1 values(1,100);
-select * from t1;
-select * from t1 where _id = 2;
-select * from t1 where _id = 20;
-drop table t1;
+INSERT INTO t1 VALUES(null, 100);
+INSERT INTO t1 VALUES(1,100);
+INSERT INTO t1 VALUES(1,100);
+INSERT INTO t1 VALUES(1,100);
+INSERT INTO t1 VALUES(1,100);
+
+SELECT * FROM t1;
+SELECT * FROM t1 WHERE _id = 2;
+SELECT * FROM t1 WHERE _id = 20;
+
+DROP TABLE t1;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_unique.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_unique.test
index 8f1e6b889bb..bf665e83bc5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_unique.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_id_unique.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_normal_column_insert.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_normal_column_insert.test
index acb298ef812..e9f20387651 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_normal_column_insert.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_normal_column_insert.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_strict_sql_mode_id_primary.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_strict_sql_mode_id_primary.test
new file mode 100644
index 00000000000..b2629c80675
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_hash_strict_sql_mode_id_primary.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2010 Tetsuro IKEDA
+# Copyright(C) 2016-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_strict_sql_mode.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (_id int, a int, PRIMARY KEY (_id) USING HASH);
+
+--error ER_BAD_NULL_ERROR
+INSERT INTO t1 VALUES(null, 100);
+--error 1265
+INSERT INTO t1 VALUES(1,100);
+--error 1265
+INSERT INTO t1 VALUES(1,100);
+--error 1265
+INSERT INTO t1 VALUES(1,100);
+--error 1265
+INSERT INTO t1 VALUES(1,100);
+
+SELECT * FROM t1;
+SELECT * FROM t1 WHERE _id = 2;
+SELECT * FROM t1 WHERE _id = 20;
+
+DROP TABLE t1;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_delete.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_delete.test
index ebf331d2f15..5cb0eed102f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_delete.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_delete.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_smallint.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_smallint.test
index 5afdd36b5b8..c5d97a29785 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_smallint.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_smallint.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_bigint.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_bigint.test
index 314dbd85d95..be7b7eefd0f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_bigint.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_bigint.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_int.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_int.test
index 82372d63527..23e75a58073 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_int.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_int.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_smallint.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_smallint.test
index a221c40dcc1..eef9de2d095 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_smallint.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_unsigned_smallint.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_varchar.test
index b765bab6769..8d2d6c92ade 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_varchar.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_nullable_varchar.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_order_by_where_equal_asc_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_order_by_where_equal_asc_asc.test
new file mode 100644
index 00000000000..521061cdf61
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_order_by_where_equal_asc_asc.test
@@ -0,0 +1,49 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT,
+ score2 INT,
+ score3 INT,
+ INDEX (score1, score2, score3)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+
+INSERT INTO items (score1, score2, score3) VALUES(1, 10, -100);
+INSERT INTO items (score1, score2, score3) VALUES(1, 10, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 10, 100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, -100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, 100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, -100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, 100);
+
+SELECT *
+ FROM items
+ WHERE score1 = 2
+ ORDER BY score2 ASC, score3 ASC;
+
+DROP TABLE items;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_order_by_where_equal_desc_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_order_by_where_equal_desc_desc.test
new file mode 100644
index 00000000000..d48c0e56b17
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_order_by_where_equal_desc_desc.test
@@ -0,0 +1,49 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT,
+ score2 INT,
+ score3 INT,
+ INDEX (score1, score2, score3)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+
+INSERT INTO items (score1, score2, score3) VALUES(1, 10, -100);
+INSERT INTO items (score1, score2, score3) VALUES(1, 10, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 10, 100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, -100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 30, 100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, -100);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, 0);
+INSERT INTO items (score1, score2, score3) VALUES(2, 20, 100);
+
+SELECT *
+ FROM items
+ WHERE score1 = 2
+ ORDER BY score2 DESC, score3 DESC;
+
+DROP TABLE items;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_delete.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_delete.test
index 40b39fe8538..92a83088086 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_delete.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_delete.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_select_int.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_select_int.test
index 52cee4c7b33..8978ee2af49 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_select_int.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_select_int.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_strict_sql_mode_update.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_strict_sql_mode_update.test
new file mode 100644
index 00000000000..6abe39795fd
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_strict_sql_mode_update.test
@@ -0,0 +1,47 @@
+# Copyright(C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_strict_sql_mode.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS scores;
+--enable_warnings
+
+SET NAMES utf8;
+CREATE TABLE scores (
+ name char(30) NOT NULL,
+ score int NOT NULL,
+ PRIMARY KEY (name, score)
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", 29);
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", -12);
+INSERT INTO scores (name, score) VALUES ("Jiro Yamada", 27);
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", 10);
+
+SELECT * FROM scores;
+
+--error 1265
+UPDATE scores SET name = "Taro Yamada"
+ WHERE name = "Jiro Yamada" AND score = 27;
+
+SELECT * FROM scores
+ WHERE name = "Taro Yamada" AND (score >= -12 AND score < 29);
+
+DROP TABLE scores;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_update.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_update.test
index d71d1917df5..64292cf18d1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_update.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_primary_update.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,28 +12,35 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source ../../include/mroonga/skip_strict_sql_mode.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
-drop table if exists listing;
+DROP TABLE IF EXISTS scores;
--enable_warnings
-set names utf8;
-create table scores (
- name char(30) not null,
- score int not null,
- primary key (name, score)
-) default charset utf8;
-show create table scores;
-insert into scores (name, score) values("Taro Yamada", 29);
-insert into scores (name, score) values("Taro Yamada", -12);
-insert into scores (name, score) values("Jiro Yamada", 27);
-insert into scores (name, score) values("Taro Yamada", 10);
-select * from scores;
-update ignore scores set name = "Taro Yamada" where name = "Jiro Yamada" and score = 27;
-select * from scores where name = "Taro Yamada" and (score >= -12 and score < 29);
-drop table scores;
+SET NAMES utf8;
+CREATE TABLE scores (
+ name char(30) NOT NULL,
+ score int NOT NULL,
+ PRIMARY KEY (name, score)
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", 29);
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", -12);
+INSERT INTO scores (name, score) VALUES ("Jiro Yamada", 27);
+INSERT INTO scores (name, score) VALUES ("Taro Yamada", 10);
+
+SELECT * FROM scores;
+
+UPDATE scores SET name = "Taro Yamada"
+ WHERE name = "Jiro Yamada" AND score = 27;
+
+SELECT * FROM scores
+ WHERE name = "Taro Yamada" AND (score >= -12 AND score < 29);
+
+DROP TABLE scores;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_greater_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_greater_than.test
index 431f123497b..0cfbea67080 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_greater_than.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_greater_than.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_greater_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_greater_than_or_equal.test
index bc739fdfb52..e5543a66b45 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_greater_than_or_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_greater_than_or_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_less_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_less_than.test
index a3c3b766340..e326aca2678 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_less_than.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_less_than.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_less_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_less_than_or_equal.test
index 3cbac1c1ff9..d2e09033f03 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_not_used_in_order_by_less_than_or_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_all_used_less_than_or_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_greater_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_greater_than.test
new file mode 100644
index 00000000000..49d0d7798d6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_greater_than.test
@@ -0,0 +1,50 @@
+# Copyright(C) 2015 Masafumi Yokoyama <yokoyama@clear-code.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT,
+ score2 INT,
+ created_at DATETIME,
+ INDEX (score1, created_at, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-02 00:00:00");
+
+SELECT *
+ FROM items
+ WHERE score1 = 2 AND created_at > "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+
+DROP TABLE items;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_greater_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_greater_than_or_equal.test
new file mode 100644
index 00000000000..d8e90a15df9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_greater_than_or_equal.test
@@ -0,0 +1,50 @@
+# Copyright(C) 2015 Masafumi Yokoyama <yokoyama@clear-code.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT,
+ score2 INT,
+ created_at DATETIME,
+ INDEX (score1, created_at, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-02 00:00:00");
+
+SELECT *
+ FROM items
+ WHERE score1 = 2 AND created_at >= "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+
+DROP TABLE items;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_less_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_less_than.test
new file mode 100644
index 00000000000..317517f4ca9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_less_than.test
@@ -0,0 +1,50 @@
+# Copyright(C) 2015 Masafumi Yokoyama <yokoyama@clear-code.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT,
+ score2 INT,
+ created_at DATETIME,
+ INDEX (score1, created_at, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-02 00:00:00");
+
+SELECT *
+ FROM items
+ WHERE score1 = 2 AND created_at < "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+
+DROP TABLE items;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_less_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_less_than_or_equal.test
new file mode 100644
index 00000000000..310cc476419
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_have_prefix_less_than_or_equal.test
@@ -0,0 +1,50 @@
+# Copyright(C) 2015 Masafumi Yokoyama <yokoyama@clear-code.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT,
+ score2 INT,
+ created_at DATETIME,
+ INDEX (score1, created_at, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(3, 0, "2015-07-02 00:00:00");
+
+SELECT *
+ FROM items
+ WHERE score1 = 2 AND created_at <= "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+
+DROP TABLE items;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_greater_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_greater_than.test
new file mode 100644
index 00000000000..7449e21ef3c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_greater_than.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2015 Masafumi Yokoyama <yokoyama@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT,
+ score2 INT,
+ created_at DATETIME,
+ INDEX (created_at, score1, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+
+SELECT *
+ FROM items
+ WHERE created_at > "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+
+DROP TABLE items;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_greater_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_greater_than_or_equal.test
new file mode 100644
index 00000000000..3ea5db1493a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_greater_than_or_equal.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2015 Masafumi Yokoyama <yokoyama@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT,
+ score2 INT,
+ created_at DATETIME,
+ INDEX (created_at, score1, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+
+SELECT *
+ FROM items
+ WHERE created_at >= "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+
+DROP TABLE items;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_less_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_less_than.test
new file mode 100644
index 00000000000..50e9ca0d76f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_less_than.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2015 Masafumi Yokoyama <yokoyama@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT,
+ score2 INT,
+ created_at DATETIME,
+ INDEX (created_at, score1, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+
+SELECT *
+ FROM items
+ WHERE created_at < "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+
+DROP TABLE items;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_less_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_less_than_or_equal.test
new file mode 100644
index 00000000000..125143d71ba
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_range_partially_used_no_prefix_less_than_or_equal.test
@@ -0,0 +1,45 @@
+# Copyright(C) 2015 Masafumi Yokoyama <yokoyama@clear-code.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT,
+ score2 INT,
+ created_at DATETIME,
+ INDEX (created_at, score1, score2)
+) DEFAULT CHARSET=UTF8;
+SHOW CREATE TABLE items;
+
+INSERT INTO items (score1, score2, created_at) VALUES(1, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 00:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-01 12:00:00");
+INSERT INTO items (score1, score2, created_at) VALUES(2, 0, "2015-07-02 00:00:00");
+
+SELECT *
+ FROM items
+ WHERE created_at <= "2015-07-01 12:00:00"
+ ORDER BY created_at DESC;
+
+DROP TABLE items;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_recreate.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_recreate.test
index 430b3bb94a2..c674388e181 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_recreate.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_recreate.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_replace.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_replace.test
index 18db29cc85f..4bffa8c396a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_replace.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_replace.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_double.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_double.test
index 07ab3d38028..01139dc631d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_double.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_double.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_float.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_float.test
index 567d32e0ffd..902750ba265 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_float.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_float.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_int.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_int.test
index 0658bbcedf3..4172666fafd 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_int.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_int.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_max.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_max.test
new file mode 100644
index 00000000000..2077b914428
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_max.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS listing;
+--enable_warnings
+
+CREATE TABLE scores (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT NOT NULL,
+ score2 INT NOT NULL,
+ INDEX (score1, score2)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO scores (score1, score2) VALUES(1, 1);
+INSERT INTO scores (score1, score2) VALUES(1, 2);
+INSERT INTO scores (score1, score2) VALUES(2, 3);
+INSERT INTO scores (score1, score2) VALUES(2, 2);
+INSERT INTO scores (score1, score2) VALUES(2, 1);
+INSERT INTO scores (score1, score2) VALUES(2, 0);
+INSERT INTO scores (score1, score2) VALUES(2, -1);
+INSERT INTO scores (score1, score2) VALUES(2, -2);
+INSERT INTO scores (score1, score2) VALUES(2, -3);
+
+SELECT MAX(score2) FROM scores WHERE score1 = 2;
+
+DROP TABLE scores;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_min.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_min.test
new file mode 100644
index 00000000000..8541aaddae0
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_min.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS listing;
+--enable_warnings
+
+CREATE TABLE scores (
+ id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
+ score1 INT NOT NULL,
+ score2 INT NOT NULL,
+ INDEX (score1, score2)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO scores (score1, score2) VALUES(1, 1);
+INSERT INTO scores (score1, score2) VALUES(1, 2);
+INSERT INTO scores (score1, score2) VALUES(2, 3);
+INSERT INTO scores (score1, score2) VALUES(2, 2);
+INSERT INTO scores (score1, score2) VALUES(2, 1);
+INSERT INTO scores (score1, score2) VALUES(2, 0);
+INSERT INTO scores (score1, score2) VALUES(2, -1);
+INSERT INTO scores (score1, score2) VALUES(2, -2);
+INSERT INTO scores (score1, score2) VALUES(2, -3);
+
+SELECT MIN(score2) FROM scores WHERE score1 = 2;
+
+DROP TABLE scores;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_string.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_string.test
index a79567bde7f..936a57bc2d8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_string.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_string.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_varchar.test
index 7c9af9aa998..4778da9afa0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_varchar.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_select_varchar.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_32bit_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_32bit_equal.test
index 0c949ab25b1..bbb03e0229c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_32bit_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_32bit_equal.test
@@ -13,9 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_32bit.inc
+--source ../../include/mroonga/skip_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_64bit_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_64bit_equal.test
index c842ff428c3..1323b4ce4a8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_64bit_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_64bit_equal.test
@@ -14,12 +14,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/skip_freebsd.inc
---source ../../include/mroonga/skip_osx.inc
---source ../../include/mroonga/skip_solaris10.inc
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -33,13 +31,13 @@ CREATE TABLE ranges (
UNIQUE KEY range_key(start, end)
);
-INSERT INTO ranges VALUES (1, "1000-01-01", "2012-10-05");
-INSERT INTO ranges VALUES (2, "1000-01-01", "9999-12-31");
+INSERT INTO ranges VALUES (1, "1000-01-02", "2012-10-05");
+INSERT INTO ranges VALUES (2, "1000-01-02", "9999-12-31");
INSERT INTO ranges VALUES (3, "2012-10-25", "9999-12-31");
-INSERT INTO ranges VALUES (4, "9999-12-31", "1000-01-01");
+INSERT INTO ranges VALUES (4, "9999-12-31", "1000-01-02");
SELECT * FROM ranges FORCE INDEX(range_key)
- WHERE start = "1000-01-01" AND end = "9999-12-31";
+ WHERE start = "1000-01-02" AND end = "9999-12-31";
DROP TABLE ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_index_read.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_index_read.test
index 708ba0b44dc..666b9566efa 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_index_read.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_index_read.test
@@ -14,11 +14,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
--source ../../include/mroonga/skip_freebsd.inc
---source ../../include/mroonga/skip_osx.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -32,10 +31,10 @@ CREATE TABLE ranges (
UNIQUE KEY range_key(start, end)
);
-INSERT INTO ranges VALUES (1, "1000-01-01", "2012-10-05");
-INSERT INTO ranges VALUES (2, "1000-01-01", "9999-12-31");
+INSERT INTO ranges VALUES (1, "1000-01-02", "2012-10-05");
+INSERT INTO ranges VALUES (2, "1000-01-02", "9999-12-31");
INSERT INTO ranges VALUES (3, "2012-10-25", "9999-12-31");
-INSERT INTO ranges VALUES (4, "9999-12-31", "1000-01-01");
+INSERT INTO ranges VALUES (4, "9999-12-31", "1000-01-02");
SELECT start, end
FROM ranges FORCE INDEX(range_key)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_32bit_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_32bit_asc.test
index ce28c45aac6..071113a6ca1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_32bit_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_32bit_asc.test
@@ -13,9 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_32bit.inc
+--source ../../include/mroonga/skip_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_32bit_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_32bit_desc.test
index 9e68d627890..630ae74b25e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_32bit_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_32bit_desc.test
@@ -13,9 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_32bit.inc
+--source ../../include/mroonga/skip_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_64bit_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_64bit_asc.test
index 92bd9915a22..89108b7270d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_64bit_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_64bit_asc.test
@@ -14,12 +14,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/skip_freebsd.inc
---source ../../include/mroonga/skip_osx.inc
---source ../../include/mroonga/skip_solaris10.inc
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -34,9 +32,9 @@ CREATE TABLE ranges (
);
INSERT INTO ranges VALUES (1, "2012-10-25", "9999-12-31");
-INSERT INTO ranges VALUES (2, "1000-01-01", "2012-10-05");
-INSERT INTO ranges VALUES (3, "9999-12-31", "1000-01-01");
-INSERT INTO ranges VALUES (4, "1000-01-01", "9999-12-31");
+INSERT INTO ranges VALUES (2, "1000-01-02", "2012-10-05");
+INSERT INTO ranges VALUES (3, "9999-12-31", "1000-01-02");
+INSERT INTO ranges VALUES (4, "1000-01-02", "9999-12-31");
SELECT * FROM ranges FORCE INDEX(range_key)
ORDER BY start, end;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_64bit_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_64bit_desc.test
index a25cd4d87c3..3cb5bcae3bf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_64bit_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_order_64bit_desc.test
@@ -14,12 +14,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/skip_freebsd.inc
---source ../../include/mroonga/skip_osx.inc
---source ../../include/mroonga/skip_solaris10.inc
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -34,9 +32,9 @@ CREATE TABLE ranges (
);
INSERT INTO ranges VALUES (1, "2012-10-25", "9999-12-31");
-INSERT INTO ranges VALUES (2, "1000-01-01", "2012-10-05");
-INSERT INTO ranges VALUES (3, "9999-12-31", "1000-01-01");
-INSERT INTO ranges VALUES (4, "1000-01-01", "9999-12-31");
+INSERT INTO ranges VALUES (2, "1000-01-02", "2012-10-05");
+INSERT INTO ranges VALUES (3, "9999-12-31", "1000-01-02");
+INSERT INTO ranges VALUES (4, "1000-01-02", "9999-12-31");
SELECT * FROM ranges FORCE INDEX(range_key)
ORDER BY start DESC, end DESC;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_reinsert.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_reinsert.test
index 6a04c4a9df5..182f185a0d6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_reinsert.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_date_reinsert.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_index_read.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_index_read.test
index 0807e78c0aa..d33d2c1f84e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_index_read.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_index_read.test
@@ -14,12 +14,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
--source ../../include/mroonga/skip_freebsd.inc
---source ../../include/mroonga/skip_osx.inc
---source ../../include/mroonga/skip_solaris10.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -33,10 +31,10 @@ CREATE TABLE ranges (
UNIQUE KEY range_key(start, end)
);
-INSERT INTO ranges VALUES (1, "1000-01-01 00:00:00", "2012-10-05 16:18:29");
-INSERT INTO ranges VALUES (2, "1000-01-01 00:00:00", "9999-12-31 23:59:59");
+INSERT INTO ranges VALUES (1, "1000-01-02 00:00:00", "2012-10-05 16:18:29");
+INSERT INTO ranges VALUES (2, "1000-01-02 00:00:00", "9999-12-31 23:59:59");
INSERT INTO ranges VALUES (3, "2012-10-25 16:18:29", "9999-12-31 23:59:59");
-INSERT INTO ranges VALUES (4, "9999-12-31 23:59:59", "1000-01-01 00:00:00");
+INSERT INTO ranges VALUES (4, "9999-12-31 23:59:59", "1000-01-02 00:00:00");
SELECT start, end
FROM ranges FORCE INDEX(range_key)
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test
index 776e05a2ffe..8d4f348c4c3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,8 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source ../../include/mroonga/skip_strict_sql_mode.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_order_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_order_asc.test
index 3fcc92f7acf..b4b5f500c56 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_order_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_order_asc.test
@@ -14,12 +14,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/skip_freebsd.inc
---source ../../include/mroonga/skip_osx.inc
---source ../../include/mroonga/skip_solaris10.inc
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -34,9 +32,9 @@ CREATE TABLE ranges (
);
INSERT INTO ranges VALUES (1, "2012-10-25 16:18:29", "9999-12-31 23:59:59");
-INSERT INTO ranges VALUES (2, "1000-01-01 00:00:00", "2012-10-05 16:18:29");
-INSERT INTO ranges VALUES (3, "9999-12-31 23:59:59", "1000-01-01 00:00:00");
-INSERT INTO ranges VALUES (4, "1000-01-01 00:00:00", "9999-12-31 23:59:59");
+INSERT INTO ranges VALUES (2, "1000-01-02 00:00:00", "2012-10-05 16:18:29");
+INSERT INTO ranges VALUES (3, "9999-12-31 23:59:59", "1000-01-02 00:00:00");
+INSERT INTO ranges VALUES (4, "1000-01-02 00:00:00", "9999-12-31 23:59:59");
SELECT * FROM ranges FORCE INDEX(range_key)
ORDER BY start, end;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_order_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_order_desc.test
index 4d25f29cfdc..a2c4564253a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_order_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_order_desc.test
@@ -14,12 +14,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/skip_freebsd.inc
---source ../../include/mroonga/skip_osx.inc
---source ../../include/mroonga/skip_solaris10.inc
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -34,9 +32,9 @@ CREATE TABLE ranges (
);
INSERT INTO ranges VALUES (1, "2012-10-25 16:18:29", "9999-12-31 23:59:59");
-INSERT INTO ranges VALUES (2, "1000-01-01 00:00:00", "2012-10-05 16:18:29");
-INSERT INTO ranges VALUES (3, "9999-12-31 23:59:59", "1000-01-01 00:00:00");
-INSERT INTO ranges VALUES (4, "1000-01-01 00:00:00", "9999-12-31 23:59:59");
+INSERT INTO ranges VALUES (2, "1000-01-02 00:00:00", "2012-10-05 16:18:29");
+INSERT INTO ranges VALUES (3, "9999-12-31 23:59:59", "1000-01-02 00:00:00");
+INSERT INTO ranges VALUES (4, "1000-01-02 00:00:00", "9999-12-31 23:59:59");
SELECT * FROM ranges FORCE INDEX(range_key)
ORDER BY start DESC, end DESC;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_reinsert.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_reinsert.test
index eb6df3af8ad..bd360544ee1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_reinsert.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_reinsert.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_decimal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_decimal.test
index faf590d84b6..38265a6ed99 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_decimal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_decimal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_index_read.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_index_read.test
index 52e4113dc09..fa4780d541b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_index_read.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_index_read.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_order_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_order_asc.test
index a8e36f2ff26..af3394b1f61 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_order_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_order_asc.test
@@ -13,9 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_order_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_order_desc.test
index c13ed51cf7f..bc8a7e723a0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_order_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_order_desc.test
@@ -13,9 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_reinsert.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_reinsert.test
index 497010df032..63f708afbb2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_reinsert.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_time_reinsert.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_index_read.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_index_read.test
index 2ee8ae466ac..7e7357108a5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_index_read.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_index_read.test
@@ -1,5 +1,5 @@
# Copyright(C) 2012 Kentoku SHIBA
-# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -23,8 +23,8 @@ DROP TABLE IF EXISTS ranges;
CREATE TABLE ranges (
id int PRIMARY KEY,
- start timestamp,
- end timestamp,
+ start timestamp DEFAULT '2016-04-21 00:00:00',
+ end timestamp DEFAULT '2016-04-22 00:00:00',
UNIQUE KEY range_key(start, end)
);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_order_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_order_asc.test
index efb7ab70ae2..3f337d05523 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_order_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_order_asc.test
@@ -13,9 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -24,8 +24,8 @@ DROP TABLE IF EXISTS ranges;
CREATE TABLE ranges (
id int PRIMARY KEY,
- start timestamp,
- end timestamp,
+ start timestamp DEFAULT '2016-04-21 00:00:00',
+ end timestamp DEFAULT '2016-04-22 00:00:00',
UNIQUE KEY range_key(start, end)
);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_order_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_order_desc.test
index 1b1e62951e4..6dbc4938874 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_order_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_order_desc.test
@@ -1,5 +1,5 @@
# Copyright(C) 2012 Kentoku SHIBA
-# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,9 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -24,8 +24,8 @@ DROP TABLE IF EXISTS ranges;
CREATE TABLE ranges (
id int PRIMARY KEY,
- start timestamp,
- end timestamp,
+ start timestamp DEFAULT '2016-04-21 00:00:00',
+ end timestamp DEFAULT '2016-04-22 00:00:00',
UNIQUE KEY range_key(start, end)
);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_reinsert.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_reinsert.test
index 74bd0eb133a..7a1bd6bc74f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_reinsert.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_timestamp_reinsert.test
@@ -1,5 +1,5 @@
# Copyright(C) 2012 Kentoku SHIBA
-# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -23,8 +23,8 @@ DROP TABLE IF EXISTS ranges;
CREATE TABLE ranges (
id int PRIMARY KEY,
- start timestamp,
- end timestamp,
+ start timestamp DEFAULT '2016-04-21 00:00:00',
+ end timestamp DEFAULT '2016-04-22 00:00:00',
UNIQUE KEY range_key(start, end)
);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_varchar.test
index e116e7a251e..67ae21224d1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_varchar.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_varchar.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_32bit_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_32bit_equal.test
index 7a17092d599..ac77089ac73 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_32bit_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_32bit_equal.test
@@ -13,9 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_32bit.inc
+--source ../../include/mroonga/skip_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_64bit_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_64bit_equal.test
index 2505b47b1bc..21a3b936afe 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_64bit_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_64bit_equal.test
@@ -13,11 +13,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
---source ../../include/mroonga/skip_osx.inc
--disable_warnings
DROP TABLE IF EXISTS ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_index_read.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_index_read.test
index b475b857fd4..fa91ca3177d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_index_read.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_index_read.test
@@ -13,11 +13,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
---source ../../include/mroonga/skip_osx.inc
--disable_warnings
DROP TABLE IF EXISTS ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_32bit_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_32bit_asc.test
index 4317cc1e974..1db76c68e46 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_32bit_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_32bit_asc.test
@@ -13,9 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_32bit.inc
+--source ../../include/mroonga/skip_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_32bit_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_32bit_desc.test
index b7e910f0829..503322a5470 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_32bit_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_32bit_desc.test
@@ -13,9 +13,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_32bit.inc
+--source ../../include/mroonga/skip_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_64bit_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_64bit_asc.test
index 5a4525fe7a5..226a51b4333 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_64bit_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_64bit_asc.test
@@ -13,11 +13,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
---source ../../include/mroonga/skip_osx.inc
--disable_warnings
DROP TABLE IF EXISTS ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_64bit_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_64bit_desc.test
index 8865c3610ff..0f1830ff6d6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_64bit_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_order_64bit_desc.test
@@ -13,11 +13,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_64bit.inc
+--source ../../include/mroonga/have_signed_64bit_time_t.inc
--source ../../include/mroonga/have_mroonga.inc
---source ../../include/mroonga/skip_osx.inc
--disable_warnings
DROP TABLE IF EXISTS ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_reinsert.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_reinsert.test
index e7ac3a8a941..b80986c3938 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_reinsert.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_year_reinsert.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_update_int.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_update_int.test
index d1c23dfbc73..0d303496afb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_update_int.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_update_int.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_update_string.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_update_string.test
index 19fc2c36dfb..e250885d058 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_update_string.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_update_string.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_exact_length.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_exact_length.test
index 37cd919eb77..a954ffd4ee3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_exact_length.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_exact_length.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_null_character.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_null_character.test
index 9cdee6b1efb..19cedaffcd4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_null_character.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_null_character.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_short.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_short.test
index 1e1029d0d86..9228b1ffb91 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_short.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_char_short.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_date.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_date.test
index 9b94d315836..dc9db9652f6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_date.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_date.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -24,7 +24,6 @@ CREATE TABLE diaries (
day DATE PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (day, title) VALUES ("2012-01-29", "clear day");
INSERT INTO diaries (day, title) VALUES ("2012-01-30", "rainy day");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_datetime_with_fractional_seconds.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_datetime_with_fractional_seconds.test
index 44a9fcaca69..7ddd4861708 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_datetime_with_fractional_seconds.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_datetime_with_fractional_seconds.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_fractional_seconds.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -25,7 +25,6 @@ CREATE TABLE diaries (
day DATETIME(6) PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (day, title)
VALUES ("2012-01-29 21:51:01.111111", "clear day");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_datetime_without_fractional_seconds.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_datetime_without_fractional_seconds.test
index 82b6632672c..aba0d8755f0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_datetime_without_fractional_seconds.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_datetime_without_fractional_seconds.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -24,7 +24,6 @@ CREATE TABLE diaries (
day DATETIME PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (day, title)
VALUES ("2012-01-29 21:51:01", "clear day");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_decimal_with_fractional_seconds.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_decimal_with_fractional_seconds.test
index c9134275c45..4e2bd44d2d1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_decimal_with_fractional_seconds.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_decimal_with_fractional_seconds.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -24,7 +24,6 @@ CREATE TABLE releases (
version DECIMAL(6, 3) PRIMARY KEY,
message TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE releases;
INSERT INTO releases (version, message) VALUES (10.000, "10th release!");
INSERT INTO releases (version, message) VALUES (10.001, "minor fix.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_decimal_without_fractional_seconds.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_decimal_without_fractional_seconds.test
index f9cdd093ff4..a5073a6334a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_decimal_without_fractional_seconds.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_decimal_without_fractional_seconds.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -24,7 +24,6 @@ CREATE TABLE releases (
version DECIMAL PRIMARY KEY,
message TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE releases;
INSERT INTO releases (version, message) VALUES (1, "the first release!!!");
INSERT INTO releases (version, message) VALUES (10, "10th release!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_time_with_fractional_seconds.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_time_with_fractional_seconds.test
index 7b8f48e185a..bf61a4fbd0f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_time_with_fractional_seconds.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_time_with_fractional_seconds.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_fractional_seconds.inc
@@ -25,7 +25,6 @@ CREATE TABLE running_records (
time TIME(6) PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE running_records;
INSERT INTO running_records (time, title)
VALUES ("01:00:00.000001", "normal condition");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_time_without_fractional_seconds.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_time_without_fractional_seconds.test
index d71dd6485d2..6e5c369ffa0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_time_without_fractional_seconds.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_time_without_fractional_seconds.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -24,7 +24,6 @@ CREATE TABLE running_records (
time TIME PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE running_records;
INSERT INTO running_records (time, title)
VALUES ("01:00:00", "normal condition");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_timestamp_with_fractional_seconds.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_timestamp_with_fractional_seconds.test
index f59ee627301..1eb103b76c7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_timestamp_with_fractional_seconds.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_timestamp_with_fractional_seconds.test
@@ -12,9 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/skip_mariadb_55.inc
+--source ../../include/mroonga/skip_mariadb_5_5.inc
--source ../../include/mroonga/have_fractional_seconds.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
time TIMESTAMP(6) PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (time, title)
VALUES ("2012-01-29 21:51:01.111111", "clear day");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_timestamp_without_fractional_seconds.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_timestamp_without_fractional_seconds.test
index 7d8c1778331..341dfd21c09 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_timestamp_without_fractional_seconds.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_timestamp_without_fractional_seconds.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -24,7 +24,6 @@ CREATE TABLE diaries (
time TIMESTAMP PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (time, title) VALUES ("2012-01-29 21:51:01", "clear day");
INSERT INTO diaries (time, title) VALUES ("2012-01-30 01:23:45", "rainy day");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_varchar_null_character.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_varchar_null_character.test
index 9c8e4e46c28..a610944d835 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_varchar_null_character.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_varchar_null_character.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_year.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_year.test
index 6236b2d961d..a390eba41f7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_year.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_primary_year.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -24,7 +24,6 @@ CREATE TABLE aniversary_memos (
party_year YEAR PRIMARY KEY,
title TEXT
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE aniversary_memos;
INSERT INTO aniversary_memos (party_year, title)
VALUES ("11", "We need a big cake!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_asc.test
index 9358c7c0e47..97e8efc73cb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_asc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_desc.test
index 9fe76989745..a3e040b554b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_desc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_or_equal_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_or_equal_asc.test
index 24967c9d14b..454326ea212 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_or_equal_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_or_equal_asc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_or_equal_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_or_equal_desc.test
index 7f4bc666fe1..1a9a06f8b40 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_or_equal_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_greater_than_or_equal_desc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_asc.test
index 58604aa347d..d19cfcb2262 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_asc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_desc.test
index df89318fbe4..aa0761aa871 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_desc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_or_equal_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_or_equal_asc.test
index 97dc161f191..068f53fea69 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_or_equal_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_or_equal_asc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_or_equal_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_or_equal_desc.test
index 2e4451b9fb7..b9033323962 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_or_equal_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_normal_less_than_or_equal_desc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_asc.test
index 76729da279e..5b1e16538ad 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_asc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_desc.test
index 692953f9332..10446b115b5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_desc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_or_equal_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_or_equal_asc.test
index d5c73ac3d81..66d29dfb8f1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_or_equal_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_or_equal_asc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_or_equal_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_or_equal_desc.test
index b8d2dac9cac..7dcbb6e9023 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_or_equal_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_greater_than_or_equal_desc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_asc.test
index 8f262237cde..8537caed403 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_asc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_desc.test
index 994eff8b69a..d7d48ea72be 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_desc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_or_equal_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_or_equal_asc.test
index 9e58d3cd8e4..216c5f4ef99 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_or_equal_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_or_equal_asc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_or_equal_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_or_equal_desc.test
index 14c97749c37..90f241ad285 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_or_equal_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_range_primary_less_than_or_equal_desc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_bigint.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_bigint.test
index 318ccbfb820..58e58f4dbdd 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_bigint.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_bigint.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_bigint_unsigned.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_bigint_unsigned.test
index ef89fbdd128..2b81524aef2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_bigint_unsigned.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_bigint_unsigned.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_double.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_double.test
index e35baa13037..7ad385098ea 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_double.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_double.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_float.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_float.test
index aca93729e3b..0baa5d4b311 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_float.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_float.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_int.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_int.test
index f9563018bea..15e539b5524 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_int.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_int.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_int_unsigned.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_int_unsigned.test
index b95dca5fe07..a3e1d35647b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_int_unsigned.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_int_unsigned.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_mediumint.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_mediumint.test
index a817dfc285c..c63a8a867a8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_mediumint.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_mediumint.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_mediumint_unsigned.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_mediumint_unsigned.test
index f9f42e48ac5..81d6df92ffa 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_mediumint_unsigned.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_mediumint_unsigned.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_smallint.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_smallint.test
index 97762972912..c64bd185b21 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_smallint.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_smallint.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_smallint_unsigned.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_smallint_unsigned.test
index bba35ebbdeb..82ea8949d86 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_smallint_unsigned.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_smallint_unsigned.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_tinyint.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_tinyint.test
index 04344db0034..68557022856 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_tinyint.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_tinyint.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_tinyint_unsigned.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_tinyint_unsigned.test
index 27ef9af3a80..c513983d886 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_tinyint_unsigned.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_tinyint_unsigned.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_varchar.test
index 518eabe1cb0..51ed0a3bb8b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_varchar.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_varchar.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_varchar_collation.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_varchar_collation.test
index 08b9c5b5648..9d9d02c4b02 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_varchar_collation.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_multiple_varchar_collation.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_normal_int.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_normal_int.test
index 84f2adce7c8..04584d2f71f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_normal_int.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_normal_int.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_normal_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_normal_varchar.test
index 995dd9d77a6..7b8a6fecbab 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_normal_varchar.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_normal_varchar.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_primary_int.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_primary_int.test
index 106a5bdd9f2..c2307642392 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_primary_int.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_primary_int.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_primary_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_primary_varchar.test
index 4a0b2ff3492..c4004e4207a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_read_primary_varchar.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_read_primary_varchar.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_delete_all.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_delete_all.test
new file mode 100644
index 00000000000..f4d468b71b3
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_delete_all.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS ids;
+--enable_warnings
+
+CREATE TABLE ids (
+ id int,
+ UNIQUE KEY (id)
+);
+
+INSERT INTO ids VALUES (1);
+DELETE FROM ids;
+INSERT INTO ids VALUES (1);
+
+SELECT * FROM ids;
+
+-- error ER_DUP_ENTRY
+INSERT INTO ids VALUES (1);
+
+DROP TABLE ids;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_delete_by_primary_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_delete_by_primary_key.test
index 27c094acec9..3b3743b8b37 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_delete_by_primary_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_delete_by_primary_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_insert_after_error.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_insert_after_error.test
index 4acdfc0f1bf..70c6ec8576f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_insert_after_error.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_insert_after_error.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_search_after_duplicated.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_search_after_duplicated.test
index 7642ee733f3..27fb6eea834 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_search_after_duplicated.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_search_after_duplicated.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_varchar.test
index 8bcdb56ccfd..fe222c377ec 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_varchar.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_varchar.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_update_multiple_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_update_multiple_column.test
index fbf776d9e39..b1a37b5acc9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_update_multiple_column.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_update_multiple_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_update_single_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_update_single_column.test
index 557ce195ae3..3d47500544f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/index_update_single_column.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_update_single_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_plugins.test b/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_plugins.test
index 43988b71a9a..fb462fd7685 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_plugins.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_plugins.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_auto_increment_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_auto_increment_none.test
index f6d2d8fb5db..2dcf6716e2e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_auto_increment_none.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_auto_increment_none.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_auto_increment_use.test b/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_auto_increment_use.test
index 3135ad9fa34..f1aac9c1c33 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_auto_increment_use.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_auto_increment_use.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_data_length.test b/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_data_length.test
index 7b54e8d3ac5..445bcfabe39 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_data_length.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/information_schema_tables_data_length.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ CREATE TABLE diaries (
content TEXT,
FULLTEXT INDEX (content)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/insert_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/storage/t/insert_TODO_SPLIT_ME.test
index 6e3ce140eba..95c21513d57 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/insert_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/insert_TODO_SPLIT_ME.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -77,22 +77,6 @@ insert into t1 values("2010/03/26 11:22:33");
select * from t1;
drop table t1;
-
-# for virtual columns
-create table t1 (c1 int, _id int);
-set sql_mode="";
-# warning WARN_DATA_TRUNCATED
-insert into t1 (c1,_id) values (1,1);
-set sql_mode="strict_all_tables";
-# We can't use WARN_DATA_TRUNCATED here because "WXXX" isn't supported
-# MySQL 5.5, 5.6 and MariaDB 5.6. MariaDB 10.0 only supports it.
-# We share this test with all MySQL servers. So we use number here.
---error 1265
-insert into t1 (c1,_id) values (4,1);
-select * from t1;
-drop table t1;
-
-
# duplicated key error
create table t1 (c1 int primary key, c2 int);
insert into t1 values(1,100);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/insert_delayed.test b/storage/mroonga/mysql-test/mroonga/storage/t/insert_delayed.test
index d58d4326742..e52d11c5582 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/insert_delayed.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/insert_delayed.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2014-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,9 +12,12 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+skip "This test is too fragile.";
--source include/not_embedded.inc
+--source ../../include/mroonga/skip_mysql_5_7_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_no_primary_key_and_unique_key_twice.test b/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_no_primary_key_and_unique_key_twice.test
index a53e672cbe4..e6c0cae164f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_no_primary_key_and_unique_key_twice.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_no_primary_key_and_unique_key_twice.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_primary_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_primary_key.test
index c25e4606359..1b07775d681 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_primary_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_primary_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -24,7 +24,6 @@ CREATE TABLE diaries (
day DATE PRIMARY KEY,
title TEXT
) DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (day, title)
VALUES ("2012-02-14", "clear day")
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_unique_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_unique_key.test
index 5542b0ece3b..f5b6db7bab6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_unique_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_unique_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
title TEXT,
UNIQUE KEY day (day)
) DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (day, title)
VALUES ("2012-02-14", "clear day1")
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/insert_virtual_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/insert_virtual_column.test
new file mode 100644
index 00000000000..3f3fd208aef
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/insert_virtual_column.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2010 Tetsuro IKEDA
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (c1 int, _id int);
+--disable_warnings
+SET sql_mode="";
+--enable_warnings
+# warning WARN_DATA_TRUNCATED
+INSERT INTO t1 (c1,_id) VALUES (1,1);
+--disable_warnings
+SET sql_mode="STRICT_ALL_TABLES";
+--enable_warnings
+# We can't use WARN_DATA_TRUNCATED here because "WXXX" isn't supported
+# MySQL 5.5, 5.6 and MariaDB 5.6. MariaDB 10.0 only supports it.
+# We share this test with all MySQL servers. So we use number here.
+--error 1265
+INSERT INTO t1 (c1,_id) VALUES (4,1);
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/like_unicode_ci.test b/storage/mroonga/mysql-test/mroonga/storage/t/like_unicode_ci.test
index 48d50135b08..1f9c5fd3849 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/like_unicode_ci.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/like_unicode_ci.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/lock_tables_read.test b/storage/mroonga/mysql-test/mroonga/storage/t/lock_tables_read.test
index eeda3dac4a9..6c7627e7967 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/lock_tables_read.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/lock_tables_read.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_TODO_SPLIT_ME.test
deleted file mode 100644
index 2355e5d4af4..00000000000
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_TODO_SPLIT_ME.test
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright(C) 2010 Kentoku SHIBA
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library 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
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-
---source ../../include/mroonga/have_mroonga.inc
-
---disable_warnings
-drop table if exists t1, t2, t3;
---enable_warnings
-
-flush status;
-create table t1 (c1 int primary key, c2 int, c3 text, key idx1(c2), fulltext index ft(c3));
-insert into t1 values(1,10,"aa ii uu ee oo");
-insert into t1 values(2,20,"ka ki ku ke ko");
-insert into t1 values(3,30,"sa si su se so");
-insert into t1 values(4,40,"ta ti tu te to");
-insert into t1 values(5,50,"aa ii uu ee oo");
-show status like 'mroonga_count_skip';
-select * from t1;
-show status like 'mroonga_count_skip';
-select count(*) from t1;
-show status like 'mroonga_count_skip';
-select * from t1 force index(primary) where c1 between 2 and 4;
-show status like 'mroonga_count_skip';
-select count(*) from t1 force index(primary) where c1 between 2 and 4;
-show status like 'mroonga_count_skip';
-select c1 from t1 force index(primary) where c1 < 3;
-show status like 'mroonga_count_skip';
-select count(c1) from t1 force index(primary) where c1 < 3;
-show status like 'mroonga_count_skip';
-select 1 from t1 force index(primary) where c1 > 3;
-show status like 'mroonga_count_skip';
-select count(1) from t1 force index(primary) where c1 > 3;
-show status like 'mroonga_count_skip';
-select * from t1 where match(c3) against("su");
-show status like 'mroonga_count_skip';
-select count(*) from t1 where match(c3) against("su");
-show status like 'mroonga_count_skip';
-select * from t1 where match(c3) against("+su" in boolean mode);
-show status like 'mroonga_count_skip';
-select count(*) from t1 where match(c3) against("+su" in boolean mode);
-show status like 'mroonga_count_skip';
-select * from t1 force index(idx1) where c2 between 20 and 40;
-show status like 'mroonga_count_skip';
-select count(*) from t1 force index(idx1) where c2 between 20 and 40;
-show status like 'mroonga_count_skip';
-drop table t1;
-
---source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_after_insert_multithread.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_after_insert_multithread.test
index 6d07ab7b606..69713752f4f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_after_insert_multithread.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_after_insert_multithread.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,11 +30,17 @@ CREATE TABLE diaries (
INSERT INTO diaries VALUES("Hello mroonga!");
INSERT INTO diaries VALUES("It's funny.");
+disable_query_log;
CONNECT (thread2, localhost, root, ,);
CONNECTION thread2;
+enable_query_log;
+
INSERT INTO diaries VALUES("Happy birthday!");
+
+disable_query_log;
DISCONNECT thread2;
CONNECTION default;
+enable_query_log;
SHOW STATUS LIKE 'mroonga_count_skip';
SELECT COUNT(*) FROM diaries WHERE MATCH(title) AGAINST("mroonga" IN BOOLEAN MODE);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_after_insert_single_thread.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_after_insert_single_thread.test
index 26930d47502..07bbc773973 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_after_insert_single_thread.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_after_insert_single_thread.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_disabled.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_disabled.test
index fedf31810c7..2014a8fa476 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_disabled.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_disabled.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -29,7 +29,6 @@ CREATE TABLE diaries (
content TEXT,
FULLTEXT INDEX(content)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_and.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_and.test
new file mode 100644
index 00000000000..3c63ecc9c12
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_and.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ id INT,
+ age INT,
+ INDEX (id, age)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (id, age) VALUES (1, 28);
+INSERT INTO users (id, age) VALUES (1, 28);
+INSERT INTO users (id, age) VALUES (1, 29);
+INSERT INTO users (id, age) VALUES (2, 29);
+INSERT INTO users (id, age) VALUES (2, 29);
+INSERT INTO users (id, age) VALUES (3, 29);
+
+SELECT COUNT(*) FROM users WHERE id = 2 AND age = 29;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_between.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_between.test
new file mode 100644
index 00000000000..cccb0d3f48f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_between.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ age INT,
+ INDEX (age)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (age) VALUES (27);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (30);
+INSERT INTO users (age) VALUES (31);
+
+SELECT COUNT(*) FROM users WHERE age BETWEEN 28 AND 30;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_equal.test
new file mode 100644
index 00000000000..f8ebad5d7bb
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_equal.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ age INT,
+ INDEX (age)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (29);
+
+SELECT COUNT(*) FROM users WHERE age = 29;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_full_text_search_in_boolean_mode.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_full_text_search_in_boolean_mode.test
new file mode 100644
index 00000000000..9e3c6fd8a32
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_full_text_search_in_boolean_mode.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE memos (
+ content TEXT,
+ FULLTEXT INDEX (content)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO memos (content) VALUES ('Groonga is good.');
+INSERT INTO memos (content) VALUES ('Groonga is very good.');
+INSERT INTO memos (content) VALUES ('Mroonga is good.');
+INSERT INTO memos (content) VALUES ('Mroonga is very good.');
+INSERT INTO memos (content) VALUES ('Mroonga uses Groonga.');
+
+SELECT COUNT(*) FROM memos
+ WHERE MATCH(content) AGAINST('+Groonga' IN BOOLEAN MODE);
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_full_text_search_in_natural_language_mode.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_full_text_search_in_natural_language_mode.test
new file mode 100644
index 00000000000..634428c5c95
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_full_text_search_in_natural_language_mode.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE memos (
+ content TEXT,
+ FULLTEXT INDEX (content)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO memos (content) VALUES ('Groonga is good.');
+INSERT INTO memos (content) VALUES ('Groonga is very good.');
+INSERT INTO memos (content) VALUES ('Mroonga is good.');
+INSERT INTO memos (content) VALUES ('Mroonga is very good.');
+INSERT INTO memos (content) VALUES ('Mroonga uses Groonga.');
+
+SELECT COUNT(*) FROM memos
+ WHERE MATCH(content) AGAINST('Groonga');
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_greater.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_greater.test
new file mode 100644
index 00000000000..0feababfbf2
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_greater.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ age INT,
+ INDEX (age)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (age) VALUES (27);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (30);
+INSERT INTO users (age) VALUES (31);
+
+SELECT COUNT(*) FROM users WHERE age > 29;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_greater_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_greater_equal.test
new file mode 100644
index 00000000000..5e69f1684ec
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_greater_equal.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ age INT,
+ INDEX (age)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (age) VALUES (27);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (30);
+INSERT INTO users (age) VALUES (31);
+
+SELECT COUNT(*) FROM users WHERE age >= 29;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_less.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_less.test
new file mode 100644
index 00000000000..8aa1ba17621
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_less.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ age INT,
+ INDEX (age)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (age) VALUES (27);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (30);
+INSERT INTO users (age) VALUES (31);
+
+SELECT COUNT(*) FROM users WHERE age < 29;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_less_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_less_equal.test
new file mode 100644
index 00000000000..a6e0f3a51ed
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_less_equal.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ age INT,
+ INDEX (age)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (age) VALUES (27);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (30);
+INSERT INTO users (age) VALUES (31);
+
+SELECT COUNT(*) FROM users WHERE age <= 29;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_not_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_not_equal.test
new file mode 100644
index 00000000000..f07d1b9beae
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_not_equal.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ age INT,
+ INDEX (age)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (28);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (29);
+INSERT INTO users (age) VALUES (29);
+
+SELECT COUNT(*) FROM users WHERE age <> 29;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_view.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_view.test
index 378f4424da1..cc3de7c3ce6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_view.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_view.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_multiple_conditions.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_multiple_conditions.test
new file mode 100644
index 00000000000..1f49597bb27
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_multiple_conditions.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ id INT,
+ age INT,
+ INDEX (age)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (id, age) VALUES (1, 29);
+INSERT INTO users (id, age) VALUES (2, 29);
+INSERT INTO users (id, age) VALUES (3, 29);
+
+SELECT COUNT(*) FROM users WHERE id = 3 AND age = 29;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_between.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_between.test
new file mode 100644
index 00000000000..1c9e7354c35
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_between.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+
+SELECT COUNT(*) FROM users WHERE id BETWEEN 2 AND 4;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_equal.test
new file mode 100644
index 00000000000..23fb2152f94
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_equal.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+
+SELECT COUNT(*) FROM users WHERE id = 3;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_greater.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_greater.test
new file mode 100644
index 00000000000..9020dd11efa
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_greater.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+
+SELECT COUNT(*) FROM users WHERE id > 3;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_greater_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_greater_equal.test
new file mode 100644
index 00000000000..f4c1e0687c5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_greater_equal.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+
+SELECT COUNT(*) FROM users WHERE id >= 3;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_less.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_less.test
new file mode 100644
index 00000000000..bcf5afa52de
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_less.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+
+SELECT COUNT(*) FROM users WHERE id < 3;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_less_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_less_equal.test
new file mode 100644
index 00000000000..ddfad77ceff
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_less_equal.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+
+SELECT COUNT(*) FROM users WHERE id <= 3;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_not_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_not_equal.test
new file mode 100644
index 00000000000..c49385ed849
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_primary_key_not_equal.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+FLUSH STATUS;
+
+CREATE TABLE users (
+ id INT PRIMARY KEY
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO users (id) VALUES (1);
+INSERT INTO users (id) VALUES (2);
+INSERT INTO users (id) VALUES (3);
+INSERT INTO users (id) VALUES (4);
+INSERT INTO users (id) VALUES (5);
+
+SELECT COUNT(*) FROM users WHERE id <> 3;
+
+SHOW STATUS LIKE 'mroonga_count_skip';
+
+DROP TABLE users;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_disabled.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_disabled.test
index 20b89f72463..e65e44d1f60 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_disabled.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_disabled.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_multiple_match_againsts.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_multiple_match_againsts.test
new file mode 100644
index 00000000000..14f548db124
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_multiple_match_againsts.test
@@ -0,0 +1,57 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+FLUSH STATUS;
+
+SET NAMES UTF8;
+CREATE TABLE memos (
+ id INT UNSIGNED NOT NULL,
+ title VARCHAR(255),
+ content TEXT,
+ FULLTEXT INDEX(title),
+ FULLTEXT INDEX(content)
+) DEFAULT CHARSET UTF8;
+
+INSERT INTO memos VALUES(5, "title 1", "content a");
+INSERT INTO memos VALUES(12, "title 1", "content a");
+INSERT INTO memos VALUES(10, "title 1", "content a");
+INSERT INTO memos VALUES(4, "title 2", "content b");
+INSERT INTO memos VALUES(6, "title 2", "content b");
+INSERT INTO memos VALUES(1, "title 2", "content b");
+INSERT INTO memos VALUES(11, "title 1-a", "content a-1");
+INSERT INTO memos VALUES(3, "title 2-b", "content a-2");
+INSERT INTO memos VALUES(2, "title 2-c", "content a-3");
+INSERT INTO memos VALUES(8, "title 1-a", "content b-1");
+INSERT INTO memos VALUES(9, "title 2-b", "content b-2");
+INSERT INTO memos VALUES(7, "title 2-c", "content b-3");
+
+SELECT * FROM memos
+ WHERE MATCH(title) AGAINST("+1" IN BOOLEAN MODE) AND
+ MATCH(content) AGAINST("+a" IN BOOLEAN MODE)
+ ORDER BY id
+ LIMIT 1,3;
+
+SHOW STATUS LIKE 'mroonga_fast_order_limit';
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_no_limit.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_no_limit.test
index b1246ddfbdc..eb9e7ef55bc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_no_limit.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_not_optimized_no_limit.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_cp932.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_cp932.test
new file mode 100644
index 00000000000..c14ee787f1a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_cp932.test
@@ -0,0 +1,46 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+FLUSH STATUS;
+
+SET NAMES CP932;
+CREATE TABLE memos (
+ Ž¯•ÊŽq INT UNSIGNED,
+ “à—e TEXT,
+ FULLTEXT INDEX(“à—e),
+ KEY(Ž¯•ÊŽq)
+) DEFAULT CHARSET CP932;
+
+INSERT INTO memos VALUES(2, "–¾“ú‚ÍŽR“o‚èB");
+INSERT INTO memos VALUES(3, "¡“ú‚̓Tƒ{ƒeƒ“‚ð‚à‚ç‚Á‚½B");
+INSERT INTO memos VALUES(1, "¡“ú‚Í“V‹C‚ª‚æ‚­‚Ä‚æ‚©‚Á‚½B");
+
+SELECT * FROM memos
+ WHERE MATCH(“à—e) AGAINST("¡“ú" IN BOOLEAN MODE)
+ ORDER BY Ž¯•ÊŽq
+ LIMIT 1;
+
+SHOW STATUS LIKE 'mroonga_fast_order_limit';
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_between.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_between.test
index 41d5facf644..04cd30ab337 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_between.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_between.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_between_over.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_between_over.test
index f6440777ab5..cdc7b433532 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_between_over.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_between_over.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_equal.test
index 5b57d2980c6..c7a5244042c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:34", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:34", "Tomorrow will be fine.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_greater_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_greater_than.test
index 4f878af84cc..0f87b70186c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_greater_than.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_greater_than.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_greater_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_greater_than_or_equal.test
index e8735fda41c..922e72e2bbb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_greater_than_or_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_greater_than_or_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_less_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_less_than.test
index 4a748bc130b..78f8f19a14d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_less_than.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_less_than.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_less_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_less_than_or_equal.test
index 80fe51e1e80..2b12fa6ccc1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_less_than_or_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_datetime_less_than_or_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(date)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "2011-11-11 12:23:30", "Today is fine.");
INSERT INTO diaries VALUES(2, "2011-11-11 12:23:31", "Today's lucky item is flower!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_duplicated_order_by_columns.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_duplicated_order_by_columns.test
index b36a13f3727..1908ce34d8a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_duplicated_order_by_columns.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_duplicated_order_by_columns.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_enum_name.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_enum_name.test
new file mode 100644
index 00000000000..834a39fe75c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_enum_name.test
@@ -0,0 +1,49 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+FLUSH STATUS;
+
+SET NAMES utf8;
+CREATE TABLE memos (
+ id int PRIMARY KEY,
+ tag ENUM('Groonga', 'Mroonga'),
+ content TEXT,
+ FULLTEXT INDEX(content),
+ KEY(tag),
+ KEY(id)
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO memos VALUES(1, 'Groonga', 'Groonga is great!');
+INSERT INTO memos VALUES(2, 'Mroonga', 'Mroonga is great!');
+INSERT INTO memos VALUES(3, 'Mroonga', 'Mroonga is a MySQL storage engine.');
+INSERT INTO memos VALUES(4, 'Mroonga', 'Mroonga is based on Groonga.');
+
+SELECT * FROM memos
+ WHERE MATCH(content) AGAINST("+Groonga" IN BOOLEAN MODE) AND
+ tag = 'Mroonga'
+ ORDER BY id LIMIT 1;
+
+SHOW STATUS LIKE 'mroonga_fast_order_limit';
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_enum_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_enum_value.test
new file mode 100644
index 00000000000..703d79dc8e1
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_enum_value.test
@@ -0,0 +1,49 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+FLUSH STATUS;
+
+SET NAMES utf8;
+CREATE TABLE memos (
+ id int PRIMARY KEY,
+ tag ENUM('Groonga', 'Mroonga'),
+ content TEXT,
+ FULLTEXT INDEX(content),
+ KEY(tag),
+ KEY(id)
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO memos VALUES(1, 'Groonga', 'Groonga is great!');
+INSERT INTO memos VALUES(2, 'Mroonga', 'Mroonga is great!');
+INSERT INTO memos VALUES(3, 'Mroonga', 'Mroonga is a MySQL storage engine.');
+INSERT INTO memos VALUES(4, 'Mroonga', 'Mroonga is based on Groonga.');
+
+SELECT * FROM memos
+ WHERE MATCH(content) AGAINST("+Groonga" IN BOOLEAN MODE) AND
+ tag = 2
+ ORDER BY id LIMIT 1;
+
+SHOW STATUS LIKE 'mroonga_fast_order_limit';
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_have_primary_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_have_primary_key.test
index bcc678360e2..9c44110bfd5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_have_primary_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_have_primary_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -33,7 +33,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_between.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_between.test
index e0a2df2e587..32345f66139 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_between.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_between.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_between_over.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_between_over.test
index c8f698cdbcc..508f85f3a73 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_between_over.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_between_over.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_equal.test
index ee510ab7527..a2024e8dda5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_greater_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_greater_than.test
index 76f2de8146b..4924cb374e9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_greater_than.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_greater_than.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_greater_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_greater_than_or_equal.test
index caca6b56b89..b81247ed2f9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_greater_than_or_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_greater_than_or_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_less_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_less_than.test
index 1c26bef936f..d32d9f1128c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_less_than.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_less_than.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_less_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_less_than_or_equal.test
index 4df32d8a590..9289bee3068 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_less_than_or_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_int_less_than_or_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_no_primary_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_no_primary_key.test
index 07907f1dfb7..23adb84f91c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_no_primary_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_no_primary_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -33,7 +33,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_no_where_clause.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_no_where_clause.test
index 0e0b3f8e1ea..1031427f9ce 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_no_where_clause.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_no_where_clause.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_asc.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_asc.test
index 213605adca1..78b42e5d8d7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_asc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_asc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_desc.test
index 58505edf7a7..f09a2a0e3b4 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_desc.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_desc.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_id.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_id.test
index 92178a45158..9a758560913 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_id.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_id.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -35,7 +35,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(NULL, 1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(NULL, 2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_match_against.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_match_against.test
index 4ec5a8b1596..e49a79a7db2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_match_against.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_order_by_match_against.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_select_match_against.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_select_match_against.test
index eaedbbdc7dc..b563028c81d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_select_match_against.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_select_match_against.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_between.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_between.test
index 72d2890a123..c11603c94f8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_between.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_between.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE memos (
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_between_over.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_between_over.test
index eeb2e36ae29..71f93c6ee1b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_between_over.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_between_over.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE memos (
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_equal.test
index 666887d3347..883f676e45e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE memos (
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
INSERT INTO memos VALUES(1, "1:23:34", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:34", "Tomorrow will be fine.");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_greater_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_greater_than.test
index feeae64b8d1..a8af0bbb781 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_greater_than.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_greater_than.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE memos (
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!" );
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_greater_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_greater_than_or_equal.test
index 4744add7881..a0795f8eba6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_greater_than_or_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_greater_than_or_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE memos (
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!" );
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_less_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_less_than.test
index cb407d35450..4087207c2a8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_less_than.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_less_than.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE memos (
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_less_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_less_than_or_equal.test
index b9327e4251d..e423a4b937b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_less_than_or_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_time_less_than_or_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ CREATE TABLE memos (
FULLTEXT INDEX(content),
KEY(writing_time)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE memos;
INSERT INTO memos VALUES(1, "1:23:30", "Today is fine.");
INSERT INTO memos VALUES(2, "1:23:31", "Today's lucky item is flower!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_varchar_equal_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_varchar_equal_with_index.test
index 7c460d1086a..60565dd7bab 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_varchar_equal_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_varchar_equal_with_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -35,7 +35,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_varchar_equal_without_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_varchar_equal_without_index.test
index ffebd0a4bad..dcde9373317 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_varchar_equal_without_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_varchar_equal_without_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -34,7 +34,6 @@ CREATE TABLE diaries (
KEY(month),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_between.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_between.test
index c4e86ac1039..4e7c117d654 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_between.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_between.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_between_over.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_between_over.test
index 57b512ed88d..d6e7b345c05 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_between_over.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_between_over.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_equal.test
index 729d8b03770..bac10448269 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_greater_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_greater_than.test
index 6bd955cc956..9ffae4a6528 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_greater_than.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_greater_than.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_greater_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_greater_than_or_equal.test
index 3e40e885859..09015f9c2c3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_greater_than_or_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_greater_than_or_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_less_than.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_less_than.test
index 44fb928774f..35adc29839f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_less_than.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_less_than.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_less_than_or_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_less_than_or_equal.test
index f7d0865f303..831ef4c3e6a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_less_than_or_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_order_limit_optimized_year_less_than_or_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/partition_insert.test b/storage/mroonga/mysql-test/mroonga/storage/t/partition_insert.test
index 25270f14def..4e59a2ca3ab 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/partition_insert.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/partition_insert.test
@@ -12,9 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/skip_mariadb_100_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_0_or_later.inc
+--source ../../include/mroonga/skip_mysql_5_7_or_later.inc
--source include/have_partition.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/partition_update.test b/storage/mroonga/mysql-test/mroonga/storage/t/partition_update.test
index d601b4d4fe9..eaf3304dac5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/partition_update.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/partition_update.test
@@ -12,9 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/skip_mariadb_100_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_0_or_later.inc
+--source ../../include/mroonga/skip_mysql_5_7_or_later.inc
--source include/have_partition.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/repair_table_no_index_file.test b/storage/mroonga/mysql-test/mroonga/storage/t/repair_table_no_index_file.test
index 65989b60e8a..22fade591b6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/repair_table_no_index_file.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/repair_table_no_index_file.test
@@ -12,9 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
+--source ../../include/mroonga/skip_solaris.inc
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_mroonga_helper.inc
@@ -27,7 +28,6 @@ CREATE TABLE diaries (
body TEXT,
FULLTEXT INDEX body_index (body)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) VALUES ("survey", "will start Groonga!");
INSERT INTO diaries (title, body) VALUES ("Groonga (1)", "starting Groonga...");
@@ -35,11 +35,11 @@ INSERT INTO diaries (title, body) VALUES ("Groonga (2)", "started Groonga.");
SELECT * FROM diaries WHERE MATCH(body) AGAINST("+starting" IN BOOLEAN MODE);
---remove_file $MYSQLD_DATADIR/repair_test.mrn.000010A.c
+--remove_file $MYSQLD_DATADIR/repair_test.mrn.000010E.c
FLUSH TABLES;
-# Error ER_CANT_OPEN_FILE syscall error 'repair_test.mrn.000010A.c' (No such file or directory)
+# Error ER_CANT_OPEN_FILE system call error: No such file or directory: failed to open path: <repair_test.mrn.000010E.c>
--error ER_CANT_OPEN_FILE
SELECT * FROM diaries WHERE MATCH(body) AGAINST("+starting" IN BOOLEAN MODE);
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_geometry.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_geometry.test
index 81dcbe318b3..e9ba60c2c28 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/replace_geometry.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_geometry.test
@@ -12,10 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_geometry.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test
index 0f8e90c0c03..3ff23185741 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# Based on #910.
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_text.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_text.test
index bb134cd04e4..4aba5eda256 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/replace_text.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_text.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ create table diaries (
content text,
fulltext index (content)
) default charset utf8;
-show create table diaries;
insert into diaries values(1, "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_varchar.test
index 231e8b09762..da3faa03053 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/replace_varchar.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_varchar.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ create table diaries (
content varchar(256),
fulltext index (content)
) default charset utf8;
-show create table diaries;
insert into diaries values(1, "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_vector.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_vector.test
index 2e06bf7e5f8..22cbf13889b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/replace_vector.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_vector.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test
index fb8a6750fb9..db5b90ab0b1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/select_all.test b/storage/mroonga/mysql-test/mroonga/storage/t/select_all.test
index c3973cb9164..b607c314a84 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/select_all.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/select_all.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/select_empty_key_where_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/select_empty_key_where_equal.test
index c624f8e0c36..52630fec0f0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/select_empty_key_where_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/select_empty_key_where_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/select_empty_key_where_not_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/select_empty_key_where_not_equal.test
index 59c358cc1b8..75d00e7a737 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/select_empty_key_where_not_equal.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/select_empty_key_where_not_equal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/select_group_by_with_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/select_group_by_with_index.test
index 4424cf283da..ad71ac7119b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/select_group_by_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/select_group_by_with_index.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -31,7 +31,7 @@ INSERT INTO users VALUES ("Alice", 20);
INSERT INTO users VALUES ("Bob", 20);
INSERT INTO users VALUES ("Charry", 29);
-SELECT *, COUNT(*) FROM users GROUP BY age;
+SELECT age, COUNT(*) FROM users GROUP BY age;
DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/select_group_by_without_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/select_group_by_without_index.test
index 46c0e5aa70e..710bea0dd5a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/select_group_by_without_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/select_group_by_without_index.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -30,9 +30,7 @@ INSERT INTO users VALUES ("Alice", 20);
INSERT INTO users VALUES ("Bob", 20);
INSERT INTO users VALUES ("Charry", 29);
-EXPLAIN SELECT *, COUNT(*) FROM users GROUP BY age;
-
-SELECT *, COUNT(*) FROM users GROUP BY age;
+SELECT age, COUNT(*) FROM users GROUP BY age;
DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/select_pkey.test b/storage/mroonga/mysql-test/mroonga/storage/t/select_pkey.test
index a0afe1198ef..0bce1387b3f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/select_pkey.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/select_pkey.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/select_secondary_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/select_secondary_key.test
index 231e7c27037..32bb5758a10 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/select_secondary_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/select_secondary_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/show_create_table_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/storage/t/show_create_table_TODO_SPLIT_ME.test
index 3f00049092c..95007d8032f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/show_create_table_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/show_create_table_TODO_SPLIT_ME.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/sub_query_fulltext.test b/storage/mroonga/mysql-test/mroonga/storage/t/sub_query_fulltext.test
index c2df2522b9c..a7460343c26 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/sub_query_fulltext.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/sub_query_fulltext.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -31,7 +31,6 @@ CREATE TABLE diaries (
title TEXT,
FULLTEXT INDEX (title)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO users (name) VALUES ("alice");
INSERT INTO users (name) VALUES ("bob");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/temporary_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/temporary_table.test
index e71a2322bb2..ef26b467dbc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/temporary_table.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/temporary_table.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/skip_osx.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ CREATE TEMPORARY TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT
) DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title) VALUES ("clear day");
INSERT INTO diaries (title) VALUES ("rainy day");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test b/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test
index 7e5bc2d010c..840ff375489 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -31,7 +31,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(day)
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/update_binlog_row.test b/storage/mroonga/mysql-test/mroonga/storage/t/update_binlog_row.test
new file mode 100644
index 00000000000..c90a8cbf1cb
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/update_binlog_row.test
@@ -0,0 +1,38 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+SET SESSION binlog_format = 'ROW';
+
+CREATE TABLE memos (
+ title varchar(20) PRIMARY KEY,
+ content varchar(140) NOT NULL
+) COLLATE=utf8mb4_general_ci
+ DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO memos (title, content) VALUES ('Mroonga', 'Mroonga is great!');
+SELECT * FROM memos;
+UPDATE memos SET content = 'Mroonga is very great!' WHERE title = 'Mroonga';
+SELECT * FROM memos;
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/update_fulltext.test b/storage/mroonga/mysql-test/mroonga/storage/t/update_fulltext.test
index 33ccec42989..dbcfd665464 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/update_fulltext.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/update_fulltext.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/update_id_hash_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/update_id_hash_index.test
index 5b5a47ad447..526d6f18c20 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/update_id_hash_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/update_id_hash_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/update_id_unique_hash_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/update_id_unique_hash_index.test
index f1c91bfd8d3..0f9ecdbf337 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/update_id_unique_hash_index.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/update_id_unique_hash_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/update_int.test b/storage/mroonga/mysql-test/mroonga/storage/t/update_int.test
index 7f40ba09b2e..eb4af2c117e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/update_int.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/update_int.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/update_last_insert_grn_id.test b/storage/mroonga/mysql-test/mroonga/storage/t/update_last_insert_grn_id.test
index 65f0ce3b253..872f1673569 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/update_last_insert_grn_id.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/update_last_insert_grn_id.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/update_virtual_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/update_virtual_column.test
index a50bfd6929e..e0cb953d51d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/update_virtual_column.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/update_virtual_column.test
@@ -12,32 +12,38 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
-drop table if exists t1, t2, t3;
+DROP TABLE IF EXISTS t1;
--enable_warnings
# for virtual columns
-create table t1 (c1 int, _id int);
-insert into t1 values(1,null);
-insert into t1 values(2,null);
-insert into t1 values(3,null);
-select * from t1;
-set sql_mode="";
+CREATE TABLE t1 (c1 int, _id int);
+INSERT INTO t1 VALUES(1,null);
+INSERT INTO t1 VALUES(2,null);
+INSERT INTO t1 VALUES(3,null);
+SELECT * FROM t1;
+--disable_warnings
+SET sql_mode="";
+--enable_warnings
# warning WARN_DATA_TRUNCATED
-update t1 set _id = 10 where c1 = 1;
-select * from t1;
-set sql_mode="strict_all_tables";
+UPDATE t1 SET _id = 10 WHERE c1 = 1;
+SELECT * FROM t1;
+--disable_warnings
+SET sql_mode="STRICT_ALL_TABLES";
+--enable_warnings
# We can't use WARN_DATA_TRUNCATED here because "WXXX" isn't supported
# MySQL 5.5, 5.6 and MariaDB 5.6. MariaDB 10.0 only supports it.
# We share this test with all MySQL servers. So we use number here.
--error 1265
-update t1 set _id = 11 where c1 = 1;
-select * from t1;
-drop table t1;
+UPDATE t1 SET _id = 11 WHERE c1 = 1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+SET sql_mode=DEFAULT;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_column.test
index 2cba585bc2a..83dc25e4989 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_column.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# TODO: Remove the check after MariaDB 5.5.42 and MariaDB 10.0.17 are released.
--source ../../include/mroonga/have_mysql.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_leading_not.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_leading_not.test
index bdd4f915bbf..21879480c7d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_leading_not.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_leading_not.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# TODO: Remove the check after MariaDB 5.5.42 and MariaDB 10.0.17 are released.
--source ../../include/mroonga/have_mysql.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_update.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_update.test
index c7f54925382..77c4c1db2b1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_update.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_update.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# TODO: Remove the check after MariaDB 5.5.42 and MariaDB 10.0.17 are released.
--source ../../include/mroonga/have_mysql.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_query.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_query.test
index b3265d9645b..b312b31ad39 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_query.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_query.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# TODO: Remove the check after MariaDB 5.5.42 and MariaDB 10.0.17 are released.
--source ../../include/mroonga/have_mysql.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_script.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_script.test
index 61613ef2906..6509eeee2bf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_script.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_script.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# TODO: Remove the check after MariaDB 5.5.42 and MariaDB 10.0.17 are released.
--source ../../include/mroonga/have_mysql.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_database_path_prefix.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_database_path_prefix.test
index ad934696171..b7a4b80b6f1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_database_path_prefix.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_database_path_prefix.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_parser_new_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_parser_new_value.test
index e71dcfe0dda..83138aee0ec 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_parser_new_value.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_parser_new_value.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_parser_same_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_parser_same_value.test
index 4cfbe489b90..41aac1a146f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_parser_same_value.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_parser_same_value.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_tokenizer_new_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_tokenizer_new_value.test
new file mode 100644
index 00000000000..4c518b28e9f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_tokenizer_new_value.test
@@ -0,0 +1,25 @@
+# Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2014 Kentoku SHIBA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+SET @mroonga_default_tokenizer_backup = @@mroonga_default_tokenizer;
+SET GLOBAL mroonga_default_tokenizer = "TokenBigramSplitAlpha";
+SHOW GLOBAL VARIABLES LIKE 'mroonga_default_tokenizer';
+SET GLOBAL mroonga_default_tokenizer = @mroonga_default_tokenizer_backup;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_tokenizer_same_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_tokenizer_same_value.test
new file mode 100644
index 00000000000..ebd08460b3c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_default_tokenizer_same_value.test
@@ -0,0 +1,22 @@
+# Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+SET GLOBAL mroonga_default_tokenizer = "TokenBigram";
+SHOW GLOBAL VARIABLES LIKE 'mroonga_default_tokenizer';
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_delete.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_delete.test
index de97096e5a4..767ce3f9286 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_delete.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_delete.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -25,7 +25,6 @@ create table diaries (
body text,
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
insert into diaries (body) values ("will start groonga!");
select * from diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_insert.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_insert.test
index b52385793d2..4ad242dd59d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_insert.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_insert.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -25,7 +25,6 @@ create table diaries (
body text,
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
insert into diaries (body) values ("will start groonga!");
select * from diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_update.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_update.test
index 47c24421586..66f82a5c052 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_update.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_dry_write_update.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -25,7 +25,6 @@ create table diaries (
body text,
fulltext index body_index (body)
) default charset utf8;
-show create table diaries;
insert into diaries (body) values ("will start groonga!");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_enable_operations_recording_insert.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_enable_operations_recording_insert.test
new file mode 100644
index 00000000000..ad2b8167d81
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_enable_operations_recording_insert.test
@@ -0,0 +1,50 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+CREATE TABLE diaries (
+ title TEXT
+) DEFAULT CHARSET=utf8;
+
+SELECT mroonga_command('truncate mroonga_operations');
+INSERT INTO diaries VALUES("Unlogged: Research for Mroonga");
+SELECT mroonga_command('load --table mroonga_operations --values "[{}]"');
+SELECT mroonga_command('select mroonga_operations --output_columns _id');
+
+SET GLOBAL mroonga_enable_operations_recording = false;
+FLUSH TABLES;
+
+SELECT mroonga_command('truncate mroonga_operations');
+INSERT INTO diaries VALUES("Logged: Research for Mroonga");
+SELECT mroonga_command('load --table mroonga_operations --values "[{}]"');
+SELECT mroonga_command('select mroonga_operations --output_columns _id');
+
+DROP TABLE diaries;
+SELECT mroonga_command('truncate mroonga_operations');
+
+SET GLOBAL mroonga_enable_operations_recording = default;
+FLUSH TABLES;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_disable.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_disable.test
index 3e2c5bfe7bf..a3720f2ef5b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_disable.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_disable.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2014-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,17 +12,17 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_version_100_or_later.inc
+--source ../../include/mroonga/have_version_10_0_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
SET GLOBAL mroonga_lock_timeout = -1;
SHOW GLOBAL VARIABLES LIKE "mroonga_lock_timeout";
-disable_query_log;
-SET GLOBAL mroonga_lock_timeout = 10000000;
-enable_query_log;
+--disable_query_log
+SET GLOBAL mroonga_lock_timeout = DEFAULT;
+--enable_query_log
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_invalid.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_invalid.test
index 7358389bb5d..54c834d7e4c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_invalid.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_invalid.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2014-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,17 +12,17 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
---source ../../include/mroonga/have_version_100_or_later.inc
+--source ../../include/mroonga/have_version_10_0_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
SET GLOBAL mroonga_lock_timeout = -2;
SHOW GLOBAL VARIABLES LIKE "mroonga_lock_timeout";
-disable_query_log;
-SET GLOBAL mroonga_lock_timeout = 10000000;
-enable_query_log;
+--disable_query_log
+SET GLOBAL mroonga_lock_timeout = DEFAULT;
+--enable_query_log
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_no_retry.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_no_retry.test
index c25d1747b1d..60e468bf0a6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_no_retry.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_no_retry.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2014-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -20,8 +20,8 @@ SET GLOBAL mroonga_lock_timeout = 0;
SHOW GLOBAL VARIABLES LIKE "mroonga_lock_timeout";
-disable_query_log;
-SET GLOBAL mroonga_lock_timeout = 10000000;
-enable_query_log;
+--disable_query_log
+SET GLOBAL mroonga_lock_timeout = DEFAULT;
+--enable_query_log
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_valid.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_valid.test
index 523baa1b3e9..4b490b8a74d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_valid.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_lock_timeout_valid.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2014-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -20,8 +20,8 @@ SET GLOBAL mroonga_lock_timeout = 1000;
SHOW GLOBAL VARIABLES LIKE "mroonga_lock_timeout";
-disable_query_log;
-SET GLOBAL mroonga_lock_timeout = 10000000;
-enable_query_log;
+--disable_query_log
+SET GLOBAL mroonga_lock_timeout = DEFAULT;
+--enable_query_log
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_new_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_new_value.test
index c96b021be76..07a4afbe76e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_new_value.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_new_value.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_nonexistent_path.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_nonexistent_path.test
index d05cbd2349a..13c544b95a5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_nonexistent_path.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_nonexistent_path.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_same_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_same_value.test
index ead099e0cc1..e2cda37b79b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_same_value.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_file_same_value.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_level_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_level_TODO_SPLIT_ME.test
index 1f73f4f447f..2cf196f49ca 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_level_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_log_level_TODO_SPLIT_ME.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test
index 8585c1c2f11..fda1f8768f6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -20,7 +20,7 @@
DROP TABLE IF EXISTS diaries;
--enable_warnings
-# MySQL <= 5.5 reports wrong a warning. :<
+# MySQL <= 5.5 reports a wrong warning. :<
# It has been fixed in MySQL >= 5.6 and MariaDB >= 5.3.
--disable_warnings
SET GLOBAL mroonga_match_escalation_threshold = -1;
@@ -30,24 +30,31 @@ CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
tags TEXT,
- FULLTEXT INDEX tags_index (tags) COMMENT 'parser "TokenDelimit"'
+ FULLTEXT INDEX tags_index (tags) COMMENT 'tokenizer "TokenDelimit"'
) DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
-INSERT INTO diaries (title, tags) VALUES ("Hello groonga!", "groonga install");
-INSERT INTO diaries (title, tags) VALUES ("Hello mroonga!", "mroonga install");
+INSERT INTO diaries (title, tags) VALUES ("Hello Groonga!", "groonga install");
+INSERT INTO diaries (title, tags) VALUES ("Hello Mroonga!", "mroonga install");
+disable_query_log;
+CONNECT (new_connection, localhost, root, ,);
+CONNECTION new_connection;
+enable_query_log;
-SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("install" IN BOOLEAN MODE);
+SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("+install" IN BOOLEAN MODE);
-SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
+SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("+gr" IN BOOLEAN MODE);
SET GLOBAL mroonga_match_escalation_threshold = 0;
-SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
+SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("+gr" IN BOOLEAN MODE);
SET mroonga_match_escalation_threshold = 0;
-SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
+SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("+gr" IN BOOLEAN MODE);
+disable_query_log;
+CONNECTION default;
+DISCONNECT new_connection;
+enable_query_log;
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test
index 8743c3faadb..0a7d192f76f 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -24,9 +24,8 @@ CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
tags TEXT,
- FULLTEXT INDEX tags_index (tags) COMMENT 'parser "TokenDelimit"'
+ FULLTEXT INDEX tags_index (tags) COMMENT 'tokenizer "TokenDelimit"'
) DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, tags) VALUES ("Hello groonga!", "groonga install");
INSERT INTO diaries (title, tags) VALUES ("Hello mroonga!", "mroonga install");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_global.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_global.test
index 043d8d3340b..9ce8cf8bae7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_global.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_global.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,8 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source ../../include/mroonga/skip_mysql_5_7_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -38,13 +39,17 @@ INSERT INTO ids VALUES (10);
SET GLOBAL mroonga_max_n_records_for_estimate = 1;
+disable_query_log;
CONNECT (new_connection, localhost, root, ,);
CONNECTION new_connection;
+enable_query_log;
EXPLAIN SELECT * FROM ids WHERE id > 5;
+disable_query_log;
CONNECTION default;
DISCONNECT new_connection;
+enable_query_log;
SET GLOBAL mroonga_max_n_records_for_estimate = DEFAULT;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_global.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_global.test
new file mode 100644
index 00000000000..757a7f9590d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_global.test
@@ -0,0 +1,60 @@
+# Copyright(C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS ids;
+--enable_warnings
+
+CREATE TABLE ids (
+ id INT PRIMARY KEY AUTO_INCREMENT
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+INSERT INTO ids VALUES (4);
+INSERT INTO ids VALUES (5);
+INSERT INTO ids VALUES (6);
+INSERT INTO ids VALUES (7);
+INSERT INTO ids VALUES (8);
+INSERT INTO ids VALUES (9);
+INSERT INTO ids VALUES (10);
+
+
+SET GLOBAL mroonga_max_n_records_for_estimate = 1;
+
+disable_query_log;
+CONNECT (new_connection, localhost, root, ,);
+CONNECTION new_connection;
+enable_query_log;
+
+EXPLAIN SELECT * FROM ids WHERE id > 5;
+
+disable_query_log;
+CONNECTION default;
+DISCONNECT new_connection;
+enable_query_log;
+
+SET GLOBAL mroonga_max_n_records_for_estimate = DEFAULT;
+
+
+DROP TABLE ids;
+
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_not_found_in_limit.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_not_found_in_limit.test
new file mode 100644
index 00000000000..df9f498632e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_not_found_in_limit.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS ids;
+--enable_warnings
+
+CREATE TABLE ids (
+ id INT,
+ INDEX (id)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+
+DELETE FROM ids WHERE id < 2;
+
+SET mroonga_max_n_records_for_estimate = 1;
+
+EXPLAIN SELECT * FROM ids WHERE id > 0;
+
+SET mroonga_max_n_records_for_estimate = DEFAULT;
+
+DROP TABLE ids;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_session.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_session.test
new file mode 100644
index 00000000000..19b4b2836b1
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_mysql_5_7_or_later_session.test
@@ -0,0 +1,47 @@
+# Copyright(C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS ids;
+--enable_warnings
+
+CREATE TABLE ids (
+ id INT PRIMARY KEY AUTO_INCREMENT
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+INSERT INTO ids VALUES (4);
+INSERT INTO ids VALUES (5);
+INSERT INTO ids VALUES (6);
+INSERT INTO ids VALUES (7);
+INSERT INTO ids VALUES (8);
+INSERT INTO ids VALUES (9);
+INSERT INTO ids VALUES (10);
+
+SET mroonga_max_n_records_for_estimate = 1;
+
+EXPLAIN SELECT * FROM ids WHERE id > 5;
+
+SET mroonga_max_n_records_for_estimate = DEFAULT;
+
+DROP TABLE ids;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_not_found_in_limit.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_not_found_in_limit.test
new file mode 100644
index 00000000000..0b9357e06c0
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_not_found_in_limit.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/skip_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS ids;
+--enable_warnings
+
+CREATE TABLE ids (
+ id INT,
+ INDEX (id)
+) DEFAULT CHARSET=UTF8;
+
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+
+DELETE FROM ids WHERE id < 2;
+
+SET mroonga_max_n_records_for_estimate = 1;
+
+EXPLAIN SELECT * FROM ids WHERE id > 0;
+
+SET mroonga_max_n_records_for_estimate = DEFAULT;
+
+DROP TABLE ids;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_session.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_session.test
index 894e14f4802..5e31c8b0d63 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_session.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_max_n_records_for_estimate_session.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,8 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source ../../include/mroonga/skip_mysql_5_7_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_disabled_empty_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_disabled_empty_value.test
new file mode 100644
index 00000000000..fdd21cc0f4d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_disabled_empty_value.test
@@ -0,0 +1,31 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_mroonga_helper.inc
+
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+
+SET GLOBAL mroonga_query_log_file = "";
+--source ../../include/mroonga/print_groonga_query_log.inc
+
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
+
+--remove_file $MYSQLD_DATADIR/groonga-query-log.log
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_disabled_null_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_disabled_null_value.test
new file mode 100644
index 00000000000..b84fc3978ed
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_disabled_null_value.test
@@ -0,0 +1,31 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_mroonga_helper.inc
+
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+
+SET GLOBAL mroonga_query_log_file = NULL;
+--source ../../include/mroonga/print_groonga_query_log.inc
+
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
+
+--remove_file $MYSQLD_DATADIR/groonga-query-log.log
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_enabled_empty_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_enabled_empty_value.test
new file mode 100644
index 00000000000..0cb1a8d243a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_enabled_empty_value.test
@@ -0,0 +1,33 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_mroonga_helper.inc
+
+SET GLOBAL mroonga_query_log_file = "groonga-query.log";
+
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+
+SET GLOBAL mroonga_query_log_file = "";
+--source ../../include/mroonga/print_groonga_query_log.inc
+
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
+
+--remove_file $MYSQLD_DATADIR/groonga-query-log.log
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_enabled_null_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_enabled_null_value.test
new file mode 100644
index 00000000000..d1704a43d3a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_enabled_null_value.test
@@ -0,0 +1,33 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_mroonga_helper.inc
+
+SET GLOBAL mroonga_query_log_file = "groonga-query.log";
+
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+
+SET GLOBAL mroonga_query_log_file = NULL;
+--source ../../include/mroonga/print_groonga_query_log.inc
+
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
+
+--remove_file $MYSQLD_DATADIR/groonga-query-log.log
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_new_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_new_value.test
new file mode 100644
index 00000000000..e298aaa43b1
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_new_value.test
@@ -0,0 +1,33 @@
+# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2014 Kentoku SHIBA
+# Copyright(C) 2017 Kentaro Hayashi <hayashi@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_mroonga_helper.inc
+
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+
+SET GLOBAL mroonga_query_log_file = "groonga-query.log";
+--source ../../include/mroonga/print_groonga_query_log.inc
+
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
+
+--remove_file $MYSQLD_DATADIR/groonga-query-log.log
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_same_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_same_value.test
new file mode 100644
index 00000000000..4c500f1e674
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_query_log_file_same_value.test
@@ -0,0 +1,34 @@
+# Copyright(C) 2014-2017 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2017 Kentaro Hayashi <hayashi@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_mroonga_helper.inc
+
+SET GLOBAL mroonga_query_log_file = "groonga-query.log";
+
+SET GLOBAL mroonga_log_file = "groonga-query-log.log";
+
+SET GLOBAL mroonga_query_log_file = "groonga-query.log";
+--source ../../include/mroonga/print_groonga_query_log.inc
+
+SET GLOBAL mroonga_query_log_file = DEFAULT;
+SET GLOBAL mroonga_log_file = DEFAULT;
+
+--remove_file $MYSQLD_DATADIR/groonga-query-log.log
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_vector_column_delimiter.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_vector_column_delimiter.test
index d2ae3fd8718..f1fe11864d9 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_vector_column_delimiter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_vector_column_delimiter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_version.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_version.test
index 6c21f8d50d7..2bd4496a2de 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_version.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_version.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column.result
index c47a5ccc354..2be9834c617 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column.result
@@ -3,13 +3,6 @@ CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT
) DEFAULT CHARSET UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries (title) VALUES ("survey");
SELECT * FROM diaries;
id title
@@ -26,12 +19,4 @@ id title body
1 survey will start groonga!
2 groonga (1) starting groonga...
3 groonga (2) started groonga.
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column_multibyte_cp932.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column_multibyte_cp932.result
new file mode 100644
index 00000000000..9628df686b3
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column_multibyte_cp932.result
@@ -0,0 +1,33 @@
+DROP TABLE IF EXISTS users;
+SET NAMES cp932;
+CREATE TABLE users (
+id int unsigned PRIMARY KEY AUTO_INCREMENT
+) DEFAULT CHARSET=cp932 COMMENT='Engine "InnoDB"';
+ALTER TABLE users
+ADD COLUMN –¼‘O text,
+ADD FULLTEXT INDEX (–¼‘O);
+INSERT INTO users (–¼‘O) VALUES ("‚â‚Ü‚¾");
+INSERT INTO users (–¼‘O) VALUES ("‚½‚È‚©");
+INSERT INTO users (–¼‘O) VALUES ("‚·‚¸‚«");
+SELECT * FROM users;
+id –¼‘O
+1 ‚â‚Ü‚¾
+2 ‚½‚È‚©
+3 ‚·‚¸‚«
+SELECT * FROM users
+WHERE MATCH (–¼‘O) AGAINST ('+‚½‚È‚©' IN BOOLEAN MODE);
+id –¼‘O
+2 ‚½‚È‚©
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+mroonga_command("dump --dump_plugins no --dump_records no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create users TABLE_HASH_KEY ShortText
+
+table_create users#@540d@524d TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
+
+column_create users#@540d@524d index COLUMN_INDEX|WITH_POSITION users
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column_multibyte_utf8.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column_multibyte_utf8.result
new file mode 100644
index 00000000000..abd2271f051
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_add_column_multibyte_utf8.result
@@ -0,0 +1,33 @@
+DROP TABLE IF EXISTS users;
+SET NAMES utf8;
+CREATE TABLE users (
+id int unsigned PRIMARY KEY AUTO_INCREMENT
+) DEFAULT CHARSET=utf8 COMMENT='Engine "InnoDB"';
+ALTER TABLE users
+ADD COLUMN åå‰ text,
+ADD FULLTEXT INDEX (åå‰);
+INSERT INTO users (åå‰) VALUES ("ã‚„ã¾ã ");
+INSERT INTO users (åå‰) VALUES ("ãŸãªã‹");
+INSERT INTO users (åå‰) VALUES ("ã™ãšã");
+SELECT * FROM users;
+id åå‰
+1 ã‚„ã¾ã 
+2 ãŸãªã‹
+3 ã™ãšã
+SELECT * FROM users
+WHERE MATCH (åå‰) AGAINST ('+ãŸãªã‹' IN BOOLEAN MODE);
+id åå‰
+2 ãŸãªã‹
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+mroonga_command("dump --dump_plugins no --dump_records no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create users TABLE_HASH_KEY ShortText
+
+table_create users#@540d@524d TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI
+
+column_create users#@540d@524d index COLUMN_INDEX|WITH_POSITION users
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_change_engine.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_change_engine.result
index 3e270abe16d..7197d3a9dc0 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_change_engine.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_change_engine.result
@@ -6,16 +6,11 @@ body TEXT,
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) ENGINE MyISAM DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8
+SELECT table_name, engine, table_comment
+FROM information_schema.tables
+WHERE table_name = 'diaries';
+table_name engine table_comment
+diaries MyISAM
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
SELECT * FROM diaries
@@ -24,16 +19,11 @@ MATCH(body) AGAINST("groonga" IN BOOLEAN MODE);
id title body
1 survey will start groonga!
ALTER TABLE diaries ENGINE = mroonga COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
+SELECT table_name, engine, table_comment
+FROM information_schema.tables
+WHERE table_name = 'diaries';
+table_name engine table_comment
+diaries Mroonga ENGINE "InnoDB"
SELECT * FROM diaries
WHERE MATCH(title) AGAINST("survey" IN BOOLEAN MODE) AND
MATCH(body) AGAINST("groonga" IN BOOLEAN MODE);
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_comment_change_engine.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_comment_change_engine.result
index 9d225f46f25..05bd0e4e1e0 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_comment_change_engine.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_comment_change_engine.result
@@ -6,28 +6,15 @@ title VARCHAR(64),
content TEXT,
FULLTEXT INDEX(content)
) DEFAULT CHARSET=utf8 COMMENT='engine "InnoDB"';
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` varchar(64) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "InnoDB"'
INSERT INTO memos (title, content) VALUES ("Hello", "I start to write memos!");
INSERT INTO memos (title, content) VALUES ("groonga", "I start to use groonga!");
INSERT INTO memos (title, content) VALUES ("mroonga", "I use mroonga too!");
ALTER TABLE memos COMMENT='engine "MyISAM"';
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` varchar(64) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='engine "MyISAM"'
+SELECT table_name, table_comment
+FROM information_schema.tables
+WHERE table_name = 'memos';
+table_name table_comment
+memos engine "MyISAM"
SELECT * FROM memos;
id title content
1 Hello I start to write memos!
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_drop_column.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_drop_column.result
index c9fef8e4d8f..25cb53ded0b 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_drop_column.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_drop_column.result
@@ -4,26 +4,11 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
body TEXT
) DEFAULT CHARSET UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
SELECT * FROM diaries;
id title body
1 survey will start groonga!
ALTER TABLE diaries DROP COLUMN body;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
SELECT * FROM diaries;
id title
1 survey
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_fulltext.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_fulltext.result
index 5bf1bbf2124..37f03b40616 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_fulltext.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_fulltext.result
@@ -4,14 +4,6 @@ id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
FULLTEXT INDEX title_index (title)
) DEFAULT CHARSET UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries (title) VALUES ("survey");
SELECT * FROM diaries;
id title
@@ -39,14 +31,4 @@ WHERE MATCH(title) AGAINST("groonga") AND
MATCH(body) AGAINST("starting");
id title body
2 groonga (1) starting groonga...
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_rename_table.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_rename_table.result
index 8d161b424d1..bfbe96d14d7 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_rename_table.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_rename_table.result
@@ -6,16 +6,6 @@ body TEXT,
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) DEFAULT CHARSET UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
SELECT * FROM diaries;
id title body
@@ -32,14 +22,4 @@ SELECT * FROM memos
WHERE MATCH(title) AGAINST("groonga") AND
MATCH(body) AGAINST("starting");
id title body
-SHOW CREATE TABLE memos;
-Table Create Table
-memos CREATE TABLE `memos` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result
index abb7769224c..fa42d4a1fd3 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result
@@ -119,13 +119,4 @@ id name location_text
14 tetsuji POINT(139.76857 35.680912)
19 daruma POINT(139.770599 35.681461)
26 kazuya POINT(139.760895 35.673508)
-SHOW CREATE TABLE shops;
-Table Create Table
-shops CREATE TABLE `shops` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `name` text DEFAULT NULL,
- `location` geometry NOT NULL,
- PRIMARY KEY (`id`),
- SPATIAL KEY `location_index` (`location`)
-) ENGINE=Mroonga AUTO_INCREMENT=37 DEFAULT CHARSET=latin1 COMMENT='ENGINE "InnoDB"'
DROP TABLE shops;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/check_table_for_upgrade.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/check_table_for_upgrade.result
new file mode 100644
index 00000000000..61122f7842f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/check_table_for_upgrade.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS memos;
+SET NAMES utf8;
+CREATE TABLE memos (
+id int NOT NULL PRIMARY KEY,
+content text,
+FULLTEXT INDEX (content)
+) COMMENT='engine "InnoDB"';
+INSERT INTO memos VALUES (1, 'Hello MySQL');
+INSERT INTO memos VALUES (2, 'Hello Mroonga');
+CHECK TABLE memos FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.memos check status OK
+FLUSH TABLES;
+SELECT * FROM memos
+WHERE MATCH(content) AGAINST('+mroonga' IN BOOLEAN MODE);
+id content
+2 Hello Mroonga
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_add_column.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_add_column.result
new file mode 100644
index 00000000000..5b379d08e3a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_add_column.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+ALTER TABLE logs ADD COLUMN message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED;
+ALTER TABLE logs ADD FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"';
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "restart"} "restart"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_delete.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_delete.result
new file mode 100644
index 00000000000..24c9275b5e7
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_delete.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+DELETE FROM logs WHERE id = 1;
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+id record message
+2 {"level": "info", "message": "restart"} "restart"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_drop_column.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_drop_column.result
new file mode 100644
index 00000000000..65a55204a32
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_drop_column.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+ALTER TABLE logs DROP COLUMN message;
+SELECT * FROM logs;
+id record
+1 {"level": "info", "message": "start"}
+2 {"level": "info", "message": "restart"}
+3 {"level": "warn", "message": "abort"}
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_insert.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_insert.result
new file mode 100644
index 00000000000..febfd34345b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_insert.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "restart"} "restart"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_reindex.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_reindex.result
new file mode 100644
index 00000000000..c0d9452f15e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_reindex.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+ALTER TABLE logs DISABLE KEYS;
+ALTER TABLE logs ENABLE KEYS;
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "restart"} "restart"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_update.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_update.result
new file mode 100644
index 00000000000..ae9c244d880
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_stored_update.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+UPDATE logs SET record = '{"level": "info", "message": "shutdown"}' WHERE id = 2;
+SELECT * FROM logs WHERE MATCH(message) AGAINST("hut" IN BOOLEAN MODE);
+id record message
+2 {"level": "info", "message": "shutdown"} "shutdown"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_column.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_column.result
new file mode 100644
index 00000000000..6daeb5e2f31
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_column.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+ALTER TABLE logs ADD COLUMN message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL;
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+SELECT * FROM logs;
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "restart"} "restart"
+3 {"level": "warn", "message": "abort"} "abort"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_fulltext_index.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_fulltext_index.result
new file mode 100644
index 00000000000..82a46e3fcfc
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_fulltext_index.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record)
+VALUES (1, '{"level": "info", "message": "start server"}');
+ALTER TABLE logs ADD FULLTEXT INDEX (message);
+INSERT INTO logs(id, record)
+VALUES (2, '{"level": "info", "message": "start server"}');
+INSERT INTO logs(id, record)
+VALUES (3, '{"level": "warn", "message": "abort server"}');
+SELECT * FROM logs WHERE MATCH(message) AGAINST('+start' IN BOOLEAN MODE);
+id record message
+2 {"level": "info", "message": "start server"} "start server"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_index.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_index.result
new file mode 100644
index 00000000000..09cd18915f8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_add_index.result
@@ -0,0 +1,19 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+level VARCHAR(255) GENERATED ALWAYS AS
+(json_unquote(json_extract(`record`, '$.level'))) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record)
+VALUES (1, '{"level": "info", "message": "start server"}');
+ALTER TABLE logs ADD INDEX (level);
+INSERT INTO logs(id, record)
+VALUES (2, '{"level": "info", "message": "start server"}');
+INSERT INTO logs(id, record)
+VALUES (3, '{"level": "warn", "message": "abort server"}');
+SELECT * FROM logs WHERE level = 'info';
+id record level
+1 {"level": "info", "message": "start server"} info
+2 {"level": "info", "message": "start server"} info
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_delete.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_delete.result
new file mode 100644
index 00000000000..8c1ceaf13dd
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_delete.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+DELETE FROM logs WHERE id = 1;
+SELECT * FROM logs;
+id record message
+2 {"level": "info", "message": "restart"} "restart"
+3 {"level": "warn", "message": "abort"} "abort"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_drop_column.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_drop_column.result
new file mode 100644
index 00000000000..7d3226175ea
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_drop_column.result
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+ALTER TABLE logs DROP COLUMN message;
+SELECT * FROM logs;
+id record
+1 {"level": "info", "message": "start"}
+2 {"level": "info", "message": "restart"}
+3 {"level": "warn", "message": "abort"}
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_insert.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_insert.result
new file mode 100644
index 00000000000..5a0e63ed7c4
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_insert.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+SELECT * FROM logs;
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "restart"} "restart"
+3 {"level": "warn", "message": "abort"} "abort"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_update.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_update.result
new file mode 100644
index 00000000000..2411f7a725c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_generated_virtual_update.result
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY,
+record JSON,
+message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+UPDATE logs SET record = '{"level": "info", "message": "shutdown"}' WHERE id = 2;
+SELECT * FROM logs;
+id record message
+1 {"level": "info", "message": "start"} "start"
+2 {"level": "info", "message": "shutdown"} "shutdown"
+3 {"level": "warn", "message": "abort"} "abort"
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_multibyte_cp932.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_multibyte_cp932.result
new file mode 100644
index 00000000000..38185f5ec97
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_multibyte_cp932.result
@@ -0,0 +1,32 @@
+DROP TABLE IF EXISTS users;
+SET NAMES cp932;
+CREATE TABLE users (
+id int unsigned PRIMARY KEY AUTO_INCREMENT,
+–¼‘O text,
+FULLTEXT INDEX (–¼‘O)
+) DEFAULT CHARSET=cp932 COMMENT='Engine "InnoDB"';
+INSERT INTO users (–¼‘O) VALUES ("‚â‚Ü‚¾");
+INSERT INTO users (–¼‘O) VALUES ("‚½‚È‚©");
+INSERT INTO users (–¼‘O) VALUES ("‚·‚¸‚«");
+SELECT * FROM users;
+id –¼‘O
+1 ‚â‚Ü‚¾
+2 ‚½‚È‚©
+3 ‚·‚¸‚«
+SELECT * FROM users
+WHERE MATCH (–¼‘O) AGAINST ('+‚½‚È‚©' IN BOOLEAN MODE);
+id –¼‘O
+2 ‚½‚È‚©
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+mroonga_command("dump --dump_plugins no --dump_records no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create users TABLE_HASH_KEY ShortText
+
+table_create users#@540d@524d TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
+
+column_create users#@540d@524d index COLUMN_INDEX|WITH_POSITION users
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/column_multibyte_utf8.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_multibyte_utf8.result
new file mode 100644
index 00000000000..2d31307392f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/column_multibyte_utf8.result
@@ -0,0 +1,32 @@
+DROP TABLE IF EXISTS users;
+SET NAMES utf8;
+CREATE TABLE users (
+id int unsigned PRIMARY KEY AUTO_INCREMENT,
+åå‰ text,
+FULLTEXT INDEX (åå‰)
+) DEFAULT CHARSET=utf8 COMMENT='Engine "InnoDB"';
+INSERT INTO users (åå‰) VALUES ("ã‚„ã¾ã ");
+INSERT INTO users (åå‰) VALUES ("ãŸãªã‹");
+INSERT INTO users (åå‰) VALUES ("ã™ãšã");
+SELECT * FROM users;
+id åå‰
+1 ã‚„ã¾ã 
+2 ãŸãªã‹
+3 ã™ãšã
+SELECT * FROM users
+WHERE MATCH (åå‰) AGAINST ('+ãŸãªã‹' IN BOOLEAN MODE);
+id åå‰
+2 ãŸãªã‹
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+mroonga_command("dump --dump_plugins no --dump_records no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create users TABLE_HASH_KEY ShortText
+
+table_create users#@540d@524d TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI
+
+column_create users#@540d@524d index COLUMN_INDEX|WITH_POSITION users
+DROP TABLE users;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/count_star.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/count_star.result
new file mode 100644
index 00000000000..7822d118733
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/count_star.result
@@ -0,0 +1,11 @@
+DROP TABLE IF EXISTS ids;
+CREATE TABLE ids (
+id int PRIMARY KEY
+) COMMENT='ENGINE "InnoDB"';
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+SELECT COUNT(*) FROM ids;
+COUNT(*)
+3
+DROP TABLE ids;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/count_star_mysql_5_7_or_later_with_index.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/count_star_mysql_5_7_or_later_with_index.result
new file mode 100644
index 00000000000..141117f608a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/count_star_mysql_5_7_or_later_with_index.result
@@ -0,0 +1,30 @@
+CREATE TABLE diaries_innodb (
+id INT PRIMARY KEY AUTO_INCREMENT,
+body TEXT,
+flag TINYINT(2),
+INDEX (flag)
+) ENGINE = InnoDB DEFAULT CHARSET UTF8;
+CREATE TABLE diaries_mroonga (
+id INT PRIMARY KEY AUTO_INCREMENT,
+body TEXT,
+flag TINYINT(2),
+INDEX (flag)
+) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET UTF8;
+INSERT INTO diaries_innodb (body) VALUES ("will start groonga!");
+INSERT INTO diaries_innodb (body) VALUES ("starting groonga...");
+INSERT INTO diaries_innodb (body) VALUES ("started groonga.");
+INSERT INTO diaries_mroonga (body) VALUES ("will start groonga!");
+INSERT INTO diaries_mroonga (body) VALUES ("starting groonga...");
+INSERT INTO diaries_mroonga (body) VALUES ("started groonga.");
+EXPLAIN SELECT COUNT(*) FROM diaries_innodb;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE diaries_innodb NULL index NULL flag 2 NULL 3 100.00 Using index
+Warnings:
+Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`diaries_innodb`
+EXPLAIN SELECT COUNT(*) FROM diaries_mroonga;
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE diaries_mroonga NULL index NULL flag 2 NULL 3 100.00 Using index
+Warnings:
+Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`diaries_mroonga`
+DROP TABLE diaries_innodb;
+DROP TABLE diaries_mroonga;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/count_star_with_index.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/count_star_with_index.result
index a6d2f7862af..1ebd0ba870e 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/count_star_with_index.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/count_star_with_index.result
@@ -18,9 +18,9 @@ INSERT INTO diaries_mroonga (body) VALUES ("starting groonga...");
INSERT INTO diaries_mroonga (body) VALUES ("started groonga.");
EXPLAIN SELECT COUNT(*) FROM diaries_innodb;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE diaries_innodb index NULL flag 2 NULL 3 Using index
+1 SIMPLE diaries_innodb index NULL flag 2 NULL # Using index
EXPLAIN SELECT COUNT(*) FROM diaries_mroonga;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE diaries_mroonga index NULL flag 2 NULL 3 Using index
+1 SIMPLE diaries_mroonga index NULL flag 2 NULL # Using index
DROP TABLE diaries_innodb;
DROP TABLE diaries_mroonga;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_TODO_SPLIT_ME.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_TODO_SPLIT_ME.result
index 49e5e0a1466..b3814331038 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_TODO_SPLIT_ME.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_TODO_SPLIT_ME.result
@@ -63,7 +63,7 @@ drop table t1;
create table t1 (c1 timestamp primary key) COMMENT = 'engine "innodb"';
desc t1;
Field Type Null Key Default Extra
-c1 timestamp NO PRI current_timestamp() on update current_timestamp()
+c1 timestamp NO PRI CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
drop table t1;
create table t1 (c1 datetime primary key) COMMENT = 'engine "innodb"';
desc t1;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_comment_combined.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_comment_combined.result
index ce1b5470231..3610ab6f556 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_comment_combined.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_comment_combined.result
@@ -3,10 +3,12 @@ CREATE TABLE bugs (
id INT UNSIGNED PRIMARY KEY
) DEFAULT CHARSET=utf8
COMMENT='Free style normal comment, engine "InnoDB"';
-SHOW CREATE TABLE bugs;
-Table Create Table
-bugs CREATE TABLE `bugs` (
- `id` int(10) unsigned NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='Free style normal comment, engine "InnoDB"'
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create bugs TABLE_HASH_KEY ShortText
+
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
DROP TABLE bugs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result
index fb03bfe8d8d..6ff4c105384 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result
@@ -5,5 +5,5 @@ FULLTEXT INDEX (content) COMMENT 'flags "WITH_POSITION|WITH_WEIGHT"'
) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
-column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos
+column_create memos#content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result
index 4a7107146ce..9048b677a2f 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result
@@ -5,5 +5,5 @@ FULLTEXT INDEX (content) COMMENT 'flags "NONE"'
) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
-column_create memos-content index COLUMN_INDEX memos
+column_create memos#content index COLUMN_INDEX memos
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result
index 6e00526c736..1c701d0eb8f 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result
@@ -12,5 +12,5 @@ memos CREATE TABLE `memos` (
) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
-column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos
+column_create memos#content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_index_flags_none.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_index_flags_none.result
index 08bdd72ee03..e378ba3b7ba 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_index_flags_none.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_index_flags_none.result
@@ -5,5 +5,5 @@ FULLTEXT INDEX (content) COMMENT 'index_flags "NONE"'
) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
-column_create memos-content index COLUMN_INDEX memos
+column_create memos#content index COLUMN_INDEX memos
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_index_flags_with_position_and_with_weight.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_index_flags_with_position_and_with_weight.result
index a5ac716d38e..1367a3adbb9 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_index_flags_with_position_and_with_weight.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_index_flags_with_position_and_with_weight.result
@@ -5,5 +5,5 @@ FULLTEXT INDEX (content) COMMENT 'index_flags "WITH_POSITION|WITH_WEIGHT"'
) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
-column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos
+column_create memos#content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index_bin.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index_bin.result
new file mode 100644
index 00000000000..5230963af79
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index_bin.result
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS memos;
+SET NAMES utf8;
+CREATE TABLE memos (
+id INT NOT NULL PRIMARY KEY,
+content TEXT NOT NULL,
+FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+SHOW CREATE TABLE memos;
+Table Create Table
+memos CREATE TABLE `memos` (
+ `id` int(11) NOT NULL,
+ `content` text COLLATE utf8_bin NOT NULL,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `content` (`content`) COMMENT 'normalizer "NormalizerAuto"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='ENGINE "InnoDB"'
+INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ");
+SELECT * FROM memos
+WHERE MATCH (content) AGAINST ("+カロリー" IN BOOLEAN MODE);
+id content
+1 1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_parser_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_parser_comment.result
index d382e937cea..4d9d20dc8ab 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_parser_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_parser_comment.result
@@ -5,15 +5,11 @@ body text,
fulltext index body_index (body)
comment 'parser "TokenBigramSplitSymbolAlphaDigit"'
) comment = 'engine "innodb"' default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`) COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
+Warnings:
+Warning 1287 'parser' is deprecated and will be removed in a future release. Please use tokenizer instead
insert into diaries (body) values ("will start Groonga!");
+Warnings:
+Warning 1287 'parser' is deprecated and will be removed in a future release. Please use tokenizer instead
insert into diaries (body) values ("starting Groonga...");
insert into diaries (body) values ("started Groonga.");
select * from diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_multiple_token_filters.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_multiple_token_filters.result
index e1e32dccc37..7f4885fb0da 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_multiple_token_filters.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_multiple_token_filters.result
@@ -11,7 +11,12 @@ SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
table_create memos TABLE_HASH_KEY ShortText
-table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
+table_create memos#content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
-column_create memos-content index COLUMN_INDEX|WITH_POSITION memos
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create memos#content index COLUMN_INDEX|WITH_POSITION memos
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_one_token_filter.result
index 11ee04e2998..2d7c67489e6 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_one_token_filter.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_one_token_filter.result
@@ -11,7 +11,12 @@ SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
table_create memos TABLE_HASH_KEY ShortText
-table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord
+table_create memos#content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord
-column_create memos-content index COLUMN_INDEX|WITH_POSITION memos
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create memos#content index COLUMN_INDEX|WITH_POSITION memos
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result
index f6d6be1b643..4626d1443f8 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result
@@ -19,7 +19,12 @@ SELECT mroonga_command("dump --dump_plugins no");
mroonga_command("dump --dump_plugins no")
table_create memos TABLE_HASH_KEY ShortText
-table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
+table_create memos#content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
-column_create memos-content index COLUMN_INDEX|WITH_POSITION memos
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+column_create memos#content index COLUMN_INDEX|WITH_POSITION memos
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result
index 45cdffb8cd3..34e3f88dbad 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result
@@ -5,14 +5,6 @@ body text,
fulltext index body_index (body)
comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
) comment = 'engine "innodb"' default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`) COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
insert into diaries (body) values ("will start Groonga!");
insert into diaries (body) values ("starting Groonga...");
insert into diaries (body) values ("started Groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result
index 318be3f364a..219d8e08deb 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result
@@ -4,14 +4,6 @@ id int PRIMARY KEY AUTO_INCREMENT,
body text,
FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit'
) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET utf8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`) `TOKENIZER`='TokenBigramSplitSymbolAlphaDigit'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries (body) VALUES ("will start Groonga!");
INSERT INTO diaries (body) VALUES ("starting Groonga...");
INSERT INTO diaries (body) VALUES ("started Groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/drop_table_new_connection.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/drop_table_new_connection.result
new file mode 100644
index 00000000000..f7d5b439b69
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/drop_table_new_connection.result
@@ -0,0 +1,13 @@
+CREATE TABLE logs (
+id INT PRIMARY KEY AUTO_INCREMENT,
+message TEXT,
+FULLTEXT INDEX (message)
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+USE test;
+DROP TABLE logs;
+CREATE TABLE logs (
+id INT PRIMARY KEY AUTO_INCREMENT,
+message TEXT,
+FULLTEXT INDEX (message)
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+DROP TABLE logs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_leading_not.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_leading_not.result
index de8e47dcd82..8614eaa73f8 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_leading_not.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_leading_not.result
@@ -6,15 +6,6 @@ title VARCHAR(255),
content TEXT,
FULLTEXT INDEX (content)
) DEFAULT CHARSET = UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries VALUES(1, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_multiple_match_against.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_multiple_match_against.result
index 0659c7c59df..1ecf18cb131 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_multiple_match_against.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_multiple_match_against.result
@@ -7,16 +7,6 @@ content TEXT,
FULLTEXT INDEX (title),
FULLTEXT INDEX (content)
) DEFAULT CHARSET = UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries VALUES(1, "富士山", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, "天気 1月1日", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, "天気 4月4日", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_index_recreate.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_index_recreate.result
index 13b2bcb4ff1..d3bdfca0def 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_index_recreate.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_index_recreate.result
@@ -6,15 +6,6 @@ title varchar(255),
content text,
FULLTEXT INDEX (title)
) DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries VALUES (1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES (2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES (3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result
index 7391ee4ba8d..c25b47c6bde 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result
@@ -6,7 +6,11 @@ insert into t1 values (2, "ka ki ku ke ko");
insert into t1 values (3, "aa ii ii ii oo");
insert into t1 values (4, "sa si su se so");
insert into t1 values (5, "ta ti ii ii to");
-insert into t2 (c1,c2) select c1,c2 from t1;
+insert into t2 values (1, "aa ii uu ee oo");
+insert into t2 values (2, "ka ki ku ke ko");
+insert into t2 values (3, "aa ii ii ii oo");
+insert into t2 values (4, "sa si su se so");
+insert into t2 values (5, "ta ti ii ii to");
select * from t1;
c1 c2
1 aa ii uu ee oo
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_values.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_values.result
index 11d40fc0589..f4719cbdd95 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_values.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_values.result
@@ -1,13 +1,5 @@
drop table if exists t1, t2, t3;
create table t1 (c1 int primary key, c2 text, fulltext index ft (c2)) COMMENT = 'engine "innodb"';
-show create table t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `c1` int(11) NOT NULL,
- `c2` text DEFAULT NULL,
- PRIMARY KEY (`c1`),
- FULLTEXT KEY `ft` (`c2`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1 COMMENT='engine "innodb"'
insert into t1 values (1, "hoge hoge");
insert into t1 values (2, "fuga fuga");
insert into t1 values (3, "moge moge");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result
index 03cf96b55f8..9d1e838b893 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result
@@ -5,14 +5,6 @@ id int primary key,
title varchar(255),
fulltext index (title)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
set autocommit=0;
insert into diaries values(0, "2011-07-14");
insert into diaries values(1, "2011-07-15");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result
index 81ce556e745..39ab80edf3b 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result
@@ -10,15 +10,18 @@ FULLTEXT KEY (not_matched)
INSERT INTO texts VALUES (1, 'Hello1', 'World1');
INSERT INTO texts VALUES (2, 'Hello2', 'World2');
INSERT INTO texts VALUES (3, 'Hello3', 'World3');
-SELECT id,
+SELECT *
+FROM (SELECT id,
matched,
not_matched,
MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
FROM texts
-WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE);
+WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE))
+AS searched_texts
+ORDER BY id;
id matched not_matched MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE) MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
1 Hello1 World1 1 0
-3 Hello3 World3 1 0
2 Hello2 World2 1 0
+3 Hello3 World3 1 0
DROP TABLE texts;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_delete.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_delete.result
index 3c014b1b2b3..fbdf241b81e 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_delete.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_delete.result
@@ -8,17 +8,6 @@ fulltext index (title, content),
fulltext index (title),
fulltext index (content)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`,`content`),
- FULLTEXT KEY `title_2` (`title`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_insert.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_insert.result
index 3b65bc1a2ba..074d1991505 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_insert.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_insert.result
@@ -8,17 +8,6 @@ fulltext index (title, content),
fulltext index (title),
fulltext index (content)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`,`content`),
- FULLTEXT KEY `title_2` (`title`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_recreate.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_recreate.result
index cc0fb391628..756a702171a 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_recreate.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_recreate.result
@@ -8,17 +8,6 @@ fulltext index (title, content),
fulltext index (title),
fulltext index (content)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`,`content`),
- FULLTEXT KEY `title_2` (`title`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_update.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_update.result
index 863b95a3059..db869eaa697 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_update.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_column_index_update.result
@@ -8,17 +8,6 @@ fulltext index (title, content),
fulltext index (title),
fulltext index (content)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title` (`title`,`content`),
- FULLTEXT KEY `title_2` (`title`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_index.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_index.result
index 9ccffb28be1..7121e5109d3 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_index.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_multiple_index.result
@@ -6,16 +6,6 @@ body text,
fulltext index title_index (title),
fulltext index body_index (body)
) comment = 'engine "innodb"' default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
insert into diaries (title, body) values ("survey", "will start groonga!");
insert into diaries (title, body) values ("groonga (1)", "starting groonga...");
insert into diaries (title, body) values ("groonga (2)", "started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result
index ab3c321959e..90376bdf156 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result
@@ -1,13 +1,5 @@
drop table if exists t1, t2, t3;
create table t1 (c1 int primary key, c2 text, fulltext index ft (c2)) COMMENT = 'engine "myisam"';
-show create table t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `c1` int(11) NOT NULL,
- `c2` text DEFAULT NULL,
- PRIMARY KEY (`c1`),
- FULLTEXT KEY `ft` (`c2`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1 COMMENT='engine "myisam"'
insert into t1 values (1, "hoge hoge");
insert into t1 values (2, "fuga fuga");
insert into t1 values (3, "moge moge");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result
index ceff90c477c..f79798cec6d 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result
@@ -1,23 +1,13 @@
DROP TABLE IF EXISTS diaries;
SET NAMES UTF8;
CREATE TABLE ft(
-a INT,
+a INT DEFAULT 0,
b TEXT,
c TEXT,
PRIMARY KEY(a),
FULLTEXT KEY ftx1(b),
FULLTEXT KEY ftx2(c)
)ENGINE=Mroonga DEFAULT CHARSET=UTF8 COMMENT = 'engine "innodb"';
-SHOW CREATE TABLE ft;
-Table Create Table
-ft CREATE TABLE `ft` (
- `a` int(11) NOT NULL,
- `b` text DEFAULT NULL,
- `c` text DEFAULT NULL,
- PRIMARY KEY (`a`),
- FULLTEXT KEY `ftx1` (`b`),
- FULLTEXT KEY `ftx2` (`c`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
INSERT INTO ft VALUES(1,'aaaaa','abcde');
INSERT INTO ft VALUES(2,'bbbbb','bcdef');
INSERT INTO ft VALUES(3,'ccccc','cdefg');
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_transaction.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_transaction.result
index 1d8284e2370..3ee15c63bfd 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_transaction.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_transaction.result
@@ -6,16 +6,6 @@ body TEXT,
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
START TRANSACTION;
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
@@ -27,15 +17,12 @@ id title body
1 survey will start groonga!
2 groonga (1) starting groonga...
3 groonga (2) started groonga.
-CONNECT search_connection, localhost, root;
USE test;
SELECT * FROM diaries
WHERE MATCH(body) AGAINST("groonga")
ORDER BY id;
id title body
-connection default;
COMMIT;
-connection search_connection;
SELECT * FROM diaries
WHERE MATCH(body) AGAINST("groonga")
ORDER BY id;
@@ -43,8 +30,6 @@ id title body
1 survey will start groonga!
2 groonga (1) starting groonga...
3 groonga (2) started groonga.
-disconnect search_connection;
-connection default;
SELECT * FROM diaries
WHERE MATCH(body) AGAINST("groonga")
ORDER BY id;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_contains.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_contains.result
index 7f32fed3810..550554eac8c 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_contains.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_contains.result
@@ -5,15 +5,6 @@ name text,
location geometry NOT NULL,
spatial key location_index (location)
) comment = 'engine "innodb"';
-show create table shops;
-Table Create Table
-shops CREATE TABLE `shops` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `name` text DEFAULT NULL,
- `location` geometry NOT NULL,
- PRIMARY KEY (`id`),
- SPATIAL KEY `location_index` (`location`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1 COMMENT='engine "innodb"'
insert into shops (name, location)
values ('nezu-no-taiyaki',
ST_GeomFromText('POINT(139.762573 35.720253)'));
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_delete.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_delete.result
index 92c70d223e9..615d185f79f 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_delete.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_delete.result
@@ -5,15 +5,6 @@ name text,
location geometry NOT NULL,
spatial key location_index (location)
) comment = 'engine "innodb"';
-show create table shops;
-Table Create Table
-shops CREATE TABLE `shops` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `name` text DEFAULT NULL,
- `location` geometry NOT NULL,
- PRIMARY KEY (`id`),
- SPATIAL KEY `location_index` (`location`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1 COMMENT='engine "innodb"'
insert into shops (name, location)
values ('sazare',
ST_GeomFromText('POINT(139.685043 35.714653)'));
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_update.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_update.result
index 3594339c685..adfb53e10a2 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_update.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_update.result
@@ -5,15 +5,6 @@ name text,
location geometry NOT NULL,
spatial key location_index (location)
) comment = 'engine "innodb"';
-show create table shops;
-Table Create Table
-shops CREATE TABLE `shops` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `name` text DEFAULT NULL,
- `location` geometry NOT NULL,
- PRIMARY KEY (`id`),
- SPATIAL KEY `location_index` (`location`)
-) ENGINE=Mroonga DEFAULT CHARSET=latin1 COMMENT='engine "innodb"'
insert into shops (name, location)
values ('sazare',
ST_GeomFromText('POINT(139.685043 35.714653)'));
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_bulk.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_bulk.result
index c249b4995a0..552cf58682b 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_bulk.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_bulk.result
@@ -5,14 +5,6 @@ id int primary key,
content text,
fulltext index (content)
) default charset utf8 comment = 'engine "innodb"';
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
LOCK TABLE diaries WRITE;
insert into diaries values(1, "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_on_duplicate_key_update_multiple_column_primary_key_myisam.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_on_duplicate_key_update_multiple_column_primary_key_myisam.result
index ab3e86baec3..f0ceb937a01 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_on_duplicate_key_update_multiple_column_primary_key_myisam.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_on_duplicate_key_update_multiple_column_primary_key_myisam.result
@@ -8,7 +8,7 @@ PRIMARY KEY (date, title)
SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
- `date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
+ `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`title` varchar(100) NOT NULL,
`content` text NOT NULL,
PRIMARY KEY (`date`,`title`)
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_on_duplicate_key_update_multiple_column_unique_index_myisam.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_on_duplicate_key_update_multiple_column_unique_index_myisam.result
index 0a9709a1d31..97428b768a6 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_on_duplicate_key_update_multiple_column_unique_index_myisam.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/insert_on_duplicate_key_update_multiple_column_unique_index_myisam.result
@@ -10,7 +10,7 @@ SHOW CREATE TABLE diaries;
Table Create Table
diaries CREATE TABLE `diaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
+ `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`title` varchar(100) NOT NULL,
`content` text NOT NULL,
PRIMARY KEY (`id`),
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/multi_range_read_mysql_5_7_or_later_disk_sweep.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/multi_range_read_mysql_5_7_or_later_disk_sweep.result
new file mode 100644
index 00000000000..bf1e67b9378
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/multi_range_read_mysql_5_7_or_later_disk_sweep.result
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS integers;
+SET optimizer_switch='mrr_cost_based=off';
+CREATE TABLE integers (
+id INT PRIMARY KEY AUTO_INCREMENT,
+value INT,
+KEY (value)
+) COMMENT='engine "InnoDB"';
+INSERT INTO integers (value) VALUES (0), (1), (2), (3);
+EXPLAIN SELECT * FROM integers
+WHERE value IN (0, 2);
+id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE integers NULL range value value 5 NULL 2 100.00 Using where; Using MRR
+Warnings:
+Note 1003 /* select#1 */ select `test`.`integers`.`id` AS `id`,`test`.`integers`.`value` AS `value` from `test`.`integers` where (`test`.`integers`.`value` in (0,2))
+SELECT * FROM integers
+WHERE value IN (0, 2);
+id value
+1 0
+3 2
+DROP TABLE integers;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/repair_table_no_files.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/repair_table_no_files.result
index 1eeaec1efd8..8258a03bf42 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/repair_table_no_files.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/repair_table_no_files.result
@@ -6,15 +6,6 @@ title TEXT,
body TEXT,
FULLTEXT INDEX body_index (body)
) COMMENT = 'engine "innodb"' DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
INSERT INTO diaries (title, body) VALUES ("groonga (2)", "started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/repair_table_no_index_file.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/repair_table_no_index_file.result
index 3813b320562..cca7aee95de 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/repair_table_no_index_file.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/repair_table_no_index_file.result
@@ -6,15 +6,6 @@ title TEXT,
body TEXT,
FULLTEXT INDEX body_index (body)
) COMMENT = 'engine "innodb"' DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
INSERT INTO diaries (title, body) VALUES ("groonga (2)", "started groonga.");
@@ -23,7 +14,7 @@ id title body
2 groonga (1) starting groonga...
FLUSH TABLES;
SELECT * FROM diaries WHERE MATCH(body) AGAINST("starting");
-ERROR HY000: syscall error 'repair_test.mrn.0000106' (No such file or directory)
+ERROR HY000: system call error: No such file or directory: failed to open path: <repair_test.mrn.000010A>
REPAIR TABLE diaries;
Table Op Msg_type Msg_text
repair_test.diaries repair status OK
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/temporary_table.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/temporary_table.result
index 4e2ebf121e2..d66b463d7ed 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/temporary_table.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/temporary_table.result
@@ -3,13 +3,6 @@ CREATE TEMPORARY TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT
) DEFAULT CHARSET=UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TEMPORARY TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries (title) VALUES ("clear day");
INSERT INTO diaries (title) VALUES ("rainy day");
INSERT INTO diaries (title) VALUES ("cloudy day");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_query_cache.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_query_cache.result
index 61fbe239a35..54afac7a1a7 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_query_cache.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_query_cache.result
@@ -11,23 +11,18 @@ simple_table CREATE TABLE `simple_table` (
PRIMARY KEY (`id`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO simple_table (id) VALUES (1),(2);
-CONNECT second_connection, localhost, root;
USE test;
START TRANSACTION;
INSERT INTO simple_table (id) VALUES (3);
-connection default;
SELECT * FROM simple_table;
id
1
2
-connection second_connection;
COMMIT;
-connection default;
SELECT * FROM simple_table;
id
1
2
3
DROP TABLE simple_table;
-disconnect second_connection;
SET GLOBAL query_cache_size = @tmp_query_cache_size;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_delete.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_delete.result
index 8ea9ffb0e67..9082032ff6e 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_delete.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_delete.result
@@ -6,16 +6,6 @@ body TEXT,
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
INSERT INTO diaries (title, body) VALUES ("groonga (2)", "started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_update.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_update.result
index a06a57371be..0a424e77806 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_update.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_update.result
@@ -6,16 +6,6 @@ body TEXT,
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `title_index` (`title`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
INSERT INTO diaries (title, body) VALUES ("groonga (2)", "started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result
index 0285bb7f62e..296f87ade66 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result
@@ -10,19 +10,6 @@ content TEXT,
FULLTEXT INDEX(content),
KEY(day)
) DEFAULT CHARSET UTF8 COMMENT = 'engine "innodb"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `year` int(10) unsigned DEFAULT NULL,
- `month` int(10) unsigned DEFAULT NULL,
- `day` int(10) unsigned DEFAULT NULL,
- `title` varchar(255) DEFAULT NULL,
- `content` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `day` (`day`),
- FULLTEXT KEY `content` (`content`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_delete.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_delete.result
index 674a6666081..ccc28a0f4c7 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_delete.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_delete.result
@@ -4,14 +4,6 @@ id int primary key auto_increment,
body text,
fulltext index body_index (body)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
insert into diaries (body) values ("will start groonga!");
insert into diaries (body) values ("starting groonga...");
insert into diaries (body) values ("started groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_insert.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_insert.result
index 46777cd877d..a9bdd38fa22 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_insert.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_insert.result
@@ -4,14 +4,6 @@ id int primary key auto_increment,
body text,
fulltext index body_index (body)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
insert into diaries (body) values ("will start groonga!");
select * from diaries;
id body
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_update.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_update.result
index e9be95ab90e..b2fe4607f8f 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_update.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_dry_write_update.result
@@ -4,14 +4,6 @@ id int primary key auto_increment,
body text,
fulltext index body_index (body)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`)
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
insert into diaries (body) values ("will start groonga!");
set mroonga_dry_write=true;
update diaries set body = "starting groonga..." where id = 1;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_match_escalation_threshold_global.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_match_escalation_threshold_global.result
index c988a101095..9405879f4f5 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_match_escalation_threshold_global.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_match_escalation_threshold_global.result
@@ -3,28 +3,16 @@ CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
tags TEXT,
-FULLTEXT INDEX tags_index (tags) COMMENT 'parser "TokenDelimit"'
+FULLTEXT INDEX tags_index (tags) COMMENT 'tokenizer "TokenDelimit"'
) DEFAULT CHARSET=UTF8 COMMENT='ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `tags` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `tags_index` (`tags`) COMMENT 'parser "TokenDelimit"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries (title, tags) VALUES ("Hello groonga!", "groonga install");
INSERT INTO diaries (title, tags) VALUES ("Hello mroonga!", "mroonga install");
SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
id title tags
1 Hello groonga! groonga install
SET GLOBAL mroonga_match_escalation_threshold = -1;
-CONNECT search_connection, localhost, root;
USE test;
SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
id title tags
-disconnect search_connection;
-connection default;
SET GLOBAL mroonga_match_escalation_threshold = DEFAULT;
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_match_escalation_threshold_session.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_match_escalation_threshold_session.result
index bedfb372e93..fa2da48cc71 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_match_escalation_threshold_session.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/variable_match_escalation_threshold_session.result
@@ -3,17 +3,8 @@ CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
tags TEXT,
-FULLTEXT INDEX tags_index (tags) COMMENT 'parser "TokenDelimit"'
+FULLTEXT INDEX tags_index (tags) COMMENT 'tokenizer "TokenDelimit"'
) DEFAULT CHARSET=UTF8 COMMENT='ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text DEFAULT NULL,
- `tags` text DEFAULT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `tags_index` (`tags`) COMMENT 'parser "TokenDelimit"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
INSERT INTO diaries (title, tags) VALUES ("Hello groonga!", "groonga install");
INSERT INTO diaries (title, tags) VALUES ("Hello mroonga!", "mroonga install");
SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("install" IN BOOLEAN MODE);
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column.test
index bb4d5389909..a6d25d3f438 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/not_embedded.inc
@@ -26,7 +26,6 @@ CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT
) DEFAULT CHARSET UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title) VALUES ("survey");
SELECT * FROM diaries;
@@ -39,8 +38,6 @@ INSERT INTO diaries (title, body) values ("groonga (1)", "starting groonga...");
INSERT INTO diaries (title, body) values ("groonga (2)", "started groonga.");
SELECT * FROM diaries;
-SHOW CREATE TABLE diaries;
-
DROP TABLE diaries;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column_multibyte_cp932.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column_multibyte_cp932.test
new file mode 100644
index 00000000000..49f65449a4d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column_multibyte_cp932.test
@@ -0,0 +1,54 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES cp932;
+
+CREATE TABLE users (
+ id int unsigned PRIMARY KEY AUTO_INCREMENT
+) DEFAULT CHARSET=cp932 COMMENT='Engine "InnoDB"';
+ALTER TABLE users
+ ADD COLUMN –¼‘O text,
+ ADD FULLTEXT INDEX (–¼‘O);
+
+INSERT INTO users (–¼‘O) VALUES ("‚â‚Ü‚¾");
+INSERT INTO users (–¼‘O) VALUES ("‚½‚È‚©");
+INSERT INTO users (–¼‘O) VALUES ("‚·‚¸‚«");
+
+SELECT * FROM users;
+
+SELECT * FROM users
+ WHERE MATCH (–¼‘O) AGAINST ('+‚½‚È‚©' IN BOOLEAN MODE);
+
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+
+DROP TABLE users;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column_multibyte_utf8.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column_multibyte_utf8.test
new file mode 100644
index 00000000000..bd5c7389bed
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_add_column_multibyte_utf8.test
@@ -0,0 +1,54 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE users (
+ id int unsigned PRIMARY KEY AUTO_INCREMENT
+) DEFAULT CHARSET=utf8 COMMENT='Engine "InnoDB"';
+ALTER TABLE users
+ ADD COLUMN åå‰ text,
+ ADD FULLTEXT INDEX (åå‰);
+
+INSERT INTO users (åå‰) VALUES ("ã‚„ã¾ã ");
+INSERT INTO users (åå‰) VALUES ("ãŸãªã‹");
+INSERT INTO users (åå‰) VALUES ("ã™ãšã");
+
+SELECT * FROM users;
+
+SELECT * FROM users
+ WHERE MATCH (åå‰) AGAINST ('+ãŸãªã‹' IN BOOLEAN MODE);
+
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+
+DROP TABLE users;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_change_column_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_change_column_comment.test
index a1d5c28baf1..dc98dc9c531 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_change_column_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_change_column_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_change_engine.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_change_engine.test
index e1b657b7ee8..d466b4466f1 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_change_engine.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_change_engine.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/not_embedded.inc
@@ -29,7 +29,9 @@ CREATE TABLE diaries (
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) ENGINE MyISAM DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
+SELECT table_name, engine, table_comment
+ FROM information_schema.tables
+ WHERE table_name = 'diaries';
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
@@ -38,7 +40,9 @@ SELECT * FROM diaries
MATCH(body) AGAINST("groonga" IN BOOLEAN MODE);
ALTER TABLE diaries ENGINE = mroonga COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
+SELECT table_name, engine, table_comment
+ FROM information_schema.tables
+ WHERE table_name = 'diaries';
SELECT * FROM diaries
WHERE MATCH(title) AGAINST("survey" IN BOOLEAN MODE) AND
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_comment_change_engine.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_comment_change_engine.test
index 645d3dad7b3..ff2b6b47ef1 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_comment_change_engine.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_comment_change_engine.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -28,14 +28,15 @@ CREATE TABLE memos (
content TEXT,
FULLTEXT INDEX(content)
) DEFAULT CHARSET=utf8 COMMENT='engine "InnoDB"';
-SHOW CREATE TABLE memos;
INSERT INTO memos (title, content) VALUES ("Hello", "I start to write memos!");
INSERT INTO memos (title, content) VALUES ("groonga", "I start to use groonga!");
INSERT INTO memos (title, content) VALUES ("mroonga", "I use mroonga too!");
ALTER TABLE memos COMMENT='engine "MyISAM"';
-SHOW CREATE TABLE memos;
+SELECT table_name, table_comment
+ FROM information_schema.tables
+ WHERE table_name = 'memos';
SELECT * FROM memos;
SELECT * FROM memos WHERE MATCH(content) AGAINST("start" IN BOOLEAN MODE);
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_create_fulltext.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_create_fulltext.test
index 68bf5c9bbe9..13344843ebe 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_create_fulltext.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_create_fulltext.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_fulltext.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_fulltext.test
index 0cd02e1812a..7bfd5fe5070 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_fulltext.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_fulltext.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_multiple_column.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_multiple_column.test
index 217df7a1edb..f05945e1b76 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_multiple_column.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_multiple_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_normal.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_normal.test
index ea3ef4f1484..f272698c1a8 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_normal.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_normal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_primary.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_primary.test
index 107f4a9a755..e1de36d25d1 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_primary.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_primary.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_updating.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_updating.test
index 3c63d4a1496..2c994bdcc76 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_updating.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_disable_keys_updating.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_drop_column.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_drop_column.test
index cc4b79ebf39..01fce22c3f0 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_drop_column.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_drop_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/not_embedded.inc
@@ -27,13 +27,11 @@ CREATE TABLE diaries (
title TEXT,
body TEXT
) DEFAULT CHARSET UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
SELECT * FROM diaries;
ALTER TABLE diaries DROP COLUMN body;
-SHOW CREATE TABLE diaries;
SELECT * FROM diaries;
INSERT INTO diaries (title) values ("groonga (1)");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_fulltext.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_fulltext.test
index e92a2e5c7f7..bc451c354b1 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_fulltext.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_fulltext.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_lock_tables.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_lock_tables.test
index f5f7e307d5d..66ee293bff1 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_lock_tables.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_lock_tables.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_multiple_column.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_multiple_column.test
index 587102c3db4..f364ba3d706 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_multiple_column.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_multiple_column.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_normal.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_normal.test
index 2f28eef1574..7b72b113c79 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_normal.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_normal.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_primary.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_primary.test
index aaff5f90b74..25cdc13ac35 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_primary.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_enable_keys_primary.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_fulltext.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_fulltext.test
index 62e56899aad..671b9617231 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_fulltext.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_fulltext.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/not_embedded.inc
@@ -27,7 +27,6 @@ CREATE TABLE diaries (
title TEXT,
FULLTEXT INDEX title_index (title)
) DEFAULT CHARSET UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title) VALUES ("survey");
SELECT * FROM diaries;
@@ -50,8 +49,6 @@ SELECT * FROM diaries
WHERE MATCH(title) AGAINST("groonga") AND
MATCH(body) AGAINST("starting");
-SHOW CREATE TABLE diaries;
-
DROP TABLE diaries;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_rename_table.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_rename_table.test
index c84e86594ca..288e5cdc0de 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_rename_table.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_rename_table.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/not_embedded.inc
@@ -29,7 +29,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) DEFAULT CHARSET UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
SELECT * FROM diaries;
@@ -43,8 +42,6 @@ SELECT * FROM memos
WHERE MATCH(title) AGAINST("groonga") AND
MATCH(body) AGAINST("starting");
-SHOW CREATE TABLE memos;
-
DROP TABLE memos;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test
index 34c8bc02a1d..bcc043485a0 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test
@@ -12,12 +12,12 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/not_embedded.inc
--source include/have_geometry.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -144,8 +144,6 @@ ALTER TABLE shops ADD SPATIAL KEY location_index (location);
SELECT id, name, ST_AsText(location) AS location_text FROM shops
WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location);
-SHOW CREATE TABLE shops;
-
DROP TABLE shops;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/auto_increment_text.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/auto_increment_text.test
index b4ebd69a5e9..57af6f121cc 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/auto_increment_text.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/auto_increment_text.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/binlog_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/binlog_TODO_SPLIT_ME.test
index 224bdfa07c6..1c120f36457 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/binlog_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/binlog_TODO_SPLIT_ME.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/have_log_bin.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/check_table_for_upgrade.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/check_table_for_upgrade.test
new file mode 100644
index 00000000000..c6d4a924691
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/check_table_for_upgrade.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ id int NOT NULL PRIMARY KEY,
+ content text,
+ FULLTEXT INDEX (content)
+) COMMENT='engine "InnoDB"';
+
+INSERT INTO memos VALUES (1, 'Hello MySQL');
+INSERT INTO memos VALUES (2, 'Hello Mroonga');
+
+CHECK TABLE memos FOR UPGRADE;
+
+FLUSH TABLES;
+
+SELECT * FROM memos
+ WHERE MATCH(content) AGAINST('+mroonga' IN BOOLEAN MODE);
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_comment_index_not_for_mroonga.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_comment_index_not_for_mroonga.test
index 2adbae8afd8..de195a5b981 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_comment_index_not_for_mroonga.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_comment_index_not_for_mroonga.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_add_column.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_add_column.test
new file mode 100644
index 00000000000..e10ecfe9b56
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_add_column.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+
+ALTER TABLE logs ADD COLUMN message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED;
+ALTER TABLE logs ADD FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"';
+
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_delete.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_delete.test
new file mode 100644
index 00000000000..784f419e24c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_delete.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+ FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+DELETE FROM logs WHERE id = 1;
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_drop_column.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_drop_column.test
new file mode 100644
index 00000000000..de2e40680df
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_drop_column.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+ FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+ALTER TABLE logs DROP COLUMN message;
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_insert.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_insert.test
new file mode 100644
index 00000000000..a8fcf191e08
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_insert.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+ FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_reindex.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_reindex.test
new file mode 100644
index 00000000000..db4f0ed4460
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_reindex.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+ FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+ALTER TABLE logs DISABLE KEYS;
+ALTER TABLE logs ENABLE KEYS;
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST("ar" IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_update.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_update.test
new file mode 100644
index 00000000000..a59e5b6c4f1
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_stored_update.test
@@ -0,0 +1,43 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED,
+ FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+UPDATE logs SET record = '{"level": "info", "message": "shutdown"}' WHERE id = 2;
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST("hut" IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_column.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_column.test
new file mode 100644
index 00000000000..502fb1502ff
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_column.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+
+ALTER TABLE logs ADD COLUMN message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL;
+
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_fulltext_index.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_fulltext_index.test
new file mode 100644
index 00000000000..5103a91e909
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_fulltext_index.test
@@ -0,0 +1,46 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mariadb_10_2_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record)
+ VALUES (1, '{"level": "info", "message": "start server"}');
+
+ALTER TABLE logs ADD FULLTEXT INDEX (message);
+
+INSERT INTO logs(id, record)
+ VALUES (2, '{"level": "info", "message": "start server"}');
+INSERT INTO logs(id, record)
+ VALUES (3, '{"level": "warn", "message": "abort server"}');
+
+SELECT * FROM logs WHERE MATCH(message) AGAINST('+start' IN BOOLEAN MODE);
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_index.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_index.test
new file mode 100644
index 00000000000..3b3b67c9747
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_add_index.test
@@ -0,0 +1,47 @@
+# Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ level VARCHAR(255) GENERATED ALWAYS AS
+ (json_unquote(json_extract(`record`, '$.level'))) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record)
+ VALUES (1, '{"level": "info", "message": "start server"}');
+
+ALTER TABLE logs ADD INDEX (level);
+
+INSERT INTO logs(id, record)
+ VALUES (2, '{"level": "info", "message": "start server"}');
+INSERT INTO logs(id, record)
+ VALUES (3, '{"level": "warn", "message": "abort server"}');
+
+SELECT * FROM logs WHERE level = 'info';
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_delete.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_delete.test
new file mode 100644
index 00000000000..73848a3f2cb
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_delete.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+DELETE FROM logs WHERE id = 1;
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_drop_column.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_drop_column.test
new file mode 100644
index 00000000000..cd5a9cb404b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_drop_column.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+ALTER TABLE logs DROP COLUMN message;
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_insert.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_insert.test
new file mode 100644
index 00000000000..a5180a973d5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_insert.test
@@ -0,0 +1,40 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_update.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_update.test
new file mode 100644
index 00000000000..c266ffe6ec5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_generated_virtual_update.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2017 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_version_5_7_or_later.inc
+--source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS logs;
+--enable_warnings
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY,
+ record JSON,
+ message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) VIRTUAL
+) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 COMMENT = 'ENGINE "InnoDB"';
+
+INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}');
+INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}');
+INSERT INTO logs(id, record) VALUES (3, '{"level": "warn", "message": "abort"}');
+
+UPDATE logs SET record = '{"level": "info", "message": "shutdown"}' WHERE id = 2;
+
+SELECT * FROM logs;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_multibyte_cp932.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_multibyte_cp932.test
new file mode 100644
index 00000000000..cea67376fa6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_multibyte_cp932.test
@@ -0,0 +1,53 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES cp932;
+
+CREATE TABLE users (
+ id int unsigned PRIMARY KEY AUTO_INCREMENT,
+ –¼‘O text,
+ FULLTEXT INDEX (–¼‘O)
+) DEFAULT CHARSET=cp932 COMMENT='Engine "InnoDB"';
+
+INSERT INTO users (–¼‘O) VALUES ("‚â‚Ü‚¾");
+INSERT INTO users (–¼‘O) VALUES ("‚½‚È‚©");
+INSERT INTO users (–¼‘O) VALUES ("‚·‚¸‚«");
+
+SELECT * FROM users;
+
+SELECT * FROM users
+ WHERE MATCH (–¼‘O) AGAINST ('+‚½‚È‚©' IN BOOLEAN MODE);
+
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+
+DROP TABLE users;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_multibyte_utf8.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_multibyte_utf8.test
new file mode 100644
index 00000000000..f1e0f39411f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_multibyte_utf8.test
@@ -0,0 +1,53 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS users;
+--enable_warnings
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE users (
+ id int unsigned PRIMARY KEY AUTO_INCREMENT,
+ åå‰ text,
+ FULLTEXT INDEX (åå‰)
+) DEFAULT CHARSET=utf8 COMMENT='Engine "InnoDB"';
+
+INSERT INTO users (åå‰) VALUES ("ã‚„ã¾ã ");
+INSERT INTO users (åå‰) VALUES ("ãŸãªã‹");
+INSERT INTO users (åå‰) VALUES ("ã™ãšã");
+
+SELECT * FROM users;
+
+SELECT * FROM users
+ WHERE MATCH (åå‰) AGAINST ('+ãŸãªã‹' IN BOOLEAN MODE);
+
+SELECT mroonga_command("dump --dump_plugins no --dump_records no");
+
+DROP TABLE users;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_normal_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_normal_comment.test
index 2e9674c860e..ba5786d05ab 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/column_normal_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/column_normal_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star.test
new file mode 100644
index 00000000000..b557a96518a
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star.test
@@ -0,0 +1,36 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS ids;
+--enable_warnings
+
+CREATE TABLE ids (
+ id int PRIMARY KEY
+) COMMENT='ENGINE "InnoDB"';
+
+INSERT INTO ids VALUES (1);
+INSERT INTO ids VALUES (2);
+INSERT INTO ids VALUES (3);
+
+SELECT COUNT(*) FROM ids;
+
+DROP TABLE ids;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_mysql_5_7_or_later_with_index.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_mysql_5_7_or_later_with_index.test
new file mode 100644
index 00000000000..b329d9a5ff6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_mysql_5_7_or_later_with_index.test
@@ -0,0 +1,55 @@
+# Copyright(C) 2011-2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+CREATE TABLE diaries_innodb (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ body TEXT,
+ flag TINYINT(2),
+ INDEX (flag)
+) ENGINE = InnoDB DEFAULT CHARSET UTF8;
+
+CREATE TABLE diaries_mroonga (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ body TEXT,
+ flag TINYINT(2),
+ INDEX (flag)
+) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET UTF8;
+
+INSERT INTO diaries_innodb (body) VALUES ("will start groonga!");
+INSERT INTO diaries_innodb (body) VALUES ("starting groonga...");
+INSERT INTO diaries_innodb (body) VALUES ("started groonga.");
+
+INSERT INTO diaries_mroonga (body) VALUES ("will start groonga!");
+INSERT INTO diaries_mroonga (body) VALUES ("starting groonga...");
+INSERT INTO diaries_mroonga (body) VALUES ("started groonga.");
+
+EXPLAIN SELECT COUNT(*) FROM diaries_innodb;
+EXPLAIN SELECT COUNT(*) FROM diaries_mroonga;
+
+DROP TABLE diaries_innodb;
+DROP TABLE diaries_mroonga;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test
index 6fd0ff1971c..0a3a5c81865 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,9 +12,10 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
+--source ../../include/mroonga/skip_mysql_5_7_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_query_log
@@ -45,7 +46,9 @@ INSERT INTO diaries_mroonga (body) VALUES ("will start groonga!");
INSERT INTO diaries_mroonga (body) VALUES ("starting groonga...");
INSERT INTO diaries_mroonga (body) VALUES ("started groonga.");
+-- replace_column 9 #
EXPLAIN SELECT COUNT(*) FROM diaries_innodb;
+-- replace_column 9 #
EXPLAIN SELECT COUNT(*) FROM diaries_mroonga;
DROP TABLE diaries_innodb;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_TODO_SPLIT_ME.test
index 4eab593cfe7..1c0d445013c 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_TODO_SPLIT_ME.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -65,6 +65,8 @@ create table t1 (c1 time primary key) COMMENT = 'engine "innodb"';
desc t1;
drop table t1;
create table t1 (c1 timestamp primary key) COMMENT = 'engine "innodb"';
+# For MariaDB 10.2.3
+-- replace_result current_timestamp() CURRENT_TIMESTAMP
desc t1;
drop table t1;
create table t1 (c1 datetime primary key) COMMENT = 'engine "innodb"';
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_comment_combined.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_comment_combined.test
index f2d4cf80e3a..eaad5ed47cf 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_comment_combined.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_comment_combined.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,7 @@ CREATE TABLE bugs (
) DEFAULT CHARSET=utf8
COMMENT='Free style normal comment, engine "InnoDB"';
-SHOW CREATE TABLE bugs;
+SELECT mroonga_command("dump --dump_plugins no");
DROP TABLE bugs;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test
index aa6b1f01f10..6daa5acfd0f 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test
index d116aa6cd34..22d28e941fd 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test
index 3c6bb52d143..c3b689580f6 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
--source include/have_innodb.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_index_flags_none.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_index_flags_none.test
index b433e54e885..06cb7658c21 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_index_flags_none.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_index_flags_none.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_index_flags_with_position_and_with_weight.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_index_flags_with_position_and_with_weight.test
index 47cededee55..84dc9d8526a 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_index_flags_with_position_and_with_weight.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_index_flags_with_position_and_with_weight.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test
index 0d26c751c22..8846821cfc1 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_fulltext_index_bin.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_fulltext_index_bin.test
new file mode 100644
index 00000000000..5454b176313
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_fulltext_index_bin.test
@@ -0,0 +1,40 @@
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ id INT NOT NULL PRIMARY KEY,
+ content TEXT NOT NULL,
+ FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+SHOW CREATE TABLE memos;
+
+INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ");
+
+SELECT * FROM memos
+ WHERE MATCH (content) AGAINST ("+カロリー" IN BOOLEAN MODE);
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test
index 141d15c3c45..287d594b7f5 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
--source include/have_innodb.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_parser_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_parser_comment.test
index 151d15a9870..54d63fbe49c 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_parser_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_parser_comment.test
@@ -12,8 +12,9 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+--source include/not_embedded.inc
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +28,6 @@ create table diaries (
fulltext index body_index (body)
comment 'parser "TokenBigramSplitSymbolAlphaDigit"'
) comment = 'engine "innodb"' default charset utf8;
-show create table diaries;
insert into diaries (body) values ("will start Groonga!");
insert into diaries (body) values ("starting Groonga...");
insert into diaries (body) values ("started Groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_multiple_token_filters.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_multiple_token_filters.test
index d5487a3b828..c79744993e9 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_multiple_token_filters.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_multiple_token_filters.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_one_token_filter.test
index 0d863c9f99f..80bb5cf8701 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_one_token_filter.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_one_token_filter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test
index 0532c19dbde..99343ec60cf 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
--source include/have_innodb.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_comment.test
index 0a55dd6ae69..e3e6d671ac6 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_comment.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ create table diaries (
fulltext index body_index (body)
comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
) comment = 'engine "innodb"' default charset utf8;
-show create table diaries;
insert into diaries (body) values ("will start Groonga!");
insert into diaries (body) values ("starting Groonga...");
insert into diaries (body) values ("started Groonga.");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_parameter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_parameter.test
index a2087ca8a9f..3eadb51a73a 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_parameter.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_parameter.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mariadb.inc
--source include/have_innodb.inc
@@ -27,7 +27,6 @@ CREATE TABLE diaries (
body text,
FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit'
) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET utf8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (body) VALUES ("will start Groonga!");
INSERT INTO diaries (body) VALUES ("starting Groonga...");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/delete_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/delete_TODO_SPLIT_ME.test
index dae9bf033ca..b06a6067144 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/delete_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/delete_TODO_SPLIT_ME.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/delete_all.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/delete_all.test
index b25fc596813..ca33da8c309 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/delete_all.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/delete_all.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/drop_table_new_connection.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/drop_table_new_connection.test
new file mode 100644
index 00000000000..c0f492d1920
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/drop_table_new_connection.test
@@ -0,0 +1,46 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source include/not_embedded.inc
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ message TEXT,
+ FULLTEXT INDEX (message)
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+
+disable_query_log;
+CONNECT(drop_connection, localhost, root);
+enable_query_log;
+
+USE test;
+DROP TABLE logs;
+
+disable_query_log;
+CONNECTION default;
+enable_query_log;
+
+CREATE TABLE logs (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ message TEXT,
+ FULLTEXT INDEX (message)
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+
+DROP TABLE logs;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_leading_not.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_leading_not.test
index d835a20746c..0234f831fb1 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_leading_not.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_leading_not.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,6 @@ CREATE TABLE diaries (
content TEXT,
FULLTEXT INDEX (content)
) DEFAULT CHARSET = UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_multiple_match_against.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_multiple_match_against.test
index 9882883e597..73de4d5e70e 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_multiple_match_against.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_multiple_match_against.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -29,7 +29,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX (title),
FULLTEXT INDEX (content)
) DEFAULT CHARSET = UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, "富士山", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, "天気 1月1日", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_no_operator.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_no_operator.test
index 1e57b56d6b0..14fba8d2275 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_no_operator.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_no_operator.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_with_or.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_with_or.test
index 3fdad5365fe..9cfd841b753 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_with_or.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_with_or.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_with_plus.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_with_plus.test
index 53251eb2af7..b28caa87e2f 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_with_plus.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_minus_with_plus.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
index f46f732203b..1dfdc49695b 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
index 8f8130b7b45..66f7aaf880e 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
index 6fa65d395ee..54278e97681 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_no_operator.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_no_operator.test
index 9d7f887c98d..459fd913552 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_no_operator.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_no_operator.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_with_minus.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_with_minus.test
index 7feca394fa5..3245501d6b7 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_with_minus.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_with_minus.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_with_or.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_with_or.test
index ade88c9c60d..0e69941134e 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_with_or.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_plus_with_or.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_full_spec.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_full_spec.test
index ecc1e0d0bad..3191ff6c44c 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_full_spec.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_full_spec.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_no_weight.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_no_weight.test
index 384b951f562..90216c0a438 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_no_weight.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_no_weight.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_omit_section.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_omit_section.test
index f259fc85388..4a5512791a1 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_omit_section.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_weight_omit_section.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_ascii.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_ascii.test
index 4cec44d01a2..27af7f5d880 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_ascii.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_ascii.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_cp932.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_cp932.test
index 169069fb67d..912b3c9eec1 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_cp932.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_cp932.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/have_cp932.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_eucjpms.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_eucjpms.test
index cda39ce2ad6..56309998b42 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_eucjpms.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_eucjpms.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/have_eucjpms.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_japanese.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_japanese.test
index 93e78d6b46d..589b4d79dcf 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_japanese.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_charset_japanese.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_index_recreate.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_index_recreate.test
index 27af190ed7a..6b07647625d 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_index_recreate.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_index_recreate.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,6 @@ CREATE TABLE diaries (
content text,
FULLTEXT INDEX (title)
) DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES (1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES (2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test
index 083384b04d1..d4364af2da7 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -29,7 +29,11 @@ insert into t1 values (2, "ka ki ku ke ko");
insert into t1 values (3, "aa ii ii ii oo");
insert into t1 values (4, "sa si su se so");
insert into t1 values (5, "ta ti ii ii to");
-insert into t2 (c1,c2) select c1,c2 from t1;
+insert into t2 values (1, "aa ii uu ee oo");
+insert into t2 values (2, "ka ki ku ke ko");
+insert into t2 values (3, "aa ii ii ii oo");
+insert into t2 values (4, "sa si su se so");
+insert into t2 values (5, "ta ti ii ii to");
select * from t1;
select * from t2;
select * from t1 where c1=3;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_values.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_values.test
index f4b76888b76..ea76dd055db 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_values.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_values.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,7 +23,6 @@ drop table if exists t1, t2, t3;
--enable_warnings
create table t1 (c1 int primary key, c2 text, fulltext index ft (c2)) COMMENT = 'engine "innodb"';
-show create table t1;
insert into t1 values (1, "hoge hoge");
insert into t1 values (2, "fuga fuga");
insert into t1 values (3, "moge moge");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test
index 07750416342..38e17700269 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ create table diaries (
title varchar(255),
fulltext index (title)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
set autocommit=0;
insert into diaries values(0, "2011-07-14");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test
index 52700ad01fe..61ef72370f0 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test
index b362acd4565..1cc2f6c297a 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -35,13 +35,16 @@ INSERT INTO texts VALUES (1, 'Hello1', 'World1');
INSERT INTO texts VALUES (2, 'Hello2', 'World2');
INSERT INTO texts VALUES (3, 'Hello3', 'World3');
-SELECT id,
- matched,
- not_matched,
- MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
- MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
- FROM texts
- WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE);
+SELECT *
+ FROM (SELECT id,
+ matched,
+ not_matched,
+ MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
+ MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
+ FROM texts
+ WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE))
+ AS searched_texts
+ ORDER BY id;
DROP TABLE texts;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test
index fa8fb79634d..673ed5619d9 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_delete.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_delete.test
index d6defc1fca2..2d2ffe7b014 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_delete.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_delete.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ create table diaries (
fulltext index (title),
fulltext index (content)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_insert.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_insert.test
index ebf5c37ad94..81047e78302 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_insert.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_insert.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ create table diaries (
fulltext index (title),
fulltext index (content)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_recreate.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_recreate.test
index 8ae0dd8892b..037784e4251 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_recreate.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_recreate.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ create table diaries (
fulltext index (title),
fulltext index (content)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_update.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_update.test
index a6c12aa1714..72662d78093 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_update.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_column_index_update.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -30,7 +30,6 @@ create table diaries (
fulltext index (title),
fulltext index (content)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
insert into diaries values(1, "Hello", "ã¯ã˜ã‚ã¾ã—ãŸã€‚");
insert into diaries values(2, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
insert into diaries values(3, "富士山", "今日もãã‚Œã„。");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_index.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_index.test
index 58c0ea3faf7..8ecb8eeec65 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_index.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_multiple_index.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,6 @@ create table diaries (
fulltext index title_index (title),
fulltext index body_index (body)
) comment = 'engine "innodb"' default charset utf8;
-show create table diaries;
insert into diaries (title, body) values ("survey", "will start groonga!");
insert into diaries (title, body) values ("groonga (1)", "starting groonga...");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test
index 305f51d4a02..818624392a4 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -22,7 +22,6 @@ drop table if exists t1, t2, t3;
--enable_warnings
create table t1 (c1 int primary key, c2 text, fulltext index ft (c2)) COMMENT = 'engine "myisam"';
-show create table t1;
insert into t1 values (1, "hoge hoge");
insert into t1 values (2, "fuga fuga");
insert into t1 values (3, "moge moge");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test
index 7fcffefd234..d65fdefd647 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test
index cba565b0253..55813bd3fdc 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -23,14 +23,13 @@ DROP TABLE IF EXISTS diaries;
SET NAMES UTF8;
CREATE TABLE ft(
- a INT,
+ a INT DEFAULT 0,
b TEXT,
c TEXT,
PRIMARY KEY(a),
FULLTEXT KEY ftx1(b),
FULLTEXT KEY ftx2(c)
)ENGINE=Mroonga DEFAULT CHARSET=UTF8 COMMENT = 'engine "innodb"';
-SHOW CREATE TABLE ft;
INSERT INTO ft VALUES(1,'aaaaa','abcde');
INSERT INTO ft VALUES(2,'bbbbb','bcdef');
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_transaction.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_transaction.test
index 825cf361546..bcab5307e18 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_transaction.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_transaction.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET=UTF8;
-SHOW CREATE TABLE diaries;
START TRANSACTION;
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
@@ -39,22 +38,32 @@ SELECT * FROM diaries
WHERE MATCH(body) AGAINST("groonga")
ORDER BY id;
+disable_query_log;
CONNECT(search_connection, localhost, root);
+enable_query_log;
USE test;
SELECT * FROM diaries
WHERE MATCH(body) AGAINST("groonga")
ORDER BY id;
+disable_query_log;
CONNECTION default;
+enable_query_log;
COMMIT;
+disable_query_log;
CONNECTION search_connection;
+enable_query_log;
SELECT * FROM diaries
WHERE MATCH(body) AGAINST("groonga")
ORDER BY id;
+disable_query_log;
DISCONNECT search_connection;
+enable_query_log;
+disable_query_log;
CONNECTION default;
+enable_query_log;
SELECT * FROM diaries
WHERE MATCH(body) AGAINST("groonga")
ORDER BY id;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/function_last_insert_id_reference.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/function_last_insert_id_reference.test
index 2cfd00b2172..f08337af9d1 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/function_last_insert_id_reference.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/function_last_insert_id_reference.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/function_last_insert_id_set.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/function_last_insert_id_set.test
index b5f7dd80c31..d1be7ae64da 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/function_last_insert_id_set.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/function_last_insert_id_set.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_contains.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_contains.test
index 88fa88427cf..8c669052d2e 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_contains.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_contains.test
@@ -12,11 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/have_geometry.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -29,7 +29,6 @@ create table shops (
location geometry NOT NULL,
spatial key location_index (location)
) comment = 'engine "innodb"';
-show create table shops;
insert into shops (name, location)
values ('nezu-no-taiyaki',
ST_GeomFromText('POINT(139.762573 35.720253)'));
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_delete.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_delete.test
index 655a8416725..3a4d399beec 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_delete.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_delete.test
@@ -12,11 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/have_geometry.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -29,7 +29,6 @@ create table shops (
location geometry NOT NULL,
spatial key location_index (location)
) comment = 'engine "innodb"';
-show create table shops;
insert into shops (name, location)
values ('sazare',
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_update.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_update.test
index 6a734958158..db7aa344e0a 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_update.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/geometry_update.test
@@ -12,11 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/have_geometry.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -29,7 +29,6 @@ create table shops (
location geometry NOT NULL,
spatial key location_index (location)
) comment = 'engine "innodb"';
-show create table shops;
insert into shops (name, location)
values ('sazare',
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/index_force_index_not_used.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/index_force_index_not_used.test
index b7a4dd4c36b..1c73f30b60c 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/index_force_index_not_used.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/index_force_index_not_used.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_TODO_SPLIT_ME.test
index 87947f1ea6c..021d3f8e95d 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_TODO_SPLIT_ME.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_bulk.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_bulk.test
index a5edb8bae4a..b21dcc5b893 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_bulk.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_bulk.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -27,7 +27,6 @@ create table diaries (
content text,
fulltext index (content)
) default charset utf8 comment = 'engine "innodb"';
-show create table diaries;
LOCK TABLE diaries WRITE;
insert into diaries values(1, "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_on_duplicate_key_update_multiple_column_primary_key_myisam.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_on_duplicate_key_update_multiple_column_primary_key_myisam.test
index d16527644e3..3006bac6d21 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_on_duplicate_key_update_multiple_column_primary_key_myisam.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_on_duplicate_key_update_multiple_column_primary_key_myisam.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -26,6 +26,8 @@ CREATE TABLE diaries (
content TEXT NOT NULL,
PRIMARY KEY (date, title)
) DEFAULT CHARSET=UTF8 COMMENT='ENGINE "MyISAM"';
+# For MariaDB 10.2.3
+-- replace_result current_timestamp() CURRENT_TIMESTAMP
SHOW CREATE TABLE diaries;
INSERT INTO diaries (date, title, content)
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_on_duplicate_key_update_multiple_column_unique_index_myisam.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_on_duplicate_key_update_multiple_column_unique_index_myisam.test
index d97823f77a2..ae993b76b09 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_on_duplicate_key_update_multiple_column_unique_index_myisam.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/insert_on_duplicate_key_update_multiple_column_unique_index_myisam.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mroonga.inc
@@ -27,6 +27,8 @@ CREATE TABLE diaries (
content TEXT NOT NULL,
UNIQUE INDEX (date, title)
) DEFAULT CHARSET=UTF8 COMMENT='ENGINE "MyISAM"';
+# For MariaDB 10.2.3
+-- replace_result current_timestamp() CURRENT_TIMESTAMP
SHOW CREATE TABLE diaries;
INSERT INTO diaries (date, title, content)
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/multi_range_read_disk_sweep.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/multi_range_read_disk_sweep.test
index dbe11f03bec..ce9cf85e7dc 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/multi_range_read_disk_sweep.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/multi_range_read_disk_sweep.test
@@ -1,5 +1,5 @@
# Copyright(C) 2013 Kenji Maruyama <mmmaru777@gmail.com>
-# Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2013-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,10 +13,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source ../../include/mroonga/have_mysql.inc
---source ../../include/mroonga/have_version_56_or_later.inc
+--source ../../include/mroonga/have_version_5_6_or_later.inc
+--source ../../include/mroonga/skip_mysql_5_7_or_later.inc
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/multi_range_read_mysql_5_7_or_later_disk_sweep.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/multi_range_read_mysql_5_7_or_later_disk_sweep.test
new file mode 100644
index 00000000000..fb6529ef782
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/multi_range_read_mysql_5_7_or_later_disk_sweep.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2013 Kenji Maruyama <mmmaru777@gmail.com>
+# Copyright(C) 2013-2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+--source ../../include/mroonga/have_mysql_5_7_or_later.inc
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS integers;
+--enable_warnings
+
+SET optimizer_switch='mrr_cost_based=off';
+
+CREATE TABLE integers (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ value INT,
+ KEY (value)
+) COMMENT='engine "InnoDB"';
+
+INSERT INTO integers (value) VALUES (0), (1), (2), (3);
+
+EXPLAIN SELECT * FROM integers
+ WHERE value IN (0, 2);
+
+SELECT * FROM integers
+ WHERE value IN (0, 2);
+
+DROP TABLE integers;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_TODO_SPLIT_ME.test
index 078e0b6e28e..9aeeef0e842 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_TODO_SPLIT_ME.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_no_direction.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_no_direction.test
index 07a497d7871..4a2338714e4 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_no_direction.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_no_direction.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_no_where_clause.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_no_where_clause.test
index a74db4417b2..8b8e4754dc2 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_no_where_clause.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_no_where_clause.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_order_by_primary_key.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_order_by_primary_key.test
index 25a02398a66..f1b6ad62c88 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_order_by_primary_key.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/optimization_order_limit_order_by_primary_key.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/performance_schema.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/performance_schema.test
index 7d663bef626..5ea33c4e150 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/performance_schema.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/performance_schema.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/not_embedded.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_files.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_files.test
index d11a3efe900..31b43712261 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_files.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_files.test
@@ -12,10 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/not_embedded.inc
+--source ../../include/mroonga/skip_solaris.inc
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_mroonga_helper.inc
@@ -28,7 +29,6 @@ CREATE TABLE diaries (
body TEXT,
FULLTEXT INDEX body_index (body)
) COMMENT = 'engine "innodb"' DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
@@ -36,13 +36,7 @@ INSERT INTO diaries (title, body) VALUES ("groonga (2)", "started groonga.");
SELECT * FROM diaries WHERE MATCH(body) AGAINST("starting");
---remove_file $MYSQLD_DATADIR/repair_test.mrn
---remove_file $MYSQLD_DATADIR/repair_test.mrn.001
---remove_file $MYSQLD_DATADIR/repair_test.mrn.0000000
---remove_file $MYSQLD_DATADIR/repair_test.mrn.0000105
---remove_file $MYSQLD_DATADIR/repair_test.mrn.0000106
---remove_file $MYSQLD_DATADIR/repair_test.mrn.0000107
---remove_file $MYSQLD_DATADIR/repair_test.mrn.0000107.c
+--remove_files_wildcard $MYSQLD_DATADIR repair_test.mrn*
FLUSH TABLES;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_index_file.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_index_file.test
index 6d09479e554..f2b1f63a8e0 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_index_file.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/repair_table_no_index_file.test
@@ -12,10 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source include/not_embedded.inc
+--source ../../include/mroonga/skip_solaris.inc
--source ../../include/mroonga/have_mroonga.inc
--source ../../include/mroonga/have_mroonga_helper.inc
@@ -28,7 +29,6 @@ CREATE TABLE diaries (
body TEXT,
FULLTEXT INDEX body_index (body)
) COMMENT = 'engine "innodb"' DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
@@ -36,14 +36,11 @@ INSERT INTO diaries (title, body) VALUES ("groonga (2)", "started groonga.");
SELECT * FROM diaries WHERE MATCH(body) AGAINST("starting");
---remove_file $MYSQLD_DATADIR/repair_test.mrn.0000106
+--remove_file $MYSQLD_DATADIR/repair_test.mrn.000010A
FLUSH TABLES;
-# Error ER_CANT_OPEN_FILE syscall error 'repair_test.mrn.0000104' (No such file or directory)
-# The (Error 0)[0]" replaces is for Solaris
-#
---replace_result "(Error 0)[0]" "(No such file or directory)"
+# Error ER_CANT_OPEN_FILE system call error: No such file or directory: failed to open path: <repair_test.mrn.000010A>
--error ER_CANT_OPEN_FILE
SELECT * FROM diaries WHERE MATCH(body) AGAINST("starting");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/temporary_table.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/temporary_table.test
index 7d98ca0bfa7..143270dcf20 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/temporary_table.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/temporary_table.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/skip_osx.inc
@@ -27,7 +27,6 @@ CREATE TEMPORARY TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT
) DEFAULT CHARSET=UTF8 COMMENT = 'ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title) VALUES ("clear day");
INSERT INTO diaries (title) VALUES ("rainy day");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_query_cache.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_query_cache.test
index 9055715486b..7c848641626 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_query_cache.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_query_cache.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -31,22 +31,32 @@ SHOW CREATE TABLE simple_table;
INSERT INTO simple_table (id) VALUES (1),(2);
+disable_query_log;
CONNECT(second_connection, localhost, root);
+enable_query_log;
USE test;
START TRANSACTION;
INSERT INTO simple_table (id) VALUES (3);
+disable_query_log;
CONNECTION default;
+enable_query_log;
SELECT * FROM simple_table;
+disable_query_log;
CONNECTION second_connection;
+enable_query_log;
COMMIT;
+disable_query_log;
CONNECTION default;
+enable_query_log;
SELECT * FROM simple_table;
DROP TABLE simple_table;
+disable_query_log;
DISCONNECT second_connection;
+enable_query_log;
SET GLOBAL query_cache_size = @tmp_query_cache_size;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_rollback_delete_delete.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_rollback_delete_delete.test
index dd08d93cd47..f11ca4a9839 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_rollback_delete_delete.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_rollback_delete_delete.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_rollback_delete_update.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_rollback_delete_update.test
index ae9099a7ab9..36bc09be73b 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_rollback_delete_update.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/transaction_rollback_delete_update.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -28,7 +28,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX title_index (title),
FULLTEXT INDEX body_index (body)
) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, body) VALUES ("survey", "will start groonga!");
INSERT INTO diaries (title, body) VALUES ("groonga (1)", "starting groonga...");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test
index 1920237fdad..b021b26b5e3 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -32,7 +32,6 @@ CREATE TABLE diaries (
FULLTEXT INDEX(content),
KEY(day)
) DEFAULT CHARSET UTF8 COMMENT = 'engine "innodb"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries VALUES(1, 2011, 11, 9, "Hello", "今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚");
INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/update_fulltext.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/update_fulltext.test
index 7afeee05ffd..9052c434c31 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/update_fulltext.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/update_fulltext.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/update_int.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/update_int.test
index db1e2da9a18..ffa26994efe 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/update_int.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/update_int.test
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_delete.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_delete.test
index 2757c94b4c5..c6f2a2a14da 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_delete.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_delete.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ create table diaries (
body text,
fulltext index body_index (body)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
insert into diaries (body) values ("will start groonga!");
insert into diaries (body) values ("starting groonga...");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_insert.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_insert.test
index 5e958528275..b80f60fcba5 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_insert.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_insert.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ create table diaries (
body text,
fulltext index body_index (body)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
insert into diaries (body) values ("will start groonga!");
select * from diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_update.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_update.test
index 8e9a9e3308a..ab75babfbac 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_update.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_dry_write_update.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -26,7 +26,6 @@ create table diaries (
body text,
fulltext index body_index (body)
) default charset utf8 COMMENT = 'engine "innodb"';
-show create table diaries;
insert into diaries (body) values ("will start groonga!");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test
index ead26bca2c1..71d44ab5704 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -25,9 +25,8 @@ CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
tags TEXT,
- FULLTEXT INDEX tags_index (tags) COMMENT 'parser "TokenDelimit"'
+ FULLTEXT INDEX tags_index (tags) COMMENT 'tokenizer "TokenDelimit"'
) DEFAULT CHARSET=UTF8 COMMENT='ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, tags) VALUES ("Hello groonga!", "groonga install");
INSERT INTO diaries (title, tags) VALUES ("Hello mroonga!", "mroonga install");
@@ -41,11 +40,17 @@ SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
SET GLOBAL mroonga_match_escalation_threshold = -1;
--enable_warnings
+disable_query_log;
CONNECT(search_connection, localhost, root);
+enable_query_log;
USE test;
+
SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
+
+disable_query_log;
DISCONNECT search_connection;
CONNECTION default;
+enable_query_log;
SET GLOBAL mroonga_match_escalation_threshold = DEFAULT;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test
index 5f5ae169890..91196faf612 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test
@@ -12,7 +12,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
@@ -25,9 +25,8 @@ CREATE TABLE diaries (
id INT PRIMARY KEY AUTO_INCREMENT,
title TEXT,
tags TEXT,
- FULLTEXT INDEX tags_index (tags) COMMENT 'parser "TokenDelimit"'
+ FULLTEXT INDEX tags_index (tags) COMMENT 'tokenizer "TokenDelimit"'
) DEFAULT CHARSET=UTF8 COMMENT='ENGINE "InnoDB"';
-SHOW CREATE TABLE diaries;
INSERT INTO diaries (title, tags) VALUES ("Hello groonga!", "groonga install");
INSERT INTO diaries (title, tags) VALUES ("Hello mroonga!", "mroonga install");
diff --git a/storage/mroonga/packages/apt/Makefile.am b/storage/mroonga/packages/apt/Makefile.am
index ca0e1dcb19d..0ebc7f67d04 100644
--- a/storage/mroonga/packages/apt/Makefile.am
+++ b/storage/mroonga/packages/apt/Makefile.am
@@ -1,11 +1,12 @@
REPOSITORIES_PATH = repositories
DISTRIBUTIONS = debian
ARCHITECTURES = i386 amd64
-CODE_NAMES = wheezy jessie
+CODE_NAMES = jessie stretch
+MYSQL_VARIANTS = 5.5 mariadb-10.0
all:
-release: build sign-packages update-repository sign-repository upload
+release: download build sign-packages update-repository sign-repository upload
remove-existing-packages:
for distribution in $(DISTRIBUTIONS); do \
@@ -45,21 +46,44 @@ upload: ensure-rsync-path
build: build-package-deb
-build-package-deb: prepare-build-package-deb
+build-package-deb: source env.sh
vagrant destroy --force
- for architecture in $(ARCHITECTURES); do \
- for code_name in $(CODE_NAMES); do \
- id=debian-$$code_name-$$architecture; \
- vagrant up $$id || exit 1; \
- vagrant destroy --force $$id; \
+ for variant in $(MYSQL_VARIANTS); do \
+ cp env.sh tmp/; \
+ echo "MYSQL_VARIANT=$${variant}" >> tmp/env.sh; \
+ for architecture in $(ARCHITECTURES); do \
+ for code_name in $(CODE_NAMES); do \
+ rm -rf tmp/debian; \
+ if [ $${variant} = "5.5" -a $${code_name} = "stretch" ]; then \
+ continue; \
+ fi; \
+ if [ $${code_name} = "stretch" ]; then \
+ cp -rp $(srcdir)/../debian-mariadb-10.0 tmp/debian; \
+ for f in `find tmp/debian -maxdepth 2 -type f`; do \
+ RENAMED=`echo $$f | sed 's/10.0/10.1/'`; \
+ sed -i'' 's/10.0/10.1/g' $${f}; \
+ if [ $${f} = $$RENAMED ]; then \
+ continue; \
+ fi; \
+ mv $${f} $$RENAMED; \
+ done; \
+ if [ $${architecture} = "amd64" ]; then \
+ sed -i'' 's,lib/mysql/,lib/x86_64-linux-gnu/mariadb18/,' \
+ tmp/debian/mariadb-server-10.1-mroonga.install; \
+ elif [ $${architecture} = "i386" ]; then \
+ sed -i'' 's,lib/mysql/,lib/i386-linux-gnu/mariadb18/,' \
+ tmp/debian/mariadb-server-10.1-mroonga.install; \
+ fi; \
+ else \
+ cp -rp $(srcdir)/../debian-$${variant} tmp/debian; \
+ fi; \
+ id=debian-$$code_name-$$architecture; \
+ vagrant up $$id || exit 1; \
+ vagrant destroy --force $$id; \
+ done; \
done; \
done
-prepare-build-package-deb: source env.sh
- cp env.sh tmp/
- rm -rf tmp/debian
- cp -rp $(srcdir)/../debian tmp/
-
source: tmp/$(PACKAGE)-$(VERSION).tar.gz
tmp/$(PACKAGE)-$(VERSION).tar.gz: $(abs_top_builddir)/$(PACKAGE)-$(VERSION).tar.gz
diff --git a/storage/mroonga/packages/apt/Vagrantfile b/storage/mroonga/packages/apt/Vagrantfile
index 2829da879dd..ee4a6aebc23 100644
--- a/storage/mroonga/packages/apt/Vagrantfile
+++ b/storage/mroonga/packages/apt/Vagrantfile
@@ -7,30 +7,43 @@ VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
vms = [
{
- :id => "debian-wheezy-i386",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-7.8-i386_chef-provisionerless.box",
+ :id => "debian-jessie-i386",
+ :box => "bento/debian-8.9-i386",
},
{
- :id => "debian-wheezy-amd64",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-7.8_chef-provisionerless.box",
+ :id => "debian-jessie-amd64",
+ :box => "bento/debian-8.9",
},
{
- :id => "debian-jessie-i386",
- :box_url => "http://packages.groonga.org/tmp/opscode_debian-8.0-i386_chef-provisionerless.box",
+ :id => "debian-stretch-i386",
+ :box => "bento/debian-9.1-i386",
},
{
- :id => "debian-jessie-amd64",
- :box_url => "http://packages.groonga.org/tmp/opscode_debian-8.0_chef-provisionerless.box",
+ :id => "debian-stretch-amd64",
+ :box => "bento/debian-9.1",
},
]
vms.each do |vm|
config.vm.define(vm[:id]) do |node|
- node.vm.box = vm[:id]
- node.vm.box_url = vm[:box_url]
+ # Use official box
+ node.vm.box = vm[:box] if vm[:box]
+ # Use box and box_url until official box is released
+ node.vm.box = vm[:id] if vm[:box_url]
+ node.vm.box_url = vm[:box_url] if vm[:box_url]
node.vm.provision(:shell, :path => "build-deb.sh")
node.vm.provider("virtualbox") do |virtual_box|
- virtual_box.memory = 768
+ system_n_cpus = 1
+ if File.exist?("/proc/cpuinfo")
+ system_n_cpus = File.readlines("/proc/cpuinfo").grep(/^processor/).size
+ end
+ if system_n_cpus > 1
+ vm_n_cpus = system_n_cpus / 2
+ else
+ vm_n_cpus = 1
+ end
+ virtual_box.cpus = (ENV["VM_CPUS"] || vm_n_cpus).to_i
+ virtual_box.memory = (ENV["VM_MEMORY"] || 768).to_i
end
end
end
diff --git a/storage/mroonga/packages/apt/build-deb.sh b/storage/mroonga/packages/apt/build-deb.sh
index 510886cb24f..e0e03d8ec15 100755
--- a/storage/mroonga/packages/apt/build-deb.sh
+++ b/storage/mroonga/packages/apt/build-deb.sh
@@ -2,8 +2,6 @@
LANG=C
-mysql_server_package=mysql-server
-
run()
{
"$@"
@@ -15,14 +13,37 @@ run()
. /vagrant/tmp/env.sh
+code_name=$(lsb_release --codename --short)
+case "${MYSQL_VARIANT}" in
+ mariadb-*)
+ case "${code_name}" in
+ stretch)
+ mysql_server_package=mariadb-server-10.1
+ MYSQL_VARIANT=mariadb-10.1
+ ;;
+ *)
+ mysql_server_package=mariadb-server-${MYSQL_VARIANT##mariadb-}
+ ;;
+ esac
+ DEPENDED_PACKAGES="${DEPENDED_PACKAGES} libmariadb-client-lgpl-dev"
+ DEPENDED_PACKAGES="${DEPENDED_PACKAGES} libmariadbd-dev"
+ ;;
+ *)
+ mysql_server_package=mysql-server-${MYSQL_VARIANT}
+ DEPENDED_PACKAGES="${DEPENDED_PACKAGES} libmysqlclient-dev"
+ DEPENDED_PACKAGES="${DEPENDED_PACKAGES} libmysqld-dev"
+ ;;
+esac
+
grep '^deb ' /etc/apt/sources.list | \
sed -e 's/^deb /deb-src /' > /etc/apt/sources.list.d/base-source.list
+run sudo sed -i'' -e 's/httpredir/ftp.jp/g' /etc/apt/sources.list
+
run apt-get update
run apt-get install -y lsb-release
distribution=$(lsb_release --id --short | tr 'A-Z' 'a-z')
-code_name=$(lsb_release --codename --short)
case "${distribution}" in
debian)
component=main
@@ -59,16 +80,23 @@ run apt-get install -V -y build-essential devscripts ${DEPENDED_PACKAGES}
run apt-get build-dep -y ${mysql_server_package}
run mkdir -p build
-run cp /vagrant/tmp/${PACKAGE}-${VERSION}.tar.gz \
- build/${PACKAGE}_${VERSION}.orig.tar.gz
run cd build
-run tar xfz ${PACKAGE}_${VERSION}.orig.tar.gz
-run cd ${PACKAGE}-${VERSION}/
+run tar xfz /vagrant/tmp/${PACKAGE}-${VERSION}.tar.gz
+run mv ${PACKAGE}-${VERSION} ${PACKAGE}-${MYSQL_VARIANT}-${VERSION}
+run tar cfz ${PACKAGE}-${MYSQL_VARIANT}_${VERSION}.orig.tar.gz \
+ ${PACKAGE}-${MYSQL_VARIANT}-${VERSION}
+run cd ${PACKAGE}-${MYSQL_VARIANT}-${VERSION}/
run cp -rp /vagrant/tmp/debian debian
# export DEB_BUILD_OPTIONS=noopt
-MYSQL_PACKAGE_INFO=$(apt-cache show mysql-server | grep Version | sort | tail -1)
+MYSQL_PACKAGE_INFO=$(apt-cache show ${mysql_server_package} |
+ grep Version |
+ sort |
+ tail -1)
MYSQL_PACKAGE_VERSION=${MYSQL_PACKAGE_INFO##Version: }
-sed -i "s/MYSQL_VERSION/$MYSQL_PACKAGE_VERSION/" debian/control
+sed -i'' \
+ -e "s/MYSQL_VERSION/$MYSQL_PACKAGE_VERSION/g" \
+ -e "s/MARIADB_VERSION/$MYSQL_PACKAGE_VERSION/g" \
+ debian/control
run debuild -us -uc
run cd -
diff --git a/storage/mroonga/packages/apt/env.sh.in b/storage/mroonga/packages/apt/env.sh.in
index a44d6b36871..51109aee4f7 100644
--- a/storage/mroonga/packages/apt/env.sh.in
+++ b/storage/mroonga/packages/apt/env.sh.in
@@ -7,8 +7,9 @@ libgroonga-dev
pkg-config
libmecab-dev
mecab-utils
-libmysqlclient-dev
-libmysqld-dev
+gdb
+libxml2-dev
+unixodbc-dev
libssl-dev
groonga-normalizer-mysql
wget
diff --git a/storage/mroonga/packages/apt/sign-packages.sh b/storage/mroonga/packages/apt/sign-packages.sh
index 11a4aea26db..57c985f38f6 100755
--- a/storage/mroonga/packages/apt/sign-packages.sh
+++ b/storage/mroonga/packages/apt/sign-packages.sh
@@ -23,7 +23,7 @@ run()
for code_name in ${CODES}; do
case ${code_name} in
- squeeze|wheezy|jessie|unstable)
+ jessie|stretch|unstable)
distribution=debian
;;
*)
diff --git a/storage/mroonga/packages/apt/sign-repository.sh b/storage/mroonga/packages/apt/sign-repository.sh
index fb0de850d6f..e0d963ffb5f 100755
--- a/storage/mroonga/packages/apt/sign-repository.sh
+++ b/storage/mroonga/packages/apt/sign-repository.sh
@@ -23,7 +23,7 @@ run()
for code_name in ${CODES}; do
case ${code_name} in
- squeeze|wheezy|jessie|unstable)
+ jessie|stretch|unstable)
distribution=debian
;;
*)
diff --git a/storage/mroonga/packages/apt/update-repository.sh b/storage/mroonga/packages/apt/update-repository.sh
index da1f8cd121c..a95ad117ccc 100755
--- a/storage/mroonga/packages/apt/update-repository.sh
+++ b/storage/mroonga/packages/apt/update-repository.sh
@@ -109,7 +109,7 @@ EOF
for code_name in ${CODES}; do
case ${code_name} in
- squeeze|wheezy|jessie|unstable)
+ jessie|stretch|unstable)
distribution=debian
component=main
;;
diff --git a/storage/mroonga/packages/check-utility.sh b/storage/mroonga/packages/check-utility.sh
deleted file mode 100755
index 211e231a473..00000000000
--- a/storage/mroonga/packages/check-utility.sh
+++ /dev/null
@@ -1,665 +0,0 @@
-#!/bin/sh
-
-# Usage: check-utility.sh [--install-groonga]
-# [--check-install]
-# [--check-address]
-# [--enable-repository]
-#
-# CODES="squeeze wheezy unstable lucid natty oneiric precise"
-# DISTRIBUTIONS="centos fedora"
-
-CHROOT_ROOT=/var/lib/chroot
-CHECK_ADDRESS=0
-CHECK_INSTALL=0
-CHECK_INSTALL_PACKAGE=mysql-server-mroonga
-CHECK_BUILD=0
-CHECK_DEPENDS=0
-CHECK_PROVIDES=0
-ENABLE_REPOSITORY=0
-DISABLE_REPOSITORY=0
-INSTALL_SCRIPT=0
-INSTALL_MROONGA=0
-UNINSTALL_MROONGA=0
-
-common_deb_procedure ()
-{
- for code in $CODES; do
- for arch in $DEB_ARCHITECTURES; do
- root_dir=$CHROOT_ROOT/$code-$arch
- eval $1 $code $arch $root_dir
- done
- done
-}
-
-common_rpm_procedure ()
-{
- for dist in $DISTRIBUTIONS; do
- case $dist in
- "fedora")
- DISTRIBUTIONS_VERSION="19"
- ;;
- "centos")
- DISTRIBUTIONS_VERSION="5 6"
- ;;
- esac
- for ver in $DISTRIBUTIONS_VERSION; do
- for arch in $RPM_ARCHITECTURES; do
- root_dir=$CHROOT_ROOT/$dist-$ver-$arch
- eval $1 $dist $arch $ver $root_dir
- done
- done
- done
-}
-
-echo_packages_repository_address ()
-{
- root_dir=$1
- code=$2
- arch=$3
- address=`grep "packages.groonga.org" $root_dir/etc/hosts | grep -v "#"`
- if [ -z "$address" ]; then
- echo "$code-$arch: default"
- else
- echo "$code-$arch: $address"
- fi
-}
-
-setup_distributions ()
-{
- if [ -z "$DISTRIBUTIONS" ]; then
- DISTRIBUTIONS="centos fedora"
- fi
-}
-
-setup_rpm_architectures ()
-{
- if [ -z "$RPM_ARCHITECTURES" ]; then
- RPM_ARCHITECTURES="i386 x86_64"
- fi
-}
-
-setup_codes ()
-{
- if [ -z "$CODES" ]; then
- CODES="squeeze wheezy jessie unstable lucid precise quantal raring"
- fi
-}
-setup_deb_architectures ()
-{
- if [ -z "$DEB_ARCHITECTURES" ]; then
- DEB_ARCHITECTURES="i386 amd64"
- fi
-}
-
-check_packages_repository_address ()
-{
- common_deb_procedure "check_packages_deb_repository_address"
- common_rpm_procedure "check_packages_rpm_repository_address"
-}
-
-check_packages_deb_repository_address ()
-{
- code=$1
- arch=$2
- root_dir=$4
- echo_packages_repository_address "$root_dir" "$code" "$arch"
-}
-
-check_packages_rpm_repository_address ()
-{
- dist=$1
- arch=$2
- ver=$3
- root_dir=$4
- echo_packages_repository_address "$root_dir" "$dist-$ver" "$arch"
-}
-
-host_address ()
-{
- ifconfig_result=`LANG=C /sbin/ifconfig wlan0`
- inet_addr=`echo "$ifconfig_result" | grep "inet addr:192"`
- address=`echo $inet_addr | ruby -ne '/inet addr:(.+?)\s/ =~ $_ && puts($1)'`
- HOST_ADDRESS=$address
-}
-
-check_build_packages ()
-{
- common_deb_procedure "check_build_deb_packages"
- common_rpm_procedure "check_build_rpm_packages"
-}
-
-check_build_deb_packages ()
-{
- code=$1
- arch=$2
- BASE_VERSION=`cat ../version`
- RESULT_SET=`find apt/repositories -name "*$BASE_VERSION*" | grep $code | grep $arch`
- if [ -z "$RESULT_SET" ]; then
- printf "%8s %5s %s => 0 deb\n" $code $arch $BASE_VERSION
- else
- PACKAGE_COUNT=`find apt/repositories -name "*$BASE_VERSION*" | grep $code | grep $arch | wc | awk '{print \$1}'`
- printf "%8s %5s %s => %2d debs\n" $code $arch $BASE_VERSION $PACKAGE_COUNT
- fi
-}
-
-check_build_rpm_packages ()
-{
- dist=$1
- arch=$2
- ver=$3
- BASE_VERSION=`cat ../version`
- FIND_PATH=yum/repositories/$dist/$ver/$arch
- RESULT_SET=`find $FIND_PATH -name "*$BASE_VERSION*"`
- if [ -z "$RESULT_SET" ]; then
- printf "%8s %6s %s => 0 rpm\n" $dist$ver $arch $BASE_VERSION
- else
- PACKAGE_COUNT=`find $FIND_PATH -name "*$BASE_VERSION*" | wc -l`
- printf "%8s %6s %s => %2d rpms\n" $dist$ver $arch $BASE_VERSION $PACKAGE_COUNT
- fi
-}
-
-check_depends_packages ()
-{
- common_deb_procedure "check_depends_deb_packages"
- common_rpm_procedure "check_depends_rpm_packages"
-}
-
-check_depends_deb_packages ()
-{
- code=$1
- arch=$2
- BASE_VERSION=`cat ../version`
- FIND_PATH=apt/repositories/*/pool/$code
- RESULT_SET=`find $FIND_PATH -name "*$BASE_VERSION*.deb"`
- if [ -z "$RESULT_SET" ]; then
- printf "%8s %5s %s => 404 deb\n" $code $arch $BASE_VERSION
- else
- for pkg in $RESULT_SET; do
- DEB_NAME=`basename $pkg`
- DEPENDS=`dpkg -I $pkg | grep "Depends"`
- printf "%8s %5s %s => %s\n" $code $arch $DEB_NAME "$DEPENDS"
- done
- fi
-}
-
-check_depends_rpm_packages ()
-{
- dist=$1
- arch=$2
- ver=$3
- BASE_VERSION=`cat ../version`
- FIND_PATH=yum/repositories/$dist/$ver/$arch
- RESULT_SET=`find $FIND_PATH -name "*$BASE_VERSION*"`
- if [ -z "$RESULT_SET" ]; then
- printf "%8s %6s %s => 404 rpm\n" $dist$ver $arch $BASE_VERSION
- else
- for pkg in $RESULT_SET; do
- RPM_NAME=`basename $pkg`
- DEPENDS=`rpm -qp --requires $pkg | grep -i "mysql" | tr -t '\n' ' '`
- printf "%9s %6s %s => %s\n" $dist$ver $arch $RPM_NAME "$DEPENDS"
- done
- fi
-}
-
-check_provided_mysql_packages ()
-{
- common_deb_procedure "check_provided_mysql_deb_packages"
- common_rpm_procedure "check_provided_mysql_rpm_packages"
- for code in $CODES; do
- echo $code
- cat tmp/$code-amd64-mysql-server.txt
- done
- for dist in $DISTRIBUTIONS; do
- echo $dist
- cat tmp/$dist-x86_64-mysql-server.txt
- done
-}
-
-check_provided_mysql_deb_packages ()
-{
- code=$1
- arch=$2
- root_dir=$3
- cat > tmp/check-provided-mysql.sh <<EOF
-#!/bin/sh
-apt-get update > /dev/null
-apt-cache show mysql-server | grep "Version" | head -1 > /tmp/$code-$arch-mysql-server.txt
-EOF
- if [ -d $root_dir ]; then
- CHECK_SCRIPT=check-provided-mysql.sh
- echo "copy check script $CHECK_SCRIPT to $root_dir/tmp"
- sudo rm -f $root_dir/tmp/$CHECK_SCRIPT
- cp tmp/$CHECK_SCRIPT $root_dir/tmp
- sudo chmod 755 $root_dir/tmp/$CHECK_SCRIPT
- sudo chname $code-$arch chroot $root_dir /tmp/$CHECK_SCRIPT
- cp $root_dir/tmp/$code-$arch-mysql-server.txt tmp
- fi
-}
-
-check_provided_mysql_rpm_packages ()
-{
- dist=$1
- arch=$2
- ver=$3
- root_dir=$4
- cat > tmp/check-provided-mysql.sh <<EOF
-#!/bin/sh
-yum update > /dev/null
-yum info mysql-server | grep "Version" > /tmp/$code-$arch-mysql-server.txt
-EOF
- if [ -d $root_dir ]; then
- CHECK_SCRIPT=check-provided-mysql.sh
- echo "copy check script $CHECK_SCRIPT to $root_dir/tmp"
- sudo rm -f $root_dir/tmp/$CHECK_SCRIPT
- cp tmp/$CHECK_SCRIPT $root_dir/tmp
- sudo chmod 755 $root_dir/tmp/$CHECK_SCRIPT
- sudo chname $code-$arch chroot $root_dir /tmp/$CHECK_SCRIPT
- cp $root_dir/tmp/$code-$arch-mysql-server.txt tmp
- fi
-}
-
-check_installed_mroonga_packages ()
-{
- common_deb_procedure "check_installed_mroonga_deb_packages"
- common_rpm_procedure "check_installed_mroonga_rpm_packages"
-}
-
-check_installed_mroonga_deb_packages ()
-{
- code=$1
- arch=$2
- root_dir=$3
- cat > tmp/check-deb-mroonga.sh <<EOF
-#!/bin/sh
-dpkg -l | grep $CHECK_INSTALL_PACKAGE
-EOF
- if [ -d $root_dir ]; then
- CHECK_SCRIPT=check-deb-mroonga.sh
- echo "copy check script $CHECK_SCRIPT to $root_dir/tmp"
- sudo rm -f $root_dir/tmp/$CHECK_SCRIPT
- cp tmp/$CHECK_SCRIPT $root_dir/tmp
- sudo chmod 755 $root_dir/tmp/$CHECK_SCRIPT
- sudo chname $code-$arch chroot $root_dir /tmp/$CHECK_SCRIPT
- fi
-}
-
-check_installed_mroonga_rpm_packages ()
-{
- dist=$1
- arch=$2
- ver=$3
- root_dir=$4
- cat > tmp/check-rpm-mroonga.sh <<EOF
-#!/bin/sh
-rpm -qa | grep $CHECK_INSTALL_PACKAGE
-EOF
- CHECK_SCRIPT=check-rpm-mroonga.sh
- if [ -d $root_dir ]; then
- echo "copy check script $CHECK_SCRIPT to $root_dir/tmp"
- sudo rm -f $root_dir/tmp/$CHECK_SCRIPT
- cp tmp/$CHECK_SCRIPT $root_dir/tmp
- sudo chmod 755 $root_dir/tmp/$CHECK_SCRIPT
- sudo chname $code-$ver-$arch chroot $root_dir /tmp/$CHECK_SCRIPT
- fi
-}
-
-install_mroonga_packages ()
-{
- common_deb_procedure "install_mroonga_deb_packages"
- common_rpm_procedure "install_mroonga_rpm_packages"
-}
-
-install_mroonga_deb_packages ()
-{
- code=$1
- arch=$2
- root_dir=$4
- cat > tmp/install-aptitude-mroonga.sh <<EOF
-#!/bin/sh
-sudo aptitude clean
-rm -f /var/lib/apt/lists/packages.groonga.org_*
-rm -f /var/lib/apt/lists/partial/packages.groonga.org_*
-sudo aptitude update
-sudo aptitude -V -D -y --allow-untrusted install groonga-keyring
-sudo aptitude update
-sudo aptitude -V -D install mysql-server-mroonga
-sudo aptitude -V -D install groonga-tokenizer-mecab
-EOF
- cat > tmp/install-aptget-mroonga.sh <<EOF
-#!/bin/sh
-sudo apt-get clean
-rm -f /var/lib/apt/lists/packages.groonga.org_*
-rm -f /var/lib/apt/lists/partial/packages.groonga.org_*
-sudo apt-get update
-sudo apt-get -y --allow-unauthenticated install groonga-keyring
-sudo apt-get update
-sudo apt-get -V -y install mysql-server-mroonga
-sudo apt-get -V -y install groonga-tokenizer-mecab
-EOF
- root_dir=$CHROOT_ROOT/$code-$arch
- INSTALL_SCRIPT=""
- case $code in
- squeeze|unstable)
- INSTALL_SCRIPT=install-aptitude-mroonga.sh
- ;;
- *)
- INSTALL_SCRIPT=install-aptget-mroonga.sh
- ;;
- esac
- if [ -d $root_dir ]; then
- echo "copy install script $INSTALL_SCRIPT to $root_dir/tmp"
- sudo rm -f $root_dir/tmp/$INSTALL_SCRIPT
- cp tmp/$INSTALL_SCRIPT $root_dir/tmp
- chmod 755 $root_dir/tmp/$INSTALL_SCRIPT
- sudo chname $code-$arch chroot $root_dir /tmp/$INSTALL_SCRIPT
- fi
-}
-
-install_mroonga_rpm_packages ()
-{
- dist=$1
- arch=$2
- ver=$3
- root_dir=$4
- cat > tmp/install-centos5-mroonga.sh <<EOF
-sudo rpm -ivh http://packages.groonga.org/centos/groonga-release-1.1.0-0.noarch.rpm
-sudo yum makecache
-sudo yum install -y MySQL-server
-sudo service mysql start
-sudo yum install -y mysql-mroonga
-sudo yum install -y groonga-tokenizer-mecab
-EOF
- cat > tmp/install-centos6-mroonga.sh <<EOF
-sudo rpm -ivh http://packages.groonga.org/centos/groonga-release-1.1.0-0.noarch.rpm
-sudo yum makecache
-sudo yum install -y mysql-server
-sudo service mysql start
-sudo yum install -y mysql-mroonga
-sudo yum install -y groonga-tokenizer-mecab
-EOF
- cat > tmp/install-fedora-mroonga.sh <<EOF
-sudo rpm -ivh http://packages.groonga.org/fedora/groonga-release-1.1.0-0.noarch.rpm
-sudo yum makecache
-sudo yum install -y mysql-mroonga
-sudo yum install -y groonga-tokenizer-mecab
-EOF
- INSTALL_SCRIPT=""
- case "$dist-$ver" in
- centos-5)
- INSTALL_SCRIPT=install-centos5-mroonga.sh
- ;;
- centos-6)
- INSTALL_SCRIPT=install-centos6-mroonga.sh
- ;;
- fedora-18)
- INSTALL_SCRIPT=install-fedora-mroonga.sh
- ;;
- *)
- ;;
- esac
- if [ -d $root_dir ]; then
- echo "copy install script $INSTALL_SCRIPT to $root_dir/tmp"
- sudo rm -f $root_dir/tmp/$INSTALL_SCRIPT
- cp tmp/$INSTALL_SCRIPT $root_dir/tmp
- chmod 755 $root_dir/tmp/$INSTALL_SCRIPT
- sudo chname $code-$ver-$arch chroot $root_dir /tmp/$INSTALL_SCRIPT
- fi
-}
-
-
-uninstall_mroonga_packages ()
-{
- common_deb_procedure "uninstall_mroonga_deb_packages"
- common_rpm_procedure "uninstall_mroonga_rpm_packages"
-}
-
-uninstall_mroonga_deb_packages ()
-{
- code=$1
- arch=$2
- root_dir=$4
- UNINSTALL_SCRIPT=uninstall-deb-mroonga.sh
- cat > $UNINSTALL_SCRIPT <<EOF
-#!/bin/sh
-sudo apt-get purge mroonga-* mysql-*
-EOF
- if [ -d $root_dir ]; then
- echo "copy uninstall script $UNINSTALL_SCRIPT to $root_dir/tmp"
- sudo rm -f $root_dir/tmp/$UNINSTALL_SCRIPT
- cp $UNINSTALL_SCRIPT $root_dir/tmp
- chmod 755 $root_dir/tmp/$UNINSTALL_SCRIPT
- sudo chname $code-$arch chroot $root_dir /tmp/$UNINSTALL_SCRIPT
- fi
-}
-
-uninstall_mroonga_rpm_packages ()
-{
- dist=$1
- arch=$2
- ver=$3
- root_dir=$4
- UNINSTALL_SCRIPT=uninstall-rpm-mroonga.sh
- cat > tmp/$UNINSTALL_SCRIPT <<EOF
-#!/bin/sh
-sudo yum remove mroonga-* mysql-*
-EOF
- if [ -d $root_dir ]; then
- echo "copy install script $UNINSTALL_SCRIPT to $root_dir/tmp"
- sudo rm -f $root_dir/tmp/$UNINSTALL_SCRIPT
- cp tmp/$UNINSTALL_SCRIPT $root_dir/tmp
- chmod 755 $root_dir/tmp/$UNINSTALL_SCRIPT
- sudo chname $code-$ver-$arch chroot $root_dir /tmp/$UNINSTALL_SCRIPT
- fi
-}
-
-
-enable_temporaly_mroonga_repository ()
-{
- cat > tmp/enable-repository.sh <<EOF
-#!/bin/sh
-
-grep -v "packages.groonga.org" /etc/hosts > /tmp/hosts
-echo "$HOST_ADDRESS packages.groonga.org" >> /tmp/hosts
-cp -f /tmp/hosts /etc/hosts
-EOF
- common_deb_procedure "enable_temporaly_mroonga_deb_repository"
- common_rpm_procedure "enable_temporaly_mroonga_rpm_repository"
- check_packages_repository_address
-}
-
-enable_temporaly_mroonga_deb_repository ()
-{
- code=$1
- arch=$2
- root_dir=$4
- today=`date '+%Y%m%d.%s'`
- if [ -d $root_dir ]; then
- sudo cp $root_dir/etc/hosts $root_dir/etc/hosts.$today
- sudo cp tmp/enable-repository.sh $root_dir/tmp
- sudo chname $code-$arch chroot $root_dir /tmp/enable-repository.sh
- fi
-}
-
-enable_temporaly_mroonga_rpm_repository ()
-{
- dist=$1
- arch=$2
- ver=$3
- root_dir=$4
- today=`date '+%Y%m%d.%s'`
- if [ -d $root_dir ]; then
- sudo cp $root_dir/etc/hosts $root_dir/etc/hosts.$today
- sudo cp tmp/enable-repository.sh $root_dir/tmp
- sudo chname $code-$arch chroot $root_dir /tmp/enable-repository.sh
- fi
-}
-
-disable_temporaly_mroonga_repository ()
-{
- cat > tmp/disable-repository.sh <<EOF
-#!/bin/sh
-
-grep -v "packages.groonga.org" /etc/hosts > /tmp/hosts
-cp -f /tmp/hosts /etc/hosts
-EOF
- common_deb_procedure "disable_temporaly_mroonga_deb_repository"
- common_rpm_procedure "disable_temporaly_mroonga_rpm_repository"
- check_packages_repository_address
-}
-
-disable_temporaly_mroonga_deb_repository ()
-{
- code=$1
- arch=$2
- root_dir=$4
- DISABLE_SCRIPT=disable-repository.sh
- today=`date '+%Y%m%d.%s'`
- if [ -d $root_dir ]; then
- sudo cp $root_dir/etc/hosts $root_dir/etc/hosts.$today
- cp tmp/$DISABLE_SCRIPT $root_dir/tmp
- chmod 755 $root_dir/tmp/$DISABLE_SCRIPT
- sudo chname $code-$arch chroot $root_dir /tmp/$DISABLE_SCRIPT
- fi
-
-}
-
-disable_temporaly_mroonga_rpm_repository ()
-{
- dist=$1
- arch=$2
- ver=$3
- root_dir=$4
- DISABLE_SCRIPT=disable-repository.sh
- today=`date '+%Y%m%d.%s'`
- if [ -d $root_dir ]; then
- sudo cp $root_dir/etc/hosts $root_dir/etc/hosts.$today
- cp tmp/$DISABLE_SCRIPT $root_dir/tmp
- chmod 755 $root_dir/tmp/$DISABLE_SCRIPT
- sudo chname $code-$arch chroot $root_dir /tmp/$DISABLE_SCRIPT
- fi
-}
-
-host_address
-echo $HOST_ADDRESS
-
-while [ $# -ne 0 ]; do
- case $1 in
- --check-install)
- CHECK_INSTALL=1
- shift
- if [ ! -z "$1" ]; then
- case $1 in
- groonga|mroonga|roonga|mecab|mysql)
- CHECK_INSTALL_PACKAGE=$1
- ;;
- *)
- ;;
- esac
- fi
- ;;
- --check-address)
- CHECK_ADDRESS=1
- shift
- ;;
- --check-depends)
- CHECK_DEPENDS=1
- shift
- ;;
- --check-provides)
- CHECK_PROVIDES=1
- shift
- ;;
- --check-build)
- CHECK_BUILD=1
- shift
- ;;
- --enable-repository)
- ENABLE_REPOSITORY=1
- shift
- ;;
- --disable-repository)
- DISABLE_REPOSITORY=1
- shift
- ;;
- --install-mroonga)
- INSTALL_MROONGA=1
- shift
- ;;
- --uninstall-mroonga)
- UNINSTALL_MROONGA=1
- shift
- ;;
- --code)
- shift
- if [ "$1" = "all" ]; then
- setup_codes
- else
- CODES=$1
- fi
- shift
- ;;
- --code-arch)
- shift
- if [ "$1" = "all" ]; then
- setup_deb_architectures
- else
- DEB_ARCHITECTURES=$1
- fi
- shift
- ;;
- --dist)
- shift
- if [ "$1" = "all" ]; then
- setup_distributions
- else
- DISTRIBUTIONS=$1
- fi
- shift
- ;;
- --dist-arch)
- shift
- if [ "$1" = "all" ]; then
- setup_rpm_architectures
- else
- RPM_ARCHITECTURES=$1
- fi
- shift
- ;;
- *)
- shift
- ;;
- esac
-done
-
-mkdir -p tmp
-setup_deb_architectures
-setup_rpm_architectures
-
-if [ $CHECK_INSTALL -ne 0 ]; then
- check_installed_mroonga_packages
-fi
-if [ $CHECK_ADDRESS -ne 0 ]; then
- check_packages_repository_address
-fi
-if [ $CHECK_BUILD -ne 0 ]; then
- check_build_packages
-fi
-if [ $CHECK_DEPENDS -ne 0 ]; then
- check_depends_packages
-fi
-if [ $CHECK_PROVIDES -ne 0 ]; then
- check_provided_mysql_packages
-fi
-if [ $ENABLE_REPOSITORY -ne 0 ]; then
- enable_temporaly_mroonga_repository
-fi
-if [ $DISABLE_REPOSITORY -ne 0 ]; then
- disable_temporaly_mroonga_repository
-fi
-if [ $INSTALL_MROONGA -ne 0 ]; then
- install_mroonga_packages
-fi
-if [ $UNINSTALL_MROONGA -ne 0 ]; then
- uninstall_mroonga_packages
-fi
-
diff --git a/storage/mroonga/packages/debian/apparmor/mysql-server-mroonga b/storage/mroonga/packages/debian/apparmor/mysql-server-mroonga
deleted file mode 100644
index 259f8d1dc0c..00000000000
--- a/storage/mroonga/packages/debian/apparmor/mysql-server-mroonga
+++ /dev/null
@@ -1,5 +0,0 @@
-/usr/lib/groonga/plugins/ r,
-/usr/lib/groonga/plugins/** rm,
-/etc/mecabrc r,
-/var/lib/mecab/dic/** r,
-#include <local/mysql-server-mroonga>
diff --git a/storage/mroonga/packages/debian/changelog b/storage/mroonga/packages/debian/changelog
deleted file mode 100644
index 366edca7b4e..00000000000
--- a/storage/mroonga/packages/debian/changelog
+++ /dev/null
@@ -1,415 +0,0 @@
-mroonga (5.04-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Masafumi Yokoyama <myokoym@gmail.com> Mon, 29 Jun 2015 00:00:00 +0900
-
-mroonga (5.03-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Fri, 29 May 2015 00:00:00 +0900
-
-mroonga (5.02-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Wed, 29 Apr 2015 00:00:00 +0900
-
-mroonga (5.01-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sun, 29 Mar 2015 00:00:00 +0900
-
-mroonga (5.00-1) unstable; urgency=low
-
- * New upstream release.
-
- -- <hayashi@clear-code.com> Mon, 09 Feb 2015 00:00:00 +0900
-
-mroonga (4.10-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Thu, 29 Jan 2015 00:00:00 +0900
-
-mroonga (4.09-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@cozmixng.org> Mon, 29 Dec 2014 00:00:00 +0900
-
-mroonga (4.08-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sat, 29 Nov 2014 00:00:00 +0900
-
-mroonga (4.07-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Wed, 29 Oct 2014 00:00:00 +0900
-
-mroonga (4.06-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Mon, 29 Sep 2014 00:00:00 +0900
-
-mroonga (4.05-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Fri, 29 Aug 2014 00:00:00 +0900
-
-mroonga (4.04-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Tue, 29 Jul 2014 00:00:00 +0900
-
-mroonga (4.03-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Thu, 29 May 2014 00:00:00 +0900
-
-mroonga (4.02-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Tue, 29 Apr 2014 00:00:00 +0900
-
-mroonga (4.01-2) unstable; urgency=low
-
- * Built for mysql-server 5.5.37
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Mon, 28 Apr 2014 00:00:00 +0900
-
-mroonga (4.01-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sat, 29 Mar 2014 00:00:00 +0900
-
-mroonga (4.00-2) unstable; urgency=low
-
- * Built for mysql-server 5.5.35+dfsg-2 on Debian jessie
- * Built for mysql-server 5.5.35+dfsg-2 on Debian sid
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Thu, 06 Mar 2014 00:00:00 +0900
-
-mroonga (4.00-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sun, 09 Feb 2014 00:00:00 +0900
-
-mroonga (3.12-2) unstable; urgency=low
-
- * Built for mysql-server updates on Ubuntu 12.04,12.10, and 13.10.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Wed, 29 Jan 2014 13:12:56 +0900
-
-mroonga (3.12-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Wed, 29 Jan 2014 00:00:00 +0900
-
-mroonga (3.11-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sun, 29 Dec 2013 00:00:00 +0900
-
-mroonga (3.10-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Fri, 29 Nov 2013 00:00:00 +0900
-
-mroonga (3.09-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Tue, 29 Oct 2013 00:00:00 +0900
-
-mroonga (3.08-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sun, 29 Sep 2013 00:00:00 +0900
-
-mroonga (3.07-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Thu, 29 Aug 2013 00:00:00 +0900
-
-mroonga (3.06-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Mon, 29 Jul 2013 00:00:00 +0900
-
-mroonga (3.05-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sat, 29 Jun 2013 00:00:00 +0900
-
-mroonga (3.04-2) unstable; urgency=low
-
- * Built for mysql-server 5.5.31-0ubuntu0.12.04.2 on Ubuntu 12.04 (precise)
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Thu, 13 Jun 2013 00:00:00 +0900
-
-mroonga (3.04-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Wed, 29 May 2013 00:00:00 +0900
-
-mroonga (3.03-2) unstable; urgency=low
-
- * Built for mysql-server 5.5.31+dfsg-0+wheezy1 on Debian wheezy
- * Built for mysql-server 5.5.31+dfsg-1 on Debian unstable
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Thu, 16 May 2013 00:00:00 +0900
-
-mroonga (3.03-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Mon, 29 Apr 2013 00:00:00 +0900
-
-mroonga (3.02-2) unstable; urgency=low
-
- * Built for mysql-server 5.5.29-0ubuntu0.12.04.2 on Ubuntu 12.04 (precise)
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Fri, 29 Mar 2013 22:15:39 +0900
-
-mroonga (3.02-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Fri, 29 Mar 2013 00:00:00 +0900
-
-mroonga (3.01-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Thu, 28 Feb 2013 00:00:00 +0900
-
-mroonga (3.00-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sat, 09 Feb 2013 00:00:00 +0900
-
-mroonga (2.10-2) unstable; urgency=low
-
- * Built for mysql-server 5.5.29+dfsg-1 on Debian/unstable.
- * Built for mysql-server 5.1.67-0ubuntu0.10.04.1 on Ubuntu 10.04(lucid).
- * Built for mysql-server 5.1.67-0ubuntu0.11.10.1 on Ubuntu 11.10(oneiric).
- * Built for mysql-server 5.5.29-0ubuntu0.12.04.1 on Ubuntu 12.04(precise).
- * Built for mysql-server 5.5.29-0ubuntu0.12.10.1 on Ubuntu 12.10(quantal).
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Thu, 24 Jan 2013 10:28:16 +0900
-
-mroonga (2.10-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sat, 29 Dec 2012 00:00:00 +0900
-
-mroonga (2.09-2) unstable; urgency=low
-
- * Built for mysql-server 5.5.28-0ubuntu0.12.10.2 on Ubuntu 12.10.
- Reported by @watanabekiyokaz
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Wed, 12 Dec 2012 13:28:00 +0900
-
-mroonga (2.09-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Thu, 29 Nov 2012 00:00:00 +0900
-
-mroonga (2.08-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Mon, 29 Oct 2012 00:00:00 +0900
-
-mroonga (2.07-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sat, 29 Sep 2012 00:00:00 +0900
-
-mroonga (2.06-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Wed, 29 Aug 2012 00:00:00 +0900
-
-mroonga (2.05-1) unstable; urgency=low
-
- * New upstream release.
-
- -- HAYASHI Kentaro <hayashi@clear-code.com> Sun, 29 Jul 2012 00:00:00 +0900
-
-mroonga (2.04-1) unstable; urgency=low
-
- * New upstream release.
- * Ensure deleting mroonga plugin before install.
- Suggested by Kazuhiro Isobe. Thanks!!!
-
- -- Kouhei Sutou <kou@clear-code.com> Fri, 29 Jun 2012 00:00:00 +0900
-
-mroonga (2.03-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Tue, 29 May 2012 00:00:00 +0900
-
-mroonga (2.02-1) unstable; urgency=low
-
- * New upstream release.
- * Require groonga >= 2.0.2.
-
- -- Kouhei Sutou <kou@clear-code.com> Sun, 29 Apr 2012 00:00:00 +0900
-
-mroonga (2.01-1) unstable; urgency=low
-
- * New upstream release.
- * Ensure plugin is uninstalled by closing all tables use mroonga.
-
- -- Kouhei Sutou <kou@clear-code.com> Thu, 29 Mar 2012 00:00:00 +0900
-
-mroonga (2.00-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Wed, 29 Feb 2012 00:00:00 +0900
-
-mroonga (1.20-1) unstable; urgency=low
-
- * New upstream release.
- * Add mysql-server-mroonga-compatible package for "groonga" storage engine.
-
- -- Kouhei Sutou <kou@clear-code.com> Sun, 29 Jan 2012 00:00:00 +0900
-
-mroonga (1.11-1) unstable; urgency=low
-
- * New upstream release.
- * Change apparmor configuration file name:
- mysql-server-groonga -> mysql-server-mroonga
-
- -- Kouhei Sutou <kou@clear-code.com> Thu, 29 Dec 2011 00:00:00 +0900
-
-mroonga (1.10-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Sat, 29 Oct 2011 00:00:00 +0900
-
-groonga-storage-engine (1.0.0-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Thu, 29 Sep 2011 00:00:00 +0900
-
-groonga-storage-engine (0.9-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Mon, 29 Aug 2011 00:00:00 +0900
-
-groonga-storage-engine (0.8-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Fri, 29 Jul 2011 00:00:00 +0900
-
-groonga-storage-engine (0.7-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Wed, 29 Jun 2011 00:00:00 +0900
-
-groonga-storage-engine (0.6-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Sun, 29 May 2011 00:00:00 +0900
-
-groonga-storage-engine (0.5-4) unstable; urgency=low
-
- * fix a typo.
-
- -- Kouhei Sutou <kou@clear-code.com> Tue, 30 Mar 2011 01:05:00 +0900
-
-groonga-storage-engine (0.5-3) unstable; urgency=low
-
- * fix AppArmor files.
-
- -- Kouhei Sutou <kou@clear-code.com> Tue, 30 Mar 2011 00:59:00 +0900
-
-groonga-storage-engine (0.5-2) unstable; urgency=low
-
- * hook script fix.
-
- -- Kouhei Sutou <kou@clear-code.com> Tue, 30 Mar 2011 00:58:00 +0900
-
-groonga-storage-engine (0.5-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Tue, 29 Mar 2011 00:00:00 +0900
-
-groonga-storage-engine (0.4-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Mon, 29 Nov 2010 00:00:00 +0900
-
-groonga-storage-engine (0.3-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Fri, 29 Oct 2010 16:34:04 +0900
-
-groonga-storage-engine (0.2-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Sat, 25 Sep 2010 14:52:49 +0900
-
-groonga-storage-engine (0.1-4) unstable; urgency=low
-
- * follow configure option changes.
-
- -- Kouhei Sutou <kou@cozmixng.org> Fri, 10 Sep 2010 08:45:53 +0900
-
-groonga-storage-engine (0.1-3) unstable; urgency=low
-
- * Use HEAD.
-
- -- Kouhei Sutou <kou@clear-code.com> Thu, 02 Sep 2010 12:03:46 +0900
-
-groonga-storage-engine (0.1-2) unstable; urgency=low
-
- * Built with groonga 1.0.0.
-
- -- Kouhei Sutou <kou@cozmixng.org> Mon, 30 Aug 2010 13:26:25 +0900
-
-groonga-storage-engine (0.1-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Kouhei Sutou <kou@clear-code.com> Mon, 23 Aug 2010 13:52:01 +0900
diff --git a/storage/mroonga/packages/debian/compat b/storage/mroonga/packages/debian/compat
deleted file mode 100644
index ec635144f60..00000000000
--- a/storage/mroonga/packages/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/storage/mroonga/packages/debian/control.in b/storage/mroonga/packages/debian/control.in
deleted file mode 100644
index d6d03fa9a4e..00000000000
--- a/storage/mroonga/packages/debian/control.in
+++ /dev/null
@@ -1,51 +0,0 @@
-Source: mroonga
-Section: database
-Priority: optional
-Maintainer: Kouhei Sutou <kou@clear-code.com>
-Build-Depends:
- debhelper (>= 7.0.50),
- autotools-dev,
- pkg-config,
- libgroonga-dev (>= @REQUIRED_GROONGA_VERSION@),
- groonga-normalizer-mysql,
- libmysqlclient-dev,
- libmysqld-dev,
- libssl-dev,
- wget,
- lsb-release
-Standards-Version: 3.9.1
-Homepage: http://mroonga.org/
-
-Package: mysql-server-mroonga
-Section: database
-Architecture: any
-Replaces: mysql-server-groonga (<< 1.10-1)
-Breaks: mysql-server-groonga (<< 1.10-1)
-Depends:
- ${misc:Depends},
- ${shlibs:Depends},
- libgroonga0 (>= @REQUIRED_GROONGA_VERSION@),
- mysql-server (= MYSQL_VERSION),
- groonga-normalizer-mysql
-Description: A fast fulltext searchable storage engine for MySQL.
- Mroonga is a fast fulltext searchable storage engine for MySQL.
- It is based on Groonga, a fast fulltext search engine and column store.
- Groonga is good at real time update.
- .
- This package provides a MySQL storage engine as a shared library.
- This provides "mroonga" storage engine. It means you can use
- "ENGINE = mroonga" in "CREATE TABLE".
-
-Package: mysql-server-mroonga-doc
-Section: doc
-Architecture: all
-Replaces: mysql-server-groonga-doc (<< 1.10-1)
-Breaks: mysql-server-groonga-doc (<< 1.10-1)
-Depends:
- ${misc:Depends}
-Description: Documentation of Mroonga.
- Mroonga is a fast fulltext searchable storage engine for MySQL.
- It is based on Groonga, a fast fulltext search engine and column store.
- Groonga is good at real time update.
- .
- This package provides documentation of Mroonga.
diff --git a/storage/mroonga/packages/debian/copyright b/storage/mroonga/packages/debian/copyright
deleted file mode 100644
index bb41984e8e4..00000000000
--- a/storage/mroonga/packages/debian/copyright
+++ /dev/null
@@ -1,27 +0,0 @@
-This work was packaged for Debian by:
-
- Kouhei Sutou <kou@clear-code.com> on Thu, 02 Sep 2010 13:51:56 +0900.
-
-It was downloaded:
-
- <http://github.com/mroonga/mroonga/downloads>
-
-Upstream Author(s):
-
- Tetsuro IKEDA <ikdttr at gmail.com>
- Daijiro MORI <morita at razil. jp>
- Tasuku SUENAGA <a at razil. jp>
- Kouhei Sutou <kou at clear-code. com>
-
-Copyright:
-
- Copyright(C) 2009-2010 Tetsuro IKEDA
-
-License:
-
- LGPLv2.1
-
- See `/usr/share/common-licenses/LGPL-2.1'.
-
-The Debian packaging is done by Kouhei Sutou <kou@clear-code.com> in 2010,
-and put into public domain, anyone can use it for any purpose.
diff --git a/storage/mroonga/packages/debian/mysql-server-mroonga-doc.install b/storage/mroonga/packages/debian/mysql-server-mroonga-doc.install
deleted file mode 100644
index ad2e27ef7dd..00000000000
--- a/storage/mroonga/packages/debian/mysql-server-mroonga-doc.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/share/doc/mysql-server-mroonga-doc/
diff --git a/storage/mroonga/packages/debian/mysql-server-mroonga.install b/storage/mroonga/packages/debian/mysql-server-mroonga.install
deleted file mode 100644
index 03f64cfedb4..00000000000
--- a/storage/mroonga/packages/debian/mysql-server-mroonga.install
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/lib/mysql/plugin/ha_mroonga.so*
-usr/share/mroonga/*
-debian/apparmor/mysql-server-mroonga etc/apparmor.d/abstractions/
diff --git a/storage/mroonga/packages/debian/mysql-server-mroonga.postinst b/storage/mroonga/packages/debian/mysql-server-mroonga.postinst
deleted file mode 100755
index 9a3db8784a2..00000000000
--- a/storage/mroonga/packages/debian/mysql-server-mroonga.postinst
+++ /dev/null
@@ -1,72 +0,0 @@
-#! /bin/sh
-
-set -e
-
-prevver="$2"
-
-install_plugin() {
- cat /usr/share/mroonga/install.sql | \
- mysql --defaults-file=/etc/mysql/debian.cnf || true
-}
-
-install_apparmor() {
- mysql_apparmor_profile_name=usr.sbin.mysqld
- mysql_apparmor_profile=/etc/apparmor.d/${mysql_apparmor_profile_name}
- mysql_local_apparmor_profile=/etc/apparmor.d/local/${mysql_apparmor_profile_name}
- apparmor_profile_name=mysql-server-mroonga
- include_profile="#include <abstractions/${apparmor_profile_name}>"
- local_apparmor_profile=/etc/apparmor.d/local/${apparmor_profile_name}
- if test -f "${mysql_local_apparmor_profile}"; then
- if ! grep -q "${include_profile}" "${mysql_local_apparmor_profile}"; then
- echo >> "${mysql_local_apparmor_profile}"
- echo "${include_profile}" >> "${mysql_local_apparmor_profile}"
- fi
- else
- mysql_abstraction_apparmor_profile=/etc/apparmor.d/abstractions/mysql
- mysql_plugin_dir=/usr/lib/mysql/plugin
- if test -f "${mysql_abstraction_apparmor_profile}" && \
- ! grep -q "${mysql_plugin_dir}" \
- "${mysql_abstraction_apparmor_profile}"; then
- # For Lucid.
- cat <<EOF >> "${mysql_abstraction_apparmor_profile}"
-
-# ${apparmor_profile_name}: START
-# Added by mysql-server-mroonga.
-${mysql_plugin_dir}/ r,
-${mysql_plugin_dir}/*.so* mr,
-${include_profile}
-# ${apparmor_profile_name}: END
-EOF
- fi
- fi
-
- if ! test -e "$local_apparmor_profile"; then
- mkdir -p $(dirname "$local_apparmor_profile")
- cat <<EOF > "$local_apparmor_profile"
-# Site-specific additions and overrides for ${apparmor_profile_name}.
-# For more details, please see /etc/apparmor.d/local/README.
-EOF
- fi
-
- if aa-status --enabled 2>/dev/null; then
- apparmor_parser -r -T -W "${mysql_apparmor_profile}" || true
- fi
-
- true
-}
-
-case "$1" in
- configure)
- install_apparmor
- install_plugin
- ;;
- abort-upgrade|abort-deconfigure|abort-remove)
- :
- ;;
- *)
- echo "Called with unknown argument $1, bailing out."
- exit 1
- ;;
-esac
-
-#DEBHELPER#
diff --git a/storage/mroonga/packages/debian/mysql-server-mroonga.postrm b/storage/mroonga/packages/debian/mysql-server-mroonga.postrm
deleted file mode 100755
index 84d7f1ef4ab..00000000000
--- a/storage/mroonga/packages/debian/mysql-server-mroonga.postrm
+++ /dev/null
@@ -1,38 +0,0 @@
-#! /bin/sh
-
-set -e
-
-if [ "$1" = "purge" ]; then
- mysql_apparmor_profile_name=usr.sbin.mysqld
- mysql_apparmor_profile=/etc/apparmor.d/${mysql_apparmor_profile_name}
- mysql_local_apparmor_profile=/etc/apparmor.d/local/${mysql_apparmor_profile_name}
- mysql_abstraction_apparmor_profile=/etc/apparmor.d/abstractions/mysql
- apparmor_profile_name=mysql-server-mroonga
- if test -f "${mysql_local_apparmor_profile}"; then
- include_profile="#include <abstractions/${apparmor_profile_name}>"
- if grep -q "${include_profile}" "${mysql_local_apparmor_profile}"; then
- sed -i'' -e "s,${include_profile},," \
- "${mysql_local_apparmor_profile}"
- fi
- else
- start_marker_re="^# ${apparmor_profile_name}: START$"
- end_marker_re="^# ${apparmor_profile_name}: END$"
- if test -f "${mysql_abstraction_apparmor_profile}" && \
- grep -q "${start_marker_re}" \
- "${mysql_abstraction_apparmor_profile}"; then
- sed -i'' -e "/${start_marker_re}/,/${end_marker_re}/d" \
- "${mysql_abstraction_apparmor_profile}"
- fi
- fi
-
- rm -f "/etc/apparmor.d/local/${apparmor_profile_name}" || true
- rmdir /etc/apparmor.d/local 2>/dev/null || true
-
- if aa-status --enabled 2>/dev/null; then
- apparmor_parser -r -T -W "${mysql_apparmor_profile}" || true
- fi
-fi
-
-#DEBHELPER#
-
-exit 0
diff --git a/storage/mroonga/packages/debian/mysql-server-mroonga.prerm b/storage/mroonga/packages/debian/mysql-server-mroonga.prerm
deleted file mode 100755
index 7fad990d75f..00000000000
--- a/storage/mroonga/packages/debian/mysql-server-mroonga.prerm
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /bin/sh
-
-set -e
-
-cat /usr/share/mroonga/uninstall.sql | \
- mysql --defaults-file=/etc/mysql/debian.cnf || true
-
-#DEBHELPER#
-
-exit 0
diff --git a/storage/mroonga/packages/debian/rules b/storage/mroonga/packages/debian/rules
deleted file mode 100755
index 2a397b333e1..00000000000
--- a/storage/mroonga/packages/debian/rules
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile-gmake -*-
-#
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-# This has to be exported to make some magic below work.
-export DH_OPTIONS
-
-export MYSQL_VERSION := $(shell apt-cache show mysql-server-5.5 | grep Version | head -n 1 | awk '{print $$2}' | awk -F '-' '{print $$1}')
-
-%:
- dh $@
-
-override_dh_auto_configure:
- path=main/m/mysql-5.5/mysql-5.5_$(MYSQL_VERSION).orig.tar.gz; \
- if [ "$$(lsb_release --id --short)" = "Ubuntu" ]; then \
- base_url=http://archive.ubuntu.com/ubuntu/pool; \
- security_base_url=http://security.ubuntu.com/ubuntu/pool; \
- else \
- base_url=http://ftp.debian.org/debian/pool; \
- security_base_url=http://security.debian.org/pool/updates; \
- fi; \
- wget $${security_base_url}/$${path} || \
- wget $${base_url}/$${path}
- tar xf mysql-5.5_$(MYSQL_VERSION).orig.tar.gz
- dh_auto_configure -- --with-mysql-source=./mysql-$(MYSQL_VERSION)
-
-# disable 'make check'.
-override_dh_auto_test:
-
-override_dh_install:
- mv debian/tmp/usr/share/doc/mroonga/ \
- debian/tmp/usr/share/doc/mysql-server-mroonga-doc/
- dh_install
-# if test -x /usr/bin/dh_apparmor; then \
-# dh_apparmor \
-# -pmysql-server-mroonga \
-# --profile-name=usr.lib.mysql.plugin.ha_mroonga; \
-# fi
diff --git a/storage/mroonga/packages/rpm/centos/Makefile.am b/storage/mroonga/packages/rpm/centos/Makefile.am
index e7b22cfa025..72d860a90f2 100644
--- a/storage/mroonga/packages/rpm/centos/Makefile.am
+++ b/storage/mroonga/packages/rpm/centos/Makefile.am
@@ -1,9 +1,19 @@
EXTRA_DIST = \
mysql55-mroonga.spec.in \
mysql56-community-mroonga.spec.in \
- mariadb-mroonga.spec.in
+ mysql57-community-mroonga.spec.in \
+ mariadb-mroonga.spec.in \
+ mariadb-10.1-mroonga.spec.in \
+ mariadb-10.2-mroonga.spec.in \
+ percona-server-56-mroonga.spec.in \
+ percona-server-57-mroonga.spec.in
noinst_DATA = \
mysql55-mroonga.spec \
mysql56-community-mroonga.spec \
- mariadb-mroonga.spec
+ mysql57-community-mroonga.spec \
+ mariadb-mroonga.spec \
+ mariadb-10.1-mroonga.spec \
+ mariadb-10.2-mroonga.spec \
+ percona-server-56-mroonga.spec \
+ percona-server-57-mroonga.spec
diff --git a/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in
index 04d1c41f2cc..d23c499fd44 100644
--- a/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in
+++ b/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in
@@ -1,18 +1,18 @@
%define mariadb_epoch_default 1
-%define mariadb_version_default 5.5.41
+%define mariadb_version_default 5.5.56
%define mariadb_release_default 2
-%define mariadb_dist_default .el7_0
-%define mariadb_download_base_url_default http://vault.centos.org/7.1.1503/os/Source/SPackages
+%define mariadb_dist_default .el7
+%define mariadb_download_base_url_default http://vault.centos.org/7.4.1708/os/Source/SPackages/
%define mariadb_spec_file_default mariadb.spec
-%{!?mariadb_epoch:%define mariadb_epoch %{mariadb_epoch_default}}
-%{!?mariadb_version:%define mariadb_version %{mariadb_version_default}}
-%{!?mariadb_release:%define mariadb_release %{mariadb_release_default}}
-%{!?mariadb_dist:%define mariadb_dist %{mariadb_dist_default}}
-%{!?mariadb_download_base_url:%define mariadb_download_base_url %{mariadb_download_base_url_default}}
-%{!?mariadb_spec_file:%define mariadb_spec_file %{mariadb_spec_file_default}}
+%define _mariadb_epoch %{?mariadb_epoch:%{mariadb_epoch}}%{!?mariadb_epoch:%{mariadb_epoch_default}}
+%define _mariadb_version %{?mariadb_version:%{mariadb_version}}%{!?mariadb_version:%{mariadb_version_default}}
+%define _mariadb_release %{?mariadb_release:%{mariadb_release}}%{!?mariadb_release:%{mariadb_release_default}}
+%define _mariadb_dist %{?mariadb_dist:%{mariadb_dist}}%{!?mariadb_dist:%{mariadb_dist_default}}
+%define _mariadb_download_base_url %{?mariadb_download_base_url:%{mariadb_download_base_url}}%{!?mariadb_download_base_url:%{mariadb_download_base_url_default}}
+%define _mariadb_spec_file %{?mariadb_spec_file:%{mariadb_spec_file}}%{!?mariadb_spec_file:%{mariadb_spec_file_default}}
-%define mariadb_package_version %{mariadb_epoch}:%{mariadb_version}-%{mariadb_release}%{mariadb_dist}
+%define _mariadb_package_version %{_mariadb_epoch}:%{_mariadb_version}-%{_mariadb_release}%{_mariadb_dist}
%define groonga_required_version @REQUIRED_GROONGA_VERSION@
@@ -30,9 +30,9 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%(%{__id_u} -n)
BuildRequires: groonga-devel >= %{groonga_required_version}
BuildRequires: groonga-normalizer-mysql-devel
BuildRequires: wget
-BuildRequires: mariadb-devel = %{mariadb_package_version}
-Requires: mariadb-server = %{mariadb_package_version}
-Requires: mariadb = %{mariadb_package_version}
+BuildRequires: mariadb-devel = %{_mariadb_package_version}
+Requires: mariadb-server = %{_mariadb_package_version}
+Requires: mariadb = %{_mariadb_package_version}
Requires: groonga-libs >= %{groonga_required_version}
Requires: groonga-normalizer-mysql
@@ -53,21 +53,21 @@ Documentation for Mroonga
%prep
%setup -q -n mroonga-%{version}
-mariadb_full_version=%{mariadb_version}-%{mariadb_release}%{mariadb_dist}
+mariadb_full_version=%{_mariadb_version}-%{_mariadb_release}%{_mariadb_dist}
srpm=mariadb-${mariadb_full_version}.src.rpm
if [ ! -f ../../SRPMS/$srpm ]; then
- wget --continue -O ../../SRPMS/$srpm %{mariadb_download_base_url}/$srpm
+ wget --continue -O ../../SRPMS/$srpm %{_mariadb_download_base_url}/$srpm
rpm -Uvh ../../SRPMS/$srpm
rm ../../SRPMS/$srpm
fi
%build
-mariadb_source=../mariadb-%{mariadb_version}
+mariadb_source=../mariadb-%{_mariadb_version}
if [ ! -d ${mariadb_source} ]; then
rpmbuild -bc \
--define 'runselftest 0' \
--define 'optflags -O0' \
- ../../SPECS/%{mariadb_spec_file}
+ ../../SPECS/%{_mariadb_spec_file}
fi
%configure \
--disable-static \
@@ -86,7 +86,7 @@ mv $RPM_BUILD_ROOT%{_datadir}/doc/mroonga/ mysql-mroonga-doc/
rm -rf $RPM_BUILD_ROOT
%post
-if /usr/bin/mysql -u root -e "quit"; then
+if /usr/bin/mysql -u root -e "quit" > /dev/null 2>&1; then
password_option=""
else
password_option="-p"
@@ -128,7 +128,7 @@ eval $command || \
%preun
uninstall_sql=%{_datadir}/mroonga/uninstall.sql
-if mysql -u root -e "quit"; then
+if mysql -u root -e "quit" > /dev/null 2>&1; then
password_option=""
else
password_option="-p"
@@ -154,6 +154,84 @@ fi
%doc mysql-mroonga-doc/*
%changelog
+* Thu Oct 12 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.07-1
+- new upstream release.
+
+* Fri Sep 15 2017 Kouhei Sutou <kou@clear-code.com> - 7.06-2
+- rebuild against the latest MariaDB.
+
+* Tue Aug 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.06-1
+- new upstream release.
+
+* Sat Jul 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.05-1
+- new upstream release.
+
+* Thu Jun 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.04-1
+- new upstream release.
+
+* Mon May 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.03-1
+- new upstream release.
+
+* Sat Apr 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.02-1
+- new upstream release.
+
+* Wed Mar 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.01-1
+- new upstream release.
+
+* Thu Feb 09 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.00-1
+- new upstream release.
+
+* Sat Oct 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.10-1
+- new upstream release.
+
+* Thu Sep 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.09-1
+- new upstream release.
+
+* Mon Aug 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.08-1
+- new upstream release.
+
+* Fri Jul 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.07-1
+- new upstream release.
+
+* Thu Jun 30 2016 Masafumi Yokoyama <yokoyama@clear-code.com> - 6.06-1
+- new upstream release.
+
+* Wed Jun 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.05-1
+- new upstream release.
+
+* Sun May 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.03-1
+- new upstream release.
+
+* Fri Apr 29 2016 HAYASHI Kentaro <hayashi@clear-code.com> - 6.02-1
+- new upstream release.
+
+* Tue Mar 29 2016 Masafumi Yokoyama <yokoyama@clear-code.com> - 6.01-1
+- new upstream release.
+
+* Mon Feb 29 2016 Kouhei Sutou <kou@clear-code.com> - 6.00-1
+- new upstream release.
+
+* Tue Dec 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.11-1
+- new upstream release.
+
+* Wed Dec 16 2015 Kouhei Sutou <kou@clear-code.com> - 5.10-2
+- rebuild against MariaDB on CentOS 7.2. Reported by Larry Kim. Thanks!!!
+
+* Sun Nov 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.10-1
+- new upstream release.
+
+* Thu Oct 29 2015 Kouhei Sutou <kou@cozmixng.org> - 5.09-1
+- new upstream release.
+
+* Tue Sep 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.08-1
+- new upstream release.
+
+* Mon Aug 31 2015 Kouhei Sutou <kou@clear-code.com> - 5.06-1
+- new upstream release.
+
+* Wed Jul 29 2015 Masafumi Yokoyama <yokoyama@clear-code.com> - 5.05-1
+- new upstream release.
+
* Mon Jun 29 2015 Masafumi Yokoyama <myokoym@gmail.com> - 5.04-1
- new upstream release.
diff --git a/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in
index e20e1b32162..8bd2ba540d3 100644
--- a/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in
+++ b/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in
@@ -1,26 +1,26 @@
%{?scl:%scl_package mroonga}
%{!?scl:%global pkg_name %{name}}
-%{!?centos_ver:%define centos_ver 5}
+%define _centos_ver %{?centos_ver:%{centos_ver}}%{!?centos_ver:5}
-%if %{centos_ver} == 6
-%define mysql_version_default 5.5.41
-%define mysql_release_default 2
-%define mysql_dist_default el6.centos.alt
-%define mysql_download_base_url_default http://vault.centos.org/6.6/SCL/Source/SPackages
+%if %{_centos_ver} == 6
+%define mysql_version_default 5.5.52
+%define mysql_release_default 1
+%define mysql_dist_default el6
+%define mysql_download_base_url_default http://vault.centos.org/6.8/sclo/Source/rh/mysql55/
%define mysql_spec_file_default mysql.spec
%else
-%define mysql_version_default 5.5.40
-%define mysql_release_default 2
+%define mysql_version_default 5.5.45
+%define mysql_release_default 1
%define mysql_dist_default el5
%define mysql_download_base_url_default http://vault.centos.org/5.11/updates/SRPMS
%define mysql_spec_file_default mysql.spec
%endif
-%{!?mysql_version:%define mysql_version %{mysql_version_default}}
-%{!?mysql_release:%define mysql_release %{mysql_release_default}}
-%{!?mysql_dist:%define mysql_dist %{mysql_dist_default}}
-%{!?mysql_download_base_url:%define mysql_download_base_url %{mysql_download_base_url_default}}
-%{!?mysql_spec_file:%define mysql_spec_file %{mysql_spec_file_default}}
+%define _mysql_version %{?mysql_version:%{mysql_version}}%{!?mysql_version:%{mysql_version_default}}
+%define _mysql_release %{?mysql_release:%{mysql_release}}%{!?mysql_release:%{mysql_release_default}}
+%define _mysql_dist %{?mysql_dist:%{mysql_dist}}%{!?mysql_dist:%{mysql_dist_default}}
+%define _mysql_download_base_url %{?mysql_download_base_url:%{mysql_download_base_url}}%{!?mysql_download_base_url:%{mysql_download_base_url_default}}
+%define _mysql_spec_file %{?mysql_spec_file:%{mysql_spec_file}}%{!?mysql_spec_file:%{mysql_spec_file_default}}
%define groonga_required_version @REQUIRED_GROONGA_VERSION@
@@ -39,10 +39,10 @@ BuildRequires: groonga-devel >= %{groonga_required_version}
BuildRequires: groonga-normalizer-mysql-devel
BuildRequires: wget
BuildRequires: which
-BuildRequires: mysql55-mysql-devel = %{mysql_version}-%{mysql_release}.%{mysql_dist}
+BuildRequires: mysql55-mysql-devel = %{_mysql_version}-%{_mysql_release}.%{_mysql_dist}
BuildRequires: mysql55-build
-Requires: mysql55-mysql-server = %{mysql_version}-%{mysql_release}.%{mysql_dist}
-Requires: mysql55-mysql = %{mysql_version}-%{mysql_release}.%{mysql_dist}
+Requires: mysql55-mysql-server = %{_mysql_version}-%{_mysql_release}.%{_mysql_dist}
+Requires: mysql55-mysql = %{_mysql_version}-%{_mysql_release}.%{_mysql_dist}
Requires: groonga-libs >= %{groonga_required_version}
Requires: groonga-normalizer-mysql
%{?scl:Requires: %scl_runtime}
@@ -64,21 +64,21 @@ Documentation for Mroonga
%prep
%setup -q -n %{pkg_name}-%{version}
-mysql_full_version=%{mysql_version}-%{mysql_release}.%{mysql_dist}
+mysql_full_version=%{_mysql_version}-%{_mysql_release}.%{_mysql_dist}
srpm=mysql55-mysql-${mysql_full_version}.src.rpm
if [ ! -f ../../SRPMS/$srpm ]; then
- wget --continue -O ../../SRPMS/$srpm %{mysql_download_base_url}/$srpm
+ wget --continue -O ../../SRPMS/$srpm %{_mysql_download_base_url}/$srpm
rpm -Uvh ../../SRPMS/$srpm
fi
%build
-mysql_source=../mysql-%{mysql_version}
+mysql_source=../mysql-%{_mysql_version}
if [ ! -d ${mysql_source} ]; then
specs_dir=
MYSQL_RPMBUILD_TEST=no rpmbuild -bp \
--define 'runselftest 0' \
--define 'optflags -O0' \
- ../../SPECS/%{mysql_spec_file}
+ ../../SPECS/%{_mysql_spec_file}
fi
%configure --disable-static --with-mysql-source=${mysql_source} \
--disable-fast-mutexes \
@@ -97,10 +97,10 @@ rm -rf $RPM_BUILD_ROOT
%post
mysql_command=`scl enable mysql55 'which mysql'`
-password_option=""
-$mysql_command -u root -e "quit"
-if [ $? -ne 0 ]; then
- password_option="-p"
+if $mysql_command -u root -e "quit" > /dev/null 2>&1; then
+ password_option=""
+else
+ password_option="-p"
fi
current_version=0
version=`echo %{groonga_required_version} | sed -e 's/\.//g'`
@@ -137,7 +137,7 @@ eval $command || \
%preun
uninstall_sql=%{_datadir}/mroonga/uninstall.sql
mysql_command=`scl enable mysql55 'which mysql'`
-if $mysql_command -u root -e "quit"; then
+if $mysql_command -u root -e "quit" > /dev/null 2>&1; then
password_option=""
else
password_option="-p"
@@ -163,6 +163,87 @@ fi
%doc mysql-mroonga-doc/*
%changelog
+* Thu Oct 12 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.07-1
+- new upstream release.
+
+* Tue Aug 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.06-1
+- new upstream release.
+
+* Sat Jul 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.05-1
+- new upstream release.
+
+* Thu Jun 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.04-1
+- new upstream release.
+
+* Mon May 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.03-1
+- new upstream release.
+
+* Sat Apr 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.02-1
+- new upstream release.
+
+* Wed Mar 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.01-1
+- new upstream release.
+
+* Thu Feb 09 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.00-1
+- new upstream release.
+
+* Fri Jan 13 2017 Kouhei Sutou <kou@clear-code.com> - 6.13-1
+- new upstream release.
+
+* Thu Dec 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.12-1
+- new upstream release.
+
+* Tue Nov 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.11-1
+- new upstream release.
+
+* Sat Oct 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.10-1
+- new upstream release.
+
+* Thu Sep 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.09-1
+- new upstream release.
+
+* Mon Aug 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.08-1
+- new upstream release.
+
+* Fri Jul 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.07-1
+- new upstream release.
+
+* Thu Jun 30 2016 Masafumi Yokoyama <yokoyama@clear-code.com> - 6.06-1
+- new upstream release.
+
+* Wed Jun 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.05-1
+- new upstream release.
+
+* Sun May 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.03-1
+- new upstream release.
+
+* Fri Apr 29 2016 HAYASHI Kentaro <hayashi@clear-code.com> - 6.02-1
+- new upstream release.
+
+* Tue Mar 29 2016 Masafumi Yokoyama <yokoyama@clear-code.com> - 6.01-1
+- new upstream release.
+
+* Mon Feb 29 2016 Kouhei Sutou <kou@clear-code.com> - 6.00-1
+- new upstream release.
+
+* Fri Jan 29 2016 Kouhei Sutou <kou@clear-code.com> - 5.12-1
+- new upstream release.
+
+* Sun Nov 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.10-1
+- new upstream release.
+
+* Thu Oct 29 2015 Kouhei Sutou <kou@cozmixng.org> - 5.09-1
+- new upstream release.
+
+* Tue Sep 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.08-1
+- new upstream release.
+
+* Mon Aug 31 2015 Kouhei Sutou <kou@clear-code.com> - 5.06-1
+- new upstream release.
+
+* Wed Jul 29 2015 Masafumi Yokoyama <yokoyama@clear-code.com> - 5.05-1
+- new upstream release.
+
* Mon Jun 29 2015 Masafumi Yokoyama <myokoym@gmail.com> - 5.04-1
- new upstream release.
diff --git a/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in
index f3233d17afe..dea7cebc7d9 100644
--- a/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in
+++ b/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in
@@ -1,24 +1,24 @@
-%{!?centos_ver:%define centos_ver 6}
+%define _centos_ver %{?centos_ver:%{centos_ver}}%{!?centos_ver:5}
-%if %{centos_ver} == 7
-%define mysql_version_default 5.6.25
+%if %{_centos_ver} == 7
+%define mysql_version_default 5.6.37
%define mysql_release_default 2
%define mysql_dist_default el7
%define mysql_download_base_url_default http://repo.mysql.com/yum/mysql-5.6-community/el/7/SRPMS
%define mysql_spec_file_default mysql.spec
%else
-%define mysql_version_default 5.6.25
+%define mysql_version_default 5.6.37
%define mysql_release_default 2
%define mysql_dist_default el6
%define mysql_download_base_url_default http://repo.mysql.com/yum/mysql-5.6-community/el/6/SRPMS
%define mysql_spec_file_default mysql.spec
%endif
-%{!?mysql_version:%define mysql_version %{mysql_version_default}}
-%{!?mysql_release:%define mysql_release %{mysql_release_default}}
-%{!?mysql_dist:%define mysql_dist %{mysql_dist_default}}
-%{!?mysql_download_base_url:%define mysql_download_base_url %{mysql_download_base_url_default}}
-%{!?mysql_spec_file:%define mysql_spec_file %{mysql_spec_file_default}}
+%define _mysql_version %{?mysql_version:%{mysql_version}}%{!?mysql_version:%{mysql_version_default}}
+%define _mysql_release %{?mysql_release:%{mysql_release}}%{!?mysql_release:%{mysql_release_default}}
+%define _mysql_dist %{?mysql_dist:%{mysql_dist}}%{!?mysql_dist:%{mysql_dist_default}}
+%define _mysql_download_base_url %{?mysql_download_base_url:%{mysql_download_base_url}}%{!?mysql_download_base_url:%{mysql_download_base_url_default}}
+%define _mysql_spec_file %{?mysql_spec_file:%{mysql_spec_file}}%{!?mysql_spec_file:%{mysql_spec_file_default}}
%define groonga_required_version @REQUIRED_GROONGA_VERSION@
@@ -38,9 +38,10 @@ BuildRequires: groonga-normalizer-mysql-devel
BuildRequires: wget
BuildRequires: which
BuildRequires: gcc, gcc-c++
-BuildRequires: mysql-community-devel = %{mysql_version}-%{mysql_release}.%{mysql_dist}
-Requires: mysql-community-server = %{mysql_version}-%{mysql_release}.%{mysql_dist}
-Requires: mysql-community-client = %{mysql_version}-%{mysql_release}.%{mysql_dist}
+BuildRequires: numactl-devel
+BuildRequires: mysql-community-devel = %{_mysql_version}-%{_mysql_release}.%{_mysql_dist}
+Requires: mysql-community-server = %{_mysql_version}-%{_mysql_release}.%{_mysql_dist}
+Requires: mysql-community-client = %{_mysql_version}-%{_mysql_release}.%{_mysql_dist}
Requires: groonga-libs >= %{groonga_required_version}
Requires: groonga-normalizer-mysql
@@ -61,21 +62,21 @@ Documentation for Mroonga
%prep
%setup -q -n mroonga-%{version}
-mysql_full_version=%{mysql_version}-%{mysql_release}.%{mysql_dist}
+mysql_full_version=%{_mysql_version}-%{_mysql_release}.%{_mysql_dist}
srpm=mysql-community-${mysql_full_version}.src.rpm
if [ ! -f ../../SRPMS/$srpm ]; then
- wget --continue -O ../../SRPMS/$srpm %{mysql_download_base_url}/$srpm
+ wget --continue -O ../../SRPMS/$srpm %{_mysql_download_base_url}/$srpm
rpm -Uvh ../../SRPMS/$srpm
fi
%build
-mysql_source=../mysql-%{mysql_version}/mysql-%{mysql_version}
+mysql_source=../mysql-%{_mysql_version}/mysql-%{_mysql_version}
if [ ! -d ${mysql_source} ]; then
specs_dir=
MYSQL_RPMBUILD_TEST=no rpmbuild -bp \
--define 'runselftest 0' \
--define 'optflags -O0' \
- ../../SPECS/%{mysql_spec_file}
+ ../../SPECS/%{_mysql_spec_file}
fi
%configure \
--disable-static \
@@ -102,10 +103,10 @@ else
fi
mysql_command=`which mysql`
-password_option=""
-$mysql_command -u root -e "quit"
-if [ $? -ne 0 ]; then
- password_option="-p"
+if $mysql_command -u root -e "quit" > /dev/null 2>&1; then
+ password_option=""
+else
+ password_option="-p"
fi
current_version=0
version=`echo %{groonga_required_version} | sed -e 's/\.//g'`
@@ -153,7 +154,7 @@ fi
uninstall_sql=%{_datadir}/mroonga/uninstall.sql
mysql_command=`which mysql`
-if $mysql_command -u root -e "quit"; then
+if $mysql_command -u root -e "quit" > /dev/null 2>&1; then
password_option=""
else
password_option="-p"
@@ -183,10 +184,118 @@ fi
%doc mysql-mroonga-doc/*
%changelog
+* Thu Oct 12 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.07-1
+- new upstream release.
+
+* Tue Aug 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.06-1
+- new upstream release.
+
+* Wed Aug 23 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.05-2
+- build against MySQL 5.6.37 on CentOS 7. Reported by Hiroshi Kagami. Thanks!!!
+
+* Sat Jul 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.05-1
+- new upstream release.
+
+* Fri Jul 21 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.04-2
+- build against MySQL 5.6.37 on CentOS 6. Reported by Hiroshi Kagami. Thanks!!!
+
+* Thu Jun 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.04-1
+- new upstream release.
+
+* Mon May 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.03-1
+- new upstream release.
+
+* Sat Apr 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.02-1
+- new upstream release.
+
+* Wed Apr 12 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.01-2
+- build against MySQL 5.6.36 Reported by @tigersun2000. Thanks!!!
+
+* Wed Mar 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.01-1
+- new upstream release.
+
+* Thu Feb 09 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.00-1
+- new upstream release.
+
+* Fri Jan 13 2017 Kouhei Sutou <kou@clear-code.com> - 6.13-1
+- new upstream release.
+
+* Thu Dec 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.12-1
+- new upstream release.
+
+* Tue Nov 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.11-1
+- new upstream release.
+
+* Sat Oct 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.10-1
+- new upstream release.
+
+* Mon Oct 24 2016 Kouhei Sutou <kou@clear-code.com> - 6.09-2
+- build against MySQL 5.6.34. Reported by Hiroshi Kagami. Thanks!!!
+
+* Thu Sep 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.09-1
+- new upstream release.
+
+* Wed Sep 14 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.08-2
+- build against MySQL 5.6.33.
+
+* Mon Aug 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.08-1
+- new upstream release.
+
+* Fri Jul 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.07-1
+- new upstream release.
+
+* Thu Jun 30 2016 Masafumi Yokoyama <yokoyama@clear-code.com> - 6.06-1
+- new upstream release.
+
+* Wed Jun 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.05-1
+- new upstream release.
+
+* Mon Jun 06 2016 Kouhei Sutou <kou@clear-code.com> - 6.03-2
+- build against MySQL 5.6.30.
+
+* Sun May 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.03-1
+- new upstream release.
+
+* Fri Apr 29 2016 HAYASHI Kentaro <hayashi@clear-code.com> - 6.02-1
+- new upstream release.
+
+* Tue Mar 29 2016 Masafumi Yokoyama <yokoyama@clear-code.com> - 6.01-1
+- new upstream release.
+
+* Mon Feb 29 2016 Kouhei Sutou <kou@clear-code.com> - 6.00-1
+- new upstream release.
+
+* Fri Jan 29 2016 Kouhei Sutou <kou@clear-code.com> - 5.12-1
+- new upstream release.
+
+* Tue Dec 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.11-1
+- new upstream release.
+
+* Wed Dec 09 2015 Kouhei Sutou <kou@clear-code.com> - 5.10-2
+- build against MySQL 5.6.28. Reported by @stealthinu. Thanks!!!
+
+* Sun Nov 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.10-1
+- new upstream release.
+
+* Thu Oct 29 2015 Kouhei Sutou <kou@cozmixng.org> - 5.09-1
+- new upstream release.
+
+* Sat Oct 03 2015 Kouhei Sutou <kou@clear-code.com> - 5.08-2
+- build against MySQL 5.6.27. Reported by @star_orihime. Thanks!!!
+
+* Tue Sep 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.08-1
+- new upstream release.
+
+* Mon Aug 31 2015 Kouhei Sutou <kou@clear-code.com> - 5.06-1
+- new upstream release.
+
+* Wed Jul 29 2015 Masafumi Yokoyama <yokoyama@clear-code.com> - 5.05-1
+- new upstream release.
+
* Mon Jun 29 2015 Masafumi Yokoyama <myokoym@gmail.com> - 5.04-1
- new upstream release.
-* Thu Jun 02 2015 Masafumi Yokoyama <yokoyama@clear-code.com> - 5.03-2
+* Tue Jun 02 2015 Masafumi Yokoyama <yokoyama@clear-code.com> - 5.03-2
- build against MySQL 5.6.25.
* Fri May 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.03-1
diff --git a/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in
index cf1947e2676..abf3bfdee9e 100644
--- a/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in
+++ b/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in
@@ -1,16 +1,16 @@
-%{!?centos_ver:%define centos_ver 6}
+%define _centos_ver %{?centos_ver:%{centos_ver}}%{!?centos_ver:5}
-%define mysql_version_default 5.6.24
-%define mysql_release_default rel72.2
+%define mysql_version_default 5.6.37
+%define mysql_release_default rel82.2
%define mysql_dist_default %{?dist}
-%define mysql_download_base_url_default http://repo.percona.com/centos/%{centos_ver}/SRPMS
+%define mysql_download_base_url_default http://repo.percona.com/centos/%{_centos_ver}/SRPMS
%define mysql_spec_file_default percona-server.spec
-%{!?mysql_version:%define mysql_version %{mysql_version_default}}
-%{!?mysql_release:%define mysql_release %{mysql_release_default}}
-%{!?mysql_dist:%define mysql_dist %{mysql_dist_default}}
-%{!?mysql_download_base_url:%define mysql_download_base_url %{mysql_download_base_url_default}}
-%{!?mysql_spec_file:%define mysql_spec_file %{mysql_spec_file_default}}
+%define _mysql_version %{?mysql_version:%{mysql_version}}%{!?mysql_version:%{mysql_version_default}}
+%define _mysql_release %{?mysql_release:%{mysql_release}}%{!?mysql_release:%{mysql_release_default}}
+%define _mysql_dist %{?mysql_dist:%{mysql_dist}}%{!?mysql_dist:%{mysql_dist_default}}
+%define _mysql_download_base_url %{?mysql_download_base_url:%{mysql_download_base_url}}%{!?mysql_download_base_url:%{mysql_download_base_url_default}}
+%define _mysql_spec_file %{?mysql_spec_file:%{mysql_spec_file}}%{!?mysql_spec_file:%{mysql_spec_file_default}}
%define groonga_required_version @REQUIRED_GROONGA_VERSION@
@@ -31,10 +31,10 @@ BuildRequires: wget
BuildRequires: which
BuildRequires: gcc
BuildRequires: gcc-c++
-BuildRequires: Percona-Server-devel-56 = %{mysql_version}-%{mysql_release}%{mysql_dist}
+BuildRequires: Percona-Server-devel-56 = %{_mysql_version}-%{_mysql_release}%{_mysql_dist}
BuildRequires: selinux-policy-devel
-Requires: Percona-Server-server-56 = %{mysql_version}-%{mysql_release}%{mysql_dist}
-Requires: Percona-Server-client-56 = %{mysql_version}-%{mysql_release}%{mysql_dist}
+Requires: Percona-Server-server-56 = %{_mysql_version}-%{_mysql_release}%{_mysql_dist}
+Requires: Percona-Server-client-56 = %{_mysql_version}-%{_mysql_release}%{_mysql_dist}
Requires: groonga-libs >= %{groonga_required_version}
Requires: groonga-normalizer-mysql
@@ -55,23 +55,26 @@ Documentation for Mroonga
%prep
%setup -q -n mroonga-%{version}
-mysql_full_version=%{mysql_version}-%{mysql_release}.generic
+mysql_full_version=%{_mysql_version}-%{_mysql_release}.generic
srpm=Percona-Server-56-${mysql_full_version}.src.rpm
if [ ! -f ../../SRPMS/$srpm ]; then
- wget --continue -O ../../SRPMS/$srpm %{mysql_download_base_url}/$srpm
+ wget --continue -O ../../SRPMS/$srpm %{_mysql_download_base_url}/$srpm
rpm -Uvh ../../SRPMS/$srpm
fi
%build
-mysql_source=../percona-server-%{mysql_version}-$(echo %{mysql_release} | sed -e 's/rel//')
+mysql_source=../percona-server-%{_mysql_version}-$(echo %{_mysql_release} | sed -e 's/rel//')
if [ ! -d ${mysql_source} ]; then
specs_dir=
rpmbuild -bp \
--define 'runselftest 0' \
--define 'optflags -O0' \
- ../../SPECS/%{mysql_spec_file}
+ ../../SPECS/%{_mysql_spec_file}
fi
-%configure --disable-static --with-mysql-source=${mysql_source} \
+%configure \
+ --disable-static \
+ --with-mysql-source=${mysql_source} \
+ --enable-fast-mutexes \
%{?mroonga_configure_options}
make %{?_smp_mflags}
@@ -94,9 +97,11 @@ fi
mysql_command=`which mysql`
password_option=""
-$mysql_command -u root -e "quit"
-if [ $? -ne 0 ]; then
- password_option="-p"
+
+if $mysql_command -u root -e "quit" > /dev/null 2>&1; then
+ password_option=""
+else
+ password_option="-p"
fi
current_version=0
version=`echo %{groonga_required_version} | sed -e 's/\.//g'`
@@ -144,7 +149,7 @@ fi
uninstall_sql=%{_datadir}/mroonga/uninstall.sql
mysql_command=`which mysql`
-if $mysql_command -u root -e "quit"; then
+if $mysql_command -u root -e "quit" > /dev/null 2>&1; then
password_option=""
else
password_option="-p"
@@ -174,5 +179,95 @@ fi
%doc mysql-mroonga-doc/*
%changelog
+* Thu Oct 12 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.07-1
+- new upstream release.
+
+* Tue Aug 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.06-1
+- new upstream release.
+
+* Mon Aug 14 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.05-2
+- build against Percona Server 5.6.36rel82.1 Reported by @tigersun2000_twitter. Thanks!!!
+
+* Sat Jul 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.05-1
+- new upstream release.
+
+* Thu Jun 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.04-1
+- new upstream release.
+
+* Mon May 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.03-1
+- new upstream release.
+
+* Thu May 17 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.02-2
+- build against Percona Server 5.6.36. Reported by @pinpikokun. Thanks!!!
+
+* Sat Apr 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.02-1
+- new upstream release.
+
+* Wed Mar 29 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.01-1
+- new upstream release.
+
+* Thu Feb 09 2017 Kentaro Hayashi <hayashi@clear-code.com> - 7.00-1
+- new upstream release.
+
+* Fri Jan 13 2017 Kouhei Sutou <kou@clear-code.com> - 6.13-1
+- new upstream release.
+
+* Thu Dec 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.12-1
+- new upstream release.
+
+* Tue Nov 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.11-1
+- new upstream release.
+
+* Sat Oct 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.10-1
+- new upstream release.
+
+* Mon Oct 24 2016 Kouhei Sutou <kou@clear-code.com> - 6.09-2
+- build against Percona Server 5.6.33. Reported by Hiroshi Kagami. Thanks!!!
+
+* Thu Sep 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.09-1
+- new upstream release.
+
+* Mon Aug 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.08-1
+- new upstream release.
+
+* Fri Jul 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.07-1
+- new upstream release.
+
+* Thu Jun 30 2016 Masafumi Yokoyama <yokoyama@clear-code.com> - 6.06-1
+- new upstream release.
+
+* Wed Jun 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.05-1
+- new upstream release.
+
+* Sun May 29 2016 Kentaro Hayashi <hayashi@clear-code.com> - 6.03-1
+- new upstream release.
+
+* Fri Apr 29 2016 HAYASHI Kentaro <hayashi@clear-code.com> - 6.02-1
+- new upstream release.
+
+* Tue Mar 29 2016 Masafumi Yokoyama <yokoyama@clear-code.com> - 6.01-1
+- new upstream release.
+
+* Mon Feb 29 2016 Kouhei Sutou <kou@clear-code.com> - 6.00-1
+- new upstream release.
+
+* Fri Jan 29 2016 Kouhei Sutou <kou@clear-code.com> - 5.12-1
+- new upstream release.
+
+* Tue Dec 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.11-1
+- new upstream release.
+
+* Sun Nov 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.10-1
+- new upstream release.
+
+* Thu Oct 29 2015 Kouhei Sutou <kou@cozmixng.org> - 5.09-1
+- new upstream release.
+
+* Tue Sep 29 2015 Kouhei Sutou <kou@clear-code.com> - 5.08-1
+- new upstream release.
+
+* Mon Aug 31 2015 Kouhei Sutou <kou@clear-code.com> - 5.06-1
+- new upstream release.
+
* Tue Mar 17 2015 Kouhei Sutou <kou@clear-code.com> - 5.00-1
- initial release.
diff --git a/storage/mroonga/packages/source/Makefile.am b/storage/mroonga/packages/source/Makefile.am
index 143f5d0387e..efd09777add 100644
--- a/storage/mroonga/packages/source/Makefile.am
+++ b/storage/mroonga/packages/source/Makefile.am
@@ -1,17 +1,17 @@
MROONGA_BASE = $(PACKAGE)-$(VERSION)
MROONGA_TAR_GZ = $(MROONGA_BASE).tar.gz
-GROONGA_VERSION = 5.0.5
+GROONGA_VERSION = 7.0.7
GROONGA_BASE = groonga-$(GROONGA_VERSION)
GROONGA_TAR_GZ = $(GROONGA_BASE).tar.gz
-GROONGA_NORMALIZER_MYSQL_VERSION = 1.1.0
+GROONGA_NORMALIZER_MYSQL_VERSION = 1.1.1
GROONGA_NORMALIZER_MYSQL_BASE = \
groonga-normalizer-mysql-$(GROONGA_NORMALIZER_MYSQL_VERSION)
GROONGA_NORMALIZER_MYSQL_TAR_GZ = \
$(GROONGA_NORMALIZER_MYSQL_BASE).tar.gz
-MARIADB_VERSION = 10.0.20
+MARIADB_VERSION = 10.1.28
MARIADB_BASE = mariadb-$(MARIADB_VERSION)
MARIADB_TAR_GZ = $(MARIADB_BASE).tar.gz
@@ -29,7 +29,7 @@ CURL = curl --fail --silent --show-error
all:
-release: archive upload
+release: download archive upload
ensure-rsync-path:
@if test -z "$(RSYNC_PATH)"; then \
@@ -88,6 +88,8 @@ tmp/$(MARIADB_WITH_MROONGA_BASE).stamp: $(MARIADB_WITH_MROONGA_ARCHIVES)
mkdir -p $$(dirname $(BUNDLED_GROONGA_PATH))
tar xf tmp/$(GROONGA_TAR_GZ)
rm -rf $(GROONGA_BASE)/test
+ cd $(GROONGA_BASE)/vendor && ruby download_mecab.rb
+ cd $(GROONGA_BASE)/vendor && ruby download_lz4.rb
mv $(GROONGA_BASE) $(BUNDLED_GROONGA_PATH)
tar xf tmp/$(GROONGA_NORMALIZER_MYSQL_TAR_GZ)
@@ -103,7 +105,7 @@ files/$(MARIADB_WITH_MROONGA_BASE).tar.gz: tmp/$(MARIADB_WITH_MROONGA_BASE).stam
mkdir -p files/
(cd tmp && tar czf ../$@ $(MARIADB_WITH_MROONGA_BASE))
-PATCHES = \
+PATCHES = \
patches/mariadb-10.0.3-windows-build.diff
tmp/$(MARIADB_WITH_MROONGA_FOR_WINDOWS_BASE).stamp: tmp/$(MARIADB_WITH_MROONGA_BASE).stamp $(PATCHES)
diff --git a/storage/mroonga/packages/ubuntu/Makefile.am b/storage/mroonga/packages/ubuntu/Makefile.am
index 2297a50bfc9..7241391bcbf 100644
--- a/storage/mroonga/packages/ubuntu/Makefile.am
+++ b/storage/mroonga/packages/ubuntu/Makefile.am
@@ -1,5 +1,13 @@
-CODE_NAMES = precise,trusty,utopic,vivid
+CODE_NAMES = trusty,xenial,zesty
SOURCE = ../$(PACKAGE)-$(VERSION).tar.gz
+SOURCE_55_BASE = $(PACKAGE)-5.5
+SOURCE_55 = $(SOURCE_55_BASE)_$(VERSION).orig.tar.gz
+SOURCE_56_BASE = $(PACKAGE)-5.6
+SOURCE_56 = $(SOURCE_56_BASE)_$(VERSION).orig.tar.gz
+SOURCE_57_BASE = $(PACKAGE)-5.7
+SOURCE_57 = $(SOURCE_57_BASE)_$(VERSION).orig.tar.gz
+SOURCE_MARIADB_10_0_BASE = $(PACKAGE)-mariadb-10.0
+SOURCE_MARIADB_10_0 = $(SOURCE_MARIADB_10_0_BASE)_$(VERSION).orig.tar.gz
all:
@@ -13,12 +21,37 @@ upload: source ensure-launchpad-configuration
./upload.rb \
--package '$(PACKAGE)' \
--version '$(VERSION)' \
- --source-archive '$(SOURCE)' \
+ --source-archive-directory '$(builddir)/' \
--code-names '$(CODE_NAMES)' \
- --debian-directory '$(srcdir)/../debian/' \
+ --debian-base-directory '$(srcdir)/../' \
+ --ppa '$(LAUNCHPAD_PPA)' \
--pgp-sign-key '$(LAUNCHPAD_UPLOADER_PGP_KEY)'
-source: $(SOURCE)
+source: $(SOURCE_55) $(SOURCE_56) $(SOURCE_57) $(SOURCE_MARIADB_10_0)
$(SOURCE):
ln -s $(abs_top_builddir)/$(PACKAGE)-$(VERSION).tar.gz $(SOURCE)
+
+$(SOURCE_55): $(SOURCE)
+ tar xf $(SOURCE)
+ mv $(PACKAGE)-$(VERSION) $(SOURCE_55_BASE)-$(VERSION)
+ tar cfz $(SOURCE_55) $(SOURCE_55_BASE)-$(VERSION)
+ rm -r $(SOURCE_55_BASE)-$(VERSION)
+
+$(SOURCE_56): $(SOURCE)
+ tar xf $(SOURCE)
+ mv $(PACKAGE)-$(VERSION) $(SOURCE_56_BASE)-$(VERSION)
+ tar cfz $(SOURCE_56) $(SOURCE_56_BASE)-$(VERSION)
+ rm -r $(SOURCE_56_BASE)-$(VERSION)
+
+$(SOURCE_57): $(SOURCE)
+ tar xf $(SOURCE)
+ mv $(PACKAGE)-$(VERSION) $(SOURCE_57_BASE)-$(VERSION)
+ tar cfz $(SOURCE_57) $(SOURCE_57_BASE)-$(VERSION)
+ rm -r $(SOURCE_57_BASE)-$(VERSION)
+
+$(SOURCE_MARIADB_10_0): $(SOURCE)
+ tar xf $(SOURCE)
+ mv $(PACKAGE)-$(VERSION) $(SOURCE_MARIADB_10_0_BASE)-$(VERSION)
+ tar cfz $(SOURCE_MARIADB_10_0) $(SOURCE_MARIADB_10_0_BASE)-$(VERSION)
+ rm -r $(SOURCE_MARIADB_10_0_BASE)-$(VERSION)
diff --git a/storage/mroonga/packages/ubuntu/upload.rb b/storage/mroonga/packages/ubuntu/upload.rb
index 8743520b5ac..1fedb2ecbe6 100755
--- a/storage/mroonga/packages/ubuntu/upload.rb
+++ b/storage/mroonga/packages/ubuntu/upload.rb
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
#
-# Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2014-2016 Kouhei Sutou <kou@clear-code.com>
# Copyright(C) 2014 HAYASHI Kentaro <hayashi@clear-code.com>
#
# This library is free software; you can redistribute it and/or
@@ -24,6 +24,7 @@ require "open-uri"
class Uploader
def initialize
@dput_configuration_name = "groonga-ppa"
+ @use_pbuilder = false
end
def run
@@ -36,7 +37,22 @@ class Uploader
@required_groonga_version = required_groonga_version
@code_names.each do |code_name|
- upload(code_name)
+ mysql55_version = @mysql55_versions[code_name]
+ mysql56_version = @mysql56_versions[code_name]
+ mysql57_version = @mysql57_versions[code_name]
+ mariadb10_0_version = @mariadb10_0_versions[code_name]
+ if mysql55_version
+ upload(code_name, "5.5", mysql55_version)
+ end
+ if mysql56_version
+ upload(code_name, "5.6", mysql56_version)
+ end
+ if mysql57_version
+ upload(code_name, "5.7", mysql57_version)
+ end
+ if mariadb10_0_version
+ upload(code_name, "mariadb-10.0", mariadb10_0_version)
+ end
end
end
@@ -66,18 +82,37 @@ allow_unsigned_uploads = 0
end
def ensure_mysql_version
- @mysql_version = {}
+ @mysql_versions = {}
+ @mysql55_versions = {}
+ @mysql56_versions = {}
+ @mysql57_versions = {}
+ @mariadb10_0_versions = {}
@code_names.each do |code_name|
- open("http://packages.ubuntu.com/#{code_name}/allpackages?format=txt.gz") do |file|
- file.each_line do |line|
- @mysql_version[code_name] = $1 if line =~ /\Amysql-server \((.+?)\).+/
+ source_names = [code_name, "#{code_name}-updates"]
+ source_names.each do |source_name|
+ allpackages_url =
+ "http://packages.ubuntu.com/#{source_name}/allpackages?format=txt.gz"
+ open(allpackages_url) do |file|
+ file.each_line do |line|
+ case line
+ when /\Amysql-server \((.+?)[\s)]/
+ @mysql_versions[code_name] = $1
+ when /\Amysql-server-5\.5 \((.+?)[\s)]/
+ @mysql55_versions[code_name] = $1
+ when /\Amysql-server-5\.6 \((.+?)[\s)]/
+ @mysql56_versions[code_name] = $1
+ when /\Amysql-server-5\.7 \((.+?)[\s)]/
+ @mysql57_versions[code_name] = $1
+ when /\Amariadb-server-10\.0 \((.+?)[\s)]/
+ @mariadb10_0_versions[code_name] = $1
+ end
+ end
end
end
end
end
def parse_command_line!
-
parser = OptionParser.new
parser.on("--package=NAME",
"The package name") do |name|
@@ -87,59 +122,97 @@ allow_unsigned_uploads = 0
"The version") do |version|
@version = version
end
- parser.on("--source-archive=ARCHIVE",
- "The source archive") do |source_archive|
- @source_archive = Pathname.new(source_archive).expand_path
+ parser.on("--source-archive-directory=DIRECTORY",
+ "The directory that has source archives") do |directory|
+ @source_archive_directory = Pathname.new(directory).expand_path
end
parser.on("--code-names=CODE_NAME1,CODE_NAME2,CODE_NAME3,...", Array,
"The target code names") do |code_names|
@code_names = code_names
end
- parser.on("--debian-directory=DIRECTORY",
- "The debian/ directory") do |debian_directory|
- @debian_directory = Pathname.new(debian_directory).expand_path
+ parser.on("--debian-base-directory=DIRECTORY",
+ "The directory that has debianXX/ directory") do |directory|
+ @debian_base_directory = Pathname.new(directory).expand_path
+ end
+ parser.on("--ppa=PPA",
+ "The personal package archive name (groonga-ppa or groonga-nightly") do |ppa|
+ @dput_configuration_name = ppa
end
parser.on("--pgp-sign-key=KEY",
"The PGP key to sign .changes and .dsc") do |pgp_sign_key|
@pgp_sign_key = pgp_sign_key
end
- parser.on("--pbuilder",
- "Use pbuilder for build check") do |pbuilder|
- @use_pbuilder = pbuilder
+ parser.on("--[no-]pbuilder",
+ "Use pbuilder for build check") do |use_pbuilder|
+ @use_pbuilder = use_pbuilder
end
parser.parse!
end
- def upload(code_name)
+ def upload(code_name, mysql_short_version, mysql_version)
+ default_mysql_version = (@mysql_versions[code_name] == mysql_version)
+ deb_package_name = "#{@package}-#{mysql_short_version}"
in_temporary_directory do
- FileUtils.cp(@source_archive.to_s,
- "#{@package}_#{@version}.orig.tar.gz")
- run_command("tar", "xf", @source_archive.to_s)
- directory_name = "#{@package}-#{@version}"
+ source_archive =
+ @source_archive_directory + "#{deb_package_name}_#{@version}.orig.tar.gz"
+ run_command("tar", "xf", source_archive.to_s)
+ directory_name = "#{deb_package_name}-#{@version}"
Dir.chdir(directory_name) do
- FileUtils.cp_r(@debian_directory.to_s, "debian")
+ debian_directory =
+ @debian_base_directory + "debian-#{mysql_short_version}"
+ FileUtils.cp_r(debian_directory.to_s, "debian")
deb_version = "#{current_deb_version.succ}~#{code_name}1"
run_command("dch",
"--distribution", code_name,
"--newversion", deb_version,
"Build for #{code_name}.")
- case code_name
- when "vivid"
- run_command("sed",
- "-i", "-e", "s,5\\.5,5.6,g",
- "debian/rules")
+ remove_versionless_mroonga = true
+ if default_mysql_version or mysql_short_version.start_with?("mariadb-")
+ remove_versionless_mroonga = false
+ end
+ if remove_versionless_mroonga
+ control_content = File.read("debian/control")
+ File.open("debian/control", "w") do |control|
+ in_mysql_server_mroonga = false
+ control_content.each_line do |line|
+ case line.chomp
+ when ""
+ if in_mysql_server_mroonga
+ in_mysql_server_mroonga = false
+ else
+ control.print(line)
+ end
+ when "Package: mysql-server-mroonga"
+ in_mysql_server_mroonga = true
+ else
+ next if in_mysql_server_mroonga
+ control.print(line)
+ end
+ end
+ end
end
run_command("sed",
- "-i", "-e", "s,MYSQL_VERSION,#{@mysql_version[code_name]},",
+ "-i", "-e",
+ "s,MYSQL_VERSION\\|MARIADB_VERSION,#{mysql_version},",
"debian/control")
- run_command("debuild", "-S", "-sa", "-pgpg2", "-k#{@pgp_sign_key}")
+ run_command("debuild",
+ "--no-lintian",
+ # Workaround for Launchpad. Launchpad doesn't accept
+ # .buildinfo yet.
+ # See also: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=853795
+ "--buildinfo-option=-O",
+ "-d",
+ "-S",
+ "-sa",
+ "-pgpg2",
+ "-k#{@pgp_sign_key}")
if @use_pbuilder
run_command("pbuilder-dist", code_name, "build",
- "../#{@package}_#{deb_version}.dsc")
+ "../#{deb_package_name}_#{deb_version}.dsc")
else
run_command("dput", @dput_configuration_name,
- "../#{@package}_#{deb_version}_source.changes")
+ "../#{deb_package_name}_#{deb_version}_source.changes")
end
end
end
diff --git a/storage/mroonga/packages/windows/Makefile.am b/storage/mroonga/packages/windows/Makefile.am
index 192709fac6d..240c3873a89 100644
--- a/storage/mroonga/packages/windows/Makefile.am
+++ b/storage/mroonga/packages/windows/Makefile.am
@@ -1,12 +1,12 @@
EXTRA_DIST = \
README.md \
- build-vc2013.bat \
- build-vc2013-zip-32.bat \
- build-vc2013-zip-64.bat \
- build-vc2013-msi-32.bat \
- build-vc2013-msi-64.bat \
build-vc2015.bat \
build-vc2015-zip-32.bat \
build-vc2015-zip-64.bat \
build-vc2015-msi-32.bat \
- build-vc2015-msi-64.bat
+ build-vc2015-msi-64.bat \
+ build-vc2017.bat \
+ build-vc2017-zip-32.bat \
+ build-vc2017-zip-64.bat \
+ build-vc2017-msi-32.bat \
+ build-vc2017-msi-64.bat
diff --git a/storage/mroonga/packages/windows/README.md b/storage/mroonga/packages/windows/README.md
index f220634b1e7..8737f26232a 100644
--- a/storage/mroonga/packages/windows/README.md
+++ b/storage/mroonga/packages/windows/README.md
@@ -6,16 +6,16 @@ TODO...
## Build with Visual C++ Express
-You need to use Visual C++ 2013 or later to build Mroonga with Express
-edition. `build-vc2013.bat` is a build batch script to build with
-Visual C++ Express 2013.
+You need to use Visual Studio 2015 for Windows Desktop or later to build Mroonga with express
+edition. `build-vc2015.bat` is a build batch script to build with
+Visual Studio 2015 for Windows Desktop.
Note that you can't build MSI file with Express edition. You need to
use Professional edition or upper editions to build MSI file.
-## Build with Visual C++ Professional
+## Build with Visual Studio Community
You can build both zip file MSI file with Professional edition.
But now, this feature is temporary disabled.
-If you want to create MSI package, please uncomment in `build-vc2013.bat`.
-And then, you can build MSI package with Visual Studio 2013 Professional.
+If you want to create MSI package, please uncomment in `build-vc2015.bat`.
+And then, you can build MSI package with Visual Studio 2015 Community.
diff --git a/storage/mroonga/packages/windows/build-vc2013-msi-32.bat b/storage/mroonga/packages/windows/build-vc2013-msi-32.bat
deleted file mode 100644
index 22b29972885..00000000000
--- a/storage/mroonga/packages/windows/build-vc2013-msi-32.bat
+++ /dev/null
@@ -1,8 +0,0 @@
-rmdir /S /Q build-vc2013-msi-32
-mkdir build-vc2013-msi-32
-cd build-vc2013-msi-32
-cmake ..\source -G "Visual Studio 12" > config.log
-cmake --build . --config RelWithDebInfo > build.log
-cmake --build . --config RelWithDebInfo --target msi > msi.log
-move *.msi ..\
-cd ..
diff --git a/storage/mroonga/packages/windows/build-vc2013-msi-64.bat b/storage/mroonga/packages/windows/build-vc2013-msi-64.bat
deleted file mode 100644
index c83a376cdb9..00000000000
--- a/storage/mroonga/packages/windows/build-vc2013-msi-64.bat
+++ /dev/null
@@ -1,8 +0,0 @@
-rmdir /S /Q build-vc2013-msi-64
-mkdir build-vc2013-msi-64
-cd build-vc2013-msi-64
-cmake ..\source -G "Visual Studio 12 Win64" > config.log
-cmake --build . --config RelWithDebInfo > build.log
-cmake --build . --config RelWithDebInfo --target msi > msi.log
-move *.msi ..\
-cd ..
diff --git a/storage/mroonga/packages/windows/build-vc2013-zip-32.bat b/storage/mroonga/packages/windows/build-vc2013-zip-32.bat
deleted file mode 100644
index d3e0e4f8b8e..00000000000
--- a/storage/mroonga/packages/windows/build-vc2013-zip-32.bat
+++ /dev/null
@@ -1,8 +0,0 @@
-rmdir /S /Q build-vc2013-zip-32
-mkdir build-vc2013-zip-32
-cd build-vc2013-zip-32
-cmake ..\source -G "Visual Studio 12" -DMRN_GROONGA_EMBED=OFF -DMRN_GROONGA_NORMALIZER_MYSQL_EMBED=OFF > config.log
-cmake --build . --config RelWithDebInfo > build.log
-cmake --build . --config RelWithDebInfo --target package > zip.log
-move *.zip ..\
-cd ..
diff --git a/storage/mroonga/packages/windows/build-vc2013-zip-64.bat b/storage/mroonga/packages/windows/build-vc2013-zip-64.bat
deleted file mode 100644
index 6ca288b6a8b..00000000000
--- a/storage/mroonga/packages/windows/build-vc2013-zip-64.bat
+++ /dev/null
@@ -1,8 +0,0 @@
-rmdir /S /Q build-vc2013-zip-64
-mkdir build-vc2013-zip-64
-cd build-vc2013-zip-64
-cmake ..\source -G "Visual Studio 12 Win64" -DMRN_GROONGA_EMBED=OFF -DMRN_GROONGA_NORMALIZER_MYSQL_EMBED=OFF > config.log
-cmake --build . --config RelWithDebInfo > build.log
-cmake --build . --config RelWithDebInfo --target package > zip.log
-move *.zip ..\
-cd ..
diff --git a/storage/mroonga/packages/windows/build-vc2013.bat b/storage/mroonga/packages/windows/build-vc2013.bat
deleted file mode 100644
index 99d7e4042c5..00000000000
--- a/storage/mroonga/packages/windows/build-vc2013.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-build-vc2013-zip-32.bat
-build-vc2013-zip-64.bat
-REM build-vc2013-msi-32.bat
-REM build-vc2013-msi-64.bat
diff --git a/storage/mroonga/packages/windows/build-vc2015-msi-32.bat b/storage/mroonga/packages/windows/build-vc2015-msi-32.bat
index 4c92b5c02cc..69d803e84fe 100644
--- a/storage/mroonga/packages/windows/build-vc2015-msi-32.bat
+++ b/storage/mroonga/packages/windows/build-vc2015-msi-32.bat
@@ -1,7 +1,7 @@
rmdir /S /Q build-vc2015-msi-32
mkdir build-vc2015-msi-32
cd build-vc2015-msi-32
-cmake ..\source -G "Visual Studio 14" > config.log
+cmake ..\source -G "Visual Studio 14 2015" > config.log
cmake --build . --config RelWithDebInfo > build.log
cmake --build . --config RelWithDebInfo --target msi > msi.log
move *.msi ..\
diff --git a/storage/mroonga/packages/windows/build-vc2015-msi-64.bat b/storage/mroonga/packages/windows/build-vc2015-msi-64.bat
index 82bc2a148ec..a3d6681bf3b 100644
--- a/storage/mroonga/packages/windows/build-vc2015-msi-64.bat
+++ b/storage/mroonga/packages/windows/build-vc2015-msi-64.bat
@@ -1,7 +1,7 @@
rmdir /S /Q build-vc2015-msi-64
mkdir build-vc2015-msi-64
cd build-vc2015-msi-64
-cmake ..\source -G "Visual Studio 14 Win64" > config.log
+cmake ..\source -G "Visual Studio 14 2015 Win64" > config.log
cmake --build . --config RelWithDebInfo > build.log
cmake --build . --config RelWithDebInfo --target msi > msi.log
move *.msi ..\
diff --git a/storage/mroonga/packages/windows/build-vc2015-zip-32.bat b/storage/mroonga/packages/windows/build-vc2015-zip-32.bat
index 5cef259afe5..8247fd542f3 100644
--- a/storage/mroonga/packages/windows/build-vc2015-zip-32.bat
+++ b/storage/mroonga/packages/windows/build-vc2015-zip-32.bat
@@ -1,7 +1,12 @@
rmdir /S /Q build-vc2015-zip-32
mkdir build-vc2015-zip-32
cd build-vc2015-zip-32
-cmake ..\source -G "Visual Studio 14" -DMRN_GROONGA_EMBED=OFF -DMRN_GROONGA_NORMALIZER_MYSQL_EMBED=OFF > config.log
+cmake ..\source -G "Visual Studio 14 2015" ^
+ -DMRN_GROONGA_EMBED=OFF ^
+ -DMRN_GROONGA_NORMALIZER_MYSQL_EMBED=OFF ^
+ -DGRN_WITH_BUNDLED_LZ4=ON ^
+ -DGRN_WITH_BUNDLED_MECAB=ON ^
+ > config.log
cmake --build . --config RelWithDebInfo > build.log
cmake --build . --config RelWithDebInfo --target package > zip.log
move *.zip ..\
diff --git a/storage/mroonga/packages/windows/build-vc2015-zip-64.bat b/storage/mroonga/packages/windows/build-vc2015-zip-64.bat
index caabca179e7..b56d80eb151 100644
--- a/storage/mroonga/packages/windows/build-vc2015-zip-64.bat
+++ b/storage/mroonga/packages/windows/build-vc2015-zip-64.bat
@@ -1,7 +1,12 @@
rmdir /S /Q build-vc2015-zip-64
mkdir build-vc2015-zip-64
cd build-vc2015-zip-64
-cmake ..\source -G "Visual Studio 14 Win64" -DMRN_GROONGA_EMBED=OFF -DMRN_GROONGA_NORMALIZER_MYSQL_EMBED=OFF > config.log
+cmake ..\source -G "Visual Studio 14 2015 Win64" ^
+ -DMRN_GROONGA_EMBED=OFF ^
+ -DMRN_GROONGA_NORMALIZER_MYSQL_EMBED=OFF ^
+ -DGRN_WITH_BUNDLED_LZ4=ON ^
+ -DGRN_WITH_BUNDLED_MECAB=ON ^
+ > config.log
cmake --build . --config RelWithDebInfo > build.log
cmake --build . --config RelWithDebInfo --target package > zip.log
move *.zip ..\
diff --git a/storage/mroonga/packages/windows/build-vc2015.bat b/storage/mroonga/packages/windows/build-vc2015.bat
index f9ac1765792..729f181dbe3 100644
--- a/storage/mroonga/packages/windows/build-vc2015.bat
+++ b/storage/mroonga/packages/windows/build-vc2015.bat
@@ -1,4 +1,4 @@
-build-vc2015-zip-32.bat
-build-vc2015-zip-64.bat
+call build-vc2015-zip-32.bat
+call build-vc2015-zip-64.bat
REM build-vc2015-msi-32.bat
REM build-vc2015--msi-64.bat
diff --git a/storage/mroonga/packages/yum/Makefile.am b/storage/mroonga/packages/yum/Makefile.am
index 8321619868f..9d1bd6061c6 100644
--- a/storage/mroonga/packages/yum/Makefile.am
+++ b/storage/mroonga/packages/yum/Makefile.am
@@ -1,7 +1,16 @@
REPOSITORIES_PATH = repositories
DISTRIBUTIONS = centos
ARCHITECTURES = i386 x86_64
-MYSQL_VARIANTS = mysql55 mysql56-community mariadb percona-server-56
+MYSQL_VARIANTS = \
+ mysql55 \
+ mysql56-community \
+ mysql57-community \
+ mariadb \
+ mariadb-10.1 \
+ mariadb-10.2 \
+ percona-server-56 \
+ percona-server-57
+CENTOS_VERSIONS = 6 7
SPEC_DIR = $(builddir)/../rpm/centos
all:
@@ -47,7 +56,8 @@ build-in-vm: source specs env.sh
"$(PACKAGE)" \
"$(SPEC_DIR)" \
"$(MYSQL_VARIANTS)" \
- "$(ARCHITECTURES)"
+ "$(ARCHITECTURES)" \
+ "$(CENTOS_VERSIONS)"
source: tmp/$(PACKAGE)-$(VERSION).tar.gz
@@ -61,4 +71,7 @@ $(abs_top_builddir)/$(PACKAGE)-$(VERSION).tar.gz:
specs: $(SPEC_DIR)/mysql55-$(PACKAGE).spec
specs: $(SPEC_DIR)/mysql56-community-$(PACKAGE).spec
specs: $(SPEC_DIR)/mariadb-$(PACKAGE).spec
+specs: $(SPEC_DIR)/mariadb-10.1-$(PACKAGE).spec
+specs: $(SPEC_DIR)/mariadb-10.2-$(PACKAGE).spec
specs: $(SPEC_DIR)/percona-server-56-$(PACKAGE).spec
+specs: $(SPEC_DIR)/percona-server-57-$(PACKAGE).spec
diff --git a/storage/mroonga/packages/yum/Vagrantfile b/storage/mroonga/packages/yum/Vagrantfile
index da41350eed3..af14bc9a76b 100644
--- a/storage/mroonga/packages/yum/Vagrantfile
+++ b/storage/mroonga/packages/yum/Vagrantfile
@@ -7,31 +7,22 @@ VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
vms = [
{
- :id => "centos-5-i386",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-5.11-i386_chef-provisionerless.box",
- },
- {
- :id => "centos-5-x86_64",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-5.11_chef-provisionerless.box",
- },
- {
:id => "centos-6-i386",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.6-i386_chef-provisionerless.box",
+ :box => "bento/centos-6.9-i386",
},
{
:id => "centos-6-x86_64",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.6_chef-provisionerless.box",
+ :box => "bento/centos-6.9",
},
{
:id => "centos-7-x86_64",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-7.1_chef-provisionerless.box",
+ :box => "bento/centos-7.4",
},
]
vms.each do |vm|
config.vm.define(vm[:id]) do |node|
- node.vm.box = vm[:id]
- node.vm.box_url = vm[:box_url]
+ node.vm.box = vm[:box]
node.vm.provision(:shell, :path => "build-rpm.sh")
node.vm.provider("virtualbox") do |virtual_box|
system_n_cpus = 1
@@ -44,6 +35,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
vm_n_cpus = 1
end
virtual_box.cpus = vm_n_cpus
+ virtual_box.memory = (ENV["VM_MEMORY"] || 1024).to_i
end
end
end
diff --git a/storage/mroonga/packages/yum/build-in-vm.sh b/storage/mroonga/packages/yum/build-in-vm.sh
index cf9ef581fd0..fc84e45024c 100755
--- a/storage/mroonga/packages/yum/build-in-vm.sh
+++ b/storage/mroonga/packages/yum/build-in-vm.sh
@@ -1,8 +1,8 @@
#!/bin/sh
-if [ $# != 4 ]; then
+if [ $# != 5 ]; then
echo "Usage: $0 PACKAGE SPEC_DIR MYSQL_VARIANTS ARCHITECTURES"
- echo " e.g.: $0 mroonga ../rpm/centos 'mysql55 mariadb' 'i386 x86_64'"
+ echo " e.g.: $0 mroonga ../rpm/centos 'mysql55 mariadb' 'i386 x86_64' '6 7'"
exit 1
fi
@@ -10,6 +10,7 @@ PACKAGE="$1"
SPEC_DIR="$2"
MYSQL_VARIANTS="$3"
ARCHITECTURES="$4"
+CENTOS_VERSIONS="$5"
run()
{
@@ -30,21 +31,42 @@ for mysql_variant in ${MYSQL_VARIANTS}; do
architectures="${ARCHITECTURES}"
case ${mysql_variant} in
mysql55)
- centos_versions="5 6"
+ centos_versions="6"
;;
mysql56-community)
centos_versions="6 7"
;;
+ mysql57-community)
+ centos_versions="6 7"
+ ;;
mariadb)
centos_versions="7"
;;
+ mariadb-10.1)
+ centos_versions="6 7"
+ ;;
+ mariadb-10.2)
+ centos_versions="6 7"
+ ;;
percona-server-56)
centos_versions="6 7"
;;
+ percona-server-57)
+ centos_versions="6 7"
+ ;;
esac
for architecture in ${architectures}; do
for centos_version in ${centos_versions}; do
+ skip=1
+ for given_version in ${CENTOS_VERSIONS}; do
+ if [ ${given_version} = ${centos_version} ]; then
+ skip=0
+ fi
+ done
+ if [ $skip -eq 1 ]; then
+ continue
+ fi
if [ ${mysql_variant} = mysql55 -a ${centos_version} = 6 -a ${architecture} = i386 ]; then
continue
fi
diff --git a/storage/mroonga/packages/yum/build-rpm.sh b/storage/mroonga/packages/yum/build-rpm.sh
index 8661e659390..6ba943ae74d 100755
--- a/storage/mroonga/packages/yum/build-rpm.sh
+++ b/storage/mroonga/packages/yum/build-rpm.sh
@@ -70,36 +70,94 @@ case ${distribution} in
run yum install -y mariadb-devel
;;
centos)
+ release_rpm=groonga-release-1.3.0-1.noarch.rpm
+ if [ ${distribution_version} = 5 ]; then
+ wget http://packages.groonga.org/${distribution}/${release_rpm}
+ run yum install -y --nogpgcheck ${release_rpm}
+ rm -f ${release_rpm}
+ else
+ run yum install -y \
+ http://packages.groonga.org/${distribution}/${release_rpm}
+ fi
+ run yum makecache
+
case ${package_name} in
mysql55-${PACKAGE})
USE_MYSQLSERVICES_COMPAT=yes
run yum install -y scl-utils-build
if [ ${distribution_version} = 6 ]; then
- run yum install -y centos-release-SCL
+ run yum install -y centos-release-scl
fi
run yum install -y mysql55-mysql-devel mysql55-build
;;
- mysql56-community-${PACKAGE})
- release_rpm=mysql-community-release-el${distribution_version}-5.noarch.rpm
+ mysql5?-community-${PACKAGE})
+ release_rpm=mysql-community-release-el${distribution_version}-7.noarch.rpm
run yum -y install http://repo.mysql.com/${release_rpm}
- run yum -y install mysql-community-devel
+ if [ "${package_name}" = "mysql57-community-${PACKAGE}" ]; then
+ run yum install -y yum-utils
+ run yum-config-manager --disable mysql56-community
+ run yum-config-manager --enable mysql57-community
+ if [ ${distribution_version} = 6 ]; then
+ run yum install -y cmake28
+ fi
+ fi
+ run yum install -y mysql-community-devel
;;
mariadb-${PACKAGE})
- run yum -y install mariadb-devel
- ;;
+ run yum install -y mariadb-devel
+ ;;
+ mariadb-10.1-${PACKAGE})
+ if [ "${architecture}" = "x86_64" ]; then
+ mariadb_architecture="amd64"
+ else
+ mariadb_architecture="x86"
+ fi
+ cat <<REPO > /etc/yum.repos.d/MariaDB.repo
+[mariadb]
+name = MariaDB
+baseurl = http://yum.mariadb.org/10.1/${distribution}${distribution_version}-${mariadb_architecture}
+gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
+gpgcheck=1
+REPO
+ run yum install -y MariaDB-devel
+ if [ ${distribution_version} = 6 ]; then
+ run yum install -y cmake28
+ fi
+ ;;
+ mariadb-10.2-${PACKAGE})
+ if [ "${architecture}" = "x86_64" ]; then
+ mariadb_architecture="amd64"
+ else
+ mariadb_architecture="x86"
+ fi
+ cat <<REPO > /etc/yum.repos.d/MariaDB.repo
+[mariadb]
+name = MariaDB
+baseurl = http://yum.mariadb.org/10.2/${distribution}${distribution_version}-${mariadb_architecture}
+gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
+gpgcheck=1
+REPO
+ run yum install -y MariaDB-devel
+ if [ ${distribution_version} = 6 ]; then
+ run yum install -y cmake28
+ fi
+ ;;
percona-server-56-${PACKAGE})
- release_rpm_version=0.1-3
+ release_rpm_version=0.1-4
+ release_rpm=percona-release-${release_rpm_version}.noarch.rpm
+ run yum install -y http://www.percona.com/downloads/percona-release/redhat/${release_rpm_version}/${release_rpm}
+ run yum install -y Percona-Server-devel-56
+ ;;
+ percona-server-57-${PACKAGE})
+ release_rpm_version=0.1-4
release_rpm=percona-release-${release_rpm_version}.noarch.rpm
- run yum -y install http://www.percona.com/downloads/percona-release/redhat/${release_rpm_version}/${release_rpm}
- run yum -y install Percona-Server-devel-56
+ run yum install -y http://www.percona.com/downloads/percona-release/redhat/${release_rpm_version}/${release_rpm}
+ run yum install -y Percona-Server-devel-57
+ if [ ${distribution_version} = 6 ]; then
+ run yum install -y cmake28
+ fi
;;
esac
-
- release_rpm=groonga-release-1.1.0-1.noarch.rpm
- wget http://packages.groonga.org/${distribution}/${release_rpm}
- run rpm -U ${release_rpm}
- rm -f ${release_rpm}
- run yum makecache
;;
esac
run yum install -y ${DEPENDED_PACKAGES}
@@ -109,6 +167,11 @@ if [ "${package_name}" = "percona-server-56-${PACKAGE}" ]; then
rpmbuild_options="$rpmbuild_options --define 'dist .el7'"
fi
fi
+if [ "${package_name}" = "percona-server-57-${PACKAGE}" ]; then
+ if [ "${distribution_version}" = "7" ]; then
+ rpmbuild_options="$rpmbuild_options --define 'dist .el7'"
+ fi
+fi
if [ "${USE_MYSQLSERVICES_COMPAT}" = "yes" ]; then
rpmbuild_options="$rpmbuild_options --define 'mroonga_configure_options --with-libmysqlservices-compat'"
fi
diff --git a/storage/mroonga/packages/yum/env.sh.in b/storage/mroonga/packages/yum/env.sh.in
index 8c6d05baf5c..3d327a17efb 100644
--- a/storage/mroonga/packages/yum/env.sh.in
+++ b/storage/mroonga/packages/yum/env.sh.in
@@ -9,6 +9,7 @@ make
gperf
readline-devel
openssl-devel
+zlib-devel
time
wget
ncurses-devel
@@ -23,6 +24,9 @@ perl-Env
perl-Test-Simple
pam-devel
selinux-policy-devel
+numactl-devel
groonga-devel
groonga-normalizer-mysql-devel
+cyrus-sasl-devel
+openldap-devel
"
diff --git a/storage/mroonga/packages/yum/update-repository.sh b/storage/mroonga/packages/yum/update-repository.sh
index 630b6c87422..59eeafa55aa 100755
--- a/storage/mroonga/packages/yum/update-repository.sh
+++ b/storage/mroonga/packages/yum/update-repository.sh
@@ -22,8 +22,6 @@ run()
for distribution in ${DISTRIBUTIONS}; do
for dir in ${DESTINATION}${distribution}/*/*; do
- # "--checksum sha" is for CentOS 5. If we drop CentOS 5 support,
- # we can remove the option.
- test -d $dir && run createrepo --checksum sha $dir
+ test -d $dir && run createrepo $dir
done;
done
diff --git a/storage/mroonga/plugin_version b/storage/mroonga/plugin_version
index 48c32b26a12..120096f1f8f 100644
--- a/storage/mroonga/plugin_version
+++ b/storage/mroonga/plugin_version
@@ -1 +1 @@
-5.4 \ No newline at end of file
+7.7 \ No newline at end of file
diff --git a/storage/mroonga/required_groonga_version b/storage/mroonga/required_groonga_version
index a1ef0cae183..024b4b9b53a 100644
--- a/storage/mroonga/required_groonga_version
+++ b/storage/mroonga/required_groonga_version
@@ -1 +1 @@
-5.0.2
+7.0.6
diff --git a/storage/mroonga/test/run-sql-test.sh b/storage/mroonga/test/run-sql-test.sh
index f1679dc70fa..d3aaf6aecf7 100755
--- a/storage/mroonga/test/run-sql-test.sh
+++ b/storage/mroonga/test/run-sql-test.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright(C) 2010 Tetsuro IKEDA
-# Copyright(C) 2010-2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2010-2017 Kouhei Sutou <kou@clear-code.com>
# Copyright(C) 2011 Kazuhiko
#
# This library is free software; you can redistribute it and/or
@@ -16,7 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
export BASE_DIR="$(cd $(dirname $0); pwd)"
top_dir="$BASE_DIR/.."
@@ -24,31 +24,44 @@ mroonga_test_dir="${top_dir}/mysql-test/mroonga"
n_processors=1
case `uname` in
- Linux)
- n_processors="$(grep '^processor' /proc/cpuinfo | wc -l)"
- ;;
- Darwin)
- n_processors="$(/usr/sbin/sysctl -n hw.ncpu)"
- ;;
- *)
- :
- ;;
+ Linux)
+ n_processors="$(grep '^processor' /proc/cpuinfo | wc -l)"
+ ;;
+ Darwin)
+ n_processors="$(/usr/sbin/sysctl -n hw.ncpu)"
+ ;;
+ *)
+ :
+ ;;
esac
if [ "$NO_MAKE" != "yes" ]; then
- MAKE_ARGS=
- if [ -n "$n_processors" ]; then
- MAKE_ARGS="-j${n_processors}"
- fi
- make $MAKE_ARGS -C $top_dir > /dev/null || exit 1
+ MAKE_ARGS=
+ if [ -n "$n_processors" ]; then
+ MAKE_ARGS="-j${n_processors}"
+ fi
+ make $MAKE_ARGS -C $top_dir > /dev/null || exit 1
fi
. "${top_dir}/config.sh"
bundled_groonga_normalizer_mysql_dir="${top_dir}/vendor/groonga/vendor/plugins/groonga-normalizer-mysql"
if [ -d "${bundled_groonga_normalizer_mysql_dir}" ]; then
- GRN_PLUGINS_DIR="${bundled_groonga_normalizer_mysql_dir}"
- export GRN_PLUGINS_DIR
+ GRN_PLUGINS_DIR="${bundled_groonga_normalizer_mysql_dir}"
+ export GRN_PLUGINS_DIR
+fi
+
+maria_storage_dir="${MYSQL_SOURCE_DIR}/storage/maria"
+if [ -d "${maria_storage_dir}" ]; then
+ mariadb="yes"
+else
+ mariadb="no"
+fi
+percona_udf_dir="${MYSQL_SOURCE_DIR}/plugin/percona-udf"
+if [ -d "${percona_udf_dir}" ]; then
+ percona="yes"
+else
+ percona="no"
fi
source_mysql_test_dir="${MYSQL_SOURCE_DIR}/mysql-test"
@@ -58,51 +71,47 @@ source_test_include_dir="${source_mysql_test_dir}/include"
build_test_suites_dir="${build_mysql_test_dir}/suite"
build_test_include_dir="${build_mysql_test_dir}/include"
case "${MYSQL_VERSION}" in
- 5.1.*)
- plugins_dir="${MYSQL_BUILD_DIR}/lib/mysql/plugin"
- if [ ! -d "${build_test_suites_dir}" ]; then
- mkdir -p "${build_test_suites_dir}"
- fi
- ;;
- *)
- if [ ! -d "${build_test_suites_dir}" ]; then
- ln -s "${source_test_suites_dir}" "${build_test_suites_dir}"
- fi
- maria_storage_dir="${MYSQL_SOURCE_DIR}/storage/maria"
- if [ -d "${maria_storage_dir}" ]; then
- mariadb="yes"
- else
- mariadb="no"
- fi
- if [ "${mariadb}" = "yes" ]; then
- if [ "${MRN_BUNDLED}" != "TRUE" ]; then
- mariadb_mroonga_plugin_dir="${MYSQL_BUILD_DIR}/plugin/mroonga"
- if [ ! -e "${mariadb_mroonga_plugin_dir}" ]; then
- ln -s "${top_dir}" "${mariadb_mroonga_plugin_dir}"
- fi
- fi
- plugins_dir=
- else
- plugins_dir="${MYSQL_SOURCE_DIR}/lib/plugin"
+ 5.1.*)
+ plugins_dir="${MYSQL_BUILD_DIR}/lib/mysql/plugin"
+ if [ ! -d "${build_test_suites_dir}" ]; then
+ mkdir -p "${build_test_suites_dir}"
+ fi
+ ;;
+ *)
+ if [ ! -d "${build_test_suites_dir}" ]; then
+ ln -s "${source_test_suites_dir}" "${build_test_suites_dir}"
+ fi
+ if [ "${mariadb}" = "yes" ]; then
+ if [ "${MRN_BUNDLED}" != "TRUE" ]; then
+ mariadb_mroonga_plugin_dir="${MYSQL_BUILD_DIR}/plugin/mroonga"
+ if [ ! -e "${mariadb_mroonga_plugin_dir}" ]; then
+ ln -s "${top_dir}" "${mariadb_mroonga_plugin_dir}"
fi
- ;;
+ fi
+ plugins_dir=
+ elif [ "${percona}" = "yes" ]; then
+ plugins_dir="${MYSQL_SOURCE_DIR}/lib/mysql/plugin"
+ else
+ plugins_dir="${MYSQL_SOURCE_DIR}/lib/plugin"
+ fi
+ ;;
esac
same_link_p()
{
- src=$1
- dest=$2
- if [ -L "$dest" -a "$(readlink "$dest")" = "$src" ]; then
- return 0
- else
- return 1
- fi
+ src=$1
+ dest=$2
+ if [ -L "$dest" -a "$(readlink "$dest")" = "$src" ]; then
+ return 0
+ else
+ return 1
+ fi
}
mroonga_mysql_test_suite_dir="${build_test_suites_dir}/mroonga"
if ! same_link_p "${mroonga_test_dir}" "${mroonga_mysql_test_suite_dir}"; then
- rm -rf "${mroonga_mysql_test_suite_dir}"
- ln -s "${mroonga_test_dir}" "${mroonga_mysql_test_suite_dir}"
+ rm -rf "${mroonga_mysql_test_suite_dir}"
+ ln -s "${mroonga_test_dir}" "${mroonga_mysql_test_suite_dir}"
fi
innodb_test_suite_dir="${build_test_suites_dir}/innodb"
@@ -110,27 +119,27 @@ mroonga_wrapper_innodb_test_suite_name="mroonga_wrapper_innodb"
mroonga_wrapper_innodb_test_suite_dir="${build_test_suites_dir}/${mroonga_wrapper_innodb_test_suite_name}"
mroonga_wrapper_innodb_include_dir="${mroonga_wrapper_innodb_test_suite_dir}/include/"
if [ "$0" -nt "$(dirname "${mroonga_wrapper_innodb_test_suite_dir}")" ]; then
- rm -rf "${mroonga_wrapper_innodb_test_suite_dir}"
+ rm -rf "${mroonga_wrapper_innodb_test_suite_dir}"
fi
if [ ! -d "${mroonga_wrapper_innodb_test_suite_dir}" ]; then
- cp -rp "${innodb_test_suite_dir}" "${mroonga_wrapper_innodb_test_suite_dir}"
- mkdir -p "${mroonga_wrapper_innodb_include_dir}"
- cp -rp "${source_test_include_dir}"/innodb[-_]*.inc \
- "${mroonga_wrapper_innodb_include_dir}"
- ruby -i'' \
- -pe "\$_.gsub!(/\\bengine\\s*=\\s*innodb\\b([^;\\n]*)/i,
+ cp -rp "${innodb_test_suite_dir}" "${mroonga_wrapper_innodb_test_suite_dir}"
+ mkdir -p "${mroonga_wrapper_innodb_include_dir}"
+ cp -rp "${source_test_include_dir}"/innodb[-_]*.inc \
+ "${mroonga_wrapper_innodb_include_dir}"
+ ruby -i'' \
+ -pe "\$_.gsub!(/\\bengine\\s*=\\s*innodb\\b([^;\\n]*)/i,
\"ENGINE=mroonga\\\1 COMMENT='ENGINE \\\"InnoDB\\\"'\")
\$_.gsub!(/\\b(storage_engine\\s*=\\s*)innodb\\b([^;\\n]*)/i,
\"\\\1mroonga\")
\$_.gsub!(/^(--\\s*source\\s+)(include\\/innodb)/i,
\"\\\1suite/mroonga_wrapper_innodb/\\\2\")
" \
- ${mroonga_wrapper_innodb_test_suite_dir}/r/*.result \
- ${mroonga_wrapper_innodb_test_suite_dir}/t/*.test \
- ${mroonga_wrapper_innodb_test_suite_dir}/include/*.inc
- sed -i'' \
- -e '1 i --source ../mroonga/include/mroonga/have_mroonga.inc' \
- ${mroonga_wrapper_innodb_test_suite_dir}/t/*.test
+ ${mroonga_wrapper_innodb_test_suite_dir}/r/*.result \
+ ${mroonga_wrapper_innodb_test_suite_dir}/t/*.test \
+ ${mroonga_wrapper_innodb_test_suite_dir}/include/*.inc
+ sed -i'' \
+ -e '1 i --source ../mroonga/include/mroonga/have_mroonga.inc' \
+ ${mroonga_wrapper_innodb_test_suite_dir}/t/*.test
fi
all_test_suite_names=""
@@ -138,84 +147,87 @@ suite_dir="${mroonga_test_dir}/.."
cd "${suite_dir}"
suite_dir="$(pwd)"
for test_suite_name in \
- $(find mroonga -type d -name 'include' '!' -prune -o \
- -type d '!' -name 'mroonga' \
- '!' -name 'include' \
- '!' -name '[tr]'); do
- if [ -n "${all_test_suite_names}" ]; then
- all_test_suite_names="${all_test_suite_names},"
- fi
- all_test_suite_names="${all_test_suite_names}${test_suite_name}"
+ $(find mroonga -type d -name 'include' '!' -prune -o \
+ -type d '!' -name 'mroonga' \
+ '!' -name 'include' \
+ '!' -name '[tr]'); do
+ if [ -n "${all_test_suite_names}" ]; then
+ all_test_suite_names="${all_test_suite_names},"
+ fi
+ all_test_suite_names="${all_test_suite_names}${test_suite_name}"
done
cd -
if [ -n "${plugins_dir}" ]; then
- if [ -d "${top_dir}/.libs" ]; then
- make -C ${top_dir} \
- install-pluginLTLIBRARIES \
- plugindir=${plugins_dir} > /dev/null || \
- exit 1
- else
- mkdir -p "${plugins_dir}"
- cp "${top_dir}/ha_mroonga.so" "${plugins_dir}" || exit 1
- fi
+ if [ -d "${top_dir}/.libs" ]; then
+ make -C ${top_dir} \
+ install-pluginLTLIBRARIES \
+ plugindir=${plugins_dir} > /dev/null || \
+ exit 1
+ else
+ mkdir -p "${plugins_dir}"
+ cp "${top_dir}/ha_mroonga.so" "${plugins_dir}" || exit 1
+ fi
fi
+mysql_test_run_options=""
test_suite_names=""
test_names=""
while [ $# -gt 0 ]; do
- case "$1" in
- --manual-gdb|--debug)
- n_processors=1
- break
- ;;
- --*)
- break
- ;;
+ arg="$1"
+ shift
+ case "$arg" in
+ --manual-gdb|--gdb|--client-gdb|--boot-gdb|--debug|--valgrind)
+ n_processors=1
+ mysql_test_run_options="${mysql_test_run_options} ${arg}"
+ ;;
+ --*)
+ mysql_test_run_options="${mysql_test_run_options} ${arg}"
+ ;;
+ *)
+ case "$arg" in
+ */t/*.test)
+ test_suite_name=$(echo "$arg" | sed -e 's,/t/.*\.test,,g')
+ test_suite_name=$(cd "$test_suite_name" && pwd)
+ test_name=$(echo "$arg" | sed -e 's,.*/t/\(.*\)\.test,\1,g')
+ ;;
*)
- case "$1" in
- */t/*.test)
- test_suite_name=$(echo "$1" | sed -e 's,/t/.*\.test,,g')
- test_suite_name=$(cd "$test_suite_name" && pwd)
- test_name=$(echo "$1" | sed -e 's,.*/t/\(.*\)\.test,\1,g')
- ;;
- *)
- if [ -d "$1" ]; then
- test_suite_name=$(cd "$1" && pwd)
- else
- test_suite_name="$1"
- fi
- test_name=""
- ;;
- esac
- shift
-
- if [ -n "${test_name}" ]; then
- if [ -n "${test_names}" ]; then
- test_names="${test_names}|"
- fi
- test_names="${test_names}.*${test_name}"
- fi
-
- test_suite_name=$(echo "$test_suite_name" | sed -e "s,^${suite_dir}/,,")
- if echo "${test_suite_names}" | grep --quiet "${test_suite_name}"; then
- continue
- fi
- if [ -n "${test_suite_names}" ]; then
- test_suite_names="${test_suite_names},"
- fi
- test_suite_names="${test_suite_names}${test_suite_name}"
- ;;
- esac
+ if [ -d "$arg" ]; then
+ test_suite_name=$(cd "$arg" && pwd)
+ else
+ test_suite_name="$arg"
+ fi
+ test_name=""
+ ;;
+ esac
+
+ if [ -n "${test_name}" ]; then
+ if [ -n "${test_names}" ]; then
+ test_names="${test_names}|"
+ fi
+ test_names="${test_names}${test_name}"
+ fi
+
+ test_suite_name=$(echo "$test_suite_name" | sed -e "s,^${suite_dir}/,,")
+ if echo "${test_suite_names}" | grep --quiet "${test_suite_name}"; then
+ continue
+ fi
+ if [ -n "${test_suite_names}" ]; then
+ test_suite_names="${test_suite_names},"
+ fi
+ test_suite_names="${test_suite_names}${test_suite_name}"
+ ;;
+ esac
done
if [ -z "$test_suite_names" ]; then
- test_suite_names="${all_test_suite_names}"
+ test_suite_names="${all_test_suite_names}"
fi
mysql_test_run_args=""
-mysql_test_run_args="${mysql_test_run_args} --mem"
-mysql_test_run_args="${mysql_test_run_args} --no-check-testcases"
+if [ "${percona}" != "yes" ]; then
+ mysql_test_run_args="${mysql_test_run_args} --mem"
+fi
mysql_test_run_args="${mysql_test_run_args} --parallel=${n_processors}"
mysql_test_run_args="${mysql_test_run_args} --retry=1"
mysql_test_run_args="${mysql_test_run_args} --suite=${test_suite_names}"
@@ -223,10 +235,10 @@ mysql_test_run_args="${mysql_test_run_args} --force"
mysql_test_run_args="${mysql_test_run_args} --mysqld=--loose-plugin-load-add=ha_mroonga.so"
mysql_test_run_args="${mysql_test_run_args} --mysqld=--loose-plugin-mroonga=ON"
if [ -n "$test_names" ]; then
- mysql_test_run_args="${mysql_test_run_args} --do-test=${test_names}"
+ mysql_test_run_args="${mysql_test_run_args} --do-test=${test_names}"
fi
(cd "$build_mysql_test_dir" && \
- ./mysql-test-run.pl \
- ${mysql_test_run_args} \
- "$@")
+ perl -I . ./mysql-test-run.pl \
+ ${mysql_test_run_args} \
+ ${mysql_test_run_options})
diff --git a/storage/mroonga/test/unit/test_mrn_path_mapper.cpp b/storage/mroonga/test/unit/test_mrn_path_mapper.cpp
index a5d0d81c340..54a9f35b03f 100644
--- a/storage/mroonga/test/unit/test_mrn_path_mapper.cpp
+++ b/storage/mroonga/test/unit/test_mrn_path_mapper.cpp
@@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
diff --git a/storage/mroonga/tools/prepare-sphinx-html.rb b/storage/mroonga/tools/prepare-sphinx-html.rb
index 76eed24a042..71e12f0e3ca 100755
--- a/storage/mroonga/tools/prepare-sphinx-html.rb
+++ b/storage/mroonga/tools/prepare-sphinx-html.rb
@@ -48,13 +48,6 @@ def fix_html_link(html, language)
end
end
-def add_language_annotation_to_source_label(html)
- html.gsub(/>(ソースコードを表示)</) do
- label = $1
- ">#{label}(英語)<"
- end
-end
-
def fix_js_link(js, language)
fix_link_path(js)
end
@@ -156,7 +149,6 @@ language_dirs.each do |language_dir|
content = fix_link(content, extension, language)
if extension == "html"
content = insert_facebook_html(content, language)
- content = add_language_annotation_to_source_label(content)
end
dest_path.open("wb") do |dest|
dest.print(content.strip)
diff --git a/storage/mroonga/tools/travis/before_script.sh b/storage/mroonga/tools/travis/before_script.sh
index 2b4591a60a4..e3e22c8768a 100755
--- a/storage/mroonga/tools/travis/before_script.sh
+++ b/storage/mroonga/tools/travis/before_script.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright(C) 2012-2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# set -x
set -e
@@ -40,6 +40,7 @@ if [ "${MROONGA_BUNDLED}" = "yes" ]; then
cmake_args=("${cmake_args[@]}" -DWITHOUT_TOKUDB=TRUE)
if [ "${MROONGA_TEST_EMBEDDED}" = "yes" ]; then
cmake_args=("${cmake_args[@]}" -DWITH_EMBEDDED_SERVER=TRUE)
+ cmake_args=("${cmake_args[@]}" -DMRN_BUILD_FOR_EMBEDDED_SERVER=TRUE)
fi
cmake . "${cmake_args[@]}"
else
@@ -49,9 +50,48 @@ else
PATH=$(echo /opt/mysql/server-*/bin/):$PATH
fi
configure_args=("--with-mysql-source=$PWD/vendor/mysql")
- if [ "${MYSQL_VERSION}" = "mysql-5.6.25" ]; then
- configure_args=("${configure_args[@]}" --enable-fast-mutexes)
- fi
+ case "${MYSQL_VERSION}" in
+ mysql-5.6)
+ configure_args=("${configure_args[@]}" --enable-fast-mutexes)
+ ;;
+ mysql-5.7)
+ boost_archive=boost_1_59_0.tar.gz
+ curl -L -O http://downloads.sourceforge.net/project/boost/boost/1.59.0/${boost_archive}
+ sudo mkdir -p /usr/global/share
+ sudo mv ${boost_archive} /usr/global/share/
+ (cd vendor/mysql && sudo debian/rules override_dh_auto_configure)
+ ;;
+ mariadb-5.5)
+ (cd vendor/mysql && sudo debian/rules configure)
+ configure_args=("${configure_args[@]}"
+ "--with-mysql-build=$PWD/vendor/mysql/builddir")
+ ;;
+ percona-server-5.6)
+ (cd vendor/mysql && \
+ sudo debian/rules configure SKIP_DEBUG_BINARY=yes && \
+ cd builddir/libservices && \
+ sudo make > /dev/null && \
+ cd ../extra && \
+ sudo make > /dev/null)
+ configure_args=("${configure_args[@]}"
+ "--enable-fast-mutexes"
+ "--with-mysql-build=$PWD/vendor/mysql/builddir"
+ "--with-mysql-config=$PWD/vendor/mysql/builddir/scripts/mysql_config")
+ ;;
+ percona-server-5.7)
+ (cd vendor/mysql && \
+ sudo debian/rules override_dh_auto_configure SKIP_DEBUG_BINARY=yes && \
+ cd builddir/libservices && \
+ sudo make > /dev/null && \
+ cd ../extra && \
+ sudo make > /dev/null)
+ configure_args=("${configure_args[@]}"
+ "--with-mysql-build=$PWD/vendor/mysql/builddir"
+ "--with-mysql-config=$PWD/vendor/mysql/builddir/scripts/mysql_config")
+ ;;
+ *)
+ :
+ ;;
+ esac
./configure "${configure_args[@]}"
- cat "$(mysql_config --include | sed -e 's/-I//g')/my_config.h"
fi
diff --git a/storage/mroonga/tools/travis/install.sh b/storage/mroonga/tools/travis/install.sh
index c723eb69f35..7596c1ccc32 100755
--- a/storage/mroonga/tools/travis/install.sh
+++ b/storage/mroonga/tools/travis/install.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright(C) 2012-2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2017 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -14,21 +14,50 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-# set -x
+set -x
set -e
-mariadb_download_base=http://mirror.jmu.edu/pub/mariadb
+# export GROONGA_MASTER=yes
+# export GROONGA_NORMALIZER_MYSQL_MASTER=yes
-export GROONGA_MASTER=yes
-export GROONGA_NORMALIZER_MYSQL_MASTER=yes
+#mariadb_download_base=http://mirror.jmu.edu/pub/mariadb
+mariadb_download_base=http://ftp.osuosl.org/pub/mariadb
+
+version=$(echo "$MYSQL_VERSION" | sed -r -e 's/^(mysql|mariadb|percona-server)-//')
+series=$(echo "$version" | sed -r -e 's/^([0-9]+\.[0-9]+).*$/\1/g')
+
+setup_mariadb_apt()
+{
+ distribution=$(lsb_release --short --id | tr 'A-Z' 'a-z')
+ code_name=$(lsb_release --short --codename)
+ component=main
+ apt_url_base="${mariadb_download_base}/repo/${series}"
+ cat <<EOF | sudo tee /etc/apt/sources.list.d/mariadb.list
+deb ${apt_url_base}/${distribution}/ ${code_name} ${component}
+deb-src ${apt_url_base}/${distribution}/ ${code_name} ${component}
+EOF
+ sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db
+ sudo apt-get -qq update
+}
+
+setup_percona_apt()
+{
+ code_name=$(lsb_release --short --codename)
+ release_deb_version=0.1-4
+ release_deb=percona-release_${release_deb_version}.${code_name}_all.deb
+ wget http://www.percona.com/downloads/percona-release/ubuntu/${release_deb_version}/${release_deb}
+ sudo dpkg -i ${release_deb}
+ sudo apt-get -qq update
+}
if [ "${MROONGA_BUNDLED}" = "yes" ]; then
mkdir -p .mroonga
mv * .mroonga/
mv .mroonga/tools ./
- sudo apt-get -qq -y build-dep mysql-server
+ setup_mariadb_apt
+ sudo apt-get -qq -y build-dep mariadb-server
# Support MariaDB for now.
download_base=${mariadb_download_base}/${MYSQL_VERSION}
tar_gz=${MYSQL_VERSION}.tar.gz
@@ -46,11 +75,11 @@ if [ "${MROONGA_BUNDLED}" = "yes" ]; then
storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql
else
curl --silent --location \
- https://github.com/groonga/groonga/raw/master/data/travis/setup.sh | sh
+ https://raw.githubusercontent.com/groonga/groonga/master/data/travis/setup.sh | sh
curl --silent --location \
- https://github.com/groonga/groonga-normalizer-mysql/raw/master/data/travis/setup.sh | sh
+ https://raw.githubusercontent.com/groonga/groonga-normalizer-mysql/master/data/travis/setup.sh | sh
# curl --silent --location \
- # https://github.com/clear-code/cutter/raw/master/data/travis/setup.sh | sh
+ # https://raw.githubusercontent.com/clear-code/cutter/master/data/travis/setup.sh | sh
if [ ! -f /usr/lib/groonga/plugins/tokenizers/mecab.so ]; then
sudo apt-get -qq -y install groonga-tokenizer-mecab
@@ -59,53 +88,67 @@ else
mkdir -p vendor
cd vendor
- version=$(echo "$MYSQL_VERSION" | sed -e 's/^\(mysql\|mariadb\)-//')
- series=$(echo "$version" | sed -e 's/\.[0-9]*\(-\?[a-z]*\)\?$//g')
case "$MYSQL_VERSION" in
mysql-*)
sudo apt-get -qq update
sudo apt-get -qq -y build-dep mysql-server
if [ "$version" = "system" ]; then
+ sudo apt-get -y remove --purge \
+ mysql-server-5.6 \
+ mysql-server-core-5.6 \
+ mysql-client-5.6 \
+ mysql-client-core-5.6
+ sudo rm -rf /var/lib/mysql
+ sudo apt-get -y install \
+ mysql-server \
+ mysql-client \
+ mysql-testsuite \
+ libmysqld-dev
+ apt-get source mysql-server
+ ln -s $(find . -maxdepth 1 -type d | sort | tail -1) mysql
+ else
+ repository_deb=mysql-apt-config_0.8.3-1_all.deb
+ curl -O http://repo.mysql.com/${repository_deb}
+ sudo env MYSQL_SERVER_VERSION=mysql-${series} \
+ dpkg -i ${repository_deb}
+ sudo apt-get -qq update
+ sudo apt-get -qq -y remove --purge mysql-common
+ sudo apt-get -qq -y build-dep mysql-server
sudo apt-get -qq -y install \
- mysql-server mysql-server-5.5 mysql-server-core-5.5 \
- mysql-testsuite libmysqld-dev
+ mysql-server \
+ libmysqlclient-dev \
+ libmysqld-dev \
+ mysql-testsuite
apt-get -qq source mysql-server
ln -s $(find . -maxdepth 1 -type d | sort | tail -1) mysql
- else
- download_base="http://cdn.mysql.com/Downloads/MySQL-${series}/"
- if [ "$(uname -m)" = "x86_64" ]; then
- architecture=x86_64
- else
- architecture=i686
- fi
- deb=mysql-${version}-debian6.0-${architecture}.deb
- tar_gz=mysql-${version}.tar.gz
- curl -O ${download_base}${deb} &
- curl -O ${download_base}${tar_gz} &
- wait
- sudo apt-get -qq -y install libaio1
- sudo dpkg -i $deb
- tar xzf $tar_gz
- ln -s mysql-${version} mysql
fi
;;
mariadb-*)
- sudo apt-get -qq -y remove --purge mysql-common
-
- distribution=$(lsb_release --short --id | tr 'A-Z' 'a-z')
- code_name=$(lsb_release --short --codename)
- component=main
- apt_url_base="${mariadb_download_base}/repo/${series}"
- cat <<EOF | sudo tee /etc/apt/sources.list.d/mariadb.list
-deb ${apt_url_base}/${distribution}/ ${code_name} ${component}
-deb-src ${apt_url_base}/${distribution}/ ${code_name} ${component}
-EOF
- sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db
- sudo apt-get -qq update
+ sudo apt-get -y remove --purge \
+ mysql-server-5.6 \
+ mysql-server-core-5.6 \
+ mysql-client-5.6 \
+ mysql-client-core-5.6 \
+ mysql-common
+ sudo rm -rf /var/lib/mysql
+ setup_mariadb_apt
sudo apt-get -qq -y build-dep mariadb-server
+ sudo apt-get -y install \
+ mariadb-server \
+ mariadb-client \
+ mariadb-test \
+ libmariadbclient-dev
+ apt-get source mariadb-server
+ ln -s $(find . -maxdepth 1 -type d | sort | tail -1) mysql
+ ;;
+ percona-server-*)
+ setup_percona_apt
+ sudo apt-get -qq -y build-dep percona-server-server-${series}
sudo apt-get -qq -y install \
- mariadb-server libmariadbclient-dev mariadb-test
- apt-get -qq source mariadb-server
+ percona-server-server-${series} \
+ percona-server-client-${series} \
+ percona-server-test-${series}
+ apt-get -qq source percona-server-server-${series}
ln -s $(find . -maxdepth 1 -type d | sort | tail -1) mysql
;;
esac
diff --git a/storage/mroonga/tools/travis/script.sh b/storage/mroonga/tools/travis/script.sh
index 91fa06b8b4d..bc2a83e8387 100755
--- a/storage/mroonga/tools/travis/script.sh
+++ b/storage/mroonga/tools/travis/script.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright(C) 2012-2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# set -x
set -e
@@ -43,11 +43,7 @@ fi
build()
{
- if [ "${MROONGA_BUNDLED}" = "yes" ]; then
- make -j${n_processors} > /dev/null
- else
- make -j${n_processors} > /dev/null
- fi
+ make -j${n_processors} > /dev/null
}
run_unit_test()
@@ -62,8 +58,12 @@ prepare_mysql_test_dir()
mysql_test_dir=/usr/mysql-test
if [ -d /usr/lib/mysql-testsuite/ ]; then
sudo cp -a /usr/lib/mysql-testsuite/ ${mysql_test_dir}/
+ elif [ -d /usr/lib/mysql-test/ ]; then
+ sudo cp -a /usr/lib/mysql-test/ ${mysql_test_dir}/
elif [ -d /usr/share/mysql/mysql-test/ ]; then
sudo cp -a /usr/share/mysql/mysql-test/ ${mysql_test_dir}/
+ elif [ -d /usr/share/mysql-test/ ]; then
+ sudo cp -a /usr/share/mysql-test/ ${mysql_test_dir}/
elif [ -d /opt/mysql/ ]; then
mysql_test_dir=$(echo /opt/mysql/server-*/mysql-test)
else
@@ -100,6 +100,9 @@ run_sql_test()
if [ "${MROONGA_TEST_EMBEDDED}" = "yes" ]; then
test_args=("${test_args[@]}" "--embedded-server")
fi
+ if [ "${MROONGA_TEST_PS_PROTOCOL}" = "yes" ]; then
+ test_args=("${test_args[@]}" "--ps-protocol")
+ fi
if [ "${MROONGA_BUNDLED}" = "yes" ]; then
# Plugins aren't supported.
@@ -112,16 +115,17 @@ run_sql_test()
${mroonga_dir}/test/run-sql-test.sh \
"${test_args[@]}" \
- --parallel="${n_processors}"
+ --parallel="${n_processors}" \
+ --retry=3
else
prepare_sql_test
cd ${mysql_test_dir}/
- ./mysql-test-run.pl \
+ perl ./mysql-test-run.pl \
"${test_args[@]}" \
--no-check-testcases \
--parallel="${n_processors}" \
- --retry=1 \
+ --retry=3 \
--suite="${test_suite_names}" \
--force
fi
diff --git a/storage/mroonga/udf/mrn_udf_command.cpp b/storage/mroonga/udf/mrn_udf_command.cpp
index d14f3ffd49d..b4d0f8b20a3 100644
--- a/storage/mroonga/udf/mrn_udf_command.cpp
+++ b/storage/mroonga/udf/mrn_udf_command.cpp
@@ -2,7 +2,7 @@
/*
Copyright(C) 2010 Tetsuro IKEDA
Copyright(C) 2010-2013 Kentoku SHIBA
- Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -25,39 +25,93 @@
#include <mrn_windows.hpp>
#include <mrn_macro.hpp>
#include <mrn_database_manager.hpp>
+#include <mrn_context_pool.hpp>
#include <mrn_variables.hpp>
+#include <mrn_current_thread.hpp>
+
+#include <sql_table.h>
MRN_BEGIN_DECLS
extern mrn::DatabaseManager *mrn_db_manager;
+extern mrn::ContextPool *mrn_context_pool;
struct CommandInfo
{
- grn_ctx ctx;
+ grn_ctx *ctx;
grn_obj *db;
bool use_shared_db;
+ grn_obj command;
String result;
};
-MRN_API my_bool mroonga_command_init(UDF_INIT *initid, UDF_ARGS *args,
+MRN_API my_bool mroonga_command_init(UDF_INIT *init, UDF_ARGS *args,
char *message)
{
CommandInfo *info = NULL;
- initid->ptr = NULL;
- if (args->arg_count != 1) {
- sprintf(message,
- "mroonga_command(): Incorrect number of arguments: %u for 1",
- args->arg_count);
+ init->ptr = NULL;
+ if (args->arg_count == 0) {
+ grn_snprintf(message,
+ MYSQL_ERRMSG_SIZE,
+ MYSQL_ERRMSG_SIZE,
+ "mroonga_command(): Wrong number of arguments: %u for 1..",
+ args->arg_count);
goto error;
}
- if (args->arg_type[0] != STRING_RESULT) {
- strcpy(message,
- "mroonga_command(): The 1st argument must be command as string");
+
+ if ((args->arg_count % 2) == 0) {
+ grn_snprintf(message,
+ MYSQL_ERRMSG_SIZE,
+ MYSQL_ERRMSG_SIZE,
+ "mroonga_command(): The number of arguments must be odd: %u",
+ args->arg_count);
goto error;
}
- initid->maybe_null = 1;
- initid->const_item = 1;
+
+ for (unsigned int i = 0; i < args->arg_count; ++i) {
+ switch (args->arg_type[i]) {
+ case STRING_RESULT:
+ // OK
+ break;
+ case REAL_RESULT:
+ grn_snprintf(message,
+ MYSQL_ERRMSG_SIZE,
+ MYSQL_ERRMSG_SIZE,
+ "mroonga_command(): Argument must be string: <%g>",
+ *reinterpret_cast<double *>(args->args[i]));
+ goto error;
+ break;
+ case INT_RESULT:
+ grn_snprintf(message,
+ MYSQL_ERRMSG_SIZE,
+ MYSQL_ERRMSG_SIZE,
+ "mroonga_command(): Argument must be string: <%lld>",
+ *reinterpret_cast<longlong *>(args->args[i]));
+ goto error;
+ break;
+ case DECIMAL_RESULT:
+ grn_snprintf(message,
+ MYSQL_ERRMSG_SIZE,
+ MYSQL_ERRMSG_SIZE,
+ "mroonga_command(): Argument must be string: <%.*s>",
+ static_cast<int>(args->lengths[i]),
+ args->args[i]);
+ goto error;
+ break;
+ default:
+ grn_snprintf(message,
+ MYSQL_ERRMSG_SIZE,
+ MYSQL_ERRMSG_SIZE,
+ "mroonga_command(): Argument must be string: <%d>(%u)",
+ args->arg_type[i],
+ i);
+ goto error;
+ break;
+ }
+ }
+ init->maybe_null = 1;
+ init->const_item = 0;
info = (CommandInfo *)mrn_my_malloc(sizeof(CommandInfo),
MYF(MY_WME | MY_ZEROFILL));
@@ -66,53 +120,100 @@ MRN_API my_bool mroonga_command_init(UDF_INIT *initid, UDF_ARGS *args,
goto error;
}
- grn_ctx_init(&(info->ctx), 0);
+ info->ctx = mrn_context_pool->pull();
{
const char *current_db_path = MRN_THD_DB_PATH(current_thd);
const char *action;
if (current_db_path) {
action = "open database";
- int error = mrn_db_manager->open(current_db_path, &(info->db));
+ char encoded_db_path[FN_REFLEN + 1];
+ uint encoded_db_path_length =
+ tablename_to_filename(current_db_path,
+ encoded_db_path,
+ sizeof(encoded_db_path));
+ encoded_db_path[encoded_db_path_length] = '\0';
+ mrn::Database *db;
+ int error = mrn_db_manager->open(encoded_db_path, &db);
if (error == 0) {
- grn_ctx_use(&(info->ctx), info->db);
+ info->db = db->get();
+ grn_ctx_use(info->ctx, info->db);
info->use_shared_db = true;
}
} else {
action = "create anonymous database";
- info->db = grn_db_create(&(info->ctx), NULL, NULL);
+ info->db = grn_db_create(info->ctx, NULL, NULL);
info->use_shared_db = false;
}
if (!info->db) {
- sprintf(message,
- "mroonga_command(): failed to %s: %s",
- action,
- info->ctx.errbuf);
+ grn_snprintf(message,
+ MYSQL_ERRMSG_SIZE,
+ MYSQL_ERRMSG_SIZE,
+ "mroonga_command(): failed to %s: %s",
+ action,
+ info->ctx->errbuf);
goto error;
}
}
+ GRN_TEXT_INIT(&(info->command), 0);
- initid->ptr = (char *)info;
+ init->ptr = (char *)info;
return FALSE;
error:
if (info) {
if (!info->use_shared_db) {
- grn_obj_close(&(info->ctx), info->db);
+ grn_obj_close(info->ctx, info->db);
}
- grn_ctx_fin(&(info->ctx));
+ mrn_context_pool->release(info->ctx);
my_free(info);
}
return TRUE;
}
-MRN_API char *mroonga_command(UDF_INIT *initid, UDF_ARGS *args, char *result,
+static void mroonga_command_escape_value(grn_ctx *ctx,
+ grn_obj *command,
+ const char *value,
+ unsigned long value_length)
+{
+ GRN_TEXT_PUTC(ctx, command, '"');
+
+ const char *value_current = value;
+ const char *value_end = value_current + value_length;
+ while (value_current < value_end) {
+ int char_length = grn_charlen(ctx, value_current, value_end);
+
+ if (char_length == 0) {
+ break;
+ } else if (char_length == 1) {
+ switch (*value_current) {
+ case '\\':
+ case '"':
+ GRN_TEXT_PUTC(ctx, command, '\\');
+ GRN_TEXT_PUTC(ctx, command, *value_current);
+ break;
+ case '\n':
+ GRN_TEXT_PUTS(ctx, command, "\\n");
+ break;
+ default:
+ GRN_TEXT_PUTC(ctx, command, *value_current);
+ break;
+ }
+ } else {
+ GRN_TEXT_PUT(ctx, command, value_current, char_length);
+ }
+
+ value_current += char_length;
+ }
+
+ GRN_TEXT_PUTC(ctx, command, '"');
+}
+
+MRN_API char *mroonga_command(UDF_INIT *init, UDF_ARGS *args, char *result,
unsigned long *length, char *is_null, char *error)
{
- CommandInfo *info = (CommandInfo *)initid->ptr;
- grn_ctx *ctx = &(info->ctx);
- char *command;
- unsigned int command_length;
+ CommandInfo *info = (CommandInfo *)init->ptr;
+ grn_ctx *ctx = info->ctx;
int flags = 0;
if (!args->args[0]) {
@@ -120,11 +221,31 @@ MRN_API char *mroonga_command(UDF_INIT *initid, UDF_ARGS *args, char *result,
return NULL;
}
+ GRN_BULK_REWIND(&(info->command));
+ GRN_TEXT_PUT(ctx, &(info->command), args->args[0], args->lengths[0]);
+ for (unsigned int i = 1; i < args->arg_count; i += 2) {
+ if (!args->args[i] || !args->args[i + 1]) {
+ *is_null = 1;
+ return NULL;
+ }
+
+ const char *name = args->args[i];
+ unsigned long name_length = args->lengths[i];
+ GRN_TEXT_PUTS(ctx, &(info->command), " --");
+ GRN_TEXT_PUT(ctx, &(info->command), name, name_length);
+
+ const char *value = args->args[i + 1];
+ unsigned long value_length = args->lengths[i + 1];
+ GRN_TEXT_PUTS(ctx, &(info->command), " ");
+ mroonga_command_escape_value(ctx, &(info->command), value, value_length);
+ }
+
*is_null = 0;
- command = args->args[0];
- command_length = args->lengths[0];
- grn_ctx_send(ctx, command, command_length, 0);
+ grn_ctx_send(ctx,
+ GRN_TEXT_VALUE(&(info->command)),
+ GRN_TEXT_LEN(&(info->command)),
+ 0);
if (ctx->rc) {
my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
goto error;
@@ -156,14 +277,15 @@ error:
return NULL;
}
-MRN_API void mroonga_command_deinit(UDF_INIT *initid)
+MRN_API void mroonga_command_deinit(UDF_INIT *init)
{
- CommandInfo *info = (CommandInfo *)initid->ptr;
+ CommandInfo *info = (CommandInfo *)init->ptr;
if (info) {
+ GRN_OBJ_FIN(info->ctx, &(info->command));
if (!info->use_shared_db) {
- grn_obj_close(&(info->ctx), info->db);
+ grn_obj_close(info->ctx, info->db);
}
- grn_ctx_fin(&(info->ctx));
+ mrn_context_pool->release(info->ctx);
MRN_STRING_FREE(info->result);
my_free(info);
}
diff --git a/storage/mroonga/udf/mrn_udf_escape.cpp b/storage/mroonga/udf/mrn_udf_escape.cpp
index 89b08a1c6d5..b97327fb1d0 100644
--- a/storage/mroonga/udf/mrn_udf_escape.cpp
+++ b/storage/mroonga/udf/mrn_udf_escape.cpp
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
- Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2013-2017 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -23,33 +23,56 @@
#include <mrn_windows.hpp>
#include <mrn_macro.hpp>
#include <mrn_variables.hpp>
+#include <mrn_context_pool.hpp>
MRN_BEGIN_DECLS
+extern mrn::ContextPool *mrn_context_pool;
+
struct EscapeInfo
{
- grn_ctx ctx;
+ grn_ctx *ctx;
+ bool script_mode;
grn_obj target_characters;
- grn_obj escaped_query;
- bool processed;
+ grn_obj escaped_value;
};
-MRN_API my_bool mroonga_escape_init(UDF_INIT *initid, UDF_ARGS *args,
+MRN_API my_bool mroonga_escape_init(UDF_INIT *init, UDF_ARGS *args,
char *message)
{
EscapeInfo *info = NULL;
+ bool script_mode = false;
- initid->ptr = NULL;
+ init->ptr = NULL;
if (!(1 <= args->arg_count && args->arg_count <= 2)) {
- sprintf(message,
- "mroonga_escape(): Incorrect number of arguments: %u for 1..2",
- args->arg_count);
+ snprintf(message,
+ MYSQL_ERRMSG_SIZE,
+ "mroonga_escape(): Incorrect number of arguments: %u for 1..2",
+ args->arg_count);
goto error;
}
- if (args->arg_type[0] != STRING_RESULT) {
- strcpy(message,
- "mroonga_escape(): The 1st argument must be query as string");
- goto error;
+
+ if (args->attribute_lengths[0] == strlen("script") &&
+ strncmp(args->attributes[0], "script", strlen("script")) == 0) {
+ switch (args->arg_type[0]) {
+ case ROW_RESULT:
+ snprintf(message,
+ MYSQL_ERRMSG_SIZE,
+ "mroonga_escape(): "
+ "The 1st script argument must be "
+ "string, integer or floating point: <row>");
+ goto error;
+ break;
+ default:
+ break;
+ }
+ script_mode = true;
+ } else {
+ if (args->arg_type[0] != STRING_RESULT) {
+ strcpy(message,
+ "mroonga_escape(): The 1st query argument must be string");
+ goto error;
+ }
}
if (args->arg_count == 2) {
if (args->arg_type[1] != STRING_RESULT) {
@@ -60,28 +83,27 @@ MRN_API my_bool mroonga_escape_init(UDF_INIT *initid, UDF_ARGS *args,
}
}
- initid->maybe_null = 1;
- initid->const_item = 1;
+ init->maybe_null = 1;
- info = (EscapeInfo *)mrn_my_malloc(sizeof(EscapeInfo),
- MYF(MY_WME | MY_ZEROFILL));
+ info = static_cast<EscapeInfo *>(mrn_my_malloc(sizeof(EscapeInfo),
+ MYF(MY_WME | MY_ZEROFILL)));
if (!info) {
strcpy(message, "mroonga_escape(): out of memory");
goto error;
}
- grn_ctx_init(&(info->ctx), 0);
+ info->ctx = mrn_context_pool->pull();
+ info->script_mode = script_mode;
GRN_TEXT_INIT(&(info->target_characters), 0);
- GRN_TEXT_INIT(&(info->escaped_query), 0);
- info->processed = false;
+ GRN_TEXT_INIT(&(info->escaped_value), 0);
- initid->ptr = (char *)info;
+ init->ptr = reinterpret_cast<char *>(info);
return FALSE;
error:
if (info) {
- grn_ctx_fin(&(info->ctx));
+ mrn_context_pool->release(info->ctx);
my_free(info);
}
return TRUE;
@@ -89,32 +111,103 @@ error:
static void escape(EscapeInfo *info, UDF_ARGS *args)
{
- grn_ctx *ctx = &(info->ctx);
- char *query = args->args[0];
- unsigned int query_length = args->lengths[0];
-
- if (args->arg_count == 2) {
- char *target_characters = args->args[1];
- unsigned int target_characters_length = args->lengths[1];
- GRN_TEXT_PUT(ctx, &(info->target_characters),
- target_characters,
- target_characters_length);
- GRN_TEXT_PUTC(ctx, &(info->target_characters), '\0');
- grn_expr_syntax_escape(ctx, query, query_length,
- GRN_TEXT_VALUE(&(info->target_characters)),
- GRN_QUERY_ESCAPE,
- &(info->escaped_query));
+ grn_ctx *ctx = info->ctx;
+
+ GRN_BULK_REWIND(&(info->escaped_value));
+ if (info->script_mode) {
+ switch (args->arg_type[0]) {
+ case STRING_RESULT:
+ {
+ char *value = args->args[0];
+ unsigned long value_length = args->lengths[0];
+ GRN_TEXT_PUTC(ctx, &(info->escaped_value), '"');
+ if (args->arg_count == 2) {
+ grn_obj special_characters;
+ GRN_TEXT_INIT(&special_characters, 0);
+ GRN_TEXT_PUT(ctx,
+ &special_characters,
+ args->args[1],
+ args->lengths[1]);
+ GRN_TEXT_PUTC(ctx, &special_characters, '\0');
+ grn_expr_syntax_escape(ctx,
+ value,
+ value_length,
+ GRN_TEXT_VALUE(&special_characters),
+ '\\',
+ &(info->escaped_value));
+ GRN_OBJ_FIN(ctx, &special_characters);
+ } else {
+ const char *special_characters = "\"\\";
+ grn_expr_syntax_escape(ctx,
+ value,
+ value_length,
+ special_characters,
+ '\\',
+ &(info->escaped_value));
+ }
+ GRN_TEXT_PUTC(ctx, &(info->escaped_value), '"');
+ }
+ break;
+ case REAL_RESULT:
+ {
+ double value = *reinterpret_cast<double *>(args->args[0]);
+ grn_text_ftoa(ctx, &(info->escaped_value), value);
+ }
+ break;
+ case INT_RESULT:
+ {
+ longlong value = *reinterpret_cast<longlong *>(args->args[0]);
+ grn_text_lltoa(ctx, &(info->escaped_value), value);
+ }
+ break;
+ case DECIMAL_RESULT:
+ {
+ grn_obj value_raw;
+ GRN_TEXT_INIT(&value_raw, GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_TEXT_SET(ctx, &value_raw, args->args[0], args->lengths[0]);
+ grn_obj value;
+ GRN_FLOAT_INIT(&value, 0);
+ if (grn_obj_cast(ctx, &value_raw, &value, GRN_FALSE) == GRN_SUCCESS) {
+ grn_text_ftoa(ctx, &(info->escaped_value), GRN_FLOAT_VALUE(&value));
+ } else {
+ GRN_TEXT_PUT(ctx,
+ &(info->escaped_value),
+ args->args[0],
+ args->lengths[0]);
+ }
+ GRN_OBJ_FIN(ctx, &value);
+ GRN_OBJ_FIN(ctx, &value_raw);
+ }
+ break;
+ default:
+ break;
+ }
} else {
- grn_expr_syntax_escape_query(ctx, query, query_length,
- &(info->escaped_query));
+ char *query = args->args[0];
+ unsigned long query_length = args->lengths[0];
+ if (args->arg_count == 2) {
+ char *target_characters = args->args[1];
+ unsigned long target_characters_length = args->lengths[1];
+ GRN_TEXT_PUT(ctx, &(info->target_characters),
+ target_characters,
+ target_characters_length);
+ GRN_TEXT_PUTC(ctx, &(info->target_characters), '\0');
+ grn_expr_syntax_escape(ctx, query, query_length,
+ GRN_TEXT_VALUE(&(info->target_characters)),
+ GRN_QUERY_ESCAPE,
+ &(info->escaped_value));
+ } else {
+ grn_expr_syntax_escape_query(ctx, query, query_length,
+ &(info->escaped_value));
+ }
}
}
-MRN_API char *mroonga_escape(UDF_INIT *initid, UDF_ARGS *args, char *result,
+MRN_API char *mroonga_escape(UDF_INIT *init, UDF_ARGS *args, char *result,
unsigned long *length, char *is_null, char *error)
{
- EscapeInfo *info = (EscapeInfo *)initid->ptr;
- grn_ctx *ctx = &(info->ctx);
+ EscapeInfo *info = reinterpret_cast<EscapeInfo *>(init->ptr);
+ grn_ctx *ctx = info->ctx;
if (!args->args[0]) {
*is_null = 1;
@@ -123,31 +216,28 @@ MRN_API char *mroonga_escape(UDF_INIT *initid, UDF_ARGS *args, char *result,
*is_null = 0;
- if (!info->processed) {
- escape(info, args);
- info->processed = true;
- }
+ escape(info, args);
if (ctx->rc) {
my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
goto error;
}
- *length = GRN_TEXT_LEN(&(info->escaped_query));
- return (char *)(GRN_TEXT_VALUE(&(info->escaped_query)));
+ *length = GRN_TEXT_LEN(&(info->escaped_value));
+ return GRN_TEXT_VALUE(&(info->escaped_value));
error:
*error = 1;
return NULL;
}
-MRN_API void mroonga_escape_deinit(UDF_INIT *initid)
+MRN_API void mroonga_escape_deinit(UDF_INIT *init)
{
- EscapeInfo *info = (EscapeInfo *)initid->ptr;
+ EscapeInfo *info = reinterpret_cast<EscapeInfo *>(init->ptr);
if (info) {
- grn_obj_unlink(&(info->ctx), &(info->target_characters));
- grn_obj_unlink(&(info->ctx), &(info->escaped_query));
- grn_ctx_fin(&(info->ctx));
+ grn_obj_unlink(info->ctx, &(info->target_characters));
+ grn_obj_unlink(info->ctx, &(info->escaped_value));
+ mrn_context_pool->release(info->ctx);
my_free(info);
}
}
diff --git a/storage/mroonga/udf/mrn_udf_highlight_html.cpp b/storage/mroonga/udf/mrn_udf_highlight_html.cpp
new file mode 100644
index 00000000000..dc46ef5f205
--- /dev/null
+++ b/storage/mroonga/udf/mrn_udf_highlight_html.cpp
@@ -0,0 +1,494 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
+/*
+ Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <mrn_mysql.h>
+#include <mrn_mysql_compat.h>
+#include <mrn_err.h>
+#include <mrn_encoding.hpp>
+#include <mrn_windows.hpp>
+#include <mrn_table.hpp>
+#include <mrn_macro.hpp>
+#include <mrn_database_manager.hpp>
+#include <mrn_context_pool.hpp>
+#include <mrn_variables.hpp>
+#include <mrn_query_parser.hpp>
+#include <mrn_current_thread.hpp>
+
+MRN_BEGIN_DECLS
+
+extern mrn::DatabaseManager *mrn_db_manager;
+extern mrn::ContextPool *mrn_context_pool;
+
+typedef struct st_mrn_highlight_html_info
+{
+ grn_ctx *ctx;
+ grn_obj *db;
+ bool use_shared_db;
+ grn_obj *keywords;
+ String result_str;
+ struct {
+ bool used;
+ grn_obj *table;
+ grn_obj *default_column;
+ } query_mode;
+} mrn_highlight_html_info;
+
+static my_bool mrn_highlight_html_prepare(mrn_highlight_html_info *info,
+ UDF_ARGS *args,
+ char *message,
+ grn_obj **keywords)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ grn_ctx *ctx = info->ctx;
+ const char *normalizer_name = "NormalizerAuto";
+ grn_obj *expr = NULL;
+ String *result_str = &(info->result_str);
+
+ *keywords = NULL;
+
+ mrn::encoding::set_raw(ctx, system_charset_info);
+ if (system_charset_info->state & (MY_CS_BINSORT | MY_CS_CSSORT)) {
+ normalizer_name = NULL;
+ }
+
+ *keywords = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_OBJ_TABLE_PAT_KEY,
+ grn_ctx_at(ctx, GRN_DB_SHORT_TEXT),
+ NULL);
+ if (ctx->rc != GRN_SUCCESS) {
+ if (message) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_highlight_html(): "
+ "failed to create grn_pat for keywords: <%s>",
+ ctx->errbuf);
+ }
+ goto error;
+ }
+ if (normalizer_name) {
+ grn_obj_set_info(ctx,
+ *keywords,
+ GRN_INFO_NORMALIZER,
+ grn_ctx_get(ctx, normalizer_name, -1));
+ }
+
+ if (info->query_mode.used) {
+ if (!info->query_mode.table) {
+ grn_obj *short_text;
+ short_text = grn_ctx_at(info->ctx, GRN_DB_SHORT_TEXT);
+ info->query_mode.table = grn_table_create(info->ctx,
+ NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY,
+ short_text,
+ NULL);
+ }
+ if (!info->query_mode.default_column) {
+ info->query_mode.default_column =
+ grn_obj_column(info->ctx,
+ info->query_mode.table,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ }
+
+ grn_obj *record = NULL;
+ GRN_EXPR_CREATE_FOR_QUERY(info->ctx, info->query_mode.table, expr, record);
+ if (!expr) {
+ if (message) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_highlight_html(): "
+ "failed to create expression: <%s>",
+ ctx->errbuf);
+ }
+ goto error;
+ }
+
+ mrn::QueryParser query_parser(info->ctx,
+ current_thd,
+ expr,
+ info->query_mode.default_column,
+ 0,
+ NULL);
+ grn_rc rc = query_parser.parse(args->args[1], args->lengths[1]);
+ if (rc != GRN_SUCCESS) {
+ if (message) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_highlight_html(): "
+ "failed to parse query: <%s>",
+ ctx->errbuf);
+ }
+ goto error;
+ }
+
+ {
+ grn_obj extracted_keywords;
+ GRN_PTR_INIT(&extracted_keywords, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ grn_expr_get_keywords(ctx, expr, &extracted_keywords);
+
+ size_t n_keywords =
+ GRN_BULK_VSIZE(&extracted_keywords) / sizeof(grn_obj *);
+ for (size_t i = 0; i < n_keywords; ++i) {
+ grn_obj *extracted_keyword = GRN_PTR_VALUE_AT(&extracted_keywords, i);
+ grn_table_add(ctx,
+ *keywords,
+ GRN_TEXT_VALUE(extracted_keyword),
+ GRN_TEXT_LEN(extracted_keyword),
+ NULL);
+ if (ctx->rc != GRN_SUCCESS) {
+ if (message) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_highlight_html(): "
+ "failed to add a keyword: <%.*s>: <%s>",
+ static_cast<int>(GRN_TEXT_LEN(extracted_keyword)),
+ GRN_TEXT_VALUE(extracted_keyword),
+ ctx->errbuf);
+ GRN_OBJ_FIN(ctx, &extracted_keywords);
+ }
+ goto error;
+ }
+ }
+ GRN_OBJ_FIN(ctx, &extracted_keywords);
+ }
+ } else {
+ for (unsigned int i = 1; i < args->arg_count; ++i) {
+ if (!args->args[i]) {
+ continue;
+ }
+ grn_table_add(ctx,
+ *keywords,
+ args->args[i],
+ args->lengths[i],
+ NULL);
+ if (ctx->rc != GRN_SUCCESS) {
+ if (message) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_highlight_html(): "
+ "failed to add a keyword: <%.*s>: <%s>",
+ static_cast<int>(args->lengths[i]),
+ args->args[i],
+ ctx->errbuf);
+ }
+ goto error;
+ }
+ }
+ }
+
+ result_str->set_charset(system_charset_info);
+ DBUG_RETURN(FALSE);
+
+error:
+ if (expr) {
+ grn_obj_close(ctx, expr);
+ }
+ if (*keywords) {
+ grn_obj_close(ctx, *keywords);
+ }
+ DBUG_RETURN(TRUE);
+}
+
+MRN_API my_bool mroonga_highlight_html_init(UDF_INIT *init,
+ UDF_ARGS *args,
+ char *message)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ mrn_highlight_html_info *info = NULL;
+
+ init->ptr = NULL;
+
+ if (args->arg_count < 1) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_highlight_html(): wrong number of arguments: %u for 1+",
+ args->arg_count);
+ goto error;
+ }
+
+
+ for (unsigned int i = 0; i < args->arg_count; ++i) {
+ switch (args->arg_type[i]) {
+ case STRING_RESULT:
+ /* OK */
+ break;
+ case REAL_RESULT:
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_highlight_html(): all arguments must be string: "
+ "<%u>=<%g>",
+ i, *((double *)(args->args[i])));
+ goto error;
+ break;
+ case INT_RESULT:
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_highlight_html(): all arguments must be string: "
+ "<%u>=<%lld>",
+ i, *((longlong *)(args->args[i])));
+ goto error;
+ break;
+ default:
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_highlight_html(): all arguments must be string: <%u>",
+ i);
+ goto error;
+ break;
+ }
+ }
+
+ init->maybe_null = 0;
+
+ info =
+ reinterpret_cast<mrn_highlight_html_info *>(
+ mrn_my_malloc(sizeof(mrn_highlight_html_info),
+ MYF(MY_WME | MY_ZEROFILL)));
+ if (!info) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_highlight_html(): failed to allocate memory");
+ goto error;
+ }
+
+ info->ctx = mrn_context_pool->pull();
+ {
+ const char *current_db_path = MRN_THD_DB_PATH(current_thd);
+ const char *action;
+ if (current_db_path) {
+ action = "open database";
+ mrn::Database *db;
+ int error = mrn_db_manager->open(current_db_path, &db);
+ if (error == 0) {
+ info->db = db->get();
+ grn_ctx_use(info->ctx, info->db);
+ info->use_shared_db = true;
+ }
+ } else {
+ action = "create anonymous database";
+ info->db = grn_db_create(info->ctx, NULL, NULL);
+ info->use_shared_db = false;
+ }
+ if (!info->db) {
+ sprintf(message,
+ "mroonga_highlight_html(): failed to %s: %s",
+ action,
+ info->ctx->errbuf);
+ goto error;
+ }
+ }
+
+ info->query_mode.used = FALSE;
+
+ if (args->arg_count == 2 &&
+ args->attribute_lengths[1] == strlen("query") &&
+ strncmp(args->attributes[1], "query", strlen("query")) == 0) {
+ info->query_mode.used = TRUE;
+ info->query_mode.table = NULL;
+ info->query_mode.default_column = NULL;
+ }
+
+ {
+ bool all_keywords_are_constant = TRUE;
+ for (unsigned int i = 1; i < args->arg_count; ++i) {
+ if (!args->args[i]) {
+ all_keywords_are_constant = FALSE;
+ break;
+ }
+ }
+
+ if (all_keywords_are_constant) {
+ if (mrn_highlight_html_prepare(info, args, message, &(info->keywords))) {
+ goto error;
+ }
+ } else {
+ info->keywords = NULL;
+ }
+ }
+
+ init->ptr = (char *)info;
+
+ DBUG_RETURN(FALSE);
+
+error:
+ if (info) {
+ if (!info->use_shared_db) {
+ grn_obj_close(info->ctx, info->db);
+ }
+ mrn_context_pool->release(info->ctx);
+ my_free(info);
+ }
+ DBUG_RETURN(TRUE);
+}
+
+static bool highlight_html(grn_ctx *ctx,
+ grn_pat *keywords,
+ const char *target,
+ size_t target_length,
+ String *output)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ grn_obj buffer;
+
+ GRN_TEXT_INIT(&buffer, 0);
+
+ {
+ const char *open_tag = "<span class=\"keyword\">";
+ size_t open_tag_length = strlen(open_tag);
+ const char *close_tag = "</span>";
+ size_t close_tag_length = strlen(close_tag);
+
+ while (target_length > 0) {
+#define MAX_N_HITS 16
+ grn_pat_scan_hit hits[MAX_N_HITS];
+ const char *rest;
+ size_t previous = 0;
+ size_t chunk_length;
+
+ int n_hits = grn_pat_scan(ctx,
+ keywords,
+ target,
+ target_length,
+ hits, MAX_N_HITS, &rest);
+ for (int i = 0; i < n_hits; i++) {
+ if ((hits[i].offset - previous) > 0) {
+ grn_text_escape_xml(ctx,
+ &buffer,
+ target + previous,
+ hits[i].offset - previous);
+ }
+ GRN_TEXT_PUT(ctx, &buffer, open_tag, open_tag_length);
+ grn_text_escape_xml(ctx,
+ &buffer,
+ target + hits[i].offset,
+ hits[i].length);
+ GRN_TEXT_PUT(ctx, &buffer, close_tag, close_tag_length);
+ previous = hits[i].offset + hits[i].length;
+ }
+
+ chunk_length = rest - target;
+ if ((chunk_length - previous) > 0) {
+ grn_text_escape_xml(ctx,
+ &buffer,
+ target + previous,
+ target_length - previous);
+ }
+ target_length -= chunk_length;
+ target = rest;
+#undef MAX_N_HITS
+ }
+ }
+
+ if (output->reserve(GRN_TEXT_LEN(&buffer))) {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
+ GRN_OBJ_FIN(ctx, &buffer);
+ DBUG_RETURN(false);
+ }
+
+ output->q_append(GRN_TEXT_VALUE(&buffer), GRN_TEXT_LEN(&buffer));
+ GRN_OBJ_FIN(ctx, &buffer);
+ DBUG_RETURN(true);
+}
+
+MRN_API char *mroonga_highlight_html(UDF_INIT *init,
+ UDF_ARGS *args,
+ char *result,
+ unsigned long *length,
+ char *is_null,
+ char *error)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ mrn_highlight_html_info *info =
+ reinterpret_cast<mrn_highlight_html_info *>(init->ptr);
+
+ grn_ctx *ctx = info->ctx;
+ grn_obj *keywords = info->keywords;
+ String *result_str = &(info->result_str);
+
+ if (!args->args[0]) {
+ *is_null = 1;
+ DBUG_RETURN(NULL);
+ }
+
+ if (!keywords) {
+ if (mrn_highlight_html_prepare(info, args, NULL, &keywords)) {
+ goto error;
+ }
+ }
+
+ *is_null = 0;
+ result_str->length(0);
+
+ if (!highlight_html(ctx,
+ reinterpret_cast<grn_pat *>(keywords),
+ args->args[0],
+ args->lengths[0],
+ result_str)) {
+ goto error;
+ }
+
+ if (!info->keywords) {
+ grn_rc rc = grn_obj_close(ctx, keywords);
+ if (rc != GRN_SUCCESS) {
+ my_printf_error(ER_MRN_ERROR_FROM_GROONGA_NUM,
+ ER_MRN_ERROR_FROM_GROONGA_STR, MYF(0), ctx->errbuf);
+ goto error;
+ }
+ }
+
+ *length = result_str->length();
+ DBUG_RETURN((char *)result_str->ptr());
+
+error:
+ if (!info->keywords && keywords) {
+ grn_obj_close(ctx, keywords);
+ }
+
+ *is_null = 1;
+ *error = 1;
+
+ DBUG_RETURN(NULL);
+}
+
+MRN_API void mroonga_highlight_html_deinit(UDF_INIT *init)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ mrn_highlight_html_info *info =
+ reinterpret_cast<mrn_highlight_html_info *>(init->ptr);
+ if (!info) {
+ DBUG_VOID_RETURN;
+ }
+
+ if (info->keywords) {
+ grn_obj_close(info->ctx, info->keywords);
+ }
+ if (info->query_mode.used) {
+ if (info->query_mode.default_column) {
+ grn_obj_close(info->ctx, info->query_mode.default_column);
+ }
+ if (info->query_mode.table) {
+ grn_obj_close(info->ctx, info->query_mode.table);
+ }
+ }
+ MRN_STRING_FREE(info->result_str);
+ if (!info->use_shared_db) {
+ grn_obj_close(info->ctx, info->db);
+ }
+ mrn_context_pool->release(info->ctx);
+ my_free(info);
+
+ DBUG_VOID_RETURN;
+}
+
+MRN_END_DECLS
diff --git a/storage/mroonga/udf/mrn_udf_last_insert_grn_id.cpp b/storage/mroonga/udf/mrn_udf_last_insert_grn_id.cpp
index b54f5c53206..fb4b5440ef1 100644
--- a/storage/mroonga/udf/mrn_udf_last_insert_grn_id.cpp
+++ b/storage/mroonga/udf/mrn_udf_last_insert_grn_id.cpp
@@ -2,7 +2,7 @@
/*
Copyright(C) 2010 Tetsuro IKEDA
Copyright(C) 2010-2013 Kentoku SHIBA
- Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -23,20 +23,21 @@
#include <mrn_windows.hpp>
#include <mrn_table.hpp>
#include <mrn_macro.hpp>
+#include <mrn_current_thread.hpp>
MRN_BEGIN_DECLS
-MRN_API my_bool last_insert_grn_id_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+MRN_API my_bool last_insert_grn_id_init(UDF_INIT *init, UDF_ARGS *args, char *message)
{
if (args->arg_count != 0) {
strcpy(message, "last_insert_grn_id must not have arguments");
return 1;
}
- initid->maybe_null = 0;
+ init->maybe_null = 0;
return 0;
}
-MRN_API longlong last_insert_grn_id(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
+MRN_API longlong last_insert_grn_id(UDF_INIT *init, UDF_ARGS *args, char *is_null, char *error)
{
THD *thd = current_thd;
st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, false);
@@ -47,7 +48,7 @@ MRN_API longlong last_insert_grn_id(UDF_INIT *initid, UDF_ARGS *args, char *is_n
return last_insert_record_id;
}
-MRN_API void last_insert_grn_id_deinit(UDF_INIT *initid)
+MRN_API void last_insert_grn_id_deinit(UDF_INIT *init)
{
}
diff --git a/storage/mroonga/udf/mrn_udf_normalize.cpp b/storage/mroonga/udf/mrn_udf_normalize.cpp
new file mode 100644
index 00000000000..dd597946ea8
--- /dev/null
+++ b/storage/mroonga/udf/mrn_udf_normalize.cpp
@@ -0,0 +1,212 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
+/*
+ Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+ Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <mrn_mysql.h>
+#include <mrn_mysql_compat.h>
+#include <mrn_encoding.hpp>
+#include <mrn_windows.hpp>
+#include <mrn_table.hpp>
+#include <mrn_macro.hpp>
+#include <mrn_database_manager.hpp>
+#include <mrn_context_pool.hpp>
+#include <mrn_variables.hpp>
+#include <mrn_current_thread.hpp>
+
+MRN_BEGIN_DECLS
+
+extern mrn::DatabaseManager *mrn_db_manager;
+extern mrn::ContextPool *mrn_context_pool;
+
+#define DEFAULT_NORMALIZER_NAME "NormalizerAuto"
+
+struct st_mrn_normalize_info
+{
+ grn_ctx *ctx;
+ grn_obj *db;
+ bool use_shared_db;
+ grn_obj *normalizer;
+ int flags;
+ String result_str;
+};
+
+MRN_API my_bool mroonga_normalize_init(UDF_INIT *init, UDF_ARGS *args,
+ char *message)
+{
+ st_mrn_normalize_info *info = NULL;
+ String *result_str = NULL;
+
+ init->ptr = NULL;
+ if (!(1 <= args->arg_count && args->arg_count <= 2)) {
+ sprintf(message,
+ "mroonga_normalize(): Incorrect number of arguments: %u for 1..2",
+ args->arg_count);
+ goto error;
+ }
+ if (args->arg_type[0] != STRING_RESULT) {
+ strcpy(message,
+ "mroonga_normalize(): The 1st argument must be query as string");
+ goto error;
+ }
+ if (args->arg_count == 2) {
+ if (args->arg_type[1] != STRING_RESULT) {
+ strcpy(message,
+ "mroonga_normalize(): "
+ "The 2st argument must be normalizer name as string");
+ goto error;
+ }
+ }
+
+ init->maybe_null = 1;
+
+ info = (st_mrn_normalize_info *)mrn_my_malloc(sizeof(st_mrn_normalize_info),
+ MYF(MY_WME | MY_ZEROFILL));
+ if (!info) {
+ strcpy(message, "mroonga_normalize(): out of memory");
+ goto error;
+ }
+
+ info->ctx = mrn_context_pool->pull();
+ {
+ const char *current_db_path = MRN_THD_DB_PATH(current_thd);
+ const char *action;
+ if (current_db_path) {
+ action = "open database";
+ mrn::Database *db;
+ int error = mrn_db_manager->open(current_db_path, &db);
+ if (error == 0) {
+ info->db = db->get();
+ grn_ctx_use(info->ctx, info->db);
+ info->use_shared_db = true;
+ }
+ } else {
+ action = "create anonymous database";
+ info->db = grn_db_create(info->ctx, NULL, NULL);
+ info->use_shared_db = false;
+ }
+ if (!info->db) {
+ sprintf(message,
+ "mroonga_normalize(): failed to %s: %s",
+ action,
+ info->ctx->errbuf);
+ goto error;
+ }
+ }
+
+ if (args->arg_count == 1) {
+ info->normalizer = grn_ctx_get(info->ctx, DEFAULT_NORMALIZER_NAME, -1);
+ } else {
+ info->normalizer = grn_ctx_get(info->ctx, args->args[1], args->lengths[1]);
+ }
+ if (!info->normalizer) {
+ sprintf(message, "mroonga_normalize(): nonexistent normalizer %.*s",
+ (int)args->lengths[1], args->args[1]);
+ goto error;
+ }
+ info->flags = 0;
+
+ result_str = &(info->result_str);
+ mrn::encoding::set_raw(info->ctx, system_charset_info);
+ result_str->set_charset(system_charset_info);
+
+ init->ptr = (char *)info;
+
+ return FALSE;
+
+error:
+ if (info) {
+ if (!info->use_shared_db) {
+ grn_obj_close(info->ctx, info->db);
+ }
+ mrn_context_pool->release(info->ctx);
+ my_free(info);
+ }
+ return TRUE;
+}
+
+MRN_API char *mroonga_normalize(UDF_INIT *init, UDF_ARGS *args, char *result,
+ unsigned long *length, char *is_null, char *error)
+{
+ st_mrn_normalize_info *info = (st_mrn_normalize_info *)init->ptr;
+ grn_ctx *ctx = info->ctx;
+ String *result_str = &(info->result_str);
+
+ if (!args->args[0]) {
+ *is_null = 1;
+ return NULL;
+ }
+
+ result_str->length(0);
+ {
+ char *target = args->args[0];
+ unsigned int target_length = args->lengths[0];
+ grn_obj *grn_string;
+ const char *normalized;
+ unsigned int normalized_length_in_bytes;
+ unsigned int normalized_n_characters;
+
+ grn_string = grn_string_open(ctx,
+ target, target_length,
+ info->normalizer, info->flags);
+ grn_string_get_normalized(ctx, grn_string,
+ &normalized,
+ &normalized_length_in_bytes,
+ &normalized_n_characters);
+ if (result_str->reserve(normalized_length_in_bytes)) {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
+ goto error;
+ }
+ result_str->q_append(normalized, normalized_length_in_bytes);
+ result_str->length(normalized_length_in_bytes);
+ grn_obj_unlink(ctx, grn_string);
+ }
+ *is_null = 0;
+
+ if (ctx->rc) {
+ my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
+ goto error;
+ }
+
+ *length = result_str->length();
+ return (char *)result_str->ptr();
+
+error:
+ *is_null = 1;
+ *error = 1;
+ return NULL;
+}
+
+MRN_API void mroonga_normalize_deinit(UDF_INIT *init)
+{
+ st_mrn_normalize_info *info = (st_mrn_normalize_info *)init->ptr;
+
+ if (info) {
+ MRN_STRING_FREE(info->result_str);
+ if (info->normalizer) {
+ grn_obj_unlink(info->ctx, info->normalizer);
+ }
+ if (!info->use_shared_db) {
+ grn_obj_close(info->ctx, info->db);
+ }
+ mrn_context_pool->release(info->ctx);
+ my_free(info);
+ }
+}
+
+MRN_END_DECLS
diff --git a/storage/mroonga/udf/mrn_udf_query_expand.cpp b/storage/mroonga/udf/mrn_udf_query_expand.cpp
new file mode 100644
index 00000000000..562499242fc
--- /dev/null
+++ b/storage/mroonga/udf/mrn_udf_query_expand.cpp
@@ -0,0 +1,282 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
+/*
+ Copyright(C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <mrn_mysql.h>
+#include <mrn_mysql_compat.h>
+#include <mrn_path_mapper.hpp>
+#include <mrn_windows.hpp>
+#include <mrn_macro.hpp>
+#include <mrn_variables.hpp>
+#include <mrn_database_manager.hpp>
+#include <mrn_context_pool.hpp>
+#include <mrn_current_thread.hpp>
+#include <mrn_query_parser.hpp>
+
+MRN_BEGIN_DECLS
+
+extern mrn::DatabaseManager *mrn_db_manager;
+extern mrn::ContextPool *mrn_context_pool;
+
+namespace mrn {
+ struct QueryExpandInfo {
+ grn_ctx *ctx;
+ grn_obj expanded_query;
+ grn_obj *term_column;
+ grn_obj *expanded_term_column;
+ };
+}
+
+static void mrn_query_expand_info_free(mrn::QueryExpandInfo *info)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ if (!info) {
+ DBUG_VOID_RETURN;
+ }
+
+ if (info->ctx) {
+ GRN_OBJ_FIN(info->ctx, &(info->expanded_query));
+ if (grn_obj_is_accessor(info->ctx, info->expanded_term_column)) {
+ grn_obj_unlink(info->ctx, info->expanded_term_column);
+ }
+ if (grn_obj_is_accessor(info->ctx, info->term_column)) {
+ grn_obj_unlink(info->ctx, info->term_column);
+ }
+ mrn_context_pool->release(info->ctx);
+ }
+ my_free(info);
+
+ DBUG_VOID_RETURN;
+}
+
+MRN_API my_bool mroonga_query_expand_init(UDF_INIT *init,
+ UDF_ARGS *args,
+ char *message)
+{
+ mrn::QueryExpandInfo *info = NULL;
+
+ MRN_DBUG_ENTER_FUNCTION();
+
+ init->ptr = NULL;
+ if (args->arg_count != 4) {
+ sprintf(message,
+ "mroonga_query_expand(): wrong number of arguments: %u for 4",
+ args->arg_count);
+ goto error;
+ }
+ if (args->arg_type[0] != STRING_RESULT) {
+ strcpy(message,
+ "mroonga_query_expand(): "
+ "the 1st argument must be table name as string");
+ goto error;
+ }
+ if (args->arg_type[1] != STRING_RESULT) {
+ strcpy(message,
+ "mroonga_query_expand(): "
+ "the 2nd argument must be term column name as string");
+ goto error;
+ }
+ if (args->arg_type[2] != STRING_RESULT) {
+ strcpy(message,
+ "mroonga_query_expand(): "
+ "the 3nd argument must be expanded term column name as string");
+ goto error;
+ }
+ if (args->arg_type[3] != STRING_RESULT) {
+ strcpy(message,
+ "mroonga_query_expand(): "
+ "the 4th argument must be query as string");
+ goto error;
+ }
+
+ init->maybe_null = 1;
+
+ info = static_cast<mrn::QueryExpandInfo *>(
+ mrn_my_malloc(sizeof(mrn::QueryExpandInfo),
+ MYF(MY_WME | MY_ZEROFILL)));
+ if (!info) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_query_expand(): failed to allocate memory");
+ goto error;
+ }
+
+ {
+ const char *current_db_path = MRN_THD_DB_PATH(current_thd);
+ if (!current_db_path) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_query_expand(): no current database");
+ goto error;
+ }
+
+ mrn::Database *db;
+ int error = mrn_db_manager->open(current_db_path, &db);
+ if (error != 0) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_query_expand(): failed to open database: %s",
+ mrn_db_manager->error_message());
+ goto error;
+ }
+ info->ctx = mrn_context_pool->pull();
+ grn_ctx_use(info->ctx, db->get());
+ }
+
+ GRN_TEXT_INIT(&(info->expanded_query), 0);
+
+ {
+ const char *table_name = args->args[0];
+ unsigned int table_name_length = args->lengths[0];
+ grn_obj *table = grn_ctx_get(info->ctx,
+ table_name,
+ table_name_length);
+ if (!table) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_query_expand(): table doesn't exist: <%.*s>",
+ static_cast<int>(table_name_length),
+ table_name);
+ goto error;
+ }
+
+ const char *term_column_name = args->args[1];
+ unsigned int term_column_name_length = args->lengths[1];
+ info->term_column = grn_obj_column(info->ctx,
+ table,
+ term_column_name,
+ term_column_name_length);
+ if (!info->term_column) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_query_expand(): term column doesn't exist: <%.*s.%.*s>",
+ static_cast<int>(table_name_length),
+ table_name,
+ static_cast<int>(term_column_name_length),
+ term_column_name);
+ goto error;
+ }
+
+ const char *expanded_term_column_name = args->args[2];
+ unsigned int expanded_term_column_name_length = args->lengths[2];
+ info->expanded_term_column = grn_obj_column(info->ctx,
+ table,
+ expanded_term_column_name,
+ expanded_term_column_name_length);
+ if (!info->expanded_term_column) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_query_expand(): "
+ "expanded term column doesn't exist: <%.*s.%.*s>",
+ static_cast<int>(table_name_length),
+ table_name,
+ static_cast<int>(expanded_term_column_name_length),
+ expanded_term_column_name);
+ goto error;
+ }
+ }
+
+ init->ptr = reinterpret_cast<char *>(info);
+
+ DBUG_RETURN(FALSE);
+
+error:
+ mrn_query_expand_info_free(info);
+ DBUG_RETURN(TRUE);
+}
+
+static void query_expand(mrn::QueryExpandInfo *info, UDF_ARGS *args)
+{
+ grn_ctx *ctx = info->ctx;
+ const char *query = args->args[3];
+ unsigned int query_length = args->lengths[3];
+
+ mrn::QueryParser query_parser(info->ctx,
+ current_thd,
+ NULL,
+ NULL,
+ 0,
+ NULL);
+ const char *raw_query;
+ size_t raw_query_length;
+ grn_operator default_operator;
+ grn_expr_flags flags;
+ query_parser.parse_pragma(query,
+ query_length,
+ &raw_query,
+ &raw_query_length,
+ &default_operator,
+ &flags);
+ GRN_TEXT_SET(info->ctx,
+ &(info->expanded_query),
+ query,
+ raw_query - query);
+ grn_expr_syntax_expand_query_by_table(ctx,
+ raw_query,
+ raw_query_length,
+ flags,
+ info->term_column,
+ info->expanded_term_column,
+ &(info->expanded_query));
+}
+
+MRN_API char *mroonga_query_expand(UDF_INIT *init,
+ UDF_ARGS *args,
+ char *result,
+ unsigned long *length,
+ char *is_null,
+ char *error)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ mrn::QueryExpandInfo *info =
+ reinterpret_cast<mrn::QueryExpandInfo *>(init->ptr);
+ grn_ctx *ctx = info->ctx;
+
+ if (!args->args[3]) {
+ *is_null = 1;
+ DBUG_RETURN(NULL);
+ }
+
+ *is_null = 0;
+
+ query_expand(info, args);
+
+ if (ctx->rc) {
+ char message[MYSQL_ERRMSG_SIZE];
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_query_expand(): "
+ "failed to expand: %s",
+ ctx->errbuf);
+ my_message(ER_ERROR_ON_WRITE, message, MYF(0));
+ goto error;
+ }
+
+ *length = GRN_TEXT_LEN(&(info->expanded_query));
+ DBUG_RETURN(GRN_TEXT_VALUE(&(info->expanded_query)));
+
+error:
+ *error = 1;
+ DBUG_RETURN(NULL);
+}
+
+MRN_API void mroonga_query_expand_deinit(UDF_INIT *init)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+ mrn::QueryExpandInfo *info =
+ reinterpret_cast<mrn::QueryExpandInfo *>(init->ptr);
+ mrn_query_expand_info_free(info);
+ DBUG_VOID_RETURN;
+}
+
+MRN_END_DECLS
diff --git a/storage/mroonga/udf/mrn_udf_snippet.cpp b/storage/mroonga/udf/mrn_udf_snippet.cpp
index 22ec0884014..7a35225545d 100644
--- a/storage/mroonga/udf/mrn_udf_snippet.cpp
+++ b/storage/mroonga/udf/mrn_udf_snippet.cpp
@@ -2,7 +2,7 @@
/*
Copyright(C) 2010 Tetsuro IKEDA
Copyright(C) 2010-2013 Kentoku SHIBA
- Copyright(C) 2011-2014 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -26,13 +26,21 @@
#include <mrn_windows.hpp>
#include <mrn_table.hpp>
#include <mrn_macro.hpp>
+#include <mrn_database_manager.hpp>
+#include <mrn_context_pool.hpp>
#include <mrn_variables.hpp>
+#include <mrn_current_thread.hpp>
MRN_BEGIN_DECLS
+extern mrn::DatabaseManager *mrn_db_manager;
+extern mrn::ContextPool *mrn_context_pool;
+
struct st_mrn_snip_info
{
- grn_ctx ctx;
+ grn_ctx *ctx;
+ grn_obj *db;
+ bool use_shared_db;
grn_obj *snippet;
String result_str;
};
@@ -42,7 +50,7 @@ static my_bool mrn_snippet_prepare(st_mrn_snip_info *snip_info, UDF_ARGS *args,
{
unsigned int i;
CHARSET_INFO *cs;
- grn_ctx *ctx = &snip_info->ctx;
+ grn_ctx *ctx = snip_info->ctx;
long long snip_max_len;
long long snip_max_num;
long long skip_leading_spaces;
@@ -121,12 +129,12 @@ error:
return TRUE;
}
-MRN_API my_bool mroonga_snippet_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+MRN_API my_bool mroonga_snippet_init(UDF_INIT *init, UDF_ARGS *args, char *message)
{
uint i;
st_mrn_snip_info *snip_info = NULL;
bool can_open_snippet = TRUE;
- initid->ptr = NULL;
+ init->ptr = NULL;
if (args->arg_count < 11 || (args->arg_count - 11) % 3)
{
sprintf(message, "Incorrect number of arguments for mroonga_snippet(): %u",
@@ -168,8 +176,7 @@ MRN_API my_bool mroonga_snippet_init(UDF_INIT *initid, UDF_ARGS *args, char *mes
goto error;
}
}
- initid->maybe_null = 1;
- initid->const_item = 1;
+ init->maybe_null = 1;
if (!(snip_info = (st_mrn_snip_info *) mrn_my_malloc(sizeof(st_mrn_snip_info),
MYF(MY_WME | MY_ZEROFILL))))
@@ -177,8 +184,32 @@ MRN_API my_bool mroonga_snippet_init(UDF_INIT *initid, UDF_ARGS *args, char *mes
strcpy(message, "mroonga_snippet() out of memory");
goto error;
}
- grn_ctx_init(&snip_info->ctx, 0);
- grn_db_create(&snip_info->ctx, NULL, 0);
+ snip_info->ctx = mrn_context_pool->pull();
+ {
+ const char *current_db_path = MRN_THD_DB_PATH(current_thd);
+ const char *action;
+ if (current_db_path) {
+ action = "open database";
+ mrn::Database *db;
+ int error = mrn_db_manager->open(current_db_path, &db);
+ if (error == 0) {
+ snip_info->db = db->get();
+ grn_ctx_use(snip_info->ctx, snip_info->db);
+ snip_info->use_shared_db = true;
+ }
+ } else {
+ action = "create anonymous database";
+ snip_info->db = grn_db_create(snip_info->ctx, NULL, NULL);
+ snip_info->use_shared_db = false;
+ }
+ if (!snip_info->db) {
+ sprintf(message,
+ "mroonga_snippet(): failed to %s: %s",
+ action,
+ snip_info->ctx->errbuf);
+ goto error;
+ }
+ }
for (i = 1; i < args->arg_count; i++) {
if (!args->args[i]) {
@@ -191,24 +222,26 @@ MRN_API my_bool mroonga_snippet_init(UDF_INIT *initid, UDF_ARGS *args, char *mes
goto error;
}
}
- initid->ptr = (char *) snip_info;
+ init->ptr = (char *) snip_info;
return FALSE;
error:
if (snip_info) {
- grn_obj_close(&snip_info->ctx, grn_ctx_db(&snip_info->ctx));
- grn_ctx_fin(&snip_info->ctx);
+ if (!snip_info->use_shared_db) {
+ grn_obj_close(snip_info->ctx, snip_info->db);
+ }
+ mrn_context_pool->release(snip_info->ctx);
my_free(snip_info);
}
return TRUE;
}
-MRN_API char *mroonga_snippet(UDF_INIT *initid, UDF_ARGS *args, char *result,
- unsigned long *length, char *is_null, char *error)
+MRN_API char *mroonga_snippet(UDF_INIT *init, UDF_ARGS *args, char *result,
+ unsigned long *length, char *is_null, char *error)
{
- st_mrn_snip_info *snip_info = (st_mrn_snip_info *) initid->ptr;
- grn_ctx *ctx = &snip_info->ctx;
+ st_mrn_snip_info *snip_info = (st_mrn_snip_info *) init->ptr;
+ grn_ctx *ctx = snip_info->ctx;
String *result_str = &snip_info->result_str;
char *target;
unsigned int target_length;
@@ -286,16 +319,18 @@ error:
return NULL;
}
-MRN_API void mroonga_snippet_deinit(UDF_INIT *initid)
+MRN_API void mroonga_snippet_deinit(UDF_INIT *init)
{
- st_mrn_snip_info *snip_info = (st_mrn_snip_info *) initid->ptr;
+ st_mrn_snip_info *snip_info = (st_mrn_snip_info *) init->ptr;
if (snip_info) {
if (snip_info->snippet) {
- grn_obj_close(&snip_info->ctx, snip_info->snippet);
+ grn_obj_close(snip_info->ctx, snip_info->snippet);
}
MRN_STRING_FREE(snip_info->result_str);
- grn_obj_close(&snip_info->ctx, grn_ctx_db(&snip_info->ctx));
- grn_ctx_fin(&snip_info->ctx);
+ if (!snip_info->use_shared_db) {
+ grn_obj_close(snip_info->ctx, snip_info->db);
+ }
+ mrn_context_pool->release(snip_info->ctx);
my_free(snip_info);
}
}
diff --git a/storage/mroonga/udf/mrn_udf_snippet_html.cpp b/storage/mroonga/udf/mrn_udf_snippet_html.cpp
new file mode 100644
index 00000000000..99c9edfbba8
--- /dev/null
+++ b/storage/mroonga/udf/mrn_udf_snippet_html.cpp
@@ -0,0 +1,444 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
+/*
+ Copyright(C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <mrn_mysql.h>
+#include <mrn_mysql_compat.h>
+#include <mrn_err.h>
+#include <mrn_encoding.hpp>
+#include <mrn_windows.hpp>
+#include <mrn_table.hpp>
+#include <mrn_macro.hpp>
+#include <mrn_database_manager.hpp>
+#include <mrn_context_pool.hpp>
+#include <mrn_variables.hpp>
+#include <mrn_query_parser.hpp>
+#include <mrn_current_thread.hpp>
+
+MRN_BEGIN_DECLS
+
+extern mrn::DatabaseManager *mrn_db_manager;
+extern mrn::ContextPool *mrn_context_pool;
+
+typedef struct st_mrn_snippet_html_info
+{
+ grn_ctx *ctx;
+ grn_obj *db;
+ bool use_shared_db;
+ grn_obj *snippet;
+ String result_str;
+ struct {
+ bool used;
+ grn_obj *table;
+ grn_obj *default_column;
+ } query_mode;
+} mrn_snippet_html_info;
+
+static my_bool mrn_snippet_html_prepare(mrn_snippet_html_info *info,
+ UDF_ARGS *args,
+ char *message,
+ grn_obj **snippet)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ grn_ctx *ctx = info->ctx;
+ int flags = GRN_SNIP_SKIP_LEADING_SPACES;
+ unsigned int width = 200;
+ unsigned int max_n_results = 3;
+ const char *open_tag = "<span class=\"keyword\">";
+ const char *close_tag = "</span>";
+ grn_snip_mapping *mapping = GRN_SNIP_MAPPING_HTML_ESCAPE;
+ grn_obj *expr = NULL;
+ String *result_str = &(info->result_str);
+
+ *snippet = NULL;
+
+ mrn::encoding::set_raw(ctx, system_charset_info);
+ if (!(system_charset_info->state & (MY_CS_BINSORT | MY_CS_CSSORT))) {
+ flags |= GRN_SNIP_NORMALIZE;
+ }
+
+ *snippet = grn_snip_open(ctx, flags,
+ width, max_n_results,
+ open_tag, strlen(open_tag),
+ close_tag, strlen(close_tag),
+ mapping);
+ if (ctx->rc != GRN_SUCCESS) {
+ if (message) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_snippet_html(): failed to open grn_snip: <%s>",
+ ctx->errbuf);
+ }
+ goto error;
+ }
+
+ if (info->query_mode.used) {
+ if (!info->query_mode.table) {
+ grn_obj *short_text;
+ short_text = grn_ctx_at(info->ctx, GRN_DB_SHORT_TEXT);
+ info->query_mode.table = grn_table_create(info->ctx,
+ NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY,
+ short_text,
+ NULL);
+ }
+ if (!info->query_mode.default_column) {
+ info->query_mode.default_column =
+ grn_obj_column(info->ctx,
+ info->query_mode.table,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ }
+
+ grn_obj *record = NULL;
+ GRN_EXPR_CREATE_FOR_QUERY(info->ctx, info->query_mode.table, expr, record);
+ if (!expr) {
+ if (message) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_snippet_html(): "
+ "failed to create expression: <%s>",
+ ctx->errbuf);
+ }
+ goto error;
+ }
+
+ mrn::QueryParser query_parser(info->ctx,
+ current_thd,
+ expr,
+ info->query_mode.default_column,
+ 0,
+ NULL);
+ grn_rc rc = query_parser.parse(args->args[1], args->lengths[1]);
+ if (rc != GRN_SUCCESS) {
+ if (message) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_snippet_html(): "
+ "failed to parse query: <%s>",
+ ctx->errbuf);
+ }
+ goto error;
+ }
+
+ rc = grn_expr_snip_add_conditions(info->ctx,
+ expr,
+ *snippet,
+ 0,
+ NULL, NULL,
+ NULL, NULL);
+ if (rc != GRN_SUCCESS) {
+ if (message) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_snippet_html(): "
+ "failed to add conditions: <%s>",
+ ctx->errbuf);
+ }
+ goto error;
+ }
+ } else {
+ unsigned int i;
+ for (i = 1; i < args->arg_count; ++i) {
+ if (!args->args[i]) {
+ continue;
+ }
+ grn_rc rc = grn_snip_add_cond(ctx, *snippet,
+ args->args[i], args->lengths[i],
+ NULL, 0,
+ NULL, 0);
+ if (rc != GRN_SUCCESS) {
+ if (message) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_snippet_html(): "
+ "failed to add a condition to grn_snip: <%s>",
+ ctx->errbuf);
+ }
+ goto error;
+ }
+ }
+ }
+
+ result_str->set_charset(system_charset_info);
+ DBUG_RETURN(FALSE);
+
+error:
+ if (expr) {
+ grn_obj_close(ctx, expr);
+ }
+ if (*snippet) {
+ grn_obj_close(ctx, *snippet);
+ }
+ DBUG_RETURN(TRUE);
+}
+
+MRN_API my_bool mroonga_snippet_html_init(UDF_INIT *init,
+ UDF_ARGS *args,
+ char *message)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ mrn_snippet_html_info *info = NULL;
+
+ init->ptr = NULL;
+
+ if (args->arg_count < 1) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_snippet_html(): wrong number of arguments: %u for 1+",
+ args->arg_count);
+ goto error;
+ }
+
+
+ for (unsigned int i = 0; i < args->arg_count; ++i) {
+ switch (args->arg_type[i]) {
+ case STRING_RESULT:
+ /* OK */
+ break;
+ case REAL_RESULT:
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_snippet_html(): all arguments must be string: "
+ "<%u>=<%g>",
+ i, *((double *)(args->args[i])));
+ goto error;
+ break;
+ case INT_RESULT:
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_snippet_html(): all arguments must be string: "
+ "<%u>=<%lld>",
+ i, *((longlong *)(args->args[i])));
+ goto error;
+ break;
+ default:
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_snippet_html(): all arguments must be string: <%u>",
+ i);
+ goto error;
+ break;
+ }
+ }
+
+ init->maybe_null = 1;
+
+ info = (mrn_snippet_html_info *)mrn_my_malloc(sizeof(mrn_snippet_html_info),
+ MYF(MY_WME | MY_ZEROFILL));
+ if (!info) {
+ snprintf(message, MYSQL_ERRMSG_SIZE,
+ "mroonga_snippet_html(): failed to allocate memory");
+ goto error;
+ }
+
+ info->ctx = mrn_context_pool->pull();
+ {
+ const char *current_db_path = MRN_THD_DB_PATH(current_thd);
+ const char *action;
+ if (current_db_path) {
+ action = "open database";
+ mrn::Database *db;
+ int error = mrn_db_manager->open(current_db_path, &db);
+ if (error == 0) {
+ info->db = db->get();
+ grn_ctx_use(info->ctx, info->db);
+ info->use_shared_db = true;
+ }
+ } else {
+ action = "create anonymous database";
+ info->db = grn_db_create(info->ctx, NULL, NULL);
+ info->use_shared_db = false;
+ }
+ if (!info->db) {
+ sprintf(message,
+ "mroonga_snippet_html(): failed to %s: %s",
+ action,
+ info->ctx->errbuf);
+ goto error;
+ }
+ }
+
+ info->query_mode.used = FALSE;
+
+ if (args->arg_count == 2 &&
+ args->attribute_lengths[1] == strlen("query") &&
+ strncmp(args->attributes[1], "query", strlen("query")) == 0) {
+ info->query_mode.used = TRUE;
+ info->query_mode.table = NULL;
+ info->query_mode.default_column = NULL;
+ }
+
+ {
+ bool all_keywords_are_constant = TRUE;
+ for (unsigned int i = 1; i < args->arg_count; ++i) {
+ if (!args->args[i]) {
+ all_keywords_are_constant = FALSE;
+ break;
+ }
+ }
+
+ if (all_keywords_are_constant) {
+ if (mrn_snippet_html_prepare(info, args, message, &(info->snippet))) {
+ goto error;
+ }
+ } else {
+ info->snippet = NULL;
+ }
+ }
+
+ init->ptr = (char *)info;
+
+ DBUG_RETURN(FALSE);
+
+error:
+ if (info) {
+ if (!info->use_shared_db) {
+ grn_obj_close(info->ctx, info->db);
+ }
+ mrn_context_pool->release(info->ctx);
+ my_free(info);
+ }
+ DBUG_RETURN(TRUE);
+}
+
+MRN_API char *mroonga_snippet_html(UDF_INIT *init,
+ UDF_ARGS *args,
+ char *result,
+ unsigned long *length,
+ char *is_null,
+ char *error)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ mrn_snippet_html_info *info =
+ reinterpret_cast<mrn_snippet_html_info *>(init->ptr);
+
+ grn_ctx *ctx = info->ctx;
+ grn_obj *snippet = info->snippet;
+ String *result_str = &(info->result_str);
+
+ if (!args->args[0]) {
+ *is_null = 1;
+ DBUG_RETURN(NULL);
+ }
+
+ if (!snippet) {
+ if (mrn_snippet_html_prepare(info, args, NULL, &snippet)) {
+ goto error;
+ }
+ }
+
+ {
+ char *target = args->args[0];
+ unsigned int target_length = args->lengths[0];
+
+ unsigned int n_results, max_tagged_length;
+ {
+ grn_rc rc = grn_snip_exec(ctx, snippet, target, target_length,
+ &n_results, &max_tagged_length);
+ if (rc != GRN_SUCCESS) {
+ my_printf_error(ER_MRN_ERROR_FROM_GROONGA_NUM,
+ ER_MRN_ERROR_FROM_GROONGA_STR, MYF(0), ctx->errbuf);
+ goto error;
+ }
+ }
+
+ *is_null = 0;
+ result_str->length(0);
+
+ {
+ const char *start_tag = "<div class=\"snippet\">";
+ const char *end_tag = "</div>";
+ size_t start_tag_length = strlen(start_tag);
+ size_t end_tag_length = strlen(end_tag);
+ unsigned int max_length_per_snippet =
+ start_tag_length + end_tag_length + max_tagged_length;
+ if (result_str->reserve(max_length_per_snippet * n_results)) {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
+ goto error;
+ }
+
+ for (unsigned int i = 0; i < n_results; ++i) {
+ result_str->q_append(start_tag, start_tag_length);
+
+ unsigned int result_length;
+ grn_rc rc =
+ grn_snip_get_result(ctx, snippet, i,
+ (char *)result_str->ptr() + result_str->length(),
+ &result_length);
+ if (rc) {
+ my_printf_error(ER_MRN_ERROR_FROM_GROONGA_NUM,
+ ER_MRN_ERROR_FROM_GROONGA_STR, MYF(0), ctx->errbuf);
+ goto error;
+ }
+ result_str->length(result_str->length() + result_length);
+
+ result_str->q_append(end_tag, end_tag_length);
+ }
+ }
+
+ if (!info->snippet) {
+ grn_rc rc = grn_obj_close(ctx, snippet);
+ if (rc != GRN_SUCCESS) {
+ my_printf_error(ER_MRN_ERROR_FROM_GROONGA_NUM,
+ ER_MRN_ERROR_FROM_GROONGA_STR, MYF(0), ctx->errbuf);
+ goto error;
+ }
+ }
+ }
+
+ *length = result_str->length();
+ DBUG_RETURN((char *)result_str->ptr());
+
+error:
+ if (!info->snippet && snippet) {
+ grn_obj_close(ctx, snippet);
+ }
+
+ *is_null = 1;
+ *error = 1;
+
+ DBUG_RETURN(NULL);
+}
+
+MRN_API void mroonga_snippet_html_deinit(UDF_INIT *init)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+
+ mrn_snippet_html_info *info =
+ reinterpret_cast<mrn_snippet_html_info *>(init->ptr);
+ if (!info) {
+ DBUG_VOID_RETURN;
+ }
+
+ if (info->snippet) {
+ grn_obj_close(info->ctx, info->snippet);
+ }
+ if (info->query_mode.used) {
+ if (info->query_mode.default_column) {
+ grn_obj_close(info->ctx, info->query_mode.default_column);
+ }
+ if (info->query_mode.table) {
+ grn_obj_close(info->ctx, info->query_mode.table);
+ }
+ }
+ MRN_STRING_FREE(info->result_str);
+ if (!info->use_shared_db) {
+ grn_obj_close(info->ctx, info->db);
+ }
+ mrn_context_pool->release(info->ctx);
+ my_free(info);
+
+ DBUG_VOID_RETURN;
+}
+
+MRN_END_DECLS
diff --git a/storage/mroonga/udf/sources.am b/storage/mroonga/udf/sources.am
index 380ab4b60cf..ac2f098e310 100644
--- a/storage/mroonga/udf/sources.am
+++ b/storage/mroonga/udf/sources.am
@@ -1,5 +1,9 @@
libmrn_udf_la_SOURCES = \
mrn_udf_last_insert_grn_id.cpp \
mrn_udf_snippet.cpp \
+ mrn_udf_snippet_html.cpp \
mrn_udf_command.cpp \
- mrn_udf_escape.cpp
+ mrn_udf_escape.cpp \
+ mrn_udf_normalize.cpp \
+ mrn_udf_highlight_html.cpp \
+ mrn_udf_query_expand.cpp
diff --git a/storage/mroonga/vendor/groonga/CMakeLists.txt b/storage/mroonga/vendor/groonga/CMakeLists.txt
index 6c448a4e606..e27070f9e0c 100644
--- a/storage/mroonga/vendor/groonga/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright(C) 2012-2015 Brazil
+# Copyright(C) 2012-2016 Brazil
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -18,6 +18,7 @@
cmake_minimum_required(VERSION 2.6.2)
# cmake_minimum_required(VERSION 2.6.4) # CentOS 5
set(GRN_PROJECT_NAME "groonga")
+set(GRN_PROJECT_LABEL "Groonga")
project("${GRN_PROJECT_NAME}")
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
@@ -39,7 +40,7 @@ if(MSVC)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
- set(CMAKE_COMPILER_IS_CLANGC ON)
+ set(CMAKE_COMPILER_IS_CLANGCC ON)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_COMPILER_IS_CLANGCXX ON)
@@ -59,6 +60,8 @@ else()
endif()
endif()
string(REGEX REPLACE "(^.*=|\n)" "" GRN_VERSION "${GRN_VERSION}")
+string(REGEX REPLACE "\\." "," GRN_VERSION_RC "${GRN_VERSION}")
+string(REGEX REPLACE "-.*$" "" GRN_VERSION_RC "${GRN_VERSION_RC}")
include(CheckIncludeFile)
include(CheckFunctionExists)
@@ -97,25 +100,25 @@ set(GRN_DEFAULT_ENCODING
CACHE STRING "Groonga's default encoding")
set(GRN_DEFAULT_MATCH_ESCALATION_THRESHOLD
0
- CACHE STRING "groonga default match escalation threshold")
+ CACHE STRING "Groonga's default match escalation threshold")
set(GRN_DEFAULT_DOCUMENT_ROOT_BASE
"html/admin"
- CACHE PATH "groonga default document root base path")
+ CACHE PATH "Groonga's default document root base path")
set(GRN_DEFAULT_RELATIVE_DOCUMENT_ROOT
"share/${GRN_PROJECT_NAME}/${GRN_DEFAULT_DOCUMENT_ROOT_BASE}"
- CACHE PATH "groonga default relative document root")
+ CACHE PATH "Groonga's default relative document root")
set(GRN_DEFAULT_DOCUMENT_ROOT
"${CMAKE_INSTALL_PREFIX}/${GRN_DATA_DIR}/${GRN_DEFAULT_DOCUMENT_ROOT_BASE}"
- CACHE PATH "groonga default document root")
+ CACHE PATH "Groonga's default document root")
set(GRN_DEFAULT_DB_KEY
"auto"
CACHE STRING "Groonga's default DB key management algorithm")
set(GRN_STACK_SIZE
1024
CACHE STRING
- "DANGER!!! groonga stack size. Normarlly, you should not change this variable.")
+ "DANGER!!! Groonga's stack size. Normarlly, you should not change this variable.")
set(GRN_LOCK_TIMEOUT
- 10000000
+ 900000
CACHE STRING
"timeout to acquire a lock.")
set(GRN_LOCK_WAIT_TIME_NANOSECOND
@@ -129,42 +132,42 @@ set(GRN_PLUGINS_DIR
set(GRN_PLUGIN_SUFFIX "${CMAKE_SHARED_MODULE_SUFFIX}")
set(GRN_DLL_FILENAME
"${CMAKE_SHARED_LIBRARY_PREFIX}groonga${CMAKE_SHARED_LIBRARY_SUFFIX}")
-set(GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE "synonyms.tsv")
+set(GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE
+ "${GRN_CONFIG_DIR}/synonyms.tsv")
set(GRN_QUERY_EXPANDER_TSV_SYNONYMS_FILE
- "${CMAKE_INSTALL_PREFIX}/${GRN_DATA_DIR}/${GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE}")
+ "${CMAKE_INSTALL_PREFIX}/${GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE}")
set(GRN_RELATIVE_RUBY_SCRIPTS_DIR
"${LIB_DIR}/${GRN_PROJECT_NAME}/scripts/ruby")
set(GRN_RUBY_SCRIPTS_DIR
"${CMAKE_INSTALL_PREFIX}/${GRN_RELATIVE_RUBY_SCRIPTS_DIR}")
-if(CMAKE_COMPILER_IS_GNUCC)
+if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
set(GRN_C_COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS} -std=gnu99")
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX)
MY_CHECK_AND_SET_COMPILER_FLAG("-Wall")
- MY_CHECK_AND_SET_COMPILER_FLAG("-Wextra")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-unused-but-set-variable")
- MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-unused-parameter")
- MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-sign-compare")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-pointer-sign")
- MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-missing-field-initializers")
- MY_CHECK_AND_SET_COMPILER_FLAG("-Wformat=2")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wformat")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wstrict-aliasing=2")
MY_CHECK_AND_SET_COMPILER_FLAG("-fno-strict-aliasing")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-disabled-optimization")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wfloat-equal")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wpointer-arith")
- MY_CHECK_AND_SET_COMPILER_FLAG("-Wdeclaration-after-statement")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wbad-function-cast")
- MY_CHECK_AND_SET_COMPILER_FLAG("-Wcast-align")
- #MY_CHECK_AND_SET_COMPILER_FLAG("-Wredundant-decls")
+ if(NOT CMAKE_COMPILER_IS_CLANGCXX)
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wcast-align")
+ endif()
+ # MY_CHECK_AND_SET_COMPILER_FLAG("-Wredundant-decls")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wwrite-strings")
MY_CHECK_AND_SET_COMPILER_FLAG("-fexceptions")
MY_CHECK_AND_SET_COMPILER_FLAG("-fimplicit-templates")
- MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-clobbered")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-unused-parameter")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-sign-compare")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-missing-field-initializers")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-implicit-fallthrough")
endif()
@@ -304,7 +307,7 @@ else()
endif()
if(NOT USE_KQUEUE)
- ac_check_headers(sys/poll.h)
+ ac_check_headers(poll.h)
if(${HAVE_SYS_POLL_H})
ac_check_funcs(poll)
if(${HAVE_POLL})
@@ -339,54 +342,92 @@ if(NOT ${GRN_WITH_ZLIB} STREQUAL "no")
endif()
endif()
+file(READ "${CMAKE_CURRENT_SOURCE_DIR}/bundled_lz4_version"
+ GRN_BUNDLED_LZ4_VERSION)
+string(STRIP
+ "${GRN_BUNDLED_LZ4_VERSION}"
+ GRN_BUNDLED_LZ4_VERSION)
+option(GRN_WITH_BUNDLED_LZ4 "use bundled LZ4" OFF)
+
set(GRN_WITH_LZ4 "auto"
CACHE STRING "Support data compression by LZ4.")
if(NOT ${GRN_WITH_LZ4} STREQUAL "no")
- if(NOT DEFINED LIBLZ4_FOUND)
- pkg_check_modules(LIBLZ4 liblz4)
- endif()
- if(LIBLZ4_FOUND)
- set(GRN_WITH_LZ4 TRUE)
+ if(GRN_WITH_BUNDLED_LZ4)
+ set(LIBLZ4_INCLUDE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}/vendor/lz4-${GRN_BUNDLED_LZ4_VERSION}/lib")
+ set(LZ4_LIBS liblz4)
else()
- if(${GRN_WITH_LZ4} STREQUAL "yes")
- message(FATAL_ERROR "No LZ4 found")
+ if(NOT DEFINED LIBLZ4_FOUND)
+ pkg_check_modules(LIBLZ4 liblz4)
+ endif()
+ if(LIBLZ4_FOUND)
+ find_library(LZ4_LIBS
+ NAMES ${LIBLZ4_LIBRARIES}
+ PATHS ${LIBLZ4_LIBRARY_DIRS}
+ NO_DEFAULT_PATH)
+ set(GRN_WITH_LZ4 TRUE)
+ else()
+ if(${GRN_WITH_LZ4} STREQUAL "yes")
+ message(FATAL_ERROR "No LZ4 found")
+ endif()
+ set(GRN_WITH_LZ4 FALSE)
endif()
- set(GRN_WITH_LZ4 FALSE)
endif()
endif()
+
+file(READ "${CMAKE_CURRENT_SOURCE_DIR}/bundled_mecab_version"
+ GRN_BUNDLED_MECAB_VERSION)
+string(STRIP
+ "${GRN_BUNDLED_MECAB_VERSION}"
+ GRN_BUNDLED_MECAB_VERSION)
+file(READ "${CMAKE_CURRENT_SOURCE_DIR}/bundled_mecab_naist_jdic_version"
+ GRN_BUNDLED_MECAB_NAIST_JDIC_VERSION)
+string(STRIP
+ "${GRN_BUNDLED_MECAB_NAIST_JDIC_VERSION}"
+ GRN_BUNDLED_MECAB_NAIST_JDIC_VERSION)
+option(GRN_WITH_BUNDLED_MECAB "use bundled MeCab" OFF)
+
set(GRN_WITH_MECAB "auto"
CACHE STRING "use MeCab for morphological analysis")
if(NOT ${GRN_WITH_MECAB} STREQUAL "no")
- set(GRN_MECAB_CONFIG "mecab-config" CACHE FILEPATH "mecab-config path")
- if(NOT CMAKE_CROSSCOMPILING)
- find_program(GRN_MECAB_CONFIG_ABSOLUTE_PATH "${GRN_MECAB_CONFIG}")
- endif()
- if(EXISTS "${GRN_MECAB_CONFIG_ABSOLUTE_PATH}")
- execute_process(COMMAND "${GRN_MECAB_CONFIG_ABSOLUTE_PATH}" --inc-dir
- OUTPUT_VARIABLE MECAB_INCLUDE_DIRS
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- execute_process(COMMAND "${GRN_MECAB_CONFIG_ABSOLUTE_PATH}" --libs-only-L
- OUTPUT_VARIABLE MECAB_LIBRARY_DIRS
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- set(MECAB_LIBRARIES "mecab")
- ac_check_lib(${MECAB_LIBRARIES} mecab_new)
- if(HAVE_LIBMECAB)
- set(GRN_WITH_MECAB TRUE)
+ if(GRN_WITH_BUNDLED_MECAB)
+ set(MECAB_INCLUDE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}/vendor/mecab-${GRN_BUNDLED_MECAB_VERSION}/src")
+ set(MECAB_LIBRARY_DIRS
+ "${CMAKE_CURRENT_BUILD_DIR}/vendor/mecab")
+ set(MECAB_LIBRARIES libmecab)
+ else()
+ set(GRN_MECAB_CONFIG "mecab-config" CACHE FILEPATH "mecab-config path")
+ if(NOT CMAKE_CROSSCOMPILING)
+ find_program(GRN_MECAB_CONFIG_ABSOLUTE_PATH "${GRN_MECAB_CONFIG}")
+ endif()
+ if(EXISTS "${GRN_MECAB_CONFIG_ABSOLUTE_PATH}")
+ execute_process(COMMAND "${GRN_MECAB_CONFIG_ABSOLUTE_PATH}" --inc-dir
+ OUTPUT_VARIABLE MECAB_INCLUDE_DIRS
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(COMMAND "${GRN_MECAB_CONFIG_ABSOLUTE_PATH}" --libs-only-L
+ OUTPUT_VARIABLE MECAB_LIBRARY_DIRS
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ set(MECAB_LIBRARIES "mecab")
+ ac_check_lib(${MECAB_LIBRARIES} mecab_new)
+ if(HAVE_LIBMECAB)
+ set(GRN_WITH_MECAB TRUE)
+ else()
+ if(${GRN_WITH_MECAB} STREQUAL "yes")
+ message(FATAL_ERROR
+ "No MeCab library found: "
+ "include directories: <${MECAB_INCLUDE_DIRS}>, "
+ "library directories: <${MECAB_LIBRARY_DIRS}>")
+ endif()
+ set(GRN_WITH_MECAB FALSE)
+ endif()
else()
if(${GRN_WITH_MECAB} STREQUAL "yes")
- message(FATAL_ERROR
- "No MeCab library found: "
- "include directories: <${MECAB_INCLUDE_DIRS}>, "
- "library directories: <${MECAB_LIBRARY_DIRS}>")
+ message(FATAL_ERROR "No mecab-config found: <${GRN_MECAB_CONFIG}>")
endif()
set(GRN_WITH_MECAB FALSE)
endif()
- else()
- if(${GRN_WITH_MECAB} STREQUAL "yes")
- message(FATAL_ERROR "No mecab-config found: <${GRN_MECAB_CONFIG}>")
- endif()
- set(GRN_WITH_MECAB FALSE)
endif()
else()
set(GRN_WITH_MECAB FALSE)
@@ -487,41 +528,65 @@ else()
set(GRN_WITH_LIBEVENT FALSE)
endif()
+file(READ "${CMAKE_CURRENT_SOURCE_DIR}/bundled_message_pack_version"
+ GRN_BUNDLED_MESSAGE_PACK_VERSION)
+string(STRIP
+ "${GRN_BUNDLED_MESSAGE_PACK_VERSION}"
+ GRN_BUNDLED_MESSAGE_PACK_VERSION)
+option(GRN_WITH_BUNDLED_MESSAGE_PACK "use bundled MessagePack" OFF)
+
set(GRN_WITH_MESSAGE_PACK "auto"
CACHE STRING "use MessagePack for suggestion")
if(NOT ${GRN_WITH_MESSAGE_PACK} STREQUAL "no")
- if(NOT DEFINED MESSAGE_PACK_FOUND)
- pkg_check_modules(MESSAGE_PACK msgpack)
- endif()
- if(MESSAGE_PACK_FOUND)
- set(GRN_WITH_MESSAGE_PACK TRUE)
+ if(GRN_WITH_BUNDLED_MESSAGE_PACK)
+ set(MESSAGE_PACK_INCLUDE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}/vendor/msgpack-${GRN_BUNDLED_MESSAGE_PACK_VERSION}/include")
+ set(MESSAGE_PACK_LIBS msgpackc)
else()
- if("${GRN_WITH_MESSAGE_PACK}" STREQUAL "yes" OR
- "${GRN_WITH_MESSAGE_PACK}" STREQUAL "auto")
- set(MESSAGE_PACK_INCLUDE_DIRS "")
- set(MESSAGE_PACK_LIBRARY_DIRS "")
- else()
- set(MESSAGE_PACK_INCLUDE_DIRS "${GRN_WITH_MESSAGE_PACK}/include")
- set(MESSAGE_PACK_LIBRARY_DIRS "${GRN_WITH_MESSAGE_PACK}/lib")
+ if(NOT DEFINED MESSAGE_PACK_FOUND)
+ pkg_check_modules(MESSAGE_PACK msgpack)
endif()
- set(CMAKE_REQUIRED_INCLUDES_SAVE ${CMAKE_REQUIRED_INCLUDES})
- ac_check_lib(msgpack msgpack_version "${MESSAGE_PACK_LIBRARY_DIRS}")
- set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_SAVE})
- if(HAVE_LIBMSGPACK)
- set(MESSAGE_PACK_LIBRARIES "msgpack")
+ if(MESSAGE_PACK_FOUND)
+ find_library(MESSAGE_PACK_LIBS
+ NAMES ${MESSAGE_PACK_LIBRARIES}
+ PATHS ${MESSAGE_PACK_LIBRARY_DIRS}
+ NO_DEFAULT_PATH)
set(GRN_WITH_MESSAGE_PACK TRUE)
else()
- if(${GRN_WITH_MESSAGE_PACK} STREQUAL "yes")
- message(FATAL_ERROR "No MessagePack found")
+ if("${GRN_WITH_MESSAGE_PACK}" STREQUAL "yes" OR
+ "${GRN_WITH_MESSAGE_PACK}" STREQUAL "auto")
+ set(MESSAGE_PACK_INCLUDE_DIRS "")
+ set(MESSAGE_PACK_LIBRARY_DIRS "")
+ else()
+ set(MESSAGE_PACK_INCLUDE_DIRS "${GRN_WITH_MESSAGE_PACK}/include")
+ set(MESSAGE_PACK_LIBRARY_DIRS "${GRN_WITH_MESSAGE_PACK}/lib")
+ endif()
+ set(CMAKE_REQUIRED_INCLUDES_SAVE ${CMAKE_REQUIRED_INCLUDES})
+ ac_check_lib(msgpack msgpack_version "${MESSAGE_PACK_LIBRARY_DIRS}")
+ set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_SAVE})
+ if(HAVE_LIBMSGPACK)
+ find_library(MESSAGE_PACK_LIBS
+ NAMES "msgpack"
+ PATHS ${MESSAGE_PACK_LIBRARY_DIRS}
+ NO_DEFAULT_PATH)
+ set(GRN_WITH_MESSAGE_PACK TRUE)
+ else()
+ if(${GRN_WITH_MESSAGE_PACK} STREQUAL "yes")
+ message(FATAL_ERROR "No MessagePack found")
+ endif()
+ set(GRN_WITH_MESSAGE_PACK FALSE)
endif()
- set(GRN_WITH_MESSAGE_PACK FALSE)
endif()
endif()
else()
set(GRN_WITH_MESSAGE_PACK FALSE)
endif()
-find_program(RUBY NAMES "ruby2.1" "ruby21" "ruby")
+find_program(RUBY NAMES
+ "ruby2.3" "ruby23"
+ "ruby2.2" "ruby22"
+ "ruby2.1" "ruby21"
+ "ruby")
option(GRN_WITH_MRUBY "use mruby" OFF)
if(GRN_WITH_MRUBY)
@@ -532,6 +597,7 @@ else()
set(MRUBY_INCLUDE_DIRS "")
set(MRUBY_LIBS "")
endif()
+set(MRUBY_DEFINITIONS "MRB_INT64" "HAVE_ONIGMO_H")
# TODO: Support using system Onigmo instead of bundled Onigmo.
# set(GRN_WITH_ONIGMO ON)
@@ -581,4 +647,9 @@ if(NOT GRN_EMBED)
DESTINATION "${LIB_DIR}/pkgconfig/")
endif()
+install(FILES
+ "COPYING"
+ "README.md"
+ DESTINATION "${GRN_DATA_DIR}")
+
add_subdirectory(vendor/plugins)
diff --git a/storage/mroonga/vendor/groonga/Makefile.am b/storage/mroonga/vendor/groonga/Makefile.am
index 6f760a52b30..1fc7028ff7e 100644
--- a/storage/mroonga/vendor/groonga/Makefile.am
+++ b/storage/mroonga/vendor/groonga/Makefile.am
@@ -2,7 +2,7 @@
LOCALES = ja
-ACLOCAL_AMFLAGS = ${ACLOCAL_ARGS} -I .
+ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = 1.9.6
SUBDIRS = \
build \
@@ -20,16 +20,23 @@ SUBDIRS = \
doc
#dist_data_DATA =
EXTRA_DIST = \
+ CMakeLists.txt \
README.md \
- bindings \
- version-gen.sh \
base_version \
+ bindings \
+ bundled_lz4_version \
+ bundled_mecab_naist_jdic_version \
+ bundled_mecab_version \
+ config.h.cmake \
gpg_uid \
- CMakeLists.txt \
- config.h.cmake
+ nginx_version \
+ version-gen.sh
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = groonga.pc
+if GRN_WITH_ARROW
+pkgconfig_DATA += groonga-arrow.pc
+endif
.PHONY: FORCE
@@ -42,6 +49,7 @@ include $(srcdir)/version.sh
dist-hook:
echo "$(GRN_VERSION)" > $(distdir)/version
+ cd $(distdir) && autoreconf --install --force && find . -name autom4te.cache | xargs rm -fr
benchmark:
cd test/benchmark && $(MAKE) benchmark
@@ -74,8 +82,7 @@ update-latest-release: misc
doc/source/install.rst \
doc/source/install/*.rst \
doc/locale/*/LC_MESSAGES/install.po \
- $(GROONGA_ORG_PATH)/index.html \
- $(GROONGA_ORG_PATH)/ja/index.html
+ $(GROONGA_ORG_PATH)/_config.yml
update-po:
@for lang in $(LOCALES); do \
diff --git a/storage/mroonga/vendor/groonga/README.md b/storage/mroonga/vendor/groonga/README.md
index 09e5764a024..af0b5a7dbb5 100644
--- a/storage/mroonga/vendor/groonga/README.md
+++ b/storage/mroonga/vendor/groonga/README.md
@@ -6,6 +6,19 @@ Groonga is an open-source fulltext search engine and column store.
See doc/source/ directory or http://groonga.org/docs/.
+Here are shortcut links:
+
+ * How to install: http://groonga.org/docs/install.html
+ * Tutorial: http://groonga.org/docs/tutorial.html
+ * How to build as a developer: http://groonga.org/docs/contribution/development/build.html
+
+## Community
+
+ * [@groonga on Twitter](https://twitter.com/groonga/)
+ * [Groonga page on Facebook](https://www.facebook.com/groonga)
+ * [Mailing list on SourceForge.net](http://lists.sourceforge.net/mailman/listinfo/groonga-talk)
+ * [Chat room on Gitter](https://gitter.im/groonga/public)
+
## Bundled software
### mruby
diff --git a/storage/mroonga/vendor/groonga/appveyor.yml b/storage/mroonga/vendor/groonga/appveyor.yml
index d755e6b49fd..fca8c229a55 100644
--- a/storage/mroonga/vendor/groonga/appveyor.yml
+++ b/storage/mroonga/vendor/groonga/appveyor.yml
@@ -1,19 +1,72 @@
version: "{build}"
clone_depth: 10
-build_script:
- - git submodule update --init
- - cmake . -G "Visual Studio 12 2013 Win64"
- - cmake --build . --config Debug
+
+environment:
+ matrix:
+ - VS_VERSION: 12
+ ARCH: x86
+ - VS_VERSION: 12
+ ARCH: amd64
+ - VS_VERSION: 14
+ ARCH: x86
+ - VS_VERSION: 14
+ ARCH: amd64
notifications:
- provider: Email
to:
- - kou@clear-code.com
- - groonga-commit@lists.sourceforge.jp
+ - groonga-commit@lists.osdn.me
on_build_status_changed: true
-test: off
-# before_test:
-# - gem install grntest
-# test_script:
-# - grntest --groonga src\groonga.exe --base-directory test\command test\command\suite
+init:
+ - set PATH=C:\Ruby22\bin;%PATH%
+ - set PATH=C:\msys64\usr\bin;%PATH%
+ - call
+ "C:\Program Files (x86)\Microsoft Visual Studio %VS_VERSION%.0\VC\vcvarsall.bat"
+ %ARCH%
+# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
+
+install:
+ - tzutil /s "Tokyo Standard Time"
+ # - choco install -y imdisk-toolkit
+ # - mkdir tmp
+ # - imdisk -a -t file -m tmp -o awe -s 1G -p "/fs:ntfs /q /y"
+
+build_script:
+ - git submodule update --init
+ - cd vendor
+ - ruby download_mecab.rb
+ - ruby download_message_pack.rb
+ - ruby download_lz4.rb
+ - cd ..
+ - set CMAKE_GENERATOR_NAME=Visual Studio %VS_VERSION%
+ - if "%VS_VERSION%" == "12"
+ set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% 2013
+ - if "%VS_VERSION%" == "14"
+ set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% 2015
+ - if "%ARCH%" == "amd64"
+ set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64
+ - cmake . -G "%CMAKE_GENERATOR_NAME%"
+ -DCMAKE_INSTALL_PREFIX=c:\groonga
+ -DGRN_WITH_MRUBY=yes
+ -DGRN_WITH_BUNDLED_MECAB=yes
+ -DGRN_WITH_BUNDLED_MESSAGE_PACK=yes
+ -DGRN_WITH_BUNDLED_LZ4=yes
+ - cmake --build . --config Debug
+ - cmake --build . --config Debug --target Install
+
+before_test:
+ - git clone --depth 1
+ https://github.com/groonga/grntest.git
+ test\command\grntest
+ - cd test\command\grntest
+ - bundle install --binstubs=..\bin
+ - cd ..\..\..
+test_script:
+ - ruby test\command\bin\grntest
+ --groonga c:\groonga\bin\groonga.exe
+ --base-directory test\command
+ --reporter mark
+ --n-workers 1
+ --timeout 60
+ test\command\suite
diff --git a/storage/mroonga/vendor/groonga/autogen.sh b/storage/mroonga/vendor/groonga/autogen.sh
index 66184bf13be..98dcc83a79e 100755
--- a/storage/mroonga/vendor/groonga/autogen.sh
+++ b/storage/mroonga/vendor/groonga/autogen.sh
@@ -6,15 +6,20 @@ case `uname -s` in
Darwin)
homebrew_aclocal=/usr/local/share/aclocal
if [ -d $homebrew_aclocal ]; then
- ACLOCAL_ARGS="$ACLOCAL_ARGS -I $homebrew_aclocal"
+ ACLOCAL_PATH="$ACLOCAL_PATH $homebrew_aclocal"
fi
- gettext_aclocal="$(echo /usr/local/Cellar/gettext/*/share/aclocal)"
- if [ -d $gettext_aclocal ]; then
- ACLOCAL_ARGS="$ACLOCAL_ARGS -I $gettext_aclocal"
+ gettext_prefix=/usr/local/Cellar/gettext
+ if [ -d $gettext_prefix ]; then
+ gettext_aclocal=$(ls $gettext_prefix/*/share/aclocal | \
+ gsort --version-sort | \
+ tail -n 1)
+ if [ -d $gettext_aclocal ]; then
+ ACLOCAL_PATH="$ACLOCAL_PATH $gettext_aclocal"
+ fi
fi
;;
FreeBSD)
- ACLOCAL_ARGS="$ACLOCAL_ARGS -I /usr/local/share/aclocal/"
+ ACLOCAL_PATH="$ACLOCAL_PATH /usr/local/share/aclocal/"
;;
esac
@@ -23,4 +28,6 @@ if [ ! -e vendor/mruby-source/.git ]; then
fi
git submodule update --init
-${AUTORECONF:-autoreconf} --force --install
+mkdir -p m4
+
+${AUTORECONF:-autoreconf} --force --install "$@"
diff --git a/storage/mroonga/vendor/groonga/base_version b/storage/mroonga/vendor/groonga/base_version
index 25b08bbc78f..bf993904af8 100644
--- a/storage/mroonga/vendor/groonga/base_version
+++ b/storage/mroonga/vendor/groonga/base_version
@@ -1 +1 @@
-5.0.5 \ No newline at end of file
+7.0.7 \ No newline at end of file
diff --git a/storage/mroonga/vendor/groonga/benchmark/Makefile.am b/storage/mroonga/vendor/groonga/benchmark/Makefile.am
index 310fb4585a3..a2a8b29ab79 100644
--- a/storage/mroonga/vendor/groonga/benchmark/Makefile.am
+++ b/storage/mroonga/vendor/groonga/benchmark/Makefile.am
@@ -5,17 +5,23 @@ SUBDIRS = \
NONEXISTENT_CXX_SOURCE = nonexistent.cpp
if WITH_BENCHMARK
-noinst_PROGRAMS = \
- bench-table-factory \
- bench-geo-distance \
- bench-geo-select \
- bench-ctx-create \
- bench-query-optimizer \
- bench-range-select
+noinst_PROGRAMS = \
+ bench-table-factory \
+ bench-geo-distance \
+ bench-geo-select \
+ bench-ctx-create \
+ bench-query-optimizer \
+ bench-range-select \
+ bench-result-set \
+ bench-between-sequential \
+ bench-nfkc \
+ bench-cache
endif
EXTRA_DIST = \
- bench-query-optimizer-ddl.grn
+ bench-geo-select.sh \
+ bench-query-optimizer-ddl.grn \
+ geo-select-generate-grn.rb
AM_CPPFLAGS = \
-I$(srcdir) \
@@ -50,33 +56,56 @@ nodist_EXTRA_bench_query_optimizer_SOURCES = $(NONEXISTENT_CXX_SOURCE)
bench_range_select_SOURCES = bench-range-select.c
nodist_EXTRA_bench_range_select_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+bench_result_set_SOURCES = bench-result-set.c
+nodist_EXTRA_bench_result_set_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_between_sequential_SOURCES = bench-between-sequential.c
+nodist_EXTRA_bench_between_sequential_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_nfkc_SOURCES = bench-nfkc.c
+nodist_EXTRA_bench_nfkc_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_cache_SOURCES = bench-cache.c
+nodist_EXTRA_bench_cache_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
benchmarks = \
run-bench-table-factory \
run-bench-geo-distance \
run-bench-geo-select \
run-bench-ctx-create \
run-bench-query-optimizer \
- run-bench-range-select
+ run-bench-range-select \
+ run-bench-result-set \
+ run-bench-between-sequential \
+ run-bench-nfkc \
+ run-bench-cache
run-bench-table-factory: bench-table-factory
@echo $@:
- ./bench-table-factory
+ env \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ ./bench-table-factory
run-bench-geo-distance: bench-geo-distance
@echo $@:
- ./bench-geo-distance
+ env \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ ./bench-geo-distance
run-bench-geo-select: bench-geo-select
@echo $@:
- env \
- RUBY="$(RUBY)" \
- GROONGA="$(GROONGA)" \
- srcdir="$(srcdir)" \
+ env \
+ RUBY="$(RUBY)" \
+ GROONGA="$(GROONGA)" \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ srcdir="$(srcdir)" \
$(srcdir)/bench-geo-select.sh
run-bench-ctx-create: bench-ctx-create
@echo $@:
- ./bench-ctx-create
+ env \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ ./bench-ctx-create
run-bench-query-optimizer: bench-query-optimizer
@echo $@:
@@ -99,4 +128,26 @@ run-bench-range-select: bench-range-select
GRN_RUBY_SCRIPTS_DIR=$(top_srcdir)/lib/mrb/scripts \
./bench-range-select
+run-bench-result-set: bench-result-set
+ @echo $@:
+ env \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ ./bench-result-set
+
+run-bench-between-sequential: bench-between-sequential
+ @echo $@:
+ @[ ! -e tmp ] && ln -s /dev/shm tmp || :
+ @mkdir -p tmp/between-sequential
+ env \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ ./bench-between-sequential
+
+run-bench-nfkc: bench-nfkc
+ @echo $@:
+ ./bench-nfkc
+
+run-bench-cache: bench-cache
+ @echo $@:
+ ./bench-cache
+
benchmark: $(benchmarks)
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c b/storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c
new file mode 100644
index 00000000000..53bc3af5388
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c
@@ -0,0 +1,276 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*
+ Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
+
+ CFLAGS: -O2 -g
+
+ Groonga: e2971d9a555a90724b76964cc8c8805373500b4a
+ % make --quiet -C benchmark run-bench-between-sequential
+ run-bench-between-sequential:
+ Process 10 times in each pattern
+ (total) (average) (median)
+ ( 500, 600] ( 1000): between: (0.0528s) (0.0053s) (0.0043s)
+ ( 500, 600] ( 1000): range: (0.0120s) (0.0012s) (0.2500ms)
+ ( 5000, 5100] ( 10000): between: (0.4052s) (0.0405s) (0.0395s)
+ ( 5000, 5100] ( 10000): range: (0.0197s) (0.0020s) (0.0010s)
+ ( 50000, 50100] ( 100000): between: (3.9343s) (0.3934s) (0.3900s)
+ ( 50000, 50100] ( 100000): range: (0.0969s) (0.0097s) (0.0088s)
+ (500000, 500100] (1000000): between: (38.2969s) (3.8297s) (3.7983s)
+ (500000, 500100] (1000000): range: (0.9158s) (0.0916s) (0.0900s)
+
+ Groonga: 35e4e431bb7660b3170e98c329f7219bd6723f05
+ % make --quiet -C benchmark run-bench-between-sequential
+ run-bench-between-sequential:
+ Process 10 times in each pattern
+ (total) (average) (median)
+ ( 500, 600] ( 1000): between: (0.0130s) (0.0013s) (0.2590ms)
+ ( 500, 600] ( 1000): range: (0.0124s) (0.0012s) (0.2530ms)
+ ( 5000, 5100] ( 10000): between: (0.0163s) (0.0016s) (0.6440ms)
+ ( 5000, 5100] ( 10000): range: (0.0205s) (0.0021s) (0.0011s)
+ ( 50000, 50100] ( 100000): between: (0.0611s) (0.0061s) (0.0051s)
+ ( 50000, 50100] ( 100000): range: (0.1004s) (0.0100s) (0.0091s)
+ (500000, 500100] (1000000): between: (0.4518s) (0.0452s) (0.0442s)
+ (500000, 500100] (1000000): range: (0.8866s) (0.0887s) (0.0878s)
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grn_db.h>
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+#define GET(context, name) (grn_ctx_get(context, name, strlen(name)))
+
+typedef struct _BenchmarkData
+{
+ grn_ctx context;
+ grn_obj *database;
+ guint n_records;
+ const gchar *command;
+} BenchmarkData;
+
+static void
+run_command(grn_ctx *context, const gchar *command)
+{
+ gchar *response;
+ unsigned int response_length;
+ int flags;
+
+ grn_ctx_send(context, command, strlen(command), 0);
+ grn_ctx_recv(context, &response, &response_length, &flags);
+}
+
+static void
+bench(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ grn_ctx *context = &(data->context);
+
+ run_command(context, data->command);
+}
+
+static gchar *
+get_tmp_dir(void)
+{
+ gchar *current_dir;
+ gchar *tmp_dir;
+
+ current_dir = g_get_current_dir();
+ tmp_dir = g_build_filename(current_dir, "tmp", NULL);
+ g_free(current_dir);
+
+ return tmp_dir;
+}
+
+static void
+setup_database(BenchmarkData *data)
+{
+ grn_ctx *context = &(data->context);
+ gchar *tmp_dir;
+ gchar *database_last_component_name;
+ gchar *database_path;
+ guint i;
+
+ tmp_dir = get_tmp_dir();
+ database_last_component_name = g_strdup_printf("db-%d", data->n_records);
+ database_path = g_build_filename(tmp_dir,
+ "between-sequential",
+ database_last_component_name,
+ NULL);
+ g_free(database_last_component_name);
+
+ if (g_file_test(database_path, G_FILE_TEST_EXISTS)) {
+ data->database = grn_db_open(context, database_path);
+ run_command(context, "dump");
+ } else {
+ data->database = grn_db_create(context, database_path, NULL);
+
+ run_command(context, "table_create Entries TABLE_NO_KEY");
+ run_command(context, "column_create Entries rank COLUMN_SCALAR Int32");
+
+ run_command(context, "load --table Entries");
+ run_command(context, "[");
+ for (i = 0; i < data->n_records; i++) {
+#define BUFFER_SIZE 4096
+ gchar buffer[BUFFER_SIZE];
+ const gchar *separator;
+ if (i == (data->n_records - 1)) {
+ separator = "";
+ } else {
+ separator = ",";
+ }
+ snprintf(buffer, BUFFER_SIZE, "{\"rank\": %u}%s", i, separator);
+ run_command(context, buffer);
+#undef BUFFER_SIZE
+ }
+ run_command(context, "]");
+ }
+
+ g_free(database_path);
+}
+
+static void
+bench_startup(BenchmarkData *data)
+{
+ grn_ctx_init(&(data->context), 0);
+ setup_database(data);
+}
+
+static void
+bench_shutdown(BenchmarkData *data)
+{
+ grn_ctx *context = &(data->context);
+
+ grn_obj_close(context, data->database);
+ grn_ctx_fin(context);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchReporter *reporter;
+ gint n = 10;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+
+ g_print("Process %d times in each pattern\n", n);
+
+ bench_init(&argc, &argv);
+ reporter = bench_reporter_new();
+
+ {
+ BenchmarkData data_small_between;
+ BenchmarkData data_small_range;
+ BenchmarkData data_medium_between;
+ BenchmarkData data_medium_range;
+ BenchmarkData data_large_between;
+ BenchmarkData data_large_range;
+ BenchmarkData data_very_large_between;
+ BenchmarkData data_very_large_range;
+
+#define REGISTER(data, n_records_, min, max, is_between) \
+ do { \
+ gchar *label; \
+ label = \
+ g_strdup_printf("(%6d, %6d] (%7d): %7s", \
+ min, max, n_records_, \
+ is_between ? "between" : "range"); \
+ data.n_records = n_records_; \
+ if (is_between) { \
+ data.command = \
+ "select Entries --cache no " \
+ "--filter " \
+ "'between(rank, " #min ", \"exclude\"," \
+ " " #max ", \"include\")'"; \
+ } else { \
+ data.command = \
+ "select Entries --cache no " \
+ "--filter 'rank > " #min " && rank <= " #max "'"; \
+ } \
+ bench_startup(&data); \
+ bench_reporter_register(reporter, label, \
+ n, \
+ NULL, \
+ bench, \
+ NULL, \
+ &data); \
+ g_free(label); \
+ } while(FALSE)
+
+ REGISTER(data_small_between,
+ 1000,
+ 500, 600,
+ TRUE);
+ REGISTER(data_small_range,
+ 1000,
+ 500, 600,
+ FALSE);
+ REGISTER(data_medium_between,
+ 10000,
+ 5000, 5100,
+ TRUE);
+ REGISTER(data_medium_range,
+ 10000,
+ 5000, 5100,
+ FALSE);
+ REGISTER(data_large_between,
+ 100000,
+ 50000, 50100,
+ TRUE);
+ REGISTER(data_large_range,
+ 100000,
+ 50000, 50100,
+ FALSE);
+ REGISTER(data_very_large_between,
+ 1000000,
+ 500000, 500100,
+ TRUE);
+ REGISTER(data_very_large_range,
+ 1000000,
+ 500000, 500100,
+ FALSE);
+
+#undef REGISTER
+
+ bench_reporter_run(reporter);
+
+ bench_shutdown(&data_small_between);
+ bench_shutdown(&data_small_range);
+ bench_shutdown(&data_medium_between);
+ bench_shutdown(&data_medium_range);
+ bench_shutdown(&data_large_between);
+ bench_shutdown(&data_large_range);
+ bench_shutdown(&data_very_large_between);
+ bench_shutdown(&data_very_large_range);
+ }
+ g_object_unref(reporter);
+
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-cache.c b/storage/mroonga/vendor/groonga/benchmark/bench-cache.c
new file mode 100644
index 00000000000..ee54209c7ab
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-cache.c
@@ -0,0 +1,155 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*
+ Groonga: eb65125330b3a8f920693ef3ad53011c7412f2c9
+ CFLAGS: -O2 -g3
+ CPU: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
+
+ % make --silent -C benchmark run-bench-cache
+ run-bench-cache:
+ (total) (average) (median)
+ 1000: (0.0458s) (0.4576ms) (0.4170ms)
+ 10000: (0.3464s) (0.0035s) (0.0034s)
+ % GRN_CACHE_TYPE=persistent make --silent -C benchmark run-bench-cache
+ run-bench-cache:
+ (total) (average) (median)
+ 1000: (0.0480s) (0.4801ms) (0.4700ms)
+ 10000: (0.4033s) (0.0040s) (0.0040s)
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <grn_cache.h>
+
+#include "lib/benchmark.h"
+
+typedef struct _BenchmarkData
+{
+ grn_ctx *context;
+ grn_cache *cache;
+ grn_obj value;
+} BenchmarkData;
+
+static void
+bench_n(BenchmarkData *data, gint64 n)
+{
+ gint64 i;
+ grn_ctx *ctx;
+ grn_cache *cache;
+ grn_obj *value;
+ grn_obj fetch_buffer;
+
+ ctx = data->context;
+ cache = data->cache;
+ value = &(data->value);
+ GRN_TEXT_INIT(&fetch_buffer, 0);
+ for (i = 0; i < n; i++) {
+ char key[GRN_TABLE_MAX_KEY_SIZE];
+ grn_snprintf(key,
+ GRN_TABLE_MAX_KEY_SIZE,
+ GRN_TABLE_MAX_KEY_SIZE,
+ "key:%" GRN_FMT_INT64D,
+ i);
+ GRN_BULK_REWIND(&fetch_buffer);
+ grn_cache_fetch(ctx, cache, key, strlen(key), &fetch_buffer);
+ grn_cache_update(ctx, cache, key, strlen(key), value);
+ }
+ GRN_OBJ_FIN(ctx, &fetch_buffer);
+}
+
+static void
+bench_1000(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ bench_n(data, 1000);
+}
+
+static void
+bench_10000(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ bench_n(data, 10000);
+}
+
+static void
+bench_setup(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ data->cache = grn_cache_open(data->context);
+ GRN_TEXT_INIT(&(data->value), 0);
+ while (GRN_TEXT_LEN(&(data->value)) < 1024) {
+ GRN_TEXT_PUTS(data->context, &(data->value), "XXXXXXXXXXX");
+ }
+}
+
+static void
+bench_teardown(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ grn_obj_close(data->context, &(data->value));
+ grn_cache_close(data->context, data->cache);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchmarkData data;
+ BenchReporter *reporter;
+ gchar *base_dir;
+ grn_ctx ctx;
+ gint n = 100;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ grn_ctx_init(&ctx, 0);
+
+ data.context = &ctx;
+
+ base_dir = g_build_filename(g_get_tmp_dir(), "groonga-bench", NULL);
+ bench_utils_remove_path_recursive_force(base_dir);
+ g_mkdir_with_parents(base_dir, 0755);
+
+ reporter = bench_reporter_new();
+ bench_reporter_register(reporter, "1000", n,
+ bench_setup, bench_1000, bench_teardown, &data);
+ bench_reporter_register(reporter, "10000", n,
+ bench_setup, bench_10000, bench_teardown, &data);
+ bench_reporter_run(reporter);
+ g_object_unref(reporter);
+
+ grn_ctx_fin(&ctx);
+
+ bench_utils_remove_path_recursive_force(base_dir);
+
+ bench_quit();
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c b/storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c
index 3e43519071d..cd6a99a401f 100644
--- a/storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2; coding: utf-8 -*- */
/*
- Copyright (C) 2013-2014 Kouhei Sutou <kou@clear-code.com>
+ Copyright (C) 2013-2016 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -153,12 +153,18 @@ teardown_database(grn_ctx *context, grn_obj *database)
int
main(int argc, gchar **argv)
{
+ grn_rc rc;
grn_ctx context;
BenchmarkData data;
BenchReporter *reporter;
gint n = 1;
- grn_init();
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
bench_init(&argc, &argv);
grn_ctx_init(&context, 0);
@@ -188,5 +194,5 @@ main(int argc, gchar **argv)
grn_fin();
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c b/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c
index 72d1d79b73f..f77cfb1d3e7 100644
--- a/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2; coding: utf-8 -*- */
/*
- Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
+ Copyright (C) 2009-2016 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -48,6 +48,7 @@
*/
#include <string.h>
+#include <stdlib.h>
#include <grn_db.h>
#include <groonga.h>
@@ -421,11 +422,17 @@ bench_teardown(gpointer user_data)
int
main(int argc, gchar **argv)
{
+ grn_rc rc;
BenchmarkData data;
BenchReporter *reporter;
gint n = 1000;
- grn_init();
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
bench_init(&argc, &argv);
data.report_result = g_getenv("GROONGA_BENCH_REPORT_RESULT") != NULL;
@@ -495,5 +502,5 @@ main(int argc, gchar **argv)
bench_quit();
grn_fin();
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c
index 7b57eaaffdc..31be2c7ad17 100644
--- a/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2; coding: utf-8 -*- */
/*
- Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
+ Copyright (C) 2011-2016 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -56,6 +56,7 @@
2nd: select_in_rectangle (all): (4.61558)
*/
+#include <stdlib.h>
#include <string.h>
#include <grn_db.h>
@@ -212,11 +213,17 @@ teardown_database(BenchmarkData *data)
int
main(int argc, gchar **argv)
{
+ grn_rc rc;
BenchmarkData data;
BenchReporter *reporter;
gint n = 100;
- grn_init();
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
bench_init(&argc, &argv);
data.report_result = g_getenv("GROONGA_BENCH_REPORT_RESULT") != NULL;
@@ -265,5 +272,5 @@ main(int argc, gchar **argv)
bench_quit();
grn_fin();
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c b/storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c
new file mode 100644
index 00000000000..96b1c9bc6e2
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c
@@ -0,0 +1,275 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*
+ Groonga: ed300a833d44eaefa978b5ecf46a96ef91ae0891
+
+ CFLAGS: -O2 -g
+ % make --quiet -C benchmark run-bench-nfkc
+ run-bench-nfkc:
+ (total) (average) (median)
+ map1 - switch : (0.0060ms) (0.00060000ms) (0.00000000ms)
+ map1 - table : (0.00000000ms) (0.00000000ms) (0.00000000ms)
+ map2 - switch - no change: (0.0010ms) (0.00010000ms) (0.00000000ms)
+ map2 - table - no change: (0.00000000ms) (0.00000000ms) (0.00000000ms)
+ map2 - switch - change: (0.0010ms) (0.00010000ms) (0.00000000ms)
+ map2 - table - change: (0.0010ms) (0.00010000ms) (0.00000000ms)
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <glib.h>
+
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+#include "../lib/nfkc50.c"
+
+#define MAX_UNICODE 0x110000
+#define BUFFER_SIZE 0x100
+
+static inline int
+ucs2utf8(unsigned int i, unsigned char *buf)
+{
+ unsigned char *p = buf;
+ if (i < 0x80) {
+ *p++ = i;
+ } else {
+ if (i < 0x800) {
+ *p++ = (i >> 6) | 0xc0;
+ } else {
+ if (i < 0x00010000) {
+ *p++ = (i >> 12) | 0xe0;
+ } else {
+ if (i < 0x00200000) {
+ *p++ = (i >> 18) | 0xf0;
+ } else {
+ if (i < 0x04000000) {
+ *p++ = (i >> 24) | 0xf8;
+ } else if (i < 0x80000000) {
+ *p++ = (i >> 30) | 0xfc;
+ *p++ = ((i >> 24) & 0x3f) | 0x80;
+ }
+ *p++ = ((i >> 18) & 0x3f) | 0x80;
+ }
+ *p++ = ((i >> 12) & 0x3f) | 0x80;
+ }
+ *p++ = ((i >> 6) & 0x3f) | 0x80;
+ }
+ *p++ = (0x3f & i) | 0x80;
+ }
+ *p = '\0';
+ return (p - buf);
+}
+
+static void
+bench_char_type(gpointer user_data)
+{
+ uint64_t code_point;
+ char utf8[7];
+
+ for (code_point = 1; code_point < MAX_UNICODE; code_point++) {
+ ucs2utf8(code_point, (unsigned char *)utf8);
+ grn_nfkc50_char_type(utf8);
+ }
+}
+
+static void
+bench_decompose(gpointer user_data)
+{
+ uint64_t code_point;
+ char utf8[7];
+
+ for (code_point = 1; code_point < MAX_UNICODE; code_point++) {
+ ucs2utf8(code_point, (unsigned char *)utf8);
+ grn_nfkc50_decompose(utf8);
+ }
+}
+
+static void
+bench_compose_no_change(gpointer user_data)
+{
+ uint64_t prefix_code_point;
+ uint64_t suffix_code_point = 0x61; /* a */
+ char prefix_utf8[7];
+ char suffix_utf8[7];
+
+ ucs2utf8(suffix_code_point, (unsigned char *)suffix_utf8);
+ for (prefix_code_point = 1;
+ prefix_code_point < MAX_UNICODE;
+ prefix_code_point++) {
+ ucs2utf8(prefix_code_point, (unsigned char *)prefix_utf8);
+ grn_nfkc50_compose(prefix_utf8, suffix_utf8);
+ }
+}
+
+static void
+bench_compose_change(gpointer user_data)
+{
+ uint64_t prefix_code_point;
+ uint64_t suffix_code_point = 0x11ba;
+ char prefix_utf8[7];
+ char suffix_utf8[7];
+
+ ucs2utf8(suffix_code_point, (unsigned char *)suffix_utf8);
+ for (prefix_code_point = 1;
+ prefix_code_point < MAX_UNICODE;
+ prefix_code_point++) {
+ ucs2utf8(prefix_code_point, (unsigned char *)prefix_utf8);
+ grn_nfkc50_compose(prefix_utf8, suffix_utf8);
+ }
+}
+
+/*
+static void
+check_char_type(gpointer user_data)
+{
+ uint64_t code_point;
+ char utf8[7];
+
+ for (code_point = 1; code_point < MAX_UNICODE; code_point++) {
+ grn_char_type a;
+ grn_char_type b;
+
+ ucs2utf8(code_point, (unsigned char *)utf8);
+ a = grn_nfkc_char_type(utf8);
+ b = grn_nfkc50_char_type(utf8);
+ if (a == b) {
+ continue;
+ }
+ printf("%lx: %s: %d != %d\n", code_point, utf8, a, b);
+ }
+}
+
+static void
+check_decompose(gpointer user_data)
+{
+ uint64_t code_point;
+ char utf8[7];
+
+ for (code_point = 1; code_point < MAX_UNICODE; code_point++) {
+ const char *a;
+ const char *b;
+
+ ucs2utf8(code_point, (unsigned char *)utf8);
+ a = grn_nfkc_decompose(utf8);
+ b = grn_nfkc50_decompose(utf8);
+ if (a == b) {
+ continue;
+ }
+ if (!a || !b) {
+ printf("%lx: %s: %s != %s\n", code_point, utf8, a, b);
+ continue;
+ }
+ if (strcmp(a, b) != 0) {
+ printf("%lx: %s: %s != %s\n", code_point, utf8, a, b);
+ }
+ }
+}
+
+static void
+check_compose(gpointer user_data)
+{
+ uint64_t prefix_code_point;
+ uint64_t suffix_code_point;
+ char prefix_utf8[7];
+ char suffix_utf8[7];
+
+ for (prefix_code_point = 1;
+ prefix_code_point < MAX_UNICODE;
+ prefix_code_point++) {
+ ucs2utf8(prefix_code_point, (unsigned char *)prefix_utf8);
+ for (suffix_code_point = 1;
+ suffix_code_point < MAX_UNICODE;
+ suffix_code_point++) {
+ const char *a;
+ const char *b;
+
+ ucs2utf8(suffix_code_point, (unsigned char *)suffix_utf8);
+ a = grn_nfkc_compose(prefix_utf8, suffix_utf8);
+ b = grn_nfkc50_compose(prefix_utf8, suffix_utf8);
+ if (a == b) {
+ continue;
+ }
+ if (!a || !b) {
+ printf("%lx-%lx: %s-%s: %s != %s\n",
+ prefix_code_point, suffix_code_point,
+ prefix_utf8, suffix_utf8,
+ a, b);
+ continue;
+ }
+ if (strcmp(a, b) != 0) {
+ printf("%lx-%lx: %s-%s: %s != %s\n",
+ prefix_code_point, suffix_code_point,
+ prefix_utf8, suffix_utf8,
+ a, b);
+ }
+ }
+ if ((prefix_code_point % 10000) == 0) {
+ printf("%" G_GUINT64_FORMAT "\n", prefix_code_point);
+ }
+ }
+}
+*/
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchReporter *reporter;
+ gint n = 10;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ reporter = bench_reporter_new();
+
+ if (g_getenv("N")) {
+ n = atoi(g_getenv("N"));
+ }
+
+#define REGISTER(label, bench_function) \
+ bench_reporter_register(reporter, label, n, \
+ NULL, \
+ bench_function, \
+ NULL, \
+ NULL)
+ REGISTER("char_type ", bench_char_type);
+ REGISTER("decompose ", bench_decompose);
+ REGISTER("compose - no change", bench_compose_no_change);
+ REGISTER("compose - change", bench_compose_change);
+
+ /*
+ REGISTER("check - char_type", check_char_type);
+ REGISTER("check - decompose", check_decompose);
+ REGISTER("check - compose ", check_compose);
+ */
+#undef REGISTER
+
+ bench_reporter_run(reporter);
+ g_object_unref(reporter);
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c b/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c
index d7ed91d0c56..4ce55c55b6a 100644
--- a/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2; coding: utf-8 -*- */
/*
- Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
+ Copyright (C) 2014-2016 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -135,12 +135,18 @@ teardown_database(grn_ctx *context, grn_obj *database)
int
main(int argc, gchar **argv)
{
+ grn_rc rc;
grn_ctx context;
grn_obj *database;
BenchReporter *reporter;
gint n = 100;
- grn_init();
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
bench_init(&argc, &argv);
grn_ctx_init(&context, 0);
@@ -204,5 +210,5 @@ main(int argc, gchar **argv)
grn_fin();
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c b/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c
index d45d453cba6..a0664d58270 100644
--- a/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2; coding: utf-8 -*- */
/*
- Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
+ Copyright (C) 2014-2016 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -179,10 +179,16 @@ bench_shutdown(BenchmarkData *data)
int
main(int argc, gchar **argv)
{
+ grn_rc rc;
BenchReporter *reporter;
gint n = 10;
- grn_init();
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
g_print("Process %d times in each pattern\n", n);
@@ -270,5 +276,5 @@ main(int argc, gchar **argv)
grn_fin();
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-result-set.c b/storage/mroonga/vendor/groonga/benchmark/bench-result-set.c
new file mode 100644
index 00000000000..cd4866e5033
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-result-set.c
@@ -0,0 +1,151 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+typedef struct _BenchmarkData
+{
+ gchar *base_dir;
+ grn_ctx *context;
+ grn_obj *source_table;
+ grn_obj *result_set;
+} BenchmarkData;
+
+static void
+bench_n(BenchmarkData *data, gint64 n)
+{
+ gint64 i;
+ grn_ctx *ctx;
+ grn_hash *result_set;
+
+ ctx = data->context;
+ result_set = (grn_hash *)data->result_set;
+ for (i = 0; i < n; i++) {
+ grn_id id = i;
+ grn_hash_add(ctx, result_set, &id, sizeof(grn_id), NULL, NULL);
+ }
+}
+
+static void
+bench_1000(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ bench_n(data, 1000);
+}
+
+static void
+bench_10000(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ bench_n(data, 10000);
+}
+
+static void
+bench_100000(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ bench_n(data, 100000);
+}
+
+static void
+bench_setup(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ data->result_set = grn_table_create(data->context,
+ NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
+ data->source_table,
+ NULL);
+
+}
+
+static void
+bench_teardown(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ grn_obj_close(data->context, data->result_set);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchmarkData data;
+ BenchReporter *reporter;
+ gchar *base_dir;
+ grn_ctx ctx;
+ gint n = 100;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ data.context = &ctx;
+
+ base_dir = g_build_filename(g_get_tmp_dir(), "groonga-bench", NULL);
+ bench_utils_remove_path_recursive_force(base_dir);
+ g_mkdir_with_parents(base_dir, 0755);
+
+ {
+ gchar *database_path;
+ const gchar *source_table_name = "Sources";
+
+ grn_ctx_init(&ctx, 0);
+ database_path = g_build_filename(base_dir, "db", NULL);
+ grn_db_create(&ctx, database_path, NULL);
+ g_free(database_path);
+
+ data.source_table = grn_table_create(&ctx,
+ source_table_name,
+ strlen(source_table_name),
+ NULL,
+ GRN_TABLE_PAT_KEY | GRN_OBJ_PERSISTENT,
+ grn_ctx_at(&ctx, GRN_DB_SHORT_TEXT),
+ NULL);
+ }
+
+ reporter = bench_reporter_new();
+ bench_reporter_register(reporter, "1000", n,
+ bench_setup, bench_1000, bench_teardown, &data);
+ bench_reporter_register(reporter, "10000", n,
+ bench_setup, bench_10000, bench_teardown, &data);
+ bench_reporter_register(reporter, "100000", n,
+ bench_setup, bench_100000, bench_teardown, &data);
+ bench_reporter_run(reporter);
+ g_object_unref(reporter);
+
+ grn_ctx_fin(&ctx);
+
+ bench_utils_remove_path_recursive_force(data.base_dir);
+
+ bench_quit();
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c b/storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c
index 7e06874dffd..9e378f5530b 100644
--- a/storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2; coding: utf-8 -*- */
/*
- Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org>
+ Copyright (C) 2008-2016 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -17,6 +17,7 @@
*/
#include <string.h>
+#include <stdlib.h>
#include <groonga.h>
@@ -226,11 +227,17 @@ bench_teardown(gpointer user_data)
int
main(int argc, gchar **argv)
{
+ grn_rc rc;
BenchmarkData data;
BenchReporter *reporter;
gint n = 100;
- grn_init();
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
bench_init(&argc, &argv);
data.context = g_new(grn_ctx, 1);
@@ -266,5 +273,5 @@ main(int argc, gchar **argv)
bench_quit();
grn_fin();
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am b/storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am
index 55d113f92e9..2031b9aad8c 100644
--- a/storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am
+++ b/storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am
@@ -9,6 +9,9 @@ AM_CPPFLAGS = \
AM_CFLAGS = \
$(GLIB_CFLAGS)
+CFLAGS += \
+ $(NO_BAD_FUNCTION_CAST_CFLAGS)
+
LIBS = \
$(GLIB_LIBS)
diff --git a/storage/mroonga/vendor/groonga/build/ac_macros/check_functions.m4 b/storage/mroonga/vendor/groonga/build/ac_macros/check_functions.m4
index 02eb52f30a6..a0b424b3111 100644
--- a/storage/mroonga/vendor/groonga/build/ac_macros/check_functions.m4
+++ b/storage/mroonga/vendor/groonga/build/ac_macros/check_functions.m4
@@ -2,8 +2,6 @@
AC_CHECK_FUNCS(_gmtime64_s)
AC_CHECK_FUNCS(_localtime64_s)
-AC_CHECK_FUNCS(_stricmp)
-AC_CHECK_FUNCS(_strnicmp)
AC_CHECK_FUNCS(_strtoui64)
AC_CHECK_FUNCS(gmtime_r)
AC_CHECK_FUNCS(localtime_r)
diff --git a/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4 b/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4
index 9a30ca8fc9c..fca8465123c 100644
--- a/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4
+++ b/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4
@@ -7,10 +7,6 @@ AC_CHECK_HEADERS(execinfo.h)
AC_CHECK_HEADERS(inttypes.h)
AC_CHECK_HEADERS(netdb.h)
AC_CHECK_HEADERS(signal.h)
-AC_CHECK_HEADERS(stdarg.h)
-AC_CHECK_HEADERS(stdint.h)
-AC_CHECK_HEADERS(string.h)
-AC_CHECK_HEADERS(strings.h)
AC_CHECK_HEADERS(sys/mman.h)
AC_CHECK_HEADERS(sys/param.h)
AC_CHECK_HEADERS(sys/resource.h)
diff --git a/storage/mroonga/vendor/groonga/build/makefiles/gettext.am b/storage/mroonga/vendor/groonga/build/makefiles/gettext.am
index 9cea8ce63c1..c6e57c7b47b 100644
--- a/storage/mroonga/vendor/groonga/build/makefiles/gettext.am
+++ b/storage/mroonga/vendor/groonga/build/makefiles/gettext.am
@@ -59,8 +59,6 @@ build:
endif
html: build
-man: build
-pdf: build
gettext:
rm *.pot || true
diff --git a/storage/mroonga/vendor/groonga/build/makefiles/sphinx-build.am b/storage/mroonga/vendor/groonga/build/makefiles/sphinx-build.am
index e237377ba80..047823b6ed7 100644
--- a/storage/mroonga/vendor/groonga/build/makefiles/sphinx-build.am
+++ b/storage/mroonga/vendor/groonga/build/makefiles/sphinx-build.am
@@ -2,18 +2,13 @@
DOCTREES_BASE = doctrees
SPHINXOPTS =
-PAPER =
# Internal variables.
SOURCE_DIR = $(abs_top_srcdir)/doc/source
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = $(PAPEROPT_$(PAPER)) -E $(SPHINXOPTS) $(SOURCE_DIR)
+ALLSPHINXOPTS = -E $(SPHINXOPTS) $(SOURCE_DIR)
-SPHINX_DIR = $(abs_top_builddir)/doc/sphinx
-SPHINX_BUILD_COMMAND = \
- DOCUMENT_VERSION="$(DOCUMENT_VERSION)" \
+SPHINX_BUILD_COMMAND = \
+ DOCUMENT_VERSION="$(DOCUMENT_VERSION)" \
DOCUMENT_VERSION_FULL="$(DOCUMENT_VERSION_FULL)" \
- LOCALE="$(LOCALE)" \
- PYTHONPATH="$(SPHINX_DIR):$$PYTHONPATH" \
+ LOCALE="$(LOCALE)" \
$(SPHINX_BUILD)
diff --git a/storage/mroonga/vendor/groonga/build/makefiles/sphinx.am b/storage/mroonga/vendor/groonga/build/makefiles/sphinx.am
index c68f62e26ec..161abe06757 100644
--- a/storage/mroonga/vendor/groonga/build/makefiles/sphinx.am
+++ b/storage/mroonga/vendor/groonga/build/makefiles/sphinx.am
@@ -3,7 +3,6 @@ include $(top_srcdir)/build/makefiles/sphinx-build.am
$(html_files): html-build-stamp
$(html_files_relative_from_locale_dir): html-build-stamp
-$(man_files): man-build-stamp
am__nobase_dist_doc_locale_DATA_DIST =
if DOCUMENT_AVAILABLE
@@ -22,41 +21,16 @@ document_source_files = \
required_build_stamps = \
html-build-stamp \
- man-build-stamp \
mo-build-stamp
if DOCUMENT_BUILDABLE
EXTRA_DIST += $(required_build_stamps)
endif
-man_files = \
- man/$(PACKAGE_NAME).1
-
generated_files = \
$(DOCTREES_BASE) \
- man \
- man-build-stamp \
html \
- html-build-stamp \
- pdf \
- pdf-build-stamp \
- dirhtml \
- dirhtml-build-stamp \
- pickle \
- pikcle-build-stamp \
- json \
- json-build-stamp \
- htmlhelp \
- htmlhelp-build-stamp \
- qthelp \
- qthelp-build-stamp \
- latex \
- latex-build-stamp \
- changes \
- changes-build-stamp \
- linkcheck \
- linkcheck-build-stamp \
- doctest
+ html-build-stamp
$(mo_files_relative_from_locale_dir): mo-build-stamp
@@ -75,83 +49,24 @@ maintainer-clean-local:
endif
.PHONY: help
-.PHONY: man clean-man
.PHONY: html clean-html
-.PHONY: pdf
-.PHONY: dirhtml
-.PHONY: pickle
-.PHONY: json
-.PHONY: htmlhelp
-.PHONY: qthelp
-.PHONY: latex
-.PHONY: changes
-.PHONY: linkcheck
-.PHONY: doctest
if DOCUMENT_BUILDABLE
help:
@echo "Please use \`make <target>' where <target> is one of"
- @echo " man to make man files"
@echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " rdoc to make RDoc files"
- @echo " textile to make Textile files"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
-
-man: man-build-stamp
+
html: html-recursive html-build-stamp
-dirhtml: dirhtml-build-stamp
-pickle: pickle-build-stamp
-json: json-build-stamp
-htmlhelp: htmlhelp-build-stamp
-qthelp: qthelp-build-stamp
-latex: latex-build-stamp
-rdoc: rdoc-build-stamp
-textile: textile-build-stamp
-changes: changes-build-stamp
-linkcheck: linkcheck-build-stamp
-doctest: doctest-build-stamp
clean_targets = \
- clean-man \
- clean-html \
- clean-dirhtml \
- clean-pickle \
- clean-json \
- clean-htmlhelp \
- clean-qthelp \
- clean-latex \
- clean-rdoc \
- clean-textile \
- clean-changes \
- clean-linkcheck \
- clean-doctest
+ clean-html
$(clean_targets):
target=`echo $@ | sed -e 's/^clean-//'`; \
rm -rf $${target}-build-stamp $${target}
build_stamps = \
- man-build-stamp \
- html-build-stamp \
- dirhtml-build-stamp \
- pickle-build-stamp \
- json-build-stamp \
- htmlhelp-build-stamp \
- qthelp-build-stamp \
- latex-build-stamp \
- rdoc-build-stamp \
- textile-build-stamp \
- changes-build-stamp \
- linkcheck-build-stamp \
- doctest-build-stamp
+ html-build-stamp
$(build_stamps): $(document_source_files)
target=`echo $@ | sed -e 's/-build-stamp$$//'`; \
@@ -162,18 +77,4 @@ $(build_stamps): $(document_source_files)
$(ALLSPHINXOPTS) \
$${target}
@touch $@
-
-qthelp: qthelp-message
-qthelp-message: qthelp-build-stamp
- @echo "Build finished; now you can run 'qcollectiongenerator' with the" \
- ".qhcp project file in qthelp/*, like this:"
- @echo "# qcollectiongenerator qthelp/groonga.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile qthelp/groonga.qhc"
-
-latex: latex-message
-latex-message: latex-build-stamp
- @echo "Build finished; the LaTeX files are in latex/*."
- @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
- "run these through (pdf)latex."
endif
diff --git a/storage/mroonga/vendor/groonga/bundled_lz4_version b/storage/mroonga/vendor/groonga/bundled_lz4_version
new file mode 100644
index 00000000000..6a126f402d5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/bundled_lz4_version
@@ -0,0 +1 @@
+1.7.5
diff --git a/storage/mroonga/vendor/groonga/bundled_mecab_naist_jdic_version b/storage/mroonga/vendor/groonga/bundled_mecab_naist_jdic_version
new file mode 100644
index 00000000000..495c21efd6d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/bundled_mecab_naist_jdic_version
@@ -0,0 +1 @@
+0.6.3b-20111013
diff --git a/storage/mroonga/vendor/groonga/bundled_mecab_version b/storage/mroonga/vendor/groonga/bundled_mecab_version
new file mode 100644
index 00000000000..00445f812df
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/bundled_mecab_version
@@ -0,0 +1 @@
+0.996
diff --git a/storage/mroonga/vendor/groonga/bundled_message_pack_version b/storage/mroonga/vendor/groonga/bundled_message_pack_version
new file mode 100644
index 00000000000..3e3c2f1e5ed
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/bundled_message_pack_version
@@ -0,0 +1 @@
+2.1.1
diff --git a/storage/mroonga/vendor/groonga/config.h.cmake b/storage/mroonga/vendor/groonga/config.h.cmake
index 8e3bdaf216b..bfd0cbdc012 100644
--- a/storage/mroonga/vendor/groonga/config.h.cmake
+++ b/storage/mroonga/vendor/groonga/config.h.cmake
@@ -3,12 +3,13 @@
/* general constants */
#define CONFIGURE_OPTIONS "${CONFIGURE_OPTIONS}"
-#define HOST_CPU "${CMAKE_HOST_SYSTEM_PROCESSOR}"
-#define HOST_OS "${CMAKE_HOST_SYSTEM_NAME}"
+#define HOST_CPU "${CMAKE_SYSTEM_PROCESSOR}"
+#define HOST_OS "${CMAKE_SYSTEM_NAME}"
#define VERSION "${VERSION}"
#define PACKAGE "${PROJECT_NAME}"
#define PACKAGE_NAME "${PROJECT_NAME}"
+#define PACKAGE_LABEL "${GRN_PROJECT_LABEL}"
#define PACKAGE_STRING "${PROJECT_NAME} ${VERSION}"
#define PACKAGE_TARNAME "${PROJECT_NAME}"
#define PACKAGE_URL "${PACKAGE_URL}"
@@ -84,6 +85,7 @@
#cmakedefine GRN_WITH_CUTTER
#cmakedefine GRN_WITH_KYTEA
#cmakedefine GRN_WITH_LZ4
+#cmakedefine GRN_WITH_ZSTD
#cmakedefine GRN_WITH_MECAB
#cmakedefine GRN_WITH_MESSAGE_PACK
#cmakedefine GRN_WITH_MRUBY
@@ -103,10 +105,6 @@
#cmakedefine HAVE_NETDB_H
#cmakedefine HAVE_PTHREAD_H
#cmakedefine HAVE_SIGNAL_H
-#cmakedefine HAVE_STDARG_H
-#cmakedefine HAVE_STDINT_H
-#cmakedefine HAVE_STRINGS_H
-#cmakedefine HAVE_STRING_H
#cmakedefine HAVE_SYS_MMAN_H
#cmakedefine HAVE_SYS_PARAM_H
#cmakedefine HAVE_SYS_RESOURCE_H
@@ -133,8 +131,6 @@
/* functions */
#cmakedefine HAVE__GMTIME64_S
#cmakedefine HAVE__LOCALTIME64_S
-#cmakedefine HAVE__STRICMP
-#cmakedefine HAVE__STRNICMP
#cmakedefine HAVE__STRTOUI64
#cmakedefine HAVE_BACKTRACE
#cmakedefine HAVE_CLOCK
diff --git a/storage/mroonga/vendor/groonga/configure.ac b/storage/mroonga/vendor/groonga/configure.ac
index dad29c78f4c..414876c6a26 100644
--- a/storage/mroonga/vendor/groonga/configure.ac
+++ b/storage/mroonga/vendor/groonga/configure.ac
@@ -1,13 +1,18 @@
AC_PREREQ(2.59)
m4_define([groonga_version], m4_include(base_version))
AC_INIT([groonga], groonga_version, [groonga@razil.jp])
+AC_CONFIG_MACRO_DIR([m4])
AM_CONFIG_HEADER(config.h)
+GRN_VERSION_RC=`echo groonga_version | sed -e 's/\./,/g'`
+AC_SUBST(GRN_VERSION_RC)
+
AM_INIT_AUTOMAKE([foreign tar-pax subdir-objects])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-PACKAGE_TITLE=Groonga
-AC_SUBST(PACKAGE_TITLE)
+PACKAGE_LABEL=Groonga
+AC_SUBST(PACKAGE_LABEL)
+AC_DEFINE_UNQUOTED(PACKAGE_LABEL, ["$PACKAGE_LABEL"], [Label of package])
# for Autoconf 2.60 or earlier.
if test -z "${datarootdir}"; then
@@ -74,6 +79,8 @@ AC_MSG_RESULT([$solaris])
AC_C_BIGENDIAN
AC_PROG_CXX
+m4_ifdef([AX_CXX_COMPILE_STDCXX_11],
+ [AX_CXX_COMPILE_STDCXX_11([ext], [optional])])
AC_PROG_CC
m4_ifdef([AC_PROG_CC_C99],
[AC_PROG_CC_C99])
@@ -142,19 +149,17 @@ TEST_CFLAGS=""
TEST_CXXFLAGS=""
NO_STRICT_ALIASING_CFLAGS=""
NO_FLOAT_EQUAL_CFLAGS=""
+NO_BAD_FUNCTION_CAST_CFLAGS=""
if test "$GCC" = "yes"; then
CHECK_BUILD_FLAG([-Wall])
- CHECK_BUILD_FLAG([-Wextra])
if test "x$check_cflag" = "xno"; then
CHECK_BUILD_FLAG([-W])
fi
CHECK_BUILD_FLAG([-Wno-unused-but-set-variable]) # FIXME: enable it.
- CHECK_BUILD_FLAG([-Wno-unused-parameter])
- CHECK_BUILD_FLAG([-Wno-sign-compare])
CHECK_CFLAG([-Wno-pointer-sign])
- CHECK_BUILD_FLAG([-Wno-missing-field-initializers])
+ CHECK_CFLAG([-Wno-declaration-after-statement])
- CHECK_BUILD_FLAG([-Wformat=2])
+ CHECK_BUILD_FLAG([-Wformat])
CHECK_BUILD_FLAG([-Wstrict-aliasing=2])
if test "x$check_cflag" = "xyes"; then
NO_STRICT_ALIASING_CFLAGS="-fno-strict-aliasing"
@@ -166,6 +171,9 @@ if test "$GCC" = "yes"; then
fi
CHECK_BUILD_FLAG([-Wpointer-arith])
CHECK_CFLAG([-Wbad-function-cast])
+ if test "x$check_cflag" = "xyes"; then
+ NO_BAD_FUNCTION_CAST_CFLAGS="-Wno-bad-function-cast"
+ fi
if test "$CLANG" = "no"; then
CHECK_BUILD_FLAG([-Wcast-align])
fi
@@ -180,27 +188,16 @@ if test "$GCC" = "yes"; then
CHECK_CXXFLAG([-fexceptions])
CHECK_CXXFLAG([-fimplicit-templates])
-
- CFLAGS_for_source="$CFLAGS"
- CXXFLAGS_for_source="$CXXFLAGS"
- CHECK_BUILD_FLAG([-Wno-clobbered])
- if test "x$check_cflag" = "xyes"; then
- TEST_CFLAGS="-Wno-clobbered"
- fi
- if test "x$check_cxxflag" = "xyes"; then
- TEST_CXXFLAGS="-Wno-clobbered"
- fi
- CFLAGS="$CFLAGS_for_source"
- CXXFLAGS="$CXXFLAGS_for_source"
fi
AC_SUBST(TEST_CFLAGS)
AC_SUBST(TEST_CXXFLAGS)
AC_SUBST(NO_STRICT_ALIASING_CFLAGS)
AC_SUBST(NO_FLOAT_EQUAL_CFLAGS)
+AC_SUBST(NO_BAD_FUNCTION_CAST_CFLAGS)
-AC_LIBTOOL_WIN32_DLL
-AM_PROG_LIBTOOL
-m4_ifdef([LT_OUTPUT], [LT_OUTPUT])
+LT_INIT([dlopen win32-dll])
+LT_LANG([Windows Resource])
+LT_OUTPUT
LT_CURRENT=0
LT_REVISION=0
@@ -233,19 +230,23 @@ AC_CONFIG_FILES([
lib/mrb/scripts/Makefile
lib/mrb/scripts/command_line/Makefile
lib/mrb/scripts/context/Makefile
+ lib/mrb/scripts/expression_tree/Makefile
lib/mrb/scripts/initialize/Makefile
lib/mrb/scripts/logger/Makefile
+ lib/mrb/scripts/query_logger/Makefile
+ lib/proc/Makefile
+ lib/ts/Makefile
include/Makefile
include/groonga/Makefile
plugins/Makefile
plugins/tokenizers/Makefile
plugins/suggest/Makefile
- plugins/table/Makefile
plugins/query_expanders/Makefile
plugins/ruby/Makefile
plugins/token_filters/Makefile
plugins/sharding/Makefile
plugins/functions/Makefile
+ plugins/expression_rewriters/Makefile
examples/Makefile
examples/dictionary/Makefile
examples/dictionary/edict/Makefile
@@ -264,19 +265,18 @@ AC_CONFIG_FILES([
packages/windows/language-files/Makefile
packages/windows/setup-x64.nsi
data/Makefile
- data/images/Makefile
- data/images/logo/Makefile
data/html/Makefile
data/munin/Makefile
data/init.d/Makefile
- data/init.d/redhat/Makefile
- data/init.d/redhat/sysconfig/Makefile
+ data/init.d/centos/Makefile
+ data/init.d/centos/sysconfig/Makefile
data/logrotate.d/Makefile
- data/logrotate.d/redhat/Makefile
+ data/logrotate.d/centos/Makefile
data/systemd/Makefile
- data/systemd/fedora/Makefile
- data/systemd/fedora/sysconfig/Makefile
+ data/systemd/centos/Makefile
+ data/systemd/centos/sysconfig/Makefile
data/scripts/Makefile
+ data/tmpfiles.d/Makefile
tools/Makefile
doc/Makefile
doc/locale/Makefile
@@ -304,7 +304,10 @@ AC_CONFIG_FILES([
benchmark/fixtures/geo-select/Makefile
benchmark/lib/Makefile
vendor/Makefile
+ vendor/lz4/Makefile
vendor/onigmo/Makefile
+ vendor/mecab/Makefile
+ vendor/message_pack/Makefile
vendor/mruby/Makefile
])
@@ -355,14 +358,14 @@ AC_LINK_IFELSE(
[
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
- [#define _ISOC99_SOURCE
+ [#define _ISOC99_SOURCE
#include <math.h>],
- [if (fpclassify(0.0)) {return 0;}]
+ [if (fpclassify(0.0)) {return 0;}]
)],
[
AC_DEFINE(_ISOC99_SOURCE, [1], [Define to 1 for fpclassify])
- AC_DEFINE(HAVE_FPCLASSIFY, [1], [use fpclassify with _ISOC99_SOURCE])
- AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_FPCLASSIFY, [1], [use fpclassify with _ISOC99_SOURCE])
+ AC_MSG_RESULT(yes)
],
[
AC_MSG_RESULT(no)
@@ -454,7 +457,7 @@ AC_ARG_WITH(stack_size,
AC_DEFINE_UNQUOTED(GRN_STACK_SIZE, [$GRN_STACK_SIZE], [stack size])
# lock timeout
-GRN_LOCK_TIMEOUT=10000000
+GRN_LOCK_TIMEOUT=900000
AC_ARG_WITH(lock_timeout,
[AS_HELP_STRING([--with-lock-timeout=N],
[This option specifies how many times Groonga tries to acquire a lock.
@@ -609,7 +612,7 @@ if test "x$have_epoll" != "xyes"; then
])
])
if test "x$have_kqueue" != "xyes"; then
- AC_CHECK_HEADER(sys/poll.h, [
+ AC_CHECK_HEADER(poll.h, [
AC_CHECK_FUNC(poll, [
have_poll="yes"
AC_DEFINE(USE_POLL, [1], [use poll])
@@ -617,7 +620,7 @@ if test "x$have_epoll" != "xyes"; then
])
if test "x$have_poll" != "xyes"; then
if test "$os_win32" = "yes"; then
- AC_CHECK_HEADER(winsock2.h, [have_select="yes"])
+ AC_CHECK_HEADER(winsock2.h, [have_select="yes"])
else
AC_CHECK_FUNC(select, [
have_select="yes"
@@ -750,18 +753,23 @@ if test "x$RUBY" = "xno"; then
else
if test "x$RUBY" = "xyes"; then
AC_PATH_PROGS(RUBY,
- [ruby2.1 ruby21 ruby2.0 ruby20 ruby1.9 ruby19 ruby1.9.1 ruby],
+ [ dnl
+ ruby2.3 ruby23 dnl
+ ruby2.2 ruby22 dnl
+ ruby2.1 ruby21 dnl
+ ruby dnl
+ ],
ruby-not-found)
if test "$RUBY" != "ruby-not-found"; then
ruby_version="`$RUBY --version`"
- if echo "$ruby_version" | grep -q -- 'ruby \(1\.9\|2\.\)'; then
+ if echo "$ruby_version" | grep -q -- 'ruby \(2\.\)'; then
ac_cv_ruby_available="yes"
else
- AC_MSG_WARN([$RUBY isn't Ruby 1.9 or later ($ruby_version)])
+ AC_MSG_WARN([$RUBY isn't Ruby 2.0 or later ($ruby_version)])
fi
fi
else
- ruby_not_found_warning_message="$RUBY is not found. Disable HTTP test."
+ ruby_not_found_warning_message="$RUBY is not found."
case "$RUBY" in
/*)
AC_CHECK_FILE([$RUBY],
@@ -791,39 +799,13 @@ AM_CONDITIONAL([WITH_UNIT_TEST],
AM_CONDITIONAL([WITH_COMMAND_TEST],
[test "$ac_cv_ruby_available" = "yes"])
-# check Inkscape for generating PNG images
-inkscape_available="no"
-AC_ARG_WITH([inkscape],
- AS_HELP_STRING([--with-inkscape=PATH],
- [Inkscape path (default: auto)]),
- [INKSCAPE="$withval"],
- [INKSCAPE="yes"])
-
-if test "x$INKSCAPE" = "xno"; then
- INKSCAPE=
-else
- if test "x$INKSCAPE" = "xyes"; then
- AC_PATH_PROGS(INKSCAPE, [inkscape], none)
- if test "$INKSCAPE" != "none"; then
- inkscape_available="yes"
- fi
- else
- AC_CHECK_FILE([$INKSCAPE],
- [inkscape_available="yes"],
- [AC_MSG_WARN([$INKSCAPE is not found.
- Disable PNG image generation.])])
- fi
-fi
-AC_SUBST(INKSCAPE)
-AM_CONDITIONAL([WITH_INKSCAPE], [test "$inkscape_available" = "yes"])
-
# check Lemon for generating .c and .h files from .y file
lemon_available="no"
AC_ARG_WITH([lemon],
AS_HELP_STRING([--with-lemon=PATH],
[Lemon path (default: auto)]),
[LEMON="$withval"],
- [: ${LEMON:=auto}])
+ [: ${LEMON:=auto}])
if test "$LEMON" = "no"; then
LEMON=
@@ -842,8 +824,8 @@ else
fi
else
AC_CHECK_FILE([$LEMON],
- [lemon_available="yes"],
- [AC_MSG_WARN([$LEMON is not found. Disable .y compilation.])])
+ [lemon_available="yes"],
+ [AC_MSG_WARN([$LEMON is not found. Disable .y compilation.])])
fi
fi
AC_SUBST(LEMON)
@@ -925,6 +907,30 @@ if test "x$with_lz4" != "xno"; then
fi
fi
+# Zstandard
+AC_ARG_WITH(zstd,
+ [AS_HELP_STRING([--with-zstd],
+ [Support data compression by Zstandard. [default=auto]])],
+ [with_zstd="$withval"],
+ [with_zstd="auto"])
+if test "x$with_zstd" != "xno"; then
+ m4_ifdef([PKG_CHECK_MODULES], [
+ PKG_CHECK_MODULES([LIBZSTD],
+ [libzstd],
+ [GRN_WITH_ZSTD=yes],
+ [GRN_WITH_ZSTD=no])
+ ],
+ [GRN_WITH_ZSTD=no])
+ if test "$GRN_WITH_ZSTD" = "yes"; then
+ AC_DEFINE(GRN_WITH_ZSTD, [1],
+ [Support data compression by Zstandard.])
+ else
+ if test "x$with_zstd" != "xauto"; then
+ AC_MSG_ERROR("No libzstd found")
+ fi
+ fi
+fi
+
# jemalloc
AC_ARG_WITH(jemalloc,
[AS_HELP_STRING([--with-jemalloc],
@@ -941,8 +947,38 @@ if test "x$with_jemalloc" != "xno"; then
[AC_MSG_ERROR("No libjemalloc found")])
fi
+# Apache Arrow
+AC_ARG_ENABLE(arrow,
+ [AS_HELP_STRING([--disable-arrow],
+ [enable Apache Arrow support. [default=auto-detect]])],
+ [enable_arrow="$enableval"],
+ [enable_arrow="auto"])
+if test "x$enable_arrow" != "xno"; then
+ m4_ifdef([PKG_CHECK_MODULES], [
+ PKG_CHECK_MODULES([ARROW],
+ [arrow >= 0.5.0],
+ [arrow_available=yes],
+ [arrow_available=no])
+ ],
+ [arrow_available=no])
+ if test "x$arrow_available" = "xyes"; then
+ AC_DEFINE(GRN_WITH_ARROW, [1], [Enable Apache Arrow support.])
+ else
+ if test "x$enable_arrow" = "xyes"; then
+ AC_MSG_ERROR("No Apache Arrow found")
+ fi
+ fi
+fi
+AM_CONDITIONAL([GRN_WITH_ARROW], [test "$arrow_available" = "yes"])
+
# MeCab
# NOTE: MUST be checked last
+
+BUNDLED_MECAB_VERSION=m4_include([bundled_mecab_version])
+AC_SUBST(BUNDLED_MECAB_VERSION)
+BUNDLED_MECAB_NAIST_JDIC_VERSION=m4_include([bundled_mecab_naist_jdic_version])
+AC_SUBST(BUNDLED_MECAB_NAIST_JDIC_VERSION)
+
AC_ARG_WITH(mecab,
[AS_HELP_STRING([--with-mecab],
[use MeCab for morphological analysis. [default=yes]])],
@@ -1170,6 +1206,9 @@ AC_SUBST(LIBEVENT_CFLAGS)
AC_SUBST(LIBEVENT_LIBS)
# MessagePack
+BUNDLED_MESSAGE_PACK_VERSION=m4_include([bundled_message_pack_version])
+AC_SUBST(BUNDLED_MESSAGE_PACK_VERSION)
+
AC_ARG_ENABLE(message-pack,
[AS_HELP_STRING([--disable-message-pack],
[Disable MessagePack support. [default=auto-detect]])],
@@ -1203,7 +1242,7 @@ if test "x$enable_message_pack" != "xno"; then
if test "x$message_pack_available" = "xyes"; then
MESSAGE_PACK_CFLAGS="-I$with_message_pack/include"
- MESSAGE_PACK_LIBS="-L$with_message_pack/lib -lmsgpack"
+ MESSAGE_PACK_LIBS="-L$with_message_pack/lib -lmsgpackc"
fi
fi
@@ -1224,6 +1263,17 @@ AM_CONDITIONAL([ENABLE_SUGGEST_LEARNER],
"$libevent_available" = "yes" -a \
"$message_pack_available" = "yes"])
+# Check built-in atomic
+case "$host" in
+ i*86*|x86_64*)
+ ;;
+ *)
+ AC_MSG_CHECKING([for platform which requires libatomic])
+ AC_CHECK_LIB(atomic, __atomic_store_8, [ATOMIC_LIBS="-latomic"])
+ AC_SUBST(ATOMIC_LIBS)
+ ;;
+esac
+
# Document
AC_MSG_CHECKING([whether enable document])
AC_ARG_ENABLE(document,
@@ -1246,10 +1296,10 @@ if test x"$enable_document" != x"no"; then
AC_PATH_PROG(SPHINX_BUILD, sphinx-build, [])
if test -n "$SPHINX_BUILD"; then
sphinx_build_version=`"$SPHINX_BUILD" --version`
- if ! echo "$sphinx_build_version" | grep -q ' 1\.[[23]]'; then
- AC_MSG_ERROR([
+ if ! echo "$sphinx_build_version" | grep -q ' 1\.[[3-6]]'; then
+ AC_MSG_ERROR([
sphinx-build is old: $sphinx_build_version
-Sphinx 1.2 or later is required.])
+Sphinx 1.3 or later is required.])
fi
document_available=yes
document_buildable=yes
@@ -1281,8 +1331,8 @@ fi
AC_ARG_WITH([cutter-source-path],
AS_HELP_STRING([--with-cutter-source-path=PATH],
[Specify Cutter source path for
- groonga's release manager.]),
- [CUTTER_SOURCE_PATH="$withval"])
+ groonga's release manager.]),
+ [CUTTER_SOURCE_PATH="$withval"])
case "$CUTTER_SOURCE_PATH" in
""|/*)
: # do nothing
@@ -1330,15 +1380,29 @@ AC_MSG_CHECKING([whether package platform])
AC_ARG_WITH(package-platform,
[AS_HELP_STRING([--with-package-platform=PLATFORM],
[install package platform related files. [default=no]
- (supported package platforms: redhat, fedora)])],
+ (supported package platforms: centos, centos5, centos6, centos7, fedora)])],
[package_platform="$withval"],
[package_platform="no"])
+if test "$package_platform" = "centos"; then
+ distribution=$(cut -d " " -f 1 /etc/redhat-release | tr "A-Z" "a-z")
+ if grep -q Linux /etc/redhat-release; then
+ distribution_version=$(cut -d " " -f 4 /etc/redhat-release)
+ else
+ distribution_version=$(cut -d " " -f 3 /etc/redhat-release)
+ fi
+ distribution_version=$(echo ${distribution_version} | sed -e 's/\..*$//g')
+ package_platform="${package_platform}${distribution_version}"
+fi
AC_MSG_RESULT($package_platform)
-AM_CONDITIONAL([REDHAT_PLATFORM],
- [test "${package_platform}" = "redhat"])
-AM_CONDITIONAL([FEDORA_PLATFORM],
- [test "${package_platform}" = "fedora"])
+AM_CONDITIONAL([CENTOS_PLATFORM],
+ [test "${package_platform}" != "no"])
+AM_CONDITIONAL([CENTOS_INIT_PLATFORM],
+ [test "${package_platform}" = "centos5" ||
+ test "${package_platform}" = "centos6"])
+AM_CONDITIONAL([CENTOS_SYSTEMD_PLATFORM],
+ [test "${package_platform}" = "centos7" ||
+ test "${package_platform}" = "fedora"])
# plugins check
relative_pluginsdir_base="\$(PACKAGE)/plugins"
@@ -1354,18 +1418,15 @@ AC_SUBST(pluginsdir)
expanded_pluginsdir="\${libdir}/${expanded_relative_pluginsdir_base}"
AC_SUBST(expanded_pluginsdir)
-tokenizers_pluginsdir="\${pluginsdir}/tokenizers"
-AC_SUBST(tokenizers_pluginsdir)
+tokenizer_pluginsdir="\${pluginsdir}/tokenizers"
+AC_SUBST(tokenizer_pluginsdir)
-query_expanders_pluginsdir="\${pluginsdir}/query_expanders"
-AC_SUBST(query_expanders_pluginsdir)
+query_expander_pluginsdir="\${pluginsdir}/query_expanders"
+AC_SUBST(query_expander_pluginsdir)
suggest_pluginsdir="\${pluginsdir}/suggest"
AC_SUBST(suggest_pluginsdir)
-table_pluginsdir="\${pluginsdir}/table"
-AC_SUBST(table_pluginsdir)
-
ruby_pluginsdir="\${pluginsdir}/ruby"
AC_SUBST(ruby_pluginsdir)
@@ -1378,6 +1439,9 @@ AC_SUBST(sharding_pluginsdir)
function_pluginsdir="\${pluginsdir}/functions"
AC_SUBST(function_pluginsdir)
+expression_rewriter_pluginsdir="\${pluginsdir}/expression_rewriters"
+AC_SUBST(expression_rewriter_pluginsdir)
+
AC_MSG_CHECKING(for the suffix of plugin shared libraries)
shrext_cmds=$(./libtool --config | grep '^shrext_cmds=')
eval $shrext_cmds
@@ -1389,12 +1453,13 @@ fi
AC_DEFINE_UNQUOTED(GRN_PLUGIN_SUFFIX, ["$suffix"], "plugin suffix")
# for query expanders
-GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE="synonyms.tsv"
+GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE_BASE="synonyms.tsv"
+GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE="etc/${PACKAGE}/${GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE_BASE}"
AC_DEFINE_UNQUOTED(GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE,
["$GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE"],
"The relative synonyms file for TSV query expander")
GRN_QUERY_EXPANDER_TSV_SYNONYMS_PATH="`
- eval echo ${sysconfdir}/${PACKAGE}/${GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE}
+ eval echo ${sysconfdir}/${PACKAGE}/${GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE_BASE}
`"
AC_DEFINE_UNQUOTED(GRN_QUERY_EXPANDER_TSV_SYNONYMS_FILE,
["$GRN_QUERY_EXPANDER_TSV_SYNONYMS_PATH"],
@@ -1451,8 +1516,7 @@ AC_ARG_WITH(groonga-org-path,
AC_SUBST(GROONGA_ORG_PATH)
# groonga-httpd
-m4_define([nginx_version], m4_include(nginx_version))
-NGINX_VERSION=nginx_version
+NGINX_VERSION=m4_include([nginx_version])
AC_SUBST(NGINX_VERSION)
# groonga-httpd binary path
@@ -1472,6 +1536,12 @@ else
fi
AM_CONDITIONAL(WITH_GROONGA_HTTPD, test "$enable_groonga_httpd" = "yes")
+GROONGA_HTTPD_PID_PATH="`
+ test \"$prefix\" = NONE && prefix=/usr/local
+ eval echo ${localstatedir}/run/groonga/groonga-httpd.pid
+`"
+AC_SUBST(GROONGA_HTTPD_PID_PATH)
+
# mruby
AC_ARG_ENABLE(mruby,
[AS_HELP_STRING([--enable-mruby],
@@ -1492,12 +1562,17 @@ if test "$enable_mruby" = "yes"; then
fi
AC_DEFINE(GRN_WITH_MRUBY, [1], [Define to 1 if mruby is enabled.])
MRUBY_CFLAGS="-I\$(top_srcdir)/vendor/mruby-source/include"
+ GRN_WITH_MRUBY="yes"
else
MRUBY_CFLAGS=""
fi
+AC_SUBST(GRN_WITH_MRUBY)
AC_SUBST(MRUBY_CFLAGS)
AM_CONDITIONAL(WITH_MRUBY, test "$enable_mruby" = "yes")
+MRUBY_CPPFLAGS="-DMRB_INT64"
+AC_SUBST(MRUBY_CPPFLAGS)
+
# This option is used in vendor/onigmo/configure
AC_ARG_ENABLE(shared-onigmo,
[AS_HELP_STRING([--enable-shared-onigmo],
@@ -1506,16 +1581,37 @@ AC_ARG_ENABLE(shared-onigmo,
[enable_shared_onigmo="no"])
AM_CONDITIONAL(WITH_SHARED_ONIGMO, test "$enable_shared_onigmo" = "yes")
-# TODO: Support using system Onigmo instead of bundled Onigmo.
-AC_DEFINE(GRN_WITH_ONIGMO, [1], [Use Onigmo.])
-GRN_WITH_ONIGMO="yes"
+AC_ARG_WITH(onigmo,
+ [AS_HELP_STRING([--without-onigmo],
+ [Don't Use Onigmo. [default=bundled]])],
+ [with_onigmo="$withval"],
+ [with_onigmo="bundled"])
+if test "x$with_onigmo" != "xno"; then
+ GRN_WITH_ONIGMO="yes"
+ if test "x$with_onigmo" != "xbundled"; then
+ m4_ifdef([PKG_CHECK_MODULES], [
+ PKG_CHECK_MODULES([ONIGMO], [onigmo],
+ [have_onigmo=yes],
+ [have_onigmo=no])
+ ],
+ [have_onigmo=no])
+ fi
+ if test "x$with_onigmo" = "xsystem" -a "$have_onigmo" = "no"; then
+ AC_MSG_ERROR("No Onigmo found")
+ fi
+ if test "x$with_onigmo" = "xbundled" -o "$have_onigmo" = "no"; then
+ AC_CONFIG_SUBDIRS([vendor/onigmo])
+ ONIGMO_CFLAGS="-I\$(top_srcdir)/vendor/onigmo-source"
+ ONIGMO_LIBS="\$(top_builddir)/vendor/onigmo-source/libonigmo.la"
+ fi
+ AC_DEFINE(GRN_WITH_ONIGMO, [1], [Use Onigmo.])
+else
+ GRN_WITH_ONIGMO="no"
+fi
AC_SUBST(GRN_WITH_ONIGMO)
-AC_CONFIG_SUBDIRS([vendor/onigmo])
-
-ONIGMO_CFLAGS="-I\$(top_srcdir)/vendor/onigmo-source"
-ONIGMO_LIBS="\$(top_builddir)/vendor/onigmo-source/libonig.la"
AC_SUBST(ONIGMO_CFLAGS)
AC_SUBST(ONIGMO_LIBS)
+AM_CONDITIONAL(WITH_BUNDLED_ONIGMO, test "$with_onigmo" != "no" -a "x$have_onigmo" != "xyes")
# PCRE
GRN_WITH_PCRE=no
@@ -1541,6 +1637,30 @@ AC_SUBST(GRN_WITH_PCRE)
AC_SUBST(PCRE_CFLAGS)
AC_SUBST(PCRE_LIBS_ONLY_L)
+# SSL
+GRN_WITH_SSL=no
+AC_ARG_WITH(ssl,
+ [AS_HELP_STRING([--without-ssl],
+ [Don't use SSL module for groonga-httpd. [default=auto-detect]])],
+ [with_ssl="$withval"],
+ [with_ssl="auto"])
+if test "x$with_ssl" != "xno"; then
+ m4_ifdef([PKG_CHECK_MODULES], [
+ PKG_CHECK_MODULES([SSL], [libssl],
+ [_PKG_CONFIG(SSL_LIBS_ONLY_L, [libs-only-L], [libssl])
+ SSL_LIBS_ONLY_L="$pkg_cv_SSL_LIBS_ONLY_L"
+ GRN_WITH_SSL=yes],
+ [GRN_WITH_SSL=no])
+ ],
+ [GRN_WITH_SSL=no])
+ if test "x$with_ssl" = "xyes" -a "$GRN_WITH_SSL" != "yes"; then
+ AC_MSG_ERROR("No SSL found")
+ fi
+fi
+AC_SUBST(GRN_WITH_SSL)
+AC_SUBST(SSL_CFLAGS)
+AC_SUBST(SSL_LIBS_ONLY_L)
+
# For package
AC_ARG_WITH(rsync-path,
[AS_HELP_STRING([--with-rsync-path=PATH],
@@ -1549,6 +1669,13 @@ AC_ARG_WITH(rsync-path,
[RSYNC_PATH="packages@packages.groonga.org:public"])
AC_SUBST(RSYNC_PATH)
+AC_ARG_WITH(launchpad-ppa,
+ [AS_HELP_STRING([--with-launchpad-ppa=PPA],
+ [specify Launchpad Personal Package Archive. [default=groonga-ppa]])],
+ [LAUNCHPAD_PPA="$withval"],
+ [LAUNCHPAD_PPA="groonga-ppa"])
+AC_SUBST(LAUNCHPAD_PPA)
+
AC_ARG_WITH(launchpad-uploader-pgp-key,
[AS_HELP_STRING([--with-launchpad-uploader-pgp-key=KEY],
[specify PGP key UID to upload Groonga packages to Launchpad.])],
@@ -1582,15 +1709,19 @@ GROONGA_HTTPD_DEFAULT_DATABASE_PATH="`
AC_SUBST(GROONGA_HTTPD_DEFAULT_DATABASE_PATH)
AC_OUTPUT([
+ lib/metadata.rc
packages/rpm/centos/groonga.spec
packages/apt/debian/groonga-keyring.postrm
packages/apt/env.sh
packages/yum/env.sh
groonga.pc
+ groonga-arrow.pc
config.sh
groonga-httpd-conf.sh
data/groonga-httpd.conf
+ data/logrotate.d/centos/groonga-httpd
data/scripts/groonga-httpd-restart
+ data/systemd/centos/groonga-httpd.service
])
echo "$PACKAGE_NAME $PACKAGE_VERSION configuration:"
@@ -1657,11 +1788,16 @@ echo "groonga-httpd:"
echo " enable: $enable_groonga_httpd"
if test "$enable_groonga_httpd" = "yes"; then
echo " default database path: $GROONGA_HTTPD_DEFAULT_DATABASE_PATH"
- echo " PCRE: $WITH_PCRE"
- if test "$WITH_PCRE" = "yes"; then
+ echo " PCRE: $GRN_WITH_PCRE"
+ if test "$GRN_WITH_PCRE" = "yes"; then
echo " CFLAGS: $PCRE_CFLAGS"
echo " LIBS only -L: $PCRE_LIBS_ONLY_L"
fi
+ echo " SSL: $GRN_WITH_SSL"
+ if test "$GRN_WITH_SSL" = "yes"; then
+ echo " CFLAGS: $SSL_CFLAGS"
+ echo " LIBS only -L: $SSL_LIBS_ONLY_L"
+ fi
fi
echo
diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict-import.sh b/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict-import.sh
index b98397be05a..e48700af07b 100755
--- a/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict-import.sh
+++ b/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict-import.sh
@@ -16,6 +16,12 @@ else
edict_gz=$2
fi
-if zcat $edict_gz | ${base_dir}/edict2grn.rb | groonga $1 > /dev/null; then
+if type gzcat > /dev/null 2>&1; then
+ zcat="gzcat"
+else
+ zcat="zcat"
+fi
+
+if $zcat $edict_gz | ${base_dir}/edict2grn.rb | groonga $1 > /dev/null; then
echo "edict data loaded."
fi
diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/index.html b/storage/mroonga/vendor/groonga/examples/dictionary/html/index.html
index aaad128a290..47e81754094 100644
--- a/storage/mroonga/vendor/groonga/examples/dictionary/html/index.html
+++ b/storage/mroonga/vendor/groonga/examples/dictionary/html/index.html
@@ -16,7 +16,7 @@
<input type="submit" value="検索"/>
</form>
<script type="text/javascript" src="js/jquery-1.7.2.js"></script>
-<script type="text/javascript" src="js/jquery-ui-1.8.18.custom.min.js"></script>
+<script type="text/javascript" src="js/jquery-ui-1.8.18.custom.js"></script>
<script type="text/javascript" src="js/dictionary.js"></script>
<script type="text/javascript">
$(document).ready(function(){
diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-ui-1.8.18.custom.min.js b/storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-ui-1.8.18.custom.min.js
deleted file mode 100644
index f00a62f133f..00000000000
--- a/storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-ui-1.8.18.custom.min.js
+++ /dev/null
@@ -1,356 +0,0 @@
-/*!
- * jQuery UI 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI
- */(function(a,b){function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;if(!b.href||!g||f.nodeName.toLowerCase()!=="map")return!1;h=a("img[usemap=#"+g+"]")[0];return!!h&&d(h)}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}a.ui=a.ui||{};a.ui.version||(a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.each(["Width","Height"],function(c,d){function h(b,c,d,f){a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)});return c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){if(c===b)return g["inner"+d].call(this);return this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){if(typeof b!="number")return g["outer"+d].call(this,b);return this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));c.offsetHeight,a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!!d&&!!a.element[0].parentNode)for(var e=0;e<d.length;e++)a.options[d[e][0]]&&d[e][1].apply(a.element,c)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(b,c){if(a(b).css("overflow")==="hidden")return!1;var d=c&&c==="left"?"scrollLeft":"scrollTop",e=!1;if(b[d]>0)return!0;b[d]=1,e=b[d]>0,b[d]=0;return e},isOverAxis:function(a,b,c){return a>b&&a<b+c},isOver:function(b,c,d,e,f,g){return a.ui.isOverAxis(b,d,f)&&a.ui.isOverAxis(c,e,g)}}))})(jQuery);/*!
- * jQuery UI Widget 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Widget
- */(function(a,b){if(a.cleanData){var c=a.cleanData;a.cleanData=function(b){for(var d=0,e;(e=b[d])!=null;d++)try{a(e).triggerHandler("remove")}catch(f){}c(b)}}else{var d=a.fn.remove;a.fn.remove=function(b,c){return this.each(function(){c||(!b||a.filter(b,[this]).length)&&a("*",this).add([this]).each(function(){try{a(this).triggerHandler("remove")}catch(b){}});return d.call(a(this),b,c)})}}a.widget=function(b,c,d){var e=b.split(".")[0],f;b=b.split(".")[1],f=e+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][f]=function(c){return!!a.data(c,b)},a[e]=a[e]||{},a[e][b]=function(a,b){arguments.length&&this._createWidget(a,b)};var g=new c;g.options=a.extend(!0,{},g.options),a[e][b].prototype=a.extend(!0,g,{namespace:e,widgetName:b,widgetEventPrefix:a[e][b].prototype.widgetEventPrefix||b,widgetBaseClass:f},d),a.widget.bridge(b,a[e][b])},a.widget.bridge=function(c,d){a.fn[c]=function(e){var f=typeof e=="string",g=Array.prototype.slice.call(arguments,1),h=this;e=!f&&g.length?a.extend.apply(null,[!0,e].concat(g)):e;if(f&&e.charAt(0)==="_")return h;f?this.each(function(){var d=a.data(this,c),f=d&&a.isFunction(d[e])?d[e].apply(d,g):d;if(f!==d&&f!==b){h=f;return!1}}):this.each(function(){var b=a.data(this,c);b?b.option(e||{})._init():a.data(this,c,new d(e,this))});return h}},a.Widget=function(a,b){arguments.length&&this._createWidget(a,b)},a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:!1},_createWidget:function(b,c){a.data(c,this.widgetName,this),this.element=a(c),this.options=a.extend(!0,{},this.options,this._getCreateOptions(),b);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()}),this._create(),this._trigger("create"),this._init()},_getCreateOptions:function(){return a.metadata&&a.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName),this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled "+"ui-state-disabled")},widget:function(){return this.element},option:function(c,d){var e=c;if(arguments.length===0)return a.extend({},this.options);if(typeof c=="string"){if(d===b)return this.options[c];e={},e[c]=d}this._setOptions(e);return this},_setOptions:function(b){var c=this;a.each(b,function(a,b){c._setOption(a,b)});return this},_setOption:function(a,b){this.options[a]=b,a==="disabled"&&this.widget()[b?"addClass":"removeClass"](this.widgetBaseClass+"-disabled"+" "+"ui-state-disabled").attr("aria-disabled",b);return this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_trigger:function(b,c,d){var e,f,g=this.options[b];d=d||{},c=a.Event(c),c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase(),c.target=this.element[0],f=c.originalEvent;if(f)for(e in f)e in c||(c[e]=f[e]);this.element.trigger(c,d);return!(a.isFunction(g)&&g.call(this.element[0],c,d)===!1||c.isDefaultPrevented())}}})(jQuery);/*!
- * jQuery UI Mouse 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Mouse
- *
- * Depends:
- * jquery.ui.widget.js
- */(function(a,b){var c=!1;a(document).mouseup(function(a){c=!1}),a.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var b=this;this.element.bind("mousedown."+this.widgetName,function(a){return b._mouseDown(a)}).bind("click."+this.widgetName,function(c){if(!0===a.data(c.target,b.widgetName+".preventClickEvent")){a.removeData(c.target,b.widgetName+".preventClickEvent"),c.stopImmediatePropagation();return!1}}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(b){if(!c){this._mouseStarted&&this._mouseUp(b),this._mouseDownEvent=b;var d=this,e=b.which==1,f=typeof this.options.cancel=="string"&&b.target.nodeName?a(b.target).closest(this.options.cancel).length:!1;if(!e||f||!this._mouseCapture(b))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){d.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)){this._mouseStarted=this._mouseStart(b)!==!1;if(!this._mouseStarted){b.preventDefault();return!0}}!0===a.data(b.target,this.widgetName+".preventClickEvent")&&a.removeData(b.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(a){return d._mouseMove(a)},this._mouseUpDelegate=function(a){return d._mouseUp(a)},a(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),b.preventDefault(),c=!0;return!0}},_mouseMove:function(b){if(a.browser.msie&&!(document.documentMode>=9)&&!b.button)return this._mouseUp(b);if(this._mouseStarted){this._mouseDrag(b);return b.preventDefault()}this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b));return!this._mouseStarted},_mouseUp:function(b){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b));return!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})})(jQuery);/*
- * jQuery UI Position 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Position
- */(function(a,b){a.ui=a.ui||{};var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1];return this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]!==e){var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0}},top:function(b,c){if(c.at[1]!==e){var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];if(!c||!c.ownerDocument)return null;if(b)return this.each(function(){a.offset.setOffset(this,b)});return h.call(this)}),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&a.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()})(jQuery);/*
- * jQuery UI Draggable 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Draggables
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.mouse.js
- * jquery.ui.widget.js
- */(function(a,b){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},destroy:function(){if(!!this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy();return this}},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle"))return!1;this.handle=this._getHandle(b);if(!this.handle)return!1;c.iframeFix&&a(c.iframeFix===!0?"iframe":c.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(a(this).offset()).appendTo("body")});return!0},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),c.containment&&this._setContainment();if(this._trigger("start",b)===!1){this._clear();return!1}this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.helper.addClass("ui-draggable-dragging"),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b);return!0},_mouseDrag:function(b,c){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute");if(!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1){this._mouseUp({});return!1}this.position=d.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";a.ui.ddmanager&&a.ui.ddmanager.drag(this,b);return!1},_mouseStop:function(b){var c=!1;a.ui.ddmanager&&!this.options.dropBehaviour&&(c=a.ui.ddmanager.drop(this,b)),this.dropped&&(c=this.dropped,this.dropped=!1);if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return!1;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var d=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){d._trigger("stop",b)!==!1&&d._clear()})}else this._trigger("stop",b)!==!1&&this._clear();return!1},_mouseUp:function(b){this.options.iframeFix===!0&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b);return a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?!0:!1;a(this.options.handle,this.element).find("*").andSelf().each(function(){this==b.target&&(c=!0)});return c},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo),d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&d.css("position","absolute");return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[b.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,b.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(b.containment=="document"?0:a(window).scrollLeft())+a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(b.containment=="document"?0:a(window).scrollTop())+(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)&&b.containment.constructor!=Array){var c=a(b.containment),d=c[0];if(!d)return;var e=c.offset(),f=a(d).css("overflow")!="hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(f?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(f?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"),10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c}else b.containment.constructor==Array&&(this.containment=b.containment)},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName),f=b.pageX,g=b.pageY;if(this.originalPosition){var h;if(this.containment){if(this.relative_container){var i=this.relative_container.offset();h=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]}else h=this.containment;b.pageX-this.offset.click.left<h[0]&&(f=h[0]+this.offset.click.left),b.pageY-this.offset.click.top<h[1]&&(g=h[1]+this.offset.click.top),b.pageX-this.offset.click.left>h[2]&&(f=h[2]+this.offset.click.left),b.pageY-this.offset.click.top>h[3]&&(g=h[3]+this.offset.click.top)}if(c.grid){var j=c.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;g=h?j-this.offset.click.top<h[1]||j-this.offset.click.top>h[3]?j-this.offset.click.top<h[1]?j+c.grid[1]:j-c.grid[1]:j:j;var k=c.grid[0]?this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0]:this.originalPageX;f=h?k-this.offset.click.left<h[0]||k-this.offset.click.left>h[2]?k-this.offset.click.left<h[0]?k+c.grid[0]:k-c.grid[0]:k:k}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(b,c,d){d=d||this._uiHash(),a.ui.plugin.call(this,b,[c,d]),b=="drag"&&(this.positionAbs=this._convertPositionTo("absolute"));return a.Widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(a){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),a.extend(a.ui.draggable,{version:"1.8.18"}),a.ui.plugin.add("draggable","connectToSortable",{start:function(b,c){var d=a(this).data("draggable"),e=d.options,f=a.extend({},c,{item:d.element});d.sortables=[],a(e.connectToSortable).each(function(){var c=a.data(this,"sortable");c&&!c.options.disabled&&(d.sortables.push({instance:c,shouldRevert:c.options.revert}),c.refreshPositions(),c._trigger("activate",b,f))})},stop:function(b,c){var d=a(this).data("draggable"),e=a.extend({},c,{item:d.element});a.each(d.sortables,function(){this.instance.isOver?(this.instance.isOver=0,d.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(b),this.instance.options.helper=this.instance.options._helper,d.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",b,e))})},drag:function(b,c){var d=a(this).data("draggable"),e=this,f=function(b){var c=this.offset.click.top,d=this.offset.click.left,e=this.positionAbs.top,f=this.positionAbs.left,g=b.height,h=b.width,i=b.top,j=b.left;return a.ui.isOver(e+c,f+d,i,j,g,h)};a.each(d.sortables,function(f){this.instance.positionAbs=d.positionAbs,this.instance.helperProportions=d.helperProportions,this.instance.offset.click=d.offset.click,this.instance._intersectsWith(this.instance.containerCache)?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=a(e).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return c.helper[0]},b.target=this.instance.currentItem[0],this.instance._mouseCapture(b,!0),this.instance._mouseStart(b,!0,!0),this.instance.offset.click.top=d.offset.click.top,this.instance.offset.click.left=d.offset.click.left,this.instance.offset.parent.left-=d.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=d.offset.parent.top-this.instance.offset.parent.top,d._trigger("toSortable",b),d.dropped=this.instance.element,d.currentItem=d.element,this.instance.fromOutside=d),this.instance.currentItem&&this.instance._mouseDrag(b)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",b,this.instance._uiHash(this.instance)),this.instance._mouseStop(b,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),d._trigger("fromSortable",b),d.dropped=!1)})}}),a.ui.plugin.add("draggable","cursor",{start:function(b,c){var d=a("body"),e=a(this).data("draggable").options;d.css("cursor")&&(e._cursor=d.css("cursor")),d.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;d._cursor&&a("body").css("cursor",d._cursor)}}),a.ui.plugin.add("draggable","opacity",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("opacity")&&(e._opacity=d.css("opacity")),d.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;d._opacity&&a(c.helper).css("opacity",d._opacity)}}),a.ui.plugin.add("draggable","scroll",{start:function(b,c){var d=a(this).data("draggable");d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"&&(d.overflowOffset=d.scrollParent.offset())},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=!1;if(d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"){if(!e.axis||e.axis!="x")d.overflowOffset.top+d.scrollParent[0].offsetHeight-b.pageY<e.scrollSensitivity?d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop+e.scrollSpeed:b.pageY-d.overflowOffset.top<e.scrollSensitivity&&(d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop-e.scrollSpeed);if(!e.axis||e.axis!="y")d.overflowOffset.left+d.scrollParent[0].offsetWidth-b.pageX<e.scrollSensitivity?d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft+e.scrollSpeed:b.pageX-d.overflowOffset.left<e.scrollSensitivity&&(d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft-e.scrollSpeed)}else{if(!e.axis||e.axis!="x")b.pageY-a(document).scrollTop()<e.scrollSensitivity?f=a(document).scrollTop(a(document).scrollTop()-e.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<e.scrollSensitivity&&(f=a(document).scrollTop(a(document).scrollTop()+e.scrollSpeed));if(!e.axis||e.axis!="y")b.pageX-a(document).scrollLeft()<e.scrollSensitivity?f=a(document).scrollLeft(a(document).scrollLeft()-e.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<e.scrollSensitivity&&(f=a(document).scrollLeft(a(document).scrollLeft()+e.scrollSpeed))}f!==!1&&a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(d,b)}}),a.ui.plugin.add("draggable","snap",{start:function(b,c){var d=a(this).data("draggable"),e=d.options;d.snapElements=[],a(e.snap.constructor!=String?e.snap.items||":data(draggable)":e.snap).each(function(){var b=a(this),c=b.offset();this!=d.element[0]&&d.snapElements.push({item:this,width:b.outerWidth(),height:b.outerHeight(),top:c.top,left:c.left})})},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=e.snapTolerance,g=c.offset.left,h=g+d.helperProportions.width,i=c.offset.top,j=i+d.helperProportions.height;for(var k=d.snapElements.length-1;k>=0;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,n=d.snapElements[k].top,o=n+d.snapElements[k].height;if(!(l-f<g&&g<m+f&&n-f<i&&i<o+f||l-f<g&&g<m+f&&n-f<j&&j<o+f||l-f<h&&h<m+f&&n-f<i&&i<o+f||l-f<h&&h<m+f&&n-f<j&&j<o+f)){d.snapElements[k].snapping&&d.options.snap.release&&d.options.snap.release.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=!1;continue}if(e.snapMode!="inner"){var p=Math.abs(n-j)<=f,q=Math.abs(o-i)<=f,r=Math.abs(l-h)<=f,s=Math.abs(m-g)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n-d.helperProportions.height,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l-d.helperProportions.width}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m}).left-d.margins.left)}var t=p||q||r||s;if(e.snapMode!="outer"){var p=Math.abs(n-i)<=f,q=Math.abs(o-j)<=f,r=Math.abs(l-g)<=f,s=Math.abs(m-h)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o-d.helperProportions.height,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m-d.helperProportions.width}).left-d.margins.left)}!d.snapElements[k].snapping&&(p||q||r||s||t)&&d.options.snap.snap&&d.options.snap.snap.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=p||q||r||s||t}}}),a.ui.plugin.add("draggable","stack",{start:function(b,c){var d=a(this).data("draggable").options,e=a.makeArray(a(d.stack)).sort(function(b,c){return(parseInt(a(b).css("zIndex"),10)||0)-(parseInt(a(c).css("zIndex"),10)||0)});if(!!e.length){var f=parseInt(e[0].style.zIndex)||0;a(e).each(function(a){this.style.zIndex=f+a}),this[0].style.zIndex=f+e.length}}}),a.ui.plugin.add("draggable","zIndex",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("zIndex")&&(e._zIndex=d.css("zIndex")),d.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;d._zIndex&&a(c.helper).css("zIndex",d._zIndex)}})})(jQuery);/*
- * jQuery UI Droppable 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Droppables
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.widget.js
- * jquery.ui.mouse.js
- * jquery.ui.draggable.js
- */(function(a,b){a.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var b=this.options,c=b.accept;this.isover=0,this.isout=1,this.accept=a.isFunction(c)?c:function(a){return a.is(c)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},a.ui.ddmanager.droppables[b.scope]=a.ui.ddmanager.droppables[b.scope]||[],a.ui.ddmanager.droppables[b.scope].push(this),b.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){var b=a.ui.ddmanager.droppables[this.options.scope];for(var c=0;c<b.length;c++)b[c]==this&&b.splice(c,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(b,c){b=="accept"&&(this.accept=a.isFunction(c)?c:function(a){return a.is(c)}),a.Widget.prototype._setOption.apply(this,arguments)},_activate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),c&&this._trigger("activate",b,this.ui(c))},_deactivate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),c&&this._trigger("deactivate",b,this.ui(c))},_over:function(b){var c=a.ui.ddmanager.current;!!c&&(c.currentItem||c.element)[0]!=this.element[0]&&this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",b,this.ui(c)))},_out:function(b){var c=a.ui.ddmanager.current;!!c&&(c.currentItem||c.element)[0]!=this.element[0]&&this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",b,this.ui(c)))},_drop:function(b,c){var d=c||a.ui.ddmanager.current;if(!d||(d.currentItem||d.element)[0]==this.element[0])return!1;var e=!1;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var b=a.data(this,"droppable");if(b.options.greedy&&!b.options.disabled&&b.options.scope==d.options.scope&&b.accept.call(b.element[0],d.currentItem||d.element)&&a.ui.intersect(d,a.extend(b,{offset:b.element.offset()}),b.options.tolerance)){e=!0;return!1}});if(e)return!1;if(this.accept.call(this.element[0],d.currentItem||d.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",b,this.ui(d));return this.element}return!1},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}}),a.extend(a.ui.droppable,{version:"1.8.18"}),a.ui.intersect=function(b,c,d){if(!c.offset)return!1;var e=(b.positionAbs||b.position.absolute).left,f=e+b.helperProportions.width,g=(b.positionAbs||b.position.absolute).top,h=g+b.helperProportions.height,i=c.offset.left,j=i+c.proportions.width,k=c.offset.top,l=k+c.proportions.height;switch(d){case"fit":return i<=e&&f<=j&&k<=g&&h<=l;case"intersect":return i<e+b.helperProportions.width/2&&f-b.helperProportions.width/2<j&&k<g+b.helperProportions.height/2&&h-b.helperProportions.height/2<l;case"pointer":var m=(b.positionAbs||b.position.absolute).left+(b.clickOffset||b.offset.click).left,n=(b.positionAbs||b.position.absolute).top+(b.clickOffset||b.offset.click).top,o=a.ui.isOver(n,m,k,i,c.proportions.height,c.proportions.width);return o;case"touch":return(g>=k&&g<=l||h>=k&&h<=l||g<k&&h>l)&&(e>=i&&e<=j||f>=i&&f<=j||e<i&&f>j);default:return!1}},a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d=a.ui.ddmanager.droppables[b.options.scope]||[],e=c?c.type:null,f=(b.currentItem||b.element).find(":data(droppable)").andSelf();droppablesLoop:for(var g=0;g<d.length;g++){if(d[g].options.disabled||b&&!d[g].accept.call(d[g].element[0],b.currentItem||b.element))continue;for(var h=0;h<f.length;h++)if(f[h]==d[g].element[0]){d[g].proportions.height=0;continue droppablesLoop}d[g].visible=d[g].element.css("display")!="none";if(!d[g].visible)continue;e=="mousedown"&&d[g]._activate.call(d[g],c),d[g].offset=d[g].element.offset(),d[g].proportions={width:d[g].element[0].offsetWidth,height:d[g].element[0].offsetHeight}}},drop:function(b,c){var d=!1;a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){!this.options||(!this.options.disabled&&this.visible&&a.ui.intersect(b,this,this.options.tolerance)&&(d=this._drop.call(this,c)||d),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],b.currentItem||b.element)&&(this.isout=1,this.isover=0,this._deactivate.call(this,c)))});return d},dragStart:function(b,c){b.element.parents(":not(body,html)").bind("scroll.droppable",function(){b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)})},drag:function(b,c){b.options.refreshPositions&&a.ui.ddmanager.prepareOffsets(b,c),a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var d=a.ui.intersect(b,this,this.options.tolerance),e=!d&&this.isover==1?"isout":d&&this.isover==0?"isover":null;if(!e)return;var f;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");g.length&&(f=a.data(g[0],"droppable"),f.greedyChild=e=="isover"?1:0)}f&&e=="isover"&&(f.isover=0,f.isout=1,f._out.call(f,c)),this[e]=1,this[e=="isout"?"isover":"isout"]=0,this[e=="isover"?"_over":"_out"].call(this,c),f&&e=="isout"&&(f.isout=0,f.isover=1,f._over.call(f,c))}})},dragStop:function(b,c){b.element.parents(":not(body,html)").unbind("scroll.droppable"),b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)}}})(jQuery);/*
- * jQuery UI Resizable 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Resizables
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.mouse.js
- * jquery.ui.widget.js
- */(function(a,b){a.widget("ui.resizable",a.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var b=this,c=this.options;this.element.addClass("ui-resizable"),a.extend(this,{_aspectRatio:!!c.aspectRatio,aspectRatio:c.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:c.helper||c.ghost||c.animate?c.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(a('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e<d.length;e++){var f=a.trim(d[e]),g="ui-resizable-"+f,h=a('<div class="ui-resizable-handle '+g+'"></div>');/sw|se|ne|nw/.test(f)&&h.css({zIndex:++c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){c.disabled||(a(this).removeClass("ui-resizable-autohide"),b._handles.show())},function(){c.disabled||b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement);return this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b);return!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui());return!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove();return!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),e<h.maxWidth&&(h.maxWidth=e),g<h.maxHeight&&(h.maxHeight=g);this._vBoundaries=h},_updateCache:function(a){var b=this.options;this.offset=this.helper.offset(),d(a.left)&&(this.position.left=a.left),d(a.top)&&(this.position.top=a.top),d(a.height)&&(this.size.height=a.height),d(a.width)&&(this.size.width=a.width)},_updateRatio:function(a,b){var c=this.options,e=this.position,f=this.size,g=this.axis;d(a.height)?a.width=a.height*this.aspectRatio:d(a.width)&&(a.height=a.width/this.aspectRatio),g=="sw"&&(a.left=e.left+(f.width-a.width),a.top=null),g=="nw"&&(a.top=e.top+(f.height-a.height),a.left=e.left+(f.width-a.width));return a},_respectSize:function(a,b){var c=this.helper,e=this._vBoundaries,f=this._aspectRatio||b.shiftKey,g=this.axis,h=d(a.width)&&e.maxWidth&&e.maxWidth<a.width,i=d(a.height)&&e.maxHeight&&e.maxHeight<a.height,j=d(a.width)&&e.minWidth&&e.minWidth>a.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null);return a},_proportionallyResize:function(){var b=this.options;if(!!this._proportionallyResizeElements.length){var c=this.helper||this.element;for(var d=0;d<this._proportionallyResizeElements.length;d++){var e=this._proportionallyResizeElements[d];if(!this.borderDif){var f=[e.css("borderTopWidth"),e.css("borderRightWidth"),e.css("borderBottomWidth"),e.css("borderLeftWidth")],g=[e.css("paddingTop"),e.css("paddingRight"),e.css("paddingBottom"),e.css("paddingLeft")];this.borderDif=a.map(f,function(a,b){var c=parseInt(a,10)||0,d=parseInt(g[b],10)||0;return c+d})}if(a.browser.msie&&(!!a(c).is(":hidden")||!!a(c).parents(":hidden").length))continue;e.css({height:c.height()-this.borderDif[0]-this.borderDif[2]||0,width:c.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var b=this.element,c=this.options;this.elementOffset=b.offset();if(this._helper){this.helper=this.helper||a('<div style="overflow:hidden;"></div>');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.18"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10)})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,d){a(b).each(function(){var b=a(this),e=a(this).data("resizable-alsoresize"),f={},g=d&&d.length?d:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(g,function(a,b){var c=(e[b]||0)+(h[b]||0);c&&c>=0&&(f[b]=c||null)}),b.css(f)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!!i){e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/e.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*e.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery);/*
- * jQuery UI Selectable 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Selectables
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.mouse.js
- * jquery.ui.widget.js
- */(function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy();return this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(!this.options.disabled){var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element});return!1}})}},_mouseDrag:function(b){var c=this;this.dragged=!0;if(!this.options.disabled){var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!!i&&i.element!=c.element[0]){var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.right<e||i.top>h||i.bottom<f):d.tolerance=="fit"&&(j=i.left>e&&i.right<g&&i.top>f&&i.bottom<h),j?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,c._trigger("selecting",b,{selecting:i.element}))):(i.selecting&&((b.metaKey||b.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),c._trigger("unselecting",b,{unselecting:i.element}))),i.selected&&!b.metaKey&&!b.ctrlKey&&!i.startselected&&(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,c._trigger("unselecting",b,{unselecting:i.element})))}});return!1}},_mouseStop:function(b){var c=this;this.dragged=!1;var d=this.options;a(".ui-unselecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-unselecting"),d.unselecting=!1,d.startselected=!1,c._trigger("unselected",b,{unselected:d.element})}),a(".ui-selecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected"),d.selecting=!1,d.selected=!0,d.startselected=!0,c._trigger("selected",b,{selected:d.element})}),this._trigger("stop",b),this.helper.remove();return!1}}),a.extend(a.ui.selectable,{version:"1.8.18"})})(jQuery);/*
- * jQuery UI Sortable 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Sortables
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.mouse.js
- * jquery.ui.widget.js
- */(function(a,b){a.widget("ui.sortable",a.ui.mouse,{widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},destroy:function(){a.Widget.prototype.destroy.call(this),this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--)this.items[b].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f){e=a(this);return!1}});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}this.currentItem=e,this._removeCurrentsFromItems();return!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b);return!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY<c.scrollSensitivity?this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop+c.scrollSpeed:b.pageY-this.overflowOffset.top<c.scrollSensitivity&&(this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop-c.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-b.pageX<c.scrollSensitivity?this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft+c.scrollSpeed:b.pageX-this.overflowOffset.left<c.scrollSensitivity&&(this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft-c.scrollSpeed)):(b.pageY-a(document).scrollTop()<c.scrollSensitivity?d=a(document).scrollTop(a(document).scrollTop()-c.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<c.scrollSensitivity&&(d=a(document).scrollTop(a(document).scrollTop()+c.scrollSpeed)),b.pageX-a(document).scrollLeft()<c.scrollSensitivity?d=a(document).scrollLeft(a(document).scrollLeft()-c.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<c.scrollSensitivity&&(d=a(document).scrollLeft(a(document).scrollLeft()+c.scrollSpeed))),d!==!1&&a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(var e=this.items.length-1;e>=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs;return!1},_mouseStop:function(b,c){if(!!b){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1}},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem));return this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"=");return d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")});return d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+j<i&&b+k>f&&b+k<g;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?l:f<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<g&&h<d+this.helperProportions.height/2&&e-this.helperProportions.height/2<i},_intersectsWithPointer:function(b){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top,b.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left,b.width),e=c&&d,f=this._getDragVerticalDirection(),g=this._getDragHorizontalDirection();if(!e)return!1;return this.floating?g&&g=="right"||f=="down"?2:1:f&&(f=="down"?2:1)},_intersectsWithSides:function(b){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top+b.height/2,b.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left+b.width/2,b.width),e=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();return this.floating&&f?f=="right"&&d||f=="left"&&!d:e&&(e=="down"&&c||e=="up"&&!c)},_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a),this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(b){this.items=[],this.containers=[this];var c=this.items,d=this,e=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],b,{item:this.currentItem}):a(this.options.items,this.element),this]],f=this._connectWith();if(f&&this.ready)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i<m;i++){var n=a(l[i]);n.data(this.widgetName+"-item",k),c.push({item:n,instance:k,width:0,height:0,left:0,top:0})}}},refreshPositions:function(b){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var c=this.items.length-1;c>=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];e||(b.style.visibility="hidden");return b},update:function(a,b){if(!e||!!d.forcePlaceholderSize)b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!!c)if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.items[i][this.containers[d].floating?"left":"top"];Math.abs(j-h)<f&&(f=Math.abs(j-h),g=this.items[i])}if(!g&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[d],g?this._rearrange(b,g,null,!0):this._rearrange(b,null,this.containers[d].element,!0),this._trigger("change",b,this._uiHash()),this.containers[d]._trigger("change",b,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1}},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b,this.currentItem])):c.helper=="clone"?this.currentItem.clone():this.currentItem;d.parents("body").length||a(c.appendTo!="parent"?c.appendTo:this.currentItem[0].parentNode)[0].appendChild(d[0]),d[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(d[0].style.width==""||c.forceHelperSize)&&d.width(this.currentItem.width()),(d[0].style.height==""||c.forceHelperSize)&&d.height(this.currentItem.height());return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)){var c=a(b.containment)[0],d=a(b.containment).offset(),e=a(c).css("overflow")!="hidden";this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var f=b.pageX,g=b.pageY;if(this.originalPosition){this.containment&&(b.pageX-this.offset.click.left<this.containment[0]&&(f=this.containment[0]+this.offset.click.left),b.pageY-this.offset.click.top<this.containment[1]&&(g=this.containment[1]+this.offset.click.top),b.pageX-this.offset.click.left>this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.top<this.containment[1]||h-this.offset.click.top>this.containment[3]?h-this.offset.click.top<this.containment[1]?h+c.grid[1]:h-c.grid[1]:h:h;var i=this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0];f=this.containment?i-this.offset.click.left<this.containment[0]||i-this.offset.click.left>this.containment[2]?i-this.offset.click.left<this.containment[0]?i+c.grid[0]:i-c.grid[0]:i:i}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_rearrange:function(a,b,c,d){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?b.item[0]:b.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var e=this,f=this.counter;window.setTimeout(function(){f==e.counter&&e.refreshPositions(!d)},0)},_clear:function(b,c){this.reverting=!1;var d=[],e=this;!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var f in this._storedCSS)if(this._storedCSS[f]=="auto"||this._storedCSS[f]=="static")this._storedCSS[f]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!c&&d.push(function(a){this._trigger("receive",a,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!c&&d.push(function(a){this._trigger("update",a,this._uiHash())});if(!a.ui.contains(this.element[0],this.currentItem[0])){c||d.push(function(a){this._trigger("remove",a,this._uiHash())});for(var f=this.containers.length-1;f>=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}return!1}c||this._trigger("beforeStop",b,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!=this.currentItem[0]&&this.helper.remove(),this.helper=null;if(!c){for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}this.fromOutside=!1;return!0},_trigger:function(){a.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(b){var c=b||this;return{helper:c.helper,placeholder:c.placeholder||a([]),position:c.position,originalPosition:c.originalPosition,offset:c.positionAbs,item:c.currentItem,sender:b?b.element:null}}}),a.extend(a.ui.sortable,{version:"1.8.18"})})(jQuery);/*
- * jQuery UI Accordion 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Accordion
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.widget.js
- */(function(a,b){a.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:!0,clearStyle:!1,collapsible:!1,event:"click",fillSpace:!1,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var b=this,c=b.options;b.running=0,b.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"),b.headers=b.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c.disabled||a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c.disabled||a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c.disabled||a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c.disabled||a(this).removeClass("ui-state-focus")}),b.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(c.navigation){var d=b.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var e=d.closest(".ui-accordion-header");e.length?b.active=e:b.active=d.closest(".ui-accordion-content").prev()}}b.active=b._findActive(b.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"),b.active.next().addClass("ui-accordion-content-active"),b._createIcons(),b.resize(),b.element.attr("role","tablist"),b.headers.attr("role","tab").bind("keydown.accordion",function(a){return b._keydown(a)}).next().attr("role","tabpanel"),b.headers.not(b.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide(),b.active.length?b.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):b.headers.eq(0).attr("tabIndex",0),a.browser.safari||b.headers.find("a").attr("tabIndex",-1),c.event&&b.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(a){b._clickHandler.call(b,a,this),a.preventDefault()})},_createIcons:function(){var b=this.options;b.icons&&(a("<span></span>").addClass("ui-icon "+b.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(b.icons.header).toggleClass(b.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove(),this.element.removeClass("ui-accordion-icons")},destroy:function(){var b=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"),this.headers.find("a").removeAttr("tabIndex"),this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");(b.autoHeight||b.fillHeight)&&c.css("height","");return a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b=="active"&&this.activate(c),b=="icons"&&(this._destroyIcons(),c&&this._createIcons()),b=="disabled"&&this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(b){if(!(this.options.disabled||b.altKey||b.ctrlKey)){var c=a.ui.keyCode,d=this.headers.length,e=this.headers.index(b.target),f=!1;switch(b.keyCode){case c.RIGHT:case c.DOWN:f=this.headers[(e+1)%d];break;case c.LEFT:case c.UP:f=this.headers[(e-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:b.target},b.target),b.preventDefault()}if(f){a(b.target).attr("tabIndex",-1),a(f).attr("tabIndex",0),f.focus();return!1}return!0}},resize:function(){var b=this.options,c;if(b.fillSpace){if(a.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height(),a.browser.msie&&this.element.parent().css("overflow",d),this.headers.each(function(){c-=a(this).outerHeight(!0)}),this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")}else b.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c));return this},activate:function(a){this.options.active=a;var b=this._findActive(a)[0];this._clickHandler({target:b},b);return this},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===!1?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,c){var d=this.options;if(!d.disabled){if(!b.target){if(!d.collapsible)return;this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),this.active.next().addClass("ui-accordion-content-active");var e=this.active.next(),f={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:e},g=this.active=a([]);this._toggle(g,e,f);return}var h=a(b.currentTarget||c),i=h[0]===this.active[0];d.active=d.collapsible&&i?!1:this.headers.index(h);if(this.running||!d.collapsible&&i)return;var j=this.active,g=h.next(),e=this.active.next(),f={options:d,newHeader:i&&d.collapsible?a([]):h,oldHeader:this.active,newContent:i&&d.collapsible?a([]):g,oldContent:e},k=this.headers.index(this.active[0])>this.headers.index(h[0]);this.active=i?a([]):h,this._toggle(g,e,f,i,k),j.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),i||(h.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),h.next().addClass("ui-accordion-content-active"));return}},_toggle:function(b,c,d,e,f){var g=this,h=g.options;g.toShow=b,g.toHide=c,g.data=d;var i=function(){if(!!g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data),g.running=c.size()===0?b.size():c.size();if(h.animated){var j={};h.collapsible&&e?j={toShow:a([]),toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace}:j={toShow:b,toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace},h.proxied||(h.proxied=h.animated),h.proxiedDuration||(h.proxiedDuration=h.duration),h.animated=a.isFunction(h.proxied)?h.proxied(j):h.proxied,h.duration=a.isFunction(h.proxiedDuration)?h.proxiedDuration(j):h.proxiedDuration;var k=a.ui.accordion.animations,l=h.duration,m=h.animated;m&&!k[m]&&!a.easing[m]&&(m="slide"),k[m]||(k[m]=function(a){this.slide(a,{easing:m,duration:l||700})}),k[m](j)}else h.collapsible&&e?b.toggle():(c.hide(),b.show()),i(!0);c.prev().attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).blur(),b.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;this.running||(this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data))}}),a.extend(a.ui.accordion,{version:"1.8.18",animations:{slide:function(b,c){b=a.extend({easing:"swing",duration:300},b,c);if(!b.toHide.size())b.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},b);else{if(!b.toShow.size()){b.toHide.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide"},b);return}var d=b.toShow.css("overflow"),e=0,f={},g={},h=["height","paddingTop","paddingBottom"],i,j=b.toShow;i=j[0].style.width,j.width(j.parent().width()-parseFloat(j.css("paddingLeft"))-parseFloat(j.css("paddingRight"))-(parseFloat(j.css("borderLeftWidth"))||0)-(parseFloat(j.css("borderRightWidth"))||0)),a.each(h,function(c,d){g[d]="hide";var e=(""+a.css(b.toShow[0],d)).match(/^([\d+-.]+)(.*)$/);f[d]={value:e[1],unit:e[2]||"px"}}),b.toShow.css({height:0,overflow:"hidden"}).show(),b.toHide.filter(":hidden").each(b.complete).end().filter(":visible").animate(g,{step:function(a,c){c.prop=="height"&&(e=c.end-c.start===0?0:(c.now-c.start)/(c.end-c.start)),b.toShow[0].style[c.prop]=e*f[c.prop].value+f[c.prop].unit},duration:b.duration,easing:b.easing,complete:function(){b.autoHeight||b.toShow.css("height",""),b.toShow.css({width:i,overflow:d}),b.complete()}})}},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1e3:200})}}})})(jQuery);/*
- * jQuery UI Autocomplete 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Autocomplete
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.widget.js
- * jquery.ui.position.js
- */(function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!b.options.disabled&&!b.element.propAttr("readOnly")){d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._move("previous",c),c.preventDefault();break;case e.DOWN:b._move("next",c),c.preventDefault();break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){b.options.disabled||(b.selectedItem=null,b.previous=b.element.val())}).bind("blur.autocomplete",function(a){b.options.disabled||(clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150))}),this._initSource(),this.response=function(){return b._response.apply(b,arguments)},this.menu=a("<ul></ul>").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,d,e;a.isArray(this.options.source)?(d=this.options.source,this.source=function(b,c){c(a.ui.autocomplete.filter(d,b.term))}):typeof this.options.source=="string"?(e=this.options.source,this.source=function(d,f){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:e,data:d,dataType:"json",context:{autocompleteRequest:++c},success:function(a,b){this.autocompleteRequest===c&&f(a)},error:function(){this.autocompleteRequest===c&&f([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==!1)return this._search(a)},_search:function(a){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.source({term:a},this.response)},_response:function(a){!this.options.disabled&&a&&a.length?(a=this._normalize(a),this._suggest(a),this._trigger("open")):this.close(),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.deactivate(),this._trigger("close",a))},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(b){if(b.length&&b[0].label&&b[0].value)return b;return a.map(b,function(b){if(typeof b=="string")return{label:b,value:b};return a.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(b){var c=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(c,b),this.menu.deactivate(),this.menu.refresh(),c.show(),this._resizeMenu(),c.position(a.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(new a.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(b,c){var d=this;a.each(c,function(a,c){d._renderItem(b,c)})},_renderItem:function(b,c){return a("<li></li>").data("item.autocomplete",c).append(a("<a></a>").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible"))this.search(null,b);else{if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)}},widget:function(){return this.menu.element}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})})(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){!a(c.target).closest(".ui-menu-item a").length||(c.preventDefault(),b.select(c))}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){!this.active||(this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null)},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active)this.activate(c,this.element.children(b));else{var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))}},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10}),result.length||(result=this.element.children(".ui-menu-item:first")),this.activate(b,result)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[a.fn.prop?"prop":"attr"]("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})}(jQuery);/*
- * jQuery UI Button 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Button
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.widget.js
- */(function(a,b){var c,d,e,f,g="ui-button ui-widget ui-state-default ui-corner-all",h="ui-state-hover ui-state-active ",i="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",j=function(){var b=a(this).find(":ui-button");setTimeout(function(){b.button("refresh")},1)},k=function(b){var c=b.name,d=b.form,e=a([]);c&&(d?e=a(d).find("[name='"+c+"']"):e=a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form}));return e};a.widget("ui.button",{options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",j),typeof this.options.disabled!="boolean"?this.options.disabled=!!this.element.propAttr("disabled"):this.element.propAttr("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var b=this,h=this.options,i=this.type==="checkbox"||this.type==="radio",l="ui-state-hover"+(i?"":" ui-state-active"),m="ui-state-focus";h.label===null&&(h.label=this.buttonElement.html()),this.buttonElement.addClass(g).attr("role","button").bind("mouseenter.button",function(){h.disabled||(a(this).addClass("ui-state-hover"),this===c&&a(this).addClass("ui-state-active"))}).bind("mouseleave.button",function(){h.disabled||a(this).removeClass(l)}).bind("click.button",function(a){h.disabled&&(a.preventDefault(),a.stopImmediatePropagation())}),this.element.bind("focus.button",function(){b.buttonElement.addClass(m)}).bind("blur.button",function(){b.buttonElement.removeClass(m)}),i&&(this.element.bind("change.button",function(){f||b.refresh()}),this.buttonElement.bind("mousedown.button",function(a){h.disabled||(f=!1,d=a.pageX,e=a.pageY)}).bind("mouseup.button",function(a){!h.disabled&&(d!==a.pageX||e!==a.pageY)&&(f=!0)})),this.type==="checkbox"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).toggleClass("ui-state-active"),b.buttonElement.attr("aria-pressed",b.element[0].checked)}):this.type==="radio"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).addClass("ui-state-active"),b.buttonElement.attr("aria-pressed","true");var c=b.element[0];k(c).not(c).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown.button",function(){if(h.disabled)return!1;a(this).addClass("ui-state-active"),c=this,a(document).one("mouseup",function(){c=null})}).bind("mouseup.button",function(){if(h.disabled)return!1;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(b){if(h.disabled)return!1;(b.keyCode==a.ui.keyCode.SPACE||b.keyCode==a.ui.keyCode.ENTER)&&a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(b){b.keyCode===a.ui.keyCode.SPACE&&a(this).click()})),this._setOption("disabled",h.disabled),this._resetButton()},_determineButtonType:function(){this.element.is(":checkbox")?this.type="checkbox":this.element.is(":radio")?this.type="radio":this.element.is("input")?this.type="input":this.type="button";if(this.type==="checkbox"||this.type==="radio"){var a=this.element.parents().filter(":last"),b="label[for='"+this.element.attr("id")+"']";this.buttonElement=a.find(b),this.buttonElement.length||(a=a.length?a.siblings():this.element.siblings(),this.buttonElement=a.filter(b),this.buttonElement.length||(this.buttonElement=a.find(b))),this.element.addClass("ui-helper-hidden-accessible");var c=this.element.is(":checked");c&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.attr("aria-pressed",c)}else this.buttonElement=this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(g+" "+h+" "+i).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title"),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments);b==="disabled"?c?this.element.propAttr("disabled",!0):this.element.propAttr("disabled",!1):this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b),this.type==="radio"?k(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):this.type==="checkbox"&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement.removeClass(i),c=a("<span></span>",this.element[0].ownerDocument).addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary,f=[];d.primary||d.secondary?(this.options.text&&f.push("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary")),d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>"),d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>"),this.options.text||(f.push(e?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||b.attr("title",c))):f.push("ui-button-text-only"),b.addClass(f.join(" "))}}}),a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c),a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(b?"ui-corner-left":"ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"),a.Widget.prototype.destroy.call(this)}})})(jQuery);/*
- * jQuery UI Dialog 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Dialog
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.widget.js
- * jquery.ui.button.js
- * jquery.ui.draggable.js
- * jquery.ui.mouse.js
- * jquery.ui.position.js
- * jquery.ui.resizable.js
- */(function(a,b){var c="ui-dialog ui-widget ui-widget-content ui-corner-all ",d={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},e={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},f=a.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};a.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(b){var c=a(this).css(b).offset().top;c<0&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.options.title=this.options.title||this.originalTitle;var b=this,d=b.options,e=d.title||"&#160;",f=a.ui.dialog.getTitleId(b.element),g=(b.uiDialog=a("<div></div>")).appendTo(document.body).hide().addClass(c+d.dialogClass).css({zIndex:d.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(c){d.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(a){b.moveToTop(!1,a)}),h=b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g),i=(b.uiDialogTitlebar=a("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),j=a('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){j.addClass("ui-state-hover")},function(){j.removeClass("ui-state-hover")}).focus(function(){j.addClass("ui-state-focus")}).blur(function(){j.removeClass("ui-state-focus")}).click(function(a){b.close(a);return!1}).appendTo(i),k=(b.uiDialogTitlebarCloseText=a("<span></span>")).addClass("ui-icon ui-icon-closethick").text(d.closeText).appendTo(j),l=a("<span></span>").addClass("ui-dialog-title").attr("id",f).html(e).prependTo(i);a.isFunction(d.beforeclose)&&!a.isFunction(d.beforeClose)&&(d.beforeClose=d.beforeclose),i.find("*").add(i).disableSelection(),d.draggable&&a.fn.draggable&&b._makeDraggable(),d.resizable&&a.fn.resizable&&b._makeResizable(),b._createButtons(d.buttons),b._isOpen=!1,a.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy(),a.uiDialog.hide(),a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),a.uiDialog.remove(),a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(b){var c=this,d,e;if(!1!==c._trigger("beforeClose",b)){c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(d=0,a(".ui-dialog").each(function(){this!==c.uiDialog[0]&&(e=a(this).css("z-index"),isNaN(e)||(d=Math.max(d,e)))}),a.ui.dialog.maxZ=d);return c}},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var d=this,e=d.options,f;if(e.modal&&!b||!e.stack&&!e.modal)return d._trigger("focus",c);e.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=e.zIndex),d.overlay&&(a.ui.dialog.maxZ+=1,d.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),f={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()},a.ui.dialog.maxZ+=1,d.uiDialog.css("z-index",a.ui.dialog.maxZ),d.element.attr(f),d._trigger("focus",c);return d},open:function(){if(!this._isOpen){var b=this,c=b.options,d=b.uiDialog;b.overlay=c.modal?new a.ui.dialog.overlay(b):null,b._size(),b._position(c.position),d.show(c.show),b.moveToTop(!0),c.modal&&d.bind("keydown.ui-dialog",function(b){if(b.keyCode===a.ui.keyCode.TAB){var c=a(":tabbable",this),d=c.filter(":first"),e=c.filter(":last");if(b.target===e[0]&&!b.shiftKey){d.focus(1);return!1}if(b.target===d[0]&&b.shiftKey){e.focus(1);return!1}}}),a(b.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(),b._isOpen=!0,b._trigger("open");return b}},_createButtons:function(b){var c=this,d=!1,e=a("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=a("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);c.uiDialog.find(".ui-dialog-buttonpane").remove(),typeof b=="object"&&b!==null&&a.each(b,function(){return!(d=!0)}),d&&(a.each(b,function(b,d){d=a.isFunction(d)?{click:d,text:b}:d;var e=a('<button type="button"></button>').click(function(){d.click.apply(c.element[0],arguments)}).appendTo(g);a.each(d,function(a,b){a!=="click"&&(a in f?e[a](b):e.attr(a,b))}),a.fn.button&&e.button()}),e.appendTo(c.uiDialog))},_makeDraggable:function(){function f(a){return{position:a.position,offset:a.offset}}var b=this,c=b.options,d=a(document),e;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(d,g){e=c.height==="auto"?"auto":a(this).height(),a(this).height(a(this).height()).addClass("ui-dialog-dragging"),b._trigger("dragStart",d,f(g))},drag:function(a,c){b._trigger("drag",a,f(c))},stop:function(g,h){c.position=[h.position.left-d.scrollLeft(),h.position.top-d.scrollTop()],a(this).removeClass("ui-dialog-dragging").height(e),b._trigger("dragStop",g,f(h)),a.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function h(a){return{originalPosition:a.originalPosition,originalSize:a.originalSize,position:a.position,size:a.size}}c=c===b?this.options.resizable:c;var d=this,e=d.options,f=d.uiDialog.css("position"),g=typeof c=="string"?c:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:g,start:function(b,c){a(this).addClass("ui-dialog-resizing"),d._trigger("resizeStart",b,h(c))},resize:function(a,b){d._trigger("resize",a,h(b))},stop:function(b,c){a(this).removeClass("ui-dialog-resizing"),e.height=a(this).height(),e.width=a(this).width(),d._trigger("resizeStop",b,h(c)),a.ui.dialog.overlay.resize()}}).css("position",f).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],d=[0,0],e;if(b){if(typeof b=="string"||typeof b=="object"&&"0"in b)c=b.split?b.split(" "):[b[0],b[1]],c.length===1&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(d[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:d.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b)),e||this.uiDialog.hide()},_setOptions:function(b){var c=this,f={},g=!1;a.each(b,function(a,b){c._setOption(a,b),a in d&&(g=!0),a in e&&(f[a]=b)}),g&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,d){var e=this,f=e.uiDialog;switch(b){case"beforeclose":b="beforeClose";break;case"buttons":e._createButtons(d);break;case"closeText":e.uiDialogTitlebarCloseText.text(""+d);break;case"dialogClass":f.removeClass(e.options.dialogClass).addClass(c+d);break;case"disabled":d?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case"draggable":var g=f.is(":data(draggable)");g&&!d&&f.draggable("destroy"),!g&&d&&e._makeDraggable();break;case"position":e._position(d);break;case"resizable":var h=f.is(":data(resizable)");h&&!d&&f.resizable("destroy"),h&&typeof d=="string"&&f.resizable("option","handles",d),!h&&d!==!1&&e._makeResizable(d);break;case"title":a(".ui-dialog-title",e.uiDialogTitlebar).html(""+(d||"&#160;"))}a.Widget.prototype._setOption.apply(e,arguments)},_size:function(){var b=this.options,c,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),b.minWidth>b.width&&(b.width=b.minWidth),c=this.uiDialog.css({height:"auto",width:b.width}).height(),d=Math.max(0,b.minHeight-c);if(b.height==="auto")if(a.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();var f=this.element.css("height","auto").height();e||this.uiDialog.hide(),this.element.height(Math.max(f,d))}else this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),a.extend(a.ui.dialog,{version:"1.8.18",uuid:0,maxZ:0,getTitleId:function(a){var b=a.attr("id");b||(this.uuid+=1,b=this.uuid);return"ui-dialog-title-"+b},overlay:function(b){this.$el=a.ui.dialog.overlay.create(b)}}),a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(b){this.instances.length===0&&(setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()<a.ui.dialog.overlay.maxZ)return!1})},1),a(document).bind("keydown.dialog-overlay",function(c){b.options.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}),a(window).bind("resize.dialog-overlay",a.ui.dialog.overlay.resize));var c=(this.oldInstances.pop()||a("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});a.fn.bgiframe&&c.bgiframe(),this.instances.push(c);return c},destroy:function(b){var c=a.inArray(b,this.instances);c!=-1&&this.oldInstances.push(this.instances.splice(c,1)[0]),this.instances.length===0&&a([document,window]).unbind(".dialog-overlay"),b.remove();var d=0;a.each(this.instances,function(){d=Math.max(d,this.css("z-index"))}),this.maxZ=d},height:function(){var b,c;if(a.browser.msie&&a.browser.version<7){b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return b<c?a(window).height()+"px":b+"px"}return a(document).height()+"px"},width:function(){var b,c;if(a.browser.msie){b=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth),c=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return b<c?a(window).width()+"px":b+"px"}return a(document).width()+"px"},resize:function(){var b=a([]);a.each(a.ui.dialog.overlay.instances,function(){b=b.add(this)}),b.css({width:0,height:0}).css({width:a.ui.dialog.overlay.width(),height:a.ui.dialog.overlay.height()})}}),a.extend(a.ui.dialog.overlay.prototype,{destroy:function(){a.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);/*
- * jQuery UI Slider 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Slider
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.mouse.js
- * jquery.ui.widget.js
- */(function(a,b){var c=5;a.widget("ui.slider",a.ui.mouse,{widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var b=this,d=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",g=d.values&&d.values.length||1,h=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(d.disabled?" ui-slider-disabled ui-disabled":"")),this.range=a([]),d.range&&(d.range===!0&&(d.values||(d.values=[this._valueMin(),this._valueMin()]),d.values.length&&d.values.length!==2&&(d.values=[d.values[0],d.values[0]])),this.range=a("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:"")));for(var i=e.length;i<g;i+=1)h.push(f);this.handles=e.add(a(h.join("")).appendTo(b.element)),this.handle=this.handles.eq(0),this.handles.add(this.range).filter("a").click(function(a){a.preventDefault()}).hover(function(){d.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){d.disabled?a(this).blur():(a(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),a(this).addClass("ui-state-focus"))}).blur(function(){a(this).removeClass("ui-state-focus")}),this.handles.each(function(b){a(this).data("index.ui-slider-handle",b)}),this.handles.keydown(function(d){var e=a(this).data("index.ui-slider-handle"),f,g,h,i;if(!b.options.disabled){switch(d.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:d.preventDefault();if(!b._keySliding){b._keySliding=!0,a(this).addClass("ui-state-active"),f=b._start(d,e);if(f===!1)return}}i=b.options.step,b.options.values&&b.options.values.length?g=h=b.values(e):g=h=b.value();switch(d.keyCode){case a.ui.keyCode.HOME:h=b._valueMin();break;case a.ui.keyCode.END:h=b._valueMax();break;case a.ui.keyCode.PAGE_UP:h=b._trimAlignValue(g+(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.PAGE_DOWN:h=b._trimAlignValue(g-(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(g===b._valueMax())return;h=b._trimAlignValue(g+i);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(g===b._valueMin())return;h=b._trimAlignValue(g-i)}b._slide(d,e,h)}}).keyup(function(c){var d=a(this).data("index.ui-slider-handle");b._keySliding&&(b._keySliding=!1,b._stop(c,d),b._change(c,d),a(this).removeClass("ui-state-active"))}),this._refreshValue(),this._animateOff=!1},destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider"),this._mouseDestroy();return this},_mouseCapture:function(b){var c=this.options,d,e,f,g,h,i,j,k,l;if(c.disabled)return!1;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),d={x:b.pageX,y:b.pageY},e=this._normValueFromMouse(d),f=this._valueMax()-this._valueMin()+1,h=this,this.handles.each(function(b){var c=Math.abs(e-h.values(b));f>c&&(f=c,g=a(this),i=b)}),c.range===!0&&this.values(1)===c.min&&(i+=1,g=a(this.handles[i])),j=this._start(b,i);if(j===!1)return!1;this._mouseSliding=!0,h._handleIndex=i,g.addClass("ui-state-active").focus(),k=g.offset(),l=!a(b.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:b.pageX-k.left-g.width()/2,top:b.pageY-k.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,i,e),this._animateOff=!0;return!0},_mouseStart:function(a){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);this._slide(a,this._handleIndex,c);return!1},_mouseStop:function(a){this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1;return!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;this.orientation==="horizontal"?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),d<0&&(d=0),this.orientation==="vertical"&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e;return this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values());return this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),this.options.values.length===2&&this.options.range===!0&&(b===0&&c>d||b===1&&c<d)&&(c=d),c!==this.values(b)&&(e=this.values(),e[b]=c,f=this._trigger("slide",a,{handle:this.handles[b],value:c,values:e}),d=this.values(b?0:1),f!==!1&&this.values(b,c,!0))):c!==this.value()&&(f=this._trigger("slide",a,{handle:this.handles[b],value:c}),f!==!1&&this.value(c))},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("change",a,c)}},value:function(a){if(arguments.length)this.options.value=this._trimAlignValue(a),this._refreshValue(),this._change(null,0);else return this._value()},values:function(b,c){var d,e,f;if(arguments.length>1)this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),this._change(null,b);else{if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();d=this.options.values,e=arguments[0];for(f=0;f<d.length;f+=1)d[f]=this._trimAlignValue(e[f]),this._change(null,f);this._refreshValue()}},_setOption:function(b,c){var d,e=0;a.isArray(this.options.values)&&(e=this.options.values.length),a.Widget.prototype._setOption.apply(this,arguments);switch(b){case"disabled":c?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.propAttr("disabled",!0),this.element.addClass("ui-disabled")):(this.handles.propAttr("disabled",!1),this.element.removeClass("ui-disabled"));break;case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":this._animateOff=!0,this._refreshValue();for(d=0;d<e;d+=1)this._change(null,d);this._animateOff=!1}},_value:function(){var a=this.options.value;a=this._trimAlignValue(a);return a},_values:function(a){var b,c,d;if(arguments.length){b=this.options.values[a],b=this._trimAlignValue(b);return b}c=this.options.values.slice();for(d=0;d<c.length;d+=1)c[d]=this._trimAlignValue(c[d]);return c},_trimAlignValue:function(a){if(a<=this._valueMin())return this._valueMin();if(a>=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;Math.abs(c)*2>=b&&(d+=c>0?b:-b);return parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var b=this.options.range,c=this.options,d=this,e=this._animateOff?!1:c.animate,f,g={},h,i,j,k;this.options.values&&this.options.values.length?this.handles.each(function(b,i){f=(d.values(b)-d._valueMin())/(d._valueMax()-d._valueMin())*100,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",a(this).stop(1,1)[e?"animate":"css"](g,c.animate),d.options.range===!0&&(d.orientation==="horizontal"?(b===0&&d.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({width:f-h+"%"},{queue:!1,duration:c.animate})):(b===0&&d.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({height:f-h+"%"},{queue:!1,duration:c.animate}))),h=f}):(i=this.value(),j=this._valueMin(),k=this._valueMax(),f=k!==j?(i-j)/(k-j)*100:0,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",this.handle.stop(1,1)[e?"animate":"css"](g,c.animate),b==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},c.animate),b==="max"&&this.orientation==="horizontal"&&this.range[e?"animate":"css"]({width:100-f+"%"},{queue:!1,duration:c.animate}),b==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},c.animate),b==="max"&&this.orientation==="vertical"&&this.range[e?"animate":"css"]({height:100-f+"%"},{queue:!1,duration:c.animate}))}}),a.extend(a.ui.slider,{version:"1.8.18"})})(jQuery);/*
- * jQuery UI Tabs 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Tabs
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.widget.js
- */(function(a,b){function f(){return++d}function e(){return++c}var c=0,d=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:!1,cookie:null,collapsible:!1,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(!0)},_setOption:function(a,b){if(a=="selected"){if(this.options.collapsible&&b==this.options.selected)return;this.select(b)}else this.options[a]=b,this._tabify()},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+e()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+f());return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,b){return{tab:a,panel:b,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function m(b,c){b.css("display",""),!a.support.opacity&&c.opacity&&b[0].style.removeAttribute("filter")}var d=this,e=this.options,f=/^#.+/;this.list=this.element.find("ol,ul").eq(0),this.lis=a(" > li:has(a[href])",this.list),this.anchors=this.lis.map(function(){return a("a",this)[0]}),this.panels=a([]),this.anchors.each(function(b,c){var g=a(c).attr("href"),h=g.split("#")[0],i;h&&(h===location.toString().split("#")[0]||(i=a("base")[0])&&h===i.href)&&(g=c.hash,c.href=g);if(f.test(g))d.panels=d.panels.add(d.element.find(d._sanitizeSelector(g)));else if(g&&g!=="#"){a.data(c,"href.tabs",g),a.data(c,"load.tabs",g.replace(/#.*$/,""));var j=d._tabId(c);c.href="#"+j;var k=d.element.find("#"+j);k.length||(k=a(e.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),k.data("destroy.tabs",!0)),d.panels=d.panels.add(k)}else e.disabled.push(b)}),c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),e.selected===b?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash){e.selected=a;return!1}}),typeof e.selected!="number"&&e.cookie&&(e.selected=parseInt(d._cookie(),10)),typeof e.selected!="number"&&this.lis.filter(".ui-tabs-selected").length&&(e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))),e.selected=e.selected||(this.lis.length?0:-1)):e.selected===null&&(e.selected=-1),e.selected=e.selected>=0&&this.anchors[e.selected]||e.selected<0?e.selected:0,e.disabled=a.unique(e.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a,b){return d.lis.index(a)}))).sort(),a.inArray(e.selected,e.disabled)!=-1&&e.disabled.splice(a.inArray(e.selected,e.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),e.selected>=0&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(e.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[e.selected],d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash))[0]))}),this.load(e.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs"),d.lis=d.anchors=d.panels=null})):e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")),this.element[e.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible"),e.cookie&&this._cookie(e.selected,e.cookie);for(var g=0,h;h=this.lis[g];g++)a(h)[a.inArray(g,e.disabled)!=-1&&!a(h).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");e.cache===!1&&this.anchors.removeData("cache.tabs"),this.lis.add(this.anchors).unbind(".tabs");if(e.event!=="mouseover"){var i=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)},j=function(a,b){b.removeClass("ui-state-"+a)};this.lis.bind("mouseover.tabs",function(){i("hover",a(this))}),this.lis.bind("mouseout.tabs",function(){j("hover",a(this))}),this.anchors.bind("focus.tabs",function(){i("focus",a(this).closest("li"))}),this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var k,l;e.fx&&(a.isArray(e.fx)?(k=e.fx[0],l=e.fx[1]):k=l=e.fx);var n=l?function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.hide().removeClass("ui-tabs-hide").animate(l,l.duration||"normal",function(){m(c,l),d._trigger("show",null,d._ui(b,c[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.removeClass("ui-tabs-hide"),d._trigger("show",null,d._ui(b,c[0]))},o=k?function(a,b){b.animate(k,k.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),m(b,k),d.element.dequeue("tabs")})}:function(a,b,c){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),d.element.dequeue("tabs")};this.anchors.bind(e.event+".tabs",function(){var b=this,c=a(b).closest("li"),f=d.panels.filter(":not(.ui-tabs-hide)"),g=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!e.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||d.panels.filter(":animated").length||d._trigger("select",null,d._ui(this,g[0]))===!1){this.blur();return!1}e.selected=d.anchors.index(this),d.abort();if(e.collapsible){if(c.hasClass("ui-tabs-selected")){e.selected=-1,e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){o(b,f)}).dequeue("tabs"),this.blur();return!1}if(!f.length){e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this)),this.blur();return!1}}e.cookie&&d._cookie(e.selected,e.cookie);if(g.length)f.length&&d.element.queue("tabs",function(){o(b,f)}),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier.";a.browser.msie&&this.blur()}),this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){typeof a=="string"&&(a=this.anchors.index(this.anchors.filter("[href$="+a+"]")));return a},destroy:function(){var b=this.options;this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b=a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}),b.cookie&&this._cookie(null,b.cookie);return this},add:function(c,d,e){e===b&&(e=this.anchors.length);var f=this,g=this.options,h=a(g.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),i=c.indexOf("#")?this._tabId(a("a",h)[0]):c.replace("#","");h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+i);j.length||(j=a(g.panelTemplate).attr("id",i).data("destroy.tabs",!0)),j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),e>=this.lis.length?(h.appendTo(this.list),j.appendTo(this.list[0].parentNode)):(h.insertBefore(this.lis[e]),j.insertBefore(this.panels[e])),g.disabled=a.map(g.disabled,function(a,b){return a>=e?++a:a}),this._tabify(),this.anchors.length==1&&(g.selected=0,h.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[e],this.panels[e]));return this},remove:function(b){b=this._getIndex(b);var c=this.options,d=this.lis.eq(b).remove(),e=this.panels.eq(b).remove();d.hasClass("ui-tabs-selected")&&this.anchors.length>1&&this.select(b+(b+1<this.anchors.length?1:-1)),c.disabled=a.map(a.grep(c.disabled,function(a,c){return a!=b}),function(a,c){return a>=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],e[0]));return this},enable:function(b){b=this._getIndex(b);var c=this.options;if(a.inArray(b,c.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a,c){return a!=b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(a){a=this._getIndex(a);var b=this,c=this.options;a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a])));return this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;this.anchors.eq(a).trigger(this.options.event+".tabs");return this},load:function(b){b=this._getIndex(b);var c=this,d=this.options,e=this.anchors.eq(b)[0],f=a.data(e,"load.tabs");this.abort();if(!f||this.element.queue("tabs").length!==0&&a.data(e,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var g=a("span",e);g.data("label.tabs",g.html()).html(d.spinner)}this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:f,success:function(f,g){c.element.find(c._sanitizeSelector(e.hash)).html(f),c._cleanup(),d.cache&&a.data(e,"cache.tabs",!0),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(f,g)}catch(h){}},error:function(a,f,g){c._cleanup(),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,f,b,e)}catch(g){}}})),c.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup();return this},url:function(a,b){this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",b);return this},length:function(){return this.anchors.length}}),a.extend(a.ui.tabs,{version:"1.8.18"}),a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,b){var c=this,d=this.options,e=c._rotate||(c._rotate=function(b){clearTimeout(c.rotation),c.rotation=setTimeout(function(){var a=d.selected;c.select(++a<c.anchors.length?a:0)},a),b&&b.stopPropagation()}),f=c._unrotate||(c._unrotate=b?function(a){t=d.selected,e()}:function(a){a.clientX&&c.rotate(null)});a?(this.element.bind("tabsshow",e),this.anchors.bind(d.event+".tabs",f),e()):(clearTimeout(c.rotation),this.element.unbind("tabsshow",e),this.anchors.unbind(d.event+".tabs",f),delete this._rotate,delete this._unrotate);return this}})})(jQuery);/*
- * jQuery UI Datepicker 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Datepicker
- *
- * Depends:
- * jquery.ui.core.js
- */(function($,undefined){function isArray(a){return a&&($.browser.safari&&typeof a=="object"&&a.length||a.constructor&&a.constructor.toString().match(/\Array\(\)/))}function extendRemove(a,b){$.extend(a,b);for(var c in b)if(b[c]==null||b[c]==undefined)a[c]=b[c];return a}function bindHover(a){var b="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return a.bind("mouseout",function(a){var c=$(a.target).closest(b);!c.length||c.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){var d=$(c.target).closest(b);!$.datepicker._isDisabledDatepicker(instActive.inline?a.parent()[0]:instActive.input[0])&&!!d.length&&(d.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),d.addClass("ui-state-hover"),d.hasClass("ui-datepicker-prev")&&d.addClass("ui-datepicker-prev-hover"),d.hasClass("ui-datepicker-next")&&d.addClass("ui-datepicker-next-hover"))})}function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}$.extend($.ui,{datepicker:{version:"1.8.18"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){extendRemove(this._defaults,a||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(a,b){var c=a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:c,input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:b?bindHover($('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')):this.dpDiv}},_connectDatepicker:function(a,b){var c=$(a);b.append=$([]),b.trigger=$([]);c.hasClass(this.markerClassName)||(this._attachments(c,b),c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),this._autoSize(b),$.data(a,PROP_NAME,b),b.settings.disabled&&this._disableDatepicker(a))},_attachments:function(a,b){var c=this._get(b,"appendText"),d=this._get(b,"isRTL");b.append&&b.append.remove(),c&&(b.append=$('<span class="'+this._appendClass+'">'+c+"</span>"),a[d?"before":"after"](b.append)),a.unbind("focus",this._showDatepicker),b.trigger&&b.trigger.remove();var e=this._get(b,"showOn");(e=="focus"||e=="both")&&a.focus(this._showDatepicker);if(e=="button"||e=="both"){var f=this._get(b,"buttonText"),g=this._get(b,"buttonImage");b.trigger=$(this._get(b,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:g,alt:f,title:f}):$('<button type="button"></button>').addClass(this._triggerClass).html(g==""?f:$("<img/>").attr({src:g,alt:f,title:f}))),a[d?"before":"after"](b.trigger),b.trigger.click(function(){$.datepicker._datepickerShowing&&$.datepicker._lastInput==a[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=a[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(a[0])):$.datepicker._showDatepicker(a[0]);return!1})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var d=function(a){var b=0,c=0;for(var d=0;d<a.length;d++)a[d].length>b&&(b=a[d].length,c=d);return c};b.setMonth(d(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort"))),b.setDate(d(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=$(a);c.hasClass(this.markerClassName)||(c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),$.data(a,PROP_NAME,b),this._setDate(b,this._getDefaultDate(b),!0),this._updateDatepicker(b),this._updateAlternate(b),b.settings.disabled&&this._disableDatepicker(a),b.dpDiv.css("display","block"))},_dialogDatepicker:function(a,b,c,d,e){var f=this._dialogInst;if(!f){this.uuid+=1;var g="dp"+this.uuid;this._dialogInput=$('<input type="text" id="'+g+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>'),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),f=this._dialogInst=this._newInst(this._dialogInput,!1),f.settings={},$.data(this._dialogInput[0],PROP_NAME,f)}extendRemove(f.settings,d||{}),b=b&&b.constructor==Date?this._formatDate(f,b):b,this._dialogInput.val(b),this._pos=e?e.length?e:[e.pageX,e.pageY]:null;if(!this._pos){var h=document.documentElement.clientWidth,i=document.documentElement.clientHeight,j=document.documentElement.scrollLeft||document.body.scrollLeft,k=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[h/2-100+j,i/2-150+k]}this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),f.settings.onSelect=c,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,f);return this},_destroyDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();$.removeData(a,PROP_NAME),d=="input"?(c.append.remove(),c.trigger.remove(),b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(d=="div"||d=="span")&&b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!1,c.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().removeClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b})}},_disableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!0,c.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().addClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b}),this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return!0;return!1},_getInst:function(a){try{return $.data(a,PROP_NAME)}catch(b){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(a,b,c){var d=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?$.extend({},$.datepicker._defaults):d?b=="all"?$.extend({},d.settings):this._get(d,b):null;var e=b||{};typeof b=="string"&&(e={},e[b]=c);if(d){this._curInst==d&&this._hideDatepicker();var f=this._getDateDatepicker(a,!0),g=this._getMinMaxDate(d,"min"),h=this._getMinMaxDate(d,"max");extendRemove(d.settings,e),g!==null&&e.dateFormat!==undefined&&e.minDate===undefined&&(d.settings.minDate=this._formatDate(d,g)),h!==null&&e.dateFormat!==undefined&&e.maxDate===undefined&&(d.settings.maxDate=this._formatDate(d,h)),this._attachments($(a),d),this._autoSize(d),this._setDate(d,f),this._updateAlternate(d),this._updateDatepicker(d)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){var b=this._getInst(a);b&&this._updateDatepicker(b)},_setDateDatepicker:function(a,b){var c=this._getInst(a);c&&(this._setDate(c,b),this._updateDatepicker(c),this._updateAlternate(c))},_getDateDatepicker:function(a,b){var c=this._getInst(a);c&&!c.inline&&this._setDateFromField(c,b);return c?this._getDate(c):null},_doKeyDown:function(a){var b=$.datepicker._getInst(a.target),c=!0,d=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=!0;if($.datepicker._datepickerShowing)switch(a.keyCode){case 9:$.datepicker._hideDatepicker(),c=!1;break;case 13:var e=$("td."+$.datepicker._dayOverClass+":not(."+$.datepicker._currentClass+")",b.dpDiv);e[0]&&$.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,e[0]);var f=$.datepicker._get(b,"onSelect");if(f){var g=$.datepicker._formatDate(b);f.apply(b.input?b.input[0]:null,[g,b])}else $.datepicker._hideDatepicker();return!1;case 27:$.datepicker._hideDatepicker();break;case 33:$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 34:$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 35:(a.ctrlKey||a.metaKey)&&$.datepicker._clearDate(a.target),c=a.ctrlKey||a.metaKey;break;case 36:(a.ctrlKey||a.metaKey)&&$.datepicker._gotoToday(a.target),c=a.ctrlKey||a.metaKey;break;case 37:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?1:-1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 38:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,-7,"D"),c=a.ctrlKey||a.metaKey;break;case 39:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?-1:1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 40:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,7,"D"),c=a.ctrlKey||a.metaKey;break;default:c=!1}else a.keyCode==36&&a.ctrlKey?$.datepicker._showDatepicker(this):c=!1;c&&(a.preventDefault(),a.stopPropagation())},_doKeyPress:function(a){var b=$.datepicker._getInst(a.target);if($.datepicker._get(b,"constrainInput")){var c=$.datepicker._possibleChars($.datepicker._get(b,"dateFormat")),d=String.fromCharCode(a.charCode==undefined?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||d<" "||!c||c.indexOf(d)>-1}},_doKeyUp:function(a){var b=$.datepicker._getInst(a.target);if(b.input.val()!=b.lastVal)try{var c=$.datepicker.parseDate($.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,$.datepicker._getFormatConfig(b));c&&($.datepicker._setDateFromField(b),$.datepicker._updateAlternate(b),$.datepicker._updateDatepicker(b))}catch(a){$.datepicker.log(a)}return!0},_showDatepicker:function(a){a=a.target||a,a.nodeName.toLowerCase()!="input"&&(a=$("input",a.parentNode)[0]);if(!$.datepicker._isDisabledDatepicker(a)&&$.datepicker._lastInput!=a){var b=$.datepicker._getInst(a);$.datepicker._curInst&&$.datepicker._curInst!=b&&($.datepicker._curInst.dpDiv.stop(!0,!0),b&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var c=$.datepicker._get(b,"beforeShow"),d=c?c.apply(a,[a,b]):{};if(d===!1)return;extendRemove(b.settings,d),b.lastVal=null,$.datepicker._lastInput=a,$.datepicker._setDateFromField(b),$.datepicker._inDialog&&(a.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(a),$.datepicker._pos[1]+=a.offsetHeight);var e=!1;$(a).parents().each(function(){e|=$(this).css("position")=="fixed";return!e}),e&&$.browser.opera&&($.datepicker._pos[0]-=document.documentElement.scrollLeft,$.datepicker._pos[1]-=document.documentElement.scrollTop);var f={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,b.dpDiv.empty(),b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(b),f=$.datepicker._checkOffset(b,f,e),b.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":e?"fixed":"absolute",display:"none",left:f.left+"px",top:f.top+"px"});if(!b.inline){var g=$.datepicker._get(b,"showAnim"),h=$.datepicker._get(b,"duration"),i=function(){var a=b.dpDiv.find("iframe.ui-datepicker-cover");if(!!a.length){var c=$.datepicker._getBorders(b.dpDiv);a.css({left:-c[0],top:-c[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex($(a).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&$.effects[g]?b.dpDiv.show(g,$.datepicker._get(b,"showOptions"),h,i):b.dpDiv[g||"show"](g?h:null,i),(!g||!h)&&i(),b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus(),$.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this;b.maxRows=4;var c=$.datepicker._getBorders(a.dpDiv);instActive=a,a.dpDiv.empty().append(this._generateHTML(a));var d=a.dpDiv.find("iframe.ui-datepicker-cover");!d.length||d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}),a.dpDiv.find("."+this._dayOverClass+" a").mouseover();var e=this._getNumberOfMonths(a),f=e[1],g=17;a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),f>1&&a.dpDiv.addClass("ui-datepicker-multi-"+f).css("width",g*f+"em"),a.dpDiv[(e[0]!=1||e[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),a==$.datepicker._curInst&&$.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var h=a.yearshtml;setTimeout(function(){h===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml),h=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var d=a.dpDiv.outerWidth(),e=a.dpDiv.outerHeight(),f=a.input?a.input.outerWidth():0,g=a.input?a.input.outerHeight():0,h=document.documentElement.clientWidth+$(document).scrollLeft(),i=document.documentElement.clientHeight+$(document).scrollTop();b.left-=this._get(a,"isRTL")?d-f:0,b.left-=c&&b.left==a.input.offset().left?$(document).scrollLeft():0,b.top-=c&&b.top==a.input.offset().top+g?$(document).scrollTop():0,b.left-=Math.min(b.left,b.left+d>h&&h>d?Math.abs(b.left+d-h):0),b.top-=Math.min(b.top,b.top+e>i&&i>e?Math.abs(e+g):0);return b},_findPos:function(a){var b=this._getInst(a),c=this._get(b,"isRTL");while(a&&(a.type=="hidden"||a.nodeType!=1||$.expr.filters.hidden(a)))a=a[c?"previousSibling":"nextSibling"];var d=$(a).offset();return[d.left,d.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=$.data(a,PROP_NAME))&&this._datepickerShowing){var c=this._get(b,"showAnim"),d=this._get(b,"duration"),e=this,f=function(){$.datepicker._tidyDialog(b),e._curInst=null};$.effects&&$.effects[c]?b.dpDiv.hide(c,$.datepicker._get(b,"showOptions"),d,f):b.dpDiv[c=="slideDown"?"slideUp":c=="fadeIn"?"fadeOut":"hide"](c?d:null,f),c||f(),this._datepickerShowing=!1;var g=this._get(b,"onClose");g&&g.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(!!$.datepicker._curInst){var b=$(a.target),c=$.datepicker._getInst(b[0]);(b[0].id!=$.datepicker._mainDivId&&b.parents("#"+$.datepicker._mainDivId).length==0&&!b.hasClass($.datepicker.markerClassName)&&!b.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||b.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=c)&&$.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){var d=$(a),e=this._getInst(d[0]);this._isDisabledDatepicker(d[0])||(this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c),this._updateDatepicker(e))},_gotoToday:function(a){var b=$(a),c=this._getInst(b[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate(),c.drawMonth=c.selectedMonth=d.getMonth(),c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c),this._adjustDate(b)},_selectMonthYear:function(a,b,c){var d=$(a),e=this._getInst(d[0]);e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10),this._notifyChange(e),this._adjustDate(d)},_selectDay:function(a,b,c,d){var e=$(a);if(!$(d).hasClass(this._unselectableClass)&&!this._isDisabledDatepicker(e[0])){var f=this._getInst(e[0]);f.selectedDay=f.currentDay=$("a",d).html(),f.selectedMonth=f.currentMonth=b,f.selectedYear=f.currentYear=c,this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){var b=$(a),c=this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(a,b){var c=$(a),d=this._getInst(c[0]);b=b!=null?b:this._formatDate(d),d.input&&d.input.val(b),this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[b,d]):d.input&&d.input.trigger("change"),d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],typeof d.input[0]!="object"&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),d=this._getDate(a),e=this.formatDate(c,d,this._getFormatConfig(a));$(b).each(function(){$(this).val(e)})}},noWeekends:function(a){var b=a.getDay();return[b>0&&b<6,""]},iso8601Week:function(a){var b=new Date(a.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();b.setMonth(0),b.setDate(1);return Math.floor(Math.round((c-b)/864e5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var d=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;d=typeof d!="string"?d:(new Date).getFullYear()%100+parseInt(d,10);var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=-1,j=-1,k=-1,l=-1,m=!1,n=function(b){var c=s+1<a.length&&a.charAt(s+1)==b;c&&s++;return c},o=function(a){var c=n(a),d=a=="@"?14:a=="!"?20:a=="y"&&c?4:a=="o"?3:2,e=new RegExp("^\\d{1,"+d+"}"),f=b.substring(r).match(e);if(!f)throw"Missing number at position "+r;r+=f[0].length;return parseInt(f[0],10)},p=function(a,c,d){var e=$.map(n(a)?d:c,function(a,b){return[[b,a]]}).sort(function(a,b){return-(a[1].length-b[1].length)}),f=-1;$.each(e,function(a,c){var d=c[1];if(b.substr(r,d.length).toLowerCase()==d.toLowerCase()){f=c[0],r+=d.length;return!1}});if(f!=-1)return f+1;throw"Unknown name at position "+r},q=function(){if(b.charAt(r)!=a.charAt(s))throw"Unexpected literal at position "+r;r++},r=0;for(var s=0;s<a.length;s++)if(m)a.charAt(s)=="'"&&!n("'")?m=!1:q();else switch(a.charAt(s)){case"d":k=o("d");break;case"D":p("D",e,f);break;case"o":l=o("o");break;case"m":j=o("m");break;case"M":j=p("M",g,h);break;case"y":i=o("y");break;case"@":var t=new Date(o("@"));i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"!":var t=new Date((o("!")-this._ticksTo1970)/1e4);i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"'":n("'")?q():m=!0;break;default:q()}if(r<b.length)throw"Extra/unparsed characters found in date: "+b.substring(r);i==-1?i=(new Date).getFullYear():i<100&&(i+=(new Date).getFullYear()-(new Date).getFullYear()%100+(i<=d?0:-100));if(l>-1){j=1,k=l;for(;;){var u=this._getDaysInMonth(i,j-1);if(k<=u)break;j++,k-=u}}var t=this._daylightSavingAdjust(new Date(i,j-1,k));if(t.getFullYear()!=i||t.getMonth()+1!=j||t.getDate()!=k)throw"Invalid date";return t},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:null)||this._defaults.dayNames,f=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){var c=m+1<a.length&&a.charAt(m+1)==b;c&&m++;return c},i=function(a,b,c){var d=""+b;if(h(a))while(d.length<c)d="0"+d;return d},j=function(a,b,c,d){return h(a)?d[b]:c[b]},k="",l=!1;if(b)for(var m=0;m<a.length;m++)if(l)a.charAt(m)=="'"&&!h("'")?l=!1:k+=a.charAt(m);else switch(a.charAt(m)){case"d":k+=i("d",b.getDate(),2);break;case"D":k+=j("D",b.getDay(),d,e);break;case"o":k+=i("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864e5),3);break;case"m":k+=i("m",b.getMonth()+1,2);break;case"M":k+=j("M",b.getMonth(),f,g);break;case"y":k+=h("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case"@":k+=b.getTime();break;case"!":k+=b.getTime()*1e4+this._ticksTo1970;break;case"'":h("'")?k+="'":l=!0;break;default:k+=a.charAt(m)}return k},_possibleChars:function(a){var b="",c=!1,d=function(b){var c=e+1<a.length&&a.charAt(e+1)==b;c&&e++;return c};for(var e=0;e<a.length;e++)if(c)a.charAt(e)=="'"&&!d("'")?c=!1:b+=a.charAt(e);else switch(a.charAt(e)){case"d":case"m":case"y":case"@":b+="0123456789";break;case"D":case"M":return null;case"'":d("'")?b+="'":c=!0;break;default:b+=a.charAt(e)}return b},_get:function(a,b){return a.settings[b]!==undefined?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),d=a.lastVal=a.input?a.input.val():null,e,f;e=f=this._getDefaultDate(a);var g=this._getFormatConfig(a);try{e=this.parseDate(c,d,g)||f}catch(h){this.log(h),d=b?"":d}a.selectedDay=e.getDate(),a.drawMonth=a.selectedMonth=e.getMonth(),a.drawYear=a.selectedYear=e.getFullYear(),a.currentDay=d?e.getDate():0,a.currentMonth=d?e.getMonth():0,a.currentYear=d?e.getFullYear():0,this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var d=function(a){var b=new Date;b.setDate(b.getDate()+a);return b},e=function(b){try{return $.datepicker.parseDate($.datepicker._get(a,"dateFormat"),b,$.datepicker._getFormatConfig(a))}catch(c){}var d=(b.toLowerCase().match(/^c/)?$.datepicker._getDate(a):null)||new Date,e=d.getFullYear(),f=d.getMonth(),g=d.getDate(),h=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,i=h.exec(b);while(i){switch(i[2]||"d"){case"d":case"D":g+=parseInt(i[1],10);break;case"w":case"W":g+=parseInt(i[1],10)*7;break;case"m":case"M":f+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f));break;case"y":case"Y":e+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f))}i=h.exec(b)}return new Date(e,f,g)},f=b==null||b===""?c:typeof b=="string"?e(b):typeof b=="number"?isNaN(b)?c:d(b):new Date(b.getTime());f=f&&f.toString()=="Invalid Date"?c:f,f&&(f.setHours(0),f.setMinutes(0),f.setSeconds(0),f.setMilliseconds(0));return this._daylightSavingAdjust(f)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),(e!=a.selectedMonth||f!=a.selectedYear)&&!c&&this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),d=this._get(a,"showButtonPanel"),e=this._get(a,"hideIfNoPrevNext"),f=this._get(a,"navigationAsDateFormat"),g=this._getNumberOfMonths(a),h=this._get(a,"showCurrentAtPos"),i=this._get(a,"stepMonths"),j=g[0]!=1||g[1]!=1,k=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),l=this._getMinMaxDate(a,"min"),m=this._getMinMaxDate(a,"max"),n=a.drawMonth-h,o=a.drawYear;n<0&&(n+=12,o--);if(m){var p=this._daylightSavingAdjust(new Date(m.getFullYear(),m.getMonth()-g[0]*g[1]+1,m.getDate()));p=l&&p<l?l:p;while(this._daylightSavingAdjust(new Date(o,n,1))>p)n--,n<0&&(n=11,o--)}a.drawMonth=n,a.drawYear=o;var q=this._get(a,"prevText");q=f?this.formatDate(q,this._daylightSavingAdjust(new Date(o,n-i,1)),this._getFormatConfig(a)):q;var r=this._canAdjustMonth(a,-1,o,n)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', -"+i+", 'M');\""+' title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>":e?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>",s=this._get(a,"nextText");s=f?this.formatDate(s,this._daylightSavingAdjust(new Date(o,n+i,1)),this._getFormatConfig(a)):s;var t=this._canAdjustMonth(a,1,o,n)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', +"+i+", 'M');\""+' title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>":e?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>",u=this._get(a,"currentText"),v=this._get(a,"gotoCurrent")&&a.currentDay?k:b;u=f?this.formatDate(u,v,this._getFormatConfig(a)):u;var w=a.inline?"":'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+dpuuid+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>",x=d?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?w:"")+(this._isInRange(a,v)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._gotoToday('#"+a.id+"');\""+">"+u+"</button>":"")+(c?"":w)+"</div>":"",y=parseInt(this._get(a,"firstDay"),10);y=isNaN(y)?0:y;var z=this._get(a,"showWeek"),A=this._get(a,"dayNames"),B=this._get(a,"dayNamesShort"),C=this._get(a,"dayNamesMin"),D=this._get(a,"monthNames"),E=this._get(a,"monthNamesShort"),F=this._get(a,"beforeShowDay"),G=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths"),I=this._get(a,"calculateWeek")||this.iso8601Week,J=this._getDefaultDate(a),K="";for(var L=0;L<g[0];L++){var M="";this.maxRows=4;for(var N=0;N<g[1];N++){var O=this._daylightSavingAdjust(new Date(o,n,a.selectedDay)),P=" ui-corner-all",Q="";if(j){Q+='<div class="ui-datepicker-group';if(g[1]>1)switch(N){case 0:Q+=" ui-datepicker-group-first",P=" ui-corner-"+(c?"right":"left");break;case g[1]-1:Q+=" ui-datepicker-group-last",P=" ui-corner-"+(c?"left":"right");break;default:Q+=" ui-datepicker-group-middle",P=""}Q+='">'}Q+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+P+'">'+(/all|left/.test(P)&&L==0?c?t:r:"")+(/all|right/.test(P)&&L==0?c?r:t:"")+this._generateMonthYearHeader(a,n,o,l,m,L>0||N>0,D,E)+'</div><table class="ui-datepicker-calendar"><thead>'+"<tr>";var R=z?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(var S=0;S<7;S++){var T=(S+y)%7;R+="<th"+((S+y+6)%7>=5?' class="ui-datepicker-week-end"':"")+">"+'<span title="'+A[T]+'">'+C[T]+"</span></th>"}Q+=R+"</tr></thead><tbody>";var U=this._getDaysInMonth(o,n);o==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,U));var V=(this._getFirstDayOfMonth(o,n)-y+7)%7,W=Math.ceil((V+U)/7),X=j?this.maxRows>W?this.maxRows:W:W;this.maxRows=X;var Y=this._daylightSavingAdjust(new Date(o,n,1-V));for(var Z=0;Z<X;Z++){Q+="<tr>";var _=z?'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(Y)+"</td>":"";for(var S=0;S<7;S++){var ba=F?F.apply(a.input?a.input[0]:null,[Y]):[!0,""],bb=Y.getMonth()!=n,bc=bb&&!H||!ba[0]||l&&Y<l||m&&Y>m;_+='<td class="'+((S+y+6)%7>=5?" ui-datepicker-week-end":"")+(bb?" ui-datepicker-other-month":"")+(Y.getTime()==O.getTime()&&n==a.selectedMonth&&a._keyEvent||J.getTime()==Y.getTime()&&J.getTime()==O.getTime()?" "+this._dayOverClass:"")+(bc?" "+this._unselectableClass+" ui-state-disabled":"")+(bb&&!G?"":" "+ba[1]+(Y.getTime()==k.getTime()?" "+this._currentClass:"")+(Y.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!bb||G)&&ba[2]?' title="'+ba[2]+'"':"")+(bc?"":' onclick="DP_jQuery_'+dpuuid+".datepicker._selectDay('#"+a.id+"',"+Y.getMonth()+","+Y.getFullYear()+', this);return false;"')+">"+(bb&&!G?"&#xa0;":bc?'<span class="ui-state-default">'+Y.getDate()+"</span>":'<a class="ui-state-default'+(Y.getTime()==b.getTime()?" ui-state-highlight":"")+(Y.getTime()==k.getTime()?" ui-state-active":"")+(bb?" ui-priority-secondary":"")+'" href="#">'+Y.getDate()+"</a>")+"</td>",Y.setDate(Y.getDate()+1),Y=this._daylightSavingAdjust(Y)}Q+=_+"</tr>"}n++,n>11&&(n=0,o++),Q+="</tbody></table>"+(j?"</div>"+(g[0]>0&&N==g[1]-1?'<div class="ui-datepicker-row-break"></div>':""):""),M+=Q}K+=M}K+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':""),
-a._keyEvent=!1;return K},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i=this._get(a,"changeMonth"),j=this._get(a,"changeYear"),k=this._get(a,"showMonthAfterYear"),l='<div class="ui-datepicker-title">',m="";if(f||!i)m+='<span class="ui-datepicker-month">'+g[b]+"</span>";else{var n=d&&d.getFullYear()==c,o=e&&e.getFullYear()==c;m+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" "+">";for(var p=0;p<12;p++)(!n||p>=d.getMonth())&&(!o||p<=e.getMonth())&&(m+='<option value="'+p+'"'+(p==b?' selected="selected"':"")+">"+h[p]+"</option>");m+="</select>"}k||(l+=m+(f||!i||!j?"&#xa0;":""));if(!a.yearshtml){a.yearshtml="";if(f||!j)l+='<span class="ui-datepicker-year">'+c+"</span>";else{var q=this._get(a,"yearRange").split(":"),r=(new Date).getFullYear(),s=function(a){var b=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?r+parseInt(a,10):parseInt(a,10);return isNaN(b)?r:b},t=s(q[0]),u=Math.max(t,s(q[1]||""));t=d?Math.max(t,d.getFullYear()):t,u=e?Math.min(u,e.getFullYear()):u,a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" "+">";for(;t<=u;t++)a.yearshtml+='<option value="'+t+'"'+(t==c?' selected="selected"':"")+">"+t+"</option>";a.yearshtml+="</select>",l+=a.yearshtml,a.yearshtml=null}}l+=this._get(a,"yearSuffix"),k&&(l+=(f||!i||!j?"&#xa0;":"")+m),l+="</div>";return l},_adjustInstDate:function(a,b,c){var d=a.drawYear+(c=="Y"?b:0),e=a.drawMonth+(c=="M"?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+(c=="D"?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),(c=="M"||c=="Y")&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&b<c?c:b;e=d&&e>d?d:e;return e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(b<0?b:e[0]*e[1]),1));b<0&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth()));return this._isInRange(a,f)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),$.fn.datepicker=function(a){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv),$.datepicker.initialized=!0);var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));return this.each(function(){typeof a=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this].concat(b)):$.datepicker._attachDatepicker(this,a)})},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.8.18",window["DP_jQuery_"+dpuuid]=$})(jQuery);/*
- * jQuery UI Progressbar 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Progressbar
- *
- * Depends:
- * jquery.ui.core.js
- * jquery.ui.widget.js
- */(function(a,b){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=a("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove(),a.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===b)return this._value();this._setOption("value",a);return this},_setOption:function(b,c){b==="value"&&(this.options.value=c,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;typeof a!="number"&&(a=0);return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change")),this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%"),this.element.attr("aria-valuenow",a)}}),a.extend(a.ui.progressbar,{version:"1.8.18"})})(jQuery);/*
- * jQuery UI Effects 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/
- */jQuery.effects||function(a,b){function l(b){if(!b||typeof b=="number"||a.fx.speeds[b])return!0;if(typeof b=="string"&&!a.effects[b])return!0;return!1}function k(b,c,d,e){typeof b=="object"&&(e=c,d=null,c=b,b=c.effect),a.isFunction(c)&&(e=c,d=null,c={});if(typeof c=="number"||a.fx.speeds[c])e=d,d=c,c={};a.isFunction(d)&&(e=d,d=null),c=c||{},d=d||c.duration,d=a.fx.off?0:typeof d=="number"?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,e=e||c.complete;return[b,c,d,e]}function j(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function i(b){var c,d;for(c in b)d=b[c],(d==null||a.isFunction(d)||c in g||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete b[c];return b}function h(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]]){var e=a.length;while(e--)c=a[e],typeof a[c]=="string"&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c])}else for(c in a)typeof a[c]=="string"&&(b[c]=a[c]);return b}function d(b,d){var e;do{e=a.curCSS(b,d);if(e!=""&&e!="transparent"||a.nodeName(b,"body"))break;d="backgroundColor"}while(b=b.parentNode);return c(e)}function c(b){var c;if(b&&b.constructor==Array&&b.length==3)return b;if(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))return[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)];if(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))return[parseFloat(c[1])*2.55,parseFloat(c[2])*2.55,parseFloat(c[3])*2.55];if(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))return[parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)];if(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))return[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)];if(c=/rgba\(0, 0, 0, 0\)/.exec(b))return e.transparent;return e[a.trim(b).toLowerCase()]}a.effects={},a.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(b,e){a.fx.step[e]=function(a){a.colorInit||(a.start=d(a.elem,e),a.end=c(a.end),a.colorInit=!0),a.elem.style[e]="rgb("+Math.max(Math.min(parseInt(a.pos*(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var e={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},f=["add","remove","toggle"],g={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(b,c,d,e){a.isFunction(d)&&(e=d,d=null);return this.queue(function(){var g=a(this),k=g.attr("style")||" ",l=i(h.call(this)),m,n=g.attr("class");a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),m=i(h.call(this)),g.attr("class",n),g.animate(j(l,m),{queue:!1,duration:c,easing:d,complete:function(){a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),typeof g.attr("style")=="object"?(g.attr("style").cssText="",g.attr("style").cssText=k):g.attr("style",k),e&&e.apply(this,arguments),a.dequeue(this)}})})},a.fn.extend({_addClass:a.fn.addClass,addClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{add:b},c,d,e]):this._addClass(b)},_removeClass:a.fn.removeClass,removeClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{remove:b},c,d,e]):this._removeClass(b)},_toggleClass:a.fn.toggleClass,toggleClass:function(c,d,e,f,g){return typeof d=="boolean"||d===b?e?a.effects.animateClass.apply(this,[d?{add:c}:{remove:c},e,f,g]):this._toggleClass(c,d):a.effects.animateClass.apply(this,[{toggle:c},d,e,f])},switchClass:function(b,c,d,e,f){return a.effects.animateClass.apply(this,[{add:c,remove:b},d,e,f])}}),a.extend(a.effects,{version:"1.8.18",save:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.data("ec.storage."+b[c],a[0].style[b[c]])},restore:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.css(b[c],a.data("ec.storage."+b[c]))},setMode:function(a,b){b=="toggle"&&(b=a.is(":hidden")?"show":"hide");return b},getBaseline:function(a,b){var c,d;switch(a[0]){case"top":c=0;break;case"middle":c=.5;break;case"bottom":c=1;break;default:c=a[0]/b.height}switch(a[1]){case"left":d=0;break;case"center":d=.5;break;case"right":d=1;break;default:d=a[1]/b.width}return{x:d,y:c}},createWrapper:function(b){if(b.parent().is(".ui-effects-wrapper"))return b.parent();var c={width:b.outerWidth(!0),height:b.outerHeight(!0),"float":b.css("float")},d=a("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e=document.activeElement;b.wrap(d),(b[0]===e||a.contains(b[0],e))&&a(e).focus(),d=b.parent(),b.css("position")=="static"?(d.css({position:"relative"}),b.css({position:"relative"})):(a.extend(c,{position:b.css("position"),zIndex:b.css("z-index")}),a.each(["top","left","bottom","right"],function(a,d){c[d]=b.css(d),isNaN(parseInt(c[d],10))&&(c[d]="auto")}),b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"}));return d.css(c).show()},removeWrapper:function(b){var c,d=document.activeElement;if(b.parent().is(".ui-effects-wrapper")){c=b.parent().replaceWith(b),(b[0]===d||a.contains(b[0],d))&&a(d).focus();return c}return b},setTransition:function(b,c,d,e){e=e||{},a.each(c,function(a,c){unit=b.cssUnit(c),unit[0]>0&&(e[c]=unit[0]*d+unit[1])});return e}}),a.fn.extend({effect:function(b,c,d,e){var f=k.apply(this,arguments),g={options:f[1],duration:f[2],callback:f[3]},h=g.options.mode,i=a.effects[b];if(a.fx.off||!i)return h?this[h](g.duration,g.callback):this.each(function(){g.callback&&g.callback.call(this)});return i.call(this,g)},_show:a.fn.show,show:function(a){if(l(a))return this._show.apply(this,arguments);var b=k.apply(this,arguments);b[1].mode="show";return this.effect.apply(this,b)},_hide:a.fn.hide,hide:function(a){if(l(a))return this._hide.apply(this,arguments);var b=k.apply(this,arguments);b[1].mode="hide";return this.effect.apply(this,b)},__toggle:a.fn.toggle,toggle:function(b){if(l(b)||typeof b=="boolean"||a.isFunction(b))return this.__toggle.apply(this,arguments);var c=k.apply(this,arguments);c[1].mode="toggle";return this.effect.apply(this,c)},cssUnit:function(b){var c=this.css(b),d=[];a.each(["em","px","%","pt"],function(a,b){c.indexOf(b)>0&&(d=[parseFloat(c),b])});return d}}),a.easing.jswing=a.easing.swing,a.extend(a.easing,{def:"easeOutQuad",swing:function(b,c,d,e,f){return a.easing[a.easing.def](b,c,d,e,f)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b+c;return-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b+c;return d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b*b+c;return-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b*b*b+c;return d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return b==0?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){if(b==0)return c;if(b==e)return c+d;if((b/=e/2)<1)return d/2*Math.pow(2,10*(b-1))+c;return d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){if((b/=e/2)<1)return-d/2*(Math.sqrt(1-b*b)-1)+c;return d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g))+c},easeOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*b)*Math.sin((b*e-f)*2*Math.PI/g)+d+c},easeInOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e/2)==2)return c+d;g||(g=e*.3*1.5);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);if(b<1)return-0.5*h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)+c;return h*Math.pow(2,-10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)*.5+d+c},easeInBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);return e*(c/=f)*c*((g+1)*c-g)+d},easeOutBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);return e*((c=c/f-1)*c*((g+1)*c+g)+1)+d},easeInOutBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);if((c/=f/2)<1)return e/2*c*c*(((g*=1.525)+1)*c-g)+d;return e/2*((c-=2)*c*(((g*=1.525)+1)*c+g)+2)+d},easeInBounce:function(b,c,d,e,f){return e-a.easing.easeOutBounce(b,f-c,0,e,f)+d},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*7.5625*b*b+c:b<2/2.75?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:b<2.5/2.75?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c},easeInOutBounce:function(b,c,d,e,f){if(c<f/2)return a.easing.easeInBounce(b,c*2,0,e,f)*.5+d;return a.easing.easeOutBounce(b,c*2-f,0,e,f)*.5+e*.5+d}})}(jQuery);/*
- * jQuery UI Effects Blind 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Blind
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.blind=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=f=="vertical"?"height":"width",i=f=="vertical"?g.height():g.width();e=="show"&&g.css(h,0);var j={};j[h]=e=="show"?i:0,g.animate(j,b.duration,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);/*
- * jQuery UI Effects Bounce 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Bounce
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.bounce=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"up",g=b.options.distance||20,h=b.options.times||5,i=b.duration||250;/show|hide/.test(e)&&d.push("opacity"),a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",g=b.options.distance||(j=="top"?c.outerHeight({margin:!0})/3:c.outerWidth({margin:!0})/3);e=="show"&&c.css("opacity",0).css(j,k=="pos"?-g:g),e=="hide"&&(g=g/(h*2)),e!="hide"&&h--;if(e=="show"){var l={opacity:1};l[j]=(k=="pos"?"+=":"-=")+g,c.animate(l,i/2,b.options.easing),g=g/2,h--}for(var m=0;m<h;m++){var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing),g=e=="hide"?g*2:g/2}if(e=="hide"){var l={opacity:0};l[j]=(k=="pos"?"-=":"+=")+g,c.animate(l,i/2,b.options.easing,function(){c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}else{var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}c.queue("fx",function(){c.dequeue()}),c.dequeue()})}})(jQuery);/*
- * jQuery UI Effects Clip 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Clip
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.clip=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","height","width"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=c[0].tagName=="IMG"?g:c,i={size:f=="vertical"?"height":"width",position:f=="vertical"?"top":"left"},j=f=="vertical"?h.height():h.width();e=="show"&&(h.css(i.size,0),h.css(i.position,j/2));var k={};k[i.size]=e=="show"?j:0,k[i.position]=e=="show"?0:j/2,h.animate(k,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()}})})}})(jQuery);/*
- * jQuery UI Effects Drop 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Drop
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.drop=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","opacity"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight({margin:!0})/2:c.outerWidth({margin:!0})/2);e=="show"&&c.css("opacity",0).css(g,h=="pos"?-i:i);var j={opacity:e=="show"?1:0};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/*
- * jQuery UI Effects Explode 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Explode
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.explode=function(b){return this.queue(function(){var c=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3,d=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;b.options.mode=b.options.mode=="toggle"?a(this).is(":visible")?"hide":"show":b.options.mode;var e=a(this).show().css("visibility","hidden"),f=e.offset();f.top-=parseInt(e.css("marginTop"),10)||0,f.left-=parseInt(e.css("marginLeft"),10)||0;var g=e.outerWidth(!0),h=e.outerHeight(!0);for(var i=0;i<c;i++)for(var j=0;j<d;j++)e.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-j*(g/d),top:-i*(h/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/d,height:h/c,left:f.left+j*(g/d)+(b.options.mode=="show"?(j-Math.floor(d/2))*(g/d):0),top:f.top+i*(h/c)+(b.options.mode=="show"?(i-Math.floor(c/2))*(h/c):0),opacity:b.options.mode=="show"?0:1}).animate({left:f.left+j*(g/d)+(b.options.mode=="show"?0:(j-Math.floor(d/2))*(g/d)),top:f.top+i*(h/c)+(b.options.mode=="show"?0:(i-Math.floor(c/2))*(h/c)),opacity:b.options.mode=="show"?1:0},b.duration||500);setTimeout(function(){b.options.mode=="show"?e.css({visibility:"visible"}):e.css({visibility:"visible"}).hide(),b.callback&&b.callback.apply(e[0]),e.dequeue(),a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);/*
- * jQuery UI Effects Fade 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Fade
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.fade=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide");c.animate({opacity:d},{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/*
- * jQuery UI Effects Fold 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Fold
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.fold=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.size||15,g=!!b.options.horizFirst,h=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(c,d),c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"}),j=e=="show"!=g,k=j?["width","height"]:["height","width"],l=j?[i.width(),i.height()]:[i.height(),i.width()],m=/([0-9]+)%/.exec(f);m&&(f=parseInt(m[1],10)/100*l[e=="hide"?0:1]),e=="show"&&i.css(g?{height:0,width:f}:{height:f,width:0});var n={},p={};n[k[0]]=e=="show"?l[0]:f,p[k[1]]=e=="show"?l[1]:0,i.animate(n,h,b.options.easing).animate(p,h,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);/*
- * jQuery UI Effects Highlight 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Highlight
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.highlight=function(b){return this.queue(function(){var c=a(this),d=["backgroundImage","backgroundColor","opacity"],e=a.effects.setMode(c,b.options.mode||"show"),f={backgroundColor:c.css("backgroundColor")};e=="hide"&&(f.opacity=0),a.effects.save(c,d),c.show().css({backgroundImage:"none",backgroundColor:b.options.color||"#ffff99"}).animate(f,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),e=="show"&&!a.support.opacity&&this.style.removeAttribute("filter"),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/*
- * jQuery UI Effects Pulsate 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Pulsate
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.pulsate=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"show");times=(b.options.times||5)*2-1,duration=b.duration?b.duration/2:a.fx.speeds._default/2,isVisible=c.is(":visible"),animateTo=0,isVisible||(c.css("opacity",0).show(),animateTo=1),(d=="hide"&&isVisible||d=="show"&&!isVisible)&&times--;for(var e=0;e<times;e++)c.animate({opacity:animateTo},duration,b.options.easing),animateTo=(animateTo+1)%2;c.animate({opacity:animateTo},duration,b.options.easing,function(){animateTo==0&&c.hide(),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}).dequeue()})}})(jQuery);/*
- * jQuery UI Effects Scale 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Scale
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.puff=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide"),e=parseInt(b.options.percent,10)||150,f=e/100,g={height:c.height(),width:c.width()};a.extend(b.options,{fade:!0,mode:d,percent:d=="hide"?e:100,from:d=="hide"?g:{height:g.height*f,width:g.width*f}}),c.effect("scale",b.options,b.duration,b.callback),c.dequeue()})},a.effects.scale=function(b){return this.queue(function(){var c=a(this),d=a.extend(!0,{},b.options),e=a.effects.setMode(c,b.options.mode||"effect"),f=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:e=="hide"?0:100),g=b.options.direction||"both",h=b.options.origin;e!="effect"&&(d.origin=h||["middle","center"],d.restore=!0);var i={height:c.height(),width:c.width()};c.from=b.options.from||(e=="show"?{height:0,width:0}:i);var j={y:g!="horizontal"?f/100:1,x:g!="vertical"?f/100:1};c.to={height:i.height*j.y,width:i.width*j.x},b.options.fade&&(e=="show"&&(c.from.opacity=0,c.to.opacity=1),e=="hide"&&(c.from.opacity=1,c.to.opacity=0)),d.from=c.from,d.to=c.to,d.mode=e,c.effect("size",d,b.duration,b.callback),c.dequeue()})},a.effects.size=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","width","height","overflow","opacity"],e=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],g=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],i=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],j=a.effects.setMode(c,b.options.mode||"effect"),k=b.options.restore||!1,l=b.options.scale||"both",m=b.options.origin,n={height:c.height(),width:c.width()};c.from=b.options.from||n,c.to=b.options.to||n;if(m){var p=a.effects.getBaseline(m,n);c.from.top=(n.height-c.from.height)*p.y,c.from.left=(n.width-c.from.width)*p.x,c.to.top=(n.height-c.to.height)*p.y,c.to.left=(n.width-c.to.width)*p.x}var q={from:{y:c.from.height/n.height,x:c.from.width/n.width},to:{y:c.to.height/n.height,x:c.to.width/n.width}};if(l=="box"||l=="both")q.from.y!=q.to.y&&(d=d.concat(h),c.from=a.effects.setTransition(c,h,q.from.y,c.from),c.to=a.effects.setTransition(c,h,q.to.y,c.to)),q.from.x!=q.to.x&&(d=d.concat(i),c.from=a.effects.setTransition(c,i,q.from.x,c.from),c.to=a.effects.setTransition(c,i,q.to.x,c.to));(l=="content"||l=="both")&&q.from.y!=q.to.y&&(d=d.concat(g),c.from=a.effects.setTransition(c,g,q.from.y,c.from),c.to=a.effects.setTransition(c,g,q.to.y,c.to)),a.effects.save(c,k?d:e),c.show(),a.effects.createWrapper(c),c.css("overflow","hidden").css(c.from);if(l=="content"||l=="both")h=h.concat(["marginTop","marginBottom"]).concat(g),i=i.concat(["marginLeft","marginRight"]),f=d.concat(h).concat(i),c.find("*[width]").each(function(){child=a(this),k&&a.effects.save(child,f);var c={height:child.height(),width:child.width()};child.from={height:c.height*q.from.y,width:c.width*q.from.x},child.to={height:c.height*q.to.y,width:c.width*q.to.x},q.from.y!=q.to.y&&(child.from=a.effects.setTransition(child,h,q.from.y,child.from),child.to=a.effects.setTransition(child,h,q.to.y,child.to)),q.from.x!=q.to.x&&(child.from=a.effects.setTransition(child,i,q.from.x,child.from),child.to=a.effects.setTransition(child,i,q.to.x,child.to)),child.css(child.from),child.animate(child.to,b.duration,b.options.easing,function(){k&&a.effects.restore(child,f)})});c.animate(c.to,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){c.to.opacity===0&&c.css("opacity",c.from.opacity),j=="hide"&&c.hide(),a.effects.restore(c,k?d:e),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/*
- * jQuery UI Effects Shake 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Shake
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.shake=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"left",g=b.options.distance||20,h=b.options.times||3,i=b.duration||b.options.duration||140;a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",l={},m={},n={};l[j]=(k=="pos"?"-=":"+=")+g,m[j]=(k=="pos"?"+=":"-=")+g*2,n[j]=(k=="pos"?"-=":"+=")+g*2,c.animate(l,i,b.options.easing);for(var p=1;p<h;p++)c.animate(m,i,b.options.easing).animate(n,i,b.options.easing);c.animate(m,i,b.options.easing).animate(l,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}),c.dequeue()})}})(jQuery);/*
- * jQuery UI Effects Slide 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Slide
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.slide=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"show"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c).css({overflow:"hidden"});var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight({margin:!0}):c.outerWidth({margin:!0}));e=="show"&&c.css(g,h=="pos"?isNaN(i)?"-"+i:-i:i);var j={};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/*
- * jQuery UI Effects Transfer 1.8.18
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Transfer
- *
- * Depends:
- * jquery.effects.core.js
- */(function(a,b){a.effects.transfer=function(b){return this.queue(function(){var c=a(this),d=a(b.options.to),e=d.offset(),f={top:e.top,left:e.left,height:d.innerHeight(),width:d.innerWidth()},g=c.offset(),h=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(f,b.duration,b.options.easing,function(){h.remove(),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery); \ No newline at end of file
diff --git a/storage/mroonga/vendor/groonga/groonga-arrow.pc.in b/storage/mroonga/vendor/groonga/groonga-arrow.pc.in
new file mode 100644
index 00000000000..d0b22f65b3a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/groonga-arrow.pc.in
@@ -0,0 +1,4 @@
+Name: Groonga Arrow
+Description: Apache Arrow support for Groonga
+Version: @VERSION@
+Requires: groonga arrow
diff --git a/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in b/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in
index 73b8867eafa..4dbb400fb77 100644
--- a/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in
+++ b/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in
@@ -20,7 +20,7 @@ export GROONGA_HTTPD_ERROR_LOG_PATH="${localstatedir}/log/groonga/httpd/error.lo
export GROONGA_HTTPD_HTTP_LOG_PATH="${localstatedir}/log/groonga/httpd/access.log"
export GROONGA_HTTPD_GROONGA_LOG_PATH="${localstatedir}/log/groonga/httpd/groonga.log"
export GROONGA_HTTPD_GROONGA_QUERY_LOG_PATH="${localstatedir}/log/groonga/httpd/groonga-query.log"
-export GROONGA_HTTPD_PID_PATH="${localstatedir}/run/groonga/groonga-httpd.pid"
+export GROONGA_HTTPD_PID_PATH="@GROONGA_HTTPD_PID_PATH@"
export GROONGA_HTTPD_DEBUG="@grn_debug@"
export GROONGA_HTTPD_WITH_PCRE="@GRN_WITH_PCRE@"
export GROONGA_HTTPD_PCRE_CFLAGS="@PCRE_CFLAGS@"
@@ -28,3 +28,7 @@ export GROONGA_HTTPD_PCRE_LIBS_ONLY_L="@PCRE_LIBS_ONLY_L@"
export GROONGA_HTTPD_WITH_ONIGMO="@GRN_WITH_ONIGMO@"
export GROONGA_HTTPD_ONIGMO_IN_TREE_LINK_PATH="@abs_top_builddir@/vendor/onigmo-source/.libs"
export GROONGA_HTTPD_WITH_ZLIB="@GRN_WITH_ZLIB@"
+export GROONGA_HTTPD_WITH_SSL="@GRN_WITH_SSL@"
+export GROONGA_HTTPD_SSL_CFLAGS="@SSL_CFLAGS@"
+export GROONGA_HTTPD_SSL_LIBS_ONLY_L="@SSL_LIBS_ONLY_L@"
+export GROONGA_HTTPD_WITH_MRUBY="@GRN_WITH_MRUBY@"
diff --git a/storage/mroonga/vendor/groonga/include/Makefile.am b/storage/mroonga/vendor/groonga/include/Makefile.am
index 19ced0d2d6c..c7dee7100d2 100644
--- a/storage/mroonga/vendor/groonga/include/Makefile.am
+++ b/storage/mroonga/vendor/groonga/include/Makefile.am
@@ -1,6 +1,8 @@
SUBDIRS = groonga
-pkginclude_HEADERS = groonga.h
+pkginclude_HEADERS = \
+ groonga.h \
+ groonga.hpp
EXTRA_DIST = \
CMakeLists.txt
diff --git a/storage/mroonga/vendor/groonga/include/groonga.h b/storage/mroonga/vendor/groonga/include/groonga.h
index db2303a32c6..6e1be29d279 100644
--- a/storage/mroonga/vendor/groonga/include/groonga.h
+++ b/storage/mroonga/vendor/groonga/include/groonga.h
@@ -1,5 +1,5 @@
/*
- Copyright(C) 2014-2015 Brazil
+ Copyright(C) 2014-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,16 +15,39 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_H
-#define GROONGA_H
+
+#pragma once
#include "groonga/portability.h"
#include "groonga/groonga.h"
-#include "groonga/obj.h"
-#include "groonga/ii.h"
+
+#include "groonga/accessor.h"
+#include "groonga/array.h"
+#include "groonga/arrow.h"
+#include "groonga/cache.h"
+#include "groonga/column.h"
+#include "groonga/config.h"
+#include "groonga/dat.h"
+#include "groonga/db.h"
+#include "groonga/dump.h"
+#include "groonga/error.h"
#include "groonga/expr.h"
+#include "groonga/file_reader.h"
+#include "groonga/geo.h"
+#include "groonga/hash.h"
+#include "groonga/id.h"
+#include "groonga/ii.h"
+#include "groonga/obj.h"
+#include "groonga/operator.h"
#include "groonga/output.h"
-#include "groonga/util.h"
+#include "groonga/pat.h"
#include "groonga/request_canceler.h"
-
-#endif /* GROONGA_H */
+#include "groonga/request_timer.h"
+#include "groonga/table.h"
+#include "groonga/thread.h"
+#include "groonga/time.h"
+#include "groonga/type.h"
+#include "groonga/util.h"
+#include "groonga/window_function.h"
+#include "groonga/windows.h"
+#include "groonga/windows_event_logger.h"
diff --git a/storage/mroonga/vendor/groonga/include/groonga.hpp b/storage/mroonga/vendor/groonga/include/groonga.hpp
new file mode 100644
index 00000000000..3d8313b4e37
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga.hpp
@@ -0,0 +1,21 @@
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "groonga.h"
diff --git a/storage/mroonga/vendor/groonga/include/groonga/Makefile.am b/storage/mroonga/vendor/groonga/include/groonga/Makefile.am
index 37a2b6f45a8..7cc4d56ef46 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/Makefile.am
+++ b/storage/mroonga/vendor/groonga/include/groonga/Makefile.am
@@ -1,18 +1,43 @@
groonga_includedir = $(pkgincludedir)/groonga
groonga_include_HEADERS = \
+ accessor.h \
+ array.h \
+ arrow.h \
+ arrow.hpp \
+ cache.h \
+ column.h \
command.h \
+ config.h \
+ dat.h \
+ db.h \
+ dump.h \
+ error.h \
expr.h \
+ file_reader.h \
+ hash.h \
+ geo.h \
groonga.h \
+ id.h \
ii.h \
obj.h \
+ operator.h \
output.h \
+ pat.h \
plugin.h \
portability.h \
request_canceler.h \
+ request_timer.h \
scorer.h \
+ table.h \
+ thread.h \
+ time.h \
token.h \
tokenizer.h \
token_filter.h \
+ type.h \
nfkc.h \
normalizer.h \
- util.h
+ util.h \
+ window_function.h \
+ windows.h \
+ windows_event_logger.h
diff --git a/storage/mroonga/vendor/groonga/include/groonga/accessor.h b/storage/mroonga/vendor/groonga/include/groonga/accessor.h
new file mode 100644
index 00000000000..43953287bef
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/accessor.h
@@ -0,0 +1,34 @@
+/*
+ Copyright(C) 2012-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API grn_rc grn_accessor_resolve(grn_ctx *ctx,
+ grn_obj *accessor,
+ int deep,
+ grn_obj *base_res,
+ grn_obj *res,
+ grn_operator op);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/array.h b/storage/mroonga/vendor/groonga/include/groonga/array.h
new file mode 100644
index 00000000000..9c5e5c02ada
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/array.h
@@ -0,0 +1,89 @@
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _grn_array grn_array;
+typedef struct _grn_array_cursor grn_array_cursor;
+
+GRN_API grn_array *grn_array_create(grn_ctx *ctx, const char *path,
+ unsigned int value_size, unsigned int flags);
+GRN_API grn_array *grn_array_open(grn_ctx *ctx, const char *path);
+GRN_API grn_rc grn_array_close(grn_ctx *ctx, grn_array *array);
+GRN_API grn_id grn_array_add(grn_ctx *ctx, grn_array *array, void **value);
+GRN_API grn_id grn_array_push(grn_ctx *ctx, grn_array *array,
+ void (*func)(grn_ctx *ctx, grn_array *array,
+ grn_id id, void *func_arg),
+ void *func_arg);
+GRN_API grn_id grn_array_pull(grn_ctx *ctx, grn_array *array, grn_bool blockp,
+ void (*func)(grn_ctx *ctx, grn_array *array,
+ grn_id id, void *func_arg),
+ void *func_arg);
+GRN_API void grn_array_unblock(grn_ctx *ctx, grn_array *array);
+GRN_API int grn_array_get_value(grn_ctx *ctx, grn_array *array, grn_id id, void *valuebuf);
+GRN_API grn_rc grn_array_set_value(grn_ctx *ctx, grn_array *array, grn_id id,
+ const void *value, int flags);
+GRN_API grn_array_cursor *grn_array_cursor_open(grn_ctx *ctx, grn_array *array,
+ grn_id min, grn_id max,
+ int offset, int limit, int flags);
+GRN_API grn_id grn_array_cursor_next(grn_ctx *ctx, grn_array_cursor *cursor);
+GRN_API int grn_array_cursor_get_value(grn_ctx *ctx, grn_array_cursor *cursor, void **value);
+GRN_API grn_rc grn_array_cursor_set_value(grn_ctx *ctx, grn_array_cursor *cursor,
+ const void *value, int flags);
+GRN_API grn_rc grn_array_cursor_delete(grn_ctx *ctx, grn_array_cursor *cursor,
+ grn_table_delete_optarg *optarg);
+GRN_API void grn_array_cursor_close(grn_ctx *ctx, grn_array_cursor *cursor);
+GRN_API grn_rc grn_array_delete_by_id(grn_ctx *ctx, grn_array *array, grn_id id,
+ grn_table_delete_optarg *optarg);
+
+GRN_API grn_id grn_array_next(grn_ctx *ctx, grn_array *array, grn_id id);
+
+GRN_API void *_grn_array_get_value(grn_ctx *ctx, grn_array *array, grn_id id);
+
+#define GRN_ARRAY_EACH(ctx,array,head,tail,id,value,block) do {\
+ grn_array_cursor *_sc = grn_array_cursor_open(ctx, array, head, tail, 0, -1, 0); \
+ if (_sc) {\
+ grn_id id;\
+ while ((id = grn_array_cursor_next(ctx, _sc))) {\
+ grn_array_cursor_get_value(ctx, _sc, (void **)(value));\
+ block\
+ }\
+ grn_array_cursor_close(ctx, _sc); \
+ }\
+} while (0)
+
+#define GRN_ARRAY_EACH_BEGIN(ctx, array, cursor, head, tail, id) do {\
+ grn_array_cursor *cursor;\
+ cursor = grn_array_cursor_open((ctx), (array), (head), (tail), 0, -1, 0);\
+ if (cursor) {\
+ grn_id id;\
+ while ((id = grn_array_cursor_next(ctx, cursor))) {
+
+#define GRN_ARRAY_EACH_END(ctx, cursor)\
+ }\
+ grn_array_cursor_close(ctx, cursor);\
+ }\
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/arrow.h b/storage/mroonga/vendor/groonga/include/groonga/arrow.h
new file mode 100644
index 00000000000..248b44df43c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/arrow.h
@@ -0,0 +1,38 @@
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API grn_rc grn_arrow_load(grn_ctx *ctx,
+ grn_obj *table,
+ const char *path);
+GRN_API grn_rc grn_arrow_dump(grn_ctx *ctx,
+ grn_obj *table,
+ const char *path);
+GRN_API grn_rc grn_arrow_dump_columns(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *columns,
+ const char *path);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/arrow.hpp b/storage/mroonga/vendor/groonga/include/groonga/arrow.hpp
new file mode 100644
index 00000000000..a35a4aba61d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/arrow.hpp
@@ -0,0 +1,21 @@
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include <groonga.hpp>
diff --git a/storage/mroonga/vendor/groonga/include/groonga/cache.h b/storage/mroonga/vendor/groonga/include/groonga/cache.h
new file mode 100644
index 00000000000..bba72243fd7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/cache.h
@@ -0,0 +1,49 @@
+/*
+ Copyright(C) 2013-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_CACHE_DEFAULT_MAX_N_ENTRIES 100
+typedef struct _grn_cache grn_cache;
+
+GRN_API void grn_set_default_cache_base_path(const char *base_path);
+GRN_API const char *grn_get_default_cache_base_path(void);
+
+GRN_API grn_cache *grn_cache_open(grn_ctx *ctx);
+GRN_API grn_cache *grn_persistent_cache_open(grn_ctx *ctx,
+ const char *base_path);
+GRN_API grn_rc grn_cache_close(grn_ctx *ctx, grn_cache *cache);
+
+GRN_API grn_rc grn_cache_current_set(grn_ctx *ctx, grn_cache *cache);
+GRN_API grn_cache *grn_cache_current_get(grn_ctx *ctx);
+
+GRN_API grn_rc grn_cache_default_reopen(void);
+
+GRN_API grn_rc grn_cache_set_max_n_entries(grn_ctx *ctx,
+ grn_cache *cache,
+ unsigned int n);
+GRN_API unsigned int grn_cache_get_max_n_entries(grn_ctx *ctx,
+ grn_cache *cache);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/column.h b/storage/mroonga/vendor/groonga/include/groonga/column.h
new file mode 100644
index 00000000000..434543c2235
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/column.h
@@ -0,0 +1,29 @@
+/*
+ Copyright(C) 2009-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API grn_column_flags grn_column_get_flags(grn_ctx *ctx, grn_obj *column);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/command.h b/storage/mroonga/vendor/groonga/include/groonga/command.h
index ac5270e9798..6e0880965d9 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/command.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/command.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_COMMAND_H
-#define GROONGA_COMMAND_H
+
+#pragma once
#include <groonga/plugin.h>
@@ -77,5 +77,3 @@ GRN_PLUGIN_EXPORT grn_rc grn_command_run(grn_ctx *ctx,
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
-
-#endif /* GROONGA_COMMAND_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/config.h b/storage/mroonga/vendor/groonga/include/groonga/config.h
new file mode 100644
index 00000000000..8a8a5fc3f91
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/config.h
@@ -0,0 +1,65 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_CONFIG_MAX_KEY_SIZE GRN_TABLE_MAX_KEY_SIZE
+#define GRN_CONFIG_MAX_VALUE_SIZE \
+ (GRN_CONFIG_VALUE_SPACE_SIZE - sizeof(uint32_t) - 1) /* 1 is for '\0' */
+#define GRN_CONFIG_VALUE_SPACE_SIZE (4 * 1024)
+
+GRN_API grn_rc grn_config_set(grn_ctx *ctx,
+ const char *key, int32_t key_size,
+ const char *value, int32_t value_size);
+GRN_API grn_rc grn_config_get(grn_ctx *ctx,
+ const char *key, int32_t key_size,
+ const char **value, uint32_t *value_size);
+
+
+GRN_API grn_rc grn_config_delete(grn_ctx *ctx,
+ const char *key, int32_t key_size);
+
+GRN_API grn_obj *grn_config_cursor_open(grn_ctx *ctx);
+GRN_API grn_bool grn_config_cursor_next(grn_ctx *ctx, grn_obj *cursor);
+GRN_API uint32_t grn_config_cursor_get_key(grn_ctx *ctx,
+ grn_obj *cursor,
+ const char **key);
+GRN_API uint32_t grn_config_cursor_get_value(grn_ctx *ctx,
+ grn_obj *cursor,
+ const char **value);
+
+/* Deprecated since 5.1.2. Use GRN_CONFIG_* instead. */
+
+#define GRN_CONF_MAX_KEY_SIZE GRN_CONFIG_MAX_KEY_SIZE
+#define GRN_CONF_MAX_VALUE_SIZE GRN_CONFIG_MAX_VALUE_SIZE
+#define GRN_CONF_VALUE_SPACE_SIZE GRN_CONFIG_VALUE_SPACE_SIZE
+
+GRN_API grn_rc grn_conf_set(grn_ctx *ctx,
+ const char *key, int32_t key_size,
+ const char *value, int32_t value_size);
+GRN_API grn_rc grn_conf_get(grn_ctx *ctx,
+ const char *key, int32_t key_size,
+ const char **value, uint32_t *value_size);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/dat.h b/storage/mroonga/vendor/groonga/include/groonga/dat.h
new file mode 100644
index 00000000000..164c7e7935e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/dat.h
@@ -0,0 +1,100 @@
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _grn_dat grn_dat;
+typedef struct _grn_dat_cursor grn_dat_cursor;
+typedef struct _grn_table_scan_hit grn_dat_scan_hit;
+
+GRN_API int grn_dat_scan(grn_ctx *ctx, grn_dat *dat, const char *str,
+ unsigned int str_size, grn_dat_scan_hit *scan_hits,
+ unsigned int max_num_scan_hits, const char **str_rest);
+
+GRN_API grn_id grn_dat_lcp_search(grn_ctx *ctx, grn_dat *dat,
+ const void *key, unsigned int key_size);
+
+GRN_API grn_dat *grn_dat_create(grn_ctx *ctx, const char *path, unsigned int key_size,
+ unsigned int value_size, unsigned int flags);
+
+GRN_API grn_dat *grn_dat_open(grn_ctx *ctx, const char *path);
+
+GRN_API grn_rc grn_dat_close(grn_ctx *ctx, grn_dat *dat);
+
+GRN_API grn_rc grn_dat_remove(grn_ctx *ctx, const char *path);
+
+GRN_API grn_id grn_dat_get(grn_ctx *ctx, grn_dat *dat, const void *key,
+ unsigned int key_size, void **value);
+GRN_API grn_id grn_dat_add(grn_ctx *ctx, grn_dat *dat, const void *key,
+ unsigned int key_size, void **value, int *added);
+
+GRN_API int grn_dat_get_key(grn_ctx *ctx, grn_dat *dat, grn_id id, void *keybuf, int bufsize);
+GRN_API int grn_dat_get_key2(grn_ctx *ctx, grn_dat *dat, grn_id id, grn_obj *bulk);
+
+GRN_API grn_rc grn_dat_delete_by_id(grn_ctx *ctx, grn_dat *dat, grn_id id,
+ grn_table_delete_optarg *optarg);
+GRN_API grn_rc grn_dat_delete(grn_ctx *ctx, grn_dat *dat, const void *key, unsigned int key_size,
+ grn_table_delete_optarg *optarg);
+
+GRN_API grn_rc grn_dat_update_by_id(grn_ctx *ctx, grn_dat *dat, grn_id src_key_id,
+ const void *dest_key, unsigned int dest_key_size);
+GRN_API grn_rc grn_dat_update(grn_ctx *ctx, grn_dat *dat,
+ const void *src_key, unsigned int src_key_size,
+ const void *dest_key, unsigned int dest_key_size);
+
+GRN_API unsigned int grn_dat_size(grn_ctx *ctx, grn_dat *dat);
+
+GRN_API grn_dat_cursor *grn_dat_cursor_open(grn_ctx *ctx, grn_dat *dat,
+ const void *min, unsigned int min_size,
+ const void *max, unsigned int max_size,
+ int offset, int limit, int flags);
+GRN_API grn_id grn_dat_cursor_next(grn_ctx *ctx, grn_dat_cursor *c);
+GRN_API void grn_dat_cursor_close(grn_ctx *ctx, grn_dat_cursor *c);
+
+GRN_API int grn_dat_cursor_get_key(grn_ctx *ctx, grn_dat_cursor *c, const void **key);
+GRN_API grn_rc grn_dat_cursor_delete(grn_ctx *ctx, grn_dat_cursor *c,
+ grn_table_delete_optarg *optarg);
+
+#define GRN_DAT_EACH(ctx,dat,id,key,key_size,block) do {\
+ grn_dat_cursor *_sc = grn_dat_cursor_open(ctx, dat, NULL, 0, NULL, 0, 0, -1, 0);\
+ if (_sc) {\
+ grn_id id;\
+ unsigned int *_ks = (key_size);\
+ if (_ks) {\
+ while ((id = grn_dat_cursor_next(ctx, _sc))) {\
+ int _ks_raw = grn_dat_cursor_get_key(ctx, _sc, (const void **)(key));\
+ *(_ks) = (unsigned int)_ks_raw;\
+ block\
+ }\
+ } else {\
+ while ((id = grn_dat_cursor_next(ctx, _sc))) {\
+ grn_dat_cursor_get_key(ctx, _sc, (const void **)(key));\
+ block\
+ }\
+ }\
+ grn_dat_cursor_close(ctx, _sc);\
+ }\
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/db.h b/storage/mroonga/vendor/groonga/include/groonga/db.h
new file mode 100644
index 00000000000..cbfbfec302f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/db.h
@@ -0,0 +1,68 @@
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _grn_db_create_optarg grn_db_create_optarg;
+
+struct _grn_db_create_optarg {
+ char **builtin_type_names;
+ int n_builtin_type_names;
+};
+
+GRN_API grn_obj *grn_db_create(grn_ctx *ctx, const char *path, grn_db_create_optarg *optarg);
+
+#define GRN_DB_OPEN_OR_CREATE(ctx,path,optarg,db) \
+ (((db) = grn_db_open((ctx), (path))) || (db = grn_db_create((ctx), (path), (optarg))))
+
+GRN_API grn_obj *grn_db_open(grn_ctx *ctx, const char *path);
+GRN_API void grn_db_touch(grn_ctx *ctx, grn_obj *db);
+GRN_API grn_rc grn_db_recover(grn_ctx *ctx, grn_obj *db);
+GRN_API grn_rc grn_db_unmap(grn_ctx *ctx, grn_obj *db);
+GRN_API uint32_t grn_db_get_last_modified(grn_ctx *ctx, grn_obj *db);
+GRN_API grn_bool grn_db_is_dirty(grn_ctx *ctx, grn_obj *db);
+
+#define GRN_DB_EACH_BEGIN_FLAGS(ctx, cursor, id, flags) \
+ GRN_TABLE_EACH_BEGIN_FLAGS(ctx, \
+ grn_ctx_db((ctx)), \
+ cursor, \
+ id, \
+ flags)
+
+#define GRN_DB_EACH_BEGIN_BY_ID(ctx, cursor, id) \
+ GRN_DB_EACH_BEGIN_FLAGS(ctx, \
+ cursor, \
+ id, \
+ GRN_CURSOR_BY_ID | GRN_CURSOR_ASCENDING)
+
+#define GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) \
+ GRN_DB_EACH_BEGIN_FLAGS(ctx, \
+ cursor, \
+ id, \
+ GRN_CURSOR_BY_KEY | GRN_CURSOR_ASCENDING)
+
+#define GRN_DB_EACH_END(ctx, cursor) \
+ GRN_TABLE_EACH_END(ctx, cursor)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/dump.h b/storage/mroonga/vendor/groonga/include/groonga/dump.h
new file mode 100644
index 00000000000..4f292f480a8
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/dump.h
@@ -0,0 +1,34 @@
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API grn_rc grn_dump_table_create_flags(grn_ctx *ctx,
+ grn_table_flags flags,
+ grn_obj *buffer);
+GRN_API grn_rc grn_dump_column_create_flags(grn_ctx *ctx,
+ grn_column_flags flags,
+ grn_obj *buffer);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/error.h b/storage/mroonga/vendor/groonga/include/groonga/error.h
new file mode 100644
index 00000000000..abf3aa293e6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/error.h
@@ -0,0 +1,29 @@
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API const char *grn_rc_to_string(grn_rc rc);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/expr.h b/storage/mroonga/vendor/groonga/include/groonga/expr.h
index 63cbb6ebc7a..0665f7f5907 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/expr.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/expr.h
@@ -1,5 +1,5 @@
/*
- Copyright(C) 2009-2014 Brazil
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,13 +15,25 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_EXPR_H
-#define GROONGA_EXPR_H
+
+#pragma once
#ifdef __cplusplus
extern "C" {
#endif
+typedef unsigned int grn_expr_flags;
+
+#define GRN_EXPR_SYNTAX_QUERY (0x00)
+#define GRN_EXPR_SYNTAX_SCRIPT (0x01)
+#define GRN_EXPR_SYNTAX_OUTPUT_COLUMNS (0x20)
+#define GRN_EXPR_SYNTAX_ADJUSTER (0x40)
+#define GRN_EXPR_ALLOW_PRAGMA (0x02)
+#define GRN_EXPR_ALLOW_COLUMN (0x04)
+#define GRN_EXPR_ALLOW_UPDATE (0x08)
+#define GRN_EXPR_ALLOW_LEADING_NOT (0x10)
+#define GRN_EXPR_QUERY_NO_SYNTAX_ERROR (0x80)
+
GRN_API grn_obj *grn_expr_create(grn_ctx *ctx, const char *name, unsigned int name_size);
GRN_API grn_rc grn_expr_close(grn_ctx *ctx, grn_obj *expr);
GRN_API grn_obj *grn_expr_add_var(grn_ctx *ctx, grn_obj *expr,
@@ -31,6 +43,7 @@ GRN_API grn_obj *grn_expr_get_var(grn_ctx *ctx, grn_obj *expr,
GRN_API grn_obj *grn_expr_get_var_by_offset(grn_ctx *ctx, grn_obj *expr, unsigned int offset);
GRN_API grn_rc grn_expr_clear_vars(grn_ctx *ctx, grn_obj *expr);
+GRN_API void grn_expr_take_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj);
GRN_API grn_obj *grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj,
grn_operator op, int nargs);
@@ -53,13 +66,26 @@ GRN_API grn_rc grn_expr_syntax_escape(grn_ctx *ctx,
GRN_API grn_rc grn_expr_syntax_escape_query(grn_ctx *ctx,
const char *query, int query_size,
grn_obj *escaped_query);
+GRN_API grn_rc grn_expr_syntax_expand_query(grn_ctx *ctx,
+ const char *query, int query_size,
+ grn_expr_flags flags,
+ grn_obj *expander,
+ grn_obj *expanded_query);
+GRN_API grn_rc grn_expr_syntax_expand_query_by_table(grn_ctx *ctx,
+ const char *query,
+ int query_size,
+ grn_expr_flags flags,
+ grn_obj *term_column,
+ grn_obj *expanded_term_column,
+ grn_obj *expanded_query);
GRN_API grn_rc grn_expr_compile(grn_ctx *ctx, grn_obj *expr);
+GRN_API grn_obj *grn_expr_rewrite(grn_ctx *ctx, grn_obj *expr);
GRN_API grn_rc grn_expr_dump_plan(grn_ctx *ctx, grn_obj *expr, grn_obj *buffer);
GRN_API grn_obj *grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs);
GRN_API grn_obj *grn_expr_alloc(grn_ctx *ctx, grn_obj *expr,
- grn_id domain, grn_obj_flags flags);
+ grn_id domain, unsigned char flags);
#define GRN_EXPR_CREATE_FOR_QUERY(ctx,table,expr,var) do {\
if (((expr) = grn_expr_create((ctx), NULL, 0)) &&\
@@ -70,17 +96,6 @@ GRN_API grn_obj *grn_expr_alloc(grn_ctx *ctx, grn_obj *expr,
}\
} while (0)
-typedef unsigned int grn_expr_flags;
-
-#define GRN_EXPR_SYNTAX_QUERY (0x00)
-#define GRN_EXPR_SYNTAX_SCRIPT (0x01)
-#define GRN_EXPR_SYNTAX_OUTPUT_COLUMNS (0x20)
-#define GRN_EXPR_SYNTAX_ADJUSTER (0x40)
-#define GRN_EXPR_ALLOW_PRAGMA (0x02)
-#define GRN_EXPR_ALLOW_COLUMN (0x04)
-#define GRN_EXPR_ALLOW_UPDATE (0x08)
-#define GRN_EXPR_ALLOW_LEADING_NOT (0x10)
-
GRN_API grn_rc grn_expr_parse(grn_ctx *ctx, grn_obj *expr,
const char *str, unsigned int str_size,
grn_obj *default_column, grn_operator default_mode,
@@ -106,5 +121,3 @@ GRN_API unsigned int grn_expr_estimate_size(grn_ctx *ctx, grn_obj *expr);
#ifdef __cplusplus
}
#endif
-
-#endif /* GROONGA_EXPR_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/file_reader.h b/storage/mroonga/vendor/groonga/include/groonga/file_reader.h
new file mode 100644
index 00000000000..743240716a2
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/file_reader.h
@@ -0,0 +1,37 @@
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _grn_file_reader grn_file_reader;
+
+GRN_API grn_file_reader *grn_file_reader_open(grn_ctx *ctx, const char *path);
+GRN_API void grn_file_reader_close(grn_ctx *ctx,
+ grn_file_reader *reader);
+
+GRN_API grn_rc grn_file_reader_read_line(grn_ctx *ctx,
+ grn_file_reader *reader,
+ grn_obj *buffer);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/geo.h b/storage/mroonga/vendor/groonga/include/groonga/geo.h
new file mode 100644
index 00000000000..30fbb8d25ee
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/geo.h
@@ -0,0 +1,36 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API int grn_geo_table_sort(grn_ctx *ctx,
+ grn_obj *table,
+ int offset,
+ int limit,
+ grn_obj *result,
+ grn_obj *column,
+ grn_obj *geo_point);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/groonga.h b/storage/mroonga/vendor/groonga/include/groonga/groonga.h
index 14b21bda05c..e289bf97f37 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/groonga.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/groonga.h
@@ -1,5 +1,5 @@
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,11 +15,13 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_GROONGA_H
-#define GROONGA_GROONGA_H
+
+#pragma once
#include <stdarg.h>
#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
#ifdef __cplusplus
extern "C" {
@@ -34,7 +36,7 @@ extern "C" {
#endif /* GRN_API */
typedef unsigned int grn_id;
-typedef unsigned char grn_bool;
+typedef uint8_t grn_bool;
#define GRN_ID_NIL (0x00)
#define GRN_ID_MAX (0x3fffffff)
@@ -122,12 +124,17 @@ typedef enum {
GRN_TOKEN_FILTER_ERROR = -73,
GRN_COMMAND_ERROR = -74,
GRN_PLUGIN_ERROR = -75,
- GRN_SCORER_ERROR = -76
+ GRN_SCORER_ERROR = -76,
+ GRN_CANCEL = -77,
+ GRN_WINDOW_FUNCTION_ERROR = -78,
+ GRN_ZSTD_ERROR = -79
} grn_rc;
GRN_API grn_rc grn_init(void);
GRN_API grn_rc grn_fin(void);
+GRN_API const char *grn_get_global_error_message(void);
+
typedef enum {
GRN_ENC_DEFAULT = 0,
GRN_ENC_NONE,
@@ -141,12 +148,13 @@ typedef enum {
typedef enum {
GRN_COMMAND_VERSION_DEFAULT = 0,
GRN_COMMAND_VERSION_1,
- GRN_COMMAND_VERSION_2
+ GRN_COMMAND_VERSION_2,
+ GRN_COMMAND_VERSION_3
} grn_command_version;
#define GRN_COMMAND_VERSION_MIN GRN_COMMAND_VERSION_1
#define GRN_COMMAND_VERSION_STABLE GRN_COMMAND_VERSION_1
-#define GRN_COMMAND_VERSION_MAX GRN_COMMAND_VERSION_2
+#define GRN_COMMAND_VERSION_MAX GRN_COMMAND_VERSION_3
typedef enum {
GRN_LOG_NONE = 0,
@@ -161,6 +169,9 @@ typedef enum {
GRN_LOG_DUMP
} grn_log_level;
+GRN_API const char *grn_log_level_to_string(grn_log_level level);
+GRN_API grn_bool grn_log_level_parse(const char *string, grn_log_level *level);
+
/* query log flags */
#define GRN_QUERY_LOG_NONE (0x00)
#define GRN_QUERY_LOG_COMMAND (0x01<<0)
@@ -237,6 +248,10 @@ GRN_API grn_ctx *grn_ctx_open(int flags);
GRN_API grn_rc grn_ctx_close(grn_ctx *ctx);
GRN_API grn_rc grn_ctx_set_finalizer(grn_ctx *ctx, grn_proc_func *func);
+GRN_API grn_rc grn_ctx_push_temporary_open_space(grn_ctx *ctx);
+GRN_API grn_rc grn_ctx_pop_temporary_open_space(grn_ctx *ctx);
+GRN_API grn_rc grn_ctx_merge_temporary_open_space(grn_ctx *ctx);
+
GRN_API grn_encoding grn_get_default_encoding(void);
GRN_API grn_rc grn_set_default_encoding(grn_encoding encoding);
@@ -246,6 +261,7 @@ GRN_API grn_rc grn_set_default_encoding(grn_encoding encoding);
GRN_API const char *grn_get_version(void);
GRN_API const char *grn_get_package(void);
+GRN_API const char *grn_get_package_label(void);
GRN_API grn_command_version grn_get_default_command_version(void);
GRN_API grn_rc grn_set_default_command_version(grn_command_version version);
@@ -259,22 +275,6 @@ GRN_API grn_rc grn_set_default_match_escalation_threshold(long long int threshol
GRN_API int grn_get_lock_timeout(void);
GRN_API grn_rc grn_set_lock_timeout(int timeout);
-/* cache */
-#define GRN_CACHE_DEFAULT_MAX_N_ENTRIES 100
-typedef struct _grn_cache grn_cache;
-
-GRN_API grn_cache *grn_cache_open(grn_ctx *ctx);
-GRN_API grn_rc grn_cache_close(grn_ctx *ctx, grn_cache *cache);
-
-GRN_API grn_rc grn_cache_current_set(grn_ctx *ctx, grn_cache *cache);
-GRN_API grn_cache *grn_cache_current_get(grn_ctx *ctx);
-
-GRN_API grn_rc grn_cache_set_max_n_entries(grn_ctx *ctx,
- grn_cache *cache,
- unsigned int n);
-GRN_API unsigned int grn_cache_get_max_n_entries(grn_ctx *ctx,
- grn_cache *cache);
-
/* grn_encoding */
GRN_API const char *grn_encoding_to_string(grn_encoding encoding);
@@ -282,7 +282,13 @@ GRN_API grn_encoding grn_encoding_parse(const char *name);
/* obj */
-typedef unsigned short int grn_obj_flags;
+typedef uint16_t grn_obj_flags;
+typedef uint32_t grn_table_flags;
+typedef uint32_t grn_column_flags;
+
+/* flags for grn_obj_flags and grn_table_flags */
+
+#define GRN_OBJ_FLAGS_MASK (0xffff)
#define GRN_OBJ_TABLE_TYPE_MASK (0x07)
#define GRN_OBJ_TABLE_HASH_KEY (0x00)
@@ -310,6 +316,7 @@ typedef unsigned short int grn_obj_flags;
#define GRN_OBJ_COMPRESS_LZ4 (0x02<<4)
/* Just for backward compatibility. We'll remove it at 5.0.0. */
#define GRN_OBJ_COMPRESS_LZO GRN_OBJ_COMPRESS_LZ4
+#define GRN_OBJ_COMPRESS_ZSTD (0x03<<4)
#define GRN_OBJ_WITH_SECTION (0x01<<7)
#define GRN_OBJ_WITH_WEIGHT (0x01<<8)
@@ -327,6 +334,8 @@ typedef unsigned short int grn_obj_flags;
#define GRN_OBJ_UNIT_USERDEF_SECTION (0x07<<8)
#define GRN_OBJ_UNIT_USERDEF_POSITION (0x08<<8)
+/* Don't use (0x01<<12) because it's used internally. */
+
#define GRN_OBJ_NO_SUBREC (0x00<<13)
#define GRN_OBJ_WITH_SUBREC (0x01<<13)
@@ -335,6 +344,15 @@ typedef unsigned short int grn_obj_flags;
#define GRN_OBJ_TEMPORARY (0x00<<15)
#define GRN_OBJ_PERSISTENT (0x01<<15)
+/* flags only for grn_table_flags */
+
+#define GRN_OBJ_KEY_LARGE (0x01<<16)
+
+/* flags only for grn_column_flags */
+
+#define GRN_OBJ_INDEX_SMALL (0x01<<16)
+#define GRN_OBJ_INDEX_MEDIUM (0x01<<17)
+
/* obj types */
#define GRN_VOID (0x00)
@@ -355,6 +373,7 @@ typedef unsigned short int grn_obj_flags;
#define GRN_CURSOR_TABLE_NO_KEY (0x13)
#define GRN_CURSOR_COLUMN_INDEX (0x18)
#define GRN_CURSOR_COLUMN_GEO_INDEX (0x1a)
+#define GRN_CURSOR_CONFIG (0x1f)
#define GRN_TYPE (0x20)
#define GRN_PROC (0x21)
#define GRN_EXPR (0x22)
@@ -402,6 +421,7 @@ struct _grn_obj {
#define GRN_OBJ_REFER (0x01<<0)
#define GRN_OBJ_OUTPLACE (0x01<<1)
+#define GRN_OBJ_OWN (0x01<<5)
#define GRN_OBJ_INIT(obj,obj_type,obj_flags,obj_domain) do { \
(obj)->header.type = (obj_type);\
@@ -415,26 +435,17 @@ struct _grn_obj {
#define GRN_OBJ_FIN(ctx,obj) (grn_obj_close((ctx), (obj)))
-typedef struct _grn_db_create_optarg grn_db_create_optarg;
-
-struct _grn_db_create_optarg {
- char **builtin_type_names;
- int n_builtin_type_names;
-};
-
-GRN_API grn_obj *grn_db_create(grn_ctx *ctx, const char *path, grn_db_create_optarg *optarg);
-
-#define GRN_DB_OPEN_OR_CREATE(ctx,path,optarg,db) \
- (((db) = grn_db_open((ctx), (path))) || (db = grn_db_create((ctx), (path), (optarg))))
-
-GRN_API grn_obj *grn_db_open(grn_ctx *ctx, const char *path);
-GRN_API void grn_db_touch(grn_ctx *ctx, grn_obj *db);
-GRN_API grn_rc grn_db_recover(grn_ctx *ctx, grn_obj *db);
-
GRN_API grn_rc grn_ctx_use(grn_ctx *ctx, grn_obj *db);
GRN_API grn_obj *grn_ctx_db(grn_ctx *ctx);
GRN_API grn_obj *grn_ctx_get(grn_ctx *ctx, const char *name, int name_size);
GRN_API grn_rc grn_ctx_get_all_tables(grn_ctx *ctx, grn_obj *tables_buffer);
+GRN_API grn_rc grn_ctx_get_all_types(grn_ctx *ctx, grn_obj *types_buffer);
+GRN_API grn_rc grn_ctx_get_all_tokenizers(grn_ctx *ctx,
+ grn_obj *tokenizers_buffer);
+GRN_API grn_rc grn_ctx_get_all_normalizers(grn_ctx *ctx,
+ grn_obj *normalizers_buffer);
+GRN_API grn_rc grn_ctx_get_all_token_filters(grn_ctx *ctx,
+ grn_obj *token_filters_buffer);
typedef enum {
GRN_DB_VOID = 0,
@@ -467,9 +478,7 @@ typedef enum {
} grn_builtin_tokenizer;
GRN_API grn_obj *grn_ctx_at(grn_ctx *ctx, grn_id id);
-
-GRN_API grn_obj *grn_type_create(grn_ctx *ctx, const char *name, unsigned int name_size,
- grn_obj_flags flags, unsigned int size);
+GRN_API grn_bool grn_ctx_is_opened(grn_ctx *ctx, grn_id id);
GRN_API grn_rc grn_plugin_register(grn_ctx *ctx, const char *name);
GRN_API grn_rc grn_plugin_unregister(grn_ctx *ctx, const char *name);
@@ -478,6 +487,7 @@ GRN_API grn_rc grn_plugin_unregister_by_path(grn_ctx *ctx, const char *path);
GRN_API const char *grn_plugin_get_system_plugins_dir(void);
GRN_API const char *grn_plugin_get_suffix(void);
GRN_API const char *grn_plugin_get_ruby_suffix(void);
+GRN_API grn_rc grn_plugin_get_names(grn_ctx *ctx, grn_obj *names);
typedef struct {
const char *name;
@@ -495,7 +505,8 @@ typedef enum {
GRN_PROC_HOOK,
GRN_PROC_NORMALIZER,
GRN_PROC_TOKEN_FILTER,
- GRN_PROC_SCORER
+ GRN_PROC_SCORER,
+ GRN_PROC_WINDOW_FUNCTION
} grn_proc_type;
GRN_API grn_obj *grn_proc_create(grn_ctx *ctx,
@@ -506,136 +517,17 @@ GRN_API grn_obj *grn_proc_get_info(grn_ctx *ctx, grn_user_data *user_data,
grn_expr_var **vars, unsigned int *nvars, grn_obj **caller);
GRN_API grn_proc_type grn_proc_get_type(grn_ctx *ctx, grn_obj *proc);
-/*-------------------------------------------------------------
- * API for table
- */
-
-#define GRN_TABLE_MAX_KEY_SIZE (0x1000)
-
-GRN_API grn_obj *grn_table_create(grn_ctx *ctx,
- const char *name, unsigned int name_size,
- const char *path, grn_obj_flags flags,
- grn_obj *key_type, grn_obj *value_type);
-
-#define GRN_TABLE_OPEN_OR_CREATE(ctx,name,name_size,path,flags,key_type,value_type,table) \
- (((table) = grn_ctx_get((ctx), (name), (name_size))) ||\
- ((table) = grn_table_create((ctx), (name), (name_size), (path), (flags), (key_type), (value_type))))
-
-/* TODO: int *added -> grn_bool *added */
-GRN_API grn_id grn_table_add(grn_ctx *ctx, grn_obj *table,
- const void *key, unsigned int key_size, int *added);
-GRN_API grn_id grn_table_get(grn_ctx *ctx, grn_obj *table,
- const void *key, unsigned int key_size);
-GRN_API grn_id grn_table_at(grn_ctx *ctx, grn_obj *table, grn_id id);
-GRN_API grn_id grn_table_lcp_search(grn_ctx *ctx, grn_obj *table,
- const void *key, unsigned int key_size);
-GRN_API int grn_table_get_key(grn_ctx *ctx, grn_obj *table,
- grn_id id, void *keybuf, int buf_size);
-GRN_API grn_rc grn_table_delete(grn_ctx *ctx, grn_obj *table,
- const void *key, unsigned int key_size);
-GRN_API grn_rc grn_table_delete_by_id(grn_ctx *ctx, grn_obj *table, grn_id id);
-GRN_API grn_rc grn_table_update_by_id(grn_ctx *ctx, grn_obj *table, grn_id id,
- const void *dest_key, unsigned int dest_key_size);
-GRN_API grn_rc grn_table_update(grn_ctx *ctx, grn_obj *table,
- const void *src_key, unsigned int src_key_size,
- const void *dest_key, unsigned int dest_key_size);
-GRN_API grn_rc grn_table_truncate(grn_ctx *ctx, grn_obj *table);
-
typedef grn_obj grn_table_cursor;
-#define GRN_CURSOR_ASCENDING (0x00<<0)
-#define GRN_CURSOR_DESCENDING (0x01<<0)
-#define GRN_CURSOR_GE (0x00<<1)
-#define GRN_CURSOR_GT (0x01<<1)
-#define GRN_CURSOR_LE (0x00<<2)
-#define GRN_CURSOR_LT (0x01<<2)
-#define GRN_CURSOR_BY_KEY (0x00<<3)
-#define GRN_CURSOR_BY_ID (0x01<<3)
-#define GRN_CURSOR_PREFIX (0x01<<4)
-#define GRN_CURSOR_SIZE_BY_BIT (0x01<<5)
-#define GRN_CURSOR_RK (0x01<<6)
-
-GRN_API grn_table_cursor *grn_table_cursor_open(grn_ctx *ctx, grn_obj *table,
- const void *min, unsigned int min_size,
- const void *max, unsigned int max_size,
- int offset, int limit, int flags);
-GRN_API grn_rc grn_table_cursor_close(grn_ctx *ctx, grn_table_cursor *tc);
-GRN_API grn_id grn_table_cursor_next(grn_ctx *ctx, grn_table_cursor *tc);
-GRN_API int grn_table_cursor_get_key(grn_ctx *ctx, grn_table_cursor *tc, void **key);
-GRN_API int grn_table_cursor_get_value(grn_ctx *ctx, grn_table_cursor *tc, void **value);
-GRN_API grn_rc grn_table_cursor_set_value(grn_ctx *ctx, grn_table_cursor *tc,
- const void *value, int flags);
-GRN_API grn_rc grn_table_cursor_delete(grn_ctx *ctx, grn_table_cursor *tc);
-GRN_API grn_obj *grn_table_cursor_table(grn_ctx *ctx, grn_table_cursor *tc);
-
typedef struct {
grn_id rid;
- grn_id sid;
- unsigned int pos;
- unsigned int tf;
- unsigned int weight;
- unsigned int rest;
+ uint32_t sid;
+ uint32_t pos;
+ uint32_t tf;
+ uint32_t weight;
+ uint32_t rest;
} grn_posting;
-GRN_API grn_obj *grn_index_cursor_open(grn_ctx *ctx, grn_table_cursor *tc, grn_obj *index,
- grn_id rid_min, grn_id rid_max, int flags);
-GRN_API grn_posting *grn_index_cursor_next(grn_ctx *ctx, grn_obj *ic, grn_id *tid);
-
-#define GRN_TABLE_EACH(ctx,table,head,tail,id,key,key_size,value,block) do {\
- (ctx)->errlvl = GRN_LOG_NOTICE;\
- (ctx)->rc = GRN_SUCCESS;\
- if ((ctx)->seqno & 1) {\
- (ctx)->subno++;\
- } else {\
- (ctx)->seqno++;\
- }\
- if (table) {\
- switch ((table)->header.type) {\
- case GRN_TABLE_PAT_KEY :\
- GRN_PAT_EACH((ctx), (grn_pat *)(table), (id), (key), (key_size), (value), block);\
- break;\
- case GRN_TABLE_DAT_KEY :\
- GRN_DAT_EACH((ctx), (grn_dat *)(table), (id), (key), (key_size), block);\
- break;\
- case GRN_TABLE_HASH_KEY :\
- GRN_HASH_EACH((ctx), (grn_hash *)(table), (id), (key), (key_size), (value), block);\
- break;\
- case GRN_TABLE_NO_KEY :\
- GRN_ARRAY_EACH((ctx), (grn_array *)(table), (head), (tail), (id), (value), block);\
- break;\
- }\
- }\
- if ((ctx)->subno) {\
- (ctx)->subno--;\
- } else {\
- (ctx)->seqno++;\
- }\
-} while (0)
-
-typedef struct _grn_table_sort_key grn_table_sort_key;
-typedef unsigned char grn_table_sort_flags;
-
-#define GRN_TABLE_SORT_ASC (0x00<<0)
-#define GRN_TABLE_SORT_DESC (0x01<<0)
-
-struct _grn_table_sort_key {
- grn_obj *key;
- grn_table_sort_flags flags;
- int offset;
-};
-
-GRN_API int grn_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit,
- grn_obj *result, grn_table_sort_key *keys, int n_keys);
-
-typedef struct _grn_table_group_result grn_table_group_result;
-typedef unsigned int grn_table_group_flags;
-
-#define GRN_TABLE_GROUP_CALC_COUNT (0x01<<3)
-#define GRN_TABLE_GROUP_CALC_MAX (0x01<<4)
-#define GRN_TABLE_GROUP_CALC_MIN (0x01<<5)
-#define GRN_TABLE_GROUP_CALC_SUM (0x01<<6)
-#define GRN_TABLE_GROUP_CALC_AVG (0x01<<7)
-
typedef enum {
GRN_OP_PUSH = 0,
GRN_OP_POP,
@@ -716,53 +608,13 @@ typedef enum {
GRN_OP_TABLE_GROUP,
GRN_OP_JSON_PUT,
GRN_OP_GET_MEMBER,
- GRN_OP_REGEXP
+ GRN_OP_REGEXP,
+ GRN_OP_FUZZY
} grn_operator;
-GRN_API const char *grn_operator_to_string(grn_operator op);
-GRN_API grn_bool grn_operator_exec_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y);
-GRN_API grn_bool grn_operator_exec_not_equal(grn_ctx *ctx,
- grn_obj *x, grn_obj *y);
-GRN_API grn_bool grn_operator_exec_less(grn_ctx *ctx, grn_obj *x, grn_obj *y);
-GRN_API grn_bool grn_operator_exec_greater(grn_ctx *ctx, grn_obj *x, grn_obj *y);
-GRN_API grn_bool grn_operator_exec_less_equal(grn_ctx *ctx,
- grn_obj *x, grn_obj *y);
-GRN_API grn_bool grn_operator_exec_greater_equal(grn_ctx *ctx,
- grn_obj *x, grn_obj *y);
-GRN_API grn_bool grn_operator_exec_match(grn_ctx *ctx,
- grn_obj *target, grn_obj *sub_text);
-GRN_API grn_bool grn_operator_exec_prefix(grn_ctx *ctx,
- grn_obj *target, grn_obj *prefix);
-GRN_API grn_bool grn_operator_exec_regexp(grn_ctx *ctx,
- grn_obj *target, grn_obj *pattern);
-
-struct _grn_table_group_result {
- grn_obj *table;
- unsigned char key_begin;
- unsigned char key_end;
- int limit;
- grn_table_group_flags flags;
- grn_operator op;
- unsigned int max_n_subrecs;
- grn_obj *calc_target;
-};
-
-GRN_API grn_rc grn_table_group(grn_ctx *ctx, grn_obj *table,
- grn_table_sort_key *keys, int n_keys,
- grn_table_group_result *results, int n_results);
-GRN_API grn_rc grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2,
- grn_obj *res, grn_operator op);
-GRN_API grn_rc grn_table_difference(grn_ctx *ctx, grn_obj *table1, grn_obj *table2,
- grn_obj *res1, grn_obj *res2);
-GRN_API int grn_table_columns(grn_ctx *ctx, grn_obj *table,
- const char *name, unsigned int name_size,
- grn_obj *res);
-
GRN_API grn_obj *grn_obj_column(grn_ctx *ctx, grn_obj *table,
const char *name, unsigned int name_size);
-GRN_API unsigned int grn_table_size(grn_ctx *ctx, grn_obj *table);
-
/*-------------------------------------------------------------
* API for column
*/
@@ -788,7 +640,7 @@ GRN_API unsigned int grn_table_size(grn_ctx *ctx, grn_obj *table);
GRN_API grn_obj *grn_column_create(grn_ctx *ctx, grn_obj *table,
const char *name, unsigned int name_size,
- const char *path, grn_obj_flags flags, grn_obj *type);
+ const char *path, grn_column_flags flags, grn_obj *type);
#define GRN_COLUMN_OPEN_OR_CREATE(ctx,table,name,name_size,path,flags,type,column) \
(((column) = grn_obj_column((ctx), (table), (name), (name_size))) ||\
@@ -839,7 +691,9 @@ typedef enum {
/* Just for backward compatibility. We'll remove it at 5.0.0. */
#define GRN_INFO_SUPPORT_LZO GRN_INFO_SUPPORT_LZ4
GRN_INFO_NORMALIZER,
- GRN_INFO_TOKEN_FILTERS
+ GRN_INFO_TOKEN_FILTERS,
+ GRN_INFO_SUPPORT_ZSTD,
+ GRN_INFO_SUPPORT_ARROW
} grn_info_type;
GRN_API grn_obj *grn_obj_get_info(grn_ctx *ctx, grn_obj *obj, grn_info_type type, grn_obj *valuebuf);
@@ -875,6 +729,10 @@ GRN_API int grn_obj_get_values(grn_ctx *ctx, grn_obj *obj, grn_id offset, void *
GRN_API grn_rc grn_obj_set_value(grn_ctx *ctx, grn_obj *obj, grn_id id, grn_obj *value, int flags);
GRN_API grn_rc grn_obj_remove(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_rc grn_obj_remove_dependent(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_rc grn_obj_remove_force(grn_ctx *ctx,
+ const char *name,
+ int name_size);
GRN_API grn_rc grn_obj_rename(grn_ctx *ctx, grn_obj *obj,
const char *name, unsigned int name_size);
GRN_API grn_rc grn_table_rename(grn_ctx *ctx, grn_obj *table,
@@ -915,6 +773,27 @@ GRN_API grn_obj *grn_obj_db(grn_ctx *ctx, grn_obj *obj);
GRN_API grn_id grn_obj_id(grn_ctx *ctx, grn_obj *obj);
+/* Flags for grn_fuzzy_search_optarg::flags. */
+#define GRN_TABLE_FUZZY_SEARCH_WITH_TRANSPOSITION (0x01)
+
+typedef struct _grn_fuzzy_search_optarg grn_fuzzy_search_optarg;
+
+struct _grn_fuzzy_search_optarg {
+ unsigned int max_distance;
+ unsigned int max_expansion;
+ unsigned int prefix_match_size;
+ int flags;
+};
+
+#define GRN_MATCH_INFO_GET_MIN_RECORD_ID (0x01)
+
+typedef struct _grn_match_info grn_match_info;
+
+struct _grn_match_info {
+ int flags;
+ grn_id min;
+};
+
typedef struct _grn_search_optarg grn_search_optarg;
struct _grn_search_optarg {
@@ -928,6 +807,8 @@ struct _grn_search_optarg {
grn_obj *scorer;
grn_obj *scorer_args_expr;
unsigned int scorer_args_expr_offset;
+ grn_fuzzy_search_optarg fuzzy;
+ grn_match_info match_info;
};
GRN_API grn_rc grn_obj_search(grn_ctx *ctx, grn_obj *obj, grn_obj *query,
@@ -939,6 +820,16 @@ typedef grn_rc grn_selector_func(grn_ctx *ctx, grn_obj *table, grn_obj *index,
GRN_API grn_rc grn_proc_set_selector(grn_ctx *ctx, grn_obj *proc,
grn_selector_func selector);
+GRN_API grn_rc grn_proc_set_selector_operator(grn_ctx *ctx,
+ grn_obj *proc,
+ grn_operator selector_op);
+GRN_API grn_operator grn_proc_get_selector_operator(grn_ctx *ctx,
+ grn_obj *proc);
+
+GRN_API grn_rc grn_proc_set_is_stable(grn_ctx *ctx,
+ grn_obj *proc,
+ grn_bool is_stable);
+GRN_API grn_bool grn_proc_is_stable(grn_ctx *ctx, grn_obj *proc);
/*-------------------------------------------------------------
* grn_vector
@@ -953,6 +844,10 @@ GRN_API grn_rc grn_vector_add_element(grn_ctx *ctx, grn_obj *vector,
GRN_API unsigned int grn_vector_get_element(grn_ctx *ctx, grn_obj *vector,
unsigned int offset, const char **str,
unsigned int *weight, grn_id *domain);
+GRN_API unsigned int grn_vector_pop_element(grn_ctx *ctx, grn_obj *vector,
+ const char **str,
+ unsigned int *weight,
+ grn_id *domain);
/*-------------------------------------------------------------
* grn_uvector
@@ -1008,6 +903,11 @@ GRN_API unsigned int grn_column_find_index_data(grn_ctx *ctx, grn_obj *column,
grn_operator op,
grn_index_datum *index_data,
unsigned int n_index_data);
+/* @since 5.1.2. */
+GRN_API uint32_t grn_column_get_all_index_data(grn_ctx *ctx,
+ grn_obj *column,
+ grn_index_datum *index_data,
+ uint32_t n_index_data);
GRN_API grn_rc grn_obj_delete_by_id(grn_ctx *ctx, grn_obj *db, grn_id id, grn_bool removep);
GRN_API grn_rc grn_obj_path_by_id(grn_ctx *ctx, grn_obj *db, grn_id id, char *buffer);
@@ -1123,6 +1023,7 @@ GRN_API grn_rc grn_snip_get_result(grn_ctx *ctx, grn_obj *snip, const unsigned i
#define GRN_LOG_TITLE (0x01<<1)
#define GRN_LOG_MESSAGE (0x01<<2)
#define GRN_LOG_LOCATION (0x01<<3)
+#define GRN_LOG_PID (0x01<<4)
/* Deprecated since 2.1.2. Use grn_logger instead. */
typedef struct _grn_logger_info grn_logger_info;
@@ -1163,8 +1064,34 @@ GRN_API grn_log_level grn_logger_get_max_level(grn_ctx *ctx);
# define GRN_ATTRIBUTE_PRINTF(fmt_pos)
#endif /* __GNUC__ */
+#if defined(__clang__)
+# if __has_attribute(__alloc_size__)
+# define HAVE_ALLOC_SIZE_ATTRIBUTE
+# endif /* __has_attribute(__alloc_size__) */
+#elif defined(__GNUC__) && \
+ ((__GNUC__ >= 5) || (__GNUC__ > 4 && __GNUC_MINOR__ >= 3))
+# define HAVE_ALLOC_SIZE_ATTRIBUTE
+#endif /* __clang__ */
+
+#ifdef HAVE_ALLOC_SIZE_ATTRIBUTE
+# define GRN_ATTRIBUTE_ALLOC_SIZE(size) \
+ __attribute__ ((alloc_size(size)))
+# define GRN_ATTRIBUTE_ALLOC_SIZE_N(n, size) \
+ __attribute__ ((alloc_size(n, size)))
+#else
+# define GRN_ATTRIBUTE_ALLOC_SIZE(size)
+# define GRN_ATTRIBUTE_ALLOC_SIZE_N(n, size)
+#endif /* HAVE_ALLOC_SIZE_ATTRIBUTE */
+
GRN_API void grn_logger_put(grn_ctx *ctx, grn_log_level level,
const char *file, int line, const char *func, const char *fmt, ...) GRN_ATTRIBUTE_PRINTF(6);
+GRN_API void grn_logger_putv(grn_ctx *ctx,
+ grn_log_level level,
+ const char *file,
+ int line,
+ const char *func,
+ const char *fmt,
+ va_list ap);
GRN_API void grn_logger_reopen(grn_ctx *ctx);
GRN_API grn_bool grn_logger_pass(grn_ctx *ctx, grn_log_level level);
@@ -1175,6 +1102,8 @@ GRN_API grn_bool grn_logger_pass(grn_ctx *ctx, grn_log_level level);
GRN_API void grn_default_logger_set_max_level(grn_log_level level);
GRN_API grn_log_level grn_default_logger_get_max_level(void);
+GRN_API void grn_default_logger_set_flags(int flags);
+GRN_API int grn_default_logger_get_flags(void);
GRN_API void grn_default_logger_set_path(const char *path);
GRN_API const char *grn_default_logger_get_path(void);
GRN_API void grn_default_logger_set_rotate_threshold_size(off_t threshold);
@@ -1198,7 +1127,15 @@ struct _grn_query_logger {
void (*fin)(grn_ctx *ctx, void *user_data);
};
+GRN_API grn_bool grn_query_log_flags_parse(const char *string,
+ int string_size,
+ unsigned int *flags);
+
GRN_API grn_rc grn_query_logger_set(grn_ctx *ctx, const grn_query_logger *logger);
+GRN_API void grn_query_logger_set_flags(grn_ctx *ctx, unsigned int flags);
+GRN_API void grn_query_logger_add_flags(grn_ctx *ctx, unsigned int flags);
+GRN_API void grn_query_logger_remove_flags(grn_ctx *ctx, unsigned int flags);
+GRN_API unsigned int grn_query_logger_get_flags(grn_ctx *ctx);
GRN_API void grn_query_logger_put(grn_ctx *ctx, unsigned int flag,
const char *mark,
@@ -1246,6 +1183,13 @@ GRN_API off_t grn_default_query_logger_get_rotate_threshold_size(void);
}\
}\
} while (0)
+#define GRN_BULK_INCR_LEN(bulk,len) do {\
+ if (GRN_BULK_OUTP(bulk)) {\
+ (bulk)->u.b.curr += (len);\
+ } else {\
+ (bulk)->header.flags += (grn_obj_flags)(len);\
+ }\
+} while (0)
#define GRN_BULK_WSIZE(bulk) \
(GRN_BULK_OUTP(bulk)\
? ((bulk)->u.b.tail - (bulk)->u.b.head)\
@@ -1356,6 +1300,10 @@ GRN_API void grn_ctx_recv_handler_set(grn_ctx *,
#define GRN_TEXT_VALUE(obj) GRN_BULK_HEAD(obj)
#define GRN_TEXT_LEN(obj) GRN_BULK_VSIZE(obj)
+#define GRN_TEXT_EQUAL_CSTRING(bulk, string)\
+ (GRN_TEXT_LEN(bulk) == strlen(string) &&\
+ memcmp(GRN_TEXT_VALUE(bulk), string, GRN_TEXT_LEN(bulk)) == 0)
+
#define GRN_BOOL_INIT(obj,flags) \
GRN_VALUE_FIX_SIZE_INIT(obj, flags, GRN_DB_BOOL)
#define GRN_INT8_INIT(obj,flags) \
@@ -1381,7 +1329,8 @@ GRN_API void grn_ctx_recv_handler_set(grn_ctx *,
#define GRN_RECORD_INIT GRN_VALUE_FIX_SIZE_INIT
#define GRN_PTR_INIT(obj,flags,domain)\
GRN_OBJ_INIT((obj), ((flags) & GRN_OBJ_VECTOR) ? GRN_PVECTOR : GRN_PTR,\
- ((flags) & GRN_OBJ_DO_SHALLOW_COPY), (domain))
+ ((flags) & (GRN_OBJ_DO_SHALLOW_COPY | GRN_OBJ_OWN)),\
+ (domain))
#define GRN_TOKYO_GEO_POINT_INIT(obj,flags) \
GRN_VALUE_FIX_SIZE_INIT(obj, flags, GRN_DB_TOKYO_GEO_POINT)
#define GRN_WGS84_GEO_POINT_INIT(obj,flags) \
@@ -1512,17 +1461,6 @@ GRN_API void grn_ctx_recv_handler_set(grn_ctx *,
(offset) * sizeof(grn_obj *), sizeof(grn_obj *));\
} while (0)
-#define GRN_TIME_USEC_PER_SEC 1000000
-#define GRN_TIME_PACK(sec, usec) ((long long int)(sec) * GRN_TIME_USEC_PER_SEC + (usec))
-#define GRN_TIME_UNPACK(time_value, sec, usec) do {\
- sec = (time_value) / GRN_TIME_USEC_PER_SEC;\
- usec = (time_value) % GRN_TIME_USEC_PER_SEC;\
-} while (0)
-
-GRN_API void grn_time_now(grn_ctx *ctx, grn_obj *obj);
-
-#define GRN_TIME_NOW(ctx,obj) (grn_time_now((ctx), (obj)))
-
#define GRN_BOOL_VALUE(obj) (*((unsigned char *)GRN_BULK_HEAD(obj)))
#define GRN_INT8_VALUE(obj) (*((signed char *)GRN_BULK_HEAD(obj)))
#define GRN_UINT8_VALUE(obj) (*((unsigned char *)GRN_BULK_HEAD(obj)))
@@ -1601,6 +1539,28 @@ GRN_API void grn_time_now(grn_ctx *ctx, grn_obj *obj);
grn_bulk_write((ctx), (obj), (char *)&_val, sizeof(grn_obj *));\
} while (0)
+#define GRN_BULK_POP(obj, value, type, default) do {\
+ if (GRN_BULK_VSIZE(obj) >= sizeof(type)) {\
+ GRN_BULK_INCR_LEN((obj), -(sizeof(type)));\
+ value = *(type *)(GRN_BULK_CURR(obj));\
+ } else {\
+ value = default;\
+ }\
+} while (0)
+#define GRN_BOOL_POP(obj, value) GRN_BULK_POP(obj, value, unsigned char, 0)
+#define GRN_INT8_POP(obj, value) GRN_BULK_POP(obj, value, int8_t, 0)
+#define GRN_UINT8_POP(obj, value) GRN_BULK_POP(obj, value, uint8_t, 0)
+#define GRN_INT16_POP(obj, value) GRN_BULK_POP(obj, value, int16_t, 0)
+#define GRN_UINT16_POP(obj, value) GRN_BULK_POP(obj, value, uint16_t, 0)
+#define GRN_INT32_POP(obj, value) GRN_BULK_POP(obj, value, int32_t, 0)
+#define GRN_UINT32_POP(obj, value) GRN_BULK_POP(obj, value, uint32_t, 0)
+#define GRN_INT64_POP(obj, value) GRN_BULK_POP(obj, value, int64_t, 0)
+#define GRN_UINT64_POP(obj, value) GRN_BULK_POP(obj, value, uint64_t, 0)
+#define GRN_FLOAT_POP(obj, value) GRN_BULK_POP(obj, value, double, 0.0)
+#define GRN_TIME_POP GRN_INT64_POP
+#define GRN_RECORD_POP(obj, value) GRN_BULK_POP(obj, value, grn_id, GRN_ID_NIL)
+#define GRN_PTR_POP(obj, value) GRN_BULK_POP(obj, value, grn_obj *, NULL)
+
/* grn_str: deprecated. use grn_string instead. */
typedef struct {
@@ -1680,38 +1640,9 @@ GRN_API int grn_charlen(grn_ctx *ctx, const char *str, const char *end);
GRN_API grn_rc grn_ctx_push(grn_ctx *ctx, grn_obj *obj);
GRN_API grn_obj *grn_ctx_pop(grn_ctx *ctx);
-GRN_API grn_obj *grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
- grn_obj *res, grn_operator op);
-
GRN_API int grn_obj_columns(grn_ctx *ctx, grn_obj *table,
const char *str, unsigned int str_size, grn_obj *res);
-GRN_API grn_table_sort_key *grn_table_sort_key_from_str(grn_ctx *ctx,
- const char *str, unsigned int str_size,
- grn_obj *table, unsigned int *nkeys);
-GRN_API grn_rc grn_table_sort_key_close(grn_ctx *ctx,
- grn_table_sort_key *keys, unsigned int nkeys);
-
-GRN_API grn_bool grn_table_is_grouped(grn_ctx *ctx, grn_obj *table);
-
-GRN_API unsigned int grn_table_max_n_subrecs(grn_ctx *ctx, grn_obj *table);
-
-GRN_API grn_obj *grn_table_create_for_group(grn_ctx *ctx,
- const char *name,
- unsigned int name_size,
- const char *path,
- grn_obj *group_key,
- grn_obj *value_type,
- unsigned int max_n_subrecs);
-
-GRN_API unsigned int grn_table_get_subrecs(grn_ctx *ctx, grn_obj *table,
- grn_id id, grn_id *subrecbuf,
- int *scorebuf, int buf_size);
-
-GRN_API grn_obj *grn_table_tokenize(grn_ctx *ctx, grn_obj *table,
- const char *str, unsigned int str_len,
- grn_obj *buf, grn_bool addp);
-
GRN_API grn_rc grn_load(grn_ctx *ctx, grn_content_type input_type,
const char *table, unsigned int table_len,
const char *columns, unsigned int columns_len,
@@ -1744,28 +1675,6 @@ GRN_API grn_rc grn_set_segv_handler(void);
GRN_API grn_rc grn_set_int_handler(void);
GRN_API grn_rc grn_set_term_handler(void);
-/* hash */
-
-typedef struct _grn_hash grn_hash;
-typedef struct _grn_hash_cursor grn_hash_cursor;
-
-GRN_API grn_hash *grn_hash_create(grn_ctx *ctx, const char *path, unsigned int key_size,
- unsigned int value_size, unsigned int flags);
-
-GRN_API grn_hash *grn_hash_open(grn_ctx *ctx, const char *path);
-
-GRN_API grn_rc grn_hash_close(grn_ctx *ctx, grn_hash *hash);
-
-GRN_API grn_id grn_hash_add(grn_ctx *ctx, grn_hash *hash, const void *key,
- unsigned int key_size, void **value, int *added);
-GRN_API grn_id grn_hash_get(grn_ctx *ctx, grn_hash *hash, const void *key,
- unsigned int key_size, void **value);
-
-GRN_API int grn_hash_get_key(grn_ctx *ctx, grn_hash *hash, grn_id id, void *keybuf, int bufsize);
-GRN_API int grn_hash_get_key2(grn_ctx *ctx, grn_hash *hash, grn_id id, grn_obj *bulk);
-GRN_API int grn_hash_get_value(grn_ctx *ctx, grn_hash *hash, grn_id id, void *valuebuf);
-GRN_API grn_rc grn_hash_set_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
- const void *value, int flags);
typedef struct _grn_table_delete_optarg grn_table_delete_optarg;
@@ -1775,253 +1684,17 @@ struct _grn_table_delete_optarg {
void *func_arg;
};
-GRN_API grn_rc grn_hash_delete_by_id(grn_ctx *ctx, grn_hash *hash, grn_id id,
- grn_table_delete_optarg *optarg);
-GRN_API grn_rc grn_hash_delete(grn_ctx *ctx, grn_hash *hash,
- const void *key, unsigned int key_size,
- grn_table_delete_optarg *optarg);
-
-GRN_API grn_hash_cursor *grn_hash_cursor_open(grn_ctx *ctx, grn_hash *hash,
- const void *min, unsigned int min_size,
- const void *max, unsigned int max_size,
- int offset, int limit, int flags);
-GRN_API grn_id grn_hash_cursor_next(grn_ctx *ctx, grn_hash_cursor *c);
-GRN_API void grn_hash_cursor_close(grn_ctx *ctx, grn_hash_cursor *c);
-
-GRN_API int grn_hash_cursor_get_key(grn_ctx *ctx, grn_hash_cursor *c, void **key);
-GRN_API int grn_hash_cursor_get_value(grn_ctx *ctx, grn_hash_cursor *c, void **value);
-GRN_API grn_rc grn_hash_cursor_set_value(grn_ctx *ctx, grn_hash_cursor *c,
- const void *value, int flags);
-
-GRN_API int grn_hash_cursor_get_key_value(grn_ctx *ctx, grn_hash_cursor *c,
- void **key, unsigned int *key_size, void **value);
-
-GRN_API grn_rc grn_hash_cursor_delete(grn_ctx *ctx, grn_hash_cursor *c,
- grn_table_delete_optarg *optarg);
-
-#define GRN_HASH_EACH(ctx,hash,id,key,key_size,value,block) do {\
- grn_hash_cursor *_sc = grn_hash_cursor_open(ctx, hash, NULL, 0, NULL, 0, 0, -1, 0); \
- if (_sc) {\
- grn_id id;\
- while ((id = grn_hash_cursor_next(ctx, _sc))) {\
- grn_hash_cursor_get_key_value(ctx, _sc, (void **)(key),\
- (key_size), (void **)(value));\
- block\
- }\
- grn_hash_cursor_close(ctx, _sc);\
- }\
-} while (0)
-
-/* array */
-
-typedef struct _grn_array grn_array;
-typedef struct _grn_array_cursor grn_array_cursor;
-
-GRN_API grn_array *grn_array_create(grn_ctx *ctx, const char *path,
- unsigned int value_size, unsigned int flags);
-GRN_API grn_array *grn_array_open(grn_ctx *ctx, const char *path);
-GRN_API grn_rc grn_array_close(grn_ctx *ctx, grn_array *array);
-GRN_API grn_id grn_array_add(grn_ctx *ctx, grn_array *array, void **value);
-GRN_API grn_id grn_array_push(grn_ctx *ctx, grn_array *array,
- void (*func)(grn_ctx *ctx, grn_array *array,
- grn_id id, void *func_arg),
- void *func_arg);
-GRN_API grn_id grn_array_pull(grn_ctx *ctx, grn_array *array, grn_bool blockp,
- void (*func)(grn_ctx *ctx, grn_array *array,
- grn_id id, void *func_arg),
- void *func_arg);
-GRN_API void grn_array_unblock(grn_ctx *ctx, grn_array *array);
-GRN_API int grn_array_get_value(grn_ctx *ctx, grn_array *array, grn_id id, void *valuebuf);
-GRN_API grn_rc grn_array_set_value(grn_ctx *ctx, grn_array *array, grn_id id,
- const void *value, int flags);
-GRN_API grn_array_cursor *grn_array_cursor_open(grn_ctx *ctx, grn_array *array,
- grn_id min, grn_id max,
- int offset, int limit, int flags);
-GRN_API grn_id grn_array_cursor_next(grn_ctx *ctx, grn_array_cursor *cursor);
-GRN_API int grn_array_cursor_get_value(grn_ctx *ctx, grn_array_cursor *cursor, void **value);
-GRN_API grn_rc grn_array_cursor_set_value(grn_ctx *ctx, grn_array_cursor *cursor,
- const void *value, int flags);
-GRN_API grn_rc grn_array_cursor_delete(grn_ctx *ctx, grn_array_cursor *cursor,
- grn_table_delete_optarg *optarg);
-GRN_API void grn_array_cursor_close(grn_ctx *ctx, grn_array_cursor *cursor);
-GRN_API grn_rc grn_array_delete_by_id(grn_ctx *ctx, grn_array *array, grn_id id,
- grn_table_delete_optarg *optarg);
-
-GRN_API grn_id grn_array_next(grn_ctx *ctx, grn_array *array, grn_id id);
-
-GRN_API void *_grn_array_get_value(grn_ctx *ctx, grn_array *array, grn_id id);
-
-#define GRN_ARRAY_EACH(ctx,array,head,tail,id,value,block) do {\
- grn_array_cursor *_sc = grn_array_cursor_open(ctx, array, head, tail, 0, -1, 0); \
- if (_sc) {\
- grn_id id;\
- while ((id = grn_array_cursor_next(ctx, _sc))) {\
- grn_array_cursor_get_value(ctx, _sc, (void **)(value));\
- block\
- }\
- grn_array_cursor_close(ctx, _sc); \
- }\
-} while (0)
-
-/* pat */
-
-typedef struct _grn_pat grn_pat;
-typedef struct _grn_pat_cursor grn_pat_cursor;
-
-GRN_API grn_pat *grn_pat_create(grn_ctx *ctx, const char *path, unsigned int key_size,
- unsigned int value_size, unsigned int flags);
-
-GRN_API grn_pat *grn_pat_open(grn_ctx *ctx, const char *path);
-
-GRN_API grn_rc grn_pat_close(grn_ctx *ctx, grn_pat *pat);
-
-GRN_API grn_rc grn_pat_remove(grn_ctx *ctx, const char *path);
-
-GRN_API grn_id grn_pat_get(grn_ctx *ctx, grn_pat *pat, const void *key,
- unsigned int key_size, void **value);
-GRN_API grn_id grn_pat_add(grn_ctx *ctx, grn_pat *pat, const void *key,
- unsigned int key_size, void **value, int *added);
-
-GRN_API int grn_pat_get_key(grn_ctx *ctx, grn_pat *pat, grn_id id, void *keybuf, int bufsize);
-GRN_API int grn_pat_get_key2(grn_ctx *ctx, grn_pat *pat, grn_id id, grn_obj *bulk);
-GRN_API int grn_pat_get_value(grn_ctx *ctx, grn_pat *pat, grn_id id, void *valuebuf);
-GRN_API grn_rc grn_pat_set_value(grn_ctx *ctx, grn_pat *pat, grn_id id,
- const void *value, int flags);
-
-GRN_API grn_rc grn_pat_delete_by_id(grn_ctx *ctx, grn_pat *pat, grn_id id,
- grn_table_delete_optarg *optarg);
-GRN_API grn_rc grn_pat_delete(grn_ctx *ctx, grn_pat *pat, const void *key, unsigned int key_size,
- grn_table_delete_optarg *optarg);
-GRN_API int grn_pat_delete_with_sis(grn_ctx *ctx, grn_pat *pat, grn_id id,
- grn_table_delete_optarg *optarg);
-
-typedef struct _grn_table_scan_hit grn_pat_scan_hit;
-typedef struct _grn_table_scan_hit grn_dat_scan_hit;
-
struct _grn_table_scan_hit {
grn_id id;
unsigned int offset;
unsigned int length;
};
-GRN_API int grn_pat_scan(grn_ctx *ctx, grn_pat *pat, const char *str, unsigned int str_len,
- grn_pat_scan_hit *sh, unsigned int sh_size, const char **rest);
-
-GRN_API grn_rc grn_pat_prefix_search(grn_ctx *ctx, grn_pat *pat,
- const void *key, unsigned int key_size, grn_hash *h);
-GRN_API grn_rc grn_pat_suffix_search(grn_ctx *ctx, grn_pat *pat,
- const void *key, unsigned int key_size, grn_hash *h);
-GRN_API grn_id grn_pat_lcp_search(grn_ctx *ctx, grn_pat *pat,
- const void *key, unsigned int key_size);
-
-GRN_API unsigned int grn_pat_size(grn_ctx *ctx, grn_pat *pat);
-
-GRN_API grn_pat_cursor *grn_pat_cursor_open(grn_ctx *ctx, grn_pat *pat,
- const void *min, unsigned int min_size,
- const void *max, unsigned int max_size,
- int offset, int limit, int flags);
-GRN_API grn_id grn_pat_cursor_next(grn_ctx *ctx, grn_pat_cursor *c);
-GRN_API void grn_pat_cursor_close(grn_ctx *ctx, grn_pat_cursor *c);
-
-GRN_API int grn_pat_cursor_get_key(grn_ctx *ctx, grn_pat_cursor *c, void **key);
-GRN_API int grn_pat_cursor_get_value(grn_ctx *ctx, grn_pat_cursor *c, void **value);
-
-GRN_API int grn_pat_cursor_get_key_value(grn_ctx *ctx, grn_pat_cursor *c,
- void **key, unsigned int *key_size, void **value);
-GRN_API grn_rc grn_pat_cursor_set_value(grn_ctx *ctx, grn_pat_cursor *c,
- const void *value, int flags);
-GRN_API grn_rc grn_pat_cursor_delete(grn_ctx *ctx, grn_pat_cursor *c,
- grn_table_delete_optarg *optarg);
-
-#define GRN_PAT_EACH(ctx,pat,id,key,key_size,value,block) do { \
- grn_pat_cursor *_sc = grn_pat_cursor_open(ctx, pat, NULL, 0, NULL, 0, 0, -1, 0); \
- if (_sc) {\
- grn_id id;\
- while ((id = grn_pat_cursor_next(ctx, _sc))) {\
- grn_pat_cursor_get_key_value(ctx, _sc, (void **)(key),\
- (key_size), (void **)(value));\
- block\
- }\
- grn_pat_cursor_close(ctx, _sc);\
- }\
-} while (0)
-
-/* dat */
-
-typedef struct _grn_dat grn_dat;
-typedef struct _grn_dat_cursor grn_dat_cursor;
-
-GRN_API int grn_dat_scan(grn_ctx *ctx, grn_dat *dat, const char *str,
- unsigned int str_size, grn_dat_scan_hit *scan_hits,
- unsigned int max_num_scan_hits, const char **str_rest);
-
-GRN_API grn_id grn_dat_lcp_search(grn_ctx *ctx, grn_dat *dat,
- const void *key, unsigned int key_size);
-
-GRN_API grn_dat *grn_dat_create(grn_ctx *ctx, const char *path, unsigned int key_size,
- unsigned int value_size, unsigned int flags);
-
-GRN_API grn_dat *grn_dat_open(grn_ctx *ctx, const char *path);
-
-GRN_API grn_rc grn_dat_close(grn_ctx *ctx, grn_dat *dat);
-
-GRN_API grn_rc grn_dat_remove(grn_ctx *ctx, const char *path);
-
-GRN_API grn_id grn_dat_get(grn_ctx *ctx, grn_dat *dat, const void *key,
- unsigned int key_size, void **value);
-GRN_API grn_id grn_dat_add(grn_ctx *ctx, grn_dat *dat, const void *key,
- unsigned int key_size, void **value, int *added);
-
-GRN_API int grn_dat_get_key(grn_ctx *ctx, grn_dat *dat, grn_id id, void *keybuf, int bufsize);
-GRN_API int grn_dat_get_key2(grn_ctx *ctx, grn_dat *dat, grn_id id, grn_obj *bulk);
-
-GRN_API grn_rc grn_dat_delete_by_id(grn_ctx *ctx, grn_dat *dat, grn_id id,
- grn_table_delete_optarg *optarg);
-GRN_API grn_rc grn_dat_delete(grn_ctx *ctx, grn_dat *dat, const void *key, unsigned int key_size,
- grn_table_delete_optarg *optarg);
-
-GRN_API grn_rc grn_dat_update_by_id(grn_ctx *ctx, grn_dat *dat, grn_id src_key_id,
- const void *dest_key, unsigned int dest_key_size);
-GRN_API grn_rc grn_dat_update(grn_ctx *ctx, grn_dat *dat,
- const void *src_key, unsigned int src_key_size,
- const void *dest_key, unsigned int dest_key_size);
-
-GRN_API unsigned int grn_dat_size(grn_ctx *ctx, grn_dat *dat);
-
-GRN_API grn_dat_cursor *grn_dat_cursor_open(grn_ctx *ctx, grn_dat *dat,
- const void *min, unsigned int min_size,
- const void *max, unsigned int max_size,
- int offset, int limit, int flags);
-GRN_API grn_id grn_dat_cursor_next(grn_ctx *ctx, grn_dat_cursor *c);
-GRN_API void grn_dat_cursor_close(grn_ctx *ctx, grn_dat_cursor *c);
-
-GRN_API int grn_dat_cursor_get_key(grn_ctx *ctx, grn_dat_cursor *c, const void **key);
-GRN_API grn_rc grn_dat_cursor_delete(grn_ctx *ctx, grn_dat_cursor *c,
- grn_table_delete_optarg *optarg);
-
-#define GRN_DAT_EACH(ctx,dat,id,key,key_size,block) do {\
- grn_dat_cursor *_sc = grn_dat_cursor_open(ctx, dat, NULL, 0, NULL, 0, 0, -1, 0);\
- if (_sc) {\
- grn_id id;\
- unsigned int *_ks = (key_size);\
- if (_ks) {\
- while ((id = grn_dat_cursor_next(ctx, _sc))) {\
- int _ks_raw = grn_dat_cursor_get_key(ctx, _sc, (const void **)(key));\
- *(_ks) = (unsigned int)_ks_raw;\
- block\
- }\
- } else {\
- while ((id = grn_dat_cursor_next(ctx, _sc))) {\
- grn_dat_cursor_get_key(ctx, _sc, (const void **)(key));\
- block\
- }\
- }\
- grn_dat_cursor_close(ctx, _sc);\
- }\
-} while (0)
+typedef struct {
+ int64_t tv_sec;
+ int32_t tv_nsec;
+} grn_timeval;
#ifdef __cplusplus
}
#endif
-
-#endif /* GROONGA_GROONGA_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/hash.h b/storage/mroonga/vendor/groonga/include/groonga/hash.h
new file mode 100644
index 00000000000..7dc2df45f4b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/hash.h
@@ -0,0 +1,104 @@
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_HASH_TINY (0x01<<6)
+
+typedef struct _grn_hash grn_hash;
+typedef struct _grn_hash_cursor grn_hash_cursor;
+
+GRN_API grn_hash *grn_hash_create(grn_ctx *ctx, const char *path, unsigned int key_size,
+ unsigned int value_size, unsigned int flags);
+
+GRN_API grn_hash *grn_hash_open(grn_ctx *ctx, const char *path);
+
+GRN_API grn_rc grn_hash_close(grn_ctx *ctx, grn_hash *hash);
+
+GRN_API grn_id grn_hash_add(grn_ctx *ctx, grn_hash *hash, const void *key,
+ unsigned int key_size, void **value, int *added);
+GRN_API grn_id grn_hash_get(grn_ctx *ctx, grn_hash *hash, const void *key,
+ unsigned int key_size, void **value);
+
+GRN_API int grn_hash_get_key(grn_ctx *ctx, grn_hash *hash, grn_id id, void *keybuf, int bufsize);
+GRN_API int grn_hash_get_key2(grn_ctx *ctx, grn_hash *hash, grn_id id, grn_obj *bulk);
+GRN_API int grn_hash_get_value(grn_ctx *ctx, grn_hash *hash, grn_id id, void *valuebuf);
+GRN_API grn_rc grn_hash_set_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
+ const void *value, int flags);
+
+GRN_API grn_rc grn_hash_delete_by_id(grn_ctx *ctx, grn_hash *hash, grn_id id,
+ grn_table_delete_optarg *optarg);
+GRN_API grn_rc grn_hash_delete(grn_ctx *ctx, grn_hash *hash,
+ const void *key, unsigned int key_size,
+ grn_table_delete_optarg *optarg);
+
+GRN_API uint32_t grn_hash_size(grn_ctx *ctx, grn_hash *hash);
+
+GRN_API grn_hash_cursor *grn_hash_cursor_open(grn_ctx *ctx, grn_hash *hash,
+ const void *min, unsigned int min_size,
+ const void *max, unsigned int max_size,
+ int offset, int limit, int flags);
+GRN_API grn_id grn_hash_cursor_next(grn_ctx *ctx, grn_hash_cursor *c);
+GRN_API void grn_hash_cursor_close(grn_ctx *ctx, grn_hash_cursor *c);
+
+GRN_API int grn_hash_cursor_get_key(grn_ctx *ctx, grn_hash_cursor *c, void **key);
+GRN_API int grn_hash_cursor_get_value(grn_ctx *ctx, grn_hash_cursor *c, void **value);
+GRN_API grn_rc grn_hash_cursor_set_value(grn_ctx *ctx, grn_hash_cursor *c,
+ const void *value, int flags);
+
+GRN_API int grn_hash_cursor_get_key_value(grn_ctx *ctx, grn_hash_cursor *c,
+ void **key, unsigned int *key_size, void **value);
+
+GRN_API grn_rc grn_hash_cursor_delete(grn_ctx *ctx, grn_hash_cursor *c,
+ grn_table_delete_optarg *optarg);
+
+#define GRN_HASH_EACH(ctx,hash,id,key,key_size,value,block) do {\
+ grn_hash_cursor *_sc = grn_hash_cursor_open(ctx, hash, NULL, 0, NULL, 0, 0, -1, 0); \
+ if (_sc) {\
+ grn_id id;\
+ while ((id = grn_hash_cursor_next(ctx, _sc))) {\
+ grn_hash_cursor_get_key_value(ctx, _sc, (void **)(key),\
+ (key_size), (void **)(value));\
+ block\
+ }\
+ grn_hash_cursor_close(ctx, _sc);\
+ }\
+} while (0)
+
+#define GRN_HASH_EACH_BEGIN(ctx, hash, cursor, id) do {\
+ grn_hash_cursor *cursor;\
+ cursor = grn_hash_cursor_open((ctx), (hash),\
+ NULL, 0, NULL, 0,\
+ 0, -1, GRN_CURSOR_BY_ID);\
+ if (cursor) {\
+ grn_id id;\
+ while ((id = grn_hash_cursor_next((ctx), cursor)) != GRN_ID_NIL) {
+
+#define GRN_HASH_EACH_END(ctx, cursor)\
+ }\
+ grn_hash_cursor_close((ctx), cursor);\
+ }\
+} while(0)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/id.h b/storage/mroonga/vendor/groonga/include/groonga/id.h
new file mode 100644
index 00000000000..3284320edd7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/id.h
@@ -0,0 +1,31 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API grn_bool grn_id_is_builtin(grn_ctx *ctx, grn_id id);
+GRN_API grn_bool grn_id_is_builtin_type(grn_ctx *ctx, grn_id id);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/ii.h b/storage/mroonga/vendor/groonga/include/groonga/ii.h
index 176e137480c..2e8aaf7dbd1 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/ii.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/ii.h
@@ -1,5 +1,5 @@
/*
- Copyright(C) 2009-2014 Brazil
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_II_H
-#define GROONGA_II_H
+
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -27,14 +27,19 @@ extern "C" {
typedef struct _grn_ii grn_ii;
typedef struct _grn_ii_buffer grn_ii_buffer;
-GRN_API unsigned int grn_ii_estimate_size(grn_ctx *ctx, grn_ii *ii, grn_id tid);
-GRN_API unsigned int grn_ii_estimate_size_for_query(grn_ctx *ctx, grn_ii *ii,
- const char *query,
- unsigned int query_len,
- grn_search_optarg *optarg);
-GRN_API unsigned int grn_ii_estimate_size_for_lexicon_cursor(grn_ctx *ctx,
- grn_ii *ii,
- grn_table_cursor *lexicon_cursor);
+GRN_API uint32_t grn_ii_get_n_elements(grn_ctx *ctx, grn_ii *ii);
+
+GRN_API void grn_ii_cursor_set_min_enable_set(grn_bool enable);
+GRN_API grn_bool grn_ii_cursor_set_min_enable_get(void);
+
+GRN_API uint32_t grn_ii_estimate_size(grn_ctx *ctx, grn_ii *ii, grn_id tid);
+GRN_API uint32_t grn_ii_estimate_size_for_query(grn_ctx *ctx, grn_ii *ii,
+ const char *query,
+ unsigned int query_len,
+ grn_search_optarg *optarg);
+GRN_API uint32_t grn_ii_estimate_size_for_lexicon_cursor(grn_ctx *ctx,
+ grn_ii *ii,
+ grn_table_cursor *lexicon_cursor);
GRN_API grn_ii_buffer *grn_ii_buffer_open(grn_ctx *ctx, grn_ii *ii,
long long unsigned int update_buffer_size);
@@ -46,8 +51,19 @@ GRN_API grn_rc grn_ii_buffer_append(grn_ctx *ctx,
GRN_API grn_rc grn_ii_buffer_commit(grn_ctx *ctx, grn_ii_buffer *ii_buffer);
GRN_API grn_rc grn_ii_buffer_close(grn_ctx *ctx, grn_ii_buffer *ii_buffer);
+GRN_API grn_rc grn_ii_posting_add(grn_ctx *ctx, grn_posting *pos,
+ grn_hash *s, grn_operator op);
+GRN_API void grn_ii_resolve_sel_and(grn_ctx *ctx, grn_hash *s, grn_operator op);
+
+
+/* Experimental */
+typedef struct _grn_ii_cursor grn_ii_cursor;
+GRN_API grn_ii_cursor *grn_ii_cursor_open(grn_ctx *ctx, grn_ii *ii, grn_id tid,
+ grn_id min, grn_id max, int nelements, int flags);
+GRN_API grn_posting *grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c);
+GRN_API grn_posting *grn_ii_cursor_next_pos(grn_ctx *ctx, grn_ii_cursor *c);
+GRN_API grn_rc grn_ii_cursor_close(grn_ctx *ctx, grn_ii_cursor *c);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* GROONGA_II_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/nfkc.h b/storage/mroonga/vendor/groonga/include/groonga/nfkc.h
index f4e628de53c..f77ff118de4 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/nfkc.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/nfkc.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_NFKC_H
-#define GROONGA_NFKC_H
+
+#pragma once
#include <groonga.h>
@@ -23,10 +24,8 @@
extern "C" {
#endif
-GRN_API grn_char_type grn_nfkc_char_type(const unsigned char *str);
+GRN_API grn_char_type grn_nfkc_char_type(const unsigned char *utf8);
#ifdef __cplusplus
}
#endif
-
-#endif /* GROONGA_NFKC_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/normalizer.h b/storage/mroonga/vendor/groonga/include/groonga/normalizer.h
index 3ec843c6e07..82768926509 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/normalizer.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/normalizer.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2012 Brazil
+ Copyright(C) 2012-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_NORMALIER_H
-#define GROONGA_NORMALIER_H
+
+#pragma once
#include <stddef.h>
@@ -51,5 +51,3 @@ GRN_PLUGIN_EXPORT grn_rc grn_normalizer_register(grn_ctx *ctx,
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
-
-#endif /* GROONGA_NORMALIER_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/obj.h b/storage/mroonga/vendor/groonga/include/groonga/obj.h
index 7544a6cb382..7bc554950fc 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/obj.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/obj.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,22 +16,66 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_OBJ_H
-#define GROONGA_OBJ_H
+
+#pragma once
#ifdef __cplusplus
extern "C" {
#endif
+/* Just for backward compatibility. Use grn_obj_is_true() instead. */
+#define GRN_OBJ_IS_TRUE(ctx, obj, result) do { \
+ result = grn_obj_is_true(ctx, obj); \
+} while (0)
+
+GRN_API grn_bool grn_obj_is_true(grn_ctx *ctx, grn_obj *obj);
+
GRN_API grn_bool grn_obj_is_builtin(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_bulk(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_text_family_bulk(grn_ctx *ctx, grn_obj *obj);
GRN_API grn_bool grn_obj_is_table(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_column(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_scalar_column(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_vector_column(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_weight_vector_column(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_reference_column(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_data_column(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_index_column(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_accessor(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_key_accessor(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_type(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_text_family_type(grn_ctx *ctx, grn_obj *obj);
GRN_API grn_bool grn_obj_is_proc(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_tokenizer_proc(grn_ctx *ctx, grn_obj *obj);
GRN_API grn_bool grn_obj_is_function_proc(grn_ctx *ctx, grn_obj *obj);
GRN_API grn_bool grn_obj_is_selector_proc(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_selector_only_proc(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_normalizer_proc(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_token_filter_proc(grn_ctx *ctx, grn_obj *obj);
GRN_API grn_bool grn_obj_is_scorer_proc(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_window_function_proc(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_expr(grn_ctx *ctx, grn_obj *obj);
+
+GRN_API grn_rc grn_obj_cast(grn_ctx *ctx,
+ grn_obj *src,
+ grn_obj *dest,
+ grn_bool add_record_if_not_exist);
+
+GRN_API grn_rc grn_obj_reindex(grn_ctx *ctx, grn_obj *obj);
+
+GRN_API void grn_obj_touch(grn_ctx *ctx, grn_obj *obj, grn_timeval *tv);
+GRN_API uint32_t grn_obj_get_last_modified(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_bool grn_obj_is_dirty(grn_ctx *ctx, grn_obj *obj);
+
+GRN_API const char *grn_obj_type_to_string(uint8_t type);
+
+GRN_API grn_bool grn_obj_name_is_column(grn_ctx *ctx,
+ const char *name,
+ int name_len);
+
+GRN_API grn_bool grn_obj_is_corrupt(grn_ctx *ctx, grn_obj *obj);
+GRN_API size_t grn_obj_get_disk_usage(grn_ctx *ctx, grn_obj *obj);
#ifdef __cplusplus
}
#endif
-
-#endif /* GROONGA_OBJ_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/operator.h b/storage/mroonga/vendor/groonga/include/groonga/operator.h
new file mode 100644
index 00000000000..3e79e4015de
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/operator.h
@@ -0,0 +1,49 @@
+/*
+ Copyright(C) 2009-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef grn_bool grn_operator_exec_func(grn_ctx *ctx,
+ grn_obj *x,
+ grn_obj *y);
+
+GRN_API const char *grn_operator_to_string(grn_operator op);
+GRN_API grn_operator_exec_func *grn_operator_to_exec_func(grn_operator op);
+GRN_API grn_bool grn_operator_exec_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y);
+GRN_API grn_bool grn_operator_exec_not_equal(grn_ctx *ctx,
+ grn_obj *x, grn_obj *y);
+GRN_API grn_bool grn_operator_exec_less(grn_ctx *ctx, grn_obj *x, grn_obj *y);
+GRN_API grn_bool grn_operator_exec_greater(grn_ctx *ctx, grn_obj *x, grn_obj *y);
+GRN_API grn_bool grn_operator_exec_less_equal(grn_ctx *ctx,
+ grn_obj *x, grn_obj *y);
+GRN_API grn_bool grn_operator_exec_greater_equal(grn_ctx *ctx,
+ grn_obj *x, grn_obj *y);
+GRN_API grn_bool grn_operator_exec_match(grn_ctx *ctx,
+ grn_obj *target, grn_obj *sub_text);
+GRN_API grn_bool grn_operator_exec_prefix(grn_ctx *ctx,
+ grn_obj *target, grn_obj *prefix);
+GRN_API grn_bool grn_operator_exec_regexp(grn_ctx *ctx,
+ grn_obj *target, grn_obj *pattern);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/output.h b/storage/mroonga/vendor/groonga/include/groonga/output.h
index fc23bb2db01..d5241aec638 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/output.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/output.h
@@ -1,5 +1,5 @@
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_OUTPUT_H
-#define GROONGA_OUTPUT_H
+
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -58,7 +58,13 @@ struct _grn_obj_format {
#define GRN_OBJ_FORMAT_FIN(ctx,format) do {\
int ncolumns = GRN_BULK_VSIZE(&(format)->columns) / sizeof(grn_obj *);\
grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&(format)->columns);\
- while (ncolumns--) { grn_obj_unlink((ctx), *columns++); }\
+ while (ncolumns--) {\
+ grn_obj *column = *columns;\
+ columns++;\
+ if (grn_obj_is_accessor((ctx), column)) {\
+ grn_obj_close((ctx), column);\
+ }\
+ }\
GRN_OBJ_FIN((ctx), &(format)->columns);\
if ((format)->expression) { GRN_OBJ_FIN((ctx), (format)->expression); } \
} while (0)
@@ -76,8 +82,10 @@ GRN_API void grn_ctx_output_array_close(grn_ctx *ctx);
GRN_API void grn_ctx_output_map_open(grn_ctx *ctx,
const char *name, int nelements);
GRN_API void grn_ctx_output_map_close(grn_ctx *ctx);
+GRN_API void grn_ctx_output_null(grn_ctx *ctx);
GRN_API void grn_ctx_output_int32(grn_ctx *ctx, int value);
-GRN_API void grn_ctx_output_int64(grn_ctx *ctx, long long int value);
+GRN_API void grn_ctx_output_int64(grn_ctx *ctx, int64_t value);
+GRN_API void grn_ctx_output_uint64(grn_ctx *ctx, uint64_t value);
GRN_API void grn_ctx_output_float(grn_ctx *ctx, double value);
GRN_API void grn_ctx_output_cstr(grn_ctx *ctx, const char *value);
GRN_API void grn_ctx_output_str(grn_ctx *ctx,
@@ -85,6 +93,16 @@ GRN_API void grn_ctx_output_str(grn_ctx *ctx,
GRN_API void grn_ctx_output_bool(grn_ctx *ctx, grn_bool value);
GRN_API void grn_ctx_output_obj(grn_ctx *ctx,
grn_obj *value, grn_obj_format *format);
+GRN_API void grn_ctx_output_result_set_open(grn_ctx *ctx,
+ grn_obj *result_set,
+ grn_obj_format *format,
+ uint32_t n_additional_elements);
+GRN_API void grn_ctx_output_result_set_close(grn_ctx *ctx,
+ grn_obj *result_set,
+ grn_obj_format *format);
+GRN_API void grn_ctx_output_result_set(grn_ctx *ctx,
+ grn_obj *result_set,
+ grn_obj_format *format);
GRN_API void grn_ctx_output_table_columns(grn_ctx *ctx,
grn_obj *table,
grn_obj_format *format);
@@ -104,5 +122,3 @@ GRN_API grn_rc grn_text_otoj(grn_ctx *ctx, grn_obj *bulk, grn_obj *obj,
#ifdef __cplusplus
}
#endif
-
-#endif /* GROONGA_OUTPUT_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/pat.h b/storage/mroonga/vendor/groonga/include/groonga/pat.h
new file mode 100644
index 00000000000..27f45c0f63c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/pat.h
@@ -0,0 +1,102 @@
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "hash.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _grn_pat grn_pat;
+typedef struct _grn_pat_cursor grn_pat_cursor;
+typedef struct _grn_table_scan_hit grn_pat_scan_hit;
+
+GRN_API grn_pat *grn_pat_create(grn_ctx *ctx, const char *path, unsigned int key_size,
+ unsigned int value_size, unsigned int flags);
+
+GRN_API grn_pat *grn_pat_open(grn_ctx *ctx, const char *path);
+
+GRN_API grn_rc grn_pat_close(grn_ctx *ctx, grn_pat *pat);
+
+GRN_API grn_rc grn_pat_remove(grn_ctx *ctx, const char *path);
+
+GRN_API grn_id grn_pat_get(grn_ctx *ctx, grn_pat *pat, const void *key,
+ unsigned int key_size, void **value);
+GRN_API grn_id grn_pat_add(grn_ctx *ctx, grn_pat *pat, const void *key,
+ unsigned int key_size, void **value, int *added);
+
+GRN_API int grn_pat_get_key(grn_ctx *ctx, grn_pat *pat, grn_id id, void *keybuf, int bufsize);
+GRN_API int grn_pat_get_key2(grn_ctx *ctx, grn_pat *pat, grn_id id, grn_obj *bulk);
+GRN_API int grn_pat_get_value(grn_ctx *ctx, grn_pat *pat, grn_id id, void *valuebuf);
+GRN_API grn_rc grn_pat_set_value(grn_ctx *ctx, grn_pat *pat, grn_id id,
+ const void *value, int flags);
+
+GRN_API grn_rc grn_pat_delete_by_id(grn_ctx *ctx, grn_pat *pat, grn_id id,
+ grn_table_delete_optarg *optarg);
+GRN_API grn_rc grn_pat_delete(grn_ctx *ctx, grn_pat *pat, const void *key, unsigned int key_size,
+ grn_table_delete_optarg *optarg);
+GRN_API int grn_pat_delete_with_sis(grn_ctx *ctx, grn_pat *pat, grn_id id,
+ grn_table_delete_optarg *optarg);
+
+GRN_API int grn_pat_scan(grn_ctx *ctx, grn_pat *pat, const char *str, unsigned int str_len,
+ grn_pat_scan_hit *sh, unsigned int sh_size, const char **rest);
+
+GRN_API grn_rc grn_pat_prefix_search(grn_ctx *ctx, grn_pat *pat,
+ const void *key, unsigned int key_size, grn_hash *h);
+GRN_API grn_rc grn_pat_suffix_search(grn_ctx *ctx, grn_pat *pat,
+ const void *key, unsigned int key_size, grn_hash *h);
+GRN_API grn_id grn_pat_lcp_search(grn_ctx *ctx, grn_pat *pat,
+ const void *key, unsigned int key_size);
+
+GRN_API unsigned int grn_pat_size(grn_ctx *ctx, grn_pat *pat);
+
+GRN_API grn_pat_cursor *grn_pat_cursor_open(grn_ctx *ctx, grn_pat *pat,
+ const void *min, unsigned int min_size,
+ const void *max, unsigned int max_size,
+ int offset, int limit, int flags);
+GRN_API grn_id grn_pat_cursor_next(grn_ctx *ctx, grn_pat_cursor *c);
+GRN_API void grn_pat_cursor_close(grn_ctx *ctx, grn_pat_cursor *c);
+
+GRN_API int grn_pat_cursor_get_key(grn_ctx *ctx, grn_pat_cursor *c, void **key);
+GRN_API int grn_pat_cursor_get_value(grn_ctx *ctx, grn_pat_cursor *c, void **value);
+
+GRN_API int grn_pat_cursor_get_key_value(grn_ctx *ctx, grn_pat_cursor *c,
+ void **key, unsigned int *key_size, void **value);
+GRN_API grn_rc grn_pat_cursor_set_value(grn_ctx *ctx, grn_pat_cursor *c,
+ const void *value, int flags);
+GRN_API grn_rc grn_pat_cursor_delete(grn_ctx *ctx, grn_pat_cursor *c,
+ grn_table_delete_optarg *optarg);
+
+#define GRN_PAT_EACH(ctx,pat,id,key,key_size,value,block) do { \
+ grn_pat_cursor *_sc = grn_pat_cursor_open(ctx, pat, NULL, 0, NULL, 0, 0, -1, 0); \
+ if (_sc) {\
+ grn_id id;\
+ while ((id = grn_pat_cursor_next(ctx, _sc))) {\
+ grn_pat_cursor_get_key_value(ctx, _sc, (void **)(key),\
+ (key_size), (void **)(value));\
+ block\
+ }\
+ grn_pat_cursor_close(ctx, _sc);\
+ }\
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/plugin.h b/storage/mroonga/vendor/groonga/include/groonga/plugin.h
index 98ca6961407..d241444549f 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/plugin.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/plugin.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2010-2014 Brazil
+ Copyright(C) 2010-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_PLUGIN_H
-#define GROONGA_PLUGIN_H
+
+#pragma once
#include <stddef.h>
@@ -62,17 +62,34 @@ GRN_PLUGIN_EXPORT grn_rc GRN_PLUGIN_FIN(grn_ctx *ctx);
/*
Don't call these functions directly. Use GRN_PLUGIN_MALLOC(),
- GRN_PLUGIN_REALLOC() and GRN_PLUGIN_FREE() instead.
+ GRN_PLUGIN_CALLOC(), GRN_PLUGIN_REALLOC() and GRN_PLUGIN_FREE() instead.
*/
-GRN_API void *grn_plugin_malloc(grn_ctx *ctx, size_t size, const char *file,
- int line, const char *func);
-GRN_API void *grn_plugin_realloc(grn_ctx *ctx, void *ptr, size_t size,
- const char *file, int line, const char *func);
+GRN_API void *grn_plugin_malloc(grn_ctx *ctx,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(2);
+GRN_API void *grn_plugin_calloc(grn_ctx *ctx,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(2);
+GRN_API void *grn_plugin_realloc(grn_ctx *ctx,
+ void *ptr,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(3);
GRN_API void grn_plugin_free(grn_ctx *ctx, void *ptr, const char *file,
int line, const char *func);
#define GRN_PLUGIN_MALLOC(ctx, size) \
grn_plugin_malloc((ctx), (size), __FILE__, __LINE__, __FUNCTION__)
+#define GRN_PLUGIN_MALLOCN(ctx, type, n) \
+ ((type *)(grn_plugin_malloc((ctx), sizeof(type) * (n), \
+ __FILE__, __LINE__, __FUNCTION__)))
+#define GRN_PLUGIN_CALLOC(ctx, size) \
+ grn_plugin_calloc((ctx), (size), __FILE__, __LINE__, __FUNCTION__)
#define GRN_PLUGIN_REALLOC(ctx, ptr, size) \
grn_plugin_realloc((ctx), (ptr), (size), __FILE__, __LINE__, __FUNCTION__)
#define GRN_PLUGIN_FREE(ctx, ptr) \
@@ -89,6 +106,8 @@ GRN_API void grn_plugin_set_error(grn_ctx *ctx, grn_log_level level,
grn_rc error_code,
const char *file, int line, const char *func,
const char *format, ...) GRN_ATTRIBUTE_PRINTF(7);
+GRN_API void grn_plugin_clear_error(grn_ctx *ctx);
+
/*
Don't call these functions directly. grn_plugin_backtrace() and
@@ -104,14 +123,15 @@ GRN_API void grn_plugin_logtrace(grn_ctx *ctx, grn_log_level level);
#define GRN_PLUGIN_SET_ERROR(ctx, level, error_code, ...) do { \
grn_plugin_set_error(ctx, level, error_code, \
__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__); \
- GRN_LOG(ctx, level, __VA_ARGS__); \
- grn_plugin_backtrace(ctx); \
- grn_plugin_logtrace(ctx, level); \
} while (0)
#define GRN_PLUGIN_ERROR(ctx, error_code, ...) \
GRN_PLUGIN_SET_ERROR(ctx, GRN_LOG_ERROR, error_code, __VA_ARGS__)
+#define GRN_PLUGIN_CLEAR_ERROR(ctx) do { \
+ grn_plugin_clear_error((ctx)); \
+} while (0)
+
typedef struct _grn_plugin_mutex grn_plugin_mutex;
GRN_API grn_plugin_mutex *grn_plugin_mutex_open(grn_ctx *ctx);
@@ -135,18 +155,43 @@ GRN_API void grn_plugin_mutex_lock(grn_ctx *ctx, grn_plugin_mutex *mutex);
GRN_API void grn_plugin_mutex_unlock(grn_ctx *ctx, grn_plugin_mutex *mutex);
GRN_API grn_obj *grn_plugin_proc_alloc(grn_ctx *ctx, grn_user_data *user_data,
- grn_id domain, grn_obj_flags flags);
+ grn_id domain, unsigned char flags);
GRN_API grn_obj *grn_plugin_proc_get_vars(grn_ctx *ctx, grn_user_data *user_data);
GRN_API grn_obj *grn_plugin_proc_get_var(grn_ctx *ctx, grn_user_data *user_data,
const char *name, int name_size);
+GRN_API grn_bool grn_plugin_proc_get_var_bool(grn_ctx *ctx,
+ grn_user_data *user_data,
+ const char *name,
+ int name_size,
+ grn_bool default_value);
+GRN_API int32_t grn_plugin_proc_get_var_int32(grn_ctx *ctx,
+ grn_user_data *user_data,
+ const char *name,
+ int name_size,
+ int32_t default_value);
+GRN_API const char *grn_plugin_proc_get_var_string(grn_ctx *ctx,
+ grn_user_data *user_data,
+ const char *name,
+ int name_size,
+ size_t *size);
+GRN_API grn_content_type grn_plugin_proc_get_var_content_type(grn_ctx *ctx,
+ grn_user_data *user_data,
+ const char *name,
+ int name_size,
+ grn_content_type default_value);
GRN_API grn_obj *grn_plugin_proc_get_var_by_offset(grn_ctx *ctx,
grn_user_data *user_data,
unsigned int offset);
+GRN_API grn_obj *grn_plugin_proc_get_caller(grn_ctx *ctx,
+ grn_user_data *user_data);
+
+/* Deprecated since 5.0.9. Use grn_plugin_windows_base_dir() instead. */
GRN_API const char *grn_plugin_win32_base_dir(void);
+GRN_API const char *grn_plugin_windows_base_dir(void);
GRN_API int grn_plugin_charlen(grn_ctx *ctx, const char *str_ptr,
unsigned int str_length, grn_encoding encoding);
@@ -159,16 +204,14 @@ GRN_API grn_rc grn_plugin_expr_var_init(grn_ctx *ctx,
const char *name,
int name_size);
-GRN_API grn_obj * grn_plugin_command_create(grn_ctx *ctx,
- const char *name,
- int name_size,
- grn_proc_func func,
- unsigned int n_vars,
- grn_expr_var *vars);
+GRN_API grn_obj *grn_plugin_command_create(grn_ctx *ctx,
+ const char *name,
+ int name_size,
+ grn_proc_func func,
+ unsigned int n_vars,
+ grn_expr_var *vars);
#ifdef __cplusplus
}
#endif
-
-#endif /* GROONGA_PLUGIN_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/portability.h b/storage/mroonga/vendor/groonga/include/groonga/portability.h
index 1d763765c2c..a45ba2f5702 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/portability.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/portability.h
@@ -1,5 +1,5 @@
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_PORTABILITY_H
-#define GROONGA_PORTABILITY_H
+
+#pragma once
#ifdef WIN32
# ifdef __cplusplus
@@ -118,11 +118,38 @@
#endif /* WIN32 */
#ifdef WIN32
-# define grn_snprintf(dest, dest_size, n, format, ...) \
- _snprintf_s((dest), (dest_size), (n) - 1, (format), __VA_ARGS__)
+# define grn_strcasecmp(string1, string2) \
+ _stricmp((string1), (string2))
+#else /* WIN32 */
+# define grn_strcasecmp(string1, string2) \
+ strcasecmp((string1), (string2))
+#endif /* WIN32 */
+
+#ifdef WIN32
+# define grn_strncasecmp(string1, string2, n) \
+ _strnicmp((string1), (string2), (n))
+#else /* WIN32 */
+# define grn_strncasecmp(string1, string2, n) \
+ strncasecmp((string1), (string2), (n))
+#endif /* WIN32 */
+
+#ifdef WIN32
+# define grn_snprintf(dest, dest_size, n, ...) do { \
+ _snprintf_s((dest), (dest_size), (n) - 1, __VA_ARGS__); \
+ } while (GRN_FALSE)
+#else /* WIN32 */
+# define grn_snprintf(dest, dest_size, n, ...) \
+ snprintf((dest), (n), __VA_ARGS__)
+#endif /* WIN32 */
+
+#ifdef WIN32
+# define grn_vsnprintf(dest, dest_size, format, args) do { \
+ vsnprintf((dest), (dest_size), (format), (args)); \
+ (dest)[(dest_size) - 1] = '\0'; \
+ } while (GRN_FALSE)
#else /* WIN32 */
-# define grn_snprintf(dest, dest_size, n, format, ...) \
- snprintf((dest), (n), (format), __VA_ARGS__)
+# define grn_vsnprintf(dest, dest_size, format, args) \
+ vsnprintf((dest), (dest_size), (format), (args))
#endif /* WIN32 */
#ifdef WIN32
@@ -155,4 +182,20 @@
# define grn_close(fd) close((fd))
#endif /* WIN32 */
-#endif /* GROONGA_PORTABILITY_H */
+#ifdef WIN32
+# define grn_fileno(stream) _fileno((stream))
+#else /* WIN32 */
+# define grn_fileno(stream) fileno((stream))
+#endif /* WIN32 */
+
+#ifdef WIN32
+# define grn_isatty(stream) _isatty((stream))
+#else /* WIN32 */
+# define grn_isatty(stream) isatty((stream))
+#endif /* WIN32 */
+
+#ifdef WIN32
+# define grn_getpid() _getpid()
+#else /* WIN32 */
+# define grn_getpid() getpid()
+#endif /* WIN32 */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/request_canceler.h b/storage/mroonga/vendor/groonga/include/groonga/request_canceler.h
index 0032a778c25..a837b606a38 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/request_canceler.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/request_canceler.h
@@ -1,5 +1,5 @@
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_REQUEST_CANCELER_H
-#define GROONGA_REQUEST_CANCELER_H
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -31,9 +30,8 @@ GRN_API void grn_request_canceler_unregister(grn_ctx *ctx,
unsigned int size);
GRN_API grn_bool grn_request_canceler_cancel(const char *request_id,
unsigned int size);
+GRN_API grn_bool grn_request_canceler_cancel_all(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* GROONGA_REQUEST_CANCELER_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/request_timer.h b/storage/mroonga/vendor/groonga/include/groonga/request_timer.h
new file mode 100644
index 00000000000..ccc093b0595
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/request_timer.h
@@ -0,0 +1,53 @@
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _grn_request_timer {
+ void *user_data;
+ void *(*register_func)(const char *request_id,
+ unsigned int request_id_size,
+ double timeout,
+ void *user_data);
+ void (*unregister_func)(void *timer_id,
+ void *user_data);
+ void (*fin_func)(void *user_data);
+} grn_request_timer;
+
+/* Multithreading unsafe. */
+GRN_API void grn_request_timer_set(grn_request_timer *timer);
+
+/* Multithreading safety is depends on grn_request_timer. */
+GRN_API void *grn_request_timer_register(const char *request_id,
+ unsigned int request_id_size,
+ double timeout);
+/* Multithreading safety is depends on grn_request_timer. */
+GRN_API void grn_request_timer_unregister(void *timer_id);
+
+
+GRN_API double grn_get_default_request_timeout(void);
+GRN_API void grn_set_default_request_timeout(double timeout);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/scorer.h b/storage/mroonga/vendor/groonga/include/groonga/scorer.h
index 6f9c589affb..7ee3f92a1c0 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/scorer.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/scorer.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_SCORER_H
-#define GROONGA_SCORER_H
+
+#pragma once
#include <groonga/plugin.h>
@@ -74,7 +74,7 @@ typedef double grn_scorer_score_func(grn_ctx *ctx,
/*
grn_scorer_register() registers a plugin to the database which is
- associated with `ctx'. `plugin_name_ptr' and `plugin_name_length' specify the
+ associated with `ctx'. `scorer_name_ptr' and `scorer_name_length' specify the
plugin name. Alphabetic letters ('A'-'Z' and 'a'-'z'), digits ('0'-'9') and
an underscore ('_') are capable characters.
@@ -84,12 +84,10 @@ typedef double grn_scorer_score_func(grn_ctx *ctx,
code on failure.
*/
GRN_PLUGIN_EXPORT grn_rc grn_scorer_register(grn_ctx *ctx,
- const char *plugin_name_ptr,
- int plugin_name_length,
+ const char *scorer_name_ptr,
+ int scorer_name_length,
grn_scorer_score_func *score);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
-
-#endif /* GROONGA_SCORER_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/table.h b/storage/mroonga/vendor/groonga/include/groonga/table.h
new file mode 100644
index 00000000000..f9de43f46e8
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/table.h
@@ -0,0 +1,246 @@
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_TABLE_MAX_KEY_SIZE (0x1000)
+
+GRN_API grn_obj *grn_table_create(grn_ctx *ctx,
+ const char *name, unsigned int name_size,
+ const char *path, grn_table_flags flags,
+ grn_obj *key_type, grn_obj *value_type);
+
+#define GRN_TABLE_OPEN_OR_CREATE(ctx,name,name_size,path,flags,key_type,value_type,table) \
+ (((table) = grn_ctx_get((ctx), (name), (name_size))) ||\
+ ((table) = grn_table_create((ctx), (name), (name_size), (path), (flags), (key_type), (value_type))))
+
+/* TODO: int *added -> grn_bool *added */
+GRN_API grn_id grn_table_add(grn_ctx *ctx, grn_obj *table,
+ const void *key, unsigned int key_size, int *added);
+GRN_API grn_id grn_table_get(grn_ctx *ctx, grn_obj *table,
+ const void *key, unsigned int key_size);
+GRN_API grn_id grn_table_at(grn_ctx *ctx, grn_obj *table, grn_id id);
+GRN_API grn_id grn_table_lcp_search(grn_ctx *ctx, grn_obj *table,
+ const void *key, unsigned int key_size);
+GRN_API int grn_table_get_key(grn_ctx *ctx, grn_obj *table,
+ grn_id id, void *keybuf, int buf_size);
+GRN_API grn_rc grn_table_delete(grn_ctx *ctx, grn_obj *table,
+ const void *key, unsigned int key_size);
+GRN_API grn_rc grn_table_delete_by_id(grn_ctx *ctx, grn_obj *table, grn_id id);
+GRN_API grn_rc grn_table_update_by_id(grn_ctx *ctx, grn_obj *table, grn_id id,
+ const void *dest_key, unsigned int dest_key_size);
+GRN_API grn_rc grn_table_update(grn_ctx *ctx, grn_obj *table,
+ const void *src_key, unsigned int src_key_size,
+ const void *dest_key, unsigned int dest_key_size);
+GRN_API grn_rc grn_table_truncate(grn_ctx *ctx, grn_obj *table);
+
+#define GRN_CURSOR_ASCENDING (0x00<<0)
+#define GRN_CURSOR_DESCENDING (0x01<<0)
+#define GRN_CURSOR_GE (0x00<<1)
+#define GRN_CURSOR_GT (0x01<<1)
+#define GRN_CURSOR_LE (0x00<<2)
+#define GRN_CURSOR_LT (0x01<<2)
+#define GRN_CURSOR_BY_KEY (0x00<<3)
+#define GRN_CURSOR_BY_ID (0x01<<3)
+#define GRN_CURSOR_PREFIX (0x01<<4)
+#define GRN_CURSOR_SIZE_BY_BIT (0x01<<5)
+#define GRN_CURSOR_RK (0x01<<6)
+
+GRN_API grn_table_cursor *grn_table_cursor_open(grn_ctx *ctx, grn_obj *table,
+ const void *min, unsigned int min_size,
+ const void *max, unsigned int max_size,
+ int offset, int limit, int flags);
+GRN_API grn_rc grn_table_cursor_close(grn_ctx *ctx, grn_table_cursor *tc);
+GRN_API grn_id grn_table_cursor_next(grn_ctx *ctx, grn_table_cursor *tc);
+GRN_API int grn_table_cursor_get_key(grn_ctx *ctx, grn_table_cursor *tc, void **key);
+GRN_API int grn_table_cursor_get_value(grn_ctx *ctx, grn_table_cursor *tc, void **value);
+GRN_API grn_rc grn_table_cursor_set_value(grn_ctx *ctx, grn_table_cursor *tc,
+ const void *value, int flags);
+GRN_API grn_rc grn_table_cursor_delete(grn_ctx *ctx, grn_table_cursor *tc);
+GRN_API grn_obj *grn_table_cursor_table(grn_ctx *ctx, grn_table_cursor *tc);
+
+GRN_API grn_obj *grn_index_cursor_open(grn_ctx *ctx, grn_table_cursor *tc, grn_obj *index,
+ grn_id rid_min, grn_id rid_max, int flags);
+GRN_API grn_posting *grn_index_cursor_next(grn_ctx *ctx, grn_obj *ic, grn_id *tid);
+
+#define GRN_TABLE_EACH(ctx,table,head,tail,id,key,key_size,value,block) do {\
+ (ctx)->errlvl = GRN_LOG_NOTICE;\
+ (ctx)->rc = GRN_SUCCESS;\
+ if ((ctx)->seqno & 1) {\
+ (ctx)->subno++;\
+ } else {\
+ (ctx)->seqno++;\
+ }\
+ if (table) {\
+ switch ((table)->header.type) {\
+ case GRN_TABLE_PAT_KEY :\
+ GRN_PAT_EACH((ctx), (grn_pat *)(table), (id), (key), (key_size), (value), block);\
+ break;\
+ case GRN_TABLE_DAT_KEY :\
+ GRN_DAT_EACH((ctx), (grn_dat *)(table), (id), (key), (key_size), block);\
+ break;\
+ case GRN_TABLE_HASH_KEY :\
+ GRN_HASH_EACH((ctx), (grn_hash *)(table), (id), (key), (key_size), (value), block);\
+ break;\
+ case GRN_TABLE_NO_KEY :\
+ GRN_ARRAY_EACH((ctx), (grn_array *)(table), (head), (tail), (id), (value), block);\
+ break;\
+ }\
+ }\
+ if ((ctx)->subno) {\
+ (ctx)->subno--;\
+ } else {\
+ (ctx)->seqno++;\
+ }\
+} while (0)
+
+#define GRN_TABLE_EACH_BEGIN(ctx, table, cursor, id) do {\
+ if ((table)) {\
+ grn_table_cursor *cursor;\
+ cursor = grn_table_cursor_open((ctx), (table),\
+ NULL, 0,\
+ NULL, 0,\
+ 0, -1, GRN_CURSOR_ASCENDING);\
+ if (cursor) {\
+ grn_id id;\
+ while ((id = grn_table_cursor_next((ctx), cursor))) {
+
+#define GRN_TABLE_EACH_BEGIN_FLAGS(ctx, table, cursor, id, flags) do {\
+ if ((table)) {\
+ grn_table_cursor *cursor;\
+ cursor = grn_table_cursor_open((ctx), (table),\
+ NULL, 0,\
+ NULL, 0,\
+ 0, -1, (flags));\
+ if (cursor) {\
+ grn_id id;\
+ while ((id = grn_table_cursor_next((ctx), cursor))) {
+
+#define GRN_TABLE_EACH_BEGIN_MIN(ctx, table, cursor, id,\
+ min, min_size, flags) do {\
+ if ((table)) {\
+ grn_table_cursor *cursor;\
+ cursor = grn_table_cursor_open((ctx), (table),\
+ (min), (min_size),\
+ NULL, 0,\
+ 0, -1, (flags));\
+ if (cursor) {\
+ grn_id id;\
+ while ((id = grn_table_cursor_next((ctx), cursor))) {
+
+#define GRN_TABLE_EACH_END(ctx, cursor)\
+ }\
+ grn_table_cursor_close((ctx), cursor);\
+ }\
+ }\
+} while (0)
+
+typedef struct _grn_table_sort_key grn_table_sort_key;
+typedef unsigned char grn_table_sort_flags;
+
+#define GRN_TABLE_SORT_ASC (0x00<<0)
+#define GRN_TABLE_SORT_DESC (0x01<<0)
+
+struct _grn_table_sort_key {
+ grn_obj *key;
+ grn_table_sort_flags flags;
+ int offset;
+};
+
+GRN_API int grn_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit,
+ grn_obj *result, grn_table_sort_key *keys, int n_keys);
+
+typedef struct _grn_table_group_result grn_table_group_result;
+typedef uint32_t grn_table_group_flags;
+
+#define GRN_TABLE_GROUP_CALC_COUNT (0x01<<3)
+#define GRN_TABLE_GROUP_CALC_MAX (0x01<<4)
+#define GRN_TABLE_GROUP_CALC_MIN (0x01<<5)
+#define GRN_TABLE_GROUP_CALC_SUM (0x01<<6)
+#define GRN_TABLE_GROUP_CALC_AVG (0x01<<7)
+
+struct _grn_table_group_result {
+ grn_obj *table;
+ unsigned char key_begin;
+ unsigned char key_end;
+ int limit;
+ grn_table_group_flags flags;
+ grn_operator op;
+ unsigned int max_n_subrecs;
+ grn_obj *calc_target;
+};
+
+GRN_API grn_rc grn_table_group(grn_ctx *ctx, grn_obj *table,
+ grn_table_sort_key *keys, int n_keys,
+ grn_table_group_result *results, int n_results);
+GRN_API grn_rc grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2,
+ grn_obj *res, grn_operator op);
+GRN_API grn_rc grn_table_difference(grn_ctx *ctx, grn_obj *table1, grn_obj *table2,
+ grn_obj *res1, grn_obj *res2);
+GRN_API int grn_table_columns(grn_ctx *ctx, grn_obj *table,
+ const char *name, unsigned int name_size,
+ grn_obj *res);
+
+GRN_API unsigned int grn_table_size(grn_ctx *ctx, grn_obj *table);
+
+GRN_API grn_rc grn_table_rename(grn_ctx *ctx, grn_obj *table,
+ const char *name, unsigned int name_size);
+
+GRN_API grn_obj *grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
+ grn_obj *res, grn_operator op);
+
+GRN_API grn_table_sort_key *grn_table_sort_key_from_str(grn_ctx *ctx,
+ const char *str, unsigned int str_size,
+ grn_obj *table, unsigned int *nkeys);
+GRN_API grn_rc grn_table_sort_key_close(grn_ctx *ctx,
+ grn_table_sort_key *keys, unsigned int nkeys);
+
+GRN_API grn_bool grn_table_is_grouped(grn_ctx *ctx, grn_obj *table);
+
+GRN_API unsigned int grn_table_max_n_subrecs(grn_ctx *ctx, grn_obj *table);
+
+GRN_API grn_obj *grn_table_create_for_group(grn_ctx *ctx,
+ const char *name,
+ unsigned int name_size,
+ const char *path,
+ grn_obj *group_key,
+ grn_obj *value_type,
+ unsigned int max_n_subrecs);
+
+GRN_API unsigned int grn_table_get_subrecs(grn_ctx *ctx, grn_obj *table,
+ grn_id id, grn_id *subrecbuf,
+ int *scorebuf, int buf_size);
+
+GRN_API grn_obj *grn_table_tokenize(grn_ctx *ctx, grn_obj *table,
+ const char *str, unsigned int str_len,
+ grn_obj *buf, grn_bool addp);
+
+GRN_API grn_rc grn_table_apply_expr(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *output_column,
+ grn_obj *expr);
+
+GRN_API grn_id grn_table_find_reference_object(grn_ctx *ctx, grn_obj *table);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/thread.h b/storage/mroonga/vendor/groonga/include/groonga/thread.h
new file mode 100644
index 00000000000..c7c8f80147b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/thread.h
@@ -0,0 +1,39 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API uint32_t grn_thread_get_limit(void);
+GRN_API void grn_thread_set_limit(uint32_t new_limit);
+
+
+typedef uint32_t (*grn_thread_get_limit_func)(void *data);
+GRN_API void grn_thread_set_get_limit_func(grn_thread_get_limit_func func,
+ void *data);
+typedef void (*grn_thread_set_limit_func)(uint32_t new_limit, void *data);
+GRN_API void grn_thread_set_set_limit_func(grn_thread_set_limit_func func,
+ void *data);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/time.h b/storage/mroonga/vendor/groonga/include/groonga/time.h
new file mode 100644
index 00000000000..44379598e8e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/time.h
@@ -0,0 +1,61 @@
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_TIMEVAL_TO_MSEC(timeval) \
+ (((timeval)->tv_sec * GRN_TIME_MSEC_PER_SEC) + \
+ ((timeval)->tv_nsec / GRN_TIME_NSEC_PER_MSEC))
+
+#define GRN_TIME_NSEC_PER_SEC 1000000000
+#define GRN_TIME_NSEC_PER_SEC_F 1000000000.0
+#define GRN_TIME_NSEC_PER_MSEC 1000000
+#define GRN_TIME_NSEC_PER_USEC (GRN_TIME_NSEC_PER_SEC / GRN_TIME_USEC_PER_SEC)
+#define GRN_TIME_MSEC_PER_SEC 1000
+#define GRN_TIME_NSEC_TO_USEC(nsec) ((nsec) / GRN_TIME_NSEC_PER_USEC)
+#define GRN_TIME_USEC_TO_NSEC(usec) ((usec) * GRN_TIME_NSEC_PER_USEC)
+
+#define GRN_TIME_USEC_PER_SEC 1000000
+#define GRN_TIME_PACK(sec, usec) ((int64_t)(sec) * GRN_TIME_USEC_PER_SEC + (usec))
+#define GRN_TIME_UNPACK(time_value, sec, usec) do {\
+ sec = (time_value) / GRN_TIME_USEC_PER_SEC;\
+ usec = (time_value) % GRN_TIME_USEC_PER_SEC;\
+} while (0)
+
+GRN_API grn_rc grn_timeval_now(grn_ctx *ctx, grn_timeval *tv);
+
+GRN_API void grn_time_now(grn_ctx *ctx, grn_obj *obj);
+
+#define GRN_TIME_NOW(ctx,obj) (grn_time_now((ctx), (obj)))
+
+GRN_API grn_bool grn_time_to_tm(grn_ctx *ctx,
+ int64_t time,
+ struct tm *tm);
+GRN_API grn_bool grn_time_from_tm(grn_ctx *ctx,
+ int64_t *time,
+ struct tm *tm);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/token.h b/storage/mroonga/vendor/groonga/include/groonga/token.h
index 5aeaf0b4361..af5e656a305 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/token.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/token.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_TOKEN_H
-#define GROONGA_TOKEN_H
+
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -36,7 +36,8 @@ extern "C" {
typedef enum {
GRN_TOKENIZE_GET = 0,
GRN_TOKENIZE_ADD,
- GRN_TOKENIZE_DELETE
+ GRN_TOKENIZE_DELETE,
+ GRN_TOKENIZE_ONLY
} grn_tokenize_mode;
/*
@@ -132,5 +133,3 @@ GRN_PLUGIN_EXPORT grn_rc grn_token_set_status(grn_ctx *ctx,
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
-
-#endif /* GROONGA_TOKEN_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/token_filter.h b/storage/mroonga/vendor/groonga/include/groonga/token_filter.h
index 9c5a3567b3b..6b09add127d 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/token_filter.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/token_filter.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_TOKEN_FILTER_H
-#define GROONGA_TOKEN_FILTER_H
+
+#pragma once
#include <groonga/tokenizer.h>
@@ -65,5 +65,3 @@ GRN_PLUGIN_EXPORT grn_rc grn_token_filter_register(grn_ctx *ctx,
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
-
-#endif /* GROONGA_TOKEN_FILTER_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/tokenizer.h b/storage/mroonga/vendor/groonga/include/groonga/tokenizer.h
index 8ad7f6757f4..bdb1c41aa3a 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/tokenizer.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/tokenizer.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2012 Brazil
+ Copyright(C) 2012-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_TOKENIZER_H
-#define GROONGA_TOKENIZER_H
+
+#pragma once
#include <groonga/plugin.h>
#include <groonga/token.h>
@@ -258,5 +258,3 @@ GRN_PLUGIN_EXPORT grn_rc grn_tokenizer_register(grn_ctx *ctx, const char *plugin
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
-
-#endif /* GROONGA_TOKENIZER_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/type.h b/storage/mroonga/vendor/groonga/include/groonga/type.h
new file mode 100644
index 00000000000..c68dcd1acd7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/type.h
@@ -0,0 +1,40 @@
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Just for backward compatibility.
+ Use grn_type_id_is_text_family() instead. */
+#define GRN_TYPE_IS_TEXT_FAMILY(type) \
+ grn_type_id_is_text_family(NULL, (type))
+
+GRN_API grn_bool grn_type_id_is_builtin(grn_ctx *ctx, grn_id id);
+GRN_API grn_bool grn_type_id_is_number_family(grn_ctx *ctx, grn_id id);
+GRN_API grn_bool grn_type_id_is_text_family(grn_ctx *ctx, grn_id id);
+
+GRN_API grn_obj *grn_type_create(grn_ctx *ctx, const char *name, unsigned int name_size,
+ grn_obj_flags flags, unsigned int size);
+GRN_API uint32_t grn_type_size(grn_ctx *ctx, grn_obj *type);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/util.h b/storage/mroonga/vendor/groonga/include/groonga/util.h
index 446cb88f8c3..0a574c665bf 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/util.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/util.h
@@ -1,5 +1,5 @@
/*
- Copyright(C) 2010-2014 Brazil
+ Copyright(C) 2010-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GROONGA_UTIL_H
-#define GROONGA_UTIL_H
+
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -25,9 +25,15 @@ extern "C" {
GRN_API grn_obj *grn_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *obj);
GRN_API grn_obj *grn_inspect_indented(grn_ctx *ctx, grn_obj *buffer,
grn_obj *obj, const char *indent);
+GRN_API grn_obj *grn_inspect_limited(grn_ctx *ctx,
+ grn_obj *buffer,
+ grn_obj *obj);
GRN_API grn_obj *grn_inspect_name(grn_ctx *ctx, grn_obj *buffer, grn_obj *obj);
GRN_API grn_obj *grn_inspect_encoding(grn_ctx *ctx, grn_obj *buffer, grn_encoding encoding);
GRN_API grn_obj *grn_inspect_type(grn_ctx *ctx, grn_obj *buffer, unsigned char type);
+GRN_API grn_obj *grn_inspect_query_log_flags(grn_ctx *ctx,
+ grn_obj *buffer,
+ unsigned int flags);
GRN_API void grn_p(grn_ctx *ctx, grn_obj *obj);
GRN_API void grn_p_geo_point(grn_ctx *ctx, grn_geo_point *point);
@@ -36,5 +42,3 @@ GRN_API void grn_p_ii_values(grn_ctx *ctx, grn_obj *obj);
#ifdef __cplusplus
}
#endif
-
-#endif /* GROONGA_UTIL_H */
diff --git a/storage/mroonga/vendor/groonga/include/groonga/window_function.h b/storage/mroonga/vendor/groonga/include/groonga/window_function.h
new file mode 100644
index 00000000000..404fd04bbee
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/window_function.h
@@ -0,0 +1,73 @@
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ GRN_WINDOW_DIRECTION_ASCENDING,
+ GRN_WINDOW_DIRECTION_DESCENDING
+} grn_window_direction;
+
+typedef struct _grn_window grn_window;
+
+GRN_API grn_id grn_window_next(grn_ctx *ctx,
+ grn_window *window);
+GRN_API grn_rc grn_window_rewind(grn_ctx *ctx,
+ grn_window *window);
+GRN_API grn_rc grn_window_set_direction(grn_ctx *ctx,
+ grn_window *window,
+ grn_window_direction direction);
+GRN_API grn_obj *grn_window_get_table(grn_ctx *ctx,
+ grn_window *window);
+GRN_API grn_bool grn_window_is_sorted(grn_ctx *ctx,
+ grn_window *window);
+GRN_API size_t grn_window_get_size(grn_ctx *ctx,
+ grn_window *window);
+
+typedef struct _grn_window_definition {
+ grn_table_sort_key *sort_keys;
+ size_t n_sort_keys;
+ grn_table_sort_key *group_keys;
+ size_t n_group_keys;
+} grn_window_definition;
+
+typedef grn_rc grn_window_function_func(grn_ctx *ctx,
+ grn_obj *output_column,
+ grn_window *window,
+ grn_obj **args,
+ int n_args);
+
+GRN_API grn_obj *grn_window_function_create(grn_ctx *ctx,
+ const char *name,
+ int name_size,
+ grn_window_function_func func);
+
+
+GRN_API grn_rc grn_table_apply_window_function(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *output_column,
+ grn_window_definition *definition,
+ grn_obj *window_function_call);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/windows.h b/storage/mroonga/vendor/groonga/include/groonga/windows.h
new file mode 100644
index 00000000000..1984a773297
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/windows.h
@@ -0,0 +1,31 @@
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WIN32
+GRN_API const char *grn_windows_base_dir(void);
+#endif /* WIN32 */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/include/groonga/windows_event_logger.h b/storage/mroonga/vendor/groonga/include/groonga/windows_event_logger.h
new file mode 100644
index 00000000000..7fe6ea8f5cc
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/include/groonga/windows_event_logger.h
@@ -0,0 +1,30 @@
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API grn_rc grn_windows_event_logger_set(grn_ctx *ctx,
+ const char *event_source_name);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
index 78258789083..2274e95aa24 100644
--- a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright(C) 2012-2013 Brazil
+# Copyright(C) 2012-2016 Brazil
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -21,35 +21,63 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/dat
${ONIGMO_INCLUDE_DIRS}
${MRUBY_INCLUDE_DIRS}
- ${LIBLZ4_INCLUDE_DIRS})
-if (LIBLZ4_LIBRARY_DIRS)
- find_library(LZ4_LIBS
- NAMES ${LIBLZ4_LIBRARIES}
- PATHS ${LIBLZ4_LIBRARY_DIRS}
- NO_DEFAULT_PATH)
-else()
- set(LZ4_LIBS ${LIBLZ4_LIBRARIES})
-endif()
+ ${LIBLZ4_INCLUDE_DIRS}
+ ${LIBZSTD_INCLUDE_DIRS}
+ ${MESSAGE_PACK_INCLUDE_DIRS})
-read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am LIBGROONGA_SOURCES)
+read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/c_sources.am LIBGROONGA_C_SOURCES)
+read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/cpp_sources.am LIBGROONGA_CPP_SOURCES)
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/dat/sources.am LIBGRNDAT_SOURCES)
string(REGEX REPLACE "([^;]+)" "dat/\\1"
LIBGRNDAT_SOURCES "${LIBGRNDAT_SOURCES}")
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/sources.am LIBGRNMRB_SOURCES)
string(REGEX REPLACE "([^;]+)" "mrb/\\1"
LIBGRNMRB_SOURCES "${LIBGRNMRB_SOURCES}")
+read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/proc/sources.am LIBGRNPROC_SOURCES)
+string(REGEX REPLACE "([^;]+)" "proc/\\1"
+ LIBGRNPROC_SOURCES "${LIBGRNPROC_SOURCES}")
+read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/ts/sources.am LIBGRNTS_SOURCES)
+string(REGEX REPLACE "([^;]+)" "ts/\\1"
+ LIBGRNTS_SOURCES "${LIBGRNTS_SOURCES}")
+
+if(WIN32)
+ configure_file(
+ "metadata.rc.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/metadata.rc"
+ @ONLY)
+ set(LIBGROONGA_METADATA_SOURCES
+ "${CMAKE_CURRENT_BINARY_DIR}/metadata.rc")
+else()
+ set(LIBGROONGA_METADATA_SOURCES)
+endif()
-set_source_files_properties(${LIBGROONGA_SOURCES} ${LIBGRNMRB_SOURCES}
+set_source_files_properties(
+ ${LIBGROONGA_C_SOURCES}
+ ${LIBGRNMRB_SOURCES}
+ ${LIBGRNPROC_SOURCES}
+ ${LIBGRNTS_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
-set_source_files_properties(dat.cpp egn.cpp ${LIBGRNDAT_SOURCES}
+set_source_files_properties(
+ ${LIBGROONGA_C_SOURCES}
+ ${LIBGROONGA_CPP_SOURCES}
+ ${LIBGRNMRB_SOURCES}
+ PROPERTIES
+ COMPILE_DEFINITIONS "${MRUBY_DEFINITIONS}")
+set_source_files_properties(
+ ${LIBGROONGA_CPP_SOURCES}
+ ${LIBGRNDAT_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS}")
set(GRN_ALL_SOURCES
- ${LIBGROONGA_SOURCES}
+ ${LIBGROONGA_C_SOURCES}
+ ${LIBGROONGA_CPP_SOURCES}
${LIBGRNDAT_SOURCES}
- ${LIBGRNMRB_SOURCES})
+ ${LIBGRNMRB_SOURCES}
+ ${LIBGRNPROC_SOURCES}
+ ${LIBGRNTS_SOURCES}
+ ${LIBGROONGA_METADATA_SOURCES})
if(GRN_EMBED)
add_library(libgroonga STATIC ${GRN_ALL_SOURCES})
set_target_properties(
@@ -67,6 +95,8 @@ set(GRN_ALL_LIBRARIES
${PTHREAD_LIBS}
${Z_LIBS}
${LZ4_LIBS}
+ ${LIBZSTD_LIBS}
+ ${MESSAGE_PACK_LIBS}
${DL_LIBS}
${M_LIBS}
${WS2_32_LIBS}
@@ -130,4 +160,25 @@ if(GRN_WITH_MRUBY)
install(
FILES ${LOGGER_RUBY_SCRIPTS}
DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}/logger")
+
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/query_logger/sources.am
+ QUERY_LOGGER_RUBY_SCRIPTS)
+ string(REGEX REPLACE "([^;]+)" "mrb/scripts/query_logger/\\1"
+ QUERY_LOGGER_RUBY_SCRIPTS "${QUERY_LOGGER_RUBY_SCRIPTS}")
+ install(
+ FILES ${QUERY_LOGGER_RUBY_SCRIPTS}
+ DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}/query_logger")
+
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/expression_tree/sources.am
+ EXPRESSION_TREE_RUBY_SCRIPTS)
+ string(REGEX REPLACE "([^;]+)" "mrb/scripts/expression_tree/\\1"
+ EXPRESSION_TREE_RUBY_SCRIPTS "${EXPRESSION_TREE_RUBY_SCRIPTS}")
+ install(
+ FILES ${EXPRESSION_TREE_RUBY_SCRIPTS}
+ DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}/expression_tree")
endif()
+
+# Workaround GCC ICE on ARM64
+IF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
+ ADD_COMPILE_FLAGS(ts/ts_expr_node.c COMPILE_FLAGS "-fno-tree-loop-vectorize")
+ENDIF()
diff --git a/storage/mroonga/vendor/groonga/lib/Makefile.am b/storage/mroonga/vendor/groonga/lib/Makefile.am
index 8f4e76ea212..9a2217ee12d 100644
--- a/storage/mroonga/vendor/groonga/lib/Makefile.am
+++ b/storage/mroonga/vendor/groonga/lib/Makefile.am
@@ -1,16 +1,29 @@
SUBDIRS = \
dat \
- mrb
+ mrb \
+ proc \
+ ts
lib_LTLIBRARIES = libgroonga.la
include $(top_srcdir)/version.sh
+
+AM_CPPFLAGS = \
+ $(MRUBY_CPPFLAGS)
+
AM_CFLAGS = \
$(NO_STRICT_ALIASING_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(GRN_CFLAGS) \
$(MESSAGE_PACK_CFLAGS) \
- $(LIBLZ4_CFLAGS)
+ $(LIBLZ4_CFLAGS) \
+ $(LIBZSTD_CFLAGS)
+
+AM_CXXFLAGS = \
+ $(NO_STRICT_ALIASING_CFLAGS) \
+ $(COVERAGE_CFLAGS) \
+ $(GRN_CXXFLAGS) \
+ $(ARROW_CFLAGS)
BUNDLED_LIBRARIES_CFLAGS = \
$(MRUBY_CFLAGS) \
@@ -23,7 +36,14 @@ DEFAULT_INCLUDES = \
DEFS += -D_REENTRANT $(GRN_DEFS) -DGRN_DAT_EXPORT
-include sources.am
+include c_sources.am
+include cpp_sources.am
+libgroonga_la_SOURCES = \
+ $(libgroonga_c_sources) \
+ $(libgroonga_cpp_source)
+
+#nfkc.c:
+# $(RUBY) nfkc.rb --impl=table
libgroonga_la_LDFLAGS = \
-version-info $(LT_VERSION_INFO) \
@@ -33,6 +53,8 @@ libgroonga_la_LDFLAGS = \
libgroonga_la_LIBADD = \
dat/libgrndat.la \
mrb/libgrnmrb.la \
+ proc/libgrnproc.la \
+ ts/libgrnts.la \
$(MESSAGE_PACK_LIBS)
if WITH_MRUBY
@@ -42,7 +64,10 @@ endif
libgroonga_la_LIBADD += \
$(ONIGMO_LIBS) \
- $(LIBLZ4_LIBS)
+ $(LIBLZ4_LIBS) \
+ $(LIBZSTD_LIBS) \
+ $(ATOMIC_LIBS) \
+ $(ARROW_LIBS)
if WITH_LEMON
BUILT_SOURCES = \
@@ -54,6 +79,17 @@ SUFFIXES = .lemon .c
$(LEMON) $<
endif
+if PLATFORM_WIN32
+libgroonga_la_SOURCES += \
+ metadata.rc
+
+.rc.lo:
+ $(LIBTOOL) $(AM_V_lt) --tag=RC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile \
+ $(RC) $(RCFLAGS) -o $@ $<
+endif
+
EXTRA_DIST = \
grn_ecmascript.c \
grn_ecmascript.h \
diff --git a/storage/mroonga/vendor/groonga/lib/alloc.c b/storage/mroonga/vendor/groonga/lib/alloc.c
new file mode 100644
index 00000000000..5d77c19e74c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/alloc.c
@@ -0,0 +1,961 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn.h"
+#include "grn_alloc.h"
+#include "grn_ctx_impl.h"
+
+static int alloc_count = 0;
+
+#ifdef USE_FAIL_MALLOC
+static int grn_fmalloc_prob = 0;
+static char *grn_fmalloc_func = NULL;
+static char *grn_fmalloc_file = NULL;
+static int grn_fmalloc_line = 0;
+#endif /* USE_FAIL_MALLOC */
+
+#ifdef USE_EXACT_ALLOC_COUNT
+# define GRN_ADD_ALLOC_COUNT(count) do { \
+ uint32_t alloced; \
+ GRN_ATOMIC_ADD_EX(&alloc_count, count, alloced); \
+} while (0)
+#else /* USE_EXACT_ALLOC_COUNT */
+# define GRN_ADD_ALLOC_COUNT(count) do { \
+ alloc_count += count; \
+} while (0)
+#endif
+
+void
+grn_alloc_init_from_env(void)
+{
+#ifdef USE_FAIL_MALLOC
+ {
+ char grn_fmalloc_prob_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_FMALLOC_PROB",
+ grn_fmalloc_prob_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_fmalloc_prob_env[0]) {
+ char grn_fmalloc_seed_env[GRN_ENV_BUFFER_SIZE];
+ grn_fmalloc_prob = strtod(grn_fmalloc_prob_env, 0) * RAND_MAX;
+ grn_getenv("GRN_FMALLOC_SEED",
+ grn_fmalloc_seed_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_fmalloc_seed_env[0]) {
+ srand((unsigned int)atoi(grn_fmalloc_seed_env));
+ } else {
+ srand((unsigned int)time(NULL));
+ }
+ }
+ }
+ {
+ static char grn_fmalloc_func_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_FMALLOC_FUNC",
+ grn_fmalloc_func_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_fmalloc_func_env[0]) {
+ grn_fmalloc_func = grn_fmalloc_func_env;
+ }
+ }
+ {
+ static char grn_fmalloc_file_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_FMALLOC_FILE",
+ grn_fmalloc_file_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_fmalloc_file_env[0]) {
+ grn_fmalloc_file = grn_fmalloc_file_env;
+ }
+ }
+ {
+ char grn_fmalloc_line_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_FMALLOC_LINE",
+ grn_fmalloc_line_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_fmalloc_line_env[0]) {
+ grn_fmalloc_line = atoi(grn_fmalloc_line_env);
+ }
+ }
+#endif /* USE_FAIL_MALLOC */
+}
+
+#ifdef USE_MEMORY_DEBUG
+static grn_critical_section grn_alloc_info_lock;
+
+void
+grn_alloc_info_init(void)
+{
+ CRITICAL_SECTION_INIT(grn_alloc_info_lock);
+}
+
+void
+grn_alloc_info_fin(void)
+{
+ CRITICAL_SECTION_FIN(grn_alloc_info_lock);
+}
+
+inline static void
+grn_alloc_info_set_backtrace(char *buffer, size_t size)
+{
+# ifdef HAVE_BACKTRACE
+# define N_TRACE_LEVEL 100
+ static void *trace[N_TRACE_LEVEL];
+ char **symbols;
+ int i, n, rest;
+
+ rest = size;
+ n = backtrace(trace, N_TRACE_LEVEL);
+ symbols = backtrace_symbols(trace, n);
+ if (symbols) {
+ for (i = 0; i < n; i++) {
+ int symbol_length;
+
+ symbol_length = strlen(symbols[i]);
+ if (symbol_length + 2 > rest) {
+ break;
+ }
+ grn_memcpy(buffer, symbols[i], symbol_length);
+ buffer += symbol_length;
+ rest -= symbol_length;
+ buffer[0] = '\n';
+ buffer++;
+ rest--;
+ buffer[0] = '\0';
+ rest--;
+ }
+ free(symbols);
+ } else {
+ buffer[0] = '\0';
+ }
+# undef N_TRACE_LEVEL
+# else /* HAVE_BACKTRACE */
+ buffer[0] = '\0';
+# endif /* HAVE_BACKTRACE */
+}
+
+inline static void
+grn_alloc_info_add(void *address, size_t size,
+ const char *file, int line, const char *func)
+{
+ grn_ctx *ctx;
+ grn_alloc_info *new_alloc_info;
+
+ ctx = &grn_gctx;
+ if (!ctx->impl) { return; }
+
+ CRITICAL_SECTION_ENTER(grn_alloc_info_lock);
+ new_alloc_info = malloc(sizeof(grn_alloc_info));
+ if (new_alloc_info) {
+ new_alloc_info->address = address;
+ new_alloc_info->size = size;
+ new_alloc_info->freed = GRN_FALSE;
+ grn_alloc_info_set_backtrace(new_alloc_info->alloc_backtrace,
+ sizeof(new_alloc_info->alloc_backtrace));
+ if (file) {
+ new_alloc_info->file = strdup(file);
+ } else {
+ new_alloc_info->file = NULL;
+ }
+ new_alloc_info->line = line;
+ if (func) {
+ new_alloc_info->func = strdup(func);
+ } else {
+ new_alloc_info->func = NULL;
+ }
+ new_alloc_info->next = ctx->impl->alloc_info;
+ ctx->impl->alloc_info = new_alloc_info;
+ }
+ CRITICAL_SECTION_LEAVE(grn_alloc_info_lock);
+}
+
+inline static void
+grn_alloc_info_change(void *old_address, void *new_address, size_t size)
+{
+ grn_ctx *ctx;
+ grn_alloc_info *alloc_info;
+
+ ctx = &grn_gctx;
+ if (!ctx->impl) { return; }
+
+ CRITICAL_SECTION_ENTER(grn_alloc_info_lock);
+ alloc_info = ctx->impl->alloc_info;
+ for (; alloc_info; alloc_info = alloc_info->next) {
+ if (alloc_info->address == old_address) {
+ alloc_info->address = new_address;
+ alloc_info->size = size;
+ grn_alloc_info_set_backtrace(alloc_info->alloc_backtrace,
+ sizeof(alloc_info->alloc_backtrace));
+ }
+ }
+ CRITICAL_SECTION_LEAVE(grn_alloc_info_lock);
+}
+
+void
+grn_alloc_info_dump(grn_ctx *ctx)
+{
+ int i = 0;
+ grn_alloc_info *alloc_info;
+
+ if (!ctx) { return; }
+ if (!ctx->impl) { return; }
+
+ alloc_info = ctx->impl->alloc_info;
+ for (; alloc_info; alloc_info = alloc_info->next) {
+ if (alloc_info->freed) {
+ printf("address[%d][freed]: %p(%" GRN_FMT_SIZE ")\n",
+ i, alloc_info->address, alloc_info->size);
+ } else {
+ printf("address[%d][not-freed]: %p(%" GRN_FMT_SIZE "): %s:%d: %s()\n%s",
+ i,
+ alloc_info->address,
+ alloc_info->size,
+ alloc_info->file ? alloc_info->file : "(unknown)",
+ alloc_info->line,
+ alloc_info->func ? alloc_info->func : "(unknown)",
+ alloc_info->alloc_backtrace);
+ }
+ i++;
+ }
+}
+
+inline static void
+grn_alloc_info_check(grn_ctx *ctx, void *address)
+{
+ grn_alloc_info *alloc_info;
+
+ if (!grn_gctx.impl) { return; }
+ /* grn_alloc_info_dump(ctx); */
+
+ CRITICAL_SECTION_ENTER(grn_alloc_info_lock);
+ alloc_info = grn_gctx.impl->alloc_info;
+ for (; alloc_info; alloc_info = alloc_info->next) {
+ if (alloc_info->address == address) {
+ if (alloc_info->freed) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "double free: %p(%" GRN_FMT_SIZE "):\n"
+ "alloc backtrace:\n"
+ "%sfree backtrace:\n"
+ "%s",
+ alloc_info->address,
+ alloc_info->size,
+ alloc_info->alloc_backtrace,
+ alloc_info->free_backtrace);
+ } else {
+ alloc_info->freed = GRN_TRUE;
+ grn_alloc_info_set_backtrace(alloc_info->free_backtrace,
+ sizeof(alloc_info->free_backtrace));
+ }
+ break;
+ }
+ }
+ CRITICAL_SECTION_LEAVE(grn_alloc_info_lock);
+}
+
+void
+grn_alloc_info_free(grn_ctx *ctx)
+{
+ grn_alloc_info *alloc_info;
+
+ if (!ctx) { return; }
+ if (!ctx->impl) { return; }
+
+ alloc_info = ctx->impl->alloc_info;
+ while (alloc_info) {
+ grn_alloc_info *current_alloc_info = alloc_info;
+ alloc_info = alloc_info->next;
+ current_alloc_info->next = NULL;
+ free(current_alloc_info->file);
+ free(current_alloc_info->func);
+ free(current_alloc_info);
+ }
+ ctx->impl->alloc_info = NULL;
+}
+
+#else /* USE_MEMORY_DEBUG */
+void
+grn_alloc_info_init(void)
+{
+}
+
+void
+grn_alloc_info_fin(void)
+{
+}
+
+# define grn_alloc_info_add(address, size, file, line, func)
+# define grn_alloc_info_change(old_address, new_address, size)
+# define grn_alloc_info_check(ctx, address)
+
+void
+grn_alloc_info_dump(grn_ctx *ctx)
+{
+}
+
+void
+grn_alloc_info_free(grn_ctx *ctx)
+{
+}
+#endif /* USE_MEMORY_DEBUG */
+
+#define GRN_CTX_SEGMENT_SIZE (1<<22)
+#define GRN_CTX_SEGMENT_MASK (GRN_CTX_SEGMENT_SIZE - 1)
+
+#define GRN_CTX_SEGMENT_WORD (1<<31)
+#define GRN_CTX_SEGMENT_VLEN (1<<30)
+#define GRN_CTX_SEGMENT_LIFO (1<<29)
+#define GRN_CTX_SEGMENT_DIRTY (1<<28)
+
+void
+grn_alloc_init_ctx_impl(grn_ctx *ctx)
+{
+#ifdef USE_DYNAMIC_MALLOC_CHANGE
+# ifdef USE_FAIL_MALLOC
+ ctx->impl->malloc_func = grn_malloc_fail;
+ ctx->impl->calloc_func = grn_calloc_fail;
+ ctx->impl->realloc_func = grn_realloc_fail;
+ ctx->impl->strdup_func = grn_strdup_fail;
+# else
+ ctx->impl->malloc_func = grn_malloc_default;
+ ctx->impl->calloc_func = grn_calloc_default;
+ ctx->impl->realloc_func = grn_realloc_default;
+ ctx->impl->strdup_func = grn_strdup_default;
+# endif
+#endif
+
+#ifdef USE_MEMORY_DEBUG
+ ctx->impl->alloc_info = NULL;
+#endif
+}
+
+void
+grn_alloc_fin_ctx_impl(grn_ctx *ctx)
+{
+ int i;
+ grn_io_mapinfo *mi;
+ for (i = 0, mi = ctx->impl->segs; i < GRN_CTX_N_SEGMENTS; i++, mi++) {
+ if (mi->map) {
+ //GRN_LOG(ctx, GRN_LOG_NOTICE, "unmap in ctx_fin(%d,%d,%d)", i, (mi->count & GRN_CTX_SEGMENT_MASK), mi->nref);
+ if (mi->count & GRN_CTX_SEGMENT_VLEN) {
+ grn_io_anon_unmap(ctx, mi, mi->nref * grn_pagesize);
+ } else {
+ grn_io_anon_unmap(ctx, mi, GRN_CTX_SEGMENT_SIZE);
+ }
+ }
+ }
+}
+
+#define ALIGN_SIZE (1<<3)
+#define ALIGN_MASK (ALIGN_SIZE-1)
+#define GRN_CTX_ALLOC_CLEAR 1
+
+static void *
+grn_ctx_alloc(grn_ctx *ctx, size_t size, int flags,
+ const char* file, int line, const char *func)
+{
+ void *res = NULL;
+ if (!ctx) { return res; }
+ if (!ctx->impl) {
+ if (ERRP(ctx, GRN_ERROR)) { return res; }
+ }
+ CRITICAL_SECTION_ENTER(ctx->impl->lock);
+ {
+ int32_t i;
+ int32_t *header;
+ grn_io_mapinfo *mi;
+ size = ((size + ALIGN_MASK) & ~ALIGN_MASK) + ALIGN_SIZE;
+ if (size > GRN_CTX_SEGMENT_SIZE) {
+ uint64_t npages = (size + (grn_pagesize - 1)) / grn_pagesize;
+ size_t aligned_size;
+ if (npages >= (1LL<<32)) {
+ MERR("too long request size=%" GRN_FMT_SIZE, size);
+ goto exit;
+ }
+ for (i = 0, mi = ctx->impl->segs;; i++, mi++) {
+ if (i >= GRN_CTX_N_SEGMENTS) {
+ MERR("all segments are full");
+ goto exit;
+ }
+ if (!mi->map) { break; }
+ }
+ aligned_size = grn_pagesize * ((size_t)npages);
+ if (!grn_io_anon_map(ctx, mi, aligned_size)) { goto exit; }
+ /* GRN_LOG(ctx, GRN_LOG_NOTICE, "map i=%d (%d)", i, npages * grn_pagesize); */
+ mi->nref = (uint32_t) npages;
+ mi->count = GRN_CTX_SEGMENT_VLEN;
+ ctx->impl->currseg = -1;
+ header = mi->map;
+ header[0] = i;
+ header[1] = (int32_t) size;
+ } else {
+ i = ctx->impl->currseg;
+ mi = &ctx->impl->segs[i];
+ if (i < 0 || size + mi->nref > GRN_CTX_SEGMENT_SIZE) {
+ for (i = 0, mi = ctx->impl->segs;; i++, mi++) {
+ if (i >= GRN_CTX_N_SEGMENTS) {
+ MERR("all segments are full");
+ goto exit;
+ }
+ if (!mi->map) { break; }
+ }
+ if (!grn_io_anon_map(ctx, mi, GRN_CTX_SEGMENT_SIZE)) { goto exit; }
+ /* GRN_LOG(ctx, GRN_LOG_NOTICE, "map i=%d", i); */
+ mi->nref = 0;
+ mi->count = GRN_CTX_SEGMENT_WORD;
+ ctx->impl->currseg = i;
+ }
+ header = (int32_t *)((byte *)mi->map + mi->nref);
+ mi->nref += size;
+ mi->count++;
+ header[0] = i;
+ header[1] = (int32_t) size;
+ if ((flags & GRN_CTX_ALLOC_CLEAR) &&
+ (mi->count & GRN_CTX_SEGMENT_DIRTY) && (size > ALIGN_SIZE)) {
+ memset(&header[2], 0, size - ALIGN_SIZE);
+ }
+ }
+ /*
+ {
+ char g = (ctx == &grn_gctx) ? 'g' : ' ';
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "+%c(%p) %s:%d(%s) (%d:%d)%p mi(%d:%d)", g, ctx, file, line, func, header[0], header[1], &header[2], mi->nref, (mi->count & GRN_CTX_SEGMENT_MASK));
+ }
+ */
+ res = &header[2];
+ }
+exit :
+ CRITICAL_SECTION_LEAVE(ctx->impl->lock);
+ return res;
+}
+
+void *
+grn_ctx_malloc(grn_ctx *ctx, size_t size,
+ const char* file, int line, const char *func)
+{
+ return grn_ctx_alloc(ctx, size, 0, file, line, func);
+}
+
+void *
+grn_ctx_calloc(grn_ctx *ctx, size_t size,
+ const char* file, int line, const char *func)
+{
+ return grn_ctx_alloc(ctx, size, GRN_CTX_ALLOC_CLEAR, file, line, func);
+}
+
+void *
+grn_ctx_realloc(grn_ctx *ctx, void *ptr, size_t size,
+ const char* file, int line, const char *func)
+{
+ void *res = NULL;
+ if (size) {
+ /* todo : expand if possible */
+ res = grn_ctx_alloc(ctx, size, 0, file, line, func);
+ if (res && ptr) {
+ int32_t *header = &((int32_t *)ptr)[-2];
+ size_t size_ = header[1];
+ grn_memcpy(res, ptr, size_ > size ? size : size_);
+ grn_ctx_free(ctx, ptr, file, line, func);
+ }
+ } else {
+ grn_ctx_free(ctx, ptr, file, line, func);
+ }
+ return res;
+}
+
+char *
+grn_ctx_strdup(grn_ctx *ctx, const char *s,
+ const char* file, int line, const char *func)
+{
+ void *res = NULL;
+ if (s) {
+ size_t size = strlen(s) + 1;
+ if ((res = grn_ctx_alloc(ctx, size, 0, file, line, func))) {
+ grn_memcpy(res, s, size);
+ }
+ }
+ return res;
+}
+
+void
+grn_ctx_free(grn_ctx *ctx, void *ptr,
+ const char* file, int line, const char *func)
+{
+ if (!ctx) { return; }
+ if (!ctx->impl) {
+ ERR(GRN_INVALID_ARGUMENT,"ctx without impl passed.");
+ return;
+ }
+ CRITICAL_SECTION_ENTER(ctx->impl->lock);
+ if (ptr) {
+ int32_t *header = &((int32_t *)ptr)[-2];
+
+ if (header[0] >= GRN_CTX_N_SEGMENTS) {
+ ERR(GRN_INVALID_ARGUMENT,"invalid ptr passed. ptr=%p seg=%d", ptr, *header);
+ goto exit;
+ }
+ /*
+ {
+ int32_t i = header[0];
+ char c = 'X', g = (ctx == &grn_gctx) ? 'g' : ' ';
+ grn_io_mapinfo *mi = &ctx->impl->segs[i];
+ if (!(mi->count & GRN_CTX_SEGMENT_VLEN) &&
+ mi->map <= (void *)header && (char *)header < ((char *)mi->map + GRN_CTX_SEGMENT_SIZE)) { c = '-'; }
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "%c%c(%p) %s:%d(%s) (%d:%d)%p mi(%d:%d)", c, g, ctx, file, line, func, header[0], header[1], &header[2], mi->nref, (mi->count & GRN_CTX_SEGMENT_MASK));
+ }
+ */
+ {
+ int32_t i = header[0];
+ grn_io_mapinfo *mi = &ctx->impl->segs[i];
+ if (mi->count & GRN_CTX_SEGMENT_VLEN) {
+ if (mi->map != header) {
+ ERR(GRN_INVALID_ARGUMENT,"invalid ptr passed.. ptr=%p seg=%d", ptr, i);
+ goto exit;
+ }
+ //GRN_LOG(ctx, GRN_LOG_NOTICE, "umap i=%d (%d)", i, mi->nref * grn_pagesize);
+ grn_io_anon_unmap(ctx, mi, mi->nref * grn_pagesize);
+ mi->map = NULL;
+ } else {
+ if (!mi->map) {
+ ERR(GRN_INVALID_ARGUMENT,"invalid ptr passed... ptr=%p seg=%d", ptr, i);
+ goto exit;
+ }
+ mi->count--;
+ if (!(mi->count & GRN_CTX_SEGMENT_MASK)) {
+ //GRN_LOG(ctx, GRN_LOG_NOTICE, "umap i=%d", i);
+ if (i == ctx->impl->currseg) {
+ mi->count |= GRN_CTX_SEGMENT_DIRTY;
+ mi->nref = 0;
+ } else {
+ grn_io_anon_unmap(ctx, mi, GRN_CTX_SEGMENT_SIZE);
+ mi->map = NULL;
+ }
+ }
+ }
+ }
+ }
+exit :
+ CRITICAL_SECTION_LEAVE(ctx->impl->lock);
+}
+
+void *
+grn_ctx_alloc_lifo(grn_ctx *ctx, size_t size,
+ const char* file, int line, const char *func)
+{
+ if (!ctx) { return NULL; }
+ if (!ctx->impl) {
+ if (ERRP(ctx, GRN_ERROR)) { return NULL; }
+ }
+ {
+ int32_t i = ctx->impl->lifoseg;
+ grn_io_mapinfo *mi = &ctx->impl->segs[i];
+ if (size > GRN_CTX_SEGMENT_SIZE) {
+ uint64_t npages = (size + (grn_pagesize - 1)) / grn_pagesize;
+ size_t aligned_size;
+ if (npages >= (1LL<<32)) {
+ MERR("too long request size=%" GRN_FMT_SIZE, size);
+ return NULL;
+ }
+ for (;;) {
+ if (++i >= GRN_CTX_N_SEGMENTS) {
+ MERR("all segments are full");
+ return NULL;
+ }
+ mi++;
+ if (!mi->map) { break; }
+ }
+ aligned_size = grn_pagesize * ((size_t)npages);
+ if (!grn_io_anon_map(ctx, mi, aligned_size)) { return NULL; }
+ mi->nref = (uint32_t) npages;
+ mi->count = GRN_CTX_SEGMENT_VLEN|GRN_CTX_SEGMENT_LIFO;
+ ctx->impl->lifoseg = i;
+ return mi->map;
+ } else {
+ size = (size + ALIGN_MASK) & ~ALIGN_MASK;
+ if (i < 0 || (mi->count & GRN_CTX_SEGMENT_VLEN) || size + mi->nref > GRN_CTX_SEGMENT_SIZE) {
+ for (;;) {
+ if (++i >= GRN_CTX_N_SEGMENTS) {
+ MERR("all segments are full");
+ return NULL;
+ }
+ if (!(++mi)->map) { break; }
+ }
+ if (!grn_io_anon_map(ctx, mi, GRN_CTX_SEGMENT_SIZE)) { return NULL; }
+ mi->nref = 0;
+ mi->count = GRN_CTX_SEGMENT_WORD|GRN_CTX_SEGMENT_LIFO;
+ ctx->impl->lifoseg = i;
+ }
+ {
+ uint32_t u = mi->nref;
+ mi->nref += size;
+ return (byte *)mi->map + u;
+ }
+ }
+ }
+}
+
+void
+grn_ctx_free_lifo(grn_ctx *ctx, void *ptr,
+ const char* file, int line, const char *func)
+{
+ if (!ctx) { return; }
+ if (!ctx->impl) {
+ ERR(GRN_INVALID_ARGUMENT,"ctx without impl passed.");
+ return;
+ }
+ {
+ int32_t i = ctx->impl->lifoseg, done = 0;
+ grn_io_mapinfo *mi = &ctx->impl->segs[i];
+ if (i < 0) {
+ ERR(GRN_INVALID_ARGUMENT, "lifo buffer is void");
+ return;
+ }
+ for (; i >= 0; i--, mi--) {
+ if (!(mi->count & GRN_CTX_SEGMENT_LIFO)) { continue; }
+ if (done) { break; }
+ if (mi->count & GRN_CTX_SEGMENT_VLEN) {
+ if (mi->map == ptr) { done = 1; }
+ grn_io_anon_unmap(ctx, mi, mi->nref * grn_pagesize);
+ mi->map = NULL;
+ } else {
+ if (mi->map == ptr) {
+ done = 1;
+ } else {
+ if (mi->map < ptr && ptr < (void *)((byte*)mi->map + mi->nref)) {
+ mi->nref = (uint32_t) ((uintptr_t)ptr - (uintptr_t)mi->map);
+ break;
+ }
+ }
+ grn_io_anon_unmap(ctx, mi, GRN_CTX_SEGMENT_SIZE);
+ mi->map = NULL;
+ }
+ }
+ ctx->impl->lifoseg = i;
+ }
+}
+
+#if USE_DYNAMIC_MALLOC_CHANGE
+grn_malloc_func
+grn_ctx_get_malloc(grn_ctx *ctx)
+{
+ if (!ctx || !ctx->impl) { return NULL; }
+ return ctx->impl->malloc_func;
+}
+
+void
+grn_ctx_set_malloc(grn_ctx *ctx, grn_malloc_func malloc_func)
+{
+ if (!ctx || !ctx->impl) { return; }
+ ctx->impl->malloc_func = malloc_func;
+}
+
+grn_calloc_func
+grn_ctx_get_calloc(grn_ctx *ctx)
+{
+ if (!ctx || !ctx->impl) { return NULL; }
+ return ctx->impl->calloc_func;
+}
+
+void
+grn_ctx_set_calloc(grn_ctx *ctx, grn_calloc_func calloc_func)
+{
+ if (!ctx || !ctx->impl) { return; }
+ ctx->impl->calloc_func = calloc_func;
+}
+
+grn_realloc_func
+grn_ctx_get_realloc(grn_ctx *ctx)
+{
+ if (!ctx || !ctx->impl) { return NULL; }
+ return ctx->impl->realloc_func;
+}
+
+void
+grn_ctx_set_realloc(grn_ctx *ctx, grn_realloc_func realloc_func)
+{
+ if (!ctx || !ctx->impl) { return; }
+ ctx->impl->realloc_func = realloc_func;
+}
+
+grn_strdup_func
+grn_ctx_get_strdup(grn_ctx *ctx)
+{
+ if (!ctx || !ctx->impl) { return NULL; }
+ return ctx->impl->strdup_func;
+}
+
+void
+grn_ctx_set_strdup(grn_ctx *ctx, grn_strdup_func strdup_func)
+{
+ if (!ctx || !ctx->impl) { return; }
+ ctx->impl->strdup_func = strdup_func;
+}
+
+grn_free_func
+grn_ctx_get_free(grn_ctx *ctx)
+{
+ if (!ctx || !ctx->impl) { return NULL; }
+ return ctx->impl->free_func;
+}
+
+void
+grn_ctx_set_free(grn_ctx *ctx, grn_free_func free_func)
+{
+ if (!ctx || !ctx->impl) { return; }
+ ctx->impl->free_func = free_func;
+}
+
+void *
+grn_malloc(grn_ctx *ctx, size_t size,
+ const char* file, int line, const char *func)
+{
+ if (ctx && ctx->impl && ctx->impl->malloc_func) {
+ return ctx->impl->malloc_func(ctx, size, file, line, func);
+ } else {
+ return grn_malloc_default(ctx, size, file, line, func);
+ }
+}
+
+void *
+grn_calloc(grn_ctx *ctx, size_t size,
+ const char* file, int line, const char *func)
+{
+ if (ctx && ctx->impl && ctx->impl->calloc_func) {
+ return ctx->impl->calloc_func(ctx, size, file, line, func);
+ } else {
+ return grn_calloc_default(ctx, size, file, line, func);
+ }
+}
+
+void *
+grn_realloc(grn_ctx *ctx, void *ptr, size_t size,
+ const char* file, int line, const char *func)
+{
+ if (ctx && ctx->impl && ctx->impl->realloc_func) {
+ return ctx->impl->realloc_func(ctx, ptr, size, file, line, func);
+ } else {
+ return grn_realloc_default(ctx, ptr, size, file, line, func);
+ }
+}
+
+char *
+grn_strdup(grn_ctx *ctx, const char *string,
+ const char* file, int line, const char *func)
+{
+ if (ctx && ctx->impl && ctx->impl->strdup_func) {
+ return ctx->impl->strdup_func(ctx, string, file, line, func);
+ } else {
+ return grn_strdup_default(ctx, string, file, line, func);
+ }
+}
+
+void
+grn_free(grn_ctx *ctx, void *ptr,
+ const char* file, int line, const char *func)
+{
+ if (ctx && ctx->impl && ctx->impl->free_func) {
+ return ctx->impl->free_func(ctx, ptr, file, line, func);
+ } else {
+ return grn_free_default(ctx, ptr, file, line, func);
+ }
+}
+#endif
+
+void *
+grn_malloc_default(grn_ctx *ctx, size_t size,
+ const char* file, int line, const char *func)
+{
+ if (!ctx) { return NULL; }
+ {
+ void *res = malloc(size);
+ if (res) {
+ GRN_ADD_ALLOC_COUNT(1);
+ grn_alloc_info_add(res, size, file, line, func);
+ } else {
+ if (!(res = malloc(size))) {
+ MERR("malloc fail (%" GRN_FMT_SIZE ")=%p (%s:%d) <%d>",
+ size, res, file, line, alloc_count);
+ } else {
+ GRN_ADD_ALLOC_COUNT(1);
+ grn_alloc_info_add(res, size, file, line, func);
+ }
+ }
+ return res;
+ }
+}
+
+void *
+grn_calloc_default(grn_ctx *ctx, size_t size,
+ const char* file, int line, const char *func)
+{
+ if (!ctx) { return NULL; }
+ {
+ void *res = calloc(size, 1);
+ if (res) {
+ GRN_ADD_ALLOC_COUNT(1);
+ grn_alloc_info_add(res, size, file, line, func);
+ } else {
+ if (!(res = calloc(size, 1))) {
+ MERR("calloc fail (%" GRN_FMT_SIZE ")=%p (%s:%d) <%d>",
+ size, res, file, line, alloc_count);
+ } else {
+ GRN_ADD_ALLOC_COUNT(1);
+ grn_alloc_info_add(res, size, file, line, func);
+ }
+ }
+ return res;
+ }
+}
+
+void
+grn_free_default(grn_ctx *ctx, void *ptr,
+ const char* file, int line, const char *func)
+{
+ if (!ctx) { return; }
+ grn_alloc_info_check(ctx, ptr);
+ {
+ free(ptr);
+ if (ptr) {
+ GRN_ADD_ALLOC_COUNT(-1);
+ } else {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "free fail (%p) (%s:%d) <%d>",
+ ptr, file, line, alloc_count);
+ }
+ }
+}
+
+void *
+grn_realloc_default(grn_ctx *ctx, void *ptr, size_t size,
+ const char* file, int line, const char *func)
+{
+ void *res;
+ if (!ctx) { return NULL; }
+ if (size) {
+ if (!(res = realloc(ptr, size))) {
+ if (!(res = realloc(ptr, size))) {
+ MERR("realloc fail (%p,%" GRN_FMT_SIZE ")=%p (%s:%d) <%d>",
+ ptr, size, res, file, line, alloc_count);
+ return NULL;
+ }
+ }
+ if (ptr) {
+ grn_alloc_info_change(ptr, res, size);
+ } else {
+ GRN_ADD_ALLOC_COUNT(1);
+ grn_alloc_info_add(res, size, file, line, func);
+ }
+ } else {
+ if (!ptr) { return NULL; }
+ grn_alloc_info_check(ctx, ptr);
+ GRN_ADD_ALLOC_COUNT(-1);
+ free(ptr);
+ res = NULL;
+ }
+ return res;
+}
+
+int
+grn_alloc_count(void)
+{
+ return alloc_count;
+}
+
+char *
+grn_strdup_default(grn_ctx *ctx, const char *s,
+ const char* file, int line, const char *func)
+{
+ if (!ctx) { return NULL; }
+ {
+ char *res = grn_strdup_raw(s);
+ if (res) {
+ GRN_ADD_ALLOC_COUNT(1);
+ grn_alloc_info_add(res, strlen(res) + 1, file, line, func);
+ } else {
+ if (!(res = grn_strdup_raw(s))) {
+ MERR("strdup(%p)=%p (%s:%d) <%d>", s, res, file, line, alloc_count);
+ } else {
+ GRN_ADD_ALLOC_COUNT(1);
+ grn_alloc_info_add(res, strlen(res) + 1, file, line, func);
+ }
+ }
+ return res;
+ }
+}
+
+#ifdef USE_FAIL_MALLOC
+int
+grn_fail_malloc_check(size_t size,
+ const char *file, int line, const char *func)
+{
+ if ((grn_fmalloc_file && strcmp(file, grn_fmalloc_file)) ||
+ (grn_fmalloc_line && line != grn_fmalloc_line) ||
+ (grn_fmalloc_func && strcmp(func, grn_fmalloc_func))) {
+ return 1;
+ }
+ if (grn_fmalloc_prob && grn_fmalloc_prob >= rand()) {
+ return 0;
+ }
+ return 1;
+}
+
+void *
+grn_malloc_fail(grn_ctx *ctx, size_t size,
+ const char* file, int line, const char *func)
+{
+ if (grn_fail_malloc_check(size, file, line, func)) {
+ return grn_malloc_default(ctx, size, file, line, func);
+ } else {
+ MERR("fail_malloc (%" GRN_FMT_SIZE ") (%s:%d@%s) <%d>",
+ size, file, line, func, alloc_count);
+ return NULL;
+ }
+}
+
+void *
+grn_calloc_fail(grn_ctx *ctx, size_t size,
+ const char* file, int line, const char *func)
+{
+ if (grn_fail_malloc_check(size, file, line, func)) {
+ return grn_calloc_default(ctx, size, file, line, func);
+ } else {
+ MERR("fail_calloc (%" GRN_FMT_SIZE ") (%s:%d@%s) <%d>",
+ size, file, line, func, alloc_count);
+ return NULL;
+ }
+}
+
+void *
+grn_realloc_fail(grn_ctx *ctx, void *ptr, size_t size,
+ const char* file, int line, const char *func)
+{
+ if (grn_fail_malloc_check(size, file, line, func)) {
+ return grn_realloc_default(ctx, ptr, size, file, line, func);
+ } else {
+ MERR("fail_realloc (%p,%" GRN_FMT_SIZE ") (%s:%d@%s) <%d>",
+ ptr, size, file, line, func, alloc_count);
+ return NULL;
+ }
+}
+
+char *
+grn_strdup_fail(grn_ctx *ctx, const char *s,
+ const char* file, int line, const char *func)
+{
+ if (grn_fail_malloc_check(strlen(s), file, line, func)) {
+ return grn_strdup_default(ctx, s, file, line, func);
+ } else {
+ MERR("fail_strdup(%p) (%s:%d@%s) <%d>", s, file, line, func, alloc_count);
+ return NULL;
+ }
+}
+#endif /* USE_FAIL_MALLOC */
diff --git a/storage/mroonga/vendor/groonga/lib/arrow.cpp b/storage/mroonga/vendor/groonga/lib/arrow.cpp
new file mode 100644
index 00000000000..d96231f76e4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/arrow.cpp
@@ -0,0 +1,849 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn.h"
+#include "grn_db.h"
+
+#ifdef GRN_WITH_ARROW
+#include <groonga/arrow.hpp>
+
+#include <arrow/api.h>
+#include <arrow/io/file.h>
+#include <arrow/ipc/api.h>
+
+#include <sstream>
+
+namespace grnarrow {
+ grn_rc status_to_rc(arrow::Status &status) {
+ switch (status.code()) {
+ case arrow::StatusCode::OK:
+ return GRN_SUCCESS;
+ case arrow::StatusCode::OutOfMemory:
+ return GRN_NO_MEMORY_AVAILABLE;
+ case arrow::StatusCode::KeyError:
+ return GRN_INVALID_ARGUMENT; // TODO
+ case arrow::StatusCode::TypeError:
+ return GRN_INVALID_ARGUMENT; // TODO
+ case arrow::StatusCode::Invalid:
+ return GRN_INVALID_ARGUMENT;
+ case arrow::StatusCode::IOError:
+ return GRN_INPUT_OUTPUT_ERROR;
+ case arrow::StatusCode::UnknownError:
+ return GRN_UNKNOWN_ERROR;
+ case arrow::StatusCode::NotImplemented:
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+ default:
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+
+ grn_bool check_status(grn_ctx *ctx,
+ arrow::Status &status,
+ const char *context) {
+ if (status.ok()) {
+ return GRN_TRUE;
+ } else {
+ auto rc = status_to_rc(status);
+ auto message = status.ToString();
+ ERR(rc, "%s: %s", context, message.c_str());
+ return GRN_FALSE;
+ }
+ }
+
+ grn_bool check_status(grn_ctx *ctx,
+ arrow::Status &status,
+ std::ostream &output) {
+ return check_status(ctx,
+ status,
+ static_cast<std::stringstream &>(output).str().c_str());
+ }
+
+ class ColumnLoadVisitor : public arrow::ArrayVisitor {
+ public:
+ ColumnLoadVisitor(grn_ctx *ctx,
+ grn_obj *grn_table,
+ std::shared_ptr<arrow::Column> &arrow_column,
+ const grn_id *ids)
+ : ctx_(ctx),
+ grn_table_(grn_table),
+ ids_(ids),
+ time_unit_(arrow::TimeUnit::SECOND) {
+ auto column_name = arrow_column->name();
+ grn_column_ = grn_obj_column(ctx_, grn_table_,
+ column_name.data(),
+ column_name.size());
+
+ auto arrow_type = arrow_column->type();
+ grn_id type_id;
+ switch (arrow_type->id()) {
+ case arrow::Type::BOOL :
+ type_id = GRN_DB_BOOL;
+ break;
+ case arrow::Type::UINT8 :
+ type_id = GRN_DB_UINT8;
+ break;
+ case arrow::Type::INT8 :
+ type_id = GRN_DB_INT8;
+ break;
+ case arrow::Type::UINT16 :
+ type_id = GRN_DB_UINT16;
+ break;
+ case arrow::Type::INT16 :
+ type_id = GRN_DB_INT16;
+ break;
+ case arrow::Type::UINT32 :
+ type_id = GRN_DB_UINT32;
+ break;
+ case arrow::Type::INT32 :
+ type_id = GRN_DB_INT32;
+ break;
+ case arrow::Type::UINT64 :
+ type_id = GRN_DB_UINT64;
+ break;
+ case arrow::Type::INT64 :
+ type_id = GRN_DB_INT64;
+ break;
+ case arrow::Type::HALF_FLOAT :
+ case arrow::Type::FLOAT :
+ case arrow::Type::DOUBLE :
+ type_id = GRN_DB_FLOAT;
+ break;
+ case arrow::Type::STRING :
+ type_id = GRN_DB_TEXT;
+ break;
+ case arrow::Type::DATE64 :
+ type_id = GRN_DB_TIME;
+ break;
+ case arrow::Type::TIMESTAMP :
+ type_id = GRN_DB_TIME;
+ {
+ auto arrow_timestamp_type =
+ std::static_pointer_cast<arrow::TimestampType>(arrow_type);
+ time_unit_ = arrow_timestamp_type->unit();
+ }
+ break;
+ default :
+ type_id = GRN_DB_VOID;
+ break;
+ }
+
+ if (type_id == GRN_DB_VOID) {
+ // TODO
+ return;
+ }
+
+ if (!grn_column_) {
+ grn_column_ = grn_column_create(ctx_,
+ grn_table_,
+ column_name.data(),
+ column_name.size(),
+ NULL,
+ GRN_OBJ_COLUMN_SCALAR,
+ grn_ctx_at(ctx_, type_id));
+ }
+ if (type_id == GRN_DB_TEXT) {
+ GRN_TEXT_INIT(&buffer_, GRN_OBJ_DO_SHALLOW_COPY);
+ } else {
+ GRN_VALUE_FIX_SIZE_INIT(&buffer_, 0, type_id);
+ }
+ }
+
+ ~ColumnLoadVisitor() {
+ if (grn_obj_is_accessor(ctx_, grn_column_)) {
+ grn_obj_unlink(ctx_, grn_column_);
+ }
+ GRN_OBJ_FIN(ctx_, &buffer_);
+ }
+
+ arrow::Status Visit(const arrow::BooleanArray &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::Int8Array &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::UInt8Array &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::Int16Array &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::UInt16Array &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::Int32Array &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::UInt32Array &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::Int64Array &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::UInt64Array &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::HalfFloatArray &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::FloatArray &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::DoubleArray &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::StringArray &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::Date64Array &array) {
+ return set_values(array);
+ }
+
+ arrow::Status Visit(const arrow::TimestampArray &array) {
+ return set_values(array);
+ }
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *grn_table_;
+ const grn_id *ids_;
+ arrow::TimeUnit::type time_unit_;
+ grn_obj *grn_column_;
+ grn_obj buffer_;
+
+ template <typename T>
+ arrow::Status set_values(const T &array) {
+ int64_t n_rows = array.length();
+ for (int i = 0; i < n_rows; ++i) {
+ auto id = ids_[i];
+ GRN_BULK_REWIND(&buffer_);
+ get_value(array, i);
+ grn_obj_set_value(ctx_, grn_column_, id, &buffer_, GRN_OBJ_SET);
+ }
+ return arrow::Status::OK();
+ }
+
+ void
+ get_value(const arrow::BooleanArray &array, int i) {
+ GRN_BOOL_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::UInt8Array &array, int i) {
+ GRN_UINT8_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::Int8Array &array, int i) {
+ GRN_INT8_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::UInt16Array &array, int i) {
+ GRN_UINT16_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::Int16Array &array, int i) {
+ GRN_INT16_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::UInt32Array &array, int i) {
+ GRN_UINT32_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::Int32Array &array, int i) {
+ GRN_INT32_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::UInt64Array &array, int i) {
+ GRN_UINT64_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::Int64Array &array, int i) {
+ GRN_INT64_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::HalfFloatArray &array, int i) {
+ GRN_FLOAT_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::FloatArray &array, int i) {
+ GRN_FLOAT_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::DoubleArray &array, int i) {
+ GRN_FLOAT_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::StringArray &array, int i) {
+ int32_t size;
+ const auto data = array.GetValue(i, &size);
+ GRN_TEXT_SET(ctx_, &buffer_, data, size);
+ }
+
+ void
+ get_value(const arrow::Date64Array &array, int i) {
+ GRN_TIME_SET(ctx_, &buffer_, array.Value(i));
+ }
+
+ void
+ get_value(const arrow::TimestampArray &array, int i) {
+ switch (time_unit_) {
+ case arrow::TimeUnit::SECOND :
+ GRN_TIME_SET(ctx_, &buffer_, GRN_TIME_PACK(array.Value(i), 0));
+ break;
+ case arrow::TimeUnit::MILLI :
+ GRN_TIME_SET(ctx_, &buffer_, array.Value(i) * 1000);
+ break;
+ case arrow::TimeUnit::MICRO :
+ GRN_TIME_SET(ctx_, &buffer_, array.Value(i));
+ break;
+ case arrow::TimeUnit::NANO :
+ GRN_TIME_SET(ctx_, &buffer_, array.Value(i) / 1000);
+ break;
+ }
+ }
+ };
+
+ class FileLoader {
+ public:
+ FileLoader(grn_ctx *ctx, grn_obj *grn_table)
+ : ctx_(ctx),
+ grn_table_(grn_table),
+ key_column_name_("") {
+ }
+
+ ~FileLoader() {
+ }
+
+ grn_rc load_table(const std::shared_ptr<arrow::Table> &arrow_table) {
+ int n_columns = arrow_table->num_columns();
+
+ if (key_column_name_.empty()) {
+ grn_obj ids;
+ GRN_RECORD_INIT(&ids, GRN_OBJ_VECTOR, grn_obj_id(ctx_, grn_table_));
+ auto n_records = arrow_table->num_rows();
+ for (int64_t i = 0; i < n_records; ++i) {
+ auto id = grn_table_add(ctx_, grn_table_, NULL, 0, NULL);
+ GRN_RECORD_PUT(ctx_, &ids, id);
+ }
+ for (int i = 0; i < n_columns; ++i) {
+ int64_t offset = 0;
+ auto arrow_column = arrow_table->column(i);
+ auto arrow_chunked_data = arrow_column->data();
+ for (auto arrow_array : arrow_chunked_data->chunks()) {
+ grn_id *sub_ids =
+ reinterpret_cast<grn_id *>(GRN_BULK_HEAD(&ids)) + offset;
+ ColumnLoadVisitor visitor(ctx_,
+ grn_table_,
+ arrow_column,
+ sub_ids);
+ arrow_array->Accept(&visitor);
+ offset += arrow_array->length();
+ }
+ }
+ GRN_OBJ_FIN(ctx_, &ids);
+ } else {
+ auto status = arrow::Status::NotImplemented("_key isn't supported yet");
+ check_status(ctx_, status, "[arrow][load]");
+ }
+ return ctx_->rc;
+ };
+
+ grn_rc load_record_batch(const std::shared_ptr<arrow::RecordBatch> &arrow_record_batch) {
+ std::shared_ptr<arrow::Table> arrow_table;
+ std::vector<std::shared_ptr<arrow::RecordBatch>> arrow_record_batches(1);
+ arrow_record_batches[0] = arrow_record_batch;
+ auto status =
+ arrow::Table::FromRecordBatches(arrow_record_batches, &arrow_table);
+ if (!check_status(ctx_,
+ status,
+ "[arrow][load] "
+ "failed to convert record batch to table")) {
+ return ctx_->rc;
+ }
+ return load_table(arrow_table);
+ };
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *grn_table_;
+ std::string key_column_name_;
+ };
+
+ class FileDumper {
+ public:
+ FileDumper(grn_ctx *ctx, grn_obj *grn_table, grn_obj *grn_columns)
+ : ctx_(ctx),
+ grn_table_(grn_table),
+ grn_columns_(grn_columns) {
+ }
+
+ ~FileDumper() {
+ }
+
+ grn_rc dump(arrow::io::OutputStream *output) {
+ std::vector<std::shared_ptr<arrow::Field>> fields;
+ auto n_columns = GRN_BULK_VSIZE(grn_columns_) / sizeof(grn_obj *);
+ for (auto i = 0; i < n_columns; ++i) {
+ auto column = GRN_PTR_VALUE_AT(grn_columns_, i);
+
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int column_name_size;
+ column_name_size =
+ grn_column_name(ctx_, column, column_name, GRN_TABLE_MAX_KEY_SIZE);
+ std::string field_name(column_name, column_name_size);
+ std::shared_ptr<arrow::DataType> field_type;
+ switch (grn_obj_get_range(ctx_, column)) {
+ case GRN_DB_BOOL :
+ field_type = arrow::boolean();
+ break;
+ case GRN_DB_UINT8 :
+ field_type = arrow::uint8();
+ break;
+ case GRN_DB_INT8 :
+ field_type = arrow::int8();
+ break;
+ case GRN_DB_UINT16 :
+ field_type = arrow::uint16();
+ break;
+ case GRN_DB_INT16 :
+ field_type = arrow::int16();
+ break;
+ case GRN_DB_UINT32 :
+ field_type = arrow::uint32();
+ break;
+ case GRN_DB_INT32 :
+ field_type = arrow::int32();
+ break;
+ case GRN_DB_UINT64 :
+ field_type = arrow::uint64();
+ break;
+ case GRN_DB_INT64 :
+ field_type = arrow::int64();
+ break;
+ case GRN_DB_FLOAT :
+ field_type = arrow::float64();
+ break;
+ case GRN_DB_TIME :
+ field_type =
+ std::make_shared<arrow::TimestampType>(arrow::TimeUnit::MICRO);
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ field_type = arrow::utf8();
+ break;
+ default :
+ break;
+ }
+ if (!field_type) {
+ continue;
+ }
+
+ auto field = std::make_shared<arrow::Field>(field_name,
+ field_type,
+ false);
+ fields.push_back(field);
+ };
+
+ auto schema = std::make_shared<arrow::Schema>(fields);
+
+ std::shared_ptr<arrow::ipc::RecordBatchFileWriter> writer;
+ auto status =
+ arrow::ipc::RecordBatchFileWriter::Open(output, schema, &writer);
+ if (!check_status(ctx_,
+ status,
+ "[arrow][dump] failed to create file format writer")) {
+ return ctx_->rc;
+ }
+
+ std::vector<grn_id> ids;
+ int n_records_per_batch = 1000;
+ GRN_TABLE_EACH_BEGIN(ctx_, grn_table_, table_cursor, record_id) {
+ ids.push_back(record_id);
+ if (ids.size() == n_records_per_batch) {
+ write_record_batch(ids, schema, writer);
+ ids.clear();
+ }
+ } GRN_TABLE_EACH_END(ctx_, table_cursor);
+ if (!ids.empty()) {
+ write_record_batch(ids, schema, writer);
+ }
+ writer->Close();
+
+ return ctx_->rc;
+ }
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *grn_table_;
+ grn_obj *grn_columns_;
+
+ void write_record_batch(std::vector<grn_id> &ids,
+ std::shared_ptr<arrow::Schema> &schema,
+ std::shared_ptr<arrow::ipc::RecordBatchFileWriter> &writer) {
+ std::vector<std::shared_ptr<arrow::Array>> columns;
+ auto n_columns = GRN_BULK_VSIZE(grn_columns_) / sizeof(grn_obj *);
+ for (auto i = 0; i < n_columns; ++i) {
+ auto grn_column = GRN_PTR_VALUE_AT(grn_columns_, i);
+
+ arrow::Status status;
+ std::shared_ptr<arrow::Array> column;
+
+ switch (grn_obj_get_range(ctx_, grn_column)) {
+ case GRN_DB_BOOL :
+ status = build_boolean_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_UINT8 :
+ status = build_uint8_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_INT8 :
+ status = build_int8_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_UINT16 :
+ status = build_uint16_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_INT16 :
+ status = build_int16_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_UINT32 :
+ status = build_uint32_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_INT32 :
+ status = build_int32_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_UINT64 :
+ status = build_uint64_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_INT64 :
+ status = build_int64_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_FLOAT :
+ status = build_double_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_TIME :
+ status = build_timestamp_array(ids, grn_column, &column);
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ status = build_utf8_array(ids, grn_column, &column);
+ break;
+ default :
+ status =
+ arrow::Status::NotImplemented("[arrow][dumper] not supported type: TODO");
+ break;
+ }
+ if (!status.ok()) {
+ continue;
+ }
+ columns.push_back(column);
+ }
+
+ arrow::RecordBatch record_batch(schema, ids.size(), columns);
+ writer->WriteRecordBatch(record_batch);
+ }
+
+ arrow::Status build_boolean_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::BooleanBuilder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(*(reinterpret_cast<const grn_bool *>(data)));
+ }
+ return builder.Finish(array);
+ }
+
+ arrow::Status build_uint8_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::UInt8Builder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(*(reinterpret_cast<const uint8_t *>(data)));
+ }
+ return builder.Finish(array);
+ }
+
+ arrow::Status build_int8_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::Int8Builder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(*(reinterpret_cast<const int8_t *>(data)));
+ }
+ return builder.Finish(array);
+ }
+
+ arrow::Status build_uint16_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::UInt16Builder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(*(reinterpret_cast<const uint16_t *>(data)));
+ }
+ return builder.Finish(array);
+ }
+
+ arrow::Status build_int16_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::Int16Builder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(*(reinterpret_cast<const int16_t *>(data)));
+ }
+ return builder.Finish(array);
+ }
+
+ arrow::Status build_uint32_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::UInt32Builder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(*(reinterpret_cast<const uint32_t *>(data)));
+ }
+ return builder.Finish(array);
+ }
+
+ arrow::Status build_int32_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::Int32Builder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(*(reinterpret_cast<const int32_t *>(data)));
+ }
+ return builder.Finish(array);
+ }
+ arrow::Status build_uint64_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::UInt64Builder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(*(reinterpret_cast<const uint64_t *>(data)));
+ }
+ return builder.Finish(array);
+ }
+
+ arrow::Status build_int64_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::Int64Builder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(*(reinterpret_cast<const int64_t *>(data)));
+ }
+ return builder.Finish(array);
+ }
+
+ arrow::Status build_double_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::DoubleBuilder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(*(reinterpret_cast<const double *>(data)));
+ }
+ return builder.Finish(array);
+ }
+
+ arrow::Status build_timestamp_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ auto timestamp_ns_data_type =
+ std::make_shared<arrow::TimestampType>(arrow::TimeUnit::MICRO);
+ arrow::TimestampBuilder builder(arrow::default_memory_pool(),
+ timestamp_ns_data_type);
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ auto timestamp_ns = *(reinterpret_cast<const int64_t *>(data));
+ builder.Append(timestamp_ns);
+ }
+ return builder.Finish(array);
+ }
+
+ arrow::Status build_utf8_array(std::vector<grn_id> &ids,
+ grn_obj *grn_column,
+ std::shared_ptr<arrow::Array> *array) {
+ arrow::StringBuilder builder(arrow::default_memory_pool());
+ for (auto id : ids) {
+ uint32_t size;
+ auto data = grn_obj_get_value_(ctx_, grn_column, id, &size);
+ builder.Append(data, size);
+ }
+ return builder.Finish(array);
+ }
+ };
+}
+#endif /* GRN_WITH_ARROW */
+
+extern "C" {
+grn_rc
+grn_arrow_load(grn_ctx *ctx,
+ grn_obj *table,
+ const char *path)
+{
+ GRN_API_ENTER;
+#ifdef GRN_WITH_ARROW
+ std::shared_ptr<arrow::io::MemoryMappedFile> input;
+ auto status =
+ arrow::io::MemoryMappedFile::Open(path, arrow::io::FileMode::READ, &input);
+ if (!grnarrow::check_status(ctx,
+ status,
+ std::ostringstream() <<
+ "[arrow][load] failed to open path: " <<
+ "<" << path << ">")) {
+ GRN_API_RETURN(ctx->rc);
+ }
+ std::shared_ptr<arrow::ipc::RecordBatchFileReader> reader;
+ status = arrow::ipc::RecordBatchFileReader::Open(input, &reader);
+ if (!grnarrow::check_status(ctx,
+ status,
+ "[arrow][load] "
+ "failed to create file format reader")) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ grnarrow::FileLoader loader(ctx, table);
+ int n_record_batches = reader->num_record_batches();
+ for (int i = 0; i < n_record_batches; ++i) {
+ std::shared_ptr<arrow::RecordBatch> record_batch;
+ status = reader->ReadRecordBatch(i, &record_batch);
+ if (!grnarrow::check_status(ctx,
+ status,
+ std::ostringstream("") <<
+ "[arrow][load] failed to get " <<
+ "the " << i << "-th " << "record")) {
+ break;
+ }
+ loader.load_record_batch(record_batch);
+ if (ctx->rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+#else /* GRN_WITH_ARROW */
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "[arrow][load] Apache Arrow support isn't enabled");
+#endif /* GRN_WITH_ARROW */
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_arrow_dump(grn_ctx *ctx,
+ grn_obj *table,
+ const char *path)
+{
+ GRN_API_ENTER;
+#ifdef GRN_WITH_ARROW
+ auto all_columns =
+ grn_hash_create(ctx,
+ NULL,
+ sizeof(grn_id),
+ 0,
+ GRN_OBJ_TABLE_HASH_KEY | GRN_HASH_TINY);
+ grn_table_columns(ctx,
+ table,
+ "", 0,
+ reinterpret_cast<grn_obj *>(all_columns));
+
+ grn_obj columns;
+ GRN_PTR_INIT(&columns, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ GRN_HASH_EACH_BEGIN(ctx, all_columns, cursor, id) {
+ void *key;
+ grn_hash_cursor_get_key(ctx, cursor, &key);
+ auto column_id = static_cast<grn_id *>(key);
+ auto column = grn_ctx_at(ctx, *column_id);
+ GRN_PTR_PUT(ctx, &columns, column);
+ } GRN_HASH_EACH_END(ctx, cursor);
+ grn_hash_close(ctx, all_columns);
+
+ grn_arrow_dump_columns(ctx, table, &columns, path);
+ GRN_OBJ_FIN(ctx, &columns);
+#else /* GRN_WITH_ARROW */
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "[arrow][dump] Apache Arrow support isn't enabled");
+#endif /* GRN_WITH_ARROW */
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_arrow_dump_columns(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *columns,
+ const char *path)
+{
+ GRN_API_ENTER;
+#ifdef GRN_WITH_ARROW
+ std::shared_ptr<arrow::io::FileOutputStream> output;
+ auto status = arrow::io::FileOutputStream::Open(path, &output);
+ if (!grnarrow::check_status(ctx,
+ status,
+ std::stringstream() <<
+ "[arrow][dump] failed to open path: " <<
+ "<" << path << ">")) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ grnarrow::FileDumper dumper(ctx, table, columns);
+ dumper.dump(output.get());
+#else /* GRN_WITH_ARROW */
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "[arrow][dump] Apache Arrow support isn't enabled");
+#endif /* GRN_WITH_ARROW */
+ GRN_API_RETURN(ctx->rc);
+}
+}
diff --git a/storage/mroonga/vendor/groonga/lib/sources.am b/storage/mroonga/vendor/groonga/lib/c_sources.am
index ab1ad3e81b5..3b76e69309f 100644
--- a/storage/mroonga/vendor/groonga/lib/sources.am
+++ b/storage/mroonga/vendor/groonga/lib/c_sources.am
@@ -1,43 +1,62 @@
-libgroonga_la_SOURCES = \
+libgroonga_c_sources = \
+ alloc.c \
+ grn_alloc.h \
+ cache.c \
+ grn_cache.h \
+ column.c \
com.c \
grn_com.h \
command.c \
+ config.c \
+ grn_config.h \
ctx.c \
grn_ctx.h \
grn_ctx_impl.h \
ctx_impl_mrb.c \
grn_ctx_impl_mrb.h \
- dat.cpp \
grn_dat.h \
db.c \
grn_db.h \
- egn.cpp \
- grn_egn.h \
- grn_egn.hpp \
+ dump.c \
+ ts.c \
+ grn_ts.h \
+ type.c \
error.c \
grn_error.h \
expr.c \
grn_expr.h \
expr_code.c \
grn_expr_code.h \
+ expr_executor.c \
+ grn_expr_executor.h \
+ file_lock.c \
+ grn_file_lock.h \
geo.c \
grn_geo.h \
grn.h \
hash.c \
grn_hash.h \
+ id.c \
ii.c \
grn_ii.h \
+ index_column.c \
+ grn_index_column.h \
io.c \
grn_io.h \
+ load.c \
+ grn_load.h \
logger.c \
grn_logger.h \
mrb.c \
grn_mrb.h \
grn_msgpack.h \
nfkc.c \
+ grn_nfkc.h \
+ nfkc50.c \
normalizer.c \
grn_normalizer.h \
obj.c \
+ grn_obj.h \
operator.c \
output.c \
grn_output.h \
@@ -47,10 +66,18 @@ libgroonga_la_SOURCES = \
grn_plugin.h \
proc.c \
grn_proc.h \
+ raw_string.c \
+ grn_raw_string.h \
+ report.c \
+ grn_report.h \
request_canceler.c \
grn_request_canceler.h \
+ request_timer.c \
+ grn_request_timer.h \
rset.c \
grn_rset.h \
+ scanner.c \
+ grn_scanner.h \
scorer.c \
grn_scorer.h \
scorers.c \
@@ -63,6 +90,10 @@ libgroonga_la_SOURCES = \
grn_str.h \
string.c \
grn_string.h \
+ table.c \
+ thread.c \
+ time.c \
+ grn_time.h \
token_cursor.c \
grn_token_cursor.h \
tokenizer.c \
@@ -70,4 +101,12 @@ libgroonga_la_SOURCES = \
grn_tokenizers.h \
token_filter.c \
util.c \
- grn_util.h
+ grn_util.h \
+ windows.c \
+ grn_windows.h \
+ windows_event_logger.c \
+ file_reader.c \
+ window_function.c \
+ grn_window_function.h \
+ window_functions.c \
+ grn_window_functions.h
diff --git a/storage/mroonga/vendor/groonga/lib/cache.c b/storage/mroonga/vendor/groonga/lib/cache.c
new file mode 100644
index 00000000000..38238f6894b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/cache.c
@@ -0,0 +1,1036 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_cache.h"
+#include "grn_ctx.h"
+#include "grn_ctx_impl.h"
+#include "grn_hash.h"
+#include "grn_pat.h"
+#include "grn_store.h"
+#include "grn_db.h"
+#include "grn_file_lock.h"
+
+#include <sys/stat.h>
+
+typedef struct _grn_cache_entry_memory grn_cache_entry_memory;
+
+struct _grn_cache_entry_memory {
+ grn_cache_entry_memory *next;
+ grn_cache_entry_memory *prev;
+ grn_obj *value;
+ grn_timeval tv;
+ grn_id id;
+};
+
+typedef struct _grn_cache_entry_persistent_data {
+ grn_id next;
+ grn_id prev;
+ grn_timeval modified_time;
+} grn_cache_entry_persistent_data;
+
+/*
+ sizeof(grn_cache_entry_persistent_metadata) should be equal or smaller
+ than sizeof(grn_cache_entry_persistent_data).
+ */
+typedef struct _grn_cache_entry_persistent_metadata {
+ uint32_t max_nentries;
+ uint32_t nfetches;
+ uint32_t nhits;
+} grn_cache_entry_persistent_metadata;
+
+typedef union _grn_cache_entry_persistent {
+ grn_cache_entry_persistent_data data;
+ grn_cache_entry_persistent_metadata metadata;
+} grn_cache_entry_persistent;
+
+struct _grn_cache {
+ union {
+ struct {
+ grn_cache_entry_memory *next;
+ grn_cache_entry_memory *prev;
+ grn_hash *hash;
+ grn_mutex mutex;
+ uint32_t max_nentries;
+ uint32_t nfetches;
+ uint32_t nhits;
+ } memory;
+ struct {
+ grn_hash *keys;
+ grn_ja *values;
+ int timeout;
+ } persistent;
+ } impl;
+ grn_bool is_memory;
+ grn_ctx *ctx;
+};
+
+#define GRN_CACHE_PERSISTENT_ROOT_ID 1
+#define GRN_CACHE_PERSISTENT_ROOT_KEY "\0"
+#define GRN_CACHE_PERSISTENT_ROOT_KEY_LEN \
+ (sizeof(GRN_CACHE_PERSISTENT_ROOT_KEY) - 1)
+#define GRN_CACHE_PERSISTENT_METADATA_ID 2
+#define GRN_CACHE_PERSISTENT_METADATA_KEY "\1"
+#define GRN_CACHE_PERSISTENT_METADATA_KEY_LEN \
+ (sizeof(GRN_CACHE_PERSISTENT_METADATA_KEY) - 1)
+
+static grn_ctx grn_cache_ctx;
+static grn_cache *grn_cache_current = NULL;
+static grn_cache *grn_cache_default = NULL;
+static char grn_cache_default_base_path[PATH_MAX];
+
+void
+grn_set_default_cache_base_path(const char *base_path)
+{
+ if (base_path) {
+ grn_strcpy(grn_cache_default_base_path,
+ PATH_MAX,
+ base_path);
+ } else {
+ grn_cache_default_base_path[0] = '\0';
+ }
+}
+
+const char *
+grn_get_default_cache_base_path(void)
+{
+ if (grn_cache_default_base_path[0] == '\0') {
+ return NULL;
+ } else {
+ return grn_cache_default_base_path;
+ }
+}
+
+static void
+grn_cache_open_memory(grn_ctx *ctx, grn_cache *cache)
+{
+ cache->impl.memory.next = (grn_cache_entry_memory *)cache;
+ cache->impl.memory.prev = (grn_cache_entry_memory *)cache;
+ cache->impl.memory.hash = grn_hash_create(cache->ctx,
+ NULL,
+ GRN_CACHE_MAX_KEY_SIZE,
+ sizeof(grn_cache_entry_memory),
+ GRN_OBJ_KEY_VAR_SIZE);
+ if (!cache->impl.memory.hash) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "[cache] failed to create hash table");
+ return;
+ }
+ MUTEX_INIT(cache->impl.memory.mutex);
+
+ cache->impl.memory.max_nentries = GRN_CACHE_DEFAULT_MAX_N_ENTRIES;
+ cache->impl.memory.nfetches = 0;
+ cache->impl.memory.nhits = 0;
+}
+
+static void
+grn_cache_open_persistent(grn_ctx *ctx,
+ grn_cache *cache,
+ const char *base_path)
+{
+ grn_file_lock file_lock;
+ char *keys_path = NULL;
+ char *values_path = NULL;
+ char lock_path_buffer[PATH_MAX];
+ char keys_path_buffer[PATH_MAX];
+ char values_path_buffer[PATH_MAX];
+
+ cache->impl.persistent.timeout = 1000;
+
+ if (base_path) {
+ grn_snprintf(lock_path_buffer, PATH_MAX, PATH_MAX, "%s.lock", base_path);
+ grn_file_lock_init(ctx, &file_lock, lock_path_buffer);
+ } else {
+ grn_file_lock_init(ctx, &file_lock, NULL);
+ }
+
+ if (base_path) {
+ struct stat stat_buffer;
+
+ grn_snprintf(keys_path_buffer, PATH_MAX, PATH_MAX, "%s.keys", base_path);
+ grn_snprintf(values_path_buffer, PATH_MAX, PATH_MAX, "%s.values", base_path);
+ keys_path = keys_path_buffer;
+ values_path = values_path_buffer;
+
+ if (!grn_file_lock_acquire(ctx,
+ &file_lock,
+ cache->impl.persistent.timeout,
+ "[cache][persistent][open]")) {
+ goto exit;
+ }
+
+ if (stat(keys_path, &stat_buffer) == 0) {
+ cache->impl.persistent.keys = grn_hash_open(ctx, keys_path);
+ if (cache->impl.persistent.keys) {
+ cache->impl.persistent.values = grn_ja_open(ctx, values_path);
+ }
+ }
+ if (!cache->impl.persistent.keys) {
+ if (cache->impl.persistent.values) {
+ grn_ja_close(ctx, cache->impl.persistent.values);
+ cache->impl.persistent.values = NULL;
+ }
+ if (stat(keys_path, &stat_buffer) == 0) {
+ if (grn_hash_remove(ctx, keys_path) != GRN_SUCCESS) {
+ ERRNO_ERR("[cache][persistent] "
+ "failed to remove path for cache keys: <%s>",
+ keys_path);
+ goto exit;
+ }
+ }
+ if (stat(values_path, &stat_buffer) == 0) {
+ if (grn_ja_remove(ctx, values_path) != GRN_SUCCESS) {
+ ERRNO_ERR("[cache][persistent] "
+ "failed to remove path for cache values: <%s>",
+ values_path);
+ goto exit;
+ }
+ }
+ }
+ }
+
+ if (!cache->impl.persistent.keys) {
+ cache->impl.persistent.keys =
+ grn_hash_create(ctx,
+ keys_path,
+ GRN_CACHE_MAX_KEY_SIZE,
+ sizeof(grn_cache_entry_persistent),
+ GRN_OBJ_KEY_VAR_SIZE);
+ if (!cache->impl.persistent.keys) {
+ ERR(ctx->rc == GRN_SUCCESS ? GRN_FILE_CORRUPT : ctx->rc,
+ "[cache][persistent] failed to create cache keys storage: <%s>",
+ keys_path ? keys_path : "(memory)");
+ goto exit;
+ }
+ cache->impl.persistent.values =
+ grn_ja_create(ctx,
+ values_path,
+ 1 << 16,
+ 0);
+ if (!cache->impl.persistent.values) {
+ grn_hash_close(ctx, cache->impl.persistent.keys);
+ ERR(ctx->rc == GRN_SUCCESS ? GRN_FILE_CORRUPT : ctx->rc,
+ "[cache][persistent] failed to create cache values storage: <%s>",
+ values_path ? values_path : "(memory)");
+ goto exit;
+ }
+ }
+
+ {
+ grn_cache_entry_persistent *entry;
+ grn_id root_id;
+ int added;
+
+ root_id = grn_hash_add(ctx,
+ cache->impl.persistent.keys,
+ GRN_CACHE_PERSISTENT_ROOT_KEY,
+ GRN_CACHE_PERSISTENT_ROOT_KEY_LEN,
+ (void **)&entry,
+ &added);
+ if (root_id != GRN_CACHE_PERSISTENT_ROOT_ID) {
+ grn_ja_close(ctx, cache->impl.persistent.values);
+ grn_hash_close(ctx, cache->impl.persistent.keys);
+ if (values_path) {
+ grn_ja_remove(ctx, values_path);
+ }
+ if (keys_path) {
+ grn_hash_remove(ctx, keys_path);
+ }
+ ERR(ctx->rc == GRN_SUCCESS ? GRN_FILE_CORRUPT : ctx->rc,
+ "[cache][persistent] broken cache keys storage: broken root: <%s>",
+ keys_path ? keys_path : "(memory)");
+ return;
+ }
+
+ if (added) {
+ entry->data.next = root_id;
+ entry->data.prev = root_id;
+ entry->data.modified_time.tv_sec = 0;
+ entry->data.modified_time.tv_nsec = 0;
+ }
+ }
+
+ {
+ grn_cache_entry_persistent *entry;
+ grn_id metadata_id;
+ int added;
+
+ metadata_id = grn_hash_add(ctx,
+ cache->impl.persistent.keys,
+ GRN_CACHE_PERSISTENT_METADATA_KEY,
+ GRN_CACHE_PERSISTENT_METADATA_KEY_LEN,
+ (void **)&entry,
+ &added);
+ if (metadata_id != GRN_CACHE_PERSISTENT_METADATA_ID) {
+ grn_ja_close(ctx, cache->impl.persistent.values);
+ grn_hash_close(ctx, cache->impl.persistent.keys);
+ if (values_path) {
+ grn_ja_remove(ctx, values_path);
+ }
+ if (keys_path) {
+ grn_hash_remove(ctx, keys_path);
+ }
+ ERR(ctx->rc == GRN_SUCCESS ? GRN_FILE_CORRUPT : ctx->rc,
+ "[cache][persistent] broken cache keys storage: broken metadata: <%s>",
+ keys_path ? keys_path : "(memory)");
+ goto exit;
+ }
+
+ if (added) {
+ entry->metadata.max_nentries = GRN_CACHE_DEFAULT_MAX_N_ENTRIES;
+ entry->metadata.nfetches = 0;
+ entry->metadata.nhits = 0;
+ }
+ }
+
+exit :
+ grn_file_lock_release(ctx, &file_lock);
+ grn_file_lock_fin(ctx, &file_lock);
+}
+
+static grn_cache *
+grn_cache_open_raw(grn_ctx *ctx,
+ grn_bool is_memory,
+ const char *base_path)
+{
+ grn_cache *cache = NULL;
+
+ GRN_API_ENTER;
+ cache = GRN_CALLOC(sizeof(grn_cache));
+ if (!cache) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "[cache] failed to allocate grn_cache");
+ goto exit;
+ }
+
+ cache->ctx = ctx;
+ cache->is_memory = is_memory;
+ if (cache->is_memory) {
+ grn_cache_open_memory(ctx, cache);
+ } else {
+ grn_cache_open_persistent(ctx, cache, base_path);
+ }
+ if (ctx->rc != GRN_SUCCESS) {
+ GRN_FREE(cache);
+ cache = NULL;
+ goto exit;
+ }
+
+exit :
+ GRN_API_RETURN(cache);
+}
+
+grn_cache *
+grn_cache_open(grn_ctx *ctx)
+{
+ const char *base_path = NULL;
+ grn_bool is_memory;
+
+ if (grn_cache_default_base_path[0] != '\0') {
+ base_path = grn_cache_default_base_path;
+ }
+
+ if (base_path) {
+ is_memory = GRN_FALSE;
+ } else {
+ char grn_cache_type_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_CACHE_TYPE", grn_cache_type_env, GRN_ENV_BUFFER_SIZE);
+ if (strcmp(grn_cache_type_env, "persistent") == 0) {
+ is_memory = GRN_FALSE;
+ } else {
+ is_memory = GRN_TRUE;
+ }
+ }
+
+ return grn_cache_open_raw(ctx, is_memory, base_path);
+}
+
+grn_cache *
+grn_persistent_cache_open(grn_ctx *ctx, const char *base_path)
+{
+ grn_bool is_memory = GRN_FALSE;
+ return grn_cache_open_raw(ctx, is_memory, base_path);
+}
+
+
+static void
+grn_cache_close_memory(grn_ctx *ctx, grn_cache *cache)
+{
+ grn_cache_entry_memory *vp;
+
+ GRN_HASH_EACH(ctx, cache->impl.memory.hash, id, NULL, NULL, &vp, {
+ grn_obj_close(ctx, vp->value);
+ });
+ grn_hash_close(ctx, cache->impl.memory.hash);
+ MUTEX_FIN(cache->impl.memory.mutex);
+}
+
+static void
+grn_cache_close_persistent(grn_ctx *ctx, grn_cache *cache)
+{
+ grn_hash_close(ctx, cache->impl.persistent.keys);
+ grn_ja_close(ctx, cache->impl.persistent.values);
+}
+
+grn_rc
+grn_cache_close(grn_ctx *ctx_not_used, grn_cache *cache)
+{
+ grn_ctx *ctx = cache->ctx;
+
+ GRN_API_ENTER;
+
+ if (cache->is_memory) {
+ grn_cache_close_memory(ctx, cache);
+ } else {
+ grn_cache_close_persistent(ctx, cache);
+ }
+ GRN_FREE(cache);
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_cache_current_set(grn_ctx *ctx, grn_cache *cache)
+{
+ grn_cache_current = cache;
+ return GRN_SUCCESS;
+}
+
+grn_cache *
+grn_cache_current_get(grn_ctx *ctx)
+{
+ return grn_cache_current;
+}
+
+void
+grn_cache_init(void)
+{
+ grn_ctx *ctx = &grn_cache_ctx;
+
+ grn_ctx_init(ctx, 0);
+
+ grn_cache_default = grn_cache_open(ctx);
+ grn_cache_current_set(ctx, grn_cache_default);
+}
+
+grn_rc
+grn_cache_default_reopen(void)
+{
+ grn_ctx *ctx = &grn_cache_ctx;
+ grn_cache *new_default;
+ grn_bool default_is_current;
+
+ GRN_API_ENTER;
+
+ new_default = grn_cache_open(ctx);
+ if (!new_default) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ default_is_current = (grn_cache_default == grn_cache_current_get(ctx));
+ if (default_is_current) {
+ grn_cache_current_set(ctx, new_default);
+ }
+
+ if (grn_cache_default) {
+ grn_cache_close(ctx, grn_cache_default);
+ }
+ grn_cache_default = new_default;
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+static void
+grn_cache_expire_entry_memory(grn_cache *cache, grn_cache_entry_memory *ce)
+{
+ ce->prev->next = ce->next;
+ ce->next->prev = ce->prev;
+ grn_obj_close(cache->ctx, ce->value);
+ grn_hash_delete_by_id(cache->ctx, cache->impl.memory.hash, ce->id, NULL);
+}
+
+static void
+grn_cache_entry_persistent_delete_link(grn_cache *cache,
+ grn_cache_entry_persistent *entry)
+{
+ grn_ctx *ctx = cache->ctx;
+ grn_hash *keys = cache->impl.persistent.keys;
+ grn_cache_entry_persistent *prev_entry;
+ grn_cache_entry_persistent *next_entry;
+
+ prev_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ entry->data.prev,
+ NULL);
+ next_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ entry->data.next,
+ NULL);
+ prev_entry->data.next = entry->data.next;
+ next_entry->data.prev = entry->data.prev;
+}
+
+static void
+grn_cache_entry_persistent_prepend_link(grn_cache *cache,
+ grn_cache_entry_persistent *entry,
+ grn_id entry_id,
+ grn_cache_entry_persistent *head_entry,
+ grn_id head_entry_id)
+{
+ grn_ctx *ctx = cache->ctx;
+ grn_hash *keys = cache->impl.persistent.keys;
+ grn_cache_entry_persistent *head_next_entry;
+
+ entry->data.next = head_entry->data.next;
+ entry->data.prev = head_entry_id;
+ head_next_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ head_entry->data.next,
+ NULL);
+ head_next_entry->data.prev = entry_id;
+ head_entry->data.next = entry_id;
+}
+
+static void
+grn_cache_expire_entry_persistent(grn_cache *cache,
+ grn_cache_entry_persistent *entry,
+ grn_id cache_id)
+{
+ grn_hash *keys = cache->impl.persistent.keys;
+ grn_ja *values = cache->impl.persistent.values;
+
+ grn_cache_entry_persistent_delete_link(cache, entry);
+ grn_ja_put(cache->ctx, values, cache_id, NULL, 0, GRN_OBJ_SET, NULL);
+ grn_hash_delete_by_id(cache->ctx, keys, cache_id, NULL);
+}
+
+static void
+grn_cache_expire_memory_without_lock(grn_cache *cache, int32_t size)
+{
+ grn_cache_entry_memory *ce0 =
+ (grn_cache_entry_memory *)(&(cache->impl.memory));
+ while (ce0 != ce0->prev && size--) {
+ grn_cache_expire_entry_memory(cache, ce0->prev);
+ }
+}
+
+static void
+grn_cache_expire_persistent_without_lock(grn_cache *cache, int32_t size)
+{
+ grn_ctx *ctx = cache->ctx;
+ grn_hash *keys = cache->impl.persistent.keys;
+ grn_cache_entry_persistent *head_entry;
+
+ head_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ GRN_CACHE_PERSISTENT_ROOT_ID,
+ NULL);
+ while (head_entry->data.prev != GRN_CACHE_PERSISTENT_ROOT_ID &&
+ size > 0) {
+ grn_cache_entry_persistent *tail_entry;
+ tail_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ head_entry->data.prev,
+ NULL);
+ grn_cache_expire_entry_persistent(cache, tail_entry, head_entry->data.prev);
+ size--;
+ }
+}
+
+static grn_rc
+grn_cache_set_max_n_entries_memory(grn_ctx *ctx,
+ grn_cache *cache,
+ unsigned int n)
+{
+ uint32_t current_max_n_entries;
+
+ MUTEX_LOCK(cache->impl.memory.mutex);
+ current_max_n_entries = cache->impl.memory.max_nentries;
+ cache->impl.memory.max_nentries = n;
+ if (n < current_max_n_entries) {
+ grn_cache_expire_memory_without_lock(cache, current_max_n_entries - n);
+ }
+ MUTEX_UNLOCK(cache->impl.memory.mutex);
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_cache_set_max_n_entries_persistent(grn_ctx *ctx,
+ grn_cache *cache,
+ unsigned int n)
+{
+ grn_rc rc;
+ grn_hash *keys = cache->impl.persistent.keys;
+ grn_cache_entry_persistent *metadata_entry;
+ uint32_t current_max_n_entries;
+
+ rc = grn_io_lock(ctx, keys->io, cache->impl.persistent.timeout);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ metadata_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ GRN_CACHE_PERSISTENT_METADATA_ID,
+ NULL);
+
+ current_max_n_entries = metadata_entry->metadata.max_nentries;
+ metadata_entry->metadata.max_nentries = n;
+ if (n < current_max_n_entries) {
+ grn_cache_expire_persistent_without_lock(cache, current_max_n_entries - n);
+ }
+ grn_io_unlock(keys->io);
+
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_cache_set_max_n_entries(grn_ctx *ctx, grn_cache *cache, unsigned int n)
+{
+ if (!cache) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ if (cache->is_memory) {
+ return grn_cache_set_max_n_entries_memory(cache->ctx, cache, n);
+ } else {
+ return grn_cache_set_max_n_entries_persistent(cache->ctx, cache, n);
+ }
+}
+
+static uint32_t
+grn_cache_get_max_n_entries_memory(grn_ctx *ctx, grn_cache *cache)
+{
+ return cache->impl.memory.max_nentries;
+}
+
+static uint32_t
+grn_cache_get_max_n_entries_persistent(grn_ctx *ctx, grn_cache *cache)
+{
+ grn_rc rc;
+ grn_hash *keys = cache->impl.persistent.keys;
+ grn_cache_entry_persistent *metadata_entry;
+ uint32_t current_max_n_entries;
+
+ rc = grn_io_lock(ctx, keys->io, cache->impl.persistent.timeout);
+ if (rc != GRN_SUCCESS) {
+ return 0;
+ }
+
+ metadata_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ GRN_CACHE_PERSISTENT_METADATA_ID,
+ NULL);
+ current_max_n_entries = metadata_entry->metadata.max_nentries;
+ grn_io_unlock(keys->io);
+
+ return current_max_n_entries;
+}
+
+uint32_t
+grn_cache_get_max_n_entries(grn_ctx *ctx, grn_cache *cache)
+{
+ if (!cache) {
+ return 0;
+ }
+
+ if (cache->is_memory) {
+ return grn_cache_get_max_n_entries_memory(cache->ctx, cache);
+ } else {
+ return grn_cache_get_max_n_entries_persistent(cache->ctx, cache);
+ }
+}
+
+static void
+grn_cache_get_statistics_memory(grn_ctx *ctx, grn_cache *cache,
+ grn_cache_statistics *statistics)
+{
+ MUTEX_LOCK(cache->impl.memory.mutex);
+ statistics->nentries = GRN_HASH_SIZE(cache->impl.memory.hash);
+ statistics->max_nentries = cache->impl.memory.max_nentries;
+ statistics->nfetches = cache->impl.memory.nfetches;
+ statistics->nhits = cache->impl.memory.nhits;
+ MUTEX_UNLOCK(cache->impl.memory.mutex);
+}
+
+static void
+grn_cache_get_statistics_persistent(grn_ctx *ctx, grn_cache *cache,
+ grn_cache_statistics *statistics)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_hash *keys = cache->impl.persistent.keys;
+ grn_cache_entry_persistent *metadata_entry;
+
+ rc = grn_io_lock(ctx, keys->io, cache->impl.persistent.timeout);
+ if (rc != GRN_SUCCESS) {
+ return;
+ }
+
+ metadata_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ GRN_CACHE_PERSISTENT_METADATA_ID,
+ NULL);
+
+ statistics->nentries = GRN_HASH_SIZE(keys);
+ statistics->max_nentries = metadata_entry->metadata.max_nentries;
+ statistics->nfetches = metadata_entry->metadata.nfetches;
+ statistics->nhits = metadata_entry->metadata.nhits;
+
+ grn_io_unlock(keys->io);
+}
+
+void
+grn_cache_get_statistics(grn_ctx *ctx, grn_cache *cache,
+ grn_cache_statistics *statistics)
+{
+ if (cache->is_memory) {
+ return grn_cache_get_statistics_memory(ctx, cache, statistics);
+ } else {
+ return grn_cache_get_statistics_persistent(ctx, cache, statistics);
+ }
+}
+
+static grn_rc
+grn_cache_fetch_memory(grn_ctx *ctx, grn_cache *cache,
+ const char *key, uint32_t key_len,
+ grn_obj *output)
+{
+ /* TODO: How about GRN_NOT_FOUND? */
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_cache_entry_memory *ce;
+
+ MUTEX_LOCK(cache->impl.memory.mutex);
+ cache->impl.memory.nfetches++;
+ if (grn_hash_get(cache->ctx, cache->impl.memory.hash, key, key_len,
+ (void **)&ce)) {
+ if (ce->tv.tv_sec <= grn_db_get_last_modified(ctx, ctx->impl->db)) {
+ grn_cache_expire_entry_memory(cache, ce);
+ goto exit;
+ }
+ rc = GRN_SUCCESS;
+ GRN_TEXT_PUT(ctx,
+ output,
+ GRN_TEXT_VALUE(ce->value),
+ GRN_TEXT_LEN(ce->value));
+ ce->prev->next = ce->next;
+ ce->next->prev = ce->prev;
+ {
+ grn_cache_entry_memory *ce0 =
+ (grn_cache_entry_memory *)(&(cache->impl.memory));
+ ce->next = ce0->next;
+ ce->prev = ce0;
+ ce0->next->prev = ce;
+ ce0->next = ce;
+ }
+ cache->impl.memory.nhits++;
+ }
+exit :
+ MUTEX_UNLOCK(cache->impl.memory.mutex);
+ return rc;
+}
+
+static grn_rc
+grn_cache_fetch_persistent(grn_ctx *ctx, grn_cache *cache,
+ const char *key, uint32_t key_len,
+ grn_obj *output)
+{
+ /* TODO: How about GRN_NOT_FOUND? */
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_hash *keys = cache->impl.persistent.keys;
+ grn_ja *values = cache->impl.persistent.values;
+ grn_id cache_id;
+ grn_cache_entry_persistent *entry;
+ grn_cache_entry_persistent *metadata_entry;
+
+ if (key_len == GRN_CACHE_PERSISTENT_ROOT_KEY_LEN &&
+ memcmp(key,
+ GRN_CACHE_PERSISTENT_ROOT_KEY,
+ GRN_CACHE_PERSISTENT_ROOT_KEY_LEN) == 0) {
+ return rc;
+ }
+
+ rc = grn_io_lock(ctx, keys->io, cache->impl.persistent.timeout);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ /* TODO: How about GRN_NOT_FOUND? */
+ rc = GRN_INVALID_ARGUMENT;
+
+ metadata_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ GRN_CACHE_PERSISTENT_METADATA_ID,
+ NULL);
+ metadata_entry->metadata.nfetches++;
+
+ cache_id = grn_hash_get(cache->ctx, keys, key, key_len, (void **)&entry);
+ if (cache_id == GRN_ID_NIL) {
+ goto exit;
+ }
+
+ if (cache_id != GRN_ID_NIL) {
+ if (entry->data.modified_time.tv_sec <=
+ grn_db_get_last_modified(ctx, ctx->impl->db)) {
+ grn_cache_expire_entry_persistent(cache, entry, cache_id);
+ goto exit;
+ }
+
+ rc = GRN_SUCCESS;
+ grn_ja_get_value(ctx, values, cache_id, output);
+ grn_cache_entry_persistent_delete_link(cache, entry);
+ {
+ grn_cache_entry_persistent *head_entry;
+ head_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ GRN_CACHE_PERSISTENT_ROOT_ID,
+ NULL);
+ grn_cache_entry_persistent_prepend_link(cache,
+ entry,
+ cache_id,
+ head_entry,
+ GRN_CACHE_PERSISTENT_ROOT_ID);
+ }
+ metadata_entry->metadata.nhits++;
+ }
+
+exit :
+ grn_io_unlock(keys->io);
+
+ return rc;
+}
+
+grn_rc
+grn_cache_fetch(grn_ctx *ctx, grn_cache *cache,
+ const char *key, uint32_t key_len,
+ grn_obj *output)
+{
+ if (!ctx->impl || !ctx->impl->db) { return GRN_INVALID_ARGUMENT; }
+
+ if (cache->is_memory) {
+ return grn_cache_fetch_memory(ctx, cache, key, key_len, output);
+ } else {
+ return grn_cache_fetch_persistent(ctx, cache, key, key_len, output);
+ }
+}
+
+static void
+grn_cache_update_memory(grn_ctx *ctx, grn_cache *cache,
+ const char *key, uint32_t key_len,
+ grn_obj *value)
+{
+ grn_id id;
+ int added = 0;
+ grn_cache_entry_memory *ce;
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *old = NULL;
+ grn_obj *obj = NULL;
+
+ if (cache->impl.memory.max_nentries == 0) {
+ return;
+ }
+
+ MUTEX_LOCK(cache->impl.memory.mutex);
+ obj = grn_obj_open(cache->ctx, GRN_BULK, 0, GRN_DB_TEXT);
+ if (!obj) {
+ goto exit;
+ }
+ GRN_TEXT_PUT(cache->ctx, obj, GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
+ id = grn_hash_add(cache->ctx, cache->impl.memory.hash, key, key_len,
+ (void **)&ce, &added);
+ if (id) {
+ if (!added) {
+ old = ce->value;
+ ce->prev->next = ce->next;
+ ce->next->prev = ce->prev;
+ }
+ ce->id = id;
+ ce->value = obj;
+ ce->tv = ctx->impl->tv;
+ {
+ grn_cache_entry_memory *ce0 =
+ (grn_cache_entry_memory *)(&(cache->impl.memory));
+ ce->next = ce0->next;
+ ce->prev = ce0;
+ ce0->next->prev = ce;
+ ce0->next = ce;
+ }
+ if (GRN_HASH_SIZE(cache->impl.memory.hash) >
+ cache->impl.memory.max_nentries) {
+ grn_cache_expire_entry_memory(cache, cache->impl.memory.prev);
+ }
+ } else {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ }
+exit :
+ if (rc) { grn_obj_close(cache->ctx, obj); }
+ if (old) { grn_obj_close(cache->ctx, old); }
+ MUTEX_UNLOCK(cache->impl.memory.mutex);
+}
+
+static void
+grn_cache_update_persistent(grn_ctx *ctx, grn_cache *cache,
+ const char *key, uint32_t key_len,
+ grn_obj *value)
+{
+ grn_rc rc;
+ grn_hash *keys = cache->impl.persistent.keys;
+ grn_ja *values = cache->impl.persistent.values;
+ grn_cache_entry_persistent *metadata_entry;
+ grn_id cache_id;
+ grn_cache_entry_persistent *entry;
+ int added;
+
+ if (key_len == GRN_CACHE_PERSISTENT_ROOT_KEY_LEN &&
+ memcmp(key,
+ GRN_CACHE_PERSISTENT_ROOT_KEY,
+ GRN_CACHE_PERSISTENT_ROOT_KEY_LEN) == 0) {
+ return;
+ }
+
+ if (key_len == GRN_CACHE_PERSISTENT_METADATA_KEY_LEN &&
+ memcmp(key,
+ GRN_CACHE_PERSISTENT_METADATA_KEY,
+ GRN_CACHE_PERSISTENT_METADATA_KEY_LEN) == 0) {
+ return;
+ }
+
+ rc = grn_io_lock(ctx, keys->io, cache->impl.persistent.timeout);
+ if (rc != GRN_SUCCESS) {
+ return;
+ }
+
+ metadata_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ GRN_CACHE_PERSISTENT_METADATA_ID,
+ NULL);
+ if (metadata_entry->metadata.max_nentries == 0) {
+ goto exit;
+ }
+
+ cache_id = grn_hash_add(cache->ctx, keys, key, key_len, (void **)&entry,
+ &added);
+ if (cache_id) {
+ grn_cache_entry_persistent *head_entry;
+
+ if (!added) {
+ grn_cache_entry_persistent_delete_link(cache, entry);
+ }
+ entry->data.modified_time = ctx->impl->tv;
+
+ grn_ja_put(cache->ctx, values, cache_id,
+ GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value),
+ GRN_OBJ_SET, NULL);
+
+ head_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ GRN_CACHE_PERSISTENT_ROOT_ID,
+ NULL);
+ grn_cache_entry_persistent_prepend_link(cache,
+ entry,
+ cache_id,
+ head_entry,
+ GRN_CACHE_PERSISTENT_ROOT_ID);
+ if (GRN_HASH_SIZE(keys) > metadata_entry->metadata.max_nentries) {
+ grn_cache_entry_persistent *tail_entry;
+ tail_entry =
+ (grn_cache_entry_persistent *)grn_hash_get_value_(ctx,
+ keys,
+ head_entry->data.prev,
+ NULL);
+ grn_cache_expire_entry_persistent(cache,
+ tail_entry,
+ head_entry->data.prev);
+ }
+ }
+
+exit :
+ grn_io_unlock(keys->io);
+}
+
+void
+grn_cache_update(grn_ctx *ctx, grn_cache *cache,
+ const char *key, uint32_t key_len, grn_obj *value)
+{
+ if (!ctx->impl) { return; }
+
+ if (cache->is_memory) {
+ grn_cache_update_memory(ctx, cache, key, key_len, value);
+ } else {
+ grn_cache_update_persistent(ctx, cache, key, key_len, value);
+ }
+}
+
+static void
+grn_cache_expire_memory(grn_cache *cache, int32_t size)
+{
+ MUTEX_LOCK(cache->impl.memory.mutex);
+ grn_cache_expire_memory_without_lock(cache, size);
+ MUTEX_UNLOCK(cache->impl.memory.mutex);
+}
+
+static void
+grn_cache_expire_persistent(grn_cache *cache, int32_t size)
+{
+ grn_rc rc;
+ grn_ctx *ctx = cache->ctx;
+ grn_hash *keys = cache->impl.persistent.keys;
+
+ rc = grn_io_lock(ctx, keys->io, cache->impl.persistent.timeout);
+ if (rc != GRN_SUCCESS) {
+ return;
+ }
+
+ grn_cache_expire_persistent_without_lock(cache, size);
+
+ grn_io_unlock(keys->io);
+}
+
+void
+grn_cache_expire(grn_cache *cache, int32_t size)
+{
+ if (cache->is_memory) {
+ grn_cache_expire_memory(cache, size);
+ } else {
+ grn_cache_expire_persistent(cache, size);
+ }
+}
+
+void
+grn_cache_fin(void)
+{
+ grn_ctx *ctx = &grn_cache_ctx;
+
+ grn_cache_current_set(ctx, NULL);
+
+ if (grn_cache_default) {
+ grn_cache_close(ctx, grn_cache_default);
+ grn_cache_default = NULL;
+ }
+
+ grn_ctx_fin(ctx);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/column.c b/storage/mroonga/vendor/groonga/lib/column.c
new file mode 100644
index 00000000000..63c5d592132
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/column.c
@@ -0,0 +1,49 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn.h"
+#include "grn_store.h"
+#include "grn_ii.h"
+
+grn_column_flags
+grn_column_get_flags(grn_ctx *ctx, grn_obj *column)
+{
+ grn_column_flags flags = 0;
+
+ GRN_API_ENTER;
+
+ if (!column) {
+ GRN_API_RETURN(0);
+ }
+
+ switch (column->header.type) {
+ case GRN_COLUMN_FIX_SIZE :
+ flags = column->header.flags;
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ flags = grn_ja_get_flags(ctx, (grn_ja *)column);
+ break;
+ case GRN_COLUMN_INDEX :
+ flags = grn_ii_get_flags(ctx, (grn_ii *)column);
+ break;
+ default :
+ break;
+ }
+
+ GRN_API_RETURN(flags);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/com.c b/storage/mroonga/vendor/groonga/lib/com.c
index 5455d1f8e09..4d685b77841 100644
--- a/storage/mroonga/vendor/groonga/lib/com.c
+++ b/storage/mroonga/vendor/groonga/lib/com.c
@@ -199,9 +199,9 @@ grn_msg_send(grn_ctx *ctx, grn_obj *msg, int flags)
break;
case GRN_COM_PROTO_GQTP :
{
- if ((flags & GRN_CTX_MORE)) { flags |= GRN_CTX_QUIET; }
+ if (flags & GRN_CTX_MORE) { flags |= GRN_CTX_QUIET; }
if (ctx->stat == GRN_CTX_QUIT) { flags |= GRN_CTX_QUIT; }
- header->qtype = (uint8_t) ctx->impl->output_type;
+ header->qtype = (uint8_t) ctx->impl->output.type;
header->keylen = 0;
header->level = 0;
header->flags = flags;
@@ -277,6 +277,10 @@ grn_com_event_init(grn_ctx *ctx, grn_com_event *ev, int max_nevents, int data_si
MUTEX_INIT(ev->mutex);
COND_INIT(ev->cond);
GRN_COM_QUEUE_INIT(&ev->recv_old);
+ ev->msg_handler = NULL;
+ memset(&(ev->curr_edge_id), 0, sizeof(grn_com_addr));
+ ev->acceptor = NULL;
+ ev->opaque = NULL;
#ifndef USE_SELECT
# ifdef USE_EPOLL
if ((ev->events = GRN_MALLOC(sizeof(struct epoll_event) * max_nevents))) {
@@ -451,7 +455,7 @@ grn_com_event_del(grn_ctx *ctx, grn_com_event *ev, grn_sock fd)
} else {
GRN_LOG(ctx, GRN_LOG_ERROR,
"%04x| fd(%" GRN_FMT_SOCKET ") not found in ev(%p)",
- getpid(), fd, ev);
+ grn_getpid(), fd, ev);
return GRN_INVALID_ARGUMENT;
}
}
@@ -568,8 +572,8 @@ grn_com_event_poll(grn_ctx *ctx, grn_com_event *ev, int timeout)
(void **)(&pfd),
&dummy,
(void **)(&com));
- if ((com->events & GRN_COM_POLLIN)) { FD_SET(*pfd, &rfds); }
- if ((com->events & GRN_COM_POLLOUT)) { FD_SET(*pfd, &wfds); }
+ if (com->events & GRN_COM_POLLIN) { FD_SET(*pfd, &rfds); }
+ if (com->events & GRN_COM_POLLOUT) { FD_SET(*pfd, &wfds); }
# ifndef WIN32
if (*pfd > nfds) { nfds = *pfd; }
# endif /* WIN32 */
@@ -651,7 +655,7 @@ grn_com_event_poll(grn_ctx *ctx, grn_com_event *ev, int timeout)
if (grn_sock_close(efd) == -1) { SOERR("close"); }
continue;
}
- if ((ep->events & GRN_COM_POLLIN)) { grn_com_receiver(ctx, com); }
+ if (ep->events & GRN_COM_POLLIN) { grn_com_receiver(ctx, com); }
# else /* USE_EPOLL */
# ifdef USE_KQUEUE
efd = ep->ident;
@@ -665,7 +669,7 @@ grn_com_event_poll(grn_ctx *ctx, grn_com_event *ev, int timeout)
if (grn_sock_close(efd) == -1) { SOERR("close"); }
continue;
}
- if ((ep->filter == GRN_COM_POLLIN)) { grn_com_receiver(ctx, com); }
+ if (ep->filter == GRN_COM_POLLIN) { grn_com_receiver(ctx, com); }
# else
efd = ep->fd;
if (!(ep->events & ep->revents)) { continue; }
@@ -675,7 +679,7 @@ grn_com_event_poll(grn_ctx *ctx, grn_com_event *ev, int timeout)
if (grn_sock_close(efd) == -1) { SOERR("close"); }
continue;
}
- if ((ep->revents & GRN_COM_POLLIN)) { grn_com_receiver(ctx, com); }
+ if (ep->revents & GRN_COM_POLLIN) { grn_com_receiver(ctx, com); }
# endif /* USE_KQUEUE */
# endif /* USE_EPOLL */
}
@@ -884,7 +888,7 @@ grn_com_recv(grn_ctx *ctx, grn_com *com, grn_com_header *header, grn_obj *buf)
case GRN_COM_PROTO_GQTP :
case GRN_COM_PROTO_MBREQ :
if (GRN_BULK_WSIZE(buf) < value_size) {
- if ((grn_bulk_resize(ctx, buf, value_size))) {
+ if (grn_bulk_resize(ctx, buf, value_size)) {
goto exit;
}
}
@@ -963,21 +967,30 @@ grn_com_copen(grn_ctx *ctx, grn_com_event *ev, const char *dest, int port)
for (addrinfo_ptr = addrinfo_list; addrinfo_ptr;
addrinfo_ptr = addrinfo_ptr->ai_next) {
- static const int value = 1;
fd = socket(addrinfo_ptr->ai_family, addrinfo_ptr->ai_socktype,
addrinfo_ptr->ai_protocol);
if (fd == -1) {
SOERR("socket");
- } else if (setsockopt(fd, 6, TCP_NODELAY,
- (const char *)&value, sizeof(value))) {
- SOERR("setsockopt");
- grn_sock_close(fd);
- } else if (connect(fd, addrinfo_ptr->ai_addr, addrinfo_ptr->ai_addrlen)) {
+ continue;
+ }
+#ifdef TCP_NODELAY
+ {
+ static const int value = 1;
+ if (setsockopt(fd, 6, TCP_NODELAY,
+ (const char *)&value, sizeof(value)) != 0) {
+ SOERR("setsockopt");
+ grn_sock_close(fd);
+ continue;
+ }
+ }
+#endif
+ if (connect(fd, addrinfo_ptr->ai_addr, addrinfo_ptr->ai_addrlen) != 0) {
SOERR("connect");
grn_sock_close(fd);
- } else {
- break;
+ continue;
}
+
+ break;
}
freeaddrinfo(addrinfo_list);
@@ -1086,10 +1099,12 @@ grn_com_sopen(grn_ctx *ctx, grn_com_event *ev,
ev->curr_edge_id.sid = 0;
{
int v = 1;
+#ifdef TCP_NODELAY
if (setsockopt(lfd, SOL_TCP, TCP_NODELAY, (void *) &v, sizeof(int)) == -1) {
SOERR("setsockopt");
goto exit;
}
+#endif
if (setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (void *) &v, sizeof(int)) == -1) {
SOERR("setsockopt");
goto exit;
diff --git a/storage/mroonga/vendor/groonga/lib/command.c b/storage/mroonga/vendor/groonga/lib/command.c
index 282d15b6a0e..82db2170da9 100644
--- a/storage/mroonga/vendor/groonga/lib/command.c
+++ b/storage/mroonga/vendor/groonga/lib/command.c
@@ -122,9 +122,8 @@ grn_command_input_at(grn_ctx *ctx,
GRN_API_ENTER;
if (input->arguments) {
- uint32_t size;
argument = (grn_obj *)grn_hash_get_value_(ctx, input->arguments,
- offset + 1, &size);
+ offset + 1, NULL);
}
GRN_API_RETURN(argument);
}
diff --git a/storage/mroonga/vendor/groonga/lib/config.c b/storage/mroonga/vendor/groonga/lib/config.c
new file mode 100644
index 00000000000..ef40cc9c4de
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/config.c
@@ -0,0 +1,289 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_ctx_impl.h"
+#include "grn_config.h"
+
+#include <string.h>
+
+grn_rc
+grn_config_set(grn_ctx *ctx,
+ const char *key, int32_t key_size,
+ const char *value, int32_t value_size)
+{
+ grn_obj *db;
+ grn_hash *config;
+ void *packed_value;
+ grn_id id;
+
+ GRN_API_ENTER;
+
+ if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
+ ERR(GRN_INVALID_ARGUMENT, "[config][set] DB isn't initialized");
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ if (key_size == -1) {
+ key_size = strlen(key);
+ }
+ if (key_size > GRN_CONFIG_MAX_KEY_SIZE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[config][set] too large key: max=<%d>: <%d>",
+ GRN_CONFIG_MAX_KEY_SIZE, key_size);
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ if (value_size == -1) {
+ value_size = strlen(value);
+ }
+ if (value_size > GRN_CONFIG_MAX_VALUE_SIZE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[config][set] too large value: max=<%" GRN_FMT_SIZE ">: <%d>",
+ GRN_CONFIG_MAX_VALUE_SIZE, value_size);
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ config = ((grn_db *)db)->config;
+ {
+ grn_rc rc;
+ rc = grn_io_lock(ctx, config->io, grn_lock_timeout);
+ if (rc != GRN_SUCCESS) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(rc, "[config][set] failed to lock");
+ }
+ GRN_API_RETURN(rc);
+ }
+ id = grn_hash_add(ctx, config, key, key_size, &packed_value, NULL);
+ grn_io_unlock(config->io);
+ }
+ if (id == GRN_ID_NIL && ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[config][set] failed to set: name=<%.*s>: <%d>",
+ key_size, key, value_size);
+ }
+
+ *((uint32_t *)packed_value) = (uint32_t)value_size;
+ grn_memcpy((char *)packed_value + sizeof(uint32_t),
+ value, value_size);
+ ((char *)packed_value)[sizeof(uint32_t) + value_size] = '\0';
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_config_get(grn_ctx *ctx,
+ const char *key, int32_t key_size,
+ const char **value, uint32_t *value_size)
+{
+ grn_obj *db;
+ grn_hash *config;
+ grn_id id;
+ void *packed_value;
+
+ GRN_API_ENTER;
+
+ if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
+ ERR(GRN_INVALID_ARGUMENT, "[config][get] DB isn't initialized");
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ if (key_size == -1) {
+ key_size = strlen(key);
+ }
+ if (key_size > GRN_CONFIG_MAX_KEY_SIZE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[config][get] too large key: max=<%d>: <%d>",
+ GRN_CONFIG_MAX_KEY_SIZE, key_size);
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ config = ((grn_db *)db)->config;
+ id = grn_hash_get(ctx, config, key, key_size, &packed_value);
+ if (id == GRN_ID_NIL) {
+ *value = NULL;
+ *value_size = 0;
+ GRN_API_RETURN(GRN_SUCCESS);
+ }
+
+ *value = (char *)packed_value + sizeof(uint32_t);
+ *value_size = *((uint32_t *)packed_value);
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+grn_rc
+grn_config_delete(grn_ctx *ctx,
+ const char *key, int key_size)
+{
+ grn_obj *db;
+ grn_hash *config;
+
+ GRN_API_ENTER;
+
+ if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
+ ERR(GRN_INVALID_ARGUMENT, "[config][delete] DB isn't initialized");
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ if (key_size == -1) {
+ key_size = strlen(key);
+ }
+ if (key_size > GRN_CONFIG_MAX_KEY_SIZE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[config][delete] too large key: max=<%d>: <%d>",
+ GRN_CONFIG_MAX_KEY_SIZE, key_size);
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ config = ((grn_db *)db)->config;
+ {
+ grn_rc rc;
+ rc = grn_io_lock(ctx, config->io, grn_lock_timeout);
+ if (rc != GRN_SUCCESS) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(rc, "[config][delete] failed to lock");
+ }
+ GRN_API_RETURN(rc);
+ }
+ rc = grn_hash_delete(ctx, config, key, key_size, NULL);
+ grn_io_unlock(config->io);
+ if (rc != GRN_SUCCESS) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(rc, "[config][delete] failed to delete");
+ }
+ }
+ }
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_obj *
+grn_config_cursor_open(grn_ctx *ctx)
+{
+ grn_obj *db;
+ grn_hash *config;
+ grn_config_cursor *cursor;
+ grn_id id;
+
+ GRN_API_ENTER;
+
+ if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
+ ERR(GRN_INVALID_ARGUMENT, "[config][cursor][open] DB isn't initialized");
+ GRN_API_RETURN(NULL);
+ }
+ config = ((grn_db *)db)->config;
+
+ cursor = GRN_MALLOCN(grn_config_cursor, 1);
+ if (!cursor) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[config][cursor][open] failed to allocate memory for config cursor");
+ GRN_API_RETURN(NULL);
+ }
+
+ GRN_DB_OBJ_SET_TYPE(cursor, GRN_CURSOR_CONFIG);
+ cursor->hash_cursor = grn_hash_cursor_open(ctx, config,
+ NULL, -1,
+ NULL, -1,
+ 0, -1, 0);
+ if (!cursor->hash_cursor) {
+ GRN_FREE(cursor);
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[config][cursor][open] failed to allocate memory for hash cursor");
+ GRN_API_RETURN(NULL);
+ }
+
+ id = grn_obj_register(ctx, ctx->impl->db, NULL, 0);
+ DB_OBJ(cursor)->header.domain = GRN_ID_NIL;
+ DB_OBJ(cursor)->range = GRN_ID_NIL;
+ grn_db_obj_init(ctx, ctx->impl->db, id, DB_OBJ(cursor));
+
+ GRN_API_RETURN((grn_obj *)cursor);
+}
+
+grn_rc
+grn_config_cursor_close(grn_ctx *ctx, grn_config_cursor *cursor)
+{
+ grn_hash_cursor_close(ctx, cursor->hash_cursor);
+ GRN_FREE(cursor);
+
+ return GRN_SUCCESS;
+}
+
+grn_bool
+grn_config_cursor_next(grn_ctx *ctx, grn_obj *cursor)
+{
+ grn_bool have_next;
+ grn_config_cursor *config_cursor = (grn_config_cursor *)cursor;
+
+ GRN_API_ENTER;
+
+ have_next = grn_hash_cursor_next(ctx, config_cursor->hash_cursor) != GRN_ID_NIL;
+
+ GRN_API_RETURN(have_next);
+}
+
+uint32_t
+grn_config_cursor_get_key(grn_ctx *ctx, grn_obj *cursor, const char **key)
+{
+ void *key_raw;
+ uint32_t key_size;
+ grn_config_cursor *config_cursor = (grn_config_cursor *)cursor;
+
+ GRN_API_ENTER;
+
+ key_size = grn_hash_cursor_get_key(ctx, config_cursor->hash_cursor, &key_raw);
+ *key = key_raw;
+
+ GRN_API_RETURN(key_size);
+}
+
+uint32_t
+grn_config_cursor_get_value(grn_ctx *ctx, grn_obj *cursor, const char **value)
+{
+ void *value_raw;
+ uint32_t value_size;
+ uint32_t value_size_raw;
+ grn_config_cursor *config_cursor = (grn_config_cursor *)cursor;
+
+ GRN_API_ENTER;
+
+ value_size_raw = grn_hash_cursor_get_value(ctx,
+ config_cursor->hash_cursor,
+ &value_raw);
+ *value = (char *)value_raw + sizeof(uint32_t);
+ value_size = *((uint32_t *)value_raw);
+
+ GRN_API_RETURN(value_size);
+}
+
+/* Deprecated since 5.1.2. Use grn_config_* instead. */
+grn_rc
+grn_conf_set(grn_ctx *ctx,
+ const char *key, int32_t key_size,
+ const char *value, int32_t value_size)
+{
+ return grn_config_set(ctx, key, key_size, value, value_size);
+}
+
+grn_rc
+grn_conf_get(grn_ctx *ctx,
+ const char *key, int32_t key_size,
+ const char **value, uint32_t *value_size)
+{
+ return grn_config_get(ctx, key, key_size, value, value_size);
+}
+
diff --git a/storage/mroonga/vendor/groonga/lib/cpp_sources.am b/storage/mroonga/vendor/groonga/lib/cpp_sources.am
new file mode 100644
index 00000000000..c1d09a97a26
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/cpp_sources.am
@@ -0,0 +1,3 @@
+libgroonga_cpp_source = \
+ arrow.cpp \
+ dat.cpp
diff --git a/storage/mroonga/vendor/groonga/lib/ctx.c b/storage/mroonga/vendor/groonga/lib/ctx.c
index c4a485527c1..b6c7ba559c3 100644
--- a/storage/mroonga/vendor/groonga/lib/ctx.c
+++ b/storage/mroonga/vendor/groonga/lib/ctx.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -19,10 +19,12 @@
#include "grn.h"
#include <string.h>
#include "grn_request_canceler.h"
+#include "grn_request_timer.h"
#include "grn_tokenizers.h"
#include "grn_ctx_impl.h"
#include "grn_ii.h"
#include "grn_pat.h"
+#include "grn_index_column.h"
#include "grn_proc.h"
#include "grn_plugin.h"
#include "grn_snip.h"
@@ -31,24 +33,26 @@
#include "grn_mrb.h"
#include "grn_ctx_impl_mrb.h"
#include "grn_logger.h"
+#include "grn_cache.h"
+#include "grn_expr.h"
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
+#ifdef GRN_WITH_ONIGMO
+# define GRN_SUPPORT_REGEXP
+#endif /* GRN_WITH_ONIGMO */
+
+#ifdef GRN_SUPPORT_REGEXP
+# include <onigmo.h>
+#endif /* GRN_SUPPORT_REGEXP */
+
#ifdef WIN32
# include <share.h>
#else /* WIN32 */
# include <netinet/in.h>
#endif /* WIN32 */
-#if defined(HAVE__LOCALTIME64_S) && defined(__GNUC__)
-# ifdef _WIN64
-# define localtime_s(tm, time) _localtime64_s(tm, time)
-# else /* _WIN64 */
-# define localtime_s(tm, time) _localtime32_s(tm, time)
-# endif /* _WIN64 */
-#endif /* defined(HAVE__LOCALTIME64_S) && defined(__GNUC__) */
-
#define GRN_CTX_INITIALIZER(enc) \
{ GRN_SUCCESS, 0, enc, 0, GRN_LOG_NOTICE,\
GRN_CTX_FIN, 0, 0, 0, 0, {0}, NULL, NULL, NULL, NULL, NULL, \
@@ -56,17 +60,6 @@
#define GRN_CTX_CLOSED(ctx) ((ctx)->stat == GRN_CTX_FIN)
-#ifdef USE_EXACT_ALLOC_COUNT
-#define GRN_ADD_ALLOC_COUNT(count) do { \
- uint32_t alloced; \
- GRN_ATOMIC_ADD_EX(&alloc_count, count, alloced); \
-} while (0)
-#else /* USE_EXACT_ALLOC_COUNT */
-#define GRN_ADD_ALLOC_COUNT(count) do { \
- alloc_count += count; \
-} while (0)
-#endif
-
grn_ctx grn_gctx = GRN_CTX_INITIALIZER(GRN_ENC_DEFAULT);
int grn_pagesize;
grn_critical_section grn_glock;
@@ -92,15 +85,34 @@ grn_init_from_env(void)
}
}
+ grn_alloc_init_from_env();
grn_mrb_init_from_env();
grn_ctx_impl_mrb_init_from_env();
grn_io_init_from_env();
grn_ii_init_from_env();
grn_db_init_from_env();
+ grn_expr_init_from_env();
+ grn_index_column_init_from_env();
grn_proc_init_from_env();
grn_plugin_init_from_env();
}
+static void
+grn_init_external_libraries(void)
+{
+#ifdef GRN_SUPPORT_REGEXP
+ onig_init();
+#endif /* GRN_SUPPORT_REGEXP */
+}
+
+static void
+grn_fin_external_libraries(void)
+{
+#ifdef GRN_SUPPORT_REGEXP
+ onig_end();
+#endif /* GRN_SUPPORT_REGEXP */
+}
+
void
grn_sleep(uint32_t seconds)
{
@@ -124,357 +136,22 @@ grn_nanosleep(uint64_t nanoseconds)
#endif // WIN32
}
-/* fixme by 2038 */
-
-grn_rc
-grn_timeval_now(grn_ctx *ctx, grn_timeval *tv)
-{
-#ifdef HAVE_CLOCK_GETTIME
- struct timespec t;
- if (clock_gettime(CLOCK_REALTIME, &t)) {
- SERR("clock_gettime");
- } else {
- tv->tv_sec = t.tv_sec;
- tv->tv_nsec = t.tv_nsec;
- }
- return ctx->rc;
-#else /* HAVE_CLOCK_GETTIME */
-#ifdef WIN32
- time_t t;
- struct _timeb tb;
- time(&t);
- _ftime(&tb);
- tv->tv_sec = t;
- tv->tv_nsec = tb.millitm * (GRN_TIME_NSEC_PER_SEC / 1000);
- return GRN_SUCCESS;
-#else /* WIN32 */
- struct timeval t;
- if (gettimeofday(&t, NULL)) {
- SERR("gettimeofday");
- } else {
- tv->tv_sec = t.tv_sec;
- tv->tv_nsec = GRN_TIME_USEC_TO_NSEC(t.tv_usec);
- }
- return ctx->rc;
-#endif /* WIN32 */
-#endif /* HAVE_CLOCK_GETTIME */
-}
-
-void
-grn_time_now(grn_ctx *ctx, grn_obj *obj)
-{
- grn_timeval tv;
- grn_timeval_now(ctx, &tv);
- GRN_TIME_SET(ctx, obj, GRN_TIME_PACK(tv.tv_sec,
- GRN_TIME_NSEC_TO_USEC(tv.tv_nsec)));
-}
-
-struct tm *
-grn_timeval2tm(grn_ctx *ctx, grn_timeval *tv, struct tm *tm_buffer)
-{
- struct tm *ltm;
- const char *function_name;
-#ifdef HAVE__LOCALTIME64_S
- time_t t = tv->tv_sec;
- function_name = "localtime_s";
- ltm = (localtime_s(tm_buffer, &t) == 0) ? tm_buffer : NULL;
-#else /* HAVE__LOCALTIME64_S */
-# ifdef HAVE_LOCALTIME_R
- time_t t = tv->tv_sec;
- function_name = "localtime_r";
- ltm = localtime_r(&t, tm_buffer);
-# else /* HAVE_LOCALTIME_R */
- time_t tvsec = (time_t) tv->tv_sec;
- function_name = "localtime";
- ltm = localtime(&tvsec);
-# endif /* HAVE_LOCALTIME_R */
-#endif /* HAVE__LOCALTIME64_S */
- if (!ltm) {
- SERR(function_name);
- }
- return ltm;
-}
-
-grn_rc
-grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf, size_t buf_size)
-{
- struct tm tm;
- struct tm *ltm;
- ltm = grn_timeval2tm(ctx, tv, &tm);
- grn_snprintf(buf, buf_size, GRN_TIMEVAL_STR_SIZE,
- GRN_TIMEVAL_STR_FORMAT,
- ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday,
- ltm->tm_hour, ltm->tm_min, ltm->tm_sec,
- (int)(GRN_TIME_NSEC_TO_USEC(tv->tv_nsec)));
- if (buf_size > GRN_TIMEVAL_STR_SIZE) {
- buf[GRN_TIMEVAL_STR_SIZE - 1] = '\0';
- } else {
- buf[buf_size - 1] = '\0';
- }
- return ctx->rc;
-}
-
-grn_rc
-grn_str2timeval(const char *str, uint32_t str_len, grn_timeval *tv)
-{
- struct tm tm;
- const char *r1, *r2, *rend = str + str_len;
- uint32_t uv;
- memset(&tm, 0, sizeof(struct tm));
-
- tm.tm_year = (int)grn_atoui(str, rend, &r1) - 1900;
- if ((r1 + 1) >= rend || (*r1 != '/' && *r1 != '-') ||
- tm.tm_year < 0) { return GRN_INVALID_ARGUMENT; }
- r1++;
- tm.tm_mon = (int)grn_atoui(r1, rend, &r1) - 1;
- if ((r1 + 1) >= rend || (*r1 != '/' && *r1 != '-') ||
- tm.tm_mon < 0 || tm.tm_mon >= 12) { return GRN_INVALID_ARGUMENT; }
- r1++;
- tm.tm_mday = (int)grn_atoui(r1, rend, &r1);
- if ((r1 + 1) >= rend || *r1 != ' ' ||
- tm.tm_mday < 1 || tm.tm_mday > 31) { return GRN_INVALID_ARGUMENT; }
-
- tm.tm_hour = (int)grn_atoui(++r1, rend, &r2);
- if ((r2 + 1) >= rend || r1 == r2 || *r2 != ':' ||
- tm.tm_hour < 0 || tm.tm_hour >= 24) {
- return GRN_INVALID_ARGUMENT;
- }
- r1 = r2 + 1;
- tm.tm_min = (int)grn_atoui(r1, rend, &r2);
- if ((r2 + 1) >= rend || r1 == r2 || *r2 != ':' ||
- tm.tm_min < 0 || tm.tm_min >= 60) {
- return GRN_INVALID_ARGUMENT;
- }
- r1 = r2 + 1;
- tm.tm_sec = (int)grn_atoui(r1, rend, &r2);
- if (r1 == r2 ||
- tm.tm_sec < 0 || tm.tm_sec > 61 /* leap 2sec */) {
- return GRN_INVALID_ARGUMENT;
- }
- r1 = r2;
- tm.tm_yday = -1;
- tm.tm_isdst = -1;
-
- /* tm_yday is set appropriately (0-365) on successful completion. */
- tv->tv_sec = mktime(&tm);
- if (tm.tm_yday == -1) { return GRN_INVALID_ARGUMENT; }
- if ((r1 + 1) < rend && *r1 == '.') { r1++; }
- uv = grn_atoi(r1, rend, &r2);
- while (r2 < r1 + 6) {
- uv *= 10;
- r2++;
- }
- if (uv >= GRN_TIME_USEC_PER_SEC) { return GRN_INVALID_ARGUMENT; }
- tv->tv_nsec = GRN_TIME_USEC_TO_NSEC(uv);
- return GRN_SUCCESS;
-}
-
-#ifdef USE_MEMORY_DEBUG
-inline static void
-grn_alloc_info_set_backtrace(char *buffer, size_t size)
-{
-# define N_TRACE_LEVEL 100
- static void *trace[N_TRACE_LEVEL];
- char **symbols;
- int i, n, rest;
-
- rest = size;
- n = backtrace(trace, N_TRACE_LEVEL);
- symbols = backtrace_symbols(trace, n);
- if (symbols) {
- for (i = 0; i < n; i++) {
- int symbol_length;
-
- symbol_length = strlen(symbols[i]);
- if (symbol_length + 2 > rest) {
- break;
- }
- grn_memcpy(buffer, symbols[i], symbol_length);
- buffer += symbol_length;
- rest -= symbol_length;
- buffer[0] = '\n';
- buffer++;
- rest--;
- buffer[0] = '\0';
- rest--;
- }
- free(symbols);
- } else {
- buffer[0] = '\0';
- }
-# undef N_TRACE_LEVEL
-}
-
-inline static void
-grn_alloc_info_add(void *address, const char *file, int line, const char *func)
-{
- grn_ctx *ctx;
- grn_alloc_info *new_alloc_info;
-
- ctx = &grn_gctx;
- if (!ctx->impl) { return; }
-
- new_alloc_info = malloc(sizeof(grn_alloc_info));
- new_alloc_info->address = address;
- new_alloc_info->freed = GRN_FALSE;
- grn_alloc_info_set_backtrace(new_alloc_info->alloc_backtrace,
- sizeof(new_alloc_info->alloc_backtrace));
- if (file) {
- new_alloc_info->file = strdup(file);
- } else {
- new_alloc_info->file = NULL;
- }
- new_alloc_info->line = line;
- if (func) {
- new_alloc_info->func = strdup(func);
- } else {
- new_alloc_info->func = NULL;
- }
- new_alloc_info->next = ctx->impl->alloc_info;
- ctx->impl->alloc_info = new_alloc_info;
-}
-
-inline static void
-grn_alloc_info_change(void *old_address, void *new_address)
-{
- grn_ctx *ctx;
- grn_alloc_info *alloc_info;
-
- ctx = &grn_gctx;
- if (!ctx->impl) { return; }
-
- alloc_info = ctx->impl->alloc_info;
- for (; alloc_info; alloc_info = alloc_info->next) {
- if (alloc_info->address == old_address) {
- alloc_info->address = new_address;
- grn_alloc_info_set_backtrace(alloc_info->alloc_backtrace,
- sizeof(alloc_info->alloc_backtrace));
- }
- }
-}
-
-inline static void
-grn_alloc_info_dump(grn_ctx *ctx)
-{
- int i = 0;
- grn_alloc_info *alloc_info;
-
- if (!ctx) { return; }
- if (!ctx->impl) { return; }
-
- alloc_info = ctx->impl->alloc_info;
- for (; alloc_info; alloc_info = alloc_info->next) {
- if (alloc_info->freed) {
- printf("address[%d][freed]: %p\n", i, alloc_info->address);
- } else {
- printf("address[%d][not-freed]: %p: %s:%d: %s()\n%s",
- i,
- alloc_info->address,
- alloc_info->file ? alloc_info->file : "(unknown)",
- alloc_info->line,
- alloc_info->func ? alloc_info->func : "(unknown)",
- alloc_info->alloc_backtrace);
- }
- i++;
- }
-}
-
-inline static void
-grn_alloc_info_check(void *address)
+const char *
+grn_get_global_error_message(void)
{
- grn_ctx *ctx;
- grn_alloc_info *alloc_info;
-
- ctx = &grn_gctx;
- if (!ctx->impl) { return; }
- /* grn_alloc_info_dump(ctx); */
-
- alloc_info = ctx->impl->alloc_info;
- for (; alloc_info; alloc_info = alloc_info->next) {
- if (alloc_info->address == address) {
- if (alloc_info->freed) {
- GRN_LOG(ctx, GRN_LOG_WARNING,
- "double free: (%p):\nalloc backtrace:\n%sfree backtrace:\n%s",
- alloc_info->address,
- alloc_info->alloc_backtrace,
- alloc_info->free_backtrace);
- } else {
- alloc_info->freed = GRN_TRUE;
- grn_alloc_info_set_backtrace(alloc_info->free_backtrace,
- sizeof(alloc_info->free_backtrace));
- }
- return;
- }
- }
+ return grn_gctx.errbuf;
}
-inline static void
-grn_alloc_info_free(grn_ctx *ctx)
-{
- grn_alloc_info *alloc_info;
-
- if (!ctx) { return; }
- if (!ctx->impl) { return; }
-
- alloc_info = ctx->impl->alloc_info;
- while (alloc_info) {
- grn_alloc_info *current_alloc_info = alloc_info;
- alloc_info = alloc_info->next;
- current_alloc_info->next = NULL;
- free(current_alloc_info->file);
- free(current_alloc_info->func);
- free(current_alloc_info);
- }
- ctx->impl->alloc_info = NULL;
-}
-
-#else /* USE_MEMORY_DEBUG */
-# define grn_alloc_info_add(address, file, line, func)
-# define grn_alloc_info_change(old_address, new_address)
-# define grn_alloc_info_check(address)
-# define grn_alloc_info_dump(ctx)
-# define grn_alloc_info_free(ctx)
-#endif /* USE_MEMORY_DEBUG */
-
-#ifdef USE_FAIL_MALLOC
-int grn_fmalloc_prob = 0;
-char *grn_fmalloc_func = NULL;
-char *grn_fmalloc_file = NULL;
-int grn_fmalloc_line = 0;
-#endif /* USE_FAIL_MALLOC */
-
-#define GRN_CTX_SEGMENT_SIZE (1<<22)
-#define GRN_CTX_SEGMENT_MASK (GRN_CTX_SEGMENT_SIZE - 1)
-
-#define GRN_CTX_SEGMENT_WORD (1<<31)
-#define GRN_CTX_SEGMENT_VLEN (1<<30)
-#define GRN_CTX_SEGMENT_LIFO (1<<29)
-#define GRN_CTX_SEGMENT_DIRTY (1<<28)
-
-#ifdef USE_DYNAMIC_MALLOC_CHANGE
-static void
-grn_ctx_impl_init_malloc(grn_ctx *ctx)
-{
-# ifdef USE_FAIL_MALLOC
- ctx->impl->malloc_func = grn_malloc_fail;
- ctx->impl->calloc_func = grn_calloc_fail;
- ctx->impl->realloc_func = grn_realloc_fail;
- ctx->impl->strdup_func = grn_strdup_fail;
-# else
- ctx->impl->malloc_func = grn_malloc_default;
- ctx->impl->calloc_func = grn_calloc_default;
- ctx->impl->realloc_func = grn_realloc_default;
- ctx->impl->strdup_func = grn_strdup_default;
-# endif
-}
-#endif
-
static void
grn_loader_init(grn_loader *loader)
{
GRN_TEXT_INIT(&loader->values, 0);
GRN_UINT32_INIT(&loader->level, GRN_OBJ_VECTOR);
GRN_PTR_INIT(&loader->columns, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ GRN_UINT32_INIT(&loader->ids, GRN_OBJ_VECTOR);
+ GRN_INT32_INIT(&loader->return_codes, GRN_OBJ_VECTOR);
+ GRN_TEXT_INIT(&loader->error_messages, GRN_OBJ_VECTOR);
+ loader->id_offset = -1;
loader->key_offset = -1;
loader->table = NULL;
loader->last = NULL;
@@ -483,6 +160,11 @@ grn_loader_init(grn_loader *loader)
loader->values_size = 0;
loader->nrecords = 0;
loader->stat = GRN_LOADER_BEGIN;
+ loader->columns_status = GRN_LOADER_COLUMNS_UNSET;
+ loader->rc = GRN_SUCCESS;
+ loader->errbuf[0] = '\0';
+ loader->output_ids = GRN_FALSE;
+ loader->output_errors = GRN_FALSE;
}
void
@@ -500,6 +182,9 @@ grn_ctx_loader_clear(grn_ctx *ctx)
GRN_OBJ_FIN(ctx, &loader->values);
GRN_OBJ_FIN(ctx, &loader->level);
GRN_OBJ_FIN(ctx, &loader->columns);
+ GRN_OBJ_FIN(ctx, &loader->ids);
+ GRN_OBJ_FIN(ctx, &loader->return_codes);
+ GRN_OBJ_FIN(ctx, &loader->error_messages);
grn_loader_init(loader);
}
@@ -510,24 +195,18 @@ static int
grn_msgpack_buffer_write(void *data, const char *buf, msgpack_size_t len)
{
grn_ctx *ctx = (grn_ctx *)data;
- return grn_bulk_write(ctx, ctx->impl->outbuf, buf, len);
+ return grn_bulk_write(ctx, ctx->impl->output.buf, buf, len);
}
#endif
-static void
+static grn_rc
grn_ctx_impl_init(grn_ctx *ctx)
{
grn_io_mapinfo mi;
if (!(ctx->impl = grn_io_anon_map(ctx, &mi, IMPL_SIZE))) {
- ctx->impl = NULL;
- return;
+ return ctx->rc;
}
-#ifdef USE_DYNAMIC_MALLOC_CHANGE
- grn_ctx_impl_init_malloc(ctx);
-#endif
-#ifdef USE_MEMORY_DEBUG
- ctx->impl->alloc_info = NULL;
-#endif
+ grn_alloc_init_ctx_impl(ctx);
ctx->impl->encoding = ctx->encoding;
ctx->impl->lifoseg = -1;
ctx->impl->currseg = -1;
@@ -537,33 +216,48 @@ grn_ctx_impl_init(grn_ctx *ctx)
CRITICAL_SECTION_FIN(ctx->impl->lock);
grn_io_anon_unmap(ctx, &mi, IMPL_SIZE);
ctx->impl = NULL;
- return;
+ return ctx->rc;
+ }
+ if (!(ctx->impl->temporary_columns = grn_pat_create(ctx, NULL,
+ GRN_TABLE_MAX_KEY_SIZE,
+ sizeof(grn_obj *),
+ 0))) {
+ grn_array_close(ctx, ctx->impl->values);
+ CRITICAL_SECTION_FIN(ctx->impl->lock);
+ grn_io_anon_unmap(ctx, &mi, IMPL_SIZE);
+ ctx->impl = NULL;
+ return ctx->rc;
}
if (!(ctx->impl->ios = grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE,
sizeof(grn_io *),
GRN_OBJ_KEY_VAR_SIZE|GRN_HASH_TINY))) {
grn_array_close(ctx, ctx->impl->values);
+ grn_pat_close(ctx, ctx->impl->temporary_columns);
CRITICAL_SECTION_FIN(ctx->impl->lock);
grn_io_anon_unmap(ctx, &mi, IMPL_SIZE);
ctx->impl = NULL;
- return;
+ return ctx->rc;
}
ctx->impl->db = NULL;
ctx->impl->expr_vars = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(grn_obj *), 0);
ctx->impl->stack_curr = 0;
ctx->impl->curr_expr = NULL;
- ctx->impl->qe_next = NULL;
+ GRN_TEXT_INIT(&ctx->impl->current_request_id, 0);
+ ctx->impl->current_request_timer_id = NULL;
ctx->impl->parser = NULL;
- GRN_TEXT_INIT(&ctx->impl->names, GRN_OBJ_VECTOR);
- GRN_UINT32_INIT(&ctx->impl->levels, GRN_OBJ_VECTOR);
+ GRN_TEXT_INIT(&ctx->impl->output.names, GRN_OBJ_VECTOR);
+ GRN_UINT32_INIT(&ctx->impl->output.levels, GRN_OBJ_VECTOR);
+ ctx->impl->command.flags = 0;
if (ctx == &grn_gctx) {
- ctx->impl->command_version = GRN_COMMAND_VERSION_STABLE;
+ ctx->impl->command.version = GRN_COMMAND_VERSION_STABLE;
} else {
- ctx->impl->command_version = grn_get_default_command_version();
+ ctx->impl->command.version = grn_get_default_command_version();
}
+ ctx->impl->command.keep.command = NULL;
+ ctx->impl->command.keep.version = ctx->impl->command.version;
if (ctx == &grn_gctx) {
ctx->impl->match_escalation_threshold =
@@ -576,9 +270,13 @@ grn_ctx_impl_init(grn_ctx *ctx)
ctx->impl->finalizer = NULL;
ctx->impl->com = NULL;
- ctx->impl->outbuf = grn_obj_open(ctx, GRN_BULK, 0, 0);
- ctx->impl->output = NULL;
- ctx->impl->data.ptr = NULL;
+ ctx->impl->output.buf = grn_obj_open(ctx, GRN_BULK, 0, GRN_DB_TEXT);
+ ctx->impl->output.func = NULL;
+ ctx->impl->output.data.ptr = NULL;
+#ifdef GRN_WITH_MESSAGE_PACK
+ msgpack_packer_init(&ctx->impl->output.msgpacker,
+ ctx, grn_msgpack_buffer_write);
+#endif
ctx->impl->tv.tv_sec = 0;
ctx->impl->tv.tv_nsec = 0;
ctx->impl->edge = NULL;
@@ -590,17 +288,19 @@ grn_ctx_impl_init(grn_ctx *ctx)
ctx->impl->previous_errbuf[0] = '\0';
ctx->impl->n_same_error_messages = 0;
-#ifdef GRN_WITH_MESSAGE_PACK
- msgpack_packer_init(&ctx->impl->msgpacker, ctx, grn_msgpack_buffer_write);
-#endif
-
grn_ctx_impl_mrb_init(ctx);
+
+ GRN_TEXT_INIT(&(ctx->impl->temporary_open_spaces.stack), 0);
+ ctx->impl->temporary_open_spaces.current = NULL;
+
+ return ctx->rc;
}
void
-grn_ctx_set_next_expr(grn_ctx *ctx, grn_obj *expr)
+grn_ctx_set_keep_command(grn_ctx *ctx, grn_obj *command)
{
- ctx->impl->qe_next = expr;
+ ctx->impl->command.keep.command = command;
+ ctx->impl->command.keep.version = ctx->impl->command.version;
}
static void
@@ -646,12 +346,12 @@ grn_ctx_init_internal(grn_ctx *ctx, int flags)
{
if (!ctx) { return GRN_INVALID_ARGUMENT; }
// if (ctx->stat != GRN_CTX_FIN) { return GRN_INVALID_ARGUMENT; }
+ ctx->rc = GRN_SUCCESS;
ERRCLR(ctx);
ctx->flags = flags;
if (grn_ctx_per_db) {
ctx->flags |= GRN_CTX_PER_DB;
}
- if (ERRP(ctx, GRN_ERROR)) { return ctx->rc; }
ctx->stat = GRN_CTX_INITED;
ctx->encoding = grn_gctx.encoding;
ctx->seqno = 0;
@@ -670,7 +370,7 @@ grn_ctx_init_internal(grn_ctx *ctx, int flags)
ctx->errfunc = "";
ctx->trace[0] = NULL;
ctx->errbuf[0] = '\0';
- return ctx->rc;
+ return GRN_SUCCESS;
}
grn_rc
@@ -682,6 +382,15 @@ grn_ctx_init(grn_ctx *ctx, int flags)
if (rc == GRN_SUCCESS) {
grn_ctx_impl_init(ctx);
rc = ctx->rc;
+ if (rc != GRN_SUCCESS) {
+ grn_ctx_fin(ctx);
+ if (flags & GRN_CTX_ALLOCATED) {
+ CRITICAL_SECTION_ENTER(grn_glock);
+ ctx->next->prev = ctx->prev;
+ ctx->prev->next = ctx->next;
+ CRITICAL_SECTION_LEAVE(grn_glock);
+ }
+ }
}
return rc;
@@ -694,7 +403,6 @@ grn_ctx_open(int flags)
if (ctx) {
grn_ctx_init(ctx, flags|GRN_CTX_ALLOCATED);
if (ERRP(ctx, GRN_ERROR)) {
- grn_ctx_fin(ctx);
GRN_GFREE(ctx);
ctx = NULL;
}
@@ -719,11 +427,26 @@ grn_ctx_fin(grn_ctx *ctx)
if (ctx->impl->finalizer) {
ctx->impl->finalizer(ctx, 0, NULL, &(ctx->user_data));
}
+ {
+ grn_obj *stack;
+ grn_obj *spaces;
+ unsigned int i, n_spaces;
+
+ stack = &(ctx->impl->temporary_open_spaces.stack);
+ spaces = (grn_obj *)GRN_BULK_HEAD(stack);
+ n_spaces = GRN_BULK_VSIZE(stack) / sizeof(grn_obj);
+ for (i = 0; i < n_spaces; i++) {
+ grn_obj *space = spaces + (n_spaces - i - 1);
+ GRN_OBJ_FIN(ctx, space);
+ }
+ GRN_OBJ_FIN(ctx, stack);
+ }
grn_ctx_impl_mrb_fin(ctx);
grn_ctx_loader_clear(ctx);
if (ctx->impl->parser) {
grn_expr_parser_close(ctx);
}
+ GRN_OBJ_FIN(ctx, &ctx->impl->current_request_id);
if (ctx->impl->values) {
#ifndef USE_MEMORY_DEBUG
grn_db_obj *o;
@@ -733,6 +456,15 @@ grn_ctx_fin(grn_ctx *ctx)
#endif
grn_array_close(ctx, ctx->impl->values);
}
+ if (ctx->impl->temporary_columns) {
+#ifndef USE_MEMORY_DEBUG
+ grn_obj *value;
+ GRN_PAT_EACH(ctx, ctx->impl->temporary_columns, id, NULL, NULL, &value, {
+ grn_obj_close(ctx, *((grn_obj **)value));
+ });
+#endif
+ grn_pat_close(ctx, ctx->impl->temporary_columns);
+ }
if (ctx->impl->ios) {
grn_hash_close(ctx, ctx->impl->ios);
}
@@ -747,10 +479,10 @@ grn_ctx_fin(grn_ctx *ctx)
grn_ctx_send(ctx, "ACK", 3, GRN_CTX_HEAD);
rc = grn_com_close(ctx, ctx->impl->com);
}
- GRN_OBJ_FIN(ctx, &ctx->impl->names);
- GRN_OBJ_FIN(ctx, &ctx->impl->levels);
GRN_OBJ_FIN(ctx, &ctx->impl->query_log_buf);
- rc = grn_obj_close(ctx, ctx->impl->outbuf);
+ GRN_OBJ_FIN(ctx, &ctx->impl->output.names);
+ GRN_OBJ_FIN(ctx, &ctx->impl->output.levels);
+ rc = grn_obj_close(ctx, ctx->impl->output.buf);
{
grn_hash **vp;
grn_obj *value;
@@ -769,20 +501,7 @@ grn_ctx_fin(grn_ctx *ctx)
ctx->impl->db = NULL;
grn_obj_close(ctx, db);
}
- {
- int i;
- grn_io_mapinfo *mi;
- for (i = 0, mi = ctx->impl->segs; i < GRN_CTX_N_SEGMENTS; i++, mi++) {
- if (mi->map) {
- //GRN_LOG(ctx, GRN_LOG_NOTICE, "unmap in ctx_fin(%d,%d,%d)", i, (mi->count & GRN_CTX_SEGMENT_MASK), mi->nref);
- if (mi->count & GRN_CTX_SEGMENT_VLEN) {
- grn_io_anon_unmap(ctx, mi, mi->nref * grn_pagesize);
- } else {
- grn_io_anon_unmap(ctx, mi, GRN_CTX_SEGMENT_SIZE);
- }
- }
- }
- }
+ grn_alloc_fin_ctx_impl(ctx);
grn_alloc_info_dump(ctx);
grn_alloc_info_free(ctx);
CRITICAL_SECTION_FIN(ctx->impl->lock);
@@ -843,15 +562,23 @@ grn_init(void)
grn_rc rc;
grn_ctx *ctx = &grn_gctx;
grn_init_from_env();
+ grn_init_external_libraries();
+ grn_alloc_info_init();
grn_logger_init();
grn_query_logger_init();
CRITICAL_SECTION_INIT(grn_glock);
grn_gtick = 0;
ctx->next = ctx;
ctx->prev = ctx;
- grn_ctx_init_internal(ctx, 0);
+ rc = grn_ctx_init_internal(ctx, 0);
+ if (rc) {
+ goto fail_ctx_init_internal;
+ }
ctx->encoding = grn_encoding_parse(GRN_DEFAULT_ENCODING);
- grn_timeval_now(ctx, &grn_starttime);
+ rc = grn_timeval_now(ctx, &grn_starttime);
+ if (rc) {
+ goto fail_start_time;
+ }
#ifdef WIN32
{
SYSTEM_INFO si;
@@ -861,94 +588,76 @@ grn_init(void)
#else /* WIN32 */
if ((grn_pagesize = sysconf(_SC_PAGESIZE)) == -1) {
SERR("_SC_PAGESIZE");
- return ctx->rc;
+ rc = ctx->rc;
+ goto fail_page_size;
}
#endif /* WIN32 */
if (grn_pagesize & (grn_pagesize - 1)) {
GRN_LOG(ctx, GRN_LOG_CRIT, "pagesize=%x", grn_pagesize);
}
// expand_stack();
-#ifdef USE_FAIL_MALLOC
- {
- char grn_fmalloc_prob_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_FMALLOC_PROB",
- grn_fmalloc_prob_env,
- GRN_ENV_BUFFER_SIZE);
- if (grn_fmalloc_prob_env[0]) {
- char grn_fmalloc_seed_env[GRN_ENV_BUFFER_SIZE];
- grn_fmalloc_prob = strtod(grn_fmalloc_prob_env, 0) * RAND_MAX;
- grn_getenv("GRN_FMALLOC_SEED",
- grn_fmalloc_seed_env,
- GRN_ENV_BUFFER_SIZE);
- if (grn_fmalloc_seed_env[0]) {
- srand((unsigned int)atoi(grn_fmalloc_seed_env));
- } else {
- srand((unsigned int)time(NULL));
- }
- }
- }
- {
- static char grn_fmalloc_func_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_FMALLOC_FUNC",
- grn_fmalloc_func_env,
- GRN_ENV_BUFFER_SIZE);
- if (grn_fmalloc_func_env[0]) {
- grn_fmalloc_func = grn_fmalloc_func_env;
- }
- }
- {
- static char grn_fmalloc_file_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_FMALLOC_FILE",
- grn_fmalloc_file_env,
- GRN_ENV_BUFFER_SIZE);
- if (grn_fmalloc_file_env[0]) {
- grn_fmalloc_file = grn_fmalloc_file_env;
- }
- }
- {
- char grn_fmalloc_line_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_FMALLOC_LINE",
- grn_fmalloc_line_env,
- GRN_ENV_BUFFER_SIZE);
- if (grn_fmalloc_line_env[0]) {
- grn_fmalloc_line = atoi(grn_fmalloc_line_env);
- }
- }
-#endif /* USE_FAIL_MALLOC */
if ((rc = grn_com_init())) {
GRN_LOG(ctx, GRN_LOG_ALERT, "grn_com_init failed (%d)", rc);
- return rc;
+ goto fail_com;
+ }
+ if ((rc = grn_ctx_impl_init(ctx))) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_ctx_impl_init failed (%d)", rc);
+ goto fail_ctx_impl;
}
- grn_ctx_impl_init(ctx);
if ((rc = grn_plugins_init())) {
GRN_LOG(ctx, GRN_LOG_ALERT, "grn_plugins_init failed (%d)", rc);
- return rc;
+ goto fail_plugins;
}
if ((rc = grn_normalizer_init())) {
GRN_LOG(ctx, GRN_LOG_ALERT, "grn_normalizer_init failed (%d)", rc);
- return rc;
+ goto fail_normalizer;
}
if ((rc = grn_tokenizers_init())) {
GRN_LOG(ctx, GRN_LOG_ALERT, "grn_tokenizers_init failed (%d)", rc);
- return rc;
- }
- /*
- if ((rc = grn_index_init())) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "index initialize failed (%d)", rc);
- return rc;
+ goto fail_tokenizer;
}
- */
grn_cache_init();
if (!grn_request_canceler_init()) {
rc = ctx->rc;
- grn_cache_fin();
GRN_LOG(ctx, GRN_LOG_ALERT,
"failed to initialize request canceler (%d)", rc);
- return rc;
+ goto fail_request_canceler;
}
- GRN_LOG(ctx, GRN_LOG_NOTICE, "grn_init");
+ if (!grn_request_timer_init()) {
+ rc = ctx->rc;
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "failed to initialize request timer (%d)", rc);
+ goto fail_request_timer;
+ }
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "grn_init: <%s>", grn_get_version());
check_overcommit_memory(ctx);
return rc;
+
+fail_request_timer:
+ grn_request_canceler_fin();
+fail_request_canceler:
+ grn_cache_fin();
+fail_tokenizer:
+ grn_normalizer_fin();
+fail_normalizer:
+ grn_plugins_fin();
+fail_plugins:
+ grn_ctx_fin(ctx);
+fail_ctx_impl:
+ grn_com_fin();
+fail_com:
+#ifndef WIN32
+fail_page_size:
+#endif /* WIN32 */
+fail_start_time:
+fail_ctx_init_internal:
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "grn_init: <%s>: failed", grn_get_version());
+ grn_query_logger_fin(ctx);
+ grn_logger_fin(ctx);
+ CRITICAL_SECTION_FIN(grn_glock);
+ grn_alloc_info_fin();
+ grn_fin_external_libraries();
+ return rc;
}
grn_encoding
@@ -1014,8 +723,6 @@ grn_set_lock_timeout(int timeout)
return GRN_SUCCESS;
}
-static int alloc_count = 0;
-
grn_rc
grn_fin(void)
{
@@ -1031,6 +738,7 @@ grn_fin(void)
}
}
grn_query_logger_fin(ctx);
+ grn_request_timer_fin();
grn_request_canceler_fin();
grn_cache_fin();
grn_tokenizers_fin();
@@ -1038,9 +746,11 @@ grn_fin(void)
grn_plugins_fin();
grn_ctx_fin(ctx);
grn_com_fin();
- GRN_LOG(ctx, GRN_LOG_NOTICE, "grn_fin (%d)", alloc_count);
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "grn_fin (%d)", grn_alloc_count());
grn_logger_fin(ctx);
CRITICAL_SECTION_FIN(grn_glock);
+ grn_alloc_info_fin();
+ grn_fin_external_libraries();
return GRN_SUCCESS;
}
@@ -1063,8 +773,10 @@ grn_rc
grn_ctx_close(grn_ctx *ctx)
{
grn_rc rc = grn_ctx_fin(ctx);
+ CRITICAL_SECTION_ENTER(grn_glock);
ctx->next->prev = ctx->prev;
ctx->prev->next = ctx->next;
+ CRITICAL_SECTION_LEAVE(grn_glock);
GRN_GFREE(ctx);
return rc;
}
@@ -1073,7 +785,7 @@ grn_command_version
grn_ctx_get_command_version(grn_ctx *ctx)
{
if (ctx->impl) {
- return ctx->impl->command_version;
+ return ctx->impl->command.version;
} else {
return GRN_COMMAND_VERSION_STABLE;
}
@@ -1084,12 +796,12 @@ grn_ctx_set_command_version(grn_ctx *ctx, grn_command_version version)
{
switch (version) {
case GRN_COMMAND_VERSION_DEFAULT :
- ctx->impl->command_version = GRN_COMMAND_VERSION_STABLE;
+ ctx->impl->command.version = GRN_COMMAND_VERSION_STABLE;
return GRN_SUCCESS;
default :
if (GRN_COMMAND_VERSION_MIN <= version &&
version <= GRN_COMMAND_VERSION_MAX) {
- ctx->impl->command_version = version;
+ ctx->impl->command.version = version;
return GRN_SUCCESS;
} else {
return GRN_UNSUPPORTED_COMMAND_VERSION;
@@ -1101,7 +813,7 @@ grn_content_type
grn_ctx_get_output_type(grn_ctx *ctx)
{
if (ctx->impl) {
- return ctx->impl->output_type;
+ return ctx->impl->output.type;
} else {
return GRN_CONTENT_NONE;
}
@@ -1113,25 +825,25 @@ grn_ctx_set_output_type(grn_ctx *ctx, grn_content_type type)
grn_rc rc = GRN_SUCCESS;
if (ctx->impl) {
- ctx->impl->output_type = type;
- switch (ctx->impl->output_type) {
+ ctx->impl->output.type = type;
+ switch (ctx->impl->output.type) {
case GRN_CONTENT_NONE :
- ctx->impl->mime_type = "application/octet-stream";
+ ctx->impl->output.mime_type = "application/octet-stream";
break;
case GRN_CONTENT_TSV :
- ctx->impl->mime_type = "text/tab-separated-values";
+ ctx->impl->output.mime_type = "text/tab-separated-values";
break;
case GRN_CONTENT_JSON :
- ctx->impl->mime_type = "application/json";
+ ctx->impl->output.mime_type = "application/json";
break;
case GRN_CONTENT_XML :
- ctx->impl->mime_type = "text/xml";
+ ctx->impl->output.mime_type = "text/xml";
break;
case GRN_CONTENT_MSGPACK :
- ctx->impl->mime_type = "application/x-msgpack";
+ ctx->impl->output.mime_type = "application/x-msgpack";
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
- ctx->impl->mime_type = "text/x-groonga-command-list";
+ ctx->impl->output.mime_type = "text/x-groonga-command-list";
break;
}
} else {
@@ -1145,7 +857,7 @@ const char *
grn_ctx_get_mime_type(grn_ctx *ctx)
{
if (ctx->impl) {
- return ctx->impl->mime_type;
+ return ctx->impl->output.mime_type;
} else {
return NULL;
}
@@ -1171,7 +883,15 @@ grn_ctx_set_match_escalation_threshold(grn_ctx *ctx, long long int threshold)
grn_content_type
grn_get_ctype(grn_obj *var)
{
- grn_content_type ct = GRN_CONTENT_JSON;
+ return grn_content_type_parse(NULL, var, GRN_CONTENT_JSON);
+}
+
+grn_content_type
+grn_content_type_parse(grn_ctx *ctx,
+ grn_obj *var,
+ grn_content_type default_value)
+{
+ grn_content_type ct = default_value;
if (var->header.domain == GRN_DB_INT32) {
ct = GRN_INT32_VALUE(var);
} else if (GRN_TEXT_LEN(var)) {
@@ -1196,70 +916,70 @@ grn_get_ctype(grn_obj *var)
static void
get_content_mime_type(grn_ctx *ctx, const char *p, const char *pe)
{
- ctx->impl->output_type = GRN_CONTENT_NONE;
- ctx->impl->mime_type = "application/octet-stream";
+ ctx->impl->output.type = GRN_CONTENT_NONE;
+ ctx->impl->output.mime_type = "application/octet-stream";
if (p + 2 <= pe) {
switch (*p) {
case 'c' :
if (p + 3 == pe && !memcmp(p, "css", 3)) {
- ctx->impl->output_type = GRN_CONTENT_NONE;
- ctx->impl->mime_type = "text/css";
+ ctx->impl->output.type = GRN_CONTENT_NONE;
+ ctx->impl->output.mime_type = "text/css";
}
break;
case 'g' :
if (p + 3 == pe && !memcmp(p, "gif", 3)) {
- ctx->impl->output_type = GRN_CONTENT_NONE;
- ctx->impl->mime_type = "image/gif";
+ ctx->impl->output.type = GRN_CONTENT_NONE;
+ ctx->impl->output.mime_type = "image/gif";
}
break;
case 'h' :
if (p + 4 == pe && !memcmp(p, "html", 4)) {
- ctx->impl->output_type = GRN_CONTENT_NONE;
- ctx->impl->mime_type = "text/html";
+ ctx->impl->output.type = GRN_CONTENT_NONE;
+ ctx->impl->output.mime_type = "text/html";
}
break;
case 'j' :
if (!memcmp(p, "js", 2)) {
if (p + 2 == pe) {
- ctx->impl->output_type = GRN_CONTENT_NONE;
- ctx->impl->mime_type = "text/javascript";
+ ctx->impl->output.type = GRN_CONTENT_NONE;
+ ctx->impl->output.mime_type = "text/javascript";
} else if (p + 4 == pe && !memcmp(p + 2, "on", 2)) {
- ctx->impl->output_type = GRN_CONTENT_JSON;
- ctx->impl->mime_type = "application/json";
+ ctx->impl->output.type = GRN_CONTENT_JSON;
+ ctx->impl->output.mime_type = "application/json";
}
} else if (p + 3 == pe && !memcmp(p, "jpg", 3)) {
- ctx->impl->output_type = GRN_CONTENT_NONE;
- ctx->impl->mime_type = "image/jpeg";
+ ctx->impl->output.type = GRN_CONTENT_NONE;
+ ctx->impl->output.mime_type = "image/jpeg";
}
break;
#ifdef GRN_WITH_MESSAGE_PACK
case 'm' :
if (p + 7 == pe && !memcmp(p, "msgpack", 7)) {
- ctx->impl->output_type = GRN_CONTENT_MSGPACK;
- ctx->impl->mime_type = "application/x-msgpack";
+ ctx->impl->output.type = GRN_CONTENT_MSGPACK;
+ ctx->impl->output.mime_type = "application/x-msgpack";
}
break;
#endif
case 'p' :
if (p + 3 == pe && !memcmp(p, "png", 3)) {
- ctx->impl->output_type = GRN_CONTENT_NONE;
- ctx->impl->mime_type = "image/png";
+ ctx->impl->output.type = GRN_CONTENT_NONE;
+ ctx->impl->output.mime_type = "image/png";
}
break;
case 't' :
if (p + 3 == pe && !memcmp(p, "txt", 3)) {
- ctx->impl->output_type = GRN_CONTENT_NONE;
- ctx->impl->mime_type = "text/plain";
+ ctx->impl->output.type = GRN_CONTENT_NONE;
+ ctx->impl->output.mime_type = "text/plain";
} else if (p + 3 == pe && !memcmp(p, "tsv", 3)) {
- ctx->impl->output_type = GRN_CONTENT_TSV;
- ctx->impl->mime_type = "text/tab-separated-values";
+ ctx->impl->output.type = GRN_CONTENT_TSV;
+ ctx->impl->output.mime_type = "text/tab-separated-values";
}
break;
case 'x':
if (p + 3 == pe && !memcmp(p, "xml", 3)) {
- ctx->impl->output_type = GRN_CONTENT_XML;
- ctx->impl->mime_type = "text/xml";
+ ctx->impl->output.type = GRN_CONTENT_XML;
+ ctx->impl->output.mime_type = "text/xml";
}
break;
}
@@ -1309,10 +1029,14 @@ get_command_version(grn_ctx *ctx, const char *p, const char *pe)
#define OUTPUT_TYPE "output_type"
#define COMMAND_VERSION "command_version"
#define REQUEST_ID "request_id"
+#define REQUEST_TIMEOUT "request_timeout"
+#define OUTPUT_PRETTY "output_pretty"
#define EXPR_MISSING "expr_missing"
#define OUTPUT_TYPE_LEN (sizeof(OUTPUT_TYPE) - 1)
#define COMMAND_VERSION_LEN (sizeof(COMMAND_VERSION) - 1)
#define REQUEST_ID_LEN (sizeof(REQUEST_ID) - 1)
+#define REQUEST_TIMEOUT_LEN (sizeof(REQUEST_TIMEOUT) - 1)
+#define OUTPUT_PRETTY_LEN (sizeof(OUTPUT_PRETTY) - 1)
#define HTTP_QUERY_PAIR_DELIMITER "="
#define HTTP_QUERY_PAIRS_DELIMITERS "&;"
@@ -1329,7 +1053,11 @@ grn_ctx_qe_exec_uri(grn_ctx *ctx, const char *path, uint32_t path_len)
{
grn_obj buf, *expr, *val;
grn_obj request_id;
+ double request_timeout;
const char *p = path, *e = path + path_len, *v, *key_end, *filename_end;
+
+ request_timeout = grn_get_default_request_timeout();
+
GRN_TEXT_INIT(&buf, 0);
GRN_TEXT_INIT(&request_id, 0);
p = grn_text_urldec(ctx, &buf, p, e, '?');
@@ -1363,7 +1091,22 @@ grn_ctx_qe_exec_uri(grn_ctx *ctx, const char *path, uint32_t path_len)
GRN_BULK_REWIND(&request_id);
p = grn_text_cgidec(ctx, &request_id, p, e,
HTTP_QUERY_PAIRS_DELIMITERS);
- if (ctx->rc) { goto exit; }
+ } else if (l == REQUEST_TIMEOUT_LEN &&
+ !memcmp(v, REQUEST_TIMEOUT, REQUEST_TIMEOUT_LEN)) {
+ GRN_BULK_REWIND(&buf);
+ p = grn_text_cgidec(ctx, &buf, p, e, HTTP_QUERY_PAIRS_DELIMITERS);
+ GRN_TEXT_PUTC(ctx, &buf, '\0');
+ request_timeout = strtod(GRN_TEXT_VALUE(&buf), NULL);
+ } else if (l == OUTPUT_PRETTY_LEN &&
+ !memcmp(v, OUTPUT_PRETTY, OUTPUT_PRETTY_LEN)) {
+ GRN_BULK_REWIND(&buf);
+ p = grn_text_cgidec(ctx, &buf, p, e, HTTP_QUERY_PAIRS_DELIMITERS);
+ if (GRN_TEXT_LEN(&buf) == strlen("yes") &&
+ !memcmp(GRN_TEXT_VALUE(&buf), "yes", GRN_TEXT_LEN(&buf))) {
+ ctx->impl->output.is_pretty = GRN_TRUE;
+ } else {
+ ctx->impl->output.is_pretty = GRN_FALSE;
+ }
} else {
if (!(val = grn_expr_get_or_add_var(ctx, expr, v, l))) {
val = &buf;
@@ -1372,18 +1115,25 @@ grn_ctx_qe_exec_uri(grn_ctx *ctx, const char *path, uint32_t path_len)
p = grn_text_cgidec(ctx, val, p, e, HTTP_QUERY_PAIRS_DELIMITERS);
}
}
+ if (request_timeout > 0 && GRN_TEXT_LEN(&request_id) == 0) {
+ grn_text_printf(ctx, &request_id, "%p", ctx);
+ }
if (GRN_TEXT_LEN(&request_id) > 0) {
+ GRN_TEXT_SET(ctx, &ctx->impl->current_request_id,
+ GRN_TEXT_VALUE(&request_id),
+ GRN_TEXT_LEN(&request_id));
grn_request_canceler_register(ctx,
GRN_TEXT_VALUE(&request_id),
GRN_TEXT_LEN(&request_id));
+ if (request_timeout > 0.0) {
+ ctx->impl->current_request_timer_id =
+ grn_request_timer_register(GRN_TEXT_VALUE(&request_id),
+ GRN_TEXT_LEN(&request_id),
+ request_timeout);
+ }
}
ctx->impl->curr_expr = expr;
grn_expr_exec(ctx, expr, 0);
- if (GRN_TEXT_LEN(&request_id) > 0) {
- grn_request_canceler_unregister(ctx,
- GRN_TEXT_VALUE(&request_id),
- GRN_TEXT_LEN(&request_id));
- }
} else {
ERR(GRN_INVALID_ARGUMENT, "invalid command name: %.*s",
command_name_size, command_name);
@@ -1398,7 +1148,9 @@ grn_ctx_qe_exec_uri(grn_ctx *ctx, const char *path, uint32_t path_len)
grn_expr_exec(ctx, expr, 0);
}
exit :
+ GRN_OBJ_FIN(ctx, &request_id);
GRN_OBJ_FIN(ctx, &buf);
+
return expr;
}
@@ -1409,7 +1161,11 @@ grn_ctx_qe_exec(grn_ctx *ctx, const char *str, uint32_t str_len)
int offset = 0;
grn_obj buf, *expr = NULL, *val = NULL;
grn_obj request_id;
+ double request_timeout;
const char *p = str, *e = str + str_len, *v;
+
+ request_timeout = grn_get_default_request_timeout();
+
GRN_TEXT_INIT(&buf, 0);
GRN_TEXT_INIT(&request_id, 0);
p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
@@ -1441,7 +1197,22 @@ grn_ctx_qe_exec(grn_ctx *ctx, const char *str, uint32_t str_len)
!memcmp(v, REQUEST_ID, REQUEST_ID_LEN)) {
GRN_BULK_REWIND(&request_id);
p = grn_text_unesc_tok(ctx, &request_id, p, e, &tok_type);
- if (ctx->rc) { goto exit; }
+ } else if (l == REQUEST_TIMEOUT_LEN &&
+ !memcmp(v, REQUEST_TIMEOUT, REQUEST_TIMEOUT_LEN)) {
+ GRN_BULK_REWIND(&buf);
+ p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
+ GRN_TEXT_PUTC(ctx, &buf, '\0');
+ request_timeout = strtod(GRN_TEXT_VALUE(&buf), NULL);
+ } else if (l == OUTPUT_PRETTY_LEN &&
+ !memcmp(v, OUTPUT_PRETTY, OUTPUT_PRETTY_LEN)) {
+ GRN_BULK_REWIND(&buf);
+ p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
+ if (GRN_TEXT_LEN(&buf) == strlen("yes") &&
+ !memcmp(GRN_TEXT_VALUE(&buf), "yes", GRN_TEXT_LEN(&buf))) {
+ ctx->impl->output.is_pretty = GRN_TRUE;
+ } else {
+ ctx->impl->output.is_pretty = GRN_FALSE;
+ }
} else if (expr && (val = grn_expr_get_or_add_var(ctx, expr, v, l))) {
grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
p = grn_text_unesc_tok(ctx, val, p, e, &tok_type);
@@ -1462,10 +1233,22 @@ grn_ctx_qe_exec(grn_ctx *ctx, const char *str, uint32_t str_len)
break;
}
}
+ if (request_timeout > 0 && GRN_TEXT_LEN(&request_id) == 0) {
+ grn_text_printf(ctx, &request_id, "%p", ctx);
+ }
if (GRN_TEXT_LEN(&request_id) > 0) {
+ GRN_TEXT_SET(ctx, &ctx->impl->current_request_id,
+ GRN_TEXT_VALUE(&request_id),
+ GRN_TEXT_LEN(&request_id));
grn_request_canceler_register(ctx,
GRN_TEXT_VALUE(&request_id),
GRN_TEXT_LEN(&request_id));
+ if (request_timeout > 0.0) {
+ ctx->impl->current_request_timer_id =
+ grn_request_timer_register(GRN_TEXT_VALUE(&request_id),
+ GRN_TEXT_LEN(&request_id),
+ request_timeout);
+ }
}
ctx->impl->curr_expr = expr;
if (expr && command_proc_p(expr)) {
@@ -1478,14 +1261,10 @@ grn_ctx_qe_exec(grn_ctx *ctx, const char *str, uint32_t str_len)
(int)GRN_TEXT_LEN(&buf), GRN_TEXT_VALUE(&buf));
}
}
- if (GRN_TEXT_LEN(&request_id) > 0) {
- grn_request_canceler_unregister(ctx,
- GRN_TEXT_VALUE(&request_id),
- GRN_TEXT_LEN(&request_id));
- }
exit :
GRN_OBJ_FIN(ctx, &request_id);
GRN_OBJ_FIN(ctx, &buf);
+
return expr;
}
@@ -1532,12 +1311,14 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags)
if (!ctx) { return 0; }
GRN_API_ENTER;
if (ctx->impl) {
+ if ((flags & GRN_CTX_MORE)) { flags |= GRN_CTX_QUIET; }
+ if (ctx->stat == GRN_CTX_QUIT) { flags |= GRN_CTX_QUIT; }
+
+ ctx->impl->command.flags = flags;
if (ctx->impl->com) {
grn_rc rc;
grn_com_header sheader;
grn_timeval_now(ctx, &ctx->impl->tv);
- if ((flags & GRN_CTX_MORE)) { flags |= GRN_CTX_QUIET; }
- if (ctx->stat == GRN_CTX_QUIT) { flags |= GRN_CTX_QUIT; }
sheader.proto = GRN_COM_PROTO_GQTP;
sheader.qtype = 0;
sheader.keylen = 0;
@@ -1551,11 +1332,15 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags)
}
goto exit;
} else {
+ grn_command_version command_version;
grn_obj *expr = NULL;
- if (ctx->impl->qe_next) {
+
+ command_version = grn_ctx_get_command_version(ctx);
+ if (ctx->impl->command.keep.command) {
grn_obj *val;
- expr = ctx->impl->qe_next;
- ctx->impl->qe_next = NULL;
+ expr = ctx->impl->command.keep.command;
+ ctx->impl->command.keep.command = NULL;
+ grn_ctx_set_command_version(ctx, ctx->impl->command.keep.version);
if ((val = grn_expr_get_var_by_offset(ctx, expr, 0))) {
grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
GRN_TEXT_PUT(ctx, val, str, str_len);
@@ -1563,8 +1348,10 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags)
grn_expr_exec(ctx, expr, 0);
} else {
if (comment_command_p(str, str_len)) { goto output; };
- ctx->impl->mime_type = "application/json";
- ctx->impl->output_type = GRN_CONTENT_JSON;
+ GRN_BULK_REWIND(ctx->impl->output.buf);
+ ctx->impl->output.type = GRN_CONTENT_JSON;
+ ctx->impl->output.mime_type = "application/json";
+ ctx->impl->output.is_pretty = GRN_FALSE;
grn_timeval_now(ctx, &ctx->impl->tv);
GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_COMMAND,
">", "%.*s", str_len, str);
@@ -1575,19 +1362,31 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags)
}
}
if (ctx->stat == GRN_CTX_QUITTING) { ctx->stat = GRN_CTX_QUIT; }
- if (ctx->impl->qe_next) {
+ if (ctx->impl->command.keep.command) {
ERRCLR(ctx);
} else {
+ if (ctx->impl->current_request_timer_id) {
+ void *timer_id = ctx->impl->current_request_timer_id;
+ ctx->impl->current_request_timer_id = NULL;
+ grn_request_timer_unregister(timer_id);
+ }
+ if (GRN_TEXT_LEN(&ctx->impl->current_request_id) > 0) {
+ grn_obj *request_id = &ctx->impl->current_request_id;
+ grn_request_canceler_unregister(ctx,
+ GRN_TEXT_VALUE(request_id),
+ GRN_TEXT_LEN(request_id));
+ GRN_BULK_REWIND(&ctx->impl->current_request_id);
+ }
GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_RESULT_CODE,
"<", "rc=%d", ctx->rc);
}
output :
- if (!ERRP(ctx, GRN_CRIT)) {
- if (!(flags & GRN_CTX_QUIET) && ctx->impl->output) {
- ctx->impl->output(ctx, GRN_CTX_TAIL, ctx->impl->data.ptr);
- }
+ if (!(ctx->impl->command.flags & GRN_CTX_QUIET) &&
+ ctx->impl->output.func) {
+ ctx->impl->output.func(ctx, GRN_CTX_TAIL, ctx->impl->output.data.ptr);
}
if (expr) { grn_expr_clear_vars(ctx, expr); }
+ grn_ctx_set_command_version(ctx, command_version);
goto exit;
}
}
@@ -1600,30 +1399,46 @@ unsigned int
grn_ctx_recv(grn_ctx *ctx, char **str, unsigned int *str_len, int *flags)
{
if (!ctx) { return GRN_INVALID_ARGUMENT; }
+
+ *flags = 0;
+
if (ctx->stat == GRN_CTX_QUIT) {
- *str = NULL;
- *str_len = 0;
- *flags = GRN_CTX_QUIT;
- return 0;
+ grn_bool have_buffer = GRN_FALSE;
+
+ if (ctx->impl &&
+ !ctx->impl->com &&
+ GRN_TEXT_LEN(ctx->impl->output.buf) > 0) {
+ have_buffer = GRN_TRUE;
+ }
+
+ *flags |= GRN_CTX_QUIT;
+ if (!have_buffer) {
+ *str = NULL;
+ *str_len = 0;
+ return 0;
+ }
}
+
GRN_API_ENTER;
if (ctx->impl) {
if (ctx->impl->com) {
grn_com_header header;
- if (grn_com_recv(ctx, ctx->impl->com, &header, ctx->impl->outbuf)) {
+ if (grn_com_recv(ctx, ctx->impl->com, &header, ctx->impl->output.buf)) {
*str = NULL;
*str_len = 0;
*flags = 0;
} else {
- *str = GRN_BULK_HEAD(ctx->impl->outbuf);
- *str_len = GRN_BULK_VSIZE(ctx->impl->outbuf);
+ *str = GRN_BULK_HEAD(ctx->impl->output.buf);
+ *str_len = GRN_BULK_VSIZE(ctx->impl->output.buf);
if (header.flags & GRN_CTX_QUIT) {
ctx->stat = GRN_CTX_QUIT;
- *flags = GRN_CTX_QUIT;
+ *flags |= GRN_CTX_QUIT;
} else {
- *flags = (header.flags & GRN_CTX_TAIL) ? 0 : GRN_CTX_MORE;
+ if (!(header.flags & GRN_CTX_TAIL)) {
+ *flags |= GRN_CTX_MORE;
+ }
}
- ctx->impl->output_type = header.qtype;
+ ctx->impl->output.type = header.qtype;
ctx->rc = (int16_t)ntohs(header.status);
ctx->errbuf[0] = '\0';
ctx->errline = 0;
@@ -1632,11 +1447,11 @@ grn_ctx_recv(grn_ctx *ctx, char **str, unsigned int *str_len, int *flags)
}
goto exit;
} else {
- grn_obj *buf = ctx->impl->outbuf;
+ grn_obj *buf = ctx->impl->output.buf;
unsigned int head = 0, tail = GRN_BULK_VSIZE(buf);
*str = GRN_BULK_HEAD(buf) + head;
*str_len = tail - head;
- GRN_BULK_REWIND(ctx->impl->outbuf);
+ GRN_BULK_REWIND(ctx->impl->output.buf);
goto exit;
}
}
@@ -1649,7 +1464,7 @@ void
grn_ctx_stream_out_func(grn_ctx *ctx, int flags, void *stream)
{
if (ctx && ctx->impl) {
- grn_obj *buf = ctx->impl->outbuf;
+ grn_obj *buf = ctx->impl->output.buf;
uint32_t size = GRN_BULK_VSIZE(buf);
if (size) {
if (fwrite(GRN_BULK_HEAD(buf), 1, size, (FILE *)stream)) {
@@ -1665,8 +1480,8 @@ void
grn_ctx_recv_handler_set(grn_ctx *ctx, void (*func)(grn_ctx *, int, void *), void *func_arg)
{
if (ctx && ctx->impl) {
- ctx->impl->output = func;
- ctx->impl->data.ptr = func_arg;
+ ctx->impl->output.func = func;
+ ctx->impl->output.data.ptr = func_arg;
}
}
@@ -1677,456 +1492,17 @@ grn_ctx_info_get(grn_ctx *ctx, grn_ctx_info *info)
if (ctx->impl->com) {
info->fd = ctx->impl->com->fd;
info->com_status = ctx->impl->com_status;
- info->outbuf = ctx->impl->outbuf;
+ info->outbuf = ctx->impl->output.buf;
info->stat = ctx->stat;
} else {
info->fd = -1;
info->com_status = 0;
- info->outbuf = ctx->impl->outbuf;
+ info->outbuf = ctx->impl->output.buf;
info->stat = ctx->stat;
}
return GRN_SUCCESS;
}
-
-typedef struct _grn_cache_entry grn_cache_entry;
-
-struct _grn_cache {
- grn_cache_entry *next;
- grn_cache_entry *prev;
- grn_hash *hash;
- grn_mutex mutex;
- uint32_t max_nentries;
- uint32_t nfetches;
- uint32_t nhits;
-};
-
-struct _grn_cache_entry {
- grn_cache_entry *next;
- grn_cache_entry *prev;
- grn_obj *value;
- grn_timeval tv;
- grn_id id;
- uint32_t nref;
-};
-
-static grn_cache *grn_cache_current = NULL;
-static grn_cache *grn_cache_default = NULL;
-
-grn_cache *
-grn_cache_open(grn_ctx *ctx)
-{
- grn_cache *cache = NULL;
-
- GRN_API_ENTER;
- cache = GRN_MALLOC(sizeof(grn_cache));
- if (!cache) {
- ERR(GRN_NO_MEMORY_AVAILABLE, "[cache] failed to allocate grn_cache");
- goto exit;
- }
-
- cache->next = (grn_cache_entry *)cache;
- cache->prev = (grn_cache_entry *)cache;
- cache->hash = grn_hash_create(&grn_gctx, NULL, GRN_CACHE_MAX_KEY_SIZE,
- sizeof(grn_cache_entry), GRN_OBJ_KEY_VAR_SIZE);
- MUTEX_INIT(cache->mutex);
- cache->max_nentries = GRN_CACHE_DEFAULT_MAX_N_ENTRIES;
- cache->nfetches = 0;
- cache->nhits = 0;
-
-exit :
- GRN_API_RETURN(cache);
-}
-
-grn_rc
-grn_cache_close(grn_ctx *ctx, grn_cache *cache)
-{
- grn_ctx *ctx_original = ctx;
- grn_cache_entry *vp;
-
- GRN_API_ENTER;
-
- ctx = &grn_gctx;
- GRN_HASH_EACH(ctx, cache->hash, id, NULL, NULL, &vp, {
- grn_obj_close(ctx, vp->value);
- });
- grn_hash_close(ctx, cache->hash);
- MUTEX_FIN(cache->mutex);
- ctx = ctx_original;
- GRN_FREE(cache);
-
- GRN_API_RETURN(ctx->rc);
-}
-
-grn_rc
-grn_cache_current_set(grn_ctx *ctx, grn_cache *cache)
-{
- grn_cache_current = cache;
- return GRN_SUCCESS;
-}
-
-grn_cache *
-grn_cache_current_get(grn_ctx *ctx)
-{
- return grn_cache_current;
-}
-
-void
-grn_cache_init(void)
-{
- grn_cache_default = grn_cache_open(&grn_gctx);
- grn_cache_current_set(&grn_gctx, grn_cache_default);
-}
-
-grn_rc
-grn_cache_set_max_n_entries(grn_ctx *ctx, grn_cache *cache, unsigned int n)
-{
- uint32_t current_max_n_entries;
-
- if (!cache) {
- return GRN_INVALID_ARGUMENT;
- }
-
- current_max_n_entries = cache->max_nentries;
- cache->max_nentries = n;
- if (n < current_max_n_entries) {
- grn_cache_expire(cache, current_max_n_entries - n);
- }
-
- return GRN_SUCCESS;
-}
-
-uint32_t
-grn_cache_get_max_n_entries(grn_ctx *ctx, grn_cache *cache)
-{
- if (!cache) {
- return 0;
- }
- return cache->max_nentries;
-}
-
-void
-grn_cache_get_statistics(grn_ctx *ctx, grn_cache *cache,
- grn_cache_statistics *statistics)
-{
- MUTEX_LOCK(cache->mutex);
- statistics->nentries = GRN_HASH_SIZE(cache->hash);
- statistics->max_nentries = cache->max_nentries;
- statistics->nfetches = cache->nfetches;
- statistics->nhits = cache->nhits;
- MUTEX_UNLOCK(cache->mutex);
-}
-
-static void
-grn_cache_expire_entry(grn_cache *cache, grn_cache_entry *ce)
-{
- if (!ce->nref) {
- ce->prev->next = ce->next;
- ce->next->prev = ce->prev;
- grn_obj_close(&grn_gctx, ce->value);
- grn_hash_delete_by_id(&grn_gctx, cache->hash, ce->id, NULL);
- }
-}
-
-grn_obj *
-grn_cache_fetch(grn_ctx *ctx, grn_cache *cache,
- const char *str, uint32_t str_len)
-{
- grn_cache_entry *ce;
- grn_obj *obj = NULL;
- if (!ctx->impl || !ctx->impl->db) { return obj; }
- MUTEX_LOCK(cache->mutex);
- cache->nfetches++;
- if (grn_hash_get(&grn_gctx, cache->hash, str, str_len, (void **)&ce)) {
- if (ce->tv.tv_sec <= grn_db_lastmod(ctx->impl->db)) {
- grn_cache_expire_entry(cache, ce);
- goto exit;
- }
- ce->nref++;
- obj = ce->value;
- ce->prev->next = ce->next;
- ce->next->prev = ce->prev;
- {
- grn_cache_entry *ce0 = (grn_cache_entry *)cache;
- ce->next = ce0->next;
- ce->prev = ce0;
- ce0->next->prev = ce;
- ce0->next = ce;
- }
- cache->nhits++;
- }
-exit :
- MUTEX_UNLOCK(cache->mutex);
- return obj;
-}
-
-void
-grn_cache_unref(grn_ctx *ctx, grn_cache *cache,
- const char *str, uint32_t str_len)
-{
- grn_cache_entry *ce;
- ctx = &grn_gctx;
- MUTEX_LOCK(cache->mutex);
- if (grn_hash_get(ctx, cache->hash, str, str_len, (void **)&ce)) {
- if (ce->nref) { ce->nref--; }
- }
- MUTEX_UNLOCK(cache->mutex);
-}
-
-void
-grn_cache_update(grn_ctx *ctx, grn_cache *cache,
- const char *str, uint32_t str_len, grn_obj *value)
-{
- grn_id id;
- int added = 0;
- grn_cache_entry *ce;
- grn_rc rc = GRN_SUCCESS;
- grn_obj *old = NULL, *obj;
- if (!ctx->impl || !cache->max_nentries) { return; }
- if (!(obj = grn_obj_open(&grn_gctx, GRN_BULK, 0, GRN_DB_TEXT))) { return; }
- GRN_TEXT_PUT(&grn_gctx, obj, GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
- MUTEX_LOCK(cache->mutex);
- if ((id = grn_hash_add(&grn_gctx, cache->hash, str, str_len, (void **)&ce, &added))) {
- if (!added) {
- if (ce->nref) {
- rc = GRN_RESOURCE_BUSY;
- goto exit;
- }
- old = ce->value;
- ce->prev->next = ce->next;
- ce->next->prev = ce->prev;
- }
- ce->id = id;
- ce->value = obj;
- ce->tv = ctx->impl->tv;
- ce->nref = 0;
- {
- grn_cache_entry *ce0 = (grn_cache_entry *)cache;
- ce->next = ce0->next;
- ce->prev = ce0;
- ce0->next->prev = ce;
- ce0->next = ce;
- }
- if (GRN_HASH_SIZE(cache->hash) > cache->max_nentries) {
- grn_cache_expire_entry(cache, cache->prev);
- }
- } else {
- rc = GRN_NO_MEMORY_AVAILABLE;
- }
-exit :
- MUTEX_UNLOCK(cache->mutex);
- if (rc) { grn_obj_close(&grn_gctx, obj); }
- if (old) { grn_obj_close(&grn_gctx, old); }
-}
-
-void
-grn_cache_expire(grn_cache *cache, int32_t size)
-{
- grn_cache_entry *ce0 = (grn_cache_entry *)cache;
- MUTEX_LOCK(cache->mutex);
- while (ce0 != ce0->prev && size--) {
- grn_cache_expire_entry(cache, ce0->prev);
- }
- MUTEX_UNLOCK(cache->mutex);
-}
-
-void
-grn_cache_fin(void)
-{
- grn_cache_current_set(&grn_gctx, NULL);
- grn_cache_close(&grn_gctx, grn_cache_default);
-}
-
-/**** memory allocation ****/
-
-#define ALIGN_SIZE (1<<3)
-#define ALIGN_MASK (ALIGN_SIZE-1)
-#define GRN_CTX_ALLOC_CLEAR 1
-
-void *
-grn_ctx_alloc(grn_ctx *ctx, size_t size, int flags,
- const char* file, int line, const char *func)
-{
- void *res = NULL;
- if (!ctx) { return res; }
- if (!ctx->impl) {
- if (ERRP(ctx, GRN_ERROR)) { return res; }
- }
- CRITICAL_SECTION_ENTER(ctx->impl->lock);
- {
- int32_t i;
- int32_t *header;
- grn_io_mapinfo *mi;
- size = ((size + ALIGN_MASK) & ~ALIGN_MASK) + ALIGN_SIZE;
- if (size > GRN_CTX_SEGMENT_SIZE) {
- uint64_t npages = (size + (grn_pagesize - 1)) / grn_pagesize;
- if (npages >= (1LL<<32)) {
- MERR("too long request size=%" GRN_FMT_SIZE, size);
- goto exit;
- }
- for (i = 0, mi = ctx->impl->segs;; i++, mi++) {
- if (i >= GRN_CTX_N_SEGMENTS) {
- MERR("all segments are full");
- goto exit;
- }
- if (!mi->map) { break; }
- }
- if (!grn_io_anon_map(ctx, mi, npages * grn_pagesize)) { goto exit; }
- //GRN_LOG(ctx, GRN_LOG_NOTICE, "map i=%d (%d)", i, npages * grn_pagesize);
- mi->nref = (uint32_t) npages;
- mi->count = GRN_CTX_SEGMENT_VLEN;
- ctx->impl->currseg = -1;
- header = mi->map;
- header[0] = i;
- header[1] = (int32_t) size;
- } else {
- i = ctx->impl->currseg;
- mi = &ctx->impl->segs[i];
- if (i < 0 || size + mi->nref > GRN_CTX_SEGMENT_SIZE) {
- for (i = 0, mi = ctx->impl->segs;; i++, mi++) {
- if (i >= GRN_CTX_N_SEGMENTS) {
- MERR("all segments are full");
- goto exit;
- }
- if (!mi->map) { break; }
- }
- if (!grn_io_anon_map(ctx, mi, GRN_CTX_SEGMENT_SIZE)) { goto exit; }
- //GRN_LOG(ctx, GRN_LOG_NOTICE, "map i=%d", i);
- mi->nref = 0;
- mi->count = GRN_CTX_SEGMENT_WORD;
- ctx->impl->currseg = i;
- }
- header = (int32_t *)((byte *)mi->map + mi->nref);
- mi->nref += size;
- mi->count++;
- header[0] = i;
- header[1] = (int32_t) size;
- if ((flags & GRN_CTX_ALLOC_CLEAR) &&
- (mi->count & GRN_CTX_SEGMENT_DIRTY) && (size > ALIGN_SIZE)) {
- memset(&header[2], 0, size - ALIGN_SIZE);
- }
- }
- /*
- {
- char g = (ctx == &grn_gctx) ? 'g' : ' ';
- GRN_LOG(ctx, GRN_LOG_NOTICE, "+%c(%p) %s:%d(%s) (%d:%d)%p mi(%d:%d)", g, ctx, file, line, func, header[0], header[1], &header[2], mi->nref, (mi->count & GRN_CTX_SEGMENT_MASK));
- }
- */
- res = &header[2];
- }
-exit :
- CRITICAL_SECTION_LEAVE(ctx->impl->lock);
- return res;
-}
-
-void *
-grn_ctx_malloc(grn_ctx *ctx, size_t size,
- const char* file, int line, const char *func)
-{
- return grn_ctx_alloc(ctx, size, 0, file, line, func);
-}
-
-void *
-grn_ctx_calloc(grn_ctx *ctx, size_t size,
- const char* file, int line, const char *func)
-{
- return grn_ctx_alloc(ctx, size, GRN_CTX_ALLOC_CLEAR, file, line, func);
-}
-
-void *
-grn_ctx_realloc(grn_ctx *ctx, void *ptr, size_t size,
- const char* file, int line, const char *func)
-{
- void *res = NULL;
- if (size) {
- /* todo : expand if possible */
- res = grn_ctx_alloc(ctx, size, 0, file, line, func);
- if (res && ptr) {
- int32_t *header = &((int32_t *)ptr)[-2];
- size_t size_ = header[1];
- grn_memcpy(res, ptr, size_ > size ? size : size_);
- grn_ctx_free(ctx, ptr, file, line, func);
- }
- } else {
- grn_ctx_free(ctx, ptr, file, line, func);
- }
- return res;
-}
-
-char *
-grn_ctx_strdup(grn_ctx *ctx, const char *s, const char* file, int line, const char *func)
-{
- void *res = NULL;
- if (s) {
- size_t size = strlen(s) + 1;
- if ((res = grn_ctx_alloc(ctx, size, 0, file, line, func))) {
- grn_memcpy(res, s, size);
- }
- }
- return res;
-}
-
-void
-grn_ctx_free(grn_ctx *ctx, void *ptr,
- const char* file, int line, const char *func)
-{
- if (!ctx) { return; }
- if (!ctx->impl) {
- ERR(GRN_INVALID_ARGUMENT,"ctx without impl passed.");
- return;
- }
- CRITICAL_SECTION_ENTER(ctx->impl->lock);
- if (ptr) {
- int32_t *header = &((int32_t *)ptr)[-2];
-
- if (header[0] >= GRN_CTX_N_SEGMENTS) {
- ERR(GRN_INVALID_ARGUMENT,"invalid ptr passed. ptr=%p seg=%d", ptr, *header);
- goto exit;
- }
- /*
- {
- int32_t i = header[0];
- char c = 'X', g = (ctx == &grn_gctx) ? 'g' : ' ';
- grn_io_mapinfo *mi = &ctx->impl->segs[i];
- if (!(mi->count & GRN_CTX_SEGMENT_VLEN) &&
- mi->map <= (void *)header && (char *)header < ((char *)mi->map + GRN_CTX_SEGMENT_SIZE)) { c = '-'; }
- GRN_LOG(ctx, GRN_LOG_NOTICE, "%c%c(%p) %s:%d(%s) (%d:%d)%p mi(%d:%d)", c, g, ctx, file, line, func, header[0], header[1], &header[2], mi->nref, (mi->count & GRN_CTX_SEGMENT_MASK));
- }
- */
- {
- int32_t i = header[0];
- grn_io_mapinfo *mi = &ctx->impl->segs[i];
- if (mi->count & GRN_CTX_SEGMENT_VLEN) {
- if (mi->map != header) {
- ERR(GRN_INVALID_ARGUMENT,"invalid ptr passed.. ptr=%p seg=%d", ptr, i);
- goto exit;
- }
- //GRN_LOG(ctx, GRN_LOG_NOTICE, "umap i=%d (%d)", i, mi->nref * grn_pagesize);
- grn_io_anon_unmap(ctx, mi, mi->nref * grn_pagesize);
- mi->map = NULL;
- } else {
- if (!mi->map) {
- ERR(GRN_INVALID_ARGUMENT,"invalid ptr passed... ptr=%p seg=%d", ptr, i);
- goto exit;
- }
- mi->count--;
- if (!(mi->count & GRN_CTX_SEGMENT_MASK)) {
- //GRN_LOG(ctx, GRN_LOG_NOTICE, "umap i=%d", i);
- if (i == ctx->impl->currseg) {
- mi->count |= GRN_CTX_SEGMENT_DIRTY;
- mi->nref = 0;
- } else {
- grn_io_anon_unmap(ctx, mi, GRN_CTX_SEGMENT_SIZE);
- mi->map = NULL;
- }
- }
- }
- }
- }
-exit :
- CRITICAL_SECTION_LEAVE(ctx->impl->lock);
-}
-
#define DB_P(s) ((s) && (s)->header.type == GRN_DB)
grn_rc
@@ -2150,410 +1526,23 @@ grn_ctx_use(grn_ctx *ctx, grn_obj *db)
GRN_API_RETURN(ctx->rc);
}
-void *
-grn_ctx_alloc_lifo(grn_ctx *ctx, size_t size,
- const char* file, int line, const char *func)
-{
- if (!ctx) { return NULL; }
- if (!ctx->impl) {
- if (ERRP(ctx, GRN_ERROR)) { return NULL; }
- }
- {
- int32_t i = ctx->impl->lifoseg;
- grn_io_mapinfo *mi = &ctx->impl->segs[i];
- if (size > GRN_CTX_SEGMENT_SIZE) {
- uint64_t npages = (size + (grn_pagesize - 1)) / grn_pagesize;
- if (npages >= (1LL<<32)) {
- MERR("too long request size=%" GRN_FMT_SIZE, size);
- return NULL;
- }
- for (;;) {
- if (++i >= GRN_CTX_N_SEGMENTS) {
- MERR("all segments are full");
- return NULL;
- }
- mi++;
- if (!mi->map) { break; }
- }
- if (!grn_io_anon_map(ctx, mi, npages * grn_pagesize)) { return NULL; }
- mi->nref = (uint32_t) npages;
- mi->count = GRN_CTX_SEGMENT_VLEN|GRN_CTX_SEGMENT_LIFO;
- ctx->impl->lifoseg = i;
- return mi->map;
- } else {
- size = (size + ALIGN_MASK) & ~ALIGN_MASK;
- if (i < 0 || (mi->count & GRN_CTX_SEGMENT_VLEN) || size + mi->nref > GRN_CTX_SEGMENT_SIZE) {
- for (;;) {
- if (++i >= GRN_CTX_N_SEGMENTS) {
- MERR("all segments are full");
- return NULL;
- }
- if (!(++mi)->map) { break; }
- }
- if (!grn_io_anon_map(ctx, mi, GRN_CTX_SEGMENT_SIZE)) { return NULL; }
- mi->nref = 0;
- mi->count = GRN_CTX_SEGMENT_WORD|GRN_CTX_SEGMENT_LIFO;
- ctx->impl->lifoseg = i;
- }
- {
- uint32_t u = mi->nref;
- mi->nref += size;
- return (byte *)mi->map + u;
- }
- }
- }
-}
-
-void
-grn_ctx_free_lifo(grn_ctx *ctx, void *ptr,
- const char* file, int line, const char *func)
-{
- if (!ctx) { return; }
- if (!ctx->impl) {
- ERR(GRN_INVALID_ARGUMENT,"ctx without impl passed.");
- return;
- }
- {
- int32_t i = ctx->impl->lifoseg, done = 0;
- grn_io_mapinfo *mi = &ctx->impl->segs[i];
- if (i < 0) {
- ERR(GRN_INVALID_ARGUMENT, "lifo buffer is void");
- return;
- }
- for (; i >= 0; i--, mi--) {
- if (!(mi->count & GRN_CTX_SEGMENT_LIFO)) { continue; }
- if (done) { break; }
- if (mi->count & GRN_CTX_SEGMENT_VLEN) {
- if (mi->map == ptr) { done = 1; }
- grn_io_anon_unmap(ctx, mi, mi->nref * grn_pagesize);
- mi->map = NULL;
- } else {
- if (mi->map == ptr) {
- done = 1;
- } else {
- if (mi->map < ptr && ptr < (void *)((byte*)mi->map + mi->nref)) {
- mi->nref = (uint32_t) ((uintptr_t)ptr - (uintptr_t)mi->map);
- break;
- }
- }
- grn_io_anon_unmap(ctx, mi, GRN_CTX_SEGMENT_SIZE);
- mi->map = NULL;
- }
- }
- ctx->impl->lifoseg = i;
- }
-}
-
-#if USE_DYNAMIC_MALLOC_CHANGE
-grn_malloc_func
-grn_ctx_get_malloc(grn_ctx *ctx)
-{
- if (!ctx || !ctx->impl) { return NULL; }
- return ctx->impl->malloc_func;
-}
-
-void
-grn_ctx_set_malloc(grn_ctx *ctx, grn_malloc_func malloc_func)
-{
- if (!ctx || !ctx->impl) { return; }
- ctx->impl->malloc_func = malloc_func;
-}
-
-grn_calloc_func
-grn_ctx_get_calloc(grn_ctx *ctx)
-{
- if (!ctx || !ctx->impl) { return NULL; }
- return ctx->impl->calloc_func;
-}
-
-void
-grn_ctx_set_calloc(grn_ctx *ctx, grn_calloc_func calloc_func)
-{
- if (!ctx || !ctx->impl) { return; }
- ctx->impl->calloc_func = calloc_func;
-}
-
-grn_realloc_func
-grn_ctx_get_realloc(grn_ctx *ctx)
-{
- if (!ctx || !ctx->impl) { return NULL; }
- return ctx->impl->realloc_func;
-}
-
-void
-grn_ctx_set_realloc(grn_ctx *ctx, grn_realloc_func realloc_func)
-{
- if (!ctx || !ctx->impl) { return; }
- ctx->impl->realloc_func = realloc_func;
-}
-
-grn_strdup_func
-grn_ctx_get_strdup(grn_ctx *ctx)
-{
- if (!ctx || !ctx->impl) { return NULL; }
- return ctx->impl->strdup_func;
-}
-
-void
-grn_ctx_set_strdup(grn_ctx *ctx, grn_strdup_func strdup_func)
-{
- if (!ctx || !ctx->impl) { return; }
- ctx->impl->strdup_func = strdup_func;
-}
-
-grn_free_func
-grn_ctx_get_free(grn_ctx *ctx)
-{
- if (!ctx || !ctx->impl) { return NULL; }
- return ctx->impl->free_func;
-}
-
-void
-grn_ctx_set_free(grn_ctx *ctx, grn_free_func free_func)
-{
- if (!ctx || !ctx->impl) { return; }
- ctx->impl->free_func = free_func;
-}
-
-void *
-grn_malloc(grn_ctx *ctx, size_t size, const char* file, int line, const char *func)
-{
- if (ctx && ctx->impl && ctx->impl->malloc_func) {
- return ctx->impl->malloc_func(ctx, size, file, line, func);
- } else {
- return grn_malloc_default(ctx, size, file, line, func);
- }
-}
-
-void *
-grn_calloc(grn_ctx *ctx, size_t size, const char* file, int line, const char *func)
-{
- if (ctx && ctx->impl && ctx->impl->calloc_func) {
- return ctx->impl->calloc_func(ctx, size, file, line, func);
- } else {
- return grn_calloc_default(ctx, size, file, line, func);
- }
-}
-
-void *
-grn_realloc(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func)
-{
- if (ctx && ctx->impl && ctx->impl->realloc_func) {
- return ctx->impl->realloc_func(ctx, ptr, size, file, line, func);
- } else {
- return grn_realloc_default(ctx, ptr, size, file, line, func);
- }
-}
-
-char *
-grn_strdup(grn_ctx *ctx, const char *string, const char* file, int line, const char *func)
-{
- if (ctx && ctx->impl && ctx->impl->strdup_func) {
- return ctx->impl->strdup_func(ctx, string, file, line, func);
- } else {
- return grn_strdup_default(ctx, string, file, line, func);
- }
-}
-
-void
-grn_free(grn_ctx *ctx, void *ptr, const char* file, int line, const char *func)
-{
- if (ctx && ctx->impl && ctx->impl->free_func) {
- return ctx->impl->free_func(ctx, ptr, file, line, func);
- } else {
- return grn_free_default(ctx, ptr, file, line, func);
- }
-}
-#endif
-
-void *
-grn_malloc_default(grn_ctx *ctx, size_t size, const char* file, int line, const char *func)
-{
- if (!ctx) { return NULL; }
- {
- void *res = malloc(size);
- if (res) {
- GRN_ADD_ALLOC_COUNT(1);
- grn_alloc_info_add(res, file, line, func);
- } else {
- if (!(res = malloc(size))) {
- MERR("malloc fail (%" GRN_FMT_SIZE ")=%p (%s:%d) <%d>",
- size, res, file, line, alloc_count);
- } else {
- GRN_ADD_ALLOC_COUNT(1);
- grn_alloc_info_add(res, file, line, func);
- }
- }
- return res;
- }
-}
-
-void *
-grn_calloc_default(grn_ctx *ctx, size_t size, const char* file, int line, const char *func)
-{
- if (!ctx) { return NULL; }
- {
- void *res = calloc(size, 1);
- if (res) {
- GRN_ADD_ALLOC_COUNT(1);
- grn_alloc_info_add(res, file, line, func);
- } else {
- if (!(res = calloc(size, 1))) {
- MERR("calloc fail (%" GRN_FMT_SIZE ")=%p (%s:%d) <%d>",
- size, res, file, line, alloc_count);
- } else {
- GRN_ADD_ALLOC_COUNT(1);
- grn_alloc_info_add(res, file, line, func);
- }
- }
- return res;
- }
-}
+/* don't handle error inside logger functions */
void
-grn_free_default(grn_ctx *ctx, void *ptr, const char* file, int line, const char *func)
-{
- if (!ctx) { return; }
- grn_alloc_info_check(ptr);
- {
- free(ptr);
- if (ptr) {
- GRN_ADD_ALLOC_COUNT(-1);
- } else {
- GRN_LOG(ctx, GRN_LOG_ALERT, "free fail (%p) (%s:%d) <%d>", ptr, file, line, alloc_count);
- }
- }
-}
-
-void *
-grn_realloc_default(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func)
-{
- void *res;
- if (!ctx) { return NULL; }
- if (size) {
- if (!(res = realloc(ptr, size))) {
- if (!(res = realloc(ptr, size))) {
- MERR("realloc fail (%p,%" GRN_FMT_SIZE ")=%p (%s:%d) <%d>",
- ptr, size, res, file, line, alloc_count);
- return NULL;
- }
- }
- if (ptr) {
- grn_alloc_info_change(ptr, res);
- } else {
- GRN_ADD_ALLOC_COUNT(1);
- grn_alloc_info_add(res, file, line, func);
- }
- } else {
- if (!ptr) { return NULL; }
- grn_alloc_info_check(ptr);
- GRN_ADD_ALLOC_COUNT(-1);
- free(ptr);
- res = NULL;
- }
- return res;
-}
-
-int
-grn_alloc_count(void)
-{
- return alloc_count;
-}
-
-char *
-grn_strdup_default(grn_ctx *ctx, const char *s, const char* file, int line, const char *func)
-{
- if (!ctx) { return NULL; }
- {
- char *res = grn_strdup_raw(s);
- if (res) {
- GRN_ADD_ALLOC_COUNT(1);
- grn_alloc_info_add(res, file, line, func);
- } else {
- if (!(res = grn_strdup_raw(s))) {
- MERR("strdup(%p)=%p (%s:%d) <%d>", s, res, file, line, alloc_count);
- } else {
- GRN_ADD_ALLOC_COUNT(1);
- grn_alloc_info_add(res, file, line, func);
- }
- }
- return res;
- }
-}
-
-#ifdef USE_FAIL_MALLOC
-int
-grn_fail_malloc_check(size_t size, const char *file, int line, const char *func)
-{
- if ((grn_fmalloc_file && strcmp(file, grn_fmalloc_file)) ||
- (grn_fmalloc_line && line != grn_fmalloc_line) ||
- (grn_fmalloc_func && strcmp(func, grn_fmalloc_func))) {
- return 1;
- }
- if (grn_fmalloc_prob && grn_fmalloc_prob >= rand()) {
- return 0;
- }
- return 1;
-}
-
-void *
-grn_malloc_fail(grn_ctx *ctx, size_t size, const char* file, int line, const char *func)
-{
- if (grn_fail_malloc_check(size, file, line, func)) {
- return grn_malloc_default(ctx, size, file, line, func);
- } else {
- MERR("fail_malloc (%" GRN_FMT_SIZE ") (%s:%d@%s) <%d>",
- size, file, line, func, alloc_count);
- return NULL;
- }
-}
-
-void *
-grn_calloc_fail(grn_ctx *ctx, size_t size, const char* file, int line, const char *func)
-{
- if (grn_fail_malloc_check(size, file, line, func)) {
- return grn_calloc_default(ctx, size, file, line, func);
- } else {
- MERR("fail_calloc (%" GRN_FMT_SIZE ") (%s:%d@%s) <%d>",
- size, file, line, func, alloc_count);
- return NULL;
- }
-}
-
-void *
-grn_realloc_fail(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line,
- const char *func)
-{
- if (grn_fail_malloc_check(size, file, line, func)) {
- return grn_realloc_default(ctx, ptr, size, file, line, func);
- } else {
- MERR("fail_realloc (%p,%" GRN_FMT_SIZE ") (%s:%d@%s) <%d>",
- ptr, size, file, line, func, alloc_count);
- return NULL;
- }
-}
-
-char *
-grn_strdup_fail(grn_ctx *ctx, const char *s, const char* file, int line, const char *func)
+grn_ctx_log(grn_ctx *ctx, const char *fmt, ...)
{
- if (grn_fail_malloc_check(strlen(s), file, line, func)) {
- return grn_strdup_default(ctx, s, file, line, func);
- } else {
- MERR("fail_strdup(%p) (%s:%d@%s) <%d>", s, file, line, func, alloc_count);
- return NULL;
- }
+ va_list ap;
+ va_start(ap, fmt);
+ grn_ctx_logv(ctx, fmt, ap);
+ va_end(ap);
}
-#endif /* USE_FAIL_MALLOC */
-
-/* don't handle error inside logger functions */
void
-grn_ctx_log(grn_ctx *ctx, const char *fmt, ...)
+grn_ctx_logv(grn_ctx *ctx, const char *fmt, va_list ap)
{
- va_list argp;
- va_start(argp, fmt);
- vsnprintf(ctx->errbuf, GRN_CTX_MSGSIZE, fmt, argp);
- va_end(argp);
+ char buffer[GRN_CTX_MSGSIZE];
+ grn_vsnprintf(buffer, GRN_CTX_MSGSIZE, fmt, ap);
+ grn_strcpy(ctx->errbuf, GRN_CTX_MSGSIZE, buffer);
}
void
@@ -2576,6 +1565,12 @@ grn_get_package(void)
return PACKAGE;
}
+const char *
+grn_get_package_label(void)
+{
+ return PACKAGE_LABEL;
+}
+
#if defined(HAVE_SIGNAL_H) && !defined(WIN32)
static int segv_received = 0;
static void
@@ -2697,89 +1692,171 @@ grn_ctx_output_flush(grn_ctx *ctx, int flags)
if (flags & GRN_CTX_QUIET) {
return;
}
- if (!ctx->impl->output) {
+ if (!ctx->impl->output.func) {
return;
}
- ctx->impl->output(ctx, 0, ctx->impl->data.ptr);
+ ctx->impl->output.func(ctx, 0, ctx->impl->output.data.ptr);
}
void
grn_ctx_output_array_open(grn_ctx *ctx, const char *name, int nelements)
{
- grn_output_array_open(ctx, ctx->impl->outbuf, ctx->impl->output_type,
+ grn_output_array_open(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
name, nelements);
}
void
grn_ctx_output_array_close(grn_ctx *ctx)
{
- grn_output_array_close(ctx, ctx->impl->outbuf, ctx->impl->output_type);
+ grn_output_array_close(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type);
}
void
grn_ctx_output_map_open(grn_ctx *ctx, const char *name, int nelements)
{
- grn_output_map_open(ctx, ctx->impl->outbuf, ctx->impl->output_type,
+ grn_output_map_open(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
name, nelements);
}
void
grn_ctx_output_map_close(grn_ctx *ctx)
{
- grn_output_map_close(ctx, ctx->impl->outbuf, ctx->impl->output_type);
+ grn_output_map_close(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type);
+}
+
+void
+grn_ctx_output_null(grn_ctx *ctx)
+{
+ grn_output_null(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type);
}
void
grn_ctx_output_int32(grn_ctx *ctx, int value)
{
- grn_output_int32(ctx, ctx->impl->outbuf, ctx->impl->output_type, value);
+ grn_output_int32(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
+ value);
}
void
-grn_ctx_output_int64(grn_ctx *ctx, long long int value)
+grn_ctx_output_int64(grn_ctx *ctx, int64_t value)
{
- grn_output_int64(ctx, ctx->impl->outbuf, ctx->impl->output_type, value);
+ grn_output_int64(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
+ value);
+}
+
+void
+grn_ctx_output_uint64(grn_ctx *ctx, uint64_t value)
+{
+ grn_output_uint64(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
+ value);
}
void
grn_ctx_output_float(grn_ctx *ctx, double value)
{
- grn_output_float(ctx, ctx->impl->outbuf, ctx->impl->output_type, value);
+ grn_output_float(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
+ value);
}
void
grn_ctx_output_cstr(grn_ctx *ctx, const char *value)
{
- grn_output_cstr(ctx, ctx->impl->outbuf, ctx->impl->output_type, value);
+ grn_output_cstr(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
+ value);
}
void
grn_ctx_output_str(grn_ctx *ctx, const char *value, unsigned int value_len)
{
- grn_output_str(ctx, ctx->impl->outbuf, ctx->impl->output_type,
+ grn_output_str(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
value, value_len);
}
void
grn_ctx_output_bool(grn_ctx *ctx, grn_bool value)
{
- grn_output_bool(ctx, ctx->impl->outbuf, ctx->impl->output_type, value);
+ grn_output_bool(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
+ value);
}
void
grn_ctx_output_obj(grn_ctx *ctx, grn_obj *value, grn_obj_format *format)
{
- grn_output_obj(ctx, ctx->impl->outbuf, ctx->impl->output_type,
+ grn_output_obj(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
value, format);
}
void
+grn_ctx_output_result_set_open(grn_ctx *ctx,
+ grn_obj *result_set,
+ grn_obj_format *format,
+ uint32_t n_additional_elements)
+{
+ grn_output_result_set_open(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
+ result_set,
+ format,
+ n_additional_elements);
+}
+
+void
+grn_ctx_output_result_set_close(grn_ctx *ctx,
+ grn_obj *result_set,
+ grn_obj_format *format)
+{
+ grn_output_result_set_close(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
+ result_set,
+ format);
+}
+
+void
+grn_ctx_output_result_set(grn_ctx *ctx,
+ grn_obj *result_set,
+ grn_obj_format *format)
+{
+ grn_output_result_set(ctx,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
+ result_set,
+ format);
+}
+
+void
grn_ctx_output_table_columns(grn_ctx *ctx, grn_obj *table,
grn_obj_format *format)
{
grn_output_table_columns(ctx,
- ctx->impl->outbuf,
- ctx->impl->output_type,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
table,
format);
}
@@ -2789,8 +1866,8 @@ grn_ctx_output_table_records(grn_ctx *ctx, grn_obj *table,
grn_obj_format *format)
{
grn_output_table_records(ctx,
- ctx->impl->outbuf,
- ctx->impl->output_type,
+ ctx->impl->output.buf,
+ ctx->impl->output.type,
table,
format);
}
diff --git a/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c b/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c
index 39a1aa17b86..fdb25108d88 100644
--- a/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c
+++ b/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2015 Brazil
+ Copyright(C) 2013-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -28,13 +28,18 @@
# include "mrb/mrb_error.h"
# include "mrb/mrb_id.h"
# include "mrb/mrb_operator.h"
+# include "mrb/mrb_command_version.h"
# include "mrb/mrb_ctx.h"
# include "mrb/mrb_logger.h"
+# include "mrb/mrb_query_logger.h"
# include "mrb/mrb_void.h"
# include "mrb/mrb_bulk.h"
+# include "mrb/mrb_pointer.h"
+# include "mrb/mrb_cache.h"
# include "mrb/mrb_object.h"
# include "mrb/mrb_object_flags.h"
# include "mrb/mrb_database.h"
+# include "mrb/mrb_indexable.h"
# include "mrb/mrb_table.h"
# include "mrb/mrb_array.h"
# include "mrb/mrb_hash_table.h"
@@ -44,6 +49,7 @@
# include "mrb/mrb_table_group_result.h"
# include "mrb/mrb_table_sort_flags.h"
# include "mrb/mrb_table_sort_key.h"
+# include "mrb/mrb_record.h"
# include "mrb/mrb_column.h"
# include "mrb/mrb_fixed_size_column.h"
# include "mrb/mrb_variable_size_column.h"
@@ -59,8 +65,13 @@
# include "mrb/mrb_table_cursor_flags.h"
# include "mrb/mrb_content_type.h"
# include "mrb/mrb_writer.h"
+# include "mrb/mrb_config.h"
+# include "mrb/mrb_eval_context.h"
+# include "mrb/mrb_thread.h"
+# include "mrb/mrb_window_definition.h"
# include <mruby/array.h>
+# include <mruby/string.h>
# include <mruby/variable.h>
#endif /* GRN_WITH_MRUBY */
@@ -100,13 +111,12 @@ mrb_kernel_load(mrb_state *mrb, mrb_value self)
return mrb_true_value();
}
-static void
-grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx)
+static mrb_value
+mrb_groonga_init(mrb_state *mrb, mrb_value self)
{
- mrb_state *mrb = ctx->impl->mrb.state;
+ grn_ctx *ctx = mrb->ud;
- mrb->ud = ctx;
- ctx->impl->mrb.module = mrb_define_module(mrb, "Groonga");
+ mrb_undef_class_method(mrb, ctx->impl->mrb.module, "init");
mrb_define_class(mrb, "LoadError", mrb_class_get(mrb, "ScriptError"));
mrb_define_method(mrb, mrb->kernel_module,
@@ -134,13 +144,18 @@ grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx)
grn_mrb_error_init(ctx);
grn_mrb_id_init(ctx);
grn_mrb_operator_init(ctx);
+ grn_mrb_command_version_init(ctx);
grn_mrb_ctx_init(ctx);
grn_mrb_logger_init(ctx);
+ grn_mrb_query_logger_init(ctx);
grn_mrb_void_init(ctx);
grn_mrb_bulk_init(ctx);
+ grn_mrb_pointer_init(ctx);
+ grn_mrb_cache_init(ctx);
grn_mrb_object_init(ctx);
grn_mrb_object_flags_init(ctx);
grn_mrb_database_init(ctx);
+ grn_mrb_indexable_init(ctx);
grn_mrb_table_init(ctx);
grn_mrb_array_init(ctx);
grn_mrb_hash_table_init(ctx);
@@ -150,6 +165,7 @@ grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx)
grn_mrb_table_group_result_init(ctx);
grn_mrb_table_sort_flags_init(ctx);
grn_mrb_table_sort_key_init(ctx);
+ grn_mrb_record_init(ctx);
grn_mrb_column_init(ctx);
grn_mrb_fixed_size_column_init(ctx);
grn_mrb_variable_size_column_init(ctx);
@@ -165,12 +181,57 @@ grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx)
grn_mrb_table_cursor_flags_init(ctx);
grn_mrb_content_type_init(ctx);
grn_mrb_writer_init(ctx);
+ grn_mrb_config_init(ctx);
+ grn_mrb_eval_context_init(ctx);
+ grn_mrb_thread_init(ctx);
+ grn_mrb_window_definition_init(ctx);
grn_mrb_load(ctx, "initialize/post.rb");
+
+ return mrb_nil_value();
}
-void
-grn_ctx_impl_mrb_init(grn_ctx *ctx)
+static void
+grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx)
+{
+ mrb_state *mrb = ctx->impl->mrb.state;
+
+ mrb->ud = ctx;
+ ctx->impl->mrb.module = mrb_define_module(mrb, "Groonga");
+ mrb_define_const(mrb,
+ ctx->impl->mrb.module,
+ "ORDER_BY_ESTIMATED_SIZE",
+ grn_mrb_is_order_by_estimated_size_enabled() ?
+ mrb_true_value() :
+ mrb_false_value());
+ mrb_define_class_method(mrb, ctx->impl->mrb.module,
+ "init", mrb_groonga_init, MRB_ARGS_NONE());
+ mrb_funcall(mrb, mrb_obj_value(ctx->impl->mrb.module), "init", 0);
+}
+
+#ifndef USE_MEMORY_DEBUG
+static void *
+grn_ctx_impl_mrb_allocf(mrb_state *mrb, void *ptr, size_t size, void *ud)
+{
+ grn_ctx *ctx = ud;
+
+ if (size == 0) {
+ if (ptr) {
+ grn_free(ctx, ptr, __FILE__, __LINE__, __FUNCTION__);
+ }
+ return NULL;
+ } else {
+ if (ptr) {
+ return grn_realloc(ctx, ptr, size, __FILE__, __LINE__, __FUNCTION__);
+ } else {
+ return grn_malloc(ctx, size, __FILE__, __LINE__, __FUNCTION__);
+ }
+ }
+}
+#endif /* USE_MEMORY_DEBUG */
+
+static void
+grn_ctx_impl_mrb_init_lazy(grn_ctx *ctx)
{
if (!grn_ctx_impl_mrb_mruby_enabled) {
ctx->impl->mrb.state = NULL;
@@ -183,26 +244,37 @@ grn_ctx_impl_mrb_init(grn_ctx *ctx)
ctx->impl->mrb.groonga.operator_class = NULL;
} else {
mrb_state *mrb;
+#ifdef USE_MEMORY_DEBUG
mrb = mrb_open();
+#else /* USE_MEMORY_DEBUG */
+ mrb = mrb_open_allocf(grn_ctx_impl_mrb_allocf, ctx);
+#endif /* USE_MEMORY_DEBUG */
ctx->impl->mrb.state = mrb;
ctx->impl->mrb.base_directory[0] = '\0';
grn_ctx_impl_mrb_init_bindings(ctx);
- /* TODO: Implement better error handling on init. */
if (ctx->impl->mrb.state->exc) {
- mrb_print_error(mrb);
+ mrb_value reason;
+ reason = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
+ ERR(GRN_UNKNOWN_ERROR,
+ "failed to initialize mruby: %.*s",
+ (int)RSTRING_LEN(reason),
+ RSTRING_PTR(reason));
+ mrb_close(ctx->impl->mrb.state);
+ ctx->impl->mrb.state = NULL;
+ } else {
+ ctx->impl->mrb.checked_procs =
+ grn_hash_create(ctx, NULL, sizeof(grn_id), 0, GRN_HASH_TINY);
+ ctx->impl->mrb.registered_plugins =
+ grn_hash_create(ctx, NULL, sizeof(grn_id), 0, GRN_HASH_TINY);
+ GRN_VOID_INIT(&(ctx->impl->mrb.buffer.from));
+ GRN_VOID_INIT(&(ctx->impl->mrb.buffer.to));
+ ctx->impl->mrb.builtin.time_class = mrb_class_get(mrb, "Time");
}
- ctx->impl->mrb.checked_procs =
- grn_hash_create(ctx, NULL, sizeof(grn_id), 0, GRN_HASH_TINY);
- ctx->impl->mrb.registered_plugins =
- grn_hash_create(ctx, NULL, sizeof(grn_id), 0, GRN_HASH_TINY);
- GRN_VOID_INIT(&(ctx->impl->mrb.buffer.from));
- GRN_VOID_INIT(&(ctx->impl->mrb.buffer.to));
- ctx->impl->mrb.builtin.time_class = mrb_class_get(mrb, "Time");
}
}
-void
-grn_ctx_impl_mrb_fin(grn_ctx *ctx)
+static void
+grn_ctx_impl_mrb_fin_real(grn_ctx *ctx)
{
if (ctx->impl->mrb.state) {
mrb_close(ctx->impl->mrb.state);
@@ -214,13 +286,39 @@ grn_ctx_impl_mrb_fin(grn_ctx *ctx)
}
}
#else /* GRN_WITH_MRUBY */
+static void
+grn_ctx_impl_mrb_init_lazy(grn_ctx *ctx)
+{
+}
+
+static void
+grn_ctx_impl_mrb_fin_real(grn_ctx *ctx)
+{
+}
+#endif /* GRN_WITH_MRUBY */
+
void
grn_ctx_impl_mrb_init(grn_ctx *ctx)
{
+ ctx->impl->mrb.initialized = GRN_FALSE;
}
void
grn_ctx_impl_mrb_fin(grn_ctx *ctx)
{
+ if (!ctx->impl->mrb.initialized) {
+ return;
+ }
+
+ ctx->impl->mrb.initialized = GRN_FALSE;
+ grn_ctx_impl_mrb_fin_real(ctx);
+}
+
+void
+grn_ctx_impl_mrb_ensure_init(grn_ctx *ctx)
+{
+ if (!ctx->impl->mrb.initialized) {
+ ctx->impl->mrb.initialized = GRN_TRUE;
+ grn_ctx_impl_mrb_init_lazy(ctx);
+ }
}
-#endif /* GRN_WITH_MRUBY */
diff --git a/storage/mroonga/vendor/groonga/lib/dat.cpp b/storage/mroonga/vendor/groonga/lib/dat.cpp
index 51a84da2af9..51f625f0b3f 100644
--- a/storage/mroonga/vendor/groonga/lib/dat.cpp
+++ b/storage/mroonga/vendor/groonga/lib/dat.cpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011-2015 Brazil
+/*
+ Copyright(C) 2011-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -70,7 +71,22 @@ bool
grn_dat_remove_file(grn_ctx *ctx, const char *path)
{
struct stat stat;
- return !::stat(path, &stat) && !grn_unlink(path);
+
+ if (::stat(path, &stat) == -1) {
+ return false;
+ }
+
+ if (grn_unlink(path) == -1) {
+ const char *system_message = grn_strerror(errno);
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "[dat][remove-file] failed to remove path: %s: <%s>",
+ system_message, path);
+ return false;
+ }
+
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[dat][remove-file] removed: <%s>", path);
+ return true;
}
grn_rc
@@ -115,6 +131,7 @@ grn_dat_init(grn_ctx *, grn_dat *dat)
dat->normalizer = NULL;
GRN_PTR_INIT(&(dat->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
CRITICAL_SECTION_INIT(dat->lock);
+ dat->is_dirty = GRN_FALSE;
}
void
@@ -126,6 +143,10 @@ grn_dat_fin(grn_ctx *ctx, grn_dat *dat)
dat->old_trie = NULL;
dat->trie = NULL;
if (dat->io) {
+ if (dat->is_dirty) {
+ uint32_t n_dirty_opens;
+ GRN_ATOMIC_ADD_EX(&(dat->header->n_dirty_opens), -1, n_dirty_opens);
+ }
grn_io_close(ctx, dat->io);
dat->io = NULL;
}
@@ -188,13 +209,26 @@ grn_dat_open_trie_if_needed(grn_ctx *ctx, grn_dat *dat)
return false;
}
- try {
- new_trie->open(trie_path);
- } catch (const grn::dat::Exception &ex) {
- ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::open failed");
- delete new_trie;
- return false;
+ if (trie_path[0] == '\0') {
+ try {
+ new_trie->create(trie_path);
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::Trie::create failed: %s",
+ ex.what());
+ delete new_trie;
+ return false;
+ }
+ } else {
+ try {
+ new_trie->open(trie_path);
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::Trie::open failed: %s",
+ ex.what());
+ delete new_trie;
+ return false;
+ }
}
dat->old_trie = trie;
@@ -212,6 +246,7 @@ grn_dat_open_trie_if_needed(grn_ctx *ctx, grn_dat *dat)
}
bool grn_dat_rebuild_trie(grn_ctx *ctx, grn_dat *dat) {
+ const grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
grn::dat::Trie * const new_trie = new (std::nothrow) grn::dat::Trie;
if (!new_trie) {
MERR("new grn::dat::Trie failed");
@@ -219,16 +254,22 @@ bool grn_dat_rebuild_trie(grn_ctx *ctx, grn_dat *dat) {
}
const uint32_t file_id = dat->header->file_id;
- try {
- char trie_path[PATH_MAX];
- grn_dat_generate_trie_path(grn_io_path(dat->io), trie_path, file_id + 1);
- const grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
- new_trie->create(*trie, trie_path, trie->file_size() * 2);
- } catch (const grn::dat::Exception &ex) {
- ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::open failed");
- delete new_trie;
- return false;
+ char trie_path[PATH_MAX];
+ grn_dat_generate_trie_path(grn_io_path(dat->io), trie_path, file_id + 1);
+
+ for (uint64_t file_size = trie->file_size() * 2;; file_size *= 2) {
+ try {
+ new_trie->create(*trie, trie_path, file_size);
+ } catch (const grn::dat::SizeError &) {
+ continue;
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::Trie::open failed: %s",
+ ex.what());
+ delete new_trie;
+ return false;
+ }
+ break;
}
grn::dat::Trie * const old_trie = static_cast<grn::dat::Trie *>(dat->old_trie);
@@ -278,7 +319,7 @@ grn_dat_create(grn_ctx *ctx, const char *path, uint32_t,
}
}
- grn_dat * const dat = static_cast<grn_dat *>(GRN_MALLOC(sizeof(grn_dat)));
+ grn_dat * const dat = static_cast<grn_dat *>(GRN_CALLOC(sizeof(grn_dat)));
if (!dat) {
return NULL;
}
@@ -426,7 +467,8 @@ grn_dat_get(grn_ctx *ctx, grn_dat *dat, const void *key,
}
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::search failed");
+ "grn::dat::Trie::search failed: %s",
+ ex.what());
}
return GRN_ID_NIL;
}
@@ -453,7 +495,8 @@ grn_dat_add(grn_ctx *ctx, grn_dat *dat, const void *key,
new_trie->create(trie_path);
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::create failed");
+ "grn::dat::Trie::create failed: %s",
+ ex.what());
delete new_trie;
return GRN_ID_NIL;
}
@@ -482,7 +525,8 @@ grn_dat_add(grn_ctx *ctx, grn_dat *dat, const void *key,
return new_trie->get_key(key_pos).id();
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::insert failed");
+ "grn::dat::Trie::insert failed: %s",
+ ex.what());
return GRN_ID_NIL;
}
}
@@ -556,7 +600,8 @@ grn_dat_delete_by_id(grn_ctx *ctx, grn_dat *dat, grn_id id,
}
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::remove failed");
+ "grn::dat::Trie::remove failed: %s",
+ ex.what());
return ctx->rc;
}
return GRN_SUCCESS;
@@ -584,7 +629,8 @@ grn_dat_delete(grn_ctx *ctx, grn_dat *dat, const void *key, unsigned int key_siz
}
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::search failed");
+ "grn::dat::Trie::search failed: %s",
+ ex.what());
return ctx->rc;
}
}
@@ -596,7 +642,8 @@ grn_dat_delete(grn_ctx *ctx, grn_dat *dat, const void *key, unsigned int key_siz
}
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::remove failed");
+ "grn::dat::Trie::remove failed: %s",
+ ex.what());
return ctx->rc;
}
return GRN_SUCCESS;
@@ -630,7 +677,8 @@ grn_dat_update_by_id(grn_ctx *ctx, grn_dat *dat, grn_id src_key_id,
}
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::update failed");
+ "grn::dat::Trie::update failed: %s",
+ ex.what());
return ctx->rc;
}
return GRN_SUCCESS;
@@ -665,7 +713,8 @@ grn_dat_update(grn_ctx *ctx, grn_dat *dat,
}
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::update failed");
+ "grn::dat::Trie::update failed: %s",
+ ex.what());
return ctx->rc;
}
return GRN_SUCCESS;
@@ -785,7 +834,8 @@ grn_dat_scan(grn_ctx *ctx, grn_dat *dat, const char *str,
}
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::lcp_search failed");
+ "grn::dat::lcp_search failed: %s",
+ ex.what());
if (str_rest) {
*str_rest = str;
}
@@ -816,7 +866,8 @@ grn_dat_lcp_search(grn_ctx *ctx, grn_dat *dat,
return trie->get_key(key_pos).id();
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::PrefixCursor::open failed");
+ "grn::dat::PrefixCursor::open failed: %s",
+ ex.what());
return GRN_ID_NIL;
}
}
@@ -899,7 +950,8 @@ grn_dat_cursor_open(grn_ctx *ctx, grn_dat *dat,
}
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::CursorFactory::open failed");
+ "grn::dat::CursorFactory::open failed: %s",
+ ex.what());
GRN_FREE(dc);
return NULL;
}
@@ -925,7 +977,8 @@ grn_dat_cursor_next(grn_ctx *ctx, grn_dat_cursor *c)
c->curr_rec = key.is_valid() ? key.id() : GRN_ID_NIL;
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Cursor::next failed");
+ "grn::dat::Cursor::next failed: %s",
+ ex.what());
return GRN_ID_NIL;
}
return c->curr_rec;
@@ -972,7 +1025,8 @@ grn_dat_cursor_delete(grn_ctx *ctx, grn_dat_cursor *c,
}
} catch (const grn::dat::Exception &ex) {
ERR(grn_dat_translate_error_code(ex.code()),
- "grn::dat::Trie::remove failed");
+ "grn::dat::Trie::remove failed: %s",
+ ex.what());
return GRN_INVALID_ARGUMENT;
}
return GRN_INVALID_ARGUMENT;
@@ -1008,7 +1062,7 @@ grn_dat_truncate(grn_ctx *ctx, grn_dat *dat)
grn::dat::Trie().create(trie_path);
} catch (const grn::dat::Exception &ex) {
const grn_rc error_code = grn_dat_translate_error_code(ex.code());
- ERR(error_code, "grn::dat::Trie::create failed");
+ ERR(error_code, "grn::dat::Trie::create failed: %s", ex.what());
return error_code;
}
++dat->header->file_id;
@@ -1022,14 +1076,17 @@ const char *
_grn_dat_key(grn_ctx *ctx, grn_dat *dat, grn_id id, uint32_t *key_size)
{
if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ *key_size = 0;
return NULL;
}
const grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
if (!trie) {
+ *key_size = 0;
return NULL;
}
const grn::dat::Key &key = trie->ith_key(id);
if (!key.is_valid()) {
+ *key_size = 0;
return NULL;
}
*key_size = key.length();
@@ -1102,7 +1159,7 @@ grn_dat_repair(grn_ctx *ctx, grn_dat *dat)
grn::dat::Trie().repair(*trie, trie_path);
} catch (const grn::dat::Exception &ex) {
const grn_rc error_code = grn_dat_translate_error_code(ex.code());
- ERR(error_code, "grn::dat::Trie::create failed");
+ ERR(error_code, "grn::dat::Trie::create failed: %s", ex.what());
return error_code;
}
++dat->header->file_id;
@@ -1131,9 +1188,9 @@ grn_dat_flush(grn_ctx *ctx, grn_dat *dat)
} catch (const grn::dat::Exception &ex) {
const grn_rc error_code = grn_dat_translate_error_code(ex.code());
if (error_code == GRN_INPUT_OUTPUT_ERROR) {
- SERR("grn::dat::Trie::flush failed");
+ SERR("grn::dat::Trie::flush failed: %s", ex.what());
} else {
- ERR(error_code, "grn::dat::Trie::flush failed");
+ ERR(error_code, "grn::dat::Trie::flush failed: %s", ex.what());
}
return error_code;
}
@@ -1142,4 +1199,140 @@ grn_dat_flush(grn_ctx *ctx, grn_dat *dat)
return GRN_SUCCESS;
}
+grn_rc
+grn_dat_dirty(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!dat->io) {
+ return GRN_SUCCESS;
+ }
+
+ grn_rc rc = GRN_SUCCESS;
+
+ {
+ CriticalSection critical_section(&dat->lock);
+ if (!dat->is_dirty) {
+ uint32_t n_dirty_opens;
+ dat->is_dirty = GRN_TRUE;
+ GRN_ATOMIC_ADD_EX(&(dat->header->n_dirty_opens), 1, n_dirty_opens);
+ rc = grn_io_flush(ctx, dat->io);
+ }
+ }
+
+ return rc;
+}
+
+grn_bool
+grn_dat_is_dirty(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!dat->header) {
+ return GRN_FALSE;
+ }
+
+ return dat->header->n_dirty_opens > 0;
+}
+
+grn_rc
+grn_dat_clean(grn_ctx *ctx, grn_dat *dat)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ if (!dat->io) {
+ return rc;
+ }
+
+ {
+ CriticalSection critical_section(&dat->lock);
+ if (dat->is_dirty) {
+ uint32_t n_dirty_opens;
+ dat->is_dirty = GRN_FALSE;
+ GRN_ATOMIC_ADD_EX(&(dat->header->n_dirty_opens), -1, n_dirty_opens);
+ rc = grn_io_flush(ctx, dat->io);
+ }
+ }
+
+ return rc;
+}
+
+grn_rc
+grn_dat_clear_dirty(grn_ctx *ctx, grn_dat *dat)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ if (!dat->io) {
+ return rc;
+ }
+
+ {
+ CriticalSection critical_section(&dat->lock);
+ dat->is_dirty = GRN_FALSE;
+ dat->header->n_dirty_opens = 0;
+ rc = grn_io_flush(ctx, dat->io);
+ }
+
+ return rc;
+}
+
+grn_bool
+grn_dat_is_corrupt(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!dat->io) {
+ return GRN_FALSE;
+ }
+
+ {
+ CriticalSection critical_section(&dat->lock);
+
+ if (grn_io_is_corrupt(ctx, dat->io)) {
+ return GRN_TRUE;
+ }
+
+ if (dat->header->file_id == 0) {
+ return GRN_FALSE;
+ }
+
+ char trie_path[PATH_MAX];
+ grn_dat_generate_trie_path(grn_io_path(dat->io),
+ trie_path,
+ dat->header->file_id);
+ struct stat stat;
+ if (::stat(trie_path, &stat) != 0) {
+ SERR("[dat][corrupt] used path doesn't exist: <%s>",
+ trie_path);
+ return GRN_TRUE;
+ }
+ }
+
+ return GRN_FALSE;
+}
+
+size_t
+grn_dat_get_disk_usage(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!dat->io) {
+ return 0;
+ }
+
+ {
+ CriticalSection critical_section(&dat->lock);
+ size_t usage;
+
+ usage = grn_io_get_disk_usage(ctx, dat->io);
+
+ if (dat->header->file_id == 0) {
+ return usage;
+ }
+
+ char trie_path[PATH_MAX];
+ grn_dat_generate_trie_path(grn_io_path(dat->io),
+ trie_path,
+ dat->header->file_id);
+ struct stat stat;
+ if (::stat(trie_path, &stat) == 0) {
+ usage += stat.st_size;
+ }
+
+ return usage;
+ }
+}
+
} // extern "C"
diff --git a/storage/mroonga/vendor/groonga/lib/dat/array.hpp b/storage/mroonga/vendor/groonga/lib/dat/array.hpp
index 5536552b36d..ba297e81c4b 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/array.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/array.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_ARRAY_HPP_
-#define GRN_DAT_ARRAY_HPP_
+#pragma once
#include "dat.hpp"
@@ -96,5 +96,3 @@ class GRN_DAT_API Array {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_ARRAY_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/base.hpp b/storage/mroonga/vendor/groonga/lib/dat/base.hpp
index 577e69ed62d..6f80d7c29fa 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/base.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/base.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_BASE_HPP_
-#define GRN_DAT_BASE_HPP_
+#pragma once
#include "dat.hpp"
@@ -65,5 +65,3 @@ class GRN_DAT_API Base {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_BASE_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/block.hpp b/storage/mroonga/vendor/groonga/lib/dat/block.hpp
index 4675083ecea..4f1e78b0bf7 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/block.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/block.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_BLOCK_HPP_
-#define GRN_DAT_BLOCK_HPP_
+#pragma once
#include "dat.hpp"
@@ -92,5 +92,3 @@ class GRN_DAT_API Block {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_BLOCK_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/check.hpp b/storage/mroonga/vendor/groonga/lib/dat/check.hpp
index f7e57874ca2..27abbc9873e 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/check.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/check.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_CHECK_HPP_
-#define GRN_DAT_CHECK_HPP_
+#pragma once
#include "dat.hpp"
@@ -147,5 +147,3 @@ class GRN_DAT_API Check {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_CHECK_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp b/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp
index 7276c148796..b47323a2b29 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp
@@ -32,7 +32,6 @@ Cursor *CursorFactory::open(const Trie &trie,
UInt32 offset,
UInt32 limit,
UInt32 flags) {
-
const UInt32 cursor_type = flags & CURSOR_TYPE_MASK;
switch (cursor_type) {
case ID_RANGE_CURSOR: {
diff --git a/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.hpp b/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.hpp
index c79ac4e89c7..48a0ac5052f 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_CURSOR_FACTORY_HPP_
-#define GRN_DAT_CURSOR_FACTORY_HPP_
+#pragma once
#include "cursor.hpp"
@@ -42,5 +42,3 @@ class GRN_DAT_API CursorFactory {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_CURSOR_FACTORY_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/cursor.hpp b/storage/mroonga/vendor/groonga/lib/dat/cursor.hpp
index 0a4887e1a74..2dfd98ff1de 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/cursor.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/cursor.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_CURSOR_HPP_
-#define GRN_DAT_CURSOR_HPP_
+#pragma once
#include "key.hpp"
@@ -44,5 +44,3 @@ class GRN_DAT_API Cursor {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_CURSOR_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/dat.hpp b/storage/mroonga/vendor/groonga/lib/dat/dat.hpp
index c941bf25523..a454ae7caec 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/dat.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/dat.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_COMMON_HPP_
-#define GRN_DAT_COMMON_HPP_
+#pragma once
#ifndef _MSC_VER
# include <stddef.h>
@@ -126,6 +126,7 @@ const UInt64 MIN_FILE_SIZE = 1 << 16;
const UInt64 DEFAULT_FILE_SIZE = 1 << 20;
const UInt64 MAX_FILE_SIZE = (UInt64)1 << 40;
const double DEFAULT_NUM_NODES_PER_KEY = 4.0;
+const double MAX_NUM_NODES_PER_KEY = 16.0;
const double DEFAULT_AVERAGE_KEY_LENGTH = 16.0;
const UInt32 MAX_KEY_BUF_SIZE = 0x80000000U;
const UInt32 MAX_TOTAL_KEY_LENGTH = 0xFFFFFFFFU;
@@ -245,5 +246,3 @@ typedef Error<STATUS_ERROR> StatusError;
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_COMMON_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/entry.hpp b/storage/mroonga/vendor/groonga/lib/dat/entry.hpp
index 0c0b3ad41ad..47916e282fc 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/entry.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/entry.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_ENTRY_HPP_
-#define GRN_DAT_ENTRY_HPP_
+#pragma once
#include "dat.hpp"
@@ -57,5 +57,3 @@ class GRN_DAT_API Entry {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_ENTRY_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp b/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp
index 7a9879aa369..5bd442ef4b7 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011-2015 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -36,10 +37,11 @@
#include <algorithm>
#include <limits>
+/* Must be the same value as GRN_OPEN_CREATE_MODE */
#ifdef WIN32
# define GRN_IO_FILE_CREATE_MODE (GENERIC_READ | GENERIC_WRITE)
#else /* WIN32 */
-# define GRN_IO_FILE_CREATE_MODE 0644
+# define GRN_IO_FILE_CREATE_MODE 0640
#endif /* WIN32 */
namespace grn {
@@ -128,14 +130,23 @@ void FileImpl::flush() {
return;
}
- BOOL succeeded = ::FlushViewOfFile(addr_, size_);
+ BOOL succeeded = ::FlushViewOfFile(addr_, static_cast<SIZE_T>(size_));
+ GRN_DAT_THROW_IF(IO_ERROR, !succeeded);
+
+ SYSTEMTIME system_time;
+ GetSystemTime(&system_time);
+ FILETIME file_time;
+ succeeded = SystemTimeToFileTime(&system_time, &file_time);
+ GRN_DAT_THROW_IF(IO_ERROR, !succeeded);
+
+ succeeded = SetFileTime(file_, NULL, NULL, &file_time);
GRN_DAT_THROW_IF(IO_ERROR, !succeeded);
}
void FileImpl::create_(const char *path, UInt64 size) {
if ((path != NULL) && (path[0] != '\0')) {
file_ = ::CreateFileA(path, GRN_IO_FILE_CREATE_MODE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
GRN_DAT_THROW_IF(IO_ERROR, file_ == INVALID_HANDLE_VALUE);
@@ -178,7 +189,7 @@ void FileImpl::open_(const char *path) {
static_cast<UInt64>(st.st_size) > std::numeric_limits< ::size_t>::max());
file_ = ::CreateFileA(path, GRN_IO_FILE_CREATE_MODE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
GRN_DAT_THROW_IF(IO_ERROR, file_ == NULL);
diff --git a/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp b/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp
index 245dbfc2ae7..830cf773799 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011-2015 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_FILE_IMPL_HPP_
-#define GRN_DAT_FILE_IMPL_HPP_
+#pragma once
#ifdef WIN32
# include <windows.h>
@@ -71,5 +71,3 @@ class FileImpl {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_FILE_IMPL_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/file.hpp b/storage/mroonga/vendor/groonga/lib/dat/file.hpp
index e7dda0e025e..25d988d3e1e 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/file.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/file.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011-2015 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_FILE_HPP_
-#define GRN_DAT_FILE_HPP_
+#pragma once
#include "dat.hpp"
@@ -58,5 +58,3 @@ class GRN_DAT_API File {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_FILE_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/header.hpp b/storage/mroonga/vendor/groonga/lib/dat/header.hpp
index 4f383ac8bf9..cf213076275 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/header.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/header.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_HPP_HEADER_HPP_
-#define GRN_DAT_HPP_HEADER_HPP_
+#pragma once
#include "dat.hpp"
@@ -177,5 +177,3 @@ class GRN_DAT_API Header {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_HPP_HEADER_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/id-cursor.hpp b/storage/mroonga/vendor/groonga/lib/dat/id-cursor.hpp
index aabd734e92e..0e02b225087 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/id-cursor.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/id-cursor.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_ID_CURSOR_HPP_
-#define GRN_DAT_ID_CURSOR_HPP_
+#pragma once
#include "cursor.hpp"
@@ -81,5 +81,3 @@ class GRN_DAT_API IdCursor : public Cursor {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_ID_CURSOR_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/key-cursor.hpp b/storage/mroonga/vendor/groonga/lib/dat/key-cursor.hpp
index adce41c3123..fcaa9355098 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/key-cursor.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/key-cursor.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_KEY_CURSOR_HPP_
-#define GRN_DAT_KEY_CURSOR_HPP_
+#pragma once
#include "cursor.hpp"
#include "vector.hpp"
@@ -86,5 +86,3 @@ class GRN_DAT_API KeyCursor : public Cursor {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_KEY_CURSOR_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/key.hpp b/storage/mroonga/vendor/groonga/lib/dat/key.hpp
index 21ae474cf44..95fb2b425ac 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/key.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/key.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_KEY_HPP_
-#define GRN_DAT_KEY_HPP_
+#pragma once
#include "string.hpp"
@@ -108,5 +108,3 @@ class GRN_DAT_API Key {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_KEY_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/node.hpp b/storage/mroonga/vendor/groonga/lib/dat/node.hpp
index 45ae5089b3f..7f22d67d35d 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/node.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/node.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_NODE_HPP_
-#define GRN_DAT_NODE_HPP_
+#pragma once
// See base.hpp and check.hpp for details.
#include "base.hpp"
@@ -125,5 +125,3 @@ class GRN_DAT_API Node {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_NODE_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.hpp b/storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.hpp
index e4041ff22f8..d02b7787503 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_PREDICTIVE_CURSOR_HPP_
-#define GRN_DAT_PREDICTIVE_CURSOR_HPP_
+#pragma once
#include "cursor.hpp"
#include "vector.hpp"
@@ -82,5 +82,3 @@ class GRN_DAT_API PredictiveCursor : public Cursor {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_PREDICTIVE_CURSOR_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.hpp b/storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.hpp
index 7a84228cefa..9d2a62666ad 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_PREFIX_CURSOR_HPP_
-#define GRN_DAT_PREFIX_CURSOR_HPP_
+#pragma once
#include "cursor.hpp"
#include "vector.hpp"
@@ -76,5 +76,3 @@ class GRN_DAT_API PrefixCursor : public Cursor {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_PREFIX_CURSOR_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/string.hpp b/storage/mroonga/vendor/groonga/lib/dat/string.hpp
index ecbb1e79d04..c6bee8641d5 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/string.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/string.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_STRING_HPP_
-#define GRN_DAT_STRING_HPP_
+#pragma once
#include "dat.hpp"
@@ -171,5 +171,3 @@ inline bool operator>=(const String &lhs, const String &rhs) {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_STRING_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/trie.cpp b/storage/mroonga/vendor/groonga/lib/dat/trie.cpp
index 2f9e79bac56..1022c2da0a3 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/trie.cpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/trie.cpp
@@ -67,7 +67,11 @@ void Trie::create(const char *file_name,
if (num_nodes_per_key < 1.0) {
num_nodes_per_key = DEFAULT_NUM_NODES_PER_KEY;
}
+ if (num_nodes_per_key > MAX_NUM_NODES_PER_KEY) {
+ num_nodes_per_key = MAX_NUM_NODES_PER_KEY;
+ }
GRN_DAT_THROW_IF(PARAM_ERROR, num_nodes_per_key < 1.0);
+ GRN_DAT_THROW_IF(PARAM_ERROR, num_nodes_per_key > MAX_NUM_NODES_PER_KEY);
if (average_key_length < 1.0) {
average_key_length = DEFAULT_AVERAGE_KEY_LENGTH;
@@ -105,9 +109,13 @@ void Trie::create(const Trie &trie,
num_nodes_per_key = DEFAULT_NUM_NODES_PER_KEY;
} else {
num_nodes_per_key = 1.0 * trie.num_nodes() / trie.num_keys();
+ if (num_nodes_per_key > MAX_NUM_NODES_PER_KEY) {
+ num_nodes_per_key = MAX_NUM_NODES_PER_KEY;
+ }
}
}
GRN_DAT_THROW_IF(PARAM_ERROR, num_nodes_per_key < 1.0);
+ GRN_DAT_THROW_IF(PARAM_ERROR, num_nodes_per_key > MAX_NUM_NODES_PER_KEY);
if (average_key_length < 1.0) {
if (trie.num_keys() == 0) {
diff --git a/storage/mroonga/vendor/groonga/lib/dat/trie.hpp b/storage/mroonga/vendor/groonga/lib/dat/trie.hpp
index 8a272bb7940..d6e5b9c284c 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/trie.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/trie.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011-2015 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_TRIE_HPP_
-#define GRN_DAT_TRIE_HPP_
+#pragma once
#include "array.hpp"
#include "header.hpp"
@@ -283,5 +283,3 @@ class GRN_DAT_API Trie {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_TRIE_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/dat/vector.hpp b/storage/mroonga/vendor/groonga/lib/dat/vector.hpp
index 4f32c590e0b..202203334ab 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/vector.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/vector.hpp
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/*
+ Copyright(C) 2011-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_VECTOR_HPP_
-#define GRN_DAT_VECTOR_HPP_
+#pragma once
#include "dat.hpp"
@@ -189,5 +189,3 @@ class GRN_DAT_API Vector {
} // namespace dat
} // namespace grn
-
-#endif // GRN_DAT_VECTOR_HPP_
diff --git a/storage/mroonga/vendor/groonga/lib/db.c b/storage/mroonga/vendor/groonga/lib/db.c
index 05e4d73e5ed..01aa1e25581 100644
--- a/storage/mroonga/vendor/groonga/lib/db.c
+++ b/storage/mroonga/vendor/groonga/lib/db.c
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,11 +16,14 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "grn.h"
+#include "grn_config.h"
#include "grn_db.h"
+#include "grn_obj.h"
#include "grn_hash.h"
#include "grn_pat.h"
#include "grn_dat.h"
#include "grn_ii.h"
+#include "grn_index_column.h"
#include "grn_ctx_impl.h"
#include "grn_token_cursor.h"
#include "grn_tokenizers.h"
@@ -30,8 +34,12 @@
#include "grn_snip.h"
#include "grn_string.h"
#include "grn_normalizer.h"
+#include "grn_report.h"
#include "grn_util.h"
+#include "grn_cache.h"
+#include "grn_window_functions.h"
#include <string.h>
+#include <math.h>
typedef struct {
grn_id id;
@@ -40,8 +48,6 @@ typedef struct {
#define IS_WEIGHT_UVECTOR(obj) ((obj)->header.flags & GRN_OBJ_WITH_WEIGHT)
-#define NEXT_ADDR(p) (((byte *)(p)) + sizeof(*(p)))
-
#define GRN_TABLE_GROUPED (0x01<<0)
#define GRN_TABLE_IS_GROUPED(table)\
((table)->header.impl_flags & GRN_TABLE_GROUPED)
@@ -85,9 +91,7 @@ inline static void
grn_obj_get_range_info(grn_ctx *ctx, grn_obj *obj,
grn_id *range_id, grn_obj_flags *range_flags);
-
static char grn_db_key[GRN_ENV_BUFFER_SIZE];
-static uint64_t grn_index_sparsity = 10;
void
grn_db_init_from_env(void)
@@ -95,21 +99,6 @@ grn_db_init_from_env(void)
grn_getenv("GRN_DB_KEY",
grn_db_key,
GRN_ENV_BUFFER_SIZE);
-
- {
- char grn_index_sparsity_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_INDEX_SPARSITY",
- grn_index_sparsity_env,
- GRN_ENV_BUFFER_SIZE);
- if (grn_index_sparsity_env[0]) {
- uint64_t sparsity;
- errno = 0;
- sparsity = strtoull(grn_index_sparsity_env, NULL, 0);
- if (errno == 0) {
- grn_index_sparsity = sparsity;
- }
- }
- }
}
inline static void
@@ -126,192 +115,304 @@ gen_pathname(const char *path, char *buffer, int fno)
}
}
+void
+grn_db_generate_pathname(grn_ctx *ctx, grn_obj *db, grn_id id, char *buffer)
+{
+ gen_pathname(grn_obj_get_io(ctx, db)->path, buffer, id);
+}
+
+typedef struct {
+ grn_obj *ptr;
+ uint32_t lock;
+ uint32_t done;
+} db_value;
+
+static const char *GRN_DB_CONFIG_PATH_FORMAT = "%s.conf";
+
static grn_bool
-is_text_object(grn_obj *object)
+grn_db_config_create(grn_ctx *ctx, grn_db *s, const char *path,
+ const char *context_tag)
{
- if (!object) {
- return GRN_FALSE;
- }
+ char *config_path;
+ char config_path_buffer[PATH_MAX];
+ uint32_t flags = GRN_OBJ_KEY_VAR_SIZE;
- if (object->header.type != GRN_BULK) {
+ if (path) {
+ grn_snprintf(config_path_buffer, PATH_MAX, PATH_MAX,
+ GRN_DB_CONFIG_PATH_FORMAT, path);
+ config_path = config_path_buffer;
+ } else {
+ config_path = NULL;
+ }
+ s->config = grn_hash_create(ctx, config_path,
+ GRN_CONFIG_MAX_KEY_SIZE,
+ GRN_CONFIG_VALUE_SPACE_SIZE,
+ flags);
+ if (!s->config) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "%s failed to create data store for configuration: <%s>",
+ context_tag,
+ config_path ? config_path : "(temporary)");
return GRN_FALSE;
}
- switch (object->header.domain) {
- case GRN_DB_SHORT_TEXT:
- case GRN_DB_TEXT:
- case GRN_DB_LONG_TEXT:
- return GRN_TRUE;
- default:
- return GRN_FALSE;
- }
+ return GRN_TRUE;
}
-static void
-limited_size_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *object)
+static grn_bool
+grn_db_config_open(grn_ctx *ctx, grn_db *s, const char *path)
{
- unsigned int original_size = 0;
- unsigned int max_size = GRN_CTX_MSGSIZE / 2;
-
- if (object) {
- original_size = GRN_BULK_VSIZE(object);
- }
+ char config_path[PATH_MAX];
- if (original_size > max_size && is_text_object(object)) {
- grn_text_esc(ctx, buffer, GRN_TEXT_VALUE(object), max_size);
- GRN_TEXT_PUTS(ctx, buffer, "...(");
- grn_text_lltoa(ctx, buffer, original_size);
- GRN_TEXT_PUTS(ctx, buffer, ")");
+ grn_snprintf(config_path, PATH_MAX, PATH_MAX, GRN_DB_CONFIG_PATH_FORMAT, path);
+ if (grn_path_exist(config_path)) {
+ s->config = grn_hash_open(ctx, config_path);
+ if (!s->config) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[db][open] failed to open data store for configuration: <%s>",
+ config_path);
+ return GRN_FALSE;
+ }
+ return GRN_TRUE;
} else {
- grn_inspect(ctx, buffer, object);
+ return grn_db_config_create(ctx, s, path, "[db][open]");
}
}
-typedef struct {
- grn_obj *ptr;
- uint32_t lock;
- uint32_t done;
-} db_value;
+static grn_rc
+grn_db_config_remove(grn_ctx *ctx, const char *path)
+{
+ char config_path[PATH_MAX];
+
+ grn_snprintf(config_path, PATH_MAX, PATH_MAX, GRN_DB_CONFIG_PATH_FORMAT, path);
+ return grn_hash_remove(ctx, config_path);
+}
grn_obj *
grn_db_create(grn_ctx *ctx, const char *path, grn_db_create_optarg *optarg)
{
- grn_db *s;
+ grn_db *s = NULL;
+
GRN_API_ENTER;
- if (!path || strlen(path) <= PATH_MAX - 14) {
- if ((s = GRN_MALLOC(sizeof(grn_db)))) {
- grn_bool use_default_db_key = GRN_TRUE;
- grn_bool use_pat_as_db_keys = GRN_FALSE;
- if (grn_db_key[0]) {
- if (!strcmp(grn_db_key, "pat")) {
- use_default_db_key = GRN_FALSE;
- use_pat_as_db_keys = GRN_TRUE;
- } else if (!strcmp(grn_db_key, "dat")) {
- use_default_db_key = GRN_FALSE;
- }
- }
- if (use_default_db_key && !strcmp(GRN_DEFAULT_DB_KEY, "pat")) {
+
+ if (path && strlen(path) > PATH_MAX - 14) {
+ ERR(GRN_INVALID_ARGUMENT, "too long path");
+ goto exit;
+ }
+
+ s = GRN_MALLOC(sizeof(grn_db));
+ if (!s) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "grn_db alloc failed");
+ goto exit;
+ }
+
+ CRITICAL_SECTION_INIT(s->lock);
+ grn_tiny_array_init(ctx, &s->values, sizeof(db_value),
+ GRN_TINY_ARRAY_CLEAR|
+ GRN_TINY_ARRAY_THREADSAFE|
+ GRN_TINY_ARRAY_USE_MALLOC);
+ s->keys = NULL;
+ s->specs = NULL;
+ s->config = NULL;
+
+ {
+ grn_bool use_default_db_key = GRN_TRUE;
+ grn_bool use_pat_as_db_keys = GRN_FALSE;
+ if (grn_db_key[0]) {
+ if (!strcmp(grn_db_key, "pat")) {
+ use_default_db_key = GRN_FALSE;
use_pat_as_db_keys = GRN_TRUE;
+ } else if (!strcmp(grn_db_key, "dat")) {
+ use_default_db_key = GRN_FALSE;
}
- grn_tiny_array_init(ctx, &s->values, sizeof(db_value),
- GRN_TINY_ARRAY_CLEAR|
- GRN_TINY_ARRAY_THREADSAFE|
- GRN_TINY_ARRAY_USE_MALLOC);
- if (use_pat_as_db_keys) {
- s->keys = (grn_obj *)grn_pat_create(ctx, path, GRN_TABLE_MAX_KEY_SIZE,
- 0, GRN_OBJ_KEY_VAR_SIZE);
- } else {
- s->keys = (grn_obj *)grn_dat_create(ctx, path, GRN_TABLE_MAX_KEY_SIZE,
- 0, GRN_OBJ_KEY_VAR_SIZE);
- }
- if (s->keys) {
- CRITICAL_SECTION_INIT(s->lock);
- GRN_DB_OBJ_SET_TYPE(s, GRN_DB);
- s->obj.db = (grn_obj *)s;
- s->obj.header.domain = GRN_ID_NIL;
- DB_OBJ(&s->obj)->range = GRN_ID_NIL;
- // prepare builtin classes and load builtin plugins.
- if (path) {
- char specs_path[PATH_MAX];
- gen_pathname(path, specs_path, 0);
- if ((s->specs = grn_ja_create(ctx, specs_path, 65536, 0))) {
- grn_ctx_use(ctx, (grn_obj *)s);
- grn_db_init_builtin_types(ctx);
- GRN_API_RETURN((grn_obj *)s);
- } else {
- ERR(GRN_NO_MEMORY_AVAILABLE,
- "failed to create specs: <%s>", specs_path);
- }
- } else {
- s->specs = NULL;
- grn_ctx_use(ctx, (grn_obj *)s);
- grn_db_init_builtin_types(ctx);
- GRN_API_RETURN((grn_obj *)s);
- }
- if (use_pat_as_db_keys) {
- grn_pat_close(ctx, (grn_pat *)s->keys);
- grn_pat_remove(ctx, path);
- } else {
- grn_dat_close(ctx, (grn_dat *)s->keys);
- grn_dat_remove(ctx, path);
- }
- }
- grn_tiny_array_fin(&s->values);
- GRN_FREE(s);
+ }
+
+ if (use_default_db_key && !strcmp(GRN_DEFAULT_DB_KEY, "pat")) {
+ use_pat_as_db_keys = GRN_TRUE;
+ }
+ if (use_pat_as_db_keys) {
+ s->keys = (grn_obj *)grn_pat_create(ctx, path, GRN_TABLE_MAX_KEY_SIZE,
+ 0, GRN_OBJ_KEY_VAR_SIZE);
} else {
- ERR(GRN_NO_MEMORY_AVAILABLE, "grn_db alloc failed");
+ s->keys = (grn_obj *)grn_dat_create(ctx, path, GRN_TABLE_MAX_KEY_SIZE,
+ 0, GRN_OBJ_KEY_VAR_SIZE);
}
+ }
+
+ if (!s->keys) {
+ goto exit;
+ }
+
+ GRN_DB_OBJ_SET_TYPE(s, GRN_DB);
+ s->obj.db = (grn_obj *)s;
+ s->obj.header.domain = GRN_ID_NIL;
+ DB_OBJ(&s->obj)->range = GRN_ID_NIL;
+ /* prepare builtin classes and load builtin plugins. */
+ if (path) {
+ {
+ char specs_path[PATH_MAX];
+ gen_pathname(path, specs_path, 0);
+ s->specs = grn_ja_create(ctx, specs_path, 65536, 0);
+ if (!s->specs) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to create specs: <%s>", specs_path);
+ goto exit;
+ }
+ }
+ if (!grn_db_config_create(ctx, s, path, "[db][create]")) {
+ goto exit;
+ }
+ grn_ctx_use(ctx, (grn_obj *)s);
+ grn_db_init_builtin_types(ctx);
+ grn_obj_flush(ctx, (grn_obj *)s);
+ GRN_API_RETURN((grn_obj *)s);
} else {
- ERR(GRN_INVALID_ARGUMENT, "too long path");
+ if (!grn_db_config_create(ctx, s, NULL, "[db][create]")) {
+ goto exit;
+ }
+ grn_ctx_use(ctx, (grn_obj *)s);
+ grn_db_init_builtin_types(ctx);
+ GRN_API_RETURN((grn_obj *)s);
+ }
+
+exit:
+ if (s) {
+ if (s->keys) {
+ if (s->keys->header.type == GRN_TABLE_PAT_KEY) {
+ grn_pat_close(ctx, (grn_pat *)s->keys);
+ grn_pat_remove(ctx, path);
+ } else {
+ grn_dat_close(ctx, (grn_dat *)s->keys);
+ grn_dat_remove(ctx, path);
+ }
+ }
+ if (s->specs) {
+ const char *specs_path;
+ specs_path = grn_obj_path(ctx, (grn_obj *)(s->specs));
+ grn_ja_close(ctx, s->specs);
+ grn_ja_remove(ctx, specs_path);
+ }
+ grn_tiny_array_fin(&s->values);
+ CRITICAL_SECTION_FIN(s->lock);
+ GRN_FREE(s);
}
+
GRN_API_RETURN(NULL);
}
grn_obj *
grn_db_open(grn_ctx *ctx, const char *path)
{
- grn_db *s;
+ grn_db *s = NULL;
+
GRN_API_ENTER;
- if (path && strlen(path) <= PATH_MAX - 14) {
- if ((s = GRN_MALLOC(sizeof(grn_db)))) {
- uint32_t type = grn_io_detect_type(ctx, path);
- grn_tiny_array_init(ctx, &s->values, sizeof(db_value),
- GRN_TINY_ARRAY_CLEAR|
- GRN_TINY_ARRAY_THREADSAFE|
- GRN_TINY_ARRAY_USE_MALLOC);
- switch (type) {
- case GRN_TABLE_PAT_KEY :
- s->keys = (grn_obj *)grn_pat_open(ctx, path);
- break;
- case GRN_TABLE_DAT_KEY :
- s->keys = (grn_obj *)grn_dat_open(ctx, path);
- break;
- default :
- s->keys = NULL;
- if (ctx->rc == GRN_SUCCESS) {
- ERR(GRN_INVALID_ARGUMENT,
- "[db][open] invalid keys table's type: %#x", type);
- }
- break;
+
+ if (!path) {
+ ERR(GRN_INVALID_ARGUMENT, "[db][open] path is missing");
+ goto exit;
+ }
+
+ if (strlen(path) > PATH_MAX - 14) {
+ ERR(GRN_INVALID_ARGUMENT, "inappropriate path");
+ goto exit;
+ }
+
+ s = GRN_MALLOC(sizeof(grn_db));
+ if (!s) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "grn_db alloc failed");
+ goto exit;
+ }
+
+ CRITICAL_SECTION_INIT(s->lock);
+ grn_tiny_array_init(ctx, &s->values, sizeof(db_value),
+ GRN_TINY_ARRAY_CLEAR|
+ GRN_TINY_ARRAY_THREADSAFE|
+ GRN_TINY_ARRAY_USE_MALLOC);
+ s->keys = NULL;
+ s->specs = NULL;
+ s->config = NULL;
+
+ {
+ uint32_t type = grn_io_detect_type(ctx, path);
+ switch (type) {
+ case GRN_TABLE_PAT_KEY :
+ s->keys = (grn_obj *)grn_pat_open(ctx, path);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ s->keys = (grn_obj *)grn_dat_open(ctx, path);
+ break;
+ default :
+ s->keys = NULL;
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[db][open] invalid keys table's type: %#x", type);
+ goto exit;
}
- if (s->keys) {
- char specs_path[PATH_MAX];
- gen_pathname(path, specs_path, 0);
- if ((s->specs = grn_ja_open(ctx, specs_path))) {
- CRITICAL_SECTION_INIT(s->lock);
- GRN_DB_OBJ_SET_TYPE(s, GRN_DB);
- s->obj.db = (grn_obj *)s;
- s->obj.header.domain = GRN_ID_NIL;
- DB_OBJ(&s->obj)->range = GRN_ID_NIL;
- grn_ctx_use(ctx, (grn_obj *)s);
+ break;
+ }
+ }
+
+ if (!s->keys) {
+ goto exit;
+ }
+
+ {
+ char specs_path[PATH_MAX];
+ gen_pathname(path, specs_path, 0);
+ s->specs = grn_ja_open(ctx, specs_path);
+ if (!s->specs) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[db][open] failed to open specs: <%s>", specs_path);
+ goto exit;
+ }
+ }
+ if (!grn_db_config_open(ctx, s, path)) {
+ goto exit;
+ }
+
+ GRN_DB_OBJ_SET_TYPE(s, GRN_DB);
+ s->obj.db = (grn_obj *)s;
+ s->obj.header.domain = GRN_ID_NIL;
+ DB_OBJ(&s->obj)->range = GRN_ID_NIL;
+ grn_ctx_use(ctx, (grn_obj *)s);
+ {
+ unsigned int n_records;
+
+ n_records = grn_table_size(ctx, (grn_obj *)s);
#ifdef GRN_WITH_MECAB
- if (grn_db_init_mecab_tokenizer(ctx)) {
- ERRCLR(ctx);
- }
+ if (grn_db_init_mecab_tokenizer(ctx)) {
+ ERRCLR(ctx);
+ }
#endif
- grn_db_init_builtin_tokenizers(ctx);
- grn_db_init_builtin_normalizers(ctx);
- grn_db_init_builtin_scorers(ctx);
- grn_db_init_builtin_query(ctx);
- GRN_API_RETURN((grn_obj *)s);
- }
- switch (type) {
- case GRN_TABLE_PAT_KEY :
- grn_pat_close(ctx, (grn_pat *)s->keys);
- break;
- case GRN_TABLE_DAT_KEY :
- grn_dat_close(ctx, (grn_dat *)s->keys);
- break;
- }
+ grn_db_init_builtin_tokenizers(ctx);
+ grn_db_init_builtin_normalizers(ctx);
+ grn_db_init_builtin_scorers(ctx);
+ grn_db_init_builtin_commands(ctx);
+ grn_db_init_builtin_window_functions(ctx);
+
+ if (grn_table_size(ctx, (grn_obj *)s) > n_records) {
+ grn_obj_flush(ctx, (grn_obj *)s);
+ }
+ }
+ GRN_API_RETURN((grn_obj *)s);
+
+exit:
+ if (s) {
+ if (s->specs) {
+ grn_ja_close(ctx, s->specs);
+ }
+ if (s->keys) {
+ if (s->keys->header.type == GRN_TABLE_PAT_KEY) {
+ grn_pat_close(ctx, (grn_pat *)s->keys);
+ } else {
+ grn_dat_close(ctx, (grn_dat *)s->keys);
}
- grn_tiny_array_fin(&s->values);
- GRN_FREE(s);
- } else {
- ERR(GRN_NO_MEMORY_AVAILABLE, "grn_db alloc failed");
}
- } else {
- ERR(GRN_INVALID_ARGUMENT, "inappropriate path");
+ grn_tiny_array_fin(&s->values);
+ CRITICAL_SECTION_FIN(s->lock);
+ GRN_FREE(s);
}
+
GRN_API_RETURN(NULL);
}
@@ -383,6 +484,7 @@ grn_db_close(grn_ctx *ctx, grn_obj *db)
}
CRITICAL_SECTION_FIN(s->lock);
if (s->specs) { grn_ja_close(ctx, s->specs); }
+ grn_hash_close(ctx, s->config);
GRN_FREE(s);
if (ctx_used_db) {
@@ -400,7 +502,6 @@ grn_db_close(grn_ctx *ctx, grn_obj *db)
grn_obj *
grn_ctx_get(grn_ctx *ctx, const char *name, int name_size)
{
- grn_id id;
grn_obj *obj = NULL;
grn_obj *db;
if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
@@ -409,12 +510,70 @@ grn_ctx_get(grn_ctx *ctx, const char *name, int name_size)
GRN_API_ENTER;
if (GRN_DB_P(db)) {
grn_db *s = (grn_db *)db;
+ grn_obj *alias_table = NULL;
+ grn_obj *alias_column = NULL;
+ grn_obj alias_name_buffer;
+
if (name_size < 0) {
name_size = strlen(name);
}
- if ((id = grn_table_get(ctx, s->keys, name, name_size))) {
- obj = grn_ctx_at(ctx, id);
+ GRN_TEXT_INIT(&alias_name_buffer, 0);
+ while (GRN_TRUE) {
+ grn_id id;
+
+ id = grn_table_get(ctx, s->keys, name, name_size);
+ if (id) {
+ obj = grn_ctx_at(ctx, id);
+ break;
+ }
+
+ if (!alias_column) {
+ grn_id alias_column_id;
+ const char *alias_column_name;
+ uint32_t alias_column_name_size;
+
+ grn_config_get(ctx,
+ "alias.column", -1,
+ &alias_column_name, &alias_column_name_size);
+ if (!alias_column_name) {
+ break;
+ }
+ alias_column_id = grn_table_get(ctx,
+ s->keys,
+ alias_column_name,
+ alias_column_name_size);
+ if (!alias_column_id) {
+ break;
+ }
+ alias_column = grn_ctx_at(ctx, alias_column_id);
+ if (alias_column->header.type != GRN_COLUMN_VAR_SIZE) {
+ break;
+ }
+ if (alias_column->header.flags & GRN_OBJ_VECTOR) {
+ break;
+ }
+ if (DB_OBJ(alias_column)->range != GRN_DB_SHORT_TEXT) {
+ break;
+ }
+ alias_table = grn_ctx_at(ctx, alias_column->header.domain);
+ if (alias_table->header.type == GRN_TABLE_NO_KEY) {
+ break;
+ }
+ }
+
+ {
+ grn_id alias_id;
+ alias_id = grn_table_get(ctx, alias_table, name, name_size);
+ if (!alias_id) {
+ break;
+ }
+ GRN_BULK_REWIND(&alias_name_buffer);
+ grn_obj_get_value(ctx, alias_column, alias_id, &alias_name_buffer);
+ name = GRN_TEXT_VALUE(&alias_name_buffer);
+ name_size = GRN_TEXT_LEN(&alias_name_buffer);
+ }
}
+ GRN_OBJ_FIN(ctx, &alias_name_buffer);
}
GRN_API_RETURN(obj);
}
@@ -431,55 +590,175 @@ grn_db_keys(grn_obj *s)
return (grn_obj *)(((grn_db *)s)->keys);
}
-static grn_io*
-grn_obj_io(grn_obj *obj)
+uint32_t
+grn_obj_get_last_modified(grn_ctx *ctx, grn_obj *obj)
{
- grn_io *io = NULL;
- if (obj) {
- if (obj->header.type == GRN_DB) { obj = ((grn_db *)obj)->keys; }
- switch (obj->header.type) {
- case GRN_TABLE_PAT_KEY :
- io = ((grn_pat *)obj)->io;
- break;
- case GRN_TABLE_DAT_KEY :
- io = ((grn_dat *)obj)->io;
- break;
- case GRN_TABLE_HASH_KEY :
- io = ((grn_hash *)obj)->io;
- break;
- case GRN_TABLE_NO_KEY :
- io = ((grn_array *)obj)->io;
- break;
- case GRN_COLUMN_VAR_SIZE :
- io = ((grn_ja *)obj)->io;
- break;
- case GRN_COLUMN_FIX_SIZE :
- io = ((grn_ra *)obj)->io;
- break;
- case GRN_COLUMN_INDEX :
- io = ((grn_ii *)obj)->seg;
- break;
- }
+ if (!obj) {
+ return 0;
+ }
+
+ return grn_obj_get_io(ctx, obj)->header->last_modified;
+}
+
+grn_bool
+grn_obj_is_dirty(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!obj) {
+ return GRN_FALSE;
+ }
+
+ switch (obj->header.type) {
+ case GRN_DB :
+ return grn_db_is_dirty(ctx, obj);
+ case GRN_TABLE_PAT_KEY :
+ return grn_pat_is_dirty(ctx, (grn_pat *)obj);
+ case GRN_TABLE_DAT_KEY :
+ return grn_dat_is_dirty(ctx, (grn_dat *)obj);
+ default :
+ return GRN_FALSE;
}
- return io;
}
uint32_t
-grn_db_lastmod(grn_obj *s)
+grn_db_get_last_modified(grn_ctx *ctx, grn_obj *db)
+{
+ return grn_obj_get_last_modified(ctx, db);
+}
+
+grn_bool
+grn_db_is_dirty(grn_ctx *ctx, grn_obj *db)
+{
+ grn_obj *keys;
+
+ if (!db) {
+ return GRN_FALSE;
+ }
+
+ keys = ((grn_db *)db)->keys;
+ return grn_obj_is_dirty(ctx, keys);
+}
+
+static grn_rc
+grn_db_dirty(grn_ctx *ctx, grn_obj *db)
{
- return grn_obj_io(((grn_db *)s)->keys)->header->lastmod;
+ grn_obj *keys;
+
+ if (!db) {
+ return GRN_SUCCESS;
+ }
+
+ keys = ((grn_db *)db)->keys;
+ switch (keys->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ return grn_pat_dirty(ctx, (grn_pat *)keys);
+ case GRN_TABLE_DAT_KEY :
+ return grn_dat_dirty(ctx, (grn_dat *)keys);
+ default :
+ return GRN_SUCCESS;
+ }
+}
+
+static grn_rc
+grn_db_clean(grn_ctx *ctx, grn_obj *db)
+{
+ grn_obj *keys;
+
+ if (!db) {
+ return GRN_SUCCESS;
+ }
+
+ keys = ((grn_db *)db)->keys;
+ switch (keys->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ return grn_pat_clean(ctx, (grn_pat *)keys);
+ case GRN_TABLE_DAT_KEY :
+ return grn_dat_clean(ctx, (grn_dat *)keys);
+ default :
+ return GRN_SUCCESS;
+ }
+}
+
+static grn_rc
+grn_db_clear_dirty(grn_ctx *ctx, grn_obj *db)
+{
+ grn_obj *keys;
+
+ if (!db) {
+ return GRN_SUCCESS;
+ }
+
+ keys = ((grn_db *)db)->keys;
+ switch (keys->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ return grn_pat_clear_dirty(ctx, (grn_pat *)keys);
+ case GRN_TABLE_DAT_KEY :
+ return grn_dat_clear_dirty(ctx, (grn_dat *)keys);
+ default :
+ return GRN_SUCCESS;
+ }
}
void
grn_db_touch(grn_ctx *ctx, grn_obj *s)
{
- grn_timeval tv;
- grn_timeval_now(ctx, &tv);
- grn_obj_io(s)->header->lastmod = tv.tv_sec;
+ grn_obj_touch(ctx, s, NULL);
+}
+
+grn_bool
+grn_obj_is_corrupt(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_bool is_corrupt = GRN_FALSE;
+
+ GRN_API_ENTER;
+
+ if (!obj) {
+ ERR(GRN_INVALID_ARGUMENT, "[object][corrupt] object must not be NULL");
+ GRN_API_RETURN(GRN_FALSE);
+ }
+
+ switch (obj->header.type) {
+ case GRN_DB :
+ is_corrupt = grn_io_is_corrupt(ctx, grn_obj_get_io(ctx, obj));
+ if (!is_corrupt) {
+ is_corrupt = grn_io_is_corrupt(ctx, ((grn_db *)obj)->specs->io);
+ }
+ if (!is_corrupt) {
+ is_corrupt = grn_io_is_corrupt(ctx, ((grn_db *)obj)->config->io);
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ is_corrupt = grn_io_is_corrupt(ctx, grn_obj_get_io(ctx, obj));
+ break;
+ case GRN_TABLE_DAT_KEY :
+ is_corrupt = grn_dat_is_corrupt(ctx, (grn_dat *)obj);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ is_corrupt = grn_io_is_corrupt(ctx, grn_obj_get_io(ctx, obj));
+ break;
+ case GRN_COLUMN_INDEX :
+ is_corrupt = grn_io_is_corrupt(ctx, ((grn_ii *)obj)->seg);
+ if (!is_corrupt) {
+ is_corrupt = grn_io_is_corrupt(ctx, ((grn_ii *)obj)->chunk);
+ }
+ break;
+ default :
+ break;
+ }
+
+ GRN_API_RETURN(is_corrupt);
}
#define IS_TEMP(obj) (DB_OBJ(obj)->id & GRN_OBJ_TMP_OBJECT)
+static inline void
+grn_obj_touch_db(grn_ctx *ctx, grn_obj *obj, grn_timeval *tv)
+{
+ grn_obj_get_io(ctx, obj)->header->last_modified = tv->tv_sec;
+ grn_db_dirty(ctx, obj);
+}
+
void
grn_obj_touch(grn_ctx *ctx, grn_obj *obj, grn_timeval *tv)
{
@@ -491,7 +770,7 @@ grn_obj_touch(grn_ctx *ctx, grn_obj *obj, grn_timeval *tv)
if (obj) {
switch (obj->header.type) {
case GRN_DB :
- grn_obj_io(obj)->header->lastmod = tv->tv_sec;
+ grn_obj_touch_db(ctx, obj, tv);
break;
case GRN_TABLE_HASH_KEY :
case GRN_TABLE_PAT_KEY :
@@ -501,7 +780,8 @@ grn_obj_touch(grn_ctx *ctx, grn_obj *obj, grn_timeval *tv)
case GRN_COLUMN_FIX_SIZE :
case GRN_COLUMN_INDEX :
if (!IS_TEMP(obj)) {
- grn_obj_io(DB_OBJ(obj)->db)->header->lastmod = tv->tv_sec;
+ grn_obj_get_io(ctx, obj)->header->last_modified = tv->tv_sec;
+ grn_obj_touch(ctx, DB_OBJ(obj)->db, tv);
}
break;
}
@@ -533,41 +813,6 @@ grn_db_check_name(grn_ctx *ctx, const char *name, unsigned int name_size)
return GRN_SUCCESS;
}
-grn_obj *
-grn_type_create(grn_ctx *ctx, const char *name, unsigned int name_size,
- grn_obj_flags flags, unsigned int size)
-{
- grn_id id;
- struct _grn_type *res = NULL;
- grn_obj *db;
- if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
- ERR(GRN_INVALID_ARGUMENT, "db not initialized");
- return NULL;
- }
- GRN_API_ENTER;
- if (grn_db_check_name(ctx, name, name_size)) {
- GRN_DB_CHECK_NAME_ERR("[type][create]", name, name_size);
- GRN_API_RETURN(NULL);
- }
- if (!GRN_DB_P(db)) {
- ERR(GRN_INVALID_ARGUMENT, "invalid db assigned");
- GRN_API_RETURN(NULL);
- }
- id = grn_obj_register(ctx, db, name, name_size);
- if (id && (res = GRN_MALLOC(sizeof(grn_db_obj)))) {
- GRN_DB_OBJ_SET_TYPE(res, GRN_TYPE);
- res->obj.header.flags = flags;
- res->obj.header.domain = GRN_ID_NIL;
- GRN_TYPE_SIZE(&res->obj) = size;
- if (grn_db_obj_init(ctx, db, id, DB_OBJ(res))) {
- // grn_obj_delete(ctx, db, id);
- GRN_FREE(res);
- GRN_API_RETURN(NULL);
- }
- }
- GRN_API_RETURN((grn_obj *)res);
-}
-
static grn_obj *
grn_type_open(grn_ctx *ctx, grn_obj_spec *spec)
{
@@ -591,12 +836,13 @@ grn_proc_create(grn_ctx *ctx, const char *name, int name_size, grn_proc_type typ
grn_id range = GRN_ID_NIL;
int added = 0;
grn_obj *db;
- const char *path = ctx->impl->plugin_path;
+ const char *path;
if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
ERR(GRN_INVALID_ARGUMENT, "db not initialized");
return NULL;
}
GRN_API_ENTER;
+ path = ctx->impl->plugin_path;
if (path) {
range = grn_plugin_reference(ctx, path);
}
@@ -653,8 +899,9 @@ grn_proc_create(grn_ctx *ctx, const char *name, int name_size, grn_proc_type typ
res->funcs[PROC_INIT] = init;
res->funcs[PROC_NEXT] = next;
res->funcs[PROC_FIN] = fin;
- res->selector = NULL;
memset(&(res->callbacks), 0, sizeof(res->callbacks));
+ res->callbacks.function.selector_op = GRN_OP_NOP;
+ res->callbacks.function.is_stable = GRN_TRUE;
GRN_TEXT_INIT(&res->name_buf, 0);
res->vars = NULL;
res->nvars = 0;
@@ -678,7 +925,7 @@ grn_proc_create(grn_ctx *ctx, const char *name, int name_size, grn_proc_type typ
/* grn_table */
static void
-calc_rec_size(grn_obj_flags flags, uint32_t max_n_subrecs, uint32_t range_size,
+calc_rec_size(grn_table_flags flags, uint32_t max_n_subrecs, uint32_t range_size,
uint32_t additional_value_size,
uint8_t *subrec_size, uint8_t *subrec_offset,
uint32_t *key_size, uint32_t *value_size)
@@ -726,56 +973,94 @@ calc_rec_size(grn_obj_flags flags, uint32_t max_n_subrecs, uint32_t range_size,
*value_size += additional_value_size;
}
-static void _grn_obj_remove(grn_ctx *ctx, grn_obj *obj);
+static grn_rc _grn_obj_remove(grn_ctx *ctx, grn_obj *obj, grn_bool dependent);
static grn_rc
grn_table_create_validate(grn_ctx *ctx, const char *name, unsigned int name_size,
- const char *path, grn_obj_flags flags,
+ const char *path, grn_table_flags flags,
grn_obj *key_type, grn_obj *value_type)
{
- switch (flags & GRN_OBJ_TABLE_TYPE_MASK) {
+ grn_table_flags table_type;
+ const char *table_type_name = NULL;
+
+ table_type = (flags & GRN_OBJ_TABLE_TYPE_MASK);
+ switch (table_type) {
case GRN_OBJ_TABLE_HASH_KEY :
- if (flags & GRN_OBJ_KEY_WITH_SIS) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][create] "
- "key with SIS isn't available for hash table: <%.*s>",
- name_size, name);
- }
+ table_type_name = "TABLE_HASH_KEY";
break;
case GRN_OBJ_TABLE_PAT_KEY :
+ table_type_name = "TABLE_PAT_KEY";
break;
case GRN_OBJ_TABLE_DAT_KEY :
+ table_type_name = "TABLE_DAT_KEY";
break;
case GRN_OBJ_TABLE_NO_KEY :
- if (key_type) {
- int key_name_size;
- char key_name[GRN_TABLE_MAX_KEY_SIZE];
- key_name_size = grn_obj_name(ctx, key_type, key_name,
- GRN_TABLE_MAX_KEY_SIZE);
- ERR(GRN_INVALID_ARGUMENT,
- "[table][create] "
- "key isn't available for no key table: <%.*s> (%.*s)",
- name_size, name, key_name_size, key_name);
- } else if (flags & GRN_OBJ_KEY_WITH_SIS) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][create] "
- "key with SIS isn't available for no key table: <%.*s>",
- name_size, name);
- } else if (flags & GRN_OBJ_KEY_NORMALIZE) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][create] "
- "key normalization isn't available for no key table: <%.*s>",
- name_size, name);
- }
+ table_type_name = "TABLE_NO_KEY";
+ break;
+ default :
+ table_type_name = "unknown";
break;
}
+
+ if (!key_type && table_type != GRN_OBJ_TABLE_NO_KEY &&
+ !(flags & GRN_OBJ_KEY_VAR_SIZE)) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][create] "
+ "key type is required for TABLE_HASH_KEY, TABLE_PAT_KEY or "
+ "TABLE_DAT_KEY: <%.*s>", name_size, name);
+ return ctx->rc;
+ }
+
+ if (key_type && table_type == GRN_OBJ_TABLE_NO_KEY) {
+ int key_name_size;
+ char key_name[GRN_TABLE_MAX_KEY_SIZE];
+ key_name_size = grn_obj_name(ctx, key_type, key_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][create] "
+ "key isn't available for TABLE_NO_KEY table: <%.*s> (%.*s)",
+ name_size, name, key_name_size, key_name);
+ return ctx->rc;
+ }
+
+ if ((flags & GRN_OBJ_KEY_WITH_SIS) &&
+ table_type != GRN_OBJ_TABLE_PAT_KEY) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][create] "
+ "key with SIS is available only for TABLE_PAT_KEY table: "
+ "<%.*s>(%s)",
+ name_size, name,
+ table_type_name);
+ return ctx->rc;
+ }
+
+ if ((flags & GRN_OBJ_KEY_NORMALIZE) &&
+ table_type == GRN_OBJ_TABLE_NO_KEY) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][create] "
+ "key normalization isn't available for TABLE_NO_KEY table: <%.*s>",
+ name_size, name);
+ return ctx->rc;
+ }
+
+ if ((flags & GRN_OBJ_KEY_LARGE) &&
+ table_type != GRN_OBJ_TABLE_HASH_KEY) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][create] "
+ "large key support is available only for TABLE_HASH_KEY key table: "
+ "<%.*s>(%s)",
+ name_size, name,
+ table_type_name);
+ return ctx->rc;
+ }
+
return ctx->rc;
}
static grn_obj *
grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name,
unsigned int name_size, const char *path,
- grn_obj_flags flags, grn_obj *key_type,
+ grn_table_flags flags, grn_obj *key_type,
grn_obj *value_type,
uint32_t max_n_subrecs,
uint32_t additional_value_size)
@@ -890,10 +1175,11 @@ grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name,
id = grn_obj_register(ctx, db, name, name_size);
if (ERRP(ctx, GRN_ERROR)) { return NULL; }
if (GRN_OBJ_PERSISTENT & flags) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "DDL:table_create %.*s", name_size, name);
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "DDL:%u:table_create %.*s", id, name_size, name);
if (!path) {
if (GRN_DB_PERSISTENT_P(db)) {
- gen_pathname(grn_obj_io(db)->path, buffer, id);
+ grn_db_generate_pathname(ctx, db, id, buffer);
path = buffer;
} else {
ERR(GRN_INVALID_ARGUMENT, "path not assigned for persistent table");
@@ -941,7 +1227,7 @@ grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name,
DB_OBJ(res)->subrec_offset = subrec_offset;
DB_OBJ(res)->flags.group = 0;
if (grn_db_obj_init(ctx, db, id, DB_OBJ(res))) {
- _grn_obj_remove(ctx, res);
+ _grn_obj_remove(ctx, res, GRN_FALSE);
res = NULL;
}
} else {
@@ -952,7 +1238,7 @@ grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name,
grn_obj *
grn_table_create(grn_ctx *ctx, const char *name, unsigned int name_size,
- const char *path, grn_obj_flags flags,
+ const char *path, grn_table_flags flags,
grn_obj *key_type, grn_obj *value_type)
{
grn_obj *res;
@@ -1123,19 +1409,8 @@ grn_table_lcp_search(grn_ctx *ctx, grn_obj *table, const void *key, unsigned int
GRN_API_RETURN(id);
}
-typedef struct {
- grn_id target;
- unsigned int section;
-} default_set_value_hook_data;
-
-struct _grn_hook {
- grn_hook *next;
- grn_proc *proc;
- uint32_t hld_size;
-};
-
-static grn_obj *
-default_set_value_hook(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+grn_obj *
+grn_obj_default_set_value_hook(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
grn_proc_ctx *pctx = (grn_proc_ctx *)user_data;
if (!pctx) {
@@ -1146,7 +1421,7 @@ default_set_value_hook(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *u
grn_obj *oldvalue = grn_ctx_pop(ctx);
grn_obj *id = grn_ctx_pop(ctx);
grn_hook *h = pctx->currh;
- default_set_value_hook_data *data = (void *)NEXT_ADDR(h);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(h);
grn_obj *target = grn_ctx_at(ctx, data->target);
int section = data->section;
if (flags) { /* todo */ }
@@ -1265,7 +1540,7 @@ grn_table_add(grn_ctx *ctx, grn_obj *table, const void *key, unsigned int key_si
if (hooks->proc) {
hooks->proc->funcs[PROC_INIT](ctx, 1, &table, &pctx.user_data);
} else {
- default_set_value_hook(ctx, 1, &table, &pctx.user_data);
+ grn_obj_default_set_value_hook(ctx, 1, &table, &pctx.user_data);
}
if (ctx->rc) { break; }
hooks = hooks->next;
@@ -1288,7 +1563,8 @@ grn_table_get_by_key(grn_ctx *ctx, grn_obj *table, grn_obj *key)
grn_obj buf;
GRN_OBJ_INIT(&buf, GRN_BULK, 0, table->header.domain);
if ((rc = grn_obj_cast(ctx, key, &buf, GRN_TRUE))) {
- ERR(rc, "cast failed");
+ grn_obj *domain = grn_ctx_at(ctx, table->header.domain);
+ ERR_CAST(table, domain, key);
} else {
id = grn_table_get(ctx, table, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
}
@@ -1308,7 +1584,8 @@ grn_table_add_by_key(grn_ctx *ctx, grn_obj *table, grn_obj *key, int *added)
grn_obj buf;
GRN_OBJ_INIT(&buf, GRN_BULK, 0, table->header.domain);
if ((rc = grn_obj_cast(ctx, key, &buf, GRN_TRUE))) {
- ERR(rc, "cast failed");
+ grn_obj *domain = grn_ctx_at(ctx, table->header.domain);
+ ERR_CAST(table, domain, key);
} else {
id = grn_table_add(ctx, table, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf), added);
}
@@ -1454,6 +1731,9 @@ grn_table_get_key(grn_ctx *ctx, grn_obj *table, grn_id id, void *keybuf, int buf
int r = 0;
GRN_API_ENTER;
if (table) {
+ if (table->header.type == GRN_DB) {
+ table = ((grn_db *)table)->keys;
+ }
switch (table->header.type) {
case GRN_TABLE_HASH_KEY :
r = grn_hash_get_key(ctx, (grn_hash *)table, id, keybuf, buf_size);
@@ -1487,6 +1767,9 @@ grn_table_get_key2(grn_ctx *ctx, grn_obj *table, grn_id id, grn_obj *bulk)
int r = 0;
GRN_API_ENTER;
if (table) {
+ if (table->header.type == GRN_DB) {
+ table = ((grn_db *)table)->keys;
+ }
switch (table->header.type) {
case GRN_TABLE_HASH_KEY :
r = grn_hash_get_key2(ctx, (grn_hash *)table, id, bulk);
@@ -1558,7 +1841,7 @@ call_delete_hook(grn_ctx *ctx, grn_obj *table, grn_id rid, const void *key, unsi
if (hooks->proc) {
hooks->proc->funcs[PROC_INIT](ctx, 1, &table, &pctx.user_data);
} else {
- default_set_value_hook(ctx, 1, &table, &pctx.user_data);
+ grn_obj_default_set_value_hook(ctx, 1, &table, &pctx.user_data);
}
if (ctx->rc) { break; }
hooks = hooks->next;
@@ -1593,7 +1876,7 @@ delete_reference_records_in_index(grn_ctx *ctx, grn_obj *table, grn_id id,
{
grn_ii *ii = (grn_ii *)index;
grn_ii_cursor *ii_cursor = NULL;
- grn_ii_posting *posting;
+ grn_posting *posting;
grn_obj source_ids;
unsigned int i, n_ids;
grn_obj sources;
@@ -1733,11 +2016,9 @@ delete_reference_records(grn_ctx *ctx, grn_obj *table, grn_id id)
continue;
}
if (col->header.type != GRN_COLUMN_INDEX) {
- grn_obj_unlink(ctx, col);
continue;
}
delete_reference_records_in_index(ctx, table, id, col);
- grn_obj_unlink(ctx, col);
if (ctx->rc != GRN_SUCCESS) {
break;
}
@@ -1874,7 +2155,7 @@ grn_table_delete_by_id(grn_ctx *ctx, grn_obj *table, grn_id id)
grn_rc rc;
grn_io *io;
GRN_API_ENTER;
- if ((io = grn_obj_io(table)) && !(io->flags & GRN_IO_TEMPORARY)) {
+ if ((io = grn_obj_get_io(ctx, table)) && !(io->flags & GRN_IO_TEMPORARY)) {
if (!(rc = grn_io_lock(ctx, io, grn_lock_timeout))) {
rc = _grn_table_delete_by_id(ctx, table, id, NULL);
grn_io_unlock(io);
@@ -1888,7 +2169,6 @@ grn_table_delete_by_id(grn_ctx *ctx, grn_obj *table, grn_id id)
GRN_API_RETURN(rc);
}
-grn_rc grn_ii_truncate(grn_ctx *ctx, grn_ii *ii);
grn_rc grn_ja_truncate(grn_ctx *ctx, grn_ja *ja);
grn_rc grn_ra_truncate(grn_ctx *ctx, grn_ra *ra);
@@ -1905,7 +2185,7 @@ grn_column_truncate(grn_ctx *ctx, grn_obj *column)
break;
case GRN_COLUMN_VAR_SIZE :
for (hooks = DB_OBJ(column)->hooks[GRN_HOOK_SET]; hooks; hooks = hooks->next) {
- default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
grn_obj *target = grn_ctx_at(ctx, data->target);
if (target->header.type != GRN_COLUMN_INDEX) { continue; }
if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
@@ -1914,7 +2194,7 @@ grn_column_truncate(grn_ctx *ctx, grn_obj *column)
break;
case GRN_COLUMN_FIX_SIZE :
for (hooks = DB_OBJ(column)->hooks[GRN_HOOK_SET]; hooks; hooks = hooks->next) {
- default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
grn_obj *target = grn_ctx_at(ctx, data->target);
if (target->header.type != GRN_COLUMN_INDEX) { continue; }
if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
@@ -1960,7 +2240,7 @@ grn_table_truncate(grn_ctx *ctx, grn_obj *table)
switch (table->header.type) {
case GRN_TABLE_PAT_KEY :
for (hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT]; hooks; hooks = hooks->next) {
- default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
grn_obj *target = grn_ctx_at(ctx, data->target);
if (target->header.type != GRN_COLUMN_INDEX) { continue; }
if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
@@ -1969,7 +2249,7 @@ grn_table_truncate(grn_ctx *ctx, grn_obj *table)
break;
case GRN_TABLE_DAT_KEY :
for (hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT]; hooks; hooks = hooks->next) {
- default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
grn_obj *target = grn_ctx_at(ctx, data->target);
if (target->header.type != GRN_COLUMN_INDEX) { continue; }
if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
@@ -1978,7 +2258,7 @@ grn_table_truncate(grn_ctx *ctx, grn_obj *table)
break;
case GRN_TABLE_HASH_KEY :
for (hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT]; hooks; hooks = hooks->next) {
- default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
grn_obj *target = grn_ctx_at(ctx, data->target);
if (target->header.type != GRN_COLUMN_INDEX) { continue; }
if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
@@ -2004,7 +2284,7 @@ exit :
}
grn_rc
-grn_table_get_info(grn_ctx *ctx, grn_obj *table, grn_obj_flags *flags,
+grn_table_get_info(grn_ctx *ctx, grn_obj *table, grn_table_flags *flags,
grn_encoding *encoding, grn_obj **tokenizer,
grn_obj **normalizer,
grn_obj **token_filters)
@@ -2014,7 +2294,7 @@ grn_table_get_info(grn_ctx *ctx, grn_obj *table, grn_obj_flags *flags,
if (table) {
switch (table->header.type) {
case GRN_TABLE_PAT_KEY :
- if (flags) { *flags = ((grn_pat *)table)->obj.header.flags; }
+ if (flags) { *flags = ((grn_pat *)table)->header->flags; }
if (encoding) { *encoding = ((grn_pat *)table)->encoding; }
if (tokenizer) { *tokenizer = ((grn_pat *)table)->tokenizer; }
if (normalizer) { *normalizer = ((grn_pat *)table)->normalizer; }
@@ -2022,7 +2302,7 @@ grn_table_get_info(grn_ctx *ctx, grn_obj *table, grn_obj_flags *flags,
rc = GRN_SUCCESS;
break;
case GRN_TABLE_DAT_KEY :
- if (flags) { *flags = ((grn_dat *)table)->obj.header.flags; }
+ if (flags) { *flags = ((grn_dat *)table)->header->flags; }
if (encoding) { *encoding = ((grn_dat *)table)->encoding; }
if (tokenizer) { *tokenizer = ((grn_dat *)table)->tokenizer; }
if (normalizer) { *normalizer = ((grn_dat *)table)->normalizer; }
@@ -2030,7 +2310,7 @@ grn_table_get_info(grn_ctx *ctx, grn_obj *table, grn_obj_flags *flags,
rc = GRN_SUCCESS;
break;
case GRN_TABLE_HASH_KEY :
- if (flags) { *flags = ((grn_hash *)table)->obj.header.flags; }
+ if (flags) { *flags = ((grn_hash *)table)->header.common->flags; }
if (encoding) { *encoding = ((grn_hash *)table)->encoding; }
if (tokenizer) { *tokenizer = ((grn_hash *)table)->tokenizer; }
if (normalizer) { *normalizer = ((grn_hash *)table)->normalizer; }
@@ -2038,9 +2318,9 @@ grn_table_get_info(grn_ctx *ctx, grn_obj *table, grn_obj_flags *flags,
rc = GRN_SUCCESS;
break;
case GRN_TABLE_NO_KEY :
- if (flags) { *flags = 0; }
+ if (flags) { *flags = grn_array_get_flags(ctx, ((grn_array *)table)); }
if (encoding) { *encoding = GRN_ENC_NONE; }
- if (tokenizer) { *tokenizer = grn_tokenizer_uvector; }
+ if (tokenizer) { *tokenizer = NULL; }
if (normalizer) { *normalizer = NULL; }
if (token_filters) { *token_filters = NULL; }
rc = GRN_SUCCESS;
@@ -2067,10 +2347,10 @@ grn_table_size(grn_ctx *ctx, grn_obj *table)
n = grn_dat_size(ctx, (grn_dat *)table);
break;
case GRN_TABLE_HASH_KEY :
- n = GRN_HASH_SIZE((grn_hash *)table);
+ n = grn_hash_size(ctx, (grn_hash *)table);
break;
case GRN_TABLE_NO_KEY :
- n = GRN_ARRAY_SIZE((grn_array *)table);
+ n = grn_array_size(ctx, (grn_array *)table);
break;
default :
ERR(GRN_INVALID_ARGUMENT, "not supported");
@@ -2185,12 +2465,12 @@ grn_table_cursor_open(grn_ctx *ctx, grn_obj *table,
"can't use negative offset with GRN_CURSOR_PREFIX: %d", offset);
} else if (offset != 0 && offset >= table_size) {
ERR(GRN_TOO_LARGE_OFFSET,
- "offset is rather than table size: offset:%d, table_size:%d",
+ "offset is not less than table size: offset:%d, table_size:%d",
offset, table_size);
} else {
if (limit < -1) {
ERR(GRN_TOO_SMALL_LIMIT,
- "can't use small limit rather than -1 with GRN_CURSOR_PREFIX: %d",
+ "can't use smaller limit than -1 with GRN_CURSOR_PREFIX: %d",
limit);
} else if (limit == -1) {
limit = table_size;
@@ -2298,11 +2578,12 @@ grn_table_cursor_open_by_id(grn_ctx *ctx, grn_obj *table,
grn_rc
grn_table_cursor_close(grn_ctx *ctx, grn_table_cursor *tc)
{
+ const char *tag = "[table][cursor][close]";
grn_rc rc = GRN_SUCCESS;
GRN_API_ENTER;
if (!tc) {
- ERR(GRN_INVALID_ARGUMENT, "tc is null");
rc = GRN_INVALID_ARGUMENT;
+ ERR(rc, "%s invalid cursor", tag);
} else {
{
if (DB_OBJ(tc)->finalizer) {
@@ -2334,6 +2615,7 @@ grn_table_cursor_close(grn_ctx *ctx, grn_table_cursor *tc)
break;
default :
rc = GRN_INVALID_ARGUMENT;
+ ERR(rc, "%s invalid type %d", tag, tc->header.type);
break;
}
}
@@ -2343,9 +2625,10 @@ grn_table_cursor_close(grn_ctx *ctx, grn_table_cursor *tc)
inline static grn_id
grn_table_cursor_next_inline(grn_ctx *ctx, grn_table_cursor *tc)
{
+ const char *tag = "[table][cursor][next]";
grn_id id = GRN_ID_NIL;
if (!tc) {
- ERR(GRN_INVALID_ARGUMENT, "tc is null");
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid cursor", tag);
} else {
switch (tc->header.type) {
case GRN_CURSOR_TABLE_PAT_KEY :
@@ -2366,6 +2649,9 @@ grn_table_cursor_next_inline(grn_ctx *ctx, grn_table_cursor *tc)
if (ip) { id = ip->rid; }
}
break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
+ break;
}
}
return id;
@@ -2383,10 +2669,11 @@ grn_table_cursor_next(grn_ctx *ctx, grn_table_cursor *tc)
int
grn_table_cursor_get_key(grn_ctx *ctx, grn_table_cursor *tc, void **key)
{
+ const char *tag = "[table][cursor][get-key]";
int len = 0;
GRN_API_ENTER;
if (!tc) {
- ERR(GRN_INVALID_ARGUMENT, "tc is null");
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid cursor", tag);
} else {
switch (tc->header.type) {
case GRN_CURSOR_TABLE_PAT_KEY :
@@ -2399,7 +2686,7 @@ grn_table_cursor_get_key(grn_ctx *ctx, grn_table_cursor *tc, void **key)
len = grn_hash_cursor_get_key(ctx, (grn_hash_cursor *)tc, key);
break;
default :
- ERR(GRN_INVALID_ARGUMENT, "invalid type %d", tc->header.type);
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
break;
}
}
@@ -2409,9 +2696,10 @@ grn_table_cursor_get_key(grn_ctx *ctx, grn_table_cursor *tc, void **key)
inline static int
grn_table_cursor_get_value_inline(grn_ctx *ctx, grn_table_cursor *tc, void **value)
{
+ const char *tag = "[table][cursor][get-value]";
int len = 0;
if (!tc) {
- ERR(GRN_INVALID_ARGUMENT, "tc is null");
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid cursor", tag);
} else {
switch (tc->header.type) {
case GRN_CURSOR_TABLE_PAT_KEY :
@@ -2428,7 +2716,7 @@ grn_table_cursor_get_value_inline(grn_ctx *ctx, grn_table_cursor *tc, void **val
len = grn_array_cursor_get_value(ctx, (grn_array_cursor *)tc, value);
break;
default :
- ERR(GRN_INVALID_ARGUMENT, "invalid type %d", tc->header.type);
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
break;
}
}
@@ -2448,10 +2736,11 @@ grn_rc
grn_table_cursor_set_value(grn_ctx *ctx, grn_table_cursor *tc,
const void *value, int flags)
{
+ const char *tag = "[table][cursor][set-value]";
grn_rc rc = GRN_INVALID_ARGUMENT;
GRN_API_ENTER;
if (!tc) {
- ERR(GRN_INVALID_ARGUMENT, "tc is null");
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid cursor", tag);
} else {
switch (tc->header.type) {
case GRN_CURSOR_TABLE_PAT_KEY :
@@ -2467,7 +2756,7 @@ grn_table_cursor_set_value(grn_ctx *ctx, grn_table_cursor *tc,
rc = grn_array_cursor_set_value(ctx, (grn_array_cursor *)tc, value, flags);
break;
default :
- ERR(GRN_INVALID_ARGUMENT, "invalid type %d", tc->header.type);
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
break;
}
}
@@ -2477,10 +2766,11 @@ grn_table_cursor_set_value(grn_ctx *ctx, grn_table_cursor *tc,
grn_rc
grn_table_cursor_delete(grn_ctx *ctx, grn_table_cursor *tc)
{
+ const char *tag = "[table][cursor][delete]";
grn_rc rc = GRN_INVALID_ARGUMENT;
GRN_API_ENTER;
if (!tc) {
- ERR(GRN_INVALID_ARGUMENT, "tc is null");
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid cursor", tag);
} else {
grn_id id;
grn_obj *table;
@@ -2529,7 +2819,7 @@ grn_table_cursor_delete(grn_ctx *ctx, grn_table_cursor *tc)
}
break;
default :
- ERR(GRN_INVALID_ARGUMENT, "invalid type %d", tc->header.type);
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
break;
}
}
@@ -2540,10 +2830,11 @@ exit :
grn_obj *
grn_table_cursor_table(grn_ctx *ctx, grn_table_cursor *tc)
{
+ const char *tag = "[table][cursor][table]";
grn_obj *obj = NULL;
GRN_API_ENTER;
if (!tc) {
- ERR(GRN_INVALID_ARGUMENT, "tc is null");
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid cursor", tag);
} else {
switch (tc->header.type) {
case GRN_CURSOR_TABLE_PAT_KEY :
@@ -2559,7 +2850,7 @@ grn_table_cursor_table(grn_ctx *ctx, grn_table_cursor *tc)
obj = (grn_obj *)(((grn_array_cursor *)tc)->array);
break;
default :
- ERR(GRN_INVALID_ARGUMENT, "invalid type %d", tc->header.type);
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
break;
}
}
@@ -2605,7 +2896,7 @@ grn_index_cursor_open(grn_ctx *ctx, grn_table_cursor *tc,
grn_posting *
grn_index_cursor_next(grn_ctx *ctx, grn_obj *c, grn_id *tid)
{
- grn_ii_posting *ip = NULL;
+ grn_posting *ip = NULL;
grn_index_cursor *ic = (grn_index_cursor *)c;
GRN_API_ENTER;
if (ic->iic) {
@@ -2764,6 +3055,44 @@ grn_table_search(grn_ctx *ctx, grn_obj *table, const void *key, uint32_t key_siz
GRN_API_RETURN(rc);
}
+grn_rc
+grn_table_fuzzy_search(grn_ctx *ctx, grn_obj *table, const void *key, uint32_t key_size,
+ grn_fuzzy_search_optarg *args, grn_obj *res, grn_operator op)
+{
+ grn_rc rc = GRN_SUCCESS;
+ GRN_API_ENTER;
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ {
+ grn_pat *pat = (grn_pat *)table;
+ if (!grn_table_size(ctx, res) && op == GRN_OP_OR) {
+ WITH_NORMALIZE(pat, key, key_size, {
+ rc = grn_pat_fuzzy_search(ctx, pat, key, key_size,
+ args, (grn_hash *)res);
+ });
+ } else {
+ grn_obj *hash;
+ hash = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ table, NULL);
+ WITH_NORMALIZE(pat, key, key_size, {
+ rc = grn_pat_fuzzy_search(ctx, pat, key, key_size,
+ args, (grn_hash *)hash);
+ });
+ if (rc == GRN_SUCCESS) {
+ rc = grn_table_setoperation(ctx, res, hash, res, op);
+ }
+ grn_obj_unlink(ctx, hash);
+ }
+ }
+ break;
+ default :
+ rc = GRN_OPERATION_NOT_SUPPORTED;
+ break;
+ }
+ GRN_API_RETURN(rc);
+}
+
grn_id
grn_table_next(grn_ctx *ctx, grn_obj *table, grn_id id)
{
@@ -2790,8 +3119,7 @@ grn_table_next(grn_ctx *ctx, grn_obj *table, grn_id id)
static grn_rc
grn_accessor_resolve_one_index_column(grn_ctx *ctx, grn_accessor *accessor,
- grn_obj *current_res, grn_obj **next_res,
- grn_search_optarg *optarg)
+ grn_obj *current_res, grn_obj **next_res)
{
grn_rc rc = GRN_SUCCESS;
grn_obj *column = NULL;
@@ -2842,7 +3170,7 @@ grn_accessor_resolve_one_index_column(grn_ctx *ctx, grn_accessor *accessor,
{
grn_obj_flags column_value_flags = 0;
grn_obj column_value;
- grn_ii_posting add_posting;
+ grn_posting add_posting;
grn_id *tid;
grn_rset_recinfo *recinfo;
@@ -2893,21 +3221,121 @@ grn_accessor_resolve_one_index_column(grn_ctx *ctx, grn_accessor *accessor,
}
static grn_rc
+grn_accessor_resolve_one_table(grn_ctx *ctx, grn_accessor *accessor,
+ grn_obj *current_res, grn_obj **next_res)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *table;
+
+ table = accessor->obj;
+ *next_res = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ table, NULL);
+ if (!*next_res) {
+ return ctx->rc;
+ }
+
+ grn_report_table(ctx,
+ "[accessor][resolve]",
+ "",
+ table);
+
+ {
+ grn_posting posting;
+
+ memset(&posting, 0, sizeof(posting));
+ GRN_HASH_EACH_BEGIN(ctx, (grn_hash *)current_res, cursor, id) {
+ void *key;
+ void *value;
+ grn_id *record_id;
+ grn_rset_recinfo *recinfo;
+ grn_id next_record_id;
+
+ grn_hash_cursor_get_key_value(ctx, cursor, &key, NULL, &value);
+ record_id = key;
+ recinfo = value;
+ next_record_id = grn_table_get(ctx,
+ table,
+ record_id,
+ sizeof(grn_id));
+ if (next_record_id == GRN_ID_NIL) {
+ continue;
+ }
+
+ posting.rid = next_record_id;
+ posting.weight = recinfo->score;
+ rc = grn_ii_posting_add(ctx,
+ &posting,
+ (grn_hash *)*next_res,
+ GRN_OP_OR);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
+ }
+
+ if (rc != GRN_SUCCESS) {
+ grn_obj_unlink(ctx, *next_res);
+ }
+
+ return rc;
+}
+
+static grn_rc
grn_accessor_resolve_one_data_column(grn_ctx *ctx, grn_accessor *accessor,
- grn_obj *current_res, grn_obj **next_res,
- grn_search_optarg *optarg)
+ grn_obj *current_res, grn_obj **next_res)
{
grn_rc rc = GRN_SUCCESS;
- grn_obj *index = NULL;
- grn_operator index_op = GRN_OP_MATCH;
+ grn_index_datum index_datum;
+ unsigned int n_index_data;
grn_id next_res_domain_id = GRN_ID_NIL;
- if (grn_column_index(ctx, accessor->obj, index_op, &index, 1, NULL) == 0) {
+ n_index_data = grn_column_get_all_index_data(ctx,
+ accessor->obj,
+ &index_datum,
+ 1);
+ if (n_index_data == 0) {
return GRN_INVALID_ARGUMENT;
}
- next_res_domain_id = DB_OBJ(index)->range;
{
+ grn_obj *lexicon;
+ lexicon = grn_ctx_at(ctx, index_datum.index->header.domain);
+ if (grn_obj_id(ctx, lexicon) != current_res->header.domain) {
+ char index_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_name_size;
+ grn_obj *expected;
+ char expected_name[GRN_TABLE_MAX_KEY_SIZE];
+ int expected_name_size;
+
+ index_name_size = grn_obj_name(ctx,
+ index_datum.index,
+ index_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ expected = grn_ctx_at(ctx, current_res->header.domain);
+ expected_name_size = grn_obj_name(ctx,
+ expected,
+ expected_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[accessor][resolve][data-column] lexicon mismatch index: "
+ "<%.*s> "
+ "expected:<%.*s>",
+ index_name_size,
+ index_name,
+ expected_name_size,
+ expected_name);
+ return ctx->rc;
+ }
+ }
+
+ next_res_domain_id = DB_OBJ(index_datum.index)->range;
+
+ grn_report_index(ctx,
+ "[accessor][resolve][data-column]",
+ "",
+ index_datum.index);
+ {
grn_rc rc;
grn_obj *next_res_domain = grn_ctx_at(ctx, next_res_domain_id);
*next_res = grn_table_create(ctx, NULL, 0, NULL,
@@ -2925,9 +3353,9 @@ grn_accessor_resolve_one_data_column(grn_ctx *ctx, grn_accessor *accessor,
grn_rset_recinfo *recinfo;
GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, {
- grn_ii *ii = (grn_ii *)index;
+ grn_ii *ii = (grn_ii *)(index_datum.index);
grn_ii_cursor *ii_cursor;
- grn_ii_posting *posting;
+ grn_posting *posting;
ii_cursor = grn_ii_cursor_open(ctx, ii, *tid,
GRN_ID_NIL, GRN_ID_MAX,
@@ -2938,7 +3366,13 @@ grn_accessor_resolve_one_data_column(grn_ctx *ctx, grn_accessor *accessor,
}
while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) {
- grn_ii_posting add_posting = *posting;
+ grn_posting add_posting;
+
+ if (index_datum.section > 0 && posting->sid != index_datum.section) {
+ continue;
+ }
+
+ add_posting = *posting;
add_posting.weight += recinfo->score - 1;
rc = grn_ii_posting_add(ctx,
&add_posting,
@@ -2965,8 +3399,8 @@ grn_accessor_resolve_one_data_column(grn_ctx *ctx, grn_accessor *accessor,
grn_rc
grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep,
- grn_obj *base_res, grn_obj **res,
- grn_search_optarg *optarg)
+ grn_obj *base_res, grn_obj *res,
+ grn_operator op)
{
grn_rc rc = GRN_SUCCESS;
grn_accessor *a;
@@ -2990,12 +3424,13 @@ grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep,
a = (grn_accessor *)GRN_PTR_VALUE_AT(&accessor_stack, i - 1);
if (a->obj->header.type == GRN_COLUMN_INDEX) {
rc = grn_accessor_resolve_one_index_column(ctx, a,
- current_res, &next_res,
- optarg);
+ current_res, &next_res);
+ } else if (grn_obj_is_table(ctx, a->obj)) {
+ rc = grn_accessor_resolve_one_table(ctx, a,
+ current_res, &next_res);
} else {
rc = grn_accessor_resolve_one_data_column(ctx, a,
- current_res, &next_res,
- optarg);
+ current_res, &next_res);
}
if (current_res != base_res) {
@@ -3010,9 +3445,19 @@ grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep,
}
if (rc == GRN_SUCCESS && current_res != base_res) {
- *res = current_res;
+ grn_id *record_id;
+ grn_rset_recinfo *recinfo;
+ GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &record_id, NULL, &recinfo, {
+ grn_posting posting;
+ posting.rid = *record_id;
+ posting.sid = 1;
+ posting.pos = 0;
+ posting.weight = recinfo->score - 1;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
+ });
+ grn_obj_unlink(ctx, current_res);
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
} else {
- *res = NULL;
if (rc == GRN_SUCCESS) {
rc = GRN_INVALID_ARGUMENT;
}
@@ -3022,6 +3467,12 @@ grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep,
return rc;
}
+static inline void
+grn_obj_search_index_report(grn_ctx *ctx, const char *tag, grn_obj *index)
+{
+ grn_report_index(ctx, "[object][search]", tag, index);
+}
+
static inline grn_rc
grn_obj_search_accessor(grn_ctx *ctx, grn_obj *obj, grn_obj *query,
grn_obj *res, grn_operator op, grn_search_optarg *optarg)
@@ -3059,7 +3510,6 @@ grn_obj_search_accessor(grn_ctx *ctx, grn_obj *obj, grn_obj *query,
rc = grn_obj_search(ctx, index, query, res, op, optarg);
} else {
grn_obj *base_res;
- grn_obj *resolve_res = NULL;
grn_obj *range = grn_ctx_at(ctx, DB_OBJ(index)->range);
base_res = grn_table_create(ctx, NULL, 0, NULL,
GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
@@ -3070,28 +3520,15 @@ grn_obj_search_accessor(grn_ctx *ctx, grn_obj *obj, grn_obj *query,
if (!base_res) {
goto exit;
}
+ if (optarg) {
+ optarg->match_info.min = GRN_ID_NIL;
+ }
rc = grn_obj_search(ctx, index, query, base_res, GRN_OP_OR, optarg);
if (rc != GRN_SUCCESS) {
grn_obj_unlink(ctx, base_res);
goto exit;
}
- rc = grn_accessor_resolve(ctx, obj, n_accessors - 1, base_res,
- &resolve_res, optarg);
- if (resolve_res) {
- grn_id *record_id;
- grn_rset_recinfo *recinfo;
- GRN_HASH_EACH(ctx, (grn_hash *)resolve_res, id, &record_id, NULL,
- &recinfo, {
- grn_ii_posting posting;
- posting.rid = *record_id;
- posting.sid = 1;
- posting.pos = 0;
- posting.weight = recinfo->score - 1;
- grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
- });
- grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
- grn_obj_unlink(ctx, resolve_res);
- }
+ rc = grn_accessor_resolve(ctx, obj, n_accessors - 1, base_res, res, op);
grn_obj_unlink(ctx, base_res);
}
}
@@ -3106,10 +3543,14 @@ grn_obj_search_column_index_by_id(grn_ctx *ctx, grn_obj *obj,
grn_obj *res, grn_operator op,
grn_search_optarg *optarg)
{
- grn_ii_cursor *c = grn_ii_cursor_open(ctx, (grn_ii *)obj, tid,
- GRN_ID_NIL, GRN_ID_MAX, 1, 0);
+ grn_ii_cursor *c;
+
+ grn_obj_search_index_report(ctx, "[id]", obj);
+
+ c = grn_ii_cursor_open(ctx, (grn_ii *)obj, tid,
+ GRN_ID_NIL, GRN_ID_MAX, 1, 0);
if (c) {
- grn_ii_posting *pos;
+ grn_posting *pos;
grn_hash *s = (grn_hash *)res;
while ((pos = grn_ii_cursor_next(ctx, c))) {
/* todo: support orgarg(op)
@@ -3157,6 +3598,40 @@ grn_obj_search_column_index_by_key(grn_ctx *ctx, grn_obj *obj,
key_len = GRN_BULK_VSIZE(query);
}
if (rc == GRN_SUCCESS) {
+ if (grn_logger_pass(ctx, GRN_REPORT_INDEX_LOG_LEVEL)) {
+ const char *tag;
+ if (optarg) {
+ switch (optarg->mode) {
+ case GRN_OP_MATCH :
+ tag = "[key][match]";
+ break;
+ case GRN_OP_EXACT :
+ tag = "[key][exact]";
+ break;
+ case GRN_OP_NEAR :
+ tag = "[key][near]";
+ break;
+ case GRN_OP_NEAR2 :
+ tag = "[key][near2]";
+ break;
+ case GRN_OP_SIMILAR :
+ tag = "[key][similar]";
+ break;
+ case GRN_OP_REGEXP :
+ tag = "[key][regexp]";
+ break;
+ case GRN_OP_FUZZY :
+ tag = "[key][fuzzy]";
+ break;
+ default :
+ tag = "[key][unknown]";
+ break;
+ }
+ } else {
+ tag = "[key][exact]";
+ }
+ grn_obj_search_index_report(ctx, tag, obj);
+ }
rc = grn_ii_sel(ctx, (grn_ii *)obj, key, key_len,
(grn_hash *)res, op, optarg);
}
@@ -3213,7 +3688,43 @@ grn_obj_search(grn_ctx *ctx, grn_obj *obj, grn_obj *query,
uint32_t key_size = GRN_BULK_VSIZE(query);
grn_operator mode = optarg ? optarg->mode : GRN_OP_EXACT;
if (key && key_size) {
- rc = grn_table_search(ctx, obj, key, key_size, mode, res, op);
+ if (grn_logger_pass(ctx, GRN_REPORT_INDEX_LOG_LEVEL)) {
+ const char *tag;
+ if (optarg) {
+ switch (optarg->mode) {
+ case GRN_OP_EXACT :
+ tag = "[table][exact]";
+ break;
+ case GRN_OP_LCP :
+ tag = "[table][lcp]";
+ break;
+ case GRN_OP_SUFFIX :
+ tag = "[table][suffix]";
+ break;
+ case GRN_OP_PREFIX :
+ tag = "[table][prefix]";
+ break;
+ case GRN_OP_TERM_EXTRACT :
+ tag = "[table][term-extract]";
+ break;
+ case GRN_OP_FUZZY :
+ tag = "[table][fuzzy]";
+ break;
+ default :
+ tag = "[table][unknown]";
+ break;
+ }
+ } else {
+ tag = "[table][exact]";
+ }
+ grn_obj_search_index_report(ctx, tag, obj);
+ }
+ if (optarg && optarg->mode == GRN_OP_FUZZY) {
+ rc = grn_table_fuzzy_search(ctx, obj, key, key_size,
+ &(optarg->fuzzy), res, op);
+ } else {
+ rc = grn_table_search(ctx, obj, key, key_size, mode, res, op);
+ }
}
}
break;
@@ -3389,20 +3900,36 @@ grn_table_group_single_key_records(grn_ctx *ctx, grn_obj *table,
switch (bulk.header.type) {
case GRN_UVECTOR :
{
- // todo : support objects except grn_id
- grn_id *v = (grn_id *)GRN_BULK_HEAD(&bulk);
- grn_id *ve = (grn_id *)GRN_BULK_CURR(&bulk);
- while (v < ve) {
- if ((*v != GRN_ID_NIL) &&
- grn_table_add_v_inline(ctx, res,
- v, sizeof(grn_id), &value, NULL)) {
- grn_table_group_add_subrec(ctx, res, value,
- ri ? ri->score : 0,
- (grn_rset_posinfo *)&id, 0,
- calc_target,
- &value_buffer);
+ grn_bool is_reference;
+ unsigned int element_size;
+ uint8_t *elements;
+ int i, n_elements;
+
+ is_reference = !grn_type_id_is_builtin(ctx, bulk.header.type);
+
+ element_size = grn_uvector_element_size(ctx, &bulk);
+ elements = GRN_BULK_HEAD(&bulk);
+ n_elements = GRN_BULK_VSIZE(&bulk) / element_size;
+ for (i = 0; i < n_elements; i++) {
+ uint8_t *element = elements + (element_size * i);
+
+ if (is_reference) {
+ grn_id id = *((grn_id *)element);
+ if (id == GRN_ID_NIL) {
+ continue;
+ }
}
- v++;
+
+ if (!grn_table_add_v_inline(ctx, res, element, element_size,
+ &value, NULL)) {
+ continue;
+ }
+
+ grn_table_group_add_subrec(ctx, res, value,
+ ri ? ri->score : 0,
+ (grn_rset_posinfo *)&id, 0,
+ calc_target,
+ &value_buffer);
}
}
break;
@@ -3448,7 +3975,45 @@ grn_table_group_single_key_records(grn_ctx *ctx, grn_obj *table,
}
grn_table_cursor_close(ctx, tc);
}
- grn_obj_close(ctx, &bulk);
+ GRN_OBJ_FIN(ctx, &value_buffer);
+ GRN_OBJ_FIN(ctx, &bulk);
+}
+
+#define GRN_TABLE_GROUP_ALL_NAME "_all"
+#define GRN_TABLE_GROUP_ALL_NAME_LEN (sizeof(GRN_TABLE_GROUP_ALL_NAME) - 1)
+
+static void
+grn_table_group_all_records(grn_ctx *ctx, grn_obj *table,
+ grn_table_group_result *result)
+{
+ grn_obj value_buffer;
+ grn_table_cursor *tc;
+ grn_obj *res = result->table;
+ grn_obj *calc_target = result->calc_target;
+
+ GRN_VOID_INIT(&value_buffer);
+ if ((tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, 0))) {
+ grn_id id;
+ void *value;
+ if (grn_table_add_v_inline(ctx, res,
+ GRN_TABLE_GROUP_ALL_NAME,
+ GRN_TABLE_GROUP_ALL_NAME_LEN,
+ &value, NULL)) {
+ while ((id = grn_table_cursor_next_inline(ctx, tc))) {
+ grn_rset_recinfo *ri = NULL;
+ if (DB_OBJ(table)->header.flags & GRN_OBJ_WITH_SUBREC) {
+ grn_table_cursor_get_value_inline(ctx, tc, (void **)&ri);
+ }
+ grn_table_group_add_subrec(ctx, res, value,
+ ri ? ri->score : 0,
+ (grn_rset_posinfo *)&id, 0,
+ calc_target,
+ &value_buffer);
+ }
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+ GRN_OBJ_FIN(ctx, &value_buffer);
}
grn_rc
@@ -3817,7 +4382,10 @@ grn_table_group(grn_ctx *ctx, grn_obj *table,
grn_table_group_result *results, int n_results)
{
grn_rc rc = GRN_SUCCESS;
- if (!table || !n_keys || !n_results) {
+ grn_bool group_by_all_records = GRN_FALSE;
+ if (n_keys == 0 && n_results == 1) {
+ group_by_all_records = GRN_TRUE;
+ } else if (!table || !n_keys || !n_results) {
ERR(GRN_INVALID_ARGUMENT, "table or n_keys or n_results is void");
return GRN_INVALID_ARGUMENT;
}
@@ -3834,14 +4402,16 @@ grn_table_group(grn_ctx *ctx, grn_obj *table,
}
for (r = 0, rp = results; r < n_results; r++, rp++) {
if (!rp->table) {
- grn_obj_flags flags;
+ grn_table_flags flags;
grn_obj *key_type = NULL;
uint32_t additional_value_size;
flags = GRN_TABLE_HASH_KEY|
GRN_OBJ_WITH_SUBREC|
GRN_OBJ_UNIT_USERDEF_DOCUMENT;
- if (n_keys == 1) {
+ if (group_by_all_records) {
+ key_type = grn_ctx_at(ctx, GRN_DB_SHORT_TEXT);
+ } else if (n_keys == 1) {
key_type = grn_ctx_at(ctx, grn_obj_get_range(ctx, keys[0].key));
} else {
flags |= GRN_OBJ_KEY_VAR_SIZE;
@@ -3862,7 +4432,9 @@ grn_table_group(grn_ctx *ctx, grn_obj *table,
DB_OBJ(rp->table)->flags.group = rp->flags;
}
}
- if (n_keys == 1 && n_results == 1) {
+ if (group_by_all_records) {
+ grn_table_group_all_records(ctx, table, results);
+ } else if (n_keys == 1 && n_results == 1) {
if (!accelerated_table_group(ctx, table, keys->key, results)) {
grn_table_group_single_key_records(ctx, table, keys->key, results);
}
@@ -3899,18 +4471,34 @@ grn_rc
grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj *res,
grn_operator op)
{
- grn_rc rc = GRN_SUCCESS;
void *key = NULL, *value1 = NULL, *value2 = NULL;
uint32_t value_size = 0;
uint32_t key_size = 0;
grn_bool have_subrec;
+
+ GRN_API_ENTER;
+ if (!table1) {
+ ERR(GRN_INVALID_ARGUMENT, "[table][setoperation] table1 is NULL");
+ GRN_API_RETURN(ctx->rc);
+ }
+ if (!table2) {
+ ERR(GRN_INVALID_ARGUMENT, "[table][setoperation] table2 is NULL");
+ GRN_API_RETURN(ctx->rc);
+ }
+ if (!res) {
+ ERR(GRN_INVALID_ARGUMENT, "[table][setoperation] result table is NULL");
+ GRN_API_RETURN(ctx->rc);
+ }
+
if (table1 != res) {
if (table2 == res) {
grn_obj *t = table1;
table1 = table2;
table2 = t;
} else {
- return GRN_INVALID_ARGUMENT;
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][setoperation] table1 or table2 must be result table");
+ GRN_API_RETURN(ctx->rc);
}
}
have_subrec = ((DB_OBJ(table1)->header.flags & GRN_OBJ_WITH_SUBREC) &&
@@ -3997,16 +4585,26 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj *
});
break;
case GRN_OP_ADJUST :
- GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
- if (grn_table_get_v(ctx, table1, key, key_size, &value1)) {
- grn_memcpy(value1, value2, value_size);
- }
- });
+ if (have_subrec) {
+ GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
+ if (grn_table_get_v(ctx, table1, key, key_size, &value1)) {
+ grn_rset_recinfo *ri1 = value1;
+ grn_rset_recinfo *ri2 = value2;
+ ri1->score += ri2->score;
+ }
+ });
+ } else {
+ GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
+ if (grn_table_get_v(ctx, table1, key, key_size, &value1)) {
+ grn_memcpy(value1, value2, value_size);
+ }
+ });
+ }
break;
default :
break;
}
- return rc;
+ GRN_API_RETURN(ctx->rc);
}
grn_rc
@@ -4042,20 +4640,34 @@ static grn_obj *grn_obj_get_accessor(grn_ctx *ctx, grn_obj *obj,
static grn_obj *
grn_obj_column_(grn_ctx *ctx, grn_obj *table, const char *name, unsigned int name_size)
{
+ grn_id table_id = DB_OBJ(table)->id;
grn_obj *column = NULL;
- char buf[GRN_TABLE_MAX_KEY_SIZE];
- int len = grn_obj_name(ctx, table, buf, GRN_TABLE_MAX_KEY_SIZE);
- if (len) {
- buf[len++] = GRN_DB_DELIMITER;
- if (len + name_size <= GRN_TABLE_MAX_KEY_SIZE) {
- grn_memcpy(buf + len, name, name_size);
- column = grn_ctx_get(ctx, buf, len + name_size);
- } else {
- ERR(GRN_INVALID_ARGUMENT, "name is too long");
+
+ if (table_id & GRN_OBJ_TMP_OBJECT) {
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ void *value = NULL;
+ grn_snprintf(column_name, GRN_TABLE_MAX_KEY_SIZE, GRN_TABLE_MAX_KEY_SIZE,
+ "%u%c%.*s", table_id, GRN_DB_DELIMITER, name_size, name);
+ grn_pat_get(ctx, ctx->impl->temporary_columns,
+ column_name, strlen(column_name),
+ &value);
+ if (value) {
+ column = *((grn_obj **)value);
}
} else {
- /* todo : support temporary table */
+ char buf[GRN_TABLE_MAX_KEY_SIZE];
+ int len = grn_obj_name(ctx, table, buf, GRN_TABLE_MAX_KEY_SIZE);
+ if (len) {
+ buf[len++] = GRN_DB_DELIMITER;
+ if (len + name_size <= GRN_TABLE_MAX_KEY_SIZE) {
+ grn_memcpy(buf + len, name, name_size);
+ column = grn_ctx_get(ctx, buf, len + name_size);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "name is too long");
+ }
+ }
}
+
return column;
}
@@ -4080,14 +4692,46 @@ grn_table_columns(grn_ctx *ctx, grn_obj *table, const char *name, unsigned int n
grn_obj *res)
{
int n = 0;
+ grn_id id;
+
GRN_API_ENTER;
- if (GRN_OBJ_TABLEP(table) && DB_OBJ(table)->id &&
- !(DB_OBJ(table)->id & GRN_OBJ_TMP_OBJECT)) {
+
+ if (!GRN_OBJ_TABLEP(table)) {
+ GRN_API_RETURN(n);
+ }
+
+ id = DB_OBJ(table)->id;
+
+ if (id == GRN_ID_NIL) {
+ GRN_API_RETURN(n);
+ }
+
+ if (id & GRN_OBJ_TMP_OBJECT) {
+ char search_key[GRN_TABLE_MAX_KEY_SIZE];
+ grn_pat_cursor *cursor;
+ grn_snprintf(search_key, GRN_TABLE_MAX_KEY_SIZE, GRN_TABLE_MAX_KEY_SIZE,
+ "%u%c%.*s", id, GRN_DB_DELIMITER, name_size, name);
+ cursor = grn_pat_cursor_open(ctx, ctx->impl->temporary_columns,
+ search_key, strlen(search_key),
+ NULL, 0,
+ 0, -1, GRN_CURSOR_PREFIX);
+ if (cursor) {
+ grn_id column_id;
+ while ((column_id = grn_pat_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ column_id |= GRN_OBJ_TMP_OBJECT | GRN_OBJ_TMP_COLUMN;
+ grn_hash_add(ctx, (grn_hash *)res,
+ &column_id, sizeof(grn_id),
+ NULL, NULL);
+ n++;
+ }
+ grn_pat_cursor_close(ctx, cursor);
+ }
+ } else {
grn_db *s = (grn_db *)DB_OBJ(table)->db;
if (s->keys) {
grn_obj bulk;
GRN_TEXT_INIT(&bulk, 0);
- grn_table_get_key2(ctx, s->keys, DB_OBJ(table)->id, &bulk);
+ grn_table_get_key2(ctx, s->keys, id, &bulk);
GRN_TEXT_PUTC(ctx, &bulk, GRN_DB_DELIMITER);
grn_bulk_write(ctx, &bulk, name, name_size);
grn_table_search(ctx, s->keys, GRN_BULK_HEAD(&bulk), GRN_BULK_VSIZE(&bulk),
@@ -4096,6 +4740,7 @@ grn_table_columns(grn_ctx *ctx, grn_obj *table, const char *name, unsigned int n
n = grn_table_size(ctx, res);
}
}
+
GRN_API_RETURN(n);
}
@@ -4133,7 +4778,7 @@ _grn_table_key(grn_ctx *ctx, grn_obj *table, grn_id id, uint32_t *key_size)
grn_obj *
grn_column_create(grn_ctx *ctx, grn_obj *table,
const char *name, unsigned int name_size,
- const char *path, grn_obj_flags flags, grn_obj *type)
+ const char *path, grn_column_flags flags, grn_obj *type)
{
grn_db *s;
uint32_t value_size;
@@ -4141,8 +4786,11 @@ grn_column_create(grn_ctx *ctx, grn_obj *table,
grn_id id = GRN_ID_NIL;
grn_id range = GRN_ID_NIL;
grn_id domain = GRN_ID_NIL;
+ grn_bool is_persistent_table;
char fullname[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int fullname_size;
char buffer[PATH_MAX];
+
GRN_API_ENTER;
if (!table) {
ERR(GRN_INVALID_ARGUMENT, "[column][create] table is missing");
@@ -4167,46 +4815,50 @@ grn_column_create(grn_ctx *ctx, grn_obj *table,
table_name_len, table_name, name_size, name);
goto exit;
}
- if (DB_OBJ(table)->id & GRN_OBJ_TMP_OBJECT) {
- ERR(GRN_INVALID_ARGUMENT,
- "[column][create] temporary table doesn't support column: <%.*s>",
- name_size, name);
- goto exit;
- }
- {
- uint32_t s = 0;
- const char *n = _grn_table_key(ctx, ctx->impl->db, DB_OBJ(table)->id, &s);
- GRN_LOG(ctx, GRN_LOG_NOTICE,
- "DDL:column_create %.*s %.*s", s, n, name_size, name);
- }
+
if (grn_db_check_name(ctx, name, name_size)) {
GRN_DB_CHECK_NAME_ERR("[column][create]", name, name_size);
goto exit;
}
- if ((domain = DB_OBJ(table)->id)) {
- int len = grn_table_get_key(ctx, s->keys, domain, fullname, GRN_TABLE_MAX_KEY_SIZE);
- if (name_size + 1 + len > GRN_TABLE_MAX_KEY_SIZE) {
+
+ domain = DB_OBJ(table)->id;
+ is_persistent_table = !(domain & GRN_OBJ_TMP_OBJECT);
+
+ if (!domain) {
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "[column][create] [todo] table-less column isn't supported yet");
+ goto exit;
+ }
+
+ {
+ int table_name_len;
+ if (is_persistent_table) {
+ table_name_len = grn_table_get_key(ctx, s->keys, domain,
+ fullname, GRN_TABLE_MAX_KEY_SIZE);
+ } else {
+ grn_snprintf(fullname, GRN_TABLE_MAX_KEY_SIZE, GRN_TABLE_MAX_KEY_SIZE,
+ "%u", domain);
+ table_name_len = strlen(fullname);
+ }
+ if (name_size + 1 + table_name_len > GRN_TABLE_MAX_KEY_SIZE) {
ERR(GRN_INVALID_ARGUMENT,
"[column][create] too long column name: required name_size(%d) < %d"
": <%.*s>.<%.*s>",
- name_size, GRN_TABLE_MAX_KEY_SIZE - 1 - len,
- len, fullname, name_size, name);
+ name_size, GRN_TABLE_MAX_KEY_SIZE - 1 - table_name_len,
+ table_name_len, fullname, name_size, name);
goto exit;
}
- fullname[len] = GRN_DB_DELIMITER;
- grn_memcpy(fullname + len + 1, name, name_size);
- name_size += len + 1;
- } else {
- ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
- "[column][create] [todo] table-less column isn't supported yet");
- goto exit;
+ fullname[table_name_len] = GRN_DB_DELIMITER;
+ grn_memcpy(fullname + table_name_len + 1, name, name_size);
+ fullname_size = table_name_len + 1 + name_size;
}
+
range = DB_OBJ(type)->id;
switch (type->header.type) {
case GRN_TYPE :
{
grn_db_obj *t = (grn_db_obj *)type;
- flags |= t->header.flags;
+ flags |= t->header.flags & ~GRN_OBJ_KEY_MASK;
value_size = GRN_TYPE_SIZE(t);
}
break;
@@ -4224,12 +4876,46 @@ grn_column_create(grn_ctx *ctx, grn_obj *table,
*/
value_size = sizeof(grn_id);
}
- id = grn_obj_register(ctx, db, fullname, name_size);
- if (ERRP(ctx, GRN_ERROR)) { goto exit; }
- if (GRN_OBJ_PERSISTENT & flags) {
+
+ if (is_persistent_table) {
+ id = grn_obj_register(ctx, db, fullname, fullname_size);
+ if (ERRP(ctx, GRN_ERROR)) { goto exit; }
+
+ {
+ uint32_t table_name_size = 0;
+ const char *table_name;
+ table_name = _grn_table_key(ctx, ctx->impl->db, domain, &table_name_size);
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "DDL:%u:column_create %.*s %.*s",
+ id,
+ table_name_size, table_name,
+ name_size, name);
+ }
+ } else {
+ int added;
+ id = grn_pat_add(ctx, ctx->impl->temporary_columns,
+ fullname, fullname_size, NULL,
+ &added);
+ if (!id) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[column][create][temporary] "
+ "failed to register temporary column name: <%.*s>",
+ fullname_size, fullname);
+ goto exit;
+ } else if (!added) {
+ id = GRN_ID_NIL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[column][create][temporary] already used name was assigned: <%.*s>",
+ fullname_size, fullname);
+ goto exit;
+ }
+ id |= GRN_OBJ_TMP_OBJECT | GRN_OBJ_TMP_COLUMN;
+ }
+
+ if (is_persistent_table && flags & GRN_OBJ_PERSISTENT) {
if (!path) {
if (GRN_DB_PERSISTENT_P(db)) {
- gen_pathname(grn_obj_io(db)->path, buffer, id);
+ grn_db_generate_pathname(ctx, db, id, buffer);
path = buffer;
} else {
int table_name_len;
@@ -4281,7 +4967,7 @@ grn_column_create(grn_ctx *ctx, grn_obj *table,
DB_OBJ(res)->header.flags = flags;
res->header.flags = flags;
if (grn_db_obj_init(ctx, db, id, DB_OBJ(res))) {
- _grn_obj_remove(ctx, res);
+ _grn_obj_remove(ctx, res, GRN_FALSE);
res = NULL;
} else {
grn_obj_touch(ctx, res, NULL);
@@ -4634,21 +5320,20 @@ grn_vector_decode(grn_ctx *ctx, grn_obj *v, const char *data, uint32_t data_size
}
{
grn_section *vp;
+ grn_obj *body = grn_vector_body(ctx, v);
+ uint32_t offset = GRN_BULK_VSIZE(body);
uint32_t o = 0, l, i;
for (i = n, vp = v->u.v.sections + n0; i; i--, vp++) {
if (pe <= p) { return GRN_INVALID_ARGUMENT; }
GRN_B_DEC(l, p);
vp->length = l;
- vp->offset = o;
+ vp->offset = offset + o;
vp->weight = 0;
vp->domain = 0;
o += l;
}
if (pe < p + o) { return GRN_INVALID_ARGUMENT; }
- {
- grn_obj *body = grn_vector_body(ctx, v);
- grn_bulk_write(ctx, body, (char *)p, o);
- }
+ grn_bulk_write(ctx, body, (char *)p, o);
p += o;
if (p < pe) {
for (i = n, vp = v->u.v.sections + n0; i; i--, vp++) {
@@ -4861,8 +5546,10 @@ accessor_new(grn_ctx *ctx)
res->header.impl_flags = GRN_OBJ_ALLOCATED;
res->header.flags = 0;
res->header.domain = GRN_ID_NIL;
+ res->range = GRN_ID_NIL;
res->action = GRN_ACCESSOR_VOID;
res->offset = 0;
+ res->obj = NULL;
res->next = NULL;
}
return res;
@@ -4879,6 +5566,17 @@ grn_obj_get_accessor_rset_value(grn_ctx *ctx, grn_obj *obj,
*rp = accessor_new(ctx);
(*rp)->obj = obj;
+#define CHECK_GROUP_CALC_FLAG(flag) do { \
+ if (GRN_TABLE_IS_GROUPED(obj)) { \
+ grn_table_group_flags flags; \
+ flags = DB_OBJ(obj)->flags.group; \
+ if (flags & flag) { \
+ succeeded = GRN_TRUE; \
+ (*rp)->action = action; \
+ goto exit; \
+ } \
+ } \
+ } while(GRN_FALSE)
switch (action) {
case GRN_ACCESSOR_GET_SCORE :
if (DB_OBJ(obj)->header.flags & GRN_OBJ_WITH_SUBREC) {
@@ -4888,9 +5586,17 @@ grn_obj_get_accessor_rset_value(grn_ctx *ctx, grn_obj *obj,
}
break;
case GRN_ACCESSOR_GET_MAX :
+ CHECK_GROUP_CALC_FLAG(GRN_TABLE_GROUP_CALC_MAX);
+ break;
case GRN_ACCESSOR_GET_MIN :
+ CHECK_GROUP_CALC_FLAG(GRN_TABLE_GROUP_CALC_MIN);
+ break;
case GRN_ACCESSOR_GET_SUM :
+ CHECK_GROUP_CALC_FLAG(GRN_TABLE_GROUP_CALC_SUM);
+ break;
case GRN_ACCESSOR_GET_AVG :
+ CHECK_GROUP_CALC_FLAG(GRN_TABLE_GROUP_CALC_AVG);
+ break;
case GRN_ACCESSOR_GET_NSUBRECS :
if (GRN_TABLE_IS_GROUPED(obj)) {
(*rp)->action = action;
@@ -4899,6 +5605,7 @@ grn_obj_get_accessor_rset_value(grn_ctx *ctx, grn_obj *obj,
}
break;
}
+#undef CHECK_GROUP_CALC_FLAG
switch (obj->header.type) {
case GRN_TABLE_PAT_KEY :
@@ -5303,7 +6010,12 @@ inline static void
grn_obj_get_range_info(grn_ctx *ctx, grn_obj *obj,
grn_id *range_id, grn_obj_flags *range_flags)
{
- if (GRN_DB_OBJP(obj)) {
+ if (!obj) {
+ *range_id = GRN_ID_NIL;
+ } else if (grn_obj_is_proc(ctx, obj)) {
+ /* TODO */
+ *range_id = GRN_ID_NIL;
+ } else if (GRN_DB_OBJP(obj)) {
*range_id = DB_OBJ(obj)->range;
if (grn_column_is_vector(ctx, obj)) {
*range_flags = GRN_OBJ_VECTOR;
@@ -5401,30 +6113,37 @@ grn_obj_is_persistent(grn_ctx *ctx, grn_obj *obj)
grn_obj key;\
GRN_OBJ_INIT(&key, GRN_BULK, 0, table->header.domain);\
if (src->header.domain != table->header.domain) {\
- grn_obj_cast(ctx, src, &key, GRN_TRUE);\
+ rc = grn_obj_cast(ctx, src, &key, GRN_TRUE);\
p_key = &key;\
}\
- if (GRN_BULK_VSIZE(p_key)) {\
- id = addp ? grn_table_add_by_key(ctx, table, p_key, NULL)\
- : grn_table_get_by_key(ctx, table, p_key);\
- if (id) {\
- GRN_RECORD_SET(ctx, dest, id);\
+ if (!rc) {\
+ if (GRN_BULK_VSIZE(p_key)) {\
+ if (add_record_if_not_exist) {\
+ id = grn_table_add_by_key(ctx, table, p_key, NULL);\
+ } else {\
+ id = grn_table_get_by_key(ctx, table, p_key);\
+ }\
+ if (id) {\
+ GRN_RECORD_SET(ctx, dest, id);\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
} else {\
- rc = GRN_INVALID_ARGUMENT;\
+ GRN_RECORD_SET(ctx, dest, GRN_ID_NIL);\
}\
- } else {\
- GRN_RECORD_SET(ctx, dest, GRN_ID_NIL);\
}\
GRN_OBJ_FIN(ctx, &key);\
} else {\
grn_obj record_id;\
GRN_UINT32_INIT(&record_id, 0);\
- grn_obj_cast(ctx, src, &record_id, GRN_TRUE);\
- id = GRN_UINT32_VALUE(&record_id);\
- if (id) {\
- GRN_RECORD_SET(ctx, dest, id);\
- } else {\
- rc = GRN_INVALID_ARGUMENT;\
+ rc = grn_obj_cast(ctx, src, &record_id, GRN_TRUE);\
+ if (!rc) {\
+ id = GRN_UINT32_VALUE(&record_id);\
+ if (id) {\
+ GRN_RECORD_SET(ctx, dest, id);\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
}\
}\
} else {\
@@ -5433,7 +6152,8 @@ grn_obj_is_persistent(grn_ctx *ctx, grn_obj *obj)
} while (0)
inline static grn_rc
-grn_obj_cast_bool(grn_ctx *ctx, grn_obj *src, grn_obj *dest, grn_bool addp)
+grn_obj_cast_bool(grn_ctx *ctx, grn_obj *src, grn_obj *dest,
+ grn_bool add_record_if_not_exist)
{
grn_rc rc = GRN_SUCCESS;
@@ -5552,7 +6272,7 @@ grn_obj_cast_bool(grn_ctx *ctx, grn_obj *src, grn_obj *dest, grn_bool addp)
GRN_VOID_INIT(&buf);\
rc = grn_aton(ctx, str, str_end, &rest, &buf);\
if (!rc) {\
- rc = grn_obj_cast(ctx, &buf, dest, addp);\
+ rc = grn_obj_cast(ctx, &buf, dest, add_record_if_not_exist);\
}\
GRN_OBJ_FIN(ctx, &buf);\
} else {\
@@ -5570,8 +6290,10 @@ grn_obj_cast_bool(grn_ctx *ctx, grn_obj *src, grn_obj *dest, grn_bool addp)
GRN_TIME_SET(ctx, dest, (long long int)(value) * GRN_TIME_USEC_PER_SEC);
#define TIME2TIME(ctx, dest, value)\
GRN_TIME_SET(ctx, dest, value);
-#define FLOAT2TIME(ctx, dest, value)\
- GRN_TIME_SET(ctx, dest, (long long int)(value * GRN_TIME_USEC_PER_SEC));
+#define FLOAT2TIME(ctx, dest, value) do {\
+ int64_t usec = llround(value * GRN_TIME_USEC_PER_SEC);\
+ GRN_TIME_SET(ctx, dest, usec);\
+} while (0)
#define NUM2FLOAT(ctx, dest, value)\
GRN_FLOAT_SET(ctx, dest, value);
@@ -5580,13 +6302,67 @@ grn_obj_cast_bool(grn_ctx *ctx, grn_obj *src, grn_obj *dest, grn_bool addp)
#define FLOAT2FLOAT(ctx, dest, value)\
GRN_FLOAT_SET(ctx, dest, value);
+static grn_rc
+grn_obj_cast_record(grn_ctx *ctx,
+ grn_obj *src,
+ grn_obj *dest,
+ grn_bool add_record_if_not_exist)
+{
+ grn_obj *src_table;
+ grn_obj *dest_table;
+ const char *key;
+ uint32_t key_size;
+ grn_id dest_id;
+
+ if (src->header.domain == dest->header.domain) {
+ GRN_RECORD_SET(ctx, dest, GRN_RECORD_VALUE(src));
+ return GRN_SUCCESS;
+ }
+
+ src_table = grn_ctx_at(ctx, src->header.domain);
+ if (!src_table) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (src_table->header.type == GRN_TABLE_NO_KEY) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ dest_table = grn_ctx_at(ctx, dest->header.domain);
+ if (!dest_table) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ switch (dest_table->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ break;
+ default :
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ if (GRN_RECORD_VALUE(src) == GRN_ID_NIL) {
+ GRN_RECORD_SET(ctx, dest, GRN_RECORD_VALUE(src));
+ return GRN_SUCCESS;
+ }
+
+ key = _grn_table_key(ctx, src_table, GRN_RECORD_VALUE(src), &key_size);
+ if (add_record_if_not_exist) {
+ dest_id = grn_table_add(ctx, dest_table, key, key_size, NULL);
+ } else {
+ dest_id = grn_table_get(ctx, dest_table, key, key_size);
+ }
+ GRN_RECORD_SET(ctx, dest, dest_id);
+ return GRN_SUCCESS;
+}
+
grn_rc
-grn_obj_cast(grn_ctx *ctx, grn_obj *src, grn_obj *dest, grn_bool addp)
+grn_obj_cast(grn_ctx *ctx, grn_obj *src, grn_obj *dest,
+ grn_bool add_record_if_not_exist)
{
grn_rc rc = GRN_SUCCESS;
switch (src->header.domain) {
case GRN_DB_BOOL :
- rc = grn_obj_cast_bool(ctx, src, dest, addp);
+ rc = grn_obj_cast_bool(ctx, src, dest, add_record_if_not_exist);
break;
case GRN_DB_INT8 :
NUM2DEST(GRN_INT8_VALUE, grn_text_itoa, NUM2BOOL, NUM2TIME, NUM2FLOAT);
@@ -5835,7 +6611,23 @@ grn_obj_cast(grn_ctx *ctx, grn_obj *src, grn_obj *dest, grn_bool addp)
rc = grn_obj_reinit(ctx, dest, dest->header.domain, dest->header.flags);
break;
default :
- rc = GRN_FUNCTION_NOT_IMPLEMENTED;
+ if (src->header.domain >= GRN_N_RESERVED_TYPES) {
+ grn_obj *table;
+ table = grn_ctx_at(ctx, src->header.domain);
+ switch (table->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ rc = grn_obj_cast_record(ctx, src, dest, add_record_if_not_exist);
+ break;
+ default :
+ rc = GRN_FUNCTION_NOT_IMPLEMENTED;
+ break;
+ }
+ } else {
+ rc = GRN_FUNCTION_NOT_IMPLEMENTED;
+ }
break;
}
return rc;
@@ -6363,7 +7155,7 @@ call_hook(grn_ctx *ctx, grn_obj *obj, grn_id id, grn_obj *value, int flags)
if (hooks->proc) {
hooks->proc->funcs[PROC_INIT](ctx, 1, &obj, &pctx.user_data);
} else {
- default_set_value_hook(ctx, 1, &obj, &pctx.user_data);
+ grn_obj_default_set_value_hook(ctx, 1, &obj, &pctx.user_data);
}
if (ctx->rc) {
grn_obj_close(ctx, oldvalue);
@@ -6378,48 +7170,6 @@ call_hook(grn_ctx *ctx, grn_obj *obj, grn_id id, grn_obj *value, int flags)
return 0;
}
-inline static int
-call_hook_for_build(grn_ctx *ctx, grn_obj *obj, grn_id id, grn_obj *value, int flags)
-{
- grn_hook *hooks = DB_OBJ(obj)->hooks[GRN_HOOK_SET];
-
- if (hooks || obj->header.type == GRN_COLUMN_VAR_SIZE) {
- grn_obj oldvalue;
- GRN_TEXT_INIT(&oldvalue, 0);
-
- if (hooks) {
- // todo : grn_proc_ctx_open()
- grn_obj id_, flags_;
- grn_proc_ctx pctx = {{0}, hooks->proc, NULL, hooks, hooks, PROC_INIT, 4, 4};
- GRN_UINT32_INIT(&id_, 0);
- GRN_UINT32_INIT(&flags_, 0);
- GRN_UINT32_SET(ctx, &id_, id);
- GRN_UINT32_SET(ctx, &flags_, flags);
- while (hooks) {
- grn_ctx_push(ctx, &id_);
- grn_ctx_push(ctx, &oldvalue);
- grn_ctx_push(ctx, value);
- grn_ctx_push(ctx, &flags_);
- pctx.caller = NULL;
- pctx.currh = hooks;
- if (hooks->proc) {
- hooks->proc->funcs[PROC_INIT](ctx, 1, &obj, &pctx.user_data);
- } else {
- default_set_value_hook(ctx, 1, &obj, &pctx.user_data);
- }
- if (ctx->rc) {
- grn_obj_close(ctx, &oldvalue);
- return 1;
- }
- hooks = hooks->next;
- pctx.offset++;
- }
- }
- grn_obj_close(ctx, &oldvalue);
- }
- return 0;
-}
-
static grn_rc
grn_obj_set_value_table_pat_key(grn_ctx *ctx, grn_obj *obj, grn_id id,
grn_obj *value, int flags)
@@ -6430,6 +7180,9 @@ grn_obj_set_value_table_pat_key(grn_ctx *ctx, grn_obj *obj, grn_id id,
grn_obj buf;
if (call_hook(ctx, obj, id, value, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
return rc;
}
@@ -6457,6 +7210,9 @@ grn_obj_set_value_table_hash_key(grn_ctx *ctx, grn_obj *obj, grn_id id,
grn_obj buf;
if (call_hook(ctx, obj, id, value, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
return rc;
}
@@ -6484,6 +7240,9 @@ grn_obj_set_value_table_no_key(grn_ctx *ctx, grn_obj *obj, grn_id id,
grn_obj buf;
if (call_hook(ctx, obj, id, value, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
return rc;
}
@@ -6513,6 +7272,9 @@ grn_obj_set_value_column_var_size_scalar(grn_ctx *ctx, grn_obj *obj, grn_id id,
grn_id buf_domain = GRN_DB_VOID;
if (call_hook(ctx, obj, id, value, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
return rc;
}
@@ -6558,10 +7320,12 @@ grn_obj_set_value_column_var_size_vector_uvector(grn_ctx *ctx, grn_obj *column,
grn_id id, grn_obj *value,
int flags)
{
- grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_rc rc = GRN_SUCCESS;
grn_obj uvector;
grn_obj_flags uvector_flags = 0;
grn_bool need_convert = GRN_FALSE;
+ grn_bool need_cast = GRN_FALSE;
+ grn_id column_range_id;
void *raw_value;
unsigned int size;
@@ -6575,17 +7339,67 @@ grn_obj_set_value_column_var_size_vector_uvector(grn_ctx *ctx, grn_obj *column,
uvector_flags = GRN_OBJ_WITH_WEIGHT;
}
}
+ column_range_id = DB_OBJ(column)->range;
+ if (column_range_id != value->header.domain) {
+ need_convert = GRN_TRUE;
+ need_cast = GRN_TRUE;
+ }
if (need_convert) {
unsigned int i, n;
- GRN_VALUE_FIX_SIZE_INIT(&uvector, GRN_OBJ_VECTOR, value->header.domain);
+
+ GRN_VALUE_FIX_SIZE_INIT(&uvector, GRN_OBJ_VECTOR, column_range_id);
uvector.header.flags |= uvector_flags;
n = grn_uvector_size(ctx, value);
- for (i = 0; i < n; i++) {
- grn_id id;
- unsigned int weight = 0;
- id = grn_uvector_get_element(ctx, value, i, NULL);
- grn_uvector_add_element(ctx, &uvector, id, weight);
+ if (need_cast) {
+ grn_obj value_record;
+ grn_obj casted_record;
+
+ GRN_VALUE_FIX_SIZE_INIT(&value_record, 0, value->header.domain);
+ GRN_VALUE_FIX_SIZE_INIT(&casted_record, 0, column_range_id);
+ for (i = 0; i < n; i++) {
+ grn_id id;
+ grn_id casted_id;
+ unsigned int weight = 0;
+
+ GRN_BULK_REWIND(&value_record);
+ GRN_BULK_REWIND(&casted_record);
+
+ id = grn_uvector_get_element(ctx, value, i, NULL);
+ GRN_RECORD_SET(ctx, &value_record, id);
+ rc = grn_obj_cast(ctx, &value_record, &casted_record, GRN_TRUE);
+ if (rc != GRN_SUCCESS) {
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int column_name_size;
+ grn_obj inspected;
+ column_name_size = grn_obj_name(ctx,
+ column,
+ column_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, &value_record);
+ ERR(rc,
+ "[column][set-value] failed to cast: <%.*s>: <%.*s>",
+ column_name_size,
+ column_name,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ break;
+ }
+ casted_id = GRN_RECORD_VALUE(&casted_record);
+ grn_uvector_add_element(ctx, &uvector, casted_id, weight);
+ }
+
+ GRN_OBJ_FIN(ctx, &value_record);
+ GRN_OBJ_FIN(ctx, &casted_record);
+ } else {
+ for (i = 0; i < n; i++) {
+ grn_id id;
+ unsigned int weight = 0;
+ id = grn_uvector_get_element(ctx, value, i, NULL);
+ grn_uvector_add_element(ctx, &uvector, id, weight);
+ }
}
raw_value = GRN_BULK_HEAD(&uvector);
size = GRN_BULK_VSIZE(&uvector);
@@ -6594,7 +7408,9 @@ grn_obj_set_value_column_var_size_vector_uvector(grn_ctx *ctx, grn_obj *column,
size = GRN_BULK_VSIZE(value);
}
- rc = grn_ja_put(ctx, (grn_ja *)column, id, raw_value, size, flags, NULL);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ja_put(ctx, (grn_ja *)column, id, raw_value, size, flags, NULL);
+ }
if (need_convert) {
GRN_OBJ_FIN(ctx, &uvector);
@@ -6614,6 +7430,9 @@ grn_obj_set_value_column_var_size_vector(grn_ctx *ctx, grn_obj *obj, grn_id id,
grn_obj *lexicon = grn_ctx_at(ctx, range);
if (call_hook(ctx, obj, id, value, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
return rc;
}
@@ -6770,6 +7589,9 @@ grn_obj_set_value_column_fix_size(grn_ctx *ctx, grn_obj *obj, grn_id id,
switch (flags & GRN_OBJ_SET_MASK) {
case GRN_OBJ_SET :
if (call_hook(ctx, obj, id, value_, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
GRN_OBJ_FIN(ctx, &buf);
grn_ra_unref(ctx, (grn_ra *)obj, id);
return rc;
@@ -7233,6 +8055,30 @@ grn_obj_get_info(grn_ctx *ctx, grn_obj *obj, grn_info_type type, grn_obj *valueb
GRN_BOOL_PUT(ctx, valuebuf, GRN_FALSE);
#endif /* GRN_WITH_LZ4 */
break;
+ case GRN_INFO_SUPPORT_ZSTD :
+ if (!valuebuf && !(valuebuf = grn_obj_open(ctx, GRN_BULK, 0, GRN_DB_BOOL))) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "failed to open value buffer for GRN_INFO_ZSTD_SUPPORT");
+ goto exit;
+ }
+#ifdef GRN_WITH_ZSTD
+ GRN_BOOL_PUT(ctx, valuebuf, GRN_TRUE);
+#else /* GRN_WITH_ZSTD */
+ GRN_BOOL_PUT(ctx, valuebuf, GRN_FALSE);
+#endif /* GRN_WITH_ZSTD */
+ break;
+ case GRN_INFO_SUPPORT_ARROW :
+ if (!valuebuf && !(valuebuf = grn_obj_open(ctx, GRN_BULK, 0, GRN_DB_BOOL))) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "failed to open value buffer for GRN_INFO_ARROW_SUPPORT");
+ goto exit;
+ }
+#ifdef GRN_WITH_ARROW
+ GRN_BOOL_PUT(ctx, valuebuf, GRN_TRUE);
+#else /* GRN_WITH_ARROW */
+ GRN_BOOL_PUT(ctx, valuebuf, GRN_FALSE);
+#endif /* GRN_WITH_ARROW */
+ break;
default :
if (!obj) {
ERR(GRN_INVALID_ARGUMENT, "grn_obj_get_info failed");
@@ -7352,82 +8198,11 @@ exit :
}
static void
-build_index(grn_ctx *ctx, grn_obj *obj)
-{
- grn_obj *src, **cp, **col, *target;
- grn_id *s = DB_OBJ(obj)->source;
- if (!(DB_OBJ(obj)->source_size) || !s) { return; }
- if ((src = grn_ctx_at(ctx, *s))) {
- target = GRN_OBJ_TABLEP(src) ? src : grn_ctx_at(ctx, src->header.domain);
- if (target) {
- int i, ncol = DB_OBJ(obj)->source_size / sizeof(grn_id);
- grn_obj_flags flags;
- grn_ii *ii = (grn_ii *)obj;
- grn_bool use_grn_ii_build;
- grn_table_get_info(ctx, ii->lexicon, &flags, NULL, NULL, NULL, NULL);
- switch (flags & GRN_OBJ_TABLE_TYPE_MASK) {
- case GRN_OBJ_TABLE_PAT_KEY :
- case GRN_OBJ_TABLE_DAT_KEY :
- use_grn_ii_build = GRN_TRUE;
- break;
- default :
- use_grn_ii_build = GRN_FALSE;
- break;
- }
- if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) {
- use_grn_ii_build = GRN_FALSE;
- }
- if ((col = GRN_MALLOC(ncol * sizeof(grn_obj *)))) {
- for (cp = col, i = ncol; i; s++, cp++, i--) {
- if (!(*cp = grn_ctx_at(ctx, *s))) {
- ERR(GRN_INVALID_ARGUMENT, "source invalid, n=%d",i);
- GRN_FREE(col);
- return;
- }
- if (GRN_OBJ_TABLEP(grn_ctx_at(ctx, DB_OBJ(*cp)->range))) {
- use_grn_ii_build = GRN_FALSE;
- }
- }
- if (use_grn_ii_build) {
- grn_ii_build(ctx, ii, grn_index_sparsity);
- } else {
- grn_table_cursor *tc;
- if ((tc = grn_table_cursor_open(ctx, target, NULL, 0, NULL, 0,
- 0, -1, GRN_CURSOR_BY_ID))) {
- grn_id id;
- grn_obj rv;
- GRN_TEXT_INIT(&rv, 0);
- while ((id = grn_table_cursor_next_inline(ctx, tc)) != GRN_ID_NIL) {
- for (cp = col, i = ncol; i; i--, cp++) {
- GRN_BULK_REWIND(&rv);
- if (GRN_OBJ_TABLEP(*cp)) {
- grn_table_get_key2(ctx, *cp, id, &rv);
- } else {
- grn_obj_get_value(ctx, *cp, id, &rv);
- }
- call_hook_for_build(ctx, *cp, id, &rv, 0);
- }
- }
- GRN_OBJ_FIN(ctx, &rv);
- grn_table_cursor_close(ctx, tc);
- }
- }
- GRN_FREE(col);
- }
- } else {
- ERR(GRN_INVALID_ARGUMENT, "invalid target");
- }
- } else {
- ERR(GRN_INVALID_ARGUMENT, "invalid source");
- }
-}
-
-static void
update_source_hook(grn_ctx *ctx, grn_obj *obj)
{
grn_id *s = DB_OBJ(obj)->source;
int i, n = DB_OBJ(obj)->source_size / sizeof(grn_id);
- default_set_value_hook_data hook_data = { DB_OBJ(obj)->id, 0 };
+ grn_obj_default_set_value_hook_data hook_data = { DB_OBJ(obj)->id, 0 };
grn_obj *source, data;
GRN_TEXT_INIT(&data, GRN_OBJ_DO_SHALLOW_COPY);
GRN_TEXT_SET_REF(&data, &hook_data, sizeof(hook_data));
@@ -7466,7 +8241,7 @@ del_hook(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry, grn_obj *hld)
hld_size = GRN_BULK_VSIZE(hld);
if (!hld_size) { return; }
for (i = 0, last = &DB_OBJ(obj)->hooks[entry]; *last; i++, last = &(*last)->next) {
- if (!memcmp(NEXT_ADDR(*last), hld_value, hld_size)) {
+ if (!memcmp(GRN_NEXT_ADDR(*last), hld_value, hld_size)) {
grn_obj_delete_hook(ctx, obj, entry, i);
return;
}
@@ -7478,28 +8253,33 @@ delete_source_hook(grn_ctx *ctx, grn_obj *obj)
{
grn_id *s = DB_OBJ(obj)->source;
int i, n = DB_OBJ(obj)->source_size / sizeof(grn_id);
- default_set_value_hook_data hook_data = { DB_OBJ(obj)->id, 0 };
+ grn_obj_default_set_value_hook_data hook_data = { DB_OBJ(obj)->id, 0 };
grn_obj *source, data;
GRN_TEXT_INIT(&data, GRN_OBJ_DO_SHALLOW_COPY);
GRN_TEXT_SET_REF(&data, &hook_data, sizeof(hook_data));
for (i = 1; i <= n; i++, s++) {
hook_data.section = i;
- if ((source = grn_ctx_at(ctx, *s))) {
- switch (source->header.type) {
- case GRN_TABLE_HASH_KEY :
- case GRN_TABLE_PAT_KEY :
- case GRN_TABLE_DAT_KEY :
- del_hook(ctx, source, GRN_HOOK_INSERT, &data);
- del_hook(ctx, source, GRN_HOOK_DELETE, &data);
- break;
- case GRN_COLUMN_FIX_SIZE :
- case GRN_COLUMN_VAR_SIZE :
- del_hook(ctx, source, GRN_HOOK_SET, &data);
- break;
- default :
- /* invalid target */
- break;
- }
+
+ source = grn_ctx_at(ctx, *s);
+ if (!source) {
+ ERRCLR(ctx);
+ continue;
+ }
+
+ switch (source->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ del_hook(ctx, source, GRN_HOOK_INSERT, &data);
+ del_hook(ctx, source, GRN_HOOK_DELETE, &data);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ del_hook(ctx, source, GRN_HOOK_SET, &data);
+ break;
+ default :
+ /* invalid target */
+ break;
}
}
grn_obj_close(ctx, &data);
@@ -7518,7 +8298,7 @@ grn_hook_pack(grn_ctx *ctx, grn_db_obj *obj, grn_obj *buf)
grn_id id = hooks->proc ? hooks->proc->obj.id : 0;
if ((rc = grn_text_benc(ctx, buf, id + 1))) { goto exit; }
if ((rc = grn_text_benc(ctx, buf, hooks->hld_size))) { goto exit; }
- if ((rc = grn_bulk_write(ctx, buf, (char *)NEXT_ADDR(hooks), hooks->hld_size))) { goto exit; }
+ if ((rc = grn_bulk_write(ctx, buf, (char *)GRN_NEXT_ADDR(hooks), hooks->hld_size))) { goto exit; }
}
if ((rc = grn_text_benc(ctx, buf, 0))) { goto exit; }
}
@@ -7554,7 +8334,7 @@ grn_hook_unpack(grn_ctx *ctx, grn_db_obj *obj, const char *buf, uint32_t buf_siz
new->proc = NULL;
}
if ((new->hld_size = hld_size)) {
- grn_memcpy(NEXT_ADDR(new), p, hld_size);
+ grn_memcpy(GRN_NEXT_ADDR(new), p, hld_size);
p += hld_size;
}
*last = new;
@@ -7583,15 +8363,79 @@ grn_token_filters_pack(grn_ctx *ctx,
}
}
+static grn_bool
+grn_obj_encoded_spec_equal(grn_ctx *ctx,
+ grn_obj *encoded_spec1,
+ grn_obj *encoded_spec2)
+{
+ unsigned int i, n_elements;
+
+ if (encoded_spec1->header.type != GRN_VECTOR) {
+ return GRN_FALSE;
+ }
+
+ if (encoded_spec1->header.type != encoded_spec2->header.type) {
+ return GRN_FALSE;
+ }
+
+ n_elements = grn_vector_size(ctx, encoded_spec1);
+ if (grn_vector_size(ctx, encoded_spec2) != n_elements) {
+ return GRN_FALSE;
+ }
+
+ for (i = 0; i < n_elements; i++) {
+ const char *content1;
+ const char *content2;
+ unsigned int content_size1;
+ unsigned int content_size2;
+ unsigned int weight1;
+ unsigned int weight2;
+ grn_id domain1;
+ grn_id domain2;
+
+ content_size1 = grn_vector_get_element(ctx,
+ encoded_spec1,
+ i,
+ &content1,
+ &weight1,
+ &domain1);
+ content_size2 = grn_vector_get_element(ctx,
+ encoded_spec2,
+ i,
+ &content2,
+ &weight2,
+ &domain2);
+ if (content_size1 != content_size2) {
+ return GRN_FALSE;
+ }
+ if (memcmp(content1, content2, content_size1) != 0) {
+ return GRN_FALSE;
+ }
+ if (weight1 != weight2) {
+ return GRN_FALSE;
+ }
+ if (domain1 != domain2) {
+ return GRN_FALSE;
+ }
+ }
+
+ return GRN_TRUE;
+}
+
void
grn_obj_spec_save(grn_ctx *ctx, grn_db_obj *obj)
{
grn_db *s;
grn_obj v, *b;
grn_obj_spec spec;
+ grn_bool need_update = GRN_TRUE;
+
if (obj->id & GRN_OBJ_TMP_OBJECT) { return; }
if (!ctx->impl || !GRN_DB_OBJP(obj)) { return; }
if (!(s = (grn_db *)ctx->impl->db) || !s->specs) { return; }
+ if (obj->header.type == GRN_PROC && obj->range == GRN_ID_NIL) {
+ return;
+ }
GRN_OBJ_INIT(&v, GRN_VECTOR, 0, GRN_DB_TEXT);
if (!(b = grn_vector_body(ctx, &v))) { return; }
spec.header = obj->header;
@@ -7624,32 +8468,107 @@ grn_obj_spec_save(grn_ctx *ctx, grn_db_obj *obj)
grn_vector_delimit(ctx, &v, 0, 0);
break;
}
+
+ {
+ grn_io_win jw;
+ uint32_t current_spec_raw_len;
+ char *current_spec_raw;
+
+ current_spec_raw = grn_ja_ref(ctx,
+ s->specs,
+ obj->id,
+ &jw,
+ &current_spec_raw_len);
+ if (current_spec_raw) {
+ grn_rc rc;
+ grn_obj current_spec;
+
+ GRN_OBJ_INIT(&current_spec, GRN_VECTOR, 0, GRN_DB_TEXT);
+ rc = grn_vector_decode(ctx,
+ &current_spec,
+ current_spec_raw,
+ current_spec_raw_len);
+ if (rc == GRN_SUCCESS) {
+ need_update = !grn_obj_encoded_spec_equal(ctx, &v, &current_spec);
+ }
+ GRN_OBJ_FIN(ctx, &current_spec);
+ grn_ja_unref(ctx, &jw);
+ }
+ }
+
+ if (!need_update) {
+ grn_obj_close(ctx, &v);
+ return;
+ }
+
+ {
+ const char *name;
+ uint32_t name_size = 0;
+ const char *range_name = NULL;
+ uint32_t range_name_size = 0;
+
+ name = _grn_table_key(ctx, s->keys, obj->id, &name_size);
+ switch (obj->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ if (obj->range != GRN_ID_NIL) {
+ range_name = _grn_table_key(ctx, s->keys, obj->range, &range_name_size);
+ }
+ break;
+ default :
+ break;
+ }
+ /* TODO: reduce log level. */
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "spec:%u:update:%.*s:%u(%s):%u%s%.*s%s",
+ obj->id,
+ name_size, name,
+ obj->header.type,
+ grn_obj_type_to_string(obj->header.type),
+ obj->range,
+ range_name_size == 0 ? "" : "(",
+ range_name_size, range_name,
+ range_name_size == 0 ? "" : ")");
+ }
grn_ja_putv(ctx, s->specs, obj->id, &v, 0);
grn_obj_close(ctx, &v);
}
-inline static grn_rc
-grn_obj_set_info_source_validate_report_error(grn_ctx *ctx,
- grn_obj *column,
- grn_obj *table_domain,
- grn_obj *source,
- grn_id source_type_id)
-{
- char column_name[GRN_TABLE_MAX_KEY_SIZE];
- char table_domain_name[GRN_TABLE_MAX_KEY_SIZE];
+inline static void
+grn_obj_set_info_source_invalid_lexicon_error(grn_ctx *ctx,
+ const char *message,
+ grn_obj *actual_type,
+ grn_obj *expected_type,
+ grn_obj *index_column,
+ grn_obj *source)
+{
+ char actual_type_name[GRN_TABLE_MAX_KEY_SIZE];
+ int actual_type_name_size;
+ char expected_type_name[GRN_TABLE_MAX_KEY_SIZE];
+ int expected_type_name_size;
+ char index_column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_column_name_size;
char source_name[GRN_TABLE_MAX_KEY_SIZE];
- char source_type_name[GRN_TABLE_MAX_KEY_SIZE];
- int column_name_size;
- int table_domain_name_size;
int source_name_size;
- int source_type_name_size;
- grn_obj *source_type;
- column_name_size = grn_obj_name(ctx, column,
- column_name, GRN_TABLE_MAX_KEY_SIZE);
+ actual_type_name_size = grn_obj_name(ctx, actual_type,
+ actual_type_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ expected_type_name_size = grn_obj_name(ctx, expected_type,
+ expected_type_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ index_column_name_size = grn_obj_name(ctx, index_column,
+ index_column_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+
source_name_size = grn_obj_name(ctx, source,
source_name, GRN_TABLE_MAX_KEY_SIZE);
- if (GRN_OBJ_TABLEP(source)) {
+ if (grn_obj_is_table(ctx, source)) {
source_name[source_name_size] = '\0';
grn_strncat(source_name,
GRN_TABLE_MAX_KEY_SIZE,
@@ -7657,53 +8576,40 @@ grn_obj_set_info_source_validate_report_error(grn_ctx *ctx,
GRN_TABLE_MAX_KEY_SIZE - source_name_size - 1);
source_name_size = strlen(source_name);
}
- table_domain_name_size = grn_obj_name(ctx, table_domain,
- table_domain_name,
- GRN_TABLE_MAX_KEY_SIZE);
- source_type = grn_ctx_at(ctx, source_type_id);
- if (source_type) {
- source_type_name_size = grn_obj_name(ctx, source_type,
- source_type_name,
- GRN_TABLE_MAX_KEY_SIZE);
- grn_obj_unlink(ctx, source_type);
- } else {
- grn_strncpy(source_type_name,
- GRN_TABLE_MAX_KEY_SIZE,
- "(nil)",
- GRN_TABLE_MAX_KEY_SIZE);
- source_type_name_size = strlen(source_type_name);
- }
+
ERR(GRN_INVALID_ARGUMENT,
- "grn_obj_set_info(): GRN_INFO_SOURCE: "
- "source type must equal to index table's key type: "
- "source:<%.*s(%.*s)> index:<%.*s(%.*s)>",
- source_name_size, source_name,
- source_type_name_size, source_type_name,
- column_name_size, column_name,
- table_domain_name_size, table_domain_name);
- return ctx->rc;
+ "[column][index][source] %s: "
+ "<%.*s> -> <%.*s>: "
+ "index-column:<%.*s> "
+ "source:<%.*s>",
+ message,
+ actual_type_name_size, actual_type_name,
+ expected_type_name_size, expected_type_name,
+ index_column_name_size, index_column_name,
+ source_name_size, source_name);
}
inline static grn_rc
grn_obj_set_info_source_validate(grn_ctx *ctx, grn_obj *obj, grn_obj *value)
{
- grn_rc rc = GRN_SUCCESS;
- grn_id table_id;
- grn_obj *table = NULL;
- grn_id table_domain_id;
- grn_obj *table_domain = NULL;
+ grn_id lexicon_id;
+ grn_obj *lexicon = NULL;
+ grn_id lexicon_domain_id;
+ grn_obj *lexicon_domain = NULL;
+ grn_bool lexicon_domain_is_table;
+ grn_bool lexicon_have_tokenizer;
grn_id *source_ids;
int i, n_source_ids;
- table_id = obj->header.domain;
- table = grn_ctx_at(ctx, table_id);
- if (!table) {
+ lexicon_id = obj->header.domain;
+ lexicon = grn_ctx_at(ctx, lexicon_id);
+ if (!lexicon) {
goto exit;
}
- table_domain_id = table->header.domain;
- table_domain = grn_ctx_at(ctx, table_domain_id);
- if (!table_domain) {
+ lexicon_domain_id = lexicon->header.domain;
+ lexicon_domain = grn_ctx_at(ctx, lexicon_domain_id);
+ if (!lexicon_domain) {
goto exit;
}
@@ -7721,43 +8627,66 @@ grn_obj_set_info_source_validate(grn_ctx *ctx, grn_obj *obj, grn_obj *value)
goto exit;
}
- if (!GRN_OBJ_TABLEP(table_domain)) {
- goto exit;
+ lexicon_domain_is_table = grn_obj_is_table(ctx, lexicon_domain);
+ {
+ grn_obj *tokenizer;
+ grn_table_get_info(ctx, lexicon, NULL, NULL, &tokenizer, NULL, NULL);
+ lexicon_have_tokenizer = (tokenizer != NULL);
}
for (i = 0; i < n_source_ids; i++) {
grn_id source_id = source_ids[i];
grn_obj *source;
grn_id source_type_id;
+ grn_obj *source_type;
source = grn_ctx_at(ctx, source_id);
if (!source) {
continue;
}
- if (GRN_OBJ_TABLEP(source)) {
+ if (grn_obj_is_table(ctx, source)) {
source_type_id = source->header.domain;
} else {
source_type_id = DB_OBJ(source)->range;
}
- if (table_domain_id != source_type_id) {
- rc = grn_obj_set_info_source_validate_report_error(ctx,
- obj,
- table_domain,
- source,
- source_type_id);
+ source_type = grn_ctx_at(ctx, source_type_id);
+ if (!lexicon_have_tokenizer) {
+ if (grn_obj_is_table(ctx, source_type)) {
+ if (lexicon_id != source_type_id) {
+ grn_obj_set_info_source_invalid_lexicon_error(
+ ctx,
+ "index table must equal to source type",
+ lexicon,
+ source_type,
+ obj,
+ source);
+ }
+ } else {
+ if (!(lexicon_domain_id == source_type_id ||
+ (grn_type_id_is_text_family(ctx, lexicon_domain_id) &&
+ grn_type_id_is_text_family(ctx, source_type_id)))) {
+ grn_obj_set_info_source_invalid_lexicon_error(
+ ctx,
+ "index table's key must equal source type",
+ lexicon_domain,
+ source_type,
+ obj,
+ source);
+ }
+ }
}
grn_obj_unlink(ctx, source);
- if (rc != GRN_SUCCESS) {
+ if (ctx->rc != GRN_SUCCESS) {
goto exit;
}
}
exit:
- if (table) {
- grn_obj_unlink(ctx, table);
+ if (lexicon) {
+ grn_obj_unlink(ctx, lexicon);
}
- if (table_domain) {
- grn_obj_unlink(ctx, table_domain);
+ if (lexicon_domain) {
+ grn_obj_unlink(ctx, lexicon_domain);
}
return ctx->rc;
}
@@ -7768,7 +8697,11 @@ grn_obj_set_info_source_log(grn_ctx *ctx, grn_obj *obj, grn_obj *value)
grn_obj buf;
grn_id *vp = (grn_id *)GRN_BULK_HEAD(value);
uint32_t vs = GRN_BULK_VSIZE(value), s = 0;
- const char *n = _grn_table_key(ctx, ctx->impl->db, DB_OBJ(obj)->id, &s);
+ grn_id id;
+ const char *n;
+
+ id = DB_OBJ(obj)->id;
+ n = _grn_table_key(ctx, ctx->impl->db, id, &s);
GRN_TEXT_INIT(&buf, 0);
GRN_TEXT_PUT(ctx, &buf, n, s);
GRN_TEXT_PUTC(ctx, &buf, ' ');
@@ -7778,7 +8711,9 @@ grn_obj_set_info_source_log(grn_ctx *ctx, grn_obj *obj, grn_obj *value)
vs -= sizeof(grn_id);
if (vs) { GRN_TEXT_PUTC(ctx, &buf, ','); }
}
- GRN_LOG(ctx, GRN_LOG_NOTICE, "DDL:set_source %.*s",
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "DDL:%u:set_source %.*s",
+ id,
(int)GRN_BULK_VSIZE(&buf), GRN_BULK_HEAD(&buf));
GRN_OBJ_FIN(ctx, &buf);
}
@@ -7800,7 +8735,7 @@ grn_obj_set_info_source_update(grn_ctx *ctx, grn_obj *obj, grn_obj *value)
if (obj->header.type == GRN_COLUMN_INDEX) {
update_source_hook(ctx, obj);
- build_index(ctx, obj);
+ grn_index_column_build(ctx, obj);
}
} else {
DB_OBJ(obj)->source = NULL;
@@ -7883,7 +8818,8 @@ grn_obj_set_info_token_filters(grn_ctx *ctx,
token_filter_name_size);
}
if (n_token_filters > 0 || n_token_filters != n_current_token_filters) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "DDL:set_token_filters %.*s",
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "DDL:%u:set_token_filters %.*s",
+ DB_OBJ(table)->id,
(int)GRN_BULK_VSIZE(&token_filter_names),
GRN_BULK_HEAD(&token_filter_names));
}
@@ -8013,7 +8949,7 @@ grn_obj_add_hook(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry,
new->proc = (grn_proc *)proc;
new->hld_size = hld_size;
if (hld_size) {
- grn_memcpy(NEXT_ADDR(new), hld_value, hld_size);
+ grn_memcpy(GRN_NEXT_ADDR(new), hld_value, hld_size);
}
for (i = 0; i != offset && *last; i++) { last = &(*last)->next; }
new->next = *last;
@@ -8053,7 +8989,7 @@ grn_obj_get_hook(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry,
if (!hook) { return NULL; }
}
res = (grn_obj *)hook->proc;
- grn_bulk_write(ctx, hldbuf, (char *)NEXT_ADDR(hook), hook->hld_size);
+ grn_bulk_write(ctx, hldbuf, (char *)GRN_NEXT_ADDR(hook), hook->hld_size);
}
GRN_API_RETURN(res);
}
@@ -8077,24 +9013,36 @@ grn_obj_delete_hook(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry, int offset
GRN_API_RETURN(GRN_SUCCESS);
}
-static void
+static grn_rc
remove_index(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry)
{
+ grn_rc rc = GRN_SUCCESS;
grn_hook *h0, *hooks = DB_OBJ(obj)->hooks[entry];
DB_OBJ(obj)->hooks[entry] = NULL; /* avoid mutual recursive call */
while (hooks) {
- default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
grn_obj *target = grn_ctx_at(ctx, data->target);
if (!target) {
char name[GRN_TABLE_MAX_KEY_SIZE];
int length;
+ char hook_name[GRN_TABLE_MAX_KEY_SIZE];
+ int hook_name_length;
+
length = grn_obj_name(ctx, obj, name, GRN_TABLE_MAX_KEY_SIZE);
- ERR(GRN_UNKNOWN_ERROR,
+ hook_name_length = grn_table_get_key(ctx,
+ ctx->impl->db,
+ data->target,
+ hook_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_OBJECT_CORRUPT,
"[column][remove][index] "
- "hook has a dangling reference: %.*s", length, name);
+ "hook has a dangling reference: <%.*s> -> <%.*s>",
+ length, name,
+ hook_name_length, hook_name);
+ rc = ctx->rc;
} else if (target->header.type == GRN_COLUMN_INDEX) {
//TODO: multicolumn MULTI_COLUMN_INDEXP
- _grn_obj_remove(ctx, target);
+ rc = _grn_obj_remove(ctx, target, GRN_FALSE);
} else {
//TODO: err
char fn[GRN_TABLE_MAX_KEY_SIZE];
@@ -8102,49 +9050,91 @@ remove_index(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry)
flen = grn_obj_name(ctx, target, fn, GRN_TABLE_MAX_KEY_SIZE);
fn[flen] = '\0';
ERR(GRN_UNKNOWN_ERROR, "column has unsupported hooks, col=%s",fn);
+ rc = ctx->rc;
+ }
+ if (rc != GRN_SUCCESS) {
+ DB_OBJ(obj)->hooks[entry] = hooks;
+ break;
}
h0 = hooks;
hooks = hooks->next;
GRN_FREE(h0);
}
+ return rc;
}
-static void
+static grn_rc
remove_columns(grn_ctx *ctx, grn_obj *obj)
{
+ grn_rc rc = GRN_SUCCESS;
grn_hash *cols;
if ((cols = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY))) {
if (grn_table_columns(ctx, obj, "", 0, (grn_obj *)cols)) {
- grn_id *key;
- GRN_HASH_EACH(ctx, cols, id, &key, NULL, NULL, {
- grn_obj *col = grn_ctx_at(ctx, *key);
- if (col) { _grn_obj_remove(ctx, col); }
- });
+ GRN_HASH_EACH_BEGIN(ctx, cols, cursor, id) {
+ grn_id *key;
+ grn_obj *col;
+
+ grn_hash_cursor_get_key(ctx, cursor, (void **)&key);
+ col = grn_ctx_at(ctx, *key);
+
+ if (!col) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_table_get_key(ctx, ctx->impl->db, *key,
+ name, GRN_TABLE_MAX_KEY_SIZE);
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[object][remove] column is broken: <%.*s>",
+ name_size, name);
+ } else {
+ ERR(ctx->rc,
+ "[object][remove] column is broken: <%.*s>: %s",
+ name_size, name,
+ ctx->errbuf);
+ }
+ rc = ctx->rc;
+ break;
+ }
+
+ rc = _grn_obj_remove(ctx, col, GRN_FALSE);
+ if (rc != GRN_SUCCESS) {
+ grn_obj_unlink(ctx, col);
+ break;
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
}
grn_hash_close(ctx, cols);
}
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_db_index_columns(grn_ctx *ctx, grn_obj *db)
{
+ grn_rc rc = GRN_SUCCESS;
grn_table_cursor *cur;
if ((cur = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1, 0))) {
grn_id id;
while ((id = grn_table_cursor_next_inline(ctx, cur)) != GRN_ID_NIL) {
grn_obj *obj = grn_ctx_at(ctx, id);
if (obj && obj->header.type == GRN_COLUMN_INDEX) {
- _grn_obj_remove(ctx, obj);
+ rc = _grn_obj_remove(ctx, obj, GRN_FALSE);
+ if (rc != GRN_SUCCESS) {
+ grn_obj_unlink(ctx, obj);
+ break;
+ }
}
}
grn_table_cursor_close(ctx, cur);
}
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_db_reference_columns(grn_ctx *ctx, grn_obj *db)
{
+ grn_rc rc = GRN_SUCCESS;
grn_table_cursor *cur;
if ((cur = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1, 0))) {
grn_id id;
@@ -8169,23 +9159,29 @@ _grn_obj_remove_db_reference_columns(grn_ctx *ctx, grn_obj *db)
}
switch (range->header.type) {
- case GRN_TABLE_NO_KEY :
- case GRN_TABLE_HASH_KEY :
- case GRN_TABLE_PAT_KEY :
- case GRN_TABLE_DAT_KEY :
- _grn_obj_remove(ctx, obj);
- break;
+ case GRN_TABLE_NO_KEY :
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ rc = _grn_obj_remove(ctx, obj, GRN_FALSE);
+ break;
}
break;
}
+
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
}
grn_table_cursor_close(ctx, cur);
}
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_db_reference_tables(grn_ctx *ctx, grn_obj *db)
{
+ grn_rc rc = GRN_SUCCESS;
grn_table_cursor *cur;
if ((cur = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1, 0))) {
grn_id id;
@@ -8211,23 +9207,29 @@ _grn_obj_remove_db_reference_tables(grn_ctx *ctx, grn_obj *db)
}
switch (domain->header.type) {
- case GRN_TABLE_NO_KEY :
- case GRN_TABLE_HASH_KEY :
- case GRN_TABLE_PAT_KEY :
- case GRN_TABLE_DAT_KEY :
- _grn_obj_remove(ctx, obj);
- break;
+ case GRN_TABLE_NO_KEY :
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ rc = _grn_obj_remove(ctx, obj, GRN_FALSE);
+ break;
}
break;
}
+
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
}
grn_table_cursor_close(ctx, cur);
}
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_db_all_tables(grn_ctx *ctx, grn_obj *db)
{
+ grn_rc rc = GRN_SUCCESS;
grn_table_cursor *cur;
if ((cur = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1, 0))) {
grn_id id;
@@ -8243,28 +9245,43 @@ _grn_obj_remove_db_all_tables(grn_ctx *ctx, grn_obj *db)
case GRN_TABLE_HASH_KEY :
case GRN_TABLE_PAT_KEY :
case GRN_TABLE_DAT_KEY :
- _grn_obj_remove(ctx, obj);
+ rc = _grn_obj_remove(ctx, obj, GRN_FALSE);
+ break;
+ }
+
+ if (rc != GRN_SUCCESS) {
break;
}
}
grn_table_cursor_close(ctx, cur);
}
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_db(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
const char *path)
{
+ grn_rc rc = GRN_SUCCESS;
const char *io_spath;
char *spath;
grn_db *s = (grn_db *)db;
unsigned char key_type;
+ rc = _grn_obj_remove_db_index_columns(ctx, db);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = _grn_obj_remove_db_reference_columns(ctx, db);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = _grn_obj_remove_db_reference_tables(ctx, db);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = _grn_obj_remove_db_all_tables(ctx, db);
+ if (rc != GRN_SUCCESS) { return rc; }
+
if (s->specs &&
(io_spath = grn_obj_path(ctx, (grn_obj *)s->specs)) && *io_spath != '\0') {
if (!(spath = GRN_STRDUP(io_spath))) {
ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path: <%s>", io_spath);
- return;
+ return ctx->rc;
}
} else {
spath = NULL;
@@ -8272,39 +9289,53 @@ _grn_obj_remove_db(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
key_type = s->keys->header.type;
- _grn_obj_remove_db_index_columns(ctx, db);
- _grn_obj_remove_db_reference_columns(ctx, db);
- _grn_obj_remove_db_reference_tables(ctx, db);
- _grn_obj_remove_db_all_tables(ctx, db);
-
- grn_obj_close(ctx, obj);
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) {
+ if (spath) {
+ GRN_FREE(spath);
+ }
+ return rc;
+ }
if (spath) {
- grn_ja_remove(ctx, spath);
+ rc = grn_ja_remove(ctx, spath);
GRN_FREE(spath);
+ if (rc != GRN_SUCCESS) { return rc; }
}
if (path) {
switch (key_type) {
case GRN_TABLE_PAT_KEY :
- grn_pat_remove(ctx, path);
+ rc = grn_pat_remove(ctx, path);
break;
case GRN_TABLE_DAT_KEY :
- grn_dat_remove(ctx, path);
+ rc = grn_dat_remove(ctx, path);
break;
}
+ if (rc == GRN_SUCCESS) {
+ rc = grn_db_config_remove(ctx, path);
+ } else {
+ grn_db_config_remove(ctx, path);
+ }
}
+
+ return rc;
}
-static grn_bool
-is_removable_table(grn_ctx *ctx, grn_obj *table, grn_obj *db)
+static grn_rc
+remove_reference_tables(grn_ctx *ctx, grn_obj *table, grn_obj *db)
{
- grn_bool removable = GRN_TRUE;
+ grn_rc rc = GRN_SUCCESS;
+ grn_bool is_close_opened_object_mode = GRN_FALSE;
grn_id table_id;
char table_name[GRN_TABLE_MAX_KEY_SIZE];
int table_name_size;
grn_table_cursor *cursor;
+ if (grn_thread_get_limit() == 1) {
+ is_close_opened_object_mode = GRN_TRUE;
+ }
+
table_id = DB_OBJ(table)->id;
table_name_size = grn_obj_name(ctx, table, table_name, GRN_TABLE_MAX_KEY_SIZE);
if ((cursor = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1,
@@ -8312,10 +9343,18 @@ is_removable_table(grn_ctx *ctx, grn_obj *table, grn_obj *db)
grn_id id;
while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
grn_obj *object;
+ grn_bool is_removed = GRN_FALSE;
+
+ if (is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
object = grn_ctx_at(ctx, id);
if (!object) {
ERRCLR(ctx);
+ if (is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
continue;
}
@@ -8328,204 +9367,435 @@ is_removable_table(grn_ctx *ctx, grn_obj *table, grn_obj *db)
}
if (object->header.domain == table_id) {
- char reference_table_name[GRN_TABLE_MAX_KEY_SIZE];
- int reference_table_name_size;
- reference_table_name_size =
- grn_obj_name(ctx, object, reference_table_name,
- GRN_TABLE_MAX_KEY_SIZE);
- ERR(GRN_OPERATION_NOT_PERMITTED,
- "[table][remove] a table that references the table exists: "
- "<%.*s._key> -> <%.*s>",
- reference_table_name_size, reference_table_name,
- table_name_size, table_name);
- removable = GRN_FALSE;
+ rc = _grn_obj_remove(ctx, object, GRN_TRUE);
+ is_removed = (grn_table_at(ctx, db, id) == GRN_ID_NIL);
}
break;
+ case GRN_TABLE_NO_KEY :
+ break;
case GRN_COLUMN_VAR_SIZE :
case GRN_COLUMN_FIX_SIZE :
if (object->header.domain == table_id) {
break;
}
if (DB_OBJ(object)->range == table_id) {
- char column_name[GRN_TABLE_MAX_KEY_SIZE];
- int column_name_size;
- column_name_size = grn_obj_name(ctx, object, column_name,
- GRN_TABLE_MAX_KEY_SIZE);
- ERR(GRN_OPERATION_NOT_PERMITTED,
- "[table][remove] a column that references the table exists: "
- "<%.*s> -> <%.*s>",
- column_name_size, column_name,
- table_name_size, table_name);
- removable = GRN_FALSE;
+ rc = _grn_obj_remove(ctx, object, GRN_FALSE);
+ is_removed = (grn_table_at(ctx, db, id) == GRN_ID_NIL);
}
break;
+ case GRN_COLUMN_INDEX :
+ break;
default:
break;
}
- grn_obj_unlink(ctx, object);
- if (!removable) {
+ if (!is_removed) {
+ grn_obj_unlink(ctx, object);
+ }
+
+ if (is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+
+ if (rc != GRN_SUCCESS) {
break;
}
}
grn_table_cursor_close(ctx, cursor);
}
- return removable;
+ return rc;
}
-static void
+static grn_bool
+is_removable_table(grn_ctx *ctx, grn_obj *table, grn_obj *db)
+{
+ grn_id table_id;
+ grn_id reference_object_id;
+
+ table_id = DB_OBJ(table)->id;
+ if (table_id & GRN_OBJ_TMP_OBJECT) {
+ return GRN_TRUE;
+ }
+
+ reference_object_id = grn_table_find_reference_object(ctx, table);
+ if (reference_object_id == GRN_ID_NIL) {
+ return GRN_TRUE;
+ }
+
+ {
+ grn_obj *db;
+ const char *table_name;
+ int table_name_size;
+ grn_obj *reference_object;
+ const char *reference_object_name;
+ int reference_object_name_size;
+
+ db = grn_ctx_db(ctx);
+
+ table_name = _grn_table_key(ctx, db, table_id,&table_name_size);
+
+ reference_object = grn_ctx_at(ctx, reference_object_id);
+ reference_object_name = _grn_table_key(ctx,
+ db,
+ reference_object_id,
+ &reference_object_name_size);
+ if (reference_object) {
+ if (grn_obj_is_table(ctx, reference_object)) {
+ ERR(GRN_OPERATION_NOT_PERMITTED,
+ "[table][remove] a table that references the table exists: "
+ "<%.*s._key> -> <%.*s>",
+ reference_object_name_size, reference_object_name,
+ table_name_size, table_name);
+ } else {
+ ERR(GRN_OPERATION_NOT_PERMITTED,
+ "[table][remove] a column that references the table exists: "
+ "<%.*s> -> <%.*s>",
+ reference_object_name_size, reference_object_name,
+ table_name_size, table_name);
+ }
+ } else {
+ ERR(GRN_OPERATION_NOT_PERMITTED,
+ "[table][remove] a dangling object that references the table exists: "
+ "<%.*s(%u)> -> <%.*s>",
+ reference_object_name_size,
+ reference_object_name,
+ reference_object_id,
+ table_name_size, table_name);
+ }
+ }
+
+ return GRN_FALSE;
+}
+
+static inline grn_rc
+_grn_obj_remove_spec(grn_ctx *ctx, grn_obj *db, grn_id id, uint8_t type)
+{
+ const char *name;
+ uint32_t name_size = 0;
+
+ name = _grn_table_key(ctx, db, id, &name_size);
+ /* TODO: reduce log level. */
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "spec:%u:remove:%.*s:%u(%s)",
+ id,
+ name_size, name,
+ type,
+ grn_obj_type_to_string(type));
+
+ return grn_ja_put(ctx, ((grn_db *)db)->specs, id, NULL, 0, GRN_OBJ_SET, NULL);
+}
+
+static grn_rc
_grn_obj_remove_pat(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
- const char *path)
+ const char *path, grn_bool dependent)
{
- if (!is_removable_table(ctx, obj, db)) {
- return;
+ grn_rc rc = GRN_SUCCESS;
+ uint8_t type;
+
+ type = obj->header.type;
+
+ if (dependent) {
+ rc = remove_reference_tables(ctx, obj, db);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ } else {
+ if (!is_removable_table(ctx, obj, db)) {
+ return ctx->rc;
+ }
}
- remove_index(ctx, obj, GRN_HOOK_INSERT);
- remove_columns(ctx, obj);
- grn_obj_close(ctx, obj);
+
+ rc = remove_index(ctx, obj, GRN_HOOK_INSERT);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = remove_columns(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
if (path) {
- grn_ja_put(ctx, ((grn_db *)db)->specs, id, NULL, 0, GRN_OBJ_SET, NULL);
- grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
- grn_pat_remove(ctx, path);
+ rc = grn_pat_remove(ctx, path);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = _grn_obj_remove_spec(ctx, db, id, type);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ if (rc != GRN_SUCCESS) { return rc; }
}
+
grn_obj_touch(ctx, db, NULL);
+
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_dat(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
- const char *path)
+ const char *path, grn_bool dependent)
{
- if (!is_removable_table(ctx, obj, db)) {
- return;
+ grn_rc rc = GRN_SUCCESS;
+ uint8_t type;
+
+ type = obj->header.type;
+
+ if (dependent) {
+ rc = remove_reference_tables(ctx, obj, db);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ } else {
+ if (!is_removable_table(ctx, obj, db)) {
+ return ctx->rc;
+ }
}
- remove_index(ctx, obj, GRN_HOOK_INSERT);
- remove_columns(ctx, obj);
- grn_obj_close(ctx, obj);
+
+ rc = remove_index(ctx, obj, GRN_HOOK_INSERT);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = remove_columns(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
if (path) {
- grn_ja_put(ctx, ((grn_db *)db)->specs, id, NULL, 0, GRN_OBJ_SET, NULL);
- grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
- grn_dat_remove(ctx, path);
+ rc = grn_dat_remove(ctx, path);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = _grn_obj_remove_spec(ctx, db, id, type);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ if (rc != GRN_SUCCESS) { return rc; }
}
+
grn_obj_touch(ctx, db, NULL);
+
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_hash(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
- const char *path)
+ const char *path, grn_bool dependent)
{
- if (!is_removable_table(ctx, obj, db)) {
- return;
+ grn_rc rc = GRN_SUCCESS;
+ uint8_t type;
+
+ type = obj->header.type;
+
+ if (dependent) {
+ rc = remove_reference_tables(ctx, obj, db);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ } else {
+ if (!is_removable_table(ctx, obj, db)) {
+ return ctx->rc;
+ }
}
- remove_index(ctx, obj, GRN_HOOK_INSERT);
- remove_columns(ctx, obj);
- grn_obj_close(ctx, obj);
+
+ rc = remove_index(ctx, obj, GRN_HOOK_INSERT);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = remove_columns(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
if (path) {
- grn_ja_put(ctx, ((grn_db *)db)->specs, id, NULL, 0, GRN_OBJ_SET, NULL);
- grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
- grn_hash_remove(ctx, path);
+ rc = grn_hash_remove(ctx, path);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = _grn_obj_remove_spec(ctx, db, id, type);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ if (rc != GRN_SUCCESS) { return rc; }
}
+
grn_obj_touch(ctx, db, NULL);
+
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_array(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
- const char *path)
+ const char *path, grn_bool dependent)
{
- if (!is_removable_table(ctx, obj, db)) {
- return;
+ grn_rc rc = GRN_SUCCESS;
+ uint8_t type;
+
+ type = obj->header.type;
+
+ if (dependent) {
+ rc = remove_reference_tables(ctx, obj, db);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ } else {
+ if (!is_removable_table(ctx, obj, db)) {
+ return ctx->rc;
+ }
}
- remove_columns(ctx, obj);
- grn_obj_close(ctx, obj);
+
+ rc = remove_columns(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
if (path) {
- grn_ja_put(ctx, ((grn_db *)db)->specs, id, NULL, 0, GRN_OBJ_SET, NULL);
- grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
- grn_array_remove(ctx, path);
+ rc = grn_array_remove(ctx, path);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = _grn_obj_remove_spec(ctx, db, id, type);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ if (rc != GRN_SUCCESS) { return rc; }
}
+
grn_obj_touch(ctx, db, NULL);
+
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_ja(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
const char *path)
{
- remove_index(ctx, obj, GRN_HOOK_SET);
- grn_obj_close(ctx, obj);
+ grn_rc rc = GRN_SUCCESS;
+ uint8_t type;
+
+ type = obj->header.type;
+
+ rc = remove_index(ctx, obj, GRN_HOOK_SET);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
if (path) {
- grn_ja_put(ctx, ((grn_db *)db)->specs, id, NULL, 0, GRN_OBJ_SET, NULL);
- grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
- grn_ja_remove(ctx, path);
+ rc = grn_ja_remove(ctx, path);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = _grn_obj_remove_spec(ctx, db, id, type);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ if (rc != GRN_SUCCESS) { return rc; }
}
+
grn_obj_touch(ctx, db, NULL);
+
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_ra(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
const char *path)
{
- remove_index(ctx, obj, GRN_HOOK_SET);
- grn_obj_close(ctx, obj);
+ grn_rc rc = GRN_SUCCESS;
+ uint8_t type;
+
+ type = obj->header.type;
+
+ rc = remove_index(ctx, obj, GRN_HOOK_SET);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
if (path) {
- grn_ja_put(ctx, ((grn_db *)db)->specs, id, NULL, 0, GRN_OBJ_SET, NULL);
- grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
- grn_ra_remove(ctx, path);
+ rc = grn_ra_remove(ctx, path);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = _grn_obj_remove_spec(ctx, db, id, type);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ if (rc != GRN_SUCCESS) { return rc; }
}
grn_obj_touch(ctx, db, NULL);
+
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_index(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
const char *path)
{
+ grn_rc rc = GRN_SUCCESS;
+ uint8_t type;
+
+ type = obj->header.type;
+
delete_source_hook(ctx, obj);
- grn_obj_close(ctx, obj);
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
if (path) {
- grn_ja_put(ctx, ((grn_db *)db)->specs, id, NULL, 0, GRN_OBJ_SET, NULL);
- grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
- grn_ii_remove(ctx, path);
+ rc = grn_ii_remove(ctx, path);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = _grn_obj_remove_spec(ctx, db, id, type);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ if (rc != GRN_SUCCESS) { return rc; }
}
+
grn_obj_touch(ctx, db, NULL);
+
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_db_obj(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
const char *path)
{
- grn_obj_close(ctx, obj);
- if (!(id & GRN_OBJ_TMP_OBJECT)) {
- grn_ja_put(ctx, ((grn_db *)db)->specs, id, NULL, 0, GRN_OBJ_SET, NULL);
- grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
- }
+ grn_rc rc = GRN_SUCCESS;
+ uint8_t type;
+
+ type = obj->header.type;
+
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
if (path) {
- grn_io_remove(ctx, path);
+ rc = grn_io_remove(ctx, path);
+ if (rc != GRN_SUCCESS) { return rc; }
+ }
+
+ if (!(id & GRN_OBJ_TMP_OBJECT)) {
+ rc = _grn_obj_remove_spec(ctx, db, id, type);
+ if (rc != GRN_SUCCESS) { return rc; }
+ rc = grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ if (rc != GRN_SUCCESS) { return rc; }
}
+
grn_obj_touch(ctx, db, NULL);
+
+ return rc;
}
-static void
+static grn_rc
_grn_obj_remove_other(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
const char *path)
{
- grn_obj_close(ctx, obj);
+ return grn_obj_close(ctx, obj);
}
-static void
-_grn_obj_remove(grn_ctx *ctx, grn_obj *obj)
+static grn_rc
+_grn_obj_remove(grn_ctx *ctx, grn_obj *obj, grn_bool dependent)
{
+ grn_rc rc = GRN_SUCCESS;
grn_id id = GRN_ID_NIL;
grn_obj *db = NULL;
const char *io_path;
char *path;
+ grn_bool is_temporary_open_target = GRN_FALSE;
+
if (ctx->impl && ctx->impl->db) {
+ grn_id id;
uint32_t s = 0;
- const char *n = _grn_table_key(ctx, ctx->impl->db, DB_OBJ(obj)->id, &s);
- GRN_LOG(ctx, GRN_LOG_NOTICE, "DDL:obj_remove %.*s", s, n);
+ const char *n;
+
+ id = DB_OBJ(obj)->id;
+ n = _grn_table_key(ctx, ctx->impl->db, id, &s);
+ if (s > 0) {
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "DDL:%u:obj_remove %.*s", id, s, n);
+ }
}
if (obj->header.type != GRN_PROC &&
(io_path = grn_obj_path(ctx, obj)) && *io_path != '\0') {
if (!(path = GRN_STRDUP(io_path))) {
ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path: <%s>", io_path);
- return;
+ return ctx->rc;
}
} else {
path = NULL;
@@ -8536,53 +9806,140 @@ _grn_obj_remove(grn_ctx *ctx, grn_obj *obj)
}
switch (obj->header.type) {
case GRN_DB :
- _grn_obj_remove_db(ctx, obj, db, id, path);
+ rc = _grn_obj_remove_db(ctx, obj, db, id, path);
break;
case GRN_TABLE_PAT_KEY :
- _grn_obj_remove_pat(ctx, obj, db, id, path);
+ rc = _grn_obj_remove_pat(ctx, obj, db, id, path, dependent);
+ is_temporary_open_target = GRN_TRUE;
break;
case GRN_TABLE_DAT_KEY :
- _grn_obj_remove_dat(ctx, obj, db, id, path);
+ rc = _grn_obj_remove_dat(ctx, obj, db, id, path, dependent);
+ is_temporary_open_target = GRN_TRUE;
break;
case GRN_TABLE_HASH_KEY :
- _grn_obj_remove_hash(ctx, obj, db, id, path);
+ rc = _grn_obj_remove_hash(ctx, obj, db, id, path, dependent);
+ is_temporary_open_target = GRN_TRUE;
break;
case GRN_TABLE_NO_KEY :
- _grn_obj_remove_array(ctx, obj, db, id, path);
+ rc = _grn_obj_remove_array(ctx, obj, db, id, path, dependent);
+ is_temporary_open_target = GRN_TRUE;
break;
case GRN_COLUMN_VAR_SIZE :
- _grn_obj_remove_ja(ctx, obj, db, id, path);
+ rc = _grn_obj_remove_ja(ctx, obj, db, id, path);
+ is_temporary_open_target = GRN_TRUE;
break;
case GRN_COLUMN_FIX_SIZE :
- _grn_obj_remove_ra(ctx, obj, db, id, path);
+ rc = _grn_obj_remove_ra(ctx, obj, db, id, path);
+ is_temporary_open_target = GRN_TRUE;
break;
case GRN_COLUMN_INDEX :
- _grn_obj_remove_index(ctx, obj, db, id, path);
+ rc = _grn_obj_remove_index(ctx, obj, db, id, path);
+ is_temporary_open_target = GRN_TRUE;
break;
default :
if (GRN_DB_OBJP(obj)) {
- _grn_obj_remove_db_obj(ctx, obj, db, id, path);
+ rc = _grn_obj_remove_db_obj(ctx, obj, db, id, path);
} else {
- _grn_obj_remove_other(ctx, obj, db, id, path);
+ rc = _grn_obj_remove_other(ctx, obj, db, id, path);
}
}
- if (path) { GRN_FREE(path); }
+ if (path) {
+ GRN_FREE(path);
+ } else {
+ is_temporary_open_target = GRN_FALSE;
+ }
+
+ if (is_temporary_open_target && rc == GRN_SUCCESS) {
+ grn_obj *space;
+ space = ctx->impl->temporary_open_spaces.current;
+ if (space) {
+ unsigned int i, n_elements;
+ n_elements = GRN_BULK_VSIZE(space) / sizeof(grn_obj *);
+ for (i = 0; i < n_elements; i++) {
+ if (GRN_PTR_VALUE_AT(space, i) == obj) {
+ GRN_PTR_SET_AT(ctx, space, i, NULL);
+ }
+ }
+ }
+ }
+
+ return rc;
}
grn_rc
grn_obj_remove(grn_ctx *ctx, grn_obj *obj)
{
+ grn_rc rc = GRN_SUCCESS;
GRN_API_ENTER;
if (ctx->impl && ctx->impl->db && ctx->impl->db != obj) {
- grn_io *io = grn_obj_io(ctx->impl->db);
- if (!grn_io_lock(ctx, io, grn_lock_timeout)) {
- _grn_obj_remove(ctx, obj);
+ grn_io *io = grn_obj_get_io(ctx, ctx->impl->db);
+ rc = grn_io_lock(ctx, io, grn_lock_timeout);
+ if (rc == GRN_SUCCESS) {
+ rc = _grn_obj_remove(ctx, obj, GRN_FALSE);
grn_io_unlock(io);
}
} else {
- _grn_obj_remove(ctx, obj);
+ rc = _grn_obj_remove(ctx, obj, GRN_FALSE);
}
- GRN_API_RETURN(ctx->rc);
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+grn_obj_remove_dependent(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_rc rc = GRN_SUCCESS;
+ GRN_API_ENTER;
+ if (ctx->impl && ctx->impl->db && ctx->impl->db != obj) {
+ grn_io *io = grn_obj_get_io(ctx, ctx->impl->db);
+ rc = grn_io_lock(ctx, io, grn_lock_timeout);
+ if (rc == GRN_SUCCESS) {
+ rc = _grn_obj_remove(ctx, obj, GRN_TRUE);
+ grn_io_unlock(io);
+ }
+ } else {
+ rc = _grn_obj_remove(ctx, obj, GRN_TRUE);
+ }
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+grn_obj_remove_force(grn_ctx *ctx, const char *name, int name_size)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *db;
+ grn_id obj_id;
+ char path[PATH_MAX];
+
+ GRN_API_ENTER;
+
+ if (!(ctx->impl && ctx->impl->db)) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[object][remove][force] database isn't initialized");
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ db = ctx->impl->db;
+ if (name_size == -1) {
+ name_size = strlen(name);
+ }
+ obj_id = grn_table_get(ctx, db, name, name_size);
+ if (obj_id == GRN_ID_NIL) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[object][remove][force] nonexistent object: <%.*s>",
+ name_size, name);
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ grn_obj_delete_by_id(ctx, db, obj_id, GRN_TRUE);
+ grn_obj_path_by_id(ctx, db, obj_id, path);
+ grn_io_remove_if_exist(ctx, path);
+ grn_strcat(path, PATH_MAX, ".c");
+ grn_io_remove_if_exist(ctx, path);
+
+exit :
+ GRN_API_RETURN(rc);
}
grn_rc
@@ -8714,6 +10071,9 @@ grn_column_rename(grn_ctx *ctx, grn_obj *column, const char *name, unsigned int
grn_memcpy(fullname + len + 1, name, name_size);
name_size += len + 1;
rc = grn_obj_rename(ctx, column, fullname, name_size);
+ if (rc == GRN_SUCCESS) {
+ grn_obj_touch(ctx, column, NULL);
+ }
}
exit :
GRN_API_RETURN(rc);
@@ -8735,11 +10095,21 @@ grn_obj_register(grn_ctx *ctx, grn_obj *db, const char *name, unsigned int name_
grn_db *s = (grn_db *)db;
int added;
if (!(id = grn_table_add(ctx, s->keys, name, name_size, &added))) {
- ERR(GRN_NO_MEMORY_AVAILABLE,
- "grn_table_add failed: <%.*s>", name_size, name);
+ grn_rc rc;
+ rc = ctx->rc;
+ if (rc == GRN_SUCCESS) {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ }
+ ERR(rc,
+ "[object][register] failed to register a name: <%.*s>%s%s%s",
+ name_size, name,
+ ctx->rc == GRN_SUCCESS ? "" : ": <",
+ ctx->rc == GRN_SUCCESS ? "" : ctx->errbuf,
+ ctx->rc == GRN_SUCCESS ? "" : ">");
} else if (!added) {
ERR(GRN_INVALID_ARGUMENT,
- "already used name was assigned: <%.*s>", name_size, name);
+ "[object][register] already used name was assigned: <%.*s>",
+ name_size, name);
id = GRN_ID_NIL;
}
} else if (ctx->impl && ctx->impl->values) {
@@ -8755,9 +10125,19 @@ grn_obj_delete_by_id(grn_ctx *ctx, grn_obj *db, grn_id id, grn_bool removep)
GRN_API_ENTER;
if (id) {
if (id & GRN_OBJ_TMP_OBJECT) {
- if (ctx->impl && ctx->impl->values) {
- rc = grn_array_delete_by_id(ctx, ctx->impl->values,
- id & ~GRN_OBJ_TMP_OBJECT, NULL);
+ if (ctx->impl) {
+ if (id & GRN_OBJ_TMP_COLUMN) {
+ if (ctx->impl->temporary_columns) {
+ rc = grn_pat_delete_by_id(ctx, ctx->impl->temporary_columns,
+ id & ~(GRN_OBJ_TMP_COLUMN | GRN_OBJ_TMP_OBJECT),
+ NULL);
+ }
+ } else {
+ if (ctx->impl->values) {
+ rc = grn_array_delete_by_id(ctx, ctx->impl->values,
+ id & ~GRN_OBJ_TMP_OBJECT, NULL);
+ }
+ }
}
} else {
db_value *vp;
@@ -8794,7 +10174,7 @@ grn_obj_path_by_id(grn_ctx *ctx, grn_obj *db, grn_id id, char *buffer)
if (!GRN_DB_P(db) || !buffer) {
rc = GRN_INVALID_ARGUMENT;
} else {
- gen_pathname(grn_obj_io(db)->path, buffer, id);
+ grn_db_generate_pathname(ctx, db, id, buffer);
}
GRN_API_RETURN(rc);
}
@@ -8806,9 +10186,17 @@ grn_db_obj_init(grn_ctx *ctx, grn_obj *db, grn_id id, grn_db_obj *obj)
grn_rc rc = GRN_SUCCESS;
if (id) {
if (id & GRN_OBJ_TMP_OBJECT) {
- if (ctx->impl && ctx->impl->values) {
- rc = grn_array_set_value(ctx, ctx->impl->values,
- id & ~GRN_OBJ_TMP_OBJECT, &obj, GRN_OBJ_SET);
+ if (id & GRN_OBJ_TMP_COLUMN) {
+ if (ctx->impl && ctx->impl->temporary_columns) {
+ grn_id real_id = id & ~(GRN_OBJ_TMP_COLUMN | GRN_OBJ_TMP_OBJECT);
+ rc = grn_pat_set_value(ctx, ctx->impl->temporary_columns,
+ real_id, &obj, GRN_OBJ_SET);
+ }
+ } else {
+ if (ctx->impl && ctx->impl->values) {
+ rc = grn_array_set_value(ctx, ctx->impl->values,
+ id & ~GRN_OBJ_TMP_OBJECT, &obj, GRN_OBJ_SET);
+ }
}
} else {
db_value *vp;
@@ -8836,19 +10224,12 @@ grn_db_obj_init(grn_ctx *ctx, grn_obj *db, grn_id id, grn_db_obj *obj)
return rc;
}
-#define SERIALIZED_SPEC_INDEX_SPEC 0
-#define SERIALIZED_SPEC_INDEX_PATH 1
-#define SERIALIZED_SPEC_INDEX_SOURCE 2
-#define SERIALIZED_SPEC_INDEX_HOOK 3
-#define SERIALIZED_SPEC_INDEX_TOKEN_FILTERS 4
-#define SERIALIZED_SPEC_INDEX_EXPR 4
-
-#define GET_PATH(spec,buffer,s,id) do {\
+#define GET_PATH(spec,decoded_spec,buffer,s,id) do {\
if (spec->header.flags & GRN_OBJ_CUSTOM_NAME) {\
const char *path;\
unsigned int size = grn_vector_get_element(ctx,\
- &v,\
- SERIALIZED_SPEC_INDEX_PATH,\
+ decoded_spec,\
+ GRN_SERIALIZED_SPEC_INDEX_PATH,\
&path,\
NULL,\
NULL);\
@@ -8856,20 +10237,22 @@ grn_db_obj_init(grn_ctx *ctx, grn_obj *db, grn_id id, grn_db_obj *obj)
grn_memcpy(buffer, path, size);\
buffer[size] = '\0';\
} else {\
- gen_pathname(grn_obj_io(s->keys)->path, buffer, id); \
+ grn_db_generate_pathname(ctx, (grn_obj *)s, id, buffer);\
}\
} while (0)
-#define UNPACK_INFO() do {\
+#define UNPACK_INFO(spec,decoded_spec) do {\
if (vp->ptr) {\
+ const char *p;\
+ uint32_t size;\
grn_db_obj *r = DB_OBJ(vp->ptr);\
r->header = spec->header;\
r->id = id;\
r->range = spec->range;\
r->db = (grn_obj *)s;\
size = grn_vector_get_element(ctx,\
- &v,\
- SERIALIZED_SPEC_INDEX_SOURCE,\
+ decoded_spec,\
+ GRN_SERIALIZED_SPEC_INDEX_SOURCE,\
&p,\
NULL,\
NULL);\
@@ -8880,8 +10263,8 @@ grn_db_obj_init(grn_ctx *ctx, grn_obj *db, grn_id id, grn_db_obj *obj)
}\
}\
size = grn_vector_get_element(ctx,\
- &v,\
- SERIALIZED_SPEC_INDEX_HOOK,\
+ decoded_spec,\
+ GRN_SERIALIZED_SPEC_INDEX_HOOK,\
&p,\
NULL,\
NULL);\
@@ -8898,13 +10281,13 @@ grn_token_filters_unpack(grn_ctx *ctx,
unsigned int element_size;
unsigned int i, n_token_filter_ids;
- if (grn_vector_size(ctx, spec_vector) <= SERIALIZED_SPEC_INDEX_TOKEN_FILTERS) {
+ if (grn_vector_size(ctx, spec_vector) <= GRN_SERIALIZED_SPEC_INDEX_TOKEN_FILTERS) {
return;
}
element_size = grn_vector_get_element(ctx,
spec_vector,
- SERIALIZED_SPEC_INDEX_TOKEN_FILTERS,
+ GRN_SERIALIZED_SPEC_INDEX_TOKEN_FILTERS,
(const char **)(&token_filter_ids),
NULL,
NULL);
@@ -8923,6 +10306,62 @@ grn_token_filters_unpack(grn_ctx *ctx,
}
}
+grn_bool
+grn_db_spec_unpack(grn_ctx *ctx,
+ grn_id id,
+ void *encoded_spec,
+ uint32_t encoded_spec_size,
+ grn_obj_spec **spec,
+ grn_obj *decoded_spec,
+ const char *error_message_tag)
+{
+ grn_obj *db;
+ grn_db *db_raw;
+ grn_rc rc;
+ uint32_t spec_size;
+
+ db = ctx->impl->db;
+ db_raw = (grn_db *)db;
+
+ rc = grn_vector_decode(ctx,
+ decoded_spec,
+ encoded_spec,
+ encoded_spec_size);
+ if (rc != GRN_SUCCESS) {
+ const char *name;
+ uint32_t name_size;
+ name = _grn_table_key(ctx, db, id, &name_size);
+ GRN_LOG((ctx), GRN_LOG_ERROR,
+ "%s: failed to decode spec: <%u>(<%.*s>):<%u>: %s",
+ error_message_tag,
+ id,
+ name_size, name,
+ encoded_spec_size,
+ grn_rc_to_string(rc));
+ return GRN_FALSE;
+ }
+
+ spec_size = grn_vector_get_element(ctx,
+ decoded_spec,
+ GRN_SERIALIZED_SPEC_INDEX_SPEC,
+ (const char **)spec,
+ NULL,
+ NULL);
+ if (spec_size == 0) {
+ const char *name;
+ uint32_t name_size;
+ name = _grn_table_key(ctx, db, id, &name_size);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "%s: spec value is empty: <%u>(<%.*s>)",
+ error_message_tag,
+ id,
+ name_size, name);
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
grn_obj *
grn_ctx_at(grn_ctx *ctx, grn_id id)
{
@@ -8930,11 +10369,27 @@ grn_ctx_at(grn_ctx *ctx, grn_id id)
if (!ctx || !ctx->impl || !id) { return res; }
GRN_API_ENTER;
if (id & GRN_OBJ_TMP_OBJECT) {
- if (ctx->impl->values) {
- grn_obj **tmp_obj;
- tmp_obj = _grn_array_get_value(ctx, ctx->impl->values, id & ~GRN_OBJ_TMP_OBJECT);
- if (tmp_obj) {
- res = *tmp_obj;
+ if (id & GRN_OBJ_TMP_COLUMN) {
+ if (ctx->impl->temporary_columns) {
+ grn_id real_id = id & ~(GRN_OBJ_TMP_COLUMN | GRN_OBJ_TMP_OBJECT);
+ grn_obj **tmp_obj;
+ uint32_t size;
+ tmp_obj = (grn_obj **)grn_pat_get_value_(ctx,
+ ctx->impl->temporary_columns,
+ real_id,
+ &size);
+ if (tmp_obj) {
+ res = *tmp_obj;
+ }
+ }
+ } else {
+ if (ctx->impl->values) {
+ grn_obj **tmp_obj;
+ tmp_obj = _grn_array_get_value(ctx, ctx->impl->values,
+ id & ~GRN_OBJ_TMP_OBJECT);
+ if (tmp_obj) {
+ res = *tmp_obj;
+ }
}
}
} else {
@@ -8971,107 +10426,128 @@ grn_ctx_at(grn_ctx *ctx, grn_id id)
}
#endif /* USE_NREF */
if (!l) {
- grn_io_win jw;
- uint32_t value_len;
- char *value = grn_ja_ref(ctx, s->specs, id, &jw, &value_len);
- if (value) {
- grn_obj v;
- GRN_OBJ_INIT(&v, GRN_VECTOR, 0, GRN_DB_TEXT);
- if (!grn_vector_decode(ctx, &v, value, value_len)) {
- const char *p;
- uint32_t size;
- grn_obj_spec *spec;
+ grn_io_win iw;
+ uint32_t encoded_spec_size;
+ void *encoded_spec;
+
+ encoded_spec = grn_ja_ref(ctx, s->specs, id, &iw, &encoded_spec_size);
+ if (encoded_spec) {
+ grn_bool success;
+ grn_obj_spec *spec;
+ grn_obj decoded_spec;
+
+ GRN_OBJ_INIT(&decoded_spec, GRN_VECTOR, 0, GRN_DB_TEXT);
+ success = grn_db_spec_unpack(ctx,
+ id,
+ encoded_spec,
+ encoded_spec_size,
+ &spec,
+ &decoded_spec,
+ "grn_ctx_at");
+ if (success) {
char buffer[PATH_MAX];
- size = grn_vector_get_element(ctx,
- &v,
- SERIALIZED_SPEC_INDEX_SPEC,
- (const char **)&spec,
- NULL,
- NULL);
- if (size) {
- switch (spec->header.type) {
- case GRN_TYPE :
- vp->ptr = (grn_obj *)grn_type_open(ctx, spec);
- UNPACK_INFO();
- break;
- case GRN_TABLE_HASH_KEY :
- GET_PATH(spec, buffer, s, id);
- vp->ptr = (grn_obj *)grn_hash_open(ctx, buffer);
- if (vp->ptr) {
- grn_hash *hash = (grn_hash *)(vp->ptr);
- grn_obj_flags flags = vp->ptr->header.flags;
- UNPACK_INFO();
- vp->ptr->header.flags = flags;
- grn_token_filters_unpack(ctx, &(hash->token_filters), &v);
- }
- break;
- case GRN_TABLE_PAT_KEY :
- GET_PATH(spec, buffer, s, id);
- vp->ptr = (grn_obj *)grn_pat_open(ctx, buffer);
- if (vp->ptr) {
- grn_pat *pat = (grn_pat *)(vp->ptr);
- grn_obj_flags flags = vp->ptr->header.flags;
- UNPACK_INFO();
- vp->ptr->header.flags = flags;
- grn_token_filters_unpack(ctx, &(pat->token_filters), &v);
- }
- break;
- case GRN_TABLE_DAT_KEY :
- GET_PATH(spec, buffer, s, id);
- vp->ptr = (grn_obj *)grn_dat_open(ctx, buffer);
- if (vp->ptr) {
- grn_dat *dat = (grn_dat *)(vp->ptr);
- grn_obj_flags flags = vp->ptr->header.flags;
- UNPACK_INFO();
- vp->ptr->header.flags = flags;
- grn_token_filters_unpack(ctx, &(dat->token_filters), &v);
- }
- break;
- case GRN_TABLE_NO_KEY :
- GET_PATH(spec, buffer, s, id);
- vp->ptr = (grn_obj *)grn_array_open(ctx, buffer);
- UNPACK_INFO();
- break;
- case GRN_COLUMN_VAR_SIZE :
- GET_PATH(spec, buffer, s, id);
- vp->ptr = (grn_obj *)grn_ja_open(ctx, buffer);
- UNPACK_INFO();
- break;
- case GRN_COLUMN_FIX_SIZE :
- GET_PATH(spec, buffer, s, id);
- vp->ptr = (grn_obj *)grn_ra_open(ctx, buffer);
- UNPACK_INFO();
- break;
- case GRN_COLUMN_INDEX :
- GET_PATH(spec, buffer, s, id);
- {
- grn_obj *table = grn_ctx_at(ctx, spec->header.domain);
- vp->ptr = (grn_obj *)grn_ii_open(ctx, buffer, table);
- }
- UNPACK_INFO();
- break;
- case GRN_PROC :
- GET_PATH(spec, buffer, s, id);
- grn_plugin_register(ctx, buffer);
- break;
- case GRN_EXPR :
- {
- uint8_t *u;
- size = grn_vector_get_element(ctx,
- &v,
- SERIALIZED_SPEC_INDEX_EXPR,
- &p,
- NULL,
- NULL);
- u = (uint8_t *)p;
- vp->ptr = grn_expr_open(ctx, spec, u, u + size);
- }
- break;
+ switch (spec->header.type) {
+ case GRN_TYPE :
+ vp->ptr = (grn_obj *)grn_type_open(ctx, spec);
+ UNPACK_INFO(spec, &decoded_spec);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ GET_PATH(spec, &decoded_spec, buffer, s, id);
+ vp->ptr = (grn_obj *)grn_hash_open(ctx, buffer);
+ if (vp->ptr) {
+ grn_hash *hash = (grn_hash *)(vp->ptr);
+ grn_obj_flags flags = vp->ptr->header.flags;
+ UNPACK_INFO(spec, &decoded_spec);
+ vp->ptr->header.flags = flags;
+ grn_token_filters_unpack(ctx,
+ &(hash->token_filters),
+ &decoded_spec);
}
+ break;
+ case GRN_TABLE_PAT_KEY :
+ GET_PATH(spec, &decoded_spec, buffer, s, id);
+ vp->ptr = (grn_obj *)grn_pat_open(ctx, buffer);
+ if (vp->ptr) {
+ grn_pat *pat = (grn_pat *)(vp->ptr);
+ grn_obj_flags flags = vp->ptr->header.flags;
+ UNPACK_INFO(spec, &decoded_spec);
+ vp->ptr->header.flags = flags;
+ grn_token_filters_unpack(ctx,
+ &(pat->token_filters),
+ &decoded_spec);
+ }
+ break;
+ case GRN_TABLE_DAT_KEY :
+ GET_PATH(spec, &decoded_spec, buffer, s, id);
+ vp->ptr = (grn_obj *)grn_dat_open(ctx, buffer);
+ if (vp->ptr) {
+ grn_dat *dat = (grn_dat *)(vp->ptr);
+ grn_obj_flags flags = vp->ptr->header.flags;
+ UNPACK_INFO(spec, &decoded_spec);
+ vp->ptr->header.flags = flags;
+ grn_token_filters_unpack(ctx,
+ &(dat->token_filters),
+ &decoded_spec);
+ }
+ break;
+ case GRN_TABLE_NO_KEY :
+ GET_PATH(spec, &decoded_spec, buffer, s, id);
+ vp->ptr = (grn_obj *)grn_array_open(ctx, buffer);
+ UNPACK_INFO(spec, &decoded_spec);
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ GET_PATH(spec, &decoded_spec, buffer, s, id);
+ vp->ptr = (grn_obj *)grn_ja_open(ctx, buffer);
+ UNPACK_INFO(spec, &decoded_spec);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ GET_PATH(spec, &decoded_spec, buffer, s, id);
+ vp->ptr = (grn_obj *)grn_ra_open(ctx, buffer);
+ UNPACK_INFO(spec, &decoded_spec);
+ break;
+ case GRN_COLUMN_INDEX :
+ GET_PATH(spec, &decoded_spec, buffer, s, id);
+ {
+ grn_obj *table = grn_ctx_at(ctx, spec->header.domain);
+ vp->ptr = (grn_obj *)grn_ii_open(ctx, buffer, table);
+ }
+ UNPACK_INFO(spec, &decoded_spec);
+ break;
+ case GRN_PROC :
+ GET_PATH(spec, &decoded_spec, buffer, s, id);
+ grn_plugin_register(ctx, buffer);
+ break;
+ case GRN_EXPR :
+ {
+ const char *p;
+ uint32_t size;
+ uint8_t *u;
+ size = grn_vector_get_element(ctx,
+ &decoded_spec,
+ GRN_SERIALIZED_SPEC_INDEX_EXPR,
+ &p,
+ NULL,
+ NULL);
+ u = (uint8_t *)p;
+ vp->ptr = grn_expr_open(ctx, spec, u, u + size);
+ }
+ break;
+ }
+ if (!vp->ptr) {
+ const char *name;
+ uint32_t name_size = 0;
+ name = _grn_table_key(ctx, (grn_obj *)s, id, &name_size);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "grn_ctx_at: failed to open object: "
+ "<%u>(<%.*s>):<%u>(<%s>)",
+ id,
+ name_size, name,
+ spec->header.type,
+ grn_obj_type_to_string(spec->header.type));
}
- grn_obj_close(ctx, &v);
}
- grn_ja_unref(ctx, &jw);
+ GRN_OBJ_FIN(ctx, &decoded_spec);
+ grn_ja_unref(ctx, &iw);
}
#ifndef USE_NREF
GRN_ATOMIC_ADD_EX(pl, -1, l);
@@ -9087,6 +10563,25 @@ grn_ctx_at(grn_ctx *ctx, grn_id id)
GRN_FUTEX_WAIT(&vp->ptr);
}
}
+ if (vp->ptr) {
+ switch (vp->ptr->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ {
+ grn_obj *space;
+ space = ctx->impl->temporary_open_spaces.current;
+ if (space) {
+ GRN_PTR_PUT(ctx, space, vp->ptr);
+ }
+ }
+ break;
+ }
+ }
}
res = vp->ptr;
if (res && res->header.type == GRN_PROC) {
@@ -9098,6 +10593,38 @@ exit :
GRN_API_RETURN(res);
}
+grn_bool
+grn_ctx_is_opened(grn_ctx *ctx, grn_id id)
+{
+ grn_bool is_opened = GRN_FALSE;
+
+ if (!ctx || !ctx->impl || !id) {
+ return GRN_FALSE;
+ }
+
+ GRN_API_ENTER;
+ if (id & GRN_OBJ_TMP_OBJECT) {
+ if (ctx->impl->values) {
+ grn_obj **tmp_obj;
+ tmp_obj = _grn_array_get_value(ctx, ctx->impl->values,
+ id & ~GRN_OBJ_TMP_OBJECT);
+ if (tmp_obj) {
+ is_opened = GRN_TRUE;
+ }
+ }
+ } else {
+ grn_db *s = (grn_db *)ctx->impl->db;
+ if (s) {
+ db_value *vp;
+ vp = grn_tiny_array_at(&s->values, id);
+ if (vp && vp->ptr) {
+ is_opened = GRN_TRUE;
+ }
+ }
+ }
+ GRN_API_RETURN(is_opened);
+}
+
grn_obj *
grn_obj_open(grn_ctx *ctx, unsigned char type, grn_obj_flags flags, grn_id domain)
{
@@ -9126,11 +10653,75 @@ grn_obj_graft(grn_ctx *ctx, grn_obj *obj)
}
grn_rc
+grn_pvector_fin(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_rc rc;
+ if (obj->header.impl_flags & GRN_OBJ_OWN) {
+ /*
+ * Note that GRN_OBJ_OWN should not be used outside the DB API function
+ * because grn_obj_close is a DB API function.
+ */
+ unsigned int i, n_elements;
+ n_elements = GRN_BULK_VSIZE(obj) / sizeof(grn_obj *);
+ for (i = 0; i < n_elements; i++) {
+ grn_obj *element = GRN_PTR_VALUE_AT(obj, n_elements - i - 1);
+ if (element) {
+ grn_obj_close(ctx, element);
+ }
+ }
+ }
+ obj->header.type = GRN_VOID;
+ rc = grn_bulk_fin(ctx, obj);
+ if (obj->header.impl_flags & GRN_OBJ_ALLOCATED) {
+ GRN_FREE(obj);
+ }
+ return rc;
+}
+
+static void
+grn_table_close_columns(grn_ctx *ctx, grn_obj *table)
+{
+ grn_hash *columns;
+ int n_columns;
+
+ columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY | GRN_HASH_TINY);
+ if (!columns) {
+ return;
+ }
+
+ n_columns = grn_table_columns(ctx, table, "", 0, (grn_obj *)columns);
+ if (n_columns > 0) {
+ grn_hash_cursor *cursor;
+ cursor = grn_hash_cursor_open(ctx, columns, NULL, 0, NULL, 0, 0, -1, 0);
+ if (cursor) {
+ while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ grn_id *id;
+ grn_obj *column;
+
+ grn_hash_cursor_get_key(ctx, cursor, (void **)&id);
+ column = grn_ctx_at(ctx, *id);
+ if (column) {
+ grn_obj_close(ctx, column);
+ }
+ }
+ grn_hash_cursor_close(ctx, cursor);
+ }
+ }
+
+ grn_hash_close(ctx, columns);
+}
+
+grn_rc
grn_obj_close(grn_ctx *ctx, grn_obj *obj)
{
grn_rc rc = GRN_INVALID_ARGUMENT;
GRN_API_ENTER;
if (obj) {
+ if (grn_obj_is_table(ctx, obj) &&
+ (DB_OBJ(obj)->id & GRN_OBJ_TMP_OBJECT)) {
+ grn_table_close_columns(ctx, obj);
+ }
if (GRN_DB_OBJP(obj)) {
grn_hook_entry entry;
if (DB_OBJ(obj)->finalizer) {
@@ -9155,14 +10746,25 @@ grn_obj_close(grn_ctx *ctx, grn_obj *obj)
break;
case GRN_VOID :
case GRN_BULK :
- case GRN_PTR :
case GRN_UVECTOR :
- case GRN_PVECTOR :
case GRN_MSG :
obj->header.type = GRN_VOID;
rc = grn_bulk_fin(ctx, obj);
if (obj->header.impl_flags & GRN_OBJ_ALLOCATED) { GRN_FREE(obj); }
break;
+ case GRN_PTR :
+ if (obj->header.impl_flags & GRN_OBJ_OWN) {
+ if (GRN_BULK_VSIZE(obj) == sizeof(grn_obj *)) {
+ grn_obj_close(ctx, GRN_PTR_VALUE(obj));
+ }
+ }
+ obj->header.type = GRN_VOID;
+ rc = grn_bulk_fin(ctx, obj);
+ if (obj->header.impl_flags & GRN_OBJ_ALLOCATED) { GRN_FREE(obj); }
+ break;
+ case GRN_PVECTOR :
+ rc = grn_pvector_fin(ctx, obj);
+ break;
case GRN_ACCESSOR :
{
grn_accessor *p, *n;
@@ -9201,6 +10803,9 @@ grn_obj_close(grn_ctx *ctx, grn_obj *obj)
case GRN_CURSOR_COLUMN_GEO_INDEX :
grn_geo_cursor_close(ctx, obj);
break;
+ case GRN_CURSOR_CONFIG :
+ grn_config_cursor_close(ctx, (grn_config_cursor *)obj);
+ break;
case GRN_TYPE :
GRN_FREE(obj);
rc = GRN_SUCCESS;
@@ -9333,6 +10938,30 @@ grn_obj_reinit(grn_ctx *ctx, grn_obj *obj, grn_id domain, unsigned char flags)
if (!GRN_OBJ_MUTABLE(obj)) {
ERR(GRN_INVALID_ARGUMENT, "invalid obj assigned");
} else {
+ switch (obj->header.type) {
+ case GRN_PTR :
+ if (obj->header.impl_flags & GRN_OBJ_OWN) {
+ if (GRN_BULK_VSIZE(obj) == sizeof(grn_obj *)) {
+ grn_obj_close(ctx, GRN_PTR_VALUE(obj));
+ }
+ obj->header.impl_flags &= ~GRN_OBJ_OWN;
+ }
+ break;
+ case GRN_PVECTOR :
+ if (obj->header.impl_flags & GRN_OBJ_OWN) {
+ unsigned int i, n_elements;
+ n_elements = GRN_BULK_VSIZE(obj) / sizeof(grn_obj *);
+ for (i = 0; i < n_elements; i++) {
+ grn_obj *element = GRN_PTR_VALUE_AT(obj, i);
+ grn_obj_close(ctx, element);
+ }
+ obj->header.impl_flags &= ~GRN_OBJ_OWN;
+ }
+ break;
+ default :
+ break;
+ }
+
switch (domain) {
case GRN_DB_VOID :
if (obj->header.type == GRN_VECTOR) { VECTOR_CLEAR(ctx, obj); }
@@ -9413,7 +11042,7 @@ grn_obj_reinit_for(grn_ctx *ctx, grn_obj *obj, grn_obj *domain_obj)
if (!GRN_DB_OBJP(domain_obj) && domain_obj->header.type != GRN_ACCESSOR) {
grn_obj inspected;
GRN_TEXT_INIT(&inspected, 0);
- limited_size_inspect(ctx, &inspected, domain_obj);
+ grn_inspect_limited(ctx, &inspected, domain_obj);
ERR(GRN_INVALID_ARGUMENT,
"[reinit] invalid domain object: <%.*s>",
(int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected));
@@ -9443,7 +11072,7 @@ grn_obj_path(grn_ctx *ctx, grn_obj *obj)
path = grn_plugin_path(ctx, DB_OBJ(obj)->range);
GRN_API_RETURN(path);
}
- io = grn_obj_io(obj);
+ io = grn_obj_get_io(ctx, obj);
if (io && !(io->flags & GRN_IO_TEMPORARY)) { path = io->path; }
GRN_API_RETURN(path);
}
@@ -9456,8 +11085,15 @@ grn_obj_name(grn_ctx *ctx, grn_obj *obj, char *namebuf, int buf_size)
if (GRN_DB_OBJP(obj)) {
if (DB_OBJ(obj)->id) {
grn_db *s = (grn_db *)DB_OBJ(obj)->db;
- if (!(DB_OBJ(obj)->id & GRN_OBJ_TMP_OBJECT)) {
- len = grn_table_get_key(ctx, s->keys, DB_OBJ(obj)->id, namebuf, buf_size);
+ grn_id id = DB_OBJ(obj)->id;
+ if (id & GRN_OBJ_TMP_OBJECT) {
+ if (id & GRN_OBJ_TMP_COLUMN) {
+ grn_id real_id = id & ~(GRN_OBJ_TMP_OBJECT | GRN_OBJ_TMP_COLUMN);
+ len = grn_pat_get_key(ctx, ctx->impl->temporary_columns,
+ real_id, namebuf, buf_size);
+ }
+ } else {
+ len = grn_table_get_key(ctx, s->keys, id, namebuf, buf_size);
}
}
}
@@ -9472,66 +11108,107 @@ grn_column_name(grn_ctx *ctx, grn_obj *obj, char *namebuf, int buf_size)
if (!obj) { return len; }
GRN_API_ENTER;
if (GRN_DB_OBJP(obj)) {
- if (DB_OBJ(obj)->id && DB_OBJ(obj)->id < GRN_ID_MAX) {
+ grn_id id = DB_OBJ(obj)->id;
+ if (id & GRN_OBJ_TMP_OBJECT) {
+ if (id & GRN_OBJ_TMP_COLUMN) {
+ grn_id real_id = id & ~(GRN_OBJ_TMP_OBJECT | GRN_OBJ_TMP_COLUMN);
+ len = grn_pat_get_key(ctx, ctx->impl->temporary_columns,
+ real_id, buf, GRN_TABLE_MAX_KEY_SIZE);
+ }
+ } else if (id && id < GRN_ID_MAX) {
grn_db *s = (grn_db *)DB_OBJ(obj)->db;
- len = grn_table_get_key(ctx, s->keys, DB_OBJ(obj)->id, buf, GRN_TABLE_MAX_KEY_SIZE);
- if (len) {
- int cl;
- char *p = buf, *p0 = p, *pe = p + len;
- for (; p < pe && (cl = grn_charlen(ctx, p, pe)); p += cl) {
- if (*p == GRN_DB_DELIMITER && cl == 1) { p0 = p + cl; }
- }
- len = pe - p0;
- if (len && len <= buf_size) {
- grn_memcpy(namebuf, p0, len);
- }
+ len = grn_table_get_key(ctx, s->keys, id, buf, GRN_TABLE_MAX_KEY_SIZE);
+ }
+ if (len) {
+ int cl;
+ char *p = buf, *p0 = p, *pe = p + len;
+ for (; p < pe && (cl = grn_charlen(ctx, p, pe)); p += cl) {
+ if (*p == GRN_DB_DELIMITER && cl == 1) { p0 = p + cl; }
+ }
+ len = pe - p0;
+ if (len && len <= buf_size) {
+ grn_memcpy(namebuf, p0, len);
}
}
} else if (obj->header.type == GRN_ACCESSOR) {
- const char *name = NULL;
+ grn_obj name;
grn_accessor *a;
+
+ GRN_TEXT_INIT(&name, 0);
+
+#define ADD_DELMITER() do { \
+ if (GRN_TEXT_LEN(&name) > 0) { \
+ GRN_TEXT_PUTC(ctx, &name, GRN_DB_DELIMITER); \
+ } \
+ } while (GRN_FALSE)
+
for (a = (grn_accessor *)obj; a; a = a->next) {
switch (a->action) {
case GRN_ACCESSOR_GET_ID :
- name = GRN_COLUMN_NAME_ID;
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_ID);
break;
case GRN_ACCESSOR_GET_KEY :
- name = GRN_COLUMN_NAME_KEY;
+ if (!a->next) {
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_KEY);
+ }
break;
case GRN_ACCESSOR_GET_VALUE :
- name = GRN_COLUMN_NAME_VALUE;
+ if (!a->next) {
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_VALUE);
+ }
break;
case GRN_ACCESSOR_GET_SCORE :
- name = GRN_COLUMN_NAME_SCORE;
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_SCORE);
break;
case GRN_ACCESSOR_GET_NSUBRECS :
- name = GRN_COLUMN_NAME_NSUBRECS;
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_NSUBRECS);
break;
case GRN_ACCESSOR_GET_MAX :
- name = GRN_COLUMN_NAME_MAX;
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_MAX);
break;
case GRN_ACCESSOR_GET_MIN :
- name = GRN_COLUMN_NAME_MIN;
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_MIN);
break;
case GRN_ACCESSOR_GET_SUM :
- name = GRN_COLUMN_NAME_SUM;
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_SUM);
break;
case GRN_ACCESSOR_GET_AVG :
- name = GRN_COLUMN_NAME_AVG;
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_AVG);
break;
case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ ADD_DELMITER();
+ {
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int column_name_size;
+ column_name_size = grn_column_name(ctx, a->obj,
+ column_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ GRN_TEXT_PUT(ctx, &name, column_name, column_name_size);
+ }
+ break;
case GRN_ACCESSOR_GET_DB_OBJ :
case GRN_ACCESSOR_LOOKUP :
case GRN_ACCESSOR_FUNCALL :
break;
}
}
- if (name) {
- len = strlen(name);
- if (len <= buf_size) {
- grn_memcpy(namebuf, name, len);
- }
+#undef ADD_DELIMITER
+
+ len = GRN_TEXT_LEN(&name);
+ if (len > 0 && len <= buf_size) {
+ grn_memcpy(namebuf, GRN_TEXT_VALUE(&name), len);
}
+
+ GRN_OBJ_FIN(ctx, &name);
}
GRN_API_RETURN(len);
}
@@ -9540,18 +11217,25 @@ grn_rc
grn_column_name_(grn_ctx *ctx, grn_obj *obj, grn_obj *buf)
{
if (GRN_DB_OBJP(obj)) {
- if (DB_OBJ(obj)->id && DB_OBJ(obj)->id < GRN_ID_MAX) {
- uint32_t len;
+ uint32_t len = 0;
+ const char *p = NULL;
+ grn_id id = DB_OBJ(obj)->id;
+ if (id & GRN_OBJ_TMP_OBJECT) {
+ if (id & GRN_OBJ_TMP_COLUMN) {
+ grn_id real_id = id & ~(GRN_OBJ_TMP_OBJECT | GRN_OBJ_TMP_COLUMN);
+ p = _grn_pat_key(ctx, ctx->impl->temporary_columns, real_id, &len);
+ }
+ } else if (id && id < GRN_ID_MAX) {
grn_db *s = (grn_db *)DB_OBJ(obj)->db;
- const char *p = _grn_table_key(ctx, s->keys, DB_OBJ(obj)->id, &len);
- if (len) {
- int cl;
- const char *p0 = p, *pe = p + len;
- for (; p < pe && (cl = grn_charlen(ctx, p, pe)); p += cl) {
- if (*p == GRN_DB_DELIMITER && cl == 1) { p0 = p + cl; }
- }
- GRN_TEXT_PUT(ctx, buf, p0, pe - p0);
+ p = _grn_table_key(ctx, s->keys, id, &len);
+ }
+ if (len) {
+ int cl;
+ const char *p0 = p, *pe = p + len;
+ for (; p < pe && (cl = grn_charlen(ctx, p, pe)); p += cl) {
+ if (*p == GRN_DB_DELIMITER && cl == 1) { p0 = p + cl; }
}
+ GRN_TEXT_PUT(ctx, buf, p0, pe - p0);
}
} else if (obj->header.type == GRN_ACCESSOR) {
grn_accessor *a;
@@ -9635,7 +11319,10 @@ grn_obj_lock(grn_ctx *ctx, grn_obj *obj, grn_id id, int timeout)
{
grn_rc rc = GRN_SUCCESS;
GRN_API_ENTER;
- rc = grn_io_lock(ctx, grn_obj_io(obj), timeout);
+ rc = grn_io_lock(ctx, grn_obj_get_io(ctx, obj), timeout);
+ if (rc == GRN_SUCCESS && obj && obj->header.type == GRN_COLUMN_INDEX) {
+ rc = grn_io_lock(ctx, ((grn_ii *)obj)->chunk, timeout);
+ }
GRN_API_RETURN(rc);
}
@@ -9643,7 +11330,10 @@ grn_rc
grn_obj_unlock(grn_ctx *ctx, grn_obj *obj, grn_id id)
{
GRN_API_ENTER;
- grn_io_unlock(grn_obj_io(obj));
+ if (obj && obj->header.type == GRN_COLUMN_INDEX) {
+ grn_io_unlock(((grn_ii *)obj)->chunk);
+ }
+ grn_io_unlock(grn_obj_get_io(ctx, obj));
GRN_API_RETURN(GRN_SUCCESS);
}
@@ -9692,7 +11382,13 @@ grn_obj_clear_lock(grn_ctx *ctx, grn_obj *obj)
grn_table_cursor_close(ctx, cur);
}
}
- grn_io_clear_lock(grn_obj_io(obj));
+ grn_io_clear_lock(grn_obj_get_io(ctx, obj));
+ {
+ grn_db *db = (grn_db *)obj;
+ if (db->specs) {
+ grn_obj_clear_lock(ctx, (grn_obj *)(db->specs));
+ }
+ }
break;
case GRN_TABLE_NO_KEY :
grn_array_queue_lock_clear(ctx, (grn_array *)obj);
@@ -9713,13 +11409,18 @@ grn_obj_clear_lock(grn_ctx *ctx, grn_obj *obj)
}
grn_hash_close(ctx, cols);
}
- grn_io_clear_lock(grn_obj_io(obj));
+ grn_io_clear_lock(grn_obj_get_io(ctx, obj));
}
break;
case GRN_COLUMN_FIX_SIZE:
case GRN_COLUMN_VAR_SIZE:
+ grn_io_clear_lock(grn_obj_get_io(ctx, obj));
+ break;
case GRN_COLUMN_INDEX:
- grn_io_clear_lock(grn_obj_io(obj));
+ grn_io_clear_lock(grn_obj_get_io(ctx, obj));
+ if (obj) {
+ grn_io_clear_lock(((grn_ii *)obj)->chunk);
+ }
break;
}
GRN_API_RETURN(GRN_SUCCESS);
@@ -9730,7 +11431,10 @@ grn_obj_is_locked(grn_ctx *ctx, grn_obj *obj)
{
unsigned int res = 0;
GRN_API_ENTER;
- res = grn_io_is_locked(grn_obj_io(obj));
+ res = grn_io_is_locked(grn_obj_get_io(ctx, obj));
+ if (obj && obj->header.type == GRN_COLUMN_INDEX) {
+ res += grn_io_is_locked(((grn_ii *)obj)->chunk);
+ }
GRN_API_RETURN(res);
}
@@ -9738,15 +11442,20 @@ grn_rc
grn_obj_flush(grn_ctx *ctx, grn_obj *obj)
{
grn_rc rc = GRN_SUCCESS;
+
GRN_API_ENTER;
+
switch (obj->header.type) {
case GRN_DB :
{
grn_db *db = (grn_db *)obj;
rc = grn_obj_flush(ctx, db->keys);
- if (rc == GRN_SUCCESS) {
+ if (rc == GRN_SUCCESS && db->specs) {
rc = grn_obj_flush(ctx, (grn_obj *)(db->specs));
}
+ if (rc == GRN_SUCCESS) {
+ rc = grn_obj_flush(ctx, (grn_obj *)(db->config));
+ }
}
break;
case GRN_TABLE_DAT_KEY :
@@ -9756,9 +11465,23 @@ grn_obj_flush(grn_ctx *ctx, grn_obj *obj)
rc = grn_ii_flush(ctx, (grn_ii *)obj);
break;
default :
- rc = grn_io_flush(ctx, grn_obj_io(obj));
+ {
+ grn_io *io;
+ io = grn_obj_get_io(ctx, obj);
+ if (io) {
+ rc = grn_io_flush(ctx, io);
+ }
+ }
break;
}
+
+ if (rc == GRN_SUCCESS &&
+ GRN_DB_OBJP(obj) &&
+ DB_OBJ(obj)->id != GRN_ID_NIL &&
+ !IS_TEMP(obj)) {
+ rc = grn_db_clean(ctx, DB_OBJ(obj)->db);
+ }
+
GRN_API_RETURN(rc);
}
@@ -10446,15 +12169,34 @@ grn_table_sort_value(grn_ctx *ctx, grn_obj *table,
static grn_bool
is_compressed_column(grn_ctx *ctx, grn_obj *obj)
{
+ grn_obj *target_obj;
+
if (!obj) {
return GRN_FALSE;
}
- if (obj->header.type != GRN_COLUMN_VAR_SIZE) {
+ if (obj->header.type == GRN_ACCESSOR) {
+ grn_accessor *a = (grn_accessor *)obj;
+ while (a->next) {
+ a = a->next;
+ }
+ target_obj = a->obj;
+ } else {
+ target_obj = obj;
+ }
+
+ if (target_obj->header.type != GRN_COLUMN_VAR_SIZE) {
return GRN_FALSE;
}
- return (obj->header.flags & (GRN_OBJ_COMPRESS_ZLIB | GRN_OBJ_COMPRESS_LZ4));
+ switch (target_obj->header.flags & GRN_OBJ_COMPRESS_MASK) {
+ case GRN_OBJ_COMPRESS_ZLIB :
+ case GRN_OBJ_COMPRESS_LZ4 :
+ case GRN_OBJ_COMPRESS_ZSTD :
+ return GRN_TRUE;
+ default :
+ return GRN_FALSE;
+ }
}
static grn_bool
@@ -10485,6 +12227,31 @@ is_sub_record_accessor(grn_ctx *ctx, grn_obj *obj)
return GRN_FALSE;
}
+static grn_bool
+is_encoded_pat_key_accessor(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_accessor *accessor;
+
+ if (!grn_obj_is_accessor(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ accessor = (grn_accessor *)obj;
+ while (accessor->next) {
+ accessor = accessor->next;
+ }
+
+ if (accessor->action != GRN_ACCESSOR_GET_KEY) {
+ return GRN_FALSE;
+ }
+
+ if (accessor->obj->header.type != GRN_TABLE_PAT_KEY) {
+ return GRN_FALSE;
+ }
+
+ return grn_pat_is_key_encoded(ctx, (grn_pat *)(accessor->obj));
+}
+
static int
range_is_idp(grn_obj *obj)
{
@@ -10525,7 +12292,12 @@ grn_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit,
e = offset + limit;
}
if (keys->flags & GRN_TABLE_SORT_GEO) {
- i = grn_geo_table_sort(ctx, table, offset, limit, result, keys, n_keys);
+ if (n_keys == 2) {
+ i = grn_geo_table_sort(ctx, table, offset, limit, result,
+ keys[0].key, keys[1].key);
+ } else {
+ i = 0;
+ }
goto exit;
}
if (n_keys == 1 && !GRN_ACCESSORP(keys->key) &&
@@ -10542,7 +12314,7 @@ grn_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit,
while (i < e && (tid = grn_pat_cursor_next(ctx, pc))) {
grn_ii_cursor *ic = grn_ii_cursor_open(ctx, (grn_ii *)index, tid, 0, 0, 1, 0);
if (ic) {
- grn_ii_posting *posting;
+ grn_posting *posting;
while (i < e && (posting = grn_ii_cursor_next(ctx, ic))) {
if (offset <= i) {
grn_id *v;
@@ -10560,6 +12332,7 @@ grn_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit,
int j;
grn_bool have_compressed_column = GRN_FALSE;
grn_bool have_sub_record_accessor = GRN_FALSE;
+ grn_bool have_encoded_pat_key_accessor = GRN_FALSE;
grn_bool have_index_value_get = GRN_FALSE;
grn_table_sort_key *kp;
for (kp = keys, j = n_keys; j; kp++, j--) {
@@ -10569,6 +12342,9 @@ grn_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit,
if (is_sub_record_accessor(ctx, kp->key)) {
have_sub_record_accessor = GRN_TRUE;
}
+ if (is_encoded_pat_key_accessor(ctx, kp->key)) {
+ have_encoded_pat_key_accessor = GRN_TRUE;
+ }
if (range_is_idp(kp->key)) {
kp->offset = KEY_ID;
} else {
@@ -10643,6 +12419,7 @@ grn_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit,
}
if (have_compressed_column ||
have_sub_record_accessor ||
+ have_encoded_pat_key_accessor ||
have_index_value_get) {
i = grn_table_sort_value(ctx, table, offset, limit, result,
keys, n_keys);
@@ -10741,7 +12518,8 @@ grn_db_init_builtin_types(grn_ctx *ctx)
grn_itoh(id, buf + 3, 2);
grn_obj_register(ctx, db, buf, 5);
}
- grn_db_init_builtin_query(ctx);
+ grn_db_init_builtin_commands(ctx);
+ grn_db_init_builtin_window_functions(ctx);
for (id = grn_db_curr_id(ctx, db) + 1; id < GRN_N_RESERVED_TYPES; id++) {
grn_itoh(id, buf + 3, 2);
grn_obj_register(ctx, db, buf, 5);
@@ -10751,7 +12529,31 @@ grn_db_init_builtin_types(grn_ctx *ctx)
#define MULTI_COLUMN_INDEXP(i) (DB_OBJ(i)->source_size > sizeof(grn_id))
-static inline int
+static grn_obj *
+grn_index_column_get_tokenizer(grn_ctx *ctx, grn_obj *index_column)
+{
+ grn_obj *tokenizer;
+ grn_obj *lexicon;
+
+ lexicon = grn_ctx_at(ctx, index_column->header.domain);
+ if (!lexicon) {
+ return NULL;
+ }
+
+ grn_table_get_info(ctx, lexicon, NULL, NULL, &tokenizer, NULL, NULL);
+ return tokenizer;
+}
+
+static grn_bool
+is_full_text_searchable_index(grn_ctx *ctx, grn_obj *index_column)
+{
+ grn_obj *tokenizer;
+
+ tokenizer = grn_index_column_get_tokenizer(ctx, index_column);
+ return tokenizer != NULL;
+}
+
+static int
grn_column_find_index_data_column_equal(grn_ctx *ctx, grn_obj *obj,
grn_operator op,
grn_index_datum *index_data,
@@ -10764,18 +12566,15 @@ grn_column_find_index_data_column_equal(grn_ctx *ctx, grn_obj *obj,
grn_hook *hooks;
for (hooks = DB_OBJ(obj)->hooks[GRN_HOOK_SET]; hooks; hooks = hooks->next) {
- default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
grn_obj *target = grn_ctx_at(ctx, data->target);
int section;
if (target->header.type != GRN_COLUMN_INDEX) { continue; }
- section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0;
- if (section_buf) { *section_buf = section; }
if (obj->header.type != GRN_COLUMN_FIX_SIZE) {
- grn_obj *tokenizer, *lexicon = grn_ctx_at(ctx, target->header.domain);
- if (!lexicon) { continue; }
- grn_table_get_info(ctx, lexicon, NULL, NULL, &tokenizer, NULL, NULL);
- if (tokenizer) { continue; }
+ if (is_full_text_searchable_index(ctx, target)) { continue; }
}
+ section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0;
+ if (section_buf) { *section_buf = section; }
if (n < buf_size) {
*ip++ = target;
}
@@ -10789,28 +12588,17 @@ grn_column_find_index_data_column_equal(grn_ctx *ctx, grn_obj *obj,
return n;
}
-static inline grn_bool
+static grn_bool
is_valid_regexp_index(grn_ctx *ctx, grn_obj *index_column)
{
grn_obj *tokenizer;
- grn_obj *lexicon;
-
- lexicon = grn_ctx_at(ctx, index_column->header.domain);
- if (!lexicon) {
- return GRN_FALSE;
- }
-
- grn_table_get_info(ctx, lexicon, NULL, NULL, &tokenizer, NULL, NULL);
- grn_obj_unlink(ctx, lexicon);
- if (!tokenizer) {
- return GRN_FALSE;
- }
+ tokenizer = grn_index_column_get_tokenizer(ctx, index_column);
/* TODO: Restrict to TokenRegexp? */
- return GRN_TRUE;
+ return tokenizer != NULL;
}
-static inline int
+static int
grn_column_find_index_data_column_match(grn_ctx *ctx, grn_obj *obj,
grn_operator op,
grn_index_datum *index_data,
@@ -10822,6 +12610,7 @@ grn_column_find_index_data_column_match(grn_ctx *ctx, grn_obj *obj,
grn_obj **ip = index_buf;
grn_hook_entry hook_entry;
grn_hook *hooks;
+ grn_bool prefer_full_text_search_index = GRN_FALSE;
switch (obj->header.type) {
case GRN_TABLE_HASH_KEY :
@@ -10835,14 +12624,44 @@ grn_column_find_index_data_column_match(grn_ctx *ctx, grn_obj *obj,
break;
}
+ if (op != GRN_OP_REGEXP && !grn_column_is_vector(ctx, obj)) {
+ prefer_full_text_search_index = GRN_TRUE;
+ }
+
+ if (prefer_full_text_search_index) {
+ for (hooks = DB_OBJ(obj)->hooks[hook_entry]; hooks; hooks = hooks->next) {
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
+ grn_obj *target = grn_ctx_at(ctx, data->target);
+ int section;
+ if (target->header.type != GRN_COLUMN_INDEX) { continue; }
+ if (!is_full_text_searchable_index(ctx, target)) { continue; }
+ section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0;
+ if (section_buf) { *section_buf = section; }
+ if (n < buf_size) {
+ *ip++ = target;
+ }
+ if (n < n_index_data) {
+ index_data[n].index = target;
+ index_data[n].section = section;
+ }
+ n++;
+ }
+ }
+
for (hooks = DB_OBJ(obj)->hooks[hook_entry]; hooks; hooks = hooks->next) {
- default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
grn_obj *target = grn_ctx_at(ctx, data->target);
int section;
+
if (target->header.type != GRN_COLUMN_INDEX) { continue; }
if (op == GRN_OP_REGEXP && !is_valid_regexp_index(ctx, target)) {
continue;
}
+
+ if (prefer_full_text_search_index) {
+ if (is_full_text_searchable_index(ctx, target)) { continue; }
+ }
+
section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0;
if (section_buf) { *section_buf = section; }
if (n < buf_size) {
@@ -10858,7 +12677,7 @@ grn_column_find_index_data_column_match(grn_ctx *ctx, grn_obj *obj,
return n;
}
-static inline int
+static int
grn_column_find_index_data_column_range(grn_ctx *ctx, grn_obj *obj,
grn_operator op,
grn_index_datum *index_data,
@@ -10884,9 +12703,10 @@ grn_column_find_index_data_column_range(grn_ctx *ctx, grn_obj *obj,
}
for (hooks = DB_OBJ(obj)->hooks[hook_entry]; hooks; hooks = hooks->next) {
- default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
grn_obj *target = grn_ctx_at(ctx, data->target);
int section;
+ if (!target) { continue; }
if (target->header.type != GRN_COLUMN_INDEX) { continue; }
section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0;
if (section_buf) { *section_buf = section; }
@@ -10911,13 +12731,13 @@ grn_column_find_index_data_column_range(grn_ctx *ctx, grn_obj *obj,
return n;
}
-static inline grn_bool
+static grn_bool
is_valid_match_index(grn_ctx *ctx, grn_obj *index_column)
{
return GRN_TRUE;
}
-static inline grn_bool
+static grn_bool
is_valid_range_index(grn_ctx *ctx, grn_obj *index_column)
{
grn_obj *tokenizer;
@@ -11030,7 +12850,50 @@ grn_column_find_index_data_accessor_index_column(grn_ctx *ctx, grn_accessor *a,
return 1;
}
-static inline int
+static grn_bool
+grn_column_find_index_data_accessor_is_key_search(grn_ctx *ctx,
+ grn_accessor *accessor,
+ grn_operator op)
+{
+ if (accessor->next) {
+ return GRN_FALSE;
+ }
+
+ if (accessor->action != GRN_ACCESSOR_GET_KEY) {
+ return GRN_FALSE;
+ }
+
+ if (!grn_obj_is_table(ctx, accessor->obj)) {
+ return GRN_FALSE;
+ }
+
+ switch (op) {
+ case GRN_OP_LESS :
+ case GRN_OP_GREATER :
+ case GRN_OP_LESS_EQUAL :
+ case GRN_OP_GREATER_EQUAL :
+ switch (accessor->obj->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ return GRN_TRUE;
+ default :
+ return GRN_FALSE;
+ }
+ case GRN_OP_EQUAL :
+ switch (accessor->obj->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ return GRN_TRUE;
+ default :
+ return GRN_FALSE;
+ }
+ default :
+ return GRN_FALSE;
+ }
+}
+
+static int
grn_column_find_index_data_accessor_match(grn_ctx *ctx, grn_obj *obj,
grn_operator op,
grn_index_datum *index_data,
@@ -11073,7 +12936,7 @@ grn_column_find_index_data_accessor_match(grn_ctx *ctx, grn_obj *obj,
}
for (hooks = DB_OBJ(a->obj)->hooks[entry]; hooks; hooks = hooks->next) {
- default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
grn_obj *target = grn_ctx_at(ctx, data->target);
if (target->header.type != GRN_COLUMN_INDEX) { continue; }
@@ -11101,6 +12964,52 @@ grn_column_find_index_data_accessor_match(grn_ctx *ctx, grn_obj *obj,
}
}
+ if (!found &&
+ grn_column_find_index_data_accessor_is_key_search(ctx, a, op)) {
+ grn_obj *index;
+ int section = 0;
+
+ if ((grn_obj *)a == obj) {
+ index = a->obj;
+ } else {
+ index = (grn_obj *)a;
+ }
+
+ found = GRN_TRUE;
+ if (section_buf) {
+ *section_buf = section;
+ }
+ if (n < buf_size) {
+ *ip++ = index;
+ }
+ if (n < n_index_data) {
+ index_data[n].index = index;
+ index_data[n].section = section;
+ }
+ n++;
+ }
+
+ if (!found &&
+ a->next &&
+ grn_obj_is_table(ctx, a->obj) &&
+ a->obj->header.domain == a->next->obj->header.domain) {
+ grn_obj *index = (grn_obj *)a;
+ int section = 0;
+
+ found = GRN_TRUE;
+ if (section_buf) {
+ *section_buf = section;
+ }
+ if (n < buf_size) {
+ *ip++ = index;
+ }
+ if (n < n_index_data) {
+ index_data[n].index = index;
+ index_data[n].section = section;
+ }
+ n++;
+ }
+
if (!found) {
break;
}
@@ -11110,7 +13019,7 @@ grn_column_find_index_data_accessor_match(grn_ctx *ctx, grn_obj *obj,
return n;
}
-static inline int
+static int
grn_column_find_index_data_accessor(grn_ctx *ctx, grn_obj *obj,
grn_operator op,
grn_index_datum *index_data,
@@ -11125,12 +13034,13 @@ grn_column_find_index_data_accessor(grn_ctx *ctx, grn_obj *obj,
}
switch (op) {
case GRN_OP_EQUAL :
+ case GRN_OP_NOT_EQUAL :
case GRN_OP_TERM_EXTRACT :
if (buf_size > 0) {
index_buf[n] = obj;
}
if (n_index_data > 0) {
- index_data[n].index = obj;
+ index_data[n].index = obj;
index_data[n].section = 0;
}
n++;
@@ -11144,7 +13054,7 @@ grn_column_find_index_data_accessor(grn_ctx *ctx, grn_obj *obj,
index_buf[n] = obj;
}
if (n_index_data > 0) {
- index_data[n].index = obj;
+ index_data[n].index = obj;
index_data[n].section = 0;
}
n++;
@@ -11160,10 +13070,10 @@ grn_column_find_index_data_accessor(grn_ctx *ctx, grn_obj *obj,
if (a->obj->header.type == GRN_TABLE_PAT_KEY &&
a->obj->header.flags & GRN_OBJ_KEY_WITH_SIS) {
if (buf_size > 0) {
- index_buf[n] = obj;
+ index_buf[n] = obj;
}
if (n_index_data > 0) {
- index_data[n].index = obj;
+ index_data[n].index = obj;
index_data[n].section = 0;
}
n++;
@@ -11181,6 +13091,7 @@ grn_column_find_index_data_accessor(grn_ctx *ctx, grn_obj *obj,
case GRN_OP_GREATER_EQUAL :
case GRN_OP_CALL :
case GRN_OP_REGEXP :
+ case GRN_OP_FUZZY :
n = grn_column_find_index_data_accessor_match(ctx, obj, op,
index_data, n_index_data,
index_buf, buf_size,
@@ -11202,6 +13113,7 @@ grn_column_index(grn_ctx *ctx, grn_obj *obj, grn_operator op,
if (GRN_DB_OBJP(obj)) {
switch (op) {
case GRN_OP_EQUAL :
+ case GRN_OP_NOT_EQUAL :
n = grn_column_find_index_data_column_equal(ctx, obj, op,
NULL, 0,
index_buf, buf_size,
@@ -11214,6 +13126,7 @@ grn_column_index(grn_ctx *ctx, grn_obj *obj, grn_operator op,
case GRN_OP_NEAR2 :
case GRN_OP_SIMILAR :
case GRN_OP_REGEXP :
+ case GRN_OP_FUZZY :
n = grn_column_find_index_data_column_match(ctx, obj, op,
NULL, 0,
index_buf, buf_size,
@@ -11251,6 +13164,7 @@ grn_column_find_index_data(grn_ctx *ctx, grn_obj *obj, grn_operator op,
if (GRN_DB_OBJP(obj)) {
switch (op) {
case GRN_OP_EQUAL :
+ case GRN_OP_NOT_EQUAL :
n = grn_column_find_index_data_column_equal(ctx, obj, op,
index_data, n_index_data,
NULL, 0, NULL);
@@ -11262,6 +13176,7 @@ grn_column_find_index_data(grn_ctx *ctx, grn_obj *obj, grn_operator op,
case GRN_OP_NEAR2 :
case GRN_OP_SIMILAR :
case GRN_OP_REGEXP :
+ case GRN_OP_FUZZY :
n = grn_column_find_index_data_column_match(ctx, obj, op,
index_data, n_index_data,
NULL, 0, NULL);
@@ -11286,31 +13201,182 @@ grn_column_find_index_data(grn_ctx *ctx, grn_obj *obj, grn_operator op,
GRN_API_RETURN(n);
}
-/* todo : refine */
-static int
-tokenize(const char *str, size_t str_len, const char **tokbuf, int buf_size, const char **rest)
+static uint32_t
+grn_column_get_all_index_data_column(grn_ctx *ctx,
+ grn_obj *obj,
+ grn_index_datum *index_data,
+ uint32_t n_index_data)
{
- const char **tok = tokbuf, **tok_end = tokbuf + buf_size;
- if (buf_size > 0) {
- const char *str_end = str + str_len;
- while (str < str_end && (' ' == *str || ',' == *str)) { str++; }
- for (;;) {
- if (str == str_end) {
- *tok++ = str;
- break;
+ uint32_t n = 0;
+ grn_hook_entry hook_entry;
+ grn_hook *hooks;
+
+ switch (obj->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ hook_entry = GRN_HOOK_INSERT;
+ break;
+ default :
+ hook_entry = GRN_HOOK_SET;
+ break;
+ }
+
+ for (hooks = DB_OBJ(obj)->hooks[hook_entry]; hooks; hooks = hooks->next) {
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
+ grn_obj *target = grn_ctx_at(ctx, data->target);
+ int section = 0;
+ if (!target) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int length;
+ char hook_name[GRN_TABLE_MAX_KEY_SIZE];
+ int hook_name_length;
+
+ length = grn_obj_name(ctx, obj, name, GRN_TABLE_MAX_KEY_SIZE);
+ hook_name_length = grn_table_get_key(ctx,
+ ctx->impl->db,
+ data->target,
+ hook_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_OBJECT_CORRUPT,
+ "[column][indexes][all] "
+ "hook has a dangling reference: <%.*s> -> <%.*s>",
+ length, name,
+ hook_name_length, hook_name);
+ continue;
+ }
+ if (target->header.type != GRN_COLUMN_INDEX) {
+ continue;
+ }
+ if (MULTI_COLUMN_INDEXP(target)) {
+ section = data->section;
+ }
+ if (n < n_index_data) {
+ index_data[n].index = target;
+ index_data[n].section = section;
+ }
+ n++;
+ }
+
+ return n;
+}
+
+static uint32_t
+grn_column_get_all_index_data_accessor_index_column(grn_ctx *ctx,
+ grn_accessor *a,
+ grn_index_datum *index_data,
+ uint32_t n_index_data)
+{
+ grn_obj *index_column = a->obj;
+ int section = 0;
+
+ if (a->next) {
+ int specified_section;
+ grn_bool is_invalid_section;
+ if (a->next->next) {
+ return 0;
+ }
+ specified_section = find_section(ctx, index_column, a->next->obj);
+ is_invalid_section = (specified_section == 0);
+ if (is_invalid_section) {
+ return 0;
+ }
+ section = specified_section;
+ }
+ if (n_index_data > 0) {
+ index_data[0].index = index_column;
+ index_data[0].section = section;
+ }
+
+ return 1;
+}
+
+static uint32_t
+grn_column_get_all_index_data_accessor(grn_ctx *ctx,
+ grn_obj *obj,
+ grn_index_datum *index_data,
+ uint32_t n_index_data)
+{
+ uint32_t n = 0;
+ grn_accessor *a = (grn_accessor *)obj;
+
+ while (a) {
+ grn_hook *hooks;
+ grn_bool found = GRN_FALSE;
+ grn_hook_entry entry = (grn_hook_entry)-1;
+
+ if (a->action == GRN_ACCESSOR_GET_COLUMN_VALUE &&
+ GRN_OBJ_INDEX_COLUMNP(a->obj)) {
+ return grn_column_get_all_index_data_accessor_index_column(ctx,
+ a,
+ index_data,
+ n_index_data);
+ }
+
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_KEY :
+ entry = GRN_HOOK_INSERT;
+ break;
+ case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ entry = GRN_HOOK_SET;
+ break;
+ default :
+ break;
+ }
+
+ if (entry == (grn_hook_entry)-1) {
+ break;
+ }
+
+ for (hooks = DB_OBJ(a->obj)->hooks[entry]; hooks; hooks = hooks->next) {
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
+ grn_obj *target = grn_ctx_at(ctx, data->target);
+
+ if (target->header.type != GRN_COLUMN_INDEX) {
+ continue;
}
- if (' ' == *str || ',' == *str) {
- // *str = '\0';
- *tok++ = str;
- if (tok == tok_end) { break; }
- do { str++; } while (str < str_end && (' ' == *str || ',' == *str));
- } else {
- str++;
+
+ found = GRN_TRUE;
+ if (!a->next) {
+ int section = 0;
+
+ if (MULTI_COLUMN_INDEXP(target)) {
+ section = data->section;
+ }
+ if (n < n_index_data) {
+ index_data[n].index = target;
+ index_data[n].section = section;
+ }
+ n++;
}
}
+
+ if (!found) {
+ break;
+ }
+ a = a->next;
+ }
+
+ return n;
+}
+
+uint32_t
+grn_column_get_all_index_data(grn_ctx *ctx,
+ grn_obj *obj,
+ grn_index_datum *index_data,
+ uint32_t n_index_data)
+{
+ uint32_t n = 0;
+ GRN_API_ENTER;
+ if (GRN_DB_OBJP(obj)) {
+ n = grn_column_get_all_index_data_column(ctx, obj,
+ index_data, n_index_data);
+ } else if (GRN_ACCESSORP(obj)) {
+ n = grn_column_get_all_index_data_accessor(ctx, obj,
+ index_data, n_index_data);
}
- if (rest) { *rest = str; }
- return tok - tokbuf;
+ GRN_API_RETURN(n);
}
grn_rc
@@ -11320,7 +13386,7 @@ grn_obj_columns(grn_ctx *ctx, grn_obj *table,
grn_obj *col;
const char *p = (char *)str, *q, *r, *pe = p + str_size, *tokbuf[256];
while (p < pe) {
- int i, n = tokenize(p, pe - p, tokbuf, 256, &q);
+ int i, n = grn_tokenize(p, pe - p, tokbuf, 256, &q);
for (i = 0; i < n; i++) {
r = tokbuf[i];
while (p < r && (' ' == *p || ',' == *p)) { p++; }
@@ -11344,19 +13410,24 @@ grn_obj_columns(grn_ctx *ctx, grn_obj *table,
GRN_COLUMN_NAME_ID_LEN);
if (ai) {
if (ai->header.type == GRN_ACCESSOR) {
- cols = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
- GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
- if (cols) {
- grn_id *key;
- grn_accessor *a, *ac;
- grn_obj *target_table = table;
- for (a = (grn_accessor *)ai; a; a = a->next) {
- target_table = a->obj;
+ grn_id *key;
+ grn_accessor *id_accessor;
+ for (id_accessor = ((grn_accessor *)ai)->next;
+ id_accessor;
+ id_accessor = id_accessor->next) {
+ grn_obj *target_table = id_accessor->obj;
+
+ cols = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ if (!cols) {
+ continue;
}
grn_table_columns(ctx, target_table,
p, r - p - 1, (grn_obj *)cols);
GRN_HASH_EACH(ctx, cols, id, &key, NULL, NULL, {
if ((col = grn_ctx_at(ctx, *key))) {
+ grn_accessor *a;
+ grn_accessor *ac;
ac = accessor_new(ctx);
GRN_PTR_PUT(ctx, res, (grn_obj *)ac);
for (a = (grn_accessor *)ai; a; a = a->next) {
@@ -11406,7 +13477,7 @@ grn_table_sort_key_from_str_geo(grn_ctx *ctx, const char *str, unsigned int str_
p = str;
if ((tokbuf = GRN_MALLOCN(const char *, str_size))) {
grn_id domain = GRN_ID_NIL;
- int i, n = tokenize(str, str_size, tokbuf, str_size, NULL);
+ int i, n = grn_tokenize(str, str_size, tokbuf, str_size, NULL);
if ((keys = GRN_MALLOCN(grn_table_sort_key, n))) {
k = keys;
for (i = 0; i < n; i++) {
@@ -11470,7 +13541,7 @@ grn_table_sort_key_from_str(grn_ctx *ctx, const char *str, unsigned int str_size
return keys;
}
if ((tokbuf = GRN_MALLOCN(const char *, str_size))) {
- int i, n = tokenize(str, str_size, tokbuf, str_size, NULL);
+ int i, n = grn_tokenize(str, str_size, tokbuf, str_size, NULL);
if ((keys = GRN_MALLOCN(grn_table_sort_key, n))) {
k = keys;
for (i = 0; i < n; i++) {
@@ -11490,13 +13561,37 @@ grn_table_sort_key_from_str(grn_ctx *ctx, const char *str, unsigned int str_size
} else {
if (r - p == GRN_COLUMN_NAME_SCORE_LEN &&
memcmp(p, GRN_COLUMN_NAME_SCORE, GRN_COLUMN_NAME_SCORE_LEN) == 0) {
+ char table_name[GRN_TABLE_MAX_KEY_SIZE];
+ int table_name_size;
+ table_name_size = grn_obj_name(ctx, table,
+ table_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ if (table_name_size == 0) {
+ grn_strcpy(table_name, GRN_TABLE_MAX_KEY_SIZE, "(anonymous)");
+ table_name_size = strlen(table_name);
+ }
GRN_LOG(ctx, GRN_WARN,
- "ignore invalid sort key: <%.*s>(<%.*s>)",
- (int)(r - p), p, str_size, str);
+ "ignore invalid sort key: <%.*s>: "
+ "table:<%*.s> keys:<%.*s>",
+ (int)(r - p), p,
+ table_name_size, table_name,
+ str_size, str);
} else {
+ char table_name[GRN_TABLE_MAX_KEY_SIZE];
+ int table_name_size;
+ table_name_size = grn_obj_name(ctx, table,
+ table_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ if (table_name_size == 0) {
+ grn_strcpy(table_name, GRN_TABLE_MAX_KEY_SIZE, "(anonymous)");
+ table_name_size = strlen(table_name);
+ }
WARN(GRN_INVALID_ARGUMENT,
- "invalid sort key: <%.*s>(<%.*s>)",
- (int)(r - p), p, str_size, str);
+ "invalid sort key: <%.*s>: "
+ "table:<%.*s> keys:<%.*s>",
+ (int)(r - p), p,
+ table_name_size, table_name,
+ str_size, str);
break;
}
}
@@ -11522,7 +13617,10 @@ grn_table_sort_key_close(grn_ctx *ctx, grn_table_sort_key *keys, unsigned int nk
int i;
if (keys) {
for (i = 0; i < nkeys; i++) {
- grn_obj_unlink(ctx, keys[i].key);
+ grn_obj *key = keys[i].key;
+ if (!grn_obj_is_column(ctx, key)) {
+ grn_obj_unlink(ctx, key);
+ }
}
GRN_FREE(keys);
}
@@ -11578,1014 +13676,39 @@ exit :
GRN_API_RETURN(buf);
}
-/* grn_load */
-
-static grn_obj *
-values_add(grn_ctx *ctx, grn_loader *loader)
-{
- grn_obj *res;
- uint32_t curr_size = loader->values_size * sizeof(grn_obj);
- if (curr_size < GRN_TEXT_LEN(&loader->values)) {
- res = (grn_obj *)(GRN_TEXT_VALUE(&loader->values) + curr_size);
- res->header.domain = GRN_DB_TEXT;
- GRN_BULK_REWIND(res);
- } else {
- if (grn_bulk_space(ctx, &loader->values, sizeof(grn_obj))) { return NULL; }
- res = (grn_obj *)(GRN_TEXT_VALUE(&loader->values) + curr_size);
- GRN_TEXT_INIT(res, 0);
- }
- loader->values_size++;
- loader->last = res;
- return res;
-}
-
-static grn_obj *
-values_next(grn_ctx *ctx, grn_obj *value)
-{
- if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET ||
- value->header.domain == GRN_JSON_LOAD_OPEN_BRACE) {
- value += GRN_UINT32_VALUE(value);
- }
- return value + 1;
-}
-
-static int
-values_len(grn_ctx *ctx, grn_obj *head, grn_obj *tail)
-{
- int len;
- for (len = 0; head < tail; head = values_next(ctx, head), len++) ;
- return len;
-}
-
-static grn_id
-loader_add(grn_ctx *ctx, grn_obj *key)
-{
- int added = 0;
- grn_loader *loader = &ctx->impl->loader;
- grn_id id = grn_table_add_by_key(ctx, loader->table, key, &added);
- if (!added && loader->ifexists) {
- grn_obj *v = grn_expr_get_var_by_offset(ctx, loader->ifexists, 0);
- grn_obj *result;
- unsigned int result_boolean;
- GRN_RECORD_SET(ctx, v, id);
- result = grn_expr_exec(ctx, loader->ifexists, 0);
- GRN_TRUEP(ctx, result, result_boolean);
- if (!result_boolean) { id = 0; }
- }
- return id;
-}
-
static void
-set_vector(grn_ctx *ctx, grn_obj *column, grn_id id, grn_obj *vector)
-{
- int n = GRN_UINT32_VALUE(vector);
- grn_obj buf, *v = vector + 1;
- grn_id range_id;
- grn_obj *range;
-
- range_id = DB_OBJ(column)->range;
- range = grn_ctx_at(ctx, range_id);
- if (GRN_OBJ_TABLEP(range)) {
- GRN_RECORD_INIT(&buf, GRN_OBJ_VECTOR, range_id);
- while (n--) {
- grn_bool cast_failed = GRN_FALSE;
- grn_obj record, *element = v;
- if (range_id != element->header.domain) {
- GRN_RECORD_INIT(&record, 0, range_id);
- if (grn_obj_cast(ctx, element, &record, GRN_TRUE)) {
- cast_failed = GRN_TRUE;
- ERR_CAST(column, range, element);
- }
- element = &record;
- }
- if (!cast_failed) {
- GRN_UINT32_PUT(ctx, &buf, GRN_RECORD_VALUE(element));
- }
- if (element == &record) { GRN_OBJ_FIN(ctx, element); }
- v = values_next(ctx, v);
- }
- } else {
- if (((struct _grn_type *)range)->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
- GRN_TEXT_INIT(&buf, GRN_OBJ_VECTOR);
- while (n--) {
- if (v->header.domain == GRN_DB_TEXT) {
- grn_bool cast_failed = GRN_FALSE;
- grn_obj casted_element, *element = v;
- if (range_id != element->header.domain) {
- GRN_OBJ_INIT(&casted_element, GRN_BULK, 0, range_id);
- if (grn_obj_cast(ctx, element, &casted_element, GRN_TRUE)) {
- cast_failed = GRN_TRUE;
- ERR_CAST(column, range, element);
- }
- element = &casted_element;
- }
- if (!cast_failed) {
- grn_vector_add_element(ctx, &buf,
- GRN_TEXT_VALUE(element),
- GRN_TEXT_LEN(element), 0,
- element->header.domain);
- }
- if (element == &casted_element) { GRN_OBJ_FIN(ctx, element); }
- } else {
- ERR(GRN_INVALID_ARGUMENT, "bad syntax.");
- }
- v = values_next(ctx, v);
- }
- } else {
- grn_id value_size = ((grn_db_obj *)range)->range;
- GRN_VALUE_FIX_SIZE_INIT(&buf, GRN_OBJ_VECTOR, range_id);
- while (n--) {
- grn_bool cast_failed = GRN_FALSE;
- grn_obj casted_element, *element = v;
- if (range_id != element->header.domain) {
- GRN_OBJ_INIT(&casted_element, GRN_BULK, 0, range_id);
- if (grn_obj_cast(ctx, element, &casted_element, GRN_TRUE)) {
- cast_failed = GRN_TRUE;
- ERR_CAST(column, range, element);
- }
- element = &casted_element;
- }
- if (!cast_failed) {
- grn_bulk_write(ctx, &buf, GRN_TEXT_VALUE(element), value_size);
- }
- if (element == &casted_element) { GRN_OBJ_FIN(ctx, element); }
- v = values_next(ctx, v);
- }
- }
- }
- grn_obj_set_value(ctx, column, id, &buf, GRN_OBJ_SET);
- GRN_OBJ_FIN(ctx, &buf);
-}
-
-static void
-set_weight_vector(grn_ctx *ctx, grn_obj *column, grn_id id, grn_obj *index_value)
-{
- if (!GRN_OBJ_WEIGHT_VECTOR_COLUMNP(column)) {
- char column_name[GRN_TABLE_MAX_KEY_SIZE];
- int column_name_size;
- column_name_size = grn_obj_name(ctx, column, column_name,
- GRN_TABLE_MAX_KEY_SIZE);
- ERR(GRN_INVALID_ARGUMENT,
- "<%.*s>: columns except weight vector column don't support object value",
- column_name_size, column_name);
- return;
- }
-
- {
- unsigned int i, n;
- grn_obj vector;
- grn_obj weight_buffer;
-
- n = GRN_UINT32_VALUE(index_value);
- GRN_TEXT_INIT(&vector, GRN_OBJ_VECTOR);
- GRN_UINT32_INIT(&weight_buffer, 0);
- for (i = 0; i < n; i += 2) {
- grn_rc rc;
- grn_obj *key, *weight;
-
- key = index_value + 1 + i;
- weight = key + 1;
-
- GRN_BULK_REWIND(&weight_buffer);
- rc = grn_obj_cast(ctx, weight, &weight_buffer, GRN_TRUE);
- if (rc != GRN_SUCCESS) {
- grn_obj *range;
- range = grn_ctx_at(ctx, weight_buffer.header.domain);
- ERR_CAST(column, range, weight);
- grn_obj_unlink(ctx, range);
- break;
- }
- grn_vector_add_element(ctx, &vector,
- GRN_BULK_HEAD(key), GRN_BULK_VSIZE(key),
- GRN_UINT32_VALUE(&weight_buffer),
- key->header.domain);
- }
- grn_obj_set_value(ctx, column, id, &vector, GRN_OBJ_SET);
- GRN_OBJ_FIN(ctx, &vector);
- }
-}
-
-static inline int
-name_equal(const char *p, unsigned int size, const char *name)
-{
- if (strlen(name) != size) { return 0; }
- if (*p != GRN_DB_PSEUDO_COLUMN_PREFIX) { return 0; }
- return !memcmp(p + 1, name + 1, size - 1);
-}
-
-static void
-report_set_column_value_failure(grn_ctx *ctx,
- grn_obj *key,
- const char *column_name,
- unsigned int column_name_size,
- grn_obj *column_value)
-{
- grn_obj key_inspected, column_value_inspected;
-
- GRN_TEXT_INIT(&key_inspected, 0);
- GRN_TEXT_INIT(&column_value_inspected, 0);
- limited_size_inspect(ctx, &key_inspected, key);
- limited_size_inspect(ctx, &column_value_inspected, column_value);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "[table][load] failed to set column value: %s: "
- "key: <%.*s>, column: <%.*s>, value: <%.*s>",
- ctx->errbuf,
- (int)GRN_TEXT_LEN(&key_inspected),
- GRN_TEXT_VALUE(&key_inspected),
- column_name_size,
- column_name,
- (int)GRN_TEXT_LEN(&column_value_inspected),
- GRN_TEXT_VALUE(&column_value_inspected));
- GRN_OBJ_FIN(ctx, &key_inspected);
- GRN_OBJ_FIN(ctx, &column_value_inspected);
-}
-
-static void
-bracket_close(grn_ctx *ctx, grn_loader *loader)
-{
- grn_obj *value, *col, *ve;
- grn_id id = GRN_ID_NIL;
- grn_obj *key_value = NULL;
- grn_obj **cols = (grn_obj **)GRN_BULK_HEAD(&loader->columns);
- uint32_t begin, ndata, ncols = GRN_BULK_VSIZE(&loader->columns) / sizeof(grn_obj *);
- GRN_UINT32_POP(&loader->level, begin);
- value = ((grn_obj *)(GRN_TEXT_VALUE(&loader->values))) + begin;
- ve = ((grn_obj *)(GRN_TEXT_VALUE(&loader->values))) + loader->values_size;
- GRN_ASSERT(value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET);
- GRN_UINT32_SET(ctx, value, loader->values_size - begin - 1);
- value++;
- if (GRN_BULK_VSIZE(&loader->level) <= sizeof(uint32_t) * loader->emit_level) {
- ndata = values_len(ctx, value, ve);
- if (loader->table) {
- switch (loader->table->header.type) {
- case GRN_TABLE_HASH_KEY :
- case GRN_TABLE_PAT_KEY :
- case GRN_TABLE_DAT_KEY :
- if (loader->key_offset != -1 && ndata == ncols + 1) {
- key_value = value + loader->key_offset;
- id = loader_add(ctx, key_value);
- } else if (loader->key_offset == -1) {
- int i = 0;
- grn_obj *key_column_name = NULL;
- while (ndata--) {
- char *column_name = GRN_TEXT_VALUE(value);
- unsigned int column_name_size = GRN_TEXT_LEN(value);
- if (value->header.domain == GRN_DB_TEXT &&
- (name_equal(column_name, column_name_size,
- GRN_COLUMN_NAME_KEY) ||
- name_equal(column_name, column_name_size,
- GRN_COLUMN_NAME_ID))) {
- if (loader->key_offset != -1) {
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "duplicated key columns: <%.*s> at %d and <%.*s> at %i",
- (int)GRN_TEXT_LEN(key_column_name),
- GRN_TEXT_VALUE(key_column_name),
- loader->key_offset,
- column_name_size, column_name, i);
- return;
- }
- key_column_name = value;
- loader->key_offset = i;
- } else {
- col = grn_obj_column(ctx, loader->table,
- column_name, column_name_size);
- if (!col) {
- ERR(GRN_INVALID_ARGUMENT,
- "nonexistent column: <%.*s>",
- column_name_size, column_name);
- return;
- }
- GRN_PTR_PUT(ctx, &loader->columns, col);
- }
- value++;
- i++;
- }
- }
- break;
- case GRN_TABLE_NO_KEY :
- if ((GRN_BULK_VSIZE(&loader->level)) > 0 &&
- (ndata == 0 || ndata == ncols)) {
- id = grn_table_add(ctx, loader->table, NULL, 0, NULL);
- } else if (!ncols) {
- while (ndata--) {
- if (value->header.domain == GRN_DB_TEXT) {
- char *column_name = GRN_TEXT_VALUE(value);
- unsigned int column_name_size = GRN_TEXT_LEN(value);
- col = grn_obj_column(ctx, loader->table,
- column_name, column_name_size);
- if (!col) {
- ERR(GRN_INVALID_ARGUMENT,
- "nonexistent column: <%.*s>",
- column_name_size, column_name);
- return;
- }
- GRN_PTR_PUT(ctx, &loader->columns, col);
- value++;
- } else {
- grn_obj buffer;
- GRN_TEXT_INIT(&buffer, 0);
- grn_inspect(ctx, &buffer, value);
- ERR(GRN_INVALID_ARGUMENT,
- "column name must be string: <%.*s>",
- (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer));
- GRN_OBJ_FIN(ctx, &buffer);
- return;
- }
- }
- }
- break;
- default :
- break;
- }
- if (id) {
- int i = 0;
- while (ndata--) {
- grn_obj *column;
- if ((loader->table->header.type == GRN_TABLE_HASH_KEY ||
- loader->table->header.type == GRN_TABLE_PAT_KEY ||
- loader->table->header.type == GRN_TABLE_DAT_KEY) &&
- i == loader->key_offset) {
- /* skip this value, because it's already used as key value */
- value = values_next(ctx, value);
- i++;
- continue;
- }
-
- column = *cols;
- if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET) {
- set_vector(ctx, column, id, value);
- } else if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACE) {
- set_weight_vector(ctx, column, id, value);
- } else {
- grn_obj_set_value(ctx, column, id, value, GRN_OBJ_SET);
- }
- if (ctx->rc != GRN_SUCCESS) {
- char column_name[GRN_TABLE_MAX_KEY_SIZE];
- unsigned int column_name_size;
- column_name_size = grn_obj_name(ctx, column, column_name,
- GRN_TABLE_MAX_KEY_SIZE);
- report_set_column_value_failure(ctx, key_value,
- column_name, column_name_size,
- value);
- ERRCLR(ctx);
- }
- value = values_next(ctx, value);
- cols++;
- i++;
- }
- if (loader->each) {
- grn_obj *v = grn_expr_get_var_by_offset(ctx, loader->each, 0);
- GRN_RECORD_SET(ctx, v, id);
- grn_expr_exec(ctx, loader->each, 0);
- }
- loader->nrecords++;
- }
- }
- loader->values_size = begin;
- }
-}
-
-static void
-brace_close(grn_ctx *ctx, grn_loader *loader)
+grn_db_recover_database_remove_orphan_inspect(grn_ctx *ctx, grn_obj *db)
{
- uint32_t begin;
- grn_obj *key_value = NULL;
- grn_obj *value, *ve;
- grn_id id = GRN_ID_NIL;
- GRN_UINT32_POP(&loader->level, begin);
- value = ((grn_obj *)(GRN_TEXT_VALUE(&loader->values))) + begin;
- ve = ((grn_obj *)(GRN_TEXT_VALUE(&loader->values))) + loader->values_size;
- GRN_ASSERT(value->header.domain == GRN_JSON_LOAD_OPEN_BRACE);
- GRN_UINT32_SET(ctx, value, loader->values_size - begin - 1);
- value++;
- if (GRN_BULK_VSIZE(&loader->level) <= sizeof(uint32_t) * loader->emit_level) {
- if (loader->table) {
- switch (loader->table->header.type) {
- case GRN_TABLE_HASH_KEY :
- case GRN_TABLE_PAT_KEY :
- case GRN_TABLE_DAT_KEY :
- {
- grn_obj *v, *key_column_name = NULL;
- for (v = value; v + 1 < ve; v = values_next(ctx, v)) {
- char *column_name = GRN_TEXT_VALUE(v);
- unsigned int column_name_size = GRN_TEXT_LEN(v);
- if (v->header.domain == GRN_DB_TEXT &&
- (name_equal(column_name, column_name_size,
- GRN_COLUMN_NAME_KEY) ||
- name_equal(column_name, column_name_size,
- GRN_COLUMN_NAME_ID))) {
- if (key_column_name) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "duplicated key columns: %.*s and %.*s",
- (int)GRN_TEXT_LEN(key_column_name),
- GRN_TEXT_VALUE(key_column_name),
- column_name_size, column_name);
- goto exit;
- }
- key_column_name = value;
- v++;
- key_value = v;
- id = loader_add(ctx, key_value);
- } else {
- v = values_next(ctx, v);
- }
- }
- }
- break;
- case GRN_TABLE_NO_KEY :
- {
- grn_obj *v;
- grn_bool found_id_column = GRN_FALSE;
- for (v = value; v + 1 < ve; v = values_next(ctx, v)) {
- char *column_name = GRN_TEXT_VALUE(v);
- unsigned int column_name_size = GRN_TEXT_LEN(v);
- if (v->header.domain == GRN_DB_TEXT &&
- (name_equal(column_name, column_name_size,
- GRN_COLUMN_NAME_ID))) {
- grn_obj *id_column;
- grn_obj *id_value;
- if (found_id_column) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "duplicated '_id' column");
- goto exit;
- }
- found_id_column = GRN_TRUE;
- id_column = v;
- v = values_next(ctx, v);
- id_value = v;
- switch (id_value->header.type) {
- case GRN_DB_UINT32 :
- id = GRN_UINT32_VALUE(id_value);
- break;
- case GRN_DB_INT32 :
- id = GRN_INT32_VALUE(id_value);
- break;
- default :
- {
- grn_obj casted_id_value;
- GRN_UINT32_INIT(&casted_id_value, 0);
- if (grn_obj_cast(ctx, id_value, &casted_id_value, GRN_FALSE)) {
- grn_obj inspected;
- GRN_TEXT_INIT(&inspected, 0);
- grn_inspect(ctx, &inspected, id_value);
- ERR(GRN_INVALID_ARGUMENT,
- "<%.*s>: failed to cast to <UInt32>: <%.*s>",
- (int)column_name_size, column_name,
- (int)GRN_TEXT_LEN(&inspected),
- GRN_TEXT_VALUE(&inspected));
- grn_obj_unlink(ctx, &inspected);
- goto exit;
- } else {
- id = GRN_UINT32_VALUE(&casted_id_value);
- }
- GRN_OBJ_FIN(ctx, &casted_id_value);
- }
- break;
- }
- } else {
- v = values_next(ctx, v);
- }
- }
- }
- if (id == GRN_ID_NIL) {
- id = grn_table_add(ctx, loader->table, NULL, 0, NULL);
- }
- break;
- default :
- break;
- }
- if (id) {
- grn_obj *col;
- const char *name;
- unsigned int name_size;
- while (value + 1 < ve) {
- if (value->header.domain != GRN_DB_TEXT) { break; /* error */ }
- name = GRN_TEXT_VALUE(value);
- name_size = GRN_TEXT_LEN(value);
- col = grn_obj_column(ctx, loader->table, name, name_size);
- value++;
- /* auto column create
- if (!col) {
- if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET) {
- grn_obj *v = value + 1;
- col = grn_column_create(ctx, loader->table, name, name_size,
- NULL, GRN_OBJ_PERSISTENT|GRN_OBJ_COLUMN_VECTOR,
- grn_ctx_at(ctx, v->header.domain));
- } else {
- col = grn_column_create(ctx, loader->table, name, name_size,
- NULL, GRN_OBJ_PERSISTENT,
- grn_ctx_at(ctx, value->header.domain));
- }
- }
- */
- if (col) {
- if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET) {
- set_vector(ctx, col, id, value);
- } else if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACE) {
- set_weight_vector(ctx, col, id, value);
- } else {
- grn_obj_set_value(ctx, col, id, value, GRN_OBJ_SET);
- }
- if (ctx->rc != GRN_SUCCESS) {
- report_set_column_value_failure(ctx, key_value,
- name, name_size, value);
- ERRCLR(ctx);
- }
- grn_obj_unlink(ctx, col);
- } else {
- GRN_LOG(ctx, GRN_LOG_ERROR, "invalid column('%.*s')", (int)name_size, name);
- }
- value = values_next(ctx, value);
- }
- if (loader->each) {
- grn_obj *v = grn_expr_get_var_by_offset(ctx, loader->each, 0);
- GRN_RECORD_SET(ctx, v, id);
- grn_expr_exec(ctx, loader->each, 0);
- }
- loader->nrecords++;
- } else {
- GRN_LOG(ctx, GRN_LOG_ERROR, "neither _key nor _id is assigned");
- }
- }
- exit:
- loader->values_size = begin;
- }
-}
-
-#define JSON_READ_OPEN_BRACKET() do {\
- GRN_UINT32_PUT(ctx, &loader->level, loader->values_size);\
- values_add(ctx, loader);\
- loader->last->header.domain = GRN_JSON_LOAD_OPEN_BRACKET;\
- loader->stat = GRN_LOADER_TOKEN;\
- str++;\
-} while (0)
-
-#define JSON_READ_OPEN_BRACE() do {\
- GRN_UINT32_PUT(ctx, &loader->level, loader->values_size);\
- values_add(ctx, loader);\
- loader->last->header.domain = GRN_JSON_LOAD_OPEN_BRACE;\
- loader->stat = GRN_LOADER_TOKEN;\
- str++;\
-} while (0)
+ GRN_TABLE_EACH_BEGIN_FLAGS(ctx, db, cursor, id, GRN_CURSOR_BY_ID) {
+ void *key;
+ int key_size;
-static void
-json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned int str_len)
-{
- const char *const beg = str;
- char c;
- int len;
- const char *se = str + str_len;
- while (str < se) {
- c = *str;
- switch (loader->stat) {
- case GRN_LOADER_BEGIN :
- if ((len = grn_isspace(str, ctx->encoding))) {
- str += len;
- continue;
- }
- switch (c) {
- case '[' :
- JSON_READ_OPEN_BRACKET();
- break;
- case '{' :
- JSON_READ_OPEN_BRACE();
- break;
- default :
- ERR(GRN_INVALID_ARGUMENT,
- "JSON must start with '[' or '{': <%.*s>", str_len, beg);
- loader->stat = GRN_LOADER_END;
- break;
- }
- break;
- case GRN_LOADER_TOKEN :
- if ((len = grn_isspace(str, ctx->encoding))) {
- str += len;
- continue;
- }
- switch (c) {
- case '"' :
- loader->stat = GRN_LOADER_STRING;
- values_add(ctx, loader);
- str++;
- break;
- case '[' :
- JSON_READ_OPEN_BRACKET();
- break;
- case '{' :
- JSON_READ_OPEN_BRACE();
- break;
- case ':' :
- str++;
- break;
- case ',' :
- str++;
- break;
- case ']' :
- bracket_close(ctx, loader);
- loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END;
- str++;
- break;
- case '}' :
- brace_close(ctx, loader);
- loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END;
- str++;
- break;
- case '+' : case '-' : case '0' : case '1' : case '2' : case '3' :
- case '4' : case '5' : case '6' : case '7' : case '8' : case '9' :
- loader->stat = GRN_LOADER_NUMBER;
- values_add(ctx, loader);
- break;
- default :
- if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('_' == c)) {
- loader->stat = GRN_LOADER_SYMBOL;
- values_add(ctx, loader);
- } else {
- if ((len = grn_charlen(ctx, str, se))) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char('%c') at", c);
- GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg) + len, beg);
- GRN_LOG(ctx, GRN_LOG_ERROR, "%*s", (int)(str - beg) + 1, "^");
- str += len;
- } else {
- GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char(\\x%.2x) after", c);
- GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg), beg);
- str = se;
- }
- }
- break;
- }
- break;
- case GRN_LOADER_SYMBOL :
- if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') ||
- ('0' <= c && c <= '9') || ('_' == c)) {
- GRN_TEXT_PUTC(ctx, loader->last, c);
- str++;
- } else {
- char *v = GRN_TEXT_VALUE(loader->last);
- switch (*v) {
- case 'n' :
- if (GRN_TEXT_LEN(loader->last) == 4 && !memcmp(v, "null", 4)) {
- loader->last->header.domain = GRN_DB_VOID;
- GRN_BULK_REWIND(loader->last);
- }
- break;
- case 't' :
- if (GRN_TEXT_LEN(loader->last) == 4 && !memcmp(v, "true", 4)) {
- loader->last->header.domain = GRN_DB_BOOL;
- GRN_BOOL_SET(ctx, loader->last, GRN_TRUE);
- }
- break;
- case 'f' :
- if (GRN_TEXT_LEN(loader->last) == 5 && !memcmp(v, "false", 5)) {
- loader->last->header.domain = GRN_DB_BOOL;
- GRN_BOOL_SET(ctx, loader->last, GRN_FALSE);
- }
- break;
- default :
- break;
- }
- loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END;
- }
- break;
- case GRN_LOADER_NUMBER :
- switch (c) {
- case '+' : case '-' : case '.' : case 'e' : case 'E' :
- case '0' : case '1' : case '2' : case '3' : case '4' :
- case '5' : case '6' : case '7' : case '8' : case '9' :
- GRN_TEXT_PUTC(ctx, loader->last, c);
- str++;
- break;
- default :
- {
- const char *cur, *str = GRN_BULK_HEAD(loader->last);
- const char *str_end = GRN_BULK_CURR(loader->last);
- int64_t i = grn_atoll(str, str_end, &cur);
- if (cur == str_end) {
- loader->last->header.domain = GRN_DB_INT64;
- GRN_INT64_SET(ctx, loader->last, i);
- } else if (cur != str) {
- double d;
- char *end;
- grn_obj buf;
- GRN_TEXT_INIT(&buf, 0);
- GRN_TEXT_PUT(ctx, &buf, str, GRN_BULK_VSIZE(loader->last));
- GRN_TEXT_PUTC(ctx, &buf, '\0');
- errno = 0;
- d = strtod(GRN_TEXT_VALUE(&buf), &end);
- if (!errno && end + 1 == GRN_BULK_CURR(&buf)) {
- loader->last->header.domain = GRN_DB_FLOAT;
- GRN_FLOAT_SET(ctx, loader->last, d);
- }
- GRN_OBJ_FIN(ctx, &buf);
- }
- }
- loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END;
- break;
- }
- break;
- case GRN_LOADER_STRING :
- switch (c) {
- case '\\' :
- loader->stat = GRN_LOADER_STRING_ESC;
- str++;
- break;
- case '"' :
- str++;
- loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END;
- /*
- *(GRN_BULK_CURR(loader->last)) = '\0';
- GRN_LOG(ctx, GRN_LOG_ALERT, "read str(%s)", GRN_TEXT_VALUE(loader->last));
- */
- break;
- default :
- if ((len = grn_charlen(ctx, str, se))) {
- GRN_TEXT_PUT(ctx, loader->last, str, len);
- str += len;
- } else {
- GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char(\\x%.2x) after", c);
- GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg), beg);
- str = se;
- }
- break;
- }
- break;
- case GRN_LOADER_STRING_ESC :
- switch (c) {
- case 'b' :
- GRN_TEXT_PUTC(ctx, loader->last, '\b');
- loader->stat = GRN_LOADER_STRING;
- break;
- case 'f' :
- GRN_TEXT_PUTC(ctx, loader->last, '\f');
- loader->stat = GRN_LOADER_STRING;
- break;
- case 'n' :
- GRN_TEXT_PUTC(ctx, loader->last, '\n');
- loader->stat = GRN_LOADER_STRING;
- break;
- case 'r' :
- GRN_TEXT_PUTC(ctx, loader->last, '\r');
- loader->stat = GRN_LOADER_STRING;
- break;
- case 't' :
- GRN_TEXT_PUTC(ctx, loader->last, '\t');
- loader->stat = GRN_LOADER_STRING;
- break;
- case 'u' :
- loader->stat = GRN_LOADER_UNICODE0;
- break;
- default :
- GRN_TEXT_PUTC(ctx, loader->last, c);
- loader->stat = GRN_LOADER_STRING;
- break;
- }
- str++;
- break;
- case GRN_LOADER_UNICODE0 :
- switch (c) {
- case '0' : case '1' : case '2' : case '3' : case '4' :
- case '5' : case '6' : case '7' : case '8' : case '9' :
- loader->unichar = (c - '0') * 0x1000;
- break;
- case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' :
- loader->unichar = (c - 'a' + 10) * 0x1000;
- break;
- case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' :
- loader->unichar = (c - 'A' + 10) * 0x1000;
- break;
- default :
- ;// todo : error
- }
- loader->stat = GRN_LOADER_UNICODE1;
- str++;
- break;
- case GRN_LOADER_UNICODE1 :
- switch (c) {
- case '0' : case '1' : case '2' : case '3' : case '4' :
- case '5' : case '6' : case '7' : case '8' : case '9' :
- loader->unichar += (c - '0') * 0x100;
- break;
- case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' :
- loader->unichar += (c - 'a' + 10) * 0x100;
- break;
- case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' :
- loader->unichar += (c - 'A' + 10) * 0x100;
- break;
- default :
- ;// todo : error
- }
- loader->stat = GRN_LOADER_UNICODE2;
- str++;
- break;
- case GRN_LOADER_UNICODE2 :
- switch (c) {
- case '0' : case '1' : case '2' : case '3' : case '4' :
- case '5' : case '6' : case '7' : case '8' : case '9' :
- loader->unichar += (c - '0') * 0x10;
- break;
- case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' :
- loader->unichar += (c - 'a' + 10) * 0x10;
- break;
- case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' :
- loader->unichar += (c - 'A' + 10) * 0x10;
- break;
- default :
- ;// todo : error
- }
- loader->stat = GRN_LOADER_UNICODE3;
- str++;
- break;
- case GRN_LOADER_UNICODE3 :
- switch (c) {
- case '0' : case '1' : case '2' : case '3' : case '4' :
- case '5' : case '6' : case '7' : case '8' : case '9' :
- loader->unichar += (c - '0');
- break;
- case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' :
- loader->unichar += (c - 'a' + 10);
- break;
- case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' :
- loader->unichar += (c - 'A' + 10);
- break;
- default :
- ;// todo : error
- }
- {
- uint32_t u = loader->unichar;
- if (u < 0x80) {
- GRN_TEXT_PUTC(ctx, loader->last, u);
- } else {
- if (u < 0x800) {
- GRN_TEXT_PUTC(ctx, loader->last, ((u >> 6) & 0x1f) | 0xc0);
- } else {
- GRN_TEXT_PUTC(ctx, loader->last, (u >> 12) | 0xe0);
- GRN_TEXT_PUTC(ctx, loader->last, ((u >> 6) & 0x3f) | 0x80);
- }
- GRN_TEXT_PUTC(ctx, loader->last, (u & 0x3f) | 0x80);
- }
+ key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+#define INSPECT "inspect"
+#define INSPECT_LEN (sizeof(INSPECT) - 1)
+ if (key_size == INSPECT_LEN && memcmp(key, INSPECT, INSPECT_LEN) == 0) {
+ if (!grn_ctx_at(ctx, id)) {
+ ERRCLR(ctx);
+ grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
}
- loader->stat = GRN_LOADER_STRING;
- str++;
- break;
- case GRN_LOADER_END :
- str = se;
break;
}
- }
-}
-
-#undef JSON_READ_OPEN_BRACKET
-#undef JSON_READ_OPEN_BRACE
-
-static grn_rc
-parse_load_columns(grn_ctx *ctx, grn_obj *table,
- const char *str, unsigned int str_size, grn_obj *res)
-{
- const char *p = (char *)str, *q, *r, *pe = p + str_size, *tokbuf[256];
- while (p < pe) {
- int i, n = tokenize(p, pe - p, tokbuf, 256, &q);
- for (i = 0; i < n; i++) {
- grn_obj *col;
- r = tokbuf[i];
- while (p < r && (' ' == *p || ',' == *p)) { p++; }
- col = grn_obj_column(ctx, table, p, r - p);
- if (!col) {
- ERR(GRN_INVALID_ARGUMENT, "nonexistent column: <%.*s>", (int)(r - p), p);
- goto exit;
- }
- GRN_PTR_PUT(ctx, res, col);
- p = r;
- }
- p = q;
- }
-exit:
- return ctx->rc;
-}
-
-static grn_com_addr *addr;
-
-void
-grn_load_(grn_ctx *ctx, grn_content_type input_type,
- const char *table, unsigned int table_len,
- const char *columns, unsigned int columns_len,
- const char *values, unsigned int values_len,
- const char *ifexists, unsigned int ifexists_len,
- const char *each, unsigned int each_len,
- uint32_t emit_level)
-{
- grn_loader *loader;
- loader = &ctx->impl->loader;
- loader->emit_level = emit_level;
- if (ctx->impl->edge) {
- grn_edge *edge = grn_edges_add_communicator(ctx, addr);
- grn_obj *msg = grn_msg_open(ctx, edge->com, &ctx->impl->edge->send_old);
- /* build msg */
- grn_edge_dispatch(ctx, edge, msg);
- }
- if (table && table_len) {
- grn_ctx_loader_clear(ctx);
- loader->input_type = input_type;
- if (grn_db_check_name(ctx, table, table_len)) {
- GRN_DB_CHECK_NAME_ERR("[table][load]", table, table_len);
- loader->stat = GRN_LOADER_END;
- return;
- }
- loader->table = grn_ctx_get(ctx, table, table_len);
- if (!loader->table) {
- ERR(GRN_INVALID_ARGUMENT, "nonexistent table: <%.*s>", table_len, table);
- loader->stat = GRN_LOADER_END;
- return;
- }
- if (loader->table && columns && columns_len) {
- int i, n_columns;
- grn_obj parsed_columns;
-
- GRN_PTR_INIT(&parsed_columns, GRN_OBJ_VECTOR, GRN_ID_NIL);
- if (parse_load_columns(ctx, loader->table, columns, columns_len,
- &parsed_columns)) {
- loader->stat = GRN_LOADER_END;
- return;
- }
- n_columns = GRN_BULK_VSIZE(&parsed_columns) / sizeof(grn_obj *);
- for (i = 0; i < n_columns; i++) {
- grn_obj *column;
- column = GRN_PTR_VALUE_AT(&parsed_columns, i);
- if (column->header.type == GRN_ACCESSOR &&
- ((grn_accessor *)column)->action == GRN_ACCESSOR_GET_KEY) {
- loader->key_offset = i;
- grn_obj_unlink(ctx, column);
- } else {
- GRN_PTR_PUT(ctx, &loader->columns, column);
- }
- }
- GRN_OBJ_FIN(ctx, &parsed_columns);
- }
- if (ifexists && ifexists_len) {
- grn_obj *v;
- GRN_EXPR_CREATE_FOR_QUERY(ctx, loader->table, loader->ifexists, v);
- if (loader->ifexists && v) {
- grn_expr_parse(ctx, loader->ifexists, ifexists, ifexists_len,
- NULL, GRN_OP_EQUAL, GRN_OP_AND,
- GRN_EXPR_SYNTAX_SCRIPT|GRN_EXPR_ALLOW_UPDATE);
- }
- }
- if (each && each_len) {
- grn_obj *v;
- GRN_EXPR_CREATE_FOR_QUERY(ctx, loader->table, loader->each, v);
- if (loader->each && v) {
- grn_expr_parse(ctx, loader->each, each, each_len,
- NULL, GRN_OP_EQUAL, GRN_OP_AND,
- GRN_EXPR_SYNTAX_SCRIPT|GRN_EXPR_ALLOW_UPDATE);
- }
- }
- } else {
- if (!loader->table) {
- ERR(GRN_INVALID_ARGUMENT, "mandatory \"table\" parameter is absent");
- loader->stat = GRN_LOADER_END;
- return;
- }
- input_type = loader->input_type;
- }
- switch (input_type) {
- case GRN_CONTENT_JSON :
- json_read(ctx, loader, values, values_len);
- break;
- case GRN_CONTENT_NONE :
- case GRN_CONTENT_TSV :
- case GRN_CONTENT_XML :
- case GRN_CONTENT_MSGPACK :
- case GRN_CONTENT_GROONGA_COMMAND_LIST :
- ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "unsupported input_type");
- // todo
- break;
- }
-}
-
-grn_rc
-grn_load(grn_ctx *ctx, grn_content_type input_type,
- const char *table, unsigned int table_len,
- const char *columns, unsigned int columns_len,
- const char *values, unsigned int values_len,
- const char *ifexists, unsigned int ifexists_len,
- const char *each, unsigned int each_len)
-{
- if (!ctx || !ctx->impl) {
- ERR(GRN_INVALID_ARGUMENT, "db not initialized");
- return ctx->rc;
- }
- GRN_API_ENTER;
- grn_load_(ctx, input_type, table, table_len,
- columns, columns_len, values, values_len,
- ifexists, ifexists_len, each, each_len, 1);
- GRN_API_RETURN(ctx->rc);
+#undef INSPECT
+#undef INSPECT_LEN
+ } GRN_TABLE_EACH_END(ctx, cursor);
}
static void
grn_db_recover_database(grn_ctx *ctx, grn_obj *db)
{
- if (!grn_obj_is_locked(ctx, db)) {
+ if (grn_obj_is_locked(ctx, db)) {
+ ERR(GRN_OBJECT_CORRUPT,
+ "[db][recover] database may be broken. Please re-create the database");
return;
}
- ERR(GRN_OBJECT_CORRUPT,
- "[db][recover] database may be broken. Please re-create the database");
+ grn_db_clear_dirty(ctx, db);
+ grn_db_recover_database_remove_orphan_inspect(ctx, db);
}
static void
@@ -12629,14 +13752,39 @@ grn_db_recover_data_column(grn_ctx *ctx, grn_obj *data_column)
static void
grn_db_recover_index_column(grn_ctx *ctx, grn_obj *index_column)
{
- grn_ii *ii = (grn_ii *)index_column;
-
if (!grn_obj_is_locked(ctx, index_column)) {
return;
}
- grn_ii_truncate(ctx, ii);
- build_index(ctx, index_column);
+ grn_index_column_rebuild(ctx, index_column);
+}
+
+static grn_bool
+grn_db_recover_is_builtin(grn_ctx *ctx, grn_id id, grn_table_cursor *cursor)
+{
+ void *key;
+ const char *name;
+ int name_size;
+
+ if (id < GRN_N_RESERVED_TYPES) {
+ return GRN_TRUE;
+ }
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &key);
+ name = key;
+
+#define NAME_EQUAL(value) \
+ (name_size == strlen(value) && memcmp(name, value, strlen(value)) == 0)
+
+ if (NAME_EQUAL("inspect")) {
+ /* Just for compatibility. It's needed for users who used
+ Groonga master at between 2016-02-03 and 2016-02-26. */
+ return GRN_TRUE;
+ }
+
+#undef NAME_EQUAL
+
+ return GRN_FALSE;
}
grn_rc
@@ -12644,9 +13792,12 @@ grn_db_recover(grn_ctx *ctx, grn_obj *db)
{
grn_table_cursor *cursor;
grn_id id;
+ grn_bool is_close_opened_object_mode;
GRN_API_ENTER;
+ is_close_opened_object_mode = (grn_thread_get_limit() == 1);
+
grn_db_recover_database(ctx, db);
if (ctx->rc != GRN_SUCCESS) {
GRN_API_RETURN(ctx->rc);
@@ -12663,6 +13814,10 @@ grn_db_recover(grn_ctx *ctx, grn_obj *db)
while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
grn_obj *object;
+ if (is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
if ((object = grn_ctx_at(ctx, id))) {
switch (object->header.type) {
case GRN_TABLE_NO_KEY :
@@ -12683,7 +13838,13 @@ grn_db_recover(grn_ctx *ctx, grn_obj *db)
}
grn_obj_unlink(ctx, object);
} else {
- ERRCLR(ctx);
+ if (grn_db_recover_is_builtin(ctx, id, cursor)) {
+ ERRCLR(ctx);
+ }
+ }
+
+ if (is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
}
if (ctx->rc != GRN_SUCCESS) {
@@ -12696,7 +13857,38 @@ grn_db_recover(grn_ctx *ctx, grn_obj *db)
}
grn_rc
-grn_ctx_get_all_tables(grn_ctx *ctx, grn_obj *tables_buffer)
+grn_db_unmap(grn_ctx *ctx, grn_obj *db)
+{
+ grn_id id;
+ db_value *vp;
+ grn_db *s = (grn_db *)db;
+
+ GRN_API_ENTER;
+
+ GRN_TINY_ARRAY_EACH(&s->values, 1, grn_db_curr_id(ctx, db), id, vp, {
+ grn_obj *obj = vp->ptr;
+
+ if (obj) {
+ switch (obj->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ grn_obj_close(ctx, obj);
+ break;
+ }
+ }
+ });
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+static grn_rc
+grn_ctx_get_all_objects(grn_ctx *ctx, grn_obj *objects_buffer,
+ grn_bool (*predicate)(grn_ctx *ctx, grn_obj *object))
{
grn_obj *db;
grn_table_cursor *cursor;
@@ -12719,8 +13911,8 @@ grn_ctx_get_all_tables(grn_ctx *ctx, grn_obj *tables_buffer)
grn_obj *object;
if ((object = grn_ctx_at(ctx, id))) {
- if (grn_obj_is_table(ctx, object)) {
- GRN_PTR_PUT(ctx, tables_buffer, object);
+ if (predicate(ctx, object)) {
+ GRN_PTR_PUT(ctx, objects_buffer, object);
} else {
grn_obj_unlink(ctx, object);
}
@@ -12734,3 +13926,126 @@ grn_ctx_get_all_tables(grn_ctx *ctx, grn_obj *tables_buffer)
GRN_API_RETURN(ctx->rc);
}
+
+grn_rc
+grn_ctx_get_all_tables(grn_ctx *ctx, grn_obj *tables_buffer)
+{
+ return grn_ctx_get_all_objects(ctx, tables_buffer, grn_obj_is_table);
+}
+
+grn_rc
+grn_ctx_get_all_types(grn_ctx *ctx, grn_obj *types_buffer)
+{
+ return grn_ctx_get_all_objects(ctx, types_buffer, grn_obj_is_type);
+}
+
+grn_rc
+grn_ctx_get_all_tokenizers(grn_ctx *ctx, grn_obj *tokenizers_buffer)
+{
+ return grn_ctx_get_all_objects(ctx, tokenizers_buffer,
+ grn_obj_is_tokenizer_proc);
+}
+
+grn_rc
+grn_ctx_get_all_normalizers(grn_ctx *ctx, grn_obj *normalizers_buffer)
+{
+ return grn_ctx_get_all_objects(ctx, normalizers_buffer,
+ grn_obj_is_normalizer_proc);
+}
+
+grn_rc
+grn_ctx_get_all_token_filters(grn_ctx *ctx, grn_obj *token_filters_buffer)
+{
+ return grn_ctx_get_all_objects(ctx, token_filters_buffer,
+ grn_obj_is_token_filter_proc);
+}
+
+grn_rc
+grn_ctx_push_temporary_open_space(grn_ctx *ctx)
+{
+ grn_obj *stack;
+ grn_obj *space;
+ grn_obj buffer;
+
+ GRN_API_ENTER;
+
+ stack = &(ctx->impl->temporary_open_spaces.stack);
+ GRN_VOID_INIT(&buffer);
+ grn_bulk_write(ctx, stack, (const char *)&buffer, sizeof(grn_obj));
+ space = ((grn_obj *)GRN_BULK_CURR(stack)) - 1;
+ GRN_PTR_INIT(space, GRN_OBJ_VECTOR | GRN_OBJ_OWN, GRN_ID_NIL);
+
+ ctx->impl->temporary_open_spaces.current = space;
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_ctx_pop_temporary_open_space(grn_ctx *ctx)
+{
+ grn_obj *stack;
+ grn_obj *space;
+
+ GRN_API_ENTER;
+
+ stack = &(ctx->impl->temporary_open_spaces.stack);
+ if (GRN_BULK_EMPTYP(stack)) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[ctx][temporary-open-spaces][pop] too much pop");
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ space = ctx->impl->temporary_open_spaces.current;
+ GRN_OBJ_FIN(ctx, space);
+ grn_bulk_truncate(ctx, stack, GRN_BULK_VSIZE(stack) - sizeof(grn_obj));
+
+ if (GRN_BULK_EMPTYP(stack)) {
+ space = NULL;
+ } else {
+ space = ((grn_obj *)GRN_BULK_CURR(stack)) - 1;
+ }
+ ctx->impl->temporary_open_spaces.current = space;
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_ctx_merge_temporary_open_space(grn_ctx *ctx)
+{
+ grn_obj *stack;
+ grn_obj *space;
+ grn_obj *next_space;
+
+ GRN_API_ENTER;
+
+ stack = &(ctx->impl->temporary_open_spaces.stack);
+ if (GRN_BULK_VSIZE(stack) < sizeof(grn_obj) * 2) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[ctx][temporary-open-spaces][merge] "
+ "merge requires at least two spaces");
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ space = ctx->impl->temporary_open_spaces.current;
+ next_space = ctx->impl->temporary_open_spaces.current - 1;
+ {
+ unsigned int i, n_elements;
+ n_elements = GRN_BULK_VSIZE(space) / sizeof(grn_obj *);
+ for (i = 0; i < n_elements; i++) {
+ grn_obj *element = GRN_PTR_VALUE_AT(space, i);
+ GRN_PTR_PUT(ctx, next_space, element);
+ }
+ }
+ GRN_BULK_REWIND(space);
+ GRN_OBJ_FIN(ctx, space);
+ grn_bulk_truncate(ctx, stack, GRN_BULK_VSIZE(stack) - sizeof(grn_obj));
+
+ if (GRN_BULK_EMPTYP(stack)) {
+ space = NULL;
+ } else {
+ space = ((grn_obj *)GRN_BULK_CURR(stack)) - 1;
+ }
+ ctx->impl->temporary_open_spaces.current = space;
+
+ GRN_API_RETURN(ctx->rc);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/dump.c b/storage/mroonga/vendor/groonga/lib/dump.c
new file mode 100644
index 00000000000..0c6eb680180
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dump.c
@@ -0,0 +1,112 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_ctx.h"
+
+grn_rc
+grn_dump_table_create_flags(grn_ctx *ctx,
+ grn_table_flags flags,
+ grn_obj *buffer)
+{
+ GRN_API_ENTER;
+
+ switch (flags & GRN_OBJ_TABLE_TYPE_MASK) {
+ case GRN_OBJ_TABLE_HASH_KEY:
+ GRN_TEXT_PUTS(ctx, buffer, "TABLE_HASH_KEY");
+ break;
+ case GRN_OBJ_TABLE_PAT_KEY:
+ GRN_TEXT_PUTS(ctx, buffer, "TABLE_PAT_KEY");
+ break;
+ case GRN_OBJ_TABLE_DAT_KEY:
+ GRN_TEXT_PUTS(ctx, buffer, "TABLE_DAT_KEY");
+ break;
+ case GRN_OBJ_TABLE_NO_KEY:
+ GRN_TEXT_PUTS(ctx, buffer, "TABLE_NO_KEY");
+ break;
+ }
+ if (flags & GRN_OBJ_KEY_LARGE) {
+ GRN_TEXT_PUTS(ctx, buffer, "|KEY_LARGE");
+ }
+ if (flags & GRN_OBJ_KEY_WITH_SIS) {
+ GRN_TEXT_PUTS(ctx, buffer, "|KEY_WITH_SIS");
+ }
+ if (flags & GRN_OBJ_KEY_NORMALIZE) {
+ GRN_TEXT_PUTS(ctx, buffer, "|KEY_NORMALIZE");
+ }
+ if (flags & GRN_OBJ_PERSISTENT) {
+ GRN_TEXT_PUTS(ctx, buffer, "|PERSISTENT");
+ }
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_dump_column_create_flags(grn_ctx *ctx,
+ grn_column_flags flags,
+ grn_obj *buffer)
+{
+ GRN_API_ENTER;
+
+ switch (flags & GRN_OBJ_COLUMN_TYPE_MASK) {
+ case GRN_OBJ_COLUMN_SCALAR:
+ GRN_TEXT_PUTS(ctx, buffer, "COLUMN_SCALAR");
+ break;
+ case GRN_OBJ_COLUMN_VECTOR:
+ GRN_TEXT_PUTS(ctx, buffer, "COLUMN_VECTOR");
+ if (flags & GRN_OBJ_WITH_WEIGHT) {
+ GRN_TEXT_PUTS(ctx, buffer, "|WITH_WEIGHT");
+ }
+ break;
+ case GRN_OBJ_COLUMN_INDEX:
+ GRN_TEXT_PUTS(ctx, buffer, "COLUMN_INDEX");
+ if (flags & GRN_OBJ_WITH_SECTION) {
+ GRN_TEXT_PUTS(ctx, buffer, "|WITH_SECTION");
+ }
+ if (flags & GRN_OBJ_WITH_WEIGHT) {
+ GRN_TEXT_PUTS(ctx, buffer, "|WITH_WEIGHT");
+ }
+ if (flags & GRN_OBJ_WITH_POSITION) {
+ GRN_TEXT_PUTS(ctx, buffer, "|WITH_POSITION");
+ }
+ if (flags & GRN_OBJ_INDEX_SMALL) {
+ GRN_TEXT_PUTS(ctx, buffer, "|INDEX_SMALL");
+ }
+ if (flags & GRN_OBJ_INDEX_MEDIUM) {
+ GRN_TEXT_PUTS(ctx, buffer, "|INDEX_MEDIUM");
+ }
+ break;
+ }
+ switch (flags & GRN_OBJ_COMPRESS_MASK) {
+ case GRN_OBJ_COMPRESS_NONE:
+ break;
+ case GRN_OBJ_COMPRESS_ZLIB:
+ GRN_TEXT_PUTS(ctx, buffer, "|COMPRESS_ZLIB");
+ break;
+ case GRN_OBJ_COMPRESS_LZ4:
+ GRN_TEXT_PUTS(ctx, buffer, "|COMPRESS_LZ4");
+ break;
+ case GRN_OBJ_COMPRESS_ZSTD:
+ GRN_TEXT_PUTS(ctx, buffer, "|COMPRESS_ZSTD");
+ break;
+ }
+ if (flags & GRN_OBJ_PERSISTENT) {
+ GRN_TEXT_PUTS(ctx, buffer, "|PERSISTENT");
+ }
+
+ GRN_API_RETURN(ctx->rc);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/egn.cpp b/storage/mroonga/vendor/groonga/lib/egn.cpp
deleted file mode 100644
index c7e7357fffb..00000000000
--- a/storage/mroonga/vendor/groonga/lib/egn.cpp
+++ /dev/null
@@ -1,3245 +0,0 @@
-/* -*- c-basic-offset: 2 -*- */
-/*
- Copyright(C) 2015 Brazil
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License version 2.1 as published by the Free Software Foundation.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifdef GRN_WITH_EGN
-
-#include "grn_egn.hpp"
-
-#include <cctype>
-#include <cstdio>
-#include <limits>
-#include <memory>
-#include <string>
-
-#include <iostream> // for debug!
-
-#include "grn_ctx_impl.h"
-#include "grn_db.h"
-#include "grn_output.h"
-#include "grn_str.h"
-
-// TODO: Error handling.
-
-namespace {
-
-enum { GRN_EGN_MAX_BATCH_SIZE = 1024 };
-
-bool grn_egn_is_table_cursor(grn_obj *obj) {
- if (!obj) {
- return false;
- }
- switch (obj->header.type) {
- case GRN_CURSOR_TABLE_PAT_KEY:
- case GRN_CURSOR_TABLE_DAT_KEY:
- case GRN_CURSOR_TABLE_HASH_KEY:
- case GRN_CURSOR_TABLE_NO_KEY: {
- return true;
- }
- default: {
- return false;
- }
- }
-}
-
-bool grn_egn_is_table(grn_obj *obj) {
- if (!obj) {
- return false;
- }
- switch (obj->header.type) {
- case GRN_TABLE_HASH_KEY:
- case GRN_TABLE_PAT_KEY:
- case GRN_TABLE_DAT_KEY:
- case GRN_TABLE_NO_KEY: {
- return true;
- }
- default: {
- return false;
- }
- }
-}
-
-} // namespace
-
-namespace grn {
-namespace egn {
-
-// -- TableCursor --
-
-// TableCursor is a wrapper for grn_table_cursor:
-// - GRN_CURSOR_PAT_KEY
-// - GRN_CURSOR_DAT_KEY
-// - GRN_CURSOR_HASH_KEY
-// - GRN_CURSOR_NO_KEY
-class TableCursor : public Cursor {
- public:
- ~TableCursor() {
- grn_table_cursor_close(ctx_, cursor_);
- }
-
- static grn_rc open(grn_ctx *ctx, grn_obj *cursor, Score default_score,
- Cursor **wrapper) {
- if (!ctx || !grn_egn_is_table_cursor(cursor) || !wrapper) {
- return GRN_INVALID_ARGUMENT;
- }
- TableCursor *new_wrapper =
- new (std::nothrow) TableCursor(ctx, cursor, default_score);
- if (!new_wrapper) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *wrapper = new_wrapper;
- return GRN_SUCCESS;
- }
-
- grn_rc read(Record *records, size_t size, size_t *count);
-
- private:
- grn_ctx *ctx_;
- grn_obj *cursor_;
- Score default_score_;
-
- TableCursor(grn_ctx *ctx, grn_obj *cursor, Score default_score)
- : Cursor(), ctx_(ctx), cursor_(cursor), default_score_(default_score) {}
-};
-
-grn_rc TableCursor::read(Record *records, size_t size, size_t *count) {
- if ((!records && (size != 0)) || !count) {
- return GRN_INVALID_ARGUMENT;
- }
- switch (cursor_->header.type) {
- case GRN_CURSOR_TABLE_PAT_KEY: {
- for (size_t i = 0; i < size; ++i) {
- grn_id id = grn_pat_cursor_next(
- ctx_, reinterpret_cast<grn_pat_cursor *>(cursor_));
- if (id == GRN_ID_NIL) {
- *count = i;
- return GRN_SUCCESS;
- }
- records[i].id = id;
- records[i].score = default_score_;
- }
- break;
- }
- case GRN_CURSOR_TABLE_DAT_KEY: {
- for (size_t i = 0; i < size; ++i) {
- grn_id id = grn_dat_cursor_next(
- ctx_, reinterpret_cast<grn_dat_cursor *>(cursor_));
- if (id == GRN_ID_NIL) {
- *count = i;
- return GRN_SUCCESS;
- }
- records[i].id = id;
- records[i].score = default_score_;
- }
- break;
- }
- case GRN_CURSOR_TABLE_HASH_KEY: {
- for (size_t i = 0; i < size; ++i) {
- grn_id id = grn_hash_cursor_next(
- ctx_, reinterpret_cast<grn_hash_cursor *>(cursor_));
- if (id == GRN_ID_NIL) {
- *count = i;
- return GRN_SUCCESS;
- }
- records[i].id = id;
- records[i].score = default_score_;
- }
- break;
- }
- case GRN_CURSOR_TABLE_NO_KEY: {
- for (size_t i = 0; i < size; ++i) {
- grn_id id = grn_array_cursor_next(
- ctx_, reinterpret_cast<grn_array_cursor *>(cursor_));
- if (id == GRN_ID_NIL) {
- *count = i;
- return GRN_SUCCESS;
- }
- records[i].id = id;
- records[i].score = default_score_;
- }
- break;
- }
- default: {
- return GRN_UNKNOWN_ERROR;
- }
- }
- *count = size;
- return GRN_SUCCESS;
-}
-
-// -- Cursor --
-
-grn_rc Cursor::open_table_cursor(
- grn_ctx *ctx, grn_obj *table, Cursor **cursor) {
- if (!ctx || !grn_egn_is_table(table) || !cursor) {
- return GRN_INVALID_ARGUMENT;
- }
- grn_table_cursor *table_cursor = grn_table_cursor_open(
- ctx, table, NULL, 0, NULL, 0, 0, -1,
- GRN_CURSOR_ASCENDING | GRN_CURSOR_BY_ID);
- if (!table_cursor) {
- return ctx->rc;
- }
- grn_rc rc = TableCursor::open(ctx, table_cursor, 0.0, cursor);
- if (rc != GRN_SUCCESS) {
- grn_table_cursor_close(ctx, table_cursor);
- }
- return rc;
-}
-
-grn_rc Cursor::read(Record *records, size_t size, size_t *count) {
- if ((!records && (size != 0)) || !count) {
- return GRN_INVALID_ARGUMENT;
- }
- *count = 0;
- return GRN_SUCCESS;
-}
-
-// -- ExpressionNode --
-
-class ExpressionNode {
- public:
- ExpressionNode() {}
- virtual ~ExpressionNode() {}
-
- virtual ExpressionNodeType type() const = 0;
- virtual DataType data_type() const = 0;
-
- virtual grn_rc filter(Record *input, size_t input_size,
- Record *output, size_t *output_size) {
- return GRN_OPERATION_NOT_SUPPORTED;
- }
- virtual grn_rc adjust(Record *records, size_t num_records) {
- return GRN_OPERATION_NOT_SUPPORTED;
- }
-};
-
-// -- TypedNode<T> --
-
-template <typename T>
-class TypedNode : public ExpressionNode {
- public:
- TypedNode() : ExpressionNode() {}
- virtual ~TypedNode() {}
-
- DataType data_type() const {
- return T::data_type();
- }
-
- virtual grn_rc evaluate(
- const Record *records, size_t num_records, T *results) = 0;
-};
-
-// -- TypedNode<Bool> --
-
-template <>
-class TypedNode<Bool> : public ExpressionNode {
- public:
- TypedNode() : ExpressionNode(), values_for_filter_() {}
- virtual ~TypedNode() {}
-
- DataType data_type() const {
- return Bool::data_type();
- }
-
- virtual grn_rc filter(Record *input, size_t input_size,
- Record *output, size_t *output_size);
-
- virtual grn_rc evaluate(
- const Record *records, size_t num_records, Bool *results) = 0;
-
- private:
- std::vector<Bool> values_for_filter_;
-};
-
-grn_rc TypedNode<Bool>::filter(Record *input, size_t input_size,
- Record *output, size_t *output_size) {
- if (values_for_filter_.size() < input_size) {
- values_for_filter_.resize(input_size);
- }
- grn_rc rc = evaluate(input, input_size, &*values_for_filter_.begin());
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- size_t count = 0;
- for (size_t i = 0; i < input_size; ++i) {
- if (values_for_filter_[i].raw) {
- output[count] = input[i];
- ++count;
- }
- }
- *output_size = count;
- return GRN_SUCCESS;
-}
-
-// -- TypedNode<Float> --
-
-template <>
-class TypedNode<Float> : public ExpressionNode {
- public:
- TypedNode() : ExpressionNode(), values_for_adjust_() {}
- virtual ~TypedNode() {}
-
- DataType data_type() const {
- return Float::data_type();
- }
-
- virtual grn_rc adjust(Record *records, size_t num_records);
-
- virtual grn_rc evaluate(
- const Record *records, size_t num_records, Float *results) = 0;
-
- private:
- std::vector<Float> values_for_adjust_;
-};
-
-grn_rc TypedNode<Float>::adjust(Record *records, size_t num_records) {
- if (values_for_adjust_.size() < num_records) {
- values_for_adjust_.resize(num_records);
- }
- grn_rc rc = evaluate(records, num_records, &*values_for_adjust_.begin());
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- for (size_t i = 0; i < num_records; ++i) {
- records[i].score = values_for_adjust_[i].raw;
- }
- return GRN_SUCCESS;
-}
-
-// -- IDNode --
-
-class IDNode : public TypedNode<Int> {
- public:
- ~IDNode() {}
-
- static grn_rc open(ExpressionNode **node) {
- ExpressionNode *new_node = new (std::nothrow) IDNode();
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_ID_NODE;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Int *results) {
- for (size_t i = 0; i < num_records; ++i) {
- results[i] = Int(records[i].id);
- }
- return GRN_SUCCESS;
- }
-
- private:
- IDNode() : TypedNode<Int>() {}
-};
-
-// -- ScoreNode --
-
-class ScoreNode : public TypedNode<Float> {
- public:
- ~ScoreNode() {}
-
- static grn_rc open(ExpressionNode **node) {
- ExpressionNode *new_node = new (std::nothrow) ScoreNode();
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_SCORE_NODE;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Float *results) {
- for (size_t i = 0; i < num_records; ++i) {
- results[i] = Float(records[i].score);
- }
- return GRN_SUCCESS;
- }
-
- private:
- ScoreNode() : TypedNode<Float>() {}
-};
-
-// -- ConstantNode<T> --
-
-template <typename T>
-class ConstantNode : public TypedNode<T> {
- public:
- ~ConstantNode() {}
-
- static grn_rc open(const T &value, ExpressionNode **node) {
- ConstantNode *new_node = new (std::nothrow) ConstantNode(value);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_CONSTANT_NODE;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, T *results) {
- for (size_t i = 0; i < num_records; ++i) {
- results[i] = value_;
- }
- return GRN_SUCCESS;
- }
-
- private:
- T value_;
-
- explicit ConstantNode(const T &value) : TypedNode<T>(), value_(value) {}
-};
-
-// -- ConstantNode<Bool> --
-
-template <>
-class ConstantNode<Bool> : public TypedNode<Bool> {
- public:
- ~ConstantNode() {}
-
- static grn_rc open(Bool value, ExpressionNode **node) {
- ConstantNode *new_node = new (std::nothrow) ConstantNode(value);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_CONSTANT_NODE;
- }
-
- grn_rc filter(Record *input, size_t input_size,
- Record *output, size_t *output_size);
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Bool *results) {
- for (size_t i = 0; i < num_records; ++i) {
- results[i] = value_;
- }
- return GRN_SUCCESS;
- }
-
- private:
- Bool value_;
-
- explicit ConstantNode(Bool value) : TypedNode<Bool>(), value_(value) {}
-};
-
-grn_rc ConstantNode<Bool>::filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size) {
- if (value_.raw == GRN_TRUE) {
- // The I/O areas are the same and there is no need to copy records.
- if (input != output) {
- for (size_t i = 0; i < input_size; ++i) {
- output[i] = input[i];
- }
- }
- *output_size = input_size;
- } else {
- *output_size = 0;
- }
- return GRN_SUCCESS;
-}
-
-// -- ConstantNode<Float> --
-
-template <>
-class ConstantNode<Float> : public TypedNode<Float> {
- public:
- ~ConstantNode() {}
-
- static grn_rc open(Float value, ExpressionNode **node) {
- ConstantNode *new_node = new (std::nothrow) ConstantNode(value);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_CONSTANT_NODE;
- }
-
- grn_rc adjust(Record *records, size_t num_records) {
- for (size_t i = 0; i < num_records; ++i) {
- records[i].score = value_.raw;
- }
- return GRN_SUCCESS;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Float *results) {
- for (size_t i = 0; i < num_records; ++i) {
- results[i] = value_;
- }
- return GRN_SUCCESS;
- }
-
- private:
- Float value_;
-
- explicit ConstantNode(Float value) : TypedNode<Float>(), value_(value) {}
-};
-
-// -- ConstantNode<Text> --
-
-template <>
-class ConstantNode<Text> : public TypedNode<Text> {
- public:
- ~ConstantNode() {}
-
- static grn_rc open(const Text &value, ExpressionNode **node) {
- ConstantNode *new_node = new (std::nothrow) ConstantNode(value);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- try {
- new_node->value_buf_.resize(value.raw.size);
- } catch (const std::bad_alloc &) {
- delete new_node;
- return GRN_NO_MEMORY_AVAILABLE;
- }
- std::memcpy(&*new_node->value_buf_.begin(), value.raw.ptr, value.raw.size);
- new_node->value_.raw.ptr = &*new_node->value_buf_.begin();
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_CONSTANT_NODE;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Text *results) {
- for (size_t i = 0; i < num_records; ++i) {
- results[i] = value_;
- }
- return GRN_SUCCESS;
- }
-
- private:
- Text value_;
- std::vector<char> value_buf_;
-
- explicit ConstantNode(const Text &value)
- : TypedNode<Text>(), value_(value), value_buf_() {}
-};
-
-// -- ColumnNode --
-
-template <typename T>
-class ColumnNode : public TypedNode<T> {
- public:
- ~ColumnNode() {}
-
- static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
- ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_COLUMN_NODE;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, T *results) {
- // TODO
- return GRN_OPERATION_NOT_SUPPORTED;
- }
-
- private:
- grn_ctx *ctx_;
- grn_obj *column_;
-
- ColumnNode(grn_ctx *ctx, grn_obj *column)
- : TypedNode<T>(), ctx_(ctx), column_(column) {}
-};
-
-// -- ColumnNode<Bool> --
-
-template <>
-class ColumnNode<Bool> : public TypedNode<Bool> {
- public:
- ~ColumnNode() {}
-
- static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
- ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_COLUMN_NODE;
- }
-
- grn_rc filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size);
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Bool *results);
-
- private:
- grn_ctx *ctx_;
- grn_obj *column_;
-
- ColumnNode(grn_ctx *ctx, grn_obj *column)
- : TypedNode<Bool>(), ctx_(ctx), column_(column) {}
-};
-
-grn_rc ColumnNode<Bool>::filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size) {
- grn_obj value;
- GRN_BOOL_INIT(&value, 0);
- size_t count = 0;
- for (size_t i = 0; i < input_size; ++i) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, input[i].id, &value);
- if (ctx_->rc != GRN_SUCCESS) {
- return ctx_->rc;
- }
- if (GRN_BOOL_VALUE(&value) == GRN_TRUE) {
- output[count] = input[i];
- ++count;
- }
- }
- GRN_OBJ_FIN(ctx_, &value);
- *output_size = count;
- return GRN_SUCCESS;
-}
-
-grn_rc ColumnNode<Bool>::evaluate(
- const Record *records, size_t num_records, Bool *results) {
- grn_obj value;
- GRN_BOOL_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- if (ctx_->rc != GRN_SUCCESS) {
- return ctx_->rc;
- }
- results[i] = Bool(GRN_BOOL_VALUE(&value) == GRN_TRUE);
- }
- GRN_OBJ_FIN(ctx_, &value);
- return GRN_SUCCESS;
-}
-
-// -- ColumnNode<Int> --
-
-template <>
-class ColumnNode<Int> : public TypedNode<Int> {
- public:
- ~ColumnNode() {}
-
- static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
- ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_COLUMN_NODE;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Int *results);
-
- private:
- grn_ctx *ctx_;
- grn_obj *column_;
-
- ColumnNode(grn_ctx *ctx, grn_obj *column)
- : TypedNode<Int>(), ctx_(ctx), column_(column) {}
-};
-
-grn_rc ColumnNode<Int>::evaluate(
- const Record *records, size_t num_records, Int *results) {
- grn_id range = grn_obj_get_range(ctx_, column_);
- grn_obj value;
- switch (range) {
- case GRN_DB_INT8: {
- GRN_INT8_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- results[i] = Int(GRN_INT8_VALUE(&value));
- }
- break;
- }
- case GRN_DB_INT16: {
- GRN_INT16_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- results[i] = Int(GRN_INT16_VALUE(&value));
- }
- break;
- }
- case GRN_DB_INT32: {
- GRN_INT32_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- results[i] = Int(GRN_INT32_VALUE(&value));
- }
- break;
- }
- case GRN_DB_INT64: {
- GRN_INT64_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- results[i] = Int(GRN_INT64_VALUE(&value));
- }
- break;
- }
- case GRN_DB_UINT8: {
- GRN_UINT8_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- results[i] = Int(GRN_UINT8_VALUE(&value));
- }
- break;
- }
- case GRN_DB_UINT16: {
- GRN_UINT16_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- results[i] = Int(GRN_UINT16_VALUE(&value));
- }
- break;
- }
- case GRN_DB_UINT32: {
- GRN_UINT32_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- results[i] = Int(GRN_UINT32_VALUE(&value));
- }
- break;
- }
- case GRN_DB_UINT64: {
- GRN_UINT64_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- // FIXME: Type conversion from UInt64 to Int may lose the content.
- results[i] = Int(GRN_UINT64_VALUE(&value));
- }
- break;
- }
- }
- GRN_OBJ_FIN(ctx_, &value);
- return GRN_SUCCESS;
-}
-
-// -- ColumnNode<Float> --
-
-template <>
-class ColumnNode<Float> : public TypedNode<Float> {
- public:
- ~ColumnNode() {}
-
- static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
- ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_COLUMN_NODE;
- }
-
- grn_rc adjust(Record *records, size_t num_records);
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Float *results);
-
- private:
- grn_ctx *ctx_;
- grn_obj *column_;
-
- ColumnNode(grn_ctx *ctx, grn_obj *column)
- : TypedNode<Float>(), ctx_(ctx), column_(column) {}
-};
-
-grn_rc ColumnNode<Float>::adjust(Record *records, size_t num_records) {
- grn_obj value;
- GRN_FLOAT_INIT(&value, 0);
- for (size_t i = 0; i < num_records; ++i) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- records[i].score = GRN_FLOAT_VALUE(&value);
- }
- GRN_OBJ_FIN(ctx_, &value);
- return GRN_SUCCESS;
-}
-
-grn_rc ColumnNode<Float>::evaluate(
- const Record *records, size_t num_records, Float *results) {
- grn_obj value;
- GRN_FLOAT_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- results[i] = Float(GRN_FLOAT_VALUE(&value));
- }
- GRN_OBJ_FIN(ctx_, &value);
- return GRN_SUCCESS;
-}
-
-// -- ColumnNode<Time> --
-
-template <>
-class ColumnNode<Time> : public TypedNode<Time> {
- public:
- ~ColumnNode() {}
-
- static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
- ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_COLUMN_NODE;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Time *results);
-
- private:
- grn_ctx *ctx_;
- grn_obj *column_;
-
- ColumnNode(grn_ctx *ctx, grn_obj *column)
- : TypedNode<Time>(), ctx_(ctx), column_(column) {}
-};
-
-grn_rc ColumnNode<Time>::evaluate(
- const Record *records, size_t num_records, Time *results) {
- grn_obj value;
- GRN_TIME_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- results[i] = Time(GRN_TIME_VALUE(&value));
- }
- GRN_OBJ_FIN(ctx_, &value);
- return GRN_SUCCESS;
-}
-
-// -- ColumnNode<Text> --
-
-template <>
-class ColumnNode<Text> : public TypedNode<Text> {
- public:
- ~ColumnNode() {
- GRN_OBJ_FIN(ctx_, &buf_);
- }
-
- static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
- ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_COLUMN_NODE;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Text *results);
-
- private:
- grn_ctx *ctx_;
- grn_obj *column_;
- grn_obj buf_;
-
- ColumnNode(grn_ctx *ctx, grn_obj *column)
- : TypedNode<Text>(), ctx_(ctx), column_(column), buf_() {
- GRN_TEXT_INIT(&buf_, 0);
- }
-};
-
-grn_rc ColumnNode<Text>::evaluate(
- const Record *records, size_t num_records, Text *results) {
- GRN_BULK_REWIND(&buf_);
- size_t offset = 0;
- for (size_t i = 0; i < num_records; i++) {
- grn_obj_get_value(ctx_, column_, records[i].id, &buf_);
- if (ctx_->rc != GRN_SUCCESS) {
- return ctx_->rc;
- }
- size_t next_offset = GRN_TEXT_LEN(&buf_);
- results[i].raw.size = next_offset - offset;
- offset = next_offset;
- }
- char *ptr = GRN_TEXT_VALUE(&buf_);
- for (size_t i = 0; i < num_records; i++) {
- results[i].raw.ptr = ptr;
- ptr += results[i].raw.size;
- }
- return GRN_SUCCESS;
-}
-
-// -- ColumnNode<GeoPoint> --
-
-template <>
-class ColumnNode<GeoPoint> : public TypedNode<GeoPoint> {
- public:
- ~ColumnNode() {}
-
- static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
- ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- ExpressionNodeType type() const {
- return GRN_EGN_COLUMN_NODE;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, GeoPoint *results);
-
- private:
- grn_ctx *ctx_;
- grn_obj *column_;
-
- ColumnNode(grn_ctx *ctx, grn_obj *column)
- : TypedNode<GeoPoint>(), ctx_(ctx), column_(column) {}
-};
-
-grn_rc ColumnNode<GeoPoint>::evaluate(
- const Record *records, size_t num_records, GeoPoint *results) {
- grn_obj value;
- GRN_WGS84_GEO_POINT_INIT(&value, 0);
- for (size_t i = 0; i < num_records; i++) {
- GRN_BULK_REWIND(&value);
- grn_obj_get_value(ctx_, column_, records[i].id, &value);
- GRN_GEO_POINT_VALUE(
- &value, results[i].raw.latitude, results[i].raw.longitude);
- }
- GRN_OBJ_FIN(ctx_, &value);
- return GRN_SUCCESS;
-}
-
-// -- OperatorNode --
-
-template <typename T>
-class OperatorNode : public TypedNode<T> {
- public:
- OperatorNode() : TypedNode<T>() {}
- virtual ~OperatorNode() {}
-
- ExpressionNodeType type() const {
- return GRN_EGN_OPERATOR_NODE;
- }
-};
-
-template <typename T>
-grn_rc operator_node_fill_arg_values(
- const Record *records, size_t num_records,
- TypedNode<T> *arg, std::vector<T> *arg_values) {
- size_t old_size = arg_values->size();
- if (old_size < num_records) try {
- arg_values->resize(num_records);
- } catch (const std::bad_alloc &) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- switch (arg->type()) {
- case GRN_EGN_CONSTANT_NODE: {
- if (old_size < num_records) {
- return arg->evaluate(records + old_size, num_records - old_size,
- &*arg_values->begin() + old_size);
- }
- return GRN_SUCCESS;
- }
- default: {
- return arg->evaluate(records, num_records, &*arg_values->begin());
- }
- }
-}
-
-// --- UnaryNode ---
-
-template <typename T, typename U>
-class UnaryNode : public OperatorNode<T> {
- public:
- explicit UnaryNode(ExpressionNode *arg)
- : OperatorNode<T>(), arg_(static_cast<TypedNode<U> *>(arg)),
- arg_values_() {}
- virtual ~UnaryNode() {
- delete arg_;
- }
-
- protected:
- TypedNode<U> *arg_;
- std::vector<U> arg_values_;
-
- grn_rc fill_arg_values(const Record *records, size_t num_records) {
- return operator_node_fill_arg_values(
- records, num_records, arg_, &arg_values_);
- }
-};
-
-// ---- LogicalNotNode ----
-
-class LogicalNotNode : public UnaryNode<Bool, Bool> {
- public:
- ~LogicalNotNode() {}
-
- static grn_rc open(ExpressionNode *arg, ExpressionNode **node) {
- LogicalNotNode *new_node = new (std::nothrow) LogicalNotNode(arg);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- grn_rc filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size);
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Bool *results);
-
- private:
- std::vector<Record> temp_records_;
-
- explicit LogicalNotNode(ExpressionNode *arg)
- : UnaryNode<Bool, Bool>(arg), temp_records_() {}
-};
-
-grn_rc LogicalNotNode::filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size) {
- if (temp_records_.size() <= input_size) {
- try {
- temp_records_.resize(input_size + 1);
- temp_records_[input_size].id = GRN_ID_NIL;
- } catch (const std::bad_alloc &) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- }
- size_t temp_size;
- grn_rc rc =
- arg_->filter(input, input_size, &*temp_records_.begin(), &temp_size);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- if (temp_size == 0) {
- *output_size = 0;
- return GRN_SUCCESS;
- }
-
- size_t count = 0;
- for (size_t i = 0; i < input_size; ++i) {
- if (input[i].id != temp_records_[i - count].id) {
- output[count] = input[i];
- ++count;
- }
- }
- *output_size = count;
- return GRN_SUCCESS;
-}
-
-grn_rc LogicalNotNode::evaluate(
- const Record *records, size_t num_records, Bool *results) {
- grn_rc rc = arg_->evaluate(records, num_records, results);
- if (rc == GRN_SUCCESS) {
- for (size_t i = 0; i < num_records; ++i) {
- results[i] = Bool(results[i].raw != GRN_TRUE);
- }
- }
- return rc;
-}
-
-// --- BinaryNode ---
-
-template <typename T, typename U, typename V>
-class BinaryNode : public OperatorNode<T> {
- public:
- BinaryNode(ExpressionNode *arg1, ExpressionNode *arg2)
- : OperatorNode<T>(),
- arg1_(static_cast<TypedNode<U> *>(arg1)),
- arg2_(static_cast<TypedNode<V> *>(arg2)),
- arg1_values_(), arg2_values_() {}
- virtual ~BinaryNode() {
- delete arg1_;
- delete arg2_;
- }
-
- protected:
- TypedNode<U> *arg1_;
- TypedNode<V> *arg2_;
- std::vector<U> arg1_values_;
- std::vector<V> arg2_values_;
-
- grn_rc fill_arg1_values(const Record *records, size_t num_records) {
- return operator_node_fill_arg_values(
- records, num_records, arg1_, &arg1_values_);
- }
- grn_rc fill_arg2_values(const Record *records, size_t num_records) {
- return operator_node_fill_arg_values(
- records, num_records, arg2_, &arg2_values_);
- }
-};
-
-// ---- LogicalAndNode ----
-
-class LogicalAndNode : public BinaryNode<Bool, Bool, Bool> {
- public:
- ~LogicalAndNode() {}
-
- static grn_rc open(
- ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
- LogicalAndNode *new_node = new (std::nothrow) LogicalAndNode(arg1, arg2);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- grn_rc filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size) {
- grn_rc rc = arg1_->filter(input, input_size, output, output_size);
- if (rc == GRN_SUCCESS) {
- rc = arg2_->filter(output, *output_size, output, output_size);
- }
- return rc;
- }
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Bool *results);
-
- private:
- std::vector<Record> temp_records_;
-
- LogicalAndNode(ExpressionNode *arg1, ExpressionNode *arg2)
- : BinaryNode<Bool, Bool, Bool>(arg1, arg2), temp_records_() {}
-};
-
-grn_rc LogicalAndNode::evaluate(
- const Record *records, size_t num_records, Bool *results) {
- // Evaluate "arg1" for all the records.
- // Then, evaluate "arg2" for non-false records.
- grn_rc rc = arg1_->evaluate(records, num_records, results);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- if (temp_records_.size() < num_records) try {
- temp_records_.resize(num_records);
- } catch (const std::bad_alloc &) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- size_t count = 0;
- for (size_t i = 0; i < num_records; ++i) {
- if (results[i].raw == GRN_TRUE) {
- temp_records_[count] = records[i];
- ++count;
- }
- }
- if (count == 0) {
- // Nothing to do.
- return GRN_SUCCESS;
- }
- rc = fill_arg2_values(&*temp_records_.begin(), count);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
-
- // Merge the evaluation results.
- count = 0;
- for (size_t i = 0; i < num_records; ++i) {
- if (results[i].raw == GRN_TRUE) {
- results[i] = arg2_values_[count];
- ++count;
- }
- }
- return GRN_SUCCESS;
-}
-
-// ---- LogicalOrNode ----
-
-class LogicalOrNode : public BinaryNode<Bool, Bool, Bool> {
- public:
- ~LogicalOrNode() {}
-
- static grn_rc open(
- ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
- LogicalOrNode *new_node = new (std::nothrow) LogicalOrNode(arg1, arg2);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
- }
-
- grn_rc filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size);
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Bool *results);
-
- private:
- std::vector<Record> temp_records_;
-
- LogicalOrNode(ExpressionNode *arg1, ExpressionNode *arg2)
- : BinaryNode<Bool, Bool, Bool>(arg1, arg2), temp_records_() {}
-};
-
-grn_rc LogicalOrNode::filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size) {
- // Evaluate "arg1" for all the records.
- // Then, evaluate "arg2" for non-true records.
- grn_rc rc = fill_arg1_values(input, input_size);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- if (temp_records_.size() < input_size) try {
- temp_records_.resize(input_size);
- } catch (const std::bad_alloc &) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- size_t count = 0;
- for (size_t i = 0; i < input_size; ++i) {
- if (arg1_values_[i].raw == GRN_FALSE) {
- temp_records_[count] = input[i];
- ++count;
- }
- }
- if (count == 0) {
- if (input != output) {
- for (size_t i = 0; i < input_size; ++i) {
- output[i] = input[i];
- }
- }
- *output_size = input_size;
- return GRN_SUCCESS;
- }
- rc = fill_arg2_values(&*temp_records_.begin(), count);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
-
- // Merge the evaluation results.
- count = 0;
- size_t output_count = 0;
- for (size_t i = 0; i < input_size; ++i) {
- if (arg1_values_[i].raw == GRN_TRUE) {
- output[output_count] = input[i];
- ++output_count;
- } else {
- if (arg2_values_[count].raw == GRN_TRUE) {
- output[output_count] = input[i];
- ++output_count;
- }
- ++count;
- }
- }
- *output_size = output_count;
- return GRN_SUCCESS;
-}
-
-grn_rc LogicalOrNode::evaluate(
- const Record *records, size_t num_records, Bool *results) {
- // Evaluate "arg1" for all the records.
- // Then, evaluate "arg2" for non-true records.
- grn_rc rc = arg1_->evaluate(records, num_records, results);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- if (temp_records_.size() < num_records) try {
- temp_records_.resize(num_records);
- } catch (const std::bad_alloc &) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- size_t count = 0;
- for (size_t i = 0; i < num_records; ++i) {
- if (results[i].raw == GRN_FALSE) {
- temp_records_[count] = records[i];
- ++count;
- }
- }
- if (count == 0) {
- // Nothing to do.
- return GRN_SUCCESS;
- }
- rc = fill_arg2_values(&*temp_records_.begin(), count);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
-
- // Merge the evaluation results.
- count = 0;
- for (size_t i = 0; i < num_records; ++i) {
- if (results[i].raw == GRN_FALSE) {
- results[i] = arg2_values_[count];
- ++count;
- }
- }
- return GRN_SUCCESS;
-}
-
-// -- GenericBinaryNode --
-
-template <typename T,
- typename U = typename T::Value,
- typename V = typename T::Arg1,
- typename W = typename T::Arg2>
-class GenericBinaryNode : public BinaryNode<U, V, W> {
- public:
- GenericBinaryNode(ExpressionNode *arg1, ExpressionNode *arg2)
- : BinaryNode<U, V, W>(arg1, arg2), operator_() {}
- ~GenericBinaryNode() {}
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Bool *results);
-
- private:
- T operator_;
-};
-
-template <typename T, typename U, typename V, typename W>
-grn_rc GenericBinaryNode<T, U, V, W>::evaluate(
- const Record *records, size_t num_records, Bool *results) {
- grn_rc rc = this->fill_arg1_values(records, num_records);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- rc = this->fill_arg2_values(records, num_records);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- for (size_t i = 0; i < num_records; ++i) {
- results[i] = operator_(this->arg1_values_[i], this->arg2_values_[i]);
- }
- return GRN_SUCCESS;
-}
-
-template <typename T, typename V, typename W>
-class GenericBinaryNode<T, Bool, V, W> : public BinaryNode<Bool, V, W> {
- public:
- GenericBinaryNode(ExpressionNode *arg1, ExpressionNode *arg2)
- : BinaryNode<Bool, V, W>(arg1, arg2), operator_() {}
- ~GenericBinaryNode() {}
-
- grn_rc filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size);
-
- grn_rc evaluate(
- const Record *records, size_t num_records, Bool *results);
-
- private:
- T operator_;
-};
-
-template <typename T, typename V, typename W>
-grn_rc GenericBinaryNode<T, Bool, V, W>::filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size) {
- grn_rc rc = this->fill_arg1_values(input, input_size);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- rc = this->fill_arg2_values(input, input_size);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- size_t count = 0;
- for (size_t i = 0; i < input_size; ++i) {
- if (operator_(this->arg1_values_[i], this->arg2_values_[i]).raw ==
- GRN_TRUE) {
- output[count] = input[i];
- ++count;
- }
- }
- *output_size = count;
- return GRN_SUCCESS;
-}
-
-template <typename T, typename V, typename W>
-grn_rc GenericBinaryNode<T, Bool, V, W>::evaluate(
- const Record *records, size_t num_records, Bool *results) {
- grn_rc rc = this->fill_arg1_values(records, num_records);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- rc = this->fill_arg2_values(records, num_records);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- for (size_t i = 0; i < num_records; ++i) {
- results[i] = operator_(this->arg1_values_[i], this->arg2_values_[i]);
- }
- return GRN_SUCCESS;
-}
-
-// ----- EqualNode -----
-
-template <typename T>
-struct EqualOperator {
- typedef Bool Value;
- typedef T Arg1;
- typedef T Arg2;
- Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
- return Bool(arg1 == arg2);
- }
-};
-
-template <typename T>
-grn_rc equal_node_open(EqualOperator<T> op,
- ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
- GenericBinaryNode<EqualOperator<T> > *new_node =
- new (std::nothrow) GenericBinaryNode<EqualOperator<T> >(arg1, arg2);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
-}
-
-// ----- NotEqualNode -----
-
-template <typename T>
-struct NotEqualOperator {
- typedef Bool Value;
- typedef T Arg1;
- typedef T Arg2;
- Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
- return Bool(arg1 != arg2);
- }
-};
-
-template <typename T>
-grn_rc not_equal_node_open(NotEqualOperator<T> op,
- ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
- GenericBinaryNode<NotEqualOperator<T> > *new_node =
- new (std::nothrow) GenericBinaryNode<NotEqualOperator<T> >(arg1, arg2);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
-}
-
-// ----- LessNode -----
-
-template <typename T>
-struct LessOperator {
- typedef Bool Value;
- typedef T Arg1;
- typedef T Arg2;
- Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
- return Bool(arg1 < arg2);
- }
-};
-
-template <typename T>
-grn_rc less_node_open(LessOperator<T> op,
- ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
- GenericBinaryNode<LessOperator<T> > *new_node =
- new (std::nothrow) GenericBinaryNode<LessOperator<T> >(arg1, arg2);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
-}
-
-// ----- LessEqualNode -----
-
-template <typename T>
-struct LessEqualOperator {
- typedef Bool Value;
- typedef T Arg1;
- typedef T Arg2;
- Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
- return Bool(arg1 < arg2);
- }
-};
-
-template <typename T>
-grn_rc less_equal_node_open(LessEqualOperator<T> op,
- ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
- GenericBinaryNode<LessEqualOperator<T> > *new_node =
- new (std::nothrow) GenericBinaryNode<LessEqualOperator<T> >(arg1, arg2);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
-}
-
-// ----- GreaterNode -----
-
-template <typename T>
-struct GreaterOperator {
- typedef Bool Value;
- typedef T Arg1;
- typedef T Arg2;
- Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
- return Bool(arg1 < arg2);
- }
-};
-
-template <typename T>
-grn_rc greater_node_open(GreaterOperator<T> op,
- ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
- GenericBinaryNode<GreaterOperator<T> > *new_node =
- new (std::nothrow) GenericBinaryNode<GreaterOperator<T> >(arg1, arg2);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
-}
-
-// ----- GreaterEqualNode -----
-
-template <typename T>
-struct GreaterEqualOperator {
- typedef Bool Value;
- typedef T Arg1;
- typedef T Arg2;
- Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
- return Bool(arg1 < arg2);
- }
-};
-
-template <typename T>
-grn_rc greater_equal_node_open(GreaterEqualOperator<T> op,
- ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
- GenericBinaryNode<GreaterEqualOperator<T> > *new_node =
- new (std::nothrow) GenericBinaryNode<GreaterEqualOperator<T> >(arg1, arg2);
- if (!new_node) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *node = new_node;
- return GRN_SUCCESS;
-}
-
-// -- ExpressionToken --
-
-enum ExpressionTokenType {
- DUMMY_TOKEN,
- CONSTANT_TOKEN,
- NAME_TOKEN,
- UNARY_OPERATOR_TOKEN,
- BINARY_OPERATOR_TOKEN,
- DEREFERENCE_TOKEN,
- BRACKET_TOKEN
-};
-
-enum ExpressionBracketType {
- LEFT_ROUND_BRACKET,
- RIGHT_ROUND_BRACKET,
- LEFT_SQUARE_BRACKET,
- RIGHT_SQUARE_BRACKET
-};
-
-// TODO: std::string should not be used.
-class ExpressionToken {
- public:
- ExpressionToken() : string_(), type_(DUMMY_TOKEN), dummy_(0), priority_(0) {}
- ExpressionToken(const std::string &string, ExpressionTokenType token_type)
- : string_(string), type_(token_type), dummy_(0), priority_(0) {}
- ExpressionToken(const std::string &string,
- ExpressionBracketType bracket_type)
- : string_(string), type_(BRACKET_TOKEN), bracket_type_(bracket_type),
- priority_(0) {}
- ExpressionToken(const std::string &string, OperatorType operator_type)
- : string_(string), type_(get_operator_token_type(operator_type)),
- operator_type_(operator_type),
- priority_(get_operator_priority(operator_type)) {}
-
- const std::string &string() const {
- return string_;
- }
- ExpressionTokenType type() const {
- return type_;
- }
- ExpressionBracketType bracket_type() const {
- return bracket_type_;
- }
- OperatorType operator_type() const {
- return operator_type_;
- }
- int priority() const {
- return priority_;
- }
-
- private:
- std::string string_;
- ExpressionTokenType type_;
- union {
- int dummy_;
- ExpressionBracketType bracket_type_;
- OperatorType operator_type_;
- };
- int priority_;
-
- static ExpressionTokenType get_operator_token_type(
- OperatorType operator_type);
- static int get_operator_priority(OperatorType operator_type);
-};
-
-ExpressionTokenType ExpressionToken::get_operator_token_type(
- OperatorType operator_type) {
- switch (operator_type) {
- case GRN_OP_NOT: {
- return UNARY_OPERATOR_TOKEN;
- }
- case GRN_OP_AND:
- case GRN_OP_OR:
- case GRN_OP_EQUAL:
- case GRN_OP_NOT_EQUAL:
- case GRN_OP_LESS:
- case GRN_OP_LESS_EQUAL:
- case GRN_OP_GREATER:
- case GRN_OP_GREATER_EQUAL: {
- return BINARY_OPERATOR_TOKEN;
- }
- default: {
- // TODO: ERROR_TOKEN or something should be used...?
- // Or, default should be removed?
- return DUMMY_TOKEN;
- }
- }
-}
-
-int ExpressionToken::get_operator_priority(
- OperatorType operator_type) {
- switch (operator_type) {
- case GRN_OP_NOT: {
-// case GRN_OP_BITWISE_NOT:
-// case GRN_OP_POSITIVE:
-// case GRN_OP_NEGATIVE:
-// case GRN_OP_TO_INT:
-// case GRN_OP_TO_FLOAT: {
- return 3;
- }
- case GRN_OP_AND: {
- return 13;
- }
- case GRN_OP_OR: {
- return 14;
- }
- case GRN_OP_EQUAL:
- case GRN_OP_NOT_EQUAL: {
- return 9;
- }
- case GRN_OP_LESS:
- case GRN_OP_LESS_EQUAL:
- case GRN_OP_GREATER:
- case GRN_OP_GREATER_EQUAL: {
- return 8;
- }
-// case GRN_OP_BITWISE_AND: {
-// return 10;
-// }
-// case GRN_OP_BITWISE_OR: {
-// return 12;
-// }
-// case GRN_OP_BITWISE_XOR: {
-// return 11;
-// }
-// case GRN_OP_PLUS:
-// case GRN_OP_MINUS: {
-// return 6;
-// }
-// case GRN_OP_MULTIPLICATION:
-// case GRN_OP_DIVISION:
-// case GRN_OP_MODULUS: {
-// return 5;
-// }
-// case GRN_OP_STARTS_WITH:
-// case GRN_OP_ENDS_WITH:
-// case GRN_OP_CONTAINS: {
-// return 7;
-// }
-// case GRN_OP_SUBSCRIPT: {
-// return 2;
-// }
- default: {
- return 100;
- }
- }
-}
-
-// -- ExpressionParser --
-
-class ExpressionParser {
- public:
- static grn_rc parse(grn_ctx *ctx, grn_obj *table,
- const char *query, size_t query_size, Expression **expression);
-
- private:
- grn_ctx *ctx_;
- grn_obj *table_;
- std::vector<ExpressionToken> tokens_;
- std::vector<ExpressionToken> stack_;
- Expression *expression_;
-
- ExpressionParser(grn_ctx *ctx, grn_obj *table)
- : ctx_(ctx), table_(table), tokens_(), stack_(), expression_(NULL) {}
- ~ExpressionParser() {
- delete expression_;
- }
-
- grn_rc tokenize(const char *query, size_t query_size);
- grn_rc compose();
- grn_rc push_token(const ExpressionToken &token);
-};
-
-grn_rc ExpressionParser::parse(grn_ctx *ctx, grn_obj *table,
- const char *query, size_t query_size, Expression **expression) {
- ExpressionParser *parser = new (std::nothrow) ExpressionParser(ctx, table);
- if (!parser) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- grn_rc rc = parser->tokenize(query, query_size);
- if (rc == GRN_SUCCESS) {
- rc = parser->compose();
- if (rc == GRN_SUCCESS) {
- *expression = parser->expression_;
- parser->expression_ = NULL;
- }
- }
- delete parser;
- return rc;
-}
-
-grn_rc ExpressionParser::tokenize(const char *query, size_t query_size) {
- const char *rest = query;
- size_t rest_size = query_size;
- while (rest_size != 0) {
- // Ignore white-space characters.
- size_t pos;
- for (pos = 0; pos < rest_size; ++pos) {
- if (!std::isspace(static_cast<uint8_t>(rest[pos]))) {
- break;
- }
- }
- rest += pos;
- rest_size -= pos;
- switch (rest[0]) {
- case '!': {
- if ((rest_size >= 2) && (rest[1] == '=')) {
- tokens_.push_back(ExpressionToken("!=", GRN_OP_NOT_EQUAL));
- rest += 2;
- rest_size -= 2;
- } else {
- tokens_.push_back(ExpressionToken("!", GRN_OP_NOT));
- ++rest;
- --rest_size;
- }
- break;
- }
-// case '~': {
-// tokens_.push_back(ExpressionToken("~", GRN_OP_BITWISE_NOT));
-// rest = rest.substring(1);
-// break;
-// }
- case '=': {
- if ((rest_size >= 2) && (rest[1] == '=')) {
- tokens_.push_back(ExpressionToken("==", GRN_OP_EQUAL));
- rest += 2;
- rest_size -= 2;
- } else {
- return GRN_INVALID_ARGUMENT;
- }
- break;
- }
- case '<': {
- if ((rest_size >= 2) && (rest[1] == '=')) {
- tokens_.push_back(ExpressionToken("<=", GRN_OP_LESS_EQUAL));
- rest += 2;
- rest_size -= 2;
- } else {
- tokens_.push_back(ExpressionToken("<", GRN_OP_LESS));
- ++rest;
- --rest_size;
- }
- break;
- }
- case '>': {
- if ((rest_size >= 2) && (rest[1] == '=')) {
- tokens_.push_back(ExpressionToken(">=", GRN_OP_GREATER_EQUAL));
- rest += 2;
- rest_size -= 2;
- } else {
- tokens_.push_back(ExpressionToken(">", GRN_OP_GREATER));
- ++rest;
- --rest_size;
- }
- break;
- }
- case '&': {
- if ((rest_size >= 2) && (rest[1] == '&')) {
- tokens_.push_back(ExpressionToken("&&", GRN_OP_AND));
- rest += 2;
- rest_size -= 2;
- } else {
-// tokens_.push_back(ExpressionToken("&", GRN_OP_BITWISE_AND));
-// ++rest;
-// --rest_size;
- return GRN_INVALID_ARGUMENT;
- }
- break;
- }
- case '|': {
- if ((rest_size >= 2) && (rest[1] == '|')) {
- tokens_.push_back(ExpressionToken("||", GRN_OP_OR));
- rest += 2;
- rest_size -= 2;
- } else {
-// tokens_.push_back(ExpressionToken("|", GRN_OP_BITWISE_OR));
-// ++rest;
-// --rest_size;
- return GRN_INVALID_ARGUMENT;
- }
- break;
- }
-// case '^': {
-// tokens_.push_back(ExpressionToken("^", GRN_OP_BITWISE_XOR));
-// rest = rest.substring(1);
-// break;
-// }
-// case '+': {
-// tokens_.push_back(ExpressionToken("+", GRN_OP_PLUS));
-// rest = rest.substring(1);
-// break;
-// }
-// case '-': {
-// tokens_.push_back(ExpressionToken("-", GRN_OP_MINUS));
-// rest = rest.substring(1);
-// break;
-// }
-// case '*': {
-// tokens_.push_back(ExpressionToken("*", GRN_OP_MULTIPLICATION));
-// rest = rest.substring(1);
-// break;
-// }
-// case '/': {
-// tokens_.push_back(ExpressionToken("/", GRN_OP_DIVISION));
-// rest = rest.substring(1);
-// break;
-// }
-// case '%': {
-// tokens_.push_back(ExpressionToken("%", GRN_OP_MODULUS));
-// rest = rest.substring(1);
-// break;
-// }
-// case '@': {
-// if ((rest_size >= 2) && (rest[1] == '^')) {
-// tokens_.push_back(ExpressionToken("@^", GRN_OP_STARTS_WITH));
-// rest = rest.substring(2);
-// } else if ((rest_size >= 2) && (rest[1] == '$')) {
-// tokens_.push_back(ExpressionToken("@$", GRN_OP_ENDS_WITH));
-// rest = rest.substring(2);
-// } else {
-// tokens_.push_back(ExpressionToken("@", GRN_OP_CONTAINS));
-// rest = rest.substring(1);
-// }
-// break;
-// }
-// case '.': {
-// tokens_.push_back(ExpressionToken(".", DEREFERENCE_TOKEN));
-// rest = rest.substring(1);
-// break;
-// }
- case '(': {
- tokens_.push_back(ExpressionToken("(", LEFT_ROUND_BRACKET));
- ++rest;
- --rest_size;
- break;
- }
- case ')': {
- tokens_.push_back(ExpressionToken(")", RIGHT_ROUND_BRACKET));
- ++rest;
- --rest_size;
- break;
- }
-// case '[': {
-// tokens_.push_back(ExpressionToken("[", LEFT_SQUARE_BRACKET));
-// rest = rest.substring(1);
-// break;
-// }
-// case ']': {
-// tokens_.push_back(ExpressionToken("]", RIGHT_SQUARE_BRACKET));
-// rest = rest.substring(1);
-// break;
-// }
- case '"': {
- for (pos = 1; pos < rest_size; ++pos) {
- if (rest[pos] == '\\') {
- if (pos == rest_size) {
- break;
- }
- ++pos;
- } else if (rest[pos] == '"') {
- break;
- }
- }
- if (pos == rest_size) {
- return GRN_INVALID_ARGUMENT;
- }
- tokens_.push_back(
- ExpressionToken(std::string(rest + 1, pos - 1), CONSTANT_TOKEN));
- rest += pos + 1;
- rest_size -= pos + 1;
- break;
- }
- case '0' ... '9': {
- // TODO: Improve this.
- for (pos = 1; pos < rest_size; ++pos) {
- if (!std::isdigit(static_cast<uint8_t>(rest[pos]))) {
- break;
- }
- }
- tokens_.push_back(
- ExpressionToken(std::string(rest, pos), CONSTANT_TOKEN));
- rest += pos;
- rest_size -= pos;
- break;
- }
- case '_':
- case 'A' ... 'Z':
- case 'a' ... 'z': {
- // TODO: Improve this.
- for (pos = 1; pos < rest_size; ++pos) {
- if ((rest[pos] != '_') && (!std::isalnum(rest[pos]))) {
- break;
- }
- }
- std::string token(rest, pos);
- if ((token == "true") || (token == "false")) {
- tokens_.push_back(ExpressionToken(token, CONSTANT_TOKEN));
- } else {
- tokens_.push_back(ExpressionToken(token, NAME_TOKEN));
- }
- rest += pos;
- rest_size -= pos;
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- }
- return GRN_SUCCESS;
-}
-
-grn_rc ExpressionParser::compose() {
- if (tokens_.size() == 0) {
- return GRN_INVALID_ARGUMENT;
- }
- expression_ = new (std::nothrow) Expression(ctx_, table_);
- grn_rc rc = push_token(ExpressionToken("(", LEFT_ROUND_BRACKET));
- if (rc == GRN_SUCCESS) {
- for (size_t i = 0; i < tokens_.size(); ++i) {
- rc = push_token(tokens_[i]);
- if (rc != GRN_SUCCESS) {
- break;
- }
- }
- if (rc == GRN_SUCCESS) {
- rc = push_token(ExpressionToken(")", RIGHT_ROUND_BRACKET));
- }
- }
- return rc;
-}
-
-grn_rc ExpressionParser::push_token(const ExpressionToken &token) {
- grn_rc rc = GRN_SUCCESS;
- switch (token.type()) {
- case DUMMY_TOKEN: {
- if ((stack_.size() != 0) && (stack_.back().type() == DUMMY_TOKEN)) {
- return GRN_INVALID_ARGUMENT;
- }
- stack_.push_back(token);
- break;
- }
- case CONSTANT_TOKEN: {
- grn_obj obj;
- const std::string string = token.string();
- if (std::isdigit(static_cast<uint8_t>(string[0]))) {
- if (string.find_first_of('.') == string.npos) {
- GRN_INT64_INIT(&obj, 0);
- GRN_INT64_SET(ctx_, &obj, strtoll(string.c_str(), NULL, 10));
- } else {
- GRN_FLOAT_INIT(&obj, 0);
- GRN_FLOAT_SET(ctx_, &obj, strtod(string.c_str(), NULL));
- }
- } else if (string == "true") {
- GRN_BOOL_INIT(&obj, 0);
- GRN_BOOL_SET(ctx_, &obj, GRN_TRUE);
- } else if (string == "false") {
- GRN_BOOL_INIT(&obj, 0);
- GRN_BOOL_SET(ctx_, &obj, GRN_FALSE);
- } else {
- GRN_TEXT_INIT(&obj, 0);
- GRN_TEXT_SET(ctx_, &obj, string.data(), string.size());
- }
- rc = push_token(ExpressionToken(string, DUMMY_TOKEN));
- if (rc == GRN_SUCCESS) {
- rc = expression_->push_object(&obj);
- }
- GRN_OBJ_FIN(ctx_, &obj);
- break;
- }
- case NAME_TOKEN: {
- rc = push_token(ExpressionToken(token.string(), DUMMY_TOKEN));
- if (rc == GRN_SUCCESS) {
- grn_obj *column = grn_obj_column(
- ctx_, table_, token.string().data(), token.string().size());
- rc = expression_->push_object(column);
- }
- break;
- }
- case UNARY_OPERATOR_TOKEN: {
- if ((stack_.size() != 0) && (stack_.back().type() == DUMMY_TOKEN)) {
- // A unary operator must not follow an operand.
- return GRN_INVALID_ARGUMENT;
- }
- stack_.push_back(token);
- break;
- }
- case BINARY_OPERATOR_TOKEN: {
- if ((stack_.size() == 0) || (stack_.back().type() != DUMMY_TOKEN)) {
- // A binary operator must follow an operand.
- return GRN_INVALID_ARGUMENT;
- }
- // Apply previous operators if those are prior to the new operator.
- while (stack_.size() >= 2) {
- ExpressionToken operator_token = stack_[stack_.size() - 2];
-// if (operator_token.type() == DEREFERENCE_TOKEN) {
-// expression_->end_subexpression();
-// stack_.pop_back();
-// stack_.pop_back();
-// push_token(ExpressionToken("", DUMMY_TOKEN));
-// } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) {
- if (operator_token.type() == UNARY_OPERATOR_TOKEN) {
- rc = expression_->push_operator(operator_token.operator_type());
- if (rc == GRN_SUCCESS) {
- stack_.pop_back();
- stack_.pop_back();
- rc = push_token(ExpressionToken("", DUMMY_TOKEN));
- }
- } else if ((operator_token.type() == BINARY_OPERATOR_TOKEN) &&
- (operator_token.priority() <= token.priority())) {
- rc = expression_->push_operator(operator_token.operator_type());
- if (rc == GRN_SUCCESS) {
- stack_.pop_back();
- stack_.pop_back();
- stack_.pop_back();
- rc = push_token(ExpressionToken("", DUMMY_TOKEN));
- }
- } else {
- break;
- }
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- }
- stack_.push_back(token);
- break;
- }
-// case DEREFERENCE_TOKEN: {
-// builder_->begin_subexpression();
-// stack_.pop_back();
-// stack_.push_back(token);
-// break;
-// }
- case BRACKET_TOKEN: {
- if (token.bracket_type() == LEFT_ROUND_BRACKET) {
- // A left round bracket must not follow a dummy.
- if ((stack_.size() != 0) && (stack_.back().type() == DUMMY_TOKEN)) {
- return GRN_INVALID_ARGUMENT;
- }
- stack_.push_back(token);
- } else if (token.bracket_type() == RIGHT_ROUND_BRACKET) {
- // A right round bracket must follow a dummy.
- // A left round bracket must exist before a right round bracket.
- if ((stack_.size() < 2) || (stack_.back().type() != DUMMY_TOKEN)) {
- return GRN_INVALID_ARGUMENT;
- }
- // Apply operators in brackets.
- while (stack_.size() >= 2) {
- ExpressionToken operator_token = stack_[stack_.size() - 2];
-// if (operator_token.type() == DEREFERENCE_TOKEN) {
-// rc = expression_->end_subexpression();
-// if (rc == GRN_SUCCESS) {
-// stack_.pop_back();
-// stack_.pop_back();
-// rc = push_token(ExpressionToken("", DUMMY_TOKEN));
-// }
-// } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) {
- if (operator_token.type() == UNARY_OPERATOR_TOKEN) {
- rc = expression_->push_operator(operator_token.operator_type());
- if (rc == GRN_SUCCESS) {
- stack_.pop_back();
- stack_.pop_back();
- rc = push_token(ExpressionToken("", DUMMY_TOKEN));
- }
- } else if (operator_token.type() == BINARY_OPERATOR_TOKEN) {
- rc = expression_->push_operator(operator_token.operator_type());
- if (rc == GRN_SUCCESS) {
- stack_.pop_back();
- stack_.pop_back();
- stack_.pop_back();
- rc = push_token(ExpressionToken("", DUMMY_TOKEN));
- }
- } else {
- break;
- }
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- }
- if ((stack_.size() < 2) ||
- (stack_[stack_.size() - 2].type() != BRACKET_TOKEN) ||
- (stack_[stack_.size() - 2].bracket_type() != LEFT_ROUND_BRACKET)) {
- return GRN_INVALID_ARGUMENT;
- }
- stack_[stack_.size() - 2] = stack_.back();
- stack_.pop_back();
-// } else if (token.bracket_type() == LEFT_SQUARE_BRACKET) {
-// // A left square bracket must follow a dummy.
-// if ((stack_.size() == 0) || (stack_.back().type() != DUMMY_TOKEN)) {
-// return GRN_INVALID_ARGUMENT;
-// }
-// stack_.push_back(token);
-// } else if (token.bracket_type() == RIGHT_SQUARE_BRACKET) {
-// // A right round bracket must follow a dummy.
-// // A left round bracket must exist before a right round bracket.
-// if ((stack_.size() < 2) || (stack_.back().type() != DUMMY_TOKEN)) {
-// return GRN_INVALID_ARGUMENT;
-// }
-// // Apply operators in bracket.
-// while (stack_.size() >= 2) {
-// ExpressionToken operator_token = stack_[stack_.size() - 2];
-// if (operator_token.type() == DEREFERENCE_TOKEN) {
-// builder_->end_subexpression();
-// stack_.pop_back();
-// stack_.pop_back();
-// push_token(ExpressionToken("", DUMMY_TOKEN));
-// } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) {
-// builder_->push_operator(operator_token.operator_type());
-// stack_.pop_back();
-// stack_.pop_back();
-// push_token(ExpressionToken("", DUMMY_TOKEN));
-// } else if (operator_token.type() == BINARY_OPERATOR_TOKEN) {
-// builder_->push_operator(operator_token.operator_type());
-// stack_.pop_back();
-// stack_.pop_back();
-// stack_.pop_back();
-// push_token(ExpressionToken("", DUMMY_TOKEN));
-// } else {
-// break;
-// }
-// }
-// if ((stack_.size() < 2) ||
-// (stack_[stack_.size() - 2].type() != BRACKET_TOKEN) ||
-// (stack_[stack_.size() - 2].bracket_type() != LEFT_SQUARE_BRACKET)) {
-// return GRN_INVALID_ARGUMENT;
-// }
-// stack_.pop_back();
-// stack_.pop_back();
-// builder_->push_operator(GRNXX_SUBSCRIPT);
- } else {
- return GRN_INVALID_ARGUMENT;
- }
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- return rc;
-}
-
-// -- Expression --
-
-Expression::Expression(grn_ctx *ctx, grn_obj *table)
- : ctx_(ctx), table_(table), type_(GRN_EGN_INCOMPLETE),
- data_type_(GRN_DB_VOID), stack_() {}
-
-Expression::~Expression() {
- for (size_t i = 0; i < stack_.size(); ++i) {
- delete stack_[i];
- }
-}
-
-grn_rc Expression::open(
- grn_ctx *ctx, grn_obj *table, Expression **expression) {
- if (!ctx || !grn_egn_is_table(table) || !expression) {
- return GRN_INVALID_ARGUMENT;
- }
- Expression *new_expression = new (std::nothrow) Expression(ctx, table);
- if (!new_expression) {
- return GRN_NO_MEMORY_AVAILABLE;
- }
- *expression = new_expression;
- return GRN_SUCCESS;
-}
-
-grn_rc Expression::parse(grn_ctx *ctx, grn_obj *table,
- const char *query, size_t query_size, Expression **expression) {
- if (!ctx || !grn_egn_is_table(table) ||
- !query || (query_size == 0) || !expression) {
- return GRN_INVALID_ARGUMENT;
- }
- return ExpressionParser::parse(ctx, table, query, query_size, expression);
-}
-
-grn_rc Expression::push_object(grn_obj *obj) {
- if (!obj) {
- return GRN_INVALID_ARGUMENT;
- }
- grn_rc rc = GRN_UNKNOWN_ERROR;
- switch (obj->header.type) {
- case GRN_BULK: {
- rc = push_bulk_object(obj);
- break;
- }
- case GRN_UVECTOR: {
- // FIXME: To be supported.
- return GRN_INVALID_ARGUMENT;
- }
- case GRN_VECTOR: {
- // FIXME: To be supported.
- return GRN_INVALID_ARGUMENT;
- }
- case GRN_ACCESSOR: {
- grn_accessor *accessor = (grn_accessor *)obj;
- switch (accessor->action) {
- case GRN_ACCESSOR_GET_ID: {
- ExpressionNode *node;
- rc = IDNode::open(&node);
- if (rc == GRN_SUCCESS) try {
- stack_.push_back(node);
- } catch (const std::bad_alloc &) {
- delete node;
- return GRN_NO_MEMORY_AVAILABLE;
- }
- break;
- }
- case GRN_ACCESSOR_GET_KEY: {
- // TODO: KeyNode should be provided for performance.
- ExpressionNode *node;
- grn_id range = grn_obj_get_range(ctx_, obj);
- switch (range) {
- case GRN_DB_BOOL: {
- rc = ColumnNode<Bool>::open(ctx_, obj, &node);
- break;
- }
- case GRN_DB_INT8:
- case GRN_DB_INT16:
- case GRN_DB_INT32:
- case GRN_DB_INT64:
- case GRN_DB_UINT8:
- case GRN_DB_UINT16:
- case GRN_DB_UINT32:
- case GRN_DB_UINT64: {
- rc = ColumnNode<Int>::open(ctx_, obj, &node);
- break;
- }
- case GRN_DB_FLOAT: {
- rc = ColumnNode<Float>::open(ctx_, obj, &node);
- break;
- }
- case GRN_DB_TIME: {
- rc = ColumnNode<Time>::open(ctx_, obj, &node);
- break;
- }
- case GRN_DB_TOKYO_GEO_POINT:
- case GRN_DB_WGS84_GEO_POINT: {
- rc = ColumnNode<GeoPoint>::open(ctx_, obj, &node);
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- if (rc == GRN_SUCCESS) try {
- stack_.push_back(node);
- } catch (const std::bad_alloc &) {
- delete node;
- return GRN_NO_MEMORY_AVAILABLE;
- }
- break;
- }
- case GRN_ACCESSOR_GET_VALUE: {
- // TODO
- return GRN_INVALID_ARGUMENT;
- }
- case GRN_ACCESSOR_GET_SCORE: {
- ExpressionNode *node;
- rc = ScoreNode::open(&node);
- if (rc == GRN_SUCCESS) try {
- stack_.push_back(node);
- } catch (const std::bad_alloc &) {
- delete node;
- return GRN_NO_MEMORY_AVAILABLE;
- }
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- break;
- }
- case GRN_COLUMN_FIX_SIZE:
- case GRN_COLUMN_VAR_SIZE: {
- rc = push_column_object(obj);
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- if (rc == GRN_SUCCESS) {
- update_types();
- }
- return rc;
-}
-
-grn_rc Expression::push_operator(OperatorType operator_type) {
- grn_rc rc = GRN_UNKNOWN_ERROR;
- ExpressionNode *node;
- switch (operator_type) {
- case GRN_OP_NOT: {
- if (stack_.size() < 1) {
- return GRN_INVALID_FORMAT;
- }
- ExpressionNode *arg = stack_[stack_.size() - 1];
- rc = create_unary_node(operator_type, arg, &node);
- if (rc == GRN_SUCCESS) {
- stack_.resize(stack_.size() - 1);
- }
- break;
- }
- case GRN_OP_AND:
- case GRN_OP_OR:
- case GRN_OP_EQUAL:
- case GRN_OP_NOT_EQUAL:
- case GRN_OP_LESS:
- case GRN_OP_LESS_EQUAL:
- case GRN_OP_GREATER:
- case GRN_OP_GREATER_EQUAL: {
- if (stack_.size() < 2) {
- return GRN_INVALID_FORMAT;
- }
- ExpressionNode *arg1 = stack_[stack_.size() - 2];
- ExpressionNode *arg2 = stack_[stack_.size() - 1];
- rc = create_binary_node(operator_type, arg1, arg2, &node);
- if (rc == GRN_SUCCESS) {
- stack_.resize(stack_.size() - 2);
- }
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- if (rc == GRN_SUCCESS) {
- stack_.push_back(node);
- update_types();
- }
- return rc;
-}
-
-grn_rc Expression::filter(
- Record *input, size_t input_size,
- Record *output, size_t *output_size) {
- if ((!input && (input_size != 0)) ||
- ((output > input) && (output < (input + input_size))) || !output_size) {
- return GRN_INVALID_ARGUMENT;
- }
- ExpressionNode *root = this->root();
- if (!root) {
- return GRN_UNKNOWN_ERROR;
- }
- if (!output) {
- output = input;
- }
- size_t total_output_size = 0;
- while (input_size > 0) {
- size_t batch_input_size = GRN_EGN_MAX_BATCH_SIZE;
- if (input_size < batch_input_size) {
- batch_input_size = input_size;
- }
- size_t batch_output_size;
- grn_rc rc = root->filter(
- input, batch_input_size, output, &batch_output_size);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- input += batch_input_size;
- input_size -= batch_input_size;
- output += batch_output_size;
- total_output_size += batch_output_size;
- }
- *output_size = total_output_size;
- return GRN_SUCCESS;
-}
-
-grn_rc Expression::adjust(Record *records, size_t num_records) {
- if (!records && (num_records != 0)) {
- return GRN_INVALID_ARGUMENT;
- }
- ExpressionNode *root = this->root();
- if (!root) {
- return GRN_UNKNOWN_ERROR;
- }
- while (num_records > 0) {
- size_t batch_size = GRN_EGN_MAX_BATCH_SIZE;
- if (num_records < batch_size) {
- batch_size = num_records;
- }
- grn_rc rc = root->adjust(records, batch_size);
- if (rc != GRN_SUCCESS) {
- return rc;
- }
- records += batch_size;
- num_records -= batch_size;
- }
- return GRN_SUCCESS;
-}
-
-template <typename T>
-grn_rc Expression::evaluate(
- const Record *records, size_t num_records, T *results) {
- if (((!records || !results) && (num_records != 0)) ||
- (T::data_type() != data_type())) {
- return GRN_INVALID_ARGUMENT;
- }
- ExpressionNode *root = this->root();
- if (!root) {
- return GRN_UNKNOWN_ERROR;
- }
- // FIXME: Records should be processed per block.
- // However, the contents of old blocks will be lost.
- return static_cast<TypedNode<T> *>(root)->evaluate(
- records, num_records, results);
-}
-
-template grn_rc Expression::evaluate(
- const Record *records, size_t num_records, Bool *results);
-template grn_rc Expression::evaluate(
- const Record *records, size_t num_records, Int *results);
-template grn_rc Expression::evaluate(
- const Record *records, size_t num_records, Float *results);
-template grn_rc Expression::evaluate(
- const Record *records, size_t num_records, Time *results);
-template grn_rc Expression::evaluate(
- const Record *records, size_t num_records, Text *results);
-template grn_rc Expression::evaluate(
- const Record *records, size_t num_records, GeoPoint *results);
-
-ExpressionNode *Expression::root() const {
- if (stack_.size() != 1) {
- return NULL;
- }
- return stack_.front();
-}
-
-void Expression::update_types() {
- ExpressionNode *root = this->root();
- if (!root) {
- type_ = GRN_EGN_INCOMPLETE;
- data_type_ = GRN_DB_VOID;
- } else {
- switch (root->type()) {
- case GRN_EGN_ID_NODE: {
- type_ = GRN_EGN_ID;
- break;
- }
- case GRN_EGN_SCORE_NODE: {
- type_ = GRN_EGN_SCORE;
- break;
- }
- case GRN_EGN_CONSTANT_NODE: {
- type_ = GRN_EGN_CONSTANT;
- break;
- }
- case GRN_EGN_COLUMN_NODE:
- case GRN_EGN_OPERATOR_NODE: {
- type_ = GRN_EGN_VARIABLE;
- break;
- }
- default: {
- type_ = GRN_EGN_INCOMPLETE;
- break;
- }
- }
- data_type_ = root->data_type();
- }
-}
-
-grn_rc Expression::push_bulk_object(grn_obj *obj) {
- grn_rc rc;
- ExpressionNode *node;
- switch (obj->header.domain) {
- case GRN_DB_BOOL: {
- rc = ConstantNode<Bool>::open(Bool(GRN_BOOL_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_INT8: {
- rc = ConstantNode<Int>::open(Int(GRN_INT8_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_INT16: {
- rc = ConstantNode<Int>::open(Int(GRN_INT16_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_INT32: {
- rc = ConstantNode<Int>::open(Int(GRN_INT32_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_INT64: {
- rc = ConstantNode<Int>::open(Int(GRN_INT64_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_UINT8: {
- rc = ConstantNode<Int>::open(Int(GRN_UINT8_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_UINT16: {
- rc = ConstantNode<Int>::open(Int(GRN_UINT16_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_UINT32: {
- rc = ConstantNode<Int>::open(Int(GRN_UINT32_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_UINT64: {
- // FIXME: Type conversion from UInt64 to Int may lose the content.
- rc = ConstantNode<Int>::open(Int(GRN_UINT64_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_FLOAT: {
- rc = ConstantNode<Float>::open(Float(GRN_FLOAT_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_TIME: {
- rc = ConstantNode<Time>::open(Time(GRN_TIME_VALUE(obj)), &node);
- break;
- }
- case GRN_DB_SHORT_TEXT:
- case GRN_DB_TEXT:
- case GRN_DB_LONG_TEXT: {
- Text value(GRN_TEXT_VALUE(obj), GRN_TEXT_LEN(obj));
- rc = ConstantNode<Text>::open(value, &node);
- break;
- }
- // TODO: TokyoGeoPoint and Wgs84GeoPoint should be provided?
- case GRN_DB_TOKYO_GEO_POINT:
- case GRN_DB_WGS84_GEO_POINT: {
- GeoPoint value;
- GRN_GEO_POINT_VALUE(obj, value.raw.latitude, value.raw.longitude);
- rc = ConstantNode<GeoPoint>::open(value, &node);
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- if (rc == GRN_SUCCESS) try {
- stack_.push_back(node);
- } catch (const std::bad_alloc &) {
- delete node;
- return GRN_NO_MEMORY_AVAILABLE;
- }
- return rc;
-}
-
-grn_rc Expression::push_column_object(grn_obj *obj) {
- grn_obj *owner_table = grn_column_table(ctx_, obj);
- if (owner_table != table_) {
- return GRN_INVALID_ARGUMENT;
- }
- grn_id range = grn_obj_get_range(ctx_, obj);
- grn_rc rc;
- ExpressionNode *node;
- switch (obj->header.type) {
- case GRN_COLUMN_FIX_SIZE: {
- switch (range) {
- case GRN_DB_BOOL: {
- rc = ColumnNode<Bool>::open(ctx_, obj, &node);
- break;
- }
- case GRN_DB_INT8:
- case GRN_DB_INT16:
- case GRN_DB_INT32:
- case GRN_DB_INT64:
- case GRN_DB_UINT8:
- case GRN_DB_UINT16:
- case GRN_DB_UINT32:
- case GRN_DB_UINT64: {
- rc = ColumnNode<Int>::open(ctx_, obj, &node);
- break;
- }
- case GRN_DB_FLOAT: {
- rc = ColumnNode<Float>::open(ctx_, obj, &node);
- break;
- }
- case GRN_DB_TIME: {
- rc = ColumnNode<Time>::open(ctx_, obj, &node);
- break;
- }
- case GRN_DB_TOKYO_GEO_POINT:
- case GRN_DB_WGS84_GEO_POINT: {
- rc = ColumnNode<GeoPoint>::open(ctx_, obj, &node);
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- break;
- }
- case GRN_COLUMN_VAR_SIZE: {
- grn_obj_flags column_type = obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK;
- switch (column_type) {
- case GRN_OBJ_COLUMN_SCALAR: {
- switch (range) {
- case GRN_DB_SHORT_TEXT:
- case GRN_DB_TEXT:
- case GRN_DB_LONG_TEXT: {
- rc = ColumnNode<Text>::open(ctx_, obj, &node);
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- break;
- }
- break;
- }
- case GRN_OBJ_COLUMN_VECTOR: {
- return GRN_OPERATION_NOT_SUPPORTED;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- if (rc == GRN_SUCCESS) try {
- stack_.push_back(node);
- } catch (const std::bad_alloc &) {
- delete node;
- return GRN_NO_MEMORY_AVAILABLE;
- }
- return rc;
-}
-
-grn_rc Expression::create_unary_node(OperatorType operator_type,
- ExpressionNode *arg, ExpressionNode **node) {
- grn_rc rc = GRN_SUCCESS;
- switch (operator_type) {
- case GRN_OP_NOT: {
- if (arg->data_type() != GRN_DB_BOOL) {
- return GRN_UNKNOWN_ERROR;
- }
- rc = LogicalNotNode::open(arg, node);
- break;
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
- return rc;
-}
-
-grn_rc Expression::create_binary_node(OperatorType operator_type,
- ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
- switch (operator_type) {
- case GRN_OP_AND: {
- if ((arg1->data_type() != GRN_DB_BOOL) ||
- (arg1->data_type() != GRN_DB_BOOL)) {
- return GRN_INVALID_FORMAT;
- }
- return LogicalAndNode::open(arg1, arg2, node);
- }
- case GRN_OP_OR: {
- if ((arg1->data_type() != GRN_DB_BOOL) ||
- (arg1->data_type() != GRN_DB_BOOL)) {
- return GRN_INVALID_FORMAT;
- }
- return LogicalOrNode::open(arg1, arg2, node);
- }
- case GRN_OP_EQUAL: {
- if (arg1->data_type() != arg2->data_type()) {
- return GRN_INVALID_FORMAT;
- }
- switch (arg1->data_type()) {
- case GRN_DB_BOOL: {
- return equal_node_open(EqualOperator<Bool>(), arg1, arg2, node);
- }
- case GRN_DB_INT64: {
- return equal_node_open(EqualOperator<Int>(), arg1, arg2, node);
- }
- case GRN_DB_FLOAT: {
- return equal_node_open(EqualOperator<Float>(), arg1, arg2, node);
- }
- case GRN_DB_TIME: {
- return equal_node_open(EqualOperator<Time>(), arg1, arg2, node);
- }
- case GRN_DB_TEXT: {
- return equal_node_open(EqualOperator<Text>(), arg1, arg2, node);
- }
- case GRN_DB_WGS84_GEO_POINT: {
- return equal_node_open(EqualOperator<GeoPoint>(), arg1, arg2, node);
- }
- default: {
- return GRN_UNKNOWN_ERROR;
- }
- }
- }
- case GRN_OP_NOT_EQUAL: {
- if (arg1->data_type() != arg2->data_type()) {
- return GRN_INVALID_FORMAT;
- }
- switch (arg1->data_type()) {
- case GRN_DB_BOOL: {
- return not_equal_node_open(
- NotEqualOperator<Bool>(), arg1, arg2, node);
- }
- case GRN_DB_INT64: {
- return not_equal_node_open(
- NotEqualOperator<Int>(), arg1, arg2, node);
- }
- case GRN_DB_FLOAT: {
- return not_equal_node_open(
- NotEqualOperator<Float>(), arg1, arg2, node);
- }
- case GRN_DB_TIME: {
- return not_equal_node_open(
- NotEqualOperator<Time>(), arg1, arg2, node);
- }
- case GRN_DB_TEXT: {
- return not_equal_node_open(
- NotEqualOperator<Text>(), arg1, arg2, node);
- }
- case GRN_DB_WGS84_GEO_POINT: {
- return not_equal_node_open(
- NotEqualOperator<GeoPoint>(), arg1, arg2, node);
- }
- default: {
- return GRN_UNKNOWN_ERROR;
- }
- }
- }
- case GRN_OP_LESS: {
- if (arg1->data_type() != arg2->data_type()) {
- return GRN_INVALID_FORMAT;
- }
- switch (arg1->data_type()) {
- case GRN_DB_INT64: {
- return less_node_open(LessOperator<Int>(), arg1, arg2, node);
- }
- case GRN_DB_FLOAT: {
- return less_node_open(LessOperator<Float>(), arg1, arg2, node);
- }
- case GRN_DB_TIME: {
- return less_node_open(LessOperator<Time>(), arg1, arg2, node);
- }
- case GRN_DB_TEXT: {
- return less_node_open(LessOperator<Text>(), arg1, arg2, node);
- }
- default: {
- return GRN_UNKNOWN_ERROR;
- }
- }
- }
- case GRN_OP_LESS_EQUAL: {
- if (arg1->data_type() != arg2->data_type()) {
- return GRN_INVALID_FORMAT;
- }
- switch (arg1->data_type()) {
- case GRN_DB_INT64: {
- return less_equal_node_open(
- LessEqualOperator<Int>(), arg1, arg2, node);
- }
- case GRN_DB_FLOAT: {
- return less_equal_node_open(
- LessEqualOperator<Float>(), arg1, arg2, node);
- }
- case GRN_DB_TIME: {
- return less_equal_node_open(
- LessEqualOperator<Time>(), arg1, arg2, node);
- }
- case GRN_DB_TEXT: {
- return less_equal_node_open(
- LessEqualOperator<Text>(), arg1, arg2, node);
- }
- default: {
- return GRN_UNKNOWN_ERROR;
- }
- }
- }
- case GRN_OP_GREATER: {
- if (arg1->data_type() != arg2->data_type()) {
- return GRN_INVALID_FORMAT;
- }
- switch (arg1->data_type()) {
- case GRN_DB_INT64: {
- return greater_node_open(GreaterOperator<Int>(), arg1, arg2, node);
- }
- case GRN_DB_FLOAT: {
- return greater_node_open(GreaterOperator<Float>(), arg1, arg2, node);
- }
- case GRN_DB_TIME: {
- return greater_node_open(GreaterOperator<Time>(), arg1, arg2, node);
- }
- case GRN_DB_TEXT: {
- return greater_node_open(GreaterOperator<Text>(), arg1, arg2, node);
- }
- default: {
- return GRN_UNKNOWN_ERROR;
- }
- }
- }
- case GRN_OP_GREATER_EQUAL: {
- if (arg1->data_type() != arg2->data_type()) {
- return GRN_INVALID_FORMAT;
- }
- switch (arg1->data_type()) {
- case GRN_DB_INT64: {
- return greater_equal_node_open(
- GreaterEqualOperator<Int>(), arg1, arg2, node);
- }
- case GRN_DB_FLOAT: {
- return greater_equal_node_open(
- GreaterEqualOperator<Float>(), arg1, arg2, node);
- }
- case GRN_DB_TIME: {
- return greater_equal_node_open(
- GreaterEqualOperator<Time>(), arg1, arg2, node);
- }
- case GRN_DB_TEXT: {
- return greater_equal_node_open(
- GreaterEqualOperator<Text>(), arg1, arg2, node);
- }
- default: {
- return GRN_UNKNOWN_ERROR;
- }
- }
- }
- default: {
- return GRN_INVALID_ARGUMENT;
- }
- }
-}
-
-} // namespace egn
-} // namespace grn
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-static grn_rc
-grn_egn_select_filter(grn_ctx *ctx, grn_obj *table,
- const char *filter, size_t filter_size,
- int offset, int limit,
- std::vector<grn_egn_record> *records,
- size_t *num_hits) {
- if (offset < 0) {
- offset = 0;
- }
- if (limit < 0) {
- limit = std::numeric_limits<int>::max();
- }
- grn::egn::Cursor *cursor;
- grn_rc rc = grn::egn::Cursor::open_table_cursor(ctx, table, &cursor);
- if (rc == GRN_SUCCESS) {
- grn::egn::Expression *expression;
- rc = grn::egn::Expression::parse(
- ctx, table, filter, filter_size, &expression);
- if (rc == GRN_SUCCESS) {
- size_t count = 0;
- for ( ; ; ) {
- size_t records_offset = records->size();
- try {
- records->resize(records->size() + GRN_EGN_MAX_BATCH_SIZE);
- } catch (const std::bad_alloc &) {
- rc = GRN_NO_MEMORY_AVAILABLE;
- break;
- }
- size_t batch_size;
- rc = cursor->read(&(*records)[records_offset],
- GRN_EGN_MAX_BATCH_SIZE, &batch_size);
- if (rc != GRN_SUCCESS) {
- break;
- }
- if (batch_size == 0) {
- records->resize(records_offset);
- break;
- }
- rc = expression->filter(&(*records)[records_offset], batch_size,
- NULL, &batch_size);
- if (rc != GRN_SUCCESS) {
- break;
- }
- count += batch_size;
- if (offset > 0) {
- if (offset >= batch_size) {
- offset -= batch_size;
- batch_size = 0;
- } else {
- std::memcpy(&(*records)[0], &(*records)[offset],
- sizeof(grn_egn_record) * (batch_size - offset));
- batch_size -= offset;
- offset = 0;
- }
- }
- if (limit >= batch_size) {
- limit -= batch_size;
- } else {
- batch_size = limit;
- limit = 0;
- }
- records->resize(records_offset + batch_size);
- }
- delete expression;
- *num_hits = count;
- }
- delete cursor;
- }
- return rc;
-}
-
-static grn_rc
-grn_egn_select_output(grn_ctx *ctx, grn_obj *table,
- const char *output_columns, size_t output_columns_size,
- const grn_egn_record *records, size_t num_records,
- size_t num_hits) {
- grn_rc rc = GRN_SUCCESS;
- std::vector<std::string> names;
- std::vector<grn::egn::Expression *> expressions;
-
- const char *rest = output_columns;
- size_t rest_size = output_columns_size;
- while (rest_size != 0) {
- size_t pos;
- for (pos = 0; pos < rest_size; ++pos) {
- if ((rest[pos] != ',') &&
- !std::isspace(static_cast<unsigned char>(rest[pos]))) {
- break;
- }
- }
- if (pos >= rest_size) {
- break;
- }
- rest += pos;
- rest_size -= pos;
- for (pos = 0; pos < rest_size; ++pos) {
- if ((rest[pos] == ',') ||
- std::isspace(static_cast<unsigned char>(rest[pos]))) {
- break;
- }
- }
- // TODO: Error handling.
- std::string name(rest, pos);
- if (name == "*") {
- grn_hash *columns;
- if ((columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
- GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY))) {
- if (grn_table_columns(ctx, table, "", 0, (grn_obj *)columns)) {
- grn_id *key;
- GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, {
- grn_obj *column = grn_ctx_at(ctx, *key);
- if (column) {
- char name_buf[1024];
- int name_size = grn_column_name(
- ctx, column, name_buf, sizeof(name_buf));
- grn::egn::Expression *expression;
- grn_rc r = grn::egn::Expression::open(ctx, table, &expression);
- if (r == GRN_SUCCESS) {
- r = expression->push_object(column);
- if (r == GRN_SUCCESS) {
- names.push_back(std::string(name_buf, name_size));
- expressions.push_back(expression);
- }
- }
- }
- });
- }
- grn_hash_close(ctx, columns);
- }
- } else {
- grn::egn::Expression *expression;
- grn_rc r = grn::egn::Expression::parse(
- ctx, table, rest, pos, &expression);
- if (r == GRN_SUCCESS) {
- names.push_back(name);
- expressions.push_back(expression);
- }
- }
- if (pos >= rest_size) {
- break;
- }
- rest += pos + 1;
- rest_size -= pos + 1;
- }
-
- GRN_OUTPUT_ARRAY_OPEN("RESULT", 1);
- GRN_OUTPUT_ARRAY_OPEN("RESULTSET", 2 + num_records);
- GRN_OUTPUT_ARRAY_OPEN("NHITS", 1);
- grn_text_ulltoa(ctx, ctx->impl->outbuf, num_hits);
- GRN_OUTPUT_ARRAY_CLOSE(); // NHITS.
- GRN_OUTPUT_ARRAY_OPEN("COLUMNS", expressions.size());
- for (size_t i = 0; i < expressions.size(); ++i) {
- GRN_OUTPUT_ARRAY_OPEN("COLUMN", 2);
- GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"');
- GRN_TEXT_PUT(ctx, ctx->impl->outbuf, names[i].data(), names[i].size());
- GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "\",\"", 3);
- switch (expressions[i]->data_type()) {
- case GRN_DB_BOOL: {
- GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Bool");
- break;
- }
- case GRN_DB_INT64: {
- GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Int64");
- break;
- }
- case GRN_DB_FLOAT: {
- GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Float");
- break;
- }
- case GRN_DB_TIME: {
- GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Time");
- break;
- }
- case GRN_DB_SHORT_TEXT:
- case GRN_DB_TEXT:
- case GRN_DB_LONG_TEXT: {
- GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Text");
- break;
- }
- case GRN_DB_WGS84_GEO_POINT: {
- GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "GeoPoint");
- break;
- }
- default: {
- GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "N/A");
- break;
- }
- }
- GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"');
- GRN_OUTPUT_ARRAY_CLOSE();
- }
- GRN_OUTPUT_ARRAY_CLOSE(); // COLUMNS.
- if (num_records != 0) {
- size_t count = 0;
- std::vector<std::vector<char> > bufs(expressions.size());
- while (count < num_records) {
- size_t batch_size = GRN_EGN_MAX_BATCH_SIZE;
- if (batch_size > (num_records - count)) {
- batch_size = num_records - count;
- }
- for (size_t i = 0; i < expressions.size(); ++i) {
- switch (expressions[i]->data_type()) {
- case GRN_DB_BOOL: {
- bufs[i].resize(sizeof(grn_egn_bool) * batch_size);
- expressions[i]->evaluate(records + count, batch_size,
- (grn::egn::Bool *)&bufs[i][0]);
- break;
- }
- case GRN_DB_INT64: {
- bufs[i].resize(sizeof(grn_egn_int) * batch_size);
- expressions[i]->evaluate(records + count, batch_size,
- (grn::egn::Int *)&bufs[i][0]);
- break;
- }
- case GRN_DB_FLOAT: {
- bufs[i].resize(sizeof(grn_egn_float) * batch_size);
- expressions[i]->evaluate(records + count, batch_size,
- (grn::egn::Float *)&bufs[i][0]);
- break;
- }
- case GRN_DB_TIME: {
- bufs[i].resize(sizeof(grn_egn_time) * batch_size);
- expressions[i]->evaluate(records + count, batch_size,
- (grn::egn::Time *)&bufs[i][0]);
- break;
- }
- case GRN_DB_TEXT: {
- bufs[i].resize(sizeof(grn_egn_text) * batch_size);
- expressions[i]->evaluate(records + count, batch_size,
- (grn::egn::Text *)&bufs[i][0]);
- break;
- }
- case GRN_DB_WGS84_GEO_POINT: {
- bufs[i].resize(sizeof(grn_egn_geo_point) * batch_size);
- expressions[i]->evaluate(records + count, batch_size,
- (grn::egn::GeoPoint *)&bufs[i][0]);
- break;
- }
- default: {
- break;
- }
- }
- }
- for (size_t i = 0; i < batch_size; ++i) {
- GRN_OUTPUT_ARRAY_OPEN("HIT", expressions.size());
- for (size_t j = 0; j < expressions.size(); ++j) {
- if (j != 0) {
- GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, ',');
- }
- switch (expressions[j]->data_type()) {
- case GRN_DB_BOOL: {
- if (((grn_egn_bool *)&bufs[j][0])[i]) {
- GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "true", 4);
- } else {
- GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "false", 5);
- }
- break;
- }
- case GRN_DB_INT64: {
- grn_text_lltoa(ctx, ctx->impl->outbuf,
- ((grn_egn_int *)&bufs[j][0])[i]);
- break;
- }
- case GRN_DB_FLOAT: {
- grn_text_ftoa(ctx, ctx->impl->outbuf,
- ((grn_egn_float *)&bufs[j][0])[i]);
- break;
- }
- case GRN_DB_TIME: {
- grn_text_ftoa(ctx, ctx->impl->outbuf,
- ((grn_egn_time *)&bufs[j][0])[i] * 0.000001);
- break;
- }
- case GRN_DB_TEXT: {
- grn_egn_text text = ((grn_egn_text *)&bufs[j][0])[i];
- grn_text_esc(ctx, ctx->impl->outbuf, text.ptr, text.size);
- break;
- }
- case GRN_DB_WGS84_GEO_POINT: {
- grn_egn_geo_point geo_point =
- ((grn_egn_geo_point *)&bufs[j][0])[i];
- GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"');
- grn_text_itoa(ctx, ctx->impl->outbuf, geo_point.latitude);
- GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, 'x');
- grn_text_itoa(ctx, ctx->impl->outbuf, geo_point.longitude);
- GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"');
- break;
- }
- default: {
- break;
- }
- }
- }
- GRN_OUTPUT_ARRAY_CLOSE(); // HITS.
- }
- count += batch_size;
- }
- }
- GRN_OUTPUT_ARRAY_CLOSE(); // RESULTSET.
- GRN_OUTPUT_ARRAY_CLOSE(); // RESET.
- for (size_t i = 0; i < expressions.size(); ++i) {
- delete expressions[i];
- }
- return rc;
-}
-
-grn_rc
-grn_egn_select(grn_ctx *ctx, grn_obj *table,
- const char *filter, size_t filter_size,
- const char *output_columns, size_t output_columns_size,
- int offset, int limit) {
- if (!ctx || !grn_egn_is_table(table) || (!filter && (filter_size != 0)) ||
- (!output_columns && (output_columns_size != 0))) {
- return GRN_INVALID_ARGUMENT;
- }
- std::vector<grn_egn_record> records;
- size_t num_hits;
- grn_rc rc = grn_egn_select_filter(ctx, table, filter, filter_size,
- offset, limit, &records, &num_hits);
- if (rc == GRN_SUCCESS) {
- rc = grn_egn_select_output(ctx, table, output_columns, output_columns_size,
- &*records.begin(), records.size(), num_hits);
- }
- return rc;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // GRN_WITH_EGN
diff --git a/storage/mroonga/vendor/groonga/lib/error.c b/storage/mroonga/vendor/groonga/lib/error.c
index 561394231ea..a745dd8fa08 100644
--- a/storage/mroonga/vendor/groonga/lib/error.c
+++ b/storage/mroonga/vendor/groonga/lib/error.c
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2013 Brazil
+/*
+ Copyright(C) 2013-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,6 +17,7 @@
*/
#include "grn_error.h"
+#include "grn_windows.h"
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -24,33 +26,153 @@
#include <string.h>
#ifdef WIN32
+
+grn_rc
+grn_windows_error_code_to_rc(int error_code)
+{
+ grn_rc rc;
+
+ switch (error_code) {
+ case ERROR_FILE_NOT_FOUND :
+ case ERROR_PATH_NOT_FOUND :
+ rc = GRN_NO_SUCH_FILE_OR_DIRECTORY;
+ break;
+ case ERROR_TOO_MANY_OPEN_FILES :
+ rc = GRN_TOO_MANY_OPEN_FILES;
+ break;
+ case ERROR_ACCESS_DENIED :
+ rc = GRN_PERMISSION_DENIED;
+ break;
+ case ERROR_INVALID_HANDLE :
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ case ERROR_ARENA_TRASHED :
+ rc = GRN_ADDRESS_IS_NOT_AVAILABLE;
+ break;
+ case ERROR_NOT_ENOUGH_MEMORY :
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ break;
+ case ERROR_INVALID_BLOCK :
+ case ERROR_BAD_ENVIRONMENT :
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ case ERROR_BAD_FORMAT :
+ rc = GRN_INVALID_FORMAT;
+ break;
+ case ERROR_INVALID_DATA :
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ case ERROR_OUTOFMEMORY :
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ break;
+ case ERROR_INVALID_DRIVE :
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ case ERROR_WRITE_PROTECT :
+ rc = GRN_PERMISSION_DENIED;
+ break;
+ case ERROR_BAD_LENGTH :
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ case ERROR_SEEK :
+ rc = GRN_INVALID_SEEK;
+ break;
+ case ERROR_NOT_SUPPORTED :
+ rc = GRN_OPERATION_NOT_SUPPORTED;
+ break;
+ case ERROR_NETWORK_ACCESS_DENIED :
+ rc = GRN_OPERATION_NOT_PERMITTED;
+ break;
+ case ERROR_FILE_EXISTS :
+ rc = GRN_FILE_EXISTS;
+ break;
+ case ERROR_INVALID_PARAMETER :
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ case ERROR_BROKEN_PIPE :
+ rc = GRN_BROKEN_PIPE;
+ break;
+ case ERROR_CALL_NOT_IMPLEMENTED :
+ rc = GRN_FUNCTION_NOT_IMPLEMENTED;
+ break;
+ case ERROR_INVALID_NAME :
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ case ERROR_BUSY_DRIVE :
+ case ERROR_PATH_BUSY :
+ rc = GRN_RESOURCE_BUSY;
+ break;
+ case ERROR_BAD_ARGUMENTS :
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ case ERROR_BUSY :
+ rc = GRN_RESOURCE_BUSY;
+ break;
+ case ERROR_ALREADY_EXISTS :
+ rc = GRN_FILE_EXISTS;
+ break;
+ case ERROR_BAD_EXE_FORMAT :
+ rc = GRN_EXEC_FORMAT_ERROR;
+ break;
+ case ERROR_NO_SYSTEM_RESOURCES :
+ rc = GRN_RESOURCE_TEMPORARILY_UNAVAILABLE;
+ break;
+ default:
+ rc = GRN_UNKNOWN_ERROR;
+ break;
+ }
+
+ return rc;
+}
+
+# define LANG_ID_NEUTRAL() MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
+# define LANG_ID_USER_DEFAULT() MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
+# define LANG_ID_SYSTEM_DEFAULT() MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT)
+
const char *
grn_current_error_message(void)
{
# define ERROR_MESSAGE_BUFFER_SIZE 4096
int error_code = GetLastError();
+ static WCHAR utf16_message[ERROR_MESSAGE_BUFFER_SIZE];
+ DWORD written_utf16_chars;
static char message[ERROR_MESSAGE_BUFFER_SIZE];
- DWORD written_bytes;
-
- written_bytes = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- error_code,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- message,
- ERROR_MESSAGE_BUFFER_SIZE,
- NULL);
- if (written_bytes >= 2) {
- if (message[written_bytes - 1] == '\n') {
- message[written_bytes - 1] = '\0';
- written_bytes--;
+
+ written_utf16_chars = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ error_code,
+ LANG_ID_USER_DEFAULT(),
+ utf16_message,
+ ERROR_MESSAGE_BUFFER_SIZE,
+ NULL);
+ if (written_utf16_chars >= 2) {
+ if (utf16_message[written_utf16_chars - 1] == L'\n') {
+ utf16_message[written_utf16_chars - 1] = L'\0';
+ written_utf16_chars--;
}
- if (message[written_bytes - 1] == '\r') {
- message[written_bytes - 1] = '\0';
- written_bytes--;
+ if (utf16_message[written_utf16_chars - 1] == L'\r') {
+ utf16_message[written_utf16_chars - 1] = L'\0';
+ written_utf16_chars--;
}
}
+ {
+ UINT code_page;
+ DWORD convert_flags = 0;
+ int written_bytes;
+
+ code_page = grn_windows_encoding_to_code_page(grn_get_default_encoding());
+ written_bytes = WideCharToMultiByte(code_page,
+ convert_flags,
+ utf16_message,
+ written_utf16_chars,
+ message,
+ ERROR_MESSAGE_BUFFER_SIZE,
+ NULL,
+ NULL);
+ }
+
return message;
# undef ERROR_MESSAGE_BUFFER_SIZE
@@ -76,3 +198,257 @@ grn_strerror(int error_code)
return strerror(error_code);
#endif /* WIN32 */
}
+
+const char *
+grn_rc_to_string(grn_rc rc)
+{
+ const char *message = "invalid grn_rc";
+
+ switch (rc) {
+ case GRN_SUCCESS :
+ message = "success";
+ break;
+ case GRN_END_OF_DATA :
+ message = "end of data";
+ break;
+ case GRN_UNKNOWN_ERROR :
+ message = "unknown error";
+ break;
+ case GRN_OPERATION_NOT_PERMITTED :
+ message = "operation not permitted";
+ break;
+ case GRN_NO_SUCH_FILE_OR_DIRECTORY :
+ message = "no such file or directory";
+ break;
+ case GRN_NO_SUCH_PROCESS :
+ message = "no such process";
+ break;
+ case GRN_INTERRUPTED_FUNCTION_CALL :
+ message = "interrupted function call";
+ break;
+ case GRN_INPUT_OUTPUT_ERROR :
+ message = "input output error";
+ break;
+ case GRN_NO_SUCH_DEVICE_OR_ADDRESS :
+ message = "no such device or address";
+ break;
+ case GRN_ARG_LIST_TOO_LONG :
+ message = "argument list is too long";
+ break;
+ case GRN_EXEC_FORMAT_ERROR :
+ message = "exec format error";
+ break;
+ case GRN_BAD_FILE_DESCRIPTOR :
+ message = "bad file descriptor";
+ break;
+ case GRN_NO_CHILD_PROCESSES :
+ message = "no child processes";
+ break;
+ case GRN_RESOURCE_TEMPORARILY_UNAVAILABLE :
+ message = "resource temporarily unavailable";
+ break;
+ case GRN_NOT_ENOUGH_SPACE :
+ message = "not enough space";
+ break;
+ case GRN_PERMISSION_DENIED :
+ message = "permission denied";
+ break;
+ case GRN_BAD_ADDRESS :
+ message = "bad address";
+ break;
+ case GRN_RESOURCE_BUSY :
+ message = "resource busy";
+ break;
+ case GRN_FILE_EXISTS :
+ message = "file exists";
+ break;
+ case GRN_IMPROPER_LINK :
+ message = "improper link";
+ break;
+ case GRN_NO_SUCH_DEVICE :
+ message = "no such device";
+ break;
+ case GRN_NOT_A_DIRECTORY :
+ message = "not a directory";
+ break;
+ case GRN_IS_A_DIRECTORY :
+ message = "is a directory";
+ break;
+ case GRN_INVALID_ARGUMENT :
+ message = "invalid argument";
+ break;
+ case GRN_TOO_MANY_OPEN_FILES_IN_SYSTEM :
+ message = "too many open files in system";
+ break;
+ case GRN_TOO_MANY_OPEN_FILES :
+ message = "too many open files";
+ break;
+ case GRN_INAPPROPRIATE_I_O_CONTROL_OPERATION :
+ message = "inappropriate I/O control operation";
+ break;
+ case GRN_FILE_TOO_LARGE :
+ message = "file too large";
+ break;
+ case GRN_NO_SPACE_LEFT_ON_DEVICE :
+ message = "no space left on device";
+ break;
+ case GRN_INVALID_SEEK :
+ message = "invalid seek";
+ break;
+ case GRN_READ_ONLY_FILE_SYSTEM :
+ message = "read only file system";
+ break;
+ case GRN_TOO_MANY_LINKS :
+ message = "too many links";
+ break;
+ case GRN_BROKEN_PIPE :
+ message = "broken pipe";
+ break;
+ case GRN_DOMAIN_ERROR :
+ message = "domain error";
+ break;
+ case GRN_RESULT_TOO_LARGE :
+ message = "result too large";
+ break;
+ case GRN_RESOURCE_DEADLOCK_AVOIDED :
+ message = "resource deadlock avoided";
+ break;
+ case GRN_NO_MEMORY_AVAILABLE :
+ message = "no memory available";
+ break;
+ case GRN_FILENAME_TOO_LONG :
+ message = "filename too long";
+ break;
+ case GRN_NO_LOCKS_AVAILABLE :
+ message = "no locks available";
+ break;
+ case GRN_FUNCTION_NOT_IMPLEMENTED :
+ message = "function not implemented";
+ break;
+ case GRN_DIRECTORY_NOT_EMPTY :
+ message = "directory not empty";
+ break;
+ case GRN_ILLEGAL_BYTE_SEQUENCE :
+ message = "illegal byte sequence";
+ break;
+ case GRN_SOCKET_NOT_INITIALIZED :
+ message = "socket not initialized";
+ break;
+ case GRN_OPERATION_WOULD_BLOCK :
+ message = "operation would block";
+ break;
+ case GRN_ADDRESS_IS_NOT_AVAILABLE :
+ message = "address is not available";
+ break;
+ case GRN_NETWORK_IS_DOWN :
+ message = "network is down";
+ break;
+ case GRN_NO_BUFFER :
+ message = "no buffer";
+ break;
+ case GRN_SOCKET_IS_ALREADY_CONNECTED :
+ message = "socket is already connected";
+ break;
+ case GRN_SOCKET_IS_NOT_CONNECTED :
+ message = "socket is not connected";
+ break;
+ case GRN_SOCKET_IS_ALREADY_SHUTDOWNED :
+ message = "socket is already shutdowned";
+ break;
+ case GRN_OPERATION_TIMEOUT :
+ message = "operation timeout";
+ break;
+ case GRN_CONNECTION_REFUSED :
+ message = "connection refused";
+ break;
+ case GRN_RANGE_ERROR :
+ message = "range error";
+ break;
+ case GRN_TOKENIZER_ERROR :
+ message = "tokenizer error";
+ break;
+ case GRN_FILE_CORRUPT :
+ message = "file corrupt";
+ break;
+ case GRN_INVALID_FORMAT :
+ message = "invalid format";
+ break;
+ case GRN_OBJECT_CORRUPT :
+ message = "object corrupt";
+ break;
+ case GRN_TOO_MANY_SYMBOLIC_LINKS :
+ message = "too many symbolic links";
+ break;
+ case GRN_NOT_SOCKET :
+ message = "not socket";
+ break;
+ case GRN_OPERATION_NOT_SUPPORTED :
+ message = "operation not supported";
+ break;
+ case GRN_ADDRESS_IS_IN_USE :
+ message = "address is in use";
+ break;
+ case GRN_ZLIB_ERROR :
+ message = "zlib error";
+ break;
+ case GRN_LZ4_ERROR :
+ message = "LZ4 error";
+ break;
+ case GRN_STACK_OVER_FLOW :
+ message = "stack over flow";
+ break;
+ case GRN_SYNTAX_ERROR :
+ message = "syntax error";
+ break;
+ case GRN_RETRY_MAX :
+ message = "retry max";
+ break;
+ case GRN_INCOMPATIBLE_FILE_FORMAT :
+ message = "incompatible file format";
+ break;
+ case GRN_UPDATE_NOT_ALLOWED :
+ message = "update not allowed";
+ break;
+ case GRN_TOO_SMALL_OFFSET :
+ message = "too small offset";
+ break;
+ case GRN_TOO_LARGE_OFFSET :
+ message = "too large offset";
+ break;
+ case GRN_TOO_SMALL_LIMIT :
+ message = "too small limit";
+ break;
+ case GRN_CAS_ERROR :
+ message = "cas error";
+ break;
+ case GRN_UNSUPPORTED_COMMAND_VERSION :
+ message = "unsupported command version";
+ break;
+ case GRN_NORMALIZER_ERROR :
+ message = "normalizer error";
+ break;
+ case GRN_TOKEN_FILTER_ERROR :
+ message = "token filter error";
+ break;
+ case GRN_COMMAND_ERROR :
+ message = "command error";
+ break;
+ case GRN_PLUGIN_ERROR :
+ message = "plugin error";
+ break;
+ case GRN_SCORER_ERROR :
+ message = "scorer error";
+ break;
+ case GRN_CANCEL :
+ message = "cancel";
+ break;
+ case GRN_WINDOW_FUNCTION_ERROR :
+ message = "window function error";
+ break;
+ case GRN_ZSTD_ERROR :
+ message = "Zstandard error";
+ break;
+ }
+
+ return message;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/expr.c b/storage/mroonga/vendor/groonga/lib/expr.c
index 9ce1fa0adfc..515dbe068d7 100644
--- a/storage/mroonga/vendor/groonga/lib/expr.c
+++ b/storage/mroonga/vendor/groonga/lib/expr.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2010-2015 Brazil
+ Copyright(C) 2010-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -18,17 +18,86 @@
#include "grn.h"
#include "grn_db.h"
#include "grn_ctx_impl.h"
+#include "grn_ctx_impl_mrb.h"
#include <string.h>
#include "grn_ii.h"
#include "grn_geo.h"
#include "grn_expr.h"
#include "grn_expr_code.h"
+#include "grn_expr_executor.h"
+#include "grn_scanner.h"
#include "grn_util.h"
+#include "grn_report.h"
+#include "grn_token_cursor.h"
#include "grn_mrb.h"
#include "mrb/mrb_expr.h"
+#ifdef GRN_WITH_ONIGMO
+# define GRN_SUPPORT_REGEXP
+#endif
+
+#ifdef GRN_SUPPORT_REGEXP
+# include "grn_normalizer.h"
+# include <onigmo.h>
+#endif
+
+static double grn_table_select_enough_filtered_ratio = 0.0;
+static int grn_table_select_max_n_enough_filtered_records = 1000;
+static grn_bool grn_table_select_and_min_skip_enable = GRN_TRUE;
+static grn_bool grn_scan_info_regexp_dot_asterisk_enable = GRN_TRUE;
+
+void
+grn_expr_init_from_env(void)
+{
+ {
+ char grn_table_select_enough_filtered_ratio_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_TABLE_SELECT_ENOUGH_FILTERED_RATIO",
+ grn_table_select_enough_filtered_ratio_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_table_select_enough_filtered_ratio_env[0]) {
+ grn_table_select_enough_filtered_ratio =
+ atof(grn_table_select_enough_filtered_ratio_env);
+ }
+ }
+
+ {
+ char grn_table_select_max_n_enough_filtered_records_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_TABLE_SELECT_MAX_N_ENOUGH_FILTERED_RECORDS",
+ grn_table_select_max_n_enough_filtered_records_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_table_select_max_n_enough_filtered_records_env[0]) {
+ grn_table_select_max_n_enough_filtered_records =
+ atoi(grn_table_select_max_n_enough_filtered_records_env);
+ }
+ }
+
+ {
+ char grn_table_select_and_min_skip_enable_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_TABLE_SELECT_AND_MIN_SKIP_ENABLE",
+ grn_table_select_and_min_skip_enable_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (strcmp(grn_table_select_and_min_skip_enable_env, "no") == 0) {
+ grn_table_select_and_min_skip_enable = GRN_FALSE;
+ } else {
+ grn_table_select_and_min_skip_enable = GRN_TRUE;
+ }
+ }
+
+ {
+ char grn_scan_info_regexp_dot_asterisk_enable_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_SCAN_INFO_REGEXP_DOT_ASTERISK_ENABLE",
+ grn_scan_info_regexp_dot_asterisk_enable_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (strcmp(grn_scan_info_regexp_dot_asterisk_enable_env, "no") == 0) {
+ grn_scan_info_regexp_dot_asterisk_enable = GRN_FALSE;
+ } else {
+ grn_scan_info_regexp_dot_asterisk_enable = GRN_TRUE;
+ }
+ }
+}
+
grn_obj *
-grn_expr_alloc(grn_ctx *ctx, grn_obj *expr, grn_id domain, grn_obj_flags flags)
+grn_expr_alloc(grn_ctx *ctx, grn_obj *expr, grn_id domain, unsigned char flags)
{
grn_obj *res = NULL;
grn_expr *e = (grn_expr *)expr;
@@ -150,7 +219,7 @@ grn_proc_get_or_add_var(grn_ctx *ctx, grn_user_data *user_data,
}
grn_obj *
-grn_proc_alloc(grn_ctx *ctx, grn_user_data *user_data, grn_id domain, grn_obj_flags flags)
+grn_proc_alloc(grn_ctx *ctx, grn_user_data *user_data, grn_id domain, unsigned char flags)
{
grn_proc_ctx *pctx = (grn_proc_ctx *)user_data;
return pctx->caller ? grn_expr_alloc(ctx, (grn_obj *)pctx->caller, domain, flags) : NULL;
@@ -170,10 +239,52 @@ grn_proc_set_selector(grn_ctx *ctx, grn_obj *proc, grn_selector_func selector)
if (!grn_obj_is_function_proc(ctx, proc)) {
return GRN_INVALID_ARGUMENT;
}
- proc_->selector = selector;
+ proc_->callbacks.function.selector = selector;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_proc_set_selector_operator(grn_ctx *ctx, grn_obj *proc, grn_operator op)
+{
+ grn_proc *proc_ = (grn_proc *)proc;
+ if (!grn_obj_is_function_proc(ctx, proc)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ proc_->callbacks.function.selector_op = op;
return GRN_SUCCESS;
}
+grn_operator
+grn_proc_get_selector_operator(grn_ctx *ctx, grn_obj *proc)
+{
+ grn_proc *proc_ = (grn_proc *)proc;
+ if (!grn_obj_is_function_proc(ctx, proc)) {
+ return GRN_OP_NOP;
+ }
+ return proc_->callbacks.function.selector_op;
+}
+
+grn_rc
+grn_proc_set_is_stable(grn_ctx *ctx, grn_obj *proc, grn_bool is_stable)
+{
+ grn_proc *proc_ = (grn_proc *)proc;
+ if (!grn_obj_is_function_proc(ctx, proc)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ proc_->callbacks.function.is_stable = is_stable;
+ return GRN_SUCCESS;
+}
+
+grn_bool
+grn_proc_is_stable(grn_ctx *ctx, grn_obj *proc)
+{
+ grn_proc *proc_ = (grn_proc *)proc;
+ if (!grn_obj_is_function_proc(ctx, proc)) {
+ return GRN_FALSE;
+ }
+ return proc_->callbacks.function.is_stable;
+}
+
/* grn_expr */
grn_obj *
@@ -199,19 +310,26 @@ grn_obj *
grn_expr_alloc_const(grn_ctx *ctx, grn_obj *expr)
{
grn_expr *e = (grn_expr *)expr;
-
- if (!e->consts) {
- if (!(e->consts = GRN_MALLOCN(grn_obj, GRN_STACK_SIZE))) {
+ uint32_t id = e->nconsts % GRN_EXPR_CONST_BLK_SIZE;
+ uint32_t blk_id = e->nconsts / GRN_EXPR_CONST_BLK_SIZE;
+
+ if (id == 0) {
+ uint32_t nblks = blk_id + 1;
+ grn_obj **blks = (grn_obj **)GRN_REALLOC(e->const_blks,
+ sizeof(grn_obj *) * nblks);
+ if (!blks) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "realloc failed");
+ return NULL;
+ }
+ e->const_blks = blks;
+ blks[blk_id] = GRN_MALLOCN(grn_obj, GRN_EXPR_CONST_BLK_SIZE);
+ if (!blks[blk_id]) {
ERR(GRN_NO_MEMORY_AVAILABLE, "malloc failed");
return NULL;
}
}
- if (e->nconsts < GRN_STACK_SIZE) {
- return e->consts + e->nconsts++;
- } else {
- ERR(GRN_STACK_OVER_FLOW, "too many constants.");
- return NULL;
- }
+ e->nconsts++;
+ return &e->const_blks[blk_id][id];
}
void
@@ -357,7 +475,7 @@ grn_expr_open(grn_ctx *ctx, grn_obj_spec *spec, const uint8_t *p, const uint8_t
grn_expr *expr = NULL;
if ((expr = GRN_MALLOCN(grn_expr, 1))) {
int size = GRN_STACK_SIZE;
- expr->consts = NULL;
+ expr->const_blks = NULL;
expr->nconsts = 0;
GRN_TEXT_INIT(&expr->name_buf, 0);
GRN_TEXT_INIT(&expr->dfi, 0);
@@ -408,36 +526,34 @@ typedef struct {
unsigned char type;
} grn_expr_dfi;
-#define DFI_POP(e,d) do {\
- if (GRN_BULK_VSIZE(&(e)->dfi) >= sizeof(grn_expr_dfi)) {\
- GRN_BULK_INCR_LEN((&(e)->dfi), -(sizeof(grn_expr_dfi)));\
- (d) = (grn_expr_dfi *)(GRN_BULK_CURR(&(e)->dfi));\
- (e)->code0 = (d)->code;\
- } else {\
- (d) = NULL;\
- (e)->code0 = NULL;\
- }\
-} while (0)
-
-#define DFI_PUT(e,t,d,c) do {\
- grn_expr_dfi dfi;\
- dfi.type = (t);\
- dfi.domain = (d);\
- dfi.code = (c);\
- if ((e)->code0) { (e)->code0->modify = (c) ? ((c) - (e)->code0) : 0; }\
- grn_bulk_write(ctx, &(e)->dfi, (char *)&dfi, sizeof(grn_expr_dfi));\
- (e)->code0 = NULL;\
-} while (0)
+static grn_expr_dfi *
+grn_expr_dfi_pop(grn_expr *expr)
+{
+ if (GRN_BULK_VSIZE(&expr->dfi) >= sizeof(grn_expr_dfi)) {
+ grn_expr_dfi *dfi;
+ GRN_BULK_INCR_LEN(&expr->dfi, -((ssize_t)(sizeof(grn_expr_dfi))));
+ dfi = (grn_expr_dfi *)GRN_BULK_CURR(&expr->dfi);
+ expr->code0 = dfi->code;
+ return dfi;
+ } else {
+ expr->code0 = NULL;
+ return NULL;
+ }
+}
-grn_expr_dfi *
-dfi_value_at(grn_expr *expr, int offset)
+static void
+grn_expr_dfi_put(grn_ctx *ctx, grn_expr *expr, uint8_t type, grn_id domain,
+ grn_expr_code *code)
{
- grn_obj *obj = &expr->dfi;
- int size = GRN_BULK_VSIZE(obj) / sizeof(grn_expr_dfi);
- if (offset < 0) { offset = size + offset; }
- return (0 <= offset && offset < size)
- ? &(((grn_expr_dfi *)GRN_BULK_HEAD(obj))[offset])
- : NULL;
+ grn_expr_dfi dfi;
+ dfi.type = type;
+ dfi.domain = domain;
+ dfi.code = code;
+ if (expr->code0) {
+ expr->code0->modify = code ? (code - expr->code0) : 0;
+ }
+ grn_bulk_write(ctx, &expr->dfi, (char *)&dfi, sizeof(grn_expr_dfi));
+ expr->code0 = NULL;
}
grn_obj *
@@ -452,7 +568,7 @@ grn_expr_create(grn_ctx *ctx, const char *name, unsigned int name_size)
}
if (name_size) {
ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
- "[expr][create] anonymous expression isn't implemented yet");
+ "[expr][create] named expression isn't implemented yet");
return NULL;
}
GRN_API_ENTER;
@@ -467,7 +583,7 @@ grn_expr_create(grn_ctx *ctx, const char *name, unsigned int name_size)
id = grn_obj_register(ctx, db, name, name_size);
if (id && (expr = GRN_MALLOCN(grn_expr, 1))) {
int size = GRN_STACK_SIZE;
- expr->consts = NULL;
+ expr->const_blks = NULL;
expr->nconsts = 0;
GRN_TEXT_INIT(&expr->name_buf, 0);
GRN_TEXT_INIT(&expr->dfi, 0);
@@ -504,19 +620,10 @@ exit :
GRN_API_RETURN((grn_obj *)expr);
}
-#define GRN_PTR_POP(obj,value) do {\
- if (GRN_BULK_VSIZE(obj) >= sizeof(grn_obj *)) {\
- GRN_BULK_INCR_LEN((obj), -(sizeof(grn_obj *)));\
- value = *(grn_obj **)(GRN_BULK_CURR(obj));\
- } else {\
- value = NULL;\
- }\
-} while (0)
-
grn_rc
grn_expr_close(grn_ctx *ctx, grn_obj *expr)
{
- uint32_t i;
+ uint32_t i, j;
grn_expr *e = (grn_expr *)expr;
GRN_API_ENTER;
/*
@@ -525,10 +632,24 @@ grn_expr_close(grn_ctx *ctx, grn_obj *expr)
}
*/
grn_expr_clear_vars(ctx, expr);
- for (i = 0; i < e->nconsts; i++) {
- grn_obj_close(ctx, &e->consts[i]);
+ if (e->const_blks) {
+ uint32_t nblks = e->nconsts + GRN_EXPR_CONST_BLK_SIZE - 1;
+ nblks /= GRN_EXPR_CONST_BLK_SIZE;
+ for (i = 0; i < nblks; i++) {
+ uint32_t end;
+ if (i < nblks - 1) {
+ end = GRN_EXPR_CONST_BLK_SIZE;
+ } else {
+ end = ((e->nconsts - 1) % GRN_EXPR_CONST_BLK_SIZE) + 1;
+ }
+ for (j = 0; j < end; j++) {
+ grn_obj *const_obj = &e->const_blks[i][j];
+ grn_obj_close(ctx, const_obj);
+ }
+ GRN_FREE(e->const_blks[i]);
+ }
+ GRN_FREE(e->const_blks);
}
- if (e->consts) { GRN_FREE(e->consts); }
grn_obj_close(ctx, &e->name_buf);
grn_obj_close(ctx, &e->dfi);
for (;;) {
@@ -539,6 +660,13 @@ grn_expr_close(grn_ctx *ctx, grn_obj *expr)
grn_obj_unlink(ctx, obj);
#else
if (obj->header.type) {
+ if (obj->header.type == GRN_TABLE_HASH_KEY &&
+ ((grn_hash *)obj)->value_size == sizeof(grn_obj)) {
+ grn_obj *value;
+ GRN_HASH_EACH(ctx, (grn_hash *)obj, id, NULL, NULL, (void **)&value, {
+ GRN_OBJ_FIN(ctx, value);
+ });
+ }
grn_obj_unlink(ctx, obj);
} else {
GRN_LOG(ctx, GRN_LOG_WARNING, "GRN_VOID object is tried to be unlinked");
@@ -637,7 +765,7 @@ grn_expr_get_var_by_offset(grn_ctx *ctx, grn_obj *expr, unsigned int offset)
uint32_t n;
grn_obj *res = NULL;
grn_hash *vars = grn_expr_get_vars(ctx, expr, &n);
- if (vars) { res = (grn_obj *)grn_hash_get_value_(ctx, vars, offset + 1, &n); }
+ if (vars) { res = (grn_obj *)grn_hash_get_value_(ctx, vars, offset + 1, NULL); }
return res;
}
@@ -659,7 +787,7 @@ grn_expr_get_var_by_offset(grn_ctx *ctx, grn_obj *expr, unsigned int offset)
grn_id domain; \
unsigned char type; \
grn_obj *x; \
- DFI_POP(e, dfi); \
+ dfi = grn_expr_dfi_pop(e); \
code_ = dfi->code; \
domain = dfi->domain; \
type = dfi->type; \
@@ -707,7 +835,7 @@ grn_expr_get_var_by_offset(grn_ctx *ctx, grn_obj *expr, unsigned int offset)
} else { \
PUSH_CODE(e, op, obj, nargs, code); \
} \
- DFI_PUT(e, type, domain, code_); \
+ grn_expr_dfi_put(ctx, e, type, domain, code_); \
} while (0)
#define PUSH_N_ARGS_ARITHMETIC_OP(e, op, obj, nargs, code) do { \
@@ -715,10 +843,10 @@ grn_expr_get_var_by_offset(grn_ctx *ctx, grn_obj *expr, unsigned int offset)
{ \
int i = nargs; \
while (i--) { \
- DFI_POP(e, dfi); \
+ dfi = grn_expr_dfi_pop(e); \
} \
} \
- DFI_PUT(e, type, domain, code); \
+ grn_expr_dfi_put(ctx, e, type, domain, code); \
} while (0)
static void
@@ -747,15 +875,35 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
grn_expr *e = (grn_expr *)expr;
GRN_API_ENTER;
if (e->codes_curr >= e->codes_size) {
- ERR(GRN_NO_MEMORY_AVAILABLE, "stack is full");
- goto exit;
+ grn_expr_dfi *dfis = (grn_expr_dfi *)GRN_BULK_HEAD(&e->dfi);
+ size_t i, n_dfis = GRN_BULK_VSIZE(&e->dfi) / sizeof(grn_expr_dfi);
+ uint32_t new_codes_size = e->codes_size * 2;
+ size_t n_bytes = sizeof(grn_expr_code) * new_codes_size;
+ grn_expr_code *new_codes = (grn_expr_code *)GRN_MALLOC(n_bytes);
+ if (!new_codes) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "stack is full");
+ goto exit;
+ }
+ grn_memcpy(new_codes, e->codes, sizeof(grn_expr_code) * e->codes_size);
+ if (e->code0 >= e->codes && e->code0 < e->codes + e->codes_size) {
+ e->code0 = new_codes + (e->code0 - e->codes);
+ }
+ for (i = 0; i < n_dfis; i++) {
+ if (dfis[i].code >= e->codes && dfis[i].code < e->codes + e->codes_size) {
+ dfis[i].code = new_codes + (dfis[i].code - e->codes);
+ }
+ }
+ GRN_FREE(e->codes);
+ e->codes = new_codes;
+ e->codes_size = new_codes_size;
}
{
switch (op) {
case GRN_OP_PUSH :
if (obj) {
PUSH_CODE(e, op, obj, nargs, code);
- DFI_PUT(e, obj->header.type, GRN_OBJ_GET_DOMAIN(obj), code);
+ grn_expr_dfi_put(ctx, e, obj->header.type, GRN_OBJ_GET_DOMAIN(obj),
+ code);
} else {
ERR(GRN_INVALID_ARGUMENT, "obj not assigned for GRN_OP_PUSH");
goto exit;
@@ -770,17 +918,32 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
goto exit;
} else {
PUSH_CODE(e, op, obj, nargs, code);
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
}
break;
case GRN_OP_CALL :
{
grn_obj *proc = NULL;
- if (e->codes_curr - nargs > 0) {
+ /*
+ * This is for keeping backward compatibility. We want to
+ * handle all "nargs" means that "N items on stack are used (N
+ * items are popped)" but "nargs" for OP_CALL is used as "N
+ * arguments" not "N items on stack are used" historically. It
+ * means that called function isn't included in "nargs".
+ *
+ * We adjust "nargs" here to handle "code->nargs" more easily.
+ * If we don't adjust "nargs" here, we need to care
+ * "code->nargs" at all locations that use "code->nargs". We
+ * need to use "code->nargs + 1" for OP_CALL and "code->nargs"
+ * for not OP_CALL to compute N items should be popped. It's
+ * wired. So we adjust "nargs" here.
+ */
+ nargs++;
+ if (e->codes_curr - (nargs - 1) > 0) {
int i;
grn_expr_code *code;
code = &(e->codes[e->codes_curr - 1]);
- for (i = 0; i < nargs; i++) {
+ for (i = 0; i < nargs - 1; i++) {
int rest_n_codes = 1;
while (rest_n_codes > 0) {
rest_n_codes += code->nargs;
@@ -798,7 +961,8 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
goto exit;
}
if (!(grn_obj_is_function_proc(ctx, proc) ||
- grn_obj_is_scorer_proc(ctx, proc))) {
+ grn_obj_is_scorer_proc(ctx, proc) ||
+ grn_obj_is_window_function_proc(ctx, proc))) {
grn_obj buffer;
GRN_TEXT_INIT(&buffer, 0);
@@ -820,16 +984,20 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
GRN_OBJ_FIN(ctx, &buffer);
goto exit;
}
+
+ PUSH_CODE(e, op, obj, nargs, code);
+ {
+ int i = nargs - 1;
+ while (i--) { dfi = grn_expr_dfi_pop(e); }
+ }
+ if (!obj) { dfi = grn_expr_dfi_pop(e); }
+ // todo : increment e->values_tail.
+ /* cannot identify type of return value */
+ grn_expr_dfi_put(ctx, e, type, domain, code);
+ if (!grn_proc_is_stable(ctx, proc)) {
+ e->cacheable = 0;
+ }
}
- PUSH_CODE(e, op, obj, nargs, code);
- {
- int i = nargs;
- while (i--) { DFI_POP(e, dfi); }
- }
- if (!obj) { DFI_POP(e, dfi); }
- // todo : increment e->values_tail.
- DFI_PUT(e, type, domain, code); /* cannot identify type of return value */
- e->cacheable = 0;
break;
case GRN_OP_INTERN :
if (obj && CONSTP(obj)) {
@@ -844,7 +1012,7 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
}
}
PUSH_CODE(e, op, obj, nargs, code);
- DFI_PUT(e, type, domain, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
break;
case GRN_OP_EQUAL :
PUSH_CODE(e, op, obj, nargs, code);
@@ -856,12 +1024,12 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
xd = GRN_OBJ_GET_DOMAIN(obj);
x = obj;
} else {
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
x = dfi->code->value;
xd = dfi->domain;
}
while (i--) {
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
y = dfi->code->value;
yd = dfi->domain;
}
@@ -881,7 +1049,7 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
}
}
}
- DFI_PUT(e, type, domain, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
break;
case GRN_OP_TABLE_CREATE :
case GRN_OP_EXPR_GET_VAR :
@@ -915,10 +1083,10 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
PUSH_CODE(e, op, obj, nargs, code);
if (nargs) {
int i = nargs - 1;
- if (!obj) { DFI_POP(e, dfi); }
- while (i--) { DFI_POP(e, dfi); }
+ if (!obj) { dfi = grn_expr_dfi_pop(e); }
+ while (i--) { dfi = grn_expr_dfi_pop(e); }
}
- DFI_PUT(e, type, domain, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
break;
case GRN_OP_AND :
case GRN_OP_OR :
@@ -933,7 +1101,7 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
{
int i = nargs;
while (i--) {
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
if (dfi) {
dfi->code->flags |= GRN_EXPR_CODE_RELATIONAL_EXPRESSION;
} else {
@@ -941,7 +1109,7 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
}
}
}
- DFI_PUT(e, type, domain, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
break;
case GRN_OP_NOT :
if (nargs == 1) {
@@ -961,7 +1129,25 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
}
break;
case GRN_OP_BITWISE_NOT :
+ dfi = grn_expr_dfi_pop(e);
+ if (dfi) {
+ type = dfi->type;
+ domain = dfi->domain;
+ switch (domain) {
+ case GRN_DB_UINT8 :
+ domain = GRN_DB_INT16;
+ break;
+ case GRN_DB_UINT16 :
+ domain = GRN_DB_INT32;
+ break;
+ case GRN_DB_UINT32 :
+ case GRN_DB_UINT64 :
+ domain = GRN_DB_INT64;
+ break;
+ }
+ }
PUSH_CODE(e, op, obj, nargs, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
break;
case GRN_OP_STAR :
case GRN_OP_SLASH :
@@ -979,7 +1165,7 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
case GRN_OP_INCR_POST :
case GRN_OP_DECR_POST :
{
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
if (dfi) {
type = dfi->type;
domain = dfi->domain;
@@ -995,7 +1181,7 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
}
PUSH_CODE(e, op, obj, nargs, code);
}
- DFI_PUT(e, type, domain, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
break;
case GRN_OP_GET_VALUE :
{
@@ -1005,7 +1191,7 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
grn_obj *v = grn_expr_get_var_by_offset(ctx, expr, 0);
if (v) { vdomain = GRN_OBJ_GET_DOMAIN(v); }
} else {
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
vdomain = dfi->domain;
}
if (vdomain && CONSTP(obj) && obj->header.type == GRN_BULK) {
@@ -1023,12 +1209,12 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
PUSH_CODE(e, op, obj, nargs, code);
} else {
grn_expr_dfi *dfi0;
- DFI_POP(e, dfi0);
+ dfi0 = grn_expr_dfi_pop(e);
if (nargs == 1) {
grn_obj *v = grn_expr_get_var_by_offset(ctx, expr, 0);
if (v) { vdomain = GRN_OBJ_GET_DOMAIN(v); }
} else {
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
vdomain = dfi->domain;
}
if (dfi0->code->op == GRN_OP_PUSH) {
@@ -1053,7 +1239,7 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
}
}
}
- DFI_PUT(e, type, domain, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
break;
case GRN_OP_ASSIGN :
case GRN_OP_STAR_ASSIGN :
@@ -1072,13 +1258,13 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
type = obj->header.type;
domain = GRN_OBJ_GET_DOMAIN(obj);
} else {
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
if (dfi) {
type = dfi->type;
domain = dfi->domain;
}
}
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
if (dfi && (dfi->code)) {
if (dfi->code->op == GRN_OP_GET_VALUE) {
dfi->code->op = GRN_OP_GET_REF;
@@ -1090,22 +1276,22 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
}
PUSH_CODE(e, op, obj, nargs, code);
}
- DFI_PUT(e, type, domain, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
break;
case GRN_OP_JUMP :
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
PUSH_CODE(e, op, obj, nargs, code);
break;
case GRN_OP_CJUMP :
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
PUSH_CODE(e, op, obj, nargs, code);
break;
case GRN_OP_COMMA :
PUSH_CODE(e, op, obj, nargs, code);
break;
case GRN_OP_GET_MEMBER :
- DFI_POP(e, dfi);
- DFI_POP(e, dfi);
+ dfi = grn_expr_dfi_pop(e);
+ dfi = grn_expr_dfi_pop(e);
if (dfi) {
type = dfi->type;
domain = dfi->domain;
@@ -1116,7 +1302,7 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
}
}
PUSH_CODE(e, op, obj, nargs, code);
- DFI_PUT(e, type, domain, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
break;
default :
break;
@@ -1215,6 +1401,26 @@ grn_expr_compile(grn_ctx *ctx, grn_obj *expr)
return ctx->rc;
}
+grn_obj *
+grn_expr_rewrite(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_obj *rewritten = NULL;
+
+ GRN_API_ENTER;
+
+#ifdef GRN_WITH_MRUBY
+ grn_ctx_impl_mrb_ensure_init(ctx);
+ if (ctx->rc != GRN_SUCCESS) {
+ GRN_API_RETURN(NULL);
+ }
+ if (ctx->impl->mrb.state) {
+ rewritten = grn_mrb_expr_rewrite(ctx, expr);
+ }
+#endif
+
+ GRN_API_RETURN(rewritten);
+}
+
#define WITH_SPSAVE(block) do {\
ctx->impl->stack_curr = sp - ctx->impl->stack;\
e->values_curr = vp - e->values;\
@@ -1255,20 +1461,41 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
grn_proc *p = (grn_proc *)proc;
if (nargs > ctx->impl->stack_curr) { return GRN_INVALID_ARGUMENT; }
GRN_API_ENTER;
+ if (grn_obj_is_selector_only_proc(ctx, proc)) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_obj_name(ctx, proc, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "selector only proc can't be called: <%.*s>",
+ name_size, name);
+ GRN_API_RETURN(ctx->rc);
+ }
args = ctx->impl->stack + ctx->impl->stack_curr - nargs;
pctx.proc = p;
pctx.caller = caller;
pctx.user_data.ptr = NULL;
if (p->funcs[PROC_INIT]) {
- obj = p->funcs[PROC_INIT](ctx, nargs, args, &pctx.user_data);
+ grn_obj *sub_obj;
+ sub_obj = p->funcs[PROC_INIT](ctx, nargs, args, &pctx.user_data);
+ if (sub_obj) {
+ obj = sub_obj;
+ }
}
pctx.phase = PROC_NEXT;
if (p->funcs[PROC_NEXT]) {
- obj = p->funcs[PROC_NEXT](ctx, nargs, args, &pctx.user_data);
+ grn_obj *sub_obj;
+ sub_obj = p->funcs[PROC_NEXT](ctx, nargs, args, &pctx.user_data);
+ if (sub_obj) {
+ obj = sub_obj;
+ }
}
pctx.phase = PROC_FIN;
if (p->funcs[PROC_FIN]) {
- obj = p->funcs[PROC_FIN](ctx, nargs, args, &pctx.user_data);
+ grn_obj *sub_obj;
+ sub_obj = p->funcs[PROC_FIN](ctx, nargs, args, &pctx.user_data);
+ if (sub_obj) {
+ obj = sub_obj;
+ }
}
ctx->impl->stack_curr -= nargs;
grn_ctx_push(ctx, obj);
@@ -1499,7 +1726,7 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
if (grn_obj_cast(ctx, y, res, GRN_FALSE)) { \
ERR(GRN_INVALID_ARGUMENT, \
"not a numerical format: <%.*s>", \
- (int)GRN_TEXT_LEN(y), GRN_TEXT_VALUE(y)); \
+ (int)GRN_TEXT_LEN(y), GRN_TEXT_VALUE(y)); \
goto exit; \
} \
set(ctx, res, integer_operation(x_, get(res))); \
@@ -1611,8 +1838,8 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
long long int x_; \
x_ = GRN_INT64_VALUE(x); \
left_expression_check(x_); \
- NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_UINT64_SET, \
- GRN_UINT64_VALUE, \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_INT64_SET, \
+ GRN_INT64_VALUE, \
x_, y, res, \
integer64_operation, \
float_operation, \
@@ -1748,7 +1975,7 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
int y_; \
y_ = GRN_UINT8_VALUE(y); \
ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
- set(ctx, res, signed_integer_operation(x_, y_)); \
+ set(ctx, res, unsigned_integer_operation(x_, y_)); \
} \
break; \
case GRN_DB_INT16 : \
@@ -1764,7 +1991,7 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
int y_; \
y_ = GRN_UINT16_VALUE(y); \
ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
- set(ctx, res, signed_integer_operation(x_, y_)); \
+ set(ctx, res, unsigned_integer_operation(x_, y_)); \
} \
break; \
case GRN_DB_INT32 : \
@@ -2251,13 +2478,70 @@ grn_expr_exec_get_member_vector(grn_ctx *ctx,
i = GRN_UINT32_VALUE(index);
if (values.header.type == GRN_UVECTOR) {
- int n_elements;
- grn_obj_reinit(ctx, result, DB_OBJ(column)->range, 0);
- n_elements = GRN_BULK_VSIZE(&values) / sizeof(grn_id);
+ int n_elements = 0;
+ grn_obj *range;
+ grn_id range_id = DB_OBJ(column)->range;
+
+ grn_obj_reinit(ctx, result, range_id, 0);
+ range = grn_ctx_at(ctx, range_id);
+ if (range) {
+ switch (range->header.type) {
+ case GRN_TYPE :
+ n_elements = GRN_BULK_VSIZE(&values) / grn_type_size(ctx, range);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ n_elements = GRN_BULK_VSIZE(&values) / sizeof(grn_id);
+ break;
+ }
+ }
if (n_elements > i) {
- grn_id value;
- value = GRN_RECORD_VALUE_AT(&values, i);
- GRN_RECORD_SET(ctx, result, value);
+#define GET_UVECTOR_ELEMENT_AS(type) do { \
+ GRN_ ## type ## _SET(ctx, \
+ result, \
+ GRN_ ## type ## _VALUE_AT(&values, i)); \
+ } while (GRN_FALSE)
+ switch (values.header.domain) {
+ case GRN_DB_BOOL :
+ GET_UVECTOR_ELEMENT_AS(BOOL);
+ break;
+ case GRN_DB_INT8 :
+ GET_UVECTOR_ELEMENT_AS(INT8);
+ break;
+ case GRN_DB_UINT8 :
+ GET_UVECTOR_ELEMENT_AS(UINT8);
+ break;
+ case GRN_DB_INT16 :
+ GET_UVECTOR_ELEMENT_AS(INT16);
+ break;
+ case GRN_DB_UINT16 :
+ GET_UVECTOR_ELEMENT_AS(UINT16);
+ break;
+ case GRN_DB_INT32 :
+ GET_UVECTOR_ELEMENT_AS(INT32);
+ break;
+ case GRN_DB_UINT32 :
+ GET_UVECTOR_ELEMENT_AS(UINT32);
+ break;
+ case GRN_DB_INT64 :
+ GET_UVECTOR_ELEMENT_AS(INT64);
+ break;
+ case GRN_DB_UINT64 :
+ GET_UVECTOR_ELEMENT_AS(UINT64);
+ break;
+ case GRN_DB_FLOAT :
+ GET_UVECTOR_ELEMENT_AS(FLOAT);
+ break;
+ case GRN_DB_TIME :
+ GET_UVECTOR_ELEMENT_AS(TIME);
+ break;
+ default :
+ GET_UVECTOR_ELEMENT_AS(RECORD);
+ break;
+ }
+#undef GET_UVECTOR_ELEMENT_AS
}
} else {
if (values.u.v.n_sections > i) {
@@ -2355,7 +2639,11 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
}
} else {
grn_expr *e = (grn_expr *)expr;
- register grn_obj **s_ = ctx->impl->stack, *s0 = NULL, *s1 = NULL, **sp, *vp = e->values;
+ register grn_obj **s_ = ctx->impl->stack;
+ register grn_obj *s0 = NULL;
+ register grn_obj *s1 = NULL;
+ register grn_obj **sp;
+ register grn_obj *vp = e->values;
grn_obj *res = NULL, *v0 = grn_expr_get_var_by_offset(ctx, expr, 0);
grn_expr_code *code = e->codes, *ce = &e->codes[e->codes_curr];
sp = s_ + stack_curr;
@@ -2415,24 +2703,36 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
{
grn_obj *proc;
if (code->value) {
- if (sp < s_ + code->nargs) {
+ if (sp < s_ + code->nargs - 1) {
ERR(GRN_INVALID_ARGUMENT, "stack error");
goto exit;
}
proc = code->value;
WITH_SPSAVE({
- grn_proc_call(ctx, proc, code->nargs, expr);
+ grn_proc_call(ctx, proc, code->nargs - 1, expr);
});
} else {
- int offset = code->nargs + 1;
+ int offset = code->nargs;
if (sp < s_ + offset) {
ERR(GRN_INVALID_ARGUMENT, "stack error");
goto exit;
}
proc = sp[-offset];
- WITH_SPSAVE({
- grn_proc_call(ctx, proc, code->nargs, expr);
- });
+ if (grn_obj_is_window_function_proc(ctx, proc)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, proc);
+ ERR(GRN_INVALID_ARGUMENT,
+ "window function can't be executed for each record: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ goto exit;
+ } else {
+ WITH_SPSAVE({
+ grn_proc_call(ctx, proc, code->nargs - 1, expr);
+ });
+ }
if (ctx->rc) {
goto exit;
}
@@ -2699,10 +2999,10 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
case GRN_OP_CJUMP :
{
grn_obj *v;
- unsigned int v_boolean;
POP1(v);
- GRN_TRUEP(ctx, v, v_boolean);
- if (!v_boolean) { code += code->nargs; }
+ if (!grn_obj_is_true(ctx, v)) {
+ code += code->nargs;
+ }
}
code++;
break;
@@ -2894,13 +3194,10 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
case GRN_OP_AND :
{
grn_obj *x, *y;
- unsigned int x_boolean, y_boolean;
grn_obj *result = NULL;
POP2ALLOC1(x, y, res);
- GRN_TRUEP(ctx, x, x_boolean);
- if (x_boolean) {
- GRN_TRUEP(ctx, y, y_boolean);
- if (y_boolean) {
+ if (grn_obj_is_true(ctx, x)) {
+ if (grn_obj_is_true(ctx, y)) {
result = y;
}
}
@@ -2919,15 +3216,12 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
case GRN_OP_OR :
{
grn_obj *x, *y;
- unsigned int x_boolean, y_boolean;
grn_obj *result;
POP2ALLOC1(x, y, res);
- GRN_TRUEP(ctx, x, x_boolean);
- if (x_boolean) {
+ if (grn_obj_is_true(ctx, x)) {
result = x;
} else {
- GRN_TRUEP(ctx, y, y_boolean);
- if (y_boolean) {
+ if (grn_obj_is_true(ctx, y)) {
result = y;
} else {
result = NULL;
@@ -2948,14 +3242,15 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
case GRN_OP_AND_NOT :
{
grn_obj *x, *y;
+ grn_bool is_true;
POP2ALLOC1(x, y, res);
- if (GRN_INT32_VALUE(x) == 0 || GRN_INT32_VALUE(y) == 1) {
- GRN_INT32_SET(ctx, res, 0);
+ if (!grn_obj_is_true(ctx, x) || grn_obj_is_true(ctx, y)) {
+ is_true = GRN_FALSE;
} else {
- GRN_INT32_SET(ctx, res, 1);
+ is_true = GRN_TRUE;
}
- res->header.type = GRN_BULK;
- res->header.domain = GRN_DB_INT32;
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, is_true);
}
code++;
break;
@@ -2975,8 +3270,8 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
matched = grn_operator_exec_match(ctx, x, y);
});
ALLOC1(res);
- grn_obj_reinit(ctx, res, GRN_DB_INT32, 0);
- GRN_INT32_SET(ctx, res, matched ? 1 : 0);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, matched);
}
code++;
break;
@@ -2986,8 +3281,8 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
grn_obj *x, *y;
POP2ALLOC1(x, y, res);
is_equal = grn_operator_exec_equal(ctx, x, y);
- grn_obj_reinit(ctx, res, GRN_DB_INT32, 0);
- GRN_INT32_SET(ctx, res, is_equal ? 1 : 0);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, is_equal);
}
code++;
break;
@@ -2997,8 +3292,8 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
grn_obj *x, *y;
POP2ALLOC1(x, y, res);
is_not_equal = grn_operator_exec_not_equal(ctx, x, y);
- grn_obj_reinit(ctx, res, GRN_DB_INT32, 0);
- GRN_INT32_SET(ctx, res, is_not_equal ? 1 : 0);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, is_not_equal);
}
code++;
break;
@@ -3012,21 +3307,23 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
matched = grn_operator_exec_prefix(ctx, x, y);
});
ALLOC1(res);
- grn_obj_reinit(ctx, res, GRN_DB_INT32, 0);
- GRN_INT32_SET(ctx, res, matched ? 1 : 0);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, matched);
}
code++;
break;
case GRN_OP_SUFFIX :
{
grn_obj *x, *y;
+ grn_bool matched = GRN_FALSE;
POP2ALLOC1(x, y, res);
- GRN_INT32_SET(ctx, res,
- (GRN_TEXT_LEN(x) >= GRN_TEXT_LEN(y) &&
- !memcmp(GRN_TEXT_VALUE(x) + GRN_TEXT_LEN(x) - GRN_TEXT_LEN(y),
- GRN_TEXT_VALUE(y), GRN_TEXT_LEN(y))));
- res->header.type = GRN_BULK;
- res->header.domain = GRN_DB_INT32;
+ if (GRN_TEXT_LEN(x) >= GRN_TEXT_LEN(y) &&
+ !memcmp(GRN_TEXT_VALUE(x) + GRN_TEXT_LEN(x) - GRN_TEXT_LEN(y),
+ GRN_TEXT_VALUE(y), GRN_TEXT_LEN(y))) {
+ matched = GRN_TRUE;
+ }
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, matched);
}
code++;
break;
@@ -3036,9 +3333,8 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
grn_obj *x, *y;
POP2ALLOC1(x, y, res);
r = grn_operator_exec_less(ctx, x, y);
- GRN_INT32_SET(ctx, res, r ? 1 : 0);
- res->header.type = GRN_BULK;
- res->header.domain = GRN_DB_INT32;
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, r);
}
code++;
break;
@@ -3048,9 +3344,8 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
grn_obj *x, *y;
POP2ALLOC1(x, y, res);
r = grn_operator_exec_greater(ctx, x, y);
- GRN_INT32_SET(ctx, res, r ? 1 : 0);
- res->header.type = GRN_BULK;
- res->header.domain = GRN_DB_INT32;
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, r);
}
code++;
break;
@@ -3060,9 +3355,8 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
grn_obj *x, *y;
POP2ALLOC1(x, y, res);
r = grn_operator_exec_less_equal(ctx, x, y);
- GRN_INT32_SET(ctx, res, r ? 1 : 0);
- res->header.type = GRN_BULK;
- res->header.domain = GRN_DB_INT32;
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, r);
}
code++;
break;
@@ -3072,9 +3366,8 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
grn_obj *x, *y;
POP2ALLOC1(x, y, res);
r = grn_operator_exec_greater_equal(ctx, x, y);
- GRN_INT32_SET(ctx, res, r ? 1 : 0);
- res->header.type = GRN_BULK;
- res->header.domain = GRN_DB_INT32;
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, r);
}
code++;
break;
@@ -3485,7 +3778,7 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
grn_obj *value;
grn_bool value_boolean;
POP1ALLOC1(value, res);
- GRN_TRUEP(ctx, value, value_boolean);
+ GRN_OBJ_IS_TRUE(ctx, value, value_boolean);
grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
GRN_BOOL_SET(ctx, res, !value_boolean);
}
@@ -3579,6 +3872,10 @@ struct _grn_scan_info {
grn_obj scorers;
grn_obj scorer_args_exprs;
grn_obj scorer_args_expr_offsets;
+ struct {
+ grn_bool specified;
+ int start;
+ } position;
};
#define SI_FREE(si) do {\
@@ -3590,24 +3887,33 @@ struct _grn_scan_info {
GRN_FREE(si);\
} while (0)
+#define SI_ALLOC_RAW(si, st) do {\
+ if (((si) = GRN_MALLOCN(scan_info, 1))) {\
+ GRN_INT32_INIT(&(si)->wv, GRN_OBJ_VECTOR);\
+ GRN_PTR_INIT(&(si)->index, GRN_OBJ_VECTOR, GRN_ID_NIL);\
+ (si)->logical_op = GRN_OP_OR;\
+ (si)->flags = SCAN_PUSH;\
+ (si)->nargs = 0;\
+ (si)->max_interval = DEFAULT_MAX_INTERVAL;\
+ (si)->similarity_threshold = DEFAULT_SIMILARITY_THRESHOLD;\
+ (si)->start = (st);\
+ (si)->query = NULL;\
+ GRN_PTR_INIT(&(si)->scorers, GRN_OBJ_VECTOR, GRN_ID_NIL);\
+ GRN_PTR_INIT(&(si)->scorer_args_exprs, GRN_OBJ_VECTOR, GRN_ID_NIL);\
+ GRN_UINT32_INIT(&(si)->scorer_args_expr_offsets, GRN_OBJ_VECTOR);\
+ (si)->position.specified = GRN_FALSE;\
+ (si)->position.start = 0;\
+ }\
+} while (0)
+
#define SI_ALLOC(si, i, st) do {\
- if (!((si) = GRN_MALLOCN(scan_info, 1))) {\
+ SI_ALLOC_RAW(si, st);\
+ if (!(si)) {\
int j;\
for (j = 0; j < i; j++) { SI_FREE(sis[j]); }\
GRN_FREE(sis);\
return NULL;\
}\
- GRN_INT32_INIT(&(si)->wv, GRN_OBJ_VECTOR);\
- GRN_PTR_INIT(&(si)->index, GRN_OBJ_VECTOR, GRN_ID_NIL);\
- (si)->logical_op = GRN_OP_OR;\
- (si)->flags = SCAN_PUSH;\
- (si)->nargs = 0;\
- (si)->max_interval = DEFAULT_MAX_INTERVAL;\
- (si)->similarity_threshold = DEFAULT_SIMILARITY_THRESHOLD;\
- (si)->start = (st);\
- GRN_PTR_INIT(&(si)->scorers, GRN_OBJ_VECTOR, GRN_ID_NIL);\
- GRN_PTR_INIT(&(si)->scorer_args_exprs, GRN_OBJ_VECTOR, GRN_ID_NIL);\
- GRN_UINT32_INIT(&(si)->scorer_args_expr_offsets, GRN_OBJ_VECTOR);\
} while (0)
static scan_info **
@@ -3913,6 +4219,8 @@ grn_scan_info_open(grn_ctx *ctx, int start)
GRN_PTR_INIT(&si->scorers, GRN_OBJ_VECTOR, GRN_ID_NIL);
GRN_PTR_INIT(&si->scorer_args_exprs, GRN_OBJ_VECTOR, GRN_ID_NIL);
GRN_UINT32_INIT(&si->scorer_args_expr_offsets, GRN_OBJ_VECTOR);
+ si->position.specified = GRN_FALSE;
+ si->position.start = 0;
return si;
}
@@ -4041,6 +4349,25 @@ grn_scan_info_get_arg(grn_ctx *ctx, scan_info *si, int i)
return si->args[i];
}
+int
+grn_scan_info_get_start_position(scan_info *si)
+{
+ return si->position.start;
+}
+
+void
+grn_scan_info_set_start_position(scan_info *si, int start)
+{
+ si->position.specified = GRN_TRUE;
+ si->position.start = start;
+}
+
+void
+grn_scan_info_reset_position(scan_info *si)
+{
+ si->position.specified = GRN_FALSE;
+}
+
static uint32_t
scan_info_build_match_expr_codes_find_index(grn_ctx *ctx, scan_info *si,
grn_expr *expr, uint32_t i,
@@ -4105,8 +4432,11 @@ scan_info_build_match_expr_codes_find_index(grn_ctx *ctx, scan_info *si,
}
static uint32_t
-scan_info_build_match_expr_codes(grn_ctx *ctx, scan_info *si,
- grn_expr *expr, uint32_t i)
+scan_info_build_match_expr_codes(grn_ctx *ctx,
+ scan_info *si,
+ grn_expr *expr,
+ uint32_t i,
+ int32_t weight)
{
grn_expr_code *ec;
grn_obj *index = NULL;
@@ -4131,7 +4461,7 @@ scan_info_build_match_expr_codes(grn_ctx *ctx, scan_info *si,
si->flags |= SCAN_ACCESSOR;
}
scan_info_put_index(ctx, si, index, sid,
- get_weight(ctx, &(expr->codes[i]), &offset),
+ get_weight(ctx, &(expr->codes[i]), &offset) + weight,
NULL, NULL, 0);
i += offset;
}
@@ -4161,7 +4491,7 @@ scan_info_build_match_expr_codes(grn_ctx *ctx, scan_info *si,
i++;
}
scan_info_put_index(ctx, si, index, sid,
- get_weight(ctx, &(expr->codes[i]), &offset),
+ get_weight(ctx, &(expr->codes[i]), &offset) + weight,
ec->value,
(grn_obj *)expr,
scorer_args_expr_offset);
@@ -4185,12 +4515,15 @@ scan_info_build_match_expr_codes(grn_ctx *ctx, scan_info *si,
}
static void
-scan_info_build_match_expr(grn_ctx *ctx, scan_info *si, grn_expr *expr)
+scan_info_build_match_expr(grn_ctx *ctx,
+ scan_info *si,
+ grn_expr *expr,
+ int32_t weight)
{
uint32_t i;
i = 0;
while (i < expr->codes_curr) {
- i = scan_info_build_match_expr_codes(ctx, si, expr, i);
+ i = scan_info_build_match_expr_codes(ctx, si, expr, i, weight);
}
}
@@ -4200,6 +4533,7 @@ is_index_searchable_regexp(grn_ctx *ctx, grn_obj *regexp)
const char *regexp_raw;
const char *regexp_raw_end;
grn_bool escaping = GRN_FALSE;
+ grn_bool dot = GRN_FALSE;
if (!(regexp->header.domain == GRN_DB_SHORT_TEXT ||
regexp->header.domain == GRN_DB_TEXT ||
@@ -4253,12 +4587,27 @@ is_index_searchable_regexp(grn_ctx *ctx, grn_obj *regexp)
} else {
switch (regexp_raw[0]) {
case '.' :
+ escaping = GRN_FALSE;
+ if (dot) {
+ return GRN_FALSE;
+ }
+ dot = GRN_TRUE;
+ break;
+ case '*' :
+ escaping = GRN_FALSE;
+ if (!dot) {
+ return GRN_FALSE;
+ }
+ if (!grn_scan_info_regexp_dot_asterisk_enable) {
+ return GRN_FALSE;
+ }
+ dot = GRN_FALSE;
+ break;
case '[' :
case ']' :
case '|' :
case '?' :
case '+' :
- case '*' :
case '{' :
case '}' :
case '^' :
@@ -4268,9 +4617,15 @@ is_index_searchable_regexp(grn_ctx *ctx, grn_obj *regexp)
escaping = GRN_FALSE;
return GRN_FALSE;
case '\\' :
+ if (dot) {
+ return GRN_FALSE;
+ }
escaping = GRN_TRUE;
break;
default :
+ if (dot) {
+ return GRN_FALSE;
+ }
escaping = GRN_FALSE;
break;
}
@@ -4286,7 +4641,7 @@ is_index_searchable_regexp(grn_ctx *ctx, grn_obj *regexp)
}
static void
-scan_info_build_match(grn_ctx *ctx, scan_info *si)
+scan_info_build_match(grn_ctx *ctx, scan_info *si, int32_t weight)
{
grn_obj **p, **pe;
@@ -4305,7 +4660,11 @@ scan_info_build_match(grn_ctx *ctx, scan_info *si)
pe = si->args + si->nargs;
for (; p < pe; p++) {
if ((*p)->header.type == GRN_EXPR) {
- scan_info_build_match_expr(ctx, si, (grn_expr *)(*p));
+ scan_info_build_match_expr(ctx, si, (grn_expr *)(*p), weight);
+ } else if ((*p)->header.type == GRN_COLUMN_INDEX) {
+ scan_info_put_index(ctx, si, *p, 0, 1 + weight, NULL, NULL, 0);
+ } else if (grn_obj_is_proc(ctx, *p)) {
+ break;
} else if (GRN_DB_OBJP(*p)) {
grn_index_datum index_datum;
unsigned int n_index_data;
@@ -4313,7 +4672,7 @@ scan_info_build_match(grn_ctx *ctx, scan_info *si)
&index_datum, 1);
if (n_index_data > 0) {
scan_info_put_index(ctx, si,
- index_datum.index, index_datum.section, 1,
+ index_datum.index, index_datum.section, 1 + weight,
NULL, NULL, 0);
}
} else if (GRN_ACCESSORP(*p)) {
@@ -4330,7 +4689,7 @@ scan_info_build_match(grn_ctx *ctx, scan_info *si)
index = index_datum.index;
}
scan_info_put_index(ctx, si,
- index, index_datum.section, 1,
+ index, index_datum.section, 1 + weight,
NULL, NULL, 0);
}
} else {
@@ -4362,21 +4721,120 @@ scan_info_build_match(grn_ctx *ctx, scan_info *si)
}
}
+static grn_bool
+grn_scan_info_build_full_not(grn_ctx *ctx,
+ scan_info **sis,
+ int *i,
+ grn_expr_code *codes,
+ grn_expr_code *code,
+ grn_expr_code *code_end,
+ grn_operator *next_code_op)
+{
+ scan_info *last_si;
+
+ if (*i == 0) {
+ return GRN_TRUE;
+ }
+
+ last_si = sis[*i - 1];
+ switch (last_si->op) {
+ case GRN_OP_LESS :
+ last_si->op = GRN_OP_GREATER_EQUAL;
+ last_si->end++;
+ break;
+ case GRN_OP_LESS_EQUAL :
+ last_si->op = GRN_OP_GREATER;
+ last_si->end++;
+ break;
+ case GRN_OP_GREATER :
+ last_si->op = GRN_OP_LESS_EQUAL;
+ last_si->end++;
+ break;
+ case GRN_OP_GREATER_EQUAL :
+ last_si->op = GRN_OP_LESS;
+ last_si->end++;
+ break;
+ case GRN_OP_NOT_EQUAL :
+ last_si->op = GRN_OP_EQUAL;
+ last_si->end++;
+ break;
+ default :
+ if (*i == 1) {
+ if (GRN_BULK_VSIZE(&(last_si->index)) > 0) {
+ scan_info *all_records_si = NULL;
+ SI_ALLOC_RAW(all_records_si, 0);
+ if (!all_records_si) {
+ return GRN_FALSE;
+ }
+ all_records_si->op = GRN_OP_CALL;
+ all_records_si->args[all_records_si->nargs++] =
+ grn_ctx_get(ctx, "all_records", -1);
+ last_si->logical_op = GRN_OP_AND_NOT;
+ last_si->flags &= ~SCAN_PUSH;
+ sis[*i] = sis[*i - 1];
+ sis[*i - 1] = all_records_si;
+ (*i)++;
+ } else {
+ if (last_si->op == GRN_OP_EQUAL) {
+ last_si->op = GRN_OP_NOT_EQUAL;
+ last_si->end++;
+ } else {
+ return GRN_FALSE;
+ }
+ }
+ } else {
+ grn_expr_code *next_code = code + 1;
+
+ if (next_code >= code_end) {
+ return GRN_FALSE;
+ }
+
+ switch (next_code->op) {
+ case GRN_OP_AND :
+ *next_code_op = GRN_OP_AND_NOT;
+ break;
+ case GRN_OP_AND_NOT :
+ *next_code_op = GRN_OP_AND;
+ break;
+ case GRN_OP_OR :
+ {
+ scan_info *all_records_si = NULL;
+ SI_ALLOC_RAW(all_records_si, 0);
+ if (!all_records_si) {
+ return GRN_FALSE;
+ }
+ all_records_si->op = GRN_OP_CALL;
+ all_records_si->args[all_records_si->nargs++] =
+ grn_ctx_get(ctx, "all_records", -1);
+ sis[*i] = sis[*i - 1];
+ sis[*i - 1] = all_records_si;
+ (*i)++;
+ put_logical_op(ctx, sis, i, GRN_OP_AND_NOT, code - codes);
+ }
+ break;
+ default :
+ return GRN_FALSE;
+ break;
+ }
+ }
+ }
+
+ return GRN_TRUE;
+}
+
static scan_info **
-scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
- grn_operator op, uint32_t size)
+grn_scan_info_build_full(grn_ctx *ctx, grn_obj *expr, int *n,
+ grn_operator op, grn_bool record_exist)
{
grn_obj *var;
scan_stat stat;
int i, m = 0, o = 0;
+ int n_nots = 0;
scan_info **sis, *si = NULL;
grn_expr_code *c, *ce;
grn_expr *e = (grn_expr *)expr;
-#ifdef GRN_WITH_MRUBY
- if (ctx->impl->mrb.state) {
- return grn_mrb_scan_info_build(ctx, expr, n, op, size);
- }
-#endif
+ grn_operator next_code_op;
+
if (!(var = grn_expr_get_var_by_offset(ctx, expr, 0))) { return NULL; }
for (stat = SCAN_START, c = e->codes, ce = &e->codes[e->codes_curr]; c < ce; c++) {
switch (c->op) {
@@ -4420,12 +4878,45 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
case GRN_OP_OR :
case GRN_OP_AND_NOT :
case GRN_OP_ADJUST :
- if (stat != SCAN_START) { return NULL; }
- o++;
- if (o >= m) { return NULL; }
+ switch (stat) {
+ case SCAN_START :
+ o++;
+ if (o >= m) { return NULL; }
+ break;
+ case SCAN_CONST :
+ o++;
+ m++;
+ if (o >= m) { return NULL; }
+ stat = SCAN_START;
+ break;
+ default :
+ return NULL;
+ break;
+ }
break;
case GRN_OP_PUSH :
- stat = (c->value == var) ? SCAN_VAR : SCAN_CONST;
+ {
+ grn_bool is_completed_term = GRN_FALSE;
+ if (c->modify > 0) {
+ switch ((c + c->modify)->op) {
+ case GRN_OP_AND :
+ case GRN_OP_OR :
+ case GRN_OP_AND_NOT :
+ case GRN_OP_ADJUST :
+ is_completed_term = GRN_TRUE;
+ break;
+ default :
+ is_completed_term = GRN_FALSE;
+ break;
+ }
+ }
+ if (is_completed_term) {
+ m++;
+ stat = SCAN_START;
+ } else {
+ stat = (c->value == var) ? SCAN_VAR : SCAN_CONST;
+ }
+ }
break;
case GRN_OP_GET_VALUE :
switch (stat) {
@@ -4452,15 +4943,54 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
stat = SCAN_COL2;
}
break;
+ case GRN_OP_GET_REF :
+ switch (stat) {
+ case SCAN_START :
+ stat = SCAN_COL1;
+ break;
+ default :
+ return NULL;
+ break;
+ }
+ break;
+ case GRN_OP_GET_MEMBER :
+ switch (stat) {
+ case SCAN_CONST :
+ {
+ grn_expr_code *prev_c = c - 1;
+ if (prev_c->value->header.domain < GRN_DB_INT8 ||
+ prev_c->value->header.domain > GRN_DB_UINT64) {
+ return NULL;
+ }
+ }
+ stat = SCAN_COL1;
+ break;
+ default :
+ return NULL;
+ break;
+ }
+ break;
+ case GRN_OP_NOT :
+ n_nots++;
+ break;
default :
return NULL;
break;
}
}
if (stat || m != o + 1) { return NULL; }
- if (!(sis = GRN_MALLOCN(scan_info *, m + m + o))) { return NULL; }
+ if (!(sis = GRN_MALLOCN(scan_info *, m + m + o + n_nots))) { return NULL; }
+
+ next_code_op = -1;
for (i = 0, stat = SCAN_START, c = e->codes, ce = &e->codes[e->codes_curr]; c < ce; c++) {
- switch (c->op) {
+ grn_operator code_op;
+ if (next_code_op == -1) {
+ code_op = c->op;
+ } else {
+ code_op = next_code_op;
+ next_code_op = -1;
+ }
+ switch (code_op) {
case GRN_OP_MATCH :
case GRN_OP_NEAR :
case GRN_OP_NEAR2 :
@@ -4479,10 +5009,16 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
case GRN_OP_TERM_EXTRACT :
case GRN_OP_REGEXP :
stat = SCAN_START;
- si->op = c->op;
+ si->op = code_op;
si->end = c - e->codes;
sis[i++] = si;
- scan_info_build_match(ctx, si);
+ {
+ int32_t weight = 0;
+ if (c->value && c->value->header.domain == GRN_DB_INT32) {
+ weight = GRN_INT32_VALUE(c->value);
+ }
+ scan_info_build_match(ctx, si, weight);
+ }
if (ctx->rc != GRN_SUCCESS) {
int j;
for (j = 0; j < i; j++) { SI_FREE(sis[j]); }
@@ -4495,7 +5031,13 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
case GRN_OP_OR :
case GRN_OP_AND_NOT :
case GRN_OP_ADJUST :
- if (!put_logical_op(ctx, sis, &i, c->op, c - e->codes)) { return NULL; }
+ if (stat == SCAN_CONST) {
+ si->op = GRN_OP_PUSH;
+ si->end = si->start;
+ sis[i++] = si;
+ si = NULL;
+ }
+ if (!put_logical_op(ctx, sis, &i, code_op, c - e->codes)) { return NULL; }
stat = SCAN_START;
break;
case GRN_OP_PUSH :
@@ -4509,6 +5051,27 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
if (stat == SCAN_START) { si->flags |= SCAN_PRE_CONST; }
stat = SCAN_CONST;
}
+ if (c->modify > 0) {
+ grn_bool is_completed_term = GRN_FALSE;
+ switch ((c + c->modify)->op) {
+ case GRN_OP_AND :
+ case GRN_OP_OR :
+ case GRN_OP_AND_NOT :
+ case GRN_OP_ADJUST :
+ is_completed_term = GRN_TRUE;
+ break;
+ default :
+ is_completed_term = GRN_FALSE;
+ break;
+ }
+ if (is_completed_term) {
+ si->op = GRN_OP_PUSH;
+ si->end = si->start;
+ sis[i++] = si;
+ si = NULL;
+ stat = SCAN_START;
+ }
+ }
break;
case GRN_OP_GET_VALUE :
switch (stat) {
@@ -4553,17 +5116,25 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
if (!si) { SI_ALLOC(si, i, c - e->codes); }
if ((c->flags & GRN_EXPR_CODE_RELATIONAL_EXPRESSION) || c + 1 == ce) {
stat = SCAN_START;
- si->op = c->op;
+ si->op = code_op;
si->end = c - e->codes;
sis[i++] = si;
/* better index resolving framework for functions should be implemented */
- {
- grn_obj **p = si->args, **pe = si->args + si->nargs;
+ if (grn_obj_is_selector_proc(ctx, si->args[0])) {
+ grn_obj *selector;
+ grn_obj **p;
+ grn_obj **pe;
+ grn_operator selector_op;
+
+ selector = si->args[0];
+ p = si->args + 1;
+ pe = si->args + si->nargs;
+ selector_op = grn_proc_get_selector_operator(ctx, selector);
for (; p < pe; p++) {
if (GRN_DB_OBJP(*p)) {
grn_index_datum index_datum;
unsigned int n_index_data;
- n_index_data = grn_column_find_index_data(ctx, *p, c->op,
+ n_index_data = grn_column_find_index_data(ctx, *p, selector_op,
&index_datum, 1);
if (n_index_data > 0) {
scan_info_put_index(ctx, si,
@@ -4574,7 +5145,7 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
grn_index_datum index_datum;
unsigned int n_index_data;
si->flags |= SCAN_ACCESSOR;
- n_index_data = grn_column_find_index_data(ctx, *p, c->op,
+ n_index_data = grn_column_find_index_data(ctx, *p, selector_op,
&index_datum, 1);
if (n_index_data > 0) {
scan_info_put_index(ctx, si,
@@ -4591,11 +5162,56 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
stat = SCAN_COL2;
}
break;
+ case GRN_OP_GET_REF :
+ switch (stat) {
+ case SCAN_START :
+ if (!si) { SI_ALLOC(si, i, c - e->codes); }
+ stat = SCAN_COL1;
+ if (si->nargs < GRN_SCAN_INFO_MAX_N_ARGS) {
+ si->args[si->nargs++] = c->value;
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case GRN_OP_GET_MEMBER :
+ {
+ grn_obj *start_position;
+ grn_obj buffer;
+ start_position = si->args[--si->nargs];
+ GRN_INT32_INIT(&buffer, 0);
+ grn_obj_cast(ctx, start_position, &buffer, GRN_FALSE);
+ grn_scan_info_set_start_position(si, GRN_INT32_VALUE(&buffer));
+ GRN_OBJ_FIN(ctx, &buffer);
+ }
+ stat = SCAN_COL1;
+ break;
+ case GRN_OP_NOT :
+ {
+ grn_bool valid;
+ valid = grn_scan_info_build_full_not(ctx,
+ sis,
+ &i,
+ e->codes,
+ c,
+ ce,
+ &next_code_op);
+ if (!valid) {
+ int j;
+ for (j = 0; j < i; j++) {
+ SI_FREE(sis[j]);
+ }
+ GRN_FREE(sis);
+ return NULL;
+ }
+ }
+ break;
default :
break;
}
}
- if (op == GRN_OP_OR && !size) {
+ if (op == GRN_OP_OR && !record_exist) {
// for debug
if (!(sis[0]->flags & SCAN_PUSH) || (sis[0]->logical_op != op)) {
int j;
@@ -4614,6 +5230,333 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
return sis;
}
+static scan_info **
+grn_scan_info_build_simple_open(grn_ctx *ctx, int *n, grn_operator logical_op)
+{
+ scan_info **sis;
+ scan_info *si;
+
+ sis = GRN_MALLOCN(scan_info *, 1);
+ if (!sis) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[scan_info][build] failed to allocate memory for scan_info **");
+ return NULL;
+ }
+
+ si = grn_scan_info_open(ctx, 0);
+ if (!si) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[scan_info][build] failed to allocate memory for scan_info *");
+ GRN_FREE(sis);
+ return NULL;
+ }
+
+ si->flags &= ~SCAN_PUSH;
+ si->logical_op = logical_op;
+
+ sis[0] = si;
+ *n = 1;
+
+ return sis;
+}
+
+static scan_info **
+grn_scan_info_build_simple_value(grn_ctx *ctx,
+ grn_obj *expr,
+ int *n,
+ grn_operator logical_op,
+ grn_bool record_exist)
+{
+ grn_expr *e = (grn_expr *)expr;
+ scan_info **sis;
+ scan_info *si;
+ grn_expr_code *target = e->codes;
+
+ switch (target->op) {
+ case GRN_OP_PUSH :
+ case GRN_OP_GET_VALUE :
+ break;
+ default :
+ return NULL;
+ break;
+ }
+
+ sis = grn_scan_info_build_simple_open(ctx, n, logical_op);
+ if (!sis) {
+ return NULL;
+ }
+
+ si = sis[0];
+ si->end = 0;
+ si->op = target->op;
+ return sis;
+}
+
+static scan_info **
+grn_scan_info_build_simple_operation(grn_ctx *ctx,
+ grn_obj *expr,
+ int *n,
+ grn_operator logical_op,
+ grn_bool record_exist)
+{
+ grn_expr *e = (grn_expr *)expr;
+ grn_expr_code *target;
+ grn_expr_code *constant;
+ grn_expr_code *operator;
+ scan_info **sis;
+ scan_info *si;
+
+ target = e->codes + 0;
+ constant = e->codes + 1;
+ operator = e->codes + 2;
+
+ if (target->op != GRN_OP_GET_VALUE) {
+ return NULL;
+ }
+ if (target->nargs != 1) {
+ return NULL;
+ }
+ if (!target->value) {
+ return NULL;
+ }
+
+ if (constant->op != GRN_OP_PUSH) {
+ return NULL;
+ }
+ if (constant->nargs != 1) {
+ return NULL;
+ }
+ if (!constant->value) {
+ return NULL;
+ }
+
+ if (operator->nargs != 2) {
+ return NULL;
+ }
+ switch (operator->op) {
+ case GRN_OP_MATCH :
+ case GRN_OP_NEAR :
+ case GRN_OP_SIMILAR :
+ case GRN_OP_PREFIX :
+ case GRN_OP_SUFFIX :
+ case GRN_OP_EQUAL :
+ case GRN_OP_NOT_EQUAL :
+ case GRN_OP_LESS :
+ case GRN_OP_GREATER :
+ case GRN_OP_LESS_EQUAL :
+ case GRN_OP_GREATER_EQUAL :
+ case GRN_OP_TERM_EXTRACT :
+ case GRN_OP_REGEXP :
+ break;
+ default :
+ return NULL;
+ break;
+ }
+
+ sis = grn_scan_info_build_simple_open(ctx, n, logical_op);
+ if (!sis) {
+ return NULL;
+ }
+
+ si = sis[0];
+ si->end = 2;
+ si->op = operator->op;
+ si->args[si->nargs++] = target->value;
+ si->args[si->nargs++] = constant->value;
+ {
+ int32_t weight = 0;
+ if (operator->value && operator->value->header.domain == GRN_DB_INT32) {
+ weight = GRN_INT32_VALUE(operator->value);
+ }
+ scan_info_build_match(ctx, si, weight);
+ }
+ return sis;
+}
+
+static scan_info **
+grn_scan_info_build_simple_and_operations(grn_ctx *ctx,
+ grn_obj *expr,
+ int *n,
+ grn_operator logical_op,
+ grn_bool record_exist)
+{
+ grn_expr *e = (grn_expr *)expr;
+ scan_info **sis = NULL;
+ int n_sis = 0;
+ int i;
+ int nth_sis;
+
+ for (i = 0, nth_sis = 0; i < e->codes_curr; i += 3, nth_sis++) {
+ grn_expr_code *target = e->codes + i;
+ grn_expr_code *constant = e->codes + i + 1;
+ grn_expr_code *operator = e->codes + i + 2;
+
+ if (target->op != GRN_OP_GET_VALUE) {
+ return NULL;
+ }
+ if (target->nargs != 1) {
+ return NULL;
+ }
+ if (!target->value) {
+ return NULL;
+ }
+
+ if (constant->op != GRN_OP_PUSH) {
+ return NULL;
+ }
+ if (constant->nargs != 1) {
+ return NULL;
+ }
+ if (!constant->value) {
+ return NULL;
+ }
+
+ if (operator->nargs != 2) {
+ return NULL;
+ }
+ switch (operator->op) {
+ case GRN_OP_MATCH :
+ case GRN_OP_NEAR :
+ case GRN_OP_SIMILAR :
+ case GRN_OP_PREFIX :
+ case GRN_OP_SUFFIX :
+ case GRN_OP_EQUAL :
+ case GRN_OP_NOT_EQUAL :
+ case GRN_OP_LESS :
+ case GRN_OP_GREATER :
+ case GRN_OP_LESS_EQUAL :
+ case GRN_OP_GREATER_EQUAL :
+ case GRN_OP_TERM_EXTRACT :
+ case GRN_OP_REGEXP :
+ break;
+ default :
+ return NULL;
+ break;
+ }
+
+ if (nth_sis > 0) {
+ grn_expr_code *logical_operator = e->codes + i + 3;
+
+ if (logical_operator->op != GRN_OP_AND) {
+ return NULL;
+ }
+ if (logical_operator->nargs != 2) {
+ return NULL;
+ }
+
+ i++;
+ }
+ }
+ n_sis = nth_sis;
+
+ sis = GRN_CALLOC(sizeof(scan_info *) * n_sis);
+ if (!sis) {
+ return NULL;
+ }
+
+ for (i = 0, nth_sis = 0; i < e->codes_curr; i += 3, nth_sis++) {
+ grn_expr_code *target = e->codes + i;
+ grn_expr_code *constant = e->codes + i + 1;
+ grn_expr_code *operator = e->codes + i + 2;
+ scan_info *si;
+
+ sis[nth_sis] = si = grn_scan_info_open(ctx, i);
+ if (!si) {
+ goto exit;
+ }
+ si->args[si->nargs++] = target->value;
+ si->args[si->nargs++] = constant->value;
+ si->op = operator->op;
+ si->end = i + 2;
+ si->flags &= ~SCAN_PUSH;
+ if (nth_sis == 0) {
+ si->logical_op = logical_op;
+ } else {
+ si->logical_op = GRN_OP_AND;
+ }
+ {
+ int32_t weight = 0;
+ if (operator->value && operator->value->header.domain == GRN_DB_INT32) {
+ weight = GRN_INT32_VALUE(operator->value);
+ }
+ scan_info_build_match(ctx, si, weight);
+ }
+
+ if (nth_sis > 0) {
+ i++;
+ }
+ }
+
+ *n = n_sis;
+ return sis;
+
+exit :
+ if (n_sis > 0) {
+ for (i = 0; i < n_sis; i++) {
+ scan_info *si = sis[i];
+ if (si) {
+ grn_scan_info_close(ctx, si);
+ }
+ }
+ GRN_FREE(sis);
+ }
+
+ return NULL;
+}
+
+static scan_info **
+grn_scan_info_build_simple(grn_ctx *ctx, grn_obj *expr, int *n,
+ grn_operator logical_op, grn_bool record_exist)
+{
+ grn_expr *e = (grn_expr *)expr;
+
+ if (e->codes_curr == 1) {
+ return grn_scan_info_build_simple_value(ctx,
+ expr,
+ n,
+ logical_op,
+ record_exist);
+ } else if (e->codes_curr == 3) {
+ return grn_scan_info_build_simple_operation(ctx,
+ expr,
+ n,
+ logical_op,
+ record_exist);
+ } else if (e->codes_curr % 4 == 3) {
+ return grn_scan_info_build_simple_and_operations(ctx,
+ expr,
+ n,
+ logical_op,
+ record_exist);
+ }
+
+ return NULL;
+}
+
+scan_info **
+grn_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
+ grn_operator op, grn_bool record_exist)
+{
+ scan_info **sis;
+
+ sis = grn_scan_info_build_simple(ctx, expr, n, op, record_exist);
+#ifdef GRN_WITH_MRUBY
+ if (!sis) {
+ grn_ctx_impl_mrb_ensure_init(ctx);
+ if (ctx->rc != GRN_SUCCESS) {
+ return NULL;
+ }
+ if (ctx->impl->mrb.state) {
+ return grn_mrb_scan_info_build(ctx, expr, n, op, record_exist);
+ }
+ }
+#endif
+ if (!sis) {
+ sis = grn_scan_info_build_full(ctx, expr, n, op, record_exist);
+ }
+ return sis;
+}
+
void
grn_inspect_scan_info_list(grn_ctx *ctx, grn_obj *buffer, scan_info **sis, int n)
{
@@ -4630,9 +5573,22 @@ grn_inspect_scan_info_list(grn_ctx *ctx, grn_obj *buffer, scan_info **sis, int n
" logical_op: <%s>\n",
grn_operator_to_string(si->logical_op));
- GRN_TEXT_PUTS(ctx, buffer, " query: <");
- grn_inspect(ctx, buffer, si->query);
- GRN_TEXT_PUTS(ctx, buffer, ">\n");
+ if (si->op == GRN_OP_CALL) {
+ int i;
+ for (i = 0; i < si->nargs; i++) {
+ grn_text_printf(ctx, buffer, " args[%d]: <", i);
+ grn_inspect(ctx, buffer, si->args[i]);
+ GRN_TEXT_PUTS(ctx, buffer, ">\n");
+ }
+ } else {
+ GRN_TEXT_PUTS(ctx, buffer, " index: <");
+ grn_inspect(ctx, buffer, &(si->index));
+ GRN_TEXT_PUTS(ctx, buffer, ">\n");
+
+ GRN_TEXT_PUTS(ctx, buffer, " query: <");
+ grn_inspect(ctx, buffer, si->query);
+ GRN_TEXT_PUTS(ctx, buffer, ">\n");
+ }
grn_text_printf(ctx, buffer,
" expr: <%d..%d>\n", si->start, si->end);
@@ -4662,10 +5618,18 @@ exec_result_to_score(grn_ctx *ctx, grn_obj *result, grn_obj *score_buffer)
case GRN_VOID :
return 0;
case GRN_BULK :
- if (grn_obj_cast(ctx, result, score_buffer, GRN_FALSE) != GRN_SUCCESS) {
- return 1;
+ switch (result->header.domain) {
+ case GRN_DB_BOOL :
+ return GRN_BOOL_VALUE(result) ? 1 : 0;
+ case GRN_DB_INT32 :
+ return GRN_INT32_VALUE(result);
+ default :
+ GRN_BULK_REWIND(score_buffer);
+ if (grn_obj_cast(ctx, result, score_buffer, GRN_FALSE) != GRN_SUCCESS) {
+ return 1;
+ }
+ return GRN_INT32_VALUE(score_buffer);
}
- return GRN_INT32_VALUE(score_buffer);
case GRN_UVECTOR :
case GRN_PVECTOR :
case GRN_VECTOR :
@@ -4679,25 +5643,29 @@ static void
grn_table_select_sequential(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
grn_obj *v, grn_obj *res, grn_operator op)
{
+ grn_obj *result;
+ grn_obj score_buffer;
int32_t score;
grn_id id, *idp;
grn_table_cursor *tc;
grn_hash_cursor *hc;
grn_hash *s = (grn_hash *)res;
- grn_obj *r;
- grn_obj score_buffer;
- GRN_RECORD_INIT(v, 0, grn_obj_id(ctx, table));
+ grn_expr_executor *executor;
+
+ executor = grn_expr_executor_open(ctx, expr);
+ if (!executor) {
+ return;
+ }
GRN_INT32_INIT(&score_buffer, 0);
switch (op) {
case GRN_OP_OR :
if ((tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, 0))) {
while ((id = grn_table_cursor_next(ctx, tc))) {
- GRN_RECORD_SET(ctx, v, id);
- r = grn_expr_exec(ctx, expr, 0);
+ result = grn_expr_executor_exec(ctx, executor, id);
if (ctx->rc) {
break;
}
- score = exec_result_to_score(ctx, r, &score_buffer);
+ score = exec_result_to_score(ctx, result, &score_buffer);
if (score > 0) {
grn_rset_recinfo *ri;
if (grn_hash_add(ctx, s, &id, s->key_size, (void **)&ri, NULL)) {
@@ -4712,12 +5680,11 @@ grn_table_select_sequential(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
if ((hc = grn_hash_cursor_open(ctx, s, NULL, 0, NULL, 0, 0, -1, 0))) {
while (grn_hash_cursor_next(ctx, hc)) {
grn_hash_cursor_get_key(ctx, hc, (void **) &idp);
- GRN_RECORD_SET(ctx, v, *idp);
- r = grn_expr_exec(ctx, expr, 0);
+ result = grn_expr_executor_exec(ctx, executor, *idp);
if (ctx->rc) {
break;
}
- score = exec_result_to_score(ctx, r, &score_buffer);
+ score = exec_result_to_score(ctx, result, &score_buffer);
if (score > 0) {
grn_rset_recinfo *ri;
grn_hash_cursor_get_value(ctx, hc, (void **) &ri);
@@ -4733,12 +5700,11 @@ grn_table_select_sequential(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
if ((hc = grn_hash_cursor_open(ctx, s, NULL, 0, NULL, 0, 0, -1, 0))) {
while (grn_hash_cursor_next(ctx, hc)) {
grn_hash_cursor_get_key(ctx, hc, (void **) &idp);
- GRN_RECORD_SET(ctx, v, *idp);
- r = grn_expr_exec(ctx, expr, 0);
+ result = grn_expr_executor_exec(ctx, executor, *idp);
if (ctx->rc) {
break;
}
- score = exec_result_to_score(ctx, r, &score_buffer);
+ score = exec_result_to_score(ctx, result, &score_buffer);
if (score > 0) {
grn_hash_cursor_delete(ctx, hc, NULL);
}
@@ -4750,12 +5716,11 @@ grn_table_select_sequential(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
if ((hc = grn_hash_cursor_open(ctx, s, NULL, 0, NULL, 0, 0, -1, 0))) {
while (grn_hash_cursor_next(ctx, hc)) {
grn_hash_cursor_get_key(ctx, hc, (void **) &idp);
- GRN_RECORD_SET(ctx, v, *idp);
- r = grn_expr_exec(ctx, expr, 0);
+ result = grn_expr_executor_exec(ctx, executor, *idp);
if (ctx->rc) {
break;
}
- score = exec_result_to_score(ctx, r, &score_buffer);
+ score = exec_result_to_score(ctx, result, &score_buffer);
if (score > 0) {
grn_rset_recinfo *ri;
grn_hash_cursor_get_value(ctx, hc, (void **) &ri);
@@ -4769,6 +5734,742 @@ grn_table_select_sequential(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
break;
}
GRN_OBJ_FIN(ctx, &score_buffer);
+ grn_expr_executor_close(ctx, executor);
+}
+
+static inline void
+grn_table_select_index_report(grn_ctx *ctx, const char *tag, grn_obj *index)
+{
+ grn_report_index(ctx, "[table][select]", tag, index);
+}
+
+static inline void
+grn_table_select_index_not_used_report(grn_ctx *ctx,
+ const char *tag,
+ grn_obj *index,
+ const char *reason)
+{
+ grn_report_index_not_used(ctx, "[table][select]", tag, index, reason);
+}
+
+static inline grn_bool
+grn_table_select_index_use_sequential_search(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *res,
+ grn_operator logical_op,
+ const char *tag,
+ grn_obj *index)
+{
+ int n_records;
+ int n_filtered_records;
+ double filtered_ratio;
+ grn_obj reason;
+
+ if (logical_op != GRN_OP_AND) {
+ return GRN_FALSE;
+ }
+
+ n_records = grn_table_size(ctx, table);
+ n_filtered_records = grn_table_size(ctx, res);
+ if (n_records == 0) {
+ filtered_ratio = 1.0;
+ } else {
+ filtered_ratio = (double)n_filtered_records / (double)n_records;
+ }
+
+ if (filtered_ratio >= grn_table_select_enough_filtered_ratio) {
+ return GRN_FALSE;
+ }
+
+ if (n_filtered_records > grn_table_select_max_n_enough_filtered_records) {
+ return GRN_FALSE;
+ }
+
+ GRN_TEXT_INIT(&reason, 0);
+ grn_text_printf(ctx, &reason,
+ "enough filtered: %.2f%%(%d/%d) < %.2f%% && %d <= %d",
+ filtered_ratio * 100,
+ n_filtered_records,
+ n_records,
+ grn_table_select_enough_filtered_ratio * 100,
+ n_filtered_records,
+ grn_table_select_max_n_enough_filtered_records);
+ GRN_TEXT_PUTC(ctx, &reason, '\0');
+ grn_table_select_index_not_used_report(ctx,
+ tag,
+ index,
+ GRN_TEXT_VALUE(&reason));
+ GRN_OBJ_FIN(ctx, &reason);
+ return GRN_TRUE;
+}
+
+static inline grn_bool
+grn_table_select_index_equal(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ scan_info *si,
+ grn_obj *res)
+{
+ grn_bool processed = GRN_FALSE;
+
+ if (GRN_BULK_VSIZE(si->query) == 0) {
+ /* We can't use index for empty value. */
+ return GRN_FALSE;
+ }
+
+ if (si->flags & SCAN_ACCESSOR) {
+ if (index->header.type == GRN_ACCESSOR && !((grn_accessor *)index)->next) {
+ grn_obj dest;
+ grn_accessor *a = (grn_accessor *)index;
+ grn_posting posting;
+ posting.sid = 1;
+ posting.pos = 0;
+ posting.weight = 0;
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_ID :
+ grn_table_select_index_report(ctx, "[equal][accessor][id]", table);
+ GRN_UINT32_INIT(&dest, 0);
+ if (!grn_obj_cast(ctx, si->query, &dest, GRN_FALSE)) {
+ posting.rid = GRN_UINT32_VALUE(&dest);
+ if (posting.rid) {
+ if (posting.rid == grn_table_at(ctx, table, posting.rid)) {
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res,
+ si->logical_op);
+ }
+ }
+ processed = GRN_TRUE;
+ }
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op);
+ GRN_OBJ_FIN(ctx, &dest);
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ grn_table_select_index_report(ctx, "[equal][accessor][key]", table);
+ GRN_OBJ_INIT(&dest, GRN_BULK, 0, table->header.domain);
+ if (!grn_obj_cast(ctx, si->query, &dest, GRN_FALSE)) {
+ if ((posting.rid = grn_table_get(ctx, table,
+ GRN_BULK_HEAD(&dest),
+ GRN_BULK_VSIZE(&dest)))) {
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res,
+ si->logical_op);
+ }
+ processed = GRN_TRUE;
+ }
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op);
+ GRN_OBJ_FIN(ctx, &dest);
+ break;
+ }
+ }
+ } else {
+ const char *tag = "[equal]";
+ grn_obj *domain = grn_ctx_at(ctx, index->header.domain);
+
+ if (domain) {
+ grn_bool optimizable = GRN_FALSE;
+
+ if (domain->header.domain == GRN_DB_SHORT_TEXT) {
+ grn_obj *normalizer = NULL;
+ grn_table_get_info(ctx, domain, NULL, NULL, NULL, &normalizer, NULL);
+ if (normalizer == grn_ctx_get(ctx, "NormalizerAuto", -1)) {
+ optimizable = GRN_TRUE;
+ }
+ } else {
+ optimizable = GRN_TRUE;
+ }
+ if (optimizable &&
+ grn_table_select_index_use_sequential_search(ctx,
+ table,
+ res,
+ si->logical_op,
+ tag,
+ index)) {
+ domain = NULL;
+ }
+ }
+
+ if (domain) {
+ grn_id tid;
+
+ grn_table_select_index_report(ctx, tag, index);
+
+ if (GRN_OBJ_GET_DOMAIN(si->query) == DB_OBJ(domain)->id) {
+ tid = GRN_RECORD_VALUE(si->query);
+ } else {
+ tid = grn_table_get(ctx, domain,
+ GRN_BULK_HEAD(si->query),
+ GRN_BULK_VSIZE(si->query));
+ }
+ if (tid != GRN_ID_NIL) {
+ uint32_t sid;
+ int32_t weight;
+ grn_ii *ii = (grn_ii *)index;
+ grn_ii_cursor *ii_cursor;
+
+ sid = GRN_UINT32_VALUE_AT(&(si->wv), 0);
+ weight = GRN_INT32_VALUE_AT(&(si->wv), 1);
+ ii_cursor = grn_ii_cursor_open(ctx, ii, tid,
+ GRN_ID_NIL, GRN_ID_MAX,
+ ii->n_elements, 0);
+ if (ii_cursor) {
+ grn_posting *posting;
+ while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) {
+ grn_posting new_posting;
+
+ if (!(sid == 0 || posting->sid == sid)) {
+ continue;
+ }
+
+ if (si->position.specified) {
+ while ((posting = grn_ii_cursor_next_pos(ctx, ii_cursor))) {
+ if (posting->pos == si->position.start) {
+ break;
+ }
+ }
+ if (!posting) {
+ continue;
+ }
+ }
+
+ new_posting = *posting;
+ new_posting.weight *= weight;
+ grn_ii_posting_add(ctx, &new_posting, (grn_hash *)res,
+ si->logical_op);
+ }
+ grn_ii_cursor_close(ctx, ii_cursor);
+ }
+ }
+ processed = GRN_TRUE;
+ }
+ if (processed) {
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op);
+ }
+ }
+
+ return processed;
+}
+
+static inline grn_bool
+grn_table_select_index_not_equal(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ scan_info *si,
+ grn_obj *res)
+{
+ grn_bool processed = GRN_FALSE;
+
+ if (GRN_BULK_VSIZE(si->query) == 0) {
+ /* We can't use index for empty value. */
+ return GRN_FALSE;
+ }
+
+ if (si->logical_op != GRN_OP_AND) {
+ /* We can't use index for OR and AND_NOT. */
+ return GRN_FALSE;
+ }
+
+ if (si->flags & SCAN_ACCESSOR) {
+ if (index->header.type == GRN_ACCESSOR && !((grn_accessor *)index)->next) {
+ grn_obj dest;
+ grn_accessor *a = (grn_accessor *)index;
+ grn_id id;
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_ID :
+ grn_table_select_index_report(ctx, "[not-equal][accessor][id]", table);
+ GRN_UINT32_INIT(&dest, 0);
+ if (!grn_obj_cast(ctx, si->query, &dest, GRN_FALSE)) {
+ id = GRN_UINT32_VALUE(&dest);
+ if (id != GRN_ID_NIL) {
+ if (id == grn_table_at(ctx, table, id)) {
+ grn_hash_delete(ctx, (grn_hash *)res, &id, sizeof(grn_id), NULL);
+ }
+ }
+ processed = GRN_TRUE;
+ }
+ GRN_OBJ_FIN(ctx, &dest);
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ grn_table_select_index_report(ctx, "[not-equal][accessor][key]", table);
+ GRN_OBJ_INIT(&dest, GRN_BULK, 0, table->header.domain);
+ if (!grn_obj_cast(ctx, si->query, &dest, GRN_FALSE)) {
+ id = grn_table_get(ctx, table,
+ GRN_BULK_HEAD(&dest),
+ GRN_BULK_VSIZE(&dest));
+ if (id != GRN_ID_NIL) {
+ grn_hash_delete(ctx, (grn_hash *)res, &id, sizeof(grn_id), NULL);
+ }
+ processed = GRN_TRUE;
+ }
+ GRN_OBJ_FIN(ctx, &dest);
+ break;
+ }
+ }
+ } else {
+ grn_obj *domain = grn_ctx_at(ctx, index->header.domain);
+ if (domain) {
+ grn_id tid;
+ if (GRN_OBJ_GET_DOMAIN(si->query) == DB_OBJ(domain)->id) {
+ tid = GRN_RECORD_VALUE(si->query);
+ } else {
+ tid = grn_table_get(ctx, domain,
+ GRN_BULK_HEAD(si->query),
+ GRN_BULK_VSIZE(si->query));
+ }
+ if (tid == GRN_ID_NIL) {
+ processed = GRN_TRUE;
+ } else {
+ uint32_t sid;
+ int32_t weight;
+ grn_ii *ii = (grn_ii *)index;
+ grn_ii_cursor *ii_cursor;
+
+ grn_table_select_index_report(ctx, "[not-equal]", index);
+
+ sid = GRN_UINT32_VALUE_AT(&(si->wv), 0);
+ weight = GRN_INT32_VALUE_AT(&(si->wv), 1);
+ ii_cursor = grn_ii_cursor_open(ctx, ii, tid,
+ GRN_ID_NIL, GRN_ID_MAX,
+ ii->n_elements, 0);
+ if (ii_cursor) {
+ grn_posting *posting;
+ while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) {
+ if (!(sid == 0 || posting->sid == sid)) {
+ continue;
+ }
+
+ if (si->position.specified) {
+ while ((posting = grn_ii_cursor_next_pos(ctx, ii_cursor))) {
+ if (posting->pos == si->position.start) {
+ break;
+ }
+ }
+ if (!posting) {
+ continue;
+ }
+ }
+
+ grn_hash_delete(ctx, (grn_hash *)res,
+ &(posting->rid), sizeof(grn_id),
+ NULL);
+ }
+ grn_ii_cursor_close(ctx, ii_cursor);
+ processed = GRN_TRUE;
+ }
+ }
+ }
+ }
+
+ return processed;
+}
+
+static grn_bool
+grn_table_select_index_prefix(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ scan_info *si,
+ grn_obj *res)
+{
+ grn_bool processed = GRN_FALSE;
+ if (si->flags & SCAN_ACCESSOR) {
+ if (index->header.type == GRN_ACCESSOR &&
+ !((grn_accessor *)index)->next) {
+ grn_obj dest;
+ grn_accessor *a = (grn_accessor *)index;
+ grn_posting posting;
+ posting.sid = 1;
+ posting.pos = 0;
+ posting.weight = 0;
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_ID :
+ /* todo */
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ if (si->op == GRN_OP_SUFFIX) {
+ grn_table_select_index_report(ctx,
+ "[suffix][accessor][key]", table);
+ } else {
+ grn_table_select_index_report(ctx,
+ "[prefix][accessor][key]", table);
+ }
+ GRN_OBJ_INIT(&dest, GRN_BULK, 0, table->header.domain);
+ if (!grn_obj_cast(ctx, si->query, &dest, GRN_FALSE)) {
+ grn_hash *pres;
+ if ((pres = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY))) {
+ grn_id *key;
+ grn_table_search(ctx, table,
+ GRN_BULK_HEAD(&dest), GRN_BULK_VSIZE(&dest),
+ si->op, (grn_obj *)pres, GRN_OP_OR);
+ GRN_HASH_EACH(ctx, pres, id, &key, NULL, NULL, {
+ posting.rid = *key;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res,
+ si->logical_op);
+ });
+ grn_hash_close(ctx, pres);
+ }
+ processed = GRN_TRUE;
+ }
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op);
+ GRN_OBJ_FIN(ctx, &dest);
+ }
+ }
+ } else {
+ grn_obj **indexes = &GRN_PTR_VALUE(&si->index);
+ int i, n_indexes = GRN_BULK_VSIZE(&si->index)/sizeof(grn_obj *);
+ for (i = 0; i < n_indexes; i++) {
+ grn_obj *index = indexes[i];
+ grn_obj *lexicon = grn_ctx_at(ctx, index->header.domain);
+ if (lexicon) {
+ grn_hash *keys;
+ if ((keys = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY))) {
+ grn_id *key;
+ if (si->op == GRN_OP_SUFFIX) {
+ grn_table_select_index_report(ctx, "[suffix]", index);
+ } else {
+ grn_table_select_index_report(ctx, "[prefix]", index);
+ }
+ grn_table_search(ctx, lexicon,
+ GRN_BULK_HEAD(si->query),
+ GRN_BULK_VSIZE(si->query),
+ si->op, (grn_obj *)keys, GRN_OP_OR);
+ grn_obj_unlink(ctx, lexicon);
+ GRN_HASH_EACH(ctx, keys, id, &key, NULL, NULL, {
+ grn_ii_at(ctx, (grn_ii *)index, *key, (grn_hash *)res, si->logical_op);
+ });
+ grn_hash_close(ctx, keys);
+ }
+ grn_obj_unlink(ctx, lexicon);
+ }
+ }
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op);
+ processed = GRN_TRUE;
+ }
+ return processed;
+}
+
+static grn_bool
+grn_table_select_index_suffix(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ scan_info *si,
+ grn_obj *res)
+{
+ grn_obj *domain;
+ if (si->flags & SCAN_ACCESSOR) {
+ domain = table;
+ } else {
+ domain = grn_ctx_at(ctx, index->header.domain);
+ }
+ if (domain->header.type != GRN_TABLE_PAT_KEY) {
+ return GRN_FALSE;
+ }
+ if (!(domain->header.flags & GRN_OBJ_KEY_WITH_SIS)) {
+ return GRN_FALSE;
+ }
+ return grn_table_select_index_prefix(ctx, table, index, si, res);
+}
+
+static inline grn_bool
+grn_table_select_index_match(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ scan_info *si,
+ grn_obj *res,
+ grn_id *min_id)
+{
+ grn_obj wv, **ip = &GRN_PTR_VALUE(&si->index);
+ int j;
+ int n_indexes = GRN_BULK_VSIZE(&si->index)/sizeof(grn_obj *);
+ int32_t *wp = &GRN_INT32_VALUE(&si->wv);
+ grn_search_optarg optarg;
+ grn_bool minimum_min_id_is_set = GRN_FALSE;
+ grn_id minimum_min_id = GRN_ID_NIL;
+ unsigned int previous_n_hits = grn_table_size(ctx, res);
+
+ GRN_INT32_INIT(&wv, GRN_OBJ_VECTOR);
+ if (si->op == GRN_OP_MATCH) {
+ optarg.mode = GRN_OP_EXACT;
+ } else {
+ optarg.mode = si->op;
+ }
+ optarg.max_interval = 0;
+ optarg.similarity_threshold = 0;
+ switch (si->op) {
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ optarg.max_interval = si->max_interval;
+ break;
+ case GRN_OP_SIMILAR :
+ optarg.similarity_threshold = si->similarity_threshold;
+ break;
+ default :
+ break;
+ }
+ optarg.weight_vector = (int *)GRN_BULK_HEAD(&wv);
+ /* optarg.vector_size = GRN_BULK_VSIZE(&si->wv); */
+ optarg.vector_size = 1;
+ optarg.proc = NULL;
+ optarg.max_size = 0;
+ optarg.match_info.flags |= GRN_MATCH_INFO_GET_MIN_RECORD_ID;
+ ctx->flags |= GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND;
+ for (j = 0; j < n_indexes; j++, ip++, wp += 2) {
+ uint32_t sid = (uint32_t) wp[0];
+ int32_t weight = wp[1];
+ if (grn_table_select_and_min_skip_enable) {
+ optarg.match_info.min = *min_id;
+ } else {
+ optarg.match_info.min = GRN_ID_NIL;
+ }
+ if (sid) {
+ int weight_index = sid - 1;
+ int current_vector_size;
+ current_vector_size = GRN_BULK_VSIZE(&wv)/sizeof(int32_t);
+ if (weight_index < current_vector_size) {
+ ((int *)GRN_BULK_HEAD(&wv))[weight_index] = weight;
+ } else {
+ GRN_INT32_SET_AT(ctx, &wv, weight_index, weight);
+ }
+ optarg.weight_vector = &GRN_INT32_VALUE(&wv);
+ optarg.vector_size = GRN_BULK_VSIZE(&wv)/sizeof(int32_t);
+ } else {
+ optarg.weight_vector = NULL;
+ optarg.vector_size = weight;
+ }
+ optarg.scorer = GRN_PTR_VALUE_AT(&(si->scorers), j);
+ optarg.scorer_args_expr =
+ GRN_PTR_VALUE_AT(&(si->scorer_args_exprs), j);
+ optarg.scorer_args_expr_offset =
+ GRN_UINT32_VALUE_AT(&(si->scorer_args_expr_offsets), j);
+ if (j < n_indexes - 1) {
+ if (sid && ip[0] == ip[1]) { continue; }
+ } else {
+ ctx->flags &= ~GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND;
+ }
+ grn_obj_search(ctx, ip[0], si->query, res, si->logical_op, &optarg);
+ if (optarg.weight_vector) {
+ int i;
+ for (i = 0; i < optarg.vector_size; i++) {
+ optarg.weight_vector[i] = 0;
+ }
+ }
+ GRN_BULK_REWIND(&wv);
+ if (!minimum_min_id_is_set ||
+ optarg.match_info.min < minimum_min_id) {
+ minimum_min_id_is_set = GRN_TRUE;
+ minimum_min_id = optarg.match_info.min;
+ }
+ }
+ if ((si->logical_op == GRN_OP_AND) ||
+ (si->logical_op == GRN_OP_OR && previous_n_hits == 0)) {
+ *min_id = minimum_min_id;
+ } else {
+ *min_id = GRN_ID_NIL;
+ }
+ GRN_OBJ_FIN(ctx, &wv);
+
+ return GRN_TRUE;
+}
+
+static inline grn_bool
+grn_table_select_index_call_selector(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ scan_info *si,
+ grn_obj *selector,
+ grn_obj *res)
+{
+ grn_bool processed = GRN_FALSE;
+ grn_proc *proc = (grn_proc *)selector;
+ grn_rc rc;
+
+ if (grn_logger_pass(ctx, GRN_REPORT_INDEX_LOG_LEVEL)) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ char tag[GRN_TABLE_MAX_KEY_SIZE];
+ name_size = grn_obj_name(ctx,
+ (grn_obj *)selector,
+ name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ grn_snprintf(tag, GRN_TABLE_MAX_KEY_SIZE, GRN_TABLE_MAX_KEY_SIZE,
+ "[selector][%.*s]",
+ name_size, name);
+ grn_table_select_index_report(ctx, tag, index);
+ }
+
+ if (index && index->header.type == GRN_ACCESSOR) {
+ grn_operator selector_op;
+ grn_obj *accessor = index;
+ grn_accessor *a = (grn_accessor *)accessor;
+
+ selector_op = grn_proc_get_selector_operator(ctx, selector);
+ if (a->next) {
+ unsigned int accessor_deep = 0;
+ grn_obj *base_table = NULL;
+ grn_obj *base_index = NULL;
+ grn_obj *base_res = NULL;
+
+ for (; a; a = a->next) {
+ if (a->next) {
+ accessor_deep++;
+ } else {
+ grn_index_datum index_data;
+ unsigned int n_index_datum;
+
+ if (grn_obj_is_table(ctx, a->obj)) {
+ base_table = a->obj;
+ } else {
+ base_table = grn_ctx_at(ctx, a->obj->header.domain);
+ }
+ n_index_datum = grn_column_find_index_data(ctx,
+ a->obj,
+ selector_op,
+ &index_data,
+ 1);
+ if (n_index_datum > 0) {
+ base_index = index_data.index;
+ }
+ base_res = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ base_table, NULL);
+ }
+ }
+ rc = proc->callbacks.function.selector(ctx,
+ base_table,
+ base_index,
+ si->nargs,
+ si->args,
+ base_res,
+ GRN_OP_OR);
+ if (rc == GRN_SUCCESS) {
+ grn_accessor_resolve(ctx,
+ accessor,
+ accessor_deep,
+ base_res,
+ res,
+ si->logical_op);
+ }
+ grn_obj_close(ctx, base_res);
+ } else {
+ grn_index_datum index_data;
+ unsigned int n_index_datum;
+ grn_obj *target_index = NULL;
+
+ n_index_datum = grn_column_find_index_data(ctx,
+ a->obj,
+ selector_op,
+ &index_data,
+ 1);
+ if (n_index_datum > 0) {
+ target_index = index_data.index;
+ }
+ rc = proc->callbacks.function.selector(ctx,
+ table,
+ target_index,
+ si->nargs,
+ si->args,
+ res,
+ si->logical_op);
+ }
+ } else {
+ rc = proc->callbacks.function.selector(ctx,
+ table,
+ index,
+ si->nargs,
+ si->args,
+ res,
+ si->logical_op);
+ }
+
+ if (rc) {
+ /* TODO: report error */
+ } else {
+ processed = GRN_TRUE;
+ }
+
+ return processed;
+}
+
+static inline grn_bool
+grn_table_select_index_range_key(grn_ctx *ctx,
+ grn_obj *table,
+ scan_info *si,
+ grn_operator logical_op,
+ grn_obj *res)
+{
+ const char *tag = "[range][key]";
+ grn_bool processed = GRN_FALSE;
+ grn_obj key;
+
+ if (grn_table_select_index_use_sequential_search(ctx,
+ table,
+ res,
+ logical_op,
+ tag,
+ table)) {
+ return GRN_FALSE;
+ }
+
+ GRN_OBJ_INIT(&key, GRN_BULK, 0, table->header.domain);
+ if (grn_obj_cast(ctx, si->query, &key, GRN_FALSE) == GRN_SUCCESS) {
+ grn_table_cursor *cursor;
+ const void *min = NULL, *max = NULL;
+ unsigned int min_size = 0, max_size = 0;
+ int offset = 0;
+ int limit = -1;
+ int flags = GRN_CURSOR_ASCENDING;
+
+ grn_table_select_index_report(ctx, tag, table);
+
+ switch (si->op) {
+ case GRN_OP_LESS :
+ flags |= GRN_CURSOR_LT;
+ max = GRN_BULK_HEAD(&key);
+ max_size = GRN_BULK_VSIZE(&key);
+ break;
+ case GRN_OP_GREATER :
+ flags |= GRN_CURSOR_GT;
+ min = GRN_BULK_HEAD(&key);
+ min_size = GRN_BULK_VSIZE(&key);
+ break;
+ case GRN_OP_LESS_EQUAL :
+ flags |= GRN_CURSOR_LE;
+ max = GRN_BULK_HEAD(&key);
+ max_size = GRN_BULK_VSIZE(&key);
+ break;
+ case GRN_OP_GREATER_EQUAL :
+ flags |= GRN_CURSOR_GE;
+ min = GRN_BULK_HEAD(&key);
+ min_size = GRN_BULK_VSIZE(&key);
+ break;
+ default :
+ break;
+ }
+ cursor = grn_table_cursor_open(ctx, table,
+ min, min_size, max, max_size,
+ offset, limit, flags);
+ if (cursor) {
+ uint32_t sid;
+ int32_t weight;
+
+ sid = GRN_UINT32_VALUE_AT(&(si->wv), 0);
+ weight = GRN_INT32_VALUE_AT(&(si->wv), 1);
+
+ if (sid == 0) {
+ grn_posting posting = {0};
+
+ posting.weight = weight - 1;
+ while ((posting.rid = grn_table_cursor_next(ctx, cursor))) {
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res, logical_op);
+ }
+ }
+ processed = GRN_TRUE;
+ grn_table_cursor_close(ctx, cursor);
+ }
+
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, logical_op);
+ }
+ GRN_OBJ_FIN(ctx, &key);
+
+ return processed;
}
static inline grn_bool
@@ -4777,6 +6478,7 @@ grn_table_select_index_range_column(grn_ctx *ctx, grn_obj *table,
scan_info *si, grn_operator logical_op,
grn_obj *res)
{
+ const char *tag = "[range]";
grn_bool processed = GRN_FALSE;
grn_obj *index_table;
grn_obj range;
@@ -4786,6 +6488,16 @@ grn_table_select_index_range_column(grn_ctx *ctx, grn_obj *table,
return GRN_FALSE;
}
+ if (grn_table_select_index_use_sequential_search(ctx,
+ table,
+ res,
+ logical_op,
+ tag,
+ index_table)) {
+ grn_obj_unlink(ctx, index_table);
+ return GRN_FALSE;
+ }
+
GRN_OBJ_INIT(&range, GRN_BULK, 0, index_table->header.domain);
if (grn_obj_cast(ctx, si->query, &range, GRN_FALSE) == GRN_SUCCESS) {
grn_table_cursor *cursor;
@@ -4795,6 +6507,8 @@ grn_table_select_index_range_column(grn_ctx *ctx, grn_obj *table,
int limit = -1;
int flags = GRN_CURSOR_ASCENDING;
+ grn_table_select_index_report(ctx, "[range]", index);
+
switch (si->op) {
case GRN_OP_LESS :
flags |= GRN_CURSOR_LT;
@@ -4823,28 +6537,47 @@ grn_table_select_index_range_column(grn_ctx *ctx, grn_obj *table,
min, min_size, max, max_size,
offset, limit, flags);
if (cursor) {
+ grn_id tid;
uint32_t sid;
int32_t weight;
- grn_obj *index_cursor;
+ grn_ii *ii = (grn_ii *)index;
sid = GRN_UINT32_VALUE_AT(&(si->wv), 0);
weight = GRN_INT32_VALUE_AT(&(si->wv), 1);
- index_cursor = grn_index_cursor_open(ctx, cursor, index,
- GRN_ID_NIL, GRN_ID_MAX, 0);
- if (index_cursor) {
- grn_posting *posting;
- while ((posting = grn_index_cursor_next(ctx, index_cursor, NULL))) {
- if (sid == 0 || posting->sid == sid) {
- grn_ii_posting ii_posting;
- ii_posting.rid = posting->rid;
- ii_posting.sid = posting->sid;
- ii_posting.weight = posting->weight * weight;
- grn_ii_posting_add(ctx, &ii_posting, (grn_hash *)res, logical_op);
+ while ((tid = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ grn_ii_cursor *ii_cursor;
+
+ ii_cursor = grn_ii_cursor_open(ctx, ii, tid,
+ GRN_ID_NIL, GRN_ID_MAX,
+ ii->n_elements, 0);
+ if (ii_cursor) {
+ grn_posting *posting;
+ while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) {
+ grn_posting new_posting;
+
+ if (!(sid == 0 || posting->sid == sid)) {
+ continue;
+ }
+
+ if (si->position.specified) {
+ while ((posting = grn_ii_cursor_next_pos(ctx, ii_cursor))) {
+ if (posting->pos == si->position.start) {
+ break;
+ }
+ }
+ if (!posting) {
+ continue;
+ }
+ }
+
+ new_posting = *posting;
+ new_posting.weight *= weight;
+ grn_ii_posting_add(ctx, &new_posting, (grn_hash *)res, logical_op);
}
}
- processed = GRN_TRUE;
- grn_obj_unlink(ctx, index_cursor);
+ grn_ii_cursor_close(ctx, ii_cursor);
}
+ processed = GRN_TRUE;
grn_table_cursor_close(ctx, cursor);
}
@@ -4858,157 +6591,84 @@ grn_table_select_index_range_column(grn_ctx *ctx, grn_obj *table,
}
static inline grn_bool
-grn_table_select_index_range_accessor(grn_ctx *ctx, grn_obj *table,
- grn_obj *accessor_stack,
- scan_info *si, grn_obj *res)
+grn_table_select_index_range_accessor(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *accessor,
+ scan_info *si,
+ grn_operator op,
+ grn_obj *res)
{
+ grn_rc rc;
+ grn_accessor *a;
+ grn_obj *last_obj = NULL;
int n_accessors;
- grn_obj *current_res = NULL;
-
- n_accessors = GRN_BULK_VSIZE(accessor_stack) / sizeof(grn_obj *);
-
- {
- grn_accessor *last_accessor;
- grn_obj *target;
- grn_obj *index;
- grn_obj *range;
+ grn_bool have_resolver = GRN_FALSE;
+ grn_obj *base_res = NULL;
- last_accessor = (grn_accessor *)GRN_PTR_VALUE_AT(accessor_stack,
- n_accessors - 1);
- target = last_accessor->obj;
- if (grn_column_index(ctx, target, si->op, &index, 1, NULL) == 0) {
- return GRN_FALSE;
+ for (a = (grn_accessor *)accessor; a; a = a->next) {
+ if (!a->next) {
+ last_obj = a->obj;
}
-
- range = grn_ctx_at(ctx, DB_OBJ(index)->range);
- current_res = grn_table_create(ctx, NULL, 0, NULL,
- GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
- range,
- NULL);
- grn_obj_unlink(ctx, range);
- if (!current_res) {
- return GRN_FALSE;
- }
- if (!grn_table_select_index_range_column(ctx, table, index, si, GRN_OP_OR,
- current_res)) {
- grn_obj_unlink(ctx, current_res);
- return GRN_FALSE;
+ }
+ n_accessors = 0;
+ for (a = (grn_accessor *)accessor; a; a = a->next) {
+ n_accessors++;
+ if (GRN_OBJ_INDEX_COLUMNP(a->obj) ||
+ grn_obj_is_table(ctx, a->obj)) {
+ have_resolver = GRN_TRUE;
+ break;
}
}
{
- int i;
- grn_obj weight_vector;
- grn_search_optarg optarg;
+ grn_obj *index;
+ grn_obj *range;
- GRN_INT32_INIT(&weight_vector, GRN_OBJ_VECTOR);
- memset(&optarg, 0, sizeof(grn_search_optarg));
- if (si->op == GRN_OP_MATCH) {
- optarg.mode = GRN_OP_EXACT;
- } else {
- optarg.mode = si->op;
- }
- for (i = n_accessors - 1; i > 0; i--) {
- grn_rc rc = GRN_SUCCESS;
- grn_accessor *accessor;
- grn_obj *index;
- int section;
- grn_obj *domain;
- grn_obj *target;
- grn_obj *next_res;
- grn_operator next_op;
- grn_id *next_record_id = NULL;
-
- accessor = (grn_accessor *)GRN_PTR_VALUE_AT(accessor_stack, i - 1);
- target = accessor->obj;
- {
- grn_index_datum index_datum;
- unsigned int n_index_data;
- n_index_data = grn_column_find_index_data(ctx, target, GRN_OP_EQUAL,
- &index_datum, 1);
- if (n_index_data == 0) {
- grn_obj_unlink(ctx, current_res);
- current_res = NULL;
- break;
- }
- index = index_datum.index;
- section = index_datum.section;
+ if (grn_obj_is_table(ctx, last_obj)) {
+ index = last_obj;
+ range = last_obj;
+ base_res = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ range,
+ NULL);
+ if (!base_res) {
+ return GRN_FALSE;
}
-
- if (section > 0) {
- int j;
- int weight_position = section - 1;
-
- GRN_BULK_REWIND(&weight_vector);
- GRN_INT32_SET_AT(ctx, &weight_vector, weight_position, 1);
- optarg.weight_vector = &(GRN_INT32_VALUE(&weight_vector));
- optarg.vector_size = GRN_BULK_VSIZE(&weight_vector) / sizeof(int32_t);
- for (j = 0; j < weight_position - 1; j++) {
- optarg.weight_vector[j] = 0;
- }
- } else {
- optarg.weight_vector = NULL;
- optarg.vector_size = 1;
+ if (!grn_table_select_index_range_key(ctx, last_obj, si, GRN_OP_OR,
+ base_res)) {
+ grn_obj_unlink(ctx, base_res);
+ return GRN_FALSE;
}
-
- {
- grn_obj *range;
- range = grn_ctx_at(ctx, DB_OBJ(index)->range);
- next_res = grn_table_create(ctx, NULL, 0, NULL,
- GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
- range,
- NULL);
- grn_obj_unlink(ctx, range);
- if (!next_res) {
- grn_obj_unlink(ctx, current_res);
- current_res = NULL;
- break;
- }
- next_op = GRN_OP_OR;
+ } else {
+ if (grn_column_index(ctx, last_obj, si->op, &index, 1, NULL) == 0) {
+ return GRN_FALSE;
}
- domain = grn_ctx_at(ctx, index->header.domain);
- GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &next_record_id,
- NULL, NULL, {
- if (domain->header.type == GRN_TABLE_NO_KEY) {
- rc = grn_ii_sel(ctx, (grn_ii *)index,
- (const char *)next_record_id, sizeof(grn_id),
- (grn_hash *)next_res, next_op, &optarg);
- } else {
- char key[GRN_TABLE_MAX_KEY_SIZE];
- int key_len;
- key_len = grn_table_get_key(ctx, domain, *next_record_id,
- key, GRN_TABLE_MAX_KEY_SIZE);
- rc = grn_ii_sel(ctx, (grn_ii *)index, key, key_len,
- (grn_hash *)next_res, next_op, &optarg);
- }
- if (rc != GRN_SUCCESS) {
- break;
- }
- });
- grn_obj_unlink(ctx, domain);
- grn_obj_unlink(ctx, current_res);
-
- if (rc == GRN_SUCCESS) {
- if (i == 1) {
- grn_table_setoperation(ctx, res, next_res, res, si->logical_op);
- grn_obj_unlink(ctx, next_res);
- current_res = res;
- } else {
- current_res = next_res;
- }
- } else {
- if (res != next_res) {
- grn_obj_unlink(ctx, next_res);
- }
- current_res = NULL;
- break;
+ range = grn_ctx_at(ctx, DB_OBJ(index)->range);
+ base_res = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ range,
+ NULL);
+ if (!base_res) {
+ return GRN_FALSE;
+ }
+ if (!grn_table_select_index_range_column(ctx, table, index, si, GRN_OP_OR,
+ base_res)) {
+ grn_obj_unlink(ctx, base_res);
+ return GRN_FALSE;
}
}
- GRN_OBJ_FIN(ctx, &weight_vector);
+ grn_table_select_index_report(ctx, "[range][accessor]", index);
+ }
+
+ if (n_accessors == 1 && have_resolver) {
+ rc = grn_accessor_resolve(ctx, accessor, 1, base_res, res, op);
+ } else {
+ rc = grn_accessor_resolve(ctx, accessor, n_accessors - 1, base_res, res, op);
}
+ grn_obj_unlink(ctx, base_res);
- return current_res == res;
+ return rc == GRN_SUCCESS;
}
static inline grn_bool
@@ -5016,24 +6676,18 @@ grn_table_select_index_range(grn_ctx *ctx, grn_obj *table, grn_obj *index,
scan_info *si, grn_obj *res)
{
if (si->flags & SCAN_ACCESSOR) {
- grn_bool processed;
- grn_accessor *accessor = (grn_accessor *)index;
- grn_accessor *a;
- grn_obj accessor_stack;
-
- if (index->header.type != GRN_ACCESSOR) {
+ switch (index->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ /* table == index */
+ return grn_table_select_index_range_key(ctx, table, si,
+ si->logical_op, res);
+ case GRN_ACCESSOR :
+ return grn_table_select_index_range_accessor(ctx, table, index, si,
+ si->logical_op, res);
+ default :
return GRN_FALSE;
}
-
- GRN_PTR_INIT(&accessor_stack, GRN_OBJ_VECTOR, GRN_ID_NIL);
- for (a = accessor; a; a = a->next) {
- GRN_PTR_PUT(ctx, &accessor_stack, a);
- }
- processed = grn_table_select_index_range_accessor(ctx, table,
- &accessor_stack,
- si, res);
- GRN_OBJ_FIN(ctx, &accessor_stack);
- return processed;
} else {
return grn_table_select_index_range_column(ctx, table, index, si,
si->logical_op, res);
@@ -5042,232 +6696,40 @@ grn_table_select_index_range(grn_ctx *ctx, grn_obj *table, grn_obj *index,
static inline grn_bool
grn_table_select_index(grn_ctx *ctx, grn_obj *table, scan_info *si,
- grn_obj *res)
+ grn_obj *res, grn_id *min_id)
{
grn_bool processed = GRN_FALSE;
+ if (!si->query) {
+ if (si->op != GRN_OP_CALL || !grn_obj_is_selector_proc(ctx, si->args[0])) {
+ return processed;
+ }
+ }
if (GRN_BULK_VSIZE(&si->index)) {
grn_obj *index = GRN_PTR_VALUE(&si->index);
switch (si->op) {
case GRN_OP_EQUAL :
- if (GRN_BULK_VSIZE(si->query) == 0) {
- /* We can't use index for empty value. */
- return GRN_FALSE;
- }
- if (si->flags & SCAN_ACCESSOR) {
- if (index->header.type == GRN_ACCESSOR &&
- !((grn_accessor *)index)->next) {
- grn_obj dest;
- grn_accessor *a = (grn_accessor *)index;
- grn_ii_posting posting;
- posting.sid = 1;
- posting.pos = 0;
- posting.weight = 0;
- switch (a->action) {
- case GRN_ACCESSOR_GET_ID :
- GRN_UINT32_INIT(&dest, 0);
- if (!grn_obj_cast(ctx, si->query, &dest, GRN_FALSE)) {
- posting.rid = GRN_UINT32_VALUE(&dest);
- if (posting.rid) {
- if (posting.rid == grn_table_at(ctx, table, posting.rid)) {
- grn_ii_posting_add(ctx, &posting, (grn_hash *)res,
- si->logical_op);
- }
- }
- processed = GRN_TRUE;
- }
- grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op);
- GRN_OBJ_FIN(ctx, &dest);
- break;
- case GRN_ACCESSOR_GET_KEY :
- GRN_OBJ_INIT(&dest, GRN_BULK, 0, table->header.domain);
- if (!grn_obj_cast(ctx, si->query, &dest, GRN_FALSE)) {
- if ((posting.rid = grn_table_get(ctx, table,
- GRN_BULK_HEAD(&dest),
- GRN_BULK_VSIZE(&dest)))) {
- grn_ii_posting_add(ctx, &posting, (grn_hash *)res,
- si->logical_op);
- }
- processed = GRN_TRUE;
- }
- grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op);
- GRN_OBJ_FIN(ctx, &dest);
- break;
- }
- }
- } else {
- grn_obj *domain = grn_ctx_at(ctx, index->header.domain);
- if (domain) {
- grn_id tid;
- if (GRN_OBJ_GET_DOMAIN(si->query) == DB_OBJ(domain)->id) {
- tid = GRN_RECORD_VALUE(si->query);
- } else {
- tid = grn_table_get(ctx, domain,
- GRN_BULK_HEAD(si->query),
- GRN_BULK_VSIZE(si->query));
- }
- if (tid != GRN_ID_NIL) {
- grn_ii_at(ctx, (grn_ii *)index, tid, (grn_hash *)res,
- si->logical_op);
- }
- }
- grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op);
- processed = GRN_TRUE;
- }
+ processed = grn_table_select_index_equal(ctx, table, index, si, res);
+ break;
+ case GRN_OP_NOT_EQUAL :
+ processed = grn_table_select_index_not_equal(ctx, table, index, si, res);
break;
- case GRN_OP_SUFFIX :
- {
- grn_obj *domain;
- if (si->flags & SCAN_ACCESSOR) {
- domain = table;
- } else {
- domain = grn_ctx_at(ctx, index->header.domain);
- }
- if (domain->header.type != GRN_TABLE_PAT_KEY) {
- break;
- }
- if (!(domain->header.flags & GRN_OBJ_KEY_WITH_SIS)) {
- break;
- }
- }
- /* fallthru */
case GRN_OP_PREFIX :
- if (si->flags & SCAN_ACCESSOR) {
- if (index->header.type == GRN_ACCESSOR &&
- !((grn_accessor *)index)->next) {
- grn_obj dest;
- grn_accessor *a = (grn_accessor *)index;
- grn_ii_posting posting;
- posting.sid = 1;
- posting.pos = 0;
- posting.weight = 0;
- switch (a->action) {
- case GRN_ACCESSOR_GET_ID :
- /* todo */
- break;
- case GRN_ACCESSOR_GET_KEY :
- GRN_OBJ_INIT(&dest, GRN_BULK, 0, table->header.domain);
- if (!grn_obj_cast(ctx, si->query, &dest, GRN_FALSE)) {
- grn_hash *pres;
- if ((pres = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
- GRN_OBJ_TABLE_HASH_KEY))) {
- grn_id *key;
- grn_table_search(ctx, table,
- GRN_BULK_HEAD(&dest), GRN_BULK_VSIZE(&dest),
- si->op, (grn_obj *)pres, GRN_OP_OR);
- GRN_HASH_EACH(ctx, pres, id, &key, NULL, NULL, {
- posting.rid = *key;
- grn_ii_posting_add(ctx, &posting, (grn_hash *)res,
- si->logical_op);
- });
- grn_hash_close(ctx, pres);
- }
- processed = GRN_TRUE;
- }
- grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op);
- GRN_OBJ_FIN(ctx, &dest);
- break;
- }
- }
- } else {
- grn_obj *i = GRN_PTR_VALUE(&si->index);
- grn_obj *domain = grn_ctx_at(ctx, i->header.domain);
- if (domain) {
- grn_hash *pres;
- if ((pres = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
- GRN_OBJ_TABLE_HASH_KEY))) {
- grn_id *key;
- grn_table_search(ctx, domain,
- GRN_BULK_HEAD(si->query),
- GRN_BULK_VSIZE(si->query),
- si->op, (grn_obj *)pres, GRN_OP_OR);
- grn_obj_unlink(ctx, domain);
- GRN_HASH_EACH(ctx, pres, id, &key, NULL, NULL, {
- grn_ii_at(ctx, (grn_ii *)index, *key, (grn_hash *)res, si->logical_op);
- });
- grn_hash_close(ctx, pres);
- }
- grn_obj_unlink(ctx, domain);
- }
- grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op);
- processed = GRN_TRUE;
- }
+ processed = grn_table_select_index_prefix(ctx, table, index, si, res);
+ break;
+ case GRN_OP_SUFFIX :
+ processed = grn_table_select_index_suffix(ctx, table, index, si, res);
break;
case GRN_OP_MATCH :
case GRN_OP_NEAR :
case GRN_OP_NEAR2 :
case GRN_OP_SIMILAR :
case GRN_OP_REGEXP :
- {
- grn_obj wv, **ip = &GRN_PTR_VALUE(&si->index);
- int j;
- int n_indexes = GRN_BULK_VSIZE(&si->index)/sizeof(grn_obj *);
- int32_t *wp = &GRN_INT32_VALUE(&si->wv);
- grn_search_optarg optarg;
- GRN_INT32_INIT(&wv, GRN_OBJ_VECTOR);
- if (si->op == GRN_OP_MATCH) {
- optarg.mode = GRN_OP_EXACT;
- } else {
- optarg.mode = si->op;
- }
- optarg.max_interval = 0;
- optarg.similarity_threshold = 0;
- switch (si->op) {
- case GRN_OP_NEAR :
- case GRN_OP_NEAR2 :
- optarg.max_interval = si->max_interval;
- break;
- case GRN_OP_SIMILAR :
- optarg.similarity_threshold = si->similarity_threshold;
- break;
- default :
- break;
- }
- optarg.weight_vector = (int *)GRN_BULK_HEAD(&wv);
- /* optarg.vector_size = GRN_BULK_VSIZE(&si->wv); */
- optarg.vector_size = 1;
- optarg.proc = NULL;
- optarg.max_size = 0;
- ctx->flags |= GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND;
- for (j = 0; j < n_indexes; j++, ip++, wp += 2) {
- uint32_t sid = (uint32_t) wp[0];
- int32_t weight = wp[1];
- if (sid) {
- int weight_index = sid - 1;
- int current_vector_size;
- current_vector_size = GRN_BULK_VSIZE(&wv)/sizeof(int32_t);
- if (weight_index < current_vector_size) {
- ((int *)GRN_BULK_HEAD(&wv))[weight_index] = weight;
- } else {
- GRN_INT32_SET_AT(ctx, &wv, weight_index, weight);
- }
- optarg.weight_vector = &GRN_INT32_VALUE(&wv);
- optarg.vector_size = GRN_BULK_VSIZE(&wv)/sizeof(int32_t);
- } else {
- optarg.weight_vector = NULL;
- optarg.vector_size = weight;
- }
- optarg.scorer = GRN_PTR_VALUE_AT(&(si->scorers), j);
- optarg.scorer_args_expr =
- GRN_PTR_VALUE_AT(&(si->scorer_args_exprs), j);
- optarg.scorer_args_expr_offset =
- GRN_UINT32_VALUE_AT(&(si->scorer_args_expr_offsets), j);
- if (j < n_indexes - 1) {
- if (sid && ip[0] == ip[1]) { continue; }
- } else {
- ctx->flags &= ~GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND;
- }
- grn_obj_search(ctx, ip[0], si->query, res, si->logical_op, &optarg);
- if (optarg.weight_vector) {
- int i;
- for (i = 0; i < optarg.vector_size; i++) {
- optarg.weight_vector[i] = 0;
- }
- }
- GRN_BULK_REWIND(&wv);
- }
- GRN_OBJ_FIN(ctx, &wv);
- }
- processed = GRN_TRUE;
+ processed = grn_table_select_index_match(ctx,
+ table,
+ index,
+ si,
+ res,
+ min_id);
break;
case GRN_OP_TERM_EXTRACT :
if (si->flags & SCAN_ACCESSOR) {
@@ -5276,6 +6738,8 @@ grn_table_select_index(grn_ctx *ctx, grn_obj *table, scan_info *si,
grn_accessor *a = (grn_accessor *)index;
switch (a->action) {
case GRN_ACCESSOR_GET_KEY :
+ grn_table_select_index_report(ctx, "[term-extract][accessor][key]",
+ table);
grn_table_search(ctx, table,
GRN_TEXT_VALUE(si->query), GRN_TEXT_LEN(si->query),
GRN_OP_TERM_EXTRACT, res, si->logical_op);
@@ -5287,15 +6751,12 @@ grn_table_select_index(grn_ctx *ctx, grn_obj *table, scan_info *si,
break;
case GRN_OP_CALL :
if (grn_obj_is_selector_proc(ctx, si->args[0])) {
- grn_rc rc;
- grn_proc *proc = (grn_proc *)(si->args[0]);
- rc = proc->selector(ctx, table, index, si->nargs, si->args,
- res, si->logical_op);
- if (rc) {
- /* TODO: report error */
- } else {
- processed = GRN_TRUE;
- }
+ processed = grn_table_select_index_call_selector(ctx,
+ table,
+ index,
+ si,
+ si->args[0],
+ res);
}
break;
case GRN_OP_LESS :
@@ -5315,10 +6776,30 @@ grn_table_select_index(grn_ctx *ctx, grn_obj *table, scan_info *si,
if (grn_obj_is_selector_proc(ctx, si->args[0])) {
grn_rc rc;
grn_proc *proc = (grn_proc *)(si->args[0]);
- rc = proc->selector(ctx, table, NULL, si->nargs, si->args,
- res, si->logical_op);
+ if (grn_logger_pass(ctx, GRN_REPORT_INDEX_LOG_LEVEL)) {
+ char proc_name[GRN_TABLE_MAX_KEY_SIZE];
+ int proc_name_size;
+ char tag[GRN_TABLE_MAX_KEY_SIZE];
+ proc_name_size = grn_obj_name(ctx, (grn_obj *)proc,
+ proc_name, GRN_TABLE_MAX_KEY_SIZE);
+ proc_name[proc_name_size] = '\0';
+ grn_snprintf(tag, GRN_TABLE_MAX_KEY_SIZE, GRN_TABLE_MAX_KEY_SIZE,
+ "[selector][no-index][%s]", proc_name);
+ grn_table_select_index_report(ctx, tag, table);
+ }
+ rc = proc->callbacks.function.selector(ctx,
+ table,
+ NULL,
+ si->nargs,
+ si->args,
+ res,
+ si->logical_op);
if (rc) {
- /* TODO: report error */
+ if (rc == GRN_FUNCTION_NOT_IMPLEMENTED) {
+ ERRCLR(ctx);
+ } else {
+ /* TODO: report error */
+ }
} else {
processed = GRN_TRUE;
}
@@ -5357,22 +6838,26 @@ grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
GRN_API_ENTER;
res_size = GRN_HASH_SIZE((grn_hash *)res);
if (op == GRN_OP_OR || res_size) {
- int i, n;
- scan_info **sis;
- if ((sis = scan_info_build(ctx, expr, &n, op, res_size))) {
+ int i;
+ grn_scanner *scanner;
+ scanner = grn_scanner_open(ctx, expr, op, res_size > 0);
+ if (scanner) {
grn_obj res_stack;
- grn_expr *e = (grn_expr *)expr;
+ grn_expr *e = (grn_expr *)scanner->expr;
grn_expr_code *codes = e->codes;
uint32_t codes_curr = e->codes_curr;
+ grn_id min_id = GRN_ID_NIL;
+ v = grn_expr_get_var_by_offset(ctx, (grn_obj *)e, 0);
GRN_PTR_INIT(&res_stack, GRN_OBJ_VECTOR, GRN_ID_NIL);
- for (i = 0; i < n; i++) {
- scan_info *si = sis[i];
+ for (i = 0; i < scanner->n_sis; i++) {
+ scan_info *si = scanner->sis[i];
if (si->flags & SCAN_POP) {
grn_obj *res_;
GRN_PTR_POP(&res_stack, res_);
grn_table_setoperation(ctx, res_, res, res_, si->logical_op);
grn_obj_close(ctx, res);
res = res_;
+ min_id = GRN_ID_NIL;
} else {
grn_bool processed = GRN_FALSE;
if (si->flags & SCAN_PUSH) {
@@ -5380,42 +6865,57 @@ grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
res_ = grn_table_create(ctx, NULL, 0, NULL,
GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, table, NULL);
if (!res_) {
- int i = 0;
- if (!res_created) { i++; }
- for (; i < GRN_BULK_VSIZE(&res_stack) / sizeof(grn_obj *); i++) {
- grn_obj *stacked_res;
- stacked_res = *((grn_obj **)GRN_BULK_HEAD(&res_stack) + i);
- grn_obj_close(ctx, stacked_res);
- }
break;
}
GRN_PTR_PUT(ctx, &res_stack, res);
res = res_;
+ min_id = GRN_ID_NIL;
}
- processed = grn_table_select_index(ctx, table, si, res);
+ if (si->logical_op != GRN_OP_AND) {
+ min_id = GRN_ID_NIL;
+ }
+ processed = grn_table_select_index(ctx, table, si, res, &min_id);
if (!processed) {
if (ctx->rc) { break; }
e->codes = codes + si->start;
e->codes_curr = si->end - si->start + 1;
- grn_table_select_sequential(ctx, table, expr, v,
+ grn_table_select_sequential(ctx, table, (grn_obj *)e, v,
res, si->logical_op);
+ min_id = GRN_ID_NIL;
}
}
GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
":", "filter(%d)", grn_table_size(ctx, res));
- if (ctx->rc) { break; }
+ if (ctx->rc) {
+ if (res_created) {
+ grn_obj_close(ctx, res);
+ }
+ res = NULL;
+ break;
+ }
}
- for (i = 0; i < n; i++) {
- scan_info *si = sis[i];
- SI_FREE(si);
+
+ i = 0;
+ if (!res_created) { i++; }
+ for (; i < GRN_BULK_VSIZE(&res_stack) / sizeof(grn_obj *); i++) {
+ grn_obj *stacked_res;
+ stacked_res = *((grn_obj **)GRN_BULK_HEAD(&res_stack) + i);
+ grn_obj_close(ctx, stacked_res);
}
GRN_OBJ_FIN(ctx, &res_stack);
- GRN_FREE(sis);
e->codes = codes;
e->codes_curr = codes_curr;
+
+ grn_scanner_close(ctx, scanner);
} else {
if (!ctx->rc) {
grn_table_select_sequential(ctx, table, expr, v, res, op);
+ if (ctx->rc) {
+ if (res_created) {
+ grn_obj_close(ctx, res);
+ }
+ res = NULL;
+ }
}
}
}
@@ -5464,6 +6964,7 @@ typedef struct {
grn_obj mode_stack;
grn_obj max_interval_stack;
grn_obj similarity_threshold_stack;
+ grn_obj weight_stack;
grn_operator default_op;
grn_select_optarg opt;
grn_operator default_mode;
@@ -5474,6 +6975,14 @@ typedef struct {
int weight_offset;
grn_hash *weight_set;
snip_cond *snip_conds;
+ grn_hash *object_literal;
+ int paren_depth;
+ struct {
+ const char *string;
+ size_t string_length;
+ int token;
+ int weight;
+ } pending_token;
} efs_info;
typedef struct {
@@ -5496,7 +7005,7 @@ skip_space(grn_ctx *ctx, efs_info *q)
}
static grn_bool
-get_op(efs_info *q, efs_op *op, grn_operator *mode, int *option)
+parse_query_op(efs_info *q, efs_op *op, grn_operator *mode, int *option)
{
grn_bool found = GRN_TRUE;
const char *start, *end = q->cur;
@@ -5664,14 +7173,7 @@ static grn_rc
grn_expr_parser_open(grn_ctx *ctx)
{
if (!ctx->impl->parser) {
- yyParser *pParser = GRN_MALLOCN(yyParser, 1);
- if (pParser) {
- pParser->yyidx = -1;
-#if YYSTACKDEPTH<=0
- yyGrowStack(pParser);
-#endif
- ctx->impl->parser = pParser;
- }
+ ctx->impl->parser = grn_expr_parserAlloc(malloc);
}
return ctx->rc;
}
@@ -5679,11 +7181,12 @@ grn_expr_parser_open(grn_ctx *ctx)
#define PARSE(token) grn_expr_parser(ctx->impl->parser, (token), 0, q)
static void
-accept_query_string(grn_ctx *ctx, efs_info *efsi,
- const char *str, unsigned int str_size)
+parse_query_accept_string(grn_ctx *ctx, efs_info *efsi,
+ const char *str, unsigned int str_size)
{
grn_obj *column, *token;
grn_operator mode;
+ int32_t weight;
GRN_PTR_PUT(ctx, &efsi->token_stack,
grn_expr_add_str(ctx, efsi->e, str, str_size));
@@ -5698,7 +7201,11 @@ accept_query_string(grn_ctx *ctx, efs_info *efsi,
grn_expr_append_obj(efsi->ctx, efsi->e, token, GRN_OP_PUSH, 1);
mode = grn_int32_value_at(&efsi->mode_stack, -1);
+ weight = grn_int32_value_at(&efsi->weight_stack, -1);
switch (mode) {
+ case GRN_OP_ASSIGN :
+ grn_expr_append_op(efsi->ctx, efsi->e, mode, 2);
+ break;
case GRN_OP_NEAR :
case GRN_OP_NEAR2 :
{
@@ -5706,7 +7213,11 @@ accept_query_string(grn_ctx *ctx, efs_info *efsi,
max_interval = grn_int32_value_at(&efsi->max_interval_stack, -1);
grn_expr_append_const_int(efsi->ctx, efsi->e, max_interval,
GRN_OP_PUSH, 1);
- grn_expr_append_op(efsi->ctx, efsi->e, mode, 3);
+ if (weight == 0) {
+ grn_expr_append_op(efsi->ctx, efsi->e, mode, 3);
+ } else {
+ grn_expr_append_const_int(efsi->ctx, efsi->e, weight, mode, 3);
+ }
}
break;
case GRN_OP_SIMILAR :
@@ -5716,17 +7227,104 @@ accept_query_string(grn_ctx *ctx, efs_info *efsi,
grn_int32_value_at(&efsi->similarity_threshold_stack, -1);
grn_expr_append_const_int(efsi->ctx, efsi->e, similarity_threshold,
GRN_OP_PUSH, 1);
- grn_expr_append_op(efsi->ctx, efsi->e, mode, 3);
+ if (weight == 0) {
+ grn_expr_append_op(efsi->ctx, efsi->e, mode, 3);
+ } else {
+ grn_expr_append_const_int(efsi->ctx, efsi->e, weight, mode, 3);
+ }
}
break;
default :
- grn_expr_append_op(efsi->ctx, efsi->e, mode, 2);
+ if (weight == 0) {
+ grn_expr_append_op(efsi->ctx, efsi->e, mode, 2);
+ } else {
+ grn_expr_append_const_int(efsi->ctx, efsi->e, weight, mode, 2);
+ }
break;
}
}
+static void
+parse_query_flush_pending_token(grn_ctx *ctx, efs_info *q)
+{
+ const char *cur_keep;
+
+ if (!(q->flags & GRN_EXPR_QUERY_NO_SYNTAX_ERROR)) {
+ return;
+ }
+
+ if (q->pending_token.string_length == 0) {
+ return;
+ }
+
+ cur_keep = q->cur;
+ q->cur = q->pending_token.string;
+ if (q->pending_token.token == GRN_EXPR_TOKEN_ADJUST ||
+ q->pending_token.token == GRN_EXPR_TOKEN_NEGATIVE) {
+ GRN_INT32_PUT(ctx, &q->weight_stack, q->pending_token.weight);
+ }
+ PARSE(q->pending_token.token);
+ q->cur = cur_keep;
+
+ q->pending_token.string = NULL;
+ q->pending_token.string_length = 0;
+ q->pending_token.token = 0;
+ q->pending_token.weight = 0;
+}
+
+static void
+parse_query_accept_logical_op(grn_ctx *ctx,
+ efs_info *q,
+ const char *string,
+ unsigned int string_length,
+ int token)
+{
+ if (!(q->flags & GRN_EXPR_QUERY_NO_SYNTAX_ERROR)) {
+ PARSE(token);
+ return;
+ }
+
+ if (q->pending_token.string_length > 0) {
+ parse_query_accept_string(ctx,
+ q,
+ q->pending_token.string,
+ q->pending_token.string_length);
+ }
+
+ q->pending_token.string = string;
+ q->pending_token.string_length = string_length;
+ q->pending_token.token = token;
+}
+
+static void
+parse_query_accept_adjust(grn_ctx *ctx,
+ efs_info *q,
+ const char *string,
+ unsigned int string_length,
+ int token,
+ int weight)
+{
+ if (!(q->flags & GRN_EXPR_QUERY_NO_SYNTAX_ERROR)) {
+ GRN_INT32_PUT(ctx, &q->weight_stack, weight);
+ PARSE(token);
+ return;
+ }
+
+ if (q->pending_token.string_length > 0) {
+ parse_query_accept_string(ctx,
+ q,
+ q->pending_token.string,
+ q->pending_token.string_length);
+ }
+
+ q->pending_token.string = string;
+ q->pending_token.string_length = string_length;
+ q->pending_token.token = token;
+ q->pending_token.weight = weight;
+}
+
static grn_rc
-get_word_(grn_ctx *ctx, efs_info *q)
+parse_query_word(grn_ctx *ctx, efs_info *q)
{
const char *end;
unsigned int len;
@@ -5748,7 +7346,6 @@ get_word_(grn_ctx *ctx, efs_info *q)
GRN_TEXT_VALUE(&q->buf),
GRN_TEXT_LEN(&q->buf));
if (c && end + 1 < q->str_end) {
- // efs_op op;
switch (end[1]) {
case '!' :
mode = GRN_OP_NOT_EQUAL;
@@ -5802,11 +7399,16 @@ get_word_(grn_ctx *ctx, efs_info *q)
q->cur = end + 1;
break;
}
+ } else if (q->flags & GRN_EXPR_QUERY_NO_SYNTAX_ERROR) {
+ GRN_TEXT_PUT(ctx, &q->buf, end, len);
+ end += len;
+ continue;
} else {
ERR(GRN_INVALID_ARGUMENT, "column lookup failed");
q->cur = q->str_end;
return ctx->rc;
}
+ parse_query_flush_pending_token(ctx, q);
PARSE(GRN_EXPR_TOKEN_IDENTIFIER);
PARSE(GRN_EXPR_TOKEN_RELATIVE_OP);
@@ -5829,7 +7431,11 @@ get_word_(grn_ctx *ctx, efs_info *q)
GRN_TEXT_PUT(ctx, &q->buf, end, len);
end += len;
}
- accept_query_string(ctx, q, GRN_TEXT_VALUE(&q->buf), GRN_TEXT_LEN(&q->buf));
+ parse_query_flush_pending_token(ctx, q);
+ parse_query_accept_string(ctx,
+ q,
+ GRN_TEXT_VALUE(&q->buf),
+ GRN_TEXT_LEN(&q->buf));
return GRN_SUCCESS;
}
@@ -5841,25 +7447,36 @@ parse_query(grn_ctx *ctx, efs_info *q)
grn_operator mode;
efs_op op_, *op = &op_;
grn_bool first_token = GRN_TRUE;
+ grn_bool only_first_and = GRN_FALSE;
grn_bool block_started = GRN_FALSE;
op->op = q->default_op;
op->weight = DEFAULT_WEIGHT;
while (!ctx->rc) {
skip_space(ctx, q);
+
if (q->cur >= q->str_end) { goto exit; }
+ if (*q->cur == '\0') { goto exit; }
+
+ only_first_and = GRN_FALSE;
switch (*q->cur) {
- case '\0' :
- goto exit;
- break;
case GRN_QUERY_PARENR :
- PARSE(GRN_EXPR_TOKEN_PARENR);
+ if (q->paren_depth == 0 && q->flags & GRN_EXPR_QUERY_NO_SYNTAX_ERROR) {
+ const char parenr = GRN_QUERY_PARENR;
+ parse_query_flush_pending_token(ctx, q);
+ parse_query_accept_string(ctx, q, &parenr, 1);
+ } else {
+ parse_query_flush_pending_token(ctx, q);
+ PARSE(GRN_EXPR_TOKEN_PARENR);
+ q->paren_depth--;
+ }
q->cur++;
break;
case GRN_QUERY_QUOTEL :
q->cur++;
{
+ grn_bool closed = GRN_FALSE;
const char *start, *s;
start = s = q->cur;
GRN_BULK_REWIND(&q->buf);
@@ -5876,6 +7493,7 @@ parse_query(grn_ctx *ctx, efs_info *q)
} else if (len == 1) {
if (*s == GRN_QUERY_QUOTER) {
q->cur = s + 1;
+ closed = GRN_TRUE;
break;
} else if (*s == GRN_QUERY_ESCAPE && s + 1 < q->str_end) {
s++;
@@ -5884,16 +7502,23 @@ parse_query(grn_ctx *ctx, efs_info *q)
}
GRN_TEXT_PUT(ctx, &q->buf, s, len);
s += len;
-
}
- accept_query_string(ctx, q,
- GRN_TEXT_VALUE(&q->buf), GRN_TEXT_LEN(&q->buf));
+ if (!closed && (q->flags & GRN_EXPR_QUERY_NO_SYNTAX_ERROR)) {
+ q->cur = start - 1;
+ parse_query_word(ctx, q);
+ } else {
+ parse_query_flush_pending_token(ctx, q);
+ parse_query_accept_string(ctx,
+ q,
+ GRN_TEXT_VALUE(&q->buf),
+ GRN_TEXT_LEN(&q->buf));
+ }
}
break;
case GRN_QUERY_PREFIX :
q->cur++;
- if (get_op(q, op, &mode, &option)) {
+ if (parse_query_op(q, op, &mode, &option)) {
switch (mode) {
case GRN_OP_NEAR :
case GRN_OP_NEAR2 :
@@ -5906,71 +7531,136 @@ parse_query(grn_ctx *ctx, efs_info *q)
break;
}
GRN_INT32_PUT(ctx, &q->mode_stack, mode);
+ parse_query_flush_pending_token(ctx, q);
PARSE(GRN_EXPR_TOKEN_RELATIVE_OP);
} else {
q->cur--;
- get_word_(ctx, q);
+ parse_query_word(ctx, q);
}
break;
case GRN_QUERY_AND :
- if (!first_token) {
+ if (first_token) {
+ only_first_and = GRN_TRUE;
+ } else {
op->op = GRN_OP_AND;
- PARSE(GRN_EXPR_TOKEN_LOGICAL_AND);
+ parse_query_accept_logical_op(ctx,
+ q,
+ q->cur, 1,
+ GRN_EXPR_TOKEN_LOGICAL_AND);
}
q->cur++;
break;
case GRN_QUERY_AND_NOT :
- if (first_token && (q->flags & GRN_EXPR_ALLOW_LEADING_NOT)) {
- grn_obj *all_records = grn_ctx_get(ctx, "all_records", 11);
- if (all_records) {
- /* dummy token */
- PARSE(GRN_EXPR_TOKEN_QSTRING);
- grn_expr_append_obj(ctx, q->e, all_records, GRN_OP_PUSH, 1);
- grn_expr_append_op(ctx, q->e, GRN_OP_CALL, 0);
+ if (first_token) {
+ if (q->flags & GRN_EXPR_ALLOW_LEADING_NOT) {
+ grn_obj *all_records = grn_ctx_get(ctx, "all_records", 11);
+ if (all_records) {
+ /* dummy token */
+ PARSE(GRN_EXPR_TOKEN_QSTRING);
+ grn_expr_append_obj(ctx, q->e, all_records, GRN_OP_PUSH, 1);
+ grn_expr_append_op(ctx, q->e, GRN_OP_CALL, 0);
+ }
+ } else if (q->flags & GRN_EXPR_QUERY_NO_SYNTAX_ERROR) {
+ parse_query_flush_pending_token(ctx, q);
+ parse_query_accept_string(ctx, q, q->cur, 1);
+ q->cur++;
+ break;
}
}
op->op = GRN_OP_AND_NOT;
- PARSE(GRN_EXPR_TOKEN_LOGICAL_AND_NOT);
+ parse_query_accept_logical_op(ctx,
+ q,
+ q->cur, 1,
+ GRN_EXPR_TOKEN_LOGICAL_AND_NOT);
q->cur++;
break;
case GRN_QUERY_ADJ_INC :
if (op->weight < 127) { op->weight++; }
op->op = GRN_OP_ADJUST;
- PARSE(GRN_EXPR_TOKEN_ADJUST);
+ parse_query_accept_adjust(ctx,
+ q,
+ q->cur, 1,
+ GRN_EXPR_TOKEN_ADJUST,
+ op->weight);
q->cur++;
break;
case GRN_QUERY_ADJ_DEC :
if (op->weight > -128) { op->weight--; }
op->op = GRN_OP_ADJUST;
- PARSE(GRN_EXPR_TOKEN_ADJUST);
+ parse_query_accept_adjust(ctx,
+ q,
+ q->cur, 1,
+ GRN_EXPR_TOKEN_ADJUST,
+ op->weight);
q->cur++;
break;
case GRN_QUERY_ADJ_NEG :
- op->op = GRN_OP_ADJUST;
- op->weight = -1;
- PARSE(GRN_EXPR_TOKEN_ADJUST);
+ if (first_token) {
+ parse_query_flush_pending_token(ctx, q);
+ parse_query_accept_string(ctx, q, q->cur, 1);
+ } else {
+ op->op = GRN_OP_ADJUST;
+ parse_query_accept_adjust(ctx,
+ q,
+ q->cur, 1,
+ GRN_EXPR_TOKEN_NEGATIVE,
+ -DEFAULT_WEIGHT);
+ }
q->cur++;
break;
case GRN_QUERY_PARENL :
+ parse_query_flush_pending_token(ctx, q);
PARSE(GRN_EXPR_TOKEN_PARENL);
q->cur++;
+ q->paren_depth++;
block_started = GRN_TRUE;
break;
case 'O' :
- if (q->cur[1] == 'R' && q->cur[2] == ' ') {
- PARSE(GRN_EXPR_TOKEN_LOGICAL_OR);
+ if (q->cur + 2 < q->str_end && q->cur[1] == 'R' && q->cur[2] == ' ') {
+ if (first_token && (q->flags & GRN_EXPR_QUERY_NO_SYNTAX_ERROR)) {
+ parse_query_flush_pending_token(ctx, q);
+ parse_query_accept_string(ctx, q, q->cur, 2);
+ } else {
+ parse_query_accept_logical_op(ctx,
+ q,
+ q->cur, 2,
+ GRN_EXPR_TOKEN_LOGICAL_OR);
+ }
q->cur += 2;
break;
}
/* fallthru */
default :
- get_word_(ctx, q);
+ parse_query_word(ctx, q);
break;
}
first_token = block_started;
block_started = GRN_FALSE;
}
exit :
+ if (q->flags & GRN_EXPR_QUERY_NO_SYNTAX_ERROR) {
+ if (q->pending_token.string_length > 0) {
+ parse_query_accept_string(ctx,
+ q,
+ q->pending_token.string,
+ q->pending_token.string_length);
+ } else if (only_first_and) {
+ const char query_and[] = {GRN_QUERY_AND};
+ parse_query_accept_string(ctx,
+ q,
+ query_and,
+ 1);
+ }
+ if (q->paren_depth > 0) {
+ int paren_depth = q->paren_depth;
+ while (paren_depth > 0) {
+ const char parenl = GRN_QUERY_PARENL;
+ parse_query_accept_string(ctx, q, &parenl, 1);
+ PARSE(GRN_EXPR_TOKEN_PARENR);
+ paren_depth--;
+ }
+ }
+ }
PARSE(0);
return GRN_SUCCESS;
}
@@ -6115,7 +7805,9 @@ done :
unsigned int name_size = s - q->cur;
if (name_resolve_context) {
if ((obj = grn_obj_column(ctx, name_resolve_context, name, name_size))) {
- grn_expr_take_obj(ctx, q->e, obj);
+ if (obj->header.type == GRN_ACCESSOR) {
+ grn_expr_take_obj(ctx, q->e, obj);
+ }
PARSE(GRN_EXPR_TOKEN_IDENTIFIER);
grn_expr_append_obj(ctx, q->e, obj, GRN_OP_GET_VALUE, 2);
goto exit;
@@ -6127,13 +7819,17 @@ done :
goto exit;
}
if ((obj = grn_obj_column(ctx, q->table, name, name_size))) {
- grn_expr_take_obj(ctx, q->e, obj);
+ if (obj->header.type == GRN_ACCESSOR) {
+ grn_expr_take_obj(ctx, q->e, obj);
+ }
PARSE(GRN_EXPR_TOKEN_IDENTIFIER);
grn_expr_append_obj(ctx, q->e, obj, GRN_OP_GET_VALUE, 1);
goto exit;
}
if ((obj = resolve_top_level_name(ctx, name, name_size))) {
- grn_expr_take_obj(ctx, q->e, obj);
+ if (obj->header.type == GRN_ACCESSOR) {
+ grn_expr_take_obj(ctx, q->e, obj);
+ }
PARSE(GRN_EXPR_TOKEN_IDENTIFIER);
grn_expr_append_obj(ctx, q->e, obj, GRN_OP_PUSH, 1);
goto exit;
@@ -6142,6 +7838,10 @@ done :
PARSE(GRN_EXPR_TOKEN_NONEXISTENT_COLUMN);
} else {
rc = GRN_SYNTAX_ERROR;
+ ERR(rc,
+ "[expr][parse] unknown identifier: <%.*s>",
+ (int)name_size,
+ name);
}
}
exit :
@@ -6152,8 +7852,8 @@ exit :
static void
set_tos_minor_to_curr(grn_ctx *ctx, efs_info *q)
{
- yyParser *pParser = ctx->impl->parser;
- yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
+ yyParser *parser = ctx->impl->parser;
+ yyStackEntry *yytos = parser->yytos;
yytos->minor.yy0 = ((grn_expr *)(q->e))->codes_curr;
}
@@ -6299,8 +7999,20 @@ parse_script(grn_ctx *ctx, efs_info *q)
case '*' :
switch (q->cur[1]) {
case 'N' :
- PARSE(GRN_EXPR_TOKEN_NEAR);
- q->cur += 2;
+ {
+ const char *next_start = q->cur + 2;
+ const char *end;
+ int max_interval;
+ max_interval = grn_atoi(next_start, q->str_end, &end);
+ if (end == next_start) {
+ max_interval = DEFAULT_MAX_INTERVAL;
+ } else {
+ next_start = end;
+ }
+ GRN_INT32_PUT(ctx, &q->max_interval_stack, max_interval);
+ PARSE(GRN_EXPR_TOKEN_NEAR);
+ q->cur = next_start;
+ }
break;
case 'S' :
PARSE(GRN_EXPR_TOKEN_SIMILAR);
@@ -6328,7 +8040,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 2;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'*=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'*=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
default :
@@ -6345,7 +8057,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 2;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'++' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'++' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
case '=' :
@@ -6354,7 +8066,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 2;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'+=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'+=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
default :
@@ -6371,7 +8083,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 2;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'--' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'--' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
case '=' :
@@ -6380,7 +8092,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 2;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'-=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'-=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
default :
@@ -6401,7 +8113,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 2;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'|=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'|=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
default :
@@ -6418,7 +8130,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 2;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'/=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'/=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
default :
@@ -6435,7 +8147,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 2;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'%%=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'%%=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
default :
@@ -6464,7 +8176,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
PARSE(GRN_EXPR_TOKEN_XOR_ASSIGN);
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'^=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'^=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
default :
@@ -6485,7 +8197,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 2;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'&=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'&=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
case '!' :
@@ -6510,7 +8222,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 4;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'>>>=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'>>>=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
default :
@@ -6525,7 +8237,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 3;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'>>=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'>>=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
default :
@@ -6554,7 +8266,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur += 3;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'<<=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'<<=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
default :
@@ -6585,7 +8297,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
q->cur++;
} else {
ERR(GRN_UPDATE_NOT_ALLOWED,
- "'=' is not allowed (%.*s)", (int)(q->str_end - q->str), q->str);
+ "'=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
}
break;
}
@@ -6596,7 +8308,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
const char *rest;
int64_t int64 = grn_atoll(q->cur, q->str_end, &rest);
// checks to see grn_atoll was appropriate
- // (NOTE: *q->cur begins with a digit. Thus, grn_atoll parses at leaset
+ // (NOTE: *q->cur begins with a digit. Thus, grn_atoll parses at least
// one char.)
if (q->str_end != rest &&
(*rest == '.' || *rest == 'e' || *rest == 'E' ||
@@ -6666,6 +8378,7 @@ grn_expr_parse(grn_ctx *ctx, grn_obj *expr,
GRN_INT32_INIT(&efsi.mode_stack, GRN_OBJ_VECTOR);
GRN_INT32_INIT(&efsi.max_interval_stack, GRN_OBJ_VECTOR);
GRN_INT32_INIT(&efsi.similarity_threshold_stack, GRN_OBJ_VECTOR);
+ GRN_INT32_INIT(&efsi.weight_stack, GRN_OBJ_VECTOR);
GRN_PTR_INIT(&efsi.column_stack, GRN_OBJ_VECTOR, GRN_ID_NIL);
GRN_PTR_INIT(&efsi.token_stack, GRN_OBJ_VECTOR, GRN_ID_NIL);
efsi.e = expr;
@@ -6676,12 +8389,19 @@ grn_expr_parse(grn_ctx *ctx, grn_obj *expr,
GRN_PTR_PUT(ctx, &efsi.column_stack, default_column);
GRN_INT32_PUT(ctx, &efsi.op_stack, default_op);
GRN_INT32_PUT(ctx, &efsi.mode_stack, default_mode);
+ GRN_INT32_PUT(ctx, &efsi.weight_stack, 0);
efsi.default_flags = efsi.flags = flags;
efsi.escalation_threshold = GRN_DEFAULT_MATCH_ESCALATION_THRESHOLD;
efsi.escalation_decaystep = DEFAULT_DECAYSTEP;
efsi.weight_offset = 0;
+ memset(&(efsi.opt), 0, sizeof(grn_select_optarg));
efsi.opt.weight_vector = NULL;
efsi.weight_set = NULL;
+ efsi.object_literal = NULL;
+ efsi.paren_depth = 0;
+ efsi.pending_token.string = NULL;
+ efsi.pending_token.string_length = 0;
+ efsi.pending_token.token = 0;
if (flags & (GRN_EXPR_SYNTAX_SCRIPT |
GRN_EXPR_SYNTAX_OUTPUT_COLUMNS |
@@ -6716,9 +8436,17 @@ grn_expr_parse(grn_ctx *ctx, grn_obj *expr,
GRN_OBJ_FIN(ctx, &efsi.mode_stack);
GRN_OBJ_FIN(ctx, &efsi.max_interval_stack);
GRN_OBJ_FIN(ctx, &efsi.similarity_threshold_stack);
+ GRN_OBJ_FIN(ctx, &efsi.weight_stack);
GRN_OBJ_FIN(ctx, &efsi.column_stack);
GRN_OBJ_FIN(ctx, &efsi.token_stack);
GRN_OBJ_FIN(ctx, &efsi.buf);
+ if (efsi.object_literal) {
+ grn_obj *value;
+ GRN_HASH_EACH(ctx, efsi.object_literal, i, NULL, NULL, (void **)&value, {
+ GRN_OBJ_FIN(ctx, value);
+ });
+ grn_hash_close(ctx, efsi.object_literal);
+ }
} else {
ERR(GRN_INVALID_ARGUMENT, "variable is not defined correctly");
}
@@ -6729,24 +8457,523 @@ grn_rc
grn_expr_parser_close(grn_ctx *ctx)
{
if (ctx->impl->parser) {
- yyParser *pParser = (yyParser*)ctx->impl->parser;
- while (pParser->yyidx >= 0) yy_pop_parser_stack(pParser);
-#if YYSTACKDEPTH<=0
- free(pParser->yystack);
-#endif
- GRN_FREE(pParser);
+ yyParser *parser = (yyParser *)ctx->impl->parser;
ctx->impl->parser = NULL;
+ grn_expr_parserFree(parser, free);
}
return ctx->rc;
}
+typedef grn_rc (*grn_expr_syntax_expand_term_func)(grn_ctx *ctx,
+ const char *term,
+ unsigned int term_len,
+ grn_obj *substituted_term,
+ grn_user_data *user_data);
+static grn_rc
+grn_expr_syntax_expand_term_by_func(grn_ctx *ctx,
+ const char *term, unsigned int term_len,
+ grn_obj *expanded_term,
+ grn_user_data *user_data)
+{
+ grn_rc rc;
+ grn_obj *expander = user_data->ptr;
+ grn_obj grn_term;
+ grn_obj *caller;
+ grn_obj *rc_object;
+ int nargs = 0;
+
+ GRN_TEXT_INIT(&grn_term, GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_TEXT_SET(ctx, &grn_term, term, term_len);
+ grn_ctx_push(ctx, &grn_term);
+ nargs++;
+ grn_ctx_push(ctx, expanded_term);
+ nargs++;
+
+ caller = grn_expr_create(ctx, NULL, 0);
+ rc = grn_proc_call(ctx, expander, nargs, caller);
+ GRN_OBJ_FIN(ctx, &grn_term);
+ rc_object = grn_ctx_pop(ctx);
+ rc = GRN_INT32_VALUE(rc_object);
+ grn_obj_unlink(ctx, caller);
+
+ return rc;
+}
+
+typedef struct {
+ grn_obj *table;
+ grn_obj *column;
+} grn_expr_syntax_expand_term_by_column_data;
+
+static grn_rc
+grn_expr_syntax_expand_term_by_column(grn_ctx *ctx,
+ const char *term, unsigned int term_len,
+ grn_obj *expanded_term,
+ grn_user_data *user_data)
+{
+ grn_rc rc = GRN_END_OF_DATA;
+ grn_id id;
+ grn_expr_syntax_expand_term_by_column_data *data = user_data->ptr;
+ grn_obj *table, *column;
+
+ table = data->table;
+ column = data->column;
+ if ((id = grn_table_get(ctx, table, term, term_len))) {
+ if ((column->header.type == GRN_COLUMN_VAR_SIZE) &&
+ ((column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR)) {
+ unsigned int i, n;
+ grn_obj values;
+ GRN_TEXT_INIT(&values, GRN_OBJ_VECTOR);
+ grn_obj_get_value(ctx, column, id, &values);
+ n = grn_vector_size(ctx, &values);
+ if (n > 1) { GRN_TEXT_PUTC(ctx, expanded_term, '('); }
+ for (i = 0; i < n; i++) {
+ const char *value;
+ unsigned int length;
+ if (i > 0) {
+ GRN_TEXT_PUTS(ctx, expanded_term, " OR ");
+ }
+ if (n > 1) { GRN_TEXT_PUTC(ctx, expanded_term, '('); }
+ length = grn_vector_get_element(ctx, &values, i, &value, NULL, NULL);
+ GRN_TEXT_PUT(ctx, expanded_term, value, length);
+ if (n > 1) { GRN_TEXT_PUTC(ctx, expanded_term, ')'); }
+ }
+ if (n > 1) { GRN_TEXT_PUTC(ctx, expanded_term, ')'); }
+ GRN_OBJ_FIN(ctx, &values);
+ } else {
+ grn_obj_get_value(ctx, column, id, expanded_term);
+ }
+ rc = GRN_SUCCESS;
+ }
+ return rc;
+}
+
+typedef struct {
+ grn_obj *table;
+ grn_obj *term_column;
+ grn_obj *expanded_term_column;
+} grn_expr_syntax_expand_term_by_table_data;
+
+static grn_rc
+grn_expr_syntax_expand_term_by_table(grn_ctx *ctx,
+ const char *term, unsigned int term_len,
+ grn_obj *expanded_term,
+ grn_user_data *user_data)
+{
+ grn_rc rc = GRN_END_OF_DATA;
+ grn_expr_syntax_expand_term_by_table_data *data = user_data->ptr;
+ grn_obj *table;
+ grn_obj *term_column;
+ grn_obj *expanded_term_column;
+ grn_obj *expression;
+ grn_obj *variable;
+ grn_obj *found_terms;
+ int n_terms;
+
+ table = data->table;
+ term_column = data->term_column;
+ expanded_term_column = data->expanded_term_column;
+
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, table, expression, variable);
+ if (ctx->rc != GRN_SUCCESS) {
+ ERR(ctx->rc,
+ "[query][expand][table] "
+ "failed to create expression: <%s>",
+ ctx->errbuf);
+ return ctx->rc;
+ }
+ grn_expr_append_const(ctx, expression, term_column, GRN_OP_GET_VALUE, 1);
+ grn_expr_append_const_str(ctx, expression, term, term_len, GRN_OP_PUSH, 1);
+ grn_expr_append_op(ctx, expression, GRN_OP_EQUAL, 2);
+ if (ctx->rc != GRN_SUCCESS) {
+ grn_obj_close(ctx, expression);
+ ERR(ctx->rc,
+ "[query][expand][table] "
+ "failed to build expression: <%s>",
+ ctx->errbuf);
+ return ctx->rc;
+ }
+
+ found_terms = grn_table_select(ctx, table, expression, NULL, GRN_OP_OR);
+ grn_obj_close(ctx, expression);
+ if (!found_terms) {
+ ERR(ctx->rc,
+ "[query][expand][table] "
+ "failed to find term: <%.*s>: <%s>",
+ (int)term_len,
+ term,
+ ctx->errbuf);
+ return ctx->rc;
+ }
+
+ n_terms = grn_table_size(ctx, found_terms);
+ if (n_terms == 0) {
+ grn_obj_close(ctx, found_terms);
+ return rc;
+ }
+
+ {
+ int nth_term;
+
+ GRN_TEXT_PUTC(ctx, expanded_term, '(');
+ nth_term = 0;
+ GRN_TABLE_EACH_BEGIN(ctx, found_terms, cursor, id) {
+ void *key;
+ grn_id record_id;
+
+ grn_table_cursor_get_key(ctx, cursor, &key);
+ record_id = *((grn_id *)key);
+ if (grn_obj_is_vector_column(ctx, expanded_term_column)) {
+ unsigned int j, n_values;
+ grn_obj values;
+ GRN_TEXT_INIT(&values, GRN_OBJ_VECTOR);
+ grn_obj_get_value(ctx, expanded_term_column, record_id, &values);
+ n_values = grn_vector_size(ctx, &values);
+ n_terms += n_values - 1;
+ for (j = 0; j < n_values; j++) {
+ const char *value;
+ unsigned int length;
+ if (nth_term > 0) {
+ GRN_TEXT_PUTS(ctx, expanded_term, " OR ");
+ }
+ if (n_terms > 1) {
+ GRN_TEXT_PUTC(ctx, expanded_term, '(');
+ }
+ length = grn_vector_get_element(ctx, &values, j, &value, NULL, NULL);
+ GRN_TEXT_PUT(ctx, expanded_term, value, length);
+ if (n_terms > 1) {
+ GRN_TEXT_PUTC(ctx, expanded_term, ')');
+ }
+ nth_term++;
+ }
+ GRN_OBJ_FIN(ctx, &values);
+ } else {
+ if (nth_term > 0) {
+ GRN_TEXT_PUTS(ctx, expanded_term, " OR ");
+ }
+ if (n_terms > 1) { GRN_TEXT_PUTC(ctx, expanded_term, '('); }
+ grn_obj_get_value(ctx, expanded_term_column, record_id, expanded_term);
+ if (n_terms > 1) { GRN_TEXT_PUTC(ctx, expanded_term, ')'); }
+ nth_term++;
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ GRN_TEXT_PUTC(ctx, expanded_term, ')');
+ }
+ rc = GRN_SUCCESS;
+ grn_obj_close(ctx, found_terms);
+
+ return rc;
+}
+
+static grn_rc
+grn_expr_syntax_expand_query_terms(grn_ctx *ctx,
+ const char *query, unsigned int query_size,
+ grn_expr_flags flags,
+ grn_obj *expanded_query,
+ grn_expr_syntax_expand_term_func expand_term_func,
+ grn_user_data *user_data)
+{
+ grn_obj buf;
+ unsigned int len;
+ const char *start, *cur = query, *query_end = query + (size_t)query_size;
+ GRN_TEXT_INIT(&buf, 0);
+ for (;;) {
+ while (cur < query_end && grn_isspace(cur, ctx->encoding)) {
+ if (!(len = grn_charlen(ctx, cur, query_end))) { goto exit; }
+ GRN_TEXT_PUT(ctx, expanded_query, cur, len);
+ cur += len;
+ }
+ if (query_end <= cur) { break; }
+ switch (*cur) {
+ case '\0' :
+ goto exit;
+ break;
+ case GRN_QUERY_AND :
+ case GRN_QUERY_ADJ_INC :
+ case GRN_QUERY_ADJ_DEC :
+ case GRN_QUERY_ADJ_NEG :
+ case GRN_QUERY_AND_NOT :
+ case GRN_QUERY_PARENL :
+ case GRN_QUERY_PARENR :
+ case GRN_QUERY_PREFIX :
+ GRN_TEXT_PUTC(ctx, expanded_query, *cur);
+ cur++;
+ break;
+ case GRN_QUERY_QUOTEL :
+ GRN_BULK_REWIND(&buf);
+ for (start = cur++; cur < query_end; cur += len) {
+ if (!(len = grn_charlen(ctx, cur, query_end))) {
+ goto exit;
+ } else if (len == 1) {
+ if (*cur == GRN_QUERY_QUOTER) {
+ cur++;
+ break;
+ } else if (cur + 1 < query_end && *cur == GRN_QUERY_ESCAPE) {
+ cur++;
+ len = grn_charlen(ctx, cur, query_end);
+ }
+ }
+ GRN_TEXT_PUT(ctx, &buf, cur, len);
+ }
+ if (expand_term_func(ctx, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf),
+ expanded_query, user_data)) {
+ GRN_TEXT_PUT(ctx, expanded_query, start, cur - start);
+ }
+ break;
+ case 'O' :
+ if (cur + 2 <= query_end && cur[1] == 'R' &&
+ (cur + 2 == query_end || grn_isspace(cur + 2, ctx->encoding))) {
+ GRN_TEXT_PUT(ctx, expanded_query, cur, 2);
+ cur += 2;
+ break;
+ }
+ /* fallthru */
+ default :
+ for (start = cur; cur < query_end; cur += len) {
+ if (!(len = grn_charlen(ctx, cur, query_end))) {
+ goto exit;
+ } else if (grn_isspace(cur, ctx->encoding)) {
+ break;
+ } else if (len == 1) {
+ if (*cur == GRN_QUERY_PARENL ||
+ *cur == GRN_QUERY_PARENR ||
+ *cur == GRN_QUERY_PREFIX) {
+ break;
+ } else if (flags & GRN_EXPR_ALLOW_COLUMN && *cur == GRN_QUERY_COLUMN) {
+ if (cur + 1 < query_end) {
+ switch (cur[1]) {
+ case '!' :
+ case '@' :
+ case '^' :
+ case '$' :
+ cur += 2;
+ break;
+ case '=' :
+ cur += (flags & GRN_EXPR_ALLOW_UPDATE) ? 2 : 1;
+ break;
+ case '<' :
+ case '>' :
+ cur += (cur + 2 < query_end && cur[2] == '=') ? 3 : 2;
+ break;
+ default :
+ cur += 1;
+ break;
+ }
+ } else {
+ cur += 1;
+ }
+ GRN_TEXT_PUT(ctx, expanded_query, start, cur - start);
+ start = cur;
+ break;
+ }
+ }
+ }
+ if (start < cur) {
+ if (expand_term_func(ctx, start, cur - start,
+ expanded_query, user_data)) {
+ GRN_TEXT_PUT(ctx, expanded_query, start, cur - start);
+ }
+ }
+ break;
+ }
+ }
+exit :
+ GRN_OBJ_FIN(ctx, &buf);
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_expr_syntax_expand_query(grn_ctx *ctx,
+ const char *query, int query_size,
+ grn_expr_flags flags,
+ grn_obj *expander,
+ grn_obj *expanded_query)
+{
+ GRN_API_ENTER;
+
+ if (query_size < 0) {
+ query_size = strlen(query);
+ }
+
+ switch (expander->header.type) {
+ case GRN_PROC :
+ if (((grn_proc *)expander)->type == GRN_PROC_FUNCTION) {
+ grn_user_data user_data;
+ user_data.ptr = expander;
+ grn_expr_syntax_expand_query_terms(ctx,
+ query, query_size,
+ flags,
+ expanded_query,
+ grn_expr_syntax_expand_term_by_func,
+ &user_data);
+ } else {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_obj_name(ctx, expander, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[query][expand][proc] "
+ "proc query expander must be a function proc: <%.*s>",
+ name_size, name);
+ }
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ {
+ grn_obj *expansion_table;
+ expansion_table = grn_column_table(ctx, expander);
+ if (expansion_table) {
+ grn_user_data user_data;
+ grn_expr_syntax_expand_term_by_column_data data;
+ user_data.ptr = &data;
+ data.table = expansion_table;
+ data.column = expander;
+ grn_expr_syntax_expand_query_terms(ctx,
+ query, query_size,
+ flags,
+ expanded_query,
+ grn_expr_syntax_expand_term_by_column,
+ &user_data);
+ } else {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_obj_name(ctx, expander, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[query][expand][column] "
+ "failed to get table of query expansion column: <%.*s>",
+ name_size, name);
+ }
+ }
+ break;
+ default :
+ {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ grn_obj type_name;
+
+ name_size = grn_obj_name(ctx, expander, name, GRN_TABLE_MAX_KEY_SIZE);
+ GRN_TEXT_INIT(&type_name, 0);
+ grn_inspect_type(ctx, &type_name, expander->header.type);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[query][expand] "
+ "query expander must be a data column or function proc: <%.*s>(%.*s)",
+ name_size, name,
+ (int)GRN_TEXT_LEN(&type_name), GRN_TEXT_VALUE(&type_name));
+ GRN_OBJ_FIN(ctx, &type_name);
+ }
+ break;
+ }
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_expr_syntax_expand_query_by_table(grn_ctx *ctx,
+ const char *query, int query_size,
+ grn_expr_flags flags,
+ grn_obj *term_column,
+ grn_obj *expanded_term_column,
+ grn_obj *expanded_query)
+{
+ grn_obj *table;
+ grn_bool term_column_is_key;
+
+ GRN_API_ENTER;
+
+ if (query_size < 0) {
+ query_size = strlen(query);
+ }
+
+ if (!grn_obj_is_data_column(ctx, expanded_term_column)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, expanded_term_column);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[query][expand][table] "
+ "expanded term column must be a data column: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ GRN_API_RETURN(ctx->rc);
+ }
+ table = grn_column_table(ctx, expanded_term_column);
+
+ if (!term_column) {
+ term_column_is_key = GRN_TRUE;
+ } else {
+ if (grn_obj_is_key_accessor(ctx, term_column)) {
+ term_column_is_key = GRN_TRUE;
+ } else if (grn_obj_is_data_column(ctx, term_column)) {
+ term_column_is_key = GRN_FALSE;
+ } else {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, term_column);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[query][expand][table] "
+ "term column must be NULL, _key or a data column: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ GRN_API_RETURN(ctx->rc);
+ }
+ if (term_column->header.domain != expanded_term_column->header.domain) {
+ grn_obj inspected_term_column;
+ grn_obj inspected_expanded_term_column;
+ GRN_TEXT_INIT(&inspected_term_column, 0);
+ GRN_TEXT_INIT(&inspected_expanded_term_column, 0);
+ grn_inspect(ctx, &inspected_term_column, term_column);
+ grn_inspect(ctx, &inspected_expanded_term_column, expanded_term_column);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[query][expand][table] "
+ "term column and expanded term column must belong to the same table: "
+ "term column: <%.*s>, "
+ "expanded term column: <%*.s>",
+ (int)GRN_TEXT_LEN(&inspected_term_column),
+ GRN_TEXT_VALUE(&inspected_term_column),
+ (int)GRN_TEXT_LEN(&inspected_expanded_term_column),
+ GRN_TEXT_VALUE(&inspected_expanded_term_column));
+ GRN_OBJ_FIN(ctx, &inspected_term_column);
+ GRN_OBJ_FIN(ctx, &inspected_expanded_term_column);
+ GRN_API_RETURN(ctx->rc);
+ }
+ }
+
+ if (term_column_is_key) {
+ grn_user_data user_data;
+ grn_expr_syntax_expand_term_by_column_data data;
+ user_data.ptr = &data;
+ data.table = table;
+ data.column = expanded_term_column;
+ grn_expr_syntax_expand_query_terms(ctx,
+ query, query_size,
+ flags,
+ expanded_query,
+ grn_expr_syntax_expand_term_by_column,
+ &user_data);
+ } else {
+ grn_user_data user_data;
+ grn_expr_syntax_expand_term_by_table_data data;
+ user_data.ptr = &data;
+ data.table = table;
+ data.term_column = term_column;
+ data.expanded_term_column = expanded_term_column;
+ grn_expr_syntax_expand_query_terms(ctx,
+ query, query_size,
+ flags,
+ expanded_query,
+ grn_expr_syntax_expand_term_by_table,
+ &user_data);
+ }
+
+ GRN_API_RETURN(ctx->rc);
+}
+
grn_rc
grn_expr_get_keywords(grn_ctx *ctx, grn_obj *expr, grn_obj *keywords)
{
int i, n;
scan_info **sis, *si;
GRN_API_ENTER;
- if ((sis = scan_info_build(ctx, expr, &n, GRN_OP_OR, 0))) {
+ if ((sis = grn_scan_info_build(ctx, expr, &n, GRN_OP_OR, GRN_FALSE))) {
int butp = 0, nparens = 0, npbut = 0;
grn_obj but_stack;
GRN_UINT32_INIT(&but_stack, GRN_OBJ_VECTOR);
@@ -6760,9 +8987,66 @@ grn_expr_get_keywords(grn_ctx *ctx, grn_obj *expr, grn_obj *keywords)
butp = 1 - butp;
}
} else {
- if (si->op == GRN_OP_MATCH && si->query) {
- if (butp == (si->logical_op == GRN_OP_AND_NOT)) {
- GRN_PTR_PUT(ctx, keywords, si->query);
+ if (butp == (si->logical_op == GRN_OP_AND_NOT) &&
+ si->query) {
+ switch (si->op) {
+ case GRN_OP_MATCH :
+ if (keywords->header.type == GRN_PVECTOR) {
+ GRN_PTR_PUT(ctx, keywords, si->query);
+ } else {
+ grn_vector_add_element(ctx,
+ keywords,
+ GRN_TEXT_VALUE(si->query),
+ GRN_TEXT_LEN(si->query),
+ 0,
+ GRN_DB_TEXT);
+ }
+ break;
+ case GRN_OP_SIMILAR :
+ if (keywords->header.type == GRN_VECTOR &&
+ GRN_BULK_VSIZE(&(si->index)) > 0) {
+ grn_token_cursor *token_cursor;
+ unsigned int token_flags = 0;
+ grn_obj *index = GRN_PTR_VALUE(&(si->index));
+ grn_obj *lexicon;
+
+ lexicon = grn_ctx_at(ctx, index->header.domain);
+ token_cursor = grn_token_cursor_open(ctx,
+ lexicon,
+ GRN_TEXT_VALUE(si->query),
+ GRN_TEXT_LEN(si->query),
+ GRN_TOKENIZE_GET,
+ token_flags);
+ if (token_cursor) {
+ grn_obj *source_table;
+ uint32_t n_records_threshold;
+ source_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, index));
+ n_records_threshold = grn_table_size(ctx, source_table) / 2;
+ while (token_cursor->status != GRN_TOKEN_CURSOR_DONE) {
+ grn_id token_id;
+ uint32_t n_estimated_records;
+ token_id = grn_token_cursor_next(ctx, token_cursor);
+ if (token_id == GRN_ID_NIL) {
+ continue;
+ }
+ n_estimated_records =
+ grn_ii_estimate_size(ctx, (grn_ii *)index, token_id);
+ if (n_estimated_records >= n_records_threshold) {
+ continue;
+ }
+ grn_vector_add_element(ctx,
+ keywords,
+ token_cursor->curr,
+ token_cursor->curr_size,
+ 0,
+ GRN_DB_TEXT);
+ }
+ grn_token_cursor_close(ctx, token_cursor);
+ }
+ }
+ break;
+ default :
+ break;
}
}
if (si->flags & SCAN_PUSH) {
@@ -6862,7 +9146,7 @@ grn_column_filter(grn_ctx *ctx, grn_obj *column,
grn_operator set_operation)
{
uint32_t *vp;
- grn_ii_posting posting;
+ grn_posting posting;
uint32_t value_ = grn_atoui(GRN_TEXT_VALUE(value), GRN_BULK_CURR(value), NULL);
posting.sid = 1;
posting.pos = 0;
@@ -6952,7 +9236,7 @@ grn_expr_dump_plan(grn_ctx *ctx, grn_obj *expr, grn_obj *buffer)
scan_info **sis;
GRN_API_ENTER;
- sis = scan_info_build(ctx, expr, &n, GRN_OP_OR, 0);
+ sis = grn_scan_info_build(ctx, expr, &n, GRN_OP_OR, GRN_FALSE);
if (sis) {
int i;
grn_inspect_scan_info_list(ctx, buffer, sis, n);
@@ -6994,6 +9278,10 @@ grn_expr_estimate_size(grn_ctx *ctx, grn_obj *expr)
GRN_API_ENTER;
#ifdef GRN_WITH_MRUBY
+ grn_ctx_impl_mrb_ensure_init(ctx);
+ if (ctx->rc != GRN_SUCCESS) {
+ GRN_API_RETURN(0);
+ }
if (ctx->impl->mrb.state) {
size = grn_mrb_expr_estimate_size(ctx, expr, table);
} else {
diff --git a/storage/mroonga/vendor/groonga/lib/expr_code.c b/storage/mroonga/vendor/groonga/lib/expr_code.c
index 4f03867402a..c12a3cbc8d2 100644
--- a/storage/mroonga/vendor/groonga/lib/expr_code.c
+++ b/storage/mroonga/vendor/groonga/lib/expr_code.c
@@ -24,7 +24,6 @@ grn_expr_code_n_used_codes(grn_ctx *ctx,
{
unsigned int n_codes;
int i, n_args;
- grn_bool have_proc_push_code = GRN_FALSE;
grn_expr_code *sub_code;
if (start == target) {
@@ -32,16 +31,10 @@ grn_expr_code_n_used_codes(grn_ctx *ctx,
}
n_args = target->nargs;
- if (target->op == GRN_OP_CALL) {
- if (!target->value) {
- have_proc_push_code = GRN_TRUE;
- }
- } else {
- if (target->value) {
- n_args--;
- if (n_args == 0) {
- return 1;
- }
+ if (target->value) {
+ n_args--;
+ if (n_args == 0) {
+ return 1;
}
}
@@ -58,14 +51,5 @@ grn_expr_code_n_used_codes(grn_ctx *ctx,
}
}
- if (have_proc_push_code) {
- n_codes++;
- sub_code--;
- if (sub_code < start) {
- /* TODO: report error */
- return 0;
- }
- }
-
return n_codes;
}
diff --git a/storage/mroonga/vendor/groonga/lib/expr_executor.c b/storage/mroonga/vendor/groonga/lib/expr_executor.c
new file mode 100644
index 00000000000..4fcf93a40f9
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/expr_executor.c
@@ -0,0 +1,945 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2010-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn.h"
+#include "grn_ctx_impl.h"
+#include "grn_expr_executor.h"
+
+#ifdef GRN_WITH_ONIGMO
+# define GRN_SUPPORT_REGEXP
+#endif
+
+#ifdef GRN_SUPPORT_REGEXP
+# include "grn_normalizer.h"
+# include <onigmo.h>
+#endif
+
+typedef union {
+ struct {
+ grn_obj result_buffer;
+ } constant;
+ struct {
+ grn_obj *column;
+ grn_obj value_buffer;
+ } value;
+#ifdef GRN_SUPPORT_REGEXP
+ struct {
+ grn_obj result_buffer;
+ OnigRegex regex;
+ grn_obj value_buffer;
+ grn_obj *normalizer;
+ } simple_regexp;
+#endif /* GRN_SUPPORT_REGEXP */
+ struct {
+ grn_proc_ctx proc_ctx;
+ int n_args;
+ } proc;
+ struct {
+ grn_obj result_buffer;
+ grn_ra *ra;
+ grn_ra_cache ra_cache;
+ unsigned int ra_element_size;
+ grn_obj value_buffer;
+ grn_obj constant_buffer;
+ grn_operator_exec_func *exec;
+ } simple_condition_ra;
+ struct {
+ grn_bool need_exec;
+ grn_obj result_buffer;
+ grn_obj value_buffer;
+ grn_obj constant_buffer;
+ grn_operator_exec_func *exec;
+ } simple_condition;
+} grn_expr_executor_data;
+
+typedef grn_obj *(*grn_expr_executor_exec_func)(grn_ctx *ctx,
+ grn_expr_executor *executor,
+ grn_id id);
+typedef void (*grn_expr_executor_fin_func)(grn_ctx *ctx,
+ grn_expr_executor *executor);
+
+struct _grn_expr_executor {
+ grn_obj *expr;
+ grn_obj *variable;
+ grn_expr_executor_exec_func exec;
+ grn_expr_executor_fin_func fin;
+ grn_expr_executor_data data;
+};
+
+static void
+grn_expr_executor_init_general(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+}
+
+static grn_obj *
+grn_expr_executor_exec_general(grn_ctx *ctx,
+ grn_expr_executor *executor,
+ grn_id id)
+{
+ GRN_RECORD_SET(ctx, executor->variable, id);
+ return grn_expr_exec(ctx, executor->expr, 0);
+}
+
+static void
+grn_expr_executor_fin_general(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+}
+
+static grn_bool
+grn_expr_executor_is_constant(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_expr *e = (grn_expr *)expr;
+ grn_expr_code *target;
+
+ if (e->codes_curr != 1) {
+ return GRN_FALSE;
+ }
+
+ target = &(e->codes[0]);
+
+ if (target->op != GRN_OP_PUSH) {
+ return GRN_FALSE;
+ }
+ if (!target->value) {
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+static void
+grn_expr_executor_init_constant(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ grn_obj *result_buffer = &(executor->data.constant.result_buffer);
+ grn_obj *result;
+
+ GRN_VOID_INIT(result_buffer);
+ result = grn_expr_exec(ctx, executor->expr, 0);
+ if (ctx->rc == GRN_SUCCESS) {
+ grn_obj_reinit(ctx,
+ result_buffer,
+ result->header.domain,
+ result->header.flags);
+ /* TODO: Support vector */
+ grn_bulk_write(ctx,
+ result_buffer,
+ GRN_BULK_HEAD(result),
+ GRN_BULK_VSIZE(result));
+ }
+}
+
+static grn_obj *
+grn_expr_executor_exec_constant(grn_ctx *ctx,
+ grn_expr_executor *executor,
+ grn_id id)
+{
+ return &(executor->data.constant.result_buffer);
+}
+
+static void
+grn_expr_executor_fin_constant(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ GRN_OBJ_FIN(ctx, &(executor->data.constant.result_buffer));
+}
+
+static grn_bool
+grn_expr_executor_is_value(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_expr *e = (grn_expr *)expr;
+ grn_expr_code *target;
+
+ if (e->codes_curr != 1) {
+ return GRN_FALSE;
+ }
+
+ target = &(e->codes[0]);
+
+ if (target->op != GRN_OP_GET_VALUE) {
+ return GRN_FALSE;
+ }
+ if (!target->value) {
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+static void
+grn_expr_executor_init_value(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ grn_expr *e = (grn_expr *)(executor->expr);
+
+ executor->data.value.column = e->codes[0].value;
+ GRN_VOID_INIT(&(executor->data.value.value_buffer));
+}
+
+static grn_obj *
+grn_expr_executor_exec_value(grn_ctx *ctx,
+ grn_expr_executor *executor,
+ grn_id id)
+{
+ grn_obj *value_buffer = &(executor->data.value.value_buffer);
+
+ GRN_BULK_REWIND(value_buffer);
+ grn_obj_get_value(ctx, executor->data.value.column, id, value_buffer);
+
+ return value_buffer;
+}
+
+static void
+grn_expr_executor_fin_value(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ GRN_OBJ_FIN(ctx, &(executor->data.value.value_buffer));
+}
+
+#ifdef GRN_SUPPORT_REGEXP
+static grn_bool
+grn_expr_executor_is_simple_regexp(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_expr *e = (grn_expr *)expr;
+ grn_expr_code *target;
+ grn_expr_code *pattern;
+ grn_expr_code *operator;
+
+ if (e->codes_curr != 3) {
+ return GRN_FALSE;
+ }
+
+ target = &(e->codes[0]);
+ pattern = &(e->codes[1]);
+ operator = &(e->codes[2]);
+
+ if (operator->op != GRN_OP_REGEXP) {
+ return GRN_FALSE;
+ }
+ if (operator->nargs != 2) {
+ return GRN_FALSE;
+ }
+
+ if (target->op != GRN_OP_GET_VALUE) {
+ return GRN_FALSE;
+ }
+ if (target->nargs != 1) {
+ return GRN_FALSE;
+ }
+ if (!target->value) {
+ return GRN_FALSE;
+ }
+ if (target->value->header.type != GRN_COLUMN_VAR_SIZE) {
+ return GRN_FALSE;
+ }
+ if ((target->value->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) !=
+ GRN_OBJ_COLUMN_SCALAR) {
+ return GRN_FALSE;
+ }
+ switch (grn_obj_get_range(ctx, target->value)) {
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ break;
+ default :
+ return GRN_FALSE;
+ }
+
+ if (pattern->op != GRN_OP_PUSH) {
+ return GRN_FALSE;
+ }
+ if (pattern->nargs != 1) {
+ return GRN_FALSE;
+ }
+ if (!pattern->value) {
+ return GRN_FALSE;
+ }
+ if (pattern->value->header.type != GRN_BULK) {
+ return GRN_FALSE;
+ }
+ switch (pattern->value->header.domain) {
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ break;
+ default :
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+static void
+grn_expr_executor_init_simple_regexp(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ grn_expr *e = (grn_expr *)(executor->expr);
+ grn_obj *result_buffer = &(executor->data.simple_regexp.result_buffer);
+ OnigEncoding onig_encoding;
+ int onig_result;
+ OnigErrorInfo onig_error_info;
+ grn_obj *pattern;
+
+ GRN_BOOL_INIT(result_buffer, 0);
+ GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
+
+ if (ctx->encoding == GRN_ENC_NONE) {
+ executor->data.simple_regexp.regex = NULL;
+ return;
+ }
+
+ switch (ctx->encoding) {
+ case GRN_ENC_EUC_JP :
+ onig_encoding = ONIG_ENCODING_EUC_JP;
+ break;
+ case GRN_ENC_UTF8 :
+ onig_encoding = ONIG_ENCODING_UTF8;
+ break;
+ case GRN_ENC_SJIS :
+ onig_encoding = ONIG_ENCODING_CP932;
+ break;
+ case GRN_ENC_LATIN1 :
+ onig_encoding = ONIG_ENCODING_ISO_8859_1;
+ break;
+ case GRN_ENC_KOI8R :
+ onig_encoding = ONIG_ENCODING_KOI8_R;
+ break;
+ default :
+ executor->data.simple_regexp.regex = NULL;
+ return;
+ }
+
+ pattern = e->codes[1].value;
+ onig_result = onig_new(&(executor->data.simple_regexp.regex),
+ GRN_TEXT_VALUE(pattern),
+ GRN_TEXT_VALUE(pattern) + GRN_TEXT_LEN(pattern),
+ ONIG_OPTION_ASCII_RANGE |
+ ONIG_OPTION_MULTILINE,
+ onig_encoding,
+ ONIG_SYNTAX_RUBY,
+ &onig_error_info);
+ if (onig_result != ONIG_NORMAL) {
+ char message[ONIG_MAX_ERROR_MESSAGE_LEN];
+ onig_error_code_to_str(message, onig_result, onig_error_info);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[expr-executor][regexp] "
+ "failed to create regular expression object: <%.*s>: %s",
+ (int)GRN_TEXT_LEN(pattern), GRN_TEXT_VALUE(pattern),
+ message);
+ return;
+ }
+
+ GRN_VOID_INIT(&(executor->data.simple_regexp.value_buffer));
+
+ executor->data.simple_regexp.normalizer =
+ grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+}
+
+static grn_obj *
+grn_expr_executor_exec_simple_regexp(grn_ctx *ctx,
+ grn_expr_executor *executor,
+ grn_id id)
+{
+ grn_expr *e = (grn_expr *)(executor->expr);
+ OnigRegex regex = executor->data.simple_regexp.regex;
+ grn_obj *value_buffer = &(executor->data.simple_regexp.value_buffer);
+ grn_obj *result_buffer = &(executor->data.simple_regexp.result_buffer);
+
+ if (ctx->rc) {
+ GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
+ return result_buffer;
+ }
+
+ if (!regex) {
+ return result_buffer;
+ }
+
+ grn_obj_reinit_for(ctx, value_buffer, e->codes[0].value);
+ grn_obj_get_value(ctx, e->codes[0].value, id, value_buffer);
+ {
+ grn_obj *norm_target;
+ const char *norm_target_raw;
+ unsigned int norm_target_raw_length_in_bytes;
+
+ norm_target = grn_string_open(ctx,
+ GRN_TEXT_VALUE(value_buffer),
+ GRN_TEXT_LEN(value_buffer),
+ executor->data.simple_regexp.normalizer,
+ 0);
+ grn_string_get_normalized(ctx, norm_target,
+ &norm_target_raw,
+ &norm_target_raw_length_in_bytes,
+ NULL);
+
+ {
+ OnigPosition position;
+ position = onig_search(regex,
+ norm_target_raw,
+ norm_target_raw + norm_target_raw_length_in_bytes,
+ norm_target_raw,
+ norm_target_raw + norm_target_raw_length_in_bytes,
+ NULL,
+ ONIG_OPTION_NONE);
+ grn_obj_close(ctx, norm_target);
+ GRN_BOOL_SET(ctx, result_buffer, (position != ONIG_MISMATCH));
+ return result_buffer;
+ }
+ }
+}
+
+static void
+grn_expr_executor_fin_simple_regexp(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ GRN_OBJ_FIN(ctx, &(executor->data.simple_regexp.result_buffer));
+
+ if (!executor->data.simple_regexp.regex) {
+ return;
+ }
+
+ onig_free(executor->data.simple_regexp.regex);
+ GRN_OBJ_FIN(ctx, &(executor->data.simple_regexp.value_buffer));
+}
+#endif /* GRN_SUPPORT_REGEXP */
+
+static grn_bool
+grn_expr_executor_is_proc(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_expr *e = (grn_expr *)expr;
+ grn_obj *first;
+ grn_proc *proc;
+
+ if (e->codes_curr < 2) {
+ return GRN_FALSE;
+ }
+
+ first = e->codes[0].value;
+ if (!grn_obj_is_function_proc(ctx, first)) {
+ return GRN_FALSE;
+ }
+
+ proc = (grn_proc *)first;
+ if (!(proc->funcs[PROC_INIT] &&
+ proc->funcs[PROC_NEXT])) {
+ return GRN_FALSE;
+ }
+
+ if (e->codes[e->codes_curr - 1].op != GRN_OP_CALL) {
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+static void
+grn_expr_executor_init_proc(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ grn_proc_ctx *proc_ctx = &(executor->data.proc.proc_ctx);
+ grn_expr *expr;
+ grn_proc *proc;
+
+ expr = (grn_expr *)(executor->expr);
+ proc = (grn_proc *)(expr->codes[0].value);
+ proc_ctx->proc = proc;
+ proc_ctx->caller = executor->expr;
+ proc_ctx->phase = PROC_INIT;
+
+ executor->data.proc.n_args = expr->codes[expr->codes_curr - 1].nargs - 1;
+
+ proc->funcs[PROC_INIT](ctx, 0, NULL, &(proc_ctx->user_data));
+}
+
+static grn_obj *
+grn_expr_executor_exec_proc(grn_ctx *ctx,
+ grn_expr_executor *executor,
+ grn_id id)
+{
+ grn_proc_ctx *proc_ctx = &(executor->data.proc.proc_ctx);
+ int n_args = executor->data.proc.n_args;
+ grn_proc *proc;
+ grn_expr *expr;
+ grn_obj **args;
+ uint32_t values_curr;
+ uint32_t values_tail;
+ grn_obj *result;
+
+ proc = proc_ctx->proc;
+ proc_ctx->phase = PROC_NEXT;
+ GRN_RECORD_SET(ctx, executor->variable, id);
+
+ expr = (grn_expr *)(executor->expr);
+ values_curr = expr->values_curr;
+ values_tail = expr->values_tail;
+
+ expr->codes += 1;
+ expr->codes_curr -= 2;
+ grn_expr_exec(ctx, executor->expr, 0);
+ expr->codes_curr += 2;
+ expr->codes -= 1;
+
+ args = ctx->impl->stack + ctx->impl->stack_curr;
+ ctx->impl->stack_curr += n_args;
+ expr->values_curr = expr->values_tail;
+ result = proc->funcs[PROC_NEXT](ctx,
+ n_args,
+ args,
+ &(proc_ctx->user_data));
+ ctx->impl->stack_curr -= n_args;
+
+ expr->values_tail = values_tail;
+ expr->values_curr = values_curr;
+
+ return result;
+}
+
+static void
+grn_expr_executor_fin_proc(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ grn_proc_ctx *proc_ctx = &(executor->data.proc.proc_ctx);
+ grn_proc *proc;
+
+ proc = proc_ctx->proc;
+ proc_ctx->phase = PROC_FIN;
+ if (proc->funcs[PROC_FIN]) {
+ proc->funcs[PROC_FIN](ctx, 0, NULL, &(proc_ctx->user_data));
+ }
+}
+
+static grn_bool
+grn_expr_executor_is_simple_condition_ra(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_expr *e = (grn_expr *)expr;
+ grn_expr_code *target;
+ grn_expr_code *constant;
+ grn_expr_code *operator;
+
+ if (e->codes_curr != 3) {
+ return GRN_FALSE;
+ }
+
+ target = &(e->codes[0]);
+ constant = &(e->codes[1]);
+ operator = &(e->codes[2]);
+
+ switch (operator->op) {
+ case GRN_OP_EQUAL :
+ case GRN_OP_NOT_EQUAL :
+ case GRN_OP_LESS :
+ case GRN_OP_GREATER :
+ case GRN_OP_LESS_EQUAL :
+ case GRN_OP_GREATER_EQUAL :
+ break;
+ default :
+ return GRN_FALSE;
+ }
+ if (operator->nargs != 2) {
+ return GRN_FALSE;
+ }
+
+ if (target->op != GRN_OP_GET_VALUE) {
+ return GRN_FALSE;
+ }
+ if (target->nargs != 1) {
+ return GRN_FALSE;
+ }
+ if (target->value->header.type != GRN_COLUMN_FIX_SIZE) {
+ return GRN_FALSE;
+ }
+
+ if (constant->op != GRN_OP_PUSH) {
+ return GRN_FALSE;
+ }
+ if (constant->nargs != 1) {
+ return GRN_FALSE;
+ }
+ if (!constant->value) {
+ return GRN_FALSE;
+ }
+ if (constant->value->header.type != GRN_BULK) {
+ return GRN_FALSE;
+ }
+
+ {
+ grn_obj constant_buffer;
+ grn_rc rc;
+ GRN_VOID_INIT(&constant_buffer);
+ grn_obj_reinit_for(ctx, &constant_buffer, target->value);
+ rc = grn_obj_cast(ctx, constant->value, &constant_buffer, GRN_FALSE);
+ GRN_OBJ_FIN(ctx, &constant_buffer);
+ if (rc != GRN_SUCCESS) {
+ return GRN_FALSE;
+ }
+ }
+
+ return GRN_TRUE;
+}
+
+static void
+grn_expr_executor_init_simple_condition_ra(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ grn_expr *e = (grn_expr *)(executor->expr);
+ grn_obj *target;
+ grn_obj *constant;
+ grn_operator op;
+ grn_obj *result_buffer;
+ grn_obj *value_buffer;
+ grn_obj *constant_buffer;
+
+ target = e->codes[0].value;
+ constant = e->codes[1].value;
+ op = e->codes[2].op;
+
+ result_buffer = &(executor->data.simple_condition_ra.result_buffer);
+ GRN_BOOL_INIT(result_buffer, 0);
+ GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
+
+ value_buffer = &(executor->data.simple_condition_ra.value_buffer);
+ GRN_VOID_INIT(value_buffer);
+ grn_obj_reinit_for(ctx, value_buffer, target);
+
+ executor->data.simple_condition_ra.ra = (grn_ra *)target;
+ GRN_RA_CACHE_INIT(executor->data.simple_condition_ra.ra,
+ &(executor->data.simple_condition_ra.ra_cache));
+ grn_ra_info(ctx,
+ executor->data.simple_condition_ra.ra,
+ &(executor->data.simple_condition_ra.ra_element_size));
+
+ executor->data.simple_condition_ra.exec = grn_operator_to_exec_func(op);
+
+ constant_buffer = &(executor->data.simple_condition_ra.constant_buffer);
+ GRN_VOID_INIT(constant_buffer);
+ grn_obj_reinit_for(ctx, constant_buffer, target);
+ grn_obj_cast(ctx, constant, constant_buffer, GRN_FALSE);
+}
+
+static grn_obj *
+grn_expr_executor_exec_simple_condition_ra(grn_ctx *ctx,
+ grn_expr_executor *executor,
+ grn_id id)
+{
+ grn_obj *result_buffer = &(executor->data.simple_condition_ra.result_buffer);
+ grn_obj *value_buffer = &(executor->data.simple_condition_ra.value_buffer);
+ grn_obj *constant_buffer =
+ &(executor->data.simple_condition_ra.constant_buffer);
+
+ if (ctx->rc) {
+ GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
+ return result_buffer;
+ }
+
+ {
+ grn_ra *ra = executor->data.simple_condition_ra.ra;
+ grn_ra_cache *ra_cache = &(executor->data.simple_condition_ra.ra_cache);
+ unsigned int ra_element_size =
+ executor->data.simple_condition_ra.ra_element_size;
+ void *raw_value;
+ raw_value = grn_ra_ref_cache(ctx, ra, id, ra_cache);
+ GRN_BULK_REWIND(value_buffer);
+ grn_bulk_write(ctx, value_buffer, raw_value, ra_element_size);
+ }
+
+ if (executor->data.simple_condition_ra.exec(ctx,
+ value_buffer,
+ constant_buffer)) {
+ GRN_BOOL_SET(ctx, result_buffer, GRN_TRUE);
+ } else {
+ GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
+ }
+ return result_buffer;
+}
+
+static void
+grn_expr_executor_fin_simple_condition_ra(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ GRN_OBJ_FIN(ctx, &(executor->data.simple_condition_ra.result_buffer));
+ GRN_RA_CACHE_FIN(executor->data.simple_condition_ra.ra,
+ &(executor->data.simple_condition_ra.ra_cache));
+ GRN_OBJ_FIN(ctx, &(executor->data.simple_condition_ra.value_buffer));
+ GRN_OBJ_FIN(ctx, &(executor->data.simple_condition_ra.constant_buffer));
+}
+
+static grn_bool
+grn_expr_executor_is_simple_condition(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_expr *e = (grn_expr *)expr;
+ grn_expr_code *target;
+ grn_expr_code *constant;
+ grn_expr_code *operator;
+
+ if (e->codes_curr != 3) {
+ return GRN_FALSE;
+ }
+
+ target = &(e->codes[0]);
+ constant = &(e->codes[1]);
+ operator = &(e->codes[2]);
+
+ switch (operator->op) {
+ case GRN_OP_EQUAL :
+ case GRN_OP_NOT_EQUAL :
+ case GRN_OP_LESS :
+ case GRN_OP_GREATER :
+ case GRN_OP_LESS_EQUAL :
+ case GRN_OP_GREATER_EQUAL :
+ break;
+ default :
+ return GRN_FALSE;
+ }
+ if (operator->nargs != 2) {
+ return GRN_FALSE;
+ }
+
+ if (target->op != GRN_OP_GET_VALUE) {
+ return GRN_FALSE;
+ }
+ if (target->nargs != 1) {
+ return GRN_FALSE;
+ }
+ if (!grn_obj_is_scalar_column(ctx, target->value)) {
+ return GRN_FALSE;
+ }
+
+ if (constant->op != GRN_OP_PUSH) {
+ return GRN_FALSE;
+ }
+ if (constant->nargs != 1) {
+ return GRN_FALSE;
+ }
+ if (!constant->value) {
+ return GRN_FALSE;
+ }
+ if (constant->value->header.type != GRN_BULK) {
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+static void
+grn_expr_executor_init_simple_condition(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ grn_expr *e = (grn_expr *)(executor->expr);
+ grn_obj *target;
+ grn_obj *constant;
+ grn_operator op;
+ grn_obj *result_buffer;
+ grn_obj *value_buffer;
+ grn_obj *constant_buffer;
+ grn_rc rc;
+
+ target = e->codes[0].value;
+ constant = e->codes[1].value;
+ op = e->codes[2].op;
+
+ executor->data.simple_condition.need_exec = GRN_TRUE;
+
+ result_buffer = &(executor->data.simple_condition.result_buffer);
+ GRN_BOOL_INIT(result_buffer, 0);
+ GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
+
+ value_buffer = &(executor->data.simple_condition.value_buffer);
+ GRN_VOID_INIT(value_buffer);
+ grn_obj_reinit_for(ctx, value_buffer, target);
+
+ executor->data.simple_condition.exec = grn_operator_to_exec_func(op);
+
+ constant_buffer = &(executor->data.simple_condition.constant_buffer);
+ GRN_VOID_INIT(constant_buffer);
+ grn_obj_reinit_for(ctx, constant_buffer, target);
+ rc = grn_obj_cast(ctx, constant, constant_buffer, GRN_FALSE);
+ if (rc != GRN_SUCCESS) {
+ grn_obj *type;
+
+ type = grn_ctx_at(ctx, constant_buffer->header.domain);
+ if (grn_obj_is_table(ctx, type)) {
+ GRN_BOOL_SET(ctx, result_buffer, (op == GRN_OP_NOT_EQUAL));
+ executor->data.simple_condition.need_exec = GRN_FALSE;
+ } else {
+ int type_name_size;
+ char type_name[GRN_TABLE_MAX_KEY_SIZE];
+ grn_obj inspected;
+
+ type_name_size = grn_obj_name(ctx, type, type_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, constant);
+ ERR(rc,
+ "[expr-executor][condition] "
+ "failed to cast to <%.*s>: <%.*s>",
+ type_name_size, type_name,
+ (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected));
+ }
+ }
+}
+
+static grn_obj *
+grn_expr_executor_exec_simple_condition(grn_ctx *ctx,
+ grn_expr_executor *executor,
+ grn_id id)
+{
+ grn_expr *e = (grn_expr *)(executor->expr);
+ grn_obj *target;
+ grn_obj *result_buffer = &(executor->data.simple_condition.result_buffer);
+ grn_obj *value_buffer = &(executor->data.simple_condition.value_buffer);
+ grn_obj *constant_buffer = &(executor->data.simple_condition.constant_buffer);
+
+ if (ctx->rc) {
+ GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
+ return result_buffer;
+ }
+
+ if (!executor->data.simple_condition.need_exec) {
+ return result_buffer;
+ }
+
+ target = e->codes[0].value;
+ GRN_BULK_REWIND(value_buffer);
+ grn_obj_get_value(ctx, target, id, value_buffer);
+
+ if (executor->data.simple_condition.exec(ctx, value_buffer, constant_buffer)) {
+ GRN_BOOL_SET(ctx, result_buffer, GRN_TRUE);
+ } else {
+ GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
+ }
+ return result_buffer;
+}
+
+static void
+grn_expr_executor_fin_simple_condition(grn_ctx *ctx,
+ grn_expr_executor *executor)
+{
+ GRN_OBJ_FIN(ctx, &(executor->data.simple_condition.result_buffer));
+ GRN_OBJ_FIN(ctx, &(executor->data.simple_condition.value_buffer));
+ GRN_OBJ_FIN(ctx, &(executor->data.simple_condition.constant_buffer));
+}
+
+grn_expr_executor *
+grn_expr_executor_open(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_obj *variable;
+ grn_expr_executor *executor;
+
+ GRN_API_ENTER;
+
+ if (!grn_obj_is_expr(ctx, expr)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, expr);
+ ERR(ctx->rc,
+ "[expr-executor][open] invalid expression: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ GRN_API_RETURN(NULL);
+ }
+
+ variable = grn_expr_get_var_by_offset(ctx, expr, 0);
+ if (!variable) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, expr);
+ ERR(ctx->rc,
+ "[expr-executor][open] expression has no variable: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ GRN_API_RETURN(NULL);
+ }
+
+ executor = GRN_CALLOC(sizeof(grn_expr_executor));
+ if (!executor) {
+ ERR(ctx->rc,
+ "[expr-executor][open] failed to allocate: %s",
+ ctx->errbuf);
+ GRN_API_RETURN(NULL);
+ }
+
+ executor->expr = expr;
+ executor->variable = variable;
+ if (grn_expr_executor_is_constant(ctx, expr)) {
+ grn_expr_executor_init_constant(ctx, executor);
+ executor->exec = grn_expr_executor_exec_constant;
+ executor->fin = grn_expr_executor_fin_constant;
+ } else if (grn_expr_executor_is_value(ctx, expr)) {
+ grn_expr_executor_init_value(ctx, executor);
+ executor->exec = grn_expr_executor_exec_value;
+ executor->fin = grn_expr_executor_fin_value;
+#ifdef GRN_SUPPORT_REGEXP
+ } else if (grn_expr_executor_is_simple_regexp(ctx, expr)) {
+ grn_expr_executor_init_simple_regexp(ctx, executor);
+ executor->exec = grn_expr_executor_exec_simple_regexp;
+ executor->fin = grn_expr_executor_fin_simple_regexp;
+#endif /* GRN_SUPPORT_REGEXP */
+ } else if (grn_expr_executor_is_proc(ctx, expr)) {
+ grn_expr_executor_init_proc(ctx, executor);
+ executor->exec = grn_expr_executor_exec_proc;
+ executor->fin = grn_expr_executor_fin_proc;
+ } else if (grn_expr_executor_is_simple_condition_ra(ctx, expr)) {
+ grn_expr_executor_init_simple_condition_ra(ctx, executor);
+ executor->exec = grn_expr_executor_exec_simple_condition_ra;
+ executor->fin = grn_expr_executor_fin_simple_condition_ra;
+ } else if (grn_expr_executor_is_simple_condition(ctx, expr)) {
+ grn_expr_executor_init_simple_condition(ctx, executor);
+ executor->exec = grn_expr_executor_exec_simple_condition;
+ executor->fin = grn_expr_executor_fin_simple_condition;
+ } else {
+ grn_expr_executor_init_general(ctx, executor);
+ executor->exec = grn_expr_executor_exec_general;
+ executor->fin = grn_expr_executor_fin_general;
+ }
+
+ GRN_API_RETURN(executor);
+}
+
+grn_obj *
+grn_expr_executor_exec(grn_ctx *ctx, grn_expr_executor *executor, grn_id id)
+{
+ grn_obj *value;
+
+ GRN_API_ENTER;
+
+ if (!executor) {
+ GRN_API_RETURN(NULL);
+ }
+
+ value = executor->exec(ctx, executor, id);
+
+ GRN_API_RETURN(value);
+}
+
+grn_rc
+grn_expr_executor_close(grn_ctx *ctx, grn_expr_executor *executor)
+{
+ GRN_API_ENTER;
+
+ if (!executor) {
+ GRN_API_RETURN(GRN_SUCCESS);
+ }
+
+ executor->fin(ctx, executor);
+ GRN_FREE(executor);
+
+ GRN_API_RETURN(GRN_SUCCESS);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/file_lock.c b/storage/mroonga/vendor/groonga/lib/file_lock.c
new file mode 100644
index 00000000000..3f00e45a93a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/file_lock.c
@@ -0,0 +1,121 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_file_lock.h"
+#include "grn_ctx.h"
+
+#include <sys/stat.h>
+
+#ifdef WIN32
+# include <io.h>
+# include <share.h>
+#else /* WIN32 */
+# include <sys/types.h>
+# include <fcntl.h>
+#endif /* WIN32 */
+
+#ifdef WIN32
+# define GRN_FILE_LOCK_IS_INVALID(file_lock) \
+ ((file_lock)->handle == INVALID_HANDLE_VALUE)
+#else /* WIN32 */
+# define GRN_FILE_LOCK_IS_INVALID(file_lock) \
+ ((file_lock)->fd == -1)
+#endif /* WIN32 */
+
+void
+grn_file_lock_init(grn_ctx *ctx,
+ grn_file_lock *file_lock,
+ const char *path)
+{
+ file_lock->path = path;
+#ifdef WIN32
+ file_lock->handle = INVALID_HANDLE_VALUE;
+#else /* WIN32 */
+ file_lock->fd = -1;
+#endif /* WIN32 */
+}
+
+grn_bool
+grn_file_lock_acquire(grn_ctx *ctx,
+ grn_file_lock *file_lock,
+ int timeout,
+ const char *error_message_tag)
+{
+ int i;
+ int n_lock_tries = timeout;
+
+ if (!file_lock->path) {
+ return GRN_TRUE;
+ }
+
+ for (i = 0; i < n_lock_tries; i++) {
+#ifdef WIN32
+ file_lock->handle = CreateFile(file_lock->path,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+#else /* WIN32 */
+ file_lock->fd = open(file_lock->path, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+#endif
+ if (!GRN_FILE_LOCK_IS_INVALID(file_lock)) {
+ break;
+ }
+ grn_nanosleep(GRN_LOCK_WAIT_TIME_NANOSECOND);
+ }
+
+ if (GRN_FILE_LOCK_IS_INVALID(file_lock)) {
+ ERR(GRN_NO_LOCKS_AVAILABLE,
+ "%s failed to acquire lock: <%s>",
+ error_message_tag, file_lock->path);
+ return GRN_FALSE;
+ } else {
+ return GRN_TRUE;
+ }
+}
+
+void
+grn_file_lock_release(grn_ctx *ctx, grn_file_lock *file_lock)
+{
+ if (GRN_FILE_LOCK_IS_INVALID(file_lock)) {
+ return;
+ }
+
+#ifdef WIN32
+ CloseHandle(file_lock->handle);
+ DeleteFile(file_lock->path);
+
+ file_lock->handle = INVALID_HANDLE_VALUE;
+#else /* WIN32 */
+ close(file_lock->fd);
+ unlink(file_lock->path);
+
+ file_lock->fd = -1;
+#endif /* WIN32 */
+ file_lock->path = NULL;
+}
+
+void
+grn_file_lock_fin(grn_ctx *ctx, grn_file_lock *file_lock)
+{
+ if (!GRN_FILE_LOCK_IS_INVALID(file_lock)) {
+ grn_file_lock_release(ctx, file_lock);
+ }
+}
diff --git a/storage/mroonga/vendor/groonga/lib/file_reader.c b/storage/mroonga/vendor/groonga/lib/file_reader.c
new file mode 100644
index 00000000000..b19a626d751
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/file_reader.c
@@ -0,0 +1,109 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_ctx.h"
+#include "grn_str.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef WIN32
+# include <share.h>
+#endif /* WIN32 */
+
+struct _grn_file_reader {
+ FILE *file;
+ grn_bool file_need_close;
+};
+
+grn_file_reader *
+grn_file_reader_open(grn_ctx *ctx, const char *path)
+{
+ grn_file_reader *reader;
+ FILE *file;
+ grn_bool file_need_close;
+
+ GRN_API_ENTER;
+
+ if (!path) {
+ ERR(GRN_INVALID_ARGUMENT, "[file-reader][open] path must not NULL");
+ GRN_API_RETURN(NULL);
+ }
+
+ if (strcmp(path, "-") == 0) {
+ file = stdin;
+ file_need_close = GRN_FALSE;
+ } else {
+ file = grn_fopen(path, "r");
+ if (!file) {
+ SERR("[file-reader][open] failed to open path: <%s>", path);
+ GRN_API_RETURN(NULL);
+ }
+ file_need_close = GRN_TRUE;
+ }
+
+ reader = GRN_MALLOC(sizeof(grn_file_reader));
+ reader->file = file;
+ reader->file_need_close = file_need_close;
+
+ GRN_API_RETURN(reader);
+}
+
+void
+grn_file_reader_close(grn_ctx *ctx, grn_file_reader *reader)
+{
+ if (!reader) {
+ return;
+ }
+
+ if (reader->file_need_close) {
+ if (fclose(reader->file) != 0) {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "[file-reader][close] failed to close: <%s>",
+ grn_strerror(errno));
+ }
+ }
+
+ GRN_FREE(reader);
+}
+
+grn_rc
+grn_file_reader_read_line(grn_ctx *ctx,
+ grn_file_reader *reader,
+ grn_obj *buffer)
+{
+ grn_rc rc = GRN_END_OF_DATA;
+
+ for (;;) {
+ size_t len;
+
+#define BUFFER_SIZE 4096
+ grn_bulk_reserve(ctx, buffer, BUFFER_SIZE);
+ if (!fgets(GRN_BULK_CURR(buffer), BUFFER_SIZE, reader->file)) {
+ break;
+ }
+#undef BUFFER_SIZE
+
+ if (!(len = strlen(GRN_BULK_CURR(buffer)))) { break; }
+ GRN_BULK_INCR_LEN(buffer, len);
+ rc = GRN_SUCCESS;
+ if (GRN_BULK_CURR(buffer)[-1] == '\n') { break; }
+ }
+
+ return rc;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/geo.c b/storage/mroonga/vendor/groonga/lib/geo.c
index d2eb049ce21..deb8399d6d7 100644
--- a/storage/mroonga/vendor/groonga/lib/geo.c
+++ b/storage/mroonga/vendor/groonga/lib/geo.c
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2013 Brazil
+/*
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -280,7 +281,7 @@ grn_geo_table_sort_detect_far_point(grn_ctx *ctx, grn_obj *table, grn_obj *index
while ((tid = grn_pat_cursor_next(ctx, pc))) {
grn_ii_cursor *ic = grn_ii_cursor_open(ctx, (grn_ii *)index, tid, 0, 0, 1, 0);
if (ic) {
- grn_ii_posting *posting;
+ grn_posting *posting;
grn_gton(geo_key_prev, &point, sizeof(grn_geo_point));
grn_pat_get_key(ctx, pat, tid, &point, sizeof(grn_geo_point));
grn_gton(geo_key_curr, &point, sizeof(grn_geo_point));
@@ -553,7 +554,7 @@ grn_geo_table_sort_collect_points(grn_ctx *ctx, grn_obj *table, grn_obj *index,
if (ic) {
double d;
grn_geo_point pos;
- grn_ii_posting *posting;
+ grn_posting *posting;
grn_pat_get_key(ctx, pat, tid, &pos, sizeof(grn_geo_point));
d = grn_geo_distance_rectangle_raw(ctx, base_point, &pos);
inspect_tid(ctx, tid, &pos, d);
@@ -686,25 +687,65 @@ grn_geo_table_sort_by_distance(grn_ctx *ctx,
int
grn_geo_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit,
- grn_obj *result, grn_table_sort_key *keys, int n_keys)
+ grn_obj *result, grn_obj *column, grn_obj *geo_point)
{
grn_obj *index;
- int i = 0, e = offset + limit;
- grn_bool accessorp = GRN_ACCESSORP(keys->key);
- if (n_keys == 2 && (index = find_geo_sort_index(ctx, keys->key))) {
+ int i = 0;
+
+ GRN_API_ENTER;
+
+ if (offset < 0 || limit < 0) {
+ unsigned int size;
+ grn_rc rc;
+ size = grn_table_size(ctx, table);
+ rc = grn_normalize_offset_and_limit(ctx, size, &offset, &limit);
+ if (rc != GRN_SUCCESS) {
+ ERR(rc,
+ "[sort][geo] failed to normalize offset and limit: "
+ "offset:%d limit:%d table-size:%u",
+ offset, limit, size);
+ GRN_API_RETURN(i);
+ }
+ }
+
+ if ((index = find_geo_sort_index(ctx, column))) {
grn_id tid;
- grn_obj *arg = keys[1].key;
grn_pat *pat = (grn_pat *)grn_ctx_at(ctx, index->header.domain);
- grn_id domain = pat->obj.header.domain;
- grn_pat_cursor *pc = grn_pat_cursor_open(ctx, pat, NULL, 0,
- GRN_BULK_HEAD(arg), GRN_BULK_VSIZE(arg),
- 0, -1, GRN_CURSOR_PREFIX);
+ grn_id domain;
+ grn_pat_cursor *pc;
+ if (!pat) {
+ char index_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_name_size;
+ char lexicon_name[GRN_TABLE_MAX_KEY_SIZE];
+ int lexicon_name_size;
+ index_name_size = grn_obj_name(ctx,
+ index,
+ index_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ lexicon_name_size = grn_table_get_key(ctx,
+ grn_ctx_db(ctx),
+ index->header.domain,
+ lexicon_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_OBJECT_CORRUPT,
+ "[sort][geo] lexicon is broken: <%.*s>: <%.*s>(%d)",
+ index_name_size, index_name,
+ lexicon_name_size, lexicon_name,
+ index->header.domain);
+ GRN_API_RETURN(i);
+ }
+ domain = pat->obj.header.domain;
+ pc = grn_pat_cursor_open(ctx, pat, NULL, 0,
+ GRN_BULK_HEAD(geo_point),
+ GRN_BULK_VSIZE(geo_point),
+ 0, -1, GRN_CURSOR_PREFIX);
if (pc) {
if (domain != GRN_DB_TOKYO_GEO_POINT && domain != GRN_DB_WGS84_GEO_POINT) {
+ int e = offset + limit;
while (i < e && (tid = grn_pat_cursor_next(ctx, pc))) {
grn_ii_cursor *ic = grn_ii_cursor_open(ctx, (grn_ii *)index, tid, 0, 0, 1, 0);
if (ic) {
- grn_ii_posting *posting;
+ grn_posting *posting;
while (i < e && (posting = grn_ii_cursor_next(ctx, ic))) {
if (offset <= i) {
grn_id *v;
@@ -717,15 +758,17 @@ grn_geo_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit,
}
}
} else {
- grn_geo_point *base_point = (grn_geo_point *)GRN_BULK_HEAD(arg);
+ grn_geo_point *base_point = (grn_geo_point *)GRN_BULK_HEAD(geo_point);
i = grn_geo_table_sort_by_distance(ctx, table, index, pat,
- pc, accessorp, base_point,
+ pc,
+ GRN_ACCESSORP(column),
+ base_point,
offset, limit, result);
}
grn_pat_cursor_close(ctx, pc);
}
}
- return i;
+ GRN_API_RETURN(i);
}
grn_rc
@@ -789,7 +832,7 @@ grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *table, grn_obj *index,
point_column = args[1];
column_name_size = grn_obj_name(ctx, point_column,
column_name, GRN_TABLE_MAX_KEY_SIZE);
- ERR(GRN_INVALID_ARGUMENT,
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
"geo_in_circle(): index for <%.*s> is missing",
column_name_size, column_name);
return ctx->rc;
@@ -852,6 +895,27 @@ grn_geo_select_in_circle(grn_ctx *ctx, grn_obj *index,
grn_geo_point *center, on_circle;
grn_geo_distance_raw_func distance_raw_func;
pat = grn_ctx_at(ctx, index->header.domain);
+ if (!pat) {
+ char index_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_name_size;
+ char lexicon_name[GRN_TABLE_MAX_KEY_SIZE];
+ int lexicon_name_size;
+ index_name_size = grn_obj_name(ctx,
+ index,
+ index_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ lexicon_name_size = grn_table_get_key(ctx,
+ grn_ctx_db(ctx),
+ index->header.domain,
+ lexicon_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_OBJECT_CORRUPT,
+ "geo_in_circle(): lexicon is broken: <%.*s>: <%.*s>(%d)",
+ index_name_size, index_name,
+ lexicon_name_size, lexicon_name,
+ index->header.domain);
+ goto exit;
+ }
domain = pat->header.domain;
if (domain != GRN_DB_TOKYO_GEO_POINT && domain != GRN_DB_WGS84_GEO_POINT) {
char name[GRN_TABLE_MAX_KEY_SIZE];
@@ -1024,6 +1088,29 @@ in_rectangle_data_fill(grn_ctx *ctx, grn_obj *index,
const char *domain_name;
data->pat = grn_ctx_at(ctx, index->header.domain);
+ if (!data->pat) {
+ char index_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_name_size;
+ char lexicon_name[GRN_TABLE_MAX_KEY_SIZE];
+ int lexicon_name_size;
+ index_name_size = grn_obj_name(ctx,
+ index,
+ index_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ lexicon_name_size = grn_table_get_key(ctx,
+ grn_ctx_db(ctx),
+ index->header.domain,
+ lexicon_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_OBJECT_CORRUPT,
+ "%s: lexicon lexicon is broken: <%.*s>: <%.*s>(%d)",
+ process_name,
+ index_name_size, index_name,
+ lexicon_name_size, lexicon_name,
+ index->header.domain);
+ return;
+ }
+
domain = data->pat->header.domain;
if (domain != GRN_DB_TOKYO_GEO_POINT && domain != GRN_DB_WGS84_GEO_POINT) {
char name[GRN_TABLE_MAX_KEY_SIZE];
@@ -1243,7 +1330,8 @@ in_rectangle_data_prepare(grn_ctx *ctx, grn_obj *index,
in_rectangle_data *data)
{
if (!index) {
- ERR(GRN_INVALID_ARGUMENT, "%s: index column is missing", process_name);
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "%s: index column is missing", process_name);
goto exit;
}
@@ -1788,7 +1876,7 @@ grn_geo_cursor_entry_next(grn_ctx *ctx,
return GRN_TRUE;
}
-typedef grn_bool (*grn_geo_cursor_callback)(grn_ctx *ctx, grn_ii_posting *posting, void *user_data);
+typedef grn_bool (*grn_geo_cursor_callback)(grn_ctx *ctx, grn_posting *posting, void *user_data);
static void
grn_geo_cursor_each(grn_ctx *ctx, grn_obj *geo_cursor,
@@ -1799,7 +1887,7 @@ grn_geo_cursor_each(grn_ctx *ctx, grn_obj *geo_cursor,
grn_table_cursor *pat_cursor;
grn_ii *ii;
grn_ii_cursor *ii_cursor;
- grn_ii_posting *posting = NULL;
+ grn_posting *posting = NULL;
grn_geo_point *current, *top_left, *bottom_right;
grn_id index_id;
@@ -1886,10 +1974,10 @@ grn_geo_cursor_each(grn_ctx *ctx, grn_obj *geo_cursor,
}
static grn_bool
-grn_geo_cursor_next_callback(grn_ctx *ctx, grn_ii_posting *posting,
+grn_geo_cursor_next_callback(grn_ctx *ctx, grn_posting *posting,
void *user_data)
{
- grn_ii_posting **return_posting = user_data;
+ grn_posting **return_posting = user_data;
*return_posting = posting;
return GRN_FALSE;
}
@@ -1897,7 +1985,7 @@ grn_geo_cursor_next_callback(grn_ctx *ctx, grn_ii_posting *posting,
grn_posting *
grn_geo_cursor_next(grn_ctx *ctx, grn_obj *geo_cursor)
{
- grn_ii_posting *posting = NULL;
+ grn_posting *posting = NULL;
grn_geo_cursor_each(ctx, geo_cursor, grn_geo_cursor_next_callback, &posting);
return (grn_posting *)posting;
}
@@ -1925,7 +2013,7 @@ typedef struct {
} grn_geo_select_in_rectangle_data;
static grn_bool
-grn_geo_select_in_rectangle_callback(grn_ctx *ctx, grn_ii_posting *posting,
+grn_geo_select_in_rectangle_callback(grn_ctx *ctx, grn_posting *posting,
void *user_data)
{
grn_geo_select_in_rectangle_data *data = user_data;
diff --git a/storage/mroonga/vendor/groonga/lib/grn.h b/storage/mroonga/vendor/groonga/lib/grn.h
index 80622a8421b..0d0768eba41 100644
--- a/storage/mroonga/vendor/groonga/lib/grn.h
+++ b/storage/mroonga/vendor/groonga/lib/grn.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,26 +17,48 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_H
-#define GRN_H
+#pragma once
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
-#if defined(WIN32) && defined(__GNUC__)
-# define __MINGW_MSVC_COMPAT_WARNINGS
-#endif /* defined(WIN32) && defined(__GNUC__) */
+#ifdef WIN32
+# ifdef __GNUC__
+# define __MINGW_MSVC_COMPAT_WARNINGS
+# endif /* __GNUC__ */
+
+# ifdef __GNUC__
+# include <w32api.h>
+# define GRN_MINIMUM_WINDOWS_VERSION WindowsVista
+# else /* __GNUC__ */
+# define GRN_MINIMUM_WINDOWS_VERSION 0x0600 /* Vista */
+# endif /* __GNUC__ */
+
+# ifdef WINVER
+# undef WINVER
+# endif /* WINVER */
+# define WINVER GRN_MINIMUM_WINDOWS_VERSION
+# ifdef _WIN32_WINNT
+# undef _WIN32_WINNT
+# endif /* _WIN32_WINNT */
+# define _WIN32_WINNT GRN_MINIMUM_WINDOWS_VERSION
+# ifdef NTDDI_VERSION
+# undef NTDDI_VERSION
+# endif /* NTDDI_VERSION */
+# define NTDDI_VERSION GRN_MINIMUM_WINDOWS_VERSION
+
+# ifdef WIN32_LEAN_AND_MEAN
+# undef WIN32_LEAN_AND_MEAN
+# endif /* WIN32_LEAN_AND_MEAN */
+#endif /* WIN32 */
#ifdef __cplusplus
# define __STDC_LIMIT_MACROS
#endif
#include <stdlib.h>
-
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif /* HAVE_STDINT_H */
+#include <stdint.h>
#include <sys/types.h>
@@ -57,23 +80,17 @@
#ifdef WIN32
# define GRN_API __declspec(dllexport)
-#ifdef GROONGA_MAIN
-# define GRN_VAR __declspec(dllimport)
-#else
-# define GRN_VAR __declspec(dllexport) extern
-#endif /* GROONGA_MAIN */
+# ifdef GROONGA_MAIN
+# define GRN_VAR __declspec(dllimport)
+# else
+# define GRN_VAR __declspec(dllexport) extern
+# endif /* GROONGA_MAIN */
#else
# define GRN_API
# define GRN_VAR extern
#endif
#ifdef WIN32
-
-# if defined(__GNUC__) && !defined(WINVER)
-# include <w32api.h>
-# define WINVER WindowsXP
-# endif /* defined(__GNUC__) && !defined(WINVER) */
-
# include <basetsd.h>
# include <process.h>
# include <winsock2.h>
@@ -92,33 +109,7 @@
# endif
# endif
-# if !defined(__GNUC__) && _MSC_VER < 1500
-# define vsnprintf(str, size, format, ap) _vsnprintf(str, size, format, ap)
-# endif /* !defined(__GNUC__) && _MSC_VER < 1500 */
-# define getpid() _getpid()
-# if !defined(__GNUC__) && _MSC_VER < 1400
-# define fstat(fd, buf) _fstat(fd, buf)
-# endif /* !defined(__GNUC__) && _MSC_VER < 1400 */
-# ifdef HAVE__STRICMP
-# ifdef strcasecmp
-# undef strcasecmp
-# endif /* strcasecmp */
-# define strcasecmp(s1, s2) _stricmp(s1, s2)
-# endif /* defined(HAVE__STRICMP) */
-
-# ifdef __GNUC__
-# include <stdint.h>
-# else
-typedef UINT8 uint8_t;
-typedef INT8 int8_t;
-typedef INT8 int_least8_t;
-typedef UINT8 uint_least8_t;
-typedef INT16 int16_t;
-typedef UINT16 uint16_t;
-typedef INT32 int32_t;
-typedef UINT32 uint32_t;
-typedef INT64 int64_t;
-typedef UINT64 uint64_t;
+# ifndef __GNUC__
typedef SSIZE_T ssize_t;
typedef int pid_t;
typedef int64_t off64_t;
@@ -223,10 +214,11 @@ typedef void * grn_thread_func_result;
(pthread_create(&(thread), NULL, (func), (arg)))
# define THREAD_JOIN(thread) (pthread_join(thread, NULL))
typedef pthread_mutex_t grn_mutex;
-# define MUTEX_INIT(m) pthread_mutex_init(&m, NULL)
-# define MUTEX_LOCK(m) pthread_mutex_lock(&m)
-# define MUTEX_UNLOCK(m) pthread_mutex_unlock(&m)
-# define MUTEX_FIN(m)
+# define MUTEX_INIT(m) pthread_mutex_init(&m, NULL)
+# define MUTEX_LOCK(m) pthread_mutex_lock(&m)
+# define MUTEX_LOCK_CHECK(m) (MUTEX_LOCK(m) == 0)
+# define MUTEX_UNLOCK(m) pthread_mutex_unlock(&m)
+# define MUTEX_FIN(m) pthread_mutex_destroy(&m)
# ifdef HAVE_PTHREAD_MUTEXATTR_SETPSHARED
# define MUTEX_INIT_SHARED(m) do {\
pthread_mutexattr_t mutexattr;\
@@ -259,6 +251,7 @@ typedef pthread_cond_t grn_cond;
# else
# define COND_INIT_SHARED COND_INIT
# endif /* HAVE_PTHREAD_CONDATTR_SETPSHARE */
+# define COND_FIN(c) pthread_cond_destroy(&c)
typedef pthread_key_t grn_thread_key;
# define THREAD_KEY_CREATE(key, destr) pthread_key_create(key, destr)
@@ -271,7 +264,7 @@ typedef pthread_key_t grn_thread_key;
#define GRN_TEST_YIELD() do {\
if (((++grn_uyield_count) & (0x20 - 1)) == 0) {\
sched_yield();\
- if(grn_uyield_count > 0x1000) {\
+ if (grn_uyield_count > 0x1000) {\
grn_uyield_count = (uint32_t)time(NULL) % 0x1000;\
}\
}\
@@ -286,7 +279,7 @@ typedef pthread_key_t grn_thread_key;
GRN_TEST_YIELD();\
} while (0)
- #define if(if_cond) \
+ #define if (if_cond) \
if ((((++grn_uyield_count) & (0x100 - 1)) != 0 || (sched_yield() * 0) == 0) && (if_cond))
#define while(while_cond) \
while ((((++grn_uyield_count) & (0x100 - 1)) != 0 || (sched_yield() * 0) == 0) && (while_cond))
@@ -316,10 +309,11 @@ typedef unsigned int grn_thread_func_result;
# define THREAD_JOIN(thread) \
(WaitForSingleObject((HANDLE)(thread), INFINITE) == WAIT_FAILED)
typedef HANDLE grn_mutex;
-# define MUTEX_INIT(m) ((m) = CreateMutex(0, FALSE, NULL))
-# define MUTEX_LOCK(m) WaitForSingleObject((m), INFINITE)
-# define MUTEX_UNLOCK(m) ReleaseMutex(m)
-# define MUTEX_FIN(m) CloseHandle(m)
+# define MUTEX_INIT(m) ((m) = CreateMutex(0, FALSE, NULL))
+# define MUTEX_LOCK(m) WaitForSingleObject((m), INFINITE)
+# define MUTEX_LOCK_CHECK(m) (MUTEX_LOCK(m) == WAIT_OBJECT_0)
+# define MUTEX_UNLOCK(m) ReleaseMutex(m)
+# define MUTEX_FIN(m) CloseHandle(m)
typedef CRITICAL_SECTION grn_critical_section;
# define CRITICAL_SECTION_INIT(cs) InitializeCriticalSection(&(cs))
# define CRITICAL_SECTION_ENTER(cs) EnterCriticalSection(&(cs))
@@ -392,6 +386,12 @@ typedef struct
} \
} while (0)
+# define COND_FIN(c) do { \
+ CloseHandle((c).waiters_done_); \
+ MUTEX_FIN((c).waiters_count_lock_); \
+ CloseHandle((c).sema_); \
+} while (0)
+
# else /* WIN32 */
/* todo */
typedef int grn_cond;
@@ -402,6 +402,7 @@ typedef int grn_cond;
grn_nanosleep(1000000); \
MUTEX_LOCK(m); \
} while (0)
+# define COND_FIN(c)
/* todo : must be enhanced! */
# endif /* WIN32 */
@@ -413,6 +414,20 @@ typedef int grn_cond;
#endif /* HAVE_PTHREAD_H */
+#define MUTEX_LOCK_ENSURE(ctx_, mutex) do { \
+ grn_ctx *ctx__ = (ctx_); \
+ do { \
+ grn_ctx *ctx = ctx__; \
+ if (MUTEX_LOCK_CHECK(mutex)) { \
+ break; \
+ } \
+ if (ctx) { \
+ SERR("MUTEX_LOCK"); \
+ } \
+ grn_nanosleep(1000000); \
+ } while (GRN_TRUE); \
+} while (GRN_FALSE)
+
/* format string for printf */
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
@@ -446,8 +461,10 @@ typedef int grn_cond;
# define GRN_FMT_SSIZE "Id"
# ifdef WIN64
# define GRN_FMT_SOCKET GRN_FMT_INT64U
+# define GRN_FMT_DWORD "lu"
# else /* WIN64 */
-# define GRN_FMT_SOCKET "u"
+# define GRN_FMT_SOCKET GRN_FMT_INT32U
+# define GRN_FMT_DWORD "u"
# endif /* WIN64 */
# define GRN_FMT_OFF64_T GRN_FMT_LLD
#else /* WIN32 */
@@ -524,7 +541,7 @@ typedef int grn_cond;
#elif (defined(WIN32) || defined (_WIN64)) /* __GNUC__ */
# define GRN_ATOMIC_ADD_EX(p,i,r) \
- ((r) = (uint32_t)InterlockedExchangeAdd((int32_t *)(p), (int32_t)(i)))
+ ((r) = InterlockedExchangeAdd((p), (i)))
# if defined(_WIN64) /* ATOMIC 64BIT SET */
# define GRN_SET_64BIT(p,v) \
(*(p) = (v))
@@ -734,9 +751,9 @@ grn_str_greater(const uint8_t *ap, uint32_t as, const uint8_t *bp, uint32_t bs)
# endif /* POSIX_HOST_NAME_MAX */
#endif /* HOST_NAME_MAX */
+#define GRN_NEXT_ADDR(p) (((byte *)(p)) + sizeof(*(p)))
+
GRN_API void grn_sleep(uint32_t seconds);
GRN_API void grn_nanosleep(uint64_t nanoseconds);
#include <groonga.h>
-
-#endif /* GRN_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_alloc.h b/storage/mroonga/vendor/groonga/lib/grn_alloc.h
new file mode 100644
index 00000000000..8ea98cdb998
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_alloc.h
@@ -0,0 +1,163 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_alloc_init_from_env(void);
+
+void grn_alloc_init_ctx_impl(grn_ctx *ctx);
+void grn_alloc_fin_ctx_impl(grn_ctx *ctx);
+
+void grn_alloc_info_init(void);
+void grn_alloc_info_fin(void);
+
+void grn_alloc_info_dump(grn_ctx *ctx);
+void grn_alloc_info_free(grn_ctx *ctx);
+
+#define GRN_MALLOC(s) grn_malloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_CALLOC(s) grn_calloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_REALLOC(p,s) grn_realloc(ctx,p,s,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_STRDUP(s) grn_strdup(ctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_GMALLOC(s) grn_malloc(&grn_gctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_GCALLOC(s) grn_calloc(&grn_gctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_GREALLOC(p,s) grn_realloc(&grn_gctx,p,s,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_GSTRDUP(s) grn_strdup(&grn_gctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_FREE(p) grn_free(ctx,p,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_MALLOCN(t,n) ((t *)(GRN_MALLOC(sizeof(t) * (n))))
+#define GRN_GFREE(p) grn_free(&grn_gctx,p,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_GMALLOCN(t,n) ((t *)(GRN_GMALLOC(sizeof(t) * (n))))
+
+#define GRN_CTX_ALLOC(ctx,s) grn_ctx_calloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_CTX_FREE(ctx,p) grn_ctx_free(ctx,p,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_CTX_ALLOC_L(ctx,s) grn_ctx_alloc_lifo(ctx,s,f,__FILE__,__LINE__,__FUNCTION__)
+#define GRN_CTX_FREE_L(ctx,p) grn_ctx_free_lifo(ctx,p,__FILE__,__LINE__,__FUNCTION__)
+
+void *grn_ctx_malloc(grn_ctx *ctx,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(2);
+void *grn_ctx_calloc(grn_ctx *ctx,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(2);
+void *grn_ctx_realloc(grn_ctx *ctx,
+ void *ptr,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(3);
+char *grn_ctx_strdup(grn_ctx *ctx, const char *s,
+ const char* file, int line, const char *func);
+void grn_ctx_free(grn_ctx *ctx, void *ptr,
+ const char* file, int line, const char *func);
+void *grn_ctx_alloc_lifo(grn_ctx *ctx,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(2);
+void grn_ctx_free_lifo(grn_ctx *ctx, void *ptr,
+ const char* file, int line, const char *func);
+
+#ifdef USE_DYNAMIC_MALLOC_CHANGE
+typedef void *(*grn_malloc_func) (grn_ctx *ctx, size_t size,
+ const char *file, int line, const char *func);
+typedef void *(*grn_calloc_func) (grn_ctx *ctx, size_t size,
+ const char *file, int line, const char *func);
+typedef void *(*grn_realloc_func) (grn_ctx *ctx, void *ptr, size_t size,
+ const char *file, int line, const char *func);
+typedef char *(*grn_strdup_func) (grn_ctx *ctx, const char *string,
+ const char *file, int line, const char *func);
+typedef void (*grn_free_func) (grn_ctx *ctx, void *ptr,
+ const char *file, int line, const char *func);
+grn_malloc_func grn_ctx_get_malloc(grn_ctx *ctx);
+void grn_ctx_set_malloc(grn_ctx *ctx, grn_malloc_func malloc_func);
+grn_calloc_func grn_ctx_get_calloc(grn_ctx *ctx);
+void grn_ctx_set_calloc(grn_ctx *ctx, grn_calloc_func calloc_func);
+grn_realloc_func grn_ctx_get_realloc(grn_ctx *ctx);
+void grn_ctx_set_realloc(grn_ctx *ctx, grn_realloc_func realloc_func);
+grn_strdup_func grn_ctx_get_strdup(grn_ctx *ctx);
+void grn_ctx_set_strdup(grn_ctx *ctx, grn_strdup_func strdup_func);
+grn_free_func grn_ctx_get_free(grn_ctx *ctx);
+void grn_ctx_set_free(grn_ctx *ctx, grn_free_func free_func);
+
+void *grn_malloc(grn_ctx *ctx,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(2);
+void *grn_calloc(grn_ctx *ctx,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(2);
+void *grn_realloc(grn_ctx *ctx,
+ void *ptr,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(3);
+char *grn_strdup(grn_ctx *ctx, const char *s, const char* file, int line, const char *func);
+void grn_free(grn_ctx *ctx, void *ptr, const char *file, int line, const char *func);
+#else
+# define grn_malloc grn_malloc_default
+# define grn_calloc grn_calloc_default
+# define grn_realloc grn_realloc_default
+# define grn_strdup grn_strdup_default
+# define grn_free grn_free_default
+#endif
+
+GRN_API void *grn_malloc_default(grn_ctx *ctx,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(2);
+void *grn_calloc_default(grn_ctx *ctx,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(2);
+void *grn_realloc_default(grn_ctx *ctx,
+ void *ptr,
+ size_t size,
+ const char *file,
+ int line,
+ const char *func) GRN_ATTRIBUTE_ALLOC_SIZE(3);
+GRN_API char *grn_strdup_default(grn_ctx *ctx, const char *s, const char* file, int line, const char *func);
+GRN_API void grn_free_default(grn_ctx *ctx, void *ptr, const char* file, int line, const char *func);
+
+#ifdef USE_FAIL_MALLOC
+int grn_fail_malloc_check(size_t size, const char *file, int line, const char *func);
+void *grn_malloc_fail(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
+void *grn_calloc_fail(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
+void *grn_realloc_fail(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
+char *grn_strdup_fail(grn_ctx *ctx, const char *s, const char* file, int line, const char *func);
+#endif
+
+int grn_alloc_count(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_cache.h b/storage/mroonga/vendor/groonga/lib/grn_cache.h
new file mode 100644
index 00000000000..15a36f8176c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_cache.h
@@ -0,0 +1,49 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_CACHE_MAX_KEY_SIZE GRN_HASH_MAX_KEY_SIZE_LARGE
+
+typedef struct {
+ uint32_t nentries;
+ uint32_t max_nentries;
+ uint32_t nfetches;
+ uint32_t nhits;
+} grn_cache_statistics;
+
+void grn_cache_init(void);
+grn_rc grn_cache_fetch(grn_ctx *ctx, grn_cache *cache,
+ const char *str, uint32_t str_size,
+ grn_obj *output);
+void grn_cache_update(grn_ctx *ctx, grn_cache *cache,
+ const char *str, uint32_t str_size, grn_obj *value);
+void grn_cache_expire(grn_cache *cache, int32_t size);
+void grn_cache_fin(void);
+void grn_cache_get_statistics(grn_ctx *ctx, grn_cache *cache,
+ grn_cache_statistics *statistics);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_com.h b/storage/mroonga/vendor/groonga/lib/grn_com.h
index e5ad58981cf..f4077237105 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_com.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_com.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2012 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_COM_H
-#define GRN_COM_H
+#pragma once
#include "grn.h"
#include "grn_str.h"
@@ -83,11 +83,7 @@ GRN_API grn_com_queue_entry *grn_com_queue_deque(grn_ctx *ctx, grn_com_queue *q)
# define GRN_COM_POLLIN EVFILT_READ
# define GRN_COM_POLLOUT EVFILT_WRITE
# else /* USE_KQUEUE */
-# if defined(HAVE_POLL_H)
-# include <poll.h>
-# elif defined(HAVE_SYS_POLL_H)
-# include <sys/poll.h>
-# endif /* defined(HAVE_POLL_H) */
+# include <poll.h>
# define GRN_COM_POLLIN POLLIN
# define GRN_COM_POLLOUT POLLOUT
# endif /* USE_KQUEUE */
@@ -252,5 +248,3 @@ void grn_edge_dispatch(grn_ctx *ctx, grn_edge *edge, grn_obj *msg);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_COM_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_config.h b/storage/mroonga/vendor/groonga/lib/grn_config.h
new file mode 100644
index 00000000000..18d29fa0039
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_config.h
@@ -0,0 +1,37 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn_db.h"
+#include "grn_hash.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ grn_db_obj obj;
+ grn_hash_cursor *hash_cursor;
+} grn_config_cursor;
+
+grn_rc grn_config_cursor_close(grn_ctx *ctx, grn_config_cursor *cursor);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx.h b/storage/mroonga/vendor/groonga/lib/grn_ctx.h
index 4ba5f3c9bc6..51eebaf3d0b 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_ctx.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_ctx.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_CTX_H
-#define GRN_CTX_H
+
+#pragma once
#include "grn.h"
#include "grn_error.h"
@@ -33,6 +33,8 @@
#endif /* HAVE_EXECINFO_H */
#include "grn_io.h"
+#include "grn_alloc.h"
+#include "grn_time.h"
#ifdef __cplusplus
extern "C" {
@@ -45,7 +47,9 @@ extern "C" {
(ctx)->subno++;\
} else {\
(ctx)->errlvl = GRN_OK;\
- (ctx)->rc = GRN_SUCCESS;\
+ if ((ctx)->rc != GRN_CANCEL) {\
+ (ctx)->rc = GRN_SUCCESS;\
+ }\
(ctx)->seqno++;\
}\
GRN_TEST_YIELD();\
@@ -74,7 +78,10 @@ extern "C" {
#define ERRCLR(ctx) do {\
if (ctx) {\
((grn_ctx *)ctx)->errlvl = GRN_OK;\
- ((grn_ctx *)ctx)->rc = GRN_SUCCESS;\
+ if (((grn_ctx *)ctx)->rc != GRN_CANCEL) {\
+ ((grn_ctx *)ctx)->rc = GRN_SUCCESS;\
+ ((grn_ctx *)ctx)->errbuf[0] = '\0';\
+ }\
}\
errno = 0;\
grn_gctx.errlvl = GRN_OK;\
@@ -96,10 +103,14 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
char **p;\
BACKTRACE(ctx);\
p = backtrace_symbols((ctx)->trace, (ctx)->ntrace);\
- for (i = 0; i < (ctx)->ntrace; i++) {\
- GRN_LOG((ctx), lvl, "%s", p[i]);\
+ if (!p) {\
+ GRN_LOG((ctx), lvl, "backtrace_symbols failed");\
+ } else {\
+ for (i = 0; i < (ctx)->ntrace; i++) {\
+ GRN_LOG((ctx), lvl, "%s", p[i]);\
+ }\
+ free(p);\
}\
- free(p);\
} while (0)
#else /* HAVE_BACKTRACE */
#define LOGTRACE(ctx,msg)
@@ -108,7 +119,9 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
#define ERRSET(ctx,lvl,r,...) do {\
grn_ctx *ctx_ = (grn_ctx *)ctx;\
ctx_->errlvl = (lvl);\
- ctx_->rc = (r);\
+ if (ctx_->rc != GRN_CANCEL) {\
+ ctx_->rc = (r);\
+ }\
ctx_->errfile = __FILE__;\
ctx_->errline = __LINE__;\
ctx_->errfunc = __FUNCTION__;\
@@ -116,7 +129,6 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
if (grn_ctx_impl_should_log(ctx)) {\
grn_ctx_impl_set_current_error_message(ctx);\
GRN_LOG(ctx, lvl, __VA_ARGS__);\
- BACKTRACE(ctx);\
if (lvl <= GRN_LOG_ERROR) { LOGTRACE(ctx, lvl); }\
}\
} while (0)
@@ -127,6 +139,7 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
#ifdef ERR
# undef ERR
#endif /* ERR */
+#define CRIT(rc,...) ERRSET(ctx, GRN_CRIT, (rc), __VA_ARGS__)
#define ERR(rc,...) ERRSET(ctx, GRN_ERROR, (rc), __VA_ARGS__)
#define WARN(rc,...) ERRSET(ctx, GRN_WARN, (rc), __VA_ARGS__)
#define MERR(...) ERRSET(ctx, GRN_ALERT, GRN_NO_MEMORY_AVAILABLE, __VA_ARGS__)
@@ -151,105 +164,29 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
GRN_OBJ_FIN(ctx, &inspected);\
} while (0)
+#define USER_MESSAGE_SIZE 1024
+
#ifdef WIN32
-#define SERR(str) do {\
+#define SERR(...) do {\
grn_rc rc;\
+ int error_code;\
const char *system_message;\
- int error = GetLastError();\
+ char user_message[USER_MESSAGE_SIZE];\
+ error_code = GetLastError();\
system_message = grn_current_error_message();\
- switch (error) {\
- case ERROR_FILE_NOT_FOUND :\
- case ERROR_PATH_NOT_FOUND :\
- rc = GRN_NO_SUCH_FILE_OR_DIRECTORY;\
- break;\
- case ERROR_TOO_MANY_OPEN_FILES :\
- rc = GRN_TOO_MANY_OPEN_FILES;\
- break;\
- case ERROR_ACCESS_DENIED :\
- rc = GRN_PERMISSION_DENIED;\
- break;\
- case ERROR_INVALID_HANDLE :\
- rc = GRN_INVALID_ARGUMENT;\
- break;\
- case ERROR_ARENA_TRASHED :\
- rc = GRN_ADDRESS_IS_NOT_AVAILABLE;\
- break;\
- case ERROR_NOT_ENOUGH_MEMORY :\
- rc = GRN_NO_MEMORY_AVAILABLE;\
- break;\
- case ERROR_INVALID_BLOCK :\
- case ERROR_BAD_ENVIRONMENT :\
- rc = GRN_INVALID_ARGUMENT;\
- break;\
- case ERROR_BAD_FORMAT :\
- rc = GRN_INVALID_FORMAT;\
- break;\
- case ERROR_INVALID_DATA :\
- rc = GRN_INVALID_ARGUMENT;\
- break;\
- case ERROR_OUTOFMEMORY :\
- rc = GRN_NO_MEMORY_AVAILABLE;\
- break;\
- case ERROR_INVALID_DRIVE :\
- rc = GRN_INVALID_ARGUMENT;\
- break;\
- case ERROR_WRITE_PROTECT :\
- rc = GRN_PERMISSION_DENIED;\
- break;\
- case ERROR_BAD_LENGTH :\
- rc = GRN_INVALID_ARGUMENT;\
- break;\
- case ERROR_SEEK :\
- rc = GRN_INVALID_SEEK;\
- break;\
- case ERROR_NOT_SUPPORTED :\
- rc = GRN_OPERATION_NOT_SUPPORTED;\
- break;\
- case ERROR_NETWORK_ACCESS_DENIED :\
- rc = GRN_OPERATION_NOT_PERMITTED;\
- break;\
- case ERROR_FILE_EXISTS :\
- rc = GRN_FILE_EXISTS;\
- break;\
- case ERROR_INVALID_PARAMETER :\
- rc = GRN_INVALID_ARGUMENT;\
- break;\
- case ERROR_BROKEN_PIPE :\
- rc = GRN_BROKEN_PIPE;\
- break;\
- case ERROR_CALL_NOT_IMPLEMENTED :\
- rc = GRN_FUNCTION_NOT_IMPLEMENTED;\
- break;\
- case ERROR_INVALID_NAME :\
- rc = GRN_INVALID_ARGUMENT;\
- break;\
- case ERROR_BUSY_DRIVE :\
- case ERROR_PATH_BUSY :\
- rc = GRN_RESOURCE_BUSY;\
- break;\
- case ERROR_BAD_ARGUMENTS :\
- rc = GRN_INVALID_ARGUMENT;\
- break;\
- case ERROR_BUSY :\
- rc = GRN_RESOURCE_BUSY;\
- break;\
- case ERROR_ALREADY_EXISTS :\
- rc = GRN_FILE_EXISTS;\
- break;\
- case ERROR_BAD_EXE_FORMAT :\
- rc = GRN_EXEC_FORMAT_ERROR;\
- break;\
- default:\
- rc = GRN_UNKNOWN_ERROR;\
- break;\
- }\
- ERR(rc, "syscall error '%s' (%s)[%d]", str, system_message, error);\
+ rc = grn_windows_error_code_to_rc(error_code);\
+ grn_snprintf(user_message,\
+ USER_MESSAGE_SIZE, USER_MESSAGE_SIZE,\
+ __VA_ARGS__);\
+ ERR(rc, "system error[%d]: %s: %s",\
+ error_code, system_message, user_message);\
} while (0)
-#define SOERR(str) do {\
+#define SOERR(...) do {\
grn_rc rc;\
const char *m;\
+ char user_message[USER_MESSAGE_SIZE];\
int e = WSAGetLastError();\
switch (e) {\
case WSANOTINITIALISED :\
@@ -325,14 +262,19 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
m = "unknown error";\
break;\
}\
- ERR(rc, "socket error '%s' (%s)[%d]", str, m, e);\
+ grn_snprintf(user_message,\
+ USER_MESSAGE_SIZE, USER_MESSAGE_SIZE,\
+ __VA_ARGS__);\
+ ERR(rc, "socket error[%d]: %s: %s",\
+ e, m, user_message);\
} while (0)
-#define ERRNO_ERR(str) do {\
+#define ERRNO_ERR(...) do {\
grn_rc rc;\
int errno_keep = errno;\
grn_bool show_errno = GRN_FALSE;\
const char *system_message;\
+ char user_message[USER_MESSAGE_SIZE];\
system_message = grn_strerror(errno);\
switch (errno_keep) {\
case EPERM : rc = GRN_OPERATION_NOT_PERMITTED; break;\
@@ -373,19 +315,26 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
show_errno = GRN_TRUE;\
break;\
}\
+ grn_snprintf(user_message,\
+ USER_MESSAGE_SIZE, USER_MESSAGE_SIZE,\
+ __VA_ARGS__);\
if (show_errno) {\
- ERR(rc, "syscall error '%s' (%s)[%d]", str, system_message, errno_keep);\
+ ERR(rc, "system call error[%d]: %s: %s",\
+ errno_keep, system_message, user_message);\
} else {\
- ERR(rc, "syscall error '%s' (%s)", str, system_message);\
+ ERR(rc, "system call error: %s: %s",\
+ system_message, user_message);\
}\
} while (0)
#else /* WIN32 */
-#define SERR(str) do {\
+
+#define SERR(...) do {\
grn_rc rc;\
int errno_keep = errno;\
grn_bool show_errno = GRN_FALSE;\
const char *system_message = grn_current_error_message();\
+ char user_message[USER_MESSAGE_SIZE];\
switch (errno_keep) {\
case ELOOP : rc = GRN_TOO_MANY_SYMBOLIC_LINKS; break;\
case ENAMETOOLONG : rc = GRN_FILENAME_TOO_LONG; break;\
@@ -437,112 +386,33 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
show_errno = GRN_TRUE;\
break;\
}\
+ grn_snprintf(user_message,\
+ USER_MESSAGE_SIZE, USER_MESSAGE_SIZE,\
+ __VA_ARGS__);\
if (show_errno) {\
- ERR(rc, "syscall error '%s' (%s)[%d]", str, system_message, errno_keep);\
+ ERR(rc, "system call error[%d]: %s: %s",\
+ errno_keep, system_message, user_message);\
} else {\
- ERR(rc, "syscall error '%s' (%s)", str, system_message);\
+ ERR(rc, "system call error: %s: %s",\
+ system_message, user_message);\
}\
} while (0)
-#define SOERR(str) SERR(str)
+#define SOERR(...) SERR(__VA_ARGS__)
-#define ERRNO_ERR(str) SERR(str)
+#define ERRNO_ERR(...) SERR(__VA_ARGS__)
#endif /* WIN32 */
#define GERR(rc,...) ERRSET(&grn_gctx, GRN_ERROR, (rc), __VA_ARGS__)
#define GMERR(...) ERRSET(&grn_gctx, GRN_ALERT, GRN_NO_MEMORY_AVAILABLE, __VA_ARGS__)
-#define GRN_MALLOC(s) grn_malloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_CALLOC(s) grn_calloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_REALLOC(p,s) grn_realloc(ctx,p,s,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_STRDUP(s) grn_strdup(ctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_GMALLOC(s) grn_malloc(&grn_gctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_GCALLOC(s) grn_calloc(&grn_gctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_GREALLOC(p,s) grn_realloc(&grn_gctx,p,s,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_GSTRDUP(s) grn_strdup(&grn_gctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_FREE(p) grn_free(ctx,p,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_MALLOCN(t,n) ((t *)(GRN_MALLOC(sizeof(t) * (n))))
-#define GRN_GFREE(p) grn_free(&grn_gctx,p,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_GMALLOCN(t,n) ((t *)(GRN_GMALLOC(sizeof(t) * (n))))
-
#ifdef DEBUG
#define GRN_ASSERT(s) grn_assert(ctx,(s),__FILE__,__LINE__,__FUNCTION__)
#else
#define GRN_ASSERT(s)
#endif
-#define GRN_CTX_ALLOC(ctx,s) grn_ctx_calloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_CTX_FREE(ctx,p) grn_ctx_free(ctx,p,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_CTX_ALLOC_L(ctx,s) grn_ctx_alloc_lifo(ctx,s,f,__FILE__,__LINE__,__FUNCTION__)
-#define GRN_CTX_FREE_L(ctx,p) grn_ctx_free_lifo(ctx,p,__FILE__,__LINE__,__FUNCTION__)
-
-void *grn_ctx_alloc(grn_ctx *ctx, size_t size, int flags,
- const char* file, int line, const char *func);
-void *grn_ctx_malloc(grn_ctx *ctx, size_t size,
- const char* file, int line, const char *func);
-void *grn_ctx_calloc(grn_ctx *ctx, size_t size,
- const char* file, int line, const char *func);
-void *grn_ctx_realloc(grn_ctx *ctx, void *ptr, size_t size,
- const char* file, int line, const char *func);
-char *grn_ctx_strdup(grn_ctx *ctx, const char *s,
- const char* file, int line, const char *func);
-void grn_ctx_free(grn_ctx *ctx, void *ptr,
- const char* file, int line, const char *func);
-void *grn_ctx_alloc_lifo(grn_ctx *ctx, size_t size,
- const char* file, int line, const char *func);
-void grn_ctx_free_lifo(grn_ctx *ctx, void *ptr,
- const char* file, int line, const char *func);
-
-#ifdef USE_DYNAMIC_MALLOC_CHANGE
-typedef void *(*grn_malloc_func) (grn_ctx *ctx, size_t size,
- const char *file, int line, const char *func);
-typedef void *(*grn_calloc_func) (grn_ctx *ctx, size_t size,
- const char *file, int line, const char *func);
-typedef void *(*grn_realloc_func) (grn_ctx *ctx, void *ptr, size_t size,
- const char *file, int line, const char *func);
-typedef char *(*grn_strdup_func) (grn_ctx *ctx, const char *string,
- const char *file, int line, const char *func);
-typedef void (*grn_free_func) (grn_ctx *ctx, void *ptr,
- const char *file, int line, const char *func);
-grn_malloc_func grn_ctx_get_malloc(grn_ctx *ctx);
-void grn_ctx_set_malloc(grn_ctx *ctx, grn_malloc_func malloc_func);
-grn_calloc_func grn_ctx_get_calloc(grn_ctx *ctx);
-void grn_ctx_set_calloc(grn_ctx *ctx, grn_calloc_func calloc_func);
-grn_realloc_func grn_ctx_get_realloc(grn_ctx *ctx);
-void grn_ctx_set_realloc(grn_ctx *ctx, grn_realloc_func realloc_func);
-grn_strdup_func grn_ctx_get_strdup(grn_ctx *ctx);
-void grn_ctx_set_strdup(grn_ctx *ctx, grn_strdup_func strdup_func);
-grn_free_func grn_ctx_get_free(grn_ctx *ctx);
-void grn_ctx_set_free(grn_ctx *ctx, grn_free_func free_func);
-
-void *grn_malloc(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
-void *grn_calloc(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
-void *grn_realloc(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
-char *grn_strdup(grn_ctx *ctx, const char *s, const char* file, int line, const char *func);
-void grn_free(grn_ctx *ctx, void *ptr, const char *file, int line, const char *func);
-#else
-# define grn_malloc grn_malloc_default
-# define grn_calloc grn_calloc_default
-# define grn_realloc grn_realloc_default
-# define grn_strdup grn_strdup_default
-# define grn_free grn_free_default
-#endif
-
-GRN_API void *grn_malloc_default(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
-void *grn_calloc_default(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
-void *grn_realloc_default(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
-GRN_API char *grn_strdup_default(grn_ctx *ctx, const char *s, const char* file, int line, const char *func);
-GRN_API void grn_free_default(grn_ctx *ctx, void *ptr, const char* file, int line, const char *func);
-
-#ifdef USE_FAIL_MALLOC
-int grn_fail_malloc_check(size_t size, const char *file, int line, const char *func);
-void *grn_malloc_fail(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
-void *grn_calloc_fail(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
-void *grn_realloc_fail(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
-char *grn_strdup_fail(grn_ctx *ctx, const char *s, const char* file, int line, const char *func);
-#endif
-
void grn_assert(grn_ctx *ctx, int cond, const char* file, int line, const char* func);
/**** grn_ctx ****/
@@ -556,40 +426,20 @@ extern int grn_lock_timeout;
#define GRN_CTX_ALLOCATED (0x80)
#define GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND (0x40)
-typedef struct {
- int64_t tv_sec;
- int32_t tv_nsec;
-} grn_timeval;
-
extern grn_timeval grn_starttime;
-#ifndef GRN_TIMEVAL_STR_SIZE
-#define GRN_TIMEVAL_STR_SIZE 0x100
-#endif /* GRN_TIMEVAL_STR_SIZE */
-#ifndef GRN_TIMEVAL_STR_FORMAT
-#define GRN_TIMEVAL_STR_FORMAT "%04d-%02d-%02d %02d:%02d:%02d.%06d"
-#endif /* GRN_TIMEVAL_STR_FORMAT */
-#define GRN_TIME_NSEC_PER_SEC 1000000000
-#define GRN_TIME_NSEC_PER_SEC_F 1000000000.0
-#define GRN_TIME_NSEC_PER_USEC (GRN_TIME_NSEC_PER_SEC / GRN_TIME_USEC_PER_SEC)
-#define GRN_TIME_NSEC_TO_USEC(nsec) ((nsec) / GRN_TIME_NSEC_PER_USEC)
-#define GRN_TIME_USEC_TO_NSEC(usec) ((usec) * GRN_TIME_NSEC_PER_USEC)
-
-GRN_API grn_rc grn_timeval_now(grn_ctx *ctx, grn_timeval *tv);
-GRN_API grn_rc grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf, size_t buf_size);
-struct tm *grn_timeval2tm(grn_ctx *ctx, grn_timeval *tv, struct tm *tm_buffer);
-grn_rc grn_str2timeval(const char *str, uint32_t str_len, grn_timeval *tv);
-
GRN_API void grn_ctx_log(grn_ctx *ctx, const char *fmt, ...) GRN_ATTRIBUTE_PRINTF(2);
+GRN_API void grn_ctx_logv(grn_ctx *ctx, const char *fmt, va_list ap);
void grn_ctx_loader_clear(grn_ctx *ctx);
void grn_log_reopen(grn_ctx *ctx);
GRN_API grn_rc grn_ctx_sendv(grn_ctx *ctx, int argc, char **argv, int flags);
-GRN_API void grn_ctx_set_next_expr(grn_ctx *ctx, grn_obj *expr);
-
-int grn_alloc_count(void);
+void grn_ctx_set_keep_command(grn_ctx *ctx, grn_obj *command);
grn_content_type grn_get_ctype(grn_obj *var);
+grn_content_type grn_content_type_parse(grn_ctx *ctx,
+ grn_obj *var,
+ grn_content_type default_value);
/**** db_obj ****/
@@ -627,6 +477,7 @@ typedef struct {
(db_obj)->obj.header.type = (obj_type);\
(db_obj)->obj.header.impl_flags = 0;\
(db_obj)->obj.header.flags = 0;\
+ (db_obj)->obj.header.domain = GRN_ID_NIL;\
(db_obj)->obj.id = GRN_ID_NIL;\
(db_obj)->obj.user_data.ptr = NULL;\
(db_obj)->obj.finalizer = NULL;\
@@ -639,29 +490,6 @@ typedef struct {
(db_obj)->obj.source_size = 0;\
} while (0)
-/**** cache ****/
-
-#define GRN_CACHE_MAX_KEY_SIZE GRN_HASH_MAX_KEY_SIZE_LARGE
-
-typedef struct {
- uint32_t nentries;
- uint32_t max_nentries;
- uint32_t nfetches;
- uint32_t nhits;
-} grn_cache_statistics;
-
-void grn_cache_init(void);
-grn_obj *grn_cache_fetch(grn_ctx *ctx, grn_cache *cache,
- const char *str, uint32_t str_size);
-void grn_cache_unref(grn_ctx *ctx, grn_cache *cache,
- const char *str, uint32_t str_size);
-void grn_cache_update(grn_ctx *ctx, grn_cache *cache,
- const char *str, uint32_t str_size, grn_obj *value);
-void grn_cache_expire(grn_cache *cache, int32_t size);
-void grn_cache_fin(void);
-void grn_cache_get_statistics(grn_ctx *ctx, grn_cache *cache,
- grn_cache_statistics *statistics);
-
/**** receive handler ****/
GRN_API void grn_ctx_stream_out_func(grn_ctx *c, int flags, void *stream);
@@ -671,5 +499,3 @@ grn_rc grn_db_init_builtin_procs(grn_ctx *ctx);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_CTX_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h
index b653f35015b..2d72065d4f0 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_CTX_IMPL_H
-#define GRN_CTX_IMPL_H
+
+#pragma once
#ifndef GRN_CTX_H
# include "grn_ctx.h"
@@ -59,12 +59,27 @@ typedef enum {
GRN_LOADER_END
} grn_loader_stat;
+/*
+ * Status of target columns used in Format 1.
+ * Target columns are specified via --columns or the first array in a Format 1
+ * JSON object.
+ */
+typedef enum {
+ GRN_LOADER_COLUMNS_UNSET = 0, /* Columns are not available. */
+ GRN_LOADER_COLUMNS_SET, /* Columns are available. */
+ GRN_LOADER_COLUMNS_BROKEN /* Columns are specified but broken. */
+} grn_loader_columns_status;
+
typedef struct {
grn_obj values;
grn_obj level;
grn_obj columns;
+ grn_obj ids;
+ grn_obj return_codes;
+ grn_obj error_messages;
uint32_t emit_level;
- int32_t key_offset;
+ int32_t id_offset; /* Position of _id in values or -1 if _id is N/A. */
+ int32_t key_offset; /* Position of _key in values or -1 if _key is N/A. */
grn_obj *table;
grn_obj *last;
grn_obj *ifexists;
@@ -74,6 +89,11 @@ typedef struct {
uint32_t nrecords;
grn_loader_stat stat;
grn_content_type input_type;
+ grn_loader_columns_status columns_status;
+ grn_rc rc;
+ char errbuf[GRN_CTX_MSGSIZE];
+ grn_bool output_ids;
+ grn_bool output_errors;
} grn_loader;
#define GRN_CTX_N_SEGMENTS 512
@@ -84,6 +104,7 @@ struct _grn_alloc_info
{
void *address;
int freed;
+ size_t size;
char alloc_backtrace[4096];
char free_backtrace[4096];
char *file;
@@ -93,9 +114,10 @@ struct _grn_alloc_info
};
#endif
-#ifdef GRN_WITH_MRUBY
typedef struct _grn_mrb_data grn_mrb_data;
struct _grn_mrb_data {
+ grn_bool initialized;
+#ifdef GRN_WITH_MRUBY
mrb_state *state;
char base_directory[PATH_MAX];
struct RClass *module;
@@ -112,8 +134,8 @@ struct _grn_mrb_data {
struct {
struct RClass *operator_class;
} groonga;
-};
#endif
+};
struct _grn_ctx_impl {
grn_encoding encoding;
@@ -143,7 +165,8 @@ struct _grn_ctx_impl {
uint32_t stack_curr;
grn_hash *expr_vars;
grn_obj *curr_expr;
- grn_obj *qe_next;
+ grn_obj current_request_id;
+ void *current_request_timer_id;
void *parser;
grn_timeval tv;
@@ -155,13 +178,33 @@ struct _grn_ctx_impl {
const char *plugin_path;
/* output portion */
- grn_content_type output_type;
- const char *mime_type;
- grn_obj names;
- grn_obj levels;
+ struct {
+ grn_obj *buf;
+ void (*func)(grn_ctx *, int, void *);
+ union {
+ void *ptr;
+ int fd;
+ uint32_t u32;
+ uint64_t u64;
+ } data;
+ grn_content_type type;
+ const char *mime_type;
+ grn_bool is_pretty;
+ grn_obj names;
+ grn_obj levels;
+#ifdef GRN_WITH_MESSAGE_PACK
+ msgpack_packer msgpacker;
+#endif
+ } output;
- /* command portion */
- grn_command_version command_version;
+ struct {
+ int flags;
+ grn_command_version version;
+ struct {
+ grn_obj *command;
+ grn_command_version version;
+ } keep;
+ } command;
/* match escalation portion */
int64_t match_escalation_threshold;
@@ -171,33 +214,24 @@ struct _grn_ctx_impl {
grn_obj *db;
grn_array *values; /* temporary objects */
+ grn_pat *temporary_columns;
grn_hash *ios; /* IOs */
- grn_obj *outbuf;
- void (*output)(grn_ctx *, int, void *);
grn_com *com;
unsigned int com_status;
- union {
- void *ptr;
- int fd;
- uint32_t u32;
- uint64_t u64;
- } data;
grn_obj query_log_buf;
char previous_errbuf[GRN_CTX_MSGSIZE];
unsigned int n_same_error_messages;
-#ifdef GRN_WITH_MESSAGE_PACK
- msgpack_packer msgpacker;
-#endif
-#ifdef GRN_WITH_MRUBY
grn_mrb_data mrb;
-#endif
+
+ struct {
+ grn_obj stack;
+ grn_obj *current;
+ } temporary_open_spaces;
};
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_CTX_IMPL_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h
index 3e46d2e417f..caa303461ef 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2015 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_CTX_IMPL_MRB_H
-#define GRN_CTX_IMPL_MRB_H
+#pragma once
#include "grn.h"
#include "grn_ctx.h"
@@ -29,9 +28,8 @@ extern "C" {
void grn_ctx_impl_mrb_init_from_env(void);
void grn_ctx_impl_mrb_init(grn_ctx *ctx);
void grn_ctx_impl_mrb_fin(grn_ctx *ctx);
+GRN_API void grn_ctx_impl_mrb_ensure_init(grn_ctx *ctx);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_CTX_IMPL_MRB_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_dat.h b/storage/mroonga/vendor/groonga/lib/grn_dat.h
index d3c768fa65c..774c026940c 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_dat.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_dat.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011-2015 Brazil
+/*
+ Copyright(C) 2011-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,13 +15,10 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DAT_H
-#define GRN_DAT_H
-#ifndef GRN_H
-# include "grn.h"
-#endif /* GRN_H */
+#pragma once
+#include "grn.h"
#include "grn_db.h"
#ifdef __cplusplus
@@ -39,6 +37,7 @@ struct _grn_dat {
grn_obj *normalizer;
grn_obj token_filters;
grn_critical_section lock;
+ grn_bool is_dirty;
};
struct grn_dat_header {
@@ -47,7 +46,8 @@ struct grn_dat_header {
grn_id tokenizer;
uint32_t file_id;
grn_id normalizer;
- uint32_t reserved[235];
+ uint32_t n_dirty_opens;
+ uint32_t reserved[234];
};
struct _grn_dat_cursor {
@@ -81,8 +81,15 @@ GRN_API grn_rc grn_dat_repair(grn_ctx *ctx, grn_dat *dat);
GRN_API grn_rc grn_dat_flush(grn_ctx *ctx, grn_dat *dat);
+grn_rc grn_dat_dirty(grn_ctx *ctx, grn_dat *dat);
+grn_bool grn_dat_is_dirty(grn_ctx *ctx, grn_dat *dat);
+grn_rc grn_dat_clean(grn_ctx *ctx, grn_dat *dat);
+grn_rc grn_dat_clear_dirty(grn_ctx *ctx, grn_dat *dat);
+
+grn_bool grn_dat_is_corrupt(grn_ctx *ctx, grn_dat *dat);
+
+size_t grn_dat_get_disk_usage(grn_ctx *ctx, grn_dat *dat);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_DAT_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_db.h b/storage/mroonga/vendor/groonga/lib/grn_db.h
index 6c84ad921f4..f0fbddad882 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_db.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_db.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_DB_H
-#define GRN_DB_H
+
+#pragma once
#include "grn.h"
#include "grn_ctx.h"
@@ -37,9 +38,6 @@ extern "C" {
#define GRN_N_RESERVED_TYPES 256
-#define GRN_JSON_LOAD_OPEN_BRACKET 0x40000000
-#define GRN_JSON_LOAD_OPEN_BRACE 0x40000001
-
typedef struct _grn_db grn_db;
typedef struct _grn_proc grn_proc;
@@ -47,22 +45,88 @@ struct _grn_db {
grn_db_obj obj;
grn_obj *keys;
grn_ja *specs;
+ grn_hash *config;
grn_tiny_array values;
grn_critical_section lock;
};
+#define GRN_SERIALIZED_SPEC_INDEX_SPEC 0
+#define GRN_SERIALIZED_SPEC_INDEX_PATH 1
+#define GRN_SERIALIZED_SPEC_INDEX_SOURCE 2
+#define GRN_SERIALIZED_SPEC_INDEX_HOOK 3
+#define GRN_SERIALIZED_SPEC_INDEX_TOKEN_FILTERS 4
+#define GRN_SERIALIZED_SPEC_INDEX_EXPR 4
+
typedef struct {
grn_obj_header header;
grn_id range;
} grn_obj_spec;
+grn_bool grn_db_spec_unpack(grn_ctx *ctx,
+ grn_id id,
+ void *encoded_spec,
+ uint32_t encoded_spec_size,
+ grn_obj_spec **spec,
+ grn_obj *decoded_spec,
+ const char *error_message_tag);
+
+#define GRN_DB_SPEC_EACH_BEGIN(ctx, cursor, id, spec) do { \
+ grn_obj *db = grn_ctx_db((ctx)); \
+ grn_db *db_raw = (grn_db *)db; \
+ grn_obj decoded_spec; \
+ grn_io_win iw; \
+ grn_bool iw_need_unref = GRN_FALSE; \
+ GRN_OBJ_INIT(&decoded_spec, GRN_VECTOR, 0, GRN_DB_TEXT); \
+ GRN_TABLE_EACH_BEGIN((ctx), db, cursor, id) { \
+ void *encoded_spec; \
+ uint32_t encoded_spec_size; \
+ grn_bool success; \
+ grn_obj_spec *spec; \
+ \
+ if (iw_need_unref) { \
+ grn_ja_unref(ctx, &iw); \
+ iw_need_unref = GRN_FALSE; \
+ } \
+ encoded_spec = grn_ja_ref((ctx), \
+ db_raw->specs, \
+ id, \
+ &iw, \
+ &encoded_spec_size); \
+ if (!encoded_spec) { \
+ continue; \
+ } \
+ iw_need_unref = GRN_TRUE; \
+ \
+ GRN_BULK_REWIND(&decoded_spec); \
+ success = grn_db_spec_unpack(ctx, \
+ id, \
+ encoded_spec, \
+ encoded_spec_size, \
+ &spec, \
+ &decoded_spec, \
+ __FUNCTION__); \
+ if (!success) { \
+ continue; \
+ } \
+
+#define GRN_DB_SPEC_EACH_END(ctx, cursor) \
+ } GRN_TABLE_EACH_END(ctx, cursor); \
+ if (iw_need_unref) { \
+ grn_ja_unref(ctx, &iw); \
+ } \
+ GRN_OBJ_FIN((ctx), &decoded_spec); \
+} while(GRN_FALSE)
+
void grn_db_init_from_env(void);
GRN_API grn_rc grn_db_close(grn_ctx *ctx, grn_obj *db);
grn_obj *grn_db_keys(grn_obj *s);
-uint32_t grn_db_lastmod(grn_obj *s);
+void grn_db_generate_pathname(grn_ctx *ctx,
+ grn_obj *db,
+ grn_id id,
+ char *buffer);
grn_rc _grn_table_delete_by_id(grn_ctx *ctx, grn_obj *table, grn_id id,
grn_table_delete_optarg *optarg);
@@ -71,7 +135,11 @@ grn_id grn_table_get_v(grn_ctx *ctx, grn_obj *table, const void *key, int key_si
void **value);
grn_id grn_table_add_v(grn_ctx *ctx, grn_obj *table, const void *key, int key_size,
void **value, int *added);
-GRN_API grn_rc grn_table_get_info(grn_ctx *ctx, grn_obj *table, grn_obj_flags *flags,
+grn_id grn_table_add_by_key(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *key,
+ int *added);
+GRN_API grn_rc grn_table_get_info(grn_ctx *ctx, grn_obj *table, grn_table_flags *flags,
grn_encoding *encoding, grn_obj **tokenizer,
grn_obj **normalizer,
grn_obj **token_filters);
@@ -81,6 +149,10 @@ grn_rc grn_table_search(grn_ctx *ctx, grn_obj *table,
const void *key, uint32_t key_size,
grn_operator mode, grn_obj *res, grn_operator op);
+grn_rc grn_table_fuzzy_search(grn_ctx *ctx, grn_obj *table,
+ const void *key, uint32_t key_size,
+ grn_fuzzy_search_optarg *args, grn_obj *res, grn_operator op);
+
grn_id grn_table_next(grn_ctx *ctx, grn_obj *table, grn_id id);
int grn_table_get_key2(grn_ctx *ctx, grn_obj *table, grn_id id, grn_obj *bulk);
@@ -111,6 +183,7 @@ struct _grn_type {
#define GRN_TABLE_SORT_GEO (0x02<<0)
#define GRN_OBJ_TMP_OBJECT 0x80000000
+#define GRN_OBJ_TMP_COLUMN 0x40000000
#define GRN_DB_OBJP(obj) \
(obj &&\
@@ -136,6 +209,12 @@ struct _grn_type {
(GRN_OBJ_VECTOR_COLUMNP(obj) &&\
(DB_OBJ(obj)->header.flags & GRN_OBJ_WITH_WEIGHT))
+struct _grn_hook {
+ grn_hook *next;
+ grn_proc *proc;
+ uint32_t hld_size;
+};
+
typedef struct _grn_proc_ctx grn_proc_ctx;
struct _grn_proc_ctx {
@@ -160,10 +239,13 @@ struct _grn_proc {
grn_proc_type type;
grn_proc_func *funcs[3];
- grn_selector_func *selector;
-
union {
struct {
+ grn_selector_func *selector;
+ grn_operator selector_op;
+ grn_bool is_stable;
+ } function;
+ struct {
grn_command_run_func *run;
} command;
struct {
@@ -174,6 +256,7 @@ struct _grn_proc {
struct {
grn_scorer_score_func *score;
} scorer;
+ grn_window_function_func *window_function;
} callbacks;
void *user_data;
@@ -201,7 +284,7 @@ GRN_API grn_obj *grn_proc_get_or_add_var(grn_ctx *ctx, grn_user_data *user_data,
const char *name, unsigned int name_size);
GRN_API grn_obj *grn_proc_alloc(grn_ctx *ctx, grn_user_data *user_data,
- grn_id domain, grn_obj_flags flags);
+ grn_id domain, unsigned char flags);
GRN_API grn_rc grn_proc_call(grn_ctx *ctx, grn_obj *proc,
int nargs, grn_obj *caller);
@@ -259,9 +342,6 @@ int grn_vector_delimit(grn_ctx *ctx, grn_obj *vector);
int grn_vector_size(grn_ctx *ctx, grn_obj *vector);
*/
-unsigned int grn_vector_pop_element(grn_ctx *ctx, grn_obj *vector,
- const char **str, unsigned int *weight, grn_id *domain);
-
grn_rc grn_vector_delimit(grn_ctx *ctx, grn_obj *v, unsigned int weight, grn_id domain);
grn_rc grn_vector_decode(grn_ctx *ctx, grn_obj *v, const char *data, uint32_t data_size);
@@ -293,6 +373,8 @@ typedef struct {
int32_t modify;
} grn_expr_code;
+#define GRN_EXPR_CONST_BLK_SIZE GRN_STACK_SIZE
+
struct _grn_expr {
grn_db_obj obj;
grn_obj name_buf;
@@ -302,7 +384,7 @@ struct _grn_expr {
uint16_t cacheable;
uint16_t taintable;
- grn_obj *consts;
+ grn_obj **const_blks;
grn_obj *values;
grn_expr_code *codes;
uint32_t nconsts;
@@ -318,15 +400,16 @@ struct _grn_expr {
};
grn_rc grn_expr_parser_close(grn_ctx *ctx);
-GRN_API grn_rc grn_obj_cast(grn_ctx *ctx, grn_obj *src, grn_obj *dest, grn_bool addp);
/**
* grn_table_open:
- * @name: é–‹ã“ã†ã¨ã™ã‚‹tableã®åå‰ã€‚NULLãªã‚‰ç„¡åtableã¨ãªã‚‹ã€‚
- * @path: é–‹ã“ã†ã¨ã™ã‚‹tableã®ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘ス。
+ * @name: The table name to be opened. `NULL` means anonymous table.
+ * @path: The path of the table to be opened.
*
- * ctxãŒä½¿ç”¨ã™ã‚‹dbã®ä¸­ã§nameã«å¯¾å¿œä»˜ã‘ã¦æ—¢å­˜ã®tableã‚’é–‹ã。
- * dbã«ç™»éŒ²ã•ã‚Œã¦ã„ã‚‹åå‰ä»˜ãã®æ°¸ç¶šãƒ†ãƒ¼ãƒ–ルを開ãå ´åˆã¯grn_ctx_get()を使用ã™ã‚‹ã®ãŒæœ›ã¾ã—ã„。
+ * Opens an existing table. The table is associated with @name in DB
+ * that is used by @ctx. grn_ctx_get() is better rather than this
+ * function when you want to open a permanent named table that is
+ * registered in DB.
**/
GRN_API grn_obj *grn_table_open(grn_ctx *ctx,
const char *name, unsigned int name_size,
@@ -334,13 +417,14 @@ GRN_API grn_obj *grn_table_open(grn_ctx *ctx,
/**
* grn_column_open:
- * @table: 対象table
- * @name: カラムå
- * @path: カラムを格ç´ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘ス。
- * @type: カラム値ã®åž‹ã€‚
+ * @table: The table for the opened column.
+ * @name: The column name to be opened.
+ * @path: The path of the column to be opened.
+ * @type: The type of the column value.
*
- * 既存ã®æ°¸ç¶šçš„ãªcolumnã‚’ã€tableã®nameã«å¯¾å¿œã™ã‚‹columnã¨ã—ã¦é–‹ã
- * 永続dbã«ç™»éŒ²ã•ã‚Œã¦ã„る永続テーブルã®ã‚«ãƒ©ãƒ ã‚’é–‹ãå ´åˆã¯grn_ctx_get()を使用ã™ã‚‹ã®ãŒæœ›ã¾ã—ã„。
+ * Opens an existing permanent column. The column is associated with
+ * @name in @table. grn_ctx_get() is better rather than this function
+ * when you want to open a column of an permanent table in DB.
**/
grn_obj *grn_column_open(grn_ctx *ctx, grn_obj *table,
const char *name, unsigned int name_size,
@@ -348,10 +432,10 @@ grn_obj *grn_column_open(grn_ctx *ctx, grn_obj *table,
/**
* grn_obj_path_rename:
- * @old_path: 旧ファイルパス
- * @new_path: 新ファイルパス
+ * @old_path: The current file path.
+ * @new_path: The new file path.
*
- * old_pathã«è©²å½“ã™ã‚‹ã‚ªãƒ–ジェクトã®ãƒ•ã‚¡ã‚¤ãƒ«åã‚’new_pathã«å¤‰æ›´ã™ã‚‹ã€‚
+ * It renames object's path that is stored in @old_path to @new_path.
**/
grn_rc grn_obj_path_rename(grn_ctx *ctx, const char *old_path, const char *new_path);
@@ -371,83 +455,17 @@ grn_rc grn_db_obj_init(grn_ctx *ctx, grn_obj *db, grn_id id, grn_db_obj *obj);
#define GRN_ACCESSORP(obj) \
((obj) && (((grn_obj *)(obj))->header.type == GRN_ACCESSOR))
-#define GRN_TRUEP(ctx, v, result) do {\
- switch (v->header.type) { \
- case GRN_BULK : \
- switch (v->header.domain) { \
- case GRN_DB_BOOL : \
- result = GRN_BOOL_VALUE(v); \
- break; \
- case GRN_DB_INT32 : \
- result = GRN_INT32_VALUE(v) != 0; \
- break; \
- case GRN_DB_UINT32 : \
- result = GRN_UINT32_VALUE(v) != 0; \
- break; \
- case GRN_DB_FLOAT : \
- { \
- double float_value; \
- float_value = GRN_FLOAT_VALUE(v); \
- result = (float_value < -DBL_EPSILON || \
- DBL_EPSILON < float_value); \
- } \
- break; \
- case GRN_DB_SHORT_TEXT : \
- case GRN_DB_TEXT : \
- case GRN_DB_LONG_TEXT : \
- result = GRN_TEXT_LEN(v) != 0; \
- break; \
- default : \
- result = GRN_FALSE; \
- break; \
- } \
- break; \
- case GRN_VECTOR : \
- result = GRN_TRUE; \
- break; \
- default : \
- result = GRN_FALSE; \
- break; \
- } \
-} while (0)
-
grn_id grn_obj_register(grn_ctx *ctx, grn_obj *db, const char *name, unsigned int name_size);
int grn_obj_is_persistent(grn_ctx *ctx, grn_obj *obj);
void grn_obj_spec_save(grn_ctx *ctx, grn_db_obj *obj);
grn_rc grn_obj_reinit_for(grn_ctx *ctx, grn_obj *obj, grn_obj *domain_obj);
-#define GRN_INT32_POP(obj,value) do {\
- if (GRN_BULK_VSIZE(obj) >= sizeof(int32_t)) {\
- GRN_BULK_INCR_LEN((obj), -(sizeof(int32_t)));\
- value = *(int32_t *)(GRN_BULK_CURR(obj));\
- } else {\
- value = 0;\
- }\
-} while (0)
-
-#define GRN_UINT32_POP(obj,value) do {\
- if (GRN_BULK_VSIZE(obj) >= sizeof(uint32_t)) {\
- GRN_BULK_INCR_LEN((obj), -(sizeof(uint32_t)));\
- value = *(uint32_t *)(GRN_BULK_CURR(obj));\
- } else {\
- value = 0;\
- }\
-} while (0)
-
void grn_expr_pack(grn_ctx *ctx, grn_obj *buf, grn_obj *expr);
GRN_API grn_rc grn_expr_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *expr);
grn_hash *grn_expr_get_vars(grn_ctx *ctx, grn_obj *expr, unsigned int *nvars);
grn_obj *grn_expr_open(grn_ctx *ctx, grn_obj_spec *spec, const uint8_t *p, const uint8_t *pe);
-GRN_API void grn_load_(grn_ctx *ctx, grn_content_type input_type,
- const char *table, unsigned int table_len,
- const char *columns, unsigned int columns_len,
- const char *values, unsigned int values_len,
- const char *ifexists, unsigned int ifexists_len,
- const char *each, unsigned int each_len,
- uint32_t emit_level);
-
GRN_API grn_rc grn_table_group_with_range_gap(grn_ctx *ctx, grn_obj *table,
grn_table_sort_key *group_key,
grn_obj *result_set,
@@ -458,12 +476,18 @@ GRN_API grn_rc grn_column_filter(grn_ctx *ctx, grn_obj *column,
grn_obj *value, grn_obj *result_set,
grn_operator set_op);
-grn_rc grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep,
- grn_obj *base_res, grn_obj **res,
- grn_search_optarg *optarg);
+typedef struct {
+ grn_id target;
+ unsigned int section;
+} grn_obj_default_set_value_hook_data;
+
+grn_obj *grn_obj_default_set_value_hook(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data);
+
+grn_rc grn_pvector_fin(grn_ctx *ctx, grn_obj *obj);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_DB_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c
index b3e4da09095..cfabcc9196b 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c
+++ b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c
@@ -1,70 +1,102 @@
-/* Driver template for the LEMON parser generator.
-** The author disclaims copyright to this source code.
+/*
+** 2000-05-29
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Driver template for the LEMON parser generator.
+**
+** The "lemon" program processes an LALR(1) input grammar file, then uses
+** this template to construct a parser. The "lemon" program inserts text
+** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the
+** interstitial "-" characters) contained in this template is changed into
+** the value of the %name directive from the grammar. Otherwise, the content
+** of this template is copied straight through into the generate parser
+** source file.
+**
+** The following is the concatenation of all %include directives from the
+** input grammar file:
*/
-/* First off, code is included that follows the "include" declaration
-** in the input grammar file. */
#include <stdio.h>
+/************ Begin %include sections from the grammar ************************/
#line 4 "grn_ecmascript.lemon"
-#define assert GRN_ASSERT
-#line 11 "grn_ecmascript.c"
-/* Next is all token values, in a form suitable for use by makeheaders.
-** This section will be null unless lemon is run with the -m switch.
-*/
-/*
-** These constants (all generated automatically by the parser generator)
-** specify the various kinds of tokens (terminals) that the parser
-** understands.
-**
-** Each symbol here is a terminal symbol in the grammar.
-*/
-/* Make sure the INTERFACE macro is defined.
-*/
-#ifndef INTERFACE
-# define INTERFACE 1
+#ifdef assert
+# undef assert
#endif
-/* The next thing included is series of defines which control
+#define assert GRN_ASSERT
+#line 34 "grn_ecmascript.c"
+/**************** End of %include directives **********************************/
+/* These constants specify the various numeric values for terminal symbols
+** in a format understandable to "makeheaders". This section is blank unless
+** "lemon" is run with the "-m" command-line option.
+***************** Begin makeheaders token definitions *************************/
+/**************** End makeheaders token definitions ***************************/
+
+/* The next sections is a series of control #defines.
** various aspects of the generated parser.
-** YYCODETYPE is the data type used for storing terminal
-** and nonterminal numbers. "unsigned char" is
-** used if there are fewer than 250 terminals
-** and nonterminals. "int" is used otherwise.
-** YYNOCODE is a number of type YYCODETYPE which corresponds
-** to no legal terminal or nonterminal number. This
-** number is used to fill in empty slots of the hash
-** table.
+** YYCODETYPE is the data type used to store the integer codes
+** that represent terminal and non-terminal symbols.
+** "unsigned char" is used if there are fewer than
+** 256 symbols. Larger types otherwise.
+** YYNOCODE is a number of type YYCODETYPE that is not used for
+** any terminal or nonterminal symbol.
** YYFALLBACK If defined, this indicates that one or more tokens
-** have fall-back values which should be used if the
-** original value of the token will not parse.
-** YYACTIONTYPE is the data type used for storing terminal
-** and nonterminal numbers. "unsigned char" is
-** used if there are fewer than 250 rules and
-** states combined. "int" is used otherwise.
-** grn_expr_parserTOKENTYPE is the data type used for minor tokens given
-** directly to the parser from the tokenizer.
-** YYMINORTYPE is the data type used for all minor tokens.
+** (also known as: "terminal symbols") have fall-back
+** values which should be used if the original symbol
+** would not parse. This permits keywords to sometimes
+** be used as identifiers, for example.
+** YYACTIONTYPE is the data type used for "action codes" - numbers
+** that indicate what to do in response to the next
+** token.
+** grn_expr_parserTOKENTYPE is the data type used for minor type for terminal
+** symbols. Background: A "minor type" is a semantic
+** value associated with a terminal or non-terminal
+** symbols. For example, for an "ID" terminal symbol,
+** the minor type might be the name of the identifier.
+** Each non-terminal can have a different minor type.
+** Terminal symbols all have the same minor type, though.
+** This macros defines the minor type for terminal
+** symbols.
+** YYMINORTYPE is the data type used for all minor types.
** This is typically a union of many types, one of
** which is grn_expr_parserTOKENTYPE. The entry in the union
-** for base tokens is called "yy0".
+** for terminal symbols is called "yy0".
** YYSTACKDEPTH is the maximum depth of the parser's stack. If
** zero the stack is dynamically sized using realloc()
** grn_expr_parserARG_SDECL A static variable declaration for the %extra_argument
** grn_expr_parserARG_PDECL A parameter declaration for the %extra_argument
** grn_expr_parserARG_STORE Code to store %extra_argument into yypParser
** grn_expr_parserARG_FETCH Code to extract %extra_argument from yypParser
-** YYNSTATE the combined number of states.
-** YYNRULE the number of rules in the grammar
** YYERRORSYMBOL is the code number of the error symbol. If not
** defined, then do no error processing.
+** YYNSTATE the combined number of states.
+** YYNRULE the number of rules in the grammar
+** YY_MAX_SHIFT Maximum value for shift actions
+** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
+** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
+** YY_MIN_REDUCE Maximum value for reduce actions
+** YY_ERROR_ACTION The yy_action[] code for syntax error
+** YY_ACCEPT_ACTION The yy_action[] code for accept
+** YY_NO_ACTION The yy_action[] code for no-op
*/
+#ifndef INTERFACE
+# define INTERFACE 1
+#endif
+/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned char
-#define YYNOCODE 114
+#define YYNOCODE 115
#define YYACTIONTYPE unsigned short int
#define grn_expr_parserTOKENTYPE int
typedef union {
int yyinit;
grn_expr_parserTOKENTYPE yy0;
- void * yy165;
+ void * yy217;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -73,15 +105,17 @@ typedef union {
#define grn_expr_parserARG_PDECL , efs_info *efsi
#define grn_expr_parserARG_FETCH efs_info *efsi = yypParser->efsi
#define grn_expr_parserARG_STORE yypParser->efsi = efsi
-#define YYNSTATE 225
-#define YYNRULE 132
-#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
-#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
-#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
-
-/* The yyzerominor constant is used to initialize instances of
-** YYMINORTYPE objects to zero. */
-static const YYMINORTYPE yyzerominor = { 0 };
+#define YYNSTATE 145
+#define YYNRULE 136
+#define YY_MAX_SHIFT 144
+#define YY_MIN_SHIFTREDUCE 232
+#define YY_MAX_SHIFTREDUCE 367
+#define YY_MIN_REDUCE 368
+#define YY_MAX_REDUCE 503
+#define YY_ERROR_ACTION 504
+#define YY_ACCEPT_ACTION 505
+#define YY_NO_ACTION 506
+/************* End control #defines *******************************************/
/* Define the yytestcase() macro to be a no-op if is not already defined
** otherwise.
@@ -104,29 +138,37 @@ static const YYMINORTYPE yyzerominor = { 0 };
** Suppose the action integer is N. Then the action is determined as
** follows
**
-** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
+** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead
** token onto the stack and goto state N.
**
-** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
+** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
+** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE.
+**
+** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
+** and YY_MAX_REDUCE
**
-** N == YYNSTATE+YYNRULE A syntax error has occurred.
+** N == YY_ERROR_ACTION A syntax error has occurred.
**
-** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
+** N == YY_ACCEPT_ACTION The parser accepts its input.
**
-** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
+** N == YY_NO_ACTION No such action. Denotes unused
** slots in the yy_action[] table.
**
** The action table is constructed as a single large table named yy_action[].
-** Given state S and lookahead X, the action is computed as
+** Given state S and lookahead X, the action is computed as either:
**
-** yy_action[ yy_shift_ofst[S] + X ]
+** (A) N = yy_action[ yy_shift_ofst[S] + X ]
+** (B) N = yy_default[S]
**
-** If the index value yy_shift_ofst[S]+X is out of range or if the value
-** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
-** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
-** and that yy_default[S] should be used instead.
+** The (A) formula is preferred. The B formula is used instead if:
+** (1) The yy_shift_ofst[S]+X value is out of range, or
+** (2) yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or
+** (3) yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT.
+** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that
+** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
+** Hence only tests (1) and (2) need to be evaluated.)
**
-** The formula above is for computing the action when the lookahead is
+** The formulas above are for computing the action when the lookahead is
** a terminal symbol. If the lookahead is a non-terminal (as occurs after
** a reduce action) then the yy_reduce_ofst[] array is used in place of
** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
@@ -142,404 +184,430 @@ static const YYMINORTYPE yyzerominor = { 0 };
** yy_reduce_ofst[] For each state, the offset into yy_action for
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
-*/
-#define YY_ACTTAB_COUNT (1639)
+**
+*********** Begin parsing tables **********************************************/
+#define YY_ACTTAB_COUNT (1794)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 2, 71, 53, 52, 51, 222, 1, 76, 80, 125,
- /* 10 */ 4, 221, 70, 358, 77, 109, 28, 152, 221, 191,
- /* 20 */ 194, 215, 88, 123, 122, 135, 134, 133, 117, 85,
- /* 30 */ 100, 113, 101, 180, 211, 197, 74, 190, 186, 190,
- /* 40 */ 186, 222, 72, 79, 80, 140, 9, 189, 70, 25,
- /* 50 */ 65, 64, 217, 28, 28, 68, 67, 66, 63, 62,
- /* 60 */ 61, 60, 59, 58, 185, 184, 183, 182, 181, 3,
- /* 70 */ 76, 115, 6, 193, 221, 191, 194, 215, 88, 123,
- /* 80 */ 122, 135, 134, 133, 117, 85, 100, 113, 101, 180,
- /* 90 */ 211, 197, 74, 166, 107, 190, 186, 222, 1, 23,
- /* 100 */ 80, 125, 4, 124, 70, 31, 30, 191, 194, 215,
- /* 110 */ 88, 123, 122, 135, 134, 133, 117, 85, 100, 113,
- /* 120 */ 101, 180, 211, 197, 74, 141, 129, 190, 186, 36,
- /* 130 */ 35, 112, 69, 57, 56, 8, 32, 131, 55, 54,
- /* 140 */ 34, 29, 65, 64, 176, 33, 73, 68, 67, 66,
- /* 150 */ 63, 62, 61, 60, 59, 58, 185, 184, 183, 182,
- /* 160 */ 181, 3, 7, 26, 128, 187, 84, 199, 198, 178,
- /* 170 */ 191, 168, 215, 88, 123, 122, 135, 134, 133, 117,
- /* 180 */ 85, 100, 113, 101, 180, 211, 197, 74, 144, 129,
- /* 190 */ 190, 186, 11, 83, 82, 81, 78, 222, 72, 150,
- /* 200 */ 80, 140, 9, 173, 70, 24, 65, 64, 228, 169,
- /* 210 */ 167, 68, 67, 66, 63, 62, 61, 60, 59, 58,
- /* 220 */ 185, 184, 183, 182, 181, 3, 179, 7, 196, 195,
- /* 230 */ 187, 84, 108, 143, 178, 191, 146, 215, 88, 123,
- /* 240 */ 122, 135, 134, 133, 117, 85, 100, 113, 101, 180,
- /* 250 */ 211, 197, 74, 226, 227, 190, 186, 126, 173, 75,
- /* 260 */ 173, 175, 132, 145, 142, 112, 170, 28, 5, 10,
- /* 270 */ 223, 65, 64, 220, 127, 219, 68, 67, 66, 63,
- /* 280 */ 62, 61, 60, 59, 58, 185, 184, 183, 182, 181,
- /* 290 */ 3, 172, 7, 124, 218, 187, 84, 191, 194, 215,
- /* 300 */ 88, 123, 122, 135, 134, 133, 117, 85, 100, 113,
- /* 310 */ 101, 180, 211, 197, 74, 151, 224, 190, 186, 359,
- /* 320 */ 50, 49, 48, 47, 46, 45, 44, 43, 42, 41,
- /* 330 */ 40, 39, 38, 37, 359, 359, 65, 64, 148, 359,
- /* 340 */ 359, 68, 67, 66, 63, 62, 61, 60, 59, 58,
- /* 350 */ 185, 184, 183, 182, 181, 3, 118, 359, 147, 359,
- /* 360 */ 191, 194, 215, 88, 123, 122, 135, 134, 133, 117,
- /* 370 */ 85, 100, 113, 101, 180, 211, 197, 74, 115, 359,
- /* 380 */ 190, 186, 191, 194, 215, 88, 123, 122, 135, 134,
- /* 390 */ 133, 117, 85, 100, 113, 101, 180, 211, 197, 74,
- /* 400 */ 359, 359, 190, 186, 225, 359, 359, 82, 81, 78,
- /* 410 */ 222, 72, 359, 80, 140, 9, 359, 70, 359, 191,
- /* 420 */ 164, 215, 88, 123, 122, 135, 134, 133, 117, 85,
- /* 430 */ 100, 113, 101, 180, 211, 197, 74, 359, 7, 190,
- /* 440 */ 186, 187, 84, 359, 359, 169, 111, 191, 146, 215,
- /* 450 */ 88, 123, 122, 135, 134, 133, 117, 85, 100, 113,
- /* 460 */ 101, 180, 211, 197, 74, 359, 7, 190, 186, 187,
- /* 470 */ 84, 359, 359, 359, 359, 149, 359, 359, 359, 359,
- /* 480 */ 359, 359, 65, 64, 359, 359, 359, 68, 67, 66,
- /* 490 */ 63, 62, 61, 60, 59, 58, 185, 184, 183, 182,
- /* 500 */ 181, 3, 359, 359, 359, 359, 359, 359, 359, 359,
- /* 510 */ 65, 64, 359, 359, 359, 68, 67, 66, 63, 62,
- /* 520 */ 61, 60, 59, 58, 185, 184, 183, 182, 181, 3,
- /* 530 */ 191, 216, 215, 88, 123, 122, 135, 134, 133, 117,
- /* 540 */ 85, 100, 113, 101, 180, 211, 197, 74, 359, 359,
- /* 550 */ 190, 186, 191, 214, 215, 88, 123, 122, 135, 134,
- /* 560 */ 133, 117, 85, 100, 113, 101, 180, 211, 197, 74,
- /* 570 */ 359, 359, 190, 186, 191, 139, 215, 88, 123, 122,
- /* 580 */ 135, 134, 133, 117, 85, 100, 113, 101, 180, 211,
- /* 590 */ 197, 74, 359, 359, 190, 186, 359, 359, 191, 213,
- /* 600 */ 215, 88, 123, 122, 135, 134, 133, 117, 85, 100,
- /* 610 */ 113, 101, 180, 211, 197, 74, 359, 359, 190, 186,
- /* 620 */ 191, 174, 215, 88, 123, 122, 135, 134, 133, 117,
- /* 630 */ 85, 100, 113, 101, 180, 211, 197, 74, 359, 359,
- /* 640 */ 190, 186, 191, 165, 215, 88, 123, 122, 135, 134,
- /* 650 */ 133, 117, 85, 100, 113, 101, 180, 211, 197, 74,
- /* 660 */ 359, 359, 190, 186, 191, 163, 215, 88, 123, 122,
- /* 670 */ 135, 134, 133, 117, 85, 100, 113, 101, 180, 211,
- /* 680 */ 197, 74, 359, 359, 190, 186, 191, 162, 215, 88,
- /* 690 */ 123, 122, 135, 134, 133, 117, 85, 100, 113, 101,
- /* 700 */ 180, 211, 197, 74, 359, 359, 190, 186, 191, 161,
- /* 710 */ 215, 88, 123, 122, 135, 134, 133, 117, 85, 100,
- /* 720 */ 113, 101, 180, 211, 197, 74, 359, 359, 190, 186,
- /* 730 */ 191, 160, 215, 88, 123, 122, 135, 134, 133, 117,
- /* 740 */ 85, 100, 113, 101, 180, 211, 197, 74, 359, 359,
- /* 750 */ 190, 186, 191, 159, 215, 88, 123, 122, 135, 134,
- /* 760 */ 133, 117, 85, 100, 113, 101, 180, 211, 197, 74,
- /* 770 */ 359, 359, 190, 186, 191, 158, 215, 88, 123, 122,
- /* 780 */ 135, 134, 133, 117, 85, 100, 113, 101, 180, 211,
- /* 790 */ 197, 74, 359, 359, 190, 186, 191, 157, 215, 88,
- /* 800 */ 123, 122, 135, 134, 133, 117, 85, 100, 113, 101,
- /* 810 */ 180, 211, 197, 74, 359, 359, 190, 186, 191, 156,
- /* 820 */ 215, 88, 123, 122, 135, 134, 133, 117, 85, 100,
- /* 830 */ 113, 101, 180, 211, 197, 74, 359, 359, 190, 186,
- /* 840 */ 191, 155, 215, 88, 123, 122, 135, 134, 133, 117,
- /* 850 */ 85, 100, 113, 101, 180, 211, 197, 74, 359, 359,
- /* 860 */ 190, 186, 191, 154, 215, 88, 123, 122, 135, 134,
- /* 870 */ 133, 117, 85, 100, 113, 101, 180, 211, 197, 74,
- /* 880 */ 359, 359, 190, 186, 191, 153, 215, 88, 123, 122,
- /* 890 */ 135, 134, 133, 117, 85, 100, 113, 101, 180, 211,
- /* 900 */ 197, 74, 359, 359, 190, 186, 191, 177, 215, 88,
- /* 910 */ 123, 122, 135, 134, 133, 117, 85, 100, 113, 101,
- /* 920 */ 180, 211, 197, 74, 359, 359, 190, 186, 191, 171,
- /* 930 */ 215, 88, 123, 122, 135, 134, 133, 117, 85, 100,
- /* 940 */ 113, 101, 180, 211, 197, 74, 359, 191, 190, 186,
- /* 950 */ 119, 359, 110, 135, 134, 133, 117, 85, 100, 113,
- /* 960 */ 101, 180, 211, 197, 74, 359, 191, 190, 186, 119,
- /* 970 */ 359, 359, 138, 134, 133, 117, 85, 100, 113, 101,
- /* 980 */ 180, 211, 197, 74, 359, 359, 190, 186, 191, 359,
- /* 990 */ 359, 119, 359, 359, 130, 134, 133, 117, 85, 100,
- /* 1000 */ 113, 101, 180, 211, 197, 74, 359, 359, 190, 186,
- /* 1010 */ 191, 359, 359, 119, 359, 359, 359, 137, 133, 117,
- /* 1020 */ 85, 100, 113, 101, 180, 211, 197, 74, 359, 359,
- /* 1030 */ 190, 186, 359, 27, 22, 21, 20, 19, 18, 17,
- /* 1040 */ 16, 15, 14, 13, 12, 191, 359, 359, 119, 359,
- /* 1050 */ 359, 359, 359, 136, 117, 85, 100, 113, 101, 180,
- /* 1060 */ 211, 197, 74, 359, 359, 190, 186, 359, 359, 191,
- /* 1070 */ 359, 359, 119, 359, 359, 199, 198, 359, 121, 85,
- /* 1080 */ 100, 113, 101, 180, 211, 197, 74, 359, 191, 190,
- /* 1090 */ 186, 119, 7, 359, 359, 187, 84, 359, 87, 100,
- /* 1100 */ 113, 101, 180, 211, 197, 74, 359, 191, 190, 186,
- /* 1110 */ 119, 359, 359, 359, 359, 359, 359, 86, 100, 113,
- /* 1120 */ 101, 180, 211, 197, 74, 359, 191, 190, 186, 119,
- /* 1130 */ 359, 359, 359, 359, 359, 359, 359, 106, 113, 101,
- /* 1140 */ 180, 211, 197, 74, 359, 191, 190, 186, 119, 359,
- /* 1150 */ 185, 184, 183, 182, 181, 3, 104, 113, 101, 180,
- /* 1160 */ 211, 197, 74, 359, 191, 190, 186, 119, 359, 359,
- /* 1170 */ 359, 359, 359, 359, 359, 102, 113, 101, 180, 211,
- /* 1180 */ 197, 74, 359, 191, 190, 186, 119, 359, 359, 359,
- /* 1190 */ 359, 359, 359, 359, 99, 113, 101, 180, 211, 197,
- /* 1200 */ 74, 359, 191, 190, 186, 119, 359, 359, 359, 359,
- /* 1210 */ 359, 359, 359, 98, 113, 101, 180, 211, 197, 74,
- /* 1220 */ 359, 191, 190, 186, 119, 359, 359, 359, 359, 359,
- /* 1230 */ 359, 359, 97, 113, 101, 180, 211, 197, 74, 359,
- /* 1240 */ 191, 190, 186, 119, 359, 359, 359, 359, 359, 359,
- /* 1250 */ 359, 96, 113, 101, 180, 211, 197, 74, 359, 191,
- /* 1260 */ 190, 186, 119, 359, 359, 359, 359, 359, 359, 359,
- /* 1270 */ 95, 113, 101, 180, 211, 197, 74, 359, 191, 190,
- /* 1280 */ 186, 119, 359, 359, 359, 359, 359, 359, 359, 94,
- /* 1290 */ 113, 101, 180, 211, 197, 74, 359, 191, 190, 186,
- /* 1300 */ 119, 359, 359, 359, 359, 359, 359, 359, 93, 113,
- /* 1310 */ 101, 180, 211, 197, 74, 359, 191, 190, 186, 119,
- /* 1320 */ 359, 359, 359, 359, 359, 359, 359, 92, 113, 101,
- /* 1330 */ 180, 211, 197, 74, 359, 191, 190, 186, 119, 359,
- /* 1340 */ 359, 359, 359, 359, 359, 359, 91, 113, 101, 180,
- /* 1350 */ 211, 197, 74, 359, 191, 190, 186, 119, 359, 359,
- /* 1360 */ 359, 359, 359, 359, 359, 90, 113, 101, 180, 211,
- /* 1370 */ 197, 74, 359, 191, 190, 186, 119, 359, 359, 359,
- /* 1380 */ 359, 359, 359, 359, 89, 113, 101, 180, 211, 197,
- /* 1390 */ 74, 359, 191, 190, 186, 119, 359, 359, 359, 359,
- /* 1400 */ 359, 359, 359, 359, 120, 101, 180, 211, 197, 74,
- /* 1410 */ 359, 191, 190, 186, 119, 359, 359, 359, 359, 359,
- /* 1420 */ 359, 359, 359, 116, 101, 180, 211, 197, 74, 359,
- /* 1430 */ 191, 190, 186, 119, 359, 359, 359, 359, 359, 359,
- /* 1440 */ 359, 359, 114, 101, 180, 211, 197, 74, 359, 191,
- /* 1450 */ 190, 186, 119, 359, 359, 359, 359, 359, 191, 359,
- /* 1460 */ 359, 119, 105, 180, 211, 197, 74, 359, 359, 190,
- /* 1470 */ 186, 103, 180, 211, 197, 74, 359, 191, 190, 186,
- /* 1480 */ 119, 359, 359, 359, 359, 359, 359, 191, 359, 359,
- /* 1490 */ 119, 212, 211, 197, 74, 359, 191, 190, 186, 119,
- /* 1500 */ 359, 210, 211, 197, 74, 359, 191, 190, 186, 119,
- /* 1510 */ 209, 211, 197, 74, 359, 191, 190, 186, 119, 359,
- /* 1520 */ 208, 211, 197, 74, 359, 191, 190, 186, 119, 207,
- /* 1530 */ 211, 197, 74, 359, 191, 190, 186, 119, 359, 206,
- /* 1540 */ 211, 197, 74, 359, 191, 190, 186, 119, 205, 211,
- /* 1550 */ 197, 74, 359, 191, 190, 186, 119, 359, 204, 211,
- /* 1560 */ 197, 74, 359, 191, 190, 186, 119, 203, 211, 197,
- /* 1570 */ 74, 359, 359, 190, 186, 359, 359, 202, 211, 197,
- /* 1580 */ 74, 359, 191, 190, 186, 119, 359, 359, 359, 359,
- /* 1590 */ 191, 359, 359, 119, 359, 359, 201, 211, 197, 74,
- /* 1600 */ 359, 359, 190, 186, 200, 211, 197, 74, 359, 191,
- /* 1610 */ 190, 186, 119, 359, 359, 359, 359, 191, 359, 359,
- /* 1620 */ 119, 359, 359, 192, 211, 197, 74, 359, 359, 190,
- /* 1630 */ 186, 188, 211, 197, 74, 359, 359, 190, 186,
+ /* 0 */ 3, 72, 115, 115, 136, 131, 323, 2, 363, 54,
+ /* 10 */ 83, 129, 1, 232, 71, 505, 79, 112, 10, 241,
+ /* 20 */ 79, 75, 112, 112, 91, 126, 125, 139, 138, 137,
+ /* 30 */ 120, 88, 103, 116, 104, 104, 104, 91, 75, 241,
+ /* 40 */ 241, 75, 75, 323, 74, 457, 84, 83, 144, 9,
+ /* 50 */ 236, 71, 66, 65, 53, 52, 51, 69, 68, 67,
+ /* 60 */ 64, 63, 61, 60, 59, 348, 349, 350, 351, 352,
+ /* 70 */ 4, 127, 70, 58, 57, 75, 127, 127, 91, 126,
+ /* 80 */ 125, 139, 138, 137, 120, 88, 103, 116, 104, 104,
+ /* 90 */ 104, 91, 75, 78, 456, 75, 75, 78, 76, 115,
+ /* 100 */ 115, 136, 235, 323, 2, 499, 54, 83, 129, 1,
+ /* 110 */ 5, 71, 78, 118, 110, 82, 78, 75, 118, 118,
+ /* 120 */ 91, 126, 125, 139, 138, 137, 120, 88, 103, 116,
+ /* 130 */ 104, 104, 104, 91, 75, 315, 133, 75, 75, 7,
+ /* 140 */ 300, 62, 77, 346, 73, 110, 133, 362, 136, 66,
+ /* 150 */ 65, 299, 343, 239, 69, 68, 67, 64, 63, 61,
+ /* 160 */ 60, 59, 348, 349, 350, 351, 352, 4, 50, 49,
+ /* 170 */ 48, 47, 46, 45, 44, 43, 42, 41, 40, 39,
+ /* 180 */ 38, 37, 31, 30, 66, 65, 312, 56, 55, 69,
+ /* 190 */ 68, 67, 64, 63, 61, 60, 59, 348, 349, 350,
+ /* 200 */ 351, 352, 4, 111, 238, 313, 75, 314, 314, 91,
+ /* 210 */ 126, 125, 139, 138, 137, 120, 88, 103, 116, 104,
+ /* 220 */ 104, 104, 91, 75, 36, 35, 75, 75, 7, 237,
+ /* 230 */ 62, 6, 346, 73, 309, 240, 357, 28, 75, 87,
+ /* 240 */ 87, 91, 126, 125, 139, 138, 137, 120, 88, 103,
+ /* 250 */ 116, 104, 104, 104, 91, 75, 304, 234, 75, 75,
+ /* 260 */ 11, 87, 7, 23, 62, 233, 346, 73, 297, 298,
+ /* 270 */ 357, 7, 356, 66, 65, 346, 73, 130, 69, 68,
+ /* 280 */ 67, 64, 63, 61, 60, 59, 348, 349, 350, 351,
+ /* 290 */ 352, 4, 354, 7, 8, 62, 135, 346, 73, 345,
+ /* 300 */ 317, 356, 32, 29, 316, 132, 28, 66, 65, 364,
+ /* 310 */ 24, 34, 69, 68, 67, 64, 63, 61, 60, 59,
+ /* 320 */ 348, 349, 350, 351, 352, 4, 353, 26, 355, 348,
+ /* 330 */ 349, 350, 351, 352, 4, 33, 25, 370, 66, 65,
+ /* 340 */ 370, 370, 370, 69, 68, 67, 64, 63, 61, 60,
+ /* 350 */ 59, 348, 349, 350, 351, 352, 4, 75, 314, 314,
+ /* 360 */ 91, 126, 125, 139, 138, 137, 120, 88, 103, 116,
+ /* 370 */ 104, 104, 104, 91, 75, 370, 370, 75, 75, 370,
+ /* 380 */ 370, 370, 370, 370, 370, 311, 28, 370, 370, 370,
+ /* 390 */ 370, 75, 306, 306, 91, 126, 125, 139, 138, 137,
+ /* 400 */ 120, 88, 103, 116, 104, 104, 104, 91, 75, 370,
+ /* 410 */ 370, 75, 75, 370, 370, 370, 370, 370, 114, 118,
+ /* 420 */ 370, 370, 370, 75, 118, 118, 91, 126, 125, 139,
+ /* 430 */ 138, 137, 120, 88, 103, 116, 104, 104, 104, 91,
+ /* 440 */ 75, 121, 303, 75, 75, 75, 121, 121, 91, 126,
+ /* 450 */ 125, 139, 138, 137, 120, 88, 103, 116, 104, 104,
+ /* 460 */ 104, 91, 75, 370, 370, 75, 75, 370, 7, 370,
+ /* 470 */ 62, 127, 346, 73, 370, 75, 127, 127, 91, 126,
+ /* 480 */ 125, 139, 138, 137, 120, 88, 103, 116, 104, 104,
+ /* 490 */ 104, 91, 75, 455, 370, 75, 75, 7, 370, 62,
+ /* 500 */ 370, 346, 73, 370, 370, 370, 370, 370, 370, 28,
+ /* 510 */ 370, 370, 370, 66, 65, 370, 370, 370, 69, 68,
+ /* 520 */ 67, 64, 63, 61, 60, 59, 348, 349, 128, 351,
+ /* 530 */ 352, 4, 370, 370, 370, 370, 370, 370, 370, 370,
+ /* 540 */ 370, 370, 66, 65, 370, 370, 370, 69, 68, 67,
+ /* 550 */ 64, 63, 61, 60, 59, 348, 349, 350, 351, 352,
+ /* 560 */ 4, 75, 360, 360, 91, 126, 125, 139, 138, 137,
+ /* 570 */ 120, 88, 103, 116, 104, 104, 104, 91, 75, 370,
+ /* 580 */ 370, 75, 75, 75, 359, 359, 91, 126, 125, 139,
+ /* 590 */ 138, 137, 120, 88, 103, 116, 104, 104, 104, 91,
+ /* 600 */ 75, 370, 370, 75, 75, 75, 254, 254, 91, 126,
+ /* 610 */ 125, 139, 138, 137, 120, 88, 103, 116, 104, 104,
+ /* 620 */ 104, 91, 75, 370, 370, 75, 75, 75, 253, 253,
+ /* 630 */ 91, 126, 125, 139, 138, 137, 120, 88, 103, 116,
+ /* 640 */ 104, 104, 104, 91, 75, 370, 370, 75, 75, 75,
+ /* 650 */ 252, 252, 91, 126, 125, 139, 138, 137, 120, 88,
+ /* 660 */ 103, 116, 104, 104, 104, 91, 75, 370, 370, 75,
+ /* 670 */ 75, 75, 251, 251, 91, 126, 125, 139, 138, 137,
+ /* 680 */ 120, 88, 103, 116, 104, 104, 104, 91, 75, 370,
+ /* 690 */ 370, 75, 75, 75, 250, 250, 91, 126, 125, 139,
+ /* 700 */ 138, 137, 120, 88, 103, 116, 104, 104, 104, 91,
+ /* 710 */ 75, 370, 370, 75, 75, 75, 249, 249, 91, 126,
+ /* 720 */ 125, 139, 138, 137, 120, 88, 103, 116, 104, 104,
+ /* 730 */ 104, 91, 75, 370, 370, 75, 75, 75, 248, 248,
+ /* 740 */ 91, 126, 125, 139, 138, 137, 120, 88, 103, 116,
+ /* 750 */ 104, 104, 104, 91, 75, 370, 370, 75, 75, 75,
+ /* 760 */ 247, 247, 91, 126, 125, 139, 138, 137, 120, 88,
+ /* 770 */ 103, 116, 104, 104, 104, 91, 75, 370, 370, 75,
+ /* 780 */ 75, 75, 246, 246, 91, 126, 125, 139, 138, 137,
+ /* 790 */ 120, 88, 103, 116, 104, 104, 104, 91, 75, 370,
+ /* 800 */ 370, 75, 75, 75, 245, 245, 91, 126, 125, 139,
+ /* 810 */ 138, 137, 120, 88, 103, 116, 104, 104, 104, 91,
+ /* 820 */ 75, 370, 370, 75, 75, 75, 244, 244, 91, 126,
+ /* 830 */ 125, 139, 138, 137, 120, 88, 103, 116, 104, 104,
+ /* 840 */ 104, 91, 75, 370, 370, 75, 75, 75, 307, 307,
+ /* 850 */ 91, 126, 125, 139, 138, 137, 120, 88, 103, 116,
+ /* 860 */ 104, 104, 104, 91, 75, 370, 370, 75, 75, 75,
+ /* 870 */ 302, 302, 91, 126, 125, 139, 138, 137, 120, 88,
+ /* 880 */ 103, 116, 104, 104, 104, 91, 75, 370, 370, 75,
+ /* 890 */ 75, 75, 255, 255, 91, 126, 125, 139, 138, 137,
+ /* 900 */ 120, 88, 103, 116, 104, 104, 104, 91, 75, 370,
+ /* 910 */ 370, 75, 75, 75, 143, 143, 91, 126, 125, 139,
+ /* 920 */ 138, 137, 120, 88, 103, 116, 104, 104, 104, 91,
+ /* 930 */ 75, 370, 370, 75, 75, 75, 243, 243, 91, 126,
+ /* 940 */ 125, 139, 138, 137, 120, 88, 103, 116, 104, 104,
+ /* 950 */ 104, 91, 75, 370, 370, 75, 75, 75, 242, 242,
+ /* 960 */ 91, 126, 125, 139, 138, 137, 120, 88, 103, 116,
+ /* 970 */ 104, 104, 104, 91, 75, 370, 75, 75, 75, 122,
+ /* 980 */ 370, 113, 139, 138, 137, 120, 88, 103, 116, 104,
+ /* 990 */ 104, 104, 122, 75, 370, 75, 75, 75, 122, 370,
+ /* 1000 */ 370, 134, 138, 137, 120, 88, 103, 116, 104, 104,
+ /* 1010 */ 104, 122, 75, 370, 75, 75, 75, 122, 370, 370,
+ /* 1020 */ 142, 138, 137, 120, 88, 103, 116, 104, 104, 104,
+ /* 1030 */ 122, 75, 370, 75, 75, 75, 122, 370, 370, 370,
+ /* 1040 */ 141, 137, 120, 88, 103, 116, 104, 104, 104, 122,
+ /* 1050 */ 75, 370, 75, 75, 75, 122, 370, 370, 370, 370,
+ /* 1060 */ 140, 120, 88, 103, 116, 104, 104, 104, 122, 75,
+ /* 1070 */ 370, 370, 75, 75, 370, 370, 370, 370, 27, 22,
+ /* 1080 */ 21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
+ /* 1090 */ 75, 370, 370, 122, 370, 370, 370, 370, 370, 124,
+ /* 1100 */ 88, 103, 116, 104, 104, 104, 122, 75, 370, 370,
+ /* 1110 */ 75, 75, 75, 370, 370, 122, 370, 370, 370, 370,
+ /* 1120 */ 297, 298, 89, 103, 116, 104, 104, 104, 122, 75,
+ /* 1130 */ 370, 75, 75, 75, 122, 370, 370, 370, 370, 370,
+ /* 1140 */ 370, 90, 103, 116, 104, 104, 104, 122, 75, 370,
+ /* 1150 */ 370, 75, 75, 370, 370, 86, 85, 81, 80, 323,
+ /* 1160 */ 74, 324, 84, 83, 144, 9, 454, 71, 370, 86,
+ /* 1170 */ 85, 81, 80, 323, 74, 370, 84, 83, 144, 9,
+ /* 1180 */ 370, 71, 370, 75, 370, 370, 122, 370, 370, 370,
+ /* 1190 */ 370, 370, 370, 370, 92, 116, 104, 104, 104, 122,
+ /* 1200 */ 75, 370, 370, 75, 75, 75, 370, 370, 122, 370,
+ /* 1210 */ 370, 370, 370, 370, 370, 370, 93, 116, 104, 104,
+ /* 1220 */ 104, 122, 75, 370, 370, 75, 75, 75, 370, 370,
+ /* 1230 */ 122, 370, 370, 370, 370, 370, 370, 370, 94, 116,
+ /* 1240 */ 104, 104, 104, 122, 75, 370, 75, 75, 75, 122,
+ /* 1250 */ 370, 370, 370, 370, 370, 370, 370, 95, 116, 104,
+ /* 1260 */ 104, 104, 122, 75, 370, 75, 75, 75, 122, 370,
+ /* 1270 */ 370, 370, 370, 370, 370, 370, 96, 116, 104, 104,
+ /* 1280 */ 104, 122, 75, 370, 75, 75, 75, 122, 370, 370,
+ /* 1290 */ 370, 370, 370, 370, 370, 97, 116, 104, 104, 104,
+ /* 1300 */ 122, 75, 370, 75, 75, 75, 122, 370, 370, 370,
+ /* 1310 */ 370, 370, 370, 370, 98, 116, 104, 104, 104, 122,
+ /* 1320 */ 75, 370, 75, 75, 75, 122, 370, 370, 370, 370,
+ /* 1330 */ 370, 370, 370, 99, 116, 104, 104, 104, 122, 75,
+ /* 1340 */ 370, 75, 75, 75, 122, 370, 370, 370, 370, 370,
+ /* 1350 */ 370, 370, 100, 116, 104, 104, 104, 122, 75, 370,
+ /* 1360 */ 75, 75, 75, 122, 370, 370, 370, 370, 370, 370,
+ /* 1370 */ 370, 101, 116, 104, 104, 104, 122, 75, 370, 75,
+ /* 1380 */ 75, 75, 122, 370, 370, 370, 370, 370, 370, 370,
+ /* 1390 */ 102, 116, 104, 104, 104, 122, 75, 370, 75, 75,
+ /* 1400 */ 75, 122, 370, 370, 370, 370, 370, 370, 370, 105,
+ /* 1410 */ 116, 104, 104, 104, 122, 75, 370, 75, 75, 75,
+ /* 1420 */ 122, 370, 370, 370, 370, 370, 370, 370, 107, 116,
+ /* 1430 */ 104, 104, 104, 122, 75, 370, 75, 75, 75, 122,
+ /* 1440 */ 370, 370, 370, 370, 370, 370, 370, 109, 116, 104,
+ /* 1450 */ 104, 104, 122, 75, 370, 75, 75, 75, 122, 370,
+ /* 1460 */ 370, 370, 370, 370, 370, 370, 370, 117, 104, 104,
+ /* 1470 */ 104, 122, 75, 370, 75, 75, 75, 122, 370, 370,
+ /* 1480 */ 370, 370, 370, 370, 370, 370, 119, 104, 104, 104,
+ /* 1490 */ 122, 75, 370, 75, 75, 75, 122, 370, 370, 370,
+ /* 1500 */ 237, 75, 370, 370, 122, 123, 104, 104, 104, 122,
+ /* 1510 */ 75, 370, 370, 75, 75, 293, 293, 122, 75, 370,
+ /* 1520 */ 75, 75, 75, 122, 370, 370, 370, 370, 370, 370,
+ /* 1530 */ 370, 370, 370, 106, 106, 106, 122, 75, 370, 75,
+ /* 1540 */ 75, 75, 122, 370, 370, 370, 370, 370, 370, 370,
+ /* 1550 */ 370, 370, 108, 108, 108, 122, 75, 370, 75, 75,
+ /* 1560 */ 75, 122, 370, 370, 370, 370, 370, 370, 370, 370,
+ /* 1570 */ 370, 370, 285, 285, 122, 75, 370, 75, 75, 75,
+ /* 1580 */ 122, 370, 370, 370, 370, 75, 370, 370, 122, 370,
+ /* 1590 */ 370, 284, 284, 122, 75, 370, 370, 75, 75, 296,
+ /* 1600 */ 296, 122, 75, 370, 75, 75, 75, 122, 370, 370,
+ /* 1610 */ 370, 370, 370, 370, 370, 370, 370, 370, 295, 295,
+ /* 1620 */ 122, 75, 370, 75, 75, 75, 122, 370, 370, 370,
+ /* 1630 */ 370, 370, 370, 370, 370, 370, 370, 294, 294, 122,
+ /* 1640 */ 75, 370, 75, 75, 75, 122, 370, 370, 370, 370,
+ /* 1650 */ 370, 370, 370, 370, 370, 370, 293, 293, 122, 75,
+ /* 1660 */ 370, 75, 75, 75, 122, 370, 370, 370, 370, 75,
+ /* 1670 */ 370, 370, 122, 370, 370, 292, 292, 122, 75, 370,
+ /* 1680 */ 370, 75, 75, 291, 291, 122, 75, 370, 75, 75,
+ /* 1690 */ 75, 122, 370, 370, 370, 370, 370, 370, 370, 370,
+ /* 1700 */ 370, 370, 290, 290, 122, 75, 370, 75, 75, 75,
+ /* 1710 */ 122, 370, 370, 370, 370, 370, 370, 370, 370, 370,
+ /* 1720 */ 370, 289, 289, 122, 75, 370, 75, 75, 75, 122,
+ /* 1730 */ 370, 370, 370, 370, 370, 370, 370, 370, 370, 370,
+ /* 1740 */ 288, 288, 122, 75, 370, 75, 75, 75, 122, 370,
+ /* 1750 */ 370, 370, 370, 75, 370, 370, 122, 370, 370, 287,
+ /* 1760 */ 287, 122, 75, 370, 370, 75, 75, 286, 286, 122,
+ /* 1770 */ 75, 370, 75, 75, 75, 122, 370, 370, 370, 370,
+ /* 1780 */ 370, 370, 370, 370, 370, 370, 283, 283, 122, 75,
+ /* 1790 */ 370, 370, 75, 75,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 1, 2, 48, 49, 50, 6, 7, 77, 9, 10,
- /* 10 */ 11, 81, 13, 76, 77, 78, 14, 82, 81, 82,
- /* 20 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 30 */ 93, 94, 95, 96, 97, 98, 99, 102, 103, 102,
- /* 40 */ 103, 6, 7, 9, 9, 10, 11, 8, 13, 28,
- /* 50 */ 51, 52, 12, 14, 14, 56, 57, 58, 59, 60,
+ /* 0 */ 1, 2, 107, 108, 109, 12, 7, 8, 68, 10,
+ /* 10 */ 11, 12, 13, 82, 15, 77, 78, 79, 105, 83,
+ /* 20 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ /* 30 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 103,
+ /* 40 */ 104, 103, 104, 7, 8, 0, 10, 11, 12, 13,
+ /* 50 */ 82, 15, 53, 54, 50, 51, 52, 58, 59, 60,
/* 60 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- /* 70 */ 77, 78, 7, 71, 81, 82, 83, 84, 85, 86,
- /* 80 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
- /* 90 */ 97, 98, 99, 8, 80, 102, 103, 6, 7, 14,
- /* 100 */ 9, 10, 11, 78, 13, 3, 4, 82, 83, 84,
- /* 110 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- /* 120 */ 95, 96, 97, 98, 99, 111, 112, 102, 103, 32,
- /* 130 */ 33, 106, 53, 54, 55, 70, 29, 72, 51, 52,
- /* 140 */ 31, 5, 51, 52, 12, 30, 14, 56, 57, 58,
- /* 150 */ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
- /* 160 */ 69, 70, 7, 27, 53, 10, 11, 57, 58, 14,
- /* 170 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- /* 180 */ 92, 93, 94, 95, 96, 97, 98, 99, 111, 112,
- /* 190 */ 102, 103, 104, 105, 3, 4, 5, 6, 7, 8,
- /* 200 */ 9, 10, 11, 10, 13, 28, 51, 52, 0, 14,
- /* 210 */ 10, 56, 57, 58, 59, 60, 61, 62, 63, 64,
- /* 220 */ 65, 66, 67, 68, 69, 70, 71, 7, 100, 101,
- /* 230 */ 10, 11, 79, 65, 14, 82, 83, 84, 85, 86,
- /* 240 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
- /* 250 */ 97, 98, 99, 0, 0, 102, 103, 39, 65, 51,
- /* 260 */ 67, 107, 108, 110, 67, 106, 71, 14, 14, 104,
- /* 270 */ 81, 51, 52, 81, 10, 81, 56, 57, 58, 59,
+ /* 70 */ 71, 79, 55, 56, 57, 83, 84, 85, 86, 87,
+ /* 80 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ /* 90 */ 98, 99, 100, 78, 0, 103, 104, 82, 53, 107,
+ /* 100 */ 108, 109, 82, 7, 8, 30, 10, 11, 12, 13,
+ /* 110 */ 16, 15, 78, 79, 81, 11, 82, 83, 84, 85,
+ /* 120 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ /* 130 */ 96, 97, 98, 99, 100, 112, 113, 103, 104, 8,
+ /* 140 */ 14, 10, 16, 12, 13, 112, 113, 108, 109, 53,
+ /* 150 */ 54, 101, 102, 82, 58, 59, 60, 61, 62, 63,
+ /* 160 */ 64, 65, 66, 67, 68, 69, 70, 71, 36, 37,
+ /* 170 */ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ /* 180 */ 48, 49, 3, 4, 53, 54, 55, 53, 54, 58,
+ /* 190 */ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ /* 200 */ 69, 70, 71, 80, 82, 74, 83, 84, 85, 86,
+ /* 210 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+ /* 220 */ 97, 98, 99, 100, 34, 35, 103, 104, 8, 82,
+ /* 230 */ 10, 8, 12, 13, 111, 14, 16, 16, 83, 84,
+ /* 240 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ /* 250 */ 95, 96, 97, 98, 99, 100, 9, 82, 103, 104,
+ /* 260 */ 105, 106, 8, 16, 10, 82, 12, 13, 59, 60,
+ /* 270 */ 16, 8, 16, 53, 54, 12, 13, 41, 58, 59,
/* 280 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- /* 290 */ 70, 71, 7, 78, 81, 10, 11, 82, 83, 84,
- /* 300 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- /* 310 */ 95, 96, 97, 98, 99, 81, 81, 102, 103, 113,
- /* 320 */ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
- /* 330 */ 44, 45, 46, 47, 113, 113, 51, 52, 53, 113,
- /* 340 */ 113, 56, 57, 58, 59, 60, 61, 62, 63, 64,
- /* 350 */ 65, 66, 67, 68, 69, 70, 78, 113, 73, 113,
- /* 360 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- /* 370 */ 92, 93, 94, 95, 96, 97, 98, 99, 78, 113,
- /* 380 */ 102, 103, 82, 83, 84, 85, 86, 87, 88, 89,
- /* 390 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- /* 400 */ 113, 113, 102, 103, 0, 113, 113, 3, 4, 5,
- /* 410 */ 6, 7, 113, 9, 10, 11, 113, 13, 113, 82,
- /* 420 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 430 */ 93, 94, 95, 96, 97, 98, 99, 113, 7, 102,
- /* 440 */ 103, 10, 11, 113, 113, 14, 109, 82, 83, 84,
- /* 450 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- /* 460 */ 95, 96, 97, 98, 99, 113, 7, 102, 103, 10,
- /* 470 */ 11, 113, 113, 113, 113, 110, 113, 113, 113, 113,
- /* 480 */ 113, 113, 51, 52, 113, 113, 113, 56, 57, 58,
- /* 490 */ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
- /* 500 */ 69, 70, 113, 113, 113, 113, 113, 113, 113, 113,
- /* 510 */ 51, 52, 113, 113, 113, 56, 57, 58, 59, 60,
- /* 520 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- /* 530 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- /* 540 */ 92, 93, 94, 95, 96, 97, 98, 99, 113, 113,
- /* 550 */ 102, 103, 82, 83, 84, 85, 86, 87, 88, 89,
- /* 560 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- /* 570 */ 113, 113, 102, 103, 82, 83, 84, 85, 86, 87,
- /* 580 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
- /* 590 */ 98, 99, 113, 113, 102, 103, 113, 113, 82, 83,
- /* 600 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 610 */ 94, 95, 96, 97, 98, 99, 113, 113, 102, 103,
- /* 620 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- /* 630 */ 92, 93, 94, 95, 96, 97, 98, 99, 113, 113,
- /* 640 */ 102, 103, 82, 83, 84, 85, 86, 87, 88, 89,
- /* 650 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- /* 660 */ 113, 113, 102, 103, 82, 83, 84, 85, 86, 87,
- /* 670 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
- /* 680 */ 98, 99, 113, 113, 102, 103, 82, 83, 84, 85,
- /* 690 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- /* 700 */ 96, 97, 98, 99, 113, 113, 102, 103, 82, 83,
- /* 710 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 720 */ 94, 95, 96, 97, 98, 99, 113, 113, 102, 103,
- /* 730 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- /* 740 */ 92, 93, 94, 95, 96, 97, 98, 99, 113, 113,
- /* 750 */ 102, 103, 82, 83, 84, 85, 86, 87, 88, 89,
- /* 760 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- /* 770 */ 113, 113, 102, 103, 82, 83, 84, 85, 86, 87,
- /* 780 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
- /* 790 */ 98, 99, 113, 113, 102, 103, 82, 83, 84, 85,
- /* 800 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- /* 810 */ 96, 97, 98, 99, 113, 113, 102, 103, 82, 83,
- /* 820 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 830 */ 94, 95, 96, 97, 98, 99, 113, 113, 102, 103,
- /* 840 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- /* 850 */ 92, 93, 94, 95, 96, 97, 98, 99, 113, 113,
- /* 860 */ 102, 103, 82, 83, 84, 85, 86, 87, 88, 89,
- /* 870 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- /* 880 */ 113, 113, 102, 103, 82, 83, 84, 85, 86, 87,
- /* 890 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
- /* 900 */ 98, 99, 113, 113, 102, 103, 82, 83, 84, 85,
- /* 910 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- /* 920 */ 96, 97, 98, 99, 113, 113, 102, 103, 82, 83,
- /* 930 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 940 */ 94, 95, 96, 97, 98, 99, 113, 82, 102, 103,
- /* 950 */ 85, 113, 87, 88, 89, 90, 91, 92, 93, 94,
- /* 960 */ 95, 96, 97, 98, 99, 113, 82, 102, 103, 85,
- /* 970 */ 113, 113, 88, 89, 90, 91, 92, 93, 94, 95,
- /* 980 */ 96, 97, 98, 99, 113, 113, 102, 103, 82, 113,
- /* 990 */ 113, 85, 113, 113, 88, 89, 90, 91, 92, 93,
- /* 1000 */ 94, 95, 96, 97, 98, 99, 113, 113, 102, 103,
- /* 1010 */ 82, 113, 113, 85, 113, 113, 113, 89, 90, 91,
- /* 1020 */ 92, 93, 94, 95, 96, 97, 98, 99, 113, 113,
- /* 1030 */ 102, 103, 113, 15, 16, 17, 18, 19, 20, 21,
- /* 1040 */ 22, 23, 24, 25, 26, 82, 113, 113, 85, 113,
- /* 1050 */ 113, 113, 113, 90, 91, 92, 93, 94, 95, 96,
- /* 1060 */ 97, 98, 99, 113, 113, 102, 103, 113, 113, 82,
- /* 1070 */ 113, 113, 85, 113, 113, 57, 58, 113, 91, 92,
- /* 1080 */ 93, 94, 95, 96, 97, 98, 99, 113, 82, 102,
- /* 1090 */ 103, 85, 7, 113, 113, 10, 11, 113, 92, 93,
- /* 1100 */ 94, 95, 96, 97, 98, 99, 113, 82, 102, 103,
- /* 1110 */ 85, 113, 113, 113, 113, 113, 113, 92, 93, 94,
- /* 1120 */ 95, 96, 97, 98, 99, 113, 82, 102, 103, 85,
- /* 1130 */ 113, 113, 113, 113, 113, 113, 113, 93, 94, 95,
- /* 1140 */ 96, 97, 98, 99, 113, 82, 102, 103, 85, 113,
- /* 1150 */ 65, 66, 67, 68, 69, 70, 93, 94, 95, 96,
- /* 1160 */ 97, 98, 99, 113, 82, 102, 103, 85, 113, 113,
- /* 1170 */ 113, 113, 113, 113, 113, 93, 94, 95, 96, 97,
- /* 1180 */ 98, 99, 113, 82, 102, 103, 85, 113, 113, 113,
- /* 1190 */ 113, 113, 113, 113, 93, 94, 95, 96, 97, 98,
- /* 1200 */ 99, 113, 82, 102, 103, 85, 113, 113, 113, 113,
- /* 1210 */ 113, 113, 113, 93, 94, 95, 96, 97, 98, 99,
- /* 1220 */ 113, 82, 102, 103, 85, 113, 113, 113, 113, 113,
- /* 1230 */ 113, 113, 93, 94, 95, 96, 97, 98, 99, 113,
- /* 1240 */ 82, 102, 103, 85, 113, 113, 113, 113, 113, 113,
- /* 1250 */ 113, 93, 94, 95, 96, 97, 98, 99, 113, 82,
- /* 1260 */ 102, 103, 85, 113, 113, 113, 113, 113, 113, 113,
- /* 1270 */ 93, 94, 95, 96, 97, 98, 99, 113, 82, 102,
- /* 1280 */ 103, 85, 113, 113, 113, 113, 113, 113, 113, 93,
- /* 1290 */ 94, 95, 96, 97, 98, 99, 113, 82, 102, 103,
- /* 1300 */ 85, 113, 113, 113, 113, 113, 113, 113, 93, 94,
- /* 1310 */ 95, 96, 97, 98, 99, 113, 82, 102, 103, 85,
- /* 1320 */ 113, 113, 113, 113, 113, 113, 113, 93, 94, 95,
- /* 1330 */ 96, 97, 98, 99, 113, 82, 102, 103, 85, 113,
- /* 1340 */ 113, 113, 113, 113, 113, 113, 93, 94, 95, 96,
- /* 1350 */ 97, 98, 99, 113, 82, 102, 103, 85, 113, 113,
- /* 1360 */ 113, 113, 113, 113, 113, 93, 94, 95, 96, 97,
- /* 1370 */ 98, 99, 113, 82, 102, 103, 85, 113, 113, 113,
- /* 1380 */ 113, 113, 113, 113, 93, 94, 95, 96, 97, 98,
- /* 1390 */ 99, 113, 82, 102, 103, 85, 113, 113, 113, 113,
- /* 1400 */ 113, 113, 113, 113, 94, 95, 96, 97, 98, 99,
- /* 1410 */ 113, 82, 102, 103, 85, 113, 113, 113, 113, 113,
- /* 1420 */ 113, 113, 113, 94, 95, 96, 97, 98, 99, 113,
- /* 1430 */ 82, 102, 103, 85, 113, 113, 113, 113, 113, 113,
- /* 1440 */ 113, 113, 94, 95, 96, 97, 98, 99, 113, 82,
- /* 1450 */ 102, 103, 85, 113, 113, 113, 113, 113, 82, 113,
- /* 1460 */ 113, 85, 95, 96, 97, 98, 99, 113, 113, 102,
- /* 1470 */ 103, 95, 96, 97, 98, 99, 113, 82, 102, 103,
- /* 1480 */ 85, 113, 113, 113, 113, 113, 113, 82, 113, 113,
- /* 1490 */ 85, 96, 97, 98, 99, 113, 82, 102, 103, 85,
- /* 1500 */ 113, 96, 97, 98, 99, 113, 82, 102, 103, 85,
- /* 1510 */ 96, 97, 98, 99, 113, 82, 102, 103, 85, 113,
- /* 1520 */ 96, 97, 98, 99, 113, 82, 102, 103, 85, 96,
- /* 1530 */ 97, 98, 99, 113, 82, 102, 103, 85, 113, 96,
- /* 1540 */ 97, 98, 99, 113, 82, 102, 103, 85, 96, 97,
- /* 1550 */ 98, 99, 113, 82, 102, 103, 85, 113, 96, 97,
- /* 1560 */ 98, 99, 113, 82, 102, 103, 85, 96, 97, 98,
- /* 1570 */ 99, 113, 113, 102, 103, 113, 113, 96, 97, 98,
- /* 1580 */ 99, 113, 82, 102, 103, 85, 113, 113, 113, 113,
- /* 1590 */ 82, 113, 113, 85, 113, 113, 96, 97, 98, 99,
- /* 1600 */ 113, 113, 102, 103, 96, 97, 98, 99, 113, 82,
- /* 1610 */ 102, 103, 85, 113, 113, 113, 113, 82, 113, 113,
- /* 1620 */ 85, 113, 113, 96, 97, 98, 99, 113, 113, 102,
- /* 1630 */ 103, 96, 97, 98, 99, 113, 113, 102, 103,
+ /* 290 */ 70, 71, 72, 8, 71, 10, 73, 12, 13, 9,
+ /* 300 */ 68, 16, 31, 5, 66, 55, 16, 53, 54, 12,
+ /* 310 */ 30, 33, 58, 59, 60, 61, 62, 63, 64, 65,
+ /* 320 */ 66, 67, 68, 69, 70, 71, 72, 29, 72, 66,
+ /* 330 */ 67, 68, 69, 70, 71, 32, 30, 114, 53, 54,
+ /* 340 */ 114, 114, 114, 58, 59, 60, 61, 62, 63, 64,
+ /* 350 */ 65, 66, 67, 68, 69, 70, 71, 83, 84, 85,
+ /* 360 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ /* 370 */ 96, 97, 98, 99, 100, 114, 114, 103, 104, 114,
+ /* 380 */ 114, 114, 114, 114, 114, 111, 16, 114, 114, 114,
+ /* 390 */ 114, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ /* 400 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 114,
+ /* 410 */ 114, 103, 104, 114, 114, 114, 114, 114, 110, 79,
+ /* 420 */ 114, 114, 114, 83, 84, 85, 86, 87, 88, 89,
+ /* 430 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+ /* 440 */ 100, 79, 72, 103, 104, 83, 84, 85, 86, 87,
+ /* 450 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ /* 460 */ 98, 99, 100, 114, 114, 103, 104, 114, 8, 114,
+ /* 470 */ 10, 79, 12, 13, 114, 83, 84, 85, 86, 87,
+ /* 480 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ /* 490 */ 98, 99, 100, 0, 114, 103, 104, 8, 114, 10,
+ /* 500 */ 114, 12, 13, 114, 114, 114, 114, 114, 114, 16,
+ /* 510 */ 114, 114, 114, 53, 54, 114, 114, 114, 58, 59,
+ /* 520 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ /* 530 */ 70, 71, 114, 114, 114, 114, 114, 114, 114, 114,
+ /* 540 */ 114, 114, 53, 54, 114, 114, 114, 58, 59, 60,
+ /* 550 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ /* 560 */ 71, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ /* 570 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 114,
+ /* 580 */ 114, 103, 104, 83, 84, 85, 86, 87, 88, 89,
+ /* 590 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+ /* 600 */ 100, 114, 114, 103, 104, 83, 84, 85, 86, 87,
+ /* 610 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ /* 620 */ 98, 99, 100, 114, 114, 103, 104, 83, 84, 85,
+ /* 630 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ /* 640 */ 96, 97, 98, 99, 100, 114, 114, 103, 104, 83,
+ /* 650 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 660 */ 94, 95, 96, 97, 98, 99, 100, 114, 114, 103,
+ /* 670 */ 104, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ /* 680 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 114,
+ /* 690 */ 114, 103, 104, 83, 84, 85, 86, 87, 88, 89,
+ /* 700 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+ /* 710 */ 100, 114, 114, 103, 104, 83, 84, 85, 86, 87,
+ /* 720 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ /* 730 */ 98, 99, 100, 114, 114, 103, 104, 83, 84, 85,
+ /* 740 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ /* 750 */ 96, 97, 98, 99, 100, 114, 114, 103, 104, 83,
+ /* 760 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 770 */ 94, 95, 96, 97, 98, 99, 100, 114, 114, 103,
+ /* 780 */ 104, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ /* 790 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 114,
+ /* 800 */ 114, 103, 104, 83, 84, 85, 86, 87, 88, 89,
+ /* 810 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+ /* 820 */ 100, 114, 114, 103, 104, 83, 84, 85, 86, 87,
+ /* 830 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ /* 840 */ 98, 99, 100, 114, 114, 103, 104, 83, 84, 85,
+ /* 850 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ /* 860 */ 96, 97, 98, 99, 100, 114, 114, 103, 104, 83,
+ /* 870 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 880 */ 94, 95, 96, 97, 98, 99, 100, 114, 114, 103,
+ /* 890 */ 104, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ /* 900 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 114,
+ /* 910 */ 114, 103, 104, 83, 84, 85, 86, 87, 88, 89,
+ /* 920 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+ /* 930 */ 100, 114, 114, 103, 104, 83, 84, 85, 86, 87,
+ /* 940 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ /* 950 */ 98, 99, 100, 114, 114, 103, 104, 83, 84, 85,
+ /* 960 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ /* 970 */ 96, 97, 98, 99, 100, 114, 83, 103, 104, 86,
+ /* 980 */ 114, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+ /* 990 */ 97, 98, 99, 100, 114, 83, 103, 104, 86, 114,
+ /* 1000 */ 114, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ /* 1010 */ 98, 99, 100, 114, 83, 103, 104, 86, 114, 114,
+ /* 1020 */ 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
+ /* 1030 */ 99, 100, 114, 83, 103, 104, 86, 114, 114, 114,
+ /* 1040 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+ /* 1050 */ 100, 114, 83, 103, 104, 86, 114, 114, 114, 114,
+ /* 1060 */ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+ /* 1070 */ 114, 114, 103, 104, 114, 114, 114, 114, 17, 18,
+ /* 1080 */ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ /* 1090 */ 83, 114, 114, 86, 114, 114, 114, 114, 114, 92,
+ /* 1100 */ 93, 94, 95, 96, 97, 98, 99, 100, 114, 114,
+ /* 1110 */ 103, 104, 83, 114, 114, 86, 114, 114, 114, 114,
+ /* 1120 */ 59, 60, 93, 94, 95, 96, 97, 98, 99, 100,
+ /* 1130 */ 114, 83, 103, 104, 86, 114, 114, 114, 114, 114,
+ /* 1140 */ 114, 93, 94, 95, 96, 97, 98, 99, 100, 114,
+ /* 1150 */ 114, 103, 104, 114, 114, 3, 4, 5, 6, 7,
+ /* 1160 */ 8, 9, 10, 11, 12, 13, 0, 15, 114, 3,
+ /* 1170 */ 4, 5, 6, 7, 8, 114, 10, 11, 12, 13,
+ /* 1180 */ 114, 15, 114, 83, 114, 114, 86, 114, 114, 114,
+ /* 1190 */ 114, 114, 114, 114, 94, 95, 96, 97, 98, 99,
+ /* 1200 */ 100, 114, 114, 103, 104, 83, 114, 114, 86, 114,
+ /* 1210 */ 114, 114, 114, 114, 114, 114, 94, 95, 96, 97,
+ /* 1220 */ 98, 99, 100, 114, 114, 103, 104, 83, 114, 114,
+ /* 1230 */ 86, 114, 114, 114, 114, 114, 114, 114, 94, 95,
+ /* 1240 */ 96, 97, 98, 99, 100, 114, 83, 103, 104, 86,
+ /* 1250 */ 114, 114, 114, 114, 114, 114, 114, 94, 95, 96,
+ /* 1260 */ 97, 98, 99, 100, 114, 83, 103, 104, 86, 114,
+ /* 1270 */ 114, 114, 114, 114, 114, 114, 94, 95, 96, 97,
+ /* 1280 */ 98, 99, 100, 114, 83, 103, 104, 86, 114, 114,
+ /* 1290 */ 114, 114, 114, 114, 114, 94, 95, 96, 97, 98,
+ /* 1300 */ 99, 100, 114, 83, 103, 104, 86, 114, 114, 114,
+ /* 1310 */ 114, 114, 114, 114, 94, 95, 96, 97, 98, 99,
+ /* 1320 */ 100, 114, 83, 103, 104, 86, 114, 114, 114, 114,
+ /* 1330 */ 114, 114, 114, 94, 95, 96, 97, 98, 99, 100,
+ /* 1340 */ 114, 83, 103, 104, 86, 114, 114, 114, 114, 114,
+ /* 1350 */ 114, 114, 94, 95, 96, 97, 98, 99, 100, 114,
+ /* 1360 */ 83, 103, 104, 86, 114, 114, 114, 114, 114, 114,
+ /* 1370 */ 114, 94, 95, 96, 97, 98, 99, 100, 114, 83,
+ /* 1380 */ 103, 104, 86, 114, 114, 114, 114, 114, 114, 114,
+ /* 1390 */ 94, 95, 96, 97, 98, 99, 100, 114, 83, 103,
+ /* 1400 */ 104, 86, 114, 114, 114, 114, 114, 114, 114, 94,
+ /* 1410 */ 95, 96, 97, 98, 99, 100, 114, 83, 103, 104,
+ /* 1420 */ 86, 114, 114, 114, 114, 114, 114, 114, 94, 95,
+ /* 1430 */ 96, 97, 98, 99, 100, 114, 83, 103, 104, 86,
+ /* 1440 */ 114, 114, 114, 114, 114, 114, 114, 94, 95, 96,
+ /* 1450 */ 97, 98, 99, 100, 114, 83, 103, 104, 86, 114,
+ /* 1460 */ 114, 114, 114, 114, 114, 114, 114, 95, 96, 97,
+ /* 1470 */ 98, 99, 100, 114, 83, 103, 104, 86, 114, 114,
+ /* 1480 */ 114, 114, 114, 114, 114, 114, 95, 96, 97, 98,
+ /* 1490 */ 99, 100, 114, 83, 103, 104, 86, 114, 114, 114,
+ /* 1500 */ 82, 83, 114, 114, 86, 95, 96, 97, 98, 99,
+ /* 1510 */ 100, 114, 114, 103, 104, 97, 98, 99, 100, 114,
+ /* 1520 */ 83, 103, 104, 86, 114, 114, 114, 114, 114, 114,
+ /* 1530 */ 114, 114, 114, 96, 97, 98, 99, 100, 114, 83,
+ /* 1540 */ 103, 104, 86, 114, 114, 114, 114, 114, 114, 114,
+ /* 1550 */ 114, 114, 96, 97, 98, 99, 100, 114, 83, 103,
+ /* 1560 */ 104, 86, 114, 114, 114, 114, 114, 114, 114, 114,
+ /* 1570 */ 114, 114, 97, 98, 99, 100, 114, 83, 103, 104,
+ /* 1580 */ 86, 114, 114, 114, 114, 83, 114, 114, 86, 114,
+ /* 1590 */ 114, 97, 98, 99, 100, 114, 114, 103, 104, 97,
+ /* 1600 */ 98, 99, 100, 114, 83, 103, 104, 86, 114, 114,
+ /* 1610 */ 114, 114, 114, 114, 114, 114, 114, 114, 97, 98,
+ /* 1620 */ 99, 100, 114, 83, 103, 104, 86, 114, 114, 114,
+ /* 1630 */ 114, 114, 114, 114, 114, 114, 114, 97, 98, 99,
+ /* 1640 */ 100, 114, 83, 103, 104, 86, 114, 114, 114, 114,
+ /* 1650 */ 114, 114, 114, 114, 114, 114, 97, 98, 99, 100,
+ /* 1660 */ 114, 83, 103, 104, 86, 114, 114, 114, 114, 83,
+ /* 1670 */ 114, 114, 86, 114, 114, 97, 98, 99, 100, 114,
+ /* 1680 */ 114, 103, 104, 97, 98, 99, 100, 114, 83, 103,
+ /* 1690 */ 104, 86, 114, 114, 114, 114, 114, 114, 114, 114,
+ /* 1700 */ 114, 114, 97, 98, 99, 100, 114, 83, 103, 104,
+ /* 1710 */ 86, 114, 114, 114, 114, 114, 114, 114, 114, 114,
+ /* 1720 */ 114, 97, 98, 99, 100, 114, 83, 103, 104, 86,
+ /* 1730 */ 114, 114, 114, 114, 114, 114, 114, 114, 114, 114,
+ /* 1740 */ 97, 98, 99, 100, 114, 83, 103, 104, 86, 114,
+ /* 1750 */ 114, 114, 114, 83, 114, 114, 86, 114, 114, 97,
+ /* 1760 */ 98, 99, 100, 114, 114, 103, 104, 97, 98, 99,
+ /* 1770 */ 100, 114, 83, 103, 104, 86, 114, 114, 114, 114,
+ /* 1780 */ 114, 114, 114, 114, 114, 114, 97, 98, 99, 100,
+ /* 1790 */ 114, 114, 103, 104,
};
-#define YY_SHIFT_USE_DFLT (-47)
-#define YY_SHIFT_COUNT (140)
-#define YY_SHIFT_MIN (-46)
-#define YY_SHIFT_MAX (1085)
+#define YY_SHIFT_USE_DFLT (1794)
+#define YY_SHIFT_COUNT (144)
+#define YY_SHIFT_MIN (-60)
+#define YY_SHIFT_MAX (1166)
static const short yy_shift_ofst[] = {
- /* 0 */ -1, 91, 285, 431, 459, 285, 459, 459, 459, 459,
- /* 10 */ 220, 155, 459, 459, 459, 459, 459, 459, 459, 459,
- /* 20 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
- /* 30 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
- /* 40 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
- /* 50 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
- /* 60 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
- /* 70 */ 1085, 264, 35, 193, 65, 264, 191, 404, 35, 35,
- /* 80 */ 35, 35, 35, 195, -47, 286, 286, 286, 1018, -46,
- /* 90 */ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- /* 100 */ -46, 79, -46, 79, -46, 79, -46, 208, 254, 253,
- /* 110 */ 102, 85, 132, 87, 87, 39, 87, 97, 2, 110,
- /* 120 */ 87, 97, 102, 136, 40, 34, 197, 218, 168, 111,
- /* 130 */ 107, 200, 177, 109, 115, 107, 109, 115, 107, 21,
- /* 140 */ 34,
+ /* 0 */ -1, 460, 96, 131, 285, 131, 489, 489, 489, 489,
+ /* 10 */ 220, 254, 489, 489, 489, 489, 489, 489, 489, 489,
+ /* 20 */ 489, 489, 489, 489, 489, 489, 489, 489, 489, 489,
+ /* 30 */ 489, 489, 489, 489, 489, 489, 489, 489, 489, 489,
+ /* 40 */ 489, 489, 489, 489, 489, 489, 489, 489, 489, 489,
+ /* 50 */ 489, 489, 489, 489, 96, 489, 489, 489, 489, 489,
+ /* 60 */ 489, 489, 489, 489, 489, 489, 489, 489, 489, 489,
+ /* 70 */ 489, 263, -7, -60, 36, 223, -7, -60, 1152, 1166,
+ /* 80 */ 36, 36, 36, 36, 36, 36, 36, 256, 132, 132,
+ /* 90 */ 132, 1061, 4, 4, 4, 4, 4, 4, 4, 4,
+ /* 100 */ 4, 4, 4, 4, 17, 4, 17, 4, 17, 4,
+ /* 110 */ 45, 94, 493, 179, 247, 126, 134, 134, 290, 134,
+ /* 120 */ 190, 370, 209, 134, 190, 179, 298, 221, 75, 104,
+ /* 130 */ 232, 236, 238, 250, 271, 297, 280, 278, 303, 271,
+ /* 140 */ 278, 303, 271, 306, 104,
};
-#define YY_REDUCE_USE_DFLT (-71)
-#define YY_REDUCE_COUNT (84)
-#define YY_REDUCE_MIN (-70)
-#define YY_REDUCE_MAX (1535)
+#define YY_REDUCE_USE_DFLT (-106)
+#define YY_REDUCE_COUNT (87)
+#define YY_REDUCE_MIN (-105)
+#define YY_REDUCE_MAX (1689)
static const short yy_reduce_ofst[] = {
- /* 0 */ -63, -7, 153, 88, 25, 365, 337, 300, 278, 215,
- /* 10 */ 846, 824, 802, 780, 758, 736, 714, 692, 670, 648,
- /* 20 */ 626, 604, 582, 560, 538, 516, 492, 470, 448, 865,
- /* 30 */ 906, 884, 928, 963, 987, 1025, 1006, 1291, 1272, 1253,
- /* 40 */ 1234, 1215, 1196, 1177, 1158, 1139, 1120, 1101, 1082, 1063,
- /* 50 */ 1044, 1348, 1329, 1310, 1376, 1367, 1535, 1527, 1508, 1500,
- /* 60 */ 1481, 1471, 1462, 1452, 1443, 1433, 1424, 1414, 1405, 1395,
- /* 70 */ -65, 14, -70, 154, 128, 77, 235, 235, 234, 213,
- /* 80 */ 194, 192, 189, 165, 159,
+ /* 0 */ -62, -8, 34, 123, 155, 274, 308, 340, 362, 392,
+ /* 10 */ 478, 500, 522, 544, 566, 588, 610, 632, 654, 676,
+ /* 20 */ 698, 720, 742, 764, 786, 808, 830, 852, 874, 893,
+ /* 30 */ 912, 931, 950, 969, 1007, 1029, 1048, 1100, 1122, 1144,
+ /* 40 */ 1163, 1182, 1201, 1220, 1239, 1258, 1277, 1296, 1315, 1334,
+ /* 50 */ 1353, 1372, 1391, 1410, 1418, 1437, 1456, 1475, 1494, 1502,
+ /* 60 */ 1521, 1540, 1559, 1578, 1586, 1605, 1624, 1643, 1662, 1670,
+ /* 70 */ 1689, -64, 33, -105, 15, 50, 23, 39, -69, -69,
+ /* 80 */ -32, 20, 71, 122, 147, 175, 183, -87,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 357, 357, 345, 357, 335, 357, 342, 357, 357, 357,
- /* 10 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
- /* 20 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
- /* 30 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
- /* 40 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
- /* 50 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
- /* 60 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
- /* 70 */ 357, 351, 357, 357, 313, 357, 357, 357, 357, 357,
- /* 80 */ 357, 357, 357, 357, 335, 268, 270, 269, 309, 285,
- /* 90 */ 284, 283, 282, 281, 280, 279, 278, 277, 276, 275,
- /* 100 */ 271, 290, 274, 292, 273, 291, 272, 357, 357, 357,
- /* 110 */ 258, 357, 357, 286, 289, 357, 288, 266, 357, 309,
- /* 120 */ 287, 267, 257, 255, 357, 319, 357, 357, 357, 354,
- /* 130 */ 261, 357, 357, 264, 262, 259, 265, 263, 260, 357,
- /* 140 */ 357, 352, 356, 355, 353, 346, 350, 349, 348, 347,
- /* 150 */ 235, 233, 239, 254, 253, 252, 251, 250, 249, 248,
- /* 160 */ 247, 246, 245, 244, 343, 344, 341, 340, 331, 329,
- /* 170 */ 328, 333, 327, 338, 337, 336, 334, 332, 330, 326,
- /* 180 */ 293, 325, 324, 323, 322, 321, 320, 319, 296, 318,
- /* 190 */ 317, 315, 295, 339, 240, 316, 314, 312, 311, 310,
- /* 200 */ 308, 307, 306, 305, 304, 303, 302, 301, 300, 299,
- /* 210 */ 298, 297, 294, 256, 243, 242, 241, 238, 237, 236,
- /* 220 */ 232, 229, 234, 231, 230,
+ /* 0 */ 504, 437, 504, 444, 504, 446, 441, 504, 504, 504,
+ /* 10 */ 504, 504, 504, 504, 504, 504, 504, 504, 504, 504,
+ /* 20 */ 504, 504, 504, 504, 504, 504, 504, 504, 504, 504,
+ /* 30 */ 504, 504, 504, 504, 504, 504, 504, 504, 504, 504,
+ /* 40 */ 504, 504, 504, 504, 504, 504, 504, 504, 504, 504,
+ /* 50 */ 504, 504, 504, 504, 504, 504, 504, 504, 504, 504,
+ /* 60 */ 504, 504, 504, 504, 504, 504, 504, 504, 504, 504,
+ /* 70 */ 504, 504, 501, 437, 504, 477, 504, 504, 504, 504,
+ /* 80 */ 504, 504, 504, 504, 504, 504, 504, 504, 469, 399,
+ /* 90 */ 398, 475, 413, 412, 411, 410, 409, 408, 407, 406,
+ /* 100 */ 405, 404, 403, 470, 472, 402, 418, 401, 417, 400,
+ /* 110 */ 504, 504, 504, 392, 504, 504, 471, 416, 504, 415,
+ /* 120 */ 468, 504, 475, 414, 397, 464, 463, 504, 486, 482,
+ /* 130 */ 504, 504, 504, 503, 394, 504, 504, 467, 466, 465,
+ /* 140 */ 396, 395, 393, 504, 504,
};
+/********** End of lemon-generated parsing tables *****************************/
-/* The next table maps tokens into fallback tokens. If a construct
-** like the following:
+/* The next table maps tokens (terminal symbols) into fallback tokens.
+** If a construct like the following:
**
** %fallback ID X Y Z.
**
@@ -547,6 +615,10 @@ static const YYACTIONTYPE yy_default[] = {
** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
** but it does not parse, the type of the token is changed to ID and
** the parse is retried before an error is thrown.
+**
+** This feature can be used, for example, to cause some keywords in a language
+** to revert to identifiers if they keyword does not apply in the context where
+** it appears.
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
@@ -564,9 +636,13 @@ static const YYCODETYPE yyFallback[] = {
** + The semantic value stored at this level of the stack. This is
** the information used by the action routines in the grammar.
** It is sometimes called the "minor" token.
+**
+** After the "shift" half of a SHIFTREDUCE action, the stateno field
+** actually contains the reduce action for the second half of the
+** SHIFTREDUCE.
*/
struct yyStackEntry {
- YYACTIONTYPE stateno; /* The state-number */
+ YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
YYCODETYPE major; /* The major token value. This is the code
** number for the token at this stack level */
YYMINORTYPE minor; /* The user-supplied minor token value. This
@@ -577,15 +653,18 @@ typedef struct yyStackEntry yyStackEntry;
/* The state of the parser is completely contained in an instance of
** the following structure */
struct yyParser {
- int yyidx; /* Index of top element in stack */
+ yyStackEntry *yytos; /* Pointer to top element of the stack */
#ifdef YYTRACKMAXSTACKDEPTH
- int yyidxMax; /* Maximum value of yyidx */
+ int yyhwm; /* High-water mark of the stack */
#endif
+#ifndef YYNOERRORRECOVERY
int yyerrcnt; /* Shifts left before out of the error */
+#endif
grn_expr_parserARG_SDECL /* A place to hold %extra_argument */
#if YYSTACKDEPTH<=0
int yystksz; /* Current side of the stack */
yyStackEntry *yystack; /* The parser's stack */
+ yyStackEntry yystk0; /* First stack entry */
#else
yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
#endif
@@ -629,34 +708,34 @@ void grn_expr_parserTrace(FILE *TraceFILE, char *zTracePrompt){
** are required. The following table supplies these names */
static const char *const yyTokenName[] = {
"$", "START_OUTPUT_COLUMNS", "START_ADJUSTER", "LOGICAL_AND",
- "LOGICAL_AND_NOT", "LOGICAL_OR", "QSTRING", "PARENL",
- "PARENR", "RELATIVE_OP", "IDENTIFIER", "BRACEL",
- "BRACER", "EVAL", "COMMA", "ASSIGN",
- "STAR_ASSIGN", "SLASH_ASSIGN", "MOD_ASSIGN", "PLUS_ASSIGN",
- "MINUS_ASSIGN", "SHIFTL_ASSIGN", "SHIFTR_ASSIGN", "SHIFTRR_ASSIGN",
- "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "QUESTION",
- "COLON", "BITWISE_OR", "BITWISE_XOR", "BITWISE_AND",
- "EQUAL", "NOT_EQUAL", "LESS", "GREATER",
- "LESS_EQUAL", "GREATER_EQUAL", "IN", "MATCH",
- "NEAR", "NEAR2", "SIMILAR", "TERM_EXTRACT",
- "LCP", "PREFIX", "SUFFIX", "REGEXP",
- "SHIFTL", "SHIFTR", "SHIFTRR", "PLUS",
- "MINUS", "STAR", "SLASH", "MOD",
- "DELETE", "INCR", "DECR", "NOT",
- "BITWISE_NOT", "ADJUST", "EXACT", "PARTIAL",
- "UNSPLIT", "DECIMAL", "HEX_INTEGER", "STRING",
- "BOOLEAN", "NULL", "BRACKETL", "BRACKETR",
- "DOT", "NONEXISTENT_COLUMN", "error", "suppress_unused_variable_warning",
- "input", "query", "expression", "output_columns",
- "adjuster", "query_element", "primary_expression", "assignment_expression",
- "conditional_expression", "lefthand_side_expression", "logical_or_expression", "logical_and_expression",
- "bitwise_or_expression", "bitwise_xor_expression", "bitwise_and_expression", "equality_expression",
- "relational_expression", "shift_expression", "additive_expression", "multiplicative_expression",
- "unary_expression", "postfix_expression", "call_expression", "member_expression",
- "arguments", "member_expression_part", "object_literal", "array_literal",
- "elision", "element_list", "property_name_and_value_list", "property_name_and_value",
- "property_name", "argument_list", "output_column", "adjust_expression",
- "adjust_match_expression",
+ "LOGICAL_AND_NOT", "LOGICAL_OR", "NEGATIVE", "QSTRING",
+ "PARENL", "PARENR", "ADJUST", "RELATIVE_OP",
+ "IDENTIFIER", "BRACEL", "BRACER", "EVAL",
+ "COMMA", "ASSIGN", "STAR_ASSIGN", "SLASH_ASSIGN",
+ "MOD_ASSIGN", "PLUS_ASSIGN", "MINUS_ASSIGN", "SHIFTL_ASSIGN",
+ "SHIFTR_ASSIGN", "SHIFTRR_ASSIGN", "AND_ASSIGN", "XOR_ASSIGN",
+ "OR_ASSIGN", "QUESTION", "COLON", "BITWISE_OR",
+ "BITWISE_XOR", "BITWISE_AND", "EQUAL", "NOT_EQUAL",
+ "LESS", "GREATER", "LESS_EQUAL", "GREATER_EQUAL",
+ "IN", "MATCH", "NEAR", "NEAR2",
+ "SIMILAR", "TERM_EXTRACT", "LCP", "PREFIX",
+ "SUFFIX", "REGEXP", "SHIFTL", "SHIFTR",
+ "SHIFTRR", "PLUS", "MINUS", "STAR",
+ "SLASH", "MOD", "DELETE", "INCR",
+ "DECR", "NOT", "BITWISE_NOT", "EXACT",
+ "PARTIAL", "UNSPLIT", "DECIMAL", "HEX_INTEGER",
+ "STRING", "BOOLEAN", "NULL", "BRACKETL",
+ "BRACKETR", "DOT", "NONEXISTENT_COLUMN", "error",
+ "suppress_unused_variable_warning", "input", "query", "expression",
+ "output_columns", "adjuster", "query_element", "primary_expression",
+ "assignment_expression", "conditional_expression", "lefthand_side_expression", "logical_or_expression",
+ "logical_and_expression", "bitwise_or_expression", "bitwise_xor_expression", "bitwise_and_expression",
+ "equality_expression", "relational_expression", "shift_expression", "additive_expression",
+ "multiplicative_expression", "unary_expression", "postfix_expression", "call_expression",
+ "member_expression", "arguments", "member_expression_part", "object_literal",
+ "array_literal", "elision", "element_list", "property_name_and_value_list",
+ "property_name_and_value", "property_name", "argument_list", "output_column",
+ "adjust_expression", "adjust_match_expression",
};
#endif /* NDEBUG */
@@ -664,165 +743,213 @@ static const char *const yyTokenName[] = {
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const yyRuleName[] = {
- /* 0 */ "input ::= query",
- /* 1 */ "input ::= expression",
- /* 2 */ "input ::= START_OUTPUT_COLUMNS output_columns",
- /* 3 */ "input ::= START_ADJUSTER adjuster",
- /* 4 */ "query ::= query_element",
- /* 5 */ "query ::= query query_element",
- /* 6 */ "query ::= query LOGICAL_AND query_element",
- /* 7 */ "query ::= query LOGICAL_AND_NOT query_element",
- /* 8 */ "query ::= query LOGICAL_OR query_element",
- /* 9 */ "query_element ::= QSTRING",
- /* 10 */ "query_element ::= PARENL query PARENR",
- /* 11 */ "query_element ::= RELATIVE_OP query_element",
- /* 12 */ "query_element ::= IDENTIFIER RELATIVE_OP query_element",
- /* 13 */ "query_element ::= BRACEL expression BRACER",
- /* 14 */ "query_element ::= EVAL primary_expression",
- /* 15 */ "expression ::= assignment_expression",
- /* 16 */ "expression ::= expression COMMA assignment_expression",
- /* 17 */ "assignment_expression ::= conditional_expression",
- /* 18 */ "assignment_expression ::= lefthand_side_expression ASSIGN assignment_expression",
- /* 19 */ "assignment_expression ::= lefthand_side_expression STAR_ASSIGN assignment_expression",
- /* 20 */ "assignment_expression ::= lefthand_side_expression SLASH_ASSIGN assignment_expression",
- /* 21 */ "assignment_expression ::= lefthand_side_expression MOD_ASSIGN assignment_expression",
- /* 22 */ "assignment_expression ::= lefthand_side_expression PLUS_ASSIGN assignment_expression",
- /* 23 */ "assignment_expression ::= lefthand_side_expression MINUS_ASSIGN assignment_expression",
- /* 24 */ "assignment_expression ::= lefthand_side_expression SHIFTL_ASSIGN assignment_expression",
- /* 25 */ "assignment_expression ::= lefthand_side_expression SHIFTR_ASSIGN assignment_expression",
- /* 26 */ "assignment_expression ::= lefthand_side_expression SHIFTRR_ASSIGN assignment_expression",
- /* 27 */ "assignment_expression ::= lefthand_side_expression AND_ASSIGN assignment_expression",
- /* 28 */ "assignment_expression ::= lefthand_side_expression XOR_ASSIGN assignment_expression",
- /* 29 */ "assignment_expression ::= lefthand_side_expression OR_ASSIGN assignment_expression",
- /* 30 */ "conditional_expression ::= logical_or_expression",
- /* 31 */ "conditional_expression ::= logical_or_expression QUESTION assignment_expression COLON assignment_expression",
- /* 32 */ "logical_or_expression ::= logical_and_expression",
- /* 33 */ "logical_or_expression ::= logical_or_expression LOGICAL_OR logical_and_expression",
- /* 34 */ "logical_and_expression ::= bitwise_or_expression",
- /* 35 */ "logical_and_expression ::= logical_and_expression LOGICAL_AND bitwise_or_expression",
- /* 36 */ "logical_and_expression ::= logical_and_expression LOGICAL_AND_NOT bitwise_or_expression",
- /* 37 */ "bitwise_or_expression ::= bitwise_xor_expression",
- /* 38 */ "bitwise_or_expression ::= bitwise_or_expression BITWISE_OR bitwise_xor_expression",
- /* 39 */ "bitwise_xor_expression ::= bitwise_and_expression",
- /* 40 */ "bitwise_xor_expression ::= bitwise_xor_expression BITWISE_XOR bitwise_and_expression",
- /* 41 */ "bitwise_and_expression ::= equality_expression",
- /* 42 */ "bitwise_and_expression ::= bitwise_and_expression BITWISE_AND equality_expression",
- /* 43 */ "equality_expression ::= relational_expression",
- /* 44 */ "equality_expression ::= equality_expression EQUAL relational_expression",
- /* 45 */ "equality_expression ::= equality_expression NOT_EQUAL relational_expression",
- /* 46 */ "relational_expression ::= shift_expression",
- /* 47 */ "relational_expression ::= relational_expression LESS shift_expression",
- /* 48 */ "relational_expression ::= relational_expression GREATER shift_expression",
- /* 49 */ "relational_expression ::= relational_expression LESS_EQUAL shift_expression",
- /* 50 */ "relational_expression ::= relational_expression GREATER_EQUAL shift_expression",
- /* 51 */ "relational_expression ::= relational_expression IN shift_expression",
- /* 52 */ "relational_expression ::= relational_expression MATCH shift_expression",
- /* 53 */ "relational_expression ::= relational_expression NEAR shift_expression",
- /* 54 */ "relational_expression ::= relational_expression NEAR2 shift_expression",
- /* 55 */ "relational_expression ::= relational_expression SIMILAR shift_expression",
- /* 56 */ "relational_expression ::= relational_expression TERM_EXTRACT shift_expression",
- /* 57 */ "relational_expression ::= relational_expression LCP shift_expression",
- /* 58 */ "relational_expression ::= relational_expression PREFIX shift_expression",
- /* 59 */ "relational_expression ::= relational_expression SUFFIX shift_expression",
- /* 60 */ "relational_expression ::= relational_expression REGEXP shift_expression",
- /* 61 */ "shift_expression ::= additive_expression",
- /* 62 */ "shift_expression ::= shift_expression SHIFTL additive_expression",
- /* 63 */ "shift_expression ::= shift_expression SHIFTR additive_expression",
- /* 64 */ "shift_expression ::= shift_expression SHIFTRR additive_expression",
- /* 65 */ "additive_expression ::= multiplicative_expression",
- /* 66 */ "additive_expression ::= additive_expression PLUS multiplicative_expression",
- /* 67 */ "additive_expression ::= additive_expression MINUS multiplicative_expression",
- /* 68 */ "multiplicative_expression ::= unary_expression",
- /* 69 */ "multiplicative_expression ::= multiplicative_expression STAR unary_expression",
- /* 70 */ "multiplicative_expression ::= multiplicative_expression SLASH unary_expression",
- /* 71 */ "multiplicative_expression ::= multiplicative_expression MOD unary_expression",
- /* 72 */ "unary_expression ::= postfix_expression",
- /* 73 */ "unary_expression ::= DELETE unary_expression",
- /* 74 */ "unary_expression ::= INCR unary_expression",
- /* 75 */ "unary_expression ::= DECR unary_expression",
- /* 76 */ "unary_expression ::= PLUS unary_expression",
- /* 77 */ "unary_expression ::= MINUS unary_expression",
- /* 78 */ "unary_expression ::= NOT unary_expression",
- /* 79 */ "unary_expression ::= BITWISE_NOT unary_expression",
- /* 80 */ "unary_expression ::= ADJUST unary_expression",
- /* 81 */ "unary_expression ::= EXACT unary_expression",
- /* 82 */ "unary_expression ::= PARTIAL unary_expression",
- /* 83 */ "unary_expression ::= UNSPLIT unary_expression",
- /* 84 */ "postfix_expression ::= lefthand_side_expression",
- /* 85 */ "postfix_expression ::= lefthand_side_expression INCR",
- /* 86 */ "postfix_expression ::= lefthand_side_expression DECR",
- /* 87 */ "lefthand_side_expression ::= call_expression",
- /* 88 */ "lefthand_side_expression ::= member_expression",
- /* 89 */ "call_expression ::= member_expression arguments",
- /* 90 */ "member_expression ::= primary_expression",
- /* 91 */ "member_expression ::= member_expression member_expression_part",
- /* 92 */ "primary_expression ::= object_literal",
- /* 93 */ "primary_expression ::= PARENL expression PARENR",
- /* 94 */ "primary_expression ::= IDENTIFIER",
- /* 95 */ "primary_expression ::= array_literal",
- /* 96 */ "primary_expression ::= DECIMAL",
- /* 97 */ "primary_expression ::= HEX_INTEGER",
- /* 98 */ "primary_expression ::= STRING",
- /* 99 */ "primary_expression ::= BOOLEAN",
- /* 100 */ "primary_expression ::= NULL",
- /* 101 */ "array_literal ::= BRACKETL elision BRACKETR",
- /* 102 */ "array_literal ::= BRACKETL element_list elision BRACKETR",
- /* 103 */ "array_literal ::= BRACKETL element_list BRACKETR",
- /* 104 */ "elision ::= COMMA",
- /* 105 */ "elision ::= elision COMMA",
- /* 106 */ "element_list ::= assignment_expression",
- /* 107 */ "element_list ::= elision assignment_expression",
- /* 108 */ "element_list ::= element_list elision assignment_expression",
- /* 109 */ "object_literal ::= BRACEL property_name_and_value_list BRACER",
- /* 110 */ "property_name_and_value_list ::=",
- /* 111 */ "property_name_and_value_list ::= property_name_and_value_list COMMA property_name_and_value",
- /* 112 */ "property_name_and_value ::= property_name COLON assignment_expression",
- /* 113 */ "property_name ::= IDENTIFIER|STRING|DECIMAL",
- /* 114 */ "member_expression_part ::= BRACKETL expression BRACKETR",
- /* 115 */ "member_expression_part ::= DOT IDENTIFIER",
- /* 116 */ "arguments ::= PARENL argument_list PARENR",
- /* 117 */ "argument_list ::=",
- /* 118 */ "argument_list ::= assignment_expression",
- /* 119 */ "argument_list ::= argument_list COMMA assignment_expression",
- /* 120 */ "output_columns ::=",
- /* 121 */ "output_columns ::= output_column",
- /* 122 */ "output_columns ::= output_columns COMMA output_column",
- /* 123 */ "output_column ::= STAR",
- /* 124 */ "output_column ::= NONEXISTENT_COLUMN",
- /* 125 */ "output_column ::= assignment_expression",
- /* 126 */ "adjuster ::=",
- /* 127 */ "adjuster ::= adjust_expression",
- /* 128 */ "adjuster ::= adjuster PLUS adjust_expression",
- /* 129 */ "adjust_expression ::= adjust_match_expression",
- /* 130 */ "adjust_expression ::= adjust_match_expression STAR DECIMAL",
- /* 131 */ "adjust_match_expression ::= IDENTIFIER MATCH STRING",
+ /* 0 */ "query ::= query query_element",
+ /* 1 */ "query ::= query LOGICAL_AND query_element",
+ /* 2 */ "query ::= query LOGICAL_AND_NOT query_element",
+ /* 3 */ "query ::= query LOGICAL_OR query_element",
+ /* 4 */ "query ::= query NEGATIVE query_element",
+ /* 5 */ "query_element ::= ADJUST query_element",
+ /* 6 */ "query_element ::= RELATIVE_OP query_element",
+ /* 7 */ "query_element ::= IDENTIFIER RELATIVE_OP query_element",
+ /* 8 */ "query_element ::= BRACEL expression BRACER",
+ /* 9 */ "query_element ::= EVAL primary_expression",
+ /* 10 */ "expression ::= expression COMMA assignment_expression",
+ /* 11 */ "assignment_expression ::= lefthand_side_expression ASSIGN assignment_expression",
+ /* 12 */ "assignment_expression ::= lefthand_side_expression STAR_ASSIGN assignment_expression",
+ /* 13 */ "assignment_expression ::= lefthand_side_expression SLASH_ASSIGN assignment_expression",
+ /* 14 */ "assignment_expression ::= lefthand_side_expression MOD_ASSIGN assignment_expression",
+ /* 15 */ "assignment_expression ::= lefthand_side_expression PLUS_ASSIGN assignment_expression",
+ /* 16 */ "assignment_expression ::= lefthand_side_expression MINUS_ASSIGN assignment_expression",
+ /* 17 */ "assignment_expression ::= lefthand_side_expression SHIFTL_ASSIGN assignment_expression",
+ /* 18 */ "assignment_expression ::= lefthand_side_expression SHIFTR_ASSIGN assignment_expression",
+ /* 19 */ "assignment_expression ::= lefthand_side_expression SHIFTRR_ASSIGN assignment_expression",
+ /* 20 */ "assignment_expression ::= lefthand_side_expression AND_ASSIGN assignment_expression",
+ /* 21 */ "assignment_expression ::= lefthand_side_expression XOR_ASSIGN assignment_expression",
+ /* 22 */ "assignment_expression ::= lefthand_side_expression OR_ASSIGN assignment_expression",
+ /* 23 */ "conditional_expression ::= logical_or_expression QUESTION assignment_expression COLON assignment_expression",
+ /* 24 */ "logical_or_expression ::= logical_or_expression LOGICAL_OR logical_and_expression",
+ /* 25 */ "logical_and_expression ::= logical_and_expression LOGICAL_AND bitwise_or_expression",
+ /* 26 */ "logical_and_expression ::= logical_and_expression LOGICAL_AND_NOT bitwise_or_expression",
+ /* 27 */ "bitwise_or_expression ::= bitwise_or_expression BITWISE_OR bitwise_xor_expression",
+ /* 28 */ "bitwise_xor_expression ::= bitwise_xor_expression BITWISE_XOR bitwise_and_expression",
+ /* 29 */ "bitwise_and_expression ::= bitwise_and_expression BITWISE_AND equality_expression",
+ /* 30 */ "equality_expression ::= equality_expression EQUAL relational_expression",
+ /* 31 */ "equality_expression ::= equality_expression NOT_EQUAL relational_expression",
+ /* 32 */ "relational_expression ::= relational_expression LESS shift_expression",
+ /* 33 */ "relational_expression ::= relational_expression GREATER shift_expression",
+ /* 34 */ "relational_expression ::= relational_expression LESS_EQUAL shift_expression",
+ /* 35 */ "relational_expression ::= relational_expression GREATER_EQUAL shift_expression",
+ /* 36 */ "relational_expression ::= relational_expression IN shift_expression",
+ /* 37 */ "relational_expression ::= relational_expression MATCH shift_expression",
+ /* 38 */ "relational_expression ::= relational_expression NEAR shift_expression",
+ /* 39 */ "relational_expression ::= relational_expression NEAR2 shift_expression",
+ /* 40 */ "relational_expression ::= relational_expression SIMILAR shift_expression",
+ /* 41 */ "relational_expression ::= relational_expression TERM_EXTRACT shift_expression",
+ /* 42 */ "relational_expression ::= relational_expression LCP shift_expression",
+ /* 43 */ "relational_expression ::= relational_expression PREFIX shift_expression",
+ /* 44 */ "relational_expression ::= relational_expression SUFFIX shift_expression",
+ /* 45 */ "relational_expression ::= relational_expression REGEXP shift_expression",
+ /* 46 */ "shift_expression ::= shift_expression SHIFTL additive_expression",
+ /* 47 */ "shift_expression ::= shift_expression SHIFTR additive_expression",
+ /* 48 */ "shift_expression ::= shift_expression SHIFTRR additive_expression",
+ /* 49 */ "additive_expression ::= additive_expression PLUS multiplicative_expression",
+ /* 50 */ "additive_expression ::= additive_expression MINUS multiplicative_expression",
+ /* 51 */ "multiplicative_expression ::= multiplicative_expression STAR unary_expression",
+ /* 52 */ "multiplicative_expression ::= multiplicative_expression SLASH unary_expression",
+ /* 53 */ "multiplicative_expression ::= multiplicative_expression MOD unary_expression",
+ /* 54 */ "unary_expression ::= DELETE unary_expression",
+ /* 55 */ "unary_expression ::= INCR unary_expression",
+ /* 56 */ "unary_expression ::= DECR unary_expression",
+ /* 57 */ "unary_expression ::= PLUS unary_expression",
+ /* 58 */ "unary_expression ::= MINUS unary_expression",
+ /* 59 */ "unary_expression ::= NOT unary_expression",
+ /* 60 */ "unary_expression ::= BITWISE_NOT unary_expression",
+ /* 61 */ "unary_expression ::= ADJUST unary_expression",
+ /* 62 */ "unary_expression ::= EXACT unary_expression",
+ /* 63 */ "unary_expression ::= PARTIAL unary_expression",
+ /* 64 */ "unary_expression ::= UNSPLIT unary_expression",
+ /* 65 */ "postfix_expression ::= lefthand_side_expression INCR",
+ /* 66 */ "postfix_expression ::= lefthand_side_expression DECR",
+ /* 67 */ "call_expression ::= member_expression arguments",
+ /* 68 */ "object_literal ::= BRACEL property_name_and_value_list BRACER",
+ /* 69 */ "property_name_and_value_list ::=",
+ /* 70 */ "property_name_and_value ::= property_name COLON assignment_expression",
+ /* 71 */ "member_expression_part ::= BRACKETL expression BRACKETR",
+ /* 72 */ "arguments ::= PARENL argument_list PARENR",
+ /* 73 */ "argument_list ::=",
+ /* 74 */ "argument_list ::= assignment_expression",
+ /* 75 */ "argument_list ::= argument_list COMMA assignment_expression",
+ /* 76 */ "output_columns ::=",
+ /* 77 */ "output_columns ::= output_column",
+ /* 78 */ "output_columns ::= output_columns COMMA",
+ /* 79 */ "output_columns ::= output_columns COMMA output_column",
+ /* 80 */ "output_column ::= STAR",
+ /* 81 */ "output_column ::= NONEXISTENT_COLUMN",
+ /* 82 */ "output_column ::= assignment_expression",
+ /* 83 */ "adjuster ::= adjuster PLUS adjust_expression",
+ /* 84 */ "adjust_expression ::= adjust_match_expression STAR DECIMAL",
+ /* 85 */ "adjust_match_expression ::= IDENTIFIER MATCH STRING",
+ /* 86 */ "input ::= query",
+ /* 87 */ "input ::= expression",
+ /* 88 */ "input ::= START_OUTPUT_COLUMNS output_columns",
+ /* 89 */ "input ::= START_ADJUSTER adjuster",
+ /* 90 */ "query ::= query_element",
+ /* 91 */ "query_element ::= QSTRING",
+ /* 92 */ "query_element ::= PARENL query PARENR",
+ /* 93 */ "expression ::= assignment_expression",
+ /* 94 */ "assignment_expression ::= conditional_expression",
+ /* 95 */ "conditional_expression ::= logical_or_expression",
+ /* 96 */ "logical_or_expression ::= logical_and_expression",
+ /* 97 */ "logical_and_expression ::= bitwise_or_expression",
+ /* 98 */ "bitwise_or_expression ::= bitwise_xor_expression",
+ /* 99 */ "bitwise_xor_expression ::= bitwise_and_expression",
+ /* 100 */ "bitwise_and_expression ::= equality_expression",
+ /* 101 */ "equality_expression ::= relational_expression",
+ /* 102 */ "relational_expression ::= shift_expression",
+ /* 103 */ "shift_expression ::= additive_expression",
+ /* 104 */ "additive_expression ::= multiplicative_expression",
+ /* 105 */ "multiplicative_expression ::= unary_expression",
+ /* 106 */ "unary_expression ::= postfix_expression",
+ /* 107 */ "postfix_expression ::= lefthand_side_expression",
+ /* 108 */ "lefthand_side_expression ::= call_expression",
+ /* 109 */ "lefthand_side_expression ::= member_expression",
+ /* 110 */ "member_expression ::= primary_expression",
+ /* 111 */ "member_expression ::= member_expression member_expression_part",
+ /* 112 */ "primary_expression ::= object_literal",
+ /* 113 */ "primary_expression ::= PARENL expression PARENR",
+ /* 114 */ "primary_expression ::= IDENTIFIER",
+ /* 115 */ "primary_expression ::= array_literal",
+ /* 116 */ "primary_expression ::= DECIMAL",
+ /* 117 */ "primary_expression ::= HEX_INTEGER",
+ /* 118 */ "primary_expression ::= STRING",
+ /* 119 */ "primary_expression ::= BOOLEAN",
+ /* 120 */ "primary_expression ::= NULL",
+ /* 121 */ "array_literal ::= BRACKETL elision BRACKETR",
+ /* 122 */ "array_literal ::= BRACKETL element_list elision BRACKETR",
+ /* 123 */ "array_literal ::= BRACKETL element_list BRACKETR",
+ /* 124 */ "elision ::= COMMA",
+ /* 125 */ "elision ::= elision COMMA",
+ /* 126 */ "element_list ::= assignment_expression",
+ /* 127 */ "element_list ::= elision assignment_expression",
+ /* 128 */ "element_list ::= element_list elision assignment_expression",
+ /* 129 */ "property_name_and_value_list ::= property_name_and_value",
+ /* 130 */ "property_name_and_value_list ::= property_name_and_value_list COMMA property_name_and_value",
+ /* 131 */ "property_name ::= STRING",
+ /* 132 */ "member_expression_part ::= DOT IDENTIFIER",
+ /* 133 */ "adjuster ::=",
+ /* 134 */ "adjuster ::= adjust_expression",
+ /* 135 */ "adjust_expression ::= adjust_match_expression",
};
#endif /* NDEBUG */
#if YYSTACKDEPTH<=0
/*
-** Try to increase the size of the parser stack.
+** Try to increase the size of the parser stack. Return the number
+** of errors. Return 0 on success.
*/
-static void yyGrowStack(yyParser *p){
+static int yyGrowStack(yyParser *p){
int newSize;
+ int idx;
yyStackEntry *pNew;
newSize = p->yystksz*2 + 100;
- pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
+ idx = p->yytos ? (int)(p->yytos - p->yystack) : 0;
+ if( p->yystack==&p->yystk0 ){
+ pNew = malloc(newSize*sizeof(pNew[0]));
+ if( pNew ) pNew[0] = p->yystk0;
+ }else{
+ pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
+ }
if( pNew ){
p->yystack = pNew;
- p->yystksz = newSize;
+ p->yytos = &p->yystack[idx];
#ifndef NDEBUG
if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
- yyTracePrompt, p->yystksz);
+ fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
+ yyTracePrompt, p->yystksz, newSize);
}
#endif
+ p->yystksz = newSize;
}
+ return pNew==0;
}
#endif
+/* Datatype of the argument to the memory allocated passed as the
+** second argument to grn_expr_parserAlloc() below. This can be changed by
+** putting an appropriate #define in the %include section of the input
+** grammar.
+*/
+#ifndef YYMALLOCARGTYPE
+# define YYMALLOCARGTYPE size_t
+#endif
+
+/* Initialize a new parser that has already been allocated.
+*/
+void grn_expr_parserInit(void *yypParser){
+ yyParser *pParser = (yyParser*)yypParser;
+#ifdef YYTRACKMAXSTACKDEPTH
+ pParser->yyhwm = 0;
+#endif
+#if YYSTACKDEPTH<=0
+ pParser->yytos = NULL;
+ pParser->yystack = NULL;
+ pParser->yystksz = 0;
+ if( yyGrowStack(pParser) ){
+ pParser->yystack = &pParser->yystk0;
+ pParser->yystksz = 1;
+ }
+#endif
+#ifndef YYNOERRORRECOVERY
+ pParser->yyerrcnt = -1;
+#endif
+ pParser->yytos = pParser->yystack;
+ pParser->yystack[0].stateno = 0;
+ pParser->yystack[0].major = 0;
+}
+
+#ifndef grn_expr_parser_ENGINEALWAYSONSTACK
/*
** This function allocates a new parser.
** The only argument is a pointer to a function which works like
@@ -835,27 +962,21 @@ static void yyGrowStack(yyParser *p){
** A pointer to a parser. This pointer is used in subsequent calls
** to grn_expr_parser and grn_expr_parserFree.
*/
-void *grn_expr_parserAlloc(void *(*mallocProc)(size_t)){
+void *grn_expr_parserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){
yyParser *pParser;
- pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
- if( pParser ){
- pParser->yyidx = -1;
-#ifdef YYTRACKMAXSTACKDEPTH
- pParser->yyidxMax = 0;
-#endif
-#if YYSTACKDEPTH<=0
- pParser->yystack = NULL;
- pParser->yystksz = 0;
- yyGrowStack(pParser);
-#endif
- }
+ pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
+ if( pParser ) grn_expr_parserInit(pParser);
return pParser;
}
+#endif /* grn_expr_parser_ENGINEALWAYSONSTACK */
+
-/* The following function deletes the value associated with a
-** symbol. The symbol can be either a terminal or nonterminal.
-** "yymajor" is the symbol code, and "yypminor" is a pointer to
-** the value.
+/* The following function deletes the "minor type" or semantic value
+** associated with a symbol. The symbol can be either a terminal
+** or nonterminal. "yymajor" is the symbol code, and "yypminor" is
+** a pointer to the value to be deleted. The code used to do the
+** deletions is derived from the %destructor and/or %token_destructor
+** directives of the input grammar.
*/
static void yy_destructor(
yyParser *yypParser, /* The parser */
@@ -871,18 +992,20 @@ static void yy_destructor(
** being destroyed before it is finished parsing.
**
** Note: during a reduce, the only symbols destroyed are those
- ** which appear on the RHS of the rule, but which are not used
+ ** which appear on the RHS of the rule, but which are *not* used
** inside the C code.
*/
- case 75: /* suppress_unused_variable_warning */
+/********* Begin destructor definitions ***************************************/
+ case 76: /* suppress_unused_variable_warning */
{
-#line 11 "grn_ecmascript.lemon"
+#line 14 "grn_ecmascript.lemon"
(void)efsi;
-#line 884 "grn_ecmascript.c"
+#line 1006 "grn_ecmascript.c"
}
break;
+/********* End destructor definitions *****************************************/
default: break; /* If no destructor action specified: do nothing */
}
}
@@ -892,51 +1015,53 @@ static void yy_destructor(
**
** If there is a destructor routine associated with the token which
** is popped from the stack, then call it.
-**
-** Return the major token number for the symbol popped.
*/
-static int yy_pop_parser_stack(yyParser *pParser){
- YYCODETYPE yymajor;
- yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
-
- if( pParser->yyidx<0 ) return 0;
+static void yy_pop_parser_stack(yyParser *pParser){
+ yyStackEntry *yytos;
+ assert( pParser->yytos!=0 );
+ assert( pParser->yytos > pParser->yystack );
+ yytos = pParser->yytos--;
#ifndef NDEBUG
- if( yyTraceFILE && pParser->yyidx>=0 ){
+ if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sPopping %s\n",
yyTracePrompt,
yyTokenName[yytos->major]);
}
#endif
- yymajor = yytos->major;
- yy_destructor(pParser, yymajor, &yytos->minor);
- pParser->yyidx--;
- return yymajor;
+ yy_destructor(pParser, yytos->major, &yytos->minor);
+}
+
+/*
+** Clear all secondary memory allocations from the parser
+*/
+void grn_expr_parserFinalize(void *p){
+ yyParser *pParser = (yyParser*)p;
+ while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
+#if YYSTACKDEPTH<=0
+ if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
+#endif
}
+#ifndef grn_expr_parser_ENGINEALWAYSONSTACK
/*
-** Deallocate and destroy a parser. Destructors are all called for
+** Deallocate and destroy a parser. Destructors are called for
** all stack elements before shutting the parser down.
**
-** Inputs:
-** <ul>
-** <li> A pointer to the parser. This should be a pointer
-** obtained from grn_expr_parserAlloc.
-** <li> A pointer to a function used to reclaim memory obtained
-** from malloc.
-** </ul>
+** If the YYPARSEFREENEVERNULL macro exists (for example because it
+** is defined in a %include section of the input grammar) then it is
+** assumed that the input pointer is never NULL.
*/
void grn_expr_parserFree(
void *p, /* The parser to be deleted */
void (*freeProc)(void*) /* Function used to reclaim memory */
){
- yyParser *pParser = (yyParser*)p;
- if( pParser==0 ) return;
- while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
-#if YYSTACKDEPTH<=0
- free(pParser->yystack);
+#ifndef YYPARSEFREENEVERNULL
+ if( p==0 ) return;
#endif
- (*freeProc)((void*)pParser);
+ grn_expr_parserFinalize(p);
+ (*freeProc)(p);
}
+#endif /* grn_expr_parser_ENGINEALWAYSONSTACK */
/*
** Return the peak depth of the stack for a parser.
@@ -944,33 +1069,28 @@ void grn_expr_parserFree(
#ifdef YYTRACKMAXSTACKDEPTH
int grn_expr_parserStackPeak(void *p){
yyParser *pParser = (yyParser*)p;
- return pParser->yyidxMax;
+ return pParser->yyhwm;
}
#endif
/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
-**
-** If the look-ahead token is YYNOCODE, then check to see if the action is
-** independent of the look-ahead. If it is, return the action, otherwise
-** return YY_NO_ACTION.
*/
-static int yy_find_shift_action(
+static unsigned int yy_find_shift_action(
yyParser *pParser, /* The parser */
YYCODETYPE iLookAhead /* The look-ahead token */
){
int i;
- int stateno = pParser->yystack[pParser->yyidx].stateno;
+ int stateno = pParser->yytos->stateno;
- if( stateno>YY_SHIFT_COUNT
- || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
- return yy_default[stateno];
- }
- assert( iLookAhead!=YYNOCODE );
- i += iLookAhead;
- if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
- if( iLookAhead>0 ){
+ if( stateno>=YY_MIN_REDUCE ) return stateno;
+ assert( stateno <= YY_SHIFT_COUNT );
+ do{
+ i = yy_shift_ofst[stateno];
+ assert( iLookAhead!=YYNOCODE );
+ i += iLookAhead;
+ if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
#ifdef YYFALLBACK
YYCODETYPE iFallback; /* Fallback token */
if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
@@ -981,7 +1101,9 @@ static int yy_find_shift_action(
yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
}
#endif
- return yy_find_shift_action(pParser, iFallback);
+ assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
+ iLookAhead = iFallback;
+ continue;
}
#endif
#ifdef YYWILDCARD
@@ -994,32 +1116,29 @@ static int yy_find_shift_action(
#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
j<YY_ACTTAB_COUNT &&
#endif
- yy_lookahead[j]==YYWILDCARD
+ yy_lookahead[j]==YYWILDCARD && iLookAhead>0
){
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
- yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
+ yyTracePrompt, yyTokenName[iLookAhead],
+ yyTokenName[YYWILDCARD]);
}
#endif /* NDEBUG */
return yy_action[j];
}
}
#endif /* YYWILDCARD */
+ return yy_default[stateno];
+ }else{
+ return yy_action[i];
}
- return yy_default[stateno];
- }else{
- return yy_action[i];
- }
+ }while(1);
}
/*
** Find the appropriate action for a parser given the non-terminal
** look-ahead token iLookAhead.
-**
-** If the look-ahead token is YYNOCODE, then check to see if the action is
-** independent of the look-ahead. If it is, return the action, otherwise
-** return YY_NO_ACTION.
*/
static int yy_find_reduce_action(
int stateno, /* Current state number */
@@ -1051,64 +1170,81 @@ static int yy_find_reduce_action(
/*
** The following routine is called if the stack overflows.
*/
-static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
+static void yyStackOverflow(yyParser *yypParser){
grn_expr_parserARG_FETCH;
- yypParser->yyidx--;
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
}
#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
/* Here code is inserted which will execute if the parser
** stack every overflows */
+/******** Begin %stack_overflow code ******************************************/
+/******** End %stack_overflow code ********************************************/
grn_expr_parserARG_STORE; /* Suppress warning about unused %extra_argument var */
}
/*
+** Print tracing information for a SHIFT action
+*/
+#ifndef NDEBUG
+static void yyTraceShift(yyParser *yypParser, int yyNewState){
+ if( yyTraceFILE ){
+ if( yyNewState<YYNSTATE ){
+ fprintf(yyTraceFILE,"%sShift '%s', go to state %d\n",
+ yyTracePrompt,yyTokenName[yypParser->yytos->major],
+ yyNewState);
+ }else{
+ fprintf(yyTraceFILE,"%sShift '%s'\n",
+ yyTracePrompt,yyTokenName[yypParser->yytos->major]);
+ }
+ }
+}
+#else
+# define yyTraceShift(X,Y)
+#endif
+
+/*
** Perform a shift action.
*/
static void yy_shift(
yyParser *yypParser, /* The parser to be shifted */
int yyNewState, /* The new state to shift in */
int yyMajor, /* The major token to shift in */
- YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */
+ grn_expr_parserTOKENTYPE yyMinor /* The minor token to shift in */
){
yyStackEntry *yytos;
- yypParser->yyidx++;
+ yypParser->yytos++;
#ifdef YYTRACKMAXSTACKDEPTH
- if( yypParser->yyidx>yypParser->yyidxMax ){
- yypParser->yyidxMax = yypParser->yyidx;
+ if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
+ yypParser->yyhwm++;
+ assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) );
}
#endif
#if YYSTACKDEPTH>0
- if( yypParser->yyidx>=YYSTACKDEPTH ){
- yyStackOverflow(yypParser, yypMinor);
+ if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH] ){
+ yypParser->yytos--;
+ yyStackOverflow(yypParser);
return;
}
#else
- if( yypParser->yyidx>=yypParser->yystksz ){
- yyGrowStack(yypParser);
- if( yypParser->yyidx>=yypParser->yystksz ){
- yyStackOverflow(yypParser, yypMinor);
+ if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
+ if( yyGrowStack(yypParser) ){
+ yypParser->yytos--;
+ yyStackOverflow(yypParser);
return;
}
}
#endif
- yytos = &yypParser->yystack[yypParser->yyidx];
+ if( yyNewState > YY_MAX_SHIFT ){
+ yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
+ }
+ yytos = yypParser->yytos;
yytos->stateno = (YYACTIONTYPE)yyNewState;
yytos->major = (YYCODETYPE)yyMajor;
- yytos->minor = *yypMinor;
-#ifndef NDEBUG
- if( yyTraceFILE && yypParser->yyidx>0 ){
- int i;
- fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
- fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
- for(i=1; i<=yypParser->yyidx; i++)
- fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
- fprintf(yyTraceFILE,"\n");
- }
-#endif
+ yytos->minor.yy0 = yyMinor;
+ yyTraceShift(yypParser, yyNewState);
}
/* The following table contains information about every rule that
@@ -1118,138 +1254,142 @@ static const struct {
YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
} yyRuleInfo[] = {
- { 76, 1 },
- { 76, 1 },
- { 76, 2 },
- { 76, 2 },
- { 77, 1 },
- { 77, 2 },
- { 77, 3 },
- { 77, 3 },
- { 77, 3 },
- { 81, 1 },
- { 81, 3 },
- { 81, 2 },
- { 81, 3 },
- { 81, 3 },
- { 81, 2 },
- { 78, 1 },
+ { 78, 2 },
{ 78, 3 },
- { 83, 1 },
- { 83, 3 },
- { 83, 3 },
- { 83, 3 },
- { 83, 3 },
- { 83, 3 },
- { 83, 3 },
- { 83, 3 },
- { 83, 3 },
- { 83, 3 },
- { 83, 3 },
- { 83, 3 },
- { 83, 3 },
- { 84, 1 },
- { 84, 5 },
- { 86, 1 },
- { 86, 3 },
- { 87, 1 },
- { 87, 3 },
+ { 78, 3 },
+ { 78, 3 },
+ { 78, 3 },
+ { 82, 2 },
+ { 82, 2 },
+ { 82, 3 },
+ { 82, 3 },
+ { 82, 2 },
+ { 79, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 84, 3 },
+ { 85, 5 },
{ 87, 3 },
- { 88, 1 },
{ 88, 3 },
- { 89, 1 },
+ { 88, 3 },
{ 89, 3 },
- { 90, 1 },
{ 90, 3 },
- { 91, 1 },
{ 91, 3 },
- { 91, 3 },
- { 92, 1 },
- { 92, 3 },
- { 92, 3 },
- { 92, 3 },
- { 92, 3 },
- { 92, 3 },
- { 92, 3 },
{ 92, 3 },
{ 92, 3 },
- { 92, 3 },
- { 92, 3 },
- { 92, 3 },
- { 92, 3 },
- { 92, 3 },
- { 92, 3 },
- { 93, 1 },
{ 93, 3 },
{ 93, 3 },
{ 93, 3 },
- { 94, 1 },
+ { 93, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 94, 3 },
{ 94, 3 },
{ 94, 3 },
- { 95, 1 },
- { 95, 3 },
{ 95, 3 },
{ 95, 3 },
- { 96, 1 },
- { 96, 2 },
- { 96, 2 },
- { 96, 2 },
- { 96, 2 },
- { 96, 2 },
- { 96, 2 },
- { 96, 2 },
- { 96, 2 },
- { 96, 2 },
- { 96, 2 },
- { 96, 2 },
- { 97, 1 },
+ { 96, 3 },
+ { 96, 3 },
+ { 96, 3 },
+ { 97, 2 },
+ { 97, 2 },
+ { 97, 2 },
+ { 97, 2 },
+ { 97, 2 },
+ { 97, 2 },
+ { 97, 2 },
+ { 97, 2 },
+ { 97, 2 },
{ 97, 2 },
{ 97, 2 },
- { 85, 1 },
- { 85, 1 },
{ 98, 2 },
- { 99, 1 },
+ { 98, 2 },
{ 99, 2 },
- { 82, 1 },
- { 82, 3 },
- { 82, 1 },
- { 82, 1 },
- { 82, 1 },
- { 82, 1 },
- { 82, 1 },
- { 82, 1 },
- { 82, 1 },
- { 103, 3 },
- { 103, 4 },
{ 103, 3 },
- { 104, 1 },
- { 104, 2 },
- { 105, 1 },
- { 105, 2 },
- { 105, 3 },
+ { 107, 0 },
+ { 108, 3 },
{ 102, 3 },
- { 106, 0 },
- { 106, 3 },
- { 107, 3 },
- { 108, 1 },
{ 101, 3 },
- { 101, 2 },
- { 100, 3 },
- { 109, 0 },
- { 109, 1 },
- { 109, 3 },
- { 79, 0 },
- { 79, 1 },
- { 79, 3 },
- { 110, 1 },
- { 110, 1 },
+ { 110, 0 },
{ 110, 1 },
+ { 110, 3 },
{ 80, 0 },
{ 80, 1 },
+ { 80, 2 },
{ 80, 3 },
{ 111, 1 },
- { 111, 3 },
+ { 111, 1 },
+ { 111, 1 },
+ { 81, 3 },
{ 112, 3 },
+ { 113, 3 },
+ { 77, 1 },
+ { 77, 1 },
+ { 77, 2 },
+ { 77, 2 },
+ { 78, 1 },
+ { 82, 1 },
+ { 82, 3 },
+ { 79, 1 },
+ { 84, 1 },
+ { 85, 1 },
+ { 87, 1 },
+ { 88, 1 },
+ { 89, 1 },
+ { 90, 1 },
+ { 91, 1 },
+ { 92, 1 },
+ { 93, 1 },
+ { 94, 1 },
+ { 95, 1 },
+ { 96, 1 },
+ { 97, 1 },
+ { 98, 1 },
+ { 86, 1 },
+ { 86, 1 },
+ { 100, 1 },
+ { 100, 2 },
+ { 83, 1 },
+ { 83, 3 },
+ { 83, 1 },
+ { 83, 1 },
+ { 83, 1 },
+ { 83, 1 },
+ { 83, 1 },
+ { 83, 1 },
+ { 83, 1 },
+ { 104, 3 },
+ { 104, 4 },
+ { 104, 3 },
+ { 105, 1 },
+ { 105, 2 },
+ { 106, 1 },
+ { 106, 2 },
+ { 106, 3 },
+ { 107, 1 },
+ { 107, 3 },
+ { 109, 1 },
+ { 102, 2 },
+ { 81, 0 },
+ { 81, 1 },
+ { 112, 1 },
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -1260,40 +1400,47 @@ static void yy_accept(yyParser*); /* Forward Declaration */
*/
static void yy_reduce(
yyParser *yypParser, /* The parser */
- int yyruleno /* Number of the rule by which to reduce */
+ unsigned int yyruleno /* Number of the rule by which to reduce */
){
int yygoto; /* The next state */
int yyact; /* The next action */
- YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
yyStackEntry *yymsp; /* The top of the parser's stack */
int yysize; /* Amount to pop the stack */
grn_expr_parserARG_FETCH;
- yymsp = &yypParser->yystack[yypParser->yyidx];
+ yymsp = yypParser->yytos;
#ifndef NDEBUG
- if( yyTraceFILE && yyruleno>=0
- && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
- fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
- yyRuleName[yyruleno]);
+ if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
+ yysize = yyRuleInfo[yyruleno].nrhs;
+ fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt,
+ yyRuleName[yyruleno], yymsp[-yysize].stateno);
}
#endif /* NDEBUG */
- /* Silence complaints from purify about yygotominor being uninitialized
- ** in some cases when it is copied into the stack after the following
- ** switch. yygotominor is uninitialized when a rule reduces that does
- ** not set the value of its left-hand side nonterminal. Leaving the
- ** value of the nonterminal uninitialized is utterly harmless as long
- ** as the value is never used. So really the only thing this code
- ** accomplishes is to quieten purify.
- **
- ** 2007-01-16: The wireshark project (www.wireshark.org) reports that
- ** without this code, their parser segfaults. I'm not sure what there
- ** parser is doing to make this happen. This is the second bug report
- ** from wireshark this week. Clearly they are stressing Lemon in ways
- ** that it has not been previously stressed... (SQLite ticket #2172)
- */
- /*memset(&yygotominor, 0, sizeof(yygotominor));*/
- yygotominor = yyzerominor;
-
+ /* Check that the stack is large enough to grow by a single entry
+ ** if the RHS of the rule is empty. This ensures that there is room
+ ** enough on the stack to push the LHS value */
+ if( yyRuleInfo[yyruleno].nrhs==0 ){
+#ifdef YYTRACKMAXSTACKDEPTH
+ if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
+ yypParser->yyhwm++;
+ assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack));
+ }
+#endif
+#if YYSTACKDEPTH>0
+ if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH-1] ){
+ yyStackOverflow(yypParser);
+ return;
+ }
+#else
+ if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
+ if( yyGrowStack(yypParser) ){
+ yyStackOverflow(yypParser);
+ return;
+ }
+ yymsp = yypParser->yytos;
+ }
+#endif
+ }
switch( yyruleno ){
/* Beginning here are the reduction cases. A typical example
@@ -1304,47 +1451,66 @@ static void yy_reduce(
** #line <lineno> <thisfile>
** break;
*/
- case 5: /* query ::= query query_element */
-#line 46 "grn_ecmascript.lemon"
+/********** Begin reduce actions **********************************************/
+ YYMINORTYPE yylhsminor;
+ case 0: /* query ::= query query_element */
+#line 53 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, grn_int32_value_at(&efsi->op_stack, -1), 2);
}
-#line 1313 "grn_ecmascript.c"
+#line 1462 "grn_ecmascript.c"
break;
- case 6: /* query ::= query LOGICAL_AND query_element */
- case 35: /* logical_and_expression ::= logical_and_expression LOGICAL_AND bitwise_or_expression */ yytestcase(yyruleno==35);
-#line 49 "grn_ecmascript.lemon"
+ case 1: /* query ::= query LOGICAL_AND query_element */
+ case 25: /* logical_and_expression ::= logical_and_expression LOGICAL_AND bitwise_or_expression */ yytestcase(yyruleno==25);
+#line 56 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND, 2);
}
-#line 1321 "grn_ecmascript.c"
+#line 1470 "grn_ecmascript.c"
break;
- case 7: /* query ::= query LOGICAL_AND_NOT query_element */
- case 36: /* logical_and_expression ::= logical_and_expression LOGICAL_AND_NOT bitwise_or_expression */ yytestcase(yyruleno==36);
-#line 52 "grn_ecmascript.lemon"
+ case 2: /* query ::= query LOGICAL_AND_NOT query_element */
+ case 26: /* logical_and_expression ::= logical_and_expression LOGICAL_AND_NOT bitwise_or_expression */ yytestcase(yyruleno==26);
+#line 59 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_NOT, 2);
}
-#line 1329 "grn_ecmascript.c"
+#line 1478 "grn_ecmascript.c"
break;
- case 8: /* query ::= query LOGICAL_OR query_element */
- case 33: /* logical_or_expression ::= logical_or_expression LOGICAL_OR logical_and_expression */ yytestcase(yyruleno==33);
-#line 55 "grn_ecmascript.lemon"
+ case 3: /* query ::= query LOGICAL_OR query_element */
+ case 24: /* logical_or_expression ::= logical_or_expression LOGICAL_OR logical_and_expression */ yytestcase(yyruleno==24);
+#line 62 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR, 2);
}
-#line 1337 "grn_ecmascript.c"
+#line 1486 "grn_ecmascript.c"
break;
- case 11: /* query_element ::= RELATIVE_OP query_element */
-#line 62 "grn_ecmascript.lemon"
+ case 4: /* query ::= query NEGATIVE query_element */
+#line 65 "grn_ecmascript.lemon"
+{
+ int weight;
+ GRN_INT32_POP(&efsi->weight_stack, weight);
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ADJUST, 2);
+}
+#line 1495 "grn_ecmascript.c"
+ break;
+ case 5: /* query_element ::= ADJUST query_element */
+#line 74 "grn_ecmascript.lemon"
+{
+ int weight;
+ GRN_INT32_POP(&efsi->weight_stack, weight);
+}
+#line 1503 "grn_ecmascript.c"
+ break;
+ case 6: /* query_element ::= RELATIVE_OP query_element */
+#line 78 "grn_ecmascript.lemon"
{
int mode;
GRN_INT32_POP(&efsi->mode_stack, mode);
}
-#line 1345 "grn_ecmascript.c"
+#line 1511 "grn_ecmascript.c"
break;
- case 12: /* query_element ::= IDENTIFIER RELATIVE_OP query_element */
-#line 66 "grn_ecmascript.lemon"
+ case 7: /* query_element ::= IDENTIFIER RELATIVE_OP query_element */
+#line 82 "grn_ecmascript.lemon"
{
int mode;
grn_obj *c;
@@ -1368,654 +1534,746 @@ static void yy_reduce(
break;
}
}
-#line 1372 "grn_ecmascript.c"
+#line 1538 "grn_ecmascript.c"
break;
- case 13: /* query_element ::= BRACEL expression BRACER */
- case 14: /* query_element ::= EVAL primary_expression */ yytestcase(yyruleno==14);
-#line 89 "grn_ecmascript.lemon"
+ case 8: /* query_element ::= BRACEL expression BRACER */
+ case 9: /* query_element ::= EVAL primary_expression */ yytestcase(yyruleno==9);
+#line 105 "grn_ecmascript.lemon"
{
efsi->flags = efsi->default_flags;
}
-#line 1380 "grn_ecmascript.c"
+#line 1546 "grn_ecmascript.c"
break;
- case 16: /* expression ::= expression COMMA assignment_expression */
-#line 97 "grn_ecmascript.lemon"
+ case 10: /* expression ::= expression COMMA assignment_expression */
+#line 113 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_COMMA, 2);
}
-#line 1387 "grn_ecmascript.c"
+#line 1553 "grn_ecmascript.c"
break;
- case 18: /* assignment_expression ::= lefthand_side_expression ASSIGN assignment_expression */
-#line 102 "grn_ecmascript.lemon"
+ case 11: /* assignment_expression ::= lefthand_side_expression ASSIGN assignment_expression */
+#line 118 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ASSIGN, 2);
}
-#line 1394 "grn_ecmascript.c"
+#line 1560 "grn_ecmascript.c"
break;
- case 19: /* assignment_expression ::= lefthand_side_expression STAR_ASSIGN assignment_expression */
-#line 105 "grn_ecmascript.lemon"
+ case 12: /* assignment_expression ::= lefthand_side_expression STAR_ASSIGN assignment_expression */
+#line 121 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR_ASSIGN, 2);
}
-#line 1401 "grn_ecmascript.c"
+#line 1567 "grn_ecmascript.c"
break;
- case 20: /* assignment_expression ::= lefthand_side_expression SLASH_ASSIGN assignment_expression */
-#line 108 "grn_ecmascript.lemon"
+ case 13: /* assignment_expression ::= lefthand_side_expression SLASH_ASSIGN assignment_expression */
+#line 124 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SLASH_ASSIGN, 2);
}
-#line 1408 "grn_ecmascript.c"
+#line 1574 "grn_ecmascript.c"
break;
- case 21: /* assignment_expression ::= lefthand_side_expression MOD_ASSIGN assignment_expression */
-#line 111 "grn_ecmascript.lemon"
+ case 14: /* assignment_expression ::= lefthand_side_expression MOD_ASSIGN assignment_expression */
+#line 127 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MOD_ASSIGN, 2);
}
-#line 1415 "grn_ecmascript.c"
+#line 1581 "grn_ecmascript.c"
break;
- case 22: /* assignment_expression ::= lefthand_side_expression PLUS_ASSIGN assignment_expression */
-#line 114 "grn_ecmascript.lemon"
+ case 15: /* assignment_expression ::= lefthand_side_expression PLUS_ASSIGN assignment_expression */
+#line 130 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS_ASSIGN, 2);
}
-#line 1422 "grn_ecmascript.c"
+#line 1588 "grn_ecmascript.c"
break;
- case 23: /* assignment_expression ::= lefthand_side_expression MINUS_ASSIGN assignment_expression */
-#line 117 "grn_ecmascript.lemon"
+ case 16: /* assignment_expression ::= lefthand_side_expression MINUS_ASSIGN assignment_expression */
+#line 133 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS_ASSIGN, 2);
}
-#line 1429 "grn_ecmascript.c"
+#line 1595 "grn_ecmascript.c"
break;
- case 24: /* assignment_expression ::= lefthand_side_expression SHIFTL_ASSIGN assignment_expression */
-#line 120 "grn_ecmascript.lemon"
+ case 17: /* assignment_expression ::= lefthand_side_expression SHIFTL_ASSIGN assignment_expression */
+#line 136 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL_ASSIGN, 2);
}
-#line 1436 "grn_ecmascript.c"
+#line 1602 "grn_ecmascript.c"
break;
- case 25: /* assignment_expression ::= lefthand_side_expression SHIFTR_ASSIGN assignment_expression */
-#line 123 "grn_ecmascript.lemon"
+ case 18: /* assignment_expression ::= lefthand_side_expression SHIFTR_ASSIGN assignment_expression */
+#line 139 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR_ASSIGN, 2);
}
-#line 1443 "grn_ecmascript.c"
+#line 1609 "grn_ecmascript.c"
break;
- case 26: /* assignment_expression ::= lefthand_side_expression SHIFTRR_ASSIGN assignment_expression */
-#line 126 "grn_ecmascript.lemon"
+ case 19: /* assignment_expression ::= lefthand_side_expression SHIFTRR_ASSIGN assignment_expression */
+#line 142 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTRR_ASSIGN, 2);
}
-#line 1450 "grn_ecmascript.c"
+#line 1616 "grn_ecmascript.c"
break;
- case 27: /* assignment_expression ::= lefthand_side_expression AND_ASSIGN assignment_expression */
-#line 129 "grn_ecmascript.lemon"
+ case 20: /* assignment_expression ::= lefthand_side_expression AND_ASSIGN assignment_expression */
+#line 145 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_ASSIGN, 2);
}
-#line 1457 "grn_ecmascript.c"
+#line 1623 "grn_ecmascript.c"
break;
- case 28: /* assignment_expression ::= lefthand_side_expression XOR_ASSIGN assignment_expression */
-#line 132 "grn_ecmascript.lemon"
+ case 21: /* assignment_expression ::= lefthand_side_expression XOR_ASSIGN assignment_expression */
+#line 148 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_XOR_ASSIGN, 2);
}
-#line 1464 "grn_ecmascript.c"
+#line 1630 "grn_ecmascript.c"
break;
- case 29: /* assignment_expression ::= lefthand_side_expression OR_ASSIGN assignment_expression */
-#line 135 "grn_ecmascript.lemon"
+ case 22: /* assignment_expression ::= lefthand_side_expression OR_ASSIGN assignment_expression */
+#line 151 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR_ASSIGN, 2);
}
-#line 1471 "grn_ecmascript.c"
+#line 1637 "grn_ecmascript.c"
break;
- case 31: /* conditional_expression ::= logical_or_expression QUESTION assignment_expression COLON assignment_expression */
-#line 140 "grn_ecmascript.lemon"
+ case 23: /* conditional_expression ::= logical_or_expression QUESTION assignment_expression COLON assignment_expression */
+#line 156 "grn_ecmascript.lemon"
{
grn_expr *e = (grn_expr *)efsi->e;
e->codes[yymsp[-3].minor.yy0].nargs = yymsp[-1].minor.yy0 - yymsp[-3].minor.yy0;
e->codes[yymsp[-1].minor.yy0].nargs = e->codes_curr - yymsp[-1].minor.yy0 - 1;
}
-#line 1480 "grn_ecmascript.c"
+#line 1646 "grn_ecmascript.c"
break;
- case 38: /* bitwise_or_expression ::= bitwise_or_expression BITWISE_OR bitwise_xor_expression */
-#line 160 "grn_ecmascript.lemon"
+ case 27: /* bitwise_or_expression ::= bitwise_or_expression BITWISE_OR bitwise_xor_expression */
+#line 176 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_OR, 2);
}
-#line 1487 "grn_ecmascript.c"
+#line 1653 "grn_ecmascript.c"
break;
- case 40: /* bitwise_xor_expression ::= bitwise_xor_expression BITWISE_XOR bitwise_and_expression */
-#line 165 "grn_ecmascript.lemon"
+ case 28: /* bitwise_xor_expression ::= bitwise_xor_expression BITWISE_XOR bitwise_and_expression */
+#line 181 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_XOR, 2);
}
-#line 1494 "grn_ecmascript.c"
+#line 1660 "grn_ecmascript.c"
break;
- case 42: /* bitwise_and_expression ::= bitwise_and_expression BITWISE_AND equality_expression */
-#line 170 "grn_ecmascript.lemon"
+ case 29: /* bitwise_and_expression ::= bitwise_and_expression BITWISE_AND equality_expression */
+#line 186 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_AND, 2);
}
-#line 1501 "grn_ecmascript.c"
+#line 1667 "grn_ecmascript.c"
break;
- case 44: /* equality_expression ::= equality_expression EQUAL relational_expression */
-#line 175 "grn_ecmascript.lemon"
+ case 30: /* equality_expression ::= equality_expression EQUAL relational_expression */
+#line 191 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_EQUAL, 2);
}
-#line 1508 "grn_ecmascript.c"
+#line 1674 "grn_ecmascript.c"
break;
- case 45: /* equality_expression ::= equality_expression NOT_EQUAL relational_expression */
-#line 178 "grn_ecmascript.lemon"
+ case 31: /* equality_expression ::= equality_expression NOT_EQUAL relational_expression */
+#line 194 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NOT_EQUAL, 2);
}
-#line 1515 "grn_ecmascript.c"
+#line 1681 "grn_ecmascript.c"
break;
- case 47: /* relational_expression ::= relational_expression LESS shift_expression */
-#line 183 "grn_ecmascript.lemon"
+ case 32: /* relational_expression ::= relational_expression LESS shift_expression */
+#line 199 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LESS, 2);
}
-#line 1522 "grn_ecmascript.c"
+#line 1688 "grn_ecmascript.c"
break;
- case 48: /* relational_expression ::= relational_expression GREATER shift_expression */
-#line 186 "grn_ecmascript.lemon"
+ case 33: /* relational_expression ::= relational_expression GREATER shift_expression */
+#line 202 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GREATER, 2);
}
-#line 1529 "grn_ecmascript.c"
+#line 1695 "grn_ecmascript.c"
break;
- case 49: /* relational_expression ::= relational_expression LESS_EQUAL shift_expression */
-#line 189 "grn_ecmascript.lemon"
+ case 34: /* relational_expression ::= relational_expression LESS_EQUAL shift_expression */
+#line 205 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LESS_EQUAL, 2);
}
-#line 1536 "grn_ecmascript.c"
+#line 1702 "grn_ecmascript.c"
break;
- case 50: /* relational_expression ::= relational_expression GREATER_EQUAL shift_expression */
-#line 192 "grn_ecmascript.lemon"
+ case 35: /* relational_expression ::= relational_expression GREATER_EQUAL shift_expression */
+#line 208 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GREATER_EQUAL, 2);
}
-#line 1543 "grn_ecmascript.c"
+#line 1709 "grn_ecmascript.c"
break;
- case 51: /* relational_expression ::= relational_expression IN shift_expression */
-#line 195 "grn_ecmascript.lemon"
+ case 36: /* relational_expression ::= relational_expression IN shift_expression */
+#line 211 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_IN, 2);
}
-#line 1550 "grn_ecmascript.c"
+#line 1716 "grn_ecmascript.c"
break;
- case 52: /* relational_expression ::= relational_expression MATCH shift_expression */
- case 131: /* adjust_match_expression ::= IDENTIFIER MATCH STRING */ yytestcase(yyruleno==131);
-#line 198 "grn_ecmascript.lemon"
+ case 37: /* relational_expression ::= relational_expression MATCH shift_expression */
+ case 85: /* adjust_match_expression ::= IDENTIFIER MATCH STRING */ yytestcase(yyruleno==85);
+#line 214 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MATCH, 2);
}
-#line 1558 "grn_ecmascript.c"
+#line 1724 "grn_ecmascript.c"
break;
- case 53: /* relational_expression ::= relational_expression NEAR shift_expression */
-#line 201 "grn_ecmascript.lemon"
+ case 38: /* relational_expression ::= relational_expression NEAR shift_expression */
+#line 217 "grn_ecmascript.lemon"
{
- grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR, 2);
+ {
+ int max_interval;
+ GRN_INT32_POP(&efsi->max_interval_stack, max_interval);
+ grn_expr_append_const_int(efsi->ctx, efsi->e, max_interval,
+ GRN_OP_PUSH, 1);
+ }
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR, 3);
}
-#line 1565 "grn_ecmascript.c"
+#line 1737 "grn_ecmascript.c"
break;
- case 54: /* relational_expression ::= relational_expression NEAR2 shift_expression */
-#line 204 "grn_ecmascript.lemon"
+ case 39: /* relational_expression ::= relational_expression NEAR2 shift_expression */
+#line 226 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR2, 2);
}
-#line 1572 "grn_ecmascript.c"
+#line 1744 "grn_ecmascript.c"
break;
- case 55: /* relational_expression ::= relational_expression SIMILAR shift_expression */
-#line 207 "grn_ecmascript.lemon"
+ case 40: /* relational_expression ::= relational_expression SIMILAR shift_expression */
+#line 229 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SIMILAR, 2);
}
-#line 1579 "grn_ecmascript.c"
+#line 1751 "grn_ecmascript.c"
break;
- case 56: /* relational_expression ::= relational_expression TERM_EXTRACT shift_expression */
-#line 210 "grn_ecmascript.lemon"
+ case 41: /* relational_expression ::= relational_expression TERM_EXTRACT shift_expression */
+#line 232 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_TERM_EXTRACT, 2);
}
-#line 1586 "grn_ecmascript.c"
+#line 1758 "grn_ecmascript.c"
break;
- case 57: /* relational_expression ::= relational_expression LCP shift_expression */
-#line 213 "grn_ecmascript.lemon"
+ case 42: /* relational_expression ::= relational_expression LCP shift_expression */
+#line 235 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LCP, 2);
}
-#line 1593 "grn_ecmascript.c"
+#line 1765 "grn_ecmascript.c"
break;
- case 58: /* relational_expression ::= relational_expression PREFIX shift_expression */
-#line 216 "grn_ecmascript.lemon"
+ case 43: /* relational_expression ::= relational_expression PREFIX shift_expression */
+#line 238 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PREFIX, 2);
}
-#line 1600 "grn_ecmascript.c"
+#line 1772 "grn_ecmascript.c"
break;
- case 59: /* relational_expression ::= relational_expression SUFFIX shift_expression */
-#line 219 "grn_ecmascript.lemon"
+ case 44: /* relational_expression ::= relational_expression SUFFIX shift_expression */
+#line 241 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SUFFIX, 2);
}
-#line 1607 "grn_ecmascript.c"
+#line 1779 "grn_ecmascript.c"
break;
- case 60: /* relational_expression ::= relational_expression REGEXP shift_expression */
-#line 222 "grn_ecmascript.lemon"
+ case 45: /* relational_expression ::= relational_expression REGEXP shift_expression */
+#line 244 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_REGEXP, 2);
}
-#line 1614 "grn_ecmascript.c"
+#line 1786 "grn_ecmascript.c"
break;
- case 62: /* shift_expression ::= shift_expression SHIFTL additive_expression */
-#line 227 "grn_ecmascript.lemon"
+ case 46: /* shift_expression ::= shift_expression SHIFTL additive_expression */
+#line 249 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL, 2);
}
-#line 1621 "grn_ecmascript.c"
+#line 1793 "grn_ecmascript.c"
break;
- case 63: /* shift_expression ::= shift_expression SHIFTR additive_expression */
-#line 230 "grn_ecmascript.lemon"
+ case 47: /* shift_expression ::= shift_expression SHIFTR additive_expression */
+#line 252 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR, 2);
}
-#line 1628 "grn_ecmascript.c"
+#line 1800 "grn_ecmascript.c"
break;
- case 64: /* shift_expression ::= shift_expression SHIFTRR additive_expression */
-#line 233 "grn_ecmascript.lemon"
+ case 48: /* shift_expression ::= shift_expression SHIFTRR additive_expression */
+#line 255 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTRR, 2);
}
-#line 1635 "grn_ecmascript.c"
+#line 1807 "grn_ecmascript.c"
break;
- case 66: /* additive_expression ::= additive_expression PLUS multiplicative_expression */
- case 128: /* adjuster ::= adjuster PLUS adjust_expression */ yytestcase(yyruleno==128);
-#line 238 "grn_ecmascript.lemon"
+ case 49: /* additive_expression ::= additive_expression PLUS multiplicative_expression */
+ case 83: /* adjuster ::= adjuster PLUS adjust_expression */ yytestcase(yyruleno==83);
+#line 260 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 2);
}
-#line 1643 "grn_ecmascript.c"
+#line 1815 "grn_ecmascript.c"
break;
- case 67: /* additive_expression ::= additive_expression MINUS multiplicative_expression */
-#line 241 "grn_ecmascript.lemon"
+ case 50: /* additive_expression ::= additive_expression MINUS multiplicative_expression */
+#line 263 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS, 2);
}
-#line 1650 "grn_ecmascript.c"
+#line 1822 "grn_ecmascript.c"
break;
- case 69: /* multiplicative_expression ::= multiplicative_expression STAR unary_expression */
- case 130: /* adjust_expression ::= adjust_match_expression STAR DECIMAL */ yytestcase(yyruleno==130);
-#line 246 "grn_ecmascript.lemon"
+ case 51: /* multiplicative_expression ::= multiplicative_expression STAR unary_expression */
+ case 84: /* adjust_expression ::= adjust_match_expression STAR DECIMAL */ yytestcase(yyruleno==84);
+#line 268 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR, 2);
}
-#line 1658 "grn_ecmascript.c"
+#line 1830 "grn_ecmascript.c"
break;
- case 70: /* multiplicative_expression ::= multiplicative_expression SLASH unary_expression */
-#line 249 "grn_ecmascript.lemon"
+ case 52: /* multiplicative_expression ::= multiplicative_expression SLASH unary_expression */
+#line 271 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SLASH, 2);
}
-#line 1665 "grn_ecmascript.c"
+#line 1837 "grn_ecmascript.c"
break;
- case 71: /* multiplicative_expression ::= multiplicative_expression MOD unary_expression */
-#line 252 "grn_ecmascript.lemon"
+ case 53: /* multiplicative_expression ::= multiplicative_expression MOD unary_expression */
+#line 274 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MOD, 2);
}
-#line 1672 "grn_ecmascript.c"
+#line 1844 "grn_ecmascript.c"
break;
- case 73: /* unary_expression ::= DELETE unary_expression */
-#line 257 "grn_ecmascript.lemon"
+ case 54: /* unary_expression ::= DELETE unary_expression */
+#line 279 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DELETE, 1);
}
-#line 1679 "grn_ecmascript.c"
+#line 1851 "grn_ecmascript.c"
break;
- case 74: /* unary_expression ::= INCR unary_expression */
-#line 260 "grn_ecmascript.lemon"
+ case 55: /* unary_expression ::= INCR unary_expression */
+#line 282 "grn_ecmascript.lemon"
{
grn_ctx *ctx = efsi->ctx;
grn_expr *e = (grn_expr *)(efsi->e);
grn_expr_dfi *dfi_;
unsigned int const_p;
- DFI_POP(e, dfi_);
+ dfi_ = grn_expr_dfi_pop(e);
const_p = CONSTP(dfi_->code->value);
- DFI_PUT(e, dfi_->type, dfi_->domain, dfi_->code);
+ grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code);
if (const_p) {
ERR(GRN_SYNTAX_ERROR,
- "constant can't be incremented (%.*s)",
+ "constant can't be incremented: <%.*s>",
(int)(efsi->str_end - efsi->str), efsi->str);
} else {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR, 1);
}
}
-#line 1700 "grn_ecmascript.c"
+#line 1872 "grn_ecmascript.c"
break;
- case 75: /* unary_expression ::= DECR unary_expression */
-#line 277 "grn_ecmascript.lemon"
+ case 56: /* unary_expression ::= DECR unary_expression */
+#line 299 "grn_ecmascript.lemon"
{
grn_ctx *ctx = efsi->ctx;
grn_expr *e = (grn_expr *)(efsi->e);
grn_expr_dfi *dfi_;
unsigned int const_p;
- DFI_POP(e, dfi_);
+ dfi_ = grn_expr_dfi_pop(e);
const_p = CONSTP(dfi_->code->value);
- DFI_PUT(e, dfi_->type, dfi_->domain, dfi_->code);
+ grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code);
if (const_p) {
ERR(GRN_SYNTAX_ERROR,
- "constant can't be decremented (%.*s)",
+ "constant can't be decremented: <%.*s>",
(int)(efsi->str_end - efsi->str), efsi->str);
} else {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR, 1);
}
}
-#line 1721 "grn_ecmascript.c"
+#line 1893 "grn_ecmascript.c"
break;
- case 76: /* unary_expression ::= PLUS unary_expression */
-#line 294 "grn_ecmascript.lemon"
+ case 57: /* unary_expression ::= PLUS unary_expression */
+#line 316 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 1);
}
-#line 1728 "grn_ecmascript.c"
+#line 1900 "grn_ecmascript.c"
break;
- case 77: /* unary_expression ::= MINUS unary_expression */
-#line 297 "grn_ecmascript.lemon"
+ case 58: /* unary_expression ::= MINUS unary_expression */
+#line 319 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS, 1);
}
-#line 1735 "grn_ecmascript.c"
+#line 1907 "grn_ecmascript.c"
break;
- case 78: /* unary_expression ::= NOT unary_expression */
-#line 300 "grn_ecmascript.lemon"
+ case 59: /* unary_expression ::= NOT unary_expression */
+#line 322 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NOT, 1);
}
-#line 1742 "grn_ecmascript.c"
+#line 1914 "grn_ecmascript.c"
break;
- case 79: /* unary_expression ::= BITWISE_NOT unary_expression */
-#line 303 "grn_ecmascript.lemon"
+ case 60: /* unary_expression ::= BITWISE_NOT unary_expression */
+#line 325 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_NOT, 1);
}
-#line 1749 "grn_ecmascript.c"
+#line 1921 "grn_ecmascript.c"
break;
- case 80: /* unary_expression ::= ADJUST unary_expression */
-#line 306 "grn_ecmascript.lemon"
+ case 61: /* unary_expression ::= ADJUST unary_expression */
+#line 328 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ADJUST, 1);
}
-#line 1756 "grn_ecmascript.c"
+#line 1928 "grn_ecmascript.c"
break;
- case 81: /* unary_expression ::= EXACT unary_expression */
-#line 309 "grn_ecmascript.lemon"
+ case 62: /* unary_expression ::= EXACT unary_expression */
+#line 331 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_EXACT, 1);
}
-#line 1763 "grn_ecmascript.c"
+#line 1935 "grn_ecmascript.c"
break;
- case 82: /* unary_expression ::= PARTIAL unary_expression */
-#line 312 "grn_ecmascript.lemon"
+ case 63: /* unary_expression ::= PARTIAL unary_expression */
+#line 334 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PARTIAL, 1);
}
-#line 1770 "grn_ecmascript.c"
+#line 1942 "grn_ecmascript.c"
break;
- case 83: /* unary_expression ::= UNSPLIT unary_expression */
-#line 315 "grn_ecmascript.lemon"
+ case 64: /* unary_expression ::= UNSPLIT unary_expression */
+#line 337 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_UNSPLIT, 1);
}
-#line 1777 "grn_ecmascript.c"
+#line 1949 "grn_ecmascript.c"
break;
- case 85: /* postfix_expression ::= lefthand_side_expression INCR */
-#line 320 "grn_ecmascript.lemon"
+ case 65: /* postfix_expression ::= lefthand_side_expression INCR */
+#line 342 "grn_ecmascript.lemon"
{
grn_ctx *ctx = efsi->ctx;
grn_expr *e = (grn_expr *)(efsi->e);
grn_expr_dfi *dfi_;
unsigned int const_p;
- DFI_POP(e, dfi_);
+ dfi_ = grn_expr_dfi_pop(e);
const_p = CONSTP(dfi_->code->value);
- DFI_PUT(e, dfi_->type, dfi_->domain, dfi_->code);
+ grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code);
if (const_p) {
ERR(GRN_SYNTAX_ERROR,
- "constant can't be incremented (%.*s)",
+ "constant can't be incremented: <%.*s>",
(int)(efsi->str_end - efsi->str), efsi->str);
} else {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR_POST, 1);
}
}
-#line 1798 "grn_ecmascript.c"
+#line 1970 "grn_ecmascript.c"
break;
- case 86: /* postfix_expression ::= lefthand_side_expression DECR */
-#line 337 "grn_ecmascript.lemon"
+ case 66: /* postfix_expression ::= lefthand_side_expression DECR */
+#line 359 "grn_ecmascript.lemon"
{
grn_ctx *ctx = efsi->ctx;
grn_expr *e = (grn_expr *)(efsi->e);
grn_expr_dfi *dfi_;
unsigned int const_p;
- DFI_POP(e, dfi_);
+ dfi_ = grn_expr_dfi_pop(e);
const_p = CONSTP(dfi_->code->value);
- DFI_PUT(e, dfi_->type, dfi_->domain, dfi_->code);
+ grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code);
if (const_p) {
ERR(GRN_SYNTAX_ERROR,
- "constant can't be decremented (%.*s)",
+ "constant can't be decremented: <%.*s>",
(int)(efsi->str_end - efsi->str), efsi->str);
} else {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR_POST, 1);
}
}
-#line 1819 "grn_ecmascript.c"
+#line 1991 "grn_ecmascript.c"
break;
- case 89: /* call_expression ::= member_expression arguments */
-#line 358 "grn_ecmascript.lemon"
+ case 67: /* call_expression ::= member_expression arguments */
+#line 380 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_CALL, yymsp[0].minor.yy0);
}
-#line 1826 "grn_ecmascript.c"
+#line 1998 "grn_ecmascript.c"
+ break;
+ case 68: /* object_literal ::= BRACEL property_name_and_value_list BRACER */
+#line 408 "grn_ecmascript.lemon"
+{
+ grn_ctx *ctx = efsi->ctx;
+ grn_expr_take_obj(ctx, efsi->e, (grn_obj *)(efsi->object_literal));
+ grn_expr_append_obj(ctx, efsi->e, (grn_obj *)(efsi->object_literal),
+ GRN_OP_PUSH, 1);
+ efsi->object_literal = NULL;
+}
+#line 2009 "grn_ecmascript.c"
+ break;
+ case 69: /* property_name_and_value_list ::= */
+#line 416 "grn_ecmascript.lemon"
+{
+ grn_ctx *ctx = efsi->ctx;
+
+ efsi->object_literal =
+ grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE, sizeof(grn_obj),
+ GRN_OBJ_KEY_VAR_SIZE|GRN_OBJ_TEMPORARY|GRN_HASH_TINY);
+ if (!efsi->object_literal) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "couldn't create hash table for parsing object literal: <%.*s>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ }
+}
+#line 2025 "grn_ecmascript.c"
+ break;
+ case 70: /* property_name_and_value ::= property_name COLON assignment_expression */
+#line 431 "grn_ecmascript.lemon"
+{
+ grn_ctx *ctx = efsi->ctx;
+ grn_expr *e = (grn_expr *)(efsi->e);
+ grn_obj *property = e->codes[e->codes_curr - 3].value;
+ grn_obj *value = e->codes[e->codes_curr - 1].value;
+
+ if (!efsi->object_literal) {
+ efsi->object_literal =
+ grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE, sizeof(grn_obj),
+ GRN_OBJ_KEY_VAR_SIZE|GRN_OBJ_TEMPORARY|GRN_HASH_TINY);
+ }
+
+ if (!efsi->object_literal) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "couldn't create hash table for parsing object literal: <%.*s>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ } else {
+ grn_obj *buf;
+ int added;
+ if (grn_hash_add(ctx, (grn_hash *)efsi->object_literal,
+ GRN_TEXT_VALUE(property), GRN_TEXT_LEN(property),
+ (void **)&buf, &added)) {
+ if (added) {
+ GRN_OBJ_INIT(buf, value->header.type, 0, value->header.domain);
+ GRN_TEXT_PUT(ctx, buf, GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
+ grn_expr_dfi_pop(e);
+ e->codes_curr -= 3;
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "duplicated property name: <%.*s>",
+ (int)GRN_TEXT_LEN(property),
+ GRN_TEXT_VALUE(property));
+ }
+ } else {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to add a property to object literal: <%.*s>",
+ (int)GRN_TEXT_LEN(property),
+ GRN_TEXT_VALUE(property));
+ }
+ }
+}
+#line 2070 "grn_ecmascript.c"
break;
- case 114: /* member_expression_part ::= BRACKETL expression BRACKETR */
-#line 394 "grn_ecmascript.lemon"
+ case 71: /* member_expression_part ::= BRACKETL expression BRACKETR */
+#line 475 "grn_ecmascript.lemon"
{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GET_MEMBER, 2);
}
-#line 1833 "grn_ecmascript.c"
+#line 2077 "grn_ecmascript.c"
break;
- case 116: /* arguments ::= PARENL argument_list PARENR */
-#line 399 "grn_ecmascript.lemon"
-{ yygotominor.yy0 = yymsp[-1].minor.yy0; }
-#line 1838 "grn_ecmascript.c"
+ case 72: /* arguments ::= PARENL argument_list PARENR */
+#line 480 "grn_ecmascript.lemon"
+{ yymsp[-2].minor.yy0 = yymsp[-1].minor.yy0; }
+#line 2082 "grn_ecmascript.c"
break;
- case 117: /* argument_list ::= */
-#line 400 "grn_ecmascript.lemon"
-{ yygotominor.yy0 = 0; }
-#line 1843 "grn_ecmascript.c"
+ case 73: /* argument_list ::= */
+#line 481 "grn_ecmascript.lemon"
+{ yymsp[1].minor.yy0 = 0; }
+#line 2087 "grn_ecmascript.c"
break;
- case 118: /* argument_list ::= assignment_expression */
-#line 401 "grn_ecmascript.lemon"
-{ yygotominor.yy0 = 1; }
-#line 1848 "grn_ecmascript.c"
+ case 74: /* argument_list ::= assignment_expression */
+#line 482 "grn_ecmascript.lemon"
+{ yymsp[0].minor.yy0 = 1; }
+#line 2092 "grn_ecmascript.c"
break;
- case 119: /* argument_list ::= argument_list COMMA assignment_expression */
-#line 402 "grn_ecmascript.lemon"
-{ yygotominor.yy0 = yymsp[-2].minor.yy0 + 1; }
-#line 1853 "grn_ecmascript.c"
+ case 75: /* argument_list ::= argument_list COMMA assignment_expression */
+#line 483 "grn_ecmascript.lemon"
+{ yylhsminor.yy0 = yymsp[-2].minor.yy0 + 1; }
+#line 2097 "grn_ecmascript.c"
+ yymsp[-2].minor.yy0 = yylhsminor.yy0;
break;
- case 120: /* output_columns ::= */
-#line 404 "grn_ecmascript.lemon"
+ case 76: /* output_columns ::= */
+#line 485 "grn_ecmascript.lemon"
{
- yygotominor.yy0 = 0;
+ yymsp[1].minor.yy0 = 0;
}
-#line 1860 "grn_ecmascript.c"
+#line 2105 "grn_ecmascript.c"
break;
- case 121: /* output_columns ::= output_column */
-#line 407 "grn_ecmascript.lemon"
+ case 77: /* output_columns ::= output_column */
+#line 488 "grn_ecmascript.lemon"
{
- if (yymsp[0].minor.yy0) {
- yygotominor.yy0 = 0;
- } else {
- yygotominor.yy0 = 1;
- }
+ yylhsminor.yy0 = yymsp[0].minor.yy0;
+}
+#line 2112 "grn_ecmascript.c"
+ yymsp[0].minor.yy0 = yylhsminor.yy0;
+ break;
+ case 78: /* output_columns ::= output_columns COMMA */
+#line 493 "grn_ecmascript.lemon"
+{
+ yylhsminor.yy0 = yymsp[-1].minor.yy0;
}
-#line 1871 "grn_ecmascript.c"
+#line 2120 "grn_ecmascript.c"
+ yymsp[-1].minor.yy0 = yylhsminor.yy0;
break;
- case 122: /* output_columns ::= output_columns COMMA output_column */
-#line 415 "grn_ecmascript.lemon"
+ case 79: /* output_columns ::= output_columns COMMA output_column */
+#line 498 "grn_ecmascript.lemon"
{
- if (yymsp[0].minor.yy0) {
- yygotominor.yy0 = yymsp[-2].minor.yy0;
+ if (yymsp[-2].minor.yy0 == 0) {
+ yylhsminor.yy0 = yymsp[0].minor.yy0;
+ } else if (yymsp[0].minor.yy0 == 0) {
+ yylhsminor.yy0 = yymsp[-2].minor.yy0;
} else {
- if (yymsp[-2].minor.yy0 == 1) {
+ if (yymsp[0].minor.yy0 == 1) {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_COMMA, 2);
}
- yygotominor.yy0 = 1;
+ yylhsminor.yy0 = 1;
}
}
-#line 1885 "grn_ecmascript.c"
+#line 2137 "grn_ecmascript.c"
+ yymsp[-2].minor.yy0 = yylhsminor.yy0;
break;
- case 123: /* output_column ::= STAR */
-#line 426 "grn_ecmascript.lemon"
+ case 80: /* output_column ::= STAR */
+#line 511 "grn_ecmascript.lemon"
{
grn_ctx *ctx = efsi->ctx;
grn_obj *expr = efsi->e;
- grn_expr *e = (grn_expr *)expr;
grn_obj *variable = grn_expr_get_var_by_offset(ctx, expr, 0);
if (variable) {
grn_id table_id = GRN_OBJ_GET_DOMAIN(variable);
grn_obj *table = grn_ctx_at(ctx, table_id);
grn_obj columns_buffer;
+ int n_columns;
grn_obj **columns;
- int i, n_columns;
GRN_PTR_INIT(&columns_buffer, GRN_OBJ_VECTOR, GRN_ID_NIL);
grn_obj_columns(ctx, table, "*", strlen("*"), &columns_buffer);
n_columns = GRN_BULK_VSIZE(&columns_buffer) / sizeof(grn_obj *);
columns = (grn_obj **)GRN_BULK_HEAD(&columns_buffer);
- for (i = 0; i < n_columns; i++) {
- if (i > 0) {
- grn_expr_append_op(ctx, expr, GRN_OP_COMMA, 2);
+ if (n_columns == 0) {
+ /* do nothing */
+ } else if (n_columns == 1) {
+ grn_obj *column = columns[0];
+ grn_expr_append_const(ctx, expr, column, GRN_OP_GET_VALUE, 1);
+ if (column->header.type == GRN_ACCESSOR) {
+ grn_expr_take_obj(ctx, expr, column);
+ }
+ } else {
+ grn_expr *e = (grn_expr *)expr;
+ grn_bool have_column;
+ int i;
+
+ have_column = (e->codes_curr > 0);
+ for (i = 0; i < n_columns; i++) {
+ grn_obj *column = columns[i];
+ grn_expr_append_const(ctx, expr, column, GRN_OP_GET_VALUE, 1);
+ if (have_column || i > 0) {
+ grn_expr_append_op(ctx, expr, GRN_OP_COMMA, 2);
+ }
+ if (column->header.type == GRN_ACCESSOR) {
+ grn_expr_take_obj(ctx, expr, column);
+ }
}
- grn_expr_append_const(ctx, expr, columns[i], GRN_OP_GET_VALUE, 1);
- GRN_PTR_PUT(ctx, &e->objs, columns[i]);
}
GRN_OBJ_FIN(ctx, &columns_buffer);
- if (n_columns > 0) {
- yygotominor.yy0 = GRN_FALSE;
- } else {
- yygotominor.yy0 = GRN_TRUE;
- }
+ yymsp[0].minor.yy0 = n_columns;
} else {
/* TODO: report error */
- yygotominor.yy0 = GRN_TRUE;
+ yymsp[0].minor.yy0 = 0;
}
}
-#line 1926 "grn_ecmascript.c"
+#line 2192 "grn_ecmascript.c"
break;
- case 124: /* output_column ::= NONEXISTENT_COLUMN */
-#line 463 "grn_ecmascript.lemon"
+ case 81: /* output_column ::= NONEXISTENT_COLUMN */
+#line 561 "grn_ecmascript.lemon"
{
- yygotominor.yy0 = GRN_TRUE;
+ yymsp[0].minor.yy0 = 0;
}
-#line 1933 "grn_ecmascript.c"
+#line 2199 "grn_ecmascript.c"
break;
- case 125: /* output_column ::= assignment_expression */
-#line 466 "grn_ecmascript.lemon"
+ case 82: /* output_column ::= assignment_expression */
+#line 564 "grn_ecmascript.lemon"
{
- yygotominor.yy0 = GRN_FALSE;
+ yymsp[0].minor.yy0 = 1;
}
-#line 1940 "grn_ecmascript.c"
+#line 2206 "grn_ecmascript.c"
break;
default:
- /* (0) input ::= query */ yytestcase(yyruleno==0);
- /* (1) input ::= expression */ yytestcase(yyruleno==1);
- /* (2) input ::= START_OUTPUT_COLUMNS output_columns */ yytestcase(yyruleno==2);
- /* (3) input ::= START_ADJUSTER adjuster */ yytestcase(yyruleno==3);
- /* (4) query ::= query_element */ yytestcase(yyruleno==4);
- /* (9) query_element ::= QSTRING */ yytestcase(yyruleno==9);
- /* (10) query_element ::= PARENL query PARENR */ yytestcase(yyruleno==10);
- /* (15) expression ::= assignment_expression */ yytestcase(yyruleno==15);
- /* (17) assignment_expression ::= conditional_expression */ yytestcase(yyruleno==17);
- /* (30) conditional_expression ::= logical_or_expression */ yytestcase(yyruleno==30);
- /* (32) logical_or_expression ::= logical_and_expression */ yytestcase(yyruleno==32);
- /* (34) logical_and_expression ::= bitwise_or_expression */ yytestcase(yyruleno==34);
- /* (37) bitwise_or_expression ::= bitwise_xor_expression */ yytestcase(yyruleno==37);
- /* (39) bitwise_xor_expression ::= bitwise_and_expression */ yytestcase(yyruleno==39);
- /* (41) bitwise_and_expression ::= equality_expression */ yytestcase(yyruleno==41);
- /* (43) equality_expression ::= relational_expression */ yytestcase(yyruleno==43);
- /* (46) relational_expression ::= shift_expression */ yytestcase(yyruleno==46);
- /* (61) shift_expression ::= additive_expression */ yytestcase(yyruleno==61);
- /* (65) additive_expression ::= multiplicative_expression */ yytestcase(yyruleno==65);
- /* (68) multiplicative_expression ::= unary_expression */ yytestcase(yyruleno==68);
- /* (72) unary_expression ::= postfix_expression */ yytestcase(yyruleno==72);
- /* (84) postfix_expression ::= lefthand_side_expression */ yytestcase(yyruleno==84);
- /* (87) lefthand_side_expression ::= call_expression */ yytestcase(yyruleno==87);
- /* (88) lefthand_side_expression ::= member_expression */ yytestcase(yyruleno==88);
- /* (90) member_expression ::= primary_expression */ yytestcase(yyruleno==90);
- /* (91) member_expression ::= member_expression member_expression_part */ yytestcase(yyruleno==91);
- /* (92) primary_expression ::= object_literal */ yytestcase(yyruleno==92);
- /* (93) primary_expression ::= PARENL expression PARENR */ yytestcase(yyruleno==93);
- /* (94) primary_expression ::= IDENTIFIER */ yytestcase(yyruleno==94);
- /* (95) primary_expression ::= array_literal */ yytestcase(yyruleno==95);
- /* (96) primary_expression ::= DECIMAL */ yytestcase(yyruleno==96);
- /* (97) primary_expression ::= HEX_INTEGER */ yytestcase(yyruleno==97);
- /* (98) primary_expression ::= STRING */ yytestcase(yyruleno==98);
- /* (99) primary_expression ::= BOOLEAN */ yytestcase(yyruleno==99);
- /* (100) primary_expression ::= NULL */ yytestcase(yyruleno==100);
- /* (101) array_literal ::= BRACKETL elision BRACKETR */ yytestcase(yyruleno==101);
- /* (102) array_literal ::= BRACKETL element_list elision BRACKETR */ yytestcase(yyruleno==102);
- /* (103) array_literal ::= BRACKETL element_list BRACKETR */ yytestcase(yyruleno==103);
- /* (104) elision ::= COMMA */ yytestcase(yyruleno==104);
- /* (105) elision ::= elision COMMA */ yytestcase(yyruleno==105);
- /* (106) element_list ::= assignment_expression */ yytestcase(yyruleno==106);
- /* (107) element_list ::= elision assignment_expression */ yytestcase(yyruleno==107);
- /* (108) element_list ::= element_list elision assignment_expression */ yytestcase(yyruleno==108);
- /* (109) object_literal ::= BRACEL property_name_and_value_list BRACER */ yytestcase(yyruleno==109);
- /* (110) property_name_and_value_list ::= */ yytestcase(yyruleno==110);
- /* (111) property_name_and_value_list ::= property_name_and_value_list COMMA property_name_and_value */ yytestcase(yyruleno==111);
- /* (112) property_name_and_value ::= property_name COLON assignment_expression */ yytestcase(yyruleno==112);
- /* (113) property_name ::= IDENTIFIER|STRING|DECIMAL */ yytestcase(yyruleno==113);
- /* (115) member_expression_part ::= DOT IDENTIFIER */ yytestcase(yyruleno==115);
- /* (126) adjuster ::= */ yytestcase(yyruleno==126);
- /* (127) adjuster ::= adjust_expression */ yytestcase(yyruleno==127);
- /* (129) adjust_expression ::= adjust_match_expression */ yytestcase(yyruleno==129);
- break;
+ /* (86) input ::= query */ yytestcase(yyruleno==86);
+ /* (87) input ::= expression */ yytestcase(yyruleno==87);
+ /* (88) input ::= START_OUTPUT_COLUMNS output_columns */ yytestcase(yyruleno==88);
+ /* (89) input ::= START_ADJUSTER adjuster */ yytestcase(yyruleno==89);
+ /* (90) query ::= query_element (OPTIMIZED OUT) */ assert(yyruleno!=90);
+ /* (91) query_element ::= QSTRING */ yytestcase(yyruleno==91);
+ /* (92) query_element ::= PARENL query PARENR */ yytestcase(yyruleno==92);
+ /* (93) expression ::= assignment_expression (OPTIMIZED OUT) */ assert(yyruleno!=93);
+ /* (94) assignment_expression ::= conditional_expression (OPTIMIZED OUT) */ assert(yyruleno!=94);
+ /* (95) conditional_expression ::= logical_or_expression */ yytestcase(yyruleno==95);
+ /* (96) logical_or_expression ::= logical_and_expression */ yytestcase(yyruleno==96);
+ /* (97) logical_and_expression ::= bitwise_or_expression */ yytestcase(yyruleno==97);
+ /* (98) bitwise_or_expression ::= bitwise_xor_expression */ yytestcase(yyruleno==98);
+ /* (99) bitwise_xor_expression ::= bitwise_and_expression */ yytestcase(yyruleno==99);
+ /* (100) bitwise_and_expression ::= equality_expression */ yytestcase(yyruleno==100);
+ /* (101) equality_expression ::= relational_expression */ yytestcase(yyruleno==101);
+ /* (102) relational_expression ::= shift_expression */ yytestcase(yyruleno==102);
+ /* (103) shift_expression ::= additive_expression */ yytestcase(yyruleno==103);
+ /* (104) additive_expression ::= multiplicative_expression */ yytestcase(yyruleno==104);
+ /* (105) multiplicative_expression ::= unary_expression (OPTIMIZED OUT) */ assert(yyruleno!=105);
+ /* (106) unary_expression ::= postfix_expression (OPTIMIZED OUT) */ assert(yyruleno!=106);
+ /* (107) postfix_expression ::= lefthand_side_expression */ yytestcase(yyruleno==107);
+ /* (108) lefthand_side_expression ::= call_expression (OPTIMIZED OUT) */ assert(yyruleno!=108);
+ /* (109) lefthand_side_expression ::= member_expression */ yytestcase(yyruleno==109);
+ /* (110) member_expression ::= primary_expression (OPTIMIZED OUT) */ assert(yyruleno!=110);
+ /* (111) member_expression ::= member_expression member_expression_part */ yytestcase(yyruleno==111);
+ /* (112) primary_expression ::= object_literal (OPTIMIZED OUT) */ assert(yyruleno!=112);
+ /* (113) primary_expression ::= PARENL expression PARENR */ yytestcase(yyruleno==113);
+ /* (114) primary_expression ::= IDENTIFIER */ yytestcase(yyruleno==114);
+ /* (115) primary_expression ::= array_literal (OPTIMIZED OUT) */ assert(yyruleno!=115);
+ /* (116) primary_expression ::= DECIMAL */ yytestcase(yyruleno==116);
+ /* (117) primary_expression ::= HEX_INTEGER */ yytestcase(yyruleno==117);
+ /* (118) primary_expression ::= STRING */ yytestcase(yyruleno==118);
+ /* (119) primary_expression ::= BOOLEAN */ yytestcase(yyruleno==119);
+ /* (120) primary_expression ::= NULL */ yytestcase(yyruleno==120);
+ /* (121) array_literal ::= BRACKETL elision BRACKETR */ yytestcase(yyruleno==121);
+ /* (122) array_literal ::= BRACKETL element_list elision BRACKETR */ yytestcase(yyruleno==122);
+ /* (123) array_literal ::= BRACKETL element_list BRACKETR */ yytestcase(yyruleno==123);
+ /* (124) elision ::= COMMA */ yytestcase(yyruleno==124);
+ /* (125) elision ::= elision COMMA */ yytestcase(yyruleno==125);
+ /* (126) element_list ::= assignment_expression (OPTIMIZED OUT) */ assert(yyruleno!=126);
+ /* (127) element_list ::= elision assignment_expression */ yytestcase(yyruleno==127);
+ /* (128) element_list ::= element_list elision assignment_expression */ yytestcase(yyruleno==128);
+ /* (129) property_name_and_value_list ::= property_name_and_value (OPTIMIZED OUT) */ assert(yyruleno!=129);
+ /* (130) property_name_and_value_list ::= property_name_and_value_list COMMA property_name_and_value */ yytestcase(yyruleno==130);
+ /* (131) property_name ::= STRING */ yytestcase(yyruleno==131);
+ /* (132) member_expression_part ::= DOT IDENTIFIER */ yytestcase(yyruleno==132);
+ /* (133) adjuster ::= */ yytestcase(yyruleno==133);
+ /* (134) adjuster ::= adjust_expression (OPTIMIZED OUT) */ assert(yyruleno!=134);
+ /* (135) adjust_expression ::= adjust_match_expression */ yytestcase(yyruleno==135);
+ break;
+/********** End reduce actions ************************************************/
};
+ assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
yygoto = yyRuleInfo[yyruleno].lhs;
yysize = yyRuleInfo[yyruleno].nrhs;
- yypParser->yyidx -= yysize;
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
- if( yyact < YYNSTATE ){
-#ifdef NDEBUG
- /* If we are not debugging and the reduce action popped at least
- ** one element off the stack, then we can push the new element back
- ** onto the stack here, and skip the stack overflow test in yy_shift().
- ** That gives a significant speed improvement. */
- if( yysize ){
- yypParser->yyidx++;
- yymsp -= yysize-1;
- yymsp->stateno = (YYACTIONTYPE)yyact;
- yymsp->major = (YYCODETYPE)yygoto;
- yymsp->minor = yygotominor;
- }else
-#endif
- {
- yy_shift(yypParser,yyact,yygoto,&yygotominor);
+ if( yyact <= YY_MAX_SHIFTREDUCE ){
+ if( yyact>YY_MAX_SHIFT ){
+ yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
}
+ yymsp -= yysize-1;
+ yypParser->yytos = yymsp;
+ yymsp->stateno = (YYACTIONTYPE)yyact;
+ yymsp->major = (YYCODETYPE)yygoto;
+ yyTraceShift(yypParser, yyact);
}else{
- assert( yyact == YYNSTATE + YYNRULE + 1 );
+ assert( yyact == YY_ACCEPT_ACTION );
+ yypParser->yytos -= yysize;
yy_accept(yypParser);
}
}
@@ -2033,9 +2291,11 @@ static void yy_parse_failed(
fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
}
#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
/* Here code is inserted which will be executed whenever the
** parser fails */
+/************ Begin %parse_failure code ***************************************/
+/************ End %parse_failure code *****************************************/
grn_expr_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
#endif /* YYNOERRORRECOVERY */
@@ -2046,33 +2306,39 @@ static void yy_parse_failed(
static void yy_syntax_error(
yyParser *yypParser, /* The parser */
int yymajor, /* The major type of the error token */
- YYMINORTYPE yyminor /* The minor type of the error token */
+ grn_expr_parserTOKENTYPE yyminor /* The minor type of the error token */
){
grn_expr_parserARG_FETCH;
-#define TOKEN (yyminor.yy0)
-#line 17 "grn_ecmascript.lemon"
+#define TOKEN yyminor
+/************ Begin %syntax_error code ****************************************/
+#line 20 "grn_ecmascript.lemon"
{
grn_ctx *ctx = efsi->ctx;
- if (ctx->rc == GRN_SUCCESS) {
- grn_obj message;
- GRN_TEXT_INIT(&message, 0);
- GRN_TEXT_PUT(ctx, &message, efsi->str, efsi->cur - efsi->str);
+ grn_obj message;
+ GRN_TEXT_INIT(&message, 0);
+ GRN_TEXT_PUT(ctx, &message, efsi->str, efsi->cur - efsi->str);
+ GRN_TEXT_PUTC(ctx, &message, '|');
+ if (efsi->cur < efsi->str_end) {
+ GRN_TEXT_PUTC(ctx, &message, efsi->cur[0]);
GRN_TEXT_PUTC(ctx, &message, '|');
- if (efsi->cur < efsi->str_end) {
- GRN_TEXT_PUTC(ctx, &message, efsi->cur[0]);
- GRN_TEXT_PUTC(ctx, &message, '|');
- GRN_TEXT_PUT(ctx, &message,
- efsi->cur + 1, efsi->str_end - (efsi->cur + 1));
- } else {
- GRN_TEXT_PUTC(ctx, &message, '|');
- }
+ GRN_TEXT_PUT(ctx, &message,
+ efsi->cur + 1, efsi->str_end - (efsi->cur + 1));
+ } else {
+ GRN_TEXT_PUTC(ctx, &message, '|');
+ }
+ if (ctx->rc == GRN_SUCCESS) {
ERR(GRN_SYNTAX_ERROR, "Syntax error: <%.*s>",
(int)GRN_TEXT_LEN(&message), GRN_TEXT_VALUE(&message));
- GRN_OBJ_FIN(ctx, &message);
+ } else {
+ ERR(ctx->rc, "Syntax error: <%.*s>: %s",
+ (int)GRN_TEXT_LEN(&message), GRN_TEXT_VALUE(&message),
+ ctx->errbuf);
}
+ GRN_OBJ_FIN(ctx, &message);
}
-#line 2076 "grn_ecmascript.c"
+#line 2341 "grn_ecmascript.c"
+/************ End %syntax_error code ******************************************/
grn_expr_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
@@ -2088,9 +2354,14 @@ static void yy_accept(
fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
}
#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+#ifndef YYNOERRORRECOVERY
+ yypParser->yyerrcnt = -1;
+#endif
+ assert( yypParser->yytos==yypParser->yystack );
/* Here code is inserted which will be executed whenever the
** parser accepts */
+/*********** Begin %parse_accept code *****************************************/
+/*********** End %parse_accept code *******************************************/
grn_expr_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
@@ -2120,50 +2391,41 @@ void grn_expr_parser(
grn_expr_parserARG_PDECL /* Optional %extra_argument parameter */
){
YYMINORTYPE yyminorunion;
- int yyact; /* The parser action. */
+ unsigned int yyact; /* The parser action. */
+#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
int yyendofinput; /* True if we are at the end of input */
+#endif
#ifdef YYERRORSYMBOL
int yyerrorhit = 0; /* True if yymajor has invoked an error */
#endif
yyParser *yypParser; /* The parser */
- /* (re)initialize the parser, if necessary */
yypParser = (yyParser*)yyp;
- if( yypParser->yyidx<0 ){
-#if YYSTACKDEPTH<=0
- if( yypParser->yystksz <=0 ){
- /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
- yyminorunion = yyzerominor;
- yyStackOverflow(yypParser, &yyminorunion);
- return;
- }
-#endif
- yypParser->yyidx = 0;
- yypParser->yyerrcnt = -1;
- yypParser->yystack[0].stateno = 0;
- yypParser->yystack[0].major = 0;
- }
- yyminorunion.yy0 = yyminor;
+ assert( yypParser->yytos!=0 );
+#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
yyendofinput = (yymajor==0);
+#endif
grn_expr_parserARG_STORE;
#ifndef NDEBUG
if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
+ fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]);
}
#endif
do{
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
- if( yyact<YYNSTATE ){
- assert( !yyendofinput ); /* Impossible to shift the $ token */
- yy_shift(yypParser,yyact,yymajor,&yyminorunion);
+ if( yyact <= YY_MAX_SHIFTREDUCE ){
+ yy_shift(yypParser,yyact,yymajor,yyminor);
+#ifndef YYNOERRORRECOVERY
yypParser->yyerrcnt--;
+#endif
yymajor = YYNOCODE;
- }else if( yyact < YYNSTATE + YYNRULE ){
- yy_reduce(yypParser,yyact-YYNSTATE);
+ }else if( yyact <= YY_MAX_REDUCE ){
+ yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
}else{
assert( yyact == YY_ERROR_ACTION );
+ yyminorunion.yy0 = yyminor;
#ifdef YYERRORSYMBOL
int yymx;
#endif
@@ -2193,9 +2455,9 @@ void grn_expr_parser(
**
*/
if( yypParser->yyerrcnt<0 ){
- yy_syntax_error(yypParser,yymajor,yyminorunion);
+ yy_syntax_error(yypParser,yymajor,yyminor);
}
- yymx = yypParser->yystack[yypParser->yyidx].major;
+ yymx = yypParser->yytos->major;
if( yymx==YYERRORSYMBOL || yyerrorhit ){
#ifndef NDEBUG
if( yyTraceFILE ){
@@ -2203,26 +2465,26 @@ void grn_expr_parser(
yyTracePrompt,yyTokenName[yymajor]);
}
#endif
- yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
+ yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
yymajor = YYNOCODE;
}else{
- while(
- yypParser->yyidx >= 0 &&
- yymx != YYERRORSYMBOL &&
- (yyact = yy_find_reduce_action(
- yypParser->yystack[yypParser->yyidx].stateno,
- YYERRORSYMBOL)) >= YYNSTATE
+ while( yypParser->yytos >= yypParser->yystack
+ && yymx != YYERRORSYMBOL
+ && (yyact = yy_find_reduce_action(
+ yypParser->yytos->stateno,
+ YYERRORSYMBOL)) >= YY_MIN_REDUCE
){
yy_pop_parser_stack(yypParser);
}
- if( yypParser->yyidx < 0 || yymajor==0 ){
+ if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
yy_parse_failed(yypParser);
+#ifndef YYNOERRORRECOVERY
+ yypParser->yyerrcnt = -1;
+#endif
yymajor = YYNOCODE;
}else if( yymx!=YYERRORSYMBOL ){
- YYMINORTYPE u2;
- u2.YYERRSYMDT = 0;
- yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
+ yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
}
}
yypParser->yyerrcnt = 3;
@@ -2235,7 +2497,7 @@ void grn_expr_parser(
** Applications can set this macro (for example inside %include) if
** they intend to abandon the parse upon the first syntax error seen.
*/
- yy_syntax_error(yypParser,yymajor,yyminorunion);
+ yy_syntax_error(yypParser,yymajor, yyminor);
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
yymajor = YYNOCODE;
@@ -2250,16 +2512,31 @@ void grn_expr_parser(
** three input tokens have been successfully shifted.
*/
if( yypParser->yyerrcnt<=0 ){
- yy_syntax_error(yypParser,yymajor,yyminorunion);
+ yy_syntax_error(yypParser,yymajor, yyminor);
}
yypParser->yyerrcnt = 3;
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
if( yyendofinput ){
yy_parse_failed(yypParser);
+#ifndef YYNOERRORRECOVERY
+ yypParser->yyerrcnt = -1;
+#endif
}
yymajor = YYNOCODE;
#endif
}
- }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
+ }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack );
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ yyStackEntry *i;
+ char cDiv = '[';
+ fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt);
+ for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){
+ fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]);
+ cDiv = ' ';
+ }
+ fprintf(yyTraceFILE,"]\n");
+ }
+#endif
return;
}
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.h b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.h
index 6280690482b..15272b0aac7 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.h
@@ -3,71 +3,72 @@
#define GRN_EXPR_TOKEN_LOGICAL_AND 3
#define GRN_EXPR_TOKEN_LOGICAL_AND_NOT 4
#define GRN_EXPR_TOKEN_LOGICAL_OR 5
-#define GRN_EXPR_TOKEN_QSTRING 6
-#define GRN_EXPR_TOKEN_PARENL 7
-#define GRN_EXPR_TOKEN_PARENR 8
-#define GRN_EXPR_TOKEN_RELATIVE_OP 9
-#define GRN_EXPR_TOKEN_IDENTIFIER 10
-#define GRN_EXPR_TOKEN_BRACEL 11
-#define GRN_EXPR_TOKEN_BRACER 12
-#define GRN_EXPR_TOKEN_EVAL 13
-#define GRN_EXPR_TOKEN_COMMA 14
-#define GRN_EXPR_TOKEN_ASSIGN 15
-#define GRN_EXPR_TOKEN_STAR_ASSIGN 16
-#define GRN_EXPR_TOKEN_SLASH_ASSIGN 17
-#define GRN_EXPR_TOKEN_MOD_ASSIGN 18
-#define GRN_EXPR_TOKEN_PLUS_ASSIGN 19
-#define GRN_EXPR_TOKEN_MINUS_ASSIGN 20
-#define GRN_EXPR_TOKEN_SHIFTL_ASSIGN 21
-#define GRN_EXPR_TOKEN_SHIFTR_ASSIGN 22
-#define GRN_EXPR_TOKEN_SHIFTRR_ASSIGN 23
-#define GRN_EXPR_TOKEN_AND_ASSIGN 24
-#define GRN_EXPR_TOKEN_XOR_ASSIGN 25
-#define GRN_EXPR_TOKEN_OR_ASSIGN 26
-#define GRN_EXPR_TOKEN_QUESTION 27
-#define GRN_EXPR_TOKEN_COLON 28
-#define GRN_EXPR_TOKEN_BITWISE_OR 29
-#define GRN_EXPR_TOKEN_BITWISE_XOR 30
-#define GRN_EXPR_TOKEN_BITWISE_AND 31
-#define GRN_EXPR_TOKEN_EQUAL 32
-#define GRN_EXPR_TOKEN_NOT_EQUAL 33
-#define GRN_EXPR_TOKEN_LESS 34
-#define GRN_EXPR_TOKEN_GREATER 35
-#define GRN_EXPR_TOKEN_LESS_EQUAL 36
-#define GRN_EXPR_TOKEN_GREATER_EQUAL 37
-#define GRN_EXPR_TOKEN_IN 38
-#define GRN_EXPR_TOKEN_MATCH 39
-#define GRN_EXPR_TOKEN_NEAR 40
-#define GRN_EXPR_TOKEN_NEAR2 41
-#define GRN_EXPR_TOKEN_SIMILAR 42
-#define GRN_EXPR_TOKEN_TERM_EXTRACT 43
-#define GRN_EXPR_TOKEN_LCP 44
-#define GRN_EXPR_TOKEN_PREFIX 45
-#define GRN_EXPR_TOKEN_SUFFIX 46
-#define GRN_EXPR_TOKEN_REGEXP 47
-#define GRN_EXPR_TOKEN_SHIFTL 48
-#define GRN_EXPR_TOKEN_SHIFTR 49
-#define GRN_EXPR_TOKEN_SHIFTRR 50
-#define GRN_EXPR_TOKEN_PLUS 51
-#define GRN_EXPR_TOKEN_MINUS 52
-#define GRN_EXPR_TOKEN_STAR 53
-#define GRN_EXPR_TOKEN_SLASH 54
-#define GRN_EXPR_TOKEN_MOD 55
-#define GRN_EXPR_TOKEN_DELETE 56
-#define GRN_EXPR_TOKEN_INCR 57
-#define GRN_EXPR_TOKEN_DECR 58
-#define GRN_EXPR_TOKEN_NOT 59
-#define GRN_EXPR_TOKEN_BITWISE_NOT 60
-#define GRN_EXPR_TOKEN_ADJUST 61
-#define GRN_EXPR_TOKEN_EXACT 62
-#define GRN_EXPR_TOKEN_PARTIAL 63
-#define GRN_EXPR_TOKEN_UNSPLIT 64
-#define GRN_EXPR_TOKEN_DECIMAL 65
-#define GRN_EXPR_TOKEN_HEX_INTEGER 66
-#define GRN_EXPR_TOKEN_STRING 67
-#define GRN_EXPR_TOKEN_BOOLEAN 68
-#define GRN_EXPR_TOKEN_NULL 69
-#define GRN_EXPR_TOKEN_BRACKETL 70
-#define GRN_EXPR_TOKEN_BRACKETR 71
-#define GRN_EXPR_TOKEN_DOT 72
-#define GRN_EXPR_TOKEN_NONEXISTENT_COLUMN 73
+#define GRN_EXPR_TOKEN_NEGATIVE 6
+#define GRN_EXPR_TOKEN_QSTRING 7
+#define GRN_EXPR_TOKEN_PARENL 8
+#define GRN_EXPR_TOKEN_PARENR 9
+#define GRN_EXPR_TOKEN_ADJUST 10
+#define GRN_EXPR_TOKEN_RELATIVE_OP 11
+#define GRN_EXPR_TOKEN_IDENTIFIER 12
+#define GRN_EXPR_TOKEN_BRACEL 13
+#define GRN_EXPR_TOKEN_BRACER 14
+#define GRN_EXPR_TOKEN_EVAL 15
+#define GRN_EXPR_TOKEN_COMMA 16
+#define GRN_EXPR_TOKEN_ASSIGN 17
+#define GRN_EXPR_TOKEN_STAR_ASSIGN 18
+#define GRN_EXPR_TOKEN_SLASH_ASSIGN 19
+#define GRN_EXPR_TOKEN_MOD_ASSIGN 20
+#define GRN_EXPR_TOKEN_PLUS_ASSIGN 21
+#define GRN_EXPR_TOKEN_MINUS_ASSIGN 22
+#define GRN_EXPR_TOKEN_SHIFTL_ASSIGN 23
+#define GRN_EXPR_TOKEN_SHIFTR_ASSIGN 24
+#define GRN_EXPR_TOKEN_SHIFTRR_ASSIGN 25
+#define GRN_EXPR_TOKEN_AND_ASSIGN 26
+#define GRN_EXPR_TOKEN_XOR_ASSIGN 27
+#define GRN_EXPR_TOKEN_OR_ASSIGN 28
+#define GRN_EXPR_TOKEN_QUESTION 29
+#define GRN_EXPR_TOKEN_COLON 30
+#define GRN_EXPR_TOKEN_BITWISE_OR 31
+#define GRN_EXPR_TOKEN_BITWISE_XOR 32
+#define GRN_EXPR_TOKEN_BITWISE_AND 33
+#define GRN_EXPR_TOKEN_EQUAL 34
+#define GRN_EXPR_TOKEN_NOT_EQUAL 35
+#define GRN_EXPR_TOKEN_LESS 36
+#define GRN_EXPR_TOKEN_GREATER 37
+#define GRN_EXPR_TOKEN_LESS_EQUAL 38
+#define GRN_EXPR_TOKEN_GREATER_EQUAL 39
+#define GRN_EXPR_TOKEN_IN 40
+#define GRN_EXPR_TOKEN_MATCH 41
+#define GRN_EXPR_TOKEN_NEAR 42
+#define GRN_EXPR_TOKEN_NEAR2 43
+#define GRN_EXPR_TOKEN_SIMILAR 44
+#define GRN_EXPR_TOKEN_TERM_EXTRACT 45
+#define GRN_EXPR_TOKEN_LCP 46
+#define GRN_EXPR_TOKEN_PREFIX 47
+#define GRN_EXPR_TOKEN_SUFFIX 48
+#define GRN_EXPR_TOKEN_REGEXP 49
+#define GRN_EXPR_TOKEN_SHIFTL 50
+#define GRN_EXPR_TOKEN_SHIFTR 51
+#define GRN_EXPR_TOKEN_SHIFTRR 52
+#define GRN_EXPR_TOKEN_PLUS 53
+#define GRN_EXPR_TOKEN_MINUS 54
+#define GRN_EXPR_TOKEN_STAR 55
+#define GRN_EXPR_TOKEN_SLASH 56
+#define GRN_EXPR_TOKEN_MOD 57
+#define GRN_EXPR_TOKEN_DELETE 58
+#define GRN_EXPR_TOKEN_INCR 59
+#define GRN_EXPR_TOKEN_DECR 60
+#define GRN_EXPR_TOKEN_NOT 61
+#define GRN_EXPR_TOKEN_BITWISE_NOT 62
+#define GRN_EXPR_TOKEN_EXACT 63
+#define GRN_EXPR_TOKEN_PARTIAL 64
+#define GRN_EXPR_TOKEN_UNSPLIT 65
+#define GRN_EXPR_TOKEN_DECIMAL 66
+#define GRN_EXPR_TOKEN_HEX_INTEGER 67
+#define GRN_EXPR_TOKEN_STRING 68
+#define GRN_EXPR_TOKEN_BOOLEAN 69
+#define GRN_EXPR_TOKEN_NULL 70
+#define GRN_EXPR_TOKEN_BRACKETL 71
+#define GRN_EXPR_TOKEN_BRACKETR 72
+#define GRN_EXPR_TOKEN_DOT 73
+#define GRN_EXPR_TOKEN_NONEXISTENT_COLUMN 74
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon
index 1d812655d70..234ea41c007 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon
+++ b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon
@@ -2,6 +2,9 @@
%name grn_expr_parser
%token_prefix GRN_EXPR_TOKEN_
%include {
+#ifdef assert
+# undef assert
+#endif
#define assert GRN_ASSERT
}
@@ -17,23 +20,27 @@
%syntax_error {
{
grn_ctx *ctx = efsi->ctx;
- if (ctx->rc == GRN_SUCCESS) {
- grn_obj message;
- GRN_TEXT_INIT(&message, 0);
- GRN_TEXT_PUT(ctx, &message, efsi->str, efsi->cur - efsi->str);
+ grn_obj message;
+ GRN_TEXT_INIT(&message, 0);
+ GRN_TEXT_PUT(ctx, &message, efsi->str, efsi->cur - efsi->str);
+ GRN_TEXT_PUTC(ctx, &message, '|');
+ if (efsi->cur < efsi->str_end) {
+ GRN_TEXT_PUTC(ctx, &message, efsi->cur[0]);
GRN_TEXT_PUTC(ctx, &message, '|');
- if (efsi->cur < efsi->str_end) {
- GRN_TEXT_PUTC(ctx, &message, efsi->cur[0]);
- GRN_TEXT_PUTC(ctx, &message, '|');
- GRN_TEXT_PUT(ctx, &message,
- efsi->cur + 1, efsi->str_end - (efsi->cur + 1));
- } else {
- GRN_TEXT_PUTC(ctx, &message, '|');
- }
+ GRN_TEXT_PUT(ctx, &message,
+ efsi->cur + 1, efsi->str_end - (efsi->cur + 1));
+ } else {
+ GRN_TEXT_PUTC(ctx, &message, '|');
+ }
+ if (ctx->rc == GRN_SUCCESS) {
ERR(GRN_SYNTAX_ERROR, "Syntax error: <%.*s>",
(int)GRN_TEXT_LEN(&message), GRN_TEXT_VALUE(&message));
- GRN_OBJ_FIN(ctx, &message);
+ } else {
+ ERR(ctx->rc, "Syntax error: <%.*s>: %s",
+ (int)GRN_TEXT_LEN(&message), GRN_TEXT_VALUE(&message),
+ ctx->errbuf);
}
+ GRN_OBJ_FIN(ctx, &message);
}
}
@@ -55,10 +62,19 @@ query ::= query LOGICAL_AND_NOT query_element.{
query ::= query LOGICAL_OR query_element.{
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR, 2);
}
+query ::= query NEGATIVE query_element.{
+ int weight;
+ GRN_INT32_POP(&efsi->weight_stack, weight);
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ADJUST, 2);
+}
query_element ::= QSTRING.
query_element ::= PARENL query PARENR.
+query_element ::= ADJUST query_element.{
+ int weight;
+ GRN_INT32_POP(&efsi->weight_stack, weight);
+}
query_element ::= RELATIVE_OP query_element.{
int mode;
GRN_INT32_POP(&efsi->mode_stack, mode);
@@ -199,7 +215,13 @@ relational_expression ::= relational_expression MATCH shift_expression. {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MATCH, 2);
}
relational_expression ::= relational_expression NEAR shift_expression. {
- grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR, 2);
+ {
+ int max_interval;
+ GRN_INT32_POP(&efsi->max_interval_stack, max_interval);
+ grn_expr_append_const_int(efsi->ctx, efsi->e, max_interval,
+ GRN_OP_PUSH, 1);
+ }
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR, 3);
}
relational_expression ::= relational_expression NEAR2 shift_expression. {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR2, 2);
@@ -263,12 +285,12 @@ unary_expression ::= INCR unary_expression. {
grn_expr_dfi *dfi_;
unsigned int const_p;
- DFI_POP(e, dfi_);
+ dfi_ = grn_expr_dfi_pop(e);
const_p = CONSTP(dfi_->code->value);
- DFI_PUT(e, dfi_->type, dfi_->domain, dfi_->code);
+ grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code);
if (const_p) {
ERR(GRN_SYNTAX_ERROR,
- "constant can't be incremented (%.*s)",
+ "constant can't be incremented: <%.*s>",
(int)(efsi->str_end - efsi->str), efsi->str);
} else {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR, 1);
@@ -280,12 +302,12 @@ unary_expression ::= DECR unary_expression. {
grn_expr_dfi *dfi_;
unsigned int const_p;
- DFI_POP(e, dfi_);
+ dfi_ = grn_expr_dfi_pop(e);
const_p = CONSTP(dfi_->code->value);
- DFI_PUT(e, dfi_->type, dfi_->domain, dfi_->code);
+ grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code);
if (const_p) {
ERR(GRN_SYNTAX_ERROR,
- "constant can't be decremented (%.*s)",
+ "constant can't be decremented: <%.*s>",
(int)(efsi->str_end - efsi->str), efsi->str);
} else {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR, 1);
@@ -323,12 +345,12 @@ postfix_expression ::= lefthand_side_expression INCR. {
grn_expr_dfi *dfi_;
unsigned int const_p;
- DFI_POP(e, dfi_);
+ dfi_ = grn_expr_dfi_pop(e);
const_p = CONSTP(dfi_->code->value);
- DFI_PUT(e, dfi_->type, dfi_->domain, dfi_->code);
+ grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code);
if (const_p) {
ERR(GRN_SYNTAX_ERROR,
- "constant can't be incremented (%.*s)",
+ "constant can't be incremented: <%.*s>",
(int)(efsi->str_end - efsi->str), efsi->str);
} else {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR_POST, 1);
@@ -340,12 +362,12 @@ postfix_expression ::= lefthand_side_expression DECR. {
grn_expr_dfi *dfi_;
unsigned int const_p;
- DFI_POP(e, dfi_);
+ dfi_ = grn_expr_dfi_pop(e);
const_p = CONSTP(dfi_->code->value);
- DFI_PUT(e, dfi_->type, dfi_->domain, dfi_->code);
+ grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code);
if (const_p) {
ERR(GRN_SYNTAX_ERROR,
- "constant can't be decremented (%.*s)",
+ "constant can't be decremented: <%.*s>",
(int)(efsi->str_end - efsi->str), efsi->str);
} else {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR_POST, 1);
@@ -383,13 +405,72 @@ element_list ::= assignment_expression.
element_list ::= elision assignment_expression.
element_list ::= element_list elision assignment_expression.
-object_literal ::= BRACEL property_name_and_value_list BRACER.
+object_literal ::= BRACEL property_name_and_value_list BRACER. {
+ grn_ctx *ctx = efsi->ctx;
+ grn_expr_take_obj(ctx, efsi->e, (grn_obj *)(efsi->object_literal));
+ grn_expr_append_obj(ctx, efsi->e, (grn_obj *)(efsi->object_literal),
+ GRN_OP_PUSH, 1);
+ efsi->object_literal = NULL;
+}
+
+property_name_and_value_list ::= . {
+ grn_ctx *ctx = efsi->ctx;
-property_name_and_value_list ::= .
+ efsi->object_literal =
+ grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE, sizeof(grn_obj),
+ GRN_OBJ_KEY_VAR_SIZE|GRN_OBJ_TEMPORARY|GRN_HASH_TINY);
+ if (!efsi->object_literal) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "couldn't create hash table for parsing object literal: <%.*s>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ }
+}
+property_name_and_value_list ::= property_name_and_value.
property_name_and_value_list ::= property_name_and_value_list COMMA property_name_and_value.
-property_name_and_value ::= property_name COLON assignment_expression.
-property_name ::= IDENTIFIER|STRING|DECIMAL.
+property_name_and_value ::= property_name COLON assignment_expression. {
+ grn_ctx *ctx = efsi->ctx;
+ grn_expr *e = (grn_expr *)(efsi->e);
+ grn_obj *property = e->codes[e->codes_curr - 3].value;
+ grn_obj *value = e->codes[e->codes_curr - 1].value;
+
+ if (!efsi->object_literal) {
+ efsi->object_literal =
+ grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE, sizeof(grn_obj),
+ GRN_OBJ_KEY_VAR_SIZE|GRN_OBJ_TEMPORARY|GRN_HASH_TINY);
+ }
+
+ if (!efsi->object_literal) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "couldn't create hash table for parsing object literal: <%.*s>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ } else {
+ grn_obj *buf;
+ int added;
+ if (grn_hash_add(ctx, (grn_hash *)efsi->object_literal,
+ GRN_TEXT_VALUE(property), GRN_TEXT_LEN(property),
+ (void **)&buf, &added)) {
+ if (added) {
+ GRN_OBJ_INIT(buf, value->header.type, 0, value->header.domain);
+ GRN_TEXT_PUT(ctx, buf, GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
+ grn_expr_dfi_pop(e);
+ e->codes_curr -= 3;
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "duplicated property name: <%.*s>",
+ (int)GRN_TEXT_LEN(property),
+ GRN_TEXT_VALUE(property));
+ }
+ } else {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to add a property to object literal: <%.*s>",
+ (int)GRN_TEXT_LEN(property),
+ GRN_TEXT_VALUE(property));
+ }
+ }
+}
+
+property_name ::= STRING.
member_expression_part ::= BRACKETL expression BRACKETR. {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GET_MEMBER, 2);
@@ -404,67 +485,84 @@ argument_list(A) ::= argument_list(B) COMMA assignment_expression. { A = B + 1;
output_columns(N_STACKED_COLUMNS) ::= . {
N_STACKED_COLUMNS = 0;
}
-output_columns(N_STACKED_COLUMNS) ::= output_column(IGNORED). {
- if (IGNORED) {
- N_STACKED_COLUMNS = 0;
- } else {
- N_STACKED_COLUMNS = 1;
- }
+output_columns(N_STACKED_COLUMNS) ::= output_column(SUB_N_STACKED_COLUMNS). {
+ N_STACKED_COLUMNS = SUB_N_STACKED_COLUMNS;
}
+/* Accept "column1,,,,,,column2" */
output_columns(N_STACKED_COLUMNS) ::=
- output_columns(SUB_N_STACKED_COLUMNS) COMMA output_column(IGNORED). {
- if (IGNORED) {
+ output_columns(SUB_N_STACKED_COLUMNS) COMMA. {
+ N_STACKED_COLUMNS = SUB_N_STACKED_COLUMNS;
+}
+output_columns(N_STACKED_COLUMNS) ::=
+ output_columns(SUB_N_STACKED_COLUMNS) COMMA
+ output_column(NEW_N_STACKED_COLUMNS). {
+ if (SUB_N_STACKED_COLUMNS == 0) {
+ N_STACKED_COLUMNS = NEW_N_STACKED_COLUMNS;
+ } else if (NEW_N_STACKED_COLUMNS == 0) {
N_STACKED_COLUMNS = SUB_N_STACKED_COLUMNS;
} else {
- if (SUB_N_STACKED_COLUMNS == 1) {
+ if (NEW_N_STACKED_COLUMNS == 1) {
grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_COMMA, 2);
}
N_STACKED_COLUMNS = 1;
}
}
-output_column(IGNORED) ::= STAR. {
+output_column(N_STACKED_COLUMNS) ::= STAR. {
grn_ctx *ctx = efsi->ctx;
grn_obj *expr = efsi->e;
- grn_expr *e = (grn_expr *)expr;
grn_obj *variable = grn_expr_get_var_by_offset(ctx, expr, 0);
if (variable) {
grn_id table_id = GRN_OBJ_GET_DOMAIN(variable);
grn_obj *table = grn_ctx_at(ctx, table_id);
grn_obj columns_buffer;
+ int n_columns;
grn_obj **columns;
- int i, n_columns;
GRN_PTR_INIT(&columns_buffer, GRN_OBJ_VECTOR, GRN_ID_NIL);
grn_obj_columns(ctx, table, "*", strlen("*"), &columns_buffer);
n_columns = GRN_BULK_VSIZE(&columns_buffer) / sizeof(grn_obj *);
columns = (grn_obj **)GRN_BULK_HEAD(&columns_buffer);
- for (i = 0; i < n_columns; i++) {
- if (i > 0) {
- grn_expr_append_op(ctx, expr, GRN_OP_COMMA, 2);
+ if (n_columns == 0) {
+ /* do nothing */
+ } else if (n_columns == 1) {
+ grn_obj *column = columns[0];
+ grn_expr_append_const(ctx, expr, column, GRN_OP_GET_VALUE, 1);
+ if (column->header.type == GRN_ACCESSOR) {
+ grn_expr_take_obj(ctx, expr, column);
+ }
+ } else {
+ grn_expr *e = (grn_expr *)expr;
+ grn_bool have_column;
+ int i;
+
+ have_column = (e->codes_curr > 0);
+ for (i = 0; i < n_columns; i++) {
+ grn_obj *column = columns[i];
+ grn_expr_append_const(ctx, expr, column, GRN_OP_GET_VALUE, 1);
+ if (have_column || i > 0) {
+ grn_expr_append_op(ctx, expr, GRN_OP_COMMA, 2);
+ }
+ if (column->header.type == GRN_ACCESSOR) {
+ grn_expr_take_obj(ctx, expr, column);
+ }
}
- grn_expr_append_const(ctx, expr, columns[i], GRN_OP_GET_VALUE, 1);
- GRN_PTR_PUT(ctx, &e->objs, columns[i]);
}
GRN_OBJ_FIN(ctx, &columns_buffer);
- if (n_columns > 0) {
- IGNORED = GRN_FALSE;
- } else {
- IGNORED = GRN_TRUE;
- }
+ N_STACKED_COLUMNS = n_columns;
} else {
/* TODO: report error */
- IGNORED = GRN_TRUE;
+ N_STACKED_COLUMNS = 0;
}
}
-output_column(IGNORED) ::= NONEXISTENT_COLUMN. {
- IGNORED = GRN_TRUE;
+output_column(N_STACKED_COLUMNS) ::= NONEXISTENT_COLUMN. {
+ N_STACKED_COLUMNS = 0;
}
-output_column(IGNORED) ::= assignment_expression. {
- IGNORED = GRN_FALSE;
+output_column(N_STACKED_COLUMNS) ::= assignment_expression. {
+ N_STACKED_COLUMNS = 1;
}
adjuster ::= .
diff --git a/storage/mroonga/vendor/groonga/lib/grn_egn.h b/storage/mroonga/vendor/groonga/lib/grn_egn.h
deleted file mode 100644
index 3d1d54ca9aa..00000000000
--- a/storage/mroonga/vendor/groonga/lib/grn_egn.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- c-basic-offset: 2 -*- */
-/*
- Copyright(C) 2015 Brazil
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License version 2.1 as published by the Free Software Foundation.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef GRN_EGN_H
-#define GRN_EGN_H
-
-#include "grn.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Constant values.
-
-typedef grn_operator grn_egn_operator_type;
-typedef grn_builtin_type grn_egn_data_type;
-
-typedef enum {
- GRN_EGN_ID_NODE,
- GRN_EGN_SCORE_NODE,
- GRN_EGN_CONSTANT_NODE,
- GRN_EGN_COLUMN_NODE,
- GRN_EGN_OPERATOR_NODE
-} grn_egn_expression_node_type;
-
-typedef enum {
- GRN_EGN_INCOMPLETE,
- GRN_EGN_ID,
- GRN_EGN_SCORE,
- GRN_EGN_CONSTANT,
- GRN_EGN_VARIABLE
-} grn_egn_expression_type;
-
-// Built-in data types.
-
-typedef grn_id grn_egn_id;
-typedef float grn_egn_score;
-typedef struct {
- grn_egn_id id;
- grn_egn_score score;
-} grn_egn_record;
-
-typedef grn_bool grn_egn_bool;
-typedef int64_t grn_egn_int;
-typedef double grn_egn_float;
-typedef int64_t grn_egn_time;
-typedef struct {
- const char *ptr;
- size_t size;
-} grn_egn_text;
-typedef grn_geo_point grn_egn_geo_point;
-
-/*
- * grn_egn_select() finds records passing through a filter (specified by
- * `filter' and `filter_size') and writes the associated values (specified by
- * `output_columns' and `output_columns_size') into the output buffer of `ctx'
- * (`ctx->impl->outbuf').
- *
- * Note that the first `offset` records will be discarded and at most `limit`
- * records will be output.
- *
- * On success, grn_egn_select() returns GRN_SUCCESS.
- * On failure, grn_egn_select() returns an error code and set the details into
- * `ctx`.
- */
-grn_rc grn_egn_select(grn_ctx *ctx, grn_obj *table,
- const char *filter, size_t filter_size,
- const char *output_columns, size_t output_columns_size,
- int offset, int limit);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRN_EGN_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_egn.hpp b/storage/mroonga/vendor/groonga/lib/grn_egn.hpp
deleted file mode 100644
index 46511afd6ca..00000000000
--- a/storage/mroonga/vendor/groonga/lib/grn_egn.hpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/* -*- c-basic-offset: 2 -*- */
-/*
- Copyright(C) 2015 Brazil
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License version 2.1 as published by the Free Software Foundation.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef GRN_EGN_HPP
-#define GRN_EGN_HPP
-
-#include <cstring>
-#include <vector>
-
-#include "grn_egn.h"
-
-namespace grn {
-namespace egn {
-
-// Constant values.
-
-typedef grn_egn_operator_type OperatorType;
-typedef grn_egn_data_type DataType;
-
-typedef grn_egn_expression_node_type ExpressionNodeType;
-typedef grn_egn_expression_type ExpressionType;
-
-// Built-in data types.
-
-typedef grn_egn_id ID;
-typedef grn_egn_score Score;
-typedef grn_egn_record Record;
-
-//typedef grn_egn_bool Bool;
-//typedef grn_egn_int Int;
-//typedef grn_egn_float Float;
-//typedef grn_egn_time Time;
-//typedef grn_egn_text Text;
-//typedef grn_egn_geo_point GeoPoint;
-
-//inline bool operator==(const Text &lhs, const Text &rhs) {
-// if (lhs.size != rhs.size) {
-// return false;
-// }
-// return std::memcmp(lhs.ptr, rhs.ptr, lhs.size) == 0;
-//}
-//inline bool operator!=(const Text &lhs, const Text &rhs) {
-// if (lhs.size != rhs.size) {
-// return true;
-// }
-// return std::memcmp(lhs.ptr, rhs.ptr, lhs.size) != 0;
-//}
-//inline bool operator<(const Text &lhs, const Text &rhs) {
-// size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
-// int result = std::memcmp(lhs.ptr, rhs.ptr, min_size);
-// if (result == 0) {
-// return lhs.size < rhs.size;
-// }
-// return result < 0;
-//}
-//inline bool operator<=(const Text &lhs, const Text &rhs) {
-// size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
-// int result = std::memcmp(lhs.ptr, rhs.ptr, min_size);
-// if (result == 0) {
-// return lhs.size <= rhs.size;
-// }
-// return result <= 0;
-//}
-//inline bool operator>(const Text &lhs, const Text &rhs) {
-// return rhs < lhs;
-//}
-//inline bool operator>=(const Text &lhs, const Text &rhs) {
-// return rhs <= lhs;
-//}
-
-//inline bool operator==(const GeoPoint &lhs, const GeoPoint &rhs) {
-// return (lhs.latitude == rhs.latitude) && (lhs.longitude == rhs.longitude);
-//}
-//inline bool operator!=(const GeoPoint &lhs, const GeoPoint &rhs) {
-// return (lhs.latitude != rhs.latitude) || (lhs.longitude != rhs.longitude);
-//}
-
-struct Bool {
- typedef grn_egn_bool Raw;
- Raw raw;
-
- static DataType data_type() {
- return GRN_DB_BOOL;
- }
-
- Bool() : raw() {}
- Bool(const Bool &value) : raw(value.raw) {}
- explicit Bool(Raw value) : raw(value) {}
- ~Bool() {}
-};
-
-inline bool operator!(Bool value) { return !value.raw; }
-inline bool operator==(Bool lhs, Bool rhs) { return lhs.raw == rhs.raw; }
-inline bool operator!=(Bool lhs, Bool rhs) { return lhs.raw != rhs.raw; }
-
-struct Int {
- typedef grn_egn_int Raw;
- Raw raw;
-
- static DataType data_type() {
- return GRN_DB_INT64;
- }
-
- Int() : raw() {}
- Int(const Int &value) : raw(value.raw) {}
- explicit Int(Raw value) : raw(value) {}
- ~Int() {}
-};
-
-inline bool operator==(Int lhs, Int rhs) { return lhs.raw == rhs.raw; }
-inline bool operator!=(Int lhs, Int rhs) { return lhs.raw != rhs.raw; }
-inline bool operator<(Int lhs, Int rhs) { return lhs.raw < rhs.raw; }
-inline bool operator<=(Int lhs, Int rhs) { return lhs.raw <= rhs.raw; }
-inline bool operator>(Int lhs, Int rhs) { return lhs.raw > rhs.raw; }
-inline bool operator>=(Int lhs, Int rhs) { return lhs.raw >= rhs.raw; }
-
-struct Float {
- typedef grn_egn_float Raw;
- Raw raw;
-
- static DataType data_type() {
- return GRN_DB_FLOAT;
- }
-
- Float() : raw() {}
- Float(const Float &value) : raw(value.raw) {}
- explicit Float(Raw value) : raw(value) {}
- ~Float() {}
-};
-
-inline bool operator==(Float lhs, Float rhs) { return lhs.raw == rhs.raw; }
-inline bool operator!=(Float lhs, Float rhs) { return lhs.raw != rhs.raw; }
-inline bool operator<(Float lhs, Float rhs) { return lhs.raw < rhs.raw; }
-inline bool operator<=(Float lhs, Float rhs) { return lhs.raw <= rhs.raw; }
-inline bool operator>(Float lhs, Float rhs) { return lhs.raw > rhs.raw; }
-inline bool operator>=(Float lhs, Float rhs) { return lhs.raw >= rhs.raw; }
-
-struct Time {
- typedef grn_egn_time Raw;
- Raw raw;
-
- static DataType data_type() {
- return GRN_DB_TIME;
- }
-
- Time() : raw() {}
- Time(const Time &value) : raw(value.raw) {}
- explicit Time(Raw value) : raw(value) {}
- ~Time() {}
-};
-
-inline bool operator==(Time lhs, Time rhs) { return lhs.raw == rhs.raw; }
-inline bool operator!=(Time lhs, Time rhs) { return lhs.raw != rhs.raw; }
-inline bool operator<(Time lhs, Time rhs) { return lhs.raw < rhs.raw; }
-inline bool operator<=(Time lhs, Time rhs) { return lhs.raw <= rhs.raw; }
-inline bool operator>(Time lhs, Time rhs) { return lhs.raw > rhs.raw; }
-inline bool operator>=(Time lhs, Time rhs) { return lhs.raw >= rhs.raw; }
-
-struct Text {
- typedef grn_egn_text Raw;
- Raw raw;
-
- static DataType data_type() {
- return GRN_DB_TEXT;
- }
-
- Text() : raw() {}
- Text(const Text &value) : raw(value.raw) {}
- explicit Text(const Raw &value) : raw(value) {}
- Text(const char *ptr, size_t size) : raw((Raw){ptr, size}) {}
- ~Text() {}
-};
-
-inline bool operator==(const Text &lhs, const Text &rhs) {
- if (lhs.raw.size != rhs.raw.size) {
- return false;
- }
- return std::memcmp(lhs.raw.ptr, rhs.raw.ptr, lhs.raw.size) == 0;
-}
-inline bool operator!=(const Text &lhs, const Text &rhs) {
- if (lhs.raw.size != rhs.raw.size) {
- return true;
- }
- return std::memcmp(lhs.raw.ptr, rhs.raw.ptr, lhs.raw.size) != 0;
-}
-inline bool operator<(const Text &lhs, const Text &rhs) {
- size_t min_size = (lhs.raw.size < rhs.raw.size) ?
- lhs.raw.size : rhs.raw.size;
- int result = std::memcmp(lhs.raw.ptr, rhs.raw.ptr, min_size);
- if (result == 0) {
- return lhs.raw.size < rhs.raw.size;
- }
- return result < 0;
-}
-inline bool operator<=(const Text &lhs, const Text &rhs) {
- size_t min_size = (lhs.raw.size < rhs.raw.size) ?
- lhs.raw.size : rhs.raw.size;
- int result = std::memcmp(lhs.raw.ptr, rhs.raw.ptr, min_size);
- if (result == 0) {
- return lhs.raw.size <= rhs.raw.size;
- }
- return result <= 0;
-}
-inline bool operator>(const Text &lhs, const Text &rhs) { return rhs < lhs; }
-inline bool operator>=(const Text &lhs, const Text &rhs) { return rhs <= lhs; }
-
-struct GeoPoint {
- typedef grn_egn_geo_point Raw;
- Raw raw;
-
- static DataType data_type() {
- return GRN_DB_WGS84_GEO_POINT;
- }
-
- GeoPoint() : raw() {}
- GeoPoint(const GeoPoint &value) : raw(value.raw) {}
- explicit GeoPoint(Raw value) : raw(value) {}
- GeoPoint(int latitude, int longitude) : raw((Raw){ latitude, longitude }) {}
- ~GeoPoint() {}
-};
-
-inline bool operator==(GeoPoint lhs, GeoPoint rhs) {
- return (lhs.raw.latitude == rhs.raw.latitude) &&
- (lhs.raw.longitude == rhs.raw.longitude);
-}
-inline bool operator!=(GeoPoint lhs, GeoPoint rhs) {
- return (lhs.raw.latitude != rhs.raw.latitude) ||
- (lhs.raw.longitude != rhs.raw.longitude);
-}
-
-// Cursor is a base class which provides an interface for sequential access to
-// records.
-class Cursor {
- public:
- Cursor() {}
- virtual ~Cursor() {}
-
- // FIXME: Give me options.
- static grn_rc open_table_cursor(grn_ctx *ctx, grn_obj *table,
- Cursor **cursor);
-
- virtual grn_rc read(Record *records, size_t size, size_t *count);
-};
-
-// ExpressionNode is an element of Expression.
-class ExpressionNode;
-
-// Expression is a class which represents an expression.
-class Expression {
- public:
- Expression(grn_ctx *ctx, grn_obj *table);
- ~Expression();
-
- static grn_rc open(grn_ctx *ctx, grn_obj *table, Expression **expression);
- static grn_rc parse(grn_ctx *ctx, grn_obj *table,
- const char *query, size_t query_size,
- Expression **expression);
-
- ExpressionType type() const {
- return type_;
- }
- DataType data_type() const {
- return data_type_;
- }
-
- grn_rc push_object(grn_obj *obj);
- grn_rc push_operator(grn_operator operator_type);
-
- grn_rc filter(Record *input, size_t input_size,
- Record *output, size_t *output_size);
- grn_rc adjust(Record *records, size_t num_records);
-
- template <typename T>
- grn_rc evaluate(const Record *records, size_t num_records, T *results);
-
- private:
- grn_ctx *ctx_;
- grn_obj *table_;
- ExpressionType type_;
- DataType data_type_;
- std::vector<ExpressionNode *> stack_;
-
- // Disable copy and assignment.
- Expression(const Expression &);
- Expression &operator=(const Expression &);
-
- ExpressionNode *root() const;
-
- void update_types();
-
- grn_rc push_bulk_object(grn_obj *obj);
- grn_rc push_column_object(grn_obj *obj);
-
- grn_rc create_unary_node(OperatorType operator_type,
- ExpressionNode *arg, ExpressionNode **node);
- grn_rc create_binary_node(OperatorType operator_type,
- ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node);
-};
-
-} // namespace egn
-} // namespace grn
-
-#endif // GRN_EGN_HPP
diff --git a/storage/mroonga/vendor/groonga/lib/grn_error.h b/storage/mroonga/vendor/groonga/lib/grn_error.h
index a0b18ca7183..897ae50070e 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_error.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_error.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,12 +15,10 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_ERROR_H
-#define GRN_ERROR_H
-#ifndef GRN_H
+#pragma once
+
#include "grn.h"
-#endif /* GRN_H */
#ifdef __cplusplus
extern "C" {
@@ -29,8 +27,8 @@ extern "C" {
GRN_API const char *grn_current_error_message(void);
GRN_API const char *grn_strerror(int error_code);
+GRN_API grn_rc grn_windows_error_code_to_rc(int error_code);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_ERROR_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_expr.h b/storage/mroonga/vendor/groonga/lib/grn_expr.h
index 75871491d7c..c20821f995f 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_expr.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_expr.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2015 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_EXPR_H
-#define GRN_EXPR_H
+#pragma once
#include "grn_db.h"
@@ -41,6 +40,11 @@ typedef enum {
typedef struct _grn_scan_info scan_info;
typedef grn_bool (*grn_scan_info_each_arg_callback)(grn_ctx *ctx, grn_obj *obj, void *user_data);
+void grn_expr_init_from_env(void);
+
+scan_info **grn_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
+ grn_operator op, grn_bool record_exist);
+
scan_info *grn_scan_info_open(grn_ctx *ctx, int start);
void grn_scan_info_close(grn_ctx *ctx, scan_info *si);
void grn_scan_info_put_index(grn_ctx *ctx, scan_info *si, grn_obj *index,
@@ -64,6 +68,9 @@ int grn_scan_info_get_similarity_threshold(scan_info *si);
void grn_scan_info_set_similarity_threshold(scan_info *si, int similarity_threshold);
grn_bool grn_scan_info_push_arg(scan_info *si, grn_obj *arg);
grn_obj *grn_scan_info_get_arg(grn_ctx *ctx, scan_info *si, int i);
+int grn_scan_info_get_start_position(scan_info *si);
+void grn_scan_info_set_start_position(scan_info *si, int start);
+void grn_scan_info_reset_position(scan_info *si);
int32_t grn_expr_code_get_weight(grn_ctx *ctx, grn_expr_code *ec, uint32_t *offset);
grn_rc grn_expr_code_inspect_indented(grn_ctx *ctx,
@@ -72,12 +79,8 @@ grn_rc grn_expr_code_inspect_indented(grn_ctx *ctx,
const char *indent);
void grn_p_expr_code(grn_ctx *ctx, grn_expr_code *code);
-void grn_expr_take_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj);
grn_obj *grn_expr_alloc_const(grn_ctx *ctx, grn_obj *expr);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_EXPR_H */
-
diff --git a/storage/mroonga/vendor/groonga/lib/grn_expr_code.h b/storage/mroonga/vendor/groonga/lib/grn_expr_code.h
index a0fd680e7d4..f33c532ee54 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_expr_code.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_expr_code.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_EXPR_CODE_H
-#define GRN_EXPR_CODE_H
+#pragma once
#include "grn_db.h"
@@ -32,6 +31,3 @@ unsigned int grn_expr_code_n_used_codes(grn_ctx *ctx,
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_EXPR_CODE_H */
-
diff --git a/storage/mroonga/vendor/groonga/lib/grn_expr_executor.h b/storage/mroonga/vendor/groonga/lib/grn_expr_executor.h
new file mode 100644
index 00000000000..df00134cf21
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_expr_executor.h
@@ -0,0 +1,39 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _grn_expr_executor grn_expr_executor;
+
+grn_expr_executor *grn_expr_executor_open(grn_ctx *ctx,
+ grn_obj *expr);
+grn_obj *grn_expr_executor_exec(grn_ctx *ctx,
+ grn_expr_executor *executor,
+ grn_id id);
+grn_rc grn_expr_executor_close(grn_ctx *ctx,
+ grn_expr_executor *executor);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_file_lock.h b/storage/mroonga/vendor/groonga/lib/grn_file_lock.h
new file mode 100644
index 00000000000..43ab576337c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_file_lock.h
@@ -0,0 +1,48 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ const char *path;
+#ifdef WIN32
+ HANDLE handle;
+#else /* WIN32 */
+ int fd;
+#endif /* WIN32 */
+} grn_file_lock;
+
+void grn_file_lock_init(grn_ctx *ctx,
+ grn_file_lock *file_lock,
+ const char *path);
+grn_bool grn_file_lock_acquire(grn_ctx *ctx,
+ grn_file_lock *file_lock,
+ int timeout,
+ const char *error_message_tag);
+void grn_file_lock_release(grn_ctx *ctx, grn_file_lock *file_lock);
+void grn_file_lock_fin(grn_ctx *ctx, grn_file_lock *file_lock);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_geo.h b/storage/mroonga/vendor/groonga/lib/grn_geo.h
index 5becbe4f45c..884287aeaeb 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_geo.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_geo.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2011 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,13 +15,10 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_GEO_H
-#define GRN_GEO_H
-#ifndef GRN_H
-#include "grn.h"
-#endif /* GRN_H */
+#pragma once
+#include "grn.h"
#include "grn_ii.h"
#include "grn_db.h"
@@ -125,9 +123,6 @@ typedef struct {
grn_rc grn_geo_cursor_close(grn_ctx *ctx, grn_obj *geo_cursor);
-int grn_geo_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit,
- grn_obj *result, grn_table_sort_key *keys, int n_keys);
-
grn_rc grn_geo_resolve_approximate_type(grn_ctx *ctx, grn_obj *type_name,
grn_geo_approximate_type *type);
@@ -203,5 +198,3 @@ double grn_geo_distance_ellipsoid_raw_wgs84(grn_ctx *ctx,
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_GEO_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_hash.h b/storage/mroonga/vendor/groonga/lib/grn_hash.h
index d50836d80f1..6e851c21210 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_hash.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_hash.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_HASH_H
-#define GRN_HASH_H
+
+#pragma once
#include "grn.h"
#include "grn_ctx.h"
@@ -156,7 +157,14 @@ struct _grn_array_cursor {
int dir;
};
-#define GRN_ARRAY_SIZE(array) (*((array)->n_entries))
+/*
+ * grn_array_size() returns the number of entries in an array.
+ * If the array was truncated by another process but `array` still refers to
+ * the old one, this function returns 0.
+ */
+uint32_t grn_array_size(grn_ctx *ctx, grn_array *array);
+
+uint32_t grn_array_get_flags(grn_ctx *ctx, grn_array *array);
grn_rc grn_array_truncate(grn_ctx *ctx, grn_array *array);
grn_rc grn_array_copy_sort_key(grn_ctx *ctx, grn_array *array,
@@ -186,7 +194,6 @@ GRN_API grn_id grn_table_queue_tail(grn_table_queue *queue);
/**** grn_hash ****/
-#define GRN_HASH_TINY (0x01<<6)
#define GRN_HASH_MAX_KEY_SIZE_NORMAL GRN_TABLE_MAX_KEY_SIZE
#define GRN_HASH_MAX_KEY_SIZE_LARGE (0xffff)
@@ -249,7 +256,7 @@ struct _grn_hash {
uint32_t value_size;\
grn_id tokenizer;\
uint32_t curr_rec;\
- int32_t curr_key;\
+ uint32_t curr_key_normal;\
uint32_t idx_offset;\
uint32_t entry_size;\
uint32_t max_offset;\
@@ -257,7 +264,9 @@ struct _grn_hash {
uint32_t n_garbages;\
uint32_t lock;\
grn_id normalizer;\
- uint32_t reserved[15]
+ uint32_t truncated;\
+ uint64_t curr_key_large;\
+ uint32_t reserved[12]
struct _grn_hash_header_common {
GRN_HASH_HEADER_COMMON_FIELDS;
@@ -359,8 +368,11 @@ grn_id grn_array_at(grn_ctx *ctx, grn_array *array, grn_id id);
void grn_hash_check(grn_ctx *ctx, grn_hash *hash);
+grn_bool grn_hash_is_large_total_key_size(grn_ctx *ctx, grn_hash *hash);
+
+uint64_t grn_hash_total_key_size(grn_ctx *ctx, grn_hash *hash);
+uint64_t grn_hash_max_total_key_size(grn_ctx *ctx, grn_hash *hash);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_HASH_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ii.h b/storage/mroonga/vendor/groonga/lib/grn_ii.h
index 1ac9528e4cd..21f57e2f107 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_ii.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_ii.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_II_H
-#define GRN_II_H
+
+#pragma once
/* "ii" is for inverted index */
@@ -30,15 +31,18 @@ extern "C" {
struct _grn_ii {
grn_db_obj obj;
- grn_io *seg;
- grn_io *chunk;
- grn_obj *lexicon;
- grn_obj_flags lflags;
- grn_encoding encoding;
- uint32_t n_elements;
+ grn_io *seg; /* I/O for a variety of segments */
+ grn_io *chunk; /* I/O for posting chunks */
+ grn_obj *lexicon; /* Lexicon table */
+ grn_table_flags lflags;
+ grn_encoding encoding; /* Character encoding */
+ /* This member is used for matching */
+ uint32_t n_elements; /* Number of elements in postings */
+ /* rid, [sid], tf, [weight] and [pos] */
struct grn_ii_header *header;
};
+/* BGQ is buffer garbage queue? */
#define GRN_II_BGQSIZE 16
#define GRN_II_MAX_LSEG 0x10000
#define GRN_II_W_TOTAL_CHUNK 40
@@ -47,6 +51,17 @@ struct _grn_ii {
#define GRN_II_MAX_CHUNK (1 << (GRN_II_W_TOTAL_CHUNK - GRN_II_W_CHUNK))
#define GRN_II_N_CHUNK_VARIATION (GRN_II_W_CHUNK - GRN_II_W_LEAST_CHUNK)
+#define GRN_II_MAX_CHUNK_SMALL (1 << (GRN_II_W_TOTAL_CHUNK - GRN_II_W_CHUNK - 8))
+/* GRN_II_MAX_CHUNK_MEDIUM has enough space for the following source:
+ * * Single source.
+ * * Source is a fixed size column or _key of a table.
+ * * Source column is a scalar column.
+ * * Lexicon doesn't have tokenizer.
+ */
+#define GRN_II_MAX_CHUNK_MEDIUM (1 << (GRN_II_W_TOTAL_CHUNK - GRN_II_W_CHUNK - 4))
+
+#define GRN_II_PSEG_NOT_ASSIGNED 0xffffffff
+
struct grn_ii_header {
uint64_t total_chunk_size;
uint64_t bmax;
@@ -60,8 +75,8 @@ struct grn_ii_header {
uint32_t bgqtail;
uint32_t bgqbody[GRN_II_BGQSIZE];
uint32_t reserved[288];
- uint32_t ainfo[GRN_II_MAX_LSEG];
- uint32_t binfo[GRN_II_MAX_LSEG];
+ uint32_t ainfo[GRN_II_MAX_LSEG]; /* array info */
+ uint32_t binfo[GRN_II_MAX_LSEG]; /* buffer info */
uint32_t free_chunks[GRN_II_N_CHUNK_VARIATION + 1];
uint32_t garbages[GRN_II_N_CHUNK_VARIATION + 1];
uint32_t ngarbages[GRN_II_N_CHUNK_VARIATION + 1];
@@ -95,6 +110,7 @@ GRN_API grn_ii *grn_ii_open(grn_ctx *ctx, const char *path, grn_obj *lexicon);
GRN_API grn_rc grn_ii_close(grn_ctx *ctx, grn_ii *ii);
GRN_API grn_rc grn_ii_remove(grn_ctx *ctx, const char *path);
grn_rc grn_ii_info(grn_ctx *ctx, grn_ii *ii, uint64_t *seg_size, uint64_t *chunk_size);
+grn_column_flags grn_ii_get_flags(grn_ctx *ctx, grn_ii *ii);
grn_rc grn_ii_update_one(grn_ctx *ctx, grn_ii *ii, uint32_t key, grn_ii_updspec *u,
grn_hash *h);
grn_rc grn_ii_delete_one(grn_ctx *ctx, grn_ii *ii, uint32_t key, grn_ii_updspec *u,
@@ -106,28 +122,10 @@ int grn_ii_updspec_cmp(grn_ii_updspec *a, grn_ii_updspec *b);
void grn_ii_expire(grn_ctx *ctx, grn_ii *ii);
grn_rc grn_ii_flush(grn_ctx *ctx, grn_ii *ii);
+size_t grn_ii_get_disk_usage(grn_ctx *ctx, grn_ii *ii);
-typedef struct {
- grn_id rid;
- uint32_t sid;
- uint32_t pos;
- uint32_t tf;
- uint32_t weight;
- uint32_t rest;
-} grn_ii_posting;
-
-typedef struct _grn_ii_cursor grn_ii_cursor;
-
-GRN_API grn_rc grn_ii_posting_add(grn_ctx *ctx, grn_ii_posting *pos,
- grn_hash *s, grn_operator op);
-
-GRN_API grn_ii_cursor *grn_ii_cursor_open(grn_ctx *ctx, grn_ii *ii, grn_id tid,
- grn_id min, grn_id max, int nelements, int flags);
grn_ii_cursor *grn_ii_cursor_openv1(grn_ii *ii, uint32_t key);
grn_rc grn_ii_cursor_openv2(grn_ii_cursor **cursors, int ncursors);
-GRN_API grn_ii_posting *grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c);
-grn_ii_posting *grn_ii_cursor_next_pos(grn_ctx *ctx, grn_ii_cursor *c);
-GRN_API grn_rc grn_ii_cursor_close(grn_ctx *ctx, grn_ii_cursor *c);
uint32_t grn_ii_max_section(grn_ii *ii);
@@ -157,6 +155,8 @@ struct _grn_select_optarg {
grn_obj *scorer;
grn_obj *scorer_args_expr;
unsigned int scorer_args_expr_offset;
+ grn_fuzzy_search_optarg fuzzy;
+ grn_match_info *match_info;
};
GRN_API grn_rc grn_ii_column_update(grn_ctx *ctx, grn_ii *ii, grn_id id,
@@ -179,10 +179,14 @@ grn_rc grn_ii_at(grn_ctx *ctx, grn_ii *ii, grn_id id, grn_hash *s, grn_operator
void grn_ii_inspect_values(grn_ctx *ctx, grn_ii *ii, grn_obj *buf);
void grn_ii_cursor_inspect(grn_ctx *ctx, grn_ii_cursor *c, grn_obj *buf);
+grn_rc grn_ii_truncate(grn_ctx *ctx, grn_ii *ii);
grn_rc grn_ii_build(grn_ctx *ctx, grn_ii *ii, uint64_t sparsity);
+typedef struct grn_ii_builder_options grn_ii_builder_options;
+
+grn_rc grn_ii_build2(grn_ctx *ctx, grn_ii *ii,
+ const grn_ii_builder_options *options);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_II_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_index_column.h b/storage/mroonga/vendor/groonga/lib/grn_index_column.h
new file mode 100644
index 00000000000..afaed9c9010
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_index_column.h
@@ -0,0 +1,34 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_index_column_init_from_env(void);
+grn_rc grn_index_column_build(grn_ctx *ctx, grn_obj *index_column);
+grn_rc grn_index_column_rebuild(grn_ctx *ctx, grn_obj *index_column);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_io.h b/storage/mroonga/vendor/groonga/lib/grn_io.h
index 6de63bd172a..6cea27f29b2 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_io.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_io.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_IO_H
-#define GRN_IO_H
+
+#pragma once
#include "grn.h"
#include "grn_error.h"
@@ -88,7 +89,7 @@ struct _grn_io_header {
uint32_t lock;
uint64_t curr_size;
uint32_t segment_tail;
- uint32_t lastmod;
+ uint32_t last_modified;
};
struct _grn_io {
@@ -116,6 +117,7 @@ GRN_API grn_io *grn_io_create(grn_ctx *ctx, const char *path,
grn_io *grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode);
GRN_API grn_rc grn_io_close(grn_ctx *ctx, grn_io *io);
grn_rc grn_io_remove(grn_ctx *ctx, const char *path);
+grn_rc grn_io_remove_if_exist(grn_ctx *ctx, const char *path);
grn_rc grn_io_size(grn_ctx *ctx, grn_io *io, uint64_t *size);
grn_rc grn_io_rename(grn_ctx *ctx, const char *old_name, const char *new_name);
GRN_API void *grn_io_header(grn_io *io);
@@ -174,7 +176,8 @@ void grn_io_seg_map_(grn_ctx *ctx, grn_io *io, uint32_t segno, grn_io_mapinfo *i
if (nref) {\
GRN_ATOMIC_ADD_EX(pnref, -1, nref);\
if (retry >= GRN_IO_MAX_RETRY) {\
- GRN_LOG(ctx, GRN_LOG_CRIT, "deadlock detected! in GRN_IO_SEG_REF(%p, %u)", io, segno);\
+ GRN_LOG(ctx, GRN_LOG_CRIT,\
+ "deadlock detected! in GRN_IO_SEG_REF(%p, %u)", io, segno);\
break;\
}\
GRN_FUTEX_WAIT(pnref);\
@@ -199,7 +202,9 @@ void grn_io_seg_map_(grn_ctx *ctx, grn_io *io, uint32_t segno, grn_io_mapinfo *i
if (nref >= GRN_IO_MAX_REF) {\
GRN_ATOMIC_ADD_EX(pnref, -1, nref);\
if (retry >= GRN_IO_MAX_RETRY) {\
- GRN_LOG(ctx, GRN_LOG_CRIT, "deadlock detected!! in GRN_IO_SEG_REF(%p, %u, %u)", io, segno, nref);\
+ GRN_LOG(ctx, GRN_LOG_CRIT,\
+ "deadlock detected!! in GRN_IO_SEG_REF(%p, %u, %u)",\
+ io, segno, nref);\
*pnref = 0; /* force reset */ \
break;\
}\
@@ -207,13 +212,16 @@ void grn_io_seg_map_(grn_ctx *ctx, grn_io *io, uint32_t segno, grn_io_mapinfo *i
continue;\
}\
if (nref >= 0x40000000) {\
- ALERT("strange nref value!! in GRN_IO_SEG_REF(%p, %u, %u)", io, segno, nref); \
+ ALERT("strange nref value!! in GRN_IO_SEG_REF(%p, %u, %u)",\
+ io, segno, nref); \
}\
if (!info->map) {\
if (nref) {\
GRN_ATOMIC_ADD_EX(pnref, -1, nref);\
if (retry >= GRN_IO_MAX_RETRY) {\
- GRN_LOG(ctx, GRN_LOG_CRIT, "deadlock detected!!! in GRN_IO_SEG_REF(%p, %u, %u)", io, segno, nref);\
+ GRN_LOG(ctx, GRN_LOG_CRIT,\
+ "deadlock detected!!! in GRN_IO_SEG_REF(%p, %u, %u)",\
+ io, segno, nref);\
break;\
}\
GRN_FUTEX_WAIT(pnref);\
@@ -240,7 +248,9 @@ void grn_io_seg_map_(grn_ctx *ctx, grn_io *io, uint32_t segno, grn_io_mapinfo *i
if (nref) {\
GRN_ATOMIC_ADD_EX(pnref, -1, nref);\
if (retry >= GRN_IO_MAX_RETRY) {\
- GRN_LOG(ctx, GRN_LOG_CRIT, "deadlock detected!!!! in GRN_IO_SEG_REF(%p, %u)", io, segno);\
+ GRN_LOG(ctx, GRN_LOG_CRIT,\
+ "deadlock detected!!!! in GRN_IO_SEG_REF(%p, %u)",\
+ io, segno);\
break;\
}\
GRN_FUTEX_WAIT(pnref);\
@@ -303,6 +313,8 @@ GRN_API grn_rc grn_io_lock(grn_ctx *ctx, grn_io *io, int timeout);
GRN_API void grn_io_unlock(grn_io *io);
void grn_io_clear_lock(grn_io *io);
uint32_t grn_io_is_locked(grn_io *io);
+grn_bool grn_io_is_corrupt(grn_ctx *ctx, grn_io *io);
+size_t grn_io_get_disk_usage(grn_ctx *ctx, grn_io *io);
#define GRN_IO_ARRAY_AT(io,array,offset,flags,res) do {\
grn_io_array_info *ainfo = &(io)->ainfo[array];\
@@ -353,7 +365,6 @@ uint32_t grn_io_get_type(grn_io *io);
void grn_io_init_from_env(void);
uint32_t grn_io_expire(grn_ctx *ctx, grn_io *io, int count_thresh, uint32_t limit);
-uint32_t grn_expire(grn_ctx *ctx, int count_thresh, uint32_t limit);
grn_rc grn_io_flush(grn_ctx *ctx, grn_io *io);
@@ -474,5 +485,3 @@ grn_rc grn_io_flush(grn_ctx *ctx, grn_io *io);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_IO_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_load.h b/storage/mroonga/vendor/groonga/lib/grn_load.h
new file mode 100644
index 00000000000..b4345c953a8
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_load.h
@@ -0,0 +1,47 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_raw_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_JSON_LOAD_OPEN_BRACKET 0x40000000
+#define GRN_JSON_LOAD_OPEN_BRACE 0x40000001
+
+typedef struct grn_load_input_ {
+ grn_content_type type;
+ grn_raw_string table;
+ grn_raw_string columns;
+ grn_raw_string values;
+ grn_raw_string if_exists;
+ grn_raw_string each;
+ grn_bool output_ids;
+ grn_bool output_errors;
+ uint32_t emit_level;
+} grn_load_input;
+
+void grn_load_internal(grn_ctx *ctx, grn_load_input *input);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_logger.h b/storage/mroonga/vendor/groonga/lib/grn_logger.h
index 95186ca107a..ea0a85fb2e7 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_logger.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_logger.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_LOGGER_H
-#define GRN_LOGGER_H
+
+#pragma once
#include "grn.h"
@@ -33,5 +33,3 @@ void grn_query_logger_fin(grn_ctx *ctx);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_LOGGER_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_mrb.h b/storage/mroonga/vendor/groonga/lib/grn_mrb.h
index 3726cdcba29..2fd00b328f5 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_mrb.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_mrb.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2014 Brazil
+ Copyright(C) 2013-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_H
-#define GRN_MRB_H
+#pragma once
#include "grn.h"
#include "grn_ctx.h"
@@ -33,14 +32,11 @@ extern "C" {
void grn_mrb_init_from_env(void);
#ifdef GRN_WITH_MRUBY
-GRN_API mrb_value grn_mrb_eval(grn_ctx *ctx, const char *script, int script_length);
GRN_API mrb_value grn_mrb_load(grn_ctx *ctx, const char *path);
-GRN_API grn_rc grn_mrb_to_grn(grn_ctx *ctx, mrb_value mrb_object, grn_obj *grn_object);
GRN_API const char *grn_mrb_get_system_ruby_scripts_dir(grn_ctx *ctx);
+grn_bool grn_mrb_is_order_by_estimated_size_enabled(void);
#endif
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_MRB_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_msgpack.h b/storage/mroonga/vendor/groonga/lib/grn_msgpack.h
index db86987c08a..c153d83bbad 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_msgpack.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_msgpack.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MSGPACK_H
-#define GRN_MSGPACK_H
+
+#pragma once
#ifdef GRN_WITH_MESSAGE_PACK
# include <msgpack.h>
@@ -44,5 +44,3 @@ typedef size_t msgpack_size_t;
# define MSGPACK_OBJECT_FLOAT_VALUE(object) (object)->via.f64
# endif /* MSGPACK_VERSION_MAJOR < 1 */
#endif /* GRN_WITH_MESSAGE_PACK */
-
-#endif /* GRN_MSGPACK_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_nfkc.h b/storage/mroonga/vendor/groonga/lib/grn_nfkc.h
new file mode 100644
index 00000000000..139cd5b952e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_nfkc.h
@@ -0,0 +1,39 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+grn_char_type grn_nfkc50_char_type(const unsigned char *utf8);
+
+const char *grn_nfkc_decompose(const unsigned char *utf8);
+const char *grn_nfkc50_decompose(const unsigned char *utf8);
+
+const char *grn_nfkc_compose(const unsigned char *prefix_utf8,
+ const unsigned char *suffix_utf8);
+const char *grn_nfkc50_compose(const unsigned char *prefix_utf8,
+ const unsigned char *suffix_utf8);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_normalizer.h b/storage/mroonga/vendor/groonga/lib/grn_normalizer.h
index 8c7bfddf810..3afc9bcef09 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_normalizer.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_normalizer.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2012 Brazil
+ Copyright(C) 2012-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_NORMALIZER_H
-#define GRN_NORMALIZER_H
+
+#pragma once
#include "grn.h"
#include "grn_ctx.h"
@@ -40,5 +40,3 @@ grn_rc grn_db_init_builtin_normalizers(grn_ctx *ctx);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_NORMALIZER_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_obj.h b/storage/mroonga/vendor/groonga/lib/grn_obj.h
new file mode 100644
index 00000000000..b05a3778dff
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_obj.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn_io.h"
+#include "grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+grn_io *grn_obj_get_io(grn_ctx *ctx, grn_obj *obj);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_output.h b/storage/mroonga/vendor/groonga/lib/grn_output.h
index 63752e90bd9..af99b0c9ccd 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_output.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_output.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2010-2012 Brazil
+/*
+ Copyright(C) 2010-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_OUTPUT_H
-#define GRN_OUTPUT_H
+
+#pragma once
#include "grn.h"
#include "grn_ctx.h"
@@ -32,11 +33,16 @@ GRN_API void grn_output_array_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_t
GRN_API void grn_output_map_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
const char *name, int nelements);
GRN_API void grn_output_map_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type);
+GRN_API void grn_output_null(grn_ctx *ctx, grn_obj *outbuf,
+ grn_content_type output_type);
void grn_output_int32(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
int32_t value);
GRN_API void grn_output_int64(grn_ctx *ctx, grn_obj *outbuf,
grn_content_type output_type,
int64_t value);
+GRN_API void grn_output_uint64(grn_ctx *ctx, grn_obj *outbuf,
+ grn_content_type output_type,
+ uint64_t value);
void grn_output_float(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
double value);
GRN_API void grn_output_cstr(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
@@ -48,6 +54,22 @@ GRN_API void grn_output_bool(grn_ctx *ctx, grn_obj *outbuf,
grn_content_type output_type,
grn_bool value);
+GRN_API void grn_output_result_set_open(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *result_set,
+ grn_obj_format *format,
+ uint32_t n_additional_elements);
+GRN_API void grn_output_result_set_close(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *result_set,
+ grn_obj_format *format);
+GRN_API void grn_output_result_set(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *result_set,
+ grn_obj_format *format);
GRN_API void grn_output_table_columns(grn_ctx *ctx,
grn_obj *outbuf,
grn_content_type output_type,
@@ -71,10 +93,14 @@ grn_rc grn_output_format_set_columns(grn_ctx *ctx, grn_obj_format *format,
(grn_ctx_output_map_open(ctx, name, nelements))
#define GRN_OUTPUT_MAP_CLOSE() \
(grn_ctx_output_map_close(ctx))
+#define GRN_OUTPUT_NULL() \
+ (grn_ctx_output_null(ctx))
#define GRN_OUTPUT_INT32(value) \
(grn_ctx_output_int32(ctx, value))
#define GRN_OUTPUT_INT64(value) \
(grn_ctx_output_int64(ctx, value))
+#define GRN_OUTPUT_UINT64(value) \
+ (grn_ctx_output_uint64(ctx, value))
#define GRN_OUTPUT_FLOAT(value) \
(grn_ctx_output_float(ctx, value))
#define GRN_OUTPUT_CSTR(value)\
@@ -85,6 +111,12 @@ grn_rc grn_output_format_set_columns(grn_ctx *ctx, grn_obj_format *format,
(grn_ctx_output_bool(ctx, value))
#define GRN_OUTPUT_OBJ(obj,format)\
(grn_ctx_output_obj(ctx, obj, format))
+#define GRN_OUTPUT_RESULT_SET_OPEN(result_set,format,n_additional_elements)\
+ (grn_ctx_output_result_set_open(ctx, result_set, format, n_additional_elements))
+#define GRN_OUTPUT_RESULT_SET_CLOSE(result_set,format)\
+ (grn_ctx_output_result_set_close(ctx, result_set, format))
+#define GRN_OUTPUT_RESULT_SET(result_set,format,n_additional_elements)\
+ (grn_ctx_output_result_set(ctx, result_set, format, n_additional_elements))
#define GRN_OUTPUT_TABLE_COLUMNS(table,format)\
(grn_ctx_output_table_columns(ctx, table, format))
#define GRN_OUTPUT_TABLE_RECORDS(table,format)\
@@ -93,5 +125,3 @@ grn_rc grn_output_format_set_columns(grn_ctx *ctx, grn_obj_format *format,
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_OUTPUT_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_pat.h b/storage/mroonga/vendor/groonga/lib/grn_pat.h
index 763c6848a63..69a5d0c1075 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_pat.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_pat.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2014 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_PAT_H
-#define GRN_PAT_H
+
+#pragma once
#include "grn.h"
#include "grn_db.h"
@@ -26,6 +27,7 @@ extern "C" {
#endif
#define GRN_PAT_MAX_KEY_SIZE GRN_TABLE_MAX_KEY_SIZE
+#define GRN_PAT_MAX_TOTAL_KEY_SIZE (UINT32_MAX - 1)
struct _grn_pat {
grn_db_obj obj;
@@ -39,15 +41,18 @@ struct _grn_pat {
grn_obj token_filters;
grn_id *cache;
uint32_t cache_size;
+ grn_bool is_dirty;
+ grn_critical_section lock;
};
#define GRN_PAT_NDELINFOS 0x100
typedef struct {
- grn_id d;
- grn_id ld;
- uint32_t stat;
- uint32_t shared;
+ grn_id d; /* The ID of a deleting node. */
+ grn_id ld; /* The ID of the parent node of a deleting node. */
+ /* delinfo->ld is set if required. */
+ uint32_t stat; /* DL_EMPTY, DL_PHASE1, or DL_PHASE2. */
+ uint32_t shared; /* This flag is used if GRN_OBJ_KEY_WITH_SIS is set. */
} grn_pat_delinfo;
struct grn_pat_header {
@@ -64,7 +69,9 @@ struct grn_pat_header {
int32_t curr_del3;
uint32_t n_garbages;
grn_id normalizer;
- uint32_t reserved[1004];
+ uint32_t truncated;
+ uint32_t n_dirty_opens;
+ uint32_t reserved[1002];
grn_pat_delinfo delinfos[GRN_PAT_NDELINFOS];
grn_id garbages[GRN_PAT_MAX_KEY_SIZE + 1];
};
@@ -78,14 +85,14 @@ typedef struct _grn_pat_cursor_entry grn_pat_cursor_entry;
struct _grn_pat_cursor {
grn_db_obj obj;
- grn_id curr_rec;
+ grn_id curr_rec; /* ID of the latest record */
grn_pat *pat;
grn_ctx *ctx;
- unsigned int size;
- unsigned int sp;
- grn_id tail;
- unsigned int rest;
- grn_pat_cursor_entry *ss;
+ unsigned int size; /* stack size (the maximum number of entries) */
+ unsigned int sp; /* stack pointer (the number of entries) */
+ grn_id tail; /* sentinel (the end of the traversal) */
+ unsigned int rest; /* limit rest (the number of remaining records) */
+ grn_pat_cursor_entry *ss; /* stack buffer (pointer to entries) */
uint8_t curr_key[GRN_TABLE_MAX_KEY_SIZE];
};
@@ -104,8 +111,19 @@ void grn_pat_cursor_inspect(grn_ctx *ctx, grn_pat_cursor *c, grn_obj *buf);
grn_rc grn_pat_cache_enable(grn_ctx *ctx, grn_pat *pat, uint32_t cache_size);
void grn_pat_cache_disable(grn_ctx *ctx, grn_pat *pat);
+GRN_API grn_rc grn_pat_fuzzy_search(grn_ctx *ctx, grn_pat *pat,
+ const void *key, unsigned int key_size,
+ grn_fuzzy_search_optarg *args, grn_hash *h);
+
+uint32_t grn_pat_total_key_size(grn_ctx *ctx, grn_pat *pat);
+
+grn_bool grn_pat_is_key_encoded(grn_ctx *ctx, grn_pat *pat);
+
+grn_rc grn_pat_dirty(grn_ctx *ctx, grn_pat *pat);
+grn_bool grn_pat_is_dirty(grn_ctx *ctx, grn_pat *pat);
+grn_rc grn_pat_clean(grn_ctx *ctx, grn_pat *pat);
+grn_rc grn_pat_clear_dirty(grn_ctx *ctx, grn_pat *pat);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_PAT_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_plugin.h b/storage/mroonga/vendor/groonga/lib/grn_plugin.h
index 22749c634aa..3e7b9528848 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_plugin.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_plugin.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2010-2013 Brazil
+/*
+ Copyright(C) 2010-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_PLUGIN_H
-#define GRN_PLUGIN_H
+
+#pragma once
#include "grn.h"
#include "grn_ctx.h"
@@ -59,5 +60,3 @@ void grn_plugin_ensure_registered(grn_ctx *ctx, grn_obj *proc);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_PLUGIN_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_proc.h b/storage/mroonga/vendor/groonga/lib/grn_proc.h
index b75d11079a2..961ce3e46a9 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_proc.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_proc.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_PROC_H
-#define GRN_PROC_H
+
+#pragma once
#include "grn.h"
@@ -23,13 +24,129 @@
extern "C" {
#endif
+#define GRN_SELECT_DEFAULT_LIMIT 10
+#define GRN_SELECT_DEFAULT_OUTPUT_COLUMNS "_id, _key, *"
+
+#define GRN_SELECT_INTERNAL_VAR_CONDITION "$condition"
+#define GRN_SELECT_INTERNAL_VAR_CONDITION_LEN \
+ (sizeof(GRN_SELECT_INTERNAL_VAR_CONDITION) - 1)
+
void grn_proc_init_from_env(void);
GRN_VAR const char *grn_document_root;
-void grn_db_init_builtin_query(grn_ctx *ctx);
+void grn_db_init_builtin_commands(grn_ctx *ctx);
+
+void grn_proc_init_clearlock(grn_ctx *ctx);
+void grn_proc_init_column_copy(grn_ctx *ctx);
+void grn_proc_init_column_create(grn_ctx *ctx);
+void grn_proc_init_column_list(grn_ctx *ctx);
+void grn_proc_init_column_remove(grn_ctx *ctx);
+void grn_proc_init_column_rename(grn_ctx *ctx);
+void grn_proc_init_config_get(grn_ctx *ctx);
+void grn_proc_init_config_set(grn_ctx *ctx);
+void grn_proc_init_config_delete(grn_ctx *ctx);
+void grn_proc_init_define_selector(grn_ctx *ctx);
+void grn_proc_init_dump(grn_ctx *ctx);
+void grn_proc_init_edit_distance(grn_ctx *ctx);
+void grn_proc_init_fuzzy_search(grn_ctx *ctx);
+void grn_proc_init_highlight(grn_ctx *ctx);
+void grn_proc_init_highlight_full(grn_ctx *ctx);
+void grn_proc_init_highlight_html(grn_ctx *ctx);
+void grn_proc_init_in_records(grn_ctx *ctx);
+void grn_proc_init_lock_acquire(grn_ctx *ctx);
+void grn_proc_init_lock_clear(grn_ctx *ctx);
+void grn_proc_init_lock_release(grn_ctx *ctx);
+void grn_proc_init_object_exist(grn_ctx *ctx);
+void grn_proc_init_object_inspect(grn_ctx *ctx);
+void grn_proc_init_object_list(grn_ctx *ctx);
+void grn_proc_init_object_remove(grn_ctx *ctx);
+void grn_proc_init_query_expand(grn_ctx *ctx);
+void grn_proc_init_query_log_flags_get(grn_ctx *ctx);
+void grn_proc_init_query_log_flags_set(grn_ctx *ctx);
+void grn_proc_init_query_log_flags_add(grn_ctx *ctx);
+void grn_proc_init_query_log_flags_remove(grn_ctx *ctx);
+void grn_proc_init_schema(grn_ctx *ctx);
+void grn_proc_init_select(grn_ctx *ctx);
+void grn_proc_init_snippet(grn_ctx *ctx);
+void grn_proc_init_snippet_html(grn_ctx *ctx);
+void grn_proc_init_table_copy(grn_ctx *ctx);
+void grn_proc_init_table_create(grn_ctx *ctx);
+void grn_proc_init_table_list(grn_ctx *ctx);
+void grn_proc_init_table_remove(grn_ctx *ctx);
+void grn_proc_init_table_rename(grn_ctx *ctx);
+void grn_proc_init_table_tokenize(grn_ctx *ctx);
+void grn_proc_init_tokenize(grn_ctx *ctx);
+
+grn_bool grn_proc_option_value_bool(grn_ctx *ctx,
+ grn_obj *option,
+ grn_bool default_value);
+int32_t grn_proc_option_value_int32(grn_ctx *ctx,
+ grn_obj *option,
+ int32_t default_value);
+const char *grn_proc_option_value_string(grn_ctx *ctx,
+ grn_obj *option,
+ size_t *size);
+grn_content_type grn_proc_option_value_content_type(grn_ctx *ctx,
+ grn_obj *option,
+ grn_content_type default_value);
+grn_operator grn_proc_option_value_mode(grn_ctx *ctx,
+ grn_obj *option,
+ grn_operator default_mode,
+ const char *context);
+
+
+void grn_proc_output_object_name(grn_ctx *ctx, grn_obj *obj);
+void grn_proc_output_object_id_name(grn_ctx *ctx, grn_id id);
+
+grn_bool grn_proc_table_set_token_filters(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *token_filter_names);
+
+grn_column_flags grn_proc_column_parse_flags(grn_ctx *ctx,
+ const char *error_message_tag,
+ const char *text,
+ const char *end);
+
+grn_bool grn_proc_select_output_columns_open(grn_ctx *ctx,
+ grn_obj_format *format,
+ grn_obj *result_set,
+ int n_hits,
+ int offset,
+ int limit,
+ const char *columns,
+ int columns_len,
+ grn_obj *condition,
+ uint32_t n_additional_elements);
+grn_bool grn_proc_select_output_columns_close(grn_ctx *ctx,
+ grn_obj_format *format,
+ grn_obj *result_set);
+grn_bool grn_proc_select_output_columns(grn_ctx *ctx,
+ grn_obj *res,
+ int n_hits,
+ int offset,
+ int limit,
+ const char *columns,
+ int columns_len,
+ grn_obj *condition);
+
+grn_rc grn_proc_syntax_expand_query(grn_ctx *ctx,
+ const char *query,
+ unsigned int query_len,
+ grn_expr_flags flags,
+ const char *query_expander_name,
+ unsigned int query_expander_name_len,
+ const char *term_column_name,
+ unsigned int term_column_name_len,
+ const char *expanded_term_column_name,
+ unsigned int expanded_term_column_name_len,
+ grn_obj *expanded_query,
+ const char *error_message_tag);
+
+grn_expr_flags grn_proc_expr_query_flags_parse(grn_ctx *ctx,
+ const char *query_flags,
+ size_t query_flags_size,
+ const char *error_message_tag);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_PROC_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_raw_string.h b/storage/mroonga/vendor/groonga/lib/grn_raw_string.h
new file mode 100644
index 00000000000..b115ad83813
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_raw_string.h
@@ -0,0 +1,62 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_RAW_STRING_INIT(string) do { \
+ string.value = NULL; \
+ string.length = 0; \
+ } while (GRN_FALSE)
+
+#define GRN_RAW_STRING_SET(string, bulk) \
+ if (bulk && GRN_TEXT_LEN(bulk) > 0) { \
+ string.value = GRN_TEXT_VALUE(bulk); \
+ string.length = GRN_TEXT_LEN(bulk); \
+ } else { \
+ string.value = NULL; \
+ string.length = 0; \
+ }
+
+#define GRN_RAW_STRING_FILL(string, bulk) \
+ if (bulk && GRN_TEXT_LEN(bulk) > 0) { \
+ string.value = GRN_TEXT_VALUE(bulk); \
+ string.length = GRN_TEXT_LEN(bulk); \
+ }
+
+#define GRN_RAW_STRING_EQUAL_CSTRING(string, cstring) \
+ (cstring ? \
+ (string.length == strlen(cstring) && \
+ memcmp(string.value, cstring, string.length) == 0) : \
+ (string.length == 0))
+
+typedef struct {
+ const char *value;
+ size_t length;
+} grn_raw_string;
+
+void grn_raw_string_lstrip(grn_ctx *ctx, grn_raw_string *string);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_report.h b/storage/mroonga/vendor/groonga/lib/grn_report.h
new file mode 100644
index 00000000000..a8bd52fcd1b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_report.h
@@ -0,0 +1,47 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const grn_log_level GRN_REPORT_INDEX_LOG_LEVEL;
+
+void grn_report_index(grn_ctx *ctx,
+ const char *action,
+ const char *tag,
+ grn_obj *index);
+
+void grn_report_index_not_used(grn_ctx *ctx,
+ const char *action,
+ const char *tag,
+ grn_obj *index,
+ const char *reason);
+
+void grn_report_table(grn_ctx *ctx,
+ const char *action,
+ const char *tag,
+ grn_obj *table);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_request_canceler.h b/storage/mroonga/vendor/groonga/lib/grn_request_canceler.h
index 4c77ea5246e..212605394e4 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_request_canceler.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_request_canceler.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_REQUEST_CANCELER_H
-#define GRN_REQUEST_CANCELER_H
+#pragma once
#include "grn.h"
@@ -27,5 +26,3 @@ void grn_request_canceler_fin(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_REQUEST_CANCELER_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_request_timer.h b/storage/mroonga/vendor/groonga/lib/grn_request_timer.h
new file mode 100644
index 00000000000..696687d0c66
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_request_timer.h
@@ -0,0 +1,28 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+grn_bool grn_request_timer_init(void);
+void grn_request_timer_fin(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_rset.h b/storage/mroonga/vendor/groonga/lib/grn_rset.h
index b92e21162df..6a6a8b83fbe 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_rset.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_rset.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_RSET_H
-#define GRN_RSET_H
+
+#pragma once
#include "grn.h"
@@ -111,5 +112,3 @@ void grn_rset_recinfo_set_avg(grn_ctx *ctx,
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_RSET_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_scanner.h b/storage/mroonga/vendor/groonga/lib/grn_scanner.h
new file mode 100644
index 00000000000..617c2b89aba
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_scanner.h
@@ -0,0 +1,40 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn_expr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _grn_scaner {
+ grn_obj *expr;
+ grn_obj *source_expr;
+ scan_info **sis;
+ unsigned int n_sis;
+} grn_scanner;
+
+grn_scanner *grn_scanner_open(grn_ctx *ctx, grn_obj *expr,
+ grn_operator op, grn_bool record_exist);
+void grn_scanner_close(grn_ctx *ctx, grn_scanner *scanner);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_scorer.h b/storage/mroonga/vendor/groonga/lib/grn_scorer.h
index 05f982180db..438fd87abf7 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_scorer.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_scorer.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_SCORER_H
-#define GRN_SCORER_H
+
+#pragma once
#include "grn_ctx.h"
#include "grn_db.h"
@@ -47,5 +47,3 @@ struct _grn_scorer_matched_record {
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_SCORER_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_scorers.h b/storage/mroonga/vendor/groonga/lib/grn_scorers.h
index ed6c18c211a..4a6f1e255a2 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_scorers.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_scorers.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_SCORERS_H
-#define GRN_SCORERS_H
+
+#pragma once
#include "grn_ctx.h"
@@ -29,5 +29,3 @@ grn_rc grn_db_init_builtin_scorers(grn_ctx *ctx);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_SCORERS_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_snip.h b/storage/mroonga/vendor/groonga/lib/grn_snip.h
index 7c123e0c5f4..023a1d1b2b3 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_snip.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_snip.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2014 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,17 +15,11 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_SNIP_H
-#define GRN_SNIP_H
-#ifndef GRN_H
-#include "grn.h"
-#endif /* GRN_H */
+#pragma once
-#ifndef GRN_STR_H
+#include "grn.h"
#include "grn_str.h"
-#endif /* GRN_STR_H */
-
#include "grn_db.h"
#define ASIZE 256U
@@ -128,5 +123,3 @@ void grn_bm_tunedbm(grn_ctx *ctx, snip_cond *cond, grn_obj *string, int flags);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_SNIP_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_store.h b/storage/mroonga/vendor/groonga/lib/grn_store.h
index 9e1223e0685..67f183e71e8 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_store.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_store.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2012 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_STORE_H
-#define GRN_STORE_H
+
+#pragma once
#include "grn.h"
#include "grn_ctx.h"
@@ -83,6 +84,7 @@ GRN_API grn_ja *grn_ja_create(grn_ctx *ctx, const char *path,
uint32_t max_element_size, uint32_t flags);
grn_ja *grn_ja_open(grn_ctx *ctx, const char *path);
grn_rc grn_ja_info(grn_ctx *ctx, grn_ja *ja, unsigned int *max_element_size);
+grn_column_flags grn_ja_get_flags(grn_ctx *ctx, grn_ja *ja);
GRN_API grn_rc grn_ja_close(grn_ctx *ctx, grn_ja *ja);
grn_rc grn_ja_remove(grn_ctx *ctx, const char *path);
grn_rc grn_ja_put(grn_ctx *ctx, grn_ja *ja, grn_id id,
@@ -102,8 +104,77 @@ GRN_API uint32_t grn_ja_size(grn_ctx *ctx, grn_ja *ja, grn_id id);
void grn_ja_check(grn_ctx *ctx, grn_ja *ja);
+#define GRN_JA_READER_INITIAL_REF_SEG_IDS_SIZE 16
+
+/*
+ * grn_ja_reader is designed to improve the performance of sequential access.
+ */
+typedef struct {
+ grn_ja *ja; /* Target jagged array (without ref. count). */
+ uint32_t einfo_seg_id; /* ID of the current header segment. */
+ void *einfo_seg_addr; /* Address of the current header segment. */
+ void *einfo; /* Header of the current value. */
+ grn_bool ref_avail; /* grn_ja_reader_ref() is available or not. */
+ uint32_t ref_seg_id; /* ID of the current referenced segment. */
+ void *ref_seg_addr; /* Address of the current referenced segment. */
+ uint32_t *ref_seg_ids; /* IDs of referenced segments. */
+ uint32_t nref_seg_ids; /* Number of referenced segments. */
+ uint32_t ref_seg_ids_size; /* Maximum number of referenced segments. */
+ uint32_t body_seg_id; /* ID of the current body segment. */
+ uint32_t body_seg_offset; /* Offset in the current body segment. */
+ void *body_seg_addr; /* Address of the current body segment. */
+ uint32_t value_size; /* Size of the current value. */
+ uint32_t packed_size; /* Compressed size of the current value. */
+ void *packed_buf; /* Buffer for decompression. */
+ uint32_t packed_buf_size; /* Size of the buffer for decompression. */
+ void *stream; /* Stream of a compression library. */
+} grn_ja_reader;
+
/*
+ * grn_ja_reader_init() initializes a reader.
+ * An initialized reader must be finalized by grn_ja_reader_fin().
+ */
+grn_rc grn_ja_reader_init(grn_ctx *ctx, grn_ja_reader *reader, grn_ja *ja);
+/* grn_ja_reader_fin() finalizes a reader. */
+grn_rc grn_ja_reader_fin(grn_ctx *ctx, grn_ja_reader *reader);
+
+/*
+ * grn_ja_reader_open() creates a reader.
+ * A created reader must be destroyed by grn_ja_reader_close().
+ */
+grn_rc grn_ja_reader_open(grn_ctx *ctx, grn_ja *ja, grn_ja_reader **reader);
+
+/* grn_ja_reader_close() destroys a reader. */
+grn_rc grn_ja_reader_close(grn_ctx *ctx, grn_ja_reader *reader);
+
+/*
+ * grn_ja_reader_seek() prepares to access a value specified by `id`.
+ * On success, `reader->value_size` is set.
+ */
+grn_rc grn_ja_reader_seek(grn_ctx *ctx, grn_ja_reader *reader, grn_id id);
+
+/*
+ * grn_ja_reader_ref() gets the address to the current value.
+ * This function is available if `reader->ref_avail` is true.
+ */
+grn_rc grn_ja_reader_ref(grn_ctx *ctx, grn_ja_reader *reader, void **addr);
+
+/* grn_ja_reader_unref() frees refereces returned by grn_ja_reader_ref(). */
+grn_rc grn_ja_reader_unref(grn_ctx *ctx, grn_ja_reader *reader);
+
+/* grn_ja_reader_read() reads the current value to `buf`. */
+grn_rc grn_ja_reader_read(grn_ctx *ctx, grn_ja_reader *reader, void *buf);
+
+/*
+ * grn_ja_reader_pread() reads a part of the current value to `buf`.
+ * If `offset` and `size` are invalid, the behavior is undefined.
+ * FIXME: Compressed values are not supported yet.
+ */
+grn_rc grn_ja_reader_pread(grn_ctx *ctx, grn_ja_reader *reader,
+ size_t offset, size_t size, void *buf);
+
+/*
typedef struct _grn_vgram_vnode
{
struct _grn_vgram_vnode *car;
@@ -143,5 +214,3 @@ grn_rc grn_vgram_buf_close(grn_vgram_buf *b);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_STORE_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_str.h b/storage/mroonga/vendor/groonga/lib/grn_str.h
index e6fab611ccd..61711aa7a43 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_str.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_str.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2012 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_STR_H
-#define GRN_STR_H
+
+#pragma once
#include "grn.h"
#include <groonga/nfkc.h>
@@ -74,14 +75,6 @@ grn_rc grn_substring(grn_ctx *ctx, char **str, char **str_end, int start, int en
GRN_API int grn_charlen_(grn_ctx *ctx, const char *str, const char *end, grn_encoding encoding);
GRN_API grn_str *grn_str_open_(grn_ctx *ctx, const char *str, unsigned int str_len, int flags, grn_encoding encoding);
-#define GRN_BULK_INCR_LEN(buf,len) do {\
- if (GRN_BULK_OUTP(buf)) {\
- (buf)->u.b.curr += (len);\
- } else {\
- (buf)->header.flags += (grn_obj_flags)(len);\
- }\
-} while (0)
-
#define GRN_BULK_SET_CURR(buf,p) do {\
if (GRN_BULK_OUTP(buf)) {\
(buf)->u.b.curr = (char *)(p);\
@@ -121,5 +114,3 @@ grn_bool grn_bulk_is_zero(grn_ctx *ctx, grn_obj *obj);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_STR_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_string.h b/storage/mroonga/vendor/groonga/lib/grn_string.h
index bb5905c84f8..95454ef0e85 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_string.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_string.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2012 Brazil
+ Copyright(C) 2012-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -17,24 +17,12 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_STRING_H
-#define GRN_STRING_H
+#pragma once
-#ifndef GRN_H
-# include "grn.h"
-#endif /* GRN_H */
-
-#ifndef GRN_CTX_H
-# include "grn_ctx.h"
-#endif /* GRN_CTX_H */
-
-#ifndef GRN_DB_H
-# include "grn_db.h"
-#endif /* GRN_DB_H */
-
-#ifndef GRN_STR_H
-# include "grn_str.h"
-#endif /* GRN_STR_H */
+#include "grn.h"
+#include "grn_ctx.h"
+#include "grn_db.h"
+#include "grn_str.h"
#ifdef __cplusplus
extern "C" {
@@ -61,5 +49,3 @@ grn_rc grn_string_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *string);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_STRING_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_time.h b/storage/mroonga/vendor/groonga/lib/grn_time.h
new file mode 100644
index 00000000000..1db99481e67
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_time.h
@@ -0,0 +1,40 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef GRN_TIMEVAL_STR_SIZE
+#define GRN_TIMEVAL_STR_SIZE 0x100
+#endif /* GRN_TIMEVAL_STR_SIZE */
+#ifndef GRN_TIMEVAL_STR_FORMAT
+#define GRN_TIMEVAL_STR_FORMAT "%04d-%02d-%02d %02d:%02d:%02d.%06d"
+#endif /* GRN_TIMEVAL_STR_FORMAT */
+
+GRN_API grn_rc grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf, size_t buf_size);
+struct tm *grn_timeval2tm(grn_ctx *ctx, grn_timeval *tv, struct tm *tm_buffer);
+grn_rc grn_str2timeval(const char *str, uint32_t str_len, grn_timeval *tv);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_token_cursor.h b/storage/mroonga/vendor/groonga/lib/grn_token_cursor.h
index fec62224418..17858f2362d 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_token_cursor.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_token_cursor.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2014 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_TOKEN_CURSOR_H
-#define GRN_TOKEN_CURSOR_H
+
+#pragma once
#include "grn_ctx.h"
#include "grn_db.h"
@@ -57,7 +58,10 @@ typedef struct {
grn_encoding encoding;
grn_obj *tokenizer;
grn_proc_ctx pctx;
- grn_obj *token_filters;
+ struct {
+ grn_obj *objects;
+ void **data;
+ } token_filter;
uint32_t variant;
grn_obj *nstr;
} grn_token_cursor;
@@ -75,5 +79,3 @@ GRN_API grn_rc grn_token_cursor_close(grn_ctx *ctx, grn_token_cursor *token_curs
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_TOKEN_CURSOR_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h b/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h
index fb85fb76a48..d52bbbb63ef 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2014 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_TOKENIZERS_H
-#define GRN_TOKENIZERS_H
+
+#pragma once
#include "grn_ctx.h"
@@ -34,5 +35,3 @@ grn_rc grn_db_init_builtin_tokenizers(grn_ctx *ctx);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_TOKENIZERS_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ts.h b/storage/mroonga/vendor/groonga/lib/grn_ts.h
new file mode 100644
index 00000000000..d6939646e5c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_ts.h
@@ -0,0 +1,48 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * grn_ts_select() finds records passing through a filter and writes the values
+ * of output columns (the evaluation results of output expressions) into the
+ * output buffer (`ctx->impl->outbuf`).
+ *
+ * Note that the first `offset` records will be discarded and at most `limit`
+ * records will be output.
+ *
+ * On success, grn_ts_select() returns GRN_SUCCESS.
+ * On failure, grn_ts_select() returns an error code and set the details into
+ * `ctx`.
+ */
+grn_rc grn_ts_select(grn_ctx *ctx, grn_obj *table,
+ const char *filter_ptr, size_t filter_len,
+ const char *scorer_ptr, size_t scorer_len,
+ const char *sortby_ptr, size_t sortby_len,
+ const char *output_columns_ptr, size_t output_columns_len,
+ size_t offset, size_t limit);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_util.h b/storage/mroonga/vendor/groonga/lib/grn_util.h
index f94140dcb66..b9ed347a97a 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_util.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_util.h
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2010-2015 Brazil
+/*
+ Copyright(C) 2010-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,8 +15,8 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_UTIL_H
-#define GRN_UTIL_H
+
+#pragma once
#include "grn.h"
#include "grn_ctx.h"
@@ -26,13 +27,23 @@ extern "C" {
GRN_API grn_rc grn_normalize_offset_and_limit(grn_ctx *ctx, int size, int *offset, int *limit);
-GRN_API const char *grn_win32_base_dir(void);
GRN_API char *grn_path_separator_to_system(char *dest, char *groonga_path);
+void grn_p_record(grn_ctx *ctx, grn_obj *table, grn_id id);
+
+/*
+ * grn_mkstemp generates a unique filename from path_template, creates a
+ * file with permissions 0600 and returns a open file desciptor for the file.
+ * The last 6 bytes of path_template must be "XXXXXX" and these are replaced
+ * with a string that makes the filename unique.
+ */
int grn_mkstemp(char *path_template);
+grn_bool grn_path_exist(const char *path);
+
+int grn_tokenize(const char *str, size_t str_len,
+ const char **tokbuf, int buf_size,
+ const char **rest);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_UTIL_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_window_function.h b/storage/mroonga/vendor/groonga/lib/grn_window_function.h
new file mode 100644
index 00000000000..e5179848704
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_window_function.h
@@ -0,0 +1,40 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+struct _grn_window {
+ grn_obj *table;
+ grn_obj *grouped_table;
+ grn_obj ids;
+ size_t n_ids;
+ ssize_t current_index;
+ grn_window_direction direction;
+ grn_bool is_sorted;
+};
+
+grn_rc grn_window_init(grn_ctx *ctx,
+ grn_window *window,
+ grn_obj *table,
+ grn_bool is_sorted);
+grn_rc grn_window_fin(grn_ctx *ctx, grn_window *window);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_window_functions.h b/storage/mroonga/vendor/groonga/lib/grn_window_functions.h
new file mode 100644
index 00000000000..a9d1e6fd9c3
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_window_functions.h
@@ -0,0 +1,26 @@
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+grn_rc grn_db_init_builtin_window_functions(grn_ctx *ctx);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_windows.h b/storage/mroonga/vendor/groonga/lib/grn_windows.h
new file mode 100644
index 00000000000..dd80aa54b7a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_windows.h
@@ -0,0 +1,33 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2010-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WIN32
+GRN_API UINT grn_windows_encoding_to_code_page(grn_encoding encoding);
+#endif /* WIN32 */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/hash.c b/storage/mroonga/vendor/groonga/lib/hash.c
index 2c44f25cc20..905d27c0a59 100644
--- a/storage/mroonga/vendor/groonga/lib/hash.c
+++ b/storage/mroonga/vendor/groonga/lib/hash.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -262,7 +262,7 @@ grn_tiny_bitmap_put_and_set(grn_tiny_bitmap *bitmap, grn_id bit_id,
inline static void *
grn_io_array_at_inline(grn_ctx *ctx, grn_io *io, uint32_t segment_id,
- uint32_t offset, int flags)
+ uint64_t offset, int flags)
{
void *ptr;
GRN_IO_ARRAY_AT(io, segment_id, offset, &flags, ptr);
@@ -397,7 +397,8 @@ struct grn_array_header {
uint32_t n_garbages;
grn_id garbages;
uint32_t lock;
- uint32_t reserved[9];
+ uint32_t truncated;
+ uint32_t reserved[8];
grn_table_queue queue;
};
@@ -462,6 +463,7 @@ grn_array_init_tiny_array(grn_ctx *ctx, grn_array *array, const char *path,
array->n_garbages_buf = 0;
array->n_entries_buf = 0;
array->io = NULL;
+ array->header = NULL;
array->garbages = GRN_ID_NIL;
grn_tiny_array_init(ctx, &array->array, value_size, GRN_TINY_ARRAY_CLEAR);
grn_tiny_bitmap_init(ctx, &array->bitmap);
@@ -509,6 +511,7 @@ grn_array_init_io_array(grn_ctx *ctx, grn_array *array, const char *path,
header->n_entries = 0;
header->n_garbages = 0;
header->garbages = GRN_ID_NIL;
+ header->truncated = GRN_FALSE;
grn_table_queue_init(ctx, &header->queue);
array->obj.header.flags = flags;
array->ctx = ctx;
@@ -558,7 +561,7 @@ grn_array *
grn_array_create(grn_ctx *ctx, const char *path, uint32_t value_size, uint32_t flags)
{
if (ctx) {
- grn_array * const array = (grn_array *)GRN_MALLOC(sizeof(grn_array));
+ grn_array * const array = (grn_array *)GRN_CALLOC(sizeof(grn_array));
if (array) {
GRN_DB_OBJ_SET_TYPE(array, GRN_TABLE_NO_KEY);
if (!grn_array_init(ctx, array, path, value_size, flags)) {
@@ -577,7 +580,8 @@ grn_array_open(grn_ctx *ctx, const char *path)
grn_io * const io = grn_io_open(ctx, path, grn_io_auto);
if (io) {
struct grn_array_header * const header = grn_io_header(io);
- if (grn_io_get_type(io) == GRN_TABLE_NO_KEY) {
+ uint32_t io_type = grn_io_get_type(io);
+ if (io_type == GRN_TABLE_NO_KEY) {
grn_array * const array = (grn_array *)GRN_MALLOC(sizeof(grn_array));
if (array) {
if (!(header->flags & GRN_ARRAY_TINY)) {
@@ -599,7 +603,9 @@ grn_array_open(grn_ctx *ctx, const char *path)
GRN_FREE(array);
}
} else {
- ERR(GRN_INVALID_FORMAT, "file type unmatch");
+ ERR(GRN_INVALID_FORMAT,
+ "[table][array] file type must be %#04x: <%#04x>",
+ GRN_TABLE_NO_KEY, io_type);
}
grn_io_close(ctx, io);
}
@@ -607,6 +613,25 @@ grn_array_open(grn_ctx *ctx, const char *path)
return NULL;
}
+/*
+ * grn_array_error_if_truncated() logs an error and returns its error code if
+ * an array is truncated by another process.
+ * Otherwise, this function returns GRN_SUCCESS.
+ * Note that `ctx` and `array` must be valid.
+ *
+ * FIXME: An array should be reopened if possible.
+ */
+static grn_rc
+grn_array_error_if_truncated(grn_ctx *ctx, grn_array *array)
+{
+ if (array->header && array->header->truncated) {
+ ERR(GRN_FILE_CORRUPT,
+ "array is truncated, please unmap or reopen the database");
+ return GRN_FILE_CORRUPT;
+ }
+ return GRN_SUCCESS;
+}
+
grn_rc
grn_array_close(grn_ctx *ctx, grn_array *array)
{
@@ -631,14 +656,33 @@ grn_array_remove(grn_ctx *ctx, const char *path)
return grn_io_remove(ctx, path);
}
+uint32_t
+grn_array_size(grn_ctx *ctx, grn_array *array)
+{
+ if (grn_array_error_if_truncated(ctx, array) != GRN_SUCCESS) {
+ return 0;
+ }
+ return *array->n_entries;
+}
+
+uint32_t
+grn_array_get_flags(grn_ctx *ctx, grn_array *array)
+{
+ return array->header->flags;
+}
+
grn_rc
grn_array_truncate(grn_ctx *ctx, grn_array *array)
{
- grn_rc rc = GRN_SUCCESS;
+ grn_rc rc;
char *path = NULL;
uint32_t value_size, flags;
if (!ctx || !array) { return GRN_INVALID_ARGUMENT; }
+ rc = grn_array_error_if_truncated(ctx, array);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
if (grn_array_is_io_array(array)) {
const char * const io_path = grn_io_path(array->io);
if (io_path && *io_path) {
@@ -653,6 +697,10 @@ grn_array_truncate(grn_ctx *ctx, grn_array *array)
flags = array->obj.header.flags;
if (grn_array_is_io_array(array)) {
+ if (path) {
+ /* Only an I/O array with a valid path uses the `truncated` flag. */
+ array->header->truncated = GRN_TRUE;
+ }
rc = grn_io_close(ctx, array->io);
if (!rc) {
array->io = NULL;
@@ -680,6 +728,9 @@ grn_array_get_value_inline(grn_ctx *ctx, grn_array *array, grn_id id)
if (!ctx || !array) {
return NULL;
}
+ if (grn_array_error_if_truncated(ctx, array) != GRN_SUCCESS) {
+ return NULL;
+ }
if (*array->n_garbages) {
/*
* grn_array_bitmap_at() is a time-consuming function, so it is called only
@@ -717,7 +768,8 @@ inline static grn_rc
grn_array_set_value_inline(grn_ctx *ctx, grn_array *array, grn_id id,
const void *value, int flags)
{
- void * const entry = grn_array_entry_at(ctx, array, id, 0);
+ void *entry;
+ entry = grn_array_entry_at(ctx, array, id, 0);
if (!entry) {
return GRN_NO_MEMORY_AVAILABLE;
}
@@ -760,9 +812,16 @@ grn_rc
grn_array_set_value(grn_ctx *ctx, grn_array *array, grn_id id,
const void *value, int flags)
{
+ grn_rc rc;
+
if (!ctx || !array || !value) {
return GRN_INVALID_ARGUMENT;
}
+
+ rc = grn_array_error_if_truncated(ctx, array);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
if (*array->n_garbages) {
/*
* grn_array_bitmap_at() is a time-consuming function, so it is called only
@@ -781,15 +840,20 @@ grn_rc
grn_array_delete_by_id(grn_ctx *ctx, grn_array *array, grn_id id,
grn_table_delete_optarg *optarg)
{
+ grn_rc rc;
if (!ctx || !array) {
return GRN_INVALID_ARGUMENT;
}
+ rc = grn_array_error_if_truncated(ctx, array);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
if (grn_array_bitmap_at(ctx, array, id) != 1) {
return GRN_INVALID_ARGUMENT;
}
{
- grn_rc rc = GRN_SUCCESS;
+ rc = GRN_SUCCESS;
/* lock */
if (grn_array_is_io_array(array)) {
if (array->value_size >= sizeof(grn_id)) {
@@ -841,6 +905,9 @@ grn_array_delete_by_id(grn_ctx *ctx, grn_array *array, grn_id id,
grn_id
grn_array_at(grn_ctx *ctx, grn_array *array, grn_id id)
{
+ if (grn_array_error_if_truncated(ctx, array) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
if (*array->n_garbages) {
/*
* grn_array_bitmap_at() is a time-consuming function, so it is called only
@@ -881,6 +948,9 @@ grn_array_cursor_open(grn_ctx *ctx, grn_array *array, grn_id min, grn_id max,
{
grn_array_cursor *cursor;
if (!array || !ctx) { return NULL; }
+ if (grn_array_error_if_truncated(ctx, array) != GRN_SUCCESS) {
+ return NULL;
+ }
cursor = (grn_array_cursor *)GRN_MALLOCN(grn_array_cursor, 1);
if (!cursor) { return NULL; }
@@ -958,7 +1028,11 @@ grn_array_cursor_next(grn_ctx *ctx, grn_array_cursor *cursor)
grn_id
grn_array_next(grn_ctx *ctx, grn_array *array, grn_id id)
{
- const grn_id max_id = grn_array_get_max_id(array);
+ grn_id max_id;
+ if (grn_array_error_if_truncated(ctx, array) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
+ max_id = grn_array_get_max_id(array);
while (++id <= max_id) {
if (!*array->n_garbages ||
grn_array_bitmap_at(ctx, array, id) == 1) {
@@ -1037,9 +1111,14 @@ grn_array_add_to_tiny_array(grn_ctx *ctx, grn_array *array, void **value)
inline static grn_id
grn_array_add_to_io_array(grn_ctx *ctx, grn_array *array, void **value)
{
- struct grn_array_header * const header = array->header;
- grn_id id = header->garbages;
+ grn_id id;
void *entry;
+ struct grn_array_header *header;
+ if (grn_array_error_if_truncated(ctx, array) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
+ header = array->header;
+ id = header->garbages;
if (id) {
/* These operations fail iff the array is broken. */
entry = grn_array_io_entry_at(ctx, array, id, GRN_TABLE_ADD);
@@ -1173,7 +1252,15 @@ grn_array_unblock(grn_ctx *ctx, grn_array *array)
(sizeof(grn_id) *\
(GRN_HASH_MAX_KEY_SIZE_LARGE - GRN_HASH_MAX_KEY_SIZE_NORMAL)))
#define GRN_HASH_SEGMENT_SIZE 0x400000
+#define GRN_HASH_KEY_MAX_N_SEGMENTS_NORMAL 0x400
+#define GRN_HASH_KEY_MAX_N_SEGMENTS_LARGE 0x40000
#define W_OF_KEY_IN_A_SEGMENT 22
+#define GRN_HASH_KEY_MAX_TOTAL_SIZE_NORMAL\
+ (((uint64_t)(1) << W_OF_KEY_IN_A_SEGMENT) *\
+ GRN_HASH_KEY_MAX_N_SEGMENTS_NORMAL - 1)
+#define GRN_HASH_KEY_MAX_TOTAL_SIZE_LARGE\
+ (((uint64_t)(1) << W_OF_KEY_IN_A_SEGMENT) *\
+ GRN_HASH_KEY_MAX_N_SEGMENTS_LARGE - 1)
#define IDX_MASK_IN_A_SEGMENT 0xfffff
typedef struct {
@@ -1195,7 +1282,18 @@ typedef struct {
uint32_t offset;
} key;
uint8_t value[1];
-} grn_io_hash_entry;
+} grn_io_hash_entry_normal;
+
+typedef struct {
+ uint32_t hash_value;
+ uint16_t flag;
+ uint16_t key_size;
+ union {
+ uint8_t buf[sizeof(uint64_t)];
+ uint64_t offset;
+ } key;
+ uint8_t value[1];
+} grn_io_hash_entry_large;
typedef struct {
uint32_t hash_value;
@@ -1224,7 +1322,8 @@ typedef union {
grn_hash_entry_header header;
grn_plain_hash_entry plain_entry;
grn_rich_hash_entry rich_entry;
- grn_io_hash_entry io_entry;
+ grn_io_hash_entry_normal io_entry_normal;
+ grn_io_hash_entry_large io_entry_large;
grn_tiny_hash_entry tiny_entry;
} grn_hash_entry;
@@ -1249,8 +1348,6 @@ typedef struct {
uint8_t dummy[1];
} entry_astr;
-#define LOGICAL_MAX_SEGMENT ((GRN_HASH_MAX_SEGMENT) * 4)
-
enum {
GRN_HASH_KEY_SEGMENT = 0,
GRN_HASH_ENTRY_SEGMENT = 1,
@@ -1258,6 +1355,21 @@ enum {
GRN_HASH_BITMAP_SEGMENT = 3
};
+inline static int
+grn_hash_name(grn_ctx *ctx, grn_hash *hash, char *buffer, int buffer_size)
+{
+ int name_size;
+
+ if (DB_OBJ(hash)->id == GRN_ID_NIL) {
+ grn_strcpy(buffer, buffer_size, "(anonymous)");
+ name_size = strlen(buffer);
+ } else {
+ name_size = grn_obj_name(ctx, (grn_obj *)hash, buffer, buffer_size);
+ }
+
+ return name_size;
+}
+
inline static grn_bool
grn_hash_is_io_hash(grn_hash *hash)
{
@@ -1310,7 +1422,7 @@ grn_hash_idx_at(grn_ctx *ctx, grn_hash *hash, grn_id id)
}
inline static void *
-grn_io_hash_key_at(grn_ctx *ctx, grn_hash *hash, uint32_t pos)
+grn_io_hash_key_at(grn_ctx *ctx, grn_hash *hash, uint64_t pos)
{
return grn_io_array_at_inline(ctx, hash->io, GRN_HASH_KEY_SEGMENT,
pos, GRN_TABLE_ADD);
@@ -1335,10 +1447,20 @@ grn_hash_entry_get_key(grn_ctx *ctx, grn_hash *hash, grn_hash_entry *entry)
{
if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
if (grn_hash_is_io_hash(hash)) {
- if (entry->io_entry.flag & HASH_IMMEDIATE) {
- return (char *)entry->io_entry.key.buf;
+ if (grn_hash_is_large_total_key_size(ctx, hash)) {
+ if (entry->io_entry_large.flag & HASH_IMMEDIATE) {
+ return (char *)entry->io_entry_large.key.buf;
+ } else {
+ return (char *)grn_io_hash_key_at(ctx, hash,
+ entry->io_entry_large.key.offset);
+ }
} else {
- return (char *)grn_io_hash_key_at(ctx, hash, entry->io_entry.key.offset);
+ if (entry->io_entry_normal.flag & HASH_IMMEDIATE) {
+ return (char *)entry->io_entry_normal.key.buf;
+ } else {
+ return (char *)grn_io_hash_key_at(ctx, hash,
+ entry->io_entry_normal.key.offset);
+ }
}
} else {
if (entry->tiny_entry.flag & HASH_IMMEDIATE) {
@@ -1357,11 +1479,15 @@ grn_hash_entry_get_key(grn_ctx *ctx, grn_hash *hash, grn_hash_entry *entry)
}
inline static void *
-grn_hash_entry_get_value(grn_hash *hash, grn_hash_entry *entry)
+grn_hash_entry_get_value(grn_ctx *ctx, grn_hash *hash, grn_hash_entry *entry)
{
if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
if (grn_hash_is_io_hash(hash)) {
- return entry->io_entry.value;
+ if (grn_hash_is_large_total_key_size(ctx, hash)) {
+ return entry->io_entry_large.value;
+ } else {
+ return entry->io_entry_normal.value;
+ }
} else {
return entry->tiny_entry.value;
}
@@ -1376,33 +1502,104 @@ grn_hash_entry_get_value(grn_hash *hash, grn_hash_entry *entry)
inline static grn_rc
grn_io_hash_entry_put_key(grn_ctx *ctx, grn_hash *hash,
- grn_io_hash_entry *entry,
+ grn_hash_entry *entry,
const void *key, unsigned int key_size)
{
- uint32_t key_offset;
- if (entry->key_size) {
- key_offset = entry->key.offset;
+ grn_bool is_large_mode;
+ grn_bool key_exist;
+ uint64_t key_offset;
+ grn_io_hash_entry_normal *io_entry_normal = &(entry->io_entry_normal);
+ grn_io_hash_entry_large *io_entry_large = &(entry->io_entry_large);
+
+ is_large_mode = grn_hash_is_large_total_key_size(ctx, hash);
+
+ if (is_large_mode) {
+ key_exist = (io_entry_large->key_size > 0);
+ } else {
+ key_exist = (io_entry_normal->key_size > 0);
+ }
+
+ if (key_exist > 0) {
+ if (is_large_mode) {
+ key_offset = io_entry_large->key.offset;
+ } else {
+ key_offset = io_entry_normal->key.offset;
+ }
} else {
- uint32_t segment_id;
+ uint64_t segment_id;
grn_hash_header_common *header;
+ uint64_t curr_key;
+ uint64_t max_total_size;
header = hash->header.common;
if (key_size >= GRN_HASH_SEGMENT_SIZE) {
- return GRN_INVALID_ARGUMENT;
- }
- key_offset = header->curr_key;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_hash_name(ctx, hash, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[hash][key][put] too long key: <%.*s>: max=%u: key size=%u",
+ name_size, name,
+ GRN_HASH_SEGMENT_SIZE,
+ key_size);
+ return ctx->rc;
+ }
+
+ if (is_large_mode) {
+ curr_key = header->curr_key_large;
+ max_total_size = GRN_HASH_KEY_MAX_TOTAL_SIZE_LARGE;
+ } else {
+ curr_key = header->curr_key_normal;
+ max_total_size = GRN_HASH_KEY_MAX_TOTAL_SIZE_NORMAL;
+ }
+
+ if (key_size > (max_total_size - curr_key)) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_hash_name(ctx, hash, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_NOT_ENOUGH_SPACE,
+ "[hash][key][put] total key size is over: <%.*s>: "
+ "max=%" GRN_FMT_INT64U ": "
+ "current=%" GRN_FMT_INT64U ": "
+ "new key size=%u",
+ name_size, name,
+ max_total_size,
+ curr_key,
+ key_size);
+ return ctx->rc;
+ }
+ key_offset = curr_key;
segment_id = (key_offset + key_size) >> W_OF_KEY_IN_A_SEGMENT;
if ((key_offset >> W_OF_KEY_IN_A_SEGMENT) != segment_id) {
- key_offset = header->curr_key = segment_id << W_OF_KEY_IN_A_SEGMENT;
+ key_offset = segment_id << W_OF_KEY_IN_A_SEGMENT;
+ if (is_large_mode) {
+ header->curr_key_large = key_offset;
+ } else {
+ header->curr_key_normal = key_offset;
+ }
+ }
+ if (is_large_mode) {
+ header->curr_key_large += key_size;
+ io_entry_large->key.offset = key_offset;
+ } else {
+ header->curr_key_normal += key_size;
+ io_entry_normal->key.offset = key_offset;
}
- header->curr_key += key_size;
- entry->key.offset = key_offset;
}
{
void * const key_ptr = grn_io_hash_key_at(ctx, hash, key_offset);
if (!key_ptr) {
- return GRN_NO_MEMORY_AVAILABLE;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_hash_name(ctx, hash, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[hash][key][put] failed to allocate for new key: <%.*s>: "
+ "new offset:%" GRN_FMT_INT64U " "
+ "key size:%u",
+ name_size, name,
+ key_offset,
+ key_size);
+ return ctx->rc;
}
grn_memcpy(key_ptr, key, key_size);
}
@@ -1416,20 +1613,41 @@ grn_hash_entry_put_key(grn_ctx *ctx, grn_hash *hash,
{
if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
if (grn_hash_is_io_hash(hash)) {
- if (key_size <= sizeof(entry->io_entry.key.buf)) {
- grn_memcpy(entry->io_entry.key.buf, key, key_size);
- entry->io_entry.flag = HASH_IMMEDIATE;
+ grn_bool is_large_mode;
+ uint8_t *buffer;
+ size_t buffer_size;
+ uint16_t flag;
+
+ is_large_mode = grn_hash_is_large_total_key_size(ctx, hash);
+ if (is_large_mode) {
+ buffer = entry->io_entry_large.key.buf;
+ buffer_size = sizeof(entry->io_entry_large.key.buf);
+ } else {
+ buffer = entry->io_entry_normal.key.buf;
+ buffer_size = sizeof(entry->io_entry_normal.key.buf);
+ }
+
+ if (key_size <= buffer_size) {
+ grn_memcpy(buffer, key, key_size);
+ flag = HASH_IMMEDIATE;
} else {
const grn_rc rc =
- grn_io_hash_entry_put_key(ctx, hash, (grn_io_hash_entry *)entry,
- key, key_size);
+ grn_io_hash_entry_put_key(ctx, hash, entry, key, key_size);
if (rc) {
return rc;
}
- entry->io_entry.flag = 0;
+ flag = 0;
+ }
+
+ if (is_large_mode) {
+ entry->io_entry_large.flag = flag;
+ entry->io_entry_large.hash_value = hash_value;
+ entry->io_entry_large.key_size = key_size;
+ } else {
+ entry->io_entry_normal.flag = flag;
+ entry->io_entry_normal.hash_value = hash_value;
+ entry->io_entry_normal.key_size = key_size;
}
- entry->io_entry.hash_value = hash_value;
- entry->io_entry.key_size = key_size;
} else {
if (key_size <= sizeof(entry->tiny_entry.key.buf)) {
grn_memcpy(entry->tiny_entry.key.buf, key, key_size);
@@ -1472,12 +1690,22 @@ grn_hash_entry_compare_key(grn_ctx *ctx, grn_hash *hash,
return GRN_FALSE;
}
if (grn_hash_is_io_hash(hash)) {
- if (entry->io_entry.flag & HASH_IMMEDIATE) {
- return !memcmp(key, entry->io_entry.key.buf, key_size);
+ if (grn_hash_is_large_total_key_size(ctx, hash)) {
+ if (entry->io_entry_large.flag & HASH_IMMEDIATE) {
+ return !memcmp(key, entry->io_entry_large.key.buf, key_size);
+ } else {
+ const void * const entry_key_ptr =
+ grn_io_hash_key_at(ctx, hash, entry->io_entry_large.key.offset);
+ return !memcmp(key, entry_key_ptr, key_size);
+ }
} else {
- const void * const entry_key_ptr =
- grn_io_hash_key_at(ctx, hash, entry->io_entry.key.offset);
- return !memcmp(key, entry_key_ptr, key_size);
+ if (entry->io_entry_normal.flag & HASH_IMMEDIATE) {
+ return !memcmp(key, entry->io_entry_normal.key.buf, key_size);
+ } else {
+ const void * const entry_key_ptr =
+ grn_io_hash_key_at(ctx, hash, entry->io_entry_normal.key.offset);
+ return !memcmp(key, entry_key_ptr, key_size);
+ }
}
} else {
if (entry->tiny_entry.flag & HASH_IMMEDIATE) {
@@ -1505,9 +1733,9 @@ get_key(grn_ctx *ctx, grn_hash *hash, entry_str *n)
}
inline static void *
-get_value(grn_hash *hash, entry_str *n)
+get_value(grn_ctx *ctx, grn_hash *hash, entry_str *n)
{
- return grn_hash_entry_get_value(hash, (grn_hash_entry *)n);
+ return grn_hash_entry_get_value(ctx, hash, (grn_hash_entry *)n);
}
inline static grn_rc
@@ -1532,7 +1760,11 @@ grn_io_hash_calculate_entry_size(uint32_t key_size, uint32_t value_size,
uint32_t flags)
{
if (flags & GRN_OBJ_KEY_VAR_SIZE) {
- return (uintptr_t)((grn_io_hash_entry *)0)->value + value_size;
+ if (flags & GRN_OBJ_KEY_LARGE) {
+ return (uintptr_t)((grn_io_hash_entry_large *)0)->value + value_size;
+ } else {
+ return (uintptr_t)((grn_io_hash_entry_normal *)0)->value + value_size;
+ }
} else {
if (key_size == sizeof(uint32_t)) {
return (uintptr_t)((grn_plain_hash_entry *)0)->value + value_size;
@@ -1545,7 +1777,8 @@ grn_io_hash_calculate_entry_size(uint32_t key_size, uint32_t value_size,
static grn_io *
grn_io_hash_create_io(grn_ctx *ctx, const char *path,
- uint32_t header_size, uint32_t entry_size)
+ uint32_t header_size, uint32_t entry_size,
+ uint32_t flags)
{
uint32_t w_of_element = 0;
grn_io_array_spec array_spec[4];
@@ -1555,7 +1788,13 @@ grn_io_hash_create_io(grn_ctx *ctx, const char *path,
}
array_spec[GRN_HASH_KEY_SEGMENT].w_of_element = 0;
- array_spec[GRN_HASH_KEY_SEGMENT].max_n_segments = 0x400;
+ if (flags & GRN_OBJ_KEY_LARGE) {
+ array_spec[GRN_HASH_KEY_SEGMENT].max_n_segments =
+ GRN_HASH_KEY_MAX_N_SEGMENTS_LARGE;
+ } else {
+ array_spec[GRN_HASH_KEY_SEGMENT].max_n_segments =
+ GRN_HASH_KEY_MAX_N_SEGMENTS_NORMAL;
+ }
array_spec[GRN_HASH_ENTRY_SEGMENT].w_of_element = w_of_element;
array_spec[GRN_HASH_ENTRY_SEGMENT].max_n_segments =
1U << (30 - (22 - w_of_element));
@@ -1584,7 +1823,7 @@ grn_io_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path,
}
entry_size = grn_io_hash_calculate_entry_size(key_size, value_size, flags);
- io = grn_io_hash_create_io(ctx, path, header_size, entry_size);
+ io = grn_io_hash_create_io(ctx, path, header_size, entry_size, flags);
if (!io) {
return GRN_NO_MEMORY_AVAILABLE;
}
@@ -1607,7 +1846,8 @@ grn_io_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path,
header->encoding = encoding;
header->key_size = key_size;
header->curr_rec = 0;
- header->curr_key = 0;
+ header->curr_key_normal = 0;
+ header->curr_key_large = 0;
header->lock = 0;
header->idx_offset = 0;
header->value_size = value_size;
@@ -1624,6 +1864,7 @@ grn_io_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path,
hash->normalizer = NULL;
header->normalizer = GRN_ID_NIL;
}
+ header->truncated = GRN_FALSE;
GRN_PTR_INIT(&(hash->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
{
grn_table_queue *queue;
@@ -1635,7 +1876,7 @@ grn_io_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path,
grn_table_queue_init(ctx, queue);
}
- hash->obj.header.flags = header->flags;
+ hash->obj.header.flags = (header->flags & GRN_OBJ_FLAGS_MASK);
hash->ctx = ctx;
hash->encoding = encoding;
hash->value_size = value_size;
@@ -1701,6 +1942,7 @@ grn_tiny_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path,
hash->max_offset = &hash->max_offset_;
hash->max_offset_ = INITIAL_INDEX_SIZE - 1;
hash->io = NULL;
+ hash->header.common = NULL;
hash->n_garbages_ = 0;
hash->n_entries_ = 0;
hash->garbages = GRN_ID_NIL;
@@ -1736,7 +1978,7 @@ grn_hash_create(grn_ctx *ctx, const char *path, uint32_t key_size, uint32_t valu
if (key_size > GRN_HASH_MAX_KEY_SIZE_LARGE) {
return NULL;
}
- hash = (grn_hash *)GRN_MALLOC(sizeof(grn_hash));
+ hash = (grn_hash *)GRN_CALLOC(sizeof(grn_hash));
if (!hash) {
return NULL;
}
@@ -1755,7 +1997,8 @@ grn_hash_open(grn_ctx *ctx, const char *path)
grn_io * const io = grn_io_open(ctx, path, grn_io_auto);
if (io) {
grn_hash_header_common * const header = grn_io_header(io);
- if (grn_io_get_type(io) == GRN_TABLE_HASH_KEY) {
+ uint32_t io_type = grn_io_get_type(io);
+ if (io_type == GRN_TABLE_HASH_KEY) {
grn_hash * const hash = (grn_hash *)GRN_MALLOC(sizeof(grn_hash));
if (hash) {
if (!(header->flags & GRN_HASH_TINY)) {
@@ -1789,7 +2032,9 @@ grn_hash_open(grn_ctx *ctx, const char *path)
GRN_FREE(hash);
}
} else {
- ERR(GRN_INVALID_FORMAT, "file type unmatch");
+ ERR(GRN_INVALID_FORMAT,
+ "[table][hash] file type must be %#04x: <%#04x>",
+ GRN_TABLE_HASH_KEY, io_type);
}
grn_io_close(ctx, io);
}
@@ -1797,6 +2042,25 @@ grn_hash_open(grn_ctx *ctx, const char *path)
return NULL;
}
+/*
+ * grn_hash_error_if_truncated() logs an error and returns its error code if
+ * a hash is truncated by another process.
+ * Otherwise, this function returns GRN_SUCCESS.
+ * Note that `ctx` and `hash` must be valid.
+ *
+ * FIXME: A hash should be reopened if possible.
+ */
+static grn_rc
+grn_hash_error_if_truncated(grn_ctx *ctx, grn_hash *hash)
+{
+ if (hash->header.common && hash->header.common->truncated) {
+ ERR(GRN_FILE_CORRUPT,
+ "hash is truncated, please unmap or reopen the database");
+ return GRN_FILE_CORRUPT;
+ }
+ return GRN_SUCCESS;
+}
+
static grn_rc
grn_tiny_hash_fin(grn_ctx *ctx, grn_hash *hash)
{
@@ -1835,7 +2099,7 @@ grn_hash_close(grn_ctx *ctx, grn_hash *hash)
if (!ctx || !hash) { return GRN_INVALID_ARGUMENT; }
if (grn_hash_is_io_hash(hash)) {
rc = grn_io_close(ctx, hash->io);
- GRN_PTR_INIT(&(hash->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
+ GRN_OBJ_FIN(ctx, &(hash->token_filters));
} else {
GRN_ASSERT(ctx == hash->ctx);
rc = grn_tiny_hash_fin(ctx, hash);
@@ -1854,13 +2118,17 @@ grn_hash_remove(grn_ctx *ctx, const char *path)
grn_rc
grn_hash_truncate(grn_ctx *ctx, grn_hash *hash)
{
- grn_rc rc = GRN_SUCCESS;
+ grn_rc rc;
char *path = NULL;
uint32_t key_size, value_size, flags;
if (!ctx || !hash) {
return GRN_INVALID_ARGUMENT;
}
+ rc = grn_hash_error_if_truncated(ctx, hash);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
if (grn_hash_is_io_hash(hash)) {
const char * const io_path = grn_io_path(hash->io);
@@ -1877,6 +2145,10 @@ grn_hash_truncate(grn_ctx *ctx, grn_hash *hash)
flags = hash->obj.header.flags;
if (grn_hash_is_io_hash(hash)) {
+ if (path) {
+ /* Only an I/O hash with a valid path uses the `truncated` flag. */
+ hash->header.common->truncated = GRN_TRUE;
+ }
rc = grn_io_close(ctx, hash->io);
if (!rc) {
hash->io = NULL;
@@ -1884,6 +2156,7 @@ grn_hash_truncate(grn_ctx *ctx, grn_hash *hash)
rc = grn_io_remove(ctx, path);
}
}
+ GRN_OBJ_FIN(ctx, &(hash->token_filters));
}
if (!rc) {
rc = grn_hash_init(ctx, hash, path, key_size, value_size, flags);
@@ -2054,6 +2327,15 @@ grn_hash_clear_lock(grn_ctx *ctx, grn_hash *hash)
return GRN_SUCCESS;
}
+uint32_t
+grn_hash_size(grn_ctx *ctx, grn_hash *hash)
+{
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return 0;
+ }
+ return *hash->n_entries;
+}
+
inline static grn_id
grn_io_hash_add(grn_ctx *ctx, grn_hash *hash, uint32_t hash_value,
const void *key, unsigned int key_size, void **value)
@@ -2078,7 +2360,11 @@ grn_io_hash_add(grn_ctx *ctx, grn_hash *hash, uint32_t hash_value,
garbages[key_size - 1] = *(grn_id *)entry;
if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
/* keep entry->io_entry's hash_value, flag, key_size and key. */
- memset(entry->io_entry.value, 0, header->value_size);
+ if (grn_hash_is_large_total_key_size(ctx, hash)) {
+ memset(entry->io_entry_large.value, 0, header->value_size);
+ } else {
+ memset(entry->io_entry_normal.value, 0, header->value_size);
+ }
} else {
memset(entry, 0, header->entry_size);
}
@@ -2096,11 +2382,12 @@ grn_io_hash_add(grn_ctx *ctx, grn_hash *hash, uint32_t hash_value,
}
if (grn_hash_entry_put_key(ctx, hash, entry, hash_value, key, key_size)) {
- /* TODO: error handling. */
+ grn_hash_delete_by_id(ctx, hash, entry_id, NULL);
+ return GRN_ID_NIL;
}
if (value) {
- *value = grn_hash_entry_get_value(hash, entry);
+ *value = grn_hash_entry_get_value(ctx, hash, entry);
}
return entry_id;
}
@@ -2133,7 +2420,7 @@ grn_tiny_hash_add(grn_ctx *ctx, grn_hash *hash, uint32_t hash_value,
}
if (value) {
- *value = grn_hash_entry_get_value(hash, entry);
+ *value = grn_hash_entry_get_value(ctx, hash, entry);
}
return entry_id;
}
@@ -2143,6 +2430,9 @@ grn_hash_add(grn_ctx *ctx, grn_hash *hash, const void *key,
unsigned int key_size, void **value, int *added)
{
uint32_t hash_value;
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
if (!key || !key_size) {
return GRN_ID_NIL;
}
@@ -2172,6 +2462,10 @@ grn_hash_add(grn_ctx *ctx, grn_hash *hash, const void *key,
/* lock */
if ((*hash->n_entries + *hash->n_garbages) * 2 > *hash->max_offset) {
+ if (*hash->max_offset > (1 << 29)) {
+ ERR(GRN_TOO_LARGE_OFFSET, "hash table size limit");
+ return GRN_ID_NIL;
+ }
grn_hash_reset(ctx, hash, 0);
}
@@ -2198,7 +2492,7 @@ grn_hash_add(grn_ctx *ctx, grn_hash *hash, const void *key,
if (grn_hash_entry_compare_key(ctx, hash, entry, hash_value,
key, key_size)) {
if (value) {
- *value = grn_hash_entry_get_value(hash, entry);
+ *value = grn_hash_entry_get_value(ctx, hash, entry);
}
if (added) {
*added = 0;
@@ -2235,6 +2529,9 @@ grn_hash_get(grn_ctx *ctx, grn_hash *hash, const void *key,
unsigned int key_size, void **value)
{
uint32_t hash_value;
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
if (key_size > hash->key_size) {
return GRN_ID_NIL;
@@ -2270,7 +2567,7 @@ grn_hash_get(grn_ctx *ctx, grn_hash *hash, const void *key,
if (grn_hash_entry_compare_key(ctx, hash, entry, hash_value,
key, key_size)) {
if (value) {
- *value = grn_hash_entry_get_value(hash, entry);
+ *value = grn_hash_entry_get_value(ctx, hash, entry);
}
return id;
}
@@ -2305,7 +2602,11 @@ int
grn_hash_get_key(grn_ctx *ctx, grn_hash *hash, grn_id id, void *keybuf, int bufsize)
{
int key_size;
- grn_hash_entry * const entry = grn_hash_get_entry(ctx, hash, id);
+ grn_hash_entry *entry;
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return 0;
+ }
+ entry = grn_hash_get_entry(ctx, hash, id);
if (!entry) {
return 0;
}
@@ -2321,7 +2622,11 @@ grn_hash_get_key2(grn_ctx *ctx, grn_hash *hash, grn_id id, grn_obj *bulk)
{
int key_size;
char *key;
- grn_hash_entry * const entry = grn_hash_get_entry(ctx, hash, id);
+ grn_hash_entry *entry;
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return 0;
+ }
+ entry = grn_hash_get_entry(ctx, hash, id);
if (!entry) {
return 0;
}
@@ -2340,11 +2645,15 @@ int
grn_hash_get_value(grn_ctx *ctx, grn_hash *hash, grn_id id, void *valuebuf)
{
void *value;
- grn_hash_entry * const entry = grn_hash_get_entry(ctx, hash, id);
+ grn_hash_entry *entry;
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return 0;
+ }
+ entry = grn_hash_get_entry(ctx, hash, id);
if (!entry) {
return 0;
}
- value = grn_hash_entry_get_value(hash, entry);
+ value = grn_hash_entry_get_value(ctx, hash, entry);
if (!value) {
return 0;
}
@@ -2358,15 +2667,21 @@ const char *
grn_hash_get_value_(grn_ctx *ctx, grn_hash *hash, grn_id id, uint32_t *size)
{
const void *value;
- grn_hash_entry * const entry = grn_hash_get_entry(ctx, hash, id);
+ grn_hash_entry *entry;
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return NULL;
+ }
+ entry = grn_hash_get_entry(ctx, hash, id);
if (!entry) {
return NULL;
}
- value = grn_hash_entry_get_value(hash, entry);
+ value = grn_hash_entry_get_value(ctx, hash, entry);
if (!value) {
return NULL;
}
- *size = hash->value_size;
+ if (size) {
+ *size = hash->value_size;
+ }
return (const char *)value;
}
@@ -2376,7 +2691,11 @@ grn_hash_get_key_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
{
void *value;
int key_size;
- grn_hash_entry * const entry = grn_hash_get_entry(ctx, hash, id);
+ grn_hash_entry *entry;
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return 0;
+ }
+ entry = grn_hash_get_entry(ctx, hash, id);
if (!entry) {
return 0;
}
@@ -2384,7 +2703,7 @@ grn_hash_get_key_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
if (bufsize >= key_size) {
grn_memcpy(keybuf, grn_hash_entry_get_key(ctx, hash, entry), key_size);
}
- value = grn_hash_entry_get_value(hash, entry);
+ value = grn_hash_entry_get_value(ctx, hash, entry);
if (!value) {
return 0;
}
@@ -2399,13 +2718,17 @@ _grn_hash_get_key_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
void **key, void **value)
{
int key_size;
- grn_hash_entry * const entry = grn_hash_get_entry(ctx, hash, id);
+ grn_hash_entry *entry;
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return 0;
+ }
+ entry = grn_hash_get_entry(ctx, hash, id);
if (!entry) {
return 0;
}
key_size = grn_hash_entry_get_key_size(hash, entry);
*key = grn_hash_entry_get_key(ctx, hash, entry);
- *value = grn_hash_entry_get_value(hash, entry);
+ *value = grn_hash_entry_get_value(ctx, hash, entry);
return *value ? key_size : 0;
}
@@ -2415,6 +2738,9 @@ grn_hash_set_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
{
void *entry_value;
grn_hash_entry *entry;
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
if (!value) {
return GRN_INVALID_ARGUMENT;
}
@@ -2422,7 +2748,7 @@ grn_hash_set_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
if (!entry) {
return GRN_NO_MEMORY_AVAILABLE;
}
- entry_value = grn_hash_entry_get_value(hash, entry);
+ entry_value = grn_hash_entry_get_value(ctx, hash, entry);
if (!entry_value) {
return GRN_NO_MEMORY_AVAILABLE;
}
@@ -2493,8 +2819,13 @@ grn_hash_delete_by_id(grn_ctx *ctx, grn_hash *hash, grn_id id,
grn_table_delete_optarg *optarg)
{
entry_str *ee;
- grn_rc rc = GRN_INVALID_ARGUMENT;
- if (!hash || !id) { return rc; }
+ grn_rc rc;
+ if (!hash || !id) { return GRN_INVALID_ARGUMENT; }
+ rc = grn_hash_error_if_truncated(ctx, hash);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = GRN_INVALID_ARGUMENT;
/* lock */
ee = grn_hash_entry_at(ctx, hash, id, 0);
if (ee) {
@@ -2519,7 +2850,11 @@ grn_hash_delete(grn_ctx *ctx, grn_hash *hash, const void *key, uint32_t key_size
grn_table_delete_optarg *optarg)
{
uint32_t h, i, m, s;
- grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_rc rc = grn_hash_error_if_truncated(ctx, hash);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = GRN_INVALID_ARGUMENT;
if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
if (key_size > hash->key_size) { return GRN_INVALID_ARGUMENT; }
h = grn_hash_calculate_hash_value(key, key_size);
@@ -2581,6 +2916,9 @@ grn_hash_cursor_open(grn_ctx *ctx, grn_hash *hash,
{
grn_hash_cursor *c;
if (!hash || !ctx) { return NULL; }
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return NULL;
+ }
if (!(c = GRN_MALLOCN(grn_hash_cursor, 1))) { return NULL; }
GRN_DB_OBJ_SET_TYPE(c, GRN_CURSOR_TABLE_HASH_KEY);
c->hash = hash;
@@ -2695,7 +3033,7 @@ grn_hash_cursor_get_value(grn_ctx *ctx, grn_hash_cursor *c, void **value)
entry_str *ee;
if (!c) { return 0; }
ee = grn_hash_entry_at(ctx, c->hash, c->curr_rec, 0);
- if (ee && (v = get_value(c->hash, ee))) {
+ if (ee && (v = get_value(ctx, c->hash, ee))) {
*value = v;
return c->hash->value_size;
}
@@ -2714,7 +3052,7 @@ grn_hash_cursor_get_key_value(grn_ctx *ctx, grn_hash_cursor *c,
*key_size = (c->hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) ? ee->size : c->hash->key_size;
}
if (key) { *key = get_key(ctx, c->hash, ee); }
- if (value) { *value = get_value(c->hash, ee); }
+ if (value) { *value = get_value(ctx, c->hash, ee); }
return c->hash->value_size;
}
@@ -2738,7 +3076,7 @@ grn_hash_cursor_delete(grn_ctx *ctx, grn_hash_cursor *c,
#define PREPARE_VAL(e,ep,es) do {\
if ((arg->flags & GRN_TABLE_SORT_BY_VALUE)) {\
- ep = ((const uint8_t *)(get_value(hash, (entry_str *)(e))));\
+ ep = ((const uint8_t *)(get_value(ctx, hash, (entry_str *)(e))));\
es = hash->value_size;\
} else {\
ep = ((const uint8_t *)(get_key(ctx, hash, (entry_str *)(e))));\
@@ -2896,7 +3234,7 @@ typedef struct {
(ep)->v = (arg->flags & GRN_TABLE_SORT_BY_ID)\
? (int32_t) id\
: (*((int32_t *)((byte *)((arg->flags & GRN_TABLE_SORT_BY_VALUE)\
- ? get_value(hash, (e))\
+ ? get_value(ctx, hash, (e))\
: get_key(ctx, hash, (e))) + arg->offset)));\
} while (0)
@@ -3032,6 +3370,9 @@ grn_hash_sort(grn_ctx *ctx, grn_hash *hash,
{
entry **res;
if (!result || !*hash->n_entries) { return 0; }
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return 0;
+ }
if (!(res = GRN_MALLOC(sizeof(entry *) * *hash->n_entries))) {
GRN_LOG(ctx, GRN_LOG_ALERT, "allocation of entries failed on grn_hash_sort !");
return 0;
@@ -3096,8 +3437,11 @@ grn_hash_check(grn_ctx *ctx, grn_hash *hash)
{
char buf[8];
grn_hash_header_common *h = hash->header.common;
+ if (grn_hash_error_if_truncated(ctx, hash) != GRN_SUCCESS) {
+ return;
+ }
GRN_OUTPUT_ARRAY_OPEN("RESULT", 1);
- GRN_OUTPUT_MAP_OPEN("SUMMARY", 25);
+ GRN_OUTPUT_MAP_OPEN("SUMMARY", 26);
GRN_OUTPUT_CSTR("flags");
grn_itoh(h->flags, buf, 8);
GRN_OUTPUT_STR(buf, 8);
@@ -3111,8 +3455,10 @@ grn_hash_check(grn_ctx *ctx, grn_hash *hash)
GRN_OUTPUT_INT64(h->normalizer);
GRN_OUTPUT_CSTR("curr_rec");
GRN_OUTPUT_INT64(h->curr_rec);
- GRN_OUTPUT_CSTR("curr_key");
- GRN_OUTPUT_INT64(h->curr_key);
+ GRN_OUTPUT_CSTR("curr_key_normal");
+ GRN_OUTPUT_UINT64(h->curr_key_normal);
+ GRN_OUTPUT_CSTR("curr_key_large");
+ GRN_OUTPUT_UINT64(h->curr_key_large);
GRN_OUTPUT_CSTR("idx_offset");
GRN_OUTPUT_INT64(h->idx_offset);
GRN_OUTPUT_CSTR("entry_size");
@@ -3319,7 +3665,7 @@ grn_rhash_group(grn_hash *s, int limit, grn_group_optarg *optarg)
}
grn_rc
-grn_rhash_subrec_info(grn_hash *s, grn_id rh, int index,
+grn_rhash_subrec_info(grn_ctx *ctx, grn_hash *s, grn_id rh, int index,
grn_id *rid, int *section, int *pos, int *score, void **subrec)
{
grn_rset_posinfo *pi;
@@ -3333,7 +3679,7 @@ grn_rhash_subrec_info(grn_hash *s, grn_id rh, int index,
ee = grn_hash_entry_at(ctx, s, rh, 0);
if (!ee) { return GRN_INVALID_ARGUMENT; }
pi = (grn_rset_posinfo *)get_key(ctx, s, ee);
- ri = get_value(s, ee);
+ ri = get_value(ctx, s, ee);
if (!pi || !ri) { return GRN_INVALID_ARGUMENT; }
}
if (index >= ri->n_subrecs) { return GRN_INVALID_ARGUMENT; }
@@ -3380,3 +3726,29 @@ grn_rhash_subrec_info(grn_hash *s, grn_id rh, int index,
return GRN_SUCCESS;
}
#endif /* USE_GRN_INDEX2 */
+
+grn_bool
+grn_hash_is_large_total_key_size(grn_ctx *ctx, grn_hash *hash)
+{
+ return (hash->header.common->flags & GRN_OBJ_KEY_LARGE) == GRN_OBJ_KEY_LARGE;
+}
+
+uint64_t
+grn_hash_total_key_size(grn_ctx *ctx, grn_hash *hash)
+{
+ if (grn_hash_is_large_total_key_size(ctx, hash)) {
+ return hash->header.common->curr_key_large;
+ } else {
+ return hash->header.common->curr_key_normal;
+ }
+}
+
+uint64_t
+grn_hash_max_total_key_size(grn_ctx *ctx, grn_hash *hash)
+{
+ if (grn_hash_is_large_total_key_size(ctx, hash)) {
+ return GRN_HASH_KEY_MAX_TOTAL_SIZE_LARGE;
+ } else {
+ return GRN_HASH_KEY_MAX_TOTAL_SIZE_NORMAL;
+ }
+}
diff --git a/storage/mroonga/vendor/groonga/lib/icudump.c b/storage/mroonga/vendor/groonga/lib/icudump.c
index 2cbc15c249c..233aef7bfef 100644
--- a/storage/mroonga/vendor/groonga/lib/icudump.c
+++ b/storage/mroonga/vendor/groonga/lib/icudump.c
@@ -156,14 +156,14 @@ enum {
};
static const char *ctypes[] = {
- "grn_str_null",
- "grn_str_alpha",
- "grn_str_digit",
- "grn_str_symbol",
- "grn_str_hiragana",
- "grn_str_katakana",
- "grn_str_kanji",
- "grn_str_others"
+ "GRN_CHAR_NULL",
+ "GRN_CHAR_ALPHA",
+ "GRN_CHAR_DIGIT",
+ "GRN_CHAR_SYMBOL",
+ "GRN_CHAR_HIRAGANA",
+ "GRN_CHAR_KATAKANA",
+ "GRN_CHAR_KANJI",
+ "GRN_CHAR_OTHERS"
};
void
@@ -259,12 +259,13 @@ struct option options[] = {
{"nfkc", 0, NULL, 'C'},
{"cc", 0, NULL, 'o'},
{"gc", 0, NULL, 'g'},
+ {"version", 0, NULL, 'v'},
};
int
main(int argc, char **argv)
{
- switch (getopt_long(argc, argv, "bdDcCog", options, NULL)) {
+ switch (getopt_long(argc, argv, "bdDcCogv", options, NULL)) {
case 'b' :
blockcode();
break;
@@ -286,8 +287,11 @@ main(int argc, char **argv)
case 'g' :
gcdump();
break;
+ case 'v' :
+ printf("%s\n", U_UNICODE_VERSION);
+ break;
default :
- fputs("usage: icudump --[bc|nfd|nfkd|nfc|nfkc|cc|gc]\n", stderr);
+ fputs("usage: icudump --[bc|nfd|nfkd|nfc|nfkc|cc|gc|version]\n", stderr);
break;
}
return 0;
diff --git a/storage/mroonga/vendor/groonga/lib/id.c b/storage/mroonga/vendor/groonga/lib/id.c
new file mode 100644
index 00000000000..5cf96c8a08f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/id.c
@@ -0,0 +1,36 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn.h"
+#include "grn_db.h"
+
+grn_bool
+grn_id_is_builtin(grn_ctx *ctx, grn_id id)
+{
+ if (id == GRN_ID_NIL) {
+ return GRN_FALSE;
+ } else {
+ return id < GRN_N_RESERVED_TYPES;
+ }
+}
+
+grn_bool
+grn_id_is_builtin_type(grn_ctx *ctx, grn_id id)
+{
+ return GRN_DB_OBJECT <= id && id <= GRN_DB_WGS84_GEO_POINT;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ii.c b/storage/mroonga/vendor/groonga/lib/ii.c
index df6e4ba3a34..cdde01f149d 100644
--- a/storage/mroonga/vendor/groonga/lib/ii.c
+++ b/storage/mroonga/vendor/groonga/lib/ii.c
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -19,7 +20,6 @@
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
-#include <math.h>
#ifdef WIN32
# include <io.h>
@@ -41,10 +41,18 @@
#ifdef GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH
# include "grn_string.h"
-# include <oniguruma.h>
+# include <onigmo.h>
#endif
#define MAX_PSEG 0x20000
+#define MAX_PSEG_SMALL 0x00200
+/* MAX_PSEG_MEDIUM has enough space for the following source:
+ * * Single source.
+ * * Source is a fixed size column or _key of a table.
+ * * Source column is a scalar column.
+ * * Lexicon doesn't have tokenizer.
+ */
+#define MAX_PSEG_MEDIUM 0x10000
#define S_CHUNK (1 << GRN_II_W_CHUNK)
#define W_SEGMENT 18
#define S_SEGMENT (1 << W_SEGMENT)
@@ -52,7 +60,6 @@
#define S_ARRAY_ELEMENT (1 << W_ARRAY_ELEMENT)
#define W_ARRAY (W_SEGMENT - W_ARRAY_ELEMENT)
#define ARRAY_MASK_IN_A_SEGMENT ((1 << W_ARRAY) - 1)
-#define NOT_ASSIGNED 0xffffffff
#define S_GARBAGE (1<<12)
@@ -61,12 +68,25 @@
#define MAX_N_ELEMENTS 5
+#define DEFINE_NAME(ii) \
+ const char *name; \
+ char name_buffer[GRN_TABLE_MAX_KEY_SIZE]; \
+ int name_size; \
+ do { \
+ if (DB_OBJ(ii)->id == GRN_ID_NIL) { \
+ name = "(temporary)"; \
+ name_size = strlen(name); \
+ } else { \
+ name_size = grn_obj_name(ctx, (grn_obj *)ii, \
+ name_buffer, GRN_TABLE_MAX_KEY_SIZE); \
+ name = name_buffer; \
+ } \
+ } while (GRN_FALSE)
+
#define LSEG(pos) ((pos) >> 16)
#define LPOS(pos) (((pos) & 0xffff) << 2)
#define SEG2POS(seg,pos) ((((uint32_t)(seg)) << 16) + (((uint32_t)(pos)) >> 2))
-#define NEXT_ADDR(p) (((byte *)(p)) + sizeof(*(p)))
-
#ifndef S_IRUSR
# define S_IRUSR 0400
#endif /* S_IRUSR */
@@ -74,8 +94,13 @@
# define S_IWUSR 0200
#endif /* S_IWUSR */
-static grn_bool grn_ii_cursor_set_min_enable = GRN_FALSE;
+static grn_bool grn_ii_cursor_set_min_enable = GRN_TRUE;
static double grn_ii_select_too_many_index_match_ratio = -1;
+static double grn_ii_estimate_size_for_query_reduce_ratio = 0.9;
+static grn_bool grn_ii_overlap_token_skip_enable = GRN_FALSE;
+static uint32_t grn_ii_builder_block_threshold_force = 0;
+static uint32_t grn_ii_max_n_segments_small = MAX_PSEG_SMALL;
+static uint32_t grn_ii_max_n_chunks_small = GRN_II_MAX_CHUNK_SMALL;
void
grn_ii_init_from_env(void)
@@ -85,10 +110,10 @@ grn_ii_init_from_env(void)
grn_getenv("GRN_II_CURSOR_SET_MIN_ENABLE",
grn_ii_cursor_set_min_enable_env,
GRN_ENV_BUFFER_SIZE);
- if (grn_ii_cursor_set_min_enable_env[0]) {
- grn_ii_cursor_set_min_enable = GRN_TRUE;
- } else {
+ if (strcmp(grn_ii_cursor_set_min_enable_env, "no") == 0) {
grn_ii_cursor_set_min_enable = GRN_FALSE;
+ } else {
+ grn_ii_cursor_set_min_enable = GRN_TRUE;
}
}
@@ -102,6 +127,91 @@ grn_ii_init_from_env(void)
atof(grn_ii_select_too_many_index_match_ratio_env);
}
}
+
+ {
+ char grn_ii_estimate_size_for_query_reduce_ratio_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_II_ESTIMATE_SIZE_FOR_QUERY_REDUCE_RATIO",
+ grn_ii_estimate_size_for_query_reduce_ratio_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_ii_estimate_size_for_query_reduce_ratio_env[0]) {
+ grn_ii_estimate_size_for_query_reduce_ratio =
+ atof(grn_ii_estimate_size_for_query_reduce_ratio_env);
+ }
+ }
+
+ {
+ char grn_ii_overlap_token_skip_enable_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_II_OVERLAP_TOKEN_SKIP_ENABLE",
+ grn_ii_overlap_token_skip_enable_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_ii_overlap_token_skip_enable_env[0]) {
+ grn_ii_overlap_token_skip_enable = GRN_TRUE;
+ } else {
+ grn_ii_overlap_token_skip_enable = GRN_FALSE;
+ }
+ }
+
+ {
+ char grn_ii_builder_block_threshold_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_II_BUILDER_BLOCK_THRESHOLD",
+ grn_ii_builder_block_threshold_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_ii_builder_block_threshold_env[0]) {
+ grn_ii_builder_block_threshold_force =
+ grn_atoui(grn_ii_builder_block_threshold_env,
+ grn_ii_builder_block_threshold_env +
+ strlen(grn_ii_builder_block_threshold_env),
+ NULL);
+ } else {
+ grn_ii_builder_block_threshold_force = 0;
+ }
+ }
+
+ {
+ char grn_ii_max_n_segments_small_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_II_MAX_N_SEGMENTS_SMALL",
+ grn_ii_max_n_segments_small_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_ii_max_n_segments_small_env[0]) {
+ grn_ii_max_n_segments_small =
+ grn_atoui(grn_ii_max_n_segments_small_env,
+ grn_ii_max_n_segments_small_env +
+ strlen(grn_ii_max_n_segments_small_env),
+ NULL);
+ if (grn_ii_max_n_segments_small > MAX_PSEG) {
+ grn_ii_max_n_segments_small = MAX_PSEG;
+ }
+ }
+ }
+
+ {
+ char grn_ii_max_n_chunks_small_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_II_MAX_N_CHUNKS_SMALL",
+ grn_ii_max_n_chunks_small_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_ii_max_n_chunks_small_env[0]) {
+ grn_ii_max_n_chunks_small =
+ grn_atoui(grn_ii_max_n_chunks_small_env,
+ grn_ii_max_n_chunks_small_env +
+ strlen(grn_ii_max_n_chunks_small_env),
+ NULL);
+ if (grn_ii_max_n_chunks_small > GRN_II_MAX_CHUNK) {
+ grn_ii_max_n_chunks_small = GRN_II_MAX_CHUNK;
+ }
+ }
+ }
+}
+
+void
+grn_ii_cursor_set_min_enable_set(grn_bool enable)
+{
+ grn_ii_cursor_set_min_enable = enable;
+}
+
+grn_bool
+grn_ii_cursor_set_min_enable_get(void)
+{
+ return grn_ii_cursor_set_min_enable;
}
/* segment */
@@ -119,24 +229,28 @@ segment_get(grn_ctx *ctx, grn_ii *ii)
if (!pseg) {
int i;
uint32_t pmax = 0;
- char *used = GRN_CALLOC(MAX_PSEG);
- if (!used) { return MAX_PSEG; }
- for (i = 0; i < GRN_II_MAX_LSEG; i++) {
- if ((pseg = ii->header->ainfo[i]) != NOT_ASSIGNED) {
+ char *used;
+ uint32_t max_segment = ii->seg->header->max_segment;
+ used = GRN_CALLOC(max_segment);
+ if (!used) { return max_segment; }
+ for (i = 0; i < GRN_II_MAX_LSEG && i < max_segment; i++) {
+ if ((pseg = ii->header->ainfo[i]) != GRN_II_PSEG_NOT_ASSIGNED) {
if (pseg > pmax) { pmax = pseg; }
used[pseg] = 1;
}
- if ((pseg = ii->header->binfo[i]) != NOT_ASSIGNED) {
+ if ((pseg = ii->header->binfo[i]) != GRN_II_PSEG_NOT_ASSIGNED) {
if (pseg > pmax) { pmax = pseg; }
used[pseg] = 1;
}
}
- for (pseg = 0; pseg < MAX_PSEG && used[pseg]; pseg++) ;
+ for (pseg = 0; pseg < max_segment && used[pseg]; pseg++) ;
GRN_FREE(used);
ii->header->pnext = pmax + 1;
} else
#endif /* CUT_OFF_COMPATIBILITY */
- if (ii->header->pnext < MAX_PSEG) { ii->header->pnext++; }
+ if (ii->header->pnext < ii->seg->header->max_segment) {
+ ii->header->pnext++;
+ }
}
return pseg;
}
@@ -145,7 +259,7 @@ inline static grn_rc
segment_get_clear(grn_ctx *ctx, grn_ii *ii, uint32_t *pseg)
{
uint32_t seg = segment_get(ctx, ii);
- if (seg < MAX_PSEG) {
+ if (seg < ii->seg->header->max_segment) {
void *p = NULL;
GRN_IO_SEG_REF(ii->seg, seg, p);
if (!p) { return GRN_NO_MEMORY_AVAILABLE; }
@@ -163,19 +277,19 @@ buffer_segment_new(grn_ctx *ctx, grn_ii *ii, uint32_t *segno)
{
uint32_t lseg, pseg;
if (*segno < GRN_II_MAX_LSEG) {
- if (ii->header->binfo[*segno] != NOT_ASSIGNED) {
+ if (ii->header->binfo[*segno] != GRN_II_PSEG_NOT_ASSIGNED) {
return GRN_INVALID_ARGUMENT;
}
lseg = *segno;
} else {
for (lseg = 0; lseg < GRN_II_MAX_LSEG; lseg++) {
- if (ii->header->binfo[lseg] == NOT_ASSIGNED) { break; }
+ if (ii->header->binfo[lseg] == GRN_II_PSEG_NOT_ASSIGNED) { break; }
}
if (lseg == GRN_II_MAX_LSEG) { return GRN_NO_MEMORY_AVAILABLE; }
*segno = lseg;
}
pseg = segment_get(ctx, ii);
- if (pseg < MAX_PSEG) {
+ if (pseg < ii->seg->header->max_segment) {
ii->header->binfo[lseg] = pseg;
if (lseg >= ii->header->bmax) { ii->header->bmax = lseg + 1; }
return GRN_SUCCESS;
@@ -191,44 +305,87 @@ buffer_segment_reserve(grn_ctx *ctx, grn_ii *ii,
{
uint32_t i = 0;
for (;; i++) {
- if (i == GRN_II_MAX_LSEG) { return GRN_NO_MEMORY_AVAILABLE; }
- if (ii->header->binfo[i] == NOT_ASSIGNED) { break; }
+ if (i == GRN_II_MAX_LSEG) {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][segment][reserve] "
+ "couldn't find a free buffer: <%.*s>: max:<%u>",
+ name_size, name,
+ GRN_II_MAX_LSEG);
+ return ctx->rc;
+ }
+ if (ii->header->binfo[i] == GRN_II_PSEG_NOT_ASSIGNED) { break; }
}
*lseg0 = i++;
for (;; i++) {
- if (i == GRN_II_MAX_LSEG) { return GRN_NO_MEMORY_AVAILABLE; }
- if (ii->header->binfo[i] == NOT_ASSIGNED) { break; }
+ if (i == GRN_II_MAX_LSEG) {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][segment][reserve] "
+ "couldn't find two free buffers: "
+ "<%.*s>: "
+ "found:<%u>, max:<%u>",
+ name_size, name,
+ *lseg0, GRN_II_MAX_LSEG);
+ return ctx->rc;
+ }
+ if (ii->header->binfo[i] == GRN_II_PSEG_NOT_ASSIGNED) { break; }
}
*lseg1 = i;
- if ((*pseg0 = segment_get(ctx, ii)) == MAX_PSEG) { return GRN_NO_MEMORY_AVAILABLE; }
- if ((*pseg1 = segment_get(ctx, ii)) == MAX_PSEG) { return GRN_NO_MEMORY_AVAILABLE; }
+ if ((*pseg0 = segment_get(ctx, ii)) == ii->seg->header->max_segment) {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][segment][reserve] "
+ "couldn't allocate a free segment: <%.*s>: "
+ "buffer:<%u>, max:<%u>",
+ name_size, name,
+ *lseg0, ii->seg->header->max_segment);
+ return ctx->rc;
+ }
+ if ((*pseg1 = segment_get(ctx, ii)) == ii->seg->header->max_segment) {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][segment][reserve] "
+ "couldn't allocate two free segments: "
+ "<%.*s>: "
+ "found:<%u>, not-found:<%u>, max:<%u>",
+ name_size, name,
+ *lseg0, *lseg1, ii->seg->header->max_segment);
+ return ctx->rc;
+ }
/*
{
uint32_t pseg;
- char *used = GRN_CALLOC(MAX_PSEG);
+ char *used = GRN_CALLOC(ii->seg->header->max_segment);
if (!used) { return GRN_NO_MEMORY_AVAILABLE; }
for (i = 0; i < GRN_II_MAX_LSEG; i++) {
- if ((pseg = ii->header->ainfo[i]) != NOT_ASSIGNED) { used[pseg] = 1; }
- if ((pseg = ii->header->binfo[i]) != NOT_ASSIGNED) { used[pseg] = 1; }
+ if ((pseg = ii->header->ainfo[i]) != GRN_II_PSEG_NOT_ASSIGNED) {
+ used[pseg] = 1;
+ }
+ if ((pseg = ii->header->binfo[i]) != GRN_II_PSEG_NOT_ASSIGNED) {
+ used[pseg] = 1;
+ }
}
for (pseg = 0;; pseg++) {
- if (pseg == MAX_PSEG) { GRN_FREE(used); return GRN_NO_MEMORY_AVAILABLE; }
+ if (pseg == ii->seg->header->max_segment) {
+ GRN_FREE(used);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
if (!used[pseg]) { break; }
}
*pseg0 = pseg++;
for (;; pseg++) {
- if (pseg == MAX_PSEG) { GRN_FREE(used); return GRN_NO_MEMORY_AVAILABLE; }
+ if (pseg == ii->seg->header->max_segment) {
+ GRN_FREE(used);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
if (!used[pseg]) { break; }
}
*pseg1 = pseg;
GRN_FREE(used);
}
*/
- return GRN_SUCCESS;
+ return ctx->rc;
}
#define BGQENQUE(lseg) do {\
- if (ii->header->binfo[lseg] != NOT_ASSIGNED) {\
+ if (ii->header->binfo[lseg] != GRN_II_PSEG_NOT_ASSIGNED) {\
ii->header->bgqbody[ii->header->bgqhead] = ii->header->binfo[lseg];\
ii->header->bgqhead = (ii->header->bgqhead + 1) & (GRN_II_BGQSIZE - 1);\
GRN_ASSERT(ii->header->bgqhead != ii->header->bgqtail);\
@@ -249,7 +406,7 @@ buffer_segment_clear(grn_ii *ii, uint32_t lseg)
{
BGQENQUE(lseg);
// smb_wmb();
- ii->header->binfo[lseg] = NOT_ASSIGNED;
+ ii->header->binfo[lseg] = GRN_II_PSEG_NOT_ASSIGNED;
}
/* chunk */
@@ -279,7 +436,7 @@ typedef struct {
grn_io_win_map(chunk, ctx, iw,\
((seg) >> GRN_II_N_CHUNK_VARIATION),\
(((seg) & ((1 << GRN_II_N_CHUNK_VARIATION) - 1)) << GRN_II_W_LEAST_CHUNK) + (pos),\
- size,mode)
+ size, mode)
/*
static int new_histogram[32];
static int free_histogram[32];
@@ -287,6 +444,10 @@ static int free_histogram[32];
static grn_rc
chunk_new(grn_ctx *ctx, grn_ii *ii, uint32_t *res, uint32_t size)
{
+ uint32_t n_chunks;
+
+ n_chunks = ii->chunk->header->max_segment;
+
/*
if (size) {
int m, es = size - 1;
@@ -298,7 +459,7 @@ chunk_new(grn_ctx *ctx, grn_ii *ii, uint32_t *res, uint32_t size)
if (size > S_CHUNK) {
int i, j;
uint32_t n = (size + S_CHUNK - 1) >> GRN_II_W_CHUNK;
- for (i = 0, j = -1; i < GRN_II_MAX_CHUNK; i++) {
+ for (i = 0, j = -1; i < n_chunks; i++) {
if (HEADER_CHUNK_AT(ii, i)) {
j = i;
} else {
@@ -310,8 +471,15 @@ chunk_new(grn_ctx *ctx, grn_ii *ii, uint32_t *res, uint32_t size)
}
}
}
- GRN_LOG(ctx, GRN_LOG_CRIT, "index full. requested chunk_size=%d.", size);
- return GRN_NO_MEMORY_AVAILABLE;
+ {
+ DEFINE_NAME(ii);
+ MERR("[ii][chunk][new] index is full: "
+ "<%.*s>: "
+ "size:<%u>, n-chunks:<%u>",
+ name_size, name,
+ size, n_chunks);
+ }
+ return ctx->rc;
} else {
uint32_t *vp;
int m, aligned_size;
@@ -329,14 +497,25 @@ chunk_new(grn_ctx *ctx, grn_ii *ii, uint32_t *res, uint32_t size)
grn_io_win iw, iw_;
iw_.addr = NULL;
gseg = &ii->header->garbages[m - GRN_II_W_LEAST_CHUNK];
- while (*gseg != NOT_ASSIGNED) {
+ while (*gseg != GRN_II_PSEG_NOT_ASSIGNED) {
ginfo = WIN_MAP(ii->chunk, ctx, &iw, *gseg, 0, S_GARBAGE, grn_io_rdwr);
//GRN_IO_SEG_MAP2(ii->chunk, *gseg, ginfo);
if (!ginfo) {
if (iw_.addr) { grn_io_win_unmap(&iw_); }
- return GRN_NO_MEMORY_AVAILABLE;
+ {
+ DEFINE_NAME(ii);
+ MERR("[ii][chunk][new] failed to allocate garbage segment: "
+ "<%.*s>: "
+ "n-garbages:<%u>, size:<%u>, n-chunks:<%u>",
+ name_size, name,
+ ii->header->ngarbages[m - GRN_II_W_LEAST_CHUNK],
+ size,
+ n_chunks);
+ }
+ return ctx->rc;
}
- if (ginfo->next != NOT_ASSIGNED || ginfo->nrecs > N_GARBAGES_TH) {
+ if (ginfo->next != GRN_II_PSEG_NOT_ASSIGNED ||
+ ginfo->nrecs > N_GARBAGES_TH) {
*res = ginfo->recs[ginfo->tail];
if (++ginfo->tail == N_GARBAGES) { ginfo->tail = 0; }
ginfo->nrecs--;
@@ -356,10 +535,20 @@ chunk_new(grn_ctx *ctx, grn_ii *ii, uint32_t *res, uint32_t size)
if (iw_.addr) { grn_io_win_unmap(&iw_); }
}
vp = &ii->header->free_chunks[m - GRN_II_W_LEAST_CHUNK];
- if (*vp == NOT_ASSIGNED) {
+ if (*vp == GRN_II_PSEG_NOT_ASSIGNED) {
int i = 0;
while (HEADER_CHUNK_AT(ii, i)) {
- if (++i >= GRN_II_MAX_CHUNK) { return GRN_NO_MEMORY_AVAILABLE; }
+ if (++i >= n_chunks) {
+ DEFINE_NAME(ii);
+ MERR("[ii][chunk][new] failed to find a free chunk: "
+ "<%.*s>: "
+ "index:<%u>, size:<%u>, n-chunks:<%u>",
+ name_size, name,
+ m - GRN_II_W_LEAST_CHUNK,
+ size,
+ n_chunks);
+ return ctx->rc;
+ }
}
HEADER_CHUNK_ON(ii, i);
*vp = i << GRN_II_N_CHUNK_VARIATION;
@@ -367,14 +556,15 @@ chunk_new(grn_ctx *ctx, grn_ii *ii, uint32_t *res, uint32_t size)
*res = *vp;
*vp += 1 << (m - GRN_II_W_LEAST_CHUNK);
if (!(*vp & ((1 << GRN_II_N_CHUNK_VARIATION) - 1))) {
- *vp = NOT_ASSIGNED;
+ *vp = GRN_II_PSEG_NOT_ASSIGNED;
}
return GRN_SUCCESS;
}
}
static grn_rc
-chunk_free(grn_ctx *ctx, grn_ii *ii, uint32_t offset, uint32_t dummy, uint32_t size)
+chunk_free(grn_ctx *ctx, grn_ii *ii,
+ uint32_t offset, uint32_t dummy, uint32_t size)
{
/*
if (size) {
@@ -402,7 +592,7 @@ chunk_free(grn_ctx *ctx, grn_ii *ii, uint32_t offset, uint32_t dummy, uint32_t s
}
gseg = &ii->header->garbages[m - GRN_II_W_LEAST_CHUNK];
iw_.addr = NULL;
- while (*gseg != NOT_ASSIGNED) {
+ while (*gseg != GRN_II_PSEG_NOT_ASSIGNED) {
ginfo = WIN_MAP(ii->chunk, ctx, &iw, *gseg, 0, S_GARBAGE, grn_io_rdwr);
// GRN_IO_SEG_MAP2(ii->chunk, *gseg, ginfo);
if (!ginfo) {
@@ -414,7 +604,7 @@ chunk_free(grn_ctx *ctx, grn_ii *ii, uint32_t offset, uint32_t dummy, uint32_t s
iw_ = iw;
gseg = &ginfo->next;
}
- if (*gseg == NOT_ASSIGNED) {
+ if (*gseg == GRN_II_PSEG_NOT_ASSIGNED) {
grn_rc rc;
if ((rc = chunk_new(ctx, ii, gseg, S_GARBAGE))) {
if (iw_.addr) { grn_io_win_unmap(&iw_); }
@@ -424,7 +614,9 @@ chunk_free(grn_ctx *ctx, grn_ii *ii, uint32_t offset, uint32_t dummy, uint32_t s
/*
uint32_t i = 0;
while (HEADER_CHUNK_AT(ii, i)) {
- if (++i >= GRN_II_MAX_CHUNK) { return GRN_NO_MEMORY_AVAILABLE; }
+ if (++i >= ii->chunk->header->max_segment) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
}
HEADER_CHUNK_ON(ii, i);
*gseg = i;
@@ -437,7 +629,7 @@ chunk_free(grn_ctx *ctx, grn_ii *ii, uint32_t offset, uint32_t dummy, uint32_t s
ginfo->head = 0;
ginfo->tail = 0;
ginfo->nrecs = 0;
- ginfo->next = NOT_ASSIGNED;
+ ginfo->next = GRN_II_PSEG_NOT_ASSIGNED;
}
if (iw_.addr) { grn_io_win_unmap(&iw_); }
ginfo->recs[ginfo->head] = offset;
@@ -970,10 +1162,12 @@ unpack_19(uint32_t *p, uint8_t *dp)
uint32_t v;
v = *dp++ << 11; v += *dp++ << 3; *p++ = v + (*dp >> 5);
v = ((*dp++ << 14) & 0x7ffff); v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 17) & 0x7ffff); v += *dp++ << 9; v += *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 17) & 0x7ffff); v += *dp++ << 9; v += *dp++ << 1;
+ *p++ = v + (*dp >> 7);
v = ((*dp++ << 12) & 0x7ffff); v += *dp++ << 4; *p++ = v + (*dp >> 4);
v = ((*dp++ << 15) & 0x7ffff); v += *dp++ << 7; *p++ = v + (*dp >> 1);
- v = ((*dp++ << 18) & 0x7ffff); v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 18) & 0x7ffff); v += *dp++ << 10; v += *dp++ << 2;
+ *p++ = v + (*dp >> 6);
v = ((*dp++ << 13) & 0x7ffff); v += *dp++ << 5; *p++ = v + (*dp >> 3);
v = ((*dp++ << 16) & 0x7ffff); v += *dp++ << 8; *p++ = v + *dp++;
return dp;
@@ -1025,12 +1219,16 @@ unpack_21(uint32_t *p, uint8_t *dp)
{
uint32_t v;
v = *dp++ << 13; v += *dp++ << 5; *p++ = v + (*dp >> 3);
- v = ((*dp++ << 18) & 0x1fffff); v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 18) & 0x1fffff); v += *dp++ << 10; v += *dp++ << 2;
+ *p++ = v + (*dp >> 6);
v = ((*dp++ << 15) & 0x1fffff); v += *dp++ << 7; *p++ = v + (*dp >> 1);
- v = ((*dp++ << 20) & 0x1fffff); v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 17) & 0x1fffff); v += *dp++ << 9; v += *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 20) & 0x1fffff); v += *dp++ << 12; v += *dp++ << 4;
+ *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 17) & 0x1fffff); v += *dp++ << 9; v += *dp++ << 1;
+ *p++ = v + (*dp >> 7);
v = ((*dp++ << 14) & 0x1fffff); v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 19) & 0x1fffff); v += *dp++ << 11; v += *dp++ << 3; *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 19) & 0x1fffff); v += *dp++ << 11; v += *dp++ << 3;
+ *p++ = v + (*dp >> 5);
v = ((*dp++ << 16) & 0x1fffff); v += *dp++ << 8; *p++ = v + *dp++;
return dp;
}
@@ -1053,12 +1251,16 @@ unpack_22(uint32_t *p, uint8_t *dp)
{
uint32_t v;
v = *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 20) & 0x3fffff); v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 18) & 0x3fffff); v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 20) & 0x3fffff); v += *dp++ << 12; v += *dp++ << 4;
+ *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 18) & 0x3fffff); v += *dp++ << 10; v += *dp++ << 2;
+ *p++ = v + (*dp >> 6);
v = ((*dp++ << 16) & 0x3fffff); v += *dp++ << 8; *p++ = v + *dp++;
v = *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 20) & 0x3fffff); v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 18) & 0x3fffff); v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 20) & 0x3fffff); v += *dp++ << 12; v += *dp++ << 4;
+ *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 18) & 0x3fffff); v += *dp++ << 10; v += *dp++ << 2;
+ *p++ = v + (*dp >> 6);
v = ((*dp++ << 16) & 0x3fffff); v += *dp++ << 8; *p++ = v + *dp++;
return dp;
}
@@ -1081,12 +1283,18 @@ unpack_23(uint32_t *p, uint8_t *dp)
{
uint32_t v;
v = *dp++ << 15; v += *dp++ << 7; *p++ = v + (*dp >> 1);
- v = ((*dp++ << 22) & 0x7fffff); v += *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 21) & 0x7fffff); v += *dp++ << 13; v += *dp++ << 5; *p++ = v + (*dp >> 3);
- v = ((*dp++ << 20) & 0x7fffff); v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 19) & 0x7fffff); v += *dp++ << 11; v += *dp++ << 3; *p++ = v + (*dp >> 5);
- v = ((*dp++ << 18) & 0x7fffff); v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
- v = ((*dp++ << 17) & 0x7fffff); v += *dp++ << 9; v += *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 22) & 0x7fffff); v += *dp++ << 14; v += *dp++ << 6;
+ *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 21) & 0x7fffff); v += *dp++ << 13; v += *dp++ << 5;
+ *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 20) & 0x7fffff); v += *dp++ << 12; v += *dp++ << 4;
+ *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 19) & 0x7fffff); v += *dp++ << 11; v += *dp++ << 3;
+ *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 18) & 0x7fffff); v += *dp++ << 10; v += *dp++ << 2;
+ *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 17) & 0x7fffff); v += *dp++ << 9; v += *dp++ << 1;
+ *p++ = v + (*dp >> 7);
v = ((*dp++ << 16) & 0x7fffff); v += *dp++ << 8; *p++ = v + *dp++;
return dp;
}
@@ -1136,13 +1344,20 @@ unpack_25(uint32_t *p, uint8_t *dp)
{
uint32_t v;
v = *dp++ << 17; v += *dp++ << 9; v += *dp++ << 1; *p++ = v + (*dp >> 7);
- v = ((*dp++ << 18) & 0x1ffffff); v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
- v = ((*dp++ << 19) & 0x1ffffff); v += *dp++ << 11; v += *dp++ << 3; *p++ = v + (*dp >> 5);
- v = ((*dp++ << 20) & 0x1ffffff); v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 21) & 0x1ffffff); v += *dp++ << 13; v += *dp++ << 5; *p++ = v + (*dp >> 3);
- v = ((*dp++ << 22) & 0x1ffffff); v += *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 23) & 0x1ffffff); v += *dp++ << 15; v += *dp++ << 7; *p++ = v + (*dp >> 1);
- v = ((*dp++ << 24) & 0x1ffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 18) & 0x1ffffff); v += *dp++ << 10; v += *dp++ << 2;
+ *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 19) & 0x1ffffff); v += *dp++ << 11; v += *dp++ << 3;
+ *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 20) & 0x1ffffff); v += *dp++ << 12; v += *dp++ << 4;
+ *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 21) & 0x1ffffff); v += *dp++ << 13; v += *dp++ << 5;
+ *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 22) & 0x1ffffff); v += *dp++ << 14; v += *dp++ << 6;
+ *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 23) & 0x1ffffff); v += *dp++ << 15; v += *dp++ << 7;
+ *p++ = v + (*dp >> 1);
+ v = ((*dp++ << 24) & 0x1ffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
return dp;
}
static uint8_t *
@@ -1164,13 +1379,19 @@ unpack_26(uint32_t *p, uint8_t *dp)
{
uint32_t v;
v = *dp++ << 18; v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
- v = ((*dp++ << 20) & 0x3ffffff); v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 22) & 0x3ffffff); v += *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 24) & 0x3ffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 20) & 0x3ffffff); v += *dp++ << 12; v += *dp++ << 4;
+ *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 22) & 0x3ffffff); v += *dp++ << 14; v += *dp++ << 6;
+ *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 24) & 0x3ffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
v = *dp++ << 18; v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
- v = ((*dp++ << 20) & 0x3ffffff); v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 22) & 0x3ffffff); v += *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 24) & 0x3ffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 20) & 0x3ffffff); v += *dp++ << 12; v += *dp++ << 4;
+ *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 22) & 0x3ffffff); v += *dp++ << 14; v += *dp++ << 6;
+ *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 24) & 0x3ffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
return dp;
}
static uint8_t *
@@ -1179,10 +1400,12 @@ pack_27(uint32_t *p, uint8_t *rp)
uint8_t v;
*rp++ = (*p >> 19); *rp++ = (*p >> 11); *rp++ = (*p >> 3); v = *p++ << 5;
*rp++ = v + (*p >> 22); *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
- *rp++ = v + (*p >> 25); *rp++ = (*p >> 17); *rp++ = (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 25); *rp++ = (*p >> 17); *rp++ = (*p >> 9);
+ *rp++ = (*p >> 1); v = *p++ << 7;
*rp++ = v + (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
*rp++ = v + (*p >> 23); *rp++ = (*p >> 15); *rp++ = (*p >> 7); v = *p++ << 1;
- *rp++ = v + (*p >> 26); *rp++ = (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 26); *rp++ = (*p >> 18); *rp++ = (*p >> 10);
+ *rp++ = (*p >> 2); v = *p++ << 6;
*rp++ = v + (*p >> 21); *rp++ = (*p >> 13); *rp++ = (*p >> 5); v = *p++ << 3;
*rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
return rp;
@@ -1192,13 +1415,20 @@ unpack_27(uint32_t *p, uint8_t *dp)
{
uint32_t v;
v = *dp++ << 19; v += *dp++ << 11; v += *dp++ << 3; *p++ = v + (*dp >> 5);
- v = ((*dp++ << 22) & 0x7ffffff); v += *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 25) & 0x7ffffff); v += *dp++ << 17; v += *dp++ << 9; v += *dp++ << 1; *p++ = v + (*dp >> 7);
- v = ((*dp++ << 20) & 0x7ffffff); v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 23) & 0x7ffffff); v += *dp++ << 15; v += *dp++ << 7; *p++ = v + (*dp >> 1);
- v = ((*dp++ << 26) & 0x7ffffff); v += *dp++ << 18; v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
- v = ((*dp++ << 21) & 0x7ffffff); v += *dp++ << 13; v += *dp++ << 5; *p++ = v + (*dp >> 3);
- v = ((*dp++ << 24) & 0x7ffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 22) & 0x7ffffff); v += *dp++ << 14; v += *dp++ << 6;
+ *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 25) & 0x7ffffff); v += *dp++ << 17; v += *dp++ << 9;
+ v += *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 20) & 0x7ffffff); v += *dp++ << 12; v += *dp++ << 4;
+ *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 23) & 0x7ffffff); v += *dp++ << 15; v += *dp++ << 7;
+ *p++ = v + (*dp >> 1);
+ v = ((*dp++ << 26) & 0x7ffffff); v += *dp++ << 18; v += *dp++ << 10;
+ v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 21) & 0x7ffffff); v += *dp++ << 13; v += *dp++ << 5;
+ *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 24) & 0x7ffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
return dp;
}
static uint8_t *
@@ -1220,13 +1450,17 @@ unpack_28(uint32_t *p, uint8_t *dp)
{
uint32_t v;
v = *dp++ << 20; v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 24) & 0xfffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 24) & 0xfffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
v = *dp++ << 20; v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 24) & 0xfffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 24) & 0xfffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
v = *dp++ << 20; v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 24) & 0xfffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 24) & 0xfffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
v = *dp++ << 20; v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 24) & 0xfffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 24) & 0xfffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
return dp;
}
static uint8_t *
@@ -1234,12 +1468,16 @@ pack_29(uint32_t *p, uint8_t *rp)
{
uint8_t v;
*rp++ = (*p >> 21); *rp++ = (*p >> 13); *rp++ = (*p >> 5); v = *p++ << 3;
- *rp++ = v + (*p >> 26); *rp++ = (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 26); *rp++ = (*p >> 18); *rp++ = (*p >> 10);
+ *rp++ = (*p >> 2); v = *p++ << 6;
*rp++ = v + (*p >> 23); *rp++ = (*p >> 15); *rp++ = (*p >> 7); v = *p++ << 1;
- *rp++ = v + (*p >> 28); *rp++ = (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
- *rp++ = v + (*p >> 25); *rp++ = (*p >> 17); *rp++ = (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 28); *rp++ = (*p >> 20); *rp++ = (*p >> 12);
+ *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 25); *rp++ = (*p >> 17); *rp++ = (*p >> 9);
+ *rp++ = (*p >> 1); v = *p++ << 7;
*rp++ = v + (*p >> 22); *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
- *rp++ = v + (*p >> 27); *rp++ = (*p >> 19); *rp++ = (*p >> 11); *rp++ = (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 27); *rp++ = (*p >> 19); *rp++ = (*p >> 11);
+ *rp++ = (*p >> 3); v = *p++ << 5;
*rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
return rp;
}
@@ -1248,13 +1486,20 @@ unpack_29(uint32_t *p, uint8_t *dp)
{
uint32_t v;
v = *dp++ << 21; v += *dp++ << 13; v += *dp++ << 5; *p++ = v + (*dp >> 3);
- v = ((*dp++ << 26) & 0x1fffffff); v += *dp++ << 18; v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
- v = ((*dp++ << 23) & 0x1fffffff); v += *dp++ << 15; v += *dp++ << 7; *p++ = v + (*dp >> 1);
- v = ((*dp++ << 28) & 0x1fffffff); v += *dp++ << 20; v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 25) & 0x1fffffff); v += *dp++ << 17; v += *dp++ << 9; v += *dp++ << 1; *p++ = v + (*dp >> 7);
- v = ((*dp++ << 22) & 0x1fffffff); v += *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 27) & 0x1fffffff); v += *dp++ << 19; v += *dp++ << 11; v += *dp++ << 3; *p++ = v + (*dp >> 5);
- v = ((*dp++ << 24) & 0x1fffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 26) & 0x1fffffff); v += *dp++ << 18; v += *dp++ << 10;
+ v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 23) & 0x1fffffff); v += *dp++ << 15; v += *dp++ << 7;
+ *p++ = v + (*dp >> 1);
+ v = ((*dp++ << 28) & 0x1fffffff); v += *dp++ << 20; v += *dp++ << 12;
+ v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 25) & 0x1fffffff); v += *dp++ << 17; v += *dp++ << 9;
+ v += *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 22) & 0x1fffffff); v += *dp++ << 14; v += *dp++ << 6;
+ *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 27) & 0x1fffffff); v += *dp++ << 19; v += *dp++ << 11;
+ v += *dp++ << 3; *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 24) & 0x1fffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
return dp;
}
static uint8_t *
@@ -1262,13 +1507,18 @@ pack_30(uint32_t *p, uint8_t *rp)
{
uint8_t v;
*rp++ = (*p >> 22); *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
- *rp++ = v + (*p >> 28); *rp++ = (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
- *rp++ = v + (*p >> 26); *rp++ = (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 28); *rp++ = (*p >> 20); *rp++ = (*p >> 12);
+ *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 26); *rp++ = (*p >> 18); *rp++ = (*p >> 10);
+ *rp++ = (*p >> 2); v = *p++ << 6;
*rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
*rp++ = (*p >> 22); *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
- *rp++ = v + (*p >> 28); *rp++ = (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
- *rp++ = v + (*p >> 26); *rp++ = (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
- *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = v + (*p >> 28); *rp++ = (*p >> 20); *rp++ = (*p >> 12);
+ *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 26); *rp++ = (*p >> 18); *rp++ = (*p >> 10);
+ *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8);
+ *rp++ = *p++;
return rp;
}
static uint8_t *
@@ -1276,13 +1526,19 @@ unpack_30(uint32_t *p, uint8_t *dp)
{
uint32_t v;
v = *dp++ << 22; v += *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 28) & 0x3fffffff); v += *dp++ << 20; v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 26) & 0x3fffffff); v += *dp++ << 18; v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
- v = ((*dp++ << 24) & 0x3fffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 28) & 0x3fffffff); v += *dp++ << 20; v += *dp++ << 12;
+ v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 26) & 0x3fffffff); v += *dp++ << 18; v += *dp++ << 10;
+ v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 24) & 0x3fffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
v = *dp++ << 22; v += *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 28) & 0x3fffffff); v += *dp++ << 20; v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 26) & 0x3fffffff); v += *dp++ << 18; v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
- v = ((*dp++ << 24) & 0x3fffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 28) & 0x3fffffff); v += *dp++ << 20; v += *dp++ << 12;
+ v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 26) & 0x3fffffff); v += *dp++ << 18; v += *dp++ << 10;
+ v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 24) & 0x3fffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
return dp;
}
static uint8_t *
@@ -1290,13 +1546,20 @@ pack_31(uint32_t *p, uint8_t *rp)
{
uint8_t v;
*rp++ = (*p >> 23); *rp++ = (*p >> 15); *rp++ = (*p >> 7); v = *p++ << 1;
- *rp++ = v + (*p >> 30); *rp++ = (*p >> 22); *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
- *rp++ = v + (*p >> 29); *rp++ = (*p >> 21); *rp++ = (*p >> 13); *rp++ = (*p >> 5); v = *p++ << 3;
- *rp++ = v + (*p >> 28); *rp++ = (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
- *rp++ = v + (*p >> 27); *rp++ = (*p >> 19); *rp++ = (*p >> 11); *rp++ = (*p >> 3); v = *p++ << 5;
- *rp++ = v + (*p >> 26); *rp++ = (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
- *rp++ = v + (*p >> 25); *rp++ = (*p >> 17); *rp++ = (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
- *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = v + (*p >> 30); *rp++ = (*p >> 22); *rp++ = (*p >> 14);
+ *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 29); *rp++ = (*p >> 21); *rp++ = (*p >> 13);
+ *rp++ = (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 28); *rp++ = (*p >> 20); *rp++ = (*p >> 12);
+ *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 27); *rp++ = (*p >> 19); *rp++ = (*p >> 11);
+ *rp++ = (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 26); *rp++ = (*p >> 18); *rp++ = (*p >> 10);
+ *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 25); *rp++ = (*p >> 17); *rp++ = (*p >> 9);
+ *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8);
+ *rp++ = *p++;
return rp;
}
static uint8_t *
@@ -1304,13 +1567,20 @@ unpack_31(uint32_t *p, uint8_t *dp)
{
uint32_t v;
v = *dp++ << 23; v += *dp++ << 15; v += *dp++ << 7; *p++ = v + (*dp >> 1);
- v = ((*dp++ << 30) & 0x7fffffff); v += *dp++ << 22; v += *dp++ << 14; v += *dp++ << 6; *p++ = v + (*dp >> 2);
- v = ((*dp++ << 29) & 0x7fffffff); v += *dp++ << 21; v += *dp++ << 13; v += *dp++ << 5; *p++ = v + (*dp >> 3);
- v = ((*dp++ << 28) & 0x7fffffff); v += *dp++ << 20; v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
- v = ((*dp++ << 27) & 0x7fffffff); v += *dp++ << 19; v += *dp++ << 11; v += *dp++ << 3; *p++ = v + (*dp >> 5);
- v = ((*dp++ << 26) & 0x7fffffff); v += *dp++ << 18; v += *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
- v = ((*dp++ << 25) & 0x7fffffff); v += *dp++ << 17; v += *dp++ << 9; v += *dp++ << 1; *p++ = v + (*dp >> 7);
- v = ((*dp++ << 24) & 0x7fffffff); v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = ((*dp++ << 30) & 0x7fffffff); v += *dp++ << 22; v += *dp++ << 14;
+ v += *dp++ << 6; *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 29) & 0x7fffffff); v += *dp++ << 21; v += *dp++ << 13;
+ v += *dp++ << 5; *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 28) & 0x7fffffff); v += *dp++ << 20; v += *dp++ << 12;
+ v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 27) & 0x7fffffff); v += *dp++ << 19; v += *dp++ << 11;
+ v += *dp++ << 3; *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 26) & 0x7fffffff); v += *dp++ << 18; v += *dp++ << 10;
+ v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 25) & 0x7fffffff); v += *dp++ << 17; v += *dp++ << 9;
+ v += *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 24) & 0x7fffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
return dp;
}
static uint8_t *
@@ -1473,9 +1743,9 @@ grn_p_enc(grn_ctx *ctx, uint32_t *data, uint32_t data_size, uint8_t **res)
return rp - *res;
}
-#define USE_P_ENC (1<<0)
-#define CUT_OFF (1<<1)
-#define ODD (1<<2)
+#define USE_P_ENC (1<<0) /* Use PForDelta */
+#define CUT_OFF (1<<1) /* Deprecated */
+#define ODD (1<<2) /* Variable size data */
typedef struct {
uint32_t *data;
@@ -1491,7 +1761,14 @@ datavec_reset(grn_ctx *ctx, datavec *dv, uint32_t dvlen,
if (!dv[0].data || dv[dvlen].data < dv[0].data + totalsize) {
if (dv[0].data) { GRN_FREE(dv[0].data); }
if (!(dv[0].data = GRN_MALLOC(totalsize * sizeof(uint32_t)))) {
- return GRN_NO_MEMORY_AVAILABLE;
+ MERR("[ii][data-vector][reset] failed to allocate data: "
+ "length:<%u>, "
+ "unit-size:<%" GRN_FMT_SIZE ">, "
+ "total-size:<%" GRN_FMT_SIZE ">",
+ dvlen,
+ unitsize,
+ totalsize);
+ return ctx->rc;
}
dv[dvlen].data = dv[0].data + totalsize;
}
@@ -1511,7 +1788,14 @@ datavec_init(grn_ctx *ctx, datavec *dv, uint32_t dvlen,
return GRN_SUCCESS;
}
if (!(dv[0].data = GRN_MALLOC(totalsize * sizeof(uint32_t)))) {
- return GRN_NO_MEMORY_AVAILABLE;
+ MERR("[ii][data-vector][init] failed to allocate data: "
+ "length:<%u>, "
+ "unit-size:<%" GRN_FMT_SIZE ">, "
+ "total-size:<%" GRN_FMT_SIZE ">",
+ dvlen,
+ unitsize,
+ totalsize);
+ return ctx->rc;
}
dv[dvlen].data = dv[0].data + totalsize;
for (i = 1; i < dvlen; i++) {
@@ -1821,7 +2105,7 @@ grn_p_decv(grn_ctx *ctx, uint8_t *data, uint32_t data_size, datavec *dv, uint32_
}
GRN_ASSERT(dp == dpe);
if (dp != dpe) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "data_size=%d, %" GRN_FMT_LLD,
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "data_size=%d, %" GRN_FMT_LLD,
data_size, (long long int)(dpe - dp));
}
}
@@ -1890,9 +2174,9 @@ buffer_open(grn_ctx *ctx, grn_ii *ii, uint32_t pos, buffer_term **bt, buffer **b
byte *p = NULL;
uint16_t lseg = (uint16_t) (LSEG(pos));
uint32_t pseg = ii->header->binfo[lseg];
- if (pseg != NOT_ASSIGNED) {
+ if (pseg != GRN_II_PSEG_NOT_ASSIGNED) {
GRN_IO_SEG_REF(ii->seg, pseg, p);
- if (!p) { return NOT_ASSIGNED; }
+ if (!p) { return GRN_II_PSEG_NOT_ASSIGNED; }
if (b) { *b = (buffer *)p; }
if (bt) { *bt = (buffer_term *)(p + LPOS(pos)); }
}
@@ -1902,7 +2186,7 @@ buffer_open(grn_ctx *ctx, grn_ii *ii, uint32_t pos, buffer_term **bt, buffer **b
inline static grn_rc
buffer_close(grn_ctx *ctx, grn_ii *ii, uint32_t pseg)
{
- if (pseg >= MAX_PSEG) {
+ if (pseg >= ii->seg->header->max_segment) {
GRN_LOG(ctx, GRN_LOG_NOTICE, "invalid pseg buffer_close(%d)", pseg);
return GRN_INVALID_ARGUMENT;
}
@@ -1914,14 +2198,14 @@ inline static uint32_t
buffer_open_if_capable(grn_ctx *ctx, grn_ii *ii, int32_t seg, int size, buffer **b)
{
uint32_t pseg, pos = SEG2POS(seg, 0);
- if ((pseg = buffer_open(ctx, ii, pos, NULL, b)) != NOT_ASSIGNED) {
+ if ((pseg = buffer_open(ctx, ii, pos, NULL, b)) != GRN_II_PSEG_NOT_ASSIGNED) {
uint16_t nterms = (*b)->header.nterms - (*b)->header.nterms_void;
if (!((nterms < 4096 ||
(ii->header->total_chunk_size >> ((nterms >> 8) - 6))
> (*b)->header.chunk_size) &&
((*b)->header.buffer_free >= size + sizeof(buffer_term)))) {
buffer_close(ctx, ii, pseg);
- return NOT_ASSIGNED;
+ return GRN_II_PSEG_NOT_ASSIGNED;
}
}
return pseg;
@@ -1944,20 +2228,28 @@ buffer_term_dump(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_term *bt)
int pos, rid, sid;
uint8_t *p;
buffer_rec *r;
+
+ if (!grn_logger_pass(ctx, GRN_LOG_DEBUG)) {
+ return;
+ }
+
GRN_LOG(ctx, GRN_LOG_DEBUG,
- "b=(%x %u %u %u)", b->header.chunk, b->header.chunk_size, b->header.buffer_free, b->header.nterms);
+ "b=(%x %u %u %u)", b->header.chunk, b->header.chunk_size,
+ b->header.buffer_free, b->header.nterms);
GRN_LOG(ctx, GRN_LOG_DEBUG,
- "bt=(%u %u %u %u %u)", bt->tid, bt->size_in_chunk, bt->pos_in_chunk, bt->size_in_buffer, bt->pos_in_buffer);
+ "bt=(%u %u %u %u %u)", bt->tid, bt->size_in_chunk, bt->pos_in_chunk,
+ bt->size_in_buffer, bt->pos_in_buffer);
for (pos = bt->pos_in_buffer; pos; pos = r->step) {
r = BUFFER_REC_AT(b, pos);
- p = NEXT_ADDR(r);
+ p = GRN_NEXT_ADDR(r);
GRN_B_DEC(rid, p);
if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
GRN_B_DEC(sid, p);
} else {
sid = 1;
}
- GRN_LOG(ctx, GRN_LOG_DEBUG, "%d=(%d:%d),(%d:%d)", pos, r->jump, r->step, rid, sid);
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "%d=(%d:%d),(%d:%d)", pos, r->jump, r->step, rid, sid);
}
}
@@ -1969,7 +2261,7 @@ check_jump(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_rec *r, int j)
buffer_rec *r2;
docid id, id2;
if (!j) { return GRN_SUCCESS; }
- p = NEXT_ADDR(r);
+ p = GRN_NEXT_ADDR(r);
GRN_B_DEC(id.rid, p);
if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
GRN_B_DEC(id.sid, p);
@@ -1981,7 +2273,7 @@ check_jump(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_rec *r, int j)
return GRN_SUCCESS;
}
r2 = BUFFER_REC_AT(b, j);
- p = NEXT_ADDR(r2);
+ p = GRN_NEXT_ADDR(r2);
GRN_B_DEC(id2.rid, p);
if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
GRN_B_DEC(id2.sid, p);
@@ -1989,11 +2281,15 @@ check_jump(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_rec *r, int j)
id2.sid = 1;
}
if (r2->step == i) {
- GRN_LOG(ctx, GRN_LOG_EMERG, "cycle! %d(%d:%d)<->%d(%d:%d)", i, id.rid, id.sid, j, id2.rid, id2.sid);
+ GRN_LOG(ctx, GRN_LOG_EMERG, "cycle! %d(%d:%d)<->%d(%d:%d)",
+ i, id.rid, id.sid, j, id2.rid, id2.sid);
return GRN_FILE_CORRUPT;
}
if (id2.rid < id.rid || (id2.rid == id.rid && id2.sid <= id.sid)) {
- GRN_LOG(ctx, GRN_LOG_CRIT, "invalid jump! %d(%d:%d)(%d:%d)->%d(%d:%d)(%d:%d)", i, r->jump, r->step, id.rid, id.sid, j, r2->jump, r2->step, id2.rid, id2.sid);
+ GRN_LOG(ctx, GRN_LOG_CRIT,
+ "invalid jump! %d(%d:%d)(%d:%d)->%d(%d:%d)(%d:%d)",
+ i, r->jump, r->step, id.rid, id.sid, j, r2->jump, r2->step,
+ id2.rid, id2.sid);
return GRN_FILE_CORRUPT;
}
return GRN_SUCCESS;
@@ -2035,12 +2331,11 @@ buffer_put(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_term *bt,
buffer_rec *rnew, uint8_t *bs, grn_ii_updspec *u, int size)
{
uint8_t *p;
- grn_rc rc = GRN_SUCCESS;
docid id_curr = {0, 0}, id_start = {0, 0}, id_post = {0, 0};
buffer_rec *r_curr, *r_start = NULL;
uint16_t last = 0, *lastp = &bt->pos_in_buffer, pos = BUFFER_REC_POS(b, rnew);
int vdelta = 0, delta, delta0 = 0, vhops = 0, nhops = 0, reset = 1;
- grn_memcpy(NEXT_ADDR(rnew), bs, size - sizeof(buffer_rec));
+ grn_memcpy(GRN_NEXT_ADDR(rnew), bs, size - sizeof(buffer_rec));
for (;;) {
if (!*lastp) {
rnew->step = 0;
@@ -2065,7 +2360,7 @@ buffer_put(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_term *bt,
break;
}
r_curr = BUFFER_REC_AT(b, *lastp);
- p = NEXT_ADDR(r_curr);
+ p = GRN_NEXT_ADDR(r_curr);
GRN_B_DEC(id_curr.rid, p);
if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
GRN_B_DEC(id_curr.sid, p);
@@ -2074,9 +2369,15 @@ buffer_put(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_term *bt,
}
if (id_curr.rid < id_post.rid ||
(id_curr.rid == id_post.rid && id_curr.sid < id_post.sid)) {
- rc = GRN_FILE_CORRUPT;
- ERRSET(ctx, GRN_CRIT, rc, "loop found!!! (%d:%d)->(%d:%d)",
- id_post.rid, id_post.sid, id_curr.rid, id_curr.sid);
+ {
+ DEFINE_NAME(ii);
+ CRIT(GRN_FILE_CORRUPT,
+ "[ii][buffer][put] loop is found: "
+ "<%.*s>: "
+ "(%d:%d)->(%d:%d)",
+ name_size, name,
+ id_post.rid, id_post.sid, id_curr.rid, id_curr.sid);
+ }
buffer_term_dump(ctx, ii, b, bt);
bt->pos_in_buffer = 0;
bt->size_in_buffer = 0;
@@ -2093,13 +2394,13 @@ buffer_put(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_term *bt,
BUFFER_REC_DEL(r_curr);
if (!(step = r_curr->step)) { break; }
r_curr = BUFFER_REC_AT(b, step);
- p = NEXT_ADDR(r_curr);
+ p = GRN_NEXT_ADDR(r_curr);
GRN_B_DEC(id_curr.rid, p);
- if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
- GRN_B_DEC(id_curr.sid, p);
- } else {
- id_curr.sid = 1;
- }
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
+ GRN_B_DEC(id_curr.sid, p);
+ } else {
+ id_curr.sid = 1;
+ }
}
} else if (u->sid == id_curr.sid) {
BUFFER_REC_DEL(r_curr);
@@ -2122,7 +2423,9 @@ buffer_put(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_term *bt,
vhops = 1;
vdelta = delta0 >> 1;
} else {
- if (!(delta = id_curr.rid - id_start.rid)) { delta = id_curr.sid - id_start.sid; }
+ if (!(delta = id_curr.rid - id_start.rid)) {
+ delta = id_curr.sid - id_start.sid;
+ }
if (vdelta < delta) {
vdelta += (delta0 >> ++vhops);
r_start = r_curr;
@@ -2143,7 +2446,7 @@ buffer_put(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_term *bt,
buffer_rec *rj = BUFFER_REC_AT(b, posj);
if (!BUFFER_REC_DELETED(rj)) {
docid idj;
- p = NEXT_ADDR(rj);
+ p = GRN_NEXT_ADDR(rj);
GRN_B_DEC(idj.rid, p);
if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
GRN_B_DEC(idj.sid, p);
@@ -2160,7 +2463,7 @@ buffer_put(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_term *bt,
}
}
}
- return rc;
+ return ctx->rc;
}
/* array */
@@ -2172,7 +2475,9 @@ array_at(grn_ctx *ctx, grn_ii *ii, uint32_t id)
uint32_t seg, pseg;
if (id > GRN_ID_MAX) { return NULL; }
seg = id >> W_ARRAY;
- if ((pseg = ii->header->ainfo[seg]) == NOT_ASSIGNED) { return NULL; }
+ if ((pseg = ii->header->ainfo[seg]) == GRN_II_PSEG_NOT_ASSIGNED) {
+ return NULL;
+ }
GRN_IO_SEG_REF(ii->seg, pseg, p);
if (!p) { return NULL; }
return (uint32_t *)(p + (id & ARRAY_MASK_IN_A_SEGMENT) * S_ARRAY_ELEMENT);
@@ -2186,7 +2491,7 @@ array_get(grn_ctx *ctx, grn_ii *ii, uint32_t id)
uint32_t pseg;
if (id > GRN_ID_MAX) { return NULL; }
seg = id >> W_ARRAY;
- if ((pseg = ii->header->ainfo[seg]) == NOT_ASSIGNED) {
+ if ((pseg = ii->header->ainfo[seg]) == GRN_II_PSEG_NOT_ASSIGNED) {
if (segment_get_clear(ctx, ii, &pseg)) { return NULL; }
ii->header->ainfo[seg] = pseg;
if (seg >= ii->header->amax) { ii->header->amax = seg + 1; }
@@ -2393,8 +2698,11 @@ typedef struct {
if (cid.rid) {\
if (cid.tf) {\
if (lid.rid > cid.rid || (lid.rid == cid.rid && lid.sid >= cid.sid)) {\
- GRN_LOG(ctx, GRN_LOG_CRIT, "brokenc!! (%d:%d) -> (%d:%d)", lid.rid, lid.sid, bid.rid, bid.sid);\
- rc = GRN_FILE_CORRUPT;\
+ DEFINE_NAME(ii);\
+ CRIT(GRN_FILE_CORRUPT,\
+ "[ii][broken] posting in list is larger than posting in chunk: "\
+ "<%.*s>: (%d:%d) -> (%d:%d)",\
+ name_size, name, lid.rid, lid.sid, cid.rid, cid.sid);\
break;\
}\
PUTNEXT_(cid);\
@@ -2406,8 +2714,10 @@ typedef struct {
}\
}\
} else {\
- GRN_LOG(ctx, GRN_LOG_CRIT, "invalid chunk(%d,%d)", bt->tid, cid.rid);\
- rc = GRN_FILE_CORRUPT;\
+ DEFINE_NAME(ii);\
+ CRIT(GRN_FILE_CORRUPT,\
+ "[ii][broken] invalid posting in chunk: <%.*s>: (%d,%d)",\
+ name_size, name, bt->tid, cid.rid);\
break;\
}\
}\
@@ -2418,7 +2728,7 @@ typedef struct {
if (nextb) {\
uint32_t lrid = bid.rid, lsid = bid.sid;\
buffer_rec *br = BUFFER_REC_AT(sb, nextb);\
- sbp = NEXT_ADDR(br);\
+ sbp = GRN_NEXT_ADDR(br);\
GRN_B_DEC(bid.rid, sbp);\
if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {\
GRN_B_DEC(bid.sid, sbp);\
@@ -2426,8 +2736,11 @@ typedef struct {
bid.sid = 1;\
}\
if (lrid > bid.rid || (lrid == bid.rid && lsid >= bid.sid)) {\
- GRN_LOG(ctx, GRN_LOG_CRIT, "brokeng!! (%d:%d) -> (%d:%d)", lrid, lsid, bid.rid, bid.sid);\
- rc = GRN_FILE_CORRUPT;\
+ DEFINE_NAME(ii);\
+ CRIT(GRN_FILE_CORRUPT,\
+ "[ii][broken] postings in block aren't sorted: "\
+ "<%.*s>: (%d:%d) -> (%d:%d)",\
+ name_size, name, lrid, lsid, bid.rid, bid.sid);\
break;\
}\
nextb = br->step;\
@@ -2441,11 +2754,16 @@ typedef struct {
GRN_B_DEC(bid.tf, sbp);\
if (bid.tf > 0) {\
if (lid.rid > bid.rid || (lid.rid == bid.rid && lid.sid >= bid.sid)) {\
- GRN_LOG(ctx, GRN_LOG_CRIT, "brokenb!! (%d:%d) -> (%d:%d)", lid.rid, lid.sid, bid.rid, bid.sid);\
- rc = GRN_FILE_CORRUPT;\
+ DEFINE_NAME(ii);\
+ CRIT(GRN_FILE_CORRUPT,\
+ "[ii][broken] posting in list is larger than posting in buffer: "\
+ "<%.*s>: (%d:%d) -> (%d:%d)",\
+ name_size, name, lid.rid, lid.sid, bid.rid, bid.sid);\
break;\
}\
- if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { GRN_B_DEC(bid.weight, sbp); }\
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) {\
+ GRN_B_DEC(bid.weight, sbp);\
+ }\
PUTNEXT_(bid);\
if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {\
while (bid.tf--) { GRN_B_DEC(*posp, sbp); spos += *posp++; }\
@@ -2460,16 +2778,20 @@ typedef struct {
if (cid.rid) {\
if (cid.rid < bid.rid) {\
PUTNEXTC();\
+ if (ctx->rc != GRN_SUCCESS) { break; }\
} else {\
if (bid.rid < cid.rid) {\
PUTNEXTB();\
+ if (ctx->rc != GRN_SUCCESS) { break; }\
} else {\
if (bid.sid) {\
if (cid.sid < bid.sid) {\
PUTNEXTC();\
+ if (ctx->rc != GRN_SUCCESS) { break; }\
} else {\
if (bid.sid == cid.sid) { GETNEXTC(); }\
PUTNEXTB();\
+ if (ctx->rc != GRN_SUCCESS) { break; }\
}\
} else {\
GETNEXTC();\
@@ -2478,10 +2800,12 @@ typedef struct {
}\
} else {\
PUTNEXTB();\
+ if (ctx->rc != GRN_SUCCESS) { break; }\
}\
} else {\
if (cid.rid) {\
PUTNEXTC();\
+ if (ctx->rc != GRN_SUCCESS) { break; }\
} else {\
break;\
}\
@@ -2497,12 +2821,12 @@ typedef struct {
static grn_rc
chunk_flush(grn_ctx *ctx, grn_ii *ii, chunk_info *cinfo, uint8_t *enc, uint32_t encsize)
{
- grn_rc rc = GRN_SUCCESS;
uint8_t *dc;
uint32_t dcn;
grn_io_win dw;
if (encsize) {
- if (!(rc = chunk_new(ctx, ii, &dcn, encsize))) {
+ chunk_new(ctx, ii, &dcn, encsize);
+ if (ctx->rc == GRN_SUCCESS) {
if ((dc = WIN_MAP(ii->chunk, ctx, &dw, dcn, 0, encsize, grn_io_wronly))) {
grn_memcpy(dc, enc, encsize);
grn_io_win_unmap(&dw);
@@ -2510,14 +2834,21 @@ chunk_flush(grn_ctx *ctx, grn_ii *ii, chunk_info *cinfo, uint8_t *enc, uint32_t
cinfo->size = encsize;
} else {
chunk_free(ctx, ii, dcn, 0, encsize);
- rc = GRN_NO_MEMORY_AVAILABLE;
+ {
+ DEFINE_NAME(ii);
+ MERR("[ii][chunk][flush] failed to allocate a destination chunk: "
+ "<%.*s> :"
+ "segment:<%u>, size:<%u>",
+ name_size, name,
+ dcn, encsize);
+ }
}
}
} else {
cinfo->segno = 0;
cinfo->size = 0;
}
- return rc;
+ return ctx->rc;
}
static grn_rc
@@ -2525,13 +2856,13 @@ chunk_merge(grn_ctx *ctx, grn_ii *ii, buffer *sb, buffer_term *bt,
chunk_info *cinfo, grn_id rid, datavec *dv,
uint16_t *nextbp, uint8_t **sbpp, docinfo *bidp, int32_t *balance)
{
- grn_rc rc;
grn_io_win sw;
uint64_t spos = 0;
uint32_t segno = cinfo->segno, size = cinfo->size, sdf = 0, ndf = 0;
uint32_t *ridp = NULL, *sidp = NULL, *tfp, *weightp = NULL, *posp = NULL;
docinfo cid = {0, 0, 0, 0, 0}, lid = {0, 0, 0, 0, 0}, bid = *bidp;
uint8_t *scp = WIN_MAP(ii->chunk, ctx, &sw, segno, 0, size, grn_io_rdonly);
+
if (scp) {
uint16_t nextb = *nextbp;
uint32_t snn = 0, *srp, *ssp = NULL, *stp, *sop = NULL, *snp;
@@ -2554,7 +2885,8 @@ chunk_merge(grn_ctx *ctx, grn_ii *ii, buffer *sb, buffer_term *bt,
snn = rdv[j].data_size;
snp = rdv[j].data;
}
- if (!(rc = datavec_reset(ctx, dv, ii->n_elements, sdf + S_SEGMENT, bufsize))) {
+ datavec_reset(ctx, dv, ii->n_elements, sdf + S_SEGMENT, bufsize);
+ if (ctx->rc == GRN_SUCCESS) {
{
int j = 0;
ridp = dv[j++].data;
@@ -2565,18 +2897,27 @@ chunk_merge(grn_ctx *ctx, grn_ii *ii, buffer *sb, buffer_term *bt,
}
GETNEXTC();
MERGE_BC(bid.rid <= rid || cid.rid);
- *sbpp = sbp;
- *nextbp = nextb;
- *bidp = bid;
- GRN_ASSERT(posp < dv[ii->n_elements].data);
- ndf = ridp - dv[0].data;
+ if (ctx->rc == GRN_SUCCESS) {
+ *sbpp = sbp;
+ *nextbp = nextb;
+ *bidp = bid;
+ GRN_ASSERT(posp < dv[ii->n_elements].data);
+ ndf = ridp - dv[0].data;
+ }
}
datavec_fin(ctx, rdv);
grn_io_win_unmap(&sw);
} else {
- rc = GRN_NO_MEMORY_AVAILABLE;
- }
- if (!rc) {
+ DEFINE_NAME(ii);
+ MERR("[ii][chunk][merge] failed to allocate a source chunk: "
+ "<%.*s> :"
+ "record:<%u>, segment:<%u>, size:<%u>",
+ name_size, name,
+ rid,
+ segno,
+ size);
+ }
+ if (ctx->rc == GRN_SUCCESS) {
int j = 0;
uint8_t *enc;
uint32_t encsize;
@@ -2597,24 +2938,83 @@ chunk_merge(grn_ctx *ctx, grn_ii *ii, buffer *sb, buffer_term *bt,
}
if ((enc = GRN_MALLOC((ndf * 4 + np) * 2))) {
encsize = grn_p_encv(ctx, dv, ii->n_elements, enc);
- if (!(rc = chunk_flush(ctx, ii, cinfo, enc, encsize))) {
+ chunk_flush(ctx, ii, cinfo, enc, encsize);
+ if (ctx->rc == GRN_SUCCESS) {
chunk_free(ctx, ii, segno, 0, size);
}
GRN_FREE(enc);
} else {
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][chunk][merge] failed to allocate a encode buffer: "
+ "<%.*s> :"
+ "record:<%u>, segment:<%u>, size:<%u>",
+ name_size, name,
+ rid,
+ segno,
+ size);
}
}
*balance += (ndf - sdf);
- return rc;
+ return ctx->rc;
}
+static void
+buffer_merge_dump_datavec(grn_ctx *ctx,
+ grn_ii *ii,
+ datavec *dv,
+ datavec *rdv)
+{
+ int i, j;
+ grn_obj buffer;
+
+ GRN_TEXT_INIT(&buffer, 0);
+ for (i = 0; i < ii->n_elements; i++) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "rdv[%d] data_size=%d, flags=%d",
+ i, rdv[i].data_size, rdv[i].flags);
+ GRN_BULK_REWIND(&buffer);
+ for (j = 0; j < rdv[i].data_size;) {
+ grn_text_printf(ctx, &buffer, " %d", rdv[i].data[j]);
+ j++;
+ if (!(j % 32) || j == rdv[i].data_size) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "rdv[%d].data[%d]%.*s",
+ i, j,
+ (int)GRN_TEXT_LEN(&buffer),
+ GRN_TEXT_VALUE(&buffer));
+ GRN_BULK_REWIND(&buffer);
+ }
+ }
+ }
+
+ for (i = 0; i < ii->n_elements; i++) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "dv[%d] data_size=%d, flags=%d",
+ i, dv[i].data_size, dv[i].flags);
+ GRN_BULK_REWIND(&buffer);
+ for (j = 0; j < dv[i].data_size;) {
+ grn_text_printf(ctx, &buffer, " %d", dv[i].data[j]);
+ j++;
+ if (!(j % 32) || j == dv[i].data_size) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "dv[%d].data[%d]%.*s",
+ i, j,
+ (int)GRN_TEXT_LEN(&buffer),
+ GRN_TEXT_VALUE(&buffer));
+ GRN_BULK_REWIND(&buffer);
+ }
+ }
+ }
+
+ GRN_OBJ_FIN(ctx, &buffer);
+}
+
+/* If dc doesn't have enough space, program may be crashed.
+ * TODO: Support auto space extension or max size check.
+ */
static grn_rc
buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
buffer *sb, uint8_t *sc, buffer *db, uint8_t *dc)
{
buffer_term *bt;
- grn_rc rc = GRN_SUCCESS;
uint8_t *sbp = NULL, *dcp = dc;
datavec dv[MAX_N_ELEMENTS + 1];
datavec rdv[MAX_N_ELEMENTS + 1];
@@ -2623,8 +3023,18 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
// size_t unitsize = (S_SEGMENT + sb->header.chunk_size) * 2 + (1<<24);
size_t totalsize = unitsize * ii->n_elements;
//todo : realloc
- if ((rc = datavec_init(ctx, dv, ii->n_elements, unitsize, totalsize))) {
- return rc;
+ datavec_init(ctx, dv, ii->n_elements, unitsize, totalsize);
+ if (ctx->rc != GRN_SUCCESS) {
+ DEFINE_NAME(ii);
+ ERR(ctx->rc,
+ "[ii][buffer][merge] failed to initialize data vector: "
+ "<%.*s>: "
+ "unit-size:<%" GRN_FMT_SIZE ">, "
+ "total-size:<%" GRN_FMT_SIZE ">",
+ name_size, name,
+ unitsize,
+ totalsize);
+ return ctx->rc;
}
datavec_init(ctx, rdv, ii->n_elements, 0, 0);
if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {
@@ -2666,7 +3076,21 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
if (!(cinfo = GRN_MALLOCN(chunk_info, nchunks + 1))) {
datavec_fin(ctx, dv);
datavec_fin(ctx, rdv);
- return GRN_NO_MEMORY_AVAILABLE;
+ {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][merge] failed to allocate chunk info: "
+ "<%.*s> :"
+ "segment:<%u>, "
+ "n-chunks:<%u>, "
+ "unit-size:<%" GRN_FMT_SIZE ">, "
+ "total-size:<%" GRN_FMT_SIZE ">",
+ name_size, name,
+ seg,
+ nchunks,
+ unitsize,
+ totalsize);
+ }
+ return ctx->rc;
}
for (i = 0; i < nchunks; i++) {
GRN_B_DEC(cinfo[i].segno, scp);
@@ -2674,12 +3098,24 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
GRN_B_DEC(cinfo[i].dgap, scp);
crid += cinfo[i].dgap;
if (bid.rid <= crid) {
- rc = chunk_merge(ctx, ii, sb, bt, &cinfo[i], crid, dv,
- &nextb, &sbp, &bid, &balance);
- if (rc) {
+ chunk_merge(ctx, ii, sb, bt, &cinfo[i], crid, dv,
+ &nextb, &sbp, &bid, &balance);
+ if (ctx->rc != GRN_SUCCESS) {
+ if (cinfo) { GRN_FREE(cinfo); }
datavec_fin(ctx, dv);
datavec_fin(ctx, rdv);
- return rc;
+ {
+ DEFINE_NAME(ii);
+ ERR(ctx->rc,
+ "[ii][buffer][merge] failed to merge chunk: "
+ "<%.*s>: "
+ "chunk:<%u>, "
+ "n-chunks:<%u>",
+ name_size, name,
+ i,
+ nchunks);
+ }
+ return ctx->rc;
}
}
if (cinfo[i].size) {
@@ -2702,10 +3138,23 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
snn = rdv[j].data_size;
snp = rdv[j].data;
}
- if ((rc = datavec_reset(ctx, dv, ii->n_elements, sdf + S_SEGMENT, size))) {
+ datavec_reset(ctx, dv, ii->n_elements, sdf + S_SEGMENT, size);
+ if (ctx->rc != GRN_SUCCESS) {
+ if (cinfo) { GRN_FREE(cinfo); }
datavec_fin(ctx, dv);
datavec_fin(ctx, rdv);
- return rc;
+ {
+ DEFINE_NAME(ii);
+ ERR(ctx->rc,
+ "[ii][buffer][merge] failed to reset data vector: "
+ "<%.*s>: "
+ "unit-size:<%" GRN_FMT_SIZE ">, "
+ "total-size:<%" GRN_FMT_SIZE ">",
+ name_size, name,
+ (size_t)(sdf + S_SEGMENT),
+ size);
+ }
+ return ctx->rc;
}
}
}
@@ -2719,6 +3168,18 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
}
GETNEXTC();
MERGE_BC(1);
+ if (ctx->rc != GRN_SUCCESS) {
+ if (cinfo) { GRN_FREE(cinfo); }
+ datavec_fin(ctx, dv);
+ datavec_fin(ctx, rdv);
+ {
+ DEFINE_NAME(ii);
+ ERR(ctx->rc,
+ "[ii][buffer][merge] failed to merge chunk: <%.*s>",
+ name_size, name);
+ }
+ return ctx->rc;
+ }
GRN_ASSERT(posp < dv[ii->n_elements].data);
ndf = ridp - dv[0].data;
/*
@@ -2747,7 +3208,7 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
if (tf) { GRN_TEXT_PUTC(ctx, &buf, ','); }
}
GRN_TEXT_PUTC(ctx, &buf, '\0');
- GRN_LOG(ctx, GRN_LOG_NOTICE, "Posting:%s", GRN_TEXT_VALUE(&buf));
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "Posting:%s", GRN_TEXT_VALUE(&buf));
}
GRN_OBJ_FIN(ctx, &buf);
}
@@ -2756,7 +3217,7 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
grn_id tid = bt->tid & GRN_ID_MAX;
uint32_t *a = array_at(ctx, ii, tid);
if (!a) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "array_entry not found tid=%d", tid);
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "array_entry not found tid=%d", tid);
memset(bt, 0, sizeof(buffer_term));
nterms_void++;
} else {
@@ -2813,48 +3274,20 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
}
encsize = grn_p_encv(ctx, dv, ii->n_elements, dcp);
- if (sb->header.chunk_size + S_SEGMENT <= (dcp - dc) + encsize) {
- int i;
-#define BUF_SIZE 255
- char buf[BUF_SIZE], *bufp, *buf_end;
- buf_end = buf + BUF_SIZE;
-#undef BUF_SIZE
- GRN_LOG(ctx, GRN_LOG_NOTICE,
- "cs(%d)+(%d)=(%d)<=(%" GRN_FMT_LLD ")+(%d)=(%" GRN_FMT_LLD ")",
- sb->header.chunk_size, S_SEGMENT, sb->header.chunk_size + S_SEGMENT,
- (long long int)(dcp - dc), encsize, (long long int)((dcp - dc) + encsize));
- for (j = 0; j < ii->n_elements; j++) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "rdv[%d] data_size=%d, flags=%d",
- j, rdv[j].data_size, rdv[j].flags);
- for (i = 0, bufp = buf; i < rdv[j].data_size;) {
- bufp += grn_snprintf(bufp,
- buf_end - bufp,
- buf_end - bufp,
- " %d", rdv[j].data[i]);
- i++;
- if (!(i % 32) || i == rdv[j].data_size) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "rdv[%d].data[%d]%s", j, i, buf);
- bufp = buf;
- }
- }
- }
-
- for (j = 0; j < ii->n_elements; j++) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "dv[%d] data_size=%d, flags=%d",
- j, dv[j].data_size, dv[j].flags);
- for (i = 0, bufp = buf; i < dv[j].data_size;) {
- bufp += grn_snprintf(bufp,
- buf_end - bufp,
- buf_end - bufp,
- " %d", dv[j].data[i]);
- i++;
- if (!(i % 32) || i == dv[j].data_size) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "dv[%d].data[%d]%s", j, i, buf);
- bufp = buf;
- }
- }
+ if (grn_logger_pass(ctx, GRN_LOG_DEBUG)) {
+ if (sb->header.chunk_size + S_SEGMENT <= (dcp - dc) + encsize) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "cs(%d)+(%d)=(%d)"
+ "<=(%" GRN_FMT_LLD ")+(%d)="
+ "(%" GRN_FMT_LLD ")",
+ sb->header.chunk_size,
+ S_SEGMENT,
+ sb->header.chunk_size + S_SEGMENT,
+ (long long int)(dcp - dc),
+ encsize,
+ (long long int)((dcp - dc) + encsize));
+ buffer_merge_dump_datavec(ctx, ii, dv, rdv);
}
-
}
if (encsize > CHUNK_SPLIT_THRESHOLD &&
@@ -2872,7 +3305,7 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
GRN_B_ENC(cinfo[i].dgap, dcp);
}
}
- GRN_LOG(ctx, GRN_LOG_NOTICE, "split (%d) encsize=%d", tid, encsize);
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "split (%d) encsize=%d", tid, encsize);
bt->tid |= CHUNK_SPLIT;
} else {
dcp += encsize;
@@ -2896,7 +3329,7 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
db->header.buffer_free =
S_SEGMENT - sizeof(buffer_header) - db->header.nterms * sizeof(buffer_term);
db->header.nterms_void = nterms_void;
- return rc;
+ return ctx->rc;
}
static void
@@ -2916,40 +3349,68 @@ fake_map(grn_ctx *ctx, grn_io *io, grn_io_win *iw, void *addr, uint32_t seg, uin
static grn_rc
buffer_flush(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
{
- grn_rc rc;
grn_io_win sw, dw;
buffer *sb, *db = NULL;
uint8_t *dc, *sc = NULL;
uint32_t ds, pseg, scn, dcn = 0;
- if (ii->header->binfo[seg] == NOT_ASSIGNED) { return GRN_FILE_CORRUPT; }
- if ((ds = segment_get(ctx, ii)) == MAX_PSEG) { return GRN_NO_MEMORY_AVAILABLE; }
+ if (ii->header->binfo[seg] == GRN_II_PSEG_NOT_ASSIGNED) {
+ DEFINE_NAME(ii);
+ CRIT(GRN_FILE_CORRUPT,
+ "[ii][buffer][flush] invalid segment: "
+ "<%.*s> :"
+ "request:<%u>, max:<%u>",
+ name_size, name,
+ seg, ii->seg->header->max_segment);
+ return ctx->rc;
+ }
+ if ((ds = segment_get(ctx, ii)) == ii->seg->header->max_segment) {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][flush] segment is full: "
+ "<%.*s> :"
+ "request:<%u>, max:<%u>",
+ name_size, name,
+ seg, ii->seg->header->max_segment);
+ return ctx->rc;
+ }
pseg = buffer_open(ctx, ii, SEG2POS(seg, 0), NULL, &sb);
- if (pseg != NOT_ASSIGNED) {
+ if (pseg == GRN_II_PSEG_NOT_ASSIGNED) {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][flush] failed to open buffer: "
+ "<%.*s> :"
+ "segment:<%u>, position:<%u>, max:<%u>",
+ name_size, name,
+ seg, SEG2POS(seg, 0), ii->seg->header->max_segment);
+ return ctx->rc;
+ }
+ {
GRN_IO_SEG_REF(ii->seg, ds, db);
if (db) {
uint32_t actual_chunk_size = 0;
uint32_t max_dest_chunk_size = sb->header.chunk_size + S_SEGMENT;
if ((dc = GRN_MALLOC(max_dest_chunk_size * 2))) {
- if ((scn = sb->header.chunk) == NOT_ASSIGNED ||
+ if ((scn = sb->header.chunk) == GRN_II_PSEG_NOT_ASSIGNED ||
(sc = WIN_MAP(ii->chunk, ctx, &sw, scn, 0,
sb->header.chunk_size, grn_io_rdonly))) {
uint16_t n = sb->header.nterms;
memset(db, 0, S_SEGMENT);
grn_memcpy(db->terms, sb->terms, n * sizeof(buffer_term));
db->header.nterms = n;
- if (!(rc = buffer_merge(ctx, ii, seg, h, sb, sc, db, dc))) {
+ buffer_merge(ctx, ii, seg, h, sb, sc, db, dc);
+ if (ctx->rc == GRN_SUCCESS) {
actual_chunk_size = db->header.chunk_size;
- if (actual_chunk_size >= max_dest_chunk_size) {
- GRN_LOG(ctx, GRN_LOG_WARNING, "actual_chunk_size(%d) >= max_dest_chunk_size(%d)",
- actual_chunk_size, max_dest_chunk_size);
+ if (actual_chunk_size > 0) {
+ chunk_new(ctx, ii, &dcn, actual_chunk_size);
}
- if (!actual_chunk_size || !(rc = chunk_new(ctx, ii, &dcn, actual_chunk_size))) {
- db->header.chunk = actual_chunk_size ? dcn : NOT_ASSIGNED;
+ if (ctx->rc == GRN_SUCCESS) {
+ grn_rc rc;
+ db->header.chunk =
+ actual_chunk_size ? dcn : GRN_II_PSEG_NOT_ASSIGNED;
fake_map(ctx, ii->chunk, &dw, dc, dcn, actual_chunk_size);
- if (!(rc = grn_io_win_unmap(&dw))) {
+ rc = grn_io_win_unmap(&dw);
+ if (rc == GRN_SUCCESS) {
buffer_segment_update(ii, seg, ds);
ii->header->total_chunk_size += actual_chunk_size;
- if (scn != NOT_ASSIGNED) {
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
grn_io_win_unmap(&sw);
chunk_free(ctx, ii, scn, 0, sb->header.chunk_size);
ii->header->total_chunk_size -= sb->header.chunk_size;
@@ -2959,38 +3420,67 @@ buffer_flush(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
if (actual_chunk_size) {
chunk_free(ctx, ii, dcn, 0, actual_chunk_size);
}
- if (scn != NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ {
+ DEFINE_NAME(ii);
+ ERR(rc,
+ "[ii][buffer][flush] failed to unmap a destination chunk: "
+ "<%.*s> : "
+ "segment:<%u>, destination-segment:<%u>, actual-size:<%u>",
+ name_size, name,
+ seg,
+ dcn,
+ actual_chunk_size);
+ }
}
} else {
GRN_FREE(dc);
- if (scn != NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
}
} else {
GRN_FREE(dc);
- if (scn != NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
}
} else {
GRN_FREE(dc);
- rc = GRN_NO_MEMORY_AVAILABLE;
+ {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][flush] failed to map a source chunk: "
+ "<%.*s> :"
+ "segment:<%u>, source-segment:<%u>, chunk-size:<%u>",
+ name_size, name,
+ seg,
+ scn,
+ sb->header.chunk_size);
+ }
}
} else {
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][flush] failed to allocate a destination chunk: "
+ "<%.*s> :"
+ "segment:<%u>, destination-segment:<%u>",
+ name_size, name,
+ seg,
+ ds);
}
GRN_IO_SEG_UNREF(ii->seg, ds);
} else {
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][flush] failed to allocate a destination segment: "
+ "<%.*s> :"
+ "segment:<%u>, destination-segment:<%u>",
+ name_size, name,
+ seg,
+ ds);
}
buffer_close(ctx, ii, pseg);
- } else {
- rc = GRN_NO_MEMORY_AVAILABLE;
}
- return rc;
+ return ctx->rc;
}
void
grn_ii_buffer_check(grn_ctx *ctx, grn_ii *ii, uint32_t seg)
{
- grn_rc rc;
grn_io_win sw;
buffer *sb;
uint8_t *sc = NULL;
@@ -3005,12 +3495,12 @@ grn_ii_buffer_check(grn_ctx *ctx, grn_ii *ii, uint32_t seg)
grn_obj buf;
size_t lower_bound;
int64_t nloops = 0, nviolations = 0;
- if (ii->header->binfo[seg] == NOT_ASSIGNED) {
+ if (ii->header->binfo[seg] == GRN_II_PSEG_NOT_ASSIGNED) {
GRN_OUTPUT_BOOL(GRN_FALSE);
return;
}
pseg = buffer_open(ctx, ii, SEG2POS(seg, 0), NULL, &sb);
- if (pseg == NOT_ASSIGNED) {
+ if (pseg == GRN_II_PSEG_NOT_ASSIGNED) {
GRN_OUTPUT_BOOL(GRN_FALSE);
return;
}
@@ -3024,11 +3514,12 @@ grn_ii_buffer_check(grn_ctx *ctx, grn_ii *ii, uint32_t seg)
GRN_OUTPUT_MAP_OPEN("BUFFER", -1);
GRN_OUTPUT_CSTR("buffer id");
GRN_OUTPUT_INT64(seg);
- if ((scn = sb->header.chunk) == NOT_ASSIGNED) {
+ if ((scn = sb->header.chunk) == GRN_II_PSEG_NOT_ASSIGNED) {
GRN_OUTPUT_CSTR("void chunk size");
GRN_OUTPUT_INT64(sb->header.chunk_size);
} else {
- if ((sc = WIN_MAP(ii->chunk, ctx, &sw, scn, 0, sb->header.chunk_size, grn_io_rdonly))) {
+ if ((sc = WIN_MAP(ii->chunk, ctx, &sw, scn, 0, sb->header.chunk_size,
+ grn_io_rdonly))) {
GRN_OUTPUT_CSTR("chunk size");
GRN_OUTPUT_INT64(sb->header.chunk_size);
} else {
@@ -3057,7 +3548,8 @@ grn_ii_buffer_check(grn_ctx *ctx, grn_ii *ii, uint32_t seg)
}
GRN_OUTPUT_ARRAY_OPEN("TERM", -1);
tid = (bt->tid & GRN_ID_MAX);
- key_size = grn_table_get_key(ctx, ii->lexicon, tid, key, GRN_TABLE_MAX_KEY_SIZE);
+ key_size = grn_table_get_key(ctx, ii->lexicon, tid, key,
+ GRN_TABLE_MAX_KEY_SIZE);
tid_ = grn_table_get(ctx, ii->lexicon, key, key_size);
GRN_TEXT_SET(ctx, &buf, key, key_size);
GRN_OUTPUT_OBJ(&buf, NULL);
@@ -3120,7 +3612,7 @@ grn_ii_buffer_check(grn_ctx *ctx, grn_ii *ii, uint32_t seg)
nviolations++;
}
r = BUFFER_REC_AT(sb, pos);
- p = NEXT_ADDR(r);
+ p = GRN_NEXT_ADDR(r);
GRN_B_DEC(rid, p);
if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
GRN_B_DEC(sid, p);
@@ -3186,9 +3678,11 @@ term_compar(const void *t1, const void *t2)
int r;
const term_sort *x = (term_sort *)t1, *y = (term_sort *)t2;
if (x->key_size > y->key_size) {
- return (r = memcmp(x->key, y->key, y->key_size)) ? r : x->key_size - y->key_size;
+ r = memcmp(x->key, y->key, y->key_size);
+ return r ? r : x->key_size - y->key_size;
} else {
- return (r = memcmp(x->key, y->key, x->key_size)) ? r : x->key_size - y->key_size;
+ r = memcmp(x->key, y->key, x->key_size);
+ return r ? r : x->key_size - y->key_size;
}
}
@@ -3225,7 +3719,8 @@ term_split(grn_ctx *ctx, grn_obj *lexicon, buffer *sb, buffer *db0, buffer *db1)
(*nt)++;
}
GRN_FREE(ts);
- GRN_LOG(ctx, GRN_LOG_NOTICE, "d0=%d d1=%d", db0->header.nterms, db1->header.nterms);
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "d0=%d d1=%d",
+ db0->header.nterms, db1->header.nterms);
return GRN_SUCCESS;
}
@@ -3252,17 +3747,40 @@ array_update(grn_ctx *ctx, grn_ii *ii, uint32_t dls, buffer *db)
static grn_rc
buffer_split(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
{
- grn_rc rc;
grn_io_win sw, dw0, dw1;
buffer *sb, *db0 = NULL, *db1 = NULL;
uint8_t *sc = NULL, *dc0, *dc1;
- uint32_t dps0, dps1, dls0, dls1, sps, scn, dcn0 = 0, dcn1 = 0;
- if (ii->header->binfo[seg] == NOT_ASSIGNED) { return GRN_FILE_CORRUPT; }
- if ((rc = buffer_segment_reserve(ctx, ii, &dls0, &dps0, &dls1, &dps1))) {
- return rc;
+ uint32_t dps0 = 0, dps1 = 0, dls0 = 0, dls1 = 0, sps, scn, dcn0 = 0, dcn1 = 0;
+ if (ii->header->binfo[seg] == GRN_II_PSEG_NOT_ASSIGNED) {
+ DEFINE_NAME(ii);
+ CRIT(GRN_FILE_CORRUPT,
+ "[ii][buffer][split] invalid segment: "
+ "<%.*s> :"
+ "request:<%u>, max:<%u>",
+ name_size, name,
+ seg, ii->seg->header->max_segment);
+ return ctx->rc;
+ }
+ buffer_segment_reserve(ctx, ii, &dls0, &dps0, &dls1, &dps1);
+ if (ctx->rc != GRN_SUCCESS) {
+ DEFINE_NAME(ii);
+ ERR(ctx->rc,
+ "[ii][buffer][split] failed to reserve buffer segments: "
+ "<%.*s> :"
+ "request:<%u>, max:<%u>",
+ name_size, name,
+ seg, ii->seg->header->max_segment);
+ return ctx->rc;
}
sps = buffer_open(ctx, ii, SEG2POS(seg, 0), NULL, &sb);
- if (sps != NOT_ASSIGNED) {
+ if (sps == GRN_II_PSEG_NOT_ASSIGNED) {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][split] failed to open buffer: "
+ "<%.*s> :"
+ "segment:<%u>, position:<%u>, max-segment:<%u>",
+ name_size, name,
+ seg, SEG2POS(seg, 0), ii->seg->header->max_segment);
+ } else {
GRN_IO_SEG_REF(ii->seg, dps0, db0);
if (db0) {
GRN_IO_SEG_REF(ii->seg, dps1, db1);
@@ -3272,34 +3790,36 @@ buffer_split(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
uint32_t max_dest_chunk_size = sb->header.chunk_size + S_SEGMENT;
if ((dc0 = GRN_MALLOC(max_dest_chunk_size * 2))) {
if ((dc1 = GRN_MALLOC(max_dest_chunk_size * 2))) {
- if ((scn = sb->header.chunk) == NOT_ASSIGNED ||
+ if ((scn = sb->header.chunk) == GRN_II_PSEG_NOT_ASSIGNED ||
(sc = WIN_MAP(ii->chunk, ctx, &sw, scn, 0,
sb->header.chunk_size, grn_io_rdonly))) {
term_split(ctx, ii->lexicon, sb, db0, db1);
- if (!(rc = buffer_merge(ctx, ii, seg, h, sb, sc, db0, dc0))) {
+ buffer_merge(ctx, ii, seg, h, sb, sc, db0, dc0);
+ if (ctx->rc == GRN_SUCCESS) {
actual_db0_chunk_size = db0->header.chunk_size;
- if (actual_db0_chunk_size >= max_dest_chunk_size) {
- GRN_LOG(ctx, GRN_LOG_WARNING,
- "actual_db0_chunk_size(%d) >= max_dest_chunk_size(%d)",
- actual_db0_chunk_size, max_dest_chunk_size);
+ if (actual_db0_chunk_size > 0) {
+ chunk_new(ctx, ii, &dcn0, actual_db0_chunk_size);
}
- if (!actual_db0_chunk_size ||
- !(rc = chunk_new(ctx, ii, &dcn0, actual_db0_chunk_size))) {
- db0->header.chunk = actual_db0_chunk_size ? dcn0 : NOT_ASSIGNED;
+ if (ctx->rc == GRN_SUCCESS) {
+ grn_rc rc;
+ db0->header.chunk =
+ actual_db0_chunk_size ? dcn0 : GRN_II_PSEG_NOT_ASSIGNED;
fake_map(ctx, ii->chunk, &dw0, dc0, dcn0, actual_db0_chunk_size);
- if (!(rc = grn_io_win_unmap(&dw0))) {
- if (!(rc = buffer_merge(ctx, ii, seg, h, sb, sc, db1, dc1))) {
+ rc = grn_io_win_unmap(&dw0);
+ if (rc == GRN_SUCCESS) {
+ buffer_merge(ctx, ii, seg, h, sb, sc, db1, dc1);
+ if (ctx->rc == GRN_SUCCESS) {
actual_db1_chunk_size = db1->header.chunk_size;
- if (actual_db1_chunk_size >= max_dest_chunk_size) {
- GRN_LOG(ctx, GRN_LOG_WARNING,
- "actual_db1_chunk_size(%d) >= max_dest_chunk_size(%d)",
- actual_db1_chunk_size, max_dest_chunk_size);
+ if (actual_db1_chunk_size > 0) {
+ chunk_new(ctx, ii, &dcn1, actual_db1_chunk_size);
}
- if (!actual_db1_chunk_size ||
- !(rc = chunk_new(ctx, ii, &dcn1, actual_db1_chunk_size))) {
- fake_map(ctx, ii->chunk, &dw1, dc1, dcn1, actual_db1_chunk_size);
- if (!(rc = grn_io_win_unmap(&dw1))) {
- db1->header.chunk = actual_db1_chunk_size ? dcn1 : NOT_ASSIGNED;
+ if (ctx->rc == GRN_SUCCESS) {
+ fake_map(ctx, ii->chunk, &dw1, dc1, dcn1,
+ actual_db1_chunk_size);
+ rc = grn_io_win_unmap(&dw1);
+ if (rc == GRN_SUCCESS) {
+ db1->header.chunk =
+ actual_db1_chunk_size ? dcn1 : GRN_II_PSEG_NOT_ASSIGNED;
buffer_segment_update(ii, dls0, dps0);
buffer_segment_update(ii, dls1, dps1);
array_update(ctx, ii, dls0, db0);
@@ -3307,7 +3827,7 @@ buffer_split(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
buffer_segment_clear(ii, seg);
ii->header->total_chunk_size += actual_db0_chunk_size;
ii->header->total_chunk_size += actual_db1_chunk_size;
- if (scn != NOT_ASSIGNED) {
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
grn_io_win_unmap(&sw);
chunk_free(ctx, ii, scn, 0, sb->header.chunk_size);
ii->header->total_chunk_size -= sb->header.chunk_size;
@@ -3320,21 +3840,45 @@ buffer_split(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
chunk_free(ctx, ii, dcn0, 0, actual_db0_chunk_size);
}
GRN_FREE(dc1);
- if (scn != NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
+ grn_io_win_unmap(&sw);
+ }
+ {
+ DEFINE_NAME(ii);
+ ERR(rc,
+ "[ii][buffer[merge] "
+ "failed to unmap a destination chunk2: "
+ "<%.*s> :"
+ "segment:<%u>, "
+ "destination-chunk1:<%u>, "
+ "destination-chunk2:<%u>, "
+ "actual-size1:<%u>, "
+ "actual-size2:<%u>",
+ name_size, name,
+ seg,
+ dcn0,
+ dcn1,
+ actual_db0_chunk_size,
+ actual_db1_chunk_size);
+ }
}
} else {
if (actual_db0_chunk_size) {
chunk_free(ctx, ii, dcn0, 0, actual_db0_chunk_size);
}
GRN_FREE(dc1);
- if (scn != NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
+ grn_io_win_unmap(&sw);
+ }
}
} else {
if (actual_db0_chunk_size) {
chunk_free(ctx, ii, dcn0, 0, actual_db0_chunk_size);
}
GRN_FREE(dc1);
- if (scn != NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
+ grn_io_win_unmap(&sw);
+ }
}
} else {
if (actual_db0_chunk_size) {
@@ -3342,132 +3886,329 @@ buffer_split(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
}
GRN_FREE(dc1);
GRN_FREE(dc0);
- if (scn != NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
+ grn_io_win_unmap(&sw);
+ }
+ {
+ DEFINE_NAME(ii);
+ ERR(rc,
+ "[ii][buffer[merge] "
+ "failed to unmap a destination chunk1: "
+ "<%.*s> :"
+ "segment:<%u>, "
+ "destination-chunk1:<%u>, "
+ "actual-size1:<%u>",
+ name_size, name,
+ seg,
+ dcn0,
+ actual_db0_chunk_size);
+ }
}
} else {
GRN_FREE(dc1);
GRN_FREE(dc0);
- if (scn != NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
}
} else {
GRN_FREE(dc1);
GRN_FREE(dc0);
- if (scn != NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
}
} else {
GRN_FREE(dc1);
GRN_FREE(dc0);
- rc = GRN_NO_MEMORY_AVAILABLE;
+ {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][split] failed to map a source chunk: "
+ "<%.*s> :"
+ "segment:<%u>, "
+ "source-segment:<%u>, "
+ "chunk-size:<%u>",
+ name_size, name,
+ seg,
+ scn,
+ sb->header.chunk_size);
+ }
}
} else {
GRN_FREE(dc0);
- rc = GRN_NO_MEMORY_AVAILABLE;
+ {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][split] "
+ "failed to allocate a destination chunk2: "
+ "<%.*s> :"
+ "segment:<%u>, "
+ "destination-segment1:<%u>, "
+ "destination-segment2:<%u>",
+ name_size, name,
+ seg,
+ dps0,
+ dps1);
+ }
}
} else {
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][split] failed to allocate a destination chunk1: "
+ "<%.*s>: "
+ "segment:<%u>, "
+ "destination-segment1:<%u>, "
+ "destination-segment2:<%u>",
+ name_size, name,
+ seg,
+ dps0,
+ dps1);
}
GRN_IO_SEG_UNREF(ii->seg, dps1);
} else {
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][split] failed to allocate a destination segment2: "
+ "<%.*s>: "
+ "segment:<%u>, "
+ "destination-segment1:<%u>, "
+ "destination-segment2:<%u>",
+ name_size, name,
+ seg,
+ dps0,
+ dps1);
}
GRN_IO_SEG_UNREF(ii->seg, dps0);
} else {
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][split] failed to allocate a destination segment1: "
+ "<%.*s>: "
+ "segment:<%u>, "
+ "destination-segment1:<%u>, "
+ "destination-segment2:<%u>",
+ name_size, name,
+ seg,
+ dps0,
+ dps1);
}
buffer_close(ctx, ii, sps);
- } else {
- rc = GRN_NO_MEMORY_AVAILABLE;
}
- return rc;
+ return ctx->rc;
}
#define SCALE_FACTOR 2048
#define MAX_NTERMS 8192
-#define SPLIT_COND (b->header.nterms > 1024 ||\
- (b->header.nterms > 1 &&\
- b->header.chunk_size * 100 > ii->header->total_chunk_size))
+#define SPLIT_COND(ii, buffer)\
+ ((buffer)->header.nterms > 1024 ||\
+ ((buffer)->header.nterms > 1 &&\
+ (buffer)->header.chunk_size * 100 > (ii)->header->total_chunk_size))
-inline static uint32_t
-buffer_new(grn_ctx *ctx, grn_ii *ii, int size, uint32_t *pos,
- buffer_term **bt, buffer_rec **br, buffer **bp, grn_id id, grn_hash *h)
+inline static void
+buffer_new_find_segment(grn_ctx *ctx,
+ grn_ii *ii,
+ int size,
+ grn_id tid,
+ grn_hash *h,
+ buffer **b,
+ uint32_t *lseg,
+ uint32_t *pseg)
{
- buffer *b = NULL;
- grn_id tid;
- uint16_t offset;
- char key[GRN_TABLE_MAX_KEY_SIZE];
- // unsigned int key_size;
- // const char *key = _grn_table_key(ctx, ii->lexicon, id, &key_size);
- int key_size = grn_table_get_key(ctx, ii->lexicon, id, key, GRN_TABLE_MAX_KEY_SIZE);
- uint32_t *a, lseg = NOT_ASSIGNED, pseg = NOT_ASSIGNED;
- grn_table_cursor *tc = NULL;
- if (S_SEGMENT - sizeof(buffer_header) < size + sizeof(buffer_term)) {
- GRN_LOG(ctx, GRN_LOG_CRIT, "requested size(%d) is too large", size);
- return NOT_ASSIGNED;
+ uint32_t *a;
+
+ a = array_at(ctx, ii, tid);
+ if (!a) {
+ return;
}
- if (ii->lexicon->header.type == GRN_TABLE_PAT_KEY) {
- if (ii->lexicon->header.flags & GRN_OBJ_KEY_VAR_SIZE) {
- tc = grn_table_cursor_open(ctx, ii->lexicon, key, key_size, NULL, 0, 0, -1,
- GRN_CURSOR_ASCENDING|GRN_CURSOR_GT);
+
+ for (;;) {
+ uint32_t pos = a[0];
+ if (!pos || (pos & 1)) { break; }
+ *pseg = buffer_open(ctx, ii, pos, NULL, b);
+ if (*pseg == GRN_II_PSEG_NOT_ASSIGNED) { break; }
+ if ((*b)->header.buffer_free >= size + sizeof(buffer_term)) {
+ *lseg = LSEG(pos);
+ break;
+ }
+ buffer_close(ctx, ii, *pseg);
+ if (SPLIT_COND(ii, (*b))) {
+ /* ((S_SEGMENT - sizeof(buffer_header) + ii->header->bmax -
+ (*b)->header.nterms * sizeof(buffer_term)) * 4 <
+ (*b)->header.chunk_size) */
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "nterms=%d chunk=%d total=%" GRN_FMT_INT64U,
+ (*b)->header.nterms,
+ (*b)->header.chunk_size,
+ ii->header->total_chunk_size >> 10);
+ if (buffer_split(ctx, ii, LSEG(pos), h)) { break; }
} else {
- tc = grn_table_cursor_open(ctx, ii->lexicon, NULL, 0, key, key_size, 0, -1,
- GRN_CURSOR_PREFIX);
+ if (S_SEGMENT - sizeof(buffer_header)
+ - (*b)->header.nterms * sizeof(buffer_term)
+ < size + sizeof(buffer_term)) {
+ break;
+ }
+ if (buffer_flush(ctx, ii, LSEG(pos), h)) { break; }
}
- } else {
- tc = grn_table_cursor_open(ctx, ii->lexicon, NULL, 0, NULL, 0, 0, -1,
- GRN_CURSOR_ASCENDING);
}
- if (tc) {
- while (lseg == NOT_ASSIGNED && (tid = grn_table_cursor_next(ctx, tc))) {
- if ((a = array_at(ctx, ii, tid))) {
- for (;;) {
- uint32_t pos = a[0];
- if (!pos || (pos & 1)) { break; }
- if ((pseg = buffer_open(ctx, ii, pos, NULL, &b)) == NOT_ASSIGNED) { break; }
- if (b->header.buffer_free >= size + sizeof(buffer_term)) {
- lseg = LSEG(pos);
- break;
+
+ array_unref(ii, tid);
+}
+
+inline static void
+buffer_new_lexicon_pat(grn_ctx *ctx,
+ grn_ii *ii,
+ int size,
+ grn_id id,
+ grn_hash *h,
+ buffer **b,
+ uint32_t *lseg,
+ uint32_t *pseg)
+{
+ grn_pat_cursor *cursor;
+ char key[GRN_TABLE_MAX_KEY_SIZE];
+ int key_size;
+
+ key_size = grn_table_get_key(ctx, ii->lexicon, id, key,
+ GRN_TABLE_MAX_KEY_SIZE);
+ if (ii->lexicon->header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ grn_obj *tokenizer = NULL;
+
+ grn_table_get_info(ctx, ii->lexicon, NULL, NULL, &tokenizer, NULL, NULL);
+ if (tokenizer) {
+ /* For natural language */
+ cursor = grn_pat_cursor_open(ctx,
+ (grn_pat *)(ii->lexicon),
+ key,
+ key_size,
+ NULL,
+ 0,
+ 0,
+ -1,
+ GRN_CURSOR_ASCENDING|GRN_CURSOR_GT);
+ if (cursor) {
+ grn_id tid;
+ while (ctx->rc == GRN_SUCCESS &&
+ *lseg == GRN_II_PSEG_NOT_ASSIGNED &&
+ (tid = grn_pat_cursor_next(ctx, cursor))) {
+ buffer_new_find_segment(ctx, ii, size, tid, h, b, lseg, pseg);
+ }
+ grn_pat_cursor_close(ctx, cursor);
+ }
+ } else {
+ /* For text data */
+ int target_key_size = key_size;
+ int reduced_key_size = 0;
+
+ while (*lseg == GRN_II_PSEG_NOT_ASSIGNED && target_key_size > 0) {
+ grn_id tid;
+
+ cursor = grn_pat_cursor_open(ctx,
+ (grn_pat *)(ii->lexicon),
+ key, target_key_size,
+ NULL, 0, 0, -1,
+ GRN_CURSOR_PREFIX);
+ if (!cursor) {
+ break;
+ }
+
+ if (reduced_key_size == 0) {
+ while (ctx->rc == GRN_SUCCESS &&
+ *lseg == GRN_II_PSEG_NOT_ASSIGNED &&
+ (tid = grn_pat_cursor_next(ctx, cursor))) {
+ buffer_new_find_segment(ctx, ii, size, tid, h, b, lseg, pseg);
}
- buffer_close(ctx, ii, pseg);
- if (SPLIT_COND)
- /* ((S_SEGMENT - sizeof(buffer_header) + ii->header->bmax -
- b->header.nterms * sizeof(buffer_term)) * 4 <
- b->header.chunk_size) */
- {
- GRN_LOG(ctx, GRN_LOG_NOTICE,
- "nterms=%d chunk=%d total=%" GRN_FMT_INT64U,
- b->header.nterms,
- b->header.chunk_size,
- ii->header->total_chunk_size >> 10);
- if (buffer_split(ctx, ii, LSEG(pos), h)) { break; }
- } else {
- if (S_SEGMENT - sizeof(buffer_header)
- - b->header.nterms * sizeof(buffer_term)
- < size + sizeof(buffer_term)) {
- break;
+ } else {
+ while (ctx->rc == GRN_SUCCESS &&
+ *lseg == GRN_II_PSEG_NOT_ASSIGNED &&
+ (tid = grn_pat_cursor_next(ctx, cursor))) {
+ void *current_key;
+ int current_key_size;
+
+ current_key_size = grn_pat_cursor_get_key(ctx, cursor, &current_key);
+ if (memcmp(((char *)current_key) + target_key_size,
+ key + target_key_size,
+ reduced_key_size) == 0) {
+ continue;
}
- if (buffer_flush(ctx, ii, LSEG(pos), h)) { break; }
+ buffer_new_find_segment(ctx, ii, size, tid, h, b, lseg, pseg);
}
}
- array_unref(ii, tid);
+ grn_pat_cursor_close(ctx, cursor);
+
+ if (reduced_key_size == 0) {
+ reduced_key_size = 1;
+ } else {
+ reduced_key_size *= 2;
+ }
+ target_key_size -= reduced_key_size;
}
}
- grn_table_cursor_close(ctx, tc);
+ } else {
+ /* For other data */
+ cursor = grn_pat_cursor_open(ctx,
+ (grn_pat *)(ii->lexicon),
+ NULL, 0, key, key_size, 0, -1,
+ GRN_CURSOR_PREFIX);
+ if (cursor) {
+ grn_id tid;
+ while (ctx->rc == GRN_SUCCESS &&
+ *lseg == GRN_II_PSEG_NOT_ASSIGNED &&
+ (tid = grn_pat_cursor_next(ctx, cursor))) {
+ buffer_new_find_segment(ctx, ii, size, tid, h, b, lseg, pseg);
+ }
+ grn_pat_cursor_close(ctx, cursor);
+ }
+ }
+}
+
+inline static void
+buffer_new_lexicon_other(grn_ctx *ctx,
+ grn_ii *ii,
+ int size,
+ grn_id id,
+ grn_hash *h,
+ buffer **b,
+ uint32_t *lseg,
+ uint32_t *pseg)
+{
+ GRN_TABLE_EACH_BEGIN(ctx, ii->lexicon, cursor, tid) {
+ if (ctx->rc != GRN_SUCCESS || *lseg != GRN_II_PSEG_NOT_ASSIGNED) {
+ break;
+ }
+ buffer_new_find_segment(ctx, ii, size, tid, h, b, lseg, pseg);
+ } GRN_TABLE_EACH_END(ctx, cursor);
+}
+
+
+inline static uint32_t
+buffer_new(grn_ctx *ctx, grn_ii *ii, int size, uint32_t *pos,
+ buffer_term **bt, buffer_rec **br, buffer **bp, grn_id id, grn_hash *h)
+{
+ buffer *b = NULL;
+ uint16_t offset;
+ uint32_t lseg = GRN_II_PSEG_NOT_ASSIGNED, pseg = GRN_II_PSEG_NOT_ASSIGNED;
+ if (S_SEGMENT - sizeof(buffer_header) < size + sizeof(buffer_term)) {
+ DEFINE_NAME(ii);
+ MERR("[ii][buffer][new] requested size is too large: "
+ "<%.*s> :"
+ "requested:<%" GRN_FMT_SIZE ">, max:<%" GRN_FMT_SIZE ">",
+ name_size, name,
+ (size_t)(size + sizeof(buffer_term)),
+ (size_t)(S_SEGMENT - sizeof(buffer_header)));
+ return GRN_II_PSEG_NOT_ASSIGNED;
+ }
+ if (ii->lexicon->header.type == GRN_TABLE_PAT_KEY) {
+ buffer_new_lexicon_pat(ctx, ii, size, id, h, &b, &lseg, &pseg);
+ } else {
+ buffer_new_lexicon_other(ctx, ii, size, id, h, &b, &lseg, &pseg);
}
- if (lseg == NOT_ASSIGNED) {
+ if (lseg == GRN_II_PSEG_NOT_ASSIGNED) {
if (buffer_segment_new(ctx, ii, &lseg) ||
- (pseg = buffer_open(ctx, ii, SEG2POS(lseg, 0), NULL, &b)) == NOT_ASSIGNED) {
- return NOT_ASSIGNED;
+ (pseg = buffer_open(ctx, ii, SEG2POS(lseg, 0), NULL, &b)) == GRN_II_PSEG_NOT_ASSIGNED) {
+ return GRN_II_PSEG_NOT_ASSIGNED;
}
memset(b, 0, S_SEGMENT);
b->header.buffer_free = S_SEGMENT - sizeof(buffer_header);
- b->header.chunk = NOT_ASSIGNED;
+ b->header.chunk = GRN_II_PSEG_NOT_ASSIGNED;
}
if (b->header.nterms_void) {
for (offset = 0; offset < b->header.nterms; offset++) {
if (!b->terms[offset].tid) { break; }
}
if (offset == b->header.nterms) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "inconsistent buffer(%d)", lseg);
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "inconsistent buffer(%d)", lseg);
b->header.nterms_void = 0;
b->header.nterms++;
b->header.buffer_free -= size + sizeof(buffer_term);
@@ -3492,10 +4233,12 @@ static grn_ii *
_grn_ii_create(grn_ctx *ctx, grn_ii *ii, const char *path, grn_obj *lexicon, uint32_t flags)
{
int i;
+ uint32_t max_n_segments;
+ uint32_t max_n_chunks;
grn_io *seg, *chunk;
char path2[PATH_MAX];
struct grn_ii_header *header;
- grn_obj_flags lflags;
+ grn_table_flags lflags;
grn_encoding encoding;
grn_obj *tokenizer;
/*
@@ -3509,16 +4252,33 @@ _grn_ii_create(grn_ctx *ctx, grn_ii *ii, const char *path, grn_obj *lexicon, uin
return NULL;
}
if (path && strlen(path) + 6 >= PATH_MAX) { return NULL; }
- seg = grn_io_create(ctx, path, sizeof(struct grn_ii_header),
- S_SEGMENT, MAX_PSEG, grn_io_auto, GRN_IO_EXPIRE_SEGMENT);
+
+ if (flags & GRN_OBJ_INDEX_SMALL) {
+ max_n_segments = grn_ii_max_n_segments_small;
+ max_n_chunks = grn_ii_max_n_chunks_small;
+ } else if (flags & GRN_OBJ_INDEX_MEDIUM) {
+ max_n_segments = MAX_PSEG_MEDIUM;
+ max_n_chunks = GRN_II_MAX_CHUNK_MEDIUM;
+ } else {
+ max_n_segments = MAX_PSEG;
+ max_n_chunks = GRN_II_MAX_CHUNK;
+ }
+
+ seg = grn_io_create(ctx,
+ path,
+ sizeof(struct grn_ii_header),
+ S_SEGMENT,
+ max_n_segments,
+ grn_io_auto,
+ GRN_IO_EXPIRE_SEGMENT);
if (!seg) { return NULL; }
if (path) {
grn_strcpy(path2, PATH_MAX, path);
grn_strcat(path2, PATH_MAX, ".c");
- chunk = grn_io_create(ctx, path2, 0, S_CHUNK, GRN_II_MAX_CHUNK, grn_io_auto,
+ chunk = grn_io_create(ctx, path2, 0, S_CHUNK, max_n_chunks, grn_io_auto,
GRN_IO_EXPIRE_SEGMENT);
} else {
- chunk = grn_io_create(ctx, NULL, 0, S_CHUNK, GRN_II_MAX_CHUNK, grn_io_auto, 0);
+ chunk = grn_io_create(ctx, NULL, 0, S_CHUNK, max_n_chunks, grn_io_auto, 0);
}
if (!chunk) {
grn_io_close(ctx, seg);
@@ -3528,12 +4288,12 @@ _grn_ii_create(grn_ctx *ctx, grn_ii *ii, const char *path, grn_obj *lexicon, uin
header = grn_io_header(seg);
grn_io_set_type(seg, GRN_COLUMN_INDEX);
for (i = 0; i < GRN_II_MAX_LSEG; i++) {
- header->ainfo[i] = NOT_ASSIGNED;
- header->binfo[i] = NOT_ASSIGNED;
+ header->ainfo[i] = GRN_II_PSEG_NOT_ASSIGNED;
+ header->binfo[i] = GRN_II_PSEG_NOT_ASSIGNED;
}
for (i = 0; i <= GRN_II_N_CHUNK_VARIATION; i++) {
- header->free_chunks[i] = NOT_ASSIGNED;
- header->garbages[i] = NOT_ASSIGNED;
+ header->free_chunks[i] = GRN_II_PSEG_NOT_ASSIGNED;
+ header->garbages[i] = GRN_II_PSEG_NOT_ASSIGNED;
}
header->flags = flags;
ii->seg = seg;
@@ -3553,7 +4313,7 @@ grn_ii *
grn_ii_create(grn_ctx *ctx, const char *path, grn_obj *lexicon, uint32_t flags)
{
grn_ii *ii = NULL;
- if (!(ii = GRN_GMALLOC(sizeof(grn_ii)))) {
+ if (!(ii = GRN_MALLOCN(grn_ii, 1))) {
return NULL;
}
GRN_DB_OBJ_SET_TYPE(ii, GRN_COLUMN_INDEX);
@@ -3626,7 +4386,8 @@ grn_ii_open(grn_ctx *ctx, const char *path, grn_obj *lexicon)
grn_ii *ii;
char path2[PATH_MAX];
struct grn_ii_header *header;
- grn_obj_flags lflags;
+ uint32_t io_type;
+ grn_table_flags lflags;
grn_encoding encoding;
grn_obj *tokenizer;
if (grn_table_get_info(ctx, lexicon, &lflags, &encoding, &tokenizer,
@@ -3644,13 +4405,16 @@ grn_ii_open(grn_ctx *ctx, const char *path, grn_obj *lexicon)
return NULL;
}
header = grn_io_header(seg);
- if (grn_io_get_type(seg) != GRN_COLUMN_INDEX) {
- ERR(GRN_INVALID_FORMAT, "file type unmatch");
+ io_type = grn_io_get_type(seg);
+ if (io_type != GRN_COLUMN_INDEX) {
+ ERR(GRN_INVALID_FORMAT,
+ "[column][index] file type must be %#04x: <%#04x>",
+ GRN_COLUMN_INDEX, io_type);
grn_io_close(ctx, seg);
grn_io_close(ctx, chunk);
return NULL;
}
- if (!(ii = GRN_GMALLOC(sizeof(grn_ii)))) {
+ if (!(ii = GRN_MALLOCN(grn_ii, 1))) {
grn_io_close(ctx, seg);
grn_io_close(ctx, chunk);
return NULL;
@@ -3676,12 +4440,12 @@ grn_ii_close(grn_ctx *ctx, grn_ii *ii)
if (!ii) { return GRN_INVALID_ARGUMENT; }
if ((rc = grn_io_close(ctx, ii->seg))) { return rc; }
if ((rc = grn_io_close(ctx, ii->chunk))) { return rc; }
- GRN_GFREE(ii);
+ GRN_FREE(ii);
/*
{
int i;
for (i = 0; i < 32; i++) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "new[%d]=%d free[%d]=%d",
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "new[%d]=%d free[%d]=%d",
i, new_histogram[i],
i, free_histogram[i]);
}
@@ -3710,6 +4474,26 @@ grn_ii_info(grn_ctx *ctx, grn_ii *ii, uint64_t *seg_size, uint64_t *chunk_size)
return GRN_SUCCESS;
}
+grn_column_flags
+grn_ii_get_flags(grn_ctx *ctx, grn_ii *ii)
+{
+ if (!ii) {
+ return 0;
+ }
+
+ return ii->header->flags;
+}
+
+uint32_t
+grn_ii_get_n_elements(grn_ctx *ctx, grn_ii *ii)
+{
+ if (!ii) {
+ return 0;
+ }
+
+ return ii->n_elements;
+}
+
void
grn_ii_expire(grn_ctx *ctx, grn_ii *ii)
{
@@ -3732,31 +4516,62 @@ grn_ii_flush(grn_ctx *ctx, grn_ii *ii)
return rc;
}
+size_t
+grn_ii_get_disk_usage(grn_ctx *ctx, grn_ii *ii)
+{
+ size_t usage;
+
+ usage = grn_io_get_disk_usage(ctx, ii->seg);
+ usage += grn_io_get_disk_usage(ctx, ii->chunk);
+
+ return usage;
+}
+
#define BIT11_01(x) ((x >> 1) & 0x7ff)
#define BIT31_12(x) (x >> 12)
grn_rc
grn_ii_update_one(grn_ctx *ctx, grn_ii *ii, grn_id tid, grn_ii_updspec *u, grn_hash *h)
{
- grn_rc rc = GRN_SUCCESS;
buffer *b;
uint8_t *bs;
buffer_rec *br = NULL;
buffer_term *bt;
uint32_t pseg = 0, pos = 0, size, *a;
- if (!tid) { return rc; }
+ if (!tid) { return ctx->rc; }
if (!u->tf || !u->sid) { return grn_ii_delete_one(ctx, ii, tid, u, h); }
if (u->sid > ii->header->smax) { ii->header->smax = u->sid; }
- if (!(a = array_get(ctx, ii, tid))) { return GRN_NO_MEMORY_AVAILABLE; }
+ if (!(a = array_get(ctx, ii, tid))) {
+ DEFINE_NAME(ii);
+ MERR("[ii][update][one] failed to allocate an array: "
+ "<%.*s>: "
+ "<%u>:<%u>:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid);
+ return ctx->rc;
+ }
if (!(bs = encode_rec(ctx, ii, u, &size, 0))) {
- rc = GRN_NO_MEMORY_AVAILABLE; goto exit;
+ DEFINE_NAME(ii);
+ MERR("[ii][update][one] failed to encode a record: "
+ "<%.*s>: "
+ "<%u>:<%u>:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid);
+ goto exit;
}
for (;;) {
if (a[0]) {
if (!(a[0] & 1)) {
pos = a[0];
- if ((pseg = buffer_open(ctx, ii, pos, &bt, &b)) == NOT_ASSIGNED) {
- rc = GRN_NO_MEMORY_AVAILABLE;
+ if ((pseg = buffer_open(ctx, ii, pos, &bt, &b)) == GRN_II_PSEG_NOT_ASSIGNED) {
+ DEFINE_NAME(ii);
+ MERR("[ii][update][one] failed to allocate a buffer: "
+ "<%.*s>: "
+ "<%u>:<%u>:<%u>: "
+ "segment:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid,
+ pos);
goto exit;
}
if (b->header.buffer_free < size) {
@@ -3764,38 +4579,77 @@ grn_ii_update_one(grn_ctx *ctx, grn_ii *ii, grn_id tid, grn_ii_updspec *u, grn_h
GRN_LOG(ctx, GRN_LOG_DEBUG, "flushing a[0]=%d seg=%d(%p) free=%d",
a[0], LSEG(a[0]), b, b->header.buffer_free);
buffer_close(ctx, ii, pseg);
- if (SPLIT_COND)
+ if (SPLIT_COND(ii, b)) {
/*((S_SEGMENT - sizeof(buffer_header) + ii->header->bmax -
b->header.nterms * sizeof(buffer_term)) * 4 <
b->header.chunk_size)*/
- {
- GRN_LOG(ctx, GRN_LOG_NOTICE,
- "nterms=%d chunk=%d total=%" GRN_FMT_INT64U,
- b->header.nterms,
- b->header.chunk_size,
- ii->header->total_chunk_size >> 10);
- if ((rc = buffer_split(ctx, ii, LSEG(pos), h))) { goto exit; }
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "nterms=%d chunk=%d total=%" GRN_FMT_INT64U,
+ b->header.nterms,
+ b->header.chunk_size,
+ ii->header->total_chunk_size >> 10);
+ buffer_split(ctx, ii, LSEG(pos), h);
+ if (ctx->rc != GRN_SUCCESS) {
+ DEFINE_NAME(ii);
+ ERR(ctx->rc,
+ "[ii][update][one] failed to split a buffer: "
+ "<%.*s>: "
+ "<%u>:<%u><%u>: "
+ "segment:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid,
+ pos);
+ goto exit;
+ }
continue;
}
- if ((rc = buffer_flush(ctx, ii, LSEG(pos), h))) { goto exit; }
+ buffer_flush(ctx, ii, LSEG(pos), h);
+ if (ctx->rc != GRN_SUCCESS) {
+ DEFINE_NAME(ii);
+ ERR(ctx->rc,
+ "[ii][update][one] failed to flush a buffer: "
+ "<%.*s>: "
+ "<%u>:<%u><%u>: "
+ "segment:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid,
+ pos);
+ goto exit;
+ }
if (a[0] != pos) {
- GRN_LOG(ctx, GRN_LOG_DEBUG, "grn_ii_update_one: a[0] changed %d->%d", a[0], pos);
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "grn_ii_update_one: a[0] changed %d->%d", a[0], pos);
continue;
}
- if ((pseg = buffer_open(ctx, ii, pos, &bt, &b)) == NOT_ASSIGNED) {
+ if ((pseg = buffer_open(ctx, ii, pos, &bt, &b)) == GRN_II_PSEG_NOT_ASSIGNED) {
GRN_LOG(ctx, GRN_LOG_CRIT, "buffer not found a[0]=%d", a[0]);
- rc = GRN_NO_MEMORY_AVAILABLE;
+ {
+ DEFINE_NAME(ii);
+ MERR("[ii][update][one] failed to reallocate a buffer: "
+ "<%.*s>: "
+ "<%u>:<%u>:<%u>: "
+ "segment:<%u>, new-segment:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid,
+ pos, a[0]);
+ }
goto exit;
}
- GRN_LOG(ctx, GRN_LOG_DEBUG, "flushed a[0]=%d seg=%d(%p) free=%d->%d nterms=%d v=%d",
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "flushed a[0]=%d seg=%d(%p) free=%d->%d nterms=%d v=%d",
a[0], LSEG(a[0]), b, bfb, b->header.buffer_free,
b->header.nterms, b->header.nterms_void);
if (b->header.buffer_free < size) {
+ DEFINE_NAME(ii);
+ MERR("[ii][update][one] buffer is full: "
+ "<%.*s>: "
+ "<%u>:<%u><%u>: "
+ "segment:<%u>, new-segment:<%u>, free:<%u>, required:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid,
+ pos, a[0], b->header.buffer_free, size);
buffer_close(ctx, ii, pseg);
- GRN_LOG(ctx, GRN_LOG_CRIT, "buffer(%d) is full (%d < %d) in grn_ii_update_one",
- a[0], b->header.buffer_free, size);
/* todo: direct merge */
- rc = GRN_NO_MEMORY_AVAILABLE;
goto exit;
}
}
@@ -3821,13 +4675,27 @@ grn_ii_update_one(grn_ctx *ctx, grn_ii *ii, grn_id tid, grn_ii_updspec *u, grn_h
if (u2.rid != u->rid || u2.sid != u->sid) {
uint8_t *bs2 = encode_rec(ctx, ii, &u2, &size2, 0);
if (!bs2) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "encode_rec on grn_ii_update_one failed !");
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][update][one] failed to encode a record2: "
+ "<%.*s>: "
+ "<%u>:<%u>:<%u>",
+ name_size, name,
+ u2.rid, u2.sid, tid);
goto exit;
}
pseg = buffer_new(ctx, ii, size + size2, &pos, &bt, &br, &b, tid, h);
- if (pseg == NOT_ASSIGNED) {
+ if (pseg == GRN_II_PSEG_NOT_ASSIGNED) {
GRN_FREE(bs2);
+ {
+ DEFINE_NAME(ii);
+ MERR("[ii][update][one] failed to create a buffer2: "
+ "<%.*s>: "
+ "<%u>:<%u>:<%u>: "
+ "size:<%u>",
+ name_size, name,
+ u2.rid, u2.sid, tid,
+ size + size2);
+ }
goto exit;
}
bt->tid = tid;
@@ -3835,9 +4703,18 @@ grn_ii_update_one(grn_ctx *ctx, grn_ii *ii, grn_id tid, grn_ii_updspec *u, grn_h
bt->pos_in_chunk = 0;
bt->size_in_buffer = 0;
bt->pos_in_buffer = 0;
- if ((rc = buffer_put(ctx, ii, b, bt, br, bs2, &u2, size2))) {
+ buffer_put(ctx, ii, b, bt, br, bs2, &u2, size2);
+ if (ctx->rc != GRN_SUCCESS) {
GRN_FREE(bs2);
buffer_close(ctx, ii, pseg);
+ {
+ DEFINE_NAME(ii);
+ MERR("[ii][update][one] failed to put to buffer: "
+ "<%.*s>: "
+ "<%u>:<%u>:<%u>",
+ name_size, name,
+ u2.rid, u2.sid, tid);
+ }
goto exit;
}
br = (buffer_rec *)(((byte *)br) + size2);
@@ -3862,45 +4739,81 @@ grn_ii_update_one(grn_ctx *ctx, grn_ii *ii, grn_id tid, grn_ii_updspec *u, grn_h
}
}
pseg = buffer_new(ctx, ii, size, &pos, &bt, &br, &b, tid, h);
- if (pseg == NOT_ASSIGNED) { goto exit; }
+ if (pseg == GRN_II_PSEG_NOT_ASSIGNED) {
+ DEFINE_NAME(ii);
+ MERR("[ii][update][one] failed to create a buffer: "
+ "<%.*s>: "
+ "<%u>:<%u>:<%u>: "
+ "size:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid,
+ size);
+ goto exit;
+ }
bt->tid = tid;
bt->size_in_chunk = 0;
bt->pos_in_chunk = 0;
bt->size_in_buffer = 0;
bt->pos_in_buffer = 0;
}
- rc = buffer_put(ctx, ii, b, bt, br, bs, u, size);
+ buffer_put(ctx, ii, b, bt, br, bs, u, size);
buffer_close(ctx, ii, pseg);
if (!a[0] || (a[0] & 1)) { a[0] = pos; }
exit :
array_unref(ii, tid);
if (bs) { GRN_FREE(bs); }
if (u->tf != u->atf) {
+ grn_obj *source_table;
+ char source_table_name[GRN_TABLE_MAX_KEY_SIZE];
+ int source_table_name_size;
char term[GRN_TABLE_MAX_KEY_SIZE];
int term_size;
+
+ source_table = grn_ctx_at(ctx, DB_OBJ(ii)->range);
+ if (source_table) {
+ source_table_name_size = grn_obj_name(ctx,
+ source_table,
+ source_table_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ } else {
+ grn_strcpy(source_table_name, GRN_TABLE_MAX_KEY_SIZE, "(null)");
+ source_table_name_size = strlen(source_table_name);
+ }
term_size = grn_table_get_key(ctx, ii->lexicon, tid,
term, GRN_TABLE_MAX_KEY_SIZE);
- GRN_LOG(ctx, GRN_LOG_WARNING,
- "too many postings(%d). %d postings are discarded. "
- "term: <%d>(<%.*s>)",
- u->atf, u->atf - u->tf,
- tid, term_size, term);
+ {
+ DEFINE_NAME(ii);
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "[ii][update][one] too many postings: "
+ "<%.*s>: "
+ "record:<%.*s>(%d), "
+ "n-postings:<%d>, "
+ "n-discarded-postings:<%d>, "
+ "term:<%d>(<%.*s>)",
+ name_size, name,
+ source_table_name_size, source_table_name,
+ u->rid,
+ u->atf,
+ u->atf - u->tf,
+ tid, term_size, term);
+ }
}
grn_ii_expire(ctx, ii);
- return rc;
+ return ctx->rc;
}
grn_rc
grn_ii_delete_one(grn_ctx *ctx, grn_ii *ii, grn_id tid, grn_ii_updspec *u, grn_hash *h)
{
- grn_rc rc = GRN_SUCCESS;
buffer *b;
uint8_t *bs = NULL;
buffer_rec *br;
buffer_term *bt;
uint32_t pseg, size, *a;
- if (!tid) { return rc; }
- if (!(a = array_at(ctx, ii, tid))) { return GRN_INVALID_ARGUMENT; }
+ if (!tid) { return ctx->rc; }
+ if (!(a = array_at(ctx, ii, tid))) {
+ return ctx->rc;
+ }
for (;;) {
if (!a[0]) { goto exit; }
if (a[0] & 1) {
@@ -3921,31 +4834,70 @@ grn_ii_delete_one(grn_ctx *ctx, grn_ii *ii, grn_id tid, grn_ii_updspec *u, grn_h
goto exit;
}
if (!(bs = encode_rec(ctx, ii, u, &size, 1))) {
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][delete][one] failed to encode a record: "
+ "<%.*s>: "
+ "<%u>:<%u>:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid);
goto exit;
}
- if ((pseg = buffer_open(ctx, ii, a[0], &bt, &b)) == NOT_ASSIGNED) {
- rc = GRN_NO_MEMORY_AVAILABLE;
+ if ((pseg = buffer_open(ctx, ii, a[0], &bt, &b)) == GRN_II_PSEG_NOT_ASSIGNED) {
+ DEFINE_NAME(ii);
+ MERR("[ii][delete][one] failed to allocate a buffer: "
+ "<%.*s>: "
+ "<%u>:<%u><%u>: "
+ "position:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid,
+ a[0]);
goto exit;
}
if (b->header.buffer_free < size) {
uint32_t _a = a[0];
- GRN_LOG(ctx, GRN_LOG_DEBUG, "flushing! b=%p free=%d, seg(%d)", b, b->header.buffer_free, LSEG(a[0]));
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "flushing! b=%p free=%d, seg(%d)",
+ b, b->header.buffer_free, LSEG(a[0]));
buffer_close(ctx, ii, pseg);
- if ((rc = buffer_flush(ctx, ii, LSEG(a[0]), h))) { goto exit; }
+ buffer_flush(ctx, ii, LSEG(a[0]), h);
+ if (ctx->rc != GRN_SUCCESS) {
+ DEFINE_NAME(ii);
+ ERR(ctx->rc,
+ "[ii][delete][one] failed to flush a buffer: "
+ "<%.*s>: "
+ "<%u>:<%u><%u>: "
+ "position:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid,
+ a[0]);
+ goto exit;
+ }
if (a[0] != _a) {
- GRN_LOG(ctx, GRN_LOG_DEBUG, "grn_ii_delete_one: a[0] changed %d->%d)", a[0], _a);
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "grn_ii_delete_one: a[0] changed %d->%d)",
+ a[0], _a);
continue;
}
- if ((pseg = buffer_open(ctx, ii, a[0], &bt, &b)) == NOT_ASSIGNED) {
- rc = GRN_NO_MEMORY_AVAILABLE;
+ if ((pseg = buffer_open(ctx, ii, a[0], &bt, &b)) == GRN_II_PSEG_NOT_ASSIGNED) {
+ DEFINE_NAME(ii);
+ MERR("[ii][delete][one] failed to reallocate a buffer: "
+ "<%.*s>: "
+ "<%u>:<%u><%u>: "
+ "position:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid,
+ a[0]);
goto exit;
}
- GRN_LOG(ctx, GRN_LOG_DEBUG, "flushed! b=%p free=%d, seg(%d)", b, b->header.buffer_free, LSEG(a[0]));
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "flushed! b=%p free=%d, seg(%d)",
+ b, b->header.buffer_free, LSEG(a[0]));
if (b->header.buffer_free < size) {
- GRN_LOG(ctx, GRN_LOG_CRIT, "buffer(%d) is full (%d < %d) in grn_ii_delete_one",
- a[0], b->header.buffer_free, size);
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][delete][one] buffer is full: "
+ "<%.*s>: "
+ "<%u>:<%u><%u>: "
+ "segment:<%u>, free:<%u>, required:<%u>",
+ name_size, name,
+ u->rid, u->sid, tid,
+ a[0], b->header.buffer_free, size);
buffer_close(ctx, ii, pseg);
goto exit;
}
@@ -3953,14 +4905,14 @@ grn_ii_delete_one(grn_ctx *ctx, grn_ii *ii, grn_id tid, grn_ii_updspec *u, grn_h
b->header.buffer_free -= size;
br = (buffer_rec *)(((byte *)&b->terms[b->header.nterms]) + b->header.buffer_free);
- rc = buffer_put(ctx, ii, b, bt, br, bs, u, size);
+ buffer_put(ctx, ii, b, bt, br, bs, u, size);
buffer_close(ctx, ii, pseg);
break;
}
exit :
array_unref(ii, tid);
if (bs) { GRN_FREE(bs); }
- return rc;
+ return ctx->rc;
}
#define CHUNK_USED 1
@@ -3973,20 +4925,20 @@ struct _grn_ii_cursor {
grn_ctx *ctx;
grn_ii *ii;
grn_id id;
- grn_ii_posting *post;
+ grn_posting *post;
- grn_id min;
+ grn_id min; /* Minimum record ID */
grn_id max;
- grn_ii_posting pc;
- grn_ii_posting pb;
+ grn_posting pc;
+ grn_posting pb;
- uint32_t cdf;
+ uint32_t cdf; /* Document frequency */
uint32_t *cdp;
- uint32_t *crp;
- uint32_t *csp;
- uint32_t *ctp;
- uint32_t *cwp;
- uint32_t *cpp;
+ uint32_t *crp; /* Record ID */
+ uint32_t *csp; /* Section ID */
+ uint32_t *ctp; /* Term frequency */
+ uint32_t *cwp; /* Weight */
+ uint32_t *cpp; /* Position */
uint8_t *bp;
@@ -4005,19 +4957,24 @@ struct _grn_ii_cursor {
uint32_t buffer_pseg;
int flags;
uint32_t *ppseg;
+
+ int weight;
+
+ uint32_t prev_chunk_rid;
};
-static int
+static grn_bool
buffer_is_reused(grn_ctx *ctx, grn_ii *ii, grn_ii_cursor *c)
{
if (*c->ppseg != c->buffer_pseg) {
uint32_t i;
- for (i = ii->header->bgqtail; i != ii->header->bgqhead; i = (i + 1) & (GRN_II_BGQSIZE - 1)) {
- if (ii->header->bgqbody[i] == c->buffer_pseg) { return 0; }
+ for (i = ii->header->bgqtail; i != ii->header->bgqhead;
+ i = (i + 1) & (GRN_II_BGQSIZE - 1)) {
+ if (ii->header->bgqbody[i] == c->buffer_pseg) { return GRN_FALSE; }
}
- return 1;
+ return GRN_TRUE;
}
- return 0;
+ return GRN_FALSE;
}
static int
@@ -4034,9 +4991,10 @@ chunk_is_reused(grn_ctx *ctx, grn_ii *ii, grn_ii_cursor *c, uint32_t offset, uin
m = GRN_II_W_LEAST_CHUNK;
}
gseg = ii->header->garbages[m - GRN_II_W_LEAST_CHUNK];
- while (gseg != NOT_ASSIGNED) {
+ while (gseg != GRN_II_PSEG_NOT_ASSIGNED) {
grn_io_win iw;
- grn_ii_ginfo *ginfo = WIN_MAP(ii->chunk, ctx, &iw, gseg, 0, S_GARBAGE, grn_io_rdwr);
+ grn_ii_ginfo *ginfo = WIN_MAP(ii->chunk, ctx, &iw, gseg, 0, S_GARBAGE,
+ grn_io_rdwr);
if (!ginfo) { break; }
for (i = 0; i < ginfo->nrecs; i++) {
if (ginfo->recs[i] == offset) {
@@ -4078,6 +5036,7 @@ grn_ii_cursor_open(grn_ctx *ctx, grn_ii *ii, grn_id tid,
c->max = max;
c->nelements = nelements;
c->flags = flags;
+ c->weight = 0;
if (pos & 1) {
c->stat = 0;
if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
@@ -4093,13 +5052,14 @@ grn_ii_cursor_open(grn_ctx *ctx, grn_ii *ii, grn_id tid,
} else {
uint32_t chunk;
buffer_term *bt;
- if ((c->buffer_pseg = buffer_open(ctx, ii, pos, &bt, &c->buf)) == NOT_ASSIGNED) {
+ c->buffer_pseg = buffer_open(ctx, ii, pos, &bt, &c->buf);
+ if (c->buffer_pseg == GRN_II_PSEG_NOT_ASSIGNED) {
GRN_FREE(c);
c = NULL;
goto exit;
}
c->ppseg = &ii->header->binfo[LSEG(pos)];
- if (bt->size_in_chunk && (chunk = c->buf->header.chunk) != NOT_ASSIGNED) {
+ if (bt->size_in_chunk && (chunk = c->buf->header.chunk) != GRN_II_PSEG_NOT_ASSIGNED) {
if (!(c->cp = WIN_MAP(ii->chunk, ctx, &c->iw, chunk, bt->pos_in_chunk,
bt->size_in_chunk, grn_io_rdonly))) {
buffer_close(ctx, ii, c->buffer_pseg);
@@ -4132,7 +5092,10 @@ grn_ii_cursor_open(grn_ctx *ctx, grn_ii *ii, grn_id tid,
GRN_B_DEC(c->cinfo[i].size, c->cp);
GRN_B_DEC(c->cinfo[i].dgap, c->cp);
crid += c->cinfo[i].dgap;
- if (crid < min) { c->curr_chunk = i + 1; }
+ if (crid < min) {
+ c->pc.rid = crid;
+ c->curr_chunk = i + 1;
+ }
}
if (chunk_is_reused(ctx, ii, c, chunk, c->buf->header.chunk_size)) {
grn_ii_cursor_close(ctx, c);
@@ -4162,11 +5125,23 @@ grn_ii_cursor_set_min(grn_ctx *ctx, grn_ii_cursor *c, grn_id min)
}
if (grn_ii_cursor_set_min_enable) {
+ grn_id old_min = c->min;
c->min = min;
- if (c->buf && c->pc.rid < c->min && c->curr_chunk < c->nchunks) {
- uint32_t i, skip_chunk = 0;
- grn_id rid;
- for (i = 0, rid = GRN_ID_NIL; i < c->nchunks; i++) {
+ if (c->buf &&
+ c->pc.rid != GRN_ID_NIL &&
+ c->pc.rid < c->min &&
+ c->prev_chunk_rid < c->min &&
+ c->curr_chunk < c->nchunks) {
+ uint32_t i;
+ uint32_t skip_chunk = 0;
+ grn_id rid = c->prev_chunk_rid;
+
+ if (c->curr_chunk > 0) {
+ i = c->curr_chunk - 1;
+ } else {
+ i = 0;
+ }
+ for (; i < c->nchunks; i++) {
rid += c->cinfo[i].dgap;
if (rid < c->min) {
skip_chunk = i + 1;
@@ -4176,17 +5151,36 @@ grn_ii_cursor_set_min(grn_ctx *ctx, grn_ii_cursor *c, grn_id min)
}
}
if (skip_chunk > c->curr_chunk) {
+ uint32_t old_chunk = c->curr_chunk;
+ grn_bool old_chunk_used = (c->stat & CHUNK_USED);
c->pc.rid = rid;
+ c->pc.rest = 0;
+ c->prev_chunk_rid = rid - c->cinfo[skip_chunk - 1].dgap;
c->curr_chunk = skip_chunk;
c->crp = c->cdp + c->cdf;
+ c->stat |= CHUNK_USED;
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "[ii][cursor][min] skip: %p: min(%u->%u): chunk(%u->%u): "
+ "chunk-used(%s->%s)",
+ c,
+ old_min, min,
+ old_chunk, c->curr_chunk,
+ old_chunk_used ? "true" : "false",
+ (c->stat & CHUNK_USED) ? "true" : "false");
}
}
}
}
-grn_ii_posting *
-grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
+typedef struct {
+ grn_bool include_garbage;
+} grn_ii_cursor_next_options;
+
+static inline grn_posting *
+grn_ii_cursor_next_internal(grn_ctx *ctx, grn_ii_cursor *c,
+ grn_ii_cursor_next_options *options)
{
+ const grn_bool include_garbage = options->include_garbage;
if (c->buf) {
for (;;) {
if (c->stat & CHUNK_USED) {
@@ -4228,7 +5222,7 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
}
GRN_TEXT_PUTC(ctx, &buf, ')');
GRN_TEXT_PUTC(ctx, &buf, '\0');
- GRN_LOG(ctx, GRN_LOG_NOTICE, "posting(%d):%s", count, GRN_TEXT_VALUE(&buf));
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "posting(%d):%s", count, GRN_TEXT_VALUE(&buf));
GRN_OBJ_FIN(ctx, &buf);
}
*/
@@ -4236,9 +5230,41 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
if (c->curr_chunk <= c->nchunks) {
if (c->curr_chunk == c->nchunks) {
if (c->cp < c->cpe) {
- grn_p_decv(ctx, c->cp, c->cpe - c->cp, c->rdv, c->ii->n_elements);
+ int decoded_size;
+ decoded_size =
+ grn_p_decv(ctx, c->cp, c->cpe - c->cp,
+ c->rdv, c->ii->n_elements);
+ if (decoded_size == 0) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "[ii][cursor][next][chunk][last] "
+ "chunk(%d) is changed by another thread "
+ "while decoding: %p",
+ c->cinfo[c->curr_chunk].segno,
+ c);
+ c->pc.rid = GRN_ID_NIL;
+ break;
+ }
+ if (buffer_is_reused(ctx, c->ii, c)) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "[ii][cursor][next][chunk][last] "
+ "buffer is reused by another thread: %p",
+ c);
+ c->pc.rid = GRN_ID_NIL;
+ break;
+ }
+ if (chunk_is_reused(ctx, c->ii, c,
+ c->buf->header.chunk,
+ c->buf->header.chunk_size)) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "[ii][cursor][next][chunk][last] "
+ "chunk(%d) is reused by another thread: %p",
+ c->buf->header.chunk,
+ c);
+ c->pc.rid = GRN_ID_NIL;
+ break;
+ }
} else {
- c->pc.rid = 0;
+ c->pc.rid = GRN_ID_NIL;
break;
}
} else {
@@ -4248,18 +5274,32 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
if (size && (cp = WIN_MAP(c->ii->chunk, ctx, &iw,
c->cinfo[c->curr_chunk].segno, 0,
size, grn_io_rdonly))) {
- grn_p_decv(ctx, cp, size, c->rdv, c->ii->n_elements);
+ int decoded_size;
+ decoded_size =
+ grn_p_decv(ctx, cp, size, c->rdv, c->ii->n_elements);
grn_io_win_unmap(&iw);
+ if (decoded_size == 0) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "[ii][cursor][next][chunk] "
+ "chunk(%d) is changed by another thread "
+ "while decoding: %p",
+ c->cinfo[c->curr_chunk].segno,
+ c);
+ c->pc.rid = GRN_ID_NIL;
+ break;
+ }
if (chunk_is_reused(ctx, c->ii, c,
c->cinfo[c->curr_chunk].segno, size)) {
GRN_LOG(ctx, GRN_LOG_WARNING,
- "chunk(%d) is reused by another thread",
- c->cinfo[c->curr_chunk].segno);
- c->pc.rid = 0;
+ "[ii][cursor][next][chunk] "
+ "chunk(%d) is reused by another thread: %p",
+ c->cinfo[c->curr_chunk].segno,
+ c);
+ c->pc.rid = GRN_ID_NIL;
break;
}
} else {
- c->pc.rid = 0;
+ c->pc.rid = GRN_ID_NIL;
break;
}
}
@@ -4274,15 +5314,18 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
if ((c->ii->header->flags & GRN_OBJ_WITH_WEIGHT)) {
c->cwp = c->rdv[j++].data;
}
- c->cpp = c->rdv[j].data;
+ if ((c->ii->header->flags & GRN_OBJ_WITH_POSITION)) {
+ c->cpp = c->rdv[j].data;
+ }
}
- c->pc.rid = 0;
+ c->prev_chunk_rid = c->pc.rid;
+ c->pc.rid = GRN_ID_NIL;
c->pc.sid = 0;
c->pc.rest = 0;
c->curr_chunk++;
continue;
} else {
- c->pc.rid = 0;
+ c->pc.rid = GRN_ID_NIL;
}
}
break;
@@ -4294,10 +5337,15 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
uint32_t lrid = c->pb.rid, lsid = c->pb.sid; /* for check */
buffer_rec *br = BUFFER_REC_AT(c->buf, c->nextb);
if (buffer_is_reused(ctx, c->ii, c)) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "buffer reused(%d,%d)", c->buffer_pseg, *c->ppseg);
- // todo : rewind;
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "[ii][cursor][next][buffer] "
+ "buffer(%d,%d) is reused by another thread: %p",
+ c->buffer_pseg, *c->ppseg,
+ c);
+ c->pb.rid = GRN_ID_NIL;
+ break;
}
- c->bp = NEXT_ADDR(br);
+ c->bp = GRN_NEXT_ADDR(br);
GRN_B_DEC(c->pb.rid, c->bp);
if ((c->ii->header->flags & GRN_OBJ_WITH_SECTION)) {
GRN_B_DEC(c->pb.sid, c->bp);
@@ -4305,20 +5353,34 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
c->pb.sid = 1;
}
if (lrid > c->pb.rid || (lrid == c->pb.rid && lsid >= c->pb.sid)) {
- ERR(GRN_FILE_CORRUPT, "brokend!! (%d:%d) -> (%d:%d) (%d->%d)", lrid, lsid, c->pb.rid, c->pb.sid, c->buffer_pseg, *c->ppseg);
+ DEFINE_NAME(c->ii);
+ ERR(GRN_FILE_CORRUPT,
+ "[ii][broken][cursor][next][buffer] "
+ "posting in list in buffer isn't sorted: "
+ "<%.*s>: (%d:%d) -> (%d:%d) (%d->%d)",
+ name_size, name,
+ lrid, lsid,
+ c->pb.rid, c->pb.sid,
+ c->buffer_pseg, *c->ppseg);
+ c->pb.rid = GRN_ID_NIL;
+ break;
}
if (c->pb.rid < c->min) {
c->pb.rid = 0;
- if (br->jump > 0) {
+ if (br->jump > 0 && !BUFFER_REC_DELETED(br)) {
buffer_rec *jump_br = BUFFER_REC_AT(c->buf, br->jump);
- uint8_t *jump_bp;
- uint32_t jump_rid;
- jump_bp = NEXT_ADDR(jump_br);
- GRN_B_DEC(jump_rid, jump_bp);
- if (jump_rid < c->min) {
- c->nextb = br->jump;
- } else {
+ if (BUFFER_REC_DELETED(jump_br)) {
c->nextb = br->step;
+ } else {
+ uint8_t *jump_bp;
+ uint32_t jump_rid;
+ jump_bp = GRN_NEXT_ADDR(jump_br);
+ GRN_B_DEC(jump_rid, jump_bp);
+ if (jump_rid < c->min) {
+ c->nextb = br->jump;
+ } else {
+ c->nextb = br->step;
+ }
}
} else {
c->nextb = br->step;
@@ -4344,20 +5406,32 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
if (c->pc.rid) {
if (c->pc.rid < c->pb.rid) {
c->stat = CHUNK_USED;
- if (c->pc.tf && c->pc.sid) { c->post = &c->pc; break; }
+ if (include_garbage || (c->pc.tf && c->pc.sid)) {
+ c->post = &c->pc;
+ break;
+ }
} else {
if (c->pb.rid < c->pc.rid) {
c->stat = BUFFER_USED;
- if (c->pb.tf && c->pb.sid) { c->post = &c->pb; break; }
+ if (include_garbage || (c->pb.tf && c->pb.sid)) {
+ c->post = &c->pb;
+ break;
+ }
} else {
if (c->pb.sid) {
if (c->pc.sid < c->pb.sid) {
c->stat = CHUNK_USED;
- if (c->pc.tf && c->pc.sid) { c->post = &c->pc; break; }
+ if (include_garbage || (c->pc.tf && c->pc.sid)) {
+ c->post = &c->pc;
+ break;
+ }
} else {
c->stat = BUFFER_USED;
if (c->pb.sid == c->pc.sid) { c->stat |= CHUNK_USED; }
- if (c->pb.tf) { c->post = &c->pb; break; }
+ if (include_garbage || (c->pb.tf)) {
+ c->post = &c->pb;
+ break;
+ }
}
} else {
c->stat = CHUNK_USED;
@@ -4366,12 +5440,18 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
}
} else {
c->stat = BUFFER_USED;
- if (c->pb.tf && c->pb.sid) { c->post = &c->pb; break; }
+ if (include_garbage || (c->pb.tf && c->pb.sid)) {
+ c->post = &c->pb;
+ break;
+ }
}
} else {
if (c->pc.rid) {
c->stat = CHUNK_USED;
- if (c->pc.tf && c->pc.sid) { c->post = &c->pc; break; }
+ if (include_garbage || (c->pc.tf && c->pc.sid)) {
+ c->post = &c->pc;
+ break;
+ }
} else {
c->post = NULL;
return NULL;
@@ -4394,7 +5474,16 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
return c->post;
}
-grn_ii_posting *
+grn_posting *
+grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c)
+{
+ grn_ii_cursor_next_options options = {
+ .include_garbage = GRN_FALSE
+ };
+ return grn_ii_cursor_next_internal(ctx, c, &options);
+}
+
+grn_posting *
grn_ii_cursor_next_pos(grn_ctx *ctx, grn_ii_cursor *c)
{
uint32_t gap;
@@ -4410,8 +5499,12 @@ grn_ii_cursor_next_pos(grn_ctx *ctx, grn_ii_cursor *c)
}
} else if (c->post == &c->pb) {
if (buffer_is_reused(ctx, c->ii, c)) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "buffer reused(%d,%d)", c->buffer_pseg, *c->ppseg);
- // todo : rewind;
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "[ii][cursor][next][pos][buffer] "
+ "buffer(%d,%d) is reused by another thread: %p",
+ c->buffer_pseg, *c->ppseg,
+ c);
+ return NULL;
}
if (c->pb.rest) {
c->pb.rest--;
@@ -4466,7 +5559,7 @@ grn_ii_get_chunksize(grn_ctx *ctx, grn_ii *ii, grn_id tid)
buffer *buf;
uint32_t pseg;
buffer_term *bt;
- if ((pseg = buffer_open(ctx, ii, pos, &bt, &buf)) == NOT_ASSIGNED) {
+ if ((pseg = buffer_open(ctx, ii, pos, &bt, &buf)) == GRN_II_PSEG_NOT_ASSIGNED) {
res = 0;
} else {
res = bt->size_in_chunk;
@@ -4493,7 +5586,7 @@ grn_ii_estimate_size(grn_ctx *ctx, grn_ii *ii, grn_id tid)
buffer *buf;
uint32_t pseg;
buffer_term *bt;
- if ((pseg = buffer_open(ctx, ii, pos, &bt, &buf)) == NOT_ASSIGNED) {
+ if ((pseg = buffer_open(ctx, ii, pos, &bt, &buf)) == GRN_II_PSEG_NOT_ASSIGNED) {
res = 0;
} else {
res = a[1] + bt->size_in_buffer + 2;
@@ -4509,8 +5602,10 @@ grn_ii_estimate_size(grn_ctx *ctx, grn_ii *ii, grn_id tid)
int
grn_ii_entry_info(grn_ctx *ctx, grn_ii *ii, grn_id tid, unsigned int *a,
- unsigned int *chunk, unsigned int *chunk_size, unsigned int *buffer_free,
- unsigned int *nterms, unsigned int *nterms_void, unsigned int *bt_tid,
+ unsigned int *chunk, unsigned int *chunk_size,
+ unsigned int *buffer_free,
+ unsigned int *nterms, unsigned int *nterms_void,
+ unsigned int *bt_tid,
unsigned int *size_in_chunk, unsigned int *pos_in_chunk,
unsigned int *size_in_buffer, unsigned int *pos_in_buffer)
{
@@ -4524,7 +5619,7 @@ grn_ii_entry_info(grn_ctx *ctx, grn_ii *ii, grn_id tid, unsigned int *a,
array_unref(ii, tid);
if (!a[0]) { return 1; }
if (a[0] & 1) { return 2; }
- if ((pseg = buffer_open(ctx, ii, a[0], &bt, &b)) == NOT_ASSIGNED) { return 3; }
+ if ((pseg = buffer_open(ctx, ii, a[0], &bt, &b)) == GRN_II_PSEG_NOT_ASSIGNED) { return 3; }
*chunk = b->header.chunk;
*chunk_size = b->header.chunk_size;
*buffer_free = b->header.buffer_free;
@@ -4582,7 +5677,8 @@ cursor_heap_open(grn_ctx *ctx, int max)
}
static inline grn_rc
-cursor_heap_push(grn_ctx *ctx, cursor_heap *h, grn_ii *ii, grn_id tid, uint32_t offset2)
+cursor_heap_push(grn_ctx *ctx, cursor_heap *h, grn_ii *ii, grn_id tid, uint32_t offset2,
+ int weight, grn_id min)
{
int n, n2;
grn_ii_cursor *c, *c2;
@@ -4595,7 +5691,7 @@ cursor_heap_push(grn_ctx *ctx, cursor_heap *h, grn_ii *ii, grn_id tid, uint32_t
h->bins = bins;
}
{
- if (!(c = grn_ii_cursor_open(ctx, ii, tid, GRN_ID_NIL, GRN_ID_MAX,
+ if (!(c = grn_ii_cursor_open(ctx, ii, tid, min, GRN_ID_MAX,
ii->n_elements, 0))) {
GRN_LOG(ctx, GRN_LOG_ERROR, "cursor open failed");
return ctx->rc;
@@ -4605,10 +5701,25 @@ cursor_heap_push(grn_ctx *ctx, cursor_heap *h, grn_ii *ii, grn_id tid, uint32_t
return GRN_END_OF_DATA;
}
if (!grn_ii_cursor_next_pos(ctx, c)) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "invalid ii_cursor b");
+ if (grn_logger_pass(ctx, GRN_LOG_ERROR)) {
+ char token[GRN_TABLE_MAX_KEY_SIZE];
+ int token_size;
+ token_size = grn_table_get_key(ctx,
+ c->ii->lexicon,
+ c->id,
+ &token,
+ GRN_TABLE_MAX_KEY_SIZE);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "[ii][cursor][heap][push] invalid cursor: "
+ "%p: token:<%.*s>(%u)",
+ c, token_size, token, c->id);
+ }
grn_ii_cursor_close(ctx, c);
return GRN_END_OF_DATA;
}
+ if (weight) {
+ c->weight = weight;
+ }
n = h->n_entries++;
while (n) {
n2 = (n - 1) >> 1;
@@ -4677,7 +5788,19 @@ cursor_heap_pop(grn_ctx *ctx, cursor_heap *h, grn_id min)
grn_ii_cursor_close(ctx, c);
h->bins[0] = h->bins[--h->n_entries];
} else if (!grn_ii_cursor_next_pos(ctx, c)) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "invalid ii_cursor c");
+ if (grn_logger_pass(ctx, GRN_LOG_ERROR)) {
+ char token[GRN_TABLE_MAX_KEY_SIZE];
+ int token_size;
+ token_size = grn_table_get_key(ctx,
+ c->ii->lexicon,
+ c->id,
+ &token,
+ GRN_TABLE_MAX_KEY_SIZE);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "[ii][cursor][heap][pop] invalid cursor: "
+ "%p: token:<%.*s>(%u)",
+ c, token_size, token, c->id);
+ }
grn_ii_cursor_close(ctx, c);
h->bins[0] = h->bins[--h->n_entries];
}
@@ -4695,7 +5818,19 @@ cursor_heap_pop_pos(grn_ctx *ctx, cursor_heap *h)
grn_ii_cursor_close(ctx, c);
h->bins[0] = h->bins[--h->n_entries];
} else if (!grn_ii_cursor_next_pos(ctx, c)) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "invalid ii_cursor d");
+ if (grn_logger_pass(ctx, GRN_LOG_ERROR)) {
+ char token[GRN_TABLE_MAX_KEY_SIZE];
+ int token_size;
+ token_size = grn_table_get_key(ctx,
+ c->ii->lexicon,
+ c->id,
+ &token,
+ GRN_TABLE_MAX_KEY_SIZE);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "[ii][cursor][heap][pop][position] invalid cursor: "
+ "%p: token:<%.*s>(%u)",
+ c, token_size, token, c->id);
+ }
grn_ii_cursor_close(ctx, c);
h->bins[0] = h->bins[--h->n_entries];
}
@@ -4734,7 +5869,8 @@ index_add(grn_ctx *ctx, grn_id rid, grn_obj *lexicon, grn_ii *ii, grn_vgram *vgr
return GRN_NO_MEMORY_AVAILABLE;
}
if (vgram) { sbuf = grn_vgram_buf_open(value_len); }
- h = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(grn_ii_updspec *), GRN_HASH_TINY);
+ h = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(grn_ii_updspec *),
+ GRN_HASH_TINY);
if (!h) {
GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_create on index_add failed !");
grn_token_cursor_close(ctx, token_cursor);
@@ -4744,15 +5880,19 @@ index_add(grn_ctx *ctx, grn_id rid, grn_obj *lexicon, grn_ii *ii, grn_vgram *vgr
while (!token_cursor->status) {
(tid = grn_token_cursor_next(ctx, token_cursor));
if (tid) {
- if (!grn_hash_add(ctx, h, &tid, sizeof(grn_id), (void **) &u, NULL)) { break; }
+ if (!grn_hash_add(ctx, h, &tid, sizeof(grn_id), (void **) &u, NULL)) {
+ break;
+ }
if (!*u) {
if (!(*u = grn_ii_updspec_open(ctx, rid, 1))) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "grn_ii_updspec_open on index_add failed!");
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "grn_ii_updspec_open on index_add failed!");
goto exit;
}
}
if (grn_ii_updspec_add(ctx, *u, token_cursor->pos, 0)) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "grn_ii_updspec_add on index_add failed!");
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "grn_ii_updspec_add on index_add failed!");
goto exit;
}
if (sbuf) { grn_vgram_buf_add(sbuf, tid); }
@@ -4790,7 +5930,8 @@ index_del(grn_ctx *ctx, grn_id rid, grn_obj *lexicon, grn_ii *ii, grn_vgram *vgr
GRN_TOKEN_DEL, token_flags))) {
return GRN_NO_MEMORY_AVAILABLE;
}
- h = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(grn_ii_updspec *), GRN_HASH_TINY);
+ h = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(grn_ii_updspec *),
+ GRN_HASH_TINY);
if (!h) {
GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_create on index_del failed !");
grn_token_cursor_close(ctx, token_cursor);
@@ -4798,10 +5939,13 @@ index_del(grn_ctx *ctx, grn_id rid, grn_obj *lexicon, grn_ii *ii, grn_vgram *vgr
}
while (!token_cursor->status) {
if ((tid = grn_token_cursor_next(ctx, token_cursor))) {
- if (!grn_hash_add(ctx, h, &tid, sizeof(grn_id), (void **) &u, NULL)) { break; }
+ if (!grn_hash_add(ctx, h, &tid, sizeof(grn_id), (void **) &u, NULL)) {
+ break;
+ }
if (!*u) {
if (!(*u = grn_ii_updspec_open(ctx, rid, 0))) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_ii_updspec_open on index_del failed !");
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_ii_updspec_open on index_del failed !");
grn_hash_close(ctx, h);
grn_token_cursor_close(ctx, token_cursor);
return GRN_NO_MEMORY_AVAILABLE;
@@ -4863,23 +6007,27 @@ grn_ii_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, grn_vgram *vgram, unsigned i
return GRN_INVALID_ARGUMENT;
}
if (newvalues) {
- new = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(grn_ii_updspec *), GRN_HASH_TINY);
+ new = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(grn_ii_updspec *),
+ GRN_HASH_TINY);
if (!new) {
GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_create on grn_ii_update failed !");
rc = GRN_NO_MEMORY_AVAILABLE;
goto exit;
}
for (j = newvalues->n_values, v = newvalues->values; j; j--, v++) {
- if ((token_cursor = grn_token_cursor_open(ctx, lexicon, v->str, v->str_len,
- GRN_TOKEN_ADD, token_flags))) {
+ if ((token_cursor = grn_token_cursor_open(ctx, lexicon, v->str,
+ v->str_len, GRN_TOKEN_ADD,
+ token_flags))) {
while (!token_cursor->status) {
if ((tid = grn_token_cursor_next(ctx, token_cursor))) {
- if (!grn_hash_add(ctx, new, &tid, sizeof(grn_id), (void **) &u, NULL)) {
+ if (!grn_hash_add(ctx, new, &tid, sizeof(grn_id), (void **) &u,
+ NULL)) {
break;
}
if (!*u) {
if (!(*u = grn_ii_updspec_open(ctx, rid, section))) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_ii_updspec_open on grn_ii_update failed!");
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_ii_updspec_open on grn_ii_update failed!");
grn_token_cursor_close(ctx, token_cursor);
grn_hash_close(ctx, new);
rc = GRN_NO_MEMORY_AVAILABLE;
@@ -4887,7 +6035,8 @@ grn_ii_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, grn_vgram *vgram, unsigned i
}
}
if (grn_ii_updspec_add(ctx, *u, token_cursor->pos, v->weight)) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_ii_updspec_add on grn_ii_update failed!");
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_ii_updspec_add on grn_ii_update failed!");
grn_token_cursor_close(ctx, token_cursor);
grn_hash_close(ctx, new);
rc = GRN_NO_MEMORY_AVAILABLE;
@@ -4906,24 +6055,29 @@ grn_ii_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, grn_vgram *vgram, unsigned i
new = NULL;
}
if (oldvalues) {
- old = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(grn_ii_updspec *), GRN_HASH_TINY);
+ old = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(grn_ii_updspec *),
+ GRN_HASH_TINY);
if (!old) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_create(ctx, NULL, old) on grn_ii_update failed!");
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_hash_create(ctx, NULL, old) on grn_ii_update failed!");
if (new) { grn_hash_close(ctx, new); }
rc = GRN_NO_MEMORY_AVAILABLE;
goto exit;
}
for (j = oldvalues->n_values, v = oldvalues->values; j; j--, v++) {
- if ((token_cursor = grn_token_cursor_open(ctx, lexicon, v->str, v->str_len,
- GRN_TOKEN_DEL, token_flags))) {
+ if ((token_cursor = grn_token_cursor_open(ctx, lexicon, v->str,
+ v->str_len, GRN_TOKEN_DEL,
+ token_flags))) {
while (!token_cursor->status) {
if ((tid = grn_token_cursor_next(ctx, token_cursor))) {
- if (!grn_hash_add(ctx, old, &tid, sizeof(grn_id), (void **) &u, NULL)) {
+ if (!grn_hash_add(ctx, old, &tid, sizeof(grn_id), (void **) &u,
+ NULL)) {
break;
}
if (!*u) {
if (!(*u = grn_ii_updspec_open(ctx, rid, section))) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_ii_updspec_open on grn_ii_update failed!");
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_ii_updspec_open on grn_ii_update failed!");
grn_token_cursor_close(ctx, token_cursor);
if (new) { grn_hash_close(ctx, new); };
grn_hash_close(ctx, old);
@@ -4932,7 +6086,8 @@ grn_ii_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, grn_vgram *vgram, unsigned i
}
}
if (grn_ii_updspec_add(ctx, *u, token_cursor->pos, v->weight)) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_ii_updspec_add on grn_ii_update failed!");
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_ii_updspec_add on grn_ii_update failed!");
grn_token_cursor_close(ctx, token_cursor);
if (new) { grn_hash_close(ctx, new); };
grn_hash_close(ctx, old);
@@ -4950,7 +6105,8 @@ grn_ii_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, grn_vgram *vgram, unsigned i
if (old) {
grn_id eid;
GRN_HASH_EACH(ctx, old, id, &tp, NULL, &u, {
- if (new && (eid = grn_hash_get(ctx, new, tp, sizeof(grn_id), (void **) &un))) {
+ if (new && (eid = grn_hash_get(ctx, new, tp, sizeof(grn_id),
+ (void **) &un))) {
if (!grn_ii_updspec_cmp(*u, *un)) {
grn_ii_updspec_close(ctx, *un);
grn_hash_delete_by_id(ctx, new, eid, NULL);
@@ -5000,25 +6156,39 @@ grn_vector2updspecs(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
for (j = in->u.v.n_sections, v = in->u.v.sections; j; j--, v++) {
unsigned int token_flags = 0;
if (v->length &&
- (token_cursor = grn_token_cursor_open(ctx, lexicon, head + v->offset, v->length,
- mode, token_flags))) {
+ (token_cursor = grn_token_cursor_open(ctx, lexicon, head + v->offset,
+ v->length, mode,
+ token_flags))) {
while (!token_cursor->status) {
if ((tid = grn_token_cursor_next(ctx, token_cursor))) {
if (posting) { GRN_RECORD_PUT(ctx, posting, tid); }
- if (!grn_hash_add(ctx, h, &tid, sizeof(grn_id), (void **) &u, NULL)) {
+ if (!grn_hash_add(ctx, h, &tid, sizeof(grn_id), (void **) &u,
+ NULL)) {
break;
}
if (!*u) {
if (!(*u = grn_ii_updspec_open(ctx, rid, section))) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_ii_updspec_open on grn_ii_update failed!");
+ DEFINE_NAME(ii);
+ MERR("[ii][update][spec] failed to create an update spec: "
+ "<%.*s>: "
+ "record:<%u>:<%u>, token:<%u>:<%d>:<%u>",
+ name_size, name,
+ rid, section,
+ tid, token_cursor->pos, v->weight);
grn_token_cursor_close(ctx, token_cursor);
- return GRN_NO_MEMORY_AVAILABLE;
+ return ctx->rc;
}
}
if (grn_ii_updspec_add(ctx, *u, token_cursor->pos, v->weight)) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_ii_updspec_add on grn_ii_update failed!");
+ DEFINE_NAME(ii);
+ MERR("[ii][update][spec] failed to add to update spec: "
+ "<%.*s>: "
+ "record:<%u>:<%u>, token:<%u>:<%d>:<%u>",
+ name_size, name,
+ rid, section,
+ tid, token_cursor->pos, v->weight);
grn_token_cursor_close(ctx, token_cursor);
- return GRN_NO_MEMORY_AVAILABLE;
+ return ctx->rc;
}
}
}
@@ -5026,7 +6196,7 @@ grn_vector2updspecs(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
}
}
}
- return GRN_SUCCESS;
+ return ctx->rc;
}
static grn_rc
@@ -5042,10 +6212,14 @@ grn_uvector2updspecs_data(grn_ctx *ctx, grn_ii *ii, grn_id rid,
n = grn_uvector_size(ctx, in);
element_size = grn_uvector_element_size(ctx, in);
for (i = 0; i < n; i++) {
+ grn_obj *tokenizer;
grn_token_cursor *token_cursor;
unsigned int token_flags = 0;
const char *element;
+ tokenizer = grn_obj_get_info(ctx, lexicon, GRN_INFO_DEFAULT_TOKENIZER,
+ NULL);
+
element = GRN_BULK_HEAD(in) + (element_size * i);
token_cursor = grn_token_cursor_open(ctx, lexicon,
element, element_size,
@@ -5058,6 +6232,7 @@ grn_uvector2updspecs_data(grn_ctx *ctx, grn_ii *ii, grn_id rid,
grn_id tid;
if ((tid = grn_token_cursor_next(ctx, token_cursor))) {
grn_ii_updspec **u;
+ int pos;
if (posting) { GRN_RECORD_PUT(ctx, posting, tid); }
if (!grn_hash_add(ctx, h, &tid, sizeof(grn_id), (void **)&u, NULL)) {
@@ -5071,7 +6246,12 @@ grn_uvector2updspecs_data(grn_ctx *ctx, grn_ii *ii, grn_id rid,
return GRN_NO_MEMORY_AVAILABLE;
}
}
- if (grn_ii_updspec_add(ctx, *u, token_cursor->pos, 0)) {
+ if (tokenizer) {
+ pos = token_cursor->pos;
+ } else {
+ pos = i;
+ }
+ if (grn_ii_updspec_add(ctx, *u, pos, 0)) {
GRN_LOG(ctx, GRN_LOG_ALERT,
"grn_ii_updspec_add on grn_uvector2updspecs failed!");
grn_token_cursor_close(ctx, token_cursor);
@@ -5105,12 +6285,14 @@ grn_uvector2updspecs_id(grn_ctx *ctx, grn_ii *ii, grn_id rid,
}
if (!*u) {
if (!(*u = grn_ii_updspec_open(ctx, rid, section))) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_ii_updspec_open on grn_ii_update failed!");
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_ii_updspec_open on grn_ii_update failed!");
return GRN_NO_MEMORY_AVAILABLE;
}
}
if (grn_ii_updspec_add(ctx, *u, i, weight)) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_ii_updspec_add on grn_ii_update failed!");
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_ii_updspec_add on grn_ii_update failed!");
return GRN_NO_MEMORY_AVAILABLE;
}
}
@@ -5136,12 +6318,75 @@ grn_ii_column_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
{
grn_id *tp;
grn_bool do_grn_ii_updspec_cmp = GRN_TRUE;
- grn_rc rc = GRN_SUCCESS;
grn_ii_updspec **u, **un;
- grn_obj *old_, *old = oldvalue, *new_, *new = newvalue, oldv, newv, buf, *post = NULL;
- if (!ii || !ii->lexicon || !rid) {
- ERR(GRN_INVALID_ARGUMENT, "grn_ii_column_update: invalid argument");
- return GRN_INVALID_ARGUMENT;
+ grn_obj *old_, *old = oldvalue, *new_, *new = newvalue, oldv, newv;
+ grn_obj buf, *post = NULL;
+
+ if (!ii) {
+ ERR(GRN_INVALID_ARGUMENT, "[ii][column][update] ii is NULL");
+ return ctx->rc;
+ }
+ if (!ii->lexicon) {
+ ERR(GRN_INVALID_ARGUMENT, "[ii][column][update] lexicon is NULL");
+ return ctx->rc;
+ }
+ if (rid == GRN_ID_NIL) {
+ ERR(GRN_INVALID_ARGUMENT, "[ii][column][update] record ID is nil");
+ return ctx->rc;
+ }
+ if (old || new) {
+ unsigned char type = GRN_VOID;
+ if (old) {
+ type = (ii->obj.header.domain == old->header.domain)
+ ? GRN_UVECTOR
+ : old->header.type;
+ }
+ if (new) {
+ type = (ii->obj.header.domain == new->header.domain)
+ ? GRN_UVECTOR
+ : new->header.type;
+ }
+ if (type == GRN_VECTOR) {
+ grn_obj *tokenizer;
+ grn_table_get_info(ctx, ii->lexicon, NULL, NULL, &tokenizer, NULL, NULL);
+ if (tokenizer) {
+ grn_obj old_elem, new_elem;
+ unsigned int i, max_n;
+ unsigned int old_n = 0, new_n = 0;
+ if (old) {
+ old_n = grn_vector_size(ctx, old);
+ }
+ if (new) {
+ new_n = grn_vector_size(ctx, new);
+ }
+ max_n = (old_n > new_n) ? old_n : new_n;
+ GRN_OBJ_INIT(&old_elem, GRN_BULK, GRN_OBJ_DO_SHALLOW_COPY, old->header.domain);
+ GRN_OBJ_INIT(&new_elem, GRN_BULK, GRN_OBJ_DO_SHALLOW_COPY, new->header.domain);
+ for (i = 0; i < max_n; i++) {
+ grn_rc rc;
+ grn_obj *old_p = NULL, *new_p = NULL;
+ if (i < old_n) {
+ const char *str;
+ unsigned int size = grn_vector_get_element(ctx, old, i, &str, NULL, NULL);
+ GRN_TEXT_SET_REF(&old_elem, str, size);
+ old_p = &old_elem;
+ }
+ if (i < new_n) {
+ const char *str;
+ unsigned int size = grn_vector_get_element(ctx, new, i, &str, NULL, NULL);
+ GRN_TEXT_SET_REF(&new_elem, str, size);
+ new_p = &new_elem;
+ }
+ rc = grn_ii_column_update(ctx, ii, rid, section + i, old_p, new_p, posting);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ GRN_OBJ_FIN(ctx, &old_elem);
+ GRN_OBJ_FIN(ctx, &new_elem);
+ return ctx->rc;
+ }
+ }
}
if (posting) {
GRN_RECORD_INIT(&buf, GRN_OBJ_VECTOR, grn_obj_id(ctx, ii->lexicon));
@@ -5172,13 +6417,16 @@ grn_ii_column_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
sizeof(grn_ii_updspec *),
GRN_HASH_TINY);
if (!new) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_create on grn_ii_update failed !");
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][column][update][new][vector] failed to create a hash table: "
+ "<%.*s>: ",
+ name_size, name);
} else {
- rc = grn_vector2updspecs(ctx, ii, rid, section, new_, new, GRN_TOKEN_ADD, post);
+ grn_vector2updspecs(ctx, ii, rid, section, new_, new,
+ GRN_TOKEN_ADD, post);
}
if (new_ != newvalue) { grn_obj_close(ctx, new_); }
- if (rc) { goto exit; }
+ if (ctx->rc != GRN_SUCCESS) { goto exit; }
break;
case GRN_UVECTOR :
new_ = new;
@@ -5186,32 +6434,45 @@ grn_ii_column_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
sizeof(grn_ii_updspec *),
GRN_HASH_TINY);
if (!new) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_create on grn_ii_update failed !");
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][column][update][new][uvector] failed to create a hash table: "
+ "<%.*s>: ",
+ name_size, name);
} else {
if (new_->header.type == GRN_UVECTOR) {
- rc = grn_uvector2updspecs(ctx, ii, rid, section, new_, new,
- GRN_TOKEN_ADD, post);
+ grn_uvector2updspecs(ctx, ii, rid, section, new_, new,
+ GRN_TOKEN_ADD, post);
} else {
grn_obj uvector;
unsigned int weight = 0;
- GRN_VALUE_FIX_SIZE_INIT(&uvector, GRN_OBJ_VECTOR, new_->header.domain);
+ GRN_VALUE_FIX_SIZE_INIT(&uvector, GRN_OBJ_VECTOR,
+ new_->header.domain);
if (new_->header.impl_flags & GRN_OBJ_WITH_WEIGHT) {
uvector.header.impl_flags |= GRN_OBJ_WITH_WEIGHT;
}
- grn_uvector_add_element(ctx, &uvector, GRN_RECORD_VALUE(new_), weight);
- rc = grn_uvector2updspecs(ctx, ii, rid, section, &uvector, new,
- GRN_TOKEN_ADD, post);
+ grn_uvector_add_element(ctx, &uvector, GRN_RECORD_VALUE(new_),
+ weight);
+ grn_uvector2updspecs(ctx, ii, rid, section, &uvector, new,
+ GRN_TOKEN_ADD, post);
GRN_OBJ_FIN(ctx, &uvector);
}
}
if (new_ != newvalue) { grn_obj_close(ctx, new_); }
- if (rc) { goto exit; }
+ if (ctx->rc != GRN_SUCCESS) { goto exit; }
break;
case GRN_TABLE_HASH_KEY :
break;
default :
- ERR(GRN_INVALID_ARGUMENT, "invalid object assigned as newvalue");
+ {
+ DEFINE_NAME(ii);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[ii][column][update][new] invalid object: "
+ "<%.*s>: "
+ "<%s>(%#x)",
+ name_size, name,
+ grn_obj_type_to_string(type),
+ type);
+ }
goto exit;
}
}
@@ -5238,7 +6499,8 @@ grn_ii_column_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
});
tpe = (grn_id *)GRN_BULK_CURR(post);
for (tp = (grn_id *)GRN_BULK_HEAD(post); tp < tpe; tp++) {
- grn_hash_get(ctx, (grn_hash *)new, (void *)tp, sizeof(grn_id), (void **)&u);
+ grn_hash_get(ctx, (grn_hash *)new, (void *)tp, sizeof(grn_id),
+ (void **)&u);
GRN_TEXT_PUT(ctx, posting, &(*u)->offset, sizeof(int32_t));
}
GRN_OBJ_FIN(ctx, post);
@@ -5268,13 +6530,16 @@ grn_ii_column_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
sizeof(grn_ii_updspec *),
GRN_HASH_TINY);
if (!old) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_create(ctx, NULL, old) on grn_ii_update failed!");
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][column][update][old][vector] failed to create a hash table: "
+ "<%.*s>: ",
+ name_size, name);
} else {
- rc = grn_vector2updspecs(ctx, ii, rid, section, old_, old, GRN_TOKEN_DEL, NULL);
+ grn_vector2updspecs(ctx, ii, rid, section, old_, old,
+ GRN_TOKEN_DEL, NULL);
}
if (old_ != oldvalue) { grn_obj_close(ctx, old_); }
- if (rc) { goto exit; }
+ if (ctx->rc != GRN_SUCCESS) { goto exit; }
break;
case GRN_UVECTOR :
old_ = old;
@@ -5282,32 +6547,45 @@ grn_ii_column_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
sizeof(grn_ii_updspec *),
GRN_HASH_TINY);
if (!old) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_create(ctx, NULL, old) on grn_ii_update failed!");
- rc = GRN_NO_MEMORY_AVAILABLE;
+ DEFINE_NAME(ii);
+ MERR("[ii][column][update][old][uvector] failed to create a hash table: "
+ "<%.*s>: ",
+ name_size, name);
} else {
if (old_->header.type == GRN_UVECTOR) {
- rc = grn_uvector2updspecs(ctx, ii, rid, section, old_, old,
- GRN_TOKEN_DEL, NULL);
+ grn_uvector2updspecs(ctx, ii, rid, section, old_, old,
+ GRN_TOKEN_DEL, NULL);
} else {
grn_obj uvector;
unsigned int weight = 0;
- GRN_VALUE_FIX_SIZE_INIT(&uvector, GRN_OBJ_VECTOR, old_->header.domain);
+ GRN_VALUE_FIX_SIZE_INIT(&uvector, GRN_OBJ_VECTOR,
+ old_->header.domain);
if (old_->header.impl_flags & GRN_OBJ_WITH_WEIGHT) {
uvector.header.impl_flags |= GRN_OBJ_WITH_WEIGHT;
}
- grn_uvector_add_element(ctx, &uvector, GRN_RECORD_VALUE(old_), weight);
- rc = grn_uvector2updspecs(ctx, ii, rid, section, &uvector, old,
- GRN_TOKEN_DEL, NULL);
+ grn_uvector_add_element(ctx, &uvector, GRN_RECORD_VALUE(old_),
+ weight);
+ grn_uvector2updspecs(ctx, ii, rid, section, &uvector, old,
+ GRN_TOKEN_DEL, NULL);
GRN_OBJ_FIN(ctx, &uvector);
}
}
if (old_ != oldvalue) { grn_obj_close(ctx, old_); }
- if (rc) { goto exit; }
+ if (ctx->rc != GRN_SUCCESS) { goto exit; }
break;
case GRN_TABLE_HASH_KEY :
break;
default :
- ERR(GRN_INVALID_ARGUMENT, "invalid object assigned as oldvalue");
+ {
+ DEFINE_NAME(ii);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[ii][column][update][old] invalid object: "
+ "<%.*s>: "
+ "<%s>(%#x)",
+ name_size, name,
+ grn_obj_type_to_string(type),
+ type);
+ }
goto exit;
}
}
@@ -5317,27 +6595,29 @@ grn_ii_column_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
grn_hash *o = (grn_hash *)old;
grn_hash *n = (grn_hash *)new;
GRN_HASH_EACH(ctx, o, id, &tp, NULL, &u, {
- if (n && (eid = grn_hash_get(ctx, n, tp, sizeof(grn_id), (void **) &un))) {
+ if (n && (eid = grn_hash_get(ctx, n, tp, sizeof(grn_id),
+ (void **) &un))) {
if (do_grn_ii_updspec_cmp && !grn_ii_updspec_cmp(*u, *un)) {
grn_ii_updspec_close(ctx, *un);
grn_hash_delete_by_id(ctx, n, eid, NULL);
}
} else {
- grn_rc r;
- r = grn_ii_delete_one(ctx, ii, *tp, *u, n);
- if (r) {
- rc = r;
- }
+ grn_ii_delete_one(ctx, ii, *tp, *u, n);
}
grn_ii_updspec_close(ctx, *u);
+ if (ctx->rc != GRN_SUCCESS) {
+ break;
+ }
});
}
if (new) {
grn_hash *n = (grn_hash *)new;
GRN_HASH_EACH(ctx, n, id, &tp, NULL, &u, {
- grn_rc r;
- if ((r = grn_ii_update_one(ctx, ii, *tp, *u, n))) { rc = r; }
+ grn_ii_update_one(ctx, ii, *tp, *u, n);
grn_ii_updspec_close(ctx, *u);
+ if (ctx->rc != GRN_SUCCESS) {
+ break;
+ }
});
} else {
if (!section) {
@@ -5359,13 +6639,14 @@ typedef struct {
int pos;
int size;
int ntoken;
- grn_ii_posting *p;
+ grn_posting *p;
} token_info;
#define EX_NONE 0
#define EX_PREFIX 1
#define EX_SUFFIX 2
#define EX_BOTH 3
+#define EX_FUZZY 4
inline static void
token_info_expand_both(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
@@ -5392,16 +6673,19 @@ token_info_expand_both(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
!(lexicon->header.flags & GRN_OBJ_KEY_WITH_SIS) ||
key2_size <= 2) { // todo: refine
if ((s = grn_ii_estimate_size(ctx, ii, *tp))) {
- cursor_heap_push(ctx, ti->cursors, ii, *tp, 0);
+ cursor_heap_push(ctx, ti->cursors, ii, *tp, 0, 0, GRN_ID_NIL);
ti->ntoken++;
ti->size += s;
}
} else {
- if ((g = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, GRN_HASH_TINY))) {
- grn_pat_suffix_search(ctx, (grn_pat *)lexicon, key2, key2_size, g);
+ if ((g = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_HASH_TINY))) {
+ grn_pat_suffix_search(ctx, (grn_pat *)lexicon, key2, key2_size,
+ g);
GRN_HASH_EACH(ctx, g, id, &tq, NULL, &offset2, {
if ((s = grn_ii_estimate_size(ctx, ii, *tq))) {
- cursor_heap_push(ctx, ti->cursors, ii, *tq, /* *offset2 */ 0);
+ cursor_heap_push(ctx, ti->cursors, ii, *tq,
+ /* *offset2 */ 0, 0, GRN_ID_NIL);
ti->ntoken++;
ti->size += s;
}
@@ -5428,7 +6712,8 @@ token_info_close(grn_ctx *ctx, token_info *ti)
inline static token_info *
token_info_open(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
- const char *key, unsigned int key_size, uint32_t offset, int mode)
+ const char *key, unsigned int key_size, uint32_t offset,
+ int mode, grn_fuzzy_search_optarg *args, grn_id min)
{
int s = 0;
grn_hash *h;
@@ -5449,7 +6734,7 @@ token_info_open(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
if ((tid = grn_table_get(ctx, lexicon, key, key_size)) &&
(s = grn_ii_estimate_size(ctx, ii, tid)) &&
(ti->cursors = cursor_heap_open(ctx, 1))) {
- cursor_heap_push(ctx, ti->cursors, ii, tid, 0);
+ cursor_heap_push(ctx, ti->cursors, ii, tid, 0, 0, min);
ti->ntoken++;
ti->size = s;
}
@@ -5462,7 +6747,7 @@ token_info_open(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
if ((ti->cursors = cursor_heap_open(ctx, GRN_HASH_SIZE(h)))) {
GRN_HASH_EACH(ctx, h, id, &tp, NULL, NULL, {
if ((s = grn_ii_estimate_size(ctx, ii, *tp))) {
- cursor_heap_push(ctx, ti->cursors, ii, *tp, 0);
+ cursor_heap_push(ctx, ti->cursors, ii, *tp, 0, 0, min);
ti->ntoken++;
ti->size += s;
}
@@ -5481,7 +6766,7 @@ token_info_open(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
uint32_t *offset2;
GRN_HASH_EACH(ctx, h, id, &tp, NULL, &offset2, {
if ((s = grn_ii_estimate_size(ctx, ii, *tp))) {
- cursor_heap_push(ctx, ti->cursors, ii, *tp, /* *offset2 */ 0);
+ cursor_heap_push(ctx, ti->cursors, ii, *tp, /* *offset2 */ 0, 0, min);
ti->ntoken++;
ti->size += s;
}
@@ -5491,6 +6776,27 @@ token_info_open(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
grn_hash_close(ctx, h);
}
break;
+ case EX_FUZZY :
+ if ((h = (grn_hash *)grn_table_create(ctx, NULL, 0, NULL,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ grn_ctx_at(ctx, GRN_DB_UINT32), NULL))) {
+ grn_table_fuzzy_search(ctx, lexicon, key, key_size,
+ args, (grn_obj *)h, GRN_OP_OR);
+ if (GRN_HASH_SIZE(h)) {
+ if ((ti->cursors = cursor_heap_open(ctx, GRN_HASH_SIZE(h)))) {
+ grn_rset_recinfo *ri;
+ GRN_HASH_EACH(ctx, h, id, &tp, NULL, (void **)&ri, {
+ if ((s = grn_ii_estimate_size(ctx, ii, *tp))) {
+ cursor_heap_push(ctx, ti->cursors, ii, *tp, 0, ri->score - 1, min);
+ ti->ntoken++;
+ ti->size += s;
+ }
+ });
+ }
+ }
+ grn_obj_close(ctx, (grn_obj *)h);
+ }
+ break;
}
if (cursor_heap_push2(ti->cursors)) {
token_info_close(ctx, ti);
@@ -5499,7 +6805,7 @@ token_info_open(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
{
grn_ii_cursor *ic;
if (ti->cursors && (ic = cursor_heap_min(ti->cursors))) {
- grn_ii_posting *p = ic->post;
+ grn_posting *p = ic->post;
ti->pos = p->pos - ti->offset;
ti->p = p;
} else {
@@ -5514,7 +6820,7 @@ static inline grn_rc
token_info_skip(grn_ctx *ctx, token_info *ti, uint32_t rid, uint32_t sid)
{
grn_ii_cursor *c;
- grn_ii_posting *p;
+ grn_posting *p;
for (;;) {
if (!(c = cursor_heap_min(ti->cursors))) { return GRN_END_OF_DATA; }
p = c->post;
@@ -5530,7 +6836,7 @@ static inline grn_rc
token_info_skip_pos(grn_ctx *ctx, token_info *ti, uint32_t rid, uint32_t sid, uint32_t pos)
{
grn_ii_cursor *c;
- grn_ii_posting *p;
+ grn_posting *p;
pos += ti->offset;
for (;;) {
if (!(c = cursor_heap_min(ti->cursors))) { return GRN_END_OF_DATA; }
@@ -5550,9 +6856,336 @@ token_compare(const void *a, const void *b)
return t1->size - t2->size;
}
+#define TOKEN_CANDIDATE_NODE_SIZE 32
+#define TOKEN_CANDIDATE_ADJACENT_MAX_SIZE 16
+#define TOKEN_CANDIDATE_QUEUE_SIZE 64
+#define TOKEN_CANDIDATE_SIZE 16
+
+typedef struct {
+ grn_id tid;
+ const unsigned char *token;
+ uint32_t token_size;
+ int32_t pos;
+ grn_token_cursor_status status;
+ int ef;
+ uint32_t estimated_size;
+ uint8_t adjacent[TOKEN_CANDIDATE_ADJACENT_MAX_SIZE]; /* Index of adjacent node from top */
+ uint8_t n_adjacent;
+} token_candidate_node;
+
+typedef struct {
+ uint32_t *candidates; /* Standing bits indicate index of token_candidate_node */
+ int top;
+ int rear;
+ int size;
+} token_candidate_queue;
+
+inline static void
+token_candidate_adjacent_set(grn_ctx *ctx, grn_token_cursor *token_cursor,
+ token_candidate_node *top, token_candidate_node *curr)
+{
+ grn_bool exists_adjacent = GRN_FALSE;
+ token_candidate_node *adj;
+ for (adj = top; adj < curr; adj++) {
+ if (token_cursor->curr <= adj->token + adj->token_size) {
+ if (adj->n_adjacent < TOKEN_CANDIDATE_ADJACENT_MAX_SIZE) {
+ adj->adjacent[adj->n_adjacent] = curr - top;
+ adj->n_adjacent++;
+ exists_adjacent = GRN_TRUE;
+ }
+ }
+ }
+ if (!exists_adjacent) {
+ adj = curr - 1;
+ if (adj->n_adjacent < TOKEN_CANDIDATE_ADJACENT_MAX_SIZE) {
+ adj->adjacent[adj->n_adjacent] = curr - top;
+ adj->n_adjacent++;
+ }
+ }
+}
+
+inline static grn_rc
+token_candidate_init(grn_ctx *ctx, grn_ii *ii, grn_token_cursor *token_cursor,
+ grn_id tid, int ef, token_candidate_node **nodes, int *n_nodes,
+ uint32_t *max_estimated_size)
+{
+ grn_rc rc;
+ token_candidate_node *top, *curr;
+ int size = TOKEN_CANDIDATE_NODE_SIZE;
+
+ *nodes = GRN_MALLOC(TOKEN_CANDIDATE_NODE_SIZE * sizeof(token_candidate_node));
+ if (!*nodes) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ top = *nodes;
+ curr = top;
+
+#define TOKEN_CANDIDATE_NODE_SET() { \
+ curr->tid = tid; \
+ curr->token = token_cursor->curr; \
+ curr->token_size = token_cursor->curr_size; \
+ curr->pos = token_cursor->pos; \
+ curr->status = token_cursor->status; \
+ curr->ef = ef; \
+ curr->estimated_size = grn_ii_estimate_size(ctx, ii, tid); \
+ curr->n_adjacent = 0; \
+}
+ TOKEN_CANDIDATE_NODE_SET();
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "[ii][overlap_token_skip] tid=%u pos=%d estimated_size=%u",
+ curr->tid, curr->pos, curr->estimated_size);
+ *max_estimated_size = curr->estimated_size;
+ curr++;
+
+ while (token_cursor->status == GRN_TOKEN_CURSOR_DOING) {
+ if (curr - top >= size) {
+ if (!(*nodes = GRN_REALLOC(*nodes,
+ (curr - top + TOKEN_CANDIDATE_NODE_SIZE) * sizeof(token_candidate_node)))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ top = *nodes;
+ curr = top + size;
+ size += TOKEN_CANDIDATE_NODE_SIZE;
+ }
+ tid = grn_token_cursor_next(ctx, token_cursor);
+ if (token_cursor->status != GRN_TOKEN_CURSOR_DONE_SKIP) {
+ if (token_cursor->force_prefix) { ef |= EX_PREFIX; }
+ TOKEN_CANDIDATE_NODE_SET();
+ token_candidate_adjacent_set(ctx, token_cursor, top, curr);
+ if (curr->estimated_size > *max_estimated_size) {
+ *max_estimated_size = curr->estimated_size;
+ }
+ curr++;
+ }
+ }
+ *n_nodes = curr - top;
+ rc = GRN_SUCCESS;
+ return rc;
+#undef TOKEN_CANDIDATE_NODE_SET
+}
+
+inline static grn_rc
+token_candidate_queue_init(grn_ctx *ctx, token_candidate_queue *q)
+{
+ q->top = 0;
+ q->rear = 0;
+ q->size = TOKEN_CANDIDATE_QUEUE_SIZE;
+
+ q->candidates = GRN_MALLOC(TOKEN_CANDIDATE_QUEUE_SIZE * sizeof(uint32_t));
+ if (!q->candidates) {
+ q->size = 0;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+token_candidate_enqueue(grn_ctx *ctx, token_candidate_queue *q, uint32_t candidate)
+{
+ if (q->rear >= q->size) {
+ if (!(q->candidates =
+ GRN_REALLOC(q->candidates,
+ (q->rear + TOKEN_CANDIDATE_QUEUE_SIZE) * sizeof(uint32_t)))) {
+ q->size = 0;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ q->size += TOKEN_CANDIDATE_QUEUE_SIZE;
+ }
+ *(q->candidates + q->rear) = candidate;
+ q->rear++;
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+token_candidate_dequeue(grn_ctx *ctx, token_candidate_queue *q, uint32_t *candidate)
+{
+ if (q->top == q->rear) {
+ return GRN_END_OF_DATA;
+ }
+ *candidate = *(q->candidates + q->top);
+ q->top++;
+ return GRN_SUCCESS;
+}
+
+inline static void
+token_candidate_queue_fin(grn_ctx *ctx, token_candidate_queue *q)
+{
+ GRN_FREE(q->candidates);
+}
+
+inline static token_candidate_node*
+token_candidate_last_node(grn_ctx *ctx, token_candidate_node *nodes, uint32_t candidate, int offset)
+{
+ int i;
+ GRN_BIT_SCAN_REV(candidate, i);
+ return nodes + i + offset;
+}
+
+inline static uint64_t
+token_candidate_score(grn_ctx *ctx, token_candidate_node *nodes, uint32_t candidate,
+ int offset, uint32_t max_estimated_size)
+{
+ int i, last;
+ uint64_t score = 0;
+ GRN_BIT_SCAN_REV(candidate, last);
+ for (i = 0; i <= last; i++) {
+ if (candidate & (1 << i)) {
+ token_candidate_node *node = nodes + i + offset;
+ if (node->estimated_size > 0) {
+ score += max_estimated_size / node->estimated_size;
+ }
+ }
+ }
+ return score;
+}
+
+inline static grn_rc
+token_candidate_select(grn_ctx *ctx, token_candidate_node *nodes,
+ int offset, int limit, int end,
+ uint32_t *selected_candidate, uint32_t max_estimated_size)
+{
+ grn_rc rc;
+ token_candidate_queue q;
+ uint32_t candidate;
+ uint64_t max_score = 0;
+ int i, min_n_nodes = 0;
+
+ if (offset + limit > end) {
+ limit = end - offset;
+ }
+ rc = token_candidate_queue_init(ctx, &q);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = token_candidate_enqueue(ctx, &q, 1);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ while (token_candidate_dequeue(ctx, &q, &candidate) != GRN_END_OF_DATA) {
+ token_candidate_node *candidate_last_node =
+ token_candidate_last_node(ctx, nodes, candidate, offset);
+ for (i = 0; i < candidate_last_node->n_adjacent; i++) {
+ int adjacent, n_nodes = 0;
+ uint32_t new_candidate;
+ adjacent = candidate_last_node->adjacent[i] - offset;
+ if (adjacent > limit) {
+ break;
+ }
+ new_candidate = candidate | (1 << adjacent);
+ GET_NUM_BITS(new_candidate, n_nodes);
+ if (min_n_nodes > 0 && n_nodes > min_n_nodes + 1) {
+ goto exit;
+ }
+ rc = token_candidate_enqueue(ctx, &q, new_candidate);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ if (adjacent == limit) {
+ if (min_n_nodes == 0) {
+ min_n_nodes = n_nodes;
+ }
+ if (n_nodes >= min_n_nodes && n_nodes <= min_n_nodes + 1) {
+ uint64_t score;
+ score = token_candidate_score(ctx, nodes, new_candidate, offset, max_estimated_size);
+ if (score > max_score) {
+ max_score = score;
+ *selected_candidate = new_candidate;
+ }
+ }
+ }
+ }
+ }
+ rc = GRN_SUCCESS;
+exit :
+ token_candidate_queue_fin(ctx, &q);
+ return rc;
+}
+
+inline static grn_rc
+token_candidate_build(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
+ token_info **tis, uint32_t *n,
+ token_candidate_node *nodes, uint32_t selected_candidate,
+ int offset, grn_id min)
+{
+ grn_rc rc = GRN_END_OF_DATA;
+ token_info *ti;
+ const char *key;
+ uint32_t size;
+ int i, last = 0;
+ GRN_BIT_SCAN_REV(selected_candidate, last);
+ for (i = 1; i <= last; i++) {
+ if (selected_candidate & (1 << i)) {
+ token_candidate_node *node = nodes + i + offset;
+ switch (node->status) {
+ case GRN_TOKEN_CURSOR_DOING :
+ key = _grn_table_key(ctx, lexicon, node->tid, &size);
+ ti = token_info_open(ctx, lexicon, ii, key, size, node->pos,
+ EX_NONE, NULL, min);
+ break;
+ case GRN_TOKEN_CURSOR_DONE :
+ if (node->tid) {
+ key = _grn_table_key(ctx, lexicon, node->tid, &size);
+ ti = token_info_open(ctx, lexicon, ii, key, size, node->pos,
+ node->ef & EX_PREFIX, NULL, min);
+ break;
+ } /* else fallthru */
+ default :
+ ti = token_info_open(ctx, lexicon, ii, (char *)node->token,
+ node->token_size, node->pos,
+ node->ef & EX_PREFIX, NULL, min);
+ break;
+ }
+ if (!ti) {
+ goto exit;
+ }
+ tis[(*n)++] = ti;
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "[ii][overlap_token_skip] tid=%u pos=%d estimated_size=%u",
+ node->tid, node->pos, node->estimated_size);
+ }
+ }
+ rc = GRN_SUCCESS;
+exit :
+ return rc;
+}
+
+inline static grn_rc
+token_info_build_skipping_overlap(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
+ token_info **tis, uint32_t *n,
+ grn_token_cursor *token_cursor,
+ grn_id tid, int ef, grn_id min)
+{
+ grn_rc rc;
+ token_candidate_node *nodes = NULL;
+ int n_nodes = 0, offset = 0, limit = TOKEN_CANDIDATE_SIZE - 1;
+ uint32_t max_estimated_size;
+
+ rc = token_candidate_init(ctx, ii, token_cursor, tid, ef, &nodes, &n_nodes, &max_estimated_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ while (offset < n_nodes - 1) {
+ uint32_t selected_candidate = 0;
+ rc = token_candidate_select(ctx, nodes, offset, limit, n_nodes - 1,
+ &selected_candidate, max_estimated_size);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ rc = token_candidate_build(ctx, lexicon, ii, tis, n, nodes, selected_candidate, offset, min);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ offset += limit;
+ }
+ rc = GRN_SUCCESS;
+exit :
+ if (nodes) {
+ GRN_FREE(nodes);
+ }
+ return rc;
+}
+
inline static grn_rc
token_info_build(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii, const char *string, unsigned int string_len,
- token_info **tis, uint32_t *n, grn_bool *only_skip_token,
+ token_info **tis, uint32_t *n, grn_bool *only_skip_token, grn_id min,
grn_operator mode)
{
token_info *ti;
@@ -5567,7 +7200,8 @@ token_info_build(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii, const char *string,
*only_skip_token = GRN_FALSE;
if (!token_cursor) { return GRN_NO_MEMORY_AVAILABLE; }
if (mode == GRN_OP_UNSPLIT) {
- if ((ti = token_info_open(ctx, lexicon, ii, (char *)token_cursor->orig, token_cursor->orig_blen, 0, EX_BOTH))) {
+ if ((ti = token_info_open(ctx, lexicon, ii, (char *)token_cursor->orig,
+ token_cursor->orig_blen, 0, EX_BOTH, NULL, min))) {
tis[(*n)++] = ti;
rc = GRN_SUCCESS;
}
@@ -5593,21 +7227,22 @@ token_info_build(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii, const char *string,
switch (token_cursor->status) {
case GRN_TOKEN_CURSOR_DOING :
key = _grn_table_key(ctx, lexicon, tid, &size);
- ti = token_info_open(ctx, lexicon, ii, key, size, token_cursor->pos, ef & EX_SUFFIX);
+ ti = token_info_open(ctx, lexicon, ii, key, size, token_cursor->pos,
+ ef & EX_SUFFIX, NULL, min);
break;
case GRN_TOKEN_CURSOR_DONE :
ti = token_info_open(ctx, lexicon, ii, (const char *)token_cursor->curr,
- token_cursor->curr_size, 0, ef);
+ token_cursor->curr_size, 0, ef, NULL, min);
/*
key = _grn_table_key(ctx, lexicon, tid, &size);
- ti = token_info_open(ctx, lexicon, ii, token_cursor->curr, token_cursor->curr_size, token_cursor->pos, ef);
+ ti = token_info_open(ctx, lexicon, ii, token_cursor->curr, token_cursor->curr_size, token_cursor->pos, ef, NULL, GRN_ID_NIL);
ti = token_info_open(ctx, lexicon, ii, (char *)token_cursor->orig,
- token_cursor->orig_blen, token_cursor->pos, ef);
+ token_cursor->orig_blen, token_cursor->pos, ef, NULL, GRN_ID_NIL);
*/
break;
case GRN_TOKEN_CURSOR_NOT_FOUND :
ti = token_info_open(ctx, lexicon, ii, (char *)token_cursor->orig,
- token_cursor->orig_blen, 0, ef);
+ token_cursor->orig_blen, 0, ef, NULL, min);
break;
case GRN_TOKEN_CURSOR_DONE_SKIP :
*only_skip_token = GRN_TRUE;
@@ -5617,6 +7252,12 @@ token_info_build(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii, const char *string,
}
if (!ti) { goto exit ; }
tis[(*n)++] = ti;
+
+ if (grn_ii_overlap_token_skip_enable) {
+ rc = token_info_build_skipping_overlap(ctx, lexicon, ii, tis, n, token_cursor, tid, ef, min);
+ goto exit;
+ }
+
while (token_cursor->status == GRN_TOKEN_CURSOR_DOING) {
tid = grn_token_cursor_next(ctx, token_cursor);
if (token_cursor->force_prefix) { ef |= EX_PREFIX; }
@@ -5625,17 +7266,20 @@ token_info_build(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii, const char *string,
continue;
case GRN_TOKEN_CURSOR_DOING :
key = _grn_table_key(ctx, lexicon, tid, &size);
- ti = token_info_open(ctx, lexicon, ii, key, size, token_cursor->pos, EX_NONE);
+ ti = token_info_open(ctx, lexicon, ii, key, size, token_cursor->pos,
+ EX_NONE, NULL, min);
break;
case GRN_TOKEN_CURSOR_DONE :
if (tid) {
key = _grn_table_key(ctx, lexicon, tid, &size);
- ti = token_info_open(ctx, lexicon, ii, key, size, token_cursor->pos, ef & EX_PREFIX);
+ ti = token_info_open(ctx, lexicon, ii, key, size, token_cursor->pos,
+ ef & EX_PREFIX, NULL, min);
break;
} /* else fallthru */
default :
ti = token_info_open(ctx, lexicon, ii, (char *)token_cursor->curr,
- token_cursor->curr_size, token_cursor->pos, ef & EX_PREFIX);
+ token_cursor->curr_size, token_cursor->pos,
+ ef & EX_PREFIX, NULL, min);
break;
}
if (!ti) {
@@ -5650,6 +7294,65 @@ exit :
return rc;
}
+inline static grn_rc
+token_info_build_fuzzy(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii,
+ const char *string, unsigned int string_len,
+ token_info **tis, uint32_t *n, grn_bool *only_skip_token,
+ grn_id min, grn_operator mode, grn_fuzzy_search_optarg *args)
+{
+ token_info *ti;
+ grn_rc rc = GRN_END_OF_DATA;
+ unsigned int token_flags = GRN_TOKEN_CURSOR_ENABLE_TOKENIZED_DELIMITER;
+ grn_token_cursor *token_cursor = grn_token_cursor_open(ctx, lexicon,
+ string, string_len,
+ GRN_TOKENIZE_ONLY,
+ token_flags);
+ *only_skip_token = GRN_FALSE;
+ if (!token_cursor) { return GRN_NO_MEMORY_AVAILABLE; }
+ grn_token_cursor_next(ctx, token_cursor);
+ switch (token_cursor->status) {
+ case GRN_TOKEN_CURSOR_DONE_SKIP :
+ *only_skip_token = GRN_TRUE;
+ goto exit;
+ case GRN_TOKEN_CURSOR_DOING :
+ case GRN_TOKEN_CURSOR_DONE :
+ ti = token_info_open(ctx, lexicon, ii, (const char *)token_cursor->curr,
+ token_cursor->curr_size, token_cursor->pos, EX_FUZZY,
+ args, min);
+ break;
+ default :
+ ti = NULL;
+ break;
+ }
+ if (!ti) {
+ goto exit ;
+ }
+ tis[(*n)++] = ti;
+ while (token_cursor->status == GRN_TOKEN_CURSOR_DOING) {
+ grn_token_cursor_next(ctx, token_cursor);
+ switch (token_cursor->status) {
+ case GRN_TOKEN_CURSOR_DONE_SKIP :
+ continue;
+ case GRN_TOKEN_CURSOR_DOING :
+ case GRN_TOKEN_CURSOR_DONE :
+ ti = token_info_open(ctx, lexicon, ii, (const char *)token_cursor->curr,
+ token_cursor->curr_size, token_cursor->pos, EX_FUZZY,
+ args, min);
+ break;
+ default :
+ break;
+ }
+ if (!ti) {
+ goto exit;
+ }
+ tis[(*n)++] = ti;
+ }
+ rc = GRN_SUCCESS;
+exit :
+ grn_token_cursor_close(ctx, token_cursor);
+ return rc;
+}
+
static void
token_info_clear_offset(token_info **tis, uint32_t n)
{
@@ -5701,7 +7404,7 @@ res_add(grn_ctx *ctx, grn_hash *s, grn_rset_posinfo *pi, double score,
}
grn_rc
-grn_ii_posting_add(grn_ctx *ctx, grn_ii_posting *pos, grn_hash *s, grn_operator op)
+grn_ii_posting_add(grn_ctx *ctx, grn_posting *pos, grn_hash *s, grn_operator op)
{
res_add(ctx, s, (grn_rset_posinfo *)(pos), (1 + pos->weight), op);
return ctx->rc;
@@ -5838,7 +7541,8 @@ get_weight(grn_ctx *ctx, grn_hash *s, grn_id rid, int sid,
}
*/
/* todo : cast */
- return optarg->func(ctx, (void *)s, (void *)(intptr_t)rid, sid, optarg->func_arg);
+ return optarg->func(ctx, (void *)s, (void *)(intptr_t)rid, sid,
+ optarg->func_arg);
case grn_wv_constant :
return optarg->vector_size;
default :
@@ -5858,7 +7562,9 @@ grn_ii_similar_search(grn_ctx *ctx, grn_ii *ii,
grn_token_cursor *token_cursor;
unsigned int token_flags = GRN_TOKEN_CURSOR_ENABLE_TOKENIZED_DELIMITER;
grn_obj *lexicon = ii->lexicon;
- if (!lexicon || !ii || !string || !string_len || !s || !optarg) { return GRN_INVALID_ARGUMENT; }
+ if (!lexicon || !ii || !string || !string_len || !s || !optarg) {
+ return GRN_INVALID_ARGUMENT;
+ }
if (!(h = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(int), 0))) {
return GRN_NO_MEMORY_AVAILABLE;
}
@@ -5871,24 +7577,30 @@ grn_ii_similar_search(grn_ctx *ctx, grn_ii *ii,
while (token_cursor->status != GRN_TOKEN_CURSOR_DONE &&
token_cursor->status != GRN_TOKEN_CURSOR_DONE_SKIP) {
if ((tid = grn_token_cursor_next(ctx, token_cursor))) {
- if (grn_hash_add(ctx, h, &tid, sizeof(grn_id), (void **)&w1, NULL)) { (*w1)++; }
+ if (grn_hash_add(ctx, h, &tid, sizeof(grn_id), (void **)&w1, NULL)) {
+ (*w1)++;
+ }
}
if (tid && token_cursor->curr_size) {
- if (optarg->max_interval == GRN_OP_UNSPLIT) {
- grn_table_search(ctx, lexicon, token_cursor->curr, token_cursor->curr_size,
+ if (optarg->mode == GRN_OP_UNSPLIT) {
+ grn_table_search(ctx, lexicon, token_cursor->curr,
+ token_cursor->curr_size,
GRN_OP_PREFIX, (grn_obj *)h, GRN_OP_OR);
}
- if (optarg->max_interval == GRN_OP_PARTIAL) {
- grn_table_search(ctx, lexicon, token_cursor->curr, token_cursor->curr_size,
+ if (optarg->mode == GRN_OP_PARTIAL) {
+ grn_table_search(ctx, lexicon, token_cursor->curr,
+ token_cursor->curr_size,
GRN_OP_SUFFIX, (grn_obj *)h, GRN_OP_OR);
}
}
}
grn_token_cursor_close(ctx, token_cursor);
{
- grn_hash_cursor *c = grn_hash_cursor_open(ctx, h, NULL, 0, NULL, 0, 0, -1, 0);
+ grn_hash_cursor *c = grn_hash_cursor_open(ctx, h, NULL, 0, NULL, 0,
+ 0, -1, 0);
if (!c) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_cursor_open on grn_ii_similar_search failed !");
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_hash_cursor_open on grn_ii_similar_search failed !");
grn_hash_close(ctx, h);
return GRN_NO_MEMORY_AVAILABLE;
}
@@ -5912,7 +7624,7 @@ grn_ii_similar_search(grn_ctx *ctx, grn_ii *ii,
grn_id j, id;
int w2, rep;
grn_ii_cursor *c;
- grn_ii_posting *pos;
+ grn_posting *pos;
grn_wv_mode wvm = grn_wv_none;
grn_table_sort_optarg arg = {
GRN_TABLE_SORT_DESC|GRN_TABLE_SORT_BY_VALUE|GRN_TABLE_SORT_AS_NUMBER,
@@ -5922,7 +7634,8 @@ grn_ii_similar_search(grn_ctx *ctx, grn_ii *ii,
};
grn_array *sorted = grn_array_create(ctx, NULL, sizeof(grn_id), 0);
if (!sorted) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_sort on grn_ii_similar_search failed !");
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_hash_sort on grn_ii_similar_search failed !");
grn_hash_close(ctx, h);
return GRN_NO_MEMORY_AVAILABLE;
}
@@ -5951,7 +7664,8 @@ grn_ii_similar_search(grn_ctx *ctx, grn_ii *ii,
pos = c->post;
if ((w2 = get_weight(ctx, s, pos->rid, pos->sid, wvm, optarg)) > 0) {
while (grn_ii_cursor_next_pos(ctx, c)) {
- res_add(ctx, s, (grn_rset_posinfo *) pos, *w1 * w2 * (1 + pos->weight), op);
+ res_add(ctx, s, (grn_rset_posinfo *) pos,
+ *w1 * w2 * (1 + pos->weight), op);
}
}
}
@@ -5959,7 +7673,8 @@ grn_ii_similar_search(grn_ctx *ctx, grn_ii *ii,
while (grn_ii_cursor_next(ctx, c)) {
pos = c->post;
if ((w2 = get_weight(ctx, s, pos->rid, pos->sid, wvm, optarg)) > 0) {
- res_add(ctx, s, (grn_rset_posinfo *) pos, *w1 * w2 * (pos->tf + pos->weight), op);
+ res_add(ctx, s, (grn_rset_posinfo *) pos,
+ *w1 * w2 * (pos->tf + pos->weight), op);
}
}
}
@@ -5988,7 +7703,7 @@ grn_ii_term_extract(grn_ctx *ctx, grn_ii *ii, const char *string,
const char *normalized;
unsigned int normalized_length_in_bytes;
grn_ii_cursor *c;
- grn_ii_posting *pos;
+ grn_posting *pos;
int skip, rep, policy;
grn_rc rc = GRN_SUCCESS;
grn_wv_mode wvm = grn_wv_none;
@@ -6059,27 +7774,365 @@ grn_ii_term_extract(grn_ctx *ctx, grn_ii *ii, const char *string,
return rc;
}
+typedef struct {
+ grn_id rid;
+ uint32_t sid;
+ uint32_t start_pos;
+ uint32_t end_pos;
+ uint32_t tf;
+ uint32_t weight;
+} grn_ii_select_cursor_posting;
+
+typedef struct {
+ btr *bt;
+ grn_ii *ii;
+ token_info **tis;
+ uint32_t n_tis;
+ int max_interval;
+ grn_operator mode;
+ grn_ii_select_cursor_posting posting;
+ const char *string;
+ unsigned int string_len;
+ grn_bool done;
+ grn_ii_select_cursor_posting unshifted_posting;
+ grn_bool have_unshifted_posting;
+} grn_ii_select_cursor;
+
static grn_rc
-grn_ii_select_regexp(grn_ctx *ctx, grn_ii *ii,
- const char *string, unsigned int string_len,
- grn_hash *s, grn_operator op, grn_select_optarg *optarg)
+grn_ii_select_cursor_close(grn_ctx *ctx,
+ grn_ii_select_cursor *cursor)
+{
+ token_info **tip;
+
+ if (!cursor) {
+ return GRN_SUCCESS;
+ }
+
+ for (tip = cursor->tis; tip < cursor->tis + cursor->n_tis; tip++) {
+ if (*tip) {
+ token_info_close(ctx, *tip);
+ }
+ }
+ if (cursor->tis) {
+ GRN_FREE(cursor->tis);
+ }
+ bt_close(ctx, cursor->bt);
+ GRN_FREE(cursor);
+
+ return GRN_SUCCESS;
+}
+
+static grn_ii_select_cursor *
+grn_ii_select_cursor_open(grn_ctx *ctx,
+ grn_ii *ii,
+ const char *string,
+ unsigned int string_len,
+ grn_select_optarg *optarg)
+{
+ grn_operator mode = GRN_OP_EXACT;
+ grn_ii_select_cursor *cursor;
+
+ if (string_len == 0) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[ii][select][cursor][open] empty string");
+ return NULL;
+ }
+
+ if (optarg) {
+ mode = optarg->mode;
+ }
+ switch (mode) {
+ case GRN_OP_EXACT :
+ case GRN_OP_FUZZY :
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT,
+ "[ii][select][cursor][open] "
+ "EXACT, FUZZY, NEAR and NEAR2 are only supported mode: %s",
+ grn_operator_to_string(mode));
+ break;
+ }
+
+ cursor = GRN_CALLOC(sizeof(grn_ii_select_cursor));
+ if (!cursor) {
+ ERR(ctx->rc,
+ "[ii][select][cursor][open] failed to allocate cursor: %s",
+ ctx->errbuf);
+ return NULL;
+ }
+
+ cursor->ii = ii;
+ cursor->mode = mode;
+
+ if (!(cursor->tis = GRN_MALLOC(sizeof(token_info *) * string_len * 2))) {
+ ERR(ctx->rc,
+ "[ii][select][cursor][open] failed to allocate token info container: %s",
+ ctx->errbuf);
+ GRN_FREE(cursor);
+ return NULL;
+ }
+ cursor->n_tis = 0;
+ if (cursor->mode == GRN_OP_FUZZY) {
+ grn_bool only_skip_token = GRN_FALSE;
+ grn_id previous_min = GRN_ID_NIL;
+ if (token_info_build_fuzzy(ctx, ii->lexicon, ii, string, string_len,
+ cursor->tis, &(cursor->n_tis),
+ &only_skip_token, previous_min,
+ cursor->mode, &(optarg->fuzzy)) != GRN_SUCCESS) {
+ grn_ii_select_cursor_close(ctx, cursor);
+ return NULL;
+ }
+ } else {
+ grn_bool only_skip_token = GRN_FALSE;
+ grn_id previous_min = GRN_ID_NIL;
+ if (token_info_build(ctx, ii->lexicon, ii, string, string_len,
+ cursor->tis, &(cursor->n_tis),
+ &only_skip_token, previous_min,
+ cursor->mode) != GRN_SUCCESS) {
+ grn_ii_select_cursor_close(ctx, cursor);
+ return NULL;
+ }
+ }
+ if (cursor->n_tis == 0) {
+ grn_ii_select_cursor_close(ctx, cursor);
+ return NULL;
+ }
+
+ switch (cursor->mode) {
+ case GRN_OP_NEAR2 :
+ token_info_clear_offset(cursor->tis, cursor->n_tis);
+ cursor->mode = GRN_OP_NEAR;
+ /* fallthru */
+ case GRN_OP_NEAR :
+ if (!(cursor->bt = bt_open(ctx, cursor->n_tis))) {
+ ERR(ctx->rc,
+ "[ii][select][cursor][open] failed to allocate btree: %s",
+ ctx->errbuf);
+ grn_ii_select_cursor_close(ctx, cursor);
+ return NULL;
+ }
+ cursor->max_interval = optarg->max_interval;
+ break;
+ default :
+ break;
+ }
+ qsort(cursor->tis, cursor->n_tis, sizeof(token_info *), token_compare);
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[ii][select][cursor][open] n=%d <%.*s>",
+ cursor->n_tis,
+ string_len, string);
+
+ cursor->string = string;
+ cursor->string_len = string_len;
+
+ cursor->done = GRN_FALSE;
+
+ cursor->have_unshifted_posting = GRN_FALSE;
+
+ return cursor;
+}
+
+static grn_ii_select_cursor_posting *
+grn_ii_select_cursor_next(grn_ctx *ctx,
+ grn_ii_select_cursor *cursor)
+{
+ btr *bt = cursor->bt;
+ token_info **tis = cursor->tis;
+ token_info **tie = tis + cursor->n_tis;
+ uint32_t n_tis = cursor->n_tis;
+ int max_interval = cursor->max_interval;
+ grn_operator mode = cursor->mode;
+
+ if (cursor->have_unshifted_posting) {
+ cursor->have_unshifted_posting = GRN_FALSE;
+ return &(cursor->unshifted_posting);
+ }
+
+ if (cursor->done) {
+ return NULL;
+ }
+
+ for (;;) {
+ grn_id rid;
+ grn_id sid;
+ grn_id next_rid;
+ grn_id next_sid;
+ token_info **tip;
+
+ rid = (*tis)->p->rid;
+ sid = (*tis)->p->sid;
+ for (tip = tis + 1, next_rid = rid, next_sid = sid + 1;
+ tip < tie;
+ tip++) {
+ token_info *ti = *tip;
+ if (token_info_skip(ctx, ti, rid, sid)) { return NULL; }
+ if (ti->p->rid != rid || ti->p->sid != sid) {
+ next_rid = ti->p->rid;
+ next_sid = ti->p->sid;
+ break;
+ }
+ }
+
+ if (tip == tie) {
+ int start_pos = 0;
+ int pos = 0;
+ int end_pos = 0;
+ int score = 0;
+ int tf = 0;
+ int tscore = 0;
+
+#define SKIP_OR_BREAK(pos) {\
+ if (token_info_skip_pos(ctx, ti, rid, sid, pos)) { break; } \
+ if (ti->p->rid != rid || ti->p->sid != sid) { \
+ next_rid = ti->p->rid; \
+ next_sid = ti->p->sid; \
+ break; \
+ } \
+}
+
+#define RETURN_POSTING() do { \
+ cursor->posting.rid = rid; \
+ cursor->posting.sid = sid; \
+ cursor->posting.start_pos = start_pos; \
+ cursor->posting.end_pos = end_pos; \
+ cursor->posting.tf = tf; \
+ cursor->posting.weight = tscore; \
+ if (token_info_skip_pos(ctx, *tis, rid, sid, pos) != GRN_SUCCESS) { \
+ if (token_info_skip(ctx, *tis, next_rid, next_sid) != GRN_SUCCESS) { \
+ cursor->done = GRN_TRUE; \
+ } \
+ } \
+ return &(cursor->posting); \
+} while (GRN_FALSE)
+
+ if (n_tis == 1) {
+ start_pos = pos = end_pos = (*tis)->p->pos;
+ pos++;
+ tf = (*tis)->p->tf;
+ tscore = (*tis)->p->weight + (*tis)->cursors->bins[0]->weight;
+ RETURN_POSTING();
+ } else if (mode == GRN_OP_NEAR) {
+ bt_zap(bt);
+ for (tip = tis; tip < tie; tip++) {
+ token_info *ti = *tip;
+ SKIP_OR_BREAK(pos);
+ bt_push(bt, ti);
+ }
+ if (tip == tie) {
+ for (;;) {
+ token_info *ti;
+ int min;
+ int max;
+
+ ti = bt->min;
+ min = ti->pos;
+ max = bt->max->pos;
+ if (min > max) {
+ char ii_name[GRN_TABLE_MAX_KEY_SIZE];
+ int ii_name_size;
+ ii_name_size = grn_obj_name(ctx,
+ (grn_obj *)(cursor->ii),
+ ii_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_FILE_CORRUPT,
+ "[ii][select][cursor][near] "
+ "max position must be larger than min position: "
+ "min:<%d> max:<%d> ii:<%.*s> string:<%.*s>",
+ min, max,
+ ii_name_size, ii_name,
+ cursor->string_len,
+ cursor->string);
+ return NULL;
+ }
+ if ((max_interval < 0) || (max - min <= max_interval)) {
+ /* TODO: Set start_pos, pos, end_pos, tf and tscore */
+ RETURN_POSTING();
+ if (ti->pos == max + 1) {
+ break;
+ }
+ SKIP_OR_BREAK(max + 1);
+ } else {
+ if (ti->pos == max - max_interval) {
+ break;
+ }
+ SKIP_OR_BREAK(max - max_interval);
+ }
+ bt_pop(bt);
+ }
+ }
+ } else {
+ int count = 0;
+ for (tip = tis; ; tip++) {
+ token_info *ti;
+
+ if (tip == tie) { tip = tis; }
+ ti = *tip;
+ SKIP_OR_BREAK(pos);
+ if (ti->pos == pos) {
+ score += ti->p->weight + ti->cursors->bins[0]->weight;
+ count++;
+ if (ti->p->pos > end_pos) {
+ end_pos = ti->p->pos;
+ }
+ } else {
+ score = ti->p->weight + ti->cursors->bins[0]->weight;
+ count = 1;
+ start_pos = pos = ti->pos;
+ end_pos = ti->p->pos;
+ }
+ if (count == n_tis) {
+ pos++;
+ if (ti->p->pos > end_pos) {
+ end_pos = ti->p->pos;
+ }
+ tf = 1;
+ tscore += score;
+ RETURN_POSTING();
+ }
+ }
+ }
+#undef SKIP_OR_BREAK
+ }
+ if (token_info_skip(ctx, *tis, next_rid, next_sid)) {
+ return NULL;
+ }
+ }
+}
+
+static void
+grn_ii_select_cursor_unshift(grn_ctx *ctx,
+ grn_ii_select_cursor *cursor,
+ grn_ii_select_cursor_posting *posting)
+{
+ cursor->unshifted_posting = *posting;
+ cursor->have_unshifted_posting = GRN_TRUE;
+}
+
+static grn_rc
+grn_ii_parse_regexp_query(grn_ctx *ctx,
+ const char *log_tag,
+ const char *string, unsigned int string_len,
+ grn_obj *parsed_strings)
{
- grn_rc rc;
- grn_obj parsed_string;
grn_bool escaping = GRN_FALSE;
int nth_char = 0;
const char *current = string;
const char *string_end = string + string_len;
+ grn_obj buffer;
- GRN_TEXT_INIT(&parsed_string, 0);
+ GRN_TEXT_INIT(&buffer, 0);
while (current < string_end) {
const char *target;
int char_len;
char_len = grn_charlen(ctx, current, string_end);
if (char_len == 0) {
+ GRN_OBJ_FIN(ctx, &buffer);
ERR(GRN_INVALID_ARGUMENT,
- "[ii][select][regexp] invalid encoding character: <%.*s|%#x|>",
+ "%s invalid encoding character: <%.*s|%#x|>",
+ log_tag,
(int)(current - string), string,
*current);
return ctx->rc;
@@ -6108,24 +8161,167 @@ grn_ii_select_regexp(grn_ctx *ctx, grn_ii *ii,
}
}
} else {
- if (char_len == 1 && *target == '\\') {
- escaping = GRN_TRUE;
- continue;
+ if (char_len == 1) {
+ if (*target == '\\') {
+ escaping = GRN_TRUE;
+ continue;
+ } else if (*target == '.' &&
+ grn_charlen(ctx, current, string_end) == 1 &&
+ *current == '*') {
+ if (GRN_TEXT_LEN(&buffer) > 0) {
+ grn_vector_add_element(ctx,
+ parsed_strings,
+ GRN_TEXT_VALUE(&buffer),
+ GRN_TEXT_LEN(&buffer),
+ 0,
+ GRN_DB_TEXT);
+ GRN_BULK_REWIND(&buffer);
+ }
+ current++;
+ nth_char++;
+ continue;
+ }
}
}
- GRN_TEXT_PUT(ctx, &parsed_string, target, char_len);
+ GRN_TEXT_PUT(ctx, &buffer, target, char_len);
nth_char++;
}
+ if (GRN_TEXT_LEN(&buffer) > 0) {
+ grn_vector_add_element(ctx,
+ parsed_strings,
+ GRN_TEXT_VALUE(&buffer),
+ GRN_TEXT_LEN(&buffer),
+ 0,
+ GRN_DB_TEXT);
+ }
+ GRN_OBJ_FIN(ctx, &buffer);
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_ii_select_regexp(grn_ctx *ctx, grn_ii *ii,
+ const char *string, unsigned int string_len,
+ grn_hash *s, grn_operator op, grn_select_optarg *optarg)
+{
+ grn_rc rc;
+ grn_obj parsed_strings;
+ unsigned int n_parsed_strings;
+
+ GRN_TEXT_INIT(&parsed_strings, GRN_OBJ_VECTOR);
+ rc = grn_ii_parse_regexp_query(ctx, "[ii][select][regexp]",
+ string, string_len, &parsed_strings);
+ if (rc != GRN_SUCCESS) {
+ GRN_OBJ_FIN(ctx, &parsed_strings);
+ return rc;
+ }
if (optarg) {
- optarg->mode = GRN_OP_MATCH;
+ optarg->mode = GRN_OP_EXACT;
+ }
+
+ n_parsed_strings = grn_vector_size(ctx, &parsed_strings);
+ if (n_parsed_strings == 1) {
+ const char *parsed_string;
+ unsigned int parsed_string_len;
+ parsed_string_len = grn_vector_get_element(ctx,
+ &parsed_strings,
+ 0,
+ &parsed_string,
+ NULL,
+ NULL);
+ rc = grn_ii_select(ctx, ii,
+ parsed_string,
+ parsed_string_len,
+ s, op, optarg);
+ } else {
+ int i;
+ grn_ii_select_cursor **cursors;
+ grn_bool have_error = GRN_FALSE;
+
+ cursors = GRN_CALLOC(sizeof(grn_ii_select_cursor *) * n_parsed_strings);
+ for (i = 0; i < n_parsed_strings; i++) {
+ const char *parsed_string;
+ unsigned int parsed_string_len;
+ parsed_string_len = grn_vector_get_element(ctx,
+ &parsed_strings,
+ i,
+ &parsed_string,
+ NULL,
+ NULL);
+ cursors[i] = grn_ii_select_cursor_open(ctx,
+ ii,
+ parsed_string,
+ parsed_string_len,
+ optarg);
+ if (!cursors[i]) {
+ have_error = GRN_TRUE;
+ break;
+ }
+ }
+
+ while (!have_error) {
+ grn_ii_select_cursor_posting *posting;
+ uint32_t pos;
+
+ posting = grn_ii_select_cursor_next(ctx, cursors[0]);
+ if (!posting) {
+ break;
+ }
+
+ pos = posting->end_pos;
+ for (i = 1; i < n_parsed_strings; i++) {
+ grn_ii_select_cursor_posting *posting_i;
+
+ for (;;) {
+ posting_i = grn_ii_select_cursor_next(ctx, cursors[i]);
+ if (!posting_i) {
+ break;
+ }
+
+ if (posting_i->rid == posting->rid &&
+ posting_i->sid == posting->sid &&
+ posting_i->start_pos > pos) {
+ grn_ii_select_cursor_unshift(ctx, cursors[i], posting_i);
+ break;
+ }
+ if (posting_i->rid > posting->rid) {
+ grn_ii_select_cursor_unshift(ctx, cursors[i], posting_i);
+ break;
+ }
+ }
+
+ if (!posting_i) {
+ break;
+ }
+
+ if (posting_i->rid != posting->rid || posting_i->sid != posting->sid) {
+ break;
+ }
+
+ pos = posting_i->end_pos;
+ }
+
+ if (i == n_parsed_strings) {
+ grn_rset_posinfo pi = {posting->rid, posting->sid, pos};
+ double record_score = 1.0;
+ res_add(ctx, s, &pi, record_score, op);
+ }
+ }
+
+ for (i = 0; i < n_parsed_strings; i++) {
+ if (cursors[i]) {
+ grn_ii_select_cursor_close(ctx, cursors[i]);
+ }
+ }
+ GRN_FREE(cursors);
}
+ GRN_OBJ_FIN(ctx, &parsed_strings);
- rc = grn_ii_select(ctx, ii,
- GRN_TEXT_VALUE(&parsed_string),
- GRN_TEXT_LEN(&parsed_string),
- s, op, optarg);
+ if (optarg) {
+ optarg->mode = GRN_OP_REGEXP;
+ }
return rc;
}
@@ -6198,16 +8394,31 @@ grn_ii_select_sequential_search_body(grn_ctx *ctx,
for (i = 0; i < n_sources; i++) {
grn_id source_id = source_ids[i];
grn_obj *source;
- char column_name[GRN_TABLE_MAX_KEY_SIZE];
- int column_name_size;
grn_obj *accessor;
source = grn_ctx_at(ctx, source_id);
- column_name_size = grn_column_name(ctx, source,
- column_name,
- GRN_TABLE_MAX_KEY_SIZE);
- accessor = grn_obj_column(ctx, (grn_obj *)result, column_name,
- column_name_size);
+ switch (source->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ accessor = grn_obj_column(ctx,
+ (grn_obj *)result,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ break;
+ default :
+ {
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int column_name_size;
+ column_name_size = grn_column_name(ctx, source,
+ column_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ accessor = grn_obj_column(ctx, (grn_obj *)result, column_name,
+ column_name_size);
+ }
+ break;
+ }
+
{
grn_hash_cursor *cursor;
grn_id id;
@@ -6235,9 +8446,13 @@ grn_ii_select_sequential_search_body(grn_ctx *ctx,
NULL,
0);
if (position != ONIG_MISMATCH) {
+ grn_id *record_id;
grn_rset_posinfo info;
double score;
- info.rid = id;
+
+ grn_hash_cursor_get_key(ctx, cursor, (void **)&record_id);
+
+ info.rid = *record_id;
info.sid = i + 1;
info.pos = 0;
score = get_weight(ctx, result, info.rid, info.sid, wvm, optarg);
@@ -6330,7 +8545,8 @@ grn_ii_select_sequential_search(grn_ctx *ctx,
#endif
grn_rc
-grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len,
+grn_ii_select(grn_ctx *ctx, grn_ii *ii,
+ const char *string, unsigned int string_len,
grn_hash *s, grn_operator op, grn_select_optarg *optarg)
{
btr *bt = NULL;
@@ -6344,6 +8560,9 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
grn_obj *lexicon = ii->lexicon;
grn_scorer_score_func *score_func = NULL;
grn_scorer_matched_record record;
+ grn_id previous_min = GRN_ID_NIL;
+ grn_id current_min = GRN_ID_NIL;
+ grn_bool set_min_enable_for_and_query = GRN_FALSE;
if (!lexicon || !ii || !s) { return GRN_INVALID_ARGUMENT; }
if (optarg) {
@@ -6353,6 +8572,12 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
} else if (optarg->vector_size) {
wvm = optarg->weight_vector ? grn_wv_static : grn_wv_constant;
}
+ if (optarg->match_info) {
+ if (optarg->match_info->flags & GRN_MATCH_INFO_GET_MIN_RECORD_ID) {
+ previous_min = optarg->match_info->min;
+ set_min_enable_for_and_query = GRN_TRUE;
+ }
+ }
}
if (mode == GRN_OP_SIMILAR) {
return grn_ii_similar_search(ctx, ii, string, string_len, s, op, optarg);
@@ -6373,7 +8598,20 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
if (!(tis = GRN_MALLOC(sizeof(token_info *) * string_len * 2))) {
return GRN_NO_MEMORY_AVAILABLE;
}
- if (token_info_build(ctx, lexicon, ii, string, string_len, tis, &n, &only_skip_token, mode) || !n) { goto exit; }
+ if (mode == GRN_OP_FUZZY) {
+ if (token_info_build_fuzzy(ctx, lexicon, ii, string, string_len,
+ tis, &n, &only_skip_token, previous_min,
+ mode, &(optarg->fuzzy)) ||
+ !n) {
+ goto exit;
+ }
+ } else {
+ if (token_info_build(ctx, lexicon, ii, string, string_len,
+ tis, &n, &only_skip_token, previous_min, mode) ||
+ !n) {
+ goto exit;
+ }
+ }
switch (mode) {
case GRN_OP_NEAR2 :
token_info_clear_offset(tis, n);
@@ -6404,7 +8642,7 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
if ((rc = grn_hash_array_init(s, (*tis)->size + 32768))) { goto exit; }
do {
grn_rset_recinfo *ri;
- grn_ii_posting *p = c->post;
+ grn_posting *p = c->post;
if ((weight = get_weight(ctx, s, p->rid, p->sid, wvm, optarg))) {
GRN_HASH_INT_ADD(s, p, ri);
ri->score = (p->tf + p->score) * weight;
@@ -6452,7 +8690,7 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
}
}
weight = get_weight(ctx, s, rid, sid, wvm, optarg);
- if (tip == tie && weight > 0) {
+ if (tip == tie && weight != 0) {
grn_rset_posinfo pi = {rid, sid, 0};
if (orp || grn_hash_get(ctx, s, &pi, s->key_size, NULL)) {
int count = 0, noccur = 0, pos = 0, score = 0, tscore = 0, min, max;
@@ -6474,7 +8712,7 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
}
if (n == 1 && !rep) {
noccur = (*tis)->p->tf;
- tscore = (*tis)->p->weight;
+ tscore = (*tis)->p->weight + (*tis)->cursors->bins[0]->weight;
if (score_func) {
GRN_RECORD_PUT(ctx, &(record.terms), (*tis)->cursors->bins[0]->id);
GRN_UINT32_PUT(ctx, &(record.term_weights), tscore);
@@ -6492,8 +8730,22 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
if (tip == tie) {
for (;;) {
ti = bt->min; min = ti->pos; max = bt->max->pos;
- if (min > max) { exit(0); }
- if (max - min <= max_interval) {
+ if (min > max) {
+ char ii_name[GRN_TABLE_MAX_KEY_SIZE];
+ int ii_name_size;
+ ii_name_size = grn_obj_name(ctx, (grn_obj *)ii, ii_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_FILE_CORRUPT,
+ "[ii][select][near] "
+ "max position must be larger than min position: "
+ "min:<%d> max:<%d> ii:<%.*s> string:<%.*s>",
+ min, max,
+ ii_name_size, ii_name,
+ string_len, string);
+ rc = ctx->rc;
+ goto exit;
+ }
+ if ((max_interval < 0) || (max - min <= max_interval)) {
if (rep) { pi.pos = min; res_add(ctx, s, &pi, weight, op); }
noccur++;
if (ti->pos == max + 1) {
@@ -6515,9 +8767,10 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
ti = *tip;
SKIP_OR_BREAK(pos);
if (ti->pos == pos) {
- score += ti->p->weight; count++;
+ score += ti->p->weight + ti->cursors->bins[0]->weight; count++;
} else {
- score = ti->p->weight; count = 1; pos = ti->pos;
+ score = ti->p->weight + ti->cursors->bins[0]->weight; count = 1;
+ pos = ti->pos;
if (noccur == 0 && score_func) {
GRN_BULK_REWIND(&(record.terms));
GRN_BULK_REWIND(&(record.term_weights));
@@ -6527,12 +8780,15 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
}
if (noccur == 0 && score_func) {
GRN_RECORD_PUT(ctx, &(record.terms), ti->cursors->bins[0]->id);
- GRN_UINT32_PUT(ctx, &(record.term_weights), ti->p->weight);
+ GRN_UINT32_PUT(ctx, &(record.term_weights),
+ ti->p->weight + ti->cursors->bins[0]->weight);
record.n_candidates += ti->size;
record.n_tokens += ti->ntoken;
}
if (count == n) {
- if (rep) { pi.pos = pos; res_add(ctx, s, &pi, (score + 1) * weight, op); }
+ if (rep) {
+ pi.pos = pos; res_add(ctx, s, &pi, (score + 1) * weight, op);
+ }
tscore += score;
score = 0; count = 0; pos++;
noccur++;
@@ -6550,6 +8806,11 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
} else {
record_score = (noccur + tscore) * weight;
}
+ if (set_min_enable_for_and_query) {
+ if (current_min == GRN_ID_NIL) {
+ current_min = rid;
+ }
+ }
res_add(ctx, s, &pi, record_score, op);
}
#undef SKIP_OR_BREAK
@@ -6562,6 +8823,13 @@ exit :
GRN_OBJ_FIN(ctx, &(record.terms));
GRN_OBJ_FIN(ctx, &(record.term_weights));
}
+
+ if (set_min_enable_for_and_query) {
+ if (current_min > previous_min) {
+ optarg->match_info->min = current_min;
+ }
+ }
+
for (tip = tis; tip < tis + n; tip++) {
if (*tip) { token_info_close(ctx, *tip); }
}
@@ -6582,6 +8850,40 @@ exit :
return rc;
}
+static uint32_t
+grn_ii_estimate_size_for_query_regexp(grn_ctx *ctx, grn_ii *ii,
+ const char *query, unsigned int query_len,
+ grn_search_optarg *optarg)
+{
+ grn_rc rc;
+ grn_obj parsed_query;
+ uint32_t size;
+
+ GRN_TEXT_INIT(&parsed_query, 0);
+ rc = grn_ii_parse_regexp_query(ctx, "[ii][estimate-size][query][regexp]",
+ query, query_len, &parsed_query);
+ if (rc != GRN_SUCCESS) {
+ GRN_OBJ_FIN(ctx, &parsed_query);
+ return 0;
+ }
+
+ if (optarg) {
+ optarg->mode = GRN_OP_EXACT;
+ }
+
+ size = grn_ii_estimate_size_for_query(ctx, ii,
+ GRN_TEXT_VALUE(&parsed_query),
+ GRN_TEXT_LEN(&parsed_query),
+ optarg);
+ GRN_OBJ_FIN(ctx, &parsed_query);
+
+ if (optarg) {
+ optarg->mode = GRN_OP_REGEXP;
+ }
+
+ return size;
+}
+
uint32_t
grn_ii_estimate_size_for_query(grn_ctx *ctx, grn_ii *ii,
const char *query, unsigned int query_len,
@@ -6595,16 +8897,13 @@ grn_ii_estimate_size_for_query(grn_ctx *ctx, grn_ii *ii,
grn_bool only_skip_token = GRN_FALSE;
grn_operator mode = GRN_OP_EXACT;
double estimated_size = 0;
+ double normalized_ratio = 1.0;
+ grn_id min = GRN_ID_NIL;
if (query_len == 0) {
return 0;
}
- tis = GRN_MALLOC(sizeof(token_info *) * query_len * 2);
- if (!tis) {
- return 0;
- }
-
if (optarg) {
switch (optarg->mode) {
case GRN_OP_NEAR :
@@ -6617,13 +8916,38 @@ grn_ii_estimate_size_for_query(grn_ctx *ctx, grn_ii *ii,
case GRN_OP_REGEXP :
mode = optarg->mode;
break;
+ case GRN_OP_FUZZY :
+ mode = optarg->mode;
default :
break;
}
+ if (optarg->match_info.flags & GRN_MATCH_INFO_GET_MIN_RECORD_ID) {
+ min = optarg->match_info.min;
+ }
+ }
+
+ if (mode == GRN_OP_REGEXP) {
+ return grn_ii_estimate_size_for_query_regexp(ctx, ii, query, query_len,
+ optarg);
+ }
+
+ tis = GRN_MALLOC(sizeof(token_info *) * query_len * 2);
+ if (!tis) {
+ return 0;
+ }
+
+ switch (mode) {
+ case GRN_OP_FUZZY :
+ rc = token_info_build_fuzzy(ctx, lexicon, ii, query, query_len,
+ tis, &n_tis, &only_skip_token, min,
+ mode, &(optarg->fuzzy));
+ break;
+ default :
+ rc = token_info_build(ctx, lexicon, ii, query, query_len,
+ tis, &n_tis, &only_skip_token, min, mode);
+ break;
}
- rc = token_info_build(ctx, lexicon, ii, query, query_len,
- tis, &n_tis, &only_skip_token, mode);
if (rc != GRN_SUCCESS) {
goto exit;
}
@@ -6635,10 +8959,18 @@ grn_ii_estimate_size_for_query(grn_ctx *ctx, grn_ii *ii,
if (i == 0) {
estimated_size = term_estimated_size;
} else {
- estimated_size = fmin(estimated_size, term_estimated_size);
+ if (term_estimated_size < estimated_size) {
+ estimated_size = term_estimated_size;
+ }
+ normalized_ratio *= grn_ii_estimate_size_for_query_reduce_ratio;
}
}
+ estimated_size *= normalized_ratio;
+ if (estimated_size > 0.0 && estimated_size < 1.0) {
+ estimated_size = 1.0;
+ }
+
exit :
for (i = 0; i < n_tis; i++) {
token_info *ti = tis[i];
@@ -6676,8 +9008,10 @@ grn_ii_sel(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len
ERRCLR(ctx);
GRN_LOG(ctx, GRN_LOG_INFO, "grn_ii_sel > (%.*s)", string_len, string);
{
- grn_select_optarg arg = {GRN_OP_EXACT, 0, 0, NULL, 0, NULL, NULL, 0, NULL};
+ grn_select_optarg arg;
if (!s) { return GRN_INVALID_ARGUMENT; }
+ memset(&arg, 0, sizeof(grn_select_optarg));
+ arg.mode = GRN_OP_EXACT;
if (optarg) {
switch (optarg->mode) {
case GRN_OP_NEAR :
@@ -6692,16 +9026,21 @@ grn_ii_sel(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len
case GRN_OP_REGEXP :
arg.mode = optarg->mode;
break;
+ case GRN_OP_FUZZY :
+ arg.mode = optarg->mode;
+ arg.fuzzy = optarg->fuzzy;
+ break;
default :
break;
}
- if (optarg->vector_size > 0) {
+ if (optarg->vector_size != 0) {
arg.weight_vector = optarg->weight_vector;
arg.vector_size = optarg->vector_size;
}
arg.scorer = optarg->scorer;
arg.scorer_args_expr = optarg->scorer_args_expr;
arg.scorer_args_expr_offset = optarg->scorer_args_expr_offset;
+ arg.match_info = &(optarg->match_info);
}
/* todo : support subrec
grn_rset_init(ctx, s, grn_rec_document, 0, grn_rec_none, 0, 0);
@@ -6712,21 +9051,50 @@ grn_ii_sel(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len
}
GRN_LOG(ctx, GRN_LOG_INFO, "exact: %d", GRN_HASH_SIZE(s));
if (op == GRN_OP_OR) {
+ grn_id min = GRN_ID_NIL;
if ((int64_t)GRN_HASH_SIZE(s) <= ctx->impl->match_escalation_threshold) {
arg.mode = GRN_OP_UNSPLIT;
+ if (arg.match_info) {
+ if (arg.match_info->flags & GRN_MATCH_INFO_GET_MIN_RECORD_ID) {
+ min = arg.match_info->min;
+ arg.match_info->min = GRN_ID_NIL;
+ }
+ }
if (grn_ii_select(ctx, ii, string, string_len, s, op, &arg)) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "grn_ii_select on grn_ii_sel(2) failed !");
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "grn_ii_select on grn_ii_sel(2) failed !");
return ctx->rc;
}
GRN_LOG(ctx, GRN_LOG_INFO, "unsplit: %d", GRN_HASH_SIZE(s));
+ if (arg.match_info) {
+ if (arg.match_info->flags & GRN_MATCH_INFO_GET_MIN_RECORD_ID) {
+ if (min > GRN_ID_NIL && min < arg.match_info->min) {
+ arg.match_info->min = min;
+ }
+ }
+ }
}
if ((int64_t)GRN_HASH_SIZE(s) <= ctx->impl->match_escalation_threshold) {
arg.mode = GRN_OP_PARTIAL;
+ if (arg.match_info) {
+ if (arg.match_info->flags & GRN_MATCH_INFO_GET_MIN_RECORD_ID) {
+ min = arg.match_info->min;
+ arg.match_info->min = GRN_ID_NIL;
+ }
+ }
if (grn_ii_select(ctx, ii, string, string_len, s, op, &arg)) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "grn_ii_select on grn_ii_sel(3) failed !");
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "grn_ii_select on grn_ii_sel(3) failed !");
return ctx->rc;
}
GRN_LOG(ctx, GRN_LOG_INFO, "partial: %d", GRN_HASH_SIZE(s));
+ if (arg.match_info) {
+ if (arg.match_info->flags & GRN_MATCH_INFO_GET_MIN_RECORD_ID) {
+ if (min > GRN_ID_NIL && min < arg.match_info->min) {
+ arg.match_info->min = min;
+ }
+ }
+ }
}
}
GRN_LOG(ctx, GRN_LOG_INFO, "hits=%d", GRN_HASH_SIZE(s));
@@ -6739,7 +9107,7 @@ grn_ii_at(grn_ctx *ctx, grn_ii *ii, grn_id id, grn_hash *s, grn_operator op)
{
int rep = 0;
grn_ii_cursor *c;
- grn_ii_posting *pos;
+ grn_posting *pos;
if ((c = grn_ii_cursor_open(ctx, ii, id, GRN_ID_NIL, GRN_ID_MAX,
rep ? ii->n_elements : ii->n_elements - 1, 0))) {
while ((pos = grn_ii_cursor_next(ctx, c))) {
@@ -6757,7 +9125,8 @@ grn_ii_resolve_sel_and(grn_ctx *ctx, grn_hash *s, grn_operator op)
&& !(ctx->flags & GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND)) {
grn_id eid;
grn_rset_recinfo *ri;
- grn_hash_cursor *c = grn_hash_cursor_open(ctx, s, NULL, 0, NULL, 0, 0, -1, 0);
+ grn_hash_cursor *c = grn_hash_cursor_open(ctx, s, NULL, 0, NULL, 0,
+ 0, -1, 0);
if (c) {
while ((eid = grn_hash_cursor_next(ctx, c))) {
grn_hash_cursor_get_value(ctx, c, (void **) &ri);
@@ -6772,190 +9141,6 @@ grn_ii_resolve_sel_and(grn_ctx *ctx, grn_hash *s, grn_operator op)
}
}
-/* just for inspect */
-static grn_ii_posting *
-grn_ii_cursor_next_all(grn_ctx *ctx, grn_ii_cursor *c)
-{
- if (c->buf) {
- for (;;) {
- if (c->stat & CHUNK_USED) {
- for (;;) {
- if (c->crp < c->cdp + c->cdf) {
- uint32_t dgap = *c->crp++;
- c->pc.rid += dgap;
- if (dgap) { c->pc.sid = 0; }
- if ((c->ii->header->flags & GRN_OBJ_WITH_SECTION)) {
- c->pc.sid += 1 + *c->csp++;
- } else {
- c->pc.sid = 1;
- }
- c->cpp += c->pc.rest;
- c->pc.rest = c->pc.tf = 1 + *c->ctp++;
- if ((c->ii->header->flags & GRN_OBJ_WITH_WEIGHT)) {
- c->pc.weight = *c->cwp++;
- } else {
- c->pc.weight = 0;
- }
- c->pc.pos = 0;
- /*
- {
- static int count = 0;
- int tf = c->pc.tf, pos = 0, *pp = (int *)c->cpp;
- grn_obj buf;
- GRN_TEXT_INIT(&buf, 0);
- grn_text_itoa(ctx, &buf, c->pc.rid);
- GRN_TEXT_PUTC(ctx, &buf, ':');
- grn_text_itoa(ctx, &buf, c->pc.sid);
- GRN_TEXT_PUTC(ctx, &buf, ':');
- grn_text_itoa(ctx, &buf, c->pc.tf);
- GRN_TEXT_PUTC(ctx, &buf, '(');
- while (tf--) {
- pos += *pp++;
- count++;
- grn_text_itoa(ctx, &buf, pos);
- if (tf) { GRN_TEXT_PUTC(ctx, &buf, ':'); }
- }
- GRN_TEXT_PUTC(ctx, &buf, ')');
- GRN_TEXT_PUTC(ctx, &buf, '\0');
- GRN_LOG(ctx, GRN_LOG_NOTICE, "posting(%d):%s", count, GRN_TEXT_VALUE(&buf));
- GRN_OBJ_FIN(ctx, &buf);
- }
- */
- } else {
- if (c->curr_chunk <= c->nchunks) {
- if (c->curr_chunk == c->nchunks) {
- if (c->cp < c->cpe) {
- grn_p_decv(ctx, c->cp, c->cpe - c->cp, c->rdv, c->ii->n_elements);
- } else {
- c->pc.rid = 0;
- break;
- }
- } else {
- uint8_t *cp;
- grn_io_win iw;
- uint32_t size = c->cinfo[c->curr_chunk].size;
- if (size && (cp = WIN_MAP(c->ii->chunk, ctx, &iw,
- c->cinfo[c->curr_chunk].segno, 0,
- size, grn_io_rdonly))) {
- grn_p_decv(ctx, cp, size, c->rdv, c->ii->n_elements);
- grn_io_win_unmap(&iw);
- } else {
- c->pc.rid = 0;
- break;
- }
- }
- {
- int j = 0;
- c->cdf = c->rdv[j].data_size;
- c->crp = c->cdp = c->rdv[j++].data;
- if ((c->ii->header->flags & GRN_OBJ_WITH_SECTION)) {
- c->csp = c->rdv[j++].data;
- }
- c->ctp = c->rdv[j++].data;
- if ((c->ii->header->flags & GRN_OBJ_WITH_WEIGHT)) {
- c->cwp = c->rdv[j++].data;
- }
- c->cpp = c->rdv[j].data;
- }
- c->pc.rid = 0;
- c->pc.sid = 0;
- c->pc.rest = 0;
- c->curr_chunk++;
- continue;
- } else {
- c->pc.rid = 0;
- }
- }
- break;
- }
- }
- if (c->stat & BUFFER_USED) {
- if (c->nextb) {
- uint32_t lrid = c->pb.rid, lsid = c->pb.sid; /* for check */
- buffer_rec *br = BUFFER_REC_AT(c->buf, c->nextb);
- if (buffer_is_reused(ctx, c->ii, c)) {
- GRN_LOG(ctx, GRN_LOG_NOTICE, "buffer reused(%d,%d)", c->buffer_pseg, *c->ppseg);
- // todo : rewind;
- }
- c->bp = NEXT_ADDR(br);
- GRN_B_DEC(c->pb.rid, c->bp);
- if ((c->ii->header->flags & GRN_OBJ_WITH_SECTION)) {
- GRN_B_DEC(c->pb.sid, c->bp);
- } else {
- c->pb.sid = 1;
- }
- if (lrid > c->pb.rid || (lrid == c->pb.rid && lsid >= c->pb.sid)) {
- ERR(GRN_FILE_CORRUPT, "brokend!! (%d:%d) -> (%d:%d) (%d->%d)", lrid, lsid, c->pb.rid, c->pb.sid, c->buffer_pseg, *c->ppseg);
- }
- c->nextb = br->step;
- GRN_B_DEC(c->pb.tf, c->bp);
- if ((c->ii->header->flags & GRN_OBJ_WITH_WEIGHT)) {
- GRN_B_DEC(c->pb.weight, c->bp);
- } else {
- c->pb.weight = 0;
- }
- c->pb.rest = c->pb.tf;
- c->pb.pos = 0;
- } else {
- c->pb.rid = 0;
- }
- }
- if (c->pb.rid) {
- if (c->pc.rid) {
- if (c->pc.rid < c->pb.rid) {
- c->stat = CHUNK_USED;
- c->post = &c->pc;
- break;
- } else {
- if (c->pb.rid < c->pc.rid) {
- c->stat = BUFFER_USED;
- c->post = &c->pb;
- break;
- } else {
- if (c->pb.sid) {
- if (c->pc.sid < c->pb.sid) {
- c->stat = CHUNK_USED;
- c->post = &c->pc;
- break;
- } else {
- c->stat = BUFFER_USED;
- if (c->pb.sid == c->pc.sid) { c->stat |= CHUNK_USED; }
- c->post = &c->pb;
- break;
- }
- } else {
- c->stat = CHUNK_USED;
- }
- }
- }
- } else {
- c->stat = BUFFER_USED;
- c->post = &c->pb;
- break;
- }
- } else {
- if (c->pc.rid) {
- c->stat = CHUNK_USED;
- c->post = &c->pc;
- break;
- } else {
- c->post = NULL;
- return NULL;
- }
- }
- }
- } else {
- if (c->stat & SOLE_DOC_USED) {
- c->post = NULL;
- return NULL;
- } else {
- c->post = &c->pb;
- c->stat |= SOLE_DOC_USED;
- }
- }
- return c->post;
-}
-
void
grn_ii_cursor_inspect(grn_ctx *ctx, grn_ii_cursor *c, grn_obj *buf)
{
@@ -6963,6 +9148,9 @@ grn_ii_cursor_inspect(grn_ctx *ctx, grn_ii_cursor *c, grn_obj *buf)
char key[GRN_TABLE_MAX_KEY_SIZE];
int key_size;
int i = 0;
+ grn_ii_cursor_next_options options = {
+ .include_garbage = GRN_TRUE
+ };
GRN_TEXT_PUTS(ctx, buf, " #<");
key_size = grn_table_get_key(ctx, c->ii->lexicon, c->id,
@@ -6973,8 +9161,8 @@ grn_ii_cursor_inspect(grn_ctx *ctx, grn_ii_cursor *c, grn_obj *buf)
GRN_OBJ_FIN(ctx, &key_buf);
GRN_TEXT_PUTS(ctx, buf, "\n elements:[\n ");
- while (grn_ii_cursor_next_all(ctx, c)) {
- grn_ii_posting *pos = c->post;
+ while (grn_ii_cursor_next_internal(ctx, c, &options)) {
+ grn_posting *pos = c->post;
if (i > 0) {
GRN_TEXT_PUTS(ctx, buf, ",\n ");
}
@@ -7038,11 +9226,7 @@ const grn_id II_BUFFER_TYPE_MASK = 0xc0000000;
#define II_BUFFER_TYPE(id) (((id) & II_BUFFER_TYPE_MASK))
#define II_BUFFER_PACK(value, type) ((value) | (type))
#define II_BUFFER_UNPACK(id, type) ((id) & ~(type))
-#ifdef II_BUFFER_ORDER_BY_ID
-const int II_BUFFER_ORDER = GRN_CURSOR_BY_ID;
-#else /* II_BUFFER_ORDER_BY_ID */
-const int II_BUFFER_ORDER = GRN_CURSOR_BY_KEY;
-#endif /* II_BUFFER_ORDER_BY_ID */
+#define II_BUFFER_ORDER GRN_CURSOR_BY_KEY
const uint16_t II_BUFFER_NTERMS_PER_BUFFER = 16380;
const uint32_t II_BUFFER_PACKED_BUF_SIZE = 0x4000000;
const char *TMPFILE_PATH = "grn_ii_buffer_tmp";
@@ -7051,18 +9235,34 @@ const size_t II_BUFFER_BLOCK_SIZE = 0x1000000;
const uint32_t II_BUFFER_BLOCK_READ_UNIT_SIZE = 0x200000;
typedef struct {
- uint32_t nrecs;
- uint32_t nposts;
- grn_id last_rid;
- uint32_t last_sid;
- uint32_t last_tf;
- uint32_t last_weight;
- uint32_t last_pos;
- uint32_t offset_rid;
- uint32_t offset_sid;
- uint32_t offset_tf;
- uint32_t offset_weight;
- uint32_t offset_pos;
+ unsigned int sid; /* Section ID */
+ unsigned int weight; /* Weight */
+ const char *p; /* Value address */
+ uint32_t len; /* Value length */
+ char *buf; /* Buffer address */
+ uint32_t cap; /* Buffer size */
+} ii_buffer_value;
+
+/* ii_buffer_counter is associated with a combination of a block an a term. */
+typedef struct {
+ uint32_t nrecs; /* Number of records or sections */
+ uint32_t nposts; /* Number of occurrences */
+
+ /* Information of the last value */
+ grn_id last_rid; /* Record ID */
+ uint32_t last_sid; /* Section ID */
+ uint32_t last_tf; /* Term frequency */
+ uint32_t last_weight; /* Total weight */
+ uint32_t last_pos; /* Token position */
+
+ /* Meaning of offset_* is different before/after encoding. */
+ /* Before encoding: size in encoded sequence */
+ /* After encoding: Offset in encoded sequence */
+ uint32_t offset_rid; /* Record ID */
+ uint32_t offset_sid; /* Section ID */
+ uint32_t offset_tf; /* Term frequency */
+ uint32_t offset_weight; /* Weight */
+ uint32_t offset_pos; /* Token position */
} ii_buffer_counter;
typedef struct {
@@ -7082,22 +9282,28 @@ typedef struct {
} ii_buffer_block;
struct _grn_ii_buffer {
- grn_obj *lexicon;
- grn_obj *tmp_lexicon;
- ii_buffer_block *blocks;
- uint32_t nblocks;
- int tmpfd;
- char tmpfpath[PATH_MAX];
+ grn_obj *lexicon; /* Global lexicon */
+ grn_obj *tmp_lexicon; /* Temporary lexicon for each block */
+ ii_buffer_block *blocks; /* Blocks */
+ uint32_t nblocks; /* Number of blocks */
+ int tmpfd; /* Descriptor of temporary file */
+ char tmpfpath[PATH_MAX]; /* Path of temporary file */
uint64_t update_buffer_size;
+
// stuff for parsing
- off64_t filepos;
- grn_id *block_buf;
- size_t block_buf_size;
- size_t block_pos;
- ii_buffer_counter *counters;
- uint32_t ncounters;
+ off64_t filepos; /* Write position of temporary file */
+ grn_id *block_buf; /* Buffer for the current block */
+ size_t block_buf_size; /* Size of block_buf */
+ size_t block_pos; /* Write position of block_buf */
+ ii_buffer_counter *counters; /* Status of terms */
+ uint32_t ncounters; /* Number of counters */
size_t total_size;
size_t curr_size;
+ ii_buffer_value *values; /* Values in block */
+ unsigned int nvalues; /* Number of values in block */
+ unsigned int max_nvalues; /* Size of values */
+ grn_id last_rid;
+
// stuff for merging
grn_ii *ii;
uint32_t lseg;
@@ -7110,6 +9316,7 @@ struct _grn_ii_buffer {
size_t total_chunk_size;
};
+/* block_new returns a new ii_buffer_block to store block information. */
static ii_buffer_block *
block_new(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
{
@@ -7131,6 +9338,7 @@ block_new(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
return block;
}
+/* allocate_outbuf allocates memory to flush a block. */
static uint8_t *
allocate_outbuf(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
{
@@ -7166,6 +9374,27 @@ allocate_outbuf(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
return (uint8_t *)GRN_MALLOC(bufsize);
}
+/*
+ * The temporary file format is roughly as follows:
+ *
+ * File = Block...
+ * Block = Unit...
+ * Unit = TermChunk (key order)
+ * NextUnitSize (The first unit size is kept on memory)
+ * Chunk = Term...
+ * Term = ID (gtid)
+ * NumRecordsOrSections (nrecs), NumOccurrences (nposts)
+ * RecordID... (rid, diff)
+ * [SectionID... (sid, diff)]
+ * TermFrequency... (tf, diff)
+ * [Weight... (weight, diff)]
+ * [Position... (pos, diff)]
+ */
+
+/*
+ * encode_terms encodes terms in ii_buffer->tmp_lexicon and returns the
+ * expected temporary file size.
+ */
static size_t
encode_terms(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
uint8_t *outbuf, ii_buffer_block *block)
@@ -7174,6 +9403,7 @@ encode_terms(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
uint8_t *outbufp = outbuf;
uint8_t *outbufp_ = outbuf;
grn_table_cursor *tc;
+ /* The first size is written into block->nextsize. */
uint8_t *pnext = (uint8_t *)&block->nextsize;
uint32_t flags = ii_buffer->ii->header->flags;
tc = grn_table_cursor_open(ctx, ii_buffer->tmp_lexicon,
@@ -7182,6 +9412,7 @@ encode_terms(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
char key[GRN_TABLE_MAX_KEY_SIZE];
int key_size = grn_table_get_key(ctx, ii_buffer->tmp_lexicon, tid,
key, GRN_TABLE_MAX_KEY_SIZE);
+ /* gtid is a global term ID, not in a temporary lexicon. */
grn_id gtid = grn_table_add(ctx, ii_buffer->lexicon, key, key_size, NULL);
ii_buffer_counter *counter = &ii_buffer->counters[tid - 1];
if (counter->nrecs) {
@@ -7227,6 +9458,7 @@ encode_terms(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
return outbufp - outbuf;
}
+/* encode_postings encodes data in ii_buffer->block_buf. */
static void
encode_postings(grn_ctx *ctx, grn_ii_buffer *ii_buffer, uint8_t *outbuf)
{
@@ -7303,6 +9535,7 @@ encode_postings(grn_ctx *ctx, grn_ii_buffer *ii_buffer, uint8_t *outbuf)
}
}
+/* encode_last_tf encodes last_tf and last_weight in counters. */
static void
encode_last_tf(grn_ctx *ctx, grn_ii_buffer *ii_buffer, uint8_t *outbuf)
{
@@ -7320,13 +9553,18 @@ encode_last_tf(grn_ctx *ctx, grn_ii_buffer *ii_buffer, uint8_t *outbuf)
}
}
+/*
+ * grn_ii_buffer_flush flushes the current block (ii_buffer->block_buf,
+ * counters and tmp_lexicon) to a temporary file (ii_buffer->tmpfd).
+ * Also, block information is stored into ii_buffer->blocks.
+ */
static void
grn_ii_buffer_flush(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
{
size_t encsize;
uint8_t *outbuf;
ii_buffer_block *block;
- GRN_LOG(ctx, GRN_LOG_NOTICE, "flushing:%d npostings:%" GRN_FMT_SIZE,
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "flushing:%d npostings:%" GRN_FMT_SIZE,
ii_buffer->nblocks, ii_buffer->block_pos);
if (!(block = block_new(ctx, ii_buffer))) { return; }
if (!(outbuf = allocate_outbuf(ctx, ii_buffer))) { return; }
@@ -7336,8 +9574,10 @@ grn_ii_buffer_flush(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
{
ssize_t r = grn_write(ii_buffer->tmpfd, outbuf, encsize);
if (r != encsize) {
- ERR(GRN_INPUT_OUTPUT_ERROR, "write returned %" GRN_FMT_LLD " != %" GRN_FMT_LLU,
+ ERR(GRN_INPUT_OUTPUT_ERROR,
+ "write returned %" GRN_FMT_LLD " != %" GRN_FMT_LLU,
(long long int)r, (unsigned long long int)encsize);
+ GRN_FREE(outbuf);
return;
}
ii_buffer->filepos += r;
@@ -7348,7 +9588,7 @@ grn_ii_buffer_flush(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
grn_table_size(ctx, ii_buffer->tmp_lexicon) *
sizeof(ii_buffer_counter));
grn_obj_close(ctx, ii_buffer->tmp_lexicon);
- GRN_LOG(ctx, GRN_LOG_NOTICE, "flushed: %d encsize:%" GRN_FMT_SIZE,
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "flushed: %d encsize:%" GRN_FMT_SIZE,
ii_buffer->nblocks, encsize);
ii_buffer->tmp_lexicon = NULL;
ii_buffer->nblocks++;
@@ -7357,6 +9597,12 @@ grn_ii_buffer_flush(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
const uint32_t PAT_CACHE_SIZE = 1<<20;
+/*
+ * get_tmp_lexicon returns a temporary lexicon.
+ *
+ * Note that a lexicon is created for each block and ii_buffer->tmp_lexicon is
+ * closed in grn_ii_buffer_flush.
+ */
static grn_obj *
get_tmp_lexicon(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
{
@@ -7367,7 +9613,7 @@ get_tmp_lexicon(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
grn_obj *tokenizer;
grn_obj *normalizer;
grn_obj *token_filters;
- grn_obj_flags flags;
+ grn_table_flags flags;
grn_table_get_info(ctx, ii_buffer->lexicon, &flags, NULL,
&tokenizer, &normalizer, &token_filters);
flags &= ~GRN_OBJ_PERSISTENT;
@@ -7388,6 +9634,7 @@ get_tmp_lexicon(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
return tmp_lexicon;
}
+/* get_buffer_counter returns a counter associated with tid. */
static ii_buffer_counter *
get_buffer_counter(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
grn_obj *tmp_lexicon, grn_id tid)
@@ -7407,97 +9654,132 @@ get_buffer_counter(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
return &ii_buffer->counters[tid - 1];
}
+/*
+ * grn_ii_buffer_tokenize_value tokenizes a value.
+ *
+ * The result is written into the current block (ii_buffer->tmp_lexicon,
+ * ii_buffer->block_buf, ii_buffer->counters, etc.).
+ */
static void
-grn_ii_buffer_tokenize(grn_ctx *ctx, grn_ii_buffer *ii_buffer, grn_id rid,
- unsigned int sid, unsigned int weight,
- const char *value, uint32_t value_len)
-{
- if (value_len) {
- grn_obj *tmp_lexicon;
- uint32_t est_len = value_len * 2 + 2;
- if (ii_buffer->block_buf_size < ii_buffer->block_pos + est_len) {
- grn_ii_buffer_flush(ctx, ii_buffer);
- }
- if (ii_buffer->block_buf_size < est_len) {
- grn_id *block_buf = (grn_id *)GRN_REALLOC(ii_buffer->block_buf,
- est_len * sizeof(grn_id));
- if (!block_buf) { return; }
- ii_buffer->block_buf = block_buf;
- ii_buffer->block_buf_size = est_len;
- }
- if ((tmp_lexicon = get_tmp_lexicon(ctx, ii_buffer))) {
- unsigned int token_flags = 0;
- grn_token_cursor *token_cursor;
- grn_id *buffer = ii_buffer->block_buf;
- uint32_t block_pos = ii_buffer->block_pos;
- uint32_t ii_flags = ii_buffer->ii->header->flags;
- buffer[block_pos++] = II_BUFFER_PACK(rid, II_BUFFER_TYPE_RID);
- if (ii_flags & GRN_OBJ_WITH_SECTION) {
- buffer[block_pos++] = sid;
- }
- if (weight) {
- buffer[block_pos++] = II_BUFFER_PACK(weight, II_BUFFER_TYPE_WEIGHT);
- }
- if ((token_cursor = grn_token_cursor_open(ctx, tmp_lexicon,
- value, value_len,
- GRN_TOKEN_ADD, token_flags))) {
- while (!token_cursor->status) {
- grn_id tid;
- if ((tid = grn_token_cursor_next(ctx, token_cursor))) {
- ii_buffer_counter *counter;
- counter = get_buffer_counter(ctx, ii_buffer, tmp_lexicon, tid);
- if (!counter) { return; }
- buffer[block_pos++] = tid;
- if (ii_flags & GRN_OBJ_WITH_POSITION) {
- buffer[block_pos++] = token_cursor->pos;
+grn_ii_buffer_tokenize_value(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
+ grn_id rid, const ii_buffer_value *value)
+{
+ grn_obj *tmp_lexicon;
+ if ((tmp_lexicon = get_tmp_lexicon(ctx, ii_buffer))) {
+ unsigned int token_flags = 0;
+ grn_token_cursor *token_cursor;
+ grn_id *buffer = ii_buffer->block_buf;
+ uint32_t block_pos = ii_buffer->block_pos;
+ uint32_t ii_flags = ii_buffer->ii->header->flags;
+ buffer[block_pos++] = II_BUFFER_PACK(rid, II_BUFFER_TYPE_RID);
+ if (ii_flags & GRN_OBJ_WITH_SECTION) {
+ buffer[block_pos++] = value->sid;
+ }
+ if (value->weight) {
+ buffer[block_pos++] = II_BUFFER_PACK(value->weight,
+ II_BUFFER_TYPE_WEIGHT);
+ }
+ if ((token_cursor = grn_token_cursor_open(ctx, tmp_lexicon,
+ value->p, value->len,
+ GRN_TOKEN_ADD, token_flags))) {
+ while (!token_cursor->status) {
+ grn_id tid;
+ if ((tid = grn_token_cursor_next(ctx, token_cursor))) {
+ ii_buffer_counter *counter;
+ counter = get_buffer_counter(ctx, ii_buffer, tmp_lexicon, tid);
+ if (!counter) { return; }
+ buffer[block_pos++] = tid;
+ if (ii_flags & GRN_OBJ_WITH_POSITION) {
+ buffer[block_pos++] = token_cursor->pos;
+ }
+ if (counter->last_rid != rid) {
+ counter->offset_rid += GRN_B_ENC_SIZE(rid - counter->last_rid);
+ counter->last_rid = rid;
+ counter->offset_sid += GRN_B_ENC_SIZE(value->sid - 1);
+ counter->last_sid = value->sid;
+ if (counter->last_tf) {
+ counter->offset_tf += GRN_B_ENC_SIZE(counter->last_tf - 1);
+ counter->last_tf = 0;
+ counter->offset_weight += GRN_B_ENC_SIZE(counter->last_weight);
+ counter->last_weight = 0;
}
- if (counter->last_rid != rid) {
- counter->offset_rid += GRN_B_ENC_SIZE(rid - counter->last_rid);
- counter->last_rid = rid;
- counter->offset_sid += GRN_B_ENC_SIZE(sid - 1);
- counter->last_sid = sid;
- if (counter->last_tf) {
- counter->offset_tf += GRN_B_ENC_SIZE(counter->last_tf - 1);
- counter->last_tf = 0;
- counter->offset_weight += GRN_B_ENC_SIZE(counter->last_weight);
- counter->last_weight = 0;
- }
- counter->last_pos = 0;
- counter->nrecs++;
- } else if (counter->last_sid != sid) {
- counter->offset_rid += GRN_B_ENC_SIZE(0);
- counter->offset_sid +=
- GRN_B_ENC_SIZE(sid - counter->last_sid - 1);
- counter->last_sid = sid;
- if (counter->last_tf) {
- counter->offset_tf += GRN_B_ENC_SIZE(counter->last_tf - 1);
- counter->last_tf = 0;
- counter->offset_weight += GRN_B_ENC_SIZE(counter->last_weight);
- counter->last_weight = 0;
- }
- counter->last_pos = 0;
- counter->nrecs++;
+ counter->last_pos = 0;
+ counter->nrecs++;
+ } else if (counter->last_sid != value->sid) {
+ counter->offset_rid += GRN_B_ENC_SIZE(0);
+ counter->offset_sid +=
+ GRN_B_ENC_SIZE(value->sid - counter->last_sid - 1);
+ counter->last_sid = value->sid;
+ if (counter->last_tf) {
+ counter->offset_tf += GRN_B_ENC_SIZE(counter->last_tf - 1);
+ counter->last_tf = 0;
+ counter->offset_weight += GRN_B_ENC_SIZE(counter->last_weight);
+ counter->last_weight = 0;
}
- counter->offset_pos +=
- GRN_B_ENC_SIZE(token_cursor->pos - counter->last_pos);
- counter->last_pos = token_cursor->pos;
- counter->last_tf++;
- counter->last_weight += weight;
- counter->nposts++;
+ counter->last_pos = 0;
+ counter->nrecs++;
}
+ counter->offset_pos +=
+ GRN_B_ENC_SIZE(token_cursor->pos - counter->last_pos);
+ counter->last_pos = token_cursor->pos;
+ counter->last_tf++;
+ counter->last_weight += value->weight;
+ counter->nposts++;
}
- grn_token_cursor_close(ctx, token_cursor);
}
- ii_buffer->block_pos = block_pos;
+ grn_token_cursor_close(ctx, token_cursor);
+ }
+ ii_buffer->block_pos = block_pos;
+ }
+}
+
+/*
+ * grn_ii_buffer_tokenize tokenizes ii_buffer->values.
+ *
+ * grn_ii_buffer_tokenize estimates the size of tokenized values.
+ * If the remaining space of the current block is not enough to store the new
+ * tokenized values, the current block is flushed.
+ * Then, grn_ii_buffer_tokenize tokenizes values.
+ */
+static void
+grn_ii_buffer_tokenize(grn_ctx *ctx, grn_ii_buffer *ii_buffer, grn_id rid)
+{
+ unsigned int i;
+ uint32_t est_len = 0;
+ for (i = 0; i < ii_buffer->nvalues; i++) {
+ est_len += ii_buffer->values[i].len * 2 + 2;
+ }
+ if (ii_buffer->block_buf_size < ii_buffer->block_pos + est_len) {
+ grn_ii_buffer_flush(ctx, ii_buffer);
+ }
+ if (ii_buffer->block_buf_size < est_len) {
+ grn_id *block_buf = (grn_id *)GRN_REALLOC(ii_buffer->block_buf,
+ est_len * sizeof(grn_id));
+ if (block_buf) {
+ ii_buffer->block_buf = block_buf;
+ ii_buffer->block_buf_size = est_len;
+ }
+ }
+
+ for (i = 0; i < ii_buffer->nvalues; i++) {
+ const ii_buffer_value *value = &ii_buffer->values[i];
+ if (value->len) {
+ uint32_t est_len = value->len * 2 + 2;
+ if (ii_buffer->block_buf_size >= ii_buffer->block_pos + est_len) {
+ grn_ii_buffer_tokenize_value(ctx, ii_buffer, rid, value);
+ }
}
}
+ ii_buffer->nvalues = 0;
}
+/* grn_ii_buffer_fetch fetches the next term. */
static void
grn_ii_buffer_fetch(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
ii_buffer_block *block)
{
if (!block->rest) {
+ /* Read the next unit. */
if (block->head < block->tail) {
size_t bytesize = block->nextsize;
if (block->buffersize < block->nextsize) {
@@ -7515,18 +9797,21 @@ grn_ii_buffer_fetch(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
off64_t seeked_position;
seeked_position = grn_lseek(ii_buffer->tmpfd, block->head, SEEK_SET);
if (seeked_position != block->head) {
- ERRNO_ERR("grn_lseek");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to "
- "grn_lseek(%" GRN_FMT_OFF64_T ") -> %" GRN_FMT_OFF64_T,
- block->head,
- seeked_position);
+ ERRNO_ERR("failed to "
+ "grn_lseek(%" GRN_FMT_OFF64_T ") -> %" GRN_FMT_OFF64_T,
+ block->head,
+ seeked_position);
return;
}
}
- if (grn_read(ii_buffer->tmpfd, block->buffer, bytesize) != bytesize) {
- SERR("read");
- return;
+ {
+ size_t read_bytesize;
+ read_bytesize = grn_read(ii_buffer->tmpfd, block->buffer, bytesize);
+ if (read_bytesize != bytesize) {
+ SERR("failed to grn_read(%" GRN_FMT_SIZE ") -> %" GRN_FMT_SIZE,
+ bytesize, read_bytesize);
+ return;
+ }
}
block->head += bytesize;
block->bufcur = block->buffer;
@@ -7557,6 +9842,7 @@ grn_ii_buffer_fetch(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
}
}
+/* grn_ii_buffer_chunk_flush flushes the current buffer for packed postings. */
static void
grn_ii_buffer_chunk_flush(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
{
@@ -7577,7 +9863,7 @@ grn_ii_buffer_chunk_flush(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
buffer_segment_update(ii_buffer->ii, ii_buffer->lseg, ii_buffer->dseg);
ii_buffer->ii->header->total_chunk_size += ii_buffer->packed_len;
ii_buffer->total_chunk_size += ii_buffer->packed_len;
- GRN_LOG(ctx, GRN_LOG_NOTICE,
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
"nterms=%d chunk=%d total=%" GRN_FMT_INT64U "KB",
ii_buffer->term_buffer->header.nterms,
ii_buffer->term_buffer->header.chunk_size,
@@ -7589,6 +9875,10 @@ grn_ii_buffer_chunk_flush(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
ii_buffer->curr_size = 0;
}
+/*
+ * merge_hit_blocks merges hit blocks into ii_buffer->data_vectors.
+ * merge_hit_blocks returns the estimated maximum size in bytes.
+ */
static size_t
merge_hit_blocks(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
ii_buffer_block *hits[], int nhits)
@@ -7610,10 +9900,11 @@ merge_hit_blocks(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
ii_buffer->ii->n_elements, nrecs, max_size);
{
int i;
- uint32_t lr = 0;
+ uint32_t lr = 0; /* Last rid */
uint64_t spos = 0;
uint32_t *ridp, *sidp = NULL, *tfp, *weightp = NULL, *posp = NULL;
{
+ /* Get write positions in datavec. */
int j = 0;
ridp = ii_buffer->data_vectors[j++].data;
if (flags & GRN_OBJ_WITH_SECTION) {
@@ -7628,6 +9919,7 @@ merge_hit_blocks(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
}
}
for (i = 0; i < nhits; i++) {
+ /* Read postings from hit blocks and join the postings into datavec. */
ii_buffer_block *block = hits[i];
uint8_t *p = block->bufcur;
uint32_t n = block->nrecs;
@@ -7664,6 +9956,7 @@ merge_hit_blocks(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
grn_ii_buffer_fetch(ctx, ii_buffer, block);
}
{
+ /* Set size and flags of datavec. */
int j = 0;
uint32_t f_s = (nrecs < 3) ? 0 : USE_P_ENC;
uint32_t f_d = ((nrecs < 16) || (nrecs <= (lr >> 8))) ? 0 : USE_P_ENC;
@@ -7697,10 +9990,13 @@ get_term_buffer(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
uint32_t lseg;
void *term_buffer;
for (lseg = 0; lseg < GRN_II_MAX_LSEG; lseg++) {
- if (ii_buffer->ii->header->binfo[lseg] == NOT_ASSIGNED) { break; }
+ if (ii_buffer->ii->header->binfo[lseg] == GRN_II_PSEG_NOT_ASSIGNED) { break; }
}
if (lseg == GRN_II_MAX_LSEG) {
- ERR(GRN_NO_MEMORY_AVAILABLE, "segment allocate failed");
+ DEFINE_NAME(ii_buffer->ii);
+ MERR("[ii][buffer][term-buffer] couldn't find a free buffer: "
+ "<%.*s>",
+ name_size, name);
return NULL;
}
ii_buffer->lseg = lseg;
@@ -7711,6 +10007,15 @@ get_term_buffer(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
return ii_buffer->term_buffer;
}
+/*
+ * try_in_place_packing tries to pack a posting in an array element.
+ *
+ * The requirements are as follows:
+ * - nposts == 1
+ * - nhits == 1 && nrecs == 1 && tf == 0
+ * - weight == 0
+ * - !(flags & GRN_OBJ_WITH_SECTION) || (rid < 0x100000 && sid < 0x800)
+ */
static grn_bool
try_in_place_packing(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
grn_id tid, ii_buffer_block *hits[], int nhits)
@@ -7736,6 +10041,7 @@ try_in_place_packing(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
uint32_t *a = array_get(ctx, ii_buffer->ii, tid);
a[0] = (rid << 12) + (sid << 1) + 1;
a[1] = pos;
+ array_unref(ii_buffer->ii, tid);
} else {
return GRN_FALSE;
}
@@ -7743,6 +10049,7 @@ try_in_place_packing(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
uint32_t *a = array_get(ctx, ii_buffer->ii, tid);
a[0] = (rid << 1) + 1;
a[1] = pos;
+ array_unref(ii_buffer->ii, tid);
}
block->rest -= (p - block->bufcur);
block->bufcur = p;
@@ -7753,11 +10060,13 @@ try_in_place_packing(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
return GRN_FALSE;
}
+/* grn_ii_buffer_merge merges hit blocks and pack it. */
static void
grn_ii_buffer_merge(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
grn_id tid, ii_buffer_block *hits[], int nhits)
{
if (!try_in_place_packing(ctx, ii_buffer, tid, hits, nhits)) {
+ /* Merge hit blocks and reserve a buffer for packed data. */
size_t max_size = merge_hit_blocks(ctx, ii_buffer, hits, nhits);
if (ii_buffer->packed_buf &&
ii_buffer->packed_buf_size < ii_buffer->packed_len + max_size) {
@@ -7771,12 +10080,33 @@ grn_ii_buffer_merge(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
}
}
{
+ /* Pack postings into the current buffer. */
uint16_t nterm;
size_t packed_len;
buffer_term *bt;
- uint32_t *a = array_get(ctx, ii_buffer->ii, tid);
- buffer *term_buffer = get_term_buffer(ctx, ii_buffer);
- if (!term_buffer) { return; }
+ uint32_t *a;
+ buffer *term_buffer;
+
+ a = array_get(ctx, ii_buffer->ii, tid);
+ if (!a) {
+ DEFINE_NAME(ii_buffer->ii);
+ MERR("[ii][buffer][merge] failed to allocate an array: "
+ "<%.*s>: "
+ "<%u>",
+ name_size, name,
+ tid);
+ return;
+ }
+ term_buffer = get_term_buffer(ctx, ii_buffer);
+ if (!term_buffer) {
+ DEFINE_NAME(ii_buffer->ii);
+ MERR("[ii][buffer][merge] failed to allocate a term buffer: "
+ "<%.*s>: "
+ "<%u>",
+ name_size, name,
+ tid);
+ return;
+ }
nterm = term_buffer->header.nterms++;
bt = &term_buffer->terms[nterm];
a[0] = SEG2POS(ii_buffer->lseg,
@@ -7797,6 +10127,7 @@ grn_ii_buffer_merge(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
(ii_buffer->total_size * II_BUFFER_NTERMS_PER_BUFFER * 16)) {
grn_ii_buffer_chunk_flush(ctx, ii_buffer);
}
+ array_unref(ii_buffer->ii, tid);
}
}
}
@@ -7826,6 +10157,10 @@ grn_ii_buffer_open(grn_ctx *ctx, grn_ii *ii,
ii_buffer->packed_len = 0;
ii_buffer->packed_buf_size = 0;
ii_buffer->total_chunk_size = 0;
+ ii_buffer->values = NULL;
+ ii_buffer->nvalues = 0;
+ ii_buffer->max_nvalues = 0;
+ ii_buffer->last_rid = 0;
if (ii_buffer->counters) {
ii_buffer->block_buf = GRN_MALLOCN(grn_id, II_BUFFER_BLOCK_SIZE);
if (ii_buffer->block_buf) {
@@ -7834,15 +10169,17 @@ grn_ii_buffer_open(grn_ctx *ctx, grn_ii *ii,
ii_buffer->block_buf_size = II_BUFFER_BLOCK_SIZE;
ii_buffer->tmpfd = grn_mkstemp(ii_buffer->tmpfpath);
if (ii_buffer->tmpfd != -1) {
- grn_obj_flags flags;
- grn_table_get_info(ctx, ii->lexicon, &flags, NULL, NULL, NULL, NULL);
+ grn_table_flags flags;
+ grn_table_get_info(ctx, ii->lexicon, &flags, NULL, NULL, NULL,
+ NULL);
if ((flags & GRN_OBJ_TABLE_TYPE_MASK) == GRN_OBJ_TABLE_PAT_KEY) {
grn_pat_cache_enable(ctx, (grn_pat *)ii->lexicon,
PAT_CACHE_SIZE);
}
return ii_buffer;
} else {
- SERR("mkostemp");
+ SERR("failed grn_mkstemp(%s)",
+ ii_buffer->tmpfpath);
}
GRN_FREE(ii_buffer->block_buf);
}
@@ -7856,18 +10193,103 @@ grn_ii_buffer_open(grn_ctx *ctx, grn_ii *ii,
return NULL;
}
+static void
+ii_buffer_value_init(grn_ctx *ctx, ii_buffer_value *value)
+{
+ value->sid = 0;
+ value->weight = 0;
+ value->p = NULL;
+ value->len = 0;
+ value->buf = NULL;
+ value->cap = 0;
+}
+
+static void
+ii_buffer_value_fin(grn_ctx *ctx, ii_buffer_value *value)
+{
+ if (value->buf) {
+ GRN_FREE(value->buf);
+ }
+}
+
+/*
+ * ii_buffer_values_append appends a value to ii_buffer.
+ * This function deep-copies the value if need_copy == GRN_TRUE.
+ */
+static void
+ii_buffer_values_append(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
+ unsigned int sid, unsigned weight,
+ const char *p, uint32_t len, grn_bool need_copy)
+{
+ if (ii_buffer->nvalues == ii_buffer->max_nvalues) {
+ unsigned int i;
+ unsigned int new_max_nvalues = ii_buffer->max_nvalues * 2;
+ unsigned int new_size;
+ ii_buffer_value *new_values;
+ if (new_max_nvalues == 0) {
+ new_max_nvalues = 1;
+ }
+ new_size = new_max_nvalues * sizeof(ii_buffer_value);
+ new_values = (ii_buffer_value *)GRN_REALLOC(ii_buffer->values, new_size);
+ if (!new_values) {
+ return;
+ }
+ for (i = ii_buffer->max_nvalues; i < new_max_nvalues; i++) {
+ ii_buffer_value_init(ctx, &new_values[i]);
+ }
+ ii_buffer->values = new_values;
+ ii_buffer->max_nvalues = new_max_nvalues;
+ }
+
+ {
+ ii_buffer_value *value = &ii_buffer->values[ii_buffer->nvalues];
+ if (need_copy) {
+ if (len > value->cap) {
+ char *new_buf = (char *)GRN_REALLOC(value->buf, len);
+ if (!new_buf) {
+ return;
+ }
+ value->buf = new_buf;
+ value->cap = len;
+ }
+ grn_memcpy(value->buf, p, len);
+ p = value->buf;
+ }
+ value->sid = sid;
+ value->weight = weight;
+ value->p = p;
+ value->len = len;
+ ii_buffer->nvalues++;
+ }
+}
+
grn_rc
grn_ii_buffer_append(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
grn_id rid, unsigned int sid, grn_obj *value)
{
- grn_ii_buffer_tokenize(ctx, ii_buffer, rid, sid, 0,
- GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
+ if (rid != ii_buffer->last_rid) {
+ if (ii_buffer->last_rid) {
+ grn_ii_buffer_tokenize(ctx, ii_buffer, ii_buffer->last_rid);
+ }
+ ii_buffer->last_rid = rid;
+ }
+ ii_buffer_values_append(ctx, ii_buffer, sid, 0,
+ GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value),
+ GRN_TRUE);
return ctx->rc;
}
+/*
+ * grn_ii_buffer_commit completes tokenization and builds an inverted index
+ * from data in a temporary file.
+ */
grn_rc
grn_ii_buffer_commit(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
{
+ /* Tokenize the remaining values and free resources. */
+ if (ii_buffer->last_rid && ii_buffer->nvalues) {
+ grn_ii_buffer_tokenize(ctx, ii_buffer, ii_buffer->last_rid);
+ }
if (ii_buffer->block_pos) {
grn_ii_buffer_flush(ctx, ii_buffer);
}
@@ -7894,7 +10316,7 @@ grn_ii_buffer_commit(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
}
}
- GRN_LOG(ctx, GRN_LOG_NOTICE,
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
"nblocks=%d, update_buffer_size=%" GRN_FMT_INT64U,
ii_buffer->nblocks, ii_buffer->update_buffer_size);
@@ -7903,10 +10325,11 @@ grn_ii_buffer_commit(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
ii_buffer->tmpfpath,
O_RDONLY | GRN_OPEN_FLAG_BINARY);
if (ii_buffer->tmpfd == -1) {
- ERRNO_ERR("oepn");
+ ERRNO_ERR("failed to open path: <%s>", ii_buffer->tmpfpath);
return ctx->rc;
}
{
+ /* Fetch the first term of each block. */
uint32_t i;
for (i = 0; i < ii_buffer->nblocks; i++) {
grn_ii_buffer_fetch(ctx, ii_buffer, &ii_buffer->blocks[i]);
@@ -7921,6 +10344,10 @@ grn_ii_buffer_commit(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
NULL, 0, NULL, 0, 0, -1, II_BUFFER_ORDER);
if (tc) {
while ((tid = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
+ /*
+ * Find blocks which contain the current term.
+ * Then, merge the postings.
+ */
int nrests = 0;
int nhits = 0;
uint32_t i;
@@ -7942,11 +10369,18 @@ grn_ii_buffer_commit(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
}
}
datavec_fin(ctx, ii_buffer->data_vectors);
- GRN_LOG(ctx, GRN_LOG_NOTICE,
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
"tmpfile_size:%" GRN_FMT_INT64D " > total_chunk_size:%" GRN_FMT_SIZE,
ii_buffer->filepos, ii_buffer->total_chunk_size);
grn_close(ii_buffer->tmpfd);
- grn_unlink(ii_buffer->tmpfpath);
+ if (grn_unlink(ii_buffer->tmpfpath) == 0) {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[ii][buffer][commit] removed temporary path: <%s>",
+ ii_buffer->tmpfpath);
+ } else {
+ ERRNO_ERR("[ii][buffer][commit] failed to remove temporary path: <%s>",
+ ii_buffer->tmpfpath);
+ }
ii_buffer->tmpfd = -1;
return ctx->rc;
}
@@ -7955,8 +10389,9 @@ grn_rc
grn_ii_buffer_close(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
{
uint32_t i;
- grn_obj_flags flags;
- grn_table_get_info(ctx, ii_buffer->ii->lexicon, &flags, NULL, NULL, NULL, NULL);
+ grn_table_flags flags;
+ grn_table_get_info(ctx, ii_buffer->ii->lexicon, &flags, NULL, NULL, NULL,
+ NULL);
if ((flags & GRN_OBJ_TABLE_TYPE_MASK) == GRN_OBJ_TABLE_PAT_KEY) {
grn_pat_cache_disable(ctx, (grn_pat *)ii_buffer->ii->lexicon);
}
@@ -7965,7 +10400,14 @@ grn_ii_buffer_close(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
}
if (ii_buffer->tmpfd != -1) {
grn_close(ii_buffer->tmpfd);
- grn_unlink(ii_buffer->tmpfpath);
+ if (grn_unlink(ii_buffer->tmpfpath) == 0) {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[ii][buffer][close] removed temporary path: <%s>",
+ ii_buffer->tmpfpath);
+ } else {
+ ERRNO_ERR("[ii][buffer][close] failed to remove temporary path: <%s>",
+ ii_buffer->tmpfpath);
+ }
}
if (ii_buffer->block_buf) {
GRN_FREE(ii_buffer->block_buf);
@@ -7981,75 +10423,101 @@ grn_ii_buffer_close(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
}
GRN_FREE(ii_buffer->blocks);
}
+ if (ii_buffer->values) {
+ for (i = 0; i < ii_buffer->max_nvalues; i++) {
+ ii_buffer_value_fin(ctx, &ii_buffer->values[i]);
+ }
+ GRN_FREE(ii_buffer->values);
+ }
GRN_FREE(ii_buffer);
return ctx->rc;
}
+/*
+ * grn_ii_buffer_parse tokenizes values to be indexed.
+ *
+ * For each record of the target table, grn_ii_buffer_parse makes a list of
+ * target values and calls grn_ii_buffer_tokenize. To make a list of target
+ * values, ii_buffer_values_append is called for each value. Note that
+ * ii_buffer_values_append is called for each element for a vector.
+ */
static void
grn_ii_buffer_parse(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
grn_obj *target, int ncols, grn_obj **cols)
{
grn_table_cursor *tc;
- if ((tc = grn_table_cursor_open(ctx, target,
- NULL, 0, NULL, 0, 0, -1,
- GRN_CURSOR_BY_ID))) {
- grn_id rid;
- grn_obj rv;
- GRN_TEXT_INIT(&rv, 0);
- while ((rid = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
- int sid;
- grn_obj **col;
- for (sid = 1, col = cols; sid <= ncols; sid++, col++) {
- grn_obj_reinit_for(ctx, &rv, *col);
- if (GRN_OBJ_TABLEP(*col)) {
- grn_table_get_key2(ctx, *col, rid, &rv);
- } else {
- grn_obj_get_value(ctx, *col, rid, &rv);
- }
- switch (rv.header.type) {
- case GRN_BULK :
- grn_ii_buffer_tokenize(ctx, ii_buffer, rid, sid, 0,
- GRN_TEXT_VALUE(&rv), GRN_TEXT_LEN(&rv));
- break;
- case GRN_UVECTOR :
- {
- unsigned int i, size;
- unsigned int element_size;
-
- size = grn_uvector_size(ctx, &rv);
- element_size = grn_uvector_element_size(ctx, &rv);
- for (i = 0; i < size; i++) {
- grn_ii_buffer_tokenize(ctx, ii_buffer, rid, sid, 0,
- GRN_BULK_HEAD(&rv) + (element_size * i),
- element_size);
- }
+ grn_obj *vobjs;
+ if ((vobjs = GRN_MALLOCN(grn_obj, ncols))) {
+ int i;
+ for (i = 0; i < ncols; i++) {
+ GRN_TEXT_INIT(&vobjs[i], 0);
+ }
+ if ((tc = grn_table_cursor_open(ctx, target,
+ NULL, 0, NULL, 0, 0, -1,
+ GRN_CURSOR_BY_ID))) {
+ grn_id rid;
+ while ((rid = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
+ unsigned int j;
+ int sid;
+ grn_obj **col;
+ for (sid = 1, col = cols; sid <= ncols; sid++, col++) {
+ grn_obj *rv = &vobjs[sid - 1];
+ grn_obj_reinit_for(ctx, rv, *col);
+ if (GRN_OBJ_TABLEP(*col)) {
+ grn_table_get_key2(ctx, *col, rid, rv);
+ } else {
+ grn_obj_get_value(ctx, *col, rid, rv);
}
- break;
- case GRN_VECTOR :
- if (rv.u.v.body) {
- int i;
- int n_sections = rv.u.v.n_sections;
- grn_section *sections = rv.u.v.sections;
- const char *head = GRN_BULK_HEAD(rv.u.v.body);
- for (i = 0; i < n_sections; i++) {
- grn_section *section = sections + i;
- if (section->length == 0) {
- continue;
+ switch (rv->header.type) {
+ case GRN_BULK :
+ ii_buffer_values_append(ctx, ii_buffer, sid, 0,
+ GRN_TEXT_VALUE(rv), GRN_TEXT_LEN(rv),
+ GRN_FALSE);
+ break;
+ case GRN_UVECTOR :
+ {
+ unsigned int size;
+ unsigned int elem_size;
+ size = grn_uvector_size(ctx, rv);
+ elem_size = grn_uvector_element_size(ctx, rv);
+ for (j = 0; j < size; j++) {
+ ii_buffer_values_append(ctx, ii_buffer, sid, 0,
+ GRN_BULK_HEAD(rv) + (elem_size * j),
+ elem_size, GRN_FALSE);
}
- grn_ii_buffer_tokenize(ctx, ii_buffer, rid,
- sid, section->weight,
- head + section->offset, section->length);
}
+ break;
+ case GRN_VECTOR :
+ if (rv->u.v.body) {
+ int j;
+ int n_sections = rv->u.v.n_sections;
+ grn_section *sections = rv->u.v.sections;
+ const char *head = GRN_BULK_HEAD(rv->u.v.body);
+ for (j = 0; j < n_sections; j++) {
+ grn_section *section = sections + j;
+ if (section->length == 0) {
+ continue;
+ }
+ ii_buffer_values_append(ctx, ii_buffer, sid, section->weight,
+ head + section->offset,
+ section->length, GRN_FALSE);
+ }
+ }
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT,
+ "[index] invalid object assigned as value");
+ break;
}
- break;
- default :
- ERR(GRN_INVALID_ARGUMENT, "[index] invalid object assigned as value");
- break;
}
+ grn_ii_buffer_tokenize(ctx, ii_buffer, rid);
}
+ grn_table_cursor_close(ctx, tc);
}
- GRN_OBJ_FIN(ctx, &rv);
- grn_table_cursor_close(ctx, tc);
+ for (i = 0; i < ncols; i++) {
+ GRN_OBJ_FIN(ctx, &vobjs[i]);
+ }
+ GRN_FREE(vobjs);
}
}
@@ -8059,9 +10527,8 @@ grn_ii_build(grn_ctx *ctx, grn_ii *ii, uint64_t sparsity)
grn_ii_buffer *ii_buffer;
{
- grn_obj *data_table;
-
- data_table = grn_ctx_at(ctx, DB_OBJ(ii)->range);
+ /* Do nothing if there are no targets. */
+ grn_obj *data_table = grn_ctx_at(ctx, DB_OBJ(ii)->range);
if (!data_table) {
return ctx->rc;
}
@@ -8072,16 +10539,16 @@ grn_ii_build(grn_ctx *ctx, grn_ii *ii, uint64_t sparsity)
ii_buffer = grn_ii_buffer_open(ctx, ii, sparsity);
if (ii_buffer) {
- grn_id *s = ii->obj.source;
- if ((ii->obj.source_size) && s) {
+ grn_id *source = (grn_id *)ii->obj.source;
+ if (ii->obj.source_size && ii->obj.source) {
int ncols = ii->obj.source_size / sizeof(grn_id);
grn_obj **cols = GRN_MALLOCN(grn_obj *, ncols);
if (cols) {
int i;
for (i = 0; i < ncols; i++) {
- if (!(cols[i] = grn_ctx_at(ctx, s[i]))) { break; }
+ if (!(cols[i] = grn_ctx_at(ctx, source[i]))) { break; }
}
- if (i == ncols) {
+ if (i == ncols) { /* All the source columns are available. */
grn_obj *target = cols[0];
if (!GRN_OBJ_TABLEP(target)) {
target = grn_ctx_at(ctx, target->header.domain);
@@ -8104,3 +10571,2263 @@ grn_ii_build(grn_ctx *ctx, grn_ii *ii, uint64_t sparsity)
}
return ctx->rc;
}
+
+/*
+ * ==========================================================================
+ * The following part provides constants, structures and functions for static
+ * indexing.
+ * ==========================================================================
+ */
+
+#define GRN_II_BUILDER_BUFFER_CHUNK_SIZE (S_CHUNK >> 2)
+
+#define GRN_II_BUILDER_MAX_LEXICON_CACHE_SIZE (1 << 24)
+
+#define GRN_II_BUILDER_MIN_BLOCK_THRESHOLD 1
+#define GRN_II_BUILDER_MAX_BLOCK_THRESHOLD (1 << 28)
+
+#define GRN_II_BUILDER_MIN_FILE_BUF_SIZE (1 << 12)
+#define GRN_II_BUILDER_MAX_FILE_BUF_SIZE (1 << 30)
+
+#define GRN_II_BUILDER_MIN_BLOCK_BUF_SIZE (1 << 12)
+#define GRN_II_BUILDER_MAX_BLOCK_BUF_SIZE (1 << 30)
+
+#define GRN_II_BUILDER_MIN_CHUNK_THRESHOLD 1
+#define GRN_II_BUILDER_MAX_CHUNK_THRESHOLD (1 << 28)
+
+#define GRN_II_BUILDER_MIN_BUFFER_MAX_N_TERMS 1
+#define GRN_II_BUILDER_MAX_BUFFER_MAX_N_TERMS \
+ ((S_SEGMENT - sizeof(buffer_header)) / sizeof(buffer_term))
+
+struct grn_ii_builder_options {
+ uint32_t lexicon_cache_size; /* Cache size of temporary lexicon */
+ /* A block is flushed if builder->n reaches this value. */
+ uint32_t block_threshold;
+ uint32_t file_buf_size; /* Buffer size for buffered output */
+ uint32_t block_buf_size; /* Buffer size for buffered input */
+ /* A chunk is flushed if chunk->n reaches this value. */
+ uint32_t chunk_threshold;
+ uint32_t buffer_max_n_terms; /* Maximum number of terms in each buffer */
+};
+
+static const grn_ii_builder_options grn_ii_builder_default_options = {
+ 0x80000, /* lexicon_cache_size */
+ 0x4000000, /* block_threshold */
+ 0x10000, /* file_buf_size */
+ 0x10000, /* block_buf_size */
+ 0x1000, /* chunk_threshold */
+ 0x3000, /* buffer_max_n_terms */
+};
+
+/* grn_ii_builder_options_init fills options with the default options. */
+void
+grn_ii_builder_options_init(grn_ii_builder_options *options)
+{
+ *options = grn_ii_builder_default_options;
+}
+
+/* grn_ii_builder_options_fix fixes out-of-range options. */
+static void
+grn_ii_builder_options_fix(grn_ii_builder_options *options)
+{
+ if (options->lexicon_cache_size > GRN_II_BUILDER_MAX_LEXICON_CACHE_SIZE) {
+ options->lexicon_cache_size = GRN_II_BUILDER_MAX_LEXICON_CACHE_SIZE;
+ }
+
+ if (options->block_threshold < GRN_II_BUILDER_MIN_BLOCK_THRESHOLD) {
+ options->block_threshold = GRN_II_BUILDER_MIN_BLOCK_THRESHOLD;
+ }
+ if (options->block_threshold > GRN_II_BUILDER_MAX_BLOCK_THRESHOLD) {
+ options->block_threshold = GRN_II_BUILDER_MAX_BLOCK_THRESHOLD;
+ }
+
+ if (options->file_buf_size < GRN_II_BUILDER_MIN_FILE_BUF_SIZE) {
+ options->file_buf_size = GRN_II_BUILDER_MIN_FILE_BUF_SIZE;
+ }
+ if (options->file_buf_size > GRN_II_BUILDER_MAX_FILE_BUF_SIZE) {
+ options->file_buf_size = GRN_II_BUILDER_MAX_FILE_BUF_SIZE;
+ }
+
+ if (options->block_buf_size < GRN_II_BUILDER_MIN_BLOCK_BUF_SIZE) {
+ options->block_buf_size = GRN_II_BUILDER_MIN_BLOCK_BUF_SIZE;
+ }
+ if (options->block_buf_size > GRN_II_BUILDER_MAX_BLOCK_BUF_SIZE) {
+ options->block_buf_size = GRN_II_BUILDER_MAX_BLOCK_BUF_SIZE;
+ }
+
+ if (options->chunk_threshold < GRN_II_BUILDER_MIN_CHUNK_THRESHOLD) {
+ options->chunk_threshold = GRN_II_BUILDER_MIN_CHUNK_THRESHOLD;
+ }
+ if (options->chunk_threshold > GRN_II_BUILDER_MAX_CHUNK_THRESHOLD) {
+ options->chunk_threshold = GRN_II_BUILDER_MAX_CHUNK_THRESHOLD;
+ }
+
+ if (options->buffer_max_n_terms < GRN_II_BUILDER_MIN_BUFFER_MAX_N_TERMS) {
+ options->buffer_max_n_terms = GRN_II_BUILDER_MIN_BUFFER_MAX_N_TERMS;
+ }
+ if (options->buffer_max_n_terms > GRN_II_BUILDER_MAX_BUFFER_MAX_N_TERMS) {
+ options->buffer_max_n_terms = GRN_II_BUILDER_MAX_BUFFER_MAX_N_TERMS;
+ }
+}
+
+#define GRN_II_BUILDER_TERM_INPLACE_SIZE\
+ (sizeof(grn_ii_builder_term) - (uintptr_t)&((grn_ii_builder_term *)0)->dummy)
+
+typedef struct {
+ grn_id rid; /* Last record ID */
+ uint32_t sid; /* Last section ID */
+ /* Last position (GRN_OBJ_WITH_POSITION) or frequency. */
+ uint32_t pos_or_freq;
+ uint32_t offset; /* Buffer write offset */
+ uint32_t size; /* Buffer size */
+ uint32_t dummy; /* Padding */
+ uint8_t *buf; /* Buffer (to be freed) */
+} grn_ii_builder_term;
+
+/* grn_ii_builder_term_is_inplace returns whether a term buffer is inplace. */
+inline static grn_bool
+grn_ii_builder_term_is_inplace(grn_ii_builder_term *term)
+{
+ return term->size == GRN_II_BUILDER_TERM_INPLACE_SIZE;
+}
+
+/* grn_ii_builder_term_get_buf returns a term buffer. */
+inline static uint8_t *
+grn_ii_builder_term_get_buf(grn_ii_builder_term *term)
+{
+ if (grn_ii_builder_term_is_inplace(term)) {
+ return (uint8_t *)&term->dummy;
+ } else {
+ return term->buf;
+ }
+}
+
+/*
+ * grn_ii_builder_term_init initializes a term. Note that an initialized term
+ * must be finalized by grn_ii_builder_term_fin.
+ */
+static void
+grn_ii_builder_term_init(grn_ctx *ctx, grn_ii_builder_term *term)
+{
+ term->rid = GRN_ID_NIL;
+ term->sid = 0;
+ term->pos_or_freq = 0;
+ term->offset = 0;
+ term->size = GRN_II_BUILDER_TERM_INPLACE_SIZE;
+}
+
+/* grn_ii_builder_term_fin finalizes a term. */
+static void
+grn_ii_builder_term_fin(grn_ctx *ctx, grn_ii_builder_term *term)
+{
+ if (!grn_ii_builder_term_is_inplace(term)) {
+ GRN_FREE(term->buf);
+ }
+}
+
+/* grn_ii_builder_term_reinit reinitializes a term. */
+static void
+grn_ii_builder_term_reinit(grn_ctx *ctx, grn_ii_builder_term *term)
+{
+ grn_ii_builder_term_fin(ctx, term);
+ grn_ii_builder_term_init(ctx, term);
+}
+
+/* grn_ii_builder_term_extend extends a term buffer. */
+static grn_rc
+grn_ii_builder_term_extend(grn_ctx *ctx, grn_ii_builder_term *term)
+{
+ uint8_t *buf;
+ uint32_t size = term->size * 2;
+ if (grn_ii_builder_term_is_inplace(term)) {
+ buf = (uint8_t *)GRN_MALLOC(size);
+ if (!buf) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for term buffer: size = %u", size);
+ return ctx->rc;
+ }
+ grn_memcpy(buf, &term->dummy, term->offset);
+ } else {
+ buf = (uint8_t *)GRN_REALLOC(term->buf, size);
+ if (!buf) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to reallocate memory for term buffer: size = %u", size);
+ return ctx->rc;
+ }
+ }
+ term->buf = buf;
+ term->size = size;
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_term_append appends an integer to a term buffer. */
+inline static grn_rc
+grn_ii_builder_term_append(grn_ctx *ctx, grn_ii_builder_term *term,
+ uint64_t value)
+{
+ uint8_t *p;
+ if (value < (uint64_t)1 << 5) {
+ if (term->offset + 1 > term->size) {
+ grn_rc rc = grn_ii_builder_term_extend(ctx, term);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ p = grn_ii_builder_term_get_buf(term) + term->offset;
+ p[0] = (uint8_t)value;
+ term->offset++;
+ return GRN_SUCCESS;
+ } else if (value < (uint64_t)1 << 13) {
+ if (term->offset + 2 > term->size) {
+ grn_rc rc = grn_ii_builder_term_extend(ctx, term);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ p = grn_ii_builder_term_get_buf(term) + term->offset;
+ p[0] = (uint8_t)((value & 0x1f) | (1 << 5));
+ p[1] = (uint8_t)(value >> 5);
+ term->offset += 2;
+ return GRN_SUCCESS;
+ } else {
+ uint8_t i, n;
+ if (value < (uint64_t)1 << 21) {
+ n = 3;
+ } else if (value < (uint64_t)1 << 29) {
+ n = 4;
+ } else if (value < (uint64_t)1 << 37) {
+ n = 5;
+ } else if (value < (uint64_t)1 << 45) {
+ n = 6;
+ } else if (value < (uint64_t)1 << 53) {
+ n = 7;
+ } else {
+ n = 8;
+ }
+ if (term->offset + n > term->size) {
+ grn_rc rc = grn_ii_builder_term_extend(ctx, term);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ p = grn_ii_builder_term_get_buf(term) + term->offset;
+ p[0] = (uint8_t)(value & 0x1f) | ((n - 1) << 5);
+ value >>= 5;
+ for (i = 1; i < n; i++) {
+ p[i] = (uint8_t)value;
+ value >>= 8;
+ }
+ term->offset += n;
+ return GRN_SUCCESS;
+ }
+}
+
+typedef struct {
+ uint64_t offset; /* File offset */
+ uint32_t rest; /* Remaining size */
+ uint8_t *buf; /* Buffer (to be freed) */
+ uint8_t *cur; /* Current pointer */
+ uint8_t *end; /* End pointer */
+ uint32_t tid; /* Term ID */
+} grn_ii_builder_block;
+
+/*
+ * grn_ii_builder_block_init initializes a block. Note that an initialized
+ * block must be finalized by grn_ii_builder_block_fin.
+ */
+static void
+grn_ii_builder_block_init(grn_ctx *ctx, grn_ii_builder_block *block)
+{
+ block->offset = 0;
+ block->rest = 0;
+ block->buf = NULL;
+ block->cur = NULL;
+ block->end = NULL;
+ block->tid = GRN_ID_NIL;
+}
+
+/* grn_ii_builder_block_fin finalizes a block. */
+static void
+grn_ii_builder_block_fin(grn_ctx *ctx, grn_ii_builder_block *block)
+{
+ if (block->buf) {
+ GRN_FREE(block->buf);
+ }
+}
+
+/*
+ * grn_ii_builder_block_next reads the next integer. Note that this function
+ * returns GRN_END_OF_DATA if it reaches the end of a block.
+ */
+inline static grn_rc
+grn_ii_builder_block_next(grn_ctx *ctx, grn_ii_builder_block *block,
+ uint64_t *value)
+{
+ uint8_t n;
+ if (block->cur == block->end) {
+ return GRN_END_OF_DATA;
+ }
+ n = (*block->cur >> 5) + 1;
+ if (n > block->end - block->cur) {
+ return GRN_END_OF_DATA;
+ }
+ *value = 0;
+ switch (n) {
+ case 8 :
+ *value |= (uint64_t)block->cur[7] << 53;
+ case 7 :
+ *value |= (uint64_t)block->cur[6] << 45;
+ case 6 :
+ *value |= (uint64_t)block->cur[5] << 37;
+ case 5 :
+ *value |= (uint64_t)block->cur[4] << 29;
+ case 4 :
+ *value |= (uint64_t)block->cur[3] << 21;
+ case 3 :
+ *value |= (uint64_t)block->cur[2] << 13;
+ case 2 :
+ *value |= (uint64_t)block->cur[1] << 5;
+ case 1 :
+ *value |= block->cur[0] & 0x1f;
+ break;
+ }
+ block->cur += n;
+ return GRN_SUCCESS;
+}
+
+typedef struct {
+ grn_ii *ii; /* Inverted index */
+ uint32_t buf_id; /* Buffer ID */
+ uint32_t buf_seg_id; /* Buffer segment ID */
+ buffer *buf; /* Buffer (to be unreferenced) */
+ uint32_t chunk_id; /* Chunk ID */
+ uint32_t chunk_seg_id; /* Chunk segment ID */
+ uint8_t *chunk; /* Chunk (to be unreferenced) */
+ uint32_t chunk_offset; /* Chunk write position */
+ uint32_t chunk_size; /* Chunk size */
+} grn_ii_builder_buffer;
+
+/*
+ * grn_ii_builder_buffer_init initializes a buffer. Note that a buffer must be
+ * finalized by grn_ii_builder_buffer_fin.
+ */
+static void
+grn_ii_builder_buffer_init(grn_ctx *ctx, grn_ii_builder_buffer *buf,
+ grn_ii *ii)
+{
+ buf->ii = ii;
+ buf->buf_id = 0;
+ buf->buf_seg_id = 0;
+ buf->buf = NULL;
+ buf->chunk_id = 0;
+ buf->chunk_seg_id = 0;
+ buf->chunk = NULL;
+ buf->chunk_offset = 0;
+ buf->chunk_size = 0;
+}
+
+/* grn_ii_builder_buffer_fin finalizes a buffer. */
+static void
+grn_ii_builder_buffer_fin(grn_ctx *ctx, grn_ii_builder_buffer *buf)
+{
+ if (buf->buf) {
+ GRN_IO_SEG_UNREF(buf->ii->seg, buf->buf_seg_id);
+ }
+ if (buf->chunk) {
+ GRN_IO_SEG_UNREF(buf->ii->chunk, buf->chunk_seg_id);
+ }
+}
+
+/* grn_ii_builder_buffer_is_assigned returns whether a buffer is assigned. */
+static grn_bool
+grn_ii_builder_buffer_is_assigned(grn_ctx *ctx, grn_ii_builder_buffer *buf)
+{
+ return buf->buf != NULL;
+}
+
+/* grn_ii_builder_buffer_assign assigns a buffer. */
+static grn_rc
+grn_ii_builder_buffer_assign(grn_ctx *ctx, grn_ii_builder_buffer *buf,
+ size_t min_chunk_size)
+{
+ void *seg;
+ size_t chunk_size;
+ grn_rc rc;
+
+ /* Create a buffer. */
+ buf->buf_id = GRN_II_PSEG_NOT_ASSIGNED;
+ rc = buffer_segment_new(ctx, buf->ii, &buf->buf_id);
+ if (rc != GRN_SUCCESS) {
+ if (ctx->rc != GRN_SUCCESS) {
+ ERR(rc, "failed to allocate segment for buffer");
+ }
+ return rc;
+ }
+ buf->buf_seg_id = buf->ii->header->binfo[buf->buf_id];
+ GRN_IO_SEG_REF(buf->ii->seg, buf->buf_seg_id, seg);
+ if (!seg) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_UNKNOWN_ERROR,
+ "failed access buffer segment: buf_id = %u, seg_id = %u",
+ buf->buf_id, buf->buf_seg_id);
+ }
+ return ctx->rc;
+ }
+ buf->buf = (buffer *)seg;
+
+ /* Create a chunk. */
+ chunk_size = GRN_II_BUILDER_BUFFER_CHUNK_SIZE;
+ while (chunk_size < min_chunk_size) {
+ chunk_size *= 2;
+ }
+ rc = chunk_new(ctx, buf->ii, &buf->chunk_id, chunk_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf->chunk_seg_id = buf->chunk_id >> GRN_II_N_CHUNK_VARIATION;
+ GRN_IO_SEG_REF(buf->ii->chunk, buf->chunk_seg_id, seg);
+ if (!seg) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_UNKNOWN_ERROR,
+ "failed access chunk segment: chunk_id = %u, seg_id = %u",
+ buf->chunk_id, buf->chunk_seg_id);
+ }
+ return ctx->rc;
+ }
+ buf->chunk = (uint8_t *)seg;
+ buf->chunk += (buf->chunk_id & ((1 << GRN_II_N_CHUNK_VARIATION) - 1)) <<
+ GRN_II_W_LEAST_CHUNK;
+ buf->chunk_offset = 0;
+ buf->chunk_size = chunk_size;
+
+ buf->buf->header.chunk = buf->chunk_id;
+ buf->buf->header.chunk_size = chunk_size;
+ buf->buf->header.buffer_free = S_SEGMENT - sizeof(buffer_header);
+ buf->buf->header.nterms = 0;
+ buf->buf->header.nterms_void = 0;
+ buf->ii->header->total_chunk_size += chunk_size;
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_buffer_flush flushes a buffer. */
+static grn_rc
+grn_ii_builder_buffer_flush(grn_ctx *ctx, grn_ii_builder_buffer *buf)
+{
+ grn_ii *ii;
+
+ buf->buf->header.buffer_free = S_SEGMENT - sizeof(buffer_header) -
+ buf->buf->header.nterms * sizeof(buffer_term);
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "n_terms = %u, chunk_offset = %u, chunk_size = %u, total = %"
+ GRN_FMT_INT64U "KB",
+ buf->buf->header.nterms,
+ buf->chunk_offset,
+ buf->buf->header.chunk_size,
+ buf->ii->header->total_chunk_size >> 10);
+
+ ii = buf->ii;
+ grn_ii_builder_buffer_fin(ctx, buf);
+ grn_ii_builder_buffer_init(ctx, buf, ii);
+ return GRN_SUCCESS;
+}
+
+typedef struct {
+ grn_id tid; /* Term ID */
+ uint32_t n; /* Number of integers in buffers */
+ grn_id rid; /* Record ID */
+ uint32_t rid_gap; /* Record ID gap */
+ uint64_t pos_sum; /* Sum of position gaps */
+
+ uint32_t offset; /* Write offset */
+ uint32_t size; /* Buffer size */
+ grn_id *rid_buf; /* Buffer for record IDs (to be freed) */
+ uint32_t *sid_buf; /* Buffer for section IDs (to be freed) */
+ uint32_t *freq_buf; /* Buffer for frequencies (to be freed) */
+ uint32_t *weight_buf; /* Buffer for weights (to be freed) */
+
+ uint32_t pos_offset; /* Write offset of pos_buf */
+ uint32_t pos_size; /* Buffer size of pos_buf */
+ uint32_t *pos_buf; /* Buffer for positions (to be freed) */
+
+ size_t enc_offset; /* Write offset of enc_buf */
+ size_t enc_size; /* Buffer size of enc_buf */
+ uint8_t *enc_buf; /* Buffer for encoded data (to be freed) */
+} grn_ii_builder_chunk;
+
+/*
+ * grn_ii_builder_chunk_init initializes a chunk. Note that an initialized
+ * chunk must be finalized by grn_ii_builder_chunk_fin.
+ */
+static void
+grn_ii_builder_chunk_init(grn_ctx *ctx, grn_ii_builder_chunk *chunk)
+{
+ chunk->tid = GRN_ID_NIL;
+ chunk->n = 0;
+ chunk->rid = GRN_ID_NIL;
+ chunk->rid_gap = 0;
+ chunk->pos_sum = 0;
+
+ chunk->offset = 0;
+ chunk->size = 0;
+ chunk->rid_buf = NULL;
+ chunk->sid_buf = NULL;
+ chunk->freq_buf = NULL;
+ chunk->weight_buf = NULL;
+
+ chunk->pos_offset = 0;
+ chunk->pos_size = 0;
+ chunk->pos_buf = NULL;
+
+ chunk->enc_offset = 0;
+ chunk->enc_size = 0;
+ chunk->enc_buf = NULL;
+}
+
+/* grn_ii_builder_chunk_fin finalizes a chunk. */
+static void
+grn_ii_builder_chunk_fin(grn_ctx *ctx, grn_ii_builder_chunk *chunk)
+{
+ if (chunk->enc_buf) {
+ GRN_FREE(chunk->enc_buf);
+ }
+ if (chunk->pos_buf) {
+ GRN_FREE(chunk->pos_buf);
+ }
+ if (chunk->weight_buf) {
+ GRN_FREE(chunk->weight_buf);
+ }
+ if (chunk->freq_buf) {
+ GRN_FREE(chunk->freq_buf);
+ }
+ if (chunk->sid_buf) {
+ GRN_FREE(chunk->sid_buf);
+ }
+ if (chunk->rid_buf) {
+ GRN_FREE(chunk->rid_buf);
+ }
+}
+
+/*
+ * grn_ii_builder_chunk_clear clears stats except rid and buffers except
+ * enc_buf.
+ */
+static void
+grn_ii_builder_chunk_clear(grn_ctx *ctx, grn_ii_builder_chunk *chunk)
+{
+ chunk->n = 0;
+ chunk->rid_gap = 0;
+ chunk->pos_sum = 0;
+ chunk->offset = 0;
+ chunk->pos_offset = 0;
+}
+
+/*
+ * grn_ii_builder_chunk_extend_bufs extends buffers except pos_buf and enc_buf.
+ */
+static grn_rc
+grn_ii_builder_chunk_extend_bufs(grn_ctx *ctx, grn_ii_builder_chunk *chunk,
+ uint32_t ii_flags)
+{
+ uint32_t *buf, size = chunk->size ? chunk->size * 2 : 1;
+ size_t n_bytes = size * sizeof(uint32_t);
+
+ buf = (uint32_t *)GRN_REALLOC(chunk->rid_buf, n_bytes);
+ if (!buf) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for record IDs: n_bytes = %" GRN_FMT_SIZE,
+ n_bytes);
+ return ctx->rc;
+ }
+ chunk->rid_buf = buf;
+
+ if (ii_flags & GRN_OBJ_WITH_SECTION) {
+ buf = (uint32_t *)GRN_REALLOC(chunk->sid_buf, n_bytes);
+ if (!buf) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for section IDs:"
+ " n_bytes = %" GRN_FMT_SIZE,
+ n_bytes);
+ return ctx->rc;
+ }
+ chunk->sid_buf = buf;
+ }
+
+ buf = (uint32_t *)GRN_REALLOC(chunk->freq_buf, n_bytes);
+ if (!buf) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for frequencies: n_bytes = %" GRN_FMT_SIZE,
+ n_bytes);
+ return ctx->rc;
+ }
+ chunk->freq_buf = buf;
+
+ if (ii_flags & GRN_OBJ_WITH_WEIGHT) {
+ buf = (uint32_t *)GRN_REALLOC(chunk->weight_buf, n_bytes);
+ if (!buf) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for weights: n_bytes = %" GRN_FMT_SIZE,
+ n_bytes);
+ return ctx->rc;
+ }
+ chunk->weight_buf = buf;
+ }
+
+ chunk->size = size;
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_chunk_extend_pos_buf extends pos_buf. */
+static grn_rc
+grn_ii_builder_chunk_extend_pos_buf(grn_ctx *ctx, grn_ii_builder_chunk *chunk)
+{
+ uint32_t *buf, size = chunk->pos_size ? chunk->pos_size * 2 : 1;
+ size_t n_bytes = size * sizeof(uint32_t);
+ buf = (uint32_t *)GRN_REALLOC(chunk->pos_buf, n_bytes);
+ if (!buf) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for positions: n_bytes = %" GRN_FMT_SIZE,
+ n_bytes);
+ return ctx->rc;
+ }
+ chunk->pos_buf = buf;
+ chunk->pos_size = size;
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ii_builder_chunk_reserve_enc_buf estimates a size that is enough to
+ * store encoded data and allocates memory to enc_buf.
+ */
+static grn_rc
+grn_ii_builder_chunk_reserve_enc_buf(grn_ctx *ctx, grn_ii_builder_chunk *chunk,
+ uint32_t n_cinfos)
+{
+ size_t rich_size = (chunk->n + 4) * sizeof(uint32_t) +
+ n_cinfos * sizeof(chunk_info);
+ if (chunk->enc_size < rich_size) {
+ size_t size = chunk->enc_size ? chunk->enc_size * 2 : 1;
+ uint8_t *buf;
+ while (size < rich_size) {
+ size *= 2;
+ }
+ buf = GRN_REALLOC(chunk->enc_buf, size);
+ if (!buf) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for encoding: size = %" GRN_FMT_SIZE,
+ size);
+ return ctx->rc;
+ }
+ chunk->enc_buf = buf;
+ chunk->enc_size = size;
+ }
+ chunk->enc_offset = 0;
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_chunk_encode encodes a chunk buffer. */
+static void
+grn_ii_builder_chunk_encode_buf(grn_ctx *ctx, grn_ii_builder_chunk *chunk,
+ uint32_t *values, uint32_t n_values,
+ grn_bool use_p_enc)
+{
+ uint8_t *p = chunk->enc_buf + chunk->enc_offset;
+ uint32_t i;
+ if (use_p_enc) {
+ uint8_t freq[33];
+ uint32_t buf[UNIT_SIZE];
+ while (n_values >= UNIT_SIZE) {
+ memset(freq, 0, 33);
+ for (i = 0; i < UNIT_SIZE; i++) {
+ buf[i] = values[i];
+ if (buf[i]) {
+ uint32_t w;
+ GRN_BIT_SCAN_REV(buf[i], w);
+ freq[w + 1]++;
+ } else {
+ freq[0]++;
+ }
+ }
+ p = pack(buf, UNIT_SIZE, freq, p);
+ values += UNIT_SIZE;
+ n_values -= UNIT_SIZE;
+ }
+ if (n_values) {
+ memset(freq, 0, 33);
+ for (i = 0; i < n_values; i++) {
+ buf[i] = values[i];
+ if (buf[i]) {
+ uint32_t w;
+ GRN_BIT_SCAN_REV(buf[i], w);
+ freq[w + 1]++;
+ } else {
+ freq[0]++;
+ }
+ }
+ p = pack(buf, n_values, freq, p);
+ }
+ } else {
+ for (i = 0; i < n_values; i++) {
+ GRN_B_ENC(values[i], p);
+ }
+ }
+ chunk->enc_offset = p - chunk->enc_buf;
+}
+
+/* grn_ii_builder_chunk_encode encodes a chunk. */
+static grn_rc
+grn_ii_builder_chunk_encode(grn_ctx *ctx, grn_ii_builder_chunk *chunk,
+ chunk_info *cinfos, uint32_t n_cinfos)
+{
+ grn_rc rc;
+ uint8_t *p;
+ uint8_t shift = 0, use_p_enc_flags = 0;
+ uint8_t rid_use_p_enc, rest_use_p_enc, pos_use_p_enc = 0;
+
+ /* Choose an encoding. */
+ rid_use_p_enc = chunk->offset >= 16 && chunk->offset > (chunk->rid >> 8);
+ use_p_enc_flags |= rid_use_p_enc << shift++;
+ rest_use_p_enc = chunk->offset >= 3;
+ if (chunk->sid_buf) {
+ use_p_enc_flags |= rest_use_p_enc << shift++;
+ }
+ use_p_enc_flags |= rest_use_p_enc << shift++;
+ if (chunk->weight_buf) {
+ use_p_enc_flags |= rest_use_p_enc << shift++;
+ }
+ if (chunk->pos_buf) {
+ pos_use_p_enc = chunk->pos_offset >= 32 &&
+ chunk->pos_offset > (chunk->pos_sum >> 13);
+ use_p_enc_flags |= pos_use_p_enc << shift++;
+ }
+
+ rc = grn_ii_builder_chunk_reserve_enc_buf(ctx, chunk, n_cinfos);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ /* Encode a header. */
+ p = chunk->enc_buf;
+ if (n_cinfos) {
+ uint32_t i;
+ GRN_B_ENC(n_cinfos, p);
+ for (i = 0; i < n_cinfos; i++) {
+ GRN_B_ENC(cinfos[i].segno, p);
+ GRN_B_ENC(cinfos[i].size, p);
+ GRN_B_ENC(cinfos[i].dgap, p);
+ }
+ }
+ if (use_p_enc_flags) {
+ GRN_B_ENC(use_p_enc_flags << 1, p);
+ GRN_B_ENC(chunk->offset, p);
+ if (chunk->pos_buf) {
+ GRN_B_ENC(chunk->pos_offset - chunk->offset, p);
+ }
+ } else {
+ GRN_B_ENC((chunk->offset << 1) | 1, p);
+ }
+ chunk->enc_offset = p - chunk->enc_buf;
+
+ /* Encode a body. */
+ grn_ii_builder_chunk_encode_buf(ctx, chunk, chunk->rid_buf, chunk->offset,
+ rid_use_p_enc);
+ if (chunk->sid_buf) {
+ grn_ii_builder_chunk_encode_buf(ctx, chunk, chunk->sid_buf, chunk->offset,
+ rest_use_p_enc);
+ }
+ grn_ii_builder_chunk_encode_buf(ctx, chunk, chunk->freq_buf, chunk->offset,
+ rest_use_p_enc);
+ if (chunk->weight_buf) {
+ grn_ii_builder_chunk_encode_buf(ctx, chunk, chunk->weight_buf,
+ chunk->offset, rest_use_p_enc);
+ }
+ if (chunk->pos_buf) {
+ grn_ii_builder_chunk_encode_buf(ctx, chunk, chunk->pos_buf,
+ chunk->pos_offset, pos_use_p_enc);
+ }
+
+ return GRN_SUCCESS;
+}
+
+typedef struct {
+ grn_ii *ii; /* Building inverted index */
+ grn_ii_builder_options options; /* Options */
+
+ grn_obj *src_table; /* Source table */
+ grn_obj **srcs; /* Source columns (to be freed) */
+ uint32_t n_srcs; /* Number of source columns */
+ uint8_t sid_bits; /* Number of bits for section ID */
+ uint64_t sid_mask; /* Mask bits for section ID */
+
+ grn_obj *lexicon; /* Block lexicon (to be closed) */
+ grn_obj *tokenizer; /* Lexicon's tokenizer */
+ grn_obj *normalizer; /* Lexicon's normalzier */
+
+ uint32_t n; /* Number of integers appended to the current block */
+ grn_id rid; /* Record ID */
+ uint32_t sid; /* Section ID */
+ uint32_t pos; /* Position */
+
+ grn_ii_builder_term *terms; /* Terms (to be freed) */
+ uint32_t n_terms; /* Number of distinct terms */
+ uint32_t max_n_terms; /* Maximum number of distinct terms */
+ uint32_t terms_size; /* Buffer size of terms */
+
+ /* A temporary file to save blocks. */
+ char path[PATH_MAX]; /* File path */
+ int fd; /* File descriptor (to be closed) */
+ uint8_t *file_buf; /* File buffer for buffered output (to be freed) */
+ uint32_t file_buf_offset; /* File buffer write offset */
+
+ grn_ii_builder_block *blocks; /* Blocks (to be freed) */
+ uint32_t n_blocks; /* Number of blocks */
+ uint32_t blocks_size; /* Buffer size of blocks */
+
+ grn_ii_builder_buffer buf; /* Buffer (to be finalized) */
+ grn_ii_builder_chunk chunk; /* Chunk (to be finalized) */
+
+ uint32_t df; /* Document frequency (number of sections) */
+ chunk_info *cinfos; /* Chunk headers (to be freed) */
+ uint32_t n_cinfos; /* Number of chunks */
+ uint32_t cinfos_size; /* Size of cinfos */
+} grn_ii_builder;
+
+/*
+ * grn_ii_builder_init initializes a builder. Note that an initialized builder
+ * must be finalized by grn_ii_builder_fin.
+ */
+static grn_rc
+grn_ii_builder_init(grn_ctx *ctx, grn_ii_builder *builder,
+ grn_ii *ii, const grn_ii_builder_options *options)
+{
+ builder->ii = ii;
+ builder->options = *options;
+ if (grn_ii_builder_block_threshold_force > 0) {
+ builder->options.block_threshold = grn_ii_builder_block_threshold_force;
+ }
+ grn_ii_builder_options_fix(&builder->options);
+
+ builder->src_table = NULL;
+ builder->srcs = NULL;
+ builder->n_srcs = 0;
+ builder->sid_bits = 0;
+ builder->sid_mask = 0;
+
+ builder->lexicon = NULL;
+ builder->tokenizer = NULL;
+ builder->normalizer = NULL;
+
+ builder->n = 0;
+ builder->rid = GRN_ID_NIL;
+ builder->sid = 0;
+ builder->pos = 0;
+
+ builder->terms = NULL;
+ builder->n_terms = 0;
+ builder->max_n_terms = 0;
+ builder->terms_size = 0;
+
+ builder->path[0] = '\0';
+ builder->fd = -1;
+ builder->file_buf = NULL;
+ builder->file_buf_offset = 0;
+
+ builder->blocks = NULL;
+ builder->n_blocks = 0;
+ builder->blocks_size = 0;
+
+ grn_ii_builder_buffer_init(ctx, &builder->buf, ii);
+ grn_ii_builder_chunk_init(ctx, &builder->chunk);
+
+ builder->df = 0;
+ builder->cinfos = NULL;
+ builder->n_cinfos = 0;
+ builder->cinfos_size = 0;
+
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_fin_terms finalizes terms. */
+static void
+grn_ii_builder_fin_terms(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ if (builder->terms) {
+ uint32_t i;
+ for (i = 0; i < builder->max_n_terms; i++) {
+ grn_ii_builder_term_fin(ctx, &builder->terms[i]);
+ }
+ GRN_FREE(builder->terms);
+
+ /* To avoid double finalization. */
+ builder->terms = NULL;
+ }
+}
+
+/* grn_ii_builder_fin finalizes a builder. */
+static grn_rc
+grn_ii_builder_fin(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ if (builder->cinfos) {
+ GRN_FREE(builder->cinfos);
+ }
+ grn_ii_builder_chunk_fin(ctx, &builder->chunk);
+ grn_ii_builder_buffer_fin(ctx, &builder->buf);
+ if (builder->blocks) {
+ uint32_t i;
+ for (i = 0; i < builder->n_blocks; i++) {
+ grn_ii_builder_block_fin(ctx, &builder->blocks[i]);
+ }
+ GRN_FREE(builder->blocks);
+ }
+ if (builder->file_buf) {
+ GRN_FREE(builder->file_buf);
+ }
+ if (builder->fd != -1) {
+ grn_close(builder->fd);
+ if (grn_unlink(builder->path) == 0) {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[ii][builder][fin] removed path: <%s>",
+ builder->path);
+ } else {
+ ERRNO_ERR("[ii][builder][fin] failed to remove path: <%s>",
+ builder->path);
+ }
+ }
+ grn_ii_builder_fin_terms(ctx, builder);
+ if (builder->lexicon) {
+ grn_obj_close(ctx, builder->lexicon);
+ }
+ if (builder->srcs) {
+ GRN_FREE(builder->srcs);
+ }
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ii_builder_open creates a builder. Note that a builder must be closed by
+ * grn_ii_builder_close.
+ */
+static grn_rc
+grn_ii_builder_open(grn_ctx *ctx, grn_ii *ii,
+ const grn_ii_builder_options *options,
+ grn_ii_builder **builder)
+{
+ grn_rc rc;
+ grn_ii_builder *new_builder = GRN_MALLOCN(grn_ii_builder, 1);
+ if (!new_builder) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ if (!options) {
+ options = &grn_ii_builder_default_options;
+ }
+ rc = grn_ii_builder_init(ctx, new_builder, ii, options);
+ if (rc != GRN_SUCCESS) {
+ GRN_FREE(new_builder);
+ return rc;
+ }
+ *builder = new_builder;
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_close closes a builder. */
+static grn_rc
+grn_ii_builder_close(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ grn_rc rc;
+ if (!builder) {
+ ERR(GRN_INVALID_ARGUMENT, "builder is null");
+ return ctx->rc;
+ }
+ rc = grn_ii_builder_fin(ctx, builder);
+ GRN_FREE(builder);
+ return rc;
+}
+
+/* grn_ii_builder_create_lexicon creates a block lexicon. */
+static grn_rc
+grn_ii_builder_create_lexicon(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ grn_table_flags flags;
+ grn_obj *domain = grn_ctx_at(ctx, builder->ii->lexicon->header.domain);
+ grn_obj *range = grn_ctx_at(ctx, DB_OBJ(builder->ii->lexicon)->range);
+ grn_obj *tokenizer, *normalizer, *token_filters;
+ grn_rc rc = grn_table_get_info(ctx, builder->ii->lexicon, &flags, NULL,
+ &tokenizer, &normalizer, &token_filters);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ flags &= ~GRN_OBJ_PERSISTENT;
+ builder->lexicon = grn_table_create(ctx, NULL, 0, NULL,
+ flags, domain, range);
+ if (!builder->lexicon) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_UNKNOWN_ERROR, "[index] failed to create a block lexicon");
+ }
+ return ctx->rc;
+ }
+ builder->tokenizer = tokenizer;
+ builder->normalizer = normalizer;
+ rc = grn_obj_set_info(ctx, builder->lexicon,
+ GRN_INFO_DEFAULT_TOKENIZER, tokenizer);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_obj_set_info(ctx, builder->lexicon,
+ GRN_INFO_NORMALIZER, normalizer);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_obj_set_info(ctx, builder->lexicon,
+ GRN_INFO_TOKEN_FILTERS, token_filters);
+ }
+ }
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if ((flags & GRN_OBJ_TABLE_TYPE_MASK) == GRN_OBJ_TABLE_PAT_KEY) {
+ if (builder->options.lexicon_cache_size) {
+ rc = grn_pat_cache_enable(ctx, (grn_pat *)builder->lexicon,
+ builder->options.lexicon_cache_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ii_builder_extend_terms extends a buffer for terms in order to make
+ * terms[n_terms - 1] available.
+ */
+static grn_rc
+grn_ii_builder_extend_terms(grn_ctx *ctx, grn_ii_builder *builder,
+ uint32_t n_terms)
+{
+ if (n_terms <= builder->n_terms) {
+ return GRN_SUCCESS;
+ }
+
+ if (n_terms > builder->max_n_terms) {
+ uint32_t i;
+ if (n_terms > builder->terms_size) {
+ /* Resize builder->terms for new terms. */
+ size_t n_bytes;
+ uint32_t terms_size = builder->terms_size ? builder->terms_size * 2 : 1;
+ grn_ii_builder_term *terms;
+ while (terms_size < n_terms) {
+ terms_size *= 2;
+ }
+ n_bytes = terms_size * sizeof(grn_ii_builder_term);
+ terms = (grn_ii_builder_term *)GRN_REALLOC(builder->terms, n_bytes);
+ if (!terms) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for terms: n_bytes = %" GRN_FMT_SIZE,
+ n_bytes);
+ return ctx->rc;
+ }
+ builder->terms = terms;
+ builder->terms_size = terms_size;
+ }
+ /* Initialize new terms. */
+ for (i = builder->max_n_terms; i < n_terms; i++) {
+ grn_ii_builder_term_init(ctx, &builder->terms[i]);
+ }
+ builder->max_n_terms = n_terms;
+ }
+
+ builder->n += n_terms - builder->n_terms;
+ builder->n_terms = n_terms;
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_get_term gets a term associated with tid. */
+inline static grn_rc
+grn_ii_builder_get_term(grn_ctx *ctx, grn_ii_builder *builder, grn_id tid,
+ grn_ii_builder_term **term)
+{
+ uint32_t n_terms = tid;
+ if (n_terms > builder->n_terms) {
+ grn_rc rc = grn_ii_builder_extend_terms(ctx, builder, n_terms);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ *term = &builder->terms[tid - 1];
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_flush_file_buf flushes buffered data as a block. */
+static grn_rc
+grn_ii_builder_flush_file_buf(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ if (builder->file_buf_offset) {
+ ssize_t size = grn_write(builder->fd, builder->file_buf,
+ builder->file_buf_offset);
+ if ((uint64_t)size != builder->file_buf_offset) {
+ SERR("failed to write data: expected = %u, actual = %" GRN_FMT_INT64D,
+ builder->file_buf_offset, (int64_t)size);
+ }
+ builder->file_buf_offset = 0;
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_flush_term flushes a term and clears it */
+static grn_rc
+grn_ii_builder_flush_term(grn_ctx *ctx, grn_ii_builder *builder,
+ grn_ii_builder_term *term)
+{
+ grn_rc rc;
+ uint8_t *term_buf;
+
+ /* Append sentinels. */
+ if (term->rid != GRN_ID_NIL) {
+ if (builder->ii->header->flags & GRN_OBJ_WITH_POSITION) {
+ rc = grn_ii_builder_term_append(ctx, term, 0);
+ } else {
+ rc = grn_ii_builder_term_append(ctx, term, term->pos_or_freq);
+ }
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ rc = grn_ii_builder_term_append(ctx, term, 0);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ {
+ /* Put the global term ID. */
+ int key_size;
+ char key[GRN_TABLE_MAX_KEY_SIZE];
+ uint8_t *p;
+ uint32_t rest, value;
+ grn_rc rc;
+ grn_id local_tid = term - builder->terms + 1, global_tid;
+ key_size = grn_table_get_key(ctx, builder->lexicon, local_tid,
+ key, GRN_TABLE_MAX_KEY_SIZE);
+ if (!key_size) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_UNKNOWN_ERROR, "failed to get key: tid = %u", local_tid);
+ }
+ return ctx->rc;
+ }
+ global_tid = grn_table_add(ctx, builder->ii->lexicon, key, key_size, NULL);
+ if (global_tid == GRN_ID_NIL) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_UNKNOWN_ERROR,
+ "failed to get global term ID: tid = %u, key = \"%.*s\"",
+ local_tid, key_size, key);
+ }
+ return ctx->rc;
+ }
+
+ rest = builder->options.file_buf_size - builder->file_buf_offset;
+ if (rest < 10) {
+ rc = grn_ii_builder_flush_file_buf(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ value = global_tid;
+ p = builder->file_buf + builder->file_buf_offset;
+ if (value < 1U << 5) {
+ p[0] = (uint8_t)value;
+ builder->file_buf_offset++;
+ } else if (value < 1U << 13) {
+ p[0] = (uint8_t)((value & 0x1f) | (1 << 5));
+ p[1] = (uint8_t)(value >> 5);
+ builder->file_buf_offset += 2;
+ } else {
+ uint8_t i, n;
+ if (value < 1U << 21) {
+ n = 3;
+ } else if (value < 1U << 29) {
+ n = 4;
+ } else {
+ n = 5;
+ }
+ p[0] = (uint8_t)(value & 0x1f) | ((n - 1) << 5);
+ value >>= 5;
+ for (i = 1; i < n; i++) {
+ p[i] = (uint8_t)value;
+ value >>= 8;
+ }
+ builder->file_buf_offset += n;
+ }
+ }
+
+ /* Flush a term buffer. */
+ term_buf = grn_ii_builder_term_get_buf(term);
+ if (term->offset > builder->options.file_buf_size) {
+ ssize_t size;
+ rc = grn_ii_builder_flush_file_buf(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ size = grn_write(builder->fd, term_buf, term->offset);
+ if ((uint64_t)size != term->offset) {
+ SERR("failed to write data: expected = %u, actual = %" GRN_FMT_INT64D,
+ term->offset, (int64_t)size);
+ }
+ } else {
+ uint32_t rest = builder->options.file_buf_size - builder->file_buf_offset;
+ if (term->offset <= rest) {
+ grn_memcpy(builder->file_buf + builder->file_buf_offset,
+ term_buf, term->offset);
+ builder->file_buf_offset += term->offset;
+ } else {
+ grn_memcpy(builder->file_buf + builder->file_buf_offset,
+ term_buf, rest);
+ builder->file_buf_offset += rest;
+ rc = grn_ii_builder_flush_file_buf(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ builder->file_buf_offset = term->offset - rest;
+ grn_memcpy(builder->file_buf, term_buf + rest, builder->file_buf_offset);
+ }
+ }
+ grn_ii_builder_term_reinit(ctx, term);
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ii_builder_create_file creates a temporary file and allocates memory for
+ * buffered output.
+ */
+static grn_rc
+grn_ii_builder_create_file(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ grn_snprintf(builder->path, PATH_MAX, PATH_MAX,
+ "%sXXXXXX", grn_io_path(builder->ii->seg));
+ builder->fd = grn_mkstemp(builder->path);
+ if (builder->fd == -1) {
+ SERR("failed to create a temporary file: path = \"%s\"",
+ builder->path);
+ return ctx->rc;
+ }
+ builder->file_buf = (uint8_t *)GRN_MALLOC(builder->options.file_buf_size);
+ if (!builder->file_buf) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for buffered output: size = %u",
+ builder->options.file_buf_size);
+ return ctx->rc;
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_register_block registers a block. */
+static grn_rc
+grn_ii_builder_register_block(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ grn_ii_builder_block *block;
+ uint64_t file_offset = grn_lseek(builder->fd, 0, SEEK_CUR);
+ if (file_offset == (uint64_t)-1) {
+ SERR("failed to get file offset");
+ return ctx->rc;
+ }
+ if (builder->n_blocks >= builder->blocks_size) {
+ size_t n_bytes;
+ uint32_t blocks_size = 1;
+ grn_ii_builder_block *blocks;
+ while (blocks_size <= builder->n_blocks) {
+ blocks_size *= 2;
+ }
+ n_bytes = blocks_size * sizeof(grn_ii_builder_block);
+ blocks = (grn_ii_builder_block *)GRN_REALLOC(builder->blocks, n_bytes);
+ if (!blocks) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for block: n_bytes = %" GRN_FMT_SIZE,
+ n_bytes);
+ return ctx->rc;
+ }
+ builder->blocks = blocks;
+ builder->blocks_size = blocks_size;
+ }
+ block = &builder->blocks[builder->n_blocks];
+ grn_ii_builder_block_init(ctx, block);
+ if (!builder->n_blocks) {
+ block->offset = 0;
+ } else {
+ grn_ii_builder_block *prev_block = &builder->blocks[builder->n_blocks - 1];
+ block->offset = prev_block->offset + prev_block->rest;
+ }
+ block->rest = (uint32_t)(file_offset - block->offset);
+ builder->n_blocks++;
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_flush_block flushes a block to a temporary file. */
+static grn_rc
+grn_ii_builder_flush_block(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ grn_rc rc;
+ grn_table_cursor *cursor;
+
+ if (!builder->n) {
+ /* Do nothing if there are no output data. */
+ return GRN_SUCCESS;
+ }
+ if (builder->fd == -1) {
+ rc = grn_ii_builder_create_file(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+
+ /* Flush terms into a temporary file. */
+ cursor = grn_table_cursor_open(ctx, builder->lexicon,
+ NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_KEY);
+ for (;;) {
+ grn_id tid = grn_table_cursor_next(ctx, cursor);
+ if (tid == GRN_ID_NIL) {
+ break;
+ }
+ rc = grn_ii_builder_flush_term(ctx, builder, &builder->terms[tid - 1]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+ rc = grn_ii_builder_flush_file_buf(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ /* Register a block and clear the current data. */
+ rc = grn_ii_builder_register_block(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_table_truncate(ctx, builder->lexicon);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ builder->rid = GRN_ID_NIL;
+ builder->n_terms = 0;
+ builder->n = 0;
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_append_token appends a token. */
+static grn_rc
+grn_ii_builder_append_token(grn_ctx *ctx, grn_ii_builder *builder,
+ grn_id rid, uint32_t sid, uint32_t weight,
+ grn_id tid, uint32_t pos)
+{
+ grn_rc rc;
+ uint32_t ii_flags = builder->ii->header->flags;
+ grn_ii_builder_term *term;
+ rc = grn_ii_builder_get_term(ctx, builder, tid, &term);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (rid != term->rid || sid != term->sid) {
+ uint64_t rsid;
+ if (term->rid != GRN_ID_NIL) {
+ if (ii_flags & GRN_OBJ_WITH_POSITION) {
+ /* Append the end of positions. */
+ rc = grn_ii_builder_term_append(ctx, term, 0);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ builder->n++;
+ } else {
+ /* Append a frequency if positions are not available. */
+ rc = grn_ii_builder_term_append(ctx, term, term->pos_or_freq);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ builder->n++;
+ }
+ }
+ rsid = ((uint64_t)(rid - term->rid) << builder->sid_bits) | (sid - 1);
+ rc = grn_ii_builder_term_append(ctx, term, rsid);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ builder->n++;
+ if (ii_flags & GRN_OBJ_WITH_WEIGHT) {
+ rc = grn_ii_builder_term_append(ctx, term, weight);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ builder->n++;
+ }
+ term->rid = rid;
+ term->sid = sid;
+ term->pos_or_freq = 0;
+ }
+ if (ii_flags & GRN_OBJ_WITH_POSITION) {
+ rc = grn_ii_builder_term_append(ctx, term, pos - term->pos_or_freq);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ builder->n++;
+ term->pos_or_freq = pos;
+ } else {
+ term->pos_or_freq++;
+ }
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ii_builder_append_value appends a value. Note that values must be
+ * appended in ascending rid and sid order.
+ */
+static grn_rc
+grn_ii_builder_append_value(grn_ctx *ctx, grn_ii_builder *builder,
+ grn_id rid, uint32_t sid, uint32_t weight,
+ const char *value, uint32_t value_size)
+{
+ uint32_t pos = 0;
+ grn_token_cursor *cursor;
+ if (rid != builder->rid) {
+ builder->rid = rid;
+ builder->sid = sid;
+ builder->pos = 1;
+ } else if (sid != builder->sid) {
+ builder->sid = sid;
+ builder->pos = 1;
+ } else {
+ /* Insert a space between values. */
+ builder->pos++;
+ }
+ if (value_size) {
+ if (!builder->tokenizer && !builder->normalizer) {
+ grn_id tid;
+ switch (builder->lexicon->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ tid = grn_pat_add(ctx, (grn_pat *)builder->lexicon,
+ value, value_size, NULL, NULL);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ tid = grn_dat_add(ctx, (grn_dat *)builder->lexicon,
+ value, value_size, NULL, NULL);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ tid = grn_hash_add(ctx, (grn_hash *)builder->lexicon,
+ value, value_size, NULL, NULL);
+ break;
+ case GRN_TABLE_NO_KEY :
+ tid = *(grn_id *)value;
+ break;
+ default :
+ tid = GRN_ID_NIL;
+ break;
+ }
+ if (tid != GRN_ID_NIL) {
+ grn_rc rc;
+ pos = builder->pos;
+ rc = grn_ii_builder_append_token(ctx, builder, rid, sid,
+ weight, tid, pos);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ } else {
+ cursor = grn_token_cursor_open(ctx, builder->lexicon, value, value_size,
+ GRN_TOKEN_ADD, 0);
+ if (!cursor) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_UNKNOWN_ERROR,
+ "grn_token_cursor_open failed: value = <%.*s>",
+ value_size, value);
+ }
+ return ctx->rc;
+ }
+ while (cursor->status == GRN_TOKEN_CURSOR_DOING) {
+ grn_id tid = grn_token_cursor_next(ctx, cursor);
+ if (tid != GRN_ID_NIL) {
+ grn_rc rc;
+ pos = builder->pos + cursor->pos;
+ rc = grn_ii_builder_append_token(ctx, builder, rid, sid,
+ weight, tid, pos);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ }
+ grn_token_cursor_close(ctx, cursor);
+ }
+ }
+ builder->pos = pos + 1;
+ return ctx->rc;
+}
+
+/* grn_ii_builder_append_obj appends a BULK, UVECTOR or VECTOR object. */
+static grn_rc
+grn_ii_builder_append_obj(grn_ctx *ctx, grn_ii_builder *builder,
+ grn_id rid, uint32_t sid, grn_obj *obj)
+{
+ switch (obj->header.type) {
+ case GRN_BULK :
+ return grn_ii_builder_append_value(ctx, builder, rid, sid, 0,
+ GRN_TEXT_VALUE(obj), GRN_TEXT_LEN(obj));
+ case GRN_UVECTOR :
+ {
+ const char *p = GRN_BULK_HEAD(obj);
+ uint32_t i, n_values = grn_uvector_size(ctx, obj);
+ uint32_t value_size = grn_uvector_element_size(ctx, obj);
+ for (i = 0; i < n_values; i++) {
+ grn_rc rc = grn_ii_builder_append_value(ctx, builder, rid, sid, 0,
+ p, value_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ p += value_size;
+ }
+ }
+ return GRN_SUCCESS;
+ case GRN_VECTOR :
+ if (obj->u.v.body) {
+ /*
+ * Note that the following sections and n_sections don't correspond to
+ * source columns.
+ */
+ int i, n_secs = obj->u.v.n_sections;
+ grn_section *secs = obj->u.v.sections;
+ const char *head = GRN_BULK_HEAD(obj->u.v.body);
+ for (i = 0; i < n_secs; i++) {
+ grn_rc rc;
+ grn_section *sec = &secs[i];
+ if (sec->length == 0) {
+ continue;
+ }
+ if (builder->tokenizer) {
+ sid = i + 1;
+ }
+ rc = grn_ii_builder_append_value(ctx, builder, rid, sid, sec->weight,
+ head + sec->offset, sec->length);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "[index] invalid object assigned as value");
+ return ctx->rc;
+ }
+}
+
+/*
+ * grn_ii_builder_append_srcs reads values from source columns and appends the
+ * values.
+ */
+static grn_rc
+grn_ii_builder_append_srcs(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ size_t i;
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *objs;
+ grn_table_cursor *cursor;
+
+ /* Allocate memory for objects to store source values. */
+ objs = GRN_MALLOCN(grn_obj, builder->n_srcs);
+ if (!objs) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for objs: n_srcs = %u", builder->n_srcs);
+ return ctx->rc;
+ }
+
+ /* Create a cursor to get records in the ID order. */
+ cursor = grn_table_cursor_open(ctx, builder->src_table, NULL, 0, NULL, 0,
+ 0, -1, GRN_CURSOR_BY_ID);
+ if (!cursor) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_OBJECT_CORRUPT, "[index] failed to open table cursor");
+ }
+ GRN_FREE(objs);
+ return ctx->rc;
+ }
+
+ /* Read source values and append it. */
+ for (i = 0; i < builder->n_srcs; i++) {
+ GRN_TEXT_INIT(&objs[i], 0);
+ }
+ while (rc == GRN_SUCCESS) {
+ grn_id rid = grn_table_cursor_next(ctx, cursor);
+ if (rid == GRN_ID_NIL) {
+ break;
+ }
+ for (i = 0; i < builder->n_srcs; i++) {
+ grn_obj *obj = &objs[i];
+ grn_obj *src = builder->srcs[i];
+ rc = grn_obj_reinit_for(ctx, obj, src);
+ if (rc == GRN_SUCCESS) {
+ if (GRN_OBJ_TABLEP(src)) {
+ int len = grn_table_get_key2(ctx, src, rid, obj);
+ if (len <= 0) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_UNKNOWN_ERROR, "failed to get key: rid = %u, len = %d",
+ rid, len);
+ }
+ rc = ctx->rc;
+ }
+ } else {
+ if (!grn_obj_get_value(ctx, src, rid, obj)) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_UNKNOWN_ERROR, "failed to get value: rid = %u", rid);
+ }
+ rc = ctx->rc;
+ }
+ }
+ if (rc == GRN_SUCCESS) {
+ uint32_t sid = (uint32_t)(i + 1);
+ rc = grn_ii_builder_append_obj(ctx, builder, rid, sid, obj);
+ }
+ }
+ }
+ if (rc == GRN_SUCCESS && builder->n >= builder->options.block_threshold) {
+ rc = grn_ii_builder_flush_block(ctx, builder);
+ }
+ }
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ii_builder_flush_block(ctx, builder);
+ }
+ for (i = 0; i < builder->n_srcs; i++) {
+ GRN_OBJ_FIN(ctx, &objs[i]);
+ }
+ grn_table_cursor_close(ctx, cursor);
+ GRN_FREE(objs);
+ return rc;
+}
+
+/* grn_ii_builder_set_src_table sets a source table. */
+static grn_rc
+grn_ii_builder_set_src_table(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ builder->src_table = grn_ctx_at(ctx, DB_OBJ(builder->ii)->range);
+ if (!builder->src_table) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_INVALID_ARGUMENT, "source table is null: range = %d",
+ DB_OBJ(builder->ii)->range);
+ }
+ return ctx->rc;
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_set_sid_bits calculates sid_bits and sid_mask. */
+static grn_rc
+grn_ii_builder_set_sid_bits(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ /* Calculate the number of bits required to represent a section ID. */
+ if (builder->n_srcs == 1 && builder->tokenizer &&
+ (builder->srcs[0]->header.flags & GRN_OBJ_COLUMN_VECTOR) != 0) {
+ /* If the source column is a vector column and the index has a tokenizer, */
+ /* the maximum sid equals to the maximum number of elements. */
+ size_t max_elems = 0;
+ grn_table_cursor *cursor;
+ grn_obj obj;
+ cursor = grn_table_cursor_open(ctx, builder->src_table, NULL, 0, NULL, 0,
+ 0, -1, GRN_CURSOR_BY_ID);
+ if (!cursor) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_OBJECT_CORRUPT, "[index] failed to open table cursor");
+ }
+ return ctx->rc;
+ }
+ GRN_TEXT_INIT(&obj, 0);
+ for (;;) {
+ grn_id rid = grn_table_cursor_next(ctx, cursor);
+ if (rid == GRN_ID_NIL) {
+ break;
+ }
+ if (!grn_obj_get_value(ctx, builder->srcs[0], rid, &obj)) {
+ continue;
+ }
+ if (obj.u.v.n_sections > max_elems) {
+ max_elems = obj.u.v.n_sections;
+ }
+ }
+ GRN_OBJ_FIN(ctx, &obj);
+ grn_table_cursor_close(ctx, cursor);
+ while (((uint32_t)1 << builder->sid_bits) < max_elems) {
+ builder->sid_bits++;
+ }
+ }
+ if (builder->sid_bits == 0) {
+ while (((uint32_t)1 << builder->sid_bits) < builder->n_srcs) {
+ builder->sid_bits++;
+ }
+ }
+ builder->sid_mask = ((uint64_t)1 << builder->sid_bits) - 1;
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_set_srcs sets source columns. */
+static grn_rc
+grn_ii_builder_set_srcs(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ size_t i;
+ grn_id *source;
+ builder->n_srcs = builder->ii->obj.source_size / sizeof(grn_id);
+ source = (grn_id *)builder->ii->obj.source;
+ if (!source || !builder->n_srcs) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "source is not available: source = %p, source_size = %u",
+ builder->ii->obj.source, builder->ii->obj.source_size);
+ return ctx->rc;
+ }
+ builder->srcs = GRN_MALLOCN(grn_obj *, builder->n_srcs);
+ if (!builder->srcs) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ for (i = 0; i < builder->n_srcs; i++) {
+ builder->srcs[i] = grn_ctx_at(ctx, source[i]);
+ if (!builder->srcs[i]) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_OBJECT_CORRUPT, "source not found: id = %d", source[i]);
+ }
+ return ctx->rc;
+ }
+ }
+ return grn_ii_builder_set_sid_bits(ctx, builder);
+}
+
+/* grn_ii_builder_append_source appends values in source columns. */
+static grn_rc
+grn_ii_builder_append_source(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ grn_rc rc = grn_ii_builder_set_src_table(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (grn_table_size(ctx, builder->src_table) == 0) {
+ /* Nothing to do because there are no values. */
+ return ctx->rc;
+ }
+ /* Create a block lexicon. */
+ rc = grn_ii_builder_create_lexicon(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ii_builder_set_srcs(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ii_builder_append_srcs(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ grn_ii_builder_fin_terms(ctx, builder);
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ii_builder_fill_block reads the next data from a temporary file and fill
+ * a block buffer.
+ */
+static grn_rc
+grn_ii_builder_fill_block(grn_ctx *ctx, grn_ii_builder *builder,
+ uint32_t block_id)
+{
+ ssize_t size;
+ uint32_t buf_rest;
+ uint64_t file_offset;
+ grn_ii_builder_block *block = &builder->blocks[block_id];
+ if (!block->rest) {
+ return GRN_END_OF_DATA;
+ }
+ if (!block->buf) {
+ block->buf = (uint8_t *)GRN_MALLOC(builder->options.block_buf_size);
+ if (!block->buf) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for buffered input: size = %u",
+ builder->options.block_buf_size);
+ return ctx->rc;
+ }
+ }
+
+ /* Move the remaining data to the head. */
+ buf_rest = block->end - block->cur;
+ if (buf_rest) {
+ grn_memmove(block->buf, block->cur, buf_rest);
+ }
+ block->cur = block->buf;
+ block->end = block->buf + buf_rest;
+
+ /* Read the next data. */
+ file_offset = grn_lseek(builder->fd, block->offset, SEEK_SET);
+ if (file_offset != block->offset) {
+ SERR("failed to seek file: expected = %" GRN_FMT_INT64U
+ ", actual = %" GRN_FMT_INT64D,
+ block->offset, file_offset);
+ return ctx->rc;
+ }
+ buf_rest = builder->options.block_buf_size - buf_rest;
+ if (block->rest < buf_rest) {
+ buf_rest = block->rest;
+ }
+ size = grn_read(builder->fd, block->end, buf_rest);
+ if (size <= 0) {
+ SERR("failed to read data: expected = %u, actual = %" GRN_FMT_INT64D,
+ buf_rest, (int64_t)size);
+ return ctx->rc;
+ }
+ block->offset += size;
+ block->rest -= size;
+ block->end += size;
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_read_from_block reads the next value from a block. */
+static grn_rc
+grn_ii_builder_read_from_block(grn_ctx *ctx, grn_ii_builder *builder,
+ uint32_t block_id, uint64_t *value)
+{
+ grn_ii_builder_block *block = &builder->blocks[block_id];
+ grn_rc rc = grn_ii_builder_block_next(ctx, block, value);
+ if (rc == GRN_SUCCESS) {
+ return GRN_SUCCESS;
+ } else if (rc == GRN_END_OF_DATA) {
+ rc = grn_ii_builder_fill_block(ctx, builder, block_id);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ return grn_ii_builder_block_next(ctx, block, value);
+ }
+ return rc;
+}
+
+/* grn_ii_builder_pack_chunk tries to pack a chunk. */
+static grn_rc
+grn_ii_builder_pack_chunk(grn_ctx *ctx, grn_ii_builder *builder,
+ grn_bool *packed)
+{
+ grn_id rid;
+ uint32_t sid, pos, *a;
+ grn_ii_builder_chunk *chunk = &builder->chunk;
+ *packed = GRN_FALSE;
+ if (chunk->offset != 1) { /* df != 1 */
+ return GRN_SUCCESS;
+ }
+ if (chunk->weight_buf && chunk->weight_buf[0]) { /* weight != 0 */
+ return GRN_SUCCESS;
+ }
+ if (chunk->freq_buf[0] != 0) { /* freq != 1 */
+ return GRN_SUCCESS;
+ }
+ rid = chunk->rid_buf[0];
+ if (chunk->sid_buf) {
+ if (rid >= 0x100000) {
+ return GRN_SUCCESS;
+ }
+ sid = chunk->sid_buf[0] + 1;
+ if (sid >= 0x800) {
+ return GRN_SUCCESS;
+ }
+ a = array_get(ctx, builder->ii, chunk->tid);
+ if (!a) {
+ DEFINE_NAME(builder->ii);
+ MERR("[ii][builder][chunk][pack] failed to allocate an array: "
+ "<%.*s>: "
+ "<%u>:<%u>:<%u>",
+ name_size, name,
+ rid, sid, chunk->tid);
+ return ctx->rc;
+ }
+ a[0] = ((rid << 12) + (sid << 1)) | 1;
+ } else {
+ a = array_get(ctx, builder->ii, chunk->tid);
+ if (!a) {
+ DEFINE_NAME(builder->ii);
+ MERR("[ii][builder][chunk][pack] failed to allocate an array: "
+ "<%.*s>: "
+ "<%u>:<%u>",
+ name_size, name,
+ rid, chunk->tid);
+ return ctx->rc;
+ }
+ a[0] = (rid << 1) | 1;
+ }
+ pos = 0;
+ if (chunk->pos_buf) {
+ pos = chunk->pos_buf[0];
+ }
+ a[1] = pos;
+ array_unref(builder->ii, chunk->tid);
+ *packed = GRN_TRUE;
+
+ grn_ii_builder_chunk_clear(ctx, chunk);
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_get_cinfo returns a new cinfo. */
+static grn_rc
+grn_ii_builder_get_cinfo(grn_ctx *ctx, grn_ii_builder *builder,
+ chunk_info **cinfo)
+{
+ if (builder->n_cinfos == builder->cinfos_size) {
+ uint32_t size = builder->cinfos_size ? (builder->cinfos_size * 2) : 1;
+ size_t n_bytes = size * sizeof(chunk_info);
+ chunk_info *cinfos = (chunk_info *)GRN_REALLOC(builder->cinfos, n_bytes);
+ if (!cinfos) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate memory for cinfos: n_bytes = %" GRN_FMT_SIZE,
+ n_bytes);
+ return ctx->rc;
+ }
+ builder->cinfos = cinfos;
+ builder->cinfos_size = size;
+ }
+ *cinfo = &builder->cinfos[builder->n_cinfos++];
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_flush_chunk flushes a chunk. */
+static grn_rc
+grn_ii_builder_flush_chunk(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ grn_rc rc;
+ chunk_info *cinfo = NULL;
+ grn_ii_builder_chunk *chunk = &builder->chunk;
+ void *seg;
+ uint8_t *in;
+ uint32_t in_size, chunk_id, seg_id, seg_offset, seg_rest;
+
+ rc = grn_ii_builder_chunk_encode(ctx, chunk, NULL, 0);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ in = chunk->enc_buf;
+ in_size = chunk->enc_offset;
+
+ rc = chunk_new(ctx, builder->ii, &chunk_id, chunk->enc_offset);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ /* Copy to the first segment. */
+ seg_id = chunk_id >> GRN_II_N_CHUNK_VARIATION;
+ seg_offset = (chunk_id & ((1 << GRN_II_N_CHUNK_VARIATION) - 1)) <<
+ GRN_II_W_LEAST_CHUNK;
+ GRN_IO_SEG_REF(builder->ii->chunk, seg_id, seg);
+ if (!seg) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_UNKNOWN_ERROR,
+ "failed access chunk segment: chunk_id = %u, seg_id = %u",
+ chunk_id, seg_id);
+ }
+ return ctx->rc;
+ }
+ seg_rest = S_CHUNK - seg_offset;
+ if (in_size <= seg_rest) {
+ grn_memcpy((uint8_t *)seg + seg_offset, in, in_size);
+ in_size = 0;
+ } else {
+ grn_memcpy((uint8_t *)seg + seg_offset, in, seg_rest);
+ in += seg_rest;
+ in_size -= seg_rest;
+ }
+ GRN_IO_SEG_UNREF(builder->ii->chunk, seg_id);
+
+ /* Copy to the next segments. */
+ while (in_size) {
+ seg_id++;
+ GRN_IO_SEG_REF(builder->ii->chunk, seg_id, seg);
+ if (!seg) {
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_UNKNOWN_ERROR,
+ "failed access chunk segment: chunk_id = %u, seg_id = %u",
+ chunk_id, seg_id);
+ }
+ return ctx->rc;
+ }
+ if (in_size <= S_CHUNK) {
+ grn_memcpy(seg, in, in_size);
+ in_size = 0;
+ } else {
+ grn_memcpy(seg, in, S_CHUNK);
+ in += S_CHUNK;
+ in_size -= S_CHUNK;
+ }
+ GRN_IO_SEG_UNREF(builder->ii->chunk, seg_id);
+ }
+
+ /* Append a cinfo. */
+ rc = grn_ii_builder_get_cinfo(ctx, builder, &cinfo);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ cinfo->segno = chunk_id;
+ cinfo->size = chunk->enc_offset;
+ cinfo->dgap = chunk->rid_gap;
+
+ builder->buf.ii->header->total_chunk_size += chunk->enc_offset;
+ grn_ii_builder_chunk_clear(ctx, chunk);
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_read_to_chunk read values from a block to a chunk. */
+static grn_rc
+grn_ii_builder_read_to_chunk(grn_ctx *ctx, grn_ii_builder *builder,
+ uint32_t block_id)
+{
+ grn_rc rc;
+ uint64_t value;
+ uint32_t rid = GRN_ID_NIL, last_sid = 0;
+ uint32_t ii_flags = builder->ii->header->flags;
+ grn_ii_builder_chunk *chunk = &builder->chunk;
+
+ for (;;) {
+ uint32_t gap, freq;
+ uint64_t value;
+ rc = grn_ii_builder_read_from_block(ctx, builder, block_id, &value);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (!value) {
+ break;
+ }
+ if (builder->chunk.offset == builder->chunk.size) {
+ rc = grn_ii_builder_chunk_extend_bufs(ctx, chunk, ii_flags);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+
+ /* Read record ID. */
+ gap = value >> builder->sid_bits; /* In-block gap */
+ if (gap) {
+ if (chunk->n >= builder->options.chunk_threshold) {
+ rc = grn_ii_builder_flush_chunk(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ last_sid = 0;
+ }
+ rid += gap;
+ gap = rid - chunk->rid; /* Global gap */
+ chunk->rid_buf[chunk->offset] = chunk->offset ? gap : rid;
+ chunk->n++;
+ chunk->rid = rid;
+ chunk->rid_gap += gap;
+ builder->df++;
+
+ /* Read section ID. */
+ if (ii_flags & GRN_OBJ_WITH_SECTION) {
+ uint32_t sid = (value & builder->sid_mask) + 1;
+ chunk->sid_buf[chunk->offset] = sid - last_sid - 1;
+ chunk->n++;
+ last_sid = sid;
+ }
+
+ /* Read weight. */
+ if (ii_flags & GRN_OBJ_WITH_WEIGHT) {
+ uint32_t weight;
+ rc = grn_ii_builder_read_from_block(ctx, builder, block_id, &value);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ weight = value;
+ chunk->weight_buf[chunk->offset] = weight;
+ chunk->n++;
+ }
+
+ /* Read positions or a frequency. */
+ if (ii_flags & GRN_OBJ_WITH_POSITION) {
+ uint32_t pos = -1;
+ freq = 0;
+ for (;;) {
+ rc = grn_ii_builder_read_from_block(ctx, builder, block_id, &value);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (!value) {
+ break;
+ }
+ if (builder->chunk.pos_offset == builder->chunk.pos_size) {
+ rc = grn_ii_builder_chunk_extend_pos_buf(ctx, chunk);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (pos == -1) {
+ chunk->pos_buf[chunk->pos_offset] = value - 1;
+ chunk->pos_sum += value - 1;
+ } else {
+ chunk->pos_buf[chunk->pos_offset] = value;
+ chunk->pos_sum += value;
+ }
+ chunk->n++;
+ pos += value;
+ chunk->pos_offset++;
+ freq++;
+ }
+ } else {
+ rc = grn_ii_builder_read_from_block(ctx, builder, block_id, &value);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ freq = value;
+ }
+ chunk->freq_buf[chunk->offset] = freq - 1;
+ chunk->n++;
+ chunk->offset++;
+ }
+ rc = grn_ii_builder_read_from_block(ctx, builder, block_id, &value);
+ if (rc == GRN_SUCCESS) {
+ builder->blocks[block_id].tid = value;
+ } else if (rc == GRN_END_OF_DATA) {
+ builder->blocks[block_id].tid = GRN_ID_NIL;
+ } else {
+ return rc;
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ii_builder_register_chunks registers chunks. */
+static grn_rc
+grn_ii_builder_register_chunks(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ grn_rc rc;
+ uint32_t buf_tid, *a;
+ buffer_term *buf_term;
+
+ rc = grn_ii_builder_chunk_encode(ctx, &builder->chunk, builder->cinfos,
+ builder->n_cinfos);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ if (!grn_ii_builder_buffer_is_assigned(ctx, &builder->buf)) {
+ rc = grn_ii_builder_buffer_assign(ctx, &builder->buf,
+ builder->chunk.enc_offset);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ buf_tid = builder->buf.buf->header.nterms;
+ if (buf_tid >= builder->options.buffer_max_n_terms ||
+ builder->buf.chunk_size - builder->buf.chunk_offset <
+ builder->chunk.enc_offset) {
+ rc = grn_ii_builder_buffer_flush(ctx, &builder->buf);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ii_builder_buffer_assign(ctx, &builder->buf,
+ builder->chunk.enc_offset);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_tid = 0;
+ }
+ buf_term = &builder->buf.buf->terms[buf_tid];
+ buf_term->tid = builder->chunk.tid;
+ if (builder->n_cinfos) {
+ buf_term->tid |= CHUNK_SPLIT;
+ }
+ buf_term->size_in_buffer = 0;
+ buf_term->pos_in_buffer = 0;
+ buf_term->size_in_chunk = builder->chunk.enc_offset;
+ buf_term->pos_in_chunk = builder->buf.chunk_offset;
+
+ grn_memcpy(builder->buf.chunk + builder->buf.chunk_offset,
+ builder->chunk.enc_buf, builder->chunk.enc_offset);
+ builder->buf.chunk_offset += builder->chunk.enc_offset;
+
+ a = array_get(ctx, builder->ii, builder->chunk.tid);
+ if (!a) {
+ DEFINE_NAME(builder->ii);
+ MERR("[ii][builder][chunk][register] "
+ "failed to allocate an array in segment: "
+ "<%.*s>: "
+ "tid=<%u>: max_n_segments=<%u>",
+ name_size, name,
+ builder->chunk.tid,
+ builder->ii->seg->header->max_segment);
+ return ctx->rc;
+ }
+ a[0] = SEG2POS(builder->buf.buf_id,
+ sizeof(buffer_header) + buf_tid * sizeof(buffer_term));
+ a[1] = builder->df;
+ array_unref(builder->ii, builder->chunk.tid);
+
+ builder->buf.buf->header.nterms++;
+ builder->n_cinfos = 0;
+ grn_ii_builder_chunk_clear(ctx, &builder->chunk);
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_ii_builder_commit(grn_ctx *ctx, grn_ii_builder *builder)
+{
+ uint32_t i;
+ grn_rc rc;
+ grn_table_cursor *cursor;
+
+ for (i = 0; i < builder->n_blocks; i++) {
+ uint64_t value;
+ rc = grn_ii_builder_read_from_block(ctx, builder, i, &value);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ builder->blocks[i].tid = value;
+ }
+
+ cursor = grn_table_cursor_open(ctx, builder->ii->lexicon,
+ NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_KEY);
+ for (;;) {
+ grn_id tid = grn_table_cursor_next(ctx, cursor);
+ if (tid == GRN_ID_NIL) {
+ break;
+ }
+ builder->chunk.tid = tid;
+ builder->chunk.rid = GRN_ID_NIL;
+ builder->df = 0;
+ for (i = 0; i < builder->n_blocks; i++) {
+ if (tid == builder->blocks[i].tid) {
+ rc = grn_ii_builder_read_to_chunk(ctx, builder, i);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ if (!builder->chunk.n) {
+ /* This term does not appear. */
+ continue;
+ }
+ if (!builder->n_cinfos) {
+ grn_bool packed;
+ rc = grn_ii_builder_pack_chunk(ctx, builder, &packed);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (packed) {
+ continue;
+ }
+ }
+ rc = grn_ii_builder_register_chunks(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+ if (grn_ii_builder_buffer_is_assigned(ctx, &builder->buf)) {
+ rc = grn_ii_builder_buffer_flush(ctx, &builder->buf);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ii_build2(grn_ctx *ctx, grn_ii *ii, const grn_ii_builder_options *options)
+{
+ grn_rc rc, rc_close;
+ grn_ii_builder *builder;
+ rc = grn_ii_builder_open(ctx, ii, options, &builder);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ii_builder_append_source(ctx, builder);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ii_builder_commit(ctx, builder);
+ }
+ rc_close = grn_ii_builder_close(ctx, builder);
+ if (rc == GRN_SUCCESS) {
+ rc = rc_close;
+ }
+ }
+ return rc;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/index_column.c b/storage/mroonga/vendor/groonga/lib/index_column.c
new file mode 100644
index 00000000000..9838eb52508
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/index_column.c
@@ -0,0 +1,194 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_index_column.h"
+#include "grn_ii.h"
+#include "grn_hash.h"
+
+#include <string.h>
+
+static uint64_t grn_index_sparsity = 10;
+static grn_bool grn_index_chunk_split_enable = GRN_TRUE;
+
+void
+grn_index_column_init_from_env(void)
+{
+ {
+ char grn_index_sparsity_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_INDEX_SPARSITY",
+ grn_index_sparsity_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_index_sparsity_env[0]) {
+ uint64_t sparsity;
+ errno = 0;
+ sparsity = strtoull(grn_index_sparsity_env, NULL, 0);
+ if (errno == 0) {
+ grn_index_sparsity = sparsity;
+ }
+ }
+ }
+
+ {
+ char grn_index_chunk_split_enable_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_INDEX_CHUNK_SPLIT_ENABLE",
+ grn_index_chunk_split_enable_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (strcmp(grn_index_chunk_split_enable_env, "no") == 0) {
+ grn_index_chunk_split_enable = GRN_FALSE;
+ } else {
+ grn_index_chunk_split_enable = GRN_TRUE;
+ }
+ }
+}
+
+inline static void
+grn_index_column_build_call_hook(grn_ctx *ctx, grn_obj *obj,
+ grn_id id, grn_obj *value, int flags)
+{
+ grn_hook *hooks = DB_OBJ(obj)->hooks[GRN_HOOK_SET];
+
+ if (hooks) {
+ grn_obj oldvalue;
+ /* todo : grn_proc_ctx_open() */
+ grn_obj id_, flags_;
+ grn_proc_ctx pctx = {{0}, hooks->proc, NULL, hooks, hooks, PROC_INIT, 4, 4};
+ GRN_TEXT_INIT(&oldvalue, 0);
+ GRN_UINT32_INIT(&id_, 0);
+ GRN_UINT32_INIT(&flags_, 0);
+ GRN_UINT32_SET(ctx, &id_, id);
+ GRN_UINT32_SET(ctx, &flags_, flags);
+ while (hooks) {
+ grn_ctx_push(ctx, &id_);
+ grn_ctx_push(ctx, &oldvalue);
+ grn_ctx_push(ctx, value);
+ grn_ctx_push(ctx, &flags_);
+ pctx.caller = NULL;
+ pctx.currh = hooks;
+ if (hooks->proc) {
+ hooks->proc->funcs[PROC_INIT](ctx, 1, &obj, &pctx.user_data);
+ } else {
+ grn_obj_default_set_value_hook(ctx, 1, &obj, &pctx.user_data);
+ }
+ if (ctx->rc) {
+ grn_obj_close(ctx, &oldvalue);
+ return;
+ }
+ hooks = hooks->next;
+ pctx.offset++;
+ }
+ grn_obj_close(ctx, &oldvalue);
+ }
+}
+
+grn_rc
+grn_index_column_build(grn_ctx *ctx, grn_obj *index_column)
+{
+ grn_obj *src, **cp, **col, *target;
+ grn_id *s = DB_OBJ(index_column)->source;
+ if (!(DB_OBJ(index_column)->source_size) || !s) { return ctx->rc; }
+ if ((src = grn_ctx_at(ctx, *s))) {
+ target = GRN_OBJ_TABLEP(src) ? src : grn_ctx_at(ctx, src->header.domain);
+ if (target) {
+ int i, ncol = DB_OBJ(index_column)->source_size / sizeof(grn_id);
+ grn_table_flags flags;
+ grn_ii *ii = (grn_ii *)index_column;
+ grn_bool use_grn_ii_build;
+ grn_obj *tokenizer = NULL;
+ grn_table_get_info(ctx, ii->lexicon, &flags, NULL, &tokenizer, NULL, NULL);
+ switch (flags & GRN_OBJ_TABLE_TYPE_MASK) {
+ case GRN_OBJ_TABLE_PAT_KEY :
+ case GRN_OBJ_TABLE_DAT_KEY :
+ use_grn_ii_build = GRN_TRUE;
+ break;
+ default :
+ use_grn_ii_build = GRN_FALSE;
+ break;
+ }
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) {
+ use_grn_ii_build = GRN_FALSE;
+ }
+ if ((ii->header->flags & GRN_OBJ_WITH_POSITION) &&
+ (!tokenizer &&
+ !GRN_TYPE_IS_TEXT_FAMILY(ii->lexicon->header.domain))) {
+ /* TODO: Support offline index construction for WITH_POSITION
+ * index against UInt32 vector column. */
+ use_grn_ii_build = GRN_FALSE;
+ }
+ if ((col = GRN_MALLOC(ncol * sizeof(grn_obj *)))) {
+ for (cp = col, i = ncol; i; s++, cp++, i--) {
+ if (!(*cp = grn_ctx_at(ctx, *s))) {
+ ERR(GRN_INVALID_ARGUMENT, "source invalid, n=%d",i);
+ GRN_FREE(col);
+ return ctx->rc;
+ }
+ if (GRN_OBJ_TABLEP(grn_ctx_at(ctx, DB_OBJ(*cp)->range))) {
+ use_grn_ii_build = GRN_FALSE;
+ }
+ }
+ if (use_grn_ii_build) {
+ if (grn_index_chunk_split_enable) {
+ grn_ii_build2(ctx, ii, NULL);
+ } else {
+ grn_ii_build(ctx, ii, grn_index_sparsity);
+ }
+ } else {
+ grn_table_cursor *tc;
+ if ((tc = grn_table_cursor_open(ctx, target, NULL, 0, NULL, 0,
+ 0, -1, GRN_CURSOR_BY_ID))) {
+ grn_id id;
+ grn_obj rv;
+ GRN_TEXT_INIT(&rv, 0);
+ while ((id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
+ for (cp = col, i = ncol; i; i--, cp++) {
+ GRN_BULK_REWIND(&rv);
+ if (GRN_OBJ_TABLEP(*cp)) {
+ grn_table_get_key2(ctx, *cp, id, &rv);
+ } else {
+ grn_obj_get_value(ctx, *cp, id, &rv);
+ }
+ grn_index_column_build_call_hook(ctx, *cp, id, &rv, 0);
+ }
+ }
+ GRN_OBJ_FIN(ctx, &rv);
+ grn_table_cursor_close(ctx, tc);
+ }
+ }
+ GRN_FREE(col);
+ grn_obj_touch(ctx, index_column, NULL);
+ }
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "invalid target");
+ }
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "invalid source");
+ }
+ return ctx->rc;
+}
+
+grn_rc
+grn_index_column_rebuild(grn_ctx *ctx, grn_obj *index_column)
+{
+ grn_ii *ii = (grn_ii *)index_column;
+
+ GRN_API_ENTER;
+
+ grn_ii_truncate(ctx, ii);
+ grn_index_column_build(ctx, index_column);
+
+ GRN_API_RETURN(ctx->rc);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/io.c b/storage/mroonga/vendor/groonga/lib/io.c
index 3cee03f5123..a20fef614c7 100644
--- a/storage/mroonga/vendor/groonga/lib/io.c
+++ b/storage/mroonga/vendor/groonga/lib/io.c
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -28,6 +29,7 @@
#include "grn_plugin.h"
#include "grn_hash.h"
#include "grn_ctx_impl.h"
+#include "grn_util.h"
#ifdef WIN32
# include <io.h>
@@ -62,55 +64,81 @@ typedef struct _grn_io_fileinfo {
#define IO_HEADER_SIZE 64
static uint32_t grn_io_version_default = GRN_IO_VERSION_DEFAULT;
+static grn_bool grn_io_use_sparse = GRN_FALSE;
-inline static grn_rc grn_fileinfo_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags);
+inline static grn_rc grn_fileinfo_open(grn_ctx *ctx, fileinfo *fi,
+ const char *path, int flags);
inline static void grn_fileinfo_init(fileinfo *fis, int nfis);
inline static int grn_fileinfo_opened(fileinfo *fi);
inline static grn_rc grn_fileinfo_close(grn_ctx *ctx, fileinfo *fi);
#ifdef WIN32
-inline static void * grn_mmap(grn_ctx *ctx, grn_io *io,
- HANDLE *fmo, fileinfo *fi,
+inline static void * grn_mmap(grn_ctx *ctx, grn_ctx *owner_ctx,
+ grn_io *io, HANDLE *fmo, fileinfo *fi,
off_t offset, size_t length);
-inline static int grn_munmap(grn_ctx *ctx, grn_io *io,
- HANDLE *fmo, fileinfo *fi,
+inline static int grn_munmap(grn_ctx *ctx, grn_ctx *owner_ctx,
+ grn_io *io, HANDLE *fmo, fileinfo *fi,
void *start, size_t length);
-# define GRN_MMAP(ctx,io,fmo,fi,offset,length)\
- (grn_mmap((ctx), (io), (fmo), (fi), (offset), (length)))
-# define GRN_MUNMAP(ctx,io,fmo,fi,start,length)\
- (grn_munmap((ctx), (io), (fmo), (fi), (start), (length)))
+inline static int grn_msync(grn_ctx *ctx, HANDLE fh,
+ void *start, size_t length);
+# define GRN_MMAP(ctx,owner_ctx,io,fmo,fi,offset,length)\
+ (grn_mmap((ctx), (owner_ctx), (io), (fmo), (fi), (offset), (length)))
+# define GRN_MUNMAP(ctx,owner_ctx,io,fmo,fi,start,length)\
+ (grn_munmap((ctx), (owner_ctx), (io), (fmo), (fi), (start), (length)))
+# define GRN_MSYNC(ctx,fh,start,length) \
+ (grn_msync((ctx), (fh), (start), (length)))
#else /* WIN32 */
-inline static void * grn_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi,
+inline static void * grn_mmap(grn_ctx *ctx, grn_ctx *owner_ctx,
+ grn_io *io, fileinfo *fi,
off_t offset, size_t length);
-inline static int grn_munmap(grn_ctx *ctx, grn_io *io, fileinfo *fi,
+inline static int grn_munmap(grn_ctx *ctx, grn_ctx *owner_ctx,
+ grn_io *io, fileinfo *fi,
void *start, size_t length);
-# define GRN_MUNMAP(ctx,io,fmo,fi,start,length) \
- (grn_munmap((ctx), (io), (fi), (start), (length)))
+inline static int grn_msync(grn_ctx *ctx, void *start, size_t length);
+# define GRN_MUNMAP(ctx,owner_ctx,io,fmo,fi,start,length) \
+ (grn_munmap((ctx), (owner_ctx), (io), (fi), (start), (length)))
+# define GRN_MSYNC(ctx,fh,start,length) \
+ (grn_msync((ctx), (start), (length)))
# ifdef USE_FAIL_MALLOC
-inline static void * grn_fail_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi,
+inline static void * grn_fail_mmap(grn_ctx *ctx, grn_ctx *owner_ctx,
+ grn_io *io, fileinfo *fi,
off_t offset, size_t length,
const char* file, int line, const char *func);
-# define GRN_MMAP(ctx,io,fmo,fi,offset,length)\
- (grn_fail_mmap((ctx), (io), (fi), (offset), (length),\
+# define GRN_MMAP(ctx,owner_ctx,io,fmo,fi,offset,length)\
+ (grn_fail_mmap((ctx), (owner_ctx), (io), (fi), (offset), (length),\
__FILE__, __LINE__, __FUNCTION__))
# else /* USE_FAIL_MALLOC */
-# define GRN_MMAP(ctx,io,fmo,fi,offset,length)\
- (grn_mmap((ctx), (io), (fi), (offset), (length)))
+# define GRN_MMAP(ctx,owner_ctx,io,fmo,fi,offset,length)\
+ (grn_mmap((ctx), (owner_ctx), (io), (fi), (offset), (length)))
# endif /* USE_FAIL_MALLOC */
#endif /* WIN32 */
-inline static int grn_msync(grn_ctx *ctx, void *start, size_t length);
-inline static grn_rc grn_pread(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset);
-inline static grn_rc grn_pwrite(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset);
+inline static grn_rc grn_pread(grn_ctx *ctx, fileinfo *fi, void *buf,
+ size_t count, off_t offset);
+inline static grn_rc grn_pwrite(grn_ctx *ctx, fileinfo *fi, void *buf,
+ size_t count, off_t offset);
void
grn_io_init_from_env(void)
{
- char version_env[GRN_ENV_BUFFER_SIZE];
+ {
+ char version_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_IO_VERSION",
- version_env,
- GRN_ENV_BUFFER_SIZE);
- if (version_env[0]) {
- grn_io_version_default = atoi(version_env);
+ grn_getenv("GRN_IO_VERSION",
+ version_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (version_env[0]) {
+ grn_io_version_default = atoi(version_env);
+ }
+ }
+
+ {
+ char use_sparse_env[GRN_ENV_BUFFER_SIZE];
+
+ grn_getenv("GRN_IO_USE_SPARSE",
+ use_sparse_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (use_sparse_env[0] && strcmp(use_sparse_env, "yes") == 0) {
+ grn_io_use_sparse = GRN_TRUE;
+ }
}
}
@@ -169,15 +197,31 @@ grn_io_max_n_files(grn_io *io)
file_size);
}
-grn_io *
-grn_io_create_tmp(uint32_t header_size, uint32_t segment_size,
+static inline uint32_t
+grn_io_compute_nth_file_info(grn_io *io, uint32_t nth_segment)
+{
+ uint32_t segment_size;
+ unsigned long file_size;
+ uint32_t segments_per_file;
+ uint32_t resolved_nth_segment;
+
+ segment_size = io->header->segment_size;
+ file_size = grn_io_compute_file_size(io->header->version);
+ segments_per_file = file_size / segment_size;
+ resolved_nth_segment = nth_segment + io->base_seg;
+ return resolved_nth_segment / segments_per_file;
+}
+
+static grn_io *
+grn_io_create_tmp(grn_ctx *ctx, uint32_t header_size, uint32_t segment_size,
uint32_t max_segment, grn_io_mode mode, uint32_t flags)
{
grn_io *io;
uint32_t b;
struct _grn_io_header *header;
b = grn_io_compute_base(header_size);
- header = (struct _grn_io_header *)GRN_MMAP(&grn_gctx, NULL, NULL, NULL, 0, b);
+ header = (struct _grn_io_header *)GRN_MMAP(ctx, &grn_gctx, NULL, NULL, NULL,
+ 0, b);
if (header) {
header->version = grn_io_version_default;
header->header_size = header_size;
@@ -187,9 +231,9 @@ grn_io_create_tmp(uint32_t header_size, uint32_t segment_size,
header->flags = flags;
header->lock = 0;
grn_memcpy(header->idstr, GRN_IO_IDSTR, 16);
- if ((io = GRN_GMALLOCN(grn_io, 1))) {
+ if ((io = GRN_MALLOCN(grn_io, 1))) {
grn_io_mapinfo *maps = NULL;
- if ((maps = GRN_GCALLOC(sizeof(grn_io_mapinfo) * max_segment))) {
+ if ((maps = GRN_CALLOC(sizeof(grn_io_mapinfo) * max_segment))) {
io->header = header;
io->user_header = (((byte *) header) + IO_HEADER_SIZE);
io->maps = maps;
@@ -207,15 +251,15 @@ grn_io_create_tmp(uint32_t header_size, uint32_t segment_size,
io->path[0] = '\0';
return io;
}
- GRN_GFREE(io);
+ GRN_FREE(io);
}
- GRN_MUNMAP(&grn_gctx, NULL, NULL, NULL, header, b);
+ GRN_MUNMAP(ctx, &grn_gctx, NULL, NULL, NULL, header, b);
}
return NULL;
}
static void
-grn_io_register(grn_io *io)
+grn_io_register(grn_ctx *ctx, grn_io *io)
{
if (io->fis && (io->flags & (GRN_IO_EXPIRE_GTICK|GRN_IO_EXPIRE_SEGMENT))) {
grn_bool succeeded = GRN_FALSE;
@@ -227,14 +271,14 @@ grn_io_register(grn_io *io)
}
CRITICAL_SECTION_LEAVE(grn_glock);
if (!succeeded) {
- GRN_LOG(&grn_gctx, GRN_LOG_WARNING,
+ GRN_LOG(ctx, GRN_LOG_WARNING,
"grn_io_register(%s) failed", io->path);
}
}
}
static void
-grn_io_unregister(grn_io *io)
+grn_io_unregister(grn_ctx *ctx, grn_io *io)
{
if (io->fis && (io->flags & (GRN_IO_EXPIRE_GTICK|GRN_IO_EXPIRE_SEGMENT))) {
grn_bool succeeded = GRN_FALSE;
@@ -246,15 +290,16 @@ grn_io_unregister(grn_io *io)
}
CRITICAL_SECTION_LEAVE(grn_glock);
if (!succeeded) {
- GRN_LOG(&grn_gctx, GRN_LOG_WARNING,
+ GRN_LOG(ctx, GRN_LOG_WARNING,
"grn_io_unregister(%s) failed", io->path);
}
}
}
grn_io *
-grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t segment_size,
- uint32_t max_segment, grn_io_mode mode, uint32_t flags)
+grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size,
+ uint32_t segment_size, uint32_t max_segment, grn_io_mode mode,
+ uint32_t flags)
{
grn_io *io;
fileinfo *fis;
@@ -265,7 +310,8 @@ grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t seg
unsigned long file_size;
if (!path) {
- return grn_io_create_tmp(header_size, segment_size, max_segment, mode, flags);
+ return grn_io_create_tmp(ctx, header_size, segment_size, max_segment,
+ mode, flags);
}
if (!*path || (strlen(path) > PATH_MAX - 4)) { return NULL; }
b = grn_io_compute_base(header_size);
@@ -273,10 +319,10 @@ grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t seg
file_size = grn_io_compute_file_size(version);
max_nfiles = grn_io_compute_max_n_files(segment_size, max_segment,
bs, file_size);
- if ((fis = GRN_GMALLOCN(fileinfo, max_nfiles))) {
+ if ((fis = GRN_MALLOCN(fileinfo, max_nfiles))) {
grn_fileinfo_init(fis, max_nfiles);
if (!grn_fileinfo_open(ctx, fis, path, O_RDWR|O_CREAT|O_EXCL)) {
- header = (struct _grn_io_header *)GRN_MMAP(&grn_gctx, NULL,
+ header = (struct _grn_io_header *)GRN_MMAP(ctx, &grn_gctx, NULL,
&fis->fmo, fis, 0, b);
if (header) {
header->version = version;
@@ -287,10 +333,10 @@ grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t seg
header->flags = flags;
header->lock = 0;
grn_memcpy(header->idstr, GRN_IO_IDSTR, 16);
- grn_msync(ctx, header, b);
- if ((io = GRN_GMALLOCN(grn_io, 1))) {
+ GRN_MSYNC(ctx, fis[0].fh, header, b);
+ if ((io = GRN_MALLOCN(grn_io, 1))) {
grn_io_mapinfo *maps = NULL;
- if ((maps = GRN_GCALLOC(sizeof(grn_io_mapinfo) * max_segment))) {
+ if ((maps = GRN_CALLOC(sizeof(grn_io_mapinfo) * max_segment))) {
grn_strncpy(io->path, PATH_MAX, path, PATH_MAX);
io->header = header;
io->user_header = (((byte *) header) + IO_HEADER_SIZE);
@@ -306,35 +352,35 @@ grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t seg
io->count = 0;
io->flags = flags;
io->lock = &header->lock;
- grn_io_register(io);
+ grn_io_register(ctx, io);
return io;
}
- GRN_GFREE(io);
+ GRN_FREE(io);
}
- GRN_MUNMAP(&grn_gctx, NULL, &fis->fmo, fis, header, b);
+ GRN_MUNMAP(ctx, &grn_gctx, NULL, &fis->fmo, fis, header, b);
}
grn_fileinfo_close(ctx, fis);
- if (grn_unlink(path) == -1) {
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to grn_unlink() path on grn_io_create() error: "
- "<%s>: <%s>",
- path, grn_strerror(errno));
+ if (grn_unlink(path) == 0) {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[io][create][error] removed path: <%s>", path);
+ } else {
+ ERRNO_ERR("[io][create][error] failed to remove path: <%s>", path);
}
}
- GRN_GFREE(fis);
+ GRN_FREE(fis);
}
return NULL;
}
static grn_rc
-array_init_(grn_io *io, int n_arrays, size_t hsize, size_t msize)
+array_init_(grn_ctx *ctx, grn_io *io, int n_arrays, size_t hsize, size_t msize)
{
int i;
uint32_t ws;
byte *hp, *mp;
grn_io_array_spec *array_specs = (grn_io_array_spec *)io->user_header;
hp = io->user_header;
- if (!(mp = GRN_GCALLOC(msize))) {
+ if (!(mp = GRN_CALLOC(msize))) {
return GRN_NO_MEMORY_AVAILABLE;
}
io->ainfo = (grn_io_array_info *)mp;
@@ -357,7 +403,7 @@ array_init_(grn_io *io, int n_arrays, size_t hsize, size_t msize)
}
static grn_rc
-array_init(grn_io *io, int n_arrays)
+array_init(grn_ctx *ctx, grn_io *io, int n_arrays)
{
if (n_arrays) {
int i;
@@ -368,7 +414,7 @@ array_init(grn_io *io, int n_arrays)
hsize += sizeof(uint32_t) * array_specs[i].max_n_segments;
msize += sizeof(void *) * array_specs[i].max_n_segments;
}
- return array_init_(io, n_arrays, hsize, msize);
+ return array_init_(ctx, io, n_arrays, hsize, msize);
}
return GRN_SUCCESS;
}
@@ -376,7 +422,8 @@ array_init(grn_io *io, int n_arrays)
grn_io *
grn_io_create_with_array(grn_ctx *ctx, const char *path,
uint32_t header_size, uint32_t segment_size,
- grn_io_mode mode, int n_arrays, grn_io_array_spec *array_specs)
+ grn_io_mode mode, int n_arrays,
+ grn_io_array_spec *array_specs)
{
if (n_arrays) {
int i;
@@ -392,11 +439,13 @@ grn_io_create_with_array(grn_ctx *ctx, const char *path,
}
if ((io = grn_io_create(ctx, path, header_size + hsize,
segment_size, nsegs, mode, GRN_IO_EXPIRE_GTICK))) {
+ grn_rc rc;
hp = io->user_header;
grn_memcpy(hp, array_specs, sizeof(grn_io_array_spec) * n_arrays);
io->header->n_arrays = n_arrays;
io->header->segment_tail = 1;
- if (!array_init_(io, n_arrays, hsize, msize)) {
+ rc = array_init_(ctx, io, n_arrays, hsize, msize);
+ if (rc == GRN_SUCCESS) {
return io;
}
ERR(GRN_NO_MEMORY_AVAILABLE, "grn_io_create_with_array failed");
@@ -407,7 +456,7 @@ grn_io_create_with_array(grn_ctx *ctx, const char *path,
}
inline static uint32_t
-segment_alloc(grn_io *io)
+segment_alloc(grn_ctx *ctx, grn_io *io)
{
uint32_t n, s;
grn_io_array_info *ai;
@@ -418,7 +467,7 @@ segment_alloc(grn_io *io)
s = io->header->segment_tail++;
}
} else {
- char *used = GRN_GCALLOC(io->header->max_segment + 1);
+ char *used = GRN_CALLOC(io->header->max_segment + 1);
if (!used) { return 0; }
for (n = io->header->n_arrays, ai = io->ainfo; n; n--, ai++) {
for (s = 0; s < ai->max_n_segments; s++) {
@@ -436,18 +485,19 @@ segment_alloc(grn_io *io)
break;
}
}
- GRN_GFREE(used);
+ GRN_FREE(used);
}
return s;
}
void
-grn_io_segment_alloc(grn_ctx *ctx, grn_io *io, grn_io_array_info *ai, uint32_t lseg, int *flags, void **p)
+grn_io_segment_alloc(grn_ctx *ctx, grn_io *io, grn_io_array_info *ai,
+ uint32_t lseg, int *flags, void **p)
{
uint32_t *sp = &ai->segments[lseg];
if (!*sp) {
if ((*flags & GRN_TABLE_ADD)) {
- if ((*sp = segment_alloc(io))) {
+ if ((*sp = segment_alloc(ctx, io))) {
*flags |= GRN_TABLE_ADDED;
}
}
@@ -473,11 +523,12 @@ grn_io_detect_type(grn_ctx *ctx, const char *path)
struct _grn_io_header h;
uint32_t res = 0;
int fd;
- grn_open(fd, path, O_RDWR | GRN_OPEN_FLAG_BINARY);
+ grn_open(fd, path, O_RDONLY | GRN_OPEN_FLAG_BINARY);
if (fd != -1) {
struct stat s;
if (fstat(fd, &s) != -1 && s.st_size >= sizeof(struct _grn_io_header)) {
- if (grn_read(fd, &h, sizeof(struct _grn_io_header)) == sizeof(struct _grn_io_header)) {
+ if (grn_read(fd, &h, sizeof(struct _grn_io_header)) ==
+ sizeof(struct _grn_io_header)) {
if (!memcmp(h.idstr, GRN_IO_IDSTR, GRN_IO_IDSTR_LEN)) {
res = h.type;
} else {
@@ -487,20 +538,16 @@ grn_io_detect_type(grn_ctx *ctx, const char *path)
(int)GRN_IO_IDSTR_LEN, GRN_IO_IDSTR);
}
} else {
- SERR(path);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to read enough data for detecting type: <%s>",
- path);
+ SERR("failed to read enough data for detecting type: <%s>",
+ path);
}
} else {
ERR(GRN_INVALID_FORMAT, "grn_io_detect_type failed");
}
grn_close(fd);
} else {
- ERRNO_ERR(path);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to open path for detecting type: <%s>",
- path);
+ ERRNO_ERR("failed to open path for detecting type: <%s>",
+ path);
}
return res;
}
@@ -508,48 +555,88 @@ grn_io_detect_type(grn_ctx *ctx, const char *path)
grn_io *
grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode)
{
+ size_t max_path_len = PATH_MAX - 4;
grn_io *io;
struct stat s;
fileinfo fi;
uint32_t flags = 0;
uint32_t b;
uint32_t header_size = 0, segment_size = 0, max_segment = 0, bs;
- if (!path || !*path || (strlen(path) > PATH_MAX - 4)) { return NULL; }
+ if (!path || !*path) {
+ ERR(GRN_INVALID_ARGUMENT, "[io][open] path is missing");
+ return NULL;
+ }
+ if ((strlen(path) > max_path_len)) {
+ int truncate_length = 10;
+ ERR(GRN_INVALID_ARGUMENT,
+ "[io][open] path is too long: "
+ "<%" GRN_FMT_SIZE ">(max: %" GRN_FMT_SIZE "): <%.*s...>",
+ strlen(path),
+ max_path_len,
+ truncate_length,
+ path);
+ return NULL;
+ }
{
struct _grn_io_header h;
int fd;
+ ssize_t read_bytes;
grn_open(fd, path, O_RDWR | GRN_OPEN_FLAG_BINARY);
if (fd == -1) {
- ERRNO_ERR(path);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to open path: <%s>",
- path);
+ ERRNO_ERR("failed to open path: <%s>",
+ path);
return NULL;
}
- if (fstat(fd, &s) != -1 && s.st_size >= sizeof(struct _grn_io_header)) {
- if (grn_read(fd, &h, sizeof(struct _grn_io_header)) == sizeof(struct _grn_io_header)) {
- if (!memcmp(h.idstr, GRN_IO_IDSTR, GRN_IO_IDSTR_LEN)) {
- header_size = h.header_size;
- segment_size = h.segment_size;
- max_segment = h.max_segment;
- flags = h.flags;
- } else {
- ERR(GRN_INCOMPATIBLE_FILE_FORMAT,
- "failed to open: format ID is different: <%s>: <%.*s>",
- path,
- (int)GRN_IO_IDSTR_LEN, GRN_IO_IDSTR);
- }
- }
+ if (fstat(fd, &s) == -1) {
+ ERRNO_ERR("[io][open] failed to file status: <%s>",
+ path);
+ grn_close(fd);
+ return NULL;
}
+ if (s.st_size < sizeof(struct _grn_io_header)) {
+ ERR(GRN_INCOMPATIBLE_FILE_FORMAT,
+ "[io][open] file size is too small: "
+ "<%" GRN_FMT_INT64D ">(required: >= %" GRN_FMT_SIZE "): <%s>",
+ (int64_t)(s.st_size),
+ sizeof(struct _grn_io_header),
+ path);
+ grn_close(fd);
+ return NULL;
+ }
+ read_bytes = grn_read(fd, &h, sizeof(struct _grn_io_header));
+ if (read_bytes != sizeof(struct _grn_io_header)) {
+ ERRNO_ERR("[io][open] failed to read header data: "
+ "<%" GRN_FMT_SSIZE ">(expected: %" GRN_FMT_SSIZE "): <%s>",
+ read_bytes,
+ sizeof(struct _grn_io_header),
+ path);
+ grn_close(fd);
+ return NULL;
+ }
+ if (memcmp(h.idstr, GRN_IO_IDSTR, GRN_IO_IDSTR_LEN) != 0) {
+ ERR(GRN_INCOMPATIBLE_FILE_FORMAT,
+ "failed to open: format ID is different: <%s>: <%.*s>",
+ path,
+ (int)GRN_IO_IDSTR_LEN, GRN_IO_IDSTR);
+ grn_close(fd);
+ return NULL;
+ }
+ header_size = h.header_size;
+ segment_size = h.segment_size;
+ max_segment = h.max_segment;
+ flags = h.flags;
grn_close(fd);
- if (!segment_size) { return NULL; }
+ if (segment_size == 0) {
+ ERR(GRN_INCOMPATIBLE_FILE_FORMAT, "failed to open: segment size is 0");
+ return NULL;
+ }
}
b = grn_io_compute_base(header_size);
bs = grn_io_compute_base_segment(b, segment_size);
grn_fileinfo_init(&fi, 1);
if (!grn_fileinfo_open(ctx, &fi, path, O_RDWR)) {
struct _grn_io_header *header;
- header = GRN_MMAP(&grn_gctx, NULL, &(fi.fmo), &fi, 0, b);
+ header = GRN_MMAP(ctx, &grn_gctx, NULL, &(fi.fmo), &fi, 0, b);
if (header) {
unsigned long file_size;
unsigned int max_nfiles;
@@ -558,17 +645,17 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode)
file_size = grn_io_compute_file_size(header->version);
max_nfiles = grn_io_compute_max_n_files(segment_size, max_segment,
bs, file_size);
- fis = GRN_GMALLOCN(fileinfo, max_nfiles);
+ fis = GRN_MALLOCN(fileinfo, max_nfiles);
if (!fis) {
- GRN_MUNMAP(&grn_gctx, NULL, &(fi.fmo), &fi, header, b);
+ GRN_MUNMAP(ctx, &grn_gctx, NULL, &(fi.fmo), &fi, header, b);
grn_fileinfo_close(ctx, &fi);
return NULL;
}
grn_fileinfo_init(fis, max_nfiles);
grn_memcpy(fis, &fi, sizeof(fileinfo));
- if ((io = GRN_GMALLOC(sizeof(grn_io)))) {
+ if ((io = GRN_MALLOC(sizeof(grn_io)))) {
grn_io_mapinfo *maps = NULL;
- if ((maps = GRN_GCALLOC(sizeof(grn_io_mapinfo) * max_segment))) {
+ if ((maps = GRN_CALLOC(sizeof(grn_io_mapinfo) * max_segment))) {
grn_strncpy(io->path, PATH_MAX, path, PATH_MAX);
io->header = header;
io->user_header = (((byte *) header) + IO_HEADER_SIZE);
@@ -584,17 +671,17 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode)
io->count = 0;
io->flags = header->flags;
io->lock = &header->lock;
- if (!array_init(io, io->header->n_arrays)) {
- grn_io_register(io);
+ if (!array_init(ctx, io, io->header->n_arrays)) {
+ grn_io_register(ctx, io);
return io;
}
}
- if (io->maps) { GRN_GFREE(io->maps); }
+ if (io->maps) { GRN_FREE(io->maps); }
}
- GRN_GFREE(io);
+ GRN_FREE(io);
}
- GRN_GFREE(fis);
- GRN_MUNMAP(&grn_gctx, NULL, &(fi.fmo), &fi, header, b);
+ GRN_FREE(fis);
+ GRN_MUNMAP(ctx, &grn_gctx, NULL, &(fi.fmo), &fi, header, b);
}
grn_fileinfo_close(ctx, &fi);
}
@@ -607,8 +694,8 @@ grn_io_close(grn_ctx *ctx, grn_io *io)
uint32_t max_nfiles;
max_nfiles = grn_io_max_n_files(io);
- grn_io_unregister(io);
- if (io->ainfo) { GRN_GFREE(io->ainfo); }
+ grn_io_unregister(ctx, io);
+ if (io->ainfo) { GRN_FREE(io->ainfo); }
if (io->maps) {
int i;
uint32_t max_segment;
@@ -631,12 +718,12 @@ grn_io_close(grn_ctx *ctx, grn_io *io)
uint32_t fno = bseg / segments_per_file;
fi = &io->fis[fno];
}
- GRN_MUNMAP(&grn_gctx, io, &mi->fmo, fi, mi->map, segment_size);
+ GRN_MUNMAP(ctx, &grn_gctx, io, &mi->fmo, fi, mi->map, segment_size);
}
}
- GRN_GFREE(io->maps);
+ GRN_FREE(io->maps);
}
- GRN_MUNMAP(&grn_gctx, io, (io->fis ? &io->fis->fmo : NULL),
+ GRN_MUNMAP(ctx, &grn_gctx, io, (io->fis ? &io->fis->fmo : NULL),
io->fis, io->header, io->base);
if (io->fis) {
int i;
@@ -644,9 +731,9 @@ grn_io_close(grn_ctx *ctx, grn_io *io)
fileinfo *fi = &(io->fis[i]);
grn_fileinfo_close(ctx, fi);
}
- GRN_GFREE(io->fis);
+ GRN_FREE(io->fis);
}
- GRN_GFREE(io);
+ GRN_FREE(io);
return GRN_SUCCESS;
}
@@ -699,6 +786,14 @@ gen_pathname(const char *path, char *buffer, int fno)
}
}
+static uint32_t
+grn_io_n_files(grn_ctx *ctx, grn_io *io)
+{
+ unsigned long file_size;
+ file_size = grn_io_compute_file_size(io->header->version);
+ return ((io->header->curr_size + file_size - 1) / file_size);
+}
+
grn_rc
grn_io_size(grn_ctx *ctx, grn_io *io, uint64_t *size)
{
@@ -706,22 +801,14 @@ grn_io_size(grn_ctx *ctx, grn_io *io, uint64_t *size)
struct stat s;
uint64_t tsize = 0;
char buffer[PATH_MAX];
- uint32_t nfiles;
+ uint32_t n_files;
- if (io->header->curr_size) {
- unsigned long file_size;
- file_size = grn_io_compute_file_size(io->header->version);
- nfiles = (uint32_t) ((io->header->curr_size + file_size - 1) / file_size);
- } else {
- nfiles = grn_io_max_n_files(io);
- }
- for (fno = 0; fno < nfiles; fno++) {
+ n_files = grn_io_n_files(ctx, io);
+ for (fno = 0; fno < n_files; fno++) {
gen_pathname(io->path, buffer, fno);
if (stat(buffer, &s)) {
- SERR(buffer);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to stat path to compute size: <%s>",
- buffer);
+ SERR("failed to stat path to compute size: <%s>",
+ buffer);
} else {
tsize += s.st_size;
}
@@ -731,36 +818,58 @@ grn_io_size(grn_ctx *ctx, grn_io *io, uint64_t *size)
}
grn_rc
+grn_io_remove_raw(grn_ctx *ctx, const char *path)
+{
+ grn_rc rc = GRN_SUCCESS;
+ int fno;
+ char buffer[PATH_MAX];
+
+ if (grn_unlink(path) != 0) {
+ ERRNO_ERR("[io][remove] failed to remove path: <%s>",
+ path);
+ return ctx->rc;
+ }
+ GRN_LOG(ctx, GRN_LOG_INFO, "[io][remove] removed path: <%s>", path);
+
+ for (fno = 1; ; fno++) {
+ struct stat s;
+ gen_pathname(path, buffer, fno);
+ if (stat(buffer, &s) != 0) {
+ break;
+ }
+ if (grn_unlink(buffer) == 0) {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[io][remove] removed numbered path: <%d>: <%s>", fno, buffer);
+ } else {
+ ERRNO_ERR("[io][remove] failed to remove numbered path: <%d>: <%s>",
+ fno, buffer);
+ rc = ctx->rc;
+ }
+ }
+ return rc;
+}
+
+grn_rc
grn_io_remove(grn_ctx *ctx, const char *path)
{
struct stat s;
- if (stat(path, &s)) {
- SERR("stat");
- return ctx->rc;
- } else if (grn_unlink(path)) {
- ERRNO_ERR(path);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to remove path: <%s>",
- path);
+
+ if (stat(path, &s) != 0) {
+ SERR("failed to stat: <%s>", path);
return ctx->rc;
- } else {
- int fno;
- char buffer[PATH_MAX];
- for (fno = 1; ; fno++) {
- gen_pathname(path, buffer, fno);
- if (!stat(buffer, &s)) {
- if (grn_unlink(buffer)) {
- ERRNO_ERR(buffer);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to remove path: <%s>",
- buffer);
- }
- } else {
- break;
- }
- }
- return GRN_SUCCESS;
}
+
+ return grn_io_remove_raw(ctx, path);
+}
+
+grn_rc
+grn_io_remove_if_exist(grn_ctx *ctx, const char *path)
+{
+ struct stat s;
+ if (stat(path, &s) == 0) {
+ return grn_io_remove_raw(ctx, path);
+ }
+ return GRN_SUCCESS;
}
grn_rc
@@ -768,13 +877,11 @@ grn_io_rename(grn_ctx *ctx, const char *old_name, const char *new_name)
{
struct stat s;
if (stat(old_name, &s)) {
- SERR("stat");
+ SERR("failed to stat path to be renamed: <%s>", old_name);
return ctx->rc;
} else if (rename(old_name, new_name)) {
- SERR(old_name);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to rename path: <%s> -> <%s>",
- old_name, new_name);
+ SERR("failed to rename path: <%s> -> <%s>",
+ old_name, new_name);
return ctx->rc;
} else {
int fno;
@@ -785,16 +892,12 @@ grn_io_rename(grn_ctx *ctx, const char *old_name, const char *new_name)
if (!stat(old_buffer, &s)) {
gen_pathname(new_name, new_buffer, fno);
if (rename(old_buffer, new_buffer)) {
- SERR(old_buffer);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to rename path: <%s> -> <%s>",
- old_buffer, new_buffer);
+ SERR("failed to rename path: <%s> -> <%s>",
+ old_buffer, new_buffer);
}
} else {
- SERR("stat");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to stat path to rename: <%s>",
- old_buffer);
+ SERR("failed to stat path to be renamed: <%s>",
+ old_buffer);
return ctx->rc;
}
}
@@ -808,8 +911,9 @@ typedef struct {
} ja_element;
grn_rc
-grn_io_read_ja(grn_io *io, grn_ctx *ctx, grn_io_ja_einfo *einfo, uint32_t epos, uint32_t key,
- uint32_t segment, uint32_t offset, void **value, uint32_t *value_len)
+grn_io_read_ja(grn_io *io, grn_ctx *ctx, grn_io_ja_einfo *einfo, uint32_t epos,
+ uint32_t key, uint32_t segment, uint32_t offset, void **value,
+ uint32_t *value_len)
{
uint32_t rest = 0, size = *value_len + sizeof(grn_io_ja_ehead);
uint32_t segment_size = io->header->segment_size;
@@ -847,28 +951,32 @@ grn_io_read_ja(grn_io *io, grn_ctx *ctx, grn_io_ja_einfo *einfo, uint32_t epos,
return ctx->rc;
}
if (einfo->pos != epos) {
- GRN_LOG(ctx, GRN_LOG_WARNING, "einfo pos changed %x => %x", einfo->pos, epos);
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "einfo pos changed %x => %x", einfo->pos, epos);
*value = NULL;
*value_len = 0;
GRN_FREE(v);
return GRN_FILE_CORRUPT;
}
if (einfo->size != *value_len) {
- GRN_LOG(ctx, GRN_LOG_WARNING, "einfo size changed %d => %d", einfo->size, *value_len);
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "einfo size changed %d => %d", einfo->size, *value_len);
*value = NULL;
*value_len = 0;
GRN_FREE(v);
return GRN_FILE_CORRUPT;
}
if (v->head.key != key) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "ehead key unmatch %x => %x", key, v->head.key);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "ehead key unmatch %x => %x", key, v->head.key);
*value = NULL;
*value_len = 0;
GRN_FREE(v);
return GRN_INVALID_FORMAT;
}
if (v->head.size != *value_len) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "ehead size unmatch %d => %d", *value_len, v->head.size);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "ehead size unmatch %d => %d", *value_len, v->head.size);
*value = NULL;
*value_len = 0;
GRN_FREE(v);
@@ -905,7 +1013,8 @@ grn_io_read_ja(grn_io *io, grn_ctx *ctx, grn_io_ja_einfo *einfo, uint32_t epos,
grn_rc
grn_io_write_ja(grn_io *io, grn_ctx *ctx, uint32_t key,
- uint32_t segment, uint32_t offset, void *value, uint32_t value_len)
+ uint32_t segment, uint32_t offset, void *value,
+ uint32_t value_len)
{
grn_rc rc;
uint32_t rest = 0, size = value_len + sizeof(grn_io_ja_ehead);
@@ -936,7 +1045,9 @@ grn_io_write_ja(grn_io *io, grn_ctx *ctx, uint32_t key,
grn_io_ja_ehead eh;
eh.size = value_len;
eh.key = key;
- if ((rc = grn_pwrite(ctx, fi, &eh, sizeof(grn_io_ja_ehead), pos))) { return rc; }
+ if ((rc = grn_pwrite(ctx, fi, &eh, sizeof(grn_io_ja_ehead), pos))) {
+ return rc;
+ }
pos += sizeof(grn_io_ja_ehead);
rc = grn_pwrite(ctx, fi, value, size - sizeof(grn_io_ja_ehead), pos);
}
@@ -948,7 +1059,9 @@ grn_io_write_ja(grn_io *io, grn_ctx *ctx, uint32_t key,
if (!grn_fileinfo_opened(fi)) {
char path[PATH_MAX];
gen_pathname(io->path, path, fno);
- if ((rc = grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT))) { return rc; }
+ if ((rc = grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT))) {
+ return rc;
+ }
}
size = rest > file_size ? file_size : rest;
if ((rc = grn_pwrite(ctx, fi, vr, size, 0))) { return rc; }
@@ -995,7 +1108,9 @@ grn_io_win_map(grn_io *io, grn_ctx *ctx, grn_io_win *iw, uint32_t segment,
offset = offset % segment_size;
}
nseg = (offset + size + segment_size - 1) / segment_size;
- if (!size || !ctx || segment + nseg > io->header->max_segment) { return NULL; }
+ if (!size || !ctx || segment + nseg > io->header->max_segment) {
+ return NULL;
+ }
iw->ctx = ctx;
iw->diff = 0;
iw->io = io;
@@ -1063,7 +1178,8 @@ grn_io_win_unmap(grn_io_win *iw)
byte *p, *q = NULL;
uint32_t segment_size = io->header->segment_size;
uint32_t s, r, offset = iw->offset, segment = iw->segment;
- for (p = iw->addr, r = iw->size; r; p += s, r -= s, segment++, offset = 0) {
+ for (p = iw->addr, r = iw->size; r;
+ p += s, r -= s, segment++, offset = 0) {
GRN_IO_SEG_REF(io, segment, q);
if (!q) { return GRN_NO_MEMORY_AVAILABLE; }
s = (offset + r > segment_size) ? segment_size - offset : r;
@@ -1080,7 +1196,8 @@ grn_io_win_unmap(grn_io_win *iw)
}
#define DO_MAP(io,fmo,fi,pos,size,segno,res) do {\
- if (((res) = GRN_MMAP(&grn_gctx, (io), (fmo), (fi), (pos), (size)))) {\
+ (res) = GRN_MMAP(ctx, &grn_gctx, (io), (fmo), (fi), (pos), (size));\
+ if ((res)) {\
uint32_t nmaps;\
if (io->max_map_seg < segno) { io->max_map_seg = segno; }\
GRN_ATOMIC_ADD_EX(&io->nmaps, 1, nmaps);\
@@ -1107,9 +1224,21 @@ grn_io_seg_map_(grn_ctx *ctx, grn_io *io, uint32_t segno, grn_io_mapinfo *info)
fileinfo *fi = &io->fis[fno];
if (!grn_fileinfo_opened(fi)) {
char path[PATH_MAX];
+ grn_bool path_exist = GRN_TRUE;
gen_pathname(io->path, path, fno);
+ path_exist = grn_path_exist(path);
if (!grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT)) {
DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map);
+ if (!info->map && !path_exist) {
+ if (grn_unlink(path) == 0) {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[io][map][error] memory mapping is failed and then "
+ "removed created map file: <%s>", path);
+ } else {
+ ERRNO_ERR("[io][map][error] memory mapping is failed and then "
+ "failed to remove created map file: <%s>", path);
+ }
+ }
}
} else {
DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map);
@@ -1132,7 +1261,9 @@ grn_io_seg_expire(grn_ctx *ctx, grn_io *io, uint32_t segno, uint32_t nretry)
if (nref) {
GRN_ATOMIC_ADD_EX(pnref, -1, nref);
if (retry >= GRN_IO_MAX_RETRY) {
- GRN_LOG(ctx, GRN_LOG_CRIT, "deadlock detected! in grn_io_seg_expire(%p, %u, %u)", io, segno, nref);
+ GRN_LOG(ctx, GRN_LOG_CRIT,
+ "deadlock detected! in grn_io_seg_expire(%p, %u, %u)",
+ io, segno, nref);
return GRN_RESOURCE_DEADLOCK_AVOIDED;
}
} else {
@@ -1141,14 +1272,15 @@ grn_io_seg_expire(grn_ctx *ctx, grn_io *io, uint32_t segno, uint32_t nretry)
GRN_ATOMIC_ADD_EX(pnref, -(GRN_IO_MAX_REF + 1), nref);
GRN_FUTEX_WAKE(pnref);
if (retry >= GRN_IO_MAX_RETRY) {
- GRN_LOG(ctx, GRN_LOG_CRIT, "deadlock detected!! in grn_io_seg_expire(%p, %u, %u)", io,
- segno, nref);
+ GRN_LOG(ctx, GRN_LOG_CRIT,
+ "deadlock detected!! in grn_io_seg_expire(%p, %u, %u)",
+ io, segno, nref);
return GRN_RESOURCE_DEADLOCK_AVOIDED;
}
} else {
uint32_t nmaps;
fileinfo *fi = &(io->fis[segno]);
- GRN_MUNMAP(&grn_gctx, io, &info->fmo, fi,
+ GRN_MUNMAP(ctx, &grn_gctx, io, &info->fmo, fi,
info->map, io->header->segment_size);
info->map = NULL;
GRN_ATOMIC_ADD_EX(pnref, -(GRN_IO_MAX_REF + 1), nref);
@@ -1176,7 +1308,8 @@ grn_io_expire(grn_ctx *ctx, grn_io *io, int count_thresh, uint32_t limit)
uint32_t i = io->header->n_arrays;
grn_io_array_spec *array_specs = (grn_io_array_spec *)io->user_header;
while (i--) {
- memset(io->ainfo[i].addrs, 0, sizeof(void *) * array_specs[i].max_n_segments);
+ memset(io->ainfo[i].addrs, 0,
+ sizeof(void *) * array_specs[i].max_n_segments);
}
}
{
@@ -1185,7 +1318,7 @@ grn_io_expire(grn_ctx *ctx, grn_io *io, int count_thresh, uint32_t limit)
grn_io_mapinfo *info = &(io->maps[fno]);
if (info->map) {
fileinfo *fi = &(io->fis[fno]);
- GRN_MUNMAP(&grn_gctx, io, &info->fmo, fi,
+ GRN_MUNMAP(ctx, &grn_gctx, io, &info->fmo, fi,
info->map, io->header->segment_size);
info->map = NULL;
info->nref = 0;
@@ -1212,7 +1345,7 @@ grn_io_expire(grn_ctx *ctx, grn_io *io, int count_thresh, uint32_t limit)
uint32_t nmaps, nref, *pnref = &info->nref;
GRN_ATOMIC_ADD_EX(pnref, 1, nref);
if (!nref && info->map && (grn_gtick - info->count) > count_thresh) {
- GRN_MUNMAP(&grn_gctx, io, &info->fmo, NULL,
+ GRN_MUNMAP(ctx, &grn_gctx, io, &info->fmo, NULL,
info->map, io->header->segment_size);
GRN_ATOMIC_ADD_EX(&io->nmaps, -1, nmaps);
info->map = NULL;
@@ -1226,58 +1359,22 @@ grn_io_expire(grn_ctx *ctx, grn_io *io, int count_thresh, uint32_t limit)
break;
}
if (n) {
- GRN_LOG(ctx, GRN_LOG_INFO, "<%p:%x> expired i=%p max=%d (%d/%d)",
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "<%p:%x> expired i=%p max=%d (%d/%d)",
ctx, grn_gtick, io, io->max_map_seg, n, ln);
}
return n;
}
-static uint32_t
-grn_expire_(grn_ctx *ctx, int count_thresh, uint32_t limit)
-{
- uint32_t n = 0;
- grn_io *io;
- GRN_HASH_EACH(ctx, grn_gctx.impl->ios, id, NULL, NULL, (void **)&io, {
- grn_plugin_close(ctx, id);
- n += grn_io_expire(ctx, io, count_thresh, limit);
- if (n >= limit) { break; }
- });
- return n;
-}
-
-uint32_t
-grn_expire(grn_ctx *ctx, int count_thresh, uint32_t limit)
-{
- grn_ctx *c;
- uint32_t n = 0;
- CRITICAL_SECTION_ENTER(grn_glock);
- if (grn_gtick) {
- for (c = grn_gctx.next;; c = ctx->next) {
- if (c == &grn_gctx) {
- CRITICAL_SECTION_LEAVE(grn_glock);
- n = grn_expire_(ctx, count_thresh, limit);
- CRITICAL_SECTION_ENTER(grn_glock);
- break;
- }
- if ((c->seqno & 1) && (c->seqno == c->seqno2)) { break; }
- }
- }
- grn_gtick++;
- for (c = grn_gctx.next; c != &grn_gctx; c = ctx->next) { c->seqno2 = c->seqno; }
- CRITICAL_SECTION_LEAVE(grn_glock);
- return n;
-}
-
void *
grn_io_anon_map(grn_ctx *ctx, grn_io_mapinfo *mi, size_t length)
{
- return (mi->map = GRN_MMAP(ctx, NULL, &mi->fmo, NULL, 0, length));
+ return (mi->map = GRN_MMAP(ctx, ctx, NULL, &mi->fmo, NULL, 0, length));
}
void
grn_io_anon_unmap(grn_ctx *ctx, grn_io_mapinfo *mi, size_t length)
{
- GRN_MUNMAP(ctx, NULL, &mi->fmo, NULL, mi->map, length);
+ GRN_MUNMAP(ctx, ctx, NULL, &mi->fmo, NULL, mi->map, length);
}
grn_rc
@@ -1285,6 +1382,7 @@ grn_io_lock(grn_ctx *ctx, grn_io *io, int timeout)
{
static int _ncalls = 0, _ncolls = 0;
uint32_t count, count_log_border = 1000;
+ uint32_t rc_check_interval = 1000;
_ncalls++;
if (!io) { return GRN_INVALID_ARGUMENT; }
for (count = 0;; count++) {
@@ -1311,6 +1409,11 @@ grn_io_lock(grn_ctx *ctx, grn_io *io, int timeout)
"io(%s) collisions(%d/%d)", io->path, _ncolls, _ncalls);
}
}
+ if ((count % rc_check_interval) == 0) {
+ if (ctx->rc != GRN_SUCCESS) {
+ return ctx->rc;
+ }
+ }
grn_nanosleep(GRN_LOCK_WAIT_TIME_NANOSECOND);
continue;
}
@@ -1348,14 +1451,14 @@ grn_io_flush(grn_ctx *ctx, grn_io *io)
struct _grn_io_header *header;
uint32_t aligned_header_size;
- if (!io->path) {
+ if (io->path[0] == '\0') {
return GRN_SUCCESS;
}
header = io->header;
aligned_header_size = grn_io_compute_base(header->header_size);
- if (grn_msync(ctx, header, aligned_header_size) != 0) {
+ if (GRN_MSYNC(ctx, io->fis[0].fh, header, aligned_header_size) != 0) {
return ctx->rc;
}
@@ -1368,13 +1471,37 @@ grn_io_flush(grn_ctx *ctx, grn_io *io)
segment_size = header->segment_size;
for (i = 0; i < max_mapped_segment; i++) {
grn_io_mapinfo *info = &(io->maps[i]);
+ uint32_t nth_file_info;
+ uint32_t *pnref;
+ uint32_t nref;
+ int msync_result;
+
if (!info) {
continue;
}
+
+ pnref = &info->nref;
+ GRN_ATOMIC_ADD_EX(pnref, 1, nref);
+ if (nref != 0) {
+ GRN_ATOMIC_ADD_EX(pnref, -1, nref);
+ continue;
+ }
+
if (!info->map) {
+ GRN_ATOMIC_ADD_EX(pnref, -1, nref);
+ GRN_FUTEX_WAKE(pnref);
continue;
}
- if (grn_msync(ctx, info->map, segment_size) != 0) {
+
+ nth_file_info = grn_io_compute_nth_file_info(io, i);
+ msync_result = GRN_MSYNC(ctx,
+ io->fis[nth_file_info].fh,
+ info->map,
+ segment_size);
+ GRN_ATOMIC_ADD_EX(pnref, -1, nref);
+ GRN_FUTEX_WAKE(pnref);
+
+ if (msync_result != 0) {
rc = ctx->rc;
break;
}
@@ -1384,6 +1511,56 @@ grn_io_flush(grn_ctx *ctx, grn_io *io)
return rc;
}
+grn_bool
+grn_io_is_corrupt(grn_ctx *ctx, grn_io *io)
+{
+ uint32_t i;
+ uint32_t n_files;
+
+ if (!io) {
+ return GRN_FALSE;
+ }
+
+ n_files = grn_io_n_files(ctx, io);
+ for (i = 0; i < n_files; i++) {
+ char path[PATH_MAX];
+ struct stat s;
+ gen_pathname(io->path, path, i);
+ if (stat(path, &s) != 0) {
+ SERR("[io][corrupt] used path doesn't exist: <%s>",
+ path);
+ return GRN_TRUE;
+ }
+ }
+
+ return GRN_FALSE;
+}
+
+size_t
+grn_io_get_disk_usage(grn_ctx *ctx, grn_io *io)
+{
+ size_t usage = 0;
+ uint32_t i;
+ uint32_t n_files;
+
+ if (!io) {
+ return usage;
+ }
+
+ n_files = grn_io_n_files(ctx, io);
+ for (i = 0; i < n_files; i++) {
+ char path[PATH_MAX];
+ struct stat s;
+ gen_pathname(io->path, path, i);
+ if (stat(path, &s) != 0) {
+ continue;
+ }
+ usage += s.st_size;
+ }
+
+ return usage;
+}
+
/** mmap abstraction **/
static size_t mmap_size = 0;
@@ -1398,7 +1575,8 @@ grn_fileinfo_open_v1(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
}
inline static void *
-grn_mmap_v1(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi, off_t offset, size_t length)
+grn_mmap_v1(grn_ctx *ctx, grn_ctx *owner_ctx, HANDLE *fmo, fileinfo *fi,
+ off_t offset, size_t length)
{
void *res;
if (!fi) {
@@ -1409,26 +1587,22 @@ grn_mmap_v1(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi, off_t offset, size_t length
* If VirtualAlloc() provides better performance rather than malloc(),
* we'll use it.
*/
- return GRN_GCALLOC(length);
+ return GRN_CALLOC(length);
}
/* CRITICAL_SECTION_ENTER(fi->cs); */
/* try to create fmo */
*fmo = CreateFileMapping(fi->fh, NULL, PAGE_READWRITE, 0, offset + length, NULL);
if (!*fmo) {
- SERR("CreateFileMapping");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "CreateFileMapping(%lu + %" GRN_FMT_SIZE ") failed "
- "<%" GRN_FMT_SIZE ">",
- (DWORD)offset, length,
- mmap_size);
+ SERR("CreateFileMapping(%lu + %" GRN_FMT_SIZE ") failed "
+ "<%" GRN_FMT_SIZE ">",
+ (DWORD)offset, length,
+ mmap_size);
return NULL;
}
res = MapViewOfFile(*fmo, FILE_MAP_WRITE, 0, (DWORD)offset, (SIZE_T)length);
if (!res) {
- SERR("MapViewOfFile");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "MapViewOfFile(%lu,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
- (DWORD)offset, length, mmap_size);
+ SERR("MapViewOfFile(%lu,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
+ (DWORD)offset, length, mmap_size);
return NULL;
}
/* CRITICAL_SECTION_LEAVE(fi->cs); */
@@ -1437,18 +1611,18 @@ grn_mmap_v1(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi, off_t offset, size_t length
}
inline static int
-grn_munmap_v1(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi,
+grn_munmap_v1(grn_ctx *ctx, grn_ctx *owner_ctx, HANDLE *fmo, fileinfo *fi,
void *start, size_t length)
{
int r = 0;
if (!fi) {
- GRN_GFREE(start);
+ GRN_FREE(start);
return r;
}
if (!fmo) {
- GRN_GFREE(start);
+ GRN_FREE(start);
return r;
}
@@ -1456,21 +1630,17 @@ grn_munmap_v1(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi,
if (UnmapViewOfFile(start)) {
mmap_size -= length;
} else {
- SERR("UnmapViewOfFile");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "UnmapViewOfFile(%p,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
- start, length, mmap_size);
+ SERR("UnmapViewOfFile(%p,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
+ start, length, mmap_size);
r = -1;
}
if (!CloseHandle(*fmo)) {
- SERR("CloseHandle");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "CloseHandle(%p,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
- start, length, mmap_size);
+ SERR("CloseHandle(%p,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
+ start, length, mmap_size);
}
*fmo = NULL;
} else {
- GRN_GFREE(start);
+ GRN_FREE(start);
}
return r;
@@ -1489,7 +1659,8 @@ grn_fileinfo_open_v0(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
/* failed again */
if (fi->fmo == NULL) {
/* try to create fmo */
- fi->fmo = CreateFileMapping(fi->fh, NULL, PAGE_READWRITE, 0, GRN_IO_FILE_SIZE_V0, NULL);
+ fi->fmo = CreateFileMapping(fi->fh, NULL, PAGE_READWRITE, 0,
+ GRN_IO_FILE_SIZE_V0, NULL);
}
// funlock
}
@@ -1498,7 +1669,8 @@ grn_fileinfo_open_v0(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
CRITICAL_SECTION_INIT(fi->cs);
return GRN_SUCCESS;
} else {
- GRN_LOG(ctx, GRN_LOG_ERROR, "fmo object already exists! handle=%p", fi->fh);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "fmo object already exists! handle=%p", fi->fh);
CloseHandle(fi->fmo);
}
} else {
@@ -1511,10 +1683,11 @@ grn_fileinfo_open_v0(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
}
inline static void *
-grn_mmap_v0(grn_ctx *ctx, fileinfo *fi, off_t offset, size_t length)
+grn_mmap_v0(grn_ctx *ctx, grn_ctx *owner_ctx, fileinfo *fi, off_t offset,
+ size_t length)
{
void *res;
- if (!fi) { return GRN_GCALLOC(length); }
+ if (!fi) { return GRN_CALLOC(length); }
/* file must be exceeded to GRN_IO_FILE_SIZE_V0 when FileMappingObject created.
and, after fmo created, it's not allowed to expand the size of file.
DWORD tail = (DWORD)(offset + length);
@@ -1542,10 +1715,11 @@ grn_mmap_v0(grn_ctx *ctx, fileinfo *fi, off_t offset, size_t length)
}
inline static int
-grn_munmap_v0(grn_ctx *ctx, fileinfo *fi, void *start, size_t length)
+grn_munmap_v0(grn_ctx *ctx, grn_ctx *owner_ctx, fileinfo *fi, void *start,
+ size_t length)
{
if (!fi) {
- GRN_GFREE(start);
+ GRN_FREE(start);
return 0;
}
@@ -1553,10 +1727,8 @@ grn_munmap_v0(grn_ctx *ctx, fileinfo *fi, void *start, size_t length)
mmap_size -= length;
return 0;
} else {
- SERR("UnmapViewOfFile");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "UnmapViewOfFile(%p,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
- start, length, mmap_size);
+ SERR("UnmapViewOfFile(%p,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
+ start, length, mmap_size);
return -1;
}
}
@@ -1576,43 +1748,85 @@ grn_fileinfo_open_common(grn_ctx *ctx, fileinfo *fi, const char *path, int flags
flags_description = "O_RDWR|O_CREAT";
}
fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, 0);
if (fi->fh == INVALID_HANDLE_VALUE) {
- SERR("CreateFile");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "CreateFile(<%s>, <%s>) failed",
- path, flags_description);
+ SERR("CreateFile(<%s>, <%s>) failed",
+ path, flags_description);
goto exit;
}
+
+ switch (dwCreationDisposition) {
+ case CREATE_NEW :
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[io][open] create new file: <%s>", path);
+ break;
+ case OPEN_ALWAYS :
+ if (GetLastError() == ERROR_ALREADY_EXISTS) {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[io][open] open existing file because it exists: <%s>", path);
+ } else {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[io][open] create new file because it doesn't exist: <%s>",
+ path);
+ }
+ break;
+ default :
+ break;
+ }
+
+ if (grn_io_use_sparse) {
+ FILE_SET_SPARSE_BUFFER buffer;
+ buffer.SetSparse = TRUE;
+ DWORD returned_bytes;
+ if (!DeviceIoControl(fi->fh,
+ FSCTL_SET_SPARSE,
+ &buffer,
+ sizeof(FILE_SET_SPARSE_BUFFER),
+ NULL,
+ 0,
+ &returned_bytes,
+ NULL)) {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "Tried to make file sparse but failed: "
+ "DeviceIoControl(FSCTL_SET_SPARSE): "
+ "<%s>: <%s>",
+ path, grn_current_error_message());
+ }
+ }
+
goto exit;
}
+
if ((flags & O_TRUNC)) {
CloseHandle(fi->fh);
/* unable to assign OPEN_ALWAYS and TRUNCATE_EXISTING at once */
fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (fi->fh == INVALID_HANDLE_VALUE) {
- SERR("CreateFile");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "CreateFile(<%s>, <O_RDWR|O_TRUNC>) failed",
- path);
+ SERR("CreateFile(<%s>, <O_RDWR|O_TRUNC>) failed",
+ path);
goto exit;
}
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[io][open] truncated: <%s>", path);
goto exit;
}
/* O_RDWR only */
fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (fi->fh == INVALID_HANDLE_VALUE) {
- SERR("CreateFile");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "CreateFile(<%s>, <O_RDWR>) failed",
- path);
+ SERR("CreateFile(<%s>, <O_RDWR>) failed",
+ path);
goto exit;
}
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[io][open] open existing file: <%s>", path);
exit :
return ctx->rc;
@@ -1623,16 +1837,21 @@ grn_fileinfo_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
{
grn_rc rc;
struct _grn_io_header io_header;
- DWORD header_size;
- DWORD read_bytes;
+ LARGE_INTEGER file_size;
int version = grn_io_version_default;
rc = grn_fileinfo_open_common(ctx, fi, path, flags);
if (rc != GRN_SUCCESS) {
+ if (fi->fh) {
+ CloseHandle(fi->fh);
+ fi->fh = INVALID_HANDLE_VALUE;
+ }
return rc;
}
- if (!(flags & O_CREAT)) {
+ if (GetFileSizeEx(fi->fh, &file_size) && file_size.QuadPart > 0) {
+ DWORD header_size;
+ DWORD read_bytes;
header_size = sizeof(struct _grn_io_header);
ReadFile(fi->fh, &io_header, header_size, &read_bytes, NULL);
if (read_bytes == header_size) {
@@ -1667,7 +1886,7 @@ grn_guess_io_version(grn_ctx *ctx, grn_io *io, fileinfo *fi)
}
inline static void *
-grn_mmap(grn_ctx *ctx, grn_io *io, HANDLE *fmo,
+grn_mmap(grn_ctx *ctx, grn_ctx *owner_ctx, grn_io *io, HANDLE *fmo,
fileinfo *fi, off_t offset, size_t length)
{
int version;
@@ -1675,14 +1894,14 @@ grn_mmap(grn_ctx *ctx, grn_io *io, HANDLE *fmo,
version = grn_guess_io_version(ctx, io, fi);
if (version == 0) {
- return grn_mmap_v0(ctx, fi, offset, length);
+ return grn_mmap_v0(ctx, owner_ctx, fi, offset, length);
} else {
- return grn_mmap_v1(ctx, fmo, fi, offset, length);
+ return grn_mmap_v1(ctx, owner_ctx, fmo, fi, offset, length);
}
}
inline static int
-grn_munmap(grn_ctx *ctx, grn_io *io,
+grn_munmap(grn_ctx *ctx, grn_ctx *owner_ctx, grn_io *io,
HANDLE *fmo, fileinfo *fi, void *start, size_t length)
{
int version;
@@ -1690,9 +1909,9 @@ grn_munmap(grn_ctx *ctx, grn_io *io,
version = grn_guess_io_version(ctx, io, fi);
if (version == 0) {
- return grn_munmap_v0(ctx, fi, start, length);
+ return grn_munmap_v0(ctx, owner_ctx, fi, start, length);
} else {
- return grn_munmap_v1(ctx, fmo, fi, start, length);
+ return grn_munmap_v1(ctx, owner_ctx, fmo, fi, start, length);
}
}
@@ -1727,20 +1946,45 @@ grn_fileinfo_opened(fileinfo *fi)
}
inline static int
-grn_msync(grn_ctx *ctx, void *start, size_t length)
+grn_msync(grn_ctx *ctx, HANDLE handle, void *start, size_t length)
{
BOOL succeeded;
+ SYSTEMTIME system_time;
+ FILETIME file_time;
succeeded = FlushViewOfFile(start, length);
- if (succeeded) {
+ if (!succeeded) {
+ SERR("FlushViewOfFile(<%p>, <%" GRN_FMT_SIZE ">) failed",
+ start, length);
+ return -1;
+ }
+
+ if (handle == INVALID_HANDLE_VALUE) {
return 0;
- } else {
- SERR("FlushViewOfFile");
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "FlushViewOfFile(<%p>, <%" GRN_FMT_SIZE ">) failed",
- start, length);
+ }
+
+ GetSystemTime(&system_time);
+ succeeded = SystemTimeToFileTime(&system_time, &file_time);
+ if (!succeeded) {
+ SERR("SystemTimeToFileTime(<%04u-%02u-%02uT%02u:%02u:%02u.%03u>) failed",
+ system_time.wYear,
+ system_time.wMonth,
+ system_time.wDay,
+ system_time.wHour,
+ system_time.wMinute,
+ system_time.wSecond,
+ system_time.wMilliseconds);
return -1;
}
+
+ succeeded = SetFileTime(handle, NULL, NULL, &file_time);
+ if (!succeeded) {
+ SERR("SetFileTime(<%p>, <%p>, <%" GRN_FMT_SIZE ">) failed",
+ handle, start, length);
+ return -1;
+ }
+
+ return 0;
}
inline static grn_rc
@@ -1795,17 +2039,13 @@ grn_fileinfo_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
struct stat st;
grn_open(fi->fd, path, flags);
if (fi->fd == -1) {
- ERRNO_ERR(path);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to open file info path: <%s>",
- path);
+ ERRNO_ERR("failed to open file info path: <%s>",
+ path);
return ctx->rc;
}
if (fstat(fi->fd, &st) == -1) {
- ERRNO_ERR(path);
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "failed to stat file info path: <%s>",
- path);
+ ERRNO_ERR("failed to stat file info path: <%s>",
+ path);
return ctx->rc;
}
fi->dev = st.st_dev;
@@ -1845,7 +2085,8 @@ grn_fileinfo_close(grn_ctx *ctx, fileinfo *fi)
#include <sys/mman.h>
inline static void *
-grn_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi, off_t offset, size_t length)
+grn_mmap(grn_ctx *ctx, grn_ctx *owner_ctx, grn_io *io, fileinfo *fi,
+ off_t offset, size_t length)
{
void *res;
int fd, flags;
@@ -1865,8 +2106,8 @@ grn_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi, off_t offset, size_t length)
res = mmap(NULL, length, PROT_READ|PROT_WRITE, flags, fd, offset);
if (MAP_FAILED == res) {
MERR("mmap(%" GRN_FMT_LLU ",%d,%" GRN_FMT_LLD ")=%s <%" GRN_FMT_LLU ">",
- (unsigned long long int)length, fd, (long long int)offset, strerror(errno),
- (unsigned long long int)mmap_size);
+ (unsigned long long int)length, fd, (long long int)offset,
+ strerror(errno), (unsigned long long int)mmap_size);
return NULL;
}
mmap_size += length;
@@ -1875,7 +2116,7 @@ grn_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi, off_t offset, size_t length)
#ifdef USE_FAIL_MALLOC
inline static void *
-grn_fail_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi,
+grn_fail_mmap(grn_ctx *ctx, grn_ctx *owner_ctx, grn_io *io, fileinfo *fi,
off_t offset, size_t length,
const char* file, int line, const char *func)
{
@@ -1905,14 +2146,16 @@ grn_msync(grn_ctx *ctx, void *start, size_t length)
}
inline static int
-grn_munmap(grn_ctx *ctx, grn_io *io, fileinfo *fi, void *start, size_t length)
+grn_munmap(grn_ctx *ctx, grn_ctx *owner_ctx, grn_io *io, fileinfo *fi,
+ void *start, size_t length)
{
int res;
res = munmap(start, length);
if (res) {
- SERR("munmap");
- GRN_LOG(ctx, GRN_LOG_ERROR, "munmap(%p,%" GRN_FMT_LLU ") failed <%" GRN_FMT_LLU ">",
- start, (unsigned long long int)length, (unsigned long long int)mmap_size);
+ SERR("munmap(%p,%" GRN_FMT_LLU ") failed <%" GRN_FMT_LLU ">",
+ start,
+ (unsigned long long int)length,
+ (unsigned long long int)mmap_size);
} else {
mmap_size -= length;
}
@@ -1928,7 +2171,8 @@ grn_pread(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset)
SERR("pread");
} else {
/* todo : should retry ? */
- ERR(GRN_INPUT_OUTPUT_ERROR, "pread returned %" GRN_FMT_LLD " != %" GRN_FMT_LLU,
+ ERR(GRN_INPUT_OUTPUT_ERROR,
+ "pread returned %" GRN_FMT_LLD " != %" GRN_FMT_LLU,
(long long int)r, (unsigned long long int)count);
}
return ctx->rc;
@@ -1945,7 +2189,8 @@ grn_pwrite(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset)
SERR("pwrite");
} else {
/* todo : should retry ? */
- ERR(GRN_INPUT_OUTPUT_ERROR, "pwrite returned %" GRN_FMT_LLD " != %" GRN_FMT_LLU,
+ ERR(GRN_INPUT_OUTPUT_ERROR,
+ "pwrite returned %" GRN_FMT_LLD " != %" GRN_FMT_LLU,
(long long int)r, (unsigned long long int)count);
}
return ctx->rc;
diff --git a/storage/mroonga/vendor/groonga/lib/libgroonga.c b/storage/mroonga/vendor/groonga/lib/libgroonga.c
deleted file mode 100644
index 19e0941031d..00000000000
--- a/storage/mroonga/vendor/groonga/lib/libgroonga.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifdef WIN32
-#include <windows.h>
-
-BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void * reserve)
-{
- return TRUE;
-}
-#endif
diff --git a/storage/mroonga/vendor/groonga/lib/load.c b/storage/mroonga/vendor/groonga/lib/load.c
new file mode 100644
index 00000000000..ee0a1e2a045
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/load.c
@@ -0,0 +1,1229 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_load.h"
+#include "grn_ctx_impl.h"
+#include "grn_db.h"
+#include "grn_util.h"
+
+static void
+grn_loader_save_error(grn_ctx *ctx, grn_loader *loader)
+{
+ loader->rc = ctx->rc;
+ grn_strcpy(loader->errbuf, GRN_CTX_MSGSIZE, ctx->errbuf);
+}
+
+static grn_obj *
+values_add(grn_ctx *ctx, grn_loader *loader)
+{
+ grn_obj *res;
+ uint32_t curr_size = loader->values_size * sizeof(grn_obj);
+ if (curr_size < GRN_TEXT_LEN(&loader->values)) {
+ res = (grn_obj *)(GRN_TEXT_VALUE(&loader->values) + curr_size);
+ res->header.domain = GRN_DB_TEXT;
+ GRN_BULK_REWIND(res);
+ } else {
+ if (grn_bulk_space(ctx, &loader->values, sizeof(grn_obj))) { return NULL; }
+ res = (grn_obj *)(GRN_TEXT_VALUE(&loader->values) + curr_size);
+ GRN_TEXT_INIT(res, 0);
+ }
+ loader->values_size++;
+ loader->last = res;
+ return res;
+}
+
+static grn_obj *
+values_next(grn_ctx *ctx, grn_obj *value)
+{
+ if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET ||
+ value->header.domain == GRN_JSON_LOAD_OPEN_BRACE) {
+ value += GRN_UINT32_VALUE(value);
+ }
+ return value + 1;
+}
+
+static int
+values_len(grn_ctx *ctx, grn_obj *head, grn_obj *tail)
+{
+ int len;
+ for (len = 0; head < tail; head = values_next(ctx, head), len++) ;
+ return len;
+}
+
+static grn_id
+loader_add(grn_ctx *ctx, grn_obj *key)
+{
+ int added = 0;
+ grn_loader *loader = &ctx->impl->loader;
+ grn_id id = grn_table_add_by_key(ctx, loader->table, key, &added);
+ if (id == GRN_ID_NIL) {
+ grn_loader_save_error(ctx, loader);
+ return id;
+ }
+ if (!added && loader->ifexists) {
+ grn_obj *v = grn_expr_get_var_by_offset(ctx, loader->ifexists, 0);
+ grn_obj *result;
+ GRN_RECORD_SET(ctx, v, id);
+ result = grn_expr_exec(ctx, loader->ifexists, 0);
+ if (!grn_obj_is_true(ctx, result)) {
+ id = 0;
+ }
+ }
+ return id;
+}
+
+static void
+add_weight_vector(grn_ctx *ctx,
+ grn_obj *column,
+ grn_obj *value,
+ grn_obj *vector)
+{
+ unsigned int i, n;
+ grn_obj weight_buffer;
+
+ n = GRN_UINT32_VALUE(value);
+ GRN_UINT32_INIT(&weight_buffer, 0);
+ for (i = 0; i < n; i += 2) {
+ grn_rc rc;
+ grn_obj *key, *weight;
+
+ key = value + 1 + i;
+ weight = key + 1;
+
+ GRN_BULK_REWIND(&weight_buffer);
+ rc = grn_obj_cast(ctx, weight, &weight_buffer, GRN_TRUE);
+ if (rc != GRN_SUCCESS) {
+ grn_obj *range;
+ range = grn_ctx_at(ctx, weight_buffer.header.domain);
+ ERR_CAST(column, range, weight);
+ grn_obj_unlink(ctx, range);
+ break;
+ }
+ grn_vector_add_element(ctx,
+ vector,
+ GRN_BULK_HEAD(key),
+ GRN_BULK_VSIZE(key),
+ GRN_UINT32_VALUE(&weight_buffer),
+ key->header.domain);
+ }
+ GRN_OBJ_FIN(ctx, &weight_buffer);
+}
+
+static void
+set_vector(grn_ctx *ctx, grn_obj *column, grn_id id, grn_obj *vector)
+{
+ int n = GRN_UINT32_VALUE(vector);
+ grn_obj buf, *v = vector + 1;
+ grn_id range_id;
+ grn_obj *range;
+
+ range_id = DB_OBJ(column)->range;
+ range = grn_ctx_at(ctx, range_id);
+ if (grn_obj_is_table(ctx, range)) {
+ GRN_RECORD_INIT(&buf, GRN_OBJ_VECTOR, range_id);
+ while (n--) {
+ grn_bool cast_failed = GRN_FALSE;
+ grn_obj record, *element = v;
+ if (range_id != element->header.domain) {
+ GRN_RECORD_INIT(&record, 0, range_id);
+ if (grn_obj_cast(ctx, element, &record, GRN_TRUE)) {
+ cast_failed = GRN_TRUE;
+ ERR_CAST(column, range, element);
+ }
+ element = &record;
+ }
+ if (!cast_failed) {
+ GRN_UINT32_PUT(ctx, &buf, GRN_RECORD_VALUE(element));
+ }
+ if (element == &record) { GRN_OBJ_FIN(ctx, element); }
+ v = values_next(ctx, v);
+ }
+ } else {
+ if (((struct _grn_type *)range)->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ GRN_TEXT_INIT(&buf, GRN_OBJ_VECTOR);
+ while (n--) {
+ switch (v->header.domain) {
+ case GRN_DB_TEXT :
+ {
+ grn_bool cast_failed = GRN_FALSE;
+ grn_obj casted_element, *element = v;
+ if (range_id != element->header.domain) {
+ GRN_OBJ_INIT(&casted_element, GRN_BULK, 0, range_id);
+ if (grn_obj_cast(ctx, element, &casted_element, GRN_TRUE)) {
+ cast_failed = GRN_TRUE;
+ ERR_CAST(column, range, element);
+ }
+ element = &casted_element;
+ }
+ if (!cast_failed) {
+ grn_vector_add_element(ctx, &buf,
+ GRN_TEXT_VALUE(element),
+ GRN_TEXT_LEN(element),
+ 0,
+ element->header.domain);
+ }
+ if (element == &casted_element) { GRN_OBJ_FIN(ctx, element); }
+ break;
+ }
+ case GRN_JSON_LOAD_OPEN_BRACE :
+ add_weight_vector(ctx, column, v, &buf);
+ n -= GRN_UINT32_VALUE(v);
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "array must contain string or object");
+ break;
+ }
+ v = values_next(ctx, v);
+ }
+ } else {
+ grn_id value_size = ((grn_db_obj *)range)->range;
+ GRN_VALUE_FIX_SIZE_INIT(&buf, GRN_OBJ_VECTOR, range_id);
+ while (n--) {
+ grn_bool cast_failed = GRN_FALSE;
+ grn_obj casted_element, *element = v;
+ if (range_id != element->header.domain) {
+ GRN_OBJ_INIT(&casted_element, GRN_BULK, 0, range_id);
+ if (grn_obj_cast(ctx, element, &casted_element, GRN_TRUE)) {
+ cast_failed = GRN_TRUE;
+ ERR_CAST(column, range, element);
+ }
+ element = &casted_element;
+ }
+ if (!cast_failed) {
+ grn_bulk_write(ctx, &buf, GRN_TEXT_VALUE(element), value_size);
+ }
+ if (element == &casted_element) { GRN_OBJ_FIN(ctx, element); }
+ v = values_next(ctx, v);
+ }
+ }
+ }
+ grn_obj_set_value(ctx, column, id, &buf, GRN_OBJ_SET);
+ GRN_OBJ_FIN(ctx, &buf);
+}
+
+static void
+set_weight_vector(grn_ctx *ctx, grn_obj *column, grn_id id, grn_obj *value)
+{
+ if (!grn_obj_is_weight_vector_column(ctx, column)) {
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int column_name_size;
+ column_name_size = grn_obj_name(ctx, column, column_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "<%.*s>: columns except weight vector column don't support object value",
+ column_name_size, column_name);
+ return;
+ }
+
+ {
+ grn_obj vector;
+
+ GRN_TEXT_INIT(&vector, GRN_OBJ_VECTOR);
+ add_weight_vector(ctx, column, value, &vector);
+ grn_obj_set_value(ctx, column, id, &vector, GRN_OBJ_SET);
+ GRN_OBJ_FIN(ctx, &vector);
+ }
+}
+
+static inline int
+name_equal(const char *p, unsigned int size, const char *name)
+{
+ if (strlen(name) != size) { return 0; }
+ if (*p != GRN_DB_PSEUDO_COLUMN_PREFIX) { return 0; }
+ return !memcmp(p + 1, name + 1, size - 1);
+}
+
+static void
+report_set_column_value_failure(grn_ctx *ctx,
+ grn_obj *key,
+ const char *column_name,
+ unsigned int column_name_size,
+ grn_obj *column_value)
+{
+ grn_obj key_inspected, column_value_inspected;
+
+ GRN_TEXT_INIT(&key_inspected, 0);
+ GRN_TEXT_INIT(&column_value_inspected, 0);
+ grn_inspect_limited(ctx, &key_inspected, key);
+ grn_inspect_limited(ctx, &column_value_inspected, column_value);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "[table][load] failed to set column value: %s: "
+ "key: <%.*s>, column: <%.*s>, value: <%.*s>",
+ ctx->errbuf,
+ (int)GRN_TEXT_LEN(&key_inspected),
+ GRN_TEXT_VALUE(&key_inspected),
+ column_name_size,
+ column_name,
+ (int)GRN_TEXT_LEN(&column_value_inspected),
+ GRN_TEXT_VALUE(&column_value_inspected));
+ GRN_OBJ_FIN(ctx, &key_inspected);
+ GRN_OBJ_FIN(ctx, &column_value_inspected);
+}
+
+static grn_id
+parse_id_value(grn_ctx *ctx, grn_obj *value)
+{
+ switch (value->header.type) {
+ case GRN_DB_UINT32 :
+ return GRN_UINT32_VALUE(value);
+ case GRN_DB_INT32 :
+ return GRN_INT32_VALUE(value);
+ default :
+ {
+ grn_id id = GRN_ID_NIL;
+ grn_obj casted_value;
+ GRN_UINT32_INIT(&casted_value, 0);
+ if (grn_obj_cast(ctx, value, &casted_value, GRN_FALSE) != GRN_SUCCESS) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, value);
+ ERR(GRN_INVALID_ARGUMENT,
+ "<%s>: failed to cast to <UInt32>: <%.*s>",
+ GRN_COLUMN_NAME_ID,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ } else {
+ id = GRN_UINT32_VALUE(&casted_value);
+ }
+ GRN_OBJ_FIN(ctx, &casted_value);
+ return id;
+ }
+ }
+}
+
+static void
+bracket_close(grn_ctx *ctx, grn_loader *loader)
+{
+ grn_id id = GRN_ID_NIL;
+ grn_obj *value, *value_end, *id_value = NULL, *key_value = NULL;
+ grn_obj *col, **cols; /* Columns except _id and _key. */
+ uint32_t i, begin;
+ uint32_t ncols; /* Number of columns except _id and _key. */
+ uint32_t nvalues; /* Number of values in brackets. */
+ uint32_t depth;
+ grn_bool is_record_load = GRN_FALSE;
+
+ cols = (grn_obj **)GRN_BULK_HEAD(&loader->columns);
+ ncols = GRN_BULK_VSIZE(&loader->columns) / sizeof(grn_obj *);
+ GRN_UINT32_POP(&loader->level, begin);
+ value = (grn_obj *)GRN_TEXT_VALUE(&loader->values) + begin;
+ value_end = (grn_obj *)GRN_TEXT_VALUE(&loader->values) + loader->values_size;
+ GRN_ASSERT(value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET);
+ GRN_UINT32_SET(ctx, value, loader->values_size - begin - 1);
+ value++;
+ depth = GRN_BULK_VSIZE(&loader->level);
+ if (depth > sizeof(uint32_t) * loader->emit_level) {
+ return;
+ }
+ if (depth == 0 || !loader->table ||
+ loader->columns_status == GRN_LOADER_COLUMNS_BROKEN) {
+ goto exit;
+ }
+ nvalues = values_len(ctx, value, value_end);
+
+ if (loader->columns_status == GRN_LOADER_COLUMNS_UNSET) {
+ /*
+ * Target columns and _id or _key are not specified yet and values are
+ * handled as column names and "_id" or "_key".
+ */
+ for (i = 0; i < nvalues; i++) {
+ const char *col_name;
+ unsigned int col_name_size;
+ if (value->header.domain != GRN_DB_TEXT) {
+ grn_obj buffer;
+ GRN_TEXT_INIT(&buffer, 0);
+ grn_inspect(ctx, &buffer, value);
+ ERR(GRN_INVALID_ARGUMENT,
+ "column name must be string: <%.*s>",
+ (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer));
+ grn_loader_save_error(ctx, loader);
+ GRN_OBJ_FIN(ctx, &buffer);
+ loader->columns_status = GRN_LOADER_COLUMNS_BROKEN;
+ goto exit;
+ }
+ col_name = GRN_TEXT_VALUE(value);
+ col_name_size = GRN_TEXT_LEN(value);
+ col = grn_obj_column(ctx, loader->table, col_name, col_name_size);
+ if (!col) {
+ ERR(GRN_INVALID_ARGUMENT, "nonexistent column: <%.*s>",
+ col_name_size, col_name);
+ grn_loader_save_error(ctx, loader);
+ loader->columns_status = GRN_LOADER_COLUMNS_BROKEN;
+ goto exit;
+ }
+ if (name_equal(col_name, col_name_size, GRN_COLUMN_NAME_ID)) {
+ grn_obj_unlink(ctx, col);
+ if (loader->id_offset != -1 || loader->key_offset != -1) {
+ /* _id and _key must not appear more than once. */
+ if (loader->id_offset != -1) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "duplicated id and key columns: <%s> at %d and <%s> at %d",
+ GRN_COLUMN_NAME_ID, i,
+ GRN_COLUMN_NAME_ID, loader->id_offset);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "duplicated id and key columns: <%s> at %d and <%s> at %d",
+ GRN_COLUMN_NAME_ID, i,
+ GRN_COLUMN_NAME_KEY, loader->key_offset);
+ }
+ grn_loader_save_error(ctx, loader);
+ loader->columns_status = GRN_LOADER_COLUMNS_BROKEN;
+ goto exit;
+ }
+ loader->id_offset = i;
+ } else if (name_equal(col_name, col_name_size, GRN_COLUMN_NAME_KEY)) {
+ grn_obj_unlink(ctx, col);
+ if (loader->id_offset != -1 || loader->key_offset != -1) {
+ /* _id and _key must not appear more than once. */
+ if (loader->id_offset != -1) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "duplicated id and key columns: <%s> at %d and <%s> at %d",
+ GRN_COLUMN_NAME_KEY, i,
+ GRN_COLUMN_NAME_ID, loader->id_offset);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "duplicated id and key columns: <%s> at %d and <%s> at %d",
+ GRN_COLUMN_NAME_KEY, i,
+ GRN_COLUMN_NAME_KEY, loader->key_offset);
+ }
+ grn_loader_save_error(ctx, loader);
+ loader->columns_status = GRN_LOADER_COLUMNS_BROKEN;
+ goto exit;
+ }
+ loader->key_offset = i;
+ } else {
+ GRN_PTR_PUT(ctx, &loader->columns, col);
+ }
+ value++;
+ }
+ switch (loader->table->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ if (loader->id_offset == -1 && loader->key_offset == -1) {
+ ERR(GRN_INVALID_ARGUMENT, "missing id or key column");
+ grn_loader_save_error(ctx, loader);
+ loader->columns_status = GRN_LOADER_COLUMNS_BROKEN;
+ goto exit;
+ }
+ break;
+ }
+ loader->columns_status = GRN_LOADER_COLUMNS_SET;
+ goto exit;
+ }
+
+ is_record_load = GRN_TRUE;
+
+ /* Target columns and _id or _key are already specified. */
+ if (!nvalues) {
+ /*
+ * Accept empty arrays because a dump command may output a load command
+ * which contains empty arrays for a table with deleted records.
+ */
+ id = grn_table_add(ctx, loader->table, NULL, 0, NULL);
+ } else {
+ uint32_t expected_nvalues = ncols;
+ if (loader->id_offset != -1 || loader->key_offset != -1) {
+ expected_nvalues++;
+ }
+ if (nvalues != expected_nvalues) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "unexpected #values: expected:%u, actual:%u",
+ expected_nvalues, nvalues);
+ grn_loader_save_error(ctx, loader);
+ goto exit;
+ }
+ if (loader->id_offset != -1) {
+ id_value = value + loader->id_offset;
+ id = parse_id_value(ctx, id_value);
+ if (grn_table_at(ctx, loader->table, id) == GRN_ID_NIL) {
+ id = grn_table_add(ctx, loader->table, NULL, 0, NULL);
+ }
+ } else if (loader->key_offset != -1) {
+ key_value = value + loader->key_offset;
+ id = loader_add(ctx, key_value);
+ } else {
+ id = grn_table_add(ctx, loader->table, NULL, 0, NULL);
+ }
+ }
+ if (id == GRN_ID_NIL) {
+ /* Target record is not available. */
+ goto exit;
+ }
+
+ for (i = 0; i < nvalues; i++, value = values_next(ctx, value)) {
+ if (i == loader->id_offset || i == loader->key_offset) {
+ /* Skip _id and _key, because it's already used to get id. */
+ continue;
+ }
+ col = *cols;
+ if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET) {
+ set_vector(ctx, col, id, value);
+ } else if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACE) {
+ set_weight_vector(ctx, col, id, value);
+ } else {
+ grn_obj_set_value(ctx, col, id, value, GRN_OBJ_SET);
+ }
+ if (ctx->rc != GRN_SUCCESS) {
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int column_name_size;
+ grn_loader_save_error(ctx, loader);
+ column_name_size = grn_obj_name(ctx, col, column_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ report_set_column_value_failure(ctx, key_value,
+ column_name, column_name_size,
+ value);
+ ERRCLR(ctx);
+ }
+ cols++;
+ }
+ if (loader->each) {
+ grn_obj *v = grn_expr_get_var_by_offset(ctx, loader->each, 0);
+ GRN_RECORD_SET(ctx, v, id);
+ grn_expr_exec(ctx, loader->each, 0);
+ }
+ loader->nrecords++;
+exit:
+ if (is_record_load) {
+ if (loader->output_ids) {
+ GRN_UINT32_PUT(ctx, &(loader->ids), id);
+ }
+ if (loader->output_errors) {
+ GRN_INT32_PUT(ctx, &(loader->return_codes), ctx->rc);
+ grn_vector_add_element(ctx,
+ &(loader->error_messages),
+ ctx->errbuf,
+ strlen(ctx->errbuf),
+ 0,
+ GRN_DB_TEXT);
+ }
+ }
+ loader->values_size = begin;
+ ERRCLR(ctx);
+}
+
+static void
+brace_close(grn_ctx *ctx, grn_loader *loader)
+{
+ grn_id id = GRN_ID_NIL;
+ grn_obj *value, *value_begin, *value_end;
+ grn_obj *id_value = NULL, *key_value = NULL;
+ uint32_t begin;
+
+ GRN_UINT32_POP(&loader->level, begin);
+ value_begin = (grn_obj *)GRN_TEXT_VALUE(&loader->values) + begin;
+ value_end = (grn_obj *)GRN_TEXT_VALUE(&loader->values) + loader->values_size;
+ GRN_ASSERT(value->header.domain == GRN_JSON_LOAD_OPEN_BRACE);
+ GRN_UINT32_SET(ctx, value_begin, loader->values_size - begin - 1);
+ value_begin++;
+ if (GRN_BULK_VSIZE(&loader->level) > sizeof(uint32_t) * loader->emit_level) {
+ return;
+ }
+ if (!loader->table) {
+ goto exit;
+ }
+
+ /* Scan values to find _id or _key. */
+ for (value = value_begin; value + 1 < value_end;
+ value = values_next(ctx, value)) {
+ const char *name = GRN_TEXT_VALUE(value);
+ unsigned int name_size = GRN_TEXT_LEN(value);
+ if (value->header.domain != GRN_DB_TEXT) {
+ grn_obj buffer;
+ GRN_TEXT_INIT(&buffer, 0);
+ grn_inspect(ctx, &buffer, value);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "column name must be string: <%.*s>",
+ (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer));
+ GRN_OBJ_FIN(ctx, &buffer);
+ goto exit;
+ }
+ value++;
+ if (name_equal(name, name_size, GRN_COLUMN_NAME_ID)) {
+ if (id_value || key_value) {
+ if (loader->table->header.type == GRN_TABLE_NO_KEY) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "duplicated '_id' column");
+ goto exit;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "duplicated key columns: %s and %s",
+ id_value ? GRN_COLUMN_NAME_ID : GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_ID);
+ goto exit;
+ }
+ }
+ id_value = value;
+ } else if (name_equal(name, name_size, GRN_COLUMN_NAME_KEY)) {
+ if (id_value || key_value) {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "duplicated key columns: %s and %s",
+ id_value ? GRN_COLUMN_NAME_ID : GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY);
+ goto exit;
+ }
+ key_value = value;
+ }
+ }
+
+ switch (loader->table->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ /* The target table requires _id or _key. */
+ if (!id_value && !key_value) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "neither _key nor _id is assigned");
+ goto exit;
+ }
+ break;
+ default :
+ /* The target table does not have _key. */
+ if (key_value) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "nonexistent key value");
+ goto exit;
+ }
+ break;
+ }
+
+ if (id_value) {
+ id = parse_id_value(ctx, id_value);
+ if (grn_table_at(ctx, loader->table, id) == GRN_ID_NIL) {
+ if (ctx->rc == GRN_SUCCESS) {
+ id = grn_table_add(ctx, loader->table, NULL, 0, NULL);
+ }
+ }
+ } else if (key_value) {
+ id = loader_add(ctx, key_value);
+ } else {
+ id = grn_table_add(ctx, loader->table, NULL, 0, NULL);
+ }
+ if (id == GRN_ID_NIL) {
+ /* Target record is not available. */
+ goto exit;
+ }
+
+ for (value = value_begin; value + 1 < value_end;
+ value = values_next(ctx, value)) {
+ grn_obj *col;
+ const char *name = GRN_TEXT_VALUE(value);
+ unsigned int name_size = GRN_TEXT_LEN(value);
+ value++;
+ if (value == id_value || value == key_value) {
+ /* Skip _id and _key, because it's already used to get id. */
+ continue;
+ }
+ col = grn_obj_column(ctx, loader->table, name, name_size);
+ if (!col) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "invalid column('%.*s')",
+ (int)name_size, name);
+ /* Automatic column creation is disabled. */
+ /*
+ if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET) {
+ grn_obj *v = value + 1;
+ col = grn_column_create(ctx, loader->table, name, name_size,
+ NULL, GRN_OBJ_PERSISTENT|GRN_OBJ_COLUMN_VECTOR,
+ grn_ctx_at(ctx, v->header.domain));
+ } else {
+ col = grn_column_create(ctx, loader->table, name, name_size,
+ NULL, GRN_OBJ_PERSISTENT,
+ grn_ctx_at(ctx, value->header.domain));
+ }
+ */
+ } else {
+ if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET) {
+ set_vector(ctx, col, id, value);
+ } else if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACE) {
+ set_weight_vector(ctx, col, id, value);
+ } else {
+ grn_obj_set_value(ctx, col, id, value, GRN_OBJ_SET);
+ }
+ if (ctx->rc != GRN_SUCCESS) {
+ grn_loader_save_error(ctx, loader);
+ report_set_column_value_failure(ctx, key_value,
+ name, name_size, value);
+ ERRCLR(ctx);
+ }
+ grn_obj_unlink(ctx, col);
+ }
+ }
+ if (loader->each) {
+ value = grn_expr_get_var_by_offset(ctx, loader->each, 0);
+ GRN_RECORD_SET(ctx, value, id);
+ grn_expr_exec(ctx, loader->each, 0);
+ }
+ loader->nrecords++;
+exit:
+ if (loader->output_ids) {
+ GRN_UINT32_PUT(ctx, &(loader->ids), id);
+ }
+ if (loader->output_errors) {
+ GRN_INT32_PUT(ctx, &(loader->return_codes), ctx->rc);
+ grn_vector_add_element(ctx,
+ &(loader->error_messages),
+ ctx->errbuf,
+ strlen(ctx->errbuf),
+ 0,
+ GRN_DB_TEXT);
+ }
+ loader->values_size = begin;
+ ERRCLR(ctx);
+}
+
+#define JSON_READ_OPEN_BRACKET() do {\
+ GRN_UINT32_PUT(ctx, &loader->level, loader->values_size);\
+ values_add(ctx, loader);\
+ loader->last->header.domain = GRN_JSON_LOAD_OPEN_BRACKET;\
+ loader->stat = GRN_LOADER_TOKEN;\
+ str++;\
+} while (0)
+
+#define JSON_READ_OPEN_BRACE() do {\
+ GRN_UINT32_PUT(ctx, &loader->level, loader->values_size);\
+ values_add(ctx, loader);\
+ loader->last->header.domain = GRN_JSON_LOAD_OPEN_BRACE;\
+ loader->stat = GRN_LOADER_TOKEN;\
+ str++;\
+} while (0)
+
+static void
+json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned int str_len)
+{
+ const char *const beg = str;
+ char c;
+ int len;
+ const char *se = str + str_len;
+ while (str < se) {
+ c = *str;
+ switch (loader->stat) {
+ case GRN_LOADER_BEGIN :
+ if ((len = grn_isspace(str, ctx->encoding))) {
+ str += len;
+ continue;
+ }
+ switch (c) {
+ case '[' :
+ JSON_READ_OPEN_BRACKET();
+ break;
+ case '{' :
+ JSON_READ_OPEN_BRACE();
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT,
+ "JSON must start with '[' or '{': <%.*s>", str_len, beg);
+ loader->stat = GRN_LOADER_END;
+ break;
+ }
+ break;
+ case GRN_LOADER_TOKEN :
+ if ((len = grn_isspace(str, ctx->encoding))) {
+ str += len;
+ continue;
+ }
+ switch (c) {
+ case '"' :
+ loader->stat = GRN_LOADER_STRING;
+ values_add(ctx, loader);
+ str++;
+ break;
+ case '[' :
+ JSON_READ_OPEN_BRACKET();
+ break;
+ case '{' :
+ JSON_READ_OPEN_BRACE();
+ break;
+ case ':' :
+ str++;
+ break;
+ case ',' :
+ str++;
+ break;
+ case ']' :
+ bracket_close(ctx, loader);
+ loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END;
+ if (ctx->rc == GRN_CANCEL) {
+ loader->stat = GRN_LOADER_END;
+ }
+ str++;
+ break;
+ case '}' :
+ brace_close(ctx, loader);
+ loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END;
+ if (ctx->rc == GRN_CANCEL) {
+ loader->stat = GRN_LOADER_END;
+ }
+ str++;
+ break;
+ case '+' : case '-' : case '0' : case '1' : case '2' : case '3' :
+ case '4' : case '5' : case '6' : case '7' : case '8' : case '9' :
+ loader->stat = GRN_LOADER_NUMBER;
+ values_add(ctx, loader);
+ break;
+ default :
+ if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('_' == c)) {
+ loader->stat = GRN_LOADER_SYMBOL;
+ values_add(ctx, loader);
+ } else {
+ if ((len = grn_charlen(ctx, str, se))) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char('%c') at", c);
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg) + len, beg);
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%*s", (int)(str - beg) + 1, "^");
+ str += len;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char(\\x%.2x) after", c);
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg), beg);
+ str = se;
+ }
+ }
+ break;
+ }
+ break;
+ case GRN_LOADER_SYMBOL :
+ if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') ||
+ ('0' <= c && c <= '9') || ('_' == c)) {
+ GRN_TEXT_PUTC(ctx, loader->last, c);
+ str++;
+ } else {
+ char *v = GRN_TEXT_VALUE(loader->last);
+ switch (*v) {
+ case 'n' :
+ if (GRN_TEXT_LEN(loader->last) == 4 && !memcmp(v, "null", 4)) {
+ loader->last->header.domain = GRN_DB_VOID;
+ GRN_BULK_REWIND(loader->last);
+ }
+ break;
+ case 't' :
+ if (GRN_TEXT_LEN(loader->last) == 4 && !memcmp(v, "true", 4)) {
+ loader->last->header.domain = GRN_DB_BOOL;
+ GRN_BOOL_SET(ctx, loader->last, GRN_TRUE);
+ }
+ break;
+ case 'f' :
+ if (GRN_TEXT_LEN(loader->last) == 5 && !memcmp(v, "false", 5)) {
+ loader->last->header.domain = GRN_DB_BOOL;
+ GRN_BOOL_SET(ctx, loader->last, GRN_FALSE);
+ }
+ break;
+ default :
+ break;
+ }
+ loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END;
+ }
+ break;
+ case GRN_LOADER_NUMBER :
+ switch (c) {
+ case '+' : case '-' : case '.' : case 'e' : case 'E' :
+ case '0' : case '1' : case '2' : case '3' : case '4' :
+ case '5' : case '6' : case '7' : case '8' : case '9' :
+ GRN_TEXT_PUTC(ctx, loader->last, c);
+ str++;
+ break;
+ default :
+ {
+ const char *cur, *str = GRN_BULK_HEAD(loader->last);
+ const char *str_end = GRN_BULK_CURR(loader->last);
+ int64_t i = grn_atoll(str, str_end, &cur);
+ if (cur == str_end) {
+ loader->last->header.domain = GRN_DB_INT64;
+ GRN_INT64_SET(ctx, loader->last, i);
+ } else if (cur != str) {
+ uint64_t i = grn_atoull(str, str_end, &cur);
+ if (cur == str_end) {
+ loader->last->header.domain = GRN_DB_UINT64;
+ GRN_UINT64_SET(ctx, loader->last, i);
+ } else if (cur != str) {
+ double d;
+ char *end;
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ GRN_TEXT_PUT(ctx, &buf, str, GRN_BULK_VSIZE(loader->last));
+ GRN_TEXT_PUTC(ctx, &buf, '\0');
+ errno = 0;
+ d = strtod(GRN_TEXT_VALUE(&buf), &end);
+ if (!errno && end + 1 == GRN_BULK_CURR(&buf)) {
+ loader->last->header.domain = GRN_DB_FLOAT;
+ GRN_FLOAT_SET(ctx, loader->last, d);
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+ }
+ }
+ }
+ loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END;
+ break;
+ }
+ break;
+ case GRN_LOADER_STRING :
+ switch (c) {
+ case '\\' :
+ loader->stat = GRN_LOADER_STRING_ESC;
+ str++;
+ break;
+ case '"' :
+ str++;
+ loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END;
+ /*
+ *(GRN_BULK_CURR(loader->last)) = '\0';
+ GRN_LOG(ctx, GRN_LOG_ALERT, "read str(%s)", GRN_TEXT_VALUE(loader->last));
+ */
+ break;
+ default :
+ if ((len = grn_charlen(ctx, str, se))) {
+ GRN_TEXT_PUT(ctx, loader->last, str, len);
+ str += len;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char(\\x%.2x) after", c);
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg), beg);
+ str = se;
+ }
+ break;
+ }
+ break;
+ case GRN_LOADER_STRING_ESC :
+ switch (c) {
+ case 'b' :
+ GRN_TEXT_PUTC(ctx, loader->last, '\b');
+ loader->stat = GRN_LOADER_STRING;
+ break;
+ case 'f' :
+ GRN_TEXT_PUTC(ctx, loader->last, '\f');
+ loader->stat = GRN_LOADER_STRING;
+ break;
+ case 'n' :
+ GRN_TEXT_PUTC(ctx, loader->last, '\n');
+ loader->stat = GRN_LOADER_STRING;
+ break;
+ case 'r' :
+ GRN_TEXT_PUTC(ctx, loader->last, '\r');
+ loader->stat = GRN_LOADER_STRING;
+ break;
+ case 't' :
+ GRN_TEXT_PUTC(ctx, loader->last, '\t');
+ loader->stat = GRN_LOADER_STRING;
+ break;
+ case 'u' :
+ loader->stat = GRN_LOADER_UNICODE0;
+ break;
+ default :
+ GRN_TEXT_PUTC(ctx, loader->last, c);
+ loader->stat = GRN_LOADER_STRING;
+ break;
+ }
+ str++;
+ break;
+ case GRN_LOADER_UNICODE0 :
+ switch (c) {
+ case '0' : case '1' : case '2' : case '3' : case '4' :
+ case '5' : case '6' : case '7' : case '8' : case '9' :
+ loader->unichar = (c - '0') * 0x1000;
+ break;
+ case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' :
+ loader->unichar = (c - 'a' + 10) * 0x1000;
+ break;
+ case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' :
+ loader->unichar = (c - 'A' + 10) * 0x1000;
+ break;
+ default :
+ ;// todo : error
+ }
+ loader->stat = GRN_LOADER_UNICODE1;
+ str++;
+ break;
+ case GRN_LOADER_UNICODE1 :
+ switch (c) {
+ case '0' : case '1' : case '2' : case '3' : case '4' :
+ case '5' : case '6' : case '7' : case '8' : case '9' :
+ loader->unichar += (c - '0') * 0x100;
+ break;
+ case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' :
+ loader->unichar += (c - 'a' + 10) * 0x100;
+ break;
+ case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' :
+ loader->unichar += (c - 'A' + 10) * 0x100;
+ break;
+ default :
+ ;// todo : error
+ }
+ loader->stat = GRN_LOADER_UNICODE2;
+ str++;
+ break;
+ case GRN_LOADER_UNICODE2 :
+ switch (c) {
+ case '0' : case '1' : case '2' : case '3' : case '4' :
+ case '5' : case '6' : case '7' : case '8' : case '9' :
+ loader->unichar += (c - '0') * 0x10;
+ break;
+ case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' :
+ loader->unichar += (c - 'a' + 10) * 0x10;
+ break;
+ case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' :
+ loader->unichar += (c - 'A' + 10) * 0x10;
+ break;
+ default :
+ ;// todo : error
+ }
+ loader->stat = GRN_LOADER_UNICODE3;
+ str++;
+ break;
+ case GRN_LOADER_UNICODE3 :
+ switch (c) {
+ case '0' : case '1' : case '2' : case '3' : case '4' :
+ case '5' : case '6' : case '7' : case '8' : case '9' :
+ loader->unichar += (c - '0');
+ break;
+ case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' :
+ loader->unichar += (c - 'a' + 10);
+ break;
+ case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' :
+ loader->unichar += (c - 'A' + 10);
+ break;
+ default :
+ ;// todo : error
+ }
+ {
+ uint32_t u = loader->unichar;
+ if (u < 0x80) {
+ GRN_TEXT_PUTC(ctx, loader->last, u);
+ } else {
+ if (u < 0x800) {
+ GRN_TEXT_PUTC(ctx, loader->last, ((u >> 6) & 0x1f) | 0xc0);
+ } else {
+ GRN_TEXT_PUTC(ctx, loader->last, (u >> 12) | 0xe0);
+ GRN_TEXT_PUTC(ctx, loader->last, ((u >> 6) & 0x3f) | 0x80);
+ }
+ GRN_TEXT_PUTC(ctx, loader->last, (u & 0x3f) | 0x80);
+ }
+ }
+ loader->stat = GRN_LOADER_STRING;
+ str++;
+ break;
+ case GRN_LOADER_END :
+ str = se;
+ break;
+ }
+ }
+}
+
+#undef JSON_READ_OPEN_BRACKET
+#undef JSON_READ_OPEN_BRACE
+
+/*
+ * grn_loader_parse_columns parses a columns parameter.
+ * Columns except _id and _key are appended to loader->columns.
+ * If it contains _id or _key, loader->id_offset or loader->key_offset is set.
+ */
+static grn_rc
+grn_loader_parse_columns(grn_ctx *ctx, grn_loader *loader,
+ const char *str, unsigned int str_size)
+{
+ const char *ptr = str, *ptr_end = ptr + str_size, *rest;
+ const char *tokens[256], *token_end;
+ while (ptr < ptr_end) {
+ int i, n = grn_tokenize(ptr, ptr_end - ptr, tokens, 256, &rest);
+ for (i = 0; i < n; i++) {
+ grn_obj *column;
+ token_end = tokens[i];
+ while (ptr < token_end && (' ' == *ptr || ',' == *ptr)) {
+ ptr++;
+ }
+ column = grn_obj_column(ctx, loader->table, ptr, token_end - ptr);
+ if (!column) {
+ ERR(GRN_INVALID_ARGUMENT, "nonexistent column: <%.*s>",
+ (int)(token_end - ptr), ptr);
+ return ctx->rc;
+ }
+ if (name_equal(ptr, token_end - ptr, GRN_COLUMN_NAME_ID)) {
+ grn_obj_unlink(ctx, column);
+ if (loader->id_offset != -1 || loader->key_offset != -1) {
+ /* _id and _key must not appear more than once. */
+ if (loader->id_offset != -1) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "duplicated id and key columns: <%s> at %d and <%s> at %d",
+ GRN_COLUMN_NAME_ID, i,
+ GRN_COLUMN_NAME_ID, loader->id_offset);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "duplicated id and key columns: <%s> at %d and <%s> at %d",
+ GRN_COLUMN_NAME_ID, i,
+ GRN_COLUMN_NAME_KEY, loader->key_offset);
+ }
+ return ctx->rc;
+ }
+ loader->id_offset = i;
+ } else if (name_equal(ptr, token_end - ptr, GRN_COLUMN_NAME_KEY)) {
+ grn_obj_unlink(ctx, column);
+ if (loader->id_offset != -1 || loader->key_offset != -1) {
+ /* _id and _key must not appear more than once. */
+ if (loader->id_offset != -1) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "duplicated id and key columns: <%s> at %d and <%s> at %d",
+ GRN_COLUMN_NAME_KEY, i,
+ GRN_COLUMN_NAME_ID, loader->id_offset);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "duplicated id and key columns: <%s> at %d and <%s> at %d",
+ GRN_COLUMN_NAME_KEY, i,
+ GRN_COLUMN_NAME_KEY, loader->key_offset);
+ }
+ return ctx->rc;
+ }
+ loader->key_offset = i;
+ } else {
+ GRN_PTR_PUT(ctx, &loader->columns, column);
+ }
+ ptr = token_end;
+ }
+ ptr = rest;
+ }
+ switch (loader->table->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ if (loader->id_offset == -1 && loader->key_offset == -1) {
+ ERR(GRN_INVALID_ARGUMENT, "missing id or key column");
+ return ctx->rc;
+ }
+ break;
+ }
+ return ctx->rc;
+}
+
+static grn_com_addr *addr;
+
+void
+grn_load_internal(grn_ctx *ctx, grn_load_input *input)
+{
+ grn_loader *loader = &ctx->impl->loader;
+
+ loader->emit_level = input->emit_level;
+ if (ctx->impl->edge) {
+ grn_edge *edge = grn_edges_add_communicator(ctx, addr);
+ grn_obj *msg = grn_msg_open(ctx, edge->com, &ctx->impl->edge->send_old);
+ /* build msg */
+ grn_edge_dispatch(ctx, edge, msg);
+ }
+ if (input->table.length > 0) {
+ grn_ctx_loader_clear(ctx);
+ loader->input_type = input->type;
+ if (grn_db_check_name(ctx, input->table.value, input->table.length)) {
+ GRN_DB_CHECK_NAME_ERR("[table][load]",
+ input->table.value,
+ (int)(input->table.length));
+ loader->stat = GRN_LOADER_END;
+ return;
+ }
+ loader->table = grn_ctx_get(ctx, input->table.value, input->table.length);
+ if (!loader->table) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "nonexistent table: <%.*s>",
+ (int)(input->table.length),
+ input->table.value);
+ loader->stat = GRN_LOADER_END;
+ return;
+ }
+ if (input->columns.length > 0) {
+ grn_rc rc = grn_loader_parse_columns(ctx,
+ loader,
+ input->columns.value,
+ input->columns.length);
+ if (rc != GRN_SUCCESS) {
+ loader->columns_status = GRN_LOADER_COLUMNS_BROKEN;
+ loader->stat = GRN_LOADER_END;
+ return;
+ }
+ loader->columns_status = GRN_LOADER_COLUMNS_SET;
+ }
+ if (input->if_exists.length > 0) {
+ grn_obj *v;
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, loader->table, loader->ifexists, v);
+ if (loader->ifexists && v) {
+ grn_expr_parse(ctx,
+ loader->ifexists,
+ input->if_exists.value,
+ input->if_exists.length,
+ NULL, GRN_OP_EQUAL, GRN_OP_AND,
+ GRN_EXPR_SYNTAX_SCRIPT|GRN_EXPR_ALLOW_UPDATE);
+ }
+ }
+ if (input->each.length > 0) {
+ grn_obj *v;
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, loader->table, loader->each, v);
+ if (loader->each && v) {
+ grn_expr_parse(ctx, loader->each,
+ input->each.value,
+ input->each.length,
+ NULL, GRN_OP_EQUAL, GRN_OP_AND,
+ GRN_EXPR_SYNTAX_SCRIPT|GRN_EXPR_ALLOW_UPDATE);
+ }
+ }
+ loader->output_ids = input->output_ids;
+ loader->output_errors = input->output_errors;
+ } else {
+ if (!loader->table) {
+ ERR(GRN_INVALID_ARGUMENT, "mandatory \"table\" parameter is absent");
+ loader->stat = GRN_LOADER_END;
+ return;
+ }
+ }
+ switch (loader->input_type) {
+ case GRN_CONTENT_JSON :
+ json_read(ctx, loader, input->values.value, input->values.length);
+ break;
+ case GRN_CONTENT_NONE :
+ case GRN_CONTENT_TSV :
+ case GRN_CONTENT_XML :
+ case GRN_CONTENT_MSGPACK :
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "unsupported input_type");
+ loader->stat = GRN_LOADER_END;
+ // todo
+ break;
+ }
+}
+
+grn_rc
+grn_load(grn_ctx *ctx, grn_content_type input_type,
+ const char *table, unsigned int table_len,
+ const char *columns, unsigned int columns_len,
+ const char *values, unsigned int values_len,
+ const char *ifexists, unsigned int ifexists_len,
+ const char *each, unsigned int each_len)
+{
+ if (!ctx || !ctx->impl) {
+ ERR(GRN_INVALID_ARGUMENT, "db not initialized");
+ return ctx->rc;
+ }
+ GRN_API_ENTER;
+ {
+ grn_load_input input;
+ input.type = input_type;
+ input.table.value = table;
+ input.table.length = table_len;
+ input.columns.value = columns;
+ input.columns.length = columns_len;
+ input.values.value = values;
+ input.values.length = values_len;
+ input.if_exists.value = ifexists;
+ input.if_exists.length = ifexists_len;
+ input.each.value = each;
+ input.each.length = each_len;
+ input.output_ids = GRN_FALSE;
+ input.output_errors = GRN_FALSE;
+ input.emit_level = 1;
+ grn_load_internal(ctx, &input);
+ }
+ GRN_API_RETURN(ctx->rc);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/logger.c b/storage/mroonga/vendor/groonga/lib/logger.c
index 5a85de3d43e..d86b0b92579 100644
--- a/storage/mroonga/vendor/groonga/lib/logger.c
+++ b/storage/mroonga/vendor/groonga/lib/logger.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -28,9 +28,81 @@
# include <share.h>
#endif /* WIN32 */
-#ifdef WIN32
-# define fileno(file) _fileno(file)
-#endif
+static const char *log_level_names[] = {
+ "none",
+ "emergency",
+ "alert",
+ "critical",
+ "error",
+ "warning",
+ "notice",
+ "info",
+ "debug",
+ "dump"
+};
+
+#define GRN_LOG_LAST GRN_LOG_DUMP
+
+const char *
+grn_log_level_to_string(grn_log_level level)
+{
+ if (level <= GRN_LOG_LAST) {
+ return log_level_names[level];
+ } else {
+ return "unknown";
+ }
+}
+
+grn_bool
+grn_log_level_parse(const char *string, grn_log_level *level)
+{
+ if (strcmp(string, " ") == 0 ||
+ grn_strcasecmp(string, "none") == 0) {
+ *level = GRN_LOG_NONE;
+ return GRN_TRUE;
+ } else if (strcmp(string, "E") == 0 ||
+ grn_strcasecmp(string, "emerg") == 0 ||
+ grn_strcasecmp(string, "emergency") == 0) {
+ *level = GRN_LOG_EMERG;
+ return GRN_TRUE;
+ } else if (strcmp(string, "A") == 0 ||
+ grn_strcasecmp(string, "alert") == 0) {
+ *level = GRN_LOG_ALERT;
+ return GRN_TRUE;
+ } else if (strcmp(string, "C") == 0 ||
+ grn_strcasecmp(string, "crit") == 0 ||
+ grn_strcasecmp(string, "critical") == 0) {
+ *level = GRN_LOG_CRIT;
+ return GRN_TRUE;
+ } else if (strcmp(string, "e") == 0 ||
+ grn_strcasecmp(string, "error") == 0) {
+ *level = GRN_LOG_ERROR;
+ return GRN_TRUE;
+ } else if (strcmp(string, "w") == 0 ||
+ grn_strcasecmp(string, "warn") == 0 ||
+ grn_strcasecmp(string, "warning") == 0) {
+ *level = GRN_LOG_WARNING;
+ return GRN_TRUE;
+ } else if (strcmp(string, "n") == 0 ||
+ grn_strcasecmp(string, "notice") == 0) {
+ *level = GRN_LOG_NOTICE;
+ return GRN_TRUE;
+ } else if (strcmp(string, "i") == 0 ||
+ grn_strcasecmp(string, "info") == 0) {
+ *level = GRN_LOG_INFO;
+ return GRN_TRUE;
+ } else if (strcmp(string, "d") == 0 ||
+ grn_strcasecmp(string, "debug") == 0) {
+ *level = GRN_LOG_DEBUG;
+ return GRN_TRUE;
+ } else if (strcmp(string, "-") == 0 ||
+ grn_strcasecmp(string, "dump") == 0) {
+ *level = GRN_LOG_DUMP;
+ return GRN_TRUE;
+ } else {
+ return GRN_FALSE;
+ }
+}
static void
rotate_log_file(grn_ctx *ctx, const char *current_path)
@@ -51,6 +123,7 @@ rotate_log_file(grn_ctx *ctx, const char *current_path)
rename(current_path, rotated_path);
}
+static grn_bool logger_inited = GRN_FALSE;
static char *default_logger_path = NULL;
static FILE *default_logger_file = NULL;
static grn_critical_section default_logger_lock;
@@ -73,19 +146,25 @@ default_logger_log(grn_ctx *ctx, grn_log_level level,
default_logger_size = 0;
if (default_logger_file) {
struct stat stat;
- if (fstat(fileno(default_logger_file), &stat) != -1) {
+ if (fstat(grn_fileno(default_logger_file), &stat) != -1) {
default_logger_size = stat.st_size;
}
}
}
if (default_logger_file) {
+ char label = *(slev + level);
int written;
if (location && *location) {
- written = fprintf(default_logger_file, "%s|%c|%s %s %s\n",
- timestamp, *(slev + level), title, message, location);
+ if (title && *title) {
+ written = fprintf(default_logger_file, "%s|%c|%s: %s %s\n",
+ timestamp, label, location, title, message);
+ } else {
+ written = fprintf(default_logger_file, "%s|%c|%s: %s\n",
+ timestamp, label, location, message);
+ }
} else {
- written = fprintf(default_logger_file, "%s|%c|%s %s\n", timestamp,
- *(slev + level), title, message);
+ written = fprintf(default_logger_file, "%s|%c|%s %s\n",
+ timestamp, label, title, message);
}
if (written > 0) {
default_logger_size += written;
@@ -136,14 +215,16 @@ static grn_logger default_logger = {
default_logger_fin
};
-static grn_logger current_logger = {
- GRN_LOG_DEFAULT_LEVEL,
- GRN_LOG_TIME|GRN_LOG_MESSAGE,
- NULL,
- NULL,
- NULL,
- NULL
-};
+#define INITIAL_LOGGER { \
+ GRN_LOG_DEFAULT_LEVEL, \
+ GRN_LOG_TIME|GRN_LOG_MESSAGE, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL \
+}
+
+static grn_logger current_logger = INITIAL_LOGGER;
void
grn_default_logger_set_max_level(grn_log_level max_level)
@@ -161,8 +242,27 @@ grn_default_logger_get_max_level(void)
}
void
+grn_default_logger_set_flags(int flags)
+{
+ default_logger.flags = flags;
+ if (current_logger.log == default_logger_log) {
+ current_logger.flags = flags;
+ }
+}
+
+int
+grn_default_logger_get_flags(void)
+{
+ return default_logger.flags;
+}
+
+void
grn_default_logger_set_path(const char *path)
{
+ if (logger_inited) {
+ CRITICAL_SECTION_ENTER(default_logger_lock);
+ }
+
if (default_logger_path) {
free(default_logger_path);
}
@@ -172,6 +272,10 @@ grn_default_logger_set_path(const char *path)
} else {
default_logger_path = NULL;
}
+
+ if (logger_inited) {
+ CRITICAL_SECTION_LEAVE(default_logger_lock);
+ }
}
const char *
@@ -206,6 +310,10 @@ current_logger_fin(grn_ctx *ctx)
if (current_logger.fin) {
current_logger.fin(ctx, current_logger.user_data);
}
+ {
+ grn_logger initial_logger = INITIAL_LOGGER;
+ current_logger = initial_logger;
+ }
}
static void
@@ -277,8 +385,28 @@ grn_logger_pass(grn_ctx *ctx, grn_log_level level)
#define LBUFSIZE 0x400
void
-grn_logger_put(grn_ctx *ctx, grn_log_level level,
- const char *file, int line, const char *func, const char *fmt, ...)
+grn_logger_put(grn_ctx *ctx,
+ grn_log_level level,
+ const char *file,
+ int line,
+ const char *func,
+ const char *fmt,
+ ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ grn_logger_putv(ctx, level, file, line, func, fmt, ap);
+ va_end(ap);
+}
+
+void
+grn_logger_putv(grn_ctx *ctx,
+ grn_log_level level,
+ const char *file,
+ int line,
+ const char *func,
+ const char *fmt,
+ va_list ap)
{
if (level <= current_logger.max_level && current_logger.log) {
char tbuf[TBUFSIZE];
@@ -291,18 +419,16 @@ grn_logger_put(grn_ctx *ctx, grn_log_level level,
grn_timeval2str(ctx, &tv, tbuf, TBUFSIZE);
}
if (current_logger.flags & GRN_LOG_MESSAGE) {
- va_list argp;
- va_start(argp, fmt);
- vsnprintf(mbuf, MBUFSIZE - 1, fmt, argp);
- va_end(argp);
- mbuf[MBUFSIZE - 1] = '\0';
+ grn_vsnprintf(mbuf, MBUFSIZE, fmt, ap);
} else {
mbuf[0] = '\0';
}
if (current_logger.flags & GRN_LOG_LOCATION) {
grn_snprintf(lbuf, LBUFSIZE, LBUFSIZE,
- "%d %s:%d %s()", getpid(), file, line, func);
- lbuf[LBUFSIZE - 1] = '\0';
+ "%d %s:%d %s()", grn_getpid(), file, line, func);
+ } else if (current_logger.flags & GRN_LOG_PID) {
+ grn_snprintf(lbuf, LBUFSIZE, LBUFSIZE,
+ "%d", grn_getpid());
} else {
lbuf[0] = '\0';
}
@@ -314,8 +440,12 @@ grn_logger_put(grn_ctx *ctx, grn_log_level level,
void
grn_logger_init(void)
{
- grn_memcpy(&current_logger, &default_logger, sizeof(grn_logger));
CRITICAL_SECTION_INIT(default_logger_lock);
+ if (!current_logger.log) {
+ current_logger = default_logger;
+ }
+
+ logger_inited = GRN_TRUE;
}
void
@@ -327,15 +457,72 @@ grn_logger_fin(grn_ctx *ctx)
default_logger_path = NULL;
}
CRITICAL_SECTION_FIN(default_logger_lock);
+
+ logger_inited = GRN_FALSE;
}
+static grn_bool query_logger_inited = GRN_FALSE;
static char *default_query_logger_path = NULL;
static FILE *default_query_logger_file = NULL;
static grn_critical_section default_query_logger_lock;
static off_t default_query_logger_size = 0;
static off_t default_query_logger_rotate_threshold_size = 0;
+grn_bool
+grn_query_log_flags_parse(const char *string,
+ int string_size,
+ unsigned int *flags)
+{
+ const char *string_end;
+
+ *flags = GRN_QUERY_LOG_NONE;
+
+ if (!string) {
+ return GRN_TRUE;
+ }
+
+ if (string_size < 0) {
+ string_size = strlen(string);
+ }
+
+ string_end = string + string_size;
+
+ while (string < string_end) {
+ if (*string == '|' || *string == ' ') {
+ string += 1;
+ continue;
+ }
+
+#define CHECK_FLAG(name) \
+ if (((string_end - string) >= (sizeof(#name) - 1)) && \
+ (memcmp(string, #name, sizeof(#name) - 1) == 0) && \
+ (((string_end - string) == (sizeof(#name) - 1)) || \
+ (string[sizeof(#name) - 1] == '|') || \
+ (string[sizeof(#name) - 1] == ' '))) { \
+ *flags |= GRN_QUERY_LOG_ ## name; \
+ string += sizeof(#name) - 1; \
+ continue; \
+ }
+
+ CHECK_FLAG(NONE);
+ CHECK_FLAG(COMMAND);
+ CHECK_FLAG(RESULT_CODE);
+ CHECK_FLAG(DESTINATION);
+ CHECK_FLAG(CACHE);
+ CHECK_FLAG(SIZE);
+ CHECK_FLAG(SCORE);
+ CHECK_FLAG(ALL);
+ CHECK_FLAG(DEFAULT);
+
+#undef CHECK_FLAG
+
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
static void
default_query_logger_log(grn_ctx *ctx, unsigned int flag,
const char *timestamp, const char *info,
@@ -348,7 +535,7 @@ default_query_logger_log(grn_ctx *ctx, unsigned int flag,
default_query_logger_size = 0;
if (default_query_logger_file) {
struct stat stat;
- if (fstat(fileno(default_query_logger_file), &stat) != -1) {
+ if (fstat(grn_fileno(default_query_logger_file), &stat) != -1) {
default_query_logger_size = stat.st_size;
}
}
@@ -412,13 +599,15 @@ static grn_query_logger default_query_logger = {
default_query_logger_fin
};
-static grn_query_logger current_query_logger = {
- GRN_QUERY_LOG_DEFAULT,
- NULL,
- NULL,
- NULL,
- NULL
-};
+#define INITIAL_QUERY_LOGGER { \
+ GRN_QUERY_LOG_DEFAULT, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL \
+}
+
+static grn_query_logger current_query_logger = INITIAL_QUERY_LOGGER;
void
grn_default_query_logger_set_flags(unsigned int flags)
@@ -438,6 +627,10 @@ grn_default_query_logger_get_flags(void)
void
grn_default_query_logger_set_path(const char *path)
{
+ if (query_logger_inited) {
+ CRITICAL_SECTION_ENTER(default_query_logger_lock);
+ }
+
if (default_query_logger_path) {
free(default_query_logger_path);
}
@@ -447,6 +640,10 @@ grn_default_query_logger_set_path(const char *path)
} else {
default_query_logger_path = NULL;
}
+
+ if (query_logger_inited) {
+ CRITICAL_SECTION_LEAVE(default_query_logger_lock);
+ }
}
const char *
@@ -481,6 +678,10 @@ current_query_logger_fin(grn_ctx *ctx)
if (current_query_logger.fin) {
current_query_logger.fin(ctx, current_query_logger.user_data);
}
+ {
+ grn_query_logger initial_query_logger = INITIAL_QUERY_LOGGER;
+ current_query_logger = initial_query_logger;
+ }
}
grn_rc
@@ -495,6 +696,30 @@ grn_query_logger_set(grn_ctx *ctx, const grn_query_logger *logger)
return GRN_SUCCESS;
}
+void
+grn_query_logger_set_flags(grn_ctx *ctx, unsigned int flags)
+{
+ current_query_logger.flags = flags;
+}
+
+void
+grn_query_logger_add_flags(grn_ctx *ctx, unsigned int flags)
+{
+ current_query_logger.flags |= flags;
+}
+
+void
+grn_query_logger_remove_flags(grn_ctx *ctx, unsigned int flags)
+{
+ current_query_logger.flags &= ~flags;
+}
+
+unsigned int
+grn_query_logger_get_flags(grn_ctx *ctx)
+{
+ return current_query_logger.flags;
+}
+
grn_bool
grn_query_logger_pass(grn_ctx *ctx, unsigned int flag)
{
@@ -558,9 +783,10 @@ grn_query_logger_put(grn_ctx *ctx, unsigned int flag, const char *mark,
void
grn_query_logger_init(void)
{
- grn_memcpy(&current_query_logger,
- &default_query_logger, sizeof(grn_query_logger));
+ current_query_logger = default_query_logger;
CRITICAL_SECTION_INIT(default_query_logger_lock);
+
+ query_logger_inited = GRN_TRUE;
}
void
@@ -572,6 +798,8 @@ grn_query_logger_fin(grn_ctx *ctx)
default_query_logger_path = NULL;
}
CRITICAL_SECTION_FIN(default_query_logger_lock);
+
+ query_logger_inited = GRN_FALSE;
}
void
diff --git a/storage/mroonga/vendor/groonga/lib/metadata.rc.in b/storage/mroonga/vendor/groonga/lib/metadata.rc.in
new file mode 100644
index 00000000000..0c43cd7d565
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/metadata.rc.in
@@ -0,0 +1,28 @@
+#include <windows.h>
+
+#define LANG_CODE_US_ENGLISH 0x0409
+#define CHARSET_UNICODE 0x04b0
+#define US_ENGLISH_UNICODE "040904b0"
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION 0,@GRN_VERSION_RC@
+PRODUCTVERSION 0,@GRN_VERSION_RC@
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK US_ENGLISH_UNICODE
+ BEGIN
+ VALUE "CompanyName", "Groonga project"
+ VALUE "FileDescription", "Full text search engine library"
+ VALUE "FileVersion", "@GRN_VERSION@"
+ VALUE "InternalName", "libgroonga"
+ VALUE "OriginalFilename", "@GRN_DLL_FILENAME@"
+ VALUE "ProductName", "libgroonga"
+ VALUE "ProductVersion", "@GRN_VERSION@"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", LANG_CODE_US_ENGLISH, CHARSET_UNICODE
+ END
+END
diff --git a/storage/mroonga/vendor/groonga/lib/mrb.c b/storage/mroonga/vendor/groonga/lib/mrb.c
index d406c2d356a..3293c0196ad 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2015 Brazil
+ Copyright(C) 2013-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -38,6 +38,7 @@
#define E_LOAD_ERROR (mrb_class_get(mrb, "LoadError"))
static char grn_mrb_ruby_scripts_dir[GRN_ENV_BUFFER_SIZE];
+static grn_bool grn_mrb_order_by_estimated_size_enable = GRN_FALSE;
void
grn_mrb_init_from_env(void)
@@ -45,28 +46,45 @@ grn_mrb_init_from_env(void)
grn_getenv("GRN_RUBY_SCRIPTS_DIR",
grn_mrb_ruby_scripts_dir,
GRN_ENV_BUFFER_SIZE);
+ {
+ char grn_order_by_estimated_size_enable_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_ORDER_BY_ESTIMATED_SIZE_ENABLE",
+ grn_order_by_estimated_size_enable_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (strcmp(grn_order_by_estimated_size_enable_env, "yes") == 0) {
+ grn_mrb_order_by_estimated_size_enable = GRN_TRUE;
+ } else {
+ grn_mrb_order_by_estimated_size_enable = GRN_FALSE;
+ }
+ }
+}
+
+grn_bool
+grn_mrb_is_order_by_estimated_size_enabled(void)
+{
+ return grn_mrb_order_by_estimated_size_enable;
}
#ifdef GRN_WITH_MRUBY
# ifdef WIN32
-static char *win32_ruby_scripts_dir = NULL;
-static char win32_ruby_scripts_dir_buffer[PATH_MAX];
+static char *windows_ruby_scripts_dir = NULL;
+static char windows_ruby_scripts_dir_buffer[PATH_MAX];
static const char *
grn_mrb_get_default_system_ruby_scripts_dir(void)
{
- if (!win32_ruby_scripts_dir) {
+ if (!windows_ruby_scripts_dir) {
const char *base_dir;
const char *relative_path = GRN_RELATIVE_RUBY_SCRIPTS_DIR;
size_t base_dir_length;
- base_dir = grn_win32_base_dir();
+ base_dir = grn_windows_base_dir();
base_dir_length = strlen(base_dir);
- grn_strcpy(win32_ruby_scripts_dir_buffer, PATH_MAX, base_dir);
- grn_strcat(win32_ruby_scripts_dir_buffer, PATH_MAX, "/");
- grn_strcat(win32_ruby_scripts_dir_buffer, PATH_MAX, relative_path);
- win32_ruby_scripts_dir = win32_ruby_scripts_dir_buffer;
+ grn_strcpy(windows_ruby_scripts_dir_buffer, PATH_MAX, base_dir);
+ grn_strcat(windows_ruby_scripts_dir_buffer, PATH_MAX, "/");
+ grn_strcat(windows_ruby_scripts_dir_buffer, PATH_MAX, relative_path);
+ windows_ruby_scripts_dir = windows_ruby_scripts_dir_buffer;
}
- return win32_ruby_scripts_dir;
+ return windows_ruby_scripts_dir;
}
# else /* WIN32 */
@@ -94,7 +112,7 @@ grn_mrb_is_absolute_path(const char *path)
return GRN_TRUE;
}
- if (isalpha(path[0]) && path[1] == ':' && path[2] == '/') {
+ if (isalpha((unsigned char)path[0]) && path[1] == ':' && path[2] == '/') {
return GRN_TRUE;
}
@@ -159,12 +177,9 @@ grn_mrb_load(grn_ctx *ctx, const char *path)
file = grn_fopen(expanded_path, "r");
if (!file) {
- char message[BUFFER_SIZE];
mrb_value exception;
- grn_snprintf(message, BUFFER_SIZE, BUFFER_SIZE,
- "fopen: failed to open mruby script file: <%s>",
- expanded_path);
- SERR(message);
+ SERR("fopen: failed to open mruby script file: <%s>",
+ expanded_path);
exception = mrb_exc_new(mrb, E_LOAD_ERROR,
ctx->errbuf, strlen(ctx->errbuf));
mrb->exc = mrb_obj_ptr(exception);
@@ -192,6 +207,7 @@ grn_mrb_load(grn_ctx *ctx, const char *path)
{
struct RProc *proc;
proc = mrb_generate_code(mrb, parser);
+ proc->target_class = mrb->object_class;
result = mrb_toplevel_run(mrb, proc);
}
mrb_parser_free(parser);
@@ -201,85 +217,4 @@ grn_mrb_load(grn_ctx *ctx, const char *path)
return result;
}
-
-mrb_value
-grn_mrb_eval(grn_ctx *ctx, const char *script, int script_length)
-{
- grn_mrb_data *data = &(ctx->impl->mrb);
- mrb_state *mrb = data->state;
- mrb_value result;
- struct mrb_parser_state *parser;
-
- if (!mrb) {
- return mrb_nil_value();
- }
-
- if (script_length < 0) {
- script_length = strlen(script);
- }
- parser = mrb_parse_nstring(mrb, script, script_length, NULL);
- {
- struct RProc *proc;
- struct RClass *eval_context_class;
- mrb_value eval_context;
-
- proc = mrb_generate_code(mrb, parser);
- eval_context_class = mrb_class_get_under(mrb, data->module, "EvalContext");
- eval_context = mrb_obj_new(mrb, eval_context_class, 0, NULL);
- result = mrb_context_run(mrb, proc, eval_context, 0);
- }
- mrb_parser_free(parser);
-
- return result;
-}
-
-grn_rc
-grn_mrb_to_grn(grn_ctx *ctx, mrb_value mrb_object, grn_obj *grn_object)
-{
- grn_rc rc = GRN_SUCCESS;
- grn_mrb_data *data = &(ctx->impl->mrb);
- mrb_state *mrb = data->state;
-
- switch (mrb_type(mrb_object)) {
- case MRB_TT_FALSE :
- if (mrb_nil_p(mrb_object)) {
- grn_obj_reinit(ctx, grn_object, GRN_DB_VOID, 0);
- } else {
- grn_obj_reinit(ctx, grn_object, GRN_DB_BOOL, 0);
- GRN_BOOL_SET(ctx, grn_object, GRN_FALSE);
- }
- break;
- case MRB_TT_TRUE :
- grn_obj_reinit(ctx, grn_object, GRN_DB_BOOL, 0);
- GRN_BOOL_SET(ctx, grn_object, GRN_TRUE);
- break;
- case MRB_TT_FIXNUM :
- grn_obj_reinit(ctx, grn_object, GRN_DB_INT32, 0);
- GRN_INT32_SET(ctx, grn_object, mrb_fixnum(mrb_object));
- break;
- case MRB_TT_STRING :
- grn_obj_reinit(ctx, grn_object, GRN_DB_TEXT, 0);
- GRN_TEXT_SET(ctx, grn_object,
- RSTRING_PTR(mrb_object),
- RSTRING_LEN(mrb_object));
- break;
- case MRB_TT_SYMBOL :
- {
- const char *name;
- int name_length;
-
- grn_obj_reinit(ctx, grn_object, GRN_DB_TEXT, 0);
- GRN_BULK_REWIND(grn_object);
- GRN_TEXT_PUTC(ctx, grn_object, ':');
- name = mrb_sym2name_len(mrb, mrb_symbol(mrb_object), &name_length);
- GRN_TEXT_PUT(ctx, grn_object, name, name_length);
- }
- break;
- default :
- rc = GRN_INVALID_ARGUMENT;
- break;
- }
-
- return rc;
-}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/Makefile.am
index 13b4aeb57d3..0e4db6348c8 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/Makefile.am
+++ b/storage/mroonga/vendor/groonga/lib/mrb/Makefile.am
@@ -4,7 +4,8 @@ SUBDIRS = \
AM_CPPFLAGS = \
-I$(top_builddir) \
-I$(top_srcdir)/include \
- -I$(top_srcdir)/lib
+ -I$(top_srcdir)/lib \
+ $(MRUBY_CPPFLAGS)
AM_CFLAGS = \
$(NO_STRICT_ALIASING_CFLAGS) \
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c
index daa0caada06..0ef790544ba 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c
@@ -25,6 +25,7 @@
#include <mruby/data.h>
#include "../grn_db.h"
+#include "mrb_ctx.h"
#include "mrb_accessor.h"
#include "mrb_converter.h"
@@ -71,6 +72,30 @@ mrb_grn_accessor_object(mrb_state *mrb, mrb_value self)
return grn_mrb_value_from_grn_obj(mrb, accessor->obj);
}
+static mrb_value
+mrb_grn_accessor_name(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_rc rc;
+ grn_obj *accessor;
+ grn_obj name;
+ mrb_value mrb_name;
+
+ accessor = DATA_PTR(self);
+ GRN_TEXT_INIT(&name, 0);
+ rc = grn_column_name_(ctx, accessor, &name);
+ if (rc == GRN_SUCCESS) {
+ mrb_name = mrb_str_new(mrb, GRN_TEXT_VALUE(&name), GRN_TEXT_LEN(&name));
+ GRN_OBJ_FIN(ctx, &name);
+ } else {
+ mrb_name = mrb_nil_value();
+ GRN_OBJ_FIN(ctx, &name);
+ grn_mrb_ctx_check(mrb);
+ }
+
+ return mrb_name;
+}
+
void
grn_mrb_accessor_init(grn_ctx *ctx)
{
@@ -89,5 +114,8 @@ grn_mrb_accessor_init(grn_ctx *ctx)
mrb_grn_accessor_have_next_p, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "object",
mrb_grn_accessor_object, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "name",
+ mrb_grn_accessor_name, MRB_ARGS_NONE());
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.h
index 7b27e6375ec..f8aca1e870f 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2014 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_ACCESSOR_H
-#define GRN_MRB_ACCESSOR_H
+#pragma once
#include "../grn_ctx.h"
#include "../grn_db.h"
@@ -32,4 +31,3 @@ void grn_mrb_accessor_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_ACCESSOR_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c
index f90a7c6a639..ab0b3e57bbd 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2015 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -32,7 +32,7 @@ static struct mrb_data_type mrb_grn_array_type = {
};
static mrb_value
-mrb_grn_array_singleton_create(mrb_state *mrb, mrb_value klass)
+mrb_grn_array_class_create(mrb_state *mrb, mrb_value klass)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
char *name;
@@ -82,9 +82,9 @@ grn_mrb_array_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "Array", table_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
- mrb_define_singleton_method(mrb, (struct RObject *)klass, "create",
- mrb_grn_array_singleton_create,
- MRB_ARGS_REQ(2));
+ mrb_define_class_method(mrb, klass, "create",
+ mrb_grn_array_class_create,
+ MRB_ARGS_REQ(2));
mrb_define_method(mrb, klass, "initialize",
mrb_grn_array_initialize, MRB_ARGS_REQ(1));
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.h
index 062281684ee..39e8f5f81c8 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_ARRAY_H
-#define GRN_MRB_ARRAY_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_array_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_ARRAY_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c
index 84cfb8dc204..6fa4258673e 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014-2015 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -17,6 +17,7 @@
*/
#include "../grn_ctx_impl.h"
+#include <string.h>
#ifdef GRN_WITH_MRUBY
#include <mruby.h>
@@ -72,13 +73,30 @@ grn_mrb_value_to_bulk(mrb_state *mrb, mrb_value mrb_value_, grn_obj *bulk)
GRN_FLOAT_SET(ctx, bulk, mrb_float(mrb_value_));
break;
case MRB_TT_STRING :
- grn_obj_reinit(ctx, bulk, GRN_DB_TEXT, 0);
+ grn_obj_reinit(ctx, bulk, GRN_DB_TEXT,
+ bulk->header.impl_flags & GRN_OBJ_DO_SHALLOW_COPY);
GRN_TEXT_SET(ctx, bulk, RSTRING_PTR(mrb_value_), RSTRING_LEN(mrb_value_));
break;
default :
- mrb_raisef(mrb, E_ARGUMENT_ERROR,
- "unsupported object to convert to bulk: %S",
- mrb_value_);
+ {
+ struct RClass *klass;
+
+ klass = mrb_class(mrb, mrb_value_);
+ if (klass == ctx->impl->mrb.builtin.time_class) {
+ mrb_value mrb_sec;
+ mrb_value mrb_usec;
+
+ mrb_sec = mrb_funcall(mrb, mrb_value_, "to_i", 0);
+ mrb_usec = mrb_funcall(mrb, mrb_value_, "usec", 0);
+ grn_obj_reinit(ctx, bulk, GRN_DB_TIME, 0);
+ GRN_TIME_SET(ctx, bulk,
+ GRN_TIME_PACK(mrb_fixnum(mrb_sec), mrb_fixnum(mrb_usec)));
+ } else {
+ mrb_raisef(mrb, E_ARGUMENT_ERROR,
+ "unsupported object to convert to bulk: %S",
+ mrb_value_);
+ }
+ }
break;
}
@@ -91,7 +109,46 @@ grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk)
mrb_value mrb_value_;
grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ if (!bulk) {
+ return mrb_nil_value();
+ }
+
switch (bulk->header.domain) {
+ case GRN_DB_BOOL :
+ {
+ grn_bool value;
+ value = GRN_BOOL_VALUE(bulk);
+ mrb_value_ = mrb_bool_value(value);
+ }
+ break;
+ case GRN_DB_INT8 :
+ {
+ int8_t value;
+ value = GRN_INT8_VALUE(bulk);
+ mrb_value_ = mrb_fixnum_value(value);
+ }
+ break;
+ case GRN_DB_UINT8 :
+ {
+ uint8_t value;
+ value = GRN_UINT8_VALUE(bulk);
+ mrb_value_ = mrb_fixnum_value(value);
+ }
+ break;
+ case GRN_DB_INT16 :
+ {
+ int16_t value;
+ value = GRN_INT16_VALUE(bulk);
+ mrb_value_ = mrb_fixnum_value(value);
+ }
+ break;
+ case GRN_DB_UINT16 :
+ {
+ uint16_t value;
+ value = GRN_UINT16_VALUE(bulk);
+ mrb_value_ = mrb_fixnum_value(value);
+ }
+ break;
case GRN_DB_INT32 :
{
int32_t value;
@@ -103,37 +160,70 @@ grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk)
{
int64_t value;
value = GRN_UINT32_VALUE(bulk);
- if (!FIXABLE(value)) {
- mrb_raisef(mrb, E_RANGE_ERROR,
- "can't handle large number: <%S>: max: <%S>",
- mrb_fixnum_value(value), /* TODO: This will cause overflow */
- mrb_fixnum_value(MRB_INT_MAX));
+ if (FIXABLE(value)) {
+ mrb_value_ = mrb_fixnum_value(value);
+ } else {
+ mrb_value_ = mrb_float_value(mrb, value);
}
- mrb_value_ = mrb_fixnum_value(value);
+ }
+ break;
+ case GRN_DB_INT64 :
+ {
+ int64_t value;
+ value = GRN_INT64_VALUE(bulk);
+ if (FIXABLE(value)) {
+ mrb_value_ = mrb_fixnum_value(value);
+ } else {
+ mrb_value_ = mrb_float_value(mrb, value);
+ }
+ }
+ break;
+ case GRN_DB_UINT64 :
+ {
+ uint64_t value;
+ value = GRN_UINT64_VALUE(bulk);
+ if (FIXABLE(value)) {
+ mrb_value_ = mrb_fixnum_value(value);
+ } else {
+ mrb_value_ = mrb_float_value(mrb, value);
+ }
+ }
+ break;
+ case GRN_DB_FLOAT :
+ {
+ double value;
+ value = GRN_FLOAT_VALUE(bulk);
+ mrb_value_ = mrb_float_value(mrb, value);
}
break;
case GRN_DB_TIME :
{
int64_t value;
- int32_t sec;
+ int64_t sec;
int32_t usec;
+ mrb_value mrb_sec;
value = GRN_TIME_VALUE(bulk);
GRN_TIME_UNPACK(value, sec, usec);
+ if (sec > MRB_INT_MAX) {
+ mrb_sec = mrb_float_value(mrb, sec);
+ } else {
+ mrb_sec = mrb_fixnum_value(sec);
+ }
mrb_value_ = mrb_funcall(mrb,
mrb_obj_value(ctx->impl->mrb.builtin.time_class),
"at",
2,
- mrb_fixnum_value(sec),
+ mrb_sec,
mrb_fixnum_value(usec));
}
break;
case GRN_DB_SHORT_TEXT :
case GRN_DB_TEXT :
case GRN_DB_LONG_TEXT :
- mrb_value_ = mrb_str_new_static(mrb,
- GRN_TEXT_VALUE(bulk),
- GRN_TEXT_LEN(bulk));
+ mrb_value_ = mrb_str_new(mrb,
+ GRN_TEXT_VALUE(bulk),
+ GRN_TEXT_LEN(bulk));
break;
default :
{
@@ -198,6 +288,24 @@ grn_mrb_bulk_cast(mrb_state *mrb, grn_obj *from, grn_obj *to, grn_id domain_id)
}
static mrb_value
+mrb_grn_bulk_s_is_true(mrb_state *mrb, mrb_value klass)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_value_;
+ grn_obj bulk;
+ grn_bool is_true;
+
+ mrb_get_args(mrb, "o", &mrb_value_);
+
+ GRN_TEXT_INIT(&bulk, GRN_OBJ_DO_SHALLOW_COPY);
+ grn_mrb_value_to_bulk(mrb, mrb_value_, &bulk);
+ is_true = grn_obj_is_true(ctx, &bulk);
+ GRN_OBJ_FIN(ctx, &bulk);
+
+ return mrb_bool_value(is_true);
+}
+
+static mrb_value
mrb_grn_bulk_initialize(mrb_state *mrb, mrb_value self)
{
mrb_value mrb_bulk_ptr;
@@ -247,6 +355,10 @@ grn_mrb_bulk_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "Bulk", mrb->object_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ mrb_define_singleton_method(mrb, (struct RObject *)klass, "true?",
+ mrb_grn_bulk_s_is_true, MRB_ARGS_REQ(1));
+
mrb_define_method(mrb, klass, "initialize",
mrb_grn_bulk_initialize, MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "domain",
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h
index dd1f46fb84e..b351a78ce81 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014-2015 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_BULK_H
-#define GRN_MRB_BULK_H
+#pragma once
#include "../grn_ctx.h"
#include "../grn_db.h"
@@ -40,5 +39,3 @@ grn_bool grn_mrb_bulk_cast(mrb_state *mrb,
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_MRB_BULK_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_cache.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_cache.c
new file mode 100644
index 00000000000..c0fa33b89c4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_cache.c
@@ -0,0 +1,130 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "../grn_db.h"
+#include "../grn_cache.h"
+#include "mrb_bulk.h"
+#include "mrb_cache.h"
+
+static struct mrb_data_type mrb_grn_cache_type = {
+ "Groonga::Cache",
+ NULL
+};
+
+static mrb_value
+mrb_grn_cache_class_current(mrb_state *mrb, mrb_value klass)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_cache *cache;
+ mrb_value mrb_cache;
+
+ cache = grn_cache_current_get(ctx);
+ mrb_cache = mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, cache));
+
+ return mrb_cache;
+}
+
+static mrb_value
+mrb_grn_cache_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_cache_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_cache_ptr);
+ DATA_TYPE(self) = &mrb_grn_cache_type;
+ DATA_PTR(self) = mrb_cptr(mrb_cache_ptr);
+ return self;
+}
+
+static mrb_value
+mrb_grn_cache_fetch(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_cache *cache;
+ char *key;
+ mrb_int key_size;
+ grn_rc rc;
+ grn_obj cache_value;
+ mrb_value mrb_cache_value;
+
+ cache = DATA_PTR(self);
+ mrb_get_args(mrb, "s", &key, &key_size);
+
+ GRN_TEXT_INIT(&cache_value, 0);
+ rc = grn_cache_fetch(ctx, cache, key, key_size, &cache_value);
+ if (rc == GRN_SUCCESS) {
+ mrb_cache_value = grn_mrb_value_from_bulk(mrb, &cache_value);
+ } else {
+ mrb_cache_value = mrb_nil_value();
+ }
+ GRN_OBJ_FIN(ctx, &cache_value);
+
+ return mrb_cache_value;
+}
+
+static mrb_value
+mrb_grn_cache_update(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_cache *cache;
+ char *key;
+ mrb_int key_size;
+ char *value;
+ mrb_int value_size;
+ grn_obj value_buffer;
+
+ cache = DATA_PTR(self);
+ mrb_get_args(mrb, "ss", &key, &key_size, &value, &value_size);
+
+ GRN_TEXT_INIT(&value_buffer, GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_TEXT_SET(ctx, &value_buffer, value, value_size);
+ grn_cache_update(ctx, cache, key, key_size, &value_buffer);
+ GRN_OBJ_FIN(ctx, &value_buffer);
+
+ return mrb_nil_value();
+}
+
+void
+grn_mrb_cache_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "Cache", mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ mrb_define_class_method(mrb, klass, "current",
+ mrb_grn_cache_class_current, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_cache_initialize, MRB_ARGS_REQ(1));
+
+ mrb_define_method(mrb, klass, "fetch",
+ mrb_grn_cache_fetch, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "update",
+ mrb_grn_cache_update, MRB_ARGS_REQ(2));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_cache.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_cache.h
new file mode 100644
index 00000000000..0eb7963b2bd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_cache.h
@@ -0,0 +1,33 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+#include "../grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_cache_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c
index 68aadce6658..268558dd359 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2014 Brazil
+ Copyright(C) 2013-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -17,6 +17,7 @@
*/
#include "../grn_ctx_impl.h"
+#include "../grn_proc.h"
#ifdef GRN_WITH_MRUBY
#include <mruby.h>
@@ -29,11 +30,29 @@
#include "mrb_converter.h"
static mrb_value
+mrb_grn_column_class_parse_flags(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ char *error_message_tag;
+ char *flags_text;
+ mrb_int flags_text_size;
+ grn_column_flags flags;
+
+ mrb_get_args(mrb, "zs", &error_message_tag, &flags_text, &flags_text_size);
+
+ flags = grn_proc_column_parse_flags(ctx,
+ error_message_tag,
+ flags_text,
+ flags_text + flags_text_size);
+ return mrb_fixnum_value(flags);
+}
+
+static mrb_value
mrb_grn_column_array_reference(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
grn_obj *column;
- grn_id record_id;
+ mrb_int record_id;
grn_obj *column_value;
column = DATA_PTR(self);
@@ -44,6 +63,42 @@ mrb_grn_column_array_reference(mrb_state *mrb, mrb_value self)
}
static mrb_value
+mrb_grn_column_is_scalar(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *column;
+ grn_obj_flags column_type;
+
+ column = DATA_PTR(self);
+ column_type = (column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK);
+
+ return mrb_bool_value(column_type == GRN_OBJ_COLUMN_SCALAR);
+}
+
+static mrb_value
+mrb_grn_column_is_vector(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *column;
+ grn_obj_flags column_type;
+
+ column = DATA_PTR(self);
+ column_type = (column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK);
+
+ return mrb_bool_value(column_type == GRN_OBJ_COLUMN_VECTOR);
+}
+
+static mrb_value
+mrb_grn_column_is_index(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *column;
+ grn_obj_flags column_type;
+
+ column = DATA_PTR(self);
+ column_type = (column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK);
+
+ return mrb_bool_value(column_type == GRN_OBJ_COLUMN_INDEX);
+}
+
+static mrb_value
mrb_grn_column_is_locked(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -69,6 +124,18 @@ mrb_grn_column_get_table(mrb_state *mrb, mrb_value self)
return grn_mrb_value_from_grn_obj(mrb, table);
}
+static mrb_value
+mrb_grn_column_truncate(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *column;
+
+ column = DATA_PTR(self);
+ grn_column_truncate(ctx, column);
+ grn_mrb_ctx_check(mrb);
+ return mrb_nil_value();
+}
+
void
grn_mrb_column_init(grn_ctx *ctx)
{
@@ -81,13 +148,26 @@ grn_mrb_column_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "Column", object_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_class_method(mrb, klass, "parse_flags",
+ mrb_grn_column_class_parse_flags, MRB_ARGS_REQ(2));
+
mrb_define_method(mrb, klass, "[]",
mrb_grn_column_array_reference, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "scalar?",
+ mrb_grn_column_is_scalar, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "vector?",
+ mrb_grn_column_is_vector, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "index?",
+ mrb_grn_column_is_index, MRB_ARGS_NONE());
+
mrb_define_method(mrb, klass, "locked?",
mrb_grn_column_is_locked, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "table",
mrb_grn_column_get_table, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "truncate",
+ mrb_grn_column_truncate, MRB_ARGS_NONE());
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.h
index abb99915fa5..c692e76f587 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_COLUMN_H
-#define GRN_MRB_COLUMN_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_column_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_COLUMN_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.c
index 0ff3a0d5b69..802012ebdf9 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.c
@@ -87,11 +87,27 @@ mrb_grn_command_run_wrapper(grn_ctx *ctx,
mrb_input = mrb_obj_new(mrb, command_input_class, 1, mrb_arguments);
}
mrb_funcall(mrb, mrb_command, "run_internal", 1, mrb_input);
+ if (ctx->rc == GRN_SUCCESS && mrb->exc) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_obj_name(ctx, command, name, GRN_TABLE_MAX_KEY_SIZE);
+ if (mrb->exc == mrb->nomem_err) {
+ MERR("failed to allocate memory in mruby: <%.*s>",
+ name_size, name);
+ } else {
+ mrb_value reason;
+ reason = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
+ ERR(GRN_COMMAND_ERROR,
+ "failed to run command: <%*.s>: %.*s",
+ name_size, name,
+ (int)RSTRING_LEN(reason), RSTRING_PTR(reason));
+ }
+ }
mrb_gc_arena_restore(mrb, arena_index);
}
static mrb_value
-mrb_grn_command_singleton_register(mrb_state *mrb, mrb_value klass)
+mrb_grn_command_class_register(mrb_state *mrb, mrb_value klass)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
mrb_value mrb_name;
@@ -170,9 +186,9 @@ grn_mrb_command_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "Command", procedure_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
- mrb_define_singleton_method(mrb, (struct RObject *)klass, "register",
- mrb_grn_command_singleton_register,
- MRB_ARGS_REQ(2));
+ mrb_define_class_method(mrb, klass, "register",
+ mrb_grn_command_class_register,
+ MRB_ARGS_REQ(2));
mrb_define_method(mrb, klass, "initialize",
mrb_grn_command_initialize, MRB_ARGS_REQ(1));
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.h
index 2b899df3a6d..6bbe4830a89 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_COMMAND_H
-#define GRN_MRB_COMMAND_H
+#pragma once
#include "../grn_ctx.h"
@@ -33,4 +32,3 @@ mrb_value grn_mrb_command_instantiate(grn_ctx *ctx, grn_obj *command);
}
#endif
-#endif /* GRN_MRB_COMMAND_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.h
index a4eb09779d1..074912d9295 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_COMMAND_INPUT_H
-#define GRN_MRB_COMMAND_INPUT_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_command_input_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_COMMAND_INPUT_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_version.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_version.c
new file mode 100644
index 00000000000..89ecef30981
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_version.c
@@ -0,0 +1,41 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+
+#include "mrb_command_version.h"
+
+void
+grn_mrb_command_version_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *command_version_module;
+
+ command_version_module = mrb_define_module_under(mrb, module,
+ "CommandVersion");
+
+ mrb_define_const(mrb, command_version_module, "DEFAULT",
+ mrb_fixnum_value(GRN_COMMAND_VERSION_DEFAULT));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_version.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_version.h
new file mode 100644
index 00000000000..556964a7b71
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_version.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_command_version_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_config.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_config.c
new file mode 100644
index 00000000000..ae94d2d5118
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_config.c
@@ -0,0 +1,90 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/string.h>
+
+#include "../grn_mrb.h"
+#include "mrb_config.h"
+#include "mrb_ctx.h"
+
+static mrb_value
+config_array_reference(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ char *key;
+ mrb_int key_size;
+ const char *value;
+ uint32_t value_size;
+ grn_rc rc;
+
+ mrb_get_args(mrb, "s", &key, &key_size);
+
+ rc = grn_config_get(ctx, key, key_size, &value, &value_size);
+ if (rc != GRN_SUCCESS) {
+ grn_mrb_ctx_check(mrb);
+ }
+
+ if (!value) {
+ return mrb_nil_value();
+ } else {
+ return mrb_str_new(mrb, value, value_size);
+ }
+}
+
+static mrb_value
+config_array_set(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ char *key;
+ mrb_int key_size;
+ mrb_value mrb_value_;
+ grn_rc rc;
+
+ mrb_get_args(mrb, "sS", &key, &key_size, &mrb_value_);
+
+ rc = grn_config_set(ctx,
+ key, key_size,
+ RSTRING_PTR(mrb_value_), RSTRING_LEN(mrb_value_));
+ if (rc != GRN_SUCCESS) {
+ grn_mrb_ctx_check(mrb);
+ }
+
+ return mrb_value_;
+}
+
+void
+grn_mrb_config_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module;
+
+ module = mrb_define_module_under(mrb, data->module, "Config");
+
+ mrb_define_singleton_method(mrb, (struct RObject *)module,
+ "[]", config_array_reference,
+ MRB_ARGS_REQ(1));
+ mrb_define_singleton_method(mrb, (struct RObject *)module,
+ "[]=", config_array_set,
+ MRB_ARGS_REQ(2));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_config.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_config.h
new file mode 100644
index 00000000000..5b6c95eb849
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_config.h
@@ -0,0 +1,31 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_config_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.h
index 46103ff1a62..ed0b999a721 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_CONTENT_TYPE_H
-#define GRN_MRB_CONTENT_TYPE_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_content_type_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_CONTENT_TYPE_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c
index 387d921b6d0..4dae6ba2c4d 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c
@@ -18,6 +18,7 @@
#include "../grn_ctx_impl.h"
#include "../grn_db.h"
+#include <string.h>
#ifdef GRN_WITH_MRUBY
#include <mruby.h>
@@ -136,6 +137,63 @@ grn_mrb_value_to_raw_data(mrb_state *mrb,
*raw_value_size = GRN_BULK_VSIZE(&(buffer->to));
}
+mrb_value
+grn_mrb_value_from_raw_data(mrb_state *mrb,
+ grn_id domain,
+ void *raw_value,
+ unsigned int raw_value_size)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_value_;
+
+ switch (domain) {
+ case GRN_DB_INT32 :
+ if (raw_value_size == 0) {
+ mrb_value_ = mrb_fixnum_value(0);
+ } else {
+ int32_t value;
+ value = *((int32_t *)raw_value);
+ mrb_value_ = mrb_fixnum_value(value);
+ }
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ mrb_value_ = mrb_str_new(mrb,
+ raw_value,
+ raw_value_size);
+ break;
+ default :
+ {
+ grn_obj *domain_object;
+#define MESSAGE_SIZE 4096
+ char message[MESSAGE_SIZE];
+ char domain_name[GRN_TABLE_MAX_KEY_SIZE];
+ int domain_name_size;
+
+ domain_object = grn_ctx_at(ctx, domain);
+ if (domain_object) {
+ domain_name_size = grn_obj_name(ctx, domain_object,
+ domain_name, GRN_TABLE_MAX_KEY_SIZE);
+ grn_obj_unlink(ctx, domain_object);
+ } else {
+ grn_strcpy(domain_name, GRN_TABLE_MAX_KEY_SIZE, "unknown");
+ domain_name_size = strlen(domain_name);
+ }
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "unsupported raw value type: <%d>(%.*s)",
+ domain,
+ domain_name_size,
+ domain_name);
+ mrb_raise(mrb, E_RANGE_ERROR, message);
+ }
+#undef MESSAGE_SIZE
+ break;
+ }
+
+ return mrb_value_;
+}
+
struct RClass *
grn_mrb_class_from_grn_obj(mrb_state *mrb, grn_obj *object)
{
@@ -148,6 +206,9 @@ grn_mrb_class_from_grn_obj(mrb_state *mrb, grn_obj *object)
case GRN_BULK :
klass = mrb_class_get_under(mrb, data->module, "Bulk");
break;
+ case GRN_PTR :
+ klass = mrb_class_get_under(mrb, data->module, "Pointer");
+ break;
case GRN_ACCESSOR :
klass = mrb_class_get_under(mrb, data->module, "Accessor");
break;
@@ -250,7 +311,7 @@ grn_mrb_class_to_type(mrb_state *mrb, struct RClass *klass)
}
static mrb_value
-mrb_grn_converter_singleton_convert(mrb_state *mrb, mrb_value klass)
+mrb_grn_converter_class_convert(mrb_state *mrb, mrb_value klass)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
grn_obj *from = &(ctx->impl->mrb.buffer.from);
@@ -282,8 +343,8 @@ grn_mrb_converter_init(grn_ctx *ctx)
module = mrb_define_module_under(mrb, data->module, "Converter");
- mrb_define_singleton_method(mrb, (struct RObject *)module, "convert",
- mrb_grn_converter_singleton_convert,
- MRB_ARGS_REQ(2));
+ mrb_define_class_method(mrb, module, "convert",
+ mrb_grn_converter_class_convert,
+ MRB_ARGS_REQ(2));
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h
index c2cb58c0e6d..c7628a66e86 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_CONVERTER_H
-#define GRN_MRB_CONVERTER_H
+#pragma once
#include "../grn_ctx.h"
@@ -25,6 +24,9 @@
extern "C" {
#endif
+#define GRN_MRB_DATA_PTR(mrb_object) \
+ (mrb_nil_p((mrb_object)) ? NULL : DATA_PTR((mrb_object)))
+
void grn_mrb_converter_init(grn_ctx *ctx);
typedef struct {
@@ -46,6 +48,10 @@ void grn_mrb_value_to_raw_data(mrb_state *mrb,
grn_mrb_value_to_raw_data_buffer *buffer,
void **raw_value,
unsigned int *raw_value_size);
+mrb_value grn_mrb_value_from_raw_data(mrb_state *mrb,
+ grn_id domain,
+ void *raw_value,
+ unsigned int raw_value_size);
struct RClass *grn_mrb_class_from_grn_obj(mrb_state *mrb, grn_obj *object);
mrb_value grn_mrb_value_from_grn_obj(mrb_state *mrb, grn_obj *object);
@@ -56,5 +62,3 @@ grn_id grn_mrb_value_to_grn_type(mrb_state *mrb, mrb_value value);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_MRB_CONVERTER_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c
index 3814313f3d0..e4d9eed651f 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2015 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -27,6 +27,7 @@
#include "../grn_mrb.h"
#include "mrb_ctx.h"
+#include "mrb_bulk.h"
#include "mrb_converter.h"
static mrb_value
@@ -195,13 +196,65 @@ ctx_set_error_message(mrb_state *mrb, mrb_value self)
mrb_get_args(mrb, "S", &error_message);
grn_ctx_log(ctx, "%.*s",
- RSTRING_LEN(error_message),
+ (int)RSTRING_LEN(error_message),
RSTRING_PTR(error_message));
return error_message;
}
static mrb_value
+ctx_clear_error(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ ERRCLR(ctx);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+ctx_get_command_version(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ return mrb_fixnum_value(grn_ctx_get_command_version(ctx));
+}
+
+static mrb_value
+ctx_set_command_version(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_int command_version;
+
+ mrb_get_args(mrb, "i", &command_version);
+ grn_ctx_set_command_version(ctx, command_version);
+
+ return mrb_fixnum_value(command_version);
+}
+
+static mrb_value
+ctx_get_output(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ return grn_mrb_value_from_bulk(mrb, ctx->impl->output.buf);
+}
+
+static mrb_value
+ctx_set_output(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_value_;
+
+ mrb_get_args(mrb, "S", &mrb_value_);
+ GRN_TEXT_SET(ctx, ctx->impl->output.buf,
+ RSTRING_PTR(mrb_value_),
+ RSTRING_LEN(mrb_value_));
+
+ return mrb_value_;
+}
+
+static mrb_value
ctx_get_database(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -209,13 +262,24 @@ ctx_get_database(mrb_state *mrb, mrb_value self)
return grn_mrb_value_from_grn_obj(mrb, grn_ctx_db(ctx));
}
+static mrb_value
+ctx_is_opened(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_int mrb_id;
+
+ mrb_get_args(mrb, "i", &mrb_id);
+
+ return mrb_bool_value(grn_ctx_is_opened(ctx, mrb_id));
+}
+
void
grn_mrb_ctx_check(mrb_state *mrb)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
grn_mrb_data *data = &(ctx->impl->mrb);
struct RClass *module = data->module;
- struct RClass *error_class;
+ struct RClass *error_class = NULL;
#define MESSAGE_SIZE 4096
char message[MESSAGE_SIZE];
@@ -662,12 +726,55 @@ grn_mrb_ctx_check(mrb_state *mrb)
"normalizer error: <%s>(%d)",
ctx->errbuf, ctx->rc);
break;
- default:
+ case GRN_TOKEN_FILTER_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "TokenFilterError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "token filter error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_COMMAND_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "CommandError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "command error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_PLUGIN_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "PluginError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "plugin error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_SCORER_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "ScorerError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "scorer error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_CANCEL:
+ error_class = mrb_class_get_under(mrb, module, "Cancel");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "cancel: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_WINDOW_FUNCTION_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "WindowFunctionError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "window function error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_ZSTD_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "ZstdError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "Zstandard error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ }
+
+ if (!error_class) {
error_class = mrb_class_get_under(mrb, module, "Error");
grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
"unsupported error: <%s>(%d)",
ctx->errbuf, ctx->rc);
- break;
}
#undef MESSAGE_SIZE
@@ -711,8 +818,21 @@ grn_mrb_ctx_init(grn_ctx *ctx)
MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "error_message=", ctx_set_error_message,
MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "clear_error", ctx_clear_error, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "command_version",
+ ctx_get_command_version, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "command_version=",
+ ctx_set_command_version, MRB_ARGS_REQ(1));
+
+ mrb_define_method(mrb, klass, "output",
+ ctx_get_output, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "output=",
+ ctx_set_output, MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "database", ctx_get_database,
MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "opened?", ctx_is_opened,
+ MRB_ARGS_REQ(1));
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.h
index aa527bfec51..b94128292af 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_CTX_H
-#define GRN_MRB_CTX_H
+#pragma once
#include "../grn_ctx.h"
@@ -32,4 +31,3 @@ void grn_mrb_ctx_check(mrb_state *mrb);
}
#endif
-#endif /* GRN_MRB_CTX_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.c
index 22994104add..f9133167a4f 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2015 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,7 @@
#include "mrb_ctx.h"
#include "mrb_database.h"
+#include "mrb_converter.h"
static struct mrb_data_type mrb_grn_database_type = {
"Groonga::Database",
@@ -43,7 +44,7 @@ mrb_grn_database_initialize(mrb_state *mrb, mrb_value self)
}
static mrb_value
-mrb_grn_database_singleton_open(mrb_state *mrb, mrb_value klass)
+mrb_grn_database_class_open(mrb_state *mrb, mrb_value klass)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
grn_obj *database;
@@ -58,7 +59,7 @@ mrb_grn_database_singleton_open(mrb_state *mrb, mrb_value klass)
}
static mrb_value
-mrb_grn_database_singleton_create(mrb_state *mrb, mrb_value klass)
+mrb_grn_database_class_create(mrb_state *mrb, mrb_value klass)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
grn_obj *database;
@@ -95,6 +96,81 @@ mrb_grn_database_is_locked(mrb_state *mrb, mrb_value self)
return mrb_bool_value(is_locked != 0);
}
+static mrb_value
+mrb_grn_database_get_last_modified(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ uint32_t last_modified;
+ struct RClass *time_class;
+
+ last_modified = grn_db_get_last_modified(ctx, DATA_PTR(self));
+
+ time_class = mrb_class_get(mrb, "Time");
+ return mrb_funcall(mrb,
+ mrb_obj_value(time_class),
+ "at",
+ 1,
+ mrb_float_value(mrb, last_modified));
+}
+
+static mrb_value
+mrb_grn_database_is_dirty(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_bool is_dirty;
+
+ is_dirty = grn_db_is_dirty(ctx, DATA_PTR(self));
+
+ return mrb_bool_value(is_dirty);
+}
+
+static mrb_value
+mrb_grn_database_array_reference(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *database;
+ mrb_value mrb_id_or_key;
+
+ mrb_get_args(mrb, "o", &mrb_id_or_key);
+
+ database = DATA_PTR(self);
+
+ if (mrb_fixnum_p(mrb_id_or_key)) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+
+ name_size = grn_table_get_key(ctx,
+ grn_ctx_db(ctx),
+ mrb_fixnum(mrb_id_or_key),
+ name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ if (name_size == 0) {
+ return mrb_nil_value();
+ } else {
+ return mrb_str_new(mrb, name, name_size);
+ }
+ } else {
+ grn_id name_domain_id = GRN_DB_SHORT_TEXT;
+ grn_id id;
+ grn_mrb_value_to_raw_data_buffer buffer;
+ void *name;
+ unsigned int name_size;
+
+ grn_mrb_value_to_raw_data_buffer_init(mrb, &buffer);
+ grn_mrb_value_to_raw_data(mrb, "name", mrb_id_or_key,
+ name_domain_id, &buffer,
+ &name, &name_size);
+ id = grn_table_get(ctx, database, name, name_size);
+ grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer);
+
+ if (id == GRN_ID_NIL) {
+ return mrb_nil_value();
+ } else {
+ return mrb_fixnum_value(id);
+ }
+ }
+}
+
void
grn_mrb_database_init(grn_ctx *ctx)
{
@@ -107,12 +183,12 @@ grn_mrb_database_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "Database", object_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
- mrb_define_singleton_method(mrb, (struct RObject *)klass, "open",
- mrb_grn_database_singleton_open,
- MRB_ARGS_REQ(1));
- mrb_define_singleton_method(mrb, (struct RObject *)klass, "create",
- mrb_grn_database_singleton_create,
- MRB_ARGS_REQ(1));
+ mrb_define_class_method(mrb, klass, "open",
+ mrb_grn_database_class_open,
+ MRB_ARGS_REQ(1));
+ mrb_define_class_method(mrb, klass, "create",
+ mrb_grn_database_class_create,
+ MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "initialize",
mrb_grn_database_initialize, MRB_ARGS_REQ(1));
@@ -120,5 +196,11 @@ grn_mrb_database_init(grn_ctx *ctx)
mrb_grn_database_recover, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "locked?",
mrb_grn_database_is_locked, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "last_modified",
+ mrb_grn_database_get_last_modified, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "dirty?",
+ mrb_grn_database_is_dirty, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "[]",
+ mrb_grn_database_array_reference, MRB_ARGS_REQ(1));
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.h
index fd319c55fd1..7601cddfc94 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_DATABASE_H
-#define GRN_MRB_DATABASE_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_database_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_DATABASE_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.h
index a69a94e556e..a9109a49977 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_DOUBLE_ARRAY_TRIE_H
-#define GRN_MRB_DOUBLE_ARRAY_TRIE_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_double_array_trie_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_DOUBLE_ARRAY_TRIE_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.c
index a3513be1118..5ba86341f92 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.c
@@ -190,5 +190,13 @@ grn_mrb_error_init(grn_ctx *ctx)
groonga_error_class);
mrb_define_class_under(mrb, module, "PluginError",
groonga_error_class);
+ mrb_define_class_under(mrb, module, "ScorerError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "Cancel",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "WindowFunctionError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ZstdError",
+ groonga_error_class);
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.h
index c68c58fa273..e68805076be 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_ERROR_H
-#define GRN_MRB_ERROR_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_error_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_ERROR_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_eval_context.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_eval_context.c
new file mode 100644
index 00000000000..cd23c4eb1ec
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_eval_context.c
@@ -0,0 +1,98 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/proc.h>
+#include <mruby/compile.h>
+#include <mruby/opcode.h>
+
+#include "../grn_mrb.h"
+#include "mrb_ctx.h"
+#include "mrb_eval_context.h"
+
+static mrb_value
+eval_context_compile(mrb_state *mrb, mrb_value self)
+{
+ char *script;
+ mrb_int script_length;
+ mrbc_context* compile_ctx;
+ struct mrb_parser_state *parser;
+ struct RProc *proc;
+
+ mrb_get_args(mrb, "s", &script, &script_length);
+
+ compile_ctx = mrbc_context_new(mrb);
+ if (!compile_ctx) {
+ mrb_raise(mrb, E_RUNTIME_ERROR,
+ "[mruby][eval][compile] failed to allocate context");
+ }
+ compile_ctx->capture_errors = TRUE;
+
+ parser = mrb_parse_nstring(mrb, script, script_length, compile_ctx);
+ if (!parser) {
+ mrbc_context_free(mrb, compile_ctx);
+ mrb_raise(mrb, E_RUNTIME_ERROR,
+ "[mruby][eval][compile] failed to allocate parser");
+ }
+ if (parser->nerr > 0) {
+ struct mrb_parser_message *error = &(parser->error_buffer[0]);
+ mrb_value new_args[1];
+ mrb_value exception;
+
+ new_args[0] = mrb_format(mrb,
+ "line %S:%S: %S",
+ mrb_fixnum_value(error->lineno),
+ mrb_fixnum_value(error->column),
+ mrb_str_new_cstr(mrb, error->message));
+ exception = mrb_obj_new(mrb, E_SYNTAX_ERROR, 1, new_args);
+ mrb_parser_free(parser);
+ mrbc_context_free(mrb, compile_ctx);
+
+ mrb_exc_raise(mrb, exception);
+ }
+
+ proc = mrb_generate_code(mrb, parser);
+ {
+ mrb_code *iseq = proc->body.irep->iseq;
+ while (GET_OPCODE(*iseq) != OP_STOP) {
+ iseq++;
+ }
+ *iseq = MKOP_AB(OP_RETURN, 1, OP_R_NORMAL);
+ }
+ mrb_parser_free(parser);
+ mrbc_context_free(mrb, compile_ctx);
+ return mrb_obj_value(proc);
+}
+
+void
+grn_mrb_eval_context_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "EvalContext", mrb->object_class);
+
+ mrb_define_method(mrb, klass, "compile", eval_context_compile,
+ MRB_ARGS_REQ(1));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_eval_context.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_eval_context.h
new file mode 100644
index 00000000000..ef61ed5dd26
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_eval_context.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_eval_context_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c
index dcae12a131a..47ef3b5b11d 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2015 Brazil
+ Copyright(C) 2013-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,7 @@
#include <mruby/hash.h>
#include "../grn_expr.h"
+#include "../grn_proc.h"
#include "../grn_util.h"
#include "../grn_mrb.h"
#include "mrb_accessor.h"
@@ -104,11 +105,11 @@ mrb_grn_scan_info_put_index(mrb_state *mrb, mrb_value self)
grn_ctx *ctx = (grn_ctx *)mrb->ud;
scan_info *si;
mrb_value mrb_index;
- int sid;
- int32_t weight;
+ mrb_int sid;
+ mrb_int weight;
mrb_value mrb_scorer;
mrb_value mrb_scorer_args_expr;
- int32_t scorer_args_expr_offset;
+ mrb_int scorer_args_expr_offset;
grn_obj *index;
grn_obj *scorer = NULL;
grn_obj *scorer_args_expr = NULL;
@@ -151,7 +152,7 @@ mrb_grn_scan_info_set_op(mrb_state *mrb, mrb_value self)
mrb_value mrb_op;
grn_operator op;
- mrb_get_args(mrb, "o", &mrb_op, &op);
+ mrb_get_args(mrb, "o", &mrb_op);
si = DATA_PTR(self);
op = grn_mrb_value_to_operator(mrb, mrb_op);
grn_scan_info_set_op(si, op);
@@ -162,7 +163,7 @@ static mrb_value
mrb_grn_scan_info_set_end(mrb_state *mrb, mrb_value self)
{
scan_info *si;
- int end;
+ mrb_int end;
mrb_get_args(mrb, "i", &end);
si = DATA_PTR(self);
@@ -190,7 +191,7 @@ static mrb_value
mrb_grn_scan_info_set_flags(mrb_state *mrb, mrb_value self)
{
scan_info *si;
- int flags;
+ mrb_int flags;
mrb_get_args(mrb, "i", &flags);
si = DATA_PTR(self);
@@ -238,7 +239,7 @@ static mrb_value
mrb_grn_scan_info_set_max_interval(mrb_state *mrb, mrb_value self)
{
scan_info *si;
- int max_interval;
+ mrb_int max_interval;
mrb_get_args(mrb, "i", &max_interval);
si = DATA_PTR(self);
@@ -261,7 +262,7 @@ static mrb_value
mrb_grn_scan_info_set_similarity_threshold(mrb_state *mrb, mrb_value self)
{
scan_info *si;
- int similarity_threshold;
+ mrb_int similarity_threshold;
mrb_get_args(mrb, "i", &similarity_threshold);
si = DATA_PTR(self);
@@ -285,7 +286,7 @@ mrb_grn_scan_info_get_arg(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
scan_info *si;
- int index;
+ mrb_int index;
grn_obj *arg;
mrb_get_args(mrb, "i", &index);
@@ -312,6 +313,39 @@ mrb_grn_scan_info_push_arg(mrb_state *mrb, mrb_value self)
}
static mrb_value
+mrb_grn_scan_info_get_start_position(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ int start_position;
+
+ si = DATA_PTR(self);
+ start_position = grn_scan_info_get_start_position(si);
+ return mrb_fixnum_value(start_position);
+}
+
+static mrb_value
+mrb_grn_scan_info_set_start_position(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_int start_position;
+
+ mrb_get_args(mrb, "i", &start_position);
+ si = DATA_PTR(self);
+ grn_scan_info_set_start_position(si, start_position);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_reset_position(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+
+ si = DATA_PTR(self);
+ grn_scan_info_reset_position(si);
+ return self;
+}
+
+static mrb_value
mrb_grn_expr_code_inspect(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -347,6 +381,13 @@ mrb_grn_expr_code_inspect(mrb_state *mrb, mrb_value self)
0));
}
+ mrb_str_cat_lit(mrb, inspected, ", n_args=");
+ mrb_str_concat(mrb, inspected,
+ mrb_funcall(mrb,
+ mrb_fixnum_value(code->nargs),
+ "inspect",
+ 0));
+
mrb_str_cat_lit(mrb, inspected, ", modify=");
mrb_str_concat(mrb, inspected,
mrb_funcall(mrb,
@@ -404,6 +445,15 @@ mrb_grn_expr_code_get_value(mrb_state *mrb, mrb_value self)
}
static mrb_value
+mrb_grn_expr_code_get_n_args(mrb_state *mrb, mrb_value self)
+{
+ grn_expr_code *expr_code;
+
+ expr_code = DATA_PTR(self);
+ return mrb_fixnum_value(expr_code->nargs);
+}
+
+static mrb_value
mrb_grn_expr_code_get_op(mrb_state *mrb, mrb_value self)
{
grn_expr_code *expr_code;
@@ -422,7 +472,16 @@ mrb_grn_expr_code_get_flags(mrb_state *mrb, mrb_value self)
}
static mrb_value
-mrb_grn_expression_singleton_create(mrb_state *mrb, mrb_value klass)
+mrb_grn_expr_code_get_modify(mrb_state *mrb, mrb_value self)
+{
+ grn_expr_code *expr_code;
+
+ expr_code = DATA_PTR(self);
+ return mrb_fixnum_value(expr_code->modify);
+}
+
+static mrb_value
+mrb_grn_expression_class_create(mrb_state *mrb, mrb_value klass)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
mrb_value mrb_expr;
@@ -468,6 +527,15 @@ mrb_grn_expression_initialize(mrb_state *mrb, mrb_value self)
}
static mrb_value
+mrb_grn_expression_is_empty(mrb_state *mrb, mrb_value self)
+{
+ grn_expr *expr;
+
+ expr = DATA_PTR(self);
+ return mrb_bool_value(expr->codes_curr == 0);
+}
+
+static mrb_value
mrb_grn_expression_codes(mrb_state *mrb, mrb_value self)
{
grn_expr *expr;
@@ -485,21 +553,66 @@ mrb_grn_expression_codes(mrb_state *mrb, mrb_value self)
}
static mrb_value
-mrb_grn_expression_get_var_by_offset(mrb_state *mrb, mrb_value self)
+mrb_grn_expression_array_reference(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
grn_obj *expr;
- mrb_int offset;
+ mrb_value mrb_key;
grn_obj *var;
- mrb_get_args(mrb, "i", &offset);
+ mrb_get_args(mrb, "o", &mrb_key);
expr = DATA_PTR(self);
- var = grn_expr_get_var_by_offset(ctx, expr, offset);
+ switch (mrb_type(mrb_key)) {
+ case MRB_TT_SYMBOL :
+ {
+ const char *name;
+ mrb_int name_length;
+
+ name = mrb_sym2name_len(mrb, mrb_symbol(mrb_key), &name_length);
+ var = grn_expr_get_var(ctx, expr, name, name_length);
+ }
+ break;
+ case MRB_TT_STRING :
+ var = grn_expr_get_var(ctx, expr,
+ RSTRING_PTR(mrb_key), RSTRING_LEN(mrb_key));
+ break;
+ case MRB_TT_FIXNUM :
+ var = grn_expr_get_var_by_offset(ctx, expr, mrb_fixnum(mrb_key));
+ break;
+ default :
+ mrb_raisef(mrb, E_ARGUMENT_ERROR,
+ "key must be Symbol, String or Fixnum: %S",
+ mrb_key);
+ break;
+ }
+
return grn_mrb_value_from_grn_obj(mrb, var);
}
static mrb_value
+mrb_grn_expression_set_condition(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *expr;
+ mrb_value mrb_condition;
+ grn_obj *condition_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_condition);
+
+ expr = DATA_PTR(self);
+ condition_ptr = grn_expr_get_or_add_var(ctx,
+ expr,
+ GRN_SELECT_INTERNAL_VAR_CONDITION,
+ GRN_SELECT_INTERNAL_VAR_CONDITION_LEN);
+ GRN_OBJ_FIN(ctx, condition_ptr);
+ GRN_PTR_INIT(condition_ptr, 0, GRN_DB_OBJECT);
+ GRN_PTR_SET(ctx, condition_ptr, GRN_MRB_DATA_PTR(mrb_condition));
+
+ return mrb_nil_value();
+}
+
+static mrb_value
mrb_grn_expression_take_object(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -536,6 +649,14 @@ mrb_grn_expression_allocate_constant(mrb_state *mrb, mrb_value self)
GRN_TEXT_SET(ctx, grn_object,
RSTRING_PTR(mrb_object), RSTRING_LEN(mrb_object));
break;
+ case MRB_TT_TRUE:
+ grn_object = grn_expr_alloc_const(ctx, expr);
+ if (!grn_object) {
+ grn_mrb_ctx_check(mrb);
+ }
+ GRN_BOOL_INIT(grn_object, 0);
+ GRN_BOOL_SET(ctx, grn_object, GRN_TRUE);
+ break;
default:
mrb_raisef(mrb, E_ARGUMENT_ERROR, "unsupported type: %S", mrb_object);
break;
@@ -561,8 +682,13 @@ mrb_grn_expression_parse(mrb_state *mrb, mrb_value self)
mrb_get_args(mrb, "s|H", &query, &query_size, &mrb_options);
if (!mrb_nil_p(mrb_options)) {
+ mrb_value mrb_default_column;
mrb_value mrb_flags;
+ mrb_default_column =
+ grn_mrb_options_get_lit(mrb, mrb_options, "default_column");
+ default_column = GRN_MRB_DATA_PTR(mrb_default_column);
+
mrb_flags = grn_mrb_options_get_lit(mrb, mrb_options, "flags");
if (!mrb_nil_p(mrb_flags)) {
flags = mrb_fixnum(mrb_flags);
@@ -585,7 +711,7 @@ mrb_grn_expression_append_object(mrb_state *mrb, mrb_value self)
grn_obj *object;
mrb_value mrb_op;
grn_operator op;
- int n_args;
+ mrb_int n_args;
expr = DATA_PTR(self);
mrb_get_args(mrb, "ooi", &mrb_object, &mrb_op, &n_args);
@@ -606,7 +732,7 @@ mrb_grn_expression_append_constant(mrb_state *mrb, mrb_value self)
mrb_value mrb_constant;
mrb_value mrb_op;
grn_operator op;
- int n_args;
+ mrb_int n_args;
expr = DATA_PTR(self);
mrb_get_args(mrb, "ooi", &mrb_constant, &mrb_op, &n_args);
@@ -700,7 +826,7 @@ mrb_grn_expression_append_operator(mrb_state *mrb, mrb_value self)
grn_ctx *ctx = (grn_ctx *)mrb->ud;
grn_obj *expr;
mrb_value mrb_op;
- int n_args;
+ mrb_int n_args;
grn_operator op;
expr = DATA_PTR(self);
@@ -755,6 +881,12 @@ grn_mrb_expr_init(grn_ctx *ctx)
mrb_grn_scan_info_get_arg, MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "push_arg",
mrb_grn_scan_info_push_arg, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "start_position",
+ mrb_grn_scan_info_get_start_position, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "start_position=",
+ mrb_grn_scan_info_set_start_position, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "reset_position",
+ mrb_grn_scan_info_reset_position, MRB_ARGS_NONE());
klass = mrb_define_class_under(mrb, module,
"ExpressionCode", mrb->object_class);
@@ -767,10 +899,14 @@ grn_mrb_expr_init(grn_ctx *ctx)
mrb_grn_expr_code_get_weight, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "value",
mrb_grn_expr_code_get_value, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "n_args",
+ mrb_grn_expr_code_get_n_args, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "op",
mrb_grn_expr_code_get_op, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "flags",
mrb_grn_expr_code_get_flags, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "modify",
+ mrb_grn_expr_code_get_modify, MRB_ARGS_NONE());
{
struct RClass *expression_code_class = klass;
@@ -783,16 +919,35 @@ grn_mrb_expr_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "Expression", object_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
- mrb_define_singleton_method(mrb, (struct RObject *)klass, "create",
- mrb_grn_expression_singleton_create,
- MRB_ARGS_REQ(1));
+#define DEFINE_FLAG(name) \
+ mrb_define_const(mrb, klass, \
+ #name, \
+ mrb_fixnum_value(GRN_EXPR_ ## name))
+
+ DEFINE_FLAG(SYNTAX_QUERY);
+ DEFINE_FLAG(SYNTAX_SCRIPT);
+ DEFINE_FLAG(SYNTAX_OUTPUT_COLUMNS);
+ DEFINE_FLAG(ALLOW_PRAGMA);
+ DEFINE_FLAG(ALLOW_COLUMN);
+ DEFINE_FLAG(ALLOW_UPDATE);
+ DEFINE_FLAG(ALLOW_LEADING_NOT);
+
+#undef DEFINE_FLAG
+
+ mrb_define_class_method(mrb, klass, "create",
+ mrb_grn_expression_class_create,
+ MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "initialize",
mrb_grn_expression_initialize, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "empty?",
+ mrb_grn_expression_is_empty, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "codes",
mrb_grn_expression_codes, MRB_ARGS_NONE());
- mrb_define_method(mrb, klass, "get_var_by_offset",
- mrb_grn_expression_get_var_by_offset, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "[]",
+ mrb_grn_expression_array_reference, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "condition=",
+ mrb_grn_expression_set_condition, MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "take_object",
mrb_grn_expression_take_object, MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "allocate_constant",
@@ -809,9 +964,44 @@ grn_mrb_expr_init(grn_ctx *ctx)
mrb_grn_expression_append_operator, MRB_ARGS_REQ(2));
}
+grn_obj *
+grn_mrb_expr_rewrite(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ mrb_value mrb_expression;
+ mrb_value mrb_rewritten_expression;
+ grn_obj *rewritten_expression = NULL;
+ int arena_index;
+
+ arena_index = mrb_gc_arena_save(mrb);
+
+ mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr);
+ mrb_rewritten_expression = mrb_funcall(mrb, mrb_expression, "rewrite", 0);
+ if (mrb_nil_p(mrb_rewritten_expression)) {
+ goto exit;
+ }
+
+ if (mrb_type(mrb_rewritten_expression) == MRB_TT_EXCEPTION) {
+ mrb->exc = mrb_obj_ptr(mrb_rewritten_expression);
+ mrb_print_error(mrb);
+ goto exit;
+ }
+
+ rewritten_expression = DATA_PTR(mrb_rewritten_expression);
+
+exit:
+ mrb_gc_arena_restore(mrb, arena_index);
+
+ return rewritten_expression;
+}
+
scan_info **
-grn_mrb_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
- grn_operator op, uint32_t size)
+grn_mrb_scan_info_build(grn_ctx *ctx,
+ grn_obj *expr,
+ int *n,
+ grn_operator op,
+ grn_bool record_exist)
{
grn_mrb_data *data = &(ctx->impl->mrb);
mrb_state *mrb = data->state;
@@ -826,7 +1016,7 @@ grn_mrb_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n,
mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr);
mrb_sis = mrb_funcall(mrb, mrb_expression, "build_scan_info", 2,
grn_mrb_value_from_operator(mrb, op),
- mrb_fixnum_value(size));
+ mrb_bool_value(record_exist));
if (mrb_nil_p(mrb_sis)) {
goto exit;
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h
index 0564401dac9..14a5f975d3e 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2015 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_EXPR_H
-#define GRN_MRB_EXPR_H
+#pragma once
#include "../grn_ctx.h"
#include "../grn_expr.h"
@@ -27,7 +26,13 @@ extern "C" {
#endif
void grn_mrb_expr_init(grn_ctx *ctx);
-scan_info **grn_mrb_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, grn_operator op, uint32_t size);
+
+grn_obj *grn_mrb_expr_rewrite(grn_ctx *ctx, grn_obj *expr);
+scan_info **grn_mrb_scan_info_build(grn_ctx *ctx,
+ grn_obj *expr,
+ int *n,
+ grn_operator op,
+ grn_bool record_exist);
unsigned int grn_mrb_expr_estimate_size(grn_ctx *ctx,
grn_obj *expr,
grn_obj *table);
@@ -36,4 +41,3 @@ unsigned int grn_mrb_expr_estimate_size(grn_ctx *ctx,
}
#endif
-#endif /* GRN_MRB_EXPR_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.h
index 1037716c9f7..95d8f507a7b 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_FIXED_SIZE_COLUMN_H
-#define GRN_MRB_FIXED_SIZE_COLUMN_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_fixed_size_column_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_FIXED_SIZE_COLUMN_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c
index 31d00956137..ee71987b01c 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c
@@ -34,7 +34,7 @@ static struct mrb_data_type mrb_grn_hash_table_type = {
};
static mrb_value
-mrb_grn_hash_table_singleton_create(mrb_state *mrb, mrb_value klass)
+mrb_grn_hash_table_class_create(mrb_state *mrb, mrb_value klass)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
mrb_value mrb_options = mrb_nil_value();
@@ -107,9 +107,9 @@ grn_mrb_hash_table_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "HashTable", table_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
- mrb_define_singleton_method(mrb, (struct RObject *)klass, "create",
- mrb_grn_hash_table_singleton_create,
- MRB_ARGS_OPT(1));
+ mrb_define_class_method(mrb, klass, "create",
+ mrb_grn_hash_table_class_create,
+ MRB_ARGS_OPT(1));
mrb_define_method(mrb, klass, "initialize",
mrb_grn_hash_table_initialize, MRB_ARGS_REQ(1));
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.h
index 223267b47d9..0fc40b2ba99 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_HASH_TABLE_H
-#define GRN_MRB_HASH_TABLE_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_hash_table_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_HASH_TABLE_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_id.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_id.h
index fcfd80384b5..ff277340c4c 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_id.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_id.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_ID_H
-#define GRN_MRB_ID_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_id_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_ID_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c
index 2af198c2fdb..d31336f0a38 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c
@@ -18,9 +18,11 @@
#include "../grn_ctx_impl.h"
#include "../grn_ii.h"
+#include <string.h>
#ifdef GRN_WITH_MRUBY
#include <mruby.h>
+#include <mruby/array.h>
#include <mruby/class.h>
#include <mruby/data.h>
@@ -59,6 +61,31 @@ mrb_grn_index_column_get_lexicon(mrb_state *mrb, mrb_value self)
}
static mrb_value
+mrb_grn_index_column_get_source_ids(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *index_column;
+ grn_obj source_ids;
+ unsigned int i, n_ids;
+ mrb_value mrb_source_ids;
+
+ index_column = DATA_PTR(self);
+ GRN_RECORD_INIT(&source_ids, GRN_OBJ_VECTOR, GRN_DB_VOID);
+ grn_obj_get_info(ctx, index_column, GRN_INFO_SOURCE, &source_ids);
+ n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id);
+
+ mrb_source_ids = mrb_ary_new_capa(mrb, n_ids);
+ for (i = 0; i < n_ids; i++) {
+ grn_id source_id = GRN_RECORD_VALUE_AT(&source_ids, i);
+ mrb_ary_push(mrb, mrb_source_ids, mrb_fixnum_value(source_id));
+ }
+
+ GRN_OBJ_FIN(ctx, &source_ids);
+
+ return mrb_source_ids;
+}
+
+static mrb_value
mrb_grn_index_column_estimate_size_for_term_id(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -155,6 +182,10 @@ grn_mrb_index_column_init(grn_ctx *ctx)
mrb_grn_index_column_get_lexicon,
MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "source_ids",
+ mrb_grn_index_column_get_source_ids,
+ MRB_ARGS_NONE());
+
mrb_define_method(mrb, klass, "estimate_size_for_term_id",
mrb_grn_index_column_estimate_size_for_term_id,
MRB_ARGS_REQ(1));
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.h
index 307448fd4c3..0aa29eea8e9 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_INDEX_COLUMN_H
-#define GRN_MRB_INDEX_COLUMN_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_index_column_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_INDEX_COLUMN_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c
index 34133ff7ae0..0992661318c 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c
@@ -39,7 +39,7 @@ static struct mrb_data_type mrb_grn_index_cursor_type = {
};
static mrb_value
-mrb_grn_index_cursor_singleton_open_raw(mrb_state *mrb, mrb_value klass)
+mrb_grn_index_cursor_class_open_raw(mrb_state *mrb, mrb_value klass)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
mrb_value mrb_table_cursor;
@@ -123,7 +123,9 @@ mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self)
grn_obj *expr_variable = NULL;
int offset = 0;
int limit = 10;
+ int max_n_unmatched_records = -1;
int n_matched_records = 0;
+ int n_unmatched_records = 0;
mrb_value mrb_index;
grn_obj *index;
grn_obj *lexicon;
@@ -142,6 +144,7 @@ mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self)
mrb_value mrb_expr;
mrb_value mrb_offset;
mrb_value mrb_limit;
+ mrb_value mrb_max_n_unmatched_records;
mrb_expr = grn_mrb_options_get_lit(mrb, mrb_options, "expression");
if (!mrb_nil_p(mrb_expr)) {
@@ -158,6 +161,12 @@ mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self)
if (!mrb_nil_p(mrb_limit)) {
limit = mrb_fixnum(mrb_limit);
}
+
+ mrb_max_n_unmatched_records =
+ grn_mrb_options_get_lit(mrb, mrb_options, "max_n_unmatched_records");
+ if (!mrb_nil_p(mrb_max_n_unmatched_records)) {
+ max_n_unmatched_records = mrb_fixnum(mrb_max_n_unmatched_records);
+ }
}
if (limit <= 0) {
@@ -169,15 +178,27 @@ mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self)
lexicon = ((grn_ii *)index)->lexicon;
data_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, index));
+ if (max_n_unmatched_records < 0) {
+ max_n_unmatched_records = INT32_MAX;
+ }
while ((posting = grn_index_cursor_next(ctx, index_cursor, &term_id))) {
if (expr) {
- grn_bool matched_raw;
+ grn_bool matched_raw = GRN_FALSE;
grn_obj *matched;
GRN_RECORD_SET(ctx, expr_variable, posting->rid);
matched = grn_expr_exec(ctx, expr, 0);
- GRN_TRUEP(ctx, matched, matched_raw);
+ if (matched) {
+ matched_raw = grn_obj_is_true(ctx, matched);
+ } else {
+ grn_mrb_ctx_check(mrb);
+ }
+
if (!matched_raw) {
+ n_unmatched_records++;
+ if (n_unmatched_records > max_n_unmatched_records) {
+ return mrb_fixnum_value(-1);
+ }
continue;
}
}
@@ -186,7 +207,7 @@ mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self)
offset--;
continue;
}
- grn_ii_posting_add(ctx, (grn_ii_posting *)posting, result_set, op);
+ grn_ii_posting_add(ctx, posting, result_set, op);
limit--;
if (limit == 0) {
break;
@@ -208,9 +229,9 @@ grn_mrb_index_cursor_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "IndexCursor", mrb->object_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
- mrb_define_singleton_method(mrb, (struct RObject *)klass, "open_raw",
- mrb_grn_index_cursor_singleton_open_raw,
- MRB_ARGS_ARG(2, 1));
+ mrb_define_class_method(mrb, klass, "open_raw",
+ mrb_grn_index_cursor_class_open_raw,
+ MRB_ARGS_ARG(2, 1));
mrb_define_method(mrb, klass, "initialize",
mrb_grn_index_cursor_initialize, MRB_ARGS_REQ(1));
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.h
index afbad53db9f..0c9d7b54952 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_INDEX_CURSOR_H
-#define GRN_MRB_INDEX_CURSOR_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_index_cursor_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_INDEX_CURSOR_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_indexable.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_indexable.c
new file mode 100644
index 00000000000..47a469358d0
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_indexable.c
@@ -0,0 +1,170 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2013-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+#include "../grn_db.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/data.h>
+
+#include "mrb_ctx.h"
+#include "mrb_indexable.h"
+#include "mrb_operator.h"
+#include "mrb_converter.h"
+
+static mrb_value
+indexable_find_index(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+ mrb_value mrb_operator;
+ grn_operator operator;
+ grn_index_datum index_datum;
+ int n_index_data;
+
+ mrb_get_args(mrb, "o", &mrb_operator);
+ object = DATA_PTR(self);
+ operator = grn_mrb_value_to_operator(mrb, mrb_operator);
+ n_index_data = grn_column_find_index_data(ctx,
+ object,
+ operator,
+ &index_datum,
+ 1);
+ if (n_index_data == 0) {
+ return mrb_nil_value();
+ } else {
+ grn_mrb_data *data;
+ struct RClass *klass;
+ mrb_value args[2];
+
+ data = &(ctx->impl->mrb);
+ klass = mrb_class_get_under(mrb, data->module, "IndexInfo");
+ args[0] = grn_mrb_value_from_grn_obj(mrb, index_datum.index);
+ args[1] = mrb_fixnum_value(index_datum.section);
+ return mrb_obj_new(mrb, klass, 2, args);
+ }
+}
+
+static mrb_value
+indexable_indexes(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+ grn_index_datum index_datum;
+ grn_index_datum *index_data;
+ int i, n_index_data;
+ mrb_value mrb_indexes;
+
+ object = DATA_PTR(self);
+ n_index_data = grn_column_get_all_index_data(ctx, object, &index_datum, 1);
+ if (n_index_data == 0) {
+ return mrb_ary_new(mrb);
+ }
+
+ if (n_index_data == 1) {
+ index_data = &index_datum;
+ } else {
+ index_data = GRN_MALLOCN(grn_index_datum, n_index_data);
+ n_index_data = grn_column_get_all_index_data(ctx,
+ object,
+ index_data,
+ n_index_data);
+ }
+
+ mrb_indexes = mrb_ary_new_capa(mrb, n_index_data);
+ for (i = 0; i < n_index_data; i++) {
+ grn_mrb_data *data;
+ struct RClass *klass;
+ mrb_value args[2];
+
+ data = &(ctx->impl->mrb);
+ klass = mrb_class_get_under(mrb, data->module, "IndexInfo");
+ args[0] = grn_mrb_value_from_grn_obj(mrb, index_data[i].index);
+ args[1] = mrb_fixnum_value(index_data[i].section);
+ mrb_ary_push(mrb, mrb_indexes, mrb_obj_new(mrb, klass, 2, args));
+ }
+
+ if (index_data != &index_datum) {
+ GRN_FREE(index_data);
+ }
+
+ return mrb_indexes;
+}
+
+static mrb_value
+indexable_index_ids(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+ grn_hook_entry entry;
+ int i;
+ int n_indexes;
+ mrb_value mrb_index_ids;
+ grn_obj hook_data;
+
+ object = DATA_PTR(self);
+
+ if (grn_obj_is_key_accessor(ctx, object)) {
+ object = grn_ctx_at(ctx, object->header.domain);
+ }
+ if (grn_obj_is_table(ctx, object)) {
+ entry = GRN_HOOK_INSERT;
+ } else if (grn_obj_is_column(ctx, object)) {
+ entry = GRN_HOOK_SET;
+ } else {
+ return mrb_ary_new(mrb);
+ }
+ n_indexes = grn_obj_get_nhooks(ctx, object, entry);
+
+ mrb_index_ids = mrb_ary_new_capa(mrb, n_indexes);
+
+ GRN_TEXT_INIT(&hook_data, 0);
+ for (i = 0; i < n_indexes; i++) {
+ GRN_BULK_REWIND(&hook_data);
+ grn_obj_get_hook(ctx, object, entry, i, &hook_data);
+ if (GRN_BULK_VSIZE(&hook_data) ==
+ sizeof(grn_obj_default_set_value_hook_data)) {
+ grn_obj_default_set_value_hook_data *data;
+
+ data = (grn_obj_default_set_value_hook_data *)GRN_TEXT_VALUE(&hook_data);
+ mrb_ary_push(mrb, mrb_index_ids, mrb_fixnum_value(data->target));
+ }
+ }
+
+ return mrb_index_ids;
+}
+
+void
+grn_mrb_indexable_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module;
+
+ module = mrb_define_module_under(mrb, data->module, "Indexable");
+
+ mrb_define_method(mrb, module, "find_index",
+ indexable_find_index, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, module, "indexes",
+ indexable_indexes, MRB_ARGS_NONE());
+ mrb_define_method(mrb, module, "index_ids",
+ indexable_index_ids, MRB_ARGS_NONE());
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_indexable.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_indexable.h
new file mode 100644
index 00000000000..7634dd6f5ba
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_indexable.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_indexable_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.c
index 884ca761e83..3ba09d0295b 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -29,6 +29,23 @@
#include "mrb_logger.h"
static mrb_value
+logger_s_get_default_path(mrb_state *mrb, mrb_value self)
+{
+ return mrb_str_new_cstr(mrb, grn_default_logger_get_path());
+}
+
+static mrb_value
+logger_s_get_default_level(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_level_class;
+ mrb_value mrb_level;
+
+ mrb_level_class = mrb_const_get(mrb, self, mrb_intern_lit(mrb, "Level"));
+ mrb_level = mrb_fixnum_value(grn_default_logger_get_max_level());
+ return mrb_funcall(mrb, mrb_level_class, "find", 1, mrb_level);
+}
+
+static mrb_value
logger_need_log_p(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -52,7 +69,8 @@ logger_log(mrb_state *mrb, mrb_value self)
mrb_get_args(mrb, "izizs",
&level, &file, &line, &method, &message, &message_size);
- grn_logger_put(ctx, level, file, line, method, "%.*s", message_size, message);
+ grn_logger_put(ctx, level, file, line, method,
+ "%.*s", (int)message_size, message);
return self;
}
@@ -67,6 +85,11 @@ grn_mrb_logger_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "Logger", mrb->object_class);
+ mrb_define_singleton_method(mrb, (struct RObject *)klass, "default_path",
+ logger_s_get_default_path, MRB_ARGS_NONE());
+ mrb_define_singleton_method(mrb, (struct RObject *)klass, "default_level",
+ logger_s_get_default_level, MRB_ARGS_NONE());
+
mrb_define_method(mrb, klass, "need_log?", logger_need_log_p, MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "log", logger_log, MRB_ARGS_REQ(5));
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.h
index 358313b7ff9..c6a1ede9df2 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_LOGGER_H
-#define GRN_MRB_LOGGER_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_logger_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_LOGGER_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c
index 77eb4ef3025..ffa2c55aff7 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2015 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -29,8 +29,23 @@
#include "mrb_ctx.h"
#include "mrb_object.h"
#include "mrb_operator.h"
+#include "mrb_options.h"
#include "mrb_converter.h"
+static mrb_value
+object_remove_force(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ char *name;
+ mrb_int name_size;
+
+ mrb_get_args(mrb, "s", &name, &name_size);
+ grn_obj_remove_force(ctx, name, name_size);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_nil_value();
+}
+
mrb_value
grn_mrb_object_inspect(mrb_state *mrb, mrb_value self)
{
@@ -82,39 +97,27 @@ object_get_name(mrb_state *mrb, mrb_value self)
object = DATA_PTR(self);
name_length = grn_obj_name(ctx, object, name, GRN_TABLE_MAX_KEY_SIZE);
- return mrb_str_new(mrb, name, name_length);
+ if (name_length == 0) {
+ return mrb_nil_value();
+ } else {
+ return mrb_str_new(mrb, name, name_length);
+ }
}
static mrb_value
-object_find_index(mrb_state *mrb, mrb_value self)
+object_get_path(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
grn_obj *object;
- mrb_value mrb_operator;
- grn_operator operator;
- grn_index_datum index_datum;
- int n_index_data;
+ const char *path;
- mrb_get_args(mrb, "o", &mrb_operator);
object = DATA_PTR(self);
- operator = grn_mrb_value_to_operator(mrb, mrb_operator);
- n_index_data = grn_column_find_index_data(ctx,
- object,
- operator,
- &index_datum,
- 1);
- if (n_index_data == 0) {
- return mrb_nil_value();
+ path = grn_obj_path(ctx, object);
+
+ if (path) {
+ return mrb_str_new_cstr(mrb, path);
} else {
- grn_mrb_data *data;
- struct RClass *klass;
- mrb_value args[2];
-
- data = &(ctx->impl->mrb);
- klass = mrb_class_get_under(mrb, data->module, "IndexInfo");
- args[0] = grn_mrb_value_from_grn_obj(mrb, index_datum.index);
- args[1] = mrb_fixnum_value(index_datum.section);
- return mrb_obj_new(mrb, klass, 2, args);
+ return mrb_nil_value();
}
}
@@ -146,11 +149,16 @@ object_equal(mrb_state *mrb, mrb_value self)
object = DATA_PTR(self);
other_object = DATA_PTR(mrb_other);
- if (object == other_object) {
- return mrb_true_value();
- } else {
- return mrb_false_value();
- }
+ return mrb_bool_value(object == other_object);
+}
+
+static mrb_value
+object_hash(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *object;
+
+ object = DATA_PTR(self);
+ return mrb_fixnum_value((mrb_int)((uint64_t)object));
}
static mrb_value
@@ -174,10 +182,23 @@ static mrb_value
object_remove(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_options = mrb_nil_value();
+ grn_bool dependent = GRN_FALSE;
grn_obj *object;
+ mrb_get_args(mrb, "|H", &mrb_options);
+ if (!mrb_nil_p(mrb_options)) {
+ mrb_value mrb_dependent;
+ mrb_dependent = grn_mrb_options_get_lit(mrb, mrb_options, "dependent");
+ dependent = mrb_test(mrb_dependent);
+ }
+
object = DATA_PTR(self);
- grn_obj_remove(ctx, object);
+ if (dependent) {
+ grn_obj_remove_dependent(ctx, object);
+ } else {
+ grn_obj_remove(ctx, object);
+ }
grn_mrb_ctx_check(mrb);
DATA_PTR(self) = NULL;
@@ -186,6 +207,15 @@ object_remove(mrb_state *mrb, mrb_value self)
}
static mrb_value
+object_is_closed(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *object;
+
+ object = DATA_PTR(self);
+ return mrb_bool_value(object == NULL);
+}
+
+static mrb_value
object_get_domain_id(mrb_state *mrb, mrb_value self)
{
grn_obj *object;
@@ -240,6 +270,29 @@ object_is_persistent(mrb_state *mrb, mrb_value self)
return mrb_bool_value((flags & GRN_OBJ_PERSISTENT) == GRN_OBJ_PERSISTENT);
}
+static mrb_value
+object_is_true(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+
+ object = DATA_PTR(self);
+ return mrb_bool_value(grn_obj_is_true(ctx, object));
+}
+
+static mrb_value
+object_check_corrupt(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+ grn_bool is_corrupt;
+
+ object = DATA_PTR(self);
+ is_corrupt = grn_obj_is_corrupt(ctx, object);
+ grn_mrb_ctx_check(mrb);
+ return mrb_bool_value(is_corrupt);
+}
+
void
grn_mrb_object_init(grn_ctx *ctx)
{
@@ -252,18 +305,26 @@ grn_mrb_object_init(grn_ctx *ctx)
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
data->object_class = klass;
+ mrb_define_class_method(mrb,
+ klass,
+ "remove_force",
+ object_remove_force,
+ MRB_ARGS_REQ(1));
+
mrb_define_method(mrb, klass, "inspect",
grn_mrb_object_inspect, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "id", object_get_id, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "name", object_get_name, MRB_ARGS_NONE());
- mrb_define_method(mrb, klass, "find_index",
- object_find_index, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "path", object_get_path, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "grn_inspect",
object_grn_inspect, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "==", object_equal, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "eql?", object_equal, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "hash", object_hash, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "close", object_close, MRB_ARGS_NONE());
- mrb_define_method(mrb, klass, "remove", object_remove, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "remove", object_remove, MRB_ARGS_OPT(1));
+ mrb_define_method(mrb, klass, "closed?", object_is_closed, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "domain_id", object_get_domain_id,
MRB_ARGS_NONE());
@@ -275,6 +336,11 @@ grn_mrb_object_init(grn_ctx *ctx)
mrb_define_method(mrb, klass, "persistent?", object_is_persistent,
MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "true?", object_is_true, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "check_corrupt", object_check_corrupt,
+ MRB_ARGS_NONE());
+
grn_mrb_load(ctx, "index_info.rb");
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h
index 82468bd0156..0eebe54771f 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013-2014 Brazil
+ Copyright(C) 2013-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_OBJECT_H
-#define GRN_MRB_OBJECT_H
+#pragma once
#include "../grn_ctx.h"
@@ -33,4 +32,3 @@ mrb_value grn_mrb_object_inspect(mrb_state *mrb, mrb_value self);
}
#endif
-#endif /* GRN_MRB_OBJECT_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c
index c8accada692..21d5b310f28 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c
@@ -67,6 +67,7 @@ grn_mrb_object_flags_init(grn_ctx *ctx)
MRB_DEFINE_FLAG(COMPRESS_NONE);
MRB_DEFINE_FLAG(COMPRESS_ZLIB);
MRB_DEFINE_FLAG(COMPRESS_LZ4);
+ MRB_DEFINE_FLAG(COMPRESS_ZSTD);
MRB_DEFINE_FLAG(WITH_SECTION);
MRB_DEFINE_FLAG(WITH_WEIGHT);
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.h
index 60c82227078..59e5680ea2d 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_OBJECT_FLAGS_H
-#define GRN_MRB_OBJECT_FLAGS_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_object_flags_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_OBJECT_FLAGS_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c
index 2e0cb481722..ed16a023034 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c
@@ -148,6 +148,7 @@ grn_mrb_operator_init(grn_ctx *ctx)
DEFINE_OPERATOR(JSON_PUT);
DEFINE_OPERATOR(GET_MEMBER);
DEFINE_OPERATOR(REGEXP);
+ DEFINE_OPERATOR(FUZZY);
#undef DEFINE_OPERATOR
}
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h
index b76c4983446..adbb3e24b56 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014-2015 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_OPERATOR_H
-#define GRN_MRB_OPERATOR_H
+#pragma once
#include "../grn_ctx.h"
@@ -33,4 +32,3 @@ grn_operator grn_mrb_value_to_operator(mrb_state *mrb, mrb_value mrb_op);
}
#endif
-#endif /* GRN_MRB_OPERATOR_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h
index 1aa547d3be9..1523f05e2d3 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_OPTIONS_H
-#define GRN_MRB_OPTIONS_H
+#pragma once
#include "../grn_ctx.h"
@@ -37,4 +36,3 @@ mrb_value grn_mrb_options_get_static(mrb_state *mrb,
}
#endif
-#endif /* GRN_MRB_OPTIONS_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.h
index f281b25969b..9a34bc2ae53 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_PATRICIA_TRIE_H
-#define GRN_MRB_PATRICIA_TRIE_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_patricia_trie_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_PATRICIA_TRIE_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_pointer.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_pointer.c
new file mode 100644
index 00000000000..7440dc0b140
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_pointer.c
@@ -0,0 +1,77 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+#include <string.h>
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "mrb_pointer.h"
+#include "mrb_object.h"
+#include "mrb_converter.h"
+
+static struct mrb_data_type mrb_grn_pointer_type = {
+ "Groonga::Pointer",
+ NULL
+};
+
+static mrb_value
+mrb_grn_pointer_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_pointer_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_pointer_ptr);
+ DATA_TYPE(self) = &mrb_grn_pointer_type;
+ DATA_PTR(self) = mrb_cptr(mrb_pointer_ptr);
+ return self;
+}
+
+static mrb_value
+mrb_grn_pointer_get_value(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *pointer;
+
+ pointer = DATA_PTR(self);
+ if (GRN_BULK_VSIZE(pointer) == 0) {
+ return mrb_nil_value();
+ }
+
+ return grn_mrb_value_from_grn_obj(mrb, GRN_PTR_VALUE(pointer));
+}
+
+void
+grn_mrb_pointer_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "Pointer", mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_pointer_initialize, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "value",
+ mrb_grn_pointer_get_value, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "inspect",
+ grn_mrb_object_inspect, MRB_ARGS_NONE());
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_pointer.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_pointer.h
new file mode 100644
index 00000000000..2ee7fba4bdc
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_pointer.h
@@ -0,0 +1,31 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_pointer_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.c
index 3dfe78488df..2b425d6a5ce 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,8 @@
#include "mrb_procedure.h"
+#include "mrb_operator.h"
+
static struct mrb_data_type mrb_grn_procedure_type = {
"Groonga::Procedure",
NULL
@@ -42,6 +44,24 @@ mrb_grn_procedure_initialize(mrb_state *mrb, mrb_value self)
}
static mrb_value
+mrb_grn_procedure_selector_p(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *proc = DATA_PTR(self);
+
+ return mrb_bool_value(grn_obj_is_selector_proc(ctx, proc));
+}
+
+static mrb_value
+mrb_grn_procedure_selector_only_p(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *proc = DATA_PTR(self);
+
+ return mrb_bool_value(grn_obj_is_selector_only_proc(ctx, proc));
+}
+
+static mrb_value
mrb_grn_procedure_scorer_p(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -50,6 +70,17 @@ mrb_grn_procedure_scorer_p(mrb_state *mrb, mrb_value self)
return mrb_bool_value(grn_obj_is_scorer_proc(ctx, proc));
}
+static mrb_value
+mrb_grn_procedure_get_selector_operator(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *proc = DATA_PTR(self);
+ grn_operator selector_op;
+
+ selector_op = grn_proc_get_selector_operator(ctx, proc);
+ return grn_mrb_value_from_operator(mrb, selector_op);
+}
+
void
grn_mrb_procedure_init(grn_ctx *ctx)
{
@@ -64,7 +95,14 @@ grn_mrb_procedure_init(grn_ctx *ctx)
mrb_define_method(mrb, klass, "initialize",
mrb_grn_procedure_initialize, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "selector?",
+ mrb_grn_procedure_selector_p, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "selector_only?",
+ mrb_grn_procedure_selector_only_p, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "scorer?",
mrb_grn_procedure_scorer_p, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "selector_operator",
+ mrb_grn_procedure_get_selector_operator, MRB_ARGS_NONE());
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.h
index 36bd10fdab9..32135335a72 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_PROCEDURE_H
-#define GRN_MRB_PROCEDURE_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_procedure_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_PROCEDURE_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_query_logger.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_query_logger.c
new file mode 100644
index 00000000000..b2f5e79ed45
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_query_logger.c
@@ -0,0 +1,76 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/variable.h>
+#include <mruby/string.h>
+
+#include "../grn_mrb.h"
+#include "mrb_query_logger.h"
+
+static mrb_value
+query_logger_need_log_p(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_int flag;
+
+ mrb_get_args(mrb, "i", &flag);
+
+ return mrb_bool_value(grn_query_logger_pass(ctx, flag));
+}
+
+static mrb_value
+query_logger_log_raw(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_int flag;
+ char *mark;
+ char *message;
+ mrb_int message_size;
+
+ mrb_get_args(mrb, "izs", &flag, &mark, &message, &message_size);
+ grn_query_logger_put(ctx, flag, mark,
+ "%.*s", (int)message_size, message);
+
+ return self;
+}
+
+void
+grn_mrb_query_logger_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "QueryLogger", mrb->object_class);
+
+ mrb_define_method(mrb, klass, "need_log?", query_logger_need_log_p,
+ MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "log_raw", query_logger_log_raw,
+ MRB_ARGS_REQ(3));
+
+ grn_mrb_load(ctx, "query_logger/flag.rb");
+ grn_mrb_load(ctx, "query_logger.rb");
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_query_logger.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_query_logger.h
new file mode 100644
index 00000000000..8293f399320
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_query_logger.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_query_logger_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_record.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_record.c
new file mode 100644
index 00000000000..84d061ad497
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_record.c
@@ -0,0 +1,162 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/variable.h>
+#include <mruby/data.h>
+
+#include "../grn_db.h"
+#include "mrb_record.h"
+#include "mrb_bulk.h"
+
+typedef struct {
+ grn_obj *table;
+ grn_id id;
+ grn_obj key;
+} grn_mrb_record;
+
+static void
+mrb_grn_record_free(mrb_state *mrb, void *data)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_mrb_record *record = data;
+
+ if (!record) {
+ return;
+ }
+
+ GRN_OBJ_FIN(ctx, &(record->key));
+ mrb_free(mrb, record);
+}
+
+static struct mrb_data_type mrb_grn_record_type = {
+ "Groonga::Record",
+ mrb_grn_record_free
+};
+
+static mrb_value
+mrb_grn_record_initialize(mrb_state *mrb, mrb_value self)
+{
+ grn_mrb_record *record;
+ mrb_value mrb_table;
+ mrb_value mrb_id;
+
+ mrb_get_args(mrb, "oo", &mrb_table, &mrb_id);
+
+ DATA_TYPE(self) = &mrb_grn_record_type;
+
+ record = mrb_malloc(mrb, sizeof(grn_mrb_record));
+ record->table = DATA_PTR(mrb_table);
+ if (mrb_nil_p(mrb_id)) {
+ record->id = GRN_ID_NIL;
+ } else {
+ record->id = mrb_fixnum(mrb_id);
+ }
+
+ switch (record->table->header.domain) {
+ case GRN_ID_NIL :
+ case GRN_DB_SHORT_TEXT :
+ GRN_SHORT_TEXT_INIT(&(record->key), 0);
+ break;
+ default :
+ GRN_VALUE_FIX_SIZE_INIT(&(record->key), 0, record->table->header.domain);
+ break;
+ }
+
+ DATA_PTR(self) = record;
+
+ mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@table"), mrb_table);
+ mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@id"), mrb_id);
+
+ return self;
+}
+
+static mrb_value
+mrb_grn_record_set_id(mrb_state *mrb, mrb_value self)
+{
+ grn_mrb_record *record;
+ mrb_value mrb_id;
+
+ record = DATA_PTR(self);
+ mrb_get_args(mrb, "o", &mrb_id);
+
+ if (mrb_nil_p(mrb_id)) {
+ record->id = GRN_ID_NIL;
+ } else {
+ record->id = mrb_fixnum(mrb_id);
+ }
+ mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@id"), mrb_id);
+
+ return mrb_id;
+}
+
+static mrb_value
+mrb_grn_record_key(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_mrb_record *record;
+ int key_size;
+
+ record = DATA_PTR(self);
+
+ if (record->id == GRN_ID_NIL) {
+ return mrb_nil_value();
+ }
+
+ if (record->table->header.type == GRN_TABLE_NO_KEY) {
+ return mrb_nil_value();
+ }
+
+ GRN_BULK_REWIND(&(record->key));
+ key_size = grn_table_get_key(ctx, record->table, record->id,
+ GRN_BULK_HEAD(&(record->key)),
+ GRN_BULK_VSIZE(&(record->key)));
+ if (key_size > GRN_BULK_VSIZE(&(record->key))) {
+ grn_bulk_space(ctx, &(record->key), key_size);
+ key_size = grn_table_get_key(ctx, record->table, record->id,
+ GRN_BULK_HEAD(&(record->key)),
+ GRN_BULK_VSIZE(&(record->key)));
+ }
+
+ return grn_mrb_value_from_bulk(mrb, &(record->key));
+}
+
+void
+grn_mrb_record_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "Record", data->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_record_initialize, MRB_ARGS_REQ(2));
+
+ mrb_define_method(mrb, klass, "id=",
+ mrb_grn_record_set_id, MRB_ARGS_REQ(1));
+
+ mrb_define_method(mrb, klass, "key",
+ mrb_grn_record_key, MRB_ARGS_NONE());
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_record.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_record.h
new file mode 100644
index 00000000000..ad6e01d910f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_record.h
@@ -0,0 +1,31 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_record_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c
index 2b9e00d8f04..baf110ad6f8 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014-2015 Brazil
+ Copyright(C) 2014-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -17,6 +17,7 @@
*/
#include "../grn_ctx_impl.h"
+#include <string.h>
#ifdef GRN_WITH_MRUBY
#include <mruby.h>
@@ -66,6 +67,27 @@ mrb_grn_table_array_reference(mrb_state *mrb, mrb_value self)
}
static mrb_value
+mrb_grn_table_is_id(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *table;
+ mrb_int mrb_record_id;
+ grn_id record_id;
+ grn_id real_record_id;
+
+ mrb_get_args(mrb, "i", &mrb_record_id);
+
+ table = DATA_PTR(self);
+ record_id = (grn_id)mrb_record_id;
+ real_record_id = grn_table_at(ctx, table, record_id);
+ if (real_record_id == record_id) {
+ return mrb_true_value();
+ } else {
+ return mrb_false_value();
+ }
+}
+
+static mrb_value
mrb_grn_table_find_column(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -85,6 +107,64 @@ mrb_grn_table_find_column(mrb_state *mrb, mrb_value self)
}
static mrb_value
+mrb_grn_table_get_column_ids(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *table;
+ grn_hash *columns;
+ int n_columns;
+ mrb_value mrb_column_ids;
+
+ table = DATA_PTR(self);
+ columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY | GRN_HASH_TINY);
+ if (!columns) {
+ grn_mrb_ctx_check(mrb);
+ return mrb_ary_new(mrb);
+ }
+
+ n_columns = grn_table_columns(ctx, table, "", 0, (grn_obj *)columns);
+ mrb_column_ids = mrb_ary_new_capa(mrb, n_columns);
+ {
+ grn_id *key;
+ GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, {
+ mrb_ary_push(mrb, mrb_column_ids, mrb_fixnum_value(*key));
+ });
+ }
+ grn_hash_close(ctx, columns);
+
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_column_ids;
+}
+
+static mrb_value
+mrb_grn_table_create_column(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *table;
+ mrb_value mrb_name;
+ mrb_int flags;
+ mrb_value mrb_type;
+ grn_obj *type;
+ grn_obj *column;
+
+ mrb_get_args(mrb, "oio", &mrb_name, &flags, &mrb_type);
+
+ table = DATA_PTR(self);
+ type = DATA_PTR(mrb_type);
+ column = grn_column_create(ctx, table,
+ RSTRING_PTR(mrb_name),
+ RSTRING_LEN(mrb_name),
+ NULL,
+ flags,
+ type);
+ grn_mrb_ctx_check(mrb);
+
+ return grn_mrb_value_from_grn_obj(mrb, column);
+}
+
+static mrb_value
mrb_grn_table_is_locked(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -152,7 +232,9 @@ mrb_grn_table_select(mrb_state *mrb, mrb_value self)
}
result = grn_table_select(ctx, table, expr, result, operator);
- grn_mrb_ctx_check(mrb);
+ if (ctx->rc != GRN_SUCCESS) {
+ grn_mrb_ctx_check(mrb);
+ }
return grn_mrb_value_from_grn_obj(mrb, result);
}
@@ -179,9 +261,9 @@ mrb_grn_table_sort_raw(mrb_state *mrb, mrb_value self)
n_keys = RARRAY_LEN(mrb_keys);
keys = GRN_MALLOCN(grn_table_sort_key, n_keys);
for (i = 0; i < n_keys; i++) {
- memcpy(&(keys[i]),
- DATA_PTR(RARRAY_PTR(mrb_keys)[i]),
- sizeof(grn_table_sort_key));
+ grn_memcpy(&(keys[i]),
+ DATA_PTR(RARRAY_PTR(mrb_keys)[i]),
+ sizeof(grn_table_sort_key));
}
result = DATA_PTR(mrb_result);
grn_table_sort(ctx, table, offset, limit, result, keys, n_keys);
@@ -211,9 +293,9 @@ mrb_grn_table_group_raw(mrb_state *mrb, mrb_value self)
n_keys = RARRAY_LEN(mrb_keys);
keys = GRN_MALLOCN(grn_table_sort_key, n_keys);
for (i = 0; i < n_keys; i++) {
- memcpy(&(keys[i]),
- DATA_PTR(RARRAY_PTR(mrb_keys)[i]),
- sizeof(grn_table_sort_key));
+ grn_memcpy(&(keys[i]),
+ DATA_PTR(RARRAY_PTR(mrb_keys)[i]),
+ sizeof(grn_table_sort_key));
}
result = DATA_PTR(mrb_result);
grn_table_group(ctx, table, keys, n_keys, result, 1);
@@ -293,6 +375,70 @@ mrb_grn_table_delete(mrb_state *mrb, mrb_value self)
return mrb_nil_value();
}
+static mrb_value
+mrb_grn_table_truncate(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *table;
+
+ table = DATA_PTR(self);
+ grn_table_truncate(ctx, table);
+ grn_mrb_ctx_check(mrb);
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_apply_expression(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_output_column;
+ mrb_value mrb_expression;
+ grn_obj *table;
+ grn_obj *output_column = NULL;
+ grn_obj *expression = NULL;
+
+ mrb_get_args(mrb, "oo", &mrb_output_column, &mrb_expression);
+
+ table = DATA_PTR(self);
+ output_column = GRN_MRB_DATA_PTR(mrb_output_column);
+ expression = GRN_MRB_DATA_PTR(mrb_expression);
+ grn_table_apply_expr(ctx, table, output_column, expression);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_apply_window_function_raw(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_output_column;
+ mrb_value mrb_window_definition;
+ mrb_value mrb_window_function_call;
+ grn_obj *table;
+ grn_obj *output_column = NULL;
+ grn_window_definition *window_definition = NULL;
+ grn_obj *window_function_call = NULL;
+
+ mrb_get_args(mrb, "ooo",
+ &mrb_output_column,
+ &mrb_window_definition,
+ &mrb_window_function_call);
+
+ table = DATA_PTR(self);
+ output_column = GRN_MRB_DATA_PTR(mrb_output_column);
+ window_definition = GRN_MRB_DATA_PTR(mrb_window_definition);
+ window_function_call = GRN_MRB_DATA_PTR(mrb_window_function_call);
+ grn_table_apply_window_function(ctx,
+ table,
+ output_column,
+ window_definition,
+ window_function_call);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_nil_value();
+}
+
void
grn_mrb_table_init(grn_ctx *ctx)
{
@@ -307,9 +453,16 @@ grn_mrb_table_init(grn_ctx *ctx)
mrb_define_method(mrb, klass, "[]",
mrb_grn_table_array_reference, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "id?",
+ mrb_grn_table_is_id, MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "find_column",
mrb_grn_table_find_column, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "column_ids",
+ mrb_grn_table_get_column_ids, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "create_column",
+ mrb_grn_table_create_column, MRB_ARGS_REQ(3));
mrb_define_method(mrb, klass, "locked?",
mrb_grn_table_is_locked, MRB_ARGS_NONE());
@@ -329,5 +482,12 @@ grn_mrb_table_init(grn_ctx *ctx)
mrb_define_method(mrb, klass, "delete",
mrb_grn_table_delete, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "truncate",
+ mrb_grn_table_truncate, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "apply_expression",
+ mrb_grn_table_apply_expression, MRB_ARGS_REQ(2));
+ mrb_define_method(mrb, klass, "apply_window_function_raw",
+ mrb_grn_table_apply_window_function_raw, MRB_ARGS_REQ(4));
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.h
index 000088fcf40..3af173aa314 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_TABLE_H
-#define GRN_MRB_TABLE_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_table_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_TABLE_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c
index 76d4429d24f..4a3ad93e53e 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c
@@ -24,6 +24,7 @@
#include <mruby/data.h>
#include <mruby/string.h>
#include <mruby/hash.h>
+#include <mruby/variable.h>
#include "mrb_ctx.h"
#include "mrb_bulk.h"
@@ -38,7 +39,7 @@ static struct mrb_data_type mrb_grn_table_cursor_type = {
};
static mrb_value
-mrb_grn_table_cursor_singleton_open_raw(mrb_state *mrb, mrb_value klass)
+mrb_grn_table_cursor_class_open_raw(mrb_state *mrb, mrb_value klass)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
mrb_value mrb_table;
@@ -93,7 +94,13 @@ mrb_grn_table_cursor_singleton_open_raw(mrb_state *mrb, mrb_value klass)
grn_mrb_value_to_raw_data_buffer_fin(mrb, &max_buffer);
grn_mrb_ctx_check(mrb);
- return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, table_cursor));
+ {
+ mrb_value mrb_table_cursor;
+ mrb_table_cursor = mrb_funcall(mrb, klass,
+ "new", 1, mrb_cptr_value(mrb, table_cursor));
+ mrb_iv_set(mrb, mrb_table_cursor, mrb_intern_lit(mrb, "@table"), mrb_table);
+ return mrb_table_cursor;
+ }
}
static mrb_value
@@ -149,6 +156,28 @@ mrb_grn_table_cursor_count(mrb_state *mrb, mrb_value self)
return mrb_fixnum_value(n_records);
}
+static mrb_value
+mrb_grn_table_cursor_get_key(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_table;
+ grn_obj *table;
+ grn_id domain;
+ void *key;
+ int key_size;
+
+ mrb_table = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@table"));
+ table = DATA_PTR(mrb_table);
+ if (table->header.type == GRN_DB) {
+ domain = GRN_DB_SHORT_TEXT;
+ } else {
+ domain = table->header.domain;
+ }
+ key_size = grn_table_cursor_get_key(ctx, DATA_PTR(self), &key);
+
+ return grn_mrb_value_from_raw_data(mrb, domain, key, key_size);
+}
+
void
grn_mrb_table_cursor_init(grn_ctx *ctx)
{
@@ -160,9 +189,9 @@ grn_mrb_table_cursor_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "TableCursor", mrb->object_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
- mrb_define_singleton_method(mrb, (struct RObject *)klass, "open_raw",
- mrb_grn_table_cursor_singleton_open_raw,
- MRB_ARGS_ARG(1, 1));
+ mrb_define_class_method(mrb, klass, "open_raw",
+ mrb_grn_table_cursor_class_open_raw,
+ MRB_ARGS_ARG(1, 1));
mrb_define_method(mrb, klass, "initialize",
mrb_grn_table_cursor_initialize, MRB_ARGS_REQ(1));
@@ -172,5 +201,8 @@ grn_mrb_table_cursor_init(grn_ctx *ctx)
mrb_grn_table_cursor_next, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "count",
mrb_grn_table_cursor_count, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "key",
+ mrb_grn_table_cursor_get_key, MRB_ARGS_NONE());
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.h
index f05ab0977a1..6d3e2c4bef0 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_TABLE_CURSOR_H
-#define GRN_MRB_TABLE_CURSOR_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_table_cursor_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_TABLE_CURSOR_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.h
index f336cde9325..058de5ee6a4 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_TABLE_CURSOR_FLAGS_H
-#define GRN_MRB_TABLE_CURSOR_FLAGS_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_table_cursor_flags_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_TABLE_CURSOR_FLAGS_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.h
index fda2a9be82f..1c80df39dce 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_TABLE_GROUP_FLAGS_H
-#define GRN_MRB_TABLE_GROUP_FLAGS_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_table_group_flags_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_TABLE_GROUP_FLAGS_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c
index 970ebd06220..02c73c759c1 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c
@@ -182,15 +182,15 @@ mrb_grn_table_group_result_set_operator(mrb_state *mrb, mrb_value self)
}
static mrb_value
-mrb_grn_table_group_result_set_max_n_subrecs(mrb_state *mrb, mrb_value self)
+mrb_grn_table_group_result_set_max_n_sub_records(mrb_state *mrb, mrb_value self)
{
grn_table_group_result *result;
- mrb_int max_n_subrecs;
+ mrb_int max_n_sub_records;
result = DATA_PTR(self);
- mrb_get_args(mrb, "i", &max_n_subrecs);
+ mrb_get_args(mrb, "i", &max_n_sub_records);
- result->max_n_subrecs = max_n_subrecs;
+ result->max_n_subrecs = max_n_sub_records;
return mrb_nil_value();
}
@@ -204,7 +204,11 @@ mrb_grn_table_group_result_set_calc_target(mrb_state *mrb, mrb_value self)
result = DATA_PTR(self);
mrb_get_args(mrb, "o", &mrb_calc_target);
- result->calc_target = DATA_PTR(mrb_calc_target);
+ if (mrb_nil_p(mrb_calc_target)) {
+ result->calc_target = NULL;
+ } else {
+ result->calc_target = DATA_PTR(mrb_calc_target);
+ }
return mrb_nil_value();
}
@@ -241,8 +245,8 @@ grn_mrb_table_group_result_init(grn_ctx *ctx)
mrb_grn_table_group_result_set_flags, MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "operator=",
mrb_grn_table_group_result_set_operator, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, klass, "max_n_subrecs=",
- mrb_grn_table_group_result_set_max_n_subrecs,
+ mrb_define_method(mrb, klass, "max_n_sub_records=",
+ mrb_grn_table_group_result_set_max_n_sub_records,
MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "calc_target=",
mrb_grn_table_group_result_set_calc_target, MRB_ARGS_REQ(1));
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h
index cc3c70ff3bb..87615ebdc77 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_TABLE_GROUP_RESULT_H
-#define GRN_MRB_TABLE_GROUP_RESULT_H
+#pragma once
#include "../grn_ctx.h"
@@ -30,5 +29,3 @@ void grn_mrb_table_group_result_init(grn_ctx *ctx);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_MRB_TABLE_GROUP_RESULT_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.h
index 0b5c40b9993..a8e35f49520 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_TABLE_SORT_FLAGS_H
-#define GRN_MRB_TABLE_SORT_FLAGS_H
+#pragma once
#include "../grn_ctx.h"
@@ -30,5 +29,3 @@ void grn_mrb_table_sort_flags_init(grn_ctx *ctx);
#ifdef __cplusplus
}
#endif
-
-#endif /* GRN_MRB_TABLE_SORT_FLAGS_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c
index 3313cceebb6..860dd2b476d 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c
@@ -40,7 +40,9 @@ mrb_grn_table_sort_key_free(mrb_state *mrb, void *data)
}
if (sort_key->key) {
- grn_obj_unlink(ctx, sort_key->key);
+ if (sort_key->key->header.type == GRN_ACCESSOR) {
+ grn_obj_unlink(ctx, sort_key->key);
+ }
}
mrb_free(mrb, sort_key);
}
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h
index 1d56bcd6313..9825ca80c6f 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_TABLE_SORT_KEY_H
-#define GRN_MRB_TABLE_SORT_KEY_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_table_sort_key_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_TABLE_SORT_KEY_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_thread.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_thread.c
new file mode 100644
index 00000000000..6085543e192
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_thread.c
@@ -0,0 +1,46 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+
+#include "mrb_thread.h"
+
+static mrb_value
+thread_limit(mrb_state *mrb, mrb_value self)
+{
+ uint32_t limit;
+ limit = grn_thread_get_limit();
+ return mrb_fixnum_value(limit);
+}
+
+void
+grn_mrb_thread_init(grn_ctx *ctx)
+{
+ mrb_state *mrb = ctx->impl->mrb.state;
+ struct RClass *module = ctx->impl->mrb.module;
+ struct RClass *thread_module;
+
+ thread_module = mrb_define_module_under(mrb, module, "Thread");
+
+ mrb_define_class_method(mrb, thread_module,
+ "limit", thread_limit, MRB_ARGS_NONE());
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_thread.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_thread.h
new file mode 100644
index 00000000000..946dd698e4c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_thread.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_thread_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_type.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_type.h
index f86167443a6..17b43944699 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_type.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_type.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_TYPE_H
-#define GRN_MRB_TYPE_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_type_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_TYPE_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.h
index c904e7023b1..16d5403a952 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_VARIABLE_SIZE_COLUMN_H
-#define GRN_MRB_VARIABLE_SIZE_COLUMN_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_variable_size_column_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_VARIABLE_SIZE_COLUMN_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_void.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_void.h
index 474d7804c73..3169334fe25 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_void.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_void.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_VOID_H
-#define GRN_MRB_VOID_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_void_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_VOID_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_window_definition.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_window_definition.c
new file mode 100644
index 00000000000..964a8421153
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_window_definition.c
@@ -0,0 +1,164 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/array.h>
+
+#include "mrb_ctx.h"
+#include "mrb_window_definition.h"
+
+static void
+mrb_grn_window_definition_free(mrb_state *mrb, void *data)
+{
+ grn_window_definition *definition = data;
+
+ if (!definition) {
+ return;
+ }
+
+ if (definition->sort_keys) {
+ mrb_free(mrb, definition->sort_keys);
+ }
+ if (definition->group_keys) {
+ mrb_free(mrb, definition->group_keys);
+ }
+ mrb_free(mrb, definition);
+}
+
+static struct mrb_data_type mrb_grn_window_definition_type = {
+ "Groonga::WindowDefinition",
+ mrb_grn_window_definition_free
+};
+
+static mrb_value
+mrb_grn_window_definition_initialize(mrb_state *mrb, mrb_value self)
+{
+ grn_window_definition *result;
+
+ DATA_TYPE(self) = &mrb_grn_window_definition_type;
+
+ result = mrb_calloc(mrb, 1, sizeof(grn_window_definition));
+ DATA_PTR(self) = result;
+
+ return self;
+}
+
+
+static mrb_value
+mrb_grn_window_definition_close(mrb_state *mrb, mrb_value self)
+{
+ grn_window_definition *definition;
+
+ definition = DATA_PTR(self);
+ if (definition) {
+ mrb_grn_window_definition_free(mrb, definition);
+ DATA_PTR(self) = NULL;
+ }
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_window_definition_set_sort_keys(mrb_state *mrb, mrb_value self)
+{
+ grn_window_definition *definition;
+ mrb_value mrb_keys;
+
+ definition = DATA_PTR(self);
+ mrb_get_args(mrb, "A!", &mrb_keys);
+
+ if (definition->sort_keys) {
+ mrb_free(mrb, definition->sort_keys);
+ }
+
+ if (mrb_nil_p(mrb_keys)) {
+ definition->sort_keys = NULL;
+ definition->n_sort_keys = 0;
+ } else {
+ mrb_int i, n;
+ n = RARRAY_LEN(mrb_keys);
+ definition->sort_keys = mrb_calloc(mrb, n, sizeof(grn_table_sort_key));
+ for (i = 0; i < n; i++) {
+ grn_table_sort_key *sort_key = DATA_PTR(RARRAY_PTR(mrb_keys)[i]);
+ definition->sort_keys[i] = *sort_key;
+ }
+ definition->n_sort_keys = n;
+ }
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_window_definition_set_group_keys(mrb_state *mrb, mrb_value self)
+{
+ grn_window_definition *definition;
+ mrb_value mrb_keys;
+
+ definition = DATA_PTR(self);
+ mrb_get_args(mrb, "A!", &mrb_keys);
+
+ if (definition->group_keys) {
+ mrb_free(mrb, definition->group_keys);
+ }
+
+ if (mrb_nil_p(mrb_keys)) {
+ definition->group_keys = NULL;
+ definition->n_group_keys = 0;
+ } else {
+ mrb_int i, n;
+ n = RARRAY_LEN(mrb_keys);
+ definition->group_keys = mrb_calloc(mrb, n, sizeof(grn_table_sort_key));
+ for (i = 0; i < n; i++) {
+ grn_table_sort_key *group_key = DATA_PTR(RARRAY_PTR(mrb_keys)[i]);
+ definition->group_keys[i] = *group_key;
+ }
+ definition->n_group_keys = n;
+ }
+
+ return mrb_nil_value();
+}
+
+void
+grn_mrb_window_definition_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "WindowDefinition",
+ mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_window_definition_initialize, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "close",
+ mrb_grn_window_definition_close, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "sort_keys=",
+ mrb_grn_window_definition_set_sort_keys, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "group_keys=",
+ mrb_grn_window_definition_set_group_keys, MRB_ARGS_REQ(1));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_window_definition.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_window_definition.h
new file mode 100644
index 00000000000..871be3432a5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_window_definition.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_window_definition_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c
index e35a066e560..20ebd6ab92b 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c
@@ -40,7 +40,11 @@ writer_write(mrb_state *mrb, mrb_value self)
switch (mrb_type(target)) {
case MRB_TT_FALSE :
- GRN_OUTPUT_BOOL(GRN_FALSE);
+ if (mrb_nil_p(target)) {
+ GRN_OUTPUT_NULL();
+ } else {
+ GRN_OUTPUT_BOOL(GRN_FALSE);
+ }
break;
case MRB_TT_TRUE :
GRN_OUTPUT_BOOL(GRN_TRUE);
@@ -51,12 +55,23 @@ writer_write(mrb_state *mrb, mrb_value self)
case MRB_TT_FLOAT :
GRN_OUTPUT_FLOAT(mrb_float(target));
break;
+ case MRB_TT_SYMBOL :
+ {
+ const char *name;
+ mrb_int name_length;
+
+ name = mrb_sym2name_len(mrb, mrb_symbol(target), &name_length);
+ GRN_OUTPUT_STR(name, name_length);
+ }
+ break;
case MRB_TT_STRING :
GRN_OUTPUT_STR(RSTRING_PTR(target), RSTRING_LEN(target));
break;
default :
mrb_raisef(mrb, E_ARGUMENT_ERROR,
- "must be true, false, number, float or string: %S", target);
+ "must be nil, true, false, number, float, symbol or string: "
+ "%S",
+ target);
break;
}
@@ -198,7 +213,7 @@ static mrb_value
writer_set_content_type(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
- grn_content_type content_type;
+ mrb_int content_type;
mrb_get_args(mrb, "i", &content_type);
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.h
index a6b4a6b3a75..a4de02615ea 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,8 +16,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef GRN_MRB_WRITER_H
-#define GRN_MRB_WRITER_H
+#pragma once
#include "../grn_ctx.h"
@@ -31,4 +30,3 @@ void grn_mrb_writer_init(grn_ctx *ctx);
}
#endif
-#endif /* GRN_MRB_WRITER_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am
index 9b6acf8bbda..835d881bb0a 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am
@@ -1,13 +1,14 @@
SUBDIRS = \
command_line \
context \
+ expression_tree \
initialize \
- logger
+ logger \
+ query_logger
include sources.am
EXTRA_DIST = \
- test/empty.rb \
$(RUBY_SCRIPT_FILES)
if WITH_MRUBY
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/accessor.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/accessor.rb
new file mode 100644
index 00000000000..3ae08fb6e6c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/accessor.rb
@@ -0,0 +1,5 @@
+module Groonga
+ class Accessor
+ include Indexable
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb
index c4e3e94bc4e..26dfe68cd01 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb
@@ -20,9 +20,38 @@ module Groonga
@writer ||= context.writer
end
+ def query_logger
+ @query_logger ||= context.query_logger
+ end
+
+ def cache_key(input)
+ nil
+ end
+
+ def cache_output(key, options={})
+ if key.nil?
+ yield
+ else
+ cache = Cache.current
+ cached_value = cache.fetch(key)
+ if cached_value
+ context.output = cached_value
+ query_logger.log(:cache, ":", "cache(#{cached_value.bytesize})")
+ else
+ yield
+ cache.update(key, context.output) if options[:update]
+ end
+ end
+ end
+
def run_internal(input)
begin
- run_body(input)
+ options = {
+ :update => (input["cache"] != "no"),
+ }
+ cache_output(cache_key(input), options) do
+ run_body(input)
+ end
rescue GroongaError => groonga_error
context.set_groonga_error(groonga_error)
nil
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_input.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_input.rb
new file mode 100644
index 00000000000..779edb47911
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_input.rb
@@ -0,0 +1,15 @@
+module Groonga
+ class CommandInput
+ include Enumerable
+
+ def each
+ args = arguments
+ arg = Record.new(args, nil)
+ args.each do |id|
+ arg.id = id
+ key = arg.key
+ yield(key, self[key])
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb
index 96a99c80223..edd16d588cd 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb
@@ -2,78 +2,67 @@ module Groonga
module CommandLine
class Grndb
def initialize(argv)
- @command, *@arguments = argv
+ @program_path, *@arguments = argv
@succeeded = true
- @executed = false
@database_path = nil
end
def run
- slop = create_slop
- rest = nil
+ command_line_parser = create_command_line_parser
+ options = nil
begin
- rest = slop.parse(@arguments)
- rescue Slop::Error
- $stderr.puts($!.message)
- return false
- end
-
- if slop.help?
- $stdout.puts(slop.help)
- return true
- end
-
- unless @executed
- if rest.empty?
- $stderr.puts("No command is specified.")
- else
- $stderr.puts("Unknown command: <#{rest.first}>")
- end
+ options = command_line_parser.parse(@arguments)
+ rescue Slop::Error => error
+ $stderr.puts(error.message)
+ $stderr.puts
+ $stderr.puts(command_line_parser.help_message)
return false
end
-
@succeeded
end
private
- def create_slop
- slop = Slop.new
- command_name = File.basename(@command)
- slop.banner = "Usage: #{command_name} COMMAND [OPTIONS] DB_PATH"
- slop_enable_help(slop)
-
- slop.command "check" do |command|
- command.description "Check database"
- slop_enable_help(command)
-
- command.run do |options, arguments|
- run_command(options, arguments) do |database, new_arguments|
- check(database, options, new_arguments)
+ def create_command_line_parser
+ program_name = File.basename(@program_path)
+ parser = CommandLineParser.new(program_name)
+
+ parser.add_command("check") do |command|
+ command.description = "Check database"
+
+ options = command.options
+ options.banner += " DB_PATH"
+ options.string("--target", "Check only the target object.")
+
+ command.add_action do |options|
+ open_database(command, options) do |database, rest_arguments|
+ check(database, options, rest_arguments)
end
end
end
- slop.command "recover" do |command|
- command.description "Recover database"
- slop_enable_help(command)
+ parser.add_command("recover") do |command|
+ command.description = "Recover database"
- command.run do |options, arguments|
- run_command(options, arguments) do |database, new_arguments|
- recover(database, options, new_arguments)
+ options = command.options
+ options.banner += " DB_PATH"
+ options.boolean("--force-truncate", "Force to truncate corrupted objects.")
+
+ command.add_action do |options|
+ open_database(command, options) do |database, rest_arguments|
+ recover(database, options, rest_arguments)
end
end
end
- slop
- end
-
- def slop_enable_help(slop)
- slop.on("-h", "--help", "Display this help message.", :tail => true)
+ parser
end
- def open_database(arguments)
+ def open_database(command, options)
+ arguments = options.arguments
if arguments.empty?
$stderr.puts("Database path is missing")
+ $stderr.puts
+ $stderr.puts(command.help_message)
@succeesed = false
return
end
@@ -96,51 +85,174 @@ module Groonga
end
end
- def run_command(options, arguments)
- @executed = true
-
- if options.help?
- $stdout.puts(options.help)
- return
- end
-
- open_database(arguments) do |database|
- yield(database)
+ def failed(*messages)
+ messages.each do |message|
+ $stderr.puts(message)
end
+ @succeeded = false
end
def recover(database, options, arguments)
+ recoverer = Recoverer.new
+ recoverer.database = database
+ recoverer.force_truncate = options[:force_truncate]
begin
- database.recover
+ recoverer.recover
rescue Error => error
- $stderr.puts("Failed to recover database: <#{@database_path}>")
- $stderr.puts(error.message)
- @succeeded = false
+ failed("Failed to recover database: <#{@database_path}>",
+ error.message)
end
end
def check(database, options, arguments)
- if database.locked?
+ checker = Checker.new
+ checker.program_path = @program_path
+ checker.database_path = @database_path
+ checker.database = database
+ checker.on_failure = lambda do |message|
+ failed(message)
+ end
+
+ checker.check_database
+
+ target_name = options[:target]
+ if target_name
+ checker.check_one(target_name)
+ else
+ checker.check_all
+ end
+ end
+
+ class Checker
+ attr_writer :program_path
+ attr_writer :database_path
+ attr_writer :database
+ attr_writer :on_failure
+
+ def initialize
+ @context = Context.instance
+ @checked = {}
+ end
+
+ def check_database
+ check_database_orphan_inspect
+ check_database_locked
+ check_database_corrupt
+ check_database_dirty
+ end
+
+ def check_one(target_name)
+ target = @context[target_name]
+ if target.nil?
+ exist_p = open_database_cursor do |cursor|
+ cursor.any? do
+ cursor.key == target_name
+ end
+ end
+ if exist_p
+ failed_to_open(target_name)
+ else
+ message = "[#{target_name}] Not exist."
+ failed(message)
+ end
+ return
+ end
+
+ check_object_recursive(target)
+ end
+
+ def check_all
+ open_database_cursor do |cursor|
+ cursor.each do |id|
+ next if ID.builtin?(id)
+ next if builtin_object_name?(cursor.key)
+ next if @context[id]
+ failed_to_open(cursor.key)
+ end
+ end
+
+ @database.each do |object|
+ check_object(object)
+ end
+ end
+
+ private
+ def check_database_orphan_inspect
+ open_database_cursor do |cursor|
+ cursor.each do |id|
+ if cursor.key == "inspect" and @context[id].nil?
+ message =
+ "Database has orphan 'inspect' object. " +
+ "Remove it by '#{@program_path} recover #{@database_path}'."
+ failed(message)
+ break
+ end
+ end
+ end
+ end
+
+ def check_database_locked
+ return unless @database.locked?
+
message =
"Database is locked. " +
"It may be broken. " +
"Re-create the database."
- $stdout.puts(message)
- @succeeded = false
+ failed(message)
end
- database.each do |object|
+ def check_database_corrupt
+ return unless @database.corrupt?
+
+ message =
+ "Database is corrupt. " +
+ "Re-create the database."
+ failed(message)
+ end
+
+ def check_database_dirty
+ return unless @database.dirty?
+
+ last_modified = @database.last_modified
+ if File.stat(@database.path).mtime > last_modified
+ return
+ end
+
+ open_database_cursor do |cursor|
+ cursor.each do |id|
+ next if ID.builtin?(id)
+ path = "%s.%07x" % [@database.path, id]
+ next unless File.exist?(path)
+ return if File.stat(path).mtime > last_modified
+ end
+ end
+
+ message =
+ "Database wasn't closed successfully. " +
+ "It may be broken. " +
+ "Re-create the database."
+ failed(message)
+ end
+
+ def check_object(object)
+ return if @checked.key?(object.id)
+ @checked[object.id] = true
+
+ check_object_locked(object)
+ check_object_corrupt(object)
+ end
+
+ def check_object_locked(object)
case object
when IndexColumn
- next unless object.locked?
+ return unless object.locked?
message =
"[#{object.name}] Index column is locked. " +
"It may be broken. " +
- "Re-create index by '#{@command} recover #{@database_path}'."
- $stdout.puts(message)
- @succeeded = false
+ "Re-create index by '#{@program_path} recover #{@database_path}'."
+ failed(message)
when Column
- next unless object.locked?
+ return unless object.locked?
name = object.name
message =
"[#{name}] Data column is locked. " +
@@ -148,10 +260,9 @@ module Groonga
"(1) Truncate the column (truncate #{name}) or " +
"clear lock of the column (lock_clear #{name}) " +
"and (2) load data again."
- $stdout.puts(message)
- @succeeded = false
+ failed(message)
when Table
- next unless object.locked?
+ return unless object.locked?
name = object.name
message =
"[#{name}] Table is locked. " +
@@ -159,8 +270,180 @@ module Groonga
"(1) Truncate the table (truncate #{name}) or " +
"clear lock of the table (lock_clear #{name}) " +
"and (2) load data again."
- $stdout.puts(message)
- @succeeded = false
+ failed(message)
+ end
+ end
+
+ def check_object_corrupt(object)
+ case object
+ when IndexColumn
+ return unless object.corrupt?
+ message =
+ "[#{object.name}] Index column is corrupt. " +
+ "Re-create index by '#{@program_path} recover #{@database_path}'."
+ failed(message)
+ when Column
+ return unless object.corrupt?
+ name = object.name
+ message =
+ "[#{name}] Data column is corrupt. " +
+ "(1) Truncate the column (truncate #{name} or " +
+ "'#{@program_path} recover --force-truncate #{@database_path}') " +
+ "and (2) load data again."
+ failed(message)
+ when Table
+ return unless object.corrupt?
+ name = object.name
+ message =
+ "[#{name}] Table is corrupt. " +
+ "(1) Truncate the table (truncate #{name} or " +
+ "'#{@program_path} recover --force-truncate #{@database_path}') " +
+ "and (2) load data again."
+ failed(message)
+ end
+ end
+
+ def check_object_recursive(target)
+ return if @checked.key?(target.id)
+
+ check_object(target)
+ case target
+ when Table
+ unless target.is_a?(Groonga::Array)
+ domain_id = target.domain_id
+ domain = @context[domain_id]
+ if domain.nil?
+ record = Record.new(@database, domain_id)
+ failed_to_open(record.key)
+ elsif domain.is_a?(Table)
+ check_object_recursive(domain)
+ end
+ end
+
+ target.column_ids.each do |column_id|
+ column = @context[column_id]
+ if column.nil?
+ record = Record.new(@database, column_id)
+ failed_to_open(record.key)
+ else
+ check_object_recursive(column)
+ end
+ end
+ when FixedSizeColumn, VariableSizeColumn
+ range_id = target.range_id
+ range = @context[range_id]
+ if range.nil?
+ record = Record.new(@database, range_id)
+ failed_to_open(record.key)
+ elsif range.is_a?(Table)
+ check_object_recursive(range)
+ end
+
+ lexicon_ids = []
+ target.indexes.each do |index_info|
+ index = index_info.index
+ lexicon_ids << index.domain_id
+ check_object(index)
+ end
+ lexicon_ids.uniq.each do |lexicon_id|
+ lexicon = @context[lexicon_id]
+ if lexicon.nil?
+ record = Record.new(@database, lexicon_id)
+ failed_to_open(record.key)
+ else
+ check_object(lexicon)
+ end
+ end
+ when IndexColumn
+ range_id = target.range_id
+ range = @context[range_id]
+ if range.nil?
+ record = Record.new(@database, range_id)
+ failed_to_open(record.key)
+ return
+ end
+ check_object(range)
+
+ target.source_ids.each do |source_id|
+ source = @context[source_id]
+ if source.nil?
+ record = Record.new(database, source_id)
+ failed_to_open(record.key)
+ elsif source.is_a?(Column)
+ check_object_recursive(source)
+ end
+ end
+ end
+ end
+
+ def open_database_cursor(&block)
+ flags =
+ TableCursorFlags::ASCENDING |
+ TableCursorFlags::BY_ID
+ TableCursor.open(@database, :flags => flags, &block)
+ end
+
+ def builtin_object_name?(name)
+ case name
+ when "inspect"
+ # Just for compatibility. It's needed for users who used
+ # Groonga master at between 2016-02-03 and 2016-02-26.
+ true
+ else
+ false
+ end
+ end
+
+ def failed(message)
+ @on_failure.call(message)
+ end
+
+ def failed_to_open(name)
+ message =
+ "[#{name}] Can't open object. " +
+ "It's broken. " +
+ "Re-create the object or the database."
+ failed(message)
+ end
+ end
+
+ class Recoverer
+ attr_writer :database
+ attr_writer :force_truncate
+
+ def initialize
+ @context = Context.instance
+ end
+
+ def recover
+ if @force_truncate
+ truncate_corrupt_objects
+ end
+ @database.recover
+ end
+
+ def truncate_corrupt_objects
+ @database.each do |object|
+ next unless object.corrupt?
+ logger = @context.logger
+ object_path = object.path
+ object_dirname = File.dirname(object_path)
+ object_basename = File.basename(object_path)
+ object.truncate
+ Dir.foreach(object_dirname) do |path|
+ if path.start_with?("#{object_basename}.")
+ begin
+ File.unlink("#{object_dirname}/#{path}")
+ message = "Corrupted <#{object_path}> related file is removed: <#{path}>"
+ $stdout.puts(message)
+ logger.log(Logger::Level::INFO.to_i, __FILE__, __LINE__, "truncate_corrupt_objects", message)
+ rescue Error => error
+ message = "Failed to remove file which is related to corrupted <#{object_path}>: <#{path}>"
+ $stderr.puts(message)
+ logger.log_error(message)
+ end
+ end
+ end
end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line_parser.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line_parser.rb
new file mode 100644
index 00000000000..7dad55a75cb
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line_parser.rb
@@ -0,0 +1,168 @@
+module Slop
+ class MissingCommand < Error
+ end
+
+ class UnknownCommand < Error
+ attr_reader :name
+
+ def initialize(msg, name)
+ super(msg)
+ @name = name
+ end
+ end
+end
+
+module Groonga
+ class CommandLineParser
+ def initialize(program_name=nil)
+ $0 ||= nil
+ @program_name = program_name || $0
+ @commands = []
+ @action_runner = ActionRunner.new
+ @options = Slop::Options.new
+ setup_options
+ end
+
+ def options
+ yield(@options) if block_given?
+ @options
+ end
+
+ def add_command(name)
+ command = Command.new(@program_name, name)
+ setup_common_options(command.options)
+ yield(command)
+ @commands << command
+ end
+
+ def add_action(&action)
+ @action_runner.add(&action)
+ end
+
+ def parse(command_line)
+ if @commands.empty?
+ result = @options.parse(command_line)
+ apply_actions(result)
+ return result
+ end
+
+ if command_line.empty?
+ message = "Command is missing"
+ raise Slop::MissingCommand.new(message)
+ end
+
+ first_argument = command_line.first
+ if first_argument.start_with?("-")
+ result = @options.parse(command_line)
+ apply_actions(result)
+ return result
+ end
+
+ command_name = first_argument
+ command = find_command(command_name)
+ if command.nil?
+ message = "Unknown command: <#{command_name}>"
+ raise Slop::UnknownCommand.new(message, command_name)
+ end
+
+ command.parse(command_line[1..-1])
+ end
+
+ def help_message
+ message = @options.to_s
+ @commands.each do |command|
+ message << "\n"
+ indent = " " * 4
+ message << "#{command.description}:\n" if command.description
+ message << "#{indent}#{command.options.banner}\n"
+ end
+ message
+ end
+
+ private
+ def setup_options
+ @options.banner = "Usage: #{@program_name} [OPTIONS]"
+ setup_common_options(@options)
+ @options.on("-h", "--help", "Display this help message.",
+ :tail => true) do
+ $stdout.puts(help_message)
+ end
+ end
+
+ def setup_common_options(options)
+ options.string("--log-path",
+ "Change log path (#{Logger.default_path})",
+ default: Logger.default_path)
+ default_log_level = Logger.default_level
+ options.string("--log-level",
+ "Change log level (#{default_log_level.name})",
+ default: default_log_level)
+ end
+
+ def find_command(name)
+ @commands.find do |command|
+ command.name == name
+ end
+ end
+
+ def apply_actions(result)
+ @action_runner.run(result) unless result.help?
+ end
+
+ class ActionRunner
+ def initialize
+ @actions = []
+ end
+
+ def add(&action)
+ @actions << action
+ end
+
+ def run(*args)
+ @actions.each do |action|
+ action.call(*args)
+ end
+ end
+ end
+
+ class Command
+ attr_reader :name
+ attr_reader :options
+ attr_accessor :description
+ def initialize(program_name, name)
+ @program_name = program_name
+ @name = name
+ @options = Slop::Options.new
+ setup_options
+ @description = nil
+ @action_runner = ActionRunner.new
+ end
+
+ def add_action(&action)
+ @action_runner.add(&action)
+ end
+
+ def parse(command_line)
+ result = @options.parse(command_line)
+ @action_runner.run(result) unless result.help?
+ result
+ end
+
+ def help_message
+ message = ""
+ message << "Description: #{@description}\n" if @description
+ message << @options.to_s
+ message
+ end
+
+ private
+ def setup_options
+ @options.banner = "Usage: #{@program_name} #{@name} [OPTIONS]"
+ @options.on("-h", "--help", "Display this help message.",
+ :tail => true) do
+ $stdout.puts(help_message)
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb
index e65d6653110..b6f59dc3399 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb
@@ -16,6 +16,10 @@ module Groonga
@logger ||= Logger.new
end
+ def query_logger
+ @query_logger ||= QueryLogger.new
+ end
+
def writer
@writer ||= Writer.new
end
@@ -34,6 +38,35 @@ module Groonga
logger.log_error(error)
end
+ def with_command_version(version)
+ old_version = command_version
+ begin
+ self.command_version = version
+ yield
+ ensure
+ self.command_version = old_version
+ end
+ end
+
+ def open_temporary(id)
+ if Thread.limit == 1
+ need_close = !opened?(id)
+ else
+ need_close = false
+ end
+ object = self[id]
+ begin
+ yield(object)
+ ensure
+ if need_close and object and !object.closed?
+ case object
+ when Table, Column
+ object.close
+ end
+ end
+ end
+ end
+
private
def set_error_raw(rc, error_level, message, backtrace)
self.rc = rc.to_i
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb
index f06b32d78b6..45187c22ade 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb
@@ -1,15 +1,21 @@
module Groonga
class Context
class RC
+ @@codes = {}
@@names = {}
class << self
- def find(name)
- @@names[name] || UNKNOWN_ERROR
+ def find(name_or_code)
+ if name_or_code.is_a?(Symbol)
+ @@names[name_or_code] || UNKNOWN_ERROR
+ else
+ @@codes[name_or_code] || UNKNOWN_ERROR
+ end
end
def register(name, code, error_class)
- rc = new(name, code)
+ rc = new(name, code, error_class)
+ @@codes[code] = rc
@@names[name] = rc
error_class.rc = rc if error_class
rc
@@ -17,9 +23,11 @@ module Groonga
end
attr_reader :name
- def initialize(name, code)
+ attr_reader :error_class
+ def initialize(name, code, error_class)
@name = name
@code = code
+ @error_class = error_class
end
def to_i
@@ -182,6 +190,14 @@ module Groonga
register(:command_error, -74, CommandError)
PLUGIN_ERROR =
register(:plugin_error, -75, PluginError)
+ SCORER_ERROR =
+ register(:scorer_error, -76, ScorerError)
+ CANCEL =
+ register(:cancel, -77, Cancel)
+ WINDOW_FUNCTION_ERROR =
+ register(:window_function_error, -78, WindowFunctionError)
+ ZSTD_ERROR =
+ register(:zstd_error, -79, ZstdError)
GroongaError.rc = UNKNOWN_ERROR
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb
index 54d9dc1a631..e0c6b4a0193 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb
@@ -1,28 +1,25 @@
module Groonga
class Database
- def each
- context = Context.instance
- flags =
- TableCursorFlags::ASCENDING |
- TableCursorFlags::BY_ID
- TableCursor.open(self, :flags => flags) do |cursor|
- cursor.each do |id|
- object = context[id]
- yield(object) if object
- end
- end
- end
+ def each_raw(options=nil)
+ return to_enum(__method__, options) unless block_given?
- def each_table(options={})
- context = Context.instance
- min = options[:prefix]
+ if options
+ min = options[:prefix]
+ order = options[:order]
+ order_by = options[:order_by]
+ else
+ min = nil
+ order = :ascending
+ order_by = :id
+ end
flags = 0
- if options[:order] == :descending
+
+ if order == :descending
flags |= TableCursorFlags::DESCENDING
else
flags |= TableCursorFlags::ASCENDING
end
- if options[:order_by] == :id
+ if order_by == :id
flags |= TableCursorFlags::BY_ID
else
flags |= TableCursorFlags::BY_KEY
@@ -30,10 +27,39 @@ module Groonga
flags |= TableCursorFlags::PREFIX if min
TableCursor.open(self, :min => min, :flags => flags) do |cursor|
cursor.each do |id|
- object = context[id]
- yield(object) if object.is_a?(Table)
+ yield(id, cursor)
end
end
end
+
+ def each(options=nil)
+ return to_enum(__method__, options) unless block_given?
+
+ context = Context.instance
+ each_raw(options) do |id, cursor|
+ object = context[id]
+ yield(object) if object
+ end
+ end
+
+ def each_name(options=nil)
+ return to_enum(__method__, options) unless block_given?
+
+ each_raw(options) do |id, cursor|
+ name = cursor.key
+ yield(name)
+ end
+ end
+
+ def each_table(options={})
+ return to_enum(__method__, options) unless block_given?
+
+ context = Context.instance
+ each_name(options) do |name|
+ next if name.include?(".")
+ object = context[name]
+ yield(object) if object.is_a?(Table)
+ end
+ end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/eval_context.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/eval_context.rb
index 546c130d9b5..05c7ee8dd29 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/eval_context.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/eval_context.rb
@@ -1,5 +1,10 @@
module Groonga
class EvalContext
+ def eval(script)
+ proc = compile(script)
+ instance_eval(&proc)
+ end
+
def method_missing(id, *args, &block)
return super unless args.empty?
return super if block_given?
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb
index 7b1199b7795..27dadcb7aca 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb
@@ -1,16 +1,48 @@
+require "expression_rewriter"
+require "expression_rewriters"
+
+require "expression_tree_builder"
+
require "scan_info"
require "scan_info_builder"
+require "scan_info_data_size_estimator"
require "expression_size_estimator"
module Groonga
class Expression
- def build_scan_info(op, size)
+ def rewrite
+ rewritten = nil
+ begin
+ return nil unless ExpressionRewriters.enabled?
+ source = self
+ ExpressionRewriters.classes.each do |rewriter_class|
+ rewriter = rewriter_class.new(source)
+ new_rewritten = rewriter.rewrite
+ if new_rewritten
+ rewritten.close if rewritten
+ rewritten = new_rewritten
+ source = rewritten
+ end
+ end
+ rescue GroongaError => groonga_error
+ context.set_groonga_error(groonga_error)
+ rewritten.close if rewritten
+ rewritten = nil
+ rescue => error
+ context.record_error(:invalid_argument, error)
+ rewritten.close if rewritten
+ rewritten = nil
+ end
+ rewritten
+ end
+
+ def build_scan_info(op, record_exist)
begin
- builder = ScanInfoBuilder.new(self, op, size)
+ builder = ScanInfoBuilder.new(self, op, record_exist)
builder.build
rescue => error
- Context.instance.record_error(:invalid_argument, error)
+ context.record_error(:invalid_argument, error)
nil
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_rewriter.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_rewriter.rb
new file mode 100644
index 00000000000..8f56ca7cb6e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_rewriter.rb
@@ -0,0 +1,22 @@
+module Groonga
+ class ExpressionRewriter
+ class << self
+ def register(name)
+ ExpressionRewriters.register(name, self)
+ end
+ end
+
+ def initialize(expression)
+ @expression = expression
+ end
+
+ def rewrite
+ nil
+ end
+
+ private
+ def context
+ @context ||= Context.instance
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_rewriters.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_rewriters.rb
new file mode 100644
index 00000000000..ae773541eed
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_rewriters.rb
@@ -0,0 +1,41 @@
+module Groonga
+ module ExpressionRewriters
+ @rewriters = {}
+
+ class << self
+ def register(name, rewriter_class)
+ @rewriters[name] = rewriter_class
+ end
+
+ def enabled?
+ rewriters_table_name =
+ Config["expression_rewriter.table"] || "expression_rewriters"
+ rewriters_table = Context.instance[rewriters_table_name]
+ return false if rewriters_table.nil?
+ return false if rewriters_table.empty?
+
+ true
+ end
+
+ def classes
+ rewriters_table_name =
+ Config["expression_rewriter.table"] || "expression_rewriters"
+ rewriters_table = Context.instance[rewriters_table_name]
+ return [] if rewriters_table.nil?
+
+ rewriters_table.collect do |id|
+ record = Record.new(rewriters_table, id)
+ name = record.key
+ rewriter = @rewriters[name]
+ if rewriter.nil?
+ plugin_name = record.plugin_name.value
+ require plugin_name
+ rewriter = @rewriters[name]
+ raise "unknown rewriter: <#{name}>:<#{plugin_name}>" if rewriter.nil?
+ end
+ rewriter
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb
index 28b80fc3de3..597b56f9d8f 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb
@@ -7,154 +7,48 @@ module Groonga
end
def estimate
- builder = ScanInfoBuilder.new(@expression, Operator::OR, 0)
+ builder = ScanInfoBuilder.new(@expression, Operator::OR, false)
data_list = builder.build
return @table_size if data_list.nil?
- or_data_list = group_data_list(data_list)
- or_sizes = or_data_list.collect do |and_data_list|
- and_sizes = and_data_list.collect do |data|
- size = estimate_data(data)
- if data.logical_op == Operator::AND_NOT
- size = @table_size - size
- size = 0 if size < 0
- end
- size
- end
- and_sizes.min
- end
- or_sizes.max
- end
-
- private
- def group_data_list(data_list)
- or_data_list = [[]]
+ current_size = 0
+ sizes = []
data_list.each do |data|
- next if data.op == Operator::NOP
-
- and_data_list = or_data_list.last
- if and_data_list.empty?
- and_data_list << data
- else
+ if (data.flags & ScanInfo::Flags::POP) != 0
+ size = sizes.pop
case data.logical_op
when Operator::AND, Operator::AND_NOT
- and_data_list << data
+ current_size = size if size < current_size
+ when Operator::OR
+ current_size = size if size > current_size
else
- and_data_list = [data]
- or_data_list << and_data_list
+ message = "invalid logical operator: <#{data.logical_op.inspect}>"
+ raise InvalidArgument, message
+ end
+ else
+ if (data.flags & ScanInfo::Flags::PUSH) != 0
+ sizes.push(current_size)
+ current_size = 0
end
- end
- end
- or_data_list
- end
-
- def estimate_data(data)
- search_index = data.search_indexes.first
- return @table_size if search_index.nil?
-
- index_column = resolve_index_column(search_index.index_column,
- data.op)
- return @table_size if index_column.nil?
- size = nil
- case data.op
- when Operator::MATCH
- size = estimate_match(data, index_column)
- when Operator::REGEXP
- size = estimate_regexp(data, index_column)
- when Operator::EQUAL
- size = estimate_equal(data, index_column)
- when Operator::LESS,
- Operator::LESS_EQUAL,
- Operator::GREATER,
- Operator::GREATER_EQUAL
- size = estimate_range(data, index_column)
- when Operator::CALL
- procedure = data.args.first
- if procedure.is_a?(Procedure) and procedure.name == "between"
- size = estimate_between(data, index_column)
+ estimator = ScanInfoDataSizeEstimator.new(data, @table)
+ size = estimator.estimate
+ case data.logical_op
+ when Operator::AND
+ current_size = size if size < current_size
+ when Operator::AND_NOT
+ size = @table_size - size
+ size = 0 if size < 0
+ current_size = size if size < current_size
+ when Operator::OR
+ current_size = size if size > current_size
+ else
+ message = "invalid logical operator: <#{data.logical_op.inspect}>"
+ raise InvalidArgument, message
+ end
end
end
- size || @table_size
- end
-
- def resolve_index_column(index_column, operator)
- while index_column.is_a?(Accessor)
- index_info = index_column.find_index(operator)
- return nil if index_info.nil?
- index_column = index_info.index
- end
-
- index_column
- end
-
- def estimate_match(data, index_column)
- index_column.estimate_size(:query => data.query.value)
- end
-
- def estimate_regexp(data, index_column)
- index_column.estimate_size(:query => data.query.value,
- :mode => data.op)
- end
-
- def estimate_equal(data, index_column)
- lexicon = index_column.lexicon
- query = data.query
- if query.domain == lexicon.id
- term_id = query.value
- else
- term_id = lexicon[query]
- end
- return 0 if term_id.nil?
-
- index_column.estimate_size(:term_id => term_id)
- end
-
- def estimate_range(data, index_column)
- lexicon = index_column.lexicon
- value = data.query.value
- options = {}
- case data.op
- when Operator::LESS
- options[:max] = value
- options[:flags] = TableCursorFlags::LT
- when Operator::LESS_EQUAL
- options[:max] = value
- options[:flags] = TableCursorFlags::LE
- when Operator::GREATER
- options[:min] = value
- options[:flags] = TableCursorFlags::GT
- when Operator::GREATER_EQUAL
- options[:min] = value
- options[:flags] = TableCursorFlags::GE
- end
- TableCursor.open(lexicon, options) do |cursor|
- index_column.estimate_size(:lexicon_cursor => cursor)
- end
- end
-
- def estimate_between(data, index_column)
- lexicon = index_column.lexicon
- _, _, min, min_border, max, max_border = data.args
- options = {
- :min => min,
- :max => max,
- :flags => 0,
- }
- if min_border == "include"
- options[:flags] |= TableCursorFlags::LT
- else
- options[:flags] |= TableCursorFlags::LE
- end
- if max_border == "include"
- options[:flags] |= TableCursorFlags::GT
- else
- options[:flags] |= TableCursorFlags::GE
- end
-
- TableCursor.open(lexicon, options) do |cursor|
- index_column.estimate_size(:lexicon_cursor => cursor)
- end
+ current_size
end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree.rb
new file mode 100644
index 00000000000..124ace0efb8
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree.rb
@@ -0,0 +1,9 @@
+require "expression_tree/accessor"
+require "expression_tree/constant"
+require "expression_tree/binary_operation"
+require "expression_tree/function_call"
+require "expression_tree/index_column"
+require "expression_tree/logical_operation"
+require "expression_tree/options"
+require "expression_tree/procedure"
+require "expression_tree/variable"
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/Makefile.am
new file mode 100644
index 00000000000..1235932ff14
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/Makefile.am
@@ -0,0 +1,9 @@
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_expression_treedir = $(ruby_scriptsdir)/expression_tree
+ruby_scripts_expression_tree_DATA = $(RUBY_SCRIPT_FILES)
+endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/accessor.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/accessor.rb
new file mode 100644
index 00000000000..ac4b122fb00
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/accessor.rb
@@ -0,0 +1,14 @@
+module Groonga
+ module ExpressionTree
+ class Accessor
+ attr_reader :object
+ def initialize(object)
+ @object = object
+ end
+
+ def build(expression)
+ expression.append_object(@object, Operator::PUSH, 1)
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/binary_operation.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/binary_operation.rb
new file mode 100644
index 00000000000..d59c65c7861
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/binary_operation.rb
@@ -0,0 +1,67 @@
+module Groonga
+ module ExpressionTree
+ class BinaryOperation
+ attr_reader :operator
+ attr_reader :left
+ attr_reader :right
+ def initialize(operator, left, right)
+ @operator = operator
+ @left = left
+ @right = right
+ end
+
+ def build(expression)
+ @left.build(expression)
+ @right.build(expression)
+ expression.append_operator(@operator, 2)
+ end
+
+ RANGE_OPERATORS = [
+ Operator::LESS,
+ Operator::GREATER,
+ Operator::LESS_EQUAL,
+ Operator::GREATER_EQUAL,
+ ]
+ def estimate_size(table)
+ case @operator
+ when *RANGE_OPERATORS
+ estimate_size_range(table)
+ else
+ table.size
+ end
+ end
+
+ private
+ def estimate_size_range(table)
+ return table.size unless @left.is_a?(Variable)
+ return table.size unless @right.is_a?(Constant)
+
+ column = @left.column
+ value = @right.value
+ index_info = column.find_index(@operator)
+ return table.size if index_info.nil?
+
+ index_column = index_info.index
+ lexicon = index_column.lexicon
+ options = {}
+ case @operator
+ when Operator::LESS
+ options[:max] = value
+ options[:flags] = TableCursorFlags::LT
+ when Operator::LESS_EQUAL
+ options[:max] = value
+ options[:flags] = TableCursorFlags::LE
+ when Operator::GREATER
+ options[:min] = value
+ options[:flags] = TableCursorFlags::GT
+ when Operator::GREATER_EQUAL
+ options[:min] = value
+ options[:flags] = TableCursorFlags::GE
+ end
+ TableCursor.open(lexicon, options) do |cursor|
+ index_column.estimate_size(:lexicon_cursor => cursor)
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/constant.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/constant.rb
new file mode 100644
index 00000000000..228a1fc84f5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/constant.rb
@@ -0,0 +1,22 @@
+module Groonga
+ module ExpressionTree
+ class Constant
+ attr_reader :value
+ def initialize(value)
+ @value = value
+ end
+
+ def build(expression)
+ expression.append_constant(@value, Operator::PUSH, 1)
+ end
+
+ def estimate_size(table)
+ if Bulk.true?(@value)
+ table.size
+ else
+ 0
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/function_call.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/function_call.rb
new file mode 100644
index 00000000000..0c7438d6736
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/function_call.rb
@@ -0,0 +1,66 @@
+module Groonga
+ module ExpressionTree
+ class FunctionCall
+ attr_reader :procedure
+ attr_reader :arguments
+ def initialize(procedure, arguments)
+ @procedure = procedure
+ @arguments = arguments
+ end
+
+ def build(expression)
+ @procedure.build(expression)
+ @arguments.each do |argument|
+ argument.build(expression)
+ end
+ expression.append_operator(Operator::CALL, @arguments.size)
+ end
+
+ def estimate_size(table)
+ return table.size unless @procedure.name == "between"
+
+ column, min, min_border, max, max_border = @arguments
+
+ if column.is_a?(Groonga::ExpressionTree::IndexColumn)
+ index_column = column.object
+ else
+ index_info = column.column.find_index(Operator::CALL)
+ return table.size if index_info.nil?
+ index_column = index_info.index
+ end
+
+ while index_column.is_a?(Groonga::Accessor)
+ if index_column.have_next?
+ index_column = index_column.next
+ else
+ index_column = index_column.object
+ index_info = index_column.find_index(Operator::CALL)
+ return table.size if index_info.nil?
+ index_column = index_info.index
+ end
+ end
+
+ lexicon = index_column.lexicon
+ options = {
+ :min => min.value,
+ :max => max.value,
+ :flags => 0,
+ }
+ if min_border.value == "include"
+ options[:flags] |= TableCursorFlags::LT
+ else
+ options[:flags] |= TableCursorFlags::LE
+ end
+ if max_border.value == "include"
+ options[:flags] |= TableCursorFlags::GT
+ else
+ options[:flags] |= TableCursorFlags::GE
+ end
+
+ TableCursor.open(lexicon, options) do |cursor|
+ index_column.estimate_size(:lexicon_cursor => cursor)
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/index_column.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/index_column.rb
new file mode 100644
index 00000000000..c62a8d19f0c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/index_column.rb
@@ -0,0 +1,14 @@
+module Groonga
+ module ExpressionTree
+ class IndexColumn
+ attr_reader :object
+ def initialize(object)
+ @object = object
+ end
+
+ def build(expression)
+ expression.append_object(@object, Operator::PUSH, 1)
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/logical_operation.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/logical_operation.rb
new file mode 100644
index 00000000000..e8d494f89f2
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/logical_operation.rb
@@ -0,0 +1,33 @@
+module Groonga
+ module ExpressionTree
+ class LogicalOperation
+ attr_reader :operator
+ attr_reader :nodes
+ def initialize(operator, nodes)
+ @operator = operator
+ @nodes = nodes
+ end
+
+ def build(expression)
+ @nodes.each_with_index do |node, i|
+ node.build(expression)
+ expression.append_operator(@operator, 2) if i > 0
+ end
+ end
+
+ def estimate_size(table)
+ estimated_sizes = @nodes.collect do |node|
+ node.estimate_size(table)
+ end
+ case @operator
+ when Operator::AND
+ estimated_sizes.min
+ when Operator::OR
+ estimated_sizes.max
+ else
+ estimated_sizes.first
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/options.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/options.rb
new file mode 100644
index 00000000000..1504b57a2db
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/options.rb
@@ -0,0 +1,14 @@
+module Groonga
+ module ExpressionTree
+ class Options
+ attr_reader :object
+ def initialize(object)
+ @object = object
+ end
+
+ def build(expression)
+ expression.append_object(@object, Operator::PUSH, 1)
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/procedure.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/procedure.rb
new file mode 100644
index 00000000000..1d63149cd3c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/procedure.rb
@@ -0,0 +1,18 @@
+module Groonga
+ module ExpressionTree
+ class Procedure
+ attr_reader :object
+ def initialize(object)
+ @object = object
+ end
+
+ def name
+ @object.name
+ end
+
+ def build(expression)
+ expression.append_object(@object, Operator::PUSH, 1)
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/sources.am
new file mode 100644
index 00000000000..d8a776bff92
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/sources.am
@@ -0,0 +1,10 @@
+RUBY_SCRIPT_FILES = \
+ accessor.rb \
+ binary_operation.rb \
+ constant.rb \
+ function_call.rb \
+ index_column.rb \
+ logical_operation.rb \
+ options.rb \
+ procedure.rb \
+ variable.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/variable.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/variable.rb
new file mode 100644
index 00000000000..e99ad9a83b9
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree/variable.rb
@@ -0,0 +1,18 @@
+module Groonga
+ module ExpressionTree
+ class Variable
+ attr_reader :column
+ def initialize(column)
+ @column = column
+ end
+
+ def build(expression)
+ expression.append_object(@column, Operator::GET_VALUE, 1)
+ end
+
+ def estimate_size(table)
+ table.size
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree_builder.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree_builder.rb
new file mode 100644
index 00000000000..f2cc297c231
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_tree_builder.rb
@@ -0,0 +1,111 @@
+require "expression_tree"
+
+module Groonga
+ class ExpressionTreeBuilder
+ RELATION_OPERATORS = [
+ Operator::MATCH,
+ Operator::NEAR,
+ Operator::NEAR2,
+ Operator::SIMILAR,
+ Operator::PREFIX,
+ Operator::SUFFIX,
+ Operator::EQUAL,
+ Operator::NOT_EQUAL,
+ Operator::LESS,
+ Operator::GREATER,
+ Operator::LESS_EQUAL,
+ Operator::GREATER_EQUAL,
+ Operator::GEO_WITHINP5,
+ Operator::GEO_WITHINP6,
+ Operator::GEO_WITHINP8,
+ Operator::TERM_EXTRACT,
+ Operator::REGEXP,
+ Operator::FUZZY,
+ ]
+
+ ARITHMETIC_OPERATORS = [
+ Operator::BITWISE_OR,
+ Operator::BITWISE_XOR,
+ Operator::BITWISE_AND,
+ Operator::BITWISE_NOT,
+ Operator::SHIFTL,
+ Operator::SHIFTR,
+ Operator::SHIFTRR,
+ Operator::PLUS,
+ Operator::MINUS,
+ Operator::STAR,
+ Operator::MOD,
+ ]
+
+ LOGICAL_OPERATORS = [
+ Operator::AND,
+ Operator::OR,
+ Operator::AND_NOT,
+ Operator::ADJUST,
+ ]
+
+ def initialize(expression)
+ @expression = expression
+ end
+
+ def build
+ stack = []
+ codes = @expression.codes
+ codes.each do |code|
+ case code.op
+ when *LOGICAL_OPERATORS
+ right = stack.pop
+ left = stack.pop
+ nodes = []
+ add_logical_operation_node(code.op, nodes, left)
+ add_logical_operation_node(code.op, nodes, right)
+ node = ExpressionTree::LogicalOperation.new(code.op, nodes)
+ stack.push(node)
+ when *RELATION_OPERATORS, *ARITHMETIC_OPERATORS
+ right = stack.pop
+ left = stack.pop
+ node = ExpressionTree::BinaryOperation.new(code.op, left, right)
+ stack.push(node)
+ when Operator::GET_VALUE
+ node = ExpressionTree::Variable.new(code.value)
+ stack.push(node)
+ when Operator::PUSH
+ case code.value
+ when Procedure
+ node = ExpressionTree::Procedure.new(code.value)
+ when IndexColumn
+ node = ExpressionTree::IndexColumn.new(code.value)
+ when Accessor
+ node = ExpressionTree::Accessor.new(code.value)
+ when HashTable
+ node = ExpressionTree::Options.new(code.value)
+ else
+ node = ExpressionTree::Constant.new(code.value.value)
+ end
+ stack.push(node)
+ when Operator::CALL
+ arguments = []
+ (code.n_args - 1).times do
+ arguments.unshift(stack.pop)
+ end
+ procedure = stack.pop
+ node = ExpressionTree::FunctionCall.new(procedure, arguments)
+ stack.push(node)
+ else
+ raise "unknown operator: #{code.inspect}"
+ end
+ end
+ stack.pop
+ end
+
+ private
+ def add_logical_operation_node(operator, nodes, node)
+ if node.is_a?(ExpressionTree::LogicalOperation) and
+ node.operator == operator
+ nodes.concat(node.nodes)
+ else
+ nodes << node
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/fixed_size_column.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/fixed_size_column.rb
new file mode 100644
index 00000000000..4fab9fb78e4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/fixed_size_column.rb
@@ -0,0 +1,5 @@
+module Groonga
+ class FixedSizeColumn
+ include Indexable
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/id.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/id.rb
new file mode 100644
index 00000000000..a49e4fde60e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/id.rb
@@ -0,0 +1,12 @@
+module Groonga
+ module ID
+ # TODO: Should we bind GRN_N_RESERVED_TYPES?
+ N_RESERVED_TYPES = 256
+
+ class << self
+ def builtin?(id)
+ id < N_RESERVED_TYPES
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb
index ccd44758d07..c1215f3e182 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb
@@ -4,11 +4,18 @@ require "context"
require "writer"
+require "id"
+
require "object"
require "database"
require "table"
+require "record"
+require "fixed_size_column"
+require "variable_size_column"
require "index_column"
+require "accessor"
require "command"
+require "command_input"
require "table_cursor"
require "index_cursor"
@@ -17,3 +24,5 @@ require "expression"
require "plugin_loader"
require "eval_context"
+
+require "command_line_parser"
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb
index cb747a418d6..95f86974dc4 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb
@@ -9,12 +9,12 @@ module Groonga
message = "#{error.class}: #{error.message}"
end
backtrace = error.backtrace
- last_raw_entry = backtrace.last
- if last_raw_entry
- last_entry = BacktraceEntry.parse(last_raw_entry)
- file = last_entry.file
- line = last_entry.line
- method = last_entry.method
+ first_raw_entry = backtrace.first
+ if first_raw_entry
+ first_entry = BacktraceEntry.parse(first_raw_entry)
+ file = first_entry.file
+ line = first_entry.line
+ method = first_entry.method
# message = "#{file}:#{line}:#{method}: #{message}"
else
file = ""
@@ -23,8 +23,7 @@ module Groonga
end
log(log_level, file, line, method, message)
- backtrace.reverse_each.with_index do |raw_entry, i|
- next if i == 0
+ backtrace.each_with_index do |raw_entry, i|
entry = BacktraceEntry.parse(raw_entry)
message = entry.message
message = raw_entry if message.empty?
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/level.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/level.rb
index b7660993824..4b8afa2c5d7 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/level.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/level.rb
@@ -2,13 +2,21 @@ module Groonga
class Logger
class Level
@@names = {}
- def self.find(name)
- @@names[name]
+ @@levels = {}
+ class << self
+ def find(name_or_level)
+ if name_or_level.is_a?(Integer)
+ @@levels[name_or_level]
+ else
+ @@names[name_or_level]
+ end
+ end
end
attr_reader :name
def initialize(name, level)
@@names[name] = self
+ @@levels[level] = self
@name = name
@level = level
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb
index d98b5069e7f..aa8e9e65d35 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb
@@ -7,5 +7,12 @@ module Groonga
def range
Context.instance[range_id]
end
+
+ def corrupt?
+ check_corrupt
+ false
+ rescue
+ true
+ end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger.rb
new file mode 100644
index 00000000000..386ec0e221d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger.rb
@@ -0,0 +1,9 @@
+module Groonga
+ class QueryLogger
+ def log(flag, mark, message)
+ flag = Flag.find(flag) if flag.is_a?(Symbol)
+ flag = flag.to_i if flag.is_a?(Flag)
+ log_raw(flag, mark, message)
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/Makefile.am
new file mode 100644
index 00000000000..14b4f61cc62
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/Makefile.am
@@ -0,0 +1,9 @@
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_query_loggerdir = $(ruby_scriptsdir)/query_logger
+ruby_scripts_query_logger_DATA = $(RUBY_SCRIPT_FILES)
+endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/flag.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/flag.rb
new file mode 100644
index 00000000000..659570f659a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/flag.rb
@@ -0,0 +1,39 @@
+module Groonga
+ class QueryLogger
+ class Flag
+ @@names = {}
+ class << self
+ def find(name)
+ @@names[name]
+ end
+ end
+
+ attr_reader :name
+ def initialize(name, flag)
+ @@names[name] = self
+ @name = name
+ @flag = flag
+ end
+
+ def to_i
+ @flag
+ end
+
+ NONE = new(:none, 0x00)
+ COMMAND = new(:command, 0x01 << 0)
+ RESULT_CODE = new(:result_code, 0x01 << 1)
+ DESTINATION = new(:destination, 0x01 << 2)
+ CACHE = new(:cache, 0x01 << 3)
+ SIZE = new(:size, 0x01 << 4)
+ SCORE = new(:score, 0x01 << 5)
+
+ all_flags = COMMAND.to_i |
+ RESULT_CODE.to_i |
+ DESTINATION.to_i |
+ CACHE.to_i |
+ SIZE.to_i |
+ SCORE.to_i
+ ALL = new(:all, all_flags)
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/sources.am
new file mode 100644
index 00000000000..44871a85b0e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/query_logger/sources.am
@@ -0,0 +1,2 @@
+RUBY_SCRIPT_FILES = \
+ flag.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/record.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/record.rb
new file mode 100644
index 00000000000..cd7d1a4cbe2
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/record.rb
@@ -0,0 +1,38 @@
+module Groonga
+ class Record
+ attr_reader :table
+ attr_reader :id
+
+ def inspect
+ super.gsub(/>\z/) do
+ "@id=#{@id.inspect}, @table=#{@table.inspect}>"
+ end
+ end
+
+ def [](name)
+ column = find_column(name)
+ if column.nil?
+ raise InvalidArgument, "unknown column: <#{absolute_column_name(name)}>"
+ end
+ column[@id]
+ end
+
+ def method_missing(name, *args, &block)
+ return super unless args.empty?
+
+ column = find_column(name)
+ return super if column.nil?
+
+ column[@id]
+ end
+
+ private
+ def absolute_column_name(name)
+ "#{@table.name}.#{name}"
+ end
+
+ def find_column(name)
+ Context.instance[absolute_column_name(name)]
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb
index a824e92fa51..1352b327c51 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb
@@ -8,7 +8,7 @@ class ScriptLoader
end
def load_once
- if absolete_path?(@base_path)
+ if absolute_path?(@base_path)
loaded = load_once_path(@base_path)
if loaded.nil?
raise LoadError, error_message
@@ -17,8 +17,11 @@ class ScriptLoader
end
else
$LOAD_PATH.each do |load_path|
- unless absolete_path?(load_path)
+ unless absolute_path?(load_path)
load_path = File.expand_path(load_path)
+ if File::ALT_SEPARATOR
+ load_path = load_path.gsub(File::ALT_SEPARATOR, "/")
+ end
end
loaded = load_once_path(File.join(load_path, @base_path))
return loaded unless loaded.nil?
@@ -32,20 +35,20 @@ class ScriptLoader
"cannot load such file -- #{@base_path}"
end
- def absolete_path?(path)
- path.start_with?("/")
+ def absolute_path?(path)
+ path.start_with?("/") or (/\A[a-z]:\\/i === path)
end
def load_once_path(path)
- loaded = load_once_absolete_path(path)
+ loaded = load_once_absolute_path(path)
return loaded unless loaded.nil?
return nil unless File.extname(path).empty?
- load_once_absolete_path("#{path}.rb")
+ load_once_absolute_path("#{path}.rb")
end
- def load_once_absolete_path(path)
+ def load_once_absolute_path(path)
return false if $".include?(path)
return false if @@loading_paths.key?(path)
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb
index a98cf792a9c..acdb2eeb2c6 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb
@@ -30,6 +30,9 @@ module Groonga
search_index.scorer_args_expr,
search_index.scorer_args_expr_offset || 0)
end
+ if data.start_position
+ self.start_position = data.start_position
+ end
end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb
index dc003f88948..66dad9ea403 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb
@@ -2,19 +2,13 @@ require "scan_info_data"
module Groonga
class ScanInfoBuilder
- module Status
- START = 0
- VAR = 1
- COL1 = 2
- COL2 = 3
- CONST = 4
- end
-
- def initialize(expression, operator, size)
+ def initialize(expression, operator, record_exist)
@data_list = []
@expression = expression
@operator = operator
- @size = size
+ @record_exist = record_exist
+ @variable = @expression[0]
+ @table = Context.instance[@variable.domain]
end
RELATION_OPERATORS = [
@@ -35,6 +29,7 @@ module Groonga
Operator::GEO_WITHINP8,
Operator::TERM_EXTRACT,
Operator::REGEXP,
+ Operator::FUZZY,
]
ARITHMETIC_OPERATORS = [
@@ -60,67 +55,111 @@ module Groonga
def build
return nil unless valid?
- status = Status::START
- variable = @expression.get_var_by_offset(0)
- data = nil
- codes = @expression.codes
- n_codes = codes.size
- codes.each_with_index do |code, i|
- case code.op
+ context = BuildContext.new(@expression)
+ codes = context.codes
+ while context.have_next?
+ code = context.code
+ code_op = context.code_op
+ i = context.i
+ context.next
+
+ case code_op
when *RELATION_OPERATORS
- status = Status::START
- data.op = code.op
+ context.status = :start
+ data = context.data
+ data.op = code_op
data.end = i
+ data.weight = code.value.value if code.value
data.match_resolve_index
@data_list << data
- data = nil
+ context.data = nil
when *LOGICAL_OPERATORS
- put_logical_op(code.op, i)
+ if context.status == :const
+ data = context.data
+ data.op = Operator::PUSH
+ data.end = data.start
+ @data_list << data
+ context.data = nil
+ end
+ put_logical_op(code_op, i)
# TODO: rescue and return nil
- status = Status::START
+ context.status = :start
when Operator::PUSH
- data ||= ScanInfoData.new(i)
- if code.value == variable
- status = Status::VAR
+ context.data ||= ScanInfoData.new(i)
+ data = context.data
+ if code.value == @variable
+ context.status = :var
else
data.args << code.value
- if status == Status::START
+ if context.status == :start
data.flags |= ScanInfo::Flags::PRE_CONST
end
- status = Status::CONST
+ context.status = :const
+ end
+ if code.modify > 0 and
+ LOGICAL_OPERATORS.include?(codes[i + code.modify].op)
+ data.op = Operator::PUSH
+ data.end = data.start
+ @data_list << data
+ context.data = nil
+ context.status = :start
end
when Operator::GET_VALUE
- case status
- when Status::START
- data ||= ScanInfoData.new(i)
- status = Status::COL1
+ case context.status
+ when :start
+ context.data ||= ScanInfoData.new(i)
+ data = context.data
+ context.status = :column1
data.args << code.value
- when Status::CONST, Status::VAR
- status = Status::COL1
+ when :const, :var
+ context.status = :column1
data.args << code.value
- when Status::COL1
- raise ErrorMessage, "invalid expression: can't use column as a value: <#{code.value.name}>: <#{@expression.grn_inspect}>"
- status = Status::COL2
- when Status::COL2
+ when :column1
+ message = "invalid expression: can't use column as a value: "
+ message << "<#{code.value.name}>: <#{@expression.grn_inspect}>"
+ raise ErrorMessage, message
+ when :column2
# Do nothing
+ else
+ message = "internal expression parsing error: unknown status: "
+ message << "<#{context.status.inspect}>: "
+ message << "<#{@expression.grn_inspect}>"
+ raise ErrorMessage, message
end
when Operator::CALL
- data ||= ScanInfoData.new(i)
+ context.data ||= ScanInfoData.new(i)
+ data = context.data
if (code.flags & ExpressionCode::Flags::RELATIONAL_EXPRESSION) != 0 or
- (i + 1) == n_codes
- status = Status::START
- data.op = code.op
+ (not context.have_next?)
+ context.status = :start
+ data.op = code_op
data.end = i
data.call_relational_resolve_indexes
@data_list << data
- data = nil
+ context.data = nil
else
- status = Status::COL2
+ context.status = :column2
end
+ when Operator::GET_REF
+ context.data ||= ScanInfoData.new(i)
+ case context.status
+ when :start
+ data = context.data
+ context.status = :column1
+ data.args << code.value
+ end
+ when Operator::GET_MEMBER
+ data = context.data
+ index = data.args.pop
+ data.start_position = index.value
+ context.status = :column1
+ when Operator::NOT
+ success = build_not(context, code, i)
+ return nil unless success
end
end
- if @operator == Operator::OR and @size == 0
+ if @operator == Operator::OR and !@record_exist
first_data = @data_list.first
if (first_data.flags & ScanInfo::Flags::PUSH) == 0 or
first_data.logical_op != @operator
@@ -130,7 +169,7 @@ module Groonga
first_data.logical_op = @operator
end
else
- put_logical_op(@operator, n_codes)
+ put_logical_op(@operator, context.n_codes)
end
optimize
@@ -140,38 +179,54 @@ module Groonga
def valid?
n_relation_expressions = 0
n_logical_expressions = 0
- status = Status::START
- variable = @expression.get_var_by_offset(0)
+ status = :start
codes = @expression.codes
- codes.each do |code|
+ codes.each_with_index do |code, i|
case code.op
when *RELATION_OPERATORS
- return false if status < Status::COL1
- return false if status > Status::CONST
- status = Status::START
+ if status == :start || status == :var
+ return false
+ end
+ status = :start
n_relation_expressions += 1
when *ARITHMETIC_OPERATORS
- return false if status < Status::COL1
- return false if status > Status::CONST
- status = Status::START
+ if status == :start || status == :var
+ return false
+ end
+ status = :start
return false if n_relation_expressions != (n_logical_expressions + 1)
when *LOGICAL_OPERATORS
- return false if status != Status::START
- n_logical_expressions += 1
- return false if n_logical_expressions >= n_relation_expressions
+ case status
+ when :start
+ n_logical_expressions += 1
+ return false if n_logical_expressions >= n_relation_expressions
+ when :const
+ n_logical_expressions += 1
+ n_relation_expressions += 1
+ return false if n_logical_expressions >= n_relation_expressions
+ status = :start
+ else
+ return false
+ end
when Operator::PUSH
- if code.value == variable
- status = Status::VAR
+ if code.modify > 0 and
+ LOGICAL_OPERATORS.include?(codes[i + code.modify].op)
+ n_relation_expressions += 1
+ status = :start
else
- status = Status::CONST
+ if code.value == @variable
+ status = :var
+ else
+ status = :const
+ end
end
when Operator::GET_VALUE
case status
- when Status::START, Status::CONST, Status::VAR
- status = Status::COL1
- when Status::COL1
- status = Status::COL2
- when Status::COL2
+ when :start, :const, :var
+ status = :column1
+ when :column1
+ status = :column2
+ when :column2
# Do nothing
else
return false
@@ -179,17 +234,34 @@ module Groonga
when Operator::CALL
if (code.flags & ExpressionCode::Flags::RELATIONAL_EXPRESSION) != 0 or
code == codes.last
- status = Status::START
+ status = :start
n_relation_expressions += 1
else
- status = Status::COL2
+ status = :column2
+ end
+ when Operator::GET_REF
+ case status
+ when :start
+ status = :column1
+ else
+ return false
end
+ when Operator::GET_MEMBER
+ case status
+ when :const
+ return false unless codes[i - 1].value.value.is_a?(Integer)
+ status = :column1
+ else
+ return false
+ end
+ when Operator::NOT
+ # Do nothing
else
return false
end
end
- return false if status != Status::START
+ return false if status != :start
return false if n_relation_expressions != (n_logical_expressions + 1)
true
@@ -258,6 +330,61 @@ module Groonga
end
end
+ def build_not(context, code, i)
+ last_data = @data_list.last
+ return false if last_data.nil?
+
+ case last_data.op
+ when Operator::LESS
+ last_data.op = Operator::GREATER_EQUAL
+ last_data.end += 1
+ when Operator::LESS_EQUAL
+ last_data.op = Operator::GREATER
+ last_data.end += 1
+ when Operator::GREATER
+ last_data.op = Operator::LESS_EQUAL
+ last_data.end += 1
+ when Operator::GREATER_EQUAL
+ last_data.op = Operator::LESS
+ last_data.end += 1
+ when Operator::NOT_EQUAL
+ last_data.op = Operator::EQUAL
+ last_data.end += 1
+ else
+ if @data_list.size == 1
+ if last_data.search_indexes.empty?
+ if last_data.op == Operator::EQUAL
+ last_data.op = Operator::NOT_EQUAL
+ last_data.end += 1
+ else
+ return false
+ end
+ else
+ last_data.logical_op = Operator::AND_NOT
+ last_data.flags &= ~ScanInfo::Flags::PUSH
+ @data_list.unshift(create_all_match_data)
+ end
+ else
+ next_code = context.code
+ return false if next_code.nil?
+
+ case next_code.op
+ when Operator::AND
+ context.code_op = Operator::AND_NOT
+ when Operator::AND_NOT
+ context.code_op = Operator::AND
+ when Operator::OR
+ @data_list[-1, 0] = create_all_match_data
+ put_logical_op(Operator::AND_NOT, i)
+ else
+ return false
+ end
+ end
+ end
+
+ true
+ end
+
def optimize
optimized_data_list = []
i = 0
@@ -278,7 +405,45 @@ module Groonga
end
optimized_data_list << data
end
- optimized_data_list
+
+ optimize_by_estimated_size(optimized_data_list)
+ end
+
+ def optimize_by_estimated_size(data_list)
+ return data_list unless Groonga::ORDER_BY_ESTIMATED_SIZE
+
+ start_index = nil
+ data_list.size.times do |i|
+ data = data_list[i]
+ if data.logical_op != Operator::AND
+ if start_index.nil?
+ start_index = i
+ else
+ sort_by_estimated_size!(data_list, start_index...i)
+ start_index = nil
+ end
+ end
+ end
+ unless start_index.nil?
+ sort_by_estimated_size!(data_list, start_index...data_list.size)
+ end
+ data_list
+ end
+
+ def sort_by_estimated_size!(data_list, range)
+ target_data_list = data_list[range]
+ return if target_data_list.size < 2
+
+ start_logical_op = target_data_list.first.logical_op
+ sorted_data_list = target_data_list.sort_by do |data|
+ estimator = ScanInfoDataSizeEstimator.new(data, @table)
+ estimator.estimate
+ end
+ sorted_data_list.each do |sorted_data|
+ sorted_data.logical_op = Operator::AND
+ end
+ sorted_data_list.first.logical_op = start_logical_op
+ data_list[range] = sorted_data_list
end
def range_operations?(data, next_data)
@@ -314,6 +479,17 @@ module Groonga
end
end
+ def create_all_match_data
+ data = ScanInfoData.new(0)
+ data.end = 0
+ data.flags = ScanInfo::Flags::PUSH
+ data.op = Operator::CALL
+ data.logical_op = Operator::OR
+ data.args = [Context.instance["all_records"]]
+ data.search_indexes = []
+ data
+ end
+
def create_between_data(data, next_data)
between_data = ScanInfoData.new(data.start)
between_data.end = next_data.end + 1
@@ -361,5 +537,41 @@ module Groonga
@expression.allocate_constant(max_border),
]
end
+
+ class BuildContext
+ attr_accessor :status
+ attr_reader :codes
+ attr_reader :n_codes
+ attr_reader :i
+ attr_writer :code_op
+ attr_accessor :data
+ def initialize(expression)
+ @expression = expression
+ @status = :start
+ @current_data = nil
+ @codes = @expression.codes
+ @n_codes = @codes.size
+ @i = 0
+ @code_op = nil
+ @data = nil
+ end
+
+ def have_next?
+ @i < @n_codes
+ end
+
+ def next
+ @i += 1
+ @code_op = nil
+ end
+
+ def code
+ @codes[@i]
+ end
+
+ def code_op
+ @code_op || code.op
+ end
+ end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb
index 4a6e58a951a..342f7a7a634 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb
@@ -12,6 +12,8 @@ module Groonga
attr_accessor :flags
attr_accessor :max_interval
attr_accessor :similarity_threshold
+ attr_accessor :start_position
+ attr_accessor :weight
def initialize(start)
@start = start
@end = 0
@@ -23,6 +25,8 @@ module Groonga
@flags = ScanInfo::Flags::PUSH
@max_interval = nil
@similarity_threshold = nil
+ @start_position = nil
+ @weight = 0
end
def match_resolve_index
@@ -36,9 +40,12 @@ module Groonga
end
def call_relational_resolve_indexes
- # better index resolving framework for functions should be implemented
- @args.each do |arg|
- call_relational_resolve_index(arg)
+ procedure, *args = *@args
+ return unless procedure.selector?
+
+ selector_op = procedure.selector_operator
+ args.each do |arg|
+ call_relational_resolve_index(arg, selector_op)
end
end
@@ -54,11 +61,11 @@ module Groonga
match_resolve_index_expression(arg)
when Accessor
match_resolve_index_accessor(arg)
- when Object
- match_resolve_index_db_obj(arg)
+ when Indexable
+ match_resolve_index_indexable(arg)
else
message =
- "The first argument of NEAR/NEAR2 must be Expression, Accessor or Object: #{arg.class}"
+ "The first argument of NEAR/NEAR2 must be Expression, Accessor or Indexable: #{arg.class}"
raise ErrorMessage, message
end
@@ -77,11 +84,11 @@ module Groonga
match_resolve_index_expression(arg)
when Accessor
match_resolve_index_accessor(arg)
- when Object
- match_resolve_index_db_obj(arg)
+ when Indexable
+ match_resolve_index_indexable(arg)
else
message =
- "The first argument of SIMILAR must be Expression, Accessor or Object: #{arg.class}"
+ "The first argument of SIMILAR must be Expression, Accessor or Indexable: #{arg.class}"
raise ErrorMesesage, message
end
@@ -96,8 +103,12 @@ module Groonga
match_resolve_index_expression(arg)
when Accessor
match_resolve_index_accessor(arg)
- when Object
- match_resolve_index_db_obj(arg)
+ when IndexColumn
+ match_resolve_index_index_column(arg)
+ when Indexable
+ match_resolve_index_indexable(arg)
+ when Procedure
+ break
else
self.query = arg
end
@@ -188,13 +199,12 @@ module Groonga
end
weight, offset = codes[i].weight
i += offset
- search_index = ScanInfoSearchIndex.new(index_info.index,
- index_info.section_id,
- weight,
- scorer,
- expression,
- scorer_args_expr_offset)
- @search_indexes << search_index
+ put_search_index(index_info.index,
+ index_info.section_id,
+ weight,
+ scorer,
+ expression,
+ scorer_args_expr_offset)
end
when Table
raise ErrorMessage, "invalid match target: <#{value.name}>"
@@ -258,8 +268,12 @@ module Groonga
put_search_index(index_info.index, index_info.section_id, expr_code.weight)
end
- def match_resolve_index_db_obj(db_obj)
- index_info = db_obj.find_index(op)
+ def match_resolve_index_index_column(index)
+ put_search_index(index, 0, 1)
+ end
+
+ def match_resolve_index_indexable(indexable)
+ index_info = indexable.find_index(op)
return if index_info.nil?
put_search_index(index_info.index, index_info.section_id, 1)
end
@@ -275,32 +289,35 @@ module Groonga
end
end
- def call_relational_resolve_index(object)
+ def call_relational_resolve_index(object, selector_op)
case object
when Accessor
- call_relational_resolve_index_accessor(object)
+ call_relational_resolve_index_accessor(object, selector_op)
when Bulk
self.query = object
- else
- call_relational_resolve_index_db_obj(object)
+ when Indexable
+ call_relational_resolve_index_indexable(object, selector_op)
end
end
- def call_relational_resolve_index_db_obj(db_obj)
- index_info = db_obj.find_index(op)
+ def call_relational_resolve_index_indexable(indexable, selector_op)
+ index_info = indexable.find_index(selector_op)
return if index_info.nil?
put_search_index(index_info.index, index_info.section_id, 1)
end
- def call_relational_resolve_index_accessor(accessor)
+ def call_relational_resolve_index_accessor(accessor, selector_op)
self.flags |= ScanInfo::Flags::ACCESSOR
- index_info = accessor.find_index(op)
+ index_info = accessor.find_index(selector_op)
return if index_info.nil?
put_search_index(index_info.index, index_info.section_id, 1)
end
- def put_search_index(index, section_id, weight)
- search_index = ScanInfoSearchIndex.new(index, section_id, weight)
+ def put_search_index(index, section_id, weight, *args)
+ search_index = ScanInfoSearchIndex.new(index,
+ section_id,
+ weight + @weight,
+ *args)
@search_indexes << search_index
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data_size_estimator.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data_size_estimator.rb
new file mode 100644
index 00000000000..5d3dc4e04a1
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data_size_estimator.rb
@@ -0,0 +1,185 @@
+module Groonga
+ class ScanInfoDataSizeEstimator
+ def initialize(data, table)
+ @data = data
+ @table = table
+ @table_size = @table.size
+ end
+
+ def estimate
+ search_index = @data.search_indexes.first
+ return @table_size if search_index.nil?
+
+ index_column = resolve_index_column(search_index.index_column)
+ return @table_size if index_column.nil?
+
+ size = nil
+ case @data.op
+ when Operator::MATCH,
+ Operator::FUZZY
+ size = estimate_match(index_column)
+ when Operator::REGEXP
+ size = estimate_regexp(index_column)
+ when Operator::EQUAL
+ size = estimate_equal(index_column)
+ when Operator::LESS,
+ Operator::LESS_EQUAL,
+ Operator::GREATER,
+ Operator::GREATER_EQUAL
+ size = estimate_range(index_column)
+ when Operator::PREFIX
+ size = estimate_prefix(index_column)
+ when Operator::CALL
+ size = estimate_call(index_column)
+ end
+ size || @table_size
+ end
+
+ private
+ def resolve_index_column(index_column)
+ while index_column.is_a?(Accessor)
+ index_info = index_column.find_index(@data.op)
+ return nil if index_info.nil?
+ break if index_info.index == index_column
+ index_column = index_info.index
+ end
+
+ index_column
+ end
+
+ def sampling_cursor_limit(n_terms)
+ limit = n_terms * 0.01
+ if limit < 10
+ 10
+ elsif limit > 1000
+ 1000
+ else
+ limit.to_i
+ end
+ end
+
+ def estimate_match(index_column)
+ index_column.estimate_size(:query => @data.query.value)
+ end
+
+ def estimate_regexp(index_column)
+ index_column.estimate_size(:query => @data.query.value,
+ :mode => @data.op)
+ end
+
+ def estimate_equal(index_column)
+ query = @data.query
+ if index_column.is_a?(Accessor)
+ table = index_column.object
+ if index_column.name == "_id"
+ if table.id?(query.value)
+ 1
+ else
+ 0
+ end
+ else
+ if table[query.value]
+ 1
+ else
+ 0
+ end
+ end
+ else
+ lexicon = index_column.lexicon
+ if query.domain == lexicon.id
+ term_id = query.value
+ else
+ term_id = lexicon[query]
+ end
+ return 0 if term_id.nil?
+
+ index_column.estimate_size(:term_id => term_id)
+ end
+ end
+
+ def estimate_range(index_column)
+ if index_column.is_a?(Table)
+ is_table_search = true
+ lexicon = index_column
+ elsif index_column.is_a?(Groonga::Accessor)
+ is_table_search = true
+ lexicon = index_column.object
+ else
+ is_table_search = false
+ lexicon = index_column.lexicon
+ end
+ n_terms = lexicon.size
+ return 0 if n_terms.zero?
+
+ value = @data.query.value
+ options = {
+ :limit => sampling_cursor_limit(n_terms),
+ }
+ case @data.op
+ when Operator::LESS
+ options[:max] = value
+ options[:flags] = TableCursorFlags::LT
+ when Operator::LESS_EQUAL
+ options[:max] = value
+ options[:flags] = TableCursorFlags::LE
+ when Operator::GREATER
+ options[:min] = value
+ options[:flags] = TableCursorFlags::GT
+ when Operator::GREATER_EQUAL
+ options[:min] = value
+ options[:flags] = TableCursorFlags::GE
+ end
+ TableCursor.open(lexicon, options) do |cursor|
+ if is_table_search
+ size = 1
+ else
+ size = index_column.estimate_size(:lexicon_cursor => cursor)
+ end
+ size += 1 if cursor.next != ID::NIL
+ size
+ end
+ end
+
+ def estimate_prefix(index_column)
+ is_table_search =
+ (index_column.is_a?(Accessor) and
+ index_column.name == "_key")
+ if is_table_search
+ lexicon = index_column.object
+ else
+ lexicon = index_column.lexicon
+ end
+ n_terms = lexicon.size
+ return 0 if n_terms.zero?
+
+ value = @data.query.value
+ options = {
+ :min => value,
+ :limit => sampling_cursor_limit(n_terms),
+ :flags => TableCursorFlags::PREFIX,
+ }
+ TableCursor.open(lexicon, options) do |cursor|
+ if is_table_search
+ size = 1
+ else
+ size = index_column.estimate_size(:lexicon_cursor => cursor)
+ end
+ size += 1 if cursor.next != ID::NIL
+ size
+ end
+ end
+
+ def estimate_call(index_column)
+ procedure = @data.args[0]
+ arguments = @data.args[1..-1].collect do |arg|
+ if arg.is_a?(::Groonga::Object)
+ ExpressionTree::Variable.new(arg)
+ else
+ ExpressionTree::Constant.new(arg)
+ end
+ end
+ node = ExpressionTree::FunctionCall.new(procedure, arguments)
+ node.estimate_size(@table)
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
index 6fda01812b9..9a9e2bae689 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
@@ -1,12 +1,21 @@
RUBY_SCRIPT_FILES = \
+ accessor.rb \
backtrace_entry.rb \
command.rb \
+ command_input.rb \
+ command_line_parser.rb \
context.rb \
database.rb \
error.rb \
eval_context.rb \
expression.rb \
+ expression_rewriter.rb \
+ expression_rewriters.rb \
expression_size_estimator.rb \
+ expression_tree.rb \
+ expression_tree_builder.rb \
+ fixed_size_column.rb \
+ id.rb \
index_column.rb \
index_cursor.rb \
index_info.rb \
@@ -14,11 +23,15 @@ RUBY_SCRIPT_FILES = \
object.rb \
operator.rb \
plugin_loader.rb \
+ query_logger.rb \
+ record.rb \
require.rb \
scan_info.rb \
scan_info_builder.rb \
scan_info_data.rb \
+ scan_info_data_size_estimator.rb \
scan_info_search_index.rb \
table.rb \
table_cursor.rb \
+ variable_size_column.rb \
writer.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb
index 5a1b640c25f..75c918949f0 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb
@@ -1,5 +1,26 @@
module Groonga
class Table
+ include Enumerable
+ include Indexable
+
+ def columns
+ context = Context.instance
+ column_ids.collect do |id|
+ context[id]
+ end
+ end
+
+ def each
+ flags =
+ TableCursorFlags::ASCENDING |
+ TableCursorFlags::BY_ID
+ TableCursor.open(self, :flags => flags) do |cursor|
+ cursor.each do |id|
+ yield(id)
+ end
+ end
+ end
+
def sort(keys, options={})
offset = options[:offset] || 0
limit = options[:limit] || -1
@@ -21,7 +42,32 @@ module Groonga
end
end
+ def apply_window_function(output_column,
+ window_function_call,
+ options={})
+ ensure_sort_keys_accept_nil(options[:sort_keys]) do |sort_keys|
+ ensure_sort_keys_accept_nil(options[:group_keys]) do |group_keys|
+ window_definition = WindowDefinition.new
+ begin
+ window_definition.sort_keys = sort_keys
+ window_definition.group_keys = group_keys
+ apply_window_function_raw(output_column,
+ window_definition,
+ window_function_call)
+ ensure
+ window_definition.close
+ end
+ end
+ end
+ end
+
private
+ def ensure_sort_keys_accept_nil(keys, &block)
+ return yield(nil) if keys.nil?
+
+ ensure_sort_keys(keys, &block)
+ end
+
def ensure_sort_keys(keys)
if keys.is_a?(::Array) and keys.all? {|key| key.is_a?(TableSortKey)}
return yield(keys)
@@ -77,7 +123,15 @@ module Groonga
key_name[0] = ""
end
- sort_key.key = find_column(key_name)
+ key = find_column(key_name)
+ if key.nil?
+ table_name = name || "(temporary)"
+ message = "unknown key: #{key_name.inspect}: "
+ message << "#{table_name}(#{size})"
+ raise ArgumentError, message
+ end
+
+ sort_key.key = key
if order == :ascending
sort_key.flags = Groonga::TableSortFlags::ASCENDING
else
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb
index a36d88d556d..45949b717c8 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb
@@ -1,5 +1,7 @@
module Groonga
class TableCursor
+ include Enumerable
+
class << self
def open(*arguments)
cursor = open_raw(*arguments)
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/test/empty.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/test/empty.rb
deleted file mode 100644
index 123002d4b2b..00000000000
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/test/empty.rb
+++ /dev/null
@@ -1 +0,0 @@
-# This file is just for test.
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/variable_size_column.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/variable_size_column.rb
new file mode 100644
index 00000000000..3d75502f43c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/variable_size_column.rb
@@ -0,0 +1,5 @@
+module Groonga
+ class VariableSizeColumn
+ include Indexable
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/sources.am
index b27e3654af8..9db1673715f 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/sources.am
+++ b/storage/mroonga/vendor/groonga/lib/mrb/sources.am
@@ -5,12 +5,18 @@ libgrnmrb_la_SOURCES = \
mrb_array.h \
mrb_bulk.c \
mrb_bulk.h \
+ mrb_cache.c \
+ mrb_cache.h \
mrb_column.c \
mrb_column.h \
mrb_command.c \
mrb_command.h \
mrb_command_input.c \
mrb_command_input.h \
+ mrb_command_version.c \
+ mrb_command_version.h \
+ mrb_config.c \
+ mrb_config.h \
mrb_content_type.c \
mrb_content_type.h \
mrb_converter.c \
@@ -23,6 +29,8 @@ libgrnmrb_la_SOURCES = \
mrb_double_array_trie.h \
mrb_error.c \
mrb_error.h \
+ mrb_eval_context.c \
+ mrb_eval_context.h \
mrb_expr.c \
mrb_expr.h \
mrb_fixed_size_column.c \
@@ -31,6 +39,8 @@ libgrnmrb_la_SOURCES = \
mrb_hash_table.h \
mrb_id.c \
mrb_id.h \
+ mrb_indexable.c \
+ mrb_indexable.h \
mrb_index_column.c \
mrb_index_column.h \
mrb_index_cursor.c \
@@ -47,8 +57,14 @@ libgrnmrb_la_SOURCES = \
mrb_options.h \
mrb_patricia_trie.c \
mrb_patricia_trie.h \
+ mrb_pointer.c \
+ mrb_pointer.h \
mrb_procedure.c \
mrb_procedure.h \
+ mrb_query_logger.c \
+ mrb_query_logger.h \
+ mrb_record.c \
+ mrb_record.h \
mrb_table.c \
mrb_table.h \
mrb_table_cursor.c \
@@ -63,11 +79,15 @@ libgrnmrb_la_SOURCES = \
mrb_table_sort_flags.h \
mrb_table_sort_key.c \
mrb_table_sort_key.h \
+ mrb_thread.c \
+ mrb_thread.h \
mrb_type.c \
mrb_type.h \
mrb_variable_size_column.c \
mrb_variable_size_column.h \
mrb_void.c \
mrb_void.h \
+ mrb_window_definition.c \
+ mrb_window_definition.h \
mrb_writer.c \
mrb_writer.h
diff --git a/storage/mroonga/vendor/groonga/lib/nfkc.c b/storage/mroonga/vendor/groonga/lib/nfkc.c
index 30e06f94a34..2330fbbe705 100644
--- a/storage/mroonga/vendor/groonga/lib/nfkc.c
+++ b/storage/mroonga/vendor/groonga/lib/nfkc.c
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2010 Brazil
+/*
+ Copyright(C) 2010-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -13,80233 +14,31 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-don't edit this file by hand. it generated automatically by nfkc.rb
*/
#include "grn.h"
+#include "grn_nfkc.h"
#include <groonga/nfkc.h>
#ifdef GRN_WITH_NFKC
grn_char_type
-grn_nfkc_char_type(const unsigned char *str)
+grn_nfkc_char_type(const unsigned char *utf8)
{
-switch (str[0]) {
-case 0x01 :
-case 0x02 :
-case 0x03 :
-case 0x04 :
-case 0x05 :
-case 0x06 :
-case 0x07 :
-case 0x08 :
-case 0x09 :
-case 0x0A :
-case 0x0B :
-case 0x0C :
-case 0x0D :
-case 0x0E :
-case 0x0F :
-case 0x10 :
-case 0x11 :
-case 0x12 :
-case 0x13 :
-case 0x14 :
-case 0x15 :
-case 0x16 :
-case 0x17 :
-case 0x18 :
-case 0x19 :
-case 0x1A :
-case 0x1B :
-case 0x1C :
-case 0x1D :
-case 0x1E :
-case 0x1F :
-case 0x20 :
- return GRN_CHAR_OTHERS;
- break;
-case 0x21 :
-case 0x22 :
-case 0x23 :
-case 0x24 :
-case 0x25 :
-case 0x26 :
-case 0x27 :
-case 0x28 :
-case 0x29 :
-case 0x2A :
-case 0x2B :
-case 0x2C :
-case 0x2D :
-case 0x2E :
-case 0x2F :
- return GRN_CHAR_SYMBOL;
- break;
-case 0x30 :
-case 0x31 :
-case 0x32 :
-case 0x33 :
-case 0x34 :
-case 0x35 :
-case 0x36 :
-case 0x37 :
-case 0x38 :
-case 0x39 :
- return GRN_CHAR_DIGIT;
- break;
-case 0x3A :
-case 0x3B :
-case 0x3C :
-case 0x3D :
-case 0x3E :
-case 0x3F :
-case 0x40 :
- return GRN_CHAR_SYMBOL;
- break;
-case 0x41 :
-case 0x42 :
-case 0x43 :
-case 0x44 :
-case 0x45 :
-case 0x46 :
-case 0x47 :
-case 0x48 :
-case 0x49 :
-case 0x4A :
-case 0x4B :
-case 0x4C :
-case 0x4D :
-case 0x4E :
-case 0x4F :
-case 0x50 :
-case 0x51 :
-case 0x52 :
-case 0x53 :
-case 0x54 :
-case 0x55 :
-case 0x56 :
-case 0x57 :
-case 0x58 :
-case 0x59 :
-case 0x5A :
- return GRN_CHAR_ALPHA;
- break;
-case 0x5B :
-case 0x5C :
-case 0x5D :
-case 0x5E :
-case 0x5F :
-case 0x60 :
- return GRN_CHAR_SYMBOL;
- break;
-case 0x61 :
-case 0x62 :
-case 0x63 :
-case 0x64 :
-case 0x65 :
-case 0x66 :
-case 0x67 :
-case 0x68 :
-case 0x69 :
-case 0x6A :
-case 0x6B :
-case 0x6C :
-case 0x6D :
-case 0x6E :
-case 0x6F :
-case 0x70 :
-case 0x71 :
-case 0x72 :
-case 0x73 :
-case 0x74 :
-case 0x75 :
-case 0x76 :
-case 0x77 :
-case 0x78 :
-case 0x79 :
-case 0x7A :
- return GRN_CHAR_ALPHA;
- break;
-case 0x7B :
-case 0x7C :
-case 0x7D :
-case 0x7E :
- return GRN_CHAR_SYMBOL;
- break;
-case 0x7F :
-case 0x80 :
-case 0x81 :
-case 0x82 :
-case 0x83 :
-case 0x84 :
-case 0x85 :
-case 0x86 :
-case 0x87 :
-case 0x88 :
-case 0x89 :
-case 0x8A :
-case 0x8B :
-case 0x8C :
-case 0x8D :
-case 0x8E :
-case 0x8F :
-case 0x90 :
-case 0x91 :
-case 0x92 :
-case 0x93 :
-case 0x94 :
-case 0x95 :
-case 0x96 :
-case 0x97 :
-case 0x98 :
-case 0x99 :
-case 0x9A :
-case 0x9B :
-case 0x9C :
-case 0x9D :
-case 0x9E :
-case 0x9F :
-case 0xA0 :
-case 0xA1 :
-case 0xA2 :
-case 0xA3 :
-case 0xA4 :
-case 0xA5 :
-case 0xA6 :
-case 0xA7 :
-case 0xA8 :
-case 0xA9 :
-case 0xAA :
-case 0xAB :
-case 0xAC :
-case 0xAD :
-case 0xAE :
-case 0xAF :
-case 0xB0 :
-case 0xB1 :
-case 0xB2 :
-case 0xB3 :
-case 0xB4 :
-case 0xB5 :
-case 0xB6 :
-case 0xB7 :
-case 0xB8 :
-case 0xB9 :
-case 0xBA :
-case 0xBB :
-case 0xBC :
-case 0xBD :
-case 0xBE :
-case 0xBF :
-case 0xC0 :
-case 0xC1 :
- return GRN_CHAR_OTHERS;
- break;
-case 0xC2 :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAB :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAC :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAD :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB4 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB5 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB9 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xBA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBB :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBC :
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_DIGIT;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
-case 0xC3 :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x97 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB7 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB8 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
-case 0xC4 :
-case 0xC5 :
-case 0xC6 :
-case 0xC7 :
-case 0xC8 :
-case 0xC9 :
-case 0xCA :
- return GRN_CHAR_ALPHA;
- break;
-case 0xCB :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAE :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAF :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
-case 0xCC :
- return GRN_CHAR_OTHERS;
- break;
-case 0xCD :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB4 :
- case 0xB5 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBE :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-case 0xCE :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x86 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x87 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x88 :
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA2 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA3 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
-case 0xCF :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB6 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB7 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
-case 0xD0 :
-case 0xD1 :
- return GRN_CHAR_ALPHA;
- break;
-case 0xD2 :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x82 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8A :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
-case 0xD3 :
- return GRN_CHAR_ALPHA;
- break;
-case 0xD4 :
- if (str[1] < 0x94) { return GRN_CHAR_ALPHA; }
- if (str[1] < 0xB1) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
-case 0xD5 :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x97 :
- case 0x98 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x99 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA0 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA1 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
-case 0xD6 :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x88 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBE :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-case 0xD7 :
- switch (str[1]) {
- case 0x80 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x81 :
- case 0x82 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x83 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x86 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB3 :
- case 0xB4 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB5 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-case 0xD8 :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9B :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA0 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBB :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-case 0xD9 :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB0 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB1 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
-case 0xDA :
- return GRN_CHAR_ALPHA;
- break;
-case 0xDB :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x94 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x95 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA5 :
- case 0xA6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA9 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
-case 0xDC :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-case 0xDD :
- if (str[1] < 0x8D) { return GRN_CHAR_OTHERS; }
- if (str[1] < 0xAE) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
-case 0xDE :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB2 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-case 0xDF :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB4 :
- case 0xB5 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBB :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-case 0xE0 :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA4 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA5 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA2 :
- case 0xA3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB0 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBB :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0xA6 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8D :
- case 0x8E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8F :
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- case 0x92 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB1 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB2 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA7 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8E :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB0 :
- case 0xB1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xBA :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBB :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA8 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8F :
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- case 0x92 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB1 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB4 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB5 :
- case 0xB6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA9 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9E :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB0 :
- case 0xB1 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB5 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xAA :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8F :
- case 0x90 :
- case 0x91 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x92 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB1 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB4 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xAB :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB0 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB1 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB2 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xAC :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8D :
- case 0x8E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8F :
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- case 0x92 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB1 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB4 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xAD :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB0 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB2 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xAE :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x83 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8B :
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8E :
- case 0x8F :
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x96 :
- case 0x97 :
- case 0x98 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x99 :
- case 0x9A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA3 :
- case 0xA4 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAB :
- case 0xAC :
- case 0xAD :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xAF :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBB :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB0 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8E :
- case 0x8F :
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB4 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB1 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB2 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8E :
- case 0x8F :
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB4 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB3 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9E :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB0 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB1 :
- case 0xB2 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB3 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB4 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8E :
- case 0x8F :
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB5 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB6 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB2 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBC :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB7 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB4 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB5 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB8 :
- switch (str[2]) {
- case 0x80 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB1 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0xB9 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x9A :
- case 0x9B :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9C :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xBA :
- switch (str[2]) {
- case 0x80 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x81 :
- case 0x82 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x83 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x84 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x85 :
- case 0x86 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x87 :
- case 0x88 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x89 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x98 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA0 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA4 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA5 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA6 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA7 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA8 :
- case 0xA9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAA :
- case 0xAB :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAC :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB1 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xBB :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x85 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x86 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x9A :
- case 0x9B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xBC :
- switch (str[2]) {
- case 0x80 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB4 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB6 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB8 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xBD :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x88 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAB :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xBE :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0xBF :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x86 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8D :
- case 0x8E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8F :
- case 0x90 :
- case 0x91 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x92 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-case 0xE1 :
- switch (str[1]) {
- case 0x80 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA2 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA8 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA9 :
- case 0xAA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAB :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x81 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x96 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x82 :
- if (str[2] < 0xA0) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0x83 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBB :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBD :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x84 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x85 :
- if (str[2] < 0x9A) { return GRN_CHAR_ALPHA; }
- if (str[2] < 0x9F) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0x86 :
- if (str[2] < 0xA3) { return GRN_CHAR_ALPHA; }
- if (str[2] < 0xA8) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0x87 :
- if (str[2] < 0xBA) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x88 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x89 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x89 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x97 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x98 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x99 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x8A :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x89 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB1 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB6 :
- case 0xB7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x8B :
- switch (str[2]) {
- case 0x80 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x81 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x97 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x98 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x8C :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x98 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x8D :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_DIGIT;
- break;
- case 0xBD :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x8E :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_ALPHA;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x8F :
- if (str[2] < 0xB5) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- if (str[2] < 0x81) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x99 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAD :
- case 0xAE :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB7 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x9A :
- switch (str[2]) {
- case 0x80 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9B :
- case 0x9C :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x9B :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAB :
- case 0xAC :
- case 0xAD :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB1 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x9C :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB5 :
- case 0xB6 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB7 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x9D :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAD :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB1 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x9E :
- if (str[2] < 0xB4) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x9F :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x97 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xBA :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA0 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0xA1 :
- if (str[2] < 0xB8) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0xA2 :
- if (str[2] < 0xA9) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0xA3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA4 :
- if (str[2] < 0x9D) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0xA5 :
- switch (str[2]) {
- case 0x80 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x81 :
- case 0x82 :
- case 0x83 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_DIGIT;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB5 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA6 :
- if (str[2] < 0xAA) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0xA7 :
- switch (str[2]) {
- case 0x80 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9E :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0xA8 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA0 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAC :
- if (str[2] < 0x85) { return GRN_CHAR_OTHERS; }
- if (str[2] < 0xB4) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0xAD :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBD :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- if (str[2] < 0x9C) { return GRN_CHAR_ALPHA; }
- if (str[2] < 0xA0) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0xBB :
- if (str[2] < 0xBA) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0xBC :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0xBD :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x98 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x99 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9A :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9B :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9C :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xBE :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBD :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBE :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0xBF :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x85 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x94 :
- case 0x95 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9C :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB0 :
- case 0xB1 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-case 0xE2 :
- switch (str[1]) {
- case 0x80 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9A :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9B :
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9E :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB9 :
- case 0xBA :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBB :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0x81 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB1 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x82 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB6 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x83 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x84 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x82 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x87 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x88 :
- case 0x89 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x94 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x95 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x96 :
- case 0x97 :
- case 0x98 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA4 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA5 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA7 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA9 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAE :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- case 0xBB :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBC :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x85 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8E :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x93 :
- default :
- return GRN_CHAR_DIGIT;
- break;
- }
- break;
- case 0x86 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8F :
- if (str[2] < 0xA8) { return GRN_CHAR_SYMBOL; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- if (str[2] < 0xA7) { return GRN_CHAR_SYMBOL; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x91 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- default :
- return GRN_CHAR_DIGIT;
- break;
- }
- break;
- case 0x92 :
- if (str[2] < 0x9C) { return GRN_CHAR_DIGIT; }
- return GRN_CHAR_SYMBOL;
- break;
- case 0x93 :
- if (str[2] < 0xAA) { return GRN_CHAR_SYMBOL; }
- return GRN_CHAR_DIGIT;
- break;
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9A :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB3 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x9B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9C :
- switch (str[2]) {
- case 0x80 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x85 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8A :
- case 0x8B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA8 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA9 :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0x9D :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8C :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8D :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x93 :
- case 0x94 :
- case 0x95 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x96 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x97 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9F :
- case 0xA0 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB6 :
- default :
- return GRN_CHAR_DIGIT;
- break;
- }
- break;
- case 0x9E :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x94 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x95 :
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB0 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x9F :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAC :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA4 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0xB1 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB8 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB2 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB3 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBD :
- return GRN_CHAR_DIGIT;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0xB4 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0xB5 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAF :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB6 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB7 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x87 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x97 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9F :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB8 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x86 :
- case 0x87 :
- case 0x88 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8B :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x98 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBA :
- case 0xBB :
- case 0xBC :
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_KANJI;
- break;
- case 0xBF :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_KANJI;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBC :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-case 0xE3 :
- switch (str[1]) {
- case 0x80 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x81 :
- return GRN_CHAR_HIRAGANA;
- break;
- case 0x82 :
- if (str[2] < 0xA0) { return GRN_CHAR_HIRAGANA; }
- return GRN_CHAR_KATAKANA;
- break;
- case 0x83 :
- return GRN_CHAR_KATAKANA;
- break;
- case 0x84 :
- case 0x85 :
- case 0x86 :
- return GRN_CHAR_KANJI;
- break;
- case 0x87 :
- if (str[2] < 0xB0) { return GRN_CHAR_KANJI; }
- return GRN_CHAR_KATAKANA;
- break;
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x90 :
- default :
- return GRN_CHAR_KANJI;
- break;
- }
- break;
-case 0xE4 :
- if (str[1] < 0xB7) { return GRN_CHAR_KANJI; }
- if (str[1] < 0xB8) { return GRN_CHAR_SYMBOL; }
- return GRN_CHAR_KANJI;
- break;
-case 0xE5 :
-case 0xE6 :
-case 0xE7 :
-case 0xE8 :
-case 0xE9 :
- return GRN_CHAR_KANJI;
- break;
-case 0xEA :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- return GRN_CHAR_KANJI;
- break;
- case 0x93 :
- if (str[2] < 0x90) { return GRN_CHAR_KANJI; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9C :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA2 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x82 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x83 :
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x86 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAC :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA1 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB8 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_KANJI;
- break;
- }
- break;
-case 0xEB :
-case 0xEC :
- return GRN_CHAR_KANJI;
- break;
-case 0xED :
- if (str[1] < 0x9E) { return GRN_CHAR_KANJI; }
- if (str[1] == 0x9E) {
- if (str[2] < 0xB0) { return GRN_CHAR_KANJI; }
- return GRN_CHAR_OTHERS;
- }
- return GRN_CHAR_OTHERS;
- break;
-case 0xEE :
- return GRN_CHAR_OTHERS;
- break;
-case 0xEF :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- return GRN_CHAR_KANJI;
- break;
- case 0xAC :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA9 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- case 0xBC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBD :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBE :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xAD :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x82 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x85 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x86 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0xAE :
- if (str[2] < 0xB2) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0xAF :
- if (str[2] < 0x93) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB4 :
- if (str[2] < 0xBE) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB5 :
- if (str[2] < 0x90) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0xB6 :
- if (str[2] < 0x90) { return GRN_CHAR_ALPHA; }
- if (str[2] < 0x92) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0xB7 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBC :
- case 0xBD :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBE :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xB8 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0xB9 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x93 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB5 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB6 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0xBA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBB :
- if (str[2] < 0xBD) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0xBC :
- switch (str[2]) {
- case 0x80 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBB :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0xBD :
- switch (str[2]) {
- case 0x80 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA6 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0xBE :
- if (str[2] < 0xBF) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0xBF :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x88 :
- case 0x89 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_ALPHA;
- break;
- case 0x90 :
- case 0x91 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBC :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
-case 0xF0 :
- switch (str[1]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x90 :
- switch (str[2]) {
- case 0x80 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8C :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBB :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBC :
- case 0xBD :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBE :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x81 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x82 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x83 :
- if (str[3] < 0xBB) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x84 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB7 :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0x85 :
- if (str[3] < 0xB9) { return GRN_CHAR_DIGIT; }
- return GRN_CHAR_SYMBOL;
- break;
- case 0x86 :
- if (str[3] < 0x8A) { return GRN_CHAR_SYMBOL; }
- if (str[3] < 0x8B) { return GRN_CHAR_DIGIT; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8C :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x8D :
- switch (str[3]) {
- case 0x80 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x81 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8A :
- return GRN_CHAR_DIGIT;
- break;
- case 0x8B :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x8E :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA0 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x8F :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_ALPHA;
- break;
- case 0x90 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x96 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x90 :
- case 0x91 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x92 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xAA :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x88 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x89 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB6 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB7 :
- case 0xB8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB9 :
- case 0xBA :
- case 0xBB :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA4 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA0 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA8 :
- switch (str[3]) {
- case 0x80 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x94 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x95 :
- case 0x96 :
- case 0x97 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x98 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB4 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0xA9 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x99 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x91 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x92 :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8D :
- if (str[3] < 0xAF) { return GRN_CHAR_ALPHA; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- return GRN_CHAR_DIGIT;
- break;
- case 0x91 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- return GRN_CHAR_OTHERS;
- break;
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB4 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9D :
- switch (str[2]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x83 :
- if (str[3] < 0xB6) { return GRN_CHAR_SYMBOL; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x84 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAA :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0x85 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAD :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x86 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAE :
- default :
- return GRN_CHAR_SYMBOL;
- break;
- }
- break;
- case 0x87 :
- if (str[3] < 0x9E) { return GRN_CHAR_SYMBOL; }
- return GRN_CHAR_OTHERS;
- break;
- case 0x88 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x89 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x85 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x86 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x8A :
- case 0x8B :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8C :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8D :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- return GRN_CHAR_DIGIT;
- break;
- case 0xB2 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x8E :
- case 0x8F :
- return GRN_CHAR_OTHERS;
- break;
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- if (str[3] < 0x95) { return GRN_CHAR_ALPHA; }
- if (str[3] < 0x96) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0x92 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA0 :
- case 0xA1 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA2 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA3 :
- case 0xA4 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA5 :
- case 0xA6 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAD :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBB :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBC :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBD :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x93 :
- if (str[3] < 0x84) { return GRN_CHAR_ALPHA; }
- if (str[3] < 0x85) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0x94 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x86 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8B :
- case 0x8C :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x95 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBA :
- return GRN_CHAR_OTHERS;
- break;
- case 0xBB :
- case 0xBC :
- case 0xBD :
- case 0xBE :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBF :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x95 :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x85 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x86 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x87 :
- case 0x88 :
- case 0x89 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x91 :
- return GRN_CHAR_OTHERS;
- break;
- case 0x92 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9A :
- if (str[3] < 0xA6) { return GRN_CHAR_ALPHA; }
- if (str[3] < 0xA8) { return GRN_CHAR_OTHERS; }
- return GRN_CHAR_ALPHA;
- break;
- case 0x9B :
- switch (str[3]) {
- case 0x80 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x81 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- return GRN_CHAR_ALPHA;
- break;
- case 0x9B :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- case 0xB5 :
- case 0xB6 :
- case 0xB7 :
- case 0xB8 :
- case 0xB9 :
- case 0xBA :
- return GRN_CHAR_ALPHA;
- break;
- case 0xBB :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xBC :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x9C :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x95 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- case 0xAF :
- case 0xB0 :
- case 0xB1 :
- case 0xB2 :
- case 0xB3 :
- case 0xB4 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xB5 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB6 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x9D :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8F :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- case 0xAA :
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- return GRN_CHAR_ALPHA;
- break;
- case 0xAF :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xB0 :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x9E :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- case 0x83 :
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x89 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x8A :
- case 0x8B :
- case 0x8C :
- case 0x8D :
- case 0x8E :
- case 0x8F :
- case 0x90 :
- case 0x91 :
- case 0x92 :
- case 0x93 :
- case 0x94 :
- case 0x95 :
- case 0x96 :
- case 0x97 :
- case 0x98 :
- case 0x99 :
- case 0x9A :
- case 0x9B :
- case 0x9C :
- case 0x9D :
- case 0x9E :
- case 0x9F :
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- return GRN_CHAR_ALPHA;
- break;
- case 0xA9 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0xAA :
- default :
- return GRN_CHAR_ALPHA;
- break;
- }
- break;
- case 0x9F :
- switch (str[3]) {
- case 0x80 :
- case 0x81 :
- case 0x82 :
- return GRN_CHAR_ALPHA;
- break;
- case 0x83 :
- return GRN_CHAR_SYMBOL;
- break;
- case 0x84 :
- case 0x85 :
- case 0x86 :
- case 0x87 :
- case 0x88 :
- case 0x89 :
- case 0x8A :
- case 0x8B :
- return GRN_CHAR_ALPHA;
- break;
- case 0x8C :
- case 0x8D :
- return GRN_CHAR_OTHERS;
- break;
- case 0x8E :
- default :
- return GRN_CHAR_DIGIT;
- break;
- }
- break;
- case 0xA0 :
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
- case 0x9E :
- case 0x9F :
- return GRN_CHAR_OTHERS;
- break;
- case 0xA0 :
- case 0xA1 :
- case 0xA2 :
- case 0xA3 :
- case 0xA4 :
- case 0xA5 :
- case 0xA6 :
- case 0xA7 :
- case 0xA8 :
- case 0xA9 :
- return GRN_CHAR_KANJI;
- break;
- case 0xAA :
- if (str[2] < 0x9B) { return GRN_CHAR_KANJI; }
- if (str[2] == 0x9B) {
- if (str[3] < 0xA0) { return GRN_CHAR_KANJI; }
- return GRN_CHAR_OTHERS;
- }
- return GRN_CHAR_OTHERS;
- break;
- case 0xAB :
- case 0xAC :
- case 0xAD :
- case 0xAE :
- return GRN_CHAR_OTHERS;
- break;
- case 0xAF :
- if (str[2] < 0xA0) { return GRN_CHAR_OTHERS; }
- if (str[2] < 0xA8) { return GRN_CHAR_KANJI; }
- if (str[2] == 0xA8) {
- if (str[3] < 0xA0) { return GRN_CHAR_KANJI; }
- return GRN_CHAR_OTHERS;
- }
- return GRN_CHAR_OTHERS;
- break;
- default :
- return GRN_CHAR_OTHERS;
- break;
- }
- break;
-default :
- return GRN_CHAR_OTHERS;
- break;
-}
- return -1;
+ return grn_nfkc50_char_type(utf8);
}
const char *
-grn_nfkc_map1(const unsigned char *str)
+grn_nfkc_decompose(const unsigned char *utf8)
{
-switch (str[0]) {
-case 0x41 :
- return "\x61";
- break;
-case 0x42 :
- return "\x62";
- break;
-case 0x43 :
- return "\x63";
- break;
-case 0x44 :
- return "\x64";
- break;
-case 0x45 :
- return "\x65";
- break;
-case 0x46 :
- return "\x66";
- break;
-case 0x47 :
- return "\x67";
- break;
-case 0x48 :
- return "\x68";
- break;
-case 0x49 :
- return "\x69";
- break;
-case 0x4A :
- return "\x6A";
- break;
-case 0x4B :
- return "\x6B";
- break;
-case 0x4C :
- return "\x6C";
- break;
-case 0x4D :
- return "\x6D";
- break;
-case 0x4E :
- return "\x6E";
- break;
-case 0x4F :
- return "\x6F";
- break;
-case 0x50 :
- return "\x70";
- break;
-case 0x51 :
- return "\x71";
- break;
-case 0x52 :
- return "\x72";
- break;
-case 0x53 :
- return "\x73";
- break;
-case 0x54 :
- return "\x74";
- break;
-case 0x55 :
- return "\x75";
- break;
-case 0x56 :
- return "\x76";
- break;
-case 0x57 :
- return "\x77";
- break;
-case 0x58 :
- return "\x78";
- break;
-case 0x59 :
- return "\x79";
- break;
-case 0x5A :
- return "\x7A";
- break;
-case 0xC2 :
- switch (str[1]) {
- case 0xA0 :
- return "\x20";
- break;
- case 0xA8 :
- return "\xCC\x88";
- break;
- case 0xAA :
- return "\x61";
- break;
- case 0xAF :
- return "\xCC\x84";
- break;
- case 0xB2 :
- return "\x32";
- break;
- case 0xB3 :
- return "\x33";
- break;
- case 0xB4 :
- return "\xCC\x81";
- break;
- case 0xB5 :
- return "\xCE\xBC";
- break;
- case 0xB8 :
- return "\xCC\xA7";
- break;
- case 0xB9 :
- return "\x31";
- break;
- case 0xBA :
- return "\x6F";
- break;
- case 0xBC :
- return "\x31\xE2\x81\x84\x34";
- break;
- case 0xBD :
- return "\x31\xE2\x81\x84\x32";
- break;
- case 0xBE :
- return "\x33\xE2\x81\x84\x34";
- break;
- }
- break;
-case 0xC3 :
- switch (str[1]) {
- case 0x80 :
- return "\xC3\xA0";
- break;
- case 0x81 :
- return "\xC3\xA1";
- break;
- case 0x82 :
- return "\xC3\xA2";
- break;
- case 0x83 :
- return "\xC3\xA3";
- break;
- case 0x84 :
- return "\xC3\xA4";
- break;
- case 0x85 :
- return "\xC3\xA5";
- break;
- case 0x87 :
- return "\xC3\xA7";
- break;
- case 0x88 :
- return "\xC3\xA8";
- break;
- case 0x89 :
- return "\xC3\xA9";
- break;
- case 0x8A :
- return "\xC3\xAA";
- break;
- case 0x8B :
- return "\xC3\xAB";
- break;
- case 0x8C :
- return "\xC3\xAC";
- break;
- case 0x8D :
- return "\xC3\xAD";
- break;
- case 0x8E :
- return "\xC3\xAE";
- break;
- case 0x8F :
- return "\xC3\xAF";
- break;
- case 0x91 :
- return "\xC3\xB1";
- break;
- case 0x92 :
- return "\xC3\xB2";
- break;
- case 0x93 :
- return "\xC3\xB3";
- break;
- case 0x94 :
- return "\xC3\xB4";
- break;
- case 0x95 :
- return "\xC3\xB5";
- break;
- case 0x96 :
- return "\xC3\xB6";
- break;
- case 0x99 :
- return "\xC3\xB9";
- break;
- case 0x9A :
- return "\xC3\xBA";
- break;
- case 0x9B :
- return "\xC3\xBB";
- break;
- case 0x9C :
- return "\xC3\xBC";
- break;
- case 0x9D :
- return "\xC3\xBD";
- break;
- }
- break;
-case 0xC4 :
- switch (str[1]) {
- case 0x80 :
- return "\xC4\x81";
- break;
- case 0x82 :
- return "\xC4\x83";
- break;
- case 0x84 :
- return "\xC4\x85";
- break;
- case 0x86 :
- return "\xC4\x87";
- break;
- case 0x88 :
- return "\xC4\x89";
- break;
- case 0x8A :
- return "\xC4\x8B";
- break;
- case 0x8C :
- return "\xC4\x8D";
- break;
- case 0x8E :
- return "\xC4\x8F";
- break;
- case 0x92 :
- return "\xC4\x93";
- break;
- case 0x94 :
- return "\xC4\x95";
- break;
- case 0x96 :
- return "\xC4\x97";
- break;
- case 0x98 :
- return "\xC4\x99";
- break;
- case 0x9A :
- return "\xC4\x9B";
- break;
- case 0x9C :
- return "\xC4\x9D";
- break;
- case 0x9E :
- return "\xC4\x9F";
- break;
- case 0xA0 :
- return "\xC4\xA1";
- break;
- case 0xA2 :
- return "\xC4\xA3";
- break;
- case 0xA4 :
- return "\xC4\xA5";
- break;
- case 0xA8 :
- return "\xC4\xA9";
- break;
- case 0xAA :
- return "\xC4\xAB";
- break;
- case 0xAC :
- return "\xC4\xAD";
- break;
- case 0xAE :
- return "\xC4\xAF";
- break;
- case 0xB0 :
- return "\x69\xCC\x87";
- break;
- case 0xB2 :
- return "\x69\x6A";
- break;
- case 0xB3 :
- return "\x69\x6A";
- break;
- case 0xB4 :
- return "\xC4\xB5";
- break;
- case 0xB6 :
- return "\xC4\xB7";
- break;
- case 0xB9 :
- return "\xC4\xBA";
- break;
- case 0xBB :
- return "\xC4\xBC";
- break;
- case 0xBD :
- return "\xC4\xBE";
- break;
- case 0xBF :
- return "\x6C\xC2\xB7";
- break;
- }
- break;
-case 0xC5 :
- switch (str[1]) {
- case 0x80 :
- return "\x6C\xC2\xB7";
- break;
- case 0x83 :
- return "\xC5\x84";
- break;
- case 0x85 :
- return "\xC5\x86";
- break;
- case 0x87 :
- return "\xC5\x88";
- break;
- case 0x89 :
- return "\xCA\xBC\x6E";
- break;
- case 0x8C :
- return "\xC5\x8D";
- break;
- case 0x8E :
- return "\xC5\x8F";
- break;
- case 0x90 :
- return "\xC5\x91";
- break;
- case 0x94 :
- return "\xC5\x95";
- break;
- case 0x96 :
- return "\xC5\x97";
- break;
- case 0x98 :
- return "\xC5\x99";
- break;
- case 0x9A :
- return "\xC5\x9B";
- break;
- case 0x9C :
- return "\xC5\x9D";
- break;
- case 0x9E :
- return "\xC5\x9F";
- break;
- case 0xA0 :
- return "\xC5\xA1";
- break;
- case 0xA2 :
- return "\xC5\xA3";
- break;
- case 0xA4 :
- return "\xC5\xA5";
- break;
- case 0xA8 :
- return "\xC5\xA9";
- break;
- case 0xAA :
- return "\xC5\xAB";
- break;
- case 0xAC :
- return "\xC5\xAD";
- break;
- case 0xAE :
- return "\xC5\xAF";
- break;
- case 0xB0 :
- return "\xC5\xB1";
- break;
- case 0xB2 :
- return "\xC5\xB3";
- break;
- case 0xB4 :
- return "\xC5\xB5";
- break;
- case 0xB6 :
- return "\xC5\xB7";
- break;
- case 0xB8 :
- return "\xC3\xBF";
- break;
- case 0xB9 :
- return "\xC5\xBA";
- break;
- case 0xBB :
- return "\xC5\xBC";
- break;
- case 0xBD :
- return "\xC5\xBE";
- break;
- case 0xBF :
- return "\x73";
- break;
- }
- break;
-case 0xC6 :
- switch (str[1]) {
- case 0xA0 :
- return "\xC6\xA1";
- break;
- case 0xAF :
- return "\xC6\xB0";
- break;
- }
- break;
-case 0xC7 :
- switch (str[1]) {
- case 0x84 :
- return "\x64\xC5\xBE";
- break;
- case 0x85 :
- return "\x64\xC5\xBE";
- break;
- case 0x86 :
- return "\x64\xC5\xBE";
- break;
- case 0x87 :
- return "\x6C\x6A";
- break;
- case 0x88 :
- return "\x6C\x6A";
- break;
- case 0x89 :
- return "\x6C\x6A";
- break;
- case 0x8A :
- return "\x6E\x6A";
- break;
- case 0x8B :
- return "\x6E\x6A";
- break;
- case 0x8C :
- return "\x6E\x6A";
- break;
- case 0x8D :
- return "\xC7\x8E";
- break;
- case 0x8F :
- return "\xC7\x90";
- break;
- case 0x91 :
- return "\xC7\x92";
- break;
- case 0x93 :
- return "\xC7\x94";
- break;
- case 0x95 :
- return "\xC7\x96";
- break;
- case 0x97 :
- return "\xC7\x98";
- break;
- case 0x99 :
- return "\xC7\x9A";
- break;
- case 0x9B :
- return "\xC7\x9C";
- break;
- case 0x9E :
- return "\xC7\x9F";
- break;
- case 0xA0 :
- return "\xC7\xA1";
- break;
- case 0xA6 :
- return "\xC7\xA7";
- break;
- case 0xA8 :
- return "\xC7\xA9";
- break;
- case 0xAA :
- return "\xC7\xAB";
- break;
- case 0xAC :
- return "\xC7\xAD";
- break;
- case 0xB1 :
- return "\x64\x7A";
- break;
- case 0xB2 :
- return "\x64\x7A";
- break;
- case 0xB3 :
- return "\x64\x7A";
- break;
- case 0xB4 :
- return "\xC7\xB5";
- break;
- case 0xB8 :
- return "\xC7\xB9";
- break;
- case 0xBA :
- return "\xC7\xBB";
- break;
- }
- break;
-case 0xC8 :
- switch (str[1]) {
- case 0x80 :
- return "\xC8\x81";
- break;
- case 0x82 :
- return "\xC8\x83";
- break;
- case 0x84 :
- return "\xC8\x85";
- break;
- case 0x86 :
- return "\xC8\x87";
- break;
- case 0x88 :
- return "\xC8\x89";
- break;
- case 0x8A :
- return "\xC8\x8B";
- break;
- case 0x8C :
- return "\xC8\x8D";
- break;
- case 0x8E :
- return "\xC8\x8F";
- break;
- case 0x90 :
- return "\xC8\x91";
- break;
- case 0x92 :
- return "\xC8\x93";
- break;
- case 0x94 :
- return "\xC8\x95";
- break;
- case 0x96 :
- return "\xC8\x97";
- break;
- case 0x98 :
- return "\xC8\x99";
- break;
- case 0x9A :
- return "\xC8\x9B";
- break;
- case 0x9E :
- return "\xC8\x9F";
- break;
- case 0xA6 :
- return "\xC8\xA7";
- break;
- case 0xA8 :
- return "\xC8\xA9";
- break;
- case 0xAA :
- return "\xC8\xAB";
- break;
- case 0xAC :
- return "\xC8\xAD";
- break;
- case 0xAE :
- return "\xC8\xAF";
- break;
- case 0xB0 :
- return "\xC8\xB1";
- break;
- case 0xB2 :
- return "\xC8\xB3";
- break;
- }
- break;
-case 0xCA :
- switch (str[1]) {
- case 0xB0 :
- return "\x68";
- break;
- case 0xB1 :
- return "\xC9\xA6";
- break;
- case 0xB2 :
- return "\x6A";
- break;
- case 0xB3 :
- return "\x72";
- break;
- case 0xB4 :
- return "\xC9\xB9";
- break;
- case 0xB5 :
- return "\xC9\xBB";
- break;
- case 0xB6 :
- return "\xCA\x81";
- break;
- case 0xB7 :
- return "\x77";
- break;
- case 0xB8 :
- return "\x79";
- break;
- }
- break;
-case 0xCB :
- switch (str[1]) {
- case 0x98 :
- return "\xCC\x86";
- break;
- case 0x99 :
- return "\xCC\x87";
- break;
- case 0x9A :
- return "\xCC\x8A";
- break;
- case 0x9B :
- return "\xCC\xA8";
- break;
- case 0x9C :
- return "\xCC\x83";
- break;
- case 0x9D :
- return "\xCC\x8B";
- break;
- case 0xA0 :
- return "\xC9\xA3";
- break;
- case 0xA1 :
- return "\x6C";
- break;
- case 0xA2 :
- return "\x73";
- break;
- case 0xA3 :
- return "\x78";
- break;
- case 0xA4 :
- return "\xCA\x95";
- break;
- }
- break;
-case 0xCD :
- switch (str[1]) {
- case 0x80 :
- return "\xCC\x80";
- break;
- case 0x81 :
- return "\xCC\x81";
- break;
- case 0x83 :
- return "\xCC\x93";
- break;
- case 0x84 :
- return "\xCC\x88\xCC\x81";
- break;
- case 0xB4 :
- return "\xCA\xB9";
- break;
- case 0xBA :
- return "\xCD\x85";
- break;
- case 0xBE :
- return "\x3B";
- break;
- }
- break;
-case 0xCE :
- switch (str[1]) {
- case 0x84 :
- return "\xCC\x81";
- break;
- case 0x85 :
- return "\xCC\x88\xCC\x81";
- break;
- case 0x87 :
- return "\xC2\xB7";
- break;
- }
- break;
-case 0xCF :
- switch (str[1]) {
- case 0x90 :
- return "\xCE\xB2";
- break;
- case 0x91 :
- return "\xCE\xB8";
- break;
- case 0x92 :
- return "\xCE\xA5";
- break;
- case 0x93 :
- return "\xCE\x8E";
- break;
- case 0x94 :
- return "\xCE\xAB";
- break;
- case 0x95 :
- return "\xCF\x86";
- break;
- case 0x96 :
- return "\xCF\x80";
- break;
- case 0xB0 :
- return "\xCE\xBA";
- break;
- case 0xB1 :
- return "\xCF\x81";
- break;
- case 0xB2 :
- return "\xCF\x82";
- break;
- case 0xB4 :
- return "\xCE\x98";
- break;
- case 0xB5 :
- return "\xCE\xB5";
- break;
- case 0xB9 :
- return "\xCE\xA3";
- break;
- }
- break;
-case 0xD6 :
- if (str[1] == 0x87) {
- return "\xD5\xA5\xD6\x82";
- }
- break;
-case 0xD9 :
- switch (str[1]) {
- case 0xB5 :
- return "\xD8\xA7\xD9\xB4";
- break;
- case 0xB6 :
- return "\xD9\x88\xD9\xB4";
- break;
- case 0xB7 :
- return "\xDB\x87\xD9\xB4";
- break;
- case 0xB8 :
- return "\xD9\x8A\xD9\xB4";
- break;
- }
- break;
-case 0xE0 :
- switch (str[1]) {
- case 0xA5 :
- switch (str[2]) {
- case 0x98 :
- return "\xE0\xA4\x95\xE0\xA4\xBC";
- break;
- case 0x99 :
- return "\xE0\xA4\x96\xE0\xA4\xBC";
- break;
- case 0x9A :
- return "\xE0\xA4\x97\xE0\xA4\xBC";
- break;
- case 0x9B :
- return "\xE0\xA4\x9C\xE0\xA4\xBC";
- break;
- case 0x9C :
- return "\xE0\xA4\xA1\xE0\xA4\xBC";
- break;
- case 0x9D :
- return "\xE0\xA4\xA2\xE0\xA4\xBC";
- break;
- case 0x9E :
- return "\xE0\xA4\xAB\xE0\xA4\xBC";
- break;
- case 0x9F :
- return "\xE0\xA4\xAF\xE0\xA4\xBC";
- break;
- }
- break;
- case 0xA7 :
- switch (str[2]) {
- case 0x9C :
- return "\xE0\xA6\xA1\xE0\xA6\xBC";
- break;
- case 0x9D :
- return "\xE0\xA6\xA2\xE0\xA6\xBC";
- break;
- case 0x9F :
- return "\xE0\xA6\xAF\xE0\xA6\xBC";
- break;
- }
- break;
- case 0xA8 :
- switch (str[2]) {
- case 0xB3 :
- return "\xE0\xA8\xB2\xE0\xA8\xBC";
- break;
- case 0xB6 :
- return "\xE0\xA8\xB8\xE0\xA8\xBC";
- break;
- }
- break;
- case 0xA9 :
- switch (str[2]) {
- case 0x99 :
- return "\xE0\xA8\x96\xE0\xA8\xBC";
- break;
- case 0x9A :
- return "\xE0\xA8\x97\xE0\xA8\xBC";
- break;
- case 0x9B :
- return "\xE0\xA8\x9C\xE0\xA8\xBC";
- break;
- case 0x9E :
- return "\xE0\xA8\xAB\xE0\xA8\xBC";
- break;
- }
- break;
- case 0xAD :
- switch (str[2]) {
- case 0x9C :
- return "\xE0\xAC\xA1\xE0\xAC\xBC";
- break;
- case 0x9D :
- return "\xE0\xAC\xA2\xE0\xAC\xBC";
- break;
- }
- break;
- case 0xB8 :
- if (str[2] == 0xB3) {
- return "\xE0\xB9\x8D\xE0\xB8\xB2";
- }
- break;
- case 0xBA :
- if (str[2] == 0xB3) {
- return "\xE0\xBB\x8D\xE0\xBA\xB2";
- }
- break;
- case 0xBB :
- switch (str[2]) {
- case 0x9C :
- return "\xE0\xBA\xAB\xE0\xBA\x99";
- break;
- case 0x9D :
- return "\xE0\xBA\xAB\xE0\xBA\xA1";
- break;
- }
- break;
- case 0xBC :
- if (str[2] == 0x8C) {
- return "\xE0\xBC\x8B";
- }
- break;
- case 0xBD :
- switch (str[2]) {
- case 0x83 :
- return "\xE0\xBD\x82\xE0\xBE\xB7";
- break;
- case 0x8D :
- return "\xE0\xBD\x8C\xE0\xBE\xB7";
- break;
- case 0x92 :
- return "\xE0\xBD\x91\xE0\xBE\xB7";
- break;
- case 0x97 :
- return "\xE0\xBD\x96\xE0\xBE\xB7";
- break;
- case 0x9C :
- return "\xE0\xBD\x9B\xE0\xBE\xB7";
- break;
- case 0xA9 :
- return "\xE0\xBD\x80\xE0\xBE\xB5";
- break;
- case 0xB3 :
- return "\xE0\xBD\xB1\xE0\xBD\xB2";
- break;
- case 0xB5 :
- return "\xE0\xBD\xB1\xE0\xBD\xB4";
- break;
- case 0xB6 :
- return "\xE0\xBE\xB2\xE0\xBE\x80";
- break;
- case 0xB7 :
- return "\xE0\xBE\xB2\xE0\xBD\xB1\xE0\xBE\x80";
- break;
- case 0xB8 :
- return "\xE0\xBE\xB3\xE0\xBE\x80";
- break;
- case 0xB9 :
- return "\xE0\xBE\xB3\xE0\xBD\xB1\xE0\xBE\x80";
- break;
- }
- break;
- case 0xBE :
- switch (str[2]) {
- case 0x81 :
- return "\xE0\xBD\xB1\xE0\xBE\x80";
- break;
- case 0x93 :
- return "\xE0\xBE\x92\xE0\xBE\xB7";
- break;
- case 0x9D :
- return "\xE0\xBE\x9C\xE0\xBE\xB7";
- break;
- case 0xA2 :
- return "\xE0\xBE\xA1\xE0\xBE\xB7";
- break;
- case 0xA7 :
- return "\xE0\xBE\xA6\xE0\xBE\xB7";
- break;
- case 0xAC :
- return "\xE0\xBE\xAB\xE0\xBE\xB7";
- break;
- case 0xB9 :
- return "\xE0\xBE\x90\xE0\xBE\xB5";
- break;
- }
- break;
- }
- break;
-case 0xE1 :
- switch (str[1]) {
- case 0x83 :
- if (str[2] == 0xBC) {
- return "\xE1\x83\x9C";
- }
- break;
- case 0xB4 :
- switch (str[2]) {
- case 0xAC :
- return "\x61";
- break;
- case 0xAD :
- return "\xC3\x86";
- break;
- case 0xAE :
- return "\x62";
- break;
- case 0xB0 :
- return "\x64";
- break;
- case 0xB1 :
- return "\x65";
- break;
- case 0xB2 :
- return "\xC6\x8E";
- break;
- case 0xB3 :
- return "\x67";
- break;
- case 0xB4 :
- return "\x68";
- break;
- case 0xB5 :
- return "\x69";
- break;
- case 0xB6 :
- return "\x6A";
- break;
- case 0xB7 :
- return "\x6B";
- break;
- case 0xB8 :
- return "\x6C";
- break;
- case 0xB9 :
- return "\x6D";
- break;
- case 0xBA :
- return "\x6E";
- break;
- case 0xBC :
- return "\x6F";
- break;
- case 0xBD :
- return "\xC8\xA2";
- break;
- case 0xBE :
- return "\x70";
- break;
- case 0xBF :
- return "\x72";
- break;
- }
- break;
- case 0xB5 :
- switch (str[2]) {
- case 0x80 :
- return "\x74";
- break;
- case 0x81 :
- return "\x75";
- break;
- case 0x82 :
- return "\x77";
- break;
- case 0x83 :
- return "\x61";
- break;
- case 0x84 :
- return "\xC9\x90";
- break;
- case 0x85 :
- return "\xC9\x91";
- break;
- case 0x86 :
- return "\xE1\xB4\x82";
- break;
- case 0x87 :
- return "\x62";
- break;
- case 0x88 :
- return "\x64";
- break;
- case 0x89 :
- return "\x65";
- break;
- case 0x8A :
- return "\xC9\x99";
- break;
- case 0x8B :
- return "\xC9\x9B";
- break;
- case 0x8C :
- return "\xC9\x9C";
- break;
- case 0x8D :
- return "\x67";
- break;
- case 0x8F :
- return "\x6B";
- break;
- case 0x90 :
- return "\x6D";
- break;
- case 0x91 :
- return "\xC5\x8B";
- break;
- case 0x92 :
- return "\x6F";
- break;
- case 0x93 :
- return "\xC9\x94";
- break;
- case 0x94 :
- return "\xE1\xB4\x96";
- break;
- case 0x95 :
- return "\xE1\xB4\x97";
- break;
- case 0x96 :
- return "\x70";
- break;
- case 0x97 :
- return "\x74";
- break;
- case 0x98 :
- return "\x75";
- break;
- case 0x99 :
- return "\xE1\xB4\x9D";
- break;
- case 0x9A :
- return "\xC9\xAF";
- break;
- case 0x9B :
- return "\x76";
- break;
- case 0x9C :
- return "\xE1\xB4\xA5";
- break;
- case 0x9D :
- return "\xCE\xB2";
- break;
- case 0x9E :
- return "\xCE\xB3";
- break;
- case 0x9F :
- return "\xCE\xB4";
- break;
- case 0xA0 :
- return "\xCF\x86";
- break;
- case 0xA1 :
- return "\xCF\x87";
- break;
- case 0xA2 :
- return "\x69";
- break;
- case 0xA3 :
- return "\x72";
- break;
- case 0xA4 :
- return "\x75";
- break;
- case 0xA5 :
- return "\x76";
- break;
- case 0xA6 :
- return "\xCE\xB2";
- break;
- case 0xA7 :
- return "\xCE\xB3";
- break;
- case 0xA8 :
- return "\xCF\x81";
- break;
- case 0xA9 :
- return "\xCF\x86";
- break;
- case 0xAA :
- return "\xCF\x87";
- break;
- case 0xB8 :
- return "\xD0\xBD";
- break;
- }
- break;
- case 0xB6 :
- switch (str[2]) {
- case 0x9B :
- return "\xC9\x92";
- break;
- case 0x9C :
- return "\x63";
- break;
- case 0x9D :
- return "\xC9\x95";
- break;
- case 0x9E :
- return "\xC3\xB0";
- break;
- case 0x9F :
- return "\xC9\x9C";
- break;
- case 0xA0 :
- return "\x66";
- break;
- case 0xA1 :
- return "\xC9\x9F";
- break;
- case 0xA2 :
- return "\xC9\xA1";
- break;
- case 0xA3 :
- return "\xC9\xA5";
- break;
- case 0xA4 :
- return "\xC9\xA8";
- break;
- case 0xA5 :
- return "\xC9\xA9";
- break;
- case 0xA6 :
- return "\xC9\xAA";
- break;
- case 0xA7 :
- return "\xE1\xB5\xBB";
- break;
- case 0xA8 :
- return "\xCA\x9D";
- break;
- case 0xA9 :
- return "\xC9\xAD";
- break;
- case 0xAA :
- return "\xE1\xB6\x85";
- break;
- case 0xAB :
- return "\xCA\x9F";
- break;
- case 0xAC :
- return "\xC9\xB1";
- break;
- case 0xAD :
- return "\xC9\xB0";
- break;
- case 0xAE :
- return "\xC9\xB2";
- break;
- case 0xAF :
- return "\xC9\xB3";
- break;
- case 0xB0 :
- return "\xC9\xB4";
- break;
- case 0xB1 :
- return "\xC9\xB5";
- break;
- case 0xB2 :
- return "\xC9\xB8";
- break;
- case 0xB3 :
- return "\xCA\x82";
- break;
- case 0xB4 :
- return "\xCA\x83";
- break;
- case 0xB5 :
- return "\xC6\xAB";
- break;
- case 0xB6 :
- return "\xCA\x89";
- break;
- case 0xB7 :
- return "\xCA\x8A";
- break;
- case 0xB8 :
- return "\xE1\xB4\x9C";
- break;
- case 0xB9 :
- return "\xCA\x8B";
- break;
- case 0xBA :
- return "\xCA\x8C";
- break;
- case 0xBB :
- return "\x7A";
- break;
- case 0xBC :
- return "\xCA\x90";
- break;
- case 0xBD :
- return "\xCA\x91";
- break;
- case 0xBE :
- return "\xCA\x92";
- break;
- case 0xBF :
- return "\xCE\xB8";
- break;
- }
- break;
- case 0xB8 :
- switch (str[2]) {
- case 0x80 :
- return "\xE1\xB8\x81";
- break;
- case 0x82 :
- return "\xE1\xB8\x83";
- break;
- case 0x84 :
- return "\xE1\xB8\x85";
- break;
- case 0x86 :
- return "\xE1\xB8\x87";
- break;
- case 0x88 :
- return "\xE1\xB8\x89";
- break;
- case 0x8A :
- return "\xE1\xB8\x8B";
- break;
- case 0x8C :
- return "\xE1\xB8\x8D";
- break;
- case 0x8E :
- return "\xE1\xB8\x8F";
- break;
- case 0x90 :
- return "\xE1\xB8\x91";
- break;
- case 0x92 :
- return "\xE1\xB8\x93";
- break;
- case 0x94 :
- return "\xE1\xB8\x95";
- break;
- case 0x96 :
- return "\xE1\xB8\x97";
- break;
- case 0x98 :
- return "\xE1\xB8\x99";
- break;
- case 0x9A :
- return "\xE1\xB8\x9B";
- break;
- case 0x9C :
- return "\xE1\xB8\x9D";
- break;
- case 0x9E :
- return "\xE1\xB8\x9F";
- break;
- case 0xA0 :
- return "\xE1\xB8\xA1";
- break;
- case 0xA2 :
- return "\xE1\xB8\xA3";
- break;
- case 0xA4 :
- return "\xE1\xB8\xA5";
- break;
- case 0xA6 :
- return "\xE1\xB8\xA7";
- break;
- case 0xA8 :
- return "\xE1\xB8\xA9";
- break;
- case 0xAA :
- return "\xE1\xB8\xAB";
- break;
- case 0xAC :
- return "\xE1\xB8\xAD";
- break;
- case 0xAE :
- return "\xE1\xB8\xAF";
- break;
- case 0xB0 :
- return "\xE1\xB8\xB1";
- break;
- case 0xB2 :
- return "\xE1\xB8\xB3";
- break;
- case 0xB4 :
- return "\xE1\xB8\xB5";
- break;
- case 0xB6 :
- return "\xE1\xB8\xB7";
- break;
- case 0xB8 :
- return "\xE1\xB8\xB9";
- break;
- case 0xBA :
- return "\xE1\xB8\xBB";
- break;
- case 0xBC :
- return "\xE1\xB8\xBD";
- break;
- case 0xBE :
- return "\xE1\xB8\xBF";
- break;
- }
- break;
- case 0xB9 :
- switch (str[2]) {
- case 0x80 :
- return "\xE1\xB9\x81";
- break;
- case 0x82 :
- return "\xE1\xB9\x83";
- break;
- case 0x84 :
- return "\xE1\xB9\x85";
- break;
- case 0x86 :
- return "\xE1\xB9\x87";
- break;
- case 0x88 :
- return "\xE1\xB9\x89";
- break;
- case 0x8A :
- return "\xE1\xB9\x8B";
- break;
- case 0x8C :
- return "\xE1\xB9\x8D";
- break;
- case 0x8E :
- return "\xE1\xB9\x8F";
- break;
- case 0x90 :
- return "\xE1\xB9\x91";
- break;
- case 0x92 :
- return "\xE1\xB9\x93";
- break;
- case 0x94 :
- return "\xE1\xB9\x95";
- break;
- case 0x96 :
- return "\xE1\xB9\x97";
- break;
- case 0x98 :
- return "\xE1\xB9\x99";
- break;
- case 0x9A :
- return "\xE1\xB9\x9B";
- break;
- case 0x9C :
- return "\xE1\xB9\x9D";
- break;
- case 0x9E :
- return "\xE1\xB9\x9F";
- break;
- case 0xA0 :
- return "\xE1\xB9\xA1";
- break;
- case 0xA2 :
- return "\xE1\xB9\xA3";
- break;
- case 0xA4 :
- return "\xE1\xB9\xA5";
- break;
- case 0xA6 :
- return "\xE1\xB9\xA7";
- break;
- case 0xA8 :
- return "\xE1\xB9\xA9";
- break;
- case 0xAA :
- return "\xE1\xB9\xAB";
- break;
- case 0xAC :
- return "\xE1\xB9\xAD";
- break;
- case 0xAE :
- return "\xE1\xB9\xAF";
- break;
- case 0xB0 :
- return "\xE1\xB9\xB1";
- break;
- case 0xB2 :
- return "\xE1\xB9\xB3";
- break;
- case 0xB4 :
- return "\xE1\xB9\xB5";
- break;
- case 0xB6 :
- return "\xE1\xB9\xB7";
- break;
- case 0xB8 :
- return "\xE1\xB9\xB9";
- break;
- case 0xBA :
- return "\xE1\xB9\xBB";
- break;
- case 0xBC :
- return "\xE1\xB9\xBD";
- break;
- case 0xBE :
- return "\xE1\xB9\xBF";
- break;
- }
- break;
- case 0xBA :
- switch (str[2]) {
- case 0x80 :
- return "\xE1\xBA\x81";
- break;
- case 0x82 :
- return "\xE1\xBA\x83";
- break;
- case 0x84 :
- return "\xE1\xBA\x85";
- break;
- case 0x86 :
- return "\xE1\xBA\x87";
- break;
- case 0x88 :
- return "\xE1\xBA\x89";
- break;
- case 0x8A :
- return "\xE1\xBA\x8B";
- break;
- case 0x8C :
- return "\xE1\xBA\x8D";
- break;
- case 0x8E :
- return "\xE1\xBA\x8F";
- break;
- case 0x90 :
- return "\xE1\xBA\x91";
- break;
- case 0x92 :
- return "\xE1\xBA\x93";
- break;
- case 0x94 :
- return "\xE1\xBA\x95";
- break;
- case 0x9A :
- return "\x61\xCA\xBE";
- break;
- case 0x9B :
- return "\xE1\xB9\xA1";
- break;
- case 0xA0 :
- return "\xE1\xBA\xA1";
- break;
- case 0xA2 :
- return "\xE1\xBA\xA3";
- break;
- case 0xA4 :
- return "\xE1\xBA\xA5";
- break;
- case 0xA6 :
- return "\xE1\xBA\xA7";
- break;
- case 0xA8 :
- return "\xE1\xBA\xA9";
- break;
- case 0xAA :
- return "\xE1\xBA\xAB";
- break;
- case 0xAC :
- return "\xE1\xBA\xAD";
- break;
- case 0xAE :
- return "\xE1\xBA\xAF";
- break;
- case 0xB0 :
- return "\xE1\xBA\xB1";
- break;
- case 0xB2 :
- return "\xE1\xBA\xB3";
- break;
- case 0xB4 :
- return "\xE1\xBA\xB5";
- break;
- case 0xB6 :
- return "\xE1\xBA\xB7";
- break;
- case 0xB8 :
- return "\xE1\xBA\xB9";
- break;
- case 0xBA :
- return "\xE1\xBA\xBB";
- break;
- case 0xBC :
- return "\xE1\xBA\xBD";
- break;
- case 0xBE :
- return "\xE1\xBA\xBF";
- break;
- }
- break;
- case 0xBB :
- switch (str[2]) {
- case 0x80 :
- return "\xE1\xBB\x81";
- break;
- case 0x82 :
- return "\xE1\xBB\x83";
- break;
- case 0x84 :
- return "\xE1\xBB\x85";
- break;
- case 0x86 :
- return "\xE1\xBB\x87";
- break;
- case 0x88 :
- return "\xE1\xBB\x89";
- break;
- case 0x8A :
- return "\xE1\xBB\x8B";
- break;
- case 0x8C :
- return "\xE1\xBB\x8D";
- break;
- case 0x8E :
- return "\xE1\xBB\x8F";
- break;
- case 0x90 :
- return "\xE1\xBB\x91";
- break;
- case 0x92 :
- return "\xE1\xBB\x93";
- break;
- case 0x94 :
- return "\xE1\xBB\x95";
- break;
- case 0x96 :
- return "\xE1\xBB\x97";
- break;
- case 0x98 :
- return "\xE1\xBB\x99";
- break;
- case 0x9A :
- return "\xE1\xBB\x9B";
- break;
- case 0x9C :
- return "\xE1\xBB\x9D";
- break;
- case 0x9E :
- return "\xE1\xBB\x9F";
- break;
- case 0xA0 :
- return "\xE1\xBB\xA1";
- break;
- case 0xA2 :
- return "\xE1\xBB\xA3";
- break;
- case 0xA4 :
- return "\xE1\xBB\xA5";
- break;
- case 0xA6 :
- return "\xE1\xBB\xA7";
- break;
- case 0xA8 :
- return "\xE1\xBB\xA9";
- break;
- case 0xAA :
- return "\xE1\xBB\xAB";
- break;
- case 0xAC :
- return "\xE1\xBB\xAD";
- break;
- case 0xAE :
- return "\xE1\xBB\xAF";
- break;
- case 0xB0 :
- return "\xE1\xBB\xB1";
- break;
- case 0xB2 :
- return "\xE1\xBB\xB3";
- break;
- case 0xB4 :
- return "\xE1\xBB\xB5";
- break;
- case 0xB6 :
- return "\xE1\xBB\xB7";
- break;
- case 0xB8 :
- return "\xE1\xBB\xB9";
- break;
- }
- break;
- case 0xBD :
- switch (str[2]) {
- case 0xB1 :
- return "\xCE\xAC";
- break;
- case 0xB3 :
- return "\xCE\xAD";
- break;
- case 0xB5 :
- return "\xCE\xAE";
- break;
- case 0xB7 :
- return "\xCE\xAF";
- break;
- case 0xB9 :
- return "\xCF\x8C";
- break;
- case 0xBB :
- return "\xCF\x8D";
- break;
- case 0xBD :
- return "\xCF\x8E";
- break;
- }
- break;
- case 0xBE :
- switch (str[2]) {
- case 0xBB :
- return "\xCE\x86";
- break;
- case 0xBD :
- return "\xCC\x93";
- break;
- case 0xBE :
- return "\xCE\xB9";
- break;
- case 0xBF :
- return "\xCC\x93";
- break;
- }
- break;
- case 0xBF :
- switch (str[2]) {
- case 0x80 :
- return "\xCD\x82";
- break;
- case 0x81 :
- return "\xCC\x88\xCD\x82";
- break;
- case 0x89 :
- return "\xCE\x88";
- break;
- case 0x8B :
- return "\xCE\x89";
- break;
- case 0x8D :
- return "\xCC\x93\xCC\x80";
- break;
- case 0x8E :
- return "\xCC\x93\xCC\x81";
- break;
- case 0x8F :
- return "\xCC\x93\xCD\x82";
- break;
- case 0x93 :
- return "\xCE\x90";
- break;
- case 0x9B :
- return "\xCE\x8A";
- break;
- case 0x9D :
- return "\xCC\x94\xCC\x80";
- break;
- case 0x9E :
- return "\xCC\x94\xCC\x81";
- break;
- case 0x9F :
- return "\xCC\x94\xCD\x82";
- break;
- case 0xA3 :
- return "\xCE\xB0";
- break;
- case 0xAB :
- return "\xCE\x8E";
- break;
- case 0xAD :
- return "\xCC\x88\xCC\x80";
- break;
- case 0xAE :
- return "\xCC\x88\xCC\x81";
- break;
- case 0xAF :
- return "\x60";
- break;
- case 0xB9 :
- return "\xCE\x8C";
- break;
- case 0xBB :
- return "\xCE\x8F";
- break;
- case 0xBD :
- return "\xCC\x81";
- break;
- case 0xBE :
- return "\xCC\x94";
- break;
- }
- break;
- }
- break;
-case 0xE2 :
- switch (str[1]) {
- case 0x80 :
- switch (str[2]) {
- case 0x80 :
- return "\x20";
- break;
- case 0x81 :
- return "\x20";
- break;
- case 0x82 :
- return "\x20";
- break;
- case 0x83 :
- return "\x20";
- break;
- case 0x84 :
- return "\x20";
- break;
- case 0x85 :
- return "\x20";
- break;
- case 0x86 :
- return "\x20";
- break;
- case 0x87 :
- return "\x20";
- break;
- case 0x88 :
- return "\x20";
- break;
- case 0x89 :
- return "\x20";
- break;
- case 0x8A :
- return "\x20";
- break;
- case 0x91 :
- return "\xE2\x80\x90";
- break;
- case 0x97 :
- return "\xCC\xB3";
- break;
- case 0xA4 :
- return "\x2E";
- break;
- case 0xA5 :
- return "\x2E\x2E";
- break;
- case 0xA6 :
- return "\x2E\x2E\x2E";
- break;
- case 0xAF :
- return "\x20";
- break;
- case 0xB3 :
- return "\xE2\x80\xB2\xE2\x80\xB2";
- break;
- case 0xB4 :
- return "\xE2\x80\xB2\xE2\x80\xB2\xE2\x80\xB2";
- break;
- case 0xB6 :
- return "\xE2\x80\xB5\xE2\x80\xB5";
- break;
- case 0xB7 :
- return "\xE2\x80\xB5\xE2\x80\xB5\xE2\x80\xB5";
- break;
- case 0xBC :
- return "\x21\x21";
- break;
- case 0xBE :
- return "\xCC\x85";
- break;
- }
- break;
- case 0x81 :
- switch (str[2]) {
- case 0x87 :
- return "\x3F\x3F";
- break;
- case 0x88 :
- return "\x3F\x21";
- break;
- case 0x89 :
- return "\x21\x3F";
- break;
- case 0x97 :
- return "\xE2\x80\xB2\xE2\x80\xB2\xE2\x80\xB2\xE2\x80\xB2";
- break;
- case 0x9F :
- return "\x20";
- break;
- case 0xB0 :
- return "\x30";
- break;
- case 0xB1 :
- return "\x69";
- break;
- case 0xB4 :
- return "\x34";
- break;
- case 0xB5 :
- return "\x35";
- break;
- case 0xB6 :
- return "\x36";
- break;
- case 0xB7 :
- return "\x37";
- break;
- case 0xB8 :
- return "\x38";
- break;
- case 0xB9 :
- return "\x39";
- break;
- case 0xBA :
- return "\x2B";
- break;
- case 0xBB :
- return "\xE2\x88\x92";
- break;
- case 0xBC :
- return "\x3D";
- break;
- case 0xBD :
- return "\x28";
- break;
- case 0xBE :
- return "\x29";
- break;
- case 0xBF :
- return "\x6E";
- break;
- }
- break;
- case 0x82 :
- switch (str[2]) {
- case 0x80 :
- return "\x30";
- break;
- case 0x81 :
- return "\x31";
- break;
- case 0x82 :
- return "\x32";
- break;
- case 0x83 :
- return "\x33";
- break;
- case 0x84 :
- return "\x34";
- break;
- case 0x85 :
- return "\x35";
- break;
- case 0x86 :
- return "\x36";
- break;
- case 0x87 :
- return "\x37";
- break;
- case 0x88 :
- return "\x38";
- break;
- case 0x89 :
- return "\x39";
- break;
- case 0x8A :
- return "\x2B";
- break;
- case 0x8B :
- return "\xE2\x88\x92";
- break;
- case 0x8C :
- return "\x3D";
- break;
- case 0x8D :
- return "\x28";
- break;
- case 0x8E :
- return "\x29";
- break;
- case 0x90 :
- return "\x61";
- break;
- case 0x91 :
- return "\x65";
- break;
- case 0x92 :
- return "\x6F";
- break;
- case 0x93 :
- return "\x78";
- break;
- case 0x94 :
- return "\xC9\x99";
- break;
- case 0xA8 :
- return "\x72\x73";
- break;
- }
- break;
- case 0x84 :
- switch (str[2]) {
- case 0x80 :
- return "\x61\x2F\x63";
- break;
- case 0x81 :
- return "\x61\x2F\x73";
- break;
- case 0x82 :
- return "\x63";
- break;
- case 0x83 :
- return "\xC2\xB0\x63";
- break;
- case 0x85 :
- return "\x63\x2F\x6F";
- break;
- case 0x86 :
- return "\x63\x2F\x75";
- break;
- case 0x87 :
- return "\xC6\x90";
- break;
- case 0x89 :
- return "\xC2\xB0\x66";
- break;
- case 0x8A :
- return "\x67";
- break;
- case 0x8B :
- return "\x68";
- break;
- case 0x8C :
- return "\x68";
- break;
- case 0x8D :
- return "\x68";
- break;
- case 0x8E :
- return "\x68";
- break;
- case 0x8F :
- return "\xC4\xA7";
- break;
- case 0x90 :
- return "\x69";
- break;
- case 0x91 :
- return "\x69";
- break;
- case 0x92 :
- return "\x6C";
- break;
- case 0x93 :
- return "\x6C";
- break;
- case 0x95 :
- return "\x6E";
- break;
- case 0x96 :
- return "\x6E\x6F";
- break;
- case 0x99 :
- return "\x70";
- break;
- case 0x9A :
- return "\x71";
- break;
- case 0x9B :
- return "\x72";
- break;
- case 0x9C :
- return "\x72";
- break;
- case 0x9D :
- return "\x72";
- break;
- case 0xA0 :
- return "\x73\x6D";
- break;
- case 0xA1 :
- return "\x74\x65\x6C";
- break;
- case 0xA2 :
- return "\x74\x6D";
- break;
- case 0xA4 :
- return "\x7A";
- break;
- case 0xA6 :
- return "\xCE\xA9";
- break;
- case 0xA8 :
- return "\x7A";
- break;
- case 0xAA :
- return "\x6B";
- break;
- case 0xAB :
- return "\xC3\xA5";
- break;
- case 0xAC :
- return "\x62";
- break;
- case 0xAD :
- return "\x63";
- break;
- case 0xAF :
- return "\x65";
- break;
- case 0xB0 :
- return "\x65";
- break;
- case 0xB1 :
- return "\x66";
- break;
- case 0xB3 :
- return "\x6D";
- break;
- case 0xB4 :
- return "\x6F";
- break;
- case 0xB5 :
- return "\xD7\x90";
- break;
- case 0xB6 :
- return "\xD7\x91";
- break;
- case 0xB7 :
- return "\xD7\x92";
- break;
- case 0xB8 :
- return "\xD7\x93";
- break;
- case 0xB9 :
- return "\x69";
- break;
- case 0xBB :
- return "\x66\x61\x78";
- break;
- case 0xBC :
- return "\xCF\x80";
- break;
- case 0xBD :
- return "\xCE\xB3";
- break;
- case 0xBE :
- return "\xCE\x93";
- break;
- case 0xBF :
- return "\xCE\xA0";
- break;
- }
- break;
- case 0x85 :
- switch (str[2]) {
- case 0x80 :
- return "\xE2\x88\x91";
- break;
- case 0x85 :
- return "\x64";
- break;
- case 0x86 :
- return "\x64";
- break;
- case 0x87 :
- return "\x65";
- break;
- case 0x88 :
- return "\x69";
- break;
- case 0x89 :
- return "\x6A";
- break;
- case 0x93 :
- return "\x31\xE2\x81\x84\x33";
- break;
- case 0x94 :
- return "\x32\xE2\x81\x84\x33";
- break;
- case 0x95 :
- return "\x31\xE2\x81\x84\x35";
- break;
- case 0x96 :
- return "\x32\xE2\x81\x84\x35";
- break;
- case 0x97 :
- return "\x33\xE2\x81\x84\x35";
- break;
- case 0x98 :
- return "\x34\xE2\x81\x84\x35";
- break;
- case 0x99 :
- return "\x31\xE2\x81\x84\x36";
- break;
- case 0x9A :
- return "\x35\xE2\x81\x84\x36";
- break;
- case 0x9B :
- return "\x31\xE2\x81\x84\x38";
- break;
- case 0x9C :
- return "\x33\xE2\x81\x84\x38";
- break;
- case 0x9D :
- return "\x35\xE2\x81\x84\x38";
- break;
- case 0x9E :
- return "\x37\xE2\x81\x84\x38";
- break;
- case 0x9F :
- return "\x31\xE2\x81\x84";
- break;
- case 0xA0 :
- return "\x69";
- break;
- case 0xA1 :
- return "\x69\x69";
- break;
- case 0xA2 :
- return "\x69\x69\x69";
- break;
- case 0xA3 :
- return "\x69\x76";
- break;
- case 0xA4 :
- return "\x76";
- break;
- case 0xA5 :
- return "\x76\x69";
- break;
- case 0xA6 :
- return "\x76\x69\x69";
- break;
- case 0xA7 :
- return "\x76\x69\x69\x69";
- break;
- case 0xA8 :
- return "\x69\x78";
- break;
- case 0xA9 :
- return "\x78";
- break;
- case 0xAA :
- return "\x78\x69";
- break;
- case 0xAB :
- return "\x78\x69\x69";
- break;
- case 0xAC :
- return "\x6C";
- break;
- case 0xAD :
- return "\x63";
- break;
- case 0xAE :
- return "\x64";
- break;
- case 0xAF :
- return "\x6D";
- break;
- case 0xB0 :
- return "\x69";
- break;
- case 0xB1 :
- return "\x69\x69";
- break;
- case 0xB2 :
- return "\x69\x69\x69";
- break;
- case 0xB3 :
- return "\x69\x76";
- break;
- case 0xB4 :
- return "\x76";
- break;
- case 0xB5 :
- return "\x76\x69";
- break;
- case 0xB6 :
- return "\x76\x69\x69";
- break;
- case 0xB7 :
- return "\x76\x69\x69\x69";
- break;
- case 0xB8 :
- return "\x69\x78";
- break;
- case 0xB9 :
- return "\x78";
- break;
- case 0xBA :
- return "\x78\x69";
- break;
- case 0xBB :
- return "\x78\x69\x69";
- break;
- case 0xBC :
- return "\x6C";
- break;
- case 0xBD :
- return "\x63";
- break;
- case 0xBE :
- return "\x64";
- break;
- case 0xBF :
- return "\x6D";
- break;
- }
- break;
- case 0x88 :
- switch (str[2]) {
- case 0xAC :
- return "\xE2\x88\xAB\xE2\x88\xAB";
- break;
- case 0xAD :
- return "\xE2\x88\xAB\xE2\x88\xAB\xE2\x88\xAB";
- break;
- case 0xAF :
- return "\xE2\x88\xAE\xE2\x88\xAE";
- break;
- case 0xB0 :
- return "\xE2\x88\xAE\xE2\x88\xAE\xE2\x88\xAE";
- break;
- }
- break;
- case 0x8C :
- switch (str[2]) {
- case 0xA9 :
- return "\xE3\x80\x88";
- break;
- case 0xAA :
- return "\xE3\x80\x89";
- break;
- }
- break;
- case 0x91 :
- switch (str[2]) {
- case 0xA0 :
- return "\x31";
- break;
- case 0xA1 :
- return "\x32";
- break;
- case 0xA2 :
- return "\x33";
- break;
- case 0xA3 :
- return "\x34";
- break;
- case 0xA4 :
- return "\x35";
- break;
- case 0xA5 :
- return "\x36";
- break;
- case 0xA6 :
- return "\x37";
- break;
- case 0xA7 :
- return "\x38";
- break;
- case 0xA8 :
- return "\x39";
- break;
- case 0xA9 :
- return "\x31\x30";
- break;
- case 0xAA :
- return "\x31\x31";
- break;
- case 0xAB :
- return "\x31\x32";
- break;
- case 0xAC :
- return "\x31\x33";
- break;
- case 0xAD :
- return "\x31\x34";
- break;
- case 0xAE :
- return "\x31\x35";
- break;
- case 0xAF :
- return "\x31\x36";
- break;
- case 0xB0 :
- return "\x31\x37";
- break;
- case 0xB1 :
- return "\x31\x38";
- break;
- case 0xB2 :
- return "\x31\x39";
- break;
- case 0xB3 :
- return "\x32\x30";
- break;
- case 0xB4 :
- return "\x28\x31\x29";
- break;
- case 0xB5 :
- return "\x28\x32\x29";
- break;
- case 0xB6 :
- return "\x28\x33\x29";
- break;
- case 0xB7 :
- return "\x28\x34\x29";
- break;
- case 0xB8 :
- return "\x28\x35\x29";
- break;
- case 0xB9 :
- return "\x28\x36\x29";
- break;
- case 0xBA :
- return "\x28\x37\x29";
- break;
- case 0xBB :
- return "\x28\x38\x29";
- break;
- case 0xBC :
- return "\x28\x39\x29";
- break;
- case 0xBD :
- return "\x28\x31\x30\x29";
- break;
- case 0xBE :
- return "\x28\x31\x31\x29";
- break;
- case 0xBF :
- return "\x28\x31\x32\x29";
- break;
- }
- break;
- case 0x92 :
- switch (str[2]) {
- case 0x80 :
- return "\x28\x31\x33\x29";
- break;
- case 0x81 :
- return "\x28\x31\x34\x29";
- break;
- case 0x82 :
- return "\x28\x31\x35\x29";
- break;
- case 0x83 :
- return "\x28\x31\x36\x29";
- break;
- case 0x84 :
- return "\x28\x31\x37\x29";
- break;
- case 0x85 :
- return "\x28\x31\x38\x29";
- break;
- case 0x86 :
- return "\x28\x31\x39\x29";
- break;
- case 0x87 :
- return "\x28\x32\x30\x29";
- break;
- case 0x88 :
- return "\x31\x2E";
- break;
- case 0x89 :
- return "\x32\x2E";
- break;
- case 0x8A :
- return "\x33\x2E";
- break;
- case 0x8B :
- return "\x34\x2E";
- break;
- case 0x8C :
- return "\x35\x2E";
- break;
- case 0x8D :
- return "\x36\x2E";
- break;
- case 0x8E :
- return "\x37\x2E";
- break;
- case 0x8F :
- return "\x38\x2E";
- break;
- case 0x90 :
- return "\x39\x2E";
- break;
- case 0x91 :
- return "\x31\x30\x2E";
- break;
- case 0x92 :
- return "\x31\x31\x2E";
- break;
- case 0x93 :
- return "\x31\x32\x2E";
- break;
- case 0x94 :
- return "\x31\x33\x2E";
- break;
- case 0x95 :
- return "\x31\x34\x2E";
- break;
- case 0x96 :
- return "\x31\x35\x2E";
- break;
- case 0x97 :
- return "\x31\x36\x2E";
- break;
- case 0x98 :
- return "\x31\x37\x2E";
- break;
- case 0x99 :
- return "\x31\x38\x2E";
- break;
- case 0x9A :
- return "\x31\x39\x2E";
- break;
- case 0x9B :
- return "\x32\x30\x2E";
- break;
- case 0x9C :
- return "\x28\x61\x29";
- break;
- case 0x9D :
- return "\x28\x62\x29";
- break;
- case 0x9E :
- return "\x28\x63\x29";
- break;
- case 0x9F :
- return "\x28\x64\x29";
- break;
- case 0xA0 :
- return "\x28\x65\x29";
- break;
- case 0xA1 :
- return "\x28\x66\x29";
- break;
- case 0xA2 :
- return "\x28\x67\x29";
- break;
- case 0xA3 :
- return "\x28\x68\x29";
- break;
- case 0xA4 :
- return "\x28\x69\x29";
- break;
- case 0xA5 :
- return "\x28\x6A\x29";
- break;
- case 0xA6 :
- return "\x28\x6B\x29";
- break;
- case 0xA7 :
- return "\x28\x6C\x29";
- break;
- case 0xA8 :
- return "\x28\x6D\x29";
- break;
- case 0xA9 :
- return "\x28\x6E\x29";
- break;
- case 0xAA :
- return "\x28\x6F\x29";
- break;
- case 0xAB :
- return "\x28\x70\x29";
- break;
- case 0xAC :
- return "\x28\x71\x29";
- break;
- case 0xAD :
- return "\x28\x72\x29";
- break;
- case 0xAE :
- return "\x28\x73\x29";
- break;
- case 0xAF :
- return "\x28\x74\x29";
- break;
- case 0xB0 :
- return "\x28\x75\x29";
- break;
- case 0xB1 :
- return "\x28\x76\x29";
- break;
- case 0xB2 :
- return "\x28\x77\x29";
- break;
- case 0xB3 :
- return "\x28\x78\x29";
- break;
- case 0xB4 :
- return "\x28\x79\x29";
- break;
- case 0xB5 :
- return "\x28\x7A\x29";
- break;
- case 0xB6 :
- return "\x61";
- break;
- case 0xB7 :
- return "\x62";
- break;
- case 0xB8 :
- return "\x63";
- break;
- case 0xB9 :
- return "\x64";
- break;
- case 0xBA :
- return "\x65";
- break;
- case 0xBB :
- return "\x66";
- break;
- case 0xBC :
- return "\x67";
- break;
- case 0xBD :
- return "\x68";
- break;
- case 0xBE :
- return "\x69";
- break;
- case 0xBF :
- return "\x6A";
- break;
- }
- break;
- case 0x93 :
- switch (str[2]) {
- case 0x80 :
- return "\x6B";
- break;
- case 0x81 :
- return "\x6C";
- break;
- case 0x82 :
- return "\x6D";
- break;
- case 0x83 :
- return "\x6E";
- break;
- case 0x84 :
- return "\x6F";
- break;
- case 0x85 :
- return "\x70";
- break;
- case 0x86 :
- return "\x71";
- break;
- case 0x87 :
- return "\x72";
- break;
- case 0x88 :
- return "\x73";
- break;
- case 0x89 :
- return "\x74";
- break;
- case 0x8A :
- return "\x75";
- break;
- case 0x8B :
- return "\x76";
- break;
- case 0x8C :
- return "\x77";
- break;
- case 0x8D :
- return "\x78";
- break;
- case 0x8E :
- return "\x79";
- break;
- case 0x8F :
- return "\x7A";
- break;
- case 0x90 :
- return "\x61";
- break;
- case 0x91 :
- return "\x62";
- break;
- case 0x92 :
- return "\x63";
- break;
- case 0x93 :
- return "\x64";
- break;
- case 0x94 :
- return "\x65";
- break;
- case 0x95 :
- return "\x66";
- break;
- case 0x96 :
- return "\x67";
- break;
- case 0x97 :
- return "\x68";
- break;
- case 0x98 :
- return "\x69";
- break;
- case 0x99 :
- return "\x6A";
- break;
- case 0x9A :
- return "\x6B";
- break;
- case 0x9B :
- return "\x6C";
- break;
- case 0x9C :
- return "\x6D";
- break;
- case 0x9D :
- return "\x6E";
- break;
- case 0x9E :
- return "\x6F";
- break;
- case 0x9F :
- return "\x70";
- break;
- case 0xA0 :
- return "\x71";
- break;
- case 0xA1 :
- return "\x72";
- break;
- case 0xA2 :
- return "\x73";
- break;
- case 0xA3 :
- return "\x74";
- break;
- case 0xA4 :
- return "\x75";
- break;
- case 0xA5 :
- return "\x76";
- break;
- case 0xA6 :
- return "\x77";
- break;
- case 0xA7 :
- return "\x78";
- break;
- case 0xA8 :
- return "\x79";
- break;
- case 0xA9 :
- return "\x7A";
- break;
- case 0xAA :
- return "\x30";
- break;
- }
- break;
- case 0xA8 :
- if (str[2] == 0x8C) {
- return "\xE2\x88\xAB\xE2\x88\xAB\xE2\x88\xAB\xE2\x88\xAB";
- }
- break;
- case 0xA9 :
- switch (str[2]) {
- case 0xB4 :
- return "\x3A\x3A\x3D";
- break;
- case 0xB5 :
- return "\x3D\x3D";
- break;
- case 0xB6 :
- return "\x3D\x3D\x3D";
- break;
- }
- break;
- case 0xAB :
- if (str[2] == 0x9C) {
- return "\xE2\xAB\x9D\xCC\xB8";
- }
- break;
- case 0xB5 :
- if (str[2] == 0xAF) {
- return "\xE2\xB5\xA1";
- }
- break;
- case 0xBA :
- if (str[2] == 0x9F) {
- return "\xE6\xAF\x8D";
- }
- break;
- case 0xBB :
- if (str[2] == 0xB3) {
- return "\xE9\xBE\x9F";
- }
- break;
- case 0xBC :
- switch (str[2]) {
- case 0x80 :
- return "\xE4\xB8\x80";
- break;
- case 0x81 :
- return "\xE4\xB8\xA8";
- break;
- case 0x82 :
- return "\xE4\xB8\xB6";
- break;
- case 0x83 :
- return "\xE4\xB8\xBF";
- break;
- case 0x84 :
- return "\xE4\xB9\x99";
- break;
- case 0x85 :
- return "\xE4\xBA\x85";
- break;
- case 0x86 :
- return "\xE4\xBA\x8C";
- break;
- case 0x87 :
- return "\xE4\xBA\xA0";
- break;
- case 0x88 :
- return "\xE4\xBA\xBA";
- break;
- case 0x89 :
- return "\xE5\x84\xBF";
- break;
- case 0x8A :
- return "\xE5\x85\xA5";
- break;
- case 0x8B :
- return "\xE5\x85\xAB";
- break;
- case 0x8C :
- return "\xE5\x86\x82";
- break;
- case 0x8D :
- return "\xE5\x86\x96";
- break;
- case 0x8E :
- return "\xE5\x86\xAB";
- break;
- case 0x8F :
- return "\xE5\x87\xA0";
- break;
- case 0x90 :
- return "\xE5\x87\xB5";
- break;
- case 0x91 :
- return "\xE5\x88\x80";
- break;
- case 0x92 :
- return "\xE5\x8A\x9B";
- break;
- case 0x93 :
- return "\xE5\x8B\xB9";
- break;
- case 0x94 :
- return "\xE5\x8C\x95";
- break;
- case 0x95 :
- return "\xE5\x8C\x9A";
- break;
- case 0x96 :
- return "\xE5\x8C\xB8";
- break;
- case 0x97 :
- return "\xE5\x8D\x81";
- break;
- case 0x98 :
- return "\xE5\x8D\x9C";
- break;
- case 0x99 :
- return "\xE5\x8D\xA9";
- break;
- case 0x9A :
- return "\xE5\x8E\x82";
- break;
- case 0x9B :
- return "\xE5\x8E\xB6";
- break;
- case 0x9C :
- return "\xE5\x8F\x88";
- break;
- case 0x9D :
- return "\xE5\x8F\xA3";
- break;
- case 0x9E :
- return "\xE5\x9B\x97";
- break;
- case 0x9F :
- return "\xE5\x9C\x9F";
- break;
- case 0xA0 :
- return "\xE5\xA3\xAB";
- break;
- case 0xA1 :
- return "\xE5\xA4\x82";
- break;
- case 0xA2 :
- return "\xE5\xA4\x8A";
- break;
- case 0xA3 :
- return "\xE5\xA4\x95";
- break;
- case 0xA4 :
- return "\xE5\xA4\xA7";
- break;
- case 0xA5 :
- return "\xE5\xA5\xB3";
- break;
- case 0xA6 :
- return "\xE5\xAD\x90";
- break;
- case 0xA7 :
- return "\xE5\xAE\x80";
- break;
- case 0xA8 :
- return "\xE5\xAF\xB8";
- break;
- case 0xA9 :
- return "\xE5\xB0\x8F";
- break;
- case 0xAA :
- return "\xE5\xB0\xA2";
- break;
- case 0xAB :
- return "\xE5\xB0\xB8";
- break;
- case 0xAC :
- return "\xE5\xB1\xAE";
- break;
- case 0xAD :
- return "\xE5\xB1\xB1";
- break;
- case 0xAE :
- return "\xE5\xB7\x9B";
- break;
- case 0xAF :
- return "\xE5\xB7\xA5";
- break;
- case 0xB0 :
- return "\xE5\xB7\xB1";
- break;
- case 0xB1 :
- return "\xE5\xB7\xBE";
- break;
- case 0xB2 :
- return "\xE5\xB9\xB2";
- break;
- case 0xB3 :
- return "\xE5\xB9\xBA";
- break;
- case 0xB4 :
- return "\xE5\xB9\xBF";
- break;
- case 0xB5 :
- return "\xE5\xBB\xB4";
- break;
- case 0xB6 :
- return "\xE5\xBB\xBE";
- break;
- case 0xB7 :
- return "\xE5\xBC\x8B";
- break;
- case 0xB8 :
- return "\xE5\xBC\x93";
- break;
- case 0xB9 :
- return "\xE5\xBD\x90";
- break;
- case 0xBA :
- return "\xE5\xBD\xA1";
- break;
- case 0xBB :
- return "\xE5\xBD\xB3";
- break;
- case 0xBC :
- return "\xE5\xBF\x83";
- break;
- case 0xBD :
- return "\xE6\x88\x88";
- break;
- case 0xBE :
- return "\xE6\x88\xB6";
- break;
- case 0xBF :
- return "\xE6\x89\x8B";
- break;
- }
- break;
- case 0xBD :
- switch (str[2]) {
- case 0x80 :
- return "\xE6\x94\xAF";
- break;
- case 0x81 :
- return "\xE6\x94\xB4";
- break;
- case 0x82 :
- return "\xE6\x96\x87";
- break;
- case 0x83 :
- return "\xE6\x96\x97";
- break;
- case 0x84 :
- return "\xE6\x96\xA4";
- break;
- case 0x85 :
- return "\xE6\x96\xB9";
- break;
- case 0x86 :
- return "\xE6\x97\xA0";
- break;
- case 0x87 :
- return "\xE6\x97\xA5";
- break;
- case 0x88 :
- return "\xE6\x9B\xB0";
- break;
- case 0x89 :
- return "\xE6\x9C\x88";
- break;
- case 0x8A :
- return "\xE6\x9C\xA8";
- break;
- case 0x8B :
- return "\xE6\xAC\xA0";
- break;
- case 0x8C :
- return "\xE6\xAD\xA2";
- break;
- case 0x8D :
- return "\xE6\xAD\xB9";
- break;
- case 0x8E :
- return "\xE6\xAE\xB3";
- break;
- case 0x8F :
- return "\xE6\xAF\x8B";
- break;
- case 0x90 :
- return "\xE6\xAF\x94";
- break;
- case 0x91 :
- return "\xE6\xAF\x9B";
- break;
- case 0x92 :
- return "\xE6\xB0\x8F";
- break;
- case 0x93 :
- return "\xE6\xB0\x94";
- break;
- case 0x94 :
- return "\xE6\xB0\xB4";
- break;
- case 0x95 :
- return "\xE7\x81\xAB";
- break;
- case 0x96 :
- return "\xE7\x88\xAA";
- break;
- case 0x97 :
- return "\xE7\x88\xB6";
- break;
- case 0x98 :
- return "\xE7\x88\xBB";
- break;
- case 0x99 :
- return "\xE7\x88\xBF";
- break;
- case 0x9A :
- return "\xE7\x89\x87";
- break;
- case 0x9B :
- return "\xE7\x89\x99";
- break;
- case 0x9C :
- return "\xE7\x89\x9B";
- break;
- case 0x9D :
- return "\xE7\x8A\xAC";
- break;
- case 0x9E :
- return "\xE7\x8E\x84";
- break;
- case 0x9F :
- return "\xE7\x8E\x89";
- break;
- case 0xA0 :
- return "\xE7\x93\x9C";
- break;
- case 0xA1 :
- return "\xE7\x93\xA6";
- break;
- case 0xA2 :
- return "\xE7\x94\x98";
- break;
- case 0xA3 :
- return "\xE7\x94\x9F";
- break;
- case 0xA4 :
- return "\xE7\x94\xA8";
- break;
- case 0xA5 :
- return "\xE7\x94\xB0";
- break;
- case 0xA6 :
- return "\xE7\x96\x8B";
- break;
- case 0xA7 :
- return "\xE7\x96\x92";
- break;
- case 0xA8 :
- return "\xE7\x99\xB6";
- break;
- case 0xA9 :
- return "\xE7\x99\xBD";
- break;
- case 0xAA :
- return "\xE7\x9A\xAE";
- break;
- case 0xAB :
- return "\xE7\x9A\xBF";
- break;
- case 0xAC :
- return "\xE7\x9B\xAE";
- break;
- case 0xAD :
- return "\xE7\x9F\x9B";
- break;
- case 0xAE :
- return "\xE7\x9F\xA2";
- break;
- case 0xAF :
- return "\xE7\x9F\xB3";
- break;
- case 0xB0 :
- return "\xE7\xA4\xBA";
- break;
- case 0xB1 :
- return "\xE7\xA6\xB8";
- break;
- case 0xB2 :
- return "\xE7\xA6\xBE";
- break;
- case 0xB3 :
- return "\xE7\xA9\xB4";
- break;
- case 0xB4 :
- return "\xE7\xAB\x8B";
- break;
- case 0xB5 :
- return "\xE7\xAB\xB9";
- break;
- case 0xB6 :
- return "\xE7\xB1\xB3";
- break;
- case 0xB7 :
- return "\xE7\xB3\xB8";
- break;
- case 0xB8 :
- return "\xE7\xBC\xB6";
- break;
- case 0xB9 :
- return "\xE7\xBD\x91";
- break;
- case 0xBA :
- return "\xE7\xBE\x8A";
- break;
- case 0xBB :
- return "\xE7\xBE\xBD";
- break;
- case 0xBC :
- return "\xE8\x80\x81";
- break;
- case 0xBD :
- return "\xE8\x80\x8C";
- break;
- case 0xBE :
- return "\xE8\x80\x92";
- break;
- case 0xBF :
- return "\xE8\x80\xB3";
- break;
- }
- break;
- case 0xBE :
- switch (str[2]) {
- case 0x80 :
- return "\xE8\x81\xBF";
- break;
- case 0x81 :
- return "\xE8\x82\x89";
- break;
- case 0x82 :
- return "\xE8\x87\xA3";
- break;
- case 0x83 :
- return "\xE8\x87\xAA";
- break;
- case 0x84 :
- return "\xE8\x87\xB3";
- break;
- case 0x85 :
- return "\xE8\x87\xBC";
- break;
- case 0x86 :
- return "\xE8\x88\x8C";
- break;
- case 0x87 :
- return "\xE8\x88\x9B";
- break;
- case 0x88 :
- return "\xE8\x88\x9F";
- break;
- case 0x89 :
- return "\xE8\x89\xAE";
- break;
- case 0x8A :
- return "\xE8\x89\xB2";
- break;
- case 0x8B :
- return "\xE8\x89\xB8";
- break;
- case 0x8C :
- return "\xE8\x99\x8D";
- break;
- case 0x8D :
- return "\xE8\x99\xAB";
- break;
- case 0x8E :
- return "\xE8\xA1\x80";
- break;
- case 0x8F :
- return "\xE8\xA1\x8C";
- break;
- case 0x90 :
- return "\xE8\xA1\xA3";
- break;
- case 0x91 :
- return "\xE8\xA5\xBE";
- break;
- case 0x92 :
- return "\xE8\xA6\x8B";
- break;
- case 0x93 :
- return "\xE8\xA7\x92";
- break;
- case 0x94 :
- return "\xE8\xA8\x80";
- break;
- case 0x95 :
- return "\xE8\xB0\xB7";
- break;
- case 0x96 :
- return "\xE8\xB1\x86";
- break;
- case 0x97 :
- return "\xE8\xB1\x95";
- break;
- case 0x98 :
- return "\xE8\xB1\xB8";
- break;
- case 0x99 :
- return "\xE8\xB2\x9D";
- break;
- case 0x9A :
- return "\xE8\xB5\xA4";
- break;
- case 0x9B :
- return "\xE8\xB5\xB0";
- break;
- case 0x9C :
- return "\xE8\xB6\xB3";
- break;
- case 0x9D :
- return "\xE8\xBA\xAB";
- break;
- case 0x9E :
- return "\xE8\xBB\x8A";
- break;
- case 0x9F :
- return "\xE8\xBE\x9B";
- break;
- case 0xA0 :
- return "\xE8\xBE\xB0";
- break;
- case 0xA1 :
- return "\xE8\xBE\xB5";
- break;
- case 0xA2 :
- return "\xE9\x82\x91";
- break;
- case 0xA3 :
- return "\xE9\x85\x89";
- break;
- case 0xA4 :
- return "\xE9\x87\x86";
- break;
- case 0xA5 :
- return "\xE9\x87\x8C";
- break;
- case 0xA6 :
- return "\xE9\x87\x91";
- break;
- case 0xA7 :
- return "\xE9\x95\xB7";
- break;
- case 0xA8 :
- return "\xE9\x96\x80";
- break;
- case 0xA9 :
- return "\xE9\x98\x9C";
- break;
- case 0xAA :
- return "\xE9\x9A\xB6";
- break;
- case 0xAB :
- return "\xE9\x9A\xB9";
- break;
- case 0xAC :
- return "\xE9\x9B\xA8";
- break;
- case 0xAD :
- return "\xE9\x9D\x91";
- break;
- case 0xAE :
- return "\xE9\x9D\x9E";
- break;
- case 0xAF :
- return "\xE9\x9D\xA2";
- break;
- case 0xB0 :
- return "\xE9\x9D\xA9";
- break;
- case 0xB1 :
- return "\xE9\x9F\x8B";
- break;
- case 0xB2 :
- return "\xE9\x9F\xAD";
- break;
- case 0xB3 :
- return "\xE9\x9F\xB3";
- break;
- case 0xB4 :
- return "\xE9\xA0\x81";
- break;
- case 0xB5 :
- return "\xE9\xA2\xA8";
- break;
- case 0xB6 :
- return "\xE9\xA3\x9B";
- break;
- case 0xB7 :
- return "\xE9\xA3\x9F";
- break;
- case 0xB8 :
- return "\xE9\xA6\x96";
- break;
- case 0xB9 :
- return "\xE9\xA6\x99";
- break;
- case 0xBA :
- return "\xE9\xA6\xAC";
- break;
- case 0xBB :
- return "\xE9\xAA\xA8";
- break;
- case 0xBC :
- return "\xE9\xAB\x98";
- break;
- case 0xBD :
- return "\xE9\xAB\x9F";
- break;
- case 0xBE :
- return "\xE9\xAC\xA5";
- break;
- case 0xBF :
- return "\xE9\xAC\xAF";
- break;
- }
- break;
- case 0xBF :
- switch (str[2]) {
- case 0x80 :
- return "\xE9\xAC\xB2";
- break;
- case 0x81 :
- return "\xE9\xAC\xBC";
- break;
- case 0x82 :
- return "\xE9\xAD\x9A";
- break;
- case 0x83 :
- return "\xE9\xB3\xA5";
- break;
- case 0x84 :
- return "\xE9\xB9\xB5";
- break;
- case 0x85 :
- return "\xE9\xB9\xBF";
- break;
- case 0x86 :
- return "\xE9\xBA\xA5";
- break;
- case 0x87 :
- return "\xE9\xBA\xBB";
- break;
- case 0x88 :
- return "\xE9\xBB\x83";
- break;
- case 0x89 :
- return "\xE9\xBB\x8D";
- break;
- case 0x8A :
- return "\xE9\xBB\x91";
- break;
- case 0x8B :
- return "\xE9\xBB\xB9";
- break;
- case 0x8C :
- return "\xE9\xBB\xBD";
- break;
- case 0x8D :
- return "\xE9\xBC\x8E";
- break;
- case 0x8E :
- return "\xE9\xBC\x93";
- break;
- case 0x8F :
- return "\xE9\xBC\xA0";
- break;
- case 0x90 :
- return "\xE9\xBC\xBB";
- break;
- case 0x91 :
- return "\xE9\xBD\x8A";
- break;
- case 0x92 :
- return "\xE9\xBD\x92";
- break;
- case 0x93 :
- return "\xE9\xBE\x8D";
- break;
- case 0x94 :
- return "\xE9\xBE\x9C";
- break;
- case 0x95 :
- return "\xE9\xBE\xA0";
- break;
- }
- break;
- }
- break;
-case 0xE3 :
- switch (str[1]) {
- case 0x80 :
- switch (str[2]) {
- case 0x80 :
- return "\x20";
- break;
- case 0x9C :
- return "\x7E";
- break;
- case 0xB6 :
- return "\xE3\x80\x92";
- break;
- case 0xB8 :
- return "\xE5\x8D\x81";
- break;
- case 0xB9 :
- return "\xE5\x8D\x84";
- break;
- case 0xBA :
- return "\xE5\x8D\x85";
- break;
- }
- break;
- case 0x82 :
- switch (str[2]) {
- case 0x9B :
- return "\xE3\x82\x99";
- break;
- case 0x9C :
- return "\xE3\x82\x9A";
- break;
- case 0x9F :
- return "\xE3\x82\x88\xE3\x82\x8A";
- break;
- }
- break;
- case 0x83 :
- if (str[2] == 0xBF) {
- return "\xE3\x82\xB3\xE3\x83\x88";
- }
- break;
- case 0x84 :
- switch (str[2]) {
- case 0xB1 :
- return "\xE1\x84\x80";
- break;
- case 0xB2 :
- return "\xE1\x84\x81";
- break;
- case 0xB3 :
- return "\xE1\x86\xAA";
- break;
- case 0xB4 :
- return "\xE1\x84\x82";
- break;
- case 0xB5 :
- return "\xE1\x86\xAC";
- break;
- case 0xB6 :
- return "\xE1\x86\xAD";
- break;
- case 0xB7 :
- return "\xE1\x84\x83";
- break;
- case 0xB8 :
- return "\xE1\x84\x84";
- break;
- case 0xB9 :
- return "\xE1\x84\x85";
- break;
- case 0xBA :
- return "\xE1\x86\xB0";
- break;
- case 0xBB :
- return "\xE1\x86\xB1";
- break;
- case 0xBC :
- return "\xE1\x86\xB2";
- break;
- case 0xBD :
- return "\xE1\x86\xB3";
- break;
- case 0xBE :
- return "\xE1\x86\xB4";
- break;
- case 0xBF :
- return "\xE1\x86\xB5";
- break;
- }
- break;
- case 0x85 :
- switch (str[2]) {
- case 0x80 :
- return "\xE1\x84\x9A";
- break;
- case 0x81 :
- return "\xE1\x84\x86";
- break;
- case 0x82 :
- return "\xE1\x84\x87";
- break;
- case 0x83 :
- return "\xE1\x84\x88";
- break;
- case 0x84 :
- return "\xE1\x84\xA1";
- break;
- case 0x85 :
- return "\xE1\x84\x89";
- break;
- case 0x86 :
- return "\xE1\x84\x8A";
- break;
- case 0x87 :
- return "\xE1\x84\x8B";
- break;
- case 0x88 :
- return "\xE1\x84\x8C";
- break;
- case 0x89 :
- return "\xE1\x84\x8D";
- break;
- case 0x8A :
- return "\xE1\x84\x8E";
- break;
- case 0x8B :
- return "\xE1\x84\x8F";
- break;
- case 0x8C :
- return "\xE1\x84\x90";
- break;
- case 0x8D :
- return "\xE1\x84\x91";
- break;
- case 0x8E :
- return "\xE1\x84\x92";
- break;
- case 0x8F :
- return "\xE1\x85\xA1";
- break;
- case 0x90 :
- return "\xE1\x85\xA2";
- break;
- case 0x91 :
- return "\xE1\x85\xA3";
- break;
- case 0x92 :
- return "\xE1\x85\xA4";
- break;
- case 0x93 :
- return "\xE1\x85\xA5";
- break;
- case 0x94 :
- return "\xE1\x85\xA6";
- break;
- case 0x95 :
- return "\xE1\x85\xA7";
- break;
- case 0x96 :
- return "\xE1\x85\xA8";
- break;
- case 0x97 :
- return "\xE1\x85\xA9";
- break;
- case 0x98 :
- return "\xE1\x85\xAA";
- break;
- case 0x99 :
- return "\xE1\x85\xAB";
- break;
- case 0x9A :
- return "\xE1\x85\xAC";
- break;
- case 0x9B :
- return "\xE1\x85\xAD";
- break;
- case 0x9C :
- return "\xE1\x85\xAE";
- break;
- case 0x9D :
- return "\xE1\x85\xAF";
- break;
- case 0x9E :
- return "\xE1\x85\xB0";
- break;
- case 0x9F :
- return "\xE1\x85\xB1";
- break;
- case 0xA0 :
- return "\xE1\x85\xB2";
- break;
- case 0xA1 :
- return "\xE1\x85\xB3";
- break;
- case 0xA2 :
- return "\xE1\x85\xB4";
- break;
- case 0xA3 :
- return "\xE1\x85\xB5";
- break;
- case 0xA4 :
- return "\xE1\x85\xA0";
- break;
- case 0xA5 :
- return "\xE1\x84\x94";
- break;
- case 0xA6 :
- return "\xE1\x84\x95";
- break;
- case 0xA7 :
- return "\xE1\x87\x87";
- break;
- case 0xA8 :
- return "\xE1\x87\x88";
- break;
- case 0xA9 :
- return "\xE1\x87\x8C";
- break;
- case 0xAA :
- return "\xE1\x87\x8E";
- break;
- case 0xAB :
- return "\xE1\x87\x93";
- break;
- case 0xAC :
- return "\xE1\x87\x97";
- break;
- case 0xAD :
- return "\xE1\x87\x99";
- break;
- case 0xAE :
- return "\xE1\x84\x9C";
- break;
- case 0xAF :
- return "\xE1\x87\x9D";
- break;
- case 0xB0 :
- return "\xE1\x87\x9F";
- break;
- case 0xB1 :
- return "\xE1\x84\x9D";
- break;
- case 0xB2 :
- return "\xE1\x84\x9E";
- break;
- case 0xB3 :
- return "\xE1\x84\xA0";
- break;
- case 0xB4 :
- return "\xE1\x84\xA2";
- break;
- case 0xB5 :
- return "\xE1\x84\xA3";
- break;
- case 0xB6 :
- return "\xE1\x84\xA7";
- break;
- case 0xB7 :
- return "\xE1\x84\xA9";
- break;
- case 0xB8 :
- return "\xE1\x84\xAB";
- break;
- case 0xB9 :
- return "\xE1\x84\xAC";
- break;
- case 0xBA :
- return "\xE1\x84\xAD";
- break;
- case 0xBB :
- return "\xE1\x84\xAE";
- break;
- case 0xBC :
- return "\xE1\x84\xAF";
- break;
- case 0xBD :
- return "\xE1\x84\xB2";
- break;
- case 0xBE :
- return "\xE1\x84\xB6";
- break;
- case 0xBF :
- return "\xE1\x85\x80";
- break;
- }
- break;
- case 0x86 :
- switch (str[2]) {
- case 0x80 :
- return "\xE1\x85\x87";
- break;
- case 0x81 :
- return "\xE1\x85\x8C";
- break;
- case 0x82 :
- return "\xE1\x87\xB1";
- break;
- case 0x83 :
- return "\xE1\x87\xB2";
- break;
- case 0x84 :
- return "\xE1\x85\x97";
- break;
- case 0x85 :
- return "\xE1\x85\x98";
- break;
- case 0x86 :
- return "\xE1\x85\x99";
- break;
- case 0x87 :
- return "\xE1\x86\x84";
- break;
- case 0x88 :
- return "\xE1\x86\x85";
- break;
- case 0x89 :
- return "\xE1\x86\x88";
- break;
- case 0x8A :
- return "\xE1\x86\x91";
- break;
- case 0x8B :
- return "\xE1\x86\x92";
- break;
- case 0x8C :
- return "\xE1\x86\x94";
- break;
- case 0x8D :
- return "\xE1\x86\x9E";
- break;
- case 0x8E :
- return "\xE1\x86\xA1";
- break;
- case 0x92 :
- return "\xE4\xB8\x80";
- break;
- case 0x93 :
- return "\xE4\xBA\x8C";
- break;
- case 0x94 :
- return "\xE4\xB8\x89";
- break;
- case 0x95 :
- return "\xE5\x9B\x9B";
- break;
- case 0x96 :
- return "\xE4\xB8\x8A";
- break;
- case 0x97 :
- return "\xE4\xB8\xAD";
- break;
- case 0x98 :
- return "\xE4\xB8\x8B";
- break;
- case 0x99 :
- return "\xE7\x94\xB2";
- break;
- case 0x9A :
- return "\xE4\xB9\x99";
- break;
- case 0x9B :
- return "\xE4\xB8\x99";
- break;
- case 0x9C :
- return "\xE4\xB8\x81";
- break;
- case 0x9D :
- return "\xE5\xA4\xA9";
- break;
- case 0x9E :
- return "\xE5\x9C\xB0";
- break;
- case 0x9F :
- return "\xE4\xBA\xBA";
- break;
- }
- break;
- case 0x88 :
- switch (str[2]) {
- case 0x80 :
- return "\x28\xE1\x84\x80\x29";
- break;
- case 0x81 :
- return "\x28\xE1\x84\x82\x29";
- break;
- case 0x82 :
- return "\x28\xE1\x84\x83\x29";
- break;
- case 0x83 :
- return "\x28\xE1\x84\x85\x29";
- break;
- case 0x84 :
- return "\x28\xE1\x84\x86\x29";
- break;
- case 0x85 :
- return "\x28\xE1\x84\x87\x29";
- break;
- case 0x86 :
- return "\x28\xE1\x84\x89\x29";
- break;
- case 0x87 :
- return "\x28\xE1\x84\x8B\x29";
- break;
- case 0x88 :
- return "\x28\xE1\x84\x8C\x29";
- break;
- case 0x89 :
- return "\x28\xE1\x84\x8E\x29";
- break;
- case 0x8A :
- return "\x28\xE1\x84\x8F\x29";
- break;
- case 0x8B :
- return "\x28\xE1\x84\x90\x29";
- break;
- case 0x8C :
- return "\x28\xE1\x84\x91\x29";
- break;
- case 0x8D :
- return "\x28\xE1\x84\x92\x29";
- break;
- case 0x8E :
- return "\x28\xEA\xB0\x80\x29";
- break;
- case 0x8F :
- return "\x28\xEB\x82\x98\x29";
- break;
- case 0x90 :
- return "\x28\xEB\x8B\xA4\x29";
- break;
- case 0x91 :
- return "\x28\xEB\x9D\xBC\x29";
- break;
- case 0x92 :
- return "\x28\xEB\xA7\x88\x29";
- break;
- case 0x93 :
- return "\x28\xEB\xB0\x94\x29";
- break;
- case 0x94 :
- return "\x28\xEC\x82\xAC\x29";
- break;
- case 0x95 :
- return "\x28\xEC\x95\x84\x29";
- break;
- case 0x96 :
- return "\x28\xEC\x9E\x90\x29";
- break;
- case 0x97 :
- return "\x28\xEC\xB0\xA8\x29";
- break;
- case 0x98 :
- return "\x28\xEC\xB9\xB4\x29";
- break;
- case 0x99 :
- return "\x28\xED\x83\x80\x29";
- break;
- case 0x9A :
- return "\x28\xED\x8C\x8C\x29";
- break;
- case 0x9B :
- return "\x28\xED\x95\x98\x29";
- break;
- case 0x9C :
- return "\x28\xEC\xA3\xBC\x29";
- break;
- case 0x9D :
- return "\x28\xEC\x98\xA4\xEC\xA0\x84\x29";
- break;
- case 0x9E :
- return "\x28\xEC\x98\xA4\xED\x9B\x84\x29";
- break;
- case 0xA0 :
- return "\x28\xE4\xB8\x80\x29";
- break;
- case 0xA1 :
- return "\x28\xE4\xBA\x8C\x29";
- break;
- case 0xA2 :
- return "\x28\xE4\xB8\x89\x29";
- break;
- case 0xA3 :
- return "\x28\xE5\x9B\x9B\x29";
- break;
- case 0xA4 :
- return "\x28\xE4\xBA\x94\x29";
- break;
- case 0xA5 :
- return "\x28\xE5\x85\xAD\x29";
- break;
- case 0xA6 :
- return "\x28\xE4\xB8\x83\x29";
- break;
- case 0xA7 :
- return "\x28\xE5\x85\xAB\x29";
- break;
- case 0xA8 :
- return "\x28\xE4\xB9\x9D\x29";
- break;
- case 0xA9 :
- return "\x28\xE5\x8D\x81\x29";
- break;
- case 0xAA :
- return "\x28\xE6\x9C\x88\x29";
- break;
- case 0xAB :
- return "\x28\xE7\x81\xAB\x29";
- break;
- case 0xAC :
- return "\x28\xE6\xB0\xB4\x29";
- break;
- case 0xAD :
- return "\x28\xE6\x9C\xA8\x29";
- break;
- case 0xAE :
- return "\x28\xE9\x87\x91\x29";
- break;
- case 0xAF :
- return "\x28\xE5\x9C\x9F\x29";
- break;
- case 0xB0 :
- return "\x28\xE6\x97\xA5\x29";
- break;
- case 0xB1 :
- return "\x28\xE6\xA0\xAA\x29";
- break;
- case 0xB2 :
- return "\x28\xE6\x9C\x89\x29";
- break;
- case 0xB3 :
- return "\x28\xE7\xA4\xBE\x29";
- break;
- case 0xB4 :
- return "\x28\xE5\x90\x8D\x29";
- break;
- case 0xB5 :
- return "\x28\xE7\x89\xB9\x29";
- break;
- case 0xB6 :
- return "\x28\xE8\xB2\xA1\x29";
- break;
- case 0xB7 :
- return "\x28\xE7\xA5\x9D\x29";
- break;
- case 0xB8 :
- return "\x28\xE5\x8A\xB4\x29";
- break;
- case 0xB9 :
- return "\x28\xE4\xBB\xA3\x29";
- break;
- case 0xBA :
- return "\x28\xE5\x91\xBC\x29";
- break;
- case 0xBB :
- return "\x28\xE5\xAD\xA6\x29";
- break;
- case 0xBC :
- return "\x28\xE7\x9B\xA3\x29";
- break;
- case 0xBD :
- return "\x28\xE4\xBC\x81\x29";
- break;
- case 0xBE :
- return "\x28\xE8\xB3\x87\x29";
- break;
- case 0xBF :
- return "\x28\xE5\x8D\x94\x29";
- break;
- }
- break;
- case 0x89 :
- switch (str[2]) {
- case 0x80 :
- return "\x28\xE7\xA5\xAD\x29";
- break;
- case 0x81 :
- return "\x28\xE4\xBC\x91\x29";
- break;
- case 0x82 :
- return "\x28\xE8\x87\xAA\x29";
- break;
- case 0x83 :
- return "\x28\xE8\x87\xB3\x29";
- break;
- case 0x90 :
- return "\x70\x74\x65";
- break;
- case 0x91 :
- return "\x32\x31";
- break;
- case 0x92 :
- return "\x32\x32";
- break;
- case 0x93 :
- return "\x32\x33";
- break;
- case 0x94 :
- return "\x32\x34";
- break;
- case 0x95 :
- return "\x32\x35";
- break;
- case 0x96 :
- return "\x32\x36";
- break;
- case 0x97 :
- return "\x32\x37";
- break;
- case 0x98 :
- return "\x32\x38";
- break;
- case 0x99 :
- return "\x32\x39";
- break;
- case 0x9A :
- return "\x33\x30";
- break;
- case 0x9B :
- return "\x33\x31";
- break;
- case 0x9C :
- return "\x33\x32";
- break;
- case 0x9D :
- return "\x33\x33";
- break;
- case 0x9E :
- return "\x33\x34";
- break;
- case 0x9F :
- return "\x33\x35";
- break;
- case 0xA0 :
- return "\xE1\x84\x80";
- break;
- case 0xA1 :
- return "\xE1\x84\x82";
- break;
- case 0xA2 :
- return "\xE1\x84\x83";
- break;
- case 0xA3 :
- return "\xE1\x84\x85";
- break;
- case 0xA4 :
- return "\xE1\x84\x86";
- break;
- case 0xA5 :
- return "\xE1\x84\x87";
- break;
- case 0xA6 :
- return "\xE1\x84\x89";
- break;
- case 0xA7 :
- return "\xE1\x84\x8B";
- break;
- case 0xA8 :
- return "\xE1\x84\x8C";
- break;
- case 0xA9 :
- return "\xE1\x84\x8E";
- break;
- case 0xAA :
- return "\xE1\x84\x8F";
- break;
- case 0xAB :
- return "\xE1\x84\x90";
- break;
- case 0xAC :
- return "\xE1\x84\x91";
- break;
- case 0xAD :
- return "\xE1\x84\x92";
- break;
- case 0xAE :
- return "\xEA\xB0\x80";
- break;
- case 0xAF :
- return "\xEB\x82\x98";
- break;
- case 0xB0 :
- return "\xEB\x8B\xA4";
- break;
- case 0xB1 :
- return "\xEB\x9D\xBC";
- break;
- case 0xB2 :
- return "\xEB\xA7\x88";
- break;
- case 0xB3 :
- return "\xEB\xB0\x94";
- break;
- case 0xB4 :
- return "\xEC\x82\xAC";
- break;
- case 0xB5 :
- return "\xEC\x95\x84";
- break;
- case 0xB6 :
- return "\xEC\x9E\x90";
- break;
- case 0xB7 :
- return "\xEC\xB0\xA8";
- break;
- case 0xB8 :
- return "\xEC\xB9\xB4";
- break;
- case 0xB9 :
- return "\xED\x83\x80";
- break;
- case 0xBA :
- return "\xED\x8C\x8C";
- break;
- case 0xBB :
- return "\xED\x95\x98";
- break;
- case 0xBC :
- return "\xEC\xB0\xB8\xEA\xB3\xA0";
- break;
- case 0xBD :
- return "\xEC\xA3\xBC\xEC\x9D\x98";
- break;
- case 0xBE :
- return "\xEC\x9A\xB0";
- break;
- }
- break;
- case 0x8A :
- switch (str[2]) {
- case 0x80 :
- return "\xE4\xB8\x80";
- break;
- case 0x81 :
- return "\xE4\xBA\x8C";
- break;
- case 0x82 :
- return "\xE4\xB8\x89";
- break;
- case 0x83 :
- return "\xE5\x9B\x9B";
- break;
- case 0x84 :
- return "\xE4\xBA\x94";
- break;
- case 0x85 :
- return "\xE5\x85\xAD";
- break;
- case 0x86 :
- return "\xE4\xB8\x83";
- break;
- case 0x87 :
- return "\xE5\x85\xAB";
- break;
- case 0x88 :
- return "\xE4\xB9\x9D";
- break;
- case 0x89 :
- return "\xE5\x8D\x81";
- break;
- case 0x8A :
- return "\xE6\x9C\x88";
- break;
- case 0x8B :
- return "\xE7\x81\xAB";
- break;
- case 0x8C :
- return "\xE6\xB0\xB4";
- break;
- case 0x8D :
- return "\xE6\x9C\xA8";
- break;
- case 0x8E :
- return "\xE9\x87\x91";
- break;
- case 0x8F :
- return "\xE5\x9C\x9F";
- break;
- case 0x90 :
- return "\xE6\x97\xA5";
- break;
- case 0x91 :
- return "\xE6\xA0\xAA";
- break;
- case 0x92 :
- return "\xE6\x9C\x89";
- break;
- case 0x93 :
- return "\xE7\xA4\xBE";
- break;
- case 0x94 :
- return "\xE5\x90\x8D";
- break;
- case 0x95 :
- return "\xE7\x89\xB9";
- break;
- case 0x96 :
- return "\xE8\xB2\xA1";
- break;
- case 0x97 :
- return "\xE7\xA5\x9D";
- break;
- case 0x98 :
- return "\xE5\x8A\xB4";
- break;
- case 0x99 :
- return "\xE7\xA7\x98";
- break;
- case 0x9A :
- return "\xE7\x94\xB7";
- break;
- case 0x9B :
- return "\xE5\xA5\xB3";
- break;
- case 0x9C :
- return "\xE9\x81\xA9";
- break;
- case 0x9D :
- return "\xE5\x84\xAA";
- break;
- case 0x9E :
- return "\xE5\x8D\xB0";
- break;
- case 0x9F :
- return "\xE6\xB3\xA8";
- break;
- case 0xA0 :
- return "\xE9\xA0\x85";
- break;
- case 0xA1 :
- return "\xE4\xBC\x91";
- break;
- case 0xA2 :
- return "\xE5\x86\x99";
- break;
- case 0xA3 :
- return "\xE6\xAD\xA3";
- break;
- case 0xA4 :
- return "\xE4\xB8\x8A";
- break;
- case 0xA5 :
- return "\xE4\xB8\xAD";
- break;
- case 0xA6 :
- return "\xE4\xB8\x8B";
- break;
- case 0xA7 :
- return "\xE5\xB7\xA6";
- break;
- case 0xA8 :
- return "\xE5\x8F\xB3";
- break;
- case 0xA9 :
- return "\xE5\x8C\xBB";
- break;
- case 0xAA :
- return "\xE5\xAE\x97";
- break;
- case 0xAB :
- return "\xE5\xAD\xA6";
- break;
- case 0xAC :
- return "\xE7\x9B\xA3";
- break;
- case 0xAD :
- return "\xE4\xBC\x81";
- break;
- case 0xAE :
- return "\xE8\xB3\x87";
- break;
- case 0xAF :
- return "\xE5\x8D\x94";
- break;
- case 0xB0 :
- return "\xE5\xA4\x9C";
- break;
- case 0xB1 :
- return "\x33\x36";
- break;
- case 0xB2 :
- return "\x33\x37";
- break;
- case 0xB3 :
- return "\x33\x38";
- break;
- case 0xB4 :
- return "\x33\x39";
- break;
- case 0xB5 :
- return "\x34\x30";
- break;
- case 0xB6 :
- return "\x34\x31";
- break;
- case 0xB7 :
- return "\x34\x32";
- break;
- case 0xB8 :
- return "\x34\x33";
- break;
- case 0xB9 :
- return "\x34\x34";
- break;
- case 0xBA :
- return "\x34\x35";
- break;
- case 0xBB :
- return "\x34\x36";
- break;
- case 0xBC :
- return "\x34\x37";
- break;
- case 0xBD :
- return "\x34\x38";
- break;
- case 0xBE :
- return "\x34\x39";
- break;
- case 0xBF :
- return "\x35\x30";
- break;
- }
- break;
- case 0x8B :
- switch (str[2]) {
- case 0x80 :
- return "\x31\xE6\x9C\x88";
- break;
- case 0x81 :
- return "\x32\xE6\x9C\x88";
- break;
- case 0x82 :
- return "\x33\xE6\x9C\x88";
- break;
- case 0x83 :
- return "\x34\xE6\x9C\x88";
- break;
- case 0x84 :
- return "\x35\xE6\x9C\x88";
- break;
- case 0x85 :
- return "\x36\xE6\x9C\x88";
- break;
- case 0x86 :
- return "\x37\xE6\x9C\x88";
- break;
- case 0x87 :
- return "\x38\xE6\x9C\x88";
- break;
- case 0x88 :
- return "\x39\xE6\x9C\x88";
- break;
- case 0x89 :
- return "\x31\x30\xE6\x9C\x88";
- break;
- case 0x8A :
- return "\x31\x31\xE6\x9C\x88";
- break;
- case 0x8B :
- return "\x31\x32\xE6\x9C\x88";
- break;
- case 0x8C :
- return "\x68\x67";
- break;
- case 0x8D :
- return "\x65\x72\x67";
- break;
- case 0x8E :
- return "\x65\x76";
- break;
- case 0x8F :
- return "\x6C\x74\x64";
- break;
- case 0x90 :
- return "\xE3\x82\xA2";
- break;
- case 0x91 :
- return "\xE3\x82\xA4";
- break;
- case 0x92 :
- return "\xE3\x82\xA6";
- break;
- case 0x93 :
- return "\xE3\x82\xA8";
- break;
- case 0x94 :
- return "\xE3\x82\xAA";
- break;
- case 0x95 :
- return "\xE3\x82\xAB";
- break;
- case 0x96 :
- return "\xE3\x82\xAD";
- break;
- case 0x97 :
- return "\xE3\x82\xAF";
- break;
- case 0x98 :
- return "\xE3\x82\xB1";
- break;
- case 0x99 :
- return "\xE3\x82\xB3";
- break;
- case 0x9A :
- return "\xE3\x82\xB5";
- break;
- case 0x9B :
- return "\xE3\x82\xB7";
- break;
- case 0x9C :
- return "\xE3\x82\xB9";
- break;
- case 0x9D :
- return "\xE3\x82\xBB";
- break;
- case 0x9E :
- return "\xE3\x82\xBD";
- break;
- case 0x9F :
- return "\xE3\x82\xBF";
- break;
- case 0xA0 :
- return "\xE3\x83\x81";
- break;
- case 0xA1 :
- return "\xE3\x83\x84";
- break;
- case 0xA2 :
- return "\xE3\x83\x86";
- break;
- case 0xA3 :
- return "\xE3\x83\x88";
- break;
- case 0xA4 :
- return "\xE3\x83\x8A";
- break;
- case 0xA5 :
- return "\xE3\x83\x8B";
- break;
- case 0xA6 :
- return "\xE3\x83\x8C";
- break;
- case 0xA7 :
- return "\xE3\x83\x8D";
- break;
- case 0xA8 :
- return "\xE3\x83\x8E";
- break;
- case 0xA9 :
- return "\xE3\x83\x8F";
- break;
- case 0xAA :
- return "\xE3\x83\x92";
- break;
- case 0xAB :
- return "\xE3\x83\x95";
- break;
- case 0xAC :
- return "\xE3\x83\x98";
- break;
- case 0xAD :
- return "\xE3\x83\x9B";
- break;
- case 0xAE :
- return "\xE3\x83\x9E";
- break;
- case 0xAF :
- return "\xE3\x83\x9F";
- break;
- case 0xB0 :
- return "\xE3\x83\xA0";
- break;
- case 0xB1 :
- return "\xE3\x83\xA1";
- break;
- case 0xB2 :
- return "\xE3\x83\xA2";
- break;
- case 0xB3 :
- return "\xE3\x83\xA4";
- break;
- case 0xB4 :
- return "\xE3\x83\xA6";
- break;
- case 0xB5 :
- return "\xE3\x83\xA8";
- break;
- case 0xB6 :
- return "\xE3\x83\xA9";
- break;
- case 0xB7 :
- return "\xE3\x83\xAA";
- break;
- case 0xB8 :
- return "\xE3\x83\xAB";
- break;
- case 0xB9 :
- return "\xE3\x83\xAC";
- break;
- case 0xBA :
- return "\xE3\x83\xAD";
- break;
- case 0xBB :
- return "\xE3\x83\xAF";
- break;
- case 0xBC :
- return "\xE3\x83\xB0";
- break;
- case 0xBD :
- return "\xE3\x83\xB1";
- break;
- case 0xBE :
- return "\xE3\x83\xB2";
- break;
- }
- break;
- case 0x8C :
- switch (str[2]) {
- case 0x80 :
- return "\xE3\x82\xA2\xE3\x83\x91\xE3\x83\xBC\xE3\x83\x88";
- break;
- case 0x81 :
- return "\xE3\x82\xA2\xE3\x83\xAB\xE3\x83\x95\xE3\x82\xA1";
- break;
- case 0x82 :
- return "\xE3\x82\xA2\xE3\x83\xB3\xE3\x83\x9A\xE3\x82\xA2";
- break;
- case 0x83 :
- return "\xE3\x82\xA2\xE3\x83\xBC\xE3\x83\xAB";
- break;
- case 0x84 :
- return "\xE3\x82\xA4\xE3\x83\x8B\xE3\x83\xB3\xE3\x82\xB0";
- break;
- case 0x85 :
- return "\xE3\x82\xA4\xE3\x83\xB3\xE3\x83\x81";
- break;
- case 0x86 :
- return "\xE3\x82\xA6\xE3\x82\xA9\xE3\x83\xB3";
- break;
- case 0x87 :
- return "\xE3\x82\xA8\xE3\x82\xB9\xE3\x82\xAF\xE3\x83\xBC\xE3\x83\x89";
- break;
- case 0x88 :
- return "\xE3\x82\xA8\xE3\x83\xBC\xE3\x82\xAB\xE3\x83\xBC";
- break;
- case 0x89 :
- return "\xE3\x82\xAA\xE3\x83\xB3\xE3\x82\xB9";
- break;
- case 0x8A :
- return "\xE3\x82\xAA\xE3\x83\xBC\xE3\x83\xA0";
- break;
- case 0x8B :
- return "\xE3\x82\xAB\xE3\x82\xA4\xE3\x83\xAA";
- break;
- case 0x8C :
- return "\xE3\x82\xAB\xE3\x83\xA9\xE3\x83\x83\xE3\x83\x88";
- break;
- case 0x8D :
- return "\xE3\x82\xAB\xE3\x83\xAD\xE3\x83\xAA\xE3\x83\xBC";
- break;
- case 0x8E :
- return "\xE3\x82\xAC\xE3\x83\xAD\xE3\x83\xB3";
- break;
- case 0x8F :
- return "\xE3\x82\xAC\xE3\x83\xB3\xE3\x83\x9E";
- break;
- case 0x90 :
- return "\xE3\x82\xAE\xE3\x82\xAC";
- break;
- case 0x91 :
- return "\xE3\x82\xAE\xE3\x83\x8B\xE3\x83\xBC";
- break;
- case 0x92 :
- return "\xE3\x82\xAD\xE3\x83\xA5\xE3\x83\xAA\xE3\x83\xBC";
- break;
- case 0x93 :
- return "\xE3\x82\xAE\xE3\x83\xAB\xE3\x83\x80\xE3\x83\xBC";
- break;
- case 0x94 :
- return "\xE3\x82\xAD\xE3\x83\xAD";
- break;
- case 0x95 :
- return "\xE3\x82\xAD\xE3\x83\xAD\xE3\x82\xB0\xE3\x83\xA9\xE3\x83\xA0";
- break;
- case 0x96 :
- return "\xE3\x82\xAD\xE3\x83\xAD\xE3\x83\xA1\xE3\x83\xBC\xE3\x83\x88\xE3\x83\xAB";
- break;
- case 0x97 :
- return "\xE3\x82\xAD\xE3\x83\xAD\xE3\x83\xAF\xE3\x83\x83\xE3\x83\x88";
- break;
- case 0x98 :
- return "\xE3\x82\xB0\xE3\x83\xA9\xE3\x83\xA0";
- break;
- case 0x99 :
- return "\xE3\x82\xB0\xE3\x83\xA9\xE3\x83\xA0\xE3\x83\x88\xE3\x83\xB3";
- break;
- case 0x9A :
- return "\xE3\x82\xAF\xE3\x83\xAB\xE3\x82\xBC\xE3\x82\xA4\xE3\x83\xAD";
- break;
- case 0x9B :
- return "\xE3\x82\xAF\xE3\x83\xAD\xE3\x83\xBC\xE3\x83\x8D";
- break;
- case 0x9C :
- return "\xE3\x82\xB1\xE3\x83\xBC\xE3\x82\xB9";
- break;
- case 0x9D :
- return "\xE3\x82\xB3\xE3\x83\xAB\xE3\x83\x8A";
- break;
- case 0x9E :
- return "\xE3\x82\xB3\xE3\x83\xBC\xE3\x83\x9D";
- break;
- case 0x9F :
- return "\xE3\x82\xB5\xE3\x82\xA4\xE3\x82\xAF\xE3\x83\xAB";
- break;
- case 0xA0 :
- return "\xE3\x82\xB5\xE3\x83\xB3\xE3\x83\x81\xE3\x83\xBC\xE3\x83\xA0";
- break;
- case 0xA1 :
- return "\xE3\x82\xB7\xE3\x83\xAA\xE3\x83\xB3\xE3\x82\xB0";
- break;
- case 0xA2 :
- return "\xE3\x82\xBB\xE3\x83\xB3\xE3\x83\x81";
- break;
- case 0xA3 :
- return "\xE3\x82\xBB\xE3\x83\xB3\xE3\x83\x88";
- break;
- case 0xA4 :
- return "\xE3\x83\x80\xE3\x83\xBC\xE3\x82\xB9";
- break;
- case 0xA5 :
- return "\xE3\x83\x87\xE3\x82\xB7";
- break;
- case 0xA6 :
- return "\xE3\x83\x89\xE3\x83\xAB";
- break;
- case 0xA7 :
- return "\xE3\x83\x88\xE3\x83\xB3";
- break;
- case 0xA8 :
- return "\xE3\x83\x8A\xE3\x83\x8E";
- break;
- case 0xA9 :
- return "\xE3\x83\x8E\xE3\x83\x83\xE3\x83\x88";
- break;
- case 0xAA :
- return "\xE3\x83\x8F\xE3\x82\xA4\xE3\x83\x84";
- break;
- case 0xAB :
- return "\xE3\x83\x91\xE3\x83\xBC\xE3\x82\xBB\xE3\x83\xB3\xE3\x83\x88";
- break;
- case 0xAC :
- return "\xE3\x83\x91\xE3\x83\xBC\xE3\x83\x84";
- break;
- case 0xAD :
- return "\xE3\x83\x90\xE3\x83\xBC\xE3\x83\xAC\xE3\x83\xAB";
- break;
- case 0xAE :
- return "\xE3\x83\x94\xE3\x82\xA2\xE3\x82\xB9\xE3\x83\x88\xE3\x83\xAB";
- break;
- case 0xAF :
- return "\xE3\x83\x94\xE3\x82\xAF\xE3\x83\xAB";
- break;
- case 0xB0 :
- return "\xE3\x83\x94\xE3\x82\xB3";
- break;
- case 0xB1 :
- return "\xE3\x83\x93\xE3\x83\xAB";
- break;
- case 0xB2 :
- return "\xE3\x83\x95\xE3\x82\xA1\xE3\x83\xA9\xE3\x83\x83\xE3\x83\x89";
- break;
- case 0xB3 :
- return "\xE3\x83\x95\xE3\x82\xA3\xE3\x83\xBC\xE3\x83\x88";
- break;
- case 0xB4 :
- return "\xE3\x83\x96\xE3\x83\x83\xE3\x82\xB7\xE3\x82\xA7\xE3\x83\xAB";
- break;
- case 0xB5 :
- return "\xE3\x83\x95\xE3\x83\xA9\xE3\x83\xB3";
- break;
- case 0xB6 :
- return "\xE3\x83\x98\xE3\x82\xAF\xE3\x82\xBF\xE3\x83\xBC\xE3\x83\xAB";
- break;
- case 0xB7 :
- return "\xE3\x83\x9A\xE3\x82\xBD";
- break;
- case 0xB8 :
- return "\xE3\x83\x9A\xE3\x83\x8B\xE3\x83\x92";
- break;
- case 0xB9 :
- return "\xE3\x83\x98\xE3\x83\xAB\xE3\x83\x84";
- break;
- case 0xBA :
- return "\xE3\x83\x9A\xE3\x83\xB3\xE3\x82\xB9";
- break;
- case 0xBB :
- return "\xE3\x83\x9A\xE3\x83\xBC\xE3\x82\xB8";
- break;
- case 0xBC :
- return "\xE3\x83\x99\xE3\x83\xBC\xE3\x82\xBF";
- break;
- case 0xBD :
- return "\xE3\x83\x9D\xE3\x82\xA4\xE3\x83\xB3\xE3\x83\x88";
- break;
- case 0xBE :
- return "\xE3\x83\x9C\xE3\x83\xAB\xE3\x83\x88";
- break;
- case 0xBF :
- return "\xE3\x83\x9B\xE3\x83\xB3";
- break;
- }
- break;
- case 0x8D :
- switch (str[2]) {
- case 0x80 :
- return "\xE3\x83\x9D\xE3\x83\xB3\xE3\x83\x89";
- break;
- case 0x81 :
- return "\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xAB";
- break;
- case 0x82 :
- return "\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xB3";
- break;
- case 0x83 :
- return "\xE3\x83\x9E\xE3\x82\xA4\xE3\x82\xAF\xE3\x83\xAD";
- break;
- case 0x84 :
- return "\xE3\x83\x9E\xE3\x82\xA4\xE3\x83\xAB";
- break;
- case 0x85 :
- return "\xE3\x83\x9E\xE3\x83\x83\xE3\x83\x8F";
- break;
- case 0x86 :
- return "\xE3\x83\x9E\xE3\x83\xAB\xE3\x82\xAF";
- break;
- case 0x87 :
- return "\xE3\x83\x9E\xE3\x83\xB3\xE3\x82\xB7\xE3\x83\xA7\xE3\x83\xB3";
- break;
- case 0x88 :
- return "\xE3\x83\x9F\xE3\x82\xAF\xE3\x83\xAD\xE3\x83\xB3";
- break;
- case 0x89 :
- return "\xE3\x83\x9F\xE3\x83\xAA";
- break;
- case 0x8A :
- return "\xE3\x83\x9F\xE3\x83\xAA\xE3\x83\x90\xE3\x83\xBC\xE3\x83\xAB";
- break;
- case 0x8B :
- return "\xE3\x83\xA1\xE3\x82\xAC";
- break;
- case 0x8C :
- return "\xE3\x83\xA1\xE3\x82\xAC\xE3\x83\x88\xE3\x83\xB3";
- break;
- case 0x8D :
- return "\xE3\x83\xA1\xE3\x83\xBC\xE3\x83\x88\xE3\x83\xAB";
- break;
- case 0x8E :
- return "\xE3\x83\xA4\xE3\x83\xBC\xE3\x83\x89";
- break;
- case 0x8F :
- return "\xE3\x83\xA4\xE3\x83\xBC\xE3\x83\xAB";
- break;
- case 0x90 :
- return "\xE3\x83\xA6\xE3\x82\xA2\xE3\x83\xB3";
- break;
- case 0x91 :
- return "\xE3\x83\xAA\xE3\x83\x83\xE3\x83\x88\xE3\x83\xAB";
- break;
- case 0x92 :
- return "\xE3\x83\xAA\xE3\x83\xA9";
- break;
- case 0x93 :
- return "\xE3\x83\xAB\xE3\x83\x94\xE3\x83\xBC";
- break;
- case 0x94 :
- return "\xE3\x83\xAB\xE3\x83\xBC\xE3\x83\x96\xE3\x83\xAB";
- break;
- case 0x95 :
- return "\xE3\x83\xAC\xE3\x83\xA0";
- break;
- case 0x96 :
- return "\xE3\x83\xAC\xE3\x83\xB3\xE3\x83\x88\xE3\x82\xB2\xE3\x83\xB3";
- break;
- case 0x97 :
- return "\xE3\x83\xAF\xE3\x83\x83\xE3\x83\x88";
- break;
- case 0x98 :
- return "\x30\xE7\x82\xB9";
- break;
- case 0x99 :
- return "\x31\xE7\x82\xB9";
- break;
- case 0x9A :
- return "\x32\xE7\x82\xB9";
- break;
- case 0x9B :
- return "\x33\xE7\x82\xB9";
- break;
- case 0x9C :
- return "\x34\xE7\x82\xB9";
- break;
- case 0x9D :
- return "\x35\xE7\x82\xB9";
- break;
- case 0x9E :
- return "\x36\xE7\x82\xB9";
- break;
- case 0x9F :
- return "\x37\xE7\x82\xB9";
- break;
- case 0xA0 :
- return "\x38\xE7\x82\xB9";
- break;
- case 0xA1 :
- return "\x39\xE7\x82\xB9";
- break;
- case 0xA2 :
- return "\x31\x30\xE7\x82\xB9";
- break;
- case 0xA3 :
- return "\x31\x31\xE7\x82\xB9";
- break;
- case 0xA4 :
- return "\x31\x32\xE7\x82\xB9";
- break;
- case 0xA5 :
- return "\x31\x33\xE7\x82\xB9";
- break;
- case 0xA6 :
- return "\x31\x34\xE7\x82\xB9";
- break;
- case 0xA7 :
- return "\x31\x35\xE7\x82\xB9";
- break;
- case 0xA8 :
- return "\x31\x36\xE7\x82\xB9";
- break;
- case 0xA9 :
- return "\x31\x37\xE7\x82\xB9";
- break;
- case 0xAA :
- return "\x31\x38\xE7\x82\xB9";
- break;
- case 0xAB :
- return "\x31\x39\xE7\x82\xB9";
- break;
- case 0xAC :
- return "\x32\x30\xE7\x82\xB9";
- break;
- case 0xAD :
- return "\x32\x31\xE7\x82\xB9";
- break;
- case 0xAE :
- return "\x32\x32\xE7\x82\xB9";
- break;
- case 0xAF :
- return "\x32\x33\xE7\x82\xB9";
- break;
- case 0xB0 :
- return "\x32\x34\xE7\x82\xB9";
- break;
- case 0xB1 :
- return "\x68\x70\x61";
- break;
- case 0xB2 :
- return "\x64\x61";
- break;
- case 0xB3 :
- return "\x61\x75";
- break;
- case 0xB4 :
- return "\x62\x61\x72";
- break;
- case 0xB5 :
- return "\x6F\x76";
- break;
- case 0xB6 :
- return "\x70\x63";
- break;
- case 0xB7 :
- return "\x64\x6D";
- break;
- case 0xB8 :
- return "\x64\x6D\x32";
- break;
- case 0xB9 :
- return "\x64\x6D\x33";
- break;
- case 0xBA :
- return "\x69\x75";
- break;
- case 0xBB :
- return "\xE5\xB9\xB3\xE6\x88\x90";
- break;
- case 0xBC :
- return "\xE6\x98\xAD\xE5\x92\x8C";
- break;
- case 0xBD :
- return "\xE5\xA4\xA7\xE6\xAD\xA3";
- break;
- case 0xBE :
- return "\xE6\x98\x8E\xE6\xB2\xBB";
- break;
- case 0xBF :
- return "\xE6\xA0\xAA\xE5\xBC\x8F\xE4\xBC\x9A\xE7\xA4\xBE";
- break;
- }
- break;
- case 0x8E :
- switch (str[2]) {
- case 0x80 :
- return "\x70\x61";
- break;
- case 0x81 :
- return "\x6E\x61";
- break;
- case 0x82 :
- return "\xCE\xBC\x61";
- break;
- case 0x83 :
- return "\x6D\x61";
- break;
- case 0x84 :
- return "\x6B\x61";
- break;
- case 0x85 :
- return "\x6B\x62";
- break;
- case 0x86 :
- return "\x6D\x62";
- break;
- case 0x87 :
- return "\x67\x62";
- break;
- case 0x88 :
- return "\x63\x61\x6C";
- break;
- case 0x89 :
- return "\x6B\x63\x61\x6C";
- break;
- case 0x8A :
- return "\x70\x66";
- break;
- case 0x8B :
- return "\x6E\x66";
- break;
- case 0x8C :
- return "\xCE\xBC\x66";
- break;
- case 0x8D :
- return "\xCE\xBC\x67";
- break;
- case 0x8E :
- return "\x6D\x67";
- break;
- case 0x8F :
- return "\x6B\x67";
- break;
- case 0x90 :
- return "\x68\x7A";
- break;
- case 0x91 :
- return "\x6B\x68\x7A";
- break;
- case 0x92 :
- return "\x6D\x68\x7A";
- break;
- case 0x93 :
- return "\x67\x68\x7A";
- break;
- case 0x94 :
- return "\x74\x68\x7A";
- break;
- case 0x95 :
- return "\xCE\xBC\x6C";
- break;
- case 0x96 :
- return "\x6D\x6C";
- break;
- case 0x97 :
- return "\x64\x6C";
- break;
- case 0x98 :
- return "\x6B\x6C";
- break;
- case 0x99 :
- return "\x66\x6D";
- break;
- case 0x9A :
- return "\x6E\x6D";
- break;
- case 0x9B :
- return "\xCE\xBC\x6D";
- break;
- case 0x9C :
- return "\x6D\x6D";
- break;
- case 0x9D :
- return "\x63\x6D";
- break;
- case 0x9E :
- return "\x6B\x6D";
- break;
- case 0x9F :
- return "\x6D\x6D\x32";
- break;
- case 0xA0 :
- return "\x63\x6D\x32";
- break;
- case 0xA1 :
- return "\x6D\x32";
- break;
- case 0xA2 :
- return "\x6B\x6D\x32";
- break;
- case 0xA3 :
- return "\x6D\x6D\x33";
- break;
- case 0xA4 :
- return "\x63\x6D\x33";
- break;
- case 0xA5 :
- return "\x6D\x33";
- break;
- case 0xA6 :
- return "\x6B\x6D\x33";
- break;
- case 0xA7 :
- return "\x6D\xE2\x88\x95\x73";
- break;
- case 0xA8 :
- return "\x6D\xE2\x88\x95\x73\x32";
- break;
- case 0xA9 :
- return "\x70\x61";
- break;
- case 0xAA :
- return "\x6B\x70\x61";
- break;
- case 0xAB :
- return "\x6D\x70\x61";
- break;
- case 0xAC :
- return "\x67\x70\x61";
- break;
- case 0xAD :
- return "\x72\x61\x64";
- break;
- case 0xAE :
- return "\x72\x61\x64\xE2\x88\x95\x73";
- break;
- case 0xAF :
- return "\x72\x61\x64\xE2\x88\x95\x73\x32";
- break;
- case 0xB0 :
- return "\x70\x73";
- break;
- case 0xB1 :
- return "\x6E\x73";
- break;
- case 0xB2 :
- return "\xCE\xBC\x73";
- break;
- case 0xB3 :
- return "\x6D\x73";
- break;
- case 0xB4 :
- return "\x70\x76";
- break;
- case 0xB5 :
- return "\x6E\x76";
- break;
- case 0xB6 :
- return "\xCE\xBC\x76";
- break;
- case 0xB7 :
- return "\x6D\x76";
- break;
- case 0xB8 :
- return "\x6B\x76";
- break;
- case 0xB9 :
- return "\x6D\x76";
- break;
- case 0xBA :
- return "\x70\x77";
- break;
- case 0xBB :
- return "\x6E\x77";
- break;
- case 0xBC :
- return "\xCE\xBC\x77";
- break;
- case 0xBD :
- return "\x6D\x77";
- break;
- case 0xBE :
- return "\x6B\x77";
- break;
- case 0xBF :
- return "\x6D\x77";
- break;
- }
- break;
- case 0x8F :
- switch (str[2]) {
- case 0x80 :
- return "\x6B\xCE\xA9";
- break;
- case 0x81 :
- return "\x6D\xCE\xA9";
- break;
- case 0x82 :
- return "\x61\x2E\x6D\x2E";
- break;
- case 0x83 :
- return "\x62\x71";
- break;
- case 0x84 :
- return "\x63\x63";
- break;
- case 0x85 :
- return "\x63\x64";
- break;
- case 0x86 :
- return "\x63\xE2\x88\x95\x6B\x67";
- break;
- case 0x87 :
- return "\x63\x6F\x2E";
- break;
- case 0x88 :
- return "\x64\x62";
- break;
- case 0x89 :
- return "\x67\x79";
- break;
- case 0x8A :
- return "\x68\x61";
- break;
- case 0x8B :
- return "\x68\x70";
- break;
- case 0x8C :
- return "\x69\x6E";
- break;
- case 0x8D :
- return "\x6B\x6B";
- break;
- case 0x8E :
- return "\x6B\x6D";
- break;
- case 0x8F :
- return "\x6B\x74";
- break;
- case 0x90 :
- return "\x6C\x6D";
- break;
- case 0x91 :
- return "\x6C\x6E";
- break;
- case 0x92 :
- return "\x6C\x6F\x67";
- break;
- case 0x93 :
- return "\x6C\x78";
- break;
- case 0x94 :
- return "\x6D\x62";
- break;
- case 0x95 :
- return "\x6D\x69\x6C";
- break;
- case 0x96 :
- return "\x6D\x6F\x6C";
- break;
- case 0x97 :
- return "\x70\x68";
- break;
- case 0x98 :
- return "\x70\x2E\x6D\x2E";
- break;
- case 0x99 :
- return "\x70\x70\x6D";
- break;
- case 0x9A :
- return "\x70\x72";
- break;
- case 0x9B :
- return "\x73\x72";
- break;
- case 0x9C :
- return "\x73\x76";
- break;
- case 0x9D :
- return "\x77\x62";
- break;
- case 0x9E :
- return "\x76\xE2\x88\x95\x6D";
- break;
- case 0x9F :
- return "\x61\xE2\x88\x95\x6D";
- break;
- case 0xA0 :
- return "\x31\xE6\x97\xA5";
- break;
- case 0xA1 :
- return "\x32\xE6\x97\xA5";
- break;
- case 0xA2 :
- return "\x33\xE6\x97\xA5";
- break;
- case 0xA3 :
- return "\x34\xE6\x97\xA5";
- break;
- case 0xA4 :
- return "\x35\xE6\x97\xA5";
- break;
- case 0xA5 :
- return "\x36\xE6\x97\xA5";
- break;
- case 0xA6 :
- return "\x37\xE6\x97\xA5";
- break;
- case 0xA7 :
- return "\x38\xE6\x97\xA5";
- break;
- case 0xA8 :
- return "\x39\xE6\x97\xA5";
- break;
- case 0xA9 :
- return "\x31\x30\xE6\x97\xA5";
- break;
- case 0xAA :
- return "\x31\x31\xE6\x97\xA5";
- break;
- case 0xAB :
- return "\x31\x32\xE6\x97\xA5";
- break;
- case 0xAC :
- return "\x31\x33\xE6\x97\xA5";
- break;
- case 0xAD :
- return "\x31\x34\xE6\x97\xA5";
- break;
- case 0xAE :
- return "\x31\x35\xE6\x97\xA5";
- break;
- case 0xAF :
- return "\x31\x36\xE6\x97\xA5";
- break;
- case 0xB0 :
- return "\x31\x37\xE6\x97\xA5";
- break;
- case 0xB1 :
- return "\x31\x38\xE6\x97\xA5";
- break;
- case 0xB2 :
- return "\x31\x39\xE6\x97\xA5";
- break;
- case 0xB3 :
- return "\x32\x30\xE6\x97\xA5";
- break;
- case 0xB4 :
- return "\x32\x31\xE6\x97\xA5";
- break;
- case 0xB5 :
- return "\x32\x32\xE6\x97\xA5";
- break;
- case 0xB6 :
- return "\x32\x33\xE6\x97\xA5";
- break;
- case 0xB7 :
- return "\x32\x34\xE6\x97\xA5";
- break;
- case 0xB8 :
- return "\x32\x35\xE6\x97\xA5";
- break;
- case 0xB9 :
- return "\x32\x36\xE6\x97\xA5";
- break;
- case 0xBA :
- return "\x32\x37\xE6\x97\xA5";
- break;
- case 0xBB :
- return "\x32\x38\xE6\x97\xA5";
- break;
- case 0xBC :
- return "\x32\x39\xE6\x97\xA5";
- break;
- case 0xBD :
- return "\x33\x30\xE6\x97\xA5";
- break;
- case 0xBE :
- return "\x33\x31\xE6\x97\xA5";
- break;
- case 0xBF :
- return "\x67\x61\x6C";
- break;
- }
- break;
- }
- break;
-case 0xEF :
- switch (str[1]) {
- case 0xA4 :
- switch (str[2]) {
- case 0x80 :
- return "\xE8\xB1\x88";
- break;
- case 0x81 :
- return "\xE6\x9B\xB4";
- break;
- case 0x82 :
- return "\xE8\xBB\x8A";
- break;
- case 0x83 :
- return "\xE8\xB3\x88";
- break;
- case 0x84 :
- return "\xE6\xBB\x91";
- break;
- case 0x85 :
- return "\xE4\xB8\xB2";
- break;
- case 0x86 :
- return "\xE5\x8F\xA5";
- break;
- case 0x87 :
- return "\xE9\xBE\x9C";
- break;
- case 0x88 :
- return "\xE9\xBE\x9C";
- break;
- case 0x89 :
- return "\xE5\xA5\x91";
- break;
- case 0x8A :
- return "\xE9\x87\x91";
- break;
- case 0x8B :
- return "\xE5\x96\x87";
- break;
- case 0x8C :
- return "\xE5\xA5\x88";
- break;
- case 0x8D :
- return "\xE6\x87\xB6";
- break;
- case 0x8E :
- return "\xE7\x99\xA9";
- break;
- case 0x8F :
- return "\xE7\xBE\x85";
- break;
- case 0x90 :
- return "\xE8\x98\xBF";
- break;
- case 0x91 :
- return "\xE8\x9E\xBA";
- break;
- case 0x92 :
- return "\xE8\xA3\xB8";
- break;
- case 0x93 :
- return "\xE9\x82\x8F";
- break;
- case 0x94 :
- return "\xE6\xA8\x82";
- break;
- case 0x95 :
- return "\xE6\xB4\x9B";
- break;
- case 0x96 :
- return "\xE7\x83\x99";
- break;
- case 0x97 :
- return "\xE7\x8F\x9E";
- break;
- case 0x98 :
- return "\xE8\x90\xBD";
- break;
- case 0x99 :
- return "\xE9\x85\xAA";
- break;
- case 0x9A :
- return "\xE9\xA7\xB1";
- break;
- case 0x9B :
- return "\xE4\xBA\x82";
- break;
- case 0x9C :
- return "\xE5\x8D\xB5";
- break;
- case 0x9D :
- return "\xE6\xAC\x84";
- break;
- case 0x9E :
- return "\xE7\x88\x9B";
- break;
- case 0x9F :
- return "\xE8\x98\xAD";
- break;
- case 0xA0 :
- return "\xE9\xB8\x9E";
- break;
- case 0xA1 :
- return "\xE5\xB5\x90";
- break;
- case 0xA2 :
- return "\xE6\xBF\xAB";
- break;
- case 0xA3 :
- return "\xE8\x97\x8D";
- break;
- case 0xA4 :
- return "\xE8\xA5\xA4";
- break;
- case 0xA5 :
- return "\xE6\x8B\x89";
- break;
- case 0xA6 :
- return "\xE8\x87\x98";
- break;
- case 0xA7 :
- return "\xE8\xA0\x9F";
- break;
- case 0xA8 :
- return "\xE5\xBB\x8A";
- break;
- case 0xA9 :
- return "\xE6\x9C\x97";
- break;
- case 0xAA :
- return "\xE6\xB5\xAA";
- break;
- case 0xAB :
- return "\xE7\x8B\xBC";
- break;
- case 0xAC :
- return "\xE9\x83\x8E";
- break;
- case 0xAD :
- return "\xE4\xBE\x86";
- break;
- case 0xAE :
- return "\xE5\x86\xB7";
- break;
- case 0xAF :
- return "\xE5\x8B\x9E";
- break;
- case 0xB0 :
- return "\xE6\x93\x84";
- break;
- case 0xB1 :
- return "\xE6\xAB\x93";
- break;
- case 0xB2 :
- return "\xE7\x88\x90";
- break;
- case 0xB3 :
- return "\xE7\x9B\xA7";
- break;
- case 0xB4 :
- return "\xE8\x80\x81";
- break;
- case 0xB5 :
- return "\xE8\x98\x86";
- break;
- case 0xB6 :
- return "\xE8\x99\x9C";
- break;
- case 0xB7 :
- return "\xE8\xB7\xAF";
- break;
- case 0xB8 :
- return "\xE9\x9C\xB2";
- break;
- case 0xB9 :
- return "\xE9\xAD\xAF";
- break;
- case 0xBA :
- return "\xE9\xB7\xBA";
- break;
- case 0xBB :
- return "\xE7\xA2\x8C";
- break;
- case 0xBC :
- return "\xE7\xA5\xBF";
- break;
- case 0xBD :
- return "\xE7\xB6\xA0";
- break;
- case 0xBE :
- return "\xE8\x8F\x89";
- break;
- case 0xBF :
- return "\xE9\x8C\x84";
- break;
- }
- break;
- case 0xA5 :
- switch (str[2]) {
- case 0x80 :
- return "\xE9\xB9\xBF";
- break;
- case 0x81 :
- return "\xE8\xAB\x96";
- break;
- case 0x82 :
- return "\xE5\xA3\x9F";
- break;
- case 0x83 :
- return "\xE5\xBC\x84";
- break;
- case 0x84 :
- return "\xE7\xB1\xA0";
- break;
- case 0x85 :
- return "\xE8\x81\xBE";
- break;
- case 0x86 :
- return "\xE7\x89\xA2";
- break;
- case 0x87 :
- return "\xE7\xA3\x8A";
- break;
- case 0x88 :
- return "\xE8\xB3\x82";
- break;
- case 0x89 :
- return "\xE9\x9B\xB7";
- break;
- case 0x8A :
- return "\xE5\xA3\x98";
- break;
- case 0x8B :
- return "\xE5\xB1\xA2";
- break;
- case 0x8C :
- return "\xE6\xA8\x93";
- break;
- case 0x8D :
- return "\xE6\xB7\x9A";
- break;
- case 0x8E :
- return "\xE6\xBC\x8F";
- break;
- case 0x8F :
- return "\xE7\xB4\xAF";
- break;
- case 0x90 :
- return "\xE7\xB8\xB7";
- break;
- case 0x91 :
- return "\xE9\x99\x8B";
- break;
- case 0x92 :
- return "\xE5\x8B\x92";
- break;
- case 0x93 :
- return "\xE8\x82\x8B";
- break;
- case 0x94 :
- return "\xE5\x87\x9C";
- break;
- case 0x95 :
- return "\xE5\x87\x8C";
- break;
- case 0x96 :
- return "\xE7\xA8\x9C";
- break;
- case 0x97 :
- return "\xE7\xB6\xBE";
- break;
- case 0x98 :
- return "\xE8\x8F\xB1";
- break;
- case 0x99 :
- return "\xE9\x99\xB5";
- break;
- case 0x9A :
- return "\xE8\xAE\x80";
- break;
- case 0x9B :
- return "\xE6\x8B\x8F";
- break;
- case 0x9C :
- return "\xE6\xA8\x82";
- break;
- case 0x9D :
- return "\xE8\xAB\xBE";
- break;
- case 0x9E :
- return "\xE4\xB8\xB9";
- break;
- case 0x9F :
- return "\xE5\xAF\xA7";
- break;
- case 0xA0 :
- return "\xE6\x80\x92";
- break;
- case 0xA1 :
- return "\xE7\x8E\x87";
- break;
- case 0xA2 :
- return "\xE7\x95\xB0";
- break;
- case 0xA3 :
- return "\xE5\x8C\x97";
- break;
- case 0xA4 :
- return "\xE7\xA3\xBB";
- break;
- case 0xA5 :
- return "\xE4\xBE\xBF";
- break;
- case 0xA6 :
- return "\xE5\xBE\xA9";
- break;
- case 0xA7 :
- return "\xE4\xB8\x8D";
- break;
- case 0xA8 :
- return "\xE6\xB3\x8C";
- break;
- case 0xA9 :
- return "\xE6\x95\xB8";
- break;
- case 0xAA :
- return "\xE7\xB4\xA2";
- break;
- case 0xAB :
- return "\xE5\x8F\x83";
- break;
- case 0xAC :
- return "\xE5\xA1\x9E";
- break;
- case 0xAD :
- return "\xE7\x9C\x81";
- break;
- case 0xAE :
- return "\xE8\x91\x89";
- break;
- case 0xAF :
- return "\xE8\xAA\xAA";
- break;
- case 0xB0 :
- return "\xE6\xAE\xBA";
- break;
- case 0xB1 :
- return "\xE8\xBE\xB0";
- break;
- case 0xB2 :
- return "\xE6\xB2\x88";
- break;
- case 0xB3 :
- return "\xE6\x8B\xBE";
- break;
- case 0xB4 :
- return "\xE8\x8B\xA5";
- break;
- case 0xB5 :
- return "\xE6\x8E\xA0";
- break;
- case 0xB6 :
- return "\xE7\x95\xA5";
- break;
- case 0xB7 :
- return "\xE4\xBA\xAE";
- break;
- case 0xB8 :
- return "\xE5\x85\xA9";
- break;
- case 0xB9 :
- return "\xE5\x87\x89";
- break;
- case 0xBA :
- return "\xE6\xA2\x81";
- break;
- case 0xBB :
- return "\xE7\xB3\xA7";
- break;
- case 0xBC :
- return "\xE8\x89\xAF";
- break;
- case 0xBD :
- return "\xE8\xAB\x92";
- break;
- case 0xBE :
- return "\xE9\x87\x8F";
- break;
- case 0xBF :
- return "\xE5\x8B\xB5";
- break;
- }
- break;
- case 0xA6 :
- switch (str[2]) {
- case 0x80 :
- return "\xE5\x91\x82";
- break;
- case 0x81 :
- return "\xE5\xA5\xB3";
- break;
- case 0x82 :
- return "\xE5\xBB\xAC";
- break;
- case 0x83 :
- return "\xE6\x97\x85";
- break;
- case 0x84 :
- return "\xE6\xBF\xBE";
- break;
- case 0x85 :
- return "\xE7\xA4\xAA";
- break;
- case 0x86 :
- return "\xE9\x96\xAD";
- break;
- case 0x87 :
- return "\xE9\xA9\xAA";
- break;
- case 0x88 :
- return "\xE9\xBA\x97";
- break;
- case 0x89 :
- return "\xE9\xBB\x8E";
- break;
- case 0x8A :
- return "\xE5\x8A\x9B";
- break;
- case 0x8B :
- return "\xE6\x9B\x86";
- break;
- case 0x8C :
- return "\xE6\xAD\xB7";
- break;
- case 0x8D :
- return "\xE8\xBD\xA2";
- break;
- case 0x8E :
- return "\xE5\xB9\xB4";
- break;
- case 0x8F :
- return "\xE6\x86\x90";
- break;
- case 0x90 :
- return "\xE6\x88\x80";
- break;
- case 0x91 :
- return "\xE6\x92\x9A";
- break;
- case 0x92 :
- return "\xE6\xBC\xA3";
- break;
- case 0x93 :
- return "\xE7\x85\x89";
- break;
- case 0x94 :
- return "\xE7\x92\x89";
- break;
- case 0x95 :
- return "\xE7\xA7\x8A";
- break;
- case 0x96 :
- return "\xE7\xB7\xB4";
- break;
- case 0x97 :
- return "\xE8\x81\xAF";
- break;
- case 0x98 :
- return "\xE8\xBC\xA6";
- break;
- case 0x99 :
- return "\xE8\x93\xAE";
- break;
- case 0x9A :
- return "\xE9\x80\xA3";
- break;
- case 0x9B :
- return "\xE9\x8D\x8A";
- break;
- case 0x9C :
- return "\xE5\x88\x97";
- break;
- case 0x9D :
- return "\xE5\x8A\xA3";
- break;
- case 0x9E :
- return "\xE5\x92\xBD";
- break;
- case 0x9F :
- return "\xE7\x83\x88";
- break;
- case 0xA0 :
- return "\xE8\xA3\x82";
- break;
- case 0xA1 :
- return "\xE8\xAA\xAA";
- break;
- case 0xA2 :
- return "\xE5\xBB\x89";
- break;
- case 0xA3 :
- return "\xE5\xBF\xB5";
- break;
- case 0xA4 :
- return "\xE6\x8D\xBB";
- break;
- case 0xA5 :
- return "\xE6\xAE\xAE";
- break;
- case 0xA6 :
- return "\xE7\xB0\xBE";
- break;
- case 0xA7 :
- return "\xE7\x8D\xB5";
- break;
- case 0xA8 :
- return "\xE4\xBB\xA4";
- break;
- case 0xA9 :
- return "\xE5\x9B\xB9";
- break;
- case 0xAA :
- return "\xE5\xAF\xA7";
- break;
- case 0xAB :
- return "\xE5\xB6\xBA";
- break;
- case 0xAC :
- return "\xE6\x80\x9C";
- break;
- case 0xAD :
- return "\xE7\x8E\xB2";
- break;
- case 0xAE :
- return "\xE7\x91\xA9";
- break;
- case 0xAF :
- return "\xE7\xBE\x9A";
- break;
- case 0xB0 :
- return "\xE8\x81\x86";
- break;
- case 0xB1 :
- return "\xE9\x88\xB4";
- break;
- case 0xB2 :
- return "\xE9\x9B\xB6";
- break;
- case 0xB3 :
- return "\xE9\x9D\x88";
- break;
- case 0xB4 :
- return "\xE9\xA0\x98";
- break;
- case 0xB5 :
- return "\xE4\xBE\x8B";
- break;
- case 0xB6 :
- return "\xE7\xA6\xAE";
- break;
- case 0xB7 :
- return "\xE9\x86\xB4";
- break;
- case 0xB8 :
- return "\xE9\x9A\xB8";
- break;
- case 0xB9 :
- return "\xE6\x83\xA1";
- break;
- case 0xBA :
- return "\xE4\xBA\x86";
- break;
- case 0xBB :
- return "\xE5\x83\x9A";
- break;
- case 0xBC :
- return "\xE5\xAF\xAE";
- break;
- case 0xBD :
- return "\xE5\xB0\xBF";
- break;
- case 0xBE :
- return "\xE6\x96\x99";
- break;
- case 0xBF :
- return "\xE6\xA8\x82";
- break;
- }
- break;
- case 0xA7 :
- switch (str[2]) {
- case 0x80 :
- return "\xE7\x87\x8E";
- break;
- case 0x81 :
- return "\xE7\x99\x82";
- break;
- case 0x82 :
- return "\xE8\x93\xBC";
- break;
- case 0x83 :
- return "\xE9\x81\xBC";
- break;
- case 0x84 :
- return "\xE9\xBE\x8D";
- break;
- case 0x85 :
- return "\xE6\x9A\x88";
- break;
- case 0x86 :
- return "\xE9\x98\xAE";
- break;
- case 0x87 :
- return "\xE5\x8A\x89";
- break;
- case 0x88 :
- return "\xE6\x9D\xBB";
- break;
- case 0x89 :
- return "\xE6\x9F\xB3";
- break;
- case 0x8A :
- return "\xE6\xB5\x81";
- break;
- case 0x8B :
- return "\xE6\xBA\x9C";
- break;
- case 0x8C :
- return "\xE7\x90\x89";
- break;
- case 0x8D :
- return "\xE7\x95\x99";
- break;
- case 0x8E :
- return "\xE7\xA1\xAB";
- break;
- case 0x8F :
- return "\xE7\xB4\x90";
- break;
- case 0x90 :
- return "\xE9\xA1\x9E";
- break;
- case 0x91 :
- return "\xE5\x85\xAD";
- break;
- case 0x92 :
- return "\xE6\x88\xAE";
- break;
- case 0x93 :
- return "\xE9\x99\xB8";
- break;
- case 0x94 :
- return "\xE5\x80\xAB";
- break;
- case 0x95 :
- return "\xE5\xB4\x99";
- break;
- case 0x96 :
- return "\xE6\xB7\xAA";
- break;
- case 0x97 :
- return "\xE8\xBC\xAA";
- break;
- case 0x98 :
- return "\xE5\xBE\x8B";
- break;
- case 0x99 :
- return "\xE6\x85\x84";
- break;
- case 0x9A :
- return "\xE6\xA0\x97";
- break;
- case 0x9B :
- return "\xE7\x8E\x87";
- break;
- case 0x9C :
- return "\xE9\x9A\x86";
- break;
- case 0x9D :
- return "\xE5\x88\xA9";
- break;
- case 0x9E :
- return "\xE5\x90\x8F";
- break;
- case 0x9F :
- return "\xE5\xB1\xA5";
- break;
- case 0xA0 :
- return "\xE6\x98\x93";
- break;
- case 0xA1 :
- return "\xE6\x9D\x8E";
- break;
- case 0xA2 :
- return "\xE6\xA2\xA8";
- break;
- case 0xA3 :
- return "\xE6\xB3\xA5";
- break;
- case 0xA4 :
- return "\xE7\x90\x86";
- break;
- case 0xA5 :
- return "\xE7\x97\xA2";
- break;
- case 0xA6 :
- return "\xE7\xBD\xB9";
- break;
- case 0xA7 :
- return "\xE8\xA3\x8F";
- break;
- case 0xA8 :
- return "\xE8\xA3\xA1";
- break;
- case 0xA9 :
- return "\xE9\x87\x8C";
- break;
- case 0xAA :
- return "\xE9\x9B\xA2";
- break;
- case 0xAB :
- return "\xE5\x8C\xBF";
- break;
- case 0xAC :
- return "\xE6\xBA\xBA";
- break;
- case 0xAD :
- return "\xE5\x90\x9D";
- break;
- case 0xAE :
- return "\xE7\x87\x90";
- break;
- case 0xAF :
- return "\xE7\x92\x98";
- break;
- case 0xB0 :
- return "\xE8\x97\xBA";
- break;
- case 0xB1 :
- return "\xE9\x9A\xA3";
- break;
- case 0xB2 :
- return "\xE9\xB1\x97";
- break;
- case 0xB3 :
- return "\xE9\xBA\x9F";
- break;
- case 0xB4 :
- return "\xE6\x9E\x97";
- break;
- case 0xB5 :
- return "\xE6\xB7\x8B";
- break;
- case 0xB6 :
- return "\xE8\x87\xA8";
- break;
- case 0xB7 :
- return "\xE7\xAB\x8B";
- break;
- case 0xB8 :
- return "\xE7\xAC\xA0";
- break;
- case 0xB9 :
- return "\xE7\xB2\x92";
- break;
- case 0xBA :
- return "\xE7\x8B\x80";
- break;
- case 0xBB :
- return "\xE7\x82\x99";
- break;
- case 0xBC :
- return "\xE8\xAD\x98";
- break;
- case 0xBD :
- return "\xE4\xBB\x80";
- break;
- case 0xBE :
- return "\xE8\x8C\xB6";
- break;
- case 0xBF :
- return "\xE5\x88\xBA";
- break;
- }
- break;
- case 0xA8 :
- switch (str[2]) {
- case 0x80 :
- return "\xE5\x88\x87";
- break;
- case 0x81 :
- return "\xE5\xBA\xA6";
- break;
- case 0x82 :
- return "\xE6\x8B\x93";
- break;
- case 0x83 :
- return "\xE7\xB3\x96";
- break;
- case 0x84 :
- return "\xE5\xAE\x85";
- break;
- case 0x85 :
- return "\xE6\xB4\x9E";
- break;
- case 0x86 :
- return "\xE6\x9A\xB4";
- break;
- case 0x87 :
- return "\xE8\xBC\xBB";
- break;
- case 0x88 :
- return "\xE8\xA1\x8C";
- break;
- case 0x89 :
- return "\xE9\x99\x8D";
- break;
- case 0x8A :
- return "\xE8\xA6\x8B";
- break;
- case 0x8B :
- return "\xE5\xBB\x93";
- break;
- case 0x8C :
- return "\xE5\x85\x80";
- break;
- case 0x8D :
- return "\xE5\x97\x80";
- break;
- case 0x90 :
- return "\xE5\xA1\x9A";
- break;
- case 0x92 :
- return "\xE6\x99\xB4";
- break;
- case 0x95 :
- return "\xE5\x87\x9E";
- break;
- case 0x96 :
- return "\xE7\x8C\xAA";
- break;
- case 0x97 :
- return "\xE7\x9B\x8A";
- break;
- case 0x98 :
- return "\xE7\xA4\xBC";
- break;
- case 0x99 :
- return "\xE7\xA5\x9E";
- break;
- case 0x9A :
- return "\xE7\xA5\xA5";
- break;
- case 0x9B :
- return "\xE7\xA6\x8F";
- break;
- case 0x9C :
- return "\xE9\x9D\x96";
- break;
- case 0x9D :
- return "\xE7\xB2\xBE";
- break;
- case 0x9E :
- return "\xE7\xBE\xBD";
- break;
- case 0xA0 :
- return "\xE8\x98\x92";
- break;
- case 0xA2 :
- return "\xE8\xAB\xB8";
- break;
- case 0xA5 :
- return "\xE9\x80\xB8";
- break;
- case 0xA6 :
- return "\xE9\x83\xBD";
- break;
- case 0xAA :
- return "\xE9\xA3\xAF";
- break;
- case 0xAB :
- return "\xE9\xA3\xBC";
- break;
- case 0xAC :
- return "\xE9\xA4\xA8";
- break;
- case 0xAD :
- return "\xE9\xB6\xB4";
- break;
- case 0xB0 :
- return "\xE4\xBE\xAE";
- break;
- case 0xB1 :
- return "\xE5\x83\xA7";
- break;
- case 0xB2 :
- return "\xE5\x85\x8D";
- break;
- case 0xB3 :
- return "\xE5\x8B\x89";
- break;
- case 0xB4 :
- return "\xE5\x8B\xA4";
- break;
- case 0xB5 :
- return "\xE5\x8D\x91";
- break;
- case 0xB6 :
- return "\xE5\x96\x9D";
- break;
- case 0xB7 :
- return "\xE5\x98\x86";
- break;
- case 0xB8 :
- return "\xE5\x99\xA8";
- break;
- case 0xB9 :
- return "\xE5\xA1\x80";
- break;
- case 0xBA :
- return "\xE5\xA2\xA8";
- break;
- case 0xBB :
- return "\xE5\xB1\xA4";
- break;
- case 0xBC :
- return "\xE5\xB1\xAE";
- break;
- case 0xBD :
- return "\xE6\x82\x94";
- break;
- case 0xBE :
- return "\xE6\x85\xA8";
- break;
- case 0xBF :
- return "\xE6\x86\x8E";
- break;
- }
- break;
- case 0xA9 :
- switch (str[2]) {
- case 0x80 :
- return "\xE6\x87\xB2";
- break;
- case 0x81 :
- return "\xE6\x95\x8F";
- break;
- case 0x82 :
- return "\xE6\x97\xA2";
- break;
- case 0x83 :
- return "\xE6\x9A\x91";
- break;
- case 0x84 :
- return "\xE6\xA2\x85";
- break;
- case 0x85 :
- return "\xE6\xB5\xB7";
- break;
- case 0x86 :
- return "\xE6\xB8\x9A";
- break;
- case 0x87 :
- return "\xE6\xBC\xA2";
- break;
- case 0x88 :
- return "\xE7\x85\xAE";
- break;
- case 0x89 :
- return "\xE7\x88\xAB";
- break;
- case 0x8A :
- return "\xE7\x90\xA2";
- break;
- case 0x8B :
- return "\xE7\xA2\x91";
- break;
- case 0x8C :
- return "\xE7\xA4\xBE";
- break;
- case 0x8D :
- return "\xE7\xA5\x89";
- break;
- case 0x8E :
- return "\xE7\xA5\x88";
- break;
- case 0x8F :
- return "\xE7\xA5\x90";
- break;
- case 0x90 :
- return "\xE7\xA5\x96";
- break;
- case 0x91 :
- return "\xE7\xA5\x9D";
- break;
- case 0x92 :
- return "\xE7\xA6\x8D";
- break;
- case 0x93 :
- return "\xE7\xA6\x8E";
- break;
- case 0x94 :
- return "\xE7\xA9\x80";
- break;
- case 0x95 :
- return "\xE7\xAA\x81";
- break;
- case 0x96 :
- return "\xE7\xAF\x80";
- break;
- case 0x97 :
- return "\xE7\xB7\xB4";
- break;
- case 0x98 :
- return "\xE7\xB8\x89";
- break;
- case 0x99 :
- return "\xE7\xB9\x81";
- break;
- case 0x9A :
- return "\xE7\xBD\xB2";
- break;
- case 0x9B :
- return "\xE8\x80\x85";
- break;
- case 0x9C :
- return "\xE8\x87\xAD";
- break;
- case 0x9D :
- return "\xE8\x89\xB9";
- break;
- case 0x9E :
- return "\xE8\x89\xB9";
- break;
- case 0x9F :
- return "\xE8\x91\x97";
- break;
- case 0xA0 :
- return "\xE8\xA4\x90";
- break;
- case 0xA1 :
- return "\xE8\xA6\x96";
- break;
- case 0xA2 :
- return "\xE8\xAC\x81";
- break;
- case 0xA3 :
- return "\xE8\xAC\xB9";
- break;
- case 0xA4 :
- return "\xE8\xB3\x93";
- break;
- case 0xA5 :
- return "\xE8\xB4\x88";
- break;
- case 0xA6 :
- return "\xE8\xBE\xB6";
- break;
- case 0xA7 :
- return "\xE9\x80\xB8";
- break;
- case 0xA8 :
- return "\xE9\x9B\xA3";
- break;
- case 0xA9 :
- return "\xE9\x9F\xBF";
- break;
- case 0xAA :
- return "\xE9\xA0\xBB";
- break;
- case 0xB0 :
- return "\xE4\xB8\xA6";
- break;
- case 0xB1 :
- return "\xE5\x86\xB5";
- break;
- case 0xB2 :
- return "\xE5\x85\xA8";
- break;
- case 0xB3 :
- return "\xE4\xBE\x80";
- break;
- case 0xB4 :
- return "\xE5\x85\x85";
- break;
- case 0xB5 :
- return "\xE5\x86\x80";
- break;
- case 0xB6 :
- return "\xE5\x8B\x87";
- break;
- case 0xB7 :
- return "\xE5\x8B\xBA";
- break;
- case 0xB8 :
- return "\xE5\x96\x9D";
- break;
- case 0xB9 :
- return "\xE5\x95\x95";
- break;
- case 0xBA :
- return "\xE5\x96\x99";
- break;
- case 0xBB :
- return "\xE5\x97\xA2";
- break;
- case 0xBC :
- return "\xE5\xA1\x9A";
- break;
- case 0xBD :
- return "\xE5\xA2\xB3";
- break;
- case 0xBE :
- return "\xE5\xA5\x84";
- break;
- case 0xBF :
- return "\xE5\xA5\x94";
- break;
- }
- break;
- case 0xAA :
- switch (str[2]) {
- case 0x80 :
- return "\xE5\xA9\xA2";
- break;
- case 0x81 :
- return "\xE5\xAC\xA8";
- break;
- case 0x82 :
- return "\xE5\xBB\x92";
- break;
- case 0x83 :
- return "\xE5\xBB\x99";
- break;
- case 0x84 :
- return "\xE5\xBD\xA9";
- break;
- case 0x85 :
- return "\xE5\xBE\xAD";
- break;
- case 0x86 :
- return "\xE6\x83\x98";
- break;
- case 0x87 :
- return "\xE6\x85\x8E";
- break;
- case 0x88 :
- return "\xE6\x84\x88";
- break;
- case 0x89 :
- return "\xE6\x86\x8E";
- break;
- case 0x8A :
- return "\xE6\x85\xA0";
- break;
- case 0x8B :
- return "\xE6\x87\xB2";
- break;
- case 0x8C :
- return "\xE6\x88\xB4";
- break;
- case 0x8D :
- return "\xE6\x8F\x84";
- break;
- case 0x8E :
- return "\xE6\x90\x9C";
- break;
- case 0x8F :
- return "\xE6\x91\x92";
- break;
- case 0x90 :
- return "\xE6\x95\x96";
- break;
- case 0x91 :
- return "\xE6\x99\xB4";
- break;
- case 0x92 :
- return "\xE6\x9C\x97";
- break;
- case 0x93 :
- return "\xE6\x9C\x9B";
- break;
- case 0x94 :
- return "\xE6\x9D\x96";
- break;
- case 0x95 :
- return "\xE6\xAD\xB9";
- break;
- case 0x96 :
- return "\xE6\xAE\xBA";
- break;
- case 0x97 :
- return "\xE6\xB5\x81";
- break;
- case 0x98 :
- return "\xE6\xBB\x9B";
- break;
- case 0x99 :
- return "\xE6\xBB\x8B";
- break;
- case 0x9A :
- return "\xE6\xBC\xA2";
- break;
- case 0x9B :
- return "\xE7\x80\x9E";
- break;
- case 0x9C :
- return "\xE7\x85\xAE";
- break;
- case 0x9D :
- return "\xE7\x9E\xA7";
- break;
- case 0x9E :
- return "\xE7\x88\xB5";
- break;
- case 0x9F :
- return "\xE7\x8A\xAF";
- break;
- case 0xA0 :
- return "\xE7\x8C\xAA";
- break;
- case 0xA1 :
- return "\xE7\x91\xB1";
- break;
- case 0xA2 :
- return "\xE7\x94\x86";
- break;
- case 0xA3 :
- return "\xE7\x94\xBB";
- break;
- case 0xA4 :
- return "\xE7\x98\x9D";
- break;
- case 0xA5 :
- return "\xE7\x98\x9F";
- break;
- case 0xA6 :
- return "\xE7\x9B\x8A";
- break;
- case 0xA7 :
- return "\xE7\x9B\x9B";
- break;
- case 0xA8 :
- return "\xE7\x9B\xB4";
- break;
- case 0xA9 :
- return "\xE7\x9D\x8A";
- break;
- case 0xAA :
- return "\xE7\x9D\x80";
- break;
- case 0xAB :
- return "\xE7\xA3\x8C";
- break;
- case 0xAC :
- return "\xE7\xAA\xB1";
- break;
- case 0xAD :
- return "\xE7\xAF\x80";
- break;
- case 0xAE :
- return "\xE7\xB1\xBB";
- break;
- case 0xAF :
- return "\xE7\xB5\x9B";
- break;
- case 0xB0 :
- return "\xE7\xB7\xB4";
- break;
- case 0xB1 :
- return "\xE7\xBC\xBE";
- break;
- case 0xB2 :
- return "\xE8\x80\x85";
- break;
- case 0xB3 :
- return "\xE8\x8D\x92";
- break;
- case 0xB4 :
- return "\xE8\x8F\xAF";
- break;
- case 0xB5 :
- return "\xE8\x9D\xB9";
- break;
- case 0xB6 :
- return "\xE8\xA5\x81";
- break;
- case 0xB7 :
- return "\xE8\xA6\x86";
- break;
- case 0xB8 :
- return "\xE8\xA6\x96";
- break;
- case 0xB9 :
- return "\xE8\xAA\xBF";
- break;
- case 0xBA :
- return "\xE8\xAB\xB8";
- break;
- case 0xBB :
- return "\xE8\xAB\x8B";
- break;
- case 0xBC :
- return "\xE8\xAC\x81";
- break;
- case 0xBD :
- return "\xE8\xAB\xBE";
- break;
- case 0xBE :
- return "\xE8\xAB\xAD";
- break;
- case 0xBF :
- return "\xE8\xAC\xB9";
- break;
- }
- break;
- case 0xAB :
- switch (str[2]) {
- case 0x80 :
- return "\xE8\xAE\x8A";
- break;
- case 0x81 :
- return "\xE8\xB4\x88";
- break;
- case 0x82 :
- return "\xE8\xBC\xB8";
- break;
- case 0x83 :
- return "\xE9\x81\xB2";
- break;
- case 0x84 :
- return "\xE9\x86\x99";
- break;
- case 0x85 :
- return "\xE9\x89\xB6";
- break;
- case 0x86 :
- return "\xE9\x99\xBC";
- break;
- case 0x87 :
- return "\xE9\x9B\xA3";
- break;
- case 0x88 :
- return "\xE9\x9D\x96";
- break;
- case 0x89 :
- return "\xE9\x9F\x9B";
- break;
- case 0x8A :
- return "\xE9\x9F\xBF";
- break;
- case 0x8B :
- return "\xE9\xA0\x8B";
- break;
- case 0x8C :
- return "\xE9\xA0\xBB";
- break;
- case 0x8D :
- return "\xE9\xAC\x92";
- break;
- case 0x8E :
- return "\xE9\xBE\x9C";
- break;
- case 0x8F :
- return "\xF0\xA2\xA1\x8A";
- break;
- case 0x90 :
- return "\xF0\xA2\xA1\x84";
- break;
- case 0x91 :
- return "\xF0\xA3\x8F\x95";
- break;
- case 0x92 :
- return "\xE3\xAE\x9D";
- break;
- case 0x93 :
- return "\xE4\x80\x98";
- break;
- case 0x94 :
- return "\xE4\x80\xB9";
- break;
- case 0x95 :
- return "\xF0\xA5\x89\x89";
- break;
- case 0x96 :
- return "\xF0\xA5\xB3\x90";
- break;
- case 0x97 :
- return "\xF0\xA7\xBB\x93";
- break;
- case 0x98 :
- return "\xE9\xBD\x83";
- break;
- case 0x99 :
- return "\xE9\xBE\x8E";
- break;
- }
- break;
- case 0xAC :
- switch (str[2]) {
- case 0x80 :
- return "\x66\x66";
- break;
- case 0x81 :
- return "\x66\x69";
- break;
- case 0x82 :
- return "\x66\x6C";
- break;
- case 0x83 :
- return "\x66\x66\x69";
- break;
- case 0x84 :
- return "\x66\x66\x6C";
- break;
- case 0x85 :
- return "\x73\x74";
- break;
- case 0x86 :
- return "\x73\x74";
- break;
- case 0x93 :
- return "\xD5\xB4\xD5\xB6";
- break;
- case 0x94 :
- return "\xD5\xB4\xD5\xA5";
- break;
- case 0x95 :
- return "\xD5\xB4\xD5\xAB";
- break;
- case 0x96 :
- return "\xD5\xBE\xD5\xB6";
- break;
- case 0x97 :
- return "\xD5\xB4\xD5\xAD";
- break;
- case 0x9D :
- return "\xD7\x99\xD6\xB4";
- break;
- case 0x9F :
- return "\xD7\xB2\xD6\xB7";
- break;
- case 0xA0 :
- return "\xD7\xA2";
- break;
- case 0xA1 :
- return "\xD7\x90";
- break;
- case 0xA2 :
- return "\xD7\x93";
- break;
- case 0xA3 :
- return "\xD7\x94";
- break;
- case 0xA4 :
- return "\xD7\x9B";
- break;
- case 0xA5 :
- return "\xD7\x9C";
- break;
- case 0xA6 :
- return "\xD7\x9D";
- break;
- case 0xA7 :
- return "\xD7\xA8";
- break;
- case 0xA8 :
- return "\xD7\xAA";
- break;
- case 0xA9 :
- return "\x2B";
- break;
- case 0xAA :
- return "\xD7\xA9\xD7\x81";
- break;
- case 0xAB :
- return "\xD7\xA9\xD7\x82";
- break;
- case 0xAC :
- return "\xD7\xA9\xD6\xBC\xD7\x81";
- break;
- case 0xAD :
- return "\xD7\xA9\xD6\xBC\xD7\x82";
- break;
- case 0xAE :
- return "\xD7\x90\xD6\xB7";
- break;
- case 0xAF :
- return "\xD7\x90\xD6\xB8";
- break;
- case 0xB0 :
- return "\xD7\x90\xD6\xBC";
- break;
- case 0xB1 :
- return "\xD7\x91\xD6\xBC";
- break;
- case 0xB2 :
- return "\xD7\x92\xD6\xBC";
- break;
- case 0xB3 :
- return "\xD7\x93\xD6\xBC";
- break;
- case 0xB4 :
- return "\xD7\x94\xD6\xBC";
- break;
- case 0xB5 :
- return "\xD7\x95\xD6\xBC";
- break;
- case 0xB6 :
- return "\xD7\x96\xD6\xBC";
- break;
- case 0xB8 :
- return "\xD7\x98\xD6\xBC";
- break;
- case 0xB9 :
- return "\xD7\x99\xD6\xBC";
- break;
- case 0xBA :
- return "\xD7\x9A\xD6\xBC";
- break;
- case 0xBB :
- return "\xD7\x9B\xD6\xBC";
- break;
- case 0xBC :
- return "\xD7\x9C\xD6\xBC";
- break;
- case 0xBE :
- return "\xD7\x9E\xD6\xBC";
- break;
- }
- break;
- case 0xAD :
- switch (str[2]) {
- case 0x80 :
- return "\xD7\xA0\xD6\xBC";
- break;
- case 0x81 :
- return "\xD7\xA1\xD6\xBC";
- break;
- case 0x83 :
- return "\xD7\xA3\xD6\xBC";
- break;
- case 0x84 :
- return "\xD7\xA4\xD6\xBC";
- break;
- case 0x86 :
- return "\xD7\xA6\xD6\xBC";
- break;
- case 0x87 :
- return "\xD7\xA7\xD6\xBC";
- break;
- case 0x88 :
- return "\xD7\xA8\xD6\xBC";
- break;
- case 0x89 :
- return "\xD7\xA9\xD6\xBC";
- break;
- case 0x8A :
- return "\xD7\xAA\xD6\xBC";
- break;
- case 0x8B :
- return "\xD7\x95\xD6\xB9";
- break;
- case 0x8C :
- return "\xD7\x91\xD6\xBF";
- break;
- case 0x8D :
- return "\xD7\x9B\xD6\xBF";
- break;
- case 0x8E :
- return "\xD7\xA4\xD6\xBF";
- break;
- case 0x8F :
- return "\xD7\x90\xD7\x9C";
- break;
- case 0x90 :
- return "\xD9\xB1";
- break;
- case 0x91 :
- return "\xD9\xB1";
- break;
- case 0x92 :
- return "\xD9\xBB";
- break;
- case 0x93 :
- return "\xD9\xBB";
- break;
- case 0x94 :
- return "\xD9\xBB";
- break;
- case 0x95 :
- return "\xD9\xBB";
- break;
- case 0x96 :
- return "\xD9\xBE";
- break;
- case 0x97 :
- return "\xD9\xBE";
- break;
- case 0x98 :
- return "\xD9\xBE";
- break;
- case 0x99 :
- return "\xD9\xBE";
- break;
- case 0x9A :
- return "\xDA\x80";
- break;
- case 0x9B :
- return "\xDA\x80";
- break;
- case 0x9C :
- return "\xDA\x80";
- break;
- case 0x9D :
- return "\xDA\x80";
- break;
- case 0x9E :
- return "\xD9\xBA";
- break;
- case 0x9F :
- return "\xD9\xBA";
- break;
- case 0xA0 :
- return "\xD9\xBA";
- break;
- case 0xA1 :
- return "\xD9\xBA";
- break;
- case 0xA2 :
- return "\xD9\xBF";
- break;
- case 0xA3 :
- return "\xD9\xBF";
- break;
- case 0xA4 :
- return "\xD9\xBF";
- break;
- case 0xA5 :
- return "\xD9\xBF";
- break;
- case 0xA6 :
- return "\xD9\xB9";
- break;
- case 0xA7 :
- return "\xD9\xB9";
- break;
- case 0xA8 :
- return "\xD9\xB9";
- break;
- case 0xA9 :
- return "\xD9\xB9";
- break;
- case 0xAA :
- return "\xDA\xA4";
- break;
- case 0xAB :
- return "\xDA\xA4";
- break;
- case 0xAC :
- return "\xDA\xA4";
- break;
- case 0xAD :
- return "\xDA\xA4";
- break;
- case 0xAE :
- return "\xDA\xA6";
- break;
- case 0xAF :
- return "\xDA\xA6";
- break;
- case 0xB0 :
- return "\xDA\xA6";
- break;
- case 0xB1 :
- return "\xDA\xA6";
- break;
- case 0xB2 :
- return "\xDA\x84";
- break;
- case 0xB3 :
- return "\xDA\x84";
- break;
- case 0xB4 :
- return "\xDA\x84";
- break;
- case 0xB5 :
- return "\xDA\x84";
- break;
- case 0xB6 :
- return "\xDA\x83";
- break;
- case 0xB7 :
- return "\xDA\x83";
- break;
- case 0xB8 :
- return "\xDA\x83";
- break;
- case 0xB9 :
- return "\xDA\x83";
- break;
- case 0xBA :
- return "\xDA\x86";
- break;
- case 0xBB :
- return "\xDA\x86";
- break;
- case 0xBC :
- return "\xDA\x86";
- break;
- case 0xBD :
- return "\xDA\x86";
- break;
- case 0xBE :
- return "\xDA\x87";
- break;
- case 0xBF :
- return "\xDA\x87";
- break;
- }
- break;
- case 0xAE :
- switch (str[2]) {
- case 0x80 :
- return "\xDA\x87";
- break;
- case 0x81 :
- return "\xDA\x87";
- break;
- case 0x82 :
- return "\xDA\x8D";
- break;
- case 0x83 :
- return "\xDA\x8D";
- break;
- case 0x84 :
- return "\xDA\x8C";
- break;
- case 0x85 :
- return "\xDA\x8C";
- break;
- case 0x86 :
- return "\xDA\x8E";
- break;
- case 0x87 :
- return "\xDA\x8E";
- break;
- case 0x88 :
- return "\xDA\x88";
- break;
- case 0x89 :
- return "\xDA\x88";
- break;
- case 0x8A :
- return "\xDA\x98";
- break;
- case 0x8B :
- return "\xDA\x98";
- break;
- case 0x8C :
- return "\xDA\x91";
- break;
- case 0x8D :
- return "\xDA\x91";
- break;
- case 0x8E :
- return "\xDA\xA9";
- break;
- case 0x8F :
- return "\xDA\xA9";
- break;
- case 0x90 :
- return "\xDA\xA9";
- break;
- case 0x91 :
- return "\xDA\xA9";
- break;
- case 0x92 :
- return "\xDA\xAF";
- break;
- case 0x93 :
- return "\xDA\xAF";
- break;
- case 0x94 :
- return "\xDA\xAF";
- break;
- case 0x95 :
- return "\xDA\xAF";
- break;
- case 0x96 :
- return "\xDA\xB3";
- break;
- case 0x97 :
- return "\xDA\xB3";
- break;
- case 0x98 :
- return "\xDA\xB3";
- break;
- case 0x99 :
- return "\xDA\xB3";
- break;
- case 0x9A :
- return "\xDA\xB1";
- break;
- case 0x9B :
- return "\xDA\xB1";
- break;
- case 0x9C :
- return "\xDA\xB1";
- break;
- case 0x9D :
- return "\xDA\xB1";
- break;
- case 0x9E :
- return "\xDA\xBA";
- break;
- case 0x9F :
- return "\xDA\xBA";
- break;
- case 0xA0 :
- return "\xDA\xBB";
- break;
- case 0xA1 :
- return "\xDA\xBB";
- break;
- case 0xA2 :
- return "\xDA\xBB";
- break;
- case 0xA3 :
- return "\xDA\xBB";
- break;
- case 0xA4 :
- return "\xDB\x80";
- break;
- case 0xA5 :
- return "\xDB\x80";
- break;
- case 0xA6 :
- return "\xDB\x81";
- break;
- case 0xA7 :
- return "\xDB\x81";
- break;
- case 0xA8 :
- return "\xDB\x81";
- break;
- case 0xA9 :
- return "\xDB\x81";
- break;
- case 0xAA :
- return "\xDA\xBE";
- break;
- case 0xAB :
- return "\xDA\xBE";
- break;
- case 0xAC :
- return "\xDA\xBE";
- break;
- case 0xAD :
- return "\xDA\xBE";
- break;
- case 0xAE :
- return "\xDB\x92";
- break;
- case 0xAF :
- return "\xDB\x92";
- break;
- case 0xB0 :
- return "\xDB\x93";
- break;
- case 0xB1 :
- return "\xDB\x93";
- break;
- }
- break;
- case 0xAF :
- switch (str[2]) {
- case 0x93 :
- return "\xDA\xAD";
- break;
- case 0x94 :
- return "\xDA\xAD";
- break;
- case 0x95 :
- return "\xDA\xAD";
- break;
- case 0x96 :
- return "\xDA\xAD";
- break;
- case 0x97 :
- return "\xDB\x87";
- break;
- case 0x98 :
- return "\xDB\x87";
- break;
- case 0x99 :
- return "\xDB\x86";
- break;
- case 0x9A :
- return "\xDB\x86";
- break;
- case 0x9B :
- return "\xDB\x88";
- break;
- case 0x9C :
- return "\xDB\x88";
- break;
- case 0x9D :
- return "\xDB\x87\xD9\xB4";
- break;
- case 0x9E :
- return "\xDB\x8B";
- break;
- case 0x9F :
- return "\xDB\x8B";
- break;
- case 0xA0 :
- return "\xDB\x85";
- break;
- case 0xA1 :
- return "\xDB\x85";
- break;
- case 0xA2 :
- return "\xDB\x89";
- break;
- case 0xA3 :
- return "\xDB\x89";
- break;
- case 0xA4 :
- return "\xDB\x90";
- break;
- case 0xA5 :
- return "\xDB\x90";
- break;
- case 0xA6 :
- return "\xDB\x90";
- break;
- case 0xA7 :
- return "\xDB\x90";
- break;
- case 0xA8 :
- return "\xD9\x89";
- break;
- case 0xA9 :
- return "\xD9\x89";
- break;
- case 0xAA :
- return "\xD8\xA6\xD8\xA7";
- break;
- case 0xAB :
- return "\xD8\xA6\xD8\xA7";
- break;
- case 0xAC :
- return "\xD8\xA6\xDB\x95";
- break;
- case 0xAD :
- return "\xD8\xA6\xDB\x95";
- break;
- case 0xAE :
- return "\xD8\xA6\xD9\x88";
- break;
- case 0xAF :
- return "\xD8\xA6\xD9\x88";
- break;
- case 0xB0 :
- return "\xD8\xA6\xDB\x87";
- break;
- case 0xB1 :
- return "\xD8\xA6\xDB\x87";
- break;
- case 0xB2 :
- return "\xD8\xA6\xDB\x86";
- break;
- case 0xB3 :
- return "\xD8\xA6\xDB\x86";
- break;
- case 0xB4 :
- return "\xD8\xA6\xDB\x88";
- break;
- case 0xB5 :
- return "\xD8\xA6\xDB\x88";
- break;
- case 0xB6 :
- return "\xD8\xA6\xDB\x90";
- break;
- case 0xB7 :
- return "\xD8\xA6\xDB\x90";
- break;
- case 0xB8 :
- return "\xD8\xA6\xDB\x90";
- break;
- case 0xB9 :
- return "\xD8\xA6\xD9\x89";
- break;
- case 0xBA :
- return "\xD8\xA6\xD9\x89";
- break;
- case 0xBB :
- return "\xD8\xA6\xD9\x89";
- break;
- case 0xBC :
- return "\xDB\x8C";
- break;
- case 0xBD :
- return "\xDB\x8C";
- break;
- case 0xBE :
- return "\xDB\x8C";
- break;
- case 0xBF :
- return "\xDB\x8C";
- break;
- }
- break;
- case 0xB0 :
- switch (str[2]) {
- case 0x80 :
- return "\xD8\xA6\xD8\xAC";
- break;
- case 0x81 :
- return "\xD8\xA6\xD8\xAD";
- break;
- case 0x82 :
- return "\xD8\xA6\xD9\x85";
- break;
- case 0x83 :
- return "\xD8\xA6\xD9\x89";
- break;
- case 0x84 :
- return "\xD8\xA6\xD9\x8A";
- break;
- case 0x85 :
- return "\xD8\xA8\xD8\xAC";
- break;
- case 0x86 :
- return "\xD8\xA8\xD8\xAD";
- break;
- case 0x87 :
- return "\xD8\xA8\xD8\xAE";
- break;
- case 0x88 :
- return "\xD8\xA8\xD9\x85";
- break;
- case 0x89 :
- return "\xD8\xA8\xD9\x89";
- break;
- case 0x8A :
- return "\xD8\xA8\xD9\x8A";
- break;
- case 0x8B :
- return "\xD8\xAA\xD8\xAC";
- break;
- case 0x8C :
- return "\xD8\xAA\xD8\xAD";
- break;
- case 0x8D :
- return "\xD8\xAA\xD8\xAE";
- break;
- case 0x8E :
- return "\xD8\xAA\xD9\x85";
- break;
- case 0x8F :
- return "\xD8\xAA\xD9\x89";
- break;
- case 0x90 :
- return "\xD8\xAA\xD9\x8A";
- break;
- case 0x91 :
- return "\xD8\xAB\xD8\xAC";
- break;
- case 0x92 :
- return "\xD8\xAB\xD9\x85";
- break;
- case 0x93 :
- return "\xD8\xAB\xD9\x89";
- break;
- case 0x94 :
- return "\xD8\xAB\xD9\x8A";
- break;
- case 0x95 :
- return "\xD8\xAC\xD8\xAD";
- break;
- case 0x96 :
- return "\xD8\xAC\xD9\x85";
- break;
- case 0x97 :
- return "\xD8\xAD\xD8\xAC";
- break;
- case 0x98 :
- return "\xD8\xAD\xD9\x85";
- break;
- case 0x99 :
- return "\xD8\xAE\xD8\xAC";
- break;
- case 0x9A :
- return "\xD8\xAE\xD8\xAD";
- break;
- case 0x9B :
- return "\xD8\xAE\xD9\x85";
- break;
- case 0x9C :
- return "\xD8\xB3\xD8\xAC";
- break;
- case 0x9D :
- return "\xD8\xB3\xD8\xAD";
- break;
- case 0x9E :
- return "\xD8\xB3\xD8\xAE";
- break;
- case 0x9F :
- return "\xD8\xB3\xD9\x85";
- break;
- case 0xA0 :
- return "\xD8\xB5\xD8\xAD";
- break;
- case 0xA1 :
- return "\xD8\xB5\xD9\x85";
- break;
- case 0xA2 :
- return "\xD8\xB6\xD8\xAC";
- break;
- case 0xA3 :
- return "\xD8\xB6\xD8\xAD";
- break;
- case 0xA4 :
- return "\xD8\xB6\xD8\xAE";
- break;
- case 0xA5 :
- return "\xD8\xB6\xD9\x85";
- break;
- case 0xA6 :
- return "\xD8\xB7\xD8\xAD";
- break;
- case 0xA7 :
- return "\xD8\xB7\xD9\x85";
- break;
- case 0xA8 :
- return "\xD8\xB8\xD9\x85";
- break;
- case 0xA9 :
- return "\xD8\xB9\xD8\xAC";
- break;
- case 0xAA :
- return "\xD8\xB9\xD9\x85";
- break;
- case 0xAB :
- return "\xD8\xBA\xD8\xAC";
- break;
- case 0xAC :
- return "\xD8\xBA\xD9\x85";
- break;
- case 0xAD :
- return "\xD9\x81\xD8\xAC";
- break;
- case 0xAE :
- return "\xD9\x81\xD8\xAD";
- break;
- case 0xAF :
- return "\xD9\x81\xD8\xAE";
- break;
- case 0xB0 :
- return "\xD9\x81\xD9\x85";
- break;
- case 0xB1 :
- return "\xD9\x81\xD9\x89";
- break;
- case 0xB2 :
- return "\xD9\x81\xD9\x8A";
- break;
- case 0xB3 :
- return "\xD9\x82\xD8\xAD";
- break;
- case 0xB4 :
- return "\xD9\x82\xD9\x85";
- break;
- case 0xB5 :
- return "\xD9\x82\xD9\x89";
- break;
- case 0xB6 :
- return "\xD9\x82\xD9\x8A";
- break;
- case 0xB7 :
- return "\xD9\x83\xD8\xA7";
- break;
- case 0xB8 :
- return "\xD9\x83\xD8\xAC";
- break;
- case 0xB9 :
- return "\xD9\x83\xD8\xAD";
- break;
- case 0xBA :
- return "\xD9\x83\xD8\xAE";
- break;
- case 0xBB :
- return "\xD9\x83\xD9\x84";
- break;
- case 0xBC :
- return "\xD9\x83\xD9\x85";
- break;
- case 0xBD :
- return "\xD9\x83\xD9\x89";
- break;
- case 0xBE :
- return "\xD9\x83\xD9\x8A";
- break;
- case 0xBF :
- return "\xD9\x84\xD8\xAC";
- break;
- }
- break;
- case 0xB1 :
- switch (str[2]) {
- case 0x80 :
- return "\xD9\x84\xD8\xAD";
- break;
- case 0x81 :
- return "\xD9\x84\xD8\xAE";
- break;
- case 0x82 :
- return "\xD9\x84\xD9\x85";
- break;
- case 0x83 :
- return "\xD9\x84\xD9\x89";
- break;
- case 0x84 :
- return "\xD9\x84\xD9\x8A";
- break;
- case 0x85 :
- return "\xD9\x85\xD8\xAC";
- break;
- case 0x86 :
- return "\xD9\x85\xD8\xAD";
- break;
- case 0x87 :
- return "\xD9\x85\xD8\xAE";
- break;
- case 0x88 :
- return "\xD9\x85\xD9\x85";
- break;
- case 0x89 :
- return "\xD9\x85\xD9\x89";
- break;
- case 0x8A :
- return "\xD9\x85\xD9\x8A";
- break;
- case 0x8B :
- return "\xD9\x86\xD8\xAC";
- break;
- case 0x8C :
- return "\xD9\x86\xD8\xAD";
- break;
- case 0x8D :
- return "\xD9\x86\xD8\xAE";
- break;
- case 0x8E :
- return "\xD9\x86\xD9\x85";
- break;
- case 0x8F :
- return "\xD9\x86\xD9\x89";
- break;
- case 0x90 :
- return "\xD9\x86\xD9\x8A";
- break;
- case 0x91 :
- return "\xD9\x87\xD8\xAC";
- break;
- case 0x92 :
- return "\xD9\x87\xD9\x85";
- break;
- case 0x93 :
- return "\xD9\x87\xD9\x89";
- break;
- case 0x94 :
- return "\xD9\x87\xD9\x8A";
- break;
- case 0x95 :
- return "\xD9\x8A\xD8\xAC";
- break;
- case 0x96 :
- return "\xD9\x8A\xD8\xAD";
- break;
- case 0x97 :
- return "\xD9\x8A\xD8\xAE";
- break;
- case 0x98 :
- return "\xD9\x8A\xD9\x85";
- break;
- case 0x99 :
- return "\xD9\x8A\xD9\x89";
- break;
- case 0x9A :
- return "\xD9\x8A\xD9\x8A";
- break;
- case 0x9B :
- return "\xD8\xB0\xD9\xB0";
- break;
- case 0x9C :
- return "\xD8\xB1\xD9\xB0";
- break;
- case 0x9D :
- return "\xD9\x89\xD9\xB0";
- break;
- case 0x9E :
- return "\xD9\x8C\xD9\x91";
- break;
- case 0x9F :
- return "\xD9\x8D\xD9\x91";
- break;
- case 0xA0 :
- return "\xD9\x8E\xD9\x91";
- break;
- case 0xA1 :
- return "\xD9\x8F\xD9\x91";
- break;
- case 0xA2 :
- return "\xD9\x90\xD9\x91";
- break;
- case 0xA3 :
- return "\xD9\x91\xD9\xB0";
- break;
- case 0xA4 :
- return "\xD8\xA6\xD8\xB1";
- break;
- case 0xA5 :
- return "\xD8\xA6\xD8\xB2";
- break;
- case 0xA6 :
- return "\xD8\xA6\xD9\x85";
- break;
- case 0xA7 :
- return "\xD8\xA6\xD9\x86";
- break;
- case 0xA8 :
- return "\xD8\xA6\xD9\x89";
- break;
- case 0xA9 :
- return "\xD8\xA6\xD9\x8A";
- break;
- case 0xAA :
- return "\xD8\xA8\xD8\xB1";
- break;
- case 0xAB :
- return "\xD8\xA8\xD8\xB2";
- break;
- case 0xAC :
- return "\xD8\xA8\xD9\x85";
- break;
- case 0xAD :
- return "\xD8\xA8\xD9\x86";
- break;
- case 0xAE :
- return "\xD8\xA8\xD9\x89";
- break;
- case 0xAF :
- return "\xD8\xA8\xD9\x8A";
- break;
- case 0xB0 :
- return "\xD8\xAA\xD8\xB1";
- break;
- case 0xB1 :
- return "\xD8\xAA\xD8\xB2";
- break;
- case 0xB2 :
- return "\xD8\xAA\xD9\x85";
- break;
- case 0xB3 :
- return "\xD8\xAA\xD9\x86";
- break;
- case 0xB4 :
- return "\xD8\xAA\xD9\x89";
- break;
- case 0xB5 :
- return "\xD8\xAA\xD9\x8A";
- break;
- case 0xB6 :
- return "\xD8\xAB\xD8\xB1";
- break;
- case 0xB7 :
- return "\xD8\xAB\xD8\xB2";
- break;
- case 0xB8 :
- return "\xD8\xAB\xD9\x85";
- break;
- case 0xB9 :
- return "\xD8\xAB\xD9\x86";
- break;
- case 0xBA :
- return "\xD8\xAB\xD9\x89";
- break;
- case 0xBB :
- return "\xD8\xAB\xD9\x8A";
- break;
- case 0xBC :
- return "\xD9\x81\xD9\x89";
- break;
- case 0xBD :
- return "\xD9\x81\xD9\x8A";
- break;
- case 0xBE :
- return "\xD9\x82\xD9\x89";
- break;
- case 0xBF :
- return "\xD9\x82\xD9\x8A";
- break;
- }
- break;
- case 0xB2 :
- switch (str[2]) {
- case 0x80 :
- return "\xD9\x83\xD8\xA7";
- break;
- case 0x81 :
- return "\xD9\x83\xD9\x84";
- break;
- case 0x82 :
- return "\xD9\x83\xD9\x85";
- break;
- case 0x83 :
- return "\xD9\x83\xD9\x89";
- break;
- case 0x84 :
- return "\xD9\x83\xD9\x8A";
- break;
- case 0x85 :
- return "\xD9\x84\xD9\x85";
- break;
- case 0x86 :
- return "\xD9\x84\xD9\x89";
- break;
- case 0x87 :
- return "\xD9\x84\xD9\x8A";
- break;
- case 0x88 :
- return "\xD9\x85\xD8\xA7";
- break;
- case 0x89 :
- return "\xD9\x85\xD9\x85";
- break;
- case 0x8A :
- return "\xD9\x86\xD8\xB1";
- break;
- case 0x8B :
- return "\xD9\x86\xD8\xB2";
- break;
- case 0x8C :
- return "\xD9\x86\xD9\x85";
- break;
- case 0x8D :
- return "\xD9\x86\xD9\x86";
- break;
- case 0x8E :
- return "\xD9\x86\xD9\x89";
- break;
- case 0x8F :
- return "\xD9\x86\xD9\x8A";
- break;
- case 0x90 :
- return "\xD9\x89\xD9\xB0";
- break;
- case 0x91 :
- return "\xD9\x8A\xD8\xB1";
- break;
- case 0x92 :
- return "\xD9\x8A\xD8\xB2";
- break;
- case 0x93 :
- return "\xD9\x8A\xD9\x85";
- break;
- case 0x94 :
- return "\xD9\x8A\xD9\x86";
- break;
- case 0x95 :
- return "\xD9\x8A\xD9\x89";
- break;
- case 0x96 :
- return "\xD9\x8A\xD9\x8A";
- break;
- case 0x97 :
- return "\xD8\xA6\xD8\xAC";
- break;
- case 0x98 :
- return "\xD8\xA6\xD8\xAD";
- break;
- case 0x99 :
- return "\xD8\xA6\xD8\xAE";
- break;
- case 0x9A :
- return "\xD8\xA6\xD9\x85";
- break;
- case 0x9B :
- return "\xD8\xA6\xD9\x87";
- break;
- case 0x9C :
- return "\xD8\xA8\xD8\xAC";
- break;
- case 0x9D :
- return "\xD8\xA8\xD8\xAD";
- break;
- case 0x9E :
- return "\xD8\xA8\xD8\xAE";
- break;
- case 0x9F :
- return "\xD8\xA8\xD9\x85";
- break;
- case 0xA0 :
- return "\xD8\xA8\xD9\x87";
- break;
- case 0xA1 :
- return "\xD8\xAA\xD8\xAC";
- break;
- case 0xA2 :
- return "\xD8\xAA\xD8\xAD";
- break;
- case 0xA3 :
- return "\xD8\xAA\xD8\xAE";
- break;
- case 0xA4 :
- return "\xD8\xAA\xD9\x85";
- break;
- case 0xA5 :
- return "\xD8\xAA\xD9\x87";
- break;
- case 0xA6 :
- return "\xD8\xAB\xD9\x85";
- break;
- case 0xA7 :
- return "\xD8\xAC\xD8\xAD";
- break;
- case 0xA8 :
- return "\xD8\xAC\xD9\x85";
- break;
- case 0xA9 :
- return "\xD8\xAD\xD8\xAC";
- break;
- case 0xAA :
- return "\xD8\xAD\xD9\x85";
- break;
- case 0xAB :
- return "\xD8\xAE\xD8\xAC";
- break;
- case 0xAC :
- return "\xD8\xAE\xD9\x85";
- break;
- case 0xAD :
- return "\xD8\xB3\xD8\xAC";
- break;
- case 0xAE :
- return "\xD8\xB3\xD8\xAD";
- break;
- case 0xAF :
- return "\xD8\xB3\xD8\xAE";
- break;
- case 0xB0 :
- return "\xD8\xB3\xD9\x85";
- break;
- case 0xB1 :
- return "\xD8\xB5\xD8\xAD";
- break;
- case 0xB2 :
- return "\xD8\xB5\xD8\xAE";
- break;
- case 0xB3 :
- return "\xD8\xB5\xD9\x85";
- break;
- case 0xB4 :
- return "\xD8\xB6\xD8\xAC";
- break;
- case 0xB5 :
- return "\xD8\xB6\xD8\xAD";
- break;
- case 0xB6 :
- return "\xD8\xB6\xD8\xAE";
- break;
- case 0xB7 :
- return "\xD8\xB6\xD9\x85";
- break;
- case 0xB8 :
- return "\xD8\xB7\xD8\xAD";
- break;
- case 0xB9 :
- return "\xD8\xB8\xD9\x85";
- break;
- case 0xBA :
- return "\xD8\xB9\xD8\xAC";
- break;
- case 0xBB :
- return "\xD8\xB9\xD9\x85";
- break;
- case 0xBC :
- return "\xD8\xBA\xD8\xAC";
- break;
- case 0xBD :
- return "\xD8\xBA\xD9\x85";
- break;
- case 0xBE :
- return "\xD9\x81\xD8\xAC";
- break;
- case 0xBF :
- return "\xD9\x81\xD8\xAD";
- break;
- }
- break;
- case 0xB3 :
- switch (str[2]) {
- case 0x80 :
- return "\xD9\x81\xD8\xAE";
- break;
- case 0x81 :
- return "\xD9\x81\xD9\x85";
- break;
- case 0x82 :
- return "\xD9\x82\xD8\xAD";
- break;
- case 0x83 :
- return "\xD9\x82\xD9\x85";
- break;
- case 0x84 :
- return "\xD9\x83\xD8\xAC";
- break;
- case 0x85 :
- return "\xD9\x83\xD8\xAD";
- break;
- case 0x86 :
- return "\xD9\x83\xD8\xAE";
- break;
- case 0x87 :
- return "\xD9\x83\xD9\x84";
- break;
- case 0x88 :
- return "\xD9\x83\xD9\x85";
- break;
- case 0x89 :
- return "\xD9\x84\xD8\xAC";
- break;
- case 0x8A :
- return "\xD9\x84\xD8\xAD";
- break;
- case 0x8B :
- return "\xD9\x84\xD8\xAE";
- break;
- case 0x8C :
- return "\xD9\x84\xD9\x85";
- break;
- case 0x8D :
- return "\xD9\x84\xD9\x87";
- break;
- case 0x8E :
- return "\xD9\x85\xD8\xAC";
- break;
- case 0x8F :
- return "\xD9\x85\xD8\xAD";
- break;
- case 0x90 :
- return "\xD9\x85\xD8\xAE";
- break;
- case 0x91 :
- return "\xD9\x85\xD9\x85";
- break;
- case 0x92 :
- return "\xD9\x86\xD8\xAC";
- break;
- case 0x93 :
- return "\xD9\x86\xD8\xAD";
- break;
- case 0x94 :
- return "\xD9\x86\xD8\xAE";
- break;
- case 0x95 :
- return "\xD9\x86\xD9\x85";
- break;
- case 0x96 :
- return "\xD9\x86\xD9\x87";
- break;
- case 0x97 :
- return "\xD9\x87\xD8\xAC";
- break;
- case 0x98 :
- return "\xD9\x87\xD9\x85";
- break;
- case 0x99 :
- return "\xD9\x87\xD9\xB0";
- break;
- case 0x9A :
- return "\xD9\x8A\xD8\xAC";
- break;
- case 0x9B :
- return "\xD9\x8A\xD8\xAD";
- break;
- case 0x9C :
- return "\xD9\x8A\xD8\xAE";
- break;
- case 0x9D :
- return "\xD9\x8A\xD9\x85";
- break;
- case 0x9E :
- return "\xD9\x8A\xD9\x87";
- break;
- case 0x9F :
- return "\xD8\xA6\xD9\x85";
- break;
- case 0xA0 :
- return "\xD8\xA6\xD9\x87";
- break;
- case 0xA1 :
- return "\xD8\xA8\xD9\x85";
- break;
- case 0xA2 :
- return "\xD8\xA8\xD9\x87";
- break;
- case 0xA3 :
- return "\xD8\xAA\xD9\x85";
- break;
- case 0xA4 :
- return "\xD8\xAA\xD9\x87";
- break;
- case 0xA5 :
- return "\xD8\xAB\xD9\x85";
- break;
- case 0xA6 :
- return "\xD8\xAB\xD9\x87";
- break;
- case 0xA7 :
- return "\xD8\xB3\xD9\x85";
- break;
- case 0xA8 :
- return "\xD8\xB3\xD9\x87";
- break;
- case 0xA9 :
- return "\xD8\xB4\xD9\x85";
- break;
- case 0xAA :
- return "\xD8\xB4\xD9\x87";
- break;
- case 0xAB :
- return "\xD9\x83\xD9\x84";
- break;
- case 0xAC :
- return "\xD9\x83\xD9\x85";
- break;
- case 0xAD :
- return "\xD9\x84\xD9\x85";
- break;
- case 0xAE :
- return "\xD9\x86\xD9\x85";
- break;
- case 0xAF :
- return "\xD9\x86\xD9\x87";
- break;
- case 0xB0 :
- return "\xD9\x8A\xD9\x85";
- break;
- case 0xB1 :
- return "\xD9\x8A\xD9\x87";
- break;
- case 0xB2 :
- return "\xD9\x80\xD9\x8E\xD9\x91";
- break;
- case 0xB3 :
- return "\xD9\x80\xD9\x8F\xD9\x91";
- break;
- case 0xB4 :
- return "\xD9\x80\xD9\x90\xD9\x91";
- break;
- case 0xB5 :
- return "\xD8\xB7\xD9\x89";
- break;
- case 0xB6 :
- return "\xD8\xB7\xD9\x8A";
- break;
- case 0xB7 :
- return "\xD8\xB9\xD9\x89";
- break;
- case 0xB8 :
- return "\xD8\xB9\xD9\x8A";
- break;
- case 0xB9 :
- return "\xD8\xBA\xD9\x89";
- break;
- case 0xBA :
- return "\xD8\xBA\xD9\x8A";
- break;
- case 0xBB :
- return "\xD8\xB3\xD9\x89";
- break;
- case 0xBC :
- return "\xD8\xB3\xD9\x8A";
- break;
- case 0xBD :
- return "\xD8\xB4\xD9\x89";
- break;
- case 0xBE :
- return "\xD8\xB4\xD9\x8A";
- break;
- case 0xBF :
- return "\xD8\xAD\xD9\x89";
- break;
- }
- break;
- case 0xB4 :
- switch (str[2]) {
- case 0x80 :
- return "\xD8\xAD\xD9\x8A";
- break;
- case 0x81 :
- return "\xD8\xAC\xD9\x89";
- break;
- case 0x82 :
- return "\xD8\xAC\xD9\x8A";
- break;
- case 0x83 :
- return "\xD8\xAE\xD9\x89";
- break;
- case 0x84 :
- return "\xD8\xAE\xD9\x8A";
- break;
- case 0x85 :
- return "\xD8\xB5\xD9\x89";
- break;
- case 0x86 :
- return "\xD8\xB5\xD9\x8A";
- break;
- case 0x87 :
- return "\xD8\xB6\xD9\x89";
- break;
- case 0x88 :
- return "\xD8\xB6\xD9\x8A";
- break;
- case 0x89 :
- return "\xD8\xB4\xD8\xAC";
- break;
- case 0x8A :
- return "\xD8\xB4\xD8\xAD";
- break;
- case 0x8B :
- return "\xD8\xB4\xD8\xAE";
- break;
- case 0x8C :
- return "\xD8\xB4\xD9\x85";
- break;
- case 0x8D :
- return "\xD8\xB4\xD8\xB1";
- break;
- case 0x8E :
- return "\xD8\xB3\xD8\xB1";
- break;
- case 0x8F :
- return "\xD8\xB5\xD8\xB1";
- break;
- case 0x90 :
- return "\xD8\xB6\xD8\xB1";
- break;
- case 0x91 :
- return "\xD8\xB7\xD9\x89";
- break;
- case 0x92 :
- return "\xD8\xB7\xD9\x8A";
- break;
- case 0x93 :
- return "\xD8\xB9\xD9\x89";
- break;
- case 0x94 :
- return "\xD8\xB9\xD9\x8A";
- break;
- case 0x95 :
- return "\xD8\xBA\xD9\x89";
- break;
- case 0x96 :
- return "\xD8\xBA\xD9\x8A";
- break;
- case 0x97 :
- return "\xD8\xB3\xD9\x89";
- break;
- case 0x98 :
- return "\xD8\xB3\xD9\x8A";
- break;
- case 0x99 :
- return "\xD8\xB4\xD9\x89";
- break;
- case 0x9A :
- return "\xD8\xB4\xD9\x8A";
- break;
- case 0x9B :
- return "\xD8\xAD\xD9\x89";
- break;
- case 0x9C :
- return "\xD8\xAD\xD9\x8A";
- break;
- case 0x9D :
- return "\xD8\xAC\xD9\x89";
- break;
- case 0x9E :
- return "\xD8\xAC\xD9\x8A";
- break;
- case 0x9F :
- return "\xD8\xAE\xD9\x89";
- break;
- case 0xA0 :
- return "\xD8\xAE\xD9\x8A";
- break;
- case 0xA1 :
- return "\xD8\xB5\xD9\x89";
- break;
- case 0xA2 :
- return "\xD8\xB5\xD9\x8A";
- break;
- case 0xA3 :
- return "\xD8\xB6\xD9\x89";
- break;
- case 0xA4 :
- return "\xD8\xB6\xD9\x8A";
- break;
- case 0xA5 :
- return "\xD8\xB4\xD8\xAC";
- break;
- case 0xA6 :
- return "\xD8\xB4\xD8\xAD";
- break;
- case 0xA7 :
- return "\xD8\xB4\xD8\xAE";
- break;
- case 0xA8 :
- return "\xD8\xB4\xD9\x85";
- break;
- case 0xA9 :
- return "\xD8\xB4\xD8\xB1";
- break;
- case 0xAA :
- return "\xD8\xB3\xD8\xB1";
- break;
- case 0xAB :
- return "\xD8\xB5\xD8\xB1";
- break;
- case 0xAC :
- return "\xD8\xB6\xD8\xB1";
- break;
- case 0xAD :
- return "\xD8\xB4\xD8\xAC";
- break;
- case 0xAE :
- return "\xD8\xB4\xD8\xAD";
- break;
- case 0xAF :
- return "\xD8\xB4\xD8\xAE";
- break;
- case 0xB0 :
- return "\xD8\xB4\xD9\x85";
- break;
- case 0xB1 :
- return "\xD8\xB3\xD9\x87";
- break;
- case 0xB2 :
- return "\xD8\xB4\xD9\x87";
- break;
- case 0xB3 :
- return "\xD8\xB7\xD9\x85";
- break;
- case 0xB4 :
- return "\xD8\xB3\xD8\xAC";
- break;
- case 0xB5 :
- return "\xD8\xB3\xD8\xAD";
- break;
- case 0xB6 :
- return "\xD8\xB3\xD8\xAE";
- break;
- case 0xB7 :
- return "\xD8\xB4\xD8\xAC";
- break;
- case 0xB8 :
- return "\xD8\xB4\xD8\xAD";
- break;
- case 0xB9 :
- return "\xD8\xB4\xD8\xAE";
- break;
- case 0xBA :
- return "\xD8\xB7\xD9\x85";
- break;
- case 0xBB :
- return "\xD8\xB8\xD9\x85";
- break;
- case 0xBC :
- return "\xD8\xA7\xD9\x8B";
- break;
- case 0xBD :
- return "\xD8\xA7\xD9\x8B";
- break;
- }
- break;
- case 0xB5 :
- switch (str[2]) {
- case 0x90 :
- return "\xD8\xAA\xD8\xAC\xD9\x85";
- break;
- case 0x91 :
- return "\xD8\xAA\xD8\xAD\xD8\xAC";
- break;
- case 0x92 :
- return "\xD8\xAA\xD8\xAD\xD8\xAC";
- break;
- case 0x93 :
- return "\xD8\xAA\xD8\xAD\xD9\x85";
- break;
- case 0x94 :
- return "\xD8\xAA\xD8\xAE\xD9\x85";
- break;
- case 0x95 :
- return "\xD8\xAA\xD9\x85\xD8\xAC";
- break;
- case 0x96 :
- return "\xD8\xAA\xD9\x85\xD8\xAD";
- break;
- case 0x97 :
- return "\xD8\xAA\xD9\x85\xD8\xAE";
- break;
- case 0x98 :
- return "\xD8\xAC\xD9\x85\xD8\xAD";
- break;
- case 0x99 :
- return "\xD8\xAC\xD9\x85\xD8\xAD";
- break;
- case 0x9A :
- return "\xD8\xAD\xD9\x85\xD9\x8A";
- break;
- case 0x9B :
- return "\xD8\xAD\xD9\x85\xD9\x89";
- break;
- case 0x9C :
- return "\xD8\xB3\xD8\xAD\xD8\xAC";
- break;
- case 0x9D :
- return "\xD8\xB3\xD8\xAC\xD8\xAD";
- break;
- case 0x9E :
- return "\xD8\xB3\xD8\xAC\xD9\x89";
- break;
- case 0x9F :
- return "\xD8\xB3\xD9\x85\xD8\xAD";
- break;
- case 0xA0 :
- return "\xD8\xB3\xD9\x85\xD8\xAD";
- break;
- case 0xA1 :
- return "\xD8\xB3\xD9\x85\xD8\xAC";
- break;
- case 0xA2 :
- return "\xD8\xB3\xD9\x85\xD9\x85";
- break;
- case 0xA3 :
- return "\xD8\xB3\xD9\x85\xD9\x85";
- break;
- case 0xA4 :
- return "\xD8\xB5\xD8\xAD\xD8\xAD";
- break;
- case 0xA5 :
- return "\xD8\xB5\xD8\xAD\xD8\xAD";
- break;
- case 0xA6 :
- return "\xD8\xB5\xD9\x85\xD9\x85";
- break;
- case 0xA7 :
- return "\xD8\xB4\xD8\xAD\xD9\x85";
- break;
- case 0xA8 :
- return "\xD8\xB4\xD8\xAD\xD9\x85";
- break;
- case 0xA9 :
- return "\xD8\xB4\xD8\xAC\xD9\x8A";
- break;
- case 0xAA :
- return "\xD8\xB4\xD9\x85\xD8\xAE";
- break;
- case 0xAB :
- return "\xD8\xB4\xD9\x85\xD8\xAE";
- break;
- case 0xAC :
- return "\xD8\xB4\xD9\x85\xD9\x85";
- break;
- case 0xAD :
- return "\xD8\xB4\xD9\x85\xD9\x85";
- break;
- case 0xAE :
- return "\xD8\xB6\xD8\xAD\xD9\x89";
- break;
- case 0xAF :
- return "\xD8\xB6\xD8\xAE\xD9\x85";
- break;
- case 0xB0 :
- return "\xD8\xB6\xD8\xAE\xD9\x85";
- break;
- case 0xB1 :
- return "\xD8\xB7\xD9\x85\xD8\xAD";
- break;
- case 0xB2 :
- return "\xD8\xB7\xD9\x85\xD8\xAD";
- break;
- case 0xB3 :
- return "\xD8\xB7\xD9\x85\xD9\x85";
- break;
- case 0xB4 :
- return "\xD8\xB7\xD9\x85\xD9\x8A";
- break;
- case 0xB5 :
- return "\xD8\xB9\xD8\xAC\xD9\x85";
- break;
- case 0xB6 :
- return "\xD8\xB9\xD9\x85\xD9\x85";
- break;
- case 0xB7 :
- return "\xD8\xB9\xD9\x85\xD9\x85";
- break;
- case 0xB8 :
- return "\xD8\xB9\xD9\x85\xD9\x89";
- break;
- case 0xB9 :
- return "\xD8\xBA\xD9\x85\xD9\x85";
- break;
- case 0xBA :
- return "\xD8\xBA\xD9\x85\xD9\x8A";
- break;
- case 0xBB :
- return "\xD8\xBA\xD9\x85\xD9\x89";
- break;
- case 0xBC :
- return "\xD9\x81\xD8\xAE\xD9\x85";
- break;
- case 0xBD :
- return "\xD9\x81\xD8\xAE\xD9\x85";
- break;
- case 0xBE :
- return "\xD9\x82\xD9\x85\xD8\xAD";
- break;
- case 0xBF :
- return "\xD9\x82\xD9\x85\xD9\x85";
- break;
- }
- break;
- case 0xB6 :
- switch (str[2]) {
- case 0x80 :
- return "\xD9\x84\xD8\xAD\xD9\x85";
- break;
- case 0x81 :
- return "\xD9\x84\xD8\xAD\xD9\x8A";
- break;
- case 0x82 :
- return "\xD9\x84\xD8\xAD\xD9\x89";
- break;
- case 0x83 :
- return "\xD9\x84\xD8\xAC\xD8\xAC";
- break;
- case 0x84 :
- return "\xD9\x84\xD8\xAC\xD8\xAC";
- break;
- case 0x85 :
- return "\xD9\x84\xD8\xAE\xD9\x85";
- break;
- case 0x86 :
- return "\xD9\x84\xD8\xAE\xD9\x85";
- break;
- case 0x87 :
- return "\xD9\x84\xD9\x85\xD8\xAD";
- break;
- case 0x88 :
- return "\xD9\x84\xD9\x85\xD8\xAD";
- break;
- case 0x89 :
- return "\xD9\x85\xD8\xAD\xD8\xAC";
- break;
- case 0x8A :
- return "\xD9\x85\xD8\xAD\xD9\x85";
- break;
- case 0x8B :
- return "\xD9\x85\xD8\xAD\xD9\x8A";
- break;
- case 0x8C :
- return "\xD9\x85\xD8\xAC\xD8\xAD";
- break;
- case 0x8D :
- return "\xD9\x85\xD8\xAC\xD9\x85";
- break;
- case 0x8E :
- return "\xD9\x85\xD8\xAE\xD8\xAC";
- break;
- case 0x8F :
- return "\xD9\x85\xD8\xAE\xD9\x85";
- break;
- case 0x92 :
- return "\xD9\x85\xD8\xAC\xD8\xAE";
- break;
- case 0x93 :
- return "\xD9\x87\xD9\x85\xD8\xAC";
- break;
- case 0x94 :
- return "\xD9\x87\xD9\x85\xD9\x85";
- break;
- case 0x95 :
- return "\xD9\x86\xD8\xAD\xD9\x85";
- break;
- case 0x96 :
- return "\xD9\x86\xD8\xAD\xD9\x89";
- break;
- case 0x97 :
- return "\xD9\x86\xD8\xAC\xD9\x85";
- break;
- case 0x98 :
- return "\xD9\x86\xD8\xAC\xD9\x85";
- break;
- case 0x99 :
- return "\xD9\x86\xD8\xAC\xD9\x89";
- break;
- case 0x9A :
- return "\xD9\x86\xD9\x85\xD9\x8A";
- break;
- case 0x9B :
- return "\xD9\x86\xD9\x85\xD9\x89";
- break;
- case 0x9C :
- return "\xD9\x8A\xD9\x85\xD9\x85";
- break;
- case 0x9D :
- return "\xD9\x8A\xD9\x85\xD9\x85";
- break;
- case 0x9E :
- return "\xD8\xA8\xD8\xAE\xD9\x8A";
- break;
- case 0x9F :
- return "\xD8\xAA\xD8\xAC\xD9\x8A";
- break;
- case 0xA0 :
- return "\xD8\xAA\xD8\xAC\xD9\x89";
- break;
- case 0xA1 :
- return "\xD8\xAA\xD8\xAE\xD9\x8A";
- break;
- case 0xA2 :
- return "\xD8\xAA\xD8\xAE\xD9\x89";
- break;
- case 0xA3 :
- return "\xD8\xAA\xD9\x85\xD9\x8A";
- break;
- case 0xA4 :
- return "\xD8\xAA\xD9\x85\xD9\x89";
- break;
- case 0xA5 :
- return "\xD8\xAC\xD9\x85\xD9\x8A";
- break;
- case 0xA6 :
- return "\xD8\xAC\xD8\xAD\xD9\x89";
- break;
- case 0xA7 :
- return "\xD8\xAC\xD9\x85\xD9\x89";
- break;
- case 0xA8 :
- return "\xD8\xB3\xD8\xAE\xD9\x89";
- break;
- case 0xA9 :
- return "\xD8\xB5\xD8\xAD\xD9\x8A";
- break;
- case 0xAA :
- return "\xD8\xB4\xD8\xAD\xD9\x8A";
- break;
- case 0xAB :
- return "\xD8\xB6\xD8\xAD\xD9\x8A";
- break;
- case 0xAC :
- return "\xD9\x84\xD8\xAC\xD9\x8A";
- break;
- case 0xAD :
- return "\xD9\x84\xD9\x85\xD9\x8A";
- break;
- case 0xAE :
- return "\xD9\x8A\xD8\xAD\xD9\x8A";
- break;
- case 0xAF :
- return "\xD9\x8A\xD8\xAC\xD9\x8A";
- break;
- case 0xB0 :
- return "\xD9\x8A\xD9\x85\xD9\x8A";
- break;
- case 0xB1 :
- return "\xD9\x85\xD9\x85\xD9\x8A";
- break;
- case 0xB2 :
- return "\xD9\x82\xD9\x85\xD9\x8A";
- break;
- case 0xB3 :
- return "\xD9\x86\xD8\xAD\xD9\x8A";
- break;
- case 0xB4 :
- return "\xD9\x82\xD9\x85\xD8\xAD";
- break;
- case 0xB5 :
- return "\xD9\x84\xD8\xAD\xD9\x85";
- break;
- case 0xB6 :
- return "\xD8\xB9\xD9\x85\xD9\x8A";
- break;
- case 0xB7 :
- return "\xD9\x83\xD9\x85\xD9\x8A";
- break;
- case 0xB8 :
- return "\xD9\x86\xD8\xAC\xD8\xAD";
- break;
- case 0xB9 :
- return "\xD9\x85\xD8\xAE\xD9\x8A";
- break;
- case 0xBA :
- return "\xD9\x84\xD8\xAC\xD9\x85";
- break;
- case 0xBB :
- return "\xD9\x83\xD9\x85\xD9\x85";
- break;
- case 0xBC :
- return "\xD9\x84\xD8\xAC\xD9\x85";
- break;
- case 0xBD :
- return "\xD9\x86\xD8\xAC\xD8\xAD";
- break;
- case 0xBE :
- return "\xD8\xAC\xD8\xAD\xD9\x8A";
- break;
- case 0xBF :
- return "\xD8\xAD\xD8\xAC\xD9\x8A";
- break;
- }
- break;
- case 0xB7 :
- switch (str[2]) {
- case 0x80 :
- return "\xD9\x85\xD8\xAC\xD9\x8A";
- break;
- case 0x81 :
- return "\xD9\x81\xD9\x85\xD9\x8A";
- break;
- case 0x82 :
- return "\xD8\xA8\xD8\xAD\xD9\x8A";
- break;
- case 0x83 :
- return "\xD9\x83\xD9\x85\xD9\x85";
- break;
- case 0x84 :
- return "\xD8\xB9\xD8\xAC\xD9\x85";
- break;
- case 0x85 :
- return "\xD8\xB5\xD9\x85\xD9\x85";
- break;
- case 0x86 :
- return "\xD8\xB3\xD8\xAE\xD9\x8A";
- break;
- case 0x87 :
- return "\xD9\x86\xD8\xAC\xD9\x8A";
- break;
- case 0xB0 :
- return "\xD8\xB5\xD9\x84\xDB\x92";
- break;
- case 0xB1 :
- return "\xD9\x82\xD9\x84\xDB\x92";
- break;
- case 0xB2 :
- return "\xD8\xA7\xD9\x84\xD9\x84\xD9\x87";
- break;
- case 0xB3 :
- return "\xD8\xA7\xD9\x83\xD8\xA8\xD8\xB1";
- break;
- case 0xB4 :
- return "\xD9\x85\xD8\xAD\xD9\x85\xD8\xAF";
- break;
- case 0xB5 :
- return "\xD8\xB5\xD9\x84\xD8\xB9\xD9\x85";
- break;
- case 0xB6 :
- return "\xD8\xB1\xD8\xB3\xD9\x88\xD9\x84";
- break;
- case 0xB7 :
- return "\xD8\xB9\xD9\x84\xD9\x8A\xD9\x87";
- break;
- case 0xB8 :
- return "\xD9\x88\xD8\xB3\xD9\x84\xD9\x85";
- break;
- case 0xB9 :
- return "\xD8\xB5\xD9\x84\xD9\x89";
- break;
- case 0xBA :
- return "\xD8\xB5\xD9\x84\xD9\x89\x20\xD8\xA7\xD9\x84\xD9\x84\xD9\x87\x20\xD8\xB9\xD9\x84\xD9\x8A\xD9\x87\x20\xD9\x88\xD8\xB3\xD9\x84\xD9\x85";
- break;
- case 0xBB :
- return "\xD8\xAC\xD9\x84\x20\xD8\xAC\xD9\x84\xD8\xA7\xD9\x84\xD9\x87";
- break;
- case 0xBC :
- return "\xD8\xB1\xDB\x8C\xD8\xA7\xD9\x84";
- break;
- }
- break;
- case 0xB8 :
- switch (str[2]) {
- case 0x90 :
- return "\x2C";
- break;
- case 0x91 :
- return "\xE3\x80\x81";
- break;
- case 0x92 :
- return "\xE3\x80\x82";
- break;
- case 0x93 :
- return "\x3A";
- break;
- case 0x94 :
- return "\x3B";
- break;
- case 0x95 :
- return "\x21";
- break;
- case 0x96 :
- return "\x3F";
- break;
- case 0x97 :
- return "\xE3\x80\x96";
- break;
- case 0x98 :
- return "\xE3\x80\x97";
- break;
- case 0x99 :
- return "\x2E\x2E\x2E";
- break;
- case 0xB0 :
- return "\x2E\x2E";
- break;
- case 0xB1 :
- return "\xE2\x80\x94";
- break;
- case 0xB2 :
- return "\xE2\x80\x93";
- break;
- case 0xB3 :
- return "\x5F";
- break;
- case 0xB4 :
- return "\x5F";
- break;
- case 0xB5 :
- return "\x28";
- break;
- case 0xB6 :
- return "\x29";
- break;
- case 0xB7 :
- return "\x7B";
- break;
- case 0xB8 :
- return "\x7D";
- break;
- case 0xB9 :
- return "\xE3\x80\x94";
- break;
- case 0xBA :
- return "\xE3\x80\x95";
- break;
- case 0xBB :
- return "\xE3\x80\x90";
- break;
- case 0xBC :
- return "\xE3\x80\x91";
- break;
- case 0xBD :
- return "\xE3\x80\x8A";
- break;
- case 0xBE :
- return "\xE3\x80\x8B";
- break;
- case 0xBF :
- return "\xE3\x80\x88";
- break;
- }
- break;
- case 0xB9 :
- switch (str[2]) {
- case 0x80 :
- return "\xE3\x80\x89";
- break;
- case 0x81 :
- return "\xE3\x80\x8C";
- break;
- case 0x82 :
- return "\xE3\x80\x8D";
- break;
- case 0x83 :
- return "\xE3\x80\x8E";
- break;
- case 0x84 :
- return "\xE3\x80\x8F";
- break;
- case 0x87 :
- return "\x5B";
- break;
- case 0x88 :
- return "\x5D";
- break;
- case 0x89 :
- return "\xCC\x85";
- break;
- case 0x8A :
- return "\xCC\x85";
- break;
- case 0x8B :
- return "\xCC\x85";
- break;
- case 0x8C :
- return "\xCC\x85";
- break;
- case 0x8D :
- return "\x5F";
- break;
- case 0x8E :
- return "\x5F";
- break;
- case 0x8F :
- return "\x5F";
- break;
- case 0x90 :
- return "\x2C";
- break;
- case 0x91 :
- return "\xE3\x80\x81";
- break;
- case 0x92 :
- return "\x2E";
- break;
- case 0x94 :
- return "\x3B";
- break;
- case 0x95 :
- return "\x3A";
- break;
- case 0x96 :
- return "\x3F";
- break;
- case 0x97 :
- return "\x21";
- break;
- case 0x98 :
- return "\xE2\x80\x94";
- break;
- case 0x99 :
- return "\x28";
- break;
- case 0x9A :
- return "\x29";
- break;
- case 0x9B :
- return "\x7B";
- break;
- case 0x9C :
- return "\x7D";
- break;
- case 0x9D :
- return "\xE3\x80\x94";
- break;
- case 0x9E :
- return "\xE3\x80\x95";
- break;
- case 0x9F :
- return "\x23";
- break;
- case 0xA0 :
- return "\x26";
- break;
- case 0xA1 :
- return "\x2A";
- break;
- case 0xA2 :
- return "\x2B";
- break;
- case 0xA3 :
- return "\x2D";
- break;
- case 0xA4 :
- return "\x3C";
- break;
- case 0xA5 :
- return "\x3E";
- break;
- case 0xA6 :
- return "\x3D";
- break;
- case 0xA8 :
- return "\x5C";
- break;
- case 0xA9 :
- return "\x24";
- break;
- case 0xAA :
- return "\x25";
- break;
- case 0xAB :
- return "\x40";
- break;
- case 0xB0 :
- return "\xD9\x8B";
- break;
- case 0xB1 :
- return "\xD9\x80\xD9\x8B";
- break;
- case 0xB2 :
- return "\xD9\x8C";
- break;
- case 0xB4 :
- return "\xD9\x8D";
- break;
- case 0xB6 :
- return "\xD9\x8E";
- break;
- case 0xB7 :
- return "\xD9\x80\xD9\x8E";
- break;
- case 0xB8 :
- return "\xD9\x8F";
- break;
- case 0xB9 :
- return "\xD9\x80\xD9\x8F";
- break;
- case 0xBA :
- return "\xD9\x90";
- break;
- case 0xBB :
- return "\xD9\x80\xD9\x90";
- break;
- case 0xBC :
- return "\xD9\x91";
- break;
- case 0xBD :
- return "\xD9\x80\xD9\x91";
- break;
- case 0xBE :
- return "\xD9\x92";
- break;
- case 0xBF :
- return "\xD9\x80\xD9\x92";
- break;
- }
- break;
- case 0xBA :
- switch (str[2]) {
- case 0x80 :
- return "\xD8\xA1";
- break;
- case 0x81 :
- return "\xD8\xA2";
- break;
- case 0x82 :
- return "\xD8\xA2";
- break;
- case 0x83 :
- return "\xD8\xA3";
- break;
- case 0x84 :
- return "\xD8\xA3";
- break;
- case 0x85 :
- return "\xD8\xA4";
- break;
- case 0x86 :
- return "\xD8\xA4";
- break;
- case 0x87 :
- return "\xD8\xA5";
- break;
- case 0x88 :
- return "\xD8\xA5";
- break;
- case 0x89 :
- return "\xD8\xA6";
- break;
- case 0x8A :
- return "\xD8\xA6";
- break;
- case 0x8B :
- return "\xD8\xA6";
- break;
- case 0x8C :
- return "\xD8\xA6";
- break;
- case 0x8D :
- return "\xD8\xA7";
- break;
- case 0x8E :
- return "\xD8\xA7";
- break;
- case 0x8F :
- return "\xD8\xA8";
- break;
- case 0x90 :
- return "\xD8\xA8";
- break;
- case 0x91 :
- return "\xD8\xA8";
- break;
- case 0x92 :
- return "\xD8\xA8";
- break;
- case 0x93 :
- return "\xD8\xA9";
- break;
- case 0x94 :
- return "\xD8\xA9";
- break;
- case 0x95 :
- return "\xD8\xAA";
- break;
- case 0x96 :
- return "\xD8\xAA";
- break;
- case 0x97 :
- return "\xD8\xAA";
- break;
- case 0x98 :
- return "\xD8\xAA";
- break;
- case 0x99 :
- return "\xD8\xAB";
- break;
- case 0x9A :
- return "\xD8\xAB";
- break;
- case 0x9B :
- return "\xD8\xAB";
- break;
- case 0x9C :
- return "\xD8\xAB";
- break;
- case 0x9D :
- return "\xD8\xAC";
- break;
- case 0x9E :
- return "\xD8\xAC";
- break;
- case 0x9F :
- return "\xD8\xAC";
- break;
- case 0xA0 :
- return "\xD8\xAC";
- break;
- case 0xA1 :
- return "\xD8\xAD";
- break;
- case 0xA2 :
- return "\xD8\xAD";
- break;
- case 0xA3 :
- return "\xD8\xAD";
- break;
- case 0xA4 :
- return "\xD8\xAD";
- break;
- case 0xA5 :
- return "\xD8\xAE";
- break;
- case 0xA6 :
- return "\xD8\xAE";
- break;
- case 0xA7 :
- return "\xD8\xAE";
- break;
- case 0xA8 :
- return "\xD8\xAE";
- break;
- case 0xA9 :
- return "\xD8\xAF";
- break;
- case 0xAA :
- return "\xD8\xAF";
- break;
- case 0xAB :
- return "\xD8\xB0";
- break;
- case 0xAC :
- return "\xD8\xB0";
- break;
- case 0xAD :
- return "\xD8\xB1";
- break;
- case 0xAE :
- return "\xD8\xB1";
- break;
- case 0xAF :
- return "\xD8\xB2";
- break;
- case 0xB0 :
- return "\xD8\xB2";
- break;
- case 0xB1 :
- return "\xD8\xB3";
- break;
- case 0xB2 :
- return "\xD8\xB3";
- break;
- case 0xB3 :
- return "\xD8\xB3";
- break;
- case 0xB4 :
- return "\xD8\xB3";
- break;
- case 0xB5 :
- return "\xD8\xB4";
- break;
- case 0xB6 :
- return "\xD8\xB4";
- break;
- case 0xB7 :
- return "\xD8\xB4";
- break;
- case 0xB8 :
- return "\xD8\xB4";
- break;
- case 0xB9 :
- return "\xD8\xB5";
- break;
- case 0xBA :
- return "\xD8\xB5";
- break;
- case 0xBB :
- return "\xD8\xB5";
- break;
- case 0xBC :
- return "\xD8\xB5";
- break;
- case 0xBD :
- return "\xD8\xB6";
- break;
- case 0xBE :
- return "\xD8\xB6";
- break;
- case 0xBF :
- return "\xD8\xB6";
- break;
- }
- break;
- case 0xBB :
- switch (str[2]) {
- case 0x80 :
- return "\xD8\xB6";
- break;
- case 0x81 :
- return "\xD8\xB7";
- break;
- case 0x82 :
- return "\xD8\xB7";
- break;
- case 0x83 :
- return "\xD8\xB7";
- break;
- case 0x84 :
- return "\xD8\xB7";
- break;
- case 0x85 :
- return "\xD8\xB8";
- break;
- case 0x86 :
- return "\xD8\xB8";
- break;
- case 0x87 :
- return "\xD8\xB8";
- break;
- case 0x88 :
- return "\xD8\xB8";
- break;
- case 0x89 :
- return "\xD8\xB9";
- break;
- case 0x8A :
- return "\xD8\xB9";
- break;
- case 0x8B :
- return "\xD8\xB9";
- break;
- case 0x8C :
- return "\xD8\xB9";
- break;
- case 0x8D :
- return "\xD8\xBA";
- break;
- case 0x8E :
- return "\xD8\xBA";
- break;
- case 0x8F :
- return "\xD8\xBA";
- break;
- case 0x90 :
- return "\xD8\xBA";
- break;
- case 0x91 :
- return "\xD9\x81";
- break;
- case 0x92 :
- return "\xD9\x81";
- break;
- case 0x93 :
- return "\xD9\x81";
- break;
- case 0x94 :
- return "\xD9\x81";
- break;
- case 0x95 :
- return "\xD9\x82";
- break;
- case 0x96 :
- return "\xD9\x82";
- break;
- case 0x97 :
- return "\xD9\x82";
- break;
- case 0x98 :
- return "\xD9\x82";
- break;
- case 0x99 :
- return "\xD9\x83";
- break;
- case 0x9A :
- return "\xD9\x83";
- break;
- case 0x9B :
- return "\xD9\x83";
- break;
- case 0x9C :
- return "\xD9\x83";
- break;
- case 0x9D :
- return "\xD9\x84";
- break;
- case 0x9E :
- return "\xD9\x84";
- break;
- case 0x9F :
- return "\xD9\x84";
- break;
- case 0xA0 :
- return "\xD9\x84";
- break;
- case 0xA1 :
- return "\xD9\x85";
- break;
- case 0xA2 :
- return "\xD9\x85";
- break;
- case 0xA3 :
- return "\xD9\x85";
- break;
- case 0xA4 :
- return "\xD9\x85";
- break;
- case 0xA5 :
- return "\xD9\x86";
- break;
- case 0xA6 :
- return "\xD9\x86";
- break;
- case 0xA7 :
- return "\xD9\x86";
- break;
- case 0xA8 :
- return "\xD9\x86";
- break;
- case 0xA9 :
- return "\xD9\x87";
- break;
- case 0xAA :
- return "\xD9\x87";
- break;
- case 0xAB :
- return "\xD9\x87";
- break;
- case 0xAC :
- return "\xD9\x87";
- break;
- case 0xAD :
- return "\xD9\x88";
- break;
- case 0xAE :
- return "\xD9\x88";
- break;
- case 0xAF :
- return "\xD9\x89";
- break;
- case 0xB0 :
- return "\xD9\x89";
- break;
- case 0xB1 :
- return "\xD9\x8A";
- break;
- case 0xB2 :
- return "\xD9\x8A";
- break;
- case 0xB3 :
- return "\xD9\x8A";
- break;
- case 0xB4 :
- return "\xD9\x8A";
- break;
- case 0xB5 :
- return "\xD9\x84\xD8\xA2";
- break;
- case 0xB6 :
- return "\xD9\x84\xD8\xA2";
- break;
- case 0xB7 :
- return "\xD9\x84\xD8\xA3";
- break;
- case 0xB8 :
- return "\xD9\x84\xD8\xA3";
- break;
- case 0xB9 :
- return "\xD9\x84\xD8\xA5";
- break;
- case 0xBA :
- return "\xD9\x84\xD8\xA5";
- break;
- case 0xBB :
- return "\xD9\x84\xD8\xA7";
- break;
- case 0xBC :
- return "\xD9\x84\xD8\xA7";
- break;
- }
- break;
- case 0xBC :
- switch (str[2]) {
- case 0x81 :
- return "\x21";
- break;
- case 0x82 :
- return "\x22";
- break;
- case 0x83 :
- return "\x23";
- break;
- case 0x84 :
- return "\x24";
- break;
- case 0x85 :
- return "\x25";
- break;
- case 0x86 :
- return "\x26";
- break;
- case 0x87 :
- return "\x27";
- break;
- case 0x88 :
- return "\x28";
- break;
- case 0x89 :
- return "\x29";
- break;
- case 0x8A :
- return "\x2A";
- break;
- case 0x8B :
- return "\x2B";
- break;
- case 0x8C :
- return "\x2C";
- break;
- case 0x8D :
- return "\x2D";
- break;
- case 0x8E :
- return "\x2E";
- break;
- case 0x8F :
- return "\x2F";
- break;
- case 0x90 :
- return "\x30";
- break;
- case 0x91 :
- return "\x31";
- break;
- case 0x92 :
- return "\x32";
- break;
- case 0x93 :
- return "\x33";
- break;
- case 0x94 :
- return "\x34";
- break;
- case 0x95 :
- return "\x35";
- break;
- case 0x96 :
- return "\x36";
- break;
- case 0x97 :
- return "\x37";
- break;
- case 0x98 :
- return "\x38";
- break;
- case 0x99 :
- return "\x39";
- break;
- case 0x9A :
- return "\x3A";
- break;
- case 0x9B :
- return "\x3B";
- break;
- case 0x9C :
- return "\x3C";
- break;
- case 0x9D :
- return "\x3D";
- break;
- case 0x9E :
- return "\x3E";
- break;
- case 0x9F :
- return "\x3F";
- break;
- case 0xA0 :
- return "\x40";
- break;
- case 0xA1 :
- return "\x61";
- break;
- case 0xA2 :
- return "\x62";
- break;
- case 0xA3 :
- return "\x63";
- break;
- case 0xA4 :
- return "\x64";
- break;
- case 0xA5 :
- return "\x65";
- break;
- case 0xA6 :
- return "\x66";
- break;
- case 0xA7 :
- return "\x67";
- break;
- case 0xA8 :
- return "\x68";
- break;
- case 0xA9 :
- return "\x69";
- break;
- case 0xAA :
- return "\x6A";
- break;
- case 0xAB :
- return "\x6B";
- break;
- case 0xAC :
- return "\x6C";
- break;
- case 0xAD :
- return "\x6D";
- break;
- case 0xAE :
- return "\x6E";
- break;
- case 0xAF :
- return "\x6F";
- break;
- case 0xB0 :
- return "\x70";
- break;
- case 0xB1 :
- return "\x71";
- break;
- case 0xB2 :
- return "\x72";
- break;
- case 0xB3 :
- return "\x73";
- break;
- case 0xB4 :
- return "\x74";
- break;
- case 0xB5 :
- return "\x75";
- break;
- case 0xB6 :
- return "\x76";
- break;
- case 0xB7 :
- return "\x77";
- break;
- case 0xB8 :
- return "\x78";
- break;
- case 0xB9 :
- return "\x79";
- break;
- case 0xBA :
- return "\x7A";
- break;
- case 0xBB :
- return "\x5B";
- break;
- case 0xBC :
- return "\x5C";
- break;
- case 0xBD :
- return "\x5D";
- break;
- case 0xBE :
- return "\x5E";
- break;
- case 0xBF :
- return "\x5F";
- break;
- }
- break;
- case 0xBD :
- switch (str[2]) {
- case 0x80 :
- return "\x60";
- break;
- case 0x81 :
- return "\x61";
- break;
- case 0x82 :
- return "\x62";
- break;
- case 0x83 :
- return "\x63";
- break;
- case 0x84 :
- return "\x64";
- break;
- case 0x85 :
- return "\x65";
- break;
- case 0x86 :
- return "\x66";
- break;
- case 0x87 :
- return "\x67";
- break;
- case 0x88 :
- return "\x68";
- break;
- case 0x89 :
- return "\x69";
- break;
- case 0x8A :
- return "\x6A";
- break;
- case 0x8B :
- return "\x6B";
- break;
- case 0x8C :
- return "\x6C";
- break;
- case 0x8D :
- return "\x6D";
- break;
- case 0x8E :
- return "\x6E";
- break;
- case 0x8F :
- return "\x6F";
- break;
- case 0x90 :
- return "\x70";
- break;
- case 0x91 :
- return "\x71";
- break;
- case 0x92 :
- return "\x72";
- break;
- case 0x93 :
- return "\x73";
- break;
- case 0x94 :
- return "\x74";
- break;
- case 0x95 :
- return "\x75";
- break;
- case 0x96 :
- return "\x76";
- break;
- case 0x97 :
- return "\x77";
- break;
- case 0x98 :
- return "\x78";
- break;
- case 0x99 :
- return "\x79";
- break;
- case 0x9A :
- return "\x7A";
- break;
- case 0x9B :
- return "\x7B";
- break;
- case 0x9C :
- return "\x7C";
- break;
- case 0x9D :
- return "\x7D";
- break;
- case 0x9E :
- return "\x7E";
- break;
- case 0x9F :
- return "\xE2\xA6\x85";
- break;
- case 0xA0 :
- return "\xE2\xA6\x86";
- break;
- case 0xA1 :
- return "\xE3\x80\x82";
- break;
- case 0xA2 :
- return "\xE3\x80\x8C";
- break;
- case 0xA3 :
- return "\xE3\x80\x8D";
- break;
- case 0xA4 :
- return "\xE3\x80\x81";
- break;
- case 0xA5 :
- return "\xE3\x83\xBB";
- break;
- case 0xA6 :
- return "\xE3\x83\xB2";
- break;
- case 0xA7 :
- return "\xE3\x82\xA1";
- break;
- case 0xA8 :
- return "\xE3\x82\xA3";
- break;
- case 0xA9 :
- return "\xE3\x82\xA5";
- break;
- case 0xAA :
- return "\xE3\x82\xA7";
- break;
- case 0xAB :
- return "\xE3\x82\xA9";
- break;
- case 0xAC :
- return "\xE3\x83\xA3";
- break;
- case 0xAD :
- return "\xE3\x83\xA5";
- break;
- case 0xAE :
- return "\xE3\x83\xA7";
- break;
- case 0xAF :
- return "\xE3\x83\x83";
- break;
- case 0xB0 :
- return "\xE3\x83\xBC";
- break;
- case 0xB1 :
- return "\xE3\x82\xA2";
- break;
- case 0xB2 :
- return "\xE3\x82\xA4";
- break;
- case 0xB3 :
- return "\xE3\x82\xA6";
- break;
- case 0xB4 :
- return "\xE3\x82\xA8";
- break;
- case 0xB5 :
- return "\xE3\x82\xAA";
- break;
- case 0xB6 :
- return "\xE3\x82\xAB";
- break;
- case 0xB7 :
- return "\xE3\x82\xAD";
- break;
- case 0xB8 :
- return "\xE3\x82\xAF";
- break;
- case 0xB9 :
- return "\xE3\x82\xB1";
- break;
- case 0xBA :
- return "\xE3\x82\xB3";
- break;
- case 0xBB :
- return "\xE3\x82\xB5";
- break;
- case 0xBC :
- return "\xE3\x82\xB7";
- break;
- case 0xBD :
- return "\xE3\x82\xB9";
- break;
- case 0xBE :
- return "\xE3\x82\xBB";
- break;
- case 0xBF :
- return "\xE3\x82\xBD";
- break;
- }
- break;
- case 0xBE :
- switch (str[2]) {
- case 0x80 :
- return "\xE3\x82\xBF";
- break;
- case 0x81 :
- return "\xE3\x83\x81";
- break;
- case 0x82 :
- return "\xE3\x83\x84";
- break;
- case 0x83 :
- return "\xE3\x83\x86";
- break;
- case 0x84 :
- return "\xE3\x83\x88";
- break;
- case 0x85 :
- return "\xE3\x83\x8A";
- break;
- case 0x86 :
- return "\xE3\x83\x8B";
- break;
- case 0x87 :
- return "\xE3\x83\x8C";
- break;
- case 0x88 :
- return "\xE3\x83\x8D";
- break;
- case 0x89 :
- return "\xE3\x83\x8E";
- break;
- case 0x8A :
- return "\xE3\x83\x8F";
- break;
- case 0x8B :
- return "\xE3\x83\x92";
- break;
- case 0x8C :
- return "\xE3\x83\x95";
- break;
- case 0x8D :
- return "\xE3\x83\x98";
- break;
- case 0x8E :
- return "\xE3\x83\x9B";
- break;
- case 0x8F :
- return "\xE3\x83\x9E";
- break;
- case 0x90 :
- return "\xE3\x83\x9F";
- break;
- case 0x91 :
- return "\xE3\x83\xA0";
- break;
- case 0x92 :
- return "\xE3\x83\xA1";
- break;
- case 0x93 :
- return "\xE3\x83\xA2";
- break;
- case 0x94 :
- return "\xE3\x83\xA4";
- break;
- case 0x95 :
- return "\xE3\x83\xA6";
- break;
- case 0x96 :
- return "\xE3\x83\xA8";
- break;
- case 0x97 :
- return "\xE3\x83\xA9";
- break;
- case 0x98 :
- return "\xE3\x83\xAA";
- break;
- case 0x99 :
- return "\xE3\x83\xAB";
- break;
- case 0x9A :
- return "\xE3\x83\xAC";
- break;
- case 0x9B :
- return "\xE3\x83\xAD";
- break;
- case 0x9C :
- return "\xE3\x83\xAF";
- break;
- case 0x9D :
- return "\xE3\x83\xB3";
- break;
- case 0x9E :
- return "\xE3\x82\x99";
- break;
- case 0x9F :
- return "\xE3\x82\x9A";
- break;
- case 0xA0 :
- return "\xE1\x85\xA0";
- break;
- case 0xA1 :
- return "\xE1\x84\x80";
- break;
- case 0xA2 :
- return "\xE1\x84\x81";
- break;
- case 0xA3 :
- return "\xE1\x86\xAA";
- break;
- case 0xA4 :
- return "\xE1\x84\x82";
- break;
- case 0xA5 :
- return "\xE1\x86\xAC";
- break;
- case 0xA6 :
- return "\xE1\x86\xAD";
- break;
- case 0xA7 :
- return "\xE1\x84\x83";
- break;
- case 0xA8 :
- return "\xE1\x84\x84";
- break;
- case 0xA9 :
- return "\xE1\x84\x85";
- break;
- case 0xAA :
- return "\xE1\x86\xB0";
- break;
- case 0xAB :
- return "\xE1\x86\xB1";
- break;
- case 0xAC :
- return "\xE1\x86\xB2";
- break;
- case 0xAD :
- return "\xE1\x86\xB3";
- break;
- case 0xAE :
- return "\xE1\x86\xB4";
- break;
- case 0xAF :
- return "\xE1\x86\xB5";
- break;
- case 0xB0 :
- return "\xE1\x84\x9A";
- break;
- case 0xB1 :
- return "\xE1\x84\x86";
- break;
- case 0xB2 :
- return "\xE1\x84\x87";
- break;
- case 0xB3 :
- return "\xE1\x84\x88";
- break;
- case 0xB4 :
- return "\xE1\x84\xA1";
- break;
- case 0xB5 :
- return "\xE1\x84\x89";
- break;
- case 0xB6 :
- return "\xE1\x84\x8A";
- break;
- case 0xB7 :
- return "\xE1\x84\x8B";
- break;
- case 0xB8 :
- return "\xE1\x84\x8C";
- break;
- case 0xB9 :
- return "\xE1\x84\x8D";
- break;
- case 0xBA :
- return "\xE1\x84\x8E";
- break;
- case 0xBB :
- return "\xE1\x84\x8F";
- break;
- case 0xBC :
- return "\xE1\x84\x90";
- break;
- case 0xBD :
- return "\xE1\x84\x91";
- break;
- case 0xBE :
- return "\xE1\x84\x92";
- break;
- }
- break;
- case 0xBF :
- switch (str[2]) {
- case 0x82 :
- return "\xE1\x85\xA1";
- break;
- case 0x83 :
- return "\xE1\x85\xA2";
- break;
- case 0x84 :
- return "\xE1\x85\xA3";
- break;
- case 0x85 :
- return "\xE1\x85\xA4";
- break;
- case 0x86 :
- return "\xE1\x85\xA5";
- break;
- case 0x87 :
- return "\xE1\x85\xA6";
- break;
- case 0x8A :
- return "\xE1\x85\xA7";
- break;
- case 0x8B :
- return "\xE1\x85\xA8";
- break;
- case 0x8C :
- return "\xE1\x85\xA9";
- break;
- case 0x8D :
- return "\xE1\x85\xAA";
- break;
- case 0x8E :
- return "\xE1\x85\xAB";
- break;
- case 0x8F :
- return "\xE1\x85\xAC";
- break;
- case 0x92 :
- return "\xE1\x85\xAD";
- break;
- case 0x93 :
- return "\xE1\x85\xAE";
- break;
- case 0x94 :
- return "\xE1\x85\xAF";
- break;
- case 0x95 :
- return "\xE1\x85\xB0";
- break;
- case 0x96 :
- return "\xE1\x85\xB1";
- break;
- case 0x97 :
- return "\xE1\x85\xB2";
- break;
- case 0x9A :
- return "\xE1\x85\xB3";
- break;
- case 0x9B :
- return "\xE1\x85\xB4";
- break;
- case 0x9C :
- return "\xE1\x85\xB5";
- break;
- case 0xA0 :
- return "\xC2\xA2";
- break;
- case 0xA1 :
- return "\xC2\xA3";
- break;
- case 0xA2 :
- return "\xC2\xAC";
- break;
- case 0xA3 :
- return "\xCC\x84";
- break;
- case 0xA4 :
- return "\xC2\xA6";
- break;
- case 0xA5 :
- return "\xC2\xA5";
- break;
- case 0xA6 :
- return "\xE2\x82\xA9";
- break;
- case 0xA8 :
- return "\xE2\x94\x82";
- break;
- case 0xA9 :
- return "\xE2\x86\x90";
- break;
- case 0xAA :
- return "\xE2\x86\x91";
- break;
- case 0xAB :
- return "\xE2\x86\x92";
- break;
- case 0xAC :
- return "\xE2\x86\x93";
- break;
- case 0xAD :
- return "\xE2\x96\xA0";
- break;
- case 0xAE :
- return "\xE2\x97\x8B";
- break;
- }
- break;
- }
- break;
-case 0xF0 :
- switch (str[1]) {
- case 0x9D :
- switch (str[2]) {
- case 0x85 :
- switch (str[3]) {
- case 0x9E :
- return "\xF0\x9D\x85\x97\xF0\x9D\x85\xA5";
- break;
- case 0x9F :
- return "\xF0\x9D\x85\x98\xF0\x9D\x85\xA5";
- break;
- case 0xA0 :
- return "\xF0\x9D\x85\x98\xF0\x9D\x85\xA5\xF0\x9D\x85\xAE";
- break;
- case 0xA1 :
- return "\xF0\x9D\x85\x98\xF0\x9D\x85\xA5\xF0\x9D\x85\xAF";
- break;
- case 0xA2 :
- return "\xF0\x9D\x85\x98\xF0\x9D\x85\xA5\xF0\x9D\x85\xB0";
- break;
- case 0xA3 :
- return "\xF0\x9D\x85\x98\xF0\x9D\x85\xA5\xF0\x9D\x85\xB1";
- break;
- case 0xA4 :
- return "\xF0\x9D\x85\x98\xF0\x9D\x85\xA5\xF0\x9D\x85\xB2";
- break;
- }
- break;
- case 0x86 :
- switch (str[3]) {
- case 0xBB :
- return "\xF0\x9D\x86\xB9\xF0\x9D\x85\xA5";
- break;
- case 0xBC :
- return "\xF0\x9D\x86\xBA\xF0\x9D\x85\xA5";
- break;
- case 0xBD :
- return "\xF0\x9D\x86\xB9\xF0\x9D\x85\xA5\xF0\x9D\x85\xAE";
- break;
- case 0xBE :
- return "\xF0\x9D\x86\xBA\xF0\x9D\x85\xA5\xF0\x9D\x85\xAE";
- break;
- case 0xBF :
- return "\xF0\x9D\x86\xB9\xF0\x9D\x85\xA5\xF0\x9D\x85\xAF";
- break;
- }
- break;
- case 0x87 :
- if (str[3] == 0x80) {
- return "\xF0\x9D\x86\xBA\xF0\x9D\x85\xA5\xF0\x9D\x85\xAF";
- }
- break;
- case 0x90 :
- switch (str[3]) {
- case 0x80 :
- return "\x61";
- break;
- case 0x81 :
- return "\x62";
- break;
- case 0x82 :
- return "\x63";
- break;
- case 0x83 :
- return "\x64";
- break;
- case 0x84 :
- return "\x65";
- break;
- case 0x85 :
- return "\x66";
- break;
- case 0x86 :
- return "\x67";
- break;
- case 0x87 :
- return "\x68";
- break;
- case 0x88 :
- return "\x69";
- break;
- case 0x89 :
- return "\x6A";
- break;
- case 0x8A :
- return "\x6B";
- break;
- case 0x8B :
- return "\x6C";
- break;
- case 0x8C :
- return "\x6D";
- break;
- case 0x8D :
- return "\x6E";
- break;
- case 0x8E :
- return "\x6F";
- break;
- case 0x8F :
- return "\x70";
- break;
- case 0x90 :
- return "\x71";
- break;
- case 0x91 :
- return "\x72";
- break;
- case 0x92 :
- return "\x73";
- break;
- case 0x93 :
- return "\x74";
- break;
- case 0x94 :
- return "\x75";
- break;
- case 0x95 :
- return "\x76";
- break;
- case 0x96 :
- return "\x77";
- break;
- case 0x97 :
- return "\x78";
- break;
- case 0x98 :
- return "\x79";
- break;
- case 0x99 :
- return "\x7A";
- break;
- case 0x9A :
- return "\x61";
- break;
- case 0x9B :
- return "\x62";
- break;
- case 0x9C :
- return "\x63";
- break;
- case 0x9D :
- return "\x64";
- break;
- case 0x9E :
- return "\x65";
- break;
- case 0x9F :
- return "\x66";
- break;
- case 0xA0 :
- return "\x67";
- break;
- case 0xA1 :
- return "\x68";
- break;
- case 0xA2 :
- return "\x69";
- break;
- case 0xA3 :
- return "\x6A";
- break;
- case 0xA4 :
- return "\x6B";
- break;
- case 0xA5 :
- return "\x6C";
- break;
- case 0xA6 :
- return "\x6D";
- break;
- case 0xA7 :
- return "\x6E";
- break;
- case 0xA8 :
- return "\x6F";
- break;
- case 0xA9 :
- return "\x70";
- break;
- case 0xAA :
- return "\x71";
- break;
- case 0xAB :
- return "\x72";
- break;
- case 0xAC :
- return "\x73";
- break;
- case 0xAD :
- return "\x74";
- break;
- case 0xAE :
- return "\x75";
- break;
- case 0xAF :
- return "\x76";
- break;
- case 0xB0 :
- return "\x77";
- break;
- case 0xB1 :
- return "\x78";
- break;
- case 0xB2 :
- return "\x79";
- break;
- case 0xB3 :
- return "\x7A";
- break;
- case 0xB4 :
- return "\x61";
- break;
- case 0xB5 :
- return "\x62";
- break;
- case 0xB6 :
- return "\x63";
- break;
- case 0xB7 :
- return "\x64";
- break;
- case 0xB8 :
- return "\x65";
- break;
- case 0xB9 :
- return "\x66";
- break;
- case 0xBA :
- return "\x67";
- break;
- case 0xBB :
- return "\x68";
- break;
- case 0xBC :
- return "\x69";
- break;
- case 0xBD :
- return "\x6A";
- break;
- case 0xBE :
- return "\x6B";
- break;
- case 0xBF :
- return "\x6C";
- break;
- }
- break;
- case 0x91 :
- switch (str[3]) {
- case 0x80 :
- return "\x6D";
- break;
- case 0x81 :
- return "\x6E";
- break;
- case 0x82 :
- return "\x6F";
- break;
- case 0x83 :
- return "\x70";
- break;
- case 0x84 :
- return "\x71";
- break;
- case 0x85 :
- return "\x72";
- break;
- case 0x86 :
- return "\x73";
- break;
- case 0x87 :
- return "\x74";
- break;
- case 0x88 :
- return "\x75";
- break;
- case 0x89 :
- return "\x76";
- break;
- case 0x8A :
- return "\x77";
- break;
- case 0x8B :
- return "\x78";
- break;
- case 0x8C :
- return "\x79";
- break;
- case 0x8D :
- return "\x7A";
- break;
- case 0x8E :
- return "\x61";
- break;
- case 0x8F :
- return "\x62";
- break;
- case 0x90 :
- return "\x63";
- break;
- case 0x91 :
- return "\x64";
- break;
- case 0x92 :
- return "\x65";
- break;
- case 0x93 :
- return "\x66";
- break;
- case 0x94 :
- return "\x67";
- break;
- case 0x96 :
- return "\x69";
- break;
- case 0x97 :
- return "\x6A";
- break;
- case 0x98 :
- return "\x6B";
- break;
- case 0x99 :
- return "\x6C";
- break;
- case 0x9A :
- return "\x6D";
- break;
- case 0x9B :
- return "\x6E";
- break;
- case 0x9C :
- return "\x6F";
- break;
- case 0x9D :
- return "\x70";
- break;
- case 0x9E :
- return "\x71";
- break;
- case 0x9F :
- return "\x72";
- break;
- case 0xA0 :
- return "\x73";
- break;
- case 0xA1 :
- return "\x74";
- break;
- case 0xA2 :
- return "\x75";
- break;
- case 0xA3 :
- return "\x76";
- break;
- case 0xA4 :
- return "\x77";
- break;
- case 0xA5 :
- return "\x78";
- break;
- case 0xA6 :
- return "\x79";
- break;
- case 0xA7 :
- return "\x7A";
- break;
- case 0xA8 :
- return "\x61";
- break;
- case 0xA9 :
- return "\x62";
- break;
- case 0xAA :
- return "\x63";
- break;
- case 0xAB :
- return "\x64";
- break;
- case 0xAC :
- return "\x65";
- break;
- case 0xAD :
- return "\x66";
- break;
- case 0xAE :
- return "\x67";
- break;
- case 0xAF :
- return "\x68";
- break;
- case 0xB0 :
- return "\x69";
- break;
- case 0xB1 :
- return "\x6A";
- break;
- case 0xB2 :
- return "\x6B";
- break;
- case 0xB3 :
- return "\x6C";
- break;
- case 0xB4 :
- return "\x6D";
- break;
- case 0xB5 :
- return "\x6E";
- break;
- case 0xB6 :
- return "\x6F";
- break;
- case 0xB7 :
- return "\x70";
- break;
- case 0xB8 :
- return "\x71";
- break;
- case 0xB9 :
- return "\x72";
- break;
- case 0xBA :
- return "\x73";
- break;
- case 0xBB :
- return "\x74";
- break;
- case 0xBC :
- return "\x75";
- break;
- case 0xBD :
- return "\x76";
- break;
- case 0xBE :
- return "\x77";
- break;
- case 0xBF :
- return "\x78";
- break;
- }
- break;
- case 0x92 :
- switch (str[3]) {
- case 0x80 :
- return "\x79";
- break;
- case 0x81 :
- return "\x7A";
- break;
- case 0x82 :
- return "\x61";
- break;
- case 0x83 :
- return "\x62";
- break;
- case 0x84 :
- return "\x63";
- break;
- case 0x85 :
- return "\x64";
- break;
- case 0x86 :
- return "\x65";
- break;
- case 0x87 :
- return "\x66";
- break;
- case 0x88 :
- return "\x67";
- break;
- case 0x89 :
- return "\x68";
- break;
- case 0x8A :
- return "\x69";
- break;
- case 0x8B :
- return "\x6A";
- break;
- case 0x8C :
- return "\x6B";
- break;
- case 0x8D :
- return "\x6C";
- break;
- case 0x8E :
- return "\x6D";
- break;
- case 0x8F :
- return "\x6E";
- break;
- case 0x90 :
- return "\x6F";
- break;
- case 0x91 :
- return "\x70";
- break;
- case 0x92 :
- return "\x71";
- break;
- case 0x93 :
- return "\x72";
- break;
- case 0x94 :
- return "\x73";
- break;
- case 0x95 :
- return "\x74";
- break;
- case 0x96 :
- return "\x75";
- break;
- case 0x97 :
- return "\x76";
- break;
- case 0x98 :
- return "\x77";
- break;
- case 0x99 :
- return "\x78";
- break;
- case 0x9A :
- return "\x79";
- break;
- case 0x9B :
- return "\x7A";
- break;
- case 0x9C :
- return "\x61";
- break;
- case 0x9E :
- return "\x63";
- break;
- case 0x9F :
- return "\x64";
- break;
- case 0xA2 :
- return "\x67";
- break;
- case 0xA5 :
- return "\x6A";
- break;
- case 0xA6 :
- return "\x6B";
- break;
- case 0xA9 :
- return "\x6E";
- break;
- case 0xAA :
- return "\x6F";
- break;
- case 0xAB :
- return "\x70";
- break;
- case 0xAC :
- return "\x71";
- break;
- case 0xAE :
- return "\x73";
- break;
- case 0xAF :
- return "\x74";
- break;
- case 0xB0 :
- return "\x75";
- break;
- case 0xB1 :
- return "\x76";
- break;
- case 0xB2 :
- return "\x77";
- break;
- case 0xB3 :
- return "\x78";
- break;
- case 0xB4 :
- return "\x79";
- break;
- case 0xB5 :
- return "\x7A";
- break;
- case 0xB6 :
- return "\x61";
- break;
- case 0xB7 :
- return "\x62";
- break;
- case 0xB8 :
- return "\x63";
- break;
- case 0xB9 :
- return "\x64";
- break;
- case 0xBB :
- return "\x66";
- break;
- case 0xBD :
- return "\x68";
- break;
- case 0xBE :
- return "\x69";
- break;
- case 0xBF :
- return "\x6A";
- break;
- }
- break;
- case 0x93 :
- switch (str[3]) {
- case 0x80 :
- return "\x6B";
- break;
- case 0x81 :
- return "\x6C";
- break;
- case 0x82 :
- return "\x6D";
- break;
- case 0x83 :
- return "\x6E";
- break;
- case 0x85 :
- return "\x70";
- break;
- case 0x86 :
- return "\x71";
- break;
- case 0x87 :
- return "\x72";
- break;
- case 0x88 :
- return "\x73";
- break;
- case 0x89 :
- return "\x74";
- break;
- case 0x8A :
- return "\x75";
- break;
- case 0x8B :
- return "\x76";
- break;
- case 0x8C :
- return "\x77";
- break;
- case 0x8D :
- return "\x78";
- break;
- case 0x8E :
- return "\x79";
- break;
- case 0x8F :
- return "\x7A";
- break;
- case 0x90 :
- return "\x61";
- break;
- case 0x91 :
- return "\x62";
- break;
- case 0x92 :
- return "\x63";
- break;
- case 0x93 :
- return "\x64";
- break;
- case 0x94 :
- return "\x65";
- break;
- case 0x95 :
- return "\x66";
- break;
- case 0x96 :
- return "\x67";
- break;
- case 0x97 :
- return "\x68";
- break;
- case 0x98 :
- return "\x69";
- break;
- case 0x99 :
- return "\x6A";
- break;
- case 0x9A :
- return "\x6B";
- break;
- case 0x9B :
- return "\x6C";
- break;
- case 0x9C :
- return "\x6D";
- break;
- case 0x9D :
- return "\x6E";
- break;
- case 0x9E :
- return "\x6F";
- break;
- case 0x9F :
- return "\x70";
- break;
- case 0xA0 :
- return "\x71";
- break;
- case 0xA1 :
- return "\x72";
- break;
- case 0xA2 :
- return "\x73";
- break;
- case 0xA3 :
- return "\x74";
- break;
- case 0xA4 :
- return "\x75";
- break;
- case 0xA5 :
- return "\x76";
- break;
- case 0xA6 :
- return "\x77";
- break;
- case 0xA7 :
- return "\x78";
- break;
- case 0xA8 :
- return "\x79";
- break;
- case 0xA9 :
- return "\x7A";
- break;
- case 0xAA :
- return "\x61";
- break;
- case 0xAB :
- return "\x62";
- break;
- case 0xAC :
- return "\x63";
- break;
- case 0xAD :
- return "\x64";
- break;
- case 0xAE :
- return "\x65";
- break;
- case 0xAF :
- return "\x66";
- break;
- case 0xB0 :
- return "\x67";
- break;
- case 0xB1 :
- return "\x68";
- break;
- case 0xB2 :
- return "\x69";
- break;
- case 0xB3 :
- return "\x6A";
- break;
- case 0xB4 :
- return "\x6B";
- break;
- case 0xB5 :
- return "\x6C";
- break;
- case 0xB6 :
- return "\x6D";
- break;
- case 0xB7 :
- return "\x6E";
- break;
- case 0xB8 :
- return "\x6F";
- break;
- case 0xB9 :
- return "\x70";
- break;
- case 0xBA :
- return "\x71";
- break;
- case 0xBB :
- return "\x72";
- break;
- case 0xBC :
- return "\x73";
- break;
- case 0xBD :
- return "\x74";
- break;
- case 0xBE :
- return "\x75";
- break;
- case 0xBF :
- return "\x76";
- break;
- }
- break;
- case 0x94 :
- switch (str[3]) {
- case 0x80 :
- return "\x77";
- break;
- case 0x81 :
- return "\x78";
- break;
- case 0x82 :
- return "\x79";
- break;
- case 0x83 :
- return "\x7A";
- break;
- case 0x84 :
- return "\x61";
- break;
- case 0x85 :
- return "\x62";
- break;
- case 0x87 :
- return "\x64";
- break;
- case 0x88 :
- return "\x65";
- break;
- case 0x89 :
- return "\x66";
- break;
- case 0x8A :
- return "\x67";
- break;
- case 0x8D :
- return "\x6A";
- break;
- case 0x8E :
- return "\x6B";
- break;
- case 0x8F :
- return "\x6C";
- break;
- case 0x90 :
- return "\x6D";
- break;
- case 0x91 :
- return "\x6E";
- break;
- case 0x92 :
- return "\x6F";
- break;
- case 0x93 :
- return "\x70";
- break;
- case 0x94 :
- return "\x71";
- break;
- case 0x96 :
- return "\x73";
- break;
- case 0x97 :
- return "\x74";
- break;
- case 0x98 :
- return "\x75";
- break;
- case 0x99 :
- return "\x76";
- break;
- case 0x9A :
- return "\x77";
- break;
- case 0x9B :
- return "\x78";
- break;
- case 0x9C :
- return "\x79";
- break;
- case 0x9E :
- return "\x61";
- break;
- case 0x9F :
- return "\x62";
- break;
- case 0xA0 :
- return "\x63";
- break;
- case 0xA1 :
- return "\x64";
- break;
- case 0xA2 :
- return "\x65";
- break;
- case 0xA3 :
- return "\x66";
- break;
- case 0xA4 :
- return "\x67";
- break;
- case 0xA5 :
- return "\x68";
- break;
- case 0xA6 :
- return "\x69";
- break;
- case 0xA7 :
- return "\x6A";
- break;
- case 0xA8 :
- return "\x6B";
- break;
- case 0xA9 :
- return "\x6C";
- break;
- case 0xAA :
- return "\x6D";
- break;
- case 0xAB :
- return "\x6E";
- break;
- case 0xAC :
- return "\x6F";
- break;
- case 0xAD :
- return "\x70";
- break;
- case 0xAE :
- return "\x71";
- break;
- case 0xAF :
- return "\x72";
- break;
- case 0xB0 :
- return "\x73";
- break;
- case 0xB1 :
- return "\x74";
- break;
- case 0xB2 :
- return "\x75";
- break;
- case 0xB3 :
- return "\x76";
- break;
- case 0xB4 :
- return "\x77";
- break;
- case 0xB5 :
- return "\x78";
- break;
- case 0xB6 :
- return "\x79";
- break;
- case 0xB7 :
- return "\x7A";
- break;
- case 0xB8 :
- return "\x61";
- break;
- case 0xB9 :
- return "\x62";
- break;
- case 0xBB :
- return "\x64";
- break;
- case 0xBC :
- return "\x65";
- break;
- case 0xBD :
- return "\x66";
- break;
- case 0xBE :
- return "\x67";
- break;
- }
- break;
- case 0x95 :
- switch (str[3]) {
- case 0x80 :
- return "\x69";
- break;
- case 0x81 :
- return "\x6A";
- break;
- case 0x82 :
- return "\x6B";
- break;
- case 0x83 :
- return "\x6C";
- break;
- case 0x84 :
- return "\x6D";
- break;
- case 0x86 :
- return "\x6F";
- break;
- case 0x8A :
- return "\x73";
- break;
- case 0x8B :
- return "\x74";
- break;
- case 0x8C :
- return "\x75";
- break;
- case 0x8D :
- return "\x76";
- break;
- case 0x8E :
- return "\x77";
- break;
- case 0x8F :
- return "\x78";
- break;
- case 0x90 :
- return "\x79";
- break;
- case 0x92 :
- return "\x61";
- break;
- case 0x93 :
- return "\x62";
- break;
- case 0x94 :
- return "\x63";
- break;
- case 0x95 :
- return "\x64";
- break;
- case 0x96 :
- return "\x65";
- break;
- case 0x97 :
- return "\x66";
- break;
- case 0x98 :
- return "\x67";
- break;
- case 0x99 :
- return "\x68";
- break;
- case 0x9A :
- return "\x69";
- break;
- case 0x9B :
- return "\x6A";
- break;
- case 0x9C :
- return "\x6B";
- break;
- case 0x9D :
- return "\x6C";
- break;
- case 0x9E :
- return "\x6D";
- break;
- case 0x9F :
- return "\x6E";
- break;
- case 0xA0 :
- return "\x6F";
- break;
- case 0xA1 :
- return "\x70";
- break;
- case 0xA2 :
- return "\x71";
- break;
- case 0xA3 :
- return "\x72";
- break;
- case 0xA4 :
- return "\x73";
- break;
- case 0xA5 :
- return "\x74";
- break;
- case 0xA6 :
- return "\x75";
- break;
- case 0xA7 :
- return "\x76";
- break;
- case 0xA8 :
- return "\x77";
- break;
- case 0xA9 :
- return "\x78";
- break;
- case 0xAA :
- return "\x79";
- break;
- case 0xAB :
- return "\x7A";
- break;
- case 0xAC :
- return "\x61";
- break;
- case 0xAD :
- return "\x62";
- break;
- case 0xAE :
- return "\x63";
- break;
- case 0xAF :
- return "\x64";
- break;
- case 0xB0 :
- return "\x65";
- break;
- case 0xB1 :
- return "\x66";
- break;
- case 0xB2 :
- return "\x67";
- break;
- case 0xB3 :
- return "\x68";
- break;
- case 0xB4 :
- return "\x69";
- break;
- case 0xB5 :
- return "\x6A";
- break;
- case 0xB6 :
- return "\x6B";
- break;
- case 0xB7 :
- return "\x6C";
- break;
- case 0xB8 :
- return "\x6D";
- break;
- case 0xB9 :
- return "\x6E";
- break;
- case 0xBA :
- return "\x6F";
- break;
- case 0xBB :
- return "\x70";
- break;
- case 0xBC :
- return "\x71";
- break;
- case 0xBD :
- return "\x72";
- break;
- case 0xBE :
- return "\x73";
- break;
- case 0xBF :
- return "\x74";
- break;
- }
- break;
- case 0x96 :
- switch (str[3]) {
- case 0x80 :
- return "\x75";
- break;
- case 0x81 :
- return "\x76";
- break;
- case 0x82 :
- return "\x77";
- break;
- case 0x83 :
- return "\x78";
- break;
- case 0x84 :
- return "\x79";
- break;
- case 0x85 :
- return "\x7A";
- break;
- case 0x86 :
- return "\x61";
- break;
- case 0x87 :
- return "\x62";
- break;
- case 0x88 :
- return "\x63";
- break;
- case 0x89 :
- return "\x64";
- break;
- case 0x8A :
- return "\x65";
- break;
- case 0x8B :
- return "\x66";
- break;
- case 0x8C :
- return "\x67";
- break;
- case 0x8D :
- return "\x68";
- break;
- case 0x8E :
- return "\x69";
- break;
- case 0x8F :
- return "\x6A";
- break;
- case 0x90 :
- return "\x6B";
- break;
- case 0x91 :
- return "\x6C";
- break;
- case 0x92 :
- return "\x6D";
- break;
- case 0x93 :
- return "\x6E";
- break;
- case 0x94 :
- return "\x6F";
- break;
- case 0x95 :
- return "\x70";
- break;
- case 0x96 :
- return "\x71";
- break;
- case 0x97 :
- return "\x72";
- break;
- case 0x98 :
- return "\x73";
- break;
- case 0x99 :
- return "\x74";
- break;
- case 0x9A :
- return "\x75";
- break;
- case 0x9B :
- return "\x76";
- break;
- case 0x9C :
- return "\x77";
- break;
- case 0x9D :
- return "\x78";
- break;
- case 0x9E :
- return "\x79";
- break;
- case 0x9F :
- return "\x7A";
- break;
- case 0xA0 :
- return "\x61";
- break;
- case 0xA1 :
- return "\x62";
- break;
- case 0xA2 :
- return "\x63";
- break;
- case 0xA3 :
- return "\x64";
- break;
- case 0xA4 :
- return "\x65";
- break;
- case 0xA5 :
- return "\x66";
- break;
- case 0xA6 :
- return "\x67";
- break;
- case 0xA7 :
- return "\x68";
- break;
- case 0xA8 :
- return "\x69";
- break;
- case 0xA9 :
- return "\x6A";
- break;
- case 0xAA :
- return "\x6B";
- break;
- case 0xAB :
- return "\x6C";
- break;
- case 0xAC :
- return "\x6D";
- break;
- case 0xAD :
- return "\x6E";
- break;
- case 0xAE :
- return "\x6F";
- break;
- case 0xAF :
- return "\x70";
- break;
- case 0xB0 :
- return "\x71";
- break;
- case 0xB1 :
- return "\x72";
- break;
- case 0xB2 :
- return "\x73";
- break;
- case 0xB3 :
- return "\x74";
- break;
- case 0xB4 :
- return "\x75";
- break;
- case 0xB5 :
- return "\x76";
- break;
- case 0xB6 :
- return "\x77";
- break;
- case 0xB7 :
- return "\x78";
- break;
- case 0xB8 :
- return "\x79";
- break;
- case 0xB9 :
- return "\x7A";
- break;
- case 0xBA :
- return "\x61";
- break;
- case 0xBB :
- return "\x62";
- break;
- case 0xBC :
- return "\x63";
- break;
- case 0xBD :
- return "\x64";
- break;
- case 0xBE :
- return "\x65";
- break;
- case 0xBF :
- return "\x66";
- break;
- }
- break;
- case 0x97 :
- switch (str[3]) {
- case 0x80 :
- return "\x67";
- break;
- case 0x81 :
- return "\x68";
- break;
- case 0x82 :
- return "\x69";
- break;
- case 0x83 :
- return "\x6A";
- break;
- case 0x84 :
- return "\x6B";
- break;
- case 0x85 :
- return "\x6C";
- break;
- case 0x86 :
- return "\x6D";
- break;
- case 0x87 :
- return "\x6E";
- break;
- case 0x88 :
- return "\x6F";
- break;
- case 0x89 :
- return "\x70";
- break;
- case 0x8A :
- return "\x71";
- break;
- case 0x8B :
- return "\x72";
- break;
- case 0x8C :
- return "\x73";
- break;
- case 0x8D :
- return "\x74";
- break;
- case 0x8E :
- return "\x75";
- break;
- case 0x8F :
- return "\x76";
- break;
- case 0x90 :
- return "\x77";
- break;
- case 0x91 :
- return "\x78";
- break;
- case 0x92 :
- return "\x79";
- break;
- case 0x93 :
- return "\x7A";
- break;
- case 0x94 :
- return "\x61";
- break;
- case 0x95 :
- return "\x62";
- break;
- case 0x96 :
- return "\x63";
- break;
- case 0x97 :
- return "\x64";
- break;
- case 0x98 :
- return "\x65";
- break;
- case 0x99 :
- return "\x66";
- break;
- case 0x9A :
- return "\x67";
- break;
- case 0x9B :
- return "\x68";
- break;
- case 0x9C :
- return "\x69";
- break;
- case 0x9D :
- return "\x6A";
- break;
- case 0x9E :
- return "\x6B";
- break;
- case 0x9F :
- return "\x6C";
- break;
- case 0xA0 :
- return "\x6D";
- break;
- case 0xA1 :
- return "\x6E";
- break;
- case 0xA2 :
- return "\x6F";
- break;
- case 0xA3 :
- return "\x70";
- break;
- case 0xA4 :
- return "\x71";
- break;
- case 0xA5 :
- return "\x72";
- break;
- case 0xA6 :
- return "\x73";
- break;
- case 0xA7 :
- return "\x74";
- break;
- case 0xA8 :
- return "\x75";
- break;
- case 0xA9 :
- return "\x76";
- break;
- case 0xAA :
- return "\x77";
- break;
- case 0xAB :
- return "\x78";
- break;
- case 0xAC :
- return "\x79";
- break;
- case 0xAD :
- return "\x7A";
- break;
- case 0xAE :
- return "\x61";
- break;
- case 0xAF :
- return "\x62";
- break;
- case 0xB0 :
- return "\x63";
- break;
- case 0xB1 :
- return "\x64";
- break;
- case 0xB2 :
- return "\x65";
- break;
- case 0xB3 :
- return "\x66";
- break;
- case 0xB4 :
- return "\x67";
- break;
- case 0xB5 :
- return "\x68";
- break;
- case 0xB6 :
- return "\x69";
- break;
- case 0xB7 :
- return "\x6A";
- break;
- case 0xB8 :
- return "\x6B";
- break;
- case 0xB9 :
- return "\x6C";
- break;
- case 0xBA :
- return "\x6D";
- break;
- case 0xBB :
- return "\x6E";
- break;
- case 0xBC :
- return "\x6F";
- break;
- case 0xBD :
- return "\x70";
- break;
- case 0xBE :
- return "\x71";
- break;
- case 0xBF :
- return "\x72";
- break;
- }
- break;
- case 0x98 :
- switch (str[3]) {
- case 0x80 :
- return "\x73";
- break;
- case 0x81 :
- return "\x74";
- break;
- case 0x82 :
- return "\x75";
- break;
- case 0x83 :
- return "\x76";
- break;
- case 0x84 :
- return "\x77";
- break;
- case 0x85 :
- return "\x78";
- break;
- case 0x86 :
- return "\x79";
- break;
- case 0x87 :
- return "\x7A";
- break;
- case 0x88 :
- return "\x61";
- break;
- case 0x89 :
- return "\x62";
- break;
- case 0x8A :
- return "\x63";
- break;
- case 0x8B :
- return "\x64";
- break;
- case 0x8C :
- return "\x65";
- break;
- case 0x8D :
- return "\x66";
- break;
- case 0x8E :
- return "\x67";
- break;
- case 0x8F :
- return "\x68";
- break;
- case 0x90 :
- return "\x69";
- break;
- case 0x91 :
- return "\x6A";
- break;
- case 0x92 :
- return "\x6B";
- break;
- case 0x93 :
- return "\x6C";
- break;
- case 0x94 :
- return "\x6D";
- break;
- case 0x95 :
- return "\x6E";
- break;
- case 0x96 :
- return "\x6F";
- break;
- case 0x97 :
- return "\x70";
- break;
- case 0x98 :
- return "\x71";
- break;
- case 0x99 :
- return "\x72";
- break;
- case 0x9A :
- return "\x73";
- break;
- case 0x9B :
- return "\x74";
- break;
- case 0x9C :
- return "\x75";
- break;
- case 0x9D :
- return "\x76";
- break;
- case 0x9E :
- return "\x77";
- break;
- case 0x9F :
- return "\x78";
- break;
- case 0xA0 :
- return "\x79";
- break;
- case 0xA1 :
- return "\x7A";
- break;
- case 0xA2 :
- return "\x61";
- break;
- case 0xA3 :
- return "\x62";
- break;
- case 0xA4 :
- return "\x63";
- break;
- case 0xA5 :
- return "\x64";
- break;
- case 0xA6 :
- return "\x65";
- break;
- case 0xA7 :
- return "\x66";
- break;
- case 0xA8 :
- return "\x67";
- break;
- case 0xA9 :
- return "\x68";
- break;
- case 0xAA :
- return "\x69";
- break;
- case 0xAB :
- return "\x6A";
- break;
- case 0xAC :
- return "\x6B";
- break;
- case 0xAD :
- return "\x6C";
- break;
- case 0xAE :
- return "\x6D";
- break;
- case 0xAF :
- return "\x6E";
- break;
- case 0xB0 :
- return "\x6F";
- break;
- case 0xB1 :
- return "\x70";
- break;
- case 0xB2 :
- return "\x71";
- break;
- case 0xB3 :
- return "\x72";
- break;
- case 0xB4 :
- return "\x73";
- break;
- case 0xB5 :
- return "\x74";
- break;
- case 0xB6 :
- return "\x75";
- break;
- case 0xB7 :
- return "\x76";
- break;
- case 0xB8 :
- return "\x77";
- break;
- case 0xB9 :
- return "\x78";
- break;
- case 0xBA :
- return "\x79";
- break;
- case 0xBB :
- return "\x7A";
- break;
- case 0xBC :
- return "\x61";
- break;
- case 0xBD :
- return "\x62";
- break;
- case 0xBE :
- return "\x63";
- break;
- case 0xBF :
- return "\x64";
- break;
- }
- break;
- case 0x99 :
- switch (str[3]) {
- case 0x80 :
- return "\x65";
- break;
- case 0x81 :
- return "\x66";
- break;
- case 0x82 :
- return "\x67";
- break;
- case 0x83 :
- return "\x68";
- break;
- case 0x84 :
- return "\x69";
- break;
- case 0x85 :
- return "\x6A";
- break;
- case 0x86 :
- return "\x6B";
- break;
- case 0x87 :
- return "\x6C";
- break;
- case 0x88 :
- return "\x6D";
- break;
- case 0x89 :
- return "\x6E";
- break;
- case 0x8A :
- return "\x6F";
- break;
- case 0x8B :
- return "\x70";
- break;
- case 0x8C :
- return "\x71";
- break;
- case 0x8D :
- return "\x72";
- break;
- case 0x8E :
- return "\x73";
- break;
- case 0x8F :
- return "\x74";
- break;
- case 0x90 :
- return "\x75";
- break;
- case 0x91 :
- return "\x76";
- break;
- case 0x92 :
- return "\x77";
- break;
- case 0x93 :
- return "\x78";
- break;
- case 0x94 :
- return "\x79";
- break;
- case 0x95 :
- return "\x7A";
- break;
- case 0x96 :
- return "\x61";
- break;
- case 0x97 :
- return "\x62";
- break;
- case 0x98 :
- return "\x63";
- break;
- case 0x99 :
- return "\x64";
- break;
- case 0x9A :
- return "\x65";
- break;
- case 0x9B :
- return "\x66";
- break;
- case 0x9C :
- return "\x67";
- break;
- case 0x9D :
- return "\x68";
- break;
- case 0x9E :
- return "\x69";
- break;
- case 0x9F :
- return "\x6A";
- break;
- case 0xA0 :
- return "\x6B";
- break;
- case 0xA1 :
- return "\x6C";
- break;
- case 0xA2 :
- return "\x6D";
- break;
- case 0xA3 :
- return "\x6E";
- break;
- case 0xA4 :
- return "\x6F";
- break;
- case 0xA5 :
- return "\x70";
- break;
- case 0xA6 :
- return "\x71";
- break;
- case 0xA7 :
- return "\x72";
- break;
- case 0xA8 :
- return "\x73";
- break;
- case 0xA9 :
- return "\x74";
- break;
- case 0xAA :
- return "\x75";
- break;
- case 0xAB :
- return "\x76";
- break;
- case 0xAC :
- return "\x77";
- break;
- case 0xAD :
- return "\x78";
- break;
- case 0xAE :
- return "\x79";
- break;
- case 0xAF :
- return "\x7A";
- break;
- case 0xB0 :
- return "\x61";
- break;
- case 0xB1 :
- return "\x62";
- break;
- case 0xB2 :
- return "\x63";
- break;
- case 0xB3 :
- return "\x64";
- break;
- case 0xB4 :
- return "\x65";
- break;
- case 0xB5 :
- return "\x66";
- break;
- case 0xB6 :
- return "\x67";
- break;
- case 0xB7 :
- return "\x68";
- break;
- case 0xB8 :
- return "\x69";
- break;
- case 0xB9 :
- return "\x6A";
- break;
- case 0xBA :
- return "\x6B";
- break;
- case 0xBB :
- return "\x6C";
- break;
- case 0xBC :
- return "\x6D";
- break;
- case 0xBD :
- return "\x6E";
- break;
- case 0xBE :
- return "\x6F";
- break;
- case 0xBF :
- return "\x70";
- break;
- }
- break;
- case 0x9A :
- switch (str[3]) {
- case 0x80 :
- return "\x71";
- break;
- case 0x81 :
- return "\x72";
- break;
- case 0x82 :
- return "\x73";
- break;
- case 0x83 :
- return "\x74";
- break;
- case 0x84 :
- return "\x75";
- break;
- case 0x85 :
- return "\x76";
- break;
- case 0x86 :
- return "\x77";
- break;
- case 0x87 :
- return "\x78";
- break;
- case 0x88 :
- return "\x79";
- break;
- case 0x89 :
- return "\x7A";
- break;
- case 0x8A :
- return "\x61";
- break;
- case 0x8B :
- return "\x62";
- break;
- case 0x8C :
- return "\x63";
- break;
- case 0x8D :
- return "\x64";
- break;
- case 0x8E :
- return "\x65";
- break;
- case 0x8F :
- return "\x66";
- break;
- case 0x90 :
- return "\x67";
- break;
- case 0x91 :
- return "\x68";
- break;
- case 0x92 :
- return "\x69";
- break;
- case 0x93 :
- return "\x6A";
- break;
- case 0x94 :
- return "\x6B";
- break;
- case 0x95 :
- return "\x6C";
- break;
- case 0x96 :
- return "\x6D";
- break;
- case 0x97 :
- return "\x6E";
- break;
- case 0x98 :
- return "\x6F";
- break;
- case 0x99 :
- return "\x70";
- break;
- case 0x9A :
- return "\x71";
- break;
- case 0x9B :
- return "\x72";
- break;
- case 0x9C :
- return "\x73";
- break;
- case 0x9D :
- return "\x74";
- break;
- case 0x9E :
- return "\x75";
- break;
- case 0x9F :
- return "\x76";
- break;
- case 0xA0 :
- return "\x77";
- break;
- case 0xA1 :
- return "\x78";
- break;
- case 0xA2 :
- return "\x79";
- break;
- case 0xA3 :
- return "\x7A";
- break;
- case 0xA4 :
- return "\xC4\xB1";
- break;
- case 0xA5 :
- return "\xC8\xB7";
- break;
- case 0xA8 :
- return "\xCE\x91";
- break;
- case 0xA9 :
- return "\xCE\x92";
- break;
- case 0xAA :
- return "\xCE\x93";
- break;
- case 0xAB :
- return "\xCE\x94";
- break;
- case 0xAC :
- return "\xCE\x95";
- break;
- case 0xAD :
- return "\xCE\x96";
- break;
- case 0xAE :
- return "\xCE\x97";
- break;
- case 0xAF :
- return "\xCE\x98";
- break;
- case 0xB0 :
- return "\xCE\x99";
- break;
- case 0xB1 :
- return "\xCE\x9A";
- break;
- case 0xB2 :
- return "\xCE\x9B";
- break;
- case 0xB3 :
- return "\xCE\x9C";
- break;
- case 0xB4 :
- return "\xCE\x9D";
- break;
- case 0xB5 :
- return "\xCE\x9E";
- break;
- case 0xB6 :
- return "\xCE\x9F";
- break;
- case 0xB7 :
- return "\xCE\xA0";
- break;
- case 0xB8 :
- return "\xCE\xA1";
- break;
- case 0xB9 :
- return "\xCE\x98";
- break;
- case 0xBA :
- return "\xCE\xA3";
- break;
- case 0xBB :
- return "\xCE\xA4";
- break;
- case 0xBC :
- return "\xCE\xA5";
- break;
- case 0xBD :
- return "\xCE\xA6";
- break;
- case 0xBE :
- return "\xCE\xA7";
- break;
- case 0xBF :
- return "\xCE\xA8";
- break;
- }
- break;
- case 0x9B :
- switch (str[3]) {
- case 0x80 :
- return "\xCE\xA9";
- break;
- case 0x81 :
- return "\xE2\x88\x87";
- break;
- case 0x82 :
- return "\xCE\xB1";
- break;
- case 0x83 :
- return "\xCE\xB2";
- break;
- case 0x84 :
- return "\xCE\xB3";
- break;
- case 0x85 :
- return "\xCE\xB4";
- break;
- case 0x86 :
- return "\xCE\xB5";
- break;
- case 0x87 :
- return "\xCE\xB6";
- break;
- case 0x88 :
- return "\xCE\xB7";
- break;
- case 0x89 :
- return "\xCE\xB8";
- break;
- case 0x8A :
- return "\xCE\xB9";
- break;
- case 0x8B :
- return "\xCE\xBA";
- break;
- case 0x8C :
- return "\xCE\xBB";
- break;
- case 0x8D :
- return "\xCE\xBC";
- break;
- case 0x8E :
- return "\xCE\xBD";
- break;
- case 0x8F :
- return "\xCE\xBE";
- break;
- case 0x90 :
- return "\xCE\xBF";
- break;
- case 0x91 :
- return "\xCF\x80";
- break;
- case 0x92 :
- return "\xCF\x81";
- break;
- case 0x93 :
- return "\xCF\x82";
- break;
- case 0x94 :
- return "\xCF\x83";
- break;
- case 0x95 :
- return "\xCF\x84";
- break;
- case 0x96 :
- return "\xCF\x85";
- break;
- case 0x97 :
- return "\xCF\x86";
- break;
- case 0x98 :
- return "\xCF\x87";
- break;
- case 0x99 :
- return "\xCF\x88";
- break;
- case 0x9A :
- return "\xCF\x89";
- break;
- case 0x9B :
- return "\xE2\x88\x82";
- break;
- case 0x9C :
- return "\xCE\xB5";
- break;
- case 0x9D :
- return "\xCE\xB8";
- break;
- case 0x9E :
- return "\xCE\xBA";
- break;
- case 0x9F :
- return "\xCF\x86";
- break;
- case 0xA0 :
- return "\xCF\x81";
- break;
- case 0xA1 :
- return "\xCF\x80";
- break;
- case 0xA2 :
- return "\xCE\x91";
- break;
- case 0xA3 :
- return "\xCE\x92";
- break;
- case 0xA4 :
- return "\xCE\x93";
- break;
- case 0xA5 :
- return "\xCE\x94";
- break;
- case 0xA6 :
- return "\xCE\x95";
- break;
- case 0xA7 :
- return "\xCE\x96";
- break;
- case 0xA8 :
- return "\xCE\x97";
- break;
- case 0xA9 :
- return "\xCE\x98";
- break;
- case 0xAA :
- return "\xCE\x99";
- break;
- case 0xAB :
- return "\xCE\x9A";
- break;
- case 0xAC :
- return "\xCE\x9B";
- break;
- case 0xAD :
- return "\xCE\x9C";
- break;
- case 0xAE :
- return "\xCE\x9D";
- break;
- case 0xAF :
- return "\xCE\x9E";
- break;
- case 0xB0 :
- return "\xCE\x9F";
- break;
- case 0xB1 :
- return "\xCE\xA0";
- break;
- case 0xB2 :
- return "\xCE\xA1";
- break;
- case 0xB3 :
- return "\xCE\x98";
- break;
- case 0xB4 :
- return "\xCE\xA3";
- break;
- case 0xB5 :
- return "\xCE\xA4";
- break;
- case 0xB6 :
- return "\xCE\xA5";
- break;
- case 0xB7 :
- return "\xCE\xA6";
- break;
- case 0xB8 :
- return "\xCE\xA7";
- break;
- case 0xB9 :
- return "\xCE\xA8";
- break;
- case 0xBA :
- return "\xCE\xA9";
- break;
- case 0xBB :
- return "\xE2\x88\x87";
- break;
- case 0xBC :
- return "\xCE\xB1";
- break;
- case 0xBD :
- return "\xCE\xB2";
- break;
- case 0xBE :
- return "\xCE\xB3";
- break;
- case 0xBF :
- return "\xCE\xB4";
- break;
- }
- break;
- case 0x9C :
- switch (str[3]) {
- case 0x80 :
- return "\xCE\xB5";
- break;
- case 0x81 :
- return "\xCE\xB6";
- break;
- case 0x82 :
- return "\xCE\xB7";
- break;
- case 0x83 :
- return "\xCE\xB8";
- break;
- case 0x84 :
- return "\xCE\xB9";
- break;
- case 0x85 :
- return "\xCE\xBA";
- break;
- case 0x86 :
- return "\xCE\xBB";
- break;
- case 0x87 :
- return "\xCE\xBC";
- break;
- case 0x88 :
- return "\xCE\xBD";
- break;
- case 0x89 :
- return "\xCE\xBE";
- break;
- case 0x8A :
- return "\xCE\xBF";
- break;
- case 0x8B :
- return "\xCF\x80";
- break;
- case 0x8C :
- return "\xCF\x81";
- break;
- case 0x8D :
- return "\xCF\x82";
- break;
- case 0x8E :
- return "\xCF\x83";
- break;
- case 0x8F :
- return "\xCF\x84";
- break;
- case 0x90 :
- return "\xCF\x85";
- break;
- case 0x91 :
- return "\xCF\x86";
- break;
- case 0x92 :
- return "\xCF\x87";
- break;
- case 0x93 :
- return "\xCF\x88";
- break;
- case 0x94 :
- return "\xCF\x89";
- break;
- case 0x95 :
- return "\xE2\x88\x82";
- break;
- case 0x96 :
- return "\xCE\xB5";
- break;
- case 0x97 :
- return "\xCE\xB8";
- break;
- case 0x98 :
- return "\xCE\xBA";
- break;
- case 0x99 :
- return "\xCF\x86";
- break;
- case 0x9A :
- return "\xCF\x81";
- break;
- case 0x9B :
- return "\xCF\x80";
- break;
- case 0x9C :
- return "\xCE\x91";
- break;
- case 0x9D :
- return "\xCE\x92";
- break;
- case 0x9E :
- return "\xCE\x93";
- break;
- case 0x9F :
- return "\xCE\x94";
- break;
- case 0xA0 :
- return "\xCE\x95";
- break;
- case 0xA1 :
- return "\xCE\x96";
- break;
- case 0xA2 :
- return "\xCE\x97";
- break;
- case 0xA3 :
- return "\xCE\x98";
- break;
- case 0xA4 :
- return "\xCE\x99";
- break;
- case 0xA5 :
- return "\xCE\x9A";
- break;
- case 0xA6 :
- return "\xCE\x9B";
- break;
- case 0xA7 :
- return "\xCE\x9C";
- break;
- case 0xA8 :
- return "\xCE\x9D";
- break;
- case 0xA9 :
- return "\xCE\x9E";
- break;
- case 0xAA :
- return "\xCE\x9F";
- break;
- case 0xAB :
- return "\xCE\xA0";
- break;
- case 0xAC :
- return "\xCE\xA1";
- break;
- case 0xAD :
- return "\xCE\x98";
- break;
- case 0xAE :
- return "\xCE\xA3";
- break;
- case 0xAF :
- return "\xCE\xA4";
- break;
- case 0xB0 :
- return "\xCE\xA5";
- break;
- case 0xB1 :
- return "\xCE\xA6";
- break;
- case 0xB2 :
- return "\xCE\xA7";
- break;
- case 0xB3 :
- return "\xCE\xA8";
- break;
- case 0xB4 :
- return "\xCE\xA9";
- break;
- case 0xB5 :
- return "\xE2\x88\x87";
- break;
- case 0xB6 :
- return "\xCE\xB1";
- break;
- case 0xB7 :
- return "\xCE\xB2";
- break;
- case 0xB8 :
- return "\xCE\xB3";
- break;
- case 0xB9 :
- return "\xCE\xB4";
- break;
- case 0xBA :
- return "\xCE\xB5";
- break;
- case 0xBB :
- return "\xCE\xB6";
- break;
- case 0xBC :
- return "\xCE\xB7";
- break;
- case 0xBD :
- return "\xCE\xB8";
- break;
- case 0xBE :
- return "\xCE\xB9";
- break;
- case 0xBF :
- return "\xCE\xBA";
- break;
- }
- break;
- case 0x9D :
- switch (str[3]) {
- case 0x80 :
- return "\xCE\xBB";
- break;
- case 0x81 :
- return "\xCE\xBC";
- break;
- case 0x82 :
- return "\xCE\xBD";
- break;
- case 0x83 :
- return "\xCE\xBE";
- break;
- case 0x84 :
- return "\xCE\xBF";
- break;
- case 0x85 :
- return "\xCF\x80";
- break;
- case 0x86 :
- return "\xCF\x81";
- break;
- case 0x87 :
- return "\xCF\x82";
- break;
- case 0x88 :
- return "\xCF\x83";
- break;
- case 0x89 :
- return "\xCF\x84";
- break;
- case 0x8A :
- return "\xCF\x85";
- break;
- case 0x8B :
- return "\xCF\x86";
- break;
- case 0x8C :
- return "\xCF\x87";
- break;
- case 0x8D :
- return "\xCF\x88";
- break;
- case 0x8E :
- return "\xCF\x89";
- break;
- case 0x8F :
- return "\xE2\x88\x82";
- break;
- case 0x90 :
- return "\xCE\xB5";
- break;
- case 0x91 :
- return "\xCE\xB8";
- break;
- case 0x92 :
- return "\xCE\xBA";
- break;
- case 0x93 :
- return "\xCF\x86";
- break;
- case 0x94 :
- return "\xCF\x81";
- break;
- case 0x95 :
- return "\xCF\x80";
- break;
- case 0x96 :
- return "\xCE\x91";
- break;
- case 0x97 :
- return "\xCE\x92";
- break;
- case 0x98 :
- return "\xCE\x93";
- break;
- case 0x99 :
- return "\xCE\x94";
- break;
- case 0x9A :
- return "\xCE\x95";
- break;
- case 0x9B :
- return "\xCE\x96";
- break;
- case 0x9C :
- return "\xCE\x97";
- break;
- case 0x9D :
- return "\xCE\x98";
- break;
- case 0x9E :
- return "\xCE\x99";
- break;
- case 0x9F :
- return "\xCE\x9A";
- break;
- case 0xA0 :
- return "\xCE\x9B";
- break;
- case 0xA1 :
- return "\xCE\x9C";
- break;
- case 0xA2 :
- return "\xCE\x9D";
- break;
- case 0xA3 :
- return "\xCE\x9E";
- break;
- case 0xA4 :
- return "\xCE\x9F";
- break;
- case 0xA5 :
- return "\xCE\xA0";
- break;
- case 0xA6 :
- return "\xCE\xA1";
- break;
- case 0xA7 :
- return "\xCE\x98";
- break;
- case 0xA8 :
- return "\xCE\xA3";
- break;
- case 0xA9 :
- return "\xCE\xA4";
- break;
- case 0xAA :
- return "\xCE\xA5";
- break;
- case 0xAB :
- return "\xCE\xA6";
- break;
- case 0xAC :
- return "\xCE\xA7";
- break;
- case 0xAD :
- return "\xCE\xA8";
- break;
- case 0xAE :
- return "\xCE\xA9";
- break;
- case 0xAF :
- return "\xE2\x88\x87";
- break;
- case 0xB0 :
- return "\xCE\xB1";
- break;
- case 0xB1 :
- return "\xCE\xB2";
- break;
- case 0xB2 :
- return "\xCE\xB3";
- break;
- case 0xB3 :
- return "\xCE\xB4";
- break;
- case 0xB4 :
- return "\xCE\xB5";
- break;
- case 0xB5 :
- return "\xCE\xB6";
- break;
- case 0xB6 :
- return "\xCE\xB7";
- break;
- case 0xB7 :
- return "\xCE\xB8";
- break;
- case 0xB8 :
- return "\xCE\xB9";
- break;
- case 0xB9 :
- return "\xCE\xBA";
- break;
- case 0xBA :
- return "\xCE\xBB";
- break;
- case 0xBB :
- return "\xCE\xBC";
- break;
- case 0xBC :
- return "\xCE\xBD";
- break;
- case 0xBD :
- return "\xCE\xBE";
- break;
- case 0xBE :
- return "\xCE\xBF";
- break;
- case 0xBF :
- return "\xCF\x80";
- break;
- }
- break;
- case 0x9E :
- switch (str[3]) {
- case 0x80 :
- return "\xCF\x81";
- break;
- case 0x81 :
- return "\xCF\x82";
- break;
- case 0x82 :
- return "\xCF\x83";
- break;
- case 0x83 :
- return "\xCF\x84";
- break;
- case 0x84 :
- return "\xCF\x85";
- break;
- case 0x85 :
- return "\xCF\x86";
- break;
- case 0x86 :
- return "\xCF\x87";
- break;
- case 0x87 :
- return "\xCF\x88";
- break;
- case 0x88 :
- return "\xCF\x89";
- break;
- case 0x89 :
- return "\xE2\x88\x82";
- break;
- case 0x8A :
- return "\xCE\xB5";
- break;
- case 0x8B :
- return "\xCE\xB8";
- break;
- case 0x8C :
- return "\xCE\xBA";
- break;
- case 0x8D :
- return "\xCF\x86";
- break;
- case 0x8E :
- return "\xCF\x81";
- break;
- case 0x8F :
- return "\xCF\x80";
- break;
- case 0x90 :
- return "\xCE\x91";
- break;
- case 0x91 :
- return "\xCE\x92";
- break;
- case 0x92 :
- return "\xCE\x93";
- break;
- case 0x93 :
- return "\xCE\x94";
- break;
- case 0x94 :
- return "\xCE\x95";
- break;
- case 0x95 :
- return "\xCE\x96";
- break;
- case 0x96 :
- return "\xCE\x97";
- break;
- case 0x97 :
- return "\xCE\x98";
- break;
- case 0x98 :
- return "\xCE\x99";
- break;
- case 0x99 :
- return "\xCE\x9A";
- break;
- case 0x9A :
- return "\xCE\x9B";
- break;
- case 0x9B :
- return "\xCE\x9C";
- break;
- case 0x9C :
- return "\xCE\x9D";
- break;
- case 0x9D :
- return "\xCE\x9E";
- break;
- case 0x9E :
- return "\xCE\x9F";
- break;
- case 0x9F :
- return "\xCE\xA0";
- break;
- case 0xA0 :
- return "\xCE\xA1";
- break;
- case 0xA1 :
- return "\xCE\x98";
- break;
- case 0xA2 :
- return "\xCE\xA3";
- break;
- case 0xA3 :
- return "\xCE\xA4";
- break;
- case 0xA4 :
- return "\xCE\xA5";
- break;
- case 0xA5 :
- return "\xCE\xA6";
- break;
- case 0xA6 :
- return "\xCE\xA7";
- break;
- case 0xA7 :
- return "\xCE\xA8";
- break;
- case 0xA8 :
- return "\xCE\xA9";
- break;
- case 0xA9 :
- return "\xE2\x88\x87";
- break;
- case 0xAA :
- return "\xCE\xB1";
- break;
- case 0xAB :
- return "\xCE\xB2";
- break;
- case 0xAC :
- return "\xCE\xB3";
- break;
- case 0xAD :
- return "\xCE\xB4";
- break;
- case 0xAE :
- return "\xCE\xB5";
- break;
- case 0xAF :
- return "\xCE\xB6";
- break;
- case 0xB0 :
- return "\xCE\xB7";
- break;
- case 0xB1 :
- return "\xCE\xB8";
- break;
- case 0xB2 :
- return "\xCE\xB9";
- break;
- case 0xB3 :
- return "\xCE\xBA";
- break;
- case 0xB4 :
- return "\xCE\xBB";
- break;
- case 0xB5 :
- return "\xCE\xBC";
- break;
- case 0xB6 :
- return "\xCE\xBD";
- break;
- case 0xB7 :
- return "\xCE\xBE";
- break;
- case 0xB8 :
- return "\xCE\xBF";
- break;
- case 0xB9 :
- return "\xCF\x80";
- break;
- case 0xBA :
- return "\xCF\x81";
- break;
- case 0xBB :
- return "\xCF\x82";
- break;
- case 0xBC :
- return "\xCF\x83";
- break;
- case 0xBD :
- return "\xCF\x84";
- break;
- case 0xBE :
- return "\xCF\x85";
- break;
- case 0xBF :
- return "\xCF\x86";
- break;
- }
- break;
- case 0x9F :
- switch (str[3]) {
- case 0x80 :
- return "\xCF\x87";
- break;
- case 0x81 :
- return "\xCF\x88";
- break;
- case 0x82 :
- return "\xCF\x89";
- break;
- case 0x83 :
- return "\xE2\x88\x82";
- break;
- case 0x84 :
- return "\xCE\xB5";
- break;
- case 0x85 :
- return "\xCE\xB8";
- break;
- case 0x86 :
- return "\xCE\xBA";
- break;
- case 0x87 :
- return "\xCF\x86";
- break;
- case 0x88 :
- return "\xCF\x81";
- break;
- case 0x89 :
- return "\xCF\x80";
- break;
- case 0x8A :
- return "\xCF\x9C";
- break;
- case 0x8B :
- return "\xCF\x9D";
- break;
- case 0x8E :
- return "\x30";
- break;
- case 0x8F :
- return "\x31";
- break;
- case 0x90 :
- return "\x32";
- break;
- case 0x91 :
- return "\x33";
- break;
- case 0x92 :
- return "\x34";
- break;
- case 0x93 :
- return "\x35";
- break;
- case 0x94 :
- return "\x36";
- break;
- case 0x95 :
- return "\x37";
- break;
- case 0x96 :
- return "\x38";
- break;
- case 0x97 :
- return "\x39";
- break;
- case 0x98 :
- return "\x30";
- break;
- case 0x99 :
- return "\x31";
- break;
- case 0x9A :
- return "\x32";
- break;
- case 0x9B :
- return "\x33";
- break;
- case 0x9C :
- return "\x34";
- break;
- case 0x9D :
- return "\x35";
- break;
- case 0x9E :
- return "\x36";
- break;
- case 0x9F :
- return "\x37";
- break;
- case 0xA0 :
- return "\x38";
- break;
- case 0xA1 :
- return "\x39";
- break;
- case 0xA2 :
- return "\x30";
- break;
- case 0xA3 :
- return "\x31";
- break;
- case 0xA4 :
- return "\x32";
- break;
- case 0xA5 :
- return "\x33";
- break;
- case 0xA6 :
- return "\x34";
- break;
- case 0xA7 :
- return "\x35";
- break;
- case 0xA8 :
- return "\x36";
- break;
- case 0xA9 :
- return "\x37";
- break;
- case 0xAA :
- return "\x38";
- break;
- case 0xAB :
- return "\x39";
- break;
- case 0xAC :
- return "\x30";
- break;
- case 0xAD :
- return "\x31";
- break;
- case 0xAE :
- return "\x32";
- break;
- case 0xAF :
- return "\x33";
- break;
- case 0xB0 :
- return "\x34";
- break;
- case 0xB1 :
- return "\x35";
- break;
- case 0xB2 :
- return "\x36";
- break;
- case 0xB3 :
- return "\x37";
- break;
- case 0xB4 :
- return "\x38";
- break;
- case 0xB5 :
- return "\x39";
- break;
- case 0xB6 :
- return "\x30";
- break;
- case 0xB7 :
- return "\x31";
- break;
- case 0xB8 :
- return "\x32";
- break;
- case 0xB9 :
- return "\x33";
- break;
- case 0xBA :
- return "\x34";
- break;
- case 0xBB :
- return "\x35";
- break;
- case 0xBC :
- return "\x36";
- break;
- case 0xBD :
- return "\x37";
- break;
- case 0xBE :
- return "\x38";
- break;
- case 0xBF :
- return "\x39";
- break;
- }
- break;
- }
- break;
- case 0xAF :
- switch (str[2]) {
- case 0xA0 :
- switch (str[3]) {
- case 0x80 :
- return "\xE4\xB8\xBD";
- break;
- case 0x81 :
- return "\xE4\xB8\xB8";
- break;
- case 0x82 :
- return "\xE4\xB9\x81";
- break;
- case 0x83 :
- return "\xF0\xA0\x84\xA2";
- break;
- case 0x84 :
- return "\xE4\xBD\xA0";
- break;
- case 0x85 :
- return "\xE4\xBE\xAE";
- break;
- case 0x86 :
- return "\xE4\xBE\xBB";
- break;
- case 0x87 :
- return "\xE5\x80\x82";
- break;
- case 0x88 :
- return "\xE5\x81\xBA";
- break;
- case 0x89 :
- return "\xE5\x82\x99";
- break;
- case 0x8A :
- return "\xE5\x83\xA7";
- break;
- case 0x8B :
- return "\xE5\x83\x8F";
- break;
- case 0x8C :
- return "\xE3\x92\x9E";
- break;
- case 0x8D :
- return "\xF0\xA0\x98\xBA";
- break;
- case 0x8E :
- return "\xE5\x85\x8D";
- break;
- case 0x8F :
- return "\xE5\x85\x94";
- break;
- case 0x90 :
- return "\xE5\x85\xA4";
- break;
- case 0x91 :
- return "\xE5\x85\xB7";
- break;
- case 0x92 :
- return "\xF0\xA0\x94\x9C";
- break;
- case 0x93 :
- return "\xE3\x92\xB9";
- break;
- case 0x94 :
- return "\xE5\x85\xA7";
- break;
- case 0x95 :
- return "\xE5\x86\x8D";
- break;
- case 0x96 :
- return "\xF0\xA0\x95\x8B";
- break;
- case 0x97 :
- return "\xE5\x86\x97";
- break;
- case 0x98 :
- return "\xE5\x86\xA4";
- break;
- case 0x99 :
- return "\xE4\xBB\x8C";
- break;
- case 0x9A :
- return "\xE5\x86\xAC";
- break;
- case 0x9B :
- return "\xE5\x86\xB5";
- break;
- case 0x9C :
- return "\xF0\xA9\x87\x9F";
- break;
- case 0x9D :
- return "\xE5\x87\xB5";
- break;
- case 0x9E :
- return "\xE5\x88\x83";
- break;
- case 0x9F :
- return "\xE3\x93\x9F";
- break;
- case 0xA0 :
- return "\xE5\x88\xBB";
- break;
- case 0xA1 :
- return "\xE5\x89\x86";
- break;
- case 0xA2 :
- return "\xE5\x89\xB2";
- break;
- case 0xA3 :
- return "\xE5\x89\xB7";
- break;
- case 0xA4 :
- return "\xE3\x94\x95";
- break;
- case 0xA5 :
- return "\xE5\x8B\x87";
- break;
- case 0xA6 :
- return "\xE5\x8B\x89";
- break;
- case 0xA7 :
- return "\xE5\x8B\xA4";
- break;
- case 0xA8 :
- return "\xE5\x8B\xBA";
- break;
- case 0xA9 :
- return "\xE5\x8C\x85";
- break;
- case 0xAA :
- return "\xE5\x8C\x86";
- break;
- case 0xAB :
- return "\xE5\x8C\x97";
- break;
- case 0xAC :
- return "\xE5\x8D\x89";
- break;
- case 0xAD :
- return "\xE5\x8D\x91";
- break;
- case 0xAE :
- return "\xE5\x8D\x9A";
- break;
- case 0xAF :
- return "\xE5\x8D\xB3";
- break;
- case 0xB0 :
- return "\xE5\x8D\xBD";
- break;
- case 0xB1 :
- return "\xE5\x8D\xBF";
- break;
- case 0xB2 :
- return "\xE5\x8D\xBF";
- break;
- case 0xB3 :
- return "\xE5\x8D\xBF";
- break;
- case 0xB4 :
- return "\xF0\xA0\xA8\xAC";
- break;
- case 0xB5 :
- return "\xE7\x81\xB0";
- break;
- case 0xB6 :
- return "\xE5\x8F\x8A";
- break;
- case 0xB7 :
- return "\xE5\x8F\x9F";
- break;
- case 0xB8 :
- return "\xF0\xA0\xAD\xA3";
- break;
- case 0xB9 :
- return "\xE5\x8F\xAB";
- break;
- case 0xBA :
- return "\xE5\x8F\xB1";
- break;
- case 0xBB :
- return "\xE5\x90\x86";
- break;
- case 0xBC :
- return "\xE5\x92\x9E";
- break;
- case 0xBD :
- return "\xE5\x90\xB8";
- break;
- case 0xBE :
- return "\xE5\x91\x88";
- break;
- case 0xBF :
- return "\xE5\x91\xA8";
- break;
- }
- break;
- case 0xA1 :
- switch (str[3]) {
- case 0x80 :
- return "\xE5\x92\xA2";
- break;
- case 0x81 :
- return "\xE5\x93\xB6";
- break;
- case 0x82 :
- return "\xE5\x94\x90";
- break;
- case 0x83 :
- return "\xE5\x95\x93";
- break;
- case 0x84 :
- return "\xE5\x95\xA3";
- break;
- case 0x85 :
- return "\xE5\x96\x84";
- break;
- case 0x86 :
- return "\xE5\x96\x84";
- break;
- case 0x87 :
- return "\xE5\x96\x99";
- break;
- case 0x88 :
- return "\xE5\x96\xAB";
- break;
- case 0x89 :
- return "\xE5\x96\xB3";
- break;
- case 0x8A :
- return "\xE5\x97\x82";
- break;
- case 0x8B :
- return "\xE5\x9C\x96";
- break;
- case 0x8C :
- return "\xE5\x98\x86";
- break;
- case 0x8D :
- return "\xE5\x9C\x97";
- break;
- case 0x8E :
- return "\xE5\x99\x91";
- break;
- case 0x8F :
- return "\xE5\x99\xB4";
- break;
- case 0x90 :
- return "\xE5\x88\x87";
- break;
- case 0x91 :
- return "\xE5\xA3\xAE";
- break;
- case 0x92 :
- return "\xE5\x9F\x8E";
- break;
- case 0x93 :
- return "\xE5\x9F\xB4";
- break;
- case 0x94 :
- return "\xE5\xA0\x8D";
- break;
- case 0x95 :
- return "\xE5\x9E\x8B";
- break;
- case 0x96 :
- return "\xE5\xA0\xB2";
- break;
- case 0x97 :
- return "\xE5\xA0\xB1";
- break;
- case 0x98 :
- return "\xE5\xA2\xAC";
- break;
- case 0x99 :
- return "\xF0\xA1\x93\xA4";
- break;
- case 0x9A :
- return "\xE5\xA3\xB2";
- break;
- case 0x9B :
- return "\xE5\xA3\xB7";
- break;
- case 0x9C :
- return "\xE5\xA4\x86";
- break;
- case 0x9D :
- return "\xE5\xA4\x9A";
- break;
- case 0x9E :
- return "\xE5\xA4\xA2";
- break;
- case 0x9F :
- return "\xE5\xA5\xA2";
- break;
- case 0xA0 :
- return "\xF0\xA1\x9A\xA8";
- break;
- case 0xA1 :
- return "\xF0\xA1\x9B\xAA";
- break;
- case 0xA2 :
- return "\xE5\xA7\xAC";
- break;
- case 0xA3 :
- return "\xE5\xA8\x9B";
- break;
- case 0xA4 :
- return "\xE5\xA8\xA7";
- break;
- case 0xA5 :
- return "\xE5\xA7\x98";
- break;
- case 0xA6 :
- return "\xE5\xA9\xA6";
- break;
- case 0xA7 :
- return "\xE3\x9B\xAE";
- break;
- case 0xA8 :
- return "\xE3\x9B\xBC";
- break;
- case 0xA9 :
- return "\xE5\xAC\x88";
- break;
- case 0xAA :
- return "\xE5\xAC\xBE";
- break;
- case 0xAB :
- return "\xE5\xAC\xBE";
- break;
- case 0xAC :
- return "\xF0\xA1\xA7\x88";
- break;
- case 0xAD :
- return "\xE5\xAF\x83";
- break;
- case 0xAE :
- return "\xE5\xAF\x98";
- break;
- case 0xAF :
- return "\xE5\xAF\xA7";
- break;
- case 0xB0 :
- return "\xE5\xAF\xB3";
- break;
- case 0xB1 :
- return "\xF0\xA1\xAC\x98";
- break;
- case 0xB2 :
- return "\xE5\xAF\xBF";
- break;
- case 0xB3 :
- return "\xE5\xB0\x86";
- break;
- case 0xB4 :
- return "\xE5\xBD\x93";
- break;
- case 0xB5 :
- return "\xE5\xB0\xA2";
- break;
- case 0xB6 :
- return "\xE3\x9E\x81";
- break;
- case 0xB7 :
- return "\xE5\xB1\xA0";
- break;
- case 0xB8 :
- return "\xE5\xB1\xAE";
- break;
- case 0xB9 :
- return "\xE5\xB3\x80";
- break;
- case 0xBA :
- return "\xE5\xB2\x8D";
- break;
- case 0xBB :
- return "\xF0\xA1\xB7\xA4";
- break;
- case 0xBC :
- return "\xE5\xB5\x83";
- break;
- case 0xBD :
- return "\xF0\xA1\xB7\xA6";
- break;
- case 0xBE :
- return "\xE5\xB5\xAE";
- break;
- case 0xBF :
- return "\xE5\xB5\xAB";
- break;
- }
- break;
- case 0xA2 :
- switch (str[3]) {
- case 0x80 :
- return "\xE5\xB5\xBC";
- break;
- case 0x81 :
- return "\xE5\xB7\xA1";
- break;
- case 0x82 :
- return "\xE5\xB7\xA2";
- break;
- case 0x83 :
- return "\xE3\xA0\xAF";
- break;
- case 0x84 :
- return "\xE5\xB7\xBD";
- break;
- case 0x85 :
- return "\xE5\xB8\xA8";
- break;
- case 0x86 :
- return "\xE5\xB8\xBD";
- break;
- case 0x87 :
- return "\xE5\xB9\xA9";
- break;
- case 0x88 :
- return "\xE3\xA1\xA2";
- break;
- case 0x89 :
- return "\xF0\xA2\x86\x83";
- break;
- case 0x8A :
- return "\xE3\xA1\xBC";
- break;
- case 0x8B :
- return "\xE5\xBA\xB0";
- break;
- case 0x8C :
- return "\xE5\xBA\xB3";
- break;
- case 0x8D :
- return "\xE5\xBA\xB6";
- break;
- case 0x8E :
- return "\xE5\xBB\x8A";
- break;
- case 0x8F :
- return "\xF0\xAA\x8E\x92";
- break;
- case 0x90 :
- return "\xE5\xBB\xBE";
- break;
- case 0x91 :
- return "\xF0\xA2\x8C\xB1";
- break;
- case 0x92 :
- return "\xF0\xA2\x8C\xB1";
- break;
- case 0x93 :
- return "\xE8\x88\x81";
- break;
- case 0x94 :
- return "\xE5\xBC\xA2";
- break;
- case 0x95 :
- return "\xE5\xBC\xA2";
- break;
- case 0x96 :
- return "\xE3\xA3\x87";
- break;
- case 0x97 :
- return "\xF0\xA3\x8A\xB8";
- break;
- case 0x98 :
- return "\xF0\xA6\x87\x9A";
- break;
- case 0x99 :
- return "\xE5\xBD\xA2";
- break;
- case 0x9A :
- return "\xE5\xBD\xAB";
- break;
- case 0x9B :
- return "\xE3\xA3\xA3";
- break;
- case 0x9C :
- return "\xE5\xBE\x9A";
- break;
- case 0x9D :
- return "\xE5\xBF\x8D";
- break;
- case 0x9E :
- return "\xE5\xBF\x97";
- break;
- case 0x9F :
- return "\xE5\xBF\xB9";
- break;
- case 0xA0 :
- return "\xE6\x82\x81";
- break;
- case 0xA1 :
- return "\xE3\xA4\xBA";
- break;
- case 0xA2 :
- return "\xE3\xA4\x9C";
- break;
- case 0xA3 :
- return "\xE6\x82\x94";
- break;
- case 0xA4 :
- return "\xF0\xA2\x9B\x94";
- break;
- case 0xA5 :
- return "\xE6\x83\x87";
- break;
- case 0xA6 :
- return "\xE6\x85\x88";
- break;
- case 0xA7 :
- return "\xE6\x85\x8C";
- break;
- case 0xA8 :
- return "\xE6\x85\x8E";
- break;
- case 0xA9 :
- return "\xE6\x85\x8C";
- break;
- case 0xAA :
- return "\xE6\x85\xBA";
- break;
- case 0xAB :
- return "\xE6\x86\x8E";
- break;
- case 0xAC :
- return "\xE6\x86\xB2";
- break;
- case 0xAD :
- return "\xE6\x86\xA4";
- break;
- case 0xAE :
- return "\xE6\x86\xAF";
- break;
- case 0xAF :
- return "\xE6\x87\x9E";
- break;
- case 0xB0 :
- return "\xE6\x87\xB2";
- break;
- case 0xB1 :
- return "\xE6\x87\xB6";
- break;
- case 0xB2 :
- return "\xE6\x88\x90";
- break;
- case 0xB3 :
- return "\xE6\x88\x9B";
- break;
- case 0xB4 :
- return "\xE6\x89\x9D";
- break;
- case 0xB5 :
- return "\xE6\x8A\xB1";
- break;
- case 0xB6 :
- return "\xE6\x8B\x94";
- break;
- case 0xB7 :
- return "\xE6\x8D\x90";
- break;
- case 0xB8 :
- return "\xF0\xA2\xAC\x8C";
- break;
- case 0xB9 :
- return "\xE6\x8C\xBD";
- break;
- case 0xBA :
- return "\xE6\x8B\xBC";
- break;
- case 0xBB :
- return "\xE6\x8D\xA8";
- break;
- case 0xBC :
- return "\xE6\x8E\x83";
- break;
- case 0xBD :
- return "\xE6\x8F\xA4";
- break;
- case 0xBE :
- return "\xF0\xA2\xAF\xB1";
- break;
- case 0xBF :
- return "\xE6\x90\xA2";
- break;
- }
- break;
- case 0xA3 :
- switch (str[3]) {
- case 0x80 :
- return "\xE6\x8F\x85";
- break;
- case 0x81 :
- return "\xE6\x8E\xA9";
- break;
- case 0x82 :
- return "\xE3\xA8\xAE";
- break;
- case 0x83 :
- return "\xE6\x91\xA9";
- break;
- case 0x84 :
- return "\xE6\x91\xBE";
- break;
- case 0x85 :
- return "\xE6\x92\x9D";
- break;
- case 0x86 :
- return "\xE6\x91\xB7";
- break;
- case 0x87 :
- return "\xE3\xA9\xAC";
- break;
- case 0x88 :
- return "\xE6\x95\x8F";
- break;
- case 0x89 :
- return "\xE6\x95\xAC";
- break;
- case 0x8A :
- return "\xF0\xA3\x80\x8A";
- break;
- case 0x8B :
- return "\xE6\x97\xA3";
- break;
- case 0x8C :
- return "\xE6\x9B\xB8";
- break;
- case 0x8D :
- return "\xE6\x99\x89";
- break;
- case 0x8E :
- return "\xE3\xAC\x99";
- break;
- case 0x8F :
- return "\xE6\x9A\x91";
- break;
- case 0x90 :
- return "\xE3\xAC\x88";
- break;
- case 0x91 :
- return "\xE3\xAB\xA4";
- break;
- case 0x92 :
- return "\xE5\x86\x92";
- break;
- case 0x93 :
- return "\xE5\x86\x95";
- break;
- case 0x94 :
- return "\xE6\x9C\x80";
- break;
- case 0x95 :
- return "\xE6\x9A\x9C";
- break;
- case 0x96 :
- return "\xE8\x82\xAD";
- break;
- case 0x97 :
- return "\xE4\x8F\x99";
- break;
- case 0x98 :
- return "\xE6\x9C\x97";
- break;
- case 0x99 :
- return "\xE6\x9C\x9B";
- break;
- case 0x9A :
- return "\xE6\x9C\xA1";
- break;
- case 0x9B :
- return "\xE6\x9D\x9E";
- break;
- case 0x9C :
- return "\xE6\x9D\x93";
- break;
- case 0x9D :
- return "\xF0\xA3\x8F\x83";
- break;
- case 0x9E :
- return "\xE3\xAD\x89";
- break;
- case 0x9F :
- return "\xE6\x9F\xBA";
- break;
- case 0xA0 :
- return "\xE6\x9E\x85";
- break;
- case 0xA1 :
- return "\xE6\xA1\x92";
- break;
- case 0xA2 :
- return "\xE6\xA2\x85";
- break;
- case 0xA3 :
- return "\xF0\xA3\x91\xAD";
- break;
- case 0xA4 :
- return "\xE6\xA2\x8E";
- break;
- case 0xA5 :
- return "\xE6\xA0\x9F";
- break;
- case 0xA6 :
- return "\xE6\xA4\x94";
- break;
- case 0xA7 :
- return "\xE3\xAE\x9D";
- break;
- case 0xA8 :
- return "\xE6\xA5\x82";
- break;
- case 0xA9 :
- return "\xE6\xA6\xA3";
- break;
- case 0xAA :
- return "\xE6\xA7\xAA";
- break;
- case 0xAB :
- return "\xE6\xAA\xA8";
- break;
- case 0xAC :
- return "\xF0\xA3\x9A\xA3";
- break;
- case 0xAD :
- return "\xE6\xAB\x9B";
- break;
- case 0xAE :
- return "\xE3\xB0\x98";
- break;
- case 0xAF :
- return "\xE6\xAC\xA1";
- break;
- case 0xB0 :
- return "\xF0\xA3\xA2\xA7";
- break;
- case 0xB1 :
- return "\xE6\xAD\x94";
- break;
- case 0xB2 :
- return "\xE3\xB1\x8E";
- break;
- case 0xB3 :
- return "\xE6\xAD\xB2";
- break;
- case 0xB4 :
- return "\xE6\xAE\x9F";
- break;
- case 0xB5 :
- return "\xE6\xAE\xBA";
- break;
- case 0xB6 :
- return "\xE6\xAE\xBB";
- break;
- case 0xB7 :
- return "\xF0\xA3\xAA\x8D";
- break;
- case 0xB8 :
- return "\xF0\xA1\xB4\x8B";
- break;
- case 0xB9 :
- return "\xF0\xA3\xAB\xBA";
- break;
- case 0xBA :
- return "\xE6\xB1\x8E";
- break;
- case 0xBB :
- return "\xF0\xA3\xB2\xBC";
- break;
- case 0xBC :
- return "\xE6\xB2\xBF";
- break;
- case 0xBD :
- return "\xE6\xB3\x8D";
- break;
- case 0xBE :
- return "\xE6\xB1\xA7";
- break;
- case 0xBF :
- return "\xE6\xB4\x96";
- break;
- }
- break;
- case 0xA4 :
- switch (str[3]) {
- case 0x80 :
- return "\xE6\xB4\xBE";
- break;
- case 0x81 :
- return "\xE6\xB5\xB7";
- break;
- case 0x82 :
- return "\xE6\xB5\x81";
- break;
- case 0x83 :
- return "\xE6\xB5\xA9";
- break;
- case 0x84 :
- return "\xE6\xB5\xB8";
- break;
- case 0x85 :
- return "\xE6\xB6\x85";
- break;
- case 0x86 :
- return "\xF0\xA3\xB4\x9E";
- break;
- case 0x87 :
- return "\xE6\xB4\xB4";
- break;
- case 0x88 :
- return "\xE6\xB8\xAF";
- break;
- case 0x89 :
- return "\xE6\xB9\xAE";
- break;
- case 0x8A :
- return "\xE3\xB4\xB3";
- break;
- case 0x8B :
- return "\xE6\xBB\x8B";
- break;
- case 0x8C :
- return "\xE6\xBB\x87";
- break;
- case 0x8D :
- return "\xF0\xA3\xBB\x91";
- break;
- case 0x8E :
- return "\xE6\xB7\xB9";
- break;
- case 0x8F :
- return "\xE6\xBD\xAE";
- break;
- case 0x90 :
- return "\xF0\xA3\xBD\x9E";
- break;
- case 0x91 :
- return "\xF0\xA3\xBE\x8E";
- break;
- case 0x92 :
- return "\xE6\xBF\x86";
- break;
- case 0x93 :
- return "\xE7\x80\xB9";
- break;
- case 0x94 :
- return "\xE7\x80\x9E";
- break;
- case 0x95 :
- return "\xE7\x80\x9B";
- break;
- case 0x96 :
- return "\xE3\xB6\x96";
- break;
- case 0x97 :
- return "\xE7\x81\x8A";
- break;
- case 0x98 :
- return "\xE7\x81\xBD";
- break;
- case 0x99 :
- return "\xE7\x81\xB7";
- break;
- case 0x9A :
- return "\xE7\x82\xAD";
- break;
- case 0x9B :
- return "\xF0\xA0\x94\xA5";
- break;
- case 0x9C :
- return "\xE7\x85\x85";
- break;
- case 0x9D :
- return "\xF0\xA4\x89\xA3";
- break;
- case 0x9E :
- return "\xE7\x86\x9C";
- break;
- case 0x9F :
- return "\xF0\xA4\x8E\xAB";
- break;
- case 0xA0 :
- return "\xE7\x88\xA8";
- break;
- case 0xA1 :
- return "\xE7\x88\xB5";
- break;
- case 0xA2 :
- return "\xE7\x89\x90";
- break;
- case 0xA3 :
- return "\xF0\xA4\x98\x88";
- break;
- case 0xA4 :
- return "\xE7\x8A\x80";
- break;
- case 0xA5 :
- return "\xE7\x8A\x95";
- break;
- case 0xA6 :
- return "\xF0\xA4\x9C\xB5";
- break;
- case 0xA7 :
- return "\xF0\xA4\xA0\x94";
- break;
- case 0xA8 :
- return "\xE7\x8D\xBA";
- break;
- case 0xA9 :
- return "\xE7\x8E\x8B";
- break;
- case 0xAA :
- return "\xE3\xBA\xAC";
- break;
- case 0xAB :
- return "\xE7\x8E\xA5";
- break;
- case 0xAC :
- return "\xE3\xBA\xB8";
- break;
- case 0xAD :
- return "\xE3\xBA\xB8";
- break;
- case 0xAE :
- return "\xE7\x91\x87";
- break;
- case 0xAF :
- return "\xE7\x91\x9C";
- break;
- case 0xB0 :
- return "\xE7\x91\xB1";
- break;
- case 0xB1 :
- return "\xE7\x92\x85";
- break;
- case 0xB2 :
- return "\xE7\x93\x8A";
- break;
- case 0xB3 :
- return "\xE3\xBC\x9B";
- break;
- case 0xB4 :
- return "\xE7\x94\xA4";
- break;
- case 0xB5 :
- return "\xF0\xA4\xB0\xB6";
- break;
- case 0xB6 :
- return "\xE7\x94\xBE";
- break;
- case 0xB7 :
- return "\xF0\xA4\xB2\x92";
- break;
- case 0xB8 :
- return "\xE7\x95\xB0";
- break;
- case 0xB9 :
- return "\xF0\xA2\x86\x9F";
- break;
- case 0xBA :
- return "\xE7\x98\x90";
- break;
- case 0xBB :
- return "\xF0\xA4\xBE\xA1";
- break;
- case 0xBC :
- return "\xF0\xA4\xBE\xB8";
- break;
- case 0xBD :
- return "\xF0\xA5\x81\x84";
- break;
- case 0xBE :
- return "\xE3\xBF\xBC";
- break;
- case 0xBF :
- return "\xE4\x80\x88";
- break;
- }
- break;
- case 0xA5 :
- switch (str[3]) {
- case 0x80 :
- return "\xE7\x9B\xB4";
- break;
- case 0x81 :
- return "\xF0\xA5\x83\xB3";
- break;
- case 0x82 :
- return "\xF0\xA5\x83\xB2";
- break;
- case 0x83 :
- return "\xF0\xA5\x84\x99";
- break;
- case 0x84 :
- return "\xF0\xA5\x84\xB3";
- break;
- case 0x85 :
- return "\xE7\x9C\x9E";
- break;
- case 0x86 :
- return "\xE7\x9C\x9F";
- break;
- case 0x87 :
- return "\xE7\x9C\x9F";
- break;
- case 0x88 :
- return "\xE7\x9D\x8A";
- break;
- case 0x89 :
- return "\xE4\x80\xB9";
- break;
- case 0x8A :
- return "\xE7\x9E\x8B";
- break;
- case 0x8B :
- return "\xE4\x81\x86";
- break;
- case 0x8C :
- return "\xE4\x82\x96";
- break;
- case 0x8D :
- return "\xF0\xA5\x90\x9D";
- break;
- case 0x8E :
- return "\xE7\xA1\x8E";
- break;
- case 0x8F :
- return "\xE7\xA2\x8C";
- break;
- case 0x90 :
- return "\xE7\xA3\x8C";
- break;
- case 0x91 :
- return "\xE4\x83\xA3";
- break;
- case 0x92 :
- return "\xF0\xA5\x98\xA6";
- break;
- case 0x93 :
- return "\xE7\xA5\x96";
- break;
- case 0x94 :
- return "\xF0\xA5\x9A\x9A";
- break;
- case 0x95 :
- return "\xF0\xA5\x9B\x85";
- break;
- case 0x96 :
- return "\xE7\xA6\x8F";
- break;
- case 0x97 :
- return "\xE7\xA7\xAB";
- break;
- case 0x98 :
- return "\xE4\x84\xAF";
- break;
- case 0x99 :
- return "\xE7\xA9\x80";
- break;
- case 0x9A :
- return "\xE7\xA9\x8A";
- break;
- case 0x9B :
- return "\xE7\xA9\x8F";
- break;
- case 0x9C :
- return "\xF0\xA5\xA5\xBC";
- break;
- case 0x9D :
- return "\xF0\xA5\xAA\xA7";
- break;
- case 0x9E :
- return "\xF0\xA5\xAA\xA7";
- break;
- case 0x9F :
- return "\xE7\xAB\xAE";
- break;
- case 0xA0 :
- return "\xE4\x88\x82";
- break;
- case 0xA1 :
- return "\xF0\xA5\xAE\xAB";
- break;
- case 0xA2 :
- return "\xE7\xAF\x86";
- break;
- case 0xA3 :
- return "\xE7\xAF\x89";
- break;
- case 0xA4 :
- return "\xE4\x88\xA7";
- break;
- case 0xA5 :
- return "\xF0\xA5\xB2\x80";
- break;
- case 0xA6 :
- return "\xE7\xB3\x92";
- break;
- case 0xA7 :
- return "\xE4\x8A\xA0";
- break;
- case 0xA8 :
- return "\xE7\xB3\xA8";
- break;
- case 0xA9 :
- return "\xE7\xB3\xA3";
- break;
- case 0xAA :
- return "\xE7\xB4\x80";
- break;
- case 0xAB :
- return "\xF0\xA5\xBE\x86";
- break;
- case 0xAC :
- return "\xE7\xB5\xA3";
- break;
- case 0xAD :
- return "\xE4\x8C\x81";
- break;
- case 0xAE :
- return "\xE7\xB7\x87";
- break;
- case 0xAF :
- return "\xE7\xB8\x82";
- break;
- case 0xB0 :
- return "\xE7\xB9\x85";
- break;
- case 0xB1 :
- return "\xE4\x8C\xB4";
- break;
- case 0xB2 :
- return "\xF0\xA6\x88\xA8";
- break;
- case 0xB3 :
- return "\xF0\xA6\x89\x87";
- break;
- case 0xB4 :
- return "\xE4\x8D\x99";
- break;
- case 0xB5 :
- return "\xF0\xA6\x8B\x99";
- break;
- case 0xB6 :
- return "\xE7\xBD\xBA";
- break;
- case 0xB7 :
- return "\xF0\xA6\x8C\xBE";
- break;
- case 0xB8 :
- return "\xE7\xBE\x95";
- break;
- case 0xB9 :
- return "\xE7\xBF\xBA";
- break;
- case 0xBA :
- return "\xE8\x80\x85";
- break;
- case 0xBB :
- return "\xF0\xA6\x93\x9A";
- break;
- case 0xBC :
- return "\xF0\xA6\x94\xA3";
- break;
- case 0xBD :
- return "\xE8\x81\xA0";
- break;
- case 0xBE :
- return "\xF0\xA6\x96\xA8";
- break;
- case 0xBF :
- return "\xE8\x81\xB0";
- break;
- }
- break;
- case 0xA6 :
- switch (str[3]) {
- case 0x80 :
- return "\xF0\xA3\x8D\x9F";
- break;
- case 0x81 :
- return "\xE4\x8F\x95";
- break;
- case 0x82 :
- return "\xE8\x82\xB2";
- break;
- case 0x83 :
- return "\xE8\x84\x83";
- break;
- case 0x84 :
- return "\xE4\x90\x8B";
- break;
- case 0x85 :
- return "\xE8\x84\xBE";
- break;
- case 0x86 :
- return "\xE5\xAA\xB5";
- break;
- case 0x87 :
- return "\xF0\xA6\x9E\xA7";
- break;
- case 0x88 :
- return "\xF0\xA6\x9E\xB5";
- break;
- case 0x89 :
- return "\xF0\xA3\x8E\x93";
- break;
- case 0x8A :
- return "\xF0\xA3\x8E\x9C";
- break;
- case 0x8B :
- return "\xE8\x88\x81";
- break;
- case 0x8C :
- return "\xE8\x88\x84";
- break;
- case 0x8D :
- return "\xE8\xBE\x9E";
- break;
- case 0x8E :
- return "\xE4\x91\xAB";
- break;
- case 0x8F :
- return "\xE8\x8A\x91";
- break;
- case 0x90 :
- return "\xE8\x8A\x8B";
- break;
- case 0x91 :
- return "\xE8\x8A\x9D";
- break;
- case 0x92 :
- return "\xE5\x8A\xB3";
- break;
- case 0x93 :
- return "\xE8\x8A\xB1";
- break;
- case 0x94 :
- return "\xE8\x8A\xB3";
- break;
- case 0x95 :
- return "\xE8\x8A\xBD";
- break;
- case 0x96 :
- return "\xE8\x8B\xA6";
- break;
- case 0x97 :
- return "\xF0\xA6\xAC\xBC";
- break;
- case 0x98 :
- return "\xE8\x8B\xA5";
- break;
- case 0x99 :
- return "\xE8\x8C\x9D";
- break;
- case 0x9A :
- return "\xE8\x8D\xA3";
- break;
- case 0x9B :
- return "\xE8\x8E\xAD";
- break;
- case 0x9C :
- return "\xE8\x8C\xA3";
- break;
- case 0x9D :
- return "\xE8\x8E\xBD";
- break;
- case 0x9E :
- return "\xE8\x8F\xA7";
- break;
- case 0x9F :
- return "\xE8\x91\x97";
- break;
- case 0xA0 :
- return "\xE8\x8D\x93";
- break;
- case 0xA1 :
- return "\xE8\x8F\x8A";
- break;
- case 0xA2 :
- return "\xE8\x8F\x8C";
- break;
- case 0xA3 :
- return "\xE8\x8F\x9C";
- break;
- case 0xA4 :
- return "\xF0\xA6\xB0\xB6";
- break;
- case 0xA5 :
- return "\xF0\xA6\xB5\xAB";
- break;
- case 0xA6 :
- return "\xF0\xA6\xB3\x95";
- break;
- case 0xA7 :
- return "\xE4\x94\xAB";
- break;
- case 0xA8 :
- return "\xE8\x93\xB1";
- break;
- case 0xA9 :
- return "\xE8\x93\xB3";
- break;
- case 0xAA :
- return "\xE8\x94\x96";
- break;
- case 0xAB :
- return "\xF0\xA7\x8F\x8A";
- break;
- case 0xAC :
- return "\xE8\x95\xA4";
- break;
- case 0xAD :
- return "\xF0\xA6\xBC\xAC";
- break;
- case 0xAE :
- return "\xE4\x95\x9D";
- break;
- case 0xAF :
- return "\xE4\x95\xA1";
- break;
- case 0xB0 :
- return "\xF0\xA6\xBE\xB1";
- break;
- case 0xB1 :
- return "\xF0\xA7\x83\x92";
- break;
- case 0xB2 :
- return "\xE4\x95\xAB";
- break;
- case 0xB3 :
- return "\xE8\x99\x90";
- break;
- case 0xB4 :
- return "\xE8\x99\x9C";
- break;
- case 0xB5 :
- return "\xE8\x99\xA7";
- break;
- case 0xB6 :
- return "\xE8\x99\xA9";
- break;
- case 0xB7 :
- return "\xE8\x9A\xA9";
- break;
- case 0xB8 :
- return "\xE8\x9A\x88";
- break;
- case 0xB9 :
- return "\xE8\x9C\x8E";
- break;
- case 0xBA :
- return "\xE8\x9B\xA2";
- break;
- case 0xBB :
- return "\xE8\x9D\xB9";
- break;
- case 0xBC :
- return "\xE8\x9C\xA8";
- break;
- case 0xBD :
- return "\xE8\x9D\xAB";
- break;
- case 0xBE :
- return "\xE8\x9E\x86";
- break;
- case 0xBF :
- return "\xE4\x97\x97";
- break;
- }
- break;
- case 0xA7 :
- switch (str[3]) {
- case 0x80 :
- return "\xE8\x9F\xA1";
- break;
- case 0x81 :
- return "\xE8\xA0\x81";
- break;
- case 0x82 :
- return "\xE4\x97\xB9";
- break;
- case 0x83 :
- return "\xE8\xA1\xA0";
- break;
- case 0x84 :
- return "\xE8\xA1\xA3";
- break;
- case 0x85 :
- return "\xF0\xA7\x99\xA7";
- break;
- case 0x86 :
- return "\xE8\xA3\x97";
- break;
- case 0x87 :
- return "\xE8\xA3\x9E";
- break;
- case 0x88 :
- return "\xE4\x98\xB5";
- break;
- case 0x89 :
- return "\xE8\xA3\xBA";
- break;
- case 0x8A :
- return "\xE3\x92\xBB";
- break;
- case 0x8B :
- return "\xF0\xA7\xA2\xAE";
- break;
- case 0x8C :
- return "\xF0\xA7\xA5\xA6";
- break;
- case 0x8D :
- return "\xE4\x9A\xBE";
- break;
- case 0x8E :
- return "\xE4\x9B\x87";
- break;
- case 0x8F :
- return "\xE8\xAA\xA0";
- break;
- case 0x90 :
- return "\xE8\xAB\xAD";
- break;
- case 0x91 :
- return "\xE8\xAE\x8A";
- break;
- case 0x92 :
- return "\xE8\xB1\x95";
- break;
- case 0x93 :
- return "\xF0\xA7\xB2\xA8";
- break;
- case 0x94 :
- return "\xE8\xB2\xAB";
- break;
- case 0x95 :
- return "\xE8\xB3\x81";
- break;
- case 0x96 :
- return "\xE8\xB4\x9B";
- break;
- case 0x97 :
- return "\xE8\xB5\xB7";
- break;
- case 0x98 :
- return "\xF0\xA7\xBC\xAF";
- break;
- case 0x99 :
- return "\xF0\xA0\xA0\x84";
- break;
- case 0x9A :
- return "\xE8\xB7\x8B";
- break;
- case 0x9B :
- return "\xE8\xB6\xBC";
- break;
- case 0x9C :
- return "\xE8\xB7\xB0";
- break;
- case 0x9D :
- return "\xF0\xA0\xA3\x9E";
- break;
- case 0x9E :
- return "\xE8\xBB\x94";
- break;
- case 0x9F :
- return "\xE8\xBC\xB8";
- break;
- case 0xA0 :
- return "\xF0\xA8\x97\x92";
- break;
- case 0xA1 :
- return "\xF0\xA8\x97\xAD";
- break;
- case 0xA2 :
- return "\xE9\x82\x94";
- break;
- case 0xA3 :
- return "\xE9\x83\xB1";
- break;
- case 0xA4 :
- return "\xE9\x84\x91";
- break;
- case 0xA5 :
- return "\xF0\xA8\x9C\xAE";
- break;
- case 0xA6 :
- return "\xE9\x84\x9B";
- break;
- case 0xA7 :
- return "\xE9\x88\xB8";
- break;
- case 0xA8 :
- return "\xE9\x8B\x97";
- break;
- case 0xA9 :
- return "\xE9\x8B\x98";
- break;
- case 0xAA :
- return "\xE9\x89\xBC";
- break;
- case 0xAB :
- return "\xE9\x8F\xB9";
- break;
- case 0xAC :
- return "\xE9\x90\x95";
- break;
- case 0xAD :
- return "\xF0\xA8\xAF\xBA";
- break;
- case 0xAE :
- return "\xE9\x96\x8B";
- break;
- case 0xAF :
- return "\xE4\xA6\x95";
- break;
- case 0xB0 :
- return "\xE9\x96\xB7";
- break;
- case 0xB1 :
- return "\xF0\xA8\xB5\xB7";
- break;
- case 0xB2 :
- return "\xE4\xA7\xA6";
- break;
- case 0xB3 :
- return "\xE9\x9B\x83";
- break;
- case 0xB4 :
- return "\xE5\xB6\xB2";
- break;
- case 0xB5 :
- return "\xE9\x9C\xA3";
- break;
- case 0xB6 :
- return "\xF0\xA9\x85\x85";
- break;
- case 0xB7 :
- return "\xF0\xA9\x88\x9A";
- break;
- case 0xB8 :
- return "\xE4\xA9\xAE";
- break;
- case 0xB9 :
- return "\xE4\xA9\xB6";
- break;
- case 0xBA :
- return "\xE9\x9F\xA0";
- break;
- case 0xBB :
- return "\xF0\xA9\x90\x8A";
- break;
- case 0xBC :
- return "\xE4\xAA\xB2";
- break;
- case 0xBD :
- return "\xF0\xA9\x92\x96";
- break;
- case 0xBE :
- return "\xE9\xA0\x8B";
- break;
- case 0xBF :
- return "\xE9\xA0\x8B";
- break;
- }
- break;
- case 0xA8 :
- switch (str[3]) {
- case 0x80 :
- return "\xE9\xA0\xA9";
- break;
- case 0x81 :
- return "\xF0\xA9\x96\xB6";
- break;
- case 0x82 :
- return "\xE9\xA3\xA2";
- break;
- case 0x83 :
- return "\xE4\xAC\xB3";
- break;
- case 0x84 :
- return "\xE9\xA4\xA9";
- break;
- case 0x85 :
- return "\xE9\xA6\xA7";
- break;
- case 0x86 :
- return "\xE9\xA7\x82";
- break;
- case 0x87 :
- return "\xE9\xA7\xBE";
- break;
- case 0x88 :
- return "\xE4\xAF\x8E";
- break;
- case 0x89 :
- return "\xF0\xA9\xAC\xB0";
- break;
- case 0x8A :
- return "\xE9\xAC\x92";
- break;
- case 0x8B :
- return "\xE9\xB1\x80";
- break;
- case 0x8C :
- return "\xE9\xB3\xBD";
- break;
- case 0x8D :
- return "\xE4\xB3\x8E";
- break;
- case 0x8E :
- return "\xE4\xB3\xAD";
- break;
- case 0x8F :
- return "\xE9\xB5\xA7";
- break;
- case 0x90 :
- return "\xF0\xAA\x83\x8E";
- break;
- case 0x91 :
- return "\xE4\xB3\xB8";
- break;
- case 0x92 :
- return "\xF0\xAA\x84\x85";
- break;
- case 0x93 :
- return "\xF0\xAA\x88\x8E";
- break;
- case 0x94 :
- return "\xF0\xAA\x8A\x91";
- break;
- case 0x95 :
- return "\xE9\xBA\xBB";
- break;
- case 0x96 :
- return "\xE4\xB5\x96";
- break;
- case 0x97 :
- return "\xE9\xBB\xB9";
- break;
- case 0x98 :
- return "\xE9\xBB\xBE";
- break;
- case 0x99 :
- return "\xE9\xBC\x85";
- break;
- case 0x9A :
- return "\xE9\xBC\x8F";
- break;
- case 0x9B :
- return "\xE9\xBC\x96";
- break;
- case 0x9C :
- return "\xE9\xBC\xBB";
- break;
- case 0x9D :
- return "\xF0\xAA\x98\x80";
- break;
- }
- break;
- }
- break;
- }
- break;
-}
- return 0;
+ return grn_nfkc50_decompose(utf8);
}
const char *
-grn_nfkc_map2(const unsigned char *prefix, const unsigned char *suffix)
+grn_nfkc_compose(const unsigned char *prefix_utf8,
+ const unsigned char *suffix_utf8)
{
-switch (suffix[0]) {
-case 0xCC :
- switch (suffix[1]) {
- case 0x80 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC3\xA0";
- break;
- case 0x65 :
- return "\xC3\xA8";
- break;
- case 0x69 :
- return "\xC3\xAC";
- break;
- case 0x6E :
- return "\xC7\xB9";
- break;
- case 0x6F :
- return "\xC3\xB2";
- break;
- case 0x75 :
- return "\xC3\xB9";
- break;
- case 0x77 :
- return "\xE1\xBA\x81";
- break;
- case 0x79 :
- return "\xE1\xBB\xB3";
- break;
- case 0xC3 :
- switch (prefix[1]) {
- case 0xA2 :
- return "\xE1\xBA\xA7";
- break;
- case 0xAA :
- return "\xE1\xBB\x81";
- break;
- case 0xB4 :
- return "\xE1\xBB\x93";
- break;
- case 0xBC :
- return "\xC7\x9C";
- break;
- }
- break;
- case 0xC4 :
- switch (prefix[1]) {
- case 0x83 :
- return "\xE1\xBA\xB1";
- break;
- case 0x93 :
- return "\xE1\xB8\x95";
- break;
- }
- break;
- case 0xC5 :
- if (prefix[1] == 0x8D) {
- return "\xE1\xB9\x91";
- }
- break;
- case 0xC6 :
- switch (prefix[1]) {
- case 0xA1 :
- return "\xE1\xBB\x9D";
- break;
- case 0xB0 :
- return "\xE1\xBB\xAB";
- break;
- }
- break;
- case 0xCE :
- switch (prefix[1]) {
- case 0x91 :
- return "\xE1\xBE\xBA";
- break;
- case 0x95 :
- return "\xE1\xBF\x88";
- break;
- case 0x97 :
- return "\xE1\xBF\x8A";
- break;
- case 0x99 :
- return "\xE1\xBF\x9A";
- break;
- case 0x9F :
- return "\xE1\xBF\xB8";
- break;
- case 0xA5 :
- return "\xE1\xBF\xAA";
- break;
- case 0xA9 :
- return "\xE1\xBF\xBA";
- break;
- case 0xB1 :
- return "\xE1\xBD\xB0";
- break;
- case 0xB5 :
- return "\xE1\xBD\xB2";
- break;
- case 0xB7 :
- return "\xE1\xBD\xB4";
- break;
- case 0xB9 :
- return "\xE1\xBD\xB6";
- break;
- case 0xBF :
- return "\xE1\xBD\xB8";
- break;
- }
- break;
- case 0xCF :
- switch (prefix[1]) {
- case 0x85 :
- return "\xE1\xBD\xBA";
- break;
- case 0x89 :
- return "\xE1\xBD\xBC";
- break;
- case 0x8A :
- return "\xE1\xBF\x92";
- break;
- case 0x8B :
- return "\xE1\xBF\xA2";
- break;
- }
- break;
- case 0xD0 :
- switch (prefix[1]) {
- case 0x95 :
- return "\xD0\x80";
- break;
- case 0x98 :
- return "\xD0\x8D";
- break;
- case 0xB5 :
- return "\xD1\x90";
- break;
- case 0xB8 :
- return "\xD1\x9D";
- break;
- }
- break;
- case 0xE1 :
- switch (prefix[1]) {
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xE1\xBC\x82";
- break;
- case 0x81 :
- return "\xE1\xBC\x83";
- break;
- case 0x88 :
- return "\xE1\xBC\x8A";
- break;
- case 0x89 :
- return "\xE1\xBC\x8B";
- break;
- case 0x90 :
- return "\xE1\xBC\x92";
- break;
- case 0x91 :
- return "\xE1\xBC\x93";
- break;
- case 0x98 :
- return "\xE1\xBC\x9A";
- break;
- case 0x99 :
- return "\xE1\xBC\x9B";
- break;
- case 0xA0 :
- return "\xE1\xBC\xA2";
- break;
- case 0xA1 :
- return "\xE1\xBC\xA3";
- break;
- case 0xA8 :
- return "\xE1\xBC\xAA";
- break;
- case 0xA9 :
- return "\xE1\xBC\xAB";
- break;
- case 0xB0 :
- return "\xE1\xBC\xB2";
- break;
- case 0xB1 :
- return "\xE1\xBC\xB3";
- break;
- case 0xB8 :
- return "\xE1\xBC\xBA";
- break;
- case 0xB9 :
- return "\xE1\xBC\xBB";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xE1\xBD\x82";
- break;
- case 0x81 :
- return "\xE1\xBD\x83";
- break;
- case 0x88 :
- return "\xE1\xBD\x8A";
- break;
- case 0x89 :
- return "\xE1\xBD\x8B";
- break;
- case 0x90 :
- return "\xE1\xBD\x92";
- break;
- case 0x91 :
- return "\xE1\xBD\x93";
- break;
- case 0x99 :
- return "\xE1\xBD\x9B";
- break;
- case 0xA0 :
- return "\xE1\xBD\xA2";
- break;
- case 0xA1 :
- return "\xE1\xBD\xA3";
- break;
- case 0xA8 :
- return "\xE1\xBD\xAA";
- break;
- case 0xA9 :
- return "\xE1\xBD\xAB";
- break;
- }
- break;
- }
- break;
- }
- break;
- case 0x81 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC3\xA1";
- break;
- case 0x63 :
- return "\xC4\x87";
- break;
- case 0x65 :
- return "\xC3\xA9";
- break;
- case 0x67 :
- return "\xC7\xB5";
- break;
- case 0x69 :
- return "\xC3\xAD";
- break;
- case 0x6B :
- return "\xE1\xB8\xB1";
- break;
- case 0x6C :
- return "\xC4\xBA";
- break;
- case 0x6D :
- return "\xE1\xB8\xBF";
- break;
- case 0x6E :
- return "\xC5\x84";
- break;
- case 0x6F :
- return "\xC3\xB3";
- break;
- case 0x70 :
- return "\xE1\xB9\x95";
- break;
- case 0x72 :
- return "\xC5\x95";
- break;
- case 0x73 :
- return "\xC5\x9B";
- break;
- case 0x75 :
- return "\xC3\xBA";
- break;
- case 0x77 :
- return "\xE1\xBA\x83";
- break;
- case 0x79 :
- return "\xC3\xBD";
- break;
- case 0x7A :
- return "\xC5\xBA";
- break;
- case 0xC3 :
- switch (prefix[1]) {
- case 0x86 :
- return "\xC7\xBC";
- break;
- case 0x98 :
- return "\xC7\xBE";
- break;
- case 0xA2 :
- return "\xE1\xBA\xA5";
- break;
- case 0xA5 :
- return "\xC7\xBB";
- break;
- case 0xA6 :
- return "\xC7\xBD";
- break;
- case 0xA7 :
- return "\xE1\xB8\x89";
- break;
- case 0xAA :
- return "\xE1\xBA\xBF";
- break;
- case 0xAF :
- return "\xE1\xB8\xAF";
- break;
- case 0xB4 :
- return "\xE1\xBB\x91";
- break;
- case 0xB5 :
- return "\xE1\xB9\x8D";
- break;
- case 0xB8 :
- return "\xC7\xBF";
- break;
- case 0xBC :
- return "\xC7\x98";
- break;
- }
- break;
- case 0xC4 :
- switch (prefix[1]) {
- case 0x83 :
- return "\xE1\xBA\xAF";
- break;
- case 0x93 :
- return "\xE1\xB8\x97";
- break;
- }
- break;
- case 0xC5 :
- switch (prefix[1]) {
- case 0x8D :
- return "\xE1\xB9\x93";
- break;
- case 0xA9 :
- return "\xE1\xB9\xB9";
- break;
- }
- break;
- case 0xC6 :
- switch (prefix[1]) {
- case 0xA1 :
- return "\xE1\xBB\x9B";
- break;
- case 0xB0 :
- return "\xE1\xBB\xA9";
- break;
- }
- break;
- case 0xCE :
- switch (prefix[1]) {
- case 0x91 :
- return "\xCE\x86";
- break;
- case 0x95 :
- return "\xCE\x88";
- break;
- case 0x97 :
- return "\xCE\x89";
- break;
- case 0x99 :
- return "\xCE\x8A";
- break;
- case 0x9F :
- return "\xCE\x8C";
- break;
- case 0xA5 :
- return "\xCE\x8E";
- break;
- case 0xA9 :
- return "\xCE\x8F";
- break;
- case 0xB1 :
- return "\xCE\xAC";
- break;
- case 0xB5 :
- return "\xCE\xAD";
- break;
- case 0xB7 :
- return "\xCE\xAE";
- break;
- case 0xB9 :
- return "\xCE\xAF";
- break;
- case 0xBF :
- return "\xCF\x8C";
- break;
- }
- break;
- case 0xCF :
- switch (prefix[1]) {
- case 0x85 :
- return "\xCF\x8D";
- break;
- case 0x89 :
- return "\xCF\x8E";
- break;
- case 0x8A :
- return "\xCE\x90";
- break;
- case 0x8B :
- return "\xCE\xB0";
- break;
- }
- break;
- case 0xD0 :
- switch (prefix[1]) {
- case 0x93 :
- return "\xD0\x83";
- break;
- case 0x9A :
- return "\xD0\x8C";
- break;
- case 0xB3 :
- return "\xD1\x93";
- break;
- case 0xBA :
- return "\xD1\x9C";
- break;
- }
- break;
- case 0xE1 :
- switch (prefix[1]) {
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xE1\xBC\x84";
- break;
- case 0x81 :
- return "\xE1\xBC\x85";
- break;
- case 0x88 :
- return "\xE1\xBC\x8C";
- break;
- case 0x89 :
- return "\xE1\xBC\x8D";
- break;
- case 0x90 :
- return "\xE1\xBC\x94";
- break;
- case 0x91 :
- return "\xE1\xBC\x95";
- break;
- case 0x98 :
- return "\xE1\xBC\x9C";
- break;
- case 0x99 :
- return "\xE1\xBC\x9D";
- break;
- case 0xA0 :
- return "\xE1\xBC\xA4";
- break;
- case 0xA1 :
- return "\xE1\xBC\xA5";
- break;
- case 0xA8 :
- return "\xE1\xBC\xAC";
- break;
- case 0xA9 :
- return "\xE1\xBC\xAD";
- break;
- case 0xB0 :
- return "\xE1\xBC\xB4";
- break;
- case 0xB1 :
- return "\xE1\xBC\xB5";
- break;
- case 0xB8 :
- return "\xE1\xBC\xBC";
- break;
- case 0xB9 :
- return "\xE1\xBC\xBD";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xE1\xBD\x84";
- break;
- case 0x81 :
- return "\xE1\xBD\x85";
- break;
- case 0x88 :
- return "\xE1\xBD\x8C";
- break;
- case 0x89 :
- return "\xE1\xBD\x8D";
- break;
- case 0x90 :
- return "\xE1\xBD\x94";
- break;
- case 0x91 :
- return "\xE1\xBD\x95";
- break;
- case 0x99 :
- return "\xE1\xBD\x9D";
- break;
- case 0xA0 :
- return "\xE1\xBD\xA4";
- break;
- case 0xA1 :
- return "\xE1\xBD\xA5";
- break;
- case 0xA8 :
- return "\xE1\xBD\xAC";
- break;
- case 0xA9 :
- return "\xE1\xBD\xAD";
- break;
- }
- break;
- }
- break;
- }
- break;
- case 0x82 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC3\xA2";
- break;
- case 0x63 :
- return "\xC4\x89";
- break;
- case 0x65 :
- return "\xC3\xAA";
- break;
- case 0x67 :
- return "\xC4\x9D";
- break;
- case 0x68 :
- return "\xC4\xA5";
- break;
- case 0x69 :
- return "\xC3\xAE";
- break;
- case 0x6A :
- return "\xC4\xB5";
- break;
- case 0x6F :
- return "\xC3\xB4";
- break;
- case 0x73 :
- return "\xC5\x9D";
- break;
- case 0x75 :
- return "\xC3\xBB";
- break;
- case 0x77 :
- return "\xC5\xB5";
- break;
- case 0x79 :
- return "\xC5\xB7";
- break;
- case 0x7A :
- return "\xE1\xBA\x91";
- break;
- case 0xE1 :
- switch (prefix[1]) {
- case 0xBA :
- switch (prefix[2]) {
- case 0xA1 :
- return "\xE1\xBA\xAD";
- break;
- case 0xB9 :
- return "\xE1\xBB\x87";
- break;
- }
- break;
- case 0xBB :
- if (prefix[2] == 0x8D) {
- return "\xE1\xBB\x99";
- }
- break;
- }
- break;
- }
- break;
- case 0x83 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC3\xA3";
- break;
- case 0x65 :
- return "\xE1\xBA\xBD";
- break;
- case 0x69 :
- return "\xC4\xA9";
- break;
- case 0x6E :
- return "\xC3\xB1";
- break;
- case 0x6F :
- return "\xC3\xB5";
- break;
- case 0x75 :
- return "\xC5\xA9";
- break;
- case 0x76 :
- return "\xE1\xB9\xBD";
- break;
- case 0x79 :
- return "\xE1\xBB\xB9";
- break;
- case 0xC3 :
- switch (prefix[1]) {
- case 0xA2 :
- return "\xE1\xBA\xAB";
- break;
- case 0xAA :
- return "\xE1\xBB\x85";
- break;
- case 0xB4 :
- return "\xE1\xBB\x97";
- break;
- }
- break;
- case 0xC4 :
- if (prefix[1] == 0x83) {
- return "\xE1\xBA\xB5";
- }
- break;
- case 0xC6 :
- switch (prefix[1]) {
- case 0xA1 :
- return "\xE1\xBB\xA1";
- break;
- case 0xB0 :
- return "\xE1\xBB\xAF";
- break;
- }
- break;
- }
- break;
- case 0x84 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC4\x81";
- break;
- case 0x65 :
- return "\xC4\x93";
- break;
- case 0x67 :
- return "\xE1\xB8\xA1";
- break;
- case 0x69 :
- return "\xC4\xAB";
- break;
- case 0x6F :
- return "\xC5\x8D";
- break;
- case 0x75 :
- return "\xC5\xAB";
- break;
- case 0x79 :
- return "\xC8\xB3";
- break;
- case 0xC3 :
- switch (prefix[1]) {
- case 0x86 :
- return "\xC7\xA2";
- break;
- case 0xA4 :
- return "\xC7\x9F";
- break;
- case 0xA6 :
- return "\xC7\xA3";
- break;
- case 0xB5 :
- return "\xC8\xAD";
- break;
- case 0xB6 :
- return "\xC8\xAB";
- break;
- case 0xBC :
- return "\xC7\x96";
- break;
- }
- break;
- case 0xC7 :
- if (prefix[1] == 0xAB) {
- return "\xC7\xAD";
- }
- break;
- case 0xC8 :
- switch (prefix[1]) {
- case 0xA7 :
- return "\xC7\xA1";
- break;
- case 0xAF :
- return "\xC8\xB1";
- break;
- }
- break;
- case 0xCE :
- switch (prefix[1]) {
- case 0x91 :
- return "\xE1\xBE\xB9";
- break;
- case 0x99 :
- return "\xE1\xBF\x99";
- break;
- case 0xA5 :
- return "\xE1\xBF\xA9";
- break;
- case 0xB1 :
- return "\xE1\xBE\xB1";
- break;
- case 0xB9 :
- return "\xE1\xBF\x91";
- break;
- }
- break;
- case 0xCF :
- if (prefix[1] == 0x85) {
- return "\xE1\xBF\xA1";
- }
- break;
- case 0xD0 :
- switch (prefix[1]) {
- case 0x98 :
- return "\xD3\xA2";
- break;
- case 0xA3 :
- return "\xD3\xAE";
- break;
- case 0xB8 :
- return "\xD3\xA3";
- break;
- }
- break;
- case 0xD1 :
- if (prefix[1] == 0x83) {
- return "\xD3\xAF";
- }
- break;
- case 0xE1 :
- switch (prefix[1]) {
- case 0xB8 :
- if (prefix[2] == 0xB7) {
- return "\xE1\xB8\xB9";
- }
- break;
- case 0xB9 :
- if (prefix[2] == 0x9B) {
- return "\xE1\xB9\x9D";
- }
- break;
- }
- break;
- }
- break;
- case 0x86 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC4\x83";
- break;
- case 0x65 :
- return "\xC4\x95";
- break;
- case 0x67 :
- return "\xC4\x9F";
- break;
- case 0x69 :
- return "\xC4\xAD";
- break;
- case 0x6F :
- return "\xC5\x8F";
- break;
- case 0x75 :
- return "\xC5\xAD";
- break;
- case 0xC8 :
- if (prefix[1] == 0xA9) {
- return "\xE1\xB8\x9D";
- }
- break;
- case 0xCE :
- switch (prefix[1]) {
- case 0x91 :
- return "\xE1\xBE\xB8";
- break;
- case 0x99 :
- return "\xE1\xBF\x98";
- break;
- case 0xA5 :
- return "\xE1\xBF\xA8";
- break;
- case 0xB1 :
- return "\xE1\xBE\xB0";
- break;
- case 0xB9 :
- return "\xE1\xBF\x90";
- break;
- }
- break;
- case 0xCF :
- if (prefix[1] == 0x85) {
- return "\xE1\xBF\xA0";
- }
- break;
- case 0xD0 :
- switch (prefix[1]) {
- case 0x90 :
- return "\xD3\x90";
- break;
- case 0x95 :
- return "\xD3\x96";
- break;
- case 0x96 :
- return "\xD3\x81";
- break;
- case 0x98 :
- return "\xD0\x99";
- break;
- case 0xA3 :
- return "\xD0\x8E";
- break;
- case 0xB0 :
- return "\xD3\x91";
- break;
- case 0xB5 :
- return "\xD3\x97";
- break;
- case 0xB6 :
- return "\xD3\x82";
- break;
- case 0xB8 :
- return "\xD0\xB9";
- break;
- }
- break;
- case 0xD1 :
- if (prefix[1] == 0x83) {
- return "\xD1\x9E";
- }
- break;
- case 0xE1 :
- if (prefix[1] == 0xBA) {
- if (prefix[2] == 0xA1) {
- return "\xE1\xBA\xB7";
- }
- }
- break;
- }
- break;
- case 0x87 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC8\xA7";
- break;
- case 0x62 :
- return "\xE1\xB8\x83";
- break;
- case 0x63 :
- return "\xC4\x8B";
- break;
- case 0x64 :
- return "\xE1\xB8\x8B";
- break;
- case 0x65 :
- return "\xC4\x97";
- break;
- case 0x66 :
- return "\xE1\xB8\x9F";
- break;
- case 0x67 :
- return "\xC4\xA1";
- break;
- case 0x68 :
- return "\xE1\xB8\xA3";
- break;
- case 0x6D :
- return "\xE1\xB9\x81";
- break;
- case 0x6E :
- return "\xE1\xB9\x85";
- break;
- case 0x6F :
- return "\xC8\xAF";
- break;
- case 0x70 :
- return "\xE1\xB9\x97";
- break;
- case 0x72 :
- return "\xE1\xB9\x99";
- break;
- case 0x73 :
- return "\xE1\xB9\xA1";
- break;
- case 0x74 :
- return "\xE1\xB9\xAB";
- break;
- case 0x77 :
- return "\xE1\xBA\x87";
- break;
- case 0x78 :
- return "\xE1\xBA\x8B";
- break;
- case 0x79 :
- return "\xE1\xBA\x8F";
- break;
- case 0x7A :
- return "\xC5\xBC";
- break;
- case 0xC5 :
- switch (prefix[1]) {
- case 0x9B :
- return "\xE1\xB9\xA5";
- break;
- case 0xA1 :
- return "\xE1\xB9\xA7";
- break;
- }
- break;
- case 0xE1 :
- if (prefix[1] == 0xB9) {
- if (prefix[2] == 0xA3) {
- return "\xE1\xB9\xA9";
- }
- }
- break;
- }
- break;
- case 0x88 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC3\xA4";
- break;
- case 0x65 :
- return "\xC3\xAB";
- break;
- case 0x68 :
- return "\xE1\xB8\xA7";
- break;
- case 0x69 :
- return "\xC3\xAF";
- break;
- case 0x6F :
- return "\xC3\xB6";
- break;
- case 0x74 :
- return "\xE1\xBA\x97";
- break;
- case 0x75 :
- return "\xC3\xBC";
- break;
- case 0x77 :
- return "\xE1\xBA\x85";
- break;
- case 0x78 :
- return "\xE1\xBA\x8D";
- break;
- case 0x79 :
- return "\xC3\xBF";
- break;
- case 0xC3 :
- if (prefix[1] == 0xB5) {
- return "\xE1\xB9\x8F";
- }
- break;
- case 0xC5 :
- if (prefix[1] == 0xAB) {
- return "\xE1\xB9\xBB";
- }
- break;
- case 0xCE :
- switch (prefix[1]) {
- case 0x99 :
- return "\xCE\xAA";
- break;
- case 0xA5 :
- return "\xCE\xAB";
- break;
- case 0xB9 :
- return "\xCF\x8A";
- break;
- }
- break;
- case 0xCF :
- if (prefix[1] == 0x85) {
- return "\xCF\x8B";
- }
- break;
- case 0xD0 :
- switch (prefix[1]) {
- case 0x86 :
- return "\xD0\x87";
- break;
- case 0x90 :
- return "\xD3\x92";
- break;
- case 0x95 :
- return "\xD0\x81";
- break;
- case 0x96 :
- return "\xD3\x9C";
- break;
- case 0x97 :
- return "\xD3\x9E";
- break;
- case 0x98 :
- return "\xD3\xA4";
- break;
- case 0x9E :
- return "\xD3\xA6";
- break;
- case 0xA3 :
- return "\xD3\xB0";
- break;
- case 0xA7 :
- return "\xD3\xB4";
- break;
- case 0xAB :
- return "\xD3\xB8";
- break;
- case 0xAD :
- return "\xD3\xAC";
- break;
- case 0xB0 :
- return "\xD3\x93";
- break;
- case 0xB5 :
- return "\xD1\x91";
- break;
- case 0xB6 :
- return "\xD3\x9D";
- break;
- case 0xB7 :
- return "\xD3\x9F";
- break;
- case 0xB8 :
- return "\xD3\xA5";
- break;
- case 0xBE :
- return "\xD3\xA7";
- break;
- }
- break;
- case 0xD1 :
- switch (prefix[1]) {
- case 0x83 :
- return "\xD3\xB1";
- break;
- case 0x87 :
- return "\xD3\xB5";
- break;
- case 0x8B :
- return "\xD3\xB9";
- break;
- case 0x8D :
- return "\xD3\xAD";
- break;
- case 0x96 :
- return "\xD1\x97";
- break;
- }
- break;
- case 0xD3 :
- switch (prefix[1]) {
- case 0x98 :
- return "\xD3\x9A";
- break;
- case 0x99 :
- return "\xD3\x9B";
- break;
- case 0xA8 :
- return "\xD3\xAA";
- break;
- case 0xA9 :
- return "\xD3\xAB";
- break;
- }
- break;
- }
- break;
- case 0x89 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xE1\xBA\xA3";
- break;
- case 0x65 :
- return "\xE1\xBA\xBB";
- break;
- case 0x69 :
- return "\xE1\xBB\x89";
- break;
- case 0x6F :
- return "\xE1\xBB\x8F";
- break;
- case 0x75 :
- return "\xE1\xBB\xA7";
- break;
- case 0x79 :
- return "\xE1\xBB\xB7";
- break;
- case 0xC3 :
- switch (prefix[1]) {
- case 0xA2 :
- return "\xE1\xBA\xA9";
- break;
- case 0xAA :
- return "\xE1\xBB\x83";
- break;
- case 0xB4 :
- return "\xE1\xBB\x95";
- break;
- }
- break;
- case 0xC4 :
- if (prefix[1] == 0x83) {
- return "\xE1\xBA\xB3";
- }
- break;
- case 0xC6 :
- switch (prefix[1]) {
- case 0xA1 :
- return "\xE1\xBB\x9F";
- break;
- case 0xB0 :
- return "\xE1\xBB\xAD";
- break;
- }
- break;
- }
- break;
- case 0x8A :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC3\xA5";
- break;
- case 0x75 :
- return "\xC5\xAF";
- break;
- case 0x77 :
- return "\xE1\xBA\x98";
- break;
- case 0x79 :
- return "\xE1\xBA\x99";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[0]) {
- case 0x6F :
- return "\xC5\x91";
- break;
- case 0x75 :
- return "\xC5\xB1";
- break;
- case 0xD0 :
- if (prefix[1] == 0xA3) {
- return "\xD3\xB2";
- }
- break;
- case 0xD1 :
- if (prefix[1] == 0x83) {
- return "\xD3\xB3";
- }
- break;
- }
- break;
- case 0x8C :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC7\x8E";
- break;
- case 0x63 :
- return "\xC4\x8D";
- break;
- case 0x64 :
- return "\xC4\x8F";
- break;
- case 0x65 :
- return "\xC4\x9B";
- break;
- case 0x67 :
- return "\xC7\xA7";
- break;
- case 0x68 :
- return "\xC8\x9F";
- break;
- case 0x69 :
- return "\xC7\x90";
- break;
- case 0x6A :
- return "\xC7\xB0";
- break;
- case 0x6B :
- return "\xC7\xA9";
- break;
- case 0x6C :
- return "\xC4\xBE";
- break;
- case 0x6E :
- return "\xC5\x88";
- break;
- case 0x6F :
- return "\xC7\x92";
- break;
- case 0x72 :
- return "\xC5\x99";
- break;
- case 0x73 :
- return "\xC5\xA1";
- break;
- case 0x74 :
- return "\xC5\xA5";
- break;
- case 0x75 :
- return "\xC7\x94";
- break;
- case 0x7A :
- return "\xC5\xBE";
- break;
- case 0xC3 :
- if (prefix[1] == 0xBC) {
- return "\xC7\x9A";
- }
- break;
- case 0xC6 :
- if (prefix[1] == 0xB7) {
- return "\xC7\xAE";
- }
- break;
- case 0xCA :
- if (prefix[1] == 0x92) {
- return "\xC7\xAF";
- }
- break;
- }
- break;
- case 0x8F :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC8\x81";
- break;
- case 0x65 :
- return "\xC8\x85";
- break;
- case 0x69 :
- return "\xC8\x89";
- break;
- case 0x6F :
- return "\xC8\x8D";
- break;
- case 0x72 :
- return "\xC8\x91";
- break;
- case 0x75 :
- return "\xC8\x95";
- break;
- case 0xD1 :
- switch (prefix[1]) {
- case 0xB4 :
- return "\xD1\xB6";
- break;
- case 0xB5 :
- return "\xD1\xB7";
- break;
- }
- break;
- }
- break;
- case 0x91 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC8\x83";
- break;
- case 0x65 :
- return "\xC8\x87";
- break;
- case 0x69 :
- return "\xC8\x8B";
- break;
- case 0x6F :
- return "\xC8\x8F";
- break;
- case 0x72 :
- return "\xC8\x93";
- break;
- case 0x75 :
- return "\xC8\x97";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[0]) {
- case 0xCE :
- switch (prefix[1]) {
- case 0x91 :
- return "\xE1\xBC\x88";
- break;
- case 0x95 :
- return "\xE1\xBC\x98";
- break;
- case 0x97 :
- return "\xE1\xBC\xA8";
- break;
- case 0x99 :
- return "\xE1\xBC\xB8";
- break;
- case 0x9F :
- return "\xE1\xBD\x88";
- break;
- case 0xA9 :
- return "\xE1\xBD\xA8";
- break;
- case 0xB1 :
- return "\xE1\xBC\x80";
- break;
- case 0xB5 :
- return "\xE1\xBC\x90";
- break;
- case 0xB7 :
- return "\xE1\xBC\xA0";
- break;
- case 0xB9 :
- return "\xE1\xBC\xB0";
- break;
- case 0xBF :
- return "\xE1\xBD\x80";
- break;
- }
- break;
- case 0xCF :
- switch (prefix[1]) {
- case 0x81 :
- return "\xE1\xBF\xA4";
- break;
- case 0x85 :
- return "\xE1\xBD\x90";
- break;
- case 0x89 :
- return "\xE1\xBD\xA0";
- break;
- }
- break;
- }
- break;
- case 0x94 :
- switch (prefix[0]) {
- case 0xCE :
- switch (prefix[1]) {
- case 0x91 :
- return "\xE1\xBC\x89";
- break;
- case 0x95 :
- return "\xE1\xBC\x99";
- break;
- case 0x97 :
- return "\xE1\xBC\xA9";
- break;
- case 0x99 :
- return "\xE1\xBC\xB9";
- break;
- case 0x9F :
- return "\xE1\xBD\x89";
- break;
- case 0xA1 :
- return "\xE1\xBF\xAC";
- break;
- case 0xA5 :
- return "\xE1\xBD\x99";
- break;
- case 0xA9 :
- return "\xE1\xBD\xA9";
- break;
- case 0xB1 :
- return "\xE1\xBC\x81";
- break;
- case 0xB5 :
- return "\xE1\xBC\x91";
- break;
- case 0xB7 :
- return "\xE1\xBC\xA1";
- break;
- case 0xB9 :
- return "\xE1\xBC\xB1";
- break;
- case 0xBF :
- return "\xE1\xBD\x81";
- break;
- }
- break;
- case 0xCF :
- switch (prefix[1]) {
- case 0x81 :
- return "\xE1\xBF\xA5";
- break;
- case 0x85 :
- return "\xE1\xBD\x91";
- break;
- case 0x89 :
- return "\xE1\xBD\xA1";
- break;
- }
- break;
- }
- break;
- case 0x9B :
- switch (prefix[0]) {
- case 0x6F :
- return "\xC6\xA1";
- break;
- case 0x75 :
- return "\xC6\xB0";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xE1\xBA\xA1";
- break;
- case 0x62 :
- return "\xE1\xB8\x85";
- break;
- case 0x64 :
- return "\xE1\xB8\x8D";
- break;
- case 0x65 :
- return "\xE1\xBA\xB9";
- break;
- case 0x68 :
- return "\xE1\xB8\xA5";
- break;
- case 0x69 :
- return "\xE1\xBB\x8B";
- break;
- case 0x6B :
- return "\xE1\xB8\xB3";
- break;
- case 0x6C :
- return "\xE1\xB8\xB7";
- break;
- case 0x6D :
- return "\xE1\xB9\x83";
- break;
- case 0x6E :
- return "\xE1\xB9\x87";
- break;
- case 0x6F :
- return "\xE1\xBB\x8D";
- break;
- case 0x72 :
- return "\xE1\xB9\x9B";
- break;
- case 0x73 :
- return "\xE1\xB9\xA3";
- break;
- case 0x74 :
- return "\xE1\xB9\xAD";
- break;
- case 0x75 :
- return "\xE1\xBB\xA5";
- break;
- case 0x76 :
- return "\xE1\xB9\xBF";
- break;
- case 0x77 :
- return "\xE1\xBA\x89";
- break;
- case 0x79 :
- return "\xE1\xBB\xB5";
- break;
- case 0x7A :
- return "\xE1\xBA\x93";
- break;
- case 0xC6 :
- switch (prefix[1]) {
- case 0xA1 :
- return "\xE1\xBB\xA3";
- break;
- case 0xB0 :
- return "\xE1\xBB\xB1";
- break;
- }
- break;
- }
- break;
- case 0xA4 :
- if (prefix[0] == 0x75) {
- return "\xE1\xB9\xB3";
- }
- break;
- case 0xA5 :
- if (prefix[0] == 0x61) {
- return "\xE1\xB8\x81";
- }
- break;
- case 0xA6 :
- switch (prefix[0]) {
- case 0x73 :
- return "\xC8\x99";
- break;
- case 0x74 :
- return "\xC8\x9B";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[0]) {
- case 0x63 :
- return "\xC3\xA7";
- break;
- case 0x64 :
- return "\xE1\xB8\x91";
- break;
- case 0x65 :
- return "\xC8\xA9";
- break;
- case 0x67 :
- return "\xC4\xA3";
- break;
- case 0x68 :
- return "\xE1\xB8\xA9";
- break;
- case 0x6B :
- return "\xC4\xB7";
- break;
- case 0x6C :
- return "\xC4\xBC";
- break;
- case 0x6E :
- return "\xC5\x86";
- break;
- case 0x72 :
- return "\xC5\x97";
- break;
- case 0x73 :
- return "\xC5\x9F";
- break;
- case 0x74 :
- return "\xC5\xA3";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[0]) {
- case 0x61 :
- return "\xC4\x85";
- break;
- case 0x65 :
- return "\xC4\x99";
- break;
- case 0x69 :
- return "\xC4\xAF";
- break;
- case 0x6F :
- return "\xC7\xAB";
- break;
- case 0x75 :
- return "\xC5\xB3";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[0]) {
- case 0x64 :
- return "\xE1\xB8\x93";
- break;
- case 0x65 :
- return "\xE1\xB8\x99";
- break;
- case 0x6C :
- return "\xE1\xB8\xBD";
- break;
- case 0x6E :
- return "\xE1\xB9\x8B";
- break;
- case 0x74 :
- return "\xE1\xB9\xB1";
- break;
- case 0x75 :
- return "\xE1\xB9\xB7";
- break;
- }
- break;
- case 0xAE :
- if (prefix[0] == 0x68) {
- return "\xE1\xB8\xAB";
- }
- break;
- case 0xB0 :
- switch (prefix[0]) {
- case 0x65 :
- return "\xE1\xB8\x9B";
- break;
- case 0x69 :
- return "\xE1\xB8\xAD";
- break;
- case 0x75 :
- return "\xE1\xB9\xB5";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[0]) {
- case 0x62 :
- return "\xE1\xB8\x87";
- break;
- case 0x64 :
- return "\xE1\xB8\x8F";
- break;
- case 0x68 :
- return "\xE1\xBA\x96";
- break;
- case 0x6B :
- return "\xE1\xB8\xB5";
- break;
- case 0x6C :
- return "\xE1\xB8\xBB";
- break;
- case 0x6E :
- return "\xE1\xB9\x89";
- break;
- case 0x72 :
- return "\xE1\xB9\x9F";
- break;
- case 0x74 :
- return "\xE1\xB9\xAF";
- break;
- case 0x7A :
- return "\xE1\xBA\x95";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[0]) {
- case 0x3C :
- return "\xE2\x89\xAE";
- break;
- case 0x3D :
- return "\xE2\x89\xA0";
- break;
- case 0x3E :
- return "\xE2\x89\xAF";
- break;
- case 0xE2 :
- switch (prefix[1]) {
- case 0x86 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xE2\x86\x9A";
- break;
- case 0x92 :
- return "\xE2\x86\x9B";
- break;
- case 0x94 :
- return "\xE2\x86\xAE";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xE2\x87\x8D";
- break;
- case 0x92 :
- return "\xE2\x87\x8F";
- break;
- case 0x94 :
- return "\xE2\x87\x8E";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x83 :
- return "\xE2\x88\x84";
- break;
- case 0x88 :
- return "\xE2\x88\x89";
- break;
- case 0x8B :
- return "\xE2\x88\x8C";
- break;
- case 0xA3 :
- return "\xE2\x88\xA4";
- break;
- case 0xA5 :
- return "\xE2\x88\xA6";
- break;
- case 0xBC :
- return "\xE2\x89\x81";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x83 :
- return "\xE2\x89\x84";
- break;
- case 0x85 :
- return "\xE2\x89\x87";
- break;
- case 0x88 :
- return "\xE2\x89\x89";
- break;
- case 0x8D :
- return "\xE2\x89\xAD";
- break;
- case 0xA1 :
- return "\xE2\x89\xA2";
- break;
- case 0xA4 :
- return "\xE2\x89\xB0";
- break;
- case 0xA5 :
- return "\xE2\x89\xB1";
- break;
- case 0xB2 :
- return "\xE2\x89\xB4";
- break;
- case 0xB3 :
- return "\xE2\x89\xB5";
- break;
- case 0xB6 :
- return "\xE2\x89\xB8";
- break;
- case 0xB7 :
- return "\xE2\x89\xB9";
- break;
- case 0xBA :
- return "\xE2\x8A\x80";
- break;
- case 0xBB :
- return "\xE2\x8A\x81";
- break;
- case 0xBC :
- return "\xE2\x8B\xA0";
- break;
- case 0xBD :
- return "\xE2\x8B\xA1";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x82 :
- return "\xE2\x8A\x84";
- break;
- case 0x83 :
- return "\xE2\x8A\x85";
- break;
- case 0x86 :
- return "\xE2\x8A\x88";
- break;
- case 0x87 :
- return "\xE2\x8A\x89";
- break;
- case 0x91 :
- return "\xE2\x8B\xA2";
- break;
- case 0x92 :
- return "\xE2\x8B\xA3";
- break;
- case 0xA2 :
- return "\xE2\x8A\xAC";
- break;
- case 0xA8 :
- return "\xE2\x8A\xAD";
- break;
- case 0xA9 :
- return "\xE2\x8A\xAE";
- break;
- case 0xAB :
- return "\xE2\x8A\xAF";
- break;
- case 0xB2 :
- return "\xE2\x8B\xAA";
- break;
- case 0xB3 :
- return "\xE2\x8B\xAB";
- break;
- case 0xB4 :
- return "\xE2\x8B\xAC";
- break;
- case 0xB5 :
- return "\xE2\x8B\xAD";
- break;
- }
- break;
- }
- break;
- }
- break;
- }
- break;
-case 0xCD :
- switch (suffix[1]) {
- case 0x82 :
- switch (prefix[0]) {
- case 0xCE :
- switch (prefix[1]) {
- case 0xB1 :
- return "\xE1\xBE\xB6";
- break;
- case 0xB7 :
- return "\xE1\xBF\x86";
- break;
- case 0xB9 :
- return "\xE1\xBF\x96";
- break;
- }
- break;
- case 0xCF :
- switch (prefix[1]) {
- case 0x85 :
- return "\xE1\xBF\xA6";
- break;
- case 0x89 :
- return "\xE1\xBF\xB6";
- break;
- case 0x8A :
- return "\xE1\xBF\x97";
- break;
- case 0x8B :
- return "\xE1\xBF\xA7";
- break;
- }
- break;
- case 0xE1 :
- switch (prefix[1]) {
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xE1\xBC\x86";
- break;
- case 0x81 :
- return "\xE1\xBC\x87";
- break;
- case 0x88 :
- return "\xE1\xBC\x8E";
- break;
- case 0x89 :
- return "\xE1\xBC\x8F";
- break;
- case 0xA0 :
- return "\xE1\xBC\xA6";
- break;
- case 0xA1 :
- return "\xE1\xBC\xA7";
- break;
- case 0xA8 :
- return "\xE1\xBC\xAE";
- break;
- case 0xA9 :
- return "\xE1\xBC\xAF";
- break;
- case 0xB0 :
- return "\xE1\xBC\xB6";
- break;
- case 0xB1 :
- return "\xE1\xBC\xB7";
- break;
- case 0xB8 :
- return "\xE1\xBC\xBE";
- break;
- case 0xB9 :
- return "\xE1\xBC\xBF";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xE1\xBD\x96";
- break;
- case 0x91 :
- return "\xE1\xBD\x97";
- break;
- case 0x99 :
- return "\xE1\xBD\x9F";
- break;
- case 0xA0 :
- return "\xE1\xBD\xA6";
- break;
- case 0xA1 :
- return "\xE1\xBD\xA7";
- break;
- case 0xA8 :
- return "\xE1\xBD\xAE";
- break;
- case 0xA9 :
- return "\xE1\xBD\xAF";
- break;
- }
- break;
- }
- break;
- }
- break;
- case 0x85 :
- switch (prefix[0]) {
- case 0xCE :
- switch (prefix[1]) {
- case 0x91 :
- return "\xE1\xBE\xBC";
- break;
- case 0x97 :
- return "\xE1\xBF\x8C";
- break;
- case 0xA9 :
- return "\xE1\xBF\xBC";
- break;
- case 0xAC :
- return "\xE1\xBE\xB4";
- break;
- case 0xAE :
- return "\xE1\xBF\x84";
- break;
- case 0xB1 :
- return "\xE1\xBE\xB3";
- break;
- case 0xB7 :
- return "\xE1\xBF\x83";
- break;
- }
- break;
- case 0xCF :
- switch (prefix[1]) {
- case 0x89 :
- return "\xE1\xBF\xB3";
- break;
- case 0x8E :
- return "\xE1\xBF\xB4";
- break;
- }
- break;
- case 0xE1 :
- switch (prefix[1]) {
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xE1\xBE\x80";
- break;
- case 0x81 :
- return "\xE1\xBE\x81";
- break;
- case 0x82 :
- return "\xE1\xBE\x82";
- break;
- case 0x83 :
- return "\xE1\xBE\x83";
- break;
- case 0x84 :
- return "\xE1\xBE\x84";
- break;
- case 0x85 :
- return "\xE1\xBE\x85";
- break;
- case 0x86 :
- return "\xE1\xBE\x86";
- break;
- case 0x87 :
- return "\xE1\xBE\x87";
- break;
- case 0x88 :
- return "\xE1\xBE\x88";
- break;
- case 0x89 :
- return "\xE1\xBE\x89";
- break;
- case 0x8A :
- return "\xE1\xBE\x8A";
- break;
- case 0x8B :
- return "\xE1\xBE\x8B";
- break;
- case 0x8C :
- return "\xE1\xBE\x8C";
- break;
- case 0x8D :
- return "\xE1\xBE\x8D";
- break;
- case 0x8E :
- return "\xE1\xBE\x8E";
- break;
- case 0x8F :
- return "\xE1\xBE\x8F";
- break;
- case 0xA0 :
- return "\xE1\xBE\x90";
- break;
- case 0xA1 :
- return "\xE1\xBE\x91";
- break;
- case 0xA2 :
- return "\xE1\xBE\x92";
- break;
- case 0xA3 :
- return "\xE1\xBE\x93";
- break;
- case 0xA4 :
- return "\xE1\xBE\x94";
- break;
- case 0xA5 :
- return "\xE1\xBE\x95";
- break;
- case 0xA6 :
- return "\xE1\xBE\x96";
- break;
- case 0xA7 :
- return "\xE1\xBE\x97";
- break;
- case 0xA8 :
- return "\xE1\xBE\x98";
- break;
- case 0xA9 :
- return "\xE1\xBE\x99";
- break;
- case 0xAA :
- return "\xE1\xBE\x9A";
- break;
- case 0xAB :
- return "\xE1\xBE\x9B";
- break;
- case 0xAC :
- return "\xE1\xBE\x9C";
- break;
- case 0xAD :
- return "\xE1\xBE\x9D";
- break;
- case 0xAE :
- return "\xE1\xBE\x9E";
- break;
- case 0xAF :
- return "\xE1\xBE\x9F";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0xA0 :
- return "\xE1\xBE\xA0";
- break;
- case 0xA1 :
- return "\xE1\xBE\xA1";
- break;
- case 0xA2 :
- return "\xE1\xBE\xA2";
- break;
- case 0xA3 :
- return "\xE1\xBE\xA3";
- break;
- case 0xA4 :
- return "\xE1\xBE\xA4";
- break;
- case 0xA5 :
- return "\xE1\xBE\xA5";
- break;
- case 0xA6 :
- return "\xE1\xBE\xA6";
- break;
- case 0xA7 :
- return "\xE1\xBE\xA7";
- break;
- case 0xA8 :
- return "\xE1\xBE\xA8";
- break;
- case 0xA9 :
- return "\xE1\xBE\xA9";
- break;
- case 0xAA :
- return "\xE1\xBE\xAA";
- break;
- case 0xAB :
- return "\xE1\xBE\xAB";
- break;
- case 0xAC :
- return "\xE1\xBE\xAC";
- break;
- case 0xAD :
- return "\xE1\xBE\xAD";
- break;
- case 0xAE :
- return "\xE1\xBE\xAE";
- break;
- case 0xAF :
- return "\xE1\xBE\xAF";
- break;
- case 0xB0 :
- return "\xE1\xBE\xB2";
- break;
- case 0xB4 :
- return "\xE1\xBF\x82";
- break;
- case 0xBC :
- return "\xE1\xBF\xB2";
- break;
- }
- break;
- case 0xBE :
- if (prefix[2] == 0xB6) {
- return "\xE1\xBE\xB7";
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x86 :
- return "\xE1\xBF\x87";
- break;
- case 0xB6 :
- return "\xE1\xBF\xB7";
- break;
- }
- break;
- }
- break;
- }
- break;
- }
- break;
-case 0xD9 :
- switch (suffix[1]) {
- case 0x93 :
- if (prefix[0] == 0xD8) {
- if (prefix[1] == 0xA7) {
- return "\xD8\xA2";
- }
- }
- break;
- case 0x94 :
- switch (prefix[0]) {
- case 0xD8 :
- if (prefix[1] == 0xA7) {
- return "\xD8\xA3";
- }
- break;
- case 0xD9 :
- switch (prefix[1]) {
- case 0x88 :
- return "\xD8\xA4";
- break;
- case 0x8A :
- return "\xD8\xA6";
- break;
- }
- break;
- case 0xDB :
- switch (prefix[1]) {
- case 0x81 :
- return "\xDB\x82";
- break;
- case 0x92 :
- return "\xDB\x93";
- break;
- case 0x95 :
- return "\xDB\x80";
- break;
- }
- break;
- }
- break;
- case 0x95 :
- if (prefix[0] == 0xD8) {
- if (prefix[1] == 0xA7) {
- return "\xD8\xA5";
- }
- }
- break;
- }
- break;
-case 0xE0 :
- switch (suffix[1]) {
- case 0xA4 :
- if (suffix[2] == 0xBC) {
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xA4) {
- switch (prefix[2]) {
- case 0xA8 :
- return "\xE0\xA4\xA9";
- break;
- case 0xB0 :
- return "\xE0\xA4\xB1";
- break;
- case 0xB3 :
- return "\xE0\xA4\xB4";
- break;
- }
- }
- }
- }
- break;
- case 0xA6 :
- if (suffix[2] == 0xBE) {
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xA7) {
- if (prefix[2] == 0x87) {
- return "\xE0\xA7\x8B";
- }
- }
- }
- }
- break;
- case 0xA7 :
- if (suffix[2] == 0x97) {
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xA7) {
- if (prefix[2] == 0x87) {
- return "\xE0\xA7\x8C";
- }
- }
- }
- }
- break;
- case 0xAC :
- if (suffix[2] == 0xBE) {
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xAD) {
- if (prefix[2] == 0x87) {
- return "\xE0\xAD\x8B";
- }
- }
- }
- }
- break;
- case 0xAD :
- switch (suffix[2]) {
- case 0x96 :
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xAD) {
- if (prefix[2] == 0x87) {
- return "\xE0\xAD\x88";
- }
- }
- }
- break;
- case 0x97 :
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xAD) {
- if (prefix[2] == 0x87) {
- return "\xE0\xAD\x8C";
- }
- }
- }
- break;
- }
- break;
- case 0xAE :
- if (suffix[2] == 0xBE) {
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xAF) {
- switch (prefix[2]) {
- case 0x86 :
- return "\xE0\xAF\x8A";
- break;
- case 0x87 :
- return "\xE0\xAF\x8B";
- break;
- }
- }
- }
- }
- break;
- case 0xAF :
- if (suffix[2] == 0x97) {
- if (prefix[0] == 0xE0) {
- switch (prefix[1]) {
- case 0xAE :
- if (prefix[2] == 0x92) {
- return "\xE0\xAE\x94";
- }
- break;
- case 0xAF :
- if (prefix[2] == 0x86) {
- return "\xE0\xAF\x8C";
- }
- break;
- }
- }
- }
- break;
- case 0xB1 :
- if (suffix[2] == 0x96) {
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xB1) {
- if (prefix[2] == 0x86) {
- return "\xE0\xB1\x88";
- }
- }
- }
- }
- break;
- case 0xB3 :
- switch (suffix[2]) {
- case 0x82 :
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xB3) {
- if (prefix[2] == 0x86) {
- return "\xE0\xB3\x8A";
- }
- }
- }
- break;
- case 0x95 :
- if (prefix[0] == 0xE0) {
- switch (prefix[1]) {
- case 0xB2 :
- if (prefix[2] == 0xBF) {
- return "\xE0\xB3\x80";
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x86 :
- return "\xE0\xB3\x87";
- break;
- case 0x8A :
- return "\xE0\xB3\x8B";
- break;
- }
- break;
- }
- }
- break;
- case 0x96 :
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xB3) {
- if (prefix[2] == 0x86) {
- return "\xE0\xB3\x88";
- }
- }
- }
- break;
- }
- break;
- case 0xB4 :
- if (suffix[2] == 0xBE) {
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xB5) {
- switch (prefix[2]) {
- case 0x86 :
- return "\xE0\xB5\x8A";
- break;
- case 0x87 :
- return "\xE0\xB5\x8B";
- break;
- }
- }
- }
- }
- break;
- case 0xB5 :
- if (suffix[2] == 0x97) {
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xB5) {
- if (prefix[2] == 0x86) {
- return "\xE0\xB5\x8C";
- }
- }
- }
- }
- break;
- case 0xB7 :
- switch (suffix[2]) {
- case 0x8A :
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xB7) {
- switch (prefix[2]) {
- case 0x99 :
- return "\xE0\xB7\x9A";
- break;
- case 0x9C :
- return "\xE0\xB7\x9D";
- break;
- }
- }
- }
- break;
- case 0x8F :
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xB7) {
- if (prefix[2] == 0x99) {
- return "\xE0\xB7\x9C";
- }
- }
- }
- break;
- case 0x9F :
- if (prefix[0] == 0xE0) {
- if (prefix[1] == 0xB7) {
- if (prefix[2] == 0x99) {
- return "\xE0\xB7\x9E";
- }
- }
- }
- break;
- }
- break;
- }
- break;
-case 0xE1 :
- switch (suffix[1]) {
- case 0x80 :
- if (suffix[2] == 0xAE) {
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x80) {
- if (prefix[2] == 0xA5) {
- return "\xE1\x80\xA6";
- }
- }
- }
- }
- break;
- case 0x85 :
- switch (suffix[2]) {
- case 0xA1 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x80";
- break;
- case 0x81 :
- return "\xEA\xB9\x8C";
- break;
- case 0x82 :
- return "\xEB\x82\x98";
- break;
- case 0x83 :
- return "\xEB\x8B\xA4";
- break;
- case 0x84 :
- return "\xEB\x94\xB0";
- break;
- case 0x85 :
- return "\xEB\x9D\xBC";
- break;
- case 0x86 :
- return "\xEB\xA7\x88";
- break;
- case 0x87 :
- return "\xEB\xB0\x94";
- break;
- case 0x88 :
- return "\xEB\xB9\xA0";
- break;
- case 0x89 :
- return "\xEC\x82\xAC";
- break;
- case 0x8A :
- return "\xEC\x8B\xB8";
- break;
- case 0x8B :
- return "\xEC\x95\x84";
- break;
- case 0x8C :
- return "\xEC\x9E\x90";
- break;
- case 0x8D :
- return "\xEC\xA7\x9C";
- break;
- case 0x8E :
- return "\xEC\xB0\xA8";
- break;
- case 0x8F :
- return "\xEC\xB9\xB4";
- break;
- case 0x90 :
- return "\xED\x83\x80";
- break;
- case 0x91 :
- return "\xED\x8C\x8C";
- break;
- case 0x92 :
- return "\xED\x95\x98";
- break;
- }
- }
- }
- break;
- case 0xA2 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x9C";
- break;
- case 0x81 :
- return "\xEA\xB9\xA8";
- break;
- case 0x82 :
- return "\xEB\x82\xB4";
- break;
- case 0x83 :
- return "\xEB\x8C\x80";
- break;
- case 0x84 :
- return "\xEB\x95\x8C";
- break;
- case 0x85 :
- return "\xEB\x9E\x98";
- break;
- case 0x86 :
- return "\xEB\xA7\xA4";
- break;
- case 0x87 :
- return "\xEB\xB0\xB0";
- break;
- case 0x88 :
- return "\xEB\xB9\xBC";
- break;
- case 0x89 :
- return "\xEC\x83\x88";
- break;
- case 0x8A :
- return "\xEC\x8C\x94";
- break;
- case 0x8B :
- return "\xEC\x95\xA0";
- break;
- case 0x8C :
- return "\xEC\x9E\xAC";
- break;
- case 0x8D :
- return "\xEC\xA7\xB8";
- break;
- case 0x8E :
- return "\xEC\xB1\x84";
- break;
- case 0x8F :
- return "\xEC\xBA\x90";
- break;
- case 0x90 :
- return "\xED\x83\x9C";
- break;
- case 0x91 :
- return "\xED\x8C\xA8";
- break;
- case 0x92 :
- return "\xED\x95\xB4";
- break;
- }
- }
- }
- break;
- case 0xA3 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\xB8";
- break;
- case 0x81 :
- return "\xEA\xBA\x84";
- break;
- case 0x82 :
- return "\xEB\x83\x90";
- break;
- case 0x83 :
- return "\xEB\x8C\x9C";
- break;
- case 0x84 :
- return "\xEB\x95\xA8";
- break;
- case 0x85 :
- return "\xEB\x9E\xB4";
- break;
- case 0x86 :
- return "\xEB\xA8\x80";
- break;
- case 0x87 :
- return "\xEB\xB1\x8C";
- break;
- case 0x88 :
- return "\xEB\xBA\x98";
- break;
- case 0x89 :
- return "\xEC\x83\xA4";
- break;
- case 0x8A :
- return "\xEC\x8C\xB0";
- break;
- case 0x8B :
- return "\xEC\x95\xBC";
- break;
- case 0x8C :
- return "\xEC\x9F\x88";
- break;
- case 0x8D :
- return "\xEC\xA8\x94";
- break;
- case 0x8E :
- return "\xEC\xB1\xA0";
- break;
- case 0x8F :
- return "\xEC\xBA\xAC";
- break;
- case 0x90 :
- return "\xED\x83\xB8";
- break;
- case 0x91 :
- return "\xED\x8D\x84";
- break;
- case 0x92 :
- return "\xED\x96\x90";
- break;
- }
- }
- }
- break;
- case 0xA4 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB1\x94";
- break;
- case 0x81 :
- return "\xEA\xBA\xA0";
- break;
- case 0x82 :
- return "\xEB\x83\xAC";
- break;
- case 0x83 :
- return "\xEB\x8C\xB8";
- break;
- case 0x84 :
- return "\xEB\x96\x84";
- break;
- case 0x85 :
- return "\xEB\x9F\x90";
- break;
- case 0x86 :
- return "\xEB\xA8\x9C";
- break;
- case 0x87 :
- return "\xEB\xB1\xA8";
- break;
- case 0x88 :
- return "\xEB\xBA\xB4";
- break;
- case 0x89 :
- return "\xEC\x84\x80";
- break;
- case 0x8A :
- return "\xEC\x8D\x8C";
- break;
- case 0x8B :
- return "\xEC\x96\x98";
- break;
- case 0x8C :
- return "\xEC\x9F\xA4";
- break;
- case 0x8D :
- return "\xEC\xA8\xB0";
- break;
- case 0x8E :
- return "\xEC\xB1\xBC";
- break;
- case 0x8F :
- return "\xEC\xBB\x88";
- break;
- case 0x90 :
- return "\xED\x84\x94";
- break;
- case 0x91 :
- return "\xED\x8D\xA0";
- break;
- case 0x92 :
- return "\xED\x96\xAC";
- break;
- }
- }
- }
- break;
- case 0xA5 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB1\xB0";
- break;
- case 0x81 :
- return "\xEA\xBA\xBC";
- break;
- case 0x82 :
- return "\xEB\x84\x88";
- break;
- case 0x83 :
- return "\xEB\x8D\x94";
- break;
- case 0x84 :
- return "\xEB\x96\xA0";
- break;
- case 0x85 :
- return "\xEB\x9F\xAC";
- break;
- case 0x86 :
- return "\xEB\xA8\xB8";
- break;
- case 0x87 :
- return "\xEB\xB2\x84";
- break;
- case 0x88 :
- return "\xEB\xBB\x90";
- break;
- case 0x89 :
- return "\xEC\x84\x9C";
- break;
- case 0x8A :
- return "\xEC\x8D\xA8";
- break;
- case 0x8B :
- return "\xEC\x96\xB4";
- break;
- case 0x8C :
- return "\xEC\xA0\x80";
- break;
- case 0x8D :
- return "\xEC\xA9\x8C";
- break;
- case 0x8E :
- return "\xEC\xB2\x98";
- break;
- case 0x8F :
- return "\xEC\xBB\xA4";
- break;
- case 0x90 :
- return "\xED\x84\xB0";
- break;
- case 0x91 :
- return "\xED\x8D\xBC";
- break;
- case 0x92 :
- return "\xED\x97\x88";
- break;
- }
- }
- }
- break;
- case 0xA6 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB2\x8C";
- break;
- case 0x81 :
- return "\xEA\xBB\x98";
- break;
- case 0x82 :
- return "\xEB\x84\xA4";
- break;
- case 0x83 :
- return "\xEB\x8D\xB0";
- break;
- case 0x84 :
- return "\xEB\x96\xBC";
- break;
- case 0x85 :
- return "\xEB\xA0\x88";
- break;
- case 0x86 :
- return "\xEB\xA9\x94";
- break;
- case 0x87 :
- return "\xEB\xB2\xA0";
- break;
- case 0x88 :
- return "\xEB\xBB\xAC";
- break;
- case 0x89 :
- return "\xEC\x84\xB8";
- break;
- case 0x8A :
- return "\xEC\x8E\x84";
- break;
- case 0x8B :
- return "\xEC\x97\x90";
- break;
- case 0x8C :
- return "\xEC\xA0\x9C";
- break;
- case 0x8D :
- return "\xEC\xA9\xA8";
- break;
- case 0x8E :
- return "\xEC\xB2\xB4";
- break;
- case 0x8F :
- return "\xEC\xBC\x80";
- break;
- case 0x90 :
- return "\xED\x85\x8C";
- break;
- case 0x91 :
- return "\xED\x8E\x98";
- break;
- case 0x92 :
- return "\xED\x97\xA4";
- break;
- }
- }
- }
- break;
- case 0xA7 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB2\xA8";
- break;
- case 0x81 :
- return "\xEA\xBB\xB4";
- break;
- case 0x82 :
- return "\xEB\x85\x80";
- break;
- case 0x83 :
- return "\xEB\x8E\x8C";
- break;
- case 0x84 :
- return "\xEB\x97\x98";
- break;
- case 0x85 :
- return "\xEB\xA0\xA4";
- break;
- case 0x86 :
- return "\xEB\xA9\xB0";
- break;
- case 0x87 :
- return "\xEB\xB2\xBC";
- break;
- case 0x88 :
- return "\xEB\xBC\x88";
- break;
- case 0x89 :
- return "\xEC\x85\x94";
- break;
- case 0x8A :
- return "\xEC\x8E\xA0";
- break;
- case 0x8B :
- return "\xEC\x97\xAC";
- break;
- case 0x8C :
- return "\xEC\xA0\xB8";
- break;
- case 0x8D :
- return "\xEC\xAA\x84";
- break;
- case 0x8E :
- return "\xEC\xB3\x90";
- break;
- case 0x8F :
- return "\xEC\xBC\x9C";
- break;
- case 0x90 :
- return "\xED\x85\xA8";
- break;
- case 0x91 :
- return "\xED\x8E\xB4";
- break;
- case 0x92 :
- return "\xED\x98\x80";
- break;
- }
- }
- }
- break;
- case 0xA8 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB3\x84";
- break;
- case 0x81 :
- return "\xEA\xBC\x90";
- break;
- case 0x82 :
- return "\xEB\x85\x9C";
- break;
- case 0x83 :
- return "\xEB\x8E\xA8";
- break;
- case 0x84 :
- return "\xEB\x97\xB4";
- break;
- case 0x85 :
- return "\xEB\xA1\x80";
- break;
- case 0x86 :
- return "\xEB\xAA\x8C";
- break;
- case 0x87 :
- return "\xEB\xB3\x98";
- break;
- case 0x88 :
- return "\xEB\xBC\xA4";
- break;
- case 0x89 :
- return "\xEC\x85\xB0";
- break;
- case 0x8A :
- return "\xEC\x8E\xBC";
- break;
- case 0x8B :
- return "\xEC\x98\x88";
- break;
- case 0x8C :
- return "\xEC\xA1\x94";
- break;
- case 0x8D :
- return "\xEC\xAA\xA0";
- break;
- case 0x8E :
- return "\xEC\xB3\xAC";
- break;
- case 0x8F :
- return "\xEC\xBC\xB8";
- break;
- case 0x90 :
- return "\xED\x86\x84";
- break;
- case 0x91 :
- return "\xED\x8F\x90";
- break;
- case 0x92 :
- return "\xED\x98\x9C";
- break;
- }
- }
- }
- break;
- case 0xA9 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB3\xA0";
- break;
- case 0x81 :
- return "\xEA\xBC\xAC";
- break;
- case 0x82 :
- return "\xEB\x85\xB8";
- break;
- case 0x83 :
- return "\xEB\x8F\x84";
- break;
- case 0x84 :
- return "\xEB\x98\x90";
- break;
- case 0x85 :
- return "\xEB\xA1\x9C";
- break;
- case 0x86 :
- return "\xEB\xAA\xA8";
- break;
- case 0x87 :
- return "\xEB\xB3\xB4";
- break;
- case 0x88 :
- return "\xEB\xBD\x80";
- break;
- case 0x89 :
- return "\xEC\x86\x8C";
- break;
- case 0x8A :
- return "\xEC\x8F\x98";
- break;
- case 0x8B :
- return "\xEC\x98\xA4";
- break;
- case 0x8C :
- return "\xEC\xA1\xB0";
- break;
- case 0x8D :
- return "\xEC\xAA\xBC";
- break;
- case 0x8E :
- return "\xEC\xB4\x88";
- break;
- case 0x8F :
- return "\xEC\xBD\x94";
- break;
- case 0x90 :
- return "\xED\x86\xA0";
- break;
- case 0x91 :
- return "\xED\x8F\xAC";
- break;
- case 0x92 :
- return "\xED\x98\xB8";
- break;
- }
- }
- }
- break;
- case 0xAA :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB3\xBC";
- break;
- case 0x81 :
- return "\xEA\xBD\x88";
- break;
- case 0x82 :
- return "\xEB\x86\x94";
- break;
- case 0x83 :
- return "\xEB\x8F\xA0";
- break;
- case 0x84 :
- return "\xEB\x98\xAC";
- break;
- case 0x85 :
- return "\xEB\xA1\xB8";
- break;
- case 0x86 :
- return "\xEB\xAB\x84";
- break;
- case 0x87 :
- return "\xEB\xB4\x90";
- break;
- case 0x88 :
- return "\xEB\xBD\x9C";
- break;
- case 0x89 :
- return "\xEC\x86\xA8";
- break;
- case 0x8A :
- return "\xEC\x8F\xB4";
- break;
- case 0x8B :
- return "\xEC\x99\x80";
- break;
- case 0x8C :
- return "\xEC\xA2\x8C";
- break;
- case 0x8D :
- return "\xEC\xAB\x98";
- break;
- case 0x8E :
- return "\xEC\xB4\xA4";
- break;
- case 0x8F :
- return "\xEC\xBD\xB0";
- break;
- case 0x90 :
- return "\xED\x86\xBC";
- break;
- case 0x91 :
- return "\xED\x90\x88";
- break;
- case 0x92 :
- return "\xED\x99\x94";
- break;
- }
- }
- }
- break;
- case 0xAB :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB4\x98";
- break;
- case 0x81 :
- return "\xEA\xBD\xA4";
- break;
- case 0x82 :
- return "\xEB\x86\xB0";
- break;
- case 0x83 :
- return "\xEB\x8F\xBC";
- break;
- case 0x84 :
- return "\xEB\x99\x88";
- break;
- case 0x85 :
- return "\xEB\xA2\x94";
- break;
- case 0x86 :
- return "\xEB\xAB\xA0";
- break;
- case 0x87 :
- return "\xEB\xB4\xAC";
- break;
- case 0x88 :
- return "\xEB\xBD\xB8";
- break;
- case 0x89 :
- return "\xEC\x87\x84";
- break;
- case 0x8A :
- return "\xEC\x90\x90";
- break;
- case 0x8B :
- return "\xEC\x99\x9C";
- break;
- case 0x8C :
- return "\xEC\xA2\xA8";
- break;
- case 0x8D :
- return "\xEC\xAB\xB4";
- break;
- case 0x8E :
- return "\xEC\xB5\x80";
- break;
- case 0x8F :
- return "\xEC\xBE\x8C";
- break;
- case 0x90 :
- return "\xED\x87\x98";
- break;
- case 0x91 :
- return "\xED\x90\xA4";
- break;
- case 0x92 :
- return "\xED\x99\xB0";
- break;
- }
- }
- }
- break;
- case 0xAC :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB4\xB4";
- break;
- case 0x81 :
- return "\xEA\xBE\x80";
- break;
- case 0x82 :
- return "\xEB\x87\x8C";
- break;
- case 0x83 :
- return "\xEB\x90\x98";
- break;
- case 0x84 :
- return "\xEB\x99\xA4";
- break;
- case 0x85 :
- return "\xEB\xA2\xB0";
- break;
- case 0x86 :
- return "\xEB\xAB\xBC";
- break;
- case 0x87 :
- return "\xEB\xB5\x88";
- break;
- case 0x88 :
- return "\xEB\xBE\x94";
- break;
- case 0x89 :
- return "\xEC\x87\xA0";
- break;
- case 0x8A :
- return "\xEC\x90\xAC";
- break;
- case 0x8B :
- return "\xEC\x99\xB8";
- break;
- case 0x8C :
- return "\xEC\xA3\x84";
- break;
- case 0x8D :
- return "\xEC\xAC\x90";
- break;
- case 0x8E :
- return "\xEC\xB5\x9C";
- break;
- case 0x8F :
- return "\xEC\xBE\xA8";
- break;
- case 0x90 :
- return "\xED\x87\xB4";
- break;
- case 0x91 :
- return "\xED\x91\x80";
- break;
- case 0x92 :
- return "\xED\x9A\x8C";
- break;
- }
- }
- }
- break;
- case 0xAD :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB5\x90";
- break;
- case 0x81 :
- return "\xEA\xBE\x9C";
- break;
- case 0x82 :
- return "\xEB\x87\xA8";
- break;
- case 0x83 :
- return "\xEB\x90\xB4";
- break;
- case 0x84 :
- return "\xEB\x9A\x80";
- break;
- case 0x85 :
- return "\xEB\xA3\x8C";
- break;
- case 0x86 :
- return "\xEB\xAC\x98";
- break;
- case 0x87 :
- return "\xEB\xB5\xA4";
- break;
- case 0x88 :
- return "\xEB\xBE\xB0";
- break;
- case 0x89 :
- return "\xEC\x87\xBC";
- break;
- case 0x8A :
- return "\xEC\x91\x88";
- break;
- case 0x8B :
- return "\xEC\x9A\x94";
- break;
- case 0x8C :
- return "\xEC\xA3\xA0";
- break;
- case 0x8D :
- return "\xEC\xAC\xAC";
- break;
- case 0x8E :
- return "\xEC\xB5\xB8";
- break;
- case 0x8F :
- return "\xEC\xBF\x84";
- break;
- case 0x90 :
- return "\xED\x88\x90";
- break;
- case 0x91 :
- return "\xED\x91\x9C";
- break;
- case 0x92 :
- return "\xED\x9A\xA8";
- break;
- }
- }
- }
- break;
- case 0xAE :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB5\xAC";
- break;
- case 0x81 :
- return "\xEA\xBE\xB8";
- break;
- case 0x82 :
- return "\xEB\x88\x84";
- break;
- case 0x83 :
- return "\xEB\x91\x90";
- break;
- case 0x84 :
- return "\xEB\x9A\x9C";
- break;
- case 0x85 :
- return "\xEB\xA3\xA8";
- break;
- case 0x86 :
- return "\xEB\xAC\xB4";
- break;
- case 0x87 :
- return "\xEB\xB6\x80";
- break;
- case 0x88 :
- return "\xEB\xBF\x8C";
- break;
- case 0x89 :
- return "\xEC\x88\x98";
- break;
- case 0x8A :
- return "\xEC\x91\xA4";
- break;
- case 0x8B :
- return "\xEC\x9A\xB0";
- break;
- case 0x8C :
- return "\xEC\xA3\xBC";
- break;
- case 0x8D :
- return "\xEC\xAD\x88";
- break;
- case 0x8E :
- return "\xEC\xB6\x94";
- break;
- case 0x8F :
- return "\xEC\xBF\xA0";
- break;
- case 0x90 :
- return "\xED\x88\xAC";
- break;
- case 0x91 :
- return "\xED\x91\xB8";
- break;
- case 0x92 :
- return "\xED\x9B\x84";
- break;
- }
- }
- }
- break;
- case 0xAF :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB6\x88";
- break;
- case 0x81 :
- return "\xEA\xBF\x94";
- break;
- case 0x82 :
- return "\xEB\x88\xA0";
- break;
- case 0x83 :
- return "\xEB\x91\xAC";
- break;
- case 0x84 :
- return "\xEB\x9A\xB8";
- break;
- case 0x85 :
- return "\xEB\xA4\x84";
- break;
- case 0x86 :
- return "\xEB\xAD\x90";
- break;
- case 0x87 :
- return "\xEB\xB6\x9C";
- break;
- case 0x88 :
- return "\xEB\xBF\xA8";
- break;
- case 0x89 :
- return "\xEC\x88\xB4";
- break;
- case 0x8A :
- return "\xEC\x92\x80";
- break;
- case 0x8B :
- return "\xEC\x9B\x8C";
- break;
- case 0x8C :
- return "\xEC\xA4\x98";
- break;
- case 0x8D :
- return "\xEC\xAD\xA4";
- break;
- case 0x8E :
- return "\xEC\xB6\xB0";
- break;
- case 0x8F :
- return "\xEC\xBF\xBC";
- break;
- case 0x90 :
- return "\xED\x89\x88";
- break;
- case 0x91 :
- return "\xED\x92\x94";
- break;
- case 0x92 :
- return "\xED\x9B\xA0";
- break;
- }
- }
- }
- break;
- case 0xB0 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB6\xA4";
- break;
- case 0x81 :
- return "\xEA\xBF\xB0";
- break;
- case 0x82 :
- return "\xEB\x88\xBC";
- break;
- case 0x83 :
- return "\xEB\x92\x88";
- break;
- case 0x84 :
- return "\xEB\x9B\x94";
- break;
- case 0x85 :
- return "\xEB\xA4\xA0";
- break;
- case 0x86 :
- return "\xEB\xAD\xAC";
- break;
- case 0x87 :
- return "\xEB\xB6\xB8";
- break;
- case 0x88 :
- return "\xEC\x80\x84";
- break;
- case 0x89 :
- return "\xEC\x89\x90";
- break;
- case 0x8A :
- return "\xEC\x92\x9C";
- break;
- case 0x8B :
- return "\xEC\x9B\xA8";
- break;
- case 0x8C :
- return "\xEC\xA4\xB4";
- break;
- case 0x8D :
- return "\xEC\xAE\x80";
- break;
- case 0x8E :
- return "\xEC\xB7\x8C";
- break;
- case 0x8F :
- return "\xED\x80\x98";
- break;
- case 0x90 :
- return "\xED\x89\xA4";
- break;
- case 0x91 :
- return "\xED\x92\xB0";
- break;
- case 0x92 :
- return "\xED\x9B\xBC";
- break;
- }
- }
- }
- break;
- case 0xB1 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x80";
- break;
- case 0x81 :
- return "\xEB\x80\x8C";
- break;
- case 0x82 :
- return "\xEB\x89\x98";
- break;
- case 0x83 :
- return "\xEB\x92\xA4";
- break;
- case 0x84 :
- return "\xEB\x9B\xB0";
- break;
- case 0x85 :
- return "\xEB\xA4\xBC";
- break;
- case 0x86 :
- return "\xEB\xAE\x88";
- break;
- case 0x87 :
- return "\xEB\xB7\x94";
- break;
- case 0x88 :
- return "\xEC\x80\xA0";
- break;
- case 0x89 :
- return "\xEC\x89\xAC";
- break;
- case 0x8A :
- return "\xEC\x92\xB8";
- break;
- case 0x8B :
- return "\xEC\x9C\x84";
- break;
- case 0x8C :
- return "\xEC\xA5\x90";
- break;
- case 0x8D :
- return "\xEC\xAE\x9C";
- break;
- case 0x8E :
- return "\xEC\xB7\xA8";
- break;
- case 0x8F :
- return "\xED\x80\xB4";
- break;
- case 0x90 :
- return "\xED\x8A\x80";
- break;
- case 0x91 :
- return "\xED\x93\x8C";
- break;
- case 0x92 :
- return "\xED\x9C\x98";
- break;
- }
- }
- }
- break;
- case 0xB2 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x9C";
- break;
- case 0x81 :
- return "\xEB\x80\xA8";
- break;
- case 0x82 :
- return "\xEB\x89\xB4";
- break;
- case 0x83 :
- return "\xEB\x93\x80";
- break;
- case 0x84 :
- return "\xEB\x9C\x8C";
- break;
- case 0x85 :
- return "\xEB\xA5\x98";
- break;
- case 0x86 :
- return "\xEB\xAE\xA4";
- break;
- case 0x87 :
- return "\xEB\xB7\xB0";
- break;
- case 0x88 :
- return "\xEC\x80\xBC";
- break;
- case 0x89 :
- return "\xEC\x8A\x88";
- break;
- case 0x8A :
- return "\xEC\x93\x94";
- break;
- case 0x8B :
- return "\xEC\x9C\xA0";
- break;
- case 0x8C :
- return "\xEC\xA5\xAC";
- break;
- case 0x8D :
- return "\xEC\xAE\xB8";
- break;
- case 0x8E :
- return "\xEC\xB8\x84";
- break;
- case 0x8F :
- return "\xED\x81\x90";
- break;
- case 0x90 :
- return "\xED\x8A\x9C";
- break;
- case 0x91 :
- return "\xED\x93\xA8";
- break;
- case 0x92 :
- return "\xED\x9C\xB4";
- break;
- }
- }
- }
- break;
- case 0xB3 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\xB8";
- break;
- case 0x81 :
- return "\xEB\x81\x84";
- break;
- case 0x82 :
- return "\xEB\x8A\x90";
- break;
- case 0x83 :
- return "\xEB\x93\x9C";
- break;
- case 0x84 :
- return "\xEB\x9C\xA8";
- break;
- case 0x85 :
- return "\xEB\xA5\xB4";
- break;
- case 0x86 :
- return "\xEB\xAF\x80";
- break;
- case 0x87 :
- return "\xEB\xB8\x8C";
- break;
- case 0x88 :
- return "\xEC\x81\x98";
- break;
- case 0x89 :
- return "\xEC\x8A\xA4";
- break;
- case 0x8A :
- return "\xEC\x93\xB0";
- break;
- case 0x8B :
- return "\xEC\x9C\xBC";
- break;
- case 0x8C :
- return "\xEC\xA6\x88";
- break;
- case 0x8D :
- return "\xEC\xAF\x94";
- break;
- case 0x8E :
- return "\xEC\xB8\xA0";
- break;
- case 0x8F :
- return "\xED\x81\xAC";
- break;
- case 0x90 :
- return "\xED\x8A\xB8";
- break;
- case 0x91 :
- return "\xED\x94\x84";
- break;
- case 0x92 :
- return "\xED\x9D\x90";
- break;
- }
- }
- }
- break;
- case 0xB4 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB8\x94";
- break;
- case 0x81 :
- return "\xEB\x81\xA0";
- break;
- case 0x82 :
- return "\xEB\x8A\xAC";
- break;
- case 0x83 :
- return "\xEB\x93\xB8";
- break;
- case 0x84 :
- return "\xEB\x9D\x84";
- break;
- case 0x85 :
- return "\xEB\xA6\x90";
- break;
- case 0x86 :
- return "\xEB\xAF\x9C";
- break;
- case 0x87 :
- return "\xEB\xB8\xA8";
- break;
- case 0x88 :
- return "\xEC\x81\xB4";
- break;
- case 0x89 :
- return "\xEC\x8B\x80";
- break;
- case 0x8A :
- return "\xEC\x94\x8C";
- break;
- case 0x8B :
- return "\xEC\x9D\x98";
- break;
- case 0x8C :
- return "\xEC\xA6\xA4";
- break;
- case 0x8D :
- return "\xEC\xAF\xB0";
- break;
- case 0x8E :
- return "\xEC\xB8\xBC";
- break;
- case 0x8F :
- return "\xED\x82\x88";
- break;
- case 0x90 :
- return "\xED\x8B\x94";
- break;
- case 0x91 :
- return "\xED\x94\xA0";
- break;
- case 0x92 :
- return "\xED\x9D\xAC";
- break;
- }
- }
- }
- break;
- case 0xB5 :
- if (prefix[0] == 0xE1) {
- if (prefix[1] == 0x84) {
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB8\xB0";
- break;
- case 0x81 :
- return "\xEB\x81\xBC";
- break;
- case 0x82 :
- return "\xEB\x8B\x88";
- break;
- case 0x83 :
- return "\xEB\x94\x94";
- break;
- case 0x84 :
- return "\xEB\x9D\xA0";
- break;
- case 0x85 :
- return "\xEB\xA6\xAC";
- break;
- case 0x86 :
- return "\xEB\xAF\xB8";
- break;
- case 0x87 :
- return "\xEB\xB9\x84";
- break;
- case 0x88 :
- return "\xEC\x82\x90";
- break;
- case 0x89 :
- return "\xEC\x8B\x9C";
- break;
- case 0x8A :
- return "\xEC\x94\xA8";
- break;
- case 0x8B :
- return "\xEC\x9D\xB4";
- break;
- case 0x8C :
- return "\xEC\xA7\x80";
- break;
- case 0x8D :
- return "\xEC\xB0\x8C";
- break;
- case 0x8E :
- return "\xEC\xB9\x98";
- break;
- case 0x8F :
- return "\xED\x82\xA4";
- break;
- case 0x90 :
- return "\xED\x8B\xB0";
- break;
- case 0x91 :
- return "\xED\x94\xBC";
- break;
- case 0x92 :
- return "\xED\x9E\x88";
- break;
- }
- }
- }
- break;
- }
- break;
- case 0x86 :
- switch (suffix[2]) {
- case 0xA8 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x81";
- break;
- case 0x9C :
- return "\xEA\xB0\x9D";
- break;
- case 0xB8 :
- return "\xEA\xB0\xB9";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x95";
- break;
- case 0xB0 :
- return "\xEA\xB1\xB1";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x8D";
- break;
- case 0xA8 :
- return "\xEA\xB2\xA9";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x85";
- break;
- case 0xA0 :
- return "\xEA\xB3\xA1";
- break;
- case 0xBC :
- return "\xEA\xB3\xBD";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\x99";
- break;
- case 0xB4 :
- return "\xEA\xB4\xB5";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x91";
- break;
- case 0xAC :
- return "\xEA\xB5\xAD";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x89";
- break;
- case 0xA4 :
- return "\xEA\xB6\xA5";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x81";
- break;
- case 0x9C :
- return "\xEA\xB7\x9D";
- break;
- case 0xB8 :
- return "\xEA\xB7\xB9";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x95";
- break;
- case 0xB0 :
- return "\xEA\xB8\xB1";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x8D";
- break;
- case 0xA8 :
- return "\xEA\xB9\xA9";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x85";
- break;
- case 0xA0 :
- return "\xEA\xBA\xA1";
- break;
- case 0xBC :
- return "\xEA\xBA\xBD";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\x99";
- break;
- case 0xB4 :
- return "\xEA\xBB\xB5";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x91";
- break;
- case 0xAC :
- return "\xEA\xBC\xAD";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x89";
- break;
- case 0xA4 :
- return "\xEA\xBD\xA5";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x81";
- break;
- case 0x9C :
- return "\xEA\xBE\x9D";
- break;
- case 0xB8 :
- return "\xEA\xBE\xB9";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x95";
- break;
- case 0xB0 :
- return "\xEA\xBF\xB1";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x8D";
- break;
- case 0xA8 :
- return "\xEB\x80\xA9";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x85";
- break;
- case 0xA0 :
- return "\xEB\x81\xA1";
- break;
- case 0xBC :
- return "\xEB\x81\xBD";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\x99";
- break;
- case 0xB4 :
- return "\xEB\x82\xB5";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x91";
- break;
- case 0xAC :
- return "\xEB\x83\xAD";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x89";
- break;
- case 0xA4 :
- return "\xEB\x84\xA5";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x81";
- break;
- case 0x9C :
- return "\xEB\x85\x9D";
- break;
- case 0xB8 :
- return "\xEB\x85\xB9";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x95";
- break;
- case 0xB0 :
- return "\xEB\x86\xB1";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x8D";
- break;
- case 0xA8 :
- return "\xEB\x87\xA9";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x85";
- break;
- case 0xA0 :
- return "\xEB\x88\xA1";
- break;
- case 0xBC :
- return "\xEB\x88\xBD";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\x99";
- break;
- case 0xB4 :
- return "\xEB\x89\xB5";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x91";
- break;
- case 0xAC :
- return "\xEB\x8A\xAD";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x89";
- break;
- case 0xA4 :
- return "\xEB\x8B\xA5";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x81";
- break;
- case 0x9C :
- return "\xEB\x8C\x9D";
- break;
- case 0xB8 :
- return "\xEB\x8C\xB9";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x95";
- break;
- case 0xB0 :
- return "\xEB\x8D\xB1";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x8D";
- break;
- case 0xA8 :
- return "\xEB\x8E\xA9";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x85";
- break;
- case 0xA0 :
- return "\xEB\x8F\xA1";
- break;
- case 0xBC :
- return "\xEB\x8F\xBD";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\x99";
- break;
- case 0xB4 :
- return "\xEB\x90\xB5";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x91";
- break;
- case 0xAC :
- return "\xEB\x91\xAD";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x89";
- break;
- case 0xA4 :
- return "\xEB\x92\xA5";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x81";
- break;
- case 0x9C :
- return "\xEB\x93\x9D";
- break;
- case 0xB8 :
- return "\xEB\x93\xB9";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x95";
- break;
- case 0xB0 :
- return "\xEB\x94\xB1";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x8D";
- break;
- case 0xA8 :
- return "\xEB\x95\xA9";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x85";
- break;
- case 0xA0 :
- return "\xEB\x96\xA1";
- break;
- case 0xBC :
- return "\xEB\x96\xBD";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\x99";
- break;
- case 0xB4 :
- return "\xEB\x97\xB5";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x91";
- break;
- case 0xAC :
- return "\xEB\x98\xAD";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x89";
- break;
- case 0xA4 :
- return "\xEB\x99\xA5";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x81";
- break;
- case 0x9C :
- return "\xEB\x9A\x9D";
- break;
- case 0xB8 :
- return "\xEB\x9A\xB9";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x95";
- break;
- case 0xB0 :
- return "\xEB\x9B\xB1";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x8D";
- break;
- case 0xA8 :
- return "\xEB\x9C\xA9";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x85";
- break;
- case 0xA0 :
- return "\xEB\x9D\xA1";
- break;
- case 0xBC :
- return "\xEB\x9D\xBD";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\x99";
- break;
- case 0xB4 :
- return "\xEB\x9E\xB5";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x91";
- break;
- case 0xAC :
- return "\xEB\x9F\xAD";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x89";
- break;
- case 0xA4 :
- return "\xEB\xA0\xA5";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x81";
- break;
- case 0x9C :
- return "\xEB\xA1\x9D";
- break;
- case 0xB8 :
- return "\xEB\xA1\xB9";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x95";
- break;
- case 0xB0 :
- return "\xEB\xA2\xB1";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x8D";
- break;
- case 0xA8 :
- return "\xEB\xA3\xA9";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x85";
- break;
- case 0xA0 :
- return "\xEB\xA4\xA1";
- break;
- case 0xBC :
- return "\xEB\xA4\xBD";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\x99";
- break;
- case 0xB4 :
- return "\xEB\xA5\xB5";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x91";
- break;
- case 0xAC :
- return "\xEB\xA6\xAD";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x89";
- break;
- case 0xA4 :
- return "\xEB\xA7\xA5";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x81";
- break;
- case 0x9C :
- return "\xEB\xA8\x9D";
- break;
- case 0xB8 :
- return "\xEB\xA8\xB9";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x95";
- break;
- case 0xB0 :
- return "\xEB\xA9\xB1";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x8D";
- break;
- case 0xA8 :
- return "\xEB\xAA\xA9";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x85";
- break;
- case 0xA0 :
- return "\xEB\xAB\xA1";
- break;
- case 0xBC :
- return "\xEB\xAB\xBD";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\x99";
- break;
- case 0xB4 :
- return "\xEB\xAC\xB5";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x91";
- break;
- case 0xAC :
- return "\xEB\xAD\xAD";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x89";
- break;
- case 0xA4 :
- return "\xEB\xAE\xA5";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x81";
- break;
- case 0x9C :
- return "\xEB\xAF\x9D";
- break;
- case 0xB8 :
- return "\xEB\xAF\xB9";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x95";
- break;
- case 0xB0 :
- return "\xEB\xB0\xB1";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x8D";
- break;
- case 0xA8 :
- return "\xEB\xB1\xA9";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x85";
- break;
- case 0xA0 :
- return "\xEB\xB2\xA1";
- break;
- case 0xBC :
- return "\xEB\xB2\xBD";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\x99";
- break;
- case 0xB4 :
- return "\xEB\xB3\xB5";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x91";
- break;
- case 0xAC :
- return "\xEB\xB4\xAD";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x89";
- break;
- case 0xA4 :
- return "\xEB\xB5\xA5";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x81";
- break;
- case 0x9C :
- return "\xEB\xB6\x9D";
- break;
- case 0xB8 :
- return "\xEB\xB6\xB9";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x95";
- break;
- case 0xB0 :
- return "\xEB\xB7\xB1";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x8D";
- break;
- case 0xA8 :
- return "\xEB\xB8\xA9";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x85";
- break;
- case 0xA0 :
- return "\xEB\xB9\xA1";
- break;
- case 0xBC :
- return "\xEB\xB9\xBD";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\x99";
- break;
- case 0xB4 :
- return "\xEB\xBA\xB5";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x91";
- break;
- case 0xAC :
- return "\xEB\xBB\xAD";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x89";
- break;
- case 0xA4 :
- return "\xEB\xBC\xA5";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x81";
- break;
- case 0x9C :
- return "\xEB\xBD\x9D";
- break;
- case 0xB8 :
- return "\xEB\xBD\xB9";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x95";
- break;
- case 0xB0 :
- return "\xEB\xBE\xB1";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x8D";
- break;
- case 0xA8 :
- return "\xEB\xBF\xA9";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x85";
- break;
- case 0xA0 :
- return "\xEC\x80\xA1";
- break;
- case 0xBC :
- return "\xEC\x80\xBD";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\x99";
- break;
- case 0xB4 :
- return "\xEC\x81\xB5";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x91";
- break;
- case 0xAC :
- return "\xEC\x82\xAD";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x89";
- break;
- case 0xA4 :
- return "\xEC\x83\xA5";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x81";
- break;
- case 0x9C :
- return "\xEC\x84\x9D";
- break;
- case 0xB8 :
- return "\xEC\x84\xB9";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x95";
- break;
- case 0xB0 :
- return "\xEC\x85\xB1";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x8D";
- break;
- case 0xA8 :
- return "\xEC\x86\xA9";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x85";
- break;
- case 0xA0 :
- return "\xEC\x87\xA1";
- break;
- case 0xBC :
- return "\xEC\x87\xBD";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\x99";
- break;
- case 0xB4 :
- return "\xEC\x88\xB5";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x91";
- break;
- case 0xAC :
- return "\xEC\x89\xAD";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x89";
- break;
- case 0xA4 :
- return "\xEC\x8A\xA5";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x81";
- break;
- case 0x9C :
- return "\xEC\x8B\x9D";
- break;
- case 0xB8 :
- return "\xEC\x8B\xB9";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x95";
- break;
- case 0xB0 :
- return "\xEC\x8C\xB1";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x8D";
- break;
- case 0xA8 :
- return "\xEC\x8D\xA9";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x85";
- break;
- case 0xA0 :
- return "\xEC\x8E\xA1";
- break;
- case 0xBC :
- return "\xEC\x8E\xBD";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\x99";
- break;
- case 0xB4 :
- return "\xEC\x8F\xB5";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x91";
- break;
- case 0xAC :
- return "\xEC\x90\xAD";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x89";
- break;
- case 0xA4 :
- return "\xEC\x91\xA5";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x81";
- break;
- case 0x9C :
- return "\xEC\x92\x9D";
- break;
- case 0xB8 :
- return "\xEC\x92\xB9";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x95";
- break;
- case 0xB0 :
- return "\xEC\x93\xB1";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x8D";
- break;
- case 0xA8 :
- return "\xEC\x94\xA9";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x85";
- break;
- case 0xA0 :
- return "\xEC\x95\xA1";
- break;
- case 0xBC :
- return "\xEC\x95\xBD";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\x99";
- break;
- case 0xB4 :
- return "\xEC\x96\xB5";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x91";
- break;
- case 0xAC :
- return "\xEC\x97\xAD";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x89";
- break;
- case 0xA4 :
- return "\xEC\x98\xA5";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x81";
- break;
- case 0x9C :
- return "\xEC\x99\x9D";
- break;
- case 0xB8 :
- return "\xEC\x99\xB9";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x95";
- break;
- case 0xB0 :
- return "\xEC\x9A\xB1";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x8D";
- break;
- case 0xA8 :
- return "\xEC\x9B\xA9";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x85";
- break;
- case 0xA0 :
- return "\xEC\x9C\xA1";
- break;
- case 0xBC :
- return "\xEC\x9C\xBD";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\x99";
- break;
- case 0xB4 :
- return "\xEC\x9D\xB5";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x91";
- break;
- case 0xAC :
- return "\xEC\x9E\xAD";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x89";
- break;
- case 0xA4 :
- return "\xEC\x9F\xA5";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x81";
- break;
- case 0x9C :
- return "\xEC\xA0\x9D";
- break;
- case 0xB8 :
- return "\xEC\xA0\xB9";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x95";
- break;
- case 0xB0 :
- return "\xEC\xA1\xB1";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x8D";
- break;
- case 0xA8 :
- return "\xEC\xA2\xA9";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x85";
- break;
- case 0xA0 :
- return "\xEC\xA3\xA1";
- break;
- case 0xBC :
- return "\xEC\xA3\xBD";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\x99";
- break;
- case 0xB4 :
- return "\xEC\xA4\xB5";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x91";
- break;
- case 0xAC :
- return "\xEC\xA5\xAD";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x89";
- break;
- case 0xA4 :
- return "\xEC\xA6\xA5";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x81";
- break;
- case 0x9C :
- return "\xEC\xA7\x9D";
- break;
- case 0xB8 :
- return "\xEC\xA7\xB9";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x95";
- break;
- case 0xB0 :
- return "\xEC\xA8\xB1";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x8D";
- break;
- case 0xA8 :
- return "\xEC\xA9\xA9";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x85";
- break;
- case 0xA0 :
- return "\xEC\xAA\xA1";
- break;
- case 0xBC :
- return "\xEC\xAA\xBD";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\x99";
- break;
- case 0xB4 :
- return "\xEC\xAB\xB5";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x91";
- break;
- case 0xAC :
- return "\xEC\xAC\xAD";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x89";
- break;
- case 0xA4 :
- return "\xEC\xAD\xA5";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x81";
- break;
- case 0x9C :
- return "\xEC\xAE\x9D";
- break;
- case 0xB8 :
- return "\xEC\xAE\xB9";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x95";
- break;
- case 0xB0 :
- return "\xEC\xAF\xB1";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x8D";
- break;
- case 0xA8 :
- return "\xEC\xB0\xA9";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x85";
- break;
- case 0xA0 :
- return "\xEC\xB1\xA1";
- break;
- case 0xBC :
- return "\xEC\xB1\xBD";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\x99";
- break;
- case 0xB4 :
- return "\xEC\xB2\xB5";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x91";
- break;
- case 0xAC :
- return "\xEC\xB3\xAD";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x89";
- break;
- case 0xA4 :
- return "\xEC\xB4\xA5";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x81";
- break;
- case 0x9C :
- return "\xEC\xB5\x9D";
- break;
- case 0xB8 :
- return "\xEC\xB5\xB9";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x95";
- break;
- case 0xB0 :
- return "\xEC\xB6\xB1";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x8D";
- break;
- case 0xA8 :
- return "\xEC\xB7\xA9";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x85";
- break;
- case 0xA0 :
- return "\xEC\xB8\xA1";
- break;
- case 0xBC :
- return "\xEC\xB8\xBD";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\x99";
- break;
- case 0xB4 :
- return "\xEC\xB9\xB5";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x91";
- break;
- case 0xAC :
- return "\xEC\xBA\xAD";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x89";
- break;
- case 0xA4 :
- return "\xEC\xBB\xA5";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x81";
- break;
- case 0x9C :
- return "\xEC\xBC\x9D";
- break;
- case 0xB8 :
- return "\xEC\xBC\xB9";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x95";
- break;
- case 0xB0 :
- return "\xEC\xBD\xB1";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x8D";
- break;
- case 0xA8 :
- return "\xEC\xBE\xA9";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x85";
- break;
- case 0xA0 :
- return "\xEC\xBF\xA1";
- break;
- case 0xBC :
- return "\xEC\xBF\xBD";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\x99";
- break;
- case 0xB4 :
- return "\xED\x80\xB5";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x91";
- break;
- case 0xAC :
- return "\xED\x81\xAD";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x89";
- break;
- case 0xA4 :
- return "\xED\x82\xA5";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x81";
- break;
- case 0x9C :
- return "\xED\x83\x9D";
- break;
- case 0xB8 :
- return "\xED\x83\xB9";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x95";
- break;
- case 0xB0 :
- return "\xED\x84\xB1";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x8D";
- break;
- case 0xA8 :
- return "\xED\x85\xA9";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x85";
- break;
- case 0xA0 :
- return "\xED\x86\xA1";
- break;
- case 0xBC :
- return "\xED\x86\xBD";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\x99";
- break;
- case 0xB4 :
- return "\xED\x87\xB5";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x91";
- break;
- case 0xAC :
- return "\xED\x88\xAD";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x89";
- break;
- case 0xA4 :
- return "\xED\x89\xA5";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x81";
- break;
- case 0x9C :
- return "\xED\x8A\x9D";
- break;
- case 0xB8 :
- return "\xED\x8A\xB9";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x95";
- break;
- case 0xB0 :
- return "\xED\x8B\xB1";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x8D";
- break;
- case 0xA8 :
- return "\xED\x8C\xA9";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x85";
- break;
- case 0xA0 :
- return "\xED\x8D\xA1";
- break;
- case 0xBC :
- return "\xED\x8D\xBD";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\x99";
- break;
- case 0xB4 :
- return "\xED\x8E\xB5";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x91";
- break;
- case 0xAC :
- return "\xED\x8F\xAD";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x89";
- break;
- case 0xA4 :
- return "\xED\x90\xA5";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x81";
- break;
- case 0x9C :
- return "\xED\x91\x9D";
- break;
- case 0xB8 :
- return "\xED\x91\xB9";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x95";
- break;
- case 0xB0 :
- return "\xED\x92\xB1";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x8D";
- break;
- case 0xA8 :
- return "\xED\x93\xA9";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x85";
- break;
- case 0xA0 :
- return "\xED\x94\xA1";
- break;
- case 0xBC :
- return "\xED\x94\xBD";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\x99";
- break;
- case 0xB4 :
- return "\xED\x95\xB5";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x91";
- break;
- case 0xAC :
- return "\xED\x96\xAD";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x89";
- break;
- case 0xA4 :
- return "\xED\x97\xA5";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x81";
- break;
- case 0x9C :
- return "\xED\x98\x9D";
- break;
- case 0xB8 :
- return "\xED\x98\xB9";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x95";
- break;
- case 0xB0 :
- return "\xED\x99\xB1";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x8D";
- break;
- case 0xA8 :
- return "\xED\x9A\xA9";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x85";
- break;
- case 0xA0 :
- return "\xED\x9B\xA1";
- break;
- case 0xBC :
- return "\xED\x9B\xBD";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\x99";
- break;
- case 0xB4 :
- return "\xED\x9C\xB5";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x91";
- break;
- case 0xAC :
- return "\xED\x9D\xAD";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x89";
- }
- break;
- }
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x82";
- break;
- case 0x9C :
- return "\xEA\xB0\x9E";
- break;
- case 0xB8 :
- return "\xEA\xB0\xBA";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x96";
- break;
- case 0xB0 :
- return "\xEA\xB1\xB2";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x8E";
- break;
- case 0xA8 :
- return "\xEA\xB2\xAA";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x86";
- break;
- case 0xA0 :
- return "\xEA\xB3\xA2";
- break;
- case 0xBC :
- return "\xEA\xB3\xBE";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\x9A";
- break;
- case 0xB4 :
- return "\xEA\xB4\xB6";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x92";
- break;
- case 0xAC :
- return "\xEA\xB5\xAE";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x8A";
- break;
- case 0xA4 :
- return "\xEA\xB6\xA6";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x82";
- break;
- case 0x9C :
- return "\xEA\xB7\x9E";
- break;
- case 0xB8 :
- return "\xEA\xB7\xBA";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x96";
- break;
- case 0xB0 :
- return "\xEA\xB8\xB2";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x8E";
- break;
- case 0xA8 :
- return "\xEA\xB9\xAA";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x86";
- break;
- case 0xA0 :
- return "\xEA\xBA\xA2";
- break;
- case 0xBC :
- return "\xEA\xBA\xBE";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\x9A";
- break;
- case 0xB4 :
- return "\xEA\xBB\xB6";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x92";
- break;
- case 0xAC :
- return "\xEA\xBC\xAE";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x8A";
- break;
- case 0xA4 :
- return "\xEA\xBD\xA6";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x82";
- break;
- case 0x9C :
- return "\xEA\xBE\x9E";
- break;
- case 0xB8 :
- return "\xEA\xBE\xBA";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x96";
- break;
- case 0xB0 :
- return "\xEA\xBF\xB2";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x8E";
- break;
- case 0xA8 :
- return "\xEB\x80\xAA";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x86";
- break;
- case 0xA0 :
- return "\xEB\x81\xA2";
- break;
- case 0xBC :
- return "\xEB\x81\xBE";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\x9A";
- break;
- case 0xB4 :
- return "\xEB\x82\xB6";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x92";
- break;
- case 0xAC :
- return "\xEB\x83\xAE";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x8A";
- break;
- case 0xA4 :
- return "\xEB\x84\xA6";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x82";
- break;
- case 0x9C :
- return "\xEB\x85\x9E";
- break;
- case 0xB8 :
- return "\xEB\x85\xBA";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x96";
- break;
- case 0xB0 :
- return "\xEB\x86\xB2";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x8E";
- break;
- case 0xA8 :
- return "\xEB\x87\xAA";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x86";
- break;
- case 0xA0 :
- return "\xEB\x88\xA2";
- break;
- case 0xBC :
- return "\xEB\x88\xBE";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\x9A";
- break;
- case 0xB4 :
- return "\xEB\x89\xB6";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x92";
- break;
- case 0xAC :
- return "\xEB\x8A\xAE";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x8A";
- break;
- case 0xA4 :
- return "\xEB\x8B\xA6";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x82";
- break;
- case 0x9C :
- return "\xEB\x8C\x9E";
- break;
- case 0xB8 :
- return "\xEB\x8C\xBA";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x96";
- break;
- case 0xB0 :
- return "\xEB\x8D\xB2";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x8E";
- break;
- case 0xA8 :
- return "\xEB\x8E\xAA";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x86";
- break;
- case 0xA0 :
- return "\xEB\x8F\xA2";
- break;
- case 0xBC :
- return "\xEB\x8F\xBE";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\x9A";
- break;
- case 0xB4 :
- return "\xEB\x90\xB6";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x92";
- break;
- case 0xAC :
- return "\xEB\x91\xAE";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x8A";
- break;
- case 0xA4 :
- return "\xEB\x92\xA6";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x82";
- break;
- case 0x9C :
- return "\xEB\x93\x9E";
- break;
- case 0xB8 :
- return "\xEB\x93\xBA";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x96";
- break;
- case 0xB0 :
- return "\xEB\x94\xB2";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x8E";
- break;
- case 0xA8 :
- return "\xEB\x95\xAA";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x86";
- break;
- case 0xA0 :
- return "\xEB\x96\xA2";
- break;
- case 0xBC :
- return "\xEB\x96\xBE";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\x9A";
- break;
- case 0xB4 :
- return "\xEB\x97\xB6";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x92";
- break;
- case 0xAC :
- return "\xEB\x98\xAE";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x8A";
- break;
- case 0xA4 :
- return "\xEB\x99\xA6";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x82";
- break;
- case 0x9C :
- return "\xEB\x9A\x9E";
- break;
- case 0xB8 :
- return "\xEB\x9A\xBA";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x96";
- break;
- case 0xB0 :
- return "\xEB\x9B\xB2";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x8E";
- break;
- case 0xA8 :
- return "\xEB\x9C\xAA";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x86";
- break;
- case 0xA0 :
- return "\xEB\x9D\xA2";
- break;
- case 0xBC :
- return "\xEB\x9D\xBE";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\x9A";
- break;
- case 0xB4 :
- return "\xEB\x9E\xB6";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x92";
- break;
- case 0xAC :
- return "\xEB\x9F\xAE";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x8A";
- break;
- case 0xA4 :
- return "\xEB\xA0\xA6";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x82";
- break;
- case 0x9C :
- return "\xEB\xA1\x9E";
- break;
- case 0xB8 :
- return "\xEB\xA1\xBA";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x96";
- break;
- case 0xB0 :
- return "\xEB\xA2\xB2";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x8E";
- break;
- case 0xA8 :
- return "\xEB\xA3\xAA";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x86";
- break;
- case 0xA0 :
- return "\xEB\xA4\xA2";
- break;
- case 0xBC :
- return "\xEB\xA4\xBE";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\x9A";
- break;
- case 0xB4 :
- return "\xEB\xA5\xB6";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x92";
- break;
- case 0xAC :
- return "\xEB\xA6\xAE";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x8A";
- break;
- case 0xA4 :
- return "\xEB\xA7\xA6";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x82";
- break;
- case 0x9C :
- return "\xEB\xA8\x9E";
- break;
- case 0xB8 :
- return "\xEB\xA8\xBA";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x96";
- break;
- case 0xB0 :
- return "\xEB\xA9\xB2";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x8E";
- break;
- case 0xA8 :
- return "\xEB\xAA\xAA";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x86";
- break;
- case 0xA0 :
- return "\xEB\xAB\xA2";
- break;
- case 0xBC :
- return "\xEB\xAB\xBE";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\x9A";
- break;
- case 0xB4 :
- return "\xEB\xAC\xB6";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x92";
- break;
- case 0xAC :
- return "\xEB\xAD\xAE";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x8A";
- break;
- case 0xA4 :
- return "\xEB\xAE\xA6";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x82";
- break;
- case 0x9C :
- return "\xEB\xAF\x9E";
- break;
- case 0xB8 :
- return "\xEB\xAF\xBA";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x96";
- break;
- case 0xB0 :
- return "\xEB\xB0\xB2";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x8E";
- break;
- case 0xA8 :
- return "\xEB\xB1\xAA";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x86";
- break;
- case 0xA0 :
- return "\xEB\xB2\xA2";
- break;
- case 0xBC :
- return "\xEB\xB2\xBE";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\x9A";
- break;
- case 0xB4 :
- return "\xEB\xB3\xB6";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x92";
- break;
- case 0xAC :
- return "\xEB\xB4\xAE";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x8A";
- break;
- case 0xA4 :
- return "\xEB\xB5\xA6";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x82";
- break;
- case 0x9C :
- return "\xEB\xB6\x9E";
- break;
- case 0xB8 :
- return "\xEB\xB6\xBA";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x96";
- break;
- case 0xB0 :
- return "\xEB\xB7\xB2";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x8E";
- break;
- case 0xA8 :
- return "\xEB\xB8\xAA";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x86";
- break;
- case 0xA0 :
- return "\xEB\xB9\xA2";
- break;
- case 0xBC :
- return "\xEB\xB9\xBE";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\x9A";
- break;
- case 0xB4 :
- return "\xEB\xBA\xB6";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x92";
- break;
- case 0xAC :
- return "\xEB\xBB\xAE";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x8A";
- break;
- case 0xA4 :
- return "\xEB\xBC\xA6";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x82";
- break;
- case 0x9C :
- return "\xEB\xBD\x9E";
- break;
- case 0xB8 :
- return "\xEB\xBD\xBA";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x96";
- break;
- case 0xB0 :
- return "\xEB\xBE\xB2";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x8E";
- break;
- case 0xA8 :
- return "\xEB\xBF\xAA";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x86";
- break;
- case 0xA0 :
- return "\xEC\x80\xA2";
- break;
- case 0xBC :
- return "\xEC\x80\xBE";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\x9A";
- break;
- case 0xB4 :
- return "\xEC\x81\xB6";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x92";
- break;
- case 0xAC :
- return "\xEC\x82\xAE";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x8A";
- break;
- case 0xA4 :
- return "\xEC\x83\xA6";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x82";
- break;
- case 0x9C :
- return "\xEC\x84\x9E";
- break;
- case 0xB8 :
- return "\xEC\x84\xBA";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x96";
- break;
- case 0xB0 :
- return "\xEC\x85\xB2";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x8E";
- break;
- case 0xA8 :
- return "\xEC\x86\xAA";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x86";
- break;
- case 0xA0 :
- return "\xEC\x87\xA2";
- break;
- case 0xBC :
- return "\xEC\x87\xBE";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\x9A";
- break;
- case 0xB4 :
- return "\xEC\x88\xB6";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x92";
- break;
- case 0xAC :
- return "\xEC\x89\xAE";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x8A";
- break;
- case 0xA4 :
- return "\xEC\x8A\xA6";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x82";
- break;
- case 0x9C :
- return "\xEC\x8B\x9E";
- break;
- case 0xB8 :
- return "\xEC\x8B\xBA";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x96";
- break;
- case 0xB0 :
- return "\xEC\x8C\xB2";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x8E";
- break;
- case 0xA8 :
- return "\xEC\x8D\xAA";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x86";
- break;
- case 0xA0 :
- return "\xEC\x8E\xA2";
- break;
- case 0xBC :
- return "\xEC\x8E\xBE";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\x9A";
- break;
- case 0xB4 :
- return "\xEC\x8F\xB6";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x92";
- break;
- case 0xAC :
- return "\xEC\x90\xAE";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x8A";
- break;
- case 0xA4 :
- return "\xEC\x91\xA6";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x82";
- break;
- case 0x9C :
- return "\xEC\x92\x9E";
- break;
- case 0xB8 :
- return "\xEC\x92\xBA";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x96";
- break;
- case 0xB0 :
- return "\xEC\x93\xB2";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x8E";
- break;
- case 0xA8 :
- return "\xEC\x94\xAA";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x86";
- break;
- case 0xA0 :
- return "\xEC\x95\xA2";
- break;
- case 0xBC :
- return "\xEC\x95\xBE";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\x9A";
- break;
- case 0xB4 :
- return "\xEC\x96\xB6";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x92";
- break;
- case 0xAC :
- return "\xEC\x97\xAE";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x8A";
- break;
- case 0xA4 :
- return "\xEC\x98\xA6";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x82";
- break;
- case 0x9C :
- return "\xEC\x99\x9E";
- break;
- case 0xB8 :
- return "\xEC\x99\xBA";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x96";
- break;
- case 0xB0 :
- return "\xEC\x9A\xB2";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x8E";
- break;
- case 0xA8 :
- return "\xEC\x9B\xAA";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x86";
- break;
- case 0xA0 :
- return "\xEC\x9C\xA2";
- break;
- case 0xBC :
- return "\xEC\x9C\xBE";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\x9A";
- break;
- case 0xB4 :
- return "\xEC\x9D\xB6";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x92";
- break;
- case 0xAC :
- return "\xEC\x9E\xAE";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x8A";
- break;
- case 0xA4 :
- return "\xEC\x9F\xA6";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x82";
- break;
- case 0x9C :
- return "\xEC\xA0\x9E";
- break;
- case 0xB8 :
- return "\xEC\xA0\xBA";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x96";
- break;
- case 0xB0 :
- return "\xEC\xA1\xB2";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x8E";
- break;
- case 0xA8 :
- return "\xEC\xA2\xAA";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x86";
- break;
- case 0xA0 :
- return "\xEC\xA3\xA2";
- break;
- case 0xBC :
- return "\xEC\xA3\xBE";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\x9A";
- break;
- case 0xB4 :
- return "\xEC\xA4\xB6";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x92";
- break;
- case 0xAC :
- return "\xEC\xA5\xAE";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x8A";
- break;
- case 0xA4 :
- return "\xEC\xA6\xA6";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x82";
- break;
- case 0x9C :
- return "\xEC\xA7\x9E";
- break;
- case 0xB8 :
- return "\xEC\xA7\xBA";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x96";
- break;
- case 0xB0 :
- return "\xEC\xA8\xB2";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x8E";
- break;
- case 0xA8 :
- return "\xEC\xA9\xAA";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x86";
- break;
- case 0xA0 :
- return "\xEC\xAA\xA2";
- break;
- case 0xBC :
- return "\xEC\xAA\xBE";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\x9A";
- break;
- case 0xB4 :
- return "\xEC\xAB\xB6";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x92";
- break;
- case 0xAC :
- return "\xEC\xAC\xAE";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x8A";
- break;
- case 0xA4 :
- return "\xEC\xAD\xA6";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x82";
- break;
- case 0x9C :
- return "\xEC\xAE\x9E";
- break;
- case 0xB8 :
- return "\xEC\xAE\xBA";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x96";
- break;
- case 0xB0 :
- return "\xEC\xAF\xB2";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x8E";
- break;
- case 0xA8 :
- return "\xEC\xB0\xAA";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x86";
- break;
- case 0xA0 :
- return "\xEC\xB1\xA2";
- break;
- case 0xBC :
- return "\xEC\xB1\xBE";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\x9A";
- break;
- case 0xB4 :
- return "\xEC\xB2\xB6";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x92";
- break;
- case 0xAC :
- return "\xEC\xB3\xAE";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x8A";
- break;
- case 0xA4 :
- return "\xEC\xB4\xA6";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x82";
- break;
- case 0x9C :
- return "\xEC\xB5\x9E";
- break;
- case 0xB8 :
- return "\xEC\xB5\xBA";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x96";
- break;
- case 0xB0 :
- return "\xEC\xB6\xB2";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x8E";
- break;
- case 0xA8 :
- return "\xEC\xB7\xAA";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x86";
- break;
- case 0xA0 :
- return "\xEC\xB8\xA2";
- break;
- case 0xBC :
- return "\xEC\xB8\xBE";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\x9A";
- break;
- case 0xB4 :
- return "\xEC\xB9\xB6";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x92";
- break;
- case 0xAC :
- return "\xEC\xBA\xAE";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x8A";
- break;
- case 0xA4 :
- return "\xEC\xBB\xA6";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x82";
- break;
- case 0x9C :
- return "\xEC\xBC\x9E";
- break;
- case 0xB8 :
- return "\xEC\xBC\xBA";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x96";
- break;
- case 0xB0 :
- return "\xEC\xBD\xB2";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x8E";
- break;
- case 0xA8 :
- return "\xEC\xBE\xAA";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x86";
- break;
- case 0xA0 :
- return "\xEC\xBF\xA2";
- break;
- case 0xBC :
- return "\xEC\xBF\xBE";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\x9A";
- break;
- case 0xB4 :
- return "\xED\x80\xB6";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x92";
- break;
- case 0xAC :
- return "\xED\x81\xAE";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x8A";
- break;
- case 0xA4 :
- return "\xED\x82\xA6";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x82";
- break;
- case 0x9C :
- return "\xED\x83\x9E";
- break;
- case 0xB8 :
- return "\xED\x83\xBA";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x96";
- break;
- case 0xB0 :
- return "\xED\x84\xB2";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x8E";
- break;
- case 0xA8 :
- return "\xED\x85\xAA";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x86";
- break;
- case 0xA0 :
- return "\xED\x86\xA2";
- break;
- case 0xBC :
- return "\xED\x86\xBE";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\x9A";
- break;
- case 0xB4 :
- return "\xED\x87\xB6";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x92";
- break;
- case 0xAC :
- return "\xED\x88\xAE";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x8A";
- break;
- case 0xA4 :
- return "\xED\x89\xA6";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x82";
- break;
- case 0x9C :
- return "\xED\x8A\x9E";
- break;
- case 0xB8 :
- return "\xED\x8A\xBA";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x96";
- break;
- case 0xB0 :
- return "\xED\x8B\xB2";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x8E";
- break;
- case 0xA8 :
- return "\xED\x8C\xAA";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x86";
- break;
- case 0xA0 :
- return "\xED\x8D\xA2";
- break;
- case 0xBC :
- return "\xED\x8D\xBE";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\x9A";
- break;
- case 0xB4 :
- return "\xED\x8E\xB6";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x92";
- break;
- case 0xAC :
- return "\xED\x8F\xAE";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x8A";
- break;
- case 0xA4 :
- return "\xED\x90\xA6";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x82";
- break;
- case 0x9C :
- return "\xED\x91\x9E";
- break;
- case 0xB8 :
- return "\xED\x91\xBA";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x96";
- break;
- case 0xB0 :
- return "\xED\x92\xB2";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x8E";
- break;
- case 0xA8 :
- return "\xED\x93\xAA";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x86";
- break;
- case 0xA0 :
- return "\xED\x94\xA2";
- break;
- case 0xBC :
- return "\xED\x94\xBE";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\x9A";
- break;
- case 0xB4 :
- return "\xED\x95\xB6";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x92";
- break;
- case 0xAC :
- return "\xED\x96\xAE";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x8A";
- break;
- case 0xA4 :
- return "\xED\x97\xA6";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x82";
- break;
- case 0x9C :
- return "\xED\x98\x9E";
- break;
- case 0xB8 :
- return "\xED\x98\xBA";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x96";
- break;
- case 0xB0 :
- return "\xED\x99\xB2";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x8E";
- break;
- case 0xA8 :
- return "\xED\x9A\xAA";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x86";
- break;
- case 0xA0 :
- return "\xED\x9B\xA2";
- break;
- case 0xBC :
- return "\xED\x9B\xBE";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\x9A";
- break;
- case 0xB4 :
- return "\xED\x9C\xB6";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x92";
- break;
- case 0xAC :
- return "\xED\x9D\xAE";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x8A";
- }
- break;
- }
- break;
- }
- break;
- case 0xAA :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x83";
- break;
- case 0x9C :
- return "\xEA\xB0\x9F";
- break;
- case 0xB8 :
- return "\xEA\xB0\xBB";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x97";
- break;
- case 0xB0 :
- return "\xEA\xB1\xB3";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x8F";
- break;
- case 0xA8 :
- return "\xEA\xB2\xAB";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x87";
- break;
- case 0xA0 :
- return "\xEA\xB3\xA3";
- break;
- case 0xBC :
- return "\xEA\xB3\xBF";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\x9B";
- break;
- case 0xB4 :
- return "\xEA\xB4\xB7";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x93";
- break;
- case 0xAC :
- return "\xEA\xB5\xAF";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x8B";
- break;
- case 0xA4 :
- return "\xEA\xB6\xA7";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x83";
- break;
- case 0x9C :
- return "\xEA\xB7\x9F";
- break;
- case 0xB8 :
- return "\xEA\xB7\xBB";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x97";
- break;
- case 0xB0 :
- return "\xEA\xB8\xB3";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x8F";
- break;
- case 0xA8 :
- return "\xEA\xB9\xAB";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x87";
- break;
- case 0xA0 :
- return "\xEA\xBA\xA3";
- break;
- case 0xBC :
- return "\xEA\xBA\xBF";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\x9B";
- break;
- case 0xB4 :
- return "\xEA\xBB\xB7";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x93";
- break;
- case 0xAC :
- return "\xEA\xBC\xAF";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x8B";
- break;
- case 0xA4 :
- return "\xEA\xBD\xA7";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x83";
- break;
- case 0x9C :
- return "\xEA\xBE\x9F";
- break;
- case 0xB8 :
- return "\xEA\xBE\xBB";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x97";
- break;
- case 0xB0 :
- return "\xEA\xBF\xB3";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x8F";
- break;
- case 0xA8 :
- return "\xEB\x80\xAB";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x87";
- break;
- case 0xA0 :
- return "\xEB\x81\xA3";
- break;
- case 0xBC :
- return "\xEB\x81\xBF";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\x9B";
- break;
- case 0xB4 :
- return "\xEB\x82\xB7";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x93";
- break;
- case 0xAC :
- return "\xEB\x83\xAF";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x8B";
- break;
- case 0xA4 :
- return "\xEB\x84\xA7";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x83";
- break;
- case 0x9C :
- return "\xEB\x85\x9F";
- break;
- case 0xB8 :
- return "\xEB\x85\xBB";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x97";
- break;
- case 0xB0 :
- return "\xEB\x86\xB3";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x8F";
- break;
- case 0xA8 :
- return "\xEB\x87\xAB";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x87";
- break;
- case 0xA0 :
- return "\xEB\x88\xA3";
- break;
- case 0xBC :
- return "\xEB\x88\xBF";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\x9B";
- break;
- case 0xB4 :
- return "\xEB\x89\xB7";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x93";
- break;
- case 0xAC :
- return "\xEB\x8A\xAF";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x8B";
- break;
- case 0xA4 :
- return "\xEB\x8B\xA7";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x83";
- break;
- case 0x9C :
- return "\xEB\x8C\x9F";
- break;
- case 0xB8 :
- return "\xEB\x8C\xBB";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x97";
- break;
- case 0xB0 :
- return "\xEB\x8D\xB3";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x8F";
- break;
- case 0xA8 :
- return "\xEB\x8E\xAB";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x87";
- break;
- case 0xA0 :
- return "\xEB\x8F\xA3";
- break;
- case 0xBC :
- return "\xEB\x8F\xBF";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\x9B";
- break;
- case 0xB4 :
- return "\xEB\x90\xB7";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x93";
- break;
- case 0xAC :
- return "\xEB\x91\xAF";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x8B";
- break;
- case 0xA4 :
- return "\xEB\x92\xA7";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x83";
- break;
- case 0x9C :
- return "\xEB\x93\x9F";
- break;
- case 0xB8 :
- return "\xEB\x93\xBB";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x97";
- break;
- case 0xB0 :
- return "\xEB\x94\xB3";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x8F";
- break;
- case 0xA8 :
- return "\xEB\x95\xAB";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x87";
- break;
- case 0xA0 :
- return "\xEB\x96\xA3";
- break;
- case 0xBC :
- return "\xEB\x96\xBF";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\x9B";
- break;
- case 0xB4 :
- return "\xEB\x97\xB7";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x93";
- break;
- case 0xAC :
- return "\xEB\x98\xAF";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x8B";
- break;
- case 0xA4 :
- return "\xEB\x99\xA7";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x83";
- break;
- case 0x9C :
- return "\xEB\x9A\x9F";
- break;
- case 0xB8 :
- return "\xEB\x9A\xBB";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x97";
- break;
- case 0xB0 :
- return "\xEB\x9B\xB3";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x8F";
- break;
- case 0xA8 :
- return "\xEB\x9C\xAB";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x87";
- break;
- case 0xA0 :
- return "\xEB\x9D\xA3";
- break;
- case 0xBC :
- return "\xEB\x9D\xBF";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\x9B";
- break;
- case 0xB4 :
- return "\xEB\x9E\xB7";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x93";
- break;
- case 0xAC :
- return "\xEB\x9F\xAF";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x8B";
- break;
- case 0xA4 :
- return "\xEB\xA0\xA7";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x83";
- break;
- case 0x9C :
- return "\xEB\xA1\x9F";
- break;
- case 0xB8 :
- return "\xEB\xA1\xBB";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x97";
- break;
- case 0xB0 :
- return "\xEB\xA2\xB3";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x8F";
- break;
- case 0xA8 :
- return "\xEB\xA3\xAB";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x87";
- break;
- case 0xA0 :
- return "\xEB\xA4\xA3";
- break;
- case 0xBC :
- return "\xEB\xA4\xBF";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\x9B";
- break;
- case 0xB4 :
- return "\xEB\xA5\xB7";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x93";
- break;
- case 0xAC :
- return "\xEB\xA6\xAF";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x8B";
- break;
- case 0xA4 :
- return "\xEB\xA7\xA7";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x83";
- break;
- case 0x9C :
- return "\xEB\xA8\x9F";
- break;
- case 0xB8 :
- return "\xEB\xA8\xBB";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x97";
- break;
- case 0xB0 :
- return "\xEB\xA9\xB3";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x8F";
- break;
- case 0xA8 :
- return "\xEB\xAA\xAB";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x87";
- break;
- case 0xA0 :
- return "\xEB\xAB\xA3";
- break;
- case 0xBC :
- return "\xEB\xAB\xBF";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\x9B";
- break;
- case 0xB4 :
- return "\xEB\xAC\xB7";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x93";
- break;
- case 0xAC :
- return "\xEB\xAD\xAF";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x8B";
- break;
- case 0xA4 :
- return "\xEB\xAE\xA7";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x83";
- break;
- case 0x9C :
- return "\xEB\xAF\x9F";
- break;
- case 0xB8 :
- return "\xEB\xAF\xBB";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x97";
- break;
- case 0xB0 :
- return "\xEB\xB0\xB3";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x8F";
- break;
- case 0xA8 :
- return "\xEB\xB1\xAB";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x87";
- break;
- case 0xA0 :
- return "\xEB\xB2\xA3";
- break;
- case 0xBC :
- return "\xEB\xB2\xBF";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\x9B";
- break;
- case 0xB4 :
- return "\xEB\xB3\xB7";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x93";
- break;
- case 0xAC :
- return "\xEB\xB4\xAF";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x8B";
- break;
- case 0xA4 :
- return "\xEB\xB5\xA7";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x83";
- break;
- case 0x9C :
- return "\xEB\xB6\x9F";
- break;
- case 0xB8 :
- return "\xEB\xB6\xBB";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x97";
- break;
- case 0xB0 :
- return "\xEB\xB7\xB3";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x8F";
- break;
- case 0xA8 :
- return "\xEB\xB8\xAB";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x87";
- break;
- case 0xA0 :
- return "\xEB\xB9\xA3";
- break;
- case 0xBC :
- return "\xEB\xB9\xBF";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\x9B";
- break;
- case 0xB4 :
- return "\xEB\xBA\xB7";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x93";
- break;
- case 0xAC :
- return "\xEB\xBB\xAF";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x8B";
- break;
- case 0xA4 :
- return "\xEB\xBC\xA7";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x83";
- break;
- case 0x9C :
- return "\xEB\xBD\x9F";
- break;
- case 0xB8 :
- return "\xEB\xBD\xBB";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x97";
- break;
- case 0xB0 :
- return "\xEB\xBE\xB3";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x8F";
- break;
- case 0xA8 :
- return "\xEB\xBF\xAB";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x87";
- break;
- case 0xA0 :
- return "\xEC\x80\xA3";
- break;
- case 0xBC :
- return "\xEC\x80\xBF";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\x9B";
- break;
- case 0xB4 :
- return "\xEC\x81\xB7";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x93";
- break;
- case 0xAC :
- return "\xEC\x82\xAF";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x8B";
- break;
- case 0xA4 :
- return "\xEC\x83\xA7";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x83";
- break;
- case 0x9C :
- return "\xEC\x84\x9F";
- break;
- case 0xB8 :
- return "\xEC\x84\xBB";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x97";
- break;
- case 0xB0 :
- return "\xEC\x85\xB3";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x8F";
- break;
- case 0xA8 :
- return "\xEC\x86\xAB";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x87";
- break;
- case 0xA0 :
- return "\xEC\x87\xA3";
- break;
- case 0xBC :
- return "\xEC\x87\xBF";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\x9B";
- break;
- case 0xB4 :
- return "\xEC\x88\xB7";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x93";
- break;
- case 0xAC :
- return "\xEC\x89\xAF";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x8B";
- break;
- case 0xA4 :
- return "\xEC\x8A\xA7";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x83";
- break;
- case 0x9C :
- return "\xEC\x8B\x9F";
- break;
- case 0xB8 :
- return "\xEC\x8B\xBB";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x97";
- break;
- case 0xB0 :
- return "\xEC\x8C\xB3";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x8F";
- break;
- case 0xA8 :
- return "\xEC\x8D\xAB";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x87";
- break;
- case 0xA0 :
- return "\xEC\x8E\xA3";
- break;
- case 0xBC :
- return "\xEC\x8E\xBF";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\x9B";
- break;
- case 0xB4 :
- return "\xEC\x8F\xB7";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x93";
- break;
- case 0xAC :
- return "\xEC\x90\xAF";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x8B";
- break;
- case 0xA4 :
- return "\xEC\x91\xA7";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x83";
- break;
- case 0x9C :
- return "\xEC\x92\x9F";
- break;
- case 0xB8 :
- return "\xEC\x92\xBB";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x97";
- break;
- case 0xB0 :
- return "\xEC\x93\xB3";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x8F";
- break;
- case 0xA8 :
- return "\xEC\x94\xAB";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x87";
- break;
- case 0xA0 :
- return "\xEC\x95\xA3";
- break;
- case 0xBC :
- return "\xEC\x95\xBF";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\x9B";
- break;
- case 0xB4 :
- return "\xEC\x96\xB7";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x93";
- break;
- case 0xAC :
- return "\xEC\x97\xAF";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x8B";
- break;
- case 0xA4 :
- return "\xEC\x98\xA7";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x83";
- break;
- case 0x9C :
- return "\xEC\x99\x9F";
- break;
- case 0xB8 :
- return "\xEC\x99\xBB";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x97";
- break;
- case 0xB0 :
- return "\xEC\x9A\xB3";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x8F";
- break;
- case 0xA8 :
- return "\xEC\x9B\xAB";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x87";
- break;
- case 0xA0 :
- return "\xEC\x9C\xA3";
- break;
- case 0xBC :
- return "\xEC\x9C\xBF";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\x9B";
- break;
- case 0xB4 :
- return "\xEC\x9D\xB7";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x93";
- break;
- case 0xAC :
- return "\xEC\x9E\xAF";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x8B";
- break;
- case 0xA4 :
- return "\xEC\x9F\xA7";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x83";
- break;
- case 0x9C :
- return "\xEC\xA0\x9F";
- break;
- case 0xB8 :
- return "\xEC\xA0\xBB";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x97";
- break;
- case 0xB0 :
- return "\xEC\xA1\xB3";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x8F";
- break;
- case 0xA8 :
- return "\xEC\xA2\xAB";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x87";
- break;
- case 0xA0 :
- return "\xEC\xA3\xA3";
- break;
- case 0xBC :
- return "\xEC\xA3\xBF";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\x9B";
- break;
- case 0xB4 :
- return "\xEC\xA4\xB7";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x93";
- break;
- case 0xAC :
- return "\xEC\xA5\xAF";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x8B";
- break;
- case 0xA4 :
- return "\xEC\xA6\xA7";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x83";
- break;
- case 0x9C :
- return "\xEC\xA7\x9F";
- break;
- case 0xB8 :
- return "\xEC\xA7\xBB";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x97";
- break;
- case 0xB0 :
- return "\xEC\xA8\xB3";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x8F";
- break;
- case 0xA8 :
- return "\xEC\xA9\xAB";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x87";
- break;
- case 0xA0 :
- return "\xEC\xAA\xA3";
- break;
- case 0xBC :
- return "\xEC\xAA\xBF";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\x9B";
- break;
- case 0xB4 :
- return "\xEC\xAB\xB7";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x93";
- break;
- case 0xAC :
- return "\xEC\xAC\xAF";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x8B";
- break;
- case 0xA4 :
- return "\xEC\xAD\xA7";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x83";
- break;
- case 0x9C :
- return "\xEC\xAE\x9F";
- break;
- case 0xB8 :
- return "\xEC\xAE\xBB";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x97";
- break;
- case 0xB0 :
- return "\xEC\xAF\xB3";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x8F";
- break;
- case 0xA8 :
- return "\xEC\xB0\xAB";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x87";
- break;
- case 0xA0 :
- return "\xEC\xB1\xA3";
- break;
- case 0xBC :
- return "\xEC\xB1\xBF";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\x9B";
- break;
- case 0xB4 :
- return "\xEC\xB2\xB7";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x93";
- break;
- case 0xAC :
- return "\xEC\xB3\xAF";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x8B";
- break;
- case 0xA4 :
- return "\xEC\xB4\xA7";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x83";
- break;
- case 0x9C :
- return "\xEC\xB5\x9F";
- break;
- case 0xB8 :
- return "\xEC\xB5\xBB";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x97";
- break;
- case 0xB0 :
- return "\xEC\xB6\xB3";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x8F";
- break;
- case 0xA8 :
- return "\xEC\xB7\xAB";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x87";
- break;
- case 0xA0 :
- return "\xEC\xB8\xA3";
- break;
- case 0xBC :
- return "\xEC\xB8\xBF";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\x9B";
- break;
- case 0xB4 :
- return "\xEC\xB9\xB7";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x93";
- break;
- case 0xAC :
- return "\xEC\xBA\xAF";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x8B";
- break;
- case 0xA4 :
- return "\xEC\xBB\xA7";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x83";
- break;
- case 0x9C :
- return "\xEC\xBC\x9F";
- break;
- case 0xB8 :
- return "\xEC\xBC\xBB";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x97";
- break;
- case 0xB0 :
- return "\xEC\xBD\xB3";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x8F";
- break;
- case 0xA8 :
- return "\xEC\xBE\xAB";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x87";
- break;
- case 0xA0 :
- return "\xEC\xBF\xA3";
- break;
- case 0xBC :
- return "\xEC\xBF\xBF";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\x9B";
- break;
- case 0xB4 :
- return "\xED\x80\xB7";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x93";
- break;
- case 0xAC :
- return "\xED\x81\xAF";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x8B";
- break;
- case 0xA4 :
- return "\xED\x82\xA7";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x83";
- break;
- case 0x9C :
- return "\xED\x83\x9F";
- break;
- case 0xB8 :
- return "\xED\x83\xBB";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x97";
- break;
- case 0xB0 :
- return "\xED\x84\xB3";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x8F";
- break;
- case 0xA8 :
- return "\xED\x85\xAB";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x87";
- break;
- case 0xA0 :
- return "\xED\x86\xA3";
- break;
- case 0xBC :
- return "\xED\x86\xBF";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\x9B";
- break;
- case 0xB4 :
- return "\xED\x87\xB7";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x93";
- break;
- case 0xAC :
- return "\xED\x88\xAF";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x8B";
- break;
- case 0xA4 :
- return "\xED\x89\xA7";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x83";
- break;
- case 0x9C :
- return "\xED\x8A\x9F";
- break;
- case 0xB8 :
- return "\xED\x8A\xBB";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x97";
- break;
- case 0xB0 :
- return "\xED\x8B\xB3";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x8F";
- break;
- case 0xA8 :
- return "\xED\x8C\xAB";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x87";
- break;
- case 0xA0 :
- return "\xED\x8D\xA3";
- break;
- case 0xBC :
- return "\xED\x8D\xBF";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\x9B";
- break;
- case 0xB4 :
- return "\xED\x8E\xB7";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x93";
- break;
- case 0xAC :
- return "\xED\x8F\xAF";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x8B";
- break;
- case 0xA4 :
- return "\xED\x90\xA7";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x83";
- break;
- case 0x9C :
- return "\xED\x91\x9F";
- break;
- case 0xB8 :
- return "\xED\x91\xBB";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x97";
- break;
- case 0xB0 :
- return "\xED\x92\xB3";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x8F";
- break;
- case 0xA8 :
- return "\xED\x93\xAB";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x87";
- break;
- case 0xA0 :
- return "\xED\x94\xA3";
- break;
- case 0xBC :
- return "\xED\x94\xBF";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\x9B";
- break;
- case 0xB4 :
- return "\xED\x95\xB7";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x93";
- break;
- case 0xAC :
- return "\xED\x96\xAF";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x8B";
- break;
- case 0xA4 :
- return "\xED\x97\xA7";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x83";
- break;
- case 0x9C :
- return "\xED\x98\x9F";
- break;
- case 0xB8 :
- return "\xED\x98\xBB";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x97";
- break;
- case 0xB0 :
- return "\xED\x99\xB3";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x8F";
- break;
- case 0xA8 :
- return "\xED\x9A\xAB";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x87";
- break;
- case 0xA0 :
- return "\xED\x9B\xA3";
- break;
- case 0xBC :
- return "\xED\x9B\xBF";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\x9B";
- break;
- case 0xB4 :
- return "\xED\x9C\xB7";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x93";
- break;
- case 0xAC :
- return "\xED\x9D\xAF";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x8B";
- }
- break;
- }
- break;
- }
- break;
- case 0xAB :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x84";
- break;
- case 0x9C :
- return "\xEA\xB0\xA0";
- break;
- case 0xB8 :
- return "\xEA\xB0\xBC";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x98";
- break;
- case 0xB0 :
- return "\xEA\xB1\xB4";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x90";
- break;
- case 0xA8 :
- return "\xEA\xB2\xAC";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x88";
- break;
- case 0xA0 :
- return "\xEA\xB3\xA4";
- break;
- case 0xBC :
- return "\xEA\xB4\x80";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\x9C";
- break;
- case 0xB4 :
- return "\xEA\xB4\xB8";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x94";
- break;
- case 0xAC :
- return "\xEA\xB5\xB0";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x8C";
- break;
- case 0xA4 :
- return "\xEA\xB6\xA8";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x84";
- break;
- case 0x9C :
- return "\xEA\xB7\xA0";
- break;
- case 0xB8 :
- return "\xEA\xB7\xBC";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x98";
- break;
- case 0xB0 :
- return "\xEA\xB8\xB4";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x90";
- break;
- case 0xA8 :
- return "\xEA\xB9\xAC";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x88";
- break;
- case 0xA0 :
- return "\xEA\xBA\xA4";
- break;
- case 0xBC :
- return "\xEA\xBB\x80";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\x9C";
- break;
- case 0xB4 :
- return "\xEA\xBB\xB8";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x94";
- break;
- case 0xAC :
- return "\xEA\xBC\xB0";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x8C";
- break;
- case 0xA4 :
- return "\xEA\xBD\xA8";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x84";
- break;
- case 0x9C :
- return "\xEA\xBE\xA0";
- break;
- case 0xB8 :
- return "\xEA\xBE\xBC";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x98";
- break;
- case 0xB0 :
- return "\xEA\xBF\xB4";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x90";
- break;
- case 0xA8 :
- return "\xEB\x80\xAC";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x88";
- break;
- case 0xA0 :
- return "\xEB\x81\xA4";
- break;
- case 0xBC :
- return "\xEB\x82\x80";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\x9C";
- break;
- case 0xB4 :
- return "\xEB\x82\xB8";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x94";
- break;
- case 0xAC :
- return "\xEB\x83\xB0";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x8C";
- break;
- case 0xA4 :
- return "\xEB\x84\xA8";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x84";
- break;
- case 0x9C :
- return "\xEB\x85\xA0";
- break;
- case 0xB8 :
- return "\xEB\x85\xBC";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x98";
- break;
- case 0xB0 :
- return "\xEB\x86\xB4";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x90";
- break;
- case 0xA8 :
- return "\xEB\x87\xAC";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x88";
- break;
- case 0xA0 :
- return "\xEB\x88\xA4";
- break;
- case 0xBC :
- return "\xEB\x89\x80";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\x9C";
- break;
- case 0xB4 :
- return "\xEB\x89\xB8";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x94";
- break;
- case 0xAC :
- return "\xEB\x8A\xB0";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x8C";
- break;
- case 0xA4 :
- return "\xEB\x8B\xA8";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x84";
- break;
- case 0x9C :
- return "\xEB\x8C\xA0";
- break;
- case 0xB8 :
- return "\xEB\x8C\xBC";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x98";
- break;
- case 0xB0 :
- return "\xEB\x8D\xB4";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x90";
- break;
- case 0xA8 :
- return "\xEB\x8E\xAC";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x88";
- break;
- case 0xA0 :
- return "\xEB\x8F\xA4";
- break;
- case 0xBC :
- return "\xEB\x90\x80";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\x9C";
- break;
- case 0xB4 :
- return "\xEB\x90\xB8";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x94";
- break;
- case 0xAC :
- return "\xEB\x91\xB0";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x8C";
- break;
- case 0xA4 :
- return "\xEB\x92\xA8";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x84";
- break;
- case 0x9C :
- return "\xEB\x93\xA0";
- break;
- case 0xB8 :
- return "\xEB\x93\xBC";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x98";
- break;
- case 0xB0 :
- return "\xEB\x94\xB4";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x90";
- break;
- case 0xA8 :
- return "\xEB\x95\xAC";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x88";
- break;
- case 0xA0 :
- return "\xEB\x96\xA4";
- break;
- case 0xBC :
- return "\xEB\x97\x80";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\x9C";
- break;
- case 0xB4 :
- return "\xEB\x97\xB8";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x94";
- break;
- case 0xAC :
- return "\xEB\x98\xB0";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x8C";
- break;
- case 0xA4 :
- return "\xEB\x99\xA8";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x84";
- break;
- case 0x9C :
- return "\xEB\x9A\xA0";
- break;
- case 0xB8 :
- return "\xEB\x9A\xBC";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x98";
- break;
- case 0xB0 :
- return "\xEB\x9B\xB4";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x90";
- break;
- case 0xA8 :
- return "\xEB\x9C\xAC";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x88";
- break;
- case 0xA0 :
- return "\xEB\x9D\xA4";
- break;
- case 0xBC :
- return "\xEB\x9E\x80";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\x9C";
- break;
- case 0xB4 :
- return "\xEB\x9E\xB8";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x94";
- break;
- case 0xAC :
- return "\xEB\x9F\xB0";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x8C";
- break;
- case 0xA4 :
- return "\xEB\xA0\xA8";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x84";
- break;
- case 0x9C :
- return "\xEB\xA1\xA0";
- break;
- case 0xB8 :
- return "\xEB\xA1\xBC";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x98";
- break;
- case 0xB0 :
- return "\xEB\xA2\xB4";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x90";
- break;
- case 0xA8 :
- return "\xEB\xA3\xAC";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x88";
- break;
- case 0xA0 :
- return "\xEB\xA4\xA4";
- break;
- case 0xBC :
- return "\xEB\xA5\x80";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\x9C";
- break;
- case 0xB4 :
- return "\xEB\xA5\xB8";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x94";
- break;
- case 0xAC :
- return "\xEB\xA6\xB0";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x8C";
- break;
- case 0xA4 :
- return "\xEB\xA7\xA8";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x84";
- break;
- case 0x9C :
- return "\xEB\xA8\xA0";
- break;
- case 0xB8 :
- return "\xEB\xA8\xBC";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x98";
- break;
- case 0xB0 :
- return "\xEB\xA9\xB4";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x90";
- break;
- case 0xA8 :
- return "\xEB\xAA\xAC";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x88";
- break;
- case 0xA0 :
- return "\xEB\xAB\xA4";
- break;
- case 0xBC :
- return "\xEB\xAC\x80";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\x9C";
- break;
- case 0xB4 :
- return "\xEB\xAC\xB8";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x94";
- break;
- case 0xAC :
- return "\xEB\xAD\xB0";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x8C";
- break;
- case 0xA4 :
- return "\xEB\xAE\xA8";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x84";
- break;
- case 0x9C :
- return "\xEB\xAF\xA0";
- break;
- case 0xB8 :
- return "\xEB\xAF\xBC";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x98";
- break;
- case 0xB0 :
- return "\xEB\xB0\xB4";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x90";
- break;
- case 0xA8 :
- return "\xEB\xB1\xAC";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x88";
- break;
- case 0xA0 :
- return "\xEB\xB2\xA4";
- break;
- case 0xBC :
- return "\xEB\xB3\x80";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\x9C";
- break;
- case 0xB4 :
- return "\xEB\xB3\xB8";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x94";
- break;
- case 0xAC :
- return "\xEB\xB4\xB0";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x8C";
- break;
- case 0xA4 :
- return "\xEB\xB5\xA8";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x84";
- break;
- case 0x9C :
- return "\xEB\xB6\xA0";
- break;
- case 0xB8 :
- return "\xEB\xB6\xBC";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x98";
- break;
- case 0xB0 :
- return "\xEB\xB7\xB4";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x90";
- break;
- case 0xA8 :
- return "\xEB\xB8\xAC";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x88";
- break;
- case 0xA0 :
- return "\xEB\xB9\xA4";
- break;
- case 0xBC :
- return "\xEB\xBA\x80";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\x9C";
- break;
- case 0xB4 :
- return "\xEB\xBA\xB8";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x94";
- break;
- case 0xAC :
- return "\xEB\xBB\xB0";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x8C";
- break;
- case 0xA4 :
- return "\xEB\xBC\xA8";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x84";
- break;
- case 0x9C :
- return "\xEB\xBD\xA0";
- break;
- case 0xB8 :
- return "\xEB\xBD\xBC";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x98";
- break;
- case 0xB0 :
- return "\xEB\xBE\xB4";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x90";
- break;
- case 0xA8 :
- return "\xEB\xBF\xAC";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x88";
- break;
- case 0xA0 :
- return "\xEC\x80\xA4";
- break;
- case 0xBC :
- return "\xEC\x81\x80";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\x9C";
- break;
- case 0xB4 :
- return "\xEC\x81\xB8";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x94";
- break;
- case 0xAC :
- return "\xEC\x82\xB0";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x8C";
- break;
- case 0xA4 :
- return "\xEC\x83\xA8";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x84";
- break;
- case 0x9C :
- return "\xEC\x84\xA0";
- break;
- case 0xB8 :
- return "\xEC\x84\xBC";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x98";
- break;
- case 0xB0 :
- return "\xEC\x85\xB4";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x90";
- break;
- case 0xA8 :
- return "\xEC\x86\xAC";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x88";
- break;
- case 0xA0 :
- return "\xEC\x87\xA4";
- break;
- case 0xBC :
- return "\xEC\x88\x80";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\x9C";
- break;
- case 0xB4 :
- return "\xEC\x88\xB8";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x94";
- break;
- case 0xAC :
- return "\xEC\x89\xB0";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x8C";
- break;
- case 0xA4 :
- return "\xEC\x8A\xA8";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x84";
- break;
- case 0x9C :
- return "\xEC\x8B\xA0";
- break;
- case 0xB8 :
- return "\xEC\x8B\xBC";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x98";
- break;
- case 0xB0 :
- return "\xEC\x8C\xB4";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x90";
- break;
- case 0xA8 :
- return "\xEC\x8D\xAC";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x88";
- break;
- case 0xA0 :
- return "\xEC\x8E\xA4";
- break;
- case 0xBC :
- return "\xEC\x8F\x80";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\x9C";
- break;
- case 0xB4 :
- return "\xEC\x8F\xB8";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x94";
- break;
- case 0xAC :
- return "\xEC\x90\xB0";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x8C";
- break;
- case 0xA4 :
- return "\xEC\x91\xA8";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x84";
- break;
- case 0x9C :
- return "\xEC\x92\xA0";
- break;
- case 0xB8 :
- return "\xEC\x92\xBC";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x98";
- break;
- case 0xB0 :
- return "\xEC\x93\xB4";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x90";
- break;
- case 0xA8 :
- return "\xEC\x94\xAC";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x88";
- break;
- case 0xA0 :
- return "\xEC\x95\xA4";
- break;
- case 0xBC :
- return "\xEC\x96\x80";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\x9C";
- break;
- case 0xB4 :
- return "\xEC\x96\xB8";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x94";
- break;
- case 0xAC :
- return "\xEC\x97\xB0";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x8C";
- break;
- case 0xA4 :
- return "\xEC\x98\xA8";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x84";
- break;
- case 0x9C :
- return "\xEC\x99\xA0";
- break;
- case 0xB8 :
- return "\xEC\x99\xBC";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x98";
- break;
- case 0xB0 :
- return "\xEC\x9A\xB4";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x90";
- break;
- case 0xA8 :
- return "\xEC\x9B\xAC";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x88";
- break;
- case 0xA0 :
- return "\xEC\x9C\xA4";
- break;
- case 0xBC :
- return "\xEC\x9D\x80";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\x9C";
- break;
- case 0xB4 :
- return "\xEC\x9D\xB8";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x94";
- break;
- case 0xAC :
- return "\xEC\x9E\xB0";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x8C";
- break;
- case 0xA4 :
- return "\xEC\x9F\xA8";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x84";
- break;
- case 0x9C :
- return "\xEC\xA0\xA0";
- break;
- case 0xB8 :
- return "\xEC\xA0\xBC";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x98";
- break;
- case 0xB0 :
- return "\xEC\xA1\xB4";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x90";
- break;
- case 0xA8 :
- return "\xEC\xA2\xAC";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x88";
- break;
- case 0xA0 :
- return "\xEC\xA3\xA4";
- break;
- case 0xBC :
- return "\xEC\xA4\x80";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\x9C";
- break;
- case 0xB4 :
- return "\xEC\xA4\xB8";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x94";
- break;
- case 0xAC :
- return "\xEC\xA5\xB0";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x8C";
- break;
- case 0xA4 :
- return "\xEC\xA6\xA8";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x84";
- break;
- case 0x9C :
- return "\xEC\xA7\xA0";
- break;
- case 0xB8 :
- return "\xEC\xA7\xBC";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x98";
- break;
- case 0xB0 :
- return "\xEC\xA8\xB4";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x90";
- break;
- case 0xA8 :
- return "\xEC\xA9\xAC";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x88";
- break;
- case 0xA0 :
- return "\xEC\xAA\xA4";
- break;
- case 0xBC :
- return "\xEC\xAB\x80";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\x9C";
- break;
- case 0xB4 :
- return "\xEC\xAB\xB8";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x94";
- break;
- case 0xAC :
- return "\xEC\xAC\xB0";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x8C";
- break;
- case 0xA4 :
- return "\xEC\xAD\xA8";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x84";
- break;
- case 0x9C :
- return "\xEC\xAE\xA0";
- break;
- case 0xB8 :
- return "\xEC\xAE\xBC";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x98";
- break;
- case 0xB0 :
- return "\xEC\xAF\xB4";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x90";
- break;
- case 0xA8 :
- return "\xEC\xB0\xAC";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x88";
- break;
- case 0xA0 :
- return "\xEC\xB1\xA4";
- break;
- case 0xBC :
- return "\xEC\xB2\x80";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\x9C";
- break;
- case 0xB4 :
- return "\xEC\xB2\xB8";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x94";
- break;
- case 0xAC :
- return "\xEC\xB3\xB0";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x8C";
- break;
- case 0xA4 :
- return "\xEC\xB4\xA8";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x84";
- break;
- case 0x9C :
- return "\xEC\xB5\xA0";
- break;
- case 0xB8 :
- return "\xEC\xB5\xBC";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x98";
- break;
- case 0xB0 :
- return "\xEC\xB6\xB4";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x90";
- break;
- case 0xA8 :
- return "\xEC\xB7\xAC";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x88";
- break;
- case 0xA0 :
- return "\xEC\xB8\xA4";
- break;
- case 0xBC :
- return "\xEC\xB9\x80";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\x9C";
- break;
- case 0xB4 :
- return "\xEC\xB9\xB8";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x94";
- break;
- case 0xAC :
- return "\xEC\xBA\xB0";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x8C";
- break;
- case 0xA4 :
- return "\xEC\xBB\xA8";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x84";
- break;
- case 0x9C :
- return "\xEC\xBC\xA0";
- break;
- case 0xB8 :
- return "\xEC\xBC\xBC";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x98";
- break;
- case 0xB0 :
- return "\xEC\xBD\xB4";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x90";
- break;
- case 0xA8 :
- return "\xEC\xBE\xAC";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x88";
- break;
- case 0xA0 :
- return "\xEC\xBF\xA4";
- break;
- case 0xBC :
- return "\xED\x80\x80";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\x9C";
- break;
- case 0xB4 :
- return "\xED\x80\xB8";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x94";
- break;
- case 0xAC :
- return "\xED\x81\xB0";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x8C";
- break;
- case 0xA4 :
- return "\xED\x82\xA8";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x84";
- break;
- case 0x9C :
- return "\xED\x83\xA0";
- break;
- case 0xB8 :
- return "\xED\x83\xBC";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x98";
- break;
- case 0xB0 :
- return "\xED\x84\xB4";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x90";
- break;
- case 0xA8 :
- return "\xED\x85\xAC";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x88";
- break;
- case 0xA0 :
- return "\xED\x86\xA4";
- break;
- case 0xBC :
- return "\xED\x87\x80";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\x9C";
- break;
- case 0xB4 :
- return "\xED\x87\xB8";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x94";
- break;
- case 0xAC :
- return "\xED\x88\xB0";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x8C";
- break;
- case 0xA4 :
- return "\xED\x89\xA8";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x84";
- break;
- case 0x9C :
- return "\xED\x8A\xA0";
- break;
- case 0xB8 :
- return "\xED\x8A\xBC";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x98";
- break;
- case 0xB0 :
- return "\xED\x8B\xB4";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x90";
- break;
- case 0xA8 :
- return "\xED\x8C\xAC";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x88";
- break;
- case 0xA0 :
- return "\xED\x8D\xA4";
- break;
- case 0xBC :
- return "\xED\x8E\x80";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\x9C";
- break;
- case 0xB4 :
- return "\xED\x8E\xB8";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x94";
- break;
- case 0xAC :
- return "\xED\x8F\xB0";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x8C";
- break;
- case 0xA4 :
- return "\xED\x90\xA8";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x84";
- break;
- case 0x9C :
- return "\xED\x91\xA0";
- break;
- case 0xB8 :
- return "\xED\x91\xBC";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x98";
- break;
- case 0xB0 :
- return "\xED\x92\xB4";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x90";
- break;
- case 0xA8 :
- return "\xED\x93\xAC";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x88";
- break;
- case 0xA0 :
- return "\xED\x94\xA4";
- break;
- case 0xBC :
- return "\xED\x95\x80";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\x9C";
- break;
- case 0xB4 :
- return "\xED\x95\xB8";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x94";
- break;
- case 0xAC :
- return "\xED\x96\xB0";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x8C";
- break;
- case 0xA4 :
- return "\xED\x97\xA8";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x84";
- break;
- case 0x9C :
- return "\xED\x98\xA0";
- break;
- case 0xB8 :
- return "\xED\x98\xBC";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x98";
- break;
- case 0xB0 :
- return "\xED\x99\xB4";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x90";
- break;
- case 0xA8 :
- return "\xED\x9A\xAC";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x88";
- break;
- case 0xA0 :
- return "\xED\x9B\xA4";
- break;
- case 0xBC :
- return "\xED\x9C\x80";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\x9C";
- break;
- case 0xB4 :
- return "\xED\x9C\xB8";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x94";
- break;
- case 0xAC :
- return "\xED\x9D\xB0";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x8C";
- }
- break;
- }
- break;
- }
- break;
- case 0xAC :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x85";
- break;
- case 0x9C :
- return "\xEA\xB0\xA1";
- break;
- case 0xB8 :
- return "\xEA\xB0\xBD";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x99";
- break;
- case 0xB0 :
- return "\xEA\xB1\xB5";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x91";
- break;
- case 0xA8 :
- return "\xEA\xB2\xAD";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x89";
- break;
- case 0xA0 :
- return "\xEA\xB3\xA5";
- break;
- case 0xBC :
- return "\xEA\xB4\x81";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\x9D";
- break;
- case 0xB4 :
- return "\xEA\xB4\xB9";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x95";
- break;
- case 0xAC :
- return "\xEA\xB5\xB1";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x8D";
- break;
- case 0xA4 :
- return "\xEA\xB6\xA9";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x85";
- break;
- case 0x9C :
- return "\xEA\xB7\xA1";
- break;
- case 0xB8 :
- return "\xEA\xB7\xBD";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x99";
- break;
- case 0xB0 :
- return "\xEA\xB8\xB5";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x91";
- break;
- case 0xA8 :
- return "\xEA\xB9\xAD";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x89";
- break;
- case 0xA0 :
- return "\xEA\xBA\xA5";
- break;
- case 0xBC :
- return "\xEA\xBB\x81";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\x9D";
- break;
- case 0xB4 :
- return "\xEA\xBB\xB9";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x95";
- break;
- case 0xAC :
- return "\xEA\xBC\xB1";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x8D";
- break;
- case 0xA4 :
- return "\xEA\xBD\xA9";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x85";
- break;
- case 0x9C :
- return "\xEA\xBE\xA1";
- break;
- case 0xB8 :
- return "\xEA\xBE\xBD";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x99";
- break;
- case 0xB0 :
- return "\xEA\xBF\xB5";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x91";
- break;
- case 0xA8 :
- return "\xEB\x80\xAD";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x89";
- break;
- case 0xA0 :
- return "\xEB\x81\xA5";
- break;
- case 0xBC :
- return "\xEB\x82\x81";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\x9D";
- break;
- case 0xB4 :
- return "\xEB\x82\xB9";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x95";
- break;
- case 0xAC :
- return "\xEB\x83\xB1";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x8D";
- break;
- case 0xA4 :
- return "\xEB\x84\xA9";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x85";
- break;
- case 0x9C :
- return "\xEB\x85\xA1";
- break;
- case 0xB8 :
- return "\xEB\x85\xBD";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x99";
- break;
- case 0xB0 :
- return "\xEB\x86\xB5";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x91";
- break;
- case 0xA8 :
- return "\xEB\x87\xAD";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x89";
- break;
- case 0xA0 :
- return "\xEB\x88\xA5";
- break;
- case 0xBC :
- return "\xEB\x89\x81";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\x9D";
- break;
- case 0xB4 :
- return "\xEB\x89\xB9";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x95";
- break;
- case 0xAC :
- return "\xEB\x8A\xB1";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x8D";
- break;
- case 0xA4 :
- return "\xEB\x8B\xA9";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x85";
- break;
- case 0x9C :
- return "\xEB\x8C\xA1";
- break;
- case 0xB8 :
- return "\xEB\x8C\xBD";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x99";
- break;
- case 0xB0 :
- return "\xEB\x8D\xB5";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x91";
- break;
- case 0xA8 :
- return "\xEB\x8E\xAD";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x89";
- break;
- case 0xA0 :
- return "\xEB\x8F\xA5";
- break;
- case 0xBC :
- return "\xEB\x90\x81";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\x9D";
- break;
- case 0xB4 :
- return "\xEB\x90\xB9";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x95";
- break;
- case 0xAC :
- return "\xEB\x91\xB1";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x8D";
- break;
- case 0xA4 :
- return "\xEB\x92\xA9";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x85";
- break;
- case 0x9C :
- return "\xEB\x93\xA1";
- break;
- case 0xB8 :
- return "\xEB\x93\xBD";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x99";
- break;
- case 0xB0 :
- return "\xEB\x94\xB5";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x91";
- break;
- case 0xA8 :
- return "\xEB\x95\xAD";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x89";
- break;
- case 0xA0 :
- return "\xEB\x96\xA5";
- break;
- case 0xBC :
- return "\xEB\x97\x81";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\x9D";
- break;
- case 0xB4 :
- return "\xEB\x97\xB9";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x95";
- break;
- case 0xAC :
- return "\xEB\x98\xB1";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x8D";
- break;
- case 0xA4 :
- return "\xEB\x99\xA9";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x85";
- break;
- case 0x9C :
- return "\xEB\x9A\xA1";
- break;
- case 0xB8 :
- return "\xEB\x9A\xBD";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x99";
- break;
- case 0xB0 :
- return "\xEB\x9B\xB5";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x91";
- break;
- case 0xA8 :
- return "\xEB\x9C\xAD";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x89";
- break;
- case 0xA0 :
- return "\xEB\x9D\xA5";
- break;
- case 0xBC :
- return "\xEB\x9E\x81";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\x9D";
- break;
- case 0xB4 :
- return "\xEB\x9E\xB9";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x95";
- break;
- case 0xAC :
- return "\xEB\x9F\xB1";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x8D";
- break;
- case 0xA4 :
- return "\xEB\xA0\xA9";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x85";
- break;
- case 0x9C :
- return "\xEB\xA1\xA1";
- break;
- case 0xB8 :
- return "\xEB\xA1\xBD";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x99";
- break;
- case 0xB0 :
- return "\xEB\xA2\xB5";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x91";
- break;
- case 0xA8 :
- return "\xEB\xA3\xAD";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x89";
- break;
- case 0xA0 :
- return "\xEB\xA4\xA5";
- break;
- case 0xBC :
- return "\xEB\xA5\x81";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\x9D";
- break;
- case 0xB4 :
- return "\xEB\xA5\xB9";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x95";
- break;
- case 0xAC :
- return "\xEB\xA6\xB1";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x8D";
- break;
- case 0xA4 :
- return "\xEB\xA7\xA9";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x85";
- break;
- case 0x9C :
- return "\xEB\xA8\xA1";
- break;
- case 0xB8 :
- return "\xEB\xA8\xBD";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x99";
- break;
- case 0xB0 :
- return "\xEB\xA9\xB5";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x91";
- break;
- case 0xA8 :
- return "\xEB\xAA\xAD";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x89";
- break;
- case 0xA0 :
- return "\xEB\xAB\xA5";
- break;
- case 0xBC :
- return "\xEB\xAC\x81";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\x9D";
- break;
- case 0xB4 :
- return "\xEB\xAC\xB9";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x95";
- break;
- case 0xAC :
- return "\xEB\xAD\xB1";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x8D";
- break;
- case 0xA4 :
- return "\xEB\xAE\xA9";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x85";
- break;
- case 0x9C :
- return "\xEB\xAF\xA1";
- break;
- case 0xB8 :
- return "\xEB\xAF\xBD";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x99";
- break;
- case 0xB0 :
- return "\xEB\xB0\xB5";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x91";
- break;
- case 0xA8 :
- return "\xEB\xB1\xAD";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x89";
- break;
- case 0xA0 :
- return "\xEB\xB2\xA5";
- break;
- case 0xBC :
- return "\xEB\xB3\x81";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\x9D";
- break;
- case 0xB4 :
- return "\xEB\xB3\xB9";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x95";
- break;
- case 0xAC :
- return "\xEB\xB4\xB1";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x8D";
- break;
- case 0xA4 :
- return "\xEB\xB5\xA9";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x85";
- break;
- case 0x9C :
- return "\xEB\xB6\xA1";
- break;
- case 0xB8 :
- return "\xEB\xB6\xBD";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x99";
- break;
- case 0xB0 :
- return "\xEB\xB7\xB5";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x91";
- break;
- case 0xA8 :
- return "\xEB\xB8\xAD";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x89";
- break;
- case 0xA0 :
- return "\xEB\xB9\xA5";
- break;
- case 0xBC :
- return "\xEB\xBA\x81";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\x9D";
- break;
- case 0xB4 :
- return "\xEB\xBA\xB9";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x95";
- break;
- case 0xAC :
- return "\xEB\xBB\xB1";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x8D";
- break;
- case 0xA4 :
- return "\xEB\xBC\xA9";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x85";
- break;
- case 0x9C :
- return "\xEB\xBD\xA1";
- break;
- case 0xB8 :
- return "\xEB\xBD\xBD";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x99";
- break;
- case 0xB0 :
- return "\xEB\xBE\xB5";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x91";
- break;
- case 0xA8 :
- return "\xEB\xBF\xAD";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x89";
- break;
- case 0xA0 :
- return "\xEC\x80\xA5";
- break;
- case 0xBC :
- return "\xEC\x81\x81";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\x9D";
- break;
- case 0xB4 :
- return "\xEC\x81\xB9";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x95";
- break;
- case 0xAC :
- return "\xEC\x82\xB1";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x8D";
- break;
- case 0xA4 :
- return "\xEC\x83\xA9";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x85";
- break;
- case 0x9C :
- return "\xEC\x84\xA1";
- break;
- case 0xB8 :
- return "\xEC\x84\xBD";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x99";
- break;
- case 0xB0 :
- return "\xEC\x85\xB5";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x91";
- break;
- case 0xA8 :
- return "\xEC\x86\xAD";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x89";
- break;
- case 0xA0 :
- return "\xEC\x87\xA5";
- break;
- case 0xBC :
- return "\xEC\x88\x81";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\x9D";
- break;
- case 0xB4 :
- return "\xEC\x88\xB9";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x95";
- break;
- case 0xAC :
- return "\xEC\x89\xB1";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x8D";
- break;
- case 0xA4 :
- return "\xEC\x8A\xA9";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x85";
- break;
- case 0x9C :
- return "\xEC\x8B\xA1";
- break;
- case 0xB8 :
- return "\xEC\x8B\xBD";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x99";
- break;
- case 0xB0 :
- return "\xEC\x8C\xB5";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x91";
- break;
- case 0xA8 :
- return "\xEC\x8D\xAD";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x89";
- break;
- case 0xA0 :
- return "\xEC\x8E\xA5";
- break;
- case 0xBC :
- return "\xEC\x8F\x81";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\x9D";
- break;
- case 0xB4 :
- return "\xEC\x8F\xB9";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x95";
- break;
- case 0xAC :
- return "\xEC\x90\xB1";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x8D";
- break;
- case 0xA4 :
- return "\xEC\x91\xA9";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x85";
- break;
- case 0x9C :
- return "\xEC\x92\xA1";
- break;
- case 0xB8 :
- return "\xEC\x92\xBD";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x99";
- break;
- case 0xB0 :
- return "\xEC\x93\xB5";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x91";
- break;
- case 0xA8 :
- return "\xEC\x94\xAD";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x89";
- break;
- case 0xA0 :
- return "\xEC\x95\xA5";
- break;
- case 0xBC :
- return "\xEC\x96\x81";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\x9D";
- break;
- case 0xB4 :
- return "\xEC\x96\xB9";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x95";
- break;
- case 0xAC :
- return "\xEC\x97\xB1";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x8D";
- break;
- case 0xA4 :
- return "\xEC\x98\xA9";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x85";
- break;
- case 0x9C :
- return "\xEC\x99\xA1";
- break;
- case 0xB8 :
- return "\xEC\x99\xBD";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x99";
- break;
- case 0xB0 :
- return "\xEC\x9A\xB5";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x91";
- break;
- case 0xA8 :
- return "\xEC\x9B\xAD";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x89";
- break;
- case 0xA0 :
- return "\xEC\x9C\xA5";
- break;
- case 0xBC :
- return "\xEC\x9D\x81";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\x9D";
- break;
- case 0xB4 :
- return "\xEC\x9D\xB9";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x95";
- break;
- case 0xAC :
- return "\xEC\x9E\xB1";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x8D";
- break;
- case 0xA4 :
- return "\xEC\x9F\xA9";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x85";
- break;
- case 0x9C :
- return "\xEC\xA0\xA1";
- break;
- case 0xB8 :
- return "\xEC\xA0\xBD";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x99";
- break;
- case 0xB0 :
- return "\xEC\xA1\xB5";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x91";
- break;
- case 0xA8 :
- return "\xEC\xA2\xAD";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x89";
- break;
- case 0xA0 :
- return "\xEC\xA3\xA5";
- break;
- case 0xBC :
- return "\xEC\xA4\x81";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\x9D";
- break;
- case 0xB4 :
- return "\xEC\xA4\xB9";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x95";
- break;
- case 0xAC :
- return "\xEC\xA5\xB1";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x8D";
- break;
- case 0xA4 :
- return "\xEC\xA6\xA9";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x85";
- break;
- case 0x9C :
- return "\xEC\xA7\xA1";
- break;
- case 0xB8 :
- return "\xEC\xA7\xBD";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x99";
- break;
- case 0xB0 :
- return "\xEC\xA8\xB5";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x91";
- break;
- case 0xA8 :
- return "\xEC\xA9\xAD";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x89";
- break;
- case 0xA0 :
- return "\xEC\xAA\xA5";
- break;
- case 0xBC :
- return "\xEC\xAB\x81";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\x9D";
- break;
- case 0xB4 :
- return "\xEC\xAB\xB9";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x95";
- break;
- case 0xAC :
- return "\xEC\xAC\xB1";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x8D";
- break;
- case 0xA4 :
- return "\xEC\xAD\xA9";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x85";
- break;
- case 0x9C :
- return "\xEC\xAE\xA1";
- break;
- case 0xB8 :
- return "\xEC\xAE\xBD";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x99";
- break;
- case 0xB0 :
- return "\xEC\xAF\xB5";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x91";
- break;
- case 0xA8 :
- return "\xEC\xB0\xAD";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x89";
- break;
- case 0xA0 :
- return "\xEC\xB1\xA5";
- break;
- case 0xBC :
- return "\xEC\xB2\x81";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\x9D";
- break;
- case 0xB4 :
- return "\xEC\xB2\xB9";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x95";
- break;
- case 0xAC :
- return "\xEC\xB3\xB1";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x8D";
- break;
- case 0xA4 :
- return "\xEC\xB4\xA9";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x85";
- break;
- case 0x9C :
- return "\xEC\xB5\xA1";
- break;
- case 0xB8 :
- return "\xEC\xB5\xBD";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x99";
- break;
- case 0xB0 :
- return "\xEC\xB6\xB5";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x91";
- break;
- case 0xA8 :
- return "\xEC\xB7\xAD";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x89";
- break;
- case 0xA0 :
- return "\xEC\xB8\xA5";
- break;
- case 0xBC :
- return "\xEC\xB9\x81";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\x9D";
- break;
- case 0xB4 :
- return "\xEC\xB9\xB9";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x95";
- break;
- case 0xAC :
- return "\xEC\xBA\xB1";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x8D";
- break;
- case 0xA4 :
- return "\xEC\xBB\xA9";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x85";
- break;
- case 0x9C :
- return "\xEC\xBC\xA1";
- break;
- case 0xB8 :
- return "\xEC\xBC\xBD";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x99";
- break;
- case 0xB0 :
- return "\xEC\xBD\xB5";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x91";
- break;
- case 0xA8 :
- return "\xEC\xBE\xAD";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x89";
- break;
- case 0xA0 :
- return "\xEC\xBF\xA5";
- break;
- case 0xBC :
- return "\xED\x80\x81";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\x9D";
- break;
- case 0xB4 :
- return "\xED\x80\xB9";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x95";
- break;
- case 0xAC :
- return "\xED\x81\xB1";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x8D";
- break;
- case 0xA4 :
- return "\xED\x82\xA9";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x85";
- break;
- case 0x9C :
- return "\xED\x83\xA1";
- break;
- case 0xB8 :
- return "\xED\x83\xBD";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x99";
- break;
- case 0xB0 :
- return "\xED\x84\xB5";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x91";
- break;
- case 0xA8 :
- return "\xED\x85\xAD";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x89";
- break;
- case 0xA0 :
- return "\xED\x86\xA5";
- break;
- case 0xBC :
- return "\xED\x87\x81";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\x9D";
- break;
- case 0xB4 :
- return "\xED\x87\xB9";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x95";
- break;
- case 0xAC :
- return "\xED\x88\xB1";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x8D";
- break;
- case 0xA4 :
- return "\xED\x89\xA9";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x85";
- break;
- case 0x9C :
- return "\xED\x8A\xA1";
- break;
- case 0xB8 :
- return "\xED\x8A\xBD";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x99";
- break;
- case 0xB0 :
- return "\xED\x8B\xB5";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x91";
- break;
- case 0xA8 :
- return "\xED\x8C\xAD";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x89";
- break;
- case 0xA0 :
- return "\xED\x8D\xA5";
- break;
- case 0xBC :
- return "\xED\x8E\x81";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\x9D";
- break;
- case 0xB4 :
- return "\xED\x8E\xB9";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x95";
- break;
- case 0xAC :
- return "\xED\x8F\xB1";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x8D";
- break;
- case 0xA4 :
- return "\xED\x90\xA9";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x85";
- break;
- case 0x9C :
- return "\xED\x91\xA1";
- break;
- case 0xB8 :
- return "\xED\x91\xBD";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x99";
- break;
- case 0xB0 :
- return "\xED\x92\xB5";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x91";
- break;
- case 0xA8 :
- return "\xED\x93\xAD";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x89";
- break;
- case 0xA0 :
- return "\xED\x94\xA5";
- break;
- case 0xBC :
- return "\xED\x95\x81";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\x9D";
- break;
- case 0xB4 :
- return "\xED\x95\xB9";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x95";
- break;
- case 0xAC :
- return "\xED\x96\xB1";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x8D";
- break;
- case 0xA4 :
- return "\xED\x97\xA9";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x85";
- break;
- case 0x9C :
- return "\xED\x98\xA1";
- break;
- case 0xB8 :
- return "\xED\x98\xBD";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x99";
- break;
- case 0xB0 :
- return "\xED\x99\xB5";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x91";
- break;
- case 0xA8 :
- return "\xED\x9A\xAD";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x89";
- break;
- case 0xA0 :
- return "\xED\x9B\xA5";
- break;
- case 0xBC :
- return "\xED\x9C\x81";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\x9D";
- break;
- case 0xB4 :
- return "\xED\x9C\xB9";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x95";
- break;
- case 0xAC :
- return "\xED\x9D\xB1";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x8D";
- }
- break;
- }
- break;
- }
- break;
- case 0xAD :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x86";
- break;
- case 0x9C :
- return "\xEA\xB0\xA2";
- break;
- case 0xB8 :
- return "\xEA\xB0\xBE";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x9A";
- break;
- case 0xB0 :
- return "\xEA\xB1\xB6";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x92";
- break;
- case 0xA8 :
- return "\xEA\xB2\xAE";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x8A";
- break;
- case 0xA0 :
- return "\xEA\xB3\xA6";
- break;
- case 0xBC :
- return "\xEA\xB4\x82";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\x9E";
- break;
- case 0xB4 :
- return "\xEA\xB4\xBA";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x96";
- break;
- case 0xAC :
- return "\xEA\xB5\xB2";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x8E";
- break;
- case 0xA4 :
- return "\xEA\xB6\xAA";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x86";
- break;
- case 0x9C :
- return "\xEA\xB7\xA2";
- break;
- case 0xB8 :
- return "\xEA\xB7\xBE";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x9A";
- break;
- case 0xB0 :
- return "\xEA\xB8\xB6";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x92";
- break;
- case 0xA8 :
- return "\xEA\xB9\xAE";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x8A";
- break;
- case 0xA0 :
- return "\xEA\xBA\xA6";
- break;
- case 0xBC :
- return "\xEA\xBB\x82";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\x9E";
- break;
- case 0xB4 :
- return "\xEA\xBB\xBA";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x96";
- break;
- case 0xAC :
- return "\xEA\xBC\xB2";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x8E";
- break;
- case 0xA4 :
- return "\xEA\xBD\xAA";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x86";
- break;
- case 0x9C :
- return "\xEA\xBE\xA2";
- break;
- case 0xB8 :
- return "\xEA\xBE\xBE";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x9A";
- break;
- case 0xB0 :
- return "\xEA\xBF\xB6";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x92";
- break;
- case 0xA8 :
- return "\xEB\x80\xAE";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x8A";
- break;
- case 0xA0 :
- return "\xEB\x81\xA6";
- break;
- case 0xBC :
- return "\xEB\x82\x82";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\x9E";
- break;
- case 0xB4 :
- return "\xEB\x82\xBA";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x96";
- break;
- case 0xAC :
- return "\xEB\x83\xB2";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x8E";
- break;
- case 0xA4 :
- return "\xEB\x84\xAA";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x86";
- break;
- case 0x9C :
- return "\xEB\x85\xA2";
- break;
- case 0xB8 :
- return "\xEB\x85\xBE";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x9A";
- break;
- case 0xB0 :
- return "\xEB\x86\xB6";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x92";
- break;
- case 0xA8 :
- return "\xEB\x87\xAE";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x8A";
- break;
- case 0xA0 :
- return "\xEB\x88\xA6";
- break;
- case 0xBC :
- return "\xEB\x89\x82";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\x9E";
- break;
- case 0xB4 :
- return "\xEB\x89\xBA";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x96";
- break;
- case 0xAC :
- return "\xEB\x8A\xB2";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x8E";
- break;
- case 0xA4 :
- return "\xEB\x8B\xAA";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x86";
- break;
- case 0x9C :
- return "\xEB\x8C\xA2";
- break;
- case 0xB8 :
- return "\xEB\x8C\xBE";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x9A";
- break;
- case 0xB0 :
- return "\xEB\x8D\xB6";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x92";
- break;
- case 0xA8 :
- return "\xEB\x8E\xAE";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x8A";
- break;
- case 0xA0 :
- return "\xEB\x8F\xA6";
- break;
- case 0xBC :
- return "\xEB\x90\x82";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\x9E";
- break;
- case 0xB4 :
- return "\xEB\x90\xBA";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x96";
- break;
- case 0xAC :
- return "\xEB\x91\xB2";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x8E";
- break;
- case 0xA4 :
- return "\xEB\x92\xAA";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x86";
- break;
- case 0x9C :
- return "\xEB\x93\xA2";
- break;
- case 0xB8 :
- return "\xEB\x93\xBE";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x9A";
- break;
- case 0xB0 :
- return "\xEB\x94\xB6";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x92";
- break;
- case 0xA8 :
- return "\xEB\x95\xAE";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x8A";
- break;
- case 0xA0 :
- return "\xEB\x96\xA6";
- break;
- case 0xBC :
- return "\xEB\x97\x82";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\x9E";
- break;
- case 0xB4 :
- return "\xEB\x97\xBA";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x96";
- break;
- case 0xAC :
- return "\xEB\x98\xB2";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x8E";
- break;
- case 0xA4 :
- return "\xEB\x99\xAA";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x86";
- break;
- case 0x9C :
- return "\xEB\x9A\xA2";
- break;
- case 0xB8 :
- return "\xEB\x9A\xBE";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x9A";
- break;
- case 0xB0 :
- return "\xEB\x9B\xB6";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x92";
- break;
- case 0xA8 :
- return "\xEB\x9C\xAE";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x8A";
- break;
- case 0xA0 :
- return "\xEB\x9D\xA6";
- break;
- case 0xBC :
- return "\xEB\x9E\x82";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\x9E";
- break;
- case 0xB4 :
- return "\xEB\x9E\xBA";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x96";
- break;
- case 0xAC :
- return "\xEB\x9F\xB2";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x8E";
- break;
- case 0xA4 :
- return "\xEB\xA0\xAA";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x86";
- break;
- case 0x9C :
- return "\xEB\xA1\xA2";
- break;
- case 0xB8 :
- return "\xEB\xA1\xBE";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x9A";
- break;
- case 0xB0 :
- return "\xEB\xA2\xB6";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x92";
- break;
- case 0xA8 :
- return "\xEB\xA3\xAE";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x8A";
- break;
- case 0xA0 :
- return "\xEB\xA4\xA6";
- break;
- case 0xBC :
- return "\xEB\xA5\x82";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\x9E";
- break;
- case 0xB4 :
- return "\xEB\xA5\xBA";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x96";
- break;
- case 0xAC :
- return "\xEB\xA6\xB2";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x8E";
- break;
- case 0xA4 :
- return "\xEB\xA7\xAA";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x86";
- break;
- case 0x9C :
- return "\xEB\xA8\xA2";
- break;
- case 0xB8 :
- return "\xEB\xA8\xBE";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x9A";
- break;
- case 0xB0 :
- return "\xEB\xA9\xB6";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x92";
- break;
- case 0xA8 :
- return "\xEB\xAA\xAE";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x8A";
- break;
- case 0xA0 :
- return "\xEB\xAB\xA6";
- break;
- case 0xBC :
- return "\xEB\xAC\x82";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\x9E";
- break;
- case 0xB4 :
- return "\xEB\xAC\xBA";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x96";
- break;
- case 0xAC :
- return "\xEB\xAD\xB2";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x8E";
- break;
- case 0xA4 :
- return "\xEB\xAE\xAA";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x86";
- break;
- case 0x9C :
- return "\xEB\xAF\xA2";
- break;
- case 0xB8 :
- return "\xEB\xAF\xBE";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x9A";
- break;
- case 0xB0 :
- return "\xEB\xB0\xB6";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x92";
- break;
- case 0xA8 :
- return "\xEB\xB1\xAE";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x8A";
- break;
- case 0xA0 :
- return "\xEB\xB2\xA6";
- break;
- case 0xBC :
- return "\xEB\xB3\x82";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\x9E";
- break;
- case 0xB4 :
- return "\xEB\xB3\xBA";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x96";
- break;
- case 0xAC :
- return "\xEB\xB4\xB2";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x8E";
- break;
- case 0xA4 :
- return "\xEB\xB5\xAA";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x86";
- break;
- case 0x9C :
- return "\xEB\xB6\xA2";
- break;
- case 0xB8 :
- return "\xEB\xB6\xBE";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x9A";
- break;
- case 0xB0 :
- return "\xEB\xB7\xB6";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x92";
- break;
- case 0xA8 :
- return "\xEB\xB8\xAE";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x8A";
- break;
- case 0xA0 :
- return "\xEB\xB9\xA6";
- break;
- case 0xBC :
- return "\xEB\xBA\x82";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\x9E";
- break;
- case 0xB4 :
- return "\xEB\xBA\xBA";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x96";
- break;
- case 0xAC :
- return "\xEB\xBB\xB2";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x8E";
- break;
- case 0xA4 :
- return "\xEB\xBC\xAA";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x86";
- break;
- case 0x9C :
- return "\xEB\xBD\xA2";
- break;
- case 0xB8 :
- return "\xEB\xBD\xBE";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x9A";
- break;
- case 0xB0 :
- return "\xEB\xBE\xB6";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x92";
- break;
- case 0xA8 :
- return "\xEB\xBF\xAE";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x8A";
- break;
- case 0xA0 :
- return "\xEC\x80\xA6";
- break;
- case 0xBC :
- return "\xEC\x81\x82";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\x9E";
- break;
- case 0xB4 :
- return "\xEC\x81\xBA";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x96";
- break;
- case 0xAC :
- return "\xEC\x82\xB2";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x8E";
- break;
- case 0xA4 :
- return "\xEC\x83\xAA";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x86";
- break;
- case 0x9C :
- return "\xEC\x84\xA2";
- break;
- case 0xB8 :
- return "\xEC\x84\xBE";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x9A";
- break;
- case 0xB0 :
- return "\xEC\x85\xB6";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x92";
- break;
- case 0xA8 :
- return "\xEC\x86\xAE";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x8A";
- break;
- case 0xA0 :
- return "\xEC\x87\xA6";
- break;
- case 0xBC :
- return "\xEC\x88\x82";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\x9E";
- break;
- case 0xB4 :
- return "\xEC\x88\xBA";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x96";
- break;
- case 0xAC :
- return "\xEC\x89\xB2";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x8E";
- break;
- case 0xA4 :
- return "\xEC\x8A\xAA";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x86";
- break;
- case 0x9C :
- return "\xEC\x8B\xA2";
- break;
- case 0xB8 :
- return "\xEC\x8B\xBE";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x9A";
- break;
- case 0xB0 :
- return "\xEC\x8C\xB6";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x92";
- break;
- case 0xA8 :
- return "\xEC\x8D\xAE";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x8A";
- break;
- case 0xA0 :
- return "\xEC\x8E\xA6";
- break;
- case 0xBC :
- return "\xEC\x8F\x82";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\x9E";
- break;
- case 0xB4 :
- return "\xEC\x8F\xBA";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x96";
- break;
- case 0xAC :
- return "\xEC\x90\xB2";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x8E";
- break;
- case 0xA4 :
- return "\xEC\x91\xAA";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x86";
- break;
- case 0x9C :
- return "\xEC\x92\xA2";
- break;
- case 0xB8 :
- return "\xEC\x92\xBE";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x9A";
- break;
- case 0xB0 :
- return "\xEC\x93\xB6";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x92";
- break;
- case 0xA8 :
- return "\xEC\x94\xAE";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x8A";
- break;
- case 0xA0 :
- return "\xEC\x95\xA6";
- break;
- case 0xBC :
- return "\xEC\x96\x82";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\x9E";
- break;
- case 0xB4 :
- return "\xEC\x96\xBA";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x96";
- break;
- case 0xAC :
- return "\xEC\x97\xB2";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x8E";
- break;
- case 0xA4 :
- return "\xEC\x98\xAA";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x86";
- break;
- case 0x9C :
- return "\xEC\x99\xA2";
- break;
- case 0xB8 :
- return "\xEC\x99\xBE";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x9A";
- break;
- case 0xB0 :
- return "\xEC\x9A\xB6";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x92";
- break;
- case 0xA8 :
- return "\xEC\x9B\xAE";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x8A";
- break;
- case 0xA0 :
- return "\xEC\x9C\xA6";
- break;
- case 0xBC :
- return "\xEC\x9D\x82";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\x9E";
- break;
- case 0xB4 :
- return "\xEC\x9D\xBA";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x96";
- break;
- case 0xAC :
- return "\xEC\x9E\xB2";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x8E";
- break;
- case 0xA4 :
- return "\xEC\x9F\xAA";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x86";
- break;
- case 0x9C :
- return "\xEC\xA0\xA2";
- break;
- case 0xB8 :
- return "\xEC\xA0\xBE";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x9A";
- break;
- case 0xB0 :
- return "\xEC\xA1\xB6";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x92";
- break;
- case 0xA8 :
- return "\xEC\xA2\xAE";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x8A";
- break;
- case 0xA0 :
- return "\xEC\xA3\xA6";
- break;
- case 0xBC :
- return "\xEC\xA4\x82";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\x9E";
- break;
- case 0xB4 :
- return "\xEC\xA4\xBA";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x96";
- break;
- case 0xAC :
- return "\xEC\xA5\xB2";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x8E";
- break;
- case 0xA4 :
- return "\xEC\xA6\xAA";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x86";
- break;
- case 0x9C :
- return "\xEC\xA7\xA2";
- break;
- case 0xB8 :
- return "\xEC\xA7\xBE";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x9A";
- break;
- case 0xB0 :
- return "\xEC\xA8\xB6";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x92";
- break;
- case 0xA8 :
- return "\xEC\xA9\xAE";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x8A";
- break;
- case 0xA0 :
- return "\xEC\xAA\xA6";
- break;
- case 0xBC :
- return "\xEC\xAB\x82";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\x9E";
- break;
- case 0xB4 :
- return "\xEC\xAB\xBA";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x96";
- break;
- case 0xAC :
- return "\xEC\xAC\xB2";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x8E";
- break;
- case 0xA4 :
- return "\xEC\xAD\xAA";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x86";
- break;
- case 0x9C :
- return "\xEC\xAE\xA2";
- break;
- case 0xB8 :
- return "\xEC\xAE\xBE";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x9A";
- break;
- case 0xB0 :
- return "\xEC\xAF\xB6";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x92";
- break;
- case 0xA8 :
- return "\xEC\xB0\xAE";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x8A";
- break;
- case 0xA0 :
- return "\xEC\xB1\xA6";
- break;
- case 0xBC :
- return "\xEC\xB2\x82";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\x9E";
- break;
- case 0xB4 :
- return "\xEC\xB2\xBA";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x96";
- break;
- case 0xAC :
- return "\xEC\xB3\xB2";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x8E";
- break;
- case 0xA4 :
- return "\xEC\xB4\xAA";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x86";
- break;
- case 0x9C :
- return "\xEC\xB5\xA2";
- break;
- case 0xB8 :
- return "\xEC\xB5\xBE";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x9A";
- break;
- case 0xB0 :
- return "\xEC\xB6\xB6";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x92";
- break;
- case 0xA8 :
- return "\xEC\xB7\xAE";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x8A";
- break;
- case 0xA0 :
- return "\xEC\xB8\xA6";
- break;
- case 0xBC :
- return "\xEC\xB9\x82";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\x9E";
- break;
- case 0xB4 :
- return "\xEC\xB9\xBA";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x96";
- break;
- case 0xAC :
- return "\xEC\xBA\xB2";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x8E";
- break;
- case 0xA4 :
- return "\xEC\xBB\xAA";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x86";
- break;
- case 0x9C :
- return "\xEC\xBC\xA2";
- break;
- case 0xB8 :
- return "\xEC\xBC\xBE";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x9A";
- break;
- case 0xB0 :
- return "\xEC\xBD\xB6";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x92";
- break;
- case 0xA8 :
- return "\xEC\xBE\xAE";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x8A";
- break;
- case 0xA0 :
- return "\xEC\xBF\xA6";
- break;
- case 0xBC :
- return "\xED\x80\x82";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\x9E";
- break;
- case 0xB4 :
- return "\xED\x80\xBA";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x96";
- break;
- case 0xAC :
- return "\xED\x81\xB2";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x8E";
- break;
- case 0xA4 :
- return "\xED\x82\xAA";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x86";
- break;
- case 0x9C :
- return "\xED\x83\xA2";
- break;
- case 0xB8 :
- return "\xED\x83\xBE";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x9A";
- break;
- case 0xB0 :
- return "\xED\x84\xB6";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x92";
- break;
- case 0xA8 :
- return "\xED\x85\xAE";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x8A";
- break;
- case 0xA0 :
- return "\xED\x86\xA6";
- break;
- case 0xBC :
- return "\xED\x87\x82";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\x9E";
- break;
- case 0xB4 :
- return "\xED\x87\xBA";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x96";
- break;
- case 0xAC :
- return "\xED\x88\xB2";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x8E";
- break;
- case 0xA4 :
- return "\xED\x89\xAA";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x86";
- break;
- case 0x9C :
- return "\xED\x8A\xA2";
- break;
- case 0xB8 :
- return "\xED\x8A\xBE";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x9A";
- break;
- case 0xB0 :
- return "\xED\x8B\xB6";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x92";
- break;
- case 0xA8 :
- return "\xED\x8C\xAE";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x8A";
- break;
- case 0xA0 :
- return "\xED\x8D\xA6";
- break;
- case 0xBC :
- return "\xED\x8E\x82";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\x9E";
- break;
- case 0xB4 :
- return "\xED\x8E\xBA";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x96";
- break;
- case 0xAC :
- return "\xED\x8F\xB2";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x8E";
- break;
- case 0xA4 :
- return "\xED\x90\xAA";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x86";
- break;
- case 0x9C :
- return "\xED\x91\xA2";
- break;
- case 0xB8 :
- return "\xED\x91\xBE";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x9A";
- break;
- case 0xB0 :
- return "\xED\x92\xB6";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x92";
- break;
- case 0xA8 :
- return "\xED\x93\xAE";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x8A";
- break;
- case 0xA0 :
- return "\xED\x94\xA6";
- break;
- case 0xBC :
- return "\xED\x95\x82";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\x9E";
- break;
- case 0xB4 :
- return "\xED\x95\xBA";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x96";
- break;
- case 0xAC :
- return "\xED\x96\xB2";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x8E";
- break;
- case 0xA4 :
- return "\xED\x97\xAA";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x86";
- break;
- case 0x9C :
- return "\xED\x98\xA2";
- break;
- case 0xB8 :
- return "\xED\x98\xBE";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x9A";
- break;
- case 0xB0 :
- return "\xED\x99\xB6";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x92";
- break;
- case 0xA8 :
- return "\xED\x9A\xAE";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x8A";
- break;
- case 0xA0 :
- return "\xED\x9B\xA6";
- break;
- case 0xBC :
- return "\xED\x9C\x82";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\x9E";
- break;
- case 0xB4 :
- return "\xED\x9C\xBA";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x96";
- break;
- case 0xAC :
- return "\xED\x9D\xB2";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x8E";
- }
- break;
- }
- break;
- }
- break;
- case 0xAE :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x87";
- break;
- case 0x9C :
- return "\xEA\xB0\xA3";
- break;
- case 0xB8 :
- return "\xEA\xB0\xBF";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x9B";
- break;
- case 0xB0 :
- return "\xEA\xB1\xB7";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x93";
- break;
- case 0xA8 :
- return "\xEA\xB2\xAF";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x8B";
- break;
- case 0xA0 :
- return "\xEA\xB3\xA7";
- break;
- case 0xBC :
- return "\xEA\xB4\x83";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\x9F";
- break;
- case 0xB4 :
- return "\xEA\xB4\xBB";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x97";
- break;
- case 0xAC :
- return "\xEA\xB5\xB3";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x8F";
- break;
- case 0xA4 :
- return "\xEA\xB6\xAB";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x87";
- break;
- case 0x9C :
- return "\xEA\xB7\xA3";
- break;
- case 0xB8 :
- return "\xEA\xB7\xBF";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x9B";
- break;
- case 0xB0 :
- return "\xEA\xB8\xB7";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x93";
- break;
- case 0xA8 :
- return "\xEA\xB9\xAF";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x8B";
- break;
- case 0xA0 :
- return "\xEA\xBA\xA7";
- break;
- case 0xBC :
- return "\xEA\xBB\x83";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\x9F";
- break;
- case 0xB4 :
- return "\xEA\xBB\xBB";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x97";
- break;
- case 0xAC :
- return "\xEA\xBC\xB3";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x8F";
- break;
- case 0xA4 :
- return "\xEA\xBD\xAB";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x87";
- break;
- case 0x9C :
- return "\xEA\xBE\xA3";
- break;
- case 0xB8 :
- return "\xEA\xBE\xBF";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x9B";
- break;
- case 0xB0 :
- return "\xEA\xBF\xB7";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x93";
- break;
- case 0xA8 :
- return "\xEB\x80\xAF";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x8B";
- break;
- case 0xA0 :
- return "\xEB\x81\xA7";
- break;
- case 0xBC :
- return "\xEB\x82\x83";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\x9F";
- break;
- case 0xB4 :
- return "\xEB\x82\xBB";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x97";
- break;
- case 0xAC :
- return "\xEB\x83\xB3";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x8F";
- break;
- case 0xA4 :
- return "\xEB\x84\xAB";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x87";
- break;
- case 0x9C :
- return "\xEB\x85\xA3";
- break;
- case 0xB8 :
- return "\xEB\x85\xBF";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x9B";
- break;
- case 0xB0 :
- return "\xEB\x86\xB7";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x93";
- break;
- case 0xA8 :
- return "\xEB\x87\xAF";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x8B";
- break;
- case 0xA0 :
- return "\xEB\x88\xA7";
- break;
- case 0xBC :
- return "\xEB\x89\x83";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\x9F";
- break;
- case 0xB4 :
- return "\xEB\x89\xBB";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x97";
- break;
- case 0xAC :
- return "\xEB\x8A\xB3";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x8F";
- break;
- case 0xA4 :
- return "\xEB\x8B\xAB";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x87";
- break;
- case 0x9C :
- return "\xEB\x8C\xA3";
- break;
- case 0xB8 :
- return "\xEB\x8C\xBF";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x9B";
- break;
- case 0xB0 :
- return "\xEB\x8D\xB7";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x93";
- break;
- case 0xA8 :
- return "\xEB\x8E\xAF";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x8B";
- break;
- case 0xA0 :
- return "\xEB\x8F\xA7";
- break;
- case 0xBC :
- return "\xEB\x90\x83";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\x9F";
- break;
- case 0xB4 :
- return "\xEB\x90\xBB";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x97";
- break;
- case 0xAC :
- return "\xEB\x91\xB3";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x8F";
- break;
- case 0xA4 :
- return "\xEB\x92\xAB";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x87";
- break;
- case 0x9C :
- return "\xEB\x93\xA3";
- break;
- case 0xB8 :
- return "\xEB\x93\xBF";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x9B";
- break;
- case 0xB0 :
- return "\xEB\x94\xB7";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x93";
- break;
- case 0xA8 :
- return "\xEB\x95\xAF";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x8B";
- break;
- case 0xA0 :
- return "\xEB\x96\xA7";
- break;
- case 0xBC :
- return "\xEB\x97\x83";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\x9F";
- break;
- case 0xB4 :
- return "\xEB\x97\xBB";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x97";
- break;
- case 0xAC :
- return "\xEB\x98\xB3";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x8F";
- break;
- case 0xA4 :
- return "\xEB\x99\xAB";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x87";
- break;
- case 0x9C :
- return "\xEB\x9A\xA3";
- break;
- case 0xB8 :
- return "\xEB\x9A\xBF";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x9B";
- break;
- case 0xB0 :
- return "\xEB\x9B\xB7";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x93";
- break;
- case 0xA8 :
- return "\xEB\x9C\xAF";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x8B";
- break;
- case 0xA0 :
- return "\xEB\x9D\xA7";
- break;
- case 0xBC :
- return "\xEB\x9E\x83";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\x9F";
- break;
- case 0xB4 :
- return "\xEB\x9E\xBB";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x97";
- break;
- case 0xAC :
- return "\xEB\x9F\xB3";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x8F";
- break;
- case 0xA4 :
- return "\xEB\xA0\xAB";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x87";
- break;
- case 0x9C :
- return "\xEB\xA1\xA3";
- break;
- case 0xB8 :
- return "\xEB\xA1\xBF";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x9B";
- break;
- case 0xB0 :
- return "\xEB\xA2\xB7";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x93";
- break;
- case 0xA8 :
- return "\xEB\xA3\xAF";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x8B";
- break;
- case 0xA0 :
- return "\xEB\xA4\xA7";
- break;
- case 0xBC :
- return "\xEB\xA5\x83";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\x9F";
- break;
- case 0xB4 :
- return "\xEB\xA5\xBB";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x97";
- break;
- case 0xAC :
- return "\xEB\xA6\xB3";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x8F";
- break;
- case 0xA4 :
- return "\xEB\xA7\xAB";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x87";
- break;
- case 0x9C :
- return "\xEB\xA8\xA3";
- break;
- case 0xB8 :
- return "\xEB\xA8\xBF";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x9B";
- break;
- case 0xB0 :
- return "\xEB\xA9\xB7";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x93";
- break;
- case 0xA8 :
- return "\xEB\xAA\xAF";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x8B";
- break;
- case 0xA0 :
- return "\xEB\xAB\xA7";
- break;
- case 0xBC :
- return "\xEB\xAC\x83";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\x9F";
- break;
- case 0xB4 :
- return "\xEB\xAC\xBB";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x97";
- break;
- case 0xAC :
- return "\xEB\xAD\xB3";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x8F";
- break;
- case 0xA4 :
- return "\xEB\xAE\xAB";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x87";
- break;
- case 0x9C :
- return "\xEB\xAF\xA3";
- break;
- case 0xB8 :
- return "\xEB\xAF\xBF";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x9B";
- break;
- case 0xB0 :
- return "\xEB\xB0\xB7";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x93";
- break;
- case 0xA8 :
- return "\xEB\xB1\xAF";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x8B";
- break;
- case 0xA0 :
- return "\xEB\xB2\xA7";
- break;
- case 0xBC :
- return "\xEB\xB3\x83";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\x9F";
- break;
- case 0xB4 :
- return "\xEB\xB3\xBB";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x97";
- break;
- case 0xAC :
- return "\xEB\xB4\xB3";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x8F";
- break;
- case 0xA4 :
- return "\xEB\xB5\xAB";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x87";
- break;
- case 0x9C :
- return "\xEB\xB6\xA3";
- break;
- case 0xB8 :
- return "\xEB\xB6\xBF";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x9B";
- break;
- case 0xB0 :
- return "\xEB\xB7\xB7";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x93";
- break;
- case 0xA8 :
- return "\xEB\xB8\xAF";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x8B";
- break;
- case 0xA0 :
- return "\xEB\xB9\xA7";
- break;
- case 0xBC :
- return "\xEB\xBA\x83";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\x9F";
- break;
- case 0xB4 :
- return "\xEB\xBA\xBB";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x97";
- break;
- case 0xAC :
- return "\xEB\xBB\xB3";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x8F";
- break;
- case 0xA4 :
- return "\xEB\xBC\xAB";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x87";
- break;
- case 0x9C :
- return "\xEB\xBD\xA3";
- break;
- case 0xB8 :
- return "\xEB\xBD\xBF";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x9B";
- break;
- case 0xB0 :
- return "\xEB\xBE\xB7";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x93";
- break;
- case 0xA8 :
- return "\xEB\xBF\xAF";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x8B";
- break;
- case 0xA0 :
- return "\xEC\x80\xA7";
- break;
- case 0xBC :
- return "\xEC\x81\x83";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\x9F";
- break;
- case 0xB4 :
- return "\xEC\x81\xBB";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x97";
- break;
- case 0xAC :
- return "\xEC\x82\xB3";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x8F";
- break;
- case 0xA4 :
- return "\xEC\x83\xAB";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x87";
- break;
- case 0x9C :
- return "\xEC\x84\xA3";
- break;
- case 0xB8 :
- return "\xEC\x84\xBF";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x9B";
- break;
- case 0xB0 :
- return "\xEC\x85\xB7";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x93";
- break;
- case 0xA8 :
- return "\xEC\x86\xAF";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x8B";
- break;
- case 0xA0 :
- return "\xEC\x87\xA7";
- break;
- case 0xBC :
- return "\xEC\x88\x83";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\x9F";
- break;
- case 0xB4 :
- return "\xEC\x88\xBB";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x97";
- break;
- case 0xAC :
- return "\xEC\x89\xB3";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x8F";
- break;
- case 0xA4 :
- return "\xEC\x8A\xAB";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x87";
- break;
- case 0x9C :
- return "\xEC\x8B\xA3";
- break;
- case 0xB8 :
- return "\xEC\x8B\xBF";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x9B";
- break;
- case 0xB0 :
- return "\xEC\x8C\xB7";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x93";
- break;
- case 0xA8 :
- return "\xEC\x8D\xAF";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x8B";
- break;
- case 0xA0 :
- return "\xEC\x8E\xA7";
- break;
- case 0xBC :
- return "\xEC\x8F\x83";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\x9F";
- break;
- case 0xB4 :
- return "\xEC\x8F\xBB";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x97";
- break;
- case 0xAC :
- return "\xEC\x90\xB3";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x8F";
- break;
- case 0xA4 :
- return "\xEC\x91\xAB";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x87";
- break;
- case 0x9C :
- return "\xEC\x92\xA3";
- break;
- case 0xB8 :
- return "\xEC\x92\xBF";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x9B";
- break;
- case 0xB0 :
- return "\xEC\x93\xB7";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x93";
- break;
- case 0xA8 :
- return "\xEC\x94\xAF";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x8B";
- break;
- case 0xA0 :
- return "\xEC\x95\xA7";
- break;
- case 0xBC :
- return "\xEC\x96\x83";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\x9F";
- break;
- case 0xB4 :
- return "\xEC\x96\xBB";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x97";
- break;
- case 0xAC :
- return "\xEC\x97\xB3";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x8F";
- break;
- case 0xA4 :
- return "\xEC\x98\xAB";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x87";
- break;
- case 0x9C :
- return "\xEC\x99\xA3";
- break;
- case 0xB8 :
- return "\xEC\x99\xBF";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x9B";
- break;
- case 0xB0 :
- return "\xEC\x9A\xB7";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x93";
- break;
- case 0xA8 :
- return "\xEC\x9B\xAF";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x8B";
- break;
- case 0xA0 :
- return "\xEC\x9C\xA7";
- break;
- case 0xBC :
- return "\xEC\x9D\x83";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\x9F";
- break;
- case 0xB4 :
- return "\xEC\x9D\xBB";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x97";
- break;
- case 0xAC :
- return "\xEC\x9E\xB3";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x8F";
- break;
- case 0xA4 :
- return "\xEC\x9F\xAB";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x87";
- break;
- case 0x9C :
- return "\xEC\xA0\xA3";
- break;
- case 0xB8 :
- return "\xEC\xA0\xBF";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x9B";
- break;
- case 0xB0 :
- return "\xEC\xA1\xB7";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x93";
- break;
- case 0xA8 :
- return "\xEC\xA2\xAF";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x8B";
- break;
- case 0xA0 :
- return "\xEC\xA3\xA7";
- break;
- case 0xBC :
- return "\xEC\xA4\x83";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\x9F";
- break;
- case 0xB4 :
- return "\xEC\xA4\xBB";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x97";
- break;
- case 0xAC :
- return "\xEC\xA5\xB3";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x8F";
- break;
- case 0xA4 :
- return "\xEC\xA6\xAB";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x87";
- break;
- case 0x9C :
- return "\xEC\xA7\xA3";
- break;
- case 0xB8 :
- return "\xEC\xA7\xBF";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x9B";
- break;
- case 0xB0 :
- return "\xEC\xA8\xB7";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x93";
- break;
- case 0xA8 :
- return "\xEC\xA9\xAF";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x8B";
- break;
- case 0xA0 :
- return "\xEC\xAA\xA7";
- break;
- case 0xBC :
- return "\xEC\xAB\x83";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\x9F";
- break;
- case 0xB4 :
- return "\xEC\xAB\xBB";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x97";
- break;
- case 0xAC :
- return "\xEC\xAC\xB3";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x8F";
- break;
- case 0xA4 :
- return "\xEC\xAD\xAB";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x87";
- break;
- case 0x9C :
- return "\xEC\xAE\xA3";
- break;
- case 0xB8 :
- return "\xEC\xAE\xBF";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x9B";
- break;
- case 0xB0 :
- return "\xEC\xAF\xB7";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x93";
- break;
- case 0xA8 :
- return "\xEC\xB0\xAF";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x8B";
- break;
- case 0xA0 :
- return "\xEC\xB1\xA7";
- break;
- case 0xBC :
- return "\xEC\xB2\x83";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\x9F";
- break;
- case 0xB4 :
- return "\xEC\xB2\xBB";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x97";
- break;
- case 0xAC :
- return "\xEC\xB3\xB3";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x8F";
- break;
- case 0xA4 :
- return "\xEC\xB4\xAB";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x87";
- break;
- case 0x9C :
- return "\xEC\xB5\xA3";
- break;
- case 0xB8 :
- return "\xEC\xB5\xBF";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x9B";
- break;
- case 0xB0 :
- return "\xEC\xB6\xB7";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x93";
- break;
- case 0xA8 :
- return "\xEC\xB7\xAF";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x8B";
- break;
- case 0xA0 :
- return "\xEC\xB8\xA7";
- break;
- case 0xBC :
- return "\xEC\xB9\x83";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\x9F";
- break;
- case 0xB4 :
- return "\xEC\xB9\xBB";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x97";
- break;
- case 0xAC :
- return "\xEC\xBA\xB3";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x8F";
- break;
- case 0xA4 :
- return "\xEC\xBB\xAB";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x87";
- break;
- case 0x9C :
- return "\xEC\xBC\xA3";
- break;
- case 0xB8 :
- return "\xEC\xBC\xBF";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x9B";
- break;
- case 0xB0 :
- return "\xEC\xBD\xB7";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x93";
- break;
- case 0xA8 :
- return "\xEC\xBE\xAF";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x8B";
- break;
- case 0xA0 :
- return "\xEC\xBF\xA7";
- break;
- case 0xBC :
- return "\xED\x80\x83";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\x9F";
- break;
- case 0xB4 :
- return "\xED\x80\xBB";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x97";
- break;
- case 0xAC :
- return "\xED\x81\xB3";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x8F";
- break;
- case 0xA4 :
- return "\xED\x82\xAB";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x87";
- break;
- case 0x9C :
- return "\xED\x83\xA3";
- break;
- case 0xB8 :
- return "\xED\x83\xBF";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x9B";
- break;
- case 0xB0 :
- return "\xED\x84\xB7";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x93";
- break;
- case 0xA8 :
- return "\xED\x85\xAF";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x8B";
- break;
- case 0xA0 :
- return "\xED\x86\xA7";
- break;
- case 0xBC :
- return "\xED\x87\x83";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\x9F";
- break;
- case 0xB4 :
- return "\xED\x87\xBB";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x97";
- break;
- case 0xAC :
- return "\xED\x88\xB3";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x8F";
- break;
- case 0xA4 :
- return "\xED\x89\xAB";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x87";
- break;
- case 0x9C :
- return "\xED\x8A\xA3";
- break;
- case 0xB8 :
- return "\xED\x8A\xBF";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x9B";
- break;
- case 0xB0 :
- return "\xED\x8B\xB7";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x93";
- break;
- case 0xA8 :
- return "\xED\x8C\xAF";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x8B";
- break;
- case 0xA0 :
- return "\xED\x8D\xA7";
- break;
- case 0xBC :
- return "\xED\x8E\x83";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\x9F";
- break;
- case 0xB4 :
- return "\xED\x8E\xBB";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x97";
- break;
- case 0xAC :
- return "\xED\x8F\xB3";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x8F";
- break;
- case 0xA4 :
- return "\xED\x90\xAB";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x87";
- break;
- case 0x9C :
- return "\xED\x91\xA3";
- break;
- case 0xB8 :
- return "\xED\x91\xBF";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x9B";
- break;
- case 0xB0 :
- return "\xED\x92\xB7";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x93";
- break;
- case 0xA8 :
- return "\xED\x93\xAF";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x8B";
- break;
- case 0xA0 :
- return "\xED\x94\xA7";
- break;
- case 0xBC :
- return "\xED\x95\x83";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\x9F";
- break;
- case 0xB4 :
- return "\xED\x95\xBB";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x97";
- break;
- case 0xAC :
- return "\xED\x96\xB3";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x8F";
- break;
- case 0xA4 :
- return "\xED\x97\xAB";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x87";
- break;
- case 0x9C :
- return "\xED\x98\xA3";
- break;
- case 0xB8 :
- return "\xED\x98\xBF";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x9B";
- break;
- case 0xB0 :
- return "\xED\x99\xB7";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x93";
- break;
- case 0xA8 :
- return "\xED\x9A\xAF";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x8B";
- break;
- case 0xA0 :
- return "\xED\x9B\xA7";
- break;
- case 0xBC :
- return "\xED\x9C\x83";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\x9F";
- break;
- case 0xB4 :
- return "\xED\x9C\xBB";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x97";
- break;
- case 0xAC :
- return "\xED\x9D\xB3";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x8F";
- }
- break;
- }
- break;
- }
- break;
- case 0xAF :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x88";
- break;
- case 0x9C :
- return "\xEA\xB0\xA4";
- break;
- case 0xB8 :
- return "\xEA\xB1\x80";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x9C";
- break;
- case 0xB0 :
- return "\xEA\xB1\xB8";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x94";
- break;
- case 0xA8 :
- return "\xEA\xB2\xB0";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x8C";
- break;
- case 0xA0 :
- return "\xEA\xB3\xA8";
- break;
- case 0xBC :
- return "\xEA\xB4\x84";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xA0";
- break;
- case 0xB4 :
- return "\xEA\xB4\xBC";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x98";
- break;
- case 0xAC :
- return "\xEA\xB5\xB4";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x90";
- break;
- case 0xA4 :
- return "\xEA\xB6\xAC";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x88";
- break;
- case 0x9C :
- return "\xEA\xB7\xA4";
- break;
- case 0xB8 :
- return "\xEA\xB8\x80";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x9C";
- break;
- case 0xB0 :
- return "\xEA\xB8\xB8";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x94";
- break;
- case 0xA8 :
- return "\xEA\xB9\xB0";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x8C";
- break;
- case 0xA0 :
- return "\xEA\xBA\xA8";
- break;
- case 0xBC :
- return "\xEA\xBB\x84";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xA0";
- break;
- case 0xB4 :
- return "\xEA\xBB\xBC";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x98";
- break;
- case 0xAC :
- return "\xEA\xBC\xB4";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x90";
- break;
- case 0xA4 :
- return "\xEA\xBD\xAC";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x88";
- break;
- case 0x9C :
- return "\xEA\xBE\xA4";
- break;
- case 0xB8 :
- return "\xEA\xBF\x80";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x9C";
- break;
- case 0xB0 :
- return "\xEA\xBF\xB8";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x94";
- break;
- case 0xA8 :
- return "\xEB\x80\xB0";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x8C";
- break;
- case 0xA0 :
- return "\xEB\x81\xA8";
- break;
- case 0xBC :
- return "\xEB\x82\x84";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xA0";
- break;
- case 0xB4 :
- return "\xEB\x82\xBC";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x98";
- break;
- case 0xAC :
- return "\xEB\x83\xB4";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x90";
- break;
- case 0xA4 :
- return "\xEB\x84\xAC";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x88";
- break;
- case 0x9C :
- return "\xEB\x85\xA4";
- break;
- case 0xB8 :
- return "\xEB\x86\x80";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x9C";
- break;
- case 0xB0 :
- return "\xEB\x86\xB8";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x94";
- break;
- case 0xA8 :
- return "\xEB\x87\xB0";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x8C";
- break;
- case 0xA0 :
- return "\xEB\x88\xA8";
- break;
- case 0xBC :
- return "\xEB\x89\x84";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xA0";
- break;
- case 0xB4 :
- return "\xEB\x89\xBC";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x98";
- break;
- case 0xAC :
- return "\xEB\x8A\xB4";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x90";
- break;
- case 0xA4 :
- return "\xEB\x8B\xAC";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x88";
- break;
- case 0x9C :
- return "\xEB\x8C\xA4";
- break;
- case 0xB8 :
- return "\xEB\x8D\x80";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x9C";
- break;
- case 0xB0 :
- return "\xEB\x8D\xB8";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x94";
- break;
- case 0xA8 :
- return "\xEB\x8E\xB0";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x8C";
- break;
- case 0xA0 :
- return "\xEB\x8F\xA8";
- break;
- case 0xBC :
- return "\xEB\x90\x84";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xA0";
- break;
- case 0xB4 :
- return "\xEB\x90\xBC";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x98";
- break;
- case 0xAC :
- return "\xEB\x91\xB4";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x90";
- break;
- case 0xA4 :
- return "\xEB\x92\xAC";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x88";
- break;
- case 0x9C :
- return "\xEB\x93\xA4";
- break;
- case 0xB8 :
- return "\xEB\x94\x80";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x9C";
- break;
- case 0xB0 :
- return "\xEB\x94\xB8";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x94";
- break;
- case 0xA8 :
- return "\xEB\x95\xB0";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x8C";
- break;
- case 0xA0 :
- return "\xEB\x96\xA8";
- break;
- case 0xBC :
- return "\xEB\x97\x84";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xA0";
- break;
- case 0xB4 :
- return "\xEB\x97\xBC";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x98";
- break;
- case 0xAC :
- return "\xEB\x98\xB4";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x90";
- break;
- case 0xA4 :
- return "\xEB\x99\xAC";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x88";
- break;
- case 0x9C :
- return "\xEB\x9A\xA4";
- break;
- case 0xB8 :
- return "\xEB\x9B\x80";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x9C";
- break;
- case 0xB0 :
- return "\xEB\x9B\xB8";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x94";
- break;
- case 0xA8 :
- return "\xEB\x9C\xB0";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x8C";
- break;
- case 0xA0 :
- return "\xEB\x9D\xA8";
- break;
- case 0xBC :
- return "\xEB\x9E\x84";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xA0";
- break;
- case 0xB4 :
- return "\xEB\x9E\xBC";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x98";
- break;
- case 0xAC :
- return "\xEB\x9F\xB4";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x90";
- break;
- case 0xA4 :
- return "\xEB\xA0\xAC";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x88";
- break;
- case 0x9C :
- return "\xEB\xA1\xA4";
- break;
- case 0xB8 :
- return "\xEB\xA2\x80";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x9C";
- break;
- case 0xB0 :
- return "\xEB\xA2\xB8";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x94";
- break;
- case 0xA8 :
- return "\xEB\xA3\xB0";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x8C";
- break;
- case 0xA0 :
- return "\xEB\xA4\xA8";
- break;
- case 0xBC :
- return "\xEB\xA5\x84";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xA0";
- break;
- case 0xB4 :
- return "\xEB\xA5\xBC";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x98";
- break;
- case 0xAC :
- return "\xEB\xA6\xB4";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x90";
- break;
- case 0xA4 :
- return "\xEB\xA7\xAC";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x88";
- break;
- case 0x9C :
- return "\xEB\xA8\xA4";
- break;
- case 0xB8 :
- return "\xEB\xA9\x80";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x9C";
- break;
- case 0xB0 :
- return "\xEB\xA9\xB8";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x94";
- break;
- case 0xA8 :
- return "\xEB\xAA\xB0";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x8C";
- break;
- case 0xA0 :
- return "\xEB\xAB\xA8";
- break;
- case 0xBC :
- return "\xEB\xAC\x84";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xA0";
- break;
- case 0xB4 :
- return "\xEB\xAC\xBC";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x98";
- break;
- case 0xAC :
- return "\xEB\xAD\xB4";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x90";
- break;
- case 0xA4 :
- return "\xEB\xAE\xAC";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x88";
- break;
- case 0x9C :
- return "\xEB\xAF\xA4";
- break;
- case 0xB8 :
- return "\xEB\xB0\x80";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x9C";
- break;
- case 0xB0 :
- return "\xEB\xB0\xB8";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x94";
- break;
- case 0xA8 :
- return "\xEB\xB1\xB0";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x8C";
- break;
- case 0xA0 :
- return "\xEB\xB2\xA8";
- break;
- case 0xBC :
- return "\xEB\xB3\x84";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xA0";
- break;
- case 0xB4 :
- return "\xEB\xB3\xBC";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x98";
- break;
- case 0xAC :
- return "\xEB\xB4\xB4";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x90";
- break;
- case 0xA4 :
- return "\xEB\xB5\xAC";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x88";
- break;
- case 0x9C :
- return "\xEB\xB6\xA4";
- break;
- case 0xB8 :
- return "\xEB\xB7\x80";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x9C";
- break;
- case 0xB0 :
- return "\xEB\xB7\xB8";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x94";
- break;
- case 0xA8 :
- return "\xEB\xB8\xB0";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x8C";
- break;
- case 0xA0 :
- return "\xEB\xB9\xA8";
- break;
- case 0xBC :
- return "\xEB\xBA\x84";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xA0";
- break;
- case 0xB4 :
- return "\xEB\xBA\xBC";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x98";
- break;
- case 0xAC :
- return "\xEB\xBB\xB4";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x90";
- break;
- case 0xA4 :
- return "\xEB\xBC\xAC";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x88";
- break;
- case 0x9C :
- return "\xEB\xBD\xA4";
- break;
- case 0xB8 :
- return "\xEB\xBE\x80";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x9C";
- break;
- case 0xB0 :
- return "\xEB\xBE\xB8";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x94";
- break;
- case 0xA8 :
- return "\xEB\xBF\xB0";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x8C";
- break;
- case 0xA0 :
- return "\xEC\x80\xA8";
- break;
- case 0xBC :
- return "\xEC\x81\x84";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xA0";
- break;
- case 0xB4 :
- return "\xEC\x81\xBC";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x98";
- break;
- case 0xAC :
- return "\xEC\x82\xB4";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x90";
- break;
- case 0xA4 :
- return "\xEC\x83\xAC";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x88";
- break;
- case 0x9C :
- return "\xEC\x84\xA4";
- break;
- case 0xB8 :
- return "\xEC\x85\x80";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x9C";
- break;
- case 0xB0 :
- return "\xEC\x85\xB8";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x94";
- break;
- case 0xA8 :
- return "\xEC\x86\xB0";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x8C";
- break;
- case 0xA0 :
- return "\xEC\x87\xA8";
- break;
- case 0xBC :
- return "\xEC\x88\x84";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xA0";
- break;
- case 0xB4 :
- return "\xEC\x88\xBC";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x98";
- break;
- case 0xAC :
- return "\xEC\x89\xB4";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x90";
- break;
- case 0xA4 :
- return "\xEC\x8A\xAC";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x88";
- break;
- case 0x9C :
- return "\xEC\x8B\xA4";
- break;
- case 0xB8 :
- return "\xEC\x8C\x80";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x9C";
- break;
- case 0xB0 :
- return "\xEC\x8C\xB8";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x94";
- break;
- case 0xA8 :
- return "\xEC\x8D\xB0";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x8C";
- break;
- case 0xA0 :
- return "\xEC\x8E\xA8";
- break;
- case 0xBC :
- return "\xEC\x8F\x84";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xA0";
- break;
- case 0xB4 :
- return "\xEC\x8F\xBC";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x98";
- break;
- case 0xAC :
- return "\xEC\x90\xB4";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x90";
- break;
- case 0xA4 :
- return "\xEC\x91\xAC";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x88";
- break;
- case 0x9C :
- return "\xEC\x92\xA4";
- break;
- case 0xB8 :
- return "\xEC\x93\x80";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x9C";
- break;
- case 0xB0 :
- return "\xEC\x93\xB8";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x94";
- break;
- case 0xA8 :
- return "\xEC\x94\xB0";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x8C";
- break;
- case 0xA0 :
- return "\xEC\x95\xA8";
- break;
- case 0xBC :
- return "\xEC\x96\x84";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xA0";
- break;
- case 0xB4 :
- return "\xEC\x96\xBC";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x98";
- break;
- case 0xAC :
- return "\xEC\x97\xB4";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x90";
- break;
- case 0xA4 :
- return "\xEC\x98\xAC";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x88";
- break;
- case 0x9C :
- return "\xEC\x99\xA4";
- break;
- case 0xB8 :
- return "\xEC\x9A\x80";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x9C";
- break;
- case 0xB0 :
- return "\xEC\x9A\xB8";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x94";
- break;
- case 0xA8 :
- return "\xEC\x9B\xB0";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x8C";
- break;
- case 0xA0 :
- return "\xEC\x9C\xA8";
- break;
- case 0xBC :
- return "\xEC\x9D\x84";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xA0";
- break;
- case 0xB4 :
- return "\xEC\x9D\xBC";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x98";
- break;
- case 0xAC :
- return "\xEC\x9E\xB4";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x90";
- break;
- case 0xA4 :
- return "\xEC\x9F\xAC";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x88";
- break;
- case 0x9C :
- return "\xEC\xA0\xA4";
- break;
- case 0xB8 :
- return "\xEC\xA1\x80";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x9C";
- break;
- case 0xB0 :
- return "\xEC\xA1\xB8";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x94";
- break;
- case 0xA8 :
- return "\xEC\xA2\xB0";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x8C";
- break;
- case 0xA0 :
- return "\xEC\xA3\xA8";
- break;
- case 0xBC :
- return "\xEC\xA4\x84";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xA0";
- break;
- case 0xB4 :
- return "\xEC\xA4\xBC";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x98";
- break;
- case 0xAC :
- return "\xEC\xA5\xB4";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x90";
- break;
- case 0xA4 :
- return "\xEC\xA6\xAC";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x88";
- break;
- case 0x9C :
- return "\xEC\xA7\xA4";
- break;
- case 0xB8 :
- return "\xEC\xA8\x80";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x9C";
- break;
- case 0xB0 :
- return "\xEC\xA8\xB8";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x94";
- break;
- case 0xA8 :
- return "\xEC\xA9\xB0";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x8C";
- break;
- case 0xA0 :
- return "\xEC\xAA\xA8";
- break;
- case 0xBC :
- return "\xEC\xAB\x84";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xA0";
- break;
- case 0xB4 :
- return "\xEC\xAB\xBC";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x98";
- break;
- case 0xAC :
- return "\xEC\xAC\xB4";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x90";
- break;
- case 0xA4 :
- return "\xEC\xAD\xAC";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x88";
- break;
- case 0x9C :
- return "\xEC\xAE\xA4";
- break;
- case 0xB8 :
- return "\xEC\xAF\x80";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x9C";
- break;
- case 0xB0 :
- return "\xEC\xAF\xB8";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x94";
- break;
- case 0xA8 :
- return "\xEC\xB0\xB0";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x8C";
- break;
- case 0xA0 :
- return "\xEC\xB1\xA8";
- break;
- case 0xBC :
- return "\xEC\xB2\x84";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xA0";
- break;
- case 0xB4 :
- return "\xEC\xB2\xBC";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x98";
- break;
- case 0xAC :
- return "\xEC\xB3\xB4";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x90";
- break;
- case 0xA4 :
- return "\xEC\xB4\xAC";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x88";
- break;
- case 0x9C :
- return "\xEC\xB5\xA4";
- break;
- case 0xB8 :
- return "\xEC\xB6\x80";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x9C";
- break;
- case 0xB0 :
- return "\xEC\xB6\xB8";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x94";
- break;
- case 0xA8 :
- return "\xEC\xB7\xB0";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x8C";
- break;
- case 0xA0 :
- return "\xEC\xB8\xA8";
- break;
- case 0xBC :
- return "\xEC\xB9\x84";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xA0";
- break;
- case 0xB4 :
- return "\xEC\xB9\xBC";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x98";
- break;
- case 0xAC :
- return "\xEC\xBA\xB4";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x90";
- break;
- case 0xA4 :
- return "\xEC\xBB\xAC";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x88";
- break;
- case 0x9C :
- return "\xEC\xBC\xA4";
- break;
- case 0xB8 :
- return "\xEC\xBD\x80";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x9C";
- break;
- case 0xB0 :
- return "\xEC\xBD\xB8";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x94";
- break;
- case 0xA8 :
- return "\xEC\xBE\xB0";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x8C";
- break;
- case 0xA0 :
- return "\xEC\xBF\xA8";
- break;
- case 0xBC :
- return "\xED\x80\x84";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xA0";
- break;
- case 0xB4 :
- return "\xED\x80\xBC";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x98";
- break;
- case 0xAC :
- return "\xED\x81\xB4";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x90";
- break;
- case 0xA4 :
- return "\xED\x82\xAC";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x88";
- break;
- case 0x9C :
- return "\xED\x83\xA4";
- break;
- case 0xB8 :
- return "\xED\x84\x80";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x9C";
- break;
- case 0xB0 :
- return "\xED\x84\xB8";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x94";
- break;
- case 0xA8 :
- return "\xED\x85\xB0";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x8C";
- break;
- case 0xA0 :
- return "\xED\x86\xA8";
- break;
- case 0xBC :
- return "\xED\x87\x84";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xA0";
- break;
- case 0xB4 :
- return "\xED\x87\xBC";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x98";
- break;
- case 0xAC :
- return "\xED\x88\xB4";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x90";
- break;
- case 0xA4 :
- return "\xED\x89\xAC";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x88";
- break;
- case 0x9C :
- return "\xED\x8A\xA4";
- break;
- case 0xB8 :
- return "\xED\x8B\x80";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x9C";
- break;
- case 0xB0 :
- return "\xED\x8B\xB8";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x94";
- break;
- case 0xA8 :
- return "\xED\x8C\xB0";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x8C";
- break;
- case 0xA0 :
- return "\xED\x8D\xA8";
- break;
- case 0xBC :
- return "\xED\x8E\x84";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xA0";
- break;
- case 0xB4 :
- return "\xED\x8E\xBC";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x98";
- break;
- case 0xAC :
- return "\xED\x8F\xB4";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x90";
- break;
- case 0xA4 :
- return "\xED\x90\xAC";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x88";
- break;
- case 0x9C :
- return "\xED\x91\xA4";
- break;
- case 0xB8 :
- return "\xED\x92\x80";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x9C";
- break;
- case 0xB0 :
- return "\xED\x92\xB8";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x94";
- break;
- case 0xA8 :
- return "\xED\x93\xB0";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x8C";
- break;
- case 0xA0 :
- return "\xED\x94\xA8";
- break;
- case 0xBC :
- return "\xED\x95\x84";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xA0";
- break;
- case 0xB4 :
- return "\xED\x95\xBC";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x98";
- break;
- case 0xAC :
- return "\xED\x96\xB4";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x90";
- break;
- case 0xA4 :
- return "\xED\x97\xAC";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x88";
- break;
- case 0x9C :
- return "\xED\x98\xA4";
- break;
- case 0xB8 :
- return "\xED\x99\x80";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x9C";
- break;
- case 0xB0 :
- return "\xED\x99\xB8";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x94";
- break;
- case 0xA8 :
- return "\xED\x9A\xB0";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x8C";
- break;
- case 0xA0 :
- return "\xED\x9B\xA8";
- break;
- case 0xBC :
- return "\xED\x9C\x84";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xA0";
- break;
- case 0xB4 :
- return "\xED\x9C\xBC";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x98";
- break;
- case 0xAC :
- return "\xED\x9D\xB4";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x90";
- }
- break;
- }
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x89";
- break;
- case 0x9C :
- return "\xEA\xB0\xA5";
- break;
- case 0xB8 :
- return "\xEA\xB1\x81";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x9D";
- break;
- case 0xB0 :
- return "\xEA\xB1\xB9";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x95";
- break;
- case 0xA8 :
- return "\xEA\xB2\xB1";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x8D";
- break;
- case 0xA0 :
- return "\xEA\xB3\xA9";
- break;
- case 0xBC :
- return "\xEA\xB4\x85";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xA1";
- break;
- case 0xB4 :
- return "\xEA\xB4\xBD";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x99";
- break;
- case 0xAC :
- return "\xEA\xB5\xB5";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x91";
- break;
- case 0xA4 :
- return "\xEA\xB6\xAD";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x89";
- break;
- case 0x9C :
- return "\xEA\xB7\xA5";
- break;
- case 0xB8 :
- return "\xEA\xB8\x81";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x9D";
- break;
- case 0xB0 :
- return "\xEA\xB8\xB9";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x95";
- break;
- case 0xA8 :
- return "\xEA\xB9\xB1";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x8D";
- break;
- case 0xA0 :
- return "\xEA\xBA\xA9";
- break;
- case 0xBC :
- return "\xEA\xBB\x85";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xA1";
- break;
- case 0xB4 :
- return "\xEA\xBB\xBD";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x99";
- break;
- case 0xAC :
- return "\xEA\xBC\xB5";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x91";
- break;
- case 0xA4 :
- return "\xEA\xBD\xAD";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x89";
- break;
- case 0x9C :
- return "\xEA\xBE\xA5";
- break;
- case 0xB8 :
- return "\xEA\xBF\x81";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x9D";
- break;
- case 0xB0 :
- return "\xEA\xBF\xB9";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x95";
- break;
- case 0xA8 :
- return "\xEB\x80\xB1";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x8D";
- break;
- case 0xA0 :
- return "\xEB\x81\xA9";
- break;
- case 0xBC :
- return "\xEB\x82\x85";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xA1";
- break;
- case 0xB4 :
- return "\xEB\x82\xBD";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x99";
- break;
- case 0xAC :
- return "\xEB\x83\xB5";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x91";
- break;
- case 0xA4 :
- return "\xEB\x84\xAD";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x89";
- break;
- case 0x9C :
- return "\xEB\x85\xA5";
- break;
- case 0xB8 :
- return "\xEB\x86\x81";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x9D";
- break;
- case 0xB0 :
- return "\xEB\x86\xB9";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x95";
- break;
- case 0xA8 :
- return "\xEB\x87\xB1";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x8D";
- break;
- case 0xA0 :
- return "\xEB\x88\xA9";
- break;
- case 0xBC :
- return "\xEB\x89\x85";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xA1";
- break;
- case 0xB4 :
- return "\xEB\x89\xBD";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x99";
- break;
- case 0xAC :
- return "\xEB\x8A\xB5";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x91";
- break;
- case 0xA4 :
- return "\xEB\x8B\xAD";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x89";
- break;
- case 0x9C :
- return "\xEB\x8C\xA5";
- break;
- case 0xB8 :
- return "\xEB\x8D\x81";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x9D";
- break;
- case 0xB0 :
- return "\xEB\x8D\xB9";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x95";
- break;
- case 0xA8 :
- return "\xEB\x8E\xB1";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x8D";
- break;
- case 0xA0 :
- return "\xEB\x8F\xA9";
- break;
- case 0xBC :
- return "\xEB\x90\x85";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xA1";
- break;
- case 0xB4 :
- return "\xEB\x90\xBD";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x99";
- break;
- case 0xAC :
- return "\xEB\x91\xB5";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x91";
- break;
- case 0xA4 :
- return "\xEB\x92\xAD";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x89";
- break;
- case 0x9C :
- return "\xEB\x93\xA5";
- break;
- case 0xB8 :
- return "\xEB\x94\x81";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x9D";
- break;
- case 0xB0 :
- return "\xEB\x94\xB9";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x95";
- break;
- case 0xA8 :
- return "\xEB\x95\xB1";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x8D";
- break;
- case 0xA0 :
- return "\xEB\x96\xA9";
- break;
- case 0xBC :
- return "\xEB\x97\x85";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xA1";
- break;
- case 0xB4 :
- return "\xEB\x97\xBD";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x99";
- break;
- case 0xAC :
- return "\xEB\x98\xB5";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x91";
- break;
- case 0xA4 :
- return "\xEB\x99\xAD";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x89";
- break;
- case 0x9C :
- return "\xEB\x9A\xA5";
- break;
- case 0xB8 :
- return "\xEB\x9B\x81";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x9D";
- break;
- case 0xB0 :
- return "\xEB\x9B\xB9";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x95";
- break;
- case 0xA8 :
- return "\xEB\x9C\xB1";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x8D";
- break;
- case 0xA0 :
- return "\xEB\x9D\xA9";
- break;
- case 0xBC :
- return "\xEB\x9E\x85";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xA1";
- break;
- case 0xB4 :
- return "\xEB\x9E\xBD";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x99";
- break;
- case 0xAC :
- return "\xEB\x9F\xB5";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x91";
- break;
- case 0xA4 :
- return "\xEB\xA0\xAD";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x89";
- break;
- case 0x9C :
- return "\xEB\xA1\xA5";
- break;
- case 0xB8 :
- return "\xEB\xA2\x81";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x9D";
- break;
- case 0xB0 :
- return "\xEB\xA2\xB9";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x95";
- break;
- case 0xA8 :
- return "\xEB\xA3\xB1";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x8D";
- break;
- case 0xA0 :
- return "\xEB\xA4\xA9";
- break;
- case 0xBC :
- return "\xEB\xA5\x85";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xA1";
- break;
- case 0xB4 :
- return "\xEB\xA5\xBD";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x99";
- break;
- case 0xAC :
- return "\xEB\xA6\xB5";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x91";
- break;
- case 0xA4 :
- return "\xEB\xA7\xAD";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x89";
- break;
- case 0x9C :
- return "\xEB\xA8\xA5";
- break;
- case 0xB8 :
- return "\xEB\xA9\x81";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x9D";
- break;
- case 0xB0 :
- return "\xEB\xA9\xB9";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x95";
- break;
- case 0xA8 :
- return "\xEB\xAA\xB1";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x8D";
- break;
- case 0xA0 :
- return "\xEB\xAB\xA9";
- break;
- case 0xBC :
- return "\xEB\xAC\x85";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xA1";
- break;
- case 0xB4 :
- return "\xEB\xAC\xBD";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x99";
- break;
- case 0xAC :
- return "\xEB\xAD\xB5";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x91";
- break;
- case 0xA4 :
- return "\xEB\xAE\xAD";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x89";
- break;
- case 0x9C :
- return "\xEB\xAF\xA5";
- break;
- case 0xB8 :
- return "\xEB\xB0\x81";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x9D";
- break;
- case 0xB0 :
- return "\xEB\xB0\xB9";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x95";
- break;
- case 0xA8 :
- return "\xEB\xB1\xB1";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x8D";
- break;
- case 0xA0 :
- return "\xEB\xB2\xA9";
- break;
- case 0xBC :
- return "\xEB\xB3\x85";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xA1";
- break;
- case 0xB4 :
- return "\xEB\xB3\xBD";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x99";
- break;
- case 0xAC :
- return "\xEB\xB4\xB5";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x91";
- break;
- case 0xA4 :
- return "\xEB\xB5\xAD";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x89";
- break;
- case 0x9C :
- return "\xEB\xB6\xA5";
- break;
- case 0xB8 :
- return "\xEB\xB7\x81";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x9D";
- break;
- case 0xB0 :
- return "\xEB\xB7\xB9";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x95";
- break;
- case 0xA8 :
- return "\xEB\xB8\xB1";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x8D";
- break;
- case 0xA0 :
- return "\xEB\xB9\xA9";
- break;
- case 0xBC :
- return "\xEB\xBA\x85";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xA1";
- break;
- case 0xB4 :
- return "\xEB\xBA\xBD";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x99";
- break;
- case 0xAC :
- return "\xEB\xBB\xB5";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x91";
- break;
- case 0xA4 :
- return "\xEB\xBC\xAD";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x89";
- break;
- case 0x9C :
- return "\xEB\xBD\xA5";
- break;
- case 0xB8 :
- return "\xEB\xBE\x81";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x9D";
- break;
- case 0xB0 :
- return "\xEB\xBE\xB9";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x95";
- break;
- case 0xA8 :
- return "\xEB\xBF\xB1";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x8D";
- break;
- case 0xA0 :
- return "\xEC\x80\xA9";
- break;
- case 0xBC :
- return "\xEC\x81\x85";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xA1";
- break;
- case 0xB4 :
- return "\xEC\x81\xBD";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x99";
- break;
- case 0xAC :
- return "\xEC\x82\xB5";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x91";
- break;
- case 0xA4 :
- return "\xEC\x83\xAD";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x89";
- break;
- case 0x9C :
- return "\xEC\x84\xA5";
- break;
- case 0xB8 :
- return "\xEC\x85\x81";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x9D";
- break;
- case 0xB0 :
- return "\xEC\x85\xB9";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x95";
- break;
- case 0xA8 :
- return "\xEC\x86\xB1";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x8D";
- break;
- case 0xA0 :
- return "\xEC\x87\xA9";
- break;
- case 0xBC :
- return "\xEC\x88\x85";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xA1";
- break;
- case 0xB4 :
- return "\xEC\x88\xBD";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x99";
- break;
- case 0xAC :
- return "\xEC\x89\xB5";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x91";
- break;
- case 0xA4 :
- return "\xEC\x8A\xAD";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x89";
- break;
- case 0x9C :
- return "\xEC\x8B\xA5";
- break;
- case 0xB8 :
- return "\xEC\x8C\x81";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x9D";
- break;
- case 0xB0 :
- return "\xEC\x8C\xB9";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x95";
- break;
- case 0xA8 :
- return "\xEC\x8D\xB1";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x8D";
- break;
- case 0xA0 :
- return "\xEC\x8E\xA9";
- break;
- case 0xBC :
- return "\xEC\x8F\x85";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xA1";
- break;
- case 0xB4 :
- return "\xEC\x8F\xBD";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x99";
- break;
- case 0xAC :
- return "\xEC\x90\xB5";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x91";
- break;
- case 0xA4 :
- return "\xEC\x91\xAD";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x89";
- break;
- case 0x9C :
- return "\xEC\x92\xA5";
- break;
- case 0xB8 :
- return "\xEC\x93\x81";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x9D";
- break;
- case 0xB0 :
- return "\xEC\x93\xB9";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x95";
- break;
- case 0xA8 :
- return "\xEC\x94\xB1";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x8D";
- break;
- case 0xA0 :
- return "\xEC\x95\xA9";
- break;
- case 0xBC :
- return "\xEC\x96\x85";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xA1";
- break;
- case 0xB4 :
- return "\xEC\x96\xBD";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x99";
- break;
- case 0xAC :
- return "\xEC\x97\xB5";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x91";
- break;
- case 0xA4 :
- return "\xEC\x98\xAD";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x89";
- break;
- case 0x9C :
- return "\xEC\x99\xA5";
- break;
- case 0xB8 :
- return "\xEC\x9A\x81";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x9D";
- break;
- case 0xB0 :
- return "\xEC\x9A\xB9";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x95";
- break;
- case 0xA8 :
- return "\xEC\x9B\xB1";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x8D";
- break;
- case 0xA0 :
- return "\xEC\x9C\xA9";
- break;
- case 0xBC :
- return "\xEC\x9D\x85";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xA1";
- break;
- case 0xB4 :
- return "\xEC\x9D\xBD";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x99";
- break;
- case 0xAC :
- return "\xEC\x9E\xB5";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x91";
- break;
- case 0xA4 :
- return "\xEC\x9F\xAD";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x89";
- break;
- case 0x9C :
- return "\xEC\xA0\xA5";
- break;
- case 0xB8 :
- return "\xEC\xA1\x81";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x9D";
- break;
- case 0xB0 :
- return "\xEC\xA1\xB9";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x95";
- break;
- case 0xA8 :
- return "\xEC\xA2\xB1";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x8D";
- break;
- case 0xA0 :
- return "\xEC\xA3\xA9";
- break;
- case 0xBC :
- return "\xEC\xA4\x85";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xA1";
- break;
- case 0xB4 :
- return "\xEC\xA4\xBD";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x99";
- break;
- case 0xAC :
- return "\xEC\xA5\xB5";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x91";
- break;
- case 0xA4 :
- return "\xEC\xA6\xAD";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x89";
- break;
- case 0x9C :
- return "\xEC\xA7\xA5";
- break;
- case 0xB8 :
- return "\xEC\xA8\x81";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x9D";
- break;
- case 0xB0 :
- return "\xEC\xA8\xB9";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x95";
- break;
- case 0xA8 :
- return "\xEC\xA9\xB1";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x8D";
- break;
- case 0xA0 :
- return "\xEC\xAA\xA9";
- break;
- case 0xBC :
- return "\xEC\xAB\x85";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xA1";
- break;
- case 0xB4 :
- return "\xEC\xAB\xBD";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x99";
- break;
- case 0xAC :
- return "\xEC\xAC\xB5";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x91";
- break;
- case 0xA4 :
- return "\xEC\xAD\xAD";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x89";
- break;
- case 0x9C :
- return "\xEC\xAE\xA5";
- break;
- case 0xB8 :
- return "\xEC\xAF\x81";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x9D";
- break;
- case 0xB0 :
- return "\xEC\xAF\xB9";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x95";
- break;
- case 0xA8 :
- return "\xEC\xB0\xB1";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x8D";
- break;
- case 0xA0 :
- return "\xEC\xB1\xA9";
- break;
- case 0xBC :
- return "\xEC\xB2\x85";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xA1";
- break;
- case 0xB4 :
- return "\xEC\xB2\xBD";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x99";
- break;
- case 0xAC :
- return "\xEC\xB3\xB5";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x91";
- break;
- case 0xA4 :
- return "\xEC\xB4\xAD";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x89";
- break;
- case 0x9C :
- return "\xEC\xB5\xA5";
- break;
- case 0xB8 :
- return "\xEC\xB6\x81";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x9D";
- break;
- case 0xB0 :
- return "\xEC\xB6\xB9";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x95";
- break;
- case 0xA8 :
- return "\xEC\xB7\xB1";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x8D";
- break;
- case 0xA0 :
- return "\xEC\xB8\xA9";
- break;
- case 0xBC :
- return "\xEC\xB9\x85";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xA1";
- break;
- case 0xB4 :
- return "\xEC\xB9\xBD";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x99";
- break;
- case 0xAC :
- return "\xEC\xBA\xB5";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x91";
- break;
- case 0xA4 :
- return "\xEC\xBB\xAD";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x89";
- break;
- case 0x9C :
- return "\xEC\xBC\xA5";
- break;
- case 0xB8 :
- return "\xEC\xBD\x81";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x9D";
- break;
- case 0xB0 :
- return "\xEC\xBD\xB9";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x95";
- break;
- case 0xA8 :
- return "\xEC\xBE\xB1";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x8D";
- break;
- case 0xA0 :
- return "\xEC\xBF\xA9";
- break;
- case 0xBC :
- return "\xED\x80\x85";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xA1";
- break;
- case 0xB4 :
- return "\xED\x80\xBD";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x99";
- break;
- case 0xAC :
- return "\xED\x81\xB5";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x91";
- break;
- case 0xA4 :
- return "\xED\x82\xAD";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x89";
- break;
- case 0x9C :
- return "\xED\x83\xA5";
- break;
- case 0xB8 :
- return "\xED\x84\x81";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x9D";
- break;
- case 0xB0 :
- return "\xED\x84\xB9";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x95";
- break;
- case 0xA8 :
- return "\xED\x85\xB1";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x8D";
- break;
- case 0xA0 :
- return "\xED\x86\xA9";
- break;
- case 0xBC :
- return "\xED\x87\x85";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xA1";
- break;
- case 0xB4 :
- return "\xED\x87\xBD";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x99";
- break;
- case 0xAC :
- return "\xED\x88\xB5";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x91";
- break;
- case 0xA4 :
- return "\xED\x89\xAD";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x89";
- break;
- case 0x9C :
- return "\xED\x8A\xA5";
- break;
- case 0xB8 :
- return "\xED\x8B\x81";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x9D";
- break;
- case 0xB0 :
- return "\xED\x8B\xB9";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x95";
- break;
- case 0xA8 :
- return "\xED\x8C\xB1";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x8D";
- break;
- case 0xA0 :
- return "\xED\x8D\xA9";
- break;
- case 0xBC :
- return "\xED\x8E\x85";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xA1";
- break;
- case 0xB4 :
- return "\xED\x8E\xBD";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x99";
- break;
- case 0xAC :
- return "\xED\x8F\xB5";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x91";
- break;
- case 0xA4 :
- return "\xED\x90\xAD";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x89";
- break;
- case 0x9C :
- return "\xED\x91\xA5";
- break;
- case 0xB8 :
- return "\xED\x92\x81";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x9D";
- break;
- case 0xB0 :
- return "\xED\x92\xB9";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x95";
- break;
- case 0xA8 :
- return "\xED\x93\xB1";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x8D";
- break;
- case 0xA0 :
- return "\xED\x94\xA9";
- break;
- case 0xBC :
- return "\xED\x95\x85";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xA1";
- break;
- case 0xB4 :
- return "\xED\x95\xBD";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x99";
- break;
- case 0xAC :
- return "\xED\x96\xB5";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x91";
- break;
- case 0xA4 :
- return "\xED\x97\xAD";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x89";
- break;
- case 0x9C :
- return "\xED\x98\xA5";
- break;
- case 0xB8 :
- return "\xED\x99\x81";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x9D";
- break;
- case 0xB0 :
- return "\xED\x99\xB9";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x95";
- break;
- case 0xA8 :
- return "\xED\x9A\xB1";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x8D";
- break;
- case 0xA0 :
- return "\xED\x9B\xA9";
- break;
- case 0xBC :
- return "\xED\x9C\x85";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xA1";
- break;
- case 0xB4 :
- return "\xED\x9C\xBD";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x99";
- break;
- case 0xAC :
- return "\xED\x9D\xB5";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x91";
- }
- break;
- }
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x8A";
- break;
- case 0x9C :
- return "\xEA\xB0\xA6";
- break;
- case 0xB8 :
- return "\xEA\xB1\x82";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x9E";
- break;
- case 0xB0 :
- return "\xEA\xB1\xBA";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x96";
- break;
- case 0xA8 :
- return "\xEA\xB2\xB2";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x8E";
- break;
- case 0xA0 :
- return "\xEA\xB3\xAA";
- break;
- case 0xBC :
- return "\xEA\xB4\x86";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xA2";
- break;
- case 0xB4 :
- return "\xEA\xB4\xBE";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x9A";
- break;
- case 0xAC :
- return "\xEA\xB5\xB6";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x92";
- break;
- case 0xA4 :
- return "\xEA\xB6\xAE";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x8A";
- break;
- case 0x9C :
- return "\xEA\xB7\xA6";
- break;
- case 0xB8 :
- return "\xEA\xB8\x82";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x9E";
- break;
- case 0xB0 :
- return "\xEA\xB8\xBA";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x96";
- break;
- case 0xA8 :
- return "\xEA\xB9\xB2";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x8E";
- break;
- case 0xA0 :
- return "\xEA\xBA\xAA";
- break;
- case 0xBC :
- return "\xEA\xBB\x86";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xA2";
- break;
- case 0xB4 :
- return "\xEA\xBB\xBE";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x9A";
- break;
- case 0xAC :
- return "\xEA\xBC\xB6";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x92";
- break;
- case 0xA4 :
- return "\xEA\xBD\xAE";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x8A";
- break;
- case 0x9C :
- return "\xEA\xBE\xA6";
- break;
- case 0xB8 :
- return "\xEA\xBF\x82";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x9E";
- break;
- case 0xB0 :
- return "\xEA\xBF\xBA";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x96";
- break;
- case 0xA8 :
- return "\xEB\x80\xB2";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x8E";
- break;
- case 0xA0 :
- return "\xEB\x81\xAA";
- break;
- case 0xBC :
- return "\xEB\x82\x86";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xA2";
- break;
- case 0xB4 :
- return "\xEB\x82\xBE";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x9A";
- break;
- case 0xAC :
- return "\xEB\x83\xB6";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x92";
- break;
- case 0xA4 :
- return "\xEB\x84\xAE";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x8A";
- break;
- case 0x9C :
- return "\xEB\x85\xA6";
- break;
- case 0xB8 :
- return "\xEB\x86\x82";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x9E";
- break;
- case 0xB0 :
- return "\xEB\x86\xBA";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x96";
- break;
- case 0xA8 :
- return "\xEB\x87\xB2";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x8E";
- break;
- case 0xA0 :
- return "\xEB\x88\xAA";
- break;
- case 0xBC :
- return "\xEB\x89\x86";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xA2";
- break;
- case 0xB4 :
- return "\xEB\x89\xBE";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x9A";
- break;
- case 0xAC :
- return "\xEB\x8A\xB6";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x92";
- break;
- case 0xA4 :
- return "\xEB\x8B\xAE";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x8A";
- break;
- case 0x9C :
- return "\xEB\x8C\xA6";
- break;
- case 0xB8 :
- return "\xEB\x8D\x82";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x9E";
- break;
- case 0xB0 :
- return "\xEB\x8D\xBA";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x96";
- break;
- case 0xA8 :
- return "\xEB\x8E\xB2";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x8E";
- break;
- case 0xA0 :
- return "\xEB\x8F\xAA";
- break;
- case 0xBC :
- return "\xEB\x90\x86";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xA2";
- break;
- case 0xB4 :
- return "\xEB\x90\xBE";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x9A";
- break;
- case 0xAC :
- return "\xEB\x91\xB6";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x92";
- break;
- case 0xA4 :
- return "\xEB\x92\xAE";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x8A";
- break;
- case 0x9C :
- return "\xEB\x93\xA6";
- break;
- case 0xB8 :
- return "\xEB\x94\x82";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x9E";
- break;
- case 0xB0 :
- return "\xEB\x94\xBA";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x96";
- break;
- case 0xA8 :
- return "\xEB\x95\xB2";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x8E";
- break;
- case 0xA0 :
- return "\xEB\x96\xAA";
- break;
- case 0xBC :
- return "\xEB\x97\x86";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xA2";
- break;
- case 0xB4 :
- return "\xEB\x97\xBE";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x9A";
- break;
- case 0xAC :
- return "\xEB\x98\xB6";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x92";
- break;
- case 0xA4 :
- return "\xEB\x99\xAE";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x8A";
- break;
- case 0x9C :
- return "\xEB\x9A\xA6";
- break;
- case 0xB8 :
- return "\xEB\x9B\x82";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x9E";
- break;
- case 0xB0 :
- return "\xEB\x9B\xBA";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x96";
- break;
- case 0xA8 :
- return "\xEB\x9C\xB2";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x8E";
- break;
- case 0xA0 :
- return "\xEB\x9D\xAA";
- break;
- case 0xBC :
- return "\xEB\x9E\x86";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xA2";
- break;
- case 0xB4 :
- return "\xEB\x9E\xBE";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x9A";
- break;
- case 0xAC :
- return "\xEB\x9F\xB6";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x92";
- break;
- case 0xA4 :
- return "\xEB\xA0\xAE";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x8A";
- break;
- case 0x9C :
- return "\xEB\xA1\xA6";
- break;
- case 0xB8 :
- return "\xEB\xA2\x82";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x9E";
- break;
- case 0xB0 :
- return "\xEB\xA2\xBA";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x96";
- break;
- case 0xA8 :
- return "\xEB\xA3\xB2";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x8E";
- break;
- case 0xA0 :
- return "\xEB\xA4\xAA";
- break;
- case 0xBC :
- return "\xEB\xA5\x86";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xA2";
- break;
- case 0xB4 :
- return "\xEB\xA5\xBE";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x9A";
- break;
- case 0xAC :
- return "\xEB\xA6\xB6";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x92";
- break;
- case 0xA4 :
- return "\xEB\xA7\xAE";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x8A";
- break;
- case 0x9C :
- return "\xEB\xA8\xA6";
- break;
- case 0xB8 :
- return "\xEB\xA9\x82";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x9E";
- break;
- case 0xB0 :
- return "\xEB\xA9\xBA";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x96";
- break;
- case 0xA8 :
- return "\xEB\xAA\xB2";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x8E";
- break;
- case 0xA0 :
- return "\xEB\xAB\xAA";
- break;
- case 0xBC :
- return "\xEB\xAC\x86";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xA2";
- break;
- case 0xB4 :
- return "\xEB\xAC\xBE";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x9A";
- break;
- case 0xAC :
- return "\xEB\xAD\xB6";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x92";
- break;
- case 0xA4 :
- return "\xEB\xAE\xAE";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x8A";
- break;
- case 0x9C :
- return "\xEB\xAF\xA6";
- break;
- case 0xB8 :
- return "\xEB\xB0\x82";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x9E";
- break;
- case 0xB0 :
- return "\xEB\xB0\xBA";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x96";
- break;
- case 0xA8 :
- return "\xEB\xB1\xB2";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x8E";
- break;
- case 0xA0 :
- return "\xEB\xB2\xAA";
- break;
- case 0xBC :
- return "\xEB\xB3\x86";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xA2";
- break;
- case 0xB4 :
- return "\xEB\xB3\xBE";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x9A";
- break;
- case 0xAC :
- return "\xEB\xB4\xB6";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x92";
- break;
- case 0xA4 :
- return "\xEB\xB5\xAE";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x8A";
- break;
- case 0x9C :
- return "\xEB\xB6\xA6";
- break;
- case 0xB8 :
- return "\xEB\xB7\x82";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x9E";
- break;
- case 0xB0 :
- return "\xEB\xB7\xBA";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x96";
- break;
- case 0xA8 :
- return "\xEB\xB8\xB2";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x8E";
- break;
- case 0xA0 :
- return "\xEB\xB9\xAA";
- break;
- case 0xBC :
- return "\xEB\xBA\x86";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xA2";
- break;
- case 0xB4 :
- return "\xEB\xBA\xBE";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x9A";
- break;
- case 0xAC :
- return "\xEB\xBB\xB6";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x92";
- break;
- case 0xA4 :
- return "\xEB\xBC\xAE";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x8A";
- break;
- case 0x9C :
- return "\xEB\xBD\xA6";
- break;
- case 0xB8 :
- return "\xEB\xBE\x82";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x9E";
- break;
- case 0xB0 :
- return "\xEB\xBE\xBA";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x96";
- break;
- case 0xA8 :
- return "\xEB\xBF\xB2";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x8E";
- break;
- case 0xA0 :
- return "\xEC\x80\xAA";
- break;
- case 0xBC :
- return "\xEC\x81\x86";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xA2";
- break;
- case 0xB4 :
- return "\xEC\x81\xBE";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x9A";
- break;
- case 0xAC :
- return "\xEC\x82\xB6";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x92";
- break;
- case 0xA4 :
- return "\xEC\x83\xAE";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x8A";
- break;
- case 0x9C :
- return "\xEC\x84\xA6";
- break;
- case 0xB8 :
- return "\xEC\x85\x82";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x9E";
- break;
- case 0xB0 :
- return "\xEC\x85\xBA";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x96";
- break;
- case 0xA8 :
- return "\xEC\x86\xB2";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x8E";
- break;
- case 0xA0 :
- return "\xEC\x87\xAA";
- break;
- case 0xBC :
- return "\xEC\x88\x86";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xA2";
- break;
- case 0xB4 :
- return "\xEC\x88\xBE";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x9A";
- break;
- case 0xAC :
- return "\xEC\x89\xB6";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x92";
- break;
- case 0xA4 :
- return "\xEC\x8A\xAE";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x8A";
- break;
- case 0x9C :
- return "\xEC\x8B\xA6";
- break;
- case 0xB8 :
- return "\xEC\x8C\x82";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x9E";
- break;
- case 0xB0 :
- return "\xEC\x8C\xBA";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x96";
- break;
- case 0xA8 :
- return "\xEC\x8D\xB2";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x8E";
- break;
- case 0xA0 :
- return "\xEC\x8E\xAA";
- break;
- case 0xBC :
- return "\xEC\x8F\x86";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xA2";
- break;
- case 0xB4 :
- return "\xEC\x8F\xBE";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x9A";
- break;
- case 0xAC :
- return "\xEC\x90\xB6";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x92";
- break;
- case 0xA4 :
- return "\xEC\x91\xAE";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x8A";
- break;
- case 0x9C :
- return "\xEC\x92\xA6";
- break;
- case 0xB8 :
- return "\xEC\x93\x82";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x9E";
- break;
- case 0xB0 :
- return "\xEC\x93\xBA";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x96";
- break;
- case 0xA8 :
- return "\xEC\x94\xB2";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x8E";
- break;
- case 0xA0 :
- return "\xEC\x95\xAA";
- break;
- case 0xBC :
- return "\xEC\x96\x86";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xA2";
- break;
- case 0xB4 :
- return "\xEC\x96\xBE";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x9A";
- break;
- case 0xAC :
- return "\xEC\x97\xB6";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x92";
- break;
- case 0xA4 :
- return "\xEC\x98\xAE";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x8A";
- break;
- case 0x9C :
- return "\xEC\x99\xA6";
- break;
- case 0xB8 :
- return "\xEC\x9A\x82";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x9E";
- break;
- case 0xB0 :
- return "\xEC\x9A\xBA";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x96";
- break;
- case 0xA8 :
- return "\xEC\x9B\xB2";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x8E";
- break;
- case 0xA0 :
- return "\xEC\x9C\xAA";
- break;
- case 0xBC :
- return "\xEC\x9D\x86";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xA2";
- break;
- case 0xB4 :
- return "\xEC\x9D\xBE";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x9A";
- break;
- case 0xAC :
- return "\xEC\x9E\xB6";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x92";
- break;
- case 0xA4 :
- return "\xEC\x9F\xAE";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x8A";
- break;
- case 0x9C :
- return "\xEC\xA0\xA6";
- break;
- case 0xB8 :
- return "\xEC\xA1\x82";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x9E";
- break;
- case 0xB0 :
- return "\xEC\xA1\xBA";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x96";
- break;
- case 0xA8 :
- return "\xEC\xA2\xB2";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x8E";
- break;
- case 0xA0 :
- return "\xEC\xA3\xAA";
- break;
- case 0xBC :
- return "\xEC\xA4\x86";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xA2";
- break;
- case 0xB4 :
- return "\xEC\xA4\xBE";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x9A";
- break;
- case 0xAC :
- return "\xEC\xA5\xB6";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x92";
- break;
- case 0xA4 :
- return "\xEC\xA6\xAE";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x8A";
- break;
- case 0x9C :
- return "\xEC\xA7\xA6";
- break;
- case 0xB8 :
- return "\xEC\xA8\x82";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x9E";
- break;
- case 0xB0 :
- return "\xEC\xA8\xBA";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x96";
- break;
- case 0xA8 :
- return "\xEC\xA9\xB2";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x8E";
- break;
- case 0xA0 :
- return "\xEC\xAA\xAA";
- break;
- case 0xBC :
- return "\xEC\xAB\x86";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xA2";
- break;
- case 0xB4 :
- return "\xEC\xAB\xBE";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x9A";
- break;
- case 0xAC :
- return "\xEC\xAC\xB6";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x92";
- break;
- case 0xA4 :
- return "\xEC\xAD\xAE";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x8A";
- break;
- case 0x9C :
- return "\xEC\xAE\xA6";
- break;
- case 0xB8 :
- return "\xEC\xAF\x82";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x9E";
- break;
- case 0xB0 :
- return "\xEC\xAF\xBA";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x96";
- break;
- case 0xA8 :
- return "\xEC\xB0\xB2";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x8E";
- break;
- case 0xA0 :
- return "\xEC\xB1\xAA";
- break;
- case 0xBC :
- return "\xEC\xB2\x86";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xA2";
- break;
- case 0xB4 :
- return "\xEC\xB2\xBE";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x9A";
- break;
- case 0xAC :
- return "\xEC\xB3\xB6";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x92";
- break;
- case 0xA4 :
- return "\xEC\xB4\xAE";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x8A";
- break;
- case 0x9C :
- return "\xEC\xB5\xA6";
- break;
- case 0xB8 :
- return "\xEC\xB6\x82";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x9E";
- break;
- case 0xB0 :
- return "\xEC\xB6\xBA";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x96";
- break;
- case 0xA8 :
- return "\xEC\xB7\xB2";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x8E";
- break;
- case 0xA0 :
- return "\xEC\xB8\xAA";
- break;
- case 0xBC :
- return "\xEC\xB9\x86";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xA2";
- break;
- case 0xB4 :
- return "\xEC\xB9\xBE";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x9A";
- break;
- case 0xAC :
- return "\xEC\xBA\xB6";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x92";
- break;
- case 0xA4 :
- return "\xEC\xBB\xAE";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x8A";
- break;
- case 0x9C :
- return "\xEC\xBC\xA6";
- break;
- case 0xB8 :
- return "\xEC\xBD\x82";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x9E";
- break;
- case 0xB0 :
- return "\xEC\xBD\xBA";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x96";
- break;
- case 0xA8 :
- return "\xEC\xBE\xB2";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x8E";
- break;
- case 0xA0 :
- return "\xEC\xBF\xAA";
- break;
- case 0xBC :
- return "\xED\x80\x86";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xA2";
- break;
- case 0xB4 :
- return "\xED\x80\xBE";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x9A";
- break;
- case 0xAC :
- return "\xED\x81\xB6";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x92";
- break;
- case 0xA4 :
- return "\xED\x82\xAE";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x8A";
- break;
- case 0x9C :
- return "\xED\x83\xA6";
- break;
- case 0xB8 :
- return "\xED\x84\x82";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x9E";
- break;
- case 0xB0 :
- return "\xED\x84\xBA";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x96";
- break;
- case 0xA8 :
- return "\xED\x85\xB2";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x8E";
- break;
- case 0xA0 :
- return "\xED\x86\xAA";
- break;
- case 0xBC :
- return "\xED\x87\x86";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xA2";
- break;
- case 0xB4 :
- return "\xED\x87\xBE";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x9A";
- break;
- case 0xAC :
- return "\xED\x88\xB6";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x92";
- break;
- case 0xA4 :
- return "\xED\x89\xAE";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x8A";
- break;
- case 0x9C :
- return "\xED\x8A\xA6";
- break;
- case 0xB8 :
- return "\xED\x8B\x82";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x9E";
- break;
- case 0xB0 :
- return "\xED\x8B\xBA";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x96";
- break;
- case 0xA8 :
- return "\xED\x8C\xB2";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x8E";
- break;
- case 0xA0 :
- return "\xED\x8D\xAA";
- break;
- case 0xBC :
- return "\xED\x8E\x86";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xA2";
- break;
- case 0xB4 :
- return "\xED\x8E\xBE";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x9A";
- break;
- case 0xAC :
- return "\xED\x8F\xB6";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x92";
- break;
- case 0xA4 :
- return "\xED\x90\xAE";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x8A";
- break;
- case 0x9C :
- return "\xED\x91\xA6";
- break;
- case 0xB8 :
- return "\xED\x92\x82";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x9E";
- break;
- case 0xB0 :
- return "\xED\x92\xBA";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x96";
- break;
- case 0xA8 :
- return "\xED\x93\xB2";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x8E";
- break;
- case 0xA0 :
- return "\xED\x94\xAA";
- break;
- case 0xBC :
- return "\xED\x95\x86";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xA2";
- break;
- case 0xB4 :
- return "\xED\x95\xBE";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x9A";
- break;
- case 0xAC :
- return "\xED\x96\xB6";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x92";
- break;
- case 0xA4 :
- return "\xED\x97\xAE";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x8A";
- break;
- case 0x9C :
- return "\xED\x98\xA6";
- break;
- case 0xB8 :
- return "\xED\x99\x82";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x9E";
- break;
- case 0xB0 :
- return "\xED\x99\xBA";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x96";
- break;
- case 0xA8 :
- return "\xED\x9A\xB2";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x8E";
- break;
- case 0xA0 :
- return "\xED\x9B\xAA";
- break;
- case 0xBC :
- return "\xED\x9C\x86";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xA2";
- break;
- case 0xB4 :
- return "\xED\x9C\xBE";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x9A";
- break;
- case 0xAC :
- return "\xED\x9D\xB6";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x92";
- }
- break;
- }
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x8B";
- break;
- case 0x9C :
- return "\xEA\xB0\xA7";
- break;
- case 0xB8 :
- return "\xEA\xB1\x83";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\x9F";
- break;
- case 0xB0 :
- return "\xEA\xB1\xBB";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x97";
- break;
- case 0xA8 :
- return "\xEA\xB2\xB3";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x8F";
- break;
- case 0xA0 :
- return "\xEA\xB3\xAB";
- break;
- case 0xBC :
- return "\xEA\xB4\x87";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xA3";
- break;
- case 0xB4 :
- return "\xEA\xB4\xBF";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x9B";
- break;
- case 0xAC :
- return "\xEA\xB5\xB7";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x93";
- break;
- case 0xA4 :
- return "\xEA\xB6\xAF";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x8B";
- break;
- case 0x9C :
- return "\xEA\xB7\xA7";
- break;
- case 0xB8 :
- return "\xEA\xB8\x83";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\x9F";
- break;
- case 0xB0 :
- return "\xEA\xB8\xBB";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x97";
- break;
- case 0xA8 :
- return "\xEA\xB9\xB3";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x8F";
- break;
- case 0xA0 :
- return "\xEA\xBA\xAB";
- break;
- case 0xBC :
- return "\xEA\xBB\x87";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xA3";
- break;
- case 0xB4 :
- return "\xEA\xBB\xBF";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x9B";
- break;
- case 0xAC :
- return "\xEA\xBC\xB7";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x93";
- break;
- case 0xA4 :
- return "\xEA\xBD\xAF";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x8B";
- break;
- case 0x9C :
- return "\xEA\xBE\xA7";
- break;
- case 0xB8 :
- return "\xEA\xBF\x83";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\x9F";
- break;
- case 0xB0 :
- return "\xEA\xBF\xBB";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x97";
- break;
- case 0xA8 :
- return "\xEB\x80\xB3";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x8F";
- break;
- case 0xA0 :
- return "\xEB\x81\xAB";
- break;
- case 0xBC :
- return "\xEB\x82\x87";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xA3";
- break;
- case 0xB4 :
- return "\xEB\x82\xBF";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x9B";
- break;
- case 0xAC :
- return "\xEB\x83\xB7";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x93";
- break;
- case 0xA4 :
- return "\xEB\x84\xAF";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x8B";
- break;
- case 0x9C :
- return "\xEB\x85\xA7";
- break;
- case 0xB8 :
- return "\xEB\x86\x83";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\x9F";
- break;
- case 0xB0 :
- return "\xEB\x86\xBB";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x97";
- break;
- case 0xA8 :
- return "\xEB\x87\xB3";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x8F";
- break;
- case 0xA0 :
- return "\xEB\x88\xAB";
- break;
- case 0xBC :
- return "\xEB\x89\x87";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xA3";
- break;
- case 0xB4 :
- return "\xEB\x89\xBF";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x9B";
- break;
- case 0xAC :
- return "\xEB\x8A\xB7";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x93";
- break;
- case 0xA4 :
- return "\xEB\x8B\xAF";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x8B";
- break;
- case 0x9C :
- return "\xEB\x8C\xA7";
- break;
- case 0xB8 :
- return "\xEB\x8D\x83";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\x9F";
- break;
- case 0xB0 :
- return "\xEB\x8D\xBB";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x97";
- break;
- case 0xA8 :
- return "\xEB\x8E\xB3";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x8F";
- break;
- case 0xA0 :
- return "\xEB\x8F\xAB";
- break;
- case 0xBC :
- return "\xEB\x90\x87";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xA3";
- break;
- case 0xB4 :
- return "\xEB\x90\xBF";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x9B";
- break;
- case 0xAC :
- return "\xEB\x91\xB7";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x93";
- break;
- case 0xA4 :
- return "\xEB\x92\xAF";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x8B";
- break;
- case 0x9C :
- return "\xEB\x93\xA7";
- break;
- case 0xB8 :
- return "\xEB\x94\x83";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\x9F";
- break;
- case 0xB0 :
- return "\xEB\x94\xBB";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x97";
- break;
- case 0xA8 :
- return "\xEB\x95\xB3";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x8F";
- break;
- case 0xA0 :
- return "\xEB\x96\xAB";
- break;
- case 0xBC :
- return "\xEB\x97\x87";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xA3";
- break;
- case 0xB4 :
- return "\xEB\x97\xBF";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x9B";
- break;
- case 0xAC :
- return "\xEB\x98\xB7";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x93";
- break;
- case 0xA4 :
- return "\xEB\x99\xAF";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x8B";
- break;
- case 0x9C :
- return "\xEB\x9A\xA7";
- break;
- case 0xB8 :
- return "\xEB\x9B\x83";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\x9F";
- break;
- case 0xB0 :
- return "\xEB\x9B\xBB";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x97";
- break;
- case 0xA8 :
- return "\xEB\x9C\xB3";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x8F";
- break;
- case 0xA0 :
- return "\xEB\x9D\xAB";
- break;
- case 0xBC :
- return "\xEB\x9E\x87";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xA3";
- break;
- case 0xB4 :
- return "\xEB\x9E\xBF";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x9B";
- break;
- case 0xAC :
- return "\xEB\x9F\xB7";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x93";
- break;
- case 0xA4 :
- return "\xEB\xA0\xAF";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x8B";
- break;
- case 0x9C :
- return "\xEB\xA1\xA7";
- break;
- case 0xB8 :
- return "\xEB\xA2\x83";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\x9F";
- break;
- case 0xB0 :
- return "\xEB\xA2\xBB";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x97";
- break;
- case 0xA8 :
- return "\xEB\xA3\xB3";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x8F";
- break;
- case 0xA0 :
- return "\xEB\xA4\xAB";
- break;
- case 0xBC :
- return "\xEB\xA5\x87";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xA3";
- break;
- case 0xB4 :
- return "\xEB\xA5\xBF";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x9B";
- break;
- case 0xAC :
- return "\xEB\xA6\xB7";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x93";
- break;
- case 0xA4 :
- return "\xEB\xA7\xAF";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x8B";
- break;
- case 0x9C :
- return "\xEB\xA8\xA7";
- break;
- case 0xB8 :
- return "\xEB\xA9\x83";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\x9F";
- break;
- case 0xB0 :
- return "\xEB\xA9\xBB";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x97";
- break;
- case 0xA8 :
- return "\xEB\xAA\xB3";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x8F";
- break;
- case 0xA0 :
- return "\xEB\xAB\xAB";
- break;
- case 0xBC :
- return "\xEB\xAC\x87";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xA3";
- break;
- case 0xB4 :
- return "\xEB\xAC\xBF";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x9B";
- break;
- case 0xAC :
- return "\xEB\xAD\xB7";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x93";
- break;
- case 0xA4 :
- return "\xEB\xAE\xAF";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x8B";
- break;
- case 0x9C :
- return "\xEB\xAF\xA7";
- break;
- case 0xB8 :
- return "\xEB\xB0\x83";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\x9F";
- break;
- case 0xB0 :
- return "\xEB\xB0\xBB";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x97";
- break;
- case 0xA8 :
- return "\xEB\xB1\xB3";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x8F";
- break;
- case 0xA0 :
- return "\xEB\xB2\xAB";
- break;
- case 0xBC :
- return "\xEB\xB3\x87";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xA3";
- break;
- case 0xB4 :
- return "\xEB\xB3\xBF";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x9B";
- break;
- case 0xAC :
- return "\xEB\xB4\xB7";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x93";
- break;
- case 0xA4 :
- return "\xEB\xB5\xAF";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x8B";
- break;
- case 0x9C :
- return "\xEB\xB6\xA7";
- break;
- case 0xB8 :
- return "\xEB\xB7\x83";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\x9F";
- break;
- case 0xB0 :
- return "\xEB\xB7\xBB";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x97";
- break;
- case 0xA8 :
- return "\xEB\xB8\xB3";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x8F";
- break;
- case 0xA0 :
- return "\xEB\xB9\xAB";
- break;
- case 0xBC :
- return "\xEB\xBA\x87";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xA3";
- break;
- case 0xB4 :
- return "\xEB\xBA\xBF";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x9B";
- break;
- case 0xAC :
- return "\xEB\xBB\xB7";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x93";
- break;
- case 0xA4 :
- return "\xEB\xBC\xAF";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x8B";
- break;
- case 0x9C :
- return "\xEB\xBD\xA7";
- break;
- case 0xB8 :
- return "\xEB\xBE\x83";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\x9F";
- break;
- case 0xB0 :
- return "\xEB\xBE\xBB";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x97";
- break;
- case 0xA8 :
- return "\xEB\xBF\xB3";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x8F";
- break;
- case 0xA0 :
- return "\xEC\x80\xAB";
- break;
- case 0xBC :
- return "\xEC\x81\x87";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xA3";
- break;
- case 0xB4 :
- return "\xEC\x81\xBF";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x9B";
- break;
- case 0xAC :
- return "\xEC\x82\xB7";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x93";
- break;
- case 0xA4 :
- return "\xEC\x83\xAF";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x8B";
- break;
- case 0x9C :
- return "\xEC\x84\xA7";
- break;
- case 0xB8 :
- return "\xEC\x85\x83";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\x9F";
- break;
- case 0xB0 :
- return "\xEC\x85\xBB";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x97";
- break;
- case 0xA8 :
- return "\xEC\x86\xB3";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x8F";
- break;
- case 0xA0 :
- return "\xEC\x87\xAB";
- break;
- case 0xBC :
- return "\xEC\x88\x87";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xA3";
- break;
- case 0xB4 :
- return "\xEC\x88\xBF";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x9B";
- break;
- case 0xAC :
- return "\xEC\x89\xB7";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x93";
- break;
- case 0xA4 :
- return "\xEC\x8A\xAF";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x8B";
- break;
- case 0x9C :
- return "\xEC\x8B\xA7";
- break;
- case 0xB8 :
- return "\xEC\x8C\x83";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\x9F";
- break;
- case 0xB0 :
- return "\xEC\x8C\xBB";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x97";
- break;
- case 0xA8 :
- return "\xEC\x8D\xB3";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x8F";
- break;
- case 0xA0 :
- return "\xEC\x8E\xAB";
- break;
- case 0xBC :
- return "\xEC\x8F\x87";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xA3";
- break;
- case 0xB4 :
- return "\xEC\x8F\xBF";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x9B";
- break;
- case 0xAC :
- return "\xEC\x90\xB7";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x93";
- break;
- case 0xA4 :
- return "\xEC\x91\xAF";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x8B";
- break;
- case 0x9C :
- return "\xEC\x92\xA7";
- break;
- case 0xB8 :
- return "\xEC\x93\x83";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\x9F";
- break;
- case 0xB0 :
- return "\xEC\x93\xBB";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x97";
- break;
- case 0xA8 :
- return "\xEC\x94\xB3";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x8F";
- break;
- case 0xA0 :
- return "\xEC\x95\xAB";
- break;
- case 0xBC :
- return "\xEC\x96\x87";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xA3";
- break;
- case 0xB4 :
- return "\xEC\x96\xBF";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x9B";
- break;
- case 0xAC :
- return "\xEC\x97\xB7";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x93";
- break;
- case 0xA4 :
- return "\xEC\x98\xAF";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x8B";
- break;
- case 0x9C :
- return "\xEC\x99\xA7";
- break;
- case 0xB8 :
- return "\xEC\x9A\x83";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\x9F";
- break;
- case 0xB0 :
- return "\xEC\x9A\xBB";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x97";
- break;
- case 0xA8 :
- return "\xEC\x9B\xB3";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x8F";
- break;
- case 0xA0 :
- return "\xEC\x9C\xAB";
- break;
- case 0xBC :
- return "\xEC\x9D\x87";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xA3";
- break;
- case 0xB4 :
- return "\xEC\x9D\xBF";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x9B";
- break;
- case 0xAC :
- return "\xEC\x9E\xB7";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x93";
- break;
- case 0xA4 :
- return "\xEC\x9F\xAF";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x8B";
- break;
- case 0x9C :
- return "\xEC\xA0\xA7";
- break;
- case 0xB8 :
- return "\xEC\xA1\x83";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\x9F";
- break;
- case 0xB0 :
- return "\xEC\xA1\xBB";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x97";
- break;
- case 0xA8 :
- return "\xEC\xA2\xB3";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x8F";
- break;
- case 0xA0 :
- return "\xEC\xA3\xAB";
- break;
- case 0xBC :
- return "\xEC\xA4\x87";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xA3";
- break;
- case 0xB4 :
- return "\xEC\xA4\xBF";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x9B";
- break;
- case 0xAC :
- return "\xEC\xA5\xB7";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x93";
- break;
- case 0xA4 :
- return "\xEC\xA6\xAF";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x8B";
- break;
- case 0x9C :
- return "\xEC\xA7\xA7";
- break;
- case 0xB8 :
- return "\xEC\xA8\x83";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\x9F";
- break;
- case 0xB0 :
- return "\xEC\xA8\xBB";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x97";
- break;
- case 0xA8 :
- return "\xEC\xA9\xB3";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x8F";
- break;
- case 0xA0 :
- return "\xEC\xAA\xAB";
- break;
- case 0xBC :
- return "\xEC\xAB\x87";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xA3";
- break;
- case 0xB4 :
- return "\xEC\xAB\xBF";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x9B";
- break;
- case 0xAC :
- return "\xEC\xAC\xB7";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x93";
- break;
- case 0xA4 :
- return "\xEC\xAD\xAF";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x8B";
- break;
- case 0x9C :
- return "\xEC\xAE\xA7";
- break;
- case 0xB8 :
- return "\xEC\xAF\x83";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\x9F";
- break;
- case 0xB0 :
- return "\xEC\xAF\xBB";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x97";
- break;
- case 0xA8 :
- return "\xEC\xB0\xB3";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x8F";
- break;
- case 0xA0 :
- return "\xEC\xB1\xAB";
- break;
- case 0xBC :
- return "\xEC\xB2\x87";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xA3";
- break;
- case 0xB4 :
- return "\xEC\xB2\xBF";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x9B";
- break;
- case 0xAC :
- return "\xEC\xB3\xB7";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x93";
- break;
- case 0xA4 :
- return "\xEC\xB4\xAF";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x8B";
- break;
- case 0x9C :
- return "\xEC\xB5\xA7";
- break;
- case 0xB8 :
- return "\xEC\xB6\x83";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\x9F";
- break;
- case 0xB0 :
- return "\xEC\xB6\xBB";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x97";
- break;
- case 0xA8 :
- return "\xEC\xB7\xB3";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x8F";
- break;
- case 0xA0 :
- return "\xEC\xB8\xAB";
- break;
- case 0xBC :
- return "\xEC\xB9\x87";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xA3";
- break;
- case 0xB4 :
- return "\xEC\xB9\xBF";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x9B";
- break;
- case 0xAC :
- return "\xEC\xBA\xB7";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x93";
- break;
- case 0xA4 :
- return "\xEC\xBB\xAF";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x8B";
- break;
- case 0x9C :
- return "\xEC\xBC\xA7";
- break;
- case 0xB8 :
- return "\xEC\xBD\x83";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\x9F";
- break;
- case 0xB0 :
- return "\xEC\xBD\xBB";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x97";
- break;
- case 0xA8 :
- return "\xEC\xBE\xB3";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x8F";
- break;
- case 0xA0 :
- return "\xEC\xBF\xAB";
- break;
- case 0xBC :
- return "\xED\x80\x87";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xA3";
- break;
- case 0xB4 :
- return "\xED\x80\xBF";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x9B";
- break;
- case 0xAC :
- return "\xED\x81\xB7";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x93";
- break;
- case 0xA4 :
- return "\xED\x82\xAF";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x8B";
- break;
- case 0x9C :
- return "\xED\x83\xA7";
- break;
- case 0xB8 :
- return "\xED\x84\x83";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\x9F";
- break;
- case 0xB0 :
- return "\xED\x84\xBB";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x97";
- break;
- case 0xA8 :
- return "\xED\x85\xB3";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x8F";
- break;
- case 0xA0 :
- return "\xED\x86\xAB";
- break;
- case 0xBC :
- return "\xED\x87\x87";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xA3";
- break;
- case 0xB4 :
- return "\xED\x87\xBF";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x9B";
- break;
- case 0xAC :
- return "\xED\x88\xB7";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x93";
- break;
- case 0xA4 :
- return "\xED\x89\xAF";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x8B";
- break;
- case 0x9C :
- return "\xED\x8A\xA7";
- break;
- case 0xB8 :
- return "\xED\x8B\x83";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\x9F";
- break;
- case 0xB0 :
- return "\xED\x8B\xBB";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x97";
- break;
- case 0xA8 :
- return "\xED\x8C\xB3";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x8F";
- break;
- case 0xA0 :
- return "\xED\x8D\xAB";
- break;
- case 0xBC :
- return "\xED\x8E\x87";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xA3";
- break;
- case 0xB4 :
- return "\xED\x8E\xBF";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x9B";
- break;
- case 0xAC :
- return "\xED\x8F\xB7";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x93";
- break;
- case 0xA4 :
- return "\xED\x90\xAF";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x8B";
- break;
- case 0x9C :
- return "\xED\x91\xA7";
- break;
- case 0xB8 :
- return "\xED\x92\x83";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\x9F";
- break;
- case 0xB0 :
- return "\xED\x92\xBB";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x97";
- break;
- case 0xA8 :
- return "\xED\x93\xB3";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x8F";
- break;
- case 0xA0 :
- return "\xED\x94\xAB";
- break;
- case 0xBC :
- return "\xED\x95\x87";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xA3";
- break;
- case 0xB4 :
- return "\xED\x95\xBF";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x9B";
- break;
- case 0xAC :
- return "\xED\x96\xB7";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x93";
- break;
- case 0xA4 :
- return "\xED\x97\xAF";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x8B";
- break;
- case 0x9C :
- return "\xED\x98\xA7";
- break;
- case 0xB8 :
- return "\xED\x99\x83";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\x9F";
- break;
- case 0xB0 :
- return "\xED\x99\xBB";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x97";
- break;
- case 0xA8 :
- return "\xED\x9A\xB3";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x8F";
- break;
- case 0xA0 :
- return "\xED\x9B\xAB";
- break;
- case 0xBC :
- return "\xED\x9C\x87";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xA3";
- break;
- case 0xB4 :
- return "\xED\x9C\xBF";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x9B";
- break;
- case 0xAC :
- return "\xED\x9D\xB7";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x93";
- }
- break;
- }
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x8C";
- break;
- case 0x9C :
- return "\xEA\xB0\xA8";
- break;
- case 0xB8 :
- return "\xEA\xB1\x84";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xA0";
- break;
- case 0xB0 :
- return "\xEA\xB1\xBC";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x98";
- break;
- case 0xA8 :
- return "\xEA\xB2\xB4";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x90";
- break;
- case 0xA0 :
- return "\xEA\xB3\xAC";
- break;
- case 0xBC :
- return "\xEA\xB4\x88";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xA4";
- break;
- case 0xB4 :
- return "\xEA\xB5\x80";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x9C";
- break;
- case 0xAC :
- return "\xEA\xB5\xB8";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x94";
- break;
- case 0xA4 :
- return "\xEA\xB6\xB0";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x8C";
- break;
- case 0x9C :
- return "\xEA\xB7\xA8";
- break;
- case 0xB8 :
- return "\xEA\xB8\x84";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xA0";
- break;
- case 0xB0 :
- return "\xEA\xB8\xBC";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x98";
- break;
- case 0xA8 :
- return "\xEA\xB9\xB4";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x90";
- break;
- case 0xA0 :
- return "\xEA\xBA\xAC";
- break;
- case 0xBC :
- return "\xEA\xBB\x88";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xA4";
- break;
- case 0xB4 :
- return "\xEA\xBC\x80";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x9C";
- break;
- case 0xAC :
- return "\xEA\xBC\xB8";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x94";
- break;
- case 0xA4 :
- return "\xEA\xBD\xB0";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x8C";
- break;
- case 0x9C :
- return "\xEA\xBE\xA8";
- break;
- case 0xB8 :
- return "\xEA\xBF\x84";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xA0";
- break;
- case 0xB0 :
- return "\xEA\xBF\xBC";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x98";
- break;
- case 0xA8 :
- return "\xEB\x80\xB4";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x90";
- break;
- case 0xA0 :
- return "\xEB\x81\xAC";
- break;
- case 0xBC :
- return "\xEB\x82\x88";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xA4";
- break;
- case 0xB4 :
- return "\xEB\x83\x80";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x9C";
- break;
- case 0xAC :
- return "\xEB\x83\xB8";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x94";
- break;
- case 0xA4 :
- return "\xEB\x84\xB0";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x8C";
- break;
- case 0x9C :
- return "\xEB\x85\xA8";
- break;
- case 0xB8 :
- return "\xEB\x86\x84";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xA0";
- break;
- case 0xB0 :
- return "\xEB\x86\xBC";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x98";
- break;
- case 0xA8 :
- return "\xEB\x87\xB4";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x90";
- break;
- case 0xA0 :
- return "\xEB\x88\xAC";
- break;
- case 0xBC :
- return "\xEB\x89\x88";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xA4";
- break;
- case 0xB4 :
- return "\xEB\x8A\x80";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x9C";
- break;
- case 0xAC :
- return "\xEB\x8A\xB8";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x94";
- break;
- case 0xA4 :
- return "\xEB\x8B\xB0";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x8C";
- break;
- case 0x9C :
- return "\xEB\x8C\xA8";
- break;
- case 0xB8 :
- return "\xEB\x8D\x84";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xA0";
- break;
- case 0xB0 :
- return "\xEB\x8D\xBC";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x98";
- break;
- case 0xA8 :
- return "\xEB\x8E\xB4";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x90";
- break;
- case 0xA0 :
- return "\xEB\x8F\xAC";
- break;
- case 0xBC :
- return "\xEB\x90\x88";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xA4";
- break;
- case 0xB4 :
- return "\xEB\x91\x80";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x9C";
- break;
- case 0xAC :
- return "\xEB\x91\xB8";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x94";
- break;
- case 0xA4 :
- return "\xEB\x92\xB0";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x8C";
- break;
- case 0x9C :
- return "\xEB\x93\xA8";
- break;
- case 0xB8 :
- return "\xEB\x94\x84";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xA0";
- break;
- case 0xB0 :
- return "\xEB\x94\xBC";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x98";
- break;
- case 0xA8 :
- return "\xEB\x95\xB4";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x90";
- break;
- case 0xA0 :
- return "\xEB\x96\xAC";
- break;
- case 0xBC :
- return "\xEB\x97\x88";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xA4";
- break;
- case 0xB4 :
- return "\xEB\x98\x80";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x9C";
- break;
- case 0xAC :
- return "\xEB\x98\xB8";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x94";
- break;
- case 0xA4 :
- return "\xEB\x99\xB0";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x8C";
- break;
- case 0x9C :
- return "\xEB\x9A\xA8";
- break;
- case 0xB8 :
- return "\xEB\x9B\x84";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xA0";
- break;
- case 0xB0 :
- return "\xEB\x9B\xBC";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x98";
- break;
- case 0xA8 :
- return "\xEB\x9C\xB4";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x90";
- break;
- case 0xA0 :
- return "\xEB\x9D\xAC";
- break;
- case 0xBC :
- return "\xEB\x9E\x88";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xA4";
- break;
- case 0xB4 :
- return "\xEB\x9F\x80";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x9C";
- break;
- case 0xAC :
- return "\xEB\x9F\xB8";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x94";
- break;
- case 0xA4 :
- return "\xEB\xA0\xB0";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x8C";
- break;
- case 0x9C :
- return "\xEB\xA1\xA8";
- break;
- case 0xB8 :
- return "\xEB\xA2\x84";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xA0";
- break;
- case 0xB0 :
- return "\xEB\xA2\xBC";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x98";
- break;
- case 0xA8 :
- return "\xEB\xA3\xB4";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x90";
- break;
- case 0xA0 :
- return "\xEB\xA4\xAC";
- break;
- case 0xBC :
- return "\xEB\xA5\x88";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xA4";
- break;
- case 0xB4 :
- return "\xEB\xA6\x80";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x9C";
- break;
- case 0xAC :
- return "\xEB\xA6\xB8";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x94";
- break;
- case 0xA4 :
- return "\xEB\xA7\xB0";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x8C";
- break;
- case 0x9C :
- return "\xEB\xA8\xA8";
- break;
- case 0xB8 :
- return "\xEB\xA9\x84";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xA0";
- break;
- case 0xB0 :
- return "\xEB\xA9\xBC";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x98";
- break;
- case 0xA8 :
- return "\xEB\xAA\xB4";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x90";
- break;
- case 0xA0 :
- return "\xEB\xAB\xAC";
- break;
- case 0xBC :
- return "\xEB\xAC\x88";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xA4";
- break;
- case 0xB4 :
- return "\xEB\xAD\x80";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x9C";
- break;
- case 0xAC :
- return "\xEB\xAD\xB8";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x94";
- break;
- case 0xA4 :
- return "\xEB\xAE\xB0";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x8C";
- break;
- case 0x9C :
- return "\xEB\xAF\xA8";
- break;
- case 0xB8 :
- return "\xEB\xB0\x84";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xA0";
- break;
- case 0xB0 :
- return "\xEB\xB0\xBC";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x98";
- break;
- case 0xA8 :
- return "\xEB\xB1\xB4";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x90";
- break;
- case 0xA0 :
- return "\xEB\xB2\xAC";
- break;
- case 0xBC :
- return "\xEB\xB3\x88";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xA4";
- break;
- case 0xB4 :
- return "\xEB\xB4\x80";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x9C";
- break;
- case 0xAC :
- return "\xEB\xB4\xB8";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x94";
- break;
- case 0xA4 :
- return "\xEB\xB5\xB0";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x8C";
- break;
- case 0x9C :
- return "\xEB\xB6\xA8";
- break;
- case 0xB8 :
- return "\xEB\xB7\x84";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xA0";
- break;
- case 0xB0 :
- return "\xEB\xB7\xBC";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x98";
- break;
- case 0xA8 :
- return "\xEB\xB8\xB4";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x90";
- break;
- case 0xA0 :
- return "\xEB\xB9\xAC";
- break;
- case 0xBC :
- return "\xEB\xBA\x88";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xA4";
- break;
- case 0xB4 :
- return "\xEB\xBB\x80";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x9C";
- break;
- case 0xAC :
- return "\xEB\xBB\xB8";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x94";
- break;
- case 0xA4 :
- return "\xEB\xBC\xB0";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x8C";
- break;
- case 0x9C :
- return "\xEB\xBD\xA8";
- break;
- case 0xB8 :
- return "\xEB\xBE\x84";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xA0";
- break;
- case 0xB0 :
- return "\xEB\xBE\xBC";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x98";
- break;
- case 0xA8 :
- return "\xEB\xBF\xB4";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x90";
- break;
- case 0xA0 :
- return "\xEC\x80\xAC";
- break;
- case 0xBC :
- return "\xEC\x81\x88";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xA4";
- break;
- case 0xB4 :
- return "\xEC\x82\x80";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x9C";
- break;
- case 0xAC :
- return "\xEC\x82\xB8";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x94";
- break;
- case 0xA4 :
- return "\xEC\x83\xB0";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x8C";
- break;
- case 0x9C :
- return "\xEC\x84\xA8";
- break;
- case 0xB8 :
- return "\xEC\x85\x84";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xA0";
- break;
- case 0xB0 :
- return "\xEC\x85\xBC";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x98";
- break;
- case 0xA8 :
- return "\xEC\x86\xB4";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x90";
- break;
- case 0xA0 :
- return "\xEC\x87\xAC";
- break;
- case 0xBC :
- return "\xEC\x88\x88";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xA4";
- break;
- case 0xB4 :
- return "\xEC\x89\x80";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x9C";
- break;
- case 0xAC :
- return "\xEC\x89\xB8";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x94";
- break;
- case 0xA4 :
- return "\xEC\x8A\xB0";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x8C";
- break;
- case 0x9C :
- return "\xEC\x8B\xA8";
- break;
- case 0xB8 :
- return "\xEC\x8C\x84";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xA0";
- break;
- case 0xB0 :
- return "\xEC\x8C\xBC";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x98";
- break;
- case 0xA8 :
- return "\xEC\x8D\xB4";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x90";
- break;
- case 0xA0 :
- return "\xEC\x8E\xAC";
- break;
- case 0xBC :
- return "\xEC\x8F\x88";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xA4";
- break;
- case 0xB4 :
- return "\xEC\x90\x80";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x9C";
- break;
- case 0xAC :
- return "\xEC\x90\xB8";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x94";
- break;
- case 0xA4 :
- return "\xEC\x91\xB0";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x8C";
- break;
- case 0x9C :
- return "\xEC\x92\xA8";
- break;
- case 0xB8 :
- return "\xEC\x93\x84";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xA0";
- break;
- case 0xB0 :
- return "\xEC\x93\xBC";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x98";
- break;
- case 0xA8 :
- return "\xEC\x94\xB4";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x90";
- break;
- case 0xA0 :
- return "\xEC\x95\xAC";
- break;
- case 0xBC :
- return "\xEC\x96\x88";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xA4";
- break;
- case 0xB4 :
- return "\xEC\x97\x80";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x9C";
- break;
- case 0xAC :
- return "\xEC\x97\xB8";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x94";
- break;
- case 0xA4 :
- return "\xEC\x98\xB0";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x8C";
- break;
- case 0x9C :
- return "\xEC\x99\xA8";
- break;
- case 0xB8 :
- return "\xEC\x9A\x84";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xA0";
- break;
- case 0xB0 :
- return "\xEC\x9A\xBC";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x98";
- break;
- case 0xA8 :
- return "\xEC\x9B\xB4";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x90";
- break;
- case 0xA0 :
- return "\xEC\x9C\xAC";
- break;
- case 0xBC :
- return "\xEC\x9D\x88";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xA4";
- break;
- case 0xB4 :
- return "\xEC\x9E\x80";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x9C";
- break;
- case 0xAC :
- return "\xEC\x9E\xB8";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x94";
- break;
- case 0xA4 :
- return "\xEC\x9F\xB0";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x8C";
- break;
- case 0x9C :
- return "\xEC\xA0\xA8";
- break;
- case 0xB8 :
- return "\xEC\xA1\x84";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xA0";
- break;
- case 0xB0 :
- return "\xEC\xA1\xBC";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x98";
- break;
- case 0xA8 :
- return "\xEC\xA2\xB4";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x90";
- break;
- case 0xA0 :
- return "\xEC\xA3\xAC";
- break;
- case 0xBC :
- return "\xEC\xA4\x88";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xA4";
- break;
- case 0xB4 :
- return "\xEC\xA5\x80";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x9C";
- break;
- case 0xAC :
- return "\xEC\xA5\xB8";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x94";
- break;
- case 0xA4 :
- return "\xEC\xA6\xB0";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x8C";
- break;
- case 0x9C :
- return "\xEC\xA7\xA8";
- break;
- case 0xB8 :
- return "\xEC\xA8\x84";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xA0";
- break;
- case 0xB0 :
- return "\xEC\xA8\xBC";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x98";
- break;
- case 0xA8 :
- return "\xEC\xA9\xB4";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x90";
- break;
- case 0xA0 :
- return "\xEC\xAA\xAC";
- break;
- case 0xBC :
- return "\xEC\xAB\x88";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xA4";
- break;
- case 0xB4 :
- return "\xEC\xAC\x80";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x9C";
- break;
- case 0xAC :
- return "\xEC\xAC\xB8";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x94";
- break;
- case 0xA4 :
- return "\xEC\xAD\xB0";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x8C";
- break;
- case 0x9C :
- return "\xEC\xAE\xA8";
- break;
- case 0xB8 :
- return "\xEC\xAF\x84";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xA0";
- break;
- case 0xB0 :
- return "\xEC\xAF\xBC";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x98";
- break;
- case 0xA8 :
- return "\xEC\xB0\xB4";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x90";
- break;
- case 0xA0 :
- return "\xEC\xB1\xAC";
- break;
- case 0xBC :
- return "\xEC\xB2\x88";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xA4";
- break;
- case 0xB4 :
- return "\xEC\xB3\x80";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x9C";
- break;
- case 0xAC :
- return "\xEC\xB3\xB8";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x94";
- break;
- case 0xA4 :
- return "\xEC\xB4\xB0";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x8C";
- break;
- case 0x9C :
- return "\xEC\xB5\xA8";
- break;
- case 0xB8 :
- return "\xEC\xB6\x84";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xA0";
- break;
- case 0xB0 :
- return "\xEC\xB6\xBC";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x98";
- break;
- case 0xA8 :
- return "\xEC\xB7\xB4";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x90";
- break;
- case 0xA0 :
- return "\xEC\xB8\xAC";
- break;
- case 0xBC :
- return "\xEC\xB9\x88";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xA4";
- break;
- case 0xB4 :
- return "\xEC\xBA\x80";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x9C";
- break;
- case 0xAC :
- return "\xEC\xBA\xB8";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x94";
- break;
- case 0xA4 :
- return "\xEC\xBB\xB0";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x8C";
- break;
- case 0x9C :
- return "\xEC\xBC\xA8";
- break;
- case 0xB8 :
- return "\xEC\xBD\x84";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xA0";
- break;
- case 0xB0 :
- return "\xEC\xBD\xBC";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x98";
- break;
- case 0xA8 :
- return "\xEC\xBE\xB4";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x90";
- break;
- case 0xA0 :
- return "\xEC\xBF\xAC";
- break;
- case 0xBC :
- return "\xED\x80\x88";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xA4";
- break;
- case 0xB4 :
- return "\xED\x81\x80";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x9C";
- break;
- case 0xAC :
- return "\xED\x81\xB8";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x94";
- break;
- case 0xA4 :
- return "\xED\x82\xB0";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x8C";
- break;
- case 0x9C :
- return "\xED\x83\xA8";
- break;
- case 0xB8 :
- return "\xED\x84\x84";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xA0";
- break;
- case 0xB0 :
- return "\xED\x84\xBC";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x98";
- break;
- case 0xA8 :
- return "\xED\x85\xB4";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x90";
- break;
- case 0xA0 :
- return "\xED\x86\xAC";
- break;
- case 0xBC :
- return "\xED\x87\x88";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xA4";
- break;
- case 0xB4 :
- return "\xED\x88\x80";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x9C";
- break;
- case 0xAC :
- return "\xED\x88\xB8";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x94";
- break;
- case 0xA4 :
- return "\xED\x89\xB0";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x8C";
- break;
- case 0x9C :
- return "\xED\x8A\xA8";
- break;
- case 0xB8 :
- return "\xED\x8B\x84";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xA0";
- break;
- case 0xB0 :
- return "\xED\x8B\xBC";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x98";
- break;
- case 0xA8 :
- return "\xED\x8C\xB4";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x90";
- break;
- case 0xA0 :
- return "\xED\x8D\xAC";
- break;
- case 0xBC :
- return "\xED\x8E\x88";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xA4";
- break;
- case 0xB4 :
- return "\xED\x8F\x80";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x9C";
- break;
- case 0xAC :
- return "\xED\x8F\xB8";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x94";
- break;
- case 0xA4 :
- return "\xED\x90\xB0";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x8C";
- break;
- case 0x9C :
- return "\xED\x91\xA8";
- break;
- case 0xB8 :
- return "\xED\x92\x84";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xA0";
- break;
- case 0xB0 :
- return "\xED\x92\xBC";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x98";
- break;
- case 0xA8 :
- return "\xED\x93\xB4";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x90";
- break;
- case 0xA0 :
- return "\xED\x94\xAC";
- break;
- case 0xBC :
- return "\xED\x95\x88";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xA4";
- break;
- case 0xB4 :
- return "\xED\x96\x80";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x9C";
- break;
- case 0xAC :
- return "\xED\x96\xB8";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x94";
- break;
- case 0xA4 :
- return "\xED\x97\xB0";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x8C";
- break;
- case 0x9C :
- return "\xED\x98\xA8";
- break;
- case 0xB8 :
- return "\xED\x99\x84";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xA0";
- break;
- case 0xB0 :
- return "\xED\x99\xBC";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x98";
- break;
- case 0xA8 :
- return "\xED\x9A\xB4";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x90";
- break;
- case 0xA0 :
- return "\xED\x9B\xAC";
- break;
- case 0xBC :
- return "\xED\x9C\x88";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xA4";
- break;
- case 0xB4 :
- return "\xED\x9D\x80";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x9C";
- break;
- case 0xAC :
- return "\xED\x9D\xB8";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x94";
- }
- break;
- }
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x8D";
- break;
- case 0x9C :
- return "\xEA\xB0\xA9";
- break;
- case 0xB8 :
- return "\xEA\xB1\x85";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xA1";
- break;
- case 0xB0 :
- return "\xEA\xB1\xBD";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x99";
- break;
- case 0xA8 :
- return "\xEA\xB2\xB5";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x91";
- break;
- case 0xA0 :
- return "\xEA\xB3\xAD";
- break;
- case 0xBC :
- return "\xEA\xB4\x89";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xA5";
- break;
- case 0xB4 :
- return "\xEA\xB5\x81";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x9D";
- break;
- case 0xAC :
- return "\xEA\xB5\xB9";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x95";
- break;
- case 0xA4 :
- return "\xEA\xB6\xB1";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x8D";
- break;
- case 0x9C :
- return "\xEA\xB7\xA9";
- break;
- case 0xB8 :
- return "\xEA\xB8\x85";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xA1";
- break;
- case 0xB0 :
- return "\xEA\xB8\xBD";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x99";
- break;
- case 0xA8 :
- return "\xEA\xB9\xB5";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x91";
- break;
- case 0xA0 :
- return "\xEA\xBA\xAD";
- break;
- case 0xBC :
- return "\xEA\xBB\x89";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xA5";
- break;
- case 0xB4 :
- return "\xEA\xBC\x81";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x9D";
- break;
- case 0xAC :
- return "\xEA\xBC\xB9";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x95";
- break;
- case 0xA4 :
- return "\xEA\xBD\xB1";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x8D";
- break;
- case 0x9C :
- return "\xEA\xBE\xA9";
- break;
- case 0xB8 :
- return "\xEA\xBF\x85";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xA1";
- break;
- case 0xB0 :
- return "\xEA\xBF\xBD";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x99";
- break;
- case 0xA8 :
- return "\xEB\x80\xB5";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x91";
- break;
- case 0xA0 :
- return "\xEB\x81\xAD";
- break;
- case 0xBC :
- return "\xEB\x82\x89";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xA5";
- break;
- case 0xB4 :
- return "\xEB\x83\x81";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x9D";
- break;
- case 0xAC :
- return "\xEB\x83\xB9";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x95";
- break;
- case 0xA4 :
- return "\xEB\x84\xB1";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x8D";
- break;
- case 0x9C :
- return "\xEB\x85\xA9";
- break;
- case 0xB8 :
- return "\xEB\x86\x85";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xA1";
- break;
- case 0xB0 :
- return "\xEB\x86\xBD";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x99";
- break;
- case 0xA8 :
- return "\xEB\x87\xB5";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x91";
- break;
- case 0xA0 :
- return "\xEB\x88\xAD";
- break;
- case 0xBC :
- return "\xEB\x89\x89";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xA5";
- break;
- case 0xB4 :
- return "\xEB\x8A\x81";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x9D";
- break;
- case 0xAC :
- return "\xEB\x8A\xB9";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x95";
- break;
- case 0xA4 :
- return "\xEB\x8B\xB1";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x8D";
- break;
- case 0x9C :
- return "\xEB\x8C\xA9";
- break;
- case 0xB8 :
- return "\xEB\x8D\x85";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xA1";
- break;
- case 0xB0 :
- return "\xEB\x8D\xBD";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x99";
- break;
- case 0xA8 :
- return "\xEB\x8E\xB5";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x91";
- break;
- case 0xA0 :
- return "\xEB\x8F\xAD";
- break;
- case 0xBC :
- return "\xEB\x90\x89";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xA5";
- break;
- case 0xB4 :
- return "\xEB\x91\x81";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x9D";
- break;
- case 0xAC :
- return "\xEB\x91\xB9";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x95";
- break;
- case 0xA4 :
- return "\xEB\x92\xB1";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x8D";
- break;
- case 0x9C :
- return "\xEB\x93\xA9";
- break;
- case 0xB8 :
- return "\xEB\x94\x85";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xA1";
- break;
- case 0xB0 :
- return "\xEB\x94\xBD";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x99";
- break;
- case 0xA8 :
- return "\xEB\x95\xB5";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x91";
- break;
- case 0xA0 :
- return "\xEB\x96\xAD";
- break;
- case 0xBC :
- return "\xEB\x97\x89";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xA5";
- break;
- case 0xB4 :
- return "\xEB\x98\x81";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x9D";
- break;
- case 0xAC :
- return "\xEB\x98\xB9";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x95";
- break;
- case 0xA4 :
- return "\xEB\x99\xB1";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x8D";
- break;
- case 0x9C :
- return "\xEB\x9A\xA9";
- break;
- case 0xB8 :
- return "\xEB\x9B\x85";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xA1";
- break;
- case 0xB0 :
- return "\xEB\x9B\xBD";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x99";
- break;
- case 0xA8 :
- return "\xEB\x9C\xB5";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x91";
- break;
- case 0xA0 :
- return "\xEB\x9D\xAD";
- break;
- case 0xBC :
- return "\xEB\x9E\x89";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xA5";
- break;
- case 0xB4 :
- return "\xEB\x9F\x81";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x9D";
- break;
- case 0xAC :
- return "\xEB\x9F\xB9";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x95";
- break;
- case 0xA4 :
- return "\xEB\xA0\xB1";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x8D";
- break;
- case 0x9C :
- return "\xEB\xA1\xA9";
- break;
- case 0xB8 :
- return "\xEB\xA2\x85";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xA1";
- break;
- case 0xB0 :
- return "\xEB\xA2\xBD";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x99";
- break;
- case 0xA8 :
- return "\xEB\xA3\xB5";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x91";
- break;
- case 0xA0 :
- return "\xEB\xA4\xAD";
- break;
- case 0xBC :
- return "\xEB\xA5\x89";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xA5";
- break;
- case 0xB4 :
- return "\xEB\xA6\x81";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x9D";
- break;
- case 0xAC :
- return "\xEB\xA6\xB9";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x95";
- break;
- case 0xA4 :
- return "\xEB\xA7\xB1";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x8D";
- break;
- case 0x9C :
- return "\xEB\xA8\xA9";
- break;
- case 0xB8 :
- return "\xEB\xA9\x85";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xA1";
- break;
- case 0xB0 :
- return "\xEB\xA9\xBD";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x99";
- break;
- case 0xA8 :
- return "\xEB\xAA\xB5";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x91";
- break;
- case 0xA0 :
- return "\xEB\xAB\xAD";
- break;
- case 0xBC :
- return "\xEB\xAC\x89";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xA5";
- break;
- case 0xB4 :
- return "\xEB\xAD\x81";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x9D";
- break;
- case 0xAC :
- return "\xEB\xAD\xB9";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x95";
- break;
- case 0xA4 :
- return "\xEB\xAE\xB1";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x8D";
- break;
- case 0x9C :
- return "\xEB\xAF\xA9";
- break;
- case 0xB8 :
- return "\xEB\xB0\x85";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xA1";
- break;
- case 0xB0 :
- return "\xEB\xB0\xBD";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x99";
- break;
- case 0xA8 :
- return "\xEB\xB1\xB5";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x91";
- break;
- case 0xA0 :
- return "\xEB\xB2\xAD";
- break;
- case 0xBC :
- return "\xEB\xB3\x89";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xA5";
- break;
- case 0xB4 :
- return "\xEB\xB4\x81";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x9D";
- break;
- case 0xAC :
- return "\xEB\xB4\xB9";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x95";
- break;
- case 0xA4 :
- return "\xEB\xB5\xB1";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x8D";
- break;
- case 0x9C :
- return "\xEB\xB6\xA9";
- break;
- case 0xB8 :
- return "\xEB\xB7\x85";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xA1";
- break;
- case 0xB0 :
- return "\xEB\xB7\xBD";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x99";
- break;
- case 0xA8 :
- return "\xEB\xB8\xB5";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x91";
- break;
- case 0xA0 :
- return "\xEB\xB9\xAD";
- break;
- case 0xBC :
- return "\xEB\xBA\x89";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xA5";
- break;
- case 0xB4 :
- return "\xEB\xBB\x81";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x9D";
- break;
- case 0xAC :
- return "\xEB\xBB\xB9";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x95";
- break;
- case 0xA4 :
- return "\xEB\xBC\xB1";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x8D";
- break;
- case 0x9C :
- return "\xEB\xBD\xA9";
- break;
- case 0xB8 :
- return "\xEB\xBE\x85";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xA1";
- break;
- case 0xB0 :
- return "\xEB\xBE\xBD";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x99";
- break;
- case 0xA8 :
- return "\xEB\xBF\xB5";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x91";
- break;
- case 0xA0 :
- return "\xEC\x80\xAD";
- break;
- case 0xBC :
- return "\xEC\x81\x89";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xA5";
- break;
- case 0xB4 :
- return "\xEC\x82\x81";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x9D";
- break;
- case 0xAC :
- return "\xEC\x82\xB9";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x95";
- break;
- case 0xA4 :
- return "\xEC\x83\xB1";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x8D";
- break;
- case 0x9C :
- return "\xEC\x84\xA9";
- break;
- case 0xB8 :
- return "\xEC\x85\x85";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xA1";
- break;
- case 0xB0 :
- return "\xEC\x85\xBD";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x99";
- break;
- case 0xA8 :
- return "\xEC\x86\xB5";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x91";
- break;
- case 0xA0 :
- return "\xEC\x87\xAD";
- break;
- case 0xBC :
- return "\xEC\x88\x89";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xA5";
- break;
- case 0xB4 :
- return "\xEC\x89\x81";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x9D";
- break;
- case 0xAC :
- return "\xEC\x89\xB9";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x95";
- break;
- case 0xA4 :
- return "\xEC\x8A\xB1";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x8D";
- break;
- case 0x9C :
- return "\xEC\x8B\xA9";
- break;
- case 0xB8 :
- return "\xEC\x8C\x85";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xA1";
- break;
- case 0xB0 :
- return "\xEC\x8C\xBD";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x99";
- break;
- case 0xA8 :
- return "\xEC\x8D\xB5";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x91";
- break;
- case 0xA0 :
- return "\xEC\x8E\xAD";
- break;
- case 0xBC :
- return "\xEC\x8F\x89";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xA5";
- break;
- case 0xB4 :
- return "\xEC\x90\x81";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x9D";
- break;
- case 0xAC :
- return "\xEC\x90\xB9";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x95";
- break;
- case 0xA4 :
- return "\xEC\x91\xB1";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x8D";
- break;
- case 0x9C :
- return "\xEC\x92\xA9";
- break;
- case 0xB8 :
- return "\xEC\x93\x85";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xA1";
- break;
- case 0xB0 :
- return "\xEC\x93\xBD";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x99";
- break;
- case 0xA8 :
- return "\xEC\x94\xB5";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x91";
- break;
- case 0xA0 :
- return "\xEC\x95\xAD";
- break;
- case 0xBC :
- return "\xEC\x96\x89";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xA5";
- break;
- case 0xB4 :
- return "\xEC\x97\x81";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x9D";
- break;
- case 0xAC :
- return "\xEC\x97\xB9";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x95";
- break;
- case 0xA4 :
- return "\xEC\x98\xB1";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x8D";
- break;
- case 0x9C :
- return "\xEC\x99\xA9";
- break;
- case 0xB8 :
- return "\xEC\x9A\x85";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xA1";
- break;
- case 0xB0 :
- return "\xEC\x9A\xBD";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x99";
- break;
- case 0xA8 :
- return "\xEC\x9B\xB5";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x91";
- break;
- case 0xA0 :
- return "\xEC\x9C\xAD";
- break;
- case 0xBC :
- return "\xEC\x9D\x89";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xA5";
- break;
- case 0xB4 :
- return "\xEC\x9E\x81";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x9D";
- break;
- case 0xAC :
- return "\xEC\x9E\xB9";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x95";
- break;
- case 0xA4 :
- return "\xEC\x9F\xB1";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x8D";
- break;
- case 0x9C :
- return "\xEC\xA0\xA9";
- break;
- case 0xB8 :
- return "\xEC\xA1\x85";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xA1";
- break;
- case 0xB0 :
- return "\xEC\xA1\xBD";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x99";
- break;
- case 0xA8 :
- return "\xEC\xA2\xB5";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x91";
- break;
- case 0xA0 :
- return "\xEC\xA3\xAD";
- break;
- case 0xBC :
- return "\xEC\xA4\x89";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xA5";
- break;
- case 0xB4 :
- return "\xEC\xA5\x81";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x9D";
- break;
- case 0xAC :
- return "\xEC\xA5\xB9";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x95";
- break;
- case 0xA4 :
- return "\xEC\xA6\xB1";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x8D";
- break;
- case 0x9C :
- return "\xEC\xA7\xA9";
- break;
- case 0xB8 :
- return "\xEC\xA8\x85";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xA1";
- break;
- case 0xB0 :
- return "\xEC\xA8\xBD";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x99";
- break;
- case 0xA8 :
- return "\xEC\xA9\xB5";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x91";
- break;
- case 0xA0 :
- return "\xEC\xAA\xAD";
- break;
- case 0xBC :
- return "\xEC\xAB\x89";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xA5";
- break;
- case 0xB4 :
- return "\xEC\xAC\x81";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x9D";
- break;
- case 0xAC :
- return "\xEC\xAC\xB9";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x95";
- break;
- case 0xA4 :
- return "\xEC\xAD\xB1";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x8D";
- break;
- case 0x9C :
- return "\xEC\xAE\xA9";
- break;
- case 0xB8 :
- return "\xEC\xAF\x85";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xA1";
- break;
- case 0xB0 :
- return "\xEC\xAF\xBD";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x99";
- break;
- case 0xA8 :
- return "\xEC\xB0\xB5";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x91";
- break;
- case 0xA0 :
- return "\xEC\xB1\xAD";
- break;
- case 0xBC :
- return "\xEC\xB2\x89";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xA5";
- break;
- case 0xB4 :
- return "\xEC\xB3\x81";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x9D";
- break;
- case 0xAC :
- return "\xEC\xB3\xB9";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x95";
- break;
- case 0xA4 :
- return "\xEC\xB4\xB1";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x8D";
- break;
- case 0x9C :
- return "\xEC\xB5\xA9";
- break;
- case 0xB8 :
- return "\xEC\xB6\x85";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xA1";
- break;
- case 0xB0 :
- return "\xEC\xB6\xBD";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x99";
- break;
- case 0xA8 :
- return "\xEC\xB7\xB5";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x91";
- break;
- case 0xA0 :
- return "\xEC\xB8\xAD";
- break;
- case 0xBC :
- return "\xEC\xB9\x89";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xA5";
- break;
- case 0xB4 :
- return "\xEC\xBA\x81";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x9D";
- break;
- case 0xAC :
- return "\xEC\xBA\xB9";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x95";
- break;
- case 0xA4 :
- return "\xEC\xBB\xB1";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x8D";
- break;
- case 0x9C :
- return "\xEC\xBC\xA9";
- break;
- case 0xB8 :
- return "\xEC\xBD\x85";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xA1";
- break;
- case 0xB0 :
- return "\xEC\xBD\xBD";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x99";
- break;
- case 0xA8 :
- return "\xEC\xBE\xB5";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x91";
- break;
- case 0xA0 :
- return "\xEC\xBF\xAD";
- break;
- case 0xBC :
- return "\xED\x80\x89";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xA5";
- break;
- case 0xB4 :
- return "\xED\x81\x81";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x9D";
- break;
- case 0xAC :
- return "\xED\x81\xB9";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x95";
- break;
- case 0xA4 :
- return "\xED\x82\xB1";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x8D";
- break;
- case 0x9C :
- return "\xED\x83\xA9";
- break;
- case 0xB8 :
- return "\xED\x84\x85";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xA1";
- break;
- case 0xB0 :
- return "\xED\x84\xBD";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x99";
- break;
- case 0xA8 :
- return "\xED\x85\xB5";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x91";
- break;
- case 0xA0 :
- return "\xED\x86\xAD";
- break;
- case 0xBC :
- return "\xED\x87\x89";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xA5";
- break;
- case 0xB4 :
- return "\xED\x88\x81";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x9D";
- break;
- case 0xAC :
- return "\xED\x88\xB9";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x95";
- break;
- case 0xA4 :
- return "\xED\x89\xB1";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x8D";
- break;
- case 0x9C :
- return "\xED\x8A\xA9";
- break;
- case 0xB8 :
- return "\xED\x8B\x85";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xA1";
- break;
- case 0xB0 :
- return "\xED\x8B\xBD";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x99";
- break;
- case 0xA8 :
- return "\xED\x8C\xB5";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x91";
- break;
- case 0xA0 :
- return "\xED\x8D\xAD";
- break;
- case 0xBC :
- return "\xED\x8E\x89";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xA5";
- break;
- case 0xB4 :
- return "\xED\x8F\x81";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x9D";
- break;
- case 0xAC :
- return "\xED\x8F\xB9";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x95";
- break;
- case 0xA4 :
- return "\xED\x90\xB1";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x8D";
- break;
- case 0x9C :
- return "\xED\x91\xA9";
- break;
- case 0xB8 :
- return "\xED\x92\x85";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xA1";
- break;
- case 0xB0 :
- return "\xED\x92\xBD";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x99";
- break;
- case 0xA8 :
- return "\xED\x93\xB5";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x91";
- break;
- case 0xA0 :
- return "\xED\x94\xAD";
- break;
- case 0xBC :
- return "\xED\x95\x89";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xA5";
- break;
- case 0xB4 :
- return "\xED\x96\x81";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x9D";
- break;
- case 0xAC :
- return "\xED\x96\xB9";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x95";
- break;
- case 0xA4 :
- return "\xED\x97\xB1";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x8D";
- break;
- case 0x9C :
- return "\xED\x98\xA9";
- break;
- case 0xB8 :
- return "\xED\x99\x85";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xA1";
- break;
- case 0xB0 :
- return "\xED\x99\xBD";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x99";
- break;
- case 0xA8 :
- return "\xED\x9A\xB5";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x91";
- break;
- case 0xA0 :
- return "\xED\x9B\xAD";
- break;
- case 0xBC :
- return "\xED\x9C\x89";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xA5";
- break;
- case 0xB4 :
- return "\xED\x9D\x81";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x9D";
- break;
- case 0xAC :
- return "\xED\x9D\xB9";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x95";
- }
- break;
- }
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x8E";
- break;
- case 0x9C :
- return "\xEA\xB0\xAA";
- break;
- case 0xB8 :
- return "\xEA\xB1\x86";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xA2";
- break;
- case 0xB0 :
- return "\xEA\xB1\xBE";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x9A";
- break;
- case 0xA8 :
- return "\xEA\xB2\xB6";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x92";
- break;
- case 0xA0 :
- return "\xEA\xB3\xAE";
- break;
- case 0xBC :
- return "\xEA\xB4\x8A";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xA6";
- break;
- case 0xB4 :
- return "\xEA\xB5\x82";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x9E";
- break;
- case 0xAC :
- return "\xEA\xB5\xBA";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x96";
- break;
- case 0xA4 :
- return "\xEA\xB6\xB2";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x8E";
- break;
- case 0x9C :
- return "\xEA\xB7\xAA";
- break;
- case 0xB8 :
- return "\xEA\xB8\x86";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xA2";
- break;
- case 0xB0 :
- return "\xEA\xB8\xBE";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x9A";
- break;
- case 0xA8 :
- return "\xEA\xB9\xB6";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x92";
- break;
- case 0xA0 :
- return "\xEA\xBA\xAE";
- break;
- case 0xBC :
- return "\xEA\xBB\x8A";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xA6";
- break;
- case 0xB4 :
- return "\xEA\xBC\x82";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x9E";
- break;
- case 0xAC :
- return "\xEA\xBC\xBA";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x96";
- break;
- case 0xA4 :
- return "\xEA\xBD\xB2";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x8E";
- break;
- case 0x9C :
- return "\xEA\xBE\xAA";
- break;
- case 0xB8 :
- return "\xEA\xBF\x86";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xA2";
- break;
- case 0xB0 :
- return "\xEA\xBF\xBE";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x9A";
- break;
- case 0xA8 :
- return "\xEB\x80\xB6";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x92";
- break;
- case 0xA0 :
- return "\xEB\x81\xAE";
- break;
- case 0xBC :
- return "\xEB\x82\x8A";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xA6";
- break;
- case 0xB4 :
- return "\xEB\x83\x82";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x9E";
- break;
- case 0xAC :
- return "\xEB\x83\xBA";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x96";
- break;
- case 0xA4 :
- return "\xEB\x84\xB2";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x8E";
- break;
- case 0x9C :
- return "\xEB\x85\xAA";
- break;
- case 0xB8 :
- return "\xEB\x86\x86";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xA2";
- break;
- case 0xB0 :
- return "\xEB\x86\xBE";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x9A";
- break;
- case 0xA8 :
- return "\xEB\x87\xB6";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x92";
- break;
- case 0xA0 :
- return "\xEB\x88\xAE";
- break;
- case 0xBC :
- return "\xEB\x89\x8A";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xA6";
- break;
- case 0xB4 :
- return "\xEB\x8A\x82";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x9E";
- break;
- case 0xAC :
- return "\xEB\x8A\xBA";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x96";
- break;
- case 0xA4 :
- return "\xEB\x8B\xB2";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x8E";
- break;
- case 0x9C :
- return "\xEB\x8C\xAA";
- break;
- case 0xB8 :
- return "\xEB\x8D\x86";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xA2";
- break;
- case 0xB0 :
- return "\xEB\x8D\xBE";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x9A";
- break;
- case 0xA8 :
- return "\xEB\x8E\xB6";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x92";
- break;
- case 0xA0 :
- return "\xEB\x8F\xAE";
- break;
- case 0xBC :
- return "\xEB\x90\x8A";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xA6";
- break;
- case 0xB4 :
- return "\xEB\x91\x82";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x9E";
- break;
- case 0xAC :
- return "\xEB\x91\xBA";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x96";
- break;
- case 0xA4 :
- return "\xEB\x92\xB2";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x8E";
- break;
- case 0x9C :
- return "\xEB\x93\xAA";
- break;
- case 0xB8 :
- return "\xEB\x94\x86";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xA2";
- break;
- case 0xB0 :
- return "\xEB\x94\xBE";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x9A";
- break;
- case 0xA8 :
- return "\xEB\x95\xB6";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x92";
- break;
- case 0xA0 :
- return "\xEB\x96\xAE";
- break;
- case 0xBC :
- return "\xEB\x97\x8A";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xA6";
- break;
- case 0xB4 :
- return "\xEB\x98\x82";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x9E";
- break;
- case 0xAC :
- return "\xEB\x98\xBA";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x96";
- break;
- case 0xA4 :
- return "\xEB\x99\xB2";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x8E";
- break;
- case 0x9C :
- return "\xEB\x9A\xAA";
- break;
- case 0xB8 :
- return "\xEB\x9B\x86";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xA2";
- break;
- case 0xB0 :
- return "\xEB\x9B\xBE";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x9A";
- break;
- case 0xA8 :
- return "\xEB\x9C\xB6";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x92";
- break;
- case 0xA0 :
- return "\xEB\x9D\xAE";
- break;
- case 0xBC :
- return "\xEB\x9E\x8A";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xA6";
- break;
- case 0xB4 :
- return "\xEB\x9F\x82";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x9E";
- break;
- case 0xAC :
- return "\xEB\x9F\xBA";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x96";
- break;
- case 0xA4 :
- return "\xEB\xA0\xB2";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x8E";
- break;
- case 0x9C :
- return "\xEB\xA1\xAA";
- break;
- case 0xB8 :
- return "\xEB\xA2\x86";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xA2";
- break;
- case 0xB0 :
- return "\xEB\xA2\xBE";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x9A";
- break;
- case 0xA8 :
- return "\xEB\xA3\xB6";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x92";
- break;
- case 0xA0 :
- return "\xEB\xA4\xAE";
- break;
- case 0xBC :
- return "\xEB\xA5\x8A";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xA6";
- break;
- case 0xB4 :
- return "\xEB\xA6\x82";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x9E";
- break;
- case 0xAC :
- return "\xEB\xA6\xBA";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x96";
- break;
- case 0xA4 :
- return "\xEB\xA7\xB2";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x8E";
- break;
- case 0x9C :
- return "\xEB\xA8\xAA";
- break;
- case 0xB8 :
- return "\xEB\xA9\x86";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xA2";
- break;
- case 0xB0 :
- return "\xEB\xA9\xBE";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x9A";
- break;
- case 0xA8 :
- return "\xEB\xAA\xB6";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x92";
- break;
- case 0xA0 :
- return "\xEB\xAB\xAE";
- break;
- case 0xBC :
- return "\xEB\xAC\x8A";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xA6";
- break;
- case 0xB4 :
- return "\xEB\xAD\x82";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x9E";
- break;
- case 0xAC :
- return "\xEB\xAD\xBA";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x96";
- break;
- case 0xA4 :
- return "\xEB\xAE\xB2";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x8E";
- break;
- case 0x9C :
- return "\xEB\xAF\xAA";
- break;
- case 0xB8 :
- return "\xEB\xB0\x86";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xA2";
- break;
- case 0xB0 :
- return "\xEB\xB0\xBE";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x9A";
- break;
- case 0xA8 :
- return "\xEB\xB1\xB6";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x92";
- break;
- case 0xA0 :
- return "\xEB\xB2\xAE";
- break;
- case 0xBC :
- return "\xEB\xB3\x8A";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xA6";
- break;
- case 0xB4 :
- return "\xEB\xB4\x82";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x9E";
- break;
- case 0xAC :
- return "\xEB\xB4\xBA";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x96";
- break;
- case 0xA4 :
- return "\xEB\xB5\xB2";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x8E";
- break;
- case 0x9C :
- return "\xEB\xB6\xAA";
- break;
- case 0xB8 :
- return "\xEB\xB7\x86";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xA2";
- break;
- case 0xB0 :
- return "\xEB\xB7\xBE";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x9A";
- break;
- case 0xA8 :
- return "\xEB\xB8\xB6";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x92";
- break;
- case 0xA0 :
- return "\xEB\xB9\xAE";
- break;
- case 0xBC :
- return "\xEB\xBA\x8A";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xA6";
- break;
- case 0xB4 :
- return "\xEB\xBB\x82";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x9E";
- break;
- case 0xAC :
- return "\xEB\xBB\xBA";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x96";
- break;
- case 0xA4 :
- return "\xEB\xBC\xB2";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x8E";
- break;
- case 0x9C :
- return "\xEB\xBD\xAA";
- break;
- case 0xB8 :
- return "\xEB\xBE\x86";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xA2";
- break;
- case 0xB0 :
- return "\xEB\xBE\xBE";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x9A";
- break;
- case 0xA8 :
- return "\xEB\xBF\xB6";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x92";
- break;
- case 0xA0 :
- return "\xEC\x80\xAE";
- break;
- case 0xBC :
- return "\xEC\x81\x8A";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xA6";
- break;
- case 0xB4 :
- return "\xEC\x82\x82";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x9E";
- break;
- case 0xAC :
- return "\xEC\x82\xBA";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x96";
- break;
- case 0xA4 :
- return "\xEC\x83\xB2";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x8E";
- break;
- case 0x9C :
- return "\xEC\x84\xAA";
- break;
- case 0xB8 :
- return "\xEC\x85\x86";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xA2";
- break;
- case 0xB0 :
- return "\xEC\x85\xBE";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x9A";
- break;
- case 0xA8 :
- return "\xEC\x86\xB6";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x92";
- break;
- case 0xA0 :
- return "\xEC\x87\xAE";
- break;
- case 0xBC :
- return "\xEC\x88\x8A";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xA6";
- break;
- case 0xB4 :
- return "\xEC\x89\x82";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x9E";
- break;
- case 0xAC :
- return "\xEC\x89\xBA";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x96";
- break;
- case 0xA4 :
- return "\xEC\x8A\xB2";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x8E";
- break;
- case 0x9C :
- return "\xEC\x8B\xAA";
- break;
- case 0xB8 :
- return "\xEC\x8C\x86";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xA2";
- break;
- case 0xB0 :
- return "\xEC\x8C\xBE";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x9A";
- break;
- case 0xA8 :
- return "\xEC\x8D\xB6";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x92";
- break;
- case 0xA0 :
- return "\xEC\x8E\xAE";
- break;
- case 0xBC :
- return "\xEC\x8F\x8A";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xA6";
- break;
- case 0xB4 :
- return "\xEC\x90\x82";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x9E";
- break;
- case 0xAC :
- return "\xEC\x90\xBA";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x96";
- break;
- case 0xA4 :
- return "\xEC\x91\xB2";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x8E";
- break;
- case 0x9C :
- return "\xEC\x92\xAA";
- break;
- case 0xB8 :
- return "\xEC\x93\x86";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xA2";
- break;
- case 0xB0 :
- return "\xEC\x93\xBE";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x9A";
- break;
- case 0xA8 :
- return "\xEC\x94\xB6";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x92";
- break;
- case 0xA0 :
- return "\xEC\x95\xAE";
- break;
- case 0xBC :
- return "\xEC\x96\x8A";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xA6";
- break;
- case 0xB4 :
- return "\xEC\x97\x82";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x9E";
- break;
- case 0xAC :
- return "\xEC\x97\xBA";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x96";
- break;
- case 0xA4 :
- return "\xEC\x98\xB2";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x8E";
- break;
- case 0x9C :
- return "\xEC\x99\xAA";
- break;
- case 0xB8 :
- return "\xEC\x9A\x86";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xA2";
- break;
- case 0xB0 :
- return "\xEC\x9A\xBE";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x9A";
- break;
- case 0xA8 :
- return "\xEC\x9B\xB6";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x92";
- break;
- case 0xA0 :
- return "\xEC\x9C\xAE";
- break;
- case 0xBC :
- return "\xEC\x9D\x8A";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xA6";
- break;
- case 0xB4 :
- return "\xEC\x9E\x82";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x9E";
- break;
- case 0xAC :
- return "\xEC\x9E\xBA";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x96";
- break;
- case 0xA4 :
- return "\xEC\x9F\xB2";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x8E";
- break;
- case 0x9C :
- return "\xEC\xA0\xAA";
- break;
- case 0xB8 :
- return "\xEC\xA1\x86";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xA2";
- break;
- case 0xB0 :
- return "\xEC\xA1\xBE";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x9A";
- break;
- case 0xA8 :
- return "\xEC\xA2\xB6";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x92";
- break;
- case 0xA0 :
- return "\xEC\xA3\xAE";
- break;
- case 0xBC :
- return "\xEC\xA4\x8A";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xA6";
- break;
- case 0xB4 :
- return "\xEC\xA5\x82";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x9E";
- break;
- case 0xAC :
- return "\xEC\xA5\xBA";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x96";
- break;
- case 0xA4 :
- return "\xEC\xA6\xB2";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x8E";
- break;
- case 0x9C :
- return "\xEC\xA7\xAA";
- break;
- case 0xB8 :
- return "\xEC\xA8\x86";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xA2";
- break;
- case 0xB0 :
- return "\xEC\xA8\xBE";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x9A";
- break;
- case 0xA8 :
- return "\xEC\xA9\xB6";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x92";
- break;
- case 0xA0 :
- return "\xEC\xAA\xAE";
- break;
- case 0xBC :
- return "\xEC\xAB\x8A";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xA6";
- break;
- case 0xB4 :
- return "\xEC\xAC\x82";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x9E";
- break;
- case 0xAC :
- return "\xEC\xAC\xBA";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x96";
- break;
- case 0xA4 :
- return "\xEC\xAD\xB2";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x8E";
- break;
- case 0x9C :
- return "\xEC\xAE\xAA";
- break;
- case 0xB8 :
- return "\xEC\xAF\x86";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xA2";
- break;
- case 0xB0 :
- return "\xEC\xAF\xBE";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x9A";
- break;
- case 0xA8 :
- return "\xEC\xB0\xB6";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x92";
- break;
- case 0xA0 :
- return "\xEC\xB1\xAE";
- break;
- case 0xBC :
- return "\xEC\xB2\x8A";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xA6";
- break;
- case 0xB4 :
- return "\xEC\xB3\x82";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x9E";
- break;
- case 0xAC :
- return "\xEC\xB3\xBA";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x96";
- break;
- case 0xA4 :
- return "\xEC\xB4\xB2";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x8E";
- break;
- case 0x9C :
- return "\xEC\xB5\xAA";
- break;
- case 0xB8 :
- return "\xEC\xB6\x86";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xA2";
- break;
- case 0xB0 :
- return "\xEC\xB6\xBE";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x9A";
- break;
- case 0xA8 :
- return "\xEC\xB7\xB6";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x92";
- break;
- case 0xA0 :
- return "\xEC\xB8\xAE";
- break;
- case 0xBC :
- return "\xEC\xB9\x8A";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xA6";
- break;
- case 0xB4 :
- return "\xEC\xBA\x82";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x9E";
- break;
- case 0xAC :
- return "\xEC\xBA\xBA";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x96";
- break;
- case 0xA4 :
- return "\xEC\xBB\xB2";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x8E";
- break;
- case 0x9C :
- return "\xEC\xBC\xAA";
- break;
- case 0xB8 :
- return "\xEC\xBD\x86";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xA2";
- break;
- case 0xB0 :
- return "\xEC\xBD\xBE";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x9A";
- break;
- case 0xA8 :
- return "\xEC\xBE\xB6";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x92";
- break;
- case 0xA0 :
- return "\xEC\xBF\xAE";
- break;
- case 0xBC :
- return "\xED\x80\x8A";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xA6";
- break;
- case 0xB4 :
- return "\xED\x81\x82";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x9E";
- break;
- case 0xAC :
- return "\xED\x81\xBA";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x96";
- break;
- case 0xA4 :
- return "\xED\x82\xB2";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x8E";
- break;
- case 0x9C :
- return "\xED\x83\xAA";
- break;
- case 0xB8 :
- return "\xED\x84\x86";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xA2";
- break;
- case 0xB0 :
- return "\xED\x84\xBE";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x9A";
- break;
- case 0xA8 :
- return "\xED\x85\xB6";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x92";
- break;
- case 0xA0 :
- return "\xED\x86\xAE";
- break;
- case 0xBC :
- return "\xED\x87\x8A";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xA6";
- break;
- case 0xB4 :
- return "\xED\x88\x82";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x9E";
- break;
- case 0xAC :
- return "\xED\x88\xBA";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x96";
- break;
- case 0xA4 :
- return "\xED\x89\xB2";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x8E";
- break;
- case 0x9C :
- return "\xED\x8A\xAA";
- break;
- case 0xB8 :
- return "\xED\x8B\x86";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xA2";
- break;
- case 0xB0 :
- return "\xED\x8B\xBE";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x9A";
- break;
- case 0xA8 :
- return "\xED\x8C\xB6";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x92";
- break;
- case 0xA0 :
- return "\xED\x8D\xAE";
- break;
- case 0xBC :
- return "\xED\x8E\x8A";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xA6";
- break;
- case 0xB4 :
- return "\xED\x8F\x82";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x9E";
- break;
- case 0xAC :
- return "\xED\x8F\xBA";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x96";
- break;
- case 0xA4 :
- return "\xED\x90\xB2";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x8E";
- break;
- case 0x9C :
- return "\xED\x91\xAA";
- break;
- case 0xB8 :
- return "\xED\x92\x86";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xA2";
- break;
- case 0xB0 :
- return "\xED\x92\xBE";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x9A";
- break;
- case 0xA8 :
- return "\xED\x93\xB6";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x92";
- break;
- case 0xA0 :
- return "\xED\x94\xAE";
- break;
- case 0xBC :
- return "\xED\x95\x8A";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xA6";
- break;
- case 0xB4 :
- return "\xED\x96\x82";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x9E";
- break;
- case 0xAC :
- return "\xED\x96\xBA";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x96";
- break;
- case 0xA4 :
- return "\xED\x97\xB2";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x8E";
- break;
- case 0x9C :
- return "\xED\x98\xAA";
- break;
- case 0xB8 :
- return "\xED\x99\x86";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xA2";
- break;
- case 0xB0 :
- return "\xED\x99\xBE";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x9A";
- break;
- case 0xA8 :
- return "\xED\x9A\xB6";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x92";
- break;
- case 0xA0 :
- return "\xED\x9B\xAE";
- break;
- case 0xBC :
- return "\xED\x9C\x8A";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xA6";
- break;
- case 0xB4 :
- return "\xED\x9D\x82";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x9E";
- break;
- case 0xAC :
- return "\xED\x9D\xBA";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x96";
- }
- break;
- }
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x8F";
- break;
- case 0x9C :
- return "\xEA\xB0\xAB";
- break;
- case 0xB8 :
- return "\xEA\xB1\x87";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xA3";
- break;
- case 0xB0 :
- return "\xEA\xB1\xBF";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x9B";
- break;
- case 0xA8 :
- return "\xEA\xB2\xB7";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x93";
- break;
- case 0xA0 :
- return "\xEA\xB3\xAF";
- break;
- case 0xBC :
- return "\xEA\xB4\x8B";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xA7";
- break;
- case 0xB4 :
- return "\xEA\xB5\x83";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\x9F";
- break;
- case 0xAC :
- return "\xEA\xB5\xBB";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x97";
- break;
- case 0xA4 :
- return "\xEA\xB6\xB3";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x8F";
- break;
- case 0x9C :
- return "\xEA\xB7\xAB";
- break;
- case 0xB8 :
- return "\xEA\xB8\x87";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xA3";
- break;
- case 0xB0 :
- return "\xEA\xB8\xBF";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x9B";
- break;
- case 0xA8 :
- return "\xEA\xB9\xB7";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x93";
- break;
- case 0xA0 :
- return "\xEA\xBA\xAF";
- break;
- case 0xBC :
- return "\xEA\xBB\x8B";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xA7";
- break;
- case 0xB4 :
- return "\xEA\xBC\x83";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\x9F";
- break;
- case 0xAC :
- return "\xEA\xBC\xBB";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x97";
- break;
- case 0xA4 :
- return "\xEA\xBD\xB3";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x8F";
- break;
- case 0x9C :
- return "\xEA\xBE\xAB";
- break;
- case 0xB8 :
- return "\xEA\xBF\x87";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xA3";
- break;
- case 0xB0 :
- return "\xEA\xBF\xBF";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x9B";
- break;
- case 0xA8 :
- return "\xEB\x80\xB7";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x93";
- break;
- case 0xA0 :
- return "\xEB\x81\xAF";
- break;
- case 0xBC :
- return "\xEB\x82\x8B";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xA7";
- break;
- case 0xB4 :
- return "\xEB\x83\x83";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\x9F";
- break;
- case 0xAC :
- return "\xEB\x83\xBB";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x97";
- break;
- case 0xA4 :
- return "\xEB\x84\xB3";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x8F";
- break;
- case 0x9C :
- return "\xEB\x85\xAB";
- break;
- case 0xB8 :
- return "\xEB\x86\x87";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xA3";
- break;
- case 0xB0 :
- return "\xEB\x86\xBF";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x9B";
- break;
- case 0xA8 :
- return "\xEB\x87\xB7";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x93";
- break;
- case 0xA0 :
- return "\xEB\x88\xAF";
- break;
- case 0xBC :
- return "\xEB\x89\x8B";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xA7";
- break;
- case 0xB4 :
- return "\xEB\x8A\x83";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\x9F";
- break;
- case 0xAC :
- return "\xEB\x8A\xBB";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x97";
- break;
- case 0xA4 :
- return "\xEB\x8B\xB3";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x8F";
- break;
- case 0x9C :
- return "\xEB\x8C\xAB";
- break;
- case 0xB8 :
- return "\xEB\x8D\x87";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xA3";
- break;
- case 0xB0 :
- return "\xEB\x8D\xBF";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x9B";
- break;
- case 0xA8 :
- return "\xEB\x8E\xB7";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x93";
- break;
- case 0xA0 :
- return "\xEB\x8F\xAF";
- break;
- case 0xBC :
- return "\xEB\x90\x8B";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xA7";
- break;
- case 0xB4 :
- return "\xEB\x91\x83";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\x9F";
- break;
- case 0xAC :
- return "\xEB\x91\xBB";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x97";
- break;
- case 0xA4 :
- return "\xEB\x92\xB3";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x8F";
- break;
- case 0x9C :
- return "\xEB\x93\xAB";
- break;
- case 0xB8 :
- return "\xEB\x94\x87";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xA3";
- break;
- case 0xB0 :
- return "\xEB\x94\xBF";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x9B";
- break;
- case 0xA8 :
- return "\xEB\x95\xB7";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x93";
- break;
- case 0xA0 :
- return "\xEB\x96\xAF";
- break;
- case 0xBC :
- return "\xEB\x97\x8B";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xA7";
- break;
- case 0xB4 :
- return "\xEB\x98\x83";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\x9F";
- break;
- case 0xAC :
- return "\xEB\x98\xBB";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x97";
- break;
- case 0xA4 :
- return "\xEB\x99\xB3";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x8F";
- break;
- case 0x9C :
- return "\xEB\x9A\xAB";
- break;
- case 0xB8 :
- return "\xEB\x9B\x87";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xA3";
- break;
- case 0xB0 :
- return "\xEB\x9B\xBF";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x9B";
- break;
- case 0xA8 :
- return "\xEB\x9C\xB7";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x93";
- break;
- case 0xA0 :
- return "\xEB\x9D\xAF";
- break;
- case 0xBC :
- return "\xEB\x9E\x8B";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xA7";
- break;
- case 0xB4 :
- return "\xEB\x9F\x83";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\x9F";
- break;
- case 0xAC :
- return "\xEB\x9F\xBB";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x97";
- break;
- case 0xA4 :
- return "\xEB\xA0\xB3";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x8F";
- break;
- case 0x9C :
- return "\xEB\xA1\xAB";
- break;
- case 0xB8 :
- return "\xEB\xA2\x87";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xA3";
- break;
- case 0xB0 :
- return "\xEB\xA2\xBF";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x9B";
- break;
- case 0xA8 :
- return "\xEB\xA3\xB7";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x93";
- break;
- case 0xA0 :
- return "\xEB\xA4\xAF";
- break;
- case 0xBC :
- return "\xEB\xA5\x8B";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xA7";
- break;
- case 0xB4 :
- return "\xEB\xA6\x83";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\x9F";
- break;
- case 0xAC :
- return "\xEB\xA6\xBB";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x97";
- break;
- case 0xA4 :
- return "\xEB\xA7\xB3";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x8F";
- break;
- case 0x9C :
- return "\xEB\xA8\xAB";
- break;
- case 0xB8 :
- return "\xEB\xA9\x87";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xA3";
- break;
- case 0xB0 :
- return "\xEB\xA9\xBF";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x9B";
- break;
- case 0xA8 :
- return "\xEB\xAA\xB7";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x93";
- break;
- case 0xA0 :
- return "\xEB\xAB\xAF";
- break;
- case 0xBC :
- return "\xEB\xAC\x8B";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xA7";
- break;
- case 0xB4 :
- return "\xEB\xAD\x83";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\x9F";
- break;
- case 0xAC :
- return "\xEB\xAD\xBB";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x97";
- break;
- case 0xA4 :
- return "\xEB\xAE\xB3";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x8F";
- break;
- case 0x9C :
- return "\xEB\xAF\xAB";
- break;
- case 0xB8 :
- return "\xEB\xB0\x87";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xA3";
- break;
- case 0xB0 :
- return "\xEB\xB0\xBF";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x9B";
- break;
- case 0xA8 :
- return "\xEB\xB1\xB7";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x93";
- break;
- case 0xA0 :
- return "\xEB\xB2\xAF";
- break;
- case 0xBC :
- return "\xEB\xB3\x8B";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xA7";
- break;
- case 0xB4 :
- return "\xEB\xB4\x83";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\x9F";
- break;
- case 0xAC :
- return "\xEB\xB4\xBB";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x97";
- break;
- case 0xA4 :
- return "\xEB\xB5\xB3";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x8F";
- break;
- case 0x9C :
- return "\xEB\xB6\xAB";
- break;
- case 0xB8 :
- return "\xEB\xB7\x87";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xA3";
- break;
- case 0xB0 :
- return "\xEB\xB7\xBF";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x9B";
- break;
- case 0xA8 :
- return "\xEB\xB8\xB7";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x93";
- break;
- case 0xA0 :
- return "\xEB\xB9\xAF";
- break;
- case 0xBC :
- return "\xEB\xBA\x8B";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xA7";
- break;
- case 0xB4 :
- return "\xEB\xBB\x83";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\x9F";
- break;
- case 0xAC :
- return "\xEB\xBB\xBB";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x97";
- break;
- case 0xA4 :
- return "\xEB\xBC\xB3";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x8F";
- break;
- case 0x9C :
- return "\xEB\xBD\xAB";
- break;
- case 0xB8 :
- return "\xEB\xBE\x87";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xA3";
- break;
- case 0xB0 :
- return "\xEB\xBE\xBF";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x9B";
- break;
- case 0xA8 :
- return "\xEB\xBF\xB7";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x93";
- break;
- case 0xA0 :
- return "\xEC\x80\xAF";
- break;
- case 0xBC :
- return "\xEC\x81\x8B";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xA7";
- break;
- case 0xB4 :
- return "\xEC\x82\x83";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\x9F";
- break;
- case 0xAC :
- return "\xEC\x82\xBB";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x97";
- break;
- case 0xA4 :
- return "\xEC\x83\xB3";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x8F";
- break;
- case 0x9C :
- return "\xEC\x84\xAB";
- break;
- case 0xB8 :
- return "\xEC\x85\x87";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xA3";
- break;
- case 0xB0 :
- return "\xEC\x85\xBF";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x9B";
- break;
- case 0xA8 :
- return "\xEC\x86\xB7";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x93";
- break;
- case 0xA0 :
- return "\xEC\x87\xAF";
- break;
- case 0xBC :
- return "\xEC\x88\x8B";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xA7";
- break;
- case 0xB4 :
- return "\xEC\x89\x83";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\x9F";
- break;
- case 0xAC :
- return "\xEC\x89\xBB";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x97";
- break;
- case 0xA4 :
- return "\xEC\x8A\xB3";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x8F";
- break;
- case 0x9C :
- return "\xEC\x8B\xAB";
- break;
- case 0xB8 :
- return "\xEC\x8C\x87";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xA3";
- break;
- case 0xB0 :
- return "\xEC\x8C\xBF";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x9B";
- break;
- case 0xA8 :
- return "\xEC\x8D\xB7";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x93";
- break;
- case 0xA0 :
- return "\xEC\x8E\xAF";
- break;
- case 0xBC :
- return "\xEC\x8F\x8B";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xA7";
- break;
- case 0xB4 :
- return "\xEC\x90\x83";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\x9F";
- break;
- case 0xAC :
- return "\xEC\x90\xBB";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x97";
- break;
- case 0xA4 :
- return "\xEC\x91\xB3";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x8F";
- break;
- case 0x9C :
- return "\xEC\x92\xAB";
- break;
- case 0xB8 :
- return "\xEC\x93\x87";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xA3";
- break;
- case 0xB0 :
- return "\xEC\x93\xBF";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x9B";
- break;
- case 0xA8 :
- return "\xEC\x94\xB7";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x93";
- break;
- case 0xA0 :
- return "\xEC\x95\xAF";
- break;
- case 0xBC :
- return "\xEC\x96\x8B";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xA7";
- break;
- case 0xB4 :
- return "\xEC\x97\x83";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\x9F";
- break;
- case 0xAC :
- return "\xEC\x97\xBB";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x97";
- break;
- case 0xA4 :
- return "\xEC\x98\xB3";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x8F";
- break;
- case 0x9C :
- return "\xEC\x99\xAB";
- break;
- case 0xB8 :
- return "\xEC\x9A\x87";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xA3";
- break;
- case 0xB0 :
- return "\xEC\x9A\xBF";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x9B";
- break;
- case 0xA8 :
- return "\xEC\x9B\xB7";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x93";
- break;
- case 0xA0 :
- return "\xEC\x9C\xAF";
- break;
- case 0xBC :
- return "\xEC\x9D\x8B";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xA7";
- break;
- case 0xB4 :
- return "\xEC\x9E\x83";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\x9F";
- break;
- case 0xAC :
- return "\xEC\x9E\xBB";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x97";
- break;
- case 0xA4 :
- return "\xEC\x9F\xB3";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x8F";
- break;
- case 0x9C :
- return "\xEC\xA0\xAB";
- break;
- case 0xB8 :
- return "\xEC\xA1\x87";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xA3";
- break;
- case 0xB0 :
- return "\xEC\xA1\xBF";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x9B";
- break;
- case 0xA8 :
- return "\xEC\xA2\xB7";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x93";
- break;
- case 0xA0 :
- return "\xEC\xA3\xAF";
- break;
- case 0xBC :
- return "\xEC\xA4\x8B";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xA7";
- break;
- case 0xB4 :
- return "\xEC\xA5\x83";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\x9F";
- break;
- case 0xAC :
- return "\xEC\xA5\xBB";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x97";
- break;
- case 0xA4 :
- return "\xEC\xA6\xB3";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x8F";
- break;
- case 0x9C :
- return "\xEC\xA7\xAB";
- break;
- case 0xB8 :
- return "\xEC\xA8\x87";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xA3";
- break;
- case 0xB0 :
- return "\xEC\xA8\xBF";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x9B";
- break;
- case 0xA8 :
- return "\xEC\xA9\xB7";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x93";
- break;
- case 0xA0 :
- return "\xEC\xAA\xAF";
- break;
- case 0xBC :
- return "\xEC\xAB\x8B";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xA7";
- break;
- case 0xB4 :
- return "\xEC\xAC\x83";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\x9F";
- break;
- case 0xAC :
- return "\xEC\xAC\xBB";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x97";
- break;
- case 0xA4 :
- return "\xEC\xAD\xB3";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x8F";
- break;
- case 0x9C :
- return "\xEC\xAE\xAB";
- break;
- case 0xB8 :
- return "\xEC\xAF\x87";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xA3";
- break;
- case 0xB0 :
- return "\xEC\xAF\xBF";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x9B";
- break;
- case 0xA8 :
- return "\xEC\xB0\xB7";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x93";
- break;
- case 0xA0 :
- return "\xEC\xB1\xAF";
- break;
- case 0xBC :
- return "\xEC\xB2\x8B";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xA7";
- break;
- case 0xB4 :
- return "\xEC\xB3\x83";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\x9F";
- break;
- case 0xAC :
- return "\xEC\xB3\xBB";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x97";
- break;
- case 0xA4 :
- return "\xEC\xB4\xB3";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x8F";
- break;
- case 0x9C :
- return "\xEC\xB5\xAB";
- break;
- case 0xB8 :
- return "\xEC\xB6\x87";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xA3";
- break;
- case 0xB0 :
- return "\xEC\xB6\xBF";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x9B";
- break;
- case 0xA8 :
- return "\xEC\xB7\xB7";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x93";
- break;
- case 0xA0 :
- return "\xEC\xB8\xAF";
- break;
- case 0xBC :
- return "\xEC\xB9\x8B";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xA7";
- break;
- case 0xB4 :
- return "\xEC\xBA\x83";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\x9F";
- break;
- case 0xAC :
- return "\xEC\xBA\xBB";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x97";
- break;
- case 0xA4 :
- return "\xEC\xBB\xB3";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x8F";
- break;
- case 0x9C :
- return "\xEC\xBC\xAB";
- break;
- case 0xB8 :
- return "\xEC\xBD\x87";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xA3";
- break;
- case 0xB0 :
- return "\xEC\xBD\xBF";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x9B";
- break;
- case 0xA8 :
- return "\xEC\xBE\xB7";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x93";
- break;
- case 0xA0 :
- return "\xEC\xBF\xAF";
- break;
- case 0xBC :
- return "\xED\x80\x8B";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xA7";
- break;
- case 0xB4 :
- return "\xED\x81\x83";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\x9F";
- break;
- case 0xAC :
- return "\xED\x81\xBB";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x97";
- break;
- case 0xA4 :
- return "\xED\x82\xB3";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x8F";
- break;
- case 0x9C :
- return "\xED\x83\xAB";
- break;
- case 0xB8 :
- return "\xED\x84\x87";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xA3";
- break;
- case 0xB0 :
- return "\xED\x84\xBF";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x9B";
- break;
- case 0xA8 :
- return "\xED\x85\xB7";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x93";
- break;
- case 0xA0 :
- return "\xED\x86\xAF";
- break;
- case 0xBC :
- return "\xED\x87\x8B";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xA7";
- break;
- case 0xB4 :
- return "\xED\x88\x83";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\x9F";
- break;
- case 0xAC :
- return "\xED\x88\xBB";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x97";
- break;
- case 0xA4 :
- return "\xED\x89\xB3";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x8F";
- break;
- case 0x9C :
- return "\xED\x8A\xAB";
- break;
- case 0xB8 :
- return "\xED\x8B\x87";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xA3";
- break;
- case 0xB0 :
- return "\xED\x8B\xBF";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x9B";
- break;
- case 0xA8 :
- return "\xED\x8C\xB7";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x93";
- break;
- case 0xA0 :
- return "\xED\x8D\xAF";
- break;
- case 0xBC :
- return "\xED\x8E\x8B";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xA7";
- break;
- case 0xB4 :
- return "\xED\x8F\x83";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\x9F";
- break;
- case 0xAC :
- return "\xED\x8F\xBB";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x97";
- break;
- case 0xA4 :
- return "\xED\x90\xB3";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x8F";
- break;
- case 0x9C :
- return "\xED\x91\xAB";
- break;
- case 0xB8 :
- return "\xED\x92\x87";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xA3";
- break;
- case 0xB0 :
- return "\xED\x92\xBF";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x9B";
- break;
- case 0xA8 :
- return "\xED\x93\xB7";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x93";
- break;
- case 0xA0 :
- return "\xED\x94\xAF";
- break;
- case 0xBC :
- return "\xED\x95\x8B";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xA7";
- break;
- case 0xB4 :
- return "\xED\x96\x83";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\x9F";
- break;
- case 0xAC :
- return "\xED\x96\xBB";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x97";
- break;
- case 0xA4 :
- return "\xED\x97\xB3";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x8F";
- break;
- case 0x9C :
- return "\xED\x98\xAB";
- break;
- case 0xB8 :
- return "\xED\x99\x87";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xA3";
- break;
- case 0xB0 :
- return "\xED\x99\xBF";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x9B";
- break;
- case 0xA8 :
- return "\xED\x9A\xB7";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x93";
- break;
- case 0xA0 :
- return "\xED\x9B\xAF";
- break;
- case 0xBC :
- return "\xED\x9C\x8B";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xA7";
- break;
- case 0xB4 :
- return "\xED\x9D\x83";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\x9F";
- break;
- case 0xAC :
- return "\xED\x9D\xBB";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x97";
- }
- break;
- }
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x90";
- break;
- case 0x9C :
- return "\xEA\xB0\xAC";
- break;
- case 0xB8 :
- return "\xEA\xB1\x88";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xA4";
- break;
- case 0xB0 :
- return "\xEA\xB2\x80";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x9C";
- break;
- case 0xA8 :
- return "\xEA\xB2\xB8";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x94";
- break;
- case 0xA0 :
- return "\xEA\xB3\xB0";
- break;
- case 0xBC :
- return "\xEA\xB4\x8C";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xA8";
- break;
- case 0xB4 :
- return "\xEA\xB5\x84";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xA0";
- break;
- case 0xAC :
- return "\xEA\xB5\xBC";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x98";
- break;
- case 0xA4 :
- return "\xEA\xB6\xB4";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x90";
- break;
- case 0x9C :
- return "\xEA\xB7\xAC";
- break;
- case 0xB8 :
- return "\xEA\xB8\x88";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xA4";
- break;
- case 0xB0 :
- return "\xEA\xB9\x80";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x9C";
- break;
- case 0xA8 :
- return "\xEA\xB9\xB8";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x94";
- break;
- case 0xA0 :
- return "\xEA\xBA\xB0";
- break;
- case 0xBC :
- return "\xEA\xBB\x8C";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xA8";
- break;
- case 0xB4 :
- return "\xEA\xBC\x84";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xA0";
- break;
- case 0xAC :
- return "\xEA\xBC\xBC";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x98";
- break;
- case 0xA4 :
- return "\xEA\xBD\xB4";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x90";
- break;
- case 0x9C :
- return "\xEA\xBE\xAC";
- break;
- case 0xB8 :
- return "\xEA\xBF\x88";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xA4";
- break;
- case 0xB0 :
- return "\xEB\x80\x80";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x9C";
- break;
- case 0xA8 :
- return "\xEB\x80\xB8";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x94";
- break;
- case 0xA0 :
- return "\xEB\x81\xB0";
- break;
- case 0xBC :
- return "\xEB\x82\x8C";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xA8";
- break;
- case 0xB4 :
- return "\xEB\x83\x84";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xA0";
- break;
- case 0xAC :
- return "\xEB\x83\xBC";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x98";
- break;
- case 0xA4 :
- return "\xEB\x84\xB4";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x90";
- break;
- case 0x9C :
- return "\xEB\x85\xAC";
- break;
- case 0xB8 :
- return "\xEB\x86\x88";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xA4";
- break;
- case 0xB0 :
- return "\xEB\x87\x80";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x9C";
- break;
- case 0xA8 :
- return "\xEB\x87\xB8";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x94";
- break;
- case 0xA0 :
- return "\xEB\x88\xB0";
- break;
- case 0xBC :
- return "\xEB\x89\x8C";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xA8";
- break;
- case 0xB4 :
- return "\xEB\x8A\x84";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xA0";
- break;
- case 0xAC :
- return "\xEB\x8A\xBC";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x98";
- break;
- case 0xA4 :
- return "\xEB\x8B\xB4";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x90";
- break;
- case 0x9C :
- return "\xEB\x8C\xAC";
- break;
- case 0xB8 :
- return "\xEB\x8D\x88";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xA4";
- break;
- case 0xB0 :
- return "\xEB\x8E\x80";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x9C";
- break;
- case 0xA8 :
- return "\xEB\x8E\xB8";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x94";
- break;
- case 0xA0 :
- return "\xEB\x8F\xB0";
- break;
- case 0xBC :
- return "\xEB\x90\x8C";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xA8";
- break;
- case 0xB4 :
- return "\xEB\x91\x84";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xA0";
- break;
- case 0xAC :
- return "\xEB\x91\xBC";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x98";
- break;
- case 0xA4 :
- return "\xEB\x92\xB4";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x90";
- break;
- case 0x9C :
- return "\xEB\x93\xAC";
- break;
- case 0xB8 :
- return "\xEB\x94\x88";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xA4";
- break;
- case 0xB0 :
- return "\xEB\x95\x80";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x9C";
- break;
- case 0xA8 :
- return "\xEB\x95\xB8";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x94";
- break;
- case 0xA0 :
- return "\xEB\x96\xB0";
- break;
- case 0xBC :
- return "\xEB\x97\x8C";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xA8";
- break;
- case 0xB4 :
- return "\xEB\x98\x84";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xA0";
- break;
- case 0xAC :
- return "\xEB\x98\xBC";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x98";
- break;
- case 0xA4 :
- return "\xEB\x99\xB4";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x90";
- break;
- case 0x9C :
- return "\xEB\x9A\xAC";
- break;
- case 0xB8 :
- return "\xEB\x9B\x88";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xA4";
- break;
- case 0xB0 :
- return "\xEB\x9C\x80";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x9C";
- break;
- case 0xA8 :
- return "\xEB\x9C\xB8";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x94";
- break;
- case 0xA0 :
- return "\xEB\x9D\xB0";
- break;
- case 0xBC :
- return "\xEB\x9E\x8C";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xA8";
- break;
- case 0xB4 :
- return "\xEB\x9F\x84";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xA0";
- break;
- case 0xAC :
- return "\xEB\x9F\xBC";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x98";
- break;
- case 0xA4 :
- return "\xEB\xA0\xB4";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x90";
- break;
- case 0x9C :
- return "\xEB\xA1\xAC";
- break;
- case 0xB8 :
- return "\xEB\xA2\x88";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xA4";
- break;
- case 0xB0 :
- return "\xEB\xA3\x80";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x9C";
- break;
- case 0xA8 :
- return "\xEB\xA3\xB8";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x94";
- break;
- case 0xA0 :
- return "\xEB\xA4\xB0";
- break;
- case 0xBC :
- return "\xEB\xA5\x8C";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xA8";
- break;
- case 0xB4 :
- return "\xEB\xA6\x84";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xA0";
- break;
- case 0xAC :
- return "\xEB\xA6\xBC";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x98";
- break;
- case 0xA4 :
- return "\xEB\xA7\xB4";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x90";
- break;
- case 0x9C :
- return "\xEB\xA8\xAC";
- break;
- case 0xB8 :
- return "\xEB\xA9\x88";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xA4";
- break;
- case 0xB0 :
- return "\xEB\xAA\x80";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x9C";
- break;
- case 0xA8 :
- return "\xEB\xAA\xB8";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x94";
- break;
- case 0xA0 :
- return "\xEB\xAB\xB0";
- break;
- case 0xBC :
- return "\xEB\xAC\x8C";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xA8";
- break;
- case 0xB4 :
- return "\xEB\xAD\x84";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xA0";
- break;
- case 0xAC :
- return "\xEB\xAD\xBC";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x98";
- break;
- case 0xA4 :
- return "\xEB\xAE\xB4";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x90";
- break;
- case 0x9C :
- return "\xEB\xAF\xAC";
- break;
- case 0xB8 :
- return "\xEB\xB0\x88";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xA4";
- break;
- case 0xB0 :
- return "\xEB\xB1\x80";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x9C";
- break;
- case 0xA8 :
- return "\xEB\xB1\xB8";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x94";
- break;
- case 0xA0 :
- return "\xEB\xB2\xB0";
- break;
- case 0xBC :
- return "\xEB\xB3\x8C";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xA8";
- break;
- case 0xB4 :
- return "\xEB\xB4\x84";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xA0";
- break;
- case 0xAC :
- return "\xEB\xB4\xBC";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x98";
- break;
- case 0xA4 :
- return "\xEB\xB5\xB4";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x90";
- break;
- case 0x9C :
- return "\xEB\xB6\xAC";
- break;
- case 0xB8 :
- return "\xEB\xB7\x88";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xA4";
- break;
- case 0xB0 :
- return "\xEB\xB8\x80";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x9C";
- break;
- case 0xA8 :
- return "\xEB\xB8\xB8";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x94";
- break;
- case 0xA0 :
- return "\xEB\xB9\xB0";
- break;
- case 0xBC :
- return "\xEB\xBA\x8C";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xA8";
- break;
- case 0xB4 :
- return "\xEB\xBB\x84";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xA0";
- break;
- case 0xAC :
- return "\xEB\xBB\xBC";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x98";
- break;
- case 0xA4 :
- return "\xEB\xBC\xB4";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x90";
- break;
- case 0x9C :
- return "\xEB\xBD\xAC";
- break;
- case 0xB8 :
- return "\xEB\xBE\x88";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xA4";
- break;
- case 0xB0 :
- return "\xEB\xBF\x80";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x9C";
- break;
- case 0xA8 :
- return "\xEB\xBF\xB8";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x94";
- break;
- case 0xA0 :
- return "\xEC\x80\xB0";
- break;
- case 0xBC :
- return "\xEC\x81\x8C";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xA8";
- break;
- case 0xB4 :
- return "\xEC\x82\x84";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xA0";
- break;
- case 0xAC :
- return "\xEC\x82\xBC";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x98";
- break;
- case 0xA4 :
- return "\xEC\x83\xB4";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x90";
- break;
- case 0x9C :
- return "\xEC\x84\xAC";
- break;
- case 0xB8 :
- return "\xEC\x85\x88";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xA4";
- break;
- case 0xB0 :
- return "\xEC\x86\x80";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x9C";
- break;
- case 0xA8 :
- return "\xEC\x86\xB8";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x94";
- break;
- case 0xA0 :
- return "\xEC\x87\xB0";
- break;
- case 0xBC :
- return "\xEC\x88\x8C";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xA8";
- break;
- case 0xB4 :
- return "\xEC\x89\x84";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xA0";
- break;
- case 0xAC :
- return "\xEC\x89\xBC";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x98";
- break;
- case 0xA4 :
- return "\xEC\x8A\xB4";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x90";
- break;
- case 0x9C :
- return "\xEC\x8B\xAC";
- break;
- case 0xB8 :
- return "\xEC\x8C\x88";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xA4";
- break;
- case 0xB0 :
- return "\xEC\x8D\x80";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x9C";
- break;
- case 0xA8 :
- return "\xEC\x8D\xB8";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x94";
- break;
- case 0xA0 :
- return "\xEC\x8E\xB0";
- break;
- case 0xBC :
- return "\xEC\x8F\x8C";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xA8";
- break;
- case 0xB4 :
- return "\xEC\x90\x84";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xA0";
- break;
- case 0xAC :
- return "\xEC\x90\xBC";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x98";
- break;
- case 0xA4 :
- return "\xEC\x91\xB4";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x90";
- break;
- case 0x9C :
- return "\xEC\x92\xAC";
- break;
- case 0xB8 :
- return "\xEC\x93\x88";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xA4";
- break;
- case 0xB0 :
- return "\xEC\x94\x80";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x9C";
- break;
- case 0xA8 :
- return "\xEC\x94\xB8";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x94";
- break;
- case 0xA0 :
- return "\xEC\x95\xB0";
- break;
- case 0xBC :
- return "\xEC\x96\x8C";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xA8";
- break;
- case 0xB4 :
- return "\xEC\x97\x84";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xA0";
- break;
- case 0xAC :
- return "\xEC\x97\xBC";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x98";
- break;
- case 0xA4 :
- return "\xEC\x98\xB4";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x90";
- break;
- case 0x9C :
- return "\xEC\x99\xAC";
- break;
- case 0xB8 :
- return "\xEC\x9A\x88";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xA4";
- break;
- case 0xB0 :
- return "\xEC\x9B\x80";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x9C";
- break;
- case 0xA8 :
- return "\xEC\x9B\xB8";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x94";
- break;
- case 0xA0 :
- return "\xEC\x9C\xB0";
- break;
- case 0xBC :
- return "\xEC\x9D\x8C";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xA8";
- break;
- case 0xB4 :
- return "\xEC\x9E\x84";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xA0";
- break;
- case 0xAC :
- return "\xEC\x9E\xBC";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x98";
- break;
- case 0xA4 :
- return "\xEC\x9F\xB4";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x90";
- break;
- case 0x9C :
- return "\xEC\xA0\xAC";
- break;
- case 0xB8 :
- return "\xEC\xA1\x88";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xA4";
- break;
- case 0xB0 :
- return "\xEC\xA2\x80";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x9C";
- break;
- case 0xA8 :
- return "\xEC\xA2\xB8";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x94";
- break;
- case 0xA0 :
- return "\xEC\xA3\xB0";
- break;
- case 0xBC :
- return "\xEC\xA4\x8C";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xA8";
- break;
- case 0xB4 :
- return "\xEC\xA5\x84";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xA0";
- break;
- case 0xAC :
- return "\xEC\xA5\xBC";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x98";
- break;
- case 0xA4 :
- return "\xEC\xA6\xB4";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x90";
- break;
- case 0x9C :
- return "\xEC\xA7\xAC";
- break;
- case 0xB8 :
- return "\xEC\xA8\x88";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xA4";
- break;
- case 0xB0 :
- return "\xEC\xA9\x80";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x9C";
- break;
- case 0xA8 :
- return "\xEC\xA9\xB8";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x94";
- break;
- case 0xA0 :
- return "\xEC\xAA\xB0";
- break;
- case 0xBC :
- return "\xEC\xAB\x8C";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xA8";
- break;
- case 0xB4 :
- return "\xEC\xAC\x84";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xA0";
- break;
- case 0xAC :
- return "\xEC\xAC\xBC";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x98";
- break;
- case 0xA4 :
- return "\xEC\xAD\xB4";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x90";
- break;
- case 0x9C :
- return "\xEC\xAE\xAC";
- break;
- case 0xB8 :
- return "\xEC\xAF\x88";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xA4";
- break;
- case 0xB0 :
- return "\xEC\xB0\x80";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x9C";
- break;
- case 0xA8 :
- return "\xEC\xB0\xB8";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x94";
- break;
- case 0xA0 :
- return "\xEC\xB1\xB0";
- break;
- case 0xBC :
- return "\xEC\xB2\x8C";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xA8";
- break;
- case 0xB4 :
- return "\xEC\xB3\x84";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xA0";
- break;
- case 0xAC :
- return "\xEC\xB3\xBC";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x98";
- break;
- case 0xA4 :
- return "\xEC\xB4\xB4";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x90";
- break;
- case 0x9C :
- return "\xEC\xB5\xAC";
- break;
- case 0xB8 :
- return "\xEC\xB6\x88";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xA4";
- break;
- case 0xB0 :
- return "\xEC\xB7\x80";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x9C";
- break;
- case 0xA8 :
- return "\xEC\xB7\xB8";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x94";
- break;
- case 0xA0 :
- return "\xEC\xB8\xB0";
- break;
- case 0xBC :
- return "\xEC\xB9\x8C";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xA8";
- break;
- case 0xB4 :
- return "\xEC\xBA\x84";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xA0";
- break;
- case 0xAC :
- return "\xEC\xBA\xBC";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x98";
- break;
- case 0xA4 :
- return "\xEC\xBB\xB4";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x90";
- break;
- case 0x9C :
- return "\xEC\xBC\xAC";
- break;
- case 0xB8 :
- return "\xEC\xBD\x88";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xA4";
- break;
- case 0xB0 :
- return "\xEC\xBE\x80";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x9C";
- break;
- case 0xA8 :
- return "\xEC\xBE\xB8";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x94";
- break;
- case 0xA0 :
- return "\xEC\xBF\xB0";
- break;
- case 0xBC :
- return "\xED\x80\x8C";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xA8";
- break;
- case 0xB4 :
- return "\xED\x81\x84";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xA0";
- break;
- case 0xAC :
- return "\xED\x81\xBC";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x98";
- break;
- case 0xA4 :
- return "\xED\x82\xB4";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x90";
- break;
- case 0x9C :
- return "\xED\x83\xAC";
- break;
- case 0xB8 :
- return "\xED\x84\x88";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xA4";
- break;
- case 0xB0 :
- return "\xED\x85\x80";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x9C";
- break;
- case 0xA8 :
- return "\xED\x85\xB8";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x94";
- break;
- case 0xA0 :
- return "\xED\x86\xB0";
- break;
- case 0xBC :
- return "\xED\x87\x8C";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xA8";
- break;
- case 0xB4 :
- return "\xED\x88\x84";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xA0";
- break;
- case 0xAC :
- return "\xED\x88\xBC";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x98";
- break;
- case 0xA4 :
- return "\xED\x89\xB4";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x90";
- break;
- case 0x9C :
- return "\xED\x8A\xAC";
- break;
- case 0xB8 :
- return "\xED\x8B\x88";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xA4";
- break;
- case 0xB0 :
- return "\xED\x8C\x80";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x9C";
- break;
- case 0xA8 :
- return "\xED\x8C\xB8";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x94";
- break;
- case 0xA0 :
- return "\xED\x8D\xB0";
- break;
- case 0xBC :
- return "\xED\x8E\x8C";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xA8";
- break;
- case 0xB4 :
- return "\xED\x8F\x84";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xA0";
- break;
- case 0xAC :
- return "\xED\x8F\xBC";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x98";
- break;
- case 0xA4 :
- return "\xED\x90\xB4";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x90";
- break;
- case 0x9C :
- return "\xED\x91\xAC";
- break;
- case 0xB8 :
- return "\xED\x92\x88";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xA4";
- break;
- case 0xB0 :
- return "\xED\x93\x80";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x9C";
- break;
- case 0xA8 :
- return "\xED\x93\xB8";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x94";
- break;
- case 0xA0 :
- return "\xED\x94\xB0";
- break;
- case 0xBC :
- return "\xED\x95\x8C";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xA8";
- break;
- case 0xB4 :
- return "\xED\x96\x84";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xA0";
- break;
- case 0xAC :
- return "\xED\x96\xBC";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x98";
- break;
- case 0xA4 :
- return "\xED\x97\xB4";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x90";
- break;
- case 0x9C :
- return "\xED\x98\xAC";
- break;
- case 0xB8 :
- return "\xED\x99\x88";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xA4";
- break;
- case 0xB0 :
- return "\xED\x9A\x80";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x9C";
- break;
- case 0xA8 :
- return "\xED\x9A\xB8";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x94";
- break;
- case 0xA0 :
- return "\xED\x9B\xB0";
- break;
- case 0xBC :
- return "\xED\x9C\x8C";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xA8";
- break;
- case 0xB4 :
- return "\xED\x9D\x84";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xA0";
- break;
- case 0xAC :
- return "\xED\x9D\xBC";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x98";
- }
- break;
- }
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x91";
- break;
- case 0x9C :
- return "\xEA\xB0\xAD";
- break;
- case 0xB8 :
- return "\xEA\xB1\x89";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xA5";
- break;
- case 0xB0 :
- return "\xEA\xB2\x81";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x9D";
- break;
- case 0xA8 :
- return "\xEA\xB2\xB9";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x95";
- break;
- case 0xA0 :
- return "\xEA\xB3\xB1";
- break;
- case 0xBC :
- return "\xEA\xB4\x8D";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xA9";
- break;
- case 0xB4 :
- return "\xEA\xB5\x85";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xA1";
- break;
- case 0xAC :
- return "\xEA\xB5\xBD";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x99";
- break;
- case 0xA4 :
- return "\xEA\xB6\xB5";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x91";
- break;
- case 0x9C :
- return "\xEA\xB7\xAD";
- break;
- case 0xB8 :
- return "\xEA\xB8\x89";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xA5";
- break;
- case 0xB0 :
- return "\xEA\xB9\x81";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x9D";
- break;
- case 0xA8 :
- return "\xEA\xB9\xB9";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x95";
- break;
- case 0xA0 :
- return "\xEA\xBA\xB1";
- break;
- case 0xBC :
- return "\xEA\xBB\x8D";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xA9";
- break;
- case 0xB4 :
- return "\xEA\xBC\x85";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xA1";
- break;
- case 0xAC :
- return "\xEA\xBC\xBD";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x99";
- break;
- case 0xA4 :
- return "\xEA\xBD\xB5";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x91";
- break;
- case 0x9C :
- return "\xEA\xBE\xAD";
- break;
- case 0xB8 :
- return "\xEA\xBF\x89";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xA5";
- break;
- case 0xB0 :
- return "\xEB\x80\x81";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x9D";
- break;
- case 0xA8 :
- return "\xEB\x80\xB9";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x95";
- break;
- case 0xA0 :
- return "\xEB\x81\xB1";
- break;
- case 0xBC :
- return "\xEB\x82\x8D";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xA9";
- break;
- case 0xB4 :
- return "\xEB\x83\x85";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xA1";
- break;
- case 0xAC :
- return "\xEB\x83\xBD";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x99";
- break;
- case 0xA4 :
- return "\xEB\x84\xB5";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x91";
- break;
- case 0x9C :
- return "\xEB\x85\xAD";
- break;
- case 0xB8 :
- return "\xEB\x86\x89";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xA5";
- break;
- case 0xB0 :
- return "\xEB\x87\x81";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x9D";
- break;
- case 0xA8 :
- return "\xEB\x87\xB9";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x95";
- break;
- case 0xA0 :
- return "\xEB\x88\xB1";
- break;
- case 0xBC :
- return "\xEB\x89\x8D";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xA9";
- break;
- case 0xB4 :
- return "\xEB\x8A\x85";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xA1";
- break;
- case 0xAC :
- return "\xEB\x8A\xBD";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x99";
- break;
- case 0xA4 :
- return "\xEB\x8B\xB5";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x91";
- break;
- case 0x9C :
- return "\xEB\x8C\xAD";
- break;
- case 0xB8 :
- return "\xEB\x8D\x89";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xA5";
- break;
- case 0xB0 :
- return "\xEB\x8E\x81";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x9D";
- break;
- case 0xA8 :
- return "\xEB\x8E\xB9";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x95";
- break;
- case 0xA0 :
- return "\xEB\x8F\xB1";
- break;
- case 0xBC :
- return "\xEB\x90\x8D";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xA9";
- break;
- case 0xB4 :
- return "\xEB\x91\x85";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xA1";
- break;
- case 0xAC :
- return "\xEB\x91\xBD";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x99";
- break;
- case 0xA4 :
- return "\xEB\x92\xB5";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x91";
- break;
- case 0x9C :
- return "\xEB\x93\xAD";
- break;
- case 0xB8 :
- return "\xEB\x94\x89";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xA5";
- break;
- case 0xB0 :
- return "\xEB\x95\x81";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x9D";
- break;
- case 0xA8 :
- return "\xEB\x95\xB9";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x95";
- break;
- case 0xA0 :
- return "\xEB\x96\xB1";
- break;
- case 0xBC :
- return "\xEB\x97\x8D";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xA9";
- break;
- case 0xB4 :
- return "\xEB\x98\x85";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xA1";
- break;
- case 0xAC :
- return "\xEB\x98\xBD";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x99";
- break;
- case 0xA4 :
- return "\xEB\x99\xB5";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x91";
- break;
- case 0x9C :
- return "\xEB\x9A\xAD";
- break;
- case 0xB8 :
- return "\xEB\x9B\x89";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xA5";
- break;
- case 0xB0 :
- return "\xEB\x9C\x81";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x9D";
- break;
- case 0xA8 :
- return "\xEB\x9C\xB9";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x95";
- break;
- case 0xA0 :
- return "\xEB\x9D\xB1";
- break;
- case 0xBC :
- return "\xEB\x9E\x8D";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xA9";
- break;
- case 0xB4 :
- return "\xEB\x9F\x85";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xA1";
- break;
- case 0xAC :
- return "\xEB\x9F\xBD";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x99";
- break;
- case 0xA4 :
- return "\xEB\xA0\xB5";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x91";
- break;
- case 0x9C :
- return "\xEB\xA1\xAD";
- break;
- case 0xB8 :
- return "\xEB\xA2\x89";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xA5";
- break;
- case 0xB0 :
- return "\xEB\xA3\x81";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x9D";
- break;
- case 0xA8 :
- return "\xEB\xA3\xB9";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x95";
- break;
- case 0xA0 :
- return "\xEB\xA4\xB1";
- break;
- case 0xBC :
- return "\xEB\xA5\x8D";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xA9";
- break;
- case 0xB4 :
- return "\xEB\xA6\x85";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xA1";
- break;
- case 0xAC :
- return "\xEB\xA6\xBD";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x99";
- break;
- case 0xA4 :
- return "\xEB\xA7\xB5";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x91";
- break;
- case 0x9C :
- return "\xEB\xA8\xAD";
- break;
- case 0xB8 :
- return "\xEB\xA9\x89";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xA5";
- break;
- case 0xB0 :
- return "\xEB\xAA\x81";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x9D";
- break;
- case 0xA8 :
- return "\xEB\xAA\xB9";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x95";
- break;
- case 0xA0 :
- return "\xEB\xAB\xB1";
- break;
- case 0xBC :
- return "\xEB\xAC\x8D";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xA9";
- break;
- case 0xB4 :
- return "\xEB\xAD\x85";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xA1";
- break;
- case 0xAC :
- return "\xEB\xAD\xBD";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x99";
- break;
- case 0xA4 :
- return "\xEB\xAE\xB5";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x91";
- break;
- case 0x9C :
- return "\xEB\xAF\xAD";
- break;
- case 0xB8 :
- return "\xEB\xB0\x89";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xA5";
- break;
- case 0xB0 :
- return "\xEB\xB1\x81";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x9D";
- break;
- case 0xA8 :
- return "\xEB\xB1\xB9";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x95";
- break;
- case 0xA0 :
- return "\xEB\xB2\xB1";
- break;
- case 0xBC :
- return "\xEB\xB3\x8D";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xA9";
- break;
- case 0xB4 :
- return "\xEB\xB4\x85";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xA1";
- break;
- case 0xAC :
- return "\xEB\xB4\xBD";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x99";
- break;
- case 0xA4 :
- return "\xEB\xB5\xB5";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x91";
- break;
- case 0x9C :
- return "\xEB\xB6\xAD";
- break;
- case 0xB8 :
- return "\xEB\xB7\x89";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xA5";
- break;
- case 0xB0 :
- return "\xEB\xB8\x81";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x9D";
- break;
- case 0xA8 :
- return "\xEB\xB8\xB9";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x95";
- break;
- case 0xA0 :
- return "\xEB\xB9\xB1";
- break;
- case 0xBC :
- return "\xEB\xBA\x8D";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xA9";
- break;
- case 0xB4 :
- return "\xEB\xBB\x85";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xA1";
- break;
- case 0xAC :
- return "\xEB\xBB\xBD";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x99";
- break;
- case 0xA4 :
- return "\xEB\xBC\xB5";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x91";
- break;
- case 0x9C :
- return "\xEB\xBD\xAD";
- break;
- case 0xB8 :
- return "\xEB\xBE\x89";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xA5";
- break;
- case 0xB0 :
- return "\xEB\xBF\x81";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x9D";
- break;
- case 0xA8 :
- return "\xEB\xBF\xB9";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x95";
- break;
- case 0xA0 :
- return "\xEC\x80\xB1";
- break;
- case 0xBC :
- return "\xEC\x81\x8D";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xA9";
- break;
- case 0xB4 :
- return "\xEC\x82\x85";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xA1";
- break;
- case 0xAC :
- return "\xEC\x82\xBD";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x99";
- break;
- case 0xA4 :
- return "\xEC\x83\xB5";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x91";
- break;
- case 0x9C :
- return "\xEC\x84\xAD";
- break;
- case 0xB8 :
- return "\xEC\x85\x89";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xA5";
- break;
- case 0xB0 :
- return "\xEC\x86\x81";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x9D";
- break;
- case 0xA8 :
- return "\xEC\x86\xB9";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x95";
- break;
- case 0xA0 :
- return "\xEC\x87\xB1";
- break;
- case 0xBC :
- return "\xEC\x88\x8D";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xA9";
- break;
- case 0xB4 :
- return "\xEC\x89\x85";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xA1";
- break;
- case 0xAC :
- return "\xEC\x89\xBD";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x99";
- break;
- case 0xA4 :
- return "\xEC\x8A\xB5";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x91";
- break;
- case 0x9C :
- return "\xEC\x8B\xAD";
- break;
- case 0xB8 :
- return "\xEC\x8C\x89";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xA5";
- break;
- case 0xB0 :
- return "\xEC\x8D\x81";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x9D";
- break;
- case 0xA8 :
- return "\xEC\x8D\xB9";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x95";
- break;
- case 0xA0 :
- return "\xEC\x8E\xB1";
- break;
- case 0xBC :
- return "\xEC\x8F\x8D";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xA9";
- break;
- case 0xB4 :
- return "\xEC\x90\x85";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xA1";
- break;
- case 0xAC :
- return "\xEC\x90\xBD";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x99";
- break;
- case 0xA4 :
- return "\xEC\x91\xB5";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x91";
- break;
- case 0x9C :
- return "\xEC\x92\xAD";
- break;
- case 0xB8 :
- return "\xEC\x93\x89";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xA5";
- break;
- case 0xB0 :
- return "\xEC\x94\x81";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x9D";
- break;
- case 0xA8 :
- return "\xEC\x94\xB9";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x95";
- break;
- case 0xA0 :
- return "\xEC\x95\xB1";
- break;
- case 0xBC :
- return "\xEC\x96\x8D";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xA9";
- break;
- case 0xB4 :
- return "\xEC\x97\x85";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xA1";
- break;
- case 0xAC :
- return "\xEC\x97\xBD";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x99";
- break;
- case 0xA4 :
- return "\xEC\x98\xB5";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x91";
- break;
- case 0x9C :
- return "\xEC\x99\xAD";
- break;
- case 0xB8 :
- return "\xEC\x9A\x89";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xA5";
- break;
- case 0xB0 :
- return "\xEC\x9B\x81";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x9D";
- break;
- case 0xA8 :
- return "\xEC\x9B\xB9";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x95";
- break;
- case 0xA0 :
- return "\xEC\x9C\xB1";
- break;
- case 0xBC :
- return "\xEC\x9D\x8D";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xA9";
- break;
- case 0xB4 :
- return "\xEC\x9E\x85";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xA1";
- break;
- case 0xAC :
- return "\xEC\x9E\xBD";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x99";
- break;
- case 0xA4 :
- return "\xEC\x9F\xB5";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x91";
- break;
- case 0x9C :
- return "\xEC\xA0\xAD";
- break;
- case 0xB8 :
- return "\xEC\xA1\x89";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xA5";
- break;
- case 0xB0 :
- return "\xEC\xA2\x81";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x9D";
- break;
- case 0xA8 :
- return "\xEC\xA2\xB9";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x95";
- break;
- case 0xA0 :
- return "\xEC\xA3\xB1";
- break;
- case 0xBC :
- return "\xEC\xA4\x8D";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xA9";
- break;
- case 0xB4 :
- return "\xEC\xA5\x85";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xA1";
- break;
- case 0xAC :
- return "\xEC\xA5\xBD";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x99";
- break;
- case 0xA4 :
- return "\xEC\xA6\xB5";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x91";
- break;
- case 0x9C :
- return "\xEC\xA7\xAD";
- break;
- case 0xB8 :
- return "\xEC\xA8\x89";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xA5";
- break;
- case 0xB0 :
- return "\xEC\xA9\x81";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x9D";
- break;
- case 0xA8 :
- return "\xEC\xA9\xB9";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x95";
- break;
- case 0xA0 :
- return "\xEC\xAA\xB1";
- break;
- case 0xBC :
- return "\xEC\xAB\x8D";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xA9";
- break;
- case 0xB4 :
- return "\xEC\xAC\x85";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xA1";
- break;
- case 0xAC :
- return "\xEC\xAC\xBD";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x99";
- break;
- case 0xA4 :
- return "\xEC\xAD\xB5";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x91";
- break;
- case 0x9C :
- return "\xEC\xAE\xAD";
- break;
- case 0xB8 :
- return "\xEC\xAF\x89";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xA5";
- break;
- case 0xB0 :
- return "\xEC\xB0\x81";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x9D";
- break;
- case 0xA8 :
- return "\xEC\xB0\xB9";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x95";
- break;
- case 0xA0 :
- return "\xEC\xB1\xB1";
- break;
- case 0xBC :
- return "\xEC\xB2\x8D";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xA9";
- break;
- case 0xB4 :
- return "\xEC\xB3\x85";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xA1";
- break;
- case 0xAC :
- return "\xEC\xB3\xBD";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x99";
- break;
- case 0xA4 :
- return "\xEC\xB4\xB5";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x91";
- break;
- case 0x9C :
- return "\xEC\xB5\xAD";
- break;
- case 0xB8 :
- return "\xEC\xB6\x89";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xA5";
- break;
- case 0xB0 :
- return "\xEC\xB7\x81";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x9D";
- break;
- case 0xA8 :
- return "\xEC\xB7\xB9";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x95";
- break;
- case 0xA0 :
- return "\xEC\xB8\xB1";
- break;
- case 0xBC :
- return "\xEC\xB9\x8D";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xA9";
- break;
- case 0xB4 :
- return "\xEC\xBA\x85";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xA1";
- break;
- case 0xAC :
- return "\xEC\xBA\xBD";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x99";
- break;
- case 0xA4 :
- return "\xEC\xBB\xB5";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x91";
- break;
- case 0x9C :
- return "\xEC\xBC\xAD";
- break;
- case 0xB8 :
- return "\xEC\xBD\x89";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xA5";
- break;
- case 0xB0 :
- return "\xEC\xBE\x81";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x9D";
- break;
- case 0xA8 :
- return "\xEC\xBE\xB9";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x95";
- break;
- case 0xA0 :
- return "\xEC\xBF\xB1";
- break;
- case 0xBC :
- return "\xED\x80\x8D";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xA9";
- break;
- case 0xB4 :
- return "\xED\x81\x85";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xA1";
- break;
- case 0xAC :
- return "\xED\x81\xBD";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x99";
- break;
- case 0xA4 :
- return "\xED\x82\xB5";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x91";
- break;
- case 0x9C :
- return "\xED\x83\xAD";
- break;
- case 0xB8 :
- return "\xED\x84\x89";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xA5";
- break;
- case 0xB0 :
- return "\xED\x85\x81";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x9D";
- break;
- case 0xA8 :
- return "\xED\x85\xB9";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x95";
- break;
- case 0xA0 :
- return "\xED\x86\xB1";
- break;
- case 0xBC :
- return "\xED\x87\x8D";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xA9";
- break;
- case 0xB4 :
- return "\xED\x88\x85";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xA1";
- break;
- case 0xAC :
- return "\xED\x88\xBD";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x99";
- break;
- case 0xA4 :
- return "\xED\x89\xB5";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x91";
- break;
- case 0x9C :
- return "\xED\x8A\xAD";
- break;
- case 0xB8 :
- return "\xED\x8B\x89";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xA5";
- break;
- case 0xB0 :
- return "\xED\x8C\x81";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x9D";
- break;
- case 0xA8 :
- return "\xED\x8C\xB9";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x95";
- break;
- case 0xA0 :
- return "\xED\x8D\xB1";
- break;
- case 0xBC :
- return "\xED\x8E\x8D";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xA9";
- break;
- case 0xB4 :
- return "\xED\x8F\x85";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xA1";
- break;
- case 0xAC :
- return "\xED\x8F\xBD";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x99";
- break;
- case 0xA4 :
- return "\xED\x90\xB5";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x91";
- break;
- case 0x9C :
- return "\xED\x91\xAD";
- break;
- case 0xB8 :
- return "\xED\x92\x89";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xA5";
- break;
- case 0xB0 :
- return "\xED\x93\x81";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x9D";
- break;
- case 0xA8 :
- return "\xED\x93\xB9";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x95";
- break;
- case 0xA0 :
- return "\xED\x94\xB1";
- break;
- case 0xBC :
- return "\xED\x95\x8D";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xA9";
- break;
- case 0xB4 :
- return "\xED\x96\x85";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xA1";
- break;
- case 0xAC :
- return "\xED\x96\xBD";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x99";
- break;
- case 0xA4 :
- return "\xED\x97\xB5";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x91";
- break;
- case 0x9C :
- return "\xED\x98\xAD";
- break;
- case 0xB8 :
- return "\xED\x99\x89";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xA5";
- break;
- case 0xB0 :
- return "\xED\x9A\x81";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x9D";
- break;
- case 0xA8 :
- return "\xED\x9A\xB9";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x95";
- break;
- case 0xA0 :
- return "\xED\x9B\xB1";
- break;
- case 0xBC :
- return "\xED\x9C\x8D";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xA9";
- break;
- case 0xB4 :
- return "\xED\x9D\x85";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xA1";
- break;
- case 0xAC :
- return "\xED\x9D\xBD";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x99";
- }
- break;
- }
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x92";
- break;
- case 0x9C :
- return "\xEA\xB0\xAE";
- break;
- case 0xB8 :
- return "\xEA\xB1\x8A";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xA6";
- break;
- case 0xB0 :
- return "\xEA\xB2\x82";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x9E";
- break;
- case 0xA8 :
- return "\xEA\xB2\xBA";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x96";
- break;
- case 0xA0 :
- return "\xEA\xB3\xB2";
- break;
- case 0xBC :
- return "\xEA\xB4\x8E";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xAA";
- break;
- case 0xB4 :
- return "\xEA\xB5\x86";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xA2";
- break;
- case 0xAC :
- return "\xEA\xB5\xBE";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x9A";
- break;
- case 0xA4 :
- return "\xEA\xB6\xB6";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x92";
- break;
- case 0x9C :
- return "\xEA\xB7\xAE";
- break;
- case 0xB8 :
- return "\xEA\xB8\x8A";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xA6";
- break;
- case 0xB0 :
- return "\xEA\xB9\x82";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x9E";
- break;
- case 0xA8 :
- return "\xEA\xB9\xBA";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x96";
- break;
- case 0xA0 :
- return "\xEA\xBA\xB2";
- break;
- case 0xBC :
- return "\xEA\xBB\x8E";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xAA";
- break;
- case 0xB4 :
- return "\xEA\xBC\x86";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xA2";
- break;
- case 0xAC :
- return "\xEA\xBC\xBE";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x9A";
- break;
- case 0xA4 :
- return "\xEA\xBD\xB6";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x92";
- break;
- case 0x9C :
- return "\xEA\xBE\xAE";
- break;
- case 0xB8 :
- return "\xEA\xBF\x8A";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xA6";
- break;
- case 0xB0 :
- return "\xEB\x80\x82";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x9E";
- break;
- case 0xA8 :
- return "\xEB\x80\xBA";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x96";
- break;
- case 0xA0 :
- return "\xEB\x81\xB2";
- break;
- case 0xBC :
- return "\xEB\x82\x8E";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xAA";
- break;
- case 0xB4 :
- return "\xEB\x83\x86";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xA2";
- break;
- case 0xAC :
- return "\xEB\x83\xBE";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x9A";
- break;
- case 0xA4 :
- return "\xEB\x84\xB6";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x92";
- break;
- case 0x9C :
- return "\xEB\x85\xAE";
- break;
- case 0xB8 :
- return "\xEB\x86\x8A";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xA6";
- break;
- case 0xB0 :
- return "\xEB\x87\x82";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x9E";
- break;
- case 0xA8 :
- return "\xEB\x87\xBA";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x96";
- break;
- case 0xA0 :
- return "\xEB\x88\xB2";
- break;
- case 0xBC :
- return "\xEB\x89\x8E";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xAA";
- break;
- case 0xB4 :
- return "\xEB\x8A\x86";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xA2";
- break;
- case 0xAC :
- return "\xEB\x8A\xBE";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x9A";
- break;
- case 0xA4 :
- return "\xEB\x8B\xB6";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x92";
- break;
- case 0x9C :
- return "\xEB\x8C\xAE";
- break;
- case 0xB8 :
- return "\xEB\x8D\x8A";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xA6";
- break;
- case 0xB0 :
- return "\xEB\x8E\x82";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x9E";
- break;
- case 0xA8 :
- return "\xEB\x8E\xBA";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x96";
- break;
- case 0xA0 :
- return "\xEB\x8F\xB2";
- break;
- case 0xBC :
- return "\xEB\x90\x8E";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xAA";
- break;
- case 0xB4 :
- return "\xEB\x91\x86";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xA2";
- break;
- case 0xAC :
- return "\xEB\x91\xBE";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x9A";
- break;
- case 0xA4 :
- return "\xEB\x92\xB6";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x92";
- break;
- case 0x9C :
- return "\xEB\x93\xAE";
- break;
- case 0xB8 :
- return "\xEB\x94\x8A";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xA6";
- break;
- case 0xB0 :
- return "\xEB\x95\x82";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x9E";
- break;
- case 0xA8 :
- return "\xEB\x95\xBA";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x96";
- break;
- case 0xA0 :
- return "\xEB\x96\xB2";
- break;
- case 0xBC :
- return "\xEB\x97\x8E";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xAA";
- break;
- case 0xB4 :
- return "\xEB\x98\x86";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xA2";
- break;
- case 0xAC :
- return "\xEB\x98\xBE";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x9A";
- break;
- case 0xA4 :
- return "\xEB\x99\xB6";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x92";
- break;
- case 0x9C :
- return "\xEB\x9A\xAE";
- break;
- case 0xB8 :
- return "\xEB\x9B\x8A";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xA6";
- break;
- case 0xB0 :
- return "\xEB\x9C\x82";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x9E";
- break;
- case 0xA8 :
- return "\xEB\x9C\xBA";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x96";
- break;
- case 0xA0 :
- return "\xEB\x9D\xB2";
- break;
- case 0xBC :
- return "\xEB\x9E\x8E";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xAA";
- break;
- case 0xB4 :
- return "\xEB\x9F\x86";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xA2";
- break;
- case 0xAC :
- return "\xEB\x9F\xBE";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x9A";
- break;
- case 0xA4 :
- return "\xEB\xA0\xB6";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x92";
- break;
- case 0x9C :
- return "\xEB\xA1\xAE";
- break;
- case 0xB8 :
- return "\xEB\xA2\x8A";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xA6";
- break;
- case 0xB0 :
- return "\xEB\xA3\x82";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x9E";
- break;
- case 0xA8 :
- return "\xEB\xA3\xBA";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x96";
- break;
- case 0xA0 :
- return "\xEB\xA4\xB2";
- break;
- case 0xBC :
- return "\xEB\xA5\x8E";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xAA";
- break;
- case 0xB4 :
- return "\xEB\xA6\x86";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xA2";
- break;
- case 0xAC :
- return "\xEB\xA6\xBE";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x9A";
- break;
- case 0xA4 :
- return "\xEB\xA7\xB6";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x92";
- break;
- case 0x9C :
- return "\xEB\xA8\xAE";
- break;
- case 0xB8 :
- return "\xEB\xA9\x8A";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xA6";
- break;
- case 0xB0 :
- return "\xEB\xAA\x82";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x9E";
- break;
- case 0xA8 :
- return "\xEB\xAA\xBA";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x96";
- break;
- case 0xA0 :
- return "\xEB\xAB\xB2";
- break;
- case 0xBC :
- return "\xEB\xAC\x8E";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xAA";
- break;
- case 0xB4 :
- return "\xEB\xAD\x86";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xA2";
- break;
- case 0xAC :
- return "\xEB\xAD\xBE";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x9A";
- break;
- case 0xA4 :
- return "\xEB\xAE\xB6";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x92";
- break;
- case 0x9C :
- return "\xEB\xAF\xAE";
- break;
- case 0xB8 :
- return "\xEB\xB0\x8A";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xA6";
- break;
- case 0xB0 :
- return "\xEB\xB1\x82";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x9E";
- break;
- case 0xA8 :
- return "\xEB\xB1\xBA";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x96";
- break;
- case 0xA0 :
- return "\xEB\xB2\xB2";
- break;
- case 0xBC :
- return "\xEB\xB3\x8E";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xAA";
- break;
- case 0xB4 :
- return "\xEB\xB4\x86";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xA2";
- break;
- case 0xAC :
- return "\xEB\xB4\xBE";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x9A";
- break;
- case 0xA4 :
- return "\xEB\xB5\xB6";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x92";
- break;
- case 0x9C :
- return "\xEB\xB6\xAE";
- break;
- case 0xB8 :
- return "\xEB\xB7\x8A";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xA6";
- break;
- case 0xB0 :
- return "\xEB\xB8\x82";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x9E";
- break;
- case 0xA8 :
- return "\xEB\xB8\xBA";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x96";
- break;
- case 0xA0 :
- return "\xEB\xB9\xB2";
- break;
- case 0xBC :
- return "\xEB\xBA\x8E";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xAA";
- break;
- case 0xB4 :
- return "\xEB\xBB\x86";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xA2";
- break;
- case 0xAC :
- return "\xEB\xBB\xBE";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x9A";
- break;
- case 0xA4 :
- return "\xEB\xBC\xB6";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x92";
- break;
- case 0x9C :
- return "\xEB\xBD\xAE";
- break;
- case 0xB8 :
- return "\xEB\xBE\x8A";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xA6";
- break;
- case 0xB0 :
- return "\xEB\xBF\x82";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x9E";
- break;
- case 0xA8 :
- return "\xEB\xBF\xBA";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x96";
- break;
- case 0xA0 :
- return "\xEC\x80\xB2";
- break;
- case 0xBC :
- return "\xEC\x81\x8E";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xAA";
- break;
- case 0xB4 :
- return "\xEC\x82\x86";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xA2";
- break;
- case 0xAC :
- return "\xEC\x82\xBE";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x9A";
- break;
- case 0xA4 :
- return "\xEC\x83\xB6";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x92";
- break;
- case 0x9C :
- return "\xEC\x84\xAE";
- break;
- case 0xB8 :
- return "\xEC\x85\x8A";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xA6";
- break;
- case 0xB0 :
- return "\xEC\x86\x82";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x9E";
- break;
- case 0xA8 :
- return "\xEC\x86\xBA";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x96";
- break;
- case 0xA0 :
- return "\xEC\x87\xB2";
- break;
- case 0xBC :
- return "\xEC\x88\x8E";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xAA";
- break;
- case 0xB4 :
- return "\xEC\x89\x86";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xA2";
- break;
- case 0xAC :
- return "\xEC\x89\xBE";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x9A";
- break;
- case 0xA4 :
- return "\xEC\x8A\xB6";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x92";
- break;
- case 0x9C :
- return "\xEC\x8B\xAE";
- break;
- case 0xB8 :
- return "\xEC\x8C\x8A";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xA6";
- break;
- case 0xB0 :
- return "\xEC\x8D\x82";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x9E";
- break;
- case 0xA8 :
- return "\xEC\x8D\xBA";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x96";
- break;
- case 0xA0 :
- return "\xEC\x8E\xB2";
- break;
- case 0xBC :
- return "\xEC\x8F\x8E";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xAA";
- break;
- case 0xB4 :
- return "\xEC\x90\x86";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xA2";
- break;
- case 0xAC :
- return "\xEC\x90\xBE";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x9A";
- break;
- case 0xA4 :
- return "\xEC\x91\xB6";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x92";
- break;
- case 0x9C :
- return "\xEC\x92\xAE";
- break;
- case 0xB8 :
- return "\xEC\x93\x8A";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xA6";
- break;
- case 0xB0 :
- return "\xEC\x94\x82";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x9E";
- break;
- case 0xA8 :
- return "\xEC\x94\xBA";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x96";
- break;
- case 0xA0 :
- return "\xEC\x95\xB2";
- break;
- case 0xBC :
- return "\xEC\x96\x8E";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xAA";
- break;
- case 0xB4 :
- return "\xEC\x97\x86";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xA2";
- break;
- case 0xAC :
- return "\xEC\x97\xBE";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x9A";
- break;
- case 0xA4 :
- return "\xEC\x98\xB6";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x92";
- break;
- case 0x9C :
- return "\xEC\x99\xAE";
- break;
- case 0xB8 :
- return "\xEC\x9A\x8A";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xA6";
- break;
- case 0xB0 :
- return "\xEC\x9B\x82";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x9E";
- break;
- case 0xA8 :
- return "\xEC\x9B\xBA";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x96";
- break;
- case 0xA0 :
- return "\xEC\x9C\xB2";
- break;
- case 0xBC :
- return "\xEC\x9D\x8E";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xAA";
- break;
- case 0xB4 :
- return "\xEC\x9E\x86";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xA2";
- break;
- case 0xAC :
- return "\xEC\x9E\xBE";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x9A";
- break;
- case 0xA4 :
- return "\xEC\x9F\xB6";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x92";
- break;
- case 0x9C :
- return "\xEC\xA0\xAE";
- break;
- case 0xB8 :
- return "\xEC\xA1\x8A";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xA6";
- break;
- case 0xB0 :
- return "\xEC\xA2\x82";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x9E";
- break;
- case 0xA8 :
- return "\xEC\xA2\xBA";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x96";
- break;
- case 0xA0 :
- return "\xEC\xA3\xB2";
- break;
- case 0xBC :
- return "\xEC\xA4\x8E";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xAA";
- break;
- case 0xB4 :
- return "\xEC\xA5\x86";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xA2";
- break;
- case 0xAC :
- return "\xEC\xA5\xBE";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x9A";
- break;
- case 0xA4 :
- return "\xEC\xA6\xB6";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x92";
- break;
- case 0x9C :
- return "\xEC\xA7\xAE";
- break;
- case 0xB8 :
- return "\xEC\xA8\x8A";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xA6";
- break;
- case 0xB0 :
- return "\xEC\xA9\x82";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x9E";
- break;
- case 0xA8 :
- return "\xEC\xA9\xBA";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x96";
- break;
- case 0xA0 :
- return "\xEC\xAA\xB2";
- break;
- case 0xBC :
- return "\xEC\xAB\x8E";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xAA";
- break;
- case 0xB4 :
- return "\xEC\xAC\x86";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xA2";
- break;
- case 0xAC :
- return "\xEC\xAC\xBE";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x9A";
- break;
- case 0xA4 :
- return "\xEC\xAD\xB6";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x92";
- break;
- case 0x9C :
- return "\xEC\xAE\xAE";
- break;
- case 0xB8 :
- return "\xEC\xAF\x8A";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xA6";
- break;
- case 0xB0 :
- return "\xEC\xB0\x82";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x9E";
- break;
- case 0xA8 :
- return "\xEC\xB0\xBA";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x96";
- break;
- case 0xA0 :
- return "\xEC\xB1\xB2";
- break;
- case 0xBC :
- return "\xEC\xB2\x8E";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xAA";
- break;
- case 0xB4 :
- return "\xEC\xB3\x86";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xA2";
- break;
- case 0xAC :
- return "\xEC\xB3\xBE";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x9A";
- break;
- case 0xA4 :
- return "\xEC\xB4\xB6";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x92";
- break;
- case 0x9C :
- return "\xEC\xB5\xAE";
- break;
- case 0xB8 :
- return "\xEC\xB6\x8A";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xA6";
- break;
- case 0xB0 :
- return "\xEC\xB7\x82";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x9E";
- break;
- case 0xA8 :
- return "\xEC\xB7\xBA";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x96";
- break;
- case 0xA0 :
- return "\xEC\xB8\xB2";
- break;
- case 0xBC :
- return "\xEC\xB9\x8E";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xAA";
- break;
- case 0xB4 :
- return "\xEC\xBA\x86";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xA2";
- break;
- case 0xAC :
- return "\xEC\xBA\xBE";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x9A";
- break;
- case 0xA4 :
- return "\xEC\xBB\xB6";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x92";
- break;
- case 0x9C :
- return "\xEC\xBC\xAE";
- break;
- case 0xB8 :
- return "\xEC\xBD\x8A";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xA6";
- break;
- case 0xB0 :
- return "\xEC\xBE\x82";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x9E";
- break;
- case 0xA8 :
- return "\xEC\xBE\xBA";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x96";
- break;
- case 0xA0 :
- return "\xEC\xBF\xB2";
- break;
- case 0xBC :
- return "\xED\x80\x8E";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xAA";
- break;
- case 0xB4 :
- return "\xED\x81\x86";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xA2";
- break;
- case 0xAC :
- return "\xED\x81\xBE";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x9A";
- break;
- case 0xA4 :
- return "\xED\x82\xB6";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x92";
- break;
- case 0x9C :
- return "\xED\x83\xAE";
- break;
- case 0xB8 :
- return "\xED\x84\x8A";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xA6";
- break;
- case 0xB0 :
- return "\xED\x85\x82";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x9E";
- break;
- case 0xA8 :
- return "\xED\x85\xBA";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x96";
- break;
- case 0xA0 :
- return "\xED\x86\xB2";
- break;
- case 0xBC :
- return "\xED\x87\x8E";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xAA";
- break;
- case 0xB4 :
- return "\xED\x88\x86";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xA2";
- break;
- case 0xAC :
- return "\xED\x88\xBE";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x9A";
- break;
- case 0xA4 :
- return "\xED\x89\xB6";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x92";
- break;
- case 0x9C :
- return "\xED\x8A\xAE";
- break;
- case 0xB8 :
- return "\xED\x8B\x8A";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xA6";
- break;
- case 0xB0 :
- return "\xED\x8C\x82";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x9E";
- break;
- case 0xA8 :
- return "\xED\x8C\xBA";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x96";
- break;
- case 0xA0 :
- return "\xED\x8D\xB2";
- break;
- case 0xBC :
- return "\xED\x8E\x8E";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xAA";
- break;
- case 0xB4 :
- return "\xED\x8F\x86";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xA2";
- break;
- case 0xAC :
- return "\xED\x8F\xBE";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x9A";
- break;
- case 0xA4 :
- return "\xED\x90\xB6";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x92";
- break;
- case 0x9C :
- return "\xED\x91\xAE";
- break;
- case 0xB8 :
- return "\xED\x92\x8A";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xA6";
- break;
- case 0xB0 :
- return "\xED\x93\x82";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x9E";
- break;
- case 0xA8 :
- return "\xED\x93\xBA";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x96";
- break;
- case 0xA0 :
- return "\xED\x94\xB2";
- break;
- case 0xBC :
- return "\xED\x95\x8E";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xAA";
- break;
- case 0xB4 :
- return "\xED\x96\x86";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xA2";
- break;
- case 0xAC :
- return "\xED\x96\xBE";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x9A";
- break;
- case 0xA4 :
- return "\xED\x97\xB6";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x92";
- break;
- case 0x9C :
- return "\xED\x98\xAE";
- break;
- case 0xB8 :
- return "\xED\x99\x8A";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xA6";
- break;
- case 0xB0 :
- return "\xED\x9A\x82";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x9E";
- break;
- case 0xA8 :
- return "\xED\x9A\xBA";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x96";
- break;
- case 0xA0 :
- return "\xED\x9B\xB2";
- break;
- case 0xBC :
- return "\xED\x9C\x8E";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xAA";
- break;
- case 0xB4 :
- return "\xED\x9D\x86";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xA2";
- break;
- case 0xAC :
- return "\xED\x9D\xBE";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x9A";
- }
- break;
- }
- break;
- }
- break;
- case 0xBA :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x93";
- break;
- case 0x9C :
- return "\xEA\xB0\xAF";
- break;
- case 0xB8 :
- return "\xEA\xB1\x8B";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xA7";
- break;
- case 0xB0 :
- return "\xEA\xB2\x83";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\x9F";
- break;
- case 0xA8 :
- return "\xEA\xB2\xBB";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x97";
- break;
- case 0xA0 :
- return "\xEA\xB3\xB3";
- break;
- case 0xBC :
- return "\xEA\xB4\x8F";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xAB";
- break;
- case 0xB4 :
- return "\xEA\xB5\x87";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xA3";
- break;
- case 0xAC :
- return "\xEA\xB5\xBF";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x9B";
- break;
- case 0xA4 :
- return "\xEA\xB6\xB7";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x93";
- break;
- case 0x9C :
- return "\xEA\xB7\xAF";
- break;
- case 0xB8 :
- return "\xEA\xB8\x8B";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xA7";
- break;
- case 0xB0 :
- return "\xEA\xB9\x83";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\x9F";
- break;
- case 0xA8 :
- return "\xEA\xB9\xBB";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x97";
- break;
- case 0xA0 :
- return "\xEA\xBA\xB3";
- break;
- case 0xBC :
- return "\xEA\xBB\x8F";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xAB";
- break;
- case 0xB4 :
- return "\xEA\xBC\x87";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xA3";
- break;
- case 0xAC :
- return "\xEA\xBC\xBF";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x9B";
- break;
- case 0xA4 :
- return "\xEA\xBD\xB7";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x93";
- break;
- case 0x9C :
- return "\xEA\xBE\xAF";
- break;
- case 0xB8 :
- return "\xEA\xBF\x8B";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xA7";
- break;
- case 0xB0 :
- return "\xEB\x80\x83";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\x9F";
- break;
- case 0xA8 :
- return "\xEB\x80\xBB";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x97";
- break;
- case 0xA0 :
- return "\xEB\x81\xB3";
- break;
- case 0xBC :
- return "\xEB\x82\x8F";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xAB";
- break;
- case 0xB4 :
- return "\xEB\x83\x87";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xA3";
- break;
- case 0xAC :
- return "\xEB\x83\xBF";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x9B";
- break;
- case 0xA4 :
- return "\xEB\x84\xB7";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x93";
- break;
- case 0x9C :
- return "\xEB\x85\xAF";
- break;
- case 0xB8 :
- return "\xEB\x86\x8B";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xA7";
- break;
- case 0xB0 :
- return "\xEB\x87\x83";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\x9F";
- break;
- case 0xA8 :
- return "\xEB\x87\xBB";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x97";
- break;
- case 0xA0 :
- return "\xEB\x88\xB3";
- break;
- case 0xBC :
- return "\xEB\x89\x8F";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xAB";
- break;
- case 0xB4 :
- return "\xEB\x8A\x87";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xA3";
- break;
- case 0xAC :
- return "\xEB\x8A\xBF";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x9B";
- break;
- case 0xA4 :
- return "\xEB\x8B\xB7";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x93";
- break;
- case 0x9C :
- return "\xEB\x8C\xAF";
- break;
- case 0xB8 :
- return "\xEB\x8D\x8B";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xA7";
- break;
- case 0xB0 :
- return "\xEB\x8E\x83";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\x9F";
- break;
- case 0xA8 :
- return "\xEB\x8E\xBB";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x97";
- break;
- case 0xA0 :
- return "\xEB\x8F\xB3";
- break;
- case 0xBC :
- return "\xEB\x90\x8F";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xAB";
- break;
- case 0xB4 :
- return "\xEB\x91\x87";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xA3";
- break;
- case 0xAC :
- return "\xEB\x91\xBF";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x9B";
- break;
- case 0xA4 :
- return "\xEB\x92\xB7";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x93";
- break;
- case 0x9C :
- return "\xEB\x93\xAF";
- break;
- case 0xB8 :
- return "\xEB\x94\x8B";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xA7";
- break;
- case 0xB0 :
- return "\xEB\x95\x83";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\x9F";
- break;
- case 0xA8 :
- return "\xEB\x95\xBB";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x97";
- break;
- case 0xA0 :
- return "\xEB\x96\xB3";
- break;
- case 0xBC :
- return "\xEB\x97\x8F";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xAB";
- break;
- case 0xB4 :
- return "\xEB\x98\x87";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xA3";
- break;
- case 0xAC :
- return "\xEB\x98\xBF";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x9B";
- break;
- case 0xA4 :
- return "\xEB\x99\xB7";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x93";
- break;
- case 0x9C :
- return "\xEB\x9A\xAF";
- break;
- case 0xB8 :
- return "\xEB\x9B\x8B";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xA7";
- break;
- case 0xB0 :
- return "\xEB\x9C\x83";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\x9F";
- break;
- case 0xA8 :
- return "\xEB\x9C\xBB";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x97";
- break;
- case 0xA0 :
- return "\xEB\x9D\xB3";
- break;
- case 0xBC :
- return "\xEB\x9E\x8F";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xAB";
- break;
- case 0xB4 :
- return "\xEB\x9F\x87";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xA3";
- break;
- case 0xAC :
- return "\xEB\x9F\xBF";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x9B";
- break;
- case 0xA4 :
- return "\xEB\xA0\xB7";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x93";
- break;
- case 0x9C :
- return "\xEB\xA1\xAF";
- break;
- case 0xB8 :
- return "\xEB\xA2\x8B";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xA7";
- break;
- case 0xB0 :
- return "\xEB\xA3\x83";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\x9F";
- break;
- case 0xA8 :
- return "\xEB\xA3\xBB";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x97";
- break;
- case 0xA0 :
- return "\xEB\xA4\xB3";
- break;
- case 0xBC :
- return "\xEB\xA5\x8F";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xAB";
- break;
- case 0xB4 :
- return "\xEB\xA6\x87";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xA3";
- break;
- case 0xAC :
- return "\xEB\xA6\xBF";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x9B";
- break;
- case 0xA4 :
- return "\xEB\xA7\xB7";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x93";
- break;
- case 0x9C :
- return "\xEB\xA8\xAF";
- break;
- case 0xB8 :
- return "\xEB\xA9\x8B";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xA7";
- break;
- case 0xB0 :
- return "\xEB\xAA\x83";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\x9F";
- break;
- case 0xA8 :
- return "\xEB\xAA\xBB";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x97";
- break;
- case 0xA0 :
- return "\xEB\xAB\xB3";
- break;
- case 0xBC :
- return "\xEB\xAC\x8F";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xAB";
- break;
- case 0xB4 :
- return "\xEB\xAD\x87";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xA3";
- break;
- case 0xAC :
- return "\xEB\xAD\xBF";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x9B";
- break;
- case 0xA4 :
- return "\xEB\xAE\xB7";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x93";
- break;
- case 0x9C :
- return "\xEB\xAF\xAF";
- break;
- case 0xB8 :
- return "\xEB\xB0\x8B";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xA7";
- break;
- case 0xB0 :
- return "\xEB\xB1\x83";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\x9F";
- break;
- case 0xA8 :
- return "\xEB\xB1\xBB";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x97";
- break;
- case 0xA0 :
- return "\xEB\xB2\xB3";
- break;
- case 0xBC :
- return "\xEB\xB3\x8F";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xAB";
- break;
- case 0xB4 :
- return "\xEB\xB4\x87";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xA3";
- break;
- case 0xAC :
- return "\xEB\xB4\xBF";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x9B";
- break;
- case 0xA4 :
- return "\xEB\xB5\xB7";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x93";
- break;
- case 0x9C :
- return "\xEB\xB6\xAF";
- break;
- case 0xB8 :
- return "\xEB\xB7\x8B";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xA7";
- break;
- case 0xB0 :
- return "\xEB\xB8\x83";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\x9F";
- break;
- case 0xA8 :
- return "\xEB\xB8\xBB";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x97";
- break;
- case 0xA0 :
- return "\xEB\xB9\xB3";
- break;
- case 0xBC :
- return "\xEB\xBA\x8F";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xAB";
- break;
- case 0xB4 :
- return "\xEB\xBB\x87";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xA3";
- break;
- case 0xAC :
- return "\xEB\xBB\xBF";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x9B";
- break;
- case 0xA4 :
- return "\xEB\xBC\xB7";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x93";
- break;
- case 0x9C :
- return "\xEB\xBD\xAF";
- break;
- case 0xB8 :
- return "\xEB\xBE\x8B";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xA7";
- break;
- case 0xB0 :
- return "\xEB\xBF\x83";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\x9F";
- break;
- case 0xA8 :
- return "\xEB\xBF\xBB";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x97";
- break;
- case 0xA0 :
- return "\xEC\x80\xB3";
- break;
- case 0xBC :
- return "\xEC\x81\x8F";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xAB";
- break;
- case 0xB4 :
- return "\xEC\x82\x87";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xA3";
- break;
- case 0xAC :
- return "\xEC\x82\xBF";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x9B";
- break;
- case 0xA4 :
- return "\xEC\x83\xB7";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x93";
- break;
- case 0x9C :
- return "\xEC\x84\xAF";
- break;
- case 0xB8 :
- return "\xEC\x85\x8B";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xA7";
- break;
- case 0xB0 :
- return "\xEC\x86\x83";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\x9F";
- break;
- case 0xA8 :
- return "\xEC\x86\xBB";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x97";
- break;
- case 0xA0 :
- return "\xEC\x87\xB3";
- break;
- case 0xBC :
- return "\xEC\x88\x8F";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xAB";
- break;
- case 0xB4 :
- return "\xEC\x89\x87";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xA3";
- break;
- case 0xAC :
- return "\xEC\x89\xBF";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x9B";
- break;
- case 0xA4 :
- return "\xEC\x8A\xB7";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x93";
- break;
- case 0x9C :
- return "\xEC\x8B\xAF";
- break;
- case 0xB8 :
- return "\xEC\x8C\x8B";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xA7";
- break;
- case 0xB0 :
- return "\xEC\x8D\x83";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\x9F";
- break;
- case 0xA8 :
- return "\xEC\x8D\xBB";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x97";
- break;
- case 0xA0 :
- return "\xEC\x8E\xB3";
- break;
- case 0xBC :
- return "\xEC\x8F\x8F";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xAB";
- break;
- case 0xB4 :
- return "\xEC\x90\x87";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xA3";
- break;
- case 0xAC :
- return "\xEC\x90\xBF";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x9B";
- break;
- case 0xA4 :
- return "\xEC\x91\xB7";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x93";
- break;
- case 0x9C :
- return "\xEC\x92\xAF";
- break;
- case 0xB8 :
- return "\xEC\x93\x8B";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xA7";
- break;
- case 0xB0 :
- return "\xEC\x94\x83";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\x9F";
- break;
- case 0xA8 :
- return "\xEC\x94\xBB";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x97";
- break;
- case 0xA0 :
- return "\xEC\x95\xB3";
- break;
- case 0xBC :
- return "\xEC\x96\x8F";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xAB";
- break;
- case 0xB4 :
- return "\xEC\x97\x87";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xA3";
- break;
- case 0xAC :
- return "\xEC\x97\xBF";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x9B";
- break;
- case 0xA4 :
- return "\xEC\x98\xB7";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x93";
- break;
- case 0x9C :
- return "\xEC\x99\xAF";
- break;
- case 0xB8 :
- return "\xEC\x9A\x8B";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xA7";
- break;
- case 0xB0 :
- return "\xEC\x9B\x83";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\x9F";
- break;
- case 0xA8 :
- return "\xEC\x9B\xBB";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x97";
- break;
- case 0xA0 :
- return "\xEC\x9C\xB3";
- break;
- case 0xBC :
- return "\xEC\x9D\x8F";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xAB";
- break;
- case 0xB4 :
- return "\xEC\x9E\x87";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xA3";
- break;
- case 0xAC :
- return "\xEC\x9E\xBF";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x9B";
- break;
- case 0xA4 :
- return "\xEC\x9F\xB7";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x93";
- break;
- case 0x9C :
- return "\xEC\xA0\xAF";
- break;
- case 0xB8 :
- return "\xEC\xA1\x8B";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xA7";
- break;
- case 0xB0 :
- return "\xEC\xA2\x83";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\x9F";
- break;
- case 0xA8 :
- return "\xEC\xA2\xBB";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x97";
- break;
- case 0xA0 :
- return "\xEC\xA3\xB3";
- break;
- case 0xBC :
- return "\xEC\xA4\x8F";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xAB";
- break;
- case 0xB4 :
- return "\xEC\xA5\x87";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xA3";
- break;
- case 0xAC :
- return "\xEC\xA5\xBF";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x9B";
- break;
- case 0xA4 :
- return "\xEC\xA6\xB7";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x93";
- break;
- case 0x9C :
- return "\xEC\xA7\xAF";
- break;
- case 0xB8 :
- return "\xEC\xA8\x8B";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xA7";
- break;
- case 0xB0 :
- return "\xEC\xA9\x83";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\x9F";
- break;
- case 0xA8 :
- return "\xEC\xA9\xBB";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x97";
- break;
- case 0xA0 :
- return "\xEC\xAA\xB3";
- break;
- case 0xBC :
- return "\xEC\xAB\x8F";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xAB";
- break;
- case 0xB4 :
- return "\xEC\xAC\x87";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xA3";
- break;
- case 0xAC :
- return "\xEC\xAC\xBF";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x9B";
- break;
- case 0xA4 :
- return "\xEC\xAD\xB7";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x93";
- break;
- case 0x9C :
- return "\xEC\xAE\xAF";
- break;
- case 0xB8 :
- return "\xEC\xAF\x8B";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xA7";
- break;
- case 0xB0 :
- return "\xEC\xB0\x83";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\x9F";
- break;
- case 0xA8 :
- return "\xEC\xB0\xBB";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x97";
- break;
- case 0xA0 :
- return "\xEC\xB1\xB3";
- break;
- case 0xBC :
- return "\xEC\xB2\x8F";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xAB";
- break;
- case 0xB4 :
- return "\xEC\xB3\x87";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xA3";
- break;
- case 0xAC :
- return "\xEC\xB3\xBF";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x9B";
- break;
- case 0xA4 :
- return "\xEC\xB4\xB7";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x93";
- break;
- case 0x9C :
- return "\xEC\xB5\xAF";
- break;
- case 0xB8 :
- return "\xEC\xB6\x8B";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xA7";
- break;
- case 0xB0 :
- return "\xEC\xB7\x83";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\x9F";
- break;
- case 0xA8 :
- return "\xEC\xB7\xBB";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x97";
- break;
- case 0xA0 :
- return "\xEC\xB8\xB3";
- break;
- case 0xBC :
- return "\xEC\xB9\x8F";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xAB";
- break;
- case 0xB4 :
- return "\xEC\xBA\x87";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xA3";
- break;
- case 0xAC :
- return "\xEC\xBA\xBF";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x9B";
- break;
- case 0xA4 :
- return "\xEC\xBB\xB7";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x93";
- break;
- case 0x9C :
- return "\xEC\xBC\xAF";
- break;
- case 0xB8 :
- return "\xEC\xBD\x8B";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xA7";
- break;
- case 0xB0 :
- return "\xEC\xBE\x83";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\x9F";
- break;
- case 0xA8 :
- return "\xEC\xBE\xBB";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x97";
- break;
- case 0xA0 :
- return "\xEC\xBF\xB3";
- break;
- case 0xBC :
- return "\xED\x80\x8F";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xAB";
- break;
- case 0xB4 :
- return "\xED\x81\x87";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xA3";
- break;
- case 0xAC :
- return "\xED\x81\xBF";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x9B";
- break;
- case 0xA4 :
- return "\xED\x82\xB7";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x93";
- break;
- case 0x9C :
- return "\xED\x83\xAF";
- break;
- case 0xB8 :
- return "\xED\x84\x8B";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xA7";
- break;
- case 0xB0 :
- return "\xED\x85\x83";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\x9F";
- break;
- case 0xA8 :
- return "\xED\x85\xBB";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x97";
- break;
- case 0xA0 :
- return "\xED\x86\xB3";
- break;
- case 0xBC :
- return "\xED\x87\x8F";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xAB";
- break;
- case 0xB4 :
- return "\xED\x88\x87";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xA3";
- break;
- case 0xAC :
- return "\xED\x88\xBF";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x9B";
- break;
- case 0xA4 :
- return "\xED\x89\xB7";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x93";
- break;
- case 0x9C :
- return "\xED\x8A\xAF";
- break;
- case 0xB8 :
- return "\xED\x8B\x8B";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xA7";
- break;
- case 0xB0 :
- return "\xED\x8C\x83";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\x9F";
- break;
- case 0xA8 :
- return "\xED\x8C\xBB";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x97";
- break;
- case 0xA0 :
- return "\xED\x8D\xB3";
- break;
- case 0xBC :
- return "\xED\x8E\x8F";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xAB";
- break;
- case 0xB4 :
- return "\xED\x8F\x87";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xA3";
- break;
- case 0xAC :
- return "\xED\x8F\xBF";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x9B";
- break;
- case 0xA4 :
- return "\xED\x90\xB7";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x93";
- break;
- case 0x9C :
- return "\xED\x91\xAF";
- break;
- case 0xB8 :
- return "\xED\x92\x8B";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xA7";
- break;
- case 0xB0 :
- return "\xED\x93\x83";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\x9F";
- break;
- case 0xA8 :
- return "\xED\x93\xBB";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x97";
- break;
- case 0xA0 :
- return "\xED\x94\xB3";
- break;
- case 0xBC :
- return "\xED\x95\x8F";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xAB";
- break;
- case 0xB4 :
- return "\xED\x96\x87";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xA3";
- break;
- case 0xAC :
- return "\xED\x96\xBF";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x9B";
- break;
- case 0xA4 :
- return "\xED\x97\xB7";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x93";
- break;
- case 0x9C :
- return "\xED\x98\xAF";
- break;
- case 0xB8 :
- return "\xED\x99\x8B";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xA7";
- break;
- case 0xB0 :
- return "\xED\x9A\x83";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\x9F";
- break;
- case 0xA8 :
- return "\xED\x9A\xBB";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x97";
- break;
- case 0xA0 :
- return "\xED\x9B\xB3";
- break;
- case 0xBC :
- return "\xED\x9C\x8F";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xAB";
- break;
- case 0xB4 :
- return "\xED\x9D\x87";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xA3";
- break;
- case 0xAC :
- return "\xED\x9D\xBF";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x9B";
- }
- break;
- }
- break;
- }
- break;
- case 0xBB :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x94";
- break;
- case 0x9C :
- return "\xEA\xB0\xB0";
- break;
- case 0xB8 :
- return "\xEA\xB1\x8C";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xA8";
- break;
- case 0xB0 :
- return "\xEA\xB2\x84";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\xA0";
- break;
- case 0xA8 :
- return "\xEA\xB2\xBC";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x98";
- break;
- case 0xA0 :
- return "\xEA\xB3\xB4";
- break;
- case 0xBC :
- return "\xEA\xB4\x90";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xAC";
- break;
- case 0xB4 :
- return "\xEA\xB5\x88";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xA4";
- break;
- case 0xAC :
- return "\xEA\xB6\x80";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x9C";
- break;
- case 0xA4 :
- return "\xEA\xB6\xB8";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x94";
- break;
- case 0x9C :
- return "\xEA\xB7\xB0";
- break;
- case 0xB8 :
- return "\xEA\xB8\x8C";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xA8";
- break;
- case 0xB0 :
- return "\xEA\xB9\x84";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\xA0";
- break;
- case 0xA8 :
- return "\xEA\xB9\xBC";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x98";
- break;
- case 0xA0 :
- return "\xEA\xBA\xB4";
- break;
- case 0xBC :
- return "\xEA\xBB\x90";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xAC";
- break;
- case 0xB4 :
- return "\xEA\xBC\x88";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xA4";
- break;
- case 0xAC :
- return "\xEA\xBD\x80";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x9C";
- break;
- case 0xA4 :
- return "\xEA\xBD\xB8";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x94";
- break;
- case 0x9C :
- return "\xEA\xBE\xB0";
- break;
- case 0xB8 :
- return "\xEA\xBF\x8C";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xA8";
- break;
- case 0xB0 :
- return "\xEB\x80\x84";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\xA0";
- break;
- case 0xA8 :
- return "\xEB\x80\xBC";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x98";
- break;
- case 0xA0 :
- return "\xEB\x81\xB4";
- break;
- case 0xBC :
- return "\xEB\x82\x90";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xAC";
- break;
- case 0xB4 :
- return "\xEB\x83\x88";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xA4";
- break;
- case 0xAC :
- return "\xEB\x84\x80";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x9C";
- break;
- case 0xA4 :
- return "\xEB\x84\xB8";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x94";
- break;
- case 0x9C :
- return "\xEB\x85\xB0";
- break;
- case 0xB8 :
- return "\xEB\x86\x8C";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xA8";
- break;
- case 0xB0 :
- return "\xEB\x87\x84";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\xA0";
- break;
- case 0xA8 :
- return "\xEB\x87\xBC";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x98";
- break;
- case 0xA0 :
- return "\xEB\x88\xB4";
- break;
- case 0xBC :
- return "\xEB\x89\x90";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xAC";
- break;
- case 0xB4 :
- return "\xEB\x8A\x88";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xA4";
- break;
- case 0xAC :
- return "\xEB\x8B\x80";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x9C";
- break;
- case 0xA4 :
- return "\xEB\x8B\xB8";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x94";
- break;
- case 0x9C :
- return "\xEB\x8C\xB0";
- break;
- case 0xB8 :
- return "\xEB\x8D\x8C";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xA8";
- break;
- case 0xB0 :
- return "\xEB\x8E\x84";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\xA0";
- break;
- case 0xA8 :
- return "\xEB\x8E\xBC";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x98";
- break;
- case 0xA0 :
- return "\xEB\x8F\xB4";
- break;
- case 0xBC :
- return "\xEB\x90\x90";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xAC";
- break;
- case 0xB4 :
- return "\xEB\x91\x88";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xA4";
- break;
- case 0xAC :
- return "\xEB\x92\x80";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x9C";
- break;
- case 0xA4 :
- return "\xEB\x92\xB8";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x94";
- break;
- case 0x9C :
- return "\xEB\x93\xB0";
- break;
- case 0xB8 :
- return "\xEB\x94\x8C";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xA8";
- break;
- case 0xB0 :
- return "\xEB\x95\x84";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\xA0";
- break;
- case 0xA8 :
- return "\xEB\x95\xBC";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x98";
- break;
- case 0xA0 :
- return "\xEB\x96\xB4";
- break;
- case 0xBC :
- return "\xEB\x97\x90";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xAC";
- break;
- case 0xB4 :
- return "\xEB\x98\x88";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xA4";
- break;
- case 0xAC :
- return "\xEB\x99\x80";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x9C";
- break;
- case 0xA4 :
- return "\xEB\x99\xB8";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x94";
- break;
- case 0x9C :
- return "\xEB\x9A\xB0";
- break;
- case 0xB8 :
- return "\xEB\x9B\x8C";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xA8";
- break;
- case 0xB0 :
- return "\xEB\x9C\x84";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\xA0";
- break;
- case 0xA8 :
- return "\xEB\x9C\xBC";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x98";
- break;
- case 0xA0 :
- return "\xEB\x9D\xB4";
- break;
- case 0xBC :
- return "\xEB\x9E\x90";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xAC";
- break;
- case 0xB4 :
- return "\xEB\x9F\x88";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xA4";
- break;
- case 0xAC :
- return "\xEB\xA0\x80";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x9C";
- break;
- case 0xA4 :
- return "\xEB\xA0\xB8";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x94";
- break;
- case 0x9C :
- return "\xEB\xA1\xB0";
- break;
- case 0xB8 :
- return "\xEB\xA2\x8C";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xA8";
- break;
- case 0xB0 :
- return "\xEB\xA3\x84";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\xA0";
- break;
- case 0xA8 :
- return "\xEB\xA3\xBC";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x98";
- break;
- case 0xA0 :
- return "\xEB\xA4\xB4";
- break;
- case 0xBC :
- return "\xEB\xA5\x90";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xAC";
- break;
- case 0xB4 :
- return "\xEB\xA6\x88";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xA4";
- break;
- case 0xAC :
- return "\xEB\xA7\x80";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x9C";
- break;
- case 0xA4 :
- return "\xEB\xA7\xB8";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x94";
- break;
- case 0x9C :
- return "\xEB\xA8\xB0";
- break;
- case 0xB8 :
- return "\xEB\xA9\x8C";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xA8";
- break;
- case 0xB0 :
- return "\xEB\xAA\x84";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\xA0";
- break;
- case 0xA8 :
- return "\xEB\xAA\xBC";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x98";
- break;
- case 0xA0 :
- return "\xEB\xAB\xB4";
- break;
- case 0xBC :
- return "\xEB\xAC\x90";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xAC";
- break;
- case 0xB4 :
- return "\xEB\xAD\x88";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xA4";
- break;
- case 0xAC :
- return "\xEB\xAE\x80";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x9C";
- break;
- case 0xA4 :
- return "\xEB\xAE\xB8";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x94";
- break;
- case 0x9C :
- return "\xEB\xAF\xB0";
- break;
- case 0xB8 :
- return "\xEB\xB0\x8C";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xA8";
- break;
- case 0xB0 :
- return "\xEB\xB1\x84";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\xA0";
- break;
- case 0xA8 :
- return "\xEB\xB1\xBC";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x98";
- break;
- case 0xA0 :
- return "\xEB\xB2\xB4";
- break;
- case 0xBC :
- return "\xEB\xB3\x90";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xAC";
- break;
- case 0xB4 :
- return "\xEB\xB4\x88";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xA4";
- break;
- case 0xAC :
- return "\xEB\xB5\x80";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x9C";
- break;
- case 0xA4 :
- return "\xEB\xB5\xB8";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x94";
- break;
- case 0x9C :
- return "\xEB\xB6\xB0";
- break;
- case 0xB8 :
- return "\xEB\xB7\x8C";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xA8";
- break;
- case 0xB0 :
- return "\xEB\xB8\x84";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\xA0";
- break;
- case 0xA8 :
- return "\xEB\xB8\xBC";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x98";
- break;
- case 0xA0 :
- return "\xEB\xB9\xB4";
- break;
- case 0xBC :
- return "\xEB\xBA\x90";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xAC";
- break;
- case 0xB4 :
- return "\xEB\xBB\x88";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xA4";
- break;
- case 0xAC :
- return "\xEB\xBC\x80";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x9C";
- break;
- case 0xA4 :
- return "\xEB\xBC\xB8";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x94";
- break;
- case 0x9C :
- return "\xEB\xBD\xB0";
- break;
- case 0xB8 :
- return "\xEB\xBE\x8C";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xA8";
- break;
- case 0xB0 :
- return "\xEB\xBF\x84";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\xA0";
- break;
- case 0xA8 :
- return "\xEB\xBF\xBC";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x98";
- break;
- case 0xA0 :
- return "\xEC\x80\xB4";
- break;
- case 0xBC :
- return "\xEC\x81\x90";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xAC";
- break;
- case 0xB4 :
- return "\xEC\x82\x88";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xA4";
- break;
- case 0xAC :
- return "\xEC\x83\x80";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x9C";
- break;
- case 0xA4 :
- return "\xEC\x83\xB8";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x94";
- break;
- case 0x9C :
- return "\xEC\x84\xB0";
- break;
- case 0xB8 :
- return "\xEC\x85\x8C";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xA8";
- break;
- case 0xB0 :
- return "\xEC\x86\x84";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\xA0";
- break;
- case 0xA8 :
- return "\xEC\x86\xBC";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x98";
- break;
- case 0xA0 :
- return "\xEC\x87\xB4";
- break;
- case 0xBC :
- return "\xEC\x88\x90";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xAC";
- break;
- case 0xB4 :
- return "\xEC\x89\x88";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xA4";
- break;
- case 0xAC :
- return "\xEC\x8A\x80";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x9C";
- break;
- case 0xA4 :
- return "\xEC\x8A\xB8";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x94";
- break;
- case 0x9C :
- return "\xEC\x8B\xB0";
- break;
- case 0xB8 :
- return "\xEC\x8C\x8C";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xA8";
- break;
- case 0xB0 :
- return "\xEC\x8D\x84";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\xA0";
- break;
- case 0xA8 :
- return "\xEC\x8D\xBC";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x98";
- break;
- case 0xA0 :
- return "\xEC\x8E\xB4";
- break;
- case 0xBC :
- return "\xEC\x8F\x90";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xAC";
- break;
- case 0xB4 :
- return "\xEC\x90\x88";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xA4";
- break;
- case 0xAC :
- return "\xEC\x91\x80";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x9C";
- break;
- case 0xA4 :
- return "\xEC\x91\xB8";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x94";
- break;
- case 0x9C :
- return "\xEC\x92\xB0";
- break;
- case 0xB8 :
- return "\xEC\x93\x8C";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xA8";
- break;
- case 0xB0 :
- return "\xEC\x94\x84";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\xA0";
- break;
- case 0xA8 :
- return "\xEC\x94\xBC";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x98";
- break;
- case 0xA0 :
- return "\xEC\x95\xB4";
- break;
- case 0xBC :
- return "\xEC\x96\x90";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xAC";
- break;
- case 0xB4 :
- return "\xEC\x97\x88";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xA4";
- break;
- case 0xAC :
- return "\xEC\x98\x80";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x9C";
- break;
- case 0xA4 :
- return "\xEC\x98\xB8";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x94";
- break;
- case 0x9C :
- return "\xEC\x99\xB0";
- break;
- case 0xB8 :
- return "\xEC\x9A\x8C";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xA8";
- break;
- case 0xB0 :
- return "\xEC\x9B\x84";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\xA0";
- break;
- case 0xA8 :
- return "\xEC\x9B\xBC";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x98";
- break;
- case 0xA0 :
- return "\xEC\x9C\xB4";
- break;
- case 0xBC :
- return "\xEC\x9D\x90";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xAC";
- break;
- case 0xB4 :
- return "\xEC\x9E\x88";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xA4";
- break;
- case 0xAC :
- return "\xEC\x9F\x80";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x9C";
- break;
- case 0xA4 :
- return "\xEC\x9F\xB8";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x94";
- break;
- case 0x9C :
- return "\xEC\xA0\xB0";
- break;
- case 0xB8 :
- return "\xEC\xA1\x8C";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xA8";
- break;
- case 0xB0 :
- return "\xEC\xA2\x84";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\xA0";
- break;
- case 0xA8 :
- return "\xEC\xA2\xBC";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x98";
- break;
- case 0xA0 :
- return "\xEC\xA3\xB4";
- break;
- case 0xBC :
- return "\xEC\xA4\x90";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xAC";
- break;
- case 0xB4 :
- return "\xEC\xA5\x88";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xA4";
- break;
- case 0xAC :
- return "\xEC\xA6\x80";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x9C";
- break;
- case 0xA4 :
- return "\xEC\xA6\xB8";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x94";
- break;
- case 0x9C :
- return "\xEC\xA7\xB0";
- break;
- case 0xB8 :
- return "\xEC\xA8\x8C";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xA8";
- break;
- case 0xB0 :
- return "\xEC\xA9\x84";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\xA0";
- break;
- case 0xA8 :
- return "\xEC\xA9\xBC";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x98";
- break;
- case 0xA0 :
- return "\xEC\xAA\xB4";
- break;
- case 0xBC :
- return "\xEC\xAB\x90";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xAC";
- break;
- case 0xB4 :
- return "\xEC\xAC\x88";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xA4";
- break;
- case 0xAC :
- return "\xEC\xAD\x80";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x9C";
- break;
- case 0xA4 :
- return "\xEC\xAD\xB8";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x94";
- break;
- case 0x9C :
- return "\xEC\xAE\xB0";
- break;
- case 0xB8 :
- return "\xEC\xAF\x8C";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xA8";
- break;
- case 0xB0 :
- return "\xEC\xB0\x84";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\xA0";
- break;
- case 0xA8 :
- return "\xEC\xB0\xBC";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x98";
- break;
- case 0xA0 :
- return "\xEC\xB1\xB4";
- break;
- case 0xBC :
- return "\xEC\xB2\x90";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xAC";
- break;
- case 0xB4 :
- return "\xEC\xB3\x88";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xA4";
- break;
- case 0xAC :
- return "\xEC\xB4\x80";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x9C";
- break;
- case 0xA4 :
- return "\xEC\xB4\xB8";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x94";
- break;
- case 0x9C :
- return "\xEC\xB5\xB0";
- break;
- case 0xB8 :
- return "\xEC\xB6\x8C";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xA8";
- break;
- case 0xB0 :
- return "\xEC\xB7\x84";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\xA0";
- break;
- case 0xA8 :
- return "\xEC\xB7\xBC";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x98";
- break;
- case 0xA0 :
- return "\xEC\xB8\xB4";
- break;
- case 0xBC :
- return "\xEC\xB9\x90";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xAC";
- break;
- case 0xB4 :
- return "\xEC\xBA\x88";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xA4";
- break;
- case 0xAC :
- return "\xEC\xBB\x80";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x9C";
- break;
- case 0xA4 :
- return "\xEC\xBB\xB8";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x94";
- break;
- case 0x9C :
- return "\xEC\xBC\xB0";
- break;
- case 0xB8 :
- return "\xEC\xBD\x8C";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xA8";
- break;
- case 0xB0 :
- return "\xEC\xBE\x84";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\xA0";
- break;
- case 0xA8 :
- return "\xEC\xBE\xBC";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x98";
- break;
- case 0xA0 :
- return "\xEC\xBF\xB4";
- break;
- case 0xBC :
- return "\xED\x80\x90";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xAC";
- break;
- case 0xB4 :
- return "\xED\x81\x88";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xA4";
- break;
- case 0xAC :
- return "\xED\x82\x80";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x9C";
- break;
- case 0xA4 :
- return "\xED\x82\xB8";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x94";
- break;
- case 0x9C :
- return "\xED\x83\xB0";
- break;
- case 0xB8 :
- return "\xED\x84\x8C";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xA8";
- break;
- case 0xB0 :
- return "\xED\x85\x84";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\xA0";
- break;
- case 0xA8 :
- return "\xED\x85\xBC";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x98";
- break;
- case 0xA0 :
- return "\xED\x86\xB4";
- break;
- case 0xBC :
- return "\xED\x87\x90";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xAC";
- break;
- case 0xB4 :
- return "\xED\x88\x88";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xA4";
- break;
- case 0xAC :
- return "\xED\x89\x80";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x9C";
- break;
- case 0xA4 :
- return "\xED\x89\xB8";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x94";
- break;
- case 0x9C :
- return "\xED\x8A\xB0";
- break;
- case 0xB8 :
- return "\xED\x8B\x8C";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xA8";
- break;
- case 0xB0 :
- return "\xED\x8C\x84";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\xA0";
- break;
- case 0xA8 :
- return "\xED\x8C\xBC";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x98";
- break;
- case 0xA0 :
- return "\xED\x8D\xB4";
- break;
- case 0xBC :
- return "\xED\x8E\x90";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xAC";
- break;
- case 0xB4 :
- return "\xED\x8F\x88";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xA4";
- break;
- case 0xAC :
- return "\xED\x90\x80";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x9C";
- break;
- case 0xA4 :
- return "\xED\x90\xB8";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x94";
- break;
- case 0x9C :
- return "\xED\x91\xB0";
- break;
- case 0xB8 :
- return "\xED\x92\x8C";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xA8";
- break;
- case 0xB0 :
- return "\xED\x93\x84";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\xA0";
- break;
- case 0xA8 :
- return "\xED\x93\xBC";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x98";
- break;
- case 0xA0 :
- return "\xED\x94\xB4";
- break;
- case 0xBC :
- return "\xED\x95\x90";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xAC";
- break;
- case 0xB4 :
- return "\xED\x96\x88";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xA4";
- break;
- case 0xAC :
- return "\xED\x97\x80";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x9C";
- break;
- case 0xA4 :
- return "\xED\x97\xB8";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x94";
- break;
- case 0x9C :
- return "\xED\x98\xB0";
- break;
- case 0xB8 :
- return "\xED\x99\x8C";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xA8";
- break;
- case 0xB0 :
- return "\xED\x9A\x84";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\xA0";
- break;
- case 0xA8 :
- return "\xED\x9A\xBC";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x98";
- break;
- case 0xA0 :
- return "\xED\x9B\xB4";
- break;
- case 0xBC :
- return "\xED\x9C\x90";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xAC";
- break;
- case 0xB4 :
- return "\xED\x9D\x88";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xA4";
- break;
- case 0xAC :
- return "\xED\x9E\x80";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x9C";
- }
- break;
- }
- break;
- }
- break;
- case 0xBC :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x95";
- break;
- case 0x9C :
- return "\xEA\xB0\xB1";
- break;
- case 0xB8 :
- return "\xEA\xB1\x8D";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xA9";
- break;
- case 0xB0 :
- return "\xEA\xB2\x85";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\xA1";
- break;
- case 0xA8 :
- return "\xEA\xB2\xBD";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x99";
- break;
- case 0xA0 :
- return "\xEA\xB3\xB5";
- break;
- case 0xBC :
- return "\xEA\xB4\x91";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xAD";
- break;
- case 0xB4 :
- return "\xEA\xB5\x89";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xA5";
- break;
- case 0xAC :
- return "\xEA\xB6\x81";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x9D";
- break;
- case 0xA4 :
- return "\xEA\xB6\xB9";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x95";
- break;
- case 0x9C :
- return "\xEA\xB7\xB1";
- break;
- case 0xB8 :
- return "\xEA\xB8\x8D";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xA9";
- break;
- case 0xB0 :
- return "\xEA\xB9\x85";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\xA1";
- break;
- case 0xA8 :
- return "\xEA\xB9\xBD";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x99";
- break;
- case 0xA0 :
- return "\xEA\xBA\xB5";
- break;
- case 0xBC :
- return "\xEA\xBB\x91";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xAD";
- break;
- case 0xB4 :
- return "\xEA\xBC\x89";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xA5";
- break;
- case 0xAC :
- return "\xEA\xBD\x81";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x9D";
- break;
- case 0xA4 :
- return "\xEA\xBD\xB9";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x95";
- break;
- case 0x9C :
- return "\xEA\xBE\xB1";
- break;
- case 0xB8 :
- return "\xEA\xBF\x8D";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xA9";
- break;
- case 0xB0 :
- return "\xEB\x80\x85";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\xA1";
- break;
- case 0xA8 :
- return "\xEB\x80\xBD";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x99";
- break;
- case 0xA0 :
- return "\xEB\x81\xB5";
- break;
- case 0xBC :
- return "\xEB\x82\x91";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xAD";
- break;
- case 0xB4 :
- return "\xEB\x83\x89";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xA5";
- break;
- case 0xAC :
- return "\xEB\x84\x81";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x9D";
- break;
- case 0xA4 :
- return "\xEB\x84\xB9";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x95";
- break;
- case 0x9C :
- return "\xEB\x85\xB1";
- break;
- case 0xB8 :
- return "\xEB\x86\x8D";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xA9";
- break;
- case 0xB0 :
- return "\xEB\x87\x85";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\xA1";
- break;
- case 0xA8 :
- return "\xEB\x87\xBD";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x99";
- break;
- case 0xA0 :
- return "\xEB\x88\xB5";
- break;
- case 0xBC :
- return "\xEB\x89\x91";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xAD";
- break;
- case 0xB4 :
- return "\xEB\x8A\x89";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xA5";
- break;
- case 0xAC :
- return "\xEB\x8B\x81";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x9D";
- break;
- case 0xA4 :
- return "\xEB\x8B\xB9";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x95";
- break;
- case 0x9C :
- return "\xEB\x8C\xB1";
- break;
- case 0xB8 :
- return "\xEB\x8D\x8D";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xA9";
- break;
- case 0xB0 :
- return "\xEB\x8E\x85";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\xA1";
- break;
- case 0xA8 :
- return "\xEB\x8E\xBD";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x99";
- break;
- case 0xA0 :
- return "\xEB\x8F\xB5";
- break;
- case 0xBC :
- return "\xEB\x90\x91";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xAD";
- break;
- case 0xB4 :
- return "\xEB\x91\x89";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xA5";
- break;
- case 0xAC :
- return "\xEB\x92\x81";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x9D";
- break;
- case 0xA4 :
- return "\xEB\x92\xB9";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x95";
- break;
- case 0x9C :
- return "\xEB\x93\xB1";
- break;
- case 0xB8 :
- return "\xEB\x94\x8D";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xA9";
- break;
- case 0xB0 :
- return "\xEB\x95\x85";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\xA1";
- break;
- case 0xA8 :
- return "\xEB\x95\xBD";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x99";
- break;
- case 0xA0 :
- return "\xEB\x96\xB5";
- break;
- case 0xBC :
- return "\xEB\x97\x91";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xAD";
- break;
- case 0xB4 :
- return "\xEB\x98\x89";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xA5";
- break;
- case 0xAC :
- return "\xEB\x99\x81";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x9D";
- break;
- case 0xA4 :
- return "\xEB\x99\xB9";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x95";
- break;
- case 0x9C :
- return "\xEB\x9A\xB1";
- break;
- case 0xB8 :
- return "\xEB\x9B\x8D";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xA9";
- break;
- case 0xB0 :
- return "\xEB\x9C\x85";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\xA1";
- break;
- case 0xA8 :
- return "\xEB\x9C\xBD";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x99";
- break;
- case 0xA0 :
- return "\xEB\x9D\xB5";
- break;
- case 0xBC :
- return "\xEB\x9E\x91";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xAD";
- break;
- case 0xB4 :
- return "\xEB\x9F\x89";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xA5";
- break;
- case 0xAC :
- return "\xEB\xA0\x81";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x9D";
- break;
- case 0xA4 :
- return "\xEB\xA0\xB9";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x95";
- break;
- case 0x9C :
- return "\xEB\xA1\xB1";
- break;
- case 0xB8 :
- return "\xEB\xA2\x8D";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xA9";
- break;
- case 0xB0 :
- return "\xEB\xA3\x85";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\xA1";
- break;
- case 0xA8 :
- return "\xEB\xA3\xBD";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x99";
- break;
- case 0xA0 :
- return "\xEB\xA4\xB5";
- break;
- case 0xBC :
- return "\xEB\xA5\x91";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xAD";
- break;
- case 0xB4 :
- return "\xEB\xA6\x89";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xA5";
- break;
- case 0xAC :
- return "\xEB\xA7\x81";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x9D";
- break;
- case 0xA4 :
- return "\xEB\xA7\xB9";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x95";
- break;
- case 0x9C :
- return "\xEB\xA8\xB1";
- break;
- case 0xB8 :
- return "\xEB\xA9\x8D";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xA9";
- break;
- case 0xB0 :
- return "\xEB\xAA\x85";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\xA1";
- break;
- case 0xA8 :
- return "\xEB\xAA\xBD";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x99";
- break;
- case 0xA0 :
- return "\xEB\xAB\xB5";
- break;
- case 0xBC :
- return "\xEB\xAC\x91";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xAD";
- break;
- case 0xB4 :
- return "\xEB\xAD\x89";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xA5";
- break;
- case 0xAC :
- return "\xEB\xAE\x81";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x9D";
- break;
- case 0xA4 :
- return "\xEB\xAE\xB9";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x95";
- break;
- case 0x9C :
- return "\xEB\xAF\xB1";
- break;
- case 0xB8 :
- return "\xEB\xB0\x8D";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xA9";
- break;
- case 0xB0 :
- return "\xEB\xB1\x85";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\xA1";
- break;
- case 0xA8 :
- return "\xEB\xB1\xBD";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x99";
- break;
- case 0xA0 :
- return "\xEB\xB2\xB5";
- break;
- case 0xBC :
- return "\xEB\xB3\x91";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xAD";
- break;
- case 0xB4 :
- return "\xEB\xB4\x89";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xA5";
- break;
- case 0xAC :
- return "\xEB\xB5\x81";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x9D";
- break;
- case 0xA4 :
- return "\xEB\xB5\xB9";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x95";
- break;
- case 0x9C :
- return "\xEB\xB6\xB1";
- break;
- case 0xB8 :
- return "\xEB\xB7\x8D";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xA9";
- break;
- case 0xB0 :
- return "\xEB\xB8\x85";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\xA1";
- break;
- case 0xA8 :
- return "\xEB\xB8\xBD";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x99";
- break;
- case 0xA0 :
- return "\xEB\xB9\xB5";
- break;
- case 0xBC :
- return "\xEB\xBA\x91";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xAD";
- break;
- case 0xB4 :
- return "\xEB\xBB\x89";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xA5";
- break;
- case 0xAC :
- return "\xEB\xBC\x81";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x9D";
- break;
- case 0xA4 :
- return "\xEB\xBC\xB9";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x95";
- break;
- case 0x9C :
- return "\xEB\xBD\xB1";
- break;
- case 0xB8 :
- return "\xEB\xBE\x8D";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xA9";
- break;
- case 0xB0 :
- return "\xEB\xBF\x85";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\xA1";
- break;
- case 0xA8 :
- return "\xEB\xBF\xBD";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x99";
- break;
- case 0xA0 :
- return "\xEC\x80\xB5";
- break;
- case 0xBC :
- return "\xEC\x81\x91";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xAD";
- break;
- case 0xB4 :
- return "\xEC\x82\x89";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xA5";
- break;
- case 0xAC :
- return "\xEC\x83\x81";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x9D";
- break;
- case 0xA4 :
- return "\xEC\x83\xB9";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x95";
- break;
- case 0x9C :
- return "\xEC\x84\xB1";
- break;
- case 0xB8 :
- return "\xEC\x85\x8D";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xA9";
- break;
- case 0xB0 :
- return "\xEC\x86\x85";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\xA1";
- break;
- case 0xA8 :
- return "\xEC\x86\xBD";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x99";
- break;
- case 0xA0 :
- return "\xEC\x87\xB5";
- break;
- case 0xBC :
- return "\xEC\x88\x91";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xAD";
- break;
- case 0xB4 :
- return "\xEC\x89\x89";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xA5";
- break;
- case 0xAC :
- return "\xEC\x8A\x81";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x9D";
- break;
- case 0xA4 :
- return "\xEC\x8A\xB9";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x95";
- break;
- case 0x9C :
- return "\xEC\x8B\xB1";
- break;
- case 0xB8 :
- return "\xEC\x8C\x8D";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xA9";
- break;
- case 0xB0 :
- return "\xEC\x8D\x85";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\xA1";
- break;
- case 0xA8 :
- return "\xEC\x8D\xBD";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x99";
- break;
- case 0xA0 :
- return "\xEC\x8E\xB5";
- break;
- case 0xBC :
- return "\xEC\x8F\x91";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xAD";
- break;
- case 0xB4 :
- return "\xEC\x90\x89";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xA5";
- break;
- case 0xAC :
- return "\xEC\x91\x81";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x9D";
- break;
- case 0xA4 :
- return "\xEC\x91\xB9";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x95";
- break;
- case 0x9C :
- return "\xEC\x92\xB1";
- break;
- case 0xB8 :
- return "\xEC\x93\x8D";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xA9";
- break;
- case 0xB0 :
- return "\xEC\x94\x85";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\xA1";
- break;
- case 0xA8 :
- return "\xEC\x94\xBD";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x99";
- break;
- case 0xA0 :
- return "\xEC\x95\xB5";
- break;
- case 0xBC :
- return "\xEC\x96\x91";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xAD";
- break;
- case 0xB4 :
- return "\xEC\x97\x89";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xA5";
- break;
- case 0xAC :
- return "\xEC\x98\x81";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x9D";
- break;
- case 0xA4 :
- return "\xEC\x98\xB9";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x95";
- break;
- case 0x9C :
- return "\xEC\x99\xB1";
- break;
- case 0xB8 :
- return "\xEC\x9A\x8D";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xA9";
- break;
- case 0xB0 :
- return "\xEC\x9B\x85";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\xA1";
- break;
- case 0xA8 :
- return "\xEC\x9B\xBD";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x99";
- break;
- case 0xA0 :
- return "\xEC\x9C\xB5";
- break;
- case 0xBC :
- return "\xEC\x9D\x91";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xAD";
- break;
- case 0xB4 :
- return "\xEC\x9E\x89";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xA5";
- break;
- case 0xAC :
- return "\xEC\x9F\x81";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x9D";
- break;
- case 0xA4 :
- return "\xEC\x9F\xB9";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x95";
- break;
- case 0x9C :
- return "\xEC\xA0\xB1";
- break;
- case 0xB8 :
- return "\xEC\xA1\x8D";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xA9";
- break;
- case 0xB0 :
- return "\xEC\xA2\x85";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\xA1";
- break;
- case 0xA8 :
- return "\xEC\xA2\xBD";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x99";
- break;
- case 0xA0 :
- return "\xEC\xA3\xB5";
- break;
- case 0xBC :
- return "\xEC\xA4\x91";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xAD";
- break;
- case 0xB4 :
- return "\xEC\xA5\x89";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xA5";
- break;
- case 0xAC :
- return "\xEC\xA6\x81";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x9D";
- break;
- case 0xA4 :
- return "\xEC\xA6\xB9";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x95";
- break;
- case 0x9C :
- return "\xEC\xA7\xB1";
- break;
- case 0xB8 :
- return "\xEC\xA8\x8D";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xA9";
- break;
- case 0xB0 :
- return "\xEC\xA9\x85";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\xA1";
- break;
- case 0xA8 :
- return "\xEC\xA9\xBD";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x99";
- break;
- case 0xA0 :
- return "\xEC\xAA\xB5";
- break;
- case 0xBC :
- return "\xEC\xAB\x91";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xAD";
- break;
- case 0xB4 :
- return "\xEC\xAC\x89";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xA5";
- break;
- case 0xAC :
- return "\xEC\xAD\x81";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x9D";
- break;
- case 0xA4 :
- return "\xEC\xAD\xB9";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x95";
- break;
- case 0x9C :
- return "\xEC\xAE\xB1";
- break;
- case 0xB8 :
- return "\xEC\xAF\x8D";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xA9";
- break;
- case 0xB0 :
- return "\xEC\xB0\x85";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\xA1";
- break;
- case 0xA8 :
- return "\xEC\xB0\xBD";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x99";
- break;
- case 0xA0 :
- return "\xEC\xB1\xB5";
- break;
- case 0xBC :
- return "\xEC\xB2\x91";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xAD";
- break;
- case 0xB4 :
- return "\xEC\xB3\x89";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xA5";
- break;
- case 0xAC :
- return "\xEC\xB4\x81";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x9D";
- break;
- case 0xA4 :
- return "\xEC\xB4\xB9";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x95";
- break;
- case 0x9C :
- return "\xEC\xB5\xB1";
- break;
- case 0xB8 :
- return "\xEC\xB6\x8D";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xA9";
- break;
- case 0xB0 :
- return "\xEC\xB7\x85";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\xA1";
- break;
- case 0xA8 :
- return "\xEC\xB7\xBD";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x99";
- break;
- case 0xA0 :
- return "\xEC\xB8\xB5";
- break;
- case 0xBC :
- return "\xEC\xB9\x91";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xAD";
- break;
- case 0xB4 :
- return "\xEC\xBA\x89";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xA5";
- break;
- case 0xAC :
- return "\xEC\xBB\x81";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x9D";
- break;
- case 0xA4 :
- return "\xEC\xBB\xB9";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x95";
- break;
- case 0x9C :
- return "\xEC\xBC\xB1";
- break;
- case 0xB8 :
- return "\xEC\xBD\x8D";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xA9";
- break;
- case 0xB0 :
- return "\xEC\xBE\x85";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\xA1";
- break;
- case 0xA8 :
- return "\xEC\xBE\xBD";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x99";
- break;
- case 0xA0 :
- return "\xEC\xBF\xB5";
- break;
- case 0xBC :
- return "\xED\x80\x91";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xAD";
- break;
- case 0xB4 :
- return "\xED\x81\x89";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xA5";
- break;
- case 0xAC :
- return "\xED\x82\x81";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x9D";
- break;
- case 0xA4 :
- return "\xED\x82\xB9";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x95";
- break;
- case 0x9C :
- return "\xED\x83\xB1";
- break;
- case 0xB8 :
- return "\xED\x84\x8D";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xA9";
- break;
- case 0xB0 :
- return "\xED\x85\x85";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\xA1";
- break;
- case 0xA8 :
- return "\xED\x85\xBD";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x99";
- break;
- case 0xA0 :
- return "\xED\x86\xB5";
- break;
- case 0xBC :
- return "\xED\x87\x91";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xAD";
- break;
- case 0xB4 :
- return "\xED\x88\x89";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xA5";
- break;
- case 0xAC :
- return "\xED\x89\x81";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x9D";
- break;
- case 0xA4 :
- return "\xED\x89\xB9";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x95";
- break;
- case 0x9C :
- return "\xED\x8A\xB1";
- break;
- case 0xB8 :
- return "\xED\x8B\x8D";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xA9";
- break;
- case 0xB0 :
- return "\xED\x8C\x85";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\xA1";
- break;
- case 0xA8 :
- return "\xED\x8C\xBD";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x99";
- break;
- case 0xA0 :
- return "\xED\x8D\xB5";
- break;
- case 0xBC :
- return "\xED\x8E\x91";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xAD";
- break;
- case 0xB4 :
- return "\xED\x8F\x89";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xA5";
- break;
- case 0xAC :
- return "\xED\x90\x81";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x9D";
- break;
- case 0xA4 :
- return "\xED\x90\xB9";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x95";
- break;
- case 0x9C :
- return "\xED\x91\xB1";
- break;
- case 0xB8 :
- return "\xED\x92\x8D";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xA9";
- break;
- case 0xB0 :
- return "\xED\x93\x85";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\xA1";
- break;
- case 0xA8 :
- return "\xED\x93\xBD";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x99";
- break;
- case 0xA0 :
- return "\xED\x94\xB5";
- break;
- case 0xBC :
- return "\xED\x95\x91";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xAD";
- break;
- case 0xB4 :
- return "\xED\x96\x89";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xA5";
- break;
- case 0xAC :
- return "\xED\x97\x81";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x9D";
- break;
- case 0xA4 :
- return "\xED\x97\xB9";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x95";
- break;
- case 0x9C :
- return "\xED\x98\xB1";
- break;
- case 0xB8 :
- return "\xED\x99\x8D";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xA9";
- break;
- case 0xB0 :
- return "\xED\x9A\x85";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\xA1";
- break;
- case 0xA8 :
- return "\xED\x9A\xBD";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x99";
- break;
- case 0xA0 :
- return "\xED\x9B\xB5";
- break;
- case 0xBC :
- return "\xED\x9C\x91";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xAD";
- break;
- case 0xB4 :
- return "\xED\x9D\x89";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xA5";
- break;
- case 0xAC :
- return "\xED\x9E\x81";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x9D";
- }
- break;
- }
- break;
- }
- break;
- case 0xBD :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x96";
- break;
- case 0x9C :
- return "\xEA\xB0\xB2";
- break;
- case 0xB8 :
- return "\xEA\xB1\x8E";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xAA";
- break;
- case 0xB0 :
- return "\xEA\xB2\x86";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\xA2";
- break;
- case 0xA8 :
- return "\xEA\xB2\xBE";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x9A";
- break;
- case 0xA0 :
- return "\xEA\xB3\xB6";
- break;
- case 0xBC :
- return "\xEA\xB4\x92";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xAE";
- break;
- case 0xB4 :
- return "\xEA\xB5\x8A";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xA6";
- break;
- case 0xAC :
- return "\xEA\xB6\x82";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x9E";
- break;
- case 0xA4 :
- return "\xEA\xB6\xBA";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x96";
- break;
- case 0x9C :
- return "\xEA\xB7\xB2";
- break;
- case 0xB8 :
- return "\xEA\xB8\x8E";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xAA";
- break;
- case 0xB0 :
- return "\xEA\xB9\x86";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\xA2";
- break;
- case 0xA8 :
- return "\xEA\xB9\xBE";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x9A";
- break;
- case 0xA0 :
- return "\xEA\xBA\xB6";
- break;
- case 0xBC :
- return "\xEA\xBB\x92";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xAE";
- break;
- case 0xB4 :
- return "\xEA\xBC\x8A";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xA6";
- break;
- case 0xAC :
- return "\xEA\xBD\x82";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x9E";
- break;
- case 0xA4 :
- return "\xEA\xBD\xBA";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x96";
- break;
- case 0x9C :
- return "\xEA\xBE\xB2";
- break;
- case 0xB8 :
- return "\xEA\xBF\x8E";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xAA";
- break;
- case 0xB0 :
- return "\xEB\x80\x86";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\xA2";
- break;
- case 0xA8 :
- return "\xEB\x80\xBE";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x9A";
- break;
- case 0xA0 :
- return "\xEB\x81\xB6";
- break;
- case 0xBC :
- return "\xEB\x82\x92";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xAE";
- break;
- case 0xB4 :
- return "\xEB\x83\x8A";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xA6";
- break;
- case 0xAC :
- return "\xEB\x84\x82";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x9E";
- break;
- case 0xA4 :
- return "\xEB\x84\xBA";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x96";
- break;
- case 0x9C :
- return "\xEB\x85\xB2";
- break;
- case 0xB8 :
- return "\xEB\x86\x8E";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xAA";
- break;
- case 0xB0 :
- return "\xEB\x87\x86";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\xA2";
- break;
- case 0xA8 :
- return "\xEB\x87\xBE";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x9A";
- break;
- case 0xA0 :
- return "\xEB\x88\xB6";
- break;
- case 0xBC :
- return "\xEB\x89\x92";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xAE";
- break;
- case 0xB4 :
- return "\xEB\x8A\x8A";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xA6";
- break;
- case 0xAC :
- return "\xEB\x8B\x82";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x9E";
- break;
- case 0xA4 :
- return "\xEB\x8B\xBA";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x96";
- break;
- case 0x9C :
- return "\xEB\x8C\xB2";
- break;
- case 0xB8 :
- return "\xEB\x8D\x8E";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xAA";
- break;
- case 0xB0 :
- return "\xEB\x8E\x86";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\xA2";
- break;
- case 0xA8 :
- return "\xEB\x8E\xBE";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x9A";
- break;
- case 0xA0 :
- return "\xEB\x8F\xB6";
- break;
- case 0xBC :
- return "\xEB\x90\x92";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xAE";
- break;
- case 0xB4 :
- return "\xEB\x91\x8A";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xA6";
- break;
- case 0xAC :
- return "\xEB\x92\x82";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x9E";
- break;
- case 0xA4 :
- return "\xEB\x92\xBA";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x96";
- break;
- case 0x9C :
- return "\xEB\x93\xB2";
- break;
- case 0xB8 :
- return "\xEB\x94\x8E";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xAA";
- break;
- case 0xB0 :
- return "\xEB\x95\x86";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\xA2";
- break;
- case 0xA8 :
- return "\xEB\x95\xBE";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x9A";
- break;
- case 0xA0 :
- return "\xEB\x96\xB6";
- break;
- case 0xBC :
- return "\xEB\x97\x92";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xAE";
- break;
- case 0xB4 :
- return "\xEB\x98\x8A";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xA6";
- break;
- case 0xAC :
- return "\xEB\x99\x82";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x9E";
- break;
- case 0xA4 :
- return "\xEB\x99\xBA";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x96";
- break;
- case 0x9C :
- return "\xEB\x9A\xB2";
- break;
- case 0xB8 :
- return "\xEB\x9B\x8E";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xAA";
- break;
- case 0xB0 :
- return "\xEB\x9C\x86";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\xA2";
- break;
- case 0xA8 :
- return "\xEB\x9C\xBE";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x9A";
- break;
- case 0xA0 :
- return "\xEB\x9D\xB6";
- break;
- case 0xBC :
- return "\xEB\x9E\x92";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xAE";
- break;
- case 0xB4 :
- return "\xEB\x9F\x8A";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xA6";
- break;
- case 0xAC :
- return "\xEB\xA0\x82";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x9E";
- break;
- case 0xA4 :
- return "\xEB\xA0\xBA";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x96";
- break;
- case 0x9C :
- return "\xEB\xA1\xB2";
- break;
- case 0xB8 :
- return "\xEB\xA2\x8E";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xAA";
- break;
- case 0xB0 :
- return "\xEB\xA3\x86";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\xA2";
- break;
- case 0xA8 :
- return "\xEB\xA3\xBE";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x9A";
- break;
- case 0xA0 :
- return "\xEB\xA4\xB6";
- break;
- case 0xBC :
- return "\xEB\xA5\x92";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xAE";
- break;
- case 0xB4 :
- return "\xEB\xA6\x8A";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xA6";
- break;
- case 0xAC :
- return "\xEB\xA7\x82";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x9E";
- break;
- case 0xA4 :
- return "\xEB\xA7\xBA";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x96";
- break;
- case 0x9C :
- return "\xEB\xA8\xB2";
- break;
- case 0xB8 :
- return "\xEB\xA9\x8E";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xAA";
- break;
- case 0xB0 :
- return "\xEB\xAA\x86";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\xA2";
- break;
- case 0xA8 :
- return "\xEB\xAA\xBE";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x9A";
- break;
- case 0xA0 :
- return "\xEB\xAB\xB6";
- break;
- case 0xBC :
- return "\xEB\xAC\x92";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xAE";
- break;
- case 0xB4 :
- return "\xEB\xAD\x8A";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xA6";
- break;
- case 0xAC :
- return "\xEB\xAE\x82";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x9E";
- break;
- case 0xA4 :
- return "\xEB\xAE\xBA";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x96";
- break;
- case 0x9C :
- return "\xEB\xAF\xB2";
- break;
- case 0xB8 :
- return "\xEB\xB0\x8E";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xAA";
- break;
- case 0xB0 :
- return "\xEB\xB1\x86";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\xA2";
- break;
- case 0xA8 :
- return "\xEB\xB1\xBE";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x9A";
- break;
- case 0xA0 :
- return "\xEB\xB2\xB6";
- break;
- case 0xBC :
- return "\xEB\xB3\x92";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xAE";
- break;
- case 0xB4 :
- return "\xEB\xB4\x8A";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xA6";
- break;
- case 0xAC :
- return "\xEB\xB5\x82";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x9E";
- break;
- case 0xA4 :
- return "\xEB\xB5\xBA";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x96";
- break;
- case 0x9C :
- return "\xEB\xB6\xB2";
- break;
- case 0xB8 :
- return "\xEB\xB7\x8E";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xAA";
- break;
- case 0xB0 :
- return "\xEB\xB8\x86";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\xA2";
- break;
- case 0xA8 :
- return "\xEB\xB8\xBE";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x9A";
- break;
- case 0xA0 :
- return "\xEB\xB9\xB6";
- break;
- case 0xBC :
- return "\xEB\xBA\x92";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xAE";
- break;
- case 0xB4 :
- return "\xEB\xBB\x8A";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xA6";
- break;
- case 0xAC :
- return "\xEB\xBC\x82";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x9E";
- break;
- case 0xA4 :
- return "\xEB\xBC\xBA";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x96";
- break;
- case 0x9C :
- return "\xEB\xBD\xB2";
- break;
- case 0xB8 :
- return "\xEB\xBE\x8E";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xAA";
- break;
- case 0xB0 :
- return "\xEB\xBF\x86";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\xA2";
- break;
- case 0xA8 :
- return "\xEB\xBF\xBE";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x9A";
- break;
- case 0xA0 :
- return "\xEC\x80\xB6";
- break;
- case 0xBC :
- return "\xEC\x81\x92";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xAE";
- break;
- case 0xB4 :
- return "\xEC\x82\x8A";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xA6";
- break;
- case 0xAC :
- return "\xEC\x83\x82";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x9E";
- break;
- case 0xA4 :
- return "\xEC\x83\xBA";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x96";
- break;
- case 0x9C :
- return "\xEC\x84\xB2";
- break;
- case 0xB8 :
- return "\xEC\x85\x8E";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xAA";
- break;
- case 0xB0 :
- return "\xEC\x86\x86";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\xA2";
- break;
- case 0xA8 :
- return "\xEC\x86\xBE";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x9A";
- break;
- case 0xA0 :
- return "\xEC\x87\xB6";
- break;
- case 0xBC :
- return "\xEC\x88\x92";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xAE";
- break;
- case 0xB4 :
- return "\xEC\x89\x8A";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xA6";
- break;
- case 0xAC :
- return "\xEC\x8A\x82";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x9E";
- break;
- case 0xA4 :
- return "\xEC\x8A\xBA";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x96";
- break;
- case 0x9C :
- return "\xEC\x8B\xB2";
- break;
- case 0xB8 :
- return "\xEC\x8C\x8E";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xAA";
- break;
- case 0xB0 :
- return "\xEC\x8D\x86";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\xA2";
- break;
- case 0xA8 :
- return "\xEC\x8D\xBE";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x9A";
- break;
- case 0xA0 :
- return "\xEC\x8E\xB6";
- break;
- case 0xBC :
- return "\xEC\x8F\x92";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xAE";
- break;
- case 0xB4 :
- return "\xEC\x90\x8A";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xA6";
- break;
- case 0xAC :
- return "\xEC\x91\x82";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x9E";
- break;
- case 0xA4 :
- return "\xEC\x91\xBA";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x96";
- break;
- case 0x9C :
- return "\xEC\x92\xB2";
- break;
- case 0xB8 :
- return "\xEC\x93\x8E";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xAA";
- break;
- case 0xB0 :
- return "\xEC\x94\x86";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\xA2";
- break;
- case 0xA8 :
- return "\xEC\x94\xBE";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x9A";
- break;
- case 0xA0 :
- return "\xEC\x95\xB6";
- break;
- case 0xBC :
- return "\xEC\x96\x92";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xAE";
- break;
- case 0xB4 :
- return "\xEC\x97\x8A";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xA6";
- break;
- case 0xAC :
- return "\xEC\x98\x82";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x9E";
- break;
- case 0xA4 :
- return "\xEC\x98\xBA";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x96";
- break;
- case 0x9C :
- return "\xEC\x99\xB2";
- break;
- case 0xB8 :
- return "\xEC\x9A\x8E";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xAA";
- break;
- case 0xB0 :
- return "\xEC\x9B\x86";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\xA2";
- break;
- case 0xA8 :
- return "\xEC\x9B\xBE";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x9A";
- break;
- case 0xA0 :
- return "\xEC\x9C\xB6";
- break;
- case 0xBC :
- return "\xEC\x9D\x92";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xAE";
- break;
- case 0xB4 :
- return "\xEC\x9E\x8A";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xA6";
- break;
- case 0xAC :
- return "\xEC\x9F\x82";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x9E";
- break;
- case 0xA4 :
- return "\xEC\x9F\xBA";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x96";
- break;
- case 0x9C :
- return "\xEC\xA0\xB2";
- break;
- case 0xB8 :
- return "\xEC\xA1\x8E";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xAA";
- break;
- case 0xB0 :
- return "\xEC\xA2\x86";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\xA2";
- break;
- case 0xA8 :
- return "\xEC\xA2\xBE";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x9A";
- break;
- case 0xA0 :
- return "\xEC\xA3\xB6";
- break;
- case 0xBC :
- return "\xEC\xA4\x92";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xAE";
- break;
- case 0xB4 :
- return "\xEC\xA5\x8A";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xA6";
- break;
- case 0xAC :
- return "\xEC\xA6\x82";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x9E";
- break;
- case 0xA4 :
- return "\xEC\xA6\xBA";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x96";
- break;
- case 0x9C :
- return "\xEC\xA7\xB2";
- break;
- case 0xB8 :
- return "\xEC\xA8\x8E";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xAA";
- break;
- case 0xB0 :
- return "\xEC\xA9\x86";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\xA2";
- break;
- case 0xA8 :
- return "\xEC\xA9\xBE";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x9A";
- break;
- case 0xA0 :
- return "\xEC\xAA\xB6";
- break;
- case 0xBC :
- return "\xEC\xAB\x92";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xAE";
- break;
- case 0xB4 :
- return "\xEC\xAC\x8A";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xA6";
- break;
- case 0xAC :
- return "\xEC\xAD\x82";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x9E";
- break;
- case 0xA4 :
- return "\xEC\xAD\xBA";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x96";
- break;
- case 0x9C :
- return "\xEC\xAE\xB2";
- break;
- case 0xB8 :
- return "\xEC\xAF\x8E";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xAA";
- break;
- case 0xB0 :
- return "\xEC\xB0\x86";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\xA2";
- break;
- case 0xA8 :
- return "\xEC\xB0\xBE";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x9A";
- break;
- case 0xA0 :
- return "\xEC\xB1\xB6";
- break;
- case 0xBC :
- return "\xEC\xB2\x92";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xAE";
- break;
- case 0xB4 :
- return "\xEC\xB3\x8A";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xA6";
- break;
- case 0xAC :
- return "\xEC\xB4\x82";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x9E";
- break;
- case 0xA4 :
- return "\xEC\xB4\xBA";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x96";
- break;
- case 0x9C :
- return "\xEC\xB5\xB2";
- break;
- case 0xB8 :
- return "\xEC\xB6\x8E";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xAA";
- break;
- case 0xB0 :
- return "\xEC\xB7\x86";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\xA2";
- break;
- case 0xA8 :
- return "\xEC\xB7\xBE";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x9A";
- break;
- case 0xA0 :
- return "\xEC\xB8\xB6";
- break;
- case 0xBC :
- return "\xEC\xB9\x92";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xAE";
- break;
- case 0xB4 :
- return "\xEC\xBA\x8A";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xA6";
- break;
- case 0xAC :
- return "\xEC\xBB\x82";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x9E";
- break;
- case 0xA4 :
- return "\xEC\xBB\xBA";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x96";
- break;
- case 0x9C :
- return "\xEC\xBC\xB2";
- break;
- case 0xB8 :
- return "\xEC\xBD\x8E";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xAA";
- break;
- case 0xB0 :
- return "\xEC\xBE\x86";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\xA2";
- break;
- case 0xA8 :
- return "\xEC\xBE\xBE";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x9A";
- break;
- case 0xA0 :
- return "\xEC\xBF\xB6";
- break;
- case 0xBC :
- return "\xED\x80\x92";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xAE";
- break;
- case 0xB4 :
- return "\xED\x81\x8A";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xA6";
- break;
- case 0xAC :
- return "\xED\x82\x82";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x9E";
- break;
- case 0xA4 :
- return "\xED\x82\xBA";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x96";
- break;
- case 0x9C :
- return "\xED\x83\xB2";
- break;
- case 0xB8 :
- return "\xED\x84\x8E";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xAA";
- break;
- case 0xB0 :
- return "\xED\x85\x86";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\xA2";
- break;
- case 0xA8 :
- return "\xED\x85\xBE";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x9A";
- break;
- case 0xA0 :
- return "\xED\x86\xB6";
- break;
- case 0xBC :
- return "\xED\x87\x92";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xAE";
- break;
- case 0xB4 :
- return "\xED\x88\x8A";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xA6";
- break;
- case 0xAC :
- return "\xED\x89\x82";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x9E";
- break;
- case 0xA4 :
- return "\xED\x89\xBA";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x96";
- break;
- case 0x9C :
- return "\xED\x8A\xB2";
- break;
- case 0xB8 :
- return "\xED\x8B\x8E";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xAA";
- break;
- case 0xB0 :
- return "\xED\x8C\x86";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\xA2";
- break;
- case 0xA8 :
- return "\xED\x8C\xBE";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x9A";
- break;
- case 0xA0 :
- return "\xED\x8D\xB6";
- break;
- case 0xBC :
- return "\xED\x8E\x92";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xAE";
- break;
- case 0xB4 :
- return "\xED\x8F\x8A";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xA6";
- break;
- case 0xAC :
- return "\xED\x90\x82";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x9E";
- break;
- case 0xA4 :
- return "\xED\x90\xBA";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x96";
- break;
- case 0x9C :
- return "\xED\x91\xB2";
- break;
- case 0xB8 :
- return "\xED\x92\x8E";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xAA";
- break;
- case 0xB0 :
- return "\xED\x93\x86";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\xA2";
- break;
- case 0xA8 :
- return "\xED\x93\xBE";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x9A";
- break;
- case 0xA0 :
- return "\xED\x94\xB6";
- break;
- case 0xBC :
- return "\xED\x95\x92";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xAE";
- break;
- case 0xB4 :
- return "\xED\x96\x8A";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xA6";
- break;
- case 0xAC :
- return "\xED\x97\x82";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x9E";
- break;
- case 0xA4 :
- return "\xED\x97\xBA";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x96";
- break;
- case 0x9C :
- return "\xED\x98\xB2";
- break;
- case 0xB8 :
- return "\xED\x99\x8E";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xAA";
- break;
- case 0xB0 :
- return "\xED\x9A\x86";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\xA2";
- break;
- case 0xA8 :
- return "\xED\x9A\xBE";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x9A";
- break;
- case 0xA0 :
- return "\xED\x9B\xB6";
- break;
- case 0xBC :
- return "\xED\x9C\x92";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xAE";
- break;
- case 0xB4 :
- return "\xED\x9D\x8A";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xA6";
- break;
- case 0xAC :
- return "\xED\x9E\x82";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x9E";
- }
- break;
- }
- break;
- }
- break;
- case 0xBE :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x97";
- break;
- case 0x9C :
- return "\xEA\xB0\xB3";
- break;
- case 0xB8 :
- return "\xEA\xB1\x8F";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xAB";
- break;
- case 0xB0 :
- return "\xEA\xB2\x87";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\xA3";
- break;
- case 0xA8 :
- return "\xEA\xB2\xBF";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x9B";
- break;
- case 0xA0 :
- return "\xEA\xB3\xB7";
- break;
- case 0xBC :
- return "\xEA\xB4\x93";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xAF";
- break;
- case 0xB4 :
- return "\xEA\xB5\x8B";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xA7";
- break;
- case 0xAC :
- return "\xEA\xB6\x83";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\x9F";
- break;
- case 0xA4 :
- return "\xEA\xB6\xBB";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x97";
- break;
- case 0x9C :
- return "\xEA\xB7\xB3";
- break;
- case 0xB8 :
- return "\xEA\xB8\x8F";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xAB";
- break;
- case 0xB0 :
- return "\xEA\xB9\x87";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\xA3";
- break;
- case 0xA8 :
- return "\xEA\xB9\xBF";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x9B";
- break;
- case 0xA0 :
- return "\xEA\xBA\xB7";
- break;
- case 0xBC :
- return "\xEA\xBB\x93";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xAF";
- break;
- case 0xB4 :
- return "\xEA\xBC\x8B";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xA7";
- break;
- case 0xAC :
- return "\xEA\xBD\x83";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\x9F";
- break;
- case 0xA4 :
- return "\xEA\xBD\xBB";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x97";
- break;
- case 0x9C :
- return "\xEA\xBE\xB3";
- break;
- case 0xB8 :
- return "\xEA\xBF\x8F";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xAB";
- break;
- case 0xB0 :
- return "\xEB\x80\x87";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\xA3";
- break;
- case 0xA8 :
- return "\xEB\x80\xBF";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x9B";
- break;
- case 0xA0 :
- return "\xEB\x81\xB7";
- break;
- case 0xBC :
- return "\xEB\x82\x93";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xAF";
- break;
- case 0xB4 :
- return "\xEB\x83\x8B";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xA7";
- break;
- case 0xAC :
- return "\xEB\x84\x83";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\x9F";
- break;
- case 0xA4 :
- return "\xEB\x84\xBB";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x97";
- break;
- case 0x9C :
- return "\xEB\x85\xB3";
- break;
- case 0xB8 :
- return "\xEB\x86\x8F";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xAB";
- break;
- case 0xB0 :
- return "\xEB\x87\x87";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\xA3";
- break;
- case 0xA8 :
- return "\xEB\x87\xBF";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x9B";
- break;
- case 0xA0 :
- return "\xEB\x88\xB7";
- break;
- case 0xBC :
- return "\xEB\x89\x93";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xAF";
- break;
- case 0xB4 :
- return "\xEB\x8A\x8B";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xA7";
- break;
- case 0xAC :
- return "\xEB\x8B\x83";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\x9F";
- break;
- case 0xA4 :
- return "\xEB\x8B\xBB";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x97";
- break;
- case 0x9C :
- return "\xEB\x8C\xB3";
- break;
- case 0xB8 :
- return "\xEB\x8D\x8F";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xAB";
- break;
- case 0xB0 :
- return "\xEB\x8E\x87";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\xA3";
- break;
- case 0xA8 :
- return "\xEB\x8E\xBF";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x9B";
- break;
- case 0xA0 :
- return "\xEB\x8F\xB7";
- break;
- case 0xBC :
- return "\xEB\x90\x93";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xAF";
- break;
- case 0xB4 :
- return "\xEB\x91\x8B";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xA7";
- break;
- case 0xAC :
- return "\xEB\x92\x83";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\x9F";
- break;
- case 0xA4 :
- return "\xEB\x92\xBB";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x97";
- break;
- case 0x9C :
- return "\xEB\x93\xB3";
- break;
- case 0xB8 :
- return "\xEB\x94\x8F";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xAB";
- break;
- case 0xB0 :
- return "\xEB\x95\x87";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\xA3";
- break;
- case 0xA8 :
- return "\xEB\x95\xBF";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x9B";
- break;
- case 0xA0 :
- return "\xEB\x96\xB7";
- break;
- case 0xBC :
- return "\xEB\x97\x93";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xAF";
- break;
- case 0xB4 :
- return "\xEB\x98\x8B";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xA7";
- break;
- case 0xAC :
- return "\xEB\x99\x83";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\x9F";
- break;
- case 0xA4 :
- return "\xEB\x99\xBB";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x97";
- break;
- case 0x9C :
- return "\xEB\x9A\xB3";
- break;
- case 0xB8 :
- return "\xEB\x9B\x8F";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xAB";
- break;
- case 0xB0 :
- return "\xEB\x9C\x87";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\xA3";
- break;
- case 0xA8 :
- return "\xEB\x9C\xBF";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x9B";
- break;
- case 0xA0 :
- return "\xEB\x9D\xB7";
- break;
- case 0xBC :
- return "\xEB\x9E\x93";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xAF";
- break;
- case 0xB4 :
- return "\xEB\x9F\x8B";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xA7";
- break;
- case 0xAC :
- return "\xEB\xA0\x83";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\x9F";
- break;
- case 0xA4 :
- return "\xEB\xA0\xBB";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x97";
- break;
- case 0x9C :
- return "\xEB\xA1\xB3";
- break;
- case 0xB8 :
- return "\xEB\xA2\x8F";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xAB";
- break;
- case 0xB0 :
- return "\xEB\xA3\x87";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\xA3";
- break;
- case 0xA8 :
- return "\xEB\xA3\xBF";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x9B";
- break;
- case 0xA0 :
- return "\xEB\xA4\xB7";
- break;
- case 0xBC :
- return "\xEB\xA5\x93";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xAF";
- break;
- case 0xB4 :
- return "\xEB\xA6\x8B";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xA7";
- break;
- case 0xAC :
- return "\xEB\xA7\x83";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\x9F";
- break;
- case 0xA4 :
- return "\xEB\xA7\xBB";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x97";
- break;
- case 0x9C :
- return "\xEB\xA8\xB3";
- break;
- case 0xB8 :
- return "\xEB\xA9\x8F";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xAB";
- break;
- case 0xB0 :
- return "\xEB\xAA\x87";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\xA3";
- break;
- case 0xA8 :
- return "\xEB\xAA\xBF";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x9B";
- break;
- case 0xA0 :
- return "\xEB\xAB\xB7";
- break;
- case 0xBC :
- return "\xEB\xAC\x93";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xAF";
- break;
- case 0xB4 :
- return "\xEB\xAD\x8B";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xA7";
- break;
- case 0xAC :
- return "\xEB\xAE\x83";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\x9F";
- break;
- case 0xA4 :
- return "\xEB\xAE\xBB";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x97";
- break;
- case 0x9C :
- return "\xEB\xAF\xB3";
- break;
- case 0xB8 :
- return "\xEB\xB0\x8F";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xAB";
- break;
- case 0xB0 :
- return "\xEB\xB1\x87";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\xA3";
- break;
- case 0xA8 :
- return "\xEB\xB1\xBF";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x9B";
- break;
- case 0xA0 :
- return "\xEB\xB2\xB7";
- break;
- case 0xBC :
- return "\xEB\xB3\x93";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xAF";
- break;
- case 0xB4 :
- return "\xEB\xB4\x8B";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xA7";
- break;
- case 0xAC :
- return "\xEB\xB5\x83";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\x9F";
- break;
- case 0xA4 :
- return "\xEB\xB5\xBB";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x97";
- break;
- case 0x9C :
- return "\xEB\xB6\xB3";
- break;
- case 0xB8 :
- return "\xEB\xB7\x8F";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xAB";
- break;
- case 0xB0 :
- return "\xEB\xB8\x87";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\xA3";
- break;
- case 0xA8 :
- return "\xEB\xB8\xBF";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x9B";
- break;
- case 0xA0 :
- return "\xEB\xB9\xB7";
- break;
- case 0xBC :
- return "\xEB\xBA\x93";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xAF";
- break;
- case 0xB4 :
- return "\xEB\xBB\x8B";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xA7";
- break;
- case 0xAC :
- return "\xEB\xBC\x83";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\x9F";
- break;
- case 0xA4 :
- return "\xEB\xBC\xBB";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x97";
- break;
- case 0x9C :
- return "\xEB\xBD\xB3";
- break;
- case 0xB8 :
- return "\xEB\xBE\x8F";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xAB";
- break;
- case 0xB0 :
- return "\xEB\xBF\x87";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\xA3";
- break;
- case 0xA8 :
- return "\xEB\xBF\xBF";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x9B";
- break;
- case 0xA0 :
- return "\xEC\x80\xB7";
- break;
- case 0xBC :
- return "\xEC\x81\x93";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xAF";
- break;
- case 0xB4 :
- return "\xEC\x82\x8B";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xA7";
- break;
- case 0xAC :
- return "\xEC\x83\x83";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\x9F";
- break;
- case 0xA4 :
- return "\xEC\x83\xBB";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x97";
- break;
- case 0x9C :
- return "\xEC\x84\xB3";
- break;
- case 0xB8 :
- return "\xEC\x85\x8F";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xAB";
- break;
- case 0xB0 :
- return "\xEC\x86\x87";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\xA3";
- break;
- case 0xA8 :
- return "\xEC\x86\xBF";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x9B";
- break;
- case 0xA0 :
- return "\xEC\x87\xB7";
- break;
- case 0xBC :
- return "\xEC\x88\x93";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xAF";
- break;
- case 0xB4 :
- return "\xEC\x89\x8B";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xA7";
- break;
- case 0xAC :
- return "\xEC\x8A\x83";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\x9F";
- break;
- case 0xA4 :
- return "\xEC\x8A\xBB";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x97";
- break;
- case 0x9C :
- return "\xEC\x8B\xB3";
- break;
- case 0xB8 :
- return "\xEC\x8C\x8F";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xAB";
- break;
- case 0xB0 :
- return "\xEC\x8D\x87";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\xA3";
- break;
- case 0xA8 :
- return "\xEC\x8D\xBF";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x9B";
- break;
- case 0xA0 :
- return "\xEC\x8E\xB7";
- break;
- case 0xBC :
- return "\xEC\x8F\x93";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xAF";
- break;
- case 0xB4 :
- return "\xEC\x90\x8B";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xA7";
- break;
- case 0xAC :
- return "\xEC\x91\x83";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\x9F";
- break;
- case 0xA4 :
- return "\xEC\x91\xBB";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x97";
- break;
- case 0x9C :
- return "\xEC\x92\xB3";
- break;
- case 0xB8 :
- return "\xEC\x93\x8F";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xAB";
- break;
- case 0xB0 :
- return "\xEC\x94\x87";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\xA3";
- break;
- case 0xA8 :
- return "\xEC\x94\xBF";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x9B";
- break;
- case 0xA0 :
- return "\xEC\x95\xB7";
- break;
- case 0xBC :
- return "\xEC\x96\x93";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xAF";
- break;
- case 0xB4 :
- return "\xEC\x97\x8B";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xA7";
- break;
- case 0xAC :
- return "\xEC\x98\x83";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\x9F";
- break;
- case 0xA4 :
- return "\xEC\x98\xBB";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x97";
- break;
- case 0x9C :
- return "\xEC\x99\xB3";
- break;
- case 0xB8 :
- return "\xEC\x9A\x8F";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xAB";
- break;
- case 0xB0 :
- return "\xEC\x9B\x87";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\xA3";
- break;
- case 0xA8 :
- return "\xEC\x9B\xBF";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x9B";
- break;
- case 0xA0 :
- return "\xEC\x9C\xB7";
- break;
- case 0xBC :
- return "\xEC\x9D\x93";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xAF";
- break;
- case 0xB4 :
- return "\xEC\x9E\x8B";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xA7";
- break;
- case 0xAC :
- return "\xEC\x9F\x83";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\x9F";
- break;
- case 0xA4 :
- return "\xEC\x9F\xBB";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x97";
- break;
- case 0x9C :
- return "\xEC\xA0\xB3";
- break;
- case 0xB8 :
- return "\xEC\xA1\x8F";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xAB";
- break;
- case 0xB0 :
- return "\xEC\xA2\x87";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\xA3";
- break;
- case 0xA8 :
- return "\xEC\xA2\xBF";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x9B";
- break;
- case 0xA0 :
- return "\xEC\xA3\xB7";
- break;
- case 0xBC :
- return "\xEC\xA4\x93";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xAF";
- break;
- case 0xB4 :
- return "\xEC\xA5\x8B";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xA7";
- break;
- case 0xAC :
- return "\xEC\xA6\x83";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\x9F";
- break;
- case 0xA4 :
- return "\xEC\xA6\xBB";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x97";
- break;
- case 0x9C :
- return "\xEC\xA7\xB3";
- break;
- case 0xB8 :
- return "\xEC\xA8\x8F";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xAB";
- break;
- case 0xB0 :
- return "\xEC\xA9\x87";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\xA3";
- break;
- case 0xA8 :
- return "\xEC\xA9\xBF";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x9B";
- break;
- case 0xA0 :
- return "\xEC\xAA\xB7";
- break;
- case 0xBC :
- return "\xEC\xAB\x93";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xAF";
- break;
- case 0xB4 :
- return "\xEC\xAC\x8B";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xA7";
- break;
- case 0xAC :
- return "\xEC\xAD\x83";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\x9F";
- break;
- case 0xA4 :
- return "\xEC\xAD\xBB";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x97";
- break;
- case 0x9C :
- return "\xEC\xAE\xB3";
- break;
- case 0xB8 :
- return "\xEC\xAF\x8F";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xAB";
- break;
- case 0xB0 :
- return "\xEC\xB0\x87";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\xA3";
- break;
- case 0xA8 :
- return "\xEC\xB0\xBF";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x9B";
- break;
- case 0xA0 :
- return "\xEC\xB1\xB7";
- break;
- case 0xBC :
- return "\xEC\xB2\x93";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xAF";
- break;
- case 0xB4 :
- return "\xEC\xB3\x8B";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xA7";
- break;
- case 0xAC :
- return "\xEC\xB4\x83";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\x9F";
- break;
- case 0xA4 :
- return "\xEC\xB4\xBB";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x97";
- break;
- case 0x9C :
- return "\xEC\xB5\xB3";
- break;
- case 0xB8 :
- return "\xEC\xB6\x8F";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xAB";
- break;
- case 0xB0 :
- return "\xEC\xB7\x87";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\xA3";
- break;
- case 0xA8 :
- return "\xEC\xB7\xBF";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x9B";
- break;
- case 0xA0 :
- return "\xEC\xB8\xB7";
- break;
- case 0xBC :
- return "\xEC\xB9\x93";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xAF";
- break;
- case 0xB4 :
- return "\xEC\xBA\x8B";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xA7";
- break;
- case 0xAC :
- return "\xEC\xBB\x83";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\x9F";
- break;
- case 0xA4 :
- return "\xEC\xBB\xBB";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x97";
- break;
- case 0x9C :
- return "\xEC\xBC\xB3";
- break;
- case 0xB8 :
- return "\xEC\xBD\x8F";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xAB";
- break;
- case 0xB0 :
- return "\xEC\xBE\x87";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\xA3";
- break;
- case 0xA8 :
- return "\xEC\xBE\xBF";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x9B";
- break;
- case 0xA0 :
- return "\xEC\xBF\xB7";
- break;
- case 0xBC :
- return "\xED\x80\x93";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xAF";
- break;
- case 0xB4 :
- return "\xED\x81\x8B";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xA7";
- break;
- case 0xAC :
- return "\xED\x82\x83";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\x9F";
- break;
- case 0xA4 :
- return "\xED\x82\xBB";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x97";
- break;
- case 0x9C :
- return "\xED\x83\xB3";
- break;
- case 0xB8 :
- return "\xED\x84\x8F";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xAB";
- break;
- case 0xB0 :
- return "\xED\x85\x87";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\xA3";
- break;
- case 0xA8 :
- return "\xED\x85\xBF";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x9B";
- break;
- case 0xA0 :
- return "\xED\x86\xB7";
- break;
- case 0xBC :
- return "\xED\x87\x93";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xAF";
- break;
- case 0xB4 :
- return "\xED\x88\x8B";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xA7";
- break;
- case 0xAC :
- return "\xED\x89\x83";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\x9F";
- break;
- case 0xA4 :
- return "\xED\x89\xBB";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x97";
- break;
- case 0x9C :
- return "\xED\x8A\xB3";
- break;
- case 0xB8 :
- return "\xED\x8B\x8F";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xAB";
- break;
- case 0xB0 :
- return "\xED\x8C\x87";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\xA3";
- break;
- case 0xA8 :
- return "\xED\x8C\xBF";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x9B";
- break;
- case 0xA0 :
- return "\xED\x8D\xB7";
- break;
- case 0xBC :
- return "\xED\x8E\x93";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xAF";
- break;
- case 0xB4 :
- return "\xED\x8F\x8B";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xA7";
- break;
- case 0xAC :
- return "\xED\x90\x83";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\x9F";
- break;
- case 0xA4 :
- return "\xED\x90\xBB";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x97";
- break;
- case 0x9C :
- return "\xED\x91\xB3";
- break;
- case 0xB8 :
- return "\xED\x92\x8F";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xAB";
- break;
- case 0xB0 :
- return "\xED\x93\x87";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\xA3";
- break;
- case 0xA8 :
- return "\xED\x93\xBF";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x9B";
- break;
- case 0xA0 :
- return "\xED\x94\xB7";
- break;
- case 0xBC :
- return "\xED\x95\x93";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xAF";
- break;
- case 0xB4 :
- return "\xED\x96\x8B";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xA7";
- break;
- case 0xAC :
- return "\xED\x97\x83";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\x9F";
- break;
- case 0xA4 :
- return "\xED\x97\xBB";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x97";
- break;
- case 0x9C :
- return "\xED\x98\xB3";
- break;
- case 0xB8 :
- return "\xED\x99\x8F";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xAB";
- break;
- case 0xB0 :
- return "\xED\x9A\x87";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\xA3";
- break;
- case 0xA8 :
- return "\xED\x9A\xBF";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x9B";
- break;
- case 0xA0 :
- return "\xED\x9B\xB7";
- break;
- case 0xBC :
- return "\xED\x9C\x93";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xAF";
- break;
- case 0xB4 :
- return "\xED\x9D\x8B";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xA7";
- break;
- case 0xAC :
- return "\xED\x9E\x83";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\x9F";
- }
- break;
- }
- break;
- }
- break;
- case 0xBF :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x98";
- break;
- case 0x9C :
- return "\xEA\xB0\xB4";
- break;
- case 0xB8 :
- return "\xEA\xB1\x90";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xAC";
- break;
- case 0xB0 :
- return "\xEA\xB2\x88";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\xA4";
- break;
- case 0xA8 :
- return "\xEA\xB3\x80";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x9C";
- break;
- case 0xA0 :
- return "\xEA\xB3\xB8";
- break;
- case 0xBC :
- return "\xEA\xB4\x94";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xB0";
- break;
- case 0xB4 :
- return "\xEA\xB5\x8C";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xA8";
- break;
- case 0xAC :
- return "\xEA\xB6\x84";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\xA0";
- break;
- case 0xA4 :
- return "\xEA\xB6\xBC";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x98";
- break;
- case 0x9C :
- return "\xEA\xB7\xB4";
- break;
- case 0xB8 :
- return "\xEA\xB8\x90";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xAC";
- break;
- case 0xB0 :
- return "\xEA\xB9\x88";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\xA4";
- break;
- case 0xA8 :
- return "\xEA\xBA\x80";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x9C";
- break;
- case 0xA0 :
- return "\xEA\xBA\xB8";
- break;
- case 0xBC :
- return "\xEA\xBB\x94";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xB0";
- break;
- case 0xB4 :
- return "\xEA\xBC\x8C";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xA8";
- break;
- case 0xAC :
- return "\xEA\xBD\x84";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\xA0";
- break;
- case 0xA4 :
- return "\xEA\xBD\xBC";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x98";
- break;
- case 0x9C :
- return "\xEA\xBE\xB4";
- break;
- case 0xB8 :
- return "\xEA\xBF\x90";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xAC";
- break;
- case 0xB0 :
- return "\xEB\x80\x88";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\xA4";
- break;
- case 0xA8 :
- return "\xEB\x81\x80";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x9C";
- break;
- case 0xA0 :
- return "\xEB\x81\xB8";
- break;
- case 0xBC :
- return "\xEB\x82\x94";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xB0";
- break;
- case 0xB4 :
- return "\xEB\x83\x8C";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xA8";
- break;
- case 0xAC :
- return "\xEB\x84\x84";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\xA0";
- break;
- case 0xA4 :
- return "\xEB\x84\xBC";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x98";
- break;
- case 0x9C :
- return "\xEB\x85\xB4";
- break;
- case 0xB8 :
- return "\xEB\x86\x90";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xAC";
- break;
- case 0xB0 :
- return "\xEB\x87\x88";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\xA4";
- break;
- case 0xA8 :
- return "\xEB\x88\x80";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x9C";
- break;
- case 0xA0 :
- return "\xEB\x88\xB8";
- break;
- case 0xBC :
- return "\xEB\x89\x94";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xB0";
- break;
- case 0xB4 :
- return "\xEB\x8A\x8C";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xA8";
- break;
- case 0xAC :
- return "\xEB\x8B\x84";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\xA0";
- break;
- case 0xA4 :
- return "\xEB\x8B\xBC";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x98";
- break;
- case 0x9C :
- return "\xEB\x8C\xB4";
- break;
- case 0xB8 :
- return "\xEB\x8D\x90";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xAC";
- break;
- case 0xB0 :
- return "\xEB\x8E\x88";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\xA4";
- break;
- case 0xA8 :
- return "\xEB\x8F\x80";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x9C";
- break;
- case 0xA0 :
- return "\xEB\x8F\xB8";
- break;
- case 0xBC :
- return "\xEB\x90\x94";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xB0";
- break;
- case 0xB4 :
- return "\xEB\x91\x8C";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xA8";
- break;
- case 0xAC :
- return "\xEB\x92\x84";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\xA0";
- break;
- case 0xA4 :
- return "\xEB\x92\xBC";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x98";
- break;
- case 0x9C :
- return "\xEB\x93\xB4";
- break;
- case 0xB8 :
- return "\xEB\x94\x90";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xAC";
- break;
- case 0xB0 :
- return "\xEB\x95\x88";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\xA4";
- break;
- case 0xA8 :
- return "\xEB\x96\x80";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x9C";
- break;
- case 0xA0 :
- return "\xEB\x96\xB8";
- break;
- case 0xBC :
- return "\xEB\x97\x94";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xB0";
- break;
- case 0xB4 :
- return "\xEB\x98\x8C";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xA8";
- break;
- case 0xAC :
- return "\xEB\x99\x84";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\xA0";
- break;
- case 0xA4 :
- return "\xEB\x99\xBC";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x98";
- break;
- case 0x9C :
- return "\xEB\x9A\xB4";
- break;
- case 0xB8 :
- return "\xEB\x9B\x90";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xAC";
- break;
- case 0xB0 :
- return "\xEB\x9C\x88";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\xA4";
- break;
- case 0xA8 :
- return "\xEB\x9D\x80";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x9C";
- break;
- case 0xA0 :
- return "\xEB\x9D\xB8";
- break;
- case 0xBC :
- return "\xEB\x9E\x94";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xB0";
- break;
- case 0xB4 :
- return "\xEB\x9F\x8C";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xA8";
- break;
- case 0xAC :
- return "\xEB\xA0\x84";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\xA0";
- break;
- case 0xA4 :
- return "\xEB\xA0\xBC";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x98";
- break;
- case 0x9C :
- return "\xEB\xA1\xB4";
- break;
- case 0xB8 :
- return "\xEB\xA2\x90";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xAC";
- break;
- case 0xB0 :
- return "\xEB\xA3\x88";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\xA4";
- break;
- case 0xA8 :
- return "\xEB\xA4\x80";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x9C";
- break;
- case 0xA0 :
- return "\xEB\xA4\xB8";
- break;
- case 0xBC :
- return "\xEB\xA5\x94";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xB0";
- break;
- case 0xB4 :
- return "\xEB\xA6\x8C";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xA8";
- break;
- case 0xAC :
- return "\xEB\xA7\x84";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\xA0";
- break;
- case 0xA4 :
- return "\xEB\xA7\xBC";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x98";
- break;
- case 0x9C :
- return "\xEB\xA8\xB4";
- break;
- case 0xB8 :
- return "\xEB\xA9\x90";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xAC";
- break;
- case 0xB0 :
- return "\xEB\xAA\x88";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\xA4";
- break;
- case 0xA8 :
- return "\xEB\xAB\x80";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x9C";
- break;
- case 0xA0 :
- return "\xEB\xAB\xB8";
- break;
- case 0xBC :
- return "\xEB\xAC\x94";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xB0";
- break;
- case 0xB4 :
- return "\xEB\xAD\x8C";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xA8";
- break;
- case 0xAC :
- return "\xEB\xAE\x84";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\xA0";
- break;
- case 0xA4 :
- return "\xEB\xAE\xBC";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x98";
- break;
- case 0x9C :
- return "\xEB\xAF\xB4";
- break;
- case 0xB8 :
- return "\xEB\xB0\x90";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xAC";
- break;
- case 0xB0 :
- return "\xEB\xB1\x88";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\xA4";
- break;
- case 0xA8 :
- return "\xEB\xB2\x80";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x9C";
- break;
- case 0xA0 :
- return "\xEB\xB2\xB8";
- break;
- case 0xBC :
- return "\xEB\xB3\x94";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xB0";
- break;
- case 0xB4 :
- return "\xEB\xB4\x8C";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xA8";
- break;
- case 0xAC :
- return "\xEB\xB5\x84";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\xA0";
- break;
- case 0xA4 :
- return "\xEB\xB5\xBC";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x98";
- break;
- case 0x9C :
- return "\xEB\xB6\xB4";
- break;
- case 0xB8 :
- return "\xEB\xB7\x90";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xAC";
- break;
- case 0xB0 :
- return "\xEB\xB8\x88";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\xA4";
- break;
- case 0xA8 :
- return "\xEB\xB9\x80";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x9C";
- break;
- case 0xA0 :
- return "\xEB\xB9\xB8";
- break;
- case 0xBC :
- return "\xEB\xBA\x94";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xB0";
- break;
- case 0xB4 :
- return "\xEB\xBB\x8C";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xA8";
- break;
- case 0xAC :
- return "\xEB\xBC\x84";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\xA0";
- break;
- case 0xA4 :
- return "\xEB\xBC\xBC";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x98";
- break;
- case 0x9C :
- return "\xEB\xBD\xB4";
- break;
- case 0xB8 :
- return "\xEB\xBE\x90";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xAC";
- break;
- case 0xB0 :
- return "\xEB\xBF\x88";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\xA4";
- break;
- case 0xA8 :
- return "\xEC\x80\x80";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x9C";
- break;
- case 0xA0 :
- return "\xEC\x80\xB8";
- break;
- case 0xBC :
- return "\xEC\x81\x94";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xB0";
- break;
- case 0xB4 :
- return "\xEC\x82\x8C";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xA8";
- break;
- case 0xAC :
- return "\xEC\x83\x84";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\xA0";
- break;
- case 0xA4 :
- return "\xEC\x83\xBC";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x98";
- break;
- case 0x9C :
- return "\xEC\x84\xB4";
- break;
- case 0xB8 :
- return "\xEC\x85\x90";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xAC";
- break;
- case 0xB0 :
- return "\xEC\x86\x88";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\xA4";
- break;
- case 0xA8 :
- return "\xEC\x87\x80";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x9C";
- break;
- case 0xA0 :
- return "\xEC\x87\xB8";
- break;
- case 0xBC :
- return "\xEC\x88\x94";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xB0";
- break;
- case 0xB4 :
- return "\xEC\x89\x8C";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xA8";
- break;
- case 0xAC :
- return "\xEC\x8A\x84";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\xA0";
- break;
- case 0xA4 :
- return "\xEC\x8A\xBC";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x98";
- break;
- case 0x9C :
- return "\xEC\x8B\xB4";
- break;
- case 0xB8 :
- return "\xEC\x8C\x90";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xAC";
- break;
- case 0xB0 :
- return "\xEC\x8D\x88";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\xA4";
- break;
- case 0xA8 :
- return "\xEC\x8E\x80";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x9C";
- break;
- case 0xA0 :
- return "\xEC\x8E\xB8";
- break;
- case 0xBC :
- return "\xEC\x8F\x94";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xB0";
- break;
- case 0xB4 :
- return "\xEC\x90\x8C";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xA8";
- break;
- case 0xAC :
- return "\xEC\x91\x84";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\xA0";
- break;
- case 0xA4 :
- return "\xEC\x91\xBC";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x98";
- break;
- case 0x9C :
- return "\xEC\x92\xB4";
- break;
- case 0xB8 :
- return "\xEC\x93\x90";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xAC";
- break;
- case 0xB0 :
- return "\xEC\x94\x88";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\xA4";
- break;
- case 0xA8 :
- return "\xEC\x95\x80";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x9C";
- break;
- case 0xA0 :
- return "\xEC\x95\xB8";
- break;
- case 0xBC :
- return "\xEC\x96\x94";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xB0";
- break;
- case 0xB4 :
- return "\xEC\x97\x8C";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xA8";
- break;
- case 0xAC :
- return "\xEC\x98\x84";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\xA0";
- break;
- case 0xA4 :
- return "\xEC\x98\xBC";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x98";
- break;
- case 0x9C :
- return "\xEC\x99\xB4";
- break;
- case 0xB8 :
- return "\xEC\x9A\x90";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xAC";
- break;
- case 0xB0 :
- return "\xEC\x9B\x88";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\xA4";
- break;
- case 0xA8 :
- return "\xEC\x9C\x80";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x9C";
- break;
- case 0xA0 :
- return "\xEC\x9C\xB8";
- break;
- case 0xBC :
- return "\xEC\x9D\x94";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xB0";
- break;
- case 0xB4 :
- return "\xEC\x9E\x8C";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xA8";
- break;
- case 0xAC :
- return "\xEC\x9F\x84";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\xA0";
- break;
- case 0xA4 :
- return "\xEC\x9F\xBC";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x98";
- break;
- case 0x9C :
- return "\xEC\xA0\xB4";
- break;
- case 0xB8 :
- return "\xEC\xA1\x90";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xAC";
- break;
- case 0xB0 :
- return "\xEC\xA2\x88";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\xA4";
- break;
- case 0xA8 :
- return "\xEC\xA3\x80";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x9C";
- break;
- case 0xA0 :
- return "\xEC\xA3\xB8";
- break;
- case 0xBC :
- return "\xEC\xA4\x94";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xB0";
- break;
- case 0xB4 :
- return "\xEC\xA5\x8C";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xA8";
- break;
- case 0xAC :
- return "\xEC\xA6\x84";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\xA0";
- break;
- case 0xA4 :
- return "\xEC\xA6\xBC";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x98";
- break;
- case 0x9C :
- return "\xEC\xA7\xB4";
- break;
- case 0xB8 :
- return "\xEC\xA8\x90";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xAC";
- break;
- case 0xB0 :
- return "\xEC\xA9\x88";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\xA4";
- break;
- case 0xA8 :
- return "\xEC\xAA\x80";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x9C";
- break;
- case 0xA0 :
- return "\xEC\xAA\xB8";
- break;
- case 0xBC :
- return "\xEC\xAB\x94";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xB0";
- break;
- case 0xB4 :
- return "\xEC\xAC\x8C";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xA8";
- break;
- case 0xAC :
- return "\xEC\xAD\x84";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\xA0";
- break;
- case 0xA4 :
- return "\xEC\xAD\xBC";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x98";
- break;
- case 0x9C :
- return "\xEC\xAE\xB4";
- break;
- case 0xB8 :
- return "\xEC\xAF\x90";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xAC";
- break;
- case 0xB0 :
- return "\xEC\xB0\x88";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\xA4";
- break;
- case 0xA8 :
- return "\xEC\xB1\x80";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x9C";
- break;
- case 0xA0 :
- return "\xEC\xB1\xB8";
- break;
- case 0xBC :
- return "\xEC\xB2\x94";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xB0";
- break;
- case 0xB4 :
- return "\xEC\xB3\x8C";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xA8";
- break;
- case 0xAC :
- return "\xEC\xB4\x84";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\xA0";
- break;
- case 0xA4 :
- return "\xEC\xB4\xBC";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x98";
- break;
- case 0x9C :
- return "\xEC\xB5\xB4";
- break;
- case 0xB8 :
- return "\xEC\xB6\x90";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xAC";
- break;
- case 0xB0 :
- return "\xEC\xB7\x88";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\xA4";
- break;
- case 0xA8 :
- return "\xEC\xB8\x80";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x9C";
- break;
- case 0xA0 :
- return "\xEC\xB8\xB8";
- break;
- case 0xBC :
- return "\xEC\xB9\x94";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xB0";
- break;
- case 0xB4 :
- return "\xEC\xBA\x8C";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xA8";
- break;
- case 0xAC :
- return "\xEC\xBB\x84";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\xA0";
- break;
- case 0xA4 :
- return "\xEC\xBB\xBC";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x98";
- break;
- case 0x9C :
- return "\xEC\xBC\xB4";
- break;
- case 0xB8 :
- return "\xEC\xBD\x90";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xAC";
- break;
- case 0xB0 :
- return "\xEC\xBE\x88";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\xA4";
- break;
- case 0xA8 :
- return "\xEC\xBF\x80";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x9C";
- break;
- case 0xA0 :
- return "\xEC\xBF\xB8";
- break;
- case 0xBC :
- return "\xED\x80\x94";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xB0";
- break;
- case 0xB4 :
- return "\xED\x81\x8C";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xA8";
- break;
- case 0xAC :
- return "\xED\x82\x84";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\xA0";
- break;
- case 0xA4 :
- return "\xED\x82\xBC";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x98";
- break;
- case 0x9C :
- return "\xED\x83\xB4";
- break;
- case 0xB8 :
- return "\xED\x84\x90";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xAC";
- break;
- case 0xB0 :
- return "\xED\x85\x88";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\xA4";
- break;
- case 0xA8 :
- return "\xED\x86\x80";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x9C";
- break;
- case 0xA0 :
- return "\xED\x86\xB8";
- break;
- case 0xBC :
- return "\xED\x87\x94";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xB0";
- break;
- case 0xB4 :
- return "\xED\x88\x8C";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xA8";
- break;
- case 0xAC :
- return "\xED\x89\x84";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\xA0";
- break;
- case 0xA4 :
- return "\xED\x89\xBC";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x98";
- break;
- case 0x9C :
- return "\xED\x8A\xB4";
- break;
- case 0xB8 :
- return "\xED\x8B\x90";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xAC";
- break;
- case 0xB0 :
- return "\xED\x8C\x88";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\xA4";
- break;
- case 0xA8 :
- return "\xED\x8D\x80";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x9C";
- break;
- case 0xA0 :
- return "\xED\x8D\xB8";
- break;
- case 0xBC :
- return "\xED\x8E\x94";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xB0";
- break;
- case 0xB4 :
- return "\xED\x8F\x8C";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xA8";
- break;
- case 0xAC :
- return "\xED\x90\x84";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\xA0";
- break;
- case 0xA4 :
- return "\xED\x90\xBC";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x98";
- break;
- case 0x9C :
- return "\xED\x91\xB4";
- break;
- case 0xB8 :
- return "\xED\x92\x90";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xAC";
- break;
- case 0xB0 :
- return "\xED\x93\x88";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\xA4";
- break;
- case 0xA8 :
- return "\xED\x94\x80";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x9C";
- break;
- case 0xA0 :
- return "\xED\x94\xB8";
- break;
- case 0xBC :
- return "\xED\x95\x94";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xB0";
- break;
- case 0xB4 :
- return "\xED\x96\x8C";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xA8";
- break;
- case 0xAC :
- return "\xED\x97\x84";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\xA0";
- break;
- case 0xA4 :
- return "\xED\x97\xBC";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x98";
- break;
- case 0x9C :
- return "\xED\x98\xB4";
- break;
- case 0xB8 :
- return "\xED\x99\x90";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xAC";
- break;
- case 0xB0 :
- return "\xED\x9A\x88";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\xA4";
- break;
- case 0xA8 :
- return "\xED\x9B\x80";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x9C";
- break;
- case 0xA0 :
- return "\xED\x9B\xB8";
- break;
- case 0xBC :
- return "\xED\x9C\x94";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xB0";
- break;
- case 0xB4 :
- return "\xED\x9D\x8C";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xA8";
- break;
- case 0xAC :
- return "\xED\x9E\x84";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\xA0";
- }
- break;
- }
- break;
- }
- break;
- }
- break;
- case 0x87 :
- switch (suffix[2]) {
- case 0x80 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x99";
- break;
- case 0x9C :
- return "\xEA\xB0\xB5";
- break;
- case 0xB8 :
- return "\xEA\xB1\x91";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xAD";
- break;
- case 0xB0 :
- return "\xEA\xB2\x89";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\xA5";
- break;
- case 0xA8 :
- return "\xEA\xB3\x81";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x9D";
- break;
- case 0xA0 :
- return "\xEA\xB3\xB9";
- break;
- case 0xBC :
- return "\xEA\xB4\x95";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xB1";
- break;
- case 0xB4 :
- return "\xEA\xB5\x8D";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xA9";
- break;
- case 0xAC :
- return "\xEA\xB6\x85";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\xA1";
- break;
- case 0xA4 :
- return "\xEA\xB6\xBD";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x99";
- break;
- case 0x9C :
- return "\xEA\xB7\xB5";
- break;
- case 0xB8 :
- return "\xEA\xB8\x91";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xAD";
- break;
- case 0xB0 :
- return "\xEA\xB9\x89";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\xA5";
- break;
- case 0xA8 :
- return "\xEA\xBA\x81";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x9D";
- break;
- case 0xA0 :
- return "\xEA\xBA\xB9";
- break;
- case 0xBC :
- return "\xEA\xBB\x95";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xB1";
- break;
- case 0xB4 :
- return "\xEA\xBC\x8D";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xA9";
- break;
- case 0xAC :
- return "\xEA\xBD\x85";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\xA1";
- break;
- case 0xA4 :
- return "\xEA\xBD\xBD";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x99";
- break;
- case 0x9C :
- return "\xEA\xBE\xB5";
- break;
- case 0xB8 :
- return "\xEA\xBF\x91";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xAD";
- break;
- case 0xB0 :
- return "\xEB\x80\x89";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\xA5";
- break;
- case 0xA8 :
- return "\xEB\x81\x81";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x9D";
- break;
- case 0xA0 :
- return "\xEB\x81\xB9";
- break;
- case 0xBC :
- return "\xEB\x82\x95";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xB1";
- break;
- case 0xB4 :
- return "\xEB\x83\x8D";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xA9";
- break;
- case 0xAC :
- return "\xEB\x84\x85";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\xA1";
- break;
- case 0xA4 :
- return "\xEB\x84\xBD";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x99";
- break;
- case 0x9C :
- return "\xEB\x85\xB5";
- break;
- case 0xB8 :
- return "\xEB\x86\x91";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xAD";
- break;
- case 0xB0 :
- return "\xEB\x87\x89";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\xA5";
- break;
- case 0xA8 :
- return "\xEB\x88\x81";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x9D";
- break;
- case 0xA0 :
- return "\xEB\x88\xB9";
- break;
- case 0xBC :
- return "\xEB\x89\x95";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xB1";
- break;
- case 0xB4 :
- return "\xEB\x8A\x8D";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xA9";
- break;
- case 0xAC :
- return "\xEB\x8B\x85";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\xA1";
- break;
- case 0xA4 :
- return "\xEB\x8B\xBD";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x99";
- break;
- case 0x9C :
- return "\xEB\x8C\xB5";
- break;
- case 0xB8 :
- return "\xEB\x8D\x91";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xAD";
- break;
- case 0xB0 :
- return "\xEB\x8E\x89";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\xA5";
- break;
- case 0xA8 :
- return "\xEB\x8F\x81";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x9D";
- break;
- case 0xA0 :
- return "\xEB\x8F\xB9";
- break;
- case 0xBC :
- return "\xEB\x90\x95";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xB1";
- break;
- case 0xB4 :
- return "\xEB\x91\x8D";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xA9";
- break;
- case 0xAC :
- return "\xEB\x92\x85";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\xA1";
- break;
- case 0xA4 :
- return "\xEB\x92\xBD";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x99";
- break;
- case 0x9C :
- return "\xEB\x93\xB5";
- break;
- case 0xB8 :
- return "\xEB\x94\x91";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xAD";
- break;
- case 0xB0 :
- return "\xEB\x95\x89";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\xA5";
- break;
- case 0xA8 :
- return "\xEB\x96\x81";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x9D";
- break;
- case 0xA0 :
- return "\xEB\x96\xB9";
- break;
- case 0xBC :
- return "\xEB\x97\x95";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xB1";
- break;
- case 0xB4 :
- return "\xEB\x98\x8D";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xA9";
- break;
- case 0xAC :
- return "\xEB\x99\x85";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\xA1";
- break;
- case 0xA4 :
- return "\xEB\x99\xBD";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x99";
- break;
- case 0x9C :
- return "\xEB\x9A\xB5";
- break;
- case 0xB8 :
- return "\xEB\x9B\x91";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xAD";
- break;
- case 0xB0 :
- return "\xEB\x9C\x89";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\xA5";
- break;
- case 0xA8 :
- return "\xEB\x9D\x81";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x9D";
- break;
- case 0xA0 :
- return "\xEB\x9D\xB9";
- break;
- case 0xBC :
- return "\xEB\x9E\x95";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xB1";
- break;
- case 0xB4 :
- return "\xEB\x9F\x8D";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xA9";
- break;
- case 0xAC :
- return "\xEB\xA0\x85";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\xA1";
- break;
- case 0xA4 :
- return "\xEB\xA0\xBD";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x99";
- break;
- case 0x9C :
- return "\xEB\xA1\xB5";
- break;
- case 0xB8 :
- return "\xEB\xA2\x91";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xAD";
- break;
- case 0xB0 :
- return "\xEB\xA3\x89";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\xA5";
- break;
- case 0xA8 :
- return "\xEB\xA4\x81";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x9D";
- break;
- case 0xA0 :
- return "\xEB\xA4\xB9";
- break;
- case 0xBC :
- return "\xEB\xA5\x95";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xB1";
- break;
- case 0xB4 :
- return "\xEB\xA6\x8D";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xA9";
- break;
- case 0xAC :
- return "\xEB\xA7\x85";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\xA1";
- break;
- case 0xA4 :
- return "\xEB\xA7\xBD";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x99";
- break;
- case 0x9C :
- return "\xEB\xA8\xB5";
- break;
- case 0xB8 :
- return "\xEB\xA9\x91";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xAD";
- break;
- case 0xB0 :
- return "\xEB\xAA\x89";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\xA5";
- break;
- case 0xA8 :
- return "\xEB\xAB\x81";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x9D";
- break;
- case 0xA0 :
- return "\xEB\xAB\xB9";
- break;
- case 0xBC :
- return "\xEB\xAC\x95";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xB1";
- break;
- case 0xB4 :
- return "\xEB\xAD\x8D";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xA9";
- break;
- case 0xAC :
- return "\xEB\xAE\x85";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\xA1";
- break;
- case 0xA4 :
- return "\xEB\xAE\xBD";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x99";
- break;
- case 0x9C :
- return "\xEB\xAF\xB5";
- break;
- case 0xB8 :
- return "\xEB\xB0\x91";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xAD";
- break;
- case 0xB0 :
- return "\xEB\xB1\x89";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\xA5";
- break;
- case 0xA8 :
- return "\xEB\xB2\x81";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x9D";
- break;
- case 0xA0 :
- return "\xEB\xB2\xB9";
- break;
- case 0xBC :
- return "\xEB\xB3\x95";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xB1";
- break;
- case 0xB4 :
- return "\xEB\xB4\x8D";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xA9";
- break;
- case 0xAC :
- return "\xEB\xB5\x85";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\xA1";
- break;
- case 0xA4 :
- return "\xEB\xB5\xBD";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x99";
- break;
- case 0x9C :
- return "\xEB\xB6\xB5";
- break;
- case 0xB8 :
- return "\xEB\xB7\x91";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xAD";
- break;
- case 0xB0 :
- return "\xEB\xB8\x89";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\xA5";
- break;
- case 0xA8 :
- return "\xEB\xB9\x81";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x9D";
- break;
- case 0xA0 :
- return "\xEB\xB9\xB9";
- break;
- case 0xBC :
- return "\xEB\xBA\x95";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xB1";
- break;
- case 0xB4 :
- return "\xEB\xBB\x8D";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xA9";
- break;
- case 0xAC :
- return "\xEB\xBC\x85";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\xA1";
- break;
- case 0xA4 :
- return "\xEB\xBC\xBD";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x99";
- break;
- case 0x9C :
- return "\xEB\xBD\xB5";
- break;
- case 0xB8 :
- return "\xEB\xBE\x91";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xAD";
- break;
- case 0xB0 :
- return "\xEB\xBF\x89";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\xA5";
- break;
- case 0xA8 :
- return "\xEC\x80\x81";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x9D";
- break;
- case 0xA0 :
- return "\xEC\x80\xB9";
- break;
- case 0xBC :
- return "\xEC\x81\x95";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xB1";
- break;
- case 0xB4 :
- return "\xEC\x82\x8D";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xA9";
- break;
- case 0xAC :
- return "\xEC\x83\x85";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\xA1";
- break;
- case 0xA4 :
- return "\xEC\x83\xBD";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x99";
- break;
- case 0x9C :
- return "\xEC\x84\xB5";
- break;
- case 0xB8 :
- return "\xEC\x85\x91";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xAD";
- break;
- case 0xB0 :
- return "\xEC\x86\x89";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\xA5";
- break;
- case 0xA8 :
- return "\xEC\x87\x81";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x9D";
- break;
- case 0xA0 :
- return "\xEC\x87\xB9";
- break;
- case 0xBC :
- return "\xEC\x88\x95";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xB1";
- break;
- case 0xB4 :
- return "\xEC\x89\x8D";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xA9";
- break;
- case 0xAC :
- return "\xEC\x8A\x85";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\xA1";
- break;
- case 0xA4 :
- return "\xEC\x8A\xBD";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x99";
- break;
- case 0x9C :
- return "\xEC\x8B\xB5";
- break;
- case 0xB8 :
- return "\xEC\x8C\x91";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xAD";
- break;
- case 0xB0 :
- return "\xEC\x8D\x89";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\xA5";
- break;
- case 0xA8 :
- return "\xEC\x8E\x81";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x9D";
- break;
- case 0xA0 :
- return "\xEC\x8E\xB9";
- break;
- case 0xBC :
- return "\xEC\x8F\x95";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xB1";
- break;
- case 0xB4 :
- return "\xEC\x90\x8D";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xA9";
- break;
- case 0xAC :
- return "\xEC\x91\x85";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\xA1";
- break;
- case 0xA4 :
- return "\xEC\x91\xBD";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x99";
- break;
- case 0x9C :
- return "\xEC\x92\xB5";
- break;
- case 0xB8 :
- return "\xEC\x93\x91";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xAD";
- break;
- case 0xB0 :
- return "\xEC\x94\x89";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\xA5";
- break;
- case 0xA8 :
- return "\xEC\x95\x81";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x9D";
- break;
- case 0xA0 :
- return "\xEC\x95\xB9";
- break;
- case 0xBC :
- return "\xEC\x96\x95";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xB1";
- break;
- case 0xB4 :
- return "\xEC\x97\x8D";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xA9";
- break;
- case 0xAC :
- return "\xEC\x98\x85";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\xA1";
- break;
- case 0xA4 :
- return "\xEC\x98\xBD";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x99";
- break;
- case 0x9C :
- return "\xEC\x99\xB5";
- break;
- case 0xB8 :
- return "\xEC\x9A\x91";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xAD";
- break;
- case 0xB0 :
- return "\xEC\x9B\x89";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\xA5";
- break;
- case 0xA8 :
- return "\xEC\x9C\x81";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x9D";
- break;
- case 0xA0 :
- return "\xEC\x9C\xB9";
- break;
- case 0xBC :
- return "\xEC\x9D\x95";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xB1";
- break;
- case 0xB4 :
- return "\xEC\x9E\x8D";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xA9";
- break;
- case 0xAC :
- return "\xEC\x9F\x85";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\xA1";
- break;
- case 0xA4 :
- return "\xEC\x9F\xBD";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x99";
- break;
- case 0x9C :
- return "\xEC\xA0\xB5";
- break;
- case 0xB8 :
- return "\xEC\xA1\x91";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xAD";
- break;
- case 0xB0 :
- return "\xEC\xA2\x89";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\xA5";
- break;
- case 0xA8 :
- return "\xEC\xA3\x81";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x9D";
- break;
- case 0xA0 :
- return "\xEC\xA3\xB9";
- break;
- case 0xBC :
- return "\xEC\xA4\x95";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xB1";
- break;
- case 0xB4 :
- return "\xEC\xA5\x8D";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xA9";
- break;
- case 0xAC :
- return "\xEC\xA6\x85";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\xA1";
- break;
- case 0xA4 :
- return "\xEC\xA6\xBD";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x99";
- break;
- case 0x9C :
- return "\xEC\xA7\xB5";
- break;
- case 0xB8 :
- return "\xEC\xA8\x91";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xAD";
- break;
- case 0xB0 :
- return "\xEC\xA9\x89";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\xA5";
- break;
- case 0xA8 :
- return "\xEC\xAA\x81";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x9D";
- break;
- case 0xA0 :
- return "\xEC\xAA\xB9";
- break;
- case 0xBC :
- return "\xEC\xAB\x95";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xB1";
- break;
- case 0xB4 :
- return "\xEC\xAC\x8D";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xA9";
- break;
- case 0xAC :
- return "\xEC\xAD\x85";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\xA1";
- break;
- case 0xA4 :
- return "\xEC\xAD\xBD";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x99";
- break;
- case 0x9C :
- return "\xEC\xAE\xB5";
- break;
- case 0xB8 :
- return "\xEC\xAF\x91";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xAD";
- break;
- case 0xB0 :
- return "\xEC\xB0\x89";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\xA5";
- break;
- case 0xA8 :
- return "\xEC\xB1\x81";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x9D";
- break;
- case 0xA0 :
- return "\xEC\xB1\xB9";
- break;
- case 0xBC :
- return "\xEC\xB2\x95";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xB1";
- break;
- case 0xB4 :
- return "\xEC\xB3\x8D";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xA9";
- break;
- case 0xAC :
- return "\xEC\xB4\x85";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\xA1";
- break;
- case 0xA4 :
- return "\xEC\xB4\xBD";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x99";
- break;
- case 0x9C :
- return "\xEC\xB5\xB5";
- break;
- case 0xB8 :
- return "\xEC\xB6\x91";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xAD";
- break;
- case 0xB0 :
- return "\xEC\xB7\x89";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\xA5";
- break;
- case 0xA8 :
- return "\xEC\xB8\x81";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x9D";
- break;
- case 0xA0 :
- return "\xEC\xB8\xB9";
- break;
- case 0xBC :
- return "\xEC\xB9\x95";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xB1";
- break;
- case 0xB4 :
- return "\xEC\xBA\x8D";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xA9";
- break;
- case 0xAC :
- return "\xEC\xBB\x85";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\xA1";
- break;
- case 0xA4 :
- return "\xEC\xBB\xBD";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x99";
- break;
- case 0x9C :
- return "\xEC\xBC\xB5";
- break;
- case 0xB8 :
- return "\xEC\xBD\x91";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xAD";
- break;
- case 0xB0 :
- return "\xEC\xBE\x89";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\xA5";
- break;
- case 0xA8 :
- return "\xEC\xBF\x81";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x9D";
- break;
- case 0xA0 :
- return "\xEC\xBF\xB9";
- break;
- case 0xBC :
- return "\xED\x80\x95";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xB1";
- break;
- case 0xB4 :
- return "\xED\x81\x8D";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xA9";
- break;
- case 0xAC :
- return "\xED\x82\x85";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\xA1";
- break;
- case 0xA4 :
- return "\xED\x82\xBD";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x99";
- break;
- case 0x9C :
- return "\xED\x83\xB5";
- break;
- case 0xB8 :
- return "\xED\x84\x91";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xAD";
- break;
- case 0xB0 :
- return "\xED\x85\x89";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\xA5";
- break;
- case 0xA8 :
- return "\xED\x86\x81";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x9D";
- break;
- case 0xA0 :
- return "\xED\x86\xB9";
- break;
- case 0xBC :
- return "\xED\x87\x95";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xB1";
- break;
- case 0xB4 :
- return "\xED\x88\x8D";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xA9";
- break;
- case 0xAC :
- return "\xED\x89\x85";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\xA1";
- break;
- case 0xA4 :
- return "\xED\x89\xBD";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x99";
- break;
- case 0x9C :
- return "\xED\x8A\xB5";
- break;
- case 0xB8 :
- return "\xED\x8B\x91";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xAD";
- break;
- case 0xB0 :
- return "\xED\x8C\x89";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\xA5";
- break;
- case 0xA8 :
- return "\xED\x8D\x81";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x9D";
- break;
- case 0xA0 :
- return "\xED\x8D\xB9";
- break;
- case 0xBC :
- return "\xED\x8E\x95";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xB1";
- break;
- case 0xB4 :
- return "\xED\x8F\x8D";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xA9";
- break;
- case 0xAC :
- return "\xED\x90\x85";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\xA1";
- break;
- case 0xA4 :
- return "\xED\x90\xBD";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x99";
- break;
- case 0x9C :
- return "\xED\x91\xB5";
- break;
- case 0xB8 :
- return "\xED\x92\x91";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xAD";
- break;
- case 0xB0 :
- return "\xED\x93\x89";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\xA5";
- break;
- case 0xA8 :
- return "\xED\x94\x81";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x9D";
- break;
- case 0xA0 :
- return "\xED\x94\xB9";
- break;
- case 0xBC :
- return "\xED\x95\x95";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xB1";
- break;
- case 0xB4 :
- return "\xED\x96\x8D";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xA9";
- break;
- case 0xAC :
- return "\xED\x97\x85";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\xA1";
- break;
- case 0xA4 :
- return "\xED\x97\xBD";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x99";
- break;
- case 0x9C :
- return "\xED\x98\xB5";
- break;
- case 0xB8 :
- return "\xED\x99\x91";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xAD";
- break;
- case 0xB0 :
- return "\xED\x9A\x89";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\xA5";
- break;
- case 0xA8 :
- return "\xED\x9B\x81";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x9D";
- break;
- case 0xA0 :
- return "\xED\x9B\xB9";
- break;
- case 0xBC :
- return "\xED\x9C\x95";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xB1";
- break;
- case 0xB4 :
- return "\xED\x9D\x8D";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xA9";
- break;
- case 0xAC :
- return "\xED\x9E\x85";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\xA1";
- }
- break;
- }
- break;
- }
- break;
- case 0x81 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x9A";
- break;
- case 0x9C :
- return "\xEA\xB0\xB6";
- break;
- case 0xB8 :
- return "\xEA\xB1\x92";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xAE";
- break;
- case 0xB0 :
- return "\xEA\xB2\x8A";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\xA6";
- break;
- case 0xA8 :
- return "\xEA\xB3\x82";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x9E";
- break;
- case 0xA0 :
- return "\xEA\xB3\xBA";
- break;
- case 0xBC :
- return "\xEA\xB4\x96";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xB2";
- break;
- case 0xB4 :
- return "\xEA\xB5\x8E";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xAA";
- break;
- case 0xAC :
- return "\xEA\xB6\x86";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\xA2";
- break;
- case 0xA4 :
- return "\xEA\xB6\xBE";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x9A";
- break;
- case 0x9C :
- return "\xEA\xB7\xB6";
- break;
- case 0xB8 :
- return "\xEA\xB8\x92";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xAE";
- break;
- case 0xB0 :
- return "\xEA\xB9\x8A";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\xA6";
- break;
- case 0xA8 :
- return "\xEA\xBA\x82";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x9E";
- break;
- case 0xA0 :
- return "\xEA\xBA\xBA";
- break;
- case 0xBC :
- return "\xEA\xBB\x96";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xB2";
- break;
- case 0xB4 :
- return "\xEA\xBC\x8E";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xAA";
- break;
- case 0xAC :
- return "\xEA\xBD\x86";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\xA2";
- break;
- case 0xA4 :
- return "\xEA\xBD\xBE";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x9A";
- break;
- case 0x9C :
- return "\xEA\xBE\xB6";
- break;
- case 0xB8 :
- return "\xEA\xBF\x92";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xAE";
- break;
- case 0xB0 :
- return "\xEB\x80\x8A";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\xA6";
- break;
- case 0xA8 :
- return "\xEB\x81\x82";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x9E";
- break;
- case 0xA0 :
- return "\xEB\x81\xBA";
- break;
- case 0xBC :
- return "\xEB\x82\x96";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xB2";
- break;
- case 0xB4 :
- return "\xEB\x83\x8E";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xAA";
- break;
- case 0xAC :
- return "\xEB\x84\x86";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\xA2";
- break;
- case 0xA4 :
- return "\xEB\x84\xBE";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x9A";
- break;
- case 0x9C :
- return "\xEB\x85\xB6";
- break;
- case 0xB8 :
- return "\xEB\x86\x92";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xAE";
- break;
- case 0xB0 :
- return "\xEB\x87\x8A";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\xA6";
- break;
- case 0xA8 :
- return "\xEB\x88\x82";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x9E";
- break;
- case 0xA0 :
- return "\xEB\x88\xBA";
- break;
- case 0xBC :
- return "\xEB\x89\x96";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xB2";
- break;
- case 0xB4 :
- return "\xEB\x8A\x8E";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xAA";
- break;
- case 0xAC :
- return "\xEB\x8B\x86";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\xA2";
- break;
- case 0xA4 :
- return "\xEB\x8B\xBE";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x9A";
- break;
- case 0x9C :
- return "\xEB\x8C\xB6";
- break;
- case 0xB8 :
- return "\xEB\x8D\x92";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xAE";
- break;
- case 0xB0 :
- return "\xEB\x8E\x8A";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\xA6";
- break;
- case 0xA8 :
- return "\xEB\x8F\x82";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x9E";
- break;
- case 0xA0 :
- return "\xEB\x8F\xBA";
- break;
- case 0xBC :
- return "\xEB\x90\x96";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xB2";
- break;
- case 0xB4 :
- return "\xEB\x91\x8E";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xAA";
- break;
- case 0xAC :
- return "\xEB\x92\x86";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\xA2";
- break;
- case 0xA4 :
- return "\xEB\x92\xBE";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x9A";
- break;
- case 0x9C :
- return "\xEB\x93\xB6";
- break;
- case 0xB8 :
- return "\xEB\x94\x92";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xAE";
- break;
- case 0xB0 :
- return "\xEB\x95\x8A";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\xA6";
- break;
- case 0xA8 :
- return "\xEB\x96\x82";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x9E";
- break;
- case 0xA0 :
- return "\xEB\x96\xBA";
- break;
- case 0xBC :
- return "\xEB\x97\x96";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xB2";
- break;
- case 0xB4 :
- return "\xEB\x98\x8E";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xAA";
- break;
- case 0xAC :
- return "\xEB\x99\x86";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\xA2";
- break;
- case 0xA4 :
- return "\xEB\x99\xBE";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x9A";
- break;
- case 0x9C :
- return "\xEB\x9A\xB6";
- break;
- case 0xB8 :
- return "\xEB\x9B\x92";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xAE";
- break;
- case 0xB0 :
- return "\xEB\x9C\x8A";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\xA6";
- break;
- case 0xA8 :
- return "\xEB\x9D\x82";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x9E";
- break;
- case 0xA0 :
- return "\xEB\x9D\xBA";
- break;
- case 0xBC :
- return "\xEB\x9E\x96";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xB2";
- break;
- case 0xB4 :
- return "\xEB\x9F\x8E";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xAA";
- break;
- case 0xAC :
- return "\xEB\xA0\x86";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\xA2";
- break;
- case 0xA4 :
- return "\xEB\xA0\xBE";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x9A";
- break;
- case 0x9C :
- return "\xEB\xA1\xB6";
- break;
- case 0xB8 :
- return "\xEB\xA2\x92";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xAE";
- break;
- case 0xB0 :
- return "\xEB\xA3\x8A";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\xA6";
- break;
- case 0xA8 :
- return "\xEB\xA4\x82";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x9E";
- break;
- case 0xA0 :
- return "\xEB\xA4\xBA";
- break;
- case 0xBC :
- return "\xEB\xA5\x96";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xB2";
- break;
- case 0xB4 :
- return "\xEB\xA6\x8E";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xAA";
- break;
- case 0xAC :
- return "\xEB\xA7\x86";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\xA2";
- break;
- case 0xA4 :
- return "\xEB\xA7\xBE";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x9A";
- break;
- case 0x9C :
- return "\xEB\xA8\xB6";
- break;
- case 0xB8 :
- return "\xEB\xA9\x92";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xAE";
- break;
- case 0xB0 :
- return "\xEB\xAA\x8A";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\xA6";
- break;
- case 0xA8 :
- return "\xEB\xAB\x82";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x9E";
- break;
- case 0xA0 :
- return "\xEB\xAB\xBA";
- break;
- case 0xBC :
- return "\xEB\xAC\x96";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xB2";
- break;
- case 0xB4 :
- return "\xEB\xAD\x8E";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xAA";
- break;
- case 0xAC :
- return "\xEB\xAE\x86";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\xA2";
- break;
- case 0xA4 :
- return "\xEB\xAE\xBE";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x9A";
- break;
- case 0x9C :
- return "\xEB\xAF\xB6";
- break;
- case 0xB8 :
- return "\xEB\xB0\x92";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xAE";
- break;
- case 0xB0 :
- return "\xEB\xB1\x8A";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\xA6";
- break;
- case 0xA8 :
- return "\xEB\xB2\x82";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x9E";
- break;
- case 0xA0 :
- return "\xEB\xB2\xBA";
- break;
- case 0xBC :
- return "\xEB\xB3\x96";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xB2";
- break;
- case 0xB4 :
- return "\xEB\xB4\x8E";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xAA";
- break;
- case 0xAC :
- return "\xEB\xB5\x86";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\xA2";
- break;
- case 0xA4 :
- return "\xEB\xB5\xBE";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x9A";
- break;
- case 0x9C :
- return "\xEB\xB6\xB6";
- break;
- case 0xB8 :
- return "\xEB\xB7\x92";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xAE";
- break;
- case 0xB0 :
- return "\xEB\xB8\x8A";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\xA6";
- break;
- case 0xA8 :
- return "\xEB\xB9\x82";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x9E";
- break;
- case 0xA0 :
- return "\xEB\xB9\xBA";
- break;
- case 0xBC :
- return "\xEB\xBA\x96";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xB2";
- break;
- case 0xB4 :
- return "\xEB\xBB\x8E";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xAA";
- break;
- case 0xAC :
- return "\xEB\xBC\x86";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\xA2";
- break;
- case 0xA4 :
- return "\xEB\xBC\xBE";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x9A";
- break;
- case 0x9C :
- return "\xEB\xBD\xB6";
- break;
- case 0xB8 :
- return "\xEB\xBE\x92";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xAE";
- break;
- case 0xB0 :
- return "\xEB\xBF\x8A";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\xA6";
- break;
- case 0xA8 :
- return "\xEC\x80\x82";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x9E";
- break;
- case 0xA0 :
- return "\xEC\x80\xBA";
- break;
- case 0xBC :
- return "\xEC\x81\x96";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xB2";
- break;
- case 0xB4 :
- return "\xEC\x82\x8E";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xAA";
- break;
- case 0xAC :
- return "\xEC\x83\x86";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\xA2";
- break;
- case 0xA4 :
- return "\xEC\x83\xBE";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x9A";
- break;
- case 0x9C :
- return "\xEC\x84\xB6";
- break;
- case 0xB8 :
- return "\xEC\x85\x92";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xAE";
- break;
- case 0xB0 :
- return "\xEC\x86\x8A";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\xA6";
- break;
- case 0xA8 :
- return "\xEC\x87\x82";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x9E";
- break;
- case 0xA0 :
- return "\xEC\x87\xBA";
- break;
- case 0xBC :
- return "\xEC\x88\x96";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xB2";
- break;
- case 0xB4 :
- return "\xEC\x89\x8E";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xAA";
- break;
- case 0xAC :
- return "\xEC\x8A\x86";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\xA2";
- break;
- case 0xA4 :
- return "\xEC\x8A\xBE";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x9A";
- break;
- case 0x9C :
- return "\xEC\x8B\xB6";
- break;
- case 0xB8 :
- return "\xEC\x8C\x92";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xAE";
- break;
- case 0xB0 :
- return "\xEC\x8D\x8A";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\xA6";
- break;
- case 0xA8 :
- return "\xEC\x8E\x82";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x9E";
- break;
- case 0xA0 :
- return "\xEC\x8E\xBA";
- break;
- case 0xBC :
- return "\xEC\x8F\x96";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xB2";
- break;
- case 0xB4 :
- return "\xEC\x90\x8E";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xAA";
- break;
- case 0xAC :
- return "\xEC\x91\x86";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\xA2";
- break;
- case 0xA4 :
- return "\xEC\x91\xBE";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x9A";
- break;
- case 0x9C :
- return "\xEC\x92\xB6";
- break;
- case 0xB8 :
- return "\xEC\x93\x92";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xAE";
- break;
- case 0xB0 :
- return "\xEC\x94\x8A";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\xA6";
- break;
- case 0xA8 :
- return "\xEC\x95\x82";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x9E";
- break;
- case 0xA0 :
- return "\xEC\x95\xBA";
- break;
- case 0xBC :
- return "\xEC\x96\x96";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xB2";
- break;
- case 0xB4 :
- return "\xEC\x97\x8E";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xAA";
- break;
- case 0xAC :
- return "\xEC\x98\x86";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\xA2";
- break;
- case 0xA4 :
- return "\xEC\x98\xBE";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x9A";
- break;
- case 0x9C :
- return "\xEC\x99\xB6";
- break;
- case 0xB8 :
- return "\xEC\x9A\x92";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xAE";
- break;
- case 0xB0 :
- return "\xEC\x9B\x8A";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\xA6";
- break;
- case 0xA8 :
- return "\xEC\x9C\x82";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x9E";
- break;
- case 0xA0 :
- return "\xEC\x9C\xBA";
- break;
- case 0xBC :
- return "\xEC\x9D\x96";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xB2";
- break;
- case 0xB4 :
- return "\xEC\x9E\x8E";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xAA";
- break;
- case 0xAC :
- return "\xEC\x9F\x86";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\xA2";
- break;
- case 0xA4 :
- return "\xEC\x9F\xBE";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x9A";
- break;
- case 0x9C :
- return "\xEC\xA0\xB6";
- break;
- case 0xB8 :
- return "\xEC\xA1\x92";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xAE";
- break;
- case 0xB0 :
- return "\xEC\xA2\x8A";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\xA6";
- break;
- case 0xA8 :
- return "\xEC\xA3\x82";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x9E";
- break;
- case 0xA0 :
- return "\xEC\xA3\xBA";
- break;
- case 0xBC :
- return "\xEC\xA4\x96";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xB2";
- break;
- case 0xB4 :
- return "\xEC\xA5\x8E";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xAA";
- break;
- case 0xAC :
- return "\xEC\xA6\x86";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\xA2";
- break;
- case 0xA4 :
- return "\xEC\xA6\xBE";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x9A";
- break;
- case 0x9C :
- return "\xEC\xA7\xB6";
- break;
- case 0xB8 :
- return "\xEC\xA8\x92";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xAE";
- break;
- case 0xB0 :
- return "\xEC\xA9\x8A";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\xA6";
- break;
- case 0xA8 :
- return "\xEC\xAA\x82";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x9E";
- break;
- case 0xA0 :
- return "\xEC\xAA\xBA";
- break;
- case 0xBC :
- return "\xEC\xAB\x96";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xB2";
- break;
- case 0xB4 :
- return "\xEC\xAC\x8E";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xAA";
- break;
- case 0xAC :
- return "\xEC\xAD\x86";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\xA2";
- break;
- case 0xA4 :
- return "\xEC\xAD\xBE";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x9A";
- break;
- case 0x9C :
- return "\xEC\xAE\xB6";
- break;
- case 0xB8 :
- return "\xEC\xAF\x92";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xAE";
- break;
- case 0xB0 :
- return "\xEC\xB0\x8A";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\xA6";
- break;
- case 0xA8 :
- return "\xEC\xB1\x82";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x9E";
- break;
- case 0xA0 :
- return "\xEC\xB1\xBA";
- break;
- case 0xBC :
- return "\xEC\xB2\x96";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xB2";
- break;
- case 0xB4 :
- return "\xEC\xB3\x8E";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xAA";
- break;
- case 0xAC :
- return "\xEC\xB4\x86";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\xA2";
- break;
- case 0xA4 :
- return "\xEC\xB4\xBE";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x9A";
- break;
- case 0x9C :
- return "\xEC\xB5\xB6";
- break;
- case 0xB8 :
- return "\xEC\xB6\x92";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xAE";
- break;
- case 0xB0 :
- return "\xEC\xB7\x8A";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\xA6";
- break;
- case 0xA8 :
- return "\xEC\xB8\x82";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x9E";
- break;
- case 0xA0 :
- return "\xEC\xB8\xBA";
- break;
- case 0xBC :
- return "\xEC\xB9\x96";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xB2";
- break;
- case 0xB4 :
- return "\xEC\xBA\x8E";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xAA";
- break;
- case 0xAC :
- return "\xEC\xBB\x86";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\xA2";
- break;
- case 0xA4 :
- return "\xEC\xBB\xBE";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x9A";
- break;
- case 0x9C :
- return "\xEC\xBC\xB6";
- break;
- case 0xB8 :
- return "\xEC\xBD\x92";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xAE";
- break;
- case 0xB0 :
- return "\xEC\xBE\x8A";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\xA6";
- break;
- case 0xA8 :
- return "\xEC\xBF\x82";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x9E";
- break;
- case 0xA0 :
- return "\xEC\xBF\xBA";
- break;
- case 0xBC :
- return "\xED\x80\x96";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xB2";
- break;
- case 0xB4 :
- return "\xED\x81\x8E";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xAA";
- break;
- case 0xAC :
- return "\xED\x82\x86";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\xA2";
- break;
- case 0xA4 :
- return "\xED\x82\xBE";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x9A";
- break;
- case 0x9C :
- return "\xED\x83\xB6";
- break;
- case 0xB8 :
- return "\xED\x84\x92";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xAE";
- break;
- case 0xB0 :
- return "\xED\x85\x8A";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\xA6";
- break;
- case 0xA8 :
- return "\xED\x86\x82";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x9E";
- break;
- case 0xA0 :
- return "\xED\x86\xBA";
- break;
- case 0xBC :
- return "\xED\x87\x96";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xB2";
- break;
- case 0xB4 :
- return "\xED\x88\x8E";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xAA";
- break;
- case 0xAC :
- return "\xED\x89\x86";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\xA2";
- break;
- case 0xA4 :
- return "\xED\x89\xBE";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x9A";
- break;
- case 0x9C :
- return "\xED\x8A\xB6";
- break;
- case 0xB8 :
- return "\xED\x8B\x92";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xAE";
- break;
- case 0xB0 :
- return "\xED\x8C\x8A";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\xA6";
- break;
- case 0xA8 :
- return "\xED\x8D\x82";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x9E";
- break;
- case 0xA0 :
- return "\xED\x8D\xBA";
- break;
- case 0xBC :
- return "\xED\x8E\x96";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xB2";
- break;
- case 0xB4 :
- return "\xED\x8F\x8E";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xAA";
- break;
- case 0xAC :
- return "\xED\x90\x86";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\xA2";
- break;
- case 0xA4 :
- return "\xED\x90\xBE";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x9A";
- break;
- case 0x9C :
- return "\xED\x91\xB6";
- break;
- case 0xB8 :
- return "\xED\x92\x92";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xAE";
- break;
- case 0xB0 :
- return "\xED\x93\x8A";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\xA6";
- break;
- case 0xA8 :
- return "\xED\x94\x82";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x9E";
- break;
- case 0xA0 :
- return "\xED\x94\xBA";
- break;
- case 0xBC :
- return "\xED\x95\x96";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xB2";
- break;
- case 0xB4 :
- return "\xED\x96\x8E";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xAA";
- break;
- case 0xAC :
- return "\xED\x97\x86";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\xA2";
- break;
- case 0xA4 :
- return "\xED\x97\xBE";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x9A";
- break;
- case 0x9C :
- return "\xED\x98\xB6";
- break;
- case 0xB8 :
- return "\xED\x99\x92";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xAE";
- break;
- case 0xB0 :
- return "\xED\x9A\x8A";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\xA6";
- break;
- case 0xA8 :
- return "\xED\x9B\x82";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x9E";
- break;
- case 0xA0 :
- return "\xED\x9B\xBA";
- break;
- case 0xBC :
- return "\xED\x9C\x96";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xB2";
- break;
- case 0xB4 :
- return "\xED\x9D\x8E";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xAA";
- break;
- case 0xAC :
- return "\xED\x9E\x86";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\xA2";
- }
- break;
- }
- break;
- }
- break;
- case 0x82 :
- switch (prefix[0]) {
- case 0xEA :
- switch (prefix[1]) {
- case 0xB0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB0\x9B";
- break;
- case 0x9C :
- return "\xEA\xB0\xB7";
- break;
- case 0xB8 :
- return "\xEA\xB1\x93";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB1\xAF";
- break;
- case 0xB0 :
- return "\xEA\xB2\x8B";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB2\xA7";
- break;
- case 0xA8 :
- return "\xEA\xB3\x83";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xB3\x9F";
- break;
- case 0xA0 :
- return "\xEA\xB3\xBB";
- break;
- case 0xBC :
- return "\xEA\xB4\x97";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xB4\xB3";
- break;
- case 0xB4 :
- return "\xEA\xB5\x8F";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xB5\xAB";
- break;
- case 0xAC :
- return "\xEA\xB6\x87";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xB6\xA3";
- break;
- case 0xA4 :
- return "\xEA\xB6\xBF";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xB7\x9B";
- break;
- case 0x9C :
- return "\xEA\xB7\xB7";
- break;
- case 0xB8 :
- return "\xEA\xB8\x93";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xB8\xAF";
- break;
- case 0xB0 :
- return "\xEA\xB9\x8B";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEA\xB9\xA7";
- break;
- case 0xA8 :
- return "\xEA\xBA\x83";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEA\xBA\x9F";
- break;
- case 0xA0 :
- return "\xEA\xBA\xBB";
- break;
- case 0xBC :
- return "\xEA\xBB\x97";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEA\xBB\xB3";
- break;
- case 0xB4 :
- return "\xEA\xBC\x8F";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEA\xBC\xAB";
- break;
- case 0xAC :
- return "\xEA\xBD\x87";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEA\xBD\xA3";
- break;
- case 0xA4 :
- return "\xEA\xBD\xBF";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEA\xBE\x9B";
- break;
- case 0x9C :
- return "\xEA\xBE\xB7";
- break;
- case 0xB8 :
- return "\xEA\xBF\x93";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEA\xBF\xAF";
- break;
- case 0xB0 :
- return "\xEB\x80\x8B";
- break;
- }
- break;
- }
- break;
- case 0xEB :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x80\xA7";
- break;
- case 0xA8 :
- return "\xEB\x81\x83";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x81\x9F";
- break;
- case 0xA0 :
- return "\xEB\x81\xBB";
- break;
- case 0xBC :
- return "\xEB\x82\x97";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x82\xB3";
- break;
- case 0xB4 :
- return "\xEB\x83\x8F";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x83\xAB";
- break;
- case 0xAC :
- return "\xEB\x84\x87";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x84\xA3";
- break;
- case 0xA4 :
- return "\xEB\x84\xBF";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x85\x9B";
- break;
- case 0x9C :
- return "\xEB\x85\xB7";
- break;
- case 0xB8 :
- return "\xEB\x86\x93";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x86\xAF";
- break;
- case 0xB0 :
- return "\xEB\x87\x8B";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x87\xA7";
- break;
- case 0xA8 :
- return "\xEB\x88\x83";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x88\x9F";
- break;
- case 0xA0 :
- return "\xEB\x88\xBB";
- break;
- case 0xBC :
- return "\xEB\x89\x97";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x89\xB3";
- break;
- case 0xB4 :
- return "\xEB\x8A\x8F";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x8A\xAB";
- break;
- case 0xAC :
- return "\xEB\x8B\x87";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x8B\xA3";
- break;
- case 0xA4 :
- return "\xEB\x8B\xBF";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x8C\x9B";
- break;
- case 0x9C :
- return "\xEB\x8C\xB7";
- break;
- case 0xB8 :
- return "\xEB\x8D\x93";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x8D\xAF";
- break;
- case 0xB0 :
- return "\xEB\x8E\x8B";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x8E\xA7";
- break;
- case 0xA8 :
- return "\xEB\x8F\x83";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x8F\x9F";
- break;
- case 0xA0 :
- return "\xEB\x8F\xBB";
- break;
- case 0xBC :
- return "\xEB\x90\x97";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x90\xB3";
- break;
- case 0xB4 :
- return "\xEB\x91\x8F";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x91\xAB";
- break;
- case 0xAC :
- return "\xEB\x92\x87";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x92\xA3";
- break;
- case 0xA4 :
- return "\xEB\x92\xBF";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x93\x9B";
- break;
- case 0x9C :
- return "\xEB\x93\xB7";
- break;
- case 0xB8 :
- return "\xEB\x94\x93";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x94\xAF";
- break;
- case 0xB0 :
- return "\xEB\x95\x8B";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x95\xA7";
- break;
- case 0xA8 :
- return "\xEB\x96\x83";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x96\x9F";
- break;
- case 0xA0 :
- return "\xEB\x96\xBB";
- break;
- case 0xBC :
- return "\xEB\x97\x97";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x97\xB3";
- break;
- case 0xB4 :
- return "\xEB\x98\x8F";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x98\xAB";
- break;
- case 0xAC :
- return "\xEB\x99\x87";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\x99\xA3";
- break;
- case 0xA4 :
- return "\xEB\x99\xBF";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\x9A\x9B";
- break;
- case 0x9C :
- return "\xEB\x9A\xB7";
- break;
- case 0xB8 :
- return "\xEB\x9B\x93";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\x9B\xAF";
- break;
- case 0xB0 :
- return "\xEB\x9C\x8B";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\x9C\xA7";
- break;
- case 0xA8 :
- return "\xEB\x9D\x83";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\x9D\x9F";
- break;
- case 0xA0 :
- return "\xEB\x9D\xBB";
- break;
- case 0xBC :
- return "\xEB\x9E\x97";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\x9E\xB3";
- break;
- case 0xB4 :
- return "\xEB\x9F\x8F";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\x9F\xAB";
- break;
- case 0xAC :
- return "\xEB\xA0\x87";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA0\xA3";
- break;
- case 0xA4 :
- return "\xEB\xA0\xBF";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA1\x9B";
- break;
- case 0x9C :
- return "\xEB\xA1\xB7";
- break;
- case 0xB8 :
- return "\xEB\xA2\x93";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA2\xAF";
- break;
- case 0xB0 :
- return "\xEB\xA3\x8B";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xA3\xA7";
- break;
- case 0xA8 :
- return "\xEB\xA4\x83";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xA4\x9F";
- break;
- case 0xA0 :
- return "\xEB\xA4\xBB";
- break;
- case 0xBC :
- return "\xEB\xA5\x97";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xA5\xB3";
- break;
- case 0xB4 :
- return "\xEB\xA6\x8F";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xA6\xAB";
- break;
- case 0xAC :
- return "\xEB\xA7\x87";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xA7\xA3";
- break;
- case 0xA4 :
- return "\xEB\xA7\xBF";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xA8\x9B";
- break;
- case 0x9C :
- return "\xEB\xA8\xB7";
- break;
- case 0xB8 :
- return "\xEB\xA9\x93";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xA9\xAF";
- break;
- case 0xB0 :
- return "\xEB\xAA\x8B";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xAA\xA7";
- break;
- case 0xA8 :
- return "\xEB\xAB\x83";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xAB\x9F";
- break;
- case 0xA0 :
- return "\xEB\xAB\xBB";
- break;
- case 0xBC :
- return "\xEB\xAC\x97";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xAC\xB3";
- break;
- case 0xB4 :
- return "\xEB\xAD\x8F";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xAD\xAB";
- break;
- case 0xAC :
- return "\xEB\xAE\x87";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xAE\xA3";
- break;
- case 0xA4 :
- return "\xEB\xAE\xBF";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xAF\x9B";
- break;
- case 0x9C :
- return "\xEB\xAF\xB7";
- break;
- case 0xB8 :
- return "\xEB\xB0\x93";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB0\xAF";
- break;
- case 0xB0 :
- return "\xEB\xB1\x8B";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB1\xA7";
- break;
- case 0xA8 :
- return "\xEB\xB2\x83";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB2\x9F";
- break;
- case 0xA0 :
- return "\xEB\xB2\xBB";
- break;
- case 0xBC :
- return "\xEB\xB3\x97";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xB3\xB3";
- break;
- case 0xB4 :
- return "\xEB\xB4\x8F";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xB4\xAB";
- break;
- case 0xAC :
- return "\xEB\xB5\x87";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xB5\xA3";
- break;
- case 0xA4 :
- return "\xEB\xB5\xBF";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xB6\x9B";
- break;
- case 0x9C :
- return "\xEB\xB6\xB7";
- break;
- case 0xB8 :
- return "\xEB\xB7\x93";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xB7\xAF";
- break;
- case 0xB0 :
- return "\xEB\xB8\x8B";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xB8\xA7";
- break;
- case 0xA8 :
- return "\xEB\xB9\x83";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEB\xB9\x9F";
- break;
- case 0xA0 :
- return "\xEB\xB9\xBB";
- break;
- case 0xBC :
- return "\xEB\xBA\x97";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEB\xBA\xB3";
- break;
- case 0xB4 :
- return "\xEB\xBB\x8F";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEB\xBB\xAB";
- break;
- case 0xAC :
- return "\xEB\xBC\x87";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEB\xBC\xA3";
- break;
- case 0xA4 :
- return "\xEB\xBC\xBF";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEB\xBD\x9B";
- break;
- case 0x9C :
- return "\xEB\xBD\xB7";
- break;
- case 0xB8 :
- return "\xEB\xBE\x93";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEB\xBE\xAF";
- break;
- case 0xB0 :
- return "\xEB\xBF\x8B";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEB\xBF\xA7";
- break;
- case 0xA8 :
- return "\xEC\x80\x83";
- break;
- }
- break;
- }
- break;
- case 0xEC :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x80\x9F";
- break;
- case 0xA0 :
- return "\xEC\x80\xBB";
- break;
- case 0xBC :
- return "\xEC\x81\x97";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x81\xB3";
- break;
- case 0xB4 :
- return "\xEC\x82\x8F";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x82\xAB";
- break;
- case 0xAC :
- return "\xEC\x83\x87";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x83\xA3";
- break;
- case 0xA4 :
- return "\xEC\x83\xBF";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x84\x9B";
- break;
- case 0x9C :
- return "\xEC\x84\xB7";
- break;
- case 0xB8 :
- return "\xEC\x85\x93";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x85\xAF";
- break;
- case 0xB0 :
- return "\xEC\x86\x8B";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x86\xA7";
- break;
- case 0xA8 :
- return "\xEC\x87\x83";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x87\x9F";
- break;
- case 0xA0 :
- return "\xEC\x87\xBB";
- break;
- case 0xBC :
- return "\xEC\x88\x97";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x88\xB3";
- break;
- case 0xB4 :
- return "\xEC\x89\x8F";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x89\xAB";
- break;
- case 0xAC :
- return "\xEC\x8A\x87";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x8A\xA3";
- break;
- case 0xA4 :
- return "\xEC\x8A\xBF";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x8B\x9B";
- break;
- case 0x9C :
- return "\xEC\x8B\xB7";
- break;
- case 0xB8 :
- return "\xEC\x8C\x93";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x8C\xAF";
- break;
- case 0xB0 :
- return "\xEC\x8D\x8B";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x8D\xA7";
- break;
- case 0xA8 :
- return "\xEC\x8E\x83";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x8E\x9F";
- break;
- case 0xA0 :
- return "\xEC\x8E\xBB";
- break;
- case 0xBC :
- return "\xEC\x8F\x97";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x8F\xB3";
- break;
- case 0xB4 :
- return "\xEC\x90\x8F";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x90\xAB";
- break;
- case 0xAC :
- return "\xEC\x91\x87";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x91\xA3";
- break;
- case 0xA4 :
- return "\xEC\x91\xBF";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x92\x9B";
- break;
- case 0x9C :
- return "\xEC\x92\xB7";
- break;
- case 0xB8 :
- return "\xEC\x93\x93";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x93\xAF";
- break;
- case 0xB0 :
- return "\xEC\x94\x8B";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x94\xA7";
- break;
- case 0xA8 :
- return "\xEC\x95\x83";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x95\x9F";
- break;
- case 0xA0 :
- return "\xEC\x95\xBB";
- break;
- case 0xBC :
- return "\xEC\x96\x97";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x96\xB3";
- break;
- case 0xB4 :
- return "\xEC\x97\x8F";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x97\xAB";
- break;
- case 0xAC :
- return "\xEC\x98\x87";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x98\xA3";
- break;
- case 0xA4 :
- return "\xEC\x98\xBF";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\x99\x9B";
- break;
- case 0x9C :
- return "\xEC\x99\xB7";
- break;
- case 0xB8 :
- return "\xEC\x9A\x93";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\x9A\xAF";
- break;
- case 0xB0 :
- return "\xEC\x9B\x8B";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\x9B\xA7";
- break;
- case 0xA8 :
- return "\xEC\x9C\x83";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\x9C\x9F";
- break;
- case 0xA0 :
- return "\xEC\x9C\xBB";
- break;
- case 0xBC :
- return "\xEC\x9D\x97";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\x9D\xB3";
- break;
- case 0xB4 :
- return "\xEC\x9E\x8F";
- break;
- }
- break;
- case 0x9E :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\x9E\xAB";
- break;
- case 0xAC :
- return "\xEC\x9F\x87";
- break;
- }
- break;
- case 0x9F :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\x9F\xA3";
- break;
- case 0xA4 :
- return "\xEC\x9F\xBF";
- break;
- }
- break;
- case 0xA0 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA0\x9B";
- break;
- case 0x9C :
- return "\xEC\xA0\xB7";
- break;
- case 0xB8 :
- return "\xEC\xA1\x93";
- break;
- }
- break;
- case 0xA1 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA1\xAF";
- break;
- case 0xB0 :
- return "\xEC\xA2\x8B";
- break;
- }
- break;
- case 0xA2 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA2\xA7";
- break;
- case 0xA8 :
- return "\xEC\xA3\x83";
- break;
- }
- break;
- case 0xA3 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xA3\x9F";
- break;
- case 0xA0 :
- return "\xEC\xA3\xBB";
- break;
- case 0xBC :
- return "\xEC\xA4\x97";
- break;
- }
- break;
- case 0xA4 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xA4\xB3";
- break;
- case 0xB4 :
- return "\xEC\xA5\x8F";
- break;
- }
- break;
- case 0xA5 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xA5\xAB";
- break;
- case 0xAC :
- return "\xEC\xA6\x87";
- break;
- }
- break;
- case 0xA6 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xA6\xA3";
- break;
- case 0xA4 :
- return "\xEC\xA6\xBF";
- break;
- }
- break;
- case 0xA7 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xA7\x9B";
- break;
- case 0x9C :
- return "\xEC\xA7\xB7";
- break;
- case 0xB8 :
- return "\xEC\xA8\x93";
- break;
- }
- break;
- case 0xA8 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xA8\xAF";
- break;
- case 0xB0 :
- return "\xEC\xA9\x8B";
- break;
- }
- break;
- case 0xA9 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xA9\xA7";
- break;
- case 0xA8 :
- return "\xEC\xAA\x83";
- break;
- }
- break;
- case 0xAA :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xAA\x9F";
- break;
- case 0xA0 :
- return "\xEC\xAA\xBB";
- break;
- case 0xBC :
- return "\xEC\xAB\x97";
- break;
- }
- break;
- case 0xAB :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xAB\xB3";
- break;
- case 0xB4 :
- return "\xEC\xAC\x8F";
- break;
- }
- break;
- case 0xAC :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xAC\xAB";
- break;
- case 0xAC :
- return "\xEC\xAD\x87";
- break;
- }
- break;
- case 0xAD :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xAD\xA3";
- break;
- case 0xA4 :
- return "\xEC\xAD\xBF";
- break;
- }
- break;
- case 0xAE :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xAE\x9B";
- break;
- case 0x9C :
- return "\xEC\xAE\xB7";
- break;
- case 0xB8 :
- return "\xEC\xAF\x93";
- break;
- }
- break;
- case 0xAF :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xAF\xAF";
- break;
- case 0xB0 :
- return "\xEC\xB0\x8B";
- break;
- }
- break;
- case 0xB0 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB0\xA7";
- break;
- case 0xA8 :
- return "\xEC\xB1\x83";
- break;
- }
- break;
- case 0xB1 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB1\x9F";
- break;
- case 0xA0 :
- return "\xEC\xB1\xBB";
- break;
- case 0xBC :
- return "\xEC\xB2\x97";
- break;
- }
- break;
- case 0xB2 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB2\xB3";
- break;
- case 0xB4 :
- return "\xEC\xB3\x8F";
- break;
- }
- break;
- case 0xB3 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xB3\xAB";
- break;
- case 0xAC :
- return "\xEC\xB4\x87";
- break;
- }
- break;
- case 0xB4 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xB4\xA3";
- break;
- case 0xA4 :
- return "\xEC\xB4\xBF";
- break;
- }
- break;
- case 0xB5 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xB5\x9B";
- break;
- case 0x9C :
- return "\xEC\xB5\xB7";
- break;
- case 0xB8 :
- return "\xEC\xB6\x93";
- break;
- }
- break;
- case 0xB6 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xB6\xAF";
- break;
- case 0xB0 :
- return "\xEC\xB7\x8B";
- break;
- }
- break;
- case 0xB7 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xB7\xA7";
- break;
- case 0xA8 :
- return "\xEC\xB8\x83";
- break;
- }
- break;
- case 0xB8 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xB8\x9F";
- break;
- case 0xA0 :
- return "\xEC\xB8\xBB";
- break;
- case 0xBC :
- return "\xEC\xB9\x97";
- break;
- }
- break;
- case 0xB9 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xEC\xB9\xB3";
- break;
- case 0xB4 :
- return "\xEC\xBA\x8F";
- break;
- }
- break;
- case 0xBA :
- switch (prefix[2]) {
- case 0x90 :
- return "\xEC\xBA\xAB";
- break;
- case 0xAC :
- return "\xEC\xBB\x87";
- break;
- }
- break;
- case 0xBB :
- switch (prefix[2]) {
- case 0x88 :
- return "\xEC\xBB\xA3";
- break;
- case 0xA4 :
- return "\xEC\xBB\xBF";
- break;
- }
- break;
- case 0xBC :
- switch (prefix[2]) {
- case 0x80 :
- return "\xEC\xBC\x9B";
- break;
- case 0x9C :
- return "\xEC\xBC\xB7";
- break;
- case 0xB8 :
- return "\xEC\xBD\x93";
- break;
- }
- break;
- case 0xBD :
- switch (prefix[2]) {
- case 0x94 :
- return "\xEC\xBD\xAF";
- break;
- case 0xB0 :
- return "\xEC\xBE\x8B";
- break;
- }
- break;
- case 0xBE :
- switch (prefix[2]) {
- case 0x8C :
- return "\xEC\xBE\xA7";
- break;
- case 0xA8 :
- return "\xEC\xBF\x83";
- break;
- }
- break;
- case 0xBF :
- switch (prefix[2]) {
- case 0x84 :
- return "\xEC\xBF\x9F";
- break;
- case 0xA0 :
- return "\xEC\xBF\xBB";
- break;
- case 0xBC :
- return "\xED\x80\x97";
- break;
- }
- break;
- }
- break;
- case 0xED :
- switch (prefix[1]) {
- case 0x80 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x80\xB3";
- break;
- case 0xB4 :
- return "\xED\x81\x8F";
- break;
- }
- break;
- case 0x81 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x81\xAB";
- break;
- case 0xAC :
- return "\xED\x82\x87";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x82\xA3";
- break;
- case 0xA4 :
- return "\xED\x82\xBF";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x83\x9B";
- break;
- case 0x9C :
- return "\xED\x83\xB7";
- break;
- case 0xB8 :
- return "\xED\x84\x93";
- break;
- }
- break;
- case 0x84 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x84\xAF";
- break;
- case 0xB0 :
- return "\xED\x85\x8B";
- break;
- }
- break;
- case 0x85 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x85\xA7";
- break;
- case 0xA8 :
- return "\xED\x86\x83";
- break;
- }
- break;
- case 0x86 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x86\x9F";
- break;
- case 0xA0 :
- return "\xED\x86\xBB";
- break;
- case 0xBC :
- return "\xED\x87\x97";
- break;
- }
- break;
- case 0x87 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x87\xB3";
- break;
- case 0xB4 :
- return "\xED\x88\x8F";
- break;
- }
- break;
- case 0x88 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x88\xAB";
- break;
- case 0xAC :
- return "\xED\x89\x87";
- break;
- }
- break;
- case 0x89 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x89\xA3";
- break;
- case 0xA4 :
- return "\xED\x89\xBF";
- break;
- }
- break;
- case 0x8A :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x8A\x9B";
- break;
- case 0x9C :
- return "\xED\x8A\xB7";
- break;
- case 0xB8 :
- return "\xED\x8B\x93";
- break;
- }
- break;
- case 0x8B :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x8B\xAF";
- break;
- case 0xB0 :
- return "\xED\x8C\x8B";
- break;
- }
- break;
- case 0x8C :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x8C\xA7";
- break;
- case 0xA8 :
- return "\xED\x8D\x83";
- break;
- }
- break;
- case 0x8D :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x8D\x9F";
- break;
- case 0xA0 :
- return "\xED\x8D\xBB";
- break;
- case 0xBC :
- return "\xED\x8E\x97";
- break;
- }
- break;
- case 0x8E :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x8E\xB3";
- break;
- case 0xB4 :
- return "\xED\x8F\x8F";
- break;
- }
- break;
- case 0x8F :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x8F\xAB";
- break;
- case 0xAC :
- return "\xED\x90\x87";
- break;
- }
- break;
- case 0x90 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x90\xA3";
- break;
- case 0xA4 :
- return "\xED\x90\xBF";
- break;
- }
- break;
- case 0x91 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x91\x9B";
- break;
- case 0x9C :
- return "\xED\x91\xB7";
- break;
- case 0xB8 :
- return "\xED\x92\x93";
- break;
- }
- break;
- case 0x92 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x92\xAF";
- break;
- case 0xB0 :
- return "\xED\x93\x8B";
- break;
- }
- break;
- case 0x93 :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x93\xA7";
- break;
- case 0xA8 :
- return "\xED\x94\x83";
- break;
- }
- break;
- case 0x94 :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x94\x9F";
- break;
- case 0xA0 :
- return "\xED\x94\xBB";
- break;
- case 0xBC :
- return "\xED\x95\x97";
- break;
- }
- break;
- case 0x95 :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x95\xB3";
- break;
- case 0xB4 :
- return "\xED\x96\x8F";
- break;
- }
- break;
- case 0x96 :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x96\xAB";
- break;
- case 0xAC :
- return "\xED\x97\x87";
- break;
- }
- break;
- case 0x97 :
- switch (prefix[2]) {
- case 0x88 :
- return "\xED\x97\xA3";
- break;
- case 0xA4 :
- return "\xED\x97\xBF";
- break;
- }
- break;
- case 0x98 :
- switch (prefix[2]) {
- case 0x80 :
- return "\xED\x98\x9B";
- break;
- case 0x9C :
- return "\xED\x98\xB7";
- break;
- case 0xB8 :
- return "\xED\x99\x93";
- break;
- }
- break;
- case 0x99 :
- switch (prefix[2]) {
- case 0x94 :
- return "\xED\x99\xAF";
- break;
- case 0xB0 :
- return "\xED\x9A\x8B";
- break;
- }
- break;
- case 0x9A :
- switch (prefix[2]) {
- case 0x8C :
- return "\xED\x9A\xA7";
- break;
- case 0xA8 :
- return "\xED\x9B\x83";
- break;
- }
- break;
- case 0x9B :
- switch (prefix[2]) {
- case 0x84 :
- return "\xED\x9B\x9F";
- break;
- case 0xA0 :
- return "\xED\x9B\xBB";
- break;
- case 0xBC :
- return "\xED\x9C\x97";
- break;
- }
- break;
- case 0x9C :
- switch (prefix[2]) {
- case 0x98 :
- return "\xED\x9C\xB3";
- break;
- case 0xB4 :
- return "\xED\x9D\x8F";
- break;
- }
- break;
- case 0x9D :
- switch (prefix[2]) {
- case 0x90 :
- return "\xED\x9D\xAB";
- break;
- case 0xAC :
- return "\xED\x9E\x87";
- break;
- }
- break;
- case 0x9E :
- if (prefix[2] == 0x88) {
- return "\xED\x9E\xA3";
- }
- break;
- }
- break;
- }
- break;
- }
- break;
- case 0xAC :
- if (suffix[2] == 0xB5) {
- if (prefix[0] == 0xE1) {
- switch (prefix[1]) {
- case 0xAC :
- switch (prefix[2]) {
- case 0x85 :
- return "\xE1\xAC\x86";
- break;
- case 0x87 :
- return "\xE1\xAC\x88";
- break;
- case 0x89 :
- return "\xE1\xAC\x8A";
- break;
- case 0x8B :
- return "\xE1\xAC\x8C";
- break;
- case 0x8D :
- return "\xE1\xAC\x8E";
- break;
- case 0x91 :
- return "\xE1\xAC\x92";
- break;
- case 0xBA :
- return "\xE1\xAC\xBB";
- break;
- case 0xBC :
- return "\xE1\xAC\xBD";
- break;
- case 0xBE :
- return "\xE1\xAD\x80";
- break;
- case 0xBF :
- return "\xE1\xAD\x81";
- break;
- }
- break;
- case 0xAD :
- if (prefix[2] == 0x82) {
- return "\xE1\xAD\x83";
- }
- break;
- }
- }
- }
- break;
- }
- break;
-case 0xE3 :
- if (suffix[1] == 0x82) {
- switch (suffix[2]) {
- case 0x99 :
- if (prefix[0] == 0xE3) {
- switch (prefix[1]) {
- case 0x81 :
- switch (prefix[2]) {
- case 0x86 :
- return "\xE3\x82\x94";
- break;
- case 0x8B :
- return "\xE3\x81\x8C";
- break;
- case 0x8D :
- return "\xE3\x81\x8E";
- break;
- case 0x8F :
- return "\xE3\x81\x90";
- break;
- case 0x91 :
- return "\xE3\x81\x92";
- break;
- case 0x93 :
- return "\xE3\x81\x94";
- break;
- case 0x95 :
- return "\xE3\x81\x96";
- break;
- case 0x97 :
- return "\xE3\x81\x98";
- break;
- case 0x99 :
- return "\xE3\x81\x9A";
- break;
- case 0x9B :
- return "\xE3\x81\x9C";
- break;
- case 0x9D :
- return "\xE3\x81\x9E";
- break;
- case 0x9F :
- return "\xE3\x81\xA0";
- break;
- case 0xA1 :
- return "\xE3\x81\xA2";
- break;
- case 0xA4 :
- return "\xE3\x81\xA5";
- break;
- case 0xA6 :
- return "\xE3\x81\xA7";
- break;
- case 0xA8 :
- return "\xE3\x81\xA9";
- break;
- case 0xAF :
- return "\xE3\x81\xB0";
- break;
- case 0xB2 :
- return "\xE3\x81\xB3";
- break;
- case 0xB5 :
- return "\xE3\x81\xB6";
- break;
- case 0xB8 :
- return "\xE3\x81\xB9";
- break;
- case 0xBB :
- return "\xE3\x81\xBC";
- break;
- }
- break;
- case 0x82 :
- switch (prefix[2]) {
- case 0x9D :
- return "\xE3\x82\x9E";
- break;
- case 0xA6 :
- return "\xE3\x83\xB4";
- break;
- case 0xAB :
- return "\xE3\x82\xAC";
- break;
- case 0xAD :
- return "\xE3\x82\xAE";
- break;
- case 0xAF :
- return "\xE3\x82\xB0";
- break;
- case 0xB1 :
- return "\xE3\x82\xB2";
- break;
- case 0xB3 :
- return "\xE3\x82\xB4";
- break;
- case 0xB5 :
- return "\xE3\x82\xB6";
- break;
- case 0xB7 :
- return "\xE3\x82\xB8";
- break;
- case 0xB9 :
- return "\xE3\x82\xBA";
- break;
- case 0xBB :
- return "\xE3\x82\xBC";
- break;
- case 0xBD :
- return "\xE3\x82\xBE";
- break;
- case 0xBF :
- return "\xE3\x83\x80";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x81 :
- return "\xE3\x83\x82";
- break;
- case 0x84 :
- return "\xE3\x83\x85";
- break;
- case 0x86 :
- return "\xE3\x83\x87";
- break;
- case 0x88 :
- return "\xE3\x83\x89";
- break;
- case 0x8F :
- return "\xE3\x83\x90";
- break;
- case 0x92 :
- return "\xE3\x83\x93";
- break;
- case 0x95 :
- return "\xE3\x83\x96";
- break;
- case 0x98 :
- return "\xE3\x83\x99";
- break;
- case 0x9B :
- return "\xE3\x83\x9C";
- break;
- case 0xAF :
- return "\xE3\x83\xB7";
- break;
- case 0xB0 :
- return "\xE3\x83\xB8";
- break;
- case 0xB1 :
- return "\xE3\x83\xB9";
- break;
- case 0xB2 :
- return "\xE3\x83\xBA";
- break;
- case 0xBD :
- return "\xE3\x83\xBE";
- break;
- }
- break;
- }
- }
- break;
- case 0x9A :
- if (prefix[0] == 0xE3) {
- switch (prefix[1]) {
- case 0x81 :
- switch (prefix[2]) {
- case 0xAF :
- return "\xE3\x81\xB1";
- break;
- case 0xB2 :
- return "\xE3\x81\xB4";
- break;
- case 0xB5 :
- return "\xE3\x81\xB7";
- break;
- case 0xB8 :
- return "\xE3\x81\xBA";
- break;
- case 0xBB :
- return "\xE3\x81\xBD";
- break;
- }
- break;
- case 0x83 :
- switch (prefix[2]) {
- case 0x8F :
- return "\xE3\x83\x91";
- break;
- case 0x92 :
- return "\xE3\x83\x94";
- break;
- case 0x95 :
- return "\xE3\x83\x97";
- break;
- case 0x98 :
- return "\xE3\x83\x9A";
- break;
- case 0x9B :
- return "\xE3\x83\x9D";
- break;
- }
- break;
- }
- }
- break;
- }
- }
- break;
-}
- return 0;
+ return grn_nfkc50_compose(prefix_utf8, suffix_utf8);
}
#endif /* GRN_WITH_NFKC */
diff --git a/storage/mroonga/vendor/groonga/lib/nfkc.rb b/storage/mroonga/vendor/groonga/lib/nfkc.rb
index 1a134384c80..9ad25bba9ff 100755
--- a/storage/mroonga/vendor/groonga/lib/nfkc.rb
+++ b/storage/mroonga/vendor/groonga/lib/nfkc.rb
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
#
-# Copyright(C) 2010 Brazil
+# Copyright(C) 2010-2016 Brazil
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -16,80 +16,701 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-$KCODE = 'u'
-
CUSTOM_RULE_PATH = 'nfkc-custom-rules.txt'
-def gen_bc(file, hash, level)
- bl = ' ' * (level * 2)
- h2 = {}
- hash.each{|key,val|
- head = key[0]
- rest = key[1..-1]
- if h2[head]
- h2[head][rest] = val
+class SwitchGenerator
+ def initialize(unicode_version, output)
+ @unicode_version = unicode_version
+ @output = output
+ end
+
+ def generate(bc, decompose_map, compose_map)
+ STDERR.puts('generating char type code..')
+ generate_blockcode_char_type(bc)
+ STDERR.puts('generating decompose code..')
+ generate_decompose(decompose_map)
+ STDERR.puts('generating compose code..')
+ generate_compose(compose_map)
+ end
+
+ private
+ def generate_blockcode_char_type(bc)
+ @output.puts(<<-HEADER)
+
+grn_char_type
+grn_nfkc#{@unicode_version}_char_type(const unsigned char *str)
+{
+ HEADER
+
+ @lv = 0
+ gen_bc(bc, 0)
+
+ @output.puts(<<-FOOTER)
+ return -1;
+}
+ FOOTER
+ end
+
+ def gen_bc(hash, level)
+ bl = ' ' * (level * 2)
+ h2 = {}
+ hash.each{|key,val|
+ key = key.dup
+ key.force_encoding("ASCII-8BIT")
+ head = key.bytes[0]
+ rest = key[1..-1]
+ if h2[head]
+ h2[head][rest] = val
+ else
+ h2[head] = {rest => val}
+ end
+ }
+ if h2.size < 3
+ h2.keys.sort.each{|k|
+ if (0x80 < k)
+ @output.printf("#{bl}if (str[#{level}] < 0x%02X) { return #{@lv}; }\n", k)
+ end
+ h = h2[k]
+ if h.keys.join =~ /^\x80*$/n
+ @lv, = h.values
+ else
+ @output.printf("#{bl}if (str[#{level}] == 0x%02X) {\n", k)
+ gen_bc(h, level + 1)
+ @output.puts bl + '}'
+ end
+ }
+ @output.puts bl + "return #{@lv};"
else
- h2[head] = {rest => val}
+ @output.puts bl + "switch (str[#{level}]) {"
+ lk = 0x80
+ br = true
+ h2.keys.sort.each{|k|
+ if (lk < k)
+ for j in lk..k-1
+ @output.printf("#{bl}case 0x%02X :\n", j)
+ end
+ br = false
+ end
+ unless br
+ @output.puts bl + " return #{@lv};"
+ @output.puts bl + ' break;'
+ end
+ h = h2[k]
+ @output.printf("#{bl}case 0x%02X :\n", k)
+ if h.keys.join =~ /^\x80*$/n
+ @lv, = h.values
+ br = false
+ else
+ gen_bc(h, level + 1)
+ @output.puts bl + ' break;'
+ br = true
+ end
+ lk = k + 1
+ }
+ @output.puts bl + 'default :'
+ @output.puts bl + " return #{@lv};"
+ @output.puts bl + ' break;'
+ @output.puts bl + '}'
end
- }
- if h2.size < 3
- h2.keys.sort.each{|k|
- if (0x80 < k)
- file.printf("#{bl}if (str[#{level}] < 0x%02X) { return #{$lv}; }\n", k)
+ end
+
+ def generate_decompose(hash)
+ @output.puts(<<-HEADER)
+
+const char *
+grn_nfkc#{@unicode_version}_decompose(const unsigned char *str)
+{
+ HEADER
+
+ gen_decompose(hash, 0)
+
+ @output.puts(<<-FOOTER)
+ return 0;
+}
+ FOOTER
+ end
+
+ def gen_decompose(hash, level)
+ bl = ' ' * ((level + 0) * 2)
+ if hash['']
+ dst = ''
+ hash[''].each_byte{|b| dst << format('\x%02X', b)}
+ @output.puts "#{bl}return \"#{dst}\";"
+ hash.delete('')
+ end
+ return if hash.empty?
+ h2 = {}
+ hash.each{|key,val|
+ key = key.dup
+ key.force_encoding("ASCII-8BIT")
+ head = key.bytes[0]
+ rest = key[1..-1]
+ if h2[head]
+ h2[head][rest] = val
+ else
+ h2[head] = {rest => val}
end
- h = h2[k]
- if h.keys.join =~ /^\x80*$/
- $lv, = h.values
+ }
+ if h2.size == 1
+ h2.each{|key,val|
+ @output.printf("#{bl}if (str[#{level}] == 0x%02X) {\n", key)
+ gen_decompose(val, level + 1)
+ @output.puts bl + '}'
+ }
+ else
+ @output.puts "#{bl}switch (str[#{level}]) {"
+ h2.keys.sort.each{|k|
+ @output.printf("#{bl}case 0x%02X :\n", k)
+ gen_decompose(h2[k], level + 1)
+ @output.puts("#{bl} break;")
+ }
+ @output.puts bl + '}'
+ end
+ end
+
+ def generate_compose(compose_map)
+ @output.puts(<<-HEADER)
+
+const char *
+grn_nfkc#{@unicode_version}_compose(const unsigned char *prefix, const unsigned char *suffix)
+{
+ HEADER
+ suffix = {}
+ compose_map.each{|src,dst|
+ chars = src.chars
+ if chars.size != 2
+ STDERR.puts "caution: more than two chars in pattern #{chars.join('|')}"
+ end
+ s = chars.pop
+ if suffix[s]
+ suffix[s][chars.join] = dst
else
- file.printf("#{bl}if (str[#{level}] == 0x%02X) {\n", k)
- gen_bc(file, h, level + 1)
- file.puts bl + '}'
+ suffix[s] = {chars.join=>dst}
end
}
- file.puts bl + "return #{$lv};"
- else
- file.puts bl + "switch (str[#{level}]) {"
- lk = 0x80
- br = true
- h2.keys.sort.each{|k|
- if (lk < k)
- for j in lk..k-1
- file.printf("#{bl}case 0x%02X :\n", j)
+ gen_compose_sub(suffix, 0)
+ @output.puts(<<-FOOTER)
+ return 0;
+}
+ FOOTER
+ end
+
+ def gen_compose_sub2(hash, level, indent)
+ bl = ' ' * ((level + indent + 0) * 2)
+ if hash['']
+ @output.print "#{bl}return \""
+ hash[''].each_byte{|b| @output.printf('\x%02X', b)}
+ @output.puts "\";"
+ hash.delete('')
+ end
+ return if hash.empty?
+
+ h2 = {}
+ hash.each{|key,val|
+ key = key.dup
+ key.force_encoding("ASCII-8BIT")
+ head = key.bytes[0]
+ rest = key[1..-1]
+ if h2[head]
+ h2[head][rest] = val
+ else
+ h2[head] = {rest => val}
+ end
+ }
+
+ if h2.size == 1
+ h2.each{|key,val|
+ @output.printf("#{bl}if (prefix[#{level}] == 0x%02X) {\n", key)
+ gen_compose_sub2(val, level + 1, indent)
+ @output.puts bl + '}'
+ }
+ else
+ @output.puts "#{bl}switch (prefix[#{level}]) {"
+ h2.keys.sort.each{|k|
+ @output.printf("#{bl}case 0x%02X :\n", k)
+ gen_compose_sub2(h2[k], level + 1, indent)
+ @output.puts("#{bl} break;")
+ }
+ @output.puts bl + '}'
+ end
+ end
+
+ def gen_compose_sub(hash, level)
+ bl = ' ' * ((level + 0) * 2)
+ if hash['']
+ gen_compose_sub2(hash[''], 0, level)
+ hash.delete('')
+ end
+ return if hash.empty?
+ h2 = {}
+ hash.each{|key,val|
+ key = key.dup
+ key.force_encoding("ASCII-8BIT")
+ head = key.bytes[0]
+ rest = key[1..-1]
+ if h2[head]
+ h2[head][rest] = val
+ else
+ h2[head] = {rest => val}
+ end
+ }
+ if h2.size == 1
+ h2.each{|key,val|
+ @output.printf("#{bl}if (suffix[#{level}] == 0x%02X) {\n", key)
+ gen_compose_sub(val, level + 1)
+ @output.puts bl + '}'
+ }
+ else
+ @output.puts "#{bl}switch (suffix[#{level}]) {"
+ h2.keys.sort.each{|k|
+ @output.printf("#{bl}case 0x%02X :\n", k)
+ gen_compose_sub(h2[k], level + 1)
+ @output.puts("#{bl} break;")
+ }
+ @output.puts bl + '}'
+ end
+ end
+end
+
+class TableGenerator < SwitchGenerator
+ private
+ def name_prefix
+ "grn_nfkc#{@unicode_version}_"
+ end
+
+ def table_name(type, common_bytes)
+ suffix = common_bytes.collect {|byte| "%02x" % byte}.join("")
+ "#{name_prefix}#{type}_table_#{suffix}"
+ end
+
+ def function_name(type)
+ "#{name_prefix}#{type}"
+ end
+
+ def generate_char_convert_tables(type, return_type, byte_size_groups)
+ if return_type.end_with?("*")
+ space = ""
+ else
+ space = " "
+ end
+ byte_size_groups.keys.sort.each do |common_bytes|
+ chars = byte_size_groups[common_bytes]
+ lines = []
+ all_values = []
+ last_bytes = chars.collect {|char| char.bytes.last}
+ last_bytes.min.step(last_bytes.max).each_slice(8) do |slice|
+ values = slice.collect do |last_byte|
+ char = (common_bytes + [last_byte]).pack("c*")
+ char.force_encoding("UTF-8")
+ yield(char)
+ end
+ all_values.concat(values)
+ lines << (" " + values.join(", "))
+ end
+
+ next if all_values.uniq.size == 1
+
+ @output.puts(<<-TABLE_HEADER)
+
+static #{return_type}#{space}#{table_name(type, common_bytes)}[] = {
+ TABLE_HEADER
+ @output.puts(lines.join(",\n"))
+ @output.puts(<<-TABLE_FOOTER)
+};
+ TABLE_FOOTER
+ end
+ end
+
+ def generate_char_convert_function(type,
+ argument_list,
+ char_variable,
+ default,
+ return_type,
+ byte_size_groups,
+ options={})
+ modifier = options[:internal] ? "static inline " : ""
+ @output.puts(<<-HEADER)
+
+#{modifier}#{return_type}
+#{function_name(type)}(#{argument_list})
+{
+ HEADER
+
+ prev_common_bytes = []
+ prev_n_common_bytes = 0
+ first_group = true
+ byte_size_groups.keys.sort.each do |common_bytes|
+ chars = byte_size_groups[common_bytes]
+ chars_bytes = chars.collect(&:bytes).sort
+ min = chars_bytes.first.last
+ max = chars_bytes.last.last
+ n_common_bytes = 0
+ if common_bytes.empty?
+ indent = " "
+ yield(:no_common_bytes, indent, chars, chars_bytes)
+ else
+ if first_group
+ @output.puts(<<-BODY)
+ {
+ BODY
+ end
+
+ found_different_byte = false
+ common_bytes.each_with_index do |common_byte, i|
+ unless found_different_byte
+ if prev_common_bytes[i] == common_byte
+ n_common_bytes += 1
+ next
+ end
+ found_different_byte = true
+ end
+ indent = " " * i
+ # p [i, prev_common_bytes.collect{|x| "%#04x" % x}, common_bytes.collect{|x| "%#04x" % x}, "%#04x" % common_byte, n_common_bytes, prev_n_common_bytes]
+ # TODO: The following code may be able to be simplified.
+ if prev_common_bytes[i].nil?
+ # p nil
+ @output.puts(<<-BODY)
+ #{indent}switch (#{char_variable}[#{i}]) {
+ BODY
+ elsif i < prev_n_common_bytes
+ # p :prev
+ @output.puts(<<-BODY)
+ #{indent} default :
+ #{indent} break;
+ #{indent} }
+ #{indent} break;
+ BODY
+ elsif n_common_bytes < prev_n_common_bytes
+ # p :common_prev
+ @output.puts(<<-BODY)
+ #{indent}switch (#{char_variable}[#{i}]) {
+ BODY
+ else
+ # p :else
+ prev_common_bytes.size.downto(common_bytes.size + 1) do |j|
+ sub_indent = " " * (j - 1)
+ @output.puts(<<-BODY)
+ #{indent}#{sub_indent}default :
+ #{indent}#{sub_indent} break;
+ #{indent}#{sub_indent}}
+ #{indent}#{sub_indent}break;
+ BODY
+ end
+ end
+ @output.puts(<<-BODY)
+ #{indent}case #{"%#04x" % common_byte} :
+ BODY
+ end
+
+ n = chars_bytes.first.size - 1
+ indent = " " + (" " * common_bytes.size)
+ yield(:have_common_bytes, indent, chars, chars_bytes, n, common_bytes)
+ end
+
+ prev_common_bytes = common_bytes
+ prev_n_common_bytes = n_common_bytes
+ first_group = false
+ end
+
+ # p [prev_common_bytes.collect{|x| "%#04x" % x}, prev_n_common_bytes]
+
+ (prev_common_bytes.size - 1).step(0, -1) do |i|
+ indent = " " * i
+ @output.puts(<<-BODY)
+ #{indent}default :
+ #{indent} break;
+ #{indent}}
+ BODY
+ if i > 0
+ @output.puts(<<-BODY)
+ #{indent}break;
+ BODY
+ end
+ end
+
+ @output.puts(<<-FOOTER)
+ }
+
+ return #{default};
+}
+ FOOTER
+ end
+
+ def generate_char_converter(type,
+ function_type,
+ char_map,
+ default,
+ return_type,
+ options={},
+ &converter)
+ byte_size_groups = char_map.keys.group_by do |from|
+ bytes = from.bytes
+ bytes[0..-2]
+ end
+
+ generate_char_convert_tables(type,
+ return_type,
+ byte_size_groups,
+ &converter)
+
+ char_variable = "utf8"
+ generate_char_convert_function(function_type,
+ "const unsigned char *#{char_variable}",
+ char_variable,
+ default,
+ return_type,
+ byte_size_groups,
+ options) do |state, *args|
+ case state
+ when :no_common_bytes
+ indent, chars, chars_bytes = args
+ if chars.size == 1
+ char = chars[0]
+ char_byte = chars_bytes.first.first
+ value = yield(char)
+ @output.puts(<<-BODY)
+#{indent}if (#{char_variable}[0] < 0x80) {
+#{indent} if (#{char_variable}[0] == #{"%#04x" % char_byte}) {
+#{indent} return #{value};
+#{indent} } else {
+#{indent} return #{default};
+#{indent} }
+#{indent}} else {
+ BODY
+ else
+ min = chars_bytes.first.first
+ max = chars_bytes.last.first
+ @output.puts(<<-BODY)
+#{indent}if (#{char_variable}[0] < 0x80) {
+#{indent} if (#{char_variable}[0] >= #{"%#04x" % min} &&
+#{indent} #{char_variable}[0] <= #{"%#04x" % max}) {
+#{indent} return #{table_name(type, [])}[#{char_variable}[0] - #{"%#04x" % min}];
+#{indent} } else {
+#{indent} return #{default};
+#{indent} }
+#{indent}} else {
+ BODY
+ end
+ when :have_common_bytes
+ indent, chars, chars_bytes, n, common_bytes = args
+ if chars.size == 1
+ char = chars[0]
+ char_byte = chars_bytes.first.last
+ value = yield(char)
+ @output.puts(<<-BODY)
+#{indent}if (#{char_variable}[#{n}] == #{"%#04x" % char_byte}) {
+#{indent} return #{value};
+#{indent}}
+#{indent}break;
+ BODY
+ else
+ sorted_chars = chars.sort
+ min = chars_bytes.first.last
+ max = chars_bytes.last.last
+ all_values = (min..max).collect do |last_byte|
+ char = (common_bytes + [last_byte]).pack("c*")
+ char.force_encoding("UTF-8")
+ yield(char)
+ end
+ if all_values.uniq.size == 1
+ value = all_values.first
+ else
+ value = "#{table_name(type, common_bytes)}[#{char_variable}[#{n}] - #{"%#04x" % min}]"
+ end
+ last_n_bits_for_char_in_utf8 = 6
+ max_n_chars_in_byte = 2 ** last_n_bits_for_char_in_utf8
+ if all_values.size == max_n_chars_in_byte
+ @output.puts(<<-BODY)
+#{indent}return #{value};
+ BODY
+ else
+ @output.puts(<<-BODY)
+#{indent}if (#{char_variable}[#{n}] >= #{"%#04x" % min} &&
+#{indent} #{char_variable}[#{n}] <= #{"%#04x" % max}) {
+#{indent} return #{value};
+#{indent}}
+#{indent}break;
+ BODY
+ end
end
- br = false
end
- unless br
- file.puts bl + " return #{$lv};"
- file.puts bl + ' break;'
+ end
+ end
+
+ def generate_blockcode_char_type(block_codes)
+ default = "GRN_CHAR_OTHERS"
+
+ char_types = {}
+ current_type = default
+ prev_char = nil
+ block_codes.keys.sort.each do |char|
+ type = block_codes[char]
+ if current_type != default
+ prev_code_point = prev_char.codepoints[0]
+ code_point = char.codepoints[0]
+ (prev_code_point...code_point).each do |target_code_point|
+ target_char = [target_code_point].pack("U*")
+ char_types[target_char] = current_type
+ end
end
- h = h2[k]
- file.printf("#{bl}case 0x%02X :\n", k)
- if h.keys.join =~ /^\x80*$/
- $lv, = h.values
- br = false
+ current_type = type
+ prev_char = char
+ end
+ unless current_type == default
+ raise "TODO: Consider the max unicode character"
+ max_unicode_char = "\u{10ffff}"
+ (prev_char..max_unicode_char).each do |target_char|
+ char_types[target_char] = current_type
+ end
+ end
+
+ generate_char_converter("char_type",
+ "char_type",
+ char_types,
+ default,
+ "grn_char_type") do |char|
+ char_types[char] || default
+ end
+ end
+
+ def generate_decompose(decompose_map)
+ default = "NULL"
+ generate_char_converter("decompose",
+ "decompose",
+ decompose_map,
+ default,
+ "const char *") do |from|
+ to = decompose_map[from]
+ if to
+ escaped_value = to.bytes.collect {|char| "\\x%02x" % char}.join("")
+ "\"#{escaped_value}\""
else
- gen_bc(file, h, level + 1)
- file.puts bl + ' break;'
- br = true
+ default
end
- lk = k + 1
- }
- file.puts bl + 'default :'
- file.puts bl + " return #{$lv};"
- file.puts bl + ' break;'
- file.puts bl + '}'
+ end
+ end
+
+ def generate_compose(compose_map)
+ # require "pp"
+ # p compose_map.size
+ # pp compose_map.keys.group_by {|x| x.chars[1]}.size
+ # pp compose_map.keys.group_by {|x| x.chars[1]}.collect {|k, vs| [k, k.codepoints, vs.size, vs.group_by {|x| x.chars[0].bytesize}.collect {|k2, vs2| [k2, vs2.size]}]}
+ # pp compose_map.keys.group_by {|x| x.chars[0].bytesize}.collect {|k, vs| [k, vs.size]}
+ # pp compose_map
+
+ suffix_char_map = {}
+ compose_map.each do |source, destination|
+ chars = source.chars
+ if chars.size != 2
+ STDERR.puts "caution: more than two chars in pattern #{chars.join('|')}"
+ return
+ end
+ prefix, suffix = chars
+ suffix_char_map[suffix] ||= {}
+ suffix_char_map[suffix][prefix] = destination
+ end
+
+ suffix_char_map.each do |suffix, prefix_char_map|
+ suffix_bytes = suffix.bytes.collect {|byte| "%02x" % byte}.join("")
+ default = "NULL"
+ generate_char_converter("compose_prefix_#{suffix_bytes}",
+ "compose_prefix_#{suffix_bytes}",
+ prefix_char_map,
+ default,
+ "const char *",
+ :internal => true) do |prefix|
+ to = prefix_char_map[prefix]
+ if to
+ escaped_value = to.bytes.collect {|char| "\\x%02x" % char}.join("")
+ "\"#{escaped_value}\""
+ else
+ default
+ end
+ end
+ end
+
+
+ char_variable = "suffix_utf8"
+ argument_list =
+ "const unsigned char *prefix_utf8, " +
+ "const unsigned char *#{char_variable}"
+ default = "NULL"
+ byte_size_groups = suffix_char_map.keys.group_by do |from|
+ bytes = from.bytes
+ bytes[0..-2]
+ end
+ generate_char_convert_function("compose",
+ argument_list,
+ char_variable,
+ default,
+ "const char *",
+ byte_size_groups) do |type, *args|
+ case type
+ when :no_common_bytes
+ indent, chars, chars_bytes = args
+ @output.puts(<<-BODY)
+#{indent}switch (#{char_variable}[0]) {
+ BODY
+ chars.each do |char|
+ suffix_bytes = char.bytes.collect {|byte| "%02x" % byte}.join("")
+ type = "compose_prefix_#{suffix_bytes}"
+ @output.puts(<<-BODY)
+#{indent}case #{"%#04x" % char.bytes.last} :
+#{indent} return #{function_name(type)}(prefix_utf8);
+ BODY
+ end
+ @output.puts(<<-BODY)
+#{indent}default :
+#{indent} return #{default};
+#{indent}}
+#{indent}break;
+ BODY
+ when :have_common_bytes
+ indent, chars, chars_bytes, n, common_bytes = args
+ @output.puts(<<-BODY)
+#{indent}switch (#{char_variable}[#{n}]) {
+ BODY
+ chars.each do |char|
+ suffix_bytes = char.bytes.collect {|byte| "%02x" % byte}.join("")
+ type = "compose_prefix_#{suffix_bytes}"
+ @output.puts(<<-BODY)
+#{indent}case #{"%#04x" % char.bytes.last} :
+#{indent} return #{function_name(type)}(prefix_utf8);
+ BODY
+ end
+ @output.puts(<<-BODY)
+#{indent}default :
+#{indent} return #{default};
+#{indent}}
+#{indent}break;
+ BODY
+ end
+ end
+ end
+
+ def to_bytes_map(char_map)
+ bytes_map = {}
+ char_map.each_key do |from|
+ parent = bytes_map
+ from.bytes[0..-2].each do |byte|
+ parent[byte] ||= {}
+ parent = parent[byte]
+ end
+ parent[from.bytes.last] = char_map[from]
+ end
+ bytes_map
end
end
-def generate_blockcode_char_type(file, option)
+def create_bc(option)
bc = {}
open("|./icudump --#{option}").each{|l|
src,_,code = l.chomp.split("\t")
- str = src.split(':').collect{|c| format("%c", c.hex)}.join
+ str = src.split(':').collect(&:hex).pack("c*")
+ str.force_encoding("UTF-8")
bc[str] = code
}
- $lv = 0
- gen_bc(file, bc, 0)
+ bc
end
def ccpush(hash, src, dst)
@@ -104,7 +725,7 @@ end
def subst(hash, str)
cand = nil
- src = str.split(//)
+ src = str.chars
for i in 0..src.size-1
h = hash
for j in i..src.size-1
@@ -112,7 +733,7 @@ def subst(hash, str)
h = h[head]
break unless h
if h[nil]
- cand = src[0,i].to_s + h[nil] + src[j + 1..-1].to_s
+ cand = src[0,i].join("") + h[nil] + src[j + 1..-1].join("")
end
end
return cand if cand
@@ -120,7 +741,7 @@ def subst(hash, str)
return str
end
-def map_entry(map1, cc, src, dst)
+def map_entry(decompose, cc, src, dst)
dst.downcase! unless $case_sensitive
loop {
dst2 = subst(cc, dst)
@@ -130,43 +751,43 @@ def map_entry(map1, cc, src, dst)
unless $keep_space
dst = $1 if dst =~ /^ +([^ ].*)$/
end
- map1[src] = dst if src != dst
+ decompose[src] = dst if src != dst
end
-def create_map1()
+def create_decompose_map()
cc = {}
open('|./icudump --cc').each{|l|
_,src,dst = l.chomp.split("\t")
if cc[src]
STDERR.puts "caution: ambiguous mapping #{src}|#{cc[src]}|#{dst}" if cc[src] != dst
end
- ccpush(cc, src.split(//), dst)
+ ccpush(cc, src.chars, dst)
}
- map1 = {}
+ decompose_map = {}
open('|./icudump --nfkd').each{|l|
n,src,dst = l.chomp.split("\t")
- map_entry(map1, cc, src, dst)
+ map_entry(decompose_map, cc, src, dst)
}
if File.readable?(CUSTOM_RULE_PATH)
open(CUSTOM_RULE_PATH).each{|l|
src,dst = l.chomp.split("\t")
- map_entry(map1, cc, src, dst)
+ map_entry(decompose_map, cc, src, dst)
}
end
unless $case_sensitive
for c in 'A'..'Z'
- map1[c] = c.downcase
+ decompose_map[c] = c.downcase
end
end
- return map1
+ return decompose_map
end
-def create_map2(map1)
+def create_compose_map(decompose_map)
cc = {}
open('|./icudump --cc').each{|l|
_,src,dst = l.chomp.split("\t")
- src = src.split(//).collect{|c| map1[c] || c}.join
- dst = map1[dst] || dst
+ src = src.chars.collect{|c| decompose_map[c] || c}.join
+ dst = decompose_map[dst] || dst
if cc[src] && cc[src] != dst
STDERR.puts("caution: inconsitent mapping '#{src}' => '#{cc[src]}'|'#{dst}'")
end
@@ -177,14 +798,15 @@ def create_map2(map1)
cc2 = {}
cc.each {|src,dst|
src2 = src
- chars = src.split(//)
+ chars = src.chars
l = chars.size - 1
for i in 0..l
for j in i..l
next if i == 0 && j == l
str = chars[i..j].join
- if map1[str]
- STDERR.printf("caution: recursive mapping '%s'=>'%s'\n", str, map1[str])
+ if decompose_map[str]
+ STDERR.printf("caution: recursive mapping '%s'=>'%s'\n",
+ str, decompose_map[str])
end
if cc[str]
src2 = (i > 0 ? chars[0..i-1].join : '') + cc[str] + (j < l ? chars[j+1..l].join : '')
@@ -202,134 +824,42 @@ def create_map2(map1)
return cc
end
-def generate_map1(file, hash, level)
- bl = ' ' * ((level + 0) * 2)
- if hash['']
- dst = ''
- hash[''].each_byte{|b| dst << format('\x%02X', b)}
- file.puts "#{bl}return \"#{dst}\";"
- hash.delete('')
- end
- return if hash.empty?
- h2 = {}
- hash.each{|key,val|
- head = key[0]
- rest = key[1..-1]
- if h2[head]
- h2[head][rest] = val
- else
- h2[head] = {rest => val}
- end
- }
- if h2.size == 1
- h2.each{|key,val|
- file.printf("#{bl}if (str[#{level}] == 0x%02X) {\n", key)
- generate_map1(file, val, level + 1)
- file.puts bl + '}'
- }
- else
- file.puts "#{bl}switch (str[#{level}]) {"
- h2.keys.sort.each{|k|
- file.printf("#{bl}case 0x%02X :\n", k)
- generate_map1(file, h2[k], level + 1)
- file.puts("#{bl} break;")
- }
- file.puts bl + '}'
- end
-end
+######## main #######
-def gen_map2_sub2(file, hash, level, indent)
- bl = ' ' * ((level + indent + 0) * 2)
- if hash['']
- file.print "#{bl}return \""
- hash[''].each_byte{|b| file.printf('\x%02X', b)}
- file.puts "\";"
- hash.delete('')
+generator_class = SwitchGenerator
+ARGV.each{|arg|
+ case arg
+ when /-*c/i
+ $case_sensitive = true
+ when /-*s/i
+ $keep_space = true
+ when "--impl=switch"
+ generator_class = SwitchGenerator
+ when "--impl=table"
+ generator_class = TableGenerator
end
- return if hash.empty?
-
- h2 = {}
- hash.each{|key,val|
- head = key[0]
- rest = key[1..-1]
- if h2[head]
- h2[head][rest] = val
- else
- h2[head] = {rest => val}
- end
- }
+}
- if h2.size == 1
- h2.each{|key,val|
- file.printf("#{bl}if (prefix[#{level}] == 0x%02X) {\n", key)
- gen_map2_sub2(file, val, level + 1, indent)
- file.puts bl + '}'
- }
- else
- file.puts "#{bl}switch (prefix[#{level}]) {"
- h2.keys.sort.each{|k|
- file.printf("#{bl}case 0x%02X :\n", k)
- gen_map2_sub2(file, h2[k], level + 1, indent)
- file.puts("#{bl} break;")
- }
- file.puts bl + '}'
- end
-end
+STDERR.puts('compiling icudump')
+system('cc -Wall -O3 -o icudump -I/tmp/local/include -L/tmp/local/lib icudump.c -licuuc -licui18n')
-def gen_map2_sub(file, hash, level)
- bl = ' ' * ((level + 0) * 2)
- if hash['']
- gen_map2_sub2(file, hash[''], 0, level)
- hash.delete('')
- end
- return if hash.empty?
- h2 = {}
- hash.each{|key,val|
- head = key[0]
- rest = key[1..-1]
- if h2[head]
- h2[head][rest] = val
- else
- h2[head] = {rest => val}
- end
- }
- if h2.size == 1
- h2.each{|key,val|
- file.printf("#{bl}if (suffix[#{level}] == 0x%02X) {\n", key)
- gen_map2_sub(file, val, level + 1)
- file.puts bl + '}'
- }
- else
- file.puts "#{bl}switch (suffix[#{level}]) {"
- h2.keys.sort.each{|k|
- file.printf("#{bl}case 0x%02X :\n", k)
- gen_map2_sub(file, h2[k], level + 1)
- file.puts("#{bl} break;")
- }
- file.puts bl + '}'
- end
-end
+STDERR.puts('getting Unicode version')
+unicode_version = `./icudump --version`.strip.gsub(".", "")
-def generate_map2(file, map2)
- suffix = {}
- map2.each{|src,dst|
- chars = src.split(//)
- if chars.size != 2
- STDERR.puts "caution: more than two chars in pattern #{chars.join('|')}"
- end
- s = chars.pop
- if suffix[s]
- suffix[s][chars.join] = dst
- else
- suffix[s] = {chars.join=>dst}
- end
- }
- gen_map2_sub(file, suffix, 0)
-end
+STDERR.puts('creating bc..')
+bc = create_bc("gc")
-template = <<END
+STDERR.puts('creating decompose map..')
+decompose_map = create_decompose_map()
+
+STDERR.puts('creating compose map..')
+compose_map = create_compose_map(decompose_map)
+
+File.open("nfkc#{unicode_version}.c", "w") do |output|
+ output.puts(<<-HEADER)
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2010 Brazil
+/*
+ Copyright(C) 2010-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -343,76 +873,25 @@ template = <<END
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
-don't edit this file by hand. it generated automatically by nfkc.rb
+/*
+ Don't edit this file by hand. it generated automatically by nfkc.rb.
*/
-#include "nfkc.h"
+#include "grn.h"
+#include "grn_nfkc.h"
+#include <groonga/nfkc.h>
#ifdef GRN_WITH_NFKC
+ HEADER
-unsigned char
-grn_nfkc_char_type(const unsigned char *str)
-{
-% return -1;
-}
+ generator = generator_class.new(unicode_version, output)
+ generator.generate(bc, decompose_map, compose_map)
-const char *
-grn_nfkc_map1(const unsigned char *str)
-{
-% return 0;
-}
-
-const char *
-grn_nfkc_map2(const unsigned char *prefix, const unsigned char *suffix)
-{
-% return 0;
-}
+ output.puts(<<-FOOTER)
#endif /* GRN_WITH_NFKC */
-END
-
-######## main #######
-
-ARGV.each{|arg|
- case arg
- when /-*c/i
- $case_sensitive = true
- when /-*s/i
- $keep_space = true
- end
-}
-
-STDERR.puts('compiling icudump')
-system('cc -Wall -O3 -o icudump icudump.c -licui18n')
-
-STDERR.puts('creating map1..')
-map1 = create_map1()
-
-STDERR.puts('creating map2..')
-map2 = create_map2(map1)
-
-outf = open('nfkc.c', 'w')
-
-tmps = template.split(/%/)
-
-#STDERR.puts('generating block code..')
-#outf.print(tmps.shift)
-#generate_blockcode_char_type(outf, 'bc')
-
-STDERR.puts('generating char type code..')
-outf.print(tmps.shift)
-generate_blockcode_char_type(outf, 'gc')
-
-STDERR.puts('generating map1 code..')
-outf.print(tmps.shift)
-generate_map1(outf, map1, 0)
-
-STDERR.puts('generating map2 code..')
-outf.print(tmps.shift)
-generate_map2(outf, map2)
-
-outf.print(tmps.shift)
-outf.close
-STDERR.puts('done.')
+ FOOTER
+end
diff --git a/storage/mroonga/vendor/groonga/lib/nfkc50.c b/storage/mroonga/vendor/groonga/lib/nfkc50.c
new file mode 100644
index 00000000000..06e802962a0
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/nfkc50.c
@@ -0,0 +1,77784 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2010-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*
+ Don't edit this file by hand. it generated automatically by nfkc.rb.
+*/
+
+#include "grn.h"
+#include "grn_nfkc.h"
+#include <groonga/nfkc.h>
+
+#ifdef GRN_WITH_NFKC
+
+static grn_char_type grn_nfkc50_char_type_table_[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_c2[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_DIGIT, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_c3[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_cb[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_cd[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_ce[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_cf[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_d2[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_d4[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_d5[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_d6[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_d7[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_d8[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_d9[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_db[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_dc[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_de[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_df[] = {
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0a4[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0a5[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0a6[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0a7[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0a8[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0a9[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0aa[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0ab[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0ac[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0ad[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0ae[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0af[] = {
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0b0[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0b1[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0b2[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0b3[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0b4[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0b5[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0b6[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0b7[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0b8[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0b9[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0ba[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0bb[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0bc[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0bd[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0be[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e0bf[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e180[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e181[] = {
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e183[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e185[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e186[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e189[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e18a[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e18b[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e18c[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e18d[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e18e[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e199[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e19a[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e19b[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e19c[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e19d[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e19f[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e1a0[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e1a5[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e1a7[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e1a8[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e1ad[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e1ba[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e1bc[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e1bd[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e1be[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e1bf[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e280[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e281[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_DIGIT, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e282[] = {
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e284[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e285[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e286[] = {
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e291[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e292[] = {
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e293[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e29a[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e29c[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e29d[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e29e[] = {
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e29f[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e2ac[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e2b0[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e2b1[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e2b3[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e2b4[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e2b5[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e2b6[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e2b7[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e2b8[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e2bf[] = {
+ GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI,
+ GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI,
+ GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI,
+ GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e382[] = {
+ GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA,
+ GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA,
+ GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA,
+ GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA, GRN_CHAR_HIRAGANA,
+ GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA,
+ GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA,
+ GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA,
+ GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_e387[] = {
+ GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI,
+ GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI,
+ GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI,
+ GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI,
+ GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI,
+ GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI, GRN_CHAR_KANJI,
+ GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA,
+ GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA, GRN_CHAR_KATAKANA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_ea9c[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_eaa0[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_eaa1[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_efac[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_efad[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_efb4[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_efb6[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_efb7[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_efb8[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_efb9[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_efbc[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_efbd[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_efbf[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09080[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09081[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09084[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09085[] = {
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09086[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f0908c[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f0908d[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_DIGIT, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f0908e[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f0908f[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_SYMBOL, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09092[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f090a0[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f090a4[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f090a8[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f090a9[] = {
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09291[] = {
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d84[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d85[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d86[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d89[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_SYMBOL
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d8d[] = {
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL,
+ GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_SYMBOL, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d91[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d92[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d93[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d94[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d95[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS,
+ GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d9a[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d9b[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d9c[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d9d[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d9e[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA
+};
+
+static grn_char_type grn_nfkc50_char_type_table_f09d9f[] = {
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_SYMBOL, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA,
+ GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_ALPHA, GRN_CHAR_OTHERS, GRN_CHAR_OTHERS, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT,
+ GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT, GRN_CHAR_DIGIT
+};
+
+grn_char_type
+grn_nfkc50_char_type(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x21 &&
+ utf8[0] <= 0x7e) {
+ return grn_nfkc50_char_type_table_[utf8[0] - 0x21];
+ } else {
+ return GRN_CHAR_OTHERS;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc2 :
+ if (utf8[1] >= 0xa1 &&
+ utf8[1] <= 0xbf) {
+ return grn_nfkc50_char_type_table_c2[utf8[1] - 0xa1];
+ }
+ break;
+ case 0xc3 :
+ return grn_nfkc50_char_type_table_c3[utf8[1] - 0x80];
+ case 0xc4 :
+ return GRN_CHAR_ALPHA;
+ case 0xc5 :
+ return GRN_CHAR_ALPHA;
+ case 0xc6 :
+ return GRN_CHAR_ALPHA;
+ case 0xc7 :
+ return GRN_CHAR_ALPHA;
+ case 0xc8 :
+ return GRN_CHAR_ALPHA;
+ case 0xc9 :
+ return GRN_CHAR_ALPHA;
+ case 0xca :
+ return GRN_CHAR_ALPHA;
+ case 0xcb :
+ return grn_nfkc50_char_type_table_cb[utf8[1] - 0x80];
+ case 0xcd :
+ if (utf8[1] >= 0xb4 &&
+ utf8[1] <= 0xbe) {
+ return grn_nfkc50_char_type_table_cd[utf8[1] - 0xb4];
+ }
+ break;
+ case 0xce :
+ if (utf8[1] >= 0x84 &&
+ utf8[1] <= 0xbf) {
+ return grn_nfkc50_char_type_table_ce[utf8[1] - 0x84];
+ }
+ break;
+ case 0xcf :
+ return grn_nfkc50_char_type_table_cf[utf8[1] - 0x80];
+ case 0xd0 :
+ return GRN_CHAR_ALPHA;
+ case 0xd1 :
+ return GRN_CHAR_ALPHA;
+ case 0xd2 :
+ return grn_nfkc50_char_type_table_d2[utf8[1] - 0x80];
+ case 0xd3 :
+ return GRN_CHAR_ALPHA;
+ case 0xd4 :
+ return grn_nfkc50_char_type_table_d4[utf8[1] - 0x80];
+ case 0xd5 :
+ return grn_nfkc50_char_type_table_d5[utf8[1] - 0x80];
+ case 0xd6 :
+ if (utf8[1] >= 0x80 &&
+ utf8[1] <= 0xbe) {
+ return grn_nfkc50_char_type_table_d6[utf8[1] - 0x80];
+ }
+ break;
+ case 0xd7 :
+ if (utf8[1] >= 0x80 &&
+ utf8[1] <= 0xb4) {
+ return grn_nfkc50_char_type_table_d7[utf8[1] - 0x80];
+ }
+ break;
+ case 0xd8 :
+ if (utf8[1] >= 0x8b &&
+ utf8[1] <= 0xba) {
+ return grn_nfkc50_char_type_table_d8[utf8[1] - 0x8b];
+ }
+ break;
+ case 0xd9 :
+ return grn_nfkc50_char_type_table_d9[utf8[1] - 0x80];
+ case 0xda :
+ return GRN_CHAR_ALPHA;
+ case 0xdb :
+ return grn_nfkc50_char_type_table_db[utf8[1] - 0x80];
+ case 0xdc :
+ if (utf8[1] >= 0x80 &&
+ utf8[1] <= 0xaf) {
+ return grn_nfkc50_char_type_table_dc[utf8[1] - 0x80];
+ }
+ break;
+ case 0xdd :
+ if (utf8[1] >= 0x8d &&
+ utf8[1] <= 0xad) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xde :
+ if (utf8[1] >= 0x80 &&
+ utf8[1] <= 0xb1) {
+ return grn_nfkc50_char_type_table_de[utf8[1] - 0x80];
+ }
+ break;
+ case 0xdf :
+ if (utf8[1] >= 0x80 &&
+ utf8[1] <= 0xba) {
+ return grn_nfkc50_char_type_table_df[utf8[1] - 0x80];
+ }
+ break;
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_char_type_table_e0a4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_char_type_table_e0a5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_char_type_table_e0a6[utf8[2] - 0x85];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x8e &&
+ utf8[2] <= 0xba) {
+ return grn_nfkc50_char_type_table_e0a7[utf8[2] - 0x8e];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_char_type_table_e0a8[utf8[2] - 0x85];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x99 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_char_type_table_e0a9[utf8[2] - 0x99];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_char_type_table_e0aa[utf8[2] - 0x85];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xb1) {
+ return grn_nfkc50_char_type_table_e0ab[utf8[2] - 0x90];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_char_type_table_e0ac[utf8[2] - 0x85];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x9c &&
+ utf8[2] <= 0xb1) {
+ return grn_nfkc50_char_type_table_e0ad[utf8[2] - 0x9c];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x83 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_char_type_table_e0ae[utf8[2] - 0x83];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0xa6 &&
+ utf8[2] <= 0xba) {
+ return grn_nfkc50_char_type_table_e0af[utf8[2] - 0xa6];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_char_type_table_e0b0[utf8[2] - 0x85];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0xa0 &&
+ utf8[2] <= 0xaf) {
+ return grn_nfkc50_char_type_table_e0b1[utf8[2] - 0xa0];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_char_type_table_e0b2[utf8[2] - 0x85];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x9e &&
+ utf8[2] <= 0xb2) {
+ return grn_nfkc50_char_type_table_e0b3[utf8[2] - 0x9e];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_char_type_table_e0b4[utf8[2] - 0x85];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0xa0 &&
+ utf8[2] <= 0xaf) {
+ return grn_nfkc50_char_type_table_e0b5[utf8[2] - 0xa0];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_char_type_table_e0b6[utf8[2] - 0x85];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_char_type_table_e0b7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x81 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_char_type_table_e0b8[utf8[2] - 0x81];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x9b) {
+ return grn_nfkc50_char_type_table_e0b9[utf8[2] - 0x80];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x81 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_char_type_table_e0ba[utf8[2] - 0x81];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x9d) {
+ return grn_nfkc50_char_type_table_e0bb[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_char_type_table_e0bc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xaa) {
+ return grn_nfkc50_char_type_table_e0bd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_char_type_table_e0be[utf8[2] - 0x85];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x91) {
+ return grn_nfkc50_char_type_table_e0bf[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xaa) {
+ return grn_nfkc50_char_type_table_e180[utf8[2] - 0x80];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x95) {
+ return grn_nfkc50_char_type_table_e181[utf8[2] - 0x80];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0xa0 &&
+ utf8[2] <= 0xbf) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_char_type_table_e183[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ return GRN_CHAR_ALPHA;
+ case 0x85 :
+ return grn_nfkc50_char_type_table_e185[utf8[2] - 0x80];
+ case 0x86 :
+ return grn_nfkc50_char_type_table_e186[utf8[2] - 0x80];
+ case 0x87 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb9) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0x88 :
+ return GRN_CHAR_ALPHA;
+ case 0x89 :
+ return grn_nfkc50_char_type_table_e189[utf8[2] - 0x80];
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_char_type_table_e18a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ return grn_nfkc50_char_type_table_e18b[utf8[2] - 0x80];
+ case 0x8c :
+ return grn_nfkc50_char_type_table_e18c[utf8[2] - 0x80];
+ case 0x8d :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_char_type_table_e18d[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8e :
+ return grn_nfkc50_char_type_table_e18e[utf8[2] - 0x80];
+ case 0x8f :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb4) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x81 &&
+ utf8[2] <= 0xbf) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0x91 :
+ return GRN_CHAR_ALPHA;
+ case 0x92 :
+ return GRN_CHAR_ALPHA;
+ case 0x93 :
+ return GRN_CHAR_ALPHA;
+ case 0x94 :
+ return GRN_CHAR_ALPHA;
+ case 0x95 :
+ return GRN_CHAR_ALPHA;
+ case 0x96 :
+ return GRN_CHAR_ALPHA;
+ case 0x97 :
+ return GRN_CHAR_ALPHA;
+ case 0x98 :
+ return GRN_CHAR_ALPHA;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb6) {
+ return grn_nfkc50_char_type_table_e199[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x81 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_char_type_table_e19a[utf8[2] - 0x81];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_char_type_table_e19b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb6) {
+ return grn_nfkc50_char_type_table_e19c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_char_type_table_e19d[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb3) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_char_type_table_e19f[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa0 :
+ return grn_nfkc50_char_type_table_e1a0[utf8[2] - 0x80];
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb7) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xa8) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x9c) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_char_type_table_e1a5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xa9) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x81 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_char_type_table_e1a7[utf8[2] - 0x81];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x9f) {
+ return grn_nfkc50_char_type_table_e1a8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xb3) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_char_type_table_e1ad[utf8[2] - 0x85];
+ }
+ break;
+ case 0xb4 :
+ return GRN_CHAR_ALPHA;
+ case 0xb5 :
+ return GRN_CHAR_ALPHA;
+ case 0xb6 :
+ return GRN_CHAR_ALPHA;
+ case 0xb8 :
+ return GRN_CHAR_ALPHA;
+ case 0xb9 :
+ return GRN_CHAR_ALPHA;
+ case 0xba :
+ return grn_nfkc50_char_type_table_e1ba[utf8[2] - 0x80];
+ case 0xbb :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb9) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xbc :
+ return grn_nfkc50_char_type_table_e1bc[utf8[2] - 0x80];
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_char_type_table_e1bd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ return grn_nfkc50_char_type_table_e1be[utf8[2] - 0x80];
+ case 0xbf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_char_type_table_e1bf[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xe2 :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_char_type_table_e280[utf8[2] - 0x90];
+ }
+ break;
+ case 0x81 :
+ return grn_nfkc50_char_type_table_e281[utf8[2] - 0x80];
+ case 0x82 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb5) {
+ return grn_nfkc50_char_type_table_e282[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ return grn_nfkc50_char_type_table_e284[utf8[2] - 0x80];
+ case 0x85 :
+ return grn_nfkc50_char_type_table_e285[utf8[2] - 0x80];
+ case 0x86 :
+ return grn_nfkc50_char_type_table_e286[utf8[2] - 0x80];
+ case 0x87 :
+ return GRN_CHAR_SYMBOL;
+ case 0x88 :
+ return GRN_CHAR_SYMBOL;
+ case 0x89 :
+ return GRN_CHAR_SYMBOL;
+ case 0x8a :
+ return GRN_CHAR_SYMBOL;
+ case 0x8b :
+ return GRN_CHAR_SYMBOL;
+ case 0x8c :
+ return GRN_CHAR_SYMBOL;
+ case 0x8d :
+ return GRN_CHAR_SYMBOL;
+ case 0x8e :
+ return GRN_CHAR_SYMBOL;
+ case 0x8f :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xa7) {
+ return GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xa6) {
+ return GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 0x91 :
+ return grn_nfkc50_char_type_table_e291[utf8[2] - 0x80];
+ case 0x92 :
+ return grn_nfkc50_char_type_table_e292[utf8[2] - 0x80];
+ case 0x93 :
+ return grn_nfkc50_char_type_table_e293[utf8[2] - 0x80];
+ case 0x94 :
+ return GRN_CHAR_SYMBOL;
+ case 0x95 :
+ return GRN_CHAR_SYMBOL;
+ case 0x96 :
+ return GRN_CHAR_SYMBOL;
+ case 0x97 :
+ return GRN_CHAR_SYMBOL;
+ case 0x98 :
+ return GRN_CHAR_SYMBOL;
+ case 0x99 :
+ return GRN_CHAR_SYMBOL;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb2) {
+ return grn_nfkc50_char_type_table_e29a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x81 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_char_type_table_e29c[utf8[2] - 0x81];
+ }
+ break;
+ case 0x9d :
+ return grn_nfkc50_char_type_table_e29d[utf8[2] - 0x80];
+ case 0x9e :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_char_type_table_e29e[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9f :
+ return grn_nfkc50_char_type_table_e29f[utf8[2] - 0x80];
+ case 0xa0 :
+ return GRN_CHAR_SYMBOL;
+ case 0xa1 :
+ return GRN_CHAR_SYMBOL;
+ case 0xa2 :
+ return GRN_CHAR_SYMBOL;
+ case 0xa3 :
+ return GRN_CHAR_SYMBOL;
+ case 0xa4 :
+ return GRN_CHAR_SYMBOL;
+ case 0xa5 :
+ return GRN_CHAR_SYMBOL;
+ case 0xa6 :
+ return GRN_CHAR_SYMBOL;
+ case 0xa7 :
+ return GRN_CHAR_SYMBOL;
+ case 0xa8 :
+ return GRN_CHAR_SYMBOL;
+ case 0xa9 :
+ return GRN_CHAR_SYMBOL;
+ case 0xaa :
+ return GRN_CHAR_SYMBOL;
+ case 0xab :
+ return GRN_CHAR_SYMBOL;
+ case 0xac :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xa3) {
+ return grn_nfkc50_char_type_table_e2ac[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ return grn_nfkc50_char_type_table_e2b0[utf8[2] - 0x80];
+ case 0xb1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb7) {
+ return grn_nfkc50_char_type_table_e2b1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb2 :
+ return GRN_CHAR_ALPHA;
+ case 0xb3 :
+ return grn_nfkc50_char_type_table_e2b3[utf8[2] - 0x80];
+ case 0xb4 :
+ return grn_nfkc50_char_type_table_e2b4[utf8[2] - 0x80];
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xaf) {
+ return grn_nfkc50_char_type_table_e2b5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_char_type_table_e2b6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x9e) {
+ return grn_nfkc50_char_type_table_e2b7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x97) {
+ return grn_nfkc50_char_type_table_e2b8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbb) {
+ return grn_nfkc50_char_type_table_e2bf[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xe3 :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_SYMBOL;
+ case 0x81 :
+ return GRN_CHAR_HIRAGANA;
+ case 0x82 :
+ return grn_nfkc50_char_type_table_e382[utf8[2] - 0x80];
+ case 0x83 :
+ return GRN_CHAR_KATAKANA;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return grn_nfkc50_char_type_table_e387[utf8[2] - 0x80];
+ case 0x88 :
+ return GRN_CHAR_SYMBOL;
+ case 0x89 :
+ return GRN_CHAR_SYMBOL;
+ case 0x8a :
+ return GRN_CHAR_SYMBOL;
+ case 0x8b :
+ return GRN_CHAR_SYMBOL;
+ case 0x8c :
+ return GRN_CHAR_SYMBOL;
+ case 0x8d :
+ return GRN_CHAR_SYMBOL;
+ case 0x8e :
+ return GRN_CHAR_SYMBOL;
+ case 0x8f :
+ return GRN_CHAR_SYMBOL;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xe4 :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_SYMBOL;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xe5 :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xe6 :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xe7 :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xe8 :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xe9 :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xea :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x8f) {
+ return GRN_CHAR_KANJI;
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xa1) {
+ return grn_nfkc50_char_type_table_ea9c[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xab) {
+ return grn_nfkc50_char_type_table_eaa0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb7) {
+ return grn_nfkc50_char_type_table_eaa1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xaf) {
+ return GRN_CHAR_KANJI;
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xef :
+ switch (utf8[1]) {
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_char_type_table_efac[utf8[2] - 0x80];
+ }
+ break;
+ case 0xad :
+ return grn_nfkc50_char_type_table_efad[utf8[2] - 0x80];
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb1) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x93 &&
+ utf8[2] <= 0xbf) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xb0 :
+ return GRN_CHAR_ALPHA;
+ case 0xb1 :
+ return GRN_CHAR_ALPHA;
+ case 0xb2 :
+ return GRN_CHAR_ALPHA;
+ case 0xb3 :
+ return GRN_CHAR_ALPHA;
+ case 0xb4 :
+ return grn_nfkc50_char_type_table_efb4[utf8[2] - 0x80];
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xbf) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xb6 :
+ return grn_nfkc50_char_type_table_efb6[utf8[2] - 0x80];
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_char_type_table_efb7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_char_type_table_efb8[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb9 :
+ return grn_nfkc50_char_type_table_efb9[utf8[2] - 0x80];
+ case 0xba :
+ return GRN_CHAR_ALPHA;
+ case 0xbb :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbc) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x81 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_char_type_table_efbc[utf8[2] - 0x81];
+ }
+ break;
+ case 0xbd :
+ return grn_nfkc50_char_type_table_efbd[utf8[2] - 0x80];
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x82 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_char_type_table_efbf[utf8[2] - 0x82];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xf0 :
+ switch (utf8[1]) {
+ case 0x90 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return grn_nfkc50_char_type_table_f09080[utf8[3] - 0x80];
+ case 0x81 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x9d) {
+ return grn_nfkc50_char_type_table_f09081[utf8[3] - 0x80];
+ }
+ break;
+ case 0x82 :
+ return GRN_CHAR_ALPHA;
+ case 0x83 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0xba) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0x84 :
+ return grn_nfkc50_char_type_table_f09084[utf8[3] - 0x80];
+ case 0x85 :
+ return grn_nfkc50_char_type_table_f09085[utf8[3] - 0x80];
+ case 0x86 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x8a) {
+ return grn_nfkc50_char_type_table_f09086[utf8[3] - 0x80];
+ }
+ break;
+ case 0x8c :
+ return grn_nfkc50_char_type_table_f0908c[utf8[3] - 0x80];
+ case 0x8d :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x8a) {
+ return grn_nfkc50_char_type_table_f0908d[utf8[3] - 0x80];
+ }
+ break;
+ case 0x8e :
+ return grn_nfkc50_char_type_table_f0908e[utf8[3] - 0x80];
+ case 0x8f :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x95) {
+ return grn_nfkc50_char_type_table_f0908f[utf8[3] - 0x80];
+ }
+ break;
+ case 0x90 :
+ return GRN_CHAR_ALPHA;
+ case 0x91 :
+ return GRN_CHAR_ALPHA;
+ case 0x92 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0xa9) {
+ return grn_nfkc50_char_type_table_f09092[utf8[3] - 0x80];
+ }
+ break;
+ case 0xa0 :
+ return grn_nfkc50_char_type_table_f090a0[utf8[3] - 0x80];
+ case 0xa4 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x9f) {
+ return grn_nfkc50_char_type_table_f090a4[utf8[3] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0xb3) {
+ return grn_nfkc50_char_type_table_f090a8[utf8[3] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x98) {
+ return grn_nfkc50_char_type_table_f090a9[utf8[3] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0x92 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_ALPHA;
+ case 0x81 :
+ return GRN_CHAR_ALPHA;
+ case 0x82 :
+ return GRN_CHAR_ALPHA;
+ case 0x83 :
+ return GRN_CHAR_ALPHA;
+ case 0x84 :
+ return GRN_CHAR_ALPHA;
+ case 0x85 :
+ return GRN_CHAR_ALPHA;
+ case 0x86 :
+ return GRN_CHAR_ALPHA;
+ case 0x87 :
+ return GRN_CHAR_ALPHA;
+ case 0x88 :
+ return GRN_CHAR_ALPHA;
+ case 0x89 :
+ return GRN_CHAR_ALPHA;
+ case 0x8a :
+ return GRN_CHAR_ALPHA;
+ case 0x8b :
+ return GRN_CHAR_ALPHA;
+ case 0x8c :
+ return GRN_CHAR_ALPHA;
+ case 0x8d :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0xae) {
+ return GRN_CHAR_ALPHA;
+ }
+ break;
+ case 0x90 :
+ return GRN_CHAR_DIGIT;
+ case 0x91 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0xb3) {
+ return grn_nfkc50_char_type_table_f09291[utf8[3] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0x9d :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_SYMBOL;
+ case 0x81 :
+ return GRN_CHAR_SYMBOL;
+ case 0x82 :
+ return GRN_CHAR_SYMBOL;
+ case 0x83 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0xb5) {
+ return GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 0x84 :
+ return grn_nfkc50_char_type_table_f09d84[utf8[3] - 0x80];
+ case 0x85 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0xac) {
+ return grn_nfkc50_char_type_table_f09d85[utf8[3] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[3] >= 0x83 &&
+ utf8[3] <= 0xbf) {
+ return grn_nfkc50_char_type_table_f09d86[utf8[3] - 0x83];
+ }
+ break;
+ case 0x87 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x9d) {
+ return GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 0x88 :
+ return GRN_CHAR_SYMBOL;
+ case 0x89 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x85) {
+ return grn_nfkc50_char_type_table_f09d89[utf8[3] - 0x80];
+ }
+ break;
+ case 0x8c :
+ return GRN_CHAR_SYMBOL;
+ case 0x8d :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0xb1) {
+ return grn_nfkc50_char_type_table_f09d8d[utf8[3] - 0x80];
+ }
+ break;
+ case 0x90 :
+ return GRN_CHAR_ALPHA;
+ case 0x91 :
+ return grn_nfkc50_char_type_table_f09d91[utf8[3] - 0x80];
+ case 0x92 :
+ return grn_nfkc50_char_type_table_f09d92[utf8[3] - 0x80];
+ case 0x93 :
+ return grn_nfkc50_char_type_table_f09d93[utf8[3] - 0x80];
+ case 0x94 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0xbe) {
+ return grn_nfkc50_char_type_table_f09d94[utf8[3] - 0x80];
+ }
+ break;
+ case 0x95 :
+ return grn_nfkc50_char_type_table_f09d95[utf8[3] - 0x80];
+ case 0x96 :
+ return GRN_CHAR_ALPHA;
+ case 0x97 :
+ return GRN_CHAR_ALPHA;
+ case 0x98 :
+ return GRN_CHAR_ALPHA;
+ case 0x99 :
+ return GRN_CHAR_ALPHA;
+ case 0x9a :
+ return grn_nfkc50_char_type_table_f09d9a[utf8[3] - 0x80];
+ case 0x9b :
+ return grn_nfkc50_char_type_table_f09d9b[utf8[3] - 0x80];
+ case 0x9c :
+ return grn_nfkc50_char_type_table_f09d9c[utf8[3] - 0x80];
+ case 0x9d :
+ return grn_nfkc50_char_type_table_f09d9d[utf8[3] - 0x80];
+ case 0x9e :
+ return grn_nfkc50_char_type_table_f09d9e[utf8[3] - 0x80];
+ case 0x9f :
+ return grn_nfkc50_char_type_table_f09d9f[utf8[3] - 0x80];
+ default :
+ break;
+ }
+ break;
+ case 0xa0 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xa1 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xa2 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xa3 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xa4 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xa5 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xa6 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xa7 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xa8 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xa9 :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ return GRN_CHAR_KANJI;
+ case 0x9c :
+ return GRN_CHAR_KANJI;
+ case 0x9d :
+ return GRN_CHAR_KANJI;
+ case 0x9e :
+ return GRN_CHAR_KANJI;
+ case 0x9f :
+ return GRN_CHAR_KANJI;
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ return GRN_CHAR_KANJI;
+ case 0xa9 :
+ return GRN_CHAR_KANJI;
+ case 0xaa :
+ return GRN_CHAR_KANJI;
+ case 0xab :
+ return GRN_CHAR_KANJI;
+ case 0xac :
+ return GRN_CHAR_KANJI;
+ case 0xad :
+ return GRN_CHAR_KANJI;
+ case 0xae :
+ return GRN_CHAR_KANJI;
+ case 0xaf :
+ return GRN_CHAR_KANJI;
+ case 0xb0 :
+ return GRN_CHAR_KANJI;
+ case 0xb1 :
+ return GRN_CHAR_KANJI;
+ case 0xb2 :
+ return GRN_CHAR_KANJI;
+ case 0xb3 :
+ return GRN_CHAR_KANJI;
+ case 0xb4 :
+ return GRN_CHAR_KANJI;
+ case 0xb5 :
+ return GRN_CHAR_KANJI;
+ case 0xb6 :
+ return GRN_CHAR_KANJI;
+ case 0xb7 :
+ return GRN_CHAR_KANJI;
+ case 0xb8 :
+ return GRN_CHAR_KANJI;
+ case 0xb9 :
+ return GRN_CHAR_KANJI;
+ case 0xba :
+ return GRN_CHAR_KANJI;
+ case 0xbb :
+ return GRN_CHAR_KANJI;
+ case 0xbc :
+ return GRN_CHAR_KANJI;
+ case 0xbd :
+ return GRN_CHAR_KANJI;
+ case 0xbe :
+ return GRN_CHAR_KANJI;
+ case 0xbf :
+ return GRN_CHAR_KANJI;
+ default :
+ break;
+ }
+ break;
+ case 0xaa :
+ switch (utf8[2]) {
+ case 0x80 :
+ return GRN_CHAR_KANJI;
+ case 0x81 :
+ return GRN_CHAR_KANJI;
+ case 0x82 :
+ return GRN_CHAR_KANJI;
+ case 0x83 :
+ return GRN_CHAR_KANJI;
+ case 0x84 :
+ return GRN_CHAR_KANJI;
+ case 0x85 :
+ return GRN_CHAR_KANJI;
+ case 0x86 :
+ return GRN_CHAR_KANJI;
+ case 0x87 :
+ return GRN_CHAR_KANJI;
+ case 0x88 :
+ return GRN_CHAR_KANJI;
+ case 0x89 :
+ return GRN_CHAR_KANJI;
+ case 0x8a :
+ return GRN_CHAR_KANJI;
+ case 0x8b :
+ return GRN_CHAR_KANJI;
+ case 0x8c :
+ return GRN_CHAR_KANJI;
+ case 0x8d :
+ return GRN_CHAR_KANJI;
+ case 0x8e :
+ return GRN_CHAR_KANJI;
+ case 0x8f :
+ return GRN_CHAR_KANJI;
+ case 0x90 :
+ return GRN_CHAR_KANJI;
+ case 0x91 :
+ return GRN_CHAR_KANJI;
+ case 0x92 :
+ return GRN_CHAR_KANJI;
+ case 0x93 :
+ return GRN_CHAR_KANJI;
+ case 0x94 :
+ return GRN_CHAR_KANJI;
+ case 0x95 :
+ return GRN_CHAR_KANJI;
+ case 0x96 :
+ return GRN_CHAR_KANJI;
+ case 0x97 :
+ return GRN_CHAR_KANJI;
+ case 0x98 :
+ return GRN_CHAR_KANJI;
+ case 0x99 :
+ return GRN_CHAR_KANJI;
+ case 0x9a :
+ return GRN_CHAR_KANJI;
+ case 0x9b :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x9f) {
+ return GRN_CHAR_KANJI;
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xaf :
+ switch (utf8[2]) {
+ case 0xa0 :
+ return GRN_CHAR_KANJI;
+ case 0xa1 :
+ return GRN_CHAR_KANJI;
+ case 0xa2 :
+ return GRN_CHAR_KANJI;
+ case 0xa3 :
+ return GRN_CHAR_KANJI;
+ case 0xa4 :
+ return GRN_CHAR_KANJI;
+ case 0xa5 :
+ return GRN_CHAR_KANJI;
+ case 0xa6 :
+ return GRN_CHAR_KANJI;
+ case 0xa7 :
+ return GRN_CHAR_KANJI;
+ case 0xa8 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x9f) {
+ return GRN_CHAR_KANJI;
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return GRN_CHAR_OTHERS;
+}
+
+static const char *grn_nfkc50_decompose_table_[] = {
+ "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67", "\x68",
+ "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70",
+ "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77", "\x78",
+ "\x79", "\x7a"
+};
+
+static const char *grn_nfkc50_decompose_table_c2[] = {
+ "\x20", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xcc\x88", NULL, "\x61", NULL, NULL, NULL, NULL, "\xcc\x84",
+ NULL, NULL, "\x32", "\x33", "\xcc\x81", "\xce\xbc", NULL, NULL,
+ "\xcc\xa7", "\x31", "\x6f", NULL, "\x31\xe2\x81\x84\x34", "\x31\xe2\x81\x84\x32", "\x33\xe2\x81\x84\x34"
+};
+
+static const char *grn_nfkc50_decompose_table_c3[] = {
+ "\xc3\xa0", "\xc3\xa1", "\xc3\xa2", "\xc3\xa3", "\xc3\xa4", "\xc3\xa5", NULL, "\xc3\xa7",
+ "\xc3\xa8", "\xc3\xa9", "\xc3\xaa", "\xc3\xab", "\xc3\xac", "\xc3\xad", "\xc3\xae", "\xc3\xaf",
+ NULL, "\xc3\xb1", "\xc3\xb2", "\xc3\xb3", "\xc3\xb4", "\xc3\xb5", "\xc3\xb6", NULL,
+ NULL, "\xc3\xb9", "\xc3\xba", "\xc3\xbb", "\xc3\xbc", "\xc3\xbd"
+};
+
+static const char *grn_nfkc50_decompose_table_c4[] = {
+ "\xc4\x81", NULL, "\xc4\x83", NULL, "\xc4\x85", NULL, "\xc4\x87", NULL,
+ "\xc4\x89", NULL, "\xc4\x8b", NULL, "\xc4\x8d", NULL, "\xc4\x8f", NULL,
+ NULL, NULL, "\xc4\x93", NULL, "\xc4\x95", NULL, "\xc4\x97", NULL,
+ "\xc4\x99", NULL, "\xc4\x9b", NULL, "\xc4\x9d", NULL, "\xc4\x9f", NULL,
+ "\xc4\xa1", NULL, "\xc4\xa3", NULL, "\xc4\xa5", NULL, NULL, NULL,
+ "\xc4\xa9", NULL, "\xc4\xab", NULL, "\xc4\xad", NULL, "\xc4\xaf", NULL,
+ "\x69\xcc\x87", NULL, "\x69\x6a", "\x69\x6a", "\xc4\xb5", NULL, "\xc4\xb7", NULL,
+ NULL, "\xc4\xba", NULL, "\xc4\xbc", NULL, "\xc4\xbe", NULL, "\x6c\xc2\xb7"
+};
+
+static const char *grn_nfkc50_decompose_table_c5[] = {
+ "\x6c\xc2\xb7", NULL, NULL, "\xc5\x84", NULL, "\xc5\x86", NULL, "\xc5\x88",
+ NULL, "\xca\xbc\x6e", NULL, NULL, "\xc5\x8d", NULL, "\xc5\x8f", NULL,
+ "\xc5\x91", NULL, NULL, NULL, "\xc5\x95", NULL, "\xc5\x97", NULL,
+ "\xc5\x99", NULL, "\xc5\x9b", NULL, "\xc5\x9d", NULL, "\xc5\x9f", NULL,
+ "\xc5\xa1", NULL, "\xc5\xa3", NULL, "\xc5\xa5", NULL, NULL, NULL,
+ "\xc5\xa9", NULL, "\xc5\xab", NULL, "\xc5\xad", NULL, "\xc5\xaf", NULL,
+ "\xc5\xb1", NULL, "\xc5\xb3", NULL, "\xc5\xb5", NULL, "\xc5\xb7", NULL,
+ "\xc3\xbf", "\xc5\xba", NULL, "\xc5\xbc", NULL, "\xc5\xbe", NULL, "\x73"
+};
+
+static const char *grn_nfkc50_decompose_table_c6[] = {
+ "\xc6\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xc6\xb0"
+};
+
+static const char *grn_nfkc50_decompose_table_c7[] = {
+ "\x64\xc5\xbe", "\x64\xc5\xbe", "\x64\xc5\xbe", "\x6c\x6a", "\x6c\x6a", "\x6c\x6a", "\x6e\x6a", "\x6e\x6a",
+ "\x6e\x6a", "\xc7\x8e", NULL, "\xc7\x90", NULL, "\xc7\x92", NULL, "\xc7\x94",
+ NULL, "\xc7\x96", NULL, "\xc7\x98", NULL, "\xc7\x9a", NULL, "\xc7\x9c",
+ NULL, NULL, "\xc7\x9f", NULL, "\xc7\xa1", NULL, NULL, NULL,
+ NULL, NULL, "\xc7\xa7", NULL, "\xc7\xa9", NULL, "\xc7\xab", NULL,
+ "\xc7\xad", NULL, NULL, NULL, NULL, "\x64\x7a", "\x64\x7a", "\x64\x7a",
+ "\xc7\xb5", NULL, NULL, NULL, "\xc7\xb9", NULL, "\xc7\xbb"
+};
+
+static const char *grn_nfkc50_decompose_table_c8[] = {
+ "\xc8\x81", NULL, "\xc8\x83", NULL, "\xc8\x85", NULL, "\xc8\x87", NULL,
+ "\xc8\x89", NULL, "\xc8\x8b", NULL, "\xc8\x8d", NULL, "\xc8\x8f", NULL,
+ "\xc8\x91", NULL, "\xc8\x93", NULL, "\xc8\x95", NULL, "\xc8\x97", NULL,
+ "\xc8\x99", NULL, "\xc8\x9b", NULL, NULL, NULL, "\xc8\x9f", NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, "\xc8\xa7", NULL,
+ "\xc8\xa9", NULL, "\xc8\xab", NULL, "\xc8\xad", NULL, "\xc8\xaf", NULL,
+ "\xc8\xb1", NULL, "\xc8\xb3"
+};
+
+static const char *grn_nfkc50_decompose_table_ca[] = {
+ "\x68", "\xc9\xa6", "\x6a", "\x72", "\xc9\xb9", "\xc9\xbb", "\xca\x81", "\x77",
+ "\x79"
+};
+
+static const char *grn_nfkc50_decompose_table_cb[] = {
+ "\xcc\x86", "\xcc\x87", "\xcc\x8a", "\xcc\xa8", "\xcc\x83", "\xcc\x8b", NULL, NULL,
+ "\xc9\xa3", "\x6c", "\x73", "\x78", "\xca\x95"
+};
+
+static const char *grn_nfkc50_decompose_table_cd[] = {
+ "\xcc\x80", "\xcc\x81", NULL, "\xcc\x93", "\xcc\x88\xcc\x81", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xca\xb9", NULL, NULL, NULL,
+ NULL, NULL, "\xcd\x85", NULL, NULL, NULL, "\x3b"
+};
+
+static const char *grn_nfkc50_decompose_table_ce[] = {
+ "\xcc\x81", "\xcc\x88\xcc\x81", NULL, "\xc2\xb7"
+};
+
+static const char *grn_nfkc50_decompose_table_cf[] = {
+ "\xce\xb2", "\xce\xb8", "\xce\xa5", "\xce\x8e", "\xce\xab", "\xcf\x86", "\xcf\x80", NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xce\xba", "\xcf\x81", "\xcf\x82", NULL, "\xce\x98", "\xce\xb5", NULL, NULL,
+ NULL, "\xce\xa3"
+};
+
+static const char *grn_nfkc50_decompose_table_d9[] = {
+ "\xd8\xa7\xd9\xb4", "\xd9\x88\xd9\xb4", "\xdb\x87\xd9\xb4", "\xd9\x8a\xd9\xb4"
+};
+
+static const char *grn_nfkc50_decompose_table_e0a5[] = {
+ "\xe0\xa4\x95\xe0\xa4\xbc", "\xe0\xa4\x96\xe0\xa4\xbc", "\xe0\xa4\x97\xe0\xa4\xbc", "\xe0\xa4\x9c\xe0\xa4\xbc", "\xe0\xa4\xa1\xe0\xa4\xbc", "\xe0\xa4\xa2\xe0\xa4\xbc", "\xe0\xa4\xab\xe0\xa4\xbc", "\xe0\xa4\xaf\xe0\xa4\xbc"
+};
+
+static const char *grn_nfkc50_decompose_table_e0a7[] = {
+ "\xe0\xa6\xa1\xe0\xa6\xbc", "\xe0\xa6\xa2\xe0\xa6\xbc", NULL, "\xe0\xa6\xaf\xe0\xa6\xbc"
+};
+
+static const char *grn_nfkc50_decompose_table_e0a8[] = {
+ "\xe0\xa8\xb2\xe0\xa8\xbc", NULL, NULL, "\xe0\xa8\xb8\xe0\xa8\xbc"
+};
+
+static const char *grn_nfkc50_decompose_table_e0a9[] = {
+ "\xe0\xa8\x96\xe0\xa8\xbc", "\xe0\xa8\x97\xe0\xa8\xbc", "\xe0\xa8\x9c\xe0\xa8\xbc", NULL, NULL, "\xe0\xa8\xab\xe0\xa8\xbc"
+};
+
+static const char *grn_nfkc50_decompose_table_e0ad[] = {
+ "\xe0\xac\xa1\xe0\xac\xbc", "\xe0\xac\xa2\xe0\xac\xbc"
+};
+
+static const char *grn_nfkc50_decompose_table_e0bb[] = {
+ "\xe0\xba\xab\xe0\xba\x99", "\xe0\xba\xab\xe0\xba\xa1"
+};
+
+static const char *grn_nfkc50_decompose_table_e0bd[] = {
+ "\xe0\xbd\x82\xe0\xbe\xb7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, "\xe0\xbd\x8c\xe0\xbe\xb7", NULL, NULL, NULL, NULL, "\xe0\xbd\x91\xe0\xbe\xb7",
+ NULL, NULL, NULL, NULL, "\xe0\xbd\x96\xe0\xbe\xb7", NULL, NULL, NULL,
+ NULL, "\xe0\xbd\x9b\xe0\xbe\xb7", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, "\xe0\xbd\x80\xe0\xbe\xb5", NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe0\xbd\xb1\xe0\xbd\xb2", NULL, "\xe0\xbd\xb1\xe0\xbd\xb4", "\xe0\xbe\xb2\xe0\xbe\x80", "\xe0\xbe\xb2\xe0\xbd\xb1\xe0\xbe\x80", "\xe0\xbe\xb3\xe0\xbe\x80", "\xe0\xbe\xb3\xe0\xbd\xb1\xe0\xbe\x80"
+};
+
+static const char *grn_nfkc50_decompose_table_e0be[] = {
+ "\xe0\xbd\xb1\xe0\xbe\x80", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, "\xe0\xbe\x92\xe0\xbe\xb7", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xe0\xbe\x9c\xe0\xbe\xb7", NULL, NULL, NULL,
+ NULL, "\xe0\xbe\xa1\xe0\xbe\xb7", NULL, NULL, NULL, NULL, "\xe0\xbe\xa6\xe0\xbe\xb7", NULL,
+ NULL, NULL, NULL, "\xe0\xbe\xab\xe0\xbe\xb7", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe0\xbe\x90\xe0\xbe\xb5"
+};
+
+static const char *grn_nfkc50_decompose_table_e1b4[] = {
+ "\x61", "\xc3\x86", "\x62", NULL, "\x64", "\x65", "\xc6\x8e", "\x67",
+ "\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", NULL,
+ "\x6f", "\xc8\xa2", "\x70", "\x72"
+};
+
+static const char *grn_nfkc50_decompose_table_e1b5[] = {
+ "\x74", "\x75", "\x77", "\x61", "\xc9\x90", "\xc9\x91", "\xe1\xb4\x82", "\x62",
+ "\x64", "\x65", "\xc9\x99", "\xc9\x9b", "\xc9\x9c", "\x67", NULL, "\x6b",
+ "\x6d", "\xc5\x8b", "\x6f", "\xc9\x94", "\xe1\xb4\x96", "\xe1\xb4\x97", "\x70", "\x74",
+ "\x75", "\xe1\xb4\x9d", "\xc9\xaf", "\x76", "\xe1\xb4\xa5", "\xce\xb2", "\xce\xb3", "\xce\xb4",
+ "\xcf\x86", "\xcf\x87", "\x69", "\x72", "\x75", "\x76", "\xce\xb2", "\xce\xb3",
+ "\xcf\x81", "\xcf\x86", "\xcf\x87", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xd0\xbd"
+};
+
+static const char *grn_nfkc50_decompose_table_e1b6[] = {
+ "\xc9\x92", "\x63", "\xc9\x95", "\xc3\xb0", "\xc9\x9c", "\x66", "\xc9\x9f", "\xc9\xa1",
+ "\xc9\xa5", "\xc9\xa8", "\xc9\xa9", "\xc9\xaa", "\xe1\xb5\xbb", "\xca\x9d", "\xc9\xad", "\xe1\xb6\x85",
+ "\xca\x9f", "\xc9\xb1", "\xc9\xb0", "\xc9\xb2", "\xc9\xb3", "\xc9\xb4", "\xc9\xb5", "\xc9\xb8",
+ "\xca\x82", "\xca\x83", "\xc6\xab", "\xca\x89", "\xca\x8a", "\xe1\xb4\x9c", "\xca\x8b", "\xca\x8c",
+ "\x7a", "\xca\x90", "\xca\x91", "\xca\x92", "\xce\xb8"
+};
+
+static const char *grn_nfkc50_decompose_table_e1b8[] = {
+ "\xe1\xb8\x81", NULL, "\xe1\xb8\x83", NULL, "\xe1\xb8\x85", NULL, "\xe1\xb8\x87", NULL,
+ "\xe1\xb8\x89", NULL, "\xe1\xb8\x8b", NULL, "\xe1\xb8\x8d", NULL, "\xe1\xb8\x8f", NULL,
+ "\xe1\xb8\x91", NULL, "\xe1\xb8\x93", NULL, "\xe1\xb8\x95", NULL, "\xe1\xb8\x97", NULL,
+ "\xe1\xb8\x99", NULL, "\xe1\xb8\x9b", NULL, "\xe1\xb8\x9d", NULL, "\xe1\xb8\x9f", NULL,
+ "\xe1\xb8\xa1", NULL, "\xe1\xb8\xa3", NULL, "\xe1\xb8\xa5", NULL, "\xe1\xb8\xa7", NULL,
+ "\xe1\xb8\xa9", NULL, "\xe1\xb8\xab", NULL, "\xe1\xb8\xad", NULL, "\xe1\xb8\xaf", NULL,
+ "\xe1\xb8\xb1", NULL, "\xe1\xb8\xb3", NULL, "\xe1\xb8\xb5", NULL, "\xe1\xb8\xb7", NULL,
+ "\xe1\xb8\xb9", NULL, "\xe1\xb8\xbb", NULL, "\xe1\xb8\xbd", NULL, "\xe1\xb8\xbf"
+};
+
+static const char *grn_nfkc50_decompose_table_e1b9[] = {
+ "\xe1\xb9\x81", NULL, "\xe1\xb9\x83", NULL, "\xe1\xb9\x85", NULL, "\xe1\xb9\x87", NULL,
+ "\xe1\xb9\x89", NULL, "\xe1\xb9\x8b", NULL, "\xe1\xb9\x8d", NULL, "\xe1\xb9\x8f", NULL,
+ "\xe1\xb9\x91", NULL, "\xe1\xb9\x93", NULL, "\xe1\xb9\x95", NULL, "\xe1\xb9\x97", NULL,
+ "\xe1\xb9\x99", NULL, "\xe1\xb9\x9b", NULL, "\xe1\xb9\x9d", NULL, "\xe1\xb9\x9f", NULL,
+ "\xe1\xb9\xa1", NULL, "\xe1\xb9\xa3", NULL, "\xe1\xb9\xa5", NULL, "\xe1\xb9\xa7", NULL,
+ "\xe1\xb9\xa9", NULL, "\xe1\xb9\xab", NULL, "\xe1\xb9\xad", NULL, "\xe1\xb9\xaf", NULL,
+ "\xe1\xb9\xb1", NULL, "\xe1\xb9\xb3", NULL, "\xe1\xb9\xb5", NULL, "\xe1\xb9\xb7", NULL,
+ "\xe1\xb9\xb9", NULL, "\xe1\xb9\xbb", NULL, "\xe1\xb9\xbd", NULL, "\xe1\xb9\xbf"
+};
+
+static const char *grn_nfkc50_decompose_table_e1ba[] = {
+ "\xe1\xba\x81", NULL, "\xe1\xba\x83", NULL, "\xe1\xba\x85", NULL, "\xe1\xba\x87", NULL,
+ "\xe1\xba\x89", NULL, "\xe1\xba\x8b", NULL, "\xe1\xba\x8d", NULL, "\xe1\xba\x8f", NULL,
+ "\xe1\xba\x91", NULL, "\xe1\xba\x93", NULL, "\xe1\xba\x95", NULL, NULL, NULL,
+ NULL, NULL, "\x61\xca\xbe", "\xe1\xb9\xa1", NULL, NULL, NULL, NULL,
+ "\xe1\xba\xa1", NULL, "\xe1\xba\xa3", NULL, "\xe1\xba\xa5", NULL, "\xe1\xba\xa7", NULL,
+ "\xe1\xba\xa9", NULL, "\xe1\xba\xab", NULL, "\xe1\xba\xad", NULL, "\xe1\xba\xaf", NULL,
+ "\xe1\xba\xb1", NULL, "\xe1\xba\xb3", NULL, "\xe1\xba\xb5", NULL, "\xe1\xba\xb7", NULL,
+ "\xe1\xba\xb9", NULL, "\xe1\xba\xbb", NULL, "\xe1\xba\xbd", NULL, "\xe1\xba\xbf"
+};
+
+static const char *grn_nfkc50_decompose_table_e1bb[] = {
+ "\xe1\xbb\x81", NULL, "\xe1\xbb\x83", NULL, "\xe1\xbb\x85", NULL, "\xe1\xbb\x87", NULL,
+ "\xe1\xbb\x89", NULL, "\xe1\xbb\x8b", NULL, "\xe1\xbb\x8d", NULL, "\xe1\xbb\x8f", NULL,
+ "\xe1\xbb\x91", NULL, "\xe1\xbb\x93", NULL, "\xe1\xbb\x95", NULL, "\xe1\xbb\x97", NULL,
+ "\xe1\xbb\x99", NULL, "\xe1\xbb\x9b", NULL, "\xe1\xbb\x9d", NULL, "\xe1\xbb\x9f", NULL,
+ "\xe1\xbb\xa1", NULL, "\xe1\xbb\xa3", NULL, "\xe1\xbb\xa5", NULL, "\xe1\xbb\xa7", NULL,
+ "\xe1\xbb\xa9", NULL, "\xe1\xbb\xab", NULL, "\xe1\xbb\xad", NULL, "\xe1\xbb\xaf", NULL,
+ "\xe1\xbb\xb1", NULL, "\xe1\xbb\xb3", NULL, "\xe1\xbb\xb5", NULL, "\xe1\xbb\xb7", NULL,
+ "\xe1\xbb\xb9"
+};
+
+static const char *grn_nfkc50_decompose_table_e1bd[] = {
+ "\xce\xac", NULL, "\xce\xad", NULL, "\xce\xae", NULL, "\xce\xaf", NULL,
+ "\xcf\x8c", NULL, "\xcf\x8d", NULL, "\xcf\x8e"
+};
+
+static const char *grn_nfkc50_decompose_table_e1be[] = {
+ "\xce\x86", NULL, "\xcc\x93", "\xce\xb9", "\xcc\x93"
+};
+
+static const char *grn_nfkc50_decompose_table_e1bf[] = {
+ "\xcd\x82", "\xcc\x88\xcd\x82", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, "\xce\x88", NULL, "\xce\x89", NULL, "\xcc\x93\xcc\x80", "\xcc\x93\xcc\x81", "\xcc\x93\xcd\x82",
+ NULL, NULL, NULL, "\xce\x90", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "\xce\x8a", NULL, "\xcc\x94\xcc\x80", "\xcc\x94\xcc\x81", "\xcc\x94\xcd\x82",
+ NULL, NULL, NULL, "\xce\xb0", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "\xce\x8e", NULL, "\xcc\x88\xcc\x80", "\xcc\x88\xcc\x81", "\x60",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, "\xce\x8c", NULL, "\xce\x8f", NULL, "\xcc\x81", "\xcc\x94"
+};
+
+static const char *grn_nfkc50_decompose_table_e280[] = {
+ "\x20", "\x20", "\x20", "\x20", "\x20", "\x20", "\x20", "\x20",
+ "\x20", "\x20", "\x20", NULL, NULL, NULL, NULL, NULL,
+ NULL, "\xe2\x80\x90", NULL, NULL, NULL, NULL, NULL, "\xcc\xb3",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\x2e", "\x2e\x2e", "\x2e\x2e\x2e", NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\x20",
+ NULL, NULL, NULL, "\xe2\x80\xb2\xe2\x80\xb2", "\xe2\x80\xb2\xe2\x80\xb2\xe2\x80\xb2", NULL, "\xe2\x80\xb5\xe2\x80\xb5", "\xe2\x80\xb5\xe2\x80\xb5\xe2\x80\xb5",
+ NULL, NULL, NULL, NULL, "\x21\x21", NULL, "\xcc\x85"
+};
+
+static const char *grn_nfkc50_decompose_table_e281[] = {
+ "\x3f\x3f", "\x3f\x21", "\x21\x3f", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe2\x80\xb2\xe2\x80\xb2\xe2\x80\xb2\xe2\x80\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\x20", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, "\x30", "\x69", NULL, NULL, "\x34", "\x35", "\x36",
+ "\x37", "\x38", "\x39", "\x2b", "\xe2\x88\x92", "\x3d", "\x28", "\x29",
+ "\x6e"
+};
+
+static const char *grn_nfkc50_decompose_table_e282[] = {
+ "\x30", "\x31", "\x32", "\x33", "\x34", "\x35", "\x36", "\x37",
+ "\x38", "\x39", "\x2b", "\xe2\x88\x92", "\x3d", "\x28", "\x29", NULL,
+ "\x61", "\x65", "\x6f", "\x78", "\xc9\x99", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\x72\x73"
+};
+
+static const char *grn_nfkc50_decompose_table_e284[] = {
+ "\x61\x2f\x63", "\x61\x2f\x73", "\x63", "\xc2\xb0\x63", NULL, "\x63\x2f\x6f", "\x63\x2f\x75", "\xc6\x90",
+ NULL, "\xc2\xb0\x66", "\x67", "\x68", "\x68", "\x68", "\x68", "\xc4\xa7",
+ "\x69", "\x69", "\x6c", "\x6c", NULL, "\x6e", "\x6e\x6f", NULL,
+ NULL, "\x70", "\x71", "\x72", "\x72", "\x72", NULL, NULL,
+ "\x73\x6d", "\x74\x65\x6c", "\x74\x6d", NULL, "\x7a", NULL, "\xce\xa9", NULL,
+ "\x7a", NULL, "\x6b", "\xc3\xa5", "\x62", "\x63", NULL, "\x65",
+ "\x65", "\x66", NULL, "\x6d", "\x6f", "\xd7\x90", "\xd7\x91", "\xd7\x92",
+ "\xd7\x93", "\x69", NULL, "\x66\x61\x78", "\xcf\x80", "\xce\xb3", "\xce\x93", "\xce\xa0"
+};
+
+static const char *grn_nfkc50_decompose_table_e285[] = {
+ "\xe2\x88\x91", NULL, NULL, NULL, NULL, "\x64", "\x64", "\x65",
+ "\x69", "\x6a", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "\x31\xe2\x81\x84\x33", "\x32\xe2\x81\x84\x33", "\x31\xe2\x81\x84\x35", "\x32\xe2\x81\x84\x35", "\x33\xe2\x81\x84\x35",
+ "\x34\xe2\x81\x84\x35", "\x31\xe2\x81\x84\x36", "\x35\xe2\x81\x84\x36", "\x31\xe2\x81\x84\x38", "\x33\xe2\x81\x84\x38", "\x35\xe2\x81\x84\x38", "\x37\xe2\x81\x84\x38", "\x31\xe2\x81\x84",
+ "\x69", "\x69\x69", "\x69\x69\x69", "\x69\x76", "\x76", "\x76\x69", "\x76\x69\x69", "\x76\x69\x69\x69",
+ "\x69\x78", "\x78", "\x78\x69", "\x78\x69\x69", "\x6c", "\x63", "\x64", "\x6d",
+ "\x69", "\x69\x69", "\x69\x69\x69", "\x69\x76", "\x76", "\x76\x69", "\x76\x69\x69", "\x76\x69\x69\x69",
+ "\x69\x78", "\x78", "\x78\x69", "\x78\x69\x69", "\x6c", "\x63", "\x64", "\x6d"
+};
+
+static const char *grn_nfkc50_decompose_table_e288[] = {
+ "\xe2\x88\xab\xe2\x88\xab", "\xe2\x88\xab\xe2\x88\xab\xe2\x88\xab", NULL, "\xe2\x88\xae\xe2\x88\xae", "\xe2\x88\xae\xe2\x88\xae\xe2\x88\xae"
+};
+
+static const char *grn_nfkc50_decompose_table_e28c[] = {
+ "\xe3\x80\x88", "\xe3\x80\x89"
+};
+
+static const char *grn_nfkc50_decompose_table_e291[] = {
+ "\x31", "\x32", "\x33", "\x34", "\x35", "\x36", "\x37", "\x38",
+ "\x39", "\x31\x30", "\x31\x31", "\x31\x32", "\x31\x33", "\x31\x34", "\x31\x35", "\x31\x36",
+ "\x31\x37", "\x31\x38", "\x31\x39", "\x32\x30", "\x28\x31\x29", "\x28\x32\x29", "\x28\x33\x29", "\x28\x34\x29",
+ "\x28\x35\x29", "\x28\x36\x29", "\x28\x37\x29", "\x28\x38\x29", "\x28\x39\x29", "\x28\x31\x30\x29", "\x28\x31\x31\x29", "\x28\x31\x32\x29"
+};
+
+static const char *grn_nfkc50_decompose_table_e292[] = {
+ "\x28\x31\x33\x29", "\x28\x31\x34\x29", "\x28\x31\x35\x29", "\x28\x31\x36\x29", "\x28\x31\x37\x29", "\x28\x31\x38\x29", "\x28\x31\x39\x29", "\x28\x32\x30\x29",
+ "\x31\x2e", "\x32\x2e", "\x33\x2e", "\x34\x2e", "\x35\x2e", "\x36\x2e", "\x37\x2e", "\x38\x2e",
+ "\x39\x2e", "\x31\x30\x2e", "\x31\x31\x2e", "\x31\x32\x2e", "\x31\x33\x2e", "\x31\x34\x2e", "\x31\x35\x2e", "\x31\x36\x2e",
+ "\x31\x37\x2e", "\x31\x38\x2e", "\x31\x39\x2e", "\x32\x30\x2e", "\x28\x61\x29", "\x28\x62\x29", "\x28\x63\x29", "\x28\x64\x29",
+ "\x28\x65\x29", "\x28\x66\x29", "\x28\x67\x29", "\x28\x68\x29", "\x28\x69\x29", "\x28\x6a\x29", "\x28\x6b\x29", "\x28\x6c\x29",
+ "\x28\x6d\x29", "\x28\x6e\x29", "\x28\x6f\x29", "\x28\x70\x29", "\x28\x71\x29", "\x28\x72\x29", "\x28\x73\x29", "\x28\x74\x29",
+ "\x28\x75\x29", "\x28\x76\x29", "\x28\x77\x29", "\x28\x78\x29", "\x28\x79\x29", "\x28\x7a\x29", "\x61", "\x62",
+ "\x63", "\x64", "\x65", "\x66", "\x67", "\x68", "\x69", "\x6a"
+};
+
+static const char *grn_nfkc50_decompose_table_e293[] = {
+ "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70", "\x71", "\x72",
+ "\x73", "\x74", "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a",
+ "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67", "\x68",
+ "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70",
+ "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77", "\x78",
+ "\x79", "\x7a", "\x30"
+};
+
+static const char *grn_nfkc50_decompose_table_e2a9[] = {
+ "\x3a\x3a\x3d", "\x3d\x3d", "\x3d\x3d\x3d"
+};
+
+static const char *grn_nfkc50_decompose_table_e2bc[] = {
+ "\xe4\xb8\x80", "\xe4\xb8\xa8", "\xe4\xb8\xb6", "\xe4\xb8\xbf", "\xe4\xb9\x99", "\xe4\xba\x85", "\xe4\xba\x8c", "\xe4\xba\xa0",
+ "\xe4\xba\xba", "\xe5\x84\xbf", "\xe5\x85\xa5", "\xe5\x85\xab", "\xe5\x86\x82", "\xe5\x86\x96", "\xe5\x86\xab", "\xe5\x87\xa0",
+ "\xe5\x87\xb5", "\xe5\x88\x80", "\xe5\x8a\x9b", "\xe5\x8b\xb9", "\xe5\x8c\x95", "\xe5\x8c\x9a", "\xe5\x8c\xb8", "\xe5\x8d\x81",
+ "\xe5\x8d\x9c", "\xe5\x8d\xa9", "\xe5\x8e\x82", "\xe5\x8e\xb6", "\xe5\x8f\x88", "\xe5\x8f\xa3", "\xe5\x9b\x97", "\xe5\x9c\x9f",
+ "\xe5\xa3\xab", "\xe5\xa4\x82", "\xe5\xa4\x8a", "\xe5\xa4\x95", "\xe5\xa4\xa7", "\xe5\xa5\xb3", "\xe5\xad\x90", "\xe5\xae\x80",
+ "\xe5\xaf\xb8", "\xe5\xb0\x8f", "\xe5\xb0\xa2", "\xe5\xb0\xb8", "\xe5\xb1\xae", "\xe5\xb1\xb1", "\xe5\xb7\x9b", "\xe5\xb7\xa5",
+ "\xe5\xb7\xb1", "\xe5\xb7\xbe", "\xe5\xb9\xb2", "\xe5\xb9\xba", "\xe5\xb9\xbf", "\xe5\xbb\xb4", "\xe5\xbb\xbe", "\xe5\xbc\x8b",
+ "\xe5\xbc\x93", "\xe5\xbd\x90", "\xe5\xbd\xa1", "\xe5\xbd\xb3", "\xe5\xbf\x83", "\xe6\x88\x88", "\xe6\x88\xb6", "\xe6\x89\x8b"
+};
+
+static const char *grn_nfkc50_decompose_table_e2bd[] = {
+ "\xe6\x94\xaf", "\xe6\x94\xb4", "\xe6\x96\x87", "\xe6\x96\x97", "\xe6\x96\xa4", "\xe6\x96\xb9", "\xe6\x97\xa0", "\xe6\x97\xa5",
+ "\xe6\x9b\xb0", "\xe6\x9c\x88", "\xe6\x9c\xa8", "\xe6\xac\xa0", "\xe6\xad\xa2", "\xe6\xad\xb9", "\xe6\xae\xb3", "\xe6\xaf\x8b",
+ "\xe6\xaf\x94", "\xe6\xaf\x9b", "\xe6\xb0\x8f", "\xe6\xb0\x94", "\xe6\xb0\xb4", "\xe7\x81\xab", "\xe7\x88\xaa", "\xe7\x88\xb6",
+ "\xe7\x88\xbb", "\xe7\x88\xbf", "\xe7\x89\x87", "\xe7\x89\x99", "\xe7\x89\x9b", "\xe7\x8a\xac", "\xe7\x8e\x84", "\xe7\x8e\x89",
+ "\xe7\x93\x9c", "\xe7\x93\xa6", "\xe7\x94\x98", "\xe7\x94\x9f", "\xe7\x94\xa8", "\xe7\x94\xb0", "\xe7\x96\x8b", "\xe7\x96\x92",
+ "\xe7\x99\xb6", "\xe7\x99\xbd", "\xe7\x9a\xae", "\xe7\x9a\xbf", "\xe7\x9b\xae", "\xe7\x9f\x9b", "\xe7\x9f\xa2", "\xe7\x9f\xb3",
+ "\xe7\xa4\xba", "\xe7\xa6\xb8", "\xe7\xa6\xbe", "\xe7\xa9\xb4", "\xe7\xab\x8b", "\xe7\xab\xb9", "\xe7\xb1\xb3", "\xe7\xb3\xb8",
+ "\xe7\xbc\xb6", "\xe7\xbd\x91", "\xe7\xbe\x8a", "\xe7\xbe\xbd", "\xe8\x80\x81", "\xe8\x80\x8c", "\xe8\x80\x92", "\xe8\x80\xb3"
+};
+
+static const char *grn_nfkc50_decompose_table_e2be[] = {
+ "\xe8\x81\xbf", "\xe8\x82\x89", "\xe8\x87\xa3", "\xe8\x87\xaa", "\xe8\x87\xb3", "\xe8\x87\xbc", "\xe8\x88\x8c", "\xe8\x88\x9b",
+ "\xe8\x88\x9f", "\xe8\x89\xae", "\xe8\x89\xb2", "\xe8\x89\xb8", "\xe8\x99\x8d", "\xe8\x99\xab", "\xe8\xa1\x80", "\xe8\xa1\x8c",
+ "\xe8\xa1\xa3", "\xe8\xa5\xbe", "\xe8\xa6\x8b", "\xe8\xa7\x92", "\xe8\xa8\x80", "\xe8\xb0\xb7", "\xe8\xb1\x86", "\xe8\xb1\x95",
+ "\xe8\xb1\xb8", "\xe8\xb2\x9d", "\xe8\xb5\xa4", "\xe8\xb5\xb0", "\xe8\xb6\xb3", "\xe8\xba\xab", "\xe8\xbb\x8a", "\xe8\xbe\x9b",
+ "\xe8\xbe\xb0", "\xe8\xbe\xb5", "\xe9\x82\x91", "\xe9\x85\x89", "\xe9\x87\x86", "\xe9\x87\x8c", "\xe9\x87\x91", "\xe9\x95\xb7",
+ "\xe9\x96\x80", "\xe9\x98\x9c", "\xe9\x9a\xb6", "\xe9\x9a\xb9", "\xe9\x9b\xa8", "\xe9\x9d\x91", "\xe9\x9d\x9e", "\xe9\x9d\xa2",
+ "\xe9\x9d\xa9", "\xe9\x9f\x8b", "\xe9\x9f\xad", "\xe9\x9f\xb3", "\xe9\xa0\x81", "\xe9\xa2\xa8", "\xe9\xa3\x9b", "\xe9\xa3\x9f",
+ "\xe9\xa6\x96", "\xe9\xa6\x99", "\xe9\xa6\xac", "\xe9\xaa\xa8", "\xe9\xab\x98", "\xe9\xab\x9f", "\xe9\xac\xa5", "\xe9\xac\xaf"
+};
+
+static const char *grn_nfkc50_decompose_table_e2bf[] = {
+ "\xe9\xac\xb2", "\xe9\xac\xbc", "\xe9\xad\x9a", "\xe9\xb3\xa5", "\xe9\xb9\xb5", "\xe9\xb9\xbf", "\xe9\xba\xa5", "\xe9\xba\xbb",
+ "\xe9\xbb\x83", "\xe9\xbb\x8d", "\xe9\xbb\x91", "\xe9\xbb\xb9", "\xe9\xbb\xbd", "\xe9\xbc\x8e", "\xe9\xbc\x93", "\xe9\xbc\xa0",
+ "\xe9\xbc\xbb", "\xe9\xbd\x8a", "\xe9\xbd\x92", "\xe9\xbe\x8d", "\xe9\xbe\x9c", "\xe9\xbe\xa0"
+};
+
+static const char *grn_nfkc50_decompose_table_e380[] = {
+ "\x20", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\x7e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, "\xe3\x80\x92", NULL,
+ "\xe5\x8d\x81", "\xe5\x8d\x84", "\xe5\x8d\x85"
+};
+
+static const char *grn_nfkc50_decompose_table_e382[] = {
+ "\xe3\x82\x99", "\xe3\x82\x9a", NULL, NULL, "\xe3\x82\x88\xe3\x82\x8a"
+};
+
+static const char *grn_nfkc50_decompose_table_e384[] = {
+ "\xe1\x84\x80", "\xe1\x84\x81", "\xe1\x86\xaa", "\xe1\x84\x82", "\xe1\x86\xac", "\xe1\x86\xad", "\xe1\x84\x83", "\xe1\x84\x84",
+ "\xe1\x84\x85", "\xe1\x86\xb0", "\xe1\x86\xb1", "\xe1\x86\xb2", "\xe1\x86\xb3", "\xe1\x86\xb4", "\xe1\x86\xb5"
+};
+
+static const char *grn_nfkc50_decompose_table_e385[] = {
+ "\xe1\x84\x9a", "\xe1\x84\x86", "\xe1\x84\x87", "\xe1\x84\x88", "\xe1\x84\xa1", "\xe1\x84\x89", "\xe1\x84\x8a", "\xe1\x84\x8b",
+ "\xe1\x84\x8c", "\xe1\x84\x8d", "\xe1\x84\x8e", "\xe1\x84\x8f", "\xe1\x84\x90", "\xe1\x84\x91", "\xe1\x84\x92", "\xe1\x85\xa1",
+ "\xe1\x85\xa2", "\xe1\x85\xa3", "\xe1\x85\xa4", "\xe1\x85\xa5", "\xe1\x85\xa6", "\xe1\x85\xa7", "\xe1\x85\xa8", "\xe1\x85\xa9",
+ "\xe1\x85\xaa", "\xe1\x85\xab", "\xe1\x85\xac", "\xe1\x85\xad", "\xe1\x85\xae", "\xe1\x85\xaf", "\xe1\x85\xb0", "\xe1\x85\xb1",
+ "\xe1\x85\xb2", "\xe1\x85\xb3", "\xe1\x85\xb4", "\xe1\x85\xb5", "\xe1\x85\xa0", "\xe1\x84\x94", "\xe1\x84\x95", "\xe1\x87\x87",
+ "\xe1\x87\x88", "\xe1\x87\x8c", "\xe1\x87\x8e", "\xe1\x87\x93", "\xe1\x87\x97", "\xe1\x87\x99", "\xe1\x84\x9c", "\xe1\x87\x9d",
+ "\xe1\x87\x9f", "\xe1\x84\x9d", "\xe1\x84\x9e", "\xe1\x84\xa0", "\xe1\x84\xa2", "\xe1\x84\xa3", "\xe1\x84\xa7", "\xe1\x84\xa9",
+ "\xe1\x84\xab", "\xe1\x84\xac", "\xe1\x84\xad", "\xe1\x84\xae", "\xe1\x84\xaf", "\xe1\x84\xb2", "\xe1\x84\xb6", "\xe1\x85\x80"
+};
+
+static const char *grn_nfkc50_decompose_table_e386[] = {
+ "\xe1\x85\x87", "\xe1\x85\x8c", "\xe1\x87\xb1", "\xe1\x87\xb2", "\xe1\x85\x97", "\xe1\x85\x98", "\xe1\x85\x99", "\xe1\x86\x84",
+ "\xe1\x86\x85", "\xe1\x86\x88", "\xe1\x86\x91", "\xe1\x86\x92", "\xe1\x86\x94", "\xe1\x86\x9e", "\xe1\x86\xa1", NULL,
+ NULL, NULL, "\xe4\xb8\x80", "\xe4\xba\x8c", "\xe4\xb8\x89", "\xe5\x9b\x9b", "\xe4\xb8\x8a", "\xe4\xb8\xad",
+ "\xe4\xb8\x8b", "\xe7\x94\xb2", "\xe4\xb9\x99", "\xe4\xb8\x99", "\xe4\xb8\x81", "\xe5\xa4\xa9", "\xe5\x9c\xb0", "\xe4\xba\xba"
+};
+
+static const char *grn_nfkc50_decompose_table_e388[] = {
+ "\x28\xe1\x84\x80\x29", "\x28\xe1\x84\x82\x29", "\x28\xe1\x84\x83\x29", "\x28\xe1\x84\x85\x29", "\x28\xe1\x84\x86\x29", "\x28\xe1\x84\x87\x29", "\x28\xe1\x84\x89\x29", "\x28\xe1\x84\x8b\x29",
+ "\x28\xe1\x84\x8c\x29", "\x28\xe1\x84\x8e\x29", "\x28\xe1\x84\x8f\x29", "\x28\xe1\x84\x90\x29", "\x28\xe1\x84\x91\x29", "\x28\xe1\x84\x92\x29", "\x28\xea\xb0\x80\x29", "\x28\xeb\x82\x98\x29",
+ "\x28\xeb\x8b\xa4\x29", "\x28\xeb\x9d\xbc\x29", "\x28\xeb\xa7\x88\x29", "\x28\xeb\xb0\x94\x29", "\x28\xec\x82\xac\x29", "\x28\xec\x95\x84\x29", "\x28\xec\x9e\x90\x29", "\x28\xec\xb0\xa8\x29",
+ "\x28\xec\xb9\xb4\x29", "\x28\xed\x83\x80\x29", "\x28\xed\x8c\x8c\x29", "\x28\xed\x95\x98\x29", "\x28\xec\xa3\xbc\x29", "\x28\xec\x98\xa4\xec\xa0\x84\x29", "\x28\xec\x98\xa4\xed\x9b\x84\x29", NULL,
+ "\x28\xe4\xb8\x80\x29", "\x28\xe4\xba\x8c\x29", "\x28\xe4\xb8\x89\x29", "\x28\xe5\x9b\x9b\x29", "\x28\xe4\xba\x94\x29", "\x28\xe5\x85\xad\x29", "\x28\xe4\xb8\x83\x29", "\x28\xe5\x85\xab\x29",
+ "\x28\xe4\xb9\x9d\x29", "\x28\xe5\x8d\x81\x29", "\x28\xe6\x9c\x88\x29", "\x28\xe7\x81\xab\x29", "\x28\xe6\xb0\xb4\x29", "\x28\xe6\x9c\xa8\x29", "\x28\xe9\x87\x91\x29", "\x28\xe5\x9c\x9f\x29",
+ "\x28\xe6\x97\xa5\x29", "\x28\xe6\xa0\xaa\x29", "\x28\xe6\x9c\x89\x29", "\x28\xe7\xa4\xbe\x29", "\x28\xe5\x90\x8d\x29", "\x28\xe7\x89\xb9\x29", "\x28\xe8\xb2\xa1\x29", "\x28\xe7\xa5\x9d\x29",
+ "\x28\xe5\x8a\xb4\x29", "\x28\xe4\xbb\xa3\x29", "\x28\xe5\x91\xbc\x29", "\x28\xe5\xad\xa6\x29", "\x28\xe7\x9b\xa3\x29", "\x28\xe4\xbc\x81\x29", "\x28\xe8\xb3\x87\x29", "\x28\xe5\x8d\x94\x29"
+};
+
+static const char *grn_nfkc50_decompose_table_e389[] = {
+ "\x28\xe7\xa5\xad\x29", "\x28\xe4\xbc\x91\x29", "\x28\xe8\x87\xaa\x29", "\x28\xe8\x87\xb3\x29", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\x70\x74\x65", "\x32\x31", "\x32\x32", "\x32\x33", "\x32\x34", "\x32\x35", "\x32\x36", "\x32\x37",
+ "\x32\x38", "\x32\x39", "\x33\x30", "\x33\x31", "\x33\x32", "\x33\x33", "\x33\x34", "\x33\x35",
+ "\xe1\x84\x80", "\xe1\x84\x82", "\xe1\x84\x83", "\xe1\x84\x85", "\xe1\x84\x86", "\xe1\x84\x87", "\xe1\x84\x89", "\xe1\x84\x8b",
+ "\xe1\x84\x8c", "\xe1\x84\x8e", "\xe1\x84\x8f", "\xe1\x84\x90", "\xe1\x84\x91", "\xe1\x84\x92", "\xea\xb0\x80", "\xeb\x82\x98",
+ "\xeb\x8b\xa4", "\xeb\x9d\xbc", "\xeb\xa7\x88", "\xeb\xb0\x94", "\xec\x82\xac", "\xec\x95\x84", "\xec\x9e\x90", "\xec\xb0\xa8",
+ "\xec\xb9\xb4", "\xed\x83\x80", "\xed\x8c\x8c", "\xed\x95\x98", "\xec\xb0\xb8\xea\xb3\xa0", "\xec\xa3\xbc\xec\x9d\x98", "\xec\x9a\xb0"
+};
+
+static const char *grn_nfkc50_decompose_table_e38a[] = {
+ "\xe4\xb8\x80", "\xe4\xba\x8c", "\xe4\xb8\x89", "\xe5\x9b\x9b", "\xe4\xba\x94", "\xe5\x85\xad", "\xe4\xb8\x83", "\xe5\x85\xab",
+ "\xe4\xb9\x9d", "\xe5\x8d\x81", "\xe6\x9c\x88", "\xe7\x81\xab", "\xe6\xb0\xb4", "\xe6\x9c\xa8", "\xe9\x87\x91", "\xe5\x9c\x9f",
+ "\xe6\x97\xa5", "\xe6\xa0\xaa", "\xe6\x9c\x89", "\xe7\xa4\xbe", "\xe5\x90\x8d", "\xe7\x89\xb9", "\xe8\xb2\xa1", "\xe7\xa5\x9d",
+ "\xe5\x8a\xb4", "\xe7\xa7\x98", "\xe7\x94\xb7", "\xe5\xa5\xb3", "\xe9\x81\xa9", "\xe5\x84\xaa", "\xe5\x8d\xb0", "\xe6\xb3\xa8",
+ "\xe9\xa0\x85", "\xe4\xbc\x91", "\xe5\x86\x99", "\xe6\xad\xa3", "\xe4\xb8\x8a", "\xe4\xb8\xad", "\xe4\xb8\x8b", "\xe5\xb7\xa6",
+ "\xe5\x8f\xb3", "\xe5\x8c\xbb", "\xe5\xae\x97", "\xe5\xad\xa6", "\xe7\x9b\xa3", "\xe4\xbc\x81", "\xe8\xb3\x87", "\xe5\x8d\x94",
+ "\xe5\xa4\x9c", "\x33\x36", "\x33\x37", "\x33\x38", "\x33\x39", "\x34\x30", "\x34\x31", "\x34\x32",
+ "\x34\x33", "\x34\x34", "\x34\x35", "\x34\x36", "\x34\x37", "\x34\x38", "\x34\x39", "\x35\x30"
+};
+
+static const char *grn_nfkc50_decompose_table_e38b[] = {
+ "\x31\xe6\x9c\x88", "\x32\xe6\x9c\x88", "\x33\xe6\x9c\x88", "\x34\xe6\x9c\x88", "\x35\xe6\x9c\x88", "\x36\xe6\x9c\x88", "\x37\xe6\x9c\x88", "\x38\xe6\x9c\x88",
+ "\x39\xe6\x9c\x88", "\x31\x30\xe6\x9c\x88", "\x31\x31\xe6\x9c\x88", "\x31\x32\xe6\x9c\x88", "\x68\x67", "\x65\x72\x67", "\x65\x76", "\x6c\x74\x64",
+ "\xe3\x82\xa2", "\xe3\x82\xa4", "\xe3\x82\xa6", "\xe3\x82\xa8", "\xe3\x82\xaa", "\xe3\x82\xab", "\xe3\x82\xad", "\xe3\x82\xaf",
+ "\xe3\x82\xb1", "\xe3\x82\xb3", "\xe3\x82\xb5", "\xe3\x82\xb7", "\xe3\x82\xb9", "\xe3\x82\xbb", "\xe3\x82\xbd", "\xe3\x82\xbf",
+ "\xe3\x83\x81", "\xe3\x83\x84", "\xe3\x83\x86", "\xe3\x83\x88", "\xe3\x83\x8a", "\xe3\x83\x8b", "\xe3\x83\x8c", "\xe3\x83\x8d",
+ "\xe3\x83\x8e", "\xe3\x83\x8f", "\xe3\x83\x92", "\xe3\x83\x95", "\xe3\x83\x98", "\xe3\x83\x9b", "\xe3\x83\x9e", "\xe3\x83\x9f",
+ "\xe3\x83\xa0", "\xe3\x83\xa1", "\xe3\x83\xa2", "\xe3\x83\xa4", "\xe3\x83\xa6", "\xe3\x83\xa8", "\xe3\x83\xa9", "\xe3\x83\xaa",
+ "\xe3\x83\xab", "\xe3\x83\xac", "\xe3\x83\xad", "\xe3\x83\xaf", "\xe3\x83\xb0", "\xe3\x83\xb1", "\xe3\x83\xb2"
+};
+
+static const char *grn_nfkc50_decompose_table_e38c[] = {
+ "\xe3\x82\xa2\xe3\x83\x91\xe3\x83\xbc\xe3\x83\x88", "\xe3\x82\xa2\xe3\x83\xab\xe3\x83\x95\xe3\x82\xa1", "\xe3\x82\xa2\xe3\x83\xb3\xe3\x83\x9a\xe3\x82\xa2", "\xe3\x82\xa2\xe3\x83\xbc\xe3\x83\xab", "\xe3\x82\xa4\xe3\x83\x8b\xe3\x83\xb3\xe3\x82\xb0", "\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x81", "\xe3\x82\xa6\xe3\x82\xa9\xe3\x83\xb3", "\xe3\x82\xa8\xe3\x82\xb9\xe3\x82\xaf\xe3\x83\xbc\xe3\x83\x89",
+ "\xe3\x82\xa8\xe3\x83\xbc\xe3\x82\xab\xe3\x83\xbc", "\xe3\x82\xaa\xe3\x83\xb3\xe3\x82\xb9", "\xe3\x82\xaa\xe3\x83\xbc\xe3\x83\xa0", "\xe3\x82\xab\xe3\x82\xa4\xe3\x83\xaa", "\xe3\x82\xab\xe3\x83\xa9\xe3\x83\x83\xe3\x83\x88", "\xe3\x82\xab\xe3\x83\xad\xe3\x83\xaa\xe3\x83\xbc", "\xe3\x82\xac\xe3\x83\xad\xe3\x83\xb3", "\xe3\x82\xac\xe3\x83\xb3\xe3\x83\x9e",
+ "\xe3\x82\xae\xe3\x82\xac", "\xe3\x82\xae\xe3\x83\x8b\xe3\x83\xbc", "\xe3\x82\xad\xe3\x83\xa5\xe3\x83\xaa\xe3\x83\xbc", "\xe3\x82\xae\xe3\x83\xab\xe3\x83\x80\xe3\x83\xbc", "\xe3\x82\xad\xe3\x83\xad", "\xe3\x82\xad\xe3\x83\xad\xe3\x82\xb0\xe3\x83\xa9\xe3\x83\xa0", "\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88\xe3\x83\xab", "\xe3\x82\xad\xe3\x83\xad\xe3\x83\xaf\xe3\x83\x83\xe3\x83\x88",
+ "\xe3\x82\xb0\xe3\x83\xa9\xe3\x83\xa0", "\xe3\x82\xb0\xe3\x83\xa9\xe3\x83\xa0\xe3\x83\x88\xe3\x83\xb3", "\xe3\x82\xaf\xe3\x83\xab\xe3\x82\xbc\xe3\x82\xa4\xe3\x83\xad", "\xe3\x82\xaf\xe3\x83\xad\xe3\x83\xbc\xe3\x83\x8d", "\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb9", "\xe3\x82\xb3\xe3\x83\xab\xe3\x83\x8a", "\xe3\x82\xb3\xe3\x83\xbc\xe3\x83\x9d", "\xe3\x82\xb5\xe3\x82\xa4\xe3\x82\xaf\xe3\x83\xab",
+ "\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x81\xe3\x83\xbc\xe3\x83\xa0", "\xe3\x82\xb7\xe3\x83\xaa\xe3\x83\xb3\xe3\x82\xb0", "\xe3\x82\xbb\xe3\x83\xb3\xe3\x83\x81", "\xe3\x82\xbb\xe3\x83\xb3\xe3\x83\x88", "\xe3\x83\x80\xe3\x83\xbc\xe3\x82\xb9", "\xe3\x83\x87\xe3\x82\xb7", "\xe3\x83\x89\xe3\x83\xab", "\xe3\x83\x88\xe3\x83\xb3",
+ "\xe3\x83\x8a\xe3\x83\x8e", "\xe3\x83\x8e\xe3\x83\x83\xe3\x83\x88", "\xe3\x83\x8f\xe3\x82\xa4\xe3\x83\x84", "\xe3\x83\x91\xe3\x83\xbc\xe3\x82\xbb\xe3\x83\xb3\xe3\x83\x88", "\xe3\x83\x91\xe3\x83\xbc\xe3\x83\x84", "\xe3\x83\x90\xe3\x83\xbc\xe3\x83\xac\xe3\x83\xab", "\xe3\x83\x94\xe3\x82\xa2\xe3\x82\xb9\xe3\x83\x88\xe3\x83\xab", "\xe3\x83\x94\xe3\x82\xaf\xe3\x83\xab",
+ "\xe3\x83\x94\xe3\x82\xb3", "\xe3\x83\x93\xe3\x83\xab", "\xe3\x83\x95\xe3\x82\xa1\xe3\x83\xa9\xe3\x83\x83\xe3\x83\x89", "\xe3\x83\x95\xe3\x82\xa3\xe3\x83\xbc\xe3\x83\x88", "\xe3\x83\x96\xe3\x83\x83\xe3\x82\xb7\xe3\x82\xa7\xe3\x83\xab", "\xe3\x83\x95\xe3\x83\xa9\xe3\x83\xb3", "\xe3\x83\x98\xe3\x82\xaf\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\xab", "\xe3\x83\x9a\xe3\x82\xbd",
+ "\xe3\x83\x9a\xe3\x83\x8b\xe3\x83\x92", "\xe3\x83\x98\xe3\x83\xab\xe3\x83\x84", "\xe3\x83\x9a\xe3\x83\xb3\xe3\x82\xb9", "\xe3\x83\x9a\xe3\x83\xbc\xe3\x82\xb8", "\xe3\x83\x99\xe3\x83\xbc\xe3\x82\xbf", "\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88", "\xe3\x83\x9c\xe3\x83\xab\xe3\x83\x88", "\xe3\x83\x9b\xe3\x83\xb3"
+};
+
+static const char *grn_nfkc50_decompose_table_e38d[] = {
+ "\xe3\x83\x9d\xe3\x83\xb3\xe3\x83\x89", "\xe3\x83\x9b\xe3\x83\xbc\xe3\x83\xab", "\xe3\x83\x9b\xe3\x83\xbc\xe3\x83\xb3", "\xe3\x83\x9e\xe3\x82\xa4\xe3\x82\xaf\xe3\x83\xad", "\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\xab", "\xe3\x83\x9e\xe3\x83\x83\xe3\x83\x8f", "\xe3\x83\x9e\xe3\x83\xab\xe3\x82\xaf", "\xe3\x83\x9e\xe3\x83\xb3\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3",
+ "\xe3\x83\x9f\xe3\x82\xaf\xe3\x83\xad\xe3\x83\xb3", "\xe3\x83\x9f\xe3\x83\xaa", "\xe3\x83\x9f\xe3\x83\xaa\xe3\x83\x90\xe3\x83\xbc\xe3\x83\xab", "\xe3\x83\xa1\xe3\x82\xac", "\xe3\x83\xa1\xe3\x82\xac\xe3\x83\x88\xe3\x83\xb3", "\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88\xe3\x83\xab", "\xe3\x83\xa4\xe3\x83\xbc\xe3\x83\x89", "\xe3\x83\xa4\xe3\x83\xbc\xe3\x83\xab",
+ "\xe3\x83\xa6\xe3\x82\xa2\xe3\x83\xb3", "\xe3\x83\xaa\xe3\x83\x83\xe3\x83\x88\xe3\x83\xab", "\xe3\x83\xaa\xe3\x83\xa9", "\xe3\x83\xab\xe3\x83\x94\xe3\x83\xbc", "\xe3\x83\xab\xe3\x83\xbc\xe3\x83\x96\xe3\x83\xab", "\xe3\x83\xac\xe3\x83\xa0", "\xe3\x83\xac\xe3\x83\xb3\xe3\x83\x88\xe3\x82\xb2\xe3\x83\xb3", "\xe3\x83\xaf\xe3\x83\x83\xe3\x83\x88",
+ "\x30\xe7\x82\xb9", "\x31\xe7\x82\xb9", "\x32\xe7\x82\xb9", "\x33\xe7\x82\xb9", "\x34\xe7\x82\xb9", "\x35\xe7\x82\xb9", "\x36\xe7\x82\xb9", "\x37\xe7\x82\xb9",
+ "\x38\xe7\x82\xb9", "\x39\xe7\x82\xb9", "\x31\x30\xe7\x82\xb9", "\x31\x31\xe7\x82\xb9", "\x31\x32\xe7\x82\xb9", "\x31\x33\xe7\x82\xb9", "\x31\x34\xe7\x82\xb9", "\x31\x35\xe7\x82\xb9",
+ "\x31\x36\xe7\x82\xb9", "\x31\x37\xe7\x82\xb9", "\x31\x38\xe7\x82\xb9", "\x31\x39\xe7\x82\xb9", "\x32\x30\xe7\x82\xb9", "\x32\x31\xe7\x82\xb9", "\x32\x32\xe7\x82\xb9", "\x32\x33\xe7\x82\xb9",
+ "\x32\x34\xe7\x82\xb9", "\x68\x70\x61", "\x64\x61", "\x61\x75", "\x62\x61\x72", "\x6f\x76", "\x70\x63", "\x64\x6d",
+ "\x64\x6d\x32", "\x64\x6d\x33", "\x69\x75", "\xe5\xb9\xb3\xe6\x88\x90", "\xe6\x98\xad\xe5\x92\x8c", "\xe5\xa4\xa7\xe6\xad\xa3", "\xe6\x98\x8e\xe6\xb2\xbb", "\xe6\xa0\xaa\xe5\xbc\x8f\xe4\xbc\x9a\xe7\xa4\xbe"
+};
+
+static const char *grn_nfkc50_decompose_table_e38e[] = {
+ "\x70\x61", "\x6e\x61", "\xce\xbc\x61", "\x6d\x61", "\x6b\x61", "\x6b\x62", "\x6d\x62", "\x67\x62",
+ "\x63\x61\x6c", "\x6b\x63\x61\x6c", "\x70\x66", "\x6e\x66", "\xce\xbc\x66", "\xce\xbc\x67", "\x6d\x67", "\x6b\x67",
+ "\x68\x7a", "\x6b\x68\x7a", "\x6d\x68\x7a", "\x67\x68\x7a", "\x74\x68\x7a", "\xce\xbc\x6c", "\x6d\x6c", "\x64\x6c",
+ "\x6b\x6c", "\x66\x6d", "\x6e\x6d", "\xce\xbc\x6d", "\x6d\x6d", "\x63\x6d", "\x6b\x6d", "\x6d\x6d\x32",
+ "\x63\x6d\x32", "\x6d\x32", "\x6b\x6d\x32", "\x6d\x6d\x33", "\x63\x6d\x33", "\x6d\x33", "\x6b\x6d\x33", "\x6d\xe2\x88\x95\x73",
+ "\x6d\xe2\x88\x95\x73\x32", "\x70\x61", "\x6b\x70\x61", "\x6d\x70\x61", "\x67\x70\x61", "\x72\x61\x64", "\x72\x61\x64\xe2\x88\x95\x73", "\x72\x61\x64\xe2\x88\x95\x73\x32",
+ "\x70\x73", "\x6e\x73", "\xce\xbc\x73", "\x6d\x73", "\x70\x76", "\x6e\x76", "\xce\xbc\x76", "\x6d\x76",
+ "\x6b\x76", "\x6d\x76", "\x70\x77", "\x6e\x77", "\xce\xbc\x77", "\x6d\x77", "\x6b\x77", "\x6d\x77"
+};
+
+static const char *grn_nfkc50_decompose_table_e38f[] = {
+ "\x6b\xce\xa9", "\x6d\xce\xa9", "\x61\x2e\x6d\x2e", "\x62\x71", "\x63\x63", "\x63\x64", "\x63\xe2\x88\x95\x6b\x67", "\x63\x6f\x2e",
+ "\x64\x62", "\x67\x79", "\x68\x61", "\x68\x70", "\x69\x6e", "\x6b\x6b", "\x6b\x6d", "\x6b\x74",
+ "\x6c\x6d", "\x6c\x6e", "\x6c\x6f\x67", "\x6c\x78", "\x6d\x62", "\x6d\x69\x6c", "\x6d\x6f\x6c", "\x70\x68",
+ "\x70\x2e\x6d\x2e", "\x70\x70\x6d", "\x70\x72", "\x73\x72", "\x73\x76", "\x77\x62", "\x76\xe2\x88\x95\x6d", "\x61\xe2\x88\x95\x6d",
+ "\x31\xe6\x97\xa5", "\x32\xe6\x97\xa5", "\x33\xe6\x97\xa5", "\x34\xe6\x97\xa5", "\x35\xe6\x97\xa5", "\x36\xe6\x97\xa5", "\x37\xe6\x97\xa5", "\x38\xe6\x97\xa5",
+ "\x39\xe6\x97\xa5", "\x31\x30\xe6\x97\xa5", "\x31\x31\xe6\x97\xa5", "\x31\x32\xe6\x97\xa5", "\x31\x33\xe6\x97\xa5", "\x31\x34\xe6\x97\xa5", "\x31\x35\xe6\x97\xa5", "\x31\x36\xe6\x97\xa5",
+ "\x31\x37\xe6\x97\xa5", "\x31\x38\xe6\x97\xa5", "\x31\x39\xe6\x97\xa5", "\x32\x30\xe6\x97\xa5", "\x32\x31\xe6\x97\xa5", "\x32\x32\xe6\x97\xa5", "\x32\x33\xe6\x97\xa5", "\x32\x34\xe6\x97\xa5",
+ "\x32\x35\xe6\x97\xa5", "\x32\x36\xe6\x97\xa5", "\x32\x37\xe6\x97\xa5", "\x32\x38\xe6\x97\xa5", "\x32\x39\xe6\x97\xa5", "\x33\x30\xe6\x97\xa5", "\x33\x31\xe6\x97\xa5", "\x67\x61\x6c"
+};
+
+static const char *grn_nfkc50_decompose_table_efa4[] = {
+ "\xe8\xb1\x88", "\xe6\x9b\xb4", "\xe8\xbb\x8a", "\xe8\xb3\x88", "\xe6\xbb\x91", "\xe4\xb8\xb2", "\xe5\x8f\xa5", "\xe9\xbe\x9c",
+ "\xe9\xbe\x9c", "\xe5\xa5\x91", "\xe9\x87\x91", "\xe5\x96\x87", "\xe5\xa5\x88", "\xe6\x87\xb6", "\xe7\x99\xa9", "\xe7\xbe\x85",
+ "\xe8\x98\xbf", "\xe8\x9e\xba", "\xe8\xa3\xb8", "\xe9\x82\x8f", "\xe6\xa8\x82", "\xe6\xb4\x9b", "\xe7\x83\x99", "\xe7\x8f\x9e",
+ "\xe8\x90\xbd", "\xe9\x85\xaa", "\xe9\xa7\xb1", "\xe4\xba\x82", "\xe5\x8d\xb5", "\xe6\xac\x84", "\xe7\x88\x9b", "\xe8\x98\xad",
+ "\xe9\xb8\x9e", "\xe5\xb5\x90", "\xe6\xbf\xab", "\xe8\x97\x8d", "\xe8\xa5\xa4", "\xe6\x8b\x89", "\xe8\x87\x98", "\xe8\xa0\x9f",
+ "\xe5\xbb\x8a", "\xe6\x9c\x97", "\xe6\xb5\xaa", "\xe7\x8b\xbc", "\xe9\x83\x8e", "\xe4\xbe\x86", "\xe5\x86\xb7", "\xe5\x8b\x9e",
+ "\xe6\x93\x84", "\xe6\xab\x93", "\xe7\x88\x90", "\xe7\x9b\xa7", "\xe8\x80\x81", "\xe8\x98\x86", "\xe8\x99\x9c", "\xe8\xb7\xaf",
+ "\xe9\x9c\xb2", "\xe9\xad\xaf", "\xe9\xb7\xba", "\xe7\xa2\x8c", "\xe7\xa5\xbf", "\xe7\xb6\xa0", "\xe8\x8f\x89", "\xe9\x8c\x84"
+};
+
+static const char *grn_nfkc50_decompose_table_efa5[] = {
+ "\xe9\xb9\xbf", "\xe8\xab\x96", "\xe5\xa3\x9f", "\xe5\xbc\x84", "\xe7\xb1\xa0", "\xe8\x81\xbe", "\xe7\x89\xa2", "\xe7\xa3\x8a",
+ "\xe8\xb3\x82", "\xe9\x9b\xb7", "\xe5\xa3\x98", "\xe5\xb1\xa2", "\xe6\xa8\x93", "\xe6\xb7\x9a", "\xe6\xbc\x8f", "\xe7\xb4\xaf",
+ "\xe7\xb8\xb7", "\xe9\x99\x8b", "\xe5\x8b\x92", "\xe8\x82\x8b", "\xe5\x87\x9c", "\xe5\x87\x8c", "\xe7\xa8\x9c", "\xe7\xb6\xbe",
+ "\xe8\x8f\xb1", "\xe9\x99\xb5", "\xe8\xae\x80", "\xe6\x8b\x8f", "\xe6\xa8\x82", "\xe8\xab\xbe", "\xe4\xb8\xb9", "\xe5\xaf\xa7",
+ "\xe6\x80\x92", "\xe7\x8e\x87", "\xe7\x95\xb0", "\xe5\x8c\x97", "\xe7\xa3\xbb", "\xe4\xbe\xbf", "\xe5\xbe\xa9", "\xe4\xb8\x8d",
+ "\xe6\xb3\x8c", "\xe6\x95\xb8", "\xe7\xb4\xa2", "\xe5\x8f\x83", "\xe5\xa1\x9e", "\xe7\x9c\x81", "\xe8\x91\x89", "\xe8\xaa\xaa",
+ "\xe6\xae\xba", "\xe8\xbe\xb0", "\xe6\xb2\x88", "\xe6\x8b\xbe", "\xe8\x8b\xa5", "\xe6\x8e\xa0", "\xe7\x95\xa5", "\xe4\xba\xae",
+ "\xe5\x85\xa9", "\xe5\x87\x89", "\xe6\xa2\x81", "\xe7\xb3\xa7", "\xe8\x89\xaf", "\xe8\xab\x92", "\xe9\x87\x8f", "\xe5\x8b\xb5"
+};
+
+static const char *grn_nfkc50_decompose_table_efa6[] = {
+ "\xe5\x91\x82", "\xe5\xa5\xb3", "\xe5\xbb\xac", "\xe6\x97\x85", "\xe6\xbf\xbe", "\xe7\xa4\xaa", "\xe9\x96\xad", "\xe9\xa9\xaa",
+ "\xe9\xba\x97", "\xe9\xbb\x8e", "\xe5\x8a\x9b", "\xe6\x9b\x86", "\xe6\xad\xb7", "\xe8\xbd\xa2", "\xe5\xb9\xb4", "\xe6\x86\x90",
+ "\xe6\x88\x80", "\xe6\x92\x9a", "\xe6\xbc\xa3", "\xe7\x85\x89", "\xe7\x92\x89", "\xe7\xa7\x8a", "\xe7\xb7\xb4", "\xe8\x81\xaf",
+ "\xe8\xbc\xa6", "\xe8\x93\xae", "\xe9\x80\xa3", "\xe9\x8d\x8a", "\xe5\x88\x97", "\xe5\x8a\xa3", "\xe5\x92\xbd", "\xe7\x83\x88",
+ "\xe8\xa3\x82", "\xe8\xaa\xaa", "\xe5\xbb\x89", "\xe5\xbf\xb5", "\xe6\x8d\xbb", "\xe6\xae\xae", "\xe7\xb0\xbe", "\xe7\x8d\xb5",
+ "\xe4\xbb\xa4", "\xe5\x9b\xb9", "\xe5\xaf\xa7", "\xe5\xb6\xba", "\xe6\x80\x9c", "\xe7\x8e\xb2", "\xe7\x91\xa9", "\xe7\xbe\x9a",
+ "\xe8\x81\x86", "\xe9\x88\xb4", "\xe9\x9b\xb6", "\xe9\x9d\x88", "\xe9\xa0\x98", "\xe4\xbe\x8b", "\xe7\xa6\xae", "\xe9\x86\xb4",
+ "\xe9\x9a\xb8", "\xe6\x83\xa1", "\xe4\xba\x86", "\xe5\x83\x9a", "\xe5\xaf\xae", "\xe5\xb0\xbf", "\xe6\x96\x99", "\xe6\xa8\x82"
+};
+
+static const char *grn_nfkc50_decompose_table_efa7[] = {
+ "\xe7\x87\x8e", "\xe7\x99\x82", "\xe8\x93\xbc", "\xe9\x81\xbc", "\xe9\xbe\x8d", "\xe6\x9a\x88", "\xe9\x98\xae", "\xe5\x8a\x89",
+ "\xe6\x9d\xbb", "\xe6\x9f\xb3", "\xe6\xb5\x81", "\xe6\xba\x9c", "\xe7\x90\x89", "\xe7\x95\x99", "\xe7\xa1\xab", "\xe7\xb4\x90",
+ "\xe9\xa1\x9e", "\xe5\x85\xad", "\xe6\x88\xae", "\xe9\x99\xb8", "\xe5\x80\xab", "\xe5\xb4\x99", "\xe6\xb7\xaa", "\xe8\xbc\xaa",
+ "\xe5\xbe\x8b", "\xe6\x85\x84", "\xe6\xa0\x97", "\xe7\x8e\x87", "\xe9\x9a\x86", "\xe5\x88\xa9", "\xe5\x90\x8f", "\xe5\xb1\xa5",
+ "\xe6\x98\x93", "\xe6\x9d\x8e", "\xe6\xa2\xa8", "\xe6\xb3\xa5", "\xe7\x90\x86", "\xe7\x97\xa2", "\xe7\xbd\xb9", "\xe8\xa3\x8f",
+ "\xe8\xa3\xa1", "\xe9\x87\x8c", "\xe9\x9b\xa2", "\xe5\x8c\xbf", "\xe6\xba\xba", "\xe5\x90\x9d", "\xe7\x87\x90", "\xe7\x92\x98",
+ "\xe8\x97\xba", "\xe9\x9a\xa3", "\xe9\xb1\x97", "\xe9\xba\x9f", "\xe6\x9e\x97", "\xe6\xb7\x8b", "\xe8\x87\xa8", "\xe7\xab\x8b",
+ "\xe7\xac\xa0", "\xe7\xb2\x92", "\xe7\x8b\x80", "\xe7\x82\x99", "\xe8\xad\x98", "\xe4\xbb\x80", "\xe8\x8c\xb6", "\xe5\x88\xba"
+};
+
+static const char *grn_nfkc50_decompose_table_efa8[] = {
+ "\xe5\x88\x87", "\xe5\xba\xa6", "\xe6\x8b\x93", "\xe7\xb3\x96", "\xe5\xae\x85", "\xe6\xb4\x9e", "\xe6\x9a\xb4", "\xe8\xbc\xbb",
+ "\xe8\xa1\x8c", "\xe9\x99\x8d", "\xe8\xa6\x8b", "\xe5\xbb\x93", "\xe5\x85\x80", "\xe5\x97\x80", NULL, NULL,
+ "\xe5\xa1\x9a", NULL, "\xe6\x99\xb4", NULL, NULL, "\xe5\x87\x9e", "\xe7\x8c\xaa", "\xe7\x9b\x8a",
+ "\xe7\xa4\xbc", "\xe7\xa5\x9e", "\xe7\xa5\xa5", "\xe7\xa6\x8f", "\xe9\x9d\x96", "\xe7\xb2\xbe", "\xe7\xbe\xbd", NULL,
+ "\xe8\x98\x92", NULL, "\xe8\xab\xb8", NULL, NULL, "\xe9\x80\xb8", "\xe9\x83\xbd", NULL,
+ NULL, NULL, "\xe9\xa3\xaf", "\xe9\xa3\xbc", "\xe9\xa4\xa8", "\xe9\xb6\xb4", NULL, NULL,
+ "\xe4\xbe\xae", "\xe5\x83\xa7", "\xe5\x85\x8d", "\xe5\x8b\x89", "\xe5\x8b\xa4", "\xe5\x8d\x91", "\xe5\x96\x9d", "\xe5\x98\x86",
+ "\xe5\x99\xa8", "\xe5\xa1\x80", "\xe5\xa2\xa8", "\xe5\xb1\xa4", "\xe5\xb1\xae", "\xe6\x82\x94", "\xe6\x85\xa8", "\xe6\x86\x8e"
+};
+
+static const char *grn_nfkc50_decompose_table_efa9[] = {
+ "\xe6\x87\xb2", "\xe6\x95\x8f", "\xe6\x97\xa2", "\xe6\x9a\x91", "\xe6\xa2\x85", "\xe6\xb5\xb7", "\xe6\xb8\x9a", "\xe6\xbc\xa2",
+ "\xe7\x85\xae", "\xe7\x88\xab", "\xe7\x90\xa2", "\xe7\xa2\x91", "\xe7\xa4\xbe", "\xe7\xa5\x89", "\xe7\xa5\x88", "\xe7\xa5\x90",
+ "\xe7\xa5\x96", "\xe7\xa5\x9d", "\xe7\xa6\x8d", "\xe7\xa6\x8e", "\xe7\xa9\x80", "\xe7\xaa\x81", "\xe7\xaf\x80", "\xe7\xb7\xb4",
+ "\xe7\xb8\x89", "\xe7\xb9\x81", "\xe7\xbd\xb2", "\xe8\x80\x85", "\xe8\x87\xad", "\xe8\x89\xb9", "\xe8\x89\xb9", "\xe8\x91\x97",
+ "\xe8\xa4\x90", "\xe8\xa6\x96", "\xe8\xac\x81", "\xe8\xac\xb9", "\xe8\xb3\x93", "\xe8\xb4\x88", "\xe8\xbe\xb6", "\xe9\x80\xb8",
+ "\xe9\x9b\xa3", "\xe9\x9f\xbf", "\xe9\xa0\xbb", NULL, NULL, NULL, NULL, NULL,
+ "\xe4\xb8\xa6", "\xe5\x86\xb5", "\xe5\x85\xa8", "\xe4\xbe\x80", "\xe5\x85\x85", "\xe5\x86\x80", "\xe5\x8b\x87", "\xe5\x8b\xba",
+ "\xe5\x96\x9d", "\xe5\x95\x95", "\xe5\x96\x99", "\xe5\x97\xa2", "\xe5\xa1\x9a", "\xe5\xa2\xb3", "\xe5\xa5\x84", "\xe5\xa5\x94"
+};
+
+static const char *grn_nfkc50_decompose_table_efaa[] = {
+ "\xe5\xa9\xa2", "\xe5\xac\xa8", "\xe5\xbb\x92", "\xe5\xbb\x99", "\xe5\xbd\xa9", "\xe5\xbe\xad", "\xe6\x83\x98", "\xe6\x85\x8e",
+ "\xe6\x84\x88", "\xe6\x86\x8e", "\xe6\x85\xa0", "\xe6\x87\xb2", "\xe6\x88\xb4", "\xe6\x8f\x84", "\xe6\x90\x9c", "\xe6\x91\x92",
+ "\xe6\x95\x96", "\xe6\x99\xb4", "\xe6\x9c\x97", "\xe6\x9c\x9b", "\xe6\x9d\x96", "\xe6\xad\xb9", "\xe6\xae\xba", "\xe6\xb5\x81",
+ "\xe6\xbb\x9b", "\xe6\xbb\x8b", "\xe6\xbc\xa2", "\xe7\x80\x9e", "\xe7\x85\xae", "\xe7\x9e\xa7", "\xe7\x88\xb5", "\xe7\x8a\xaf",
+ "\xe7\x8c\xaa", "\xe7\x91\xb1", "\xe7\x94\x86", "\xe7\x94\xbb", "\xe7\x98\x9d", "\xe7\x98\x9f", "\xe7\x9b\x8a", "\xe7\x9b\x9b",
+ "\xe7\x9b\xb4", "\xe7\x9d\x8a", "\xe7\x9d\x80", "\xe7\xa3\x8c", "\xe7\xaa\xb1", "\xe7\xaf\x80", "\xe7\xb1\xbb", "\xe7\xb5\x9b",
+ "\xe7\xb7\xb4", "\xe7\xbc\xbe", "\xe8\x80\x85", "\xe8\x8d\x92", "\xe8\x8f\xaf", "\xe8\x9d\xb9", "\xe8\xa5\x81", "\xe8\xa6\x86",
+ "\xe8\xa6\x96", "\xe8\xaa\xbf", "\xe8\xab\xb8", "\xe8\xab\x8b", "\xe8\xac\x81", "\xe8\xab\xbe", "\xe8\xab\xad", "\xe8\xac\xb9"
+};
+
+static const char *grn_nfkc50_decompose_table_efab[] = {
+ "\xe8\xae\x8a", "\xe8\xb4\x88", "\xe8\xbc\xb8", "\xe9\x81\xb2", "\xe9\x86\x99", "\xe9\x89\xb6", "\xe9\x99\xbc", "\xe9\x9b\xa3",
+ "\xe9\x9d\x96", "\xe9\x9f\x9b", "\xe9\x9f\xbf", "\xe9\xa0\x8b", "\xe9\xa0\xbb", "\xe9\xac\x92", "\xe9\xbe\x9c", "\xf0\xa2\xa1\x8a",
+ "\xf0\xa2\xa1\x84", "\xf0\xa3\x8f\x95", "\xe3\xae\x9d", "\xe4\x80\x98", "\xe4\x80\xb9", "\xf0\xa5\x89\x89", "\xf0\xa5\xb3\x90", "\xf0\xa7\xbb\x93",
+ "\xe9\xbd\x83", "\xe9\xbe\x8e"
+};
+
+static const char *grn_nfkc50_decompose_table_efac[] = {
+ "\x66\x66", "\x66\x69", "\x66\x6c", "\x66\x66\x69", "\x66\x66\x6c", "\x73\x74", "\x73\x74", NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "\xd5\xb4\xd5\xb6", "\xd5\xb4\xd5\xa5", "\xd5\xb4\xd5\xab", "\xd5\xbe\xd5\xb6", "\xd5\xb4\xd5\xad",
+ NULL, NULL, NULL, NULL, NULL, "\xd7\x99\xd6\xb4", NULL, "\xd7\xb2\xd6\xb7",
+ "\xd7\xa2", "\xd7\x90", "\xd7\x93", "\xd7\x94", "\xd7\x9b", "\xd7\x9c", "\xd7\x9d", "\xd7\xa8",
+ "\xd7\xaa", "\x2b", "\xd7\xa9\xd7\x81", "\xd7\xa9\xd7\x82", "\xd7\xa9\xd6\xbc\xd7\x81", "\xd7\xa9\xd6\xbc\xd7\x82", "\xd7\x90\xd6\xb7", "\xd7\x90\xd6\xb8",
+ "\xd7\x90\xd6\xbc", "\xd7\x91\xd6\xbc", "\xd7\x92\xd6\xbc", "\xd7\x93\xd6\xbc", "\xd7\x94\xd6\xbc", "\xd7\x95\xd6\xbc", "\xd7\x96\xd6\xbc", NULL,
+ "\xd7\x98\xd6\xbc", "\xd7\x99\xd6\xbc", "\xd7\x9a\xd6\xbc", "\xd7\x9b\xd6\xbc", "\xd7\x9c\xd6\xbc", NULL, "\xd7\x9e\xd6\xbc"
+};
+
+static const char *grn_nfkc50_decompose_table_efad[] = {
+ "\xd7\xa0\xd6\xbc", "\xd7\xa1\xd6\xbc", NULL, "\xd7\xa3\xd6\xbc", "\xd7\xa4\xd6\xbc", NULL, "\xd7\xa6\xd6\xbc", "\xd7\xa7\xd6\xbc",
+ "\xd7\xa8\xd6\xbc", "\xd7\xa9\xd6\xbc", "\xd7\xaa\xd6\xbc", "\xd7\x95\xd6\xb9", "\xd7\x91\xd6\xbf", "\xd7\x9b\xd6\xbf", "\xd7\xa4\xd6\xbf", "\xd7\x90\xd7\x9c",
+ "\xd9\xb1", "\xd9\xb1", "\xd9\xbb", "\xd9\xbb", "\xd9\xbb", "\xd9\xbb", "\xd9\xbe", "\xd9\xbe",
+ "\xd9\xbe", "\xd9\xbe", "\xda\x80", "\xda\x80", "\xda\x80", "\xda\x80", "\xd9\xba", "\xd9\xba",
+ "\xd9\xba", "\xd9\xba", "\xd9\xbf", "\xd9\xbf", "\xd9\xbf", "\xd9\xbf", "\xd9\xb9", "\xd9\xb9",
+ "\xd9\xb9", "\xd9\xb9", "\xda\xa4", "\xda\xa4", "\xda\xa4", "\xda\xa4", "\xda\xa6", "\xda\xa6",
+ "\xda\xa6", "\xda\xa6", "\xda\x84", "\xda\x84", "\xda\x84", "\xda\x84", "\xda\x83", "\xda\x83",
+ "\xda\x83", "\xda\x83", "\xda\x86", "\xda\x86", "\xda\x86", "\xda\x86", "\xda\x87", "\xda\x87"
+};
+
+static const char *grn_nfkc50_decompose_table_efae[] = {
+ "\xda\x87", "\xda\x87", "\xda\x8d", "\xda\x8d", "\xda\x8c", "\xda\x8c", "\xda\x8e", "\xda\x8e",
+ "\xda\x88", "\xda\x88", "\xda\x98", "\xda\x98", "\xda\x91", "\xda\x91", "\xda\xa9", "\xda\xa9",
+ "\xda\xa9", "\xda\xa9", "\xda\xaf", "\xda\xaf", "\xda\xaf", "\xda\xaf", "\xda\xb3", "\xda\xb3",
+ "\xda\xb3", "\xda\xb3", "\xda\xb1", "\xda\xb1", "\xda\xb1", "\xda\xb1", "\xda\xba", "\xda\xba",
+ "\xda\xbb", "\xda\xbb", "\xda\xbb", "\xda\xbb", "\xdb\x80", "\xdb\x80", "\xdb\x81", "\xdb\x81",
+ "\xdb\x81", "\xdb\x81", "\xda\xbe", "\xda\xbe", "\xda\xbe", "\xda\xbe", "\xdb\x92", "\xdb\x92",
+ "\xdb\x93", "\xdb\x93"
+};
+
+static const char *grn_nfkc50_decompose_table_efaf[] = {
+ "\xda\xad", "\xda\xad", "\xda\xad", "\xda\xad", "\xdb\x87", "\xdb\x87", "\xdb\x86", "\xdb\x86",
+ "\xdb\x88", "\xdb\x88", "\xdb\x87\xd9\xb4", "\xdb\x8b", "\xdb\x8b", "\xdb\x85", "\xdb\x85", "\xdb\x89",
+ "\xdb\x89", "\xdb\x90", "\xdb\x90", "\xdb\x90", "\xdb\x90", "\xd9\x89", "\xd9\x89", "\xd8\xa6\xd8\xa7",
+ "\xd8\xa6\xd8\xa7", "\xd8\xa6\xdb\x95", "\xd8\xa6\xdb\x95", "\xd8\xa6\xd9\x88", "\xd8\xa6\xd9\x88", "\xd8\xa6\xdb\x87", "\xd8\xa6\xdb\x87", "\xd8\xa6\xdb\x86",
+ "\xd8\xa6\xdb\x86", "\xd8\xa6\xdb\x88", "\xd8\xa6\xdb\x88", "\xd8\xa6\xdb\x90", "\xd8\xa6\xdb\x90", "\xd8\xa6\xdb\x90", "\xd8\xa6\xd9\x89", "\xd8\xa6\xd9\x89",
+ "\xd8\xa6\xd9\x89", "\xdb\x8c", "\xdb\x8c", "\xdb\x8c", "\xdb\x8c"
+};
+
+static const char *grn_nfkc50_decompose_table_efb0[] = {
+ "\xd8\xa6\xd8\xac", "\xd8\xa6\xd8\xad", "\xd8\xa6\xd9\x85", "\xd8\xa6\xd9\x89", "\xd8\xa6\xd9\x8a", "\xd8\xa8\xd8\xac", "\xd8\xa8\xd8\xad", "\xd8\xa8\xd8\xae",
+ "\xd8\xa8\xd9\x85", "\xd8\xa8\xd9\x89", "\xd8\xa8\xd9\x8a", "\xd8\xaa\xd8\xac", "\xd8\xaa\xd8\xad", "\xd8\xaa\xd8\xae", "\xd8\xaa\xd9\x85", "\xd8\xaa\xd9\x89",
+ "\xd8\xaa\xd9\x8a", "\xd8\xab\xd8\xac", "\xd8\xab\xd9\x85", "\xd8\xab\xd9\x89", "\xd8\xab\xd9\x8a", "\xd8\xac\xd8\xad", "\xd8\xac\xd9\x85", "\xd8\xad\xd8\xac",
+ "\xd8\xad\xd9\x85", "\xd8\xae\xd8\xac", "\xd8\xae\xd8\xad", "\xd8\xae\xd9\x85", "\xd8\xb3\xd8\xac", "\xd8\xb3\xd8\xad", "\xd8\xb3\xd8\xae", "\xd8\xb3\xd9\x85",
+ "\xd8\xb5\xd8\xad", "\xd8\xb5\xd9\x85", "\xd8\xb6\xd8\xac", "\xd8\xb6\xd8\xad", "\xd8\xb6\xd8\xae", "\xd8\xb6\xd9\x85", "\xd8\xb7\xd8\xad", "\xd8\xb7\xd9\x85",
+ "\xd8\xb8\xd9\x85", "\xd8\xb9\xd8\xac", "\xd8\xb9\xd9\x85", "\xd8\xba\xd8\xac", "\xd8\xba\xd9\x85", "\xd9\x81\xd8\xac", "\xd9\x81\xd8\xad", "\xd9\x81\xd8\xae",
+ "\xd9\x81\xd9\x85", "\xd9\x81\xd9\x89", "\xd9\x81\xd9\x8a", "\xd9\x82\xd8\xad", "\xd9\x82\xd9\x85", "\xd9\x82\xd9\x89", "\xd9\x82\xd9\x8a", "\xd9\x83\xd8\xa7",
+ "\xd9\x83\xd8\xac", "\xd9\x83\xd8\xad", "\xd9\x83\xd8\xae", "\xd9\x83\xd9\x84", "\xd9\x83\xd9\x85", "\xd9\x83\xd9\x89", "\xd9\x83\xd9\x8a", "\xd9\x84\xd8\xac"
+};
+
+static const char *grn_nfkc50_decompose_table_efb1[] = {
+ "\xd9\x84\xd8\xad", "\xd9\x84\xd8\xae", "\xd9\x84\xd9\x85", "\xd9\x84\xd9\x89", "\xd9\x84\xd9\x8a", "\xd9\x85\xd8\xac", "\xd9\x85\xd8\xad", "\xd9\x85\xd8\xae",
+ "\xd9\x85\xd9\x85", "\xd9\x85\xd9\x89", "\xd9\x85\xd9\x8a", "\xd9\x86\xd8\xac", "\xd9\x86\xd8\xad", "\xd9\x86\xd8\xae", "\xd9\x86\xd9\x85", "\xd9\x86\xd9\x89",
+ "\xd9\x86\xd9\x8a", "\xd9\x87\xd8\xac", "\xd9\x87\xd9\x85", "\xd9\x87\xd9\x89", "\xd9\x87\xd9\x8a", "\xd9\x8a\xd8\xac", "\xd9\x8a\xd8\xad", "\xd9\x8a\xd8\xae",
+ "\xd9\x8a\xd9\x85", "\xd9\x8a\xd9\x89", "\xd9\x8a\xd9\x8a", "\xd8\xb0\xd9\xb0", "\xd8\xb1\xd9\xb0", "\xd9\x89\xd9\xb0", "\xd9\x8c\xd9\x91", "\xd9\x8d\xd9\x91",
+ "\xd9\x8e\xd9\x91", "\xd9\x8f\xd9\x91", "\xd9\x90\xd9\x91", "\xd9\x91\xd9\xb0", "\xd8\xa6\xd8\xb1", "\xd8\xa6\xd8\xb2", "\xd8\xa6\xd9\x85", "\xd8\xa6\xd9\x86",
+ "\xd8\xa6\xd9\x89", "\xd8\xa6\xd9\x8a", "\xd8\xa8\xd8\xb1", "\xd8\xa8\xd8\xb2", "\xd8\xa8\xd9\x85", "\xd8\xa8\xd9\x86", "\xd8\xa8\xd9\x89", "\xd8\xa8\xd9\x8a",
+ "\xd8\xaa\xd8\xb1", "\xd8\xaa\xd8\xb2", "\xd8\xaa\xd9\x85", "\xd8\xaa\xd9\x86", "\xd8\xaa\xd9\x89", "\xd8\xaa\xd9\x8a", "\xd8\xab\xd8\xb1", "\xd8\xab\xd8\xb2",
+ "\xd8\xab\xd9\x85", "\xd8\xab\xd9\x86", "\xd8\xab\xd9\x89", "\xd8\xab\xd9\x8a", "\xd9\x81\xd9\x89", "\xd9\x81\xd9\x8a", "\xd9\x82\xd9\x89", "\xd9\x82\xd9\x8a"
+};
+
+static const char *grn_nfkc50_decompose_table_efb2[] = {
+ "\xd9\x83\xd8\xa7", "\xd9\x83\xd9\x84", "\xd9\x83\xd9\x85", "\xd9\x83\xd9\x89", "\xd9\x83\xd9\x8a", "\xd9\x84\xd9\x85", "\xd9\x84\xd9\x89", "\xd9\x84\xd9\x8a",
+ "\xd9\x85\xd8\xa7", "\xd9\x85\xd9\x85", "\xd9\x86\xd8\xb1", "\xd9\x86\xd8\xb2", "\xd9\x86\xd9\x85", "\xd9\x86\xd9\x86", "\xd9\x86\xd9\x89", "\xd9\x86\xd9\x8a",
+ "\xd9\x89\xd9\xb0", "\xd9\x8a\xd8\xb1", "\xd9\x8a\xd8\xb2", "\xd9\x8a\xd9\x85", "\xd9\x8a\xd9\x86", "\xd9\x8a\xd9\x89", "\xd9\x8a\xd9\x8a", "\xd8\xa6\xd8\xac",
+ "\xd8\xa6\xd8\xad", "\xd8\xa6\xd8\xae", "\xd8\xa6\xd9\x85", "\xd8\xa6\xd9\x87", "\xd8\xa8\xd8\xac", "\xd8\xa8\xd8\xad", "\xd8\xa8\xd8\xae", "\xd8\xa8\xd9\x85",
+ "\xd8\xa8\xd9\x87", "\xd8\xaa\xd8\xac", "\xd8\xaa\xd8\xad", "\xd8\xaa\xd8\xae", "\xd8\xaa\xd9\x85", "\xd8\xaa\xd9\x87", "\xd8\xab\xd9\x85", "\xd8\xac\xd8\xad",
+ "\xd8\xac\xd9\x85", "\xd8\xad\xd8\xac", "\xd8\xad\xd9\x85", "\xd8\xae\xd8\xac", "\xd8\xae\xd9\x85", "\xd8\xb3\xd8\xac", "\xd8\xb3\xd8\xad", "\xd8\xb3\xd8\xae",
+ "\xd8\xb3\xd9\x85", "\xd8\xb5\xd8\xad", "\xd8\xb5\xd8\xae", "\xd8\xb5\xd9\x85", "\xd8\xb6\xd8\xac", "\xd8\xb6\xd8\xad", "\xd8\xb6\xd8\xae", "\xd8\xb6\xd9\x85",
+ "\xd8\xb7\xd8\xad", "\xd8\xb8\xd9\x85", "\xd8\xb9\xd8\xac", "\xd8\xb9\xd9\x85", "\xd8\xba\xd8\xac", "\xd8\xba\xd9\x85", "\xd9\x81\xd8\xac", "\xd9\x81\xd8\xad"
+};
+
+static const char *grn_nfkc50_decompose_table_efb3[] = {
+ "\xd9\x81\xd8\xae", "\xd9\x81\xd9\x85", "\xd9\x82\xd8\xad", "\xd9\x82\xd9\x85", "\xd9\x83\xd8\xac", "\xd9\x83\xd8\xad", "\xd9\x83\xd8\xae", "\xd9\x83\xd9\x84",
+ "\xd9\x83\xd9\x85", "\xd9\x84\xd8\xac", "\xd9\x84\xd8\xad", "\xd9\x84\xd8\xae", "\xd9\x84\xd9\x85", "\xd9\x84\xd9\x87", "\xd9\x85\xd8\xac", "\xd9\x85\xd8\xad",
+ "\xd9\x85\xd8\xae", "\xd9\x85\xd9\x85", "\xd9\x86\xd8\xac", "\xd9\x86\xd8\xad", "\xd9\x86\xd8\xae", "\xd9\x86\xd9\x85", "\xd9\x86\xd9\x87", "\xd9\x87\xd8\xac",
+ "\xd9\x87\xd9\x85", "\xd9\x87\xd9\xb0", "\xd9\x8a\xd8\xac", "\xd9\x8a\xd8\xad", "\xd9\x8a\xd8\xae", "\xd9\x8a\xd9\x85", "\xd9\x8a\xd9\x87", "\xd8\xa6\xd9\x85",
+ "\xd8\xa6\xd9\x87", "\xd8\xa8\xd9\x85", "\xd8\xa8\xd9\x87", "\xd8\xaa\xd9\x85", "\xd8\xaa\xd9\x87", "\xd8\xab\xd9\x85", "\xd8\xab\xd9\x87", "\xd8\xb3\xd9\x85",
+ "\xd8\xb3\xd9\x87", "\xd8\xb4\xd9\x85", "\xd8\xb4\xd9\x87", "\xd9\x83\xd9\x84", "\xd9\x83\xd9\x85", "\xd9\x84\xd9\x85", "\xd9\x86\xd9\x85", "\xd9\x86\xd9\x87",
+ "\xd9\x8a\xd9\x85", "\xd9\x8a\xd9\x87", "\xd9\x80\xd9\x8e\xd9\x91", "\xd9\x80\xd9\x8f\xd9\x91", "\xd9\x80\xd9\x90\xd9\x91", "\xd8\xb7\xd9\x89", "\xd8\xb7\xd9\x8a", "\xd8\xb9\xd9\x89",
+ "\xd8\xb9\xd9\x8a", "\xd8\xba\xd9\x89", "\xd8\xba\xd9\x8a", "\xd8\xb3\xd9\x89", "\xd8\xb3\xd9\x8a", "\xd8\xb4\xd9\x89", "\xd8\xb4\xd9\x8a", "\xd8\xad\xd9\x89"
+};
+
+static const char *grn_nfkc50_decompose_table_efb4[] = {
+ "\xd8\xad\xd9\x8a", "\xd8\xac\xd9\x89", "\xd8\xac\xd9\x8a", "\xd8\xae\xd9\x89", "\xd8\xae\xd9\x8a", "\xd8\xb5\xd9\x89", "\xd8\xb5\xd9\x8a", "\xd8\xb6\xd9\x89",
+ "\xd8\xb6\xd9\x8a", "\xd8\xb4\xd8\xac", "\xd8\xb4\xd8\xad", "\xd8\xb4\xd8\xae", "\xd8\xb4\xd9\x85", "\xd8\xb4\xd8\xb1", "\xd8\xb3\xd8\xb1", "\xd8\xb5\xd8\xb1",
+ "\xd8\xb6\xd8\xb1", "\xd8\xb7\xd9\x89", "\xd8\xb7\xd9\x8a", "\xd8\xb9\xd9\x89", "\xd8\xb9\xd9\x8a", "\xd8\xba\xd9\x89", "\xd8\xba\xd9\x8a", "\xd8\xb3\xd9\x89",
+ "\xd8\xb3\xd9\x8a", "\xd8\xb4\xd9\x89", "\xd8\xb4\xd9\x8a", "\xd8\xad\xd9\x89", "\xd8\xad\xd9\x8a", "\xd8\xac\xd9\x89", "\xd8\xac\xd9\x8a", "\xd8\xae\xd9\x89",
+ "\xd8\xae\xd9\x8a", "\xd8\xb5\xd9\x89", "\xd8\xb5\xd9\x8a", "\xd8\xb6\xd9\x89", "\xd8\xb6\xd9\x8a", "\xd8\xb4\xd8\xac", "\xd8\xb4\xd8\xad", "\xd8\xb4\xd8\xae",
+ "\xd8\xb4\xd9\x85", "\xd8\xb4\xd8\xb1", "\xd8\xb3\xd8\xb1", "\xd8\xb5\xd8\xb1", "\xd8\xb6\xd8\xb1", "\xd8\xb4\xd8\xac", "\xd8\xb4\xd8\xad", "\xd8\xb4\xd8\xae",
+ "\xd8\xb4\xd9\x85", "\xd8\xb3\xd9\x87", "\xd8\xb4\xd9\x87", "\xd8\xb7\xd9\x85", "\xd8\xb3\xd8\xac", "\xd8\xb3\xd8\xad", "\xd8\xb3\xd8\xae", "\xd8\xb4\xd8\xac",
+ "\xd8\xb4\xd8\xad", "\xd8\xb4\xd8\xae", "\xd8\xb7\xd9\x85", "\xd8\xb8\xd9\x85", "\xd8\xa7\xd9\x8b", "\xd8\xa7\xd9\x8b"
+};
+
+static const char *grn_nfkc50_decompose_table_efb5[] = {
+ "\xd8\xaa\xd8\xac\xd9\x85", "\xd8\xaa\xd8\xad\xd8\xac", "\xd8\xaa\xd8\xad\xd8\xac", "\xd8\xaa\xd8\xad\xd9\x85", "\xd8\xaa\xd8\xae\xd9\x85", "\xd8\xaa\xd9\x85\xd8\xac", "\xd8\xaa\xd9\x85\xd8\xad", "\xd8\xaa\xd9\x85\xd8\xae",
+ "\xd8\xac\xd9\x85\xd8\xad", "\xd8\xac\xd9\x85\xd8\xad", "\xd8\xad\xd9\x85\xd9\x8a", "\xd8\xad\xd9\x85\xd9\x89", "\xd8\xb3\xd8\xad\xd8\xac", "\xd8\xb3\xd8\xac\xd8\xad", "\xd8\xb3\xd8\xac\xd9\x89", "\xd8\xb3\xd9\x85\xd8\xad",
+ "\xd8\xb3\xd9\x85\xd8\xad", "\xd8\xb3\xd9\x85\xd8\xac", "\xd8\xb3\xd9\x85\xd9\x85", "\xd8\xb3\xd9\x85\xd9\x85", "\xd8\xb5\xd8\xad\xd8\xad", "\xd8\xb5\xd8\xad\xd8\xad", "\xd8\xb5\xd9\x85\xd9\x85", "\xd8\xb4\xd8\xad\xd9\x85",
+ "\xd8\xb4\xd8\xad\xd9\x85", "\xd8\xb4\xd8\xac\xd9\x8a", "\xd8\xb4\xd9\x85\xd8\xae", "\xd8\xb4\xd9\x85\xd8\xae", "\xd8\xb4\xd9\x85\xd9\x85", "\xd8\xb4\xd9\x85\xd9\x85", "\xd8\xb6\xd8\xad\xd9\x89", "\xd8\xb6\xd8\xae\xd9\x85",
+ "\xd8\xb6\xd8\xae\xd9\x85", "\xd8\xb7\xd9\x85\xd8\xad", "\xd8\xb7\xd9\x85\xd8\xad", "\xd8\xb7\xd9\x85\xd9\x85", "\xd8\xb7\xd9\x85\xd9\x8a", "\xd8\xb9\xd8\xac\xd9\x85", "\xd8\xb9\xd9\x85\xd9\x85", "\xd8\xb9\xd9\x85\xd9\x85",
+ "\xd8\xb9\xd9\x85\xd9\x89", "\xd8\xba\xd9\x85\xd9\x85", "\xd8\xba\xd9\x85\xd9\x8a", "\xd8\xba\xd9\x85\xd9\x89", "\xd9\x81\xd8\xae\xd9\x85", "\xd9\x81\xd8\xae\xd9\x85", "\xd9\x82\xd9\x85\xd8\xad", "\xd9\x82\xd9\x85\xd9\x85"
+};
+
+static const char *grn_nfkc50_decompose_table_efb6[] = {
+ "\xd9\x84\xd8\xad\xd9\x85", "\xd9\x84\xd8\xad\xd9\x8a", "\xd9\x84\xd8\xad\xd9\x89", "\xd9\x84\xd8\xac\xd8\xac", "\xd9\x84\xd8\xac\xd8\xac", "\xd9\x84\xd8\xae\xd9\x85", "\xd9\x84\xd8\xae\xd9\x85", "\xd9\x84\xd9\x85\xd8\xad",
+ "\xd9\x84\xd9\x85\xd8\xad", "\xd9\x85\xd8\xad\xd8\xac", "\xd9\x85\xd8\xad\xd9\x85", "\xd9\x85\xd8\xad\xd9\x8a", "\xd9\x85\xd8\xac\xd8\xad", "\xd9\x85\xd8\xac\xd9\x85", "\xd9\x85\xd8\xae\xd8\xac", "\xd9\x85\xd8\xae\xd9\x85",
+ NULL, NULL, "\xd9\x85\xd8\xac\xd8\xae", "\xd9\x87\xd9\x85\xd8\xac", "\xd9\x87\xd9\x85\xd9\x85", "\xd9\x86\xd8\xad\xd9\x85", "\xd9\x86\xd8\xad\xd9\x89", "\xd9\x86\xd8\xac\xd9\x85",
+ "\xd9\x86\xd8\xac\xd9\x85", "\xd9\x86\xd8\xac\xd9\x89", "\xd9\x86\xd9\x85\xd9\x8a", "\xd9\x86\xd9\x85\xd9\x89", "\xd9\x8a\xd9\x85\xd9\x85", "\xd9\x8a\xd9\x85\xd9\x85", "\xd8\xa8\xd8\xae\xd9\x8a", "\xd8\xaa\xd8\xac\xd9\x8a",
+ "\xd8\xaa\xd8\xac\xd9\x89", "\xd8\xaa\xd8\xae\xd9\x8a", "\xd8\xaa\xd8\xae\xd9\x89", "\xd8\xaa\xd9\x85\xd9\x8a", "\xd8\xaa\xd9\x85\xd9\x89", "\xd8\xac\xd9\x85\xd9\x8a", "\xd8\xac\xd8\xad\xd9\x89", "\xd8\xac\xd9\x85\xd9\x89",
+ "\xd8\xb3\xd8\xae\xd9\x89", "\xd8\xb5\xd8\xad\xd9\x8a", "\xd8\xb4\xd8\xad\xd9\x8a", "\xd8\xb6\xd8\xad\xd9\x8a", "\xd9\x84\xd8\xac\xd9\x8a", "\xd9\x84\xd9\x85\xd9\x8a", "\xd9\x8a\xd8\xad\xd9\x8a", "\xd9\x8a\xd8\xac\xd9\x8a",
+ "\xd9\x8a\xd9\x85\xd9\x8a", "\xd9\x85\xd9\x85\xd9\x8a", "\xd9\x82\xd9\x85\xd9\x8a", "\xd9\x86\xd8\xad\xd9\x8a", "\xd9\x82\xd9\x85\xd8\xad", "\xd9\x84\xd8\xad\xd9\x85", "\xd8\xb9\xd9\x85\xd9\x8a", "\xd9\x83\xd9\x85\xd9\x8a",
+ "\xd9\x86\xd8\xac\xd8\xad", "\xd9\x85\xd8\xae\xd9\x8a", "\xd9\x84\xd8\xac\xd9\x85", "\xd9\x83\xd9\x85\xd9\x85", "\xd9\x84\xd8\xac\xd9\x85", "\xd9\x86\xd8\xac\xd8\xad", "\xd8\xac\xd8\xad\xd9\x8a", "\xd8\xad\xd8\xac\xd9\x8a"
+};
+
+static const char *grn_nfkc50_decompose_table_efb7[] = {
+ "\xd9\x85\xd8\xac\xd9\x8a", "\xd9\x81\xd9\x85\xd9\x8a", "\xd8\xa8\xd8\xad\xd9\x8a", "\xd9\x83\xd9\x85\xd9\x85", "\xd8\xb9\xd8\xac\xd9\x85", "\xd8\xb5\xd9\x85\xd9\x85", "\xd8\xb3\xd8\xae\xd9\x8a", "\xd9\x86\xd8\xac\xd9\x8a",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xd8\xb5\xd9\x84\xdb\x92", "\xd9\x82\xd9\x84\xdb\x92", "\xd8\xa7\xd9\x84\xd9\x84\xd9\x87", "\xd8\xa7\xd9\x83\xd8\xa8\xd8\xb1", "\xd9\x85\xd8\xad\xd9\x85\xd8\xaf", "\xd8\xb5\xd9\x84\xd8\xb9\xd9\x85", "\xd8\xb1\xd8\xb3\xd9\x88\xd9\x84", "\xd8\xb9\xd9\x84\xd9\x8a\xd9\x87",
+ "\xd9\x88\xd8\xb3\xd9\x84\xd9\x85", "\xd8\xb5\xd9\x84\xd9\x89", "\xd8\xb5\xd9\x84\xd9\x89\x20\xd8\xa7\xd9\x84\xd9\x84\xd9\x87\x20\xd8\xb9\xd9\x84\xd9\x8a\xd9\x87\x20\xd9\x88\xd8\xb3\xd9\x84\xd9\x85", "\xd8\xac\xd9\x84\x20\xd8\xac\xd9\x84\xd8\xa7\xd9\x84\xd9\x87", "\xd8\xb1\xdb\x8c\xd8\xa7\xd9\x84"
+};
+
+static const char *grn_nfkc50_decompose_table_efb8[] = {
+ "\x2c", "\xe3\x80\x81", "\xe3\x80\x82", "\x3a", "\x3b", "\x21", "\x3f", "\xe3\x80\x96",
+ "\xe3\x80\x97", "\x2e\x2e\x2e", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\x2e\x2e", "\xe2\x80\x94", "\xe2\x80\x93", "\x5f", "\x5f", "\x28", "\x29", "\x7b",
+ "\x7d", "\xe3\x80\x94", "\xe3\x80\x95", "\xe3\x80\x90", "\xe3\x80\x91", "\xe3\x80\x8a", "\xe3\x80\x8b", "\xe3\x80\x88"
+};
+
+static const char *grn_nfkc50_decompose_table_efb9[] = {
+ "\xe3\x80\x89", "\xe3\x80\x8c", "\xe3\x80\x8d", "\xe3\x80\x8e", "\xe3\x80\x8f", NULL, NULL, "\x5b",
+ "\x5d", "\xcc\x85", "\xcc\x85", "\xcc\x85", "\xcc\x85", "\x5f", "\x5f", "\x5f",
+ "\x2c", "\xe3\x80\x81", "\x2e", NULL, "\x3b", "\x3a", "\x3f", "\x21",
+ "\xe2\x80\x94", "\x28", "\x29", "\x7b", "\x7d", "\xe3\x80\x94", "\xe3\x80\x95", "\x23",
+ "\x26", "\x2a", "\x2b", "\x2d", "\x3c", "\x3e", "\x3d", NULL,
+ "\x5c", "\x24", "\x25", "\x40", NULL, NULL, NULL, NULL,
+ "\xd9\x8b", "\xd9\x80\xd9\x8b", "\xd9\x8c", NULL, "\xd9\x8d", NULL, "\xd9\x8e", "\xd9\x80\xd9\x8e",
+ "\xd9\x8f", "\xd9\x80\xd9\x8f", "\xd9\x90", "\xd9\x80\xd9\x90", "\xd9\x91", "\xd9\x80\xd9\x91", "\xd9\x92", "\xd9\x80\xd9\x92"
+};
+
+static const char *grn_nfkc50_decompose_table_efba[] = {
+ "\xd8\xa1", "\xd8\xa2", "\xd8\xa2", "\xd8\xa3", "\xd8\xa3", "\xd8\xa4", "\xd8\xa4", "\xd8\xa5",
+ "\xd8\xa5", "\xd8\xa6", "\xd8\xa6", "\xd8\xa6", "\xd8\xa6", "\xd8\xa7", "\xd8\xa7", "\xd8\xa8",
+ "\xd8\xa8", "\xd8\xa8", "\xd8\xa8", "\xd8\xa9", "\xd8\xa9", "\xd8\xaa", "\xd8\xaa", "\xd8\xaa",
+ "\xd8\xaa", "\xd8\xab", "\xd8\xab", "\xd8\xab", "\xd8\xab", "\xd8\xac", "\xd8\xac", "\xd8\xac",
+ "\xd8\xac", "\xd8\xad", "\xd8\xad", "\xd8\xad", "\xd8\xad", "\xd8\xae", "\xd8\xae", "\xd8\xae",
+ "\xd8\xae", "\xd8\xaf", "\xd8\xaf", "\xd8\xb0", "\xd8\xb0", "\xd8\xb1", "\xd8\xb1", "\xd8\xb2",
+ "\xd8\xb2", "\xd8\xb3", "\xd8\xb3", "\xd8\xb3", "\xd8\xb3", "\xd8\xb4", "\xd8\xb4", "\xd8\xb4",
+ "\xd8\xb4", "\xd8\xb5", "\xd8\xb5", "\xd8\xb5", "\xd8\xb5", "\xd8\xb6", "\xd8\xb6", "\xd8\xb6"
+};
+
+static const char *grn_nfkc50_decompose_table_efbb[] = {
+ "\xd8\xb6", "\xd8\xb7", "\xd8\xb7", "\xd8\xb7", "\xd8\xb7", "\xd8\xb8", "\xd8\xb8", "\xd8\xb8",
+ "\xd8\xb8", "\xd8\xb9", "\xd8\xb9", "\xd8\xb9", "\xd8\xb9", "\xd8\xba", "\xd8\xba", "\xd8\xba",
+ "\xd8\xba", "\xd9\x81", "\xd9\x81", "\xd9\x81", "\xd9\x81", "\xd9\x82", "\xd9\x82", "\xd9\x82",
+ "\xd9\x82", "\xd9\x83", "\xd9\x83", "\xd9\x83", "\xd9\x83", "\xd9\x84", "\xd9\x84", "\xd9\x84",
+ "\xd9\x84", "\xd9\x85", "\xd9\x85", "\xd9\x85", "\xd9\x85", "\xd9\x86", "\xd9\x86", "\xd9\x86",
+ "\xd9\x86", "\xd9\x87", "\xd9\x87", "\xd9\x87", "\xd9\x87", "\xd9\x88", "\xd9\x88", "\xd9\x89",
+ "\xd9\x89", "\xd9\x8a", "\xd9\x8a", "\xd9\x8a", "\xd9\x8a", "\xd9\x84\xd8\xa2", "\xd9\x84\xd8\xa2", "\xd9\x84\xd8\xa3",
+ "\xd9\x84\xd8\xa3", "\xd9\x84\xd8\xa5", "\xd9\x84\xd8\xa5", "\xd9\x84\xd8\xa7", "\xd9\x84\xd8\xa7"
+};
+
+static const char *grn_nfkc50_decompose_table_efbc[] = {
+ "\x21", "\x22", "\x23", "\x24", "\x25", "\x26", "\x27", "\x28",
+ "\x29", "\x2a", "\x2b", "\x2c", "\x2d", "\x2e", "\x2f", "\x30",
+ "\x31", "\x32", "\x33", "\x34", "\x35", "\x36", "\x37", "\x38",
+ "\x39", "\x3a", "\x3b", "\x3c", "\x3d", "\x3e", "\x3f", "\x40",
+ "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67", "\x68",
+ "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70",
+ "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77", "\x78",
+ "\x79", "\x7a", "\x5b", "\x5c", "\x5d", "\x5e", "\x5f"
+};
+
+static const char *grn_nfkc50_decompose_table_efbd[] = {
+ "\x60", "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67",
+ "\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f",
+ "\x70", "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77",
+ "\x78", "\x79", "\x7a", "\x7b", "\x7c", "\x7d", "\x7e", "\xe2\xa6\x85",
+ "\xe2\xa6\x86", "\xe3\x80\x82", "\xe3\x80\x8c", "\xe3\x80\x8d", "\xe3\x80\x81", "\xe3\x83\xbb", "\xe3\x83\xb2", "\xe3\x82\xa1",
+ "\xe3\x82\xa3", "\xe3\x82\xa5", "\xe3\x82\xa7", "\xe3\x82\xa9", "\xe3\x83\xa3", "\xe3\x83\xa5", "\xe3\x83\xa7", "\xe3\x83\x83",
+ "\xe3\x83\xbc", "\xe3\x82\xa2", "\xe3\x82\xa4", "\xe3\x82\xa6", "\xe3\x82\xa8", "\xe3\x82\xaa", "\xe3\x82\xab", "\xe3\x82\xad",
+ "\xe3\x82\xaf", "\xe3\x82\xb1", "\xe3\x82\xb3", "\xe3\x82\xb5", "\xe3\x82\xb7", "\xe3\x82\xb9", "\xe3\x82\xbb", "\xe3\x82\xbd"
+};
+
+static const char *grn_nfkc50_decompose_table_efbe[] = {
+ "\xe3\x82\xbf", "\xe3\x83\x81", "\xe3\x83\x84", "\xe3\x83\x86", "\xe3\x83\x88", "\xe3\x83\x8a", "\xe3\x83\x8b", "\xe3\x83\x8c",
+ "\xe3\x83\x8d", "\xe3\x83\x8e", "\xe3\x83\x8f", "\xe3\x83\x92", "\xe3\x83\x95", "\xe3\x83\x98", "\xe3\x83\x9b", "\xe3\x83\x9e",
+ "\xe3\x83\x9f", "\xe3\x83\xa0", "\xe3\x83\xa1", "\xe3\x83\xa2", "\xe3\x83\xa4", "\xe3\x83\xa6", "\xe3\x83\xa8", "\xe3\x83\xa9",
+ "\xe3\x83\xaa", "\xe3\x83\xab", "\xe3\x83\xac", "\xe3\x83\xad", "\xe3\x83\xaf", "\xe3\x83\xb3", "\xe3\x82\x99", "\xe3\x82\x9a",
+ "\xe1\x85\xa0", "\xe1\x84\x80", "\xe1\x84\x81", "\xe1\x86\xaa", "\xe1\x84\x82", "\xe1\x86\xac", "\xe1\x86\xad", "\xe1\x84\x83",
+ "\xe1\x84\x84", "\xe1\x84\x85", "\xe1\x86\xb0", "\xe1\x86\xb1", "\xe1\x86\xb2", "\xe1\x86\xb3", "\xe1\x86\xb4", "\xe1\x86\xb5",
+ "\xe1\x84\x9a", "\xe1\x84\x86", "\xe1\x84\x87", "\xe1\x84\x88", "\xe1\x84\xa1", "\xe1\x84\x89", "\xe1\x84\x8a", "\xe1\x84\x8b",
+ "\xe1\x84\x8c", "\xe1\x84\x8d", "\xe1\x84\x8e", "\xe1\x84\x8f", "\xe1\x84\x90", "\xe1\x84\x91", "\xe1\x84\x92"
+};
+
+static const char *grn_nfkc50_decompose_table_efbf[] = {
+ "\xe1\x85\xa1", "\xe1\x85\xa2", "\xe1\x85\xa3", "\xe1\x85\xa4", "\xe1\x85\xa5", "\xe1\x85\xa6", NULL, NULL,
+ "\xe1\x85\xa7", "\xe1\x85\xa8", "\xe1\x85\xa9", "\xe1\x85\xaa", "\xe1\x85\xab", "\xe1\x85\xac", NULL, NULL,
+ "\xe1\x85\xad", "\xe1\x85\xae", "\xe1\x85\xaf", "\xe1\x85\xb0", "\xe1\x85\xb1", "\xe1\x85\xb2", NULL, NULL,
+ "\xe1\x85\xb3", "\xe1\x85\xb4", "\xe1\x85\xb5", NULL, NULL, NULL, "\xc2\xa2", "\xc2\xa3",
+ "\xc2\xac", "\xcc\x84", "\xc2\xa6", "\xc2\xa5", "\xe2\x82\xa9", NULL, "\xe2\x94\x82", "\xe2\x86\x90",
+ "\xe2\x86\x91", "\xe2\x86\x92", "\xe2\x86\x93", "\xe2\x96\xa0", "\xe2\x97\x8b"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d85[] = {
+ "\xf0\x9d\x85\x97\xf0\x9d\x85\xa5", "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5", "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xae", "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xaf", "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xb0", "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xb1", "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xb2"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d86[] = {
+ "\xf0\x9d\x86\xb9\xf0\x9d\x85\xa5", "\xf0\x9d\x86\xba\xf0\x9d\x85\xa5", "\xf0\x9d\x86\xb9\xf0\x9d\x85\xa5\xf0\x9d\x85\xae", "\xf0\x9d\x86\xba\xf0\x9d\x85\xa5\xf0\x9d\x85\xae", "\xf0\x9d\x86\xb9\xf0\x9d\x85\xa5\xf0\x9d\x85\xaf"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d90[] = {
+ "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67", "\x68",
+ "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70",
+ "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77", "\x78",
+ "\x79", "\x7a", "\x61", "\x62", "\x63", "\x64", "\x65", "\x66",
+ "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e",
+ "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74", "\x75", "\x76",
+ "\x77", "\x78", "\x79", "\x7a", "\x61", "\x62", "\x63", "\x64",
+ "\x65", "\x66", "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d91[] = {
+ "\x6d", "\x6e", "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74",
+ "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a", "\x61", "\x62",
+ "\x63", "\x64", "\x65", "\x66", "\x67", NULL, "\x69", "\x6a",
+ "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70", "\x71", "\x72",
+ "\x73", "\x74", "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a",
+ "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67", "\x68",
+ "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70",
+ "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77", "\x78"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d92[] = {
+ "\x79", "\x7a", "\x61", "\x62", "\x63", "\x64", "\x65", "\x66",
+ "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e",
+ "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74", "\x75", "\x76",
+ "\x77", "\x78", "\x79", "\x7a", "\x61", NULL, "\x63", "\x64",
+ NULL, NULL, "\x67", NULL, NULL, "\x6a", "\x6b", NULL,
+ NULL, "\x6e", "\x6f", "\x70", "\x71", NULL, "\x73", "\x74",
+ "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a", "\x61", "\x62",
+ "\x63", "\x64", NULL, "\x66", NULL, "\x68", "\x69", "\x6a"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d93[] = {
+ "\x6b", "\x6c", "\x6d", "\x6e", NULL, "\x70", "\x71", "\x72",
+ "\x73", "\x74", "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a",
+ "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67", "\x68",
+ "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70",
+ "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77", "\x78",
+ "\x79", "\x7a", "\x61", "\x62", "\x63", "\x64", "\x65", "\x66",
+ "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e",
+ "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74", "\x75", "\x76"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d94[] = {
+ "\x77", "\x78", "\x79", "\x7a", "\x61", "\x62", NULL, "\x64",
+ "\x65", "\x66", "\x67", NULL, NULL, "\x6a", "\x6b", "\x6c",
+ "\x6d", "\x6e", "\x6f", "\x70", "\x71", NULL, "\x73", "\x74",
+ "\x75", "\x76", "\x77", "\x78", "\x79", NULL, "\x61", "\x62",
+ "\x63", "\x64", "\x65", "\x66", "\x67", "\x68", "\x69", "\x6a",
+ "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70", "\x71", "\x72",
+ "\x73", "\x74", "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a",
+ "\x61", "\x62", NULL, "\x64", "\x65", "\x66", "\x67"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d95[] = {
+ "\x69", "\x6a", "\x6b", "\x6c", "\x6d", NULL, "\x6f", NULL,
+ NULL, NULL, "\x73", "\x74", "\x75", "\x76", "\x77", "\x78",
+ "\x79", NULL, "\x61", "\x62", "\x63", "\x64", "\x65", "\x66",
+ "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e",
+ "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74", "\x75", "\x76",
+ "\x77", "\x78", "\x79", "\x7a", "\x61", "\x62", "\x63", "\x64",
+ "\x65", "\x66", "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c",
+ "\x6d", "\x6e", "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d96[] = {
+ "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a", "\x61", "\x62",
+ "\x63", "\x64", "\x65", "\x66", "\x67", "\x68", "\x69", "\x6a",
+ "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70", "\x71", "\x72",
+ "\x73", "\x74", "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a",
+ "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67", "\x68",
+ "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70",
+ "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77", "\x78",
+ "\x79", "\x7a", "\x61", "\x62", "\x63", "\x64", "\x65", "\x66"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d97[] = {
+ "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e",
+ "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74", "\x75", "\x76",
+ "\x77", "\x78", "\x79", "\x7a", "\x61", "\x62", "\x63", "\x64",
+ "\x65", "\x66", "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c",
+ "\x6d", "\x6e", "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74",
+ "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a", "\x61", "\x62",
+ "\x63", "\x64", "\x65", "\x66", "\x67", "\x68", "\x69", "\x6a",
+ "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70", "\x71", "\x72"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d98[] = {
+ "\x73", "\x74", "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a",
+ "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67", "\x68",
+ "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70",
+ "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77", "\x78",
+ "\x79", "\x7a", "\x61", "\x62", "\x63", "\x64", "\x65", "\x66",
+ "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e",
+ "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74", "\x75", "\x76",
+ "\x77", "\x78", "\x79", "\x7a", "\x61", "\x62", "\x63", "\x64"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d99[] = {
+ "\x65", "\x66", "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c",
+ "\x6d", "\x6e", "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74",
+ "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a", "\x61", "\x62",
+ "\x63", "\x64", "\x65", "\x66", "\x67", "\x68", "\x69", "\x6a",
+ "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70", "\x71", "\x72",
+ "\x73", "\x74", "\x75", "\x76", "\x77", "\x78", "\x79", "\x7a",
+ "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67", "\x68",
+ "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", "\x70"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d9a[] = {
+ "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77", "\x78",
+ "\x79", "\x7a", "\x61", "\x62", "\x63", "\x64", "\x65", "\x66",
+ "\x67", "\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e",
+ "\x6f", "\x70", "\x71", "\x72", "\x73", "\x74", "\x75", "\x76",
+ "\x77", "\x78", "\x79", "\x7a", "\xc4\xb1", "\xc8\xb7", NULL, NULL,
+ "\xce\x91", "\xce\x92", "\xce\x93", "\xce\x94", "\xce\x95", "\xce\x96", "\xce\x97", "\xce\x98",
+ "\xce\x99", "\xce\x9a", "\xce\x9b", "\xce\x9c", "\xce\x9d", "\xce\x9e", "\xce\x9f", "\xce\xa0",
+ "\xce\xa1", "\xce\x98", "\xce\xa3", "\xce\xa4", "\xce\xa5", "\xce\xa6", "\xce\xa7", "\xce\xa8"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d9b[] = {
+ "\xce\xa9", "\xe2\x88\x87", "\xce\xb1", "\xce\xb2", "\xce\xb3", "\xce\xb4", "\xce\xb5", "\xce\xb6",
+ "\xce\xb7", "\xce\xb8", "\xce\xb9", "\xce\xba", "\xce\xbb", "\xce\xbc", "\xce\xbd", "\xce\xbe",
+ "\xce\xbf", "\xcf\x80", "\xcf\x81", "\xcf\x82", "\xcf\x83", "\xcf\x84", "\xcf\x85", "\xcf\x86",
+ "\xcf\x87", "\xcf\x88", "\xcf\x89", "\xe2\x88\x82", "\xce\xb5", "\xce\xb8", "\xce\xba", "\xcf\x86",
+ "\xcf\x81", "\xcf\x80", "\xce\x91", "\xce\x92", "\xce\x93", "\xce\x94", "\xce\x95", "\xce\x96",
+ "\xce\x97", "\xce\x98", "\xce\x99", "\xce\x9a", "\xce\x9b", "\xce\x9c", "\xce\x9d", "\xce\x9e",
+ "\xce\x9f", "\xce\xa0", "\xce\xa1", "\xce\x98", "\xce\xa3", "\xce\xa4", "\xce\xa5", "\xce\xa6",
+ "\xce\xa7", "\xce\xa8", "\xce\xa9", "\xe2\x88\x87", "\xce\xb1", "\xce\xb2", "\xce\xb3", "\xce\xb4"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d9c[] = {
+ "\xce\xb5", "\xce\xb6", "\xce\xb7", "\xce\xb8", "\xce\xb9", "\xce\xba", "\xce\xbb", "\xce\xbc",
+ "\xce\xbd", "\xce\xbe", "\xce\xbf", "\xcf\x80", "\xcf\x81", "\xcf\x82", "\xcf\x83", "\xcf\x84",
+ "\xcf\x85", "\xcf\x86", "\xcf\x87", "\xcf\x88", "\xcf\x89", "\xe2\x88\x82", "\xce\xb5", "\xce\xb8",
+ "\xce\xba", "\xcf\x86", "\xcf\x81", "\xcf\x80", "\xce\x91", "\xce\x92", "\xce\x93", "\xce\x94",
+ "\xce\x95", "\xce\x96", "\xce\x97", "\xce\x98", "\xce\x99", "\xce\x9a", "\xce\x9b", "\xce\x9c",
+ "\xce\x9d", "\xce\x9e", "\xce\x9f", "\xce\xa0", "\xce\xa1", "\xce\x98", "\xce\xa3", "\xce\xa4",
+ "\xce\xa5", "\xce\xa6", "\xce\xa7", "\xce\xa8", "\xce\xa9", "\xe2\x88\x87", "\xce\xb1", "\xce\xb2",
+ "\xce\xb3", "\xce\xb4", "\xce\xb5", "\xce\xb6", "\xce\xb7", "\xce\xb8", "\xce\xb9", "\xce\xba"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d9d[] = {
+ "\xce\xbb", "\xce\xbc", "\xce\xbd", "\xce\xbe", "\xce\xbf", "\xcf\x80", "\xcf\x81", "\xcf\x82",
+ "\xcf\x83", "\xcf\x84", "\xcf\x85", "\xcf\x86", "\xcf\x87", "\xcf\x88", "\xcf\x89", "\xe2\x88\x82",
+ "\xce\xb5", "\xce\xb8", "\xce\xba", "\xcf\x86", "\xcf\x81", "\xcf\x80", "\xce\x91", "\xce\x92",
+ "\xce\x93", "\xce\x94", "\xce\x95", "\xce\x96", "\xce\x97", "\xce\x98", "\xce\x99", "\xce\x9a",
+ "\xce\x9b", "\xce\x9c", "\xce\x9d", "\xce\x9e", "\xce\x9f", "\xce\xa0", "\xce\xa1", "\xce\x98",
+ "\xce\xa3", "\xce\xa4", "\xce\xa5", "\xce\xa6", "\xce\xa7", "\xce\xa8", "\xce\xa9", "\xe2\x88\x87",
+ "\xce\xb1", "\xce\xb2", "\xce\xb3", "\xce\xb4", "\xce\xb5", "\xce\xb6", "\xce\xb7", "\xce\xb8",
+ "\xce\xb9", "\xce\xba", "\xce\xbb", "\xce\xbc", "\xce\xbd", "\xce\xbe", "\xce\xbf", "\xcf\x80"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d9e[] = {
+ "\xcf\x81", "\xcf\x82", "\xcf\x83", "\xcf\x84", "\xcf\x85", "\xcf\x86", "\xcf\x87", "\xcf\x88",
+ "\xcf\x89", "\xe2\x88\x82", "\xce\xb5", "\xce\xb8", "\xce\xba", "\xcf\x86", "\xcf\x81", "\xcf\x80",
+ "\xce\x91", "\xce\x92", "\xce\x93", "\xce\x94", "\xce\x95", "\xce\x96", "\xce\x97", "\xce\x98",
+ "\xce\x99", "\xce\x9a", "\xce\x9b", "\xce\x9c", "\xce\x9d", "\xce\x9e", "\xce\x9f", "\xce\xa0",
+ "\xce\xa1", "\xce\x98", "\xce\xa3", "\xce\xa4", "\xce\xa5", "\xce\xa6", "\xce\xa7", "\xce\xa8",
+ "\xce\xa9", "\xe2\x88\x87", "\xce\xb1", "\xce\xb2", "\xce\xb3", "\xce\xb4", "\xce\xb5", "\xce\xb6",
+ "\xce\xb7", "\xce\xb8", "\xce\xb9", "\xce\xba", "\xce\xbb", "\xce\xbc", "\xce\xbd", "\xce\xbe",
+ "\xce\xbf", "\xcf\x80", "\xcf\x81", "\xcf\x82", "\xcf\x83", "\xcf\x84", "\xcf\x85", "\xcf\x86"
+};
+
+static const char *grn_nfkc50_decompose_table_f09d9f[] = {
+ "\xcf\x87", "\xcf\x88", "\xcf\x89", "\xe2\x88\x82", "\xce\xb5", "\xce\xb8", "\xce\xba", "\xcf\x86",
+ "\xcf\x81", "\xcf\x80", "\xcf\x9c", "\xcf\x9d", NULL, NULL, "\x30", "\x31",
+ "\x32", "\x33", "\x34", "\x35", "\x36", "\x37", "\x38", "\x39",
+ "\x30", "\x31", "\x32", "\x33", "\x34", "\x35", "\x36", "\x37",
+ "\x38", "\x39", "\x30", "\x31", "\x32", "\x33", "\x34", "\x35",
+ "\x36", "\x37", "\x38", "\x39", "\x30", "\x31", "\x32", "\x33",
+ "\x34", "\x35", "\x36", "\x37", "\x38", "\x39", "\x30", "\x31",
+ "\x32", "\x33", "\x34", "\x35", "\x36", "\x37", "\x38", "\x39"
+};
+
+static const char *grn_nfkc50_decompose_table_f0afa0[] = {
+ "\xe4\xb8\xbd", "\xe4\xb8\xb8", "\xe4\xb9\x81", "\xf0\xa0\x84\xa2", "\xe4\xbd\xa0", "\xe4\xbe\xae", "\xe4\xbe\xbb", "\xe5\x80\x82",
+ "\xe5\x81\xba", "\xe5\x82\x99", "\xe5\x83\xa7", "\xe5\x83\x8f", "\xe3\x92\x9e", "\xf0\xa0\x98\xba", "\xe5\x85\x8d", "\xe5\x85\x94",
+ "\xe5\x85\xa4", "\xe5\x85\xb7", "\xf0\xa0\x94\x9c", "\xe3\x92\xb9", "\xe5\x85\xa7", "\xe5\x86\x8d", "\xf0\xa0\x95\x8b", "\xe5\x86\x97",
+ "\xe5\x86\xa4", "\xe4\xbb\x8c", "\xe5\x86\xac", "\xe5\x86\xb5", "\xf0\xa9\x87\x9f", "\xe5\x87\xb5", "\xe5\x88\x83", "\xe3\x93\x9f",
+ "\xe5\x88\xbb", "\xe5\x89\x86", "\xe5\x89\xb2", "\xe5\x89\xb7", "\xe3\x94\x95", "\xe5\x8b\x87", "\xe5\x8b\x89", "\xe5\x8b\xa4",
+ "\xe5\x8b\xba", "\xe5\x8c\x85", "\xe5\x8c\x86", "\xe5\x8c\x97", "\xe5\x8d\x89", "\xe5\x8d\x91", "\xe5\x8d\x9a", "\xe5\x8d\xb3",
+ "\xe5\x8d\xbd", "\xe5\x8d\xbf", "\xe5\x8d\xbf", "\xe5\x8d\xbf", "\xf0\xa0\xa8\xac", "\xe7\x81\xb0", "\xe5\x8f\x8a", "\xe5\x8f\x9f",
+ "\xf0\xa0\xad\xa3", "\xe5\x8f\xab", "\xe5\x8f\xb1", "\xe5\x90\x86", "\xe5\x92\x9e", "\xe5\x90\xb8", "\xe5\x91\x88", "\xe5\x91\xa8"
+};
+
+static const char *grn_nfkc50_decompose_table_f0afa1[] = {
+ "\xe5\x92\xa2", "\xe5\x93\xb6", "\xe5\x94\x90", "\xe5\x95\x93", "\xe5\x95\xa3", "\xe5\x96\x84", "\xe5\x96\x84", "\xe5\x96\x99",
+ "\xe5\x96\xab", "\xe5\x96\xb3", "\xe5\x97\x82", "\xe5\x9c\x96", "\xe5\x98\x86", "\xe5\x9c\x97", "\xe5\x99\x91", "\xe5\x99\xb4",
+ "\xe5\x88\x87", "\xe5\xa3\xae", "\xe5\x9f\x8e", "\xe5\x9f\xb4", "\xe5\xa0\x8d", "\xe5\x9e\x8b", "\xe5\xa0\xb2", "\xe5\xa0\xb1",
+ "\xe5\xa2\xac", "\xf0\xa1\x93\xa4", "\xe5\xa3\xb2", "\xe5\xa3\xb7", "\xe5\xa4\x86", "\xe5\xa4\x9a", "\xe5\xa4\xa2", "\xe5\xa5\xa2",
+ "\xf0\xa1\x9a\xa8", "\xf0\xa1\x9b\xaa", "\xe5\xa7\xac", "\xe5\xa8\x9b", "\xe5\xa8\xa7", "\xe5\xa7\x98", "\xe5\xa9\xa6", "\xe3\x9b\xae",
+ "\xe3\x9b\xbc", "\xe5\xac\x88", "\xe5\xac\xbe", "\xe5\xac\xbe", "\xf0\xa1\xa7\x88", "\xe5\xaf\x83", "\xe5\xaf\x98", "\xe5\xaf\xa7",
+ "\xe5\xaf\xb3", "\xf0\xa1\xac\x98", "\xe5\xaf\xbf", "\xe5\xb0\x86", "\xe5\xbd\x93", "\xe5\xb0\xa2", "\xe3\x9e\x81", "\xe5\xb1\xa0",
+ "\xe5\xb1\xae", "\xe5\xb3\x80", "\xe5\xb2\x8d", "\xf0\xa1\xb7\xa4", "\xe5\xb5\x83", "\xf0\xa1\xb7\xa6", "\xe5\xb5\xae", "\xe5\xb5\xab"
+};
+
+static const char *grn_nfkc50_decompose_table_f0afa2[] = {
+ "\xe5\xb5\xbc", "\xe5\xb7\xa1", "\xe5\xb7\xa2", "\xe3\xa0\xaf", "\xe5\xb7\xbd", "\xe5\xb8\xa8", "\xe5\xb8\xbd", "\xe5\xb9\xa9",
+ "\xe3\xa1\xa2", "\xf0\xa2\x86\x83", "\xe3\xa1\xbc", "\xe5\xba\xb0", "\xe5\xba\xb3", "\xe5\xba\xb6", "\xe5\xbb\x8a", "\xf0\xaa\x8e\x92",
+ "\xe5\xbb\xbe", "\xf0\xa2\x8c\xb1", "\xf0\xa2\x8c\xb1", "\xe8\x88\x81", "\xe5\xbc\xa2", "\xe5\xbc\xa2", "\xe3\xa3\x87", "\xf0\xa3\x8a\xb8",
+ "\xf0\xa6\x87\x9a", "\xe5\xbd\xa2", "\xe5\xbd\xab", "\xe3\xa3\xa3", "\xe5\xbe\x9a", "\xe5\xbf\x8d", "\xe5\xbf\x97", "\xe5\xbf\xb9",
+ "\xe6\x82\x81", "\xe3\xa4\xba", "\xe3\xa4\x9c", "\xe6\x82\x94", "\xf0\xa2\x9b\x94", "\xe6\x83\x87", "\xe6\x85\x88", "\xe6\x85\x8c",
+ "\xe6\x85\x8e", "\xe6\x85\x8c", "\xe6\x85\xba", "\xe6\x86\x8e", "\xe6\x86\xb2", "\xe6\x86\xa4", "\xe6\x86\xaf", "\xe6\x87\x9e",
+ "\xe6\x87\xb2", "\xe6\x87\xb6", "\xe6\x88\x90", "\xe6\x88\x9b", "\xe6\x89\x9d", "\xe6\x8a\xb1", "\xe6\x8b\x94", "\xe6\x8d\x90",
+ "\xf0\xa2\xac\x8c", "\xe6\x8c\xbd", "\xe6\x8b\xbc", "\xe6\x8d\xa8", "\xe6\x8e\x83", "\xe6\x8f\xa4", "\xf0\xa2\xaf\xb1", "\xe6\x90\xa2"
+};
+
+static const char *grn_nfkc50_decompose_table_f0afa3[] = {
+ "\xe6\x8f\x85", "\xe6\x8e\xa9", "\xe3\xa8\xae", "\xe6\x91\xa9", "\xe6\x91\xbe", "\xe6\x92\x9d", "\xe6\x91\xb7", "\xe3\xa9\xac",
+ "\xe6\x95\x8f", "\xe6\x95\xac", "\xf0\xa3\x80\x8a", "\xe6\x97\xa3", "\xe6\x9b\xb8", "\xe6\x99\x89", "\xe3\xac\x99", "\xe6\x9a\x91",
+ "\xe3\xac\x88", "\xe3\xab\xa4", "\xe5\x86\x92", "\xe5\x86\x95", "\xe6\x9c\x80", "\xe6\x9a\x9c", "\xe8\x82\xad", "\xe4\x8f\x99",
+ "\xe6\x9c\x97", "\xe6\x9c\x9b", "\xe6\x9c\xa1", "\xe6\x9d\x9e", "\xe6\x9d\x93", "\xf0\xa3\x8f\x83", "\xe3\xad\x89", "\xe6\x9f\xba",
+ "\xe6\x9e\x85", "\xe6\xa1\x92", "\xe6\xa2\x85", "\xf0\xa3\x91\xad", "\xe6\xa2\x8e", "\xe6\xa0\x9f", "\xe6\xa4\x94", "\xe3\xae\x9d",
+ "\xe6\xa5\x82", "\xe6\xa6\xa3", "\xe6\xa7\xaa", "\xe6\xaa\xa8", "\xf0\xa3\x9a\xa3", "\xe6\xab\x9b", "\xe3\xb0\x98", "\xe6\xac\xa1",
+ "\xf0\xa3\xa2\xa7", "\xe6\xad\x94", "\xe3\xb1\x8e", "\xe6\xad\xb2", "\xe6\xae\x9f", "\xe6\xae\xba", "\xe6\xae\xbb", "\xf0\xa3\xaa\x8d",
+ "\xf0\xa1\xb4\x8b", "\xf0\xa3\xab\xba", "\xe6\xb1\x8e", "\xf0\xa3\xb2\xbc", "\xe6\xb2\xbf", "\xe6\xb3\x8d", "\xe6\xb1\xa7", "\xe6\xb4\x96"
+};
+
+static const char *grn_nfkc50_decompose_table_f0afa4[] = {
+ "\xe6\xb4\xbe", "\xe6\xb5\xb7", "\xe6\xb5\x81", "\xe6\xb5\xa9", "\xe6\xb5\xb8", "\xe6\xb6\x85", "\xf0\xa3\xb4\x9e", "\xe6\xb4\xb4",
+ "\xe6\xb8\xaf", "\xe6\xb9\xae", "\xe3\xb4\xb3", "\xe6\xbb\x8b", "\xe6\xbb\x87", "\xf0\xa3\xbb\x91", "\xe6\xb7\xb9", "\xe6\xbd\xae",
+ "\xf0\xa3\xbd\x9e", "\xf0\xa3\xbe\x8e", "\xe6\xbf\x86", "\xe7\x80\xb9", "\xe7\x80\x9e", "\xe7\x80\x9b", "\xe3\xb6\x96", "\xe7\x81\x8a",
+ "\xe7\x81\xbd", "\xe7\x81\xb7", "\xe7\x82\xad", "\xf0\xa0\x94\xa5", "\xe7\x85\x85", "\xf0\xa4\x89\xa3", "\xe7\x86\x9c", "\xf0\xa4\x8e\xab",
+ "\xe7\x88\xa8", "\xe7\x88\xb5", "\xe7\x89\x90", "\xf0\xa4\x98\x88", "\xe7\x8a\x80", "\xe7\x8a\x95", "\xf0\xa4\x9c\xb5", "\xf0\xa4\xa0\x94",
+ "\xe7\x8d\xba", "\xe7\x8e\x8b", "\xe3\xba\xac", "\xe7\x8e\xa5", "\xe3\xba\xb8", "\xe3\xba\xb8", "\xe7\x91\x87", "\xe7\x91\x9c",
+ "\xe7\x91\xb1", "\xe7\x92\x85", "\xe7\x93\x8a", "\xe3\xbc\x9b", "\xe7\x94\xa4", "\xf0\xa4\xb0\xb6", "\xe7\x94\xbe", "\xf0\xa4\xb2\x92",
+ "\xe7\x95\xb0", "\xf0\xa2\x86\x9f", "\xe7\x98\x90", "\xf0\xa4\xbe\xa1", "\xf0\xa4\xbe\xb8", "\xf0\xa5\x81\x84", "\xe3\xbf\xbc", "\xe4\x80\x88"
+};
+
+static const char *grn_nfkc50_decompose_table_f0afa5[] = {
+ "\xe7\x9b\xb4", "\xf0\xa5\x83\xb3", "\xf0\xa5\x83\xb2", "\xf0\xa5\x84\x99", "\xf0\xa5\x84\xb3", "\xe7\x9c\x9e", "\xe7\x9c\x9f", "\xe7\x9c\x9f",
+ "\xe7\x9d\x8a", "\xe4\x80\xb9", "\xe7\x9e\x8b", "\xe4\x81\x86", "\xe4\x82\x96", "\xf0\xa5\x90\x9d", "\xe7\xa1\x8e", "\xe7\xa2\x8c",
+ "\xe7\xa3\x8c", "\xe4\x83\xa3", "\xf0\xa5\x98\xa6", "\xe7\xa5\x96", "\xf0\xa5\x9a\x9a", "\xf0\xa5\x9b\x85", "\xe7\xa6\x8f", "\xe7\xa7\xab",
+ "\xe4\x84\xaf", "\xe7\xa9\x80", "\xe7\xa9\x8a", "\xe7\xa9\x8f", "\xf0\xa5\xa5\xbc", "\xf0\xa5\xaa\xa7", "\xf0\xa5\xaa\xa7", "\xe7\xab\xae",
+ "\xe4\x88\x82", "\xf0\xa5\xae\xab", "\xe7\xaf\x86", "\xe7\xaf\x89", "\xe4\x88\xa7", "\xf0\xa5\xb2\x80", "\xe7\xb3\x92", "\xe4\x8a\xa0",
+ "\xe7\xb3\xa8", "\xe7\xb3\xa3", "\xe7\xb4\x80", "\xf0\xa5\xbe\x86", "\xe7\xb5\xa3", "\xe4\x8c\x81", "\xe7\xb7\x87", "\xe7\xb8\x82",
+ "\xe7\xb9\x85", "\xe4\x8c\xb4", "\xf0\xa6\x88\xa8", "\xf0\xa6\x89\x87", "\xe4\x8d\x99", "\xf0\xa6\x8b\x99", "\xe7\xbd\xba", "\xf0\xa6\x8c\xbe",
+ "\xe7\xbe\x95", "\xe7\xbf\xba", "\xe8\x80\x85", "\xf0\xa6\x93\x9a", "\xf0\xa6\x94\xa3", "\xe8\x81\xa0", "\xf0\xa6\x96\xa8", "\xe8\x81\xb0"
+};
+
+static const char *grn_nfkc50_decompose_table_f0afa6[] = {
+ "\xf0\xa3\x8d\x9f", "\xe4\x8f\x95", "\xe8\x82\xb2", "\xe8\x84\x83", "\xe4\x90\x8b", "\xe8\x84\xbe", "\xe5\xaa\xb5", "\xf0\xa6\x9e\xa7",
+ "\xf0\xa6\x9e\xb5", "\xf0\xa3\x8e\x93", "\xf0\xa3\x8e\x9c", "\xe8\x88\x81", "\xe8\x88\x84", "\xe8\xbe\x9e", "\xe4\x91\xab", "\xe8\x8a\x91",
+ "\xe8\x8a\x8b", "\xe8\x8a\x9d", "\xe5\x8a\xb3", "\xe8\x8a\xb1", "\xe8\x8a\xb3", "\xe8\x8a\xbd", "\xe8\x8b\xa6", "\xf0\xa6\xac\xbc",
+ "\xe8\x8b\xa5", "\xe8\x8c\x9d", "\xe8\x8d\xa3", "\xe8\x8e\xad", "\xe8\x8c\xa3", "\xe8\x8e\xbd", "\xe8\x8f\xa7", "\xe8\x91\x97",
+ "\xe8\x8d\x93", "\xe8\x8f\x8a", "\xe8\x8f\x8c", "\xe8\x8f\x9c", "\xf0\xa6\xb0\xb6", "\xf0\xa6\xb5\xab", "\xf0\xa6\xb3\x95", "\xe4\x94\xab",
+ "\xe8\x93\xb1", "\xe8\x93\xb3", "\xe8\x94\x96", "\xf0\xa7\x8f\x8a", "\xe8\x95\xa4", "\xf0\xa6\xbc\xac", "\xe4\x95\x9d", "\xe4\x95\xa1",
+ "\xf0\xa6\xbe\xb1", "\xf0\xa7\x83\x92", "\xe4\x95\xab", "\xe8\x99\x90", "\xe8\x99\x9c", "\xe8\x99\xa7", "\xe8\x99\xa9", "\xe8\x9a\xa9",
+ "\xe8\x9a\x88", "\xe8\x9c\x8e", "\xe8\x9b\xa2", "\xe8\x9d\xb9", "\xe8\x9c\xa8", "\xe8\x9d\xab", "\xe8\x9e\x86", "\xe4\x97\x97"
+};
+
+static const char *grn_nfkc50_decompose_table_f0afa7[] = {
+ "\xe8\x9f\xa1", "\xe8\xa0\x81", "\xe4\x97\xb9", "\xe8\xa1\xa0", "\xe8\xa1\xa3", "\xf0\xa7\x99\xa7", "\xe8\xa3\x97", "\xe8\xa3\x9e",
+ "\xe4\x98\xb5", "\xe8\xa3\xba", "\xe3\x92\xbb", "\xf0\xa7\xa2\xae", "\xf0\xa7\xa5\xa6", "\xe4\x9a\xbe", "\xe4\x9b\x87", "\xe8\xaa\xa0",
+ "\xe8\xab\xad", "\xe8\xae\x8a", "\xe8\xb1\x95", "\xf0\xa7\xb2\xa8", "\xe8\xb2\xab", "\xe8\xb3\x81", "\xe8\xb4\x9b", "\xe8\xb5\xb7",
+ "\xf0\xa7\xbc\xaf", "\xf0\xa0\xa0\x84", "\xe8\xb7\x8b", "\xe8\xb6\xbc", "\xe8\xb7\xb0", "\xf0\xa0\xa3\x9e", "\xe8\xbb\x94", "\xe8\xbc\xb8",
+ "\xf0\xa8\x97\x92", "\xf0\xa8\x97\xad", "\xe9\x82\x94", "\xe9\x83\xb1", "\xe9\x84\x91", "\xf0\xa8\x9c\xae", "\xe9\x84\x9b", "\xe9\x88\xb8",
+ "\xe9\x8b\x97", "\xe9\x8b\x98", "\xe9\x89\xbc", "\xe9\x8f\xb9", "\xe9\x90\x95", "\xf0\xa8\xaf\xba", "\xe9\x96\x8b", "\xe4\xa6\x95",
+ "\xe9\x96\xb7", "\xf0\xa8\xb5\xb7", "\xe4\xa7\xa6", "\xe9\x9b\x83", "\xe5\xb6\xb2", "\xe9\x9c\xa3", "\xf0\xa9\x85\x85", "\xf0\xa9\x88\x9a",
+ "\xe4\xa9\xae", "\xe4\xa9\xb6", "\xe9\x9f\xa0", "\xf0\xa9\x90\x8a", "\xe4\xaa\xb2", "\xf0\xa9\x92\x96", "\xe9\xa0\x8b", "\xe9\xa0\x8b"
+};
+
+static const char *grn_nfkc50_decompose_table_f0afa8[] = {
+ "\xe9\xa0\xa9", "\xf0\xa9\x96\xb6", "\xe9\xa3\xa2", "\xe4\xac\xb3", "\xe9\xa4\xa9", "\xe9\xa6\xa7", "\xe9\xa7\x82", "\xe9\xa7\xbe",
+ "\xe4\xaf\x8e", "\xf0\xa9\xac\xb0", "\xe9\xac\x92", "\xe9\xb1\x80", "\xe9\xb3\xbd", "\xe4\xb3\x8e", "\xe4\xb3\xad", "\xe9\xb5\xa7",
+ "\xf0\xaa\x83\x8e", "\xe4\xb3\xb8", "\xf0\xaa\x84\x85", "\xf0\xaa\x88\x8e", "\xf0\xaa\x8a\x91", "\xe9\xba\xbb", "\xe4\xb5\x96", "\xe9\xbb\xb9",
+ "\xe9\xbb\xbe", "\xe9\xbc\x85", "\xe9\xbc\x8f", "\xe9\xbc\x96", "\xe9\xbc\xbb", "\xf0\xaa\x98\x80"
+};
+
+const char *
+grn_nfkc50_decompose(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x41 &&
+ utf8[0] <= 0x5a) {
+ return grn_nfkc50_decompose_table_[utf8[0] - 0x41];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc2 :
+ if (utf8[1] >= 0xa0 &&
+ utf8[1] <= 0xbe) {
+ return grn_nfkc50_decompose_table_c2[utf8[1] - 0xa0];
+ }
+ break;
+ case 0xc3 :
+ if (utf8[1] >= 0x80 &&
+ utf8[1] <= 0x9d) {
+ return grn_nfkc50_decompose_table_c3[utf8[1] - 0x80];
+ }
+ break;
+ case 0xc4 :
+ return grn_nfkc50_decompose_table_c4[utf8[1] - 0x80];
+ case 0xc5 :
+ return grn_nfkc50_decompose_table_c5[utf8[1] - 0x80];
+ case 0xc6 :
+ if (utf8[1] >= 0xa0 &&
+ utf8[1] <= 0xaf) {
+ return grn_nfkc50_decompose_table_c6[utf8[1] - 0xa0];
+ }
+ break;
+ case 0xc7 :
+ if (utf8[1] >= 0x84 &&
+ utf8[1] <= 0xba) {
+ return grn_nfkc50_decompose_table_c7[utf8[1] - 0x84];
+ }
+ break;
+ case 0xc8 :
+ if (utf8[1] >= 0x80 &&
+ utf8[1] <= 0xb2) {
+ return grn_nfkc50_decompose_table_c8[utf8[1] - 0x80];
+ }
+ break;
+ case 0xca :
+ if (utf8[1] >= 0xb0 &&
+ utf8[1] <= 0xb8) {
+ return grn_nfkc50_decompose_table_ca[utf8[1] - 0xb0];
+ }
+ break;
+ case 0xcb :
+ if (utf8[1] >= 0x98 &&
+ utf8[1] <= 0xa4) {
+ return grn_nfkc50_decompose_table_cb[utf8[1] - 0x98];
+ }
+ break;
+ case 0xcd :
+ if (utf8[1] >= 0x80 &&
+ utf8[1] <= 0xbe) {
+ return grn_nfkc50_decompose_table_cd[utf8[1] - 0x80];
+ }
+ break;
+ case 0xce :
+ if (utf8[1] >= 0x84 &&
+ utf8[1] <= 0x87) {
+ return grn_nfkc50_decompose_table_ce[utf8[1] - 0x84];
+ }
+ break;
+ case 0xcf :
+ if (utf8[1] >= 0x90 &&
+ utf8[1] <= 0xb9) {
+ return grn_nfkc50_decompose_table_cf[utf8[1] - 0x90];
+ }
+ break;
+ case 0xd6 :
+ if (utf8[1] == 0x87) {
+ return "\xd5\xa5\xd6\x82";
+ }
+ break;
+ case 0xd9 :
+ if (utf8[1] >= 0xb5 &&
+ utf8[1] <= 0xb8) {
+ return grn_nfkc50_decompose_table_d9[utf8[1] - 0xb5];
+ }
+ break;
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0x9f) {
+ return grn_nfkc50_decompose_table_e0a5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x9c &&
+ utf8[2] <= 0x9f) {
+ return grn_nfkc50_decompose_table_e0a7[utf8[2] - 0x9c];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0xb3 &&
+ utf8[2] <= 0xb6) {
+ return grn_nfkc50_decompose_table_e0a8[utf8[2] - 0xb3];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x99 &&
+ utf8[2] <= 0x9e) {
+ return grn_nfkc50_decompose_table_e0a9[utf8[2] - 0x99];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x9c &&
+ utf8[2] <= 0x9d) {
+ return grn_nfkc50_decompose_table_e0ad[utf8[2] - 0x9c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] == 0xb3) {
+ return "\xe0\xb9\x8d\xe0\xb8\xb2";
+ }
+ break;
+ case 0xba :
+ if (utf8[2] == 0xb3) {
+ return "\xe0\xbb\x8d\xe0\xba\xb2";
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x9c &&
+ utf8[2] <= 0x9d) {
+ return grn_nfkc50_decompose_table_e0bb[utf8[2] - 0x9c];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] == 0x8c) {
+ return "\xe0\xbc\x8b";
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x83 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_decompose_table_e0bd[utf8[2] - 0x83];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x81 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_decompose_table_e0be[utf8[2] - 0x81];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x83 :
+ if (utf8[2] == 0xbc) {
+ return "\xe1\x83\x9c";
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0xac &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_decompose_table_e1b4[utf8[2] - 0xac];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_decompose_table_e1b5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x9b &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_decompose_table_e1b6[utf8[2] - 0x9b];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_decompose_table_e1b8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_decompose_table_e1b9[utf8[2] - 0x80];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_decompose_table_e1ba[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_decompose_table_e1bb[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0xb1 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_decompose_table_e1bd[utf8[2] - 0xb1];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0xbb &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_decompose_table_e1be[utf8[2] - 0xbb];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_decompose_table_e1bf[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xe2 :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_decompose_table_e280[utf8[2] - 0x80];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x87 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_decompose_table_e281[utf8[2] - 0x87];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_decompose_table_e282[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ return grn_nfkc50_decompose_table_e284[utf8[2] - 0x80];
+ case 0x85 :
+ return grn_nfkc50_decompose_table_e285[utf8[2] - 0x80];
+ case 0x88 :
+ if (utf8[2] >= 0xac &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_decompose_table_e288[utf8[2] - 0xac];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0xa9 &&
+ utf8[2] <= 0xaa) {
+ return grn_nfkc50_decompose_table_e28c[utf8[2] - 0xa9];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0xa0 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_decompose_table_e291[utf8[2] - 0xa0];
+ }
+ break;
+ case 0x92 :
+ return grn_nfkc50_decompose_table_e292[utf8[2] - 0x80];
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xaa) {
+ return grn_nfkc50_decompose_table_e293[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] == 0x8c) {
+ return "\xe2\x88\xab\xe2\x88\xab\xe2\x88\xab\xe2\x88\xab";
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0xb4 &&
+ utf8[2] <= 0xb6) {
+ return grn_nfkc50_decompose_table_e2a9[utf8[2] - 0xb4];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] == 0x9c) {
+ return "\xe2\xab\x9d\xcc\xb8";
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] == 0xaf) {
+ return "\xe2\xb5\xa1";
+ }
+ break;
+ case 0xba :
+ if (utf8[2] == 0x9f) {
+ return "\xe6\xaf\x8d";
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] == 0xb3) {
+ return "\xe9\xbe\x9f";
+ }
+ break;
+ case 0xbc :
+ return grn_nfkc50_decompose_table_e2bc[utf8[2] - 0x80];
+ case 0xbd :
+ return grn_nfkc50_decompose_table_e2bd[utf8[2] - 0x80];
+ case 0xbe :
+ return grn_nfkc50_decompose_table_e2be[utf8[2] - 0x80];
+ case 0xbf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x95) {
+ return grn_nfkc50_decompose_table_e2bf[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xe3 :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xba) {
+ return grn_nfkc50_decompose_table_e380[utf8[2] - 0x80];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x9b &&
+ utf8[2] <= 0x9f) {
+ return grn_nfkc50_decompose_table_e382[utf8[2] - 0x9b];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] == 0xbf) {
+ return "\xe3\x82\xb3\xe3\x83\x88";
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0xb1 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_decompose_table_e384[utf8[2] - 0xb1];
+ }
+ break;
+ case 0x85 :
+ return grn_nfkc50_decompose_table_e385[utf8[2] - 0x80];
+ case 0x86 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x9f) {
+ return grn_nfkc50_decompose_table_e386[utf8[2] - 0x80];
+ }
+ break;
+ case 0x88 :
+ return grn_nfkc50_decompose_table_e388[utf8[2] - 0x80];
+ case 0x89 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_decompose_table_e389[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8a :
+ return grn_nfkc50_decompose_table_e38a[utf8[2] - 0x80];
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_decompose_table_e38b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ return grn_nfkc50_decompose_table_e38c[utf8[2] - 0x80];
+ case 0x8d :
+ return grn_nfkc50_decompose_table_e38d[utf8[2] - 0x80];
+ case 0x8e :
+ return grn_nfkc50_decompose_table_e38e[utf8[2] - 0x80];
+ case 0x8f :
+ return grn_nfkc50_decompose_table_e38f[utf8[2] - 0x80];
+ default :
+ break;
+ }
+ break;
+ case 0xef :
+ switch (utf8[1]) {
+ case 0xa4 :
+ return grn_nfkc50_decompose_table_efa4[utf8[2] - 0x80];
+ case 0xa5 :
+ return grn_nfkc50_decompose_table_efa5[utf8[2] - 0x80];
+ case 0xa6 :
+ return grn_nfkc50_decompose_table_efa6[utf8[2] - 0x80];
+ case 0xa7 :
+ return grn_nfkc50_decompose_table_efa7[utf8[2] - 0x80];
+ case 0xa8 :
+ return grn_nfkc50_decompose_table_efa8[utf8[2] - 0x80];
+ case 0xa9 :
+ return grn_nfkc50_decompose_table_efa9[utf8[2] - 0x80];
+ case 0xaa :
+ return grn_nfkc50_decompose_table_efaa[utf8[2] - 0x80];
+ case 0xab :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x99) {
+ return grn_nfkc50_decompose_table_efab[utf8[2] - 0x80];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_decompose_table_efac[utf8[2] - 0x80];
+ }
+ break;
+ case 0xad :
+ return grn_nfkc50_decompose_table_efad[utf8[2] - 0x80];
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb1) {
+ return grn_nfkc50_decompose_table_efae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x93 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_decompose_table_efaf[utf8[2] - 0x93];
+ }
+ break;
+ case 0xb0 :
+ return grn_nfkc50_decompose_table_efb0[utf8[2] - 0x80];
+ case 0xb1 :
+ return grn_nfkc50_decompose_table_efb1[utf8[2] - 0x80];
+ case 0xb2 :
+ return grn_nfkc50_decompose_table_efb2[utf8[2] - 0x80];
+ case 0xb3 :
+ return grn_nfkc50_decompose_table_efb3[utf8[2] - 0x80];
+ case 0xb4 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_decompose_table_efb4[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_decompose_table_efb5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ return grn_nfkc50_decompose_table_efb6[utf8[2] - 0x80];
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_decompose_table_efb7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_decompose_table_efb8[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb9 :
+ return grn_nfkc50_decompose_table_efb9[utf8[2] - 0x80];
+ case 0xba :
+ return grn_nfkc50_decompose_table_efba[utf8[2] - 0x80];
+ case 0xbb :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_decompose_table_efbb[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x81 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_decompose_table_efbc[utf8[2] - 0x81];
+ }
+ break;
+ case 0xbd :
+ return grn_nfkc50_decompose_table_efbd[utf8[2] - 0x80];
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xbe) {
+ return grn_nfkc50_decompose_table_efbe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x82 &&
+ utf8[2] <= 0xae) {
+ return grn_nfkc50_decompose_table_efbf[utf8[2] - 0x82];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xf0 :
+ switch (utf8[1]) {
+ case 0x9d :
+ switch (utf8[2]) {
+ case 0x85 :
+ if (utf8[3] >= 0x9e &&
+ utf8[3] <= 0xa4) {
+ return grn_nfkc50_decompose_table_f09d85[utf8[3] - 0x9e];
+ }
+ break;
+ case 0x86 :
+ if (utf8[3] >= 0xbb &&
+ utf8[3] <= 0xbf) {
+ return grn_nfkc50_decompose_table_f09d86[utf8[3] - 0xbb];
+ }
+ break;
+ case 0x87 :
+ if (utf8[3] == 0x80) {
+ return "\xf0\x9d\x86\xba\xf0\x9d\x85\xa5\xf0\x9d\x85\xaf";
+ }
+ break;
+ case 0x90 :
+ return grn_nfkc50_decompose_table_f09d90[utf8[3] - 0x80];
+ case 0x91 :
+ return grn_nfkc50_decompose_table_f09d91[utf8[3] - 0x80];
+ case 0x92 :
+ return grn_nfkc50_decompose_table_f09d92[utf8[3] - 0x80];
+ case 0x93 :
+ return grn_nfkc50_decompose_table_f09d93[utf8[3] - 0x80];
+ case 0x94 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0xbe) {
+ return grn_nfkc50_decompose_table_f09d94[utf8[3] - 0x80];
+ }
+ break;
+ case 0x95 :
+ return grn_nfkc50_decompose_table_f09d95[utf8[3] - 0x80];
+ case 0x96 :
+ return grn_nfkc50_decompose_table_f09d96[utf8[3] - 0x80];
+ case 0x97 :
+ return grn_nfkc50_decompose_table_f09d97[utf8[3] - 0x80];
+ case 0x98 :
+ return grn_nfkc50_decompose_table_f09d98[utf8[3] - 0x80];
+ case 0x99 :
+ return grn_nfkc50_decompose_table_f09d99[utf8[3] - 0x80];
+ case 0x9a :
+ return grn_nfkc50_decompose_table_f09d9a[utf8[3] - 0x80];
+ case 0x9b :
+ return grn_nfkc50_decompose_table_f09d9b[utf8[3] - 0x80];
+ case 0x9c :
+ return grn_nfkc50_decompose_table_f09d9c[utf8[3] - 0x80];
+ case 0x9d :
+ return grn_nfkc50_decompose_table_f09d9d[utf8[3] - 0x80];
+ case 0x9e :
+ return grn_nfkc50_decompose_table_f09d9e[utf8[3] - 0x80];
+ case 0x9f :
+ return grn_nfkc50_decompose_table_f09d9f[utf8[3] - 0x80];
+ default :
+ break;
+ }
+ break;
+ case 0xaf :
+ switch (utf8[2]) {
+ case 0xa0 :
+ return grn_nfkc50_decompose_table_f0afa0[utf8[3] - 0x80];
+ case 0xa1 :
+ return grn_nfkc50_decompose_table_f0afa1[utf8[3] - 0x80];
+ case 0xa2 :
+ return grn_nfkc50_decompose_table_f0afa2[utf8[3] - 0x80];
+ case 0xa3 :
+ return grn_nfkc50_decompose_table_f0afa3[utf8[3] - 0x80];
+ case 0xa4 :
+ return grn_nfkc50_decompose_table_f0afa4[utf8[3] - 0x80];
+ case 0xa5 :
+ return grn_nfkc50_decompose_table_f0afa5[utf8[3] - 0x80];
+ case 0xa6 :
+ return grn_nfkc50_decompose_table_f0afa6[utf8[3] - 0x80];
+ case 0xa7 :
+ return grn_nfkc50_decompose_table_f0afa7[utf8[3] - 0x80];
+ case 0xa8 :
+ if (utf8[3] >= 0x80 &&
+ utf8[3] <= 0x9d) {
+ return grn_nfkc50_decompose_table_f0afa8[utf8[3] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc80_table_[] = {
+ "\xc3\xa0", NULL, NULL, NULL, "\xc3\xa8", NULL, NULL, NULL,
+ "\xc3\xac", NULL, NULL, NULL, NULL, "\xc7\xb9", "\xc3\xb2", NULL,
+ NULL, NULL, NULL, NULL, "\xc3\xb9", NULL, "\xe1\xba\x81", NULL,
+ "\xe1\xbb\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc80_table_c3[] = {
+ "\xe1\xba\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbb\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, "\xe1\xbb\x93", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, "\xc7\x9c"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc80_table_c4[] = {
+ "\xe1\xba\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xb8\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc80_table_c6[] = {
+ "\xe1\xbb\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xe1\xbb\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc80_table_ce[] = {
+ "\xe1\xbe\xba", NULL, NULL, NULL, "\xe1\xbf\x88", NULL, "\xe1\xbf\x8a", NULL,
+ "\xe1\xbf\x9a", NULL, NULL, NULL, NULL, NULL, "\xe1\xbf\xb8", NULL,
+ NULL, NULL, NULL, NULL, "\xe1\xbf\xaa", NULL, NULL, NULL,
+ "\xe1\xbf\xba", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\xb0", NULL, NULL, NULL, "\xe1\xbd\xb2", NULL, "\xe1\xbd\xb4", NULL,
+ "\xe1\xbd\xb6", NULL, NULL, NULL, NULL, NULL, "\xe1\xbd\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc80_table_cf[] = {
+ "\xe1\xbd\xba", NULL, NULL, NULL, "\xe1\xbd\xbc", "\xe1\xbf\x92", "\xe1\xbf\xa2"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc80_table_d0[] = {
+ "\xd0\x80", NULL, NULL, "\xd0\x8d", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xd1\x90", NULL, NULL, "\xd1\x9d"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc80_table_e1bc[] = {
+ "\xe1\xbc\x82", "\xe1\xbc\x83", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\x8a", "\xe1\xbc\x8b", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\x92", "\xe1\xbc\x93", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\x9a", "\xe1\xbc\x9b", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xa2", "\xe1\xbc\xa3", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xaa", "\xe1\xbc\xab", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xb2", "\xe1\xbc\xb3", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xba", "\xe1\xbc\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc80_table_e1bd[] = {
+ "\xe1\xbd\x82", "\xe1\xbd\x83", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\x8a", "\xe1\xbd\x8b", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\x92", "\xe1\xbd\x93", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, "\xe1\xbd\x9b", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\xa2", "\xe1\xbd\xa3", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\xaa", "\xe1\xbd\xab"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc80(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x79) {
+ return grn_nfkc50_compose_prefix_cc80_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc3 :
+ if (utf8[1] >= 0xa2 &&
+ utf8[1] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_cc80_table_c3[utf8[1] - 0xa2];
+ }
+ break;
+ case 0xc4 :
+ if (utf8[1] >= 0x83 &&
+ utf8[1] <= 0x93) {
+ return grn_nfkc50_compose_prefix_cc80_table_c4[utf8[1] - 0x83];
+ }
+ break;
+ case 0xc5 :
+ if (utf8[1] == 0x8d) {
+ return "\xe1\xb9\x91";
+ }
+ break;
+ case 0xc6 :
+ if (utf8[1] >= 0xa1 &&
+ utf8[1] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_cc80_table_c6[utf8[1] - 0xa1];
+ }
+ break;
+ case 0xce :
+ if (utf8[1] >= 0x91 &&
+ utf8[1] <= 0xbf) {
+ return grn_nfkc50_compose_prefix_cc80_table_ce[utf8[1] - 0x91];
+ }
+ break;
+ case 0xcf :
+ if (utf8[1] >= 0x85 &&
+ utf8[1] <= 0x8b) {
+ return grn_nfkc50_compose_prefix_cc80_table_cf[utf8[1] - 0x85];
+ }
+ break;
+ case 0xd0 :
+ if (utf8[1] >= 0x95 &&
+ utf8[1] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_cc80_table_d0[utf8[1] - 0x95];
+ }
+ break;
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_compose_prefix_cc80_table_e1bc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xa9) {
+ return grn_nfkc50_compose_prefix_cc80_table_e1bd[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc81_table_[] = {
+ "\xc3\xa1", NULL, "\xc4\x87", NULL, "\xc3\xa9", NULL, "\xc7\xb5", NULL,
+ "\xc3\xad", NULL, "\xe1\xb8\xb1", "\xc4\xba", "\xe1\xb8\xbf", "\xc5\x84", "\xc3\xb3", "\xe1\xb9\x95",
+ NULL, "\xc5\x95", "\xc5\x9b", NULL, "\xc3\xba", NULL, "\xe1\xba\x83", NULL,
+ "\xc3\xbd", "\xc5\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc81_table_c3[] = {
+ "\xc7\xbc", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, "\xc7\xbe", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xe1\xba\xa5", NULL, NULL, "\xc7\xbb",
+ "\xc7\xbd", "\xe1\xb8\x89", NULL, NULL, "\xe1\xba\xbf", NULL, NULL, NULL,
+ NULL, "\xe1\xb8\xaf", NULL, NULL, NULL, NULL, "\xe1\xbb\x91", "\xe1\xb9\x8d",
+ NULL, NULL, "\xc7\xbf", NULL, NULL, NULL, "\xc7\x98"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc81_table_c4[] = {
+ "\xe1\xba\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xb8\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc81_table_c5[] = {
+ "\xe1\xb9\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xe1\xb9\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc81_table_c6[] = {
+ "\xe1\xbb\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xe1\xbb\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc81_table_ce[] = {
+ "\xce\x86", NULL, NULL, NULL, "\xce\x88", NULL, "\xce\x89", NULL,
+ "\xce\x8a", NULL, NULL, NULL, NULL, NULL, "\xce\x8c", NULL,
+ NULL, NULL, NULL, NULL, "\xce\x8e", NULL, NULL, NULL,
+ "\xce\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xce\xac", NULL, NULL, NULL, "\xce\xad", NULL, "\xce\xae", NULL,
+ "\xce\xaf", NULL, NULL, NULL, NULL, NULL, "\xcf\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc81_table_cf[] = {
+ "\xcf\x8d", NULL, NULL, NULL, "\xcf\x8e", "\xce\x90", "\xce\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc81_table_d0[] = {
+ "\xd0\x83", NULL, NULL, NULL, NULL, NULL, NULL, "\xd0\x8c",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xd1\x93", NULL, NULL, NULL, NULL, NULL, NULL, "\xd1\x9c"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc81_table_e1bc[] = {
+ "\xe1\xbc\x84", "\xe1\xbc\x85", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\x8c", "\xe1\xbc\x8d", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\x94", "\xe1\xbc\x95", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\x9c", "\xe1\xbc\x9d", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xa4", "\xe1\xbc\xa5", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xac", "\xe1\xbc\xad", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xb4", "\xe1\xbc\xb5", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xbc", "\xe1\xbc\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc81_table_e1bd[] = {
+ "\xe1\xbd\x84", "\xe1\xbd\x85", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\x8c", "\xe1\xbd\x8d", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\x94", "\xe1\xbd\x95", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, "\xe1\xbd\x9d", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\xa4", "\xe1\xbd\xa5", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\xac", "\xe1\xbd\xad"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc81(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x7a) {
+ return grn_nfkc50_compose_prefix_cc81_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc3 :
+ if (utf8[1] >= 0x86 &&
+ utf8[1] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_cc81_table_c3[utf8[1] - 0x86];
+ }
+ break;
+ case 0xc4 :
+ if (utf8[1] >= 0x83 &&
+ utf8[1] <= 0x93) {
+ return grn_nfkc50_compose_prefix_cc81_table_c4[utf8[1] - 0x83];
+ }
+ break;
+ case 0xc5 :
+ if (utf8[1] >= 0x8d &&
+ utf8[1] <= 0xa9) {
+ return grn_nfkc50_compose_prefix_cc81_table_c5[utf8[1] - 0x8d];
+ }
+ break;
+ case 0xc6 :
+ if (utf8[1] >= 0xa1 &&
+ utf8[1] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_cc81_table_c6[utf8[1] - 0xa1];
+ }
+ break;
+ case 0xce :
+ if (utf8[1] >= 0x91 &&
+ utf8[1] <= 0xbf) {
+ return grn_nfkc50_compose_prefix_cc81_table_ce[utf8[1] - 0x91];
+ }
+ break;
+ case 0xcf :
+ if (utf8[1] >= 0x85 &&
+ utf8[1] <= 0x8b) {
+ return grn_nfkc50_compose_prefix_cc81_table_cf[utf8[1] - 0x85];
+ }
+ break;
+ case 0xd0 :
+ if (utf8[1] >= 0x93 &&
+ utf8[1] <= 0xba) {
+ return grn_nfkc50_compose_prefix_cc81_table_d0[utf8[1] - 0x93];
+ }
+ break;
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_compose_prefix_cc81_table_e1bc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xa9) {
+ return grn_nfkc50_compose_prefix_cc81_table_e1bd[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc82_table_[] = {
+ "\xc3\xa2", NULL, "\xc4\x89", NULL, "\xc3\xaa", NULL, "\xc4\x9d", "\xc4\xa5",
+ "\xc3\xae", "\xc4\xb5", NULL, NULL, NULL, NULL, "\xc3\xb4", NULL,
+ NULL, NULL, "\xc5\x9d", NULL, "\xc3\xbb", NULL, "\xc5\xb5", NULL,
+ "\xc5\xb7", "\xe1\xba\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc82_table_e1ba[] = {
+ "\xe1\xba\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbb\x87"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc82(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x7a) {
+ return grn_nfkc50_compose_prefix_cc82_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0xba :
+ if (utf8[2] >= 0xa1 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_compose_prefix_cc82_table_e1ba[utf8[2] - 0xa1];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] == 0x8d) {
+ return "\xe1\xbb\x99";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc83_table_[] = {
+ "\xc3\xa3", NULL, NULL, NULL, "\xe1\xba\xbd", NULL, NULL, NULL,
+ "\xc4\xa9", NULL, NULL, NULL, NULL, "\xc3\xb1", "\xc3\xb5", NULL,
+ NULL, NULL, NULL, NULL, "\xc5\xa9", "\xe1\xb9\xbd", NULL, NULL,
+ "\xe1\xbb\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc83_table_c3[] = {
+ "\xe1\xba\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbb\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, "\xe1\xbb\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc83_table_c6[] = {
+ "\xe1\xbb\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xe1\xbb\xaf"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc83(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x79) {
+ return grn_nfkc50_compose_prefix_cc83_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc3 :
+ if (utf8[1] >= 0xa2 &&
+ utf8[1] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_cc83_table_c3[utf8[1] - 0xa2];
+ }
+ break;
+ case 0xc4 :
+ if (utf8[1] == 0x83) {
+ return "\xe1\xba\xb5";
+ }
+ break;
+ case 0xc6 :
+ if (utf8[1] >= 0xa1 &&
+ utf8[1] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_cc83_table_c6[utf8[1] - 0xa1];
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc88_table_[] = {
+ "\xc3\xa4", NULL, NULL, NULL, "\xc3\xab", NULL, NULL, "\xe1\xb8\xa7",
+ "\xc3\xaf", NULL, NULL, NULL, NULL, NULL, "\xc3\xb6", NULL,
+ NULL, NULL, NULL, "\xe1\xba\x97", "\xc3\xbc", NULL, "\xe1\xba\x85", "\xe1\xba\x8d",
+ "\xc3\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc88_table_ce[] = {
+ "\xce\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xce\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xcf\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc88_table_d0[] = {
+ "\xd0\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, "\xd3\x92", NULL, NULL, NULL, NULL, "\xd0\x81",
+ "\xd3\x9c", "\xd3\x9e", "\xd3\xa4", NULL, NULL, NULL, NULL, NULL,
+ "\xd3\xa6", NULL, NULL, NULL, NULL, "\xd3\xb0", NULL, NULL,
+ NULL, "\xd3\xb4", NULL, NULL, NULL, "\xd3\xb8", NULL, "\xd3\xac",
+ NULL, NULL, "\xd3\x93", NULL, NULL, NULL, NULL, "\xd1\x91",
+ "\xd3\x9d", "\xd3\x9f", "\xd3\xa5", NULL, NULL, NULL, NULL, NULL,
+ "\xd3\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc88_table_d1[] = {
+ "\xd3\xb1", NULL, NULL, NULL, "\xd3\xb5", NULL, NULL, NULL,
+ "\xd3\xb9", NULL, "\xd3\xad", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "\xd1\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc88_table_d3[] = {
+ "\xd3\x9a", "\xd3\x9b", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xd3\xaa", "\xd3\xab"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc88(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x79) {
+ return grn_nfkc50_compose_prefix_cc88_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc3 :
+ if (utf8[1] == 0xb5) {
+ return "\xe1\xb9\x8f";
+ }
+ break;
+ case 0xc5 :
+ if (utf8[1] == 0xab) {
+ return "\xe1\xb9\xbb";
+ }
+ break;
+ case 0xce :
+ if (utf8[1] >= 0x99 &&
+ utf8[1] <= 0xb9) {
+ return grn_nfkc50_compose_prefix_cc88_table_ce[utf8[1] - 0x99];
+ }
+ break;
+ case 0xcf :
+ if (utf8[1] == 0x85) {
+ return "\xcf\x8b";
+ }
+ break;
+ case 0xd0 :
+ if (utf8[1] >= 0x86 &&
+ utf8[1] <= 0xbe) {
+ return grn_nfkc50_compose_prefix_cc88_table_d0[utf8[1] - 0x86];
+ }
+ break;
+ case 0xd1 :
+ if (utf8[1] >= 0x83 &&
+ utf8[1] <= 0x96) {
+ return grn_nfkc50_compose_prefix_cc88_table_d1[utf8[1] - 0x83];
+ }
+ break;
+ case 0xd3 :
+ if (utf8[1] >= 0x98 &&
+ utf8[1] <= 0xa9) {
+ return grn_nfkc50_compose_prefix_cc88_table_d3[utf8[1] - 0x98];
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc8a_table_[] = {
+ "\xc3\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xc5\xaf", NULL, "\xe1\xba\x98", NULL,
+ "\xe1\xba\x99"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc8a(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x79) {
+ return grn_nfkc50_compose_prefix_cc8a_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cca7_table_[] = {
+ "\xc3\xa7", "\xe1\xb8\x91", "\xc8\xa9", NULL, "\xc4\xa3", "\xe1\xb8\xa9", NULL, NULL,
+ "\xc4\xb7", "\xc4\xbc", NULL, "\xc5\x86", NULL, NULL, NULL, "\xc5\x97",
+ "\xc5\x9f", "\xc5\xa3"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cca7(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x63 &&
+ utf8[0] <= 0x74) {
+ return grn_nfkc50_compose_prefix_cca7_table_[utf8[0] - 0x63];
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc84_table_[] = {
+ "\xc4\x81", NULL, NULL, NULL, "\xc4\x93", NULL, "\xe1\xb8\xa1", NULL,
+ "\xc4\xab", NULL, NULL, NULL, NULL, NULL, "\xc5\x8d", NULL,
+ NULL, NULL, NULL, NULL, "\xc5\xab", NULL, NULL, NULL,
+ "\xc8\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc84_table_c3[] = {
+ "\xc7\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, "\xc7\x9f", NULL,
+ "\xc7\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xc8\xad",
+ "\xc8\xab", NULL, NULL, NULL, NULL, NULL, "\xc7\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc84_table_c8[] = {
+ "\xc7\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xc8\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc84_table_ce[] = {
+ "\xe1\xbe\xb9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbf\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xe1\xbf\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbe\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbf\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc84_table_d0[] = {
+ "\xd3\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "\xd3\xae", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xd3\xa3"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc84(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x79) {
+ return grn_nfkc50_compose_prefix_cc84_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc3 :
+ if (utf8[1] >= 0x86 &&
+ utf8[1] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_cc84_table_c3[utf8[1] - 0x86];
+ }
+ break;
+ case 0xc7 :
+ if (utf8[1] == 0xab) {
+ return "\xc7\xad";
+ }
+ break;
+ case 0xc8 :
+ if (utf8[1] >= 0xa7 &&
+ utf8[1] <= 0xaf) {
+ return grn_nfkc50_compose_prefix_cc84_table_c8[utf8[1] - 0xa7];
+ }
+ break;
+ case 0xce :
+ if (utf8[1] >= 0x91 &&
+ utf8[1] <= 0xb9) {
+ return grn_nfkc50_compose_prefix_cc84_table_ce[utf8[1] - 0x91];
+ }
+ break;
+ case 0xcf :
+ if (utf8[1] == 0x85) {
+ return "\xe1\xbf\xa1";
+ }
+ break;
+ case 0xd0 :
+ if (utf8[1] >= 0x98 &&
+ utf8[1] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_cc84_table_d0[utf8[1] - 0x98];
+ }
+ break;
+ case 0xd1 :
+ if (utf8[1] == 0x83) {
+ return "\xd3\xaf";
+ }
+ break;
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0xb8 :
+ if (utf8[2] == 0xb7) {
+ return "\xe1\xb8\xb9";
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] == 0x9b) {
+ return "\xe1\xb9\x9d";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc86_table_[] = {
+ "\xc4\x83", NULL, NULL, NULL, "\xc4\x95", NULL, "\xc4\x9f", NULL,
+ "\xc4\xad", NULL, NULL, NULL, NULL, NULL, "\xc5\x8f", NULL,
+ NULL, NULL, NULL, NULL, "\xc5\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc86_table_ce[] = {
+ "\xe1\xbe\xb8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbf\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xe1\xbf\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbe\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbf\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc86_table_d0[] = {
+ "\xd3\x90", NULL, NULL, NULL, NULL, "\xd3\x96", "\xd3\x81", NULL,
+ "\xd0\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "\xd0\x8e", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xd3\x91", NULL, NULL, NULL, NULL, "\xd3\x97", "\xd3\x82", NULL,
+ "\xd0\xb9"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc86(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x75) {
+ return grn_nfkc50_compose_prefix_cc86_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc8 :
+ if (utf8[1] == 0xa9) {
+ return "\xe1\xb8\x9d";
+ }
+ break;
+ case 0xce :
+ if (utf8[1] >= 0x91 &&
+ utf8[1] <= 0xb9) {
+ return grn_nfkc50_compose_prefix_cc86_table_ce[utf8[1] - 0x91];
+ }
+ break;
+ case 0xcf :
+ if (utf8[1] == 0x85) {
+ return "\xe1\xbf\xa0";
+ }
+ break;
+ case 0xd0 :
+ if (utf8[1] >= 0x90 &&
+ utf8[1] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_cc86_table_d0[utf8[1] - 0x90];
+ }
+ break;
+ case 0xd1 :
+ if (utf8[1] == 0x83) {
+ return "\xd1\x9e";
+ }
+ break;
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0xba :
+ if (utf8[2] == 0xa1) {
+ return "\xe1\xba\xb7";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cca8_table_[] = {
+ "\xc4\x85", NULL, NULL, NULL, "\xc4\x99", NULL, NULL, NULL,
+ "\xc4\xaf", NULL, NULL, NULL, NULL, NULL, "\xc7\xab", NULL,
+ NULL, NULL, NULL, NULL, "\xc5\xb3"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cca8(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x75) {
+ return grn_nfkc50_compose_prefix_cca8_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc87_table_[] = {
+ "\xc8\xa7", "\xe1\xb8\x83", "\xc4\x8b", "\xe1\xb8\x8b", "\xc4\x97", "\xe1\xb8\x9f", "\xc4\xa1", "\xe1\xb8\xa3",
+ NULL, NULL, NULL, NULL, "\xe1\xb9\x81", "\xe1\xb9\x85", "\xc8\xaf", "\xe1\xb9\x97",
+ NULL, "\xe1\xb9\x99", "\xe1\xb9\xa1", "\xe1\xb9\xab", NULL, NULL, "\xe1\xba\x87", "\xe1\xba\x8b",
+ "\xe1\xba\x8f", "\xc5\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc87_table_c5[] = {
+ "\xe1\xb9\xa5", NULL, NULL, NULL, NULL, NULL, "\xe1\xb9\xa7"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc87(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x7a) {
+ return grn_nfkc50_compose_prefix_cc87_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc5 :
+ if (utf8[1] >= 0x9b &&
+ utf8[1] <= 0xa1) {
+ return grn_nfkc50_compose_prefix_cc87_table_c5[utf8[1] - 0x9b];
+ }
+ break;
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0xb9 :
+ if (utf8[2] == 0xa3) {
+ return "\xe1\xb9\xa9";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc8c_table_[] = {
+ "\xc7\x8e", NULL, "\xc4\x8d", "\xc4\x8f", "\xc4\x9b", NULL, "\xc7\xa7", "\xc8\x9f",
+ "\xc7\x90", "\xc7\xb0", "\xc7\xa9", "\xc4\xbe", NULL, "\xc5\x88", "\xc7\x92", NULL,
+ NULL, "\xc5\x99", "\xc5\xa1", "\xc5\xa5", "\xc7\x94", NULL, NULL, NULL,
+ NULL, "\xc5\xbe"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc8c(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x7a) {
+ return grn_nfkc50_compose_prefix_cc8c_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc3 :
+ if (utf8[1] == 0xbc) {
+ return "\xc7\x9a";
+ }
+ break;
+ case 0xc6 :
+ if (utf8[1] == 0xb7) {
+ return "\xc7\xae";
+ }
+ break;
+ case 0xca :
+ if (utf8[1] == 0x92) {
+ return "\xc7\xaf";
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc8b_table_[] = {
+ "\xc5\x91", NULL, NULL, NULL, NULL, NULL, "\xc5\xb1"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc8b(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x6f &&
+ utf8[0] <= 0x75) {
+ return grn_nfkc50_compose_prefix_cc8b_table_[utf8[0] - 0x6f];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xd0 :
+ if (utf8[1] == 0xa3) {
+ return "\xd3\xb2";
+ }
+ break;
+ case 0xd1 :
+ if (utf8[1] == 0x83) {
+ return "\xd3\xb3";
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc9b_table_[] = {
+ "\xc6\xa1", NULL, NULL, NULL, NULL, NULL, "\xc6\xb0"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc9b(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x6f &&
+ utf8[0] <= 0x75) {
+ return grn_nfkc50_compose_prefix_cc9b_table_[utf8[0] - 0x6f];
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc8f_table_[] = {
+ "\xc8\x81", NULL, NULL, NULL, "\xc8\x85", NULL, NULL, NULL,
+ "\xc8\x89", NULL, NULL, NULL, NULL, NULL, "\xc8\x8d", NULL,
+ NULL, "\xc8\x91", NULL, NULL, "\xc8\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc8f_table_d1[] = {
+ "\xd1\xb6", "\xd1\xb7"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc8f(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x75) {
+ return grn_nfkc50_compose_prefix_cc8f_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xd1 :
+ if (utf8[1] >= 0xb4 &&
+ utf8[1] <= 0xb5) {
+ return grn_nfkc50_compose_prefix_cc8f_table_d1[utf8[1] - 0xb4];
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc91_table_[] = {
+ "\xc8\x83", NULL, NULL, NULL, "\xc8\x87", NULL, NULL, NULL,
+ "\xc8\x8b", NULL, NULL, NULL, NULL, NULL, "\xc8\x8f", NULL,
+ NULL, "\xc8\x93", NULL, NULL, "\xc8\x97"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc91(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x75) {
+ return grn_nfkc50_compose_prefix_cc91_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cca6_table_[] = {
+ "\xc8\x99", "\xc8\x9b"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cca6(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x73 &&
+ utf8[0] <= 0x74) {
+ return grn_nfkc50_compose_prefix_cca6_table_[utf8[0] - 0x73];
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_d993(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xd8 :
+ if (utf8[1] == 0xa7) {
+ return "\xd8\xa2";
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_d994_table_d9[] = {
+ "\xd8\xa4", NULL, "\xd8\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_d994_table_db[] = {
+ "\xdb\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, "\xdb\x93", NULL, NULL, "\xdb\x80"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_d994(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xd8 :
+ if (utf8[1] == 0xa7) {
+ return "\xd8\xa3";
+ }
+ break;
+ case 0xd9 :
+ if (utf8[1] >= 0x88 &&
+ utf8[1] <= 0x8a) {
+ return grn_nfkc50_compose_prefix_d994_table_d9[utf8[1] - 0x88];
+ }
+ break;
+ case 0xdb :
+ if (utf8[1] >= 0x81 &&
+ utf8[1] <= 0x95) {
+ return grn_nfkc50_compose_prefix_d994_table_db[utf8[1] - 0x81];
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_d995(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xd8 :
+ if (utf8[1] == 0xa7) {
+ return "\xd8\xa5";
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e0a4bc_table_e0a4[] = {
+ "\xe0\xa4\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe0\xa4\xb1", NULL, NULL, "\xe0\xa4\xb4"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0a4bc(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xa4 :
+ if (utf8[2] >= 0xa8 &&
+ utf8[2] <= 0xb3) {
+ return grn_nfkc50_compose_prefix_e0a4bc_table_e0a4[utf8[2] - 0xa8];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0a6be(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xa7 :
+ if (utf8[2] == 0x87) {
+ return "\xe0\xa7\x8b";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0a797(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xa7 :
+ if (utf8[2] == 0x87) {
+ return "\xe0\xa7\x8c";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0ad96(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xad :
+ if (utf8[2] == 0x87) {
+ return "\xe0\xad\x88";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0acbe(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xad :
+ if (utf8[2] == 0x87) {
+ return "\xe0\xad\x8b";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0ad97(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xad :
+ if (utf8[2] == 0x87) {
+ return "\xe0\xad\x8c";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0af97(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xae :
+ if (utf8[2] == 0x92) {
+ return "\xe0\xae\x94";
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] == 0x86) {
+ return "\xe0\xaf\x8c";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e0aebe_table_e0af[] = {
+ "\xe0\xaf\x8a", "\xe0\xaf\x8b"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0aebe(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xaf :
+ if (utf8[2] >= 0x86 &&
+ utf8[2] <= 0x87) {
+ return grn_nfkc50_compose_prefix_e0aebe_table_e0af[utf8[2] - 0x86];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0b196(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xb1 :
+ if (utf8[2] == 0x86) {
+ return "\xe0\xb1\x88";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e0b395_table_e0b3[] = {
+ "\xe0\xb3\x87", NULL, NULL, NULL, "\xe0\xb3\x8b"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0b395(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xb2 :
+ if (utf8[2] == 0xbf) {
+ return "\xe0\xb3\x80";
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x86 &&
+ utf8[2] <= 0x8a) {
+ return grn_nfkc50_compose_prefix_e0b395_table_e0b3[utf8[2] - 0x86];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0b396(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xb3 :
+ if (utf8[2] == 0x86) {
+ return "\xe0\xb3\x88";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0b382(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xb3 :
+ if (utf8[2] == 0x86) {
+ return "\xe0\xb3\x8a";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e0b4be_table_e0b5[] = {
+ "\xe0\xb5\x8a", "\xe0\xb5\x8b"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0b4be(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xb5 :
+ if (utf8[2] >= 0x86 &&
+ utf8[2] <= 0x87) {
+ return grn_nfkc50_compose_prefix_e0b4be_table_e0b5[utf8[2] - 0x86];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0b597(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xb5 :
+ if (utf8[2] == 0x86) {
+ return "\xe0\xb5\x8c";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e0b78a_table_e0b7[] = {
+ "\xe0\xb7\x9a", NULL, NULL, "\xe0\xb7\x9d"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0b78a(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xb7 :
+ if (utf8[2] >= 0x99 &&
+ utf8[2] <= 0x9c) {
+ return grn_nfkc50_compose_prefix_e0b78a_table_e0b7[utf8[2] - 0x99];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0b78f(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xb7 :
+ if (utf8[2] == 0x99) {
+ return "\xe0\xb7\x9c";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e0b79f(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe0 :
+ switch (utf8[1]) {
+ case 0xb7 :
+ if (utf8[2] == 0x99) {
+ return "\xe0\xb7\x9e";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_e180ae(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] == 0xa5) {
+ return "\xe1\x80\xa6";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e1acb5_table_e1ac[] = {
+ "\xe1\xac\x86", NULL, "\xe1\xac\x88", NULL, "\xe1\xac\x8a", NULL, "\xe1\xac\x8c", NULL,
+ "\xe1\xac\x8e", NULL, NULL, NULL, "\xe1\xac\x92", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, "\xe1\xac\xbb", NULL, "\xe1\xac\xbd",
+ NULL, "\xe1\xad\x80", "\xe1\xad\x81"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e1acb5(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0xac :
+ if (utf8[2] >= 0x85 &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_compose_prefix_e1acb5_table_e1ac[utf8[2] - 0x85];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] == 0x82) {
+ return "\xe1\xad\x83";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_cca5(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] == 0x61) {
+ return "\xe1\xb8\x81";
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cca3_table_[] = {
+ "\xe1\xba\xa1", "\xe1\xb8\x85", NULL, "\xe1\xb8\x8d", "\xe1\xba\xb9", NULL, NULL, "\xe1\xb8\xa5",
+ "\xe1\xbb\x8b", NULL, "\xe1\xb8\xb3", "\xe1\xb8\xb7", "\xe1\xb9\x83", "\xe1\xb9\x87", "\xe1\xbb\x8d", NULL,
+ NULL, "\xe1\xb9\x9b", "\xe1\xb9\xa3", "\xe1\xb9\xad", "\xe1\xbb\xa5", "\xe1\xb9\xbf", "\xe1\xba\x89", NULL,
+ "\xe1\xbb\xb5", "\xe1\xba\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_cca3_table_c6[] = {
+ "\xe1\xbb\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xe1\xbb\xb1"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cca3(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x7a) {
+ return grn_nfkc50_compose_prefix_cca3_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc6 :
+ if (utf8[1] >= 0xa1 &&
+ utf8[1] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_cca3_table_c6[utf8[1] - 0xa1];
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_ccb1_table_[] = {
+ "\xe1\xb8\x87", NULL, "\xe1\xb8\x8f", NULL, NULL, NULL, "\xe1\xba\x96", NULL,
+ NULL, "\xe1\xb8\xb5", "\xe1\xb8\xbb", NULL, "\xe1\xb9\x89", NULL, NULL, NULL,
+ "\xe1\xb9\x9f", NULL, "\xe1\xb9\xaf", NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xba\x95"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_ccb1(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x62 &&
+ utf8[0] <= 0x7a) {
+ return grn_nfkc50_compose_prefix_ccb1_table_[utf8[0] - 0x62];
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_ccad_table_[] = {
+ "\xe1\xb8\x93", "\xe1\xb8\x99", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xb8\xbd", NULL, "\xe1\xb9\x8b", NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xb9\xb1", "\xe1\xb9\xb7"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_ccad(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x64 &&
+ utf8[0] <= 0x75) {
+ return grn_nfkc50_compose_prefix_ccad_table_[utf8[0] - 0x64];
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_ccb0_table_[] = {
+ "\xe1\xb8\x9b", NULL, NULL, NULL, "\xe1\xb8\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xb9\xb5"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_ccb0(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x65 &&
+ utf8[0] <= 0x75) {
+ return grn_nfkc50_compose_prefix_ccb0_table_[utf8[0] - 0x65];
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_ccae(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] == 0x68) {
+ return "\xe1\xb8\xab";
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static inline const char *
+grn_nfkc50_compose_prefix_cca4(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] == 0x75) {
+ return "\xe1\xb9\xb3";
+ } else {
+ return NULL;
+ }
+ } else {
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc89_table_[] = {
+ "\xe1\xba\xa3", NULL, NULL, NULL, "\xe1\xba\xbb", NULL, NULL, NULL,
+ "\xe1\xbb\x89", NULL, NULL, NULL, NULL, NULL, "\xe1\xbb\x8f", NULL,
+ NULL, NULL, NULL, NULL, "\xe1\xbb\xa7", NULL, NULL, NULL,
+ "\xe1\xbb\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc89_table_c3[] = {
+ "\xe1\xba\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbb\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, "\xe1\xbb\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc89_table_c6[] = {
+ "\xe1\xbb\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xe1\xbb\xad"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc89(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x61 &&
+ utf8[0] <= 0x79) {
+ return grn_nfkc50_compose_prefix_cc89_table_[utf8[0] - 0x61];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xc3 :
+ if (utf8[1] >= 0xa2 &&
+ utf8[1] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_cc89_table_c3[utf8[1] - 0xa2];
+ }
+ break;
+ case 0xc4 :
+ if (utf8[1] == 0x83) {
+ return "\xe1\xba\xb3";
+ }
+ break;
+ case 0xc6 :
+ if (utf8[1] >= 0xa1 &&
+ utf8[1] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_cc89_table_c6[utf8[1] - 0xa1];
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc93_table_ce[] = {
+ "\xe1\xbc\x88", NULL, NULL, NULL, "\xe1\xbc\x98", NULL, "\xe1\xbc\xa8", NULL,
+ "\xe1\xbc\xb8", NULL, NULL, NULL, NULL, NULL, "\xe1\xbd\x88", NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\x80", NULL, NULL, NULL, "\xe1\xbc\x90", NULL, "\xe1\xbc\xa0", NULL,
+ "\xe1\xbc\xb0", NULL, NULL, NULL, NULL, NULL, "\xe1\xbd\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc93_table_cf[] = {
+ "\xe1\xbf\xa4", NULL, NULL, NULL, "\xe1\xbd\x90", NULL, NULL, NULL,
+ "\xe1\xbd\xa0"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc93(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xce :
+ if (utf8[1] >= 0x91 &&
+ utf8[1] <= 0xbf) {
+ return grn_nfkc50_compose_prefix_cc93_table_ce[utf8[1] - 0x91];
+ }
+ break;
+ case 0xcf :
+ if (utf8[1] >= 0x81 &&
+ utf8[1] <= 0x89) {
+ return grn_nfkc50_compose_prefix_cc93_table_cf[utf8[1] - 0x81];
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cc94_table_ce[] = {
+ "\xe1\xbc\x89", NULL, NULL, NULL, "\xe1\xbc\x99", NULL, "\xe1\xbc\xa9", NULL,
+ "\xe1\xbc\xb9", NULL, NULL, NULL, NULL, NULL, "\xe1\xbd\x89", NULL,
+ "\xe1\xbf\xac", NULL, NULL, NULL, "\xe1\xbd\x99", NULL, NULL, NULL,
+ "\xe1\xbd\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\x81", NULL, NULL, NULL, "\xe1\xbc\x91", NULL, "\xe1\xbc\xa1", NULL,
+ "\xe1\xbc\xb1", NULL, NULL, NULL, NULL, NULL, "\xe1\xbd\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_cc94_table_cf[] = {
+ "\xe1\xbf\xa5", NULL, NULL, NULL, "\xe1\xbd\x91", NULL, NULL, NULL,
+ "\xe1\xbd\xa1"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cc94(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xce :
+ if (utf8[1] >= 0x91 &&
+ utf8[1] <= 0xbf) {
+ return grn_nfkc50_compose_prefix_cc94_table_ce[utf8[1] - 0x91];
+ }
+ break;
+ case 0xcf :
+ if (utf8[1] >= 0x81 &&
+ utf8[1] <= 0x89) {
+ return grn_nfkc50_compose_prefix_cc94_table_cf[utf8[1] - 0x81];
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cd82_table_ce[] = {
+ "\xe1\xbe\xb6", NULL, NULL, NULL, NULL, NULL, "\xe1\xbf\x86", NULL,
+ "\xe1\xbf\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_cd82_table_cf[] = {
+ "\xe1\xbf\xa6", NULL, NULL, NULL, "\xe1\xbf\xb6", "\xe1\xbf\x97", "\xe1\xbf\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_cd82_table_e1bc[] = {
+ "\xe1\xbc\x86", "\xe1\xbc\x87", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\x8e", "\xe1\xbc\x8f", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xa6", "\xe1\xbc\xa7", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xae", "\xe1\xbc\xaf", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xb6", "\xe1\xbc\xb7", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbc\xbe", "\xe1\xbc\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_cd82_table_e1bd[] = {
+ "\xe1\xbd\x96", "\xe1\xbd\x97", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, "\xe1\xbd\x9f", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\xa6", "\xe1\xbd\xa7", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbd\xae", "\xe1\xbd\xaf"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cd82(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xce :
+ if (utf8[1] >= 0xb1 &&
+ utf8[1] <= 0xb9) {
+ return grn_nfkc50_compose_prefix_cd82_table_ce[utf8[1] - 0xb1];
+ }
+ break;
+ case 0xcf :
+ if (utf8[1] >= 0x85 &&
+ utf8[1] <= 0x8b) {
+ return grn_nfkc50_compose_prefix_cd82_table_cf[utf8[1] - 0x85];
+ }
+ break;
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb9) {
+ return grn_nfkc50_compose_prefix_cd82_table_e1bc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xa9) {
+ return grn_nfkc50_compose_prefix_cd82_table_e1bd[utf8[2] - 0x90];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_cd85_table_ce[] = {
+ "\xe1\xbe\xbc", NULL, NULL, NULL, NULL, NULL, "\xe1\xbf\x8c", NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbf\xbc", NULL, NULL, "\xe1\xbe\xb4", NULL, "\xe1\xbf\x84", NULL, NULL,
+ "\xe1\xbe\xb3", NULL, NULL, NULL, NULL, NULL, "\xe1\xbf\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_cd85_table_cf[] = {
+ "\xe1\xbf\xb3", NULL, NULL, NULL, NULL, "\xe1\xbf\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_cd85_table_e1bc[] = {
+ "\xe1\xbe\x80", "\xe1\xbe\x81", "\xe1\xbe\x82", "\xe1\xbe\x83", "\xe1\xbe\x84", "\xe1\xbe\x85", "\xe1\xbe\x86", "\xe1\xbe\x87",
+ "\xe1\xbe\x88", "\xe1\xbe\x89", "\xe1\xbe\x8a", "\xe1\xbe\x8b", "\xe1\xbe\x8c", "\xe1\xbe\x8d", "\xe1\xbe\x8e", "\xe1\xbe\x8f",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbe\x90", "\xe1\xbe\x91", "\xe1\xbe\x92", "\xe1\xbe\x93", "\xe1\xbe\x94", "\xe1\xbe\x95", "\xe1\xbe\x96", "\xe1\xbe\x97",
+ "\xe1\xbe\x98", "\xe1\xbe\x99", "\xe1\xbe\x9a", "\xe1\xbe\x9b", "\xe1\xbe\x9c", "\xe1\xbe\x9d", "\xe1\xbe\x9e", "\xe1\xbe\x9f"
+};
+
+static const char *grn_nfkc50_compose_prefix_cd85_table_e1bd[] = {
+ "\xe1\xbe\xa0", "\xe1\xbe\xa1", "\xe1\xbe\xa2", "\xe1\xbe\xa3", "\xe1\xbe\xa4", "\xe1\xbe\xa5", "\xe1\xbe\xa6", "\xe1\xbe\xa7",
+ "\xe1\xbe\xa8", "\xe1\xbe\xa9", "\xe1\xbe\xaa", "\xe1\xbe\xab", "\xe1\xbe\xac", "\xe1\xbe\xad", "\xe1\xbe\xae", "\xe1\xbe\xaf",
+ "\xe1\xbe\xb2", NULL, NULL, NULL, "\xe1\xbf\x82", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xe1\xbf\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_cd85_table_e1bf[] = {
+ "\xe1\xbf\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe1\xbf\xb7"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_cd85(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xce :
+ if (utf8[1] >= 0x91 &&
+ utf8[1] <= 0xb7) {
+ return grn_nfkc50_compose_prefix_cd85_table_ce[utf8[1] - 0x91];
+ }
+ break;
+ case 0xcf :
+ if (utf8[1] >= 0x89 &&
+ utf8[1] <= 0x8e) {
+ return grn_nfkc50_compose_prefix_cd85_table_cf[utf8[1] - 0x89];
+ }
+ break;
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xaf) {
+ return grn_nfkc50_compose_prefix_cd85_table_e1bc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0xa0 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_cd85_table_e1bd[utf8[2] - 0xa0];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] == 0xb6) {
+ return "\xe1\xbe\xb7";
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x86 &&
+ utf8[2] <= 0xb6) {
+ return grn_nfkc50_compose_prefix_cd85_table_e1bf[utf8[2] - 0x86];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_ccb8_table_[] = {
+ "\xe2\x89\xae", "\xe2\x89\xa0", "\xe2\x89\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_ccb8_table_e286[] = {
+ "\xe2\x86\x9a", NULL, "\xe2\x86\x9b", NULL, "\xe2\x86\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_ccb8_table_e287[] = {
+ "\xe2\x87\x8d", NULL, "\xe2\x87\x8f", NULL, "\xe2\x87\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_ccb8_table_e288[] = {
+ "\xe2\x88\x84", NULL, NULL, NULL, NULL, "\xe2\x88\x89", NULL, NULL,
+ "\xe2\x88\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe2\x88\xa4", NULL, "\xe2\x88\xa6", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, "\xe2\x89\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_ccb8_table_e289[] = {
+ "\xe2\x89\x84", NULL, "\xe2\x89\x87", NULL, NULL, "\xe2\x89\x89", NULL, NULL,
+ NULL, NULL, "\xe2\x89\xad", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, "\xe2\x89\xa2", NULL,
+ NULL, "\xe2\x89\xb0", "\xe2\x89\xb1", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xe2\x89\xb4",
+ "\xe2\x89\xb5", NULL, NULL, "\xe2\x89\xb8", "\xe2\x89\xb9", NULL, NULL, "\xe2\x8a\x80",
+ "\xe2\x8a\x81", "\xe2\x8b\xa0", "\xe2\x8b\xa1"
+};
+
+static const char *grn_nfkc50_compose_prefix_ccb8_table_e28a[] = {
+ "\xe2\x8a\x84", "\xe2\x8a\x85", NULL, NULL, "\xe2\x8a\x88", "\xe2\x8a\x89", NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\xe2\x8b\xa2",
+ "\xe2\x8b\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe2\x8a\xac", NULL, NULL, NULL, NULL, NULL, "\xe2\x8a\xad", "\xe2\x8a\xae",
+ NULL, "\xe2\x8a\xaf", NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xe2\x8b\xaa", "\xe2\x8b\xab", "\xe2\x8b\xac", "\xe2\x8b\xad"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_ccb8(const unsigned char *utf8)
+{
+ if (utf8[0] < 0x80) {
+ if (utf8[0] >= 0x3c &&
+ utf8[0] <= 0x3e) {
+ return grn_nfkc50_compose_prefix_ccb8_table_[utf8[0] - 0x3c];
+ } else {
+ return NULL;
+ }
+ } else {
+ switch (utf8[0]) {
+ case 0xe2 :
+ switch (utf8[1]) {
+ case 0x86 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0x94) {
+ return grn_nfkc50_compose_prefix_ccb8_table_e286[utf8[2] - 0x90];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0x94) {
+ return grn_nfkc50_compose_prefix_ccb8_table_e287[utf8[2] - 0x90];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x83 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_ccb8_table_e288[utf8[2] - 0x83];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x83 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_compose_prefix_ccb8_table_e289[utf8[2] - 0x83];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x82 &&
+ utf8[2] <= 0xb5) {
+ return grn_nfkc50_compose_prefix_ccb8_table_e28a[utf8[2] - 0x82];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e38299_table_e381[] = {
+ "\xe3\x82\x94", NULL, NULL, NULL, NULL, "\xe3\x81\x8c", NULL, "\xe3\x81\x8e",
+ NULL, "\xe3\x81\x90", NULL, "\xe3\x81\x92", NULL, "\xe3\x81\x94", NULL, "\xe3\x81\x96",
+ NULL, "\xe3\x81\x98", NULL, "\xe3\x81\x9a", NULL, "\xe3\x81\x9c", NULL, "\xe3\x81\x9e",
+ NULL, "\xe3\x81\xa0", NULL, "\xe3\x81\xa2", NULL, NULL, "\xe3\x81\xa5", NULL,
+ "\xe3\x81\xa7", NULL, "\xe3\x81\xa9", NULL, NULL, NULL, NULL, NULL,
+ NULL, "\xe3\x81\xb0", NULL, NULL, "\xe3\x81\xb3", NULL, NULL, "\xe3\x81\xb6",
+ NULL, NULL, "\xe3\x81\xb9", NULL, NULL, "\xe3\x81\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e38299_table_e382[] = {
+ "\xe3\x82\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, "\xe3\x83\xb4", NULL, NULL, NULL, NULL, "\xe3\x82\xac", NULL,
+ "\xe3\x82\xae", NULL, "\xe3\x82\xb0", NULL, "\xe3\x82\xb2", NULL, "\xe3\x82\xb4", NULL,
+ "\xe3\x82\xb6", NULL, "\xe3\x82\xb8", NULL, "\xe3\x82\xba", NULL, "\xe3\x82\xbc", NULL,
+ "\xe3\x82\xbe", NULL, "\xe3\x83\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e38299_table_e383[] = {
+ "\xe3\x83\x82", NULL, NULL, "\xe3\x83\x85", NULL, "\xe3\x83\x87", NULL, "\xe3\x83\x89",
+ NULL, NULL, NULL, NULL, NULL, NULL, "\xe3\x83\x90", NULL,
+ NULL, "\xe3\x83\x93", NULL, NULL, "\xe3\x83\x96", NULL, NULL, "\xe3\x83\x99",
+ NULL, NULL, "\xe3\x83\x9c", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, "\xe3\x83\xb7", "\xe3\x83\xb8",
+ "\xe3\x83\xb9", "\xe3\x83\xba", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xe3\x83\xbe"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e38299(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe3 :
+ switch (utf8[1]) {
+ case 0x81 :
+ if (utf8[2] >= 0x86 &&
+ utf8[2] <= 0xbb) {
+ return grn_nfkc50_compose_prefix_e38299_table_e381[utf8[2] - 0x86];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x9d &&
+ utf8[2] <= 0xbf) {
+ return grn_nfkc50_compose_prefix_e38299_table_e382[utf8[2] - 0x9d];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x81 &&
+ utf8[2] <= 0xbd) {
+ return grn_nfkc50_compose_prefix_e38299_table_e383[utf8[2] - 0x81];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e3829a_table_e381[] = {
+ "\xe3\x81\xb1", NULL, NULL, "\xe3\x81\xb4", NULL, NULL, "\xe3\x81\xb7", NULL,
+ NULL, "\xe3\x81\xba", NULL, NULL, "\xe3\x81\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e3829a_table_e383[] = {
+ "\xe3\x83\x91", NULL, NULL, "\xe3\x83\x94", NULL, NULL, "\xe3\x83\x97", NULL,
+ NULL, "\xe3\x83\x9a", NULL, NULL, "\xe3\x83\x9d"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e3829a(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe3 :
+ switch (utf8[1]) {
+ case 0x81 :
+ if (utf8[2] >= 0xaf &&
+ utf8[2] <= 0xbb) {
+ return grn_nfkc50_compose_prefix_e3829a_table_e381[utf8[2] - 0xaf];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x8f &&
+ utf8[2] <= 0x9b) {
+ return grn_nfkc50_compose_prefix_e3829a_table_e383[utf8[2] - 0x8f];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185a1_table_e184[] = {
+ "\xea\xb0\x80", "\xea\xb9\x8c", "\xeb\x82\x98", "\xeb\x8b\xa4", "\xeb\x94\xb0", "\xeb\x9d\xbc", "\xeb\xa7\x88", "\xeb\xb0\x94",
+ "\xeb\xb9\xa0", "\xec\x82\xac", "\xec\x8b\xb8", "\xec\x95\x84", "\xec\x9e\x90", "\xec\xa7\x9c", "\xec\xb0\xa8", "\xec\xb9\xb4",
+ "\xed\x83\x80", "\xed\x8c\x8c", "\xed\x95\x98"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185a1(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185a1_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eab0[] = {
+ "\xea\xb0\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb0\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eab1[] = {
+ "\xea\xb1\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eab2[] = {
+ "\xea\xb2\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eab3[] = {
+ "\xea\xb3\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb3\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eab4[] = {
+ "\xea\xb4\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eab5[] = {
+ "\xea\xb5\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eab6[] = {
+ "\xea\xb6\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eab7[] = {
+ "\xea\xb7\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb7\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eab8[] = {
+ "\xea\xb8\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eab9[] = {
+ "\xea\xb9\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eaba[] = {
+ "\xea\xba\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xba\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eabb[] = {
+ "\xea\xbb\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eabc[] = {
+ "\xea\xbc\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eabd[] = {
+ "\xea\xbd\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eabe[] = {
+ "\xea\xbe\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbe\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eabf[] = {
+ "\xea\xbf\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb80[] = {
+ "\xeb\x80\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb81[] = {
+ "\xeb\x81\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x81\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb82[] = {
+ "\xeb\x82\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb83[] = {
+ "\xeb\x83\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb84[] = {
+ "\xeb\x84\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb85[] = {
+ "\xeb\x85\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x85\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb86[] = {
+ "\xeb\x86\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb87[] = {
+ "\xeb\x87\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb88[] = {
+ "\xeb\x88\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x88\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb89[] = {
+ "\xeb\x89\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb8a[] = {
+ "\xeb\x8a\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb8b[] = {
+ "\xeb\x8b\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb8c[] = {
+ "\xeb\x8c\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8c\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb8d[] = {
+ "\xeb\x8d\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb8e[] = {
+ "\xeb\x8e\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb8f[] = {
+ "\xeb\x8f\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8f\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb90[] = {
+ "\xeb\x90\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb91[] = {
+ "\xeb\x91\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb92[] = {
+ "\xeb\x92\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb93[] = {
+ "\xeb\x93\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x93\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb94[] = {
+ "\xeb\x94\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb95[] = {
+ "\xeb\x95\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb96[] = {
+ "\xeb\x96\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x96\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb97[] = {
+ "\xeb\x97\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb98[] = {
+ "\xeb\x98\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb99[] = {
+ "\xeb\x99\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb9a[] = {
+ "\xeb\x9a\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9a\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb9b[] = {
+ "\xeb\x9b\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb9c[] = {
+ "\xeb\x9c\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb9d[] = {
+ "\xeb\x9d\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9d\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb9e[] = {
+ "\xeb\x9e\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eb9f[] = {
+ "\xeb\x9f\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eba0[] = {
+ "\xeb\xa0\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eba1[] = {
+ "\xeb\xa1\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa1\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eba2[] = {
+ "\xeb\xa2\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eba3[] = {
+ "\xeb\xa3\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eba4[] = {
+ "\xeb\xa4\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa4\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eba5[] = {
+ "\xeb\xa5\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eba6[] = {
+ "\xeb\xa6\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eba7[] = {
+ "\xeb\xa7\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eba8[] = {
+ "\xeb\xa8\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa8\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eba9[] = {
+ "\xeb\xa9\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebaa[] = {
+ "\xeb\xaa\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebab[] = {
+ "\xeb\xab\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xab\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebac[] = {
+ "\xeb\xac\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebad[] = {
+ "\xeb\xad\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebae[] = {
+ "\xeb\xae\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebaf[] = {
+ "\xeb\xaf\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xaf\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebb0[] = {
+ "\xeb\xb0\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebb1[] = {
+ "\xeb\xb1\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebb2[] = {
+ "\xeb\xb2\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb2\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebb3[] = {
+ "\xeb\xb3\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebb4[] = {
+ "\xeb\xb4\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebb5[] = {
+ "\xeb\xb5\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebb6[] = {
+ "\xeb\xb6\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb6\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebb7[] = {
+ "\xeb\xb7\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebb8[] = {
+ "\xeb\xb8\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebb9[] = {
+ "\xeb\xb9\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb9\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebba[] = {
+ "\xeb\xba\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebbb[] = {
+ "\xeb\xbb\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebbc[] = {
+ "\xeb\xbc\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebbd[] = {
+ "\xeb\xbd\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbd\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebbe[] = {
+ "\xeb\xbe\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ebbf[] = {
+ "\xeb\xbf\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec80[] = {
+ "\xec\x80\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x80\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec81[] = {
+ "\xec\x81\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec82[] = {
+ "\xec\x82\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec83[] = {
+ "\xec\x83\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec84[] = {
+ "\xec\x84\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x84\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec85[] = {
+ "\xec\x85\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec86[] = {
+ "\xec\x86\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec87[] = {
+ "\xec\x87\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x87\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec88[] = {
+ "\xec\x88\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec89[] = {
+ "\xec\x89\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec8a[] = {
+ "\xec\x8a\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec8b[] = {
+ "\xec\x8b\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8b\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec8c[] = {
+ "\xec\x8c\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec8d[] = {
+ "\xec\x8d\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec8e[] = {
+ "\xec\x8e\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8e\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec8f[] = {
+ "\xec\x8f\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec90[] = {
+ "\xec\x90\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec91[] = {
+ "\xec\x91\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec92[] = {
+ "\xec\x92\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x92\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec93[] = {
+ "\xec\x93\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec94[] = {
+ "\xec\x94\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec95[] = {
+ "\xec\x95\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x95\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec96[] = {
+ "\xec\x96\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec97[] = {
+ "\xec\x97\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec98[] = {
+ "\xec\x98\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec99[] = {
+ "\xec\x99\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x99\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec9a[] = {
+ "\xec\x9a\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec9b[] = {
+ "\xec\x9b\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec9c[] = {
+ "\xec\x9c\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9c\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec9d[] = {
+ "\xec\x9d\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec9e[] = {
+ "\xec\x9e\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ec9f[] = {
+ "\xec\x9f\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eca0[] = {
+ "\xec\xa0\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa0\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eca1[] = {
+ "\xec\xa1\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eca2[] = {
+ "\xec\xa2\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eca3[] = {
+ "\xec\xa3\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa3\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eca4[] = {
+ "\xec\xa4\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eca5[] = {
+ "\xec\xa5\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eca6[] = {
+ "\xec\xa6\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eca7[] = {
+ "\xec\xa7\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa7\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eca8[] = {
+ "\xec\xa8\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_eca9[] = {
+ "\xec\xa9\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecaa[] = {
+ "\xec\xaa\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaa\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecab[] = {
+ "\xec\xab\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecac[] = {
+ "\xec\xac\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecad[] = {
+ "\xec\xad\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecae[] = {
+ "\xec\xae\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xae\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecaf[] = {
+ "\xec\xaf\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecb0[] = {
+ "\xec\xb0\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecb1[] = {
+ "\xec\xb1\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb1\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecb2[] = {
+ "\xec\xb2\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecb3[] = {
+ "\xec\xb3\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecb4[] = {
+ "\xec\xb4\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecb5[] = {
+ "\xec\xb5\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb5\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecb6[] = {
+ "\xec\xb6\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecb7[] = {
+ "\xec\xb7\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecb8[] = {
+ "\xec\xb8\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb8\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecb9[] = {
+ "\xec\xb9\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecba[] = {
+ "\xec\xba\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecbb[] = {
+ "\xec\xbb\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecbc[] = {
+ "\xec\xbc\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbc\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecbd[] = {
+ "\xec\xbd\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecbe[] = {
+ "\xec\xbe\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ecbf[] = {
+ "\xec\xbf\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbf\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed80[] = {
+ "\xed\x80\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed81[] = {
+ "\xed\x81\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed82[] = {
+ "\xed\x82\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed83[] = {
+ "\xed\x83\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x83\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed84[] = {
+ "\xed\x84\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed85[] = {
+ "\xed\x85\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed86[] = {
+ "\xed\x86\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x86\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed87[] = {
+ "\xed\x87\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed88[] = {
+ "\xed\x88\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed89[] = {
+ "\xed\x89\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed8a[] = {
+ "\xed\x8a\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8a\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed8b[] = {
+ "\xed\x8b\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed8c[] = {
+ "\xed\x8c\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed8d[] = {
+ "\xed\x8d\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8d\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed8e[] = {
+ "\xed\x8e\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed8f[] = {
+ "\xed\x8f\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed90[] = {
+ "\xed\x90\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed91[] = {
+ "\xed\x91\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x91\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed92[] = {
+ "\xed\x92\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed93[] = {
+ "\xed\x93\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed94[] = {
+ "\xed\x94\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x94\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed95[] = {
+ "\xed\x95\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed96[] = {
+ "\xed\x96\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed97[] = {
+ "\xed\x97\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xa5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed98[] = {
+ "\xed\x98\x81", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\x9d", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x98\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed99[] = {
+ "\xed\x99\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed9a[] = {
+ "\xed\x9a\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed9b[] = {
+ "\xed\x9b\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9b\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed9c[] = {
+ "\xed\x9c\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a8_table_ed9d[] = {
+ "\xed\x9d\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xad"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186a8(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a8_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x89";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eab0[] = {
+ "\xea\xb0\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb0\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eab1[] = {
+ "\xea\xb1\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eab2[] = {
+ "\xea\xb2\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eab3[] = {
+ "\xea\xb3\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb3\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eab4[] = {
+ "\xea\xb4\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eab5[] = {
+ "\xea\xb5\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eab6[] = {
+ "\xea\xb6\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eab7[] = {
+ "\xea\xb7\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb7\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eab8[] = {
+ "\xea\xb8\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eab9[] = {
+ "\xea\xb9\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eaba[] = {
+ "\xea\xba\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xba\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eabb[] = {
+ "\xea\xbb\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eabc[] = {
+ "\xea\xbc\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eabd[] = {
+ "\xea\xbd\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eabe[] = {
+ "\xea\xbe\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbe\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eabf[] = {
+ "\xea\xbf\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb80[] = {
+ "\xeb\x80\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb81[] = {
+ "\xeb\x81\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x81\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb82[] = {
+ "\xeb\x82\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb83[] = {
+ "\xeb\x83\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb84[] = {
+ "\xeb\x84\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb85[] = {
+ "\xeb\x85\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x85\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb86[] = {
+ "\xeb\x86\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb87[] = {
+ "\xeb\x87\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb88[] = {
+ "\xeb\x88\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x88\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb89[] = {
+ "\xeb\x89\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb8a[] = {
+ "\xeb\x8a\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb8b[] = {
+ "\xeb\x8b\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb8c[] = {
+ "\xeb\x8c\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8c\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb8d[] = {
+ "\xeb\x8d\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb8e[] = {
+ "\xeb\x8e\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb8f[] = {
+ "\xeb\x8f\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8f\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb90[] = {
+ "\xeb\x90\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb91[] = {
+ "\xeb\x91\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb92[] = {
+ "\xeb\x92\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb93[] = {
+ "\xeb\x93\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x93\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb94[] = {
+ "\xeb\x94\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb95[] = {
+ "\xeb\x95\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb96[] = {
+ "\xeb\x96\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x96\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb97[] = {
+ "\xeb\x97\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb98[] = {
+ "\xeb\x98\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb99[] = {
+ "\xeb\x99\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb9a[] = {
+ "\xeb\x9a\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9a\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb9b[] = {
+ "\xeb\x9b\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb9c[] = {
+ "\xeb\x9c\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb9d[] = {
+ "\xeb\x9d\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9d\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb9e[] = {
+ "\xeb\x9e\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eb9f[] = {
+ "\xeb\x9f\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eba0[] = {
+ "\xeb\xa0\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eba1[] = {
+ "\xeb\xa1\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa1\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eba2[] = {
+ "\xeb\xa2\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eba3[] = {
+ "\xeb\xa3\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eba4[] = {
+ "\xeb\xa4\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa4\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eba5[] = {
+ "\xeb\xa5\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eba6[] = {
+ "\xeb\xa6\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eba7[] = {
+ "\xeb\xa7\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eba8[] = {
+ "\xeb\xa8\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa8\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eba9[] = {
+ "\xeb\xa9\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebaa[] = {
+ "\xeb\xaa\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebab[] = {
+ "\xeb\xab\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xab\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebac[] = {
+ "\xeb\xac\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebad[] = {
+ "\xeb\xad\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebae[] = {
+ "\xeb\xae\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebaf[] = {
+ "\xeb\xaf\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xaf\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebb0[] = {
+ "\xeb\xb0\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebb1[] = {
+ "\xeb\xb1\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebb2[] = {
+ "\xeb\xb2\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb2\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebb3[] = {
+ "\xeb\xb3\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebb4[] = {
+ "\xeb\xb4\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebb5[] = {
+ "\xeb\xb5\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebb6[] = {
+ "\xeb\xb6\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb6\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebb7[] = {
+ "\xeb\xb7\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebb8[] = {
+ "\xeb\xb8\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebb9[] = {
+ "\xeb\xb9\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb9\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebba[] = {
+ "\xeb\xba\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebbb[] = {
+ "\xeb\xbb\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebbc[] = {
+ "\xeb\xbc\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebbd[] = {
+ "\xeb\xbd\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbd\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebbe[] = {
+ "\xeb\xbe\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ebbf[] = {
+ "\xeb\xbf\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec80[] = {
+ "\xec\x80\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x80\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec81[] = {
+ "\xec\x81\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec82[] = {
+ "\xec\x82\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec83[] = {
+ "\xec\x83\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec84[] = {
+ "\xec\x84\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x84\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec85[] = {
+ "\xec\x85\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec86[] = {
+ "\xec\x86\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec87[] = {
+ "\xec\x87\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x87\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec88[] = {
+ "\xec\x88\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec89[] = {
+ "\xec\x89\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec8a[] = {
+ "\xec\x8a\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec8b[] = {
+ "\xec\x8b\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8b\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec8c[] = {
+ "\xec\x8c\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec8d[] = {
+ "\xec\x8d\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec8e[] = {
+ "\xec\x8e\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8e\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec8f[] = {
+ "\xec\x8f\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec90[] = {
+ "\xec\x90\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec91[] = {
+ "\xec\x91\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec92[] = {
+ "\xec\x92\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x92\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec93[] = {
+ "\xec\x93\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec94[] = {
+ "\xec\x94\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec95[] = {
+ "\xec\x95\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x95\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec96[] = {
+ "\xec\x96\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec97[] = {
+ "\xec\x97\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec98[] = {
+ "\xec\x98\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec99[] = {
+ "\xec\x99\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x99\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec9a[] = {
+ "\xec\x9a\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec9b[] = {
+ "\xec\x9b\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec9c[] = {
+ "\xec\x9c\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9c\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec9d[] = {
+ "\xec\x9d\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec9e[] = {
+ "\xec\x9e\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ec9f[] = {
+ "\xec\x9f\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eca0[] = {
+ "\xec\xa0\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa0\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eca1[] = {
+ "\xec\xa1\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eca2[] = {
+ "\xec\xa2\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eca3[] = {
+ "\xec\xa3\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa3\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eca4[] = {
+ "\xec\xa4\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eca5[] = {
+ "\xec\xa5\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eca6[] = {
+ "\xec\xa6\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eca7[] = {
+ "\xec\xa7\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa7\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eca8[] = {
+ "\xec\xa8\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_eca9[] = {
+ "\xec\xa9\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecaa[] = {
+ "\xec\xaa\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaa\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecab[] = {
+ "\xec\xab\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecac[] = {
+ "\xec\xac\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecad[] = {
+ "\xec\xad\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecae[] = {
+ "\xec\xae\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xae\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecaf[] = {
+ "\xec\xaf\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecb0[] = {
+ "\xec\xb0\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecb1[] = {
+ "\xec\xb1\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb1\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecb2[] = {
+ "\xec\xb2\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecb3[] = {
+ "\xec\xb3\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecb4[] = {
+ "\xec\xb4\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecb5[] = {
+ "\xec\xb5\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb5\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecb6[] = {
+ "\xec\xb6\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecb7[] = {
+ "\xec\xb7\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecb8[] = {
+ "\xec\xb8\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb8\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecb9[] = {
+ "\xec\xb9\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecba[] = {
+ "\xec\xba\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecbb[] = {
+ "\xec\xbb\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecbc[] = {
+ "\xec\xbc\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbc\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecbd[] = {
+ "\xec\xbd\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecbe[] = {
+ "\xec\xbe\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ecbf[] = {
+ "\xec\xbf\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbf\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed80[] = {
+ "\xed\x80\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed81[] = {
+ "\xed\x81\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed82[] = {
+ "\xed\x82\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed83[] = {
+ "\xed\x83\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x83\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed84[] = {
+ "\xed\x84\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed85[] = {
+ "\xed\x85\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed86[] = {
+ "\xed\x86\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x86\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed87[] = {
+ "\xed\x87\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed88[] = {
+ "\xed\x88\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed89[] = {
+ "\xed\x89\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed8a[] = {
+ "\xed\x8a\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8a\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed8b[] = {
+ "\xed\x8b\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed8c[] = {
+ "\xed\x8c\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed8d[] = {
+ "\xed\x8d\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8d\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed8e[] = {
+ "\xed\x8e\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed8f[] = {
+ "\xed\x8f\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed90[] = {
+ "\xed\x90\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed91[] = {
+ "\xed\x91\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x91\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed92[] = {
+ "\xed\x92\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed93[] = {
+ "\xed\x93\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed94[] = {
+ "\xed\x94\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x94\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed95[] = {
+ "\xed\x95\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed96[] = {
+ "\xed\x96\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed97[] = {
+ "\xed\x97\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xa6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed98[] = {
+ "\xed\x98\x82", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\x9e", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x98\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed99[] = {
+ "\xed\x99\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed9a[] = {
+ "\xed\x9a\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed9b[] = {
+ "\xed\x9b\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9b\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed9c[] = {
+ "\xed\x9c\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186a9_table_ed9d[] = {
+ "\xed\x9d\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xae"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186a9(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186a9_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x8a";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eab0[] = {
+ "\xea\xb0\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb0\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eab1[] = {
+ "\xea\xb1\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eab2[] = {
+ "\xea\xb2\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eab3[] = {
+ "\xea\xb3\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb3\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eab4[] = {
+ "\xea\xb4\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eab5[] = {
+ "\xea\xb5\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eab6[] = {
+ "\xea\xb6\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eab7[] = {
+ "\xea\xb7\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb7\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eab8[] = {
+ "\xea\xb8\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eab9[] = {
+ "\xea\xb9\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eaba[] = {
+ "\xea\xba\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xba\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eabb[] = {
+ "\xea\xbb\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eabc[] = {
+ "\xea\xbc\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eabd[] = {
+ "\xea\xbd\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eabe[] = {
+ "\xea\xbe\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbe\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eabf[] = {
+ "\xea\xbf\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb80[] = {
+ "\xeb\x80\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb81[] = {
+ "\xeb\x81\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x81\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb82[] = {
+ "\xeb\x82\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb83[] = {
+ "\xeb\x83\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb84[] = {
+ "\xeb\x84\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb85[] = {
+ "\xeb\x85\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x85\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb86[] = {
+ "\xeb\x86\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb87[] = {
+ "\xeb\x87\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb88[] = {
+ "\xeb\x88\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x88\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb89[] = {
+ "\xeb\x89\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb8a[] = {
+ "\xeb\x8a\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb8b[] = {
+ "\xeb\x8b\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb8c[] = {
+ "\xeb\x8c\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8c\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb8d[] = {
+ "\xeb\x8d\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb8e[] = {
+ "\xeb\x8e\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb8f[] = {
+ "\xeb\x8f\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8f\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb90[] = {
+ "\xeb\x90\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb91[] = {
+ "\xeb\x91\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb92[] = {
+ "\xeb\x92\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb93[] = {
+ "\xeb\x93\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x93\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb94[] = {
+ "\xeb\x94\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb95[] = {
+ "\xeb\x95\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb96[] = {
+ "\xeb\x96\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x96\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb97[] = {
+ "\xeb\x97\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb98[] = {
+ "\xeb\x98\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb99[] = {
+ "\xeb\x99\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb9a[] = {
+ "\xeb\x9a\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9a\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb9b[] = {
+ "\xeb\x9b\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb9c[] = {
+ "\xeb\x9c\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb9d[] = {
+ "\xeb\x9d\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9d\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb9e[] = {
+ "\xeb\x9e\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eb9f[] = {
+ "\xeb\x9f\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eba0[] = {
+ "\xeb\xa0\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eba1[] = {
+ "\xeb\xa1\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa1\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eba2[] = {
+ "\xeb\xa2\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eba3[] = {
+ "\xeb\xa3\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eba4[] = {
+ "\xeb\xa4\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa4\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eba5[] = {
+ "\xeb\xa5\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eba6[] = {
+ "\xeb\xa6\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eba7[] = {
+ "\xeb\xa7\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eba8[] = {
+ "\xeb\xa8\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa8\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eba9[] = {
+ "\xeb\xa9\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebaa[] = {
+ "\xeb\xaa\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebab[] = {
+ "\xeb\xab\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xab\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebac[] = {
+ "\xeb\xac\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebad[] = {
+ "\xeb\xad\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebae[] = {
+ "\xeb\xae\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebaf[] = {
+ "\xeb\xaf\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xaf\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebb0[] = {
+ "\xeb\xb0\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebb1[] = {
+ "\xeb\xb1\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebb2[] = {
+ "\xeb\xb2\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb2\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebb3[] = {
+ "\xeb\xb3\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebb4[] = {
+ "\xeb\xb4\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebb5[] = {
+ "\xeb\xb5\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebb6[] = {
+ "\xeb\xb6\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb6\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebb7[] = {
+ "\xeb\xb7\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebb8[] = {
+ "\xeb\xb8\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebb9[] = {
+ "\xeb\xb9\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb9\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebba[] = {
+ "\xeb\xba\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebbb[] = {
+ "\xeb\xbb\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebbc[] = {
+ "\xeb\xbc\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebbd[] = {
+ "\xeb\xbd\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbd\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebbe[] = {
+ "\xeb\xbe\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ebbf[] = {
+ "\xeb\xbf\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec80[] = {
+ "\xec\x80\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x80\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec81[] = {
+ "\xec\x81\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec82[] = {
+ "\xec\x82\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec83[] = {
+ "\xec\x83\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec84[] = {
+ "\xec\x84\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x84\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec85[] = {
+ "\xec\x85\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec86[] = {
+ "\xec\x86\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec87[] = {
+ "\xec\x87\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x87\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec88[] = {
+ "\xec\x88\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec89[] = {
+ "\xec\x89\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec8a[] = {
+ "\xec\x8a\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec8b[] = {
+ "\xec\x8b\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8b\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec8c[] = {
+ "\xec\x8c\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec8d[] = {
+ "\xec\x8d\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec8e[] = {
+ "\xec\x8e\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8e\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec8f[] = {
+ "\xec\x8f\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec90[] = {
+ "\xec\x90\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec91[] = {
+ "\xec\x91\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec92[] = {
+ "\xec\x92\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x92\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec93[] = {
+ "\xec\x93\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec94[] = {
+ "\xec\x94\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec95[] = {
+ "\xec\x95\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x95\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec96[] = {
+ "\xec\x96\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec97[] = {
+ "\xec\x97\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec98[] = {
+ "\xec\x98\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec99[] = {
+ "\xec\x99\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x99\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec9a[] = {
+ "\xec\x9a\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec9b[] = {
+ "\xec\x9b\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec9c[] = {
+ "\xec\x9c\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9c\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec9d[] = {
+ "\xec\x9d\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec9e[] = {
+ "\xec\x9e\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ec9f[] = {
+ "\xec\x9f\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eca0[] = {
+ "\xec\xa0\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa0\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eca1[] = {
+ "\xec\xa1\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eca2[] = {
+ "\xec\xa2\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eca3[] = {
+ "\xec\xa3\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa3\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eca4[] = {
+ "\xec\xa4\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eca5[] = {
+ "\xec\xa5\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eca6[] = {
+ "\xec\xa6\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eca7[] = {
+ "\xec\xa7\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa7\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eca8[] = {
+ "\xec\xa8\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_eca9[] = {
+ "\xec\xa9\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecaa[] = {
+ "\xec\xaa\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaa\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecab[] = {
+ "\xec\xab\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecac[] = {
+ "\xec\xac\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecad[] = {
+ "\xec\xad\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecae[] = {
+ "\xec\xae\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xae\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecaf[] = {
+ "\xec\xaf\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecb0[] = {
+ "\xec\xb0\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecb1[] = {
+ "\xec\xb1\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb1\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecb2[] = {
+ "\xec\xb2\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecb3[] = {
+ "\xec\xb3\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecb4[] = {
+ "\xec\xb4\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecb5[] = {
+ "\xec\xb5\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb5\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecb6[] = {
+ "\xec\xb6\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecb7[] = {
+ "\xec\xb7\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecb8[] = {
+ "\xec\xb8\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb8\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecb9[] = {
+ "\xec\xb9\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecba[] = {
+ "\xec\xba\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecbb[] = {
+ "\xec\xbb\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecbc[] = {
+ "\xec\xbc\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbc\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecbd[] = {
+ "\xec\xbd\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecbe[] = {
+ "\xec\xbe\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ecbf[] = {
+ "\xec\xbf\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbf\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed80[] = {
+ "\xed\x80\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed81[] = {
+ "\xed\x81\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed82[] = {
+ "\xed\x82\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed83[] = {
+ "\xed\x83\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x83\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed84[] = {
+ "\xed\x84\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed85[] = {
+ "\xed\x85\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed86[] = {
+ "\xed\x86\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x86\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed87[] = {
+ "\xed\x87\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed88[] = {
+ "\xed\x88\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed89[] = {
+ "\xed\x89\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed8a[] = {
+ "\xed\x8a\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8a\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed8b[] = {
+ "\xed\x8b\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed8c[] = {
+ "\xed\x8c\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed8d[] = {
+ "\xed\x8d\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8d\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed8e[] = {
+ "\xed\x8e\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed8f[] = {
+ "\xed\x8f\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed90[] = {
+ "\xed\x90\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed91[] = {
+ "\xed\x91\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x91\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed92[] = {
+ "\xed\x92\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed93[] = {
+ "\xed\x93\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed94[] = {
+ "\xed\x94\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x94\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed95[] = {
+ "\xed\x95\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed96[] = {
+ "\xed\x96\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed97[] = {
+ "\xed\x97\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xa7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed98[] = {
+ "\xed\x98\x83", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\x9f", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x98\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed99[] = {
+ "\xed\x99\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed9a[] = {
+ "\xed\x9a\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed9b[] = {
+ "\xed\x9b\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9b\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed9c[] = {
+ "\xed\x9c\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186aa_table_ed9d[] = {
+ "\xed\x9d\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xaf"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186aa(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186aa_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x8b";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eab0[] = {
+ "\xea\xb0\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb0\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eab1[] = {
+ "\xea\xb1\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eab2[] = {
+ "\xea\xb2\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eab3[] = {
+ "\xea\xb3\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eab4[] = {
+ "\xea\xb4\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eab5[] = {
+ "\xea\xb5\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eab6[] = {
+ "\xea\xb6\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eab7[] = {
+ "\xea\xb7\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb7\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eab8[] = {
+ "\xea\xb8\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eab9[] = {
+ "\xea\xb9\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eaba[] = {
+ "\xea\xba\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eabb[] = {
+ "\xea\xbb\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eabc[] = {
+ "\xea\xbc\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eabd[] = {
+ "\xea\xbd\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eabe[] = {
+ "\xea\xbe\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbe\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eabf[] = {
+ "\xea\xbf\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb80[] = {
+ "\xeb\x80\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb81[] = {
+ "\xeb\x81\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb82[] = {
+ "\xeb\x82\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb83[] = {
+ "\xeb\x83\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb84[] = {
+ "\xeb\x84\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb85[] = {
+ "\xeb\x85\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x85\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb86[] = {
+ "\xeb\x86\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb87[] = {
+ "\xeb\x87\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb88[] = {
+ "\xeb\x88\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb89[] = {
+ "\xeb\x89\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb8a[] = {
+ "\xeb\x8a\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb8b[] = {
+ "\xeb\x8b\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb8c[] = {
+ "\xeb\x8c\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8c\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb8d[] = {
+ "\xeb\x8d\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb8e[] = {
+ "\xeb\x8e\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb8f[] = {
+ "\xeb\x8f\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb90[] = {
+ "\xeb\x90\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb91[] = {
+ "\xeb\x91\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb92[] = {
+ "\xeb\x92\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb93[] = {
+ "\xeb\x93\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x93\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb94[] = {
+ "\xeb\x94\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb95[] = {
+ "\xeb\x95\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb96[] = {
+ "\xeb\x96\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb97[] = {
+ "\xeb\x97\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb98[] = {
+ "\xeb\x98\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb99[] = {
+ "\xeb\x99\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb9a[] = {
+ "\xeb\x9a\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9a\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb9b[] = {
+ "\xeb\x9b\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb9c[] = {
+ "\xeb\x9c\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb9d[] = {
+ "\xeb\x9d\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb9e[] = {
+ "\xeb\x9e\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eb9f[] = {
+ "\xeb\x9f\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eba0[] = {
+ "\xeb\xa0\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eba1[] = {
+ "\xeb\xa1\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa1\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eba2[] = {
+ "\xeb\xa2\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eba3[] = {
+ "\xeb\xa3\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eba4[] = {
+ "\xeb\xa4\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eba5[] = {
+ "\xeb\xa5\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eba6[] = {
+ "\xeb\xa6\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eba7[] = {
+ "\xeb\xa7\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eba8[] = {
+ "\xeb\xa8\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa8\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eba9[] = {
+ "\xeb\xa9\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebaa[] = {
+ "\xeb\xaa\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebab[] = {
+ "\xeb\xab\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebac[] = {
+ "\xeb\xac\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebad[] = {
+ "\xeb\xad\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebae[] = {
+ "\xeb\xae\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebaf[] = {
+ "\xeb\xaf\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xaf\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebb0[] = {
+ "\xeb\xb0\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebb1[] = {
+ "\xeb\xb1\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebb2[] = {
+ "\xeb\xb2\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebb3[] = {
+ "\xeb\xb3\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebb4[] = {
+ "\xeb\xb4\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebb5[] = {
+ "\xeb\xb5\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebb6[] = {
+ "\xeb\xb6\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb6\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebb7[] = {
+ "\xeb\xb7\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebb8[] = {
+ "\xeb\xb8\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebb9[] = {
+ "\xeb\xb9\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebba[] = {
+ "\xeb\xba\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebbb[] = {
+ "\xeb\xbb\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebbc[] = {
+ "\xeb\xbc\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebbd[] = {
+ "\xeb\xbd\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbd\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebbe[] = {
+ "\xeb\xbe\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ebbf[] = {
+ "\xeb\xbf\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec80[] = {
+ "\xec\x80\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec81[] = {
+ "\xec\x81\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec82[] = {
+ "\xec\x82\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec83[] = {
+ "\xec\x83\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec84[] = {
+ "\xec\x84\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x84\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec85[] = {
+ "\xec\x85\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec86[] = {
+ "\xec\x86\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec87[] = {
+ "\xec\x87\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec88[] = {
+ "\xec\x88\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec89[] = {
+ "\xec\x89\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec8a[] = {
+ "\xec\x8a\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec8b[] = {
+ "\xec\x8b\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8b\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec8c[] = {
+ "\xec\x8c\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec8d[] = {
+ "\xec\x8d\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec8e[] = {
+ "\xec\x8e\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec8f[] = {
+ "\xec\x8f\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec90[] = {
+ "\xec\x90\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec91[] = {
+ "\xec\x91\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec92[] = {
+ "\xec\x92\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x92\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec93[] = {
+ "\xec\x93\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec94[] = {
+ "\xec\x94\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec95[] = {
+ "\xec\x95\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec96[] = {
+ "\xec\x96\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec97[] = {
+ "\xec\x97\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec98[] = {
+ "\xec\x98\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec99[] = {
+ "\xec\x99\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x99\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec9a[] = {
+ "\xec\x9a\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec9b[] = {
+ "\xec\x9b\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec9c[] = {
+ "\xec\x9c\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec9d[] = {
+ "\xec\x9d\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec9e[] = {
+ "\xec\x9e\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ec9f[] = {
+ "\xec\x9f\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eca0[] = {
+ "\xec\xa0\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa0\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eca1[] = {
+ "\xec\xa1\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eca2[] = {
+ "\xec\xa2\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eca3[] = {
+ "\xec\xa3\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eca4[] = {
+ "\xec\xa4\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eca5[] = {
+ "\xec\xa5\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eca6[] = {
+ "\xec\xa6\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eca7[] = {
+ "\xec\xa7\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa7\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eca8[] = {
+ "\xec\xa8\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_eca9[] = {
+ "\xec\xa9\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecaa[] = {
+ "\xec\xaa\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecab[] = {
+ "\xec\xab\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecac[] = {
+ "\xec\xac\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecad[] = {
+ "\xec\xad\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecae[] = {
+ "\xec\xae\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xae\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecaf[] = {
+ "\xec\xaf\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecb0[] = {
+ "\xec\xb0\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecb1[] = {
+ "\xec\xb1\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecb2[] = {
+ "\xec\xb2\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecb3[] = {
+ "\xec\xb3\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecb4[] = {
+ "\xec\xb4\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecb5[] = {
+ "\xec\xb5\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb5\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecb6[] = {
+ "\xec\xb6\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecb7[] = {
+ "\xec\xb7\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecb8[] = {
+ "\xec\xb8\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecb9[] = {
+ "\xec\xb9\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecba[] = {
+ "\xec\xba\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecbb[] = {
+ "\xec\xbb\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecbc[] = {
+ "\xec\xbc\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbc\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecbd[] = {
+ "\xec\xbd\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecbe[] = {
+ "\xec\xbe\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ecbf[] = {
+ "\xec\xbf\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed80[] = {
+ "\xed\x80\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed81[] = {
+ "\xed\x81\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed82[] = {
+ "\xed\x82\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed83[] = {
+ "\xed\x83\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x83\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed84[] = {
+ "\xed\x84\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed85[] = {
+ "\xed\x85\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed86[] = {
+ "\xed\x86\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed87[] = {
+ "\xed\x87\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed88[] = {
+ "\xed\x88\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed89[] = {
+ "\xed\x89\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed8a[] = {
+ "\xed\x8a\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8a\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed8b[] = {
+ "\xed\x8b\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed8c[] = {
+ "\xed\x8c\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed8d[] = {
+ "\xed\x8d\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed8e[] = {
+ "\xed\x8e\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed8f[] = {
+ "\xed\x8f\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed90[] = {
+ "\xed\x90\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed91[] = {
+ "\xed\x91\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x91\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed92[] = {
+ "\xed\x92\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed93[] = {
+ "\xed\x93\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed94[] = {
+ "\xed\x94\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed95[] = {
+ "\xed\x95\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed96[] = {
+ "\xed\x96\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed97[] = {
+ "\xed\x97\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xa8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed98[] = {
+ "\xed\x98\x84", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xa0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x98\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed99[] = {
+ "\xed\x99\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed9a[] = {
+ "\xed\x9a\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed9b[] = {
+ "\xed\x9b\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed9c[] = {
+ "\xed\x9c\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ab_table_ed9d[] = {
+ "\xed\x9d\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xb0"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186ab(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ab_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x8c";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eab0[] = {
+ "\xea\xb0\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb0\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eab1[] = {
+ "\xea\xb1\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eab2[] = {
+ "\xea\xb2\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eab3[] = {
+ "\xea\xb3\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eab4[] = {
+ "\xea\xb4\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eab5[] = {
+ "\xea\xb5\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eab6[] = {
+ "\xea\xb6\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eab7[] = {
+ "\xea\xb7\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb7\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eab8[] = {
+ "\xea\xb8\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eab9[] = {
+ "\xea\xb9\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eaba[] = {
+ "\xea\xba\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eabb[] = {
+ "\xea\xbb\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eabc[] = {
+ "\xea\xbc\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eabd[] = {
+ "\xea\xbd\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eabe[] = {
+ "\xea\xbe\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbe\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eabf[] = {
+ "\xea\xbf\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb80[] = {
+ "\xeb\x80\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb81[] = {
+ "\xeb\x81\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb82[] = {
+ "\xeb\x82\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb83[] = {
+ "\xeb\x83\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb84[] = {
+ "\xeb\x84\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb85[] = {
+ "\xeb\x85\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x85\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb86[] = {
+ "\xeb\x86\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb87[] = {
+ "\xeb\x87\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb88[] = {
+ "\xeb\x88\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb89[] = {
+ "\xeb\x89\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb8a[] = {
+ "\xeb\x8a\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb8b[] = {
+ "\xeb\x8b\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb8c[] = {
+ "\xeb\x8c\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8c\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb8d[] = {
+ "\xeb\x8d\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb8e[] = {
+ "\xeb\x8e\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb8f[] = {
+ "\xeb\x8f\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb90[] = {
+ "\xeb\x90\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb91[] = {
+ "\xeb\x91\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb92[] = {
+ "\xeb\x92\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb93[] = {
+ "\xeb\x93\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x93\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb94[] = {
+ "\xeb\x94\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb95[] = {
+ "\xeb\x95\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb96[] = {
+ "\xeb\x96\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb97[] = {
+ "\xeb\x97\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb98[] = {
+ "\xeb\x98\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb99[] = {
+ "\xeb\x99\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb9a[] = {
+ "\xeb\x9a\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9a\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb9b[] = {
+ "\xeb\x9b\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb9c[] = {
+ "\xeb\x9c\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb9d[] = {
+ "\xeb\x9d\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb9e[] = {
+ "\xeb\x9e\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eb9f[] = {
+ "\xeb\x9f\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eba0[] = {
+ "\xeb\xa0\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eba1[] = {
+ "\xeb\xa1\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa1\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eba2[] = {
+ "\xeb\xa2\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eba3[] = {
+ "\xeb\xa3\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eba4[] = {
+ "\xeb\xa4\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eba5[] = {
+ "\xeb\xa5\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eba6[] = {
+ "\xeb\xa6\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eba7[] = {
+ "\xeb\xa7\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eba8[] = {
+ "\xeb\xa8\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa8\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eba9[] = {
+ "\xeb\xa9\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebaa[] = {
+ "\xeb\xaa\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebab[] = {
+ "\xeb\xab\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebac[] = {
+ "\xeb\xac\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebad[] = {
+ "\xeb\xad\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebae[] = {
+ "\xeb\xae\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebaf[] = {
+ "\xeb\xaf\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xaf\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebb0[] = {
+ "\xeb\xb0\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebb1[] = {
+ "\xeb\xb1\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebb2[] = {
+ "\xeb\xb2\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebb3[] = {
+ "\xeb\xb3\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebb4[] = {
+ "\xeb\xb4\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebb5[] = {
+ "\xeb\xb5\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebb6[] = {
+ "\xeb\xb6\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb6\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebb7[] = {
+ "\xeb\xb7\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebb8[] = {
+ "\xeb\xb8\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebb9[] = {
+ "\xeb\xb9\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebba[] = {
+ "\xeb\xba\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebbb[] = {
+ "\xeb\xbb\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebbc[] = {
+ "\xeb\xbc\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebbd[] = {
+ "\xeb\xbd\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbd\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebbe[] = {
+ "\xeb\xbe\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ebbf[] = {
+ "\xeb\xbf\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec80[] = {
+ "\xec\x80\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec81[] = {
+ "\xec\x81\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec82[] = {
+ "\xec\x82\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec83[] = {
+ "\xec\x83\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec84[] = {
+ "\xec\x84\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x84\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec85[] = {
+ "\xec\x85\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec86[] = {
+ "\xec\x86\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec87[] = {
+ "\xec\x87\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec88[] = {
+ "\xec\x88\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec89[] = {
+ "\xec\x89\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec8a[] = {
+ "\xec\x8a\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec8b[] = {
+ "\xec\x8b\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8b\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec8c[] = {
+ "\xec\x8c\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec8d[] = {
+ "\xec\x8d\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec8e[] = {
+ "\xec\x8e\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec8f[] = {
+ "\xec\x8f\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec90[] = {
+ "\xec\x90\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec91[] = {
+ "\xec\x91\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec92[] = {
+ "\xec\x92\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x92\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec93[] = {
+ "\xec\x93\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec94[] = {
+ "\xec\x94\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec95[] = {
+ "\xec\x95\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec96[] = {
+ "\xec\x96\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec97[] = {
+ "\xec\x97\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec98[] = {
+ "\xec\x98\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec99[] = {
+ "\xec\x99\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x99\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec9a[] = {
+ "\xec\x9a\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec9b[] = {
+ "\xec\x9b\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec9c[] = {
+ "\xec\x9c\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec9d[] = {
+ "\xec\x9d\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec9e[] = {
+ "\xec\x9e\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ec9f[] = {
+ "\xec\x9f\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eca0[] = {
+ "\xec\xa0\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa0\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eca1[] = {
+ "\xec\xa1\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eca2[] = {
+ "\xec\xa2\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eca3[] = {
+ "\xec\xa3\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eca4[] = {
+ "\xec\xa4\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eca5[] = {
+ "\xec\xa5\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eca6[] = {
+ "\xec\xa6\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eca7[] = {
+ "\xec\xa7\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa7\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eca8[] = {
+ "\xec\xa8\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_eca9[] = {
+ "\xec\xa9\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecaa[] = {
+ "\xec\xaa\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecab[] = {
+ "\xec\xab\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecac[] = {
+ "\xec\xac\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecad[] = {
+ "\xec\xad\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecae[] = {
+ "\xec\xae\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xae\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecaf[] = {
+ "\xec\xaf\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecb0[] = {
+ "\xec\xb0\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecb1[] = {
+ "\xec\xb1\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecb2[] = {
+ "\xec\xb2\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecb3[] = {
+ "\xec\xb3\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecb4[] = {
+ "\xec\xb4\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecb5[] = {
+ "\xec\xb5\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb5\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecb6[] = {
+ "\xec\xb6\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecb7[] = {
+ "\xec\xb7\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecb8[] = {
+ "\xec\xb8\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecb9[] = {
+ "\xec\xb9\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecba[] = {
+ "\xec\xba\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecbb[] = {
+ "\xec\xbb\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecbc[] = {
+ "\xec\xbc\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbc\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecbd[] = {
+ "\xec\xbd\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecbe[] = {
+ "\xec\xbe\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ecbf[] = {
+ "\xec\xbf\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed80[] = {
+ "\xed\x80\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed81[] = {
+ "\xed\x81\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed82[] = {
+ "\xed\x82\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed83[] = {
+ "\xed\x83\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x83\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed84[] = {
+ "\xed\x84\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed85[] = {
+ "\xed\x85\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed86[] = {
+ "\xed\x86\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed87[] = {
+ "\xed\x87\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed88[] = {
+ "\xed\x88\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed89[] = {
+ "\xed\x89\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed8a[] = {
+ "\xed\x8a\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8a\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed8b[] = {
+ "\xed\x8b\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed8c[] = {
+ "\xed\x8c\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed8d[] = {
+ "\xed\x8d\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed8e[] = {
+ "\xed\x8e\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed8f[] = {
+ "\xed\x8f\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed90[] = {
+ "\xed\x90\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed91[] = {
+ "\xed\x91\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x91\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed92[] = {
+ "\xed\x92\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed93[] = {
+ "\xed\x93\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed94[] = {
+ "\xed\x94\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed95[] = {
+ "\xed\x95\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed96[] = {
+ "\xed\x96\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed97[] = {
+ "\xed\x97\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xa9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed98[] = {
+ "\xed\x98\x85", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xa1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x98\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed99[] = {
+ "\xed\x99\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed9a[] = {
+ "\xed\x9a\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed9b[] = {
+ "\xed\x9b\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed9c[] = {
+ "\xed\x9c\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ac_table_ed9d[] = {
+ "\xed\x9d\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xb1"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186ac(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ac_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x8d";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eab0[] = {
+ "\xea\xb0\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb0\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eab1[] = {
+ "\xea\xb1\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eab2[] = {
+ "\xea\xb2\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eab3[] = {
+ "\xea\xb3\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eab4[] = {
+ "\xea\xb4\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eab5[] = {
+ "\xea\xb5\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eab6[] = {
+ "\xea\xb6\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eab7[] = {
+ "\xea\xb7\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb7\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eab8[] = {
+ "\xea\xb8\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eab9[] = {
+ "\xea\xb9\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eaba[] = {
+ "\xea\xba\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eabb[] = {
+ "\xea\xbb\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eabc[] = {
+ "\xea\xbc\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eabd[] = {
+ "\xea\xbd\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eabe[] = {
+ "\xea\xbe\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbe\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eabf[] = {
+ "\xea\xbf\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb80[] = {
+ "\xeb\x80\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb81[] = {
+ "\xeb\x81\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb82[] = {
+ "\xeb\x82\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb83[] = {
+ "\xeb\x83\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb84[] = {
+ "\xeb\x84\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb85[] = {
+ "\xeb\x85\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x85\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb86[] = {
+ "\xeb\x86\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb87[] = {
+ "\xeb\x87\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb88[] = {
+ "\xeb\x88\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb89[] = {
+ "\xeb\x89\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb8a[] = {
+ "\xeb\x8a\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb8b[] = {
+ "\xeb\x8b\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb8c[] = {
+ "\xeb\x8c\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8c\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb8d[] = {
+ "\xeb\x8d\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb8e[] = {
+ "\xeb\x8e\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb8f[] = {
+ "\xeb\x8f\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb90[] = {
+ "\xeb\x90\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb91[] = {
+ "\xeb\x91\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb92[] = {
+ "\xeb\x92\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb93[] = {
+ "\xeb\x93\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x93\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb94[] = {
+ "\xeb\x94\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb95[] = {
+ "\xeb\x95\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb96[] = {
+ "\xeb\x96\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb97[] = {
+ "\xeb\x97\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb98[] = {
+ "\xeb\x98\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb99[] = {
+ "\xeb\x99\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb9a[] = {
+ "\xeb\x9a\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9a\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb9b[] = {
+ "\xeb\x9b\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb9c[] = {
+ "\xeb\x9c\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb9d[] = {
+ "\xeb\x9d\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb9e[] = {
+ "\xeb\x9e\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eb9f[] = {
+ "\xeb\x9f\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eba0[] = {
+ "\xeb\xa0\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eba1[] = {
+ "\xeb\xa1\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa1\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eba2[] = {
+ "\xeb\xa2\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eba3[] = {
+ "\xeb\xa3\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eba4[] = {
+ "\xeb\xa4\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eba5[] = {
+ "\xeb\xa5\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eba6[] = {
+ "\xeb\xa6\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eba7[] = {
+ "\xeb\xa7\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eba8[] = {
+ "\xeb\xa8\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa8\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eba9[] = {
+ "\xeb\xa9\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebaa[] = {
+ "\xeb\xaa\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebab[] = {
+ "\xeb\xab\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebac[] = {
+ "\xeb\xac\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebad[] = {
+ "\xeb\xad\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebae[] = {
+ "\xeb\xae\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebaf[] = {
+ "\xeb\xaf\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xaf\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebb0[] = {
+ "\xeb\xb0\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebb1[] = {
+ "\xeb\xb1\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebb2[] = {
+ "\xeb\xb2\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebb3[] = {
+ "\xeb\xb3\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebb4[] = {
+ "\xeb\xb4\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebb5[] = {
+ "\xeb\xb5\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebb6[] = {
+ "\xeb\xb6\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb6\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebb7[] = {
+ "\xeb\xb7\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebb8[] = {
+ "\xeb\xb8\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebb9[] = {
+ "\xeb\xb9\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebba[] = {
+ "\xeb\xba\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebbb[] = {
+ "\xeb\xbb\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebbc[] = {
+ "\xeb\xbc\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebbd[] = {
+ "\xeb\xbd\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbd\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebbe[] = {
+ "\xeb\xbe\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ebbf[] = {
+ "\xeb\xbf\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec80[] = {
+ "\xec\x80\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec81[] = {
+ "\xec\x81\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec82[] = {
+ "\xec\x82\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec83[] = {
+ "\xec\x83\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec84[] = {
+ "\xec\x84\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x84\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec85[] = {
+ "\xec\x85\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec86[] = {
+ "\xec\x86\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec87[] = {
+ "\xec\x87\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec88[] = {
+ "\xec\x88\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec89[] = {
+ "\xec\x89\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec8a[] = {
+ "\xec\x8a\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec8b[] = {
+ "\xec\x8b\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8b\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec8c[] = {
+ "\xec\x8c\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec8d[] = {
+ "\xec\x8d\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec8e[] = {
+ "\xec\x8e\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec8f[] = {
+ "\xec\x8f\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec90[] = {
+ "\xec\x90\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec91[] = {
+ "\xec\x91\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec92[] = {
+ "\xec\x92\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x92\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec93[] = {
+ "\xec\x93\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec94[] = {
+ "\xec\x94\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec95[] = {
+ "\xec\x95\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec96[] = {
+ "\xec\x96\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec97[] = {
+ "\xec\x97\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec98[] = {
+ "\xec\x98\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec99[] = {
+ "\xec\x99\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x99\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec9a[] = {
+ "\xec\x9a\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec9b[] = {
+ "\xec\x9b\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec9c[] = {
+ "\xec\x9c\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec9d[] = {
+ "\xec\x9d\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec9e[] = {
+ "\xec\x9e\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ec9f[] = {
+ "\xec\x9f\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eca0[] = {
+ "\xec\xa0\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa0\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eca1[] = {
+ "\xec\xa1\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eca2[] = {
+ "\xec\xa2\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eca3[] = {
+ "\xec\xa3\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eca4[] = {
+ "\xec\xa4\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eca5[] = {
+ "\xec\xa5\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eca6[] = {
+ "\xec\xa6\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eca7[] = {
+ "\xec\xa7\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa7\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eca8[] = {
+ "\xec\xa8\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_eca9[] = {
+ "\xec\xa9\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecaa[] = {
+ "\xec\xaa\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecab[] = {
+ "\xec\xab\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecac[] = {
+ "\xec\xac\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecad[] = {
+ "\xec\xad\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecae[] = {
+ "\xec\xae\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xae\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecaf[] = {
+ "\xec\xaf\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecb0[] = {
+ "\xec\xb0\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecb1[] = {
+ "\xec\xb1\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecb2[] = {
+ "\xec\xb2\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecb3[] = {
+ "\xec\xb3\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecb4[] = {
+ "\xec\xb4\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecb5[] = {
+ "\xec\xb5\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb5\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecb6[] = {
+ "\xec\xb6\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecb7[] = {
+ "\xec\xb7\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecb8[] = {
+ "\xec\xb8\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecb9[] = {
+ "\xec\xb9\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecba[] = {
+ "\xec\xba\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecbb[] = {
+ "\xec\xbb\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecbc[] = {
+ "\xec\xbc\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbc\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecbd[] = {
+ "\xec\xbd\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecbe[] = {
+ "\xec\xbe\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ecbf[] = {
+ "\xec\xbf\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed80[] = {
+ "\xed\x80\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed81[] = {
+ "\xed\x81\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed82[] = {
+ "\xed\x82\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed83[] = {
+ "\xed\x83\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x83\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed84[] = {
+ "\xed\x84\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed85[] = {
+ "\xed\x85\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed86[] = {
+ "\xed\x86\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed87[] = {
+ "\xed\x87\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed88[] = {
+ "\xed\x88\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed89[] = {
+ "\xed\x89\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed8a[] = {
+ "\xed\x8a\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8a\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed8b[] = {
+ "\xed\x8b\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed8c[] = {
+ "\xed\x8c\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed8d[] = {
+ "\xed\x8d\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed8e[] = {
+ "\xed\x8e\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed8f[] = {
+ "\xed\x8f\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed90[] = {
+ "\xed\x90\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed91[] = {
+ "\xed\x91\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x91\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed92[] = {
+ "\xed\x92\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed93[] = {
+ "\xed\x93\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed94[] = {
+ "\xed\x94\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed95[] = {
+ "\xed\x95\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed96[] = {
+ "\xed\x96\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed97[] = {
+ "\xed\x97\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xaa"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed98[] = {
+ "\xed\x98\x86", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xa2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x98\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed99[] = {
+ "\xed\x99\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed9a[] = {
+ "\xed\x9a\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed9b[] = {
+ "\xed\x9b\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed9c[] = {
+ "\xed\x9c\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ad_table_ed9d[] = {
+ "\xed\x9d\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xb2"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186ad(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ad_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x8e";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eab0[] = {
+ "\xea\xb0\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb0\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eab1[] = {
+ "\xea\xb1\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eab2[] = {
+ "\xea\xb2\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eab3[] = {
+ "\xea\xb3\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eab4[] = {
+ "\xea\xb4\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eab5[] = {
+ "\xea\xb5\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eab6[] = {
+ "\xea\xb6\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eab7[] = {
+ "\xea\xb7\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb7\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eab8[] = {
+ "\xea\xb8\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eab9[] = {
+ "\xea\xb9\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eaba[] = {
+ "\xea\xba\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eabb[] = {
+ "\xea\xbb\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eabc[] = {
+ "\xea\xbc\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eabd[] = {
+ "\xea\xbd\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eabe[] = {
+ "\xea\xbe\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbe\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eabf[] = {
+ "\xea\xbf\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb80[] = {
+ "\xeb\x80\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb81[] = {
+ "\xeb\x81\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb82[] = {
+ "\xeb\x82\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb83[] = {
+ "\xeb\x83\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb84[] = {
+ "\xeb\x84\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb85[] = {
+ "\xeb\x85\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x85\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb86[] = {
+ "\xeb\x86\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb87[] = {
+ "\xeb\x87\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb88[] = {
+ "\xeb\x88\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb89[] = {
+ "\xeb\x89\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb8a[] = {
+ "\xeb\x8a\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb8b[] = {
+ "\xeb\x8b\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb8c[] = {
+ "\xeb\x8c\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8c\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb8d[] = {
+ "\xeb\x8d\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb8e[] = {
+ "\xeb\x8e\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb8f[] = {
+ "\xeb\x8f\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb90[] = {
+ "\xeb\x90\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb91[] = {
+ "\xeb\x91\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb92[] = {
+ "\xeb\x92\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb93[] = {
+ "\xeb\x93\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x93\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb94[] = {
+ "\xeb\x94\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb95[] = {
+ "\xeb\x95\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb96[] = {
+ "\xeb\x96\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb97[] = {
+ "\xeb\x97\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb98[] = {
+ "\xeb\x98\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb99[] = {
+ "\xeb\x99\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb9a[] = {
+ "\xeb\x9a\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9a\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb9b[] = {
+ "\xeb\x9b\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb9c[] = {
+ "\xeb\x9c\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb9d[] = {
+ "\xeb\x9d\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb9e[] = {
+ "\xeb\x9e\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eb9f[] = {
+ "\xeb\x9f\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eba0[] = {
+ "\xeb\xa0\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eba1[] = {
+ "\xeb\xa1\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa1\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eba2[] = {
+ "\xeb\xa2\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eba3[] = {
+ "\xeb\xa3\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eba4[] = {
+ "\xeb\xa4\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eba5[] = {
+ "\xeb\xa5\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eba6[] = {
+ "\xeb\xa6\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eba7[] = {
+ "\xeb\xa7\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eba8[] = {
+ "\xeb\xa8\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa8\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eba9[] = {
+ "\xeb\xa9\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebaa[] = {
+ "\xeb\xaa\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebab[] = {
+ "\xeb\xab\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebac[] = {
+ "\xeb\xac\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebad[] = {
+ "\xeb\xad\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebae[] = {
+ "\xeb\xae\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebaf[] = {
+ "\xeb\xaf\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xaf\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebb0[] = {
+ "\xeb\xb0\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebb1[] = {
+ "\xeb\xb1\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebb2[] = {
+ "\xeb\xb2\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebb3[] = {
+ "\xeb\xb3\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebb4[] = {
+ "\xeb\xb4\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebb5[] = {
+ "\xeb\xb5\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebb6[] = {
+ "\xeb\xb6\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb6\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebb7[] = {
+ "\xeb\xb7\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebb8[] = {
+ "\xeb\xb8\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebb9[] = {
+ "\xeb\xb9\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebba[] = {
+ "\xeb\xba\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebbb[] = {
+ "\xeb\xbb\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebbc[] = {
+ "\xeb\xbc\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebbd[] = {
+ "\xeb\xbd\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbd\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebbe[] = {
+ "\xeb\xbe\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ebbf[] = {
+ "\xeb\xbf\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec80[] = {
+ "\xec\x80\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec81[] = {
+ "\xec\x81\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec82[] = {
+ "\xec\x82\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec83[] = {
+ "\xec\x83\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec84[] = {
+ "\xec\x84\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x84\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec85[] = {
+ "\xec\x85\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec86[] = {
+ "\xec\x86\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec87[] = {
+ "\xec\x87\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec88[] = {
+ "\xec\x88\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec89[] = {
+ "\xec\x89\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec8a[] = {
+ "\xec\x8a\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec8b[] = {
+ "\xec\x8b\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8b\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec8c[] = {
+ "\xec\x8c\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec8d[] = {
+ "\xec\x8d\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec8e[] = {
+ "\xec\x8e\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec8f[] = {
+ "\xec\x8f\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec90[] = {
+ "\xec\x90\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec91[] = {
+ "\xec\x91\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec92[] = {
+ "\xec\x92\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x92\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec93[] = {
+ "\xec\x93\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec94[] = {
+ "\xec\x94\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec95[] = {
+ "\xec\x95\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec96[] = {
+ "\xec\x96\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec97[] = {
+ "\xec\x97\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec98[] = {
+ "\xec\x98\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec99[] = {
+ "\xec\x99\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x99\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec9a[] = {
+ "\xec\x9a\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec9b[] = {
+ "\xec\x9b\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec9c[] = {
+ "\xec\x9c\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec9d[] = {
+ "\xec\x9d\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec9e[] = {
+ "\xec\x9e\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ec9f[] = {
+ "\xec\x9f\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eca0[] = {
+ "\xec\xa0\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa0\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eca1[] = {
+ "\xec\xa1\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eca2[] = {
+ "\xec\xa2\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eca3[] = {
+ "\xec\xa3\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eca4[] = {
+ "\xec\xa4\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eca5[] = {
+ "\xec\xa5\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eca6[] = {
+ "\xec\xa6\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eca7[] = {
+ "\xec\xa7\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa7\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eca8[] = {
+ "\xec\xa8\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_eca9[] = {
+ "\xec\xa9\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecaa[] = {
+ "\xec\xaa\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecab[] = {
+ "\xec\xab\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecac[] = {
+ "\xec\xac\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecad[] = {
+ "\xec\xad\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecae[] = {
+ "\xec\xae\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xae\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecaf[] = {
+ "\xec\xaf\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecb0[] = {
+ "\xec\xb0\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecb1[] = {
+ "\xec\xb1\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecb2[] = {
+ "\xec\xb2\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecb3[] = {
+ "\xec\xb3\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecb4[] = {
+ "\xec\xb4\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecb5[] = {
+ "\xec\xb5\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb5\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecb6[] = {
+ "\xec\xb6\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecb7[] = {
+ "\xec\xb7\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecb8[] = {
+ "\xec\xb8\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecb9[] = {
+ "\xec\xb9\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecba[] = {
+ "\xec\xba\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecbb[] = {
+ "\xec\xbb\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecbc[] = {
+ "\xec\xbc\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbc\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecbd[] = {
+ "\xec\xbd\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecbe[] = {
+ "\xec\xbe\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ecbf[] = {
+ "\xec\xbf\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed80[] = {
+ "\xed\x80\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed81[] = {
+ "\xed\x81\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed82[] = {
+ "\xed\x82\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed83[] = {
+ "\xed\x83\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x83\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed84[] = {
+ "\xed\x84\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed85[] = {
+ "\xed\x85\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed86[] = {
+ "\xed\x86\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed87[] = {
+ "\xed\x87\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed88[] = {
+ "\xed\x88\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed89[] = {
+ "\xed\x89\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed8a[] = {
+ "\xed\x8a\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8a\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed8b[] = {
+ "\xed\x8b\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed8c[] = {
+ "\xed\x8c\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed8d[] = {
+ "\xed\x8d\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed8e[] = {
+ "\xed\x8e\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed8f[] = {
+ "\xed\x8f\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed90[] = {
+ "\xed\x90\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed91[] = {
+ "\xed\x91\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x91\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed92[] = {
+ "\xed\x92\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed93[] = {
+ "\xed\x93\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed94[] = {
+ "\xed\x94\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed95[] = {
+ "\xed\x95\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed96[] = {
+ "\xed\x96\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed97[] = {
+ "\xed\x97\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xab"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed98[] = {
+ "\xed\x98\x87", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xa3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x98\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed99[] = {
+ "\xed\x99\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed9a[] = {
+ "\xed\x9a\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed9b[] = {
+ "\xed\x9b\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed9c[] = {
+ "\xed\x9c\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ae_table_ed9d[] = {
+ "\xed\x9d\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xb3"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186ae(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ae_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x8f";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eab0[] = {
+ "\xea\xb0\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eab1[] = {
+ "\xea\xb1\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eab2[] = {
+ "\xea\xb2\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eab3[] = {
+ "\xea\xb3\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eab4[] = {
+ "\xea\xb4\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eab5[] = {
+ "\xea\xb5\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eab6[] = {
+ "\xea\xb6\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eab7[] = {
+ "\xea\xb7\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eab8[] = {
+ "\xea\xb8\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eab9[] = {
+ "\xea\xb9\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eaba[] = {
+ "\xea\xba\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eabb[] = {
+ "\xea\xbb\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eabc[] = {
+ "\xea\xbc\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eabd[] = {
+ "\xea\xbd\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eabe[] = {
+ "\xea\xbe\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eabf[] = {
+ "\xea\xbf\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb80[] = {
+ "\xeb\x80\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb81[] = {
+ "\xeb\x81\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb82[] = {
+ "\xeb\x82\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb83[] = {
+ "\xeb\x83\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb84[] = {
+ "\xeb\x84\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb85[] = {
+ "\xeb\x85\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb86[] = {
+ "\xeb\x86\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb87[] = {
+ "\xeb\x87\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb88[] = {
+ "\xeb\x88\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb89[] = {
+ "\xeb\x89\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb8a[] = {
+ "\xeb\x8a\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb8b[] = {
+ "\xeb\x8b\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb8c[] = {
+ "\xeb\x8c\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb8d[] = {
+ "\xeb\x8d\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb8e[] = {
+ "\xeb\x8e\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb8f[] = {
+ "\xeb\x8f\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb90[] = {
+ "\xeb\x90\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb91[] = {
+ "\xeb\x91\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb92[] = {
+ "\xeb\x92\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb93[] = {
+ "\xeb\x93\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb94[] = {
+ "\xeb\x94\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb95[] = {
+ "\xeb\x95\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb96[] = {
+ "\xeb\x96\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb97[] = {
+ "\xeb\x97\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb98[] = {
+ "\xeb\x98\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb99[] = {
+ "\xeb\x99\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb9a[] = {
+ "\xeb\x9a\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb9b[] = {
+ "\xeb\x9b\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb9c[] = {
+ "\xeb\x9c\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb9d[] = {
+ "\xeb\x9d\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb9e[] = {
+ "\xeb\x9e\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eb9f[] = {
+ "\xeb\x9f\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eba0[] = {
+ "\xeb\xa0\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eba1[] = {
+ "\xeb\xa1\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eba2[] = {
+ "\xeb\xa2\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eba3[] = {
+ "\xeb\xa3\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eba4[] = {
+ "\xeb\xa4\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eba5[] = {
+ "\xeb\xa5\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eba6[] = {
+ "\xeb\xa6\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eba7[] = {
+ "\xeb\xa7\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eba8[] = {
+ "\xeb\xa8\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eba9[] = {
+ "\xeb\xa9\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebaa[] = {
+ "\xeb\xaa\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebab[] = {
+ "\xeb\xab\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebac[] = {
+ "\xeb\xac\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebad[] = {
+ "\xeb\xad\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebae[] = {
+ "\xeb\xae\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebaf[] = {
+ "\xeb\xaf\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebb0[] = {
+ "\xeb\xb0\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebb1[] = {
+ "\xeb\xb1\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebb2[] = {
+ "\xeb\xb2\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebb3[] = {
+ "\xeb\xb3\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebb4[] = {
+ "\xeb\xb4\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebb5[] = {
+ "\xeb\xb5\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebb6[] = {
+ "\xeb\xb6\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebb7[] = {
+ "\xeb\xb7\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebb8[] = {
+ "\xeb\xb8\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebb9[] = {
+ "\xeb\xb9\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebba[] = {
+ "\xeb\xba\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebbb[] = {
+ "\xeb\xbb\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebbc[] = {
+ "\xeb\xbc\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebbd[] = {
+ "\xeb\xbd\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebbe[] = {
+ "\xeb\xbe\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ebbf[] = {
+ "\xeb\xbf\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec80[] = {
+ "\xec\x80\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec81[] = {
+ "\xec\x81\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec82[] = {
+ "\xec\x82\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec83[] = {
+ "\xec\x83\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec84[] = {
+ "\xec\x84\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec85[] = {
+ "\xec\x85\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec86[] = {
+ "\xec\x86\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec87[] = {
+ "\xec\x87\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec88[] = {
+ "\xec\x88\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec89[] = {
+ "\xec\x89\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec8a[] = {
+ "\xec\x8a\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec8b[] = {
+ "\xec\x8b\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec8c[] = {
+ "\xec\x8c\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec8d[] = {
+ "\xec\x8d\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec8e[] = {
+ "\xec\x8e\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec8f[] = {
+ "\xec\x8f\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec90[] = {
+ "\xec\x90\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec91[] = {
+ "\xec\x91\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec92[] = {
+ "\xec\x92\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec93[] = {
+ "\xec\x93\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec94[] = {
+ "\xec\x94\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec95[] = {
+ "\xec\x95\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec96[] = {
+ "\xec\x96\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec97[] = {
+ "\xec\x97\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec98[] = {
+ "\xec\x98\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec99[] = {
+ "\xec\x99\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec9a[] = {
+ "\xec\x9a\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec9b[] = {
+ "\xec\x9b\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec9c[] = {
+ "\xec\x9c\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec9d[] = {
+ "\xec\x9d\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec9e[] = {
+ "\xec\x9e\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ec9f[] = {
+ "\xec\x9f\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eca0[] = {
+ "\xec\xa0\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eca1[] = {
+ "\xec\xa1\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eca2[] = {
+ "\xec\xa2\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eca3[] = {
+ "\xec\xa3\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eca4[] = {
+ "\xec\xa4\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eca5[] = {
+ "\xec\xa5\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eca6[] = {
+ "\xec\xa6\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eca7[] = {
+ "\xec\xa7\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eca8[] = {
+ "\xec\xa8\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_eca9[] = {
+ "\xec\xa9\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecaa[] = {
+ "\xec\xaa\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecab[] = {
+ "\xec\xab\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecac[] = {
+ "\xec\xac\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecad[] = {
+ "\xec\xad\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecae[] = {
+ "\xec\xae\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecaf[] = {
+ "\xec\xaf\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecb0[] = {
+ "\xec\xb0\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecb1[] = {
+ "\xec\xb1\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecb2[] = {
+ "\xec\xb2\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecb3[] = {
+ "\xec\xb3\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecb4[] = {
+ "\xec\xb4\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecb5[] = {
+ "\xec\xb5\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecb6[] = {
+ "\xec\xb6\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecb7[] = {
+ "\xec\xb7\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecb8[] = {
+ "\xec\xb8\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecb9[] = {
+ "\xec\xb9\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecba[] = {
+ "\xec\xba\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecbb[] = {
+ "\xec\xbb\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecbc[] = {
+ "\xec\xbc\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecbd[] = {
+ "\xec\xbd\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecbe[] = {
+ "\xec\xbe\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ecbf[] = {
+ "\xec\xbf\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed80[] = {
+ "\xed\x80\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed81[] = {
+ "\xed\x81\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed82[] = {
+ "\xed\x82\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed83[] = {
+ "\xed\x83\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed84[] = {
+ "\xed\x84\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed85[] = {
+ "\xed\x85\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed86[] = {
+ "\xed\x86\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed87[] = {
+ "\xed\x87\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed88[] = {
+ "\xed\x88\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed89[] = {
+ "\xed\x89\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed8a[] = {
+ "\xed\x8a\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed8b[] = {
+ "\xed\x8b\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed8c[] = {
+ "\xed\x8c\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed8d[] = {
+ "\xed\x8d\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed8e[] = {
+ "\xed\x8e\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed8f[] = {
+ "\xed\x8f\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed90[] = {
+ "\xed\x90\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed91[] = {
+ "\xed\x91\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed92[] = {
+ "\xed\x92\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed93[] = {
+ "\xed\x93\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed94[] = {
+ "\xed\x94\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed95[] = {
+ "\xed\x95\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed96[] = {
+ "\xed\x96\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed97[] = {
+ "\xed\x97\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xac"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed98[] = {
+ "\xed\x98\x88", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xa4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed99[] = {
+ "\xed\x99\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed9a[] = {
+ "\xed\x9a\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed9b[] = {
+ "\xed\x9b\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed9c[] = {
+ "\xed\x9c\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186af_table_ed9d[] = {
+ "\xed\x9d\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xb4"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186af(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186af_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x90";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eab0[] = {
+ "\xea\xb0\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eab1[] = {
+ "\xea\xb1\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eab2[] = {
+ "\xea\xb2\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eab3[] = {
+ "\xea\xb3\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eab4[] = {
+ "\xea\xb4\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eab5[] = {
+ "\xea\xb5\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eab6[] = {
+ "\xea\xb6\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eab7[] = {
+ "\xea\xb7\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eab8[] = {
+ "\xea\xb8\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eab9[] = {
+ "\xea\xb9\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eaba[] = {
+ "\xea\xba\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eabb[] = {
+ "\xea\xbb\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eabc[] = {
+ "\xea\xbc\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eabd[] = {
+ "\xea\xbd\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eabe[] = {
+ "\xea\xbe\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eabf[] = {
+ "\xea\xbf\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb80[] = {
+ "\xeb\x80\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb81[] = {
+ "\xeb\x81\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb82[] = {
+ "\xeb\x82\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb83[] = {
+ "\xeb\x83\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb84[] = {
+ "\xeb\x84\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb85[] = {
+ "\xeb\x85\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb86[] = {
+ "\xeb\x86\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb87[] = {
+ "\xeb\x87\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb88[] = {
+ "\xeb\x88\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb89[] = {
+ "\xeb\x89\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb8a[] = {
+ "\xeb\x8a\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb8b[] = {
+ "\xeb\x8b\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb8c[] = {
+ "\xeb\x8c\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb8d[] = {
+ "\xeb\x8d\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb8e[] = {
+ "\xeb\x8e\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb8f[] = {
+ "\xeb\x8f\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb90[] = {
+ "\xeb\x90\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb91[] = {
+ "\xeb\x91\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb92[] = {
+ "\xeb\x92\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb93[] = {
+ "\xeb\x93\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb94[] = {
+ "\xeb\x94\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb95[] = {
+ "\xeb\x95\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb96[] = {
+ "\xeb\x96\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb97[] = {
+ "\xeb\x97\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb98[] = {
+ "\xeb\x98\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb99[] = {
+ "\xeb\x99\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb9a[] = {
+ "\xeb\x9a\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb9b[] = {
+ "\xeb\x9b\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb9c[] = {
+ "\xeb\x9c\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb9d[] = {
+ "\xeb\x9d\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb9e[] = {
+ "\xeb\x9e\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eb9f[] = {
+ "\xeb\x9f\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eba0[] = {
+ "\xeb\xa0\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eba1[] = {
+ "\xeb\xa1\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eba2[] = {
+ "\xeb\xa2\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eba3[] = {
+ "\xeb\xa3\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eba4[] = {
+ "\xeb\xa4\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eba5[] = {
+ "\xeb\xa5\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eba6[] = {
+ "\xeb\xa6\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eba7[] = {
+ "\xeb\xa7\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eba8[] = {
+ "\xeb\xa8\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eba9[] = {
+ "\xeb\xa9\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebaa[] = {
+ "\xeb\xaa\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebab[] = {
+ "\xeb\xab\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebac[] = {
+ "\xeb\xac\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebad[] = {
+ "\xeb\xad\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebae[] = {
+ "\xeb\xae\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebaf[] = {
+ "\xeb\xaf\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebb0[] = {
+ "\xeb\xb0\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebb1[] = {
+ "\xeb\xb1\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebb2[] = {
+ "\xeb\xb2\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebb3[] = {
+ "\xeb\xb3\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebb4[] = {
+ "\xeb\xb4\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebb5[] = {
+ "\xeb\xb5\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebb6[] = {
+ "\xeb\xb6\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebb7[] = {
+ "\xeb\xb7\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebb8[] = {
+ "\xeb\xb8\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebb9[] = {
+ "\xeb\xb9\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebba[] = {
+ "\xeb\xba\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebbb[] = {
+ "\xeb\xbb\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebbc[] = {
+ "\xeb\xbc\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebbd[] = {
+ "\xeb\xbd\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebbe[] = {
+ "\xeb\xbe\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ebbf[] = {
+ "\xeb\xbf\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec80[] = {
+ "\xec\x80\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec81[] = {
+ "\xec\x81\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec82[] = {
+ "\xec\x82\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec83[] = {
+ "\xec\x83\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec84[] = {
+ "\xec\x84\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec85[] = {
+ "\xec\x85\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec86[] = {
+ "\xec\x86\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec87[] = {
+ "\xec\x87\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec88[] = {
+ "\xec\x88\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec89[] = {
+ "\xec\x89\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec8a[] = {
+ "\xec\x8a\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec8b[] = {
+ "\xec\x8b\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec8c[] = {
+ "\xec\x8c\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec8d[] = {
+ "\xec\x8d\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec8e[] = {
+ "\xec\x8e\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec8f[] = {
+ "\xec\x8f\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec90[] = {
+ "\xec\x90\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec91[] = {
+ "\xec\x91\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec92[] = {
+ "\xec\x92\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec93[] = {
+ "\xec\x93\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec94[] = {
+ "\xec\x94\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec95[] = {
+ "\xec\x95\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec96[] = {
+ "\xec\x96\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec97[] = {
+ "\xec\x97\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec98[] = {
+ "\xec\x98\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec99[] = {
+ "\xec\x99\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec9a[] = {
+ "\xec\x9a\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec9b[] = {
+ "\xec\x9b\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec9c[] = {
+ "\xec\x9c\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec9d[] = {
+ "\xec\x9d\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec9e[] = {
+ "\xec\x9e\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ec9f[] = {
+ "\xec\x9f\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eca0[] = {
+ "\xec\xa0\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eca1[] = {
+ "\xec\xa1\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eca2[] = {
+ "\xec\xa2\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eca3[] = {
+ "\xec\xa3\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eca4[] = {
+ "\xec\xa4\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eca5[] = {
+ "\xec\xa5\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eca6[] = {
+ "\xec\xa6\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eca7[] = {
+ "\xec\xa7\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eca8[] = {
+ "\xec\xa8\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_eca9[] = {
+ "\xec\xa9\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecaa[] = {
+ "\xec\xaa\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecab[] = {
+ "\xec\xab\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecac[] = {
+ "\xec\xac\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecad[] = {
+ "\xec\xad\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecae[] = {
+ "\xec\xae\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecaf[] = {
+ "\xec\xaf\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecb0[] = {
+ "\xec\xb0\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecb1[] = {
+ "\xec\xb1\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecb2[] = {
+ "\xec\xb2\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecb3[] = {
+ "\xec\xb3\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecb4[] = {
+ "\xec\xb4\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecb5[] = {
+ "\xec\xb5\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecb6[] = {
+ "\xec\xb6\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecb7[] = {
+ "\xec\xb7\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecb8[] = {
+ "\xec\xb8\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecb9[] = {
+ "\xec\xb9\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecba[] = {
+ "\xec\xba\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecbb[] = {
+ "\xec\xbb\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecbc[] = {
+ "\xec\xbc\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecbd[] = {
+ "\xec\xbd\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecbe[] = {
+ "\xec\xbe\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ecbf[] = {
+ "\xec\xbf\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed80[] = {
+ "\xed\x80\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed81[] = {
+ "\xed\x81\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed82[] = {
+ "\xed\x82\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed83[] = {
+ "\xed\x83\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed84[] = {
+ "\xed\x84\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed85[] = {
+ "\xed\x85\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed86[] = {
+ "\xed\x86\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed87[] = {
+ "\xed\x87\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed88[] = {
+ "\xed\x88\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed89[] = {
+ "\xed\x89\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed8a[] = {
+ "\xed\x8a\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed8b[] = {
+ "\xed\x8b\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed8c[] = {
+ "\xed\x8c\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed8d[] = {
+ "\xed\x8d\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed8e[] = {
+ "\xed\x8e\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed8f[] = {
+ "\xed\x8f\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed90[] = {
+ "\xed\x90\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed91[] = {
+ "\xed\x91\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed92[] = {
+ "\xed\x92\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed93[] = {
+ "\xed\x93\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed94[] = {
+ "\xed\x94\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed95[] = {
+ "\xed\x95\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed96[] = {
+ "\xed\x96\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed97[] = {
+ "\xed\x97\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xad"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed98[] = {
+ "\xed\x98\x89", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xa5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed99[] = {
+ "\xed\x99\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed9a[] = {
+ "\xed\x9a\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed9b[] = {
+ "\xed\x9b\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed9c[] = {
+ "\xed\x9c\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b0_table_ed9d[] = {
+ "\xed\x9d\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xb5"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186b0(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b0_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x91";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eab0[] = {
+ "\xea\xb0\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eab1[] = {
+ "\xea\xb1\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eab2[] = {
+ "\xea\xb2\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eab3[] = {
+ "\xea\xb3\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eab4[] = {
+ "\xea\xb4\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eab5[] = {
+ "\xea\xb5\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eab6[] = {
+ "\xea\xb6\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eab7[] = {
+ "\xea\xb7\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eab8[] = {
+ "\xea\xb8\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eab9[] = {
+ "\xea\xb9\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eaba[] = {
+ "\xea\xba\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eabb[] = {
+ "\xea\xbb\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eabc[] = {
+ "\xea\xbc\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eabd[] = {
+ "\xea\xbd\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eabe[] = {
+ "\xea\xbe\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eabf[] = {
+ "\xea\xbf\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb80[] = {
+ "\xeb\x80\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb81[] = {
+ "\xeb\x81\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb82[] = {
+ "\xeb\x82\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb83[] = {
+ "\xeb\x83\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb84[] = {
+ "\xeb\x84\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb85[] = {
+ "\xeb\x85\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb86[] = {
+ "\xeb\x86\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb87[] = {
+ "\xeb\x87\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb88[] = {
+ "\xeb\x88\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb89[] = {
+ "\xeb\x89\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb8a[] = {
+ "\xeb\x8a\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb8b[] = {
+ "\xeb\x8b\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb8c[] = {
+ "\xeb\x8c\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb8d[] = {
+ "\xeb\x8d\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb8e[] = {
+ "\xeb\x8e\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb8f[] = {
+ "\xeb\x8f\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb90[] = {
+ "\xeb\x90\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb91[] = {
+ "\xeb\x91\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb92[] = {
+ "\xeb\x92\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb93[] = {
+ "\xeb\x93\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb94[] = {
+ "\xeb\x94\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb95[] = {
+ "\xeb\x95\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb96[] = {
+ "\xeb\x96\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb97[] = {
+ "\xeb\x97\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb98[] = {
+ "\xeb\x98\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb99[] = {
+ "\xeb\x99\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb9a[] = {
+ "\xeb\x9a\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb9b[] = {
+ "\xeb\x9b\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb9c[] = {
+ "\xeb\x9c\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb9d[] = {
+ "\xeb\x9d\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb9e[] = {
+ "\xeb\x9e\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eb9f[] = {
+ "\xeb\x9f\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eba0[] = {
+ "\xeb\xa0\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eba1[] = {
+ "\xeb\xa1\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eba2[] = {
+ "\xeb\xa2\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eba3[] = {
+ "\xeb\xa3\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eba4[] = {
+ "\xeb\xa4\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eba5[] = {
+ "\xeb\xa5\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eba6[] = {
+ "\xeb\xa6\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eba7[] = {
+ "\xeb\xa7\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eba8[] = {
+ "\xeb\xa8\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eba9[] = {
+ "\xeb\xa9\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebaa[] = {
+ "\xeb\xaa\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebab[] = {
+ "\xeb\xab\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebac[] = {
+ "\xeb\xac\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebad[] = {
+ "\xeb\xad\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebae[] = {
+ "\xeb\xae\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebaf[] = {
+ "\xeb\xaf\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebb0[] = {
+ "\xeb\xb0\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebb1[] = {
+ "\xeb\xb1\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebb2[] = {
+ "\xeb\xb2\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebb3[] = {
+ "\xeb\xb3\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebb4[] = {
+ "\xeb\xb4\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebb5[] = {
+ "\xeb\xb5\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebb6[] = {
+ "\xeb\xb6\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebb7[] = {
+ "\xeb\xb7\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebb8[] = {
+ "\xeb\xb8\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebb9[] = {
+ "\xeb\xb9\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebba[] = {
+ "\xeb\xba\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebbb[] = {
+ "\xeb\xbb\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebbc[] = {
+ "\xeb\xbc\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebbd[] = {
+ "\xeb\xbd\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebbe[] = {
+ "\xeb\xbe\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ebbf[] = {
+ "\xeb\xbf\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec80[] = {
+ "\xec\x80\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec81[] = {
+ "\xec\x81\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec82[] = {
+ "\xec\x82\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec83[] = {
+ "\xec\x83\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec84[] = {
+ "\xec\x84\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec85[] = {
+ "\xec\x85\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec86[] = {
+ "\xec\x86\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec87[] = {
+ "\xec\x87\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec88[] = {
+ "\xec\x88\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec89[] = {
+ "\xec\x89\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec8a[] = {
+ "\xec\x8a\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec8b[] = {
+ "\xec\x8b\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec8c[] = {
+ "\xec\x8c\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec8d[] = {
+ "\xec\x8d\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec8e[] = {
+ "\xec\x8e\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec8f[] = {
+ "\xec\x8f\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec90[] = {
+ "\xec\x90\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec91[] = {
+ "\xec\x91\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec92[] = {
+ "\xec\x92\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec93[] = {
+ "\xec\x93\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec94[] = {
+ "\xec\x94\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec95[] = {
+ "\xec\x95\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec96[] = {
+ "\xec\x96\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec97[] = {
+ "\xec\x97\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec98[] = {
+ "\xec\x98\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec99[] = {
+ "\xec\x99\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec9a[] = {
+ "\xec\x9a\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec9b[] = {
+ "\xec\x9b\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec9c[] = {
+ "\xec\x9c\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec9d[] = {
+ "\xec\x9d\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec9e[] = {
+ "\xec\x9e\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ec9f[] = {
+ "\xec\x9f\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eca0[] = {
+ "\xec\xa0\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eca1[] = {
+ "\xec\xa1\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eca2[] = {
+ "\xec\xa2\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eca3[] = {
+ "\xec\xa3\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eca4[] = {
+ "\xec\xa4\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eca5[] = {
+ "\xec\xa5\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eca6[] = {
+ "\xec\xa6\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eca7[] = {
+ "\xec\xa7\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eca8[] = {
+ "\xec\xa8\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_eca9[] = {
+ "\xec\xa9\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecaa[] = {
+ "\xec\xaa\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecab[] = {
+ "\xec\xab\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecac[] = {
+ "\xec\xac\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecad[] = {
+ "\xec\xad\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecae[] = {
+ "\xec\xae\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecaf[] = {
+ "\xec\xaf\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecb0[] = {
+ "\xec\xb0\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecb1[] = {
+ "\xec\xb1\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecb2[] = {
+ "\xec\xb2\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecb3[] = {
+ "\xec\xb3\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecb4[] = {
+ "\xec\xb4\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecb5[] = {
+ "\xec\xb5\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecb6[] = {
+ "\xec\xb6\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecb7[] = {
+ "\xec\xb7\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecb8[] = {
+ "\xec\xb8\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecb9[] = {
+ "\xec\xb9\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecba[] = {
+ "\xec\xba\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecbb[] = {
+ "\xec\xbb\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecbc[] = {
+ "\xec\xbc\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecbd[] = {
+ "\xec\xbd\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecbe[] = {
+ "\xec\xbe\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ecbf[] = {
+ "\xec\xbf\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed80[] = {
+ "\xed\x80\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed81[] = {
+ "\xed\x81\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed82[] = {
+ "\xed\x82\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed83[] = {
+ "\xed\x83\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed84[] = {
+ "\xed\x84\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed85[] = {
+ "\xed\x85\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed86[] = {
+ "\xed\x86\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed87[] = {
+ "\xed\x87\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed88[] = {
+ "\xed\x88\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed89[] = {
+ "\xed\x89\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed8a[] = {
+ "\xed\x8a\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed8b[] = {
+ "\xed\x8b\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed8c[] = {
+ "\xed\x8c\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed8d[] = {
+ "\xed\x8d\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed8e[] = {
+ "\xed\x8e\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed8f[] = {
+ "\xed\x8f\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed90[] = {
+ "\xed\x90\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed91[] = {
+ "\xed\x91\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed92[] = {
+ "\xed\x92\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed93[] = {
+ "\xed\x93\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed94[] = {
+ "\xed\x94\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed95[] = {
+ "\xed\x95\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed96[] = {
+ "\xed\x96\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed97[] = {
+ "\xed\x97\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xae"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed98[] = {
+ "\xed\x98\x8a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xa6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed99[] = {
+ "\xed\x99\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed9a[] = {
+ "\xed\x9a\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed9b[] = {
+ "\xed\x9b\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed9c[] = {
+ "\xed\x9c\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b1_table_ed9d[] = {
+ "\xed\x9d\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xb6"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186b1(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b1_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x92";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eab0[] = {
+ "\xea\xb0\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eab1[] = {
+ "\xea\xb1\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eab2[] = {
+ "\xea\xb2\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eab3[] = {
+ "\xea\xb3\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eab4[] = {
+ "\xea\xb4\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb4\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eab5[] = {
+ "\xea\xb5\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eab6[] = {
+ "\xea\xb6\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eab7[] = {
+ "\xea\xb7\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eab8[] = {
+ "\xea\xb8\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eab9[] = {
+ "\xea\xb9\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eaba[] = {
+ "\xea\xba\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eabb[] = {
+ "\xea\xbb\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbb\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eabc[] = {
+ "\xea\xbc\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eabd[] = {
+ "\xea\xbd\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eabe[] = {
+ "\xea\xbe\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eabf[] = {
+ "\xea\xbf\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb80[] = {
+ "\xeb\x80\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb81[] = {
+ "\xeb\x81\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb82[] = {
+ "\xeb\x82\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x82\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb83[] = {
+ "\xeb\x83\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb84[] = {
+ "\xeb\x84\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb85[] = {
+ "\xeb\x85\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb86[] = {
+ "\xeb\x86\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb87[] = {
+ "\xeb\x87\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb88[] = {
+ "\xeb\x88\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb89[] = {
+ "\xeb\x89\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x89\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb8a[] = {
+ "\xeb\x8a\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb8b[] = {
+ "\xeb\x8b\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb8c[] = {
+ "\xeb\x8c\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb8d[] = {
+ "\xeb\x8d\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb8e[] = {
+ "\xeb\x8e\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb8f[] = {
+ "\xeb\x8f\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb90[] = {
+ "\xeb\x90\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x90\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb91[] = {
+ "\xeb\x91\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb92[] = {
+ "\xeb\x92\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb93[] = {
+ "\xeb\x93\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb94[] = {
+ "\xeb\x94\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb95[] = {
+ "\xeb\x95\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb96[] = {
+ "\xeb\x96\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb97[] = {
+ "\xeb\x97\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x97\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb98[] = {
+ "\xeb\x98\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb99[] = {
+ "\xeb\x99\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb9a[] = {
+ "\xeb\x9a\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb9b[] = {
+ "\xeb\x9b\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb9c[] = {
+ "\xeb\x9c\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb9d[] = {
+ "\xeb\x9d\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb9e[] = {
+ "\xeb\x9e\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9e\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eb9f[] = {
+ "\xeb\x9f\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eba0[] = {
+ "\xeb\xa0\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eba1[] = {
+ "\xeb\xa1\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eba2[] = {
+ "\xeb\xa2\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eba3[] = {
+ "\xeb\xa3\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eba4[] = {
+ "\xeb\xa4\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eba5[] = {
+ "\xeb\xa5\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa5\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eba6[] = {
+ "\xeb\xa6\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eba7[] = {
+ "\xeb\xa7\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eba8[] = {
+ "\xeb\xa8\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eba9[] = {
+ "\xeb\xa9\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebaa[] = {
+ "\xeb\xaa\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebab[] = {
+ "\xeb\xab\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebac[] = {
+ "\xeb\xac\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xac\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebad[] = {
+ "\xeb\xad\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebae[] = {
+ "\xeb\xae\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebaf[] = {
+ "\xeb\xaf\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebb0[] = {
+ "\xeb\xb0\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebb1[] = {
+ "\xeb\xb1\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebb2[] = {
+ "\xeb\xb2\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebb3[] = {
+ "\xeb\xb3\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb3\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebb4[] = {
+ "\xeb\xb4\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebb5[] = {
+ "\xeb\xb5\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebb6[] = {
+ "\xeb\xb6\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebb7[] = {
+ "\xeb\xb7\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebb8[] = {
+ "\xeb\xb8\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebb9[] = {
+ "\xeb\xb9\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebba[] = {
+ "\xeb\xba\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xba\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebbb[] = {
+ "\xeb\xbb\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebbc[] = {
+ "\xeb\xbc\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebbd[] = {
+ "\xeb\xbd\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebbe[] = {
+ "\xeb\xbe\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ebbf[] = {
+ "\xeb\xbf\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec80[] = {
+ "\xec\x80\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec81[] = {
+ "\xec\x81\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x81\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec82[] = {
+ "\xec\x82\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec83[] = {
+ "\xec\x83\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec84[] = {
+ "\xec\x84\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec85[] = {
+ "\xec\x85\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec86[] = {
+ "\xec\x86\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec87[] = {
+ "\xec\x87\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec88[] = {
+ "\xec\x88\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x88\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec89[] = {
+ "\xec\x89\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec8a[] = {
+ "\xec\x8a\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec8b[] = {
+ "\xec\x8b\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec8c[] = {
+ "\xec\x8c\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec8d[] = {
+ "\xec\x8d\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec8e[] = {
+ "\xec\x8e\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec8f[] = {
+ "\xec\x8f\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8f\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec90[] = {
+ "\xec\x90\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec91[] = {
+ "\xec\x91\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec92[] = {
+ "\xec\x92\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec93[] = {
+ "\xec\x93\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec94[] = {
+ "\xec\x94\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec95[] = {
+ "\xec\x95\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec96[] = {
+ "\xec\x96\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x96\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec97[] = {
+ "\xec\x97\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec98[] = {
+ "\xec\x98\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec99[] = {
+ "\xec\x99\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec9a[] = {
+ "\xec\x9a\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec9b[] = {
+ "\xec\x9b\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec9c[] = {
+ "\xec\x9c\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec9d[] = {
+ "\xec\x9d\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9d\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec9e[] = {
+ "\xec\x9e\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ec9f[] = {
+ "\xec\x9f\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eca0[] = {
+ "\xec\xa0\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eca1[] = {
+ "\xec\xa1\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eca2[] = {
+ "\xec\xa2\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eca3[] = {
+ "\xec\xa3\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eca4[] = {
+ "\xec\xa4\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa4\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eca5[] = {
+ "\xec\xa5\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eca6[] = {
+ "\xec\xa6\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eca7[] = {
+ "\xec\xa7\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eca8[] = {
+ "\xec\xa8\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_eca9[] = {
+ "\xec\xa9\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecaa[] = {
+ "\xec\xaa\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecab[] = {
+ "\xec\xab\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xab\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecac[] = {
+ "\xec\xac\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecad[] = {
+ "\xec\xad\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecae[] = {
+ "\xec\xae\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecaf[] = {
+ "\xec\xaf\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecb0[] = {
+ "\xec\xb0\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecb1[] = {
+ "\xec\xb1\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecb2[] = {
+ "\xec\xb2\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb2\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecb3[] = {
+ "\xec\xb3\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecb4[] = {
+ "\xec\xb4\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecb5[] = {
+ "\xec\xb5\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecb6[] = {
+ "\xec\xb6\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecb7[] = {
+ "\xec\xb7\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecb8[] = {
+ "\xec\xb8\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecb9[] = {
+ "\xec\xb9\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb9\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecba[] = {
+ "\xec\xba\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecbb[] = {
+ "\xec\xbb\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecbc[] = {
+ "\xec\xbc\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecbd[] = {
+ "\xec\xbd\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecbe[] = {
+ "\xec\xbe\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ecbf[] = {
+ "\xec\xbf\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed80[] = {
+ "\xed\x80\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x80\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed81[] = {
+ "\xed\x81\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed82[] = {
+ "\xed\x82\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed83[] = {
+ "\xed\x83\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed84[] = {
+ "\xed\x84\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed85[] = {
+ "\xed\x85\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed86[] = {
+ "\xed\x86\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed87[] = {
+ "\xed\x87\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x87\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed88[] = {
+ "\xed\x88\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed89[] = {
+ "\xed\x89\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed8a[] = {
+ "\xed\x8a\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed8b[] = {
+ "\xed\x8b\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed8c[] = {
+ "\xed\x8c\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed8d[] = {
+ "\xed\x8d\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed8e[] = {
+ "\xed\x8e\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8e\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed8f[] = {
+ "\xed\x8f\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed90[] = {
+ "\xed\x90\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed91[] = {
+ "\xed\x91\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed92[] = {
+ "\xed\x92\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed93[] = {
+ "\xed\x93\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed94[] = {
+ "\xed\x94\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed95[] = {
+ "\xed\x95\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x95\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed96[] = {
+ "\xed\x96\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed97[] = {
+ "\xed\x97\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xaf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed98[] = {
+ "\xed\x98\x8b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xa7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed99[] = {
+ "\xed\x99\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed9a[] = {
+ "\xed\x9a\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed9b[] = {
+ "\xed\x9b\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed9c[] = {
+ "\xed\x9c\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9c\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b2_table_ed9d[] = {
+ "\xed\x9d\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xb7"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186b2(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b2_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x93";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eab0[] = {
+ "\xea\xb0\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eab1[] = {
+ "\xea\xb1\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eab2[] = {
+ "\xea\xb2\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eab3[] = {
+ "\xea\xb3\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eab4[] = {
+ "\xea\xb4\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eab5[] = {
+ "\xea\xb5\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eab6[] = {
+ "\xea\xb6\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eab7[] = {
+ "\xea\xb7\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eab8[] = {
+ "\xea\xb8\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eab9[] = {
+ "\xea\xb9\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eaba[] = {
+ "\xea\xba\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eabb[] = {
+ "\xea\xbb\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eabc[] = {
+ "\xea\xbc\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eabd[] = {
+ "\xea\xbd\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eabe[] = {
+ "\xea\xbe\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eabf[] = {
+ "\xea\xbf\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb80[] = {
+ "\xeb\x80\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb81[] = {
+ "\xeb\x81\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb82[] = {
+ "\xeb\x82\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb83[] = {
+ "\xeb\x83\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb84[] = {
+ "\xeb\x84\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb85[] = {
+ "\xeb\x85\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb86[] = {
+ "\xeb\x86\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb87[] = {
+ "\xeb\x87\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb88[] = {
+ "\xeb\x88\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb89[] = {
+ "\xeb\x89\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb8a[] = {
+ "\xeb\x8a\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb8b[] = {
+ "\xeb\x8b\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb8c[] = {
+ "\xeb\x8c\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb8d[] = {
+ "\xeb\x8d\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb8e[] = {
+ "\xeb\x8e\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb8f[] = {
+ "\xeb\x8f\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb90[] = {
+ "\xeb\x90\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb91[] = {
+ "\xeb\x91\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb92[] = {
+ "\xeb\x92\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb93[] = {
+ "\xeb\x93\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb94[] = {
+ "\xeb\x94\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb95[] = {
+ "\xeb\x95\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb96[] = {
+ "\xeb\x96\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb97[] = {
+ "\xeb\x97\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb98[] = {
+ "\xeb\x98\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb99[] = {
+ "\xeb\x99\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb9a[] = {
+ "\xeb\x9a\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb9b[] = {
+ "\xeb\x9b\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb9c[] = {
+ "\xeb\x9c\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb9d[] = {
+ "\xeb\x9d\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb9e[] = {
+ "\xeb\x9e\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eb9f[] = {
+ "\xeb\x9f\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eba0[] = {
+ "\xeb\xa0\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eba1[] = {
+ "\xeb\xa1\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eba2[] = {
+ "\xeb\xa2\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eba3[] = {
+ "\xeb\xa3\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eba4[] = {
+ "\xeb\xa4\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eba5[] = {
+ "\xeb\xa5\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eba6[] = {
+ "\xeb\xa6\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eba7[] = {
+ "\xeb\xa7\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eba8[] = {
+ "\xeb\xa8\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eba9[] = {
+ "\xeb\xa9\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebaa[] = {
+ "\xeb\xaa\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebab[] = {
+ "\xeb\xab\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebac[] = {
+ "\xeb\xac\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebad[] = {
+ "\xeb\xad\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebae[] = {
+ "\xeb\xae\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebaf[] = {
+ "\xeb\xaf\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebb0[] = {
+ "\xeb\xb0\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebb1[] = {
+ "\xeb\xb1\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebb2[] = {
+ "\xeb\xb2\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebb3[] = {
+ "\xeb\xb3\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebb4[] = {
+ "\xeb\xb4\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebb5[] = {
+ "\xeb\xb5\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebb6[] = {
+ "\xeb\xb6\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebb7[] = {
+ "\xeb\xb7\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebb8[] = {
+ "\xeb\xb8\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebb9[] = {
+ "\xeb\xb9\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebba[] = {
+ "\xeb\xba\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebbb[] = {
+ "\xeb\xbb\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebbc[] = {
+ "\xeb\xbc\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebbd[] = {
+ "\xeb\xbd\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebbe[] = {
+ "\xeb\xbe\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ebbf[] = {
+ "\xeb\xbf\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec80[] = {
+ "\xec\x80\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec81[] = {
+ "\xec\x81\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec82[] = {
+ "\xec\x82\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec83[] = {
+ "\xec\x83\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec84[] = {
+ "\xec\x84\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec85[] = {
+ "\xec\x85\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec86[] = {
+ "\xec\x86\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec87[] = {
+ "\xec\x87\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec88[] = {
+ "\xec\x88\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec89[] = {
+ "\xec\x89\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec8a[] = {
+ "\xec\x8a\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec8b[] = {
+ "\xec\x8b\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec8c[] = {
+ "\xec\x8c\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec8d[] = {
+ "\xec\x8d\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec8e[] = {
+ "\xec\x8e\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec8f[] = {
+ "\xec\x8f\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec90[] = {
+ "\xec\x90\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec91[] = {
+ "\xec\x91\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec92[] = {
+ "\xec\x92\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec93[] = {
+ "\xec\x93\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec94[] = {
+ "\xec\x94\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec95[] = {
+ "\xec\x95\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec96[] = {
+ "\xec\x96\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec97[] = {
+ "\xec\x97\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec98[] = {
+ "\xec\x98\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec99[] = {
+ "\xec\x99\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec9a[] = {
+ "\xec\x9a\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec9b[] = {
+ "\xec\x9b\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec9c[] = {
+ "\xec\x9c\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec9d[] = {
+ "\xec\x9d\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec9e[] = {
+ "\xec\x9e\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ec9f[] = {
+ "\xec\x9f\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eca0[] = {
+ "\xec\xa0\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eca1[] = {
+ "\xec\xa1\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eca2[] = {
+ "\xec\xa2\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eca3[] = {
+ "\xec\xa3\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eca4[] = {
+ "\xec\xa4\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eca5[] = {
+ "\xec\xa5\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eca6[] = {
+ "\xec\xa6\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eca7[] = {
+ "\xec\xa7\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eca8[] = {
+ "\xec\xa8\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_eca9[] = {
+ "\xec\xa9\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecaa[] = {
+ "\xec\xaa\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecab[] = {
+ "\xec\xab\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecac[] = {
+ "\xec\xac\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecad[] = {
+ "\xec\xad\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecae[] = {
+ "\xec\xae\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecaf[] = {
+ "\xec\xaf\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecb0[] = {
+ "\xec\xb0\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecb1[] = {
+ "\xec\xb1\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecb2[] = {
+ "\xec\xb2\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecb3[] = {
+ "\xec\xb3\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecb4[] = {
+ "\xec\xb4\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecb5[] = {
+ "\xec\xb5\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecb6[] = {
+ "\xec\xb6\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecb7[] = {
+ "\xec\xb7\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecb8[] = {
+ "\xec\xb8\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecb9[] = {
+ "\xec\xb9\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecba[] = {
+ "\xec\xba\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecbb[] = {
+ "\xec\xbb\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecbc[] = {
+ "\xec\xbc\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecbd[] = {
+ "\xec\xbd\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecbe[] = {
+ "\xec\xbe\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ecbf[] = {
+ "\xec\xbf\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed80[] = {
+ "\xed\x80\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed81[] = {
+ "\xed\x81\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed82[] = {
+ "\xed\x82\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed83[] = {
+ "\xed\x83\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed84[] = {
+ "\xed\x84\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed85[] = {
+ "\xed\x85\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed86[] = {
+ "\xed\x86\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed87[] = {
+ "\xed\x87\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed88[] = {
+ "\xed\x88\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed89[] = {
+ "\xed\x89\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed8a[] = {
+ "\xed\x8a\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed8b[] = {
+ "\xed\x8b\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed8c[] = {
+ "\xed\x8c\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed8d[] = {
+ "\xed\x8d\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed8e[] = {
+ "\xed\x8e\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed8f[] = {
+ "\xed\x8f\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed90[] = {
+ "\xed\x90\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed91[] = {
+ "\xed\x91\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed92[] = {
+ "\xed\x92\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed93[] = {
+ "\xed\x93\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed94[] = {
+ "\xed\x94\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed95[] = {
+ "\xed\x95\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed96[] = {
+ "\xed\x96\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed97[] = {
+ "\xed\x97\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xb0"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed98[] = {
+ "\xed\x98\x8c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xa8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed99[] = {
+ "\xed\x99\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed9a[] = {
+ "\xed\x9a\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed9b[] = {
+ "\xed\x9b\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed9c[] = {
+ "\xed\x9c\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b3_table_ed9d[] = {
+ "\xed\x9d\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xb8"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186b3(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b3_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x94";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eab0[] = {
+ "\xea\xb0\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eab1[] = {
+ "\xea\xb1\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eab2[] = {
+ "\xea\xb2\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eab3[] = {
+ "\xea\xb3\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eab4[] = {
+ "\xea\xb4\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eab5[] = {
+ "\xea\xb5\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eab6[] = {
+ "\xea\xb6\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eab7[] = {
+ "\xea\xb7\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eab8[] = {
+ "\xea\xb8\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eab9[] = {
+ "\xea\xb9\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eaba[] = {
+ "\xea\xba\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eabb[] = {
+ "\xea\xbb\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eabc[] = {
+ "\xea\xbc\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eabd[] = {
+ "\xea\xbd\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eabe[] = {
+ "\xea\xbe\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eabf[] = {
+ "\xea\xbf\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb80[] = {
+ "\xeb\x80\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb81[] = {
+ "\xeb\x81\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb82[] = {
+ "\xeb\x82\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb83[] = {
+ "\xeb\x83\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb84[] = {
+ "\xeb\x84\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb85[] = {
+ "\xeb\x85\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb86[] = {
+ "\xeb\x86\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb87[] = {
+ "\xeb\x87\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb88[] = {
+ "\xeb\x88\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb89[] = {
+ "\xeb\x89\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb8a[] = {
+ "\xeb\x8a\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb8b[] = {
+ "\xeb\x8b\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb8c[] = {
+ "\xeb\x8c\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb8d[] = {
+ "\xeb\x8d\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb8e[] = {
+ "\xeb\x8e\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb8f[] = {
+ "\xeb\x8f\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb90[] = {
+ "\xeb\x90\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb91[] = {
+ "\xeb\x91\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb92[] = {
+ "\xeb\x92\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb93[] = {
+ "\xeb\x93\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb94[] = {
+ "\xeb\x94\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb95[] = {
+ "\xeb\x95\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb96[] = {
+ "\xeb\x96\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb97[] = {
+ "\xeb\x97\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb98[] = {
+ "\xeb\x98\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb99[] = {
+ "\xeb\x99\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb9a[] = {
+ "\xeb\x9a\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb9b[] = {
+ "\xeb\x9b\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb9c[] = {
+ "\xeb\x9c\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb9d[] = {
+ "\xeb\x9d\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb9e[] = {
+ "\xeb\x9e\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eb9f[] = {
+ "\xeb\x9f\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eba0[] = {
+ "\xeb\xa0\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eba1[] = {
+ "\xeb\xa1\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eba2[] = {
+ "\xeb\xa2\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eba3[] = {
+ "\xeb\xa3\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eba4[] = {
+ "\xeb\xa4\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eba5[] = {
+ "\xeb\xa5\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eba6[] = {
+ "\xeb\xa6\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eba7[] = {
+ "\xeb\xa7\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eba8[] = {
+ "\xeb\xa8\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eba9[] = {
+ "\xeb\xa9\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebaa[] = {
+ "\xeb\xaa\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebab[] = {
+ "\xeb\xab\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebac[] = {
+ "\xeb\xac\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebad[] = {
+ "\xeb\xad\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebae[] = {
+ "\xeb\xae\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebaf[] = {
+ "\xeb\xaf\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebb0[] = {
+ "\xeb\xb0\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebb1[] = {
+ "\xeb\xb1\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebb2[] = {
+ "\xeb\xb2\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebb3[] = {
+ "\xeb\xb3\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebb4[] = {
+ "\xeb\xb4\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebb5[] = {
+ "\xeb\xb5\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebb6[] = {
+ "\xeb\xb6\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebb7[] = {
+ "\xeb\xb7\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebb8[] = {
+ "\xeb\xb8\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebb9[] = {
+ "\xeb\xb9\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebba[] = {
+ "\xeb\xba\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebbb[] = {
+ "\xeb\xbb\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebbc[] = {
+ "\xeb\xbc\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebbd[] = {
+ "\xeb\xbd\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebbe[] = {
+ "\xeb\xbe\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ebbf[] = {
+ "\xeb\xbf\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec80[] = {
+ "\xec\x80\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec81[] = {
+ "\xec\x81\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec82[] = {
+ "\xec\x82\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec83[] = {
+ "\xec\x83\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec84[] = {
+ "\xec\x84\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec85[] = {
+ "\xec\x85\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec86[] = {
+ "\xec\x86\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec87[] = {
+ "\xec\x87\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec88[] = {
+ "\xec\x88\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec89[] = {
+ "\xec\x89\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec8a[] = {
+ "\xec\x8a\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec8b[] = {
+ "\xec\x8b\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec8c[] = {
+ "\xec\x8c\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec8d[] = {
+ "\xec\x8d\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec8e[] = {
+ "\xec\x8e\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec8f[] = {
+ "\xec\x8f\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec90[] = {
+ "\xec\x90\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec91[] = {
+ "\xec\x91\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec92[] = {
+ "\xec\x92\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec93[] = {
+ "\xec\x93\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec94[] = {
+ "\xec\x94\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec95[] = {
+ "\xec\x95\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec96[] = {
+ "\xec\x96\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec97[] = {
+ "\xec\x97\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec98[] = {
+ "\xec\x98\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec99[] = {
+ "\xec\x99\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec9a[] = {
+ "\xec\x9a\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec9b[] = {
+ "\xec\x9b\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec9c[] = {
+ "\xec\x9c\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec9d[] = {
+ "\xec\x9d\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec9e[] = {
+ "\xec\x9e\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ec9f[] = {
+ "\xec\x9f\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eca0[] = {
+ "\xec\xa0\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eca1[] = {
+ "\xec\xa1\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eca2[] = {
+ "\xec\xa2\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eca3[] = {
+ "\xec\xa3\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eca4[] = {
+ "\xec\xa4\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eca5[] = {
+ "\xec\xa5\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eca6[] = {
+ "\xec\xa6\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eca7[] = {
+ "\xec\xa7\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eca8[] = {
+ "\xec\xa8\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_eca9[] = {
+ "\xec\xa9\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecaa[] = {
+ "\xec\xaa\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecab[] = {
+ "\xec\xab\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecac[] = {
+ "\xec\xac\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecad[] = {
+ "\xec\xad\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecae[] = {
+ "\xec\xae\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecaf[] = {
+ "\xec\xaf\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecb0[] = {
+ "\xec\xb0\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecb1[] = {
+ "\xec\xb1\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecb2[] = {
+ "\xec\xb2\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecb3[] = {
+ "\xec\xb3\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecb4[] = {
+ "\xec\xb4\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecb5[] = {
+ "\xec\xb5\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecb6[] = {
+ "\xec\xb6\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecb7[] = {
+ "\xec\xb7\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecb8[] = {
+ "\xec\xb8\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecb9[] = {
+ "\xec\xb9\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecba[] = {
+ "\xec\xba\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecbb[] = {
+ "\xec\xbb\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecbc[] = {
+ "\xec\xbc\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecbd[] = {
+ "\xec\xbd\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecbe[] = {
+ "\xec\xbe\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ecbf[] = {
+ "\xec\xbf\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed80[] = {
+ "\xed\x80\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed81[] = {
+ "\xed\x81\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed82[] = {
+ "\xed\x82\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed83[] = {
+ "\xed\x83\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed84[] = {
+ "\xed\x84\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed85[] = {
+ "\xed\x85\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed86[] = {
+ "\xed\x86\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed87[] = {
+ "\xed\x87\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed88[] = {
+ "\xed\x88\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed89[] = {
+ "\xed\x89\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed8a[] = {
+ "\xed\x8a\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed8b[] = {
+ "\xed\x8b\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed8c[] = {
+ "\xed\x8c\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed8d[] = {
+ "\xed\x8d\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed8e[] = {
+ "\xed\x8e\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed8f[] = {
+ "\xed\x8f\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed90[] = {
+ "\xed\x90\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed91[] = {
+ "\xed\x91\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed92[] = {
+ "\xed\x92\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed93[] = {
+ "\xed\x93\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed94[] = {
+ "\xed\x94\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed95[] = {
+ "\xed\x95\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed96[] = {
+ "\xed\x96\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed97[] = {
+ "\xed\x97\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xb1"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed98[] = {
+ "\xed\x98\x8d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xa9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed99[] = {
+ "\xed\x99\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed9a[] = {
+ "\xed\x9a\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed9b[] = {
+ "\xed\x9b\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed9c[] = {
+ "\xed\x9c\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b4_table_ed9d[] = {
+ "\xed\x9d\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xb9"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186b4(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b4_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x95";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eab0[] = {
+ "\xea\xb0\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eab1[] = {
+ "\xea\xb1\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eab2[] = {
+ "\xea\xb2\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eab3[] = {
+ "\xea\xb3\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eab4[] = {
+ "\xea\xb4\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eab5[] = {
+ "\xea\xb5\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eab6[] = {
+ "\xea\xb6\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eab7[] = {
+ "\xea\xb7\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eab8[] = {
+ "\xea\xb8\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eab9[] = {
+ "\xea\xb9\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eaba[] = {
+ "\xea\xba\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eabb[] = {
+ "\xea\xbb\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eabc[] = {
+ "\xea\xbc\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eabd[] = {
+ "\xea\xbd\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eabe[] = {
+ "\xea\xbe\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eabf[] = {
+ "\xea\xbf\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb80[] = {
+ "\xeb\x80\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb81[] = {
+ "\xeb\x81\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb82[] = {
+ "\xeb\x82\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb83[] = {
+ "\xeb\x83\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb84[] = {
+ "\xeb\x84\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb85[] = {
+ "\xeb\x85\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb86[] = {
+ "\xeb\x86\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb87[] = {
+ "\xeb\x87\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb88[] = {
+ "\xeb\x88\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb89[] = {
+ "\xeb\x89\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb8a[] = {
+ "\xeb\x8a\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb8b[] = {
+ "\xeb\x8b\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb8c[] = {
+ "\xeb\x8c\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb8d[] = {
+ "\xeb\x8d\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb8e[] = {
+ "\xeb\x8e\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb8f[] = {
+ "\xeb\x8f\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb90[] = {
+ "\xeb\x90\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb91[] = {
+ "\xeb\x91\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb92[] = {
+ "\xeb\x92\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb93[] = {
+ "\xeb\x93\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb94[] = {
+ "\xeb\x94\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb95[] = {
+ "\xeb\x95\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb96[] = {
+ "\xeb\x96\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb97[] = {
+ "\xeb\x97\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb98[] = {
+ "\xeb\x98\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb99[] = {
+ "\xeb\x99\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb9a[] = {
+ "\xeb\x9a\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb9b[] = {
+ "\xeb\x9b\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb9c[] = {
+ "\xeb\x9c\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb9d[] = {
+ "\xeb\x9d\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb9e[] = {
+ "\xeb\x9e\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eb9f[] = {
+ "\xeb\x9f\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eba0[] = {
+ "\xeb\xa0\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eba1[] = {
+ "\xeb\xa1\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eba2[] = {
+ "\xeb\xa2\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eba3[] = {
+ "\xeb\xa3\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eba4[] = {
+ "\xeb\xa4\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eba5[] = {
+ "\xeb\xa5\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eba6[] = {
+ "\xeb\xa6\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eba7[] = {
+ "\xeb\xa7\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eba8[] = {
+ "\xeb\xa8\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eba9[] = {
+ "\xeb\xa9\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebaa[] = {
+ "\xeb\xaa\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebab[] = {
+ "\xeb\xab\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebac[] = {
+ "\xeb\xac\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebad[] = {
+ "\xeb\xad\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebae[] = {
+ "\xeb\xae\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebaf[] = {
+ "\xeb\xaf\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebb0[] = {
+ "\xeb\xb0\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebb1[] = {
+ "\xeb\xb1\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebb2[] = {
+ "\xeb\xb2\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebb3[] = {
+ "\xeb\xb3\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebb4[] = {
+ "\xeb\xb4\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebb5[] = {
+ "\xeb\xb5\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebb6[] = {
+ "\xeb\xb6\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebb7[] = {
+ "\xeb\xb7\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebb8[] = {
+ "\xeb\xb8\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebb9[] = {
+ "\xeb\xb9\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebba[] = {
+ "\xeb\xba\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebbb[] = {
+ "\xeb\xbb\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebbc[] = {
+ "\xeb\xbc\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebbd[] = {
+ "\xeb\xbd\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebbe[] = {
+ "\xeb\xbe\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ebbf[] = {
+ "\xeb\xbf\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec80[] = {
+ "\xec\x80\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec81[] = {
+ "\xec\x81\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec82[] = {
+ "\xec\x82\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec83[] = {
+ "\xec\x83\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec84[] = {
+ "\xec\x84\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec85[] = {
+ "\xec\x85\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec86[] = {
+ "\xec\x86\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec87[] = {
+ "\xec\x87\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec88[] = {
+ "\xec\x88\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec89[] = {
+ "\xec\x89\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec8a[] = {
+ "\xec\x8a\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec8b[] = {
+ "\xec\x8b\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec8c[] = {
+ "\xec\x8c\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec8d[] = {
+ "\xec\x8d\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec8e[] = {
+ "\xec\x8e\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec8f[] = {
+ "\xec\x8f\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec90[] = {
+ "\xec\x90\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec91[] = {
+ "\xec\x91\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec92[] = {
+ "\xec\x92\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec93[] = {
+ "\xec\x93\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec94[] = {
+ "\xec\x94\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec95[] = {
+ "\xec\x95\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec96[] = {
+ "\xec\x96\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec97[] = {
+ "\xec\x97\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec98[] = {
+ "\xec\x98\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec99[] = {
+ "\xec\x99\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec9a[] = {
+ "\xec\x9a\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec9b[] = {
+ "\xec\x9b\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec9c[] = {
+ "\xec\x9c\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec9d[] = {
+ "\xec\x9d\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec9e[] = {
+ "\xec\x9e\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ec9f[] = {
+ "\xec\x9f\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eca0[] = {
+ "\xec\xa0\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eca1[] = {
+ "\xec\xa1\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eca2[] = {
+ "\xec\xa2\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eca3[] = {
+ "\xec\xa3\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eca4[] = {
+ "\xec\xa4\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eca5[] = {
+ "\xec\xa5\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eca6[] = {
+ "\xec\xa6\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eca7[] = {
+ "\xec\xa7\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eca8[] = {
+ "\xec\xa8\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_eca9[] = {
+ "\xec\xa9\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecaa[] = {
+ "\xec\xaa\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecab[] = {
+ "\xec\xab\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecac[] = {
+ "\xec\xac\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecad[] = {
+ "\xec\xad\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecae[] = {
+ "\xec\xae\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecaf[] = {
+ "\xec\xaf\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecb0[] = {
+ "\xec\xb0\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecb1[] = {
+ "\xec\xb1\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecb2[] = {
+ "\xec\xb2\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecb3[] = {
+ "\xec\xb3\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecb4[] = {
+ "\xec\xb4\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecb5[] = {
+ "\xec\xb5\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecb6[] = {
+ "\xec\xb6\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecb7[] = {
+ "\xec\xb7\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecb8[] = {
+ "\xec\xb8\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecb9[] = {
+ "\xec\xb9\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecba[] = {
+ "\xec\xba\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecbb[] = {
+ "\xec\xbb\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecbc[] = {
+ "\xec\xbc\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecbd[] = {
+ "\xec\xbd\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecbe[] = {
+ "\xec\xbe\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ecbf[] = {
+ "\xec\xbf\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed80[] = {
+ "\xed\x80\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed81[] = {
+ "\xed\x81\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed82[] = {
+ "\xed\x82\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed83[] = {
+ "\xed\x83\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed84[] = {
+ "\xed\x84\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed85[] = {
+ "\xed\x85\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed86[] = {
+ "\xed\x86\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed87[] = {
+ "\xed\x87\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed88[] = {
+ "\xed\x88\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed89[] = {
+ "\xed\x89\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed8a[] = {
+ "\xed\x8a\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed8b[] = {
+ "\xed\x8b\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed8c[] = {
+ "\xed\x8c\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed8d[] = {
+ "\xed\x8d\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed8e[] = {
+ "\xed\x8e\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed8f[] = {
+ "\xed\x8f\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed90[] = {
+ "\xed\x90\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed91[] = {
+ "\xed\x91\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed92[] = {
+ "\xed\x92\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed93[] = {
+ "\xed\x93\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed94[] = {
+ "\xed\x94\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed95[] = {
+ "\xed\x95\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed96[] = {
+ "\xed\x96\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed97[] = {
+ "\xed\x97\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xb2"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed98[] = {
+ "\xed\x98\x8e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xaa", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed99[] = {
+ "\xed\x99\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed9a[] = {
+ "\xed\x9a\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed9b[] = {
+ "\xed\x9b\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed9c[] = {
+ "\xed\x9c\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b5_table_ed9d[] = {
+ "\xed\x9d\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xba"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186b5(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b5_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x96";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eab0[] = {
+ "\xea\xb0\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eab1[] = {
+ "\xea\xb1\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb1\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eab2[] = {
+ "\xea\xb2\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eab3[] = {
+ "\xea\xb3\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eab4[] = {
+ "\xea\xb4\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eab5[] = {
+ "\xea\xb5\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eab6[] = {
+ "\xea\xb6\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eab7[] = {
+ "\xea\xb7\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eab8[] = {
+ "\xea\xb8\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb8\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eab9[] = {
+ "\xea\xb9\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eaba[] = {
+ "\xea\xba\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eabb[] = {
+ "\xea\xbb\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eabc[] = {
+ "\xea\xbc\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eabd[] = {
+ "\xea\xbd\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eabe[] = {
+ "\xea\xbe\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eabf[] = {
+ "\xea\xbf\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbf\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb80[] = {
+ "\xeb\x80\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb81[] = {
+ "\xeb\x81\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb82[] = {
+ "\xeb\x82\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb83[] = {
+ "\xeb\x83\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb84[] = {
+ "\xeb\x84\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb85[] = {
+ "\xeb\x85\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb86[] = {
+ "\xeb\x86\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x86\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb87[] = {
+ "\xeb\x87\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb88[] = {
+ "\xeb\x88\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb89[] = {
+ "\xeb\x89\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb8a[] = {
+ "\xeb\x8a\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb8b[] = {
+ "\xeb\x8b\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb8c[] = {
+ "\xeb\x8c\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb8d[] = {
+ "\xeb\x8d\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8d\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb8e[] = {
+ "\xeb\x8e\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb8f[] = {
+ "\xeb\x8f\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb90[] = {
+ "\xeb\x90\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb91[] = {
+ "\xeb\x91\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb92[] = {
+ "\xeb\x92\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb93[] = {
+ "\xeb\x93\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb94[] = {
+ "\xeb\x94\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x94\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb95[] = {
+ "\xeb\x95\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb96[] = {
+ "\xeb\x96\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb97[] = {
+ "\xeb\x97\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb98[] = {
+ "\xeb\x98\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb99[] = {
+ "\xeb\x99\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb9a[] = {
+ "\xeb\x9a\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb9b[] = {
+ "\xeb\x9b\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9b\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb9c[] = {
+ "\xeb\x9c\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb9d[] = {
+ "\xeb\x9d\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb9e[] = {
+ "\xeb\x9e\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eb9f[] = {
+ "\xeb\x9f\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eba0[] = {
+ "\xeb\xa0\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eba1[] = {
+ "\xeb\xa1\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eba2[] = {
+ "\xeb\xa2\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa2\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eba3[] = {
+ "\xeb\xa3\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eba4[] = {
+ "\xeb\xa4\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eba5[] = {
+ "\xeb\xa5\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eba6[] = {
+ "\xeb\xa6\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eba7[] = {
+ "\xeb\xa7\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eba8[] = {
+ "\xeb\xa8\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eba9[] = {
+ "\xeb\xa9\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa9\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebaa[] = {
+ "\xeb\xaa\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebab[] = {
+ "\xeb\xab\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebac[] = {
+ "\xeb\xac\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebad[] = {
+ "\xeb\xad\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebae[] = {
+ "\xeb\xae\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebaf[] = {
+ "\xeb\xaf\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebb0[] = {
+ "\xeb\xb0\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb0\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebb1[] = {
+ "\xeb\xb1\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebb2[] = {
+ "\xeb\xb2\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebb3[] = {
+ "\xeb\xb3\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebb4[] = {
+ "\xeb\xb4\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebb5[] = {
+ "\xeb\xb5\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebb6[] = {
+ "\xeb\xb6\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebb7[] = {
+ "\xeb\xb7\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb7\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebb8[] = {
+ "\xeb\xb8\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebb9[] = {
+ "\xeb\xb9\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebba[] = {
+ "\xeb\xba\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebbb[] = {
+ "\xeb\xbb\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebbc[] = {
+ "\xeb\xbc\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebbd[] = {
+ "\xeb\xbd\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebbe[] = {
+ "\xeb\xbe\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbe\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ebbf[] = {
+ "\xeb\xbf\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec80[] = {
+ "\xec\x80\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec81[] = {
+ "\xec\x81\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec82[] = {
+ "\xec\x82\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec83[] = {
+ "\xec\x83\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec84[] = {
+ "\xec\x84\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec85[] = {
+ "\xec\x85\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x85\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec86[] = {
+ "\xec\x86\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec87[] = {
+ "\xec\x87\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec88[] = {
+ "\xec\x88\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec89[] = {
+ "\xec\x89\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec8a[] = {
+ "\xec\x8a\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec8b[] = {
+ "\xec\x8b\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec8c[] = {
+ "\xec\x8c\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8c\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec8d[] = {
+ "\xec\x8d\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec8e[] = {
+ "\xec\x8e\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec8f[] = {
+ "\xec\x8f\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec90[] = {
+ "\xec\x90\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec91[] = {
+ "\xec\x91\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec92[] = {
+ "\xec\x92\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec93[] = {
+ "\xec\x93\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x93\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec94[] = {
+ "\xec\x94\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec95[] = {
+ "\xec\x95\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec96[] = {
+ "\xec\x96\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec97[] = {
+ "\xec\x97\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec98[] = {
+ "\xec\x98\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec99[] = {
+ "\xec\x99\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec9a[] = {
+ "\xec\x9a\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9a\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec9b[] = {
+ "\xec\x9b\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec9c[] = {
+ "\xec\x9c\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec9d[] = {
+ "\xec\x9d\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec9e[] = {
+ "\xec\x9e\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ec9f[] = {
+ "\xec\x9f\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eca0[] = {
+ "\xec\xa0\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eca1[] = {
+ "\xec\xa1\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa1\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eca2[] = {
+ "\xec\xa2\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eca3[] = {
+ "\xec\xa3\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eca4[] = {
+ "\xec\xa4\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eca5[] = {
+ "\xec\xa5\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eca6[] = {
+ "\xec\xa6\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eca7[] = {
+ "\xec\xa7\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eca8[] = {
+ "\xec\xa8\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa8\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_eca9[] = {
+ "\xec\xa9\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecaa[] = {
+ "\xec\xaa\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecab[] = {
+ "\xec\xab\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecac[] = {
+ "\xec\xac\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecad[] = {
+ "\xec\xad\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecae[] = {
+ "\xec\xae\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecaf[] = {
+ "\xec\xaf\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaf\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecb0[] = {
+ "\xec\xb0\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecb1[] = {
+ "\xec\xb1\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecb2[] = {
+ "\xec\xb2\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecb3[] = {
+ "\xec\xb3\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecb4[] = {
+ "\xec\xb4\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecb5[] = {
+ "\xec\xb5\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecb6[] = {
+ "\xec\xb6\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb6\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecb7[] = {
+ "\xec\xb7\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecb8[] = {
+ "\xec\xb8\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecb9[] = {
+ "\xec\xb9\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecba[] = {
+ "\xec\xba\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecbb[] = {
+ "\xec\xbb\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecbc[] = {
+ "\xec\xbc\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecbd[] = {
+ "\xec\xbd\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbd\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecbe[] = {
+ "\xec\xbe\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ecbf[] = {
+ "\xec\xbf\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed80[] = {
+ "\xed\x80\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed81[] = {
+ "\xed\x81\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed82[] = {
+ "\xed\x82\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed83[] = {
+ "\xed\x83\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed84[] = {
+ "\xed\x84\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x84\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed85[] = {
+ "\xed\x85\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed86[] = {
+ "\xed\x86\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed87[] = {
+ "\xed\x87\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed88[] = {
+ "\xed\x88\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed89[] = {
+ "\xed\x89\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed8a[] = {
+ "\xed\x8a\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed8b[] = {
+ "\xed\x8b\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8b\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed8c[] = {
+ "\xed\x8c\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed8d[] = {
+ "\xed\x8d\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed8e[] = {
+ "\xed\x8e\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed8f[] = {
+ "\xed\x8f\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed90[] = {
+ "\xed\x90\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed91[] = {
+ "\xed\x91\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed92[] = {
+ "\xed\x92\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x92\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed93[] = {
+ "\xed\x93\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed94[] = {
+ "\xed\x94\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed95[] = {
+ "\xed\x95\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed96[] = {
+ "\xed\x96\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed97[] = {
+ "\xed\x97\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xb3"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed98[] = {
+ "\xed\x98\x8f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xab", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed99[] = {
+ "\xed\x99\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x99\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed9a[] = {
+ "\xed\x9a\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed9b[] = {
+ "\xed\x9b\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed9c[] = {
+ "\xed\x9c\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b6_table_ed9d[] = {
+ "\xed\x9d\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xbb"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186b6(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b6_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x97";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eab0[] = {
+ "\xea\xb0\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eab1[] = {
+ "\xea\xb1\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eab2[] = {
+ "\xea\xb2\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eab3[] = {
+ "\xea\xb3\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eab4[] = {
+ "\xea\xb4\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eab5[] = {
+ "\xea\xb5\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eab6[] = {
+ "\xea\xb6\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eab7[] = {
+ "\xea\xb7\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eab8[] = {
+ "\xea\xb8\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eab9[] = {
+ "\xea\xb9\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eaba[] = {
+ "\xea\xba\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eabb[] = {
+ "\xea\xbb\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eabc[] = {
+ "\xea\xbc\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eabd[] = {
+ "\xea\xbd\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eabe[] = {
+ "\xea\xbe\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eabf[] = {
+ "\xea\xbf\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb80[] = {
+ "\xeb\x80\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb81[] = {
+ "\xeb\x81\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb82[] = {
+ "\xeb\x82\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb83[] = {
+ "\xeb\x83\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb84[] = {
+ "\xeb\x84\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb85[] = {
+ "\xeb\x85\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb86[] = {
+ "\xeb\x86\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb87[] = {
+ "\xeb\x87\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb88[] = {
+ "\xeb\x88\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb89[] = {
+ "\xeb\x89\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb8a[] = {
+ "\xeb\x8a\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb8b[] = {
+ "\xeb\x8b\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb8c[] = {
+ "\xeb\x8c\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb8d[] = {
+ "\xeb\x8d\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb8e[] = {
+ "\xeb\x8e\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb8f[] = {
+ "\xeb\x8f\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb90[] = {
+ "\xeb\x90\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb91[] = {
+ "\xeb\x91\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb92[] = {
+ "\xeb\x92\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb93[] = {
+ "\xeb\x93\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb94[] = {
+ "\xeb\x94\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb95[] = {
+ "\xeb\x95\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb96[] = {
+ "\xeb\x96\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb97[] = {
+ "\xeb\x97\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb98[] = {
+ "\xeb\x98\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb99[] = {
+ "\xeb\x99\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb9a[] = {
+ "\xeb\x9a\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb9b[] = {
+ "\xeb\x9b\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb9c[] = {
+ "\xeb\x9c\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb9d[] = {
+ "\xeb\x9d\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb9e[] = {
+ "\xeb\x9e\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eb9f[] = {
+ "\xeb\x9f\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eba0[] = {
+ "\xeb\xa0\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eba1[] = {
+ "\xeb\xa1\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eba2[] = {
+ "\xeb\xa2\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eba3[] = {
+ "\xeb\xa3\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eba4[] = {
+ "\xeb\xa4\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eba5[] = {
+ "\xeb\xa5\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eba6[] = {
+ "\xeb\xa6\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eba7[] = {
+ "\xeb\xa7\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eba8[] = {
+ "\xeb\xa8\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eba9[] = {
+ "\xeb\xa9\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebaa[] = {
+ "\xeb\xaa\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebab[] = {
+ "\xeb\xab\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebac[] = {
+ "\xeb\xac\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebad[] = {
+ "\xeb\xad\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebae[] = {
+ "\xeb\xae\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebaf[] = {
+ "\xeb\xaf\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebb0[] = {
+ "\xeb\xb0\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebb1[] = {
+ "\xeb\xb1\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebb2[] = {
+ "\xeb\xb2\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebb3[] = {
+ "\xeb\xb3\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebb4[] = {
+ "\xeb\xb4\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebb5[] = {
+ "\xeb\xb5\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebb6[] = {
+ "\xeb\xb6\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebb7[] = {
+ "\xeb\xb7\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebb8[] = {
+ "\xeb\xb8\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebb9[] = {
+ "\xeb\xb9\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebba[] = {
+ "\xeb\xba\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebbb[] = {
+ "\xeb\xbb\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebbc[] = {
+ "\xeb\xbc\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebbd[] = {
+ "\xeb\xbd\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebbe[] = {
+ "\xeb\xbe\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ebbf[] = {
+ "\xeb\xbf\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec80[] = {
+ "\xec\x80\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec81[] = {
+ "\xec\x81\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec82[] = {
+ "\xec\x82\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec83[] = {
+ "\xec\x83\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec84[] = {
+ "\xec\x84\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec85[] = {
+ "\xec\x85\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec86[] = {
+ "\xec\x86\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec87[] = {
+ "\xec\x87\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec88[] = {
+ "\xec\x88\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec89[] = {
+ "\xec\x89\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec8a[] = {
+ "\xec\x8a\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec8b[] = {
+ "\xec\x8b\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec8c[] = {
+ "\xec\x8c\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec8d[] = {
+ "\xec\x8d\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec8e[] = {
+ "\xec\x8e\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec8f[] = {
+ "\xec\x8f\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec90[] = {
+ "\xec\x90\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec91[] = {
+ "\xec\x91\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec92[] = {
+ "\xec\x92\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec93[] = {
+ "\xec\x93\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec94[] = {
+ "\xec\x94\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec95[] = {
+ "\xec\x95\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec96[] = {
+ "\xec\x96\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec97[] = {
+ "\xec\x97\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec98[] = {
+ "\xec\x98\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec99[] = {
+ "\xec\x99\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec9a[] = {
+ "\xec\x9a\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec9b[] = {
+ "\xec\x9b\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec9c[] = {
+ "\xec\x9c\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec9d[] = {
+ "\xec\x9d\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec9e[] = {
+ "\xec\x9e\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ec9f[] = {
+ "\xec\x9f\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eca0[] = {
+ "\xec\xa0\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eca1[] = {
+ "\xec\xa1\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eca2[] = {
+ "\xec\xa2\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eca3[] = {
+ "\xec\xa3\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eca4[] = {
+ "\xec\xa4\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eca5[] = {
+ "\xec\xa5\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eca6[] = {
+ "\xec\xa6\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eca7[] = {
+ "\xec\xa7\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eca8[] = {
+ "\xec\xa8\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_eca9[] = {
+ "\xec\xa9\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecaa[] = {
+ "\xec\xaa\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecab[] = {
+ "\xec\xab\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecac[] = {
+ "\xec\xac\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecad[] = {
+ "\xec\xad\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecae[] = {
+ "\xec\xae\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecaf[] = {
+ "\xec\xaf\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecb0[] = {
+ "\xec\xb0\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecb1[] = {
+ "\xec\xb1\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecb2[] = {
+ "\xec\xb2\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecb3[] = {
+ "\xec\xb3\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecb4[] = {
+ "\xec\xb4\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecb5[] = {
+ "\xec\xb5\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecb6[] = {
+ "\xec\xb6\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecb7[] = {
+ "\xec\xb7\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecb8[] = {
+ "\xec\xb8\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecb9[] = {
+ "\xec\xb9\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecba[] = {
+ "\xec\xba\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecbb[] = {
+ "\xec\xbb\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecbc[] = {
+ "\xec\xbc\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecbd[] = {
+ "\xec\xbd\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecbe[] = {
+ "\xec\xbe\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ecbf[] = {
+ "\xec\xbf\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed80[] = {
+ "\xed\x80\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed81[] = {
+ "\xed\x81\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed82[] = {
+ "\xed\x82\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed83[] = {
+ "\xed\x83\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed84[] = {
+ "\xed\x84\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed85[] = {
+ "\xed\x85\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed86[] = {
+ "\xed\x86\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed87[] = {
+ "\xed\x87\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed88[] = {
+ "\xed\x88\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed89[] = {
+ "\xed\x89\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed8a[] = {
+ "\xed\x8a\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed8b[] = {
+ "\xed\x8b\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed8c[] = {
+ "\xed\x8c\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed8d[] = {
+ "\xed\x8d\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed8e[] = {
+ "\xed\x8e\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed8f[] = {
+ "\xed\x8f\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed90[] = {
+ "\xed\x90\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed91[] = {
+ "\xed\x91\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed92[] = {
+ "\xed\x92\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed93[] = {
+ "\xed\x93\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed94[] = {
+ "\xed\x94\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed95[] = {
+ "\xed\x95\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed96[] = {
+ "\xed\x96\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed97[] = {
+ "\xed\x97\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xb4"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed98[] = {
+ "\xed\x98\x90", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xac", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed99[] = {
+ "\xed\x99\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed9a[] = {
+ "\xed\x9a\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed9b[] = {
+ "\xed\x9b\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed9c[] = {
+ "\xed\x9c\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b7_table_ed9d[] = {
+ "\xed\x9d\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xbc"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186b7(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b7_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x98";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eab0[] = {
+ "\xea\xb0\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eab1[] = {
+ "\xea\xb1\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eab2[] = {
+ "\xea\xb2\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eab3[] = {
+ "\xea\xb3\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eab4[] = {
+ "\xea\xb4\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eab5[] = {
+ "\xea\xb5\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eab6[] = {
+ "\xea\xb6\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eab7[] = {
+ "\xea\xb7\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eab8[] = {
+ "\xea\xb8\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eab9[] = {
+ "\xea\xb9\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eaba[] = {
+ "\xea\xba\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eabb[] = {
+ "\xea\xbb\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eabc[] = {
+ "\xea\xbc\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eabd[] = {
+ "\xea\xbd\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eabe[] = {
+ "\xea\xbe\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eabf[] = {
+ "\xea\xbf\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb80[] = {
+ "\xeb\x80\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb81[] = {
+ "\xeb\x81\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb82[] = {
+ "\xeb\x82\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb83[] = {
+ "\xeb\x83\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb84[] = {
+ "\xeb\x84\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb85[] = {
+ "\xeb\x85\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb86[] = {
+ "\xeb\x86\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb87[] = {
+ "\xeb\x87\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb88[] = {
+ "\xeb\x88\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb89[] = {
+ "\xeb\x89\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb8a[] = {
+ "\xeb\x8a\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb8b[] = {
+ "\xeb\x8b\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb8c[] = {
+ "\xeb\x8c\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb8d[] = {
+ "\xeb\x8d\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb8e[] = {
+ "\xeb\x8e\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb8f[] = {
+ "\xeb\x8f\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb90[] = {
+ "\xeb\x90\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb91[] = {
+ "\xeb\x91\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb92[] = {
+ "\xeb\x92\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb93[] = {
+ "\xeb\x93\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb94[] = {
+ "\xeb\x94\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb95[] = {
+ "\xeb\x95\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb96[] = {
+ "\xeb\x96\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb97[] = {
+ "\xeb\x97\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb98[] = {
+ "\xeb\x98\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb99[] = {
+ "\xeb\x99\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb9a[] = {
+ "\xeb\x9a\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb9b[] = {
+ "\xeb\x9b\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb9c[] = {
+ "\xeb\x9c\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb9d[] = {
+ "\xeb\x9d\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb9e[] = {
+ "\xeb\x9e\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eb9f[] = {
+ "\xeb\x9f\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eba0[] = {
+ "\xeb\xa0\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eba1[] = {
+ "\xeb\xa1\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eba2[] = {
+ "\xeb\xa2\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eba3[] = {
+ "\xeb\xa3\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eba4[] = {
+ "\xeb\xa4\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eba5[] = {
+ "\xeb\xa5\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eba6[] = {
+ "\xeb\xa6\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eba7[] = {
+ "\xeb\xa7\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eba8[] = {
+ "\xeb\xa8\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eba9[] = {
+ "\xeb\xa9\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebaa[] = {
+ "\xeb\xaa\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebab[] = {
+ "\xeb\xab\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebac[] = {
+ "\xeb\xac\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebad[] = {
+ "\xeb\xad\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebae[] = {
+ "\xeb\xae\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebaf[] = {
+ "\xeb\xaf\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebb0[] = {
+ "\xeb\xb0\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebb1[] = {
+ "\xeb\xb1\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebb2[] = {
+ "\xeb\xb2\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebb3[] = {
+ "\xeb\xb3\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebb4[] = {
+ "\xeb\xb4\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebb5[] = {
+ "\xeb\xb5\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebb6[] = {
+ "\xeb\xb6\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebb7[] = {
+ "\xeb\xb7\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebb8[] = {
+ "\xeb\xb8\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebb9[] = {
+ "\xeb\xb9\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebba[] = {
+ "\xeb\xba\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebbb[] = {
+ "\xeb\xbb\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebbc[] = {
+ "\xeb\xbc\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebbd[] = {
+ "\xeb\xbd\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebbe[] = {
+ "\xeb\xbe\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ebbf[] = {
+ "\xeb\xbf\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec80[] = {
+ "\xec\x80\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec81[] = {
+ "\xec\x81\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec82[] = {
+ "\xec\x82\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec83[] = {
+ "\xec\x83\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec84[] = {
+ "\xec\x84\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec85[] = {
+ "\xec\x85\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec86[] = {
+ "\xec\x86\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec87[] = {
+ "\xec\x87\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec88[] = {
+ "\xec\x88\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec89[] = {
+ "\xec\x89\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec8a[] = {
+ "\xec\x8a\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec8b[] = {
+ "\xec\x8b\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec8c[] = {
+ "\xec\x8c\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec8d[] = {
+ "\xec\x8d\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec8e[] = {
+ "\xec\x8e\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec8f[] = {
+ "\xec\x8f\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec90[] = {
+ "\xec\x90\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec91[] = {
+ "\xec\x91\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec92[] = {
+ "\xec\x92\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec93[] = {
+ "\xec\x93\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec94[] = {
+ "\xec\x94\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec95[] = {
+ "\xec\x95\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec96[] = {
+ "\xec\x96\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec97[] = {
+ "\xec\x97\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec98[] = {
+ "\xec\x98\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec99[] = {
+ "\xec\x99\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec9a[] = {
+ "\xec\x9a\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec9b[] = {
+ "\xec\x9b\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec9c[] = {
+ "\xec\x9c\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec9d[] = {
+ "\xec\x9d\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec9e[] = {
+ "\xec\x9e\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ec9f[] = {
+ "\xec\x9f\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eca0[] = {
+ "\xec\xa0\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eca1[] = {
+ "\xec\xa1\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eca2[] = {
+ "\xec\xa2\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eca3[] = {
+ "\xec\xa3\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eca4[] = {
+ "\xec\xa4\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eca5[] = {
+ "\xec\xa5\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eca6[] = {
+ "\xec\xa6\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eca7[] = {
+ "\xec\xa7\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eca8[] = {
+ "\xec\xa8\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_eca9[] = {
+ "\xec\xa9\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecaa[] = {
+ "\xec\xaa\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecab[] = {
+ "\xec\xab\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecac[] = {
+ "\xec\xac\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecad[] = {
+ "\xec\xad\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecae[] = {
+ "\xec\xae\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecaf[] = {
+ "\xec\xaf\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecb0[] = {
+ "\xec\xb0\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecb1[] = {
+ "\xec\xb1\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecb2[] = {
+ "\xec\xb2\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecb3[] = {
+ "\xec\xb3\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecb4[] = {
+ "\xec\xb4\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecb5[] = {
+ "\xec\xb5\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecb6[] = {
+ "\xec\xb6\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecb7[] = {
+ "\xec\xb7\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecb8[] = {
+ "\xec\xb8\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecb9[] = {
+ "\xec\xb9\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecba[] = {
+ "\xec\xba\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecbb[] = {
+ "\xec\xbb\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecbc[] = {
+ "\xec\xbc\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecbd[] = {
+ "\xec\xbd\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecbe[] = {
+ "\xec\xbe\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ecbf[] = {
+ "\xec\xbf\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed80[] = {
+ "\xed\x80\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed81[] = {
+ "\xed\x81\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed82[] = {
+ "\xed\x82\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed83[] = {
+ "\xed\x83\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed84[] = {
+ "\xed\x84\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed85[] = {
+ "\xed\x85\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed86[] = {
+ "\xed\x86\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed87[] = {
+ "\xed\x87\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed88[] = {
+ "\xed\x88\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed89[] = {
+ "\xed\x89\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed8a[] = {
+ "\xed\x8a\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed8b[] = {
+ "\xed\x8b\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed8c[] = {
+ "\xed\x8c\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed8d[] = {
+ "\xed\x8d\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed8e[] = {
+ "\xed\x8e\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed8f[] = {
+ "\xed\x8f\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed90[] = {
+ "\xed\x90\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed91[] = {
+ "\xed\x91\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed92[] = {
+ "\xed\x92\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed93[] = {
+ "\xed\x93\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed94[] = {
+ "\xed\x94\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed95[] = {
+ "\xed\x95\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed96[] = {
+ "\xed\x96\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed97[] = {
+ "\xed\x97\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xb5"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed98[] = {
+ "\xed\x98\x91", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xad", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed99[] = {
+ "\xed\x99\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed9a[] = {
+ "\xed\x9a\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed9b[] = {
+ "\xed\x9b\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed9c[] = {
+ "\xed\x9c\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b8_table_ed9d[] = {
+ "\xed\x9d\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xbd"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186b8(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b8_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x99";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eab0[] = {
+ "\xea\xb0\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eab1[] = {
+ "\xea\xb1\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eab2[] = {
+ "\xea\xb2\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eab3[] = {
+ "\xea\xb3\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eab4[] = {
+ "\xea\xb4\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eab5[] = {
+ "\xea\xb5\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eab6[] = {
+ "\xea\xb6\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eab7[] = {
+ "\xea\xb7\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eab8[] = {
+ "\xea\xb8\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eab9[] = {
+ "\xea\xb9\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eaba[] = {
+ "\xea\xba\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eabb[] = {
+ "\xea\xbb\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eabc[] = {
+ "\xea\xbc\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eabd[] = {
+ "\xea\xbd\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eabe[] = {
+ "\xea\xbe\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eabf[] = {
+ "\xea\xbf\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb80[] = {
+ "\xeb\x80\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb81[] = {
+ "\xeb\x81\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb82[] = {
+ "\xeb\x82\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb83[] = {
+ "\xeb\x83\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb84[] = {
+ "\xeb\x84\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb85[] = {
+ "\xeb\x85\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb86[] = {
+ "\xeb\x86\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb87[] = {
+ "\xeb\x87\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb88[] = {
+ "\xeb\x88\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb89[] = {
+ "\xeb\x89\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb8a[] = {
+ "\xeb\x8a\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb8b[] = {
+ "\xeb\x8b\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb8c[] = {
+ "\xeb\x8c\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb8d[] = {
+ "\xeb\x8d\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb8e[] = {
+ "\xeb\x8e\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb8f[] = {
+ "\xeb\x8f\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb90[] = {
+ "\xeb\x90\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb91[] = {
+ "\xeb\x91\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb92[] = {
+ "\xeb\x92\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb93[] = {
+ "\xeb\x93\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb94[] = {
+ "\xeb\x94\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb95[] = {
+ "\xeb\x95\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb96[] = {
+ "\xeb\x96\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb97[] = {
+ "\xeb\x97\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb98[] = {
+ "\xeb\x98\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb99[] = {
+ "\xeb\x99\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb9a[] = {
+ "\xeb\x9a\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb9b[] = {
+ "\xeb\x9b\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb9c[] = {
+ "\xeb\x9c\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb9d[] = {
+ "\xeb\x9d\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb9e[] = {
+ "\xeb\x9e\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eb9f[] = {
+ "\xeb\x9f\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eba0[] = {
+ "\xeb\xa0\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eba1[] = {
+ "\xeb\xa1\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eba2[] = {
+ "\xeb\xa2\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eba3[] = {
+ "\xeb\xa3\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eba4[] = {
+ "\xeb\xa4\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eba5[] = {
+ "\xeb\xa5\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eba6[] = {
+ "\xeb\xa6\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eba7[] = {
+ "\xeb\xa7\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eba8[] = {
+ "\xeb\xa8\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eba9[] = {
+ "\xeb\xa9\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebaa[] = {
+ "\xeb\xaa\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebab[] = {
+ "\xeb\xab\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebac[] = {
+ "\xeb\xac\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebad[] = {
+ "\xeb\xad\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebae[] = {
+ "\xeb\xae\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebaf[] = {
+ "\xeb\xaf\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebb0[] = {
+ "\xeb\xb0\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebb1[] = {
+ "\xeb\xb1\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebb2[] = {
+ "\xeb\xb2\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebb3[] = {
+ "\xeb\xb3\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebb4[] = {
+ "\xeb\xb4\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebb5[] = {
+ "\xeb\xb5\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebb6[] = {
+ "\xeb\xb6\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebb7[] = {
+ "\xeb\xb7\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebb8[] = {
+ "\xeb\xb8\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebb9[] = {
+ "\xeb\xb9\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebba[] = {
+ "\xeb\xba\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebbb[] = {
+ "\xeb\xbb\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebbc[] = {
+ "\xeb\xbc\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebbd[] = {
+ "\xeb\xbd\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebbe[] = {
+ "\xeb\xbe\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ebbf[] = {
+ "\xeb\xbf\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec80[] = {
+ "\xec\x80\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec81[] = {
+ "\xec\x81\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec82[] = {
+ "\xec\x82\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec83[] = {
+ "\xec\x83\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec84[] = {
+ "\xec\x84\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec85[] = {
+ "\xec\x85\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec86[] = {
+ "\xec\x86\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec87[] = {
+ "\xec\x87\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec88[] = {
+ "\xec\x88\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec89[] = {
+ "\xec\x89\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec8a[] = {
+ "\xec\x8a\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec8b[] = {
+ "\xec\x8b\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec8c[] = {
+ "\xec\x8c\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec8d[] = {
+ "\xec\x8d\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec8e[] = {
+ "\xec\x8e\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec8f[] = {
+ "\xec\x8f\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec90[] = {
+ "\xec\x90\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec91[] = {
+ "\xec\x91\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec92[] = {
+ "\xec\x92\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec93[] = {
+ "\xec\x93\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec94[] = {
+ "\xec\x94\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec95[] = {
+ "\xec\x95\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec96[] = {
+ "\xec\x96\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec97[] = {
+ "\xec\x97\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec98[] = {
+ "\xec\x98\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec99[] = {
+ "\xec\x99\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec9a[] = {
+ "\xec\x9a\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec9b[] = {
+ "\xec\x9b\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec9c[] = {
+ "\xec\x9c\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec9d[] = {
+ "\xec\x9d\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec9e[] = {
+ "\xec\x9e\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ec9f[] = {
+ "\xec\x9f\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eca0[] = {
+ "\xec\xa0\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eca1[] = {
+ "\xec\xa1\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eca2[] = {
+ "\xec\xa2\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eca3[] = {
+ "\xec\xa3\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eca4[] = {
+ "\xec\xa4\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eca5[] = {
+ "\xec\xa5\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eca6[] = {
+ "\xec\xa6\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eca7[] = {
+ "\xec\xa7\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eca8[] = {
+ "\xec\xa8\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_eca9[] = {
+ "\xec\xa9\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecaa[] = {
+ "\xec\xaa\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecab[] = {
+ "\xec\xab\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecac[] = {
+ "\xec\xac\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecad[] = {
+ "\xec\xad\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecae[] = {
+ "\xec\xae\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecaf[] = {
+ "\xec\xaf\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecb0[] = {
+ "\xec\xb0\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecb1[] = {
+ "\xec\xb1\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecb2[] = {
+ "\xec\xb2\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecb3[] = {
+ "\xec\xb3\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecb4[] = {
+ "\xec\xb4\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecb5[] = {
+ "\xec\xb5\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecb6[] = {
+ "\xec\xb6\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecb7[] = {
+ "\xec\xb7\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecb8[] = {
+ "\xec\xb8\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecb9[] = {
+ "\xec\xb9\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecba[] = {
+ "\xec\xba\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecbb[] = {
+ "\xec\xbb\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecbc[] = {
+ "\xec\xbc\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecbd[] = {
+ "\xec\xbd\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecbe[] = {
+ "\xec\xbe\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ecbf[] = {
+ "\xec\xbf\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed80[] = {
+ "\xed\x80\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed81[] = {
+ "\xed\x81\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed82[] = {
+ "\xed\x82\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed83[] = {
+ "\xed\x83\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed84[] = {
+ "\xed\x84\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed85[] = {
+ "\xed\x85\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed86[] = {
+ "\xed\x86\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed87[] = {
+ "\xed\x87\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed88[] = {
+ "\xed\x88\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed89[] = {
+ "\xed\x89\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed8a[] = {
+ "\xed\x8a\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed8b[] = {
+ "\xed\x8b\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed8c[] = {
+ "\xed\x8c\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed8d[] = {
+ "\xed\x8d\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed8e[] = {
+ "\xed\x8e\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed8f[] = {
+ "\xed\x8f\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed90[] = {
+ "\xed\x90\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed91[] = {
+ "\xed\x91\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed92[] = {
+ "\xed\x92\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed93[] = {
+ "\xed\x93\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed94[] = {
+ "\xed\x94\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed95[] = {
+ "\xed\x95\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed96[] = {
+ "\xed\x96\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed97[] = {
+ "\xed\x97\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xb6"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed98[] = {
+ "\xed\x98\x92", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xae", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed99[] = {
+ "\xed\x99\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed9a[] = {
+ "\xed\x9a\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed9b[] = {
+ "\xed\x9b\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed9c[] = {
+ "\xed\x9c\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186b9_table_ed9d[] = {
+ "\xed\x9d\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xbe"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186b9(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186b9_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x9a";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eab0[] = {
+ "\xea\xb0\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eab1[] = {
+ "\xea\xb1\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eab2[] = {
+ "\xea\xb2\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eab3[] = {
+ "\xea\xb3\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eab4[] = {
+ "\xea\xb4\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eab5[] = {
+ "\xea\xb5\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eab6[] = {
+ "\xea\xb6\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eab7[] = {
+ "\xea\xb7\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eab8[] = {
+ "\xea\xb8\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eab9[] = {
+ "\xea\xb9\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eaba[] = {
+ "\xea\xba\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eabb[] = {
+ "\xea\xbb\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eabc[] = {
+ "\xea\xbc\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eabd[] = {
+ "\xea\xbd\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eabe[] = {
+ "\xea\xbe\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eabf[] = {
+ "\xea\xbf\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb80[] = {
+ "\xeb\x80\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb81[] = {
+ "\xeb\x81\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb82[] = {
+ "\xeb\x82\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb83[] = {
+ "\xeb\x83\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb84[] = {
+ "\xeb\x84\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb85[] = {
+ "\xeb\x85\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb86[] = {
+ "\xeb\x86\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb87[] = {
+ "\xeb\x87\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb88[] = {
+ "\xeb\x88\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb89[] = {
+ "\xeb\x89\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb8a[] = {
+ "\xeb\x8a\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb8b[] = {
+ "\xeb\x8b\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb8c[] = {
+ "\xeb\x8c\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb8d[] = {
+ "\xeb\x8d\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb8e[] = {
+ "\xeb\x8e\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb8f[] = {
+ "\xeb\x8f\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb90[] = {
+ "\xeb\x90\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb91[] = {
+ "\xeb\x91\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb92[] = {
+ "\xeb\x92\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb93[] = {
+ "\xeb\x93\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb94[] = {
+ "\xeb\x94\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb95[] = {
+ "\xeb\x95\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb96[] = {
+ "\xeb\x96\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb97[] = {
+ "\xeb\x97\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb98[] = {
+ "\xeb\x98\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb99[] = {
+ "\xeb\x99\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb9a[] = {
+ "\xeb\x9a\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb9b[] = {
+ "\xeb\x9b\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb9c[] = {
+ "\xeb\x9c\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb9d[] = {
+ "\xeb\x9d\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb9e[] = {
+ "\xeb\x9e\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eb9f[] = {
+ "\xeb\x9f\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eba0[] = {
+ "\xeb\xa0\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eba1[] = {
+ "\xeb\xa1\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eba2[] = {
+ "\xeb\xa2\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eba3[] = {
+ "\xeb\xa3\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eba4[] = {
+ "\xeb\xa4\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eba5[] = {
+ "\xeb\xa5\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eba6[] = {
+ "\xeb\xa6\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eba7[] = {
+ "\xeb\xa7\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eba8[] = {
+ "\xeb\xa8\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eba9[] = {
+ "\xeb\xa9\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebaa[] = {
+ "\xeb\xaa\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebab[] = {
+ "\xeb\xab\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebac[] = {
+ "\xeb\xac\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebad[] = {
+ "\xeb\xad\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebae[] = {
+ "\xeb\xae\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebaf[] = {
+ "\xeb\xaf\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebb0[] = {
+ "\xeb\xb0\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebb1[] = {
+ "\xeb\xb1\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebb2[] = {
+ "\xeb\xb2\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebb3[] = {
+ "\xeb\xb3\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebb4[] = {
+ "\xeb\xb4\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebb5[] = {
+ "\xeb\xb5\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebb6[] = {
+ "\xeb\xb6\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebb7[] = {
+ "\xeb\xb7\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebb8[] = {
+ "\xeb\xb8\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebb9[] = {
+ "\xeb\xb9\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebba[] = {
+ "\xeb\xba\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebbb[] = {
+ "\xeb\xbb\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebbc[] = {
+ "\xeb\xbc\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebbd[] = {
+ "\xeb\xbd\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebbe[] = {
+ "\xeb\xbe\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ebbf[] = {
+ "\xeb\xbf\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec80[] = {
+ "\xec\x80\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec81[] = {
+ "\xec\x81\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec82[] = {
+ "\xec\x82\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec83[] = {
+ "\xec\x83\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec84[] = {
+ "\xec\x84\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec85[] = {
+ "\xec\x85\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec86[] = {
+ "\xec\x86\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec87[] = {
+ "\xec\x87\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec88[] = {
+ "\xec\x88\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec89[] = {
+ "\xec\x89\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec8a[] = {
+ "\xec\x8a\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec8b[] = {
+ "\xec\x8b\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec8c[] = {
+ "\xec\x8c\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec8d[] = {
+ "\xec\x8d\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec8e[] = {
+ "\xec\x8e\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec8f[] = {
+ "\xec\x8f\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec90[] = {
+ "\xec\x90\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec91[] = {
+ "\xec\x91\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec92[] = {
+ "\xec\x92\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec93[] = {
+ "\xec\x93\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec94[] = {
+ "\xec\x94\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec95[] = {
+ "\xec\x95\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec96[] = {
+ "\xec\x96\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec97[] = {
+ "\xec\x97\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec98[] = {
+ "\xec\x98\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec99[] = {
+ "\xec\x99\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec9a[] = {
+ "\xec\x9a\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec9b[] = {
+ "\xec\x9b\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec9c[] = {
+ "\xec\x9c\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec9d[] = {
+ "\xec\x9d\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec9e[] = {
+ "\xec\x9e\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ec9f[] = {
+ "\xec\x9f\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eca0[] = {
+ "\xec\xa0\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eca1[] = {
+ "\xec\xa1\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eca2[] = {
+ "\xec\xa2\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eca3[] = {
+ "\xec\xa3\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eca4[] = {
+ "\xec\xa4\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eca5[] = {
+ "\xec\xa5\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eca6[] = {
+ "\xec\xa6\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eca7[] = {
+ "\xec\xa7\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eca8[] = {
+ "\xec\xa8\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_eca9[] = {
+ "\xec\xa9\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecaa[] = {
+ "\xec\xaa\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecab[] = {
+ "\xec\xab\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecac[] = {
+ "\xec\xac\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecad[] = {
+ "\xec\xad\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecae[] = {
+ "\xec\xae\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecaf[] = {
+ "\xec\xaf\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecb0[] = {
+ "\xec\xb0\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecb1[] = {
+ "\xec\xb1\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecb2[] = {
+ "\xec\xb2\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecb3[] = {
+ "\xec\xb3\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecb4[] = {
+ "\xec\xb4\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecb5[] = {
+ "\xec\xb5\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecb6[] = {
+ "\xec\xb6\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecb7[] = {
+ "\xec\xb7\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecb8[] = {
+ "\xec\xb8\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecb9[] = {
+ "\xec\xb9\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecba[] = {
+ "\xec\xba\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecbb[] = {
+ "\xec\xbb\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecbc[] = {
+ "\xec\xbc\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecbd[] = {
+ "\xec\xbd\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecbe[] = {
+ "\xec\xbe\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ecbf[] = {
+ "\xec\xbf\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed80[] = {
+ "\xed\x80\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed81[] = {
+ "\xed\x81\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed82[] = {
+ "\xed\x82\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed83[] = {
+ "\xed\x83\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed84[] = {
+ "\xed\x84\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed85[] = {
+ "\xed\x85\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed86[] = {
+ "\xed\x86\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed87[] = {
+ "\xed\x87\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed88[] = {
+ "\xed\x88\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed89[] = {
+ "\xed\x89\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed8a[] = {
+ "\xed\x8a\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed8b[] = {
+ "\xed\x8b\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed8c[] = {
+ "\xed\x8c\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed8d[] = {
+ "\xed\x8d\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed8e[] = {
+ "\xed\x8e\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed8f[] = {
+ "\xed\x8f\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed90[] = {
+ "\xed\x90\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed91[] = {
+ "\xed\x91\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed92[] = {
+ "\xed\x92\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed93[] = {
+ "\xed\x93\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed94[] = {
+ "\xed\x94\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed95[] = {
+ "\xed\x95\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed96[] = {
+ "\xed\x96\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed97[] = {
+ "\xed\x97\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xb7"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed98[] = {
+ "\xed\x98\x93", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xaf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed99[] = {
+ "\xed\x99\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed9a[] = {
+ "\xed\x9a\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed9b[] = {
+ "\xed\x9b\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed9c[] = {
+ "\xed\x9c\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186ba_table_ed9d[] = {
+ "\xed\x9d\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\xbf"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186ba(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186ba_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x9b";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eab0[] = {
+ "\xea\xb0\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eab1[] = {
+ "\xea\xb1\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eab2[] = {
+ "\xea\xb2\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eab3[] = {
+ "\xea\xb3\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eab4[] = {
+ "\xea\xb4\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eab5[] = {
+ "\xea\xb5\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eab6[] = {
+ "\xea\xb6\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eab7[] = {
+ "\xea\xb7\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eab8[] = {
+ "\xea\xb8\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eab9[] = {
+ "\xea\xb9\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eaba[] = {
+ "\xea\xba\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eabb[] = {
+ "\xea\xbb\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eabc[] = {
+ "\xea\xbc\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eabd[] = {
+ "\xea\xbd\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eabe[] = {
+ "\xea\xbe\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eabf[] = {
+ "\xea\xbf\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb80[] = {
+ "\xeb\x80\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb81[] = {
+ "\xeb\x81\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb82[] = {
+ "\xeb\x82\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb83[] = {
+ "\xeb\x83\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb84[] = {
+ "\xeb\x84\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb85[] = {
+ "\xeb\x85\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb86[] = {
+ "\xeb\x86\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb87[] = {
+ "\xeb\x87\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb88[] = {
+ "\xeb\x88\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb89[] = {
+ "\xeb\x89\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb8a[] = {
+ "\xeb\x8a\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb8b[] = {
+ "\xeb\x8b\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb8c[] = {
+ "\xeb\x8c\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb8d[] = {
+ "\xeb\x8d\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb8e[] = {
+ "\xeb\x8e\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb8f[] = {
+ "\xeb\x8f\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb90[] = {
+ "\xeb\x90\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb91[] = {
+ "\xeb\x91\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb92[] = {
+ "\xeb\x92\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb93[] = {
+ "\xeb\x93\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb94[] = {
+ "\xeb\x94\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb95[] = {
+ "\xeb\x95\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb96[] = {
+ "\xeb\x96\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb97[] = {
+ "\xeb\x97\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb98[] = {
+ "\xeb\x98\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb99[] = {
+ "\xeb\x99\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb9a[] = {
+ "\xeb\x9a\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb9b[] = {
+ "\xeb\x9b\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb9c[] = {
+ "\xeb\x9c\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb9d[] = {
+ "\xeb\x9d\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb9e[] = {
+ "\xeb\x9e\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eb9f[] = {
+ "\xeb\x9f\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eba0[] = {
+ "\xeb\xa0\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eba1[] = {
+ "\xeb\xa1\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eba2[] = {
+ "\xeb\xa2\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eba3[] = {
+ "\xeb\xa3\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eba4[] = {
+ "\xeb\xa4\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eba5[] = {
+ "\xeb\xa5\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eba6[] = {
+ "\xeb\xa6\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eba7[] = {
+ "\xeb\xa7\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eba8[] = {
+ "\xeb\xa8\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eba9[] = {
+ "\xeb\xa9\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebaa[] = {
+ "\xeb\xaa\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebab[] = {
+ "\xeb\xab\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebac[] = {
+ "\xeb\xac\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebad[] = {
+ "\xeb\xad\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebae[] = {
+ "\xeb\xae\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebaf[] = {
+ "\xeb\xaf\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebb0[] = {
+ "\xeb\xb0\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebb1[] = {
+ "\xeb\xb1\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebb2[] = {
+ "\xeb\xb2\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebb3[] = {
+ "\xeb\xb3\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebb4[] = {
+ "\xeb\xb4\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebb5[] = {
+ "\xeb\xb5\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebb6[] = {
+ "\xeb\xb6\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebb7[] = {
+ "\xeb\xb7\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebb8[] = {
+ "\xeb\xb8\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebb9[] = {
+ "\xeb\xb9\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebba[] = {
+ "\xeb\xba\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebbb[] = {
+ "\xeb\xbb\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebbc[] = {
+ "\xeb\xbc\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebbd[] = {
+ "\xeb\xbd\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebbe[] = {
+ "\xeb\xbe\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ebbf[] = {
+ "\xeb\xbf\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec80[] = {
+ "\xec\x80\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec81[] = {
+ "\xec\x81\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec82[] = {
+ "\xec\x82\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec83[] = {
+ "\xec\x83\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec84[] = {
+ "\xec\x84\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec85[] = {
+ "\xec\x85\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec86[] = {
+ "\xec\x86\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec87[] = {
+ "\xec\x87\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec88[] = {
+ "\xec\x88\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec89[] = {
+ "\xec\x89\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec8a[] = {
+ "\xec\x8a\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec8b[] = {
+ "\xec\x8b\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec8c[] = {
+ "\xec\x8c\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec8d[] = {
+ "\xec\x8d\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec8e[] = {
+ "\xec\x8e\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec8f[] = {
+ "\xec\x8f\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec90[] = {
+ "\xec\x90\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec91[] = {
+ "\xec\x91\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec92[] = {
+ "\xec\x92\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec93[] = {
+ "\xec\x93\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec94[] = {
+ "\xec\x94\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec95[] = {
+ "\xec\x95\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec96[] = {
+ "\xec\x96\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec97[] = {
+ "\xec\x97\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec98[] = {
+ "\xec\x98\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec99[] = {
+ "\xec\x99\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec9a[] = {
+ "\xec\x9a\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec9b[] = {
+ "\xec\x9b\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec9c[] = {
+ "\xec\x9c\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec9d[] = {
+ "\xec\x9d\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec9e[] = {
+ "\xec\x9e\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ec9f[] = {
+ "\xec\x9f\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eca0[] = {
+ "\xec\xa0\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eca1[] = {
+ "\xec\xa1\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eca2[] = {
+ "\xec\xa2\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eca3[] = {
+ "\xec\xa3\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eca4[] = {
+ "\xec\xa4\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eca5[] = {
+ "\xec\xa5\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eca6[] = {
+ "\xec\xa6\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eca7[] = {
+ "\xec\xa7\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eca8[] = {
+ "\xec\xa8\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_eca9[] = {
+ "\xec\xa9\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecaa[] = {
+ "\xec\xaa\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecab[] = {
+ "\xec\xab\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecac[] = {
+ "\xec\xac\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecad[] = {
+ "\xec\xad\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecae[] = {
+ "\xec\xae\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecaf[] = {
+ "\xec\xaf\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecb0[] = {
+ "\xec\xb0\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecb1[] = {
+ "\xec\xb1\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecb2[] = {
+ "\xec\xb2\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecb3[] = {
+ "\xec\xb3\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecb4[] = {
+ "\xec\xb4\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecb5[] = {
+ "\xec\xb5\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecb6[] = {
+ "\xec\xb6\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecb7[] = {
+ "\xec\xb7\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecb8[] = {
+ "\xec\xb8\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecb9[] = {
+ "\xec\xb9\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecba[] = {
+ "\xec\xba\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecbb[] = {
+ "\xec\xbb\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecbc[] = {
+ "\xec\xbc\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecbd[] = {
+ "\xec\xbd\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecbe[] = {
+ "\xec\xbe\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ecbf[] = {
+ "\xec\xbf\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed80[] = {
+ "\xed\x80\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed81[] = {
+ "\xed\x81\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed82[] = {
+ "\xed\x82\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed83[] = {
+ "\xed\x83\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed84[] = {
+ "\xed\x84\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed85[] = {
+ "\xed\x85\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed86[] = {
+ "\xed\x86\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed87[] = {
+ "\xed\x87\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed88[] = {
+ "\xed\x88\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed89[] = {
+ "\xed\x89\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed8a[] = {
+ "\xed\x8a\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed8b[] = {
+ "\xed\x8b\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed8c[] = {
+ "\xed\x8c\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed8d[] = {
+ "\xed\x8d\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed8e[] = {
+ "\xed\x8e\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed8f[] = {
+ "\xed\x8f\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed90[] = {
+ "\xed\x90\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed91[] = {
+ "\xed\x91\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed92[] = {
+ "\xed\x92\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed93[] = {
+ "\xed\x93\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed94[] = {
+ "\xed\x94\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed95[] = {
+ "\xed\x95\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed96[] = {
+ "\xed\x96\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed97[] = {
+ "\xed\x97\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xb8"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed98[] = {
+ "\xed\x98\x94", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xb0", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed99[] = {
+ "\xed\x99\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed9a[] = {
+ "\xed\x9a\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed9b[] = {
+ "\xed\x9b\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed9c[] = {
+ "\xed\x9c\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bb_table_ed9d[] = {
+ "\xed\x9d\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9e\x80"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186bb(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bb_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x9c";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eab0[] = {
+ "\xea\xb0\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eab1[] = {
+ "\xea\xb1\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eab2[] = {
+ "\xea\xb2\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eab3[] = {
+ "\xea\xb3\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eab4[] = {
+ "\xea\xb4\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eab5[] = {
+ "\xea\xb5\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eab6[] = {
+ "\xea\xb6\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eab7[] = {
+ "\xea\xb7\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eab8[] = {
+ "\xea\xb8\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eab9[] = {
+ "\xea\xb9\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eaba[] = {
+ "\xea\xba\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eabb[] = {
+ "\xea\xbb\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eabc[] = {
+ "\xea\xbc\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eabd[] = {
+ "\xea\xbd\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eabe[] = {
+ "\xea\xbe\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eabf[] = {
+ "\xea\xbf\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb80[] = {
+ "\xeb\x80\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb81[] = {
+ "\xeb\x81\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb82[] = {
+ "\xeb\x82\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb83[] = {
+ "\xeb\x83\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb84[] = {
+ "\xeb\x84\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb85[] = {
+ "\xeb\x85\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb86[] = {
+ "\xeb\x86\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb87[] = {
+ "\xeb\x87\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb88[] = {
+ "\xeb\x88\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb89[] = {
+ "\xeb\x89\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb8a[] = {
+ "\xeb\x8a\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb8b[] = {
+ "\xeb\x8b\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb8c[] = {
+ "\xeb\x8c\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb8d[] = {
+ "\xeb\x8d\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb8e[] = {
+ "\xeb\x8e\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb8f[] = {
+ "\xeb\x8f\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb90[] = {
+ "\xeb\x90\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb91[] = {
+ "\xeb\x91\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb92[] = {
+ "\xeb\x92\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb93[] = {
+ "\xeb\x93\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb94[] = {
+ "\xeb\x94\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb95[] = {
+ "\xeb\x95\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb96[] = {
+ "\xeb\x96\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb97[] = {
+ "\xeb\x97\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb98[] = {
+ "\xeb\x98\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb99[] = {
+ "\xeb\x99\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb9a[] = {
+ "\xeb\x9a\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb9b[] = {
+ "\xeb\x9b\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb9c[] = {
+ "\xeb\x9c\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb9d[] = {
+ "\xeb\x9d\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb9e[] = {
+ "\xeb\x9e\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eb9f[] = {
+ "\xeb\x9f\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eba0[] = {
+ "\xeb\xa0\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eba1[] = {
+ "\xeb\xa1\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eba2[] = {
+ "\xeb\xa2\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eba3[] = {
+ "\xeb\xa3\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eba4[] = {
+ "\xeb\xa4\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eba5[] = {
+ "\xeb\xa5\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eba6[] = {
+ "\xeb\xa6\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eba7[] = {
+ "\xeb\xa7\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eba8[] = {
+ "\xeb\xa8\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eba9[] = {
+ "\xeb\xa9\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebaa[] = {
+ "\xeb\xaa\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebab[] = {
+ "\xeb\xab\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebac[] = {
+ "\xeb\xac\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebad[] = {
+ "\xeb\xad\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebae[] = {
+ "\xeb\xae\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebaf[] = {
+ "\xeb\xaf\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebb0[] = {
+ "\xeb\xb0\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebb1[] = {
+ "\xeb\xb1\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebb2[] = {
+ "\xeb\xb2\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebb3[] = {
+ "\xeb\xb3\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebb4[] = {
+ "\xeb\xb4\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebb5[] = {
+ "\xeb\xb5\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebb6[] = {
+ "\xeb\xb6\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebb7[] = {
+ "\xeb\xb7\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebb8[] = {
+ "\xeb\xb8\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebb9[] = {
+ "\xeb\xb9\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebba[] = {
+ "\xeb\xba\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebbb[] = {
+ "\xeb\xbb\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebbc[] = {
+ "\xeb\xbc\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebbd[] = {
+ "\xeb\xbd\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebbe[] = {
+ "\xeb\xbe\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ebbf[] = {
+ "\xeb\xbf\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec80[] = {
+ "\xec\x80\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec81[] = {
+ "\xec\x81\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec82[] = {
+ "\xec\x82\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec83[] = {
+ "\xec\x83\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec84[] = {
+ "\xec\x84\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec85[] = {
+ "\xec\x85\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec86[] = {
+ "\xec\x86\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec87[] = {
+ "\xec\x87\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec88[] = {
+ "\xec\x88\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec89[] = {
+ "\xec\x89\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec8a[] = {
+ "\xec\x8a\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec8b[] = {
+ "\xec\x8b\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec8c[] = {
+ "\xec\x8c\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec8d[] = {
+ "\xec\x8d\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec8e[] = {
+ "\xec\x8e\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec8f[] = {
+ "\xec\x8f\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec90[] = {
+ "\xec\x90\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec91[] = {
+ "\xec\x91\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec92[] = {
+ "\xec\x92\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec93[] = {
+ "\xec\x93\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec94[] = {
+ "\xec\x94\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec95[] = {
+ "\xec\x95\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec96[] = {
+ "\xec\x96\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec97[] = {
+ "\xec\x97\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec98[] = {
+ "\xec\x98\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec99[] = {
+ "\xec\x99\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec9a[] = {
+ "\xec\x9a\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec9b[] = {
+ "\xec\x9b\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec9c[] = {
+ "\xec\x9c\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec9d[] = {
+ "\xec\x9d\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec9e[] = {
+ "\xec\x9e\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ec9f[] = {
+ "\xec\x9f\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eca0[] = {
+ "\xec\xa0\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eca1[] = {
+ "\xec\xa1\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eca2[] = {
+ "\xec\xa2\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eca3[] = {
+ "\xec\xa3\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eca4[] = {
+ "\xec\xa4\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eca5[] = {
+ "\xec\xa5\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eca6[] = {
+ "\xec\xa6\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eca7[] = {
+ "\xec\xa7\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eca8[] = {
+ "\xec\xa8\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_eca9[] = {
+ "\xec\xa9\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecaa[] = {
+ "\xec\xaa\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecab[] = {
+ "\xec\xab\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecac[] = {
+ "\xec\xac\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecad[] = {
+ "\xec\xad\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecae[] = {
+ "\xec\xae\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecaf[] = {
+ "\xec\xaf\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecb0[] = {
+ "\xec\xb0\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecb1[] = {
+ "\xec\xb1\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecb2[] = {
+ "\xec\xb2\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecb3[] = {
+ "\xec\xb3\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecb4[] = {
+ "\xec\xb4\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecb5[] = {
+ "\xec\xb5\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecb6[] = {
+ "\xec\xb6\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecb7[] = {
+ "\xec\xb7\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecb8[] = {
+ "\xec\xb8\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecb9[] = {
+ "\xec\xb9\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecba[] = {
+ "\xec\xba\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecbb[] = {
+ "\xec\xbb\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecbc[] = {
+ "\xec\xbc\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecbd[] = {
+ "\xec\xbd\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecbe[] = {
+ "\xec\xbe\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ecbf[] = {
+ "\xec\xbf\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed80[] = {
+ "\xed\x80\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed81[] = {
+ "\xed\x81\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed82[] = {
+ "\xed\x82\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed83[] = {
+ "\xed\x83\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed84[] = {
+ "\xed\x84\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed85[] = {
+ "\xed\x85\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed86[] = {
+ "\xed\x86\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed87[] = {
+ "\xed\x87\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed88[] = {
+ "\xed\x88\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed89[] = {
+ "\xed\x89\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed8a[] = {
+ "\xed\x8a\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed8b[] = {
+ "\xed\x8b\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed8c[] = {
+ "\xed\x8c\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed8d[] = {
+ "\xed\x8d\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed8e[] = {
+ "\xed\x8e\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed8f[] = {
+ "\xed\x8f\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed90[] = {
+ "\xed\x90\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed91[] = {
+ "\xed\x91\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed92[] = {
+ "\xed\x92\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed93[] = {
+ "\xed\x93\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed94[] = {
+ "\xed\x94\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed95[] = {
+ "\xed\x95\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed96[] = {
+ "\xed\x96\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed97[] = {
+ "\xed\x97\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xb9"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed98[] = {
+ "\xed\x98\x95", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xb1", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed99[] = {
+ "\xed\x99\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed9a[] = {
+ "\xed\x9a\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed9b[] = {
+ "\xed\x9b\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed9c[] = {
+ "\xed\x9c\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bc_table_ed9d[] = {
+ "\xed\x9d\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9e\x81"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186bc(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bc_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x9d";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eab0[] = {
+ "\xea\xb0\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eab1[] = {
+ "\xea\xb1\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eab2[] = {
+ "\xea\xb2\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eab3[] = {
+ "\xea\xb3\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eab4[] = {
+ "\xea\xb4\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eab5[] = {
+ "\xea\xb5\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eab6[] = {
+ "\xea\xb6\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eab7[] = {
+ "\xea\xb7\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eab8[] = {
+ "\xea\xb8\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eab9[] = {
+ "\xea\xb9\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eaba[] = {
+ "\xea\xba\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eabb[] = {
+ "\xea\xbb\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eabc[] = {
+ "\xea\xbc\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eabd[] = {
+ "\xea\xbd\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eabe[] = {
+ "\xea\xbe\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eabf[] = {
+ "\xea\xbf\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb80[] = {
+ "\xeb\x80\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb81[] = {
+ "\xeb\x81\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb82[] = {
+ "\xeb\x82\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb83[] = {
+ "\xeb\x83\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb84[] = {
+ "\xeb\x84\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb85[] = {
+ "\xeb\x85\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb86[] = {
+ "\xeb\x86\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb87[] = {
+ "\xeb\x87\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb88[] = {
+ "\xeb\x88\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb89[] = {
+ "\xeb\x89\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb8a[] = {
+ "\xeb\x8a\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb8b[] = {
+ "\xeb\x8b\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb8c[] = {
+ "\xeb\x8c\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb8d[] = {
+ "\xeb\x8d\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb8e[] = {
+ "\xeb\x8e\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb8f[] = {
+ "\xeb\x8f\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb90[] = {
+ "\xeb\x90\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb91[] = {
+ "\xeb\x91\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb92[] = {
+ "\xeb\x92\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb93[] = {
+ "\xeb\x93\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb94[] = {
+ "\xeb\x94\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb95[] = {
+ "\xeb\x95\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb96[] = {
+ "\xeb\x96\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb97[] = {
+ "\xeb\x97\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb98[] = {
+ "\xeb\x98\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb99[] = {
+ "\xeb\x99\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb9a[] = {
+ "\xeb\x9a\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb9b[] = {
+ "\xeb\x9b\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb9c[] = {
+ "\xeb\x9c\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb9d[] = {
+ "\xeb\x9d\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb9e[] = {
+ "\xeb\x9e\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eb9f[] = {
+ "\xeb\x9f\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eba0[] = {
+ "\xeb\xa0\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eba1[] = {
+ "\xeb\xa1\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eba2[] = {
+ "\xeb\xa2\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eba3[] = {
+ "\xeb\xa3\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eba4[] = {
+ "\xeb\xa4\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eba5[] = {
+ "\xeb\xa5\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eba6[] = {
+ "\xeb\xa6\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eba7[] = {
+ "\xeb\xa7\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eba8[] = {
+ "\xeb\xa8\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eba9[] = {
+ "\xeb\xa9\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebaa[] = {
+ "\xeb\xaa\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebab[] = {
+ "\xeb\xab\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebac[] = {
+ "\xeb\xac\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebad[] = {
+ "\xeb\xad\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebae[] = {
+ "\xeb\xae\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebaf[] = {
+ "\xeb\xaf\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebb0[] = {
+ "\xeb\xb0\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebb1[] = {
+ "\xeb\xb1\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebb2[] = {
+ "\xeb\xb2\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebb3[] = {
+ "\xeb\xb3\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebb4[] = {
+ "\xeb\xb4\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebb5[] = {
+ "\xeb\xb5\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebb6[] = {
+ "\xeb\xb6\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebb7[] = {
+ "\xeb\xb7\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebb8[] = {
+ "\xeb\xb8\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebb9[] = {
+ "\xeb\xb9\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebba[] = {
+ "\xeb\xba\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebbb[] = {
+ "\xeb\xbb\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebbc[] = {
+ "\xeb\xbc\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebbd[] = {
+ "\xeb\xbd\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebbe[] = {
+ "\xeb\xbe\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ebbf[] = {
+ "\xeb\xbf\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec80[] = {
+ "\xec\x80\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec81[] = {
+ "\xec\x81\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec82[] = {
+ "\xec\x82\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec83[] = {
+ "\xec\x83\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec84[] = {
+ "\xec\x84\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec85[] = {
+ "\xec\x85\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec86[] = {
+ "\xec\x86\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec87[] = {
+ "\xec\x87\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec88[] = {
+ "\xec\x88\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec89[] = {
+ "\xec\x89\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec8a[] = {
+ "\xec\x8a\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec8b[] = {
+ "\xec\x8b\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec8c[] = {
+ "\xec\x8c\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec8d[] = {
+ "\xec\x8d\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec8e[] = {
+ "\xec\x8e\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec8f[] = {
+ "\xec\x8f\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec90[] = {
+ "\xec\x90\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec91[] = {
+ "\xec\x91\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec92[] = {
+ "\xec\x92\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec93[] = {
+ "\xec\x93\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec94[] = {
+ "\xec\x94\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec95[] = {
+ "\xec\x95\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec96[] = {
+ "\xec\x96\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec97[] = {
+ "\xec\x97\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec98[] = {
+ "\xec\x98\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec99[] = {
+ "\xec\x99\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec9a[] = {
+ "\xec\x9a\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec9b[] = {
+ "\xec\x9b\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec9c[] = {
+ "\xec\x9c\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec9d[] = {
+ "\xec\x9d\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec9e[] = {
+ "\xec\x9e\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ec9f[] = {
+ "\xec\x9f\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eca0[] = {
+ "\xec\xa0\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eca1[] = {
+ "\xec\xa1\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eca2[] = {
+ "\xec\xa2\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eca3[] = {
+ "\xec\xa3\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eca4[] = {
+ "\xec\xa4\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eca5[] = {
+ "\xec\xa5\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eca6[] = {
+ "\xec\xa6\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eca7[] = {
+ "\xec\xa7\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eca8[] = {
+ "\xec\xa8\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_eca9[] = {
+ "\xec\xa9\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecaa[] = {
+ "\xec\xaa\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecab[] = {
+ "\xec\xab\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecac[] = {
+ "\xec\xac\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecad[] = {
+ "\xec\xad\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecae[] = {
+ "\xec\xae\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecaf[] = {
+ "\xec\xaf\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecb0[] = {
+ "\xec\xb0\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecb1[] = {
+ "\xec\xb1\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecb2[] = {
+ "\xec\xb2\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecb3[] = {
+ "\xec\xb3\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecb4[] = {
+ "\xec\xb4\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecb5[] = {
+ "\xec\xb5\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecb6[] = {
+ "\xec\xb6\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecb7[] = {
+ "\xec\xb7\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecb8[] = {
+ "\xec\xb8\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecb9[] = {
+ "\xec\xb9\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecba[] = {
+ "\xec\xba\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecbb[] = {
+ "\xec\xbb\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecbc[] = {
+ "\xec\xbc\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecbd[] = {
+ "\xec\xbd\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecbe[] = {
+ "\xec\xbe\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ecbf[] = {
+ "\xec\xbf\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed80[] = {
+ "\xed\x80\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed81[] = {
+ "\xed\x81\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed82[] = {
+ "\xed\x82\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed83[] = {
+ "\xed\x83\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed84[] = {
+ "\xed\x84\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed85[] = {
+ "\xed\x85\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed86[] = {
+ "\xed\x86\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed87[] = {
+ "\xed\x87\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed88[] = {
+ "\xed\x88\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed89[] = {
+ "\xed\x89\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed8a[] = {
+ "\xed\x8a\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed8b[] = {
+ "\xed\x8b\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed8c[] = {
+ "\xed\x8c\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed8d[] = {
+ "\xed\x8d\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed8e[] = {
+ "\xed\x8e\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed8f[] = {
+ "\xed\x8f\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed90[] = {
+ "\xed\x90\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed91[] = {
+ "\xed\x91\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed92[] = {
+ "\xed\x92\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed93[] = {
+ "\xed\x93\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed94[] = {
+ "\xed\x94\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed95[] = {
+ "\xed\x95\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed96[] = {
+ "\xed\x96\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed97[] = {
+ "\xed\x97\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xba"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed98[] = {
+ "\xed\x98\x96", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xb2", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed99[] = {
+ "\xed\x99\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed9a[] = {
+ "\xed\x9a\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed9b[] = {
+ "\xed\x9b\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed9c[] = {
+ "\xed\x9c\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bd_table_ed9d[] = {
+ "\xed\x9d\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9e\x82"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186bd(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bd_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x9e";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eab0[] = {
+ "\xea\xb0\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eab1[] = {
+ "\xea\xb1\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eab2[] = {
+ "\xea\xb2\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eab3[] = {
+ "\xea\xb3\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eab4[] = {
+ "\xea\xb4\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eab5[] = {
+ "\xea\xb5\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eab6[] = {
+ "\xea\xb6\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eab7[] = {
+ "\xea\xb7\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eab8[] = {
+ "\xea\xb8\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eab9[] = {
+ "\xea\xb9\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eaba[] = {
+ "\xea\xba\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eabb[] = {
+ "\xea\xbb\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eabc[] = {
+ "\xea\xbc\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eabd[] = {
+ "\xea\xbd\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eabe[] = {
+ "\xea\xbe\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eabf[] = {
+ "\xea\xbf\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb80[] = {
+ "\xeb\x80\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb81[] = {
+ "\xeb\x81\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb82[] = {
+ "\xeb\x82\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb83[] = {
+ "\xeb\x83\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb84[] = {
+ "\xeb\x84\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb85[] = {
+ "\xeb\x85\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb86[] = {
+ "\xeb\x86\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb87[] = {
+ "\xeb\x87\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb88[] = {
+ "\xeb\x88\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb89[] = {
+ "\xeb\x89\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb8a[] = {
+ "\xeb\x8a\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb8b[] = {
+ "\xeb\x8b\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb8c[] = {
+ "\xeb\x8c\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb8d[] = {
+ "\xeb\x8d\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb8e[] = {
+ "\xeb\x8e\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb8f[] = {
+ "\xeb\x8f\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb90[] = {
+ "\xeb\x90\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb91[] = {
+ "\xeb\x91\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb92[] = {
+ "\xeb\x92\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb93[] = {
+ "\xeb\x93\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb94[] = {
+ "\xeb\x94\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb95[] = {
+ "\xeb\x95\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb96[] = {
+ "\xeb\x96\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb97[] = {
+ "\xeb\x97\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb98[] = {
+ "\xeb\x98\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb99[] = {
+ "\xeb\x99\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb9a[] = {
+ "\xeb\x9a\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb9b[] = {
+ "\xeb\x9b\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb9c[] = {
+ "\xeb\x9c\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb9d[] = {
+ "\xeb\x9d\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb9e[] = {
+ "\xeb\x9e\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eb9f[] = {
+ "\xeb\x9f\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eba0[] = {
+ "\xeb\xa0\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eba1[] = {
+ "\xeb\xa1\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eba2[] = {
+ "\xeb\xa2\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eba3[] = {
+ "\xeb\xa3\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eba4[] = {
+ "\xeb\xa4\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eba5[] = {
+ "\xeb\xa5\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eba6[] = {
+ "\xeb\xa6\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eba7[] = {
+ "\xeb\xa7\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eba8[] = {
+ "\xeb\xa8\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eba9[] = {
+ "\xeb\xa9\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebaa[] = {
+ "\xeb\xaa\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebab[] = {
+ "\xeb\xab\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebac[] = {
+ "\xeb\xac\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebad[] = {
+ "\xeb\xad\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebae[] = {
+ "\xeb\xae\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebaf[] = {
+ "\xeb\xaf\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebb0[] = {
+ "\xeb\xb0\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebb1[] = {
+ "\xeb\xb1\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebb2[] = {
+ "\xeb\xb2\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebb3[] = {
+ "\xeb\xb3\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebb4[] = {
+ "\xeb\xb4\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebb5[] = {
+ "\xeb\xb5\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebb6[] = {
+ "\xeb\xb6\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebb7[] = {
+ "\xeb\xb7\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebb8[] = {
+ "\xeb\xb8\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebb9[] = {
+ "\xeb\xb9\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebba[] = {
+ "\xeb\xba\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebbb[] = {
+ "\xeb\xbb\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebbc[] = {
+ "\xeb\xbc\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebbd[] = {
+ "\xeb\xbd\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebbe[] = {
+ "\xeb\xbe\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ebbf[] = {
+ "\xeb\xbf\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec80[] = {
+ "\xec\x80\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec81[] = {
+ "\xec\x81\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec82[] = {
+ "\xec\x82\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec83[] = {
+ "\xec\x83\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec84[] = {
+ "\xec\x84\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec85[] = {
+ "\xec\x85\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec86[] = {
+ "\xec\x86\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec87[] = {
+ "\xec\x87\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec88[] = {
+ "\xec\x88\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec89[] = {
+ "\xec\x89\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec8a[] = {
+ "\xec\x8a\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec8b[] = {
+ "\xec\x8b\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec8c[] = {
+ "\xec\x8c\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec8d[] = {
+ "\xec\x8d\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec8e[] = {
+ "\xec\x8e\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec8f[] = {
+ "\xec\x8f\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec90[] = {
+ "\xec\x90\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec91[] = {
+ "\xec\x91\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec92[] = {
+ "\xec\x92\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec93[] = {
+ "\xec\x93\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec94[] = {
+ "\xec\x94\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec95[] = {
+ "\xec\x95\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec96[] = {
+ "\xec\x96\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec97[] = {
+ "\xec\x97\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec98[] = {
+ "\xec\x98\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec99[] = {
+ "\xec\x99\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec9a[] = {
+ "\xec\x9a\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec9b[] = {
+ "\xec\x9b\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec9c[] = {
+ "\xec\x9c\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec9d[] = {
+ "\xec\x9d\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec9e[] = {
+ "\xec\x9e\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ec9f[] = {
+ "\xec\x9f\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eca0[] = {
+ "\xec\xa0\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eca1[] = {
+ "\xec\xa1\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eca2[] = {
+ "\xec\xa2\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eca3[] = {
+ "\xec\xa3\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eca4[] = {
+ "\xec\xa4\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eca5[] = {
+ "\xec\xa5\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eca6[] = {
+ "\xec\xa6\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eca7[] = {
+ "\xec\xa7\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eca8[] = {
+ "\xec\xa8\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_eca9[] = {
+ "\xec\xa9\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecaa[] = {
+ "\xec\xaa\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecab[] = {
+ "\xec\xab\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecac[] = {
+ "\xec\xac\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecad[] = {
+ "\xec\xad\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecae[] = {
+ "\xec\xae\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecaf[] = {
+ "\xec\xaf\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecb0[] = {
+ "\xec\xb0\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecb1[] = {
+ "\xec\xb1\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecb2[] = {
+ "\xec\xb2\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecb3[] = {
+ "\xec\xb3\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecb4[] = {
+ "\xec\xb4\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecb5[] = {
+ "\xec\xb5\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecb6[] = {
+ "\xec\xb6\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecb7[] = {
+ "\xec\xb7\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecb8[] = {
+ "\xec\xb8\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecb9[] = {
+ "\xec\xb9\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecba[] = {
+ "\xec\xba\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecbb[] = {
+ "\xec\xbb\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecbc[] = {
+ "\xec\xbc\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecbd[] = {
+ "\xec\xbd\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecbe[] = {
+ "\xec\xbe\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ecbf[] = {
+ "\xec\xbf\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed80[] = {
+ "\xed\x80\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed81[] = {
+ "\xed\x81\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed82[] = {
+ "\xed\x82\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed83[] = {
+ "\xed\x83\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed84[] = {
+ "\xed\x84\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed85[] = {
+ "\xed\x85\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed86[] = {
+ "\xed\x86\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed87[] = {
+ "\xed\x87\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed88[] = {
+ "\xed\x88\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed89[] = {
+ "\xed\x89\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed8a[] = {
+ "\xed\x8a\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed8b[] = {
+ "\xed\x8b\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed8c[] = {
+ "\xed\x8c\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed8d[] = {
+ "\xed\x8d\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed8e[] = {
+ "\xed\x8e\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed8f[] = {
+ "\xed\x8f\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed90[] = {
+ "\xed\x90\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed91[] = {
+ "\xed\x91\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed92[] = {
+ "\xed\x92\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed93[] = {
+ "\xed\x93\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed94[] = {
+ "\xed\x94\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed95[] = {
+ "\xed\x95\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed96[] = {
+ "\xed\x96\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed97[] = {
+ "\xed\x97\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xbb"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed98[] = {
+ "\xed\x98\x97", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xb3", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed99[] = {
+ "\xed\x99\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed9a[] = {
+ "\xed\x9a\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed9b[] = {
+ "\xed\x9b\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed9c[] = {
+ "\xed\x9c\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186be_table_ed9d[] = {
+ "\xed\x9d\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9e\x83"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186be(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186be_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\x9f";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eab0[] = {
+ "\xea\xb0\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eab1[] = {
+ "\xea\xb1\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eab2[] = {
+ "\xea\xb2\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eab3[] = {
+ "\xea\xb3\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eab4[] = {
+ "\xea\xb4\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eab5[] = {
+ "\xea\xb5\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eab6[] = {
+ "\xea\xb6\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eab7[] = {
+ "\xea\xb7\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eab8[] = {
+ "\xea\xb8\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eab9[] = {
+ "\xea\xb9\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eaba[] = {
+ "\xea\xba\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eabb[] = {
+ "\xea\xbb\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eabc[] = {
+ "\xea\xbc\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eabd[] = {
+ "\xea\xbd\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eabe[] = {
+ "\xea\xbe\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eabf[] = {
+ "\xea\xbf\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb80[] = {
+ "\xeb\x80\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb81[] = {
+ "\xeb\x81\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb82[] = {
+ "\xeb\x82\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb83[] = {
+ "\xeb\x83\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb84[] = {
+ "\xeb\x84\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb85[] = {
+ "\xeb\x85\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb86[] = {
+ "\xeb\x86\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb87[] = {
+ "\xeb\x87\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb88[] = {
+ "\xeb\x88\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb89[] = {
+ "\xeb\x89\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb8a[] = {
+ "\xeb\x8a\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb8b[] = {
+ "\xeb\x8b\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb8c[] = {
+ "\xeb\x8c\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb8d[] = {
+ "\xeb\x8d\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb8e[] = {
+ "\xeb\x8e\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb8f[] = {
+ "\xeb\x8f\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb90[] = {
+ "\xeb\x90\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb91[] = {
+ "\xeb\x91\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb92[] = {
+ "\xeb\x92\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb93[] = {
+ "\xeb\x93\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb94[] = {
+ "\xeb\x94\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb95[] = {
+ "\xeb\x95\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb96[] = {
+ "\xeb\x96\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb97[] = {
+ "\xeb\x97\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb98[] = {
+ "\xeb\x98\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb99[] = {
+ "\xeb\x99\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb9a[] = {
+ "\xeb\x9a\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb9b[] = {
+ "\xeb\x9b\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb9c[] = {
+ "\xeb\x9c\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb9d[] = {
+ "\xeb\x9d\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb9e[] = {
+ "\xeb\x9e\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eb9f[] = {
+ "\xeb\x9f\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eba0[] = {
+ "\xeb\xa0\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eba1[] = {
+ "\xeb\xa1\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eba2[] = {
+ "\xeb\xa2\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eba3[] = {
+ "\xeb\xa3\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eba4[] = {
+ "\xeb\xa4\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eba5[] = {
+ "\xeb\xa5\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eba6[] = {
+ "\xeb\xa6\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eba7[] = {
+ "\xeb\xa7\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eba8[] = {
+ "\xeb\xa8\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eba9[] = {
+ "\xeb\xa9\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebaa[] = {
+ "\xeb\xaa\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebab[] = {
+ "\xeb\xab\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebac[] = {
+ "\xeb\xac\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebad[] = {
+ "\xeb\xad\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebae[] = {
+ "\xeb\xae\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebaf[] = {
+ "\xeb\xaf\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebb0[] = {
+ "\xeb\xb0\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebb1[] = {
+ "\xeb\xb1\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebb2[] = {
+ "\xeb\xb2\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebb3[] = {
+ "\xeb\xb3\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebb4[] = {
+ "\xeb\xb4\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebb5[] = {
+ "\xeb\xb5\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebb6[] = {
+ "\xeb\xb6\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebb7[] = {
+ "\xeb\xb7\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebb8[] = {
+ "\xeb\xb8\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebb9[] = {
+ "\xeb\xb9\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebba[] = {
+ "\xeb\xba\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebbb[] = {
+ "\xeb\xbb\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebbc[] = {
+ "\xeb\xbc\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebbd[] = {
+ "\xeb\xbd\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebbe[] = {
+ "\xeb\xbe\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ebbf[] = {
+ "\xeb\xbf\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec80[] = {
+ "\xec\x80\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec81[] = {
+ "\xec\x81\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec82[] = {
+ "\xec\x82\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec83[] = {
+ "\xec\x83\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec84[] = {
+ "\xec\x84\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec85[] = {
+ "\xec\x85\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec86[] = {
+ "\xec\x86\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec87[] = {
+ "\xec\x87\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec88[] = {
+ "\xec\x88\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec89[] = {
+ "\xec\x89\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec8a[] = {
+ "\xec\x8a\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec8b[] = {
+ "\xec\x8b\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec8c[] = {
+ "\xec\x8c\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec8d[] = {
+ "\xec\x8d\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec8e[] = {
+ "\xec\x8e\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec8f[] = {
+ "\xec\x8f\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec90[] = {
+ "\xec\x90\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec91[] = {
+ "\xec\x91\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec92[] = {
+ "\xec\x92\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec93[] = {
+ "\xec\x93\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec94[] = {
+ "\xec\x94\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec95[] = {
+ "\xec\x95\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec96[] = {
+ "\xec\x96\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec97[] = {
+ "\xec\x97\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec98[] = {
+ "\xec\x98\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec99[] = {
+ "\xec\x99\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec9a[] = {
+ "\xec\x9a\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec9b[] = {
+ "\xec\x9b\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec9c[] = {
+ "\xec\x9c\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec9d[] = {
+ "\xec\x9d\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec9e[] = {
+ "\xec\x9e\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ec9f[] = {
+ "\xec\x9f\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eca0[] = {
+ "\xec\xa0\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eca1[] = {
+ "\xec\xa1\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eca2[] = {
+ "\xec\xa2\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eca3[] = {
+ "\xec\xa3\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eca4[] = {
+ "\xec\xa4\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eca5[] = {
+ "\xec\xa5\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eca6[] = {
+ "\xec\xa6\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eca7[] = {
+ "\xec\xa7\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eca8[] = {
+ "\xec\xa8\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_eca9[] = {
+ "\xec\xa9\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecaa[] = {
+ "\xec\xaa\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecab[] = {
+ "\xec\xab\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecac[] = {
+ "\xec\xac\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecad[] = {
+ "\xec\xad\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecae[] = {
+ "\xec\xae\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecaf[] = {
+ "\xec\xaf\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecb0[] = {
+ "\xec\xb0\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecb1[] = {
+ "\xec\xb1\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecb2[] = {
+ "\xec\xb2\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecb3[] = {
+ "\xec\xb3\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecb4[] = {
+ "\xec\xb4\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecb5[] = {
+ "\xec\xb5\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecb6[] = {
+ "\xec\xb6\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecb7[] = {
+ "\xec\xb7\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecb8[] = {
+ "\xec\xb8\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecb9[] = {
+ "\xec\xb9\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecba[] = {
+ "\xec\xba\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecbb[] = {
+ "\xec\xbb\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecbc[] = {
+ "\xec\xbc\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecbd[] = {
+ "\xec\xbd\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecbe[] = {
+ "\xec\xbe\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ecbf[] = {
+ "\xec\xbf\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed80[] = {
+ "\xed\x80\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed81[] = {
+ "\xed\x81\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed82[] = {
+ "\xed\x82\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed83[] = {
+ "\xed\x83\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed84[] = {
+ "\xed\x84\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed85[] = {
+ "\xed\x85\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed86[] = {
+ "\xed\x86\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed87[] = {
+ "\xed\x87\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed88[] = {
+ "\xed\x88\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed89[] = {
+ "\xed\x89\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed8a[] = {
+ "\xed\x8a\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed8b[] = {
+ "\xed\x8b\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed8c[] = {
+ "\xed\x8c\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed8d[] = {
+ "\xed\x8d\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed8e[] = {
+ "\xed\x8e\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed8f[] = {
+ "\xed\x8f\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed90[] = {
+ "\xed\x90\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed91[] = {
+ "\xed\x91\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed92[] = {
+ "\xed\x92\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed93[] = {
+ "\xed\x93\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed94[] = {
+ "\xed\x94\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed95[] = {
+ "\xed\x95\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed96[] = {
+ "\xed\x96\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\x84"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed97[] = {
+ "\xed\x97\xa0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xbc"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed98[] = {
+ "\xed\x98\x98", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xb4", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x90"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed99[] = {
+ "\xed\x99\xac", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x88"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed9a[] = {
+ "\xed\x9a\xa4", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\x80"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed9b[] = {
+ "\xed\x9b\x9c", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xb8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x94"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed9c[] = {
+ "\xed\x9c\xb0", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x8c"
+};
+
+static const char *grn_nfkc50_compose_prefix_e186bf_table_ed9d[] = {
+ "\xed\x9d\xa8", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9e\x84"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e186bf(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e186bf_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\xa0";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eab0[] = {
+ "\xea\xb0\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eab1[] = {
+ "\xea\xb1\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eab2[] = {
+ "\xea\xb2\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eab3[] = {
+ "\xea\xb3\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eab4[] = {
+ "\xea\xb4\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eab5[] = {
+ "\xea\xb5\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eab6[] = {
+ "\xea\xb6\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eab7[] = {
+ "\xea\xb7\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eab8[] = {
+ "\xea\xb8\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eab9[] = {
+ "\xea\xb9\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eaba[] = {
+ "\xea\xba\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eabb[] = {
+ "\xea\xbb\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eabc[] = {
+ "\xea\xbc\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eabd[] = {
+ "\xea\xbd\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eabe[] = {
+ "\xea\xbe\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eabf[] = {
+ "\xea\xbf\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb80[] = {
+ "\xeb\x80\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb81[] = {
+ "\xeb\x81\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb82[] = {
+ "\xeb\x82\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb83[] = {
+ "\xeb\x83\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb84[] = {
+ "\xeb\x84\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb85[] = {
+ "\xeb\x85\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb86[] = {
+ "\xeb\x86\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb87[] = {
+ "\xeb\x87\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb88[] = {
+ "\xeb\x88\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb89[] = {
+ "\xeb\x89\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb8a[] = {
+ "\xeb\x8a\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb8b[] = {
+ "\xeb\x8b\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb8c[] = {
+ "\xeb\x8c\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb8d[] = {
+ "\xeb\x8d\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb8e[] = {
+ "\xeb\x8e\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb8f[] = {
+ "\xeb\x8f\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb90[] = {
+ "\xeb\x90\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb91[] = {
+ "\xeb\x91\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb92[] = {
+ "\xeb\x92\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb93[] = {
+ "\xeb\x93\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb94[] = {
+ "\xeb\x94\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb95[] = {
+ "\xeb\x95\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb96[] = {
+ "\xeb\x96\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb97[] = {
+ "\xeb\x97\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb98[] = {
+ "\xeb\x98\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb99[] = {
+ "\xeb\x99\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb9a[] = {
+ "\xeb\x9a\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb9b[] = {
+ "\xeb\x9b\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb9c[] = {
+ "\xeb\x9c\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb9d[] = {
+ "\xeb\x9d\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb9e[] = {
+ "\xeb\x9e\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eb9f[] = {
+ "\xeb\x9f\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eba0[] = {
+ "\xeb\xa0\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eba1[] = {
+ "\xeb\xa1\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eba2[] = {
+ "\xeb\xa2\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eba3[] = {
+ "\xeb\xa3\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eba4[] = {
+ "\xeb\xa4\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eba5[] = {
+ "\xeb\xa5\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eba6[] = {
+ "\xeb\xa6\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eba7[] = {
+ "\xeb\xa7\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eba8[] = {
+ "\xeb\xa8\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eba9[] = {
+ "\xeb\xa9\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebaa[] = {
+ "\xeb\xaa\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebab[] = {
+ "\xeb\xab\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebac[] = {
+ "\xeb\xac\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebad[] = {
+ "\xeb\xad\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebae[] = {
+ "\xeb\xae\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebaf[] = {
+ "\xeb\xaf\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebb0[] = {
+ "\xeb\xb0\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebb1[] = {
+ "\xeb\xb1\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebb2[] = {
+ "\xeb\xb2\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebb3[] = {
+ "\xeb\xb3\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebb4[] = {
+ "\xeb\xb4\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebb5[] = {
+ "\xeb\xb5\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebb6[] = {
+ "\xeb\xb6\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebb7[] = {
+ "\xeb\xb7\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebb8[] = {
+ "\xeb\xb8\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebb9[] = {
+ "\xeb\xb9\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebba[] = {
+ "\xeb\xba\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebbb[] = {
+ "\xeb\xbb\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebbc[] = {
+ "\xeb\xbc\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebbd[] = {
+ "\xeb\xbd\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebbe[] = {
+ "\xeb\xbe\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ebbf[] = {
+ "\xeb\xbf\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec80[] = {
+ "\xec\x80\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec81[] = {
+ "\xec\x81\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec82[] = {
+ "\xec\x82\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec83[] = {
+ "\xec\x83\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec84[] = {
+ "\xec\x84\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec85[] = {
+ "\xec\x85\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec86[] = {
+ "\xec\x86\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec87[] = {
+ "\xec\x87\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec88[] = {
+ "\xec\x88\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec89[] = {
+ "\xec\x89\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec8a[] = {
+ "\xec\x8a\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec8b[] = {
+ "\xec\x8b\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec8c[] = {
+ "\xec\x8c\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec8d[] = {
+ "\xec\x8d\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec8e[] = {
+ "\xec\x8e\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec8f[] = {
+ "\xec\x8f\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec90[] = {
+ "\xec\x90\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec91[] = {
+ "\xec\x91\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec92[] = {
+ "\xec\x92\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec93[] = {
+ "\xec\x93\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec94[] = {
+ "\xec\x94\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec95[] = {
+ "\xec\x95\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec96[] = {
+ "\xec\x96\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec97[] = {
+ "\xec\x97\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec98[] = {
+ "\xec\x98\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec99[] = {
+ "\xec\x99\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec9a[] = {
+ "\xec\x9a\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec9b[] = {
+ "\xec\x9b\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec9c[] = {
+ "\xec\x9c\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec9d[] = {
+ "\xec\x9d\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec9e[] = {
+ "\xec\x9e\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ec9f[] = {
+ "\xec\x9f\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eca0[] = {
+ "\xec\xa0\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eca1[] = {
+ "\xec\xa1\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eca2[] = {
+ "\xec\xa2\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eca3[] = {
+ "\xec\xa3\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eca4[] = {
+ "\xec\xa4\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eca5[] = {
+ "\xec\xa5\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eca6[] = {
+ "\xec\xa6\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eca7[] = {
+ "\xec\xa7\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eca8[] = {
+ "\xec\xa8\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_eca9[] = {
+ "\xec\xa9\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecaa[] = {
+ "\xec\xaa\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecab[] = {
+ "\xec\xab\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecac[] = {
+ "\xec\xac\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecad[] = {
+ "\xec\xad\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecae[] = {
+ "\xec\xae\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecaf[] = {
+ "\xec\xaf\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecb0[] = {
+ "\xec\xb0\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecb1[] = {
+ "\xec\xb1\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecb2[] = {
+ "\xec\xb2\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecb3[] = {
+ "\xec\xb3\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecb4[] = {
+ "\xec\xb4\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecb5[] = {
+ "\xec\xb5\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecb6[] = {
+ "\xec\xb6\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecb7[] = {
+ "\xec\xb7\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecb8[] = {
+ "\xec\xb8\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecb9[] = {
+ "\xec\xb9\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecba[] = {
+ "\xec\xba\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecbb[] = {
+ "\xec\xbb\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecbc[] = {
+ "\xec\xbc\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecbd[] = {
+ "\xec\xbd\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecbe[] = {
+ "\xec\xbe\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ecbf[] = {
+ "\xec\xbf\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed80[] = {
+ "\xed\x80\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed81[] = {
+ "\xed\x81\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed82[] = {
+ "\xed\x82\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed83[] = {
+ "\xed\x83\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed84[] = {
+ "\xed\x84\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed85[] = {
+ "\xed\x85\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed86[] = {
+ "\xed\x86\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed87[] = {
+ "\xed\x87\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed88[] = {
+ "\xed\x88\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed89[] = {
+ "\xed\x89\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed8a[] = {
+ "\xed\x8a\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed8b[] = {
+ "\xed\x8b\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed8c[] = {
+ "\xed\x8c\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed8d[] = {
+ "\xed\x8d\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed8e[] = {
+ "\xed\x8e\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed8f[] = {
+ "\xed\x8f\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed90[] = {
+ "\xed\x90\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed91[] = {
+ "\xed\x91\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed92[] = {
+ "\xed\x92\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed93[] = {
+ "\xed\x93\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed94[] = {
+ "\xed\x94\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed95[] = {
+ "\xed\x95\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed96[] = {
+ "\xed\x96\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\x85"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed97[] = {
+ "\xed\x97\xa1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xbd"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed98[] = {
+ "\xed\x98\x99", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xb5", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x91"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed99[] = {
+ "\xed\x99\xad", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x89"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed9a[] = {
+ "\xed\x9a\xa5", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\x81"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed9b[] = {
+ "\xed\x9b\x9d", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xb9", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x95"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed9c[] = {
+ "\xed\x9c\xb1", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x8d"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18780_table_ed9d[] = {
+ "\xed\x9d\xa9", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9e\x85"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e18780(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18780_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\xa1";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eab0[] = {
+ "\xea\xb0\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eab1[] = {
+ "\xea\xb1\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eab2[] = {
+ "\xea\xb2\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eab3[] = {
+ "\xea\xb3\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eab4[] = {
+ "\xea\xb4\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eab5[] = {
+ "\xea\xb5\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eab6[] = {
+ "\xea\xb6\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eab7[] = {
+ "\xea\xb7\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eab8[] = {
+ "\xea\xb8\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eab9[] = {
+ "\xea\xb9\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eaba[] = {
+ "\xea\xba\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eabb[] = {
+ "\xea\xbb\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eabc[] = {
+ "\xea\xbc\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eabd[] = {
+ "\xea\xbd\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eabe[] = {
+ "\xea\xbe\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eabf[] = {
+ "\xea\xbf\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb80[] = {
+ "\xeb\x80\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb81[] = {
+ "\xeb\x81\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb82[] = {
+ "\xeb\x82\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb83[] = {
+ "\xeb\x83\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb84[] = {
+ "\xeb\x84\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb85[] = {
+ "\xeb\x85\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb86[] = {
+ "\xeb\x86\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb87[] = {
+ "\xeb\x87\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb88[] = {
+ "\xeb\x88\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb89[] = {
+ "\xeb\x89\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb8a[] = {
+ "\xeb\x8a\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb8b[] = {
+ "\xeb\x8b\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb8c[] = {
+ "\xeb\x8c\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb8d[] = {
+ "\xeb\x8d\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb8e[] = {
+ "\xeb\x8e\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb8f[] = {
+ "\xeb\x8f\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb90[] = {
+ "\xeb\x90\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb91[] = {
+ "\xeb\x91\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb92[] = {
+ "\xeb\x92\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb93[] = {
+ "\xeb\x93\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb94[] = {
+ "\xeb\x94\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb95[] = {
+ "\xeb\x95\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb96[] = {
+ "\xeb\x96\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb97[] = {
+ "\xeb\x97\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb98[] = {
+ "\xeb\x98\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb99[] = {
+ "\xeb\x99\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb9a[] = {
+ "\xeb\x9a\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb9b[] = {
+ "\xeb\x9b\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb9c[] = {
+ "\xeb\x9c\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb9d[] = {
+ "\xeb\x9d\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb9e[] = {
+ "\xeb\x9e\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eb9f[] = {
+ "\xeb\x9f\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eba0[] = {
+ "\xeb\xa0\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eba1[] = {
+ "\xeb\xa1\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eba2[] = {
+ "\xeb\xa2\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eba3[] = {
+ "\xeb\xa3\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eba4[] = {
+ "\xeb\xa4\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eba5[] = {
+ "\xeb\xa5\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eba6[] = {
+ "\xeb\xa6\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eba7[] = {
+ "\xeb\xa7\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eba8[] = {
+ "\xeb\xa8\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eba9[] = {
+ "\xeb\xa9\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebaa[] = {
+ "\xeb\xaa\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebab[] = {
+ "\xeb\xab\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebac[] = {
+ "\xeb\xac\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebad[] = {
+ "\xeb\xad\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebae[] = {
+ "\xeb\xae\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebaf[] = {
+ "\xeb\xaf\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebb0[] = {
+ "\xeb\xb0\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebb1[] = {
+ "\xeb\xb1\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebb2[] = {
+ "\xeb\xb2\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebb3[] = {
+ "\xeb\xb3\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebb4[] = {
+ "\xeb\xb4\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebb5[] = {
+ "\xeb\xb5\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebb6[] = {
+ "\xeb\xb6\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebb7[] = {
+ "\xeb\xb7\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebb8[] = {
+ "\xeb\xb8\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebb9[] = {
+ "\xeb\xb9\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebba[] = {
+ "\xeb\xba\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebbb[] = {
+ "\xeb\xbb\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebbc[] = {
+ "\xeb\xbc\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebbd[] = {
+ "\xeb\xbd\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebbe[] = {
+ "\xeb\xbe\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ebbf[] = {
+ "\xeb\xbf\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec80[] = {
+ "\xec\x80\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec81[] = {
+ "\xec\x81\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec82[] = {
+ "\xec\x82\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec83[] = {
+ "\xec\x83\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec84[] = {
+ "\xec\x84\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec85[] = {
+ "\xec\x85\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec86[] = {
+ "\xec\x86\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec87[] = {
+ "\xec\x87\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec88[] = {
+ "\xec\x88\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec89[] = {
+ "\xec\x89\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec8a[] = {
+ "\xec\x8a\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec8b[] = {
+ "\xec\x8b\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec8c[] = {
+ "\xec\x8c\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec8d[] = {
+ "\xec\x8d\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec8e[] = {
+ "\xec\x8e\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec8f[] = {
+ "\xec\x8f\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec90[] = {
+ "\xec\x90\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec91[] = {
+ "\xec\x91\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec92[] = {
+ "\xec\x92\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec93[] = {
+ "\xec\x93\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec94[] = {
+ "\xec\x94\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec95[] = {
+ "\xec\x95\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec96[] = {
+ "\xec\x96\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec97[] = {
+ "\xec\x97\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec98[] = {
+ "\xec\x98\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec99[] = {
+ "\xec\x99\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec9a[] = {
+ "\xec\x9a\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec9b[] = {
+ "\xec\x9b\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec9c[] = {
+ "\xec\x9c\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec9d[] = {
+ "\xec\x9d\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec9e[] = {
+ "\xec\x9e\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ec9f[] = {
+ "\xec\x9f\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eca0[] = {
+ "\xec\xa0\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eca1[] = {
+ "\xec\xa1\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eca2[] = {
+ "\xec\xa2\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eca3[] = {
+ "\xec\xa3\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eca4[] = {
+ "\xec\xa4\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eca5[] = {
+ "\xec\xa5\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eca6[] = {
+ "\xec\xa6\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eca7[] = {
+ "\xec\xa7\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eca8[] = {
+ "\xec\xa8\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_eca9[] = {
+ "\xec\xa9\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecaa[] = {
+ "\xec\xaa\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecab[] = {
+ "\xec\xab\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecac[] = {
+ "\xec\xac\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecad[] = {
+ "\xec\xad\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecae[] = {
+ "\xec\xae\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecaf[] = {
+ "\xec\xaf\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecb0[] = {
+ "\xec\xb0\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecb1[] = {
+ "\xec\xb1\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecb2[] = {
+ "\xec\xb2\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecb3[] = {
+ "\xec\xb3\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecb4[] = {
+ "\xec\xb4\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecb5[] = {
+ "\xec\xb5\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecb6[] = {
+ "\xec\xb6\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecb7[] = {
+ "\xec\xb7\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecb8[] = {
+ "\xec\xb8\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecb9[] = {
+ "\xec\xb9\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecba[] = {
+ "\xec\xba\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecbb[] = {
+ "\xec\xbb\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecbc[] = {
+ "\xec\xbc\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecbd[] = {
+ "\xec\xbd\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecbe[] = {
+ "\xec\xbe\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ecbf[] = {
+ "\xec\xbf\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed80[] = {
+ "\xed\x80\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed81[] = {
+ "\xed\x81\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed82[] = {
+ "\xed\x82\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed83[] = {
+ "\xed\x83\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed84[] = {
+ "\xed\x84\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed85[] = {
+ "\xed\x85\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed86[] = {
+ "\xed\x86\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed87[] = {
+ "\xed\x87\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed88[] = {
+ "\xed\x88\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed89[] = {
+ "\xed\x89\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed8a[] = {
+ "\xed\x8a\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed8b[] = {
+ "\xed\x8b\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed8c[] = {
+ "\xed\x8c\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed8d[] = {
+ "\xed\x8d\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed8e[] = {
+ "\xed\x8e\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed8f[] = {
+ "\xed\x8f\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed90[] = {
+ "\xed\x90\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed91[] = {
+ "\xed\x91\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed92[] = {
+ "\xed\x92\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed93[] = {
+ "\xed\x93\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed94[] = {
+ "\xed\x94\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed95[] = {
+ "\xed\x95\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed96[] = {
+ "\xed\x96\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\x86"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed97[] = {
+ "\xed\x97\xa2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xbe"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed98[] = {
+ "\xed\x98\x9a", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xb6", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x92"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed99[] = {
+ "\xed\x99\xae", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x8a"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed9a[] = {
+ "\xed\x9a\xa6", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\x82"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed9b[] = {
+ "\xed\x9b\x9e", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xba", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x96"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed9c[] = {
+ "\xed\x9c\xb2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x8e"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18781_table_ed9d[] = {
+ "\xed\x9d\xaa", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9e\x86"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e18781(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18781_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\xa2";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eab0[] = {
+ "\xea\xb0\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb0\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb1\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eab1[] = {
+ "\xea\xb1\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb2\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eab2[] = {
+ "\xea\xb2\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eab3[] = {
+ "\xea\xb3\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb3\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb4\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eab4[] = {
+ "\xea\xb4\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb5\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eab5[] = {
+ "\xea\xb5\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eab6[] = {
+ "\xea\xb6\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb6\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eab7[] = {
+ "\xea\xb7\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb7\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xb8\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eab8[] = {
+ "\xea\xb8\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xb9\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eab9[] = {
+ "\xea\xb9\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eaba[] = {
+ "\xea\xba\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xba\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbb\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eabb[] = {
+ "\xea\xbb\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbc\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eabc[] = {
+ "\xea\xbc\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eabd[] = {
+ "\xea\xbd\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbd\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eabe[] = {
+ "\xea\xbe\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xea\xbe\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xea\xbf\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eabf[] = {
+ "\xea\xbf\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x80\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb80[] = {
+ "\xeb\x80\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb81[] = {
+ "\xeb\x81\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x81\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x82\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb82[] = {
+ "\xeb\x82\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x83\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb83[] = {
+ "\xeb\x83\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb84[] = {
+ "\xeb\x84\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x84\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb85[] = {
+ "\xeb\x85\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x85\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x86\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb86[] = {
+ "\xeb\x86\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x87\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb87[] = {
+ "\xeb\x87\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb88[] = {
+ "\xeb\x88\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x88\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x89\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb89[] = {
+ "\xeb\x89\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8a\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb8a[] = {
+ "\xeb\x8a\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb8b[] = {
+ "\xeb\x8b\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8b\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb8c[] = {
+ "\xeb\x8c\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8c\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x8d\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb8d[] = {
+ "\xeb\x8d\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8e\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb8e[] = {
+ "\xeb\x8e\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb8f[] = {
+ "\xeb\x8f\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x8f\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x90\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb90[] = {
+ "\xeb\x90\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x91\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb91[] = {
+ "\xeb\x91\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb92[] = {
+ "\xeb\x92\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x92\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb93[] = {
+ "\xeb\x93\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x93\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x94\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb94[] = {
+ "\xeb\x94\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x95\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb95[] = {
+ "\xeb\x95\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb96[] = {
+ "\xeb\x96\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x96\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x97\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb97[] = {
+ "\xeb\x97\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x98\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb98[] = {
+ "\xeb\x98\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb99[] = {
+ "\xeb\x99\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x99\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb9a[] = {
+ "\xeb\x9a\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9a\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9b\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb9b[] = {
+ "\xeb\x9b\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9c\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb9c[] = {
+ "\xeb\x9c\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb9d[] = {
+ "\xeb\x9d\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9d\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\x9e\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb9e[] = {
+ "\xeb\x9e\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\x9f\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eb9f[] = {
+ "\xeb\x9f\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eba0[] = {
+ "\xeb\xa0\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa0\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eba1[] = {
+ "\xeb\xa1\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa1\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa2\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eba2[] = {
+ "\xeb\xa2\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa3\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eba3[] = {
+ "\xeb\xa3\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eba4[] = {
+ "\xeb\xa4\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa4\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa5\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eba5[] = {
+ "\xeb\xa5\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa6\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eba6[] = {
+ "\xeb\xa6\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eba7[] = {
+ "\xeb\xa7\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa7\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eba8[] = {
+ "\xeb\xa8\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xa8\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xa9\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eba9[] = {
+ "\xeb\xa9\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaa\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebaa[] = {
+ "\xeb\xaa\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebab[] = {
+ "\xeb\xab\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xab\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xac\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebac[] = {
+ "\xeb\xac\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xad\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebad[] = {
+ "\xeb\xad\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebae[] = {
+ "\xeb\xae\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xae\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebaf[] = {
+ "\xeb\xaf\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xaf\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb0\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebb0[] = {
+ "\xeb\xb0\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb1\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebb1[] = {
+ "\xeb\xb1\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebb2[] = {
+ "\xeb\xb2\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb2\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb3\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebb3[] = {
+ "\xeb\xb3\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb4\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebb4[] = {
+ "\xeb\xb4\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebb5[] = {
+ "\xeb\xb5\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb5\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebb6[] = {
+ "\xeb\xb6\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb6\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xb7\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebb7[] = {
+ "\xeb\xb7\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb8\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebb8[] = {
+ "\xeb\xb8\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebb9[] = {
+ "\xeb\xb9\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xb9\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xba\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebba[] = {
+ "\xeb\xba\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbb\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebbb[] = {
+ "\xeb\xbb\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebbc[] = {
+ "\xeb\xbc\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbc\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebbd[] = {
+ "\xeb\xbd\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbd\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xeb\xbe\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebbe[] = {
+ "\xeb\xbe\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xeb\xbf\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ebbf[] = {
+ "\xeb\xbf\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec80[] = {
+ "\xec\x80\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x80\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x81\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec81[] = {
+ "\xec\x81\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x82\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec82[] = {
+ "\xec\x82\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec83[] = {
+ "\xec\x83\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x83\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec84[] = {
+ "\xec\x84\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x84\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x85\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec85[] = {
+ "\xec\x85\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x86\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec86[] = {
+ "\xec\x86\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec87[] = {
+ "\xec\x87\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x87\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x88\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec88[] = {
+ "\xec\x88\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x89\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec89[] = {
+ "\xec\x89\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec8a[] = {
+ "\xec\x8a\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8a\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec8b[] = {
+ "\xec\x8b\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8b\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8c\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec8c[] = {
+ "\xec\x8c\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8d\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec8d[] = {
+ "\xec\x8d\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec8e[] = {
+ "\xec\x8e\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x8e\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x8f\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec8f[] = {
+ "\xec\x8f\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x90\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec90[] = {
+ "\xec\x90\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec91[] = {
+ "\xec\x91\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x91\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec92[] = {
+ "\xec\x92\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x92\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x93\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec93[] = {
+ "\xec\x93\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x94\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec94[] = {
+ "\xec\x94\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec95[] = {
+ "\xec\x95\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x95\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x96\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec96[] = {
+ "\xec\x96\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x97\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec97[] = {
+ "\xec\x97\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec98[] = {
+ "\xec\x98\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x98\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec99[] = {
+ "\xec\x99\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x99\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9a\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec9a[] = {
+ "\xec\x9a\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9b\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec9b[] = {
+ "\xec\x9b\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec9c[] = {
+ "\xec\x9c\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9c\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\x9d\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec9d[] = {
+ "\xec\x9d\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9e\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec9e[] = {
+ "\xec\x9e\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ec9f[] = {
+ "\xec\x9f\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\x9f\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eca0[] = {
+ "\xec\xa0\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa0\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa1\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eca1[] = {
+ "\xec\xa1\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa2\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eca2[] = {
+ "\xec\xa2\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eca3[] = {
+ "\xec\xa3\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa3\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa4\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eca4[] = {
+ "\xec\xa4\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa5\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eca5[] = {
+ "\xec\xa5\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eca6[] = {
+ "\xec\xa6\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa6\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eca7[] = {
+ "\xec\xa7\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa7\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xa8\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eca8[] = {
+ "\xec\xa8\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xa9\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_eca9[] = {
+ "\xec\xa9\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecaa[] = {
+ "\xec\xaa\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xaa\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xab\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecab[] = {
+ "\xec\xab\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xac\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecac[] = {
+ "\xec\xac\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecad[] = {
+ "\xec\xad\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xad\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecae[] = {
+ "\xec\xae\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xae\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xaf\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecaf[] = {
+ "\xec\xaf\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb0\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecb0[] = {
+ "\xec\xb0\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecb1[] = {
+ "\xec\xb1\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb1\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb2\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecb2[] = {
+ "\xec\xb2\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb3\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecb3[] = {
+ "\xec\xb3\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecb4[] = {
+ "\xec\xb4\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb4\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecb5[] = {
+ "\xec\xb5\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb5\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb6\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecb6[] = {
+ "\xec\xb6\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb7\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecb7[] = {
+ "\xec\xb7\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecb8[] = {
+ "\xec\xb8\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xb8\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xb9\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecb9[] = {
+ "\xec\xb9\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xba\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecba[] = {
+ "\xec\xba\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecbb[] = {
+ "\xec\xbb\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbb\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecbc[] = {
+ "\xec\xbc\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbc\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xec\xbd\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecbd[] = {
+ "\xec\xbd\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbe\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecbe[] = {
+ "\xec\xbe\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ecbf[] = {
+ "\xec\xbf\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xec\xbf\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x80\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed80[] = {
+ "\xed\x80\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x81\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed81[] = {
+ "\xed\x81\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed82[] = {
+ "\xed\x82\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x82\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed83[] = {
+ "\xed\x83\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x83\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x84\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed84[] = {
+ "\xed\x84\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x85\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed85[] = {
+ "\xed\x85\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed86[] = {
+ "\xed\x86\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x86\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x87\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed87[] = {
+ "\xed\x87\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x88\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed88[] = {
+ "\xed\x88\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed89[] = {
+ "\xed\x89\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x89\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed8a[] = {
+ "\xed\x8a\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8a\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8b\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed8b[] = {
+ "\xed\x8b\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8c\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed8c[] = {
+ "\xed\x8c\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed8d[] = {
+ "\xed\x8d\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8d\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x8e\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed8e[] = {
+ "\xed\x8e\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x8f\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed8f[] = {
+ "\xed\x8f\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed90[] = {
+ "\xed\x90\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x90\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed91[] = {
+ "\xed\x91\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x91\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x92\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed92[] = {
+ "\xed\x92\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x93\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed93[] = {
+ "\xed\x93\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed94[] = {
+ "\xed\x94\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x94\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x95\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed95[] = {
+ "\xed\x95\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x96\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed96[] = {
+ "\xed\x96\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\x87"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed97[] = {
+ "\xed\x97\xa3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x97\xbf"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed98[] = {
+ "\xed\x98\x9b", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x98\xb7", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x99\x93"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed99[] = {
+ "\xed\x99\xaf", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9a\x8b"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed9a[] = {
+ "\xed\x9a\xa7", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\x83"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed9b[] = {
+ "\xed\x9b\x9f", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9b\xbb", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "\xed\x9c\x97"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed9c[] = {
+ "\xed\x9c\xb3", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9d\x8f"
+};
+
+static const char *grn_nfkc50_compose_prefix_e18782_table_ed9d[] = {
+ "\xed\x9d\xab", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\xed\x9e\x87"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e18782(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xea :
+ switch (utf8[1]) {
+ case 0xb0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eab0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eab1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eab2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_eab3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eab4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_eab5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eab6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eab7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eab8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eab9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_eaba[utf8[2] - 0x84];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eabb[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_eabc[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eabd[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eabe[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eabf[utf8[2] - 0x94];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xeb :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb80[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb81[utf8[2] - 0x84];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb82[utf8[2] - 0x98];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb83[utf8[2] - 0x90];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb84[utf8[2] - 0x88];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb85[utf8[2] - 0x80];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb86[utf8[2] - 0x94];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb87[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb88[utf8[2] - 0x84];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb89[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb8a[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb8b[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb8c[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb8d[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb8e[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb8f[utf8[2] - 0x84];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb90[utf8[2] - 0x98];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb91[utf8[2] - 0x90];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb92[utf8[2] - 0x88];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb93[utf8[2] - 0x80];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb94[utf8[2] - 0x94];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb95[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb96[utf8[2] - 0x84];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb97[utf8[2] - 0x98];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb98[utf8[2] - 0x90];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb99[utf8[2] - 0x88];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb9a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb9b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb9c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb9d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb9e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_eb9f[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eba0[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eba1[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eba2[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eba3[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_eba4[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eba5[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_eba6[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eba7[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eba8[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eba9[utf8[2] - 0x94];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebaa[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebab[utf8[2] - 0x84];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebac[utf8[2] - 0x98];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebad[utf8[2] - 0x90];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebae[utf8[2] - 0x88];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebaf[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebb0[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebb1[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebb2[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebb3[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebb4[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebb5[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebb6[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebb7[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebb8[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebb9[utf8[2] - 0x84];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebba[utf8[2] - 0x98];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebbb[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebbc[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebbd[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebbe[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ebbf[utf8[2] - 0x8c];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xec :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec80[utf8[2] - 0x84];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec81[utf8[2] - 0x98];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec82[utf8[2] - 0x90];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec83[utf8[2] - 0x88];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec84[utf8[2] - 0x80];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec85[utf8[2] - 0x94];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec86[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec87[utf8[2] - 0x84];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec88[utf8[2] - 0x98];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec89[utf8[2] - 0x90];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec8a[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec8b[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec8c[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec8d[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec8e[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec8f[utf8[2] - 0x98];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec90[utf8[2] - 0x90];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec91[utf8[2] - 0x88];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec92[utf8[2] - 0x80];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec93[utf8[2] - 0x94];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec94[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec95[utf8[2] - 0x84];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec96[utf8[2] - 0x98];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec97[utf8[2] - 0x90];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec98[utf8[2] - 0x88];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec99[utf8[2] - 0x80];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec9a[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec9b[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec9c[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec9d[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec9e[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9f :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ec9f[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa0 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eca0[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa1 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eca1[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa2 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eca2[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xa3 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_eca3[utf8[2] - 0x84];
+ }
+ break;
+ case 0xa4 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eca4[utf8[2] - 0x98];
+ }
+ break;
+ case 0xa5 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_eca5[utf8[2] - 0x90];
+ }
+ break;
+ case 0xa6 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_eca6[utf8[2] - 0x88];
+ }
+ break;
+ case 0xa7 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eca7[utf8[2] - 0x80];
+ }
+ break;
+ case 0xa8 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_eca8[utf8[2] - 0x94];
+ }
+ break;
+ case 0xa9 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_eca9[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xaa :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecaa[utf8[2] - 0x84];
+ }
+ break;
+ case 0xab :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecab[utf8[2] - 0x98];
+ }
+ break;
+ case 0xac :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecac[utf8[2] - 0x90];
+ }
+ break;
+ case 0xad :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecad[utf8[2] - 0x88];
+ }
+ break;
+ case 0xae :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecae[utf8[2] - 0x80];
+ }
+ break;
+ case 0xaf :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecaf[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb0 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecb0[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb1 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecb1[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb2 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecb2[utf8[2] - 0x98];
+ }
+ break;
+ case 0xb3 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecb3[utf8[2] - 0x90];
+ }
+ break;
+ case 0xb4 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecb4[utf8[2] - 0x88];
+ }
+ break;
+ case 0xb5 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecb5[utf8[2] - 0x80];
+ }
+ break;
+ case 0xb6 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecb6[utf8[2] - 0x94];
+ }
+ break;
+ case 0xb7 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecb7[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xb8 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecb8[utf8[2] - 0x84];
+ }
+ break;
+ case 0xb9 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecb9[utf8[2] - 0x98];
+ }
+ break;
+ case 0xba :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecba[utf8[2] - 0x90];
+ }
+ break;
+ case 0xbb :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecbb[utf8[2] - 0x88];
+ }
+ break;
+ case 0xbc :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecbc[utf8[2] - 0x80];
+ }
+ break;
+ case 0xbd :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecbd[utf8[2] - 0x94];
+ }
+ break;
+ case 0xbe :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecbe[utf8[2] - 0x8c];
+ }
+ break;
+ case 0xbf :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ecbf[utf8[2] - 0x84];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xed :
+ switch (utf8[1]) {
+ case 0x80 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed80[utf8[2] - 0x98];
+ }
+ break;
+ case 0x81 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed81[utf8[2] - 0x90];
+ }
+ break;
+ case 0x82 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed82[utf8[2] - 0x88];
+ }
+ break;
+ case 0x83 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed83[utf8[2] - 0x80];
+ }
+ break;
+ case 0x84 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed84[utf8[2] - 0x94];
+ }
+ break;
+ case 0x85 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed85[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x86 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed86[utf8[2] - 0x84];
+ }
+ break;
+ case 0x87 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed87[utf8[2] - 0x98];
+ }
+ break;
+ case 0x88 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed88[utf8[2] - 0x90];
+ }
+ break;
+ case 0x89 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed89[utf8[2] - 0x88];
+ }
+ break;
+ case 0x8a :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed8a[utf8[2] - 0x80];
+ }
+ break;
+ case 0x8b :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed8b[utf8[2] - 0x94];
+ }
+ break;
+ case 0x8c :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed8c[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x8d :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed8d[utf8[2] - 0x84];
+ }
+ break;
+ case 0x8e :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed8e[utf8[2] - 0x98];
+ }
+ break;
+ case 0x8f :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed8f[utf8[2] - 0x90];
+ }
+ break;
+ case 0x90 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed90[utf8[2] - 0x88];
+ }
+ break;
+ case 0x91 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed91[utf8[2] - 0x80];
+ }
+ break;
+ case 0x92 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed92[utf8[2] - 0x94];
+ }
+ break;
+ case 0x93 :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed93[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x94 :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed94[utf8[2] - 0x84];
+ }
+ break;
+ case 0x95 :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed95[utf8[2] - 0x98];
+ }
+ break;
+ case 0x96 :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed96[utf8[2] - 0x90];
+ }
+ break;
+ case 0x97 :
+ if (utf8[2] >= 0x88 &&
+ utf8[2] <= 0xa4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed97[utf8[2] - 0x88];
+ }
+ break;
+ case 0x98 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0xb8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed98[utf8[2] - 0x80];
+ }
+ break;
+ case 0x99 :
+ if (utf8[2] >= 0x94 &&
+ utf8[2] <= 0xb0) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed99[utf8[2] - 0x94];
+ }
+ break;
+ case 0x9a :
+ if (utf8[2] >= 0x8c &&
+ utf8[2] <= 0xa8) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed9a[utf8[2] - 0x8c];
+ }
+ break;
+ case 0x9b :
+ if (utf8[2] >= 0x84 &&
+ utf8[2] <= 0xbc) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed9b[utf8[2] - 0x84];
+ }
+ break;
+ case 0x9c :
+ if (utf8[2] >= 0x98 &&
+ utf8[2] <= 0xb4) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed9c[utf8[2] - 0x98];
+ }
+ break;
+ case 0x9d :
+ if (utf8[2] >= 0x90 &&
+ utf8[2] <= 0xac) {
+ return grn_nfkc50_compose_prefix_e18782_table_ed9d[utf8[2] - 0x90];
+ }
+ break;
+ case 0x9e :
+ if (utf8[2] == 0x88) {
+ return "\xed\x9e\xa3";
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185a2_table_e184[] = {
+ "\xea\xb0\x9c", "\xea\xb9\xa8", "\xeb\x82\xb4", "\xeb\x8c\x80", "\xeb\x95\x8c", "\xeb\x9e\x98", "\xeb\xa7\xa4", "\xeb\xb0\xb0",
+ "\xeb\xb9\xbc", "\xec\x83\x88", "\xec\x8c\x94", "\xec\x95\xa0", "\xec\x9e\xac", "\xec\xa7\xb8", "\xec\xb1\x84", "\xec\xba\x90",
+ "\xed\x83\x9c", "\xed\x8c\xa8", "\xed\x95\xb4"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185a2(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185a2_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185a3_table_e184[] = {
+ "\xea\xb0\xb8", "\xea\xba\x84", "\xeb\x83\x90", "\xeb\x8c\x9c", "\xeb\x95\xa8", "\xeb\x9e\xb4", "\xeb\xa8\x80", "\xeb\xb1\x8c",
+ "\xeb\xba\x98", "\xec\x83\xa4", "\xec\x8c\xb0", "\xec\x95\xbc", "\xec\x9f\x88", "\xec\xa8\x94", "\xec\xb1\xa0", "\xec\xba\xac",
+ "\xed\x83\xb8", "\xed\x8d\x84", "\xed\x96\x90"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185a3(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185a3_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185a4_table_e184[] = {
+ "\xea\xb1\x94", "\xea\xba\xa0", "\xeb\x83\xac", "\xeb\x8c\xb8", "\xeb\x96\x84", "\xeb\x9f\x90", "\xeb\xa8\x9c", "\xeb\xb1\xa8",
+ "\xeb\xba\xb4", "\xec\x84\x80", "\xec\x8d\x8c", "\xec\x96\x98", "\xec\x9f\xa4", "\xec\xa8\xb0", "\xec\xb1\xbc", "\xec\xbb\x88",
+ "\xed\x84\x94", "\xed\x8d\xa0", "\xed\x96\xac"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185a4(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185a4_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185a5_table_e184[] = {
+ "\xea\xb1\xb0", "\xea\xba\xbc", "\xeb\x84\x88", "\xeb\x8d\x94", "\xeb\x96\xa0", "\xeb\x9f\xac", "\xeb\xa8\xb8", "\xeb\xb2\x84",
+ "\xeb\xbb\x90", "\xec\x84\x9c", "\xec\x8d\xa8", "\xec\x96\xb4", "\xec\xa0\x80", "\xec\xa9\x8c", "\xec\xb2\x98", "\xec\xbb\xa4",
+ "\xed\x84\xb0", "\xed\x8d\xbc", "\xed\x97\x88"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185a5(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185a5_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185a6_table_e184[] = {
+ "\xea\xb2\x8c", "\xea\xbb\x98", "\xeb\x84\xa4", "\xeb\x8d\xb0", "\xeb\x96\xbc", "\xeb\xa0\x88", "\xeb\xa9\x94", "\xeb\xb2\xa0",
+ "\xeb\xbb\xac", "\xec\x84\xb8", "\xec\x8e\x84", "\xec\x97\x90", "\xec\xa0\x9c", "\xec\xa9\xa8", "\xec\xb2\xb4", "\xec\xbc\x80",
+ "\xed\x85\x8c", "\xed\x8e\x98", "\xed\x97\xa4"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185a6(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185a6_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185a7_table_e184[] = {
+ "\xea\xb2\xa8", "\xea\xbb\xb4", "\xeb\x85\x80", "\xeb\x8e\x8c", "\xeb\x97\x98", "\xeb\xa0\xa4", "\xeb\xa9\xb0", "\xeb\xb2\xbc",
+ "\xeb\xbc\x88", "\xec\x85\x94", "\xec\x8e\xa0", "\xec\x97\xac", "\xec\xa0\xb8", "\xec\xaa\x84", "\xec\xb3\x90", "\xec\xbc\x9c",
+ "\xed\x85\xa8", "\xed\x8e\xb4", "\xed\x98\x80"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185a7(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185a7_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185a8_table_e184[] = {
+ "\xea\xb3\x84", "\xea\xbc\x90", "\xeb\x85\x9c", "\xeb\x8e\xa8", "\xeb\x97\xb4", "\xeb\xa1\x80", "\xeb\xaa\x8c", "\xeb\xb3\x98",
+ "\xeb\xbc\xa4", "\xec\x85\xb0", "\xec\x8e\xbc", "\xec\x98\x88", "\xec\xa1\x94", "\xec\xaa\xa0", "\xec\xb3\xac", "\xec\xbc\xb8",
+ "\xed\x86\x84", "\xed\x8f\x90", "\xed\x98\x9c"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185a8(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185a8_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185a9_table_e184[] = {
+ "\xea\xb3\xa0", "\xea\xbc\xac", "\xeb\x85\xb8", "\xeb\x8f\x84", "\xeb\x98\x90", "\xeb\xa1\x9c", "\xeb\xaa\xa8", "\xeb\xb3\xb4",
+ "\xeb\xbd\x80", "\xec\x86\x8c", "\xec\x8f\x98", "\xec\x98\xa4", "\xec\xa1\xb0", "\xec\xaa\xbc", "\xec\xb4\x88", "\xec\xbd\x94",
+ "\xed\x86\xa0", "\xed\x8f\xac", "\xed\x98\xb8"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185a9(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185a9_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185aa_table_e184[] = {
+ "\xea\xb3\xbc", "\xea\xbd\x88", "\xeb\x86\x94", "\xeb\x8f\xa0", "\xeb\x98\xac", "\xeb\xa1\xb8", "\xeb\xab\x84", "\xeb\xb4\x90",
+ "\xeb\xbd\x9c", "\xec\x86\xa8", "\xec\x8f\xb4", "\xec\x99\x80", "\xec\xa2\x8c", "\xec\xab\x98", "\xec\xb4\xa4", "\xec\xbd\xb0",
+ "\xed\x86\xbc", "\xed\x90\x88", "\xed\x99\x94"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185aa(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185aa_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185ab_table_e184[] = {
+ "\xea\xb4\x98", "\xea\xbd\xa4", "\xeb\x86\xb0", "\xeb\x8f\xbc", "\xeb\x99\x88", "\xeb\xa2\x94", "\xeb\xab\xa0", "\xeb\xb4\xac",
+ "\xeb\xbd\xb8", "\xec\x87\x84", "\xec\x90\x90", "\xec\x99\x9c", "\xec\xa2\xa8", "\xec\xab\xb4", "\xec\xb5\x80", "\xec\xbe\x8c",
+ "\xed\x87\x98", "\xed\x90\xa4", "\xed\x99\xb0"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185ab(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185ab_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185ac_table_e184[] = {
+ "\xea\xb4\xb4", "\xea\xbe\x80", "\xeb\x87\x8c", "\xeb\x90\x98", "\xeb\x99\xa4", "\xeb\xa2\xb0", "\xeb\xab\xbc", "\xeb\xb5\x88",
+ "\xeb\xbe\x94", "\xec\x87\xa0", "\xec\x90\xac", "\xec\x99\xb8", "\xec\xa3\x84", "\xec\xac\x90", "\xec\xb5\x9c", "\xec\xbe\xa8",
+ "\xed\x87\xb4", "\xed\x91\x80", "\xed\x9a\x8c"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185ac(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185ac_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185ad_table_e184[] = {
+ "\xea\xb5\x90", "\xea\xbe\x9c", "\xeb\x87\xa8", "\xeb\x90\xb4", "\xeb\x9a\x80", "\xeb\xa3\x8c", "\xeb\xac\x98", "\xeb\xb5\xa4",
+ "\xeb\xbe\xb0", "\xec\x87\xbc", "\xec\x91\x88", "\xec\x9a\x94", "\xec\xa3\xa0", "\xec\xac\xac", "\xec\xb5\xb8", "\xec\xbf\x84",
+ "\xed\x88\x90", "\xed\x91\x9c", "\xed\x9a\xa8"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185ad(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185ad_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185ae_table_e184[] = {
+ "\xea\xb5\xac", "\xea\xbe\xb8", "\xeb\x88\x84", "\xeb\x91\x90", "\xeb\x9a\x9c", "\xeb\xa3\xa8", "\xeb\xac\xb4", "\xeb\xb6\x80",
+ "\xeb\xbf\x8c", "\xec\x88\x98", "\xec\x91\xa4", "\xec\x9a\xb0", "\xec\xa3\xbc", "\xec\xad\x88", "\xec\xb6\x94", "\xec\xbf\xa0",
+ "\xed\x88\xac", "\xed\x91\xb8", "\xed\x9b\x84"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185ae(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185ae_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185af_table_e184[] = {
+ "\xea\xb6\x88", "\xea\xbf\x94", "\xeb\x88\xa0", "\xeb\x91\xac", "\xeb\x9a\xb8", "\xeb\xa4\x84", "\xeb\xad\x90", "\xeb\xb6\x9c",
+ "\xeb\xbf\xa8", "\xec\x88\xb4", "\xec\x92\x80", "\xec\x9b\x8c", "\xec\xa4\x98", "\xec\xad\xa4", "\xec\xb6\xb0", "\xec\xbf\xbc",
+ "\xed\x89\x88", "\xed\x92\x94", "\xed\x9b\xa0"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185af(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185af_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185b0_table_e184[] = {
+ "\xea\xb6\xa4", "\xea\xbf\xb0", "\xeb\x88\xbc", "\xeb\x92\x88", "\xeb\x9b\x94", "\xeb\xa4\xa0", "\xeb\xad\xac", "\xeb\xb6\xb8",
+ "\xec\x80\x84", "\xec\x89\x90", "\xec\x92\x9c", "\xec\x9b\xa8", "\xec\xa4\xb4", "\xec\xae\x80", "\xec\xb7\x8c", "\xed\x80\x98",
+ "\xed\x89\xa4", "\xed\x92\xb0", "\xed\x9b\xbc"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185b0(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185b0_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185b1_table_e184[] = {
+ "\xea\xb7\x80", "\xeb\x80\x8c", "\xeb\x89\x98", "\xeb\x92\xa4", "\xeb\x9b\xb0", "\xeb\xa4\xbc", "\xeb\xae\x88", "\xeb\xb7\x94",
+ "\xec\x80\xa0", "\xec\x89\xac", "\xec\x92\xb8", "\xec\x9c\x84", "\xec\xa5\x90", "\xec\xae\x9c", "\xec\xb7\xa8", "\xed\x80\xb4",
+ "\xed\x8a\x80", "\xed\x93\x8c", "\xed\x9c\x98"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185b1(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185b1_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185b2_table_e184[] = {
+ "\xea\xb7\x9c", "\xeb\x80\xa8", "\xeb\x89\xb4", "\xeb\x93\x80", "\xeb\x9c\x8c", "\xeb\xa5\x98", "\xeb\xae\xa4", "\xeb\xb7\xb0",
+ "\xec\x80\xbc", "\xec\x8a\x88", "\xec\x93\x94", "\xec\x9c\xa0", "\xec\xa5\xac", "\xec\xae\xb8", "\xec\xb8\x84", "\xed\x81\x90",
+ "\xed\x8a\x9c", "\xed\x93\xa8", "\xed\x9c\xb4"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185b2(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185b2_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185b3_table_e184[] = {
+ "\xea\xb7\xb8", "\xeb\x81\x84", "\xeb\x8a\x90", "\xeb\x93\x9c", "\xeb\x9c\xa8", "\xeb\xa5\xb4", "\xeb\xaf\x80", "\xeb\xb8\x8c",
+ "\xec\x81\x98", "\xec\x8a\xa4", "\xec\x93\xb0", "\xec\x9c\xbc", "\xec\xa6\x88", "\xec\xaf\x94", "\xec\xb8\xa0", "\xed\x81\xac",
+ "\xed\x8a\xb8", "\xed\x94\x84", "\xed\x9d\x90"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185b3(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185b3_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185b4_table_e184[] = {
+ "\xea\xb8\x94", "\xeb\x81\xa0", "\xeb\x8a\xac", "\xeb\x93\xb8", "\xeb\x9d\x84", "\xeb\xa6\x90", "\xeb\xaf\x9c", "\xeb\xb8\xa8",
+ "\xec\x81\xb4", "\xec\x8b\x80", "\xec\x94\x8c", "\xec\x9d\x98", "\xec\xa6\xa4", "\xec\xaf\xb0", "\xec\xb8\xbc", "\xed\x82\x88",
+ "\xed\x8b\x94", "\xed\x94\xa0", "\xed\x9d\xac"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185b4(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185b4_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *grn_nfkc50_compose_prefix_e185b5_table_e184[] = {
+ "\xea\xb8\xb0", "\xeb\x81\xbc", "\xeb\x8b\x88", "\xeb\x94\x94", "\xeb\x9d\xa0", "\xeb\xa6\xac", "\xeb\xaf\xb8", "\xeb\xb9\x84",
+ "\xec\x82\x90", "\xec\x8b\x9c", "\xec\x94\xa8", "\xec\x9d\xb4", "\xec\xa7\x80", "\xec\xb0\x8c", "\xec\xb9\x98", "\xed\x82\xa4",
+ "\xed\x8b\xb0", "\xed\x94\xbc", "\xed\x9e\x88"
+};
+
+static inline const char *
+grn_nfkc50_compose_prefix_e185b5(const unsigned char *utf8)
+{
+ {
+ switch (utf8[0]) {
+ case 0xe1 :
+ switch (utf8[1]) {
+ case 0x84 :
+ if (utf8[2] >= 0x80 &&
+ utf8[2] <= 0x92) {
+ return grn_nfkc50_compose_prefix_e185b5_table_e184[utf8[2] - 0x80];
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+const char *
+grn_nfkc50_compose(const unsigned char *prefix_utf8, const unsigned char *suffix_utf8)
+{
+ {
+ switch (suffix_utf8[0]) {
+ case 0xcc :
+ switch (suffix_utf8[1]) {
+ case 0x80 :
+ return grn_nfkc50_compose_prefix_cc80(prefix_utf8);
+ case 0x81 :
+ return grn_nfkc50_compose_prefix_cc81(prefix_utf8);
+ case 0x82 :
+ return grn_nfkc50_compose_prefix_cc82(prefix_utf8);
+ case 0x83 :
+ return grn_nfkc50_compose_prefix_cc83(prefix_utf8);
+ case 0x88 :
+ return grn_nfkc50_compose_prefix_cc88(prefix_utf8);
+ case 0x8a :
+ return grn_nfkc50_compose_prefix_cc8a(prefix_utf8);
+ case 0xa7 :
+ return grn_nfkc50_compose_prefix_cca7(prefix_utf8);
+ case 0x84 :
+ return grn_nfkc50_compose_prefix_cc84(prefix_utf8);
+ case 0x86 :
+ return grn_nfkc50_compose_prefix_cc86(prefix_utf8);
+ case 0xa8 :
+ return grn_nfkc50_compose_prefix_cca8(prefix_utf8);
+ case 0x87 :
+ return grn_nfkc50_compose_prefix_cc87(prefix_utf8);
+ case 0x8c :
+ return grn_nfkc50_compose_prefix_cc8c(prefix_utf8);
+ case 0x8b :
+ return grn_nfkc50_compose_prefix_cc8b(prefix_utf8);
+ case 0x9b :
+ return grn_nfkc50_compose_prefix_cc9b(prefix_utf8);
+ case 0x8f :
+ return grn_nfkc50_compose_prefix_cc8f(prefix_utf8);
+ case 0x91 :
+ return grn_nfkc50_compose_prefix_cc91(prefix_utf8);
+ case 0xa6 :
+ return grn_nfkc50_compose_prefix_cca6(prefix_utf8);
+ case 0xa5 :
+ return grn_nfkc50_compose_prefix_cca5(prefix_utf8);
+ case 0xa3 :
+ return grn_nfkc50_compose_prefix_cca3(prefix_utf8);
+ case 0xb1 :
+ return grn_nfkc50_compose_prefix_ccb1(prefix_utf8);
+ case 0xad :
+ return grn_nfkc50_compose_prefix_ccad(prefix_utf8);
+ case 0xb0 :
+ return grn_nfkc50_compose_prefix_ccb0(prefix_utf8);
+ case 0xae :
+ return grn_nfkc50_compose_prefix_ccae(prefix_utf8);
+ case 0xa4 :
+ return grn_nfkc50_compose_prefix_cca4(prefix_utf8);
+ case 0x89 :
+ return grn_nfkc50_compose_prefix_cc89(prefix_utf8);
+ case 0x93 :
+ return grn_nfkc50_compose_prefix_cc93(prefix_utf8);
+ case 0x94 :
+ return grn_nfkc50_compose_prefix_cc94(prefix_utf8);
+ case 0xb8 :
+ return grn_nfkc50_compose_prefix_ccb8(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xcd :
+ switch (suffix_utf8[1]) {
+ case 0x82 :
+ return grn_nfkc50_compose_prefix_cd82(prefix_utf8);
+ case 0x85 :
+ return grn_nfkc50_compose_prefix_cd85(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xd9 :
+ switch (suffix_utf8[1]) {
+ case 0x93 :
+ return grn_nfkc50_compose_prefix_d993(prefix_utf8);
+ case 0x94 :
+ return grn_nfkc50_compose_prefix_d994(prefix_utf8);
+ case 0x95 :
+ return grn_nfkc50_compose_prefix_d995(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xe0 :
+ switch (suffix_utf8[1]) {
+ case 0xa4 :
+ switch (suffix_utf8[2]) {
+ case 0xbc :
+ return grn_nfkc50_compose_prefix_e0a4bc(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xa6 :
+ switch (suffix_utf8[2]) {
+ case 0xbe :
+ return grn_nfkc50_compose_prefix_e0a6be(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xa7 :
+ switch (suffix_utf8[2]) {
+ case 0x97 :
+ return grn_nfkc50_compose_prefix_e0a797(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xac :
+ switch (suffix_utf8[2]) {
+ case 0xbe :
+ return grn_nfkc50_compose_prefix_e0acbe(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xad :
+ switch (suffix_utf8[2]) {
+ case 0x96 :
+ return grn_nfkc50_compose_prefix_e0ad96(prefix_utf8);
+ case 0x97 :
+ return grn_nfkc50_compose_prefix_e0ad97(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xae :
+ switch (suffix_utf8[2]) {
+ case 0xbe :
+ return grn_nfkc50_compose_prefix_e0aebe(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xaf :
+ switch (suffix_utf8[2]) {
+ case 0x97 :
+ return grn_nfkc50_compose_prefix_e0af97(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xb1 :
+ switch (suffix_utf8[2]) {
+ case 0x96 :
+ return grn_nfkc50_compose_prefix_e0b196(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xb3 :
+ switch (suffix_utf8[2]) {
+ case 0x95 :
+ return grn_nfkc50_compose_prefix_e0b395(prefix_utf8);
+ case 0x96 :
+ return grn_nfkc50_compose_prefix_e0b396(prefix_utf8);
+ case 0x82 :
+ return grn_nfkc50_compose_prefix_e0b382(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xb4 :
+ switch (suffix_utf8[2]) {
+ case 0xbe :
+ return grn_nfkc50_compose_prefix_e0b4be(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xb5 :
+ switch (suffix_utf8[2]) {
+ case 0x97 :
+ return grn_nfkc50_compose_prefix_e0b597(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xb7 :
+ switch (suffix_utf8[2]) {
+ case 0x8a :
+ return grn_nfkc50_compose_prefix_e0b78a(prefix_utf8);
+ case 0x8f :
+ return grn_nfkc50_compose_prefix_e0b78f(prefix_utf8);
+ case 0x9f :
+ return grn_nfkc50_compose_prefix_e0b79f(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xe1 :
+ switch (suffix_utf8[1]) {
+ case 0x80 :
+ switch (suffix_utf8[2]) {
+ case 0xae :
+ return grn_nfkc50_compose_prefix_e180ae(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0x85 :
+ switch (suffix_utf8[2]) {
+ case 0xa1 :
+ return grn_nfkc50_compose_prefix_e185a1(prefix_utf8);
+ case 0xa2 :
+ return grn_nfkc50_compose_prefix_e185a2(prefix_utf8);
+ case 0xa3 :
+ return grn_nfkc50_compose_prefix_e185a3(prefix_utf8);
+ case 0xa4 :
+ return grn_nfkc50_compose_prefix_e185a4(prefix_utf8);
+ case 0xa5 :
+ return grn_nfkc50_compose_prefix_e185a5(prefix_utf8);
+ case 0xa6 :
+ return grn_nfkc50_compose_prefix_e185a6(prefix_utf8);
+ case 0xa7 :
+ return grn_nfkc50_compose_prefix_e185a7(prefix_utf8);
+ case 0xa8 :
+ return grn_nfkc50_compose_prefix_e185a8(prefix_utf8);
+ case 0xa9 :
+ return grn_nfkc50_compose_prefix_e185a9(prefix_utf8);
+ case 0xaa :
+ return grn_nfkc50_compose_prefix_e185aa(prefix_utf8);
+ case 0xab :
+ return grn_nfkc50_compose_prefix_e185ab(prefix_utf8);
+ case 0xac :
+ return grn_nfkc50_compose_prefix_e185ac(prefix_utf8);
+ case 0xad :
+ return grn_nfkc50_compose_prefix_e185ad(prefix_utf8);
+ case 0xae :
+ return grn_nfkc50_compose_prefix_e185ae(prefix_utf8);
+ case 0xaf :
+ return grn_nfkc50_compose_prefix_e185af(prefix_utf8);
+ case 0xb0 :
+ return grn_nfkc50_compose_prefix_e185b0(prefix_utf8);
+ case 0xb1 :
+ return grn_nfkc50_compose_prefix_e185b1(prefix_utf8);
+ case 0xb2 :
+ return grn_nfkc50_compose_prefix_e185b2(prefix_utf8);
+ case 0xb3 :
+ return grn_nfkc50_compose_prefix_e185b3(prefix_utf8);
+ case 0xb4 :
+ return grn_nfkc50_compose_prefix_e185b4(prefix_utf8);
+ case 0xb5 :
+ return grn_nfkc50_compose_prefix_e185b5(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0x86 :
+ switch (suffix_utf8[2]) {
+ case 0xa8 :
+ return grn_nfkc50_compose_prefix_e186a8(prefix_utf8);
+ case 0xa9 :
+ return grn_nfkc50_compose_prefix_e186a9(prefix_utf8);
+ case 0xaa :
+ return grn_nfkc50_compose_prefix_e186aa(prefix_utf8);
+ case 0xab :
+ return grn_nfkc50_compose_prefix_e186ab(prefix_utf8);
+ case 0xac :
+ return grn_nfkc50_compose_prefix_e186ac(prefix_utf8);
+ case 0xad :
+ return grn_nfkc50_compose_prefix_e186ad(prefix_utf8);
+ case 0xae :
+ return grn_nfkc50_compose_prefix_e186ae(prefix_utf8);
+ case 0xaf :
+ return grn_nfkc50_compose_prefix_e186af(prefix_utf8);
+ case 0xb0 :
+ return grn_nfkc50_compose_prefix_e186b0(prefix_utf8);
+ case 0xb1 :
+ return grn_nfkc50_compose_prefix_e186b1(prefix_utf8);
+ case 0xb2 :
+ return grn_nfkc50_compose_prefix_e186b2(prefix_utf8);
+ case 0xb3 :
+ return grn_nfkc50_compose_prefix_e186b3(prefix_utf8);
+ case 0xb4 :
+ return grn_nfkc50_compose_prefix_e186b4(prefix_utf8);
+ case 0xb5 :
+ return grn_nfkc50_compose_prefix_e186b5(prefix_utf8);
+ case 0xb6 :
+ return grn_nfkc50_compose_prefix_e186b6(prefix_utf8);
+ case 0xb7 :
+ return grn_nfkc50_compose_prefix_e186b7(prefix_utf8);
+ case 0xb8 :
+ return grn_nfkc50_compose_prefix_e186b8(prefix_utf8);
+ case 0xb9 :
+ return grn_nfkc50_compose_prefix_e186b9(prefix_utf8);
+ case 0xba :
+ return grn_nfkc50_compose_prefix_e186ba(prefix_utf8);
+ case 0xbb :
+ return grn_nfkc50_compose_prefix_e186bb(prefix_utf8);
+ case 0xbc :
+ return grn_nfkc50_compose_prefix_e186bc(prefix_utf8);
+ case 0xbd :
+ return grn_nfkc50_compose_prefix_e186bd(prefix_utf8);
+ case 0xbe :
+ return grn_nfkc50_compose_prefix_e186be(prefix_utf8);
+ case 0xbf :
+ return grn_nfkc50_compose_prefix_e186bf(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0x87 :
+ switch (suffix_utf8[2]) {
+ case 0x80 :
+ return grn_nfkc50_compose_prefix_e18780(prefix_utf8);
+ case 0x81 :
+ return grn_nfkc50_compose_prefix_e18781(prefix_utf8);
+ case 0x82 :
+ return grn_nfkc50_compose_prefix_e18782(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ case 0xac :
+ switch (suffix_utf8[2]) {
+ case 0xb5 :
+ return grn_nfkc50_compose_prefix_e1acb5(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ case 0xe3 :
+ switch (suffix_utf8[1]) {
+ case 0x82 :
+ switch (suffix_utf8[2]) {
+ case 0x99 :
+ return grn_nfkc50_compose_prefix_e38299(prefix_utf8);
+ case 0x9a :
+ return grn_nfkc50_compose_prefix_e3829a(prefix_utf8);
+ default :
+ return NULL;
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+#endif /* GRN_WITH_NFKC */
+
diff --git a/storage/mroonga/vendor/groonga/lib/normalizer.c b/storage/mroonga/vendor/groonga/lib/normalizer.c
index 5999bf64317..6004372f01f 100644
--- a/storage/mroonga/vendor/groonga/lib/normalizer.c
+++ b/storage/mroonga/vendor/groonga/lib/normalizer.c
@@ -20,6 +20,7 @@
#include "grn_normalizer.h"
#include "grn_string.h"
+#include "grn_nfkc.h"
#include <groonga/normalizer.h>
#include <groonga/tokenizer.h>
@@ -559,9 +560,6 @@ sjis_normalize(grn_ctx *ctx, grn_string *nstr)
}
#ifdef GRN_WITH_NFKC
-const char *grn_nfkc_map1(const unsigned char *str);
-const char *grn_nfkc_map2(const unsigned char *prefix, const unsigned char *suffix);
-
static inline int
grn_str_charlen_utf8(grn_ctx *ctx, const unsigned char *str, const unsigned char *end)
{
@@ -661,13 +659,13 @@ utf8_normalize(grn_ctx *ctx, grn_string *nstr)
GRN_ENC_UTF8)) {
continue;
}
- if ((p = (unsigned char *)grn_nfkc_map1(s))) {
+ if ((p = (unsigned char *)grn_nfkc_decompose(s))) {
pe = p + strlen((char *)p);
} else {
p = s;
pe = p + ls;
}
- if (d_ && (p2 = (unsigned char *)grn_nfkc_map2(d_, p))) {
+ if (d_ && (p2 = (unsigned char *)grn_nfkc_compose(d_, p))) {
p = p2;
pe = p + strlen((char *)p);
if (cp) { cp--; }
diff --git a/storage/mroonga/vendor/groonga/lib/obj.c b/storage/mroonga/vendor/groonga/lib/obj.c
index 87850b6357b..09d71ec0709 100644
--- a/storage/mroonga/vendor/groonga/lib/obj.c
+++ b/storage/mroonga/vendor/groonga/lib/obj.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,9 +15,57 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
#include "grn.h"
-#include "grn_db.h"
-#include <groonga/obj.h>
+#include "grn_index_column.h"
+#include "grn_pat.h"
+#include "grn_dat.h"
+#include "grn_ii.h"
+
+grn_bool
+grn_obj_is_true(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!obj) {
+ return GRN_FALSE;
+ }
+
+ switch (obj->header.type) {
+ case GRN_BULK :
+ switch (obj->header.domain) {
+ case GRN_DB_BOOL :
+ return GRN_BOOL_VALUE(obj);
+ break;
+ case GRN_DB_INT32 :
+ return GRN_INT32_VALUE(obj) != 0;
+ break;
+ case GRN_DB_UINT32 :
+ return GRN_UINT32_VALUE(obj) != 0;
+ break;
+ case GRN_DB_FLOAT : {
+ double float_value;
+ float_value = GRN_FLOAT_VALUE(obj);
+ return (float_value < -DBL_EPSILON ||
+ DBL_EPSILON < float_value);
+ break;
+ }
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ return GRN_TEXT_LEN(obj) != 0;
+ break;
+ default :
+ return GRN_FALSE;
+ break;
+ }
+ break;
+ case GRN_VECTOR :
+ return GRN_TRUE;
+ break;
+ default :
+ return GRN_FALSE;
+ break;
+ }
+}
grn_bool
grn_obj_is_builtin(grn_ctx *ctx, grn_obj *obj)
@@ -27,11 +75,27 @@ grn_obj_is_builtin(grn_ctx *ctx, grn_obj *obj)
if (!obj) { return GRN_FALSE; }
id = grn_obj_id(ctx, obj);
- if (id == GRN_ID_NIL) {
+ return grn_id_is_builtin(ctx, id);
+}
+
+grn_bool
+grn_obj_is_bulk(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!obj) {
+ return GRN_FALSE;
+ }
+
+ return obj->header.type == GRN_BULK;
+}
+
+grn_bool
+grn_obj_is_text_family_bulk(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!grn_obj_is_bulk(ctx, obj)) {
return GRN_FALSE;
- } else {
- return id < GRN_N_RESERVED_TYPES;
}
+
+ return GRN_TYPE_IS_TEXT_FAMILY(obj->header.domain);
}
grn_bool
@@ -57,6 +121,152 @@ grn_obj_is_table(grn_ctx *ctx, grn_obj *obj)
}
grn_bool
+grn_obj_is_column(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_bool is_column = GRN_FALSE;
+
+ if (!obj) {
+ return GRN_FALSE;
+ }
+
+ switch (obj->header.type) {
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ is_column = GRN_TRUE;
+ default :
+ break;
+ }
+
+ return is_column;
+}
+
+grn_bool
+grn_obj_is_scalar_column(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!grn_obj_is_column(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ return (obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_SCALAR;
+}
+
+grn_bool
+grn_obj_is_vector_column(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!grn_obj_is_column(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ return ((obj->header.type == GRN_COLUMN_VAR_SIZE) &&
+ ((obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) ==
+ GRN_OBJ_COLUMN_VECTOR));
+}
+
+grn_bool
+grn_obj_is_weight_vector_column(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!grn_obj_is_vector_column(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ return (obj->header.flags & GRN_OBJ_WITH_WEIGHT) == GRN_OBJ_WITH_WEIGHT;
+}
+
+grn_bool
+grn_obj_is_reference_column(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_obj *range;
+
+ if (!grn_obj_is_column(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ range = grn_ctx_at(ctx, grn_obj_get_range(ctx, obj));
+ if (!range) {
+ return GRN_FALSE;
+ }
+
+ switch (range->header.type) {
+ case GRN_TABLE_HASH_KEY:
+ case GRN_TABLE_PAT_KEY:
+ case GRN_TABLE_DAT_KEY:
+ case GRN_TABLE_NO_KEY:
+ return GRN_TRUE;
+ default:
+ return GRN_FALSE;
+ }
+}
+
+grn_bool
+grn_obj_is_data_column(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!grn_obj_is_column(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ return obj->header.type == GRN_COLUMN_FIX_SIZE ||
+ obj->header.type == GRN_COLUMN_VAR_SIZE;
+}
+
+grn_bool
+grn_obj_is_index_column(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!grn_obj_is_column(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ return obj->header.type == GRN_COLUMN_INDEX;
+}
+
+grn_bool
+grn_obj_is_accessor(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!obj) {
+ return GRN_FALSE;
+ }
+
+ return obj->header.type == GRN_ACCESSOR;
+}
+
+grn_bool
+grn_obj_is_key_accessor(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_accessor *accessor;
+
+ if (!grn_obj_is_accessor(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ accessor = (grn_accessor *)obj;
+ if (accessor->next) {
+ return GRN_FALSE;
+ }
+
+ return accessor->action == GRN_ACCESSOR_GET_KEY;
+}
+
+grn_bool
+grn_obj_is_type(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!obj) {
+ return GRN_FALSE;
+ }
+
+ return obj->header.type == GRN_TYPE;
+}
+
+grn_bool
+grn_obj_is_text_family_type(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!grn_obj_is_type(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ return GRN_TYPE_IS_TEXT_FAMILY(grn_obj_id(ctx, obj));
+}
+
+grn_bool
grn_obj_is_proc(grn_ctx *ctx, grn_obj *obj)
{
if (!obj) {
@@ -67,6 +277,19 @@ grn_obj_is_proc(grn_ctx *ctx, grn_obj *obj)
}
grn_bool
+grn_obj_is_tokenizer_proc(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_proc *proc;
+
+ if (!grn_obj_is_proc(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ proc = (grn_proc *)obj;
+ return proc->type == GRN_PROC_TOKENIZER;
+}
+
+grn_bool
grn_obj_is_function_proc(grn_ctx *ctx, grn_obj *obj)
{
grn_proc *proc;
@@ -89,7 +312,46 @@ grn_obj_is_selector_proc(grn_ctx *ctx, grn_obj *obj)
}
proc = (grn_proc *)obj;
- return proc->selector != NULL;
+ return proc->callbacks.function.selector != NULL;
+}
+
+grn_bool
+grn_obj_is_selector_only_proc(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_proc *proc;
+
+ if (!grn_obj_is_selector_proc(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ proc = (grn_proc *)obj;
+ return proc->funcs[PROC_INIT] == NULL;
+}
+
+grn_bool
+grn_obj_is_normalizer_proc(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_proc *proc;
+
+ if (!grn_obj_is_proc(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ proc = (grn_proc *)obj;
+ return proc->type == GRN_PROC_NORMALIZER;
+}
+
+grn_bool
+grn_obj_is_token_filter_proc(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_proc *proc;
+
+ if (!grn_obj_is_proc(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ proc = (grn_proc *)obj;
+ return proc->type == GRN_PROC_TOKEN_FILTER;
}
grn_bool
@@ -104,3 +366,324 @@ grn_obj_is_scorer_proc(grn_ctx *ctx, grn_obj *obj)
proc = (grn_proc *)obj;
return proc->type == GRN_PROC_SCORER;
}
+
+grn_bool
+grn_obj_is_window_function_proc(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_proc *proc;
+
+ if (!grn_obj_is_proc(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ proc = (grn_proc *)obj;
+ return proc->type == GRN_PROC_WINDOW_FUNCTION;
+}
+
+grn_bool
+grn_obj_is_expr(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!obj) {
+ return GRN_FALSE;
+ }
+
+ return obj->header.type == GRN_EXPR;
+}
+
+static void
+grn_db_reindex(grn_ctx *ctx, grn_obj *db)
+{
+ grn_table_cursor *cursor;
+ grn_id id;
+
+ cursor = grn_table_cursor_open(ctx, db,
+ NULL, 0, NULL, 0,
+ 0, -1,
+ GRN_CURSOR_BY_ID);
+ if (!cursor) {
+ return;
+ }
+
+ while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ grn_obj *object;
+
+ object = grn_ctx_at(ctx, id);
+ if (!object) {
+ ERRCLR(ctx);
+ continue;
+ }
+
+ switch (object->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ grn_obj_reindex(ctx, object);
+ break;
+ default:
+ break;
+ }
+
+ grn_obj_unlink(ctx, object);
+
+ if (ctx->rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+}
+
+static void
+grn_table_reindex(grn_ctx *ctx, grn_obj *table)
+{
+ grn_hash *columns;
+
+ columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY | GRN_HASH_TINY);
+ if (!columns) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[table][reindex] failed to create a table to store columns");
+ return;
+ }
+
+ if (grn_table_columns(ctx, table, "", 0, (grn_obj *)columns) > 0) {
+ grn_id *key;
+ GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, {
+ grn_obj *column = grn_ctx_at(ctx, *key);
+ if (column && column->header.type == GRN_COLUMN_INDEX) {
+ grn_obj_reindex(ctx, column);
+ }
+ });
+ }
+ grn_hash_close(ctx, columns);
+}
+
+static void
+grn_data_column_reindex(grn_ctx *ctx, grn_obj *data_column)
+{
+ grn_hook *hooks;
+
+ for (hooks = DB_OBJ(data_column)->hooks[GRN_HOOK_SET];
+ hooks;
+ hooks = hooks->next) {
+ grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks);
+ grn_obj *target = grn_ctx_at(ctx, data->target);
+ if (target->header.type != GRN_COLUMN_INDEX) {
+ continue;
+ }
+ grn_obj_reindex(ctx, target);
+ if (ctx->rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+}
+
+grn_rc
+grn_obj_reindex(grn_ctx *ctx, grn_obj *obj)
+{
+ GRN_API_ENTER;
+
+ if (!obj) {
+ ERR(GRN_INVALID_ARGUMENT, "[object][reindex] object must not be NULL");
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ switch (obj->header.type) {
+ case GRN_DB :
+ grn_db_reindex(ctx, obj);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ grn_table_reindex(ctx, obj);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ grn_data_column_reindex(ctx, obj);
+ break;
+ case GRN_COLUMN_INDEX :
+ grn_index_column_rebuild(ctx, obj);
+ break;
+ default :
+ {
+ grn_obj type_name;
+ GRN_TEXT_INIT(&type_name, 0);
+ grn_inspect_type(ctx, &type_name, obj->header.type);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[object][reindex] object must be TABLE_HASH_KEY, "
+ "TABLE_PAT_KEY, TABLE_DAT_KEY or COLUMN_INDEX: <%.*s>",
+ (int)GRN_TEXT_LEN(&type_name),
+ GRN_TEXT_VALUE(&type_name));
+ GRN_OBJ_FIN(ctx, &type_name);
+ GRN_API_RETURN(ctx->rc);
+ }
+ break;
+ }
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+const char *
+grn_obj_type_to_string(uint8_t type)
+{
+ switch (type) {
+ case GRN_VOID :
+ return "void";
+ case GRN_BULK :
+ return "bulk";
+ case GRN_PTR :
+ return "ptr";
+ case GRN_UVECTOR :
+ return "uvector";
+ case GRN_PVECTOR :
+ return "pvector";
+ case GRN_VECTOR :
+ return "vector";
+ case GRN_MSG :
+ return "msg";
+ case GRN_QUERY :
+ return "query";
+ case GRN_ACCESSOR :
+ return "accessor";
+ case GRN_SNIP :
+ return "snip";
+ case GRN_PATSNIP :
+ return "patsnip";
+ case GRN_STRING :
+ return "string";
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ return "cursor:table:hash_key";
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ return "cursor:table:pat_key";
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ return "cursor:table:dat_key";
+ case GRN_CURSOR_TABLE_NO_KEY :
+ return "cursor:table:no_key";
+ case GRN_CURSOR_COLUMN_INDEX :
+ return "cursor:column:index";
+ case GRN_CURSOR_COLUMN_GEO_INDEX :
+ return "cursor:column:geo_index";
+ case GRN_CURSOR_CONFIG :
+ return "cursor:config";
+ case GRN_TYPE :
+ return "type";
+ case GRN_PROC :
+ return "proc";
+ case GRN_EXPR :
+ return "expr";
+ case GRN_TABLE_HASH_KEY :
+ return "table:hash_key";
+ case GRN_TABLE_PAT_KEY :
+ return "table:pat_key";
+ case GRN_TABLE_DAT_KEY :
+ return "table:dat_key";
+ case GRN_TABLE_NO_KEY :
+ return "table:no_key";
+ case GRN_DB :
+ return "db";
+ case GRN_COLUMN_FIX_SIZE :
+ return "column:fix_size";
+ case GRN_COLUMN_VAR_SIZE :
+ return "column:var_size";
+ case GRN_COLUMN_INDEX :
+ return "column:index";
+ default :
+ return "unknown";
+ }
+}
+
+grn_bool
+grn_obj_name_is_column(grn_ctx *ctx, const char *name, int name_len)
+{
+ if (!name) {
+ return GRN_FALSE;
+ }
+
+ if (name_len < 0) {
+ name_len = strlen(name);
+ }
+
+ return memchr(name, GRN_DB_DELIMITER, name_len) != NULL;
+}
+
+grn_io *
+grn_obj_get_io(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_io *io = NULL;
+
+ if (!obj) {
+ return NULL;
+ }
+
+ if (obj->header.type == GRN_DB) {
+ obj = ((grn_db *)obj)->keys;
+ }
+
+ switch (obj->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ io = ((grn_pat *)obj)->io;
+ break;
+ case GRN_TABLE_DAT_KEY :
+ io = ((grn_dat *)obj)->io;
+ break;
+ case GRN_TABLE_HASH_KEY :
+ io = ((grn_hash *)obj)->io;
+ break;
+ case GRN_TABLE_NO_KEY :
+ io = ((grn_array *)obj)->io;
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ io = ((grn_ja *)obj)->io;
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ io = ((grn_ra *)obj)->io;
+ break;
+ case GRN_COLUMN_INDEX :
+ io = ((grn_ii *)obj)->seg;
+ break;
+ }
+
+ return io;
+}
+
+size_t
+grn_obj_get_disk_usage(grn_ctx *ctx, grn_obj *obj)
+{
+ size_t usage = 0;
+
+ GRN_API_ENTER;
+
+ if (!obj) {
+ ERR(GRN_INVALID_ARGUMENT, "[object][disk-usage] object must not be NULL");
+ GRN_API_RETURN(0);
+ }
+
+ switch (obj->header.type) {
+ case GRN_DB :
+ {
+ grn_db *db = (grn_db *)obj;
+ usage = grn_obj_get_disk_usage(ctx, db->keys);
+ if (db->specs) {
+ usage += grn_obj_get_disk_usage(ctx, (grn_obj *)(db->specs));
+ }
+ usage += grn_obj_get_disk_usage(ctx, (grn_obj *)(db->config));
+ }
+ break;
+ case GRN_TABLE_DAT_KEY :
+ usage = grn_dat_get_disk_usage(ctx, (grn_dat *)obj);
+ break;
+ case GRN_COLUMN_INDEX :
+ usage = grn_ii_get_disk_usage(ctx, (grn_ii *)obj);
+ break;
+ default :
+ {
+ grn_io *io;
+ io = grn_obj_get_io(ctx, obj);
+ if (io) {
+ usage = grn_io_get_disk_usage(ctx, io);
+ }
+ }
+ break;
+ }
+
+ GRN_API_RETURN(usage);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/operator.c b/storage/mroonga/vendor/groonga/lib/operator.c
index 1fc463eb00d..bece4388383 100644
--- a/storage/mroonga/vendor/groonga/lib/operator.c
+++ b/storage/mroonga/vendor/groonga/lib/operator.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014-2015 Brazil
+ Copyright(C) 2014-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,7 @@
#endif
#ifdef GRN_SUPPORT_REGEXP
-# include <oniguruma.h>
+# include <onigmo.h>
#endif
static const char *operator_names[] = {
@@ -109,10 +109,11 @@ static const char *operator_names[] = {
"table_group",
"json_put",
"get_member",
- "regexp"
+ "regexp",
+ "fuzzy"
};
-#define GRN_OP_LAST GRN_OP_REGEXP
+#define GRN_OP_LAST GRN_OP_FUZZY
const char *
grn_operator_to_string(grn_operator op)
@@ -124,6 +125,46 @@ grn_operator_to_string(grn_operator op)
}
}
+grn_operator_exec_func *
+grn_operator_to_exec_func(grn_operator op)
+{
+ grn_operator_exec_func *func = NULL;
+
+ switch (op) {
+ case GRN_OP_EQUAL :
+ func = grn_operator_exec_equal;
+ break;
+ case GRN_OP_NOT_EQUAL :
+ func = grn_operator_exec_not_equal;
+ break;
+ case GRN_OP_LESS :
+ func = grn_operator_exec_less;
+ break;
+ case GRN_OP_GREATER :
+ func = grn_operator_exec_greater;
+ break;
+ case GRN_OP_LESS_EQUAL :
+ func = grn_operator_exec_less_equal;
+ break;
+ case GRN_OP_GREATER_EQUAL :
+ func = grn_operator_exec_greater_equal;
+ break;
+ case GRN_OP_MATCH :
+ func = grn_operator_exec_match;
+ break;
+ case GRN_OP_PREFIX :
+ func = grn_operator_exec_prefix;
+ break;
+ case GRN_OP_REGEXP :
+ func = grn_operator_exec_regexp;
+ break;
+ default :
+ break;
+ }
+
+ return func;
+}
+
#define DO_EQ_SUB do {\
switch (y->header.domain) {\
case GRN_DB_INT8 :\
@@ -343,7 +384,7 @@ grn_operator_to_string(grn_operator op)
grn_bool
grn_operator_exec_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
{
- grn_bool r;
+ grn_bool r = GRN_FALSE;
GRN_API_ENTER;
DO_EQ(x, y, r);
GRN_API_RETURN(r);
@@ -352,14 +393,17 @@ grn_operator_exec_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
grn_bool
grn_operator_exec_not_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
{
- grn_bool r= 0;
+ grn_bool r = GRN_FALSE;
GRN_API_ENTER;
DO_EQ(x, y, r);
GRN_API_RETURN(!r);
}
-#define DO_COMPARE_SUB_NUMERIC(y,op) do {\
+#define DO_COMPARE_SCALAR_SUB_NUMERIC(y,op) do {\
switch ((y)->header.domain) {\
+ case GRN_DB_BOOL :\
+ r = (x_ op (uint8_t)(GRN_BOOL_VALUE(y) ? 1 : 0));\
+ break;\
case GRN_DB_INT8 :\
r = (x_ op GRN_INT8_VALUE(y));\
break;\
@@ -396,7 +440,7 @@ grn_operator_exec_not_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
}\
} while (0)
-#define DO_COMPARE_SUB(op) do {\
+#define DO_COMPARE_SCALAR_SUB_BUILTIN(op) do {\
switch (y->header.domain) {\
case GRN_DB_SHORT_TEXT :\
case GRN_DB_TEXT :\
@@ -407,53 +451,93 @@ grn_operator_exec_not_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
if (grn_obj_cast(ctx, y, &y_, GRN_FALSE)) {\
r = GRN_FALSE;\
} else {\
- DO_COMPARE_SUB_NUMERIC(&y_, op);\
+ DO_COMPARE_SCALAR_SUB_NUMERIC(&y_, op);\
}\
GRN_OBJ_FIN(ctx, &y_);\
}\
break;\
default :\
- DO_COMPARE_SUB_NUMERIC(y,op);\
+ DO_COMPARE_SCALAR_SUB_NUMERIC(y,op);\
break;\
}\
} while (0)
-#define DO_COMPARE_BUILTIN(x,y,r,op) do {\
+#define DO_COMPARE_SCALAR_SUB(op) do {\
+ if (y->header.domain >= GRN_N_RESERVED_TYPES) {\
+ grn_obj *y_table;\
+ y_table = grn_ctx_at(ctx, y->header.domain);\
+ switch (y_table->header.type) {\
+ case GRN_TABLE_HASH_KEY :\
+ case GRN_TABLE_PAT_KEY :\
+ case GRN_TABLE_DAT_KEY :\
+ {\
+ grn_obj y_key;\
+ int length;\
+ GRN_OBJ_INIT(&y_key, GRN_BULK, 0, y_table->header.domain);\
+ length = grn_table_get_key2(ctx, y_table, GRN_RECORD_VALUE(y), &y_key);\
+ if (length > 0) {\
+ grn_obj *y_original = y;\
+ y = &y_key;\
+ DO_COMPARE_SCALAR_SUB_BUILTIN(op);\
+ y = y_original;\
+ } else {\
+ r = GRN_FALSE;\
+ }\
+ GRN_OBJ_FIN(ctx, &y_key);\
+ }\
+ break;\
+ default :\
+ r = GRN_FALSE;\
+ break;\
+ }\
+ grn_obj_unlink(ctx, y_table);\
+ } else {\
+ DO_COMPARE_SCALAR_SUB_BUILTIN(op);\
+ }\
+} while (0)
+
+#define DO_COMPARE_SCALAR_BUILTIN(x,y,r,op) do {\
switch (x->header.domain) {\
+ case GRN_DB_BOOL :\
+ {\
+ uint8_t x_ = GRN_BOOL_VALUE(x) ? 1 : 0;\
+ DO_COMPARE_SCALAR_SUB(op);\
+ }\
+ break;\
case GRN_DB_INT8 :\
{\
int8_t x_ = GRN_INT8_VALUE(x);\
- DO_COMPARE_SUB(op);\
+ DO_COMPARE_SCALAR_SUB(op);\
}\
break;\
case GRN_DB_UINT8 :\
{\
uint8_t x_ = GRN_UINT8_VALUE(x);\
- DO_COMPARE_SUB(op);\
+ DO_COMPARE_SCALAR_SUB(op);\
}\
break;\
case GRN_DB_INT16 :\
{\
int16_t x_ = GRN_INT16_VALUE(x);\
- DO_COMPARE_SUB(op);\
+ DO_COMPARE_SCALAR_SUB(op);\
}\
break;\
case GRN_DB_UINT16 :\
{\
uint16_t x_ = GRN_UINT16_VALUE(x);\
- DO_COMPARE_SUB(op);\
+ DO_COMPARE_SCALAR_SUB(op);\
}\
break;\
case GRN_DB_INT32 :\
{\
int32_t x_ = GRN_INT32_VALUE(x);\
- DO_COMPARE_SUB(op);\
+ DO_COMPARE_SCALAR_SUB(op);\
}\
break;\
case GRN_DB_UINT32 :\
{\
uint32_t x_ = GRN_UINT32_VALUE(x);\
- DO_COMPARE_SUB(op);\
+ DO_COMPARE_SCALAR_SUB(op);\
}\
break;\
case GRN_DB_TIME :\
@@ -499,19 +583,19 @@ grn_operator_exec_not_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
case GRN_DB_INT64 :\
{\
int64_t x_ = GRN_INT64_VALUE(x);\
- DO_COMPARE_SUB(op);\
+ DO_COMPARE_SCALAR_SUB(op);\
}\
break;\
case GRN_DB_UINT64 :\
{\
uint64_t x_ = GRN_UINT64_VALUE(x);\
- DO_COMPARE_SUB(op);\
+ DO_COMPARE_SCALAR_SUB(op);\
}\
break;\
case GRN_DB_FLOAT :\
{\
double x_ = GRN_FLOAT_VALUE(x);\
- DO_COMPARE_SUB(op);\
+ DO_COMPARE_SCALAR_SUB(op);\
}\
break;\
case GRN_DB_SHORT_TEXT :\
@@ -533,7 +617,7 @@ grn_operator_exec_not_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
} else {\
const char *q_ = GRN_TEXT_VALUE(x);\
int x_ = grn_atoi(q_, q_ + GRN_TEXT_LEN(x), NULL);\
- DO_COMPARE_SUB(op);\
+ DO_COMPARE_SCALAR_SUB(op);\
}\
break;\
default :\
@@ -542,43 +626,73 @@ grn_operator_exec_not_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
}\
} while (0)
-#define DO_COMPARE(x, y, r, op) do {\
+#define DO_COMPARE_SCALAR(x, y, r, op) do {\
if (x->header.domain >= GRN_N_RESERVED_TYPES) {\
- grn_obj *table;\
- table = grn_ctx_at(ctx, x->header.domain);\
- switch (table->header.type) {\
+ grn_obj *x_table;\
+ x_table = grn_ctx_at(ctx, x->header.domain);\
+ switch (x_table->header.type) {\
case GRN_TABLE_HASH_KEY :\
case GRN_TABLE_PAT_KEY :\
+ case GRN_TABLE_DAT_KEY :\
{\
- grn_obj key;\
+ grn_obj x_key;\
int length;\
- GRN_OBJ_INIT(&key, GRN_BULK, 0, table->header.domain);\
- length = grn_table_get_key2(ctx, table, GRN_RECORD_VALUE(x), &key);\
+ GRN_OBJ_INIT(&x_key, GRN_BULK, 0, x_table->header.domain);\
+ length = grn_table_get_key2(ctx, x_table, GRN_RECORD_VALUE(x), &x_key);\
if (length > 0) {\
grn_obj *x_original = x;\
- x = &key;\
- DO_COMPARE_BUILTIN((&key), y, r, op);\
+ x = &x_key;\
+ DO_COMPARE_SCALAR_BUILTIN((&x_key), y, r, op);\
x = x_original;\
} else {\
r = GRN_FALSE;\
}\
- GRN_OBJ_FIN(ctx, &key);\
+ GRN_OBJ_FIN(ctx, &x_key);\
}\
break;\
default :\
r = GRN_FALSE;\
break;\
}\
- grn_obj_unlink(ctx, table);\
+ grn_obj_unlink(ctx, x_table);\
} else {\
- DO_COMPARE_BUILTIN(x, y, r, op);\
+ DO_COMPARE_SCALAR_BUILTIN(x, y, r, op);\
+ }\
+} while (0)
+
+#define DO_COMPARE(x, y, r, op) do {\
+ if (x->header.type == GRN_UVECTOR) {\
+ grn_obj element_buffer;\
+ unsigned int i, n;\
+ unsigned int element_size;\
+ GRN_VALUE_FIX_SIZE_INIT(&element_buffer, 0, x->header.domain);\
+ n = grn_uvector_size(ctx, x);\
+ element_size = grn_uvector_element_size(ctx, x);\
+ for (i = 0; i < n; i++) {\
+ grn_obj *element = &element_buffer;\
+ GRN_BULK_REWIND(element);\
+ grn_bulk_write(ctx, element,\
+ ((uint8_t *)GRN_BULK_HEAD(x)) + (element_size * i),\
+ element_size);\
+ DO_COMPARE_SCALAR(element, y, r, op);\
+ if (r) {\
+ break;\
+ }\
+ }\
+ GRN_OBJ_FIN(ctx, &element_buffer);\
+ } else {\
+ if (GRN_BULK_VSIZE(x) == 0 || GRN_BULK_VSIZE(y) == 0) {\
+ r = GRN_FALSE;\
+ } else {\
+ DO_COMPARE_SCALAR(x, y, r, op);\
+ }\
}\
} while (0)
grn_bool
grn_operator_exec_less(grn_ctx *ctx, grn_obj *x, grn_obj *y)
{
- grn_bool r;
+ grn_bool r = GRN_FALSE;
GRN_API_ENTER;
DO_COMPARE(x, y, r, <);
GRN_API_RETURN(r);
@@ -587,7 +701,7 @@ grn_operator_exec_less(grn_ctx *ctx, grn_obj *x, grn_obj *y)
grn_bool
grn_operator_exec_greater(grn_ctx *ctx, grn_obj *x, grn_obj *y)
{
- grn_bool r;
+ grn_bool r = GRN_FALSE;
GRN_API_ENTER;
DO_COMPARE(x, y, r, >);
GRN_API_RETURN(r);
@@ -596,7 +710,7 @@ grn_operator_exec_greater(grn_ctx *ctx, grn_obj *x, grn_obj *y)
grn_bool
grn_operator_exec_less_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
{
- grn_bool r;
+ grn_bool r = GRN_FALSE;
GRN_API_ENTER;
DO_COMPARE(x, y, r, <=);
GRN_API_RETURN(r);
@@ -605,7 +719,7 @@ grn_operator_exec_less_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
grn_bool
grn_operator_exec_greater_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
{
- grn_bool r;
+ grn_bool r = GRN_FALSE;
GRN_API_ENTER;
DO_COMPARE(x, y, r, >=);
GRN_API_RETURN(r);
@@ -665,52 +779,20 @@ exec_match_vector_bulk(grn_ctx *ctx, grn_obj *vector, grn_obj *query)
return matched;
}
-static grn_bool
-string_have_sub_text(grn_ctx *ctx,
- const char *text, unsigned int text_len,
- const char *sub_text, unsigned int sub_text_len)
-{
- /* TODO: Use more fast algorithm such as Boyer-Moore algorithm that
- * is used in snip.c. */
- const char *text_end = text + text_len;
- unsigned int sub_text_current = 0;
-
- for (; text < text_end; text++) {
- if (text[0] == sub_text[sub_text_current]) {
- sub_text_current++;
- if (sub_text_current == sub_text_len) {
- return GRN_TRUE;
- }
- } else {
- sub_text_current = 0;
- }
- }
-
- return GRN_FALSE;
-}
-
-static grn_bool
-string_have_prefix(grn_ctx *ctx,
- const char *target, unsigned int target_len,
- const char *prefix, unsigned int prefix_len)
-{
- return (target_len >= prefix_len &&
- strncmp(target, prefix, prefix_len) == 0);
-}
-
-static grn_bool
-string_match_regexp(grn_ctx *ctx,
- const char *target, unsigned int target_len,
- const char *pattern, unsigned int pattern_len)
-{
#ifdef GRN_SUPPORT_REGEXP
+static OnigRegex
+regexp_compile(grn_ctx *ctx,
+ const char *pattern,
+ unsigned int pattern_len,
+ const OnigSyntaxType *syntax)
+{
OnigRegex regex;
OnigEncoding onig_encoding;
int onig_result;
OnigErrorInfo onig_error_info;
if (ctx->encoding == GRN_ENC_NONE) {
- return GRN_FALSE;
+ return NULL;
}
switch (ctx->encoding) {
@@ -730,15 +812,16 @@ string_match_regexp(grn_ctx *ctx,
onig_encoding = ONIG_ENCODING_KOI8_R;
break;
default :
- return GRN_FALSE;
+ return NULL;
}
onig_result = onig_new(&regex,
pattern,
pattern + pattern_len,
- ONIG_OPTION_ASCII_RANGE,
+ ONIG_OPTION_ASCII_RANGE |
+ ONIG_OPTION_MULTILINE,
onig_encoding,
- ONIG_SYNTAX_RUBY,
+ syntax,
&onig_error_info);
if (onig_result != ONIG_NORMAL) {
char message[ONIG_MAX_ERROR_MESSAGE_LEN];
@@ -748,24 +831,135 @@ string_match_regexp(grn_ctx *ctx,
"failed to create regular expression object: <%.*s>: %s",
pattern_len, pattern,
message);
+ return NULL;
+ }
+
+ return regex;
+}
+
+static grn_bool
+regexp_is_match(grn_ctx *ctx, OnigRegex regex,
+ const char *target, unsigned int target_len)
+{
+ OnigPosition position;
+
+ position = onig_search(regex,
+ target,
+ target + target_len,
+ target,
+ target + target_len,
+ NULL,
+ ONIG_OPTION_NONE);
+ return position != ONIG_MISMATCH;
+}
+#endif /* GRN_SUPPORT_REGEXP */
+
+static grn_bool
+string_have_sub_text(grn_ctx *ctx,
+ const char *text, unsigned int text_len,
+ const char *sub_text, unsigned int sub_text_len)
+{
+ if (sub_text_len == 0) {
+ return GRN_FALSE;
+ }
+
+ if (sub_text_len > text_len) {
return GRN_FALSE;
}
+#ifdef GRN_SUPPORT_REGEXP
{
- OnigPosition position;
- position = onig_search(regex,
- target,
- target + target_len,
- target,
- target + target_len,
- NULL,
- ONIG_OPTION_NONE);
+ OnigRegex regex;
+ grn_bool matched;
+
+ regex = regexp_compile(ctx, sub_text, sub_text_len, ONIG_SYNTAX_ASIS);
+ if (!regex) {
+ return GRN_FALSE;
+ }
+
+ matched = regexp_is_match(ctx, regex, text, text_len);
onig_free(regex);
- return position != ONIG_MISMATCH;
+ return matched;
+ }
+#else /* GRN_SUPPORT_REGEXP */
+ {
+ const char *text_current = text;
+ const char *text_end = text + text_len;
+ const char *sub_text_current = sub_text;
+ const char *sub_text_end = sub_text + sub_text_len;
+ int sub_text_start_char_len;
+ int sub_text_char_len;
+
+ sub_text_start_char_len = grn_charlen(ctx, sub_text, sub_text_end);
+ if (sub_text_start_char_len == 0) {
+ return GRN_FALSE;
+ }
+ sub_text_char_len = sub_text_start_char_len;
+
+ while (text_current < text_end) {
+ int text_char_len;
+
+ text_char_len = grn_charlen(ctx, text_current, text_end);
+ if (text_char_len == 0) {
+ return GRN_FALSE;
+ }
+
+ if (text_char_len == sub_text_char_len &&
+ memcmp(text_current, sub_text_current, text_char_len) == 0) {
+ sub_text_current += sub_text_char_len;
+ if (sub_text_current == sub_text_end) {
+ return GRN_TRUE;
+ }
+
+ sub_text_char_len = grn_charlen(ctx, sub_text_current, sub_text_end);
+ if (sub_text_char_len == 0) {
+ return GRN_FALSE;
+ }
+ } else {
+ if (sub_text_current != sub_text) {
+ sub_text_current = sub_text;
+ sub_text_char_len = sub_text_start_char_len;
+ continue;
+ }
+ }
+
+ text_current += text_char_len;
+ }
+
+ return GRN_FALSE;
+ }
+#endif /* GRN_SUPPORT_REGEXP */
+}
+
+static grn_bool
+string_have_prefix(grn_ctx *ctx,
+ const char *target, unsigned int target_len,
+ const char *prefix, unsigned int prefix_len)
+{
+ return (target_len >= prefix_len &&
+ strncmp(target, prefix, prefix_len) == 0);
+}
+
+static grn_bool
+string_match_regexp(grn_ctx *ctx,
+ const char *target, unsigned int target_len,
+ const char *pattern, unsigned int pattern_len)
+{
+#ifdef GRN_SUPPORT_REGEXP
+ OnigRegex regex;
+ grn_bool matched;
+
+ regex = regexp_compile(ctx, pattern, pattern_len, ONIG_SYNTAX_RUBY);
+ if (!regex) {
+ return GRN_FALSE;
}
-#else
+
+ matched = regexp_is_match(ctx, regex, target, target_len);
+ onig_free(regex);
+ return matched;
+#else /* GRN_SUPPORT_REGEXP */
return GRN_FALSE;
-#endif
+#endif /* GRN_SUPPORT_REGEXP */
}
static grn_bool
@@ -778,6 +972,10 @@ exec_text_operator(grn_ctx *ctx,
{
grn_bool matched = GRN_FALSE;
+ if (target_len == 0 || query_len == 0) {
+ return GRN_FALSE;
+ }
+
switch (op) {
case GRN_OP_MATCH :
matched = string_have_sub_text(ctx, target, target_len, query, query_len);
@@ -817,23 +1015,24 @@ exec_text_operator_raw_text_raw_text(grn_ctx *ctx,
return GRN_FALSE;
}
- if (op == GRN_OP_REGEXP) {
- return exec_text_operator(ctx, op,
- target, target_len,
- query, query_len);
- }
-
normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
norm_target = grn_string_open(ctx, target, target_len, normalizer, 0);
- norm_query = grn_string_open(ctx, query, query_len, normalizer, 0);
grn_string_get_normalized(ctx, norm_target,
&norm_target_raw,
&norm_target_raw_length_in_bytes,
NULL);
- grn_string_get_normalized(ctx, norm_query,
- &norm_query_raw,
- &norm_query_raw_length_in_bytes,
- NULL);
+
+ if (op == GRN_OP_REGEXP) {
+ norm_query = NULL;
+ norm_query_raw = query;
+ norm_query_raw_length_in_bytes = query_len;
+ } else {
+ norm_query = grn_string_open(ctx, query, query_len, normalizer, 0);
+ grn_string_get_normalized(ctx, norm_query,
+ &norm_query_raw,
+ &norm_query_raw_length_in_bytes,
+ NULL);
+ }
matched = exec_text_operator(ctx, op,
norm_target_raw,
@@ -842,7 +1041,9 @@ exec_text_operator_raw_text_raw_text(grn_ctx *ctx,
norm_query_raw_length_in_bytes);
grn_obj_close(ctx, norm_target);
- grn_obj_close(ctx, norm_query);
+ if (norm_query) {
+ grn_obj_close(ctx, norm_query);
+ }
grn_obj_unlink(ctx, normalizer);
return matched;
@@ -870,26 +1071,35 @@ exec_text_operator_record_text(grn_ctx *ctx,
record_key_len = grn_table_get_key(ctx, table, GRN_RECORD_VALUE(record),
record_key, GRN_TABLE_MAX_KEY_SIZE);
grn_table_get_info(ctx, table, NULL, NULL, NULL, &normalizer, NULL);
- if (normalizer && (op != GRN_OP_REGEXP)) {
+ if (normalizer) {
grn_obj *norm_query;
const char *norm_query_raw;
unsigned int norm_query_raw_length_in_bytes;
- norm_query = grn_string_open(ctx,
- GRN_TEXT_VALUE(query),
- GRN_TEXT_LEN(query),
- normalizer,
- 0);
- grn_string_get_normalized(ctx, norm_query,
- &norm_query_raw,
- &norm_query_raw_length_in_bytes,
- NULL);
+
+ if (op == GRN_OP_REGEXP) {
+ norm_query = NULL;
+ norm_query_raw = GRN_TEXT_VALUE(query);
+ norm_query_raw_length_in_bytes = GRN_TEXT_LEN(query);
+ } else {
+ norm_query = grn_string_open(ctx,
+ GRN_TEXT_VALUE(query),
+ GRN_TEXT_LEN(query),
+ normalizer,
+ 0);
+ grn_string_get_normalized(ctx, norm_query,
+ &norm_query_raw,
+ &norm_query_raw_length_in_bytes,
+ NULL);
+ }
matched = exec_text_operator(ctx,
op,
record_key,
record_key_len,
norm_query_raw,
norm_query_raw_length_in_bytes);
- grn_obj_close(ctx, norm_query);
+ if (norm_query) {
+ grn_obj_close(ctx, norm_query);
+ }
} else {
matched = exec_text_operator_raw_text_raw_text(ctx,
op,
@@ -982,11 +1192,171 @@ grn_operator_exec_prefix(grn_ctx *ctx, grn_obj *target, grn_obj *prefix)
GRN_API_RETURN(matched);
}
+static grn_bool
+exec_regexp_uvector_bulk(grn_ctx *ctx, grn_obj *uvector, grn_obj *pattern)
+{
+#ifdef GRN_SUPPORT_REGEXP
+ grn_bool matched = GRN_FALSE;
+ unsigned int i, size;
+ OnigRegex regex;
+ grn_obj *domain;
+ grn_obj *normalizer;
+ grn_obj *normalizer_auto = NULL;
+
+ size = grn_uvector_size(ctx, uvector);
+ if (size == 0) {
+ return GRN_FALSE;
+ }
+
+ regex = regexp_compile(ctx,
+ GRN_TEXT_VALUE(pattern),
+ GRN_TEXT_LEN(pattern),
+ ONIG_SYNTAX_RUBY);
+ if (!regex) {
+ return GRN_FALSE;
+ }
+
+ domain = grn_ctx_at(ctx, uvector->header.domain);
+ if (!domain) {
+ onig_free(regex);
+ return GRN_FALSE;
+ }
+
+ grn_table_get_info(ctx, domain, NULL, NULL, NULL, &normalizer, NULL);
+ if (!normalizer) {
+ normalizer_auto = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+ }
+
+ for (i = 0; i < size; i++) {
+ grn_id record_id;
+ char key[GRN_TABLE_MAX_KEY_SIZE];
+ int key_size;
+
+ record_id = grn_uvector_get_element(ctx, uvector, i, NULL);
+ key_size = grn_table_get_key(ctx, domain, record_id,
+ key, GRN_TABLE_MAX_KEY_SIZE);
+ if (key_size == 0) {
+ continue;
+ }
+
+ if (normalizer) {
+ matched = regexp_is_match(ctx, regex, key, key_size);
+ } else {
+ grn_obj *norm_key;
+ const char *norm_key_raw;
+ unsigned int norm_key_raw_length_in_bytes;
+
+ norm_key = grn_string_open(ctx, key, key_size, normalizer_auto, 0);
+ grn_string_get_normalized(ctx, norm_key,
+ &norm_key_raw,
+ &norm_key_raw_length_in_bytes,
+ NULL);
+ matched = regexp_is_match(ctx, regex,
+ norm_key_raw,
+ norm_key_raw_length_in_bytes);
+ grn_obj_unlink(ctx, norm_key);
+ }
+
+ if (matched) {
+ break;
+ }
+ }
+
+ if (normalizer_auto) {
+ grn_obj_unlink(ctx, normalizer_auto);
+ }
+
+ grn_obj_unlink(ctx, domain);
+
+ onig_free(regex);
+
+ return matched;
+#else /* GRN_SUPPORT_REGEXP */
+ return GRN_FALSE;
+#endif /* GRN_SUPPORT_REGEXP */
+}
+
+static grn_bool
+exec_regexp_vector_bulk(grn_ctx *ctx, grn_obj *vector, grn_obj *pattern)
+{
+#ifdef GRN_SUPPORT_REGEXP
+ grn_obj *normalizer = NULL;
+ grn_bool matched = GRN_FALSE;
+ unsigned int i, size;
+ OnigRegex regex;
+
+ size = grn_vector_size(ctx, vector);
+ if (size == 0) {
+ return GRN_FALSE;
+ }
+
+ regex = regexp_compile(ctx,
+ GRN_TEXT_VALUE(pattern),
+ GRN_TEXT_LEN(pattern),
+ ONIG_SYNTAX_RUBY);
+ if (!regex) {
+ return GRN_FALSE;
+ }
+
+ normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+ for (i = 0; i < size; i++) {
+ const char *content;
+ unsigned int content_size;
+ grn_id domain_id;
+ grn_obj *norm_content;
+ const char *norm_content_raw;
+ unsigned int norm_content_raw_length_in_bytes;
+
+ content_size = grn_vector_get_element(ctx, vector, i,
+ &content, NULL, &domain_id);
+ if (content_size == 0) {
+ continue;
+ }
+
+ norm_content = grn_string_open(ctx, content, content_size, normalizer, 0);
+ grn_string_get_normalized(ctx, norm_content,
+ &norm_content_raw,
+ &norm_content_raw_length_in_bytes,
+ NULL);
+
+ matched = regexp_is_match(ctx, regex,
+ norm_content_raw,
+ norm_content_raw_length_in_bytes);
+
+ grn_obj_unlink(ctx, norm_content);
+
+ if (matched) {
+ break;
+ }
+ }
+ grn_obj_unlink(ctx, normalizer);
+
+ onig_free(regex);
+
+ return matched;
+#else /* GRN_SUPPORT_REGEXP */
+ return GRN_FALSE;
+#endif /* GRN_SUPPORT_REGEXP */
+}
+
grn_bool
grn_operator_exec_regexp(grn_ctx *ctx, grn_obj *target, grn_obj *pattern)
{
- grn_bool matched;
+ grn_bool matched = GRN_FALSE;
GRN_API_ENTER;
- matched = exec_text_operator_bulk_bulk(ctx, GRN_OP_REGEXP, target, pattern);
+ switch (target->header.type) {
+ case GRN_UVECTOR :
+ matched = exec_regexp_uvector_bulk(ctx, target, pattern);
+ break;
+ case GRN_VECTOR :
+ matched = exec_regexp_vector_bulk(ctx, target, pattern);
+ break;
+ case GRN_BULK :
+ matched = exec_text_operator_bulk_bulk(ctx, GRN_OP_REGEXP, target, pattern);
+ break;
+ default :
+ matched = GRN_FALSE;
+ break;
+ }
GRN_API_RETURN(matched);
}
diff --git a/storage/mroonga/vendor/groonga/lib/output.c b/storage/mroonga/vendor/groonga/lib/output.c
index f78ef75a560..d894280ab82 100644
--- a/storage/mroonga/vendor/groonga/lib/output.c
+++ b/storage/mroonga/vendor/groonga/lib/output.c
@@ -24,7 +24,7 @@
#include "grn_util.h"
#include "grn_output.h"
-#define LEVELS (&ctx->impl->levels)
+#define LEVELS (&ctx->impl->output.levels)
#define DEPTH (GRN_BULK_VSIZE(LEVELS)>>2)
#define CURR_LEVEL (DEPTH ? (GRN_UINT32_VALUE_AT(LEVELS, (DEPTH - 1))) : 0)
#define INCR_DEPTH(i) GRN_UINT32_PUT(ctx, LEVELS, i)
@@ -32,13 +32,115 @@
#define INCR_LENGTH (DEPTH ? (GRN_UINT32_VALUE_AT(LEVELS, (DEPTH - 1)) += 2) : 0)
static void
+indent(grn_ctx *ctx, grn_obj *outbuf, size_t level)
+{
+ size_t i;
+ for (i = 0; i < level; i++) {
+ GRN_TEXT_PUTS(ctx, outbuf, " ");
+ }
+}
+
+static void
+json_array_open(grn_ctx *ctx, grn_obj *outbuf, size_t *indent_level)
+{
+ GRN_TEXT_PUTC(ctx, outbuf, '[');
+ if (ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, '\n');
+ (*indent_level)++;
+ indent(ctx, outbuf, *indent_level);
+ }
+}
+
+static void
+json_array_close(grn_ctx *ctx, grn_obj *outbuf, size_t *indent_level)
+{
+ if (ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, '\n');
+ (*indent_level)--;
+ indent(ctx, outbuf, *indent_level);
+ }
+ GRN_TEXT_PUTC(ctx, outbuf, ']');
+}
+
+static void
+json_element_end(grn_ctx *ctx, grn_obj *outbuf, size_t indent_level)
+{
+ GRN_TEXT_PUTC(ctx, outbuf, ',');
+ if (ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, '\n');
+ indent(ctx, outbuf, indent_level);
+ }
+}
+
+static void
+json_map_open(grn_ctx *ctx, grn_obj *outbuf, size_t *indent_level)
+{
+ GRN_TEXT_PUTC(ctx, outbuf, '{');
+ if (ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, '\n');
+ (*indent_level)++;
+ indent(ctx, outbuf, *indent_level);
+ }
+}
+
+static void
+json_map_close(grn_ctx *ctx, grn_obj *outbuf, size_t *indent_level)
+{
+ if (ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, '\n');
+ (*indent_level)--;
+ indent(ctx, outbuf, *indent_level);
+ }
+ GRN_TEXT_PUTC(ctx, outbuf, '}');
+}
+
+static void
+json_key_end(grn_ctx *ctx, grn_obj *outbuf)
+{
+ GRN_TEXT_PUTC(ctx, outbuf, ':');
+ if (ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, ' ');
+ }
+}
+
+static void
+json_key(grn_ctx *ctx, grn_obj *outbuf, const char *key)
+{
+ grn_text_esc(ctx, outbuf, key, strlen(key));
+ json_key_end(ctx, outbuf);
+}
+
+static void
+json_value_end(grn_ctx *ctx, grn_obj *outbuf, size_t indent_level)
+{
+ GRN_TEXT_PUTC(ctx, outbuf, ',');
+ if (ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, '\n');
+ indent(ctx, outbuf, indent_level);
+ }
+}
+
+static void
put_delimiter(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type)
{
uint32_t level = CURR_LEVEL;
switch (output_type) {
case GRN_CONTENT_JSON:
- if (level < 2) { return; }
- GRN_TEXT_PUTC(ctx, outbuf, ((level & 3) == 3) ? ':' : ',');
+ if (level < 2) {
+ if (DEPTH > 0 && ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, '\n');
+ indent(ctx, outbuf, DEPTH + 1);
+ }
+ return;
+ }
+ if ((level & 3) == 3) {
+ GRN_TEXT_PUTC(ctx, outbuf, ':');
+ if (ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, ' ');
+ }
+ } else {
+ json_element_end(ctx, outbuf, DEPTH + 1);
+ }
// if (DEPTH == 1 && ((level & 3) != 3)) { GRN_TEXT_PUTC(ctx, outbuf, '\n'); }
break;
case GRN_CONTENT_XML:
@@ -75,7 +177,10 @@ grn_output_array_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_typ
GRN_TEXT_PUTC(ctx, outbuf, '<');
GRN_TEXT_PUTS(ctx, outbuf, name);
GRN_TEXT_PUTC(ctx, outbuf, '>');
- grn_vector_add_element(ctx, &ctx->impl->names, name, strlen(name), 0, GRN_DB_SHORT_TEXT);
+ grn_vector_add_element(ctx,
+ &ctx->impl->output.names,
+ name, strlen(name),
+ 0, GRN_DB_SHORT_TEXT);
break;
case GRN_CONTENT_TSV:
if (DEPTH > 2) { GRN_TEXT_PUTS(ctx, outbuf, "[\t"); }
@@ -88,7 +193,7 @@ grn_output_array_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_typ
nelements,
name);
}
- msgpack_pack_array(&ctx->impl->msgpacker, nelements);
+ msgpack_pack_array(&ctx->impl->output.msgpacker, nelements);
#endif
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
@@ -104,6 +209,10 @@ grn_output_array_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_ty
{
switch (output_type) {
case GRN_CONTENT_JSON:
+ if (ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, '\n');
+ indent(ctx, outbuf, DEPTH);
+ }
GRN_TEXT_PUTC(ctx, outbuf, ']');
break;
case GRN_CONTENT_TSV:
@@ -115,7 +224,10 @@ grn_output_array_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_ty
case GRN_CONTENT_XML:
{
const char *name;
- unsigned int name_len = grn_vector_pop_element(ctx, &ctx->impl->names, &name, NULL, NULL);
+ unsigned int name_len;
+ name_len = grn_vector_pop_element(ctx,
+ &ctx->impl->output.names,
+ &name, NULL, NULL);
GRN_TEXT_PUTS(ctx, outbuf, "</");
GRN_TEXT_PUT(ctx, outbuf, name, name_len);
GRN_TEXT_PUTC(ctx, outbuf, '>');
@@ -146,7 +258,9 @@ grn_output_map_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
GRN_TEXT_PUTC(ctx, outbuf, '<');
GRN_TEXT_PUTS(ctx, outbuf, name);
GRN_TEXT_PUTC(ctx, outbuf, '>');
- grn_vector_add_element(ctx, &ctx->impl->names, name, strlen(name), 0, GRN_DB_SHORT_TEXT);
+ grn_vector_add_element(ctx,
+ &ctx->impl->output.names,
+ name, strlen(name), 0, GRN_DB_SHORT_TEXT);
break;
case GRN_CONTENT_TSV:
if (DEPTH > 2) { GRN_TEXT_PUTS(ctx, outbuf, "{\t"); }
@@ -159,7 +273,7 @@ grn_output_map_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
nelements,
name);
}
- msgpack_pack_map(&ctx->impl->msgpacker, nelements);
+ msgpack_pack_map(&ctx->impl->output.msgpacker, nelements);
#endif
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
@@ -175,6 +289,10 @@ grn_output_map_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type
{
switch (output_type) {
case GRN_CONTENT_JSON:
+ if (ctx->impl->output.is_pretty) {
+ GRN_TEXT_PUTC(ctx, outbuf, '\n');
+ indent(ctx, outbuf, DEPTH);
+ }
GRN_TEXT_PUTS(ctx, outbuf, "}");
break;
case GRN_CONTENT_TSV:
@@ -186,7 +304,10 @@ grn_output_map_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type
case GRN_CONTENT_XML:
{
const char *name;
- unsigned int name_len = grn_vector_pop_element(ctx, &ctx->impl->names, &name, NULL, NULL);
+ unsigned int name_len;
+ name_len = grn_vector_pop_element(ctx,
+ &ctx->impl->output.names,
+ &name, NULL, NULL);
GRN_TEXT_PUTS(ctx, outbuf, "</");
GRN_TEXT_PUT(ctx, outbuf, name, name_len);
GRN_TEXT_PUTC(ctx, outbuf, '>');
@@ -222,7 +343,7 @@ grn_output_int32(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, in
break;
case GRN_CONTENT_MSGPACK :
#ifdef GRN_WITH_MESSAGE_PACK
- msgpack_pack_int32(&ctx->impl->msgpacker, value);
+ msgpack_pack_int32(&ctx->impl->output.msgpacker, value);
#endif
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
@@ -252,7 +373,7 @@ grn_output_int64(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, in
break;
case GRN_CONTENT_MSGPACK :
#ifdef GRN_WITH_MESSAGE_PACK
- msgpack_pack_int64(&ctx->impl->msgpacker, value);
+ msgpack_pack_int64(&ctx->impl->output.msgpacker, value);
#endif
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
@@ -265,7 +386,7 @@ grn_output_int64(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, in
}
void
-grn_output_uint64(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, int64_t value)
+grn_output_uint64(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, uint64_t value)
{
put_delimiter(ctx, outbuf, output_type);
switch (output_type) {
@@ -282,7 +403,7 @@ grn_output_uint64(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, i
break;
case GRN_CONTENT_MSGPACK :
#ifdef GRN_WITH_MESSAGE_PACK
- msgpack_pack_uint64(&ctx->impl->msgpacker, value);
+ msgpack_pack_uint64(&ctx->impl->output.msgpacker, value);
#endif
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
@@ -312,7 +433,7 @@ grn_output_float(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, do
break;
case GRN_CONTENT_MSGPACK :
#ifdef GRN_WITH_MESSAGE_PACK
- msgpack_pack_double(&ctx->impl->msgpacker, value);
+ msgpack_pack_double(&ctx->impl->output.msgpacker, value);
#endif
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
@@ -343,8 +464,8 @@ grn_output_str(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
break;
case GRN_CONTENT_MSGPACK :
#ifdef GRN_WITH_MESSAGE_PACK
- msgpack_pack_str(&ctx->impl->msgpacker, value_len);
- msgpack_pack_str_body(&ctx->impl->msgpacker, value, value_len);
+ msgpack_pack_str(&ctx->impl->output.msgpacker, value_len);
+ msgpack_pack_str_body(&ctx->impl->output.msgpacker, value, value_len);
#endif
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
@@ -382,9 +503,9 @@ grn_output_bool(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn
case GRN_CONTENT_MSGPACK :
#ifdef GRN_WITH_MESSAGE_PACK
if (value) {
- msgpack_pack_true(&ctx->impl->msgpacker);
+ msgpack_pack_true(&ctx->impl->output.msgpacker);
} else {
- msgpack_pack_false(&ctx->impl->msgpacker);
+ msgpack_pack_false(&ctx->impl->output.msgpacker);
}
#endif
break;
@@ -397,7 +518,7 @@ grn_output_bool(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn
INCR_LENGTH;
}
-static inline void
+void
grn_output_null(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type)
{
put_delimiter(ctx, outbuf, output_type);
@@ -412,7 +533,7 @@ grn_output_null(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type)
break;
case GRN_CONTENT_MSGPACK :
#ifdef GRN_WITH_MESSAGE_PACK
- msgpack_pack_nil(&ctx->impl->msgpacker);
+ msgpack_pack_nil(&ctx->impl->output.msgpacker);
#endif
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
@@ -454,7 +575,7 @@ grn_output_time(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, int
break;
case GRN_CONTENT_MSGPACK :
#ifdef GRN_WITH_MESSAGE_PACK
- msgpack_pack_double(&ctx->impl->msgpacker, dv);
+ msgpack_pack_double(&ctx->impl->output.msgpacker, dv);
#endif
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
@@ -511,13 +632,13 @@ grn_output_geo_point(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type
grn_text_itoa(ctx, &buf, value->latitude);
GRN_TEXT_PUTC(ctx, &buf, 'x');
grn_text_itoa(ctx, &buf, value->longitude);
- msgpack_pack_str(&ctx->impl->msgpacker, GRN_TEXT_LEN(&buf));
- msgpack_pack_str_body(&ctx->impl->msgpacker,
+ msgpack_pack_str(&ctx->impl->output.msgpacker, GRN_TEXT_LEN(&buf));
+ msgpack_pack_str_body(&ctx->impl->output.msgpacker,
GRN_TEXT_VALUE(&buf),
GRN_TEXT_LEN(&buf));
grn_obj_close(ctx, &buf);
} else {
- msgpack_pack_nil(&ctx->impl->msgpacker);
+ msgpack_pack_nil(&ctx->impl->output.msgpacker);
}
#endif
break;
@@ -565,11 +686,18 @@ grn_text_atoj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
break;
case GRN_ACCESSOR_GET_SCORE :
{
- grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
- int32_t int32_score = ri->score;
- GRN_INT32_PUT(ctx, &buf, int32_score);
+ grn_rset_recinfo *ri =
+ (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ if (grn_ctx_get_command_version(ctx) == GRN_COMMAND_VERSION_1) {
+ int32_t int32_score = ri->score;
+ GRN_INT32_PUT(ctx, &buf, int32_score);
+ buf.header.domain = GRN_DB_INT32;
+ } else {
+ double float_score = ri->score;
+ GRN_FLOAT_PUT(ctx, &buf, float_score);
+ buf.header.domain = GRN_DB_FLOAT;
+ }
}
- buf.header.domain = GRN_DB_INT32;
break;
case GRN_ACCESSOR_GET_NSUBRECS :
{
@@ -1098,18 +1226,82 @@ grn_output_pvector(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
}
static inline void
-grn_output_table_header(grn_ctx *ctx, grn_obj *outbuf,
- grn_content_type output_type,
- grn_obj *table, grn_obj_format *format)
+grn_output_result_set_n_hits_v1(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj_format *format)
+{
+ grn_output_array_open(ctx, outbuf, output_type, "NHITS", 1);
+ if (output_type == GRN_CONTENT_XML) {
+ grn_text_itoa(ctx, outbuf, format->nhits);
+ } else {
+ grn_output_int32(ctx, outbuf, output_type, format->nhits);
+ }
+ grn_output_array_close(ctx, outbuf, output_type);
+}
+
+static inline void
+grn_output_result_set_n_hits_v3(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj_format *format)
+{
+ grn_output_cstr(ctx, outbuf, output_type, "n_hits");
+ grn_output_int32(ctx, outbuf, output_type, format->nhits);
+}
+
+static inline void
+grn_output_result_set_n_hits(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj_format *format)
+{
+ if (format->nhits == -1) {
+ return;
+ }
+
+ if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+ grn_output_result_set_n_hits_v1(ctx, outbuf, output_type, format);
+ } else {
+ grn_output_result_set_n_hits_v3(ctx, outbuf, output_type, format);
+ }
+}
+
+static inline void
+grn_output_table_column_info(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ const char *name,
+ const char *type)
{
- if (format->nhits != -1) {
- grn_output_array_open(ctx, outbuf, output_type, "NHITS", 1);
- if (output_type == GRN_CONTENT_XML) {
- grn_text_itoa(ctx, outbuf, format->nhits);
+ if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+ grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2);
+ if (name) {
+ grn_output_cstr(ctx, outbuf, output_type, name);
+ } else {
+ grn_output_null(ctx, outbuf, output_type);
+ }
+ if (type) {
+ grn_output_cstr(ctx, outbuf, output_type, type);
} else {
- grn_output_int32(ctx, outbuf, output_type, format->nhits);
+ grn_output_null(ctx, outbuf, output_type);
}
grn_output_array_close(ctx, outbuf, output_type);
+ } else {
+ grn_output_map_open(ctx, outbuf, output_type, "column", 2);
+ grn_output_cstr(ctx, outbuf, output_type, "name");
+ if (name) {
+ grn_output_cstr(ctx, outbuf, output_type, name);
+ } else {
+ grn_output_null(ctx, outbuf, output_type);
+ }
+ grn_output_cstr(ctx, outbuf, output_type, "type");
+ if (type) {
+ grn_output_cstr(ctx, outbuf, output_type, type);
+ } else {
+ grn_output_null(ctx, outbuf, output_type);
+ }
+ grn_output_map_close(ctx, outbuf, output_type);
}
}
@@ -1154,39 +1346,52 @@ grn_output_table_column(grn_ctx *ctx, grn_obj *outbuf,
grn_content_type output_type,
grn_obj *column, grn_obj *buf)
{
- grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2);
- if (column) {
- grn_id range_id = GRN_ID_NIL;
- GRN_BULK_REWIND(buf);
- grn_column_name_(ctx, column, buf);
- grn_output_obj(ctx, outbuf, output_type, buf, NULL);
- if (column->header.type == GRN_COLUMN_INDEX) {
- range_id = GRN_DB_UINT32;
- } else if (is_score_accessor(ctx, column)) {
+ grn_id range_id = GRN_ID_NIL;
+
+ if (!column) {
+ grn_output_table_column_info(ctx, outbuf, output_type, NULL, NULL);
+ return;
+ }
+
+ GRN_BULK_REWIND(buf);
+ grn_column_name_(ctx, column, buf);
+ GRN_TEXT_PUTC(ctx, buf, '\0');
+
+ if (column->header.type == GRN_COLUMN_INDEX) {
+ range_id = GRN_DB_UINT32;
+ } else if (is_score_accessor(ctx, column)) {
+ if (grn_ctx_get_command_version(ctx) == GRN_COMMAND_VERSION_1) {
range_id = GRN_DB_INT32;
- }
- if (range_id == GRN_ID_NIL) {
- range_id = grn_obj_get_range(ctx, column);
- }
- if (range_id == GRN_ID_NIL) {
- grn_output_cstr(ctx, outbuf, output_type, "null");
} else {
- int name_len;
- grn_obj *range_obj;
- char name_buf[GRN_TABLE_MAX_KEY_SIZE];
-
- range_obj = grn_ctx_at(ctx, range_id);
- name_len = grn_obj_name(ctx, range_obj, name_buf,
- GRN_TABLE_MAX_KEY_SIZE);
- GRN_BULK_REWIND(buf);
- GRN_TEXT_PUT(ctx, buf, name_buf, name_len);
- grn_output_obj(ctx, outbuf, output_type, buf, NULL);
+ range_id = GRN_DB_FLOAT;
}
+ }
+ if (range_id == GRN_ID_NIL) {
+ range_id = grn_obj_get_range(ctx, column);
+ }
+ if (range_id == GRN_ID_NIL) {
+ grn_output_table_column_info(ctx,
+ outbuf,
+ output_type,
+ GRN_TEXT_VALUE(buf),
+ NULL);
} else {
- grn_output_cstr(ctx, outbuf, output_type, "");
- grn_output_cstr(ctx, outbuf, output_type, "");
+ grn_obj *range_obj;
+ char type_name[GRN_TABLE_MAX_KEY_SIZE];
+ int type_name_len;
+
+ range_obj = grn_ctx_at(ctx, range_id);
+ type_name_len = grn_obj_name(ctx,
+ range_obj,
+ type_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ type_name[type_name_len] = '\0';
+ grn_output_table_column_info(ctx,
+ outbuf,
+ output_type,
+ GRN_TEXT_VALUE(buf),
+ type_name);
}
- grn_output_array_close(ctx, outbuf, output_type);
}
static inline void
@@ -1197,28 +1402,29 @@ grn_output_table_column_by_expression(grn_ctx *ctx, grn_obj *outbuf,
grn_obj *buf)
{
if (code_end <= code) {
- grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2);
- grn_output_null(ctx, outbuf, output_type);
- grn_output_null(ctx, outbuf, output_type);
- grn_output_array_close(ctx, outbuf, output_type);
+ grn_output_table_column_info(ctx,
+ outbuf,
+ output_type,
+ NULL,
+ NULL);
return;
}
switch (code_end[-1].op) {
case GRN_OP_GET_MEMBER :
if ((code_end - code) == 3) {
- grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2);
-
GRN_BULK_REWIND(buf);
grn_column_name_(ctx, code[0].value, buf);
GRN_TEXT_PUTC(ctx, buf, '[');
grn_inspect(ctx, buf, code[1].value);
GRN_TEXT_PUTC(ctx, buf, ']');
+ GRN_TEXT_PUTC(ctx, buf, '\0');
- grn_output_obj(ctx, outbuf, output_type, buf, NULL);
- grn_output_null(ctx, outbuf, output_type);
-
- grn_output_array_close(ctx, outbuf, output_type);
+ grn_output_table_column_info(ctx,
+ outbuf,
+ output_type,
+ GRN_TEXT_VALUE(buf),
+ NULL);
} else {
grn_output_table_column(ctx, outbuf, output_type, code->value, buf);
}
@@ -1230,6 +1436,32 @@ grn_output_table_column_by_expression(grn_ctx *ctx, grn_obj *outbuf,
}
static inline void
+grn_output_table_columns_open(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ int n_columns)
+{
+ if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+ grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", n_columns);
+ } else {
+ grn_output_cstr(ctx, outbuf, output_type, "columns");
+ grn_output_array_open(ctx, outbuf, output_type, "columns", n_columns);
+ }
+}
+
+static inline void
+grn_output_table_columns_close(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type)
+{
+ if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+ grn_output_array_close(ctx, outbuf, output_type);
+ } else {
+ grn_output_array_close(ctx, outbuf, output_type);
+ }
+}
+
+static inline void
grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf,
grn_content_type output_type,
grn_obj *table, grn_obj_format *format,
@@ -1245,7 +1477,8 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf,
n_elements = count_n_elements_in_expression(ctx, format->expression);
- grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", n_elements);
+ grn_output_table_columns_open(ctx, outbuf, output_type, n_elements);
+
for (code = expr->codes; code < code_end; code++) {
int code_start_offset;
@@ -1285,7 +1518,7 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf,
buf);
}
- grn_output_array_close(ctx, outbuf, output_type);
+ grn_output_table_columns_close(ctx, outbuf, output_type);
}
static inline void
@@ -1298,11 +1531,11 @@ grn_output_table_columns_by_columns(grn_ctx *ctx, grn_obj *outbuf,
int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *);
grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
- grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", ncolumns);
+ grn_output_table_columns_open(ctx, outbuf, output_type, ncolumns);
for (i = 0; i < ncolumns; i++) {
grn_output_table_column(ctx, outbuf, output_type, columns[i], buf);
}
- grn_output_array_close(ctx, outbuf, output_type);
+ grn_output_table_columns_close(ctx, outbuf, output_type);
}
void
@@ -1324,16 +1557,64 @@ grn_output_table_columns(grn_ctx *ctx, grn_obj *outbuf,
}
static inline void
-grn_output_table_record_by_expression(grn_ctx *ctx, grn_obj *outbuf,
+grn_output_table_record_open(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ int n_columns)
+{
+ if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+ grn_output_array_open(ctx, outbuf, output_type, "HIT", n_columns);
+ } else {
+ grn_output_array_open(ctx, outbuf, output_type, "record", n_columns);
+ }
+}
+
+static inline void
+grn_output_table_record_close(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type)
+{
+ if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+ grn_output_array_close(ctx, outbuf, output_type);
+ } else {
+ grn_output_array_close(ctx, outbuf, output_type);
+ }
+}
+
+static inline void
+grn_output_table_record_by_column(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *column,
+ grn_id id)
+{
+ grn_text_atoj(ctx, outbuf, output_type, column, id);
+}
+
+static inline void
+grn_output_table_record_by_expression(grn_ctx *ctx,
+ grn_obj *outbuf,
grn_content_type output_type,
- grn_obj *expression)
+ grn_obj *expression,
+ grn_obj *record)
{
- grn_obj *result;
- result = grn_expr_exec(ctx, expression, 0);
- if (result) {
- grn_output_obj(ctx, outbuf, output_type, result, NULL);
+ grn_expr *expr = (grn_expr *)expression;
+
+ if (expr->codes_curr == 1 && expr->codes[0].op == GRN_OP_GET_VALUE) {
+ grn_obj *column = expr->codes[0].value;
+ grn_output_table_record_by_column(ctx,
+ outbuf,
+ output_type,
+ column,
+ GRN_RECORD_VALUE(record));
} else {
- grn_output_cstr(ctx, outbuf, output_type, ctx->errbuf);
+ grn_obj *result;
+ result = grn_expr_exec(ctx, expression, 0);
+ if (result) {
+ grn_output_obj(ctx, outbuf, output_type, result, NULL);
+ } else {
+ grn_output_cstr(ctx, outbuf, output_type, ctx->errbuf);
+ }
}
}
@@ -1357,7 +1638,7 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf,
grn_bool is_first_comma = GRN_TRUE;
grn_bool have_comma = GRN_FALSE;
GRN_RECORD_SET(ctx, record, id);
- grn_output_array_open(ctx, outbuf, output_type, "HIT", n_elements);
+ grn_output_table_record_open(ctx, outbuf, output_type, n_elements);
for (code = expr->codes; code < code_end; code++) {
if (code->op == GRN_OP_COMMA) {
int code_start_offset = previous_comma_offset + 1;
@@ -1374,16 +1655,22 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf,
expr->codes,
expr->codes + second_code_offset);
expr->codes_curr = second_code_offset - second_code_n_used_codes + 1;
- grn_output_table_record_by_expression(ctx, outbuf, output_type,
- format->expression);
+ grn_output_table_record_by_expression(ctx,
+ outbuf,
+ output_type,
+ format->expression,
+ record);
code_start_offset = expr->codes_curr;
is_first_comma = GRN_FALSE;
}
code_end_offset = code - expr->codes - code_start_offset;
expr->codes += code_start_offset;
expr->codes_curr = code_end_offset;
- grn_output_table_record_by_expression(ctx, outbuf, output_type,
- format->expression);
+ grn_output_table_record_by_expression(ctx,
+ outbuf,
+ output_type,
+ format->expression,
+ record);
expr->codes -= code_start_offset;
expr->codes_curr = original_codes_curr;
previous_comma_offset = code - expr->codes;
@@ -1391,11 +1678,14 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf,
}
if (!have_comma && expr->codes_curr > 0) {
- grn_output_table_record_by_expression(ctx, outbuf, output_type,
- format->expression);
+ grn_output_table_record_by_expression(ctx,
+ outbuf,
+ output_type,
+ format->expression,
+ record);
}
- grn_output_array_close(ctx, outbuf, output_type);
+ grn_output_table_record_close(ctx, outbuf, output_type);
}
}
@@ -1410,10 +1700,36 @@ grn_output_table_records_by_columns(grn_ctx *ctx, grn_obj *outbuf,
int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *);
grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
while ((id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
- grn_output_array_open(ctx, outbuf, output_type, "HIT", ncolumns);
+ grn_output_table_record_open(ctx, outbuf, output_type, ncolumns);
for (i = 0; i < ncolumns; i++) {
- grn_text_atoj(ctx, outbuf, output_type, columns[i], id);
+ grn_output_table_record_by_column(ctx,
+ outbuf,
+ output_type,
+ columns[i],
+ id);
}
+ grn_output_table_record_close(ctx, outbuf, output_type);
+ }
+}
+
+static inline void
+grn_output_table_records_open(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ int n_records)
+{
+ if (grn_ctx_get_command_version(ctx) >= GRN_COMMAND_VERSION_3) {
+ grn_output_cstr(ctx, outbuf, output_type, "records");
+ grn_output_array_open(ctx, outbuf, output_type, "records", n_records);
+ }
+}
+
+static inline void
+grn_output_table_records_close(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type)
+{
+ if (grn_ctx_get_command_version(ctx) >= GRN_COMMAND_VERSION_3) {
grn_output_array_close(ctx, outbuf, output_type);
}
}
@@ -1423,9 +1739,12 @@ grn_output_table_records(grn_ctx *ctx, grn_obj *outbuf,
grn_content_type output_type,
grn_obj *table, grn_obj_format *format)
{
- grn_table_cursor *tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0,
- format->offset, format->limit,
- GRN_CURSOR_ASCENDING);
+ grn_table_cursor *tc;
+
+ grn_output_table_records_open(ctx, outbuf, output_type, format->limit);
+ tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0,
+ format->offset, format->limit,
+ GRN_CURSOR_ASCENDING);
if (tc) {
if (format->expression) {
grn_output_table_records_by_expression(ctx, outbuf, output_type,
@@ -1438,11 +1757,16 @@ grn_output_table_records(grn_ctx *ctx, grn_obj *outbuf,
} else {
ERRCLR(ctx);
}
+ grn_output_table_records_close(ctx, outbuf, output_type);
}
-static inline void
-grn_output_table(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
- grn_obj *table, grn_obj_format *format)
+static void
+grn_output_result_set_open_v1(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *table,
+ grn_obj_format *format,
+ uint32_t n_additional_elements)
{
grn_obj buf;
GRN_TEXT_INIT(&buf, 0);
@@ -1453,13 +1777,13 @@ grn_output_table(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
resultset_size++;
}
resultset_size += format->limit;
+ resultset_size += n_additional_elements;
grn_output_array_open(ctx, outbuf, output_type, "RESULTSET", resultset_size);
- grn_output_table_header(ctx, outbuf, output_type, table, format);
+ grn_output_result_set_n_hits(ctx, outbuf, output_type, format);
if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
grn_output_table_columns(ctx, outbuf, output_type, table, format);
}
grn_output_table_records(ctx, outbuf, output_type, table, format);
- grn_output_array_close(ctx, outbuf, output_type);
} else {
int i;
grn_obj *column = grn_obj_column(ctx, table,
@@ -1477,12 +1801,136 @@ grn_output_table(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
}
grn_table_cursor_close(ctx, tc);
}
+ grn_obj_unlink(ctx, column);
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+}
+
+static void
+grn_output_result_set_close_v1(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *table,
+ grn_obj_format *format)
+{
+ grn_output_array_close(ctx, outbuf, output_type);
+}
+
+static void
+grn_output_result_set_open_v3(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *result_set,
+ grn_obj_format *format,
+ uint32_t n_additional_elements)
+{
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ if (format) {
+ int n_elements = 2;
+ /* result_set: {"n_hits": N, ("columns": COLUMNS,) "records": records} */
+ if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
+ n_elements++;
+ }
+ n_elements += n_additional_elements;
+ grn_output_map_open(ctx, outbuf, output_type, "result_set", n_elements);
+ grn_output_result_set_n_hits(ctx, outbuf, output_type, format);
+ if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
+ grn_output_table_columns(ctx, outbuf, output_type, result_set, format);
+ }
+ grn_output_table_records(ctx, outbuf, output_type, result_set, format);
+ } else {
+ grn_obj *column;
+ int n_records;
+ int n_elements = 1;
+
+ column = grn_obj_column(ctx,
+ result_set,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ n_elements += n_additional_elements;
+ grn_output_map_open(ctx, outbuf, output_type, "result_set", n_elements);
+ n_records = grn_table_size(ctx, result_set);
+ grn_output_cstr(ctx, outbuf, output_type, "keys");
+ grn_output_array_open(ctx, outbuf, output_type, "keys", n_records);
+ GRN_TABLE_EACH_BEGIN(ctx, result_set, cursor, id) {
+ GRN_BULK_REWIND(&buf);
+ grn_obj_get_value(ctx, column, id, &buf);
+ grn_text_esc(ctx, outbuf, GRN_BULK_HEAD(&buf), GRN_BULK_VSIZE(&buf));
+ } GRN_TABLE_EACH_END(ctx, cursor);
grn_output_array_close(ctx, outbuf, output_type);
grn_obj_unlink(ctx, column);
}
GRN_OBJ_FIN(ctx, &buf);
}
+static void
+grn_output_result_set_close_v3(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *result_set,
+ grn_obj_format *format)
+{
+ grn_output_map_close(ctx, outbuf, output_type);
+}
+
+void
+grn_output_result_set_open(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *result_set,
+ grn_obj_format *format,
+ uint32_t n_additional_elements)
+{
+ if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+ grn_output_result_set_open_v1(ctx,
+ outbuf,
+ output_type,
+ result_set,
+ format,
+ n_additional_elements);
+ } else {
+ grn_output_result_set_open_v3(ctx,
+ outbuf,
+ output_type,
+ result_set,
+ format,
+ n_additional_elements);
+ }
+}
+
+void
+grn_output_result_set_close(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *result_set,
+ grn_obj_format *format)
+{
+ if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+ grn_output_result_set_close_v1(ctx, outbuf, output_type, result_set, format);
+ } else {
+ grn_output_result_set_close_v3(ctx, outbuf, output_type, result_set, format);
+ }
+}
+
+void
+grn_output_result_set(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *result_set,
+ grn_obj_format *format)
+{
+ uint32_t n_additional_elements = 0;
+
+ grn_output_result_set_open(ctx,
+ outbuf,
+ output_type,
+ result_set,
+ format,
+ n_additional_elements);
+ grn_output_result_set_close(ctx, outbuf, output_type, result_set, format);
+}
+
void
grn_output_obj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
grn_obj *obj, grn_obj_format *format)
@@ -1509,7 +1957,8 @@ grn_output_obj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
case GRN_TABLE_PAT_KEY :
case GRN_TABLE_DAT_KEY :
case GRN_TABLE_NO_KEY :
- grn_output_table(ctx, outbuf, output_type, obj, format);
+ /* Deprecated. Use grn_output_result_set() directly. */
+ grn_output_result_set(ctx, outbuf, output_type, obj, format);
break;
}
GRN_OBJ_FIN(ctx, &buf);
@@ -1805,6 +2254,413 @@ msgpack_buffer_writer(void* data, const char* buf, msgpack_size_t len)
#define JSON_CALLBACK_PARAM "callback"
+static void
+grn_output_envelope_json_v1(grn_ctx *ctx,
+ grn_rc rc,
+ grn_obj *head,
+ grn_obj *body,
+ grn_obj *foot,
+ double started,
+ double elapsed,
+ const char *file,
+ int line)
+{
+ size_t indent_level = 0;
+
+ json_array_open(ctx, head, &indent_level);
+ {
+ json_array_open(ctx, head, &indent_level);
+ {
+ grn_text_itoa(ctx, head, rc);
+
+ json_element_end(ctx, head, indent_level);
+ grn_text_ftoa(ctx, head, started);
+
+ json_element_end(ctx, head, indent_level);
+ grn_text_ftoa(ctx, head, elapsed);
+
+ if (rc != GRN_SUCCESS) {
+ json_element_end(ctx, head, indent_level);
+ grn_text_esc(ctx, head, ctx->errbuf, strlen(ctx->errbuf));
+
+ if (ctx->errfunc && ctx->errfile) {
+ grn_obj *command;
+
+ json_element_end(ctx, head, indent_level);
+ json_array_open(ctx, head, &indent_level);
+ {
+ json_array_open(ctx, head, &indent_level);
+ {
+ grn_text_esc(ctx, head, ctx->errfunc, strlen(ctx->errfunc));
+
+ json_element_end(ctx, head, indent_level);
+ grn_text_esc(ctx, head, ctx->errfile, strlen(ctx->errfile));
+
+ json_element_end(ctx, head, indent_level);
+ grn_text_itoa(ctx, head, ctx->errline);
+ }
+ json_array_close(ctx, head, &indent_level);
+
+ if (file && (command = GRN_CTX_USER_DATA(ctx)->ptr)) {
+ json_element_end(ctx, head, indent_level);
+ json_array_open(ctx, head, &indent_level);
+ {
+ grn_text_esc(ctx, head, file, strlen(file));
+
+ json_element_end(ctx, head, indent_level);
+ grn_text_itoa(ctx, head, line);
+
+ json_element_end(ctx, head, indent_level);
+ grn_text_esc(ctx, head,
+ GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command));
+ }
+ json_array_close(ctx, head, &indent_level);
+ }
+ }
+ json_array_close(ctx, head, &indent_level);
+ }
+ }
+ }
+ json_array_close(ctx, head, &indent_level);
+ }
+
+ if (GRN_TEXT_LEN(body)) {
+ json_element_end(ctx, head, indent_level);
+ }
+
+ json_array_close(ctx, foot, &indent_level);
+}
+
+static void
+grn_output_envelope_json(grn_ctx *ctx,
+ grn_rc rc,
+ grn_obj *head,
+ grn_obj *body,
+ grn_obj *foot,
+ double started,
+ double elapsed,
+ const char *file,
+ int line)
+{
+ size_t indent_level = 0;
+
+ json_map_open(ctx, head, &indent_level);
+ {
+ json_key(ctx, head, "header");
+ json_map_open(ctx, head, &indent_level);
+ {
+ json_key(ctx, head, "return_code");
+ grn_text_itoa(ctx, head, rc);
+
+ json_value_end(ctx, head, indent_level);
+ json_key(ctx, head, "start_time");
+ grn_text_ftoa(ctx, head, started);
+
+ json_value_end(ctx, head, indent_level);
+ json_key(ctx, head, "elapsed_time");
+ grn_text_ftoa(ctx, head, elapsed);
+
+ if (rc != GRN_SUCCESS) {
+ json_value_end(ctx, head, indent_level);
+ json_key(ctx, head, "error");
+ json_map_open(ctx, head, &indent_level);
+ {
+ json_key(ctx, head, "message");
+ grn_text_esc(ctx, head, ctx->errbuf, strlen(ctx->errbuf));
+
+ if (ctx->errfunc && ctx->errfile) {
+ json_value_end(ctx, head, indent_level);
+ json_key(ctx, head, "function");
+ grn_text_esc(ctx, head, ctx->errfunc, strlen(ctx->errfunc));
+
+ json_value_end(ctx, head, indent_level);
+ json_key(ctx, head, "file");
+ grn_text_esc(ctx, head, ctx->errfile, strlen(ctx->errfile));
+
+ json_value_end(ctx, head, indent_level);
+ json_key(ctx, head, "line");
+ grn_text_itoa(ctx, head, ctx->errline);
+ }
+
+ if (file) {
+ grn_obj *command;
+
+ command = GRN_CTX_USER_DATA(ctx)->ptr;
+ if (command) {
+ json_value_end(ctx, head, indent_level);
+ json_key(ctx, head, "input");
+ json_map_open(ctx, head, &indent_level);
+ {
+ json_key(ctx, head, "file");
+ grn_text_esc(ctx, head, file, strlen(file));
+
+ json_value_end(ctx, head, indent_level);
+ json_key(ctx, head, "line");
+ grn_text_itoa(ctx, head, line);
+
+ json_value_end(ctx, head, indent_level);
+ json_key(ctx, head, "command");
+ grn_text_esc(ctx, head,
+ GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command));
+ }
+ json_map_close(ctx, head, &indent_level);
+ }
+ }
+ }
+ json_map_close(ctx, head, &indent_level);
+ }
+ }
+ json_map_close(ctx, head, &indent_level);
+
+ if (GRN_TEXT_LEN(body)) {
+ json_value_end(ctx, head, indent_level);
+ json_key(ctx, head, "body");
+ }
+
+ json_map_close(ctx, foot, &indent_level);
+ }
+}
+
+#ifdef GRN_WITH_MESSAGE_PACK
+static void
+msgpack_pack_cstr(msgpack_packer *packer,
+ const char *string)
+{
+ size_t size;
+
+ size = strlen(string);
+ msgpack_pack_str(packer, size);
+ msgpack_pack_str_body(packer, string, size);
+}
+
+static void
+grn_output_envelope_msgpack_v1(grn_ctx *ctx,
+ grn_rc rc,
+ grn_obj *head,
+ grn_obj *body,
+ grn_obj *foot,
+ double started,
+ double elapsed,
+ const char *file,
+ int line)
+{
+ msgpack_writer_ctx head_writer_ctx;
+ msgpack_packer header_packer;
+ int header_size;
+
+ head_writer_ctx.ctx = ctx;
+ head_writer_ctx.buffer = head;
+ msgpack_packer_init(&header_packer, &head_writer_ctx, msgpack_buffer_writer);
+
+ /* [HEADER, (BODY)] */
+ if (GRN_TEXT_LEN(body) > 0) {
+ msgpack_pack_array(&header_packer, 2);
+ } else {
+ msgpack_pack_array(&header_packer, 1);
+ }
+
+ /* HEADER := [rc, started, elapsed, (error, (ERROR DETAIL))] */
+ header_size = 3;
+ if (rc != GRN_SUCCESS) {
+ header_size++;
+ if (ctx->errfunc && ctx->errfile) {
+ header_size++;
+ }
+ }
+ msgpack_pack_array(&header_packer, header_size);
+ msgpack_pack_int(&header_packer, rc);
+
+ msgpack_pack_double(&header_packer, started);
+ msgpack_pack_double(&header_packer, elapsed);
+
+ if (rc != GRN_SUCCESS) {
+ msgpack_pack_str(&header_packer, strlen(ctx->errbuf));
+ msgpack_pack_str_body(&header_packer, ctx->errbuf, strlen(ctx->errbuf));
+ if (ctx->errfunc && ctx->errfile) {
+ grn_obj *command = GRN_CTX_USER_DATA(ctx)->ptr;
+ int error_detail_size;
+
+ /* ERROR DETAIL : = [[errfunc, errfile, errline,
+ (file, line, command)]] */
+ /* TODO: output backtrace */
+ msgpack_pack_array(&header_packer, 1);
+ error_detail_size = 3;
+ if (command) {
+ error_detail_size += 3;
+ }
+ msgpack_pack_array(&header_packer, error_detail_size);
+
+ msgpack_pack_str(&header_packer, strlen(ctx->errfunc));
+ msgpack_pack_str_body(&header_packer, ctx->errfunc, strlen(ctx->errfunc));
+
+ msgpack_pack_str(&header_packer, strlen(ctx->errfile));
+ msgpack_pack_str_body(&header_packer, ctx->errfile, strlen(ctx->errfile));
+
+ msgpack_pack_int(&header_packer, ctx->errline);
+
+ if (command) {
+ if (file) {
+ msgpack_pack_str(&header_packer, strlen(file));
+ msgpack_pack_str_body(&header_packer, file, strlen(file));
+ } else {
+ msgpack_pack_str(&header_packer, 7);
+ msgpack_pack_str_body(&header_packer, "(stdin)", 7);
+ }
+
+ msgpack_pack_int(&header_packer, line);
+
+ msgpack_pack_str(&header_packer, GRN_TEXT_LEN(command));
+ msgpack_pack_str_body(&header_packer, GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command));
+ }
+ }
+ }
+}
+
+static void
+grn_output_envelope_msgpack(grn_ctx *ctx,
+ grn_rc rc,
+ grn_obj *head,
+ grn_obj *body,
+ grn_obj *foot,
+ double started,
+ double elapsed,
+ const char *file,
+ int line)
+{
+ msgpack_writer_ctx writer_ctx;
+ msgpack_packer packer;
+ int n_elements;
+
+ writer_ctx.ctx = ctx;
+ writer_ctx.buffer = head;
+ msgpack_packer_init(&packer, &writer_ctx, msgpack_buffer_writer);
+
+ /*
+ * ENVELOPE := {
+ * "header": HEADER,
+ * "body": BODY (optional)
+ * }
+ */
+ if (GRN_TEXT_LEN(body) > 0) {
+ n_elements = 2;
+ } else {
+ n_elements = 1;
+ }
+
+ msgpack_pack_map(&packer, n_elements);
+ {
+ int n_header_elements = 3;
+
+ /*
+ * HEADER := {
+ * "return_code": rc,
+ * "start_time": started,
+ * "elapsed_time": elapsed,
+ " "error": { (optional)
+ * "message": errbuf,
+ * "function": errfunc,
+ * "file": errfile,
+ * "line": errline,
+ * "input": { (optional)
+ * "file": input_file,
+ * "line": line,
+ * "command": command
+ * }
+ * }
+ * }
+ */
+
+ if (rc != GRN_SUCCESS) {
+ n_header_elements++;
+ }
+
+ msgpack_pack_cstr(&packer, "header");
+ msgpack_pack_map(&packer, n_header_elements);
+ {
+ msgpack_pack_cstr(&packer, "return_code");
+ msgpack_pack_int(&packer, rc);
+
+ msgpack_pack_cstr(&packer, "start_time");
+ msgpack_pack_double(&packer, started);
+
+ msgpack_pack_cstr(&packer, "elapsed_time");
+ msgpack_pack_double(&packer, elapsed);
+
+ if (rc != GRN_SUCCESS) {
+ int n_error_elements = 1;
+ grn_obj *command;
+
+ if (ctx->errfunc) {
+ n_error_elements++;
+ }
+ if (ctx->errfile) {
+ n_error_elements += 2;
+ }
+
+ command = GRN_CTX_USER_DATA(ctx)->ptr;
+ if (file || command) {
+ n_error_elements++;
+ }
+
+ msgpack_pack_cstr(&packer, "error");
+ msgpack_pack_map(&packer, n_error_elements);
+ {
+ msgpack_pack_cstr(&packer, "message");
+ msgpack_pack_cstr(&packer, ctx->errbuf);
+
+ if (ctx->errfunc) {
+ msgpack_pack_cstr(&packer, "function");
+ msgpack_pack_cstr(&packer, ctx->errfunc);
+ }
+
+ if (ctx->errfile) {
+ msgpack_pack_cstr(&packer, "file");
+ msgpack_pack_cstr(&packer, ctx->errfile);
+
+ msgpack_pack_cstr(&packer, "line");
+ msgpack_pack_int(&packer, ctx->errline);
+ }
+
+ if (file || command) {
+ int n_input_elements = 0;
+
+ if (file) {
+ n_input_elements += 2;
+ }
+ if (command) {
+ n_input_elements++;
+ }
+
+ msgpack_pack_cstr(&packer, "input");
+ msgpack_pack_map(&packer, n_input_elements);
+
+ if (file) {
+ msgpack_pack_cstr(&packer, "file");
+ msgpack_pack_cstr(&packer, file);
+
+ msgpack_pack_cstr(&packer, "line");
+ msgpack_pack_int(&packer, line);
+ }
+
+ if (command) {
+ msgpack_pack_cstr(&packer, "command");
+ msgpack_pack_str(&packer, GRN_TEXT_LEN(command));
+ msgpack_pack_str_body(&packer,
+ GRN_TEXT_VALUE(command),
+ GRN_TEXT_LEN(command));
+ }
+ }
+ }
+ }
+ }
+
+ if (GRN_TEXT_LEN(body) > 0) {
+ msgpack_pack_cstr(&packer, "body");
+ }
+ }
+}
+#endif /* GRN_WITH_MESSAGE_PACK */
+
void
grn_output_envelope(grn_ctx *ctx,
grn_rc rc,
@@ -1815,8 +2671,6 @@ grn_output_envelope(grn_ctx *ctx,
int line)
{
double started, finished, elapsed;
- grn_obj *expr = NULL;
- grn_obj *jsonp_func = NULL;
grn_timeval tv_now;
grn_timeval_now(ctx, &tv_now);
@@ -1826,53 +2680,38 @@ grn_output_envelope(grn_ctx *ctx,
finished += tv_now.tv_nsec / GRN_TIME_NSEC_PER_SEC_F;
elapsed = finished - started;
- switch (ctx->impl->output_type) {
+ switch (ctx->impl->output.type) {
case GRN_CONTENT_JSON:
- expr = ctx->impl->curr_expr;
- if (expr) {
- jsonp_func = grn_expr_get_var(ctx, expr, JSON_CALLBACK_PARAM,
- strlen(JSON_CALLBACK_PARAM));
- }
- if (jsonp_func && GRN_TEXT_LEN(jsonp_func)) {
- GRN_TEXT_PUT(ctx, head, GRN_TEXT_VALUE(jsonp_func), GRN_TEXT_LEN(jsonp_func));
- GRN_TEXT_PUTC(ctx, head, '(');
- }
- GRN_TEXT_PUTS(ctx, head, "[[");
- grn_text_itoa(ctx, head, rc);
- GRN_TEXT_PUTC(ctx, head, ',');
- grn_text_ftoa(ctx, head, started);
- GRN_TEXT_PUTC(ctx, head, ',');
- grn_text_ftoa(ctx, head, elapsed);
- if (rc != GRN_SUCCESS) {
- GRN_TEXT_PUTC(ctx, head, ',');
- grn_text_esc(ctx, head, ctx->errbuf, strlen(ctx->errbuf));
- if (ctx->errfunc && ctx->errfile) {
- grn_obj *command;
- /* TODO: output backtrace */
- GRN_TEXT_PUTS(ctx, head, ",[[");
- grn_text_esc(ctx, head, ctx->errfunc, strlen(ctx->errfunc));
- GRN_TEXT_PUTC(ctx, head, ',');
- grn_text_esc(ctx, head, ctx->errfile, strlen(ctx->errfile));
- GRN_TEXT_PUTC(ctx, head, ',');
- grn_text_itoa(ctx, head, ctx->errline);
- GRN_TEXT_PUTS(ctx, head, "]");
- if (file && (command = GRN_CTX_USER_DATA(ctx)->ptr)) {
- GRN_TEXT_PUTS(ctx, head, ",[");
- grn_text_esc(ctx, head, file, strlen(file));
- GRN_TEXT_PUTC(ctx, head, ',');
- grn_text_itoa(ctx, head, line);
- GRN_TEXT_PUTC(ctx, head, ',');
- grn_text_esc(ctx, head, GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command));
- GRN_TEXT_PUTS(ctx, head, "]");
- }
- GRN_TEXT_PUTS(ctx, head, "]");
+ {
+ grn_obj *expr;
+ grn_obj *jsonp_func = NULL;
+
+ expr = ctx->impl->curr_expr;
+ if (expr) {
+ jsonp_func = grn_expr_get_var(ctx, expr, JSON_CALLBACK_PARAM,
+ strlen(JSON_CALLBACK_PARAM));
+ }
+ if (jsonp_func && GRN_TEXT_LEN(jsonp_func)) {
+ GRN_TEXT_PUT(ctx, head,
+ GRN_TEXT_VALUE(jsonp_func), GRN_TEXT_LEN(jsonp_func));
+ GRN_TEXT_PUTC(ctx, head, '(');
+ }
+
+ if (grn_ctx_get_command_version(ctx) <= GRN_COMMAND_VERSION_2) {
+ grn_output_envelope_json_v1(ctx, rc,
+ head, body, foot,
+ started, elapsed,
+ file, line);
+ } else {
+ grn_output_envelope_json(ctx, rc,
+ head, body, foot,
+ started, elapsed,
+ file, line);
+ }
+
+ if (jsonp_func && GRN_TEXT_LEN(jsonp_func)) {
+ GRN_TEXT_PUTS(ctx, foot, ");");
}
- }
- GRN_TEXT_PUTC(ctx, head, ']');
- if (GRN_TEXT_LEN(body)) { GRN_TEXT_PUTC(ctx, head, ','); }
- GRN_TEXT_PUTC(ctx, foot, ']');
- if (jsonp_func && GRN_TEXT_LEN(jsonp_func)) {
- GRN_TEXT_PUTS(ctx, foot, ");");
}
break;
case GRN_CONTENT_TSV:
@@ -1943,79 +2782,18 @@ grn_output_envelope(grn_ctx *ctx,
break;
case GRN_CONTENT_MSGPACK:
#ifdef GRN_WITH_MESSAGE_PACK
- {
- msgpack_writer_ctx head_writer_ctx;
- msgpack_packer header_packer;
- int header_size;
-
- head_writer_ctx.ctx = ctx;
- head_writer_ctx.buffer = head;
- msgpack_packer_init(&header_packer, &head_writer_ctx, msgpack_buffer_writer);
-
- /* [HEAD, (BODY)] */
- if (GRN_TEXT_LEN(body) > 0) {
- msgpack_pack_array(&header_packer, 2);
- } else {
- msgpack_pack_array(&header_packer, 1);
- }
-
- /* HEAD := [rc, started, elapsed, (error, (ERROR DETAIL))] */
- header_size = 3;
- if (rc != GRN_SUCCESS) {
- header_size++;
- if (ctx->errfunc && ctx->errfile) {
- header_size++;
- }
- }
- msgpack_pack_array(&header_packer, header_size);
- msgpack_pack_int(&header_packer, rc);
-
- msgpack_pack_double(&header_packer, started);
- msgpack_pack_double(&header_packer, elapsed);
-
- if (rc != GRN_SUCCESS) {
- msgpack_pack_str(&header_packer, strlen(ctx->errbuf));
- msgpack_pack_str_body(&header_packer, ctx->errbuf, strlen(ctx->errbuf));
- if (ctx->errfunc && ctx->errfile) {
- grn_obj *command = GRN_CTX_USER_DATA(ctx)->ptr;
- int error_detail_size;
-
- /* ERROR DETAIL := [[errfunc, errfile, errline,
- (file, line, command)]] */
- /* TODO: output backtrace */
- msgpack_pack_array(&header_packer, 1);
- error_detail_size = 3;
- if (command) {
- error_detail_size += 3;
- }
- msgpack_pack_array(&header_packer, error_detail_size);
-
- msgpack_pack_str(&header_packer, strlen(ctx->errfunc));
- msgpack_pack_str_body(&header_packer, ctx->errfunc, strlen(ctx->errfunc));
-
- msgpack_pack_str(&header_packer, strlen(ctx->errfile));
- msgpack_pack_str_body(&header_packer, ctx->errfile, strlen(ctx->errfile));
-
- msgpack_pack_int(&header_packer, ctx->errline);
-
- if (command) {
- if (file) {
- msgpack_pack_str(&header_packer, strlen(file));
- msgpack_pack_str_body(&header_packer, file, strlen(file));
- } else {
- msgpack_pack_str(&header_packer, 7);
- msgpack_pack_str_body(&header_packer, "(stdin)", 7);
- }
-
- msgpack_pack_int(&header_packer, line);
-
- msgpack_pack_str(&header_packer, GRN_TEXT_LEN(command));
- msgpack_pack_str_body(&header_packer, GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command));
- }
- }
- }
+ if (grn_ctx_get_command_version(ctx) <= GRN_COMMAND_VERSION_2) {
+ grn_output_envelope_msgpack_v1(ctx, rc,
+ head, body, foot,
+ started, elapsed,
+ file, line);
+ } else {
+ grn_output_envelope_msgpack(ctx, rc,
+ head, body, foot,
+ started, elapsed,
+ file, line);
}
-#endif
+#endif /* GRN_WITH_MESSAGE_PACK */
break;
case GRN_CONTENT_GROONGA_COMMAND_LIST :
break;
@@ -2029,23 +2807,52 @@ is_output_columns_format_v1(grn_ctx *ctx,
const char *output_columns,
unsigned int output_columns_len)
{
- unsigned int i;
+ const char *current;
+ const char *end;
+ grn_bool in_identifier = GRN_FALSE;
- /* TODO: REMOVE ME. If new output_columns handler is marked as stable,
- this check is removed. We need more error checks. */
- if (grn_ctx_get_command_version(ctx) == GRN_COMMAND_VERSION_1) {
- return GRN_TRUE;
- }
+ current = output_columns;
+ end = current + output_columns_len;
+ while (current < end) {
+ int char_length;
- for (i = 0; i < output_columns_len; i++) {
- switch (output_columns[i]) {
- case ',' :
- case '(' :
- case '[' :
+ char_length = grn_charlen(ctx, current, end);
+ if (char_length != 1) {
return GRN_FALSE;
- default :
+ }
+
+ switch (current[0]) {
+ case ' ' :
+ case ',' :
+ in_identifier = GRN_FALSE;
+ break;
+ case '_' :
+ in_identifier = GRN_TRUE;
break;
+ case '.' :
+ case '-' :
+ case '#' :
+ case '@' :
+ if (!in_identifier) {
+ return GRN_FALSE;
+ }
+ break;
+ default :
+ if ('a' <= current[0] && current[0] <= 'z') {
+ in_identifier = GRN_TRUE;
+ break;
+ } else if ('A' <= current[0] && current[0] <= 'Z') {
+ in_identifier = GRN_TRUE;
+ break;
+ } else if ('0' <= current[0] && current[0] <= '9') {
+ in_identifier = GRN_TRUE;
+ break;
+ } else {
+ return GRN_FALSE;
+ }
}
+
+ current += char_length;
}
return GRN_TRUE;
diff --git a/storage/mroonga/vendor/groonga/lib/pat.c b/storage/mroonga/vendor/groonga/lib/pat.c
index e24dbe7bbf0..8e20fde4043 100644
--- a/storage/mroonga/vendor/groonga/lib/pat.c
+++ b/storage/mroonga/vendor/groonga/lib/pat.c
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2014 Brazil
+/*
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -72,7 +73,7 @@ typedef struct {
terminated == 1: key is terminated.
*/
uint16_t bits;
- /* length : 13, deleting : 1, immediate : 1 */
+ /* length: 13, immediate: 1, deleting: 1 */
} pat_node;
#define PAT_DELETING (1<<1)
@@ -100,6 +101,24 @@ enum {
segment_sis = 2
};
+void grn_p_pat_node(grn_ctx *ctx, grn_pat *pat, pat_node *node);
+
+/* error utilities */
+inline static int
+grn_pat_name(grn_ctx *ctx, grn_pat *pat, char *buffer, int buffer_size)
+{
+ int name_size;
+
+ if (DB_OBJ(pat)->id == GRN_ID_NIL) {
+ grn_strcpy(buffer, buffer_size, "(anonymous)");
+ name_size = strlen(buffer);
+ } else {
+ name_size = grn_obj_name(ctx, (grn_obj *)pat, buffer, buffer_size);
+ }
+
+ return name_size;
+}
+
/* bit operation */
#define nth_bit(key,n,l) ((((key)[(n)>>4]) >> (7 - (((n)>>1) & 7))) & 1)
@@ -189,11 +208,26 @@ sis_collect(grn_ctx *ctx, grn_pat *pat, grn_hash *h, grn_id id, uint32_t level)
} while (0)
inline static uint32_t
-key_put(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, int len)
+key_put(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t len)
{
uint32_t res, ts;
// if (len >= GRN_PAT_SEGMENT_SIZE) { return 0; /* error */ }
res = pat->header->curr_key;
+ if (res < GRN_PAT_MAX_TOTAL_KEY_SIZE &&
+ len > GRN_PAT_MAX_TOTAL_KEY_SIZE - res) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_pat_name(ctx, pat, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_NOT_ENOUGH_SPACE,
+ "[pat][key][put] total key size is over: <%.*s>: "
+ "max=%u: current=%u: new key size=%u",
+ name_size, name,
+ GRN_PAT_MAX_TOTAL_KEY_SIZE,
+ res,
+ len);
+ return 0;
+ }
+
ts = (res + len) >> W_OF_KEY_IN_A_SEGMENT;
if (res >> W_OF_KEY_IN_A_SEGMENT != ts) {
res = pat->header->curr_key = ts << W_OF_KEY_IN_A_SEGMENT;
@@ -201,7 +235,18 @@ key_put(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, int len)
{
uint8_t *dest;
KEY_AT(pat, res, dest, GRN_TABLE_ADD);
- if (!dest) { return 0; }
+ if (!dest) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_pat_name(ctx, pat, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[pat][key][put] failed to allocate memory for new key: <%.*s>: "
+ "new offset:%u key size:%u",
+ name_size, name,
+ res,
+ len);
+ return 0;
+ }
grn_memcpy(dest, key, len);
}
pat->header->curr_key += len;
@@ -221,25 +266,37 @@ pat_node_get_key(grn_ctx *ctx, grn_pat *pat, pat_node *n)
}
inline static grn_rc
-pat_node_set_key(grn_ctx *ctx, grn_pat *pat, pat_node *n, const uint8_t *key, unsigned int len)
+pat_node_set_key(grn_ctx *ctx, grn_pat *pat, pat_node *n, const uint8_t *key, uint32_t len)
{
+ grn_rc rc;
if (!key || !len) { return GRN_INVALID_ARGUMENT; }
PAT_LEN_SET(n, len);
if (len <= sizeof(uint32_t)) {
PAT_IMD_ON(n);
grn_memcpy(&n->key, key, len);
+ rc = GRN_SUCCESS;
} else {
PAT_IMD_OFF(n);
n->key = key_put(ctx, pat, key, len);
+ rc = ctx->rc;
}
- return GRN_SUCCESS;
+ return rc;
}
/* delinfo operation */
enum {
+ /* The delinfo is currently not used. */
DL_EMPTY = 0,
+ /*
+ * stat->d refers to a deleting node (in a tree).
+ * The deletion requires an additional operation.
+ */
DL_PHASE1,
+ /*
+ * stat->d refers to a deleted node (not in a tree).
+ * The node is pending for safety.
+ */
DL_PHASE2
};
@@ -265,32 +322,51 @@ delinfo_turn_2(grn_ctx *ctx, grn_pat *pat, grn_pat_delinfo *di)
grn_id d, *p = NULL;
pat_node *ln, *dn;
// grn_log("delinfo_turn_2> di->d=%d di->ld=%d stat=%d", di->d, di->ld, di->stat);
- if (di->stat != DL_PHASE1) { return GRN_SUCCESS; }
+ if (di->stat != DL_PHASE1) {
+ return GRN_SUCCESS;
+ }
PAT_AT(pat, di->ld, ln);
- if (!ln) { return GRN_INVALID_ARGUMENT; }
- if (!(d = di->d)) { return GRN_INVALID_ARGUMENT; }
+ if (!ln) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ d = di->d;
+ if (!d) {
+ return GRN_INVALID_ARGUMENT;
+ }
PAT_AT(pat, d, dn);
- if (!dn) { return GRN_INVALID_ARGUMENT; }
+ if (!dn) {
+ return GRN_INVALID_ARGUMENT;
+ }
PAT_DEL_OFF(ln);
PAT_DEL_OFF(dn);
{
- grn_id r, *p0;
+ grn_id *p0;
pat_node *rn;
int c0 = -1, c;
uint32_t len = PAT_LEN(dn) * 16;
const uint8_t *key = pat_node_get_key(ctx, pat, dn);
- if (!key) { return GRN_INVALID_ARGUMENT; }
+ if (!key) {
+ return GRN_INVALID_ARGUMENT;
+ }
PAT_AT(pat, 0, rn);
p0 = &rn->lr[1];
- while ((r = *p0)) {
+ for (;;) {
+ grn_id r = *p0;
+ if (!r) {
+ break;
+ }
if (r == d) {
p = p0;
break;
}
PAT_AT(pat, r, rn);
- if (!rn) { return GRN_FILE_CORRUPT; }
+ if (!rn) {
+ return GRN_FILE_CORRUPT;
+ }
c = PAT_CHK(rn);
- if (c <= c0 || len <= c) { break; }
+ if (c <= c0 || len <= c) {
+ break;
+ }
if (c & 1) {
p0 = (c + 1 < len) ? &rn->lr[1] : &rn->lr[0];
} else {
@@ -418,7 +494,7 @@ _grn_pat_create(grn_ctx *ctx, grn_pat *pat,
header->value_size = value_size;
header->n_entries = 0;
header->curr_rec = 0;
- header->curr_key = -1;
+ header->curr_key = 0;
header->curr_del = 0;
header->curr_del2 = 0;
header->curr_del3 = 0;
@@ -432,6 +508,7 @@ _grn_pat_create(grn_ctx *ctx, grn_pat *pat,
pat->normalizer = NULL;
header->normalizer = GRN_ID_NIL;
}
+ header->truncated = GRN_FALSE;
GRN_PTR_INIT(&(pat->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
pat->io = io;
pat->header = header;
@@ -455,7 +532,7 @@ grn_pat_create(grn_ctx *ctx, const char *path, uint32_t key_size,
uint32_t value_size, uint32_t flags)
{
grn_pat *pat;
- if (!(pat = GRN_MALLOC(sizeof(grn_pat)))) {
+ if (!(pat = GRN_CALLOC(sizeof(grn_pat)))) {
return NULL;
}
GRN_DB_OBJ_SET_TYPE(pat, GRN_TABLE_PAT_KEY);
@@ -465,6 +542,8 @@ grn_pat_create(grn_ctx *ctx, const char *path, uint32_t key_size,
}
pat->cache = NULL;
pat->cache_size = 0;
+ pat->is_dirty = GRN_FALSE;
+ CRITICAL_SECTION_INIT(pat->lock);
return pat;
}
@@ -508,11 +587,14 @@ grn_pat_open(grn_ctx *ctx, const char *path)
grn_pat *pat;
pat_node *node0;
struct grn_pat_header *header;
+ uint32_t io_type;
io = grn_io_open(ctx, path, grn_io_auto);
if (!io) { return NULL; }
header = grn_io_header(io);
- if (grn_io_get_type(io) != GRN_TABLE_PAT_KEY) {
- ERR(GRN_INVALID_FORMAT, "file type unmatch");
+ io_type = grn_io_get_type(io);
+ if (io_type != GRN_TABLE_PAT_KEY) {
+ ERR(GRN_INVALID_FORMAT, "[table][pat] file type must be %#04x: <%#04x>",
+ GRN_TABLE_PAT_KEY, io_type);
grn_io_close(ctx, io);
return NULL;
}
@@ -539,25 +621,55 @@ grn_pat_open(grn_ctx *ctx, const char *path)
PAT_AT(pat, 0, node0);
if (!node0) {
grn_io_close(ctx, io);
- GRN_GFREE(pat);
+ GRN_FREE(pat);
return NULL;
}
pat->cache = NULL;
pat->cache_size = 0;
+ pat->is_dirty = GRN_FALSE;
+ CRITICAL_SECTION_INIT(pat->lock);
return pat;
}
+/*
+ * grn_pat_error_if_truncated() logs an error and returns its error code if
+ * a pat is truncated by another process.
+ * Otherwise, this function returns GRN_SUCCESS.
+ * Note that `ctx` and `pat` must be valid.
+ *
+ * FIXME: A pat should be reopened if possible.
+ */
+static grn_rc
+grn_pat_error_if_truncated(grn_ctx *ctx, grn_pat *pat)
+{
+ if (pat->header->truncated) {
+ ERR(GRN_FILE_CORRUPT,
+ "pat is truncated, please unmap or reopen the database");
+ return GRN_FILE_CORRUPT;
+ }
+ return GRN_SUCCESS;
+}
+
grn_rc
grn_pat_close(grn_ctx *ctx, grn_pat *pat)
{
grn_rc rc;
+
+ CRITICAL_SECTION_FIN(pat->lock);
+
+ if (pat->is_dirty) {
+ uint32_t n_dirty_opens;
+ GRN_ATOMIC_ADD_EX(&(pat->header->n_dirty_opens), -1, n_dirty_opens);
+ }
+
if ((rc = grn_io_close(ctx, pat->io))) {
ERR(rc, "grn_io_close failed");
} else {
- GRN_OBJ_FIN(ctx, &(pat->token_filters));
+ grn_pvector_fin(ctx, &pat->token_filters);
if (pat->cache) { grn_pat_cache_disable(ctx, pat); }
GRN_FREE(pat);
}
+
return rc;
}
@@ -579,6 +691,10 @@ grn_pat_truncate(grn_ctx *ctx, grn_pat *pat)
char *path;
uint32_t key_size, value_size, flags;
+ rc = grn_pat_error_if_truncated(ctx, pat);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
if ((io_path = grn_io_path(pat->io)) && *io_path != '\0') {
if (!(path = GRN_STRDUP(io_path))) {
ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path: <%s>", io_path);
@@ -590,7 +706,11 @@ grn_pat_truncate(grn_ctx *ctx, grn_pat *pat)
key_size = pat->key_size;
value_size = pat->value_size;
flags = pat->obj.header.flags;
+ if (path) {
+ pat->header->truncated = GRN_TRUE;
+ }
if ((rc = grn_io_close(ctx, pat->io))) { goto exit; }
+ grn_pvector_fin(ctx, &pat->token_filters);
pat->io = NULL;
if (path && (rc = grn_io_remove(ctx, path))) { goto exit; }
if (!_grn_pat_create(ctx, pat, path, key_size, value_size, flags)) {
@@ -610,8 +730,9 @@ _grn_pat_add(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t size, uint
grn_id r, r0, *p0, *p1 = NULL;
pat_node *rn, *rn0;
int c, c0 = -1, c1 = -1, len;
-
uint32_t cache_id = 0;
+
+ *new = 0;
if (pat->cache) {
const uint8_t *p = key;
uint32_t length = size;
@@ -628,7 +749,6 @@ _grn_pat_add(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t size, uint
}
}
- *new = 0;
len = (int)size * 16;
PAT_AT(pat, 0, rn0);
p0 = &rn0->lr[1];
@@ -638,7 +758,7 @@ _grn_pat_add(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t size, uint
const uint8_t *s, *d;
for (;;) {
if (!(r0 = *p0)) {
- if (!(s = pat_node_get_key(ctx, pat, rn0))) { return 0; }
+ if (!(s = pat_node_get_key(ctx, pat, rn0))) { return GRN_ID_NIL; }
size2 = PAT_LEN(rn0);
break;
}
@@ -653,7 +773,7 @@ _grn_pat_add(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t size, uint
p0 = &rn0->lr[nth_bit(key, c0, len)];
}
} else {
- if (!(s = pat_node_get_key(ctx, pat, rn0))) { return 0; }
+ if (!(s = pat_node_get_key(ctx, pat, rn0))) { return GRN_ID_NIL; }
size2 = PAT_LEN(rn0);
if (size == size2 && !memcmp(s, key, size)) {
if (pat->cache) { pat->cache[cache_id] = r0; }
@@ -682,7 +802,7 @@ _grn_pat_add(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t size, uint
p0 = &rn0->lr[1];
while ((r0 = *p0)) {
PAT_AT(pat, r0, rn0);
- if (!rn0) { return 0; }
+ if (!rn0) { return GRN_ID_NIL; }
c0 = PAT_CHK(rn0);
if (c < c0) { break; }
if (c0 & 1) {
@@ -694,7 +814,7 @@ _grn_pat_add(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t size, uint
}
}
}
- if (c >= len) { return 0; }
+ if (c >= len) { return GRN_ID_NIL; }
} else {
c = len - 2;
}
@@ -703,13 +823,17 @@ _grn_pat_add(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t size, uint
if (*lkey && size2) {
if (pat->header->garbages[0]) {
r = pat->header->garbages[0];
+ PAT_AT(pat, r, rn);
+ if (!rn) { return GRN_ID_NIL; }
pat->header->n_entries++;
pat->header->n_garbages--;
- PAT_AT(pat, r, rn);
- if (!rn) { return 0; }
pat->header->garbages[0] = rn->lr[0];
} else {
- if (!(rn = pat_node_new(ctx, pat, &r))) { return 0; }
+ r = pat->header->curr_rec + 1;
+ rn = pat_get(ctx, pat, r);
+ if (!rn) { return GRN_ID_NIL; }
+ pat->header->curr_rec = r;
+ pat->header->n_entries++;
}
PAT_IMD_OFF(rn);
PAT_LEN_SET(rn, size);
@@ -718,17 +842,21 @@ _grn_pat_add(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t size, uint
if (pat->header->garbages[size2]) {
uint8_t *keybuf;
r = pat->header->garbages[size2];
+ PAT_AT(pat, r, rn);
+ if (!rn) { return GRN_ID_NIL; }
+ if (!(keybuf = pat_node_get_key(ctx, pat, rn))) { return GRN_ID_NIL; }
pat->header->n_entries++;
pat->header->n_garbages--;
- PAT_AT(pat, r, rn);
- if (!rn) { return 0; }
pat->header->garbages[size2] = rn->lr[0];
- if (!(keybuf = pat_node_get_key(ctx, pat, rn))) { return 0; }
PAT_LEN_SET(rn, size);
grn_memcpy(keybuf, key, size);
} else {
- if (!(rn = pat_node_new(ctx, pat, &r))) { return 0; }
- pat_node_set_key(ctx, pat, rn, key, size);
+ r = pat->header->curr_rec + 1;
+ rn = pat_get(ctx, pat, r);
+ if (!rn) { return GRN_ID_NIL; }
+ if (pat_node_set_key(ctx, pat, rn, key, size)) { return GRN_ID_NIL; }
+ pat->header->curr_rec = r;
+ pat->header->n_entries++;
}
*lkey = rn->key;
}
@@ -830,6 +958,9 @@ grn_pat_add(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size,
uint32_t new, lkey = 0;
grn_id r0;
uint8_t keybuf[MAX_FIXED_KEY_SIZE];
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
if (!key || !key_size) { return GRN_ID_NIL; }
if (key_size > GRN_TABLE_MAX_KEY_SIZE) {
ERR(GRN_INVALID_ARGUMENT, "too long key: (%u)", key_size);
@@ -837,6 +968,7 @@ grn_pat_add(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size,
}
KEY_ENCODE(pat, keybuf, key, key_size);
r0 = _grn_pat_add(ctx, pat, (uint8_t *)key, key_size, &new, &lkey);
+ if (r0 == GRN_ID_NIL) { return GRN_ID_NIL; }
if (added) { *added = new; }
if (r0 && (pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) &&
(*((uint8_t *)key) & 0x80)) { // todo: refine!!
@@ -919,6 +1051,9 @@ grn_id
grn_pat_get(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size, void **value)
{
uint8_t keybuf[MAX_FIXED_KEY_SIZE];
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
KEY_ENCODE(pat, keybuf, key, key_size);
return _grn_pat_get(ctx, pat, key, key_size, value);
}
@@ -928,6 +1063,9 @@ grn_pat_nextid(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size)
{
grn_id r = GRN_ID_NIL;
if (pat && key) {
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
if (!(r = pat->header->garbages[key_size > sizeof(uint32_t) ? key_size : 0])) {
r = pat->header->curr_rec + 1;
}
@@ -974,6 +1112,10 @@ grn_pat_prefix_search(grn_ctx *ctx, grn_pat *pat,
grn_id r;
pat_node *rn;
uint8_t keybuf[MAX_FIXED_KEY_SIZE];
+ grn_rc rc = grn_pat_error_if_truncated(ctx, pat);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
KEY_ENCODE(pat, keybuf, key, key_size);
PAT_AT(pat, 0, rn);
r = rn->lr[1];
@@ -1056,7 +1198,13 @@ grn_pat_lcp_search(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_siz
grn_id r, r2 = GRN_ID_NIL;
uint32_t len = key_size * 16;
int c0 = -1, c;
- if (!pat || !key || !(pat->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE)) { return GRN_ID_NIL; }
+ if (!pat || !key) {
+ return GRN_ID_NIL;
+ }
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
+ if (!(pat->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE)) { return GRN_ID_NIL; }
PAT_AT(pat, 0, rn);
for (r = rn->lr[1]; r;) {
PAT_AT(pat, r, rn);
@@ -1089,38 +1237,400 @@ grn_pat_lcp_search(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_siz
return r2;
}
+static grn_id
+common_prefix_pat_node_get(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size)
+{
+ int c0 = -1, c;
+ const uint8_t *k;
+ uint32_t len = key_size * 16;
+ grn_id r;
+ pat_node *rn;
+ uint8_t keybuf[MAX_FIXED_KEY_SIZE];
+
+ KEY_ENCODE(pat, keybuf, key, key_size);
+ PAT_AT(pat, 0, rn);
+ r = rn->lr[1];
+ while (r) {
+ PAT_AT(pat, r, rn);
+ if (!rn) { return GRN_ID_NIL; }
+ c = PAT_CHK(rn);
+ if (c0 < c && c < len - 1) {
+ if (c & 1) {
+ r = (c + 1 < len) ? rn->lr[1] : rn->lr[0];
+ } else {
+ r = rn->lr[nth_bit((uint8_t *)key, c, len)];
+ }
+ c0 = c;
+ continue;
+ }
+ if (!(k = pat_node_get_key(ctx, pat, rn))) { break; }
+ if (PAT_LEN(rn) < key_size) { break; }
+ if (!memcmp(k, key, key_size)) {
+ return r;
+ }
+ break;
+ }
+ return GRN_ID_NIL;
+}
+
+typedef struct {
+ grn_id id;
+ uint16_t distance;
+} fuzzy_heap_node;
+
+typedef struct {
+ int n_entries;
+ int limit;
+ fuzzy_heap_node *nodes;
+} fuzzy_heap;
+
+static inline fuzzy_heap *
+fuzzy_heap_open(grn_ctx *ctx, int max)
+{
+ fuzzy_heap *h = GRN_MALLOC(sizeof(fuzzy_heap));
+ if (!h) { return NULL; }
+ h->nodes = GRN_MALLOC(sizeof(fuzzy_heap_node) * max);
+ if (!h->nodes) {
+ GRN_FREE(h);
+ return NULL;
+ }
+ h->n_entries = 0;
+ h->limit = max;
+ return h;
+}
+
+static inline grn_bool
+fuzzy_heap_push(grn_ctx *ctx, fuzzy_heap *h, grn_id id, uint16_t distance)
+{
+ int n, n2;
+ fuzzy_heap_node node = {id, distance};
+ fuzzy_heap_node node2;
+ if (h->n_entries >= h->limit) {
+ int max = h->limit * 2;
+ fuzzy_heap_node *nodes = GRN_REALLOC(h->nodes, sizeof(fuzzy_heap) * max);
+ if (!h) {
+ return GRN_FALSE;
+ }
+ h->limit = max;
+ h->nodes = nodes;
+ }
+ h->nodes[h->n_entries] = node;
+ n = h->n_entries++;
+ while (n) {
+ n2 = (n - 1) >> 1;
+ if (h->nodes[n2].distance <= h->nodes[n].distance) { break; }
+ node2 = h->nodes[n];
+ h->nodes[n] = h->nodes[n2];
+ h->nodes[n2] = node2;
+ n = n2;
+ }
+ return GRN_TRUE;
+}
+
+static inline void
+fuzzy_heap_close(grn_ctx *ctx, fuzzy_heap *h)
+{
+ GRN_FREE(h->nodes);
+ GRN_FREE(h);
+}
+
+#define DIST(ox,oy) (dists[((lx + 1) * (oy)) + (ox)])
+
+inline static uint16_t
+calc_edit_distance_by_offset(grn_ctx *ctx,
+ const char *sx, const char *ex,
+ const char *sy, const char *ey,
+ uint16_t *dists, uint32_t lx,
+ uint32_t offset, uint32_t max_distance,
+ grn_bool *can_transition, int flags)
+{
+ uint32_t cx, cy, x, y;
+ const char *px, *py;
+
+ /* Skip already calculated rows */
+ for (py = sy, y = 1; py < ey && (cy = grn_charlen(ctx, py, ey)); py += cy, y++) {
+ if (py - sy >= offset) {
+ break;
+ }
+ }
+ for (; py < ey && (cy = grn_charlen(ctx, py, ey)); py += cy, y++) {
+ /* children nodes will be no longer smaller than max distance
+ * with only insertion costs.
+ * This is end of row on allocated memory. */
+ if (y > lx + max_distance) {
+ *can_transition = GRN_FALSE;
+ return max_distance + 1;
+ }
+
+ for (px = sx, x = 1; px < ex && (cx = grn_charlen(ctx, px, ex)); px += cx, x++) {
+ if (cx == cy && !memcmp(px, py, cx)) {
+ DIST(x, y) = DIST(x - 1, y - 1);
+ } else {
+ uint32_t a, b, c;
+ a = DIST(x - 1, y) + 1;
+ b = DIST(x, y - 1) + 1;
+ c = DIST(x - 1, y - 1) + 1;
+ DIST(x, y) = ((a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c));
+ if (flags & GRN_TABLE_FUZZY_SEARCH_WITH_TRANSPOSITION &&
+ x > 1 && y > 1 &&
+ cx == cy &&
+ memcmp(px, py - cy, cx) == 0 &&
+ memcmp(px - cx, py, cx) == 0) {
+ uint32_t t = DIST(x - 2, y - 2) + 1;
+ DIST(x, y) = ((DIST(x, y) < t) ? DIST(x, y) : t);
+ }
+ }
+ }
+ }
+ if (lx) {
+ /* If there is no cell which is smaller than equal to max distance on end of row,
+ * children nodes will be no longer smaller than max distance */
+ *can_transition = GRN_FALSE;
+ for (x = 1; x <= lx; x++) {
+ if (DIST(x, y - 1) <= max_distance) {
+ *can_transition = GRN_TRUE;
+ break;
+ }
+ }
+ }
+ return DIST(lx, y - 1);
+}
+
+typedef struct {
+ const char *key;
+ int key_length;
+ grn_bool can_transition;
+} fuzzy_node;
+
+inline static void
+_grn_pat_fuzzy_search(grn_ctx *ctx, grn_pat *pat, grn_id id,
+ const char *key, uint32_t key_size,
+ uint16_t *dists, uint32_t lx,
+ int last_check, fuzzy_node *last_node,
+ uint32_t max_distance, int flags, fuzzy_heap *heap)
+{
+ pat_node *node = NULL;
+ int check, len;
+ const char *k;
+ uint32_t offset = 0;
+
+ PAT_AT(pat, id, node);
+ if (!node) {
+ return;
+ }
+ check = PAT_CHK(node);
+ len = PAT_LEN(node);
+ k = pat_node_get_key(ctx, pat, node);
+
+ if (check > last_check) {
+ if (len >= last_node->key_length &&
+ !memcmp(k, last_node->key, last_node->key_length)) {
+ if (last_node->can_transition == GRN_FALSE) {
+ return;
+ }
+ }
+ _grn_pat_fuzzy_search(ctx, pat, node->lr[0],
+ key, key_size, dists, lx,
+ check, last_node,
+ max_distance, flags, heap);
+
+ _grn_pat_fuzzy_search(ctx, pat, node->lr[1],
+ key, key_size, dists, lx,
+ check, last_node,
+ max_distance, flags, heap);
+ } else {
+ if (id) {
+ /* Set already calculated common prefix length */
+ if (len >= last_node->key_length &&
+ !memcmp(k, last_node->key, last_node->key_length)) {
+ if (last_node->can_transition == GRN_FALSE) {
+ return;
+ }
+ offset = last_node->key_length;
+ } else {
+ if (last_node->can_transition == GRN_FALSE) {
+ last_node->can_transition = GRN_TRUE;
+ }
+ if (last_node->key_length) {
+ const char *kp = k;
+ const char *ke = k + len;
+ const char *p = last_node->key;
+ const char *e = last_node->key + last_node->key_length;
+ int lp;
+ for (;p < e && kp < ke && (lp = grn_charlen(ctx, p, e));
+ p += lp, kp += lp) {
+ if (p + lp <= e && kp + lp <= ke && memcmp(p, kp, lp)) {
+ break;
+ }
+ }
+ offset = kp - k;
+ }
+ }
+ if (len - offset) {
+ uint16_t distance;
+ distance =
+ calc_edit_distance_by_offset(ctx,
+ key, key + key_size,
+ k, k + len,
+ dists, lx,
+ offset, max_distance,
+ &(last_node->can_transition), flags);
+ if (distance <= max_distance) {
+ fuzzy_heap_push(ctx, heap, id, distance);
+ }
+ }
+ last_node->key = k;
+ last_node->key_length = len;
+ }
+ }
+ return;
+}
+
+#define HEAP_SIZE 256
+
+grn_rc
+grn_pat_fuzzy_search(grn_ctx *ctx, grn_pat *pat,
+ const void *key, uint32_t key_size,
+ grn_fuzzy_search_optarg *args, grn_hash *h)
+{
+ pat_node *node;
+ grn_id id;
+ uint16_t *dists;
+ uint32_t lx, len, x, y, i;
+ const char *s = key;
+ const char *e = (const char *)key + key_size;
+ fuzzy_node last_node;
+ fuzzy_heap *heap;
+ uint32_t max_distance = 1;
+ uint32_t max_expansion = 0;
+ uint32_t prefix_match_size = 0;
+ int flags = 0;
+ grn_rc rc = grn_pat_error_if_truncated(ctx, pat);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (args) {
+ max_distance = args->max_distance;
+ max_expansion = args->max_expansion;
+ prefix_match_size = args->prefix_match_size;
+ flags = args->flags;
+ }
+ if (key_size > GRN_TABLE_MAX_KEY_SIZE ||
+ max_distance > GRN_TABLE_MAX_KEY_SIZE ||
+ prefix_match_size > key_size) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ heap = fuzzy_heap_open(ctx, HEAP_SIZE);
+ if (!heap) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+
+ PAT_AT(pat, GRN_ID_NIL, node);
+ id = node->lr[1];
+
+ if (prefix_match_size) {
+ grn_id tid;
+ tid = common_prefix_pat_node_get(ctx, pat, key, prefix_match_size);
+ if (tid != GRN_ID_NIL) {
+ id = tid;
+ } else {
+ return GRN_END_OF_DATA;
+ }
+ }
+ for (lx = 0; s < e && (len = grn_charlen(ctx, s, e)); s += len) {
+ lx++;
+ }
+ dists = GRN_MALLOC((lx + 1) * (lx + max_distance + 1) * sizeof(uint16_t));
+ if (!dists) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+
+ for (x = 0; x <= lx; x++) { DIST(x, 0) = x; }
+ for (y = 0; y <= lx + max_distance ; y++) { DIST(0, y) = y; }
+
+ last_node.key = NULL;
+ last_node.key_length = 0;
+ last_node.can_transition = GRN_TRUE;
+ _grn_pat_fuzzy_search(ctx, pat, id,
+ key, key_size, dists, lx,
+ -1, &last_node, max_distance, flags, heap);
+ GRN_FREE(dists);
+ for (i = 0; i < heap->n_entries; i++) {
+ if (max_expansion > 0 && i >= max_expansion) {
+ break;
+ }
+ if (DB_OBJ(h)->header.flags & GRN_OBJ_WITH_SUBREC) {
+ grn_rset_recinfo *ri;
+ if (grn_hash_add(ctx, h, &(heap->nodes[i].id), sizeof(grn_id), (void **)&ri, NULL)) {
+ ri->score = max_distance - heap->nodes[i].distance + 1;
+ }
+ } else {
+ grn_hash_add(ctx, h, &(heap->nodes[i].id), sizeof(grn_id), NULL, NULL);
+ }
+ }
+ fuzzy_heap_close(ctx, heap);
+ if (grn_hash_size(ctx, h)) {
+ return GRN_SUCCESS;
+ } else {
+ return GRN_END_OF_DATA;
+ }
+}
+
inline static grn_rc
_grn_pat_del(grn_ctx *ctx, grn_pat *pat, const char *key, uint32_t key_size, int shared,
grn_table_delete_optarg *optarg)
{
grn_pat_delinfo *di;
- uint8_t direction;
- pat_node *rn, *rn0 = NULL, *rno;
- int c, c0 = -1, ch;
+ pat_node *rn, *rn0 = NULL, *rno = NULL;
+ int c = -1, c0 = -1, ch;
uint32_t len = key_size * 16;
grn_id r, otherside, *proot, *p, *p0 = NULL;
- di = delinfo_new(ctx, pat); /* must be called before find rn */
+ /* delinfo_new() must be called before searching for rn. */
+ di = delinfo_new(ctx, pat);
di->shared = shared;
+
+ /*
+ * Search a patricia tree for a given key.
+ * If the key exists, get its output node.
+ *
+ * rn, rn0: the output node and its previous node.
+ * rno: the other side of rn (the other destination of rn0).
+ * c, c0: checks of rn0 and its previous node.
+ * p, p0: pointers to transitions (IDs) that refer to rn and rn0.
+ */
PAT_AT(pat, 0, rn);
- c = -1;
proot = p = &rn->lr[1];
for (;;) {
- if (!(r = *p)) { return GRN_INVALID_ARGUMENT; }
+ r = *p;
+ if (!r) {
+ return GRN_INVALID_ARGUMENT;
+ }
PAT_AT(pat, r, rn);
- if (!rn) { return GRN_FILE_CORRUPT; }
+ if (!rn) {
+ return GRN_FILE_CORRUPT;
+ }
ch = PAT_CHK(rn);
- if (len <= ch) { return GRN_INVALID_ARGUMENT; }
+ if (len <= ch) {
+ return GRN_INVALID_ARGUMENT;
+ }
if (c >= ch) {
+ /* Output node found. */
const uint8_t *k = pat_node_get_key(ctx, pat, rn);
- if (!k) { return GRN_INVALID_ARGUMENT; }
- if (key_size == PAT_LEN(rn) && !memcmp(k, key, key_size)) {
- break; /* found */
- } else { return GRN_INVALID_ARGUMENT; }
+ if (!k) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (key_size != PAT_LEN(rn) || memcmp(k, key, key_size)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ /* Given key found. */
+ break;
}
c0 = c;
p0 = p;
- if ((c = ch) & 1) {
+ c = ch;
+ if (c & 1) {
p = (c + 1 < len) ? &rn->lr[1] : &rn->lr[0];
} else {
p = &rn->lr[nth_bit((uint8_t *)key, c, len)];
@@ -1131,30 +1641,58 @@ _grn_pat_del(grn_ctx *ctx, grn_pat *pat, const char *key, uint32_t key_size, int
!optarg->func(ctx, (grn_obj *)pat, r, optarg->func_arg)) {
return GRN_SUCCESS;
}
- direction = (rn0->lr[1] == r);
- otherside = direction ? rn0->lr[0] : rn0->lr[1];
+ if (rn0->lr[0] == rn0->lr[1]) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "*p0 (%d), rn0->lr[0] == rn0->lr[1] (%d)",
+ *p0, rn0->lr[0]);
+ return GRN_FILE_CORRUPT;
+ }
+ otherside = (rn0->lr[1] == r) ? rn0->lr[0] : rn0->lr[1];
+ if (otherside) {
+ PAT_AT(pat, otherside, rno);
+ if (!rno) {
+ return GRN_FILE_CORRUPT;
+ }
+ }
+
if (rn == rn0) {
+ /* The last transition (p) is a self-loop. */
di->stat = DL_PHASE2;
di->d = r;
if (otherside) {
- if (otherside == r) {
- otherside = 0;
- } else {
- PAT_AT(pat, otherside, rno);
- if (rno && c0 < PAT_CHK(rno) && PAT_CHK(rno) <= c) {
- if (!delinfo_search(pat, otherside)) {
- GRN_LOG(ctx, GRN_LOG_DEBUG, "no delinfo found %d", otherside);
- }
- PAT_CHK_SET(rno, 0);
+ if (c0 < PAT_CHK(rno) && PAT_CHK(rno) <= c) {
+ /* To keep rno as an output node, its check is set to zero. */
+ if (!delinfo_search(pat, otherside)) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "no delinfo found %d", otherside);
}
- if (proot == p0 && !rno->check) { rno->lr[0] = rno->lr[1] = otherside; }
+ PAT_CHK_SET(rno, 0);
+ }
+ if (proot == p0 && !rno->check) {
+ /*
+ * Update rno->lr because the first node, rno becomes the new first
+ * node, is not an output node even if its check is zero.
+ */
+ const uint8_t *k = pat_node_get_key(ctx, pat, rno);
+ int direction = k ? (*k >> 7) : 1;
+ rno->lr[direction] = otherside;
+ rno->lr[!direction] = 0;
}
}
*p0 = otherside;
+ } else if ((!rn->lr[0] && rn->lr[1] == r) ||
+ (!rn->lr[1] && rn->lr[0] == r)) {
+ /* The output node has only a disabled self-loop. */
+ di->stat = DL_PHASE2;
+ di->d = r;
+ *p = 0;
} else {
+ /* The last transition (p) is not a self-loop. */
grn_pat_delinfo *ldi = NULL, *ddi = NULL;
- if (PAT_DEL(rn)) { ldi = delinfo_search(pat, r); }
- if (PAT_DEL(rn0)) { ddi = delinfo_search(pat, *p0); }
+ if (PAT_DEL(rn)) {
+ ldi = delinfo_search(pat, r);
+ }
+ if (PAT_DEL(rn0)) {
+ ddi = delinfo_search(pat, *p0);
+ }
if (ldi) {
PAT_DEL_OFF(rn);
di->stat = DL_PHASE2;
@@ -1201,21 +1739,36 @@ _grn_pat_del(grn_ctx *ctx, grn_pat *pat, const char *key, uint32_t key_size, int
}
}
if (*p0 == otherside) {
- PAT_CHK_SET(rn0, 0);
- if (proot == p0 && !rn0->check) { rn0->lr[0] = rn0->lr[1] = otherside; }
+ /* The previous node (*p0) has a self-loop (rn0 == rno). */
+ PAT_CHK_SET(rno, 0);
+ if (proot == p0) {
+ /*
+ * Update rno->lr because the first node, rno becomes the new first
+ * node, is not an output node even if its check is zero.
+ */
+ const uint8_t *k = pat_node_get_key(ctx, pat, rno);
+ int direction = k ? (*k >> 7) : 1;
+ rno->lr[direction] = otherside;
+ rno->lr[!direction] = 0;
+ }
} else {
if (otherside) {
- if (otherside == r) {
- otherside = 0;
- } else {
- PAT_AT(pat, otherside, rno);
- if (rno && c0 < PAT_CHK(rno) && PAT_CHK(rno) <= c) {
- if (!delinfo_search(pat, otherside)) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "no delinfo found %d", otherside);
- }
- PAT_CHK_SET(rno, 0);
+ if (c0 < PAT_CHK(rno) && PAT_CHK(rno) <= c) {
+ /* To keep rno as an output node, its check is set to zero. */
+ if (!delinfo_search(pat, otherside)) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "no delinfo found %d", otherside);
}
- if (proot == p0 && !rno->check) { rno->lr[0] = rno->lr[1] = otherside; }
+ PAT_CHK_SET(rno, 0);
+ }
+ if (proot == p0 && !rno->check) {
+ /*
+ * Update rno->lr because the first node, rno becomes the new first
+ * node, is not an output node even if its check is zero.
+ */
+ const uint8_t *k = pat_node_get_key(ctx, pat, rno);
+ int direction = k ? (*k >> 7) : 1;
+ rno->lr[direction] = otherside;
+ rno->lr[!direction] = 0;
}
}
*p0 = otherside;
@@ -1244,8 +1797,13 @@ grn_rc
grn_pat_delete(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size,
grn_table_delete_optarg *optarg)
{
+ grn_rc rc;
uint8_t keybuf[MAX_FIXED_KEY_SIZE];
if (!pat || !key || !key_size) { return GRN_INVALID_ARGUMENT; }
+ rc = grn_pat_error_if_truncated(ctx, pat);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
KEY_ENCODE(pat, keybuf, key, key_size);
return _grn_pat_delete(ctx, pat, key, key_size, optarg);
}
@@ -1254,6 +1812,9 @@ uint32_t
grn_pat_size(grn_ctx *ctx, grn_pat *pat)
{
if (!pat) { return GRN_INVALID_ARGUMENT; }
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return 0;
+ }
return pat->header->n_entries;
}
@@ -1262,6 +1823,10 @@ _grn_pat_key(grn_ctx *ctx, grn_pat *pat, grn_id id, uint32_t *key_size)
{
pat_node *node;
uint8_t *key;
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ *key_size = 0;
+ return NULL;
+ }
PAT_AT(pat, id, node);
if (!node) {
*key_size = 0;
@@ -1280,7 +1845,12 @@ grn_rc
grn_pat_delete_by_id(grn_ctx *ctx, grn_pat *pat, grn_id id,
grn_table_delete_optarg *optarg)
{
+ grn_rc rc;
if (!pat || !id) { return GRN_INVALID_ARGUMENT; }
+ rc = grn_pat_error_if_truncated(ctx, pat);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
{
uint32_t key_size;
const char *key = _grn_pat_key(ctx, pat, id, &key_size);
@@ -1294,7 +1864,11 @@ grn_pat_get_key(grn_ctx *ctx, grn_pat *pat, grn_id id, void *keybuf, int bufsize
int len;
uint8_t *key;
pat_node *node;
- if (!pat) { return GRN_INVALID_ARGUMENT; }
+ if (!pat) { return 0; }
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return 0;
+ }
+ if (!id) { return 0; }
PAT_AT(pat, id, node);
if (!node) { return 0; }
if (!(key = pat_node_get_key(ctx, pat, node))) { return 0; }
@@ -1316,6 +1890,10 @@ grn_pat_get_key2(grn_ctx *ctx, grn_pat *pat, grn_id id, grn_obj *bulk)
uint8_t *key;
pat_node *node;
if (!pat) { return GRN_INVALID_ARGUMENT; }
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return 0;
+ }
+ if (!id) { return 0; }
PAT_AT(pat, id, node);
if (!node) { return 0; }
if (!(key = pat_node_get_key(ctx, pat, node))) { return 0; }
@@ -1343,7 +1921,11 @@ grn_pat_get_key2(grn_ctx *ctx, grn_pat *pat, grn_id id, grn_obj *bulk)
int
grn_pat_get_value(grn_ctx *ctx, grn_pat *pat, grn_id id, void *valuebuf)
{
- int value_size = (int)pat->value_size;
+ int value_size;
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return 0;
+ }
+ value_size = (int)pat->value_size;
if (value_size) {
byte *v = (byte *)sis_at(ctx, pat, id);
if (v) {
@@ -1364,6 +1946,9 @@ const char *
grn_pat_get_value_(grn_ctx *ctx, grn_pat *pat, grn_id id, uint32_t *size)
{
const char *value = NULL;
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return NULL;
+ }
if ((*size = pat->value_size)) {
if ((value = (const char *)sis_at(ctx, pat, id))
&& (pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS)) {
@@ -1377,6 +1962,10 @@ grn_rc
grn_pat_set_value(grn_ctx *ctx, grn_pat *pat, grn_id id,
const void *value, int flags)
{
+ grn_rc rc = grn_pat_error_if_truncated(ctx, pat);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
if (value) {
uint32_t value_size = pat->value_size;
if (value_size) {
@@ -1427,14 +2016,18 @@ grn_rc
grn_pat_info(grn_ctx *ctx, grn_pat *pat, int *key_size, unsigned int *flags,
grn_encoding *encoding, unsigned int *n_entries, unsigned int *file_size)
{
+ grn_rc rc;
ERRCLR(NULL);
if (!pat) { return GRN_INVALID_ARGUMENT; }
+ rc = grn_pat_error_if_truncated(ctx, pat);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
if (key_size) { *key_size = pat->key_size; }
if (flags) { *flags = pat->obj.header.flags; }
if (encoding) { *encoding = pat->encoding; }
if (n_entries) { *n_entries = pat->header->n_entries; }
if (file_size) {
- grn_rc rc;
uint64_t tmp = 0;
if ((rc = grn_io_size(ctx, pat->io, &tmp))) {
return rc;
@@ -1450,7 +2043,11 @@ grn_pat_delete_with_sis(grn_ctx *ctx, grn_pat *pat, grn_id id,
{
int level = 0, shared;
const char *key = NULL, *_key;
- sis_node *sp, *ss = NULL, *si = sis_at(ctx, pat, id);
+ sis_node *sp, *ss = NULL, *si;
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return 0;
+ }
+ si = sis_at(ctx, pat, id);
while (id) {
pat_node *rn;
uint32_t key_size;
@@ -1524,6 +2121,9 @@ grn_pat_delete_with_sis(grn_ctx *ctx, grn_pat *pat, grn_id id,
grn_id
grn_pat_next(grn_ctx *ctx, grn_pat *pat, grn_id id)
{
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
while (++id <= pat->header->curr_rec) {
uint32_t key_size;
const char *key = _grn_pat_key(ctx, pat, id, &key_size);
@@ -1546,6 +2146,9 @@ grn_pat_at(grn_ctx *ctx, grn_pat *pat, grn_id id)
grn_id
grn_pat_curr_id(grn_ctx *ctx, grn_pat *pat)
{
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
return pat->header->curr_rec;
}
@@ -1555,11 +2158,19 @@ grn_pat_scan(grn_ctx *ctx, grn_pat *pat, const char *str, unsigned int str_len,
{
int n = 0;
grn_id tid;
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return 0;
+ }
if (pat->normalizer) {
+ int flags =
+ GRN_STRING_REMOVE_BLANK |
+ GRN_STRING_WITH_TYPES |
+ GRN_STRING_WITH_CHECKS;
grn_obj *nstr = grn_string_open(ctx, str, str_len,
- pat->normalizer, GRN_STRING_WITH_CHECKS);
+ pat->normalizer, flags);
if (nstr) {
const short *cp = grn_string_get_checks(ctx, nstr);
+ const unsigned char *tp = grn_string_get_types(ctx, nstr);
unsigned int offset = 0, offset0 = 0;
unsigned int normalized_length_in_bytes;
const char *sp, *se;
@@ -1568,18 +2179,54 @@ grn_pat_scan(grn_ctx *ctx, grn_pat *pat, const char *str, unsigned int str_len,
se = sp + normalized_length_in_bytes;
while (n < sh_size) {
if ((tid = grn_pat_lcp_search(ctx, pat, sp, se - sp))) {
+ const char *key;
uint32_t len;
- _grn_pat_key(ctx, pat, tid, &len);
+ int first_key_char_len;
+ key = _grn_pat_key(ctx, pat, tid, &len);
sh[n].id = tid;
sh[n].offset = (*cp > 0) ? offset : offset0;
- while (len--) {
- if (*cp > 0) { offset0 = offset; offset += *cp; }
- sp++; cp++;
+ first_key_char_len = grn_charlen(ctx, key, key + len);
+ if (sh[n].offset > 0 &&
+ GRN_CHAR_IS_BLANK(tp[-1]) &&
+ ((first_key_char_len == 1 && key[0] != ' ') ||
+ first_key_char_len > 1)){
+ /* Remove leading spaces. */
+ const char *original_str = str + sh[n].offset;
+ while (grn_charlen(ctx, original_str, str + str_len) == 1 &&
+ original_str[0] == ' ') {
+ original_str++;
+ sh[n].offset++;
+ }
+ }
+ {
+ grn_bool blank_in_alnum = GRN_FALSE;
+ const unsigned char *start_tp = tp;
+ const unsigned char *blank_in_alnum_check_tp;
+ while (len--) {
+ if (*cp > 0) { offset0 = offset; offset += *cp; tp++; }
+ sp++; cp++;
+ }
+ sh[n].length = offset - sh[n].offset;
+ for (blank_in_alnum_check_tp = start_tp + 1;
+ blank_in_alnum_check_tp < tp;
+ blank_in_alnum_check_tp++) {
+#define GRN_CHAR_IS_ALNUM(char_type) \
+ (GRN_CHAR_TYPE(char_type) == GRN_CHAR_ALPHA || \
+ GRN_CHAR_TYPE(char_type) == GRN_CHAR_DIGIT)
+ if (GRN_CHAR_IS_BLANK(blank_in_alnum_check_tp[0]) &&
+ GRN_CHAR_IS_ALNUM(blank_in_alnum_check_tp[-1]) &&
+ (blank_in_alnum_check_tp + 1) < tp &&
+ GRN_CHAR_IS_ALNUM(blank_in_alnum_check_tp[1])) {
+ blank_in_alnum = GRN_TRUE;
+ }
+#undef GRN_CHAR_IS_ALNUM
+ }
+ if (!blank_in_alnum) {
+ n++;
+ }
}
- sh[n].length = offset - sh[n].offset;
- n++;
} else {
- if (*cp > 0) { offset0 = offset; offset += *cp; }
+ if (*cp > 0) { offset0 = offset; offset += *cp; tp++; }
do {
sp++; cp++;
} while (sp < se && !*cp);
@@ -1679,55 +2326,52 @@ grn_pat_cursor_next(grn_ctx *ctx, grn_pat_cursor *c)
while ((se = pop(c))) {
grn_id id = se->id;
int check = se->check, ch;
- for (;;) {
- if (id) {
- PAT_AT(c->pat, id, node);
- if (node) {
- ch = PAT_CHK(node);
- if (ch > check) {
+ while (id) {
+ PAT_AT(c->pat, id, node);
+ if (!node) {
+ break;
+ }
+ ch = PAT_CHK(node);
+ if (ch > check) {
+ if (c->obj.header.flags & GRN_CURSOR_DESCENDING) {
+ push(c, node->lr[0], ch);
+ id = node->lr[1];
+ } else {
+ push(c, node->lr[1], ch);
+ id = node->lr[0];
+ }
+ check = ch;
+ continue;
+ } else {
+ if (id == c->tail) {
+ c->sp = 0;
+ } else {
+ if (!c->curr_rec && c->tail) {
+ uint32_t lmin, lmax;
+ pat_node *nmin, *nmax;
+ const uint8_t *kmin, *kmax;
if (c->obj.header.flags & GRN_CURSOR_DESCENDING) {
- push(c, node->lr[0], ch);
- id = node->lr[1];
+ PAT_AT(c->pat, c->tail, nmin);
+ PAT_AT(c->pat, id, nmax);
} else {
- push(c, node->lr[1], ch);
- id = node->lr[0];
+ PAT_AT(c->pat, id, nmin);
+ PAT_AT(c->pat, c->tail, nmax);
}
- check = ch;
- continue;
- } else {
- if (id == c->tail) {
+ lmin = PAT_LEN(nmin);
+ lmax = PAT_LEN(nmax);
+ kmin = pat_node_get_key(ctx, c->pat, nmin);
+ kmax = pat_node_get_key(ctx, c->pat, nmax);
+ if ((lmin < lmax) ?
+ (memcmp(kmin, kmax, lmin) > 0) :
+ (memcmp(kmin, kmax, lmax) >= 0)) {
c->sp = 0;
- } else {
- if (!c->curr_rec && c->tail) {
- uint32_t lmin, lmax;
- pat_node *nmin, *nmax;
- const uint8_t *kmin, *kmax;
- if (c->obj.header.flags & GRN_CURSOR_DESCENDING) {
- PAT_AT(c->pat, c->tail, nmin);
- PAT_AT(c->pat, id, nmax);
- } else {
- PAT_AT(c->pat, id, nmin);
- PAT_AT(c->pat, c->tail, nmax);
- }
- lmin = PAT_LEN(nmin);
- lmax = PAT_LEN(nmax);
- kmin = pat_node_get_key(ctx, c->pat, nmin);
- kmax = pat_node_get_key(ctx, c->pat, nmax);
- if ((lmin < lmax) ?
- (memcmp(kmin, kmax, lmin) > 0) :
- (memcmp(kmin, kmax, lmax) >= 0)) {
- c->sp = 0;
- break;
- }
- }
+ break;
}
- c->curr_rec = id;
- c->rest--;
- return id;
}
}
- } else {
- break;
+ c->curr_rec = id;
+ c->rest--;
+ return id;
}
}
}
@@ -2144,6 +2788,9 @@ grn_pat_cursor_open(grn_ctx *ctx, grn_pat *pat,
pat_node *node;
grn_pat_cursor *c;
if (!pat || !ctx) { return NULL; }
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return NULL;
+ }
if ((flags & GRN_CURSOR_BY_ID)) {
return grn_pat_cursor_open_by_id(ctx, pat, min, min_size, max, max_size,
offset, limit, flags);
@@ -2307,6 +2954,9 @@ grn_pat_check(grn_ctx *ctx, grn_pat *pat)
{
char buf[8];
struct grn_pat_header *h = pat->header;
+ if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) {
+ return;
+ }
GRN_OUTPUT_ARRAY_OPEN("RESULT", 1);
GRN_OUTPUT_MAP_OPEN("SUMMARY", 23);
GRN_OUTPUT_CSTR("flags");
@@ -2338,6 +2988,47 @@ grn_pat_check(grn_ctx *ctx, grn_pat *pat)
GRN_OUTPUT_ARRAY_CLOSE();
}
+/* utilities */
+void
+grn_p_pat_node(grn_ctx *ctx, grn_pat *pat, pat_node *node)
+{
+ uint8_t *key = NULL;
+
+ if (!node) {
+ printf("#<pat_node:(null)>\n");
+ return;
+ }
+
+ if (PAT_IMD(node)) {
+ key = (uint8_t *)&(node->key);
+ } else {
+ KEY_AT(pat, node->key, key, 0);
+ }
+
+ printf("#<pat_node:%p "
+ "left:%u "
+ "right:%u "
+ "deleting:%s "
+ "immediate:%s "
+ "length:%u "
+ "nth-byte:%u "
+ "nth-bit:%u "
+ "terminated:%s "
+ "key:<%.*s>"
+ ">\n",
+ node,
+ node->lr[0],
+ node->lr[1],
+ PAT_DEL(node) ? "true" : "false",
+ PAT_IMD(node) ? "true" : "false",
+ PAT_LEN(node),
+ PAT_CHK(node) >> 4,
+ (PAT_CHK(node) >> 1) & 0x7,
+ (PAT_CHK(node) & 0x1) ? "true" : "false",
+ PAT_LEN(node),
+ (char *)key);
+}
+
static void
grn_pat_inspect_check(grn_ctx *ctx, grn_obj *buf, int check)
{
@@ -2366,8 +3057,16 @@ grn_pat_inspect_node(grn_ctx *ctx, grn_pat *pat, grn_id id, int check,
}
GRN_TEXT_PUTS(ctx, buf, prefix);
grn_text_lltoa(ctx, buf, id);
+ grn_pat_inspect_check(ctx, buf, c);
if (c > check) {
+ GRN_TEXT_PUTS(ctx, buf, "\n");
+ grn_pat_inspect_node(ctx, pat, node->lr[0], c, key_buf,
+ indent + 2, "L:", buf);
+ GRN_TEXT_PUTS(ctx, buf, "\n");
+ grn_pat_inspect_node(ctx, pat, node->lr[1], c, key_buf,
+ indent + 2, "R:", buf);
+ } else if (id) {
int key_size;
uint8_t *key;
@@ -2379,8 +3078,6 @@ grn_pat_inspect_node(grn_ctx *ctx, grn_pat *pat, grn_id id, int check,
grn_inspect(ctx, buf, key_buf);
GRN_TEXT_PUTS(ctx, buf, ")");
- grn_pat_inspect_check(ctx, buf, c);
-
GRN_TEXT_PUTS(ctx, buf, "[");
key = pat_node_get_key(ctx, pat, node);
for (i = 0; i < key_size; i++) {
@@ -2395,15 +3092,6 @@ grn_pat_inspect_node(grn_ctx *ctx, grn_pat *pat, grn_id id, int check,
}
GRN_TEXT_PUTS(ctx, buf, "]");
}
-
- if (c > check) {
- GRN_TEXT_PUTS(ctx, buf, "\n");
- grn_pat_inspect_node(ctx, pat, node->lr[0], c, key_buf,
- indent + 2, "L:", buf);
- GRN_TEXT_PUTS(ctx, buf, "\n");
- grn_pat_inspect_node(ctx, pat, node->lr[1], c, key_buf,
- indent + 2, "R:", buf);
- }
}
void
@@ -2922,3 +3610,79 @@ set_cursor_rk(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
}
return ctx->rc;
}
+
+uint32_t
+grn_pat_total_key_size(grn_ctx *ctx, grn_pat *pat)
+{
+ return pat->header->curr_key;
+}
+
+grn_bool
+grn_pat_is_key_encoded(grn_ctx *ctx, grn_pat *pat)
+{
+ grn_obj *domain;
+ uint32_t key_size;
+
+ domain = grn_ctx_at(ctx, pat->obj.header.domain);
+ if (grn_obj_is_type(ctx, domain)) {
+ key_size = grn_type_size(ctx, domain);
+ } else {
+ key_size = sizeof(grn_id);
+ }
+
+ return KEY_NEEDS_CONVERT(pat, key_size);
+}
+
+grn_rc
+grn_pat_dirty(grn_ctx *ctx, grn_pat *pat)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ CRITICAL_SECTION_ENTER(pat->lock);
+ if (!pat->is_dirty) {
+ uint32_t n_dirty_opens;
+ pat->is_dirty = GRN_TRUE;
+ GRN_ATOMIC_ADD_EX(&(pat->header->n_dirty_opens), 1, n_dirty_opens);
+ rc = grn_io_flush(ctx, pat->io);
+ }
+ CRITICAL_SECTION_LEAVE(pat->lock);
+
+ return rc;
+}
+
+grn_bool
+grn_pat_is_dirty(grn_ctx *ctx, grn_pat *pat)
+{
+ return pat->header->n_dirty_opens > 0;
+}
+
+grn_rc
+grn_pat_clean(grn_ctx *ctx, grn_pat *pat)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ CRITICAL_SECTION_ENTER(pat->lock);
+ if (pat->is_dirty) {
+ uint32_t n_dirty_opens;
+ pat->is_dirty = GRN_FALSE;
+ GRN_ATOMIC_ADD_EX(&(pat->header->n_dirty_opens), -1, n_dirty_opens);
+ rc = grn_io_flush(ctx, pat->io);
+ }
+ CRITICAL_SECTION_LEAVE(pat->lock);
+
+ return rc;
+}
+
+grn_rc
+grn_pat_clear_dirty(grn_ctx *ctx, grn_pat *pat)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ CRITICAL_SECTION_ENTER(pat->lock);
+ pat->is_dirty = GRN_FALSE;
+ pat->header->n_dirty_opens = 0;
+ rc = grn_io_flush(ctx, pat->io);
+ CRITICAL_SECTION_LEAVE(pat->lock);
+
+ return rc;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/plugin.c b/storage/mroonga/vendor/groonga/lib/plugin.c
index 7db19c1a5a5..e60c22ed998 100644
--- a/storage/mroonga/vendor/groonga/lib/plugin.c
+++ b/storage/mroonga/vendor/groonga/lib/plugin.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2012-2015 Brazil
+ Copyright(C) 2012-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,6 +16,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "grn.h"
+#include "grn_ctx_impl_mrb.h"
+#include "grn_proc.h"
#include <groonga/plugin.h>
#include <stdarg.h>
@@ -44,6 +46,7 @@
static grn_hash *grn_plugins = NULL;
static grn_critical_section grn_plugins_lock;
+static grn_ctx grn_plugins_ctx;
#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
@@ -96,7 +99,7 @@ grn_plugin_reference(grn_ctx *ctx, const char *filename)
grn_plugin **plugin = NULL;
CRITICAL_SECTION_ENTER(grn_plugins_lock);
- id = grn_hash_get(&grn_gctx, grn_plugins,
+ id = grn_hash_get(&grn_plugins_ctx, grn_plugins,
filename, GRN_PLUGIN_KEY_SIZE(filename),
(void **)&plugin);
if (plugin) {
@@ -121,7 +124,7 @@ grn_plugin_path(grn_ctx *ctx, grn_id id)
}
CRITICAL_SECTION_ENTER(grn_plugins_lock);
- value_size = grn_hash_get_value(&grn_gctx, grn_plugins, id, &plugin);
+ value_size = grn_hash_get_value(&grn_plugins_ctx, grn_plugins, id, &plugin);
CRITICAL_SECTION_LEAVE(grn_plugins_lock);
if (!plugin) {
@@ -149,12 +152,17 @@ static grn_rc
grn_plugin_call_init(grn_ctx *ctx, grn_id id)
{
grn_plugin *plugin;
- if (!grn_hash_get_value(&grn_gctx, grn_plugins, id, &plugin)) {
+ int size;
+
+ size = grn_hash_get_value(&grn_plugins_ctx, grn_plugins, id, &plugin);
+ if (size == 0) {
return GRN_INVALID_ARGUMENT;
}
+
if (plugin->init_func) {
return plugin->init_func(ctx);
}
+
return GRN_SUCCESS;
}
@@ -162,12 +170,21 @@ grn_plugin_call_init(grn_ctx *ctx, grn_id id)
static grn_rc
grn_plugin_call_register_mrb(grn_ctx *ctx, grn_id id, grn_plugin *plugin)
{
- grn_mrb_data *data = &(ctx->impl->mrb);
- mrb_state *mrb = data->state;
- struct RClass *module = data->module;
+ grn_mrb_data *data;
+ mrb_state *mrb;
+ struct RClass *module;
struct RClass *plugin_loader_class;
int arena_index;
+ grn_ctx_impl_mrb_ensure_init(ctx);
+ if (ctx->rc != GRN_SUCCESS) {
+ return ctx->rc;
+ }
+
+ data = &(ctx->impl->mrb);
+ mrb = data->state;
+ module = data->module;
+
{
int added;
grn_hash_add(ctx, ctx->impl->mrb.registered_plugins,
@@ -190,17 +207,26 @@ static grn_rc
grn_plugin_call_register(grn_ctx *ctx, grn_id id)
{
grn_plugin *plugin;
- if (!grn_hash_get_value(&grn_gctx, grn_plugins, id, &plugin)) {
+ int size;
+
+ CRITICAL_SECTION_ENTER(grn_plugins_lock);
+ size = grn_hash_get_value(&grn_plugins_ctx, grn_plugins, id, &plugin);
+ CRITICAL_SECTION_LEAVE(grn_plugins_lock);
+
+ if (size == 0) {
return GRN_INVALID_ARGUMENT;
}
+
#ifdef GRN_WITH_MRUBY
if (!plugin->dl) {
return grn_plugin_call_register_mrb(ctx, id, plugin);
}
#endif /* GRN_WITH_MRUBY */
+
if (plugin->register_func) {
return plugin->register_func(ctx);
}
+
return GRN_SUCCESS;
}
@@ -208,12 +234,17 @@ static grn_rc
grn_plugin_call_fin(grn_ctx *ctx, grn_id id)
{
grn_plugin *plugin;
- if (!grn_hash_get_value(&grn_gctx, grn_plugins, id, &plugin)) {
+ int size;
+
+ size = grn_hash_get_value(&grn_plugins_ctx, grn_plugins, id, &plugin);
+ if (size == 0) {
return GRN_INVALID_ARGUMENT;
}
+
if (plugin->fin_func) {
return plugin->fin_func(ctx);
}
+
return GRN_SUCCESS;
}
@@ -229,7 +260,7 @@ grn_plugin_initialize(grn_ctx *ctx, grn_plugin *plugin,
if (!plugin->type ## _func) { \
const char *label; \
label = grn_dl_sym_error_label(); \
- SERR(label); \
+ SERR("%s", label); \
} \
} while (0)
@@ -262,23 +293,32 @@ grn_plugin_initialize(grn_ctx *ctx, grn_plugin *plugin,
static grn_id
grn_plugin_open_mrb(grn_ctx *ctx, const char *filename, size_t filename_size)
{
+ grn_ctx *plugins_ctx = &grn_plugins_ctx;
grn_id id = GRN_ID_NIL;
grn_plugin **plugin = NULL;
+ grn_ctx_impl_mrb_ensure_init(ctx);
+ if (ctx->rc != GRN_SUCCESS) {
+ return GRN_ID_NIL;
+ }
+
if (!ctx->impl->mrb.state) {
ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "mruby support isn't enabled");
return GRN_ID_NIL;
}
- id = grn_hash_add(&grn_gctx, grn_plugins, filename, filename_size,
+ id = grn_hash_add(plugins_ctx, grn_plugins, filename, filename_size,
(void **)&plugin, NULL);
if (!id) {
return id;
}
- *plugin = GRN_GMALLOCN(grn_plugin, 1);
+ {
+ grn_ctx *ctx = plugins_ctx;
+ *plugin = GRN_MALLOCN(grn_plugin, 1);
+ }
if (!*plugin) {
- grn_hash_delete_by_id(&grn_gctx, grn_plugins, id, NULL);
+ grn_hash_delete_by_id(plugins_ctx, grn_plugins, id, NULL);
return GRN_ID_NIL;
}
@@ -296,6 +336,7 @@ grn_plugin_open_mrb(grn_ctx *ctx, const char *filename, size_t filename_size)
grn_id
grn_plugin_open(grn_ctx *ctx, const char *filename)
{
+ grn_ctx *plugins_ctx = &grn_plugins_ctx;
grn_id id = GRN_ID_NIL;
grn_dl dl;
grn_plugin **plugin = NULL;
@@ -304,7 +345,7 @@ grn_plugin_open(grn_ctx *ctx, const char *filename)
filename_size = GRN_PLUGIN_KEY_SIZE(filename);
CRITICAL_SECTION_ENTER(grn_plugins_lock);
- if ((id = grn_hash_get(&grn_gctx, grn_plugins, filename, filename_size,
+ if ((id = grn_hash_get(plugins_ctx, grn_plugins, filename, filename_size,
(void **)&plugin))) {
(*plugin)->refcount++;
goto exit;
@@ -324,18 +365,24 @@ grn_plugin_open(grn_ctx *ctx, const char *filename)
#endif /* GRN_WITH_MRUBY */
if ((dl = grn_dl_open(filename))) {
- if ((id = grn_hash_add(&grn_gctx, grn_plugins, filename, filename_size,
+ if ((id = grn_hash_add(plugins_ctx, grn_plugins, filename, filename_size,
(void **)&plugin, NULL))) {
- *plugin = GRN_GMALLOCN(grn_plugin, 1);
+ {
+ grn_ctx *ctx = plugins_ctx;
+ *plugin = GRN_MALLOCN(grn_plugin, 1);
+ }
if (*plugin) {
grn_memcpy((*plugin)->path, filename, filename_size);
if (grn_plugin_initialize(ctx, *plugin, dl, id, filename)) {
- GRN_GFREE(*plugin);
+ {
+ grn_ctx *ctx = plugins_ctx;
+ GRN_FREE(*plugin);
+ }
*plugin = NULL;
}
}
if (!*plugin) {
- grn_hash_delete_by_id(&grn_gctx, grn_plugins, id, NULL);
+ grn_hash_delete_by_id(plugins_ctx, grn_plugins, id, NULL);
if (grn_dl_close(dl)) {
/* Now, __FILE__ set in plugin is invalid. */
ctx->errline = 0;
@@ -343,7 +390,7 @@ grn_plugin_open(grn_ctx *ctx, const char *filename)
} else {
const char *label;
label = grn_dl_close_error_label();
- SERR(label);
+ SERR("%s", label);
}
id = GRN_ID_NIL;
} else {
@@ -353,13 +400,13 @@ grn_plugin_open(grn_ctx *ctx, const char *filename)
if (!grn_dl_close(dl)) {
const char *label;
label = grn_dl_close_error_label();
- SERR(label);
+ SERR("%s", label);
}
}
} else {
const char *label;
label = grn_dl_open_error_label();
- SERR(label);
+ SERR("%s", label);
}
exit:
@@ -371,6 +418,7 @@ exit:
grn_rc
grn_plugin_close(grn_ctx *ctx, grn_id id)
{
+ grn_ctx *plugins_ctx = &grn_plugins_ctx;
grn_rc rc;
grn_plugin *plugin;
@@ -379,7 +427,7 @@ grn_plugin_close(grn_ctx *ctx, grn_id id)
}
CRITICAL_SECTION_ENTER(grn_plugins_lock);
- if (!grn_hash_get_value(&grn_gctx, grn_plugins, id, &plugin)) {
+ if (!grn_hash_get_value(plugins_ctx, grn_plugins, id, &plugin)) {
rc = GRN_INVALID_ARGUMENT;
goto exit;
}
@@ -392,11 +440,14 @@ grn_plugin_close(grn_ctx *ctx, grn_id id)
if (!grn_dl_close(plugin->dl)) {
const char *label;
label = grn_dl_close_error_label();
- SERR(label);
+ SERR("%s", label);
}
}
- GRN_GFREE(plugin);
- rc = grn_hash_delete_by_id(&grn_gctx, grn_plugins, id, NULL);
+ {
+ grn_ctx *ctx = plugins_ctx;
+ GRN_FREE(plugin);
+ }
+ rc = grn_hash_delete_by_id(plugins_ctx, grn_plugins, id, NULL);
exit:
CRITICAL_SECTION_LEAVE(grn_plugins_lock);
@@ -415,7 +466,7 @@ grn_plugin_sym(grn_ctx *ctx, grn_id id, const char *symbol)
}
CRITICAL_SECTION_ENTER(grn_plugins_lock);
- if (!grn_hash_get_value(&grn_gctx, grn_plugins, id, &plugin)) {
+ if (!grn_hash_get_value(&grn_plugins_ctx, grn_plugins, id, &plugin)) {
func = NULL;
goto exit;
}
@@ -423,7 +474,7 @@ grn_plugin_sym(grn_ctx *ctx, grn_id id, const char *symbol)
if (!(func = grn_dl_sym(plugin->dl, symbol))) {
const char *label;
label = grn_dl_sym_error_label();
- SERR(label);
+ SERR("%s", label);
}
exit:
@@ -436,9 +487,14 @@ grn_rc
grn_plugins_init(void)
{
CRITICAL_SECTION_INIT(grn_plugins_lock);
- grn_plugins = grn_hash_create(&grn_gctx, NULL, PATH_MAX, sizeof(grn_plugin *),
+ grn_ctx_init(&grn_plugins_ctx, 0);
+ grn_plugins = grn_hash_create(&grn_plugins_ctx, NULL,
+ PATH_MAX, sizeof(grn_plugin *),
GRN_OBJ_KEY_VAR_SIZE);
- if (!grn_plugins) { return GRN_NO_MEMORY_AVAILABLE; }
+ if (!grn_plugins) {
+ grn_ctx_fin(&grn_plugins_ctx);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
return GRN_SUCCESS;
}
@@ -447,10 +503,11 @@ grn_plugins_fin(void)
{
grn_rc rc;
if (!grn_plugins) { return GRN_INVALID_ARGUMENT; }
- GRN_HASH_EACH(&grn_gctx, grn_plugins, id, NULL, NULL, NULL, {
- grn_plugin_close(&grn_gctx, id);
+ GRN_HASH_EACH(&grn_plugins_ctx, grn_plugins, id, NULL, NULL, NULL, {
+ grn_plugin_close(&grn_plugins_ctx, id);
});
- rc = grn_hash_close(&grn_gctx, grn_plugins);
+ rc = grn_hash_close(&grn_plugins_ctx, grn_plugins);
+ grn_ctx_fin(&grn_plugins_ctx);
CRITICAL_SECTION_FIN(grn_plugins_lock);
return rc;
}
@@ -492,24 +549,24 @@ grn_plugin_register_by_path(grn_ctx *ctx, const char *path)
}
#ifdef WIN32
-static char *win32_plugins_dir = NULL;
-static char win32_plugins_dir_buffer[PATH_MAX];
+static char *windows_plugins_dir = NULL;
+static char windows_plugins_dir_buffer[PATH_MAX];
static const char *
grn_plugin_get_default_system_plugins_dir(void)
{
- if (!win32_plugins_dir) {
+ if (!windows_plugins_dir) {
const char *base_dir;
const char *relative_path = GRN_RELATIVE_PLUGINS_DIR;
size_t base_dir_length;
- base_dir = grn_win32_base_dir();
+ base_dir = grn_windows_base_dir();
base_dir_length = strlen(base_dir);
- grn_strcpy(win32_plugins_dir_buffer, PATH_MAX, base_dir);
- grn_strcat(win32_plugins_dir_buffer, PATH_MAX, "/");
- grn_strcat(win32_plugins_dir_buffer, PATH_MAX, relative_path);
- win32_plugins_dir = win32_plugins_dir_buffer;
+ grn_strcpy(windows_plugins_dir_buffer, PATH_MAX, base_dir);
+ grn_strcat(windows_plugins_dir_buffer, PATH_MAX, "/");
+ grn_strcat(windows_plugins_dir_buffer, PATH_MAX, relative_path);
+ windows_plugins_dir = windows_plugins_dir_buffer;
}
- return win32_plugins_dir;
+ return windows_plugins_dir;
}
#else /* WIN32 */
@@ -554,11 +611,16 @@ grn_plugin_find_path_mrb(grn_ctx *ctx, const char *path, size_t path_len)
const char *mrb_suffix;
size_t mrb_path_len;
- mrb_suffix = grn_plugin_get_ruby_suffix();
+ grn_ctx_impl_mrb_ensure_init(ctx);
+ if (ctx->rc != GRN_SUCCESS) {
+ return NULL;
+ }
+
if (!ctx->impl->mrb.state) {
return NULL;
}
+ mrb_suffix = grn_plugin_get_ruby_suffix();
mrb_path_len = path_len + strlen(mrb_suffix);
if (mrb_path_len >= PATH_MAX) {
ERR(GRN_FILENAME_TOO_LONG,
@@ -675,7 +737,8 @@ grn_plugin_find_path(grn_ctx *ctx, const char *name)
}
path_len = strlen(path);
- found_path = grn_plugin_find_path_mrb(ctx, path, path_len);
+
+ found_path = grn_plugin_find_path_so(ctx, path, path_len);
if (found_path) {
goto exit;
}
@@ -683,7 +746,7 @@ grn_plugin_find_path(grn_ctx *ctx, const char *name)
goto exit;
}
- found_path = grn_plugin_find_path_so(ctx, path, path_len);
+ found_path = grn_plugin_find_path_libs_so(ctx, path, path_len);
if (found_path) {
goto exit;
}
@@ -691,7 +754,7 @@ grn_plugin_find_path(grn_ctx *ctx, const char *name)
goto exit;
}
- found_path = grn_plugin_find_path_libs_so(ctx, path, path_len);
+ found_path = grn_plugin_find_path_mrb(ctx, path, path_len);
if (found_path) {
goto exit;
}
@@ -767,7 +830,7 @@ grn_plugin_unregister_by_path(grn_ctx *ctx, const char *path)
GRN_API_ENTER;
CRITICAL_SECTION_ENTER(grn_plugins_lock);
- plugin_id = grn_hash_get(&grn_gctx, grn_plugins,
+ plugin_id = grn_hash_get(&grn_plugins_ctx, grn_plugins,
path, GRN_PLUGIN_KEY_SIZE(path),
NULL);
CRITICAL_SECTION_LEAVE(grn_plugins_lock);
@@ -831,16 +894,37 @@ grn_plugin_ensure_registered(grn_ctx *ctx, grn_obj *proc)
{
#ifdef GRN_WITH_MRUBY
grn_id plugin_id;
- const char *plugin_path;
- uint32_t key_size;
- grn_plugin *plugin;
- int value_size;
+ grn_plugin *plugin = NULL;
- if (!ctx->impl->mrb.state) {
+ if (!(proc->header.flags & GRN_OBJ_CUSTOM_NAME)) {
return;
}
- if (!(proc->header.flags & GRN_OBJ_CUSTOM_NAME)) {
+ plugin_id = DB_OBJ(proc)->range;
+ CRITICAL_SECTION_ENTER(grn_plugins_lock);
+ {
+ const char *value;
+ value = grn_hash_get_value_(&grn_plugins_ctx, grn_plugins, plugin_id, NULL);
+ if (value) {
+ plugin = *((grn_plugin **)value);
+ }
+ }
+ CRITICAL_SECTION_LEAVE(grn_plugins_lock);
+
+ if (!plugin) {
+ return;
+ }
+
+ if (plugin->dl) {
+ return;
+ }
+
+ grn_ctx_impl_mrb_ensure_init(ctx);
+ if (ctx->rc != GRN_SUCCESS) {
+ return;
+ }
+
+ if (!ctx->impl->mrb.state) {
return;
}
@@ -855,26 +939,132 @@ grn_plugin_ensure_registered(grn_ctx *ctx, grn_obj *proc)
}
}
- plugin_id = DB_OBJ(proc)->range;
- CRITICAL_SECTION_ENTER(grn_plugins_lock);
- plugin_path = _grn_hash_key(&grn_gctx, grn_plugins, plugin_id, &key_size);
- if (plugin_path) {
- value_size = grn_hash_get_value(&grn_gctx, grn_plugins, plugin_id, &plugin);
+ ctx->impl->plugin_path = plugin->path;
+ grn_plugin_call_register_mrb(ctx, plugin_id, plugin);
+ ctx->impl->plugin_path = NULL;
+#endif /* GRN_WITH_MRUBY */
+}
+
+grn_rc
+grn_plugin_get_names(grn_ctx *ctx, grn_obj *names)
+{
+ grn_hash *processed_paths;
+ const char *system_plugins_dir;
+ const char *native_plugin_suffix;
+ const char *ruby_plugin_suffix;
+ grn_bool is_close_opened_object_mode = GRN_FALSE;
+
+ GRN_API_ENTER;
+
+ if (ctx->rc) {
+ GRN_API_RETURN(ctx->rc);
}
- CRITICAL_SECTION_LEAVE(grn_plugins_lock);
- if (!plugin_path) {
- return;
+ if (grn_thread_get_limit() == 1) {
+ is_close_opened_object_mode = GRN_TRUE;
}
- if (plugin->dl) {
- return;
+ processed_paths = grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE, 0,
+ GRN_OBJ_TABLE_HASH_KEY |
+ GRN_OBJ_KEY_VAR_SIZE);
+ if (!processed_paths) {
+ GRN_API_RETURN(ctx->rc);
}
- ctx->impl->plugin_path = plugin_path;
- grn_plugin_call_register_mrb(ctx, plugin_id, plugin);
- ctx->impl->plugin_path = NULL;
-#endif /* GRN_WITH_MRUBY */
+ system_plugins_dir = grn_plugin_get_system_plugins_dir();
+ native_plugin_suffix = grn_plugin_get_suffix();
+ ruby_plugin_suffix = grn_plugin_get_ruby_suffix();
+
+ GRN_TABLE_EACH_BEGIN_FLAGS(ctx, grn_ctx_db(ctx), cursor, id,
+ GRN_CURSOR_BY_ID | GRN_CURSOR_ASCENDING) {
+ void *name;
+ int name_size;
+ grn_obj *object;
+ const char *path;
+ grn_id processed_path_id;
+
+ if (grn_id_is_builtin(ctx, id)) {
+ continue;
+ }
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+ if (grn_obj_name_is_column(ctx, name, name_size)) {
+ continue;
+ }
+
+ if (is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ object = grn_ctx_at(ctx, id);
+ if (!object) {
+ ERRCLR(ctx);
+ goto next_loop;
+ }
+
+ if (!grn_obj_is_proc(ctx, object)) {
+ goto next_loop;
+ }
+
+ path = grn_obj_path(ctx, object);
+ if (!path) {
+ goto next_loop;
+ }
+
+ processed_path_id = grn_hash_get(ctx, processed_paths,
+ path, strlen(path),
+ NULL);
+ if (processed_path_id != GRN_ID_NIL) {
+ goto next_loop;
+ }
+
+ grn_hash_add(ctx, processed_paths,
+ path, strlen(path),
+ NULL, NULL);
+
+ {
+ const char *relative_path;
+ const char *libs_path = "/.libs/";
+ const char *start_libs;
+ char name[PATH_MAX];
+
+ name[0] = '\0';
+ if (strncmp(path, system_plugins_dir, strlen(system_plugins_dir)) == 0) {
+ relative_path = path + strlen(system_plugins_dir);
+ } else {
+ relative_path = path;
+ }
+ start_libs = strstr(relative_path, libs_path);
+ if (start_libs) {
+ grn_strncat(name, PATH_MAX, relative_path, start_libs - relative_path);
+ grn_strcat(name, PATH_MAX, "/");
+ grn_strcat(name, PATH_MAX, start_libs + strlen(libs_path));
+ } else {
+ grn_strcat(name, PATH_MAX, relative_path);
+ }
+ if (strlen(name) > strlen(native_plugin_suffix) &&
+ strcmp(name + strlen(name) - strlen(native_plugin_suffix),
+ native_plugin_suffix) == 0) {
+ name[strlen(name) - strlen(native_plugin_suffix)] = '\0';
+ } else if (strlen(name) > strlen(ruby_plugin_suffix) &&
+ strcmp(name + strlen(name) - strlen(ruby_plugin_suffix),
+ ruby_plugin_suffix) == 0) {
+ name[strlen(name) - strlen(ruby_plugin_suffix)] = '\0';
+ }
+ grn_vector_add_element(ctx, names,
+ name, strlen(name),
+ 0, GRN_DB_TEXT);
+ }
+
+ next_loop :
+ if (is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+
+ grn_hash_close(ctx, processed_paths);
+
+ GRN_API_RETURN(ctx->rc);
}
void *
@@ -885,6 +1075,13 @@ grn_plugin_malloc(grn_ctx *ctx, size_t size, const char *file, int line,
}
void *
+grn_plugin_calloc(grn_ctx *ctx, size_t size, const char *file, int line,
+ const char *func)
+{
+ return grn_calloc(ctx, size, file, line, func);
+}
+
+void *
grn_plugin_realloc(grn_ctx *ctx, void *ptr, size_t size,
const char *file, int line, const char *func)
{
@@ -898,33 +1095,52 @@ grn_plugin_free(grn_ctx *ctx, void *ptr, const char *file, int line,
grn_free(ctx, ptr, file, line, func);
}
-/*
- grn_plugin_ctx_log() is a clone of grn_ctx_log() in ctx.c. The only
- difference is that grn_plugin_ctx_log() uses va_list instead of `...'.
- */
-static void
-grn_plugin_ctx_log(grn_ctx *ctx, const char *format, va_list ap)
-{
- vsnprintf(ctx->errbuf, GRN_CTX_MSGSIZE, format, ap);
-}
-
void
grn_plugin_set_error(grn_ctx *ctx, grn_log_level level, grn_rc error_code,
const char *file, int line, const char *func,
const char *format, ...)
{
+ char old_error_message[GRN_CTX_MSGSIZE];
+
ctx->errlvl = level;
ctx->rc = error_code;
ctx->errfile = file;
ctx->errline = line;
ctx->errfunc = func;
+ grn_strcpy(old_error_message, GRN_CTX_MSGSIZE, ctx->errbuf);
+
{
va_list ap;
va_start(ap, format);
- grn_plugin_ctx_log(ctx, format, ap);
+ grn_ctx_logv(ctx, format, ap);
va_end(ap);
}
+
+ if (grn_ctx_impl_should_log(ctx)) {
+ grn_ctx_impl_set_current_error_message(ctx);
+ if (grn_logger_pass(ctx, level)) {
+ char new_error_message[GRN_CTX_MSGSIZE];
+ grn_strcpy(new_error_message, GRN_CTX_MSGSIZE, ctx->errbuf);
+ grn_strcpy(ctx->errbuf, GRN_CTX_MSGSIZE, old_error_message);
+ {
+ va_list ap;
+ va_start(ap, format);
+ grn_logger_putv(ctx, level, file, line, func, format, ap);
+ va_end(ap);
+ }
+ grn_strcpy(ctx->errbuf, GRN_CTX_MSGSIZE, new_error_message);
+ }
+ if (level <= GRN_LOG_ERROR) {
+ grn_plugin_logtrace(ctx, level);
+ }
+ }
+}
+
+void
+grn_plugin_clear_error(grn_ctx *ctx)
+{
+ ERRCLR(ctx);
}
void
@@ -937,6 +1153,7 @@ void
grn_plugin_logtrace(grn_ctx *ctx, grn_log_level level)
{
if (level <= GRN_LOG_ERROR) {
+ grn_plugin_backtrace(ctx);
LOGTRACE(ctx, level);
}
}
@@ -995,7 +1212,7 @@ grn_plugin_mutex_unlock(grn_ctx *ctx, grn_plugin_mutex *mutex)
grn_obj *
grn_plugin_proc_alloc(grn_ctx *ctx, grn_user_data *user_data,
- grn_id domain, grn_obj_flags flags)
+ grn_id domain, unsigned char flags)
{
return grn_proc_alloc(ctx, user_data, domain, flags);
}
@@ -1014,6 +1231,58 @@ grn_plugin_proc_get_var(grn_ctx *ctx, grn_user_data *user_data,
return grn_proc_get_var(ctx, user_data, name, name_size);
}
+grn_bool
+grn_plugin_proc_get_var_bool(grn_ctx *ctx,
+ grn_user_data *user_data,
+ const char *name,
+ int name_size,
+ grn_bool default_value)
+{
+ grn_obj *var;
+
+ var = grn_plugin_proc_get_var(ctx, user_data, name, name_size);
+ return grn_proc_option_value_bool(ctx, var, default_value);
+}
+
+int32_t
+grn_plugin_proc_get_var_int32(grn_ctx *ctx,
+ grn_user_data *user_data,
+ const char *name,
+ int name_size,
+ int32_t default_value)
+{
+ grn_obj *var;
+
+ var = grn_plugin_proc_get_var(ctx, user_data, name, name_size);
+ return grn_proc_option_value_int32(ctx, var, default_value);
+}
+
+const char *
+grn_plugin_proc_get_var_string(grn_ctx *ctx,
+ grn_user_data *user_data,
+ const char *name,
+ int name_size,
+ size_t *size)
+{
+ grn_obj *var;
+
+ var = grn_plugin_proc_get_var(ctx, user_data, name, name_size);
+ return grn_proc_option_value_string(ctx, var, size);
+}
+
+grn_content_type
+grn_plugin_proc_get_var_content_type(grn_ctx *ctx,
+ grn_user_data *user_data,
+ const char *name,
+ int name_size,
+ grn_content_type default_value)
+{
+ grn_obj *var;
+
+ var = grn_plugin_proc_get_var(ctx, user_data, name, name_size);
+ return grn_proc_option_value_content_type(ctx, var, default_value);
+}
+
grn_obj *
grn_plugin_proc_get_var_by_offset(grn_ctx *ctx, grn_user_data *user_data,
unsigned int offset)
@@ -1021,11 +1290,26 @@ grn_plugin_proc_get_var_by_offset(grn_ctx *ctx, grn_user_data *user_data,
return grn_proc_get_var_by_offset(ctx, user_data, offset);
}
+grn_obj *
+grn_plugin_proc_get_caller(grn_ctx *ctx, grn_user_data *user_data)
+{
+ grn_obj *caller = NULL;
+ GRN_API_ENTER;
+ grn_proc_get_info(ctx, user_data, NULL, NULL, &caller);
+ GRN_API_RETURN(caller);
+}
+
const char *
grn_plugin_win32_base_dir(void)
{
+ return grn_plugin_windows_base_dir();
+}
+
+const char *
+grn_plugin_windows_base_dir(void)
+{
#ifdef WIN32
- return grn_win32_base_dir();
+ return grn_windows_base_dir();
#else /* WIN32 */
return NULL;
#endif /* WIN32 */
diff --git a/storage/mroonga/vendor/groonga/lib/proc.c b/storage/mroonga/vendor/groonga/lib/proc.c
index ba858de6f2a..e21769f3f19 100644
--- a/storage/mroonga/vendor/groonga/lib/proc.c
+++ b/storage/mroonga/vendor/groonga/lib/proc.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -17,18 +17,16 @@
*/
#include "grn_proc.h"
+#include "grn_ctx.h"
#include "grn_ii.h"
#include "grn_db.h"
#include "grn_util.h"
#include "grn_output.h"
#include "grn_pat.h"
#include "grn_geo.h"
-#include "grn_token_cursor.h"
#include "grn_expr.h"
-
-#ifdef GRN_WITH_EGN
-# include "grn_egn.h"
-#endif /* GRN_WITH_EGN */
+#include "grn_cache.h"
+#include "grn_load.h"
#include <string.h>
#include <stdlib.h>
@@ -44,25 +42,11 @@
#define O_NOFOLLOW 0
#endif
-typedef grn_rc (*grn_substitute_term_func) (grn_ctx *ctx,
- const char *term,
- unsigned int term_len,
- grn_obj *substituted_term,
- grn_user_data *user_data);
-typedef struct {
- grn_obj *table;
- grn_obj *column;
-} grn_substitute_term_by_column_data;
-
/**** globals for procs ****/
const char *grn_document_root = NULL;
#define VAR GRN_PROC_GET_VAR_BY_OFFSET
-#define GRN_SELECT_INTERNAL_VAR_CONDITION "$condition"
-#define GRN_SELECT_INTERNAL_VAR_MATCH_COLUMNS "$match_columns"
-
-
static double grn_between_too_many_index_match_ratio = 0.01;
static double grn_in_values_too_many_index_match_ratio = 0.01;
@@ -115,7 +99,7 @@ grn_bulk_put_from_file(grn_ctx *ctx, grn_obj *bulk, const char *path)
break;
#endif /* WIN32 */
default :
- ERR(GRN_UNKNOWN_ERROR, "GRN_OPEN() failed(errno: %d): <%s>", errno, path);
+ ERRNO_ERR("failed to open file: <%s>", path);
break;
}
return 0;
@@ -144,1264 +128,121 @@ exit :
# undef stat
#endif /* stat */
-/**** query expander ****/
-
-static grn_rc
-substitute_term_by_func(grn_ctx *ctx, const char *term, unsigned int term_len,
- grn_obj *expanded_term, grn_user_data *user_data)
-{
- grn_rc rc;
- grn_obj *expander = user_data->ptr;
- grn_obj grn_term;
- grn_obj *caller;
- grn_obj *rc_object;
- int nargs = 0;
-
- GRN_TEXT_INIT(&grn_term, GRN_OBJ_DO_SHALLOW_COPY);
- GRN_TEXT_SET(ctx, &grn_term, term, term_len);
- grn_ctx_push(ctx, &grn_term);
- nargs++;
- grn_ctx_push(ctx, expanded_term);
- nargs++;
-
- caller = grn_expr_create(ctx, NULL, 0);
- rc = grn_proc_call(ctx, expander, nargs, caller);
- GRN_OBJ_FIN(ctx, &grn_term);
- rc_object = grn_ctx_pop(ctx);
- rc = GRN_INT32_VALUE(rc_object);
- grn_obj_unlink(ctx, caller);
-
- return rc;
-}
-
-static grn_rc
-substitute_term_by_column(grn_ctx *ctx, const char *term, unsigned int term_len,
- grn_obj *expanded_term, grn_user_data *user_data)
-{
- grn_rc rc = GRN_END_OF_DATA;
- grn_id id;
- grn_substitute_term_by_column_data *data = user_data->ptr;
- grn_obj *table, *column;
-
- table = data->table;
- column = data->column;
- if ((id = grn_table_get(ctx, table, term, term_len))) {
- if ((column->header.type == GRN_COLUMN_VAR_SIZE) &&
- ((column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR)) {
- unsigned int i, n;
- grn_obj values;
- GRN_TEXT_INIT(&values, GRN_OBJ_VECTOR);
- grn_obj_get_value(ctx, column, id, &values);
- n = grn_vector_size(ctx, &values);
- if (n > 1) { GRN_TEXT_PUTC(ctx, expanded_term, '('); }
- for (i = 0; i < n; i++) {
- const char *value;
- unsigned int length;
- if (i > 0) {
- GRN_TEXT_PUTS(ctx, expanded_term, " OR ");
- }
- if (n > 1) { GRN_TEXT_PUTC(ctx, expanded_term, '('); }
- length = grn_vector_get_element(ctx, &values, i, &value, NULL, NULL);
- GRN_TEXT_PUT(ctx, expanded_term, value, length);
- if (n > 1) { GRN_TEXT_PUTC(ctx, expanded_term, ')'); }
- }
- if (n > 1) { GRN_TEXT_PUTC(ctx, expanded_term, ')'); }
- GRN_OBJ_FIN(ctx, &values);
- } else {
- grn_obj_get_value(ctx, column, id, expanded_term);
- }
- rc = GRN_SUCCESS;
- }
- return rc;
-}
-
-static grn_rc
-substitute_terms(grn_ctx *ctx, const char *query, unsigned int query_len,
- grn_expr_flags flags,
- grn_obj *expanded_query,
- grn_substitute_term_func substitute_term_func,
- grn_user_data *user_data)
-{
- grn_obj buf;
- unsigned int len;
- const char *start, *cur = query, *query_end = query + (size_t)query_len;
- GRN_TEXT_INIT(&buf, 0);
- for (;;) {
- while (cur < query_end && grn_isspace(cur, ctx->encoding)) {
- if (!(len = grn_charlen(ctx, cur, query_end))) { goto exit; }
- GRN_TEXT_PUT(ctx, expanded_query, cur, len);
- cur += len;
- }
- if (query_end <= cur) { break; }
- switch (*cur) {
- case '\0' :
- goto exit;
- break;
- case GRN_QUERY_AND :
- case GRN_QUERY_ADJ_INC :
- case GRN_QUERY_ADJ_DEC :
- case GRN_QUERY_ADJ_NEG :
- case GRN_QUERY_AND_NOT :
- case GRN_QUERY_PARENL :
- case GRN_QUERY_PARENR :
- case GRN_QUERY_PREFIX :
- GRN_TEXT_PUTC(ctx, expanded_query, *cur);
- cur++;
- break;
- case GRN_QUERY_QUOTEL :
- GRN_BULK_REWIND(&buf);
- for (start = cur++; cur < query_end; cur += len) {
- if (!(len = grn_charlen(ctx, cur, query_end))) {
- goto exit;
- } else if (len == 1) {
- if (*cur == GRN_QUERY_QUOTER) {
- cur++;
- break;
- } else if (cur + 1 < query_end && *cur == GRN_QUERY_ESCAPE) {
- cur++;
- len = grn_charlen(ctx, cur, query_end);
- }
- }
- GRN_TEXT_PUT(ctx, &buf, cur, len);
- }
- if (substitute_term_func(ctx, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf),
- expanded_query, user_data)) {
- GRN_TEXT_PUT(ctx, expanded_query, start, cur - start);
- }
- break;
- case 'O' :
- if (cur + 2 <= query_end && cur[1] == 'R' &&
- (cur + 2 == query_end || grn_isspace(cur + 2, ctx->encoding))) {
- GRN_TEXT_PUT(ctx, expanded_query, cur, 2);
- cur += 2;
- break;
- }
- /* fallthru */
- default :
- for (start = cur; cur < query_end; cur += len) {
- if (!(len = grn_charlen(ctx, cur, query_end))) {
- goto exit;
- } else if (grn_isspace(cur, ctx->encoding)) {
- break;
- } else if (len == 1) {
- if (*cur == GRN_QUERY_PARENL ||
- *cur == GRN_QUERY_PARENR ||
- *cur == GRN_QUERY_PREFIX) {
- break;
- } else if (flags & GRN_EXPR_ALLOW_COLUMN && *cur == GRN_QUERY_COLUMN) {
- if (cur + 1 < query_end) {
- switch (cur[1]) {
- case '!' :
- case '@' :
- case '^' :
- case '$' :
- cur += 2;
- break;
- case '=' :
- cur += (flags & GRN_EXPR_ALLOW_UPDATE) ? 2 : 1;
- break;
- case '<' :
- case '>' :
- cur += (cur + 2 < query_end && cur[2] == '=') ? 3 : 2;
- break;
- default :
- cur += 1;
- break;
- }
- } else {
- cur += 1;
- }
- GRN_TEXT_PUT(ctx, expanded_query, start, cur - start);
- start = cur;
- break;
- }
- }
- }
- if (start < cur) {
- if (substitute_term_func(ctx, start, cur - start,
- expanded_query, user_data)) {
- GRN_TEXT_PUT(ctx, expanded_query, start, cur - start);
- }
- }
- break;
- }
- }
-exit :
- GRN_OBJ_FIN(ctx, &buf);
- return GRN_SUCCESS;
-}
-
-static grn_rc
-expand_query(grn_ctx *ctx, const char *query, unsigned int query_len,
- grn_expr_flags flags,
- const char *query_expander_name,
- unsigned int query_expander_name_len,
- grn_obj *expanded_query)
-{
- grn_rc rc = GRN_SUCCESS;
- grn_obj *query_expander;
-
- query_expander = grn_ctx_get(ctx,
- query_expander_name, query_expander_name_len);
- if (!query_expander) {
- ERR(GRN_INVALID_ARGUMENT,
- "nonexistent query expansion column: <%.*s>",
- query_expander_name_len, query_expander_name);
- return GRN_INVALID_ARGUMENT;
- }
-
- switch (query_expander->header.type) {
- case GRN_PROC :
- if (((grn_proc *)query_expander)->type == GRN_PROC_FUNCTION) {
- grn_user_data user_data;
- user_data.ptr = query_expander;
- substitute_terms(ctx, query, query_len, flags, expanded_query,
- substitute_term_by_func, &user_data);
- } else {
- rc = GRN_INVALID_ARGUMENT;
- ERR(rc,
- "[expand-query] must be function proc: <%.*s>",
- query_expander_name_len, query_expander_name);
- }
- break;
- case GRN_COLUMN_FIX_SIZE :
- case GRN_COLUMN_VAR_SIZE :
- {
- grn_obj *query_expansion_table;
- query_expansion_table = grn_column_table(ctx, query_expander);
- if (query_expansion_table) {
- grn_user_data user_data;
- grn_substitute_term_by_column_data data;
- user_data.ptr = &data;
- data.table = query_expansion_table;
- data.column = query_expander;
- substitute_terms(ctx, query, query_len, flags, expanded_query,
- substitute_term_by_column, &user_data);
- grn_obj_unlink(ctx, query_expansion_table);
- } else {
- rc = GRN_INVALID_ARGUMENT;
- ERR(rc,
- "[expand-query] failed to get table of column: <%.*s>",
- query_expander_name_len, query_expander_name);
- }
- }
- break;
- default :
- rc = GRN_INVALID_ARGUMENT;
- {
- grn_obj type_name;
- GRN_TEXT_INIT(&type_name, 0);
- grn_inspect_type(ctx, &type_name, query_expander->header.type);
- ERR(rc,
- "[expand-query] must be a column or function proc: <%.*s>(%.*s)",
- query_expander_name_len, query_expander_name,
- (int)GRN_TEXT_LEN(&type_name), GRN_TEXT_VALUE(&type_name));
- GRN_OBJ_FIN(ctx, &type_name);
- }
- break;
- }
- grn_obj_unlink(ctx, query_expander);
-
- return rc;
-}
-
-
/**** procs ****/
-#define DEFAULT_LIMIT 10
-#define DEFAULT_OUTPUT_COLUMNS "_id, _key, *"
-#define DEFAULT_DRILLDOWN_LIMIT 10
-#define DEFAULT_DRILLDOWN_OUTPUT_COLUMNS "_key, _nsubrecs"
-#define DUMP_COLUMNS "_id, _key, _value, *"
-
-static grn_expr_flags
-grn_parse_query_flags(grn_ctx *ctx, const char *query_flags,
- unsigned int query_flags_len)
-{
- grn_expr_flags flags = 0;
- const char *query_flags_end = query_flags + query_flags_len;
-
- while (query_flags < query_flags_end) {
- if (*query_flags == '|' || *query_flags == ' ') {
- query_flags += 1;
- continue;
- }
-
-#define CHECK_EXPR_FLAG(name)\
- if (((query_flags_end - query_flags) >= (sizeof(#name) - 1)) &&\
- (!memcmp(query_flags, #name, sizeof(#name) - 1))) {\
- flags |= GRN_EXPR_ ## name;\
- query_flags += sizeof(#name) - 1;\
- continue;\
- }
-
- CHECK_EXPR_FLAG(ALLOW_PRAGMA);
- CHECK_EXPR_FLAG(ALLOW_COLUMN);
- CHECK_EXPR_FLAG(ALLOW_UPDATE);
- CHECK_EXPR_FLAG(ALLOW_LEADING_NOT);
-
-#define GRN_EXPR_NONE 0
- CHECK_EXPR_FLAG(NONE);
-#undef GNR_EXPR_NONE
-
- ERR(GRN_INVALID_ARGUMENT, "invalid query flag: <%.*s>",
- (int)(query_flags_end - query_flags), query_flags);
- return 0;
-#undef CHECK_EXPR_FLAG
- }
-
- return flags;
-}
-
-static int
-grn_select_apply_adjuster_ensure_factor(grn_ctx *ctx, grn_obj *factor_object)
-{
- if (!factor_object) {
- return 1;
- } else if (factor_object->header.domain == GRN_DB_INT32) {
- return GRN_INT32_VALUE(factor_object);
- } else {
- grn_rc rc;
- grn_obj int32_object;
- int factor;
- GRN_INT32_INIT(&int32_object, 0);
- rc = grn_obj_cast(ctx, factor_object, &int32_object, GRN_FALSE);
- if (rc == GRN_SUCCESS) {
- factor = GRN_INT32_VALUE(&int32_object);
- } else {
- /* TODO: Log or return error? */
- factor = 1;
- }
- GRN_OBJ_FIN(ctx, &int32_object);
- return factor;
- }
-}
-
-static void
-grn_select_apply_adjuster_adjust(grn_ctx *ctx, grn_obj *table, grn_obj *res,
- grn_obj *column, grn_obj *value,
- grn_obj *factor)
-{
- grn_obj *index;
- unsigned int n_indexes;
- int factor_value;
-
- n_indexes = grn_column_index(ctx, column, GRN_OP_MATCH, &index, 1, NULL);
- if (n_indexes == 0) {
- char column_name[GRN_TABLE_MAX_KEY_SIZE];
- int column_name_size;
- column_name_size = grn_obj_name(ctx, column,
- column_name, GRN_TABLE_MAX_KEY_SIZE);
- ERR(GRN_INVALID_ARGUMENT,
- "adjuster requires index column for the target column: <%.*s>",
- column_name_size, column_name);
- return;
- }
-
- factor_value = grn_select_apply_adjuster_ensure_factor(ctx, factor);
-
- {
- grn_search_optarg options;
- memset(&options, 0, sizeof(grn_search_optarg));
-
- options.mode = GRN_OP_EXACT;
- options.similarity_threshold = 0;
- options.max_interval = 0;
- options.weight_vector = NULL;
- options.vector_size = factor_value;
- options.proc = NULL;
- options.max_size = 0;
- options.scorer = NULL;
-
- grn_obj_search(ctx, index, value, res, GRN_OP_ADJUST, &options);
- }
-}
-
-static void
-grn_select_apply_adjuster(grn_ctx *ctx, grn_obj *table, grn_obj *res,
- grn_obj *adjuster)
-{
- grn_expr *expr = (grn_expr *)adjuster;
- grn_expr_code *code, *code_end;
-
- code = expr->codes;
- code_end = expr->codes + expr->codes_curr;
- while (code < code_end) {
- grn_obj *column, *value, *factor;
-
- if (code->op == GRN_OP_PLUS) {
- code++;
- continue;
- }
-
- column = code->value;
- code++;
- value = code->value;
- code++;
- code++; /* op == GRN_OP_MATCH */
- if ((code_end - code) >= 2 && code[1].op == GRN_OP_STAR) {
- factor = code->value;
- code++;
- code++; /* op == GRN_OP_STAR */
- } else {
- factor = NULL;
- }
- grn_select_apply_adjuster_adjust(ctx, table, res, column, value, factor);
- }
-}
-
-static void
-grn_select_output_columns(grn_ctx *ctx, grn_obj *res,
- int n_hits, int offset, int limit,
- const char *columns, int columns_len,
- grn_obj *condition)
-{
- grn_rc rc;
- grn_obj_format format;
-
- GRN_OBJ_FORMAT_INIT(&format, n_hits, offset, limit, offset);
- format.flags =
- GRN_OBJ_FORMAT_WITH_COLUMN_NAMES|
- GRN_OBJ_FORMAT_XML_ELEMENT_RESULTSET;
- rc = grn_output_format_set_columns(ctx, &format, res, columns, columns_len);
- /* TODO: check rc */
- if (format.expression) {
- grn_obj *condition_ptr;
- condition_ptr =
- grn_expr_get_or_add_var(ctx, format.expression,
- GRN_SELECT_INTERNAL_VAR_CONDITION,
- strlen(GRN_SELECT_INTERNAL_VAR_CONDITION));
- GRN_PTR_INIT(condition_ptr, 0, GRN_DB_OBJECT);
- GRN_PTR_SET(ctx, condition_ptr, condition);
- }
- GRN_OUTPUT_OBJ(res, &format);
- GRN_OBJ_FORMAT_FIN(ctx, &format);
-}
-
-typedef struct {
- const char *label;
- unsigned int label_len;
- const char *keys;
- unsigned int keys_len;
- const char *sortby;
- unsigned int sortby_len;
- const char *output_columns;
- unsigned int output_columns_len;
- int offset;
- int limit;
- grn_table_group_flags calc_types;
- const char *calc_target_name;
- unsigned int calc_target_name_len;
-} drilldown_info;
-
-static grn_table_group_flags
-grn_parse_table_group_calc_types(grn_ctx *ctx,
- const char *calc_types,
- unsigned int calc_types_len)
-{
- grn_table_group_flags flags = 0;
- const char *calc_types_end = calc_types + calc_types_len;
-
- while (calc_types < calc_types_end) {
- if (*calc_types == ',' || *calc_types == ' ') {
- calc_types += 1;
- continue;
- }
-
-#define CHECK_TABLE_GROUP_CALC_TYPE(name)\
- if (((calc_types_end - calc_types) >= (sizeof(#name) - 1)) &&\
- (!memcmp(calc_types, #name, sizeof(#name) - 1))) {\
- flags |= GRN_TABLE_GROUP_CALC_ ## name;\
- calc_types += sizeof(#name) - 1;\
- continue;\
- }
-
- CHECK_TABLE_GROUP_CALC_TYPE(COUNT);
- CHECK_TABLE_GROUP_CALC_TYPE(MAX);
- CHECK_TABLE_GROUP_CALC_TYPE(MIN);
- CHECK_TABLE_GROUP_CALC_TYPE(SUM);
- CHECK_TABLE_GROUP_CALC_TYPE(AVG);
-
-#define GRN_TABLE_GROUP_CALC_NONE 0
- CHECK_TABLE_GROUP_CALC_TYPE(NONE);
-#undef GRN_TABLE_GROUP_CALC_NONE
-
- ERR(GRN_INVALID_ARGUMENT, "invalid table group calc type: <%.*s>",
- (int)(calc_types_end - calc_types), calc_types);
- return 0;
-#undef CHECK_TABLE_GROUP_CALC_TYPE
- }
-
- return flags;
-}
-
-static void
-drilldown_info_fill(grn_ctx *ctx,
- drilldown_info *drilldown,
- grn_obj *keys,
- grn_obj *sortby,
- grn_obj *output_columns,
- grn_obj *offset,
- grn_obj *limit,
- grn_obj *calc_types,
- grn_obj *calc_target)
+static grn_obj *
+proc_load(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
- if (keys) {
- drilldown->keys = GRN_TEXT_VALUE(keys);
- drilldown->keys_len = GRN_TEXT_LEN(keys);
+ grn_load_input input;
+
+ input.type = grn_plugin_proc_get_var_content_type(ctx,
+ user_data,
+ "input_type",
+ -1,
+ GRN_CONTENT_JSON);
+#define INIT_STRING_ARGUMENT(member_name, arg_name) \
+ input.member_name.value = \
+ grn_plugin_proc_get_var_string(ctx, \
+ user_data, \
+ arg_name, \
+ -1, \
+ &(input.member_name.length))
+
+ INIT_STRING_ARGUMENT(table, "table");
+ INIT_STRING_ARGUMENT(columns, "columns");
+ INIT_STRING_ARGUMENT(values, "values");
+ INIT_STRING_ARGUMENT(if_exists, "ifexists");
+ INIT_STRING_ARGUMENT(each, "each");
+
+#undef INIT_STRING_ARGUMENT
+
+ input.output_ids = grn_plugin_proc_get_var_bool(ctx,
+ user_data,
+ "output_ids", -1,
+ GRN_FALSE);
+ input.output_errors = grn_plugin_proc_get_var_bool(ctx,
+ user_data,
+ "output_errors", -1,
+ GRN_FALSE);
+ input.emit_level = 1;
+
+ grn_load_internal(ctx, &input);
+ if (ctx->rc == GRN_CANCEL) {
+ ctx->impl->loader.stat = GRN_LOADER_END;
+ ctx->impl->loader.rc = GRN_SUCCESS;
+ }
+ if (ctx->impl->loader.stat != GRN_LOADER_END &&
+ !(ctx->impl->command.flags & GRN_CTX_TAIL)) {
+ grn_obj *command = grn_proc_get_info(ctx, user_data, NULL, NULL, NULL);
+ grn_ctx_set_keep_command(ctx, command);
} else {
- drilldown->keys = NULL;
- drilldown->keys_len = 0;
- }
-
- if (sortby) {
- drilldown->sortby = GRN_TEXT_VALUE(sortby);
- drilldown->sortby_len = GRN_TEXT_LEN(sortby);
- } else {
- drilldown->sortby = NULL;
- drilldown->sortby_len = 0;
- }
-
- if (output_columns) {
- drilldown->output_columns = GRN_TEXT_VALUE(output_columns);
- drilldown->output_columns_len = GRN_TEXT_LEN(output_columns);
- } else {
- drilldown->output_columns = NULL;
- drilldown->output_columns_len = 0;
- }
- if (!drilldown->output_columns_len) {
- drilldown->output_columns = DEFAULT_DRILLDOWN_OUTPUT_COLUMNS;
- drilldown->output_columns_len = strlen(DEFAULT_DRILLDOWN_OUTPUT_COLUMNS);
- }
-
- if (offset && GRN_TEXT_LEN(offset)) {
- drilldown->offset =
- grn_atoi(GRN_TEXT_VALUE(offset), GRN_BULK_CURR(offset), NULL);
- } else {
- drilldown->offset = 0;
- }
-
- if (limit && GRN_TEXT_LEN(limit)) {
- drilldown->limit =
- grn_atoi(GRN_TEXT_VALUE(limit), GRN_BULK_CURR(limit), NULL);
- } else {
- drilldown->limit = DEFAULT_DRILLDOWN_LIMIT;
- }
-
- if (calc_types && GRN_TEXT_LEN(calc_types)) {
- drilldown->calc_types =
- grn_parse_table_group_calc_types(ctx,
- GRN_TEXT_VALUE(calc_types),
- GRN_TEXT_LEN(calc_types));
- } else {
- drilldown->calc_types = 0;
- }
-
- if (calc_target && GRN_TEXT_LEN(calc_target)) {
- drilldown->calc_target_name = GRN_TEXT_VALUE(calc_target);
- drilldown->calc_target_name_len = GRN_TEXT_LEN(calc_target);
- } else {
- drilldown->calc_target_name = NULL;
- drilldown->calc_target_name_len = 0;
- }
-}
-
-static void
-grn_select_drilldown(grn_ctx *ctx, grn_obj *table,
- grn_table_sort_key *keys, uint32_t n_keys,
- drilldown_info *drilldown)
-{
- uint32_t i;
- for (i = 0; i < n_keys; i++) {
- grn_table_group_result g = {NULL, 0, 0, 1, GRN_TABLE_GROUP_CALC_COUNT, 0, 0 ,0};
- uint32_t n_hits;
- int offset;
- int limit;
-
- if (drilldown->calc_target_name) {
- g.calc_target = grn_obj_column(ctx, table,
- drilldown->calc_target_name,
- drilldown->calc_target_name_len);
- }
- if (g.calc_target) {
- g.flags |= drilldown->calc_types;
- }
-
- grn_table_group(ctx, table, &keys[i], 1, &g, 1);
- if (ctx->rc != GRN_SUCCESS) {
- break;
- }
- n_hits = grn_table_size(ctx, g.table);
-
- offset = drilldown->offset;
- limit = drilldown->limit;
- grn_normalize_offset_and_limit(ctx, n_hits, &offset, &limit);
-
- if (drilldown->sortby_len) {
- grn_table_sort_key *sort_keys;
- uint32_t n_sort_keys;
- sort_keys = grn_table_sort_key_from_str(ctx,
- drilldown->sortby,
- drilldown->sortby_len,
- g.table, &n_sort_keys);
- if (sort_keys) {
- grn_obj *sorted;
- sorted = grn_table_create(ctx, NULL, 0, NULL, GRN_OBJ_TABLE_NO_KEY,
- NULL, g.table);
- if (sorted) {
- grn_obj_format format;
- grn_table_sort(ctx, g.table, offset, limit,
- sorted, sort_keys, n_sort_keys);
- GRN_OBJ_FORMAT_INIT(&format, n_hits, 0, limit, offset);
- format.flags =
- GRN_OBJ_FORMAT_WITH_COLUMN_NAMES|
- GRN_OBJ_FORMAT_XML_ELEMENT_NAVIGATIONENTRY;
- grn_obj_columns(ctx, sorted,
- drilldown->output_columns,
- drilldown->output_columns_len,
- &format.columns);
- GRN_OUTPUT_OBJ(sorted, &format);
- GRN_OBJ_FORMAT_FIN(ctx, &format);
- grn_obj_unlink(ctx, sorted);
- }
- grn_table_sort_key_close(ctx, sort_keys, n_sort_keys);
- }
- } else {
- grn_obj_format format;
- GRN_OBJ_FORMAT_INIT(&format, n_hits, offset, limit, offset);
- format.flags =
- GRN_OBJ_FORMAT_WITH_COLUMN_NAMES|
- GRN_OBJ_FORMAT_XML_ELEMENT_NAVIGATIONENTRY;
- grn_obj_columns(ctx, g.table,
- drilldown->output_columns,
- drilldown->output_columns_len,
- &format.columns);
- GRN_OUTPUT_OBJ(g.table, &format);
- GRN_OBJ_FORMAT_FIN(ctx, &format);
- }
- grn_obj_unlink(ctx, g.table);
- GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
- ":", "drilldown(%d)", n_hits);
- }
-}
-
-static void
-grn_select_drilldowns(grn_ctx *ctx, grn_obj *table,
- drilldown_info *drilldowns, unsigned int n_drilldowns,
- grn_obj *condition)
-{
- unsigned int i;
-
- /* TODO: Remove invalid key drilldowns from the count. */
- GRN_OUTPUT_MAP_OPEN("DRILLDOWNS", n_drilldowns);
- for (i = 0; i < n_drilldowns; i++) {
- drilldown_info *drilldown = &(drilldowns[i]);
- grn_table_sort_key *keys = NULL;
- unsigned int n_keys;
- uint32_t n_hits;
- int offset;
- int limit;
- grn_table_group_result result = {
- NULL, 0, 0, 1, GRN_TABLE_GROUP_CALC_COUNT, 0, 0, NULL
- };
-
- keys = grn_table_sort_key_from_str(ctx,
- drilldown->keys,
- drilldown->keys_len,
- table, &n_keys);
- if (!keys) {
- continue;
- }
-
- GRN_OUTPUT_STR(drilldown->label, drilldown->label_len);
-
- result.key_begin = 0;
- result.key_end = n_keys - 1;
- if (n_keys > 1) {
- result.max_n_subrecs = 1;
- }
- if (drilldown->calc_target_name) {
- result.calc_target = grn_obj_column(ctx, table,
- drilldown->calc_target_name,
- drilldown->calc_target_name_len);
- }
- if (result.calc_target) {
- result.flags |= drilldown->calc_types;
- }
-
- grn_table_group(ctx, table, keys, n_keys, &result, 1);
- n_hits = grn_table_size(ctx, result.table);
-
- offset = drilldown->offset;
- limit = drilldown->limit;
- grn_normalize_offset_and_limit(ctx, n_hits, &offset, &limit);
-
- if (drilldown->sortby_len) {
- grn_table_sort_key *sort_keys;
- uint32_t n_sort_keys;
- sort_keys = grn_table_sort_key_from_str(ctx,
- drilldown->sortby,
- drilldown->sortby_len,
- result.table, &n_sort_keys);
- if (sort_keys) {
- grn_obj *sorted;
- sorted = grn_table_create(ctx, NULL, 0, NULL, GRN_OBJ_TABLE_NO_KEY,
- NULL, result.table);
- if (sorted) {
- grn_table_sort(ctx, result.table, offset, limit,
- sorted, sort_keys, n_sort_keys);
- grn_select_output_columns(ctx, sorted, n_hits, 0, limit,
- drilldown->output_columns,
- drilldown->output_columns_len,
- condition);
- grn_obj_unlink(ctx, sorted);
- }
- grn_table_sort_key_close(ctx, sort_keys, n_sort_keys);
- }
- } else {
- grn_select_output_columns(ctx, result.table, n_hits, offset, limit,
- drilldown->output_columns,
- drilldown->output_columns_len,
- condition);
- }
-
- grn_table_sort_key_close(ctx, keys, n_keys);
- if (result.calc_target) {
- grn_obj_unlink(ctx, result.calc_target);
- }
- grn_obj_unlink(ctx, result.table);
-
- GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
- ":", "drilldown(%d)[%.*s]", n_hits,
- (int)(drilldown->label_len), drilldown->label);
- }
- GRN_OUTPUT_MAP_CLOSE();
-}
-
-static grn_rc
-grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
- const char *match_columns, unsigned int match_columns_len,
- const char *query, unsigned int query_len,
- const char *filter, unsigned int filter_len,
- const char *scorer, unsigned int scorer_len,
- const char *sortby, unsigned int sortby_len,
- const char *output_columns, unsigned int output_columns_len,
- int offset, int limit,
- drilldown_info *drilldowns,
- unsigned int n_drilldowns,
- const char *cache, unsigned int cache_len,
- const char *match_escalation_threshold, unsigned int match_escalation_threshold_len,
- const char *query_expander, unsigned int query_expander_len,
- const char *query_flags, unsigned int query_flags_len,
- const char *adjuster, unsigned int adjuster_len)
-{
- uint32_t nkeys, nhits;
- uint16_t cacheable = 1, taintable = 0;
- grn_table_sort_key *keys;
- grn_obj *outbuf = ctx->impl->outbuf;
- grn_content_type output_type = ctx->impl->output_type;
- grn_obj *table_, *match_columns_ = NULL, *cond = NULL, *scorer_, *res = NULL, *sorted;
- char cache_key[GRN_CACHE_MAX_KEY_SIZE];
- uint32_t cache_key_size;
- long long int threshold, original_threshold = 0;
- grn_cache *cache_obj = grn_cache_current_get(ctx);
-
- {
- const char *query_end = query + query_len;
- int space_len;
- while (query < query_end) {
- space_len = grn_isspace(query, ctx->encoding);
- if (space_len == 0) {
- break;
- }
- query += space_len;
- query_len -= space_len;
- }
- }
-
- cache_key_size = table_len + 1 + match_columns_len + 1 + query_len + 1 +
- filter_len + 1 + scorer_len + 1 + sortby_len + 1 + output_columns_len + 1 +
- match_escalation_threshold_len + 1 +
- query_expander_len + 1 + query_flags_len + 1 + adjuster_len + 1 +
- sizeof(grn_content_type) + sizeof(int) * 2;
- {
- unsigned int i;
- for (i = 0; i < n_drilldowns; i++) {
- drilldown_info *drilldown = &(drilldowns[i]);
- cache_key_size +=
- drilldown->keys_len + 1 +
- drilldown->sortby_len + 1 +
- drilldown->output_columns_len + 1 +
- sizeof(int) * 2;
- }
- }
- if (cache_key_size <= GRN_CACHE_MAX_KEY_SIZE) {
- grn_obj *cache_value;
- char *cp = cache_key;
- grn_memcpy(cp, table, table_len);
- cp += table_len; *cp++ = '\0';
- grn_memcpy(cp, match_columns, match_columns_len);
- cp += match_columns_len; *cp++ = '\0';
- grn_memcpy(cp, query, query_len);
- cp += query_len; *cp++ = '\0';
- grn_memcpy(cp, filter, filter_len);
- cp += filter_len; *cp++ = '\0';
- grn_memcpy(cp, scorer, scorer_len);
- cp += scorer_len; *cp++ = '\0';
- grn_memcpy(cp, sortby, sortby_len);
- cp += sortby_len; *cp++ = '\0';
- grn_memcpy(cp, output_columns, output_columns_len);
- cp += output_columns_len; *cp++ = '\0';
- {
- unsigned int i;
- for (i = 0; i < n_drilldowns; i++) {
- drilldown_info *drilldown = &(drilldowns[i]);
- grn_memcpy(cp, drilldown->keys, drilldown->keys_len);
- cp += drilldown->keys_len; *cp++ = '\0';
- grn_memcpy(cp, drilldown->sortby, drilldown->sortby_len);
- cp += drilldown->sortby_len; *cp++ = '\0';
- grn_memcpy(cp, drilldown->output_columns, drilldown->output_columns_len);
- cp += drilldown->output_columns_len; *cp++ = '\0';
- }
- }
- grn_memcpy(cp, match_escalation_threshold, match_escalation_threshold_len);
- cp += match_escalation_threshold_len; *cp++ = '\0';
- grn_memcpy(cp, query_expander, query_expander_len);
- cp += query_expander_len; *cp++ = '\0';
- grn_memcpy(cp, query_flags, query_flags_len);
- cp += query_flags_len; *cp++ = '\0';
- grn_memcpy(cp, adjuster, adjuster_len);
- cp += adjuster_len; *cp++ = '\0';
- grn_memcpy(cp, &output_type, sizeof(grn_content_type));
- cp += sizeof(grn_content_type);
- grn_memcpy(cp, &offset, sizeof(int));
- cp += sizeof(int);
- grn_memcpy(cp, &limit, sizeof(int));
- cp += sizeof(int);
- {
- unsigned int i;
- for (i = 0; i < n_drilldowns; i++) {
- drilldown_info *drilldown = &(drilldowns[i]);
- grn_memcpy(cp, &(drilldown->offset), sizeof(int));
- cp += sizeof(int);
- grn_memcpy(cp, &(drilldown->limit), sizeof(int));
- cp += sizeof(int);
- }
- }
- cache_value = grn_cache_fetch(ctx, cache_obj, cache_key, cache_key_size);
- if (cache_value) {
- GRN_TEXT_PUT(ctx, outbuf,
- GRN_TEXT_VALUE(cache_value),
- GRN_TEXT_LEN(cache_value));
- grn_cache_unref(ctx, cache_obj, cache_key, cache_key_size);
- GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_CACHE,
- ":", "cache(%" GRN_FMT_LLD ")",
- (long long int)GRN_TEXT_LEN(cache_value));
- return ctx->rc;
- }
- }
- if (match_escalation_threshold_len) {
- const char *end, *rest;
- original_threshold = grn_ctx_get_match_escalation_threshold(ctx);
- end = match_escalation_threshold + match_escalation_threshold_len;
- threshold = grn_atoll(match_escalation_threshold, end, &rest);
- if (end == rest) {
- grn_ctx_set_match_escalation_threshold(ctx, threshold);
- }
- }
- if ((table_ = grn_ctx_get(ctx, table, table_len))) {
- // match_columns_ = grn_obj_column(ctx, table_, match_columns, match_columns_len);
-#ifdef GRN_WITH_EGN
- if (filter_len && (filter[0] == '?') &&
- (ctx->impl->output_type == GRN_CONTENT_JSON)) {
- ctx->rc = grn_egn_select(ctx, table_, filter + 1, filter_len - 1,
- output_columns, output_columns_len,
- offset, limit);
- if (!ctx->rc && cacheable && cache_key_size <= GRN_CACHE_MAX_KEY_SIZE &&
- (!cache || cache_len != 2 || cache[0] != 'n' || cache[1] != 'o')) {
- grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf);
- }
- goto exit;
- }
-#endif /* GRN_WITH_EGN */
- if (query_len || filter_len) {
- grn_obj *v;
- GRN_EXPR_CREATE_FOR_QUERY(ctx, table_, cond, v);
- if (cond) {
- if (match_columns_len) {
- GRN_EXPR_CREATE_FOR_QUERY(ctx, table_, match_columns_, v);
- if (match_columns_) {
- grn_expr_parse(ctx, match_columns_, match_columns, match_columns_len,
- NULL, GRN_OP_MATCH, GRN_OP_AND,
- GRN_EXPR_SYNTAX_SCRIPT);
- if (ctx->rc) {
- goto exit;
- }
- } else {
- /* todo */
- }
- }
- if (query_len) {
- grn_expr_flags flags;
- grn_obj query_expander_buf;
- flags = GRN_EXPR_SYNTAX_QUERY;
- if (query_flags_len) {
- flags |= grn_parse_query_flags(ctx, query_flags, query_flags_len);
- if (ctx->rc) {
- goto exit;
- }
- } else {
- flags |= GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN;
- }
- GRN_TEXT_INIT(&query_expander_buf, 0);
- if (query_expander_len) {
- if (expand_query(ctx, query, query_len, flags,
- query_expander, query_expander_len,
- &query_expander_buf) == GRN_SUCCESS) {
- query = GRN_TEXT_VALUE(&query_expander_buf);
- query_len = GRN_TEXT_LEN(&query_expander_buf);
- } else {
- GRN_OBJ_FIN(ctx, &query_expander_buf);
- goto exit;
- }
- }
- grn_expr_parse(ctx, cond, query, query_len,
- match_columns_, GRN_OP_MATCH, GRN_OP_AND, flags);
- GRN_OBJ_FIN(ctx, &query_expander_buf);
- if (!ctx->rc && filter_len) {
- grn_expr_parse(ctx, cond, filter, filter_len,
- match_columns_, GRN_OP_MATCH, GRN_OP_AND,
- GRN_EXPR_SYNTAX_SCRIPT);
- if (!ctx->rc) { grn_expr_append_op(ctx, cond, GRN_OP_AND, 2); }
- }
- } else {
- grn_expr_parse(ctx, cond, filter, filter_len,
- match_columns_, GRN_OP_MATCH, GRN_OP_AND,
- GRN_EXPR_SYNTAX_SCRIPT);
- }
- cacheable *= ((grn_expr *)cond)->cacheable;
- taintable += ((grn_expr *)cond)->taintable;
- /*
- grn_obj strbuf;
- GRN_TEXT_INIT(&strbuf, 0);
- grn_expr_inspect(ctx, &strbuf, cond);
- GRN_TEXT_PUTC(ctx, &strbuf, '\0');
- GRN_LOG(ctx, GRN_LOG_NOTICE, "query=(%s)", GRN_TEXT_VALUE(&strbuf));
- GRN_OBJ_FIN(ctx, &strbuf);
- */
- if (!ctx->rc) { res = grn_table_select(ctx, table_, cond, NULL, GRN_OP_OR); }
- } else {
- /* todo */
- ERRCLR(ctx);
+ if (ctx->impl->loader.rc != GRN_SUCCESS) {
+ ctx->rc = ctx->impl->loader.rc;
+ grn_strcpy(ctx->errbuf, GRN_CTX_MSGSIZE, ctx->impl->loader.errbuf);
+ }
+ if (grn_ctx_get_command_version(ctx) >= GRN_COMMAND_VERSION_3) {
+ int n_elements = 1;
+ if (ctx->impl->loader.output_ids) {
+ n_elements++;
}
- } else {
- res = table_;
- }
- nhits = res ? grn_table_size(ctx, res) : 0;
- GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
- ":", "select(%d)", nhits);
-
- if (res) {
- uint32_t ngkeys;
- grn_table_sort_key *gkeys = NULL;
- int result_size = 1;
- if (!ctx->rc && n_drilldowns > 0) {
- if (n_drilldowns == 1 && !drilldowns[0].label) {
- gkeys = grn_table_sort_key_from_str(ctx,
- drilldowns[0].keys,
- drilldowns[0].keys_len,
- res, &ngkeys);
- if (gkeys) {
- result_size += ngkeys;
- }
- } else {
- result_size += 1;
- }
+ if (ctx->impl->loader.output_errors) {
+ n_elements++;
}
-
- if (adjuster && adjuster_len) {
- grn_obj *adjuster_;
- grn_obj *v;
- GRN_EXPR_CREATE_FOR_QUERY(ctx, table_, adjuster_, v);
- if (adjuster_ && v) {
- grn_rc rc;
- rc = grn_expr_parse(ctx, adjuster_, adjuster, adjuster_len, NULL,
- GRN_OP_MATCH, GRN_OP_ADJUST,
- GRN_EXPR_SYNTAX_ADJUSTER);
- if (rc) {
- grn_obj_unlink(ctx, adjuster_);
- goto exit;
- }
- cacheable *= ((grn_expr *)adjuster_)->cacheable;
- taintable += ((grn_expr *)adjuster_)->taintable;
- grn_select_apply_adjuster(ctx, table_, res, adjuster_);
- grn_obj_unlink(ctx, adjuster_);
+ GRN_OUTPUT_MAP_OPEN("result", n_elements);
+ GRN_OUTPUT_CSTR("n_loaded_records");
+ GRN_OUTPUT_INT64(ctx->impl->loader.nrecords);
+ if (ctx->impl->loader.output_ids) {
+ grn_obj *ids = &(ctx->impl->loader.ids);
+ int i, n_ids;
+
+ GRN_OUTPUT_CSTR("loaded_ids");
+ n_ids = GRN_BULK_VSIZE(ids) / sizeof(uint32_t);
+ GRN_OUTPUT_ARRAY_OPEN("loaded_ids", n_ids);
+ for (i = 0; i < n_ids; i++) {
+ GRN_OUTPUT_UINT64(GRN_UINT32_VALUE_AT(ids, i));
}
- GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
- ":", "adjust(%d)", nhits);
+ GRN_OUTPUT_ARRAY_CLOSE();
}
-
- if (scorer && scorer_len) {
- grn_obj *v;
- GRN_EXPR_CREATE_FOR_QUERY(ctx, res, scorer_, v);
- if (scorer_ && v) {
- grn_table_cursor *tc;
- grn_expr_parse(ctx, scorer_, scorer, scorer_len, NULL, GRN_OP_MATCH, GRN_OP_AND,
- GRN_EXPR_SYNTAX_SCRIPT|GRN_EXPR_ALLOW_UPDATE);
- cacheable *= ((grn_expr *)scorer_)->cacheable;
- taintable += ((grn_expr *)scorer_)->taintable;
- if ((tc = grn_table_cursor_open(ctx, res, NULL, 0, NULL, 0, 0, -1, 0))) {
- grn_id id;
- while ((id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
- GRN_RECORD_SET(ctx, v, id);
- grn_expr_exec(ctx, scorer_, 0);
- if (ctx->rc) {
- break;
- }
- }
- grn_table_cursor_close(ctx, tc);
+ if (ctx->impl->loader.output_errors) {
+ grn_obj *return_codes = &(ctx->impl->loader.return_codes);
+ grn_obj *error_messages = &(ctx->impl->loader.error_messages);
+ int i, n;
+
+ GRN_OUTPUT_CSTR("errors");
+ n = GRN_BULK_VSIZE(return_codes) / sizeof(int32_t);
+ GRN_OUTPUT_ARRAY_OPEN("errors", n);
+ for (i = 0; i < n; i++) {
+ const char *message;
+ unsigned int message_size;
+
+ message_size = grn_vector_get_element(ctx,
+ error_messages,
+ i,
+ &message,
+ NULL,
+ NULL);
+
+ GRN_OUTPUT_MAP_OPEN("error", 2);
+ GRN_OUTPUT_CSTR("return_code");
+ GRN_OUTPUT_INT64(GRN_INT32_VALUE_AT(return_codes, i));
+ GRN_OUTPUT_CSTR("message");
+ if (message_size == 0) {
+ GRN_OUTPUT_NULL();
+ } else {
+ GRN_OUTPUT_STR(message, message_size);
}
- grn_obj_unlink(ctx, scorer_);
- }
- GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
- ":", "score(%d)", nhits);
- }
-
- GRN_OUTPUT_ARRAY_OPEN("RESULT", result_size);
-
- grn_normalize_offset_and_limit(ctx, nhits, &offset, &limit);
-
- if (sortby_len &&
- (keys = grn_table_sort_key_from_str(ctx, sortby, sortby_len, res, &nkeys))) {
- if ((sorted = grn_table_create(ctx, NULL, 0, NULL,
- GRN_OBJ_TABLE_NO_KEY, NULL, res))) {
- grn_table_sort(ctx, res, offset, limit, sorted, keys, nkeys);
- GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
- ":", "sort(%d)", limit);
- grn_select_output_columns(ctx, sorted, nhits, 0, limit,
- output_columns, output_columns_len, cond);
- grn_obj_unlink(ctx, sorted);
- }
- grn_table_sort_key_close(ctx, keys, nkeys);
- } else {
- if (!ctx->rc) {
- grn_select_output_columns(ctx, res, nhits, offset, limit,
- output_columns, output_columns_len, cond);
- }
- }
- GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
- ":", "output(%d)", limit);
- if (!ctx->rc) {
- if (gkeys) {
- drilldown_info *drilldown = &(drilldowns[0]);
- grn_select_drilldown(ctx, res, gkeys, ngkeys, drilldown);
- } else if (n_drilldowns > 0) {
- grn_select_drilldowns(ctx, res, drilldowns, n_drilldowns, cond);
+ GRN_OUTPUT_MAP_CLOSE();
}
+ GRN_OUTPUT_ARRAY_CLOSE();
}
- if (gkeys) {
- grn_table_sort_key_close(ctx, gkeys, ngkeys);
- }
- if (res != table_) { grn_obj_unlink(ctx, res); }
+ GRN_OUTPUT_MAP_CLOSE();
} else {
- GRN_OUTPUT_ARRAY_OPEN("RESULT", 0);
- }
- GRN_OUTPUT_ARRAY_CLOSE();
- if (!ctx->rc && cacheable && cache_key_size <= GRN_CACHE_MAX_KEY_SIZE
- && (!cache || cache_len != 2 || *cache != 'n' || *(cache + 1) != 'o')) {
- grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf);
- }
- if (taintable) { grn_db_touch(ctx, DB_OBJ(table_)->db); }
- grn_obj_unlink(ctx, table_);
- } else {
- ERR(GRN_INVALID_ARGUMENT, "invalid table name: <%.*s>", table_len, table);
- }
-exit :
- if (match_escalation_threshold_len) {
- grn_ctx_set_match_escalation_threshold(ctx, original_threshold);
- }
- if (match_columns_) {
- grn_obj_unlink(ctx, match_columns_);
- }
- if (cond) {
- grn_obj_unlink(ctx, cond);
- }
- /* GRN_LOG(ctx, GRN_LOG_NONE, "%d", ctx->seqno); */
- return ctx->rc;
-}
-
-static void
-proc_select_find_all_drilldown_labels(grn_ctx *ctx, grn_user_data *user_data,
- grn_obj *labels)
-{
- grn_obj *vars = GRN_PROC_GET_VARS();
- grn_table_cursor *cursor;
- cursor = grn_table_cursor_open(ctx, vars, NULL, 0, NULL, 0, 0, -1, 0);
- if (cursor) {
- const char *prefix = "drilldown[";
- int prefix_len = strlen(prefix);
- const char *suffix = "].keys";
- int suffix_len = strlen(suffix);
- while (grn_table_cursor_next(ctx, cursor)) {
- void *key;
- char *name;
- int name_len;
- name_len = grn_table_cursor_get_key(ctx, cursor, &key);
- name = key;
- if (name_len < (prefix_len + 1 + suffix_len)) {
- continue;
- }
- if (strncmp(prefix, name, prefix_len) != 0) {
- continue;
- }
- if (strncmp(suffix, name + name_len - suffix_len, suffix_len) != 0) {
- continue;
- }
- grn_vector_add_element(ctx, labels,
- name + prefix_len,
- name_len - prefix_len - suffix_len,
- 0, GRN_ID_NIL);
- }
- grn_table_cursor_close(ctx, cursor);
- }
-}
-
-static grn_obj *
-proc_select(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
-#define MAX_N_DRILLDOWNS 10
- int offset = GRN_TEXT_LEN(VAR(7))
- ? grn_atoi(GRN_TEXT_VALUE(VAR(7)), GRN_BULK_CURR(VAR(7)), NULL)
- : 0;
- int limit = GRN_TEXT_LEN(VAR(8))
- ? grn_atoi(GRN_TEXT_VALUE(VAR(8)), GRN_BULK_CURR(VAR(8)), NULL)
- : DEFAULT_LIMIT;
- const char *output_columns = GRN_TEXT_VALUE(VAR(6));
- uint32_t output_columns_len = GRN_TEXT_LEN(VAR(6));
- drilldown_info drilldowns[MAX_N_DRILLDOWNS];
- unsigned int n_drilldowns = 0;
- grn_obj drilldown_labels;
- grn_obj *query_expansion = VAR(16);
- grn_obj *query_expander = VAR(18);
- grn_obj *adjuster = VAR(19);
-
- if (GRN_TEXT_LEN(query_expander) == 0 && GRN_TEXT_LEN(query_expansion) > 0) {
- query_expander = query_expansion;
- }
-
- if (!output_columns_len) {
- output_columns = DEFAULT_OUTPUT_COLUMNS;
- output_columns_len = strlen(DEFAULT_OUTPUT_COLUMNS);
- }
-
- GRN_TEXT_INIT(&drilldown_labels, GRN_OBJ_VECTOR);
- if (GRN_TEXT_LEN(VAR(9))) {
- drilldown_info *drilldown = &(drilldowns[0]);
- drilldown->label = NULL;
- drilldown->label_len = 0;
- drilldown_info_fill(ctx, drilldown,
- VAR(9), VAR(10), VAR(11), VAR(12), VAR(13),
- VAR(20), VAR(21));
- n_drilldowns++;
- } else {
- unsigned int i;
- proc_select_find_all_drilldown_labels(ctx, user_data, &drilldown_labels);
- n_drilldowns = grn_vector_size(ctx, &drilldown_labels);
- for (i = 0; i < n_drilldowns; i++) {
- drilldown_info *drilldown = &(drilldowns[i]);
- const char *label;
- int label_len;
- char key_name[GRN_TABLE_MAX_KEY_SIZE];
- grn_obj *keys;
- grn_obj *sortby;
- grn_obj *output_columns;
- grn_obj *offset;
- grn_obj *limit;
- grn_obj *calc_types;
- grn_obj *calc_target;
-
- label_len = grn_vector_get_element(ctx, &drilldown_labels, i,
- &label, NULL, NULL);
- drilldown->label = label;
- drilldown->label_len = label_len;
-
-#define GET_VAR(name)\
- grn_snprintf(key_name, \
- GRN_TABLE_MAX_KEY_SIZE, \
- GRN_TABLE_MAX_KEY_SIZE, \
- "drilldown[%.*s]." # name, label_len, label); \
- name = GRN_PROC_GET_VAR(key_name);
-
- GET_VAR(keys);
- GET_VAR(sortby);
- GET_VAR(output_columns);
- GET_VAR(offset);
- GET_VAR(limit);
- GET_VAR(calc_types);
- GET_VAR(calc_target);
-
-#undef GET_VAR
-
- drilldown_info_fill(ctx, drilldown,
- keys, sortby, output_columns, offset, limit,
- calc_types, calc_target);
+ GRN_OUTPUT_INT64(ctx->impl->loader.nrecords);
}
- }
- if (grn_select(ctx, GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)),
- GRN_TEXT_VALUE(VAR(1)), GRN_TEXT_LEN(VAR(1)),
- GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)),
- GRN_TEXT_VALUE(VAR(3)), GRN_TEXT_LEN(VAR(3)),
- GRN_TEXT_VALUE(VAR(4)), GRN_TEXT_LEN(VAR(4)),
- GRN_TEXT_VALUE(VAR(5)), GRN_TEXT_LEN(VAR(5)),
- output_columns, output_columns_len,
- offset, limit,
- drilldowns, n_drilldowns,
- GRN_TEXT_VALUE(VAR(14)), GRN_TEXT_LEN(VAR(14)),
- GRN_TEXT_VALUE(VAR(15)), GRN_TEXT_LEN(VAR(15)),
- GRN_TEXT_VALUE(query_expander), GRN_TEXT_LEN(query_expander),
- GRN_TEXT_VALUE(VAR(17)), GRN_TEXT_LEN(VAR(17)),
- GRN_TEXT_VALUE(adjuster), GRN_TEXT_LEN(adjuster))) {
- }
- GRN_OBJ_FIN(ctx, &drilldown_labels);
-#undef MAX_N_DRILLDOWNS
-
- return NULL;
-}
-
-static grn_obj *
-proc_define_selector(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- uint32_t i, nvars;
- grn_expr_var *vars;
- grn_proc_get_info(ctx, user_data, &vars, &nvars, NULL);
- for (i = 1; i < nvars; i++) {
- GRN_TEXT_SET(ctx, &((vars + i)->value),
- GRN_TEXT_VALUE(VAR(i)), GRN_TEXT_LEN(VAR(i)));
- }
- grn_proc_create(ctx,
- GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)),
- GRN_PROC_COMMAND, proc_select, NULL, NULL, nvars - 1, vars + 1);
- GRN_OUTPUT_BOOL(!ctx->rc);
- return NULL;
-}
-
-static grn_obj *
-proc_load(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_load(ctx, grn_get_ctype(VAR(4)),
- GRN_TEXT_VALUE(VAR(1)), GRN_TEXT_LEN(VAR(1)),
- GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)),
- GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)),
- GRN_TEXT_VALUE(VAR(3)), GRN_TEXT_LEN(VAR(3)),
- GRN_TEXT_VALUE(VAR(5)), GRN_TEXT_LEN(VAR(5)));
- if (ctx->impl->loader.stat != GRN_LOADER_END) {
- grn_ctx_set_next_expr(ctx, grn_proc_get_info(ctx, user_data, NULL, NULL, NULL));
- } else {
- GRN_OUTPUT_INT64(ctx->impl->loader.nrecords);
if (ctx->impl->loader.table) {
grn_db_touch(ctx, DB_OBJ(ctx->impl->loader.table)->db);
}
- /* maybe necessary : grn_ctx_loader_clear(ctx); */
+ grn_ctx_loader_clear(ctx);
}
return NULL;
}
@@ -1416,11 +257,13 @@ proc_status(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
grn_timeval_now(ctx, &now);
cache = grn_cache_current_get(ctx);
grn_cache_get_statistics(ctx, cache, &statistics);
- GRN_OUTPUT_MAP_OPEN("RESULT", 9);
+ GRN_OUTPUT_MAP_OPEN("RESULT", 10);
GRN_OUTPUT_CSTR("alloc_count");
GRN_OUTPUT_INT32(grn_alloc_count());
GRN_OUTPUT_CSTR("starttime");
GRN_OUTPUT_INT32(grn_starttime.tv_sec);
+ GRN_OUTPUT_CSTR("start_time");
+ GRN_OUTPUT_INT32(grn_starttime.tv_sec);
GRN_OUTPUT_CSTR("uptime");
GRN_OUTPUT_INT32(now.tv_sec - grn_starttime.tv_sec);
GRN_OUTPUT_CSTR("version");
@@ -1442,674 +285,18 @@ proc_status(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
GRN_OUTPUT_CSTR("max_command_version");
GRN_OUTPUT_INT32(GRN_COMMAND_VERSION_MAX);
GRN_OUTPUT_MAP_CLOSE();
- return NULL;
-}
-
-static grn_obj_flags
-grn_parse_table_create_flags(grn_ctx *ctx, const char *nptr, const char *end)
-{
- grn_obj_flags flags = 0;
- while (nptr < end) {
- if (*nptr == '|' || *nptr == ' ') {
- nptr += 1;
- continue;
- }
- if (!memcmp(nptr, "TABLE_HASH_KEY", 14)) {
- flags |= GRN_OBJ_TABLE_HASH_KEY;
- nptr += 14;
- } else if (!memcmp(nptr, "TABLE_PAT_KEY", 13)) {
- flags |= GRN_OBJ_TABLE_PAT_KEY;
- nptr += 13;
- } else if (!memcmp(nptr, "TABLE_DAT_KEY", 13)) {
- flags |= GRN_OBJ_TABLE_DAT_KEY;
- nptr += 13;
- } else if (!memcmp(nptr, "TABLE_NO_KEY", 12)) {
- flags |= GRN_OBJ_TABLE_NO_KEY;
- nptr += 12;
- } else if (!memcmp(nptr, "KEY_NORMALIZE", 13)) {
- flags |= GRN_OBJ_KEY_NORMALIZE;
- nptr += 13;
- } else if (!memcmp(nptr, "KEY_WITH_SIS", 12)) {
- flags |= GRN_OBJ_KEY_WITH_SIS;
- nptr += 12;
- } else {
- ERR(GRN_INVALID_ARGUMENT, "invalid flags option: %.*s",
- (int)(end - nptr), nptr);
- return 0;
- }
- }
- return flags;
-}
-
-static grn_obj_flags
-grn_parse_column_create_flags(grn_ctx *ctx, const char *nptr, const char *end)
-{
- grn_obj_flags flags = 0;
- while (nptr < end) {
- if (*nptr == '|' || *nptr == ' ') {
- nptr += 1;
- continue;
- }
- if (!memcmp(nptr, "COLUMN_SCALAR", 13)) {
- flags |= GRN_OBJ_COLUMN_SCALAR;
- nptr += 13;
- } else if (!memcmp(nptr, "COLUMN_VECTOR", 13)) {
- flags |= GRN_OBJ_COLUMN_VECTOR;
- nptr += 13;
- } else if (!memcmp(nptr, "COLUMN_INDEX", 12)) {
- flags |= GRN_OBJ_COLUMN_INDEX;
- nptr += 12;
- } else if (!memcmp(nptr, "COMPRESS_ZLIB", 13)) {
- flags |= GRN_OBJ_COMPRESS_ZLIB;
- nptr += 13;
- } else if (!memcmp(nptr, "COMPRESS_LZ4", 12)) {
- flags |= GRN_OBJ_COMPRESS_LZ4;
- nptr += 12;
- } else if (!memcmp(nptr, "WITH_SECTION", 12)) {
- flags |= GRN_OBJ_WITH_SECTION;
- nptr += 12;
- } else if (!memcmp(nptr, "WITH_WEIGHT", 11)) {
- flags |= GRN_OBJ_WITH_WEIGHT;
- nptr += 11;
- } else if (!memcmp(nptr, "WITH_POSITION", 13)) {
- flags |= GRN_OBJ_WITH_POSITION;
- nptr += 13;
- } else if (!memcmp(nptr, "RING_BUFFER", 11)) {
- flags |= GRN_OBJ_RING_BUFFER;
- nptr += 11;
- } else {
- ERR(GRN_INVALID_ARGUMENT, "invalid flags option: %.*s",
- (int)(end - nptr), nptr);
- return 0;
- }
- }
- return flags;
-}
-
-static void
-grn_table_create_flags_to_text(grn_ctx *ctx, grn_obj *buf, grn_obj_flags flags)
-{
- GRN_BULK_REWIND(buf);
- switch (flags & GRN_OBJ_TABLE_TYPE_MASK) {
- case GRN_OBJ_TABLE_HASH_KEY:
- GRN_TEXT_PUTS(ctx, buf, "TABLE_HASH_KEY");
- break;
- case GRN_OBJ_TABLE_PAT_KEY:
- GRN_TEXT_PUTS(ctx, buf, "TABLE_PAT_KEY");
- break;
- case GRN_OBJ_TABLE_DAT_KEY:
- GRN_TEXT_PUTS(ctx, buf, "TABLE_DAT_KEY");
- break;
- case GRN_OBJ_TABLE_NO_KEY:
- GRN_TEXT_PUTS(ctx, buf, "TABLE_NO_KEY");
- break;
- }
- if (flags & GRN_OBJ_KEY_WITH_SIS) {
- GRN_TEXT_PUTS(ctx, buf, "|KEY_WITH_SIS");
- }
- if (flags & GRN_OBJ_KEY_NORMALIZE) {
- GRN_TEXT_PUTS(ctx, buf, "|KEY_NORMALIZE");
- }
- if (flags & GRN_OBJ_PERSISTENT) {
- GRN_TEXT_PUTS(ctx, buf, "|PERSISTENT");
- }
-}
-
-static void
-grn_column_create_flags_to_text(grn_ctx *ctx, grn_obj *buf, grn_obj_flags flags)
-{
- GRN_BULK_REWIND(buf);
- switch (flags & GRN_OBJ_COLUMN_TYPE_MASK) {
- case GRN_OBJ_COLUMN_SCALAR:
- GRN_TEXT_PUTS(ctx, buf, "COLUMN_SCALAR");
- break;
- case GRN_OBJ_COLUMN_VECTOR:
- GRN_TEXT_PUTS(ctx, buf, "COLUMN_VECTOR");
- if (flags & GRN_OBJ_WITH_WEIGHT) {
- GRN_TEXT_PUTS(ctx, buf, "|WITH_WEIGHT");
- }
- break;
- case GRN_OBJ_COLUMN_INDEX:
- GRN_TEXT_PUTS(ctx, buf, "COLUMN_INDEX");
- if (flags & GRN_OBJ_WITH_SECTION) {
- GRN_TEXT_PUTS(ctx, buf, "|WITH_SECTION");
- }
- if (flags & GRN_OBJ_WITH_WEIGHT) {
- GRN_TEXT_PUTS(ctx, buf, "|WITH_WEIGHT");
- }
- if (flags & GRN_OBJ_WITH_POSITION) {
- GRN_TEXT_PUTS(ctx, buf, "|WITH_POSITION");
- }
- break;
- }
- switch (flags & GRN_OBJ_COMPRESS_MASK) {
- case GRN_OBJ_COMPRESS_NONE:
- break;
- case GRN_OBJ_COMPRESS_ZLIB:
- GRN_TEXT_PUTS(ctx, buf, "|COMPRESS_ZLIB");
- break;
- case GRN_OBJ_COMPRESS_LZ4:
- GRN_TEXT_PUTS(ctx, buf, "|COMPRESS_LZ4");
- break;
- }
- if (flags & GRN_OBJ_PERSISTENT) {
- GRN_TEXT_PUTS(ctx, buf, "|PERSISTENT");
- }
-}
-
-static grn_bool
-proc_table_create_set_token_filters_put(grn_ctx *ctx,
- grn_obj *token_filters,
- const char *token_filter_name,
- int token_filter_name_length)
-{
- grn_obj *token_filter;
-
- token_filter = grn_ctx_get(ctx,
- token_filter_name,
- token_filter_name_length);
- if (token_filter) {
- GRN_PTR_PUT(ctx, token_filters, token_filter);
- return GRN_TRUE;
- } else {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][create][token-filter] nonexistent token filter: <%.*s>",
- token_filter_name_length, token_filter_name);
- return GRN_FALSE;
- }
-}
-
-static grn_bool
-proc_table_create_set_token_filters_fill(grn_ctx *ctx,
- grn_obj *token_filters,
- grn_obj *token_filter_names)
-{
- const char *start, *current, *end;
- const char *name_start, *name_end;
- const char *last_name_end;
-
- start = GRN_TEXT_VALUE(token_filter_names);
- end = start + GRN_TEXT_LEN(token_filter_names);
- current = start;
- name_start = NULL;
- name_end = NULL;
- last_name_end = start;
- while (current < end) {
- switch (current[0]) {
- case ' ' :
- if (name_start && !name_end) {
- name_end = current;
- }
- break;
- case ',' :
- if (!name_start) {
- goto break_loop;
- }
- if (!name_end) {
- name_end = current;
- }
- proc_table_create_set_token_filters_put(ctx,
- token_filters,
- name_start,
- name_end - name_start);
- last_name_end = name_end + 1;
- name_start = NULL;
- name_end = NULL;
- break;
- default :
- if (!name_start) {
- name_start = current;
- }
- break;
- }
- current++;
- }
-
-break_loop:
- if (!name_start) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][create][token-filter] empty token filter name: "
- "<%.*s|%.*s|%.*s>",
- (int)(last_name_end - start), start,
- (int)(current - last_name_end), last_name_end,
- (int)(end - current), current);
- return GRN_FALSE;
- }
-
- if (!name_end) {
- name_end = current;
- }
- proc_table_create_set_token_filters_put(ctx,
- token_filters,
- name_start,
- name_end - name_start);
-
- return GRN_TRUE;
-}
-
-static void
-proc_table_create_set_token_filters(grn_ctx *ctx,
- grn_obj *table,
- grn_obj *token_filter_names)
-{
- grn_obj token_filters;
-
- if (GRN_TEXT_LEN(token_filter_names) == 0) {
- return;
- }
-
- GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, 0);
- if (proc_table_create_set_token_filters_fill(ctx,
- &token_filters,
- token_filter_names)) {
- grn_obj_set_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters);
- }
- grn_obj_unlink(ctx, &token_filters);
-}
-
-static grn_obj *
-proc_table_create(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_obj *table;
- const char *rest;
- grn_obj_flags flags = grn_atoi(GRN_TEXT_VALUE(VAR(1)),
- GRN_BULK_CURR(VAR(1)), &rest);
- if (GRN_TEXT_VALUE(VAR(1)) == rest) {
- flags = grn_parse_table_create_flags(ctx, GRN_TEXT_VALUE(VAR(1)),
- GRN_BULK_CURR(VAR(1)));
- if (ctx->rc) { goto exit; }
- }
- if (GRN_TEXT_LEN(VAR(0))) {
- grn_obj *key_type = NULL, *value_type = NULL;
- if (GRN_TEXT_LEN(VAR(2)) > 0) {
- key_type = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(2)),
- GRN_TEXT_LEN(VAR(2)));
- if (!key_type) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][create] key type doesn't exist: <%.*s> (%.*s)",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)),
- (int)GRN_TEXT_LEN(VAR(2)), GRN_TEXT_VALUE(VAR(2)));
- return NULL;
- }
- }
- if (GRN_TEXT_LEN(VAR(3)) > 0) {
- value_type = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(3)),
- GRN_TEXT_LEN(VAR(3)));
- if (!value_type) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][create] value type doesn't exist: <%.*s> (%.*s)",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)),
- (int)GRN_TEXT_LEN(VAR(3)), GRN_TEXT_VALUE(VAR(3)));
- return NULL;
- }
- }
- flags |= GRN_OBJ_PERSISTENT;
- table = grn_table_create(ctx,
- GRN_TEXT_VALUE(VAR(0)),
- GRN_TEXT_LEN(VAR(0)),
- NULL, flags,
- key_type,
- value_type);
- if (table) {
- grn_obj *normalizer_name;
- grn_obj_set_info(ctx, table,
- GRN_INFO_DEFAULT_TOKENIZER,
- grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(4)),
- GRN_TEXT_LEN(VAR(4))));
- normalizer_name = VAR(5);
- if (GRN_TEXT_LEN(normalizer_name) > 0) {
- grn_obj_set_info(ctx, table,
- GRN_INFO_NORMALIZER,
- grn_ctx_get(ctx,
- GRN_TEXT_VALUE(normalizer_name),
- GRN_TEXT_LEN(normalizer_name)));
- }
- proc_table_create_set_token_filters(ctx, table, VAR(6));
- grn_obj_unlink(ctx, table);
- }
- } else {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][create] should not create anonymous table");
- }
-exit :
- GRN_OUTPUT_BOOL(!ctx->rc);
- return NULL;
-}
-
-static grn_obj *
-proc_table_remove(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_obj *table;
- table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)),
- GRN_TEXT_LEN(VAR(0)));
- if (table) {
- grn_obj_remove(ctx,table);
- } else {
- ERR(GRN_INVALID_ARGUMENT, "table not found.");
- }
- GRN_OUTPUT_BOOL(!ctx->rc);
- return NULL;
-}
-
-static grn_obj *
-proc_table_rename(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_rc rc = GRN_SUCCESS;
- grn_obj *table = NULL;
- if (GRN_TEXT_LEN(VAR(0)) == 0) {
- rc = GRN_INVALID_ARGUMENT;
- ERR(rc, "[table][rename] table name isn't specified");
- goto exit;
- }
- table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)));
- if (!table) {
- rc = GRN_INVALID_ARGUMENT;
- ERR(rc,
- "[table][rename] table isn't found: <%.*s>",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- goto exit;
- }
- if (GRN_TEXT_LEN(VAR(1)) == 0) {
- rc = GRN_INVALID_ARGUMENT;
- ERR(rc,
- "[table][rename] new table name isn't specified: <%.*s>",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- goto exit;
- }
- rc = grn_table_rename(ctx, table,
- GRN_TEXT_VALUE(VAR(1)), GRN_TEXT_LEN(VAR(1)));
- if (rc != GRN_SUCCESS && ctx->rc == GRN_SUCCESS) {
- ERR(rc,
- "[table][rename] failed to rename: <%.*s> -> <%.*s>",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)),
- (int)GRN_TEXT_LEN(VAR(1)), GRN_TEXT_VALUE(VAR(1)));
- }
-exit :
- GRN_OUTPUT_BOOL(!rc);
- if (table) { grn_obj_unlink(ctx, table); }
- return NULL;
-}
-
-static grn_rc
-proc_column_create_resolve_source_name(grn_ctx *ctx,
- grn_obj *table,
- const char *source_name,
- int source_name_length,
- grn_obj *source_ids)
-{
- grn_obj *column;
-
- column = grn_obj_column(ctx, table, source_name, source_name_length);
- if (!column) {
- ERR(GRN_INVALID_ARGUMENT,
- "[column][create] nonexistent source: <%.*s>",
- source_name_length, source_name);
- return ctx->rc;
- }
-
- if (column->header.type == GRN_ACCESSOR) {
- if (strncmp(source_name, "_key", source_name_length) == 0) {
- grn_id source_id = grn_obj_id(ctx, table);
- GRN_UINT32_PUT(ctx, source_ids, source_id);
- } else {
- ERR(GRN_INVALID_ARGUMENT,
- "[column][create] pseudo column except <_key> is invalid: <%.*s>",
- source_name_length, source_name);
- }
- } else {
- grn_id source_id = grn_obj_id(ctx, column);
- GRN_UINT32_PUT(ctx, source_ids, source_id);
- }
- grn_obj_unlink(ctx, column);
-
- return ctx->rc;
-}
-
-static grn_rc
-proc_column_create_resolve_source_names(grn_ctx *ctx,
- grn_obj *table,
- grn_obj *source_names,
- grn_obj *source_ids)
-{
- int i, names_length;
- int start, source_name_length;
- const char *names;
-
- names = GRN_TEXT_VALUE(source_names);
- start = 0;
- source_name_length = 0;
- names_length = GRN_TEXT_LEN(source_names);
- for (i = 0; i < names_length; i++) {
- switch (names[i]) {
- case ' ' :
- if (source_name_length == 0) {
- start++;
- }
- break;
- case ',' :
- {
- grn_rc rc;
- const char *source_name = names + start;
- rc = proc_column_create_resolve_source_name(ctx,
- table,
- source_name,
- source_name_length,
- source_ids);
- if (rc) {
- return rc;
- }
- start = i + 1;
- source_name_length = 0;
- }
- break;
- default :
- source_name_length++;
- break;
- }
- }
-
- if (source_name_length > 0) {
- grn_rc rc;
- const char *source_name = names + start;
- rc = proc_column_create_resolve_source_name(ctx,
- table,
- source_name,
- source_name_length,
- source_ids);
- if (rc) {
- return rc;
- }
- }
-
- return GRN_SUCCESS;
-}
-
-static grn_obj *
-proc_column_create(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_bool succeeded = GRN_TRUE;
- grn_obj *column, *table = NULL, *type = NULL;
- const char *rest;
- grn_obj_flags flags = grn_atoi(GRN_TEXT_VALUE(VAR(2)),
- GRN_BULK_CURR(VAR(2)), &rest);
- if (GRN_TEXT_VALUE(VAR(2)) == rest) {
- flags = grn_parse_column_create_flags(ctx, GRN_TEXT_VALUE(VAR(2)),
- GRN_BULK_CURR(VAR(2)));
- if (ctx->rc) {
- succeeded = GRN_FALSE;
- goto exit;
- }
- }
- table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)));
- if (!table) {
- ERR(GRN_INVALID_ARGUMENT,
- "[column][create] table doesn't exist: <%.*s>",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- succeeded = GRN_FALSE;
- goto exit;
- }
- type = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(3)),
- GRN_TEXT_LEN(VAR(3)));
- if (!type) {
- ERR(GRN_INVALID_ARGUMENT,
- "[column][create] type doesn't exist: <%.*s>",
- (int)GRN_TEXT_LEN(VAR(3)), GRN_TEXT_VALUE(VAR(3))) ;
- succeeded = GRN_FALSE;
- goto exit;
- }
- if (GRN_TEXT_LEN(VAR(1))) {
- flags |= GRN_OBJ_PERSISTENT;
- } else {
- ERR(GRN_INVALID_ARGUMENT, "[column][create] name is missing");
- succeeded = GRN_FALSE;
- goto exit;
- }
- column = grn_column_create(ctx, table,
- GRN_TEXT_VALUE(VAR(1)),
- GRN_TEXT_LEN(VAR(1)),
- NULL, flags, type);
- if (column) {
- if (GRN_TEXT_LEN(VAR(4))) {
- grn_rc rc;
- grn_obj source_ids;
- GRN_UINT32_INIT(&source_ids, GRN_OBJ_VECTOR);
- rc = proc_column_create_resolve_source_names(ctx,
- type,
- VAR(4),
- &source_ids);
- if (!rc && GRN_BULK_VSIZE(&source_ids)) {
- grn_obj_set_info(ctx, column, GRN_INFO_SOURCE, &source_ids);
- rc = ctx->rc;
- }
- GRN_OBJ_FIN(ctx, &source_ids);
- if (rc) {
- grn_obj_remove(ctx, column);
- succeeded = GRN_FALSE;
- goto exit;
- }
- }
- grn_obj_unlink(ctx, column);
- } else {
- succeeded = GRN_FALSE;
- }
-exit :
- GRN_OUTPUT_BOOL(succeeded);
- if (table) { grn_obj_unlink(ctx, table); }
- if (type) { grn_obj_unlink(ctx, type); }
- return NULL;
-}
-static grn_obj *
-proc_column_remove(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_obj *table, *col;
- char *colname,fullname[GRN_TABLE_MAX_KEY_SIZE];
- unsigned int colname_len,fullname_len;
-
- table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)),
- GRN_TEXT_LEN(VAR(0)));
-
- colname = GRN_TEXT_VALUE(VAR(1));
- colname_len = GRN_TEXT_LEN(VAR(1));
-
- if ((fullname_len = grn_obj_name(ctx, table, fullname, GRN_TABLE_MAX_KEY_SIZE))) {
- fullname[fullname_len] = GRN_DB_DELIMITER;
- grn_memcpy((fullname + fullname_len + 1), colname, colname_len);
- fullname_len += colname_len + 1;
- //TODO:check fullname_len < GRN_TABLE_MAX_KEY_SIZE
- col = grn_ctx_get(ctx, fullname, fullname_len);
- if (col) {
- grn_obj_remove(ctx, col);
- } else {
- ERR(GRN_INVALID_ARGUMENT, "column not found.");
- }
- } else {
- ERR(GRN_INVALID_ARGUMENT, "table not found.");
- }
- GRN_OUTPUT_BOOL(!ctx->rc);
- return NULL;
-}
+#ifdef USE_MEMORY_DEBUG
+ grn_alloc_info_dump(&grn_gctx);
+#endif /* USE_MEMORY_DEBUG */
-static grn_obj *
-proc_column_rename(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_rc rc = GRN_SUCCESS;
- grn_obj *table = NULL;
- grn_obj *column = NULL;
- if (GRN_TEXT_LEN(VAR(0)) == 0) {
- rc = GRN_INVALID_ARGUMENT;
- ERR(rc, "[column][rename] table name isn't specified");
- goto exit;
- }
- table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)));
- if (!table) {
- rc = GRN_INVALID_ARGUMENT;
- ERR(rc,
- "[column][rename] table isn't found: <%.*s>",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- goto exit;
- }
- if (GRN_TEXT_LEN(VAR(1)) == 0) {
- rc = GRN_INVALID_ARGUMENT;
- ERR(rc,
- "[column][rename] column name isn't specified: <%.*s>",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- goto exit;
- }
- column = grn_obj_column(ctx, table,
- GRN_TEXT_VALUE(VAR(1)), GRN_TEXT_LEN(VAR(1)));
- if (!column) {
- rc = GRN_INVALID_ARGUMENT;
- ERR(rc,
- "[column][rename] column isn't found: <%.*s.%.*s>",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)),
- (int)GRN_TEXT_LEN(VAR(1)), GRN_TEXT_VALUE(VAR(1)));
- goto exit;
- }
- if (GRN_TEXT_LEN(VAR(2)) == 0) {
- rc = GRN_INVALID_ARGUMENT;
- ERR(rc,
- "[column][rename] new column name isn't specified: <%.*s.%.*s>",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)),
- (int)GRN_TEXT_LEN(VAR(1)), GRN_TEXT_VALUE(VAR(1)));
- goto exit;
- }
- rc = grn_column_rename(ctx, column,
- GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)));
- if (rc != GRN_SUCCESS && ctx->rc == GRN_SUCCESS) {
- ERR(rc,
- "[column][rename] failed to rename: <%.*s.%.*s> -> <%.*s.%.*s>",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)),
- (int)GRN_TEXT_LEN(VAR(1)), GRN_TEXT_VALUE(VAR(1)),
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)),
- (int)GRN_TEXT_LEN(VAR(2)), GRN_TEXT_VALUE(VAR(2)));
- }
-exit :
- GRN_OUTPUT_BOOL(!rc);
- if (column) { grn_obj_unlink(ctx, column); }
- if (table) { grn_obj_unlink(ctx, table); }
return NULL;
}
#define GRN_STRLEN(s) ((s) ? strlen(s) : 0)
-static void
-output_column_name(grn_ctx *ctx, grn_obj *column)
-{
- grn_obj bulk;
- int name_len;
- char name[GRN_TABLE_MAX_KEY_SIZE];
-
- GRN_TEXT_INIT(&bulk, GRN_OBJ_DO_SHALLOW_COPY);
- name_len = grn_column_name(ctx, column, name, GRN_TABLE_MAX_KEY_SIZE);
- GRN_TEXT_SET(ctx, &bulk, name, name_len);
-
- GRN_OUTPUT_OBJ(&bulk, NULL);
- GRN_OBJ_FIN(ctx, &bulk);
-}
-
-static void
-output_object_name(grn_ctx *ctx, grn_obj *obj)
+void
+grn_proc_output_object_name(grn_ctx *ctx, grn_obj *obj)
{
grn_obj bulk;
int name_len;
@@ -2127,8 +314,8 @@ output_object_name(grn_ctx *ctx, grn_obj *obj)
GRN_OBJ_FIN(ctx, &bulk);
}
-static void
-output_object_id_name(grn_ctx *ctx, grn_id id)
+void
+grn_proc_output_object_id_name(grn_ctx *ctx, grn_id id)
{
grn_obj *obj = NULL;
@@ -2136,265 +323,14 @@ output_object_id_name(grn_ctx *ctx, grn_id id)
obj = grn_ctx_at(ctx, id);
}
- output_object_name(ctx, obj);
-}
-
-static int
-output_column_info(grn_ctx *ctx, grn_obj *column)
-{
- grn_obj o;
- grn_id id;
- const char *type;
- const char *path;
-
- switch (column->header.type) {
- case GRN_COLUMN_FIX_SIZE:
- type = "fix";
- break;
- case GRN_COLUMN_VAR_SIZE:
- type = "var";
- break;
- case GRN_COLUMN_INDEX:
- type = "index";
- break;
- default:
- GRN_LOG(ctx, GRN_LOG_NOTICE, "invalid header type %d\n", column->header.type);
- return 0;
- }
- id = grn_obj_id(ctx, column);
- path = grn_obj_path(ctx, column);
- GRN_TEXT_INIT(&o, 0);
- GRN_OUTPUT_ARRAY_OPEN("COLUMN", 8);
- GRN_OUTPUT_INT64(id);
- output_column_name(ctx, column);
- GRN_OUTPUT_CSTR(path);
- GRN_OUTPUT_CSTR(type);
- grn_column_create_flags_to_text(ctx, &o, column->header.flags);
- GRN_OUTPUT_OBJ(&o, NULL);
- output_object_id_name(ctx, column->header.domain);
- output_object_id_name(ctx, grn_obj_get_range(ctx, column));
- {
- grn_db_obj *obj = (grn_db_obj *)column;
- grn_id *s = obj->source;
- int i = 0, n = obj->source_size / sizeof(grn_id);
- GRN_OUTPUT_ARRAY_OPEN("SOURCES", n);
- for (i = 0; i < n; i++, s++) {
- output_object_id_name(ctx, *s);
- }
- GRN_OUTPUT_ARRAY_CLOSE();
-
- }
- // output_obj_source(ctx, (grn_db_obj *)column);
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OBJ_FIN(ctx, &o);
- return 1;
-}
-
-static grn_obj *
-proc_column_list(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_obj *table;
- if ((table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)),
- GRN_TEXT_LEN(VAR(0))))) {
- grn_hash *cols;
- grn_obj *col;
- int column_list_size = -1;
-#ifdef GRN_WITH_MESSAGE_PACK
- column_list_size = 1; /* [header, (key), (COLUMNS)] */
- if ((col = grn_obj_column(ctx, table,
- GRN_COLUMN_NAME_KEY,
- GRN_COLUMN_NAME_KEY_LEN))) {
- column_list_size++;
- grn_obj_unlink(ctx, col);
- }
- if ((cols = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
- GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY))) {
- column_list_size += grn_table_columns(ctx, table, NULL, 0,
- (grn_obj *)cols);
- grn_hash_close(ctx, cols);
- }
-#endif
- if ((cols = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
- GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY))) {
- GRN_OUTPUT_ARRAY_OPEN("COLUMN_LIST", column_list_size);
- GRN_OUTPUT_ARRAY_OPEN("HEADER", 8);
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("id");
- GRN_OUTPUT_CSTR("UInt32");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("name");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("path");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("type");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("flags");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("domain");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("range");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("source");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_CLOSE();
- if ((col = grn_obj_column(ctx, table,
- GRN_COLUMN_NAME_KEY,
- GRN_COLUMN_NAME_KEY_LEN))) {
- int name_len;
- char name_buf[GRN_TABLE_MAX_KEY_SIZE];
- grn_id id;
- grn_obj buf;
- GRN_TEXT_INIT(&buf, 0);
- GRN_OUTPUT_ARRAY_OPEN("COLUMN", 8);
- id = grn_obj_id(ctx, table);
- GRN_OUTPUT_INT64(id);
- GRN_OUTPUT_CSTR(GRN_COLUMN_NAME_KEY);
- GRN_OUTPUT_CSTR("");
- GRN_OUTPUT_CSTR("");
- grn_column_create_flags_to_text(ctx, &buf, 0);
- GRN_OUTPUT_OBJ(&buf, NULL);
- name_len = grn_obj_name(ctx, table, name_buf, GRN_TABLE_MAX_KEY_SIZE);
- GRN_OUTPUT_STR(name_buf, name_len);
- output_object_id_name(ctx, table->header.domain);
- GRN_OUTPUT_ARRAY_OPEN("SOURCES", 0);
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OBJ_FIN(ctx, &buf);
- grn_obj_unlink(ctx, col);
- }
- if (grn_table_columns(ctx, table, NULL, 0, (grn_obj *)cols) >= 0) {
- grn_id *key;
- GRN_HASH_EACH(ctx, cols, id, &key, NULL, NULL, {
- if ((col = grn_ctx_at(ctx, *key))) {
- output_column_info(ctx, col);
- grn_obj_unlink(ctx, col);
- }
- });
- }
- GRN_OUTPUT_ARRAY_CLOSE();
- grn_hash_close(ctx, cols);
- }
- grn_obj_unlink(ctx, table);
- } else {
- ERR(GRN_INVALID_ARGUMENT, "table '%.*s' does not exist.",
- (int)GRN_TEXT_LEN(VAR(0)),
- GRN_TEXT_VALUE(VAR(0)));
- }
- return NULL;
-}
-
-static int
-output_table_info(grn_ctx *ctx, grn_obj *table)
-{
- grn_id id;
- grn_obj o;
- const char *path;
- grn_obj *default_tokenizer;
- grn_obj *normalizer;
-
- id = grn_obj_id(ctx, table);
- path = grn_obj_path(ctx, table);
- GRN_TEXT_INIT(&o, 0);
- GRN_OUTPUT_ARRAY_OPEN("TABLE", 8);
- GRN_OUTPUT_INT64(id);
- output_object_id_name(ctx, id);
- GRN_OUTPUT_CSTR(path);
- grn_table_create_flags_to_text(ctx, &o, table->header.flags);
- GRN_OUTPUT_OBJ(&o, NULL);
- output_object_id_name(ctx, table->header.domain);
- output_object_id_name(ctx, grn_obj_get_range(ctx, table));
- default_tokenizer = grn_obj_get_info(ctx, table, GRN_INFO_DEFAULT_TOKENIZER,
- NULL);
- output_object_name(ctx, default_tokenizer);
- normalizer = grn_obj_get_info(ctx, table, GRN_INFO_NORMALIZER, NULL);
- output_object_name(ctx, normalizer);
- grn_obj_unlink(ctx, normalizer);
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OBJ_FIN(ctx, &o);
- return 1;
-}
-
-static grn_obj *
-proc_table_list(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_obj tables;
- int n_top_level_elements;
- int n_elements_for_header = 1;
- int n_tables;
- int i;
-
- GRN_PTR_INIT(&tables, GRN_OBJ_VECTOR, GRN_ID_NIL);
- grn_ctx_get_all_tables(ctx, &tables);
- n_tables = GRN_BULK_VSIZE(&tables) / sizeof(grn_obj *);
- n_top_level_elements = n_elements_for_header + n_tables;
- GRN_OUTPUT_ARRAY_OPEN("TABLE_LIST", n_top_level_elements);
-
- GRN_OUTPUT_ARRAY_OPEN("HEADER", 8);
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("id");
- GRN_OUTPUT_CSTR("UInt32");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("name");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("path");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("flags");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("domain");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("range");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("default_tokenizer");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
- GRN_OUTPUT_CSTR("normalizer");
- GRN_OUTPUT_CSTR("ShortText");
- GRN_OUTPUT_ARRAY_CLOSE();
- GRN_OUTPUT_ARRAY_CLOSE();
-
- for (i = 0; i < n_tables; i++) {
- grn_obj *table = GRN_PTR_VALUE_AT(&tables, i);
- output_table_info(ctx, table);
- grn_obj_unlink(ctx, table);
- }
- GRN_OBJ_FIN(ctx, &tables);
-
- GRN_OUTPUT_ARRAY_CLOSE();
-
- return NULL;
+ grn_proc_output_object_name(ctx, obj);
}
static grn_obj *
proc_missing(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
uint32_t plen;
- grn_obj *outbuf = ctx->impl->outbuf;
+ grn_obj *outbuf = ctx->impl->output.buf;
static int grn_document_root_len = -1;
if (!grn_document_root) { return NULL; }
if (grn_document_root_len < 0) {
@@ -2437,36 +373,33 @@ proc_quit(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
static grn_obj *
proc_shutdown(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
- grn_gctx.stat = GRN_CTX_QUIT;
- ctx->stat = GRN_CTX_QUITTING;
- GRN_OUTPUT_BOOL(!ctx->rc);
- return NULL;
-}
+ const char *mode;
+ size_t mode_size;
-static grn_obj *
-proc_lock_clear(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- int target_name_len;
- grn_obj *target_name;
- grn_obj *obj;
-
- target_name = VAR(0);
- target_name_len = GRN_TEXT_LEN(target_name);
-
- if (target_name_len) {
- obj = grn_ctx_get(ctx, GRN_TEXT_VALUE(target_name), target_name_len);
+ mode = grn_plugin_proc_get_var_string(ctx, user_data, "mode", -1, &mode_size);
+#define MODE_EQUAL(name) \
+ (mode_size == strlen(name) && memcmp(mode, name, mode_size) == 0)
+ if (mode_size == 0 || MODE_EQUAL("graceful")) {
+ /* Do nothing. This is the default. */
+ } else if (MODE_EQUAL("immediate")) {
+ grn_request_canceler_cancel_all();
+ if (ctx->rc == GRN_INTERRUPTED_FUNCTION_CALL) {
+ ctx->rc = GRN_SUCCESS;
+ }
} else {
- obj = ctx->impl->db;
+ ERR(GRN_INVALID_ARGUMENT,
+ "[shutdown] mode must be <graceful> or <immediate>: <%.*s>",
+ (int)mode_size, mode);
}
+#undef MODE_EQUAL
- if (obj) {
- grn_obj_clear_lock(ctx, obj);
- } else {
- ERR(GRN_INVALID_ARGUMENT, "[lock_clear] target object not found: <%.*s>",
- target_name_len, GRN_TEXT_VALUE(target_name));
+ if (ctx->rc == GRN_SUCCESS) {
+ grn_gctx.stat = GRN_CTX_QUIT;
+ ctx->stat = GRN_CTX_QUITTING;
}
+
GRN_OUTPUT_BOOL(!ctx->rc);
+
return NULL;
}
@@ -2496,18 +429,21 @@ proc_defrag(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
return NULL;
}
-static char slev[] = " EACewnid-";
-
static grn_obj *
proc_log_level(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
- char *p;
- if (GRN_TEXT_LEN(VAR(0)) &&
- (p = strchr(slev, GRN_TEXT_VALUE(VAR(0))[0]))) {
- grn_log_level max_level = (grn_log_level)(p - slev);
- grn_logger_set_max_level(ctx, max_level);
+ grn_obj *level_name = VAR(0);
+ if (GRN_TEXT_LEN(level_name) > 0) {
+ grn_log_level max_level;
+ GRN_TEXT_PUTC(ctx, level_name, '\0');
+ if (grn_log_level_parse(GRN_TEXT_VALUE(level_name), &max_level)) {
+ grn_logger_set_max_level(ctx, max_level);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "invalid log level: <%s>", GRN_TEXT_VALUE(level_name));
+ }
} else {
- ERR(GRN_INVALID_ARGUMENT, "invalid log level.");
+ ERR(GRN_INVALID_ARGUMENT, "log level is missing");
}
GRN_OUTPUT_BOOL(!ctx->rc);
return NULL;
@@ -2516,13 +452,21 @@ proc_log_level(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data
static grn_obj *
proc_log_put(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
- char *p;
- if (GRN_TEXT_LEN(VAR(0)) &&
- (p = strchr(slev, GRN_TEXT_VALUE(VAR(0))[0]))) {
- GRN_TEXT_PUTC(ctx, VAR(1), '\0');
- GRN_LOG(ctx, (int)(p - slev), "%s", GRN_TEXT_VALUE(VAR(1)));
+ grn_obj *level_name = VAR(0);
+ grn_obj *message = VAR(1);
+ if (GRN_TEXT_LEN(level_name) > 0) {
+ grn_log_level level;
+ GRN_TEXT_PUTC(ctx, level_name, '\0');
+ if (grn_log_level_parse(GRN_TEXT_VALUE(level_name), &level)) {
+ GRN_LOG(ctx, level, "%.*s",
+ (int)GRN_TEXT_LEN(message),
+ GRN_TEXT_VALUE(message));
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "invalid log level: <%s>", GRN_TEXT_VALUE(level_name));
+ }
} else {
- ERR(GRN_INVALID_ARGUMENT, "invalid log level.");
+ ERR(GRN_INVALID_ARGUMENT, "log level is missing");
}
GRN_OUTPUT_BOOL(!ctx->rc);
return NULL;
@@ -2675,29 +619,39 @@ proc_delete(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
NULL, GRN_OP_MATCH, GRN_OP_AND,
GRN_EXPR_SYNTAX_SCRIPT);
if (ctx->rc) {
- char original_error_message[GRN_CTX_MSGSIZE];
- grn_strcpy(original_error_message, GRN_CTX_MSGSIZE, ctx->errbuf);
rc = ctx->rc;
ERR(rc,
"[table][record][delete] failed to parse filter: "
"table: <%.*s>, filter: <%.*s>, detail: <%s>",
(int)GRN_TEXT_LEN(table_name), GRN_TEXT_VALUE(table_name),
(int)GRN_TEXT_LEN(filter), GRN_TEXT_VALUE(filter),
- original_error_message);
+ ctx->errbuf);
} else {
grn_obj *records;
records = grn_table_select(ctx, table, cond, NULL, GRN_OP_OR);
if (records) {
- void *key = NULL;
- GRN_TABLE_EACH(ctx, records, GRN_ID_NIL, GRN_ID_NIL,
- result_id, &key, NULL, NULL, {
- grn_id id = *(grn_id *)key;
- grn_table_delete_by_id(ctx, table, id);
- if (ctx->rc == GRN_OPERATION_NOT_PERMITTED) {
+ GRN_TABLE_EACH_BEGIN(ctx, records, cursor, result_id) {
+ void *key;
+ grn_id id;
+ grn_rc sub_rc;
+
+ if (grn_table_cursor_get_key(ctx, cursor, &key) == 0) {
+ continue;
+ }
+
+ id = *(grn_id *)key;
+ sub_rc = grn_table_delete_by_id(ctx, table, id);
+ if (rc == GRN_SUCCESS) {
+ rc = sub_rc;
+ }
+ if (ctx->rc == GRN_CANCEL) {
+ break;
+ }
+ if (ctx->rc != GRN_SUCCESS) {
ERRCLR(ctx);
}
- });
+ } GRN_TABLE_EACH_END(ctx, cursor);
grn_obj_unlink(ctx, records);
}
}
@@ -2708,852 +662,108 @@ exit :
if (table) {
grn_obj_unlink(ctx, table);
}
- GRN_OUTPUT_BOOL(!rc);
+ GRN_OUTPUT_BOOL(rc == GRN_SUCCESS);
return NULL;
}
-static const size_t DUMP_FLUSH_THRESHOLD_SIZE = 256 * 1024;
-
-static void
-dump_plugins(grn_ctx *ctx, grn_obj *outbuf)
-{
- grn_obj *db = ctx->impl->db;
- grn_table_cursor *cursor;
- grn_id id;
- grn_hash *processed_paths;
- const char *system_plugins_dir;
- const char *native_plugin_suffix;
- const char *ruby_plugin_suffix;
-
- cursor = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1,
- GRN_CURSOR_BY_ID);
- if (!cursor) {
- return;
- }
-
- processed_paths = grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE, 0,
- GRN_OBJ_TABLE_HASH_KEY |
- GRN_OBJ_KEY_VAR_SIZE);
- if (!processed_paths) {
- grn_table_cursor_close(ctx, cursor);
- return;
- }
-
- system_plugins_dir = grn_plugin_get_system_plugins_dir();
- native_plugin_suffix = grn_plugin_get_suffix();
- ruby_plugin_suffix = grn_plugin_get_ruby_suffix();
- while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
- grn_obj *object;
- const char *path;
- grn_id processed_path_id;
-
- object = grn_ctx_at(ctx, id);
- if (!object) {
- ERRCLR(ctx);
- continue;
- }
-
- if (!grn_obj_is_proc(ctx, object)) {
- grn_obj_unlink(ctx, object);
- continue;
- }
-
- if (grn_obj_is_builtin(ctx, object)) {
- grn_obj_unlink(ctx, object);
- continue;
- }
-
- path = grn_obj_path(ctx, object);
- if (!path) {
- grn_obj_unlink(ctx, object);
- continue;
- }
-
- processed_path_id = grn_hash_get(ctx, processed_paths,
- path, strlen(path),
- NULL);
- if (processed_path_id != GRN_ID_NIL) {
- grn_obj_unlink(ctx, object);
- continue;
- }
-
- grn_hash_add(ctx, processed_paths,
- path, strlen(path),
- NULL, NULL);
-
- {
- const char *relative_path;
- const char *libs_path = "/.libs/";
- const char *start_libs;
- char name[PATH_MAX];
-
- name[0] = '\0';
- if (strncmp(path, system_plugins_dir, strlen(system_plugins_dir)) == 0) {
- relative_path = path + strlen(system_plugins_dir);
- } else {
- relative_path = path;
- }
- start_libs = strstr(relative_path, libs_path);
- if (start_libs) {
- grn_strncat(name, PATH_MAX, relative_path, start_libs - relative_path);
- grn_strcat(name, PATH_MAX, "/");
- grn_strcat(name, PATH_MAX, start_libs + strlen(libs_path));
- } else {
- grn_strcat(name, PATH_MAX, relative_path);
- }
- if (strlen(name) > strlen(native_plugin_suffix) &&
- strcmp(name + strlen(name) - strlen(native_plugin_suffix),
- native_plugin_suffix) == 0) {
- name[strlen(name) - strlen(native_plugin_suffix)] = '\0';
- } else if (strlen(name) > strlen(ruby_plugin_suffix) &&
- strcmp(name + strlen(name) - strlen(ruby_plugin_suffix),
- ruby_plugin_suffix) == 0) {
- name[strlen(name) - strlen(ruby_plugin_suffix)] = '\0';
- }
- grn_text_printf(ctx, outbuf, "plugin_register %s\n", name);
- }
- }
- grn_table_cursor_close(ctx, cursor);
-
- grn_hash_close(ctx, processed_paths);
-}
-
-static void
-dump_name(grn_ctx *ctx, grn_obj *outbuf, const char *name, int name_len)
-{
- grn_obj escaped_name;
- GRN_TEXT_INIT(&escaped_name, 0);
- grn_text_esc(ctx, &escaped_name, name, name_len);
- /* is no character escaped? */
- /* TODO false positive with spaces inside names */
- if (GRN_TEXT_LEN(&escaped_name) == name_len + 2) {
- GRN_TEXT_PUT(ctx, outbuf, name, name_len);
- } else {
- GRN_TEXT_PUT(ctx, outbuf,
- GRN_TEXT_VALUE(&escaped_name), GRN_TEXT_LEN(&escaped_name));
- }
- grn_obj_close(ctx, &escaped_name);
-}
-
-static void
-dump_obj_name(grn_ctx *ctx, grn_obj *outbuf, grn_obj *obj)
-{
- char name[GRN_TABLE_MAX_KEY_SIZE];
- int name_len;
- name_len = grn_obj_name(ctx, obj, name, GRN_TABLE_MAX_KEY_SIZE);
- dump_name(ctx, outbuf, name, name_len);
-}
-
-static void
-dump_column_name(grn_ctx *ctx, grn_obj *outbuf, grn_obj *column)
+grn_bool
+grn_proc_option_value_bool(grn_ctx *ctx,
+ grn_obj *option,
+ grn_bool default_value)
{
- char name[GRN_TABLE_MAX_KEY_SIZE];
- int name_len;
- name_len = grn_column_name(ctx, column, name, GRN_TABLE_MAX_KEY_SIZE);
- dump_name(ctx, outbuf, name, name_len);
-}
-
-static void
-dump_index_column_sources(grn_ctx *ctx, grn_obj *outbuf, grn_obj *column)
-{
- grn_obj sources;
- grn_id *source_ids;
- int i, n;
-
- GRN_OBJ_INIT(&sources, GRN_BULK, 0, GRN_ID_NIL);
- grn_obj_get_info(ctx, column, GRN_INFO_SOURCE, &sources);
-
- n = GRN_BULK_VSIZE(&sources) / sizeof(grn_id);
- source_ids = (grn_id *)GRN_BULK_HEAD(&sources);
- if (n > 0) {
- GRN_TEXT_PUTC(ctx, outbuf, ' ');
- }
- for (i = 0; i < n; i++) {
- grn_obj *source;
- if ((source = grn_ctx_at(ctx, *source_ids))) {
- if (i) { GRN_TEXT_PUTC(ctx, outbuf, ','); }
- switch (source->header.type) {
- case GRN_TABLE_PAT_KEY:
- case GRN_TABLE_DAT_KEY:
- case GRN_TABLE_HASH_KEY:
- GRN_TEXT_PUT(ctx, outbuf, GRN_COLUMN_NAME_KEY, GRN_COLUMN_NAME_KEY_LEN);
- break;
- default:
- dump_column_name(ctx, outbuf, source);
- break;
- }
- }
- source_ids++;
- }
- grn_obj_close(ctx, &sources);
-}
-
-static void
-dump_column(grn_ctx *ctx, grn_obj *outbuf , grn_obj *table, grn_obj *column)
-{
- grn_obj *type;
- grn_obj_flags default_flags = GRN_OBJ_PERSISTENT;
- grn_obj buf;
-
- type = grn_ctx_at(ctx, ((grn_db_obj *)column)->range);
- if (!type) {
- // ERR(GRN_RANGE_ERROR, "couldn't get column's type object");
- return;
- }
+ const char *value;
+ size_t value_length;
- GRN_TEXT_PUTS(ctx, outbuf, "column_create ");
- dump_obj_name(ctx, outbuf, table);
- GRN_TEXT_PUTC(ctx, outbuf, ' ');
- dump_column_name(ctx, outbuf, column);
- GRN_TEXT_PUTC(ctx, outbuf, ' ');
- if (type->header.type == GRN_TYPE) {
- default_flags |= type->header.flags;
- }
- GRN_TEXT_INIT(&buf, 0);
- grn_column_create_flags_to_text(ctx, &buf, column->header.flags & ~default_flags);
- GRN_TEXT_PUT(ctx, outbuf, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
- GRN_OBJ_FIN(ctx, &buf);
- GRN_TEXT_PUTC(ctx, outbuf, ' ');
- dump_obj_name(ctx, outbuf, type);
- if (column->header.flags & GRN_OBJ_COLUMN_INDEX) {
- dump_index_column_sources(ctx, outbuf, column);
+ if (!option) {
+ return default_value;
}
- GRN_TEXT_PUTC(ctx, outbuf, '\n');
-
- grn_obj_unlink(ctx, type);
-}
-static int
-reference_column_p(grn_ctx *ctx, grn_obj *column)
-{
- grn_obj *range;
+ value = GRN_TEXT_VALUE(option);
+ value_length = GRN_TEXT_LEN(option);
- range = grn_ctx_at(ctx, grn_obj_get_range(ctx, column));
- if (!range) {
- return GRN_FALSE;
+ if (value_length == 0) {
+ return default_value;
}
- switch (range->header.type) {
- case GRN_TABLE_HASH_KEY:
- case GRN_TABLE_PAT_KEY:
- case GRN_TABLE_DAT_KEY:
- case GRN_TABLE_NO_KEY:
+ if (value_length == strlen("yes") &&
+ strncmp(value, "yes", value_length) == 0) {
return GRN_TRUE;
- default:
+ } else if (value_length == strlen("no") &&
+ strncmp(value, "no", value_length) == 0) {
return GRN_FALSE;
- }
-}
-
-static void
-dump_columns(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table,
- grn_obj *pending_reference_columns)
-{
- grn_hash *columns;
- columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
- GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
- if (!columns) {
- ERR(GRN_NO_MEMORY_AVAILABLE, "couldn't create a hash to hold columns");
- return;
- }
-
- if (grn_table_columns(ctx, table, NULL, 0, (grn_obj *)columns) >= 0) {
- grn_id *key;
-
- GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, {
- grn_obj *column;
- if ((column = grn_ctx_at(ctx, *key))) {
- if (GRN_OBJ_INDEX_COLUMNP(column)) {
- /* do nothing */
- } else if (reference_column_p(ctx, column)) {
- GRN_PTR_PUT(ctx, pending_reference_columns, column);
- } else {
- dump_column(ctx, outbuf, table, column);
- grn_obj_unlink(ctx, column);
- }
- }
- });
- }
- grn_hash_close(ctx, columns);
-}
-
-static void
-dump_record_column_vector(grn_ctx *ctx, grn_obj *outbuf, grn_id id,
- grn_obj *column, grn_id range_id, grn_obj *buf)
-{
- grn_obj *range;
-
- range = grn_ctx_at(ctx, range_id);
- if (GRN_OBJ_TABLEP(range) ||
- (range->header.flags & GRN_OBJ_KEY_VAR_SIZE) == 0) {
- GRN_OBJ_INIT(buf, GRN_UVECTOR, 0, range_id);
- grn_obj_get_value(ctx, column, id, buf);
- grn_text_otoj(ctx, outbuf, buf, NULL);
} else {
- grn_obj_format *format_argument = NULL;
- grn_obj_format format;
- if (column->header.flags & GRN_OBJ_WITH_WEIGHT) {
- format.flags = GRN_OBJ_FORMAT_WITH_WEIGHT;
- format_argument = &format;
- }
- GRN_OBJ_INIT(buf, GRN_VECTOR, 0, range_id);
- grn_obj_get_value(ctx, column, id, buf);
- grn_text_otoj(ctx, outbuf, buf, format_argument);
- }
- grn_obj_unlink(ctx, range);
- grn_obj_unlink(ctx, buf);
-}
-
-static void
-dump_records(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table)
-{
- grn_obj **columns;
- grn_id old_id = 0, id;
- grn_table_cursor *cursor;
- int i, ncolumns, n_use_columns;
- grn_obj columnbuf, delete_commands, use_columns, column_name;
- grn_bool have_index_column = GRN_FALSE;
- grn_bool have_data_column = GRN_FALSE;
-
- switch (table->header.type) {
- case GRN_TABLE_HASH_KEY:
- case GRN_TABLE_PAT_KEY:
- case GRN_TABLE_DAT_KEY:
- case GRN_TABLE_NO_KEY:
- break;
- default:
- return;
- }
-
- if (grn_table_size(ctx, table) == 0) {
- return;
- }
-
- GRN_PTR_INIT(&columnbuf, GRN_OBJ_VECTOR, GRN_ID_NIL);
- grn_obj_columns(ctx, table, DUMP_COLUMNS, strlen(DUMP_COLUMNS), &columnbuf);
- columns = (grn_obj **)GRN_BULK_HEAD(&columnbuf);
- ncolumns = GRN_BULK_VSIZE(&columnbuf)/sizeof(grn_obj *);
-
- GRN_PTR_INIT(&use_columns, GRN_OBJ_VECTOR, GRN_ID_NIL);
- GRN_TEXT_INIT(&column_name, 0);
- for (i = 0; i < ncolumns; i++) {
- if (GRN_OBJ_INDEX_COLUMNP(columns[i])) {
- have_index_column = GRN_TRUE;
- continue;
- }
-
- if (columns[i]->header.type != GRN_ACCESSOR) {
- have_data_column = GRN_TRUE;
- }
-
- GRN_BULK_REWIND(&column_name);
- grn_column_name_(ctx, columns[i], &column_name);
- if (table->header.type != GRN_TABLE_NO_KEY &&
- GRN_TEXT_LEN(&column_name) == GRN_COLUMN_NAME_ID_LEN &&
- memcmp(GRN_TEXT_VALUE(&column_name),
- GRN_COLUMN_NAME_ID,
- GRN_COLUMN_NAME_ID_LEN) == 0) {
- continue;
- }
-
- if (table->header.type == GRN_TABLE_NO_KEY &&
- GRN_TEXT_LEN(&column_name) == GRN_COLUMN_NAME_KEY_LEN &&
- memcmp(GRN_TEXT_VALUE(&column_name),
- GRN_COLUMN_NAME_KEY,
- GRN_COLUMN_NAME_KEY_LEN) == 0) {
- continue;
- }
-
- GRN_PTR_PUT(ctx, &use_columns, columns[i]);
- }
-
- if (have_index_column && !have_data_column) {
- goto exit;
- }
-
- if (GRN_TEXT_LEN(outbuf) > 0) {
- GRN_TEXT_PUTC(ctx, outbuf, '\n');
- }
-
- GRN_TEXT_PUTS(ctx, outbuf, "load --table ");
- dump_obj_name(ctx, outbuf, table);
- GRN_TEXT_PUTS(ctx, outbuf, "\n[\n");
-
- n_use_columns = GRN_BULK_VSIZE(&use_columns) / sizeof(grn_obj *);
- GRN_TEXT_PUTC(ctx, outbuf, '[');
- for (i = 0; i < n_use_columns; i++) {
- grn_obj *column;
- column = *((grn_obj **)GRN_BULK_HEAD(&use_columns) + i);
- if (i) { GRN_TEXT_PUTC(ctx, outbuf, ','); }
- GRN_BULK_REWIND(&column_name);
- grn_column_name_(ctx, column, &column_name);
- grn_text_otoj(ctx, outbuf, &column_name, NULL);
- }
- GRN_TEXT_PUTS(ctx, outbuf, "],\n");
-
- GRN_TEXT_INIT(&delete_commands, 0);
- cursor = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1,
- GRN_CURSOR_BY_KEY);
- for (i = 0; (id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL;
- ++i, old_id = id) {
- int is_value_column;
- int j;
- grn_obj buf;
- if (i) { GRN_TEXT_PUTS(ctx, outbuf, ",\n"); }
- if (table->header.type == GRN_TABLE_NO_KEY && old_id + 1 < id) {
- grn_id current_id;
- for (current_id = old_id + 1; current_id < id; current_id++) {
- GRN_TEXT_PUTS(ctx, outbuf, "[],\n");
- GRN_TEXT_PUTS(ctx, &delete_commands, "delete --table ");
- dump_obj_name(ctx, &delete_commands, table);
- GRN_TEXT_PUTS(ctx, &delete_commands, " --id ");
- grn_text_lltoa(ctx, &delete_commands, current_id);
- GRN_TEXT_PUTC(ctx, &delete_commands, '\n');
- }
- }
- GRN_TEXT_PUTC(ctx, outbuf, '[');
- for (j = 0; j < n_use_columns; j++) {
- grn_id range;
- grn_obj *column;
- column = *((grn_obj **)GRN_BULK_HEAD(&use_columns) + j);
- GRN_BULK_REWIND(&column_name);
- grn_column_name_(ctx, column, &column_name);
- if (GRN_TEXT_LEN(&column_name) == GRN_COLUMN_NAME_VALUE_LEN &&
- !memcmp(GRN_TEXT_VALUE(&column_name),
- GRN_COLUMN_NAME_VALUE,
- GRN_COLUMN_NAME_VALUE_LEN)) {
- is_value_column = 1;
- } else {
- is_value_column = 0;
- }
- range = grn_obj_get_range(ctx, column);
-
- if (j) { GRN_TEXT_PUTC(ctx, outbuf, ','); }
- switch (column->header.type) {
- case GRN_COLUMN_VAR_SIZE:
- case GRN_COLUMN_FIX_SIZE:
- switch (column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) {
- case GRN_OBJ_COLUMN_VECTOR:
- dump_record_column_vector(ctx, outbuf, id, column, range, &buf);
- break;
- case GRN_OBJ_COLUMN_SCALAR:
- {
- GRN_OBJ_INIT(&buf, GRN_BULK, 0, range);
- grn_obj_get_value(ctx, column, id, &buf);
- grn_text_otoj(ctx, outbuf, &buf, NULL);
- grn_obj_unlink(ctx, &buf);
- }
- break;
- default:
- ERR(GRN_OPERATION_NOT_SUPPORTED,
- "unsupported column type: %#x",
- column->header.type);
- break;
- }
- break;
- case GRN_COLUMN_INDEX:
- break;
- case GRN_ACCESSOR:
- {
- GRN_OBJ_INIT(&buf, GRN_BULK, 0, range);
- grn_obj_get_value(ctx, column, id, &buf);
- /* XXX maybe, grn_obj_get_range() should not unconditionally return
- GRN_DB_INT32 when column is GRN_ACCESSOR and
- GRN_ACCESSOR_GET_VALUE */
- if (is_value_column) {
- buf.header.domain = ((grn_db_obj *)table)->range;
- }
- grn_text_otoj(ctx, outbuf, &buf, NULL);
- grn_obj_unlink(ctx, &buf);
- }
- break;
- default:
- ERR(GRN_OPERATION_NOT_SUPPORTED,
- "unsupported header type %#x",
- column->header.type);
- break;
- }
- }
- GRN_TEXT_PUTC(ctx, outbuf, ']');
- if (GRN_TEXT_LEN(outbuf) >= DUMP_FLUSH_THRESHOLD_SIZE) {
- grn_ctx_output_flush(ctx, 0);
- }
- }
- grn_table_cursor_close(ctx, cursor);
- GRN_TEXT_PUTS(ctx, outbuf, "\n]\n");
- GRN_TEXT_PUT(ctx, outbuf, GRN_TEXT_VALUE(&delete_commands),
- GRN_TEXT_LEN(&delete_commands));
- grn_obj_unlink(ctx, &delete_commands);
-
-exit :
- grn_obj_unlink(ctx, &column_name);
- grn_obj_unlink(ctx, &use_columns);
-
- for (i = 0; i < ncolumns; i++) {
- grn_obj_unlink(ctx, columns[i]);
- }
- grn_obj_unlink(ctx, &columnbuf);
-}
-
-static void
-dump_table(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table,
- grn_obj *pending_reference_columns)
-{
- grn_obj *domain = NULL, *range = NULL;
- grn_obj_flags default_flags = GRN_OBJ_PERSISTENT;
- grn_obj *default_tokenizer;
- grn_obj *normalizer;
- grn_obj buf;
-
- switch (table->header.type) {
- case GRN_TABLE_HASH_KEY:
- case GRN_TABLE_PAT_KEY:
- case GRN_TABLE_DAT_KEY:
- domain = grn_ctx_at(ctx, table->header.domain);
- break;
- default:
- break;
- }
-
- if (GRN_TEXT_LEN(outbuf) > 0) {
- GRN_TEXT_PUTC(ctx, outbuf, '\n');
- grn_ctx_output_flush(ctx, 0);
- }
-
- GRN_TEXT_PUTS(ctx, outbuf, "table_create ");
- dump_obj_name(ctx, outbuf, table);
- GRN_TEXT_PUTC(ctx, outbuf, ' ');
- GRN_TEXT_INIT(&buf, 0);
- grn_table_create_flags_to_text(ctx, &buf, table->header.flags & ~default_flags);
- GRN_TEXT_PUT(ctx, outbuf, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
- GRN_OBJ_FIN(ctx, &buf);
- if (domain) {
- GRN_TEXT_PUTC(ctx, outbuf, ' ');
- dump_obj_name(ctx, outbuf, domain);
- }
- if (((grn_db_obj *)table)->range != GRN_ID_NIL) {
- range = grn_ctx_at(ctx, ((grn_db_obj *)table)->range);
- if (!range) {
- // ERR(GRN_RANGE_ERROR, "couldn't get table's value_type object");
- return;
- }
- if (table->header.type != GRN_TABLE_NO_KEY) {
- GRN_TEXT_PUTC(ctx, outbuf, ' ');
- } else {
- GRN_TEXT_PUTS(ctx, outbuf, " --value_type ");
- }
- dump_obj_name(ctx, outbuf, range);
- grn_obj_unlink(ctx, range);
- }
- default_tokenizer = grn_obj_get_info(ctx, table, GRN_INFO_DEFAULT_TOKENIZER,
- NULL);
- if (default_tokenizer) {
- GRN_TEXT_PUTS(ctx, outbuf, " --default_tokenizer ");
- dump_obj_name(ctx, outbuf, default_tokenizer);
- }
- normalizer = grn_obj_get_info(ctx, table, GRN_INFO_NORMALIZER, NULL);
- if (normalizer) {
- GRN_TEXT_PUTS(ctx, outbuf, " --normalizer ");
- dump_obj_name(ctx, outbuf, normalizer);
- }
- if (table->header.type != GRN_TABLE_NO_KEY) {
- grn_obj token_filters;
- int n_token_filters;
-
- GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, GRN_ID_NIL);
- grn_obj_get_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters);
- n_token_filters = GRN_BULK_VSIZE(&token_filters) / sizeof(grn_obj *);
- if (n_token_filters > 0) {
- int i;
- GRN_TEXT_PUTS(ctx, outbuf, " --token_filters ");
- for (i = 0; i < n_token_filters; i++) {
- grn_obj *token_filter = GRN_PTR_VALUE_AT(&token_filters, i);
- if (i > 0) {
- GRN_TEXT_PUTC(ctx, outbuf, ',');
- }
- dump_obj_name(ctx, outbuf, token_filter);
- }
- }
- GRN_OBJ_FIN(ctx, &token_filters);
- }
-
- GRN_TEXT_PUTC(ctx, outbuf, '\n');
-
- if (domain) {
- grn_obj_unlink(ctx, domain);
- }
-
- dump_columns(ctx, outbuf, table, pending_reference_columns);
-}
-
-static void
-dump_pending_columns(grn_ctx *ctx, grn_obj *outbuf, grn_obj *pending_columns)
-{
- size_t i, n_columns;
-
- n_columns = GRN_BULK_VSIZE(pending_columns) / sizeof(grn_obj *);
- if (n_columns == 0) {
- return;
- }
-
- if (GRN_TEXT_LEN(outbuf) > 0) {
- GRN_TEXT_PUTC(ctx, outbuf, '\n');
- grn_ctx_output_flush(ctx, 0);
- }
-
- for (i = 0; i < n_columns; i++) {
- grn_obj *table, *column;
-
- column = GRN_PTR_VALUE_AT(pending_columns, i);
- table = grn_ctx_at(ctx, column->header.domain);
- dump_column(ctx, outbuf, table, column);
- grn_obj_unlink(ctx, column);
- grn_obj_unlink(ctx, table);
+ return default_value;
}
}
-static void
-dump_schema(grn_ctx *ctx, grn_obj *outbuf)
+int32_t
+grn_proc_option_value_int32(grn_ctx *ctx,
+ grn_obj *option,
+ int32_t default_value)
{
- grn_obj *db = ctx->impl->db;
- grn_table_cursor *cur;
- grn_id id;
- grn_obj pending_reference_columns;
-
- cur = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1,
- GRN_CURSOR_BY_ID);
- if (!cur) {
- return;
- }
+ const char *value;
+ size_t value_length;
+ int32_t int32_value;
+ const char *rest;
- GRN_PTR_INIT(&pending_reference_columns, GRN_OBJ_VECTOR, GRN_ID_NIL);
- while ((id = grn_table_cursor_next(ctx, cur)) != GRN_ID_NIL) {
- grn_obj *object;
-
- if ((object = grn_ctx_at(ctx, id))) {
- switch (object->header.type) {
- case GRN_TABLE_HASH_KEY:
- case GRN_TABLE_PAT_KEY:
- case GRN_TABLE_DAT_KEY:
- case GRN_TABLE_NO_KEY:
- dump_table(ctx, outbuf, object, &pending_reference_columns);
- break;
- default:
- break;
- }
- grn_obj_unlink(ctx, object);
- } else {
- /* XXX: this clause is executed when MeCab tokenizer is enabled in
- database but the groonga isn't supported MeCab.
- We should return error mesage about it and error exit status
- but it's too difficult for this architecture. :< */
- ERRCLR(ctx);
- }
+ if (!option) {
+ return default_value;
}
- grn_table_cursor_close(ctx, cur);
-
- dump_pending_columns(ctx, outbuf, &pending_reference_columns);
- grn_obj_close(ctx, &pending_reference_columns);
-}
-
-static void
-dump_selected_tables_records(grn_ctx *ctx, grn_obj *outbuf, grn_obj *tables)
-{
- const char *p, *e;
- p = GRN_TEXT_VALUE(tables);
- e = p + GRN_TEXT_LEN(tables);
- while (p < e) {
- int len;
- grn_obj *table;
- const char *token, *token_e;
-
- if ((len = grn_isspace(p, ctx->encoding))) {
- p += len;
- continue;
- }
-
- token = p;
- if (!(('a' <= *p && *p <= 'z') ||
- ('A' <= *p && *p <= 'Z') ||
- (*p == '_'))) {
- while (p < e && !grn_isspace(p, ctx->encoding)) {
- p++;
- }
- GRN_LOG(ctx, GRN_LOG_WARNING, "invalid table name is ignored: <%.*s>\n",
- (int)(p - token), token);
- continue;
- }
- while (p < e &&
- (('a' <= *p && *p <= 'z') ||
- ('A' <= *p && *p <= 'Z') ||
- ('0' <= *p && *p <= '9') ||
- (*p == '_'))) {
- p++;
- }
- token_e = p;
- while (p < e && (len = grn_isspace(p, ctx->encoding))) {
- p += len;
- continue;
- }
- if (p < e && *p == ',') {
- p++;
- }
+ value = GRN_TEXT_VALUE(option);
+ value_length = GRN_TEXT_LEN(option);
- if ((table = grn_ctx_get(ctx, token, token_e - token))) {
- dump_records(ctx, outbuf, table);
- grn_obj_unlink(ctx, table);
- } else {
- GRN_LOG(ctx, GRN_LOG_WARNING,
- "nonexistent table name is ignored: <%.*s>\n",
- (int)(token_e - token), token);
- }
+ if (value_length == 0) {
+ return default_value;
}
-}
-static void
-dump_all_records(grn_ctx *ctx, grn_obj *outbuf)
-{
- grn_obj *db = ctx->impl->db;
- grn_table_cursor *cur;
- if ((cur = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1,
- GRN_CURSOR_BY_ID))) {
- grn_id id;
-
- while ((id = grn_table_cursor_next(ctx, cur)) != GRN_ID_NIL) {
- grn_obj *table;
-
- if ((table = grn_ctx_at(ctx, id))) {
- dump_records(ctx, outbuf, table);
- grn_obj_unlink(ctx, table);
- } else {
- /* XXX: this clause is executed when MeCab tokenizer is enabled in
- database but the groonga isn't supported MeCab.
- We should return error mesage about it and error exit status
- but it's too difficult for this architecture. :< */
- ERRCLR(ctx);
- }
- }
- grn_table_cursor_close(ctx, cur);
+ int32_value = grn_atoi(value, value + value_length, &rest);
+ if (rest == value + value_length) {
+ return int32_value;
+ } else {
+ return default_value;
}
}
-static void
-dump_indexes(grn_ctx *ctx, grn_obj *outbuf)
+const char *
+grn_proc_option_value_string(grn_ctx *ctx,
+ grn_obj *option,
+ size_t *size)
{
- grn_obj *db = ctx->impl->db;
- grn_table_cursor *cursor;
- grn_id id;
- grn_bool is_first_index_column = GRN_TRUE;
-
- cursor = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1,
- GRN_CURSOR_BY_ID);
- if (!cursor) {
- return;
- }
-
- while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
- grn_obj *object;
-
- object = grn_ctx_at(ctx, id);
- if (!object) {
- /* XXX: this clause is executed when MeCab tokenizer is enabled in
- database but the groonga isn't supported MeCab.
- We should return error mesage about it and error exit status
- but it's too difficult for this architecture. :< */
- ERRCLR(ctx);
- continue;
- }
-
- if (object->header.type == GRN_COLUMN_INDEX) {
- grn_obj *table;
- grn_obj *column = object;
-
- if (is_first_index_column && GRN_TEXT_LEN(outbuf) > 0) {
- GRN_TEXT_PUTC(ctx, outbuf, '\n');
- }
- is_first_index_column = GRN_FALSE;
+ const char *value;
+ size_t value_length;
- table = grn_ctx_at(ctx, column->header.domain);
- dump_column(ctx, outbuf, table, column);
- grn_obj_unlink(ctx, table);
+ if (!option) {
+ if (size) {
+ *size = 0;
}
- grn_obj_unlink(ctx, object);
+ return NULL;
}
- grn_table_cursor_close(ctx, cursor);
-}
-
-static grn_bool
-bool_option_value(grn_obj *option, grn_bool default_value)
-{
- const char *value;
- size_t value_length;
value = GRN_TEXT_VALUE(option);
value_length = GRN_TEXT_LEN(option);
- if (value_length == 0) {
- return default_value;
+ if (size) {
+ *size = value_length;
}
- if (value_length == strlen("yes") &&
- strncmp(value, "yes", value_length) == 0) {
- return GRN_TRUE;
- } else if (value_length == strlen("no") &&
- strncmp(value, "no", value_length) == 0) {
- return GRN_FALSE;
+ if (value_length == 0) {
+ return NULL;
} else {
- return default_value;
+ return value;
}
}
-static grn_obj *
-proc_dump(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+grn_content_type
+grn_proc_option_value_content_type(grn_ctx *ctx,
+ grn_obj *option,
+ grn_content_type default_value)
{
- grn_obj *outbuf = ctx->impl->outbuf;
- grn_obj *tables = VAR(0);
- grn_obj *dump_plugins_raw = VAR(1);
- grn_obj *dump_schema_raw = VAR(2);
- grn_obj *dump_records_raw = VAR(3);
- grn_obj *dump_indexes_raw = VAR(4);
- grn_bool is_dump_plugins;
- grn_bool is_dump_schema;
- grn_bool is_dump_records;
- grn_bool is_dump_indexes;
-
- grn_ctx_set_output_type(ctx, GRN_CONTENT_GROONGA_COMMAND_LIST);
-
- is_dump_plugins = bool_option_value(dump_plugins_raw, GRN_TRUE);
- is_dump_schema = bool_option_value(dump_schema_raw, GRN_TRUE);
- is_dump_records = bool_option_value(dump_records_raw, GRN_TRUE);
- is_dump_indexes = bool_option_value(dump_indexes_raw, GRN_TRUE);
-
- if (is_dump_plugins) {
- dump_plugins(ctx, outbuf);
- }
- if (is_dump_schema) {
- dump_schema(ctx, outbuf);
- }
- if (is_dump_records) {
- /* To update index columns correctly, we first create the whole schema, then
- load non-derivative records, while skipping records of index columns. That
- way, groonga will silently do the job of updating index columns for us. */
- if (GRN_TEXT_LEN(tables) > 0) {
- dump_selected_tables_records(ctx, outbuf, tables);
- } else {
- dump_all_records(ctx, outbuf);
- }
- }
- if (is_dump_indexes) {
- dump_indexes(ctx, outbuf);
+ if (!option) {
+ return default_value;
}
- /* remove the last newline because another one will be added by the caller.
- maybe, the caller of proc functions currently doesn't consider the
- possibility of multiple-line output from proc functions. */
- if (GRN_BULK_VSIZE(outbuf) > 0) {
- grn_bulk_truncate(ctx, outbuf, GRN_BULK_VSIZE(outbuf) - 1);
- }
- return NULL;
+ return grn_content_type_parse(ctx, option, default_value);
}
static grn_obj *
@@ -3642,14 +852,14 @@ proc_check(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
}
for (i = 0; i < GRN_II_MAX_LSEG; i++) {
j = h->binfo[i];
- if (j < 0x20000) {
+ if (j != GRN_II_PSEG_NOT_ASSIGNED) {
if (j > max) { max = j; }
b++;
}
}
for (i = 0; i < GRN_II_MAX_LSEG; i++) {
j = h->ainfo[i];
- if (j < 0x20000) {
+ if (j != GRN_II_PSEG_NOT_ASSIGNED) {
if (j > max) { max = j; }
a++;
}
@@ -3818,52 +1028,51 @@ is_normalizer(grn_ctx *ctx, grn_obj *object)
return GRN_TRUE;
}
-static grn_bool
-is_tokenizer(grn_ctx *ctx, grn_obj *object)
-{
- if (object->header.type != GRN_PROC) {
- return GRN_FALSE;
- }
-
- if (grn_proc_get_type(ctx, object) != GRN_PROC_TOKENIZER) {
- return GRN_FALSE;
- }
-
- return GRN_TRUE;
-}
-
static const char *
char_type_name(grn_char_type type)
{
const char *name = "unknown";
- switch (type) {
+#define CHAR_TYPE_NAME_WITH_BLANK(type_name) do { \
+ if (GRN_CHAR_IS_BLANK(type)) { \
+ name = type_name "|blank"; \
+ } else { \
+ name = type_name; \
+ } \
+ } while (GRN_FALSE)
+
+ switch (GRN_CHAR_TYPE(type)) {
case GRN_CHAR_NULL :
- name = "null";
+ CHAR_TYPE_NAME_WITH_BLANK("null");
break;
case GRN_CHAR_ALPHA :
- name = "alpha";
+ CHAR_TYPE_NAME_WITH_BLANK("alpha");
break;
case GRN_CHAR_DIGIT :
- name = "digit";
+ CHAR_TYPE_NAME_WITH_BLANK("digit");
break;
case GRN_CHAR_SYMBOL :
- name = "symbol";
+ CHAR_TYPE_NAME_WITH_BLANK("symbol");
break;
case GRN_CHAR_HIRAGANA :
- name = "hiragana";
+ CHAR_TYPE_NAME_WITH_BLANK("hiragana");
break;
case GRN_CHAR_KATAKANA :
- name = "katakana";
+ CHAR_TYPE_NAME_WITH_BLANK("katakana");
break;
case GRN_CHAR_KANJI :
- name = "kanji";
+ CHAR_TYPE_NAME_WITH_BLANK("kanji");
break;
case GRN_CHAR_OTHERS :
- name = "others";
+ CHAR_TYPE_NAME_WITH_BLANK("others");
+ break;
+ default :
+ CHAR_TYPE_NAME_WITH_BLANK("unknown");
break;
}
+#undef CHAR_TYPE_NAME_WITH_BLANK
+
return name;
}
@@ -3879,7 +1088,6 @@ proc_normalize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data
flag_names = VAR(2);
if (GRN_TEXT_LEN(normalizer_name) == 0) {
ERR(GRN_INVALID_ARGUMENT, "normalizer name is missing");
- GRN_OUTPUT_CSTR("");
return NULL;
}
@@ -3899,7 +1107,6 @@ proc_normalize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data
"[normalize] nonexistent normalizer: <%.*s>",
(int)GRN_TEXT_LEN(normalizer_name),
GRN_TEXT_VALUE(normalizer_name));
- GRN_OUTPUT_CSTR("");
return NULL;
}
@@ -3912,7 +1119,6 @@ proc_normalize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data
(int)GRN_TEXT_LEN(&inspected),
GRN_TEXT_VALUE(&inspected));
GRN_OBJ_FIN(ctx, &inspected);
- GRN_OUTPUT_CSTR("");
grn_obj_unlink(ctx, normalizer);
return NULL;
}
@@ -3975,330 +1181,6 @@ proc_normalize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data
return NULL;
}
-static unsigned int
-parse_tokenize_flags(grn_ctx *ctx, grn_obj *flag_names)
-{
- unsigned int flags = 0;
- const char *names, *names_end;
- int length;
-
- names = GRN_TEXT_VALUE(flag_names);
- length = GRN_TEXT_LEN(flag_names);
- names_end = names + length;
- while (names < names_end) {
- if (*names == '|' || *names == ' ') {
- names += 1;
- continue;
- }
-
-#define CHECK_FLAG(name)\
- if (((names_end - names) >= (sizeof(#name) - 1)) &&\
- (!memcmp(names, #name, sizeof(#name) - 1))) {\
- flags |= GRN_TOKEN_CURSOR_ ## name;\
- names += sizeof(#name) - 1;\
- continue;\
- }
-
- CHECK_FLAG(ENABLE_TOKENIZED_DELIMITER);
-
-#define GRN_TOKEN_CURSOR_NONE 0
- CHECK_FLAG(NONE);
-#undef GRN_TOKEN_CURSOR_NONE
-
- ERR(GRN_INVALID_ARGUMENT, "[tokenize] invalid flag: <%.*s>",
- (int)(names_end - names), names);
- return 0;
-#undef CHECK_FLAG
- }
-
- return flags;
-}
-
-typedef struct {
- grn_id id;
- int32_t position;
- grn_bool force_prefix;
-} tokenize_token;
-
-static void
-output_tokens(grn_ctx *ctx, grn_obj *tokens, grn_obj *lexicon)
-{
- int i, n_tokens;
-
- n_tokens = GRN_BULK_VSIZE(tokens) / sizeof(tokenize_token);
- GRN_OUTPUT_ARRAY_OPEN("TOKENS", n_tokens);
- for (i = 0; i < n_tokens; i++) {
- tokenize_token *token;
- char value[GRN_TABLE_MAX_KEY_SIZE];
- unsigned int value_size;
-
- token = ((tokenize_token *)(GRN_BULK_HEAD(tokens))) + i;
-
- GRN_OUTPUT_MAP_OPEN("TOKEN", 3);
-
- GRN_OUTPUT_CSTR("value");
- value_size = grn_table_get_key(ctx, lexicon, token->id,
- value, GRN_TABLE_MAX_KEY_SIZE);
- GRN_OUTPUT_STR(value, value_size);
-
- GRN_OUTPUT_CSTR("position");
- GRN_OUTPUT_INT32(token->position);
-
- GRN_OUTPUT_CSTR("force_prefix");
- GRN_OUTPUT_BOOL(token->force_prefix);
-
- GRN_OUTPUT_MAP_CLOSE();
- }
- GRN_OUTPUT_ARRAY_CLOSE();
-}
-
-static grn_obj *
-create_lexicon_for_tokenize(grn_ctx *ctx,
- grn_obj *tokenizer_name,
- grn_obj *normalizer_name,
- grn_obj *token_filter_names)
-{
- grn_obj *lexicon;
- grn_obj *tokenizer;
- grn_obj *normalizer = NULL;
-
- tokenizer = grn_ctx_get(ctx,
- GRN_TEXT_VALUE(tokenizer_name),
- GRN_TEXT_LEN(tokenizer_name));
- if (!tokenizer) {
- ERR(GRN_INVALID_ARGUMENT,
- "[tokenize] nonexistent tokenizer: <%.*s>",
- (int)GRN_TEXT_LEN(tokenizer_name),
- GRN_TEXT_VALUE(tokenizer_name));
- return NULL;
- }
-
- if (!is_tokenizer(ctx, tokenizer)) {
- grn_obj inspected;
- GRN_TEXT_INIT(&inspected, 0);
- grn_inspect(ctx, &inspected, tokenizer);
- ERR(GRN_INVALID_ARGUMENT,
- "[tokenize] not tokenizer: %.*s",
- (int)GRN_TEXT_LEN(&inspected),
- GRN_TEXT_VALUE(&inspected));
- GRN_OBJ_FIN(ctx, &inspected);
- grn_obj_unlink(ctx, tokenizer);
- return NULL;
- }
-
- if (GRN_TEXT_LEN(normalizer_name) > 0) {
- normalizer = grn_ctx_get(ctx,
- GRN_TEXT_VALUE(normalizer_name),
- GRN_TEXT_LEN(normalizer_name));
- if (!normalizer) {
- grn_obj_unlink(ctx, tokenizer);
- ERR(GRN_INVALID_ARGUMENT,
- "[tokenize] nonexistent normalizer: <%.*s>",
- (int)GRN_TEXT_LEN(normalizer_name),
- GRN_TEXT_VALUE(normalizer_name));
- return NULL;
- }
-
- if (!is_normalizer(ctx, normalizer)) {
- grn_obj inspected;
- grn_obj_unlink(ctx, tokenizer);
- GRN_TEXT_INIT(&inspected, 0);
- grn_inspect(ctx, &inspected, normalizer);
- ERR(GRN_INVALID_ARGUMENT,
- "[tokenize] not normalizer: %.*s",
- (int)GRN_TEXT_LEN(&inspected),
- GRN_TEXT_VALUE(&inspected));
- GRN_OBJ_FIN(ctx, &inspected);
- grn_obj_unlink(ctx, normalizer);
- return NULL;
- }
- }
-
- lexicon = grn_table_create(ctx, NULL, 0,
- NULL,
- GRN_OBJ_TABLE_HASH_KEY,
- grn_ctx_at(ctx, GRN_DB_SHORT_TEXT),
- NULL);
- grn_obj_set_info(ctx, lexicon,
- GRN_INFO_DEFAULT_TOKENIZER, tokenizer);
- grn_obj_unlink(ctx, tokenizer);
- if (normalizer) {
- grn_obj_set_info(ctx, lexicon,
- GRN_INFO_NORMALIZER, normalizer);
- grn_obj_unlink(ctx, normalizer);
- }
- proc_table_create_set_token_filters(ctx, lexicon, token_filter_names);
-
- return lexicon;
-}
-
-static void
-tokenize(grn_ctx *ctx, grn_obj *lexicon, grn_obj *string, grn_tokenize_mode mode,
- unsigned int flags, grn_obj *tokens)
-{
- grn_token_cursor *token_cursor;
-
- token_cursor =
- grn_token_cursor_open(ctx, lexicon,
- GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string),
- mode, flags);
- if (!token_cursor) {
- return;
- }
-
- while (token_cursor->status == GRN_TOKEN_CURSOR_DOING) {
- grn_id token_id = grn_token_cursor_next(ctx, token_cursor);
- tokenize_token *current_token;
- if (token_id == GRN_ID_NIL) {
- continue;
- }
- grn_bulk_space(ctx, tokens, sizeof(tokenize_token));
- current_token = ((tokenize_token *)(GRN_BULK_CURR(tokens))) - 1;
- current_token->id = token_id;
- current_token->position = token_cursor->pos;
- current_token->force_prefix = token_cursor->force_prefix;
- }
- grn_token_cursor_close(ctx, token_cursor);
-}
-
-static grn_obj *
-proc_tokenize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_obj *tokenizer_name;
- grn_obj *string;
- grn_obj *normalizer_name;
- grn_obj *flag_names;
- grn_obj *mode_name;
- grn_obj *token_filter_names;
-
- tokenizer_name = VAR(0);
- string = VAR(1);
- normalizer_name = VAR(2);
- flag_names = VAR(3);
- mode_name = VAR(4);
- token_filter_names = VAR(5);
-
- if (GRN_TEXT_LEN(tokenizer_name) == 0) {
- ERR(GRN_INVALID_ARGUMENT, "[tokenize] tokenizer name is missing");
- return NULL;
- }
-
- if (GRN_TEXT_LEN(string) == 0) {
- ERR(GRN_INVALID_ARGUMENT, "[tokenize] string is missing");
- return NULL;
- }
-
- {
- unsigned int flags;
- grn_obj *lexicon;
-
- flags = parse_tokenize_flags(ctx, flag_names);
- if (ctx->rc != GRN_SUCCESS) {
- return NULL;
- }
-
- lexicon = create_lexicon_for_tokenize(ctx,
- tokenizer_name,
- normalizer_name,
- token_filter_names);
- if (!lexicon) {
- return NULL;
- }
-
-#define MODE_NAME_EQUAL(name)\
- (GRN_TEXT_LEN(mode_name) == strlen(name) &&\
- memcmp(GRN_TEXT_VALUE(mode_name), name, strlen(name)) == 0)
-
- {
- grn_obj tokens;
- GRN_VALUE_FIX_SIZE_INIT(&tokens, GRN_OBJ_VECTOR, GRN_ID_NIL);
- if (GRN_TEXT_LEN(mode_name) == 0 || MODE_NAME_EQUAL("ADD")) {
- tokenize(ctx, lexicon, string, GRN_TOKEN_ADD, flags, &tokens);
- output_tokens(ctx, &tokens, lexicon);
- } else if (MODE_NAME_EQUAL("GET")) {
- tokenize(ctx, lexicon, string, GRN_TOKEN_ADD, flags, &tokens);
- GRN_BULK_REWIND(&tokens);
- tokenize(ctx, lexicon, string, GRN_TOKEN_GET, flags, &tokens);
- output_tokens(ctx, &tokens, lexicon);
- } else {
- ERR(GRN_INVALID_ARGUMENT, "[tokenize] invalid mode: <%.*s>",
- (int)GRN_TEXT_LEN(mode_name), GRN_TEXT_VALUE(mode_name));
- }
- GRN_OBJ_FIN(ctx, &tokens);
- }
-#undef MODE_NAME_EQUAL
-
- grn_obj_unlink(ctx, lexicon);
- }
-
- return NULL;
-}
-
-static grn_obj *
-proc_table_tokenize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_obj *table_name;
- grn_obj *string;
- grn_obj *flag_names;
- grn_obj *mode_name;
-
- table_name = VAR(0);
- string = VAR(1);
- flag_names = VAR(2);
- mode_name = VAR(3);
-
- if (GRN_TEXT_LEN(table_name) == 0) {
- ERR(GRN_INVALID_ARGUMENT, "[table_tokenize] table name is missing");
- return NULL;
- }
-
- if (GRN_TEXT_LEN(string) == 0) {
- ERR(GRN_INVALID_ARGUMENT, "[table_tokenize] string is missing");
- return NULL;
- }
-
- {
- unsigned int flags;
- grn_obj *lexicon;
-
- flags = parse_tokenize_flags(ctx, flag_names);
- if (ctx->rc != GRN_SUCCESS) {
- return NULL;
- }
-
- lexicon = grn_ctx_get(ctx, GRN_TEXT_VALUE(table_name), GRN_TEXT_LEN(table_name));
-
- if (!lexicon) {
- return NULL;
- }
-
-#define MODE_NAME_EQUAL(name)\
- (GRN_TEXT_LEN(mode_name) == strlen(name) &&\
- memcmp(GRN_TEXT_VALUE(mode_name), name, strlen(name)) == 0)
-
- {
- grn_obj tokens;
- GRN_VALUE_FIX_SIZE_INIT(&tokens, GRN_OBJ_VECTOR, GRN_ID_NIL);
- if (GRN_TEXT_LEN(mode_name) == 0 || MODE_NAME_EQUAL("GET")) {
- tokenize(ctx, lexicon, string, GRN_TOKEN_GET, flags, &tokens);
- output_tokens(ctx, &tokens, lexicon);
- } else if (MODE_NAME_EQUAL("ADD")) {
- tokenize(ctx, lexicon, string, GRN_TOKEN_ADD, flags, &tokens);
- output_tokens(ctx, &tokens, lexicon);
- } else {
- ERR(GRN_INVALID_ARGUMENT, "[table_tokenize] invalid mode: <%.*s>",
- (int)GRN_TEXT_LEN(mode_name), GRN_TEXT_VALUE(mode_name));
- }
- GRN_OBJ_FIN(ctx, &tokens);
- }
-#undef MODE_NAME_EQUAL
-
- grn_obj_unlink(ctx, lexicon);
- }
-
- return NULL;
-}
-
static void
list_proc(grn_ctx *ctx, grn_proc_type target_proc_type,
const char *name, const char *plural_name)
@@ -4516,24 +1398,27 @@ number_safe_cast(grn_ctx *ctx, grn_obj *src, grn_obj *dest, grn_id type)
GRN_UINT8_SET(ctx, dest, 0);
return GRN_TRUE;
}
+ break;
case GRN_DB_UINT16 :
if (is_negative_value(src)) {
GRN_UINT16_SET(ctx, dest, 0);
return GRN_TRUE;
}
+ break;
case GRN_DB_UINT32 :
if (is_negative_value(src)) {
GRN_UINT32_SET(ctx, dest, 0);
return GRN_TRUE;
}
+ break;
case GRN_DB_UINT64 :
if (is_negative_value(src)) {
GRN_UINT64_SET(ctx, dest, 0);
return GRN_TRUE;
}
- default :
- return grn_obj_cast(ctx, src, dest, GRN_FALSE) == GRN_SUCCESS;
+ break;
}
+ return grn_obj_cast(ctx, src, dest, GRN_FALSE) == GRN_SUCCESS;
}
static inline int
@@ -4600,6 +1485,93 @@ compare_number(grn_ctx *ctx, grn_obj *number1, grn_obj *number2, grn_id type)
#undef COMPARE_AND_RETURN
}
+inline static void
+get_number_in_grn_uvector(grn_ctx *ctx, grn_obj *uvector, unsigned int offset,
+ grn_obj *buf)
+{
+#define GET_UVECTOR_ELEMENT_AS(type) do { \
+ GRN_ ## type ## _SET(ctx, \
+ buf, \
+ GRN_ ## type ## _VALUE_AT(uvector, offset)); \
+ } while (GRN_FALSE)
+ switch (uvector->header.domain) {
+ case GRN_DB_BOOL :
+ GET_UVECTOR_ELEMENT_AS(BOOL);
+ break;
+ case GRN_DB_INT8 :
+ GET_UVECTOR_ELEMENT_AS(INT8);
+ break;
+ case GRN_DB_UINT8 :
+ GET_UVECTOR_ELEMENT_AS(UINT8);
+ break;
+ case GRN_DB_INT16 :
+ GET_UVECTOR_ELEMENT_AS(INT16);
+ break;
+ case GRN_DB_UINT16 :
+ GET_UVECTOR_ELEMENT_AS(UINT16);
+ break;
+ case GRN_DB_INT32 :
+ GET_UVECTOR_ELEMENT_AS(INT32);
+ break;
+ case GRN_DB_UINT32 :
+ GET_UVECTOR_ELEMENT_AS(UINT32);
+ break;
+ case GRN_DB_INT64 :
+ GET_UVECTOR_ELEMENT_AS(INT64);
+ break;
+ case GRN_DB_UINT64 :
+ GET_UVECTOR_ELEMENT_AS(UINT64);
+ break;
+ case GRN_DB_FLOAT :
+ GET_UVECTOR_ELEMENT_AS(FLOAT);
+ break;
+ case GRN_DB_TIME :
+ GET_UVECTOR_ELEMENT_AS(TIME);
+ break;
+ default :
+ GET_UVECTOR_ELEMENT_AS(RECORD);
+ break;
+ }
+#undef GET_UVECTOR_ELEMENT_AS
+}
+
+inline static void
+apply_max(grn_ctx *ctx, grn_obj *number, grn_obj *max,
+ grn_obj *casted_number, grn_obj *casted_max, grn_id cast_type)
+{
+ grn_id domain = number->header.domain;
+ if (!is_comparable_number_type(domain)) {
+ return;
+ }
+ cast_type = larger_number_type(cast_type, domain);
+ if (!number_safe_cast(ctx, number, casted_number, cast_type)) {
+ return;
+ }
+ if (max->header.domain == GRN_DB_VOID) {
+ grn_obj_reinit(ctx, max, cast_type, 0);
+ GRN_TEXT_SET(ctx, max,
+ GRN_TEXT_VALUE(casted_number),
+ GRN_TEXT_LEN(casted_number));
+ return;
+ }
+
+ if (max->header.domain != cast_type) {
+ if (!number_safe_cast(ctx, max, casted_max, cast_type)) {
+ return;
+ }
+ grn_obj_reinit(ctx, max, cast_type, 0);
+ GRN_TEXT_SET(ctx, max,
+ GRN_TEXT_VALUE(casted_max),
+ GRN_TEXT_LEN(casted_max));
+ }
+ if (compare_number(ctx, casted_number, max, cast_type) > 0) {
+ grn_obj_reinit(ctx, max, cast_type, 0);
+ GRN_TEXT_SET(ctx, max,
+ GRN_TEXT_VALUE(casted_number),
+ GRN_TEXT_LEN(casted_number));
+ }
+}
+
static grn_obj *
func_max(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
@@ -4615,38 +1587,37 @@ func_max(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
GRN_VOID_INIT(&casted_max);
GRN_VOID_INIT(&casted_number);
- for (i = 0; i < nargs; i++) {
- grn_obj *number = args[i];
- grn_id domain = number->header.domain;
- if (!is_comparable_number_type(domain)) {
- continue;
- }
- cast_type = larger_number_type(cast_type, domain);
- if (!number_safe_cast(ctx, number, &casted_number, cast_type)) {
- continue;
- }
- if (max->header.domain == GRN_DB_VOID) {
- grn_obj_reinit(ctx, max, cast_type, 0);
- GRN_TEXT_SET(ctx, max,
- GRN_TEXT_VALUE(&casted_number),
- GRN_TEXT_LEN(&casted_number));
- continue;
- }
- if (max->header.domain != cast_type) {
- if (!number_safe_cast(ctx, max, &casted_max, cast_type)) {
- continue;
+ for (i = 0; i < nargs; i++) {
+ switch (args[i]->header.type) {
+ case GRN_BULK :
+ apply_max(ctx, args[i], max, &casted_number, &casted_max, cast_type);
+ break;
+ case GRN_UVECTOR :
+ {
+ unsigned int j;
+ unsigned int n_elements;
+ grn_obj number_in_uvector;
+ grn_obj *domain;
+
+ domain = grn_ctx_at(ctx, args[i]->header.domain);
+ GRN_OBJ_INIT(&number_in_uvector, GRN_BULK, 0, args[i]->header.domain);
+ n_elements = grn_uvector_size(ctx, args[i]);
+ for (j = 0; j < n_elements; j++) {
+ get_number_in_grn_uvector(ctx, args[i], j, &number_in_uvector);
+ if (grn_obj_is_table(ctx, domain)) {
+ grn_obj_reinit(ctx, &number_in_uvector, domain->header.domain, 0);
+ grn_table_get_key2(ctx, domain,
+ GRN_RECORD_VALUE(&number_in_uvector),
+ &number_in_uvector);
+ }
+ apply_max(ctx, &number_in_uvector, max, &casted_number, &casted_max, cast_type);
+ }
+ GRN_OBJ_FIN(ctx, &number_in_uvector);
}
- grn_obj_reinit(ctx, max, cast_type, 0);
- GRN_TEXT_SET(ctx, max,
- GRN_TEXT_VALUE(&casted_max),
- GRN_TEXT_LEN(&casted_max));
- }
- if (compare_number(ctx, &casted_number, max, cast_type) > 0) {
- grn_obj_reinit(ctx, max, cast_type, 0);
- GRN_TEXT_SET(ctx, max,
- GRN_TEXT_VALUE(&casted_number),
- GRN_TEXT_LEN(&casted_number));
+ break;
+ default :
+ continue;
}
}
GRN_OBJ_FIN(ctx, &casted_max);
@@ -4655,6 +1626,43 @@ func_max(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
return max;
}
+static void
+apply_min(grn_ctx *ctx, grn_obj *number, grn_obj *min,
+ grn_obj *casted_number, grn_obj *casted_min, grn_id cast_type)
+{
+ grn_id domain = number->header.domain;
+ if (!is_comparable_number_type(domain)) {
+ return;
+ }
+ cast_type = smaller_number_type(cast_type, domain);
+ if (!number_safe_cast(ctx, number, casted_number, cast_type)) {
+ return;
+ }
+ if (min->header.domain == GRN_DB_VOID) {
+ grn_obj_reinit(ctx, min, cast_type, 0);
+ GRN_TEXT_SET(ctx, min,
+ GRN_TEXT_VALUE(casted_number),
+ GRN_TEXT_LEN(casted_number));
+ return;
+ }
+
+ if (min->header.domain != cast_type) {
+ if (!number_safe_cast(ctx, min, casted_min, cast_type)) {
+ return;
+ }
+ grn_obj_reinit(ctx, min, cast_type, 0);
+ GRN_TEXT_SET(ctx, min,
+ GRN_TEXT_VALUE(casted_min),
+ GRN_TEXT_LEN(casted_min));
+ }
+ if (compare_number(ctx, casted_number, min, cast_type) < 0) {
+ grn_obj_reinit(ctx, min, cast_type, 0);
+ GRN_TEXT_SET(ctx, min,
+ GRN_TEXT_VALUE(casted_number),
+ GRN_TEXT_LEN(casted_number));
+ }
+}
+
static grn_obj *
func_min(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
@@ -4671,37 +1679,35 @@ func_min(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
GRN_VOID_INIT(&casted_min);
GRN_VOID_INIT(&casted_number);
for (i = 0; i < nargs; i++) {
- grn_obj *number = args[i];
- grn_id domain = number->header.domain;
- if (!is_comparable_number_type(domain)) {
- continue;
- }
- cast_type = smaller_number_type(cast_type, domain);
- if (!number_safe_cast(ctx, number, &casted_number, cast_type)) {
- continue;
- }
- if (min->header.domain == GRN_DB_VOID) {
- grn_obj_reinit(ctx, min, cast_type, 0);
- GRN_TEXT_SET(ctx, min,
- GRN_TEXT_VALUE(&casted_number),
- GRN_TEXT_LEN(&casted_number));
- continue;
- }
-
- if (min->header.domain != cast_type) {
- if (!number_safe_cast(ctx, min, &casted_min, cast_type)) {
- continue;
+ switch (args[i]->header.type) {
+ case GRN_BULK :
+ apply_min(ctx, args[i], min, &casted_number, &casted_min, cast_type);
+ break;
+ case GRN_UVECTOR :
+ {
+ unsigned int j;
+ unsigned int n_elements;
+ grn_obj number_in_uvector;
+ grn_obj *domain;
+
+ domain = grn_ctx_at(ctx, args[i]->header.domain);
+ GRN_OBJ_INIT(&number_in_uvector, GRN_BULK, 0, args[i]->header.domain);
+ n_elements = grn_uvector_size(ctx, args[i]);
+ for (j = 0; j < n_elements; j++) {
+ get_number_in_grn_uvector(ctx, args[i], j, &number_in_uvector);
+ if (grn_obj_is_table(ctx, domain)) {
+ grn_obj_reinit(ctx, &number_in_uvector, domain->header.domain, 0);
+ grn_table_get_key2(ctx, domain,
+ GRN_RECORD_VALUE(&number_in_uvector),
+ &number_in_uvector);
+ }
+ apply_min(ctx, &number_in_uvector, min, &casted_number, &casted_min, cast_type);
+ }
+ GRN_OBJ_FIN(ctx, &number_in_uvector);
}
- grn_obj_reinit(ctx, min, cast_type, 0);
- GRN_TEXT_SET(ctx, min,
- GRN_TEXT_VALUE(&casted_min),
- GRN_TEXT_LEN(&casted_min));
- }
- if (compare_number(ctx, &casted_number, min, cast_type) < 0) {
- grn_obj_reinit(ctx, min, cast_type, 0);
- GRN_TEXT_SET(ctx, min,
- GRN_TEXT_VALUE(&casted_number),
- GRN_TEXT_LEN(&casted_number));
+ break;
+ default :
+ continue;
}
}
GRN_OBJ_FIN(ctx, &casted_min);
@@ -4714,7 +1720,7 @@ static grn_obj *
func_geo_in_circle(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
grn_obj *obj;
- unsigned char r = GRN_FALSE;
+ grn_bool r = GRN_FALSE;
grn_geo_approximate_type type = GRN_GEO_APPROXIMATE_RECTANGLE;
switch (nargs) {
case 4 :
@@ -4728,8 +1734,8 @@ func_geo_in_circle(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_
default :
break;
}
- if ((obj = GRN_PROC_ALLOC(GRN_DB_UINT32, 0))) {
- GRN_UINT32_SET(ctx, obj, r);
+ if ((obj = GRN_PROC_ALLOC(GRN_DB_BOOL, 0))) {
+ GRN_BOOL_SET(ctx, obj, r);
}
return obj;
}
@@ -4738,12 +1744,12 @@ static grn_obj *
func_geo_in_rectangle(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
grn_obj *obj;
- unsigned char r = GRN_FALSE;
+ grn_bool r = GRN_FALSE;
if (nargs == 3) {
r = grn_geo_in_rectangle(ctx, args[0], args[1], args[2]);
}
- if ((obj = GRN_PROC_ALLOC(GRN_DB_UINT32, 0))) {
- GRN_UINT32_SET(ctx, obj, r);
+ if ((obj = GRN_PROC_ALLOC(GRN_DB_BOOL, 0))) {
+ GRN_BOOL_SET(ctx, obj, r);
}
return obj;
}
@@ -4802,47 +1808,6 @@ func_geo_distance3(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_
return obj;
}
-#define DIST(ox,oy) (dists[((lx + 1) * (oy)) + (ox)])
-
-static grn_obj *
-func_edit_distance(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- int d = 0;
- grn_obj *obj;
- if (nargs == 2) {
- uint32_t cx, lx, cy, ly, *dists;
- char *px, *sx = GRN_TEXT_VALUE(args[0]), *ex = GRN_BULK_CURR(args[0]);
- char *py, *sy = GRN_TEXT_VALUE(args[1]), *ey = GRN_BULK_CURR(args[1]);
- for (px = sx, lx = 0; px < ex && (cx = grn_charlen(ctx, px, ex)); px += cx, lx++);
- for (py = sy, ly = 0; py < ey && (cy = grn_charlen(ctx, py, ey)); py += cy, ly++);
- if ((dists = GRN_MALLOC((lx + 1) * (ly + 1) * sizeof(uint32_t)))) {
- uint32_t x, y;
- for (x = 0; x <= lx; x++) { DIST(x, 0) = x; }
- for (y = 0; y <= ly; y++) { DIST(0, y) = y; }
- for (x = 1, px = sx; x <= lx; x++, px += cx) {
- cx = grn_charlen(ctx, px, ex);
- for (y = 1, py = sy; y <= ly; y++, py += cy) {
- cy = grn_charlen(ctx, py, ey);
- if (cx == cy && !memcmp(px, py, cx)) {
- DIST(x, y) = DIST(x - 1, y - 1);
- } else {
- uint32_t a = DIST(x - 1, y) + 1;
- uint32_t b = DIST(x, y - 1) + 1;
- uint32_t c = DIST(x - 1, y - 1) + 1;
- DIST(x, y) = ((a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c));
- }
- }
- }
- d = DIST(lx, ly);
- GRN_FREE(dists);
- }
- }
- if ((obj = GRN_PROC_ALLOC(GRN_DB_UINT32, 0))) {
- GRN_UINT32_SET(ctx, obj, d);
- }
- return obj;
-}
-
static grn_obj *
func_all_records(grn_ctx *ctx, int nargs, grn_obj **args,
grn_user_data *user_data)
@@ -4859,9 +1824,9 @@ selector_all_records(grn_ctx *ctx, grn_obj *table, grn_obj *index,
int nargs, grn_obj **args,
grn_obj *res, grn_operator op)
{
- grn_ii_posting posting;
+ grn_posting posting;
- memset(&posting, 0, sizeof(grn_ii_posting));
+ memset(&posting, 0, sizeof(grn_posting));
GRN_TABLE_EACH(ctx, table, 0, 0, id, NULL, NULL, NULL, {
posting.rid = id;
grn_ii_posting_add(ctx, &posting, (grn_hash *)res, GRN_OP_OR);
@@ -4870,108 +1835,6 @@ selector_all_records(grn_ctx *ctx, grn_obj *table, grn_obj *index,
return ctx->rc;
}
-static grn_obj *
-snippet_exec(grn_ctx *ctx, grn_obj *snip, grn_obj *text,
- grn_user_data *user_data)
-{
- grn_rc rc;
- unsigned int i, n_results, max_tagged_length;
- grn_obj snippet_buffer;
- grn_obj *snippets;
-
- if (GRN_TEXT_LEN(text) == 0) {
- return NULL;
- }
-
- rc = grn_snip_exec(ctx, snip,
- GRN_TEXT_VALUE(text), GRN_TEXT_LEN(text),
- &n_results, &max_tagged_length);
- if (rc != GRN_SUCCESS) {
- return NULL;
- }
-
- if (n_results == 0) {
- return GRN_PROC_ALLOC(GRN_DB_VOID, 0);
- }
-
- snippets = GRN_PROC_ALLOC(GRN_DB_SHORT_TEXT, GRN_OBJ_VECTOR);
- if (!snippets) {
- return NULL;
- }
-
- GRN_TEXT_INIT(&snippet_buffer, 0);
- grn_bulk_space(ctx, &snippet_buffer, max_tagged_length);
- for (i = 0; i < n_results; i++) {
- unsigned int snippet_length;
-
- GRN_BULK_REWIND(&snippet_buffer);
- rc = grn_snip_get_result(ctx, snip, i,
- GRN_TEXT_VALUE(&snippet_buffer),
- &snippet_length);
- if (rc == GRN_SUCCESS) {
- grn_vector_add_element(ctx, snippets,
- GRN_TEXT_VALUE(&snippet_buffer), snippet_length,
- 0, GRN_DB_SHORT_TEXT);
- }
- }
- GRN_OBJ_FIN(ctx, &snippet_buffer);
-
- return snippets;
-}
-
-static grn_obj *
-func_snippet_html(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- grn_obj *snippets = NULL;
-
- /* TODO: support parameters */
- if (nargs == 1) {
- grn_obj *text = args[0];
- grn_obj *expression = NULL;
- grn_obj *condition_ptr = NULL;
- grn_obj *condition = NULL;
- grn_obj *snip = NULL;
- int flags = GRN_SNIP_SKIP_LEADING_SPACES;
- unsigned int width = 200;
- unsigned int max_n_results = 3;
- const char *open_tag = "<span class=\"keyword\">";
- const char *close_tag = "</span>";
- grn_snip_mapping *mapping = GRN_SNIP_MAPPING_HTML_ESCAPE;
-
- grn_proc_get_info(ctx, user_data, NULL, NULL, &expression);
- condition_ptr = grn_expr_get_var(ctx, expression,
- GRN_SELECT_INTERNAL_VAR_CONDITION,
- strlen(GRN_SELECT_INTERNAL_VAR_CONDITION));
- if (condition_ptr) {
- condition = GRN_PTR_VALUE(condition_ptr);
- }
-
- if (condition) {
- snip = grn_snip_open(ctx, flags, width, max_n_results,
- open_tag, strlen(open_tag),
- close_tag, strlen(close_tag),
- mapping);
- if (snip) {
- grn_snip_set_normalizer(ctx, snip, GRN_NORMALIZER_AUTO);
- grn_expr_snip_add_conditions(ctx, condition, snip,
- 0, NULL, NULL, NULL, NULL);
- }
- }
-
- if (snip) {
- snippets = snippet_exec(ctx, snip, text, user_data);
- grn_obj_close(ctx, snip);
- }
- }
-
- if (!snippets) {
- snippets = GRN_PROC_ALLOC(GRN_DB_VOID, 0);
- }
-
- return snippets;
-}
-
typedef struct {
grn_obj *found;
grn_obj *table;
@@ -5045,10 +1908,83 @@ selector_to_function_data_fin(grn_ctx *ctx,
if (data->records) {
grn_obj_unlink(ctx, data->records);
}
+}
- if (data->table) {
- grn_obj_unlink(ctx, data->table);
- }
+grn_operator
+grn_proc_option_value_mode(grn_ctx *ctx,
+ grn_obj *option,
+ grn_operator default_mode,
+ const char *context)
+{
+ if (option->header.domain != GRN_DB_TEXT) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, option);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "%s: mode must be text: <%.*s>",
+ context,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return GRN_OP_NOP;
+ }
+
+ if (GRN_TEXT_LEN(option) == 0) {
+ return default_mode;
+ }
+
+#define EQUAL_MODE(name) \
+ (GRN_TEXT_LEN(option) == strlen(name) && \
+ memcmp(GRN_TEXT_VALUE(option), name, strlen(name)) == 0)
+
+ if (EQUAL_MODE("==") || EQUAL_MODE("EQUAL")) {
+ return GRN_OP_EQUAL;
+ } else if (EQUAL_MODE("!=") || EQUAL_MODE("NOT_EQUAL")) {
+ return GRN_OP_NOT_EQUAL;
+ } else if (EQUAL_MODE("<") || EQUAL_MODE("LESS")) {
+ return GRN_OP_LESS;
+ } else if (EQUAL_MODE(">") || EQUAL_MODE("GREATER")) {
+ return GRN_OP_GREATER;
+ } else if (EQUAL_MODE("<=") || EQUAL_MODE("LESS_EQUAL")) {
+ return GRN_OP_LESS_EQUAL;
+ } else if (EQUAL_MODE(">=") || EQUAL_MODE("GREATER_EQUAL")) {
+ return GRN_OP_GREATER_EQUAL;
+ } else if (EQUAL_MODE("@") || EQUAL_MODE("MATCH")) {
+ return GRN_OP_MATCH;
+ } else if (EQUAL_MODE("*N") || EQUAL_MODE("NEAR")) {
+ return GRN_OP_NEAR;
+ } else if (EQUAL_MODE("*S") || EQUAL_MODE("SIMILAR")) {
+ return GRN_OP_SIMILAR;
+ } else if (EQUAL_MODE("^") || EQUAL_MODE("@^") || EQUAL_MODE("PREFIX")) {
+ return GRN_OP_PREFIX;
+ } else if (EQUAL_MODE("$") || EQUAL_MODE("@$") || EQUAL_MODE("SUFFIX")) {
+ return GRN_OP_SUFFIX;
+ } else if (EQUAL_MODE("~") || EQUAL_MODE("@~") || EQUAL_MODE("REGEXP")) {
+ return GRN_OP_REGEXP;
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "%s: mode must be one of them: "
+ "["
+ "\"==\", \"EQUAL\", "
+ "\"!=\", \"NOT_EQUAL\", "
+ "\"<\", \"LESS\", "
+ "\">\", \"GREATER\", "
+ "\"<=\", \"LESS_EQUAL\", "
+ "\">=\", \"GREATER_EQUAL\", "
+ "\"@\", \"MATCH\", "
+ "\"*N\", \"NEAR\", "
+ "\"*S\", \"SIMILAR\", "
+ "\"^\", \"@^\", \"PREFIX\", "
+ "\"$\", \"@$\", \"SUFFIX\", "
+ "\"~\", \"@~\", \"REGEXP\""
+ "]: <%.*s>",
+ context,
+ (int)GRN_TEXT_LEN(option),
+ GRN_TEXT_VALUE(option));
+ return GRN_OP_NOP;
+ }
+
+#undef EQUAL_MODE
}
static grn_rc
@@ -5060,14 +1996,16 @@ run_query(grn_ctx *ctx, grn_obj *table,
grn_obj *match_columns_string;
grn_obj *query;
grn_obj *query_expander_name = NULL;
+ grn_operator default_mode = GRN_OP_MATCH;
+ grn_expr_flags flags = GRN_EXPR_SYNTAX_QUERY;
+ grn_bool flags_specified = GRN_FALSE;
grn_obj *match_columns = NULL;
grn_obj *condition = NULL;
grn_obj *dummy_variable;
- /* TODO: support flags by parameters */
if (!(2 <= nargs && nargs <= 3)) {
ERR(GRN_INVALID_ARGUMENT,
- "wrong number of arguments (%d for 2..3)", nargs);
+ "query(): wrong number of arguments (%d for 2..3)", nargs);
rc = ctx->rc;
goto exit;
}
@@ -5075,7 +2013,88 @@ run_query(grn_ctx *ctx, grn_obj *table,
match_columns_string = args[0];
query = args[1];
if (nargs > 2) {
- query_expander_name = args[2];
+ grn_obj *options = args[2];
+
+ switch (options->header.type) {
+ case GRN_BULK :
+ query_expander_name = options;
+ break;
+ case GRN_TABLE_HASH_KEY :
+ {
+ grn_hash_cursor *cursor;
+ void *key;
+ grn_obj *value;
+ int key_size;
+ cursor = grn_hash_cursor_open(ctx, (grn_hash *)options,
+ NULL, 0, NULL, 0,
+ 0, -1, 0);
+ if (!cursor) {
+ GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE,
+ "query(): failed to open cursor for options");
+ rc = ctx->rc;
+ goto exit;
+ }
+ while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ grn_hash_cursor_get_key_value(ctx, cursor, &key, &key_size,
+ (void **)&value);
+
+#define KEY_EQUAL(name) \
+ (key_size == strlen(name) && memcmp(key, name, strlen(name)) == 0)
+ if (KEY_EQUAL("expander")) {
+ query_expander_name = value;
+ } else if (KEY_EQUAL("default_mode")) {
+ default_mode = grn_proc_option_value_mode(ctx,
+ value,
+ GRN_OP_MATCH,
+ "query()");
+ if (ctx->rc != GRN_SUCCESS) {
+ grn_hash_cursor_close(ctx, cursor);
+ rc = ctx->rc;
+ goto exit;
+ }
+ } else if (KEY_EQUAL("flags")) {
+ flags_specified = GRN_TRUE;
+ flags |= grn_proc_expr_query_flags_parse(ctx,
+ GRN_TEXT_VALUE(value),
+ GRN_TEXT_LEN(value),
+ "query()");
+ if (ctx->rc != GRN_SUCCESS) {
+ grn_hash_cursor_close(ctx, cursor);
+ rc = ctx->rc;
+ goto exit;
+ }
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "query(): unknown option name: <%.*s>",
+ key_size, (char *)key);
+ grn_hash_cursor_close(ctx, cursor);
+ rc = ctx->rc;
+ goto exit;
+ }
+#undef KEY_EQUAL
+ }
+ grn_hash_cursor_close(ctx, cursor);
+ }
+ break;
+ default :
+ {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, options);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "query(): "
+ "3rd argument must be string or object literal: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ }
+ rc = ctx->rc;
+ goto exit;
+ }
+ }
+
+ if (!flags_specified) {
+ flags |= GRN_EXPR_ALLOW_PRAGMA | GRN_EXPR_ALLOW_COLUMN;
}
if (match_columns_string->header.domain == GRN_DB_TEXT &&
@@ -5101,8 +2120,6 @@ run_query(grn_ctx *ctx, grn_obj *table,
const char *query_string;
unsigned int query_string_len;
grn_obj expanded_query;
- grn_expr_flags flags =
- GRN_EXPR_SYNTAX_QUERY|GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN;
GRN_EXPR_CREATE_FOR_QUERY(ctx, table, condition, dummy_variable);
if (!condition) {
@@ -5117,10 +2134,15 @@ run_query(grn_ctx *ctx, grn_obj *table,
if (query_expander_name &&
query_expander_name->header.domain == GRN_DB_TEXT &&
GRN_TEXT_LEN(query_expander_name) > 0) {
- rc = expand_query(ctx, query_string, query_string_len, flags,
- GRN_TEXT_VALUE(query_expander_name),
- GRN_TEXT_LEN(query_expander_name),
- &expanded_query);
+ rc = grn_proc_syntax_expand_query(ctx,
+ query_string, query_string_len,
+ flags,
+ GRN_TEXT_VALUE(query_expander_name),
+ GRN_TEXT_LEN(query_expander_name),
+ NULL, 0,
+ NULL, 0,
+ &expanded_query,
+ "[query]");
if (rc != GRN_SUCCESS) {
GRN_OBJ_FIN(ctx, &expanded_query);
goto exit;
@@ -5131,7 +2153,7 @@ run_query(grn_ctx *ctx, grn_obj *table,
grn_expr_parse(ctx, condition,
query_string,
query_string_len,
- match_columns, GRN_OP_MATCH, GRN_OP_AND, flags);
+ match_columns, default_mode, GRN_OP_AND, flags);
rc = ctx->rc;
GRN_OBJ_FIN(ctx, &expanded_query);
if (rc != GRN_SUCCESS) {
@@ -5248,14 +2270,13 @@ run_sub_filter(grn_ctx *ctx, grn_obj *table,
{
grn_obj *base_res = NULL;
- grn_obj *resolve_res = NULL;
base_res = grn_table_create(ctx, NULL, 0, NULL,
GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
scope_domain, NULL);
grn_table_select(ctx, scope_domain, sub_filter, base_res, GRN_OP_OR);
if (scope->header.type == GRN_ACCESSOR) {
- rc = grn_accessor_resolve(ctx, scope, -1, base_res, &resolve_res, NULL);
+ rc = grn_accessor_resolve(ctx, scope, -1, base_res, res, op);
} else {
grn_accessor accessor;
accessor.header.type = GRN_ACCESSOR;
@@ -5263,11 +2284,7 @@ run_sub_filter(grn_ctx *ctx, grn_obj *table,
accessor.action = GRN_ACCESSOR_GET_COLUMN_VALUE;
accessor.next = NULL;
rc = grn_accessor_resolve(ctx, (grn_obj *)&accessor, -1, base_res,
- &resolve_res, NULL);
- }
- if (resolve_res) {
- rc = grn_table_setoperation(ctx, res, resolve_res, res, op);
- grn_obj_unlink(ctx, resolve_res);
+ res, op);
}
grn_obj_unlink(ctx, base_res);
}
@@ -5283,23 +2300,6 @@ exit :
return rc;
}
-static grn_obj *
-func_sub_filter(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- selector_to_function_data data;
-
- if (selector_to_function_data_init(ctx, &data, user_data)) {
- grn_rc rc;
- rc = run_sub_filter(ctx, data.table, nargs, args, data.records, GRN_OP_AND);
- if (rc == GRN_SUCCESS) {
- selector_to_function_data_selected(ctx, &data);
- }
- }
- selector_to_function_data_fin(ctx, &data);
-
- return data.found;
-}
-
static grn_rc
selector_sub_filter(grn_ctx *ctx, grn_obj *table, grn_obj *index,
int nargs, grn_obj **args,
@@ -5520,10 +2520,20 @@ between_parse_args(grn_ctx *ctx, int nargs, grn_obj **args, between_data *data)
{
grn_id value_type;
- if (data->value->header.type == GRN_BULK) {
+ switch (data->value->header.type) {
+ case GRN_BULK :
value_type = data->value->header.domain;
- } else {
+ break;
+ case GRN_COLUMN_INDEX :
+ {
+ grn_obj *domain_object;
+ domain_object = grn_ctx_at(ctx, data->value->header.domain);
+ value_type = domain_object->header.domain;
+ }
+ break;
+ default :
value_type = grn_obj_get_range(ctx, data->value);
+ break;
}
if (value_type != data->min->header.domain) {
rc = between_cast(ctx, data->min, &data->casted_min, value_type, "min");
@@ -5629,12 +2639,8 @@ func_between(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
GRN_RECORD_SET(ctx, between_variable, GRN_RECORD_VALUE(variable));
result = grn_expr_exec(ctx, between_expr, 0);
- if (result) {
- grn_bool result_boolean;
- GRN_TRUEP(ctx, result, result_boolean);
- if (result_boolean) {
- GRN_BOOL_SET(ctx, found, GRN_TRUE);
- }
+ if (grn_obj_is_true(ctx, result)) {
+ GRN_BOOL_SET(ctx, found, GRN_TRUE);
}
grn_obj_unlink(ctx, between_expr);
@@ -5669,10 +2675,18 @@ selector_between_sequential_search_should_use(grn_ctx *ctx,
return GRN_FALSE;
}
+ if (!index) {
+ return GRN_FALSE;
+ }
+
if (index->header.flags & GRN_OBJ_WITH_WEIGHT) {
return GRN_FALSE;
}
+ if (data->value->header.type == GRN_COLUMN_INDEX) {
+ return GRN_FALSE;
+ }
+
n_index_keys = grn_table_size(ctx, index_table);
if (n_index_keys == 0) {
return GRN_FALSE;
@@ -5775,94 +2789,115 @@ selector_between_sequential_search_should_use(grn_ctx *ctx,
return GRN_TRUE;
}
-static grn_bool
+static grn_rc
selector_between_sequential_search(grn_ctx *ctx,
grn_obj *table,
- grn_obj *index, grn_obj *index_table,
between_data *data,
- grn_obj *res, grn_operator op)
+ grn_obj *res,
+ grn_operator op)
{
- if (!selector_between_sequential_search_should_use(
- ctx, table, index, index_table, data, res, op,
- grn_between_too_many_index_match_ratio)) {
- return GRN_FALSE;
- }
-
{
int offset = 0;
int limit = -1;
int flags = 0;
+ grn_obj *target_table;
+ grn_obj *target_column;
+ grn_operator_exec_func *greater;
+ grn_operator_exec_func *less;
grn_table_cursor *cursor;
- grn_obj *expr;
- grn_obj *variable;
grn_id id;
+ grn_obj value;
- if (!between_create_expr(ctx, table, data, &expr, &variable)) {
- return GRN_FALSE;
+ if (op == GRN_OP_AND) {
+ target_table = res;
+ } else {
+ target_table = table;
}
-
- cursor = grn_table_cursor_open(ctx, res,
+ cursor = grn_table_cursor_open(ctx, target_table,
NULL, 0,
NULL, 0,
offset, limit, flags);
if (!cursor) {
- grn_obj_unlink(ctx, expr);
- return GRN_FALSE;
+ return ctx->rc;
}
+ if (data->value->header.type == GRN_BULK) {
+ target_column = grn_obj_column(ctx,
+ table,
+ GRN_TEXT_VALUE(data->value),
+ GRN_TEXT_LEN(data->value));
+ } else {
+ target_column = data->value;
+ }
+ if (data->min_border_type == BETWEEN_BORDER_INCLUDE) {
+ greater = grn_operator_exec_greater_equal;
+ } else {
+ greater = grn_operator_exec_greater;
+ }
+ if (data->max_border_type == BETWEEN_BORDER_INCLUDE) {
+ less = grn_operator_exec_less_equal;
+ } else {
+ less = grn_operator_exec_less;
+ }
+
+ GRN_VOID_INIT(&value);
while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
grn_id record_id;
- grn_obj *result;
- {
+
+ if (target_table == res) {
grn_id *key;
grn_table_cursor_get_key(ctx, cursor, (void **)&key);
record_id = *key;
+ } else {
+ record_id = id;
}
- GRN_RECORD_SET(ctx, variable, record_id);
- result = grn_expr_exec(ctx, expr, 0);
- if (ctx->rc) {
- break;
- }
- if (result) {
- grn_bool result_boolean;
- GRN_TRUEP(ctx, result, result_boolean);
- if (result_boolean) {
- grn_ii_posting posting;
- posting.rid = record_id;
- posting.sid = 1;
- posting.pos = 0;
- posting.weight = 0;
- grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
- }
+
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx, target_column, record_id, &value);
+ if (greater(ctx, &value, data->min) && less(ctx, &value, data->max)) {
+ grn_posting posting;
+ posting.rid = record_id;
+ posting.sid = 1;
+ posting.pos = 0;
+ posting.weight = 0;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
}
}
- grn_obj_unlink(ctx, expr);
+
+ GRN_OBJ_FIN(ctx, &value);
+
+ if (target_column != data->value &&
+ target_column->header.type == GRN_ACCESSOR) {
+ grn_obj_unlink(ctx, target_column);
+ }
+
grn_table_cursor_close(ctx, cursor);
grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
}
- return GRN_TRUE;
+ return GRN_SUCCESS;
}
static grn_rc
-selector_between(grn_ctx *ctx, grn_obj *table, grn_obj *index,
- int nargs, grn_obj **args,
- grn_obj *res, grn_operator op)
+selector_between(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ int nargs,
+ grn_obj **args,
+ grn_obj *res,
+ grn_operator op)
{
grn_rc rc = GRN_SUCCESS;
int offset = 0;
int limit = -1;
int flags = GRN_CURSOR_ASCENDING | GRN_CURSOR_BY_KEY;
between_data data;
+ grn_bool use_sequential_search;
grn_obj *index_table = NULL;
grn_table_cursor *cursor;
grn_id id;
- if (!index) {
- return GRN_INVALID_ARGUMENT;
- }
-
between_data_init(ctx, &data);
rc = between_parse_args(ctx, nargs - 1, args + 1, &data);
if (rc != GRN_SUCCESS) {
@@ -5876,9 +2911,42 @@ selector_between(grn_ctx *ctx, grn_obj *table, grn_obj *index,
flags |= GRN_CURSOR_LT;
}
- index_table = grn_ctx_at(ctx, index->header.domain);
- if (selector_between_sequential_search(ctx, table, index, index_table,
- &data, res, op)) {
+ if (data.value->header.type == GRN_COLUMN_INDEX) {
+ index = data.value;
+ }
+
+ if (index) {
+ switch (index->header.type) {
+ case GRN_TABLE_NO_KEY :
+ case GRN_TABLE_HASH_KEY :
+ break;
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ index_table = index;
+ index = NULL;
+ break;
+ default :
+ index_table = grn_ctx_at(ctx, index->header.domain);
+ break;
+ }
+ }
+
+ if (index_table) {
+ double ratio = grn_between_too_many_index_match_ratio;
+ use_sequential_search =
+ selector_between_sequential_search_should_use(ctx,
+ table,
+ index,
+ index_table,
+ &data,
+ res,
+ op,
+ ratio);
+ } else {
+ use_sequential_search = GRN_TRUE;
+ }
+ if (use_sequential_search) {
+ rc = selector_between_sequential_search(ctx, table, &data, res, op);
goto exit;
}
@@ -5893,288 +2961,29 @@ selector_between(grn_ctx *ctx, grn_obj *table, grn_obj *index,
goto exit;
}
- while ((id = grn_table_cursor_next(ctx, cursor))) {
- grn_ii_at(ctx, (grn_ii *)index, id, (grn_hash *)res, op);
+ if (index) {
+ while ((id = grn_table_cursor_next(ctx, cursor))) {
+ grn_ii_at(ctx, (grn_ii *)index, id, (grn_hash *)res, op);
+ }
+ } else {
+ grn_posting posting;
+ memset(&posting, 0, sizeof(grn_posting));
+ posting.sid = 1;
+ posting.pos = 0;
+ while ((id = grn_table_cursor_next(ctx, cursor))) {
+ posting.rid = id;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
+ }
}
grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
grn_table_cursor_close(ctx, cursor);
exit :
between_data_fin(ctx, &data);
- if (index_table) {
- grn_obj_unlink(ctx, index_table);
- }
return rc;
}
-static void
-grn_pat_tag_keys_put_original_text(grn_ctx *ctx, grn_obj *output,
- const char *text, unsigned int length,
- grn_bool use_html_escape)
-{
- if (use_html_escape) {
- grn_text_escape_xml(ctx, output, text, length);
- } else {
- GRN_TEXT_PUT(ctx, output, text, length);
- }
-}
-
-static grn_rc
-grn_pat_tag_keys(grn_ctx *ctx, grn_obj *keywords,
- const char *string, unsigned int string_length,
- const char **open_tags, unsigned int *open_tag_lengths,
- const char **close_tags, unsigned int *close_tag_lengths,
- unsigned int n_tags,
- grn_obj *highlighted,
- grn_bool use_html_escape)
-{
- while (string_length > 0) {
-#define MAX_N_HITS 1024
- grn_pat_scan_hit hits[MAX_N_HITS];
- const char *rest;
- unsigned int i, n_hits;
- unsigned int previous = 0;
-
- n_hits = grn_pat_scan(ctx, (grn_pat *)keywords,
- string, string_length,
- hits, MAX_N_HITS, &rest);
- for (i = 0; i < n_hits; i++) {
- unsigned int nth_tag;
- if (hits[i].offset - previous > 0) {
- grn_pat_tag_keys_put_original_text(ctx,
- highlighted,
- string + previous,
- hits[i].offset - previous,
- use_html_escape);
- }
- nth_tag = ((hits[i].id - 1) % n_tags);
- GRN_TEXT_PUT(ctx, highlighted,
- open_tags[nth_tag], open_tag_lengths[nth_tag]);
- grn_pat_tag_keys_put_original_text(ctx,
- highlighted,
- string + hits[i].offset,
- hits[i].length,
- use_html_escape);
- GRN_TEXT_PUT(ctx, highlighted,
- close_tags[nth_tag], close_tag_lengths[nth_tag]);
- previous = hits[i].offset + hits[i].length;
- }
- if (string_length - previous > 0) {
- grn_pat_tag_keys_put_original_text(ctx,
- highlighted,
- string + previous,
- string_length - previous,
- use_html_escape);
- }
- string_length -= rest - string;
- string = rest;
-#undef MAX_N_HITS
- }
-
- return GRN_SUCCESS;
-}
-
-static grn_obj *
-func_highlight_html(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- grn_obj *highlighted = NULL;
-
-#define N_REQUIRED_ARGS 1
- if (nargs == N_REQUIRED_ARGS) {
- grn_obj *string = args[0];
- grn_obj *expression = NULL;
- grn_obj *condition_ptr = NULL;
- grn_obj *condition = NULL;
- grn_bool use_html_escape = GRN_TRUE;
- unsigned int n_keyword_sets = 1;
- const char *open_tags[1];
- unsigned int open_tag_lengths[1];
- const char *close_tags[1];
- unsigned int close_tag_lengths[1];
- grn_obj *keywords;
-
- open_tags[0] = "<span class=\"keyword\">";
- open_tag_lengths[0] = strlen("<span class=\"keyword\">");
- close_tags[0] = "</span>";
- close_tag_lengths[0] = strlen("</span>");
-
- keywords = grn_table_create(ctx, NULL, 0, NULL,
- GRN_OBJ_TABLE_PAT_KEY,
- grn_ctx_at(ctx, GRN_DB_SHORT_TEXT),
- NULL);
- {
- grn_obj *normalizer;
- normalizer = grn_ctx_get(ctx, "NormalizerAuto", -1);
- grn_obj_set_info(ctx, keywords, GRN_INFO_NORMALIZER, normalizer);
- grn_obj_unlink(ctx, normalizer);
- }
-
- grn_proc_get_info(ctx, user_data, NULL, NULL, &expression);
- condition_ptr = grn_expr_get_var(ctx, expression,
- GRN_SELECT_INTERNAL_VAR_CONDITION,
- strlen(GRN_SELECT_INTERNAL_VAR_CONDITION));
- if (condition_ptr) {
- condition = GRN_PTR_VALUE(condition_ptr);
- }
-
- if (condition) {
- size_t i, n_keywords;
- grn_obj current_keywords;
- GRN_PTR_INIT(&current_keywords, GRN_OBJ_VECTOR, GRN_ID_NIL);
- grn_expr_get_keywords(ctx, condition, &current_keywords);
-
- n_keywords = GRN_BULK_VSIZE(&current_keywords) / sizeof(grn_obj *);
- for (i = 0; i < n_keywords; i++) {
- grn_obj *keyword;
- keyword = GRN_PTR_VALUE_AT(&current_keywords, i);
- grn_table_add(ctx, keywords,
- GRN_TEXT_VALUE(keyword),
- GRN_TEXT_LEN(keyword),
- NULL);
- }
- grn_obj_unlink(ctx, &current_keywords);
- }
-
- highlighted = GRN_PROC_ALLOC(GRN_DB_TEXT, 0);
- grn_pat_tag_keys(ctx, keywords,
- GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string),
- open_tags,
- open_tag_lengths,
- close_tags,
- close_tag_lengths,
- n_keyword_sets,
- highlighted,
- use_html_escape);
-
- grn_obj_unlink(ctx, keywords);
- }
-#undef N_REQUIRED_ARGS
-
- if (!highlighted) {
- highlighted = GRN_PROC_ALLOC(GRN_DB_VOID, 0);
- }
-
- return highlighted;
-}
-
-static grn_obj *
-func_highlight_full(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- grn_obj *highlighted = NULL;
-
-#define N_REQUIRED_ARGS 3
-#define KEYWORD_SET_SIZE 3
- if (nargs >= (N_REQUIRED_ARGS + KEYWORD_SET_SIZE) &&
- (nargs - N_REQUIRED_ARGS) % KEYWORD_SET_SIZE == 0) {
- grn_obj *string = args[0];
- grn_obj *normalizer_name = args[1];
- grn_obj *use_html_escape = args[2];
- grn_obj **keyword_set_args = args + N_REQUIRED_ARGS;
- unsigned int n_keyword_sets = (nargs - N_REQUIRED_ARGS) / KEYWORD_SET_SIZE;
- unsigned int i;
- grn_obj open_tags;
- grn_obj open_tag_lengths;
- grn_obj close_tags;
- grn_obj close_tag_lengths;
- grn_obj *keywords;
-
- keywords = grn_table_create(ctx, NULL, 0, NULL,
- GRN_OBJ_TABLE_PAT_KEY,
- grn_ctx_at(ctx, GRN_DB_SHORT_TEXT),
- NULL);
-
- if (GRN_TEXT_LEN(normalizer_name)) {
- grn_obj *normalizer;
- normalizer = grn_ctx_get(ctx,
- GRN_TEXT_VALUE(normalizer_name),
- GRN_TEXT_LEN(normalizer_name));
- if (!is_normalizer(ctx, normalizer)) {
- grn_obj inspected;
- GRN_TEXT_INIT(&inspected, 0);
- grn_inspect(ctx, &inspected, normalizer);
- ERR(GRN_INVALID_ARGUMENT,
- "[highlight_full] not normalizer: %.*s",
- (int)GRN_TEXT_LEN(&inspected),
- GRN_TEXT_VALUE(&inspected));
- GRN_OBJ_FIN(ctx, &inspected);
- grn_obj_unlink(ctx, normalizer);
- grn_obj_unlink(ctx, keywords);
- return NULL;
- }
- grn_obj_set_info(ctx, keywords, GRN_INFO_NORMALIZER, normalizer);
- grn_obj_unlink(ctx, normalizer);
- }
-
- GRN_OBJ_INIT(&open_tags, GRN_BULK, 0, GRN_DB_VOID);
- GRN_OBJ_INIT(&open_tag_lengths, GRN_BULK, 0, GRN_DB_VOID);
- GRN_OBJ_INIT(&close_tags, GRN_BULK, 0, GRN_DB_VOID);
- GRN_OBJ_INIT(&close_tag_lengths, GRN_BULK, 0, GRN_DB_VOID);
- for (i = 0; i < n_keyword_sets; i++) {
- grn_obj *keyword = keyword_set_args[i * KEYWORD_SET_SIZE + 0];
- grn_obj *open_tag = keyword_set_args[i * KEYWORD_SET_SIZE + 1];
- grn_obj *close_tag = keyword_set_args[i * KEYWORD_SET_SIZE + 2];
-
- grn_table_add(ctx, keywords,
- GRN_TEXT_VALUE(keyword),
- GRN_TEXT_LEN(keyword),
- NULL);
-
- {
- const char *open_tag_content = GRN_TEXT_VALUE(open_tag);
- grn_bulk_write(ctx, &open_tags,
- (const char *)(&open_tag_content),
- sizeof(char *));
- }
- {
- unsigned int open_tag_length = GRN_TEXT_LEN(open_tag);
- grn_bulk_write(ctx, &open_tag_lengths,
- (const char *)(&open_tag_length),
- sizeof(unsigned int));
- }
- {
- const char *close_tag_content = GRN_TEXT_VALUE(close_tag);
- grn_bulk_write(ctx, &close_tags,
- (const char *)(&close_tag_content),
- sizeof(char *));
- }
- {
- unsigned int close_tag_length = GRN_TEXT_LEN(close_tag);
- grn_bulk_write(ctx, &close_tag_lengths,
- (const char *)(&close_tag_length),
- sizeof(unsigned int));
- }
- }
-
- highlighted = GRN_PROC_ALLOC(GRN_DB_TEXT, 0);
- grn_pat_tag_keys(ctx, keywords,
- GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string),
- (const char **)GRN_BULK_HEAD(&open_tags),
- (unsigned int *)GRN_BULK_HEAD(&open_tag_lengths),
- (const char **)GRN_BULK_HEAD(&close_tags),
- (unsigned int *)GRN_BULK_HEAD(&close_tag_lengths),
- n_keyword_sets,
- highlighted,
- GRN_BOOL_VALUE(use_html_escape));
-
- grn_obj_unlink(ctx, keywords);
- grn_obj_unlink(ctx, &open_tags);
- grn_obj_unlink(ctx, &open_tag_lengths);
- grn_obj_unlink(ctx, &close_tags);
- grn_obj_unlink(ctx, &close_tag_lengths);
- }
-#undef N_REQUIRED_ARGS
-#undef KEYWORD_SET_SIZE
-
- if (!highlighted) {
- highlighted = GRN_PROC_ALLOC(GRN_DB_VOID, 0);
- }
-
- return highlighted;
-}
-
static grn_obj *
func_in_values(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
@@ -6359,24 +3168,49 @@ selector_in_values_sequential_search(grn_ctx *ctx,
local_source_name_length);
{
grn_table_cursor *cursor;
- grn_id record_id;
+ grn_id id;
grn_obj record_value;
- GRN_RECORD_INIT(&record_value, 0, grn_obj_id(ctx, res));
+
+ GRN_VOID_INIT(&record_value);
cursor = grn_table_cursor_open(ctx, res,
NULL, 0, NULL, 0,
0, -1, GRN_CURSOR_ASCENDING);
- while ((record_id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ grn_id *record_id;
+ grn_table_cursor_get_key(ctx, cursor, (void **)&record_id);
GRN_BULK_REWIND(&record_value);
- grn_obj_get_value(ctx, accessor, record_id, &record_value);
+ grn_obj_get_value(ctx, accessor, id, &record_value);
for (i = 0; i < n_value_ids; i++) {
grn_id value_id = GRN_RECORD_VALUE_AT(&value_ids, i);
- if (value_id == GRN_RECORD_VALUE(&record_value)) {
- grn_ii_posting posting;
- posting.rid = record_id;
- posting.sid = 1;
- posting.pos = 0;
- posting.weight = 0;
- grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
+ switch (record_value.header.type) {
+ case GRN_BULK :
+ if (value_id == GRN_RECORD_VALUE(&record_value)) {
+ grn_posting posting;
+ posting.rid = *record_id;
+ posting.sid = 1;
+ posting.pos = 0;
+ posting.weight = 0;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
+ }
+ break;
+ case GRN_UVECTOR :
+ {
+ int j, n_elements;
+ n_elements = GRN_BULK_VSIZE(&record_value) / sizeof(grn_id);
+ for (j = 0; j < n_elements; j++) {
+ if (value_id == GRN_RECORD_VALUE_AT(&record_value, j)) {
+ grn_posting posting;
+ posting.rid = *record_id;
+ posting.sid = 1;
+ posting.pos = 0;
+ posting.weight = 0;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
+ }
+ }
+ }
+ break;
+ default :
+ break;
}
}
}
@@ -6534,7 +3368,7 @@ proc_range_filter(grn_ctx *ctx, int nargs, grn_obj **args,
}
real_limit = GRN_INT32_VALUE(&int32_value);
} else {
- real_limit = DEFAULT_LIMIT;
+ real_limit = GRN_SELECT_DEFAULT_LIMIT;
}
GRN_OBJ_FIN(ctx, &int32_value);
@@ -6642,21 +3476,14 @@ proc_range_filter(grn_ctx *ctx, int nargs, grn_obj **args,
if (ctx->rc) {
break;
}
- if (result) {
- GRN_TRUEP(ctx, result, result_boolean);
- }
+ result_boolean = grn_obj_is_true(ctx, result);
} else {
result_boolean = GRN_TRUE;
}
if (result_boolean) {
if (n_records >= real_offset) {
- grn_ii_posting ii_posting;
- ii_posting.rid = posting->rid;
- ii_posting.sid = posting->sid;
- ii_posting.pos = posting->pos;
- ii_posting.weight = posting->weight;
- grn_ii_posting_add(ctx, &ii_posting, (grn_hash *)res, op);
+ grn_ii_posting_add(ctx, posting, (grn_hash *)res, op);
}
n_records++;
if (n_records == real_limit) {
@@ -6682,13 +3509,13 @@ proc_range_filter(grn_ctx *ctx, int nargs, grn_obj **args,
raw_output_columns = GRN_TEXT_VALUE(output_columns);
raw_output_columns_len = GRN_TEXT_LEN(output_columns);
if (raw_output_columns_len == 0) {
- raw_output_columns = DEFAULT_OUTPUT_COLUMNS;
+ raw_output_columns = GRN_SELECT_DEFAULT_OUTPUT_COLUMNS;
raw_output_columns_len = strlen(raw_output_columns);
}
- grn_select_output_columns(ctx, res, -1, real_offset, real_limit,
- raw_output_columns,
- raw_output_columns_len,
- filter_expr);
+ grn_proc_select_output_columns(ctx, res, -1, real_offset, real_limit,
+ raw_output_columns,
+ raw_output_columns_len,
+ filter_expr);
}
exit :
@@ -6763,11 +3590,14 @@ proc_io_flush(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
grn_obj *target_name;
grn_obj *recursive;
+ grn_obj *only_opened;
grn_obj *target;
grn_bool is_recursive;
+ grn_bool is_only_opened;
target_name = VAR(0);
recursive = VAR(1);
+ only_opened = VAR(2);
if (GRN_TEXT_LEN(target_name) > 0) {
target = grn_ctx_get(ctx,
@@ -6784,21 +3614,315 @@ proc_io_flush(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
target = grn_ctx_db(ctx);
}
- is_recursive = bool_option_value(recursive, GRN_TRUE);
+ is_recursive = grn_proc_option_value_bool(ctx, recursive, GRN_TRUE);
+ is_only_opened = grn_proc_option_value_bool(ctx, only_opened, GRN_FALSE);
{
grn_rc rc;
- if (is_recursive) {
- rc = grn_obj_flush_recursive(ctx, target);
- } else {
+ if (target->header.type == GRN_DB && is_only_opened) {
rc = grn_obj_flush(ctx, target);
- }
+ if (rc == GRN_SUCCESS) {
+ GRN_TABLE_EACH_BEGIN_FLAGS(ctx, target, cursor, id, GRN_CURSOR_BY_ID) {
+ grn_obj *sub_target;
+
+ if (id < GRN_N_RESERVED_TYPES) {
+ continue;
+ }
+ if (!grn_ctx_is_opened(ctx, id)) {
+ continue;
+ }
+
+ sub_target = grn_ctx_at(ctx, id);
+ rc = grn_obj_flush(ctx, sub_target);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ }
+ } else {
+ if (is_recursive) {
+ rc = grn_obj_flush_recursive(ctx, target);
+ } else {
+ rc = grn_obj_flush(ctx, target);
+ }
+ }
GRN_OUTPUT_BOOL(rc == GRN_SUCCESS);
}
+
+ return NULL;
+}
+
+static grn_obj *
+proc_thread_limit(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *max_bulk;
+ uint32_t current_limit;
+
+ current_limit = grn_thread_get_limit();
+ GRN_OUTPUT_INT64(current_limit);
+
+ max_bulk = VAR(0);
+ if (GRN_TEXT_LEN(max_bulk) > 0) {
+ uint32_t max;
+ const char *max_text = GRN_TEXT_VALUE(max_bulk);
+ const char *max_text_end;
+ const char *max_text_rest;
+
+ max_text_end = max_text + GRN_TEXT_LEN(max_bulk);
+ max = grn_atoui(max_text, max_text_end, &max_text_rest);
+ if (max_text_rest != max_text_end) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[thread_limit] max must be unsigned integer value: <%.*s>",
+ (int)GRN_TEXT_LEN(max_bulk),
+ max_text);
+ return NULL;
+ }
+ if (max == 0) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[thread_limit] max must be 1 or larger: <%.*s>",
+ (int)GRN_TEXT_LEN(max_bulk),
+ max_text);
+ return NULL;
+ }
+ grn_thread_set_limit(max);
+ }
+
return NULL;
}
+static grn_obj *
+proc_database_unmap(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_rc rc;
+ uint32_t current_limit;
+
+ current_limit = grn_thread_get_limit();
+ if (current_limit != 1) {
+ ERR(GRN_OPERATION_NOT_PERMITTED,
+ "[database_unmap] the max number of threads must be 1: <%u>",
+ current_limit);
+ GRN_OUTPUT_BOOL(GRN_FALSE);
+ return NULL;
+ }
+
+ rc = grn_db_unmap(ctx, grn_ctx_db(ctx));
+ GRN_OUTPUT_BOOL(rc == GRN_SUCCESS);
+
+ return NULL;
+}
+
+static grn_obj *
+proc_reindex(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *target_name;
+ grn_obj *target;
+
+ target_name = VAR(0);
+ if (GRN_TEXT_LEN(target_name) == 0) {
+ target = grn_ctx_db(ctx);
+ } else {
+ target = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(target_name),
+ GRN_TEXT_LEN(target_name));
+ if (!target) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[reindex] nonexistent target: <%.*s>",
+ (int)GRN_TEXT_LEN(target_name),
+ GRN_TEXT_VALUE(target_name));
+ GRN_OUTPUT_BOOL(GRN_FALSE);
+ return NULL;
+ }
+ }
+
+ grn_obj_reindex(ctx, target);
+
+ GRN_OUTPUT_BOOL(ctx->rc == GRN_SUCCESS);
+
+ return NULL;
+}
+
+static grn_rc
+selector_prefix_rk_search_key(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *column,
+ grn_obj *query,
+ grn_obj *res,
+ grn_operator op)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ if (!grn_obj_is_key_accessor(ctx, column)) {
+ grn_obj inspected_column;
+ GRN_TEXT_INIT(&inspected_column, 0);
+ grn_inspect(ctx, &inspected_column, column);
+ ERR(GRN_INVALID_ARGUMENT,
+ "prefix_rk_serach(): column must be _key: %.*s",
+ (int)GRN_TEXT_LEN(&inspected_column),
+ GRN_TEXT_VALUE(&inspected_column));
+ rc = ctx->rc;
+ GRN_OBJ_FIN(ctx, &inspected_column);
+ goto exit;
+ }
+
+ if (table->header.type != GRN_TABLE_PAT_KEY) {
+ grn_obj inspected_table;
+ GRN_TEXT_INIT(&inspected_table, 0);
+ grn_inspect(ctx, &inspected_table, table);
+ ERR(GRN_INVALID_ARGUMENT,
+ "prefix_rk_serach(): table of _key must TABLE_PAT_KEY: %.*s",
+ (int)GRN_TEXT_LEN(&inspected_table),
+ GRN_TEXT_VALUE(&inspected_table));
+ rc = ctx->rc;
+ GRN_OBJ_FIN(ctx, &inspected_table);
+ goto exit;
+ }
+
+ GRN_TABLE_EACH_BEGIN_MIN(ctx,
+ table,
+ cursor,
+ id,
+ GRN_TEXT_VALUE(query),
+ GRN_TEXT_LEN(query),
+ GRN_CURSOR_PREFIX | GRN_CURSOR_RK) {
+ grn_posting posting;
+ posting.rid = id;
+ posting.sid = 1;
+ posting.pos = 0;
+ posting.weight = 0;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
+
+exit :
+ return rc;
+}
+
+static grn_rc
+selector_prefix_rk_search_index(grn_ctx *ctx,
+ grn_obj *index,
+ grn_obj *query,
+ grn_obj *res,
+ grn_operator op)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *table;
+
+ table = grn_column_table(ctx, index);
+
+ GRN_TABLE_EACH_BEGIN_MIN(ctx,
+ table,
+ cursor,
+ id,
+ GRN_TEXT_VALUE(query),
+ GRN_TEXT_LEN(query),
+ GRN_CURSOR_PREFIX | GRN_CURSOR_RK) {
+ grn_ii_at(ctx, (grn_ii *)index, id, (grn_hash *)res, op);
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
+
+ return rc;
+}
+
+static grn_rc
+selector_prefix_rk_search(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ int nargs,
+ grn_obj **args,
+ grn_obj *res,
+ grn_operator op)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *column;
+ grn_obj *query;
+
+ if ((nargs - 1) != 2) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "prefix_rk_serach(): wrong number of arguments (%d for 2)", nargs - 1);
+ return ctx->rc;
+ }
+
+ column = args[1];
+ query = args[2];
+
+ if (index) {
+ rc = selector_prefix_rk_search_index(ctx, index, query, res, op);
+ } else if (grn_obj_is_accessor(ctx, column) &&
+ ((grn_accessor *)column)->next) {
+ grn_obj *accessor = column;
+ unsigned int accessor_deep = 0;
+ grn_obj *base_table = NULL;
+ grn_obj *base_column = NULL;
+ grn_obj *base_index = NULL;
+ grn_obj *base_res = NULL;
+ grn_accessor *a;
+
+ for (a = (grn_accessor *)accessor; a; a = a->next) {
+ if (a->next) {
+ accessor_deep++;
+ } else {
+ if (grn_obj_is_data_column(ctx, a->obj)) {
+ grn_operator selector_op;
+ grn_index_datum index_data;
+ unsigned int n_index_datum;
+
+ selector_op = grn_proc_get_selector_operator(ctx, args[0]);
+ base_column = a->obj;
+ base_table = grn_column_table(ctx, a->obj);
+ n_index_datum = grn_column_find_index_data(ctx,
+ base_column,
+ selector_op,
+ &index_data,
+ 1);
+ if (n_index_datum > 0) {
+ base_index = index_data.index;
+ }
+ } else {
+ base_column = (grn_obj *)a;
+ base_table = a->obj;
+ }
+ base_res = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ base_table, NULL);
+ }
+ }
+ if (base_index) {
+ rc = selector_prefix_rk_search_index(ctx,
+ base_index,
+ query,
+ base_res,
+ GRN_OP_OR);
+ } else {
+ rc = selector_prefix_rk_search_key(ctx,
+ base_table,
+ base_column,
+ query,
+ base_res,
+ GRN_OP_OR);
+ }
+ if (rc == GRN_SUCCESS) {
+ grn_accessor_resolve(ctx,
+ accessor,
+ accessor_deep,
+ base_res,
+ res,
+ op);
+ }
+ grn_obj_close(ctx, base_res);
+ } else {
+ rc = selector_prefix_rk_search_key(ctx,
+ table,
+ column,
+ query,
+ res,
+ op);
+ }
+ return rc;
+}
+
#define DEF_VAR(v,name_str) do {\
(v).name = (name_str);\
(v).name_size = GRN_STRLEN(name_str);\
@@ -6810,36 +3934,12 @@ proc_io_flush(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
GRN_PROC_COMMAND, (func), NULL, NULL, (nvars), (vars)))
void
-grn_db_init_builtin_query(grn_ctx *ctx)
+grn_db_init_builtin_commands(grn_ctx *ctx)
{
- grn_expr_var vars[23];
+ grn_expr_var vars[10];
- DEF_VAR(vars[0], "name");
- DEF_VAR(vars[1], "table");
- DEF_VAR(vars[2], "match_columns");
- DEF_VAR(vars[3], "query");
- DEF_VAR(vars[4], "filter");
- DEF_VAR(vars[5], "scorer");
- DEF_VAR(vars[6], "sortby");
- DEF_VAR(vars[7], "output_columns");
- DEF_VAR(vars[8], "offset");
- DEF_VAR(vars[9], "limit");
- DEF_VAR(vars[10], "drilldown");
- DEF_VAR(vars[11], "drilldown_sortby");
- DEF_VAR(vars[12], "drilldown_output_columns");
- DEF_VAR(vars[13], "drilldown_offset");
- DEF_VAR(vars[14], "drilldown_limit");
- DEF_VAR(vars[15], "cache");
- DEF_VAR(vars[16], "match_escalation_threshold");
- /* Deprecated. Use query_expander instead. */
- DEF_VAR(vars[17], "query_expansion");
- DEF_VAR(vars[18], "query_flags");
- DEF_VAR(vars[19], "query_expander");
- DEF_VAR(vars[20], "adjuster");
- DEF_VAR(vars[21], "drilldown_calc_types");
- DEF_VAR(vars[22], "drilldown_calc_target");
- DEF_COMMAND("define_selector", proc_define_selector, 23, vars);
- DEF_COMMAND("select", proc_select, 22, vars + 1);
+ grn_proc_init_define_selector(ctx);
+ grn_proc_init_select(ctx);
DEF_VAR(vars[0], "values");
DEF_VAR(vars[1], "table");
@@ -6847,60 +3947,38 @@ grn_db_init_builtin_query(grn_ctx *ctx)
DEF_VAR(vars[3], "ifexists");
DEF_VAR(vars[4], "input_type");
DEF_VAR(vars[5], "each");
- DEF_COMMAND("load", proc_load, 6, vars);
+ DEF_VAR(vars[6], "output_ids");
+ DEF_VAR(vars[7], "output_errors");
+ DEF_COMMAND("load", proc_load, 8, vars);
DEF_COMMAND("status", proc_status, 0, vars);
- DEF_COMMAND("table_list", proc_table_list, 0, vars);
+ grn_proc_init_table_list(ctx);
- DEF_VAR(vars[0], "table");
- DEF_COMMAND("column_list", proc_column_list, 1, vars);
+ grn_proc_init_column_list(ctx);
- DEF_VAR(vars[0], "name");
- DEF_VAR(vars[1], "flags");
- DEF_VAR(vars[2], "key_type");
- DEF_VAR(vars[3], "value_type");
- DEF_VAR(vars[4], "default_tokenizer");
- DEF_VAR(vars[5], "normalizer");
- DEF_VAR(vars[6], "token_filters");
- DEF_COMMAND("table_create", proc_table_create, 7, vars);
+ grn_proc_init_table_create(ctx);
- DEF_VAR(vars[0], "name");
- DEF_COMMAND("table_remove", proc_table_remove, 1, vars);
+ grn_proc_init_table_remove(ctx);
- DEF_VAR(vars[0], "name");
- DEF_VAR(vars[1], "new_name");
- DEF_COMMAND("table_rename", proc_table_rename, 2, vars);
+ grn_proc_init_table_rename(ctx);
- DEF_VAR(vars[0], "table");
- DEF_VAR(vars[1], "name");
- DEF_VAR(vars[2], "flags");
- DEF_VAR(vars[3], "type");
- DEF_VAR(vars[4], "source");
- DEF_COMMAND("column_create", proc_column_create, 5, vars);
+ grn_proc_init_column_create(ctx);
- DEF_VAR(vars[0], "table");
- DEF_VAR(vars[1], "name");
- DEF_COMMAND("column_remove", proc_column_remove, 2, vars);
+ grn_proc_init_column_remove(ctx);
- DEF_VAR(vars[0], "table");
- DEF_VAR(vars[1], "name");
- DEF_VAR(vars[2], "new_name");
- DEF_COMMAND("column_rename", proc_column_rename, 3, vars);
+ grn_proc_init_column_rename(ctx);
DEF_VAR(vars[0], "path");
DEF_COMMAND(GRN_EXPR_MISSING_NAME, proc_missing, 1, vars);
DEF_COMMAND("quit", proc_quit, 0, vars);
- DEF_COMMAND("shutdown", proc_shutdown, 0, vars);
-
- /* Deprecated. Use "lock_clear" instead. */
- DEF_VAR(vars[0], "target_name");
- DEF_COMMAND("clearlock", proc_lock_clear, 1, vars);
+ DEF_VAR(vars[0], "mode");
+ DEF_COMMAND("shutdown", proc_shutdown, 1, vars);
- DEF_VAR(vars[0], "target_name");
- DEF_COMMAND("lock_clear", proc_lock_clear, 1, vars);
+ grn_proc_init_clearlock(ctx);
+ grn_proc_init_lock_clear(ctx);
DEF_VAR(vars[0], "target_name");
DEF_VAR(vars[1], "threshold");
@@ -6924,12 +4002,7 @@ grn_db_init_builtin_query(grn_ctx *ctx)
DEF_VAR(vars[0], "max");
DEF_COMMAND("cache_limit", proc_cache_limit, 1, vars);
- DEF_VAR(vars[0], "tables");
- DEF_VAR(vars[1], "dump_plugins");
- DEF_VAR(vars[2], "dump_schema");
- DEF_VAR(vars[3], "dump_records");
- DEF_VAR(vars[4], "dump_indexes");
- DEF_COMMAND("dump", proc_dump, 5, vars);
+ grn_proc_init_dump(ctx);
/* Deprecated. Use "plugin_register" instead. */
DEF_VAR(vars[0], "path");
@@ -6947,35 +4020,31 @@ grn_db_init_builtin_query(grn_ctx *ctx)
DEF_VAR(vars[2], "flags");
DEF_COMMAND("normalize", proc_normalize, 3, vars);
- DEF_VAR(vars[0], "tokenizer");
- DEF_VAR(vars[1], "string");
- DEF_VAR(vars[2], "normalizer");
- DEF_VAR(vars[3], "flags");
- DEF_VAR(vars[4], "mode");
- DEF_VAR(vars[5], "token_filters");
- DEF_COMMAND("tokenize", proc_tokenize, 6, vars);
-
- DEF_VAR(vars[0], "table");
- DEF_VAR(vars[1], "string");
- DEF_VAR(vars[2], "flags");
- DEF_VAR(vars[3], "mode");
- DEF_COMMAND("table_tokenize", proc_table_tokenize, 4, vars);
+ grn_proc_init_tokenize(ctx);
+ grn_proc_init_table_tokenize(ctx);
DEF_COMMAND("tokenizer_list", proc_tokenizer_list, 0, vars);
DEF_COMMAND("normalizer_list", proc_normalizer_list, 0, vars);
- DEF_VAR(vars[0], "seed");
- grn_proc_create(ctx, "rand", -1, GRN_PROC_FUNCTION, func_rand,
- NULL, NULL, 0, vars);
+ {
+ grn_obj *proc;
+ proc = grn_proc_create(ctx, "rand", -1, GRN_PROC_FUNCTION, func_rand,
+ NULL, NULL, 0, NULL);
+ grn_proc_set_is_stable(ctx, proc, GRN_FALSE);
+ }
- grn_proc_create(ctx, "now", -1, GRN_PROC_FUNCTION, func_now,
- NULL, NULL, 0, vars);
+ {
+ grn_obj *proc;
+ proc = grn_proc_create(ctx, "now", -1, GRN_PROC_FUNCTION, func_now,
+ NULL, NULL, 0, NULL);
+ grn_proc_set_is_stable(ctx, proc, GRN_FALSE);
+ }
grn_proc_create(ctx, "max", -1, GRN_PROC_FUNCTION, func_max,
- NULL, NULL, 0, vars);
+ NULL, NULL, 0, NULL);
grn_proc_create(ctx, "min", -1, GRN_PROC_FUNCTION, func_min,
- NULL, NULL, 0, vars);
+ NULL, NULL, 0, NULL);
{
grn_obj *selector_proc;
@@ -6983,11 +4052,15 @@ grn_db_init_builtin_query(grn_ctx *ctx)
selector_proc = grn_proc_create(ctx, "geo_in_circle", -1, GRN_PROC_FUNCTION,
func_geo_in_circle, NULL, NULL, 0, NULL);
grn_proc_set_selector(ctx, selector_proc, grn_selector_geo_in_circle);
+ /* We may need GRN_OP_GEO_IN_CIRCLE. */
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_MATCH);
selector_proc = grn_proc_create(ctx, "geo_in_rectangle", -1,
GRN_PROC_FUNCTION,
func_geo_in_rectangle, NULL, NULL, 0, NULL);
grn_proc_set_selector(ctx, selector_proc, grn_selector_geo_in_rectangle);
+ /* We may need GRN_OP_GEO_IN_RECTANGLE. */
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_MATCH);
}
grn_proc_create(ctx, "geo_distance", -1, GRN_PROC_FUNCTION,
@@ -7001,8 +4074,7 @@ grn_db_init_builtin_query(grn_ctx *ctx)
grn_proc_create(ctx, "geo_distance3", -1, GRN_PROC_FUNCTION,
func_geo_distance3, NULL, NULL, 0, NULL);
- grn_proc_create(ctx, "edit_distance", -1, GRN_PROC_FUNCTION,
- func_edit_distance, NULL, NULL, 0, NULL);
+ grn_proc_init_edit_distance(ctx);
{
grn_obj *selector_proc;
@@ -7010,11 +4082,11 @@ grn_db_init_builtin_query(grn_ctx *ctx)
selector_proc = grn_proc_create(ctx, "all_records", -1, GRN_PROC_FUNCTION,
func_all_records, NULL, NULL, 0, NULL);
grn_proc_set_selector(ctx, selector_proc, selector_all_records);
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_NOP);
}
/* experimental */
- grn_proc_create(ctx, "snippet_html", -1, GRN_PROC_FUNCTION,
- func_snippet_html, NULL, NULL, 0, NULL);
+ grn_proc_init_snippet_html(ctx);
{
grn_obj *selector_proc;
@@ -7022,14 +4094,16 @@ grn_db_init_builtin_query(grn_ctx *ctx)
selector_proc = grn_proc_create(ctx, "query", -1, GRN_PROC_FUNCTION,
func_query, NULL, NULL, 0, NULL);
grn_proc_set_selector(ctx, selector_proc, selector_query);
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_NOP);
}
{
grn_obj *selector_proc;
selector_proc = grn_proc_create(ctx, "sub_filter", -1, GRN_PROC_FUNCTION,
- func_sub_filter, NULL, NULL, 0, NULL);
+ NULL, NULL, NULL, 0, NULL);
grn_proc_set_selector(ctx, selector_proc, selector_sub_filter);
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_NOP);
}
grn_proc_create(ctx, "html_untag", -1, GRN_PROC_FUNCTION,
@@ -7041,13 +4115,11 @@ grn_db_init_builtin_query(grn_ctx *ctx)
selector_proc = grn_proc_create(ctx, "between", -1, GRN_PROC_FUNCTION,
func_between, NULL, NULL, 0, NULL);
grn_proc_set_selector(ctx, selector_proc, selector_between);
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_LESS);
}
- grn_proc_create(ctx, "highlight_html", -1, GRN_PROC_FUNCTION,
- func_highlight_html, NULL, NULL, 0, NULL);
-
- grn_proc_create(ctx, "highlight_full", -1, GRN_PROC_FUNCTION,
- func_highlight_full, NULL, NULL, 0, NULL);
+ grn_proc_init_highlight_html(ctx);
+ grn_proc_init_highlight_full(ctx);
{
grn_obj *selector_proc;
@@ -7055,6 +4127,7 @@ grn_db_init_builtin_query(grn_ctx *ctx)
selector_proc = grn_proc_create(ctx, "in_values", -1, GRN_PROC_FUNCTION,
func_in_values, NULL, NULL, 0, NULL);
grn_proc_set_selector(ctx, selector_proc, selector_in_values);
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_EQUAL);
}
DEF_VAR(vars[0], "table");
@@ -7080,5 +4153,59 @@ grn_db_init_builtin_query(grn_ctx *ctx)
DEF_VAR(vars[0], "target_name");
DEF_VAR(vars[1], "recursive");
- DEF_COMMAND("io_flush", proc_io_flush, 2, vars);
+ DEF_VAR(vars[2], "only_opened");
+ DEF_COMMAND("io_flush", proc_io_flush, 3, vars);
+
+ grn_proc_init_object_exist(ctx);
+
+ DEF_VAR(vars[0], "max");
+ DEF_COMMAND("thread_limit", proc_thread_limit, 1, vars);
+
+ DEF_COMMAND("database_unmap", proc_database_unmap, 0, vars);
+
+ grn_proc_init_column_copy(ctx);
+
+ grn_proc_init_schema(ctx);
+
+ DEF_VAR(vars[0], "target_name");
+ DEF_COMMAND("reindex", proc_reindex, 1, vars);
+
+ {
+ grn_obj *selector_proc;
+
+ selector_proc = grn_proc_create(ctx, "prefix_rk_search", -1,
+ GRN_PROC_FUNCTION,
+ NULL, NULL, NULL, 0, NULL);
+ grn_proc_set_selector(ctx, selector_proc, selector_prefix_rk_search);
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_PREFIX);
+ }
+
+ grn_proc_init_config_get(ctx);
+ grn_proc_init_config_set(ctx);
+ grn_proc_init_config_delete(ctx);
+
+ grn_proc_init_lock_acquire(ctx);
+ grn_proc_init_lock_release(ctx);
+
+ grn_proc_init_object_inspect(ctx);
+
+ grn_proc_init_fuzzy_search(ctx);
+
+ grn_proc_init_object_remove(ctx);
+
+ grn_proc_init_snippet(ctx);
+ grn_proc_init_highlight(ctx);
+
+ grn_proc_init_query_expand(ctx);
+
+ grn_proc_init_object_list(ctx);
+
+ grn_proc_init_table_copy(ctx);
+
+ grn_proc_init_in_records(ctx);
+
+ grn_proc_init_query_log_flags_get(ctx);
+ grn_proc_init_query_log_flags_set(ctx);
+ grn_proc_init_query_log_flags_add(ctx);
+ grn_proc_init_query_log_flags_remove(ctx);
}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/Makefile.am b/storage/mroonga/vendor/groonga/lib/proc/Makefile.am
new file mode 100644
index 00000000000..e4284dc27c6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/Makefile.am
@@ -0,0 +1,17 @@
+AM_CPPFLAGS = \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib
+
+AM_CFLAGS = \
+ $(NO_STRICT_ALIASING_CFLAGS) \
+ $(COVERAGE_CFLAGS) \
+ $(GRN_CFLAGS) \
+ $(MESSAGE_PACK_CFLAGS) \
+ $(MRUBY_CFLAGS)
+
+noinst_LTLIBRARIES = libgrnproc.la
+
+include sources.am
+
+CLEANFILES = *.gcno *.gcda
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_column.c b/storage/mroonga/vendor/groonga/lib/proc/proc_column.c
new file mode 100644
index 00000000000..fa6dacf861a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_column.c
@@ -0,0 +1,1019 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+
+#include "../grn_ctx.h"
+#include "../grn_db.h"
+#include "../grn_str.h"
+
+#include <groonga/plugin.h>
+
+grn_column_flags
+grn_proc_column_parse_flags(grn_ctx *ctx,
+ const char *error_message_tag,
+ const char *text,
+ const char *end)
+{
+ grn_column_flags flags = 0;
+ while (text < end) {
+ size_t name_size;
+
+ if (*text == '|' || *text == ' ') {
+ text += 1;
+ continue;
+ }
+
+#define CHECK_FLAG(name) \
+ name_size = strlen(#name); \
+ if ((end - text) >= name_size && \
+ memcmp(text, #name, name_size) == 0) { \
+ flags |= GRN_OBJ_ ## name; \
+ text += name_size; \
+ continue; \
+ }
+
+ CHECK_FLAG(COLUMN_SCALAR);
+ CHECK_FLAG(COLUMN_VECTOR);
+ CHECK_FLAG(COLUMN_INDEX);
+ CHECK_FLAG(COMPRESS_ZLIB);
+ CHECK_FLAG(COMPRESS_LZ4);
+ CHECK_FLAG(COMPRESS_ZSTD);
+ CHECK_FLAG(WITH_SECTION);
+ CHECK_FLAG(WITH_WEIGHT);
+ CHECK_FLAG(WITH_POSITION);
+ CHECK_FLAG(RING_BUFFER);
+ CHECK_FLAG(INDEX_SMALL);
+ CHECK_FLAG(INDEX_MEDIUM);
+
+#undef CHECK_FLAG
+
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s unknown flag: <%.*s>",
+ error_message_tag,
+ (int)(end - text), text);
+ return 0;
+ }
+ return flags;
+}
+
+static grn_rc
+command_column_create_resolve_source_name(grn_ctx *ctx,
+ grn_obj *table,
+ const char *source_name,
+ int source_name_length,
+ grn_obj *source_ids)
+{
+ grn_obj *column;
+
+ column = grn_obj_column(ctx, table, source_name, source_name_length);
+ if (!column) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[column][create] nonexistent source: <%.*s>",
+ source_name_length, source_name);
+ return ctx->rc;
+ }
+
+ if (column->header.type == GRN_ACCESSOR) {
+ if (strncmp(source_name, "_key", source_name_length) == 0) {
+ grn_id source_id = grn_obj_id(ctx, table);
+ GRN_UINT32_PUT(ctx, source_ids, source_id);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[column][create] pseudo column except <_key> is invalid: <%.*s>",
+ source_name_length, source_name);
+ }
+ } else {
+ grn_id source_id = grn_obj_id(ctx, column);
+ GRN_UINT32_PUT(ctx, source_ids, source_id);
+ }
+ grn_obj_unlink(ctx, column);
+
+ return ctx->rc;
+}
+
+static grn_rc
+command_column_create_resolve_source_names(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *source_names,
+ grn_obj *source_ids)
+{
+ int i, names_length;
+ int start, source_name_length;
+ const char *names;
+
+ names = GRN_TEXT_VALUE(source_names);
+ start = 0;
+ source_name_length = 0;
+ names_length = GRN_TEXT_LEN(source_names);
+ for (i = 0; i < names_length; i++) {
+ switch (names[i]) {
+ case ' ' :
+ if (source_name_length == 0) {
+ start++;
+ }
+ break;
+ case ',' :
+ {
+ grn_rc rc;
+ const char *source_name = names + start;
+ rc = command_column_create_resolve_source_name(ctx,
+ table,
+ source_name,
+ source_name_length,
+ source_ids);
+ if (rc) {
+ return rc;
+ }
+ start = i + 1;
+ source_name_length = 0;
+ }
+ break;
+ default :
+ source_name_length++;
+ break;
+ }
+ }
+
+ if (source_name_length > 0) {
+ grn_rc rc;
+ const char *source_name = names + start;
+ rc = command_column_create_resolve_source_name(ctx,
+ table,
+ source_name,
+ source_name_length,
+ source_ids);
+ if (rc) {
+ return rc;
+ }
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_obj *
+command_column_create(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_bool succeeded = GRN_TRUE;
+ grn_obj *table;
+ grn_obj *column;
+ grn_obj *table_raw;
+ grn_obj *name;
+ grn_obj *flags_raw;
+ grn_obj *type_raw;
+ grn_obj *source_raw;
+ grn_column_flags flags;
+ grn_obj *type = NULL;
+
+ table_raw = grn_plugin_proc_get_var(ctx, user_data, "table", -1);
+ name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+ flags_raw = grn_plugin_proc_get_var(ctx, user_data, "flags", -1);
+ type_raw = grn_plugin_proc_get_var(ctx, user_data, "type", -1);
+ source_raw = grn_plugin_proc_get_var(ctx, user_data, "source", -1);
+
+ table = grn_ctx_get(ctx, GRN_TEXT_VALUE(table_raw), GRN_TEXT_LEN(table_raw));
+ if (!table) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[column][create] table doesn't exist: <%.*s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw));
+ succeeded = GRN_FALSE;
+ goto exit;
+ }
+
+ {
+ const char *rest;
+ flags = grn_atoi(GRN_TEXT_VALUE(flags_raw),
+ GRN_BULK_CURR(flags_raw),
+ &rest);
+ if (GRN_TEXT_VALUE(flags_raw) == rest) {
+ flags = grn_proc_column_parse_flags(ctx,
+ "[column][create][flags]",
+ GRN_TEXT_VALUE(flags_raw),
+ GRN_BULK_CURR(flags_raw));
+ if (ctx->rc) {
+ succeeded = GRN_FALSE;
+ goto exit;
+ }
+ }
+ }
+
+ type = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(type_raw),
+ GRN_TEXT_LEN(type_raw));
+ if (!type) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[column][create] type doesn't exist: <%.*s>",
+ (int)GRN_TEXT_LEN(type_raw),
+ GRN_TEXT_VALUE(type_raw));
+ succeeded = GRN_FALSE;
+ goto exit;
+ }
+
+ if (GRN_TEXT_LEN(name) == 0) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[column][create] name is missing");
+ succeeded = GRN_FALSE;
+ goto exit;
+ }
+ flags |= GRN_OBJ_PERSISTENT;
+
+ column = grn_column_create(ctx, table,
+ GRN_TEXT_VALUE(name),
+ GRN_TEXT_LEN(name),
+ NULL, flags, type);
+ if (!column) {
+ succeeded = GRN_FALSE;
+ goto exit;
+ }
+
+ if (GRN_TEXT_LEN(source_raw) > 0) {
+ grn_rc rc;
+ grn_obj source_ids;
+ GRN_UINT32_INIT(&source_ids, GRN_OBJ_VECTOR);
+ rc = command_column_create_resolve_source_names(ctx,
+ type,
+ source_raw,
+ &source_ids);
+ if (rc == GRN_SUCCESS && GRN_BULK_VSIZE(&source_ids) > 0) {
+ grn_obj_set_info(ctx, column, GRN_INFO_SOURCE, &source_ids);
+ rc = ctx->rc;
+ }
+ GRN_OBJ_FIN(ctx, &source_ids);
+ if (rc != GRN_SUCCESS) {
+ grn_obj_remove(ctx, column);
+ succeeded = GRN_FALSE;
+ goto exit;
+ }
+ }
+
+ grn_obj_unlink(ctx, column);
+
+exit :
+ grn_ctx_output_bool(ctx, succeeded);
+ if (table) { grn_obj_unlink(ctx, table); }
+ if (type) { grn_obj_unlink(ctx, type); }
+
+ return NULL;
+}
+
+void
+grn_proc_init_column_create(grn_ctx *ctx)
+{
+ grn_expr_var vars[5];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "table", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "name", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[2]), "flags", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[3]), "type", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[4]), "source", -1);
+ grn_plugin_command_create(ctx,
+ "column_create", -1,
+ command_column_create,
+ 5,
+ vars);
+}
+
+static grn_obj *
+command_column_remove(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *table_raw;
+ grn_obj *name;
+ grn_obj *table;
+ grn_obj *column;
+ char fullname[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int fullname_len;
+
+ table_raw = grn_plugin_proc_get_var(ctx, user_data, "table", -1);
+ name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+
+ table = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(table_raw),
+ GRN_TEXT_LEN(table_raw));
+
+ fullname_len = grn_obj_name(ctx, table, fullname, GRN_TABLE_MAX_KEY_SIZE);
+ if (fullname_len == 0) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[column][remove] table isn't found: <%.*s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw));
+ grn_ctx_output_bool(ctx, GRN_FALSE);
+ return NULL;
+ }
+
+ fullname[fullname_len] = GRN_DB_DELIMITER;
+ fullname_len++;
+ if (fullname_len + GRN_TEXT_LEN(name) > GRN_TABLE_MAX_KEY_SIZE) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[column][remove] column name is too long: <%d> > <%u>: "
+ "<%.*s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TABLE_MAX_KEY_SIZE - fullname_len,
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ grn_ctx_output_bool(ctx, GRN_FALSE);
+ return NULL;
+ }
+ grn_memcpy(fullname + fullname_len,
+ GRN_TEXT_VALUE(name),
+ GRN_TEXT_LEN(name));
+ fullname_len += GRN_TEXT_LEN(name);
+ column = grn_ctx_get(ctx, fullname, fullname_len);
+ if (!column) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[column][remove] column isn't found: <%.*s%c%.*s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw),
+ GRN_DB_DELIMITER,
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ grn_ctx_output_bool(ctx, GRN_FALSE);
+ return NULL;
+ }
+
+ grn_obj_remove(ctx, column);
+ grn_ctx_output_bool(ctx, ctx->rc == GRN_SUCCESS);
+ return NULL;
+}
+
+void
+grn_proc_init_column_remove(grn_ctx *ctx)
+{
+ grn_expr_var vars[2];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "table", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "name", -1);
+ grn_plugin_command_create(ctx,
+ "column_remove", -1,
+ command_column_remove,
+ 2,
+ vars);
+}
+
+static grn_obj *
+command_column_rename(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *table_raw;
+ grn_obj *name;
+ grn_obj *new_name;
+ grn_obj *table = NULL;
+ grn_obj *column = NULL;
+
+ table_raw = grn_plugin_proc_get_var(ctx, user_data, "table", -1);
+ name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+ new_name = grn_plugin_proc_get_var(ctx, user_data, "new_name", -1);
+
+ if (GRN_TEXT_LEN(table_raw) == 0) {
+ rc = GRN_INVALID_ARGUMENT;
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[column][rename] table name isn't specified");
+ goto exit;
+ }
+
+ table = grn_ctx_get(ctx, GRN_TEXT_VALUE(table_raw), GRN_TEXT_LEN(table_raw));
+ if (!table) {
+ rc = GRN_INVALID_ARGUMENT;
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[column][rename] table isn't found: <%.*s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw));
+ goto exit;
+ }
+
+ if (GRN_TEXT_LEN(name) == 0) {
+ rc = GRN_INVALID_ARGUMENT;
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[column][rename] column name isn't specified: <%.*s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw));
+ goto exit;
+ }
+
+ column = grn_obj_column(ctx, table,
+ GRN_TEXT_VALUE(name),
+ GRN_TEXT_LEN(name));
+ if (!column) {
+ rc = GRN_INVALID_ARGUMENT;
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[column][rename] column isn't found: <%.*s%c%.*s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw),
+ GRN_DB_DELIMITER,
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ goto exit;
+ }
+
+ if (GRN_TEXT_LEN(new_name) == 0) {
+ rc = GRN_INVALID_ARGUMENT;
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[column][rename] new column name isn't specified: "
+ "<%.*s%c%.*s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw),
+ GRN_DB_DELIMITER,
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ goto exit;
+ }
+
+ rc = grn_column_rename(ctx, column,
+ GRN_TEXT_VALUE(new_name),
+ GRN_TEXT_LEN(new_name));
+ if (rc != GRN_SUCCESS && ctx->rc == GRN_SUCCESS) {
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[column][rename] failed to rename: "
+ "<%.*s%c%.*s> -> <%.*s%c%.*s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw),
+ GRN_DB_DELIMITER,
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name),
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw),
+ GRN_DB_DELIMITER,
+ (int)GRN_TEXT_LEN(new_name),
+ GRN_TEXT_VALUE(new_name));
+ goto exit;
+ }
+
+exit :
+ grn_ctx_output_bool(ctx, rc == GRN_SUCCESS);
+ if (column) { grn_obj_unlink(ctx, column); }
+ if (table) { grn_obj_unlink(ctx, table); }
+ return NULL;
+}
+
+void
+grn_proc_init_column_rename(grn_ctx *ctx)
+{
+ grn_expr_var vars[3];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "table", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "name", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[2]), "new_name", -1);
+ grn_plugin_command_create(ctx,
+ "column_rename", -1,
+ command_column_rename,
+ 3,
+ vars);
+}
+
+static void
+output_column_name(grn_ctx *ctx, grn_obj *column)
+{
+ grn_obj bulk;
+ int name_len;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+
+ GRN_TEXT_INIT(&bulk, GRN_OBJ_DO_SHALLOW_COPY);
+ name_len = grn_column_name(ctx, column, name, GRN_TABLE_MAX_KEY_SIZE);
+ GRN_TEXT_SET(ctx, &bulk, name, name_len);
+
+ grn_ctx_output_obj(ctx, &bulk, NULL);
+ GRN_OBJ_FIN(ctx, &bulk);
+}
+
+static int
+output_column_info(grn_ctx *ctx, grn_obj *column)
+{
+ grn_obj o;
+ grn_id id;
+ const char *type;
+ const char *path;
+
+ switch (column->header.type) {
+ case GRN_COLUMN_FIX_SIZE:
+ type = "fix";
+ break;
+ case GRN_COLUMN_VAR_SIZE:
+ type = "var";
+ break;
+ case GRN_COLUMN_INDEX:
+ type = "index";
+ break;
+ default:
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "invalid header type %d\n", column->header.type);
+ return 0;
+ }
+ id = grn_obj_id(ctx, column);
+ path = grn_obj_path(ctx, column);
+ GRN_TEXT_INIT(&o, 0);
+ grn_ctx_output_array_open(ctx, "COLUMN", 8);
+ grn_ctx_output_int64(ctx, id);
+ output_column_name(ctx, column);
+ grn_ctx_output_cstr(ctx, path);
+ grn_ctx_output_cstr(ctx, type);
+ grn_dump_column_create_flags(ctx, grn_column_get_flags(ctx, column), &o);
+ grn_ctx_output_obj(ctx, &o, NULL);
+ grn_proc_output_object_id_name(ctx, column->header.domain);
+ grn_proc_output_object_id_name(ctx, grn_obj_get_range(ctx, column));
+ {
+ grn_db_obj *obj = (grn_db_obj *)column;
+ grn_id *s = obj->source;
+ int i = 0, n = obj->source_size / sizeof(grn_id);
+ grn_ctx_output_array_open(ctx, "SOURCES", n);
+ for (i = 0; i < n; i++, s++) {
+ grn_proc_output_object_id_name(ctx, *s);
+ }
+ grn_ctx_output_array_close(ctx);
+
+ }
+ /* output_obj_source(ctx, (grn_db_obj *)column); */
+ grn_ctx_output_array_close(ctx);
+ GRN_OBJ_FIN(ctx, &o);
+ return 1;
+}
+
+static grn_obj *
+command_column_list(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *table_raw;
+ grn_obj *table;
+ grn_hash *cols;
+ grn_obj *col;
+ int column_list_size = -1;
+
+ table_raw = grn_plugin_proc_get_var(ctx, user_data, "table", -1);
+
+ table = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(table_raw),
+ GRN_TEXT_LEN(table_raw));
+ if (!table) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[column][list] table doesn't exist: <%.*s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw));
+ return NULL;
+ }
+
+ if (!grn_obj_is_table(ctx, table)) {
+ const char *type_name;
+ type_name = grn_obj_type_to_string(table->header.type);
+ grn_obj_unlink(ctx, table);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[column][list] not table: <%.*s>: <%s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw),
+ type_name);
+ return NULL;
+ }
+
+ column_list_size = 1; /* [header, (key), (COLUMNS)] */
+ if (table->header.type != GRN_TABLE_NO_KEY) {
+ column_list_size++;
+ }
+ cols = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ if (!cols) {
+ grn_obj_unlink(ctx, table);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[column][list] "
+ "failed to create temporary table to list columns: <%.*s>",
+ (int)GRN_TEXT_LEN(table_raw),
+ GRN_TEXT_VALUE(table_raw));
+ return NULL;
+ }
+
+ column_list_size += grn_table_columns(ctx, table, NULL, 0, (grn_obj *)cols);
+
+ grn_ctx_output_array_open(ctx, "COLUMN_LIST", column_list_size);
+ grn_ctx_output_array_open(ctx, "HEADER", 8);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_cstr(ctx, "UInt32");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "name");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "path");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "type");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "flags");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "domain");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "range");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "source");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_close(ctx);
+
+ if ((col = grn_obj_column(ctx, table,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN))) {
+ int name_len;
+ char name_buf[GRN_TABLE_MAX_KEY_SIZE];
+ grn_id id;
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ grn_ctx_output_array_open(ctx, "COLUMN", 8);
+ id = grn_obj_id(ctx, table);
+ grn_ctx_output_int64(ctx, id);
+ grn_ctx_output_cstr(ctx, GRN_COLUMN_NAME_KEY);
+ grn_ctx_output_cstr(ctx, "");
+ grn_ctx_output_cstr(ctx, "");
+ grn_dump_column_create_flags(ctx, 0, &buf);
+ grn_ctx_output_obj(ctx, &buf, NULL);
+ name_len = grn_obj_name(ctx, table, name_buf, GRN_TABLE_MAX_KEY_SIZE);
+ grn_ctx_output_str(ctx, name_buf, name_len);
+ grn_proc_output_object_id_name(ctx, table->header.domain);
+ grn_ctx_output_array_open(ctx, "SOURCES", 0);
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_close(ctx);
+ GRN_OBJ_FIN(ctx, &buf);
+ grn_obj_unlink(ctx, col);
+ }
+ {
+ grn_id *key;
+ GRN_HASH_EACH(ctx, cols, id, &key, NULL, NULL, {
+ if ((col = grn_ctx_at(ctx, *key))) {
+ output_column_info(ctx, col);
+ grn_obj_unlink(ctx, col);
+ }
+ });
+ }
+ grn_ctx_output_array_close(ctx);
+ grn_hash_close(ctx, cols);
+ grn_obj_unlink(ctx, table);
+
+ return NULL;
+}
+
+void
+grn_proc_init_column_list(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "table", -1);
+ grn_plugin_command_create(ctx,
+ "column_list", -1,
+ command_column_list,
+ 1,
+ vars);
+}
+
+static grn_rc
+command_column_copy_resolve_target(grn_ctx *ctx,
+ const char *label,
+ grn_obj *table_name,
+ grn_obj *column_name,
+ grn_obj **table,
+ grn_obj **column)
+{
+ if (GRN_TEXT_LEN(table_name) == 0) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[column][copy] %s table name isn't specified",
+ label);
+ return ctx->rc;
+ }
+ *table = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(table_name),
+ GRN_TEXT_LEN(table_name));
+ if (!*table) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[column][copy] %s table isn't found: <%.*s>",
+ label,
+ (int)GRN_TEXT_LEN(table_name),
+ GRN_TEXT_VALUE(table_name));
+ return ctx->rc;
+ }
+
+ if (GRN_TEXT_LEN(column_name) == 0) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[column][copy] %s column name isn't specified: <%.*s>",
+ label,
+ (int)GRN_TEXT_LEN(table_name),
+ GRN_TEXT_VALUE(table_name));
+ return ctx->rc;
+ }
+ *column = grn_obj_column(ctx, *table,
+ GRN_TEXT_VALUE(column_name),
+ GRN_TEXT_LEN(column_name));
+ if (!*column) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[column][copy] %s column isn't found: <%.*s.%.*s>",
+ label,
+ (int)GRN_TEXT_LEN(table_name), GRN_TEXT_VALUE(table_name),
+ (int)GRN_TEXT_LEN(column_name), GRN_TEXT_VALUE(column_name));
+ return ctx->rc;
+ }
+
+ return ctx->rc;
+}
+
+static void
+command_column_copy_same_table(grn_ctx *ctx, grn_obj *table,
+ grn_obj *from_column, grn_obj *to_column)
+{
+ grn_table_cursor *cursor;
+ grn_id id;
+ grn_obj value;
+
+ cursor = grn_table_cursor_open(ctx, table,
+ NULL, 0,
+ NULL, 0,
+ 0, -1, 0);
+ if (!cursor) {
+ return;
+ }
+
+ GRN_VOID_INIT(&value);
+ while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx, from_column, id, &value);
+ grn_obj_set_value(ctx, to_column, id, &value, GRN_OBJ_SET);
+ }
+ GRN_OBJ_FIN(ctx, &value);
+ grn_table_cursor_close(ctx, cursor);
+}
+
+static void
+command_column_copy_same_key_type(grn_ctx *ctx,
+ grn_obj *from_table,
+ grn_obj *from_column,
+ grn_obj *to_table,
+ grn_obj *to_column)
+{
+ grn_table_cursor *cursor;
+ grn_id from_id;
+ grn_obj value;
+
+ cursor = grn_table_cursor_open(ctx, from_table,
+ NULL, 0,
+ NULL, 0,
+ 0, -1, 0);
+ if (!cursor) {
+ return;
+ }
+
+ GRN_VOID_INIT(&value);
+ while ((from_id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ void *key;
+ int key_size;
+ grn_id to_id;
+
+ key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+ to_id = grn_table_add(ctx, to_table, key, key_size, NULL);
+ if (to_id == GRN_ID_NIL) {
+ continue;
+ }
+
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx, from_column, from_id, &value);
+ grn_obj_set_value(ctx, to_column, to_id, &value, GRN_OBJ_SET);
+ }
+ GRN_OBJ_FIN(ctx, &value);
+ grn_table_cursor_close(ctx, cursor);
+}
+
+static void
+command_column_copy_different(grn_ctx *ctx,
+ grn_obj *from_table,
+ grn_obj *from_column,
+ grn_obj *to_table,
+ grn_obj *to_column,
+ grn_obj *from_table_name,
+ grn_obj *from_column_name,
+ grn_obj *to_table_name,
+ grn_obj *to_column_name)
+{
+ grn_table_cursor *cursor;
+ grn_id from_id;
+ grn_obj from_key_buffer;
+ grn_obj to_key_buffer;
+ grn_obj value;
+
+ cursor = grn_table_cursor_open(ctx, from_table,
+ NULL, 0,
+ NULL, 0,
+ 0, -1, 0);
+ if (!cursor) {
+ return;
+ }
+
+ if (from_table->header.domain == GRN_DB_SHORT_TEXT) {
+ GRN_SHORT_TEXT_INIT(&from_key_buffer, 0);
+ } else {
+ GRN_VALUE_FIX_SIZE_INIT(&from_key_buffer, 0, from_table->header.domain);
+ }
+ if (to_table->header.domain == GRN_DB_SHORT_TEXT) {
+ GRN_SHORT_TEXT_INIT(&to_key_buffer, 0);
+ } else {
+ GRN_VALUE_FIX_SIZE_INIT(&to_key_buffer, 0, to_table->header.domain);
+ }
+ GRN_VOID_INIT(&value);
+ while ((from_id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ void *key;
+ int key_size;
+ grn_rc cast_rc;
+ grn_id to_id;
+
+ GRN_BULK_REWIND(&from_key_buffer);
+ GRN_BULK_REWIND(&to_key_buffer);
+
+ key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+ grn_bulk_write(ctx, &from_key_buffer, key, key_size);
+ cast_rc = grn_obj_cast(ctx, &from_key_buffer, &to_key_buffer, GRN_FALSE);
+ if (cast_rc != GRN_SUCCESS) {
+ grn_obj *to_key_type;
+ grn_obj inspected_key;
+ grn_obj inspected_to_key_type;
+
+ to_key_type = grn_ctx_at(ctx, to_table->header.domain);
+ GRN_TEXT_INIT(&inspected_key, 0);
+ GRN_TEXT_INIT(&inspected_to_key_type, 0);
+ grn_inspect(ctx, &inspected_key, &from_key_buffer);
+ grn_inspect(ctx, &inspected_to_key_type, to_key_type);
+ ERR(cast_rc,
+ "[column][copy] failed to cast key: <%.*s> -> %.*s: "
+ "<%.*s.%.*s> -> <%.*s.%.*s>",
+ (int)GRN_TEXT_LEN(&inspected_key),
+ GRN_TEXT_VALUE(&inspected_key),
+ (int)GRN_TEXT_LEN(&inspected_to_key_type),
+ GRN_TEXT_VALUE(&inspected_to_key_type),
+ (int)GRN_TEXT_LEN(from_table_name),
+ GRN_TEXT_VALUE(from_table_name),
+ (int)GRN_TEXT_LEN(from_column_name),
+ GRN_TEXT_VALUE(from_column_name),
+ (int)GRN_TEXT_LEN(to_table_name),
+ GRN_TEXT_VALUE(to_table_name),
+ (int)GRN_TEXT_LEN(to_column_name),
+ GRN_TEXT_VALUE(to_column_name));
+ GRN_OBJ_FIN(ctx, &inspected_key);
+ GRN_OBJ_FIN(ctx, &inspected_to_key_type);
+ break;
+ }
+ to_id = grn_table_add(ctx, to_table,
+ GRN_BULK_HEAD(&to_key_buffer),
+ GRN_BULK_VSIZE(&to_key_buffer),
+ NULL);
+ if (to_id == GRN_ID_NIL) {
+ continue;
+ }
+
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx, from_column, from_id, &value);
+ grn_obj_set_value(ctx, to_column, to_id, &value, GRN_OBJ_SET);
+ }
+ GRN_OBJ_FIN(ctx, &from_key_buffer);
+ GRN_OBJ_FIN(ctx, &to_key_buffer);
+ GRN_OBJ_FIN(ctx, &value);
+
+ grn_table_cursor_close(ctx, cursor);
+}
+
+static grn_obj *
+command_column_copy(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *from_table = NULL;
+ grn_obj *from_column = NULL;
+ grn_obj *to_table = NULL;
+ grn_obj *to_column = NULL;
+ grn_obj *from_table_name;
+ grn_obj *from_column_name;
+ grn_obj *to_table_name;
+ grn_obj *to_column_name;
+
+ from_table_name = grn_plugin_proc_get_var(ctx, user_data, "from_table", -1);
+ from_column_name = grn_plugin_proc_get_var(ctx, user_data, "from_name", -1);
+ to_table_name = grn_plugin_proc_get_var(ctx, user_data, "to_table", -1);
+ to_column_name = grn_plugin_proc_get_var(ctx, user_data, "to_name", -1);
+
+ rc = command_column_copy_resolve_target(ctx, "from",
+ from_table_name, from_column_name,
+ &from_table, &from_column);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ rc = command_column_copy_resolve_target(ctx, "to",
+ to_table_name, to_column_name,
+ &to_table, &to_column);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+
+ if ((from_table->header.type == GRN_TABLE_NO_KEY ||
+ to_table->header.type == GRN_TABLE_NO_KEY) &&
+ from_table != to_table) {
+ rc = GRN_OPERATION_NOT_SUPPORTED;
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[column][copy] copy from/to TABLE_NO_KEY isn't supported: "
+ "<%.*s%c%.*s> -> <%.*s%c%.*s>",
+ (int)GRN_TEXT_LEN(from_table_name),
+ GRN_TEXT_VALUE(from_table_name),
+ GRN_DB_DELIMITER,
+ (int)GRN_TEXT_LEN(from_column_name),
+ GRN_TEXT_VALUE(from_column_name),
+ (int)GRN_TEXT_LEN(to_table_name),
+ GRN_TEXT_VALUE(to_table_name),
+ GRN_DB_DELIMITER,
+ (int)GRN_TEXT_LEN(to_column_name),
+ GRN_TEXT_VALUE(to_column_name));
+ goto exit;
+ }
+
+ if (from_table == to_table) {
+ command_column_copy_same_table(ctx, from_table, from_column, to_column);
+ } else if (from_table->header.domain == to_table->header.domain) {
+ command_column_copy_same_key_type(ctx,
+ from_table, from_column,
+ to_table, to_column);
+ } else {
+ command_column_copy_different(ctx,
+ from_table,
+ from_column,
+ to_table,
+ to_column,
+ from_table_name,
+ from_column_name,
+ to_table_name,
+ to_column_name);
+ }
+
+exit :
+ grn_ctx_output_bool(ctx, rc == GRN_SUCCESS);
+
+ if (to_column) {
+ grn_obj_unlink(ctx, to_column);
+ }
+ if (to_table) {
+ grn_obj_unlink(ctx, to_table);
+ }
+ if (from_column) {
+ grn_obj_unlink(ctx, from_column);
+ }
+ if (from_table) {
+ grn_obj_unlink(ctx, from_table);
+ }
+
+ return NULL;
+}
+
+void
+grn_proc_init_column_copy(grn_ctx *ctx)
+{
+ grn_expr_var vars[4];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "from_table", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "from_name", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[2]), "to_table", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[3]), "to_name", -1);
+ grn_plugin_command_create(ctx,
+ "column_copy", -1,
+ command_column_copy,
+ 4,
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_config.c b/storage/mroonga/vendor/groonga/lib/proc/proc_config.c
new file mode 100644
index 00000000000..98533e3bccc
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_config.c
@@ -0,0 +1,139 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+
+#include <groonga/plugin.h>
+
+static grn_obj *
+command_config_get(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *key;
+ const char *value;
+ uint32_t value_size;
+
+ key = grn_plugin_proc_get_var(ctx, user_data, "key", -1);
+ if (GRN_TEXT_LEN(key) == 0) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[config][get] key is missing");
+ return NULL;
+ }
+
+ grn_config_get(ctx,
+ GRN_TEXT_VALUE(key), GRN_TEXT_LEN(key),
+ &value, &value_size);
+ if (ctx->rc) {
+ return NULL;
+ }
+
+ grn_ctx_output_str(ctx, value, value_size);
+
+ return NULL;
+}
+
+static grn_obj *
+command_config_set(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *key;
+ grn_obj *value;
+
+ key = grn_plugin_proc_get_var(ctx, user_data, "key", -1);
+ if (GRN_TEXT_LEN(key) == 0) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[config][set] key is missing");
+ return NULL;
+ }
+
+ value = grn_plugin_proc_get_var(ctx, user_data, "value", -1);
+ grn_config_set(ctx,
+ GRN_TEXT_VALUE(key), GRN_TEXT_LEN(key),
+ GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
+
+ grn_ctx_output_bool(ctx, ctx->rc == GRN_SUCCESS);
+
+ return NULL;
+}
+
+static grn_obj *
+command_config_delete(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *key;
+
+ key = grn_plugin_proc_get_var(ctx, user_data, "key", -1);
+ if (GRN_TEXT_LEN(key) == 0) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[config][delete] key is missing");
+ return NULL;
+ }
+
+ grn_config_delete(ctx,
+ GRN_TEXT_VALUE(key), GRN_TEXT_LEN(key));
+
+ grn_ctx_output_bool(ctx, ctx->rc == GRN_SUCCESS);
+
+ return NULL;
+}
+
+void
+grn_proc_init_config_get(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "key", -1);
+ grn_plugin_command_create(ctx,
+ "config_get", -1,
+ command_config_get,
+ 1,
+ vars);
+}
+
+void
+grn_proc_init_config_set(grn_ctx *ctx)
+{
+ grn_expr_var vars[2];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "key", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "value", -1);
+ grn_plugin_command_create(ctx,
+ "config_set", -1,
+ command_config_set,
+ 2,
+ vars);
+}
+
+void
+grn_proc_init_config_delete(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "key", -1);
+ grn_plugin_command_create(ctx,
+ "config_delete", -1,
+ command_config_delete,
+ 1,
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_dump.c b/storage/mroonga/vendor/groonga/lib/proc/proc_dump.c
new file mode 100644
index 00000000000..9439e0cdaed
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_dump.c
@@ -0,0 +1,1138 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+#include "../grn_ctx_impl.h"
+#include "../grn_db.h"
+#include "../grn_str.h"
+
+#include <groonga/plugin.h>
+
+static const size_t DUMP_FLUSH_THRESHOLD_SIZE = 256 * 1024;
+
+typedef struct {
+ grn_obj *output;
+ grn_bool is_close_opened_object_mode;
+ grn_bool have_reference_column;
+ grn_bool have_index_column;
+ grn_bool is_sort_hash_table;
+ grn_obj column_name_buffer;
+} grn_dumper;
+
+static void
+dumper_collect_statistics_table(grn_ctx *ctx,
+ grn_dumper *dumper,
+ grn_obj *table)
+{
+ grn_hash *columns;
+
+ columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ if (!columns) {
+ return;
+ }
+
+ grn_table_columns(ctx, table, NULL, 0, (grn_obj *)columns);
+ GRN_HASH_EACH_BEGIN(ctx, columns, cursor, id) {
+ void *key;
+ grn_id column_id;
+ grn_obj *column;
+
+ grn_hash_cursor_get_key(ctx, cursor, &key);
+ column_id = *((grn_id *)key);
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ column = grn_ctx_at(ctx, column_id);
+ if (!column) {
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ goto next_loop;
+ }
+
+ if (grn_obj_is_index_column(ctx, column)) {
+ dumper->have_index_column = GRN_TRUE;
+ } else if (grn_obj_is_reference_column(ctx, column)) {
+ dumper->have_reference_column = GRN_TRUE;
+ }
+
+ next_loop :
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
+ grn_hash_close(ctx, columns);
+}
+
+static void
+dumper_collect_statistics(grn_ctx *ctx, grn_dumper *dumper)
+{
+ GRN_DB_EACH_BEGIN_BY_ID(ctx, cursor, id) {
+ void *name;
+ int name_size;
+ grn_obj *object;
+
+ if (grn_id_is_builtin(ctx, id)) {
+ continue;
+ }
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+ if (grn_obj_name_is_column(ctx, name, name_size)) {
+ continue;
+ }
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ object = grn_ctx_at(ctx, id);
+ if (!object) {
+ /* XXX: this clause is executed when MeCab tokenizer is enabled in
+ database but the groonga isn't supported MeCab.
+ We should return error mesage about it and error exit status
+ but it's too difficult for this architecture. :< */
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ goto next_loop;
+ }
+
+ if (!grn_obj_is_table(ctx, object)) {
+ goto next_loop;
+ }
+
+ dumper_collect_statistics_table(ctx, dumper, object);
+
+next_loop :
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_DB_EACH_END(ctx, cursor);
+}
+
+static void
+dump_value_raw(grn_ctx *ctx, grn_obj *output, const char *value, int value_len)
+{
+ grn_obj escaped_value;
+ GRN_TEXT_INIT(&escaped_value, 0);
+ grn_text_esc(ctx, &escaped_value, value, value_len);
+ /* is no character escaped? */
+ /* TODO false positive with spaces inside values */
+ if (GRN_TEXT_LEN(&escaped_value) == value_len + 2) {
+ GRN_TEXT_PUT(ctx, output, value, value_len);
+ } else {
+ GRN_TEXT_PUT(ctx, output,
+ GRN_TEXT_VALUE(&escaped_value), GRN_TEXT_LEN(&escaped_value));
+ }
+ grn_obj_close(ctx, &escaped_value);
+}
+
+static void
+dump_value(grn_ctx *ctx, grn_dumper *dumper, const char *value, int value_len)
+{
+ dump_value_raw(ctx, dumper->output, value, value_len);
+}
+
+static void
+dump_configs(grn_ctx *ctx, grn_dumper *dumper)
+{
+ grn_obj *config_cursor;
+
+ config_cursor = grn_config_cursor_open(ctx);
+ if (!config_cursor)
+ return;
+
+ while (grn_config_cursor_next(ctx, config_cursor)) {
+ const char *key;
+ uint32_t key_size;
+ const char *value;
+ uint32_t value_size;
+
+ key_size = grn_config_cursor_get_key(ctx, config_cursor, &key);
+ value_size = grn_config_cursor_get_value(ctx, config_cursor, &value);
+
+ GRN_TEXT_PUTS(ctx, dumper->output, "config_set ");
+ dump_value(ctx, dumper, key, key_size);
+ GRN_TEXT_PUTS(ctx, dumper->output, " ");
+ dump_value(ctx, dumper, value, value_size);
+ GRN_TEXT_PUTC(ctx, dumper->output, '\n');
+ }
+ grn_obj_close(ctx, config_cursor);
+}
+
+static void
+dump_plugins(grn_ctx *ctx, grn_dumper *dumper)
+{
+ grn_obj plugin_names;
+ unsigned int i, n;
+
+ GRN_TEXT_INIT(&plugin_names, GRN_OBJ_VECTOR);
+
+ grn_plugin_get_names(ctx, &plugin_names);
+
+ n = grn_vector_size(ctx, &plugin_names);
+ if (n == 0) {
+ GRN_OBJ_FIN(ctx, &plugin_names);
+ return;
+ }
+
+ if (GRN_TEXT_LEN(dumper->output) > 0) {
+ GRN_TEXT_PUTC(ctx, dumper->output, '\n');
+ grn_ctx_output_flush(ctx, 0);
+ }
+ for (i = 0; i < n; i++) {
+ const char *name;
+ unsigned int name_size;
+
+ name_size = grn_vector_get_element(ctx, &plugin_names, i, &name, NULL, NULL);
+ grn_text_printf(ctx, dumper->output, "plugin_register %.*s\n",
+ (int)name_size, name);
+ }
+
+ GRN_OBJ_FIN(ctx, &plugin_names);
+}
+
+static void
+dump_obj_name_raw(grn_ctx *ctx, grn_obj *output, grn_obj *obj)
+{
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_len;
+ name_len = grn_obj_name(ctx, obj, name, GRN_TABLE_MAX_KEY_SIZE);
+ dump_value_raw(ctx, output, name, name_len);
+}
+
+static void
+dump_obj_name(grn_ctx *ctx, grn_dumper *dumper, grn_obj *obj)
+{
+ dump_obj_name_raw(ctx, dumper->output, obj);
+}
+
+static void
+dump_column_name(grn_ctx *ctx, grn_dumper *dumper, grn_obj *column)
+{
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_len;
+ name_len = grn_column_name(ctx, column, name, GRN_TABLE_MAX_KEY_SIZE);
+ dump_value(ctx, dumper, name, name_len);
+}
+
+static void
+dump_index_column_sources(grn_ctx *ctx, grn_dumper *dumper, grn_obj *column)
+{
+ grn_obj sources;
+ grn_id *source_ids;
+ int i, n;
+
+ GRN_OBJ_INIT(&sources, GRN_BULK, 0, GRN_ID_NIL);
+ grn_obj_get_info(ctx, column, GRN_INFO_SOURCE, &sources);
+
+ n = GRN_BULK_VSIZE(&sources) / sizeof(grn_id);
+ source_ids = (grn_id *)GRN_BULK_HEAD(&sources);
+ if (n > 0) {
+ GRN_TEXT_PUTC(ctx, dumper->output, ' ');
+ }
+ for (i = 0; i < n; i++) {
+ grn_id source_id;
+ grn_obj *source;
+
+ source_id = *source_ids;
+ source_ids++;
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ source = grn_ctx_at(ctx, source_id);
+ if (!source) {
+ goto next_loop;
+ }
+
+ if (i) { GRN_TEXT_PUTC(ctx, dumper->output, ','); }
+ switch (source->header.type) {
+ case GRN_TABLE_PAT_KEY:
+ case GRN_TABLE_DAT_KEY:
+ case GRN_TABLE_HASH_KEY:
+ GRN_TEXT_PUT(ctx,
+ dumper->output,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ break;
+ default:
+ dump_column_name(ctx, dumper, source);
+ break;
+ }
+
+ next_loop :
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ }
+ grn_obj_close(ctx, &sources);
+}
+
+static void
+dump_column(grn_ctx *ctx, grn_dumper *dumper, grn_obj *table, grn_obj *column)
+{
+ grn_id type_id;
+ grn_obj *type;
+ grn_column_flags flags;
+ grn_column_flags default_flags = GRN_OBJ_PERSISTENT;
+
+ type_id = grn_obj_get_range(ctx, column);
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+ type = grn_ctx_at(ctx, type_id);
+ if (!type) {
+ /* ERR(GRN_RANGE_ERROR, "couldn't get column's type object"); */
+ goto exit;
+ }
+
+ GRN_TEXT_PUTS(ctx, dumper->output, "column_create ");
+ dump_obj_name(ctx, dumper, table);
+ GRN_TEXT_PUTC(ctx, dumper->output, ' ');
+ dump_column_name(ctx, dumper, column);
+ GRN_TEXT_PUTC(ctx, dumper->output, ' ');
+ if (type->header.type == GRN_TYPE) {
+ default_flags |= type->header.flags;
+ }
+ flags = grn_column_get_flags(ctx, column);
+ grn_dump_column_create_flags(ctx,
+ flags & ~default_flags,
+ dumper->output);
+ GRN_TEXT_PUTC(ctx, dumper->output, ' ');
+ dump_obj_name(ctx, dumper, type);
+ if (column->header.flags & GRN_OBJ_COLUMN_INDEX) {
+ dump_index_column_sources(ctx, dumper, column);
+ }
+ GRN_TEXT_PUTC(ctx, dumper->output, '\n');
+
+exit :
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+}
+
+static void
+dump_columns(grn_ctx *ctx, grn_dumper *dumper, grn_obj *table,
+ grn_bool dump_data_column,
+ grn_bool dump_reference_column,
+ grn_bool dump_index_column)
+{
+ grn_hash *columns;
+ columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ if (!columns) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_NO_MEMORY_AVAILABLE,
+ "couldn't create a hash to hold columns");
+ return;
+ }
+
+ if (grn_table_columns(ctx, table, NULL, 0, (grn_obj *)columns) >= 0) {
+ GRN_HASH_EACH_BEGIN(ctx, columns, cursor, id) {
+ void *key;
+ grn_id column_id;
+ grn_obj *column;
+
+ grn_hash_cursor_get_key(ctx, cursor, &key);
+ column_id = *((grn_id *)key);
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ column = grn_ctx_at(ctx, column_id);
+ if (!column) {
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ goto next_loop;
+ }
+
+ if (grn_obj_is_index_column(ctx, column)) {
+ if (dump_index_column) {
+ dump_column(ctx, dumper, table, column);
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ }
+ } else if (grn_obj_is_reference_column(ctx, column)) {
+ if (dump_reference_column) {
+ dump_column(ctx, dumper, table, column);
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ }
+ } else {
+ if (dump_data_column) {
+ dump_column(ctx, dumper, table, column);
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ }
+ }
+
+ next_loop :
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
+ }
+ grn_hash_close(ctx, columns);
+}
+
+static void
+dump_record_column_vector(grn_ctx *ctx, grn_dumper *dumper, grn_id id,
+ grn_obj *column, grn_id range_id, grn_obj *buf)
+{
+ grn_obj *range;
+ grn_obj_format *format_argument = NULL;
+ grn_obj_format format;
+
+ range = grn_ctx_at(ctx, range_id);
+ if (column->header.flags & GRN_OBJ_WITH_WEIGHT) {
+ format.flags = GRN_OBJ_FORMAT_WITH_WEIGHT;
+ format_argument = &format;
+ }
+
+ if (grn_obj_is_table(ctx, range) ||
+ (range->header.flags & GRN_OBJ_KEY_VAR_SIZE) == 0) {
+ GRN_OBJ_INIT(buf, GRN_UVECTOR, 0, range_id);
+ grn_obj_get_value(ctx, column, id, buf);
+ grn_text_otoj(ctx, dumper->output, buf, format_argument);
+ } else {
+ GRN_OBJ_INIT(buf, GRN_VECTOR, 0, range_id);
+ grn_obj_get_value(ctx, column, id, buf);
+ grn_text_otoj(ctx, dumper->output, buf, format_argument);
+ }
+
+ grn_obj_unlink(ctx, range);
+ grn_obj_unlink(ctx, buf);
+}
+
+static void
+dump_record(grn_ctx *ctx, grn_dumper *dumper,
+ grn_obj *table,
+ grn_id id,
+ grn_obj *columns, int n_columns)
+{
+ int j;
+ grn_obj buf;
+ grn_obj *column_name = &(dumper->column_name_buffer);
+
+ GRN_TEXT_PUTC(ctx, dumper->output, '[');
+ for (j = 0; j < n_columns; j++) {
+ grn_bool is_value_column;
+ grn_id range;
+ grn_obj *column;
+ column = GRN_PTR_VALUE_AT(columns, j);
+ /* TODO: use grn_obj_is_value_accessor() */
+ GRN_BULK_REWIND(column_name);
+ grn_column_name_(ctx, column, column_name);
+ if (GRN_TEXT_LEN(column_name) == GRN_COLUMN_NAME_VALUE_LEN &&
+ !memcmp(GRN_TEXT_VALUE(column_name),
+ GRN_COLUMN_NAME_VALUE,
+ GRN_COLUMN_NAME_VALUE_LEN)) {
+ is_value_column = GRN_TRUE;
+ } else {
+ is_value_column = GRN_FALSE;
+ }
+ range = grn_obj_get_range(ctx, column);
+
+ if (j) { GRN_TEXT_PUTC(ctx, dumper->output, ','); }
+ switch (column->header.type) {
+ case GRN_COLUMN_VAR_SIZE:
+ case GRN_COLUMN_FIX_SIZE:
+ switch (column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) {
+ case GRN_OBJ_COLUMN_VECTOR:
+ dump_record_column_vector(ctx, dumper, id, column, range, &buf);
+ break;
+ case GRN_OBJ_COLUMN_SCALAR:
+ {
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, range);
+ grn_obj_get_value(ctx, column, id, &buf);
+ grn_text_otoj(ctx, dumper->output, &buf, NULL);
+ grn_obj_unlink(ctx, &buf);
+ }
+ break;
+ default:
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_OPERATION_NOT_SUPPORTED,
+ "unsupported column type: %#x",
+ column->header.type);
+ break;
+ }
+ break;
+ case GRN_COLUMN_INDEX:
+ break;
+ case GRN_ACCESSOR:
+ {
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, range);
+ grn_obj_get_value(ctx, column, id, &buf);
+ /* XXX maybe, grn_obj_get_range() should not unconditionally return
+ GRN_DB_INT32 when column is GRN_ACCESSOR and
+ GRN_ACCESSOR_GET_VALUE */
+ if (is_value_column) {
+ buf.header.domain = grn_obj_get_range(ctx, table);
+ }
+ grn_text_otoj(ctx, dumper->output, &buf, NULL);
+ grn_obj_unlink(ctx, &buf);
+ }
+ break;
+ default:
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_OPERATION_NOT_SUPPORTED,
+ "unsupported header type %#x",
+ column->header.type);
+ break;
+ }
+ }
+ GRN_TEXT_PUTC(ctx, dumper->output, ']');
+ if (GRN_TEXT_LEN(dumper->output) >= DUMP_FLUSH_THRESHOLD_SIZE) {
+ grn_ctx_output_flush(ctx, 0);
+ }
+}
+
+static void
+dump_records(grn_ctx *ctx, grn_dumper *dumper, grn_obj *table)
+{
+ grn_table_cursor *cursor;
+ int i, n_columns;
+ grn_obj columns;
+ grn_bool have_index_column = GRN_FALSE;
+ grn_bool have_data_column = GRN_FALSE;
+
+ if (grn_table_size(ctx, table) == 0) {
+ return;
+ }
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ GRN_PTR_INIT(&columns, GRN_OBJ_VECTOR, GRN_ID_NIL);
+
+ if (table->header.type == GRN_TABLE_NO_KEY) {
+ grn_obj *id_accessor;
+ id_accessor = grn_obj_column(ctx,
+ table,
+ GRN_COLUMN_NAME_ID,
+ GRN_COLUMN_NAME_ID_LEN);
+ GRN_PTR_PUT(ctx, &columns, id_accessor);
+ } else if (table->header.domain != GRN_ID_NIL) {
+ grn_obj *key_accessor;
+ key_accessor = grn_obj_column(ctx,
+ table,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ GRN_PTR_PUT(ctx, &columns, key_accessor);
+ }
+
+ if (grn_obj_get_range(ctx, table) != GRN_ID_NIL) {
+ grn_obj *value_accessor;
+ value_accessor = grn_obj_column(ctx,
+ table,
+ GRN_COLUMN_NAME_VALUE,
+ GRN_COLUMN_NAME_VALUE_LEN);
+ GRN_PTR_PUT(ctx, &columns, value_accessor);
+ }
+
+ {
+ grn_hash *real_columns;
+
+ real_columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ grn_table_columns(ctx, table, NULL, 0, (grn_obj *)real_columns);
+ GRN_HASH_EACH_BEGIN(ctx, real_columns, cursor, id) {
+ void *key;
+ grn_id column_id;
+ grn_obj *column;
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ grn_hash_cursor_get_key(ctx, cursor, &key);
+ column_id = *((grn_id *)key);
+
+ column = grn_ctx_at(ctx, column_id);
+ if (column) {
+ if (grn_obj_is_index_column(ctx, column)) {
+ have_index_column = GRN_TRUE;
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } else {
+ have_data_column = GRN_TRUE;
+ GRN_PTR_PUT(ctx, &columns, column);
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_merge_temporary_open_space(ctx);
+ }
+ }
+ } else {
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
+ grn_hash_close(ctx, real_columns);
+ }
+
+ n_columns = GRN_BULK_VSIZE(&columns) / sizeof(grn_obj *);
+
+ if (have_index_column && !have_data_column) {
+ goto exit;
+ }
+
+ if (GRN_TEXT_LEN(dumper->output) > 0) {
+ GRN_TEXT_PUTC(ctx, dumper->output, '\n');
+ }
+
+ GRN_TEXT_PUTS(ctx, dumper->output, "load --table ");
+ dump_obj_name(ctx, dumper, table);
+ GRN_TEXT_PUTS(ctx, dumper->output, "\n[\n");
+
+ GRN_TEXT_PUTC(ctx, dumper->output, '[');
+ for (i = 0; i < n_columns; i++) {
+ grn_obj *column;
+ grn_obj *column_name = &(dumper->column_name_buffer);
+
+ column = GRN_PTR_VALUE_AT(&columns, i);
+ if (i) { GRN_TEXT_PUTC(ctx, dumper->output, ','); }
+ GRN_BULK_REWIND(column_name);
+ grn_column_name_(ctx, column, column_name);
+ grn_text_otoj(ctx, dumper->output, column_name, NULL);
+ }
+ GRN_TEXT_PUTS(ctx, dumper->output, "],\n");
+
+ if (table->header.type == GRN_TABLE_HASH_KEY && dumper->is_sort_hash_table) {
+ grn_obj *sorted;
+ grn_table_sort_key sort_keys[1];
+ uint32_t n_sort_keys = 1;
+ grn_bool is_first_record = GRN_TRUE;
+
+ sort_keys[0].key = grn_obj_column(ctx, table,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ sort_keys[0].flags = GRN_TABLE_SORT_ASC;
+ sort_keys[0].offset = 0;
+ sorted = grn_table_create(ctx,
+ NULL, 0, NULL,
+ GRN_TABLE_NO_KEY,
+ NULL,
+ table);
+ grn_table_sort(ctx,
+ table, 0, -1,
+ sorted,
+ sort_keys, n_sort_keys);
+ cursor = grn_table_cursor_open(ctx,
+ sorted,
+ NULL, 0, NULL, 0,
+ 0, -1,
+ 0);
+ while (grn_table_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ void *value_raw;
+ grn_id id;
+
+ grn_table_cursor_get_value(ctx, cursor, &value_raw);
+ id = *((grn_id *)value_raw);
+
+ if (is_first_record) {
+ is_first_record = GRN_FALSE;
+ } else {
+ GRN_TEXT_PUTS(ctx, dumper->output, ",\n");
+ }
+ dump_record(ctx, dumper, table, id, &columns, n_columns);
+ }
+ GRN_TEXT_PUTS(ctx, dumper->output, "\n]\n");
+ grn_obj_close(ctx, sorted);
+ grn_obj_unlink(ctx, sort_keys[0].key);
+ } else {
+ grn_obj delete_commands;
+ grn_id old_id = GRN_ID_NIL;
+ grn_id id;
+
+ GRN_TEXT_INIT(&delete_commands, 0);
+ cursor = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1,
+ GRN_CURSOR_BY_KEY);
+ while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ if (old_id != GRN_ID_NIL) { GRN_TEXT_PUTS(ctx, dumper->output, ",\n"); }
+ if (table->header.type == GRN_TABLE_NO_KEY && old_id + 1 < id) {
+ grn_id current_id;
+ for (current_id = old_id + 1; current_id < id; current_id++) {
+ GRN_TEXT_PUTS(ctx, dumper->output, "[],\n");
+ GRN_TEXT_PUTS(ctx, &delete_commands, "delete --table ");
+ dump_obj_name_raw(ctx, &delete_commands, table);
+ GRN_TEXT_PUTS(ctx, &delete_commands, " --id ");
+ grn_text_lltoa(ctx, &delete_commands, current_id);
+ GRN_TEXT_PUTC(ctx, &delete_commands, '\n');
+ }
+ }
+ dump_record(ctx, dumper, table, id, &columns, n_columns);
+
+ old_id = id;
+ }
+ grn_table_cursor_close(ctx, cursor);
+ GRN_TEXT_PUTS(ctx, dumper->output, "\n]\n");
+ GRN_TEXT_PUT(ctx, dumper->output,
+ GRN_TEXT_VALUE(&delete_commands),
+ GRN_TEXT_LEN(&delete_commands));
+ GRN_OBJ_FIN(ctx, &delete_commands);
+ }
+exit :
+ for (i = 0; i < n_columns; i++) {
+ grn_obj *column;
+
+ column = GRN_PTR_VALUE_AT(&columns, i);
+ if (column->header.type == GRN_ACCESSOR) {
+ grn_obj_close(ctx, column);
+ }
+ }
+ GRN_OBJ_FIN(ctx, &columns);
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+}
+
+static void
+dump_table(grn_ctx *ctx, grn_dumper *dumper, grn_obj *table)
+{
+ grn_obj *domain = NULL;
+ grn_id range_id;
+ grn_obj *range = NULL;
+ grn_table_flags flags;
+ grn_table_flags default_flags = GRN_OBJ_PERSISTENT;
+ grn_obj *default_tokenizer;
+ grn_obj *normalizer;
+ grn_obj *token_filters;
+
+ switch (table->header.type) {
+ case GRN_TABLE_HASH_KEY:
+ case GRN_TABLE_PAT_KEY:
+ case GRN_TABLE_DAT_KEY:
+ domain = grn_ctx_at(ctx, table->header.domain);
+ break;
+ default:
+ break;
+ }
+
+ if (GRN_TEXT_LEN(dumper->output) > 0) {
+ GRN_TEXT_PUTC(ctx, dumper->output, '\n');
+ grn_ctx_output_flush(ctx, 0);
+ }
+
+ grn_table_get_info(ctx, table,
+ &flags,
+ NULL,
+ &default_tokenizer,
+ &normalizer,
+ &token_filters);
+
+ GRN_TEXT_PUTS(ctx, dumper->output, "table_create ");
+ dump_obj_name(ctx, dumper, table);
+ GRN_TEXT_PUTC(ctx, dumper->output, ' ');
+ grn_dump_table_create_flags(ctx,
+ flags & ~default_flags,
+ dumper->output);
+ if (domain) {
+ GRN_TEXT_PUTC(ctx, dumper->output, ' ');
+ dump_obj_name(ctx, dumper, domain);
+ }
+ range_id = grn_obj_get_range(ctx, table);
+ if (range_id != GRN_ID_NIL) {
+ range = grn_ctx_at(ctx, range_id);
+ if (!range) {
+ // ERR(GRN_RANGE_ERROR, "couldn't get table's value_type object");
+ return;
+ }
+ if (table->header.type != GRN_TABLE_NO_KEY) {
+ GRN_TEXT_PUTC(ctx, dumper->output, ' ');
+ } else {
+ GRN_TEXT_PUTS(ctx, dumper->output, " --value_type ");
+ }
+ dump_obj_name(ctx, dumper, range);
+ grn_obj_unlink(ctx, range);
+ }
+ if (default_tokenizer) {
+ GRN_TEXT_PUTS(ctx, dumper->output, " --default_tokenizer ");
+ dump_obj_name(ctx, dumper, default_tokenizer);
+ }
+ if (normalizer) {
+ GRN_TEXT_PUTS(ctx, dumper->output, " --normalizer ");
+ dump_obj_name(ctx, dumper, normalizer);
+ }
+ if (table->header.type != GRN_TABLE_NO_KEY) {
+ int n_token_filters;
+
+ n_token_filters = GRN_BULK_VSIZE(token_filters) / sizeof(grn_obj *);
+ if (n_token_filters > 0) {
+ int i;
+ GRN_TEXT_PUTS(ctx, dumper->output, " --token_filters ");
+ for (i = 0; i < n_token_filters; i++) {
+ grn_obj *token_filter = GRN_PTR_VALUE_AT(token_filters, i);
+ if (i > 0) {
+ GRN_TEXT_PUTC(ctx, dumper->output, ',');
+ }
+ dump_obj_name(ctx, dumper, token_filter);
+ }
+ }
+ }
+
+ GRN_TEXT_PUTC(ctx, dumper->output, '\n');
+
+ dump_columns(ctx, dumper, table, GRN_TRUE, GRN_FALSE, GRN_FALSE);
+}
+
+static void
+dump_schema(grn_ctx *ctx, grn_dumper *dumper)
+{
+ GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) {
+ void *name;
+ int name_size;
+ grn_obj *object;
+
+ if (grn_id_is_builtin(ctx, id)) {
+ continue;
+ }
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+ if (grn_obj_name_is_column(ctx, name, name_size)) {
+ continue;
+ }
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ if ((object = grn_ctx_at(ctx, id))) {
+ switch (object->header.type) {
+ case GRN_TABLE_HASH_KEY:
+ case GRN_TABLE_PAT_KEY:
+ case GRN_TABLE_DAT_KEY:
+ case GRN_TABLE_NO_KEY:
+ dump_table(ctx, dumper, object);
+ break;
+ default:
+ break;
+ }
+ } else {
+ /* XXX: this clause is executed when MeCab tokenizer is enabled in
+ database but the groonga isn't supported MeCab.
+ We should return error mesage about it and error exit status
+ but it's too difficult for this architecture. :< */
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ }
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_DB_EACH_END(ctx, cursor);
+
+ if (!dumper->have_reference_column) {
+ return;
+ }
+
+ GRN_TEXT_PUTC(ctx, dumper->output, '\n');
+ grn_ctx_output_flush(ctx, 0);
+
+ GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) {
+ void *name;
+ int name_size;
+ grn_obj *object;
+
+ if (grn_id_is_builtin(ctx, id)) {
+ continue;
+ }
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+ if (grn_obj_name_is_column(ctx, name, name_size)) {
+ continue;
+ }
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ if ((object = grn_ctx_at(ctx, id))) {
+ switch (object->header.type) {
+ case GRN_TABLE_HASH_KEY:
+ case GRN_TABLE_PAT_KEY:
+ case GRN_TABLE_DAT_KEY:
+ case GRN_TABLE_NO_KEY:
+ dump_columns(ctx, dumper, object, GRN_FALSE, GRN_TRUE, GRN_FALSE);
+ break;
+ default:
+ break;
+ }
+ } else {
+ /* XXX: this clause is executed when MeCab tokenizer is enabled in
+ database but the groonga isn't supported MeCab.
+ We should return error mesage about it and error exit status
+ but it's too difficult for this architecture. :< */
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ }
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_DB_EACH_END(ctx, cursor);
+}
+
+static void
+dump_selected_tables_records(grn_ctx *ctx, grn_dumper *dumper, grn_obj *tables)
+{
+ const char *p, *e;
+
+ p = GRN_TEXT_VALUE(tables);
+ e = p + GRN_TEXT_LEN(tables);
+ while (p < e) {
+ int len;
+ grn_obj *table;
+ const char *token, *token_e;
+
+ if ((len = grn_isspace(p, ctx->encoding))) {
+ p += len;
+ continue;
+ }
+
+ token = p;
+ if (!(('a' <= *p && *p <= 'z') ||
+ ('A' <= *p && *p <= 'Z') ||
+ (*p == '_'))) {
+ while (p < e && !grn_isspace(p, ctx->encoding)) {
+ p++;
+ }
+ GRN_LOG(ctx, GRN_LOG_WARNING, "invalid table name is ignored: <%.*s>\n",
+ (int)(p - token), token);
+ continue;
+ }
+ while (p < e &&
+ (('a' <= *p && *p <= 'z') ||
+ ('A' <= *p && *p <= 'Z') ||
+ ('0' <= *p && *p <= '9') ||
+ (*p == '_'))) {
+ p++;
+ }
+ token_e = p;
+ while (p < e && (len = grn_isspace(p, ctx->encoding))) {
+ p += len;
+ continue;
+ }
+ if (p < e && *p == ',') {
+ p++;
+ }
+
+ table = grn_ctx_get(ctx, token, token_e - token);
+ if (!table) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "nonexistent table name is ignored: <%.*s>\n",
+ (int)(token_e - token), token);
+ continue;
+ }
+
+ if (grn_obj_is_table(ctx, table)) {
+ dump_records(ctx, dumper, table);
+ }
+ grn_obj_unlink(ctx, table);
+ }
+}
+
+static void
+dump_all_records(grn_ctx *ctx, grn_dumper *dumper)
+{
+ GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) {
+ void *name;
+ int name_size;
+ grn_obj *table;
+
+ if (grn_id_is_builtin(ctx, id)) {
+ continue;
+ }
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+ if (grn_obj_name_is_column(ctx, name, name_size)) {
+ continue;
+ }
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ table = grn_ctx_at(ctx, id);
+ if (!table) {
+ /* XXX: this clause is executed when MeCab tokenizer is enabled in
+ database but the groonga isn't supported MeCab.
+ We should return error mesage about it and error exit status
+ but it's too difficult for this architecture. :< */
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ goto next_loop;
+ }
+
+ if (grn_obj_is_table(ctx, table)) {
+ dump_records(ctx, dumper, table);
+ }
+
+ next_loop :
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_DB_EACH_END(ctx, cursor);
+}
+
+static void
+dump_indexes(grn_ctx *ctx, grn_dumper *dumper)
+{
+ if (!dumper->have_index_column) {
+ return;
+ }
+
+ if (GRN_TEXT_LEN(dumper->output) > 0) {
+ GRN_TEXT_PUTC(ctx, dumper->output, '\n');
+ }
+
+ GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) {
+ void *name;
+ int name_size;
+ grn_obj *object;
+
+ if (grn_id_is_builtin(ctx, id)) {
+ continue;
+ }
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+ if (grn_obj_name_is_column(ctx, name, name_size)) {
+ continue;
+ }
+
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ object = grn_ctx_at(ctx, id);
+ if (!object) {
+ /* XXX: this clause is executed when MeCab tokenizer is enabled in
+ database but the groonga isn't supported MeCab.
+ We should return error mesage about it and error exit status
+ but it's too difficult for this architecture. :< */
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ goto next_loop;
+ }
+
+ if (grn_obj_is_table(ctx, object)) {
+ dump_columns(ctx, dumper, object, GRN_FALSE, GRN_FALSE, GRN_TRUE);
+ }
+
+ next_loop :
+ if (dumper->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_DB_EACH_END(ctx, cursor);
+}
+
+static grn_obj *
+command_dump(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_dumper dumper;
+ grn_obj *tables;
+ grn_bool is_dump_plugins;
+ grn_bool is_dump_schema;
+ grn_bool is_dump_records;
+ grn_bool is_dump_indexes;
+ grn_bool is_dump_configs;
+
+ dumper.output = ctx->impl->output.buf;
+ if (grn_thread_get_limit() == 1) {
+ dumper.is_close_opened_object_mode = GRN_TRUE;
+ } else {
+ dumper.is_close_opened_object_mode = GRN_FALSE;
+ }
+ dumper.have_reference_column = GRN_FALSE;
+ dumper.have_index_column = GRN_FALSE;
+
+ tables = grn_plugin_proc_get_var(ctx, user_data, "tables", -1);
+ is_dump_plugins = grn_plugin_proc_get_var_bool(ctx, user_data,
+ "dump_plugins", -1,
+ GRN_TRUE);
+ is_dump_schema = grn_plugin_proc_get_var_bool(ctx, user_data,
+ "dump_schema", -1,
+ GRN_TRUE);
+ is_dump_records = grn_plugin_proc_get_var_bool(ctx, user_data,
+ "dump_records", -1,
+ GRN_TRUE);
+ is_dump_indexes = grn_plugin_proc_get_var_bool(ctx, user_data,
+ "dump_indexes", -1,
+ GRN_TRUE);
+ is_dump_configs = grn_plugin_proc_get_var_bool(ctx, user_data,
+ "dump_configs", -1,
+ GRN_TRUE);
+ dumper.is_sort_hash_table =
+ grn_plugin_proc_get_var_bool(ctx, user_data,
+ "sort_hash_table", -1,
+ GRN_FALSE);
+ GRN_TEXT_INIT(&(dumper.column_name_buffer), 0);
+
+ grn_ctx_set_output_type(ctx, GRN_CONTENT_GROONGA_COMMAND_LIST);
+
+ dumper_collect_statistics(ctx, &dumper);
+
+ if (is_dump_configs) {
+ dump_configs(ctx, &dumper);
+ }
+ if (is_dump_plugins) {
+ dump_plugins(ctx, &dumper);
+ }
+ if (is_dump_schema) {
+ dump_schema(ctx, &dumper);
+ }
+ if (is_dump_records) {
+ /* To update index columns correctly, we first create the whole schema, then
+ load non-derivative records, while skipping records of index columns. That
+ way, Groonga will silently do the job of updating index columns for us. */
+ if (GRN_TEXT_LEN(tables) > 0) {
+ dump_selected_tables_records(ctx, &dumper, tables);
+ } else {
+ dump_all_records(ctx, &dumper);
+ }
+ }
+ if (is_dump_indexes) {
+ dump_indexes(ctx, &dumper);
+ }
+ /* remove the last newline because another one will be added by the caller.
+ maybe, the caller of proc functions currently doesn't consider the
+ possibility of multiple-line output from proc functions. */
+ if (GRN_BULK_VSIZE(dumper.output) > 0) {
+ grn_bulk_truncate(ctx, dumper.output, GRN_BULK_VSIZE(dumper.output) - 1);
+ }
+
+ GRN_OBJ_FIN(ctx, &(dumper.column_name_buffer));
+
+ return NULL;
+}
+
+void
+grn_proc_init_dump(grn_ctx *ctx)
+{
+ grn_expr_var vars[7];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "tables", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "dump_plugins", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[2]), "dump_schema", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[3]), "dump_records", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[4]), "dump_indexes", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[5]), "dump_configs", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[6]), "sort_hash_table", -1);
+ grn_plugin_command_create(ctx,
+ "dump", -1,
+ command_dump,
+ sizeof(vars) / sizeof(vars[0]),
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_fuzzy_search.c b/storage/mroonga/vendor/groonga/lib/proc/proc_fuzzy_search.c
new file mode 100644
index 00000000000..bb1b6a65fe4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_fuzzy_search.c
@@ -0,0 +1,467 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+#include "../grn_rset.h"
+#include "../grn_ii.h"
+
+#include <groonga/plugin.h>
+
+#include <string.h>
+
+#define DIST(ox,oy) (dists[((lx + 1) * (oy)) + (ox)])
+
+static uint32_t
+calc_edit_distance(grn_ctx *ctx, char *sx, char *ex, char *sy, char *ey, int flags)
+{
+ int d = 0;
+ uint32_t cx, lx, cy, ly, *dists;
+ char *px, *py;
+ for (px = sx, lx = 0; px < ex && (cx = grn_charlen(ctx, px, ex)); px += cx, lx++);
+ for (py = sy, ly = 0; py < ey && (cy = grn_charlen(ctx, py, ey)); py += cy, ly++);
+ if ((dists = GRN_PLUGIN_MALLOC(ctx, (lx + 1) * (ly + 1) * sizeof(uint32_t)))) {
+ uint32_t x, y;
+ for (x = 0; x <= lx; x++) { DIST(x, 0) = x; }
+ for (y = 0; y <= ly; y++) { DIST(0, y) = y; }
+ for (x = 1, px = sx; x <= lx; x++, px += cx) {
+ cx = grn_charlen(ctx, px, ex);
+ for (y = 1, py = sy; y <= ly; y++, py += cy) {
+ cy = grn_charlen(ctx, py, ey);
+ if (cx == cy && !memcmp(px, py, cx)) {
+ DIST(x, y) = DIST(x - 1, y - 1);
+ } else {
+ uint32_t a = DIST(x - 1, y) + 1;
+ uint32_t b = DIST(x, y - 1) + 1;
+ uint32_t c = DIST(x - 1, y - 1) + 1;
+ DIST(x, y) = ((a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c));
+ if (flags & GRN_TABLE_FUZZY_SEARCH_WITH_TRANSPOSITION &&
+ x > 1 && y > 1 && cx == cy &&
+ memcmp(px, py - cy, cx) == 0 &&
+ memcmp(px - cx, py, cx) == 0) {
+ uint32_t t = DIST(x - 2, y - 2) + 1;
+ DIST(x, y) = ((DIST(x, y) < t) ? DIST(x, y) : t);
+ }
+ }
+ }
+ }
+ d = DIST(lx, ly);
+ GRN_PLUGIN_FREE(ctx, dists);
+ }
+ return d;
+}
+
+static grn_obj *
+func_edit_distance(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+#define N_REQUIRED_ARGS 2
+#define MAX_ARGS 3
+ int d = 0;
+ int flags = 0;
+ grn_obj *obj;
+ if (nargs >= N_REQUIRED_ARGS && nargs <= MAX_ARGS) {
+ if (nargs == MAX_ARGS && GRN_BOOL_VALUE(args[2])) {
+ flags |= GRN_TABLE_FUZZY_SEARCH_WITH_TRANSPOSITION;
+ }
+ d = calc_edit_distance(ctx, GRN_TEXT_VALUE(args[0]), GRN_BULK_CURR(args[0]),
+ GRN_TEXT_VALUE(args[1]), GRN_BULK_CURR(args[1]), flags);
+ }
+ if ((obj = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_UINT32, 0))) {
+ GRN_UINT32_SET(ctx, obj, d);
+ }
+ return obj;
+#undef N_REQUIRED_ARGS
+#undef MAX_ARGS
+}
+
+void
+grn_proc_init_edit_distance(grn_ctx *ctx)
+{
+ grn_proc_create(ctx, "edit_distance", -1, GRN_PROC_FUNCTION,
+ func_edit_distance, NULL, NULL, 0, NULL);
+}
+
+#define SCORE_HEAP_SIZE 256
+
+typedef struct {
+ grn_id id;
+ uint32_t score;
+} score_heap_node;
+
+typedef struct {
+ int n_entries;
+ int limit;
+ score_heap_node *nodes;
+} score_heap;
+
+static inline score_heap *
+score_heap_open(grn_ctx *ctx, int max)
+{
+ score_heap *h = GRN_PLUGIN_MALLOC(ctx, sizeof(score_heap));
+ if (!h) { return NULL; }
+ h->nodes = GRN_PLUGIN_MALLOC(ctx, sizeof(score_heap_node) * max);
+ if (!h->nodes) {
+ GRN_PLUGIN_FREE(ctx, h);
+ return NULL;
+ }
+ h->n_entries = 0;
+ h->limit = max;
+ return h;
+}
+
+static inline grn_bool
+score_heap_push(grn_ctx *ctx, score_heap *h, grn_id id, uint32_t score)
+{
+ int n, n2;
+ score_heap_node node = {id, score};
+ score_heap_node node2;
+ if (h->n_entries >= h->limit) {
+ int max = h->limit * 2;
+ score_heap_node *nodes;
+ nodes = GRN_PLUGIN_REALLOC(ctx, h->nodes, sizeof(score_heap) * max);
+ if (!nodes) {
+ return GRN_FALSE;
+ }
+ h->limit = max;
+ h->nodes = nodes;
+ }
+ h->nodes[h->n_entries] = node;
+ n = h->n_entries++;
+ while (n) {
+ n2 = (n - 1) >> 1;
+ if (h->nodes[n2].score <= h->nodes[n].score) { break; }
+ node2 = h->nodes[n];
+ h->nodes[n] = h->nodes[n2];
+ h->nodes[n2] = node2;
+ n = n2;
+ }
+ return GRN_TRUE;
+}
+
+static inline void
+score_heap_close(grn_ctx *ctx, score_heap *h)
+{
+ GRN_PLUGIN_FREE(ctx, h->nodes);
+ GRN_PLUGIN_FREE(ctx, h);
+}
+
+static grn_rc
+sequential_fuzzy_search(grn_ctx *ctx, grn_obj *table, grn_obj *column, grn_obj *query,
+ uint32_t max_distance, uint32_t prefix_match_size,
+ uint32_t max_expansion, int flags, grn_obj *res, grn_operator op)
+{
+ grn_table_cursor *tc;
+ char *sx = GRN_TEXT_VALUE(query);
+ char *ex = GRN_BULK_CURR(query);
+
+ if (op == GRN_OP_AND) {
+ tc = grn_table_cursor_open(ctx, res, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_ID);
+ } else {
+ tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_ID);
+ }
+ if (tc) {
+ grn_id id;
+ grn_obj value;
+ score_heap *heap;
+ int i, n;
+ GRN_TEXT_INIT(&value, 0);
+
+ heap = score_heap_open(ctx, SCORE_HEAP_SIZE);
+ if (!heap) {
+ grn_table_cursor_close(ctx, tc);
+ grn_obj_unlink(ctx, &value);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+
+ while ((id = grn_table_cursor_next(ctx, tc))) {
+ unsigned int distance = 0;
+ grn_obj *domain;
+ grn_id record_id;
+
+ if (op == GRN_OP_AND) {
+ grn_id *key;
+ grn_table_cursor_get_key(ctx, tc, (void **)&key);
+ record_id = *key;
+ } else {
+ record_id = id;
+ }
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx, column, record_id, &value);
+ domain = grn_ctx_at(ctx, ((&value))->header.domain);
+ if ((&(value))->header.type == GRN_VECTOR) {
+ n = grn_vector_size(ctx, &value);
+ for (i = 0; i < n; i++) {
+ unsigned int length;
+ const char *vector_value = NULL;
+ length = grn_vector_get_element(ctx, &value, i, &vector_value, NULL, NULL);
+
+ if (!prefix_match_size ||
+ (prefix_match_size > 0 && length >= prefix_match_size &&
+ !memcmp(sx, vector_value, prefix_match_size))) {
+ distance = calc_edit_distance(ctx, sx, ex,
+ (char *)vector_value,
+ (char *)vector_value + length, flags);
+ if (distance <= max_distance) {
+ score_heap_push(ctx, heap, record_id, distance);
+ break;
+ }
+ }
+ }
+ } else if ((&(value))->header.type == GRN_UVECTOR &&
+ grn_obj_is_table(ctx, domain)) {
+ n = grn_vector_size(ctx, &value);
+ for (i = 0; i < n; i++) {
+ grn_id rid;
+ char key_name[GRN_TABLE_MAX_KEY_SIZE];
+ int key_length;
+ rid = grn_uvector_get_element(ctx, &value, i, NULL);
+ key_length = grn_table_get_key(ctx, domain, rid, key_name, GRN_TABLE_MAX_KEY_SIZE);
+
+ if (!prefix_match_size ||
+ (prefix_match_size > 0 && key_length >= prefix_match_size &&
+ !memcmp(sx, key_name, prefix_match_size))) {
+ distance = calc_edit_distance(ctx, sx, ex,
+ key_name, key_name + key_length, flags);
+ if (distance <= max_distance) {
+ score_heap_push(ctx, heap, record_id, distance);
+ break;
+ }
+ }
+ }
+ } else {
+ if (grn_obj_is_reference_column(ctx, column)) {
+ grn_id rid;
+ char key_name[GRN_TABLE_MAX_KEY_SIZE];
+ int key_length;
+ rid = GRN_RECORD_VALUE(&value);
+ key_length = grn_table_get_key(ctx, domain, rid, key_name, GRN_TABLE_MAX_KEY_SIZE);
+ if (!prefix_match_size ||
+ (prefix_match_size > 0 && key_length >= prefix_match_size &&
+ !memcmp(sx, key_name, prefix_match_size))) {
+ distance = calc_edit_distance(ctx, sx, ex,
+ key_name, key_name + key_length, flags);
+ if (distance <= max_distance) {
+ score_heap_push(ctx, heap, record_id, distance);
+ }
+ }
+ } else {
+ if (!prefix_match_size ||
+ (prefix_match_size > 0 && GRN_TEXT_LEN(&value) >= prefix_match_size &&
+ !memcmp(sx, GRN_TEXT_VALUE(&value), prefix_match_size))) {
+ distance = calc_edit_distance(ctx, sx, ex,
+ GRN_TEXT_VALUE(&value),
+ GRN_BULK_CURR(&value), flags);
+ if (distance <= max_distance) {
+ score_heap_push(ctx, heap, record_id, distance);
+ }
+ }
+ }
+ }
+ grn_obj_unlink(ctx, domain);
+ }
+ grn_table_cursor_close(ctx, tc);
+ grn_obj_unlink(ctx, &value);
+
+ for (i = 0; i < heap->n_entries; i++) {
+ if (max_expansion > 0 && i >= max_expansion) {
+ break;
+ }
+ {
+ grn_posting posting;
+ posting.rid = heap->nodes[i].id;
+ posting.sid = 1;
+ posting.pos = 0;
+ posting.weight = max_distance - heap->nodes[i].score;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
+ }
+ }
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
+ score_heap_close(ctx, heap);
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+selector_fuzzy_search(grn_ctx *ctx, grn_obj *table, grn_obj *index,
+ int nargs, grn_obj **args,
+ grn_obj *res, grn_operator op)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *target = NULL;
+ grn_obj *obj;
+ grn_obj *query;
+ uint32_t max_distance = 1;
+ uint32_t prefix_length = 0;
+ uint32_t prefix_match_size = 0;
+ uint32_t max_expansion = 0;
+ int flags = 0;
+ grn_bool use_sequential_search = GRN_FALSE;
+
+ if ((nargs - 1) < 2) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "fuzzy_search(): wrong number of arguments (%d ...)",
+ nargs - 1);
+ rc = ctx->rc;
+ goto exit;
+ }
+ obj = args[1];
+ query = args[2];
+
+ if (nargs == 4) {
+ grn_obj *options = args[3];
+
+ switch (options->header.type) {
+ case GRN_BULK :
+ max_distance = GRN_UINT32_VALUE(options);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ {
+ grn_hash_cursor *cursor;
+ void *key;
+ grn_obj *value;
+ int key_size;
+ cursor = grn_hash_cursor_open(ctx, (grn_hash *)options,
+ NULL, 0, NULL, 0,
+ 0, -1, 0);
+ if (!cursor) {
+ GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE,
+ "fuzzy_search(): couldn't open cursor");
+ goto exit;
+ }
+ while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ grn_hash_cursor_get_key_value(ctx, cursor, &key, &key_size,
+ (void **)&value);
+
+ if (key_size == 12 && !memcmp(key, "max_distance", 12)) {
+ max_distance = GRN_UINT32_VALUE(value);
+ } else if (key_size == 13 && !memcmp(key, "prefix_length", 13)) {
+ prefix_length = GRN_UINT32_VALUE(value);
+ } else if (key_size == 13 && !memcmp(key, "max_expansion", 13)) {
+ max_expansion = GRN_UINT32_VALUE(value);
+ } else if (key_size == 18 && !memcmp(key, "with_transposition", 18)) {
+ if (GRN_BOOL_VALUE(value)) {
+ flags |= GRN_TABLE_FUZZY_SEARCH_WITH_TRANSPOSITION;
+ }
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "invalid option name: <%.*s>",
+ key_size, (char *)key);
+ grn_hash_cursor_close(ctx, cursor);
+ goto exit;
+ }
+ }
+ grn_hash_cursor_close(ctx, cursor);
+ }
+ break;
+ default :
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "fuzzy_search(): "
+ "3rd argument must be integer or object literal: <%.*s>",
+ (int)GRN_TEXT_LEN(options),
+ GRN_TEXT_VALUE(options));
+ goto exit;
+ }
+ }
+
+ if (index) {
+ target = index;
+ } else {
+ if (obj->header.type == GRN_COLUMN_INDEX) {
+ target = obj;
+ } else {
+ grn_column_index(ctx, obj, GRN_OP_FUZZY, &target, 1, NULL);
+ }
+ }
+
+ if (target) {
+ grn_obj *lexicon;
+ use_sequential_search = GRN_TRUE;
+ lexicon = grn_ctx_at(ctx, target->header.domain);
+ if (lexicon) {
+ if (lexicon->header.type == GRN_TABLE_PAT_KEY) {
+ use_sequential_search = GRN_FALSE;
+ }
+ grn_obj_unlink(ctx, lexicon);
+ }
+ } else {
+ if (grn_obj_is_key_accessor(ctx, obj) &&
+ table->header.type == GRN_TABLE_PAT_KEY) {
+ target = table;
+ } else {
+ use_sequential_search = GRN_TRUE;
+ }
+ }
+
+ if (prefix_length) {
+ const char *s = GRN_TEXT_VALUE(query);
+ const char *e = GRN_BULK_CURR(query);
+ const char *p;
+ unsigned int cl = 0;
+ unsigned int length = 0;
+ for (p = s; p < e && (cl = grn_charlen(ctx, p, e)); p += cl) {
+ length++;
+ if (length > prefix_length) {
+ break;
+ }
+ }
+ prefix_match_size = p - s;
+ }
+
+ if (use_sequential_search) {
+ rc = sequential_fuzzy_search(ctx, table, obj, query,
+ max_distance, prefix_match_size,
+ max_expansion, flags, res, op);
+ goto exit;
+ }
+
+ if (!target) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, target);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "fuzzy_search(): "
+ "column must be COLUMN_INDEX or TABLE_PAT_KEY: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ rc = ctx->rc;
+ GRN_OBJ_FIN(ctx, &inspected);
+ } else {
+ grn_search_optarg options = {0};
+ options.mode = GRN_OP_FUZZY;
+ options.fuzzy.prefix_match_size = prefix_match_size;
+ options.fuzzy.max_distance = max_distance;
+ options.fuzzy.max_expansion = max_expansion;
+ options.fuzzy.flags = flags;
+ grn_obj_search(ctx, target, query, res, op, &options);
+ }
+
+exit :
+ return rc;
+}
+
+void
+grn_proc_init_fuzzy_search(grn_ctx *ctx)
+{
+ grn_obj *selector_proc;
+
+ selector_proc = grn_proc_create(ctx, "fuzzy_search", -1,
+ GRN_PROC_FUNCTION,
+ NULL, NULL, NULL, 0, NULL);
+ grn_proc_set_selector(ctx, selector_proc, selector_fuzzy_search);
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_FUZZY);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_highlight.c b/storage/mroonga/vendor/groonga/lib/proc/proc_highlight.c
new file mode 100644
index 00000000000..7d815184a0e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_highlight.c
@@ -0,0 +1,503 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+#include "../grn_expr.h"
+
+#include <groonga/plugin.h>
+#include <string.h>
+
+#define GRN_FUNC_HIGHLIGHT_HTML_CACHE_NAME "$highlight_html"
+
+static void
+grn_pat_tag_keys_put_original_text(grn_ctx *ctx, grn_obj *output,
+ const char *text, unsigned int length,
+ grn_bool use_html_escape)
+{
+ if (use_html_escape) {
+ grn_text_escape_xml(ctx, output, text, length);
+ } else {
+ GRN_TEXT_PUT(ctx, output, text, length);
+ }
+}
+
+static grn_rc
+grn_pat_tag_keys(grn_ctx *ctx, grn_obj *keywords,
+ const char *string, unsigned int string_length,
+ const char **open_tags, unsigned int *open_tag_lengths,
+ const char **close_tags, unsigned int *close_tag_lengths,
+ unsigned int n_tags,
+ grn_obj *highlighted,
+ grn_bool use_html_escape)
+{
+ while (string_length > 0) {
+#define MAX_N_HITS 16
+ grn_pat_scan_hit hits[MAX_N_HITS];
+ const char *rest;
+ unsigned int i, n_hits;
+ unsigned int previous = 0;
+ size_t chunk_length;
+
+ n_hits = grn_pat_scan(ctx, (grn_pat *)keywords,
+ string, string_length,
+ hits, MAX_N_HITS, &rest);
+ for (i = 0; i < n_hits; i++) {
+ unsigned int nth_tag;
+ if (hits[i].offset - previous > 0) {
+ grn_pat_tag_keys_put_original_text(ctx,
+ highlighted,
+ string + previous,
+ hits[i].offset - previous,
+ use_html_escape);
+ }
+ nth_tag = ((hits[i].id - 1) % n_tags);
+ GRN_TEXT_PUT(ctx, highlighted,
+ open_tags[nth_tag], open_tag_lengths[nth_tag]);
+ grn_pat_tag_keys_put_original_text(ctx,
+ highlighted,
+ string + hits[i].offset,
+ hits[i].length,
+ use_html_escape);
+ GRN_TEXT_PUT(ctx, highlighted,
+ close_tags[nth_tag], close_tag_lengths[nth_tag]);
+ previous = hits[i].offset + hits[i].length;
+ }
+
+ chunk_length = rest - string;
+ if (chunk_length - previous > 0) {
+ grn_pat_tag_keys_put_original_text(ctx,
+ highlighted,
+ string + previous,
+ string_length - previous,
+ use_html_escape);
+ }
+ string_length -= chunk_length;
+ string = rest;
+#undef MAX_N_HITS
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_obj *
+func_highlight_create_keywords_table(grn_ctx *ctx,
+ grn_user_data *user_data,
+ const char *normalizer_name,
+ unsigned int normalizer_name_length)
+{
+ grn_obj *keywords;
+
+ keywords = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_OBJ_TABLE_PAT_KEY,
+ grn_ctx_at(ctx, GRN_DB_SHORT_TEXT),
+ NULL);
+
+ if (normalizer_name_length > 0) {
+ grn_obj *normalizer;
+ normalizer = grn_ctx_get(ctx,
+ normalizer_name,
+ normalizer_name_length);
+ if (!grn_obj_is_normalizer_proc(ctx, normalizer)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, normalizer);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "highlight_full() not normalizer: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ grn_obj_unlink(ctx, normalizer);
+ grn_obj_unlink(ctx, keywords);
+ return NULL;
+ }
+ grn_obj_set_info(ctx, keywords, GRN_INFO_NORMALIZER, normalizer);
+ grn_obj_unlink(ctx, normalizer);
+ }
+
+ return keywords;
+}
+
+static grn_obj *
+highlight_keyword_sets(grn_ctx *ctx, grn_user_data *user_data,
+ grn_obj **keyword_set_args, unsigned int n_keyword_args,
+ grn_obj *string, grn_obj *keywords,
+ grn_bool use_html_escape)
+{
+ grn_obj *highlighted = NULL;
+#define KEYWORD_SET_SIZE 3
+ {
+ unsigned int i;
+ unsigned int n_keyword_sets;
+ grn_obj open_tags;
+ grn_obj open_tag_lengths;
+ grn_obj close_tags;
+ grn_obj close_tag_lengths;
+
+ n_keyword_sets = n_keyword_args / KEYWORD_SET_SIZE;
+
+ GRN_OBJ_INIT(&open_tags, GRN_BULK, 0, GRN_DB_VOID);
+ GRN_OBJ_INIT(&open_tag_lengths, GRN_BULK, 0, GRN_DB_VOID);
+ GRN_OBJ_INIT(&close_tags, GRN_BULK, 0, GRN_DB_VOID);
+ GRN_OBJ_INIT(&close_tag_lengths, GRN_BULK, 0, GRN_DB_VOID);
+
+ for (i = 0; i < n_keyword_sets; i++) {
+ grn_obj *keyword = keyword_set_args[i * KEYWORD_SET_SIZE + 0];
+ grn_obj *open_tag = keyword_set_args[i * KEYWORD_SET_SIZE + 1];
+ grn_obj *close_tag = keyword_set_args[i * KEYWORD_SET_SIZE + 2];
+
+ grn_table_add(ctx, keywords,
+ GRN_TEXT_VALUE(keyword),
+ GRN_TEXT_LEN(keyword),
+ NULL);
+ {
+ const char *open_tag_content = GRN_TEXT_VALUE(open_tag);
+ grn_bulk_write(ctx, &open_tags,
+ (const char *)(&open_tag_content),
+ sizeof(char *));
+ }
+ {
+ unsigned int open_tag_length = GRN_TEXT_LEN(open_tag);
+ grn_bulk_write(ctx, &open_tag_lengths,
+ (const char *)(&open_tag_length),
+ sizeof(unsigned int));
+ }
+ {
+ const char *close_tag_content = GRN_TEXT_VALUE(close_tag);
+ grn_bulk_write(ctx, &close_tags,
+ (const char *)(&close_tag_content),
+ sizeof(char *));
+ }
+ {
+ unsigned int close_tag_length = GRN_TEXT_LEN(close_tag);
+ grn_bulk_write(ctx, &close_tag_lengths,
+ (const char *)(&close_tag_length),
+ sizeof(unsigned int));
+ }
+ }
+
+ highlighted = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_TEXT, 0);
+ grn_pat_tag_keys(ctx, keywords,
+ GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string),
+ (const char **)GRN_BULK_HEAD(&open_tags),
+ (unsigned int *)GRN_BULK_HEAD(&open_tag_lengths),
+ (const char **)GRN_BULK_HEAD(&close_tags),
+ (unsigned int *)GRN_BULK_HEAD(&close_tag_lengths),
+ n_keyword_sets,
+ highlighted,
+ use_html_escape);
+ grn_obj_unlink(ctx, &open_tags);
+ grn_obj_unlink(ctx, &open_tag_lengths);
+ grn_obj_unlink(ctx, &close_tags);
+ grn_obj_unlink(ctx, &close_tag_lengths);
+ }
+#undef KEYWORD_SET_SIZE
+ return highlighted;
+}
+
+static grn_obj *
+highlight_keywords(grn_ctx *ctx, grn_user_data *user_data,
+ grn_obj *string, grn_obj *keywords, grn_bool use_html_escape,
+ const char *default_open_tag, unsigned int default_open_tag_length,
+ const char *default_close_tag, unsigned int default_close_tag_length)
+{
+ grn_obj *highlighted = NULL;
+ const char *open_tags[1];
+ unsigned int open_tag_lengths[1];
+ const char *close_tags[1];
+ unsigned int close_tag_lengths[1];
+ unsigned int n_keyword_sets = 1;
+
+ open_tags[0] = default_open_tag;
+ open_tag_lengths[0] = default_open_tag_length;
+ close_tags[0] = default_close_tag;
+ close_tag_lengths[0] = default_close_tag_length;
+
+ highlighted = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_TEXT, 0);
+ grn_pat_tag_keys(ctx, keywords,
+ GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string),
+ open_tags,
+ open_tag_lengths,
+ close_tags,
+ close_tag_lengths,
+ n_keyword_sets,
+ highlighted,
+ use_html_escape);
+
+ return highlighted;
+}
+
+static grn_obj *
+func_highlight(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *highlighted = NULL;
+
+#define N_REQUIRED_ARGS 1
+ if (nargs > N_REQUIRED_ARGS) {
+ grn_obj *string = args[0];
+ grn_bool use_html_escape = GRN_FALSE;
+ grn_obj *keywords;
+ const char *normalizer_name = "NormalizerAuto";
+ unsigned int normalizer_name_length = 14;
+ const char *default_open_tag = NULL;
+ unsigned int default_open_tag_length = 0;
+ const char *default_close_tag = NULL;
+ unsigned int default_close_tag_length = 0;
+ grn_obj *end_arg = args[nargs - 1];
+ int n_args_without_option = nargs;
+
+ if (end_arg->header.type == GRN_TABLE_HASH_KEY) {
+ grn_obj *options = end_arg;
+ grn_hash_cursor *cursor;
+ void *key;
+ grn_obj *value;
+ int key_size;
+
+ n_args_without_option--;
+ cursor = grn_hash_cursor_open(ctx, (grn_hash *)options,
+ NULL, 0, NULL, 0,
+ 0, -1, 0);
+ if (!cursor) {
+ GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE,
+ "highlight(): couldn't open cursor");
+ goto exit;
+ }
+ while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ grn_hash_cursor_get_key_value(ctx, cursor, &key, &key_size,
+ (void **)&value);
+ if (key_size == 10 && !memcmp(key, "normalizer", 10)) {
+ normalizer_name = GRN_TEXT_VALUE(value);
+ normalizer_name_length = GRN_TEXT_LEN(value);
+ } else if (key_size == 11 && !memcmp(key, "html_escape", 11)) {
+ if (GRN_BOOL_VALUE(value)) {
+ use_html_escape = GRN_TRUE;
+ }
+ } else if (key_size == 16 && !memcmp(key, "default_open_tag", 16)) {
+ default_open_tag = GRN_TEXT_VALUE(value);
+ default_open_tag_length = GRN_TEXT_LEN(value);
+ } else if (key_size == 17 && !memcmp(key, "default_close_tag", 17)) {
+ default_close_tag = GRN_TEXT_VALUE(value);
+ default_close_tag_length = GRN_TEXT_LEN(value);
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "invalid option name: <%.*s>",
+ key_size, (char *)key);
+ grn_hash_cursor_close(ctx, cursor);
+ goto exit;
+ }
+ }
+ grn_hash_cursor_close(ctx, cursor);
+ }
+
+ keywords =
+ func_highlight_create_keywords_table(ctx, user_data,
+ normalizer_name,
+ normalizer_name_length);
+
+ if (keywords) {
+ grn_obj **keyword_args = args + N_REQUIRED_ARGS;
+ unsigned int n_keyword_args = n_args_without_option - N_REQUIRED_ARGS;
+ if (default_open_tag_length == 0 && default_close_tag_length == 0) {
+ highlighted = highlight_keyword_sets(ctx, user_data,
+ keyword_args, n_keyword_args,
+ string, keywords, use_html_escape);
+ } else {
+ unsigned int i;
+ for (i = 0; i < n_keyword_args; i++) {
+ grn_table_add(ctx, keywords,
+ GRN_TEXT_VALUE(keyword_args[i]),
+ GRN_TEXT_LEN(keyword_args[i]),
+ NULL);
+ }
+ highlighted = highlight_keywords(ctx, user_data,
+ string, keywords, use_html_escape,
+ default_open_tag, default_open_tag_length,
+ default_close_tag, default_close_tag_length);
+ }
+ }
+ }
+#undef N_REQUIRED_ARGS
+
+exit :
+ if (!highlighted) {
+ highlighted = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_VOID, 0);
+ }
+
+ return highlighted;
+}
+
+void
+grn_proc_init_highlight(grn_ctx *ctx)
+{
+ grn_proc_create(ctx, "highlight", -1, GRN_PROC_FUNCTION,
+ func_highlight, NULL, NULL, 0, NULL);
+}
+
+static grn_obj *
+func_highlight_full(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *highlighted = NULL;
+
+#define N_REQUIRED_ARGS 3
+#define KEYWORD_SET_SIZE 3
+ if ((nargs >= (N_REQUIRED_ARGS + KEYWORD_SET_SIZE) &&
+ (nargs - N_REQUIRED_ARGS) % KEYWORD_SET_SIZE == 0)) {
+ grn_obj *string = args[0];
+ grn_obj *keywords;
+ const char *normalizer_name = GRN_TEXT_VALUE(args[1]);
+ unsigned int normalizer_name_length = GRN_TEXT_LEN(args[1]);
+ grn_bool use_html_escape = GRN_BOOL_VALUE(args[2]);
+
+ keywords =
+ func_highlight_create_keywords_table(ctx, user_data,
+ normalizer_name,
+ normalizer_name_length);
+ if (keywords) {
+ highlighted = highlight_keyword_sets(ctx, user_data,
+ args + N_REQUIRED_ARGS,
+ nargs - N_REQUIRED_ARGS,
+ string, keywords,
+ use_html_escape);
+ }
+ }
+
+ if (!highlighted) {
+ highlighted = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_VOID, 0);
+ }
+#undef KEYWORD_SET_SIZE
+#undef N_REQUIRED_ARGS
+
+ return highlighted;
+}
+
+void
+grn_proc_init_highlight_full(grn_ctx *ctx)
+{
+ grn_proc_create(ctx, "highlight_full", -1, GRN_PROC_FUNCTION,
+ func_highlight_full, NULL, NULL, 0, NULL);
+}
+
+static grn_obj *
+func_highlight_html_create_keywords_table(grn_ctx *ctx, grn_obj *expression)
+{
+ grn_obj *keywords;
+ grn_obj *condition_ptr = NULL;
+ grn_obj *condition = NULL;
+
+ keywords = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_OBJ_TABLE_PAT_KEY,
+ grn_ctx_at(ctx, GRN_DB_SHORT_TEXT),
+ NULL);
+
+ {
+ grn_obj *normalizer;
+ normalizer = grn_ctx_get(ctx, "NormalizerAuto", -1);
+ grn_obj_set_info(ctx, keywords, GRN_INFO_NORMALIZER, normalizer);
+ grn_obj_unlink(ctx, normalizer);
+ }
+
+ condition_ptr = grn_expr_get_var(ctx, expression,
+ GRN_SELECT_INTERNAL_VAR_CONDITION,
+ strlen(GRN_SELECT_INTERNAL_VAR_CONDITION));
+ if (condition_ptr) {
+ condition = GRN_PTR_VALUE(condition_ptr);
+ }
+
+ if (condition) {
+ size_t i, n_keywords;
+ grn_obj current_keywords;
+ GRN_TEXT_INIT(&current_keywords, GRN_OBJ_VECTOR);
+ grn_expr_get_keywords(ctx, condition, &current_keywords);
+
+ n_keywords = grn_vector_size(ctx, &current_keywords);
+ for (i = 0; i < n_keywords; i++) {
+ const char *keyword;
+ unsigned int keyword_size;
+ keyword_size = grn_vector_get_element(ctx,
+ &current_keywords,
+ i,
+ &keyword,
+ NULL,
+ NULL);
+ grn_table_add(ctx,
+ keywords,
+ keyword,
+ keyword_size,
+ NULL);
+ }
+ GRN_OBJ_FIN(ctx, &current_keywords);
+ }
+
+ return keywords;
+}
+
+static grn_obj *
+func_highlight_html(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *highlighted = NULL;
+
+#define N_REQUIRED_ARGS 1
+ if (nargs == N_REQUIRED_ARGS) {
+ grn_obj *string = args[0];
+ grn_obj *expression = NULL;
+ grn_obj *keywords;
+ grn_obj *keywords_ptr;
+ grn_bool use_html_escape = GRN_TRUE;
+
+ grn_proc_get_info(ctx, user_data, NULL, NULL, &expression);
+
+ keywords_ptr = grn_expr_get_var(ctx, expression,
+ GRN_FUNC_HIGHLIGHT_HTML_CACHE_NAME,
+ strlen(GRN_FUNC_HIGHLIGHT_HTML_CACHE_NAME));
+ if (keywords_ptr) {
+ keywords = GRN_PTR_VALUE(keywords_ptr);
+ } else {
+ keywords_ptr =
+ grn_expr_get_or_add_var(ctx, expression,
+ GRN_FUNC_HIGHLIGHT_HTML_CACHE_NAME,
+ strlen(GRN_FUNC_HIGHLIGHT_HTML_CACHE_NAME));
+ GRN_OBJ_FIN(ctx, keywords_ptr);
+ GRN_PTR_INIT(keywords_ptr, GRN_OBJ_OWN, GRN_DB_OBJECT);
+
+ keywords = func_highlight_html_create_keywords_table(ctx, expression);
+ GRN_PTR_SET(ctx, keywords_ptr, keywords);
+ }
+
+ highlighted = highlight_keywords(ctx, user_data,
+ string, keywords, use_html_escape,
+ "<span class=\"keyword\">",
+ strlen("<span class=\"keyword\">"),
+ "</span>",
+ strlen("</span>"));
+ }
+#undef N_REQUIRED_ARGS
+
+ if (!highlighted) {
+ highlighted = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_VOID, 0);
+ }
+
+ return highlighted;
+}
+
+void
+grn_proc_init_highlight_html(grn_ctx *ctx)
+{
+ grn_proc_create(ctx, "highlight_html", -1, GRN_PROC_FUNCTION,
+ func_highlight_html, NULL, NULL, 0, NULL);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_in_records.c b/storage/mroonga/vendor/groonga/lib/proc/proc_in_records.c
new file mode 100644
index 00000000000..ca85678e756
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_in_records.c
@@ -0,0 +1,519 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+#include "../grn_db.h"
+#include "../grn_store.h"
+
+#include <groonga/plugin.h>
+
+typedef struct {
+ int n_conditions;
+ grn_obj *condition_table;
+ grn_obj condition_columns;
+ grn_operator *condition_modes;
+ grn_obj *search_result;
+} grn_in_records_data;
+
+static void
+grn_in_records_data_free(grn_ctx *ctx, grn_in_records_data *data)
+{
+ int i;
+ int n_condition_columns;
+
+ if (!data) {
+ return;
+ }
+
+ GRN_PLUGIN_FREE(ctx, data->condition_modes);
+
+ n_condition_columns =
+ GRN_BULK_VSIZE(&(data->condition_columns)) / sizeof(grn_obj *);
+ for (i = 0; i < n_condition_columns; i++) {
+ grn_obj *condition_column;
+ condition_column = GRN_PTR_VALUE_AT(&(data->condition_columns), i);
+ if (condition_column && condition_column->header.type == GRN_ACCESSOR) {
+ grn_obj_unlink(ctx, condition_column);
+ }
+ }
+ GRN_OBJ_FIN(ctx, &(data->condition_columns));
+
+ if (data->search_result) {
+ grn_obj_close(ctx, data->search_result);
+ }
+
+ GRN_PLUGIN_FREE(ctx, data);
+}
+
+static grn_obj *
+func_in_records_init(grn_ctx *ctx,
+ int n_args,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_in_records_data *data;
+ grn_obj *condition_table;
+ grn_expr_code *codes;
+ int n_arg_codes;
+ int n_logical_args;
+ int n_conditions;
+ int i;
+ int nth;
+
+ {
+ grn_obj *caller;
+ grn_expr *expr;
+ grn_expr_code *call_code;
+
+ caller = grn_plugin_proc_get_caller(ctx, user_data);
+ expr = (grn_expr *)caller;
+ call_code = expr->codes + expr->codes_curr - 1;
+ n_logical_args = call_code->nargs - 1;
+ codes = expr->codes + 1;
+ n_arg_codes = expr->codes_curr - 2;
+ }
+
+ if (n_logical_args < 4) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): wrong number of arguments (%d for 4..)",
+ n_logical_args);
+ return NULL;
+ }
+
+ if ((n_logical_args % 3) != 1) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): the number of arguments must be 1 + 3n (%d)",
+ n_logical_args);
+ return NULL;
+ }
+
+ n_conditions = (n_logical_args - 1) / 3;
+
+ condition_table = codes[0].value;
+ if (!grn_obj_is_table(ctx, condition_table)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, condition_table);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): the first argument must be a table: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+
+ data = GRN_PLUGIN_CALLOC(ctx, sizeof(grn_in_records_data));
+ if (!data) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): failed to allocate internal data");
+ return NULL;
+ }
+ user_data->ptr = data;
+
+ data->n_conditions = n_conditions;
+ data->condition_table = condition_table;
+ GRN_PTR_INIT(&(data->condition_columns), GRN_OBJ_VECTOR, GRN_ID_NIL);
+ data->condition_modes = GRN_PLUGIN_MALLOCN(ctx, grn_operator, n_conditions);
+ if (!data->condition_modes) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): "
+ "failed to allocate internal data for condition modes");
+ goto exit;
+ }
+
+ for (i = 1, nth = 0; i < n_arg_codes; nth++) {
+ int value_i = i;
+ int mode_name_i;
+ grn_obj *mode_name;
+ int column_name_i;
+ grn_obj *column_name;
+ grn_obj *condition_column;
+
+ value_i += codes[value_i].modify;
+
+ mode_name_i = value_i + 1;
+ mode_name = codes[mode_name_i].value;
+ data->condition_modes[nth] = grn_proc_option_value_mode(ctx,
+ mode_name,
+ GRN_OP_EQUAL,
+ "in_records()");
+ if (ctx->rc != GRN_SUCCESS) {
+ goto exit;
+ }
+
+ column_name_i = mode_name_i + 1;
+ column_name = codes[column_name_i].value;
+ if (!grn_obj_is_text_family_bulk(ctx, column_name)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, condition_table);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): "
+ "the %dth argument must be column name as string: "
+ "<%.*s>",
+ column_name_i,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ goto exit;
+ }
+
+ condition_column = grn_obj_column(ctx, condition_table,
+ GRN_TEXT_VALUE(column_name),
+ GRN_TEXT_LEN(column_name));
+ if (!condition_column) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, condition_table);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): "
+ "the %dth argument must be existing column name: "
+ "<%.*s>: <%.*s>",
+ column_name_i,
+ (int)GRN_TEXT_LEN(column_name),
+ GRN_TEXT_VALUE(column_name),
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ goto exit;
+ }
+ GRN_PTR_PUT(ctx, &(data->condition_columns), condition_column);
+
+ i = column_name_i + 1;
+ }
+
+ return NULL;
+
+exit :
+ grn_in_records_data_free(ctx, data);
+
+ return NULL;
+}
+
+static grn_obj *
+func_in_records_next(grn_ctx *ctx,
+ int n_args,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_in_records_data *data = user_data->ptr;
+ grn_obj *found;
+ grn_obj *condition;
+ grn_obj *variable;
+ int i;
+
+ found = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_BOOL, 0);
+ if (!found) {
+ return NULL;
+ }
+ GRN_BOOL_SET(ctx, found, GRN_FALSE);
+
+ if (!data) {
+ return found;
+ }
+
+ GRN_EXPR_CREATE_FOR_QUERY(ctx,
+ data->condition_table,
+ condition,
+ variable);
+ if (!condition) {
+ grn_rc rc = ctx->rc;
+ if (rc == GRN_SUCCESS) {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ }
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "in_records(): "
+ "failed to create internal expression: %s",
+ ctx->errbuf);
+ return found;
+ }
+
+ for (i = 1; i < n_args; i += 3) {
+ int nth = (i - 1) / 3;
+ grn_obj *value = args[i];
+ grn_obj *condition_column;
+ grn_operator condition_mode;
+
+ condition_column = GRN_PTR_VALUE_AT(&(data->condition_columns), nth);
+ condition_mode = data->condition_modes[nth];
+
+ switch (condition_mode) {
+ case GRN_OP_EQUAL :
+ case GRN_OP_NOT_EQUAL :
+ grn_expr_append_obj(ctx, condition, condition_column, GRN_OP_GET_VALUE, 1);
+ grn_expr_append_obj(ctx, condition, value, GRN_OP_PUSH, 1);
+ grn_expr_append_op(ctx, condition, condition_mode, 2);
+ break;
+ case GRN_OP_LESS :
+ grn_expr_append_obj(ctx, condition, condition_column, GRN_OP_GET_VALUE, 1);
+ grn_expr_append_obj(ctx, condition, value, GRN_OP_PUSH, 1);
+ grn_expr_append_op(ctx, condition, GRN_OP_GREATER_EQUAL, 2);
+ break;
+ case GRN_OP_GREATER :
+ grn_expr_append_obj(ctx, condition, condition_column, GRN_OP_GET_VALUE, 1);
+ grn_expr_append_obj(ctx, condition, value, GRN_OP_PUSH, 1);
+ grn_expr_append_op(ctx, condition, GRN_OP_LESS_EQUAL, 2);
+ break;
+ case GRN_OP_LESS_EQUAL :
+ grn_expr_append_obj(ctx, condition, condition_column, GRN_OP_GET_VALUE, 1);
+ grn_expr_append_obj(ctx, condition, value, GRN_OP_PUSH, 1);
+ grn_expr_append_op(ctx, condition, GRN_OP_GREATER, 2);
+ break;
+ case GRN_OP_GREATER_EQUAL :
+ grn_expr_append_obj(ctx, condition, condition_column, GRN_OP_GET_VALUE, 1);
+ grn_expr_append_obj(ctx, condition, value, GRN_OP_PUSH, 1);
+ grn_expr_append_op(ctx, condition, GRN_OP_LESS, 2);
+ break;
+ default :
+ grn_expr_append_obj(ctx, condition, value, GRN_OP_PUSH, 1);
+ grn_expr_append_obj(ctx, condition, condition_column, GRN_OP_GET_VALUE, 1);
+ grn_expr_append_op(ctx, condition, condition_mode, 2);
+ break;
+ }
+
+ if (nth > 0) {
+ grn_expr_append_op(ctx, condition, GRN_OP_AND, 2);
+ }
+ }
+
+ data->search_result = grn_table_select(ctx,
+ data->condition_table,
+ condition,
+ data->search_result,
+ GRN_OP_OR);
+ if (grn_table_size(ctx, data->search_result) > 0) {
+ GRN_BOOL_SET(ctx, found, GRN_TRUE);
+
+ GRN_TABLE_EACH_BEGIN(ctx, data->search_result, cursor, id) {
+ grn_table_cursor_delete(ctx, cursor);
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ }
+
+ grn_obj_close(ctx, condition);
+
+ return found;
+}
+
+static grn_obj *
+func_in_records_fin(grn_ctx *ctx,
+ int n_args,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_in_records_data *data = user_data->ptr;
+
+ grn_in_records_data_free(ctx, data);
+
+ return NULL;
+}
+
+static grn_rc
+selector_in_records(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ int n_args,
+ grn_obj **args,
+ grn_obj *res,
+ grn_operator op)
+{
+ grn_obj *condition_table;
+ grn_operator *condition_modes = NULL;
+ grn_obj condition_columns;
+ int i, nth;
+
+ /* TODO: Enable me when function call is supported. */
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+
+ if (n_args < 5) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): wrong number of arguments (%d for 4..)",
+ n_args - 1);
+ return ctx->rc;
+ }
+
+ condition_table = args[1];
+ if (!grn_obj_is_table(ctx, condition_table)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, condition_table);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): the first argument must be a table: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return ctx->rc;
+ }
+
+ condition_modes = GRN_PLUGIN_MALLOCN(ctx, grn_operator, (n_args - 2) / 3);
+ GRN_PTR_INIT(&condition_columns, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ for (i = 2, nth = 0; i < n_args; i += 3, nth++) {
+ int mode_name_i = i + 1;
+ int column_name_i = i + 2;
+ grn_obj *mode_name;
+ grn_operator mode;
+ grn_obj *column_name;
+ grn_obj *condition_column;
+
+ mode_name = args[mode_name_i];
+ mode = grn_proc_option_value_mode(ctx,
+ mode_name,
+ GRN_OP_EQUAL,
+ "in_records()");
+ if (ctx->rc != GRN_SUCCESS) {
+ goto exit;
+ }
+
+ condition_modes[nth] = mode;
+
+ column_name = args[column_name_i];
+ if (!grn_obj_is_text_family_bulk(ctx, column_name)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, condition_table);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): "
+ "the %dth argument must be column name as string: "
+ "<%.*s>",
+ column_name_i,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ goto exit;
+ }
+
+ condition_column = grn_obj_column(ctx, condition_table,
+ GRN_TEXT_VALUE(column_name),
+ GRN_TEXT_LEN(column_name));
+ if (!condition_column) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, condition_table);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): "
+ "the %dth argument must be existing column name: "
+ "<%.*s>: <%.*s>",
+ column_name_i,
+ (int)GRN_TEXT_LEN(column_name),
+ GRN_TEXT_VALUE(column_name),
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ goto exit;
+ }
+ GRN_PTR_PUT(ctx, &condition_columns, condition_column);
+ }
+
+ {
+ grn_obj condition_column_value;
+
+ GRN_VOID_INIT(&condition_column_value);
+ GRN_TABLE_EACH_BEGIN(ctx, condition_table, cursor, id) {
+ grn_obj *sub_res = NULL;
+
+ for (i = 2; i < n_args; i += 3) {
+ int nth = (i - 2) / 3;
+ grn_operator sub_op;
+ grn_obj *condition_column;
+ grn_operator condition_mode;
+ grn_obj *column = args[i];
+ grn_obj *expr;
+ grn_obj *variable;
+
+ if (nth == 0) {
+ sub_op = GRN_OP_OR;
+ } else {
+ sub_op = GRN_OP_AND;
+ }
+
+ condition_column = GRN_PTR_VALUE_AT(&condition_columns, nth);
+ condition_mode = condition_modes[nth];
+
+ GRN_BULK_REWIND(&condition_column_value);
+ grn_obj_get_value(ctx,
+ condition_column,
+ id,
+ &condition_column_value);
+
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, table, expr, variable);
+ if (!expr) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "in_records(): failed to create expression");
+ GRN_OBJ_FIN(ctx, &condition_column_value);
+ if (sub_res) {
+ grn_obj_close(ctx, sub_res);
+ }
+ goto exit;
+ }
+ grn_expr_append_obj(ctx, expr, column, GRN_OP_GET_VALUE, 1);
+ grn_expr_append_obj(ctx, expr, &condition_column_value, GRN_OP_PUSH, 1);
+ grn_expr_append_op(ctx, expr, condition_mode, 2);
+ sub_res = grn_table_select(ctx, table, expr, sub_res, sub_op);
+ grn_obj_close(ctx, expr);
+ }
+
+ if (sub_res) {
+ grn_table_setoperation(ctx, res, sub_res, res, op);
+ grn_obj_close(ctx, sub_res);
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ GRN_OBJ_FIN(ctx, &condition_column_value);
+ }
+
+exit :
+ GRN_PLUGIN_FREE(ctx, condition_modes);
+
+ for (i = 2; i < n_args; i += 3) {
+ int nth = (i - 2) / 3;
+ grn_obj *condition_column;
+ condition_column = GRN_PTR_VALUE_AT(&condition_columns, nth);
+ if (condition_column && condition_column->header.type == GRN_ACCESSOR) {
+ grn_obj_unlink(ctx, condition_column);
+ }
+ }
+ GRN_OBJ_FIN(ctx, &condition_columns);
+
+ return ctx->rc;
+}
+
+void
+grn_proc_init_in_records(grn_ctx *ctx)
+{
+ grn_obj *selector_proc;
+
+ selector_proc = grn_proc_create(ctx, "in_records", -1, GRN_PROC_FUNCTION,
+ func_in_records_init,
+ func_in_records_next,
+ func_in_records_fin,
+ 0,
+ NULL);
+ grn_proc_set_selector(ctx, selector_proc, selector_in_records);
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_NOP);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_lock.c b/storage/mroonga/vendor/groonga/lib/proc/proc_lock.c
new file mode 100644
index 00000000000..5dbcf5bbc29
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_lock.c
@@ -0,0 +1,172 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+
+#include "../grn_ctx.h"
+
+#include <groonga/plugin.h>
+
+static grn_obj *
+command_lock_clear(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ int target_name_len;
+ grn_obj *target_name;
+ grn_obj *obj;
+
+ target_name = grn_plugin_proc_get_var(ctx, user_data, "target_name", -1);
+ target_name_len = GRN_TEXT_LEN(target_name);
+
+ if (target_name_len) {
+ obj = grn_ctx_get(ctx, GRN_TEXT_VALUE(target_name), target_name_len);
+ } else {
+ obj = grn_ctx_db(ctx);
+ }
+
+ if (obj) {
+ grn_obj_clear_lock(ctx, obj);
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[lock][clear] target object not found: <%.*s>",
+ target_name_len, GRN_TEXT_VALUE(target_name));
+ }
+
+ grn_ctx_output_bool(ctx, ctx->rc == GRN_SUCCESS);
+
+ return NULL;
+}
+
+void
+grn_proc_init_clearlock(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ /* Deprecated. Use "lock_clear" instead. */
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "target_name", -1);
+ grn_plugin_command_create(ctx,
+ "clearlock", -1,
+ command_lock_clear,
+ 1,
+ vars);
+}
+
+void
+grn_proc_init_lock_clear(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "target_name", -1);
+ grn_plugin_command_create(ctx,
+ "lock_clear", -1,
+ command_lock_clear,
+ 1,
+ vars);
+}
+
+static grn_obj *
+command_lock_acquire(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ int target_name_len;
+ grn_obj *target_name;
+ grn_obj *obj;
+
+ target_name = grn_plugin_proc_get_var(ctx, user_data, "target_name", -1);
+ target_name_len = GRN_TEXT_LEN(target_name);
+
+ if (target_name_len) {
+ obj = grn_ctx_get(ctx, GRN_TEXT_VALUE(target_name), target_name_len);
+ } else {
+ obj = grn_ctx_db(ctx);
+ }
+
+ if (obj) {
+ grn_obj_lock(ctx, obj, GRN_ID_NIL, grn_lock_timeout);
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[lock][acquire] target object not found: <%.*s>",
+ target_name_len, GRN_TEXT_VALUE(target_name));
+ }
+
+ grn_ctx_output_bool(ctx, ctx->rc == GRN_SUCCESS);
+
+ return NULL;
+}
+
+void
+grn_proc_init_lock_acquire(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "target_name", -1);
+ grn_plugin_command_create(ctx,
+ "lock_acquire", -1,
+ command_lock_acquire,
+ 1,
+ vars);
+}
+
+static grn_obj *
+command_lock_release(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ int target_name_len;
+ grn_obj *target_name;
+ grn_obj *obj;
+
+ target_name = grn_plugin_proc_get_var(ctx, user_data, "target_name", -1);
+ target_name_len = GRN_TEXT_LEN(target_name);
+
+ if (target_name_len) {
+ obj = grn_ctx_get(ctx, GRN_TEXT_VALUE(target_name), target_name_len);
+ } else {
+ obj = grn_ctx_db(ctx);
+ }
+
+ if (obj) {
+ grn_obj_unlock(ctx, obj, GRN_ID_NIL);
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[lock][release] target object not found: <%.*s>",
+ target_name_len, GRN_TEXT_VALUE(target_name));
+ }
+
+ grn_ctx_output_bool(ctx, ctx->rc == GRN_SUCCESS);
+
+ return NULL;
+}
+
+void
+grn_proc_init_lock_release(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "target_name", -1);
+ grn_plugin_command_create(ctx,
+ "lock_release", -1,
+ command_lock_release,
+ 1,
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_object.c b/storage/mroonga/vendor/groonga/lib/proc/proc_object.c
new file mode 100644
index 00000000000..a4b2fbe4a05
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_object.c
@@ -0,0 +1,138 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+#include "../grn_io.h"
+
+#include <groonga/plugin.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+static grn_obj *
+command_object_exist(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *db;
+ grn_obj *name;
+ grn_id id;
+
+ db = grn_ctx_db(ctx);
+ name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+ if (GRN_TEXT_LEN(name) == 0) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[object][exist] name is missing");
+ grn_ctx_output_bool(ctx, GRN_FALSE);
+ return NULL;
+ }
+
+ id = grn_table_get(ctx, db,
+ GRN_TEXT_VALUE(name),
+ GRN_TEXT_LEN(name));
+ grn_ctx_output_bool(ctx, id != GRN_ID_NIL);
+ return NULL;
+}
+
+void
+grn_proc_init_object_exist(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "name", -1);
+ grn_plugin_command_create(ctx,
+ "object_exist", -1,
+ command_object_exist,
+ 1,
+ vars);
+}
+
+static grn_obj *
+command_object_remove(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *db;
+ grn_obj *name;
+ grn_bool force;
+ grn_obj *target;
+ grn_bool failed_to_open;
+
+ db = grn_ctx_db(ctx);
+ name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+ force = grn_plugin_proc_get_var_bool(ctx, user_data, "force", -1, GRN_FALSE);
+
+ if (GRN_TEXT_LEN(name) == 0) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[object][remove] name is missing");
+ grn_ctx_output_bool(ctx, GRN_FALSE);
+ return NULL;
+ }
+
+ target = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(name),
+ GRN_TEXT_LEN(name));
+ if (target) {
+ grn_obj_remove(ctx, target);
+ if (!force || ctx->rc == GRN_SUCCESS) {
+ grn_ctx_output_bool(ctx, ctx->rc == GRN_SUCCESS);
+ return NULL;
+ }
+ grn_obj_close(ctx, target);
+ failed_to_open = GRN_TRUE;
+ } else {
+ failed_to_open = (ctx->rc != GRN_SUCCESS);
+ }
+
+ if (force) {
+ grn_obj_remove_force(ctx, GRN_TEXT_VALUE(name), GRN_TEXT_LEN(name));
+ grn_ctx_output_bool(ctx, ctx->rc == GRN_SUCCESS);
+ } else {
+ if (failed_to_open) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[object][remove] "
+ "failed to open the target object: <%.*s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[object][remove] target object doesn't exist: <%.*s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ }
+ grn_ctx_output_bool(ctx, GRN_FALSE);
+ }
+
+ return NULL;
+}
+
+void
+grn_proc_init_object_remove(grn_ctx *ctx)
+{
+ grn_expr_var vars[2];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "name", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "force", -1);
+ grn_plugin_command_create(ctx,
+ "object_remove", -1,
+ command_object_remove,
+ 2,
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_object_inspect.c b/storage/mroonga/vendor/groonga/lib/proc/proc_object_inspect.c
new file mode 100644
index 00000000000..3b03ccb5e7c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_object_inspect.c
@@ -0,0 +1,614 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_pat.h"
+#include "../grn_dat.h"
+#include "../grn_ii.h"
+
+#include "../grn_proc.h"
+
+#include <groonga/plugin.h>
+
+static void command_object_inspect_dispatch(grn_ctx *ctx, grn_obj *obj);
+
+static void
+command_object_inspect_obj_name(grn_ctx *ctx, grn_obj *obj)
+{
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+
+ name_size = grn_obj_name(ctx, obj, name, GRN_TABLE_MAX_KEY_SIZE);
+ grn_ctx_output_str(ctx, name, name_size);
+}
+
+static void
+command_object_inspect_obj_type(grn_ctx *ctx, uint8_t type)
+{
+ grn_ctx_output_map_open(ctx, "type", 2);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_uint64(ctx, type);
+ grn_ctx_output_cstr(ctx, "name");
+ grn_ctx_output_cstr(ctx, grn_obj_type_to_string(type));
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_type(grn_ctx *ctx, grn_obj *type)
+{
+ if (!type) {
+ grn_ctx_output_null(ctx);
+ return;
+ }
+
+ grn_ctx_output_map_open(ctx, "type", 4);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_uint64(ctx, grn_obj_id(ctx, type));
+ grn_ctx_output_cstr(ctx, "name");
+ command_object_inspect_obj_name(ctx, type);
+ grn_ctx_output_cstr(ctx, "type");
+ command_object_inspect_obj_type(ctx, type->header.type);
+ grn_ctx_output_cstr(ctx, "size");
+ if (type->header.type == GRN_TYPE) {
+ grn_ctx_output_uint64(ctx, grn_type_size(ctx, type));
+ } else {
+ grn_ctx_output_uint64(ctx, sizeof(grn_id));
+ }
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_disk_usage(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_ctx_output_uint64(ctx, grn_obj_get_disk_usage(ctx, obj));
+}
+
+static void
+command_object_inspect_table_hash_key_key(grn_ctx *ctx, grn_hash *hash)
+{
+ grn_ctx_output_map_open(ctx, "key", 3);
+ {
+ grn_ctx_output_cstr(ctx, "type");
+ command_object_inspect_type(ctx, grn_ctx_at(ctx, hash->obj.header.domain));
+ grn_ctx_output_cstr(ctx, "total_size");
+ grn_ctx_output_uint64(ctx, grn_hash_total_key_size(ctx, hash));
+ grn_ctx_output_cstr(ctx, "max_total_size");
+ grn_ctx_output_uint64(ctx, grn_hash_max_total_key_size(ctx, hash));
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_table_pat_key_key(grn_ctx *ctx, grn_pat *pat)
+{
+ grn_ctx_output_map_open(ctx, "key", 3);
+ {
+ grn_ctx_output_cstr(ctx, "type");
+ command_object_inspect_type(ctx, grn_ctx_at(ctx, pat->obj.header.domain));
+ grn_ctx_output_cstr(ctx, "total_size");
+ grn_ctx_output_uint64(ctx, grn_pat_total_key_size(ctx, pat));
+ grn_ctx_output_cstr(ctx, "max_total_size");
+ grn_ctx_output_uint64(ctx, GRN_PAT_MAX_TOTAL_KEY_SIZE);
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_table_dat_key_key(grn_ctx *ctx, grn_dat *dat)
+{
+ grn_ctx_output_map_open(ctx, "key", 1);
+ {
+ grn_ctx_output_cstr(ctx, "type");
+ command_object_inspect_type(ctx, grn_ctx_at(ctx, dat->obj.header.domain));
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_table_key(grn_ctx *ctx, grn_obj *table)
+{
+ switch (table->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ command_object_inspect_table_hash_key_key(ctx, (grn_hash *)table);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ command_object_inspect_table_pat_key_key(ctx, (grn_pat *)table);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ command_object_inspect_table_dat_key_key(ctx, (grn_dat *)table);
+ break;
+ case GRN_TABLE_NO_KEY :
+ grn_ctx_output_null(ctx);
+ break;
+ default :
+ break;
+ }
+}
+
+static void
+command_object_inspect_table_value(grn_ctx *ctx, grn_obj *table)
+{
+ if (table->header.type == GRN_TABLE_DAT_KEY) {
+ grn_ctx_output_null(ctx);
+ } else {
+ grn_ctx_output_map_open(ctx, "value", 1);
+ {
+ grn_id range_id = grn_obj_get_range(ctx, table);
+ grn_ctx_output_cstr(ctx, "type");
+ command_object_inspect_type(ctx, grn_ctx_at(ctx, range_id));
+ }
+ grn_ctx_output_map_close(ctx);
+ }
+}
+
+static void
+command_object_inspect_table(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_ctx_output_map_open(ctx, "table", 7);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_uint64(ctx, grn_obj_id(ctx, obj));
+ grn_ctx_output_cstr(ctx, "name");
+ command_object_inspect_obj_name(ctx, obj);
+ grn_ctx_output_cstr(ctx, "type");
+ command_object_inspect_obj_type(ctx, obj->header.type);
+ grn_ctx_output_cstr(ctx, "key");
+ command_object_inspect_table_key(ctx, obj);
+ grn_ctx_output_cstr(ctx, "value");
+ command_object_inspect_table_value(ctx, obj);
+ grn_ctx_output_cstr(ctx, "n_records");
+ grn_ctx_output_uint64(ctx, grn_table_size(ctx, obj));
+ grn_ctx_output_cstr(ctx, "disk_usage");
+ command_object_inspect_disk_usage(ctx, obj);
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_column_name(grn_ctx *ctx, grn_obj *column)
+{
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+
+ name_size = grn_column_name(ctx, column, name, GRN_TABLE_MAX_KEY_SIZE);
+ name[name_size] = '\0';
+ grn_ctx_output_str(ctx, name, name_size);
+}
+
+static void
+command_object_inspect_column_type_name(grn_ctx *ctx, grn_obj *column)
+{
+ switch (column->header.type) {
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ switch (column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) {
+ case GRN_OBJ_COLUMN_SCALAR :
+ grn_ctx_output_cstr(ctx, "scalar");
+ break;
+ case GRN_OBJ_COLUMN_VECTOR :
+ grn_ctx_output_cstr(ctx, "vector");
+ break;
+ }
+ break;
+ case GRN_COLUMN_INDEX :
+ grn_ctx_output_cstr(ctx, "index");
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+command_object_inspect_column_type(grn_ctx *ctx, grn_obj *column)
+{
+ grn_ctx_output_map_open(ctx, "type", 2);
+ {
+ grn_ctx_output_cstr(ctx, "name");
+ command_object_inspect_column_type_name(ctx, column);
+
+ grn_ctx_output_cstr(ctx, "raw");
+ grn_ctx_output_map_open(ctx, "raw", 2);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_uint64(ctx, column->header.type);
+ grn_ctx_output_cstr(ctx, "name");
+ grn_ctx_output_cstr(ctx, grn_obj_type_to_string(column->header.type));
+ }
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_column_index_value_statistics(grn_ctx *ctx,
+ grn_ii *ii)
+{
+ grn_ctx_output_map_open(ctx, "statistics", 11);
+ {
+ struct grn_ii_header *h = ii->header;
+
+ grn_ctx_output_cstr(ctx, "max_section_id");
+ grn_ctx_output_uint64(ctx, grn_ii_max_section(ii));
+
+ {
+ uint32_t max_id = 0;
+ uint32_t n_garbage_segments = 0;
+ uint32_t n_array_segments = 0;
+ uint32_t n_buffer_segments = 0;
+
+ grn_ctx_output_cstr(ctx, "n_garbage_segments");
+ {
+ uint32_t i;
+
+ for (i = h->bgqtail;
+ i != h->bgqhead;
+ i = ((i + 1) & (GRN_II_BGQSIZE - 1))) {
+ uint32_t id = h->bgqbody[i];
+ n_garbage_segments++;
+ if (id > max_id) { max_id = id; }
+ }
+ grn_ctx_output_uint64(ctx, n_garbage_segments);
+ }
+
+ grn_ctx_output_cstr(ctx, "max_array_segment_id");
+ grn_ctx_output_uint64(ctx, h->amax);
+ grn_ctx_output_cstr(ctx, "n_array_segments");
+ {
+ uint32_t i;
+
+ for (i = 0; i < GRN_II_MAX_LSEG; i++) {
+ uint32_t id = h->ainfo[i];
+ if (id != GRN_II_PSEG_NOT_ASSIGNED) {
+ if (id > max_id) { max_id = id; }
+ n_array_segments++;
+ }
+ }
+ grn_ctx_output_uint64(ctx, n_array_segments);
+ }
+
+ grn_ctx_output_cstr(ctx, "max_buffer_segment_id");
+ grn_ctx_output_uint64(ctx, h->bmax);
+ grn_ctx_output_cstr(ctx, "n_buffer_segments");
+ {
+ uint32_t i;
+
+ for (i = 0; i < GRN_II_MAX_LSEG; i++) {
+ uint32_t id = h->binfo[i];
+ if (id != GRN_II_PSEG_NOT_ASSIGNED) {
+ if (id > max_id) { max_id = id; }
+ n_buffer_segments++;
+ }
+ }
+ grn_ctx_output_uint64(ctx, n_buffer_segments);
+ }
+
+ grn_ctx_output_cstr(ctx, "max_in_use_physical_segment_id");
+ grn_ctx_output_uint64(ctx, max_id);
+
+ grn_ctx_output_cstr(ctx, "n_unmanaged_segments");
+ grn_ctx_output_uint64(ctx,
+ h->pnext -
+ n_array_segments -
+ n_buffer_segments -
+ n_garbage_segments);
+ }
+
+ {
+ grn_ctx_output_cstr(ctx, "total_chunk_size");
+ grn_ctx_output_uint64(ctx, h->total_chunk_size);
+ grn_ctx_output_cstr(ctx, "max_in_use_chunk_id");
+ {
+ uint32_t i;
+ uint32_t max_id;
+
+ for (max_id = 0, i = 0; i < (GRN_II_MAX_CHUNK >> 3); i++) {
+ uint8_t sub_chunk_info = h->chunks[i];
+ uint8_t bit;
+
+ if (sub_chunk_info == 0) {
+ continue;
+ }
+ for (bit = 0; bit < 8; bit++) {
+ if (sub_chunk_info & (1 << bit)) {
+ max_id = (i << 3) + sub_chunk_info;
+ }
+ }
+ }
+ grn_ctx_output_uint64(ctx, max_id);
+ }
+ grn_ctx_output_cstr(ctx, "n_garbage_chunks");
+ grn_ctx_output_array_open(ctx,
+ "n_garbage_chunks",
+ GRN_II_N_CHUNK_VARIATION);
+ {
+ uint32_t i;
+ for (i = 0; i <= GRN_II_N_CHUNK_VARIATION; i++) {
+ grn_ctx_output_uint64(ctx, h->ngarbages[i]);
+ }
+ }
+ grn_ctx_output_array_close(ctx);
+ }
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_column_data_value_compress(grn_ctx *ctx, grn_obj *column)
+{
+ const char *compress = NULL;
+ grn_column_flags column_flags;
+
+ column_flags = grn_column_get_flags(ctx, column);
+ switch (column_flags & GRN_OBJ_COMPRESS_MASK) {
+ case GRN_OBJ_COMPRESS_ZLIB :
+ compress = "zlib";
+ break;
+ case GRN_OBJ_COMPRESS_LZ4 :
+ compress = "lz4";
+ break;
+ case GRN_OBJ_COMPRESS_ZSTD :
+ compress = "zstd";
+ break;
+ default :
+ break;
+ }
+
+ if (compress) {
+ grn_ctx_output_cstr(ctx, compress);
+ } else {
+ grn_ctx_output_null(ctx);
+ }
+}
+
+static void
+command_object_inspect_column_value(grn_ctx *ctx, grn_obj *column)
+{
+ int n_elements = 1;
+ grn_bool is_index = (column->header.type == GRN_COLUMN_INDEX);
+
+ if (is_index) {
+ n_elements += 5;
+ } else {
+ n_elements += 1;
+ }
+ grn_ctx_output_map_open(ctx, "value", n_elements);
+ {
+ grn_id range_id;
+ grn_column_flags column_flags;
+
+ range_id = grn_obj_get_range(ctx, column);
+ column_flags = grn_column_get_flags(ctx, column);
+
+ grn_ctx_output_cstr(ctx, "type");
+ command_object_inspect_type(ctx, grn_ctx_at(ctx, range_id));
+ if (is_index) {
+ grn_ctx_output_cstr(ctx, "section");
+ grn_ctx_output_bool(ctx, (column_flags & GRN_OBJ_WITH_SECTION) != 0);
+ grn_ctx_output_cstr(ctx, "weight");
+ grn_ctx_output_bool(ctx, (column_flags & GRN_OBJ_WITH_WEIGHT) != 0);
+ grn_ctx_output_cstr(ctx, "position");
+ grn_ctx_output_bool(ctx, (column_flags & GRN_OBJ_WITH_POSITION) != 0);
+ grn_ctx_output_cstr(ctx, "size");
+ if ((column_flags & GRN_OBJ_INDEX_SMALL) != 0) {
+ grn_ctx_output_cstr(ctx, "small");
+ } else if ((column_flags & GRN_OBJ_INDEX_MEDIUM) != 0) {
+ grn_ctx_output_cstr(ctx, "medium");
+ } else {
+ grn_ctx_output_cstr(ctx, "normal");
+ }
+ grn_ctx_output_cstr(ctx, "statistics");
+ command_object_inspect_column_index_value_statistics(ctx,
+ (grn_ii *)column);
+ } else {
+ grn_ctx_output_cstr(ctx, "compress");
+ command_object_inspect_column_data_value_compress(ctx, column);
+ }
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_column_index_sources(grn_ctx *ctx, grn_obj *column)
+{
+ grn_obj *source_table;
+ grn_obj source_ids;
+ unsigned int i, n_ids;
+
+ source_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, column));
+
+ GRN_RECORD_INIT(&source_ids, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ grn_obj_get_info(ctx, column, GRN_INFO_SOURCE, &source_ids);
+
+ n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id);
+ grn_ctx_output_array_open(ctx, "sources", n_ids);
+ for (i = 0; i < n_ids; i++) {
+ grn_id source_id;
+ grn_obj *source;
+
+ source_id = GRN_RECORD_VALUE_AT(&source_ids, i);
+ source = grn_ctx_at(ctx, source_id);
+
+ grn_ctx_output_map_open(ctx, "source", 4);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ if (grn_obj_is_table(ctx, source)) {
+ grn_ctx_output_null(ctx);
+ } else {
+ grn_ctx_output_uint64(ctx, source_id);
+ }
+
+ grn_ctx_output_cstr(ctx, "name");
+ if (grn_obj_is_table(ctx, source)) {
+ grn_ctx_output_cstr(ctx, "_key");
+ } else {
+ command_object_inspect_column_name(ctx, source);
+ }
+
+ grn_ctx_output_cstr(ctx, "table");
+ command_object_inspect_table(ctx, source_table);
+
+ grn_ctx_output_cstr(ctx, "full_name");
+ if (grn_obj_is_table(ctx, source)) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int name_size;
+ name_size = grn_obj_name(ctx, source, name, GRN_TABLE_MAX_KEY_SIZE);
+ name[name_size] = '\0';
+ grn_strcat(name, GRN_TABLE_MAX_KEY_SIZE, "._key");
+ grn_ctx_output_cstr(ctx, name);
+ } else {
+ command_object_inspect_obj_name(ctx, source);
+ }
+ }
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_array_close(ctx);
+
+ GRN_OBJ_FIN(ctx, &source_ids);
+}
+
+static void
+command_object_inspect_column(grn_ctx *ctx, grn_obj *column)
+{
+ int n_elements = 7;
+ grn_bool is_index = (column->header.type == GRN_COLUMN_INDEX);
+
+ if (is_index) {
+ n_elements += 1;
+ }
+ grn_ctx_output_map_open(ctx, "column", n_elements);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_uint64(ctx, grn_obj_id(ctx, column));
+ grn_ctx_output_cstr(ctx, "name");
+ command_object_inspect_column_name(ctx, column);
+ grn_ctx_output_cstr(ctx, "table");
+ command_object_inspect_table(ctx, grn_ctx_at(ctx, column->header.domain));
+ grn_ctx_output_cstr(ctx, "full_name");
+ command_object_inspect_obj_name(ctx, column);
+ grn_ctx_output_cstr(ctx, "type");
+ command_object_inspect_column_type(ctx, column);
+ grn_ctx_output_cstr(ctx, "value");
+ command_object_inspect_column_value(ctx, column);
+ if (is_index) {
+ grn_ctx_output_cstr(ctx, "sources");
+ command_object_inspect_column_index_sources(ctx, column);
+ }
+ grn_ctx_output_cstr(ctx, "disk_usage");
+ command_object_inspect_disk_usage(ctx, column);
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_db(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_db *db = (grn_db *)obj;
+
+ grn_ctx_output_map_open(ctx, "database", 3);
+ {
+ grn_ctx_output_cstr(ctx, "type");
+ command_object_inspect_obj_type(ctx, obj->header.type);
+ grn_ctx_output_cstr(ctx, "name_table");
+ command_object_inspect_dispatch(ctx, db->keys);
+ grn_ctx_output_cstr(ctx, "disk_usage");
+ command_object_inspect_disk_usage(ctx, obj);
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_object_inspect_dispatch(grn_ctx *ctx, grn_obj *obj)
+{
+ switch (obj->header.type) {
+ case GRN_TYPE :
+ command_object_inspect_type(ctx, obj);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ command_object_inspect_table(ctx, obj);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ command_object_inspect_column(ctx, obj);
+ break;
+ case GRN_DB :
+ command_object_inspect_db(ctx, obj);
+ break;
+ default :
+ {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_FUNCTION_NOT_IMPLEMENTED,
+ "[object][inspect] unsupported type: <%s>(%#x)",
+ grn_obj_type_to_string(obj->header.type),
+ obj->header.type);
+ grn_ctx_output_null(ctx);
+ break;
+ }
+ }
+}
+
+static grn_obj *
+command_object_inspect(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *name;
+ grn_obj *target;
+
+ name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+ if (GRN_TEXT_LEN(name) == 0) {
+ target = grn_ctx_db(ctx);
+ } else {
+ target = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(name),
+ GRN_TEXT_LEN(name));
+ if (!target) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[object][inspect] nonexistent target: <%.*s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ grn_ctx_output_null(ctx);
+ return NULL;
+ }
+ }
+
+ command_object_inspect_dispatch(ctx, target);
+
+ return NULL;
+}
+
+void
+grn_proc_init_object_inspect(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "name", -1);
+ grn_plugin_command_create(ctx,
+ "object_inspect", -1,
+ command_object_inspect,
+ 1,
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_object_list.c b/storage/mroonga/vendor/groonga/lib/proc/proc_object_list.c
new file mode 100644
index 00000000000..a15e27825ba
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_object_list.c
@@ -0,0 +1,413 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+#include "../grn_db.h"
+
+#include <groonga/plugin.h>
+
+static void
+command_object_list_dump_flags(grn_ctx *ctx, grn_obj_spec *spec)
+{
+ grn_obj flags;
+
+ GRN_TEXT_INIT(&flags, 0);
+
+ switch (spec->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ grn_dump_table_create_flags(ctx, spec->header.flags, &flags);
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_INDEX :
+ grn_dump_column_create_flags(ctx, spec->header.flags, &flags);
+ break;
+ case GRN_TYPE :
+ if (spec->header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ GRN_TEXT_PUTS(ctx, &flags, "KEY_VAR_SIZE");
+ } else {
+ switch (spec->header.flags & GRN_OBJ_KEY_MASK) {
+ case GRN_OBJ_KEY_UINT :
+ GRN_TEXT_PUTS(ctx, &flags, "KEY_UINT");
+ break;
+ case GRN_OBJ_KEY_INT :
+ GRN_TEXT_PUTS(ctx, &flags, "KEY_INT");
+ break;
+ case GRN_OBJ_KEY_FLOAT :
+ GRN_TEXT_PUTS(ctx, &flags, "KEY_FLOAT");
+ break;
+ case GRN_OBJ_KEY_GEO_POINT :
+ GRN_TEXT_PUTS(ctx, &flags, "KEY_GEO_POINT");
+ break;
+ }
+ }
+ break;
+ }
+ if (spec->header.flags & GRN_OBJ_CUSTOM_NAME) {
+ if (GRN_TEXT_LEN(&flags) > 0) {
+ GRN_TEXT_PUTS(ctx, &flags, "|");
+ }
+ GRN_TEXT_PUTS(ctx, &flags, "CUSTOM_NAME");
+ }
+
+ grn_ctx_output_str(ctx, GRN_TEXT_VALUE(&flags), GRN_TEXT_LEN(&flags));
+
+ GRN_OBJ_FIN(ctx, &flags);
+}
+
+static grn_obj *
+command_object_list(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_db *db;
+ uint32_t n_objects = 0;
+ grn_obj vector;
+
+ db = (grn_db *)grn_ctx_db(ctx);
+ if (!db->specs) {
+ grn_ctx_output_map_open(ctx, "objects", n_objects);
+ grn_ctx_output_map_close(ctx);
+ return NULL;
+ }
+
+ GRN_TABLE_EACH_BEGIN_FLAGS(ctx, (grn_obj *)db, cursor, id,
+ GRN_CURSOR_BY_ID | GRN_CURSOR_ASCENDING) {
+ grn_io_win jw;
+ uint32_t value_len;
+ char *value;
+
+ value = grn_ja_ref(ctx, db->specs, id, &jw, &value_len);
+ if (value) {
+ n_objects++;
+ grn_ja_unref(ctx, &jw);
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+
+ GRN_OBJ_INIT(&vector, GRN_VECTOR, 0, GRN_DB_TEXT);
+
+ grn_ctx_output_map_open(ctx, "objects", n_objects);
+ GRN_TABLE_EACH_BEGIN_FLAGS(ctx, (grn_obj *)db, cursor, id,
+ GRN_CURSOR_BY_ID | GRN_CURSOR_ASCENDING) {
+ void *name;
+ int name_size;
+ grn_io_win jw;
+ uint32_t value_len;
+ char *value;
+ unsigned int n_elements;
+
+ value = grn_ja_ref(ctx, db->specs, id, &jw, &value_len);
+ if (!value) {
+ continue;
+ }
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+
+ grn_ctx_output_str(ctx, name, name_size);
+
+ GRN_BULK_REWIND(&vector);
+ if (grn_vector_decode(ctx, &vector, value, value_len) != GRN_SUCCESS) {
+ grn_ctx_output_map_open(ctx, "object", 4);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_int64(ctx, id);
+ grn_ctx_output_cstr(ctx, "name");
+ grn_ctx_output_str(ctx, name, name_size);
+ grn_ctx_output_cstr(ctx, "opened");
+ grn_ctx_output_bool(ctx, grn_ctx_is_opened(ctx, id));
+ grn_ctx_output_cstr(ctx, "value_size");
+ grn_ctx_output_uint64(ctx, value_len);
+ }
+ grn_ctx_output_map_close(ctx);
+ goto next;
+ }
+
+ n_elements = grn_vector_size(ctx, &vector);
+
+ {
+ uint32_t element_size;
+ grn_obj_spec *spec;
+ uint32_t n_properties = 8;
+ grn_bool need_sources = GRN_FALSE;
+ grn_bool need_token_filters = GRN_FALSE;
+
+ element_size = grn_vector_get_element(ctx,
+ &vector,
+ GRN_SERIALIZED_SPEC_INDEX_SPEC,
+ (const char **)&spec,
+ NULL,
+ NULL);
+ if (element_size == 0) {
+ grn_ctx_output_map_open(ctx, "object", 4);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_int64(ctx, id);
+ grn_ctx_output_cstr(ctx, "name");
+ grn_ctx_output_str(ctx, name, name_size);
+ grn_ctx_output_cstr(ctx, "opened");
+ grn_ctx_output_bool(ctx, grn_ctx_is_opened(ctx, id));
+ grn_ctx_output_cstr(ctx, "n_elements");
+ grn_ctx_output_uint64(ctx, n_elements);
+ }
+ grn_ctx_output_map_close(ctx);
+ goto next;
+ }
+
+ switch (spec->header.type) {
+ case GRN_COLUMN_INDEX :
+ need_sources = GRN_TRUE;
+ n_properties++;
+ break;
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_NO_KEY :
+ need_token_filters = GRN_TRUE;
+ n_properties++;
+ break;
+ }
+ grn_ctx_output_map_open(ctx, "object", n_properties);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_uint64(ctx, id);
+
+ grn_ctx_output_cstr(ctx, "name");
+ grn_ctx_output_str(ctx, name, name_size);
+
+ grn_ctx_output_cstr(ctx, "opened");
+ grn_ctx_output_bool(ctx, grn_ctx_is_opened(ctx, id));
+
+ grn_ctx_output_cstr(ctx, "n_elements");
+ grn_ctx_output_uint64(ctx, n_elements);
+
+ grn_ctx_output_cstr(ctx, "type");
+ grn_ctx_output_map_open(ctx, "type", 2);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_uint64(ctx, spec->header.type);
+ grn_ctx_output_cstr(ctx, "name");
+ grn_ctx_output_cstr(ctx, grn_obj_type_to_string(spec->header.type));
+ }
+ grn_ctx_output_map_close(ctx);
+
+ grn_ctx_output_cstr(ctx, "flags");
+ grn_ctx_output_map_open(ctx, "flags", 2);
+ {
+ grn_ctx_output_cstr(ctx, "value");
+ grn_ctx_output_uint64(ctx, spec->header.flags);
+ grn_ctx_output_cstr(ctx, "names");
+ command_object_list_dump_flags(ctx, spec);
+ }
+ grn_ctx_output_map_close(ctx);
+
+ grn_ctx_output_cstr(ctx, "path");
+ if (spec->header.flags & GRN_OBJ_CUSTOM_NAME) {
+ const char *path;
+ uint32_t path_size;
+ path_size = grn_vector_get_element(ctx,
+ &vector,
+ GRN_SERIALIZED_SPEC_INDEX_PATH,
+ &path,
+ NULL,
+ NULL);
+ grn_ctx_output_str(ctx, path, path_size);
+ } else {
+ switch (spec->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_INDEX :
+ {
+ char path[PATH_MAX];
+ grn_db_generate_pathname(ctx, (grn_obj *)db, id, path);
+ grn_ctx_output_cstr(ctx, path);
+ }
+ break;
+ default :
+ grn_ctx_output_null(ctx);
+ break;
+ }
+ }
+
+ switch (spec->header.type) {
+ case GRN_TYPE :
+ grn_ctx_output_cstr(ctx, "size");
+ grn_ctx_output_uint64(ctx, spec->range);
+ break;
+ case GRN_PROC :
+ grn_ctx_output_cstr(ctx, "plugin_id");
+ grn_ctx_output_uint64(ctx, spec->range);
+ break;
+ default :
+ grn_ctx_output_cstr(ctx, "range");
+ grn_ctx_output_map_open(ctx, "range", 2);
+ {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+
+ name_size = grn_table_get_key(ctx,
+ (grn_obj *)db,
+ spec->range,
+ name,
+ GRN_TABLE_MAX_KEY_SIZE);
+
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_uint64(ctx, spec->range);
+
+ grn_ctx_output_cstr(ctx, "name");
+ if (name_size == 0) {
+ grn_ctx_output_null(ctx);
+ } else {
+ grn_ctx_output_str(ctx, name, name_size);
+ }
+ }
+ grn_ctx_output_map_close(ctx);
+ break;
+ }
+
+ if (need_sources) {
+ const grn_id *source_ids;
+ uint32_t n_source_ids;
+ uint32_t i;
+
+ if (n_elements > GRN_SERIALIZED_SPEC_INDEX_SOURCE) {
+ uint32_t element_size;
+
+ element_size = grn_vector_get_element(ctx,
+ &vector,
+ GRN_SERIALIZED_SPEC_INDEX_SOURCE,
+ (const char **)&source_ids,
+ NULL,
+ NULL);
+ n_source_ids = element_size / sizeof(grn_id);
+ } else {
+ source_ids = NULL;
+ n_source_ids = 0;
+ }
+
+ grn_ctx_output_cstr(ctx, "sources");
+ grn_ctx_output_array_open(ctx, "sources", n_source_ids);
+ for (i = 0; i < n_source_ids; i++) {
+ grn_id source_id;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+
+ source_id = source_ids[i];
+ name_size = grn_table_get_key(ctx,
+ (grn_obj *)db,
+ source_id,
+ name,
+ GRN_TABLE_MAX_KEY_SIZE);
+
+ grn_ctx_output_map_open(ctx, "source", 2);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_uint64(ctx, source_id);
+
+ grn_ctx_output_cstr(ctx, "name");
+ if (name_size == 0) {
+ grn_ctx_output_null(ctx);
+ } else {
+ grn_ctx_output_str(ctx, name, name_size);
+ }
+ }
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_array_close(ctx);
+ }
+
+ if (need_token_filters) {
+ const grn_id *token_filter_ids;
+ uint32_t n_token_filter_ids;
+ uint32_t i;
+
+ if (n_elements > GRN_SERIALIZED_SPEC_INDEX_TOKEN_FILTERS) {
+ uint32_t element_size;
+
+ element_size = grn_vector_get_element(ctx,
+ &vector,
+ GRN_SERIALIZED_SPEC_INDEX_TOKEN_FILTERS,
+ (const char **)&token_filter_ids,
+ NULL,
+ NULL);
+ n_token_filter_ids = element_size / sizeof(grn_id);
+ } else {
+ token_filter_ids = NULL;
+ n_token_filter_ids = 0;
+ }
+
+ grn_ctx_output_cstr(ctx, "token_filters");
+ grn_ctx_output_array_open(ctx, "token_filters", n_token_filter_ids);
+ for (i = 0; i < n_token_filter_ids; i++) {
+ grn_id token_filter_id;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+
+ token_filter_id = token_filter_ids[i];
+ name_size = grn_table_get_key(ctx,
+ (grn_obj *)db,
+ token_filter_id,
+ name,
+ GRN_TABLE_MAX_KEY_SIZE);
+
+ grn_ctx_output_map_open(ctx, "token_filter", 2);
+ {
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_uint64(ctx, token_filter_id);
+
+ grn_ctx_output_cstr(ctx, "name");
+ if (name_size == 0) {
+ grn_ctx_output_null(ctx);
+ } else {
+ grn_ctx_output_str(ctx, name, name_size);
+ }
+ }
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_array_close(ctx);
+ }
+ }
+ grn_ctx_output_map_close(ctx);
+ }
+
+ next :
+ grn_ja_unref(ctx, &jw);
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ grn_ctx_output_map_close(ctx);
+
+ GRN_OBJ_FIN(ctx, &vector);
+
+ return NULL;
+}
+
+void
+grn_proc_init_object_list(grn_ctx *ctx)
+{
+ grn_plugin_command_create(ctx,
+ "object_list", -1,
+ command_object_list,
+ 0,
+ NULL);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_query.c b/storage/mroonga/vendor/groonga/lib/proc/proc_query.c
new file mode 100644
index 00000000000..981da834bcd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_query.c
@@ -0,0 +1,118 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+
+#include <groonga/plugin.h>
+
+static grn_obj *
+command_query_expand(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ const char *expander;
+ size_t expander_size;
+ const char *query;
+ size_t query_size;
+ const char *flags_raw;
+ size_t flags_raw_size;
+ grn_expr_flags flags = GRN_EXPR_SYNTAX_QUERY;
+ const char *term_column;
+ size_t term_column_size;
+ const char *expanded_term_column;
+ size_t expanded_term_column_size;
+ grn_obj expanded_query;
+
+ expander = grn_plugin_proc_get_var_string(ctx,
+ user_data,
+ "expander",
+ -1,
+ &expander_size);
+ query = grn_plugin_proc_get_var_string(ctx,
+ user_data,
+ "query",
+ -1,
+ &query_size);
+ flags_raw = grn_plugin_proc_get_var_string(ctx,
+ user_data,
+ "flags",
+ -1,
+ &flags_raw_size);
+ term_column = grn_plugin_proc_get_var_string(ctx,
+ user_data,
+ "term_column",
+ -1,
+ &term_column_size);
+ expanded_term_column =
+ grn_plugin_proc_get_var_string(ctx,
+ user_data,
+ "expanded_term_column",
+ -1,
+ &expanded_term_column_size);
+
+ if (flags_raw_size > 0) {
+ flags |= grn_proc_expr_query_flags_parse(ctx,
+ flags_raw,
+ flags_raw_size,
+ "[query][expand]");
+ } else {
+ flags |= GRN_EXPR_ALLOW_PRAGMA | GRN_EXPR_ALLOW_COLUMN;
+ }
+
+ if (ctx->rc != GRN_SUCCESS) {
+ return NULL;
+ }
+
+ GRN_TEXT_INIT(&expanded_query, 0);
+ grn_proc_syntax_expand_query(ctx,
+ query,
+ query_size,
+ flags,
+ expander,
+ expander_size,
+ term_column,
+ term_column_size,
+ expanded_term_column,
+ expanded_term_column_size,
+ &expanded_query,
+ "[query][expand]");
+ if (ctx->rc == GRN_SUCCESS) {
+ grn_ctx_output_str(ctx,
+ GRN_TEXT_VALUE(&expanded_query),
+ GRN_TEXT_LEN(&expanded_query));
+ }
+ GRN_OBJ_FIN(ctx, &expanded_query);
+
+ return NULL;
+}
+
+void
+grn_proc_init_query_expand(grn_ctx *ctx)
+{
+ grn_expr_var vars[5];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "expander", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "query", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[2]), "flags", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[3]), "term_column", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[4]), "expanded_term_column", -1);
+ grn_plugin_command_create(ctx,
+ "query_expand", -1,
+ command_query_expand,
+ 5,
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_query_log_flags.c b/storage/mroonga/vendor/groonga/lib/proc/proc_query_log_flags.c
new file mode 100644
index 00000000000..1c0560929b9
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_query_log_flags.c
@@ -0,0 +1,220 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+
+#include <groonga/plugin.h>
+
+static grn_obj *
+command_query_log_flags_get(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ unsigned int current_flags;
+ grn_obj inspected_flags;
+
+ current_flags = grn_query_logger_get_flags(ctx);
+ GRN_TEXT_INIT(&inspected_flags, 0);
+
+ grn_inspect_query_log_flags(ctx, &inspected_flags,current_flags);
+ grn_ctx_output_str(ctx,
+ GRN_TEXT_VALUE(&inspected_flags),
+ GRN_TEXT_LEN(&inspected_flags));
+
+ GRN_OBJ_FIN(ctx, &inspected_flags);
+
+ return NULL;
+}
+
+void
+grn_proc_init_query_log_flags_get(grn_ctx *ctx)
+{
+ grn_plugin_command_create(ctx,
+ "query_log_flags_get", -1,
+ command_query_log_flags_get,
+ 0,
+ NULL);
+}
+
+typedef enum {
+ UPDATE_SET,
+ UPDATE_ADD,
+ UPDATE_REMOVE
+} grn_query_log_flags_update_mode;
+
+static void
+grn_query_log_flags_update(grn_ctx *ctx,
+ grn_obj *flags_text,
+ grn_query_log_flags_update_mode mode,
+ const char *error_message_tag)
+{
+ unsigned int previous_flags;
+ unsigned int flags = 0;
+
+ previous_flags = grn_query_logger_get_flags(ctx);
+ if (GRN_TEXT_LEN(flags_text) == 0) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "%s no query log flags",
+ error_message_tag);
+ grn_ctx_output_null(ctx);
+ return;
+ }
+
+ if (!grn_query_log_flags_parse(GRN_TEXT_VALUE(flags_text),
+ GRN_TEXT_LEN(flags_text),
+ &flags)) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "%s invalid query log flags: <%.*s>",
+ error_message_tag,
+ (int)GRN_TEXT_LEN(flags_text),
+ GRN_TEXT_VALUE(flags_text));
+ grn_ctx_output_null(ctx);
+ return;
+ }
+
+ switch (mode) {
+ case UPDATE_SET :
+ grn_query_logger_set_flags(ctx, flags);
+ break;
+ case UPDATE_ADD :
+ grn_query_logger_add_flags(ctx, flags);
+ break;
+ case UPDATE_REMOVE :
+ grn_query_logger_remove_flags(ctx, flags);
+ break;
+ }
+
+ {
+ unsigned int current_flags;
+ grn_obj inspected_flags;
+
+ current_flags = grn_query_logger_get_flags(ctx);
+ GRN_TEXT_INIT(&inspected_flags, 0);
+
+ grn_ctx_output_map_open(ctx, "query_log_flags", 2);
+
+ grn_inspect_query_log_flags(ctx, &inspected_flags, previous_flags);
+ grn_ctx_output_cstr(ctx, "previous");
+ grn_ctx_output_str(ctx,
+ GRN_TEXT_VALUE(&inspected_flags),
+ GRN_TEXT_LEN(&inspected_flags));
+
+ GRN_BULK_REWIND(&inspected_flags);
+ grn_inspect_query_log_flags(ctx, &inspected_flags, current_flags);
+ grn_ctx_output_cstr(ctx, "current");
+ grn_ctx_output_str(ctx,
+ GRN_TEXT_VALUE(&inspected_flags),
+ GRN_TEXT_LEN(&inspected_flags));
+
+ grn_ctx_output_map_close(ctx);
+
+ GRN_OBJ_FIN(ctx, &inspected_flags);
+ }
+
+ return;
+}
+
+static grn_obj *
+command_query_log_flags_set(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *flags_text;
+
+ flags_text = grn_plugin_proc_get_var(ctx, user_data, "flags", -1);
+ grn_query_log_flags_update(ctx,
+ flags_text,
+ UPDATE_SET,
+ "[query-log][flags][set]");
+ return NULL;
+}
+
+void
+grn_proc_init_query_log_flags_set(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "flags", -1);
+ grn_plugin_command_create(ctx,
+ "query_log_flags_set", -1,
+ command_query_log_flags_set,
+ 1,
+ vars);
+}
+
+static grn_obj *
+command_query_log_flags_add(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *flags_text;
+
+ flags_text = grn_plugin_proc_get_var(ctx, user_data, "flags", -1);
+ grn_query_log_flags_update(ctx,
+ flags_text,
+ UPDATE_ADD,
+ "[query-log][flags][add]");
+ return NULL;
+}
+
+void
+grn_proc_init_query_log_flags_add(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "flags", -1);
+ grn_plugin_command_create(ctx,
+ "query_log_flags_add", -1,
+ command_query_log_flags_add,
+ 1,
+ vars);
+}
+
+static grn_obj *
+command_query_log_flags_remove(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *flags_text;
+
+ flags_text = grn_plugin_proc_get_var(ctx, user_data, "flags", -1);
+ grn_query_log_flags_update(ctx,
+ flags_text,
+ UPDATE_REMOVE,
+ "[query-log][flags][remove]");
+ return NULL;
+}
+
+void
+grn_proc_init_query_log_flags_remove(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "flags", -1);
+ grn_plugin_command_create(ctx,
+ "query_log_flags_remove", -1,
+ command_query_log_flags_remove,
+ 1,
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_schema.c b/storage/mroonga/vendor/groonga/lib/proc/proc_schema.c
new file mode 100644
index 00000000000..eb1e71943d6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_schema.c
@@ -0,0 +1,1226 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+
+#include "../grn_db.h"
+
+#include <groonga/plugin.h>
+
+typedef struct {
+ grn_bool is_close_opened_object_mode;
+} grn_schema_data;
+
+static void
+command_schema_output_id(grn_ctx *ctx, grn_obj *obj)
+{
+ if (obj) {
+ grn_id id;
+ id = grn_obj_id(ctx, obj);
+ grn_ctx_output_uint64(ctx, id);
+ } else {
+ grn_ctx_output_null(ctx);
+ }
+}
+
+static void
+command_schema_output_name(grn_ctx *ctx, grn_obj *obj)
+{
+ if (obj) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int name_size;
+ name_size = grn_obj_name(ctx, obj, name, GRN_TABLE_MAX_KEY_SIZE);
+ grn_ctx_output_str(ctx, name, name_size);
+ } else {
+ grn_ctx_output_null(ctx);
+ }
+}
+
+static void
+command_schema_output_column_name(grn_ctx *ctx, grn_obj *column)
+{
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int name_size;
+ name_size = grn_column_name(ctx, column, name, GRN_TABLE_MAX_KEY_SIZE);
+ grn_ctx_output_str(ctx, name, name_size);
+}
+
+static void
+command_schema_output_type(grn_ctx *ctx, const char *type_label, grn_obj *type)
+{
+ if (!type) {
+ grn_ctx_output_null(ctx);
+ return;
+ }
+
+ grn_ctx_output_map_open(ctx, type_label, 3);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, type);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_name(ctx, type);
+
+ grn_ctx_output_cstr(ctx, "type");
+ if (grn_obj_is_table(ctx, type)) {
+ grn_ctx_output_cstr(ctx, "reference");
+ } else {
+ grn_ctx_output_cstr(ctx, "type");
+ }
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_schema_output_key_type(grn_ctx *ctx, grn_obj *key_type)
+{
+ command_schema_output_type(ctx, "key_type", key_type);
+}
+
+static void
+command_schema_output_value_type(grn_ctx *ctx, grn_obj *value_type)
+{
+ command_schema_output_type(ctx, "value_type", value_type);
+}
+
+static void
+command_schema_output_command(grn_ctx *ctx,
+ const char *command_name,
+ grn_obj *arguments)
+{
+ grn_ctx_output_map_open(ctx, "command", 3);
+
+ grn_ctx_output_cstr(ctx, "name");
+ grn_ctx_output_cstr(ctx, command_name);
+
+ grn_ctx_output_cstr(ctx, "arguments");
+ {
+ int i, n;
+
+ n = grn_vector_size(ctx, arguments);
+ grn_ctx_output_map_open(ctx, "arguments", n / 2);
+ for (i = 0; i < n; i += 2) {
+ const char *name;
+ unsigned int name_size;
+ const char *value;
+ unsigned int value_size;
+
+ name_size = grn_vector_get_element(ctx, arguments, i, &name,
+ NULL, NULL);
+ value_size = grn_vector_get_element(ctx, arguments, i + 1, &value,
+ NULL, NULL);
+ grn_ctx_output_str(ctx, name, name_size);
+ grn_ctx_output_str(ctx, value, value_size);
+ }
+ grn_ctx_output_map_close(ctx);
+ }
+
+ grn_ctx_output_cstr(ctx, "command_line");
+ {
+ int i, n;
+ grn_obj command_line;
+
+ GRN_TEXT_INIT(&command_line, 0);
+ GRN_TEXT_PUTS(ctx, &command_line, command_name);
+ n = grn_vector_size(ctx, arguments);
+ for (i = 0; i < n; i += 2) {
+ const char *name;
+ unsigned int name_size;
+ const char *value;
+ unsigned int value_size;
+
+ name_size = grn_vector_get_element(ctx, arguments, i, &name,
+ NULL, NULL);
+ value_size = grn_vector_get_element(ctx, arguments, i + 1, &value,
+ NULL, NULL);
+ grn_text_printf(ctx, &command_line,
+ " --%.*s %.*s",
+ name_size, name,
+ value_size, value);
+ }
+ grn_ctx_output_str(ctx,
+ GRN_TEXT_VALUE(&command_line),
+ GRN_TEXT_LEN(&command_line));
+ GRN_OBJ_FIN(ctx, &command_line);
+ }
+
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_schema_output_plugins(grn_ctx *ctx)
+{
+ grn_obj plugin_names;
+ unsigned int i, n;
+
+ GRN_TEXT_INIT(&plugin_names, GRN_OBJ_VECTOR);
+
+ grn_plugin_get_names(ctx, &plugin_names);
+
+ grn_ctx_output_cstr(ctx, "plugins");
+
+ n = grn_vector_size(ctx, &plugin_names);
+ grn_ctx_output_map_open(ctx, "plugins", n);
+ for (i = 0; i < n; i++) {
+ const char *name;
+ unsigned int name_size;
+
+ name_size = grn_vector_get_element(ctx, &plugin_names, i, &name, NULL, NULL);
+ grn_ctx_output_str(ctx, name, name_size);
+
+ grn_ctx_output_map_open(ctx, "plugin", 1);
+ grn_ctx_output_cstr(ctx, "name");
+ grn_ctx_output_str(ctx, name, name_size);
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_map_close(ctx);
+
+ GRN_OBJ_FIN(ctx, &plugin_names);
+}
+
+static void
+command_schema_output_types(grn_ctx *ctx)
+{
+ unsigned int n_types;
+
+ n_types = 0;
+ GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) {
+ if (grn_id_is_builtin_type(ctx, id)) {
+ n_types++;
+ }
+ } GRN_DB_EACH_END(ctx, cursor);
+
+ grn_ctx_output_cstr(ctx, "types");
+
+ grn_ctx_output_map_open(ctx, "types", n_types);
+ GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) {
+ grn_obj *type;
+
+ if (!grn_id_is_builtin_type(ctx, id)) {
+ continue;
+ }
+
+ type = grn_ctx_at(ctx, id);
+
+ command_schema_output_name(ctx, type);
+
+ grn_ctx_output_map_open(ctx, "type", 5);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, type);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_name(ctx, type);
+
+ grn_ctx_output_cstr(ctx, "size");
+ grn_ctx_output_int64(ctx, grn_type_size(ctx, type));
+
+ grn_ctx_output_cstr(ctx, "can_be_key_type");
+ grn_ctx_output_bool(ctx, grn_type_size(ctx, type) <= GRN_TABLE_MAX_KEY_SIZE);
+
+ grn_ctx_output_cstr(ctx, "can_be_value_type");
+ grn_ctx_output_bool(ctx, !(type->header.flags & GRN_OBJ_KEY_VAR_SIZE));
+
+ grn_ctx_output_map_close(ctx);
+ } GRN_DB_EACH_END(ctx, cursor);
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_schema_output_tokenizers(grn_ctx *ctx, grn_schema_data *data)
+{
+ grn_obj tokenizer_ids;
+ unsigned int i, n;
+
+ GRN_RECORD_INIT(&tokenizer_ids, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) {
+ void *name;
+ int name_size;
+ grn_obj *object;
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+ if (grn_obj_name_is_column(ctx, name, name_size)) {
+ continue;
+ }
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ object = grn_ctx_at(ctx, id);
+ if (object) {
+ if (grn_obj_is_tokenizer_proc(ctx, object)) {
+ GRN_RECORD_PUT(ctx, &tokenizer_ids, id);
+ }
+ } else {
+ /* XXX: this clause is executed when MeCab tokenizer is enabled in
+ database but the groonga isn't supported MeCab.
+ We should return error mesage about it and error exit status
+ but it's too difficult for this architecture. :< */
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ }
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_DB_EACH_END(ctx, cursor);
+
+ grn_ctx_output_cstr(ctx, "tokenizers");
+
+ n = GRN_BULK_VSIZE(&tokenizer_ids) / sizeof(grn_id);
+ grn_ctx_output_map_open(ctx, "tokenizers", n);
+ for (i = 0; i < n; i++) {
+ grn_id tokenizer_id;
+ grn_obj *tokenizer;
+
+ tokenizer_id = GRN_RECORD_VALUE_AT(&tokenizer_ids, i);
+ tokenizer = grn_ctx_at(ctx, tokenizer_id);
+
+ command_schema_output_name(ctx, tokenizer);
+
+ grn_ctx_output_map_open(ctx, "tokenizer", 2);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, tokenizer);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_name(ctx, tokenizer);
+
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_map_close(ctx);
+
+ GRN_OBJ_FIN(ctx, &tokenizer_ids);
+}
+
+static void
+command_schema_output_normalizers(grn_ctx *ctx, grn_schema_data *data)
+{
+ grn_obj normalizer_ids;
+ unsigned int i, n;
+
+ GRN_RECORD_INIT(&normalizer_ids, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) {
+ void *name;
+ int name_size;
+ grn_obj *object;
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+ if (grn_obj_name_is_column(ctx, name, name_size)) {
+ continue;
+ }
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ object = grn_ctx_at(ctx, id);
+ if (object) {
+ if (grn_obj_is_normalizer_proc(ctx, object)) {
+ GRN_RECORD_PUT(ctx, &normalizer_ids, id);
+ }
+ } else {
+ /* XXX: this clause is executed when MeCab normalizer is enabled in
+ database but the groonga isn't supported MeCab.
+ We should return error mesage about it and error exit status
+ but it's too difficult for this architecture. :< */
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ }
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_DB_EACH_END(ctx, cursor);
+
+ grn_ctx_output_cstr(ctx, "normalizers");
+
+ n = GRN_BULK_VSIZE(&normalizer_ids) / sizeof(grn_id);
+ grn_ctx_output_map_open(ctx, "normalizers", n);
+ for (i = 0; i < n; i++) {
+ grn_id normalizer_id;
+ grn_obj *normalizer;
+
+ normalizer_id = GRN_RECORD_VALUE_AT(&normalizer_ids, i);
+ normalizer = grn_ctx_at(ctx, normalizer_id);
+
+ command_schema_output_name(ctx, normalizer);
+
+ grn_ctx_output_map_open(ctx, "normalizer", 2);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, normalizer);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_name(ctx, normalizer);
+
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_map_close(ctx);
+
+ GRN_OBJ_FIN(ctx, &normalizer_ids);
+}
+
+static void
+command_schema_output_token_filters(grn_ctx *ctx, grn_schema_data *data)
+{
+ grn_obj token_filter_ids;
+ unsigned int i, n;
+
+ GRN_RECORD_INIT(&token_filter_ids, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) {
+ void *name;
+ int name_size;
+ grn_obj *object;
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+ if (grn_obj_name_is_column(ctx, name, name_size)) {
+ continue;
+ }
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ object = grn_ctx_at(ctx, id);
+ if (object) {
+ if (grn_obj_is_token_filter_proc(ctx, object)) {
+ GRN_RECORD_PUT(ctx, &token_filter_ids, id);
+ }
+ } else {
+ /* XXX: this clause is executed when MeCab normalizer is enabled in
+ database but the groonga isn't supported MeCab.
+ We should return error mesage about it and error exit status
+ but it's too difficult for this architecture. :< */
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ }
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_DB_EACH_END(ctx, cursor);
+
+ grn_ctx_output_cstr(ctx, "token_filters");
+
+ n = GRN_BULK_VSIZE(&token_filter_ids) / sizeof(grn_id);
+ grn_ctx_output_map_open(ctx, "token_filters", n);
+ for (i = 0; i < n; i++) {
+ grn_id token_filter_id;
+ grn_obj *token_filter;
+
+ token_filter_id = GRN_RECORD_VALUE_AT(&token_filter_ids, i);
+ token_filter = grn_ctx_at(ctx, token_filter_id);
+
+ command_schema_output_name(ctx, token_filter);
+
+ grn_ctx_output_map_open(ctx, "token_filter", 2);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, token_filter);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_name(ctx, token_filter);
+
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_map_close(ctx);
+
+ GRN_OBJ_FIN(ctx, &token_filter_ids);
+}
+
+static const char *
+command_schema_table_type_name(grn_ctx *ctx, grn_obj *table)
+{
+ const char *name = "unknown";
+
+ switch (table->header.type) {
+ case GRN_TABLE_NO_KEY :
+ name = "array";
+ break;
+ case GRN_TABLE_HASH_KEY :
+ name = "hash table";
+ break;
+ case GRN_TABLE_PAT_KEY :
+ name = "patricia trie";
+ break;
+ case GRN_TABLE_DAT_KEY :
+ name = "double array trie";
+ break;
+ default :
+ break;
+ }
+
+ return name;
+}
+
+static void
+command_schema_table_output_key_type(grn_ctx *ctx, grn_obj *table)
+{
+ grn_obj *key_type = NULL;
+
+ if (table->header.type != GRN_TABLE_NO_KEY &&
+ table->header.domain != GRN_ID_NIL) {
+ key_type = grn_ctx_at(ctx, table->header.domain);
+ }
+
+ command_schema_output_key_type(ctx, key_type);
+}
+
+static void
+command_schema_table_output_value_type(grn_ctx *ctx, grn_obj *table)
+{
+ grn_obj *value_type = NULL;
+ grn_id range = GRN_ID_NIL;
+
+ if (table->header.type != GRN_TABLE_DAT_KEY) {
+ range = grn_obj_get_range(ctx, table);
+ }
+ if (range != GRN_ID_NIL) {
+ value_type = grn_ctx_at(ctx, range);
+ }
+
+ command_schema_output_value_type(ctx, value_type);
+}
+
+static void
+command_schema_table_output_tokenizer(grn_ctx *ctx, grn_obj *table)
+{
+ grn_obj *tokenizer;
+
+ tokenizer = grn_obj_get_info(ctx, table, GRN_INFO_DEFAULT_TOKENIZER, NULL);
+ if (!tokenizer) {
+ grn_ctx_output_null(ctx);
+ return;
+ }
+
+ grn_ctx_output_map_open(ctx, "tokenizer", 2);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, tokenizer);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_name(ctx, tokenizer);
+
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_schema_table_output_normalizer(grn_ctx *ctx, grn_obj *table)
+{
+ grn_obj *normalizer;
+
+ normalizer = grn_obj_get_info(ctx, table, GRN_INFO_NORMALIZER, NULL);
+ if (!normalizer) {
+ grn_ctx_output_null(ctx);
+ return;
+ }
+
+ grn_ctx_output_map_open(ctx, "normalizer", 2);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, normalizer);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_name(ctx, normalizer);
+
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_schema_table_output_token_filters(grn_ctx *ctx, grn_obj *table)
+{
+ grn_obj token_filters;
+ int i, n;
+
+ GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, GRN_DB_OBJECT);
+ if (table->header.type != GRN_TABLE_NO_KEY) {
+ grn_obj_get_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters);
+ }
+
+ n = GRN_BULK_VSIZE(&token_filters) / sizeof(grn_obj *);
+ grn_ctx_output_array_open(ctx, "token_filters", n);
+ for (i = 0; i < n; i++) {
+ grn_obj *token_filter;
+
+ token_filter = GRN_PTR_VALUE_AT(&token_filters, i);
+
+ grn_ctx_output_map_open(ctx, "token_filter", 2);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, token_filter);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_name(ctx, token_filter);
+
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_array_close(ctx);
+
+ GRN_OBJ_FIN(ctx, &token_filters);
+}
+
+static void
+command_schema_table_command_collect_arguments(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *arguments)
+{
+#define ADD(name_, value_) \
+ grn_vector_add_element(ctx, arguments, \
+ name_, strlen(name_), \
+ 0, GRN_DB_TEXT); \
+ grn_vector_add_element(ctx, arguments, \
+ value_, strlen(value_), \
+ 0, GRN_DB_TEXT)
+
+#define ADD_OBJECT_NAME(name_, object_) do { \
+ char object_name[GRN_TABLE_MAX_KEY_SIZE]; \
+ unsigned int object_name_size; \
+ object_name_size = grn_obj_name(ctx, object_, \
+ object_name, \
+ GRN_TABLE_MAX_KEY_SIZE); \
+ object_name[object_name_size] = '\0'; \
+ ADD(name_, object_name); \
+ } while (GRN_FALSE)
+
+ ADD_OBJECT_NAME("name", table);
+
+ {
+ grn_obj flags;
+ grn_table_flags table_flags;
+ grn_table_flags ignored_flags = GRN_OBJ_KEY_NORMALIZE | GRN_OBJ_PERSISTENT;
+ GRN_TEXT_INIT(&flags, 0);
+ grn_table_get_info(ctx, table, &table_flags, NULL, NULL, NULL, NULL);
+ grn_dump_table_create_flags(ctx,
+ table_flags & ~ignored_flags,
+ &flags);
+ GRN_TEXT_PUTC(ctx, &flags, '\0');
+ ADD("flags", GRN_TEXT_VALUE(&flags));
+ GRN_OBJ_FIN(ctx, &flags);
+ }
+
+ {
+ grn_obj *key_type = NULL;
+
+ if (table->header.type != GRN_TABLE_NO_KEY &&
+ table->header.domain != GRN_ID_NIL) {
+ key_type = grn_ctx_at(ctx, table->header.domain);
+ }
+ if (key_type) {
+ ADD_OBJECT_NAME("key_type", key_type);
+ }
+ }
+
+ {
+ grn_obj *value_type = NULL;
+ grn_id range = GRN_ID_NIL;
+
+ if (table->header.type != GRN_TABLE_DAT_KEY) {
+ range = grn_obj_get_range(ctx, table);
+ }
+ if (range != GRN_ID_NIL) {
+ value_type = grn_ctx_at(ctx, range);
+ }
+ if (value_type) {
+ ADD_OBJECT_NAME("value_type", value_type);
+ }
+ }
+
+ {
+ grn_obj *tokenizer;
+ tokenizer = grn_obj_get_info(ctx, table, GRN_INFO_DEFAULT_TOKENIZER, NULL);
+ if (tokenizer) {
+ ADD_OBJECT_NAME("default_tokenizer", tokenizer);
+ }
+ }
+
+ {
+ grn_obj *normalizer;
+ normalizer = grn_obj_get_info(ctx, table, GRN_INFO_NORMALIZER, NULL);
+ if (!normalizer && (table->header.flags & GRN_OBJ_KEY_NORMALIZE)) {
+ normalizer = grn_ctx_get(ctx, "NormalizerAuto", -1);
+ }
+ if (normalizer) {
+ ADD_OBJECT_NAME("normalizer", normalizer);
+ }
+ }
+
+ if (table->header.type != GRN_TABLE_NO_KEY) {
+ grn_obj token_filters;
+ int n;
+
+ GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, GRN_DB_OBJECT);
+ grn_obj_get_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters);
+ n = GRN_BULK_VSIZE(&token_filters) / sizeof(grn_obj *);
+ if (n > 0) {
+ grn_obj token_filter_names;
+ int i;
+
+ GRN_TEXT_INIT(&token_filter_names, 0);
+ for (i = 0; i < n; i++) {
+ grn_obj *token_filter;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+
+ token_filter = GRN_PTR_VALUE_AT(&token_filters, i);
+ name_size = grn_obj_name(ctx, token_filter,
+ name, GRN_TABLE_MAX_KEY_SIZE);
+ if (i > 0) {
+ GRN_TEXT_PUTC(ctx, &token_filter_names, ',');
+ }
+ GRN_TEXT_PUT(ctx, &token_filter_names, name, name_size);
+ }
+ GRN_TEXT_PUTC(ctx, &token_filter_names, '\0');
+ ADD("token_filters", GRN_TEXT_VALUE(&token_filter_names));
+ GRN_OBJ_FIN(ctx, &token_filter_names);
+ }
+ GRN_OBJ_FIN(ctx, &token_filters);
+ }
+
+#undef ADD_OBJECT_NAME
+#undef ADD
+}
+
+static void
+command_schema_table_output_command(grn_ctx *ctx, grn_obj *table)
+{
+ grn_obj arguments;
+
+ GRN_TEXT_INIT(&arguments, GRN_OBJ_VECTOR);
+ command_schema_table_command_collect_arguments(ctx, table, &arguments);
+
+ command_schema_output_command(ctx, "table_create", &arguments);
+
+ GRN_OBJ_FIN(ctx, &arguments);
+}
+
+static void
+command_schema_column_output_type(grn_ctx *ctx, grn_obj *column)
+{
+ switch (column->header.type) {
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ switch (column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) {
+ case GRN_OBJ_COLUMN_SCALAR :
+ grn_ctx_output_cstr(ctx, "scalar");
+ break;
+ case GRN_OBJ_COLUMN_VECTOR :
+ grn_ctx_output_cstr(ctx, "vector");
+ break;
+ }
+ break;
+ case GRN_COLUMN_INDEX :
+ grn_ctx_output_cstr(ctx, "index");
+ break;
+ }
+}
+
+static void
+command_schema_column_output_value_type(grn_ctx *ctx, grn_obj *column)
+{
+ grn_obj *value_type;
+ value_type = grn_ctx_at(ctx, grn_obj_get_range(ctx, column));
+ command_schema_output_value_type(ctx, value_type);
+}
+
+static void
+command_schema_column_output_compress(grn_ctx *ctx, grn_obj *column)
+{
+ const char *compress = NULL;
+
+ if (column->header.type != GRN_COLUMN_INDEX) {
+ switch (column->header.flags & GRN_OBJ_COMPRESS_MASK) {
+ case GRN_OBJ_COMPRESS_ZLIB :
+ compress = "zlib";
+ break;
+ case GRN_OBJ_COMPRESS_LZ4 :
+ compress = "lz4";
+ break;
+ case GRN_OBJ_COMPRESS_ZSTD :
+ compress = "zstd";
+ break;
+ default :
+ break;
+ }
+ }
+
+ if (compress) {
+ grn_ctx_output_cstr(ctx, compress);
+ } else {
+ grn_ctx_output_null(ctx);
+ }
+}
+
+static void
+command_schema_column_output_sources(grn_ctx *ctx, grn_obj *column)
+{
+ grn_obj *source_table;
+ grn_obj source_ids;
+ unsigned int i, n_ids;
+
+ source_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, column));
+
+ GRN_RECORD_INIT(&source_ids, GRN_OBJ_VECTOR, GRN_ID_NIL);
+
+ if (column->header.type == GRN_COLUMN_INDEX) {
+ grn_obj_get_info(ctx, column, GRN_INFO_SOURCE, &source_ids);
+ }
+
+ n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id);
+ grn_ctx_output_array_open(ctx, "sources", n_ids);
+ for (i = 0; i < n_ids; i++) {
+ grn_id source_id;
+ grn_obj *source;
+
+ source_id = GRN_RECORD_VALUE_AT(&source_ids, i);
+ source = grn_ctx_at(ctx, source_id);
+
+ grn_ctx_output_map_open(ctx, "source", 4);
+
+ grn_ctx_output_cstr(ctx, "id");
+ if (grn_obj_is_table(ctx, source)) {
+ command_schema_output_id(ctx, NULL);
+ } else {
+ command_schema_output_id(ctx, source);
+ }
+
+ grn_ctx_output_cstr(ctx, "name");
+ if (grn_obj_is_table(ctx, source)) {
+ grn_ctx_output_cstr(ctx, "_key");
+ } else {
+ command_schema_output_column_name(ctx, source);
+ }
+
+ grn_ctx_output_cstr(ctx, "table");
+ command_schema_output_name(ctx, source_table);
+
+ grn_ctx_output_cstr(ctx, "full_name");
+ if (grn_obj_is_table(ctx, source)) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int name_size;
+ name_size = grn_obj_name(ctx, source, name, GRN_TABLE_MAX_KEY_SIZE);
+ name[name_size] = '\0';
+ grn_strcat(name, GRN_TABLE_MAX_KEY_SIZE, "._key");
+ grn_ctx_output_cstr(ctx, name);
+ } else {
+ command_schema_output_name(ctx, source);
+ }
+
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_array_close(ctx);
+
+ GRN_OBJ_FIN(ctx, &source_ids);
+}
+
+static void
+command_schema_output_indexes(grn_ctx *ctx, grn_obj *object)
+{
+ uint32_t i;
+ grn_index_datum *index_data = NULL;
+ uint32_t n_index_data = 0;
+
+ n_index_data = grn_column_get_all_index_data(ctx, object, NULL, 0);
+ if (n_index_data > 0) {
+ index_data = GRN_PLUGIN_MALLOC(ctx,
+ sizeof(grn_index_datum) * n_index_data);
+ if (!index_data) {
+ GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE,
+ "[schema] failed to allocate memory for indexes");
+ return;
+ }
+ grn_column_get_all_index_data(ctx, object, index_data, n_index_data);
+ }
+
+ grn_ctx_output_array_open(ctx, "indexes", n_index_data);
+ for (i = 0; i < n_index_data; i++) {
+ grn_obj *lexicon;
+
+ grn_ctx_output_map_open(ctx, "index", 5);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, index_data[i].index);
+
+ grn_ctx_output_cstr(ctx, "full_name");
+ command_schema_output_name(ctx, index_data[i].index);
+
+ grn_ctx_output_cstr(ctx, "table");
+ lexicon = grn_ctx_at(ctx, index_data[i].index->header.domain);
+ command_schema_output_name(ctx, lexicon);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_column_name(ctx, index_data[i].index);
+
+ grn_ctx_output_cstr(ctx, "section");
+ grn_ctx_output_uint64(ctx, index_data[i].section);
+
+ grn_ctx_output_map_close(ctx);
+ }
+ grn_ctx_output_array_close(ctx);
+
+ if (index_data) {
+ GRN_PLUGIN_FREE(ctx, index_data);
+ }
+}
+
+static void
+command_schema_column_command_collect_arguments(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *column,
+ grn_obj *arguments)
+{
+#define ADD(name_, value_) \
+ grn_vector_add_element(ctx, arguments, \
+ name_, strlen(name_), \
+ 0, GRN_DB_TEXT); \
+ grn_vector_add_element(ctx, arguments, \
+ value_, strlen(value_), \
+ 0, GRN_DB_TEXT)
+
+#define ADD_OBJECT_NAME(name_, object_) do { \
+ char object_name[GRN_TABLE_MAX_KEY_SIZE]; \
+ unsigned int object_name_size; \
+ object_name_size = grn_obj_name(ctx, object_, \
+ object_name, \
+ GRN_TABLE_MAX_KEY_SIZE); \
+ object_name[object_name_size] = '\0'; \
+ ADD(name_, object_name); \
+ } while (GRN_FALSE)
+
+ ADD_OBJECT_NAME("table", table);
+ {
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int column_name_size;
+ column_name_size = grn_column_name(ctx, column,
+ column_name, GRN_TABLE_MAX_KEY_SIZE);
+ column_name[column_name_size] = '\0';
+ ADD("name", column_name);
+ }
+
+ {
+ grn_obj flags;
+ grn_column_flags column_flags;
+
+ GRN_TEXT_INIT(&flags, 0);
+ column_flags = grn_column_get_flags(ctx, column);
+ grn_dump_column_create_flags(ctx,
+ column_flags & ~GRN_OBJ_PERSISTENT,
+ &flags);
+ GRN_TEXT_PUTC(ctx, &flags, '\0');
+ ADD("flags", GRN_TEXT_VALUE(&flags));
+ GRN_OBJ_FIN(ctx, &flags);
+ }
+
+ {
+ grn_obj *value_type;
+
+ value_type = grn_ctx_at(ctx, grn_obj_get_range(ctx, column));
+ ADD_OBJECT_NAME("type", value_type);
+ }
+
+ if (column->header.type == GRN_COLUMN_INDEX) {
+ grn_obj source_ids;
+ unsigned int n_ids;
+
+ GRN_RECORD_INIT(&source_ids, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ grn_obj_get_info(ctx, column, GRN_INFO_SOURCE, &source_ids);
+
+ n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id);
+ if (n_ids > 0) {
+ grn_obj sources;
+ unsigned int i;
+
+ GRN_TEXT_INIT(&sources, 0);
+ for (i = 0; i < n_ids; i++) {
+ grn_id source_id;
+ grn_obj *source;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int name_size;
+
+ source_id = GRN_RECORD_VALUE_AT(&source_ids, i);
+ source = grn_ctx_at(ctx, source_id);
+
+ if (grn_obj_is_table(ctx, source)) {
+ grn_strcpy(name, GRN_TABLE_MAX_KEY_SIZE, "_key");
+ name_size = strlen(name);
+ } else {
+ name_size = grn_column_name(ctx, source, name, GRN_TABLE_MAX_KEY_SIZE);
+ }
+ if (i > 0) {
+ GRN_TEXT_PUTC(ctx, &sources, ',');
+ }
+ GRN_TEXT_PUT(ctx, &sources, name, name_size);
+ }
+ GRN_TEXT_PUTC(ctx, &sources, '\0');
+ ADD("source", GRN_TEXT_VALUE(&sources));
+ GRN_OBJ_FIN(ctx, &sources);
+ }
+ GRN_OBJ_FIN(ctx, &source_ids);
+ }
+
+#undef ADD_OBJECT_NAME
+#undef ADD
+}
+
+static void
+command_schema_column_output_command(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *column)
+{
+ grn_obj arguments;
+
+ GRN_TEXT_INIT(&arguments, GRN_OBJ_VECTOR);
+ command_schema_column_command_collect_arguments(ctx, table, column, &arguments);
+
+ command_schema_output_command(ctx, "column_create", &arguments);
+
+ GRN_OBJ_FIN(ctx, &arguments);
+}
+
+static void
+command_schema_column_output(grn_ctx *ctx, grn_obj *table, grn_obj *column)
+{
+ if (!column) {
+ return;
+ }
+
+ command_schema_output_column_name(ctx, column);
+
+ grn_ctx_output_map_open(ctx, "column", 13);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, column);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_column_name(ctx, column);
+
+ grn_ctx_output_cstr(ctx, "table");
+ command_schema_output_name(ctx, table);
+
+ grn_ctx_output_cstr(ctx, "full_name");
+ command_schema_output_name(ctx, column);
+
+ grn_ctx_output_cstr(ctx, "type");
+ command_schema_column_output_type(ctx, column);
+
+ grn_ctx_output_cstr(ctx, "value_type");
+ command_schema_column_output_value_type(ctx, column);
+
+ grn_ctx_output_cstr(ctx, "compress");
+ command_schema_column_output_compress(ctx, column);
+
+ grn_ctx_output_cstr(ctx, "section");
+ grn_ctx_output_bool(ctx, (column->header.flags & GRN_OBJ_WITH_SECTION) != 0);
+
+ grn_ctx_output_cstr(ctx, "weight");
+ grn_ctx_output_bool(ctx, (column->header.flags & GRN_OBJ_WITH_WEIGHT) != 0);
+
+ grn_ctx_output_cstr(ctx, "position");
+ grn_ctx_output_bool(ctx, (column->header.flags & GRN_OBJ_WITH_POSITION) != 0);
+
+ grn_ctx_output_cstr(ctx, "sources");
+ command_schema_column_output_sources(ctx, column);
+
+ grn_ctx_output_cstr(ctx, "indexes");
+ command_schema_output_indexes(ctx, column);
+
+ grn_ctx_output_cstr(ctx, "command");
+ command_schema_column_output_command(ctx, table, column);
+
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_schema_table_output_columns(grn_ctx *ctx,
+ grn_obj *table,
+ grn_schema_data *data)
+{
+ grn_hash *columns;
+
+ columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY | GRN_HASH_TINY);
+ if (!columns) {
+ grn_ctx_output_map_open(ctx, "columns", 0);
+ grn_ctx_output_map_close(ctx);
+ return;
+ }
+
+ grn_table_columns(ctx, table, "", 0, (grn_obj *)columns);
+ grn_ctx_output_map_open(ctx, "columns", grn_hash_size(ctx, columns));
+ {
+ grn_id *key;
+ GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, {
+ grn_obj *column;
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ column = grn_ctx_at(ctx, *key);
+ command_schema_column_output(ctx, table, column);
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ });
+ }
+ grn_ctx_output_map_close(ctx);
+ grn_hash_close(ctx, columns);
+}
+
+static void
+command_schema_output_table(grn_ctx *ctx,
+ grn_schema_data *data,
+ grn_obj *table)
+{
+ command_schema_output_name(ctx, table);
+
+ grn_ctx_output_map_open(ctx, "table", 11);
+
+ grn_ctx_output_cstr(ctx, "id");
+ command_schema_output_id(ctx, table);
+
+ grn_ctx_output_cstr(ctx, "name");
+ command_schema_output_name(ctx, table);
+
+ grn_ctx_output_cstr(ctx, "type");
+ grn_ctx_output_cstr(ctx, command_schema_table_type_name(ctx, table));
+
+ grn_ctx_output_cstr(ctx, "key_type");
+ command_schema_table_output_key_type(ctx, table);
+
+ grn_ctx_output_cstr(ctx, "value_type");
+ command_schema_table_output_value_type(ctx, table);
+
+ grn_ctx_output_cstr(ctx, "tokenizer");
+ command_schema_table_output_tokenizer(ctx, table);
+
+ grn_ctx_output_cstr(ctx, "normalizer");
+ command_schema_table_output_normalizer(ctx, table);
+
+ grn_ctx_output_cstr(ctx, "token_filters");
+ command_schema_table_output_token_filters(ctx, table);
+
+ grn_ctx_output_cstr(ctx, "indexes");
+ command_schema_output_indexes(ctx, table);
+
+ grn_ctx_output_cstr(ctx, "command");
+ command_schema_table_output_command(ctx, table);
+
+ grn_ctx_output_cstr(ctx, "columns");
+ command_schema_table_output_columns(ctx, table, data);
+
+ grn_ctx_output_map_close(ctx);
+}
+
+static void
+command_schema_output_tables(grn_ctx *ctx, grn_schema_data *data)
+{
+ grn_obj table_ids;
+ unsigned int i, n;
+
+ GRN_RECORD_INIT(&table_ids, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) {
+ void *name;
+ int name_size;
+ grn_obj *object;
+
+ if (grn_id_is_builtin(ctx, id)) {
+ continue;
+ }
+
+ name_size = grn_table_cursor_get_key(ctx, cursor, &name);
+ if (grn_obj_name_is_column(ctx, name, name_size)) {
+ continue;
+ }
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ object = grn_ctx_at(ctx, id);
+ if (!object) {
+ /* XXX: this clause is executed when MeCab tokenizer is enabled in
+ database but the groonga isn't supported MeCab.
+ We should return error mesage about it and error exit status
+ but it's too difficult for this architecture. :< */
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ goto next_loop;
+ }
+
+ if (grn_obj_is_table(ctx, object)) {
+ GRN_RECORD_PUT(ctx, &table_ids, id);
+ }
+
+ next_loop :
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+
+ n = GRN_BULK_VSIZE(&table_ids) / sizeof(grn_id);
+
+ grn_ctx_output_cstr(ctx, "tables");
+ grn_ctx_output_map_open(ctx, "tables", n);
+ for (i = 0; i < n; i++) {
+ grn_id table_id;
+ grn_obj *table;
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_push_temporary_open_space(ctx);
+ }
+
+ table_id = GRN_RECORD_VALUE_AT(&table_ids, i);
+ table = grn_ctx_at(ctx, table_id);
+
+ command_schema_output_table(ctx, data, table);
+
+ if (data->is_close_opened_object_mode) {
+ grn_ctx_pop_temporary_open_space(ctx);
+ }
+ }
+ grn_ctx_output_map_close(ctx);
+
+ GRN_OBJ_FIN(ctx, &table_ids);
+}
+
+static grn_obj *
+command_schema(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_schema_data data;
+
+ data.is_close_opened_object_mode = (grn_thread_get_limit() == 1);
+
+ grn_ctx_output_map_open(ctx, "schema", 6);
+ command_schema_output_plugins(ctx);
+ command_schema_output_types(ctx);
+ command_schema_output_tokenizers(ctx, &data);
+ command_schema_output_normalizers(ctx, &data);
+ command_schema_output_token_filters(ctx, &data);
+ command_schema_output_tables(ctx, &data);
+ grn_ctx_output_map_close(ctx);
+
+ return NULL;
+}
+
+void
+grn_proc_init_schema(grn_ctx *ctx)
+{
+ grn_plugin_command_create(ctx,
+ "schema", -1,
+ command_schema,
+ 0,
+ NULL);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_select.c b/storage/mroonga/vendor/groonga/lib/proc/proc_select.c
new file mode 100644
index 00000000000..f902f160d0e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_select.c
@@ -0,0 +1,3808 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+#include "../grn_raw_string.h"
+#include "../grn_expr.h"
+#include "../grn_str.h"
+#include "../grn_output.h"
+#include "../grn_util.h"
+#include "../grn_cache.h"
+#include "../grn_ii.h"
+
+#include "../grn_ts.h"
+
+#include <groonga/plugin.h>
+
+#define GRN_SELECT_INTERNAL_VAR_MATCH_COLUMNS "$match_columns"
+
+#define DEFAULT_DRILLDOWN_LIMIT 10
+#define DEFAULT_DRILLDOWN_OUTPUT_COLUMNS "_key, _nsubrecs"
+
+typedef enum {
+ GRN_COLUMN_STAGE_INITIAL,
+ GRN_COLUMN_STAGE_FILTERED,
+ GRN_COLUMN_STAGE_OUTPUT
+} grn_column_stage;
+
+typedef struct {
+ grn_raw_string label;
+ grn_column_stage stage;
+ grn_obj *type;
+ grn_obj_flags flags;
+ grn_raw_string value;
+ struct {
+ grn_raw_string sort_keys;
+ grn_raw_string group_keys;
+ } window;
+} grn_column_data;
+
+typedef struct {
+ grn_hash *initial;
+ grn_hash *filtered;
+ grn_hash *output;
+} grn_columns;
+
+typedef struct {
+ grn_raw_string match_columns;
+ grn_raw_string query;
+ grn_raw_string query_expander;
+ grn_raw_string query_flags;
+ grn_raw_string filter;
+ struct {
+ grn_obj *match_columns;
+ grn_obj *expression;
+ } condition;
+ grn_obj *filtered;
+} grn_filter_data;
+
+typedef struct {
+ grn_raw_string label;
+ grn_filter_data filter;
+ grn_raw_string sort_keys;
+ grn_raw_string output_columns;
+ int offset;
+ int limit;
+ grn_obj *table;
+} grn_slice_data;
+
+typedef struct {
+ grn_raw_string label;
+ grn_raw_string keys;
+ grn_table_sort_key *parsed_keys;
+ int n_parsed_keys;
+ grn_raw_string sort_keys;
+ grn_raw_string output_columns;
+ int offset;
+ int limit;
+ grn_table_group_flags calc_types;
+ grn_raw_string calc_target_name;
+ grn_raw_string filter;
+ grn_raw_string table_name;
+ grn_columns columns;
+ grn_table_group_result result;
+ grn_obj *filtered_result;
+} grn_drilldown_data;
+
+typedef struct _grn_select_output_formatter grn_select_output_formatter;
+
+typedef struct {
+ /* inputs */
+ grn_raw_string table;
+ grn_filter_data filter;
+ grn_raw_string scorer;
+ grn_raw_string sort_keys;
+ grn_raw_string output_columns;
+ int offset;
+ int limit;
+ grn_hash *slices;
+ grn_drilldown_data drilldown;
+ grn_hash *drilldowns;
+ grn_raw_string cache;
+ grn_raw_string match_escalation_threshold;
+ grn_raw_string adjuster;
+ grn_columns columns;
+
+ /* for processing */
+ struct {
+ grn_obj *target;
+ grn_obj *initial;
+ grn_obj *result;
+ grn_obj *sorted;
+ grn_obj *output;
+ } tables;
+ uint16_t cacheable;
+ uint16_t taintable;
+ struct {
+ int n_elements;
+ grn_select_output_formatter *formatter;
+ } output;
+} grn_select_data;
+
+typedef void grn_select_output_slices_label_func(grn_ctx *ctx,
+ grn_select_data *data);
+typedef void grn_select_output_slices_open_func(grn_ctx *ctx,
+ grn_select_data *data,
+ unsigned int n_result_sets);
+typedef void grn_select_output_slices_close_func(grn_ctx *ctx,
+ grn_select_data *data);
+typedef void grn_select_output_slice_label_func(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_slice_data *slice);
+typedef void grn_select_output_drilldowns_label_func(grn_ctx *ctx,
+ grn_select_data *data);
+typedef void grn_select_output_drilldowns_open_func(grn_ctx *ctx,
+ grn_select_data *data,
+ unsigned int n_result_sets);
+typedef void grn_select_output_drilldowns_close_func(grn_ctx *ctx,
+ grn_select_data *data);
+typedef void grn_select_output_drilldown_label_func(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_drilldown_data *drilldown);
+
+struct _grn_select_output_formatter {
+ grn_select_output_slices_label_func *slices_label;
+ grn_select_output_slices_open_func *slices_open;
+ grn_select_output_slices_close_func *slices_close;
+ grn_select_output_slice_label_func *slice_label;
+ grn_select_output_drilldowns_label_func *drilldowns_label;
+ grn_select_output_drilldowns_open_func *drilldowns_open;
+ grn_select_output_drilldowns_close_func *drilldowns_close;
+ grn_select_output_drilldown_label_func *drilldown_label;
+};
+
+grn_rc
+grn_proc_syntax_expand_query(grn_ctx *ctx,
+ const char *query,
+ unsigned int query_len,
+ grn_expr_flags flags,
+ const char *query_expander_name,
+ unsigned int query_expander_name_len,
+ const char *term_column_name,
+ unsigned int term_column_name_len,
+ const char *expanded_term_column_name,
+ unsigned int expanded_term_column_name_len,
+ grn_obj *expanded_query,
+ const char *error_message_tag)
+{
+ grn_obj *query_expander;
+
+ query_expander = grn_ctx_get(ctx,
+ query_expander_name,
+ query_expander_name_len);
+ if (!query_expander) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "%s nonexistent query expander: <%.*s>",
+ error_message_tag,
+ (int)query_expander_name_len,
+ query_expander_name);
+ return ctx->rc;
+ }
+
+ if (expanded_term_column_name_len == 0) {
+ return grn_expr_syntax_expand_query(ctx, query, query_len, flags,
+ query_expander, expanded_query);
+ }
+
+ if (!grn_obj_is_table(ctx, query_expander)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, query_expander);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "%s query expander with expanded term column "
+ "must be table: <%.*s>",
+ error_message_tag,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return ctx->rc;
+ }
+
+ {
+ grn_obj *term_column = NULL;
+ grn_obj *expanded_term_column;
+
+ expanded_term_column = grn_obj_column(ctx,
+ query_expander,
+ expanded_term_column_name,
+ expanded_term_column_name_len);
+ if (!expanded_term_column) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, query_expander);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "%s nonexistent expanded term column: <%.*s>: "
+ "query expander: <%.*s>",
+ error_message_tag,
+ (int)expanded_term_column_name_len,
+ expanded_term_column_name,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return ctx->rc;
+ }
+
+ if (term_column_name_len > 0) {
+ term_column = grn_obj_column(ctx,
+ query_expander,
+ term_column_name,
+ term_column_name_len);
+ if (!term_column) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, query_expander);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "%s nonexistent term column: <%.*s>: "
+ "query expander: <%.*s>",
+ error_message_tag,
+ (int)term_column_name_len,
+ term_column_name,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ if (grn_obj_is_accessor(ctx, expanded_term_column)) {
+ grn_obj_unlink(ctx, expanded_term_column);
+ }
+ return ctx->rc;
+ }
+ }
+
+ grn_expr_syntax_expand_query_by_table(ctx,
+ query, query_len,
+ flags,
+ term_column,
+ expanded_term_column,
+ expanded_query);
+ if (grn_obj_is_accessor(ctx, term_column)) {
+ grn_obj_unlink(ctx, term_column);
+ }
+ if (grn_obj_is_accessor(ctx, expanded_term_column)) {
+ grn_obj_unlink(ctx, expanded_term_column);
+ }
+ return ctx->rc;
+ }
+}
+
+static grn_table_group_flags
+grn_parse_table_group_calc_types(grn_ctx *ctx,
+ const char *calc_types,
+ unsigned int calc_types_len)
+{
+ grn_table_group_flags flags = 0;
+ const char *calc_types_end = calc_types + calc_types_len;
+
+ while (calc_types < calc_types_end) {
+ if (*calc_types == ',' || *calc_types == ' ') {
+ calc_types += 1;
+ continue;
+ }
+
+#define CHECK_TABLE_GROUP_CALC_TYPE(name)\
+ if (((calc_types_end - calc_types) >= (sizeof(#name) - 1)) &&\
+ (!memcmp(calc_types, #name, sizeof(#name) - 1))) {\
+ flags |= GRN_TABLE_GROUP_CALC_ ## name;\
+ calc_types += sizeof(#name) - 1;\
+ continue;\
+ }
+
+ CHECK_TABLE_GROUP_CALC_TYPE(COUNT);
+ CHECK_TABLE_GROUP_CALC_TYPE(MAX);
+ CHECK_TABLE_GROUP_CALC_TYPE(MIN);
+ CHECK_TABLE_GROUP_CALC_TYPE(SUM);
+ CHECK_TABLE_GROUP_CALC_TYPE(AVG);
+
+#define GRN_TABLE_GROUP_CALC_NONE 0
+ CHECK_TABLE_GROUP_CALC_TYPE(NONE);
+#undef GRN_TABLE_GROUP_CALC_NONE
+
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "invalid table group calc type: <%.*s>",
+ (int)(calc_types_end - calc_types),
+ calc_types);
+ return 0;
+#undef CHECK_TABLE_GROUP_CALC_TYPE
+ }
+
+ return flags;
+}
+
+static const char *
+grn_column_stage_name(grn_column_stage stage)
+{
+ switch (stage) {
+ case GRN_COLUMN_STAGE_INITIAL :
+ return "initial";
+ case GRN_COLUMN_STAGE_FILTERED :
+ return "filtered";
+ case GRN_COLUMN_STAGE_OUTPUT :
+ return "output";
+ default :
+ return "unknown";
+ }
+}
+
+static grn_bool
+grn_column_data_init(grn_ctx *ctx,
+ const char *label,
+ size_t label_len,
+ grn_column_stage stage,
+ grn_hash **columns)
+{
+ void *column_raw;
+ grn_column_data *column;
+ int added;
+
+ if (!*columns) {
+ *columns = grn_hash_create(ctx,
+ NULL,
+ GRN_TABLE_MAX_KEY_SIZE,
+ sizeof(grn_column_data),
+ GRN_OBJ_TABLE_HASH_KEY |
+ GRN_OBJ_KEY_VAR_SIZE |
+ GRN_HASH_TINY);
+ }
+ if (!*columns) {
+ return GRN_FALSE;
+ }
+
+ grn_hash_add(ctx,
+ *columns,
+ label,
+ label_len,
+ &column_raw,
+ &added);
+ if (!added) {
+ return GRN_TRUE;
+ }
+
+ column = column_raw;
+ column->label.value = label;
+ column->label.length = label_len;
+ column->stage = stage;
+ column->type = grn_ctx_at(ctx, GRN_DB_TEXT);
+ column->flags = GRN_OBJ_COLUMN_SCALAR;
+ GRN_RAW_STRING_INIT(column->value);
+ GRN_RAW_STRING_INIT(column->window.sort_keys);
+ GRN_RAW_STRING_INIT(column->window.group_keys);
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_column_data_fill(grn_ctx *ctx,
+ grn_column_data *column,
+ grn_obj *type_raw,
+ grn_obj *flags,
+ grn_obj *value,
+ grn_obj *window_sort_keys,
+ grn_obj *window_group_keys)
+{
+ if (type_raw && GRN_TEXT_LEN(type_raw) > 0) {
+ grn_obj *type;
+
+ type = grn_ctx_get(ctx, GRN_TEXT_VALUE(type_raw), GRN_TEXT_LEN(type_raw));
+ if (!type) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][columns][%s][%.*s] unknown type: <%.*s>",
+ grn_column_stage_name(column->stage),
+ (int)(column->label.length),
+ column->label.value,
+ (int)(GRN_TEXT_LEN(type_raw)),
+ GRN_TEXT_VALUE(type_raw));
+ return GRN_FALSE;
+ }
+ if (!(grn_obj_is_type(ctx, type) || grn_obj_is_table(ctx, type))) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, type);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][columns][%s][%.*s] invalid type: %.*s",
+ grn_column_stage_name(column->stage),
+ (int)(column->label.length),
+ column->label.value,
+ (int)(GRN_TEXT_LEN(&inspected)),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ grn_obj_unlink(ctx, type);
+ return GRN_FALSE;
+ }
+ column->type = type;
+ }
+
+ if (flags && GRN_TEXT_LEN(flags) > 0) {
+ char error_message_tag[GRN_TABLE_MAX_KEY_SIZE];
+
+ grn_snprintf(error_message_tag,
+ GRN_TABLE_MAX_KEY_SIZE,
+ GRN_TABLE_MAX_KEY_SIZE,
+ "[select][columns][%s][%.*s]",
+ grn_column_stage_name(column->stage),
+ (int)(column->label.length),
+ column->label.value);
+ column->flags =
+ grn_proc_column_parse_flags(ctx,
+ error_message_tag,
+ GRN_TEXT_VALUE(flags),
+ GRN_TEXT_VALUE(flags) + GRN_TEXT_LEN(flags));
+ if (ctx->rc != GRN_SUCCESS) {
+ return GRN_FALSE;
+ }
+ }
+
+ GRN_RAW_STRING_FILL(column->value, value);
+ GRN_RAW_STRING_FILL(column->window.sort_keys, window_sort_keys);
+ GRN_RAW_STRING_FILL(column->window.group_keys, window_group_keys);
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_column_data_collect(grn_ctx *ctx,
+ grn_user_data *user_data,
+ grn_hash *columns,
+ const char *prefix_label,
+ size_t prefix_label_len)
+{
+ grn_hash_cursor *cursor = NULL;
+
+ cursor = grn_hash_cursor_open(ctx, columns,
+ NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ return GRN_FALSE;
+ }
+
+ while (grn_hash_cursor_next(ctx, cursor)) {
+ grn_column_data *column;
+ char key_name[GRN_TABLE_MAX_KEY_SIZE];
+ grn_obj *type = NULL;
+ grn_obj *flags = NULL;
+ grn_obj *value = NULL;
+ struct {
+ grn_obj *sort_keys;
+ grn_obj *group_keys;
+ } window;
+
+ window.sort_keys = NULL;
+ window.group_keys = NULL;
+
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&column);
+
+#define GET_VAR_RAW(parameter_key, name) \
+ if (!name) { \
+ grn_snprintf(key_name, \
+ GRN_TABLE_MAX_KEY_SIZE, \
+ GRN_TABLE_MAX_KEY_SIZE, \
+ "%.*s%s[%.*s]." # name, \
+ (int)prefix_label_len, \
+ prefix_label, \
+ parameter_key, \
+ (int)(column->label.length), \
+ column->label.value); \
+ name = grn_plugin_proc_get_var(ctx, user_data, key_name, -1); \
+ }
+
+#define GET_VAR(name) do { \
+ GET_VAR_RAW("columns", name); \
+ /* For backward compatibility */ \
+ GET_VAR_RAW("column", name); \
+ } while (GRN_FALSE)
+
+ GET_VAR(type);
+ GET_VAR(flags);
+ GET_VAR(value);
+ GET_VAR(window.sort_keys);
+ GET_VAR(window.group_keys);
+
+#undef GET_VAR
+
+#undef GET_VAR_RAW
+
+ grn_column_data_fill(ctx, column,
+ type, flags, value,
+ window.sort_keys,
+ window.group_keys);
+ }
+ grn_hash_cursor_close(ctx, cursor);
+ return GRN_TRUE;
+}
+
+static void
+grn_columns_init(grn_ctx *ctx, grn_columns *columns)
+{
+ columns->initial = NULL;
+ columns->filtered = NULL;
+ columns->output = NULL;
+}
+
+static void
+grn_columns_fin(grn_ctx *ctx, grn_columns *columns)
+{
+ if (columns->initial) {
+ grn_hash_close(ctx, columns->initial);
+ }
+
+ if (columns->filtered) {
+ grn_hash_close(ctx, columns->filtered);
+ }
+
+ if (columns->output) {
+ grn_hash_close(ctx, columns->output);
+ }
+}
+
+static grn_bool
+grn_columns_collect(grn_ctx *ctx,
+ grn_user_data *user_data,
+ grn_columns *columns,
+ const char *prefix,
+ const char *base_prefix,
+ size_t base_prefix_len)
+{
+ grn_obj *vars;
+ grn_table_cursor *cursor;
+ size_t prefix_len;
+ const char *suffix = "].stage";
+ size_t suffix_len;
+
+ vars = grn_plugin_proc_get_vars(ctx, user_data);
+ cursor = grn_table_cursor_open(ctx, vars, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ return GRN_FALSE;
+ }
+
+ prefix_len = strlen(prefix);
+ suffix_len = strlen(suffix);
+ while (grn_table_cursor_next(ctx, cursor)) {
+ void *key;
+ char *variable_name;
+ int variable_name_len;
+ char *column_name;
+ size_t column_name_len;
+ void *value_raw;
+ grn_obj *value;
+ grn_column_stage stage;
+ grn_hash **target_columns;
+
+ variable_name_len = grn_table_cursor_get_key(ctx, cursor, &key);
+ variable_name = key;
+ if (variable_name_len < base_prefix_len + prefix_len + suffix_len + 1) {
+ continue;
+ }
+
+ if (base_prefix_len > 0) {
+ if (memcmp(base_prefix, variable_name, base_prefix_len) != 0) {
+ continue;
+ }
+ }
+
+ if (memcmp(prefix, variable_name + base_prefix_len, prefix_len) != 0) {
+ continue;
+ }
+
+ if (memcmp(suffix,
+ variable_name + (variable_name_len - suffix_len),
+ suffix_len) != 0) {
+ continue;
+ }
+
+ grn_table_cursor_get_value(ctx, cursor, &value_raw);
+ value = value_raw;
+ if (GRN_TEXT_EQUAL_CSTRING(value, "initial")) {
+ stage = GRN_COLUMN_STAGE_INITIAL;
+ target_columns = &(columns->initial);
+ } else if (GRN_TEXT_EQUAL_CSTRING(value, "filtered")) {
+ stage = GRN_COLUMN_STAGE_FILTERED;
+ target_columns = &(columns->filtered);
+ } else if (GRN_TEXT_EQUAL_CSTRING(value, "output")) {
+ stage = GRN_COLUMN_STAGE_OUTPUT;
+ target_columns = &(columns->output);
+ } else {
+ continue;
+ }
+
+ column_name = variable_name + base_prefix_len + prefix_len;
+ column_name_len =
+ variable_name_len - base_prefix_len - prefix_len - suffix_len;
+ if (!grn_column_data_init(ctx,
+ column_name,
+ column_name_len,
+ stage,
+ target_columns)) {
+ grn_table_cursor_close(ctx, cursor);
+ return GRN_FALSE;
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_columns_fill(grn_ctx *ctx,
+ grn_user_data *user_data,
+ grn_columns *columns,
+ const char *prefix,
+ size_t prefix_length)
+{
+ if (!grn_columns_collect(ctx, user_data, columns,
+ "columns[", prefix, prefix_length)) {
+ return GRN_FALSE;
+ }
+
+ /* For backward compatibility */
+ if (!grn_columns_collect(ctx, user_data, columns,
+ "column[", prefix, prefix_length)) {
+ return GRN_FALSE;
+ }
+
+ if (columns->initial) {
+ if (!grn_column_data_collect(ctx,
+ user_data,
+ columns->initial,
+ prefix,
+ prefix_length)) {
+ return GRN_FALSE;
+ }
+ }
+
+ if (columns->filtered) {
+ if (!grn_column_data_collect(ctx,
+ user_data,
+ columns->filtered,
+ prefix,
+ prefix_length)) {
+ return GRN_FALSE;
+ }
+ }
+
+ if (columns->output) {
+ if (!grn_column_data_collect(ctx,
+ user_data,
+ columns->output,
+ prefix,
+ prefix_length)) {
+ return GRN_FALSE;
+ }
+ }
+
+ return GRN_TRUE;
+}
+
+static void
+grn_filter_data_init(grn_ctx *ctx, grn_filter_data *data)
+{
+ GRN_RAW_STRING_INIT(data->match_columns);
+ GRN_RAW_STRING_INIT(data->query);
+ GRN_RAW_STRING_INIT(data->query_expander);
+ GRN_RAW_STRING_INIT(data->query_flags);
+ GRN_RAW_STRING_INIT(data->filter);
+ data->condition.match_columns = NULL;
+ data->condition.expression = NULL;
+ data->filtered = NULL;
+}
+
+static void
+grn_filter_data_fin(grn_ctx *ctx, grn_filter_data *data)
+{
+ if (data->filtered) {
+ grn_obj_unlink(ctx, data->filtered);
+ }
+ if (data->condition.expression) {
+ grn_obj_close(ctx, data->condition.expression);
+ }
+ if (data->condition.match_columns) {
+ grn_obj_close(ctx, data->condition.match_columns);
+ }
+}
+
+static void
+grn_filter_data_fill(grn_ctx *ctx,
+ grn_filter_data *data,
+ grn_obj *match_columns,
+ grn_obj *query,
+ grn_obj *query_expander,
+ grn_obj *query_flags,
+ grn_obj *filter)
+{
+ GRN_RAW_STRING_FILL(data->match_columns, match_columns);
+ GRN_RAW_STRING_FILL(data->query, query);
+ GRN_RAW_STRING_FILL(data->query_expander, query_expander);
+ GRN_RAW_STRING_FILL(data->query_flags, query_flags);
+ GRN_RAW_STRING_FILL(data->filter, filter);
+}
+
+static grn_bool
+grn_filter_data_execute(grn_ctx *ctx,
+ grn_filter_data *data,
+ grn_obj *table,
+ const char *tag)
+{
+ grn_obj *variable;
+
+ if (data->query.length == 0 && data->filter.length == 0) {
+ return GRN_TRUE;
+ }
+
+ GRN_EXPR_CREATE_FOR_QUERY(ctx,
+ table,
+ data->condition.expression,
+ variable);
+ if (!data->condition.expression) {
+ grn_rc rc = ctx->rc;
+ if (rc == GRN_SUCCESS) {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ }
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "%s[condition] "
+ "failed to create expression for condition: %s",
+ tag,
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+
+ if (data->query.length > 0) {
+ if (data->match_columns.length > 0) {
+ GRN_EXPR_CREATE_FOR_QUERY(ctx,
+ table,
+ data->condition.match_columns,
+ variable);
+ if (!data->condition.match_columns) {
+ grn_rc rc = ctx->rc;
+ if (rc == GRN_SUCCESS) {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ }
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "%s[match_columns] "
+ "failed to create expression for match columns: "
+ "<%.*s>: %s",
+ tag,
+ (int)(data->match_columns.length),
+ data->match_columns.value,
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+
+ grn_expr_parse(ctx,
+ data->condition.match_columns,
+ data->match_columns.value,
+ data->match_columns.length,
+ NULL, GRN_OP_MATCH, GRN_OP_AND,
+ GRN_EXPR_SYNTAX_SCRIPT);
+ if (ctx->rc != GRN_SUCCESS) {
+ return GRN_FALSE;
+ }
+ }
+
+ {
+ grn_expr_flags flags;
+ grn_obj query_expander_buf;
+ const char *query = data->query.value;
+ unsigned int query_len = data->query.length;
+
+ flags = GRN_EXPR_SYNTAX_QUERY;
+ if (data->query_flags.length) {
+ flags |= grn_proc_expr_query_flags_parse(ctx,
+ data->query_flags.value,
+ data->query_flags.length,
+ tag);
+ if (ctx->rc != GRN_SUCCESS) {
+ return GRN_FALSE;
+ }
+ } else {
+ flags |= GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN;
+ }
+
+ GRN_TEXT_INIT(&query_expander_buf, 0);
+ if (data->query_expander.length > 0) {
+ grn_rc rc;
+ rc = grn_proc_syntax_expand_query(ctx,
+ data->query.value,
+ data->query.length,
+ flags,
+ data->query_expander.value,
+ data->query_expander.length,
+ NULL, 0,
+ NULL, 0,
+ &query_expander_buf,
+ tag);
+ if (rc == GRN_SUCCESS) {
+ query = GRN_TEXT_VALUE(&query_expander_buf);
+ query_len = GRN_TEXT_LEN(&query_expander_buf);
+ } else {
+ GRN_OBJ_FIN(ctx, &query_expander_buf);
+ return GRN_FALSE;
+ }
+ }
+
+ grn_expr_parse(ctx,
+ data->condition.expression,
+ query,
+ query_len,
+ data->condition.match_columns,
+ GRN_OP_MATCH,
+ GRN_OP_AND,
+ flags);
+ GRN_OBJ_FIN(ctx, &query_expander_buf);
+
+ if (ctx->rc != GRN_SUCCESS) {
+ return GRN_FALSE;
+ }
+ }
+ }
+
+ if (data->filter.length > 0) {
+ grn_expr_parse(ctx,
+ data->condition.expression,
+ data->filter.value,
+ data->filter.length,
+ data->condition.match_columns,
+ GRN_OP_MATCH,
+ GRN_OP_AND,
+ GRN_EXPR_SYNTAX_SCRIPT);
+ if (ctx->rc != GRN_SUCCESS) {
+ return GRN_FALSE;
+ }
+
+ if (data->query.length > 0) {
+ grn_expr_append_op(ctx, data->condition.expression, GRN_OP_AND, 2);
+ }
+
+ if (ctx->rc != GRN_SUCCESS) {
+ return GRN_FALSE;
+ }
+ }
+
+ data->filtered = grn_table_select(ctx,
+ table,
+ data->condition.expression,
+ NULL,
+ GRN_OP_OR);
+
+ return ctx->rc == GRN_SUCCESS;
+}
+
+static void
+grn_slice_data_init(grn_ctx *ctx,
+ grn_slice_data *slice,
+ const char *label,
+ size_t label_len)
+{
+ slice->label.value = label;
+ slice->label.length = label_len;
+ grn_filter_data_init(ctx, &(slice->filter));
+ GRN_RAW_STRING_INIT(slice->sort_keys);
+ GRN_RAW_STRING_INIT(slice->output_columns);
+ slice->offset = 0;
+ slice->limit = GRN_SELECT_DEFAULT_LIMIT;
+ slice->table = NULL;
+}
+
+static void
+grn_slice_data_fin(grn_ctx *ctx, grn_slice_data *slice)
+{
+ grn_filter_data_fin(ctx, &(slice->filter));
+}
+
+static void
+grn_slice_data_fill(grn_ctx *ctx,
+ grn_slice_data *slice,
+ grn_obj *match_columns,
+ grn_obj *query,
+ grn_obj *query_expander,
+ grn_obj *query_flags,
+ grn_obj *filter,
+ grn_obj *sort_keys,
+ grn_obj *output_columns,
+ grn_obj *offset,
+ grn_obj *limit)
+{
+ grn_filter_data_fill(ctx,
+ &(slice->filter),
+ match_columns,
+ query,
+ query_expander,
+ query_flags,
+ filter);
+
+ GRN_RAW_STRING_FILL(slice->sort_keys, sort_keys);
+
+ GRN_RAW_STRING_FILL(slice->output_columns, output_columns);
+ if (slice->output_columns.length == 0) {
+ slice->output_columns.value = GRN_SELECT_DEFAULT_OUTPUT_COLUMNS;
+ slice->output_columns.length = strlen(GRN_SELECT_DEFAULT_OUTPUT_COLUMNS);
+ }
+
+ slice->offset = grn_proc_option_value_int32(ctx, offset, 0);
+ slice->limit = grn_proc_option_value_int32(ctx,
+ limit,
+ GRN_SELECT_DEFAULT_LIMIT);
+}
+
+static void
+grn_drilldown_data_init(grn_ctx *ctx,
+ grn_drilldown_data *drilldown,
+ const char *label,
+ size_t label_len)
+{
+ drilldown->label.value = label;
+ drilldown->label.length = label_len;
+ GRN_RAW_STRING_INIT(drilldown->keys);
+ drilldown->parsed_keys = NULL;
+ drilldown->n_parsed_keys = 0;
+ GRN_RAW_STRING_INIT(drilldown->sort_keys);
+ GRN_RAW_STRING_INIT(drilldown->output_columns);
+ drilldown->offset = 0;
+ drilldown->limit = DEFAULT_DRILLDOWN_LIMIT;
+ drilldown->calc_types = 0;
+ GRN_RAW_STRING_INIT(drilldown->calc_target_name);
+ GRN_RAW_STRING_INIT(drilldown->filter);
+ GRN_RAW_STRING_INIT(drilldown->table_name);
+ grn_columns_init(ctx, &(drilldown->columns));
+ drilldown->result.table = NULL;
+ drilldown->filtered_result = NULL;
+}
+
+static void
+grn_drilldown_data_fin(grn_ctx *ctx, grn_drilldown_data *drilldown)
+{
+ grn_table_group_result *result;
+
+ grn_columns_fin(ctx, &(drilldown->columns));
+
+ if (drilldown->filtered_result) {
+ grn_obj_close(ctx, drilldown->filtered_result);
+ }
+
+ result = &(drilldown->result);
+ if (result->table) {
+ if (result->calc_target) {
+ grn_obj_unlink(ctx, result->calc_target);
+ }
+ if (result->table) {
+ grn_obj_close(ctx, result->table);
+ }
+ }
+}
+
+static void
+grn_drilldown_data_fill(grn_ctx *ctx,
+ grn_drilldown_data *drilldown,
+ grn_obj *keys,
+ grn_obj *sort_keys,
+ grn_obj *output_columns,
+ grn_obj *offset,
+ grn_obj *limit,
+ grn_obj *calc_types,
+ grn_obj *calc_target,
+ grn_obj *filter,
+ grn_obj *table)
+{
+ GRN_RAW_STRING_FILL(drilldown->keys, keys);
+
+ GRN_RAW_STRING_FILL(drilldown->sort_keys, sort_keys);
+
+ GRN_RAW_STRING_FILL(drilldown->output_columns, output_columns);
+ if (drilldown->output_columns.length == 0) {
+ drilldown->output_columns.value = DEFAULT_DRILLDOWN_OUTPUT_COLUMNS;
+ drilldown->output_columns.length = strlen(DEFAULT_DRILLDOWN_OUTPUT_COLUMNS);
+ }
+
+ if (offset && GRN_TEXT_LEN(offset)) {
+ drilldown->offset =
+ grn_atoi(GRN_TEXT_VALUE(offset), GRN_BULK_CURR(offset), NULL);
+ } else {
+ drilldown->offset = 0;
+ }
+
+ if (limit && GRN_TEXT_LEN(limit)) {
+ drilldown->limit =
+ grn_atoi(GRN_TEXT_VALUE(limit), GRN_BULK_CURR(limit), NULL);
+ } else {
+ drilldown->limit = DEFAULT_DRILLDOWN_LIMIT;
+ }
+
+ if (calc_types && GRN_TEXT_LEN(calc_types)) {
+ drilldown->calc_types =
+ grn_parse_table_group_calc_types(ctx,
+ GRN_TEXT_VALUE(calc_types),
+ GRN_TEXT_LEN(calc_types));
+ } else {
+ drilldown->calc_types = 0;
+ }
+
+ GRN_RAW_STRING_FILL(drilldown->calc_target_name, calc_target);
+
+ GRN_RAW_STRING_FILL(drilldown->filter, filter);
+
+ GRN_RAW_STRING_FILL(drilldown->table_name, table);
+}
+
+grn_expr_flags
+grn_proc_expr_query_flags_parse(grn_ctx *ctx,
+ const char *query_flags,
+ size_t query_flags_size,
+ const char *error_message_tag)
+{
+ grn_expr_flags flags = 0;
+ const char *query_flags_end = query_flags + query_flags_size;
+
+ while (query_flags < query_flags_end) {
+ if (*query_flags == '|' || *query_flags == ' ') {
+ query_flags += 1;
+ continue;
+ }
+
+#define CHECK_EXPR_FLAG(name) \
+ if (((query_flags_end - query_flags) >= (sizeof(#name) - 1)) && \
+ (memcmp(query_flags, #name, sizeof(#name) - 1) == 0) && \
+ (((query_flags_end - query_flags) == (sizeof(#name) - 1)) || \
+ (query_flags[sizeof(#name) - 1] == '|') || \
+ (query_flags[sizeof(#name) - 1] == ' '))) { \
+ flags |= GRN_EXPR_ ## name; \
+ query_flags += sizeof(#name) - 1; \
+ continue; \
+ }
+
+ CHECK_EXPR_FLAG(ALLOW_PRAGMA);
+ CHECK_EXPR_FLAG(ALLOW_COLUMN);
+ CHECK_EXPR_FLAG(ALLOW_UPDATE);
+ CHECK_EXPR_FLAG(ALLOW_LEADING_NOT);
+ CHECK_EXPR_FLAG(QUERY_NO_SYNTAX_ERROR);
+
+#define GRN_EXPR_NONE 0
+ CHECK_EXPR_FLAG(NONE);
+#undef GNR_EXPR_NONE
+
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "%s invalid query flag: <%.*s>",
+ error_message_tag,
+ (int)(query_flags_end - query_flags),
+ query_flags);
+ return 0;
+#undef CHECK_EXPR_FLAG
+ }
+
+ return flags;
+}
+
+static void
+grn_select_expression_set_condition(grn_ctx *ctx,
+ grn_obj *expression,
+ grn_obj *condition)
+{
+ grn_obj *condition_ptr;
+
+ if (!expression) {
+ return;
+ }
+
+ condition_ptr =
+ grn_expr_get_or_add_var(ctx, expression,
+ GRN_SELECT_INTERNAL_VAR_CONDITION,
+ GRN_SELECT_INTERNAL_VAR_CONDITION_LEN);
+ GRN_PTR_INIT(condition_ptr, 0, GRN_DB_OBJECT);
+ GRN_PTR_SET(ctx, condition_ptr, condition);
+}
+
+grn_bool
+grn_proc_select_format_init(grn_ctx *ctx,
+ grn_obj_format *format,
+ grn_obj *result_set,
+ int n_hits,
+ int offset,
+ int limit,
+ const char *columns,
+ int columns_len,
+ grn_obj *condition)
+{
+ grn_rc rc;
+
+ GRN_OBJ_FORMAT_INIT(format, n_hits, offset, limit, offset);
+ format->flags =
+ GRN_OBJ_FORMAT_WITH_COLUMN_NAMES|
+ GRN_OBJ_FORMAT_XML_ELEMENT_RESULTSET;
+ rc = grn_output_format_set_columns(ctx,
+ format,
+ result_set,
+ columns,
+ columns_len);
+ if (rc != GRN_SUCCESS) {
+ GRN_OBJ_FORMAT_FIN(ctx, format);
+ return GRN_FALSE;
+ }
+
+ grn_select_expression_set_condition(ctx, format->expression, condition);
+
+ return ctx->rc == GRN_SUCCESS;
+}
+
+grn_bool
+grn_proc_select_format_fin(grn_ctx *ctx, grn_obj_format *format)
+{
+ GRN_OBJ_FORMAT_FIN(ctx, format);
+
+ return ctx->rc == GRN_SUCCESS;
+}
+
+grn_bool
+grn_proc_select_output_columns_open(grn_ctx *ctx,
+ grn_obj_format *format,
+ grn_obj *res,
+ int n_hits,
+ int offset,
+ int limit,
+ const char *columns,
+ int columns_len,
+ grn_obj *condition,
+ uint32_t n_additional_elements)
+{
+ grn_bool succeeded;
+
+ if (!grn_proc_select_format_init(ctx,
+ format,
+ res,
+ n_hits,
+ offset,
+ limit,
+ columns,
+ columns_len,
+ condition)) {
+ return GRN_FALSE;
+ }
+
+ GRN_OUTPUT_RESULT_SET_OPEN(res, format, n_additional_elements);
+ succeeded = (ctx->rc == GRN_SUCCESS);
+ if (!succeeded) {
+ GRN_OUTPUT_RESULT_SET_CLOSE(res, format);
+ }
+
+ return succeeded;
+}
+
+grn_bool
+grn_proc_select_output_columns_close(grn_ctx *ctx,
+ grn_obj_format *format,
+ grn_obj *result_set)
+{
+ GRN_OUTPUT_RESULT_SET_CLOSE(result_set, format);
+
+ return grn_proc_select_format_fin(ctx, format);
+}
+
+grn_bool
+grn_proc_select_output_columns(grn_ctx *ctx,
+ grn_obj *res,
+ int n_hits,
+ int offset,
+ int limit,
+ const char *columns,
+ int columns_len,
+ grn_obj *condition)
+{
+ grn_obj_format format;
+ uint32_t n_additional_elements = 0;
+
+ if (!grn_proc_select_output_columns_open(ctx,
+ &format,
+ res,
+ n_hits,
+ offset,
+ limit,
+ columns,
+ columns_len,
+ condition,
+ n_additional_elements)) {
+ return GRN_FALSE;
+ }
+
+ return grn_proc_select_output_columns_close(ctx, &format, res);
+}
+
+static grn_obj *
+grn_select_create_all_selected_result_table(grn_ctx *ctx,
+ grn_obj *table)
+{
+ grn_obj *result;
+ grn_posting posting;
+
+ result = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ table, NULL);
+ if (!result) {
+ return NULL;
+ }
+
+ memset(&posting, 0, sizeof(grn_posting));
+ GRN_TABLE_EACH_BEGIN(ctx, table, cursor, id) {
+ posting.rid = id;
+ grn_ii_posting_add(ctx,
+ &posting,
+ (grn_hash *)(result),
+ GRN_OP_OR);
+ } GRN_TABLE_EACH_END(ctx, cursor);
+
+ return result;
+}
+
+static grn_obj *
+grn_select_create_no_sort_keys_sorted_table(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_obj *table)
+{
+ grn_obj *sorted;
+ grn_table_cursor *cursor;
+
+ sorted = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_OBJ_TABLE_NO_KEY,
+ NULL,
+ table);
+
+ if (!sorted) {
+ return NULL;
+ }
+
+ cursor = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0,
+ data->offset,
+ data->limit,
+ GRN_CURSOR_ASCENDING);
+ if (cursor) {
+ grn_id id;
+ while ((id = grn_table_cursor_next(ctx, cursor))) {
+ grn_id *value;
+ if (grn_array_add(ctx, (grn_array *)sorted, (void **)&value)) {
+ *value = id;
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+ }
+
+ return sorted;
+}
+
+
+static void
+grn_select_apply_columns(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_obj *table,
+ grn_hash *columns)
+{
+ grn_hash_cursor *columns_cursor;
+
+ columns_cursor = grn_hash_cursor_open(ctx, columns,
+ NULL, 0, NULL, 0, 0, -1, 0);
+ if (!columns_cursor) {
+ return;
+ }
+
+ while (grn_hash_cursor_next(ctx, columns_cursor) != GRN_ID_NIL) {
+ grn_column_data *column_data;
+ grn_obj *column;
+ grn_obj *expression;
+ grn_obj *record;
+
+ grn_hash_cursor_get_value(ctx, columns_cursor, (void **)&column_data);
+
+ column = grn_column_create(ctx,
+ table,
+ column_data->label.value,
+ column_data->label.length,
+ NULL,
+ column_data->flags,
+ column_data->type);
+ if (!column) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][column][%s][%.*s] failed to create column: %s",
+ grn_column_stage_name(column_data->stage),
+ (int)(column_data->label.length),
+ column_data->label.value,
+ ctx->errbuf);
+ break;
+ }
+
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, table, expression, record);
+ if (!expression) {
+ grn_obj_close(ctx, column);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][column][%s][%.*s] "
+ "failed to create expression to compute value: %s",
+ grn_column_stage_name(column_data->stage),
+ (int)(column_data->label.length),
+ column_data->label.value,
+ ctx->errbuf);
+ break;
+ }
+ grn_expr_parse(ctx,
+ expression,
+ column_data->value.value,
+ column_data->value.length,
+ NULL,
+ GRN_OP_MATCH,
+ GRN_OP_AND,
+ GRN_EXPR_SYNTAX_SCRIPT);
+ if (ctx->rc != GRN_SUCCESS) {
+ grn_obj_close(ctx, expression);
+ grn_obj_close(ctx, column);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][column][%s][%.*s] "
+ "failed to parse value: <%.*s>: %s",
+ grn_column_stage_name(column_data->stage),
+ (int)(column_data->label.length),
+ column_data->label.value,
+ (int)(column_data->value.length),
+ column_data->value.value,
+ ctx->errbuf);
+ break;
+ }
+ grn_select_expression_set_condition(ctx,
+ expression,
+ data->filter.condition.expression);
+
+ if (column_data->window.sort_keys.length > 0 ||
+ column_data->window.group_keys.length > 0) {
+ grn_window_definition definition;
+ grn_rc rc;
+
+ if (column_data->window.sort_keys.length > 0) {
+ int n_sort_keys;
+ definition.sort_keys =
+ grn_table_sort_key_from_str(ctx,
+ column_data->window.sort_keys.value,
+ column_data->window.sort_keys.length,
+ table, &n_sort_keys);
+ definition.n_sort_keys = n_sort_keys;
+ if (!definition.sort_keys) {
+ grn_obj_close(ctx, expression);
+ grn_obj_close(ctx, column);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][column][%s][%.*s] "
+ "failed to parse sort keys: %s",
+ grn_column_stage_name(column_data->stage),
+ (int)(column_data->label.length),
+ column_data->label.value,
+ ctx->errbuf);
+ break;
+ }
+ } else {
+ definition.sort_keys = NULL;
+ definition.n_sort_keys = 0;
+ }
+
+ if (column_data->window.group_keys.length > 0) {
+ int n_group_keys;
+ definition.group_keys =
+ grn_table_sort_key_from_str(ctx,
+ column_data->window.group_keys.value,
+ column_data->window.group_keys.length,
+ table, &n_group_keys);
+ definition.n_group_keys = n_group_keys;
+ if (!definition.group_keys) {
+ grn_obj_close(ctx, expression);
+ grn_obj_close(ctx, column);
+ if (definition.sort_keys) {
+ grn_table_sort_key_close(ctx,
+ definition.sort_keys,
+ definition.n_sort_keys);
+ }
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][column][%s][%.*s] "
+ "failed to parse group keys: %s",
+ grn_column_stage_name(column_data->stage),
+ (int)(column_data->label.length),
+ column_data->label.value,
+ ctx->errbuf);
+ break;
+ }
+ } else {
+ definition.group_keys = NULL;
+ definition.n_group_keys = 0;
+ }
+
+ rc = grn_table_apply_window_function(ctx,
+ table,
+ column,
+ &definition,
+ expression);
+ if (definition.sort_keys) {
+ grn_table_sort_key_close(ctx,
+ definition.sort_keys,
+ definition.n_sort_keys);
+ }
+ if (definition.group_keys) {
+ grn_table_sort_key_close(ctx,
+ definition.group_keys,
+ definition.n_group_keys);
+ }
+ if (rc != GRN_SUCCESS) {
+ grn_obj_close(ctx, expression);
+ grn_obj_close(ctx, column);
+ break;
+ }
+ } else {
+ grn_rc rc;
+ rc = grn_table_apply_expr(ctx, table, column, expression);
+ if (rc != GRN_SUCCESS) {
+ grn_obj_close(ctx, expression);
+ grn_obj_close(ctx, column);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][column][%s][%.*s] "
+ "failed to apply expression to generate column values: "
+ "%s",
+ grn_column_stage_name(column_data->stage),
+ (int)(column_data->label.length),
+ column_data->label.value,
+ ctx->errbuf);
+ break;
+ }
+ }
+
+ grn_obj_close(ctx, expression);
+
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "columns[%.*s](%d)",
+ (int)(column_data->label.length),
+ column_data->label.value,
+ grn_table_size(ctx, table));
+ }
+
+ grn_hash_cursor_close(ctx, columns_cursor);
+}
+
+static grn_bool
+grn_select_apply_initial_columns(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ if (!data->columns.initial) {
+ return GRN_TRUE;
+ }
+
+ data->tables.initial =
+ grn_select_create_all_selected_result_table(ctx, data->tables.target);
+ if (!data->tables.initial) {
+ return GRN_FALSE;
+ }
+
+ grn_select_apply_columns(ctx,
+ data,
+ data->tables.initial,
+ data->columns.initial);
+
+ return ctx->rc == GRN_SUCCESS;
+}
+
+static grn_bool
+grn_select_filter(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ if (!grn_filter_data_execute(ctx,
+ &(data->filter),
+ data->tables.initial,
+ "[select]")) {
+ return GRN_FALSE;
+ }
+
+ data->tables.result = data->filter.filtered;
+ if (!data->tables.result) {
+ data->tables.result = data->tables.initial;
+ }
+
+ {
+ grn_expr *expression;
+ expression = (grn_expr *)(data->filter.condition.expression);
+ if (expression) {
+ data->cacheable *= expression->cacheable;
+ data->taintable += expression->taintable;
+ }
+ }
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_select_apply_filtered_columns(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ if (!data->columns.filtered) {
+ return GRN_TRUE;
+ }
+
+ if (data->tables.result == data->tables.initial) {
+ data->tables.result =
+ grn_select_create_all_selected_result_table(ctx, data->tables.initial);
+ if (!data->tables.result) {
+ return GRN_FALSE;
+ }
+ }
+
+ grn_select_apply_columns(ctx,
+ data,
+ data->tables.result,
+ data->columns.filtered);
+
+ return ctx->rc == GRN_SUCCESS;
+}
+
+static int
+grn_select_apply_adjuster_execute_ensure_factor(grn_ctx *ctx,
+ grn_obj *factor_object)
+{
+ if (!factor_object) {
+ return 1;
+ } else if (factor_object->header.domain == GRN_DB_INT32) {
+ return GRN_INT32_VALUE(factor_object);
+ } else {
+ grn_rc rc;
+ grn_obj int32_object;
+ int factor;
+ GRN_INT32_INIT(&int32_object, 0);
+ rc = grn_obj_cast(ctx, factor_object, &int32_object, GRN_FALSE);
+ if (rc == GRN_SUCCESS) {
+ factor = GRN_INT32_VALUE(&int32_object);
+ } else {
+ /* TODO: Log or return error? */
+ factor = 1;
+ }
+ GRN_OBJ_FIN(ctx, &int32_object);
+ return factor;
+ }
+}
+
+static void
+grn_select_apply_adjuster_execute_adjust(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *column,
+ grn_obj *value,
+ grn_obj *factor)
+{
+ grn_obj *index;
+ unsigned int n_indexes;
+ int factor_value;
+
+ n_indexes = grn_column_index(ctx, column, GRN_OP_MATCH, &index, 1, NULL);
+ if (n_indexes == 0) {
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int column_name_size;
+ column_name_size = grn_obj_name(ctx, column,
+ column_name, GRN_TABLE_MAX_KEY_SIZE);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "adjuster requires index column for the target column: "
+ "<%.*s>",
+ column_name_size,
+ column_name);
+ return;
+ }
+
+ factor_value = grn_select_apply_adjuster_execute_ensure_factor(ctx, factor);
+
+ {
+ grn_search_optarg options;
+ memset(&options, 0, sizeof(grn_search_optarg));
+
+ options.mode = GRN_OP_EXACT;
+ options.similarity_threshold = 0;
+ options.max_interval = 0;
+ options.weight_vector = NULL;
+ options.vector_size = factor_value;
+ options.proc = NULL;
+ options.max_size = 0;
+ options.scorer = NULL;
+
+ grn_obj_search(ctx, index, value, table, GRN_OP_ADJUST, &options);
+ }
+}
+
+static void
+grn_select_apply_adjuster_execute(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *adjuster)
+{
+ grn_expr *expr = (grn_expr *)adjuster;
+ grn_expr_code *code, *code_end;
+
+ code = expr->codes;
+ code_end = expr->codes + expr->codes_curr;
+ while (code < code_end) {
+ grn_obj *column, *value, *factor;
+
+ if (code->op == GRN_OP_PLUS) {
+ code++;
+ continue;
+ }
+
+ column = code->value;
+ code++;
+ value = code->value;
+ code++;
+ code++; /* op == GRN_OP_MATCH */
+ if ((code_end - code) >= 2 && code[1].op == GRN_OP_STAR) {
+ factor = code->value;
+ code++;
+ code++; /* op == GRN_OP_STAR */
+ } else {
+ factor = NULL;
+ }
+ grn_select_apply_adjuster_execute_adjust(ctx, table, column, value, factor);
+ }
+}
+
+static grn_bool
+grn_select_apply_adjuster(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ grn_obj *adjuster;
+ grn_obj *record;
+ grn_rc rc;
+
+ if (data->adjuster.length == 0) {
+ return GRN_TRUE;
+ }
+
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, data->tables.target, adjuster, record);
+ if (!adjuster) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][adjuster] "
+ "failed to create expression: %s",
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+
+ rc = grn_expr_parse(ctx, adjuster,
+ data->adjuster.value,
+ data->adjuster.length,
+ NULL,
+ GRN_OP_MATCH, GRN_OP_ADJUST,
+ GRN_EXPR_SYNTAX_ADJUSTER);
+ if (rc != GRN_SUCCESS) {
+ grn_obj_unlink(ctx, adjuster);
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[select][adjuster] "
+ "failed to parse: %s",
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+
+ data->cacheable *= ((grn_expr *)adjuster)->cacheable;
+ data->taintable += ((grn_expr *)adjuster)->taintable;
+ grn_select_apply_adjuster_execute(ctx, data->tables.result, adjuster);
+ grn_obj_unlink(ctx, adjuster);
+
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "adjust(%d)", grn_table_size(ctx, data->tables.result));
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_select_apply_scorer(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ grn_obj *scorer;
+ grn_obj *record;
+ grn_rc rc = GRN_SUCCESS;
+
+ if (data->scorer.length == 0) {
+ return GRN_TRUE;
+ }
+
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, data->tables.result, scorer, record);
+ if (!scorer) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][scorer] "
+ "failed to create expression: %s",
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+
+ rc = grn_expr_parse(ctx,
+ scorer,
+ data->scorer.value,
+ data->scorer.length,
+ NULL,
+ GRN_OP_MATCH,
+ GRN_OP_AND,
+ GRN_EXPR_SYNTAX_SCRIPT|GRN_EXPR_ALLOW_UPDATE);
+ if (rc != GRN_SUCCESS) {
+ grn_obj_unlink(ctx, scorer);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][scorer] "
+ "failed to parse: %s",
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+
+ data->cacheable *= ((grn_expr *)scorer)->cacheable;
+ data->taintable += ((grn_expr *)scorer)->taintable;
+ GRN_TABLE_EACH_BEGIN(ctx, data->tables.result, cursor, id) {
+ GRN_RECORD_SET(ctx, record, id);
+ grn_expr_exec(ctx, scorer, 0);
+ if (ctx->rc) {
+ rc = ctx->rc;
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[select][scorer] "
+ "failed to execute: <%.*s>: %s",
+ (int)(data->scorer.length),
+ data->scorer.value,
+ ctx->errbuf);
+ break;
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ grn_obj_unlink(ctx, scorer);
+
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "score(%d)", grn_table_size(ctx, data->tables.result));
+
+ return rc == GRN_SUCCESS;
+}
+
+static grn_bool
+grn_select_sort(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ grn_table_sort_key *keys;
+ uint32_t n_keys;
+
+ if (data->sort_keys.length == 0) {
+ return GRN_TRUE;
+ }
+
+ keys = grn_table_sort_key_from_str(ctx,
+ data->sort_keys.value,
+ data->sort_keys.length,
+ data->tables.result,
+ &n_keys);
+ if (!keys) {
+ if (ctx->rc == GRN_SUCCESS) {
+ return GRN_TRUE;
+ } else {
+ GRN_PLUGIN_ERROR(ctx,
+ ctx->rc,
+ "[select][sort] "
+ "failed to parse: <%.*s>: %s",
+ (int)(data->sort_keys.length),
+ data->sort_keys.value,
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+ }
+
+ data->tables.sorted = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_OBJ_TABLE_NO_KEY,
+ NULL,
+ data->tables.result);
+ if (!data->tables.sorted) {
+ GRN_PLUGIN_ERROR(ctx,
+ ctx->rc,
+ "[select][sort] "
+ "failed to create table to store sorted record: "
+ "<%.*s>: %s",
+ (int)(data->sort_keys.length),
+ data->sort_keys.value,
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+
+ grn_table_sort(ctx,
+ data->tables.result,
+ data->offset,
+ data->limit,
+ data->tables.sorted,
+ keys,
+ n_keys);
+
+ grn_table_sort_key_close(ctx, keys, n_keys);
+
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "sort(%d)", data->limit);
+
+ return ctx->rc == GRN_SUCCESS;
+}
+
+static grn_bool
+grn_select_apply_output_columns(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ if (!data->columns.output) {
+ return GRN_TRUE;
+ }
+
+ if (!data->tables.sorted) {
+ data->tables.sorted =
+ grn_select_create_no_sort_keys_sorted_table(ctx,
+ data,
+ data->tables.result);
+ if (!data->tables.sorted) {
+ return GRN_FALSE;
+ }
+ }
+
+ grn_select_apply_columns(ctx,
+ data,
+ data->tables.sorted,
+ data->columns.output);
+
+ return ctx->rc == GRN_SUCCESS;
+}
+
+static grn_bool
+grn_select_output_match_open(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_obj_format *format,
+ uint32_t n_additional_elements)
+{
+ grn_bool succeeded = GRN_TRUE;
+ int offset;
+ grn_obj *output_table;
+
+ if (data->tables.sorted) {
+ offset = 0;
+ output_table = data->tables.sorted;
+ } else {
+ offset = data->offset;
+ output_table = data->tables.result;
+ }
+ succeeded =
+ grn_proc_select_output_columns_open(ctx,
+ format,
+ output_table,
+ grn_table_size(ctx, data->tables.result),
+ offset,
+ data->limit,
+ data->output_columns.value,
+ data->output_columns.length,
+ data->filter.condition.expression,
+ n_additional_elements);
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "output(%d)", data->limit);
+
+ return succeeded;
+}
+
+static grn_bool
+grn_select_output_match_close(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_obj_format *format)
+{
+ grn_obj *output_table;
+
+ if (data->tables.sorted) {
+ output_table = data->tables.sorted;
+ } else {
+ output_table = data->tables.result;
+ }
+
+ return grn_proc_select_output_columns_close(ctx, format, output_table);
+}
+
+static grn_bool
+grn_select_output_match(grn_ctx *ctx, grn_select_data *data)
+{
+ grn_obj_format format;
+ uint32_t n_additional_elements = 0;
+
+ if (!grn_select_output_match_open(ctx, data, &format, n_additional_elements)) {
+ return GRN_FALSE;
+ }
+
+ return grn_select_output_match_close(ctx, data, &format);
+}
+
+static grn_bool
+grn_select_slice_execute(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_obj *table,
+ grn_slice_data *slice)
+{
+ char tag[GRN_TABLE_MAX_KEY_SIZE];
+ grn_filter_data *filter;
+
+ grn_snprintf(tag, GRN_TABLE_MAX_KEY_SIZE, GRN_TABLE_MAX_KEY_SIZE,
+ "[select][slices][%.*s]",
+ (int)(slice->label.length),
+ slice->label.value);
+ filter = &(slice->filter);
+ if (filter->query.length == 0 && filter->filter.length == 0) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "%s slice requires query or filter",
+ tag);
+ return GRN_FALSE;
+ }
+
+ if (!grn_filter_data_execute(ctx, filter, table, tag)) {
+ return GRN_FALSE;
+ }
+
+ slice->table = filter->filtered;
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_select_slices_execute(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_obj *table,
+ grn_hash *slices)
+{
+ grn_bool succeeded = GRN_TRUE;
+
+ GRN_HASH_EACH_BEGIN(ctx, slices, cursor, id) {
+ grn_slice_data *slice;
+
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&slice);
+ if (!grn_select_slice_execute(ctx, data, table, slice)) {
+ succeeded = GRN_FALSE;
+ break;
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
+
+ return succeeded;
+}
+
+static grn_bool
+grn_select_prepare_slices(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ if (!data->slices) {
+ return GRN_TRUE;
+ }
+
+ if (!grn_select_slices_execute(ctx, data, data->tables.result, data->slices)) {
+ return GRN_FALSE;
+ }
+
+ data->output.n_elements += 1;
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_select_output_slices(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ grn_bool succeeded = GRN_TRUE;
+ unsigned int n_available_results = 0;
+
+ if (!data->slices) {
+ return GRN_TRUE;
+ }
+
+ data->output.formatter->slices_label(ctx, data);
+
+ GRN_HASH_EACH_BEGIN(ctx, data->slices, cursor, id) {
+ grn_slice_data *slice;
+
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&slice);
+ if (slice->table) {
+ n_available_results++;
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
+
+ data->output.formatter->slices_open(ctx, data, n_available_results);
+
+ GRN_HASH_EACH_BEGIN(ctx, data->slices, cursor, id) {
+ grn_slice_data *slice;
+ uint32_t n_hits;
+ int offset;
+ int limit;
+
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&slice);
+ if (!slice->table) {
+ continue;
+ }
+
+ n_hits = grn_table_size(ctx, slice->table);
+
+ offset = slice->offset;
+ limit = slice->limit;
+ grn_normalize_offset_and_limit(ctx, n_hits, &offset, &limit);
+
+ if (slice->sort_keys.length > 0) {
+ grn_table_sort_key *sort_keys;
+ uint32_t n_sort_keys;
+ sort_keys = grn_table_sort_key_from_str(ctx,
+ slice->sort_keys.value,
+ slice->sort_keys.length,
+ slice->table, &n_sort_keys);
+ if (sort_keys) {
+ grn_obj *sorted;
+ sorted = grn_table_create(ctx, NULL, 0, NULL, GRN_OBJ_TABLE_NO_KEY,
+ NULL, slice->table);
+ if (sorted) {
+ grn_table_sort(ctx, slice->table, offset, limit,
+ sorted, sort_keys, n_sort_keys);
+ data->output.formatter->slice_label(ctx, data, slice);
+ if (!grn_proc_select_output_columns(ctx,
+ sorted,
+ n_hits,
+ 0,
+ limit,
+ slice->output_columns.value,
+ slice->output_columns.length,
+ slice->filter.condition.expression)) {
+ succeeded = GRN_FALSE;
+ }
+ grn_obj_unlink(ctx, sorted);
+ }
+ grn_table_sort_key_close(ctx, sort_keys, n_sort_keys);
+ } else {
+ succeeded = GRN_FALSE;
+ }
+ } else {
+ data->output.formatter->slice_label(ctx, data, slice);
+ if (!grn_proc_select_output_columns(ctx,
+ slice->table,
+ n_hits,
+ offset,
+ limit,
+ slice->output_columns.value,
+ slice->output_columns.length,
+ slice->filter.condition.expression)) {
+ succeeded = GRN_FALSE;
+ }
+ }
+
+ if (!succeeded) {
+ break;
+ }
+
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "slice(%d)[%.*s]",
+ n_hits,
+ (int)(slice->label.length),
+ slice->label.value);
+ } GRN_HASH_EACH_END(ctx, cursor);
+
+ data->output.formatter->slices_close(ctx, data);
+
+ return succeeded;
+}
+
+static grn_bool
+grn_select_drilldown_execute(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_obj *table,
+ grn_hash *drilldowns,
+ grn_id id)
+{
+ grn_table_sort_key *keys = NULL;
+ unsigned int n_keys = 0;
+ grn_obj *target_table = table;
+ grn_drilldown_data *drilldown;
+ grn_table_group_result *result;
+
+ drilldown =
+ (grn_drilldown_data *)grn_hash_get_value_(ctx, drilldowns, id, NULL);
+ result = &(drilldown->result);
+
+ result->limit = 1;
+ result->flags = GRN_TABLE_GROUP_CALC_COUNT;
+ result->op = 0;
+ result->max_n_subrecs = 0;
+ result->key_begin = 0;
+ result->key_end = 0;
+ if (result->calc_target) {
+ grn_obj_unlink(ctx, result->calc_target);
+ }
+ result->calc_target = NULL;
+
+ if (drilldown->table_name.length > 0) {
+ grn_id dependent_id;
+ dependent_id = grn_hash_get(ctx,
+ drilldowns,
+ drilldown->table_name.value,
+ drilldown->table_name.length,
+ NULL);
+ if (dependent_id == GRN_ID_NIL) {
+ if (data->slices) {
+ grn_slice_data *slice;
+ dependent_id = grn_hash_get(ctx,
+ data->slices,
+ drilldown->table_name.value,
+ drilldown->table_name.length,
+ NULL);
+ if (dependent_id) {
+ slice =
+ (grn_slice_data *)grn_hash_get_value_(ctx, data->slices,
+ dependent_id, NULL);
+ target_table = slice->table;
+ }
+ }
+ if (dependent_id == GRN_ID_NIL) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[select][drilldowns][%.*s][table] "
+ "nonexistent label: <%.*s>",
+ (int)(drilldown->label.length),
+ drilldown->label.value,
+ (int)(drilldown->table_name.length),
+ drilldown->table_name.value);
+ return GRN_FALSE;
+ }
+ } else {
+ grn_drilldown_data *dependent_drilldown;
+ grn_table_group_result *dependent_result;
+
+ dependent_drilldown =
+ (grn_drilldown_data *)grn_hash_get_value_(ctx,
+ drilldowns,
+ dependent_id,
+ NULL);
+ dependent_result = &(dependent_drilldown->result);
+ target_table = dependent_result->table;
+ }
+ }
+
+ if (drilldown->parsed_keys) {
+ result->key_end = drilldown->n_parsed_keys;
+ } else if (drilldown->keys.length > 0) {
+ keys = grn_table_sort_key_from_str(ctx,
+ drilldown->keys.value,
+ drilldown->keys.length,
+ target_table, &n_keys);
+ if (!keys) {
+ GRN_PLUGIN_CLEAR_ERROR(ctx);
+ return GRN_FALSE;
+ }
+
+ result->key_end = n_keys - 1;
+ if (n_keys > 1) {
+ result->max_n_subrecs = 1;
+ }
+ }
+
+ if (drilldown->calc_target_name.length > 0) {
+ result->calc_target = grn_obj_column(ctx, target_table,
+ drilldown->calc_target_name.value,
+ drilldown->calc_target_name.length);
+ }
+ if (result->calc_target) {
+ result->flags |= drilldown->calc_types;
+ }
+
+ if (drilldown->parsed_keys) {
+ grn_table_group(ctx,
+ target_table,
+ drilldown->parsed_keys,
+ drilldown->n_parsed_keys,
+ result,
+ 1);
+ } else {
+ grn_table_group(ctx, target_table, keys, n_keys, result, 1);
+ }
+
+ if (keys) {
+ grn_table_sort_key_close(ctx, keys, n_keys);
+ }
+
+ if (!result->table) {
+ return GRN_FALSE;
+ }
+
+ if (drilldown->columns.initial) {
+ grn_select_apply_columns(ctx,
+ data,
+ result->table,
+ drilldown->columns.initial);
+ }
+
+ if (drilldown->filter.length > 0) {
+ grn_obj *expression;
+ grn_obj *record;
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, result->table, expression, record);
+ if (!expression) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][drilldowns]%s%.*s%s[filter] "
+ "failed to create expression for filter: %s",
+ drilldown->label.length > 0 ? "[" : "",
+ (int)(drilldown->label.length),
+ drilldown->label.value,
+ drilldown->label.length > 0 ? "]" : "",
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+ grn_expr_parse(ctx,
+ expression,
+ drilldown->filter.value,
+ drilldown->filter.length,
+ NULL,
+ GRN_OP_MATCH,
+ GRN_OP_AND,
+ GRN_EXPR_SYNTAX_SCRIPT);
+ if (ctx->rc != GRN_SUCCESS) {
+ grn_obj_close(ctx, expression);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][drilldowns]%s%.*s%s[filter] "
+ "failed to parse filter: <%.*s>: %s",
+ drilldown->label.length > 0 ? "[" : "",
+ (int)(drilldown->label.length),
+ drilldown->label.value,
+ drilldown->label.length > 0 ? "]" : "",
+ (int)(drilldown->filter.length),
+ drilldown->filter.value,
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+ drilldown->filtered_result = grn_table_select(ctx,
+ result->table,
+ expression,
+ NULL,
+ GRN_OP_OR);
+ if (ctx->rc != GRN_SUCCESS) {
+ grn_obj_close(ctx, expression);
+ if (drilldown->filtered_result) {
+ grn_obj_close(ctx, drilldown->filtered_result);
+ drilldown->filtered_result = NULL;
+ }
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][drilldowns]%s%.*s%s[filter] "
+ "failed to execute filter: <%.*s>: %s",
+ drilldown->label.length > 0 ? "[" : "",
+ (int)(drilldown->label.length),
+ drilldown->label.value,
+ drilldown->label.length > 0 ? "]" : "",
+ (int)(drilldown->filter.length),
+ drilldown->filter.value,
+ ctx->errbuf);
+ return GRN_FALSE;
+ }
+ grn_obj_close(ctx, expression);
+ }
+
+ {
+ unsigned int n_hits;
+
+ if (drilldown->filtered_result) {
+ n_hits = grn_table_size(ctx, drilldown->filtered_result);
+ } else {
+ n_hits = grn_table_size(ctx, result->table);
+ }
+ if (data->drilldown.keys.length == 0) {
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "drilldowns[%.*s](%u)",
+ (int)(drilldown->label.length),
+ drilldown->label.value,
+ n_hits);
+ } else {
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "drilldown(%u)",
+ n_hits);
+ }
+ }
+
+ return GRN_TRUE;
+}
+
+typedef enum {
+ TSORT_STATUS_NOT_VISITED,
+ TSORT_STATUS_VISITING,
+ TSORT_STATUS_VISITED
+} tsort_status;
+
+static grn_bool
+drilldown_tsort_visit(grn_ctx *ctx,
+ grn_hash *drilldowns,
+ tsort_status *statuses,
+ grn_obj *ids,
+ grn_id id)
+{
+ grn_bool cycled = GRN_TRUE;
+ uint32_t index = id - 1;
+
+ switch (statuses[index]) {
+ case TSORT_STATUS_VISITING :
+ cycled = GRN_TRUE;
+ break;
+ case TSORT_STATUS_VISITED :
+ cycled = GRN_FALSE;
+ break;
+ case TSORT_STATUS_NOT_VISITED :
+ cycled = GRN_FALSE;
+ statuses[index] = TSORT_STATUS_VISITING;
+ {
+ grn_drilldown_data *drilldown;
+ drilldown =
+ (grn_drilldown_data *)grn_hash_get_value_(ctx, drilldowns, id, NULL);
+ if (drilldown->table_name.length > 0) {
+ grn_id dependent_id;
+ dependent_id = grn_hash_get(ctx, drilldowns,
+ drilldown->table_name.value,
+ drilldown->table_name.length,
+ NULL);
+ if (dependent_id != GRN_ID_NIL) {
+ cycled = drilldown_tsort_visit(ctx,
+ drilldowns,
+ statuses,
+ ids,
+ dependent_id);
+ if (cycled) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[select][drilldowns][%.*s][table] "
+ "cycled dependency: <%.*s>",
+ (int)(drilldown->label.length),
+ drilldown->label.value,
+ (int)(drilldown->table_name.length),
+ drilldown->table_name.value);
+ }
+ }
+ }
+ }
+ if (!cycled) {
+ statuses[index] = TSORT_STATUS_VISITED;
+ GRN_RECORD_PUT(ctx, ids, id);
+ }
+ break;
+ }
+
+ return cycled;
+}
+
+static grn_bool
+drilldown_tsort_body(grn_ctx *ctx,
+ grn_hash *drilldowns,
+ tsort_status *statuses,
+ grn_obj *ids)
+{
+ grn_bool succeeded = GRN_TRUE;
+
+ GRN_HASH_EACH_BEGIN(ctx, drilldowns, cursor, id) {
+ if (drilldown_tsort_visit(ctx, drilldowns, statuses, ids, id)) {
+ succeeded = GRN_FALSE;
+ break;
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
+
+ return succeeded;
+}
+
+static void
+drilldown_tsort_init(grn_ctx *ctx,
+ tsort_status *statuses,
+ size_t n_statuses)
+{
+ size_t i;
+ for (i = 0; i < n_statuses; i++) {
+ statuses[i] = TSORT_STATUS_NOT_VISITED;
+ }
+}
+
+static grn_bool
+drilldown_tsort(grn_ctx *ctx,
+ grn_hash *drilldowns,
+ grn_obj *ids)
+{
+ tsort_status *statuses;
+ size_t n_statuses;
+ grn_bool succeeded;
+
+ n_statuses = grn_hash_size(ctx, drilldowns);
+ statuses = GRN_PLUGIN_MALLOCN(ctx, tsort_status, n_statuses);
+ if (!statuses) {
+ return GRN_FALSE;
+ }
+
+ drilldown_tsort_init(ctx, statuses, n_statuses);
+ succeeded = drilldown_tsort_body(ctx, drilldowns, statuses, ids);
+ GRN_PLUGIN_FREE(ctx, statuses);
+ return succeeded;
+}
+
+static grn_bool
+grn_select_drilldowns_execute(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ grn_bool succeeded = GRN_TRUE;
+ grn_obj tsorted_ids;
+ size_t i;
+ size_t n_drilldowns;
+
+ GRN_RECORD_INIT(&tsorted_ids, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ if (!drilldown_tsort(ctx, data->drilldowns, &tsorted_ids)) {
+ succeeded = GRN_FALSE;
+ goto exit;
+ }
+
+ n_drilldowns = GRN_BULK_VSIZE(&tsorted_ids) / sizeof(grn_id);
+ for (i = 0; i < n_drilldowns; i++) {
+ grn_id id;
+
+ id = GRN_RECORD_VALUE_AT(&tsorted_ids, i);
+ if (!grn_select_drilldown_execute(ctx,
+ data,
+ data->tables.result,
+ data->drilldowns,
+ id)) {
+ if (ctx->rc != GRN_SUCCESS) {
+ succeeded = GRN_FALSE;
+ break;
+ }
+ }
+ }
+
+exit :
+ GRN_OBJ_FIN(ctx, &tsorted_ids);
+
+ return succeeded;
+}
+
+static grn_drilldown_data *
+grn_select_data_drilldowns_add(grn_ctx *ctx,
+ grn_select_data *data,
+ const char *label,
+ size_t label_len)
+{
+ grn_drilldown_data *drilldown = NULL;
+ int added;
+
+ if (!data->drilldowns) {
+ data->drilldowns = grn_hash_create(ctx,
+ NULL,
+ GRN_TABLE_MAX_KEY_SIZE,
+ sizeof(grn_drilldown_data),
+ GRN_OBJ_TABLE_HASH_KEY |
+ GRN_OBJ_KEY_VAR_SIZE |
+ GRN_HASH_TINY);
+ if (!data->drilldowns) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][drilldowns] "
+ "failed to allocate drilldowns data: %s",
+ ctx->errbuf);
+ return NULL;
+ }
+ }
+
+ grn_hash_add(ctx,
+ data->drilldowns,
+ label,
+ label_len,
+ (void **)&drilldown,
+ &added);
+ if (added) {
+ grn_drilldown_data_init(ctx, drilldown, label, label_len);
+ }
+
+ return drilldown;
+}
+
+static grn_bool
+grn_select_prepare_drilldowns(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ if (data->drilldown.keys.length > 0) {
+ data->drilldown.parsed_keys =
+ grn_table_sort_key_from_str(ctx,
+ data->drilldown.keys.value,
+ data->drilldown.keys.length,
+ data->tables.result,
+ &(data->drilldown.n_parsed_keys));
+ if (data->drilldown.parsed_keys) {
+ int i;
+ grn_obj buffer;
+
+ GRN_TEXT_INIT(&buffer, 0);
+ for (i = 0; i < data->drilldown.n_parsed_keys; i++) {
+ grn_drilldown_data *drilldown;
+
+ GRN_BULK_REWIND(&buffer);
+ grn_text_printf(ctx, &buffer, "drilldown%d", i);
+ drilldown = grn_select_data_drilldowns_add(ctx,
+ data,
+ GRN_TEXT_VALUE(&buffer),
+ GRN_TEXT_LEN(&buffer));
+ if (!drilldown) {
+ continue;
+ }
+
+ drilldown->parsed_keys = data->drilldown.parsed_keys + i;
+ drilldown->n_parsed_keys = 1;
+
+#define COPY(field) \
+ drilldown->field = data->drilldown.field
+
+ COPY(sort_keys);
+ COPY(output_columns);
+ COPY(offset);
+ COPY(limit);
+ COPY(calc_types);
+ COPY(calc_target_name);
+ COPY(filter);
+
+#undef COPY
+ }
+ }
+ }
+
+ if (!data->drilldowns) {
+ return GRN_TRUE;
+ }
+
+ if (!grn_select_drilldowns_execute(ctx, data)) {
+ return GRN_FALSE;
+ }
+
+ {
+ unsigned int n_available_results = 0;
+
+ GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) {
+ grn_drilldown_data *drilldown;
+ grn_table_group_result *result;
+
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&drilldown);
+ result = &(drilldown->result);
+ if (result->table) {
+ n_available_results++;
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
+
+ if (data->drilldown.keys.length > 0) {
+ data->output.n_elements += n_available_results;
+ } else {
+ if (n_available_results > 0) {
+ data->output.n_elements += 1;
+ }
+ }
+ }
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_select_output_drilldowns(grn_ctx *ctx,
+ grn_select_data *data)
+{
+ grn_bool succeeded = GRN_TRUE;
+ unsigned int n_available_results = 0;
+ grn_bool is_labeled;
+
+ if (!data->drilldowns) {
+ return GRN_TRUE;
+ }
+
+ data->output.formatter->drilldowns_label(ctx, data);
+
+ GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) {
+ grn_drilldown_data *drilldown;
+ grn_table_group_result *result;
+
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&drilldown);
+ result = &(drilldown->result);
+ if (result->table) {
+ n_available_results++;
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
+
+ is_labeled = (data->drilldown.keys.length == 0);
+
+ data->output.formatter->drilldowns_open(ctx, data, n_available_results);
+
+ GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) {
+ grn_drilldown_data *drilldown;
+ grn_table_group_result *result;
+ grn_obj *target_table;
+ uint32_t n_hits;
+ int offset;
+ int limit;
+
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&drilldown);
+ result = &(drilldown->result);
+
+ if (!result->table) {
+ continue;
+ }
+
+ if (drilldown->filtered_result) {
+ target_table = drilldown->filtered_result;
+ } else {
+ target_table = result->table;
+ }
+
+ n_hits = grn_table_size(ctx, target_table);
+
+ offset = drilldown->offset;
+ limit = drilldown->limit;
+ grn_normalize_offset_and_limit(ctx, n_hits, &offset, &limit);
+
+ if (drilldown->sort_keys.length > 0) {
+ grn_table_sort_key *sort_keys;
+ uint32_t n_sort_keys;
+ sort_keys = grn_table_sort_key_from_str(ctx,
+ drilldown->sort_keys.value,
+ drilldown->sort_keys.length,
+ target_table, &n_sort_keys);
+ if (sort_keys) {
+ grn_obj *sorted;
+ sorted = grn_table_create(ctx, NULL, 0, NULL, GRN_OBJ_TABLE_NO_KEY,
+ NULL, target_table);
+ if (sorted) {
+ grn_table_sort(ctx, target_table, offset, limit,
+ sorted, sort_keys, n_sort_keys);
+ data->output.formatter->drilldown_label(ctx, data, drilldown);
+ if (!grn_proc_select_output_columns(ctx,
+ sorted,
+ n_hits,
+ 0,
+ limit,
+ drilldown->output_columns.value,
+ drilldown->output_columns.length,
+ data->filter.condition.expression)) {
+ succeeded = GRN_FALSE;
+ }
+ grn_obj_unlink(ctx, sorted);
+ }
+ grn_table_sort_key_close(ctx, sort_keys, n_sort_keys);
+ } else {
+ succeeded = GRN_FALSE;
+ }
+ } else {
+ data->output.formatter->drilldown_label(ctx, data, drilldown);
+ if (!grn_proc_select_output_columns(ctx,
+ target_table,
+ n_hits,
+ offset,
+ limit,
+ drilldown->output_columns.value,
+ drilldown->output_columns.length,
+ data->filter.condition.expression)) {
+ succeeded = GRN_FALSE;
+ }
+ }
+
+ if (!succeeded) {
+ break;
+ }
+
+ if (is_labeled) {
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "output.drilldowns[%.*s](%d)",
+ (int)(drilldown->label.length),
+ drilldown->label.value,
+ n_hits);
+ } else {
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "output.drilldown(%d)", n_hits);
+ }
+ } GRN_HASH_EACH_END(ctx, cursor);
+
+ data->output.formatter->drilldowns_close(ctx, data);
+
+ return succeeded;
+}
+
+static grn_bool
+grn_select_output(grn_ctx *ctx, grn_select_data *data)
+{
+ grn_bool succeeded = GRN_TRUE;
+
+ if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+ GRN_OUTPUT_ARRAY_OPEN("RESULT", data->output.n_elements);
+ succeeded = grn_select_output_match(ctx, data);
+ if (succeeded) {
+ succeeded = grn_select_output_slices(ctx, data);
+ }
+ if (succeeded) {
+ succeeded = grn_select_output_drilldowns(ctx, data);
+ }
+ GRN_OUTPUT_ARRAY_CLOSE();
+ } else {
+ grn_obj_format format;
+ uint32_t n_additional_elements = 0;
+
+ if (data->slices) {
+ n_additional_elements++;
+ }
+ if (data->drilldowns) {
+ n_additional_elements++;
+ }
+
+ succeeded = grn_select_output_match_open(ctx,
+ data,
+ &format,
+ n_additional_elements);
+ if (succeeded) {
+ succeeded = grn_select_output_slices(ctx, data);
+ if (succeeded) {
+ succeeded = grn_select_output_drilldowns(ctx, data);
+ }
+ if (!grn_select_output_match_close(ctx, data, &format)) {
+ succeeded = GRN_FALSE;
+ }
+ }
+ }
+
+ return succeeded;
+}
+
+static void
+grn_select_output_slices_label_v1(grn_ctx *ctx, grn_select_data *data)
+{
+}
+
+static void
+grn_select_output_slices_open_v1(grn_ctx *ctx,
+ grn_select_data *data,
+ unsigned int n_result_sets)
+{
+ GRN_OUTPUT_MAP_OPEN("SLICES", n_result_sets);
+}
+
+static void
+grn_select_output_slices_close_v1(grn_ctx *ctx, grn_select_data *data)
+{
+ GRN_OUTPUT_MAP_CLOSE();
+}
+
+static void
+grn_select_output_slice_label_v1(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_slice_data *slice)
+{
+ GRN_OUTPUT_STR(slice->label.value, slice->label.length);
+}
+
+static void
+grn_select_output_drilldowns_label_v1(grn_ctx *ctx, grn_select_data *data)
+{
+}
+
+static void
+grn_select_output_drilldowns_open_v1(grn_ctx *ctx,
+ grn_select_data *data,
+ unsigned int n_result_sets)
+{
+ if (data->drilldown.keys.length == 0) {
+ GRN_OUTPUT_MAP_OPEN("DRILLDOWNS", n_result_sets);
+ }
+}
+
+static void
+grn_select_output_drilldowns_close_v1(grn_ctx *ctx, grn_select_data *data)
+{
+ if (data->drilldown.keys.length == 0) {
+ GRN_OUTPUT_MAP_CLOSE();
+ }
+}
+
+static void
+grn_select_output_drilldown_label_v1(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_drilldown_data *drilldown)
+{
+ if (data->drilldown.keys.length == 0) {
+ GRN_OUTPUT_STR(drilldown->label.value, drilldown->label.length);
+ }
+}
+
+static grn_select_output_formatter grn_select_output_formatter_v1 = {
+ grn_select_output_slices_label_v1,
+ grn_select_output_slices_open_v1,
+ grn_select_output_slices_close_v1,
+ grn_select_output_slice_label_v1,
+ grn_select_output_drilldowns_label_v1,
+ grn_select_output_drilldowns_open_v1,
+ grn_select_output_drilldowns_close_v1,
+ grn_select_output_drilldown_label_v1
+};
+
+static void
+grn_select_output_slices_label_v3(grn_ctx *ctx, grn_select_data *data)
+{
+ GRN_OUTPUT_CSTR("slices");
+}
+
+static void
+grn_select_output_slices_open_v3(grn_ctx *ctx,
+ grn_select_data *data,
+ unsigned int n_result_sets)
+{
+ GRN_OUTPUT_MAP_OPEN("slices", n_result_sets);
+}
+
+static void
+grn_select_output_slices_close_v3(grn_ctx *ctx, grn_select_data *data)
+{
+ GRN_OUTPUT_MAP_CLOSE();
+}
+
+static void
+grn_select_output_slice_label_v3(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_slice_data *slice)
+{
+ GRN_OUTPUT_STR(slice->label.value, slice->label.length);
+}
+
+static void
+grn_select_output_drilldowns_label_v3(grn_ctx *ctx, grn_select_data *data)
+{
+ GRN_OUTPUT_CSTR("drilldowns");
+}
+
+static void
+grn_select_output_drilldowns_open_v3(grn_ctx *ctx,
+ grn_select_data *data,
+ unsigned int n_result_sets)
+{
+ GRN_OUTPUT_MAP_OPEN("drilldowns", n_result_sets);
+}
+
+static void
+grn_select_output_drilldowns_close_v3(grn_ctx *ctx, grn_select_data *data)
+{
+ GRN_OUTPUT_MAP_CLOSE();
+}
+
+static void
+grn_select_output_drilldown_label_v3(grn_ctx *ctx,
+ grn_select_data *data,
+ grn_drilldown_data *drilldown)
+{
+ if (data->drilldown.keys.length == 0) {
+ GRN_OUTPUT_STR(drilldown->label.value, drilldown->label.length);
+ } else {
+ grn_obj *key;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_len;
+
+ key = drilldown->parsed_keys[0].key;
+ switch (key->header.type) {
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ name_len = grn_column_name(ctx, key, name, GRN_TABLE_MAX_KEY_SIZE);
+ break;
+ default :
+ name_len = grn_obj_name(ctx, key, name, GRN_TABLE_MAX_KEY_SIZE);
+ break;
+ }
+ GRN_OUTPUT_STR(name, name_len);
+ }
+}
+
+static grn_select_output_formatter grn_select_output_formatter_v3 = {
+ grn_select_output_slices_label_v3,
+ grn_select_output_slices_open_v3,
+ grn_select_output_slices_close_v3,
+ grn_select_output_slice_label_v3,
+ grn_select_output_drilldowns_label_v3,
+ grn_select_output_drilldowns_open_v3,
+ grn_select_output_drilldowns_close_v3,
+ grn_select_output_drilldown_label_v3
+};
+
+static grn_rc
+grn_select(grn_ctx *ctx, grn_select_data *data)
+{
+ uint32_t nhits;
+ grn_obj *outbuf = ctx->impl->output.buf;
+ grn_content_type output_type = ctx->impl->output.type;
+ char cache_key[GRN_CACHE_MAX_KEY_SIZE];
+ uint32_t cache_key_size;
+ long long int threshold, original_threshold = 0;
+ grn_cache *cache_obj = grn_cache_current_get(ctx);
+
+ if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+ data->output.formatter = &grn_select_output_formatter_v1;
+ } else {
+ data->output.formatter = &grn_select_output_formatter_v3;
+ }
+
+ data->cacheable = 1;
+ data->taintable = 0;
+
+ data->output.n_elements = 0;
+
+ grn_raw_string_lstrip(ctx, &(data->filter.query));
+
+ cache_key_size =
+ data->table.length + 1 +
+ data->filter.match_columns.length + 1 +
+ data->filter.query.length + 1 +
+ data->filter.filter.length + 1 +
+ data->scorer.length + 1 +
+ data->sort_keys.length + 1 +
+ data->output_columns.length + 1 +
+ data->match_escalation_threshold.length + 1 +
+ data->filter.query_expander.length + 1 +
+ data->filter.query_flags.length + 1 +
+ data->adjuster.length + 1 +
+ sizeof(grn_content_type) +
+ sizeof(int) * 2 +
+ sizeof(grn_command_version) +
+ sizeof(grn_bool);
+ if (data->slices) {
+ GRN_HASH_EACH_BEGIN(ctx, data->slices, cursor, id) {
+ grn_slice_data *slice;
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&slice);
+ grn_raw_string_lstrip(ctx, &(slice->filter.query));
+ cache_key_size +=
+ slice->filter.match_columns.length + 1 +
+ slice->filter.query.length + 1 +
+ slice->filter.query_expander.length + 1 +
+ slice->filter.query_flags.length + 1 +
+ slice->filter.filter.length + 1 +
+ slice->sort_keys.length + 1 +
+ slice->output_columns.length + 1 +
+ slice->label.length + 1 +
+ sizeof(int) * 2;
+ } GRN_HASH_EACH_END(ctx, cursor);
+ }
+#define DRILLDOWN_CACHE_SIZE(drilldown) \
+ drilldown->keys.length + 1 + \
+ drilldown->sort_keys.length + 1 + \
+ drilldown->output_columns.length + 1 + \
+ drilldown->label.length + 1 + \
+ drilldown->calc_target_name.length + 1 + \
+ drilldown->filter.length + 1 + \
+ drilldown->table_name.length + 1 + \
+ sizeof(int) * 2 + \
+ sizeof(grn_table_group_flags)
+ if (data->drilldown.keys.length > 0) {
+ grn_drilldown_data *drilldown = &(data->drilldown);
+ cache_key_size += DRILLDOWN_CACHE_SIZE(drilldown);
+ }
+ if (data->drilldowns) {
+ GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) {
+ grn_drilldown_data *drilldown;
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&drilldown);
+ cache_key_size += DRILLDOWN_CACHE_SIZE(drilldown);
+ } GRN_HASH_EACH_END(ctx, cursor);
+ }
+#undef DRILLDOWN_CACHE_SIZE
+ if (cache_key_size <= GRN_CACHE_MAX_KEY_SIZE) {
+ char *cp = cache_key;
+
+#define PUT_CACHE_KEY(string) \
+ grn_memcpy(cp, (string).value, (string).length); \
+ cp += (string).length; \
+ *cp++ = '\0'
+
+ PUT_CACHE_KEY(data->table);
+ PUT_CACHE_KEY(data->filter.match_columns);
+ PUT_CACHE_KEY(data->filter.query);
+ PUT_CACHE_KEY(data->filter.filter);
+ PUT_CACHE_KEY(data->scorer);
+ PUT_CACHE_KEY(data->sort_keys);
+ PUT_CACHE_KEY(data->output_columns);
+ if (data->slices) {
+ GRN_HASH_EACH_BEGIN(ctx, data->slices, cursor, id) {
+ grn_slice_data *slice;
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&slice);
+ PUT_CACHE_KEY(slice->filter.match_columns);
+ PUT_CACHE_KEY(slice->filter.query);
+ PUT_CACHE_KEY(slice->filter.query_expander);
+ PUT_CACHE_KEY(slice->filter.query_flags);
+ PUT_CACHE_KEY(slice->filter.filter);
+ PUT_CACHE_KEY(slice->sort_keys);
+ PUT_CACHE_KEY(slice->output_columns);
+ PUT_CACHE_KEY(slice->label);
+ grn_memcpy(cp, &(slice->offset), sizeof(int));
+ cp += sizeof(int);
+ grn_memcpy(cp, &(slice->limit), sizeof(int));
+ cp += sizeof(int);
+ } GRN_HASH_EACH_END(ctx, cursor);
+ }
+#define PUT_CACHE_KEY_DRILLDOWN(drilldown) do { \
+ PUT_CACHE_KEY(drilldown->keys); \
+ PUT_CACHE_KEY(drilldown->sort_keys); \
+ PUT_CACHE_KEY(drilldown->output_columns); \
+ PUT_CACHE_KEY(drilldown->label); \
+ PUT_CACHE_KEY(drilldown->calc_target_name); \
+ PUT_CACHE_KEY(drilldown->filter); \
+ PUT_CACHE_KEY(drilldown->table_name); \
+ grn_memcpy(cp, &(drilldown->offset), sizeof(int)); \
+ cp += sizeof(int); \
+ grn_memcpy(cp, &(drilldown->limit), sizeof(int)); \
+ cp += sizeof(int); \
+ grn_memcpy(cp, \
+ &(drilldown->calc_types), \
+ sizeof(grn_table_group_flags)); \
+ cp += sizeof(grn_table_group_flags); \
+ } while (GRN_FALSE)
+ if (data->drilldown.keys.length > 0) {
+ grn_drilldown_data *drilldown = &(data->drilldown);
+ PUT_CACHE_KEY_DRILLDOWN(drilldown);
+ }
+ if (data->drilldowns) {
+ GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) {
+ grn_drilldown_data *drilldown;
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&drilldown);
+ PUT_CACHE_KEY_DRILLDOWN(drilldown);
+ } GRN_HASH_EACH_END(ctx, cursor);
+ }
+#undef PUT_CACHE_KEY_DRILLDOWN
+ PUT_CACHE_KEY(data->match_escalation_threshold);
+ PUT_CACHE_KEY(data->filter.query_expander);
+ PUT_CACHE_KEY(data->filter.query_flags);
+ PUT_CACHE_KEY(data->adjuster);
+ grn_memcpy(cp, &output_type, sizeof(grn_content_type));
+ cp += sizeof(grn_content_type);
+ grn_memcpy(cp, &(data->offset), sizeof(int));
+ cp += sizeof(int);
+ grn_memcpy(cp, &(data->limit), sizeof(int));
+ cp += sizeof(int);
+ grn_memcpy(cp, &(ctx->impl->command.version), sizeof(grn_command_version));
+ cp += sizeof(grn_command_version);
+ grn_memcpy(cp, &(ctx->impl->output.is_pretty), sizeof(grn_bool));
+ cp += sizeof(grn_bool);
+#undef PUT_CACHE_KEY
+
+ {
+ grn_rc rc;
+ rc = grn_cache_fetch(ctx, cache_obj, cache_key, cache_key_size, outbuf);
+ if (rc == GRN_SUCCESS) {
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_CACHE,
+ ":", "cache(%" GRN_FMT_LLD ")",
+ (long long int)GRN_TEXT_LEN(outbuf));
+ return ctx->rc;
+ }
+ }
+ }
+ if (data->match_escalation_threshold.length) {
+ const char *end, *rest;
+ original_threshold = grn_ctx_get_match_escalation_threshold(ctx);
+ end =
+ data->match_escalation_threshold.value +
+ data->match_escalation_threshold.length;
+ threshold = grn_atoll(data->match_escalation_threshold.value, end, &rest);
+ if (end == rest) {
+ grn_ctx_set_match_escalation_threshold(ctx, threshold);
+ }
+ }
+
+ data->tables.target = grn_ctx_get(ctx, data->table.value, data->table.length);
+ if (!data->tables.target) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][table] invalid name: <%.*s>",
+ (int)(data->table.length),
+ data->table.value);
+ goto exit;
+ }
+
+ {
+ if (data->filter.filter.length > 0 &&
+ (data->filter.filter.value[0] == '?') &&
+ (ctx->impl->output.type == GRN_CONTENT_JSON)) {
+ ctx->rc = grn_ts_select(ctx, data->tables.target,
+ data->filter.filter.value + 1,
+ data->filter.filter.length - 1,
+ data->scorer.value,
+ data->scorer.length,
+ data->sort_keys.value,
+ data->sort_keys.length,
+ data->output_columns.value,
+ data->output_columns.length,
+ data->offset,
+ data->limit);
+ if (!ctx->rc &&
+ data->cacheable > 0 &&
+ cache_key_size <= GRN_CACHE_MAX_KEY_SIZE &&
+ (!data->cache.value ||
+ data->cache.length != 2 ||
+ data->cache.value[0] != 'n' ||
+ data->cache.value[1] != 'o')) {
+ grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf);
+ }
+ goto exit;
+ }
+
+ data->tables.initial = data->tables.target;
+ if (!grn_select_apply_initial_columns(ctx, data)) {
+ goto exit;
+ }
+
+ if (!grn_select_filter(ctx, data)) {
+ goto exit;
+ }
+
+ nhits = grn_table_size(ctx, data->tables.result);
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE,
+ ":", "select(%d)", nhits);
+
+ if (!grn_select_apply_filtered_columns(ctx, data)) {
+ goto exit;
+ }
+
+ {
+ grn_bool succeeded;
+
+ /* For select results */
+ data->output.n_elements = 1;
+
+ if (!grn_select_apply_adjuster(ctx, data)) {
+ goto exit;
+ }
+
+ if (!grn_select_apply_scorer(ctx, data)) {
+ goto exit;
+ }
+
+ grn_normalize_offset_and_limit(ctx, nhits,
+ &(data->offset), &(data->limit));
+
+ if (!grn_select_sort(ctx, data)) {
+ goto exit;
+ }
+
+ if (!grn_select_apply_output_columns(ctx, data)) {
+ goto exit;
+ }
+
+ if (!grn_select_prepare_slices(ctx, data)) {
+ goto exit;
+ }
+
+ if (!grn_select_prepare_drilldowns(ctx, data)) {
+ goto exit;
+ }
+
+ succeeded = grn_select_output(ctx, data);
+ if (!succeeded) {
+ goto exit;
+ }
+ }
+ if (!ctx->rc &&
+ data->cacheable &&
+ cache_key_size <= GRN_CACHE_MAX_KEY_SIZE &&
+ (!data->cache.value ||
+ data->cache.length != 2 ||
+ data->cache.value[0] != 'n' ||
+ data->cache.value[1] != 'o')) {
+ grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf);
+ }
+ if (data->taintable > 0) {
+ grn_db_touch(ctx, DB_OBJ(data->tables.target)->db);
+ }
+ }
+
+exit :
+ if (data->match_escalation_threshold.length > 0) {
+ grn_ctx_set_match_escalation_threshold(ctx, original_threshold);
+ }
+
+ /* GRN_LOG(ctx, GRN_LOG_NONE, "%d", ctx->seqno); */
+
+ return ctx->rc;
+}
+
+static grn_slice_data *
+grn_select_data_slices_add(grn_ctx *ctx,
+ grn_select_data *data,
+ const char *label,
+ size_t label_len)
+{
+ grn_slice_data *slice = NULL;
+ int added;
+
+ if (!data->slices) {
+ data->slices = grn_hash_create(ctx,
+ NULL,
+ GRN_TABLE_MAX_KEY_SIZE,
+ sizeof(grn_slice_data),
+ GRN_OBJ_TABLE_HASH_KEY |
+ GRN_OBJ_KEY_VAR_SIZE |
+ GRN_HASH_TINY);
+ if (!data->slices) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[select][slices] "
+ "failed to allocate slices data: %s",
+ ctx->errbuf);
+ return NULL;
+ }
+ }
+
+ grn_hash_add(ctx,
+ data->slices,
+ label,
+ label_len,
+ (void **)&slice,
+ &added);
+ if (added) {
+ grn_slice_data_init(ctx, slice, label, label_len);
+ }
+
+ return slice;
+}
+
+static grn_bool
+grn_select_data_fill_slice_labels(grn_ctx *ctx,
+ grn_user_data *user_data,
+ grn_select_data *data)
+{
+ grn_obj *vars;
+ grn_table_cursor *cursor;
+ const char *prefix = "slices[";
+ int prefix_len;
+
+ vars = grn_plugin_proc_get_vars(ctx, user_data);
+
+ cursor = grn_table_cursor_open(ctx, vars, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ return GRN_FALSE;
+ }
+
+ prefix_len = strlen(prefix);
+ while (grn_table_cursor_next(ctx, cursor)) {
+ void *key;
+ char *name;
+ int name_len;
+ name_len = grn_table_cursor_get_key(ctx, cursor, &key);
+ name = key;
+ if (name_len > prefix_len + 1 &&
+ strncmp(prefix, name, prefix_len) == 0) {
+ const char *label_end;
+ size_t label_len;
+ label_end = memchr(name + prefix_len + 1,
+ ']',
+ name_len - prefix_len - 1);
+ if (!label_end) {
+ continue;
+ }
+ label_len = (label_end - name) - prefix_len;
+ grn_select_data_slices_add(ctx,
+ data,
+ name + prefix_len,
+ label_len);
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_select_data_fill_slices(grn_ctx *ctx,
+ grn_user_data *user_data,
+ grn_select_data *data)
+{
+ if (!grn_select_data_fill_slice_labels(ctx, user_data, data)) {
+ return GRN_FALSE;
+ }
+
+ GRN_HASH_EACH_BEGIN(ctx, data->slices, cursor, id) {
+ grn_slice_data *slice;
+ char slice_label[GRN_TABLE_MAX_KEY_SIZE];
+ char key_name[GRN_TABLE_MAX_KEY_SIZE];
+ grn_obj *match_columns;
+ grn_obj *query;
+ grn_obj *query_expander;
+ grn_obj *query_flags;
+ grn_obj *filter;
+ grn_obj *sort_keys;
+ grn_obj *output_columns;
+ grn_obj *offset;
+ grn_obj *limit;
+
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&slice);
+
+ grn_snprintf(slice_label,
+ GRN_TABLE_MAX_KEY_SIZE,
+ GRN_TABLE_MAX_KEY_SIZE,
+ "slices[%.*s].",
+ (int)(slice->label.length),
+ slice->label.value);
+
+#define GET_VAR(name) \
+ grn_snprintf(key_name, \
+ GRN_TABLE_MAX_KEY_SIZE, \
+ GRN_TABLE_MAX_KEY_SIZE, \
+ "%s%s", slice_label, #name); \
+ name = grn_plugin_proc_get_var(ctx, user_data, key_name, -1);
+
+ GET_VAR(match_columns);
+ GET_VAR(query);
+ GET_VAR(query_expander);
+ GET_VAR(query_flags);
+ GET_VAR(filter);
+ GET_VAR(sort_keys);
+ GET_VAR(output_columns);
+ GET_VAR(offset);
+ GET_VAR(limit);
+
+#undef GET_VAR
+
+ grn_slice_data_fill(ctx,
+ slice,
+ match_columns,
+ query,
+ query_expander,
+ query_flags,
+ filter,
+ sort_keys,
+ output_columns,
+ offset,
+ limit);
+ } GRN_HASH_EACH_END(ctx, cursor);
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_select_data_fill_drilldown_labels(grn_ctx *ctx,
+ grn_user_data *user_data,
+ grn_select_data *data,
+ const char *prefix)
+{
+ grn_obj *vars;
+ grn_table_cursor *cursor;
+ int prefix_len;
+
+ vars = grn_plugin_proc_get_vars(ctx, user_data);
+
+ cursor = grn_table_cursor_open(ctx, vars, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ return GRN_FALSE;
+ }
+
+ prefix_len = strlen(prefix);
+ while (grn_table_cursor_next(ctx, cursor)) {
+ void *key;
+ char *name;
+ int name_len;
+ name_len = grn_table_cursor_get_key(ctx, cursor, &key);
+ name = key;
+ if (name_len > prefix_len + 1 &&
+ strncmp(prefix, name, prefix_len) == 0) {
+ const char *label_end;
+ size_t label_len;
+ label_end = memchr(name + prefix_len + 1,
+ ']',
+ name_len - prefix_len - 1);
+ if (!label_end) {
+ continue;
+ }
+ label_len = (label_end - name) - prefix_len;
+ grn_select_data_drilldowns_add(ctx,
+ data,
+ name + prefix_len,
+ label_len);
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_select_data_fill_drilldown_columns(grn_ctx *ctx,
+ grn_user_data *user_data,
+ grn_drilldown_data *drilldown,
+ const char *parameter_key)
+{
+ char prefix[GRN_TABLE_MAX_KEY_SIZE];
+
+ grn_snprintf(prefix,
+ GRN_TABLE_MAX_KEY_SIZE,
+ GRN_TABLE_MAX_KEY_SIZE,
+ "%s[%.*s].",
+ parameter_key,
+ (int)(drilldown->label.length),
+ drilldown->label.value);
+ return grn_columns_fill(ctx,
+ user_data,
+ &(drilldown->columns),
+ prefix,
+ strlen(prefix));
+}
+
+static grn_bool
+grn_select_data_fill_drilldowns(grn_ctx *ctx,
+ grn_user_data *user_data,
+ grn_select_data *data)
+{
+ grn_obj *drilldown;
+
+ drilldown = grn_plugin_proc_get_var(ctx, user_data, "drilldown", -1);
+ if (GRN_TEXT_LEN(drilldown) > 0) {
+ grn_obj *sort_keys;
+
+ sort_keys = grn_plugin_proc_get_var(ctx, user_data,
+ "drilldown_sort_keys", -1);
+ if (GRN_TEXT_LEN(sort_keys) == 0) {
+ /* For backward compatibility */
+ sort_keys = grn_plugin_proc_get_var(ctx, user_data,
+ "drilldown_sortby", -1);
+ }
+ grn_drilldown_data_fill(ctx,
+ &(data->drilldown),
+ drilldown,
+ sort_keys,
+ grn_plugin_proc_get_var(ctx, user_data,
+ "drilldown_output_columns",
+ -1),
+ grn_plugin_proc_get_var(ctx, user_data,
+ "drilldown_offset", -1),
+ grn_plugin_proc_get_var(ctx, user_data,
+ "drilldown_limit", -1),
+ grn_plugin_proc_get_var(ctx, user_data,
+ "drilldown_calc_types", -1),
+ grn_plugin_proc_get_var(ctx, user_data,
+ "drilldown_calc_target", -1),
+ grn_plugin_proc_get_var(ctx, user_data,
+ "drilldown_filter", -1),
+ NULL);
+ return GRN_TRUE;
+ } else {
+ grn_bool succeeded = GRN_TRUE;
+
+ if (!grn_select_data_fill_drilldown_labels(ctx, user_data, data,
+ "drilldowns[")) {
+ return GRN_FALSE;
+ }
+
+ /* For backward compatibility */
+ if (!grn_select_data_fill_drilldown_labels(ctx, user_data, data,
+ "drilldown[")) {
+ return GRN_FALSE;
+ }
+
+ GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) {
+ grn_drilldown_data *drilldown;
+ grn_obj *keys = NULL;
+ grn_obj *sort_keys = NULL;
+ grn_obj *output_columns = NULL;
+ grn_obj *offset = NULL;
+ grn_obj *limit = NULL;
+ grn_obj *calc_types = NULL;
+ grn_obj *calc_target = NULL;
+ grn_obj *filter = NULL;
+ grn_obj *table = NULL;
+
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&drilldown);
+
+ succeeded = grn_select_data_fill_drilldown_columns(ctx,
+ user_data,
+ drilldown,
+ "drilldowns");
+ if (!succeeded) {
+ break;
+ }
+
+ /* For backward compatibility */
+ succeeded = grn_select_data_fill_drilldown_columns(ctx,
+ user_data,
+ drilldown,
+ "drilldown");
+ if (!succeeded) {
+ break;
+ }
+
+#define GET_VAR_RAW(parameter_key, name) do { \
+ if (!name) { \
+ char key_name[GRN_TABLE_MAX_KEY_SIZE]; \
+ grn_snprintf(key_name, \
+ GRN_TABLE_MAX_KEY_SIZE, \
+ GRN_TABLE_MAX_KEY_SIZE, \
+ "%s[%.*s].%s", \
+ (parameter_key), \
+ (int)(drilldown->label.length), \
+ drilldown->label.value, \
+ #name); \
+ name = grn_plugin_proc_get_var(ctx, user_data, key_name, -1); \
+ } \
+ } while (GRN_FALSE)
+
+#define GET_VAR(name) do { \
+ GET_VAR_RAW("drilldowns", name); \
+ /* For backward compatibility */ \
+ GET_VAR_RAW("drilldown", name); \
+ } while (GRN_FALSE)
+
+ GET_VAR(keys);
+ GET_VAR(sort_keys);
+ if (!sort_keys) {
+ grn_obj *sortby = NULL;
+ GET_VAR(sortby);
+ sort_keys = sortby;
+ }
+ GET_VAR(output_columns);
+ GET_VAR(offset);
+ GET_VAR(limit);
+ GET_VAR(calc_types);
+ GET_VAR(calc_target);
+ GET_VAR(filter);
+ GET_VAR(table);
+
+#undef GET_VAR
+
+#undef GET_VAR_RAW
+
+ grn_drilldown_data_fill(ctx,
+ drilldown,
+ keys,
+ sort_keys,
+ output_columns,
+ offset,
+ limit,
+ calc_types,
+ calc_target,
+ filter,
+ table);
+ } GRN_HASH_EACH_END(ctx, cursor);
+
+ return succeeded;
+ }
+}
+
+static grn_obj *
+command_select(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_select_data data;
+
+ grn_columns_init(ctx, &(data.columns));
+ grn_filter_data_init(ctx, &(data.filter));
+
+ data.tables.target = NULL;
+ data.tables.initial = NULL;
+ data.tables.result = NULL;
+ data.tables.sorted = NULL;
+
+ data.slices = NULL;
+ grn_drilldown_data_init(ctx, &(data.drilldown), NULL, 0);
+ data.drilldowns = NULL;
+
+ data.table.value = grn_plugin_proc_get_var_string(ctx, user_data,
+ "table", -1,
+ &(data.table.length));
+#define GET_VAR(name) \
+ grn_plugin_proc_get_var(ctx, user_data, name, strlen(name))
+
+ {
+ grn_obj *query_expander;
+
+ query_expander = GET_VAR("query_expander");
+ if (GRN_TEXT_LEN(query_expander) == 0) {
+ query_expander = GET_VAR("query_expansion");
+ }
+
+ grn_filter_data_fill(ctx,
+ &(data.filter),
+ GET_VAR("match_columns"),
+ GET_VAR("query"),
+ query_expander,
+ GET_VAR("query_flags"),
+ GET_VAR("filter"));
+ }
+#undef GET_VAR
+
+ data.scorer.value =
+ grn_plugin_proc_get_var_string(ctx, user_data,
+ "scorer", -1,
+ &(data.scorer.length));
+ data.sort_keys.value =
+ grn_plugin_proc_get_var_string(ctx, user_data,
+ "sort_keys", -1,
+ &(data.sort_keys.length));
+ if (data.sort_keys.length == 0) {
+ /* For backward compatibility */
+ data.sort_keys.value =
+ grn_plugin_proc_get_var_string(ctx, user_data,
+ "sortby", -1,
+ &(data.sort_keys.length));
+ }
+ data.output_columns.value =
+ grn_plugin_proc_get_var_string(ctx, user_data,
+ "output_columns", -1,
+ &(data.output_columns.length));
+ if (!data.output_columns.value) {
+ data.output_columns.value = GRN_SELECT_DEFAULT_OUTPUT_COLUMNS;
+ data.output_columns.length = strlen(GRN_SELECT_DEFAULT_OUTPUT_COLUMNS);
+ }
+ data.offset = grn_plugin_proc_get_var_int32(ctx, user_data,
+ "offset", -1,
+ 0);
+ data.limit = grn_plugin_proc_get_var_int32(ctx, user_data,
+ "limit", -1,
+ GRN_SELECT_DEFAULT_LIMIT);
+
+ data.cache.value = grn_plugin_proc_get_var_string(ctx, user_data,
+ "cache", -1,
+ &(data.cache.length));
+ data.match_escalation_threshold.value =
+ grn_plugin_proc_get_var_string(ctx, user_data,
+ "match_escalation_threshold", -1,
+ &(data.match_escalation_threshold.length));
+
+ data.adjuster.value =
+ grn_plugin_proc_get_var_string(ctx, user_data,
+ "adjuster", -1,
+ &(data.adjuster.length));
+
+ if (!grn_select_data_fill_slices(ctx, user_data, &data)) {
+ goto exit;
+ }
+
+ if (!grn_select_data_fill_drilldowns(ctx, user_data, &data)) {
+ goto exit;
+ }
+
+ if (!grn_columns_fill(ctx, user_data, &(data.columns), NULL, 0)) {
+ goto exit;
+ }
+
+ grn_select(ctx, &data);
+
+exit :
+ if (data.drilldowns) {
+ GRN_HASH_EACH_BEGIN(ctx, data.drilldowns, cursor, id) {
+ grn_drilldown_data *drilldown;
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&drilldown);
+ grn_drilldown_data_fin(ctx, drilldown);
+ } GRN_HASH_EACH_END(ctx, cursor);
+ grn_hash_close(ctx, data.drilldowns);
+ }
+
+ if (data.drilldown.parsed_keys) {
+ grn_table_sort_key_close(ctx,
+ data.drilldown.parsed_keys,
+ data.drilldown.n_parsed_keys);
+ }
+ grn_drilldown_data_fin(ctx, &(data.drilldown));
+
+ if (data.slices) {
+ GRN_HASH_EACH_BEGIN(ctx, data.slices, cursor, id) {
+ grn_slice_data *slice;
+ grn_hash_cursor_get_value(ctx, cursor, (void **)&slice);
+ grn_slice_data_fin(ctx, slice);
+ } GRN_HASH_EACH_END(ctx, cursor);
+ grn_hash_close(ctx, data.slices);
+ }
+
+ if (data.tables.sorted) {
+ grn_obj_unlink(ctx, data.tables.sorted);
+ }
+
+ if (data.tables.result == data.filter.filtered) {
+ data.tables.result = NULL;
+ }
+ grn_filter_data_fin(ctx, &(data.filter));
+
+ if (data.tables.result &&
+ data.tables.result != data.tables.initial &&
+ data.tables.result != data.tables.target) {
+ grn_obj_unlink(ctx, data.tables.result);
+ }
+
+ if (data.tables.initial && data.tables.initial != data.tables.target) {
+ grn_obj_unlink(ctx, data.tables.initial);
+ }
+
+ if (data.tables.target) {
+ grn_obj_unlink(ctx, data.tables.target);
+ }
+
+ grn_columns_fin(ctx, &(data.columns));
+
+ return NULL;
+}
+
+#define N_VARS 26
+#define DEFINE_VARS grn_expr_var vars[N_VARS]
+
+static void
+init_vars(grn_ctx *ctx, grn_expr_var *vars)
+{
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "name", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "table", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[2]), "match_columns", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[3]), "query", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[4]), "filter", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[5]), "scorer", -1);
+ /* Deprecated since 6.0.3. Use sort_keys instead. */
+ grn_plugin_expr_var_init(ctx, &(vars[6]), "sortby", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[7]), "output_columns", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[8]), "offset", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[9]), "limit", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[10]), "drilldown", -1);
+ /* Deprecated since 6.0.3. Use drilldown_sort_keys instead. */
+ grn_plugin_expr_var_init(ctx, &(vars[11]), "drilldown_sortby", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[12]), "drilldown_output_columns", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[13]), "drilldown_offset", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[14]), "drilldown_limit", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[15]), "cache", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[16]), "match_escalation_threshold", -1);
+ /* Deprecated. Use query_expander instead. */
+ grn_plugin_expr_var_init(ctx, &(vars[17]), "query_expansion", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[18]), "query_flags", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[19]), "query_expander", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[20]), "adjuster", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[21]), "drilldown_calc_types", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[22]), "drilldown_calc_target", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[23]), "drilldown_filter", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[24]), "sort_keys", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[25]), "drilldown_sort_keys", -1);
+}
+
+void
+grn_proc_init_select(grn_ctx *ctx)
+{
+ DEFINE_VARS;
+
+ init_vars(ctx, vars);
+ grn_plugin_command_create(ctx,
+ "select", -1,
+ command_select,
+ N_VARS - 1,
+ vars + 1);
+}
+
+static grn_obj *
+command_define_selector(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ uint32_t i, nvars;
+ grn_expr_var *vars;
+
+ grn_proc_get_info(ctx, user_data, &vars, &nvars, NULL);
+ for (i = 1; i < nvars; i++) {
+ grn_obj *var;
+ var = grn_plugin_proc_get_var_by_offset(ctx, user_data, i);
+ GRN_TEXT_SET(ctx, &((vars + i)->value),
+ GRN_TEXT_VALUE(var),
+ GRN_TEXT_LEN(var));
+ }
+ {
+ grn_obj *name;
+ name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+ grn_plugin_command_create(ctx,
+ GRN_TEXT_VALUE(name),
+ GRN_TEXT_LEN(name),
+ command_select,
+ nvars - 1,
+ vars + 1);
+ }
+ GRN_OUTPUT_BOOL(!ctx->rc);
+
+ return NULL;
+}
+
+void
+grn_proc_init_define_selector(grn_ctx *ctx)
+{
+ DEFINE_VARS;
+
+ init_vars(ctx, vars);
+ grn_plugin_command_create(ctx,
+ "define_selector", -1,
+ command_define_selector,
+ N_VARS,
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_snippet.c b/storage/mroonga/vendor/groonga/lib/proc/proc_snippet.c
new file mode 100644
index 00000000000..f98438d6792
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_snippet.c
@@ -0,0 +1,319 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+#include "../grn_expr.h"
+
+#include <groonga/plugin.h>
+#include <string.h>
+
+#define GRN_FUNC_SNIPPET_HTML_CACHE_NAME "$snippet_html"
+
+static grn_obj *
+snippet_exec(grn_ctx *ctx, grn_obj *snip, grn_obj *text,
+ grn_user_data *user_data,
+ const char *prefix, int prefix_length,
+ const char *suffix, int suffix_length)
+{
+ grn_rc rc;
+ unsigned int i, n_results, max_tagged_length;
+ grn_obj snippet_buffer;
+ grn_obj *snippets;
+
+ if (GRN_TEXT_LEN(text) == 0) {
+ return NULL;
+ }
+
+ rc = grn_snip_exec(ctx, snip,
+ GRN_TEXT_VALUE(text), GRN_TEXT_LEN(text),
+ &n_results, &max_tagged_length);
+ if (rc != GRN_SUCCESS) {
+ return NULL;
+ }
+
+ if (n_results == 0) {
+ return grn_plugin_proc_alloc(ctx, user_data, GRN_DB_VOID, 0);
+ }
+
+ snippets = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_SHORT_TEXT, GRN_OBJ_VECTOR);
+ if (!snippets) {
+ return NULL;
+ }
+
+ GRN_TEXT_INIT(&snippet_buffer, 0);
+ grn_bulk_space(ctx, &snippet_buffer,
+ prefix_length + max_tagged_length + suffix_length);
+ for (i = 0; i < n_results; i++) {
+ unsigned int snippet_length;
+
+ GRN_BULK_REWIND(&snippet_buffer);
+ if (prefix_length) {
+ GRN_TEXT_PUT(ctx, &snippet_buffer, prefix, prefix_length);
+ }
+ rc = grn_snip_get_result(ctx, snip, i,
+ GRN_TEXT_VALUE(&snippet_buffer) + prefix_length,
+ &snippet_length);
+ if (rc == GRN_SUCCESS) {
+ grn_strncat(GRN_TEXT_VALUE(&snippet_buffer),
+ GRN_BULK_WSIZE(&snippet_buffer),
+ suffix,
+ suffix_length);
+ grn_vector_add_element(ctx, snippets,
+ GRN_TEXT_VALUE(&snippet_buffer),
+ prefix_length + snippet_length + suffix_length,
+ 0, GRN_DB_SHORT_TEXT);
+ }
+ }
+ GRN_OBJ_FIN(ctx, &snippet_buffer);
+
+ return snippets;
+}
+
+/* TODO: support caching for the same parameter. */
+static grn_obj *
+func_snippet(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *snippets = NULL;
+
+#define N_REQUIRED_ARGS 1
+#define KEYWORD_SET_SIZE 3
+ if (nargs > N_REQUIRED_ARGS) {
+ grn_obj *text = args[0];
+ grn_obj *end_arg = args[nargs - 1];
+ grn_obj *snip = NULL;
+ unsigned int width = 200;
+ unsigned int max_n_results = 3;
+ grn_snip_mapping *mapping = NULL;
+ int flags = GRN_SNIP_SKIP_LEADING_SPACES;
+ const char *prefix = NULL;
+ int prefix_length = 0;
+ const char *suffix = NULL;
+ int suffix_length = 0;
+ const char *normalizer_name = NULL;
+ int normalizer_name_length = 0;
+ const char *default_open_tag = NULL;
+ int default_open_tag_length = 0;
+ const char *default_close_tag = NULL;
+ int default_close_tag_length = 0;
+ int n_args_without_option = nargs;
+
+ if (end_arg->header.type == GRN_TABLE_HASH_KEY) {
+ grn_obj *options = end_arg;
+ grn_hash_cursor *cursor;
+ void *key;
+ int key_size;
+ grn_obj *value;
+
+ n_args_without_option--;
+ cursor = grn_hash_cursor_open(ctx, (grn_hash *)options,
+ NULL, 0, NULL, 0,
+ 0, -1, 0);
+ if (!cursor) {
+ GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE,
+ "snippet(): couldn't open cursor");
+ goto exit;
+ }
+ while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ grn_hash_cursor_get_key_value(ctx, cursor,
+ &key, &key_size,
+ (void **)&value);
+ if (key_size == 5 && !memcmp(key, "width", 5)) {
+ width = GRN_UINT32_VALUE(value);
+ } else if (key_size == 13 && !memcmp(key, "max_n_results", 13)) {
+ max_n_results = GRN_UINT32_VALUE(value);
+ } else if (key_size == 19 && !memcmp(key, "skip_leading_spaces", 19)) {
+ if (GRN_BOOL_VALUE(value) == GRN_FALSE) {
+ flags &= ~GRN_SNIP_SKIP_LEADING_SPACES;
+ }
+ } else if (key_size == 11 && !memcmp(key, "html_escape", 11)) {
+ if (GRN_BOOL_VALUE(value)) {
+ mapping = GRN_SNIP_MAPPING_HTML_ESCAPE;
+ }
+ } else if (key_size == 6 && !memcmp(key, "prefix", 6)) {
+ prefix = GRN_TEXT_VALUE(value);
+ prefix_length = GRN_TEXT_LEN(value);
+ } else if (key_size == 6 && !memcmp(key, "suffix", 6)) {
+ suffix = GRN_TEXT_VALUE(value);
+ suffix_length = GRN_TEXT_LEN(value);
+ } else if (key_size == 10 && !memcmp(key, "normalizer", 10)) {
+ normalizer_name = GRN_TEXT_VALUE(value);
+ normalizer_name_length = GRN_TEXT_LEN(value);
+ } else if (key_size == 16 && !memcmp(key, "default_open_tag", 16)) {
+ default_open_tag = GRN_TEXT_VALUE(value);
+ default_open_tag_length = GRN_TEXT_LEN(value);
+ } else if (key_size == 17 && !memcmp(key, "default_close_tag", 17)) {
+ default_close_tag = GRN_TEXT_VALUE(value);
+ default_close_tag_length = GRN_TEXT_LEN(value);
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "invalid option name: <%.*s>",
+ key_size, (char *)key);
+ grn_hash_cursor_close(ctx, cursor);
+ goto exit;
+ }
+ }
+ grn_hash_cursor_close(ctx, cursor);
+ }
+
+ snip = grn_snip_open(ctx, flags, width, max_n_results,
+ default_open_tag, default_open_tag_length,
+ default_close_tag, default_close_tag_length, mapping);
+ if (snip) {
+ grn_rc rc;
+ unsigned int i;
+ if (!normalizer_name) {
+ grn_snip_set_normalizer(ctx, snip, GRN_NORMALIZER_AUTO);
+ } else if (normalizer_name_length > 0) {
+ grn_obj *normalizer;
+ normalizer = grn_ctx_get(ctx, normalizer_name, normalizer_name_length);
+ if (!grn_obj_is_normalizer_proc(ctx, normalizer)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, normalizer);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "snippet(): not normalizer: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ grn_obj_unlink(ctx, normalizer);
+ goto exit;
+ }
+ grn_snip_set_normalizer(ctx, snip, normalizer);
+ grn_obj_unlink(ctx, normalizer);
+ }
+ if (default_open_tag_length == 0 && default_close_tag_length == 0) {
+ unsigned int n_keyword_sets =
+ (n_args_without_option - N_REQUIRED_ARGS) / KEYWORD_SET_SIZE;
+ grn_obj **keyword_set_args = args + N_REQUIRED_ARGS;
+ for (i = 0; i < n_keyword_sets; i++) {
+ rc = grn_snip_add_cond(ctx, snip,
+ GRN_TEXT_VALUE(keyword_set_args[i * KEYWORD_SET_SIZE]),
+ GRN_TEXT_LEN(keyword_set_args[i * KEYWORD_SET_SIZE]),
+ GRN_TEXT_VALUE(keyword_set_args[i * KEYWORD_SET_SIZE + 1]),
+ GRN_TEXT_LEN(keyword_set_args[i * KEYWORD_SET_SIZE + 1]),
+ GRN_TEXT_VALUE(keyword_set_args[i * KEYWORD_SET_SIZE + 2]),
+ GRN_TEXT_LEN(keyword_set_args[i * KEYWORD_SET_SIZE + 2]));
+ }
+ } else {
+ unsigned int n_keywords = n_args_without_option - N_REQUIRED_ARGS;
+ grn_obj **keyword_args = args + N_REQUIRED_ARGS;
+ for (i = 0; i < n_keywords; i++) {
+ rc = grn_snip_add_cond(ctx, snip,
+ GRN_TEXT_VALUE(keyword_args[i]),
+ GRN_TEXT_LEN(keyword_args[i]),
+ NULL, 0,
+ NULL, 0);
+ }
+ }
+ snippets = snippet_exec(ctx, snip, text, user_data,
+ prefix, prefix_length,
+ suffix, suffix_length);
+ }
+ }
+#undef KEYWORD_SET_SIZE
+#undef N_REQUIRED_ARGS
+
+exit :
+ if (!snippets) {
+ snippets = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_VOID, 0);
+ }
+
+ return snippets;
+}
+
+void
+grn_proc_init_snippet(grn_ctx *ctx)
+{
+ grn_proc_create(ctx, "snippet", -1, GRN_PROC_FUNCTION,
+ func_snippet, NULL, NULL, 0, NULL);
+}
+
+static grn_obj *
+func_snippet_html(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *snippets = NULL;
+
+ /* TODO: support parameters */
+ if (nargs == 1) {
+ grn_obj *text = args[0];
+ grn_obj *expression = NULL;
+ grn_obj *condition_ptr = NULL;
+ grn_obj *condition = NULL;
+ grn_obj *snip = NULL;
+ int flags = GRN_SNIP_SKIP_LEADING_SPACES;
+ unsigned int width = 200;
+ unsigned int max_n_results = 3;
+ const char *open_tag = "<span class=\"keyword\">";
+ const char *close_tag = "</span>";
+ grn_snip_mapping *mapping = GRN_SNIP_MAPPING_HTML_ESCAPE;
+
+ grn_proc_get_info(ctx, user_data, NULL, NULL, &expression);
+ condition_ptr = grn_expr_get_var(ctx, expression,
+ GRN_SELECT_INTERNAL_VAR_CONDITION,
+ strlen(GRN_SELECT_INTERNAL_VAR_CONDITION));
+ if (condition_ptr) {
+ condition = GRN_PTR_VALUE(condition_ptr);
+ }
+
+ if (condition) {
+ grn_obj *snip_ptr;
+ snip_ptr = grn_expr_get_var(ctx, expression,
+ GRN_FUNC_SNIPPET_HTML_CACHE_NAME,
+ strlen(GRN_FUNC_SNIPPET_HTML_CACHE_NAME));
+ if (snip_ptr) {
+ snip = GRN_PTR_VALUE(snip_ptr);
+ } else {
+ snip_ptr =
+ grn_expr_get_or_add_var(ctx, expression,
+ GRN_FUNC_SNIPPET_HTML_CACHE_NAME,
+ strlen(GRN_FUNC_SNIPPET_HTML_CACHE_NAME));
+ GRN_OBJ_FIN(ctx, snip_ptr);
+ GRN_PTR_INIT(snip_ptr, GRN_OBJ_OWN, GRN_DB_OBJECT);
+
+ snip = grn_snip_open(ctx, flags, width, max_n_results,
+ open_tag, strlen(open_tag),
+ close_tag, strlen(close_tag),
+ mapping);
+ if (snip) {
+ grn_snip_set_normalizer(ctx, snip, GRN_NORMALIZER_AUTO);
+ grn_expr_snip_add_conditions(ctx, condition, snip,
+ 0, NULL, NULL, NULL, NULL);
+ GRN_PTR_SET(ctx, snip_ptr, snip);
+ }
+ }
+ }
+
+ if (snip) {
+ snippets = snippet_exec(ctx, snip, text, user_data, NULL, 0, NULL, 0);
+ }
+ }
+
+ if (!snippets) {
+ snippets = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_VOID, 0);
+ }
+
+ return snippets;
+}
+
+void
+grn_proc_init_snippet_html(grn_ctx *ctx)
+{
+ grn_proc_create(ctx, "snippet_html", -1, GRN_PROC_FUNCTION,
+ func_snippet_html, NULL, NULL, 0, NULL);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_table.c b/storage/mroonga/vendor/groonga/lib/proc/proc_table.c
new file mode 100644
index 00000000000..3501555969c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_table.c
@@ -0,0 +1,910 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+
+#include "../grn_ctx.h"
+#include "../grn_str.h"
+#include "../grn_db.h"
+
+#include <groonga/plugin.h>
+
+static grn_table_flags
+command_table_create_parse_flags(grn_ctx *ctx,
+ const char *nptr,
+ const char *end)
+{
+ grn_table_flags flags = 0;
+ while (nptr < end) {
+ size_t name_size;
+
+ if (*nptr == '|' || *nptr == ' ') {
+ nptr += 1;
+ continue;
+ }
+
+#define CHECK_FLAG(name) \
+ name_size = strlen(#name); \
+ if ((end - nptr) >= name_size && \
+ memcmp(nptr, #name, name_size) == 0) { \
+ flags |= GRN_OBJ_ ## name; \
+ nptr += name_size; \
+ continue; \
+ }
+
+ CHECK_FLAG(TABLE_HASH_KEY);
+ CHECK_FLAG(TABLE_PAT_KEY);
+ CHECK_FLAG(TABLE_DAT_KEY);
+ CHECK_FLAG(TABLE_NO_KEY);
+ CHECK_FLAG(KEY_NORMALIZE);
+ CHECK_FLAG(KEY_WITH_SIS);
+ CHECK_FLAG(KEY_LARGE);
+
+#undef CHECK_FLAG
+
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][create][flags] unknown flag: <%.*s>",
+ (int)(end - nptr), nptr);
+ return 0;
+ }
+ return flags;
+}
+
+static grn_bool
+grn_proc_table_set_token_filters_put(grn_ctx *ctx,
+ grn_obj *token_filters,
+ const char *token_filter_name,
+ int token_filter_name_length)
+{
+ grn_obj *token_filter;
+
+ token_filter = grn_ctx_get(ctx,
+ token_filter_name,
+ token_filter_name_length);
+ if (token_filter) {
+ GRN_PTR_PUT(ctx, token_filters, token_filter);
+ return GRN_TRUE;
+ } else {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][create][token-filter] "
+ "nonexistent token filter: <%.*s>",
+ token_filter_name_length, token_filter_name);
+ return GRN_FALSE;
+ }
+}
+
+static grn_bool
+grn_proc_table_set_token_filters_fill(grn_ctx *ctx,
+ grn_obj *token_filters,
+ grn_obj *token_filter_names)
+{
+ const char *start, *current, *end;
+ const char *name_start, *name_end;
+ const char *last_name_end;
+
+ start = GRN_TEXT_VALUE(token_filter_names);
+ end = start + GRN_TEXT_LEN(token_filter_names);
+ current = start;
+ name_start = NULL;
+ name_end = NULL;
+ last_name_end = start;
+ while (current < end) {
+ switch (current[0]) {
+ case ' ' :
+ if (name_start && !name_end) {
+ name_end = current;
+ }
+ break;
+ case ',' :
+ if (!name_start) {
+ goto break_loop;
+ }
+ if (!name_end) {
+ name_end = current;
+ }
+ if (!grn_proc_table_set_token_filters_put(ctx,
+ token_filters,
+ name_start,
+ name_end - name_start)) {
+ return GRN_FALSE;
+ }
+ last_name_end = name_end + 1;
+ name_start = NULL;
+ name_end = NULL;
+ break;
+ default :
+ if (!name_start) {
+ name_start = current;
+ }
+ break;
+ }
+ current++;
+ }
+
+break_loop:
+ if (!name_start) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][create][token-filter] empty token filter name: "
+ "<%.*s|%.*s|%.*s>",
+ (int)(last_name_end - start), start,
+ (int)(current - last_name_end), last_name_end,
+ (int)(end - current), current);
+ return GRN_FALSE;
+ }
+
+ if (!name_end) {
+ name_end = current;
+ }
+ grn_proc_table_set_token_filters_put(ctx,
+ token_filters,
+ name_start,
+ name_end - name_start);
+
+ return GRN_TRUE;
+}
+
+grn_bool
+grn_proc_table_set_token_filters(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *token_filter_names)
+{
+ grn_bool succeeded = GRN_FALSE;
+ grn_obj token_filters;
+
+ if (GRN_TEXT_LEN(token_filter_names) == 0) {
+ return GRN_TRUE;
+ }
+
+ GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, 0);
+ succeeded = grn_proc_table_set_token_filters_fill(ctx,
+ &token_filters,
+ token_filter_names);
+ if (succeeded) {
+ grn_obj_set_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters);
+ }
+ grn_obj_unlink(ctx, &token_filters);
+
+ return succeeded;
+}
+
+static grn_obj *
+command_table_create(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *name;
+ grn_obj *flags_raw;
+ grn_obj *key_type_name;
+ grn_obj *value_type_name;
+ grn_obj *default_tokenizer_name;
+ grn_obj *normalizer_name;
+ grn_obj *token_filters_name;
+ grn_obj *table;
+ const char *rest;
+ grn_table_flags flags;
+
+ name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+ flags_raw = grn_plugin_proc_get_var(ctx, user_data, "flags", -1);
+ key_type_name = grn_plugin_proc_get_var(ctx, user_data, "key_type", -1);
+ value_type_name = grn_plugin_proc_get_var(ctx, user_data, "value_type", -1);
+ default_tokenizer_name =
+ grn_plugin_proc_get_var(ctx, user_data, "default_tokenizer", -1);
+ normalizer_name =
+ grn_plugin_proc_get_var(ctx, user_data, "normalizer", -1);
+ token_filters_name =
+ grn_plugin_proc_get_var(ctx, user_data, "token_filters", -1);
+
+ flags = grn_atoi(GRN_TEXT_VALUE(flags_raw),
+ GRN_BULK_CURR(flags_raw),
+ &rest);
+
+ if (GRN_TEXT_VALUE(flags_raw) == rest) {
+ flags = command_table_create_parse_flags(ctx,
+ GRN_TEXT_VALUE(flags_raw),
+ GRN_BULK_CURR(flags_raw));
+ if (ctx->rc) { goto exit; }
+ }
+
+ if (GRN_TEXT_LEN(name) == 0) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][create] should not create anonymous table");
+ goto exit;
+ }
+
+ {
+ grn_obj *key_type = NULL;
+ grn_obj *value_type = NULL;
+
+ if (GRN_TEXT_LEN(key_type_name) > 0) {
+ key_type = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(key_type_name),
+ GRN_TEXT_LEN(key_type_name));
+ if (!key_type) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][create] "
+ "key type doesn't exist: <%.*s> (%.*s)",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name),
+ (int)GRN_TEXT_LEN(key_type_name),
+ GRN_TEXT_VALUE(key_type_name));
+ goto exit;
+ }
+ }
+
+ if (GRN_TEXT_LEN(value_type_name) > 0) {
+ value_type = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(value_type_name),
+ GRN_TEXT_LEN(value_type_name));
+ if (!value_type) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][create] "
+ "value type doesn't exist: <%.*s> (%.*s)",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name),
+ (int)GRN_TEXT_LEN(value_type_name),
+ GRN_TEXT_VALUE(value_type_name));
+ goto exit;
+ }
+ }
+
+ flags |= GRN_OBJ_PERSISTENT;
+ table = grn_table_create(ctx,
+ GRN_TEXT_VALUE(name),
+ GRN_TEXT_LEN(name),
+ NULL, flags,
+ key_type,
+ value_type);
+ if (!table) {
+ goto exit;
+ }
+
+ if (GRN_TEXT_LEN(default_tokenizer_name) > 0) {
+ grn_obj *default_tokenizer;
+
+ default_tokenizer =
+ grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(default_tokenizer_name),
+ GRN_TEXT_LEN(default_tokenizer_name));
+ if (!default_tokenizer) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][create][%.*s] unknown tokenizer: <%.*s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name),
+ (int)GRN_TEXT_LEN(default_tokenizer_name),
+ GRN_TEXT_VALUE(default_tokenizer_name));
+ grn_obj_remove(ctx, table);
+ goto exit;
+ }
+ grn_obj_set_info(ctx, table,
+ GRN_INFO_DEFAULT_TOKENIZER,
+ default_tokenizer);
+ }
+
+ if (GRN_TEXT_LEN(normalizer_name) > 0) {
+ grn_obj *normalizer;
+
+ normalizer =
+ grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(normalizer_name),
+ GRN_TEXT_LEN(normalizer_name));
+ if (!normalizer) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][create][%.*s] unknown normalizer: <%.*s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name),
+ (int)GRN_TEXT_LEN(normalizer_name),
+ GRN_TEXT_VALUE(normalizer_name));
+ grn_obj_remove(ctx, table);
+ goto exit;
+ }
+ grn_obj_set_info(ctx, table, GRN_INFO_NORMALIZER, normalizer);
+ }
+
+ if (!grn_proc_table_set_token_filters(ctx, table, token_filters_name)) {
+ grn_obj_remove(ctx, table);
+ goto exit;
+ }
+
+ grn_obj_unlink(ctx, table);
+ }
+
+exit :
+ grn_ctx_output_bool(ctx, ctx->rc == GRN_SUCCESS);
+ return NULL;
+}
+
+void
+grn_proc_init_table_create(grn_ctx *ctx)
+{
+ grn_expr_var vars[7];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "name", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "flags", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[2]), "key_type", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[3]), "value_type", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[4]), "default_tokenizer", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[5]), "normalizer", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[6]), "token_filters", -1);
+ grn_plugin_command_create(ctx,
+ "table_create", -1,
+ command_table_create,
+ 7,
+ vars);
+}
+
+static int
+output_table_info(grn_ctx *ctx, grn_obj *table)
+{
+ grn_id id;
+ grn_obj o;
+ const char *path;
+ grn_table_flags flags;
+ grn_obj *default_tokenizer;
+ grn_obj *normalizer;
+ grn_obj *token_filters;
+
+ id = grn_obj_id(ctx, table);
+ path = grn_obj_path(ctx, table);
+ GRN_TEXT_INIT(&o, 0);
+ grn_ctx_output_array_open(ctx, "TABLE", 8);
+ grn_ctx_output_int64(ctx, id);
+ grn_proc_output_object_id_name(ctx, id);
+ grn_ctx_output_cstr(ctx, path);
+ GRN_BULK_REWIND(&o);
+
+ grn_table_get_info(ctx, table,
+ &flags,
+ NULL,
+ &default_tokenizer,
+ &normalizer,
+ &token_filters);
+ grn_dump_table_create_flags(ctx, flags, &o);
+ grn_ctx_output_obj(ctx, &o, NULL);
+ grn_proc_output_object_id_name(ctx, table->header.domain);
+ grn_proc_output_object_id_name(ctx, grn_obj_get_range(ctx, table));
+ grn_proc_output_object_name(ctx, default_tokenizer);
+ grn_proc_output_object_name(ctx, normalizer);
+ grn_ctx_output_array_close(ctx);
+ GRN_OBJ_FIN(ctx, &o);
+ return 1;
+}
+
+static grn_obj *
+command_table_list(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *db;
+ grn_obj tables;
+ int n_top_level_elements;
+ int n_elements_for_header = 1;
+ int n_tables;
+ int i;
+
+ db = grn_ctx_db(ctx);
+
+ {
+ grn_table_cursor *cursor;
+ grn_id id;
+ grn_obj *prefix;
+ const void *min = NULL;
+ unsigned int min_size = 0;
+ int flags = 0;
+
+ prefix = grn_plugin_proc_get_var(ctx, user_data, "prefix", -1);
+ if (GRN_TEXT_LEN(prefix) > 0) {
+ min = GRN_TEXT_VALUE(prefix);
+ min_size = GRN_TEXT_LEN(prefix);
+ flags |= GRN_CURSOR_PREFIX;
+ }
+ cursor = grn_table_cursor_open(ctx, db,
+ min, min_size,
+ NULL, 0,
+ 0, -1, flags);
+ if (!cursor) {
+ return NULL;
+ }
+
+ GRN_PTR_INIT(&tables, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ grn_obj *object;
+ const char *name;
+ void *key;
+ int i, key_size;
+ grn_bool have_period = GRN_FALSE;
+
+ key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+ name = key;
+ for (i = 0; i < key_size; i++) {
+ if (name[i] == '.') {
+ have_period = GRN_TRUE;
+ break;
+ }
+ }
+ if (have_period) {
+ continue;
+ }
+
+ object = grn_ctx_at(ctx, id);
+ if (object) {
+ if (grn_obj_is_table(ctx, object)) {
+ GRN_PTR_PUT(ctx, &tables, object);
+ } else {
+ grn_obj_unlink(ctx, object);
+ }
+ } else {
+ if (ctx->rc != GRN_SUCCESS) {
+ ERRCLR(ctx);
+ }
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+ }
+ n_tables = GRN_BULK_VSIZE(&tables) / sizeof(grn_obj *);
+ n_top_level_elements = n_elements_for_header + n_tables;
+ grn_ctx_output_array_open(ctx, "TABLE_LIST", n_top_level_elements);
+
+ grn_ctx_output_array_open(ctx, "HEADER", 8);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "id");
+ grn_ctx_output_cstr(ctx, "UInt32");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "name");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "path");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "flags");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "domain");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "range");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "default_tokenizer");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+ grn_ctx_output_cstr(ctx, "normalizer");
+ grn_ctx_output_cstr(ctx, "ShortText");
+ grn_ctx_output_array_close(ctx);
+ grn_ctx_output_array_close(ctx);
+
+ for (i = 0; i < n_tables; i++) {
+ grn_obj *table = GRN_PTR_VALUE_AT(&tables, i);
+ output_table_info(ctx, table);
+ grn_obj_unlink(ctx, table);
+ }
+ GRN_OBJ_FIN(ctx, &tables);
+
+ grn_ctx_output_array_close(ctx);
+
+ return NULL;
+}
+
+void
+grn_proc_init_table_list(grn_ctx *ctx)
+{
+ grn_expr_var vars[1];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "prefix", -1);
+ grn_plugin_command_create(ctx,
+ "table_list", -1,
+ command_table_list,
+ 1,
+ vars);
+}
+
+static grn_obj *
+command_table_remove(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *name;
+ grn_obj *table;
+ grn_bool dependent;
+
+ name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+ dependent = grn_plugin_proc_get_var_bool(ctx, user_data, "dependent", -1,
+ GRN_FALSE);
+ table = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(name),
+ GRN_TEXT_LEN(name));
+ if (!table) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][remove] table isn't found: <%.*s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ grn_ctx_output_bool(ctx, GRN_FALSE);
+ return NULL;
+ }
+
+ if (!grn_obj_is_table(ctx, table)) {
+ const char *type_name;
+ type_name = grn_obj_type_to_string(table->header.type);
+ grn_obj_unlink(ctx, table);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][remove] not table: <%.*s>: <%s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name),
+ type_name);
+ grn_ctx_output_bool(ctx, GRN_FALSE);
+ return NULL;
+ }
+
+ if (dependent) {
+ grn_obj_remove_dependent(ctx, table);
+ } else {
+ grn_obj_remove(ctx, table);
+ }
+ grn_ctx_output_bool(ctx, !ctx->rc);
+ return NULL;
+}
+
+void
+grn_proc_init_table_remove(grn_ctx *ctx)
+{
+ grn_expr_var vars[2];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "name", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "dependent", -1);
+ grn_plugin_command_create(ctx,
+ "table_remove", -1,
+ command_table_remove,
+ 2,
+ vars);
+}
+
+static grn_obj *
+command_table_rename(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *name;
+ grn_obj *new_name;
+ grn_obj *table = NULL;
+
+ name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+ new_name = grn_plugin_proc_get_var(ctx, user_data, "new_name", -1);
+ if (GRN_TEXT_LEN(name) == 0) {
+ rc = GRN_INVALID_ARGUMENT;
+ GRN_PLUGIN_ERROR(ctx, rc, "[table][rename] table name isn't specified");
+ goto exit;
+ }
+ table = grn_ctx_get(ctx, GRN_TEXT_VALUE(name), GRN_TEXT_LEN(name));
+ if (!table) {
+ rc = GRN_INVALID_ARGUMENT;
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[table][rename] table isn't found: <%.*s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ goto exit;
+ }
+ if (GRN_TEXT_LEN(new_name) == 0) {
+ rc = GRN_INVALID_ARGUMENT;
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[table][rename] new table name isn't specified: <%.*s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ goto exit;
+ }
+ rc = grn_table_rename(ctx, table,
+ GRN_TEXT_VALUE(new_name),
+ GRN_TEXT_LEN(new_name));
+ if (rc != GRN_SUCCESS && ctx->rc == GRN_SUCCESS) {
+ GRN_PLUGIN_ERROR(ctx,
+ rc,
+ "[table][rename] failed to rename: <%.*s> -> <%.*s>",
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name),
+ (int)GRN_TEXT_LEN(new_name),
+ GRN_TEXT_VALUE(new_name));
+ }
+exit :
+ grn_ctx_output_bool(ctx, !rc);
+ if (table) { grn_obj_unlink(ctx, table); }
+ return NULL;
+}
+
+void
+grn_proc_init_table_rename(grn_ctx *ctx)
+{
+ grn_expr_var vars[2];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "name", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "new_name", -1);
+ grn_plugin_command_create(ctx,
+ "table_rename", -1,
+ command_table_rename,
+ 2,
+ vars);
+}
+
+static grn_rc
+command_table_copy_resolve_target(grn_ctx *ctx,
+ const char *label,
+ grn_obj *name,
+ grn_obj **table)
+{
+ if (GRN_TEXT_LEN(name) == 0) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][copy] %s name isn't specified",
+ label);
+ return ctx->rc;
+ }
+ *table = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(name),
+ GRN_TEXT_LEN(name));
+ if (!*table) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][copy] %s table isn't found: <%.*s>",
+ label,
+ (int)GRN_TEXT_LEN(name),
+ GRN_TEXT_VALUE(name));
+ return ctx->rc;
+ }
+
+ return ctx->rc;
+}
+
+static void
+command_table_copy_same_key_type(grn_ctx *ctx,
+ grn_obj *from_table,
+ grn_obj *to_table,
+ grn_obj *from_name,
+ grn_obj *to_name)
+{
+ GRN_TABLE_EACH_BEGIN_FLAGS(ctx, from_table, cursor, from_id,
+ GRN_CURSOR_BY_KEY | GRN_CURSOR_ASCENDING) {
+ void *key;
+ int key_size;
+ grn_id to_id;
+
+ key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+ to_id = grn_table_add(ctx, to_table, key, key_size, NULL);
+ if (to_id == GRN_ID_NIL) {
+ grn_obj key_buffer;
+ grn_obj inspected_key;
+ if (from_table->header.domain == GRN_DB_SHORT_TEXT) {
+ GRN_SHORT_TEXT_INIT(&key_buffer, 0);
+ } else {
+ GRN_VALUE_FIX_SIZE_INIT(&key_buffer, 0, from_table->header.domain);
+ }
+ grn_bulk_write(ctx, &key_buffer, key, key_size);
+ GRN_TEXT_INIT(&inspected_key, 0);
+ grn_inspect(ctx, &inspected_key, &key_buffer);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][copy] failed to copy key: <%.*s>: "
+ "<%.*s> -> <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected_key),
+ GRN_TEXT_VALUE(&inspected_key),
+ (int)GRN_TEXT_LEN(from_name),
+ GRN_TEXT_VALUE(from_name),
+ (int)GRN_TEXT_LEN(to_name),
+ GRN_TEXT_VALUE(to_name));
+ GRN_OBJ_FIN(ctx, &inspected_key);
+ GRN_OBJ_FIN(ctx, &key_buffer);
+ break;
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+}
+
+static void
+command_table_copy_different(grn_ctx *ctx,
+ grn_obj *from_table,
+ grn_obj *to_table,
+ grn_obj *from_name,
+ grn_obj *to_name)
+{
+ grn_obj from_key_buffer;
+ grn_obj to_key_buffer;
+
+ if (from_table->header.domain == GRN_DB_SHORT_TEXT) {
+ GRN_SHORT_TEXT_INIT(&from_key_buffer, 0);
+ } else {
+ GRN_VALUE_FIX_SIZE_INIT(&from_key_buffer, 0, from_table->header.domain);
+ }
+ if (to_table->header.domain == GRN_DB_SHORT_TEXT) {
+ GRN_SHORT_TEXT_INIT(&to_key_buffer, 0);
+ } else {
+ GRN_VALUE_FIX_SIZE_INIT(&to_key_buffer, 0, to_table->header.domain);
+ }
+
+ GRN_TABLE_EACH_BEGIN_FLAGS(ctx, from_table, cursor, from_id,
+ GRN_CURSOR_BY_KEY | GRN_CURSOR_ASCENDING) {
+ void *key;
+ int key_size;
+ grn_rc cast_rc;
+ grn_id to_id;
+
+ GRN_BULK_REWIND(&from_key_buffer);
+ GRN_BULK_REWIND(&to_key_buffer);
+
+ key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+ grn_bulk_write(ctx, &from_key_buffer, key, key_size);
+ cast_rc = grn_obj_cast(ctx, &from_key_buffer, &to_key_buffer, GRN_FALSE);
+ if (cast_rc != GRN_SUCCESS) {
+ grn_obj *to_key_type;
+ grn_obj inspected_key;
+ grn_obj inspected_to_key_type;
+
+ to_key_type = grn_ctx_at(ctx, to_table->header.domain);
+ GRN_TEXT_INIT(&inspected_key, 0);
+ GRN_TEXT_INIT(&inspected_to_key_type, 0);
+ grn_inspect(ctx, &inspected_key, &from_key_buffer);
+ grn_inspect(ctx, &inspected_to_key_type, to_key_type);
+ ERR(cast_rc,
+ "[table][copy] failed to cast key: <%.*s> -> %.*s: "
+ "<%.*s> -> <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected_key),
+ GRN_TEXT_VALUE(&inspected_key),
+ (int)GRN_TEXT_LEN(&inspected_to_key_type),
+ GRN_TEXT_VALUE(&inspected_to_key_type),
+ (int)GRN_TEXT_LEN(from_name),
+ GRN_TEXT_VALUE(from_name),
+ (int)GRN_TEXT_LEN(to_name),
+ GRN_TEXT_VALUE(to_name));
+ GRN_OBJ_FIN(ctx, &inspected_key);
+ GRN_OBJ_FIN(ctx, &inspected_to_key_type);
+ break;
+ }
+
+ to_id = grn_table_add(ctx, to_table,
+ GRN_BULK_HEAD(&to_key_buffer),
+ GRN_BULK_VSIZE(&to_key_buffer),
+ NULL);
+ if (to_id == GRN_ID_NIL) {
+ grn_obj inspected_from_key;
+ grn_obj inspected_to_key;
+ GRN_TEXT_INIT(&inspected_from_key, 0);
+ GRN_TEXT_INIT(&inspected_to_key, 0);
+ grn_inspect(ctx, &inspected_from_key, &from_key_buffer);
+ grn_inspect(ctx, &inspected_to_key, &to_key_buffer);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "[table][copy] failed to copy key: <%.*s> -> <%.*s>: "
+ "<%.*s> -> <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected_from_key),
+ GRN_TEXT_VALUE(&inspected_from_key),
+ (int)GRN_TEXT_LEN(&inspected_to_key),
+ GRN_TEXT_VALUE(&inspected_to_key),
+ (int)GRN_TEXT_LEN(from_name),
+ GRN_TEXT_VALUE(from_name),
+ (int)GRN_TEXT_LEN(to_name),
+ GRN_TEXT_VALUE(to_name));
+ GRN_OBJ_FIN(ctx, &inspected_from_key);
+ GRN_OBJ_FIN(ctx, &inspected_to_key);
+ break;
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ GRN_OBJ_FIN(ctx, &from_key_buffer);
+ GRN_OBJ_FIN(ctx, &to_key_buffer);
+}
+
+static grn_obj *
+command_table_copy(grn_ctx *ctx,
+ int nargs,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *from_table = NULL;
+ grn_obj *to_table = NULL;
+ grn_obj *from_name;
+ grn_obj *to_name;
+
+ from_name = grn_plugin_proc_get_var(ctx, user_data, "from_name", -1);
+ to_name = grn_plugin_proc_get_var(ctx, user_data, "to_name", -1);
+
+ rc = command_table_copy_resolve_target(ctx, "from", from_name, &from_table);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ rc = command_table_copy_resolve_target(ctx, "to", to_name, &to_table);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+
+ if (from_table->header.type == GRN_TABLE_NO_KEY ||
+ to_table->header.type == GRN_TABLE_NO_KEY) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_OPERATION_NOT_SUPPORTED,
+ "[table][copy] copy from/to TABLE_NO_KEY isn't supported: "
+ "<%.*s> -> <%.*s>",
+ (int)GRN_TEXT_LEN(from_name),
+ GRN_TEXT_VALUE(from_name),
+ (int)GRN_TEXT_LEN(to_name),
+ GRN_TEXT_VALUE(to_name));
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ if (from_table == to_table) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_OPERATION_NOT_SUPPORTED,
+ "[table][copy] from table and to table is the same: "
+ "<%.*s>",
+ (int)GRN_TEXT_LEN(from_name),
+ GRN_TEXT_VALUE(from_name));
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ if (from_table->header.domain == to_table->header.domain) {
+ command_table_copy_same_key_type(ctx,
+ from_table, to_table,
+ from_name, to_name);
+ } else {
+ command_table_copy_different(ctx,
+ from_table, to_table,
+ from_name, to_name);
+ }
+
+exit :
+ grn_ctx_output_bool(ctx, rc == GRN_SUCCESS);
+
+ if (to_table) {
+ grn_obj_unlink(ctx, to_table);
+ }
+ if (from_table) {
+ grn_obj_unlink(ctx, from_table);
+ }
+
+ return NULL;
+}
+
+void
+grn_proc_init_table_copy(grn_ctx *ctx)
+{
+ grn_expr_var vars[2];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "from_name", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "to_name", -1);
+ grn_plugin_command_create(ctx,
+ "table_copy", -1,
+ command_table_copy,
+ 2,
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_tokenize.c b/storage/mroonga/vendor/groonga/lib/proc/proc_tokenize.c
new file mode 100644
index 00000000000..cf65b13ee5a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_tokenize.c
@@ -0,0 +1,433 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_proc.h"
+#include "../grn_ctx.h"
+#include "../grn_token_cursor.h"
+
+#include <groonga/plugin.h>
+
+static unsigned int
+parse_tokenize_flags(grn_ctx *ctx, grn_obj *flag_names)
+{
+ unsigned int flags = 0;
+ const char *names, *names_end;
+ int length;
+
+ names = GRN_TEXT_VALUE(flag_names);
+ length = GRN_TEXT_LEN(flag_names);
+ names_end = names + length;
+ while (names < names_end) {
+ if (*names == '|' || *names == ' ') {
+ names += 1;
+ continue;
+ }
+
+#define CHECK_FLAG(name)\
+ if (((names_end - names) >= (sizeof(#name) - 1)) &&\
+ (!memcmp(names, #name, sizeof(#name) - 1))) {\
+ flags |= GRN_TOKEN_CURSOR_ ## name;\
+ names += sizeof(#name) - 1;\
+ continue;\
+ }
+
+ CHECK_FLAG(ENABLE_TOKENIZED_DELIMITER);
+
+#define GRN_TOKEN_CURSOR_NONE 0
+ CHECK_FLAG(NONE);
+#undef GRN_TOKEN_CURSOR_NONE
+
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[tokenize] invalid flag: <%.*s>",
+ (int)(names_end - names), names);
+ return 0;
+#undef CHECK_FLAG
+ }
+
+ return flags;
+}
+
+typedef struct {
+ grn_id id;
+ int32_t position;
+ grn_bool force_prefix;
+} tokenize_token;
+
+static void
+output_tokens(grn_ctx *ctx, grn_obj *tokens, grn_obj *lexicon, grn_obj *index_column)
+{
+ int i, n_tokens, n_elements;
+ grn_obj estimated_size;
+
+ n_tokens = GRN_BULK_VSIZE(tokens) / sizeof(tokenize_token);
+ n_elements = 3;
+ if (index_column) {
+ n_elements++;
+ GRN_UINT32_INIT(&estimated_size, 0);
+ }
+
+ grn_ctx_output_array_open(ctx, "TOKENS", n_tokens);
+ for (i = 0; i < n_tokens; i++) {
+ tokenize_token *token;
+ char value[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int value_size;
+
+ token = ((tokenize_token *)(GRN_BULK_HEAD(tokens))) + i;
+
+ grn_ctx_output_map_open(ctx, "TOKEN", n_elements);
+
+ grn_ctx_output_cstr(ctx, "value");
+ value_size = grn_table_get_key(ctx, lexicon, token->id,
+ value, GRN_TABLE_MAX_KEY_SIZE);
+ grn_ctx_output_str(ctx, value, value_size);
+
+ grn_ctx_output_cstr(ctx, "position");
+ grn_ctx_output_int32(ctx, token->position);
+
+ grn_ctx_output_cstr(ctx, "force_prefix");
+ grn_ctx_output_bool(ctx, token->force_prefix);
+
+ if (index_column) {
+ GRN_BULK_REWIND(&estimated_size);
+ grn_obj_get_value(ctx, index_column, token->id, &estimated_size);
+ grn_ctx_output_cstr(ctx, "estimated_size");
+ grn_ctx_output_int64(ctx, GRN_UINT32_VALUE(&estimated_size));
+ }
+
+ grn_ctx_output_map_close(ctx);
+ }
+
+ if (index_column) {
+ GRN_OBJ_FIN(ctx, &estimated_size);
+ }
+
+ grn_ctx_output_array_close(ctx);
+}
+
+static grn_obj *
+create_lexicon_for_tokenize(grn_ctx *ctx,
+ grn_obj *tokenizer_name,
+ grn_obj *normalizer_name,
+ grn_obj *token_filter_names)
+{
+ grn_obj *lexicon;
+ grn_obj *tokenizer;
+ grn_obj *normalizer = NULL;
+
+ tokenizer = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(tokenizer_name),
+ GRN_TEXT_LEN(tokenizer_name));
+ if (!tokenizer) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[tokenize] nonexistent tokenizer: <%.*s>",
+ (int)GRN_TEXT_LEN(tokenizer_name),
+ GRN_TEXT_VALUE(tokenizer_name));
+ return NULL;
+ }
+
+ if (!grn_obj_is_tokenizer_proc(ctx, tokenizer)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, tokenizer);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[tokenize] not tokenizer: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ grn_obj_unlink(ctx, tokenizer);
+ return NULL;
+ }
+
+ if (GRN_TEXT_LEN(normalizer_name) > 0) {
+ normalizer = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(normalizer_name),
+ GRN_TEXT_LEN(normalizer_name));
+ if (!normalizer) {
+ grn_obj_unlink(ctx, tokenizer);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[tokenize] nonexistent normalizer: <%.*s>",
+ (int)GRN_TEXT_LEN(normalizer_name),
+ GRN_TEXT_VALUE(normalizer_name));
+ return NULL;
+ }
+
+ if (!grn_obj_is_normalizer_proc(ctx, normalizer)) {
+ grn_obj inspected;
+ grn_obj_unlink(ctx, tokenizer);
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, normalizer);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[tokenize] not normalizer: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ grn_obj_unlink(ctx, normalizer);
+ return NULL;
+ }
+ }
+
+ lexicon = grn_table_create(ctx, NULL, 0,
+ NULL,
+ GRN_OBJ_TABLE_HASH_KEY,
+ grn_ctx_at(ctx, GRN_DB_SHORT_TEXT),
+ NULL);
+ grn_obj_set_info(ctx, lexicon,
+ GRN_INFO_DEFAULT_TOKENIZER, tokenizer);
+ grn_obj_unlink(ctx, tokenizer);
+ if (normalizer) {
+ grn_obj_set_info(ctx, lexicon,
+ GRN_INFO_NORMALIZER, normalizer);
+ grn_obj_unlink(ctx, normalizer);
+ }
+ grn_proc_table_set_token_filters(ctx, lexicon, token_filter_names);
+
+ return lexicon;
+}
+
+static void
+tokenize(grn_ctx *ctx, grn_obj *lexicon, grn_obj *string, grn_tokenize_mode mode,
+ unsigned int flags, grn_obj *tokens)
+{
+ grn_token_cursor *token_cursor;
+
+ token_cursor =
+ grn_token_cursor_open(ctx, lexicon,
+ GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string),
+ mode, flags);
+ if (!token_cursor) {
+ return;
+ }
+
+ while (token_cursor->status == GRN_TOKEN_CURSOR_DOING) {
+ grn_id token_id = grn_token_cursor_next(ctx, token_cursor);
+ tokenize_token *current_token;
+ if (token_id == GRN_ID_NIL) {
+ continue;
+ }
+ grn_bulk_space(ctx, tokens, sizeof(tokenize_token));
+ current_token = ((tokenize_token *)(GRN_BULK_CURR(tokens))) - 1;
+ current_token->id = token_id;
+ current_token->position = token_cursor->pos;
+ current_token->force_prefix = token_cursor->force_prefix;
+ }
+ grn_token_cursor_close(ctx, token_cursor);
+}
+
+static grn_obj *
+command_table_tokenize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *table_name;
+ grn_obj *string;
+ grn_obj *flag_names;
+ grn_obj *mode_name;
+ grn_obj *index_column_name;
+
+ table_name = grn_plugin_proc_get_var(ctx, user_data, "table", -1);
+ string = grn_plugin_proc_get_var(ctx, user_data, "string", -1);
+ flag_names = grn_plugin_proc_get_var(ctx, user_data, "flags", -1);
+ mode_name = grn_plugin_proc_get_var(ctx, user_data, "mode", -1);
+ index_column_name = grn_plugin_proc_get_var(ctx, user_data, "index_column", -1);
+
+ if (GRN_TEXT_LEN(table_name) == 0) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] table name is missing");
+ return NULL;
+ }
+
+ if (GRN_TEXT_LEN(string) == 0) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] string is missing");
+ return NULL;
+ }
+
+ {
+ unsigned int flags;
+ grn_obj *lexicon;
+ grn_obj *index_column = NULL;
+
+ flags = parse_tokenize_flags(ctx, flag_names);
+ if (ctx->rc != GRN_SUCCESS) {
+ return NULL;
+ }
+
+ lexicon = grn_ctx_get(ctx, GRN_TEXT_VALUE(table_name), GRN_TEXT_LEN(table_name));
+ if (!lexicon) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[table_tokenize] nonexistent lexicon: <%.*s>",
+ (int)GRN_TEXT_LEN(table_name),
+ GRN_TEXT_VALUE(table_name));
+ return NULL;
+ }
+
+#define MODE_NAME_EQUAL(name)\
+ (GRN_TEXT_LEN(mode_name) == strlen(name) &&\
+ memcmp(GRN_TEXT_VALUE(mode_name), name, strlen(name)) == 0)
+
+ if (GRN_TEXT_LEN(index_column_name) > 0) {
+ index_column = grn_obj_column(ctx, lexicon,
+ GRN_TEXT_VALUE(index_column_name),
+ GRN_TEXT_LEN(index_column_name));
+ if (!index_column) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[table_tokenize] nonexistent index column: <%.*s>",
+ (int)GRN_TEXT_LEN(index_column_name),
+ GRN_TEXT_VALUE(index_column_name));
+ goto exit;
+ }
+ if (index_column->header.type != GRN_COLUMN_INDEX) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[table_tokenize] index column must be COLUMN_INDEX: <%.*s>",
+ (int)GRN_TEXT_LEN(index_column_name),
+ GRN_TEXT_VALUE(index_column_name));
+ goto exit;
+ }
+ }
+
+ {
+ grn_obj tokens;
+ GRN_VALUE_FIX_SIZE_INIT(&tokens, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ if (GRN_TEXT_LEN(mode_name) == 0 || MODE_NAME_EQUAL("GET")) {
+ tokenize(ctx, lexicon, string, GRN_TOKEN_GET, flags, &tokens);
+ output_tokens(ctx, &tokens, lexicon, index_column);
+ } else if (MODE_NAME_EQUAL("ADD")) {
+ tokenize(ctx, lexicon, string, GRN_TOKEN_ADD, flags, &tokens);
+ output_tokens(ctx, &tokens, lexicon, index_column);
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[table_tokenize] invalid mode: <%.*s>",
+ (int)GRN_TEXT_LEN(mode_name), GRN_TEXT_VALUE(mode_name));
+ }
+ GRN_OBJ_FIN(ctx, &tokens);
+ }
+#undef MODE_NAME_EQUAL
+
+exit:
+ grn_obj_unlink(ctx, lexicon);
+ if (index_column) {
+ grn_obj_unlink(ctx, index_column);
+ }
+ }
+
+ return NULL;
+}
+
+void
+grn_proc_init_table_tokenize(grn_ctx *ctx)
+{
+ grn_expr_var vars[5];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "table", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "string", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[2]), "flags", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[3]), "mode", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[4]), "index_column", -1);
+ grn_plugin_command_create(ctx,
+ "table_tokenize", -1,
+ command_table_tokenize,
+ 5,
+ vars);
+}
+
+static grn_obj *
+command_tokenize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *tokenizer_name;
+ grn_obj *string;
+ grn_obj *normalizer_name;
+ grn_obj *flag_names;
+ grn_obj *mode_name;
+ grn_obj *token_filter_names;
+
+ tokenizer_name = grn_plugin_proc_get_var(ctx, user_data, "tokenizer", -1);
+ string = grn_plugin_proc_get_var(ctx, user_data, "string", -1);
+ normalizer_name = grn_plugin_proc_get_var(ctx, user_data, "normalizer", -1);
+ flag_names = grn_plugin_proc_get_var(ctx, user_data, "flags", -1);
+ mode_name = grn_plugin_proc_get_var(ctx, user_data, "mode", -1);
+ token_filter_names = grn_plugin_proc_get_var(ctx, user_data, "token_filters", -1);
+
+ if (GRN_TEXT_LEN(tokenizer_name) == 0) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[tokenize] tokenizer name is missing");
+ return NULL;
+ }
+
+ if (GRN_TEXT_LEN(string) == 0) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[tokenize] string is missing");
+ return NULL;
+ }
+
+ {
+ unsigned int flags;
+ grn_obj *lexicon;
+
+ flags = parse_tokenize_flags(ctx, flag_names);
+ if (ctx->rc != GRN_SUCCESS) {
+ return NULL;
+ }
+
+ lexicon = create_lexicon_for_tokenize(ctx,
+ tokenizer_name,
+ normalizer_name,
+ token_filter_names);
+ if (!lexicon) {
+ return NULL;
+ }
+#define MODE_NAME_EQUAL(name)\
+ (GRN_TEXT_LEN(mode_name) == strlen(name) &&\
+ memcmp(GRN_TEXT_VALUE(mode_name), name, strlen(name)) == 0)
+
+ {
+ grn_obj tokens;
+ GRN_VALUE_FIX_SIZE_INIT(&tokens, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ if (GRN_TEXT_LEN(mode_name) == 0 || MODE_NAME_EQUAL("ADD")) {
+ tokenize(ctx, lexicon, string, GRN_TOKEN_ADD, flags, &tokens);
+ output_tokens(ctx, &tokens, lexicon, NULL);
+ } else if (MODE_NAME_EQUAL("GET")) {
+ tokenize(ctx, lexicon, string, GRN_TOKEN_ADD, flags, &tokens);
+ GRN_BULK_REWIND(&tokens);
+ tokenize(ctx, lexicon, string, GRN_TOKEN_GET, flags, &tokens);
+ output_tokens(ctx, &tokens, lexicon, NULL);
+ } else {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "[tokenize] invalid mode: <%.*s>",
+ (int)GRN_TEXT_LEN(mode_name), GRN_TEXT_VALUE(mode_name));
+ }
+ GRN_OBJ_FIN(ctx, &tokens);
+ }
+#undef MODE_NAME_EQUAL
+
+ grn_obj_unlink(ctx, lexicon);
+ }
+
+ return NULL;
+}
+
+void
+grn_proc_init_tokenize(grn_ctx *ctx)
+{
+ grn_expr_var vars[6];
+
+ grn_plugin_expr_var_init(ctx, &(vars[0]), "tokenizer", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[1]), "string", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[2]), "normalizer", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[3]), "flags", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[4]), "mode", -1);
+ grn_plugin_expr_var_init(ctx, &(vars[5]), "token_filters", -1);
+ grn_plugin_command_create(ctx,
+ "tokenize", -1,
+ command_tokenize,
+ 6,
+ vars);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc/sources.am b/storage/mroonga/vendor/groonga/lib/proc/sources.am
new file mode 100644
index 00000000000..a945320ff6d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/sources.am
@@ -0,0 +1,18 @@
+libgrnproc_la_SOURCES = \
+ proc_column.c \
+ proc_config.c \
+ proc_dump.c \
+ proc_fuzzy_search.c \
+ proc_highlight.c \
+ proc_in_records.c \
+ proc_lock.c \
+ proc_object.c \
+ proc_object_inspect.c \
+ proc_object_list.c \
+ proc_query.c \
+ proc_query_log_flags.c \
+ proc_schema.c \
+ proc_select.c \
+ proc_snippet.c \
+ proc_table.c \
+ proc_tokenize.c
diff --git a/storage/mroonga/vendor/groonga/lib/raw_string.c b/storage/mroonga/vendor/groonga/lib/raw_string.c
new file mode 100644
index 00000000000..81905bf6952
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/raw_string.c
@@ -0,0 +1,38 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_raw_string.h"
+#include "grn_str.h"
+
+void
+grn_raw_string_lstrip(grn_ctx *ctx,
+ grn_raw_string *string)
+{
+ const char *end;
+ int space_len;
+
+ end = string->value + string->length;
+ while (string->value < end) {
+ space_len = grn_isspace(string->value, ctx->encoding);
+ if (space_len == 0) {
+ break;
+ }
+ string->value += space_len;
+ string->length -= space_len;
+ }
+}
diff --git a/storage/mroonga/vendor/groonga/lib/report.c b/storage/mroonga/vendor/groonga/lib/report.c
new file mode 100644
index 00000000000..b9e396e0491
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/report.c
@@ -0,0 +1,98 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_report.h"
+
+const grn_log_level GRN_REPORT_INDEX_LOG_LEVEL = GRN_LOG_INFO;
+
+void
+grn_report_index(grn_ctx *ctx,
+ const char *action,
+ const char *tag,
+ grn_obj *index)
+{
+ char index_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_name_size;
+
+ if (!grn_logger_pass(ctx, GRN_REPORT_INDEX_LOG_LEVEL)) {
+ return;
+ }
+
+ index_name_size = grn_obj_name(ctx, index, index_name, GRN_TABLE_MAX_KEY_SIZE);
+ GRN_LOG(ctx, GRN_REPORT_INDEX_LOG_LEVEL,
+ "%s[index]%s <%.*s>",
+ action, tag, index_name_size, index_name);
+}
+
+void
+grn_report_index_not_used(grn_ctx *ctx,
+ const char *action,
+ const char *tag,
+ grn_obj *index,
+ const char *reason)
+{
+ char index_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_name_size;
+
+ if (!grn_logger_pass(ctx, GRN_REPORT_INDEX_LOG_LEVEL)) {
+ return;
+ }
+
+ index_name_size = grn_obj_name(ctx, index, index_name, GRN_TABLE_MAX_KEY_SIZE);
+ GRN_LOG(ctx, GRN_REPORT_INDEX_LOG_LEVEL,
+ "%s[index-not-used]%s <%.*s>: %s",
+ action, tag, index_name_size, index_name, reason);
+}
+
+void
+grn_report_table(grn_ctx *ctx,
+ const char *action,
+ const char *tag,
+ grn_obj *table)
+{
+ grn_obj description;
+ grn_obj *target;
+
+ if (!grn_logger_pass(ctx, GRN_REPORT_INDEX_LOG_LEVEL)) {
+ return;
+ }
+
+ GRN_TEXT_INIT(&description, 0);
+ for (target = table; target; target = grn_ctx_at(ctx, target->header.domain)) {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+
+ name_size = grn_obj_name(ctx, target, name, GRN_TABLE_MAX_KEY_SIZE);
+ if (GRN_TEXT_LEN(&description) > 0) {
+ GRN_TEXT_PUTS(ctx, &description, " -> ");
+ }
+ if (name_size == 0) {
+ GRN_TEXT_PUTS(ctx, &description, "(temporary)");
+ } else {
+ GRN_TEXT_PUTS(ctx, &description, "<");
+ GRN_TEXT_PUT(ctx, &description, name, name_size);
+ GRN_TEXT_PUTS(ctx, &description, ">");
+ }
+ }
+ GRN_LOG(ctx, GRN_REPORT_INDEX_LOG_LEVEL,
+ "%s[table]%s %.*s",
+ action, tag,
+ (int)GRN_TEXT_LEN(&description),
+ GRN_TEXT_VALUE(&description));
+ GRN_OBJ_FIN(ctx, &description);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/request_canceler.c b/storage/mroonga/vendor/groonga/lib/request_canceler.c
index 866292f73de..9ffe1f41c4f 100644
--- a/storage/mroonga/vendor/groonga/lib/request_canceler.c
+++ b/storage/mroonga/vendor/groonga/lib/request_canceler.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -17,6 +17,7 @@
*/
#include "grn_ctx.h"
+#include "grn_ctx_impl.h"
#include "grn_request_canceler.h"
typedef struct _grn_request_canceler grn_request_canceler;
@@ -30,12 +31,15 @@ struct _grn_request_canceler_entry {
grn_ctx *ctx;
};
+static grn_ctx grn_the_request_canceler_ctx;
static grn_request_canceler *grn_the_request_canceler = NULL;
grn_bool
grn_request_canceler_init(void)
{
- grn_ctx *ctx = &grn_gctx;
+ grn_ctx *ctx = &grn_the_request_canceler_ctx;
+
+ grn_ctx_init(ctx, 0);
grn_the_request_canceler = GRN_MALLOC(sizeof(grn_request_canceler));
if (!grn_the_request_canceler) {
@@ -64,7 +68,8 @@ grn_request_canceler_register(grn_ctx *ctx,
grn_hash *entries = grn_the_request_canceler->entries;
grn_id id;
void *value;
- id = grn_hash_add(&grn_gctx, entries, request_id, size, &value, NULL);
+ id = grn_hash_add(&grn_the_request_canceler_ctx,
+ entries, request_id, size, &value, NULL);
if (id) {
grn_request_canceler_entry *entry = value;
entry->ctx = ctx;
@@ -80,29 +85,46 @@ grn_request_canceler_unregister(grn_ctx *ctx,
MUTEX_LOCK(grn_the_request_canceler->mutex);
{
grn_hash *entries = grn_the_request_canceler->entries;
- grn_hash_delete(&grn_gctx, entries, request_id, size, NULL);
+ grn_hash_delete(&grn_the_request_canceler_ctx,
+ entries, request_id, size, NULL);
}
MUTEX_UNLOCK(grn_the_request_canceler->mutex);
- if (ctx->rc == GRN_INTERRUPTED_FUNCTION_CALL) {
+ if (ctx->rc == GRN_CANCEL) {
ERRSET(ctx, GRN_LOG_NOTICE, ctx->rc,
"[request-canceler] a request is canceled: <%.*s>",
size, request_id);
}
}
+static grn_bool
+grn_request_canceler_cancel_entry(grn_request_canceler_entry *entry)
+{
+ if (entry->ctx->rc == GRN_SUCCESS) {
+ entry->ctx->rc = GRN_CANCEL;
+ if (entry->ctx->impl->current_request_timer_id) {
+ void *timer_id = entry->ctx->impl->current_request_timer_id;
+ entry->ctx->impl->current_request_timer_id = NULL;
+ grn_request_timer_unregister(timer_id);
+ }
+ return GRN_TRUE;
+ } else {
+ return GRN_FALSE;
+ }
+}
+
grn_bool
grn_request_canceler_cancel(const char *request_id, unsigned int size)
{
grn_bool canceled = GRN_FALSE;
MUTEX_LOCK(grn_the_request_canceler->mutex);
{
+ grn_ctx *ctx = &grn_the_request_canceler_ctx;
grn_hash *entries = grn_the_request_canceler->entries;
void *value;
- if (grn_hash_get(&grn_gctx, entries, request_id, size, &value)) {
+ if (grn_hash_get(ctx, entries, request_id, size, &value)) {
grn_request_canceler_entry *entry = value;
- if (entry->ctx->rc == GRN_SUCCESS) {
- entry->ctx->rc = GRN_INTERRUPTED_FUNCTION_CALL;
+ if (grn_request_canceler_cancel_entry(entry)) {
canceled = GRN_TRUE;
}
}
@@ -111,13 +133,44 @@ grn_request_canceler_cancel(const char *request_id, unsigned int size)
return canceled;
}
+grn_bool
+grn_request_canceler_cancel_all(void)
+{
+ grn_bool canceled = GRN_FALSE;
+ MUTEX_LOCK(grn_the_request_canceler->mutex);
+ {
+ grn_ctx *ctx = &grn_the_request_canceler_ctx;
+ grn_hash *entries = grn_the_request_canceler->entries;
+ grn_hash_cursor *cursor;
+
+ cursor = grn_hash_cursor_open(ctx, entries,
+ NULL, 0, NULL, 0,
+ 0, -1, 0);
+ if (cursor) {
+ while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ void *value;
+ if (grn_hash_cursor_get_value(ctx, cursor, &value) > 0) {
+ grn_request_canceler_entry *entry = value;
+ if (grn_request_canceler_cancel_entry(entry)) {
+ canceled = GRN_TRUE;
+ }
+ }
+ }
+ grn_hash_cursor_close(ctx, cursor);
+ }
+ }
+ MUTEX_UNLOCK(grn_the_request_canceler->mutex);
+ return canceled;
+}
+
void
grn_request_canceler_fin(void)
{
- grn_ctx *ctx = &grn_gctx;
+ grn_ctx *ctx = &grn_the_request_canceler_ctx;
grn_hash_close(ctx, grn_the_request_canceler->entries);
MUTEX_FIN(grn_the_request_canceler->mutex);
GRN_FREE(grn_the_request_canceler);
grn_the_request_canceler = NULL;
+ grn_ctx_fin(ctx);
}
diff --git a/storage/mroonga/vendor/groonga/lib/request_timer.c b/storage/mroonga/vendor/groonga/lib/request_timer.c
new file mode 100644
index 00000000000..9a5d85f79c6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/request_timer.c
@@ -0,0 +1,88 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_ctx.h"
+#include "grn_request_timer.h"
+
+static grn_request_timer grn_current_request_timer = { 0 };
+static double grn_request_timer_default_timeout = 0.0;
+
+grn_bool
+grn_request_timer_init(void)
+{
+ return GRN_TRUE;
+}
+
+void *
+grn_request_timer_register(const char *request_id,
+ unsigned int request_id_size,
+ double timeout)
+{
+ void *timer_id = NULL;
+
+ if (grn_current_request_timer.register_func) {
+ void *user_data = grn_current_request_timer.user_data;
+ timer_id = grn_current_request_timer.register_func(request_id,
+ request_id_size,
+ timeout,
+ user_data);
+ }
+
+ return timer_id;
+}
+
+void
+grn_request_timer_unregister(void *timer_id)
+{
+ if (grn_current_request_timer.unregister_func) {
+ void *user_data = grn_current_request_timer.user_data;
+ grn_current_request_timer.unregister_func(timer_id, user_data);
+ }
+}
+
+void
+grn_request_timer_set(grn_request_timer *timer)
+{
+ if (grn_current_request_timer.fin_func) {
+ void *user_data = grn_current_request_timer.user_data;
+ grn_current_request_timer.fin_func(user_data);
+ }
+ if (timer) {
+ grn_current_request_timer = *timer;
+ } else {
+ memset(&grn_current_request_timer, 0, sizeof(grn_request_timer));
+ }
+}
+
+double
+grn_get_default_request_timeout(void)
+{
+ return grn_request_timer_default_timeout;
+}
+
+void
+grn_set_default_request_timeout(double timeout)
+{
+ grn_request_timer_default_timeout = timeout;
+}
+
+void
+grn_request_timer_fin(void)
+{
+ grn_request_timer_set(NULL);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/scanner.c b/storage/mroonga/vendor/groonga/lib/scanner.c
new file mode 100644
index 00000000000..c7d86ff7b0c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/scanner.c
@@ -0,0 +1,73 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_scanner.h"
+
+grn_scanner *
+grn_scanner_open(grn_ctx *ctx,
+ grn_obj *expr,
+ grn_operator op,
+ grn_bool record_exist)
+{
+ grn_scanner *scanner;
+
+ scanner = GRN_MALLOC(sizeof(grn_scanner));
+ if (!scanner) {
+ return NULL;
+ }
+
+ scanner->source_expr = expr;
+ scanner->expr = grn_expr_rewrite(ctx, expr);
+ if (!scanner->expr) {
+ scanner->expr = expr;
+ }
+
+ scanner->sis = grn_scan_info_build(ctx,
+ scanner->expr,
+ &(scanner->n_sis),
+ op,
+ record_exist);
+ if (!scanner->sis) {
+ grn_scanner_close(ctx, scanner);
+ return NULL;
+ }
+
+ return scanner;
+}
+
+void
+grn_scanner_close(grn_ctx *ctx, grn_scanner *scanner)
+{
+ if (!scanner) {
+ return;
+ }
+
+ if (scanner->sis) {
+ int i;
+ for (i = 0; i < scanner->n_sis; i++) {
+ grn_scan_info_close(ctx, scanner->sis[i]);
+ }
+ GRN_FREE(scanner->sis);
+ }
+
+ if (scanner->expr != scanner->source_expr) {
+ grn_obj_close(ctx, scanner->expr);
+ }
+
+ GRN_FREE(scanner);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/scorer.c b/storage/mroonga/vendor/groonga/lib/scorer.c
index 2670bb3d4c6..f1c110dddaa 100644
--- a/storage/mroonga/vendor/groonga/lib/scorer.c
+++ b/storage/mroonga/vendor/groonga/lib/scorer.c
@@ -157,24 +157,24 @@ grn_scorer_matched_record_get_n_args(grn_ctx *ctx,
grn_rc
grn_scorer_register(grn_ctx *ctx,
- const char *plugin_name_ptr,
- int plugin_name_length,
+ const char *scorer_name_ptr,
+ int scorer_name_length,
grn_scorer_score_func *score)
{
- if (plugin_name_length == -1) {
- plugin_name_length = strlen(plugin_name_ptr);
+ if (scorer_name_length == -1) {
+ scorer_name_length = strlen(scorer_name_ptr);
}
{
grn_obj *scorer_object = grn_proc_create(ctx,
- plugin_name_ptr,
- plugin_name_length,
+ scorer_name_ptr,
+ scorer_name_length,
GRN_PROC_SCORER,
NULL, NULL, NULL, 0, NULL);
if (scorer_object == NULL) {
GRN_PLUGIN_ERROR(ctx, GRN_SCORER_ERROR,
"[scorer][%.*s] failed to grn_proc_create()",
- plugin_name_length, plugin_name_ptr);
+ scorer_name_length, scorer_name_ptr);
return ctx->rc;
}
diff --git a/storage/mroonga/vendor/groonga/lib/store.c b/storage/mroonga/vendor/groonga/lib/store.c
index d43ebb466e3..e814a85c361 100644
--- a/storage/mroonga/vendor/groonga/lib/store.c
+++ b/storage/mroonga/vendor/groonga/lib/store.c
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -58,8 +59,8 @@ _grn_ra_create(grn_ctx *ctx, grn_ra *ra, const char *path, unsigned int element_
grn_ra *
grn_ra_create(grn_ctx *ctx, const char *path, unsigned int element_size)
{
- grn_ra *ra = NULL;
- if (!(ra = GRN_GMALLOC(sizeof(grn_ra)))) {
+ grn_ra *ra = (grn_ra *)GRN_CALLOC(sizeof(grn_ra));
+ if (!ra) {
return NULL;
}
GRN_DB_OBJ_SET_TYPE(ra, GRN_COLUMN_FIX_SIZE);
@@ -77,15 +78,20 @@ grn_ra_open(grn_ctx *ctx, const char *path)
int n_elm, w_elm;
grn_ra *ra = NULL;
struct grn_ra_header *header;
+ uint32_t io_type;
io = grn_io_open(ctx, path, grn_io_auto);
if (!io) { return NULL; }
header = grn_io_header(io);
- if (grn_io_get_type(io) != GRN_COLUMN_FIX_SIZE) {
- ERR(GRN_INVALID_FORMAT, "file type unmatch");
+ io_type = grn_io_get_type(io);
+ if (io_type != GRN_COLUMN_FIX_SIZE) {
+ ERR(GRN_INVALID_FORMAT,
+ "[column][fix-size] file type must be %#04x: <%#04x>",
+ GRN_COLUMN_FIX_SIZE, io_type);
grn_io_close(ctx, io);
return NULL;
}
- if (!(ra = GRN_GMALLOC(sizeof(grn_ra)))) {
+ ra = GRN_MALLOCN(grn_ra, 1);
+ if (!ra) {
grn_io_close(ctx, io);
return NULL;
}
@@ -113,7 +119,7 @@ grn_ra_close(grn_ctx *ctx, grn_ra *ra)
grn_rc rc;
if (!ra) { return GRN_INVALID_ARGUMENT; }
rc = grn_io_close(ctx, ra->io);
- GRN_GFREE(ra);
+ GRN_FREE(ra);
return rc;
}
@@ -362,7 +368,7 @@ _grn_ja_create(grn_ctx *ctx, grn_ja *ja, const char *path,
header_v2->segregate_threshold = GRN_JA_W_SEGREGATE_THRESH_V2;
header_v2->n_element_variation = JA_N_ELEMENT_VARIATION_V2;
- header = GRN_GMALLOC(sizeof(struct grn_ja_header));
+ header = GRN_MALLOCN(struct grn_ja_header, 1);
if (!header) {
grn_io_close(ctx, io);
return NULL;
@@ -390,7 +396,8 @@ grn_ja *
grn_ja_create(grn_ctx *ctx, const char *path, unsigned int max_element_size, uint32_t flags)
{
grn_ja *ja = NULL;
- if (!(ja = GRN_GMALLOC(sizeof(grn_ja)))) {
+ ja = (grn_ja *)GRN_CALLOC(sizeof(grn_ja));
+ if (!ja) {
return NULL;
}
GRN_DB_OBJ_SET_TYPE(ja, GRN_COLUMN_VAR_SIZE);
@@ -408,11 +415,15 @@ grn_ja_open(grn_ctx *ctx, const char *path)
grn_ja *ja = NULL;
struct grn_ja_header *header;
struct grn_ja_header_v2 *header_v2;
+ uint32_t io_type;
io = grn_io_open(ctx, path, grn_io_auto);
if (!io) { return NULL; }
header_v2 = grn_io_header(io);
- if (grn_io_get_type(io) != GRN_COLUMN_VAR_SIZE) {
- ERR(GRN_INVALID_FORMAT, "file type unmatch");
+ io_type = grn_io_get_type(io);
+ if (io_type != GRN_COLUMN_VAR_SIZE) {
+ ERR(GRN_INVALID_FORMAT,
+ "[column][var-size] file type must be %#04x: <%#04x>",
+ GRN_COLUMN_VAR_SIZE, io_type);
grn_io_close(ctx, io);
return NULL;
}
@@ -422,14 +433,16 @@ grn_ja_open(grn_ctx *ctx, const char *path)
if (header_v2->n_element_variation == 0) {
header_v2->n_element_variation = JA_N_ELEMENT_VARIATION_V1;
}
- if (!(ja = GRN_GMALLOC(sizeof(grn_ja)))) {
+ ja = GRN_MALLOCN(grn_ja, 1);
+ if (!ja) {
grn_io_close(ctx, io);
return NULL;
}
GRN_DB_OBJ_SET_TYPE(ja, GRN_COLUMN_VAR_SIZE);
- if (!(header = GRN_GMALLOC(sizeof(struct grn_ja_header)))) {
+ header = GRN_MALLOCN(struct grn_ja_header, 1);
+ if (!header) {
grn_io_close(ctx, io);
- GRN_GFREE(ja);
+ GRN_FREE(ja);
return NULL;
}
@@ -468,14 +481,24 @@ grn_ja_info(grn_ctx *ctx, grn_ja *ja, unsigned int *max_element_size)
return GRN_SUCCESS;
}
+grn_column_flags
+grn_ja_get_flags(grn_ctx *ctx, grn_ja *ja)
+{
+ if (!ja) {
+ return 0;
+ }
+
+ return ja->header->flags;
+}
+
grn_rc
grn_ja_close(grn_ctx *ctx, grn_ja *ja)
{
grn_rc rc;
if (!ja) { return GRN_INVALID_ARGUMENT; }
rc = grn_io_close(ctx, ja->io);
- GRN_GFREE(ja->header);
- GRN_GFREE(ja);
+ GRN_FREE(ja->header);
+ GRN_FREE(ja);
return rc;
}
@@ -507,7 +530,7 @@ grn_ja_truncate(grn_ctx *ctx, grn_ja *ja)
if ((rc = grn_io_close(ctx, ja->io))) { goto exit; }
ja->io = NULL;
if (path && (rc = grn_io_remove(ctx, path))) { goto exit; }
- GRN_GFREE(ja->header);
+ GRN_FREE(ja->header);
if (!_grn_ja_create(ctx, ja, path, max_element_size, flags)) {
rc = GRN_UNKNOWN_ERROR;
}
@@ -559,11 +582,10 @@ grn_ja_unref(grn_ctx *ctx, grn_io_win *iw)
if (iw->uncompressed_value) {
GRN_FREE(iw->uncompressed_value);
iw->uncompressed_value = NULL;
- } else {
- if (!iw->addr) { return GRN_INVALID_ARGUMENT; }
- GRN_IO_SEG_UNREF(iw->io, iw->pseg);
- if (!iw->tiny_p) { grn_io_win_unmap(iw); }
}
+ if (!iw->addr) { return GRN_INVALID_ARGUMENT; }
+ GRN_IO_SEG_UNREF(iw->io, iw->pseg);
+ if (!iw->tiny_p) { grn_io_win_unmap(iw); }
return GRN_SUCCESS;
}
@@ -891,7 +913,7 @@ set_value(grn_ctx *ctx, grn_ja *ja, grn_id id, void *value, uint32_t value_len,
return rc;
}
-grn_rc
+static grn_rc
grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id,
void *value, uint32_t value_len, int flags, uint64_t *cas)
{
@@ -1179,49 +1201,220 @@ grn_ja_element_info(grn_ctx *ctx, grn_ja *ja, grn_id id,
return GRN_SUCCESS;
}
+#define COMPRESSED_VALUE_META_FLAG(meta) ((meta) & 0xf000000000000000)
+#define COMPRESSED_VALUE_META_FLAG_RAW 0x1000000000000000
+#define COMPRESSED_VALUE_META_UNCOMPRESSED_LEN(meta) \
+ ((meta) & 0x0fffffffffffffff)
+
+#define COMPRESS_THRESHOLD_BYTE 256
+#define COMPRESS_PACKED_VALUE_SIZE_MAX 257
+ /* COMPRESS_THRESHOLD_BYTE - 1 + sizeof(uint64_t) = 257 */
+
+#if defined(GRN_WITH_ZLIB) || defined(GRN_WITH_LZ4) || defined(GRN_WITH_ZSTD)
+# define GRN_WITH_COMPRESSED
+#endif
+
+#ifdef GRN_WITH_COMPRESSED
+static void *
+grn_ja_ref_packed(grn_ctx *ctx,
+ grn_io_win *iw,
+ uint32_t *value_len,
+ void *raw_value,
+ uint32_t raw_value_len,
+ void **compressed_value,
+ uint32_t *compressed_value_len,
+ uint32_t *uncompressed_value_len)
+{
+ uint64_t compressed_value_meta;
+
+ compressed_value_meta = *((uint64_t *)raw_value);
+ *compressed_value = (void *)(((uint64_t *)raw_value) + 1);
+ *compressed_value_len = raw_value_len - sizeof(uint64_t);
+
+ *uncompressed_value_len =
+ COMPRESSED_VALUE_META_UNCOMPRESSED_LEN(compressed_value_meta);
+ switch (COMPRESSED_VALUE_META_FLAG(compressed_value_meta)) {
+ case COMPRESSED_VALUE_META_FLAG_RAW :
+ iw->uncompressed_value = NULL;
+ *value_len = *uncompressed_value_len;
+ return *compressed_value;
+ default :
+ return NULL;
+ }
+}
+
+static grn_rc
+grn_ja_put_packed(grn_ctx *ctx,
+ grn_ja *ja,
+ grn_id id,
+ void *value,
+ uint32_t value_len,
+ int flags,
+ uint64_t *cas)
+{
+ char *packed_value[COMPRESS_PACKED_VALUE_SIZE_MAX];
+ uint32_t packed_value_len;
+ uint64_t packed_value_meta;
+
+ packed_value_len = value_len + sizeof(uint64_t);
+ packed_value_meta = value_len | COMPRESSED_VALUE_META_FLAG_RAW;
+ *((uint64_t *)packed_value) = packed_value_meta;
+ memcpy(((uint64_t *)packed_value) + 1,
+ value,
+ value_len);
+ return grn_ja_put_raw(ctx,
+ ja,
+ id,
+ packed_value,
+ packed_value_len,
+ flags,
+ cas);
+}
+
+static void
+grn_ja_compress_error(grn_ctx *ctx,
+ grn_ja *ja,
+ grn_id id,
+ grn_rc rc,
+ const char *message,
+ const char *detail)
+{
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_len;
+
+ if (ja->obj.id == GRN_ID_NIL) {
+ name[0] = '\0';
+ name_len = 0;
+ } else {
+ name_len = grn_obj_name(ctx, (grn_obj *)ja, name, GRN_TABLE_MAX_KEY_SIZE);
+ }
+ ERR(GRN_ZSTD_ERROR,
+ "[ja]%s: %s%.*s%s<%u>%s%s%s",
+ message,
+ name_len == 0 ? "" : "<",
+ name_len,
+ name,
+ name_len == 0 ? "" : ">: ",
+ id,
+ detail ? " :<" : "",
+ detail ? detail : "",
+ detail ? ">" : "");
+}
+#endif /* GRN_WITH_COMPRESSED */
+
#ifdef GRN_WITH_ZLIB
#include <zlib.h>
+static const char *
+grn_zrc_to_string(int zrc)
+{
+ switch (zrc) {
+ case Z_OK :
+ return "OK";
+ case Z_STREAM_END :
+ return "Stream is end";
+ case Z_NEED_DICT :
+ return "Need dictionary";
+ case Z_ERRNO :
+ return "See errno";
+ case Z_STREAM_ERROR :
+ return "Stream error";
+ case Z_DATA_ERROR :
+ return "Data error";
+ case Z_MEM_ERROR :
+ return "Memory error";
+ case Z_BUF_ERROR :
+ return "Buffer error";
+ case Z_VERSION_ERROR :
+ return "Version error";
+ default :
+ return "Unknown";
+ }
+}
+
static void *
grn_ja_ref_zlib(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_io_win *iw, uint32_t *value_len)
{
z_stream zstream;
+ void *raw_value;
+ uint32_t raw_value_len;
void *zvalue;
uint32_t zvalue_len;
- if (!(zvalue = grn_ja_ref_raw(ctx, ja, id, iw, &zvalue_len))) {
+ void *unpacked_value;
+ uint32_t uncompressed_value_len;
+ int zrc;
+
+ if (!(raw_value = grn_ja_ref_raw(ctx, ja, id, iw, &raw_value_len))) {
iw->uncompressed_value = NULL;
*value_len = 0;
return NULL;
}
- zstream.next_in = (Bytef *)(((uint64_t *)zvalue) + 1);
- zstream.avail_in = zvalue_len + sizeof(uint64_t);
+
+ unpacked_value = grn_ja_ref_packed(ctx,
+ iw, value_len,
+ raw_value, raw_value_len,
+ &zvalue, &zvalue_len,
+ &uncompressed_value_len);
+ if (unpacked_value) {
+ return unpacked_value;
+ }
+
+ zstream.next_in = (Bytef *)zvalue;
+ zstream.avail_in = zvalue_len;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
- if (inflateInit2(&zstream, 15 /* windowBits */) != Z_OK) {
+ zrc = inflateInit2(&zstream, 15 /* windowBits */);
+ if (zrc != Z_OK) {
iw->uncompressed_value = NULL;
*value_len = 0;
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZLIB_ERROR,
+ "[zlib] failed to decompress: initialize",
+ grn_zrc_to_string(zrc));
return NULL;
}
- if (!(iw->uncompressed_value = GRN_MALLOC(*((uint64_t *)zvalue)))) {
+ if (!(iw->uncompressed_value = GRN_MALLOC(uncompressed_value_len))) {
inflateEnd(&zstream);
iw->uncompressed_value = NULL;
*value_len = 0;
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZLIB_ERROR,
+ "[zlib] failed to decompress: allocate buffer",
+ NULL);
return NULL;
}
zstream.next_out = (Bytef *)iw->uncompressed_value;
- zstream.avail_out = *(uint64_t *)zvalue;
- if (inflate(&zstream, Z_FINISH) != Z_STREAM_END) {
+ zstream.avail_out = uncompressed_value_len;
+ zrc = inflate(&zstream, Z_FINISH);
+ if (zrc != Z_STREAM_END) {
inflateEnd(&zstream);
GRN_FREE(iw->uncompressed_value);
iw->uncompressed_value = NULL;
*value_len = 0;
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZLIB_ERROR,
+ "[zlib] failed to decompress: finish",
+ grn_zrc_to_string(zrc));
return NULL;
}
*value_len = zstream.total_out;
- if (inflateEnd(&zstream) != Z_OK) {
+ zrc = inflateEnd(&zstream);
+ if (zrc != Z_OK) {
GRN_FREE(iw->uncompressed_value);
iw->uncompressed_value = NULL;
*value_len = 0;
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZLIB_ERROR,
+ "[zlib] failed to decompress: end",
+ grn_zrc_to_string(zrc));
return NULL;
}
return iw->uncompressed_value;
@@ -1231,56 +1424,140 @@ grn_ja_ref_zlib(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_io_win *iw, uint32_t *v
#ifdef GRN_WITH_LZ4
#include <lz4.h>
+# if (LZ4_VERSION_MAJOR == 1 && LZ4_VERSION_MINOR < 6)
+# define LZ4_compress_default(source, dest, source_size, max_dest_size) \
+ LZ4_compress((source), (dest), (source_size))
+# endif
+
static void *
grn_ja_ref_lz4(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_io_win *iw, uint32_t *value_len)
{
- void *packed_value;
- int packed_value_len;
+ void *raw_value;
+ uint32_t raw_value_len;
void *lz4_value;
- int lz4_value_len;
- int original_value_len;
+ uint32_t lz4_value_len;
+ void *unpacked_value;
+ uint32_t uncompressed_value_len;
- if (!(packed_value = grn_ja_ref_raw(ctx, ja, id, iw, &packed_value_len))) {
+ if (!(raw_value = grn_ja_ref_raw(ctx, ja, id, iw, &raw_value_len))) {
iw->uncompressed_value = NULL;
*value_len = 0;
return NULL;
}
- original_value_len = *((uint64_t *)packed_value);
- if (!(iw->uncompressed_value = GRN_MALLOC(original_value_len))) {
+
+ unpacked_value = grn_ja_ref_packed(ctx,
+ iw, value_len,
+ raw_value, raw_value_len,
+ &lz4_value, &lz4_value_len,
+ &uncompressed_value_len);
+ if (unpacked_value) {
+ return unpacked_value;
+ }
+
+ if (!(iw->uncompressed_value = GRN_MALLOC(uncompressed_value_len))) {
iw->uncompressed_value = NULL;
*value_len = 0;
return NULL;
}
- lz4_value = (void *)((uint64_t *)packed_value + 1);
- lz4_value_len = packed_value_len - sizeof(uint64_t);
if (LZ4_decompress_safe((const char *)(lz4_value),
(char *)(iw->uncompressed_value),
lz4_value_len,
- original_value_len) < 0) {
+ uncompressed_value_len) < 0) {
GRN_FREE(iw->uncompressed_value);
iw->uncompressed_value = NULL;
*value_len = 0;
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_LZ4_ERROR,
+ "[lz4] failed to decompress",
+ NULL);
return NULL;
}
- *value_len = original_value_len;
+ *value_len = uncompressed_value_len;
return iw->uncompressed_value;
}
#endif /* GRN_WITH_LZ4 */
+#ifdef GRN_WITH_ZSTD
+#include <zstd.h>
+
+static void *
+grn_ja_ref_zstd(grn_ctx *ctx,
+ grn_ja *ja,
+ grn_id id,
+ grn_io_win *iw,
+ uint32_t *value_len)
+{
+ void *raw_value;
+ uint32_t raw_value_len;
+ void *zstd_value;
+ uint32_t zstd_value_len;
+ void *unpacked_value;
+ uint32_t uncompressed_value_len;
+ size_t written_len;
+
+ if (!(raw_value = grn_ja_ref_raw(ctx, ja, id, iw, &raw_value_len))) {
+ iw->uncompressed_value = NULL;
+ *value_len = 0;
+ return NULL;
+ }
+
+ unpacked_value = grn_ja_ref_packed(ctx,
+ iw, value_len,
+ raw_value, raw_value_len,
+ &zstd_value, &zstd_value_len,
+ &uncompressed_value_len);
+ if (unpacked_value) {
+ return unpacked_value;
+ }
+
+ if (!(iw->uncompressed_value = GRN_MALLOC(uncompressed_value_len))) {
+ iw->uncompressed_value = NULL;
+ *value_len = 0;
+ return NULL;
+ }
+
+ written_len = ZSTD_decompress((char *)(iw->uncompressed_value),
+ uncompressed_value_len,
+ zstd_value,
+ zstd_value_len);
+ if (ZSTD_isError(written_len)) {
+ GRN_FREE(iw->uncompressed_value);
+ iw->uncompressed_value = NULL;
+ *value_len = 0;
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZSTD_ERROR,
+ "[zstd] failed to decompress",
+ ZSTD_getErrorName(written_len));
+ return NULL;
+ }
+ *value_len = uncompressed_value_len;
+ return iw->uncompressed_value;
+}
+#endif /* GRN_WITH_ZSTD */
+
void *
grn_ja_ref(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_io_win *iw, uint32_t *value_len)
{
+ switch (ja->header->flags & GRN_OBJ_COMPRESS_MASK) {
#ifdef GRN_WITH_ZLIB
- if (ja->header->flags & GRN_OBJ_COMPRESS_ZLIB) {
+ case GRN_OBJ_COMPRESS_ZLIB :
return grn_ja_ref_zlib(ctx, ja, id, iw, value_len);
- }
#endif /* GRN_WITH_ZLIB */
#ifdef GRN_WITH_LZ4
- if (ja->header->flags & GRN_OBJ_COMPRESS_LZ4) {
+ case GRN_OBJ_COMPRESS_LZ4 :
return grn_ja_ref_lz4(ctx, ja, id, iw, value_len);
- }
#endif /* GRN_WITH_LZ4 */
- return grn_ja_ref_raw(ctx, ja, id, iw, value_len);
+#ifdef GRN_WITH_ZSTD
+ case GRN_OBJ_COMPRESS_ZSTD :
+ return grn_ja_ref_zstd(ctx, ja, id, iw, value_len);
+#endif /* GRN_WITH_ZSTD */
+ default :
+ return grn_ja_ref_raw(ctx, ja, id, iw, value_len);
+ }
}
grn_obj *
@@ -1322,36 +1599,68 @@ grn_ja_put_zlib(grn_ctx *ctx, grn_ja *ja, grn_id id,
z_stream zstream;
void *zvalue;
int zvalue_len;
+ int zrc;
if (value_len == 0) {
return grn_ja_put_raw(ctx, ja, id, value, value_len, flags, cas);
}
+ if (value_len < COMPRESS_THRESHOLD_BYTE) {
+ return grn_ja_put_packed(ctx, ja, id, value, value_len, flags, cas);
+ }
+
zstream.next_in = value;
zstream.avail_in = value_len;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
- if (deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
- 15 /* windowBits */,
- 8 /* memLevel */,
- Z_DEFAULT_STRATEGY) != Z_OK) {
- ERR(GRN_ZLIB_ERROR, "deflateInit2 failed");
+ zrc = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
+ 15 /* windowBits */,
+ 8 /* memLevel */,
+ Z_DEFAULT_STRATEGY);
+ if (zrc != Z_OK) {
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZLIB_ERROR,
+ "[zlib] failed to compress: initialize",
+ grn_zrc_to_string(zrc));
return ctx->rc;
}
zvalue_len = deflateBound(&zstream, value_len);
- if (!(zvalue = GRN_MALLOC(zvalue_len + sizeof(uint64_t)))) { deflateEnd(&zstream); return GRN_NO_MEMORY_AVAILABLE; }
+ if (!(zvalue = GRN_MALLOC(zvalue_len + sizeof(uint64_t)))) {
+ deflateEnd(&zstream);
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZLIB_ERROR,
+ "[zlib] failed to allocate compress buffer",
+ NULL);
+ return ctx->rc;
+ }
zstream.next_out = (Bytef *)(((uint64_t *)zvalue) + 1);
zstream.avail_out = zvalue_len;
- if (deflate(&zstream, Z_FINISH) != Z_STREAM_END) {
+ zrc = deflate(&zstream, Z_FINISH);
+ if (zrc != Z_STREAM_END) {
deflateEnd(&zstream);
GRN_FREE(zvalue);
- ERR(GRN_ZLIB_ERROR, "deflate failed");
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZLIB_ERROR,
+ "[zlib] failed to compress: finish",
+ grn_zrc_to_string(zrc));
return ctx->rc;
}
zvalue_len = zstream.total_out;
- if (deflateEnd(&zstream) != Z_OK) {
+ zrc = deflateEnd(&zstream);
+ if (zrc != Z_OK) {
GRN_FREE(zvalue);
- ERR(GRN_ZLIB_ERROR, "deflateEnd failed");
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZLIB_ERROR,
+ "[zlib] failed to compress: end",
+ grn_zrc_to_string(zrc));
return ctx->rc;
}
*(uint64_t *)zvalue = value_len;
@@ -1368,57 +1677,175 @@ grn_ja_put_lz4(grn_ctx *ctx, grn_ja *ja, grn_id id,
{
grn_rc rc;
void *packed_value;
- int packed_value_len;
+ int packed_value_len_max;
+ int packed_value_len_real;
char *lz4_value;
- int lz4_value_len;
+ int lz4_value_len_max;
+ int lz4_value_len_real;
if (value_len == 0) {
return grn_ja_put_raw(ctx, ja, id, value, value_len, flags, cas);
}
+ if (value_len < COMPRESS_THRESHOLD_BYTE) {
+ return grn_ja_put_packed(ctx, ja, id, value, value_len, flags, cas);
+ }
+
if (value_len > (uint32_t)LZ4_MAX_INPUT_SIZE) {
- ERR(GRN_INVALID_ARGUMENT,
- "[ja][lz4] too large value size: <%u>: max: <%d>",
- value_len, LZ4_MAX_INPUT_SIZE);
+ uint64_t packed_value_meta;
+
+ packed_value_len_real = value_len + sizeof(uint64_t);
+ packed_value = GRN_MALLOC(packed_value_len_real);
+ if (!packed_value) {
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_LZ4_ERROR,
+ "[lz4] failed to allocate packed buffer",
+ NULL);
+ return ctx->rc;
+ }
+ packed_value_meta = value_len | COMPRESSED_VALUE_META_FLAG_RAW;
+ *((uint64_t *)packed_value) = packed_value_meta;
+ memcpy(((uint64_t *)packed_value) + 1,
+ value,
+ value_len);
+ rc = grn_ja_put_raw(ctx,
+ ja,
+ id,
+ packed_value,
+ packed_value_len_real,
+ flags,
+ cas);
+ GRN_FREE(packed_value);
+ return rc;
+ }
+
+ lz4_value_len_max = LZ4_compressBound(value_len);
+ packed_value_len_max = lz4_value_len_max + sizeof(uint64_t);
+ if (!(packed_value = GRN_MALLOC(packed_value_len_max))) {
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_LZ4_ERROR,
+ "[lz4] failed to allocate compress buffer",
+ NULL);
+ return ctx->rc;
+ }
+ lz4_value = (char *)((uint64_t *)packed_value + 1);
+ lz4_value_len_real = LZ4_compress_default((const char *)value,
+ lz4_value,
+ value_len,
+ lz4_value_len_max);
+ if (lz4_value_len_real <= 0) {
+ GRN_FREE(packed_value);
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_LZ4_ERROR,
+ "[lz4] failed to compress",
+ NULL);
return ctx->rc;
}
+ *(uint64_t *)packed_value = value_len;
+ packed_value_len_real = lz4_value_len_real + sizeof(uint64_t);
+ rc = grn_ja_put_raw(ctx,
+ ja,
+ id,
+ packed_value,
+ packed_value_len_real,
+ flags,
+ cas);
+ GRN_FREE(packed_value);
+ return rc;
+}
+#endif /* GRN_WITH_LZ4 */
- lz4_value_len = LZ4_compressBound(value_len);
+#ifdef GRN_WITH_ZSTD
+inline static grn_rc
+grn_ja_put_zstd(grn_ctx *ctx,
+ grn_ja *ja,
+ grn_id id,
+ void *value,
+ uint32_t value_len,
+ int flags,
+ uint64_t *cas)
+{
+ grn_rc rc;
+ void *packed_value;
+ int packed_value_len_max;
+ int packed_value_len_real;
+ void *zstd_value;
+ int zstd_value_len_max;
+ int zstd_value_len_real;
+ int zstd_compression_level = 3;
- if (!(packed_value = GRN_MALLOC(lz4_value_len + sizeof(uint64_t)))) {
- return GRN_NO_MEMORY_AVAILABLE;
+ if (value_len == 0) {
+ return grn_ja_put_raw(ctx, ja, id, value, value_len, flags, cas);
}
- lz4_value = (char *)((uint64_t *)packed_value + 1);
- lz4_value_len = LZ4_compress((const char*)value, lz4_value, value_len);
- if (lz4_value_len <= 0) {
- GRN_FREE(packed_value);
- ERR(GRN_LZ4_ERROR, "LZ4_compress");
+ if (value_len < COMPRESS_THRESHOLD_BYTE) {
+ return grn_ja_put_packed(ctx, ja, id, value, value_len, flags, cas);
+ }
+
+ zstd_value_len_max = ZSTD_compressBound(value_len);
+ packed_value_len_max = zstd_value_len_max + sizeof(uint64_t);
+ if (!(packed_value = GRN_MALLOC(packed_value_len_max))) {
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZSTD_ERROR,
+ "[zstd] failed to allocate compress buffer",
+ NULL);
+ return ctx->rc;
+ }
+ zstd_value = ((uint64_t *)packed_value) + 1;
+ zstd_value_len_real = ZSTD_compress(zstd_value, zstd_value_len_max,
+ value, value_len,
+ zstd_compression_level);
+ if (ZSTD_isError(zstd_value_len_real)) {
+ grn_ja_compress_error(ctx,
+ ja,
+ id,
+ GRN_ZSTD_ERROR,
+ "[zstd] failed to compress",
+ ZSTD_getErrorName(zstd_value_len_real));
return ctx->rc;
}
*(uint64_t *)packed_value = value_len;
- packed_value_len = lz4_value_len + sizeof(uint64_t);
- rc = grn_ja_put_raw(ctx, ja, id, packed_value, packed_value_len, flags, cas);
+ packed_value_len_real = zstd_value_len_real + sizeof(uint64_t);
+ rc = grn_ja_put_raw(ctx,
+ ja,
+ id,
+ packed_value,
+ packed_value_len_real,
+ flags,
+ cas);
GRN_FREE(packed_value);
return rc;
}
-#endif /* GRN_WITH_LZ4 */
+#endif /* GRN_WITH_ZSTD */
grn_rc
grn_ja_put(grn_ctx *ctx, grn_ja *ja, grn_id id, void *value, uint32_t value_len,
int flags, uint64_t *cas)
{
+ switch (ja->header->flags & GRN_OBJ_COMPRESS_MASK) {
#ifdef GRN_WITH_ZLIB
- if (ja->header->flags & GRN_OBJ_COMPRESS_ZLIB) {
+ case GRN_OBJ_COMPRESS_ZLIB :
return grn_ja_put_zlib(ctx, ja, id, value, value_len, flags, cas);
- }
#endif /* GRN_WITH_ZLIB */
#ifdef GRN_WITH_LZ4
- if (ja->header->flags & GRN_OBJ_COMPRESS_LZ4) {
+ case GRN_OBJ_COMPRESS_LZ4 :
return grn_ja_put_lz4(ctx, ja, id, value, value_len, flags, cas);
- }
#endif /* GRN_WITH_LZ4 */
- return grn_ja_put_raw(ctx, ja, id, value, value_len, flags, cas);
+#ifdef GRN_WITH_ZSTD
+ case GRN_OBJ_COMPRESS_ZSTD :
+ return grn_ja_put_zstd(ctx, ja, id, value, value_len, flags, cas);
+#endif /* GRN_WITH_ZSTD */
+ default :
+ return grn_ja_put_raw(ctx, ja, id, value, value_len, flags, cas);
+ }
}
static grn_rc
@@ -1574,6 +2001,636 @@ grn_ja_check(grn_ctx *ctx, grn_ja *ja)
GRN_OUTPUT_ARRAY_CLOSE();
}
+/* grn_ja_reader */
+
+grn_rc
+grn_ja_reader_init(grn_ctx *ctx, grn_ja_reader *reader, grn_ja *ja)
+{
+ reader->ja = ja;
+ reader->einfo_seg_id = JA_ESEG_VOID;
+ reader->ref_avail = GRN_FALSE;
+ reader->ref_seg_id = JA_ESEG_VOID;
+ reader->ref_seg_ids = NULL;
+ reader->nref_seg_ids = 0;
+ reader->ref_seg_ids_size = 0;
+ reader->body_seg_id = JA_ESEG_VOID;
+ reader->body_seg_addr = NULL;
+ reader->packed_buf = NULL;
+ reader->packed_buf_size = 0;
+#ifdef GRN_WITH_ZLIB
+ if (reader->ja->header->flags & GRN_OBJ_COMPRESS_ZLIB) {
+ z_stream *new_stream = GRN_MALLOCN(z_stream, 1);
+ if (!new_stream) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ new_stream->zalloc = NULL;
+ new_stream->zfree = NULL;
+ new_stream->opaque = NULL;
+ if (inflateInit2(new_stream, 15) != Z_OK) {
+ GRN_FREE(new_stream);
+ return GRN_ZLIB_ERROR;
+ }
+ reader->stream = new_stream;
+ }
+#endif /* GRN_WITH_ZLIB */
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ja_reader_fin(grn_ctx *ctx, grn_ja_reader *reader)
+{
+ grn_rc rc = GRN_SUCCESS;
+ if (reader->einfo_seg_id != JA_ESEG_VOID) {
+ GRN_IO_SEG_UNREF(reader->ja->io, reader->einfo_seg_id);
+ }
+ if (reader->ref_seg_ids) {
+ grn_ja_reader_unref(ctx, reader);
+ GRN_FREE(reader->ref_seg_ids);
+ }
+ if (reader->body_seg_addr) {
+ GRN_IO_SEG_UNREF(reader->ja->io, reader->body_seg_id);
+ }
+ if (reader->packed_buf) {
+ GRN_FREE(reader->packed_buf);
+ }
+#ifdef GRN_WITH_ZLIB
+ if (reader->ja->header->flags & GRN_OBJ_COMPRESS_ZLIB) {
+ if (reader->stream) {
+ if (inflateEnd((z_stream *)reader->stream) != Z_OK) {
+ rc = GRN_UNKNOWN_ERROR;
+ }
+ GRN_FREE(reader->stream);
+ }
+ }
+#endif /* GRN_WITH_ZLIB */
+ return rc;
+}
+
+grn_rc
+grn_ja_reader_open(grn_ctx *ctx, grn_ja *ja, grn_ja_reader **reader)
+{
+ grn_rc rc;
+ grn_ja_reader *new_reader = GRN_MALLOCN(grn_ja_reader, 1);
+ if (!new_reader) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ rc = grn_ja_reader_init(ctx, new_reader, ja);
+ if (rc != GRN_SUCCESS) {
+ GRN_FREE(new_reader);
+ return rc;
+ }
+ *reader = new_reader;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ja_reader_close(grn_ctx *ctx, grn_ja_reader *reader)
+{
+ grn_rc rc = grn_ja_reader_fin(ctx, reader);
+ GRN_FREE(reader);
+ return rc;
+}
+
+#ifdef GRN_WITH_COMPRESSED
+/* grn_ja_reader_seek_compressed() prepares to access a compressed value. */
+static grn_rc
+grn_ja_reader_seek_compressed(grn_ctx *ctx, grn_ja_reader *reader, grn_id id)
+{
+ grn_ja_einfo *einfo;
+ void *seg_addr;
+ uint32_t seg_id = reader->ja->header->esegs[id >> JA_W_EINFO_IN_A_SEGMENT];
+ if (seg_id == JA_ESEG_VOID) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (seg_id != reader->einfo_seg_id) {
+ GRN_IO_SEG_REF(reader->ja->io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ if (reader->einfo_seg_id != JA_ESEG_VOID) {
+ GRN_IO_SEG_UNREF(reader->ja->io, reader->einfo_seg_id);
+ }
+ reader->einfo_seg_id = seg_id;
+ reader->einfo_seg_addr = seg_addr;
+ }
+ einfo = (grn_ja_einfo *)reader->einfo_seg_addr;
+ einfo += id & JA_M_EINFO_IN_A_SEGMENT;
+ reader->einfo = einfo;
+ /* ETINY_P(einfo) is always false because the original size needs 8 bytes. */
+ if (EHUGE_P(einfo)) {
+ EHUGE_DEC(einfo, seg_id, reader->packed_size);
+ reader->body_seg_offset = 0;
+ } else {
+ EINFO_DEC(einfo, seg_id, reader->body_seg_offset, reader->packed_size);
+ }
+ if (seg_id != reader->body_seg_id) {
+ GRN_IO_SEG_REF(reader->ja->io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ if (reader->body_seg_addr) {
+ GRN_IO_SEG_UNREF(reader->ja->io, reader->body_seg_id);
+ }
+ reader->body_seg_id = seg_id;
+ reader->body_seg_addr = seg_addr;
+ }
+ seg_addr = (char *)reader->body_seg_addr + reader->body_seg_offset;
+ reader->value_size = (uint32_t)*(uint64_t *)seg_addr;
+ return GRN_SUCCESS;
+}
+#endif /* GRN_WITH_COMPRESSED */
+
+/* grn_ja_reader_seek_raw() prepares to access a value. */
+static grn_rc
+grn_ja_reader_seek_raw(grn_ctx *ctx, grn_ja_reader *reader, grn_id id)
+{
+ grn_ja_einfo *einfo;
+ void *seg_addr;
+ uint32_t seg_id = reader->ja->header->esegs[id >> JA_W_EINFO_IN_A_SEGMENT];
+ if (seg_id == JA_ESEG_VOID) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (seg_id != reader->einfo_seg_id) {
+ GRN_IO_SEG_REF(reader->ja->io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ if (reader->einfo_seg_id != JA_ESEG_VOID) {
+ GRN_IO_SEG_UNREF(reader->ja->io, reader->einfo_seg_id);
+ }
+ reader->einfo_seg_id = seg_id;
+ reader->einfo_seg_addr = seg_addr;
+ }
+ einfo = (grn_ja_einfo *)reader->einfo_seg_addr;
+ einfo += id & JA_M_EINFO_IN_A_SEGMENT;
+ reader->einfo = einfo;
+ if (ETINY_P(einfo)) {
+ ETINY_DEC(einfo, reader->value_size);
+ reader->ref_avail = GRN_FALSE;
+ } else {
+ if (EHUGE_P(einfo)) {
+ EHUGE_DEC(einfo, seg_id, reader->value_size);
+ reader->ref_avail = GRN_FALSE;
+ } else {
+ EINFO_DEC(einfo, seg_id, reader->body_seg_offset, reader->value_size);
+ reader->ref_avail = GRN_TRUE;
+ }
+ if (reader->body_seg_addr) {
+ if (seg_id != reader->body_seg_id) {
+ GRN_IO_SEG_UNREF(reader->ja->io, reader->body_seg_id);
+ reader->body_seg_addr = NULL;
+ }
+ }
+ reader->body_seg_id = seg_id;
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ja_reader_seek(grn_ctx *ctx, grn_ja_reader *reader, grn_id id)
+{
+ switch (reader->ja->header->flags & GRN_OBJ_COMPRESS_MASK) {
+#ifdef GRN_WITH_ZLIB
+ case GRN_OBJ_COMPRESS_ZLIB :
+ return grn_ja_reader_seek_compressed(ctx, reader, id);
+#endif /* GRN_WITH_ZLIB */
+#ifdef GRN_WITH_LZ4
+ case GRN_OBJ_COMPRESS_LZ4 :
+ return grn_ja_reader_seek_compressed(ctx, reader, id);
+#endif /* GRN_WITH_LZ4 */
+#ifdef GRN_WITH_ZSTD
+ case GRN_OBJ_COMPRESS_ZSTD :
+ return grn_ja_reader_seek_compressed(ctx, reader, id);
+#endif /* GRN_WITH_ZSTD */
+ default :
+ return grn_ja_reader_seek_raw(ctx, reader, id);
+ }
+}
+
+grn_rc
+grn_ja_reader_ref(grn_ctx *ctx, grn_ja_reader *reader, void **addr)
+{
+ if (!reader->ref_avail) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (reader->body_seg_id != reader->ref_seg_id) {
+ void *seg_addr;
+ if (reader->nref_seg_ids == reader->ref_seg_ids_size) {
+ size_t n_bytes;
+ uint32_t new_size, *new_seg_ids;
+ if (reader->ref_seg_ids_size == 0) {
+ new_size = GRN_JA_READER_INITIAL_REF_SEG_IDS_SIZE;
+ } else {
+ new_size = reader->ref_seg_ids_size * 2;
+ }
+ n_bytes = sizeof(uint32_t) * new_size;
+ new_seg_ids = (uint32_t *)GRN_REALLOC(reader->ref_seg_ids, n_bytes);
+ if (!new_seg_ids) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ reader->ref_seg_ids = new_seg_ids;
+ reader->ref_seg_ids_size = new_size;
+ }
+ GRN_IO_SEG_REF(reader->ja->io, reader->body_seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ reader->ref_seg_id = reader->body_seg_id;
+ reader->ref_seg_addr = seg_addr;
+ reader->ref_seg_ids[reader->nref_seg_ids++] = reader->body_seg_id;
+ }
+ *addr = (char *)reader->ref_seg_addr + reader->body_seg_offset;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ja_reader_unref(grn_ctx *ctx, grn_ja_reader *reader)
+{
+ uint32_t i;
+ for (i = 0; i < reader->nref_seg_ids; i++) {
+ GRN_IO_SEG_UNREF(reader->ja->io, reader->ref_seg_ids[i]);
+ }
+ reader->ref_seg_id = JA_ESEG_VOID;
+ reader->nref_seg_ids = 0;
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+}
+
+#ifdef GRN_WITH_ZLIB
+/* grn_ja_reader_read_zlib() reads a value compressed with zlib. */
+static grn_rc
+grn_ja_reader_read_zlib(grn_ctx *ctx, grn_ja_reader *reader, void *buf)
+{
+ uLong dest_size = reader->value_size;
+ z_stream *stream = (z_stream *)reader->stream;
+ grn_ja_einfo *einfo = (grn_ja_einfo *)reader->einfo;
+ if (EHUGE_P(einfo)) {
+ /* TODO: Use z_stream to avoid copy. */
+ grn_io *io = reader->ja->io;
+ void *seg_addr;
+ char *packed_ptr;
+ uint32_t size, seg_id;
+ if (reader->packed_size > reader->packed_buf_size) {
+ void *new_buf = GRN_REALLOC(reader->packed_buf, reader->packed_size);
+ if (!new_buf) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ reader->packed_buf = new_buf;
+ reader->packed_buf_size = reader->packed_size;
+ }
+ packed_ptr = (char *)reader->packed_buf;
+ grn_memcpy(packed_ptr, (char *)reader->body_seg_addr + sizeof(uint64_t),
+ io->header->segment_size - sizeof(uint64_t));
+ packed_ptr += io->header->segment_size - sizeof(uint64_t);
+ size = reader->packed_size - (io->header->segment_size - sizeof(uint64_t));
+ seg_id = reader->body_seg_id + 1;
+ while (size > io->header->segment_size) {
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(packed_ptr, seg_addr, io->header->segment_size);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ seg_id++;
+ size -= io->header->segment_size;
+ packed_ptr += io->header->segment_size;
+ }
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(packed_ptr, seg_addr, size);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ seg_id++;
+ if (uncompress((Bytef *)buf, &dest_size, (Bytef *)reader->packed_buf,
+ reader->packed_size - sizeof(uint64_t)) != Z_OK) {
+ return GRN_ZLIB_ERROR;
+ }
+ if (dest_size != reader->value_size) {
+ return GRN_ZLIB_ERROR;
+ }
+ } else {
+ char *packed_addr = (char *)reader->body_seg_addr;
+ packed_addr += reader->body_seg_offset + sizeof(uint64_t);
+ if (inflateReset(stream) != Z_OK) {
+ return GRN_ZLIB_ERROR;
+ }
+ stream->next_in = (Bytef *)packed_addr;
+ stream->avail_in = reader->packed_size - sizeof(uint64_t);
+ stream->next_out = (Bytef *)buf;
+ stream->avail_out = dest_size;
+ if ((inflate(stream, Z_FINISH) != Z_STREAM_END) || stream->avail_out) {
+ return GRN_ZLIB_ERROR;
+ }
+ }
+ return GRN_SUCCESS;
+}
+#endif /* GRN_WITH_ZLIB */
+
+#ifdef GRN_WITH_LZ4
+/* grn_ja_reader_read_lz4() reads a value compressed with LZ4. */
+static grn_rc
+grn_ja_reader_read_lz4(grn_ctx *ctx, grn_ja_reader *reader, void *buf)
+{
+ int src_size, dest_size;
+ grn_ja_einfo *einfo = (grn_ja_einfo *)reader->einfo;
+ if (EHUGE_P(einfo)) {
+ grn_io *io = reader->ja->io;
+ void *seg_addr;
+ char *packed_ptr;
+ uint32_t size, seg_id;
+ if (reader->packed_size > reader->packed_buf_size) {
+ void *new_buf = GRN_REALLOC(reader->packed_buf, reader->packed_size);
+ if (!new_buf) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ reader->packed_buf = new_buf;
+ reader->packed_buf_size = reader->packed_size;
+ }
+ packed_ptr = (char *)reader->packed_buf;
+ grn_memcpy(packed_ptr, (char *)reader->body_seg_addr + sizeof(uint64_t),
+ io->header->segment_size - sizeof(uint64_t));
+ packed_ptr += io->header->segment_size - sizeof(uint64_t);
+ size = reader->packed_size - (io->header->segment_size - sizeof(uint64_t));
+ seg_id = reader->body_seg_id + 1;
+ while (size > io->header->segment_size) {
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(packed_ptr, seg_addr, io->header->segment_size);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ seg_id++;
+ size -= io->header->segment_size;
+ packed_ptr += io->header->segment_size;
+ }
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(packed_ptr, seg_addr, size);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ seg_id++;
+ src_size = (int)(reader->packed_size - sizeof(uint64_t));
+ dest_size = LZ4_decompress_safe(reader->packed_buf, buf, src_size,
+ (int)reader->value_size);
+ } else {
+ char *packed_addr = (char *)reader->body_seg_addr;
+ packed_addr += reader->body_seg_offset + sizeof(uint64_t);
+ src_size = (int)(reader->packed_size - sizeof(uint64_t));
+ dest_size = LZ4_decompress_safe(packed_addr, buf, src_size,
+ (int)reader->value_size);
+ }
+ if ((uint32_t)dest_size != reader->value_size) {
+ return GRN_LZ4_ERROR;
+ }
+ return GRN_SUCCESS;
+}
+#endif /* GRN_WITH_LZ4 */
+
+#ifdef GRN_WITH_ZSTD
+/* grn_ja_reader_read_zstd() reads a value compressed with Zstandard. */
+static grn_rc
+grn_ja_reader_read_zstd(grn_ctx *ctx, grn_ja_reader *reader, void *buf)
+{
+ int src_size, dest_size;
+ grn_ja_einfo *einfo = (grn_ja_einfo *)reader->einfo;
+ if (EHUGE_P(einfo)) {
+ grn_io *io = reader->ja->io;
+ void *seg_addr;
+ char *packed_ptr;
+ uint32_t size, seg_id;
+ if (reader->packed_size > reader->packed_buf_size) {
+ void *new_buf = GRN_REALLOC(reader->packed_buf, reader->packed_size);
+ if (!new_buf) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ reader->packed_buf = new_buf;
+ reader->packed_buf_size = reader->packed_size;
+ }
+ packed_ptr = (char *)reader->packed_buf;
+ grn_memcpy(packed_ptr, (char *)reader->body_seg_addr + sizeof(uint64_t),
+ io->header->segment_size - sizeof(uint64_t));
+ packed_ptr += io->header->segment_size - sizeof(uint64_t);
+ size = reader->packed_size - (io->header->segment_size - sizeof(uint64_t));
+ seg_id = reader->body_seg_id + 1;
+ while (size > io->header->segment_size) {
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(packed_ptr, seg_addr, io->header->segment_size);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ seg_id++;
+ size -= io->header->segment_size;
+ packed_ptr += io->header->segment_size;
+ }
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(packed_ptr, seg_addr, size);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ seg_id++;
+ src_size = (int)(reader->packed_size - sizeof(uint64_t));
+ dest_size = ZSTD_decompress(reader->packed_buf, reader->value_size,
+ buf, src_size);
+ } else {
+ char *packed_addr = (char *)reader->body_seg_addr;
+ packed_addr += reader->body_seg_offset + sizeof(uint64_t);
+ src_size = (int)(reader->packed_size - sizeof(uint64_t));
+ dest_size = ZSTD_decompress(packed_addr, reader->value_size,
+ buf, src_size);
+ }
+ if ((uint32_t)dest_size != reader->value_size) {
+ return GRN_ZSTD_ERROR;
+ }
+ return GRN_SUCCESS;
+}
+#endif /* GRN_WITH_ZSTD */
+
+/* grn_ja_reader_read_raw() reads a value. */
+static grn_rc
+grn_ja_reader_read_raw(grn_ctx *ctx, grn_ja_reader *reader, void *buf)
+{
+ grn_io *io = reader->ja->io;
+ grn_ja_einfo *einfo = (grn_ja_einfo *)reader->einfo;
+ if (ETINY_P(einfo)) {
+ grn_memcpy(buf, einfo, reader->value_size);
+ } else if (EHUGE_P(einfo)) {
+ char *buf_ptr = (char *)buf;
+ void *seg_addr;
+ uint32_t seg_id = reader->body_seg_id;
+ uint32_t size = reader->value_size;
+ while (size > io->header->segment_size) {
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(buf_ptr, seg_addr, io->header->segment_size);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ seg_id++;
+ size -= io->header->segment_size;
+ buf_ptr += io->header->segment_size;
+ }
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(buf_ptr, seg_addr, size);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ seg_id++;
+ } else {
+ if (!reader->body_seg_addr) {
+ GRN_IO_SEG_REF(io, reader->body_seg_id, reader->body_seg_addr);
+ if (!reader->body_seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+ grn_memcpy(buf, (char *)reader->body_seg_addr + reader->body_seg_offset,
+ reader->value_size);
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ja_reader_read(grn_ctx *ctx, grn_ja_reader *reader, void *buf)
+{
+ switch (reader->ja->header->flags & GRN_OBJ_COMPRESS_MASK) {
+#ifdef GRN_WITH_ZLIB
+ case GRN_OBJ_COMPRESS_ZLIB :
+ return grn_ja_reader_read_zlib(ctx, reader, buf);
+#endif /* GRN_WITH_ZLIB */
+#ifdef GRN_WITH_LZ4
+ case GRN_OBJ_COMPRESS_LZ4 :
+ return grn_ja_reader_read_lz4(ctx, reader, buf);
+#endif /* GRN_WITH_LZ4 */
+#ifdef GRN_WITH_ZSTD
+ case GRN_OBJ_COMPRESS_ZSTD :
+ return grn_ja_reader_read_zstd(ctx, reader, buf);
+#endif /* GRN_WITH_ZSTD */
+ default :
+ return grn_ja_reader_read_raw(ctx, reader, buf);
+ }
+}
+
+#ifdef GRN_WITH_ZLIB
+/* grn_ja_reader_pread_zlib() reads a part of a value compressed with zlib. */
+static grn_rc
+grn_ja_reader_pread_zlib(grn_ctx *ctx, grn_ja_reader *reader,
+ size_t offset, size_t size, void *buf)
+{
+ /* TODO: To be supported? */
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+}
+#endif /* GRN_WITH_ZLIB */
+
+#ifdef GRN_WITH_LZ4
+/* grn_ja_reader_pread_lz4() reads a part of a value compressed with LZ4. */
+static grn_rc
+grn_ja_reader_pread_lz4(grn_ctx *ctx, grn_ja_reader *reader,
+ size_t offset, size_t size, void *buf)
+{
+ /* TODO: To be supported? */
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+}
+#endif /* GRN_WITH_LZ4 */
+
+#ifdef GRN_WITH_ZSTD
+/* grn_ja_reader_pread_zstd() reads a part of a value compressed with ZSTD. */
+static grn_rc
+grn_ja_reader_pread_zstd(grn_ctx *ctx, grn_ja_reader *reader,
+ size_t offset, size_t size, void *buf)
+{
+ /* TODO: To be supported? */
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+}
+#endif /* GRN_WITH_ZSTD */
+
+/* grn_ja_reader_pread_raw() reads a part of a value. */
+static grn_rc
+grn_ja_reader_pread_raw(grn_ctx *ctx, grn_ja_reader *reader,
+ size_t offset, size_t size, void *buf)
+{
+ grn_io *io = reader->ja->io;
+ grn_ja_einfo *einfo = (grn_ja_einfo *)reader->einfo;
+ if ((offset >= reader->value_size) || !size) {
+ return GRN_SUCCESS;
+ }
+ if (size > (reader->value_size - offset)) {
+ size = reader->value_size - offset;
+ }
+ if (ETINY_P(einfo)) {
+ grn_memcpy(buf, (char *)einfo + offset, size);
+ } else if (EHUGE_P(einfo)) {
+ char *buf_ptr = (char *)buf;
+ void *seg_addr;
+ uint32_t seg_id = reader->body_seg_id;
+ if (offset >= io->header->segment_size) {
+ seg_id += offset / io->header->segment_size;
+ offset %= io->header->segment_size;
+ }
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(buf_ptr, (char *)seg_addr + offset,
+ io->header->segment_size - offset);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ seg_id++;
+ size -= io->header->segment_size - offset;
+ buf_ptr += io->header->segment_size - offset;
+ while (size > io->header->segment_size) {
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(buf_ptr, (char *)seg_addr, io->header->segment_size);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ seg_id++;
+ size -= io->header->segment_size;
+ buf_ptr += io->header->segment_size;
+ }
+ GRN_IO_SEG_REF(io, seg_id, seg_addr);
+ if (!seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ grn_memcpy(buf_ptr, seg_addr, size);
+ GRN_IO_SEG_UNREF(io, seg_id);
+ } else {
+ if (!reader->body_seg_addr) {
+ GRN_IO_SEG_REF(io, reader->body_seg_id, reader->body_seg_addr);
+ if (!reader->body_seg_addr) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+ offset += reader->body_seg_offset;
+ grn_memcpy(buf, (char *)reader->body_seg_addr + offset, size);
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ja_reader_pread(grn_ctx *ctx, grn_ja_reader *reader,
+ size_t offset, size_t size, void *buf)
+{
+ switch (reader->ja->header->flags & GRN_OBJ_COMPRESS_MASK) {
+#ifdef GRN_WITH_ZLIB
+ case GRN_OBJ_COMPRESS_ZLIB :
+ return grn_ja_reader_pread_zlib(ctx, reader, offset, size, buf);
+#endif /* GRN_WITH_ZLIB */
+#ifdef GRN_WITH_LZ4
+ case GRN_OBJ_COMPRESS_LZ4 :
+ return grn_ja_reader_pread_lz4(ctx, reader, offset, size, buf);
+#endif /* GRN_WITH_LZ4 */
+#ifdef GRN_WITH_ZSTD
+ case GRN_OBJ_COMPRESS_ZSTD :
+ return grn_ja_reader_pread_zstd(ctx, reader, offset, size, buf);
+#endif /* GRN_WITH_ZSTD */
+ default :
+ return grn_ja_reader_pread_raw(ctx, reader, offset, size, buf);
+ }
+}
+
/**** vgram ****/
/*
@@ -1587,10 +2644,10 @@ grn_vgram *
grn_vgram_create(const char *path)
{
grn_vgram *s;
- if (!(s = GRN_GMALLOC(sizeof(grn_vgram)))) { return NULL; }
+ if (!(s = GRN_MALLOCN(grn_vgram, 1))) { return NULL; }
s->vgram = grn_sym_create(path, sizeof(grn_id) * 2, 0, GRN_ENC_NONE);
if (!s->vgram) {
- GRN_GFREE(s);
+ GRN_FREE(s);
return NULL;
}
return s;
@@ -1600,10 +2657,10 @@ grn_vgram *
grn_vgram_open(const char *path)
{
grn_vgram *s;
- if (!(s = GRN_GMALLOC(sizeof(grn_vgram)))) { return NULL; }
+ if (!(s = GRN_MALLOCN(grn_vgram, 1))) { return NULL; }
s->vgram = grn_sym_open(path);
if (!s->vgram) {
- GRN_GFREE(s);
+ GRN_FREE(s);
return NULL;
}
return s;
@@ -1613,13 +2670,13 @@ grn_vgram_buf *
grn_vgram_buf_open(size_t len)
{
grn_vgram_buf *b;
- if (!(b = GRN_GMALLOC(sizeof(grn_vgram_buf)))) { return NULL; }
+ if (!(b = GRN_MALLOCN(grn_vgram_buf, 1))) { return NULL; }
b->len = len;
- b->tvs = b->tvp = GRN_GMALLOC(sizeof(grn_id) * len);
- if (!b->tvp) { GRN_GFREE(b); return NULL; }
+ b->tvs = b->tvp = GRN_MALLOCN(grn_id, len);
+ if (!b->tvp) { GRN_FREE(b); return NULL; }
b->tve = b->tvs + len;
- b->vps = b->vpp = GRN_GMALLOC(sizeof(grn_vgram_vnode) * len * 2);
- if (!b->vpp) { GRN_GFREE(b->tvp); GRN_GFREE(b); return NULL; }
+ b->vps = b->vpp = GRN_MALLOCN(grn_vgram_vnode, len * 2);
+ if (!b->vpp) { GRN_FREE(b->tvp); GRN_FREE(b); return NULL; }
b->vpe = b->vps + len;
return b;
}
@@ -1739,7 +2796,7 @@ grn_vgram_update(grn_vgram *vgram, grn_id rid, grn_vgram_buf *b, grn_hash *terms
int skip = 0;
grn_set_eh *ehs, *ehp, *ehe;
grn_set_sort_optarg arg;
- uint8_t *ps = GRN_GMALLOC(b->len * 2), *pp, *pe;
+ uint8_t *ps = GRN_MALLOC(b->len * 2), *pp, *pe;
if (!ps) {
grn_set_close(th);
return GRN_NO_MEMORY_AVAILABLE;
@@ -1751,7 +2808,7 @@ grn_vgram_update(grn_vgram *vgram, grn_id rid, grn_vgram_buf *b, grn_hash *terms
arg.compar_arg = (void *)(intptr_t)sizeof(grn_id);
ehs = grn_set_sort(th, 0, &arg);
if (!ehs) {
- GRN_GFREE(ps);
+ GRN_FREE(ps);
grn_set_close(th);
return GRN_NO_MEMORY_AVAILABLE;
}
@@ -1775,8 +2832,8 @@ grn_vgram_update(grn_vgram *vgram, grn_id rid, grn_vgram_buf *b, grn_hash *terms
len_sum += b->len;
img_sum += pp - ps;
skip_sum += skip;
- GRN_GFREE(ehs);
- GRN_GFREE(ps);
+ GRN_FREE(ehs);
+ GRN_FREE(ps);
}
grn_set_close(th);
}
@@ -1788,9 +2845,9 @@ grn_rc
grn_vgram_buf_close(grn_vgram_buf *b)
{
if (!b) { return GRN_INVALID_ARGUMENT; }
- if (b->tvs) { GRN_GFREE(b->tvs); }
- if (b->vps) { GRN_GFREE(b->vps); }
- GRN_GFREE(b);
+ if (b->tvs) { GRN_FREE(b->tvs); }
+ if (b->vps) { GRN_FREE(b->vps); }
+ GRN_FREE(b);
return GRN_SUCCESS;
}
@@ -1800,7 +2857,7 @@ grn_vgram_close(grn_vgram *vgram)
if (!vgram) { return GRN_INVALID_ARGUMENT; }
GRN_LOG(ctx, GRN_LOG_DEBUG, "len=%d img=%d skip=%d simple=%d", len_sum, img_sum, skip_sum, simple_sum);
grn_sym_close(vgram->vgram);
- GRN_GFREE(vgram);
+ GRN_FREE(vgram);
return GRN_SUCCESS;
}
*/
diff --git a/storage/mroonga/vendor/groonga/lib/str.c b/storage/mroonga/vendor/groonga/lib/str.c
index 1bbe43a591c..d5b4e716bd2 100644
--- a/storage/mroonga/vendor/groonga/lib/str.c
+++ b/storage/mroonga/vendor/groonga/lib/str.c
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/* Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,11 +16,11 @@
*/
#include "grn.h"
#include <limits.h>
-#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "grn_db.h"
#include "grn_str.h"
+#include "grn_nfkc.h"
#ifndef _ISOC99_SOURCE
#define _ISOC99_SOURCE
@@ -35,11 +35,6 @@
# endif /* _WIN64 */
#endif /* defined(HAVE__GMTIME64_S) && defined(__GNUC__) */
-/* For Visual C++ 2010. Drop the code when we drop Visual C++ 2010 support. */
-#if defined(_MSC_VER) && _MSC_VER < 1800
-# define va_copy(destination, source) destination = source
-#endif
-
inline static int
grn_str_charlen_utf8(grn_ctx *ctx, const unsigned char *str, const unsigned char *end)
{
@@ -95,7 +90,6 @@ grn_str_charlen(grn_ctx *ctx, const char *str, grn_encoding encoding)
}
}
return 1;
- break;
case GRN_ENC_UTF8 :
if (*p & 0x80) {
int b, w;
@@ -115,7 +109,6 @@ grn_str_charlen(grn_ctx *ctx, const char *str, grn_encoding encoding)
} else {
return 1;
}
- break;
case GRN_ENC_SJIS :
if (*p & 0x80) {
/* we regard 0xa0 as JIS X 0201 KANA. adjusted to other tools. */
@@ -132,10 +125,8 @@ grn_str_charlen(grn_ctx *ctx, const char *str, grn_encoding encoding)
} else {
return 1;
}
- break;
default :
return 1;
- break;
}
return 0;
}
@@ -159,10 +150,8 @@ grn_charlen_(grn_ctx *ctx, const char *str, const char *end, grn_encoding encodi
}
}
return 1;
- break;
case GRN_ENC_UTF8 :
return grn_str_charlen_utf8(ctx, p, (unsigned char *)end);
- break;
case GRN_ENC_SJIS :
if (*p & 0x80) {
/* we regard 0xa0 as JIS X 0201 KANA. adjusted to other tools. */
@@ -179,10 +168,8 @@ grn_charlen_(grn_ctx *ctx, const char *str, const char *end, grn_encoding encodi
} else {
return 1;
}
- break;
default :
return 1;
- break;
}
return 0;
}
@@ -441,9 +428,6 @@ normalize_euc(grn_ctx *ctx, grn_str *nstr)
}
#ifdef GRN_WITH_NFKC
-const char *grn_nfkc_map1(const unsigned char *str);
-const char *grn_nfkc_map2(const unsigned char *prefix, const unsigned char *suffix);
-
inline static grn_rc
normalize_utf8(grn_ctx *ctx, grn_str *nstr)
{
@@ -479,13 +463,13 @@ normalize_utf8(grn_ctx *ctx, grn_str *nstr)
if (!(ls = grn_str_charlen_utf8(ctx, s, e))) {
break;
}
- if ((p = (unsigned char *)grn_nfkc_map1(s))) {
+ if ((p = (unsigned char *)grn_nfkc_decompose(s))) {
pe = p + strlen((char *)p);
} else {
p = s;
pe = p + ls;
}
- if (d_ && (p2 = (unsigned char *)grn_nfkc_map2(d_, p))) {
+ if (d_ && (p2 = (unsigned char *)grn_nfkc_compose(d_, p))) {
p = p2;
pe = p + strlen((char *)p);
if (cp) { cp--; }
@@ -1480,24 +1464,29 @@ grn_atoui(const char *nptr, const char *end, const char **rest)
int64_t
grn_atoll(const char *nptr, const char *end, const char **rest)
{
- /* FIXME: INT_MIN is not supported */
const char *p = nptr;
- int n = 0, o = 0;
- int64_t v = 0, t;
+ int o = 0;
+ int64_t v = 0;
if (p < end && *p == '-') {
p++;
- n = 1;
o = 1;
- }
- while (p < end && *p >= '0' && *p <= '9') {
- t = v * 10 + (*p - '0');
- if (t < v) { v = 0; break; }
- v = t;
- o = 0;
- p++;
+ while (p < end && *p >= '0' && *p <= '9') {
+ int64_t t = v * 10 - (*p - '0');
+ if (t > v) { v = 0; break; }
+ v = t;
+ o = 0;
+ p++;
+ }
+ } else {
+ while (p < end && *p >= '0' && *p <= '9') {
+ int64_t t = v * 10 + (*p - '0');
+ if (t < v) { v = 0; break; }
+ v = t;
+ p++;
+ }
}
if (rest) { *rest = o ? nptr : p; }
- return n ? -v : v;
+ return v;
}
uint64_t
@@ -1776,25 +1765,35 @@ grn_aton(grn_ctx *ctx, const char *p, const char *end, const char **rest,
grn_obj_reinit(ctx, res, GRN_DB_INT64, 0);
GRN_INT64_SET(ctx, res, int64);
}
- } else if (rest_char == '.' || rest_char == 'e' || rest_char == 'E' ||
- (rest_char >= '0' && rest_char <= '9')) {
- char *rest_float;
- double d;
- errno = 0;
- d = strtod(p, &rest_float);
- if (!errno && rest_float == end) {
- grn_obj_reinit(ctx, res, GRN_DB_FLOAT, 0);
- GRN_FLOAT_SET(ctx, res, d);
- *rest = rest_float;
- } else {
- return GRN_INVALID_ARGUMENT;
+ } else {
+ if (*p != '-' && rest_char >= '0' && rest_char <= '9') {
+ uint64_t uint64 = grn_atoull(p, end, rest);
+ if (end == *rest) {
+ grn_obj_reinit(ctx, res, GRN_DB_UINT64, 0);
+ GRN_UINT64_SET(ctx, res, uint64);
+ }
+ }
+ if (end != *rest) {
+ if (rest_char == '.' || rest_char == 'e' || rest_char == 'E' ||
+ (rest_char >= '0' && rest_char <= '9')) {
+ char *rest_float;
+ double d;
+ errno = 0;
+ d = strtod(p, &rest_float);
+ if (!errno && rest_float == end) {
+ grn_obj_reinit(ctx, res, GRN_DB_FLOAT, 0);
+ GRN_FLOAT_SET(ctx, res, d);
+ *rest = rest_float;
+ } else {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
}
}
}
break;
default :
return GRN_INVALID_ARGUMENT;
- break;
}
return GRN_SUCCESS;
@@ -2099,7 +2098,7 @@ ftoa_(grn_ctx *ctx, grn_obj *buf, double d)
char *start;
size_t before_size;
size_t len;
-#define DIGIT_NUMBER 15
+#define DIGIT_NUMBER 16
#define FIRST_BUFFER_SIZE (DIGIT_NUMBER + 4)
before_size = GRN_BULK_VSIZE(buf);
grn_bulk_reserve(ctx, buf, FIRST_BUFFER_SIZE);
@@ -2530,13 +2529,13 @@ grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args)
format, copied_args);
va_end(copied_args);
- if (written_size < rest_size) {
+ if (0 <= written_size && written_size < rest_size) {
is_written = GRN_TRUE;
}
}
+ if (!is_written) {
#ifdef WIN32
- if (written_size == -1 && errno == ERANGE) {
# define N_NEW_SIZES 3
int i;
int new_sizes[N_NEW_SIZES];
@@ -2563,9 +2562,7 @@ grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args)
}
}
# undef N_NEW_SIZES
- }
#else /* WIN32 */
- if (!is_written) {
grn_rc rc;
int required_size = written_size + 1; /* "+ 1" for terminate '\0'. */
@@ -2575,8 +2572,8 @@ grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args)
}
written_size = vsnprintf(GRN_BULK_CURR(bulk), required_size,
format, args);
- }
#endif /* WIN32 */
+ }
if (written_size < 0) {
return GRN_INVALID_ARGUMENT;
@@ -2864,62 +2861,100 @@ grn_text_otoj(grn_ctx *ctx, grn_obj *bulk, grn_obj *obj, grn_obj_format *format)
break;
case GRN_UVECTOR :
if (format) {
- int i, j;
- grn_id *v = (grn_id *)GRN_BULK_HEAD(obj), *ve = (grn_id *)GRN_BULK_CURR(obj);
- int ncolumns = GRN_BULK_VSIZE(&format->columns) / sizeof(grn_obj *);
- grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
- GRN_TEXT_PUTS(ctx, bulk, "[[");
- grn_text_itoa(ctx, bulk, ve - v);
- GRN_TEXT_PUTC(ctx, bulk, ']');
- if (v < ve) {
- if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
- GRN_TEXT_PUTS(ctx, bulk, ",[");
- for (j = 0; j < ncolumns; j++) {
- grn_id range_id;
- if (j) { GRN_TEXT_PUTC(ctx, bulk, ','); }
- GRN_TEXT_PUTS(ctx, bulk, "[");
- GRN_BULK_REWIND(&buf);
- grn_column_name_(ctx, columns[j], &buf);
- grn_text_otoj(ctx, bulk, &buf, NULL);
+ if (format->flags & GRN_OBJ_FORMAT_WITH_WEIGHT) {
+ int i, n;
+ grn_obj *domain;
+
+ n = grn_uvector_size(ctx, obj);
+ domain = grn_ctx_at(ctx, obj->header.domain);
+ GRN_TEXT_PUTS(ctx, bulk, "{");
+ for (i = 0; i < n; i++) {
+ grn_id id;
+ unsigned int weight;
+
+ if (i > 0) {
GRN_TEXT_PUTC(ctx, bulk, ',');
- /* column range */
- range_id = grn_obj_get_range(ctx, columns[j]);
- if (range_id == GRN_ID_NIL) {
- GRN_TEXT_PUTS(ctx, bulk, "null");
+ }
+ id = grn_uvector_get_element(ctx, obj, i, &weight);
+ if (domain) {
+ if (domain->header.type == GRN_TABLE_NO_KEY) {
+ GRN_TEXT_PUTC(ctx, bulk, '"');
+ grn_text_ulltoa(ctx, bulk, id);
+ GRN_TEXT_PUTC(ctx, bulk, '"');
} else {
- int name_len;
- grn_obj *range_obj;
- char name_buf[GRN_TABLE_MAX_KEY_SIZE];
-
- range_obj = grn_ctx_at(ctx, range_id);
- name_len = grn_obj_name(ctx, range_obj, name_buf,
- GRN_TABLE_MAX_KEY_SIZE);
GRN_BULK_REWIND(&buf);
- GRN_TEXT_PUT(ctx, &buf, name_buf, name_len);
+ grn_table_get_key2(ctx, domain, id, &buf);
grn_text_otoj(ctx, bulk, &buf, NULL);
}
- GRN_TEXT_PUTS(ctx, bulk, "]");
+ } else {
+ GRN_TEXT_PUTC(ctx, bulk, '"');
+ grn_text_ulltoa(ctx, bulk, id);
+ GRN_TEXT_PUTC(ctx, bulk, '"');
}
- GRN_TEXT_PUTC(ctx, bulk, ']');
+ GRN_TEXT_PUTC(ctx, bulk, ':');
+ grn_text_ulltoa(ctx, bulk, weight);
}
- for (i = 0;; i++) {
- GRN_TEXT_PUTS(ctx, bulk, ",[");
- for (j = 0; j < ncolumns; j++) {
- if (j) { GRN_TEXT_PUTC(ctx, bulk, ','); }
- GRN_BULK_REWIND(&buf);
- grn_obj_get_value(ctx, columns[j], *v, &buf);
- grn_text_otoj(ctx, bulk, &buf, NULL);
+ GRN_TEXT_PUTS(ctx, bulk, "}");
+ } else {
+ /* TODO: Does we still need this code? If we don't need this, we should
+ remove this. */
+ int i, j;
+ grn_id *v = (grn_id *)GRN_BULK_HEAD(obj), *ve = (grn_id *)GRN_BULK_CURR(obj);
+ int ncolumns = GRN_BULK_VSIZE(&format->columns) / sizeof(grn_obj *);
+ grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
+ GRN_TEXT_PUTS(ctx, bulk, "[[");
+ grn_text_itoa(ctx, bulk, ve - v);
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ if (v < ve) {
+ if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
+ GRN_TEXT_PUTS(ctx, bulk, ",[");
+ for (j = 0; j < ncolumns; j++) {
+ grn_id range_id;
+ if (j) { GRN_TEXT_PUTC(ctx, bulk, ','); }
+ GRN_TEXT_PUTS(ctx, bulk, "[");
+ GRN_BULK_REWIND(&buf);
+ grn_column_name_(ctx, columns[j], &buf);
+ grn_text_otoj(ctx, bulk, &buf, NULL);
+ GRN_TEXT_PUTC(ctx, bulk, ',');
+ /* column range */
+ range_id = grn_obj_get_range(ctx, columns[j]);
+ if (range_id == GRN_ID_NIL) {
+ GRN_TEXT_PUTS(ctx, bulk, "null");
+ } else {
+ int name_len;
+ grn_obj *range_obj;
+ char name_buf[GRN_TABLE_MAX_KEY_SIZE];
+
+ range_obj = grn_ctx_at(ctx, range_id);
+ name_len = grn_obj_name(ctx, range_obj, name_buf,
+ GRN_TABLE_MAX_KEY_SIZE);
+ GRN_BULK_REWIND(&buf);
+ GRN_TEXT_PUT(ctx, &buf, name_buf, name_len);
+ grn_text_otoj(ctx, bulk, &buf, NULL);
+ }
+ GRN_TEXT_PUTS(ctx, bulk, "]");
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ']');
}
- GRN_TEXT_PUTC(ctx, bulk, ']');
- v++;
- if (v < ve) {
- GRN_TEXT_PUTC(ctx, bulk, ',');
- } else {
- break;
+ for (i = 0;; i++) {
+ GRN_TEXT_PUTS(ctx, bulk, ",[");
+ for (j = 0; j < ncolumns; j++) {
+ if (j) { GRN_TEXT_PUTC(ctx, bulk, ','); }
+ GRN_BULK_REWIND(&buf);
+ grn_obj_get_value(ctx, columns[j], *v, &buf);
+ grn_text_otoj(ctx, bulk, &buf, NULL);
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ v++;
+ if (v < ve) {
+ GRN_TEXT_PUTC(ctx, bulk, ',');
+ } else {
+ break;
+ }
}
}
+ GRN_TEXT_PUTC(ctx, bulk, ']');
}
- GRN_TEXT_PUTC(ctx, bulk, ']');
} else {
grn_obj *range = grn_ctx_at(ctx, obj->header.domain);
if (range && range->header.type == GRN_TYPE) {
@@ -2983,7 +3018,11 @@ grn_text_otoj(grn_ctx *ctx, grn_obj *bulk, grn_obj *obj, grn_obj_format *format)
GRN_UINT32_INIT(&weight, 0);
with_weight = (format && format->flags & GRN_OBJ_FORMAT_WITH_WEIGHT);
n = grn_vector_size(ctx, obj);
- GRN_TEXT_PUTC(ctx, bulk, '[');
+ if (with_weight) {
+ GRN_TEXT_PUTC(ctx, bulk, '{');
+ } else {
+ GRN_TEXT_PUTC(ctx, bulk, '[');
+ }
for (i = 0; i < n; i++) {
const char *_value;
unsigned int _weight, length;
@@ -2997,19 +3036,19 @@ grn_text_otoj(grn_ctx *ctx, grn_obj *bulk, grn_obj *obj, grn_obj_format *format)
} else {
grn_obj_reinit(ctx, &value, obj->header.domain, 0);
}
- if (with_weight) {
- GRN_TEXT_PUTC(ctx, bulk, '{');
- }
grn_bulk_write(ctx, &value, _value, length);
grn_text_otoj(ctx, bulk, &value, NULL);
if (with_weight) {
GRN_TEXT_PUTC(ctx, bulk, ':');
GRN_UINT32_SET(ctx, &weight, _weight);
grn_text_otoj(ctx, bulk, &weight, NULL);
- GRN_TEXT_PUTC(ctx, bulk, '}');
}
}
- GRN_TEXT_PUTC(ctx, bulk, ']');
+ if (with_weight) {
+ GRN_TEXT_PUTC(ctx, bulk, '}');
+ } else {
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ }
GRN_OBJ_FIN(ctx, &value);
GRN_OBJ_FIN(ctx, &weight);
}
@@ -3223,22 +3262,6 @@ grn_str_url_path_normalize(grn_ctx *ctx, const char *path, size_t path_len,
*b = '\0';
}
-grn_rc
-grn_text_fgets(grn_ctx *ctx, grn_obj *buf, FILE *fp)
-{
- size_t len;
- grn_rc rc = GRN_END_OF_DATA;
- for (;;) {
- grn_bulk_reserve(ctx, buf, BUFSIZ);
- if (!fgets(GRN_BULK_CURR(buf), BUFSIZ, fp)) { break; }
- if (!(len = strlen(GRN_BULK_CURR(buf)))) { break; }
- GRN_BULK_INCR_LEN(buf, len);
- rc = GRN_SUCCESS;
- if (GRN_BULK_CURR(buf)[-1] == '\n') { break; }
- }
- return rc;
-}
-
grn_bool
grn_bulk_is_zero(grn_ctx *ctx, grn_obj *obj)
{
diff --git a/storage/mroonga/vendor/groonga/lib/string.c b/storage/mroonga/vendor/groonga/lib/string.c
index 3249865b900..3ba8b8678c0 100644
--- a/storage/mroonga/vendor/groonga/lib/string.c
+++ b/storage/mroonga/vendor/groonga/lib/string.c
@@ -245,6 +245,9 @@ grn_string_get_normalized(grn_ctx *ctx, grn_obj *string,
if (n_characters) { *n_characters = string_->n_characters; }
rc = GRN_SUCCESS;
} else {
+ if (normalized) { *normalized = NULL; }
+ if (length_in_bytes) { *length_in_bytes = 0; }
+ if (n_characters) { *n_characters = 0; }
rc = GRN_INVALID_ARGUMENT;
}
GRN_API_RETURN(rc);
diff --git a/storage/mroonga/vendor/groonga/lib/table.c b/storage/mroonga/vendor/groonga/lib/table.c
new file mode 100644
index 00000000000..72a2f280b2f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/table.c
@@ -0,0 +1,122 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn.h"
+#include "grn_ctx.h"
+#include "grn_expr_executor.h"
+
+grn_rc
+grn_table_apply_expr(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *output_column,
+ grn_obj *expr)
+{
+ grn_expr_executor *executor;
+
+ GRN_API_ENTER;
+
+ if (!grn_obj_is_data_column(ctx, output_column)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, output_column);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][apply-expr] output column isn't data column: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ if (!grn_obj_is_expr(ctx, expr)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, expr);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][apply-expr] expr is invalid: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ executor = grn_expr_executor_open(ctx, expr);
+ if (!executor) {
+ GRN_API_RETURN(ctx->rc);
+ }
+ GRN_TABLE_EACH_BEGIN_FLAGS(ctx, table, cursor, id, GRN_CURSOR_BY_ID) {
+ grn_obj *value;
+ value = grn_expr_executor_exec(ctx, executor, id);
+ if (ctx->rc != GRN_SUCCESS) {
+ break;
+ }
+ if (value) {
+ grn_obj_set_value(ctx, output_column, id, value, GRN_OBJ_SET);
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ grn_expr_executor_close(ctx, executor);
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_id
+grn_table_find_reference_object(grn_ctx *ctx, grn_obj *table)
+{
+ grn_id table_id;
+ grn_id reference_object_id = GRN_ID_NIL;
+
+ GRN_API_ENTER;
+
+ if (!grn_obj_is_table(ctx, table)) {
+ GRN_API_RETURN(GRN_ID_NIL);
+ }
+
+ table_id = DB_OBJ(table)->id;
+
+ GRN_DB_SPEC_EACH_BEGIN(ctx, cursor, id, spec) {
+ if (id == table_id) {
+ continue;
+ }
+
+ switch (spec->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ if (spec->header.domain == table_id) {
+ reference_object_id = id;
+ }
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_FIX_SIZE :
+ if (spec->header.domain == table_id) {
+ break;
+ }
+ if (spec->range == table_id) {
+ reference_object_id = id;
+ }
+ break;
+ default :
+ break;
+ }
+
+ if (reference_object_id != GRN_ID_NIL) {
+ break;
+ }
+ } GRN_DB_SPEC_EACH_END(ctx, cursor);
+
+ GRN_API_RETURN(reference_object_id);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/thread.c b/storage/mroonga/vendor/groonga/lib/thread.c
new file mode 100644
index 00000000000..c598b7aa283
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/thread.c
@@ -0,0 +1,59 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_ctx.h"
+
+static grn_thread_get_limit_func get_limit_func = NULL;
+static void *get_limit_func_data = NULL;
+static grn_thread_set_limit_func set_limit_func = NULL;
+static void *set_limit_func_data = NULL;
+
+uint32_t
+grn_thread_get_limit(void)
+{
+ if (get_limit_func) {
+ return get_limit_func(get_limit_func_data);
+ } else {
+ return 0;
+ }
+}
+
+void
+grn_thread_set_limit(uint32_t new_limit)
+{
+ if (!set_limit_func) {
+ return;
+ }
+
+ set_limit_func(new_limit, set_limit_func_data);
+}
+
+void
+grn_thread_set_get_limit_func(grn_thread_get_limit_func func,
+ void *data)
+{
+ get_limit_func = func;
+ get_limit_func_data = data;
+}
+
+void
+grn_thread_set_set_limit_func(grn_thread_set_limit_func func, void *data)
+{
+ set_limit_func = func;
+ set_limit_func_data = data;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/time.c b/storage/mroonga/vendor/groonga/lib/time.c
new file mode 100644
index 00000000000..38fa5086e39
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/time.c
@@ -0,0 +1,245 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_time.h"
+#include "grn_ctx.h"
+#include "grn_str.h"
+
+#include <stdio.h>
+#include <time.h>
+
+#if defined(HAVE__LOCALTIME64_S) && defined(__GNUC__)
+# ifdef _WIN64
+# define localtime_s(tm, time) _localtime64_s(tm, time)
+# else /* _WIN64 */
+# define localtime_s(tm, time) _localtime32_s(tm, time)
+# endif /* _WIN64 */
+#endif /* defined(HAVE__LOCALTIME64_S) && defined(__GNUC__) */
+
+/* fixme by 2038 */
+
+grn_rc
+grn_timeval_now(grn_ctx *ctx, grn_timeval *tv)
+{
+#ifdef HAVE_CLOCK_GETTIME
+ struct timespec t;
+ if (clock_gettime(CLOCK_REALTIME, &t)) {
+ SERR("clock_gettime");
+ } else {
+ tv->tv_sec = t.tv_sec;
+ tv->tv_nsec = t.tv_nsec;
+ }
+ return ctx->rc;
+#else /* HAVE_CLOCK_GETTIME */
+# ifdef WIN32
+ time_t t;
+ struct _timeb tb;
+ time(&t);
+ _ftime(&tb);
+ tv->tv_sec = t;
+ tv->tv_nsec = tb.millitm * (GRN_TIME_NSEC_PER_SEC / 1000);
+ return GRN_SUCCESS;
+# else /* WIN32 */
+ struct timeval t;
+ if (gettimeofday(&t, NULL)) {
+ SERR("gettimeofday");
+ } else {
+ tv->tv_sec = t.tv_sec;
+ tv->tv_nsec = GRN_TIME_USEC_TO_NSEC(t.tv_usec);
+ }
+ return ctx->rc;
+# endif /* WIN32 */
+#endif /* HAVE_CLOCK_GETTIME */
+}
+
+void
+grn_time_now(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_timeval tv;
+ grn_timeval_now(ctx, &tv);
+ GRN_TIME_SET(ctx, obj, GRN_TIME_PACK(tv.tv_sec,
+ GRN_TIME_NSEC_TO_USEC(tv.tv_nsec)));
+}
+
+static grn_bool
+grn_time_t_to_tm(grn_ctx *ctx, const time_t time, struct tm *tm)
+{
+ grn_bool success;
+ const char *function_name;
+#ifdef HAVE__LOCALTIME64_S
+ function_name = "localtime_s";
+ success = (localtime_s(tm, &time) == 0);
+#else /* HAVE__LOCALTIME64_S */
+# ifdef HAVE_LOCALTIME_R
+ function_name = "localtime_r";
+ success = (localtime_r(&time, tm) != NULL);
+# else /* HAVE_LOCALTIME_R */
+ function_name = "localtime";
+ {
+ struct tm *local_tm;
+ local_tm = localtime(&time);
+ if (local_tm) {
+ success = GRN_TRUE;
+ memcpy(tm, local_tm, sizeof(struct tm));
+ } else {
+ success = GRN_FALSE;
+ }
+ }
+# endif /* HAVE_LOCALTIME_R */
+#endif /* HAVE__LOCALTIME64_S */
+ if (!success) {
+ SERR("%s: failed to convert time_t to struct tm: <%" GRN_FMT_INT64D ">",
+ function_name,
+ (int64_t)time);
+ }
+ return success;
+}
+
+struct tm *
+grn_timeval2tm(grn_ctx *ctx, grn_timeval *tv, struct tm *tm)
+{
+ if (grn_time_t_to_tm(ctx, tv->tv_sec, tm)) {
+ return tm;
+ } else {
+ return NULL;
+ }
+}
+
+grn_bool
+grn_time_to_tm(grn_ctx *ctx, int64_t time, struct tm *tm)
+{
+ int64_t sec;
+ int32_t usec;
+
+ GRN_TIME_UNPACK(time, sec, usec);
+ return grn_time_t_to_tm(ctx, sec, tm);
+}
+
+static grn_bool
+grn_time_t_from_tm(grn_ctx *ctx, time_t *time, struct tm *tm)
+{
+ grn_bool success;
+
+ tm->tm_yday = -1;
+ *time = mktime(tm);
+ success = (tm->tm_yday != -1);
+ if (!success) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "mktime: failed to convert struct tm to time_t: "
+ "<%04d-%02d-%02dT%02d:%02d:%02d>(%d)",
+ 1900 + tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ tm->tm_isdst);
+ }
+ return success;
+}
+
+grn_bool
+grn_time_from_tm(grn_ctx *ctx, int64_t *time, struct tm *tm)
+{
+ time_t sec_time_t;
+ int64_t sec;
+ int32_t usec = 0;
+
+ if (!grn_time_t_from_tm(ctx, &sec_time_t, tm)) {
+ return GRN_FALSE;
+ }
+
+ sec = sec_time_t;
+ *time = GRN_TIME_PACK(sec, usec);
+ return GRN_TRUE;
+}
+
+grn_rc
+grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf, size_t buf_size)
+{
+ struct tm tm;
+ struct tm *ltm;
+ ltm = grn_timeval2tm(ctx, tv, &tm);
+ grn_snprintf(buf, buf_size, GRN_TIMEVAL_STR_SIZE,
+ GRN_TIMEVAL_STR_FORMAT,
+ ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday,
+ ltm->tm_hour, ltm->tm_min, ltm->tm_sec,
+ (int)(GRN_TIME_NSEC_TO_USEC(tv->tv_nsec)));
+ if (buf_size > GRN_TIMEVAL_STR_SIZE) {
+ buf[GRN_TIMEVAL_STR_SIZE - 1] = '\0';
+ } else {
+ buf[buf_size - 1] = '\0';
+ }
+ return ctx->rc;
+}
+
+grn_rc
+grn_str2timeval(const char *str, uint32_t str_len, grn_timeval *tv)
+{
+ struct tm tm;
+ const char *r1, *r2, *rend = str + str_len;
+ uint32_t uv;
+ memset(&tm, 0, sizeof(struct tm));
+
+ tm.tm_year = (int)grn_atoui(str, rend, &r1) - 1900;
+ if ((r1 + 1) >= rend || (*r1 != '/' && *r1 != '-')) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ r1++;
+ tm.tm_mon = (int)grn_atoui(r1, rend, &r1) - 1;
+ if ((r1 + 1) >= rend || (*r1 != '/' && *r1 != '-') ||
+ tm.tm_mon < 0 || tm.tm_mon >= 12) { return GRN_INVALID_ARGUMENT; }
+ r1++;
+ tm.tm_mday = (int)grn_atoui(r1, rend, &r1);
+ if ((r1 + 1) >= rend || *r1 != ' ' ||
+ tm.tm_mday < 1 || tm.tm_mday > 31) { return GRN_INVALID_ARGUMENT; }
+
+ tm.tm_hour = (int)grn_atoui(++r1, rend, &r2);
+ if ((r2 + 1) >= rend || r1 == r2 || *r2 != ':' ||
+ tm.tm_hour < 0 || tm.tm_hour >= 24) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ r1 = r2 + 1;
+ tm.tm_min = (int)grn_atoui(r1, rend, &r2);
+ if ((r2 + 1) >= rend || r1 == r2 || *r2 != ':' ||
+ tm.tm_min < 0 || tm.tm_min >= 60) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ r1 = r2 + 1;
+ tm.tm_sec = (int)grn_atoui(r1, rend, &r2);
+ if (r1 == r2 ||
+ tm.tm_sec < 0 || tm.tm_sec > 61 /* leap 2sec */) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ r1 = r2;
+ tm.tm_yday = -1;
+ tm.tm_isdst = -1;
+
+ /* tm_yday is set appropriately (0-365) on successful completion. */
+ tv->tv_sec = mktime(&tm);
+ if (tm.tm_yday == -1) { return GRN_INVALID_ARGUMENT; }
+ if ((r1 + 1) < rend && *r1 == '.') { r1++; }
+ uv = grn_atoi(r1, rend, &r2);
+ while (r2 < r1 + 6) {
+ uv *= 10;
+ r2++;
+ }
+ if (uv >= GRN_TIME_USEC_PER_SEC) { return GRN_INVALID_ARGUMENT; }
+ tv->tv_nsec = GRN_TIME_USEC_TO_NSEC(uv);
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/token_cursor.c b/storage/mroonga/vendor/groonga/lib/token_cursor.c
index ac1c936110b..7aff6ec9c24 100644
--- a/storage/mroonga/vendor/groonga/lib/token_cursor.c
+++ b/storage/mroonga/vendor/groonga/lib/token_cursor.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2014 Brazil
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -24,20 +24,31 @@ static void
grn_token_cursor_open_initialize_token_filters(grn_ctx *ctx,
grn_token_cursor *token_cursor)
{
- grn_obj *token_filters = token_cursor->token_filters;
+ grn_obj *token_filters = token_cursor->token_filter.objects;
unsigned int i, n_token_filters;
+ token_cursor->token_filter.data = NULL;
+
if (token_filters) {
n_token_filters = GRN_BULK_VSIZE(token_filters) / sizeof(grn_obj *);
} else {
n_token_filters = 0;
}
+ if (n_token_filters == 0) {
+ return;
+ }
+
+ token_cursor->token_filter.data = GRN_CALLOC(sizeof(void *) * n_token_filters);
+ if (!token_cursor->token_filter.data) {
+ return;
+ }
+
for (i = 0; i < n_token_filters; i++) {
grn_obj *token_filter_object = GRN_PTR_VALUE_AT(token_filters, i);
grn_proc *token_filter = (grn_proc *)token_filter_object;
- token_filter->user_data =
+ token_cursor->token_filter.data[i] =
token_filter->callbacks.token_filter.init(ctx,
token_cursor->table,
token_cursor->mode);
@@ -54,7 +65,7 @@ grn_token_cursor_open(grn_ctx *ctx, grn_obj *table,
grn_obj *tokenizer;
grn_obj *normalizer;
grn_obj *token_filters;
- grn_obj_flags table_flags;
+ grn_table_flags table_flags;
if (grn_table_get_info(ctx, table, &table_flags, &encoding, &tokenizer,
&normalizer, &token_filters)) {
return NULL;
@@ -64,7 +75,8 @@ grn_token_cursor_open(grn_ctx *ctx, grn_obj *table,
token_cursor->mode = mode;
token_cursor->encoding = encoding;
token_cursor->tokenizer = tokenizer;
- token_cursor->token_filters = token_filters;
+ token_cursor->token_filter.objects = token_filters;
+ token_cursor->token_filter.data = NULL;
token_cursor->orig = (const unsigned char *)str;
token_cursor->orig_blen = str_len;
token_cursor->curr = NULL;
@@ -111,7 +123,9 @@ grn_token_cursor_open(grn_ctx *ctx, grn_obj *table,
}
}
- grn_token_cursor_open_initialize_token_filters(ctx, token_cursor);
+ if (ctx->rc == GRN_SUCCESS) {
+ grn_token_cursor_open_initialize_token_filters(ctx, token_cursor);
+ }
if (ctx->rc) {
grn_token_cursor_close(ctx, token_cursor);
@@ -126,7 +140,7 @@ grn_token_cursor_next_apply_token_filters(grn_ctx *ctx,
grn_obj *current_token_data,
grn_obj *status)
{
- grn_obj *token_filters = token_cursor->token_filters;
+ grn_obj *token_filters = token_cursor->token_filter.objects;
unsigned int i, n_token_filters;
grn_token current_token;
grn_token next_token;
@@ -151,6 +165,7 @@ grn_token_cursor_next_apply_token_filters(grn_ctx *ctx,
for (i = 0; i < n_token_filters; i++) {
grn_obj *token_filter_object = GRN_PTR_VALUE_AT(token_filters, i);
grn_proc *token_filter = (grn_proc *)token_filter_object;
+ void *data = token_cursor->token_filter.data[i];
#define SKIP_FLAGS\
(GRN_TOKEN_SKIP |\
@@ -163,7 +178,7 @@ grn_token_cursor_next_apply_token_filters(grn_ctx *ctx,
token_filter->callbacks.token_filter.filter(ctx,
&current_token,
&next_token,
- token_filter->user_data);
+ data);
GRN_TEXT_SET(ctx, &(current_token.data),
GRN_TEXT_VALUE(&(next_token.data)),
GRN_TEXT_LEN(&(next_token.data)));
@@ -290,7 +305,7 @@ grn_token_cursor_next(grn_ctx *ctx, grn_token_cursor *token_cursor)
}
break;
}
- } else {
+ } else if (token_cursor->mode != GRN_TOKENIZE_ONLY) {
switch (table->header.type) {
case GRN_TABLE_PAT_KEY :
tid = grn_pat_get(ctx, (grn_pat *)table, token_cursor->curr, token_cursor->curr_size, NULL);
@@ -310,7 +325,8 @@ grn_token_cursor_next(grn_ctx *ctx, grn_token_cursor *token_cursor)
break;
}
}
- if (tid == GRN_ID_NIL && token_cursor->status != GRN_TOKEN_CURSOR_DONE) {
+ if (token_cursor->mode != GRN_TOKENIZE_ONLY &&
+ tid == GRN_ID_NIL && token_cursor->status != GRN_TOKEN_CURSOR_DONE) {
token_cursor->status = GRN_TOKEN_CURSOR_NOT_FOUND;
}
token_cursor->pos++;
@@ -323,20 +339,31 @@ static void
grn_token_cursor_close_token_filters(grn_ctx *ctx,
grn_token_cursor *token_cursor)
{
- grn_obj *token_filters = token_cursor->token_filters;
+ grn_obj *token_filters = token_cursor->token_filter.objects;
unsigned int i, n_token_filters;
+ if (!token_cursor->token_filter.data) {
+ return;
+ }
+
if (token_filters) {
n_token_filters = GRN_BULK_VSIZE(token_filters) / sizeof(grn_obj *);
} else {
n_token_filters = 0;
}
+
+ if (n_token_filters == 0) {
+ return;
+ }
+
for (i = 0; i < n_token_filters; i++) {
grn_obj *token_filter_object = GRN_PTR_VALUE_AT(token_filters, i);
grn_proc *token_filter = (grn_proc *)token_filter_object;
+ void *data = token_cursor->token_filter.data[i];
- token_filter->callbacks.token_filter.fin(ctx, token_filter->user_data);
+ token_filter->callbacks.token_filter.fin(ctx, data);
}
+ GRN_FREE(token_cursor->token_filter.data);
}
grn_rc
diff --git a/storage/mroonga/vendor/groonga/lib/token_filter.c b/storage/mroonga/vendor/groonga/lib/token_filter.c
index c57650c2b55..a564bdfb8bd 100644
--- a/storage/mroonga/vendor/groonga/lib/token_filter.c
+++ b/storage/mroonga/vendor/groonga/lib/token_filter.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2015 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -38,7 +38,7 @@ grn_token_filter_register(grn_ctx *ctx,
grn_obj *token_filter_object = grn_proc_create(ctx,
plugin_name_ptr,
plugin_name_length,
- GRN_PROC_TOKENIZER,
+ GRN_PROC_TOKEN_FILTER,
NULL, NULL, NULL, 0, NULL);
if (token_filter_object == NULL) {
GRN_PLUGIN_ERROR(ctx, GRN_TOKEN_FILTER_ERROR,
diff --git a/storage/mroonga/vendor/groonga/lib/tokenizer.c b/storage/mroonga/vendor/groonga/lib/tokenizer.c
index e72d3b43d2b..c247efd2f61 100644
--- a/storage/mroonga/vendor/groonga/lib/tokenizer.c
+++ b/storage/mroonga/vendor/groonga/lib/tokenizer.c
@@ -134,7 +134,7 @@ grn_tokenizer_query_open(grn_ctx *ctx, int num_args, grn_obj **args,
{
grn_obj * const table = args[0];
- grn_obj_flags table_flags;
+ grn_table_flags table_flags;
grn_encoding table_encoding;
unsigned int query_length = GRN_TEXT_LEN(query_str);
char *query_buf = (char *)GRN_PLUGIN_MALLOC(ctx, query_length + 1);
diff --git a/storage/mroonga/vendor/groonga/lib/tokenizers.c b/storage/mroonga/vendor/groonga/lib/tokenizers.c
index c5f112fa8cd..6bd0a1b9e18 100644
--- a/storage/mroonga/vendor/groonga/lib/tokenizers.c
+++ b/storage/mroonga/vendor/groonga/lib/tokenizers.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -237,6 +237,8 @@ delimit_null_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_d
/* ngram tokenizer */
+static grn_bool grn_ngram_tokenizer_remove_blank_disable = GRN_FALSE;
+
typedef struct {
grn_tokenizer_token token;
grn_tokenizer_query *query;
@@ -268,6 +270,9 @@ ngram_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data, ui
unsigned int normalized_length_in_bytes;
grn_ngram_tokenizer *tokenizer;
+ if (grn_ngram_tokenizer_remove_blank_disable) {
+ normalize_flags &= ~GRN_STRING_REMOVE_BLANK;
+ }
query = grn_tokenizer_query_open(ctx, nargs, args, normalize_flags);
if (!query) {
return NULL;
@@ -598,6 +603,7 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
if (is_begin &&
char_len == GRN_TOKENIZER_BEGIN_MARK_UTF8_LEN &&
memcmp(current, GRN_TOKENIZER_BEGIN_MARK_UTF8, char_len) == 0) {
+ tokenizer->is_start_token = GRN_TRUE;
n_characters++;
GRN_TEXT_PUT(ctx, buffer, current, char_len);
current += char_len;
@@ -808,6 +814,17 @@ grn_db_init_builtin_tokenizers(grn_ctx *ctx)
GRN_TEXT_INIT(&vars[1].value, 0);
GRN_UINT32_INIT(&vars[2].value, 0);
+ {
+ char grn_ngram_tokenizer_remove_blank_disable_env[GRN_ENV_BUFFER_SIZE];
+
+ grn_getenv("GRN_NGRAM_TOKENIZER_REMOVE_BLANK_DISABLE",
+ grn_ngram_tokenizer_remove_blank_disable_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_ngram_tokenizer_remove_blank_disable_env[0]) {
+ grn_ngram_tokenizer_remove_blank_disable = GRN_TRUE;
+ }
+ }
+
obj = DEF_TOKENIZER("TokenDelimit",
delimit_init, delimited_next, delimited_fin, vars);
if (!obj || ((grn_db_obj *)obj)->id != GRN_DB_DELIMIT) { return GRN_FILE_CORRUPT; }
diff --git a/storage/mroonga/vendor/groonga/lib/ts.c b/storage/mroonga/vendor/groonga/lib/ts.c
new file mode 100644
index 00000000000..d1e5f095040
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts.c
@@ -0,0 +1,906 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/* TS is an acronym for "Turbo Selector". */
+
+#include "grn_ts.h"
+
+#include "grn_output.h"
+#include "grn_str.h"
+
+#include "ts/ts_buf.h"
+#include "ts/ts_cursor.h"
+#include "ts/ts_expr.h"
+#include "ts/ts_expr_parser.h"
+#include "ts/ts_log.h"
+#include "ts/ts_sorter.h"
+#include "ts/ts_str.h"
+#include "ts/ts_types.h"
+#include "ts/ts_util.h"
+
+#include <string.h>
+
+/*-------------------------------------------------------------
+ * Miscellaneous.
+ */
+
+enum { GRN_TS_BATCH_SIZE = 1024 };
+
+/* grn_ts_bool_output() outputs a value. */
+static grn_rc
+grn_ts_bool_output(grn_ctx *ctx, grn_ts_bool value)
+{
+ if (value) {
+ return grn_bulk_write(ctx, ctx->impl->output.buf, "true", 4);
+ } else {
+ return grn_bulk_write(ctx, ctx->impl->output.buf, "false", 5);
+ }
+}
+
+/* grn_ts_int_output() outputs a value. */
+static grn_rc
+grn_ts_int_output(grn_ctx *ctx, grn_ts_int value)
+{
+ return grn_text_lltoa(ctx, ctx->impl->output.buf, value);
+}
+
+/* grn_ts_float_output() outputs a value. */
+static grn_rc
+grn_ts_float_output(grn_ctx *ctx, grn_ts_float value)
+{
+ return grn_text_ftoa(ctx, ctx->impl->output.buf, value);
+}
+
+/* grn_ts_time_output() outputs a value. */
+static grn_rc
+grn_ts_time_output(grn_ctx *ctx, grn_ts_time value)
+{
+ return grn_text_ftoa(ctx, ctx->impl->output.buf, value * 0.000001);
+}
+
+/* grn_ts_text_output() outputs a value. */
+static grn_rc
+grn_ts_text_output(grn_ctx *ctx, grn_ts_text value)
+{
+ return grn_text_esc(ctx, ctx->impl->output.buf, value.ptr, value.size);
+}
+
+/* grn_ts_geo_output() outputs a value. */
+static grn_rc
+grn_ts_geo_output(grn_ctx *ctx, grn_ts_geo value)
+{
+ grn_rc rc = grn_bulk_write(ctx, ctx->impl->output.buf, "\"", 1);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_text_itoa(ctx, ctx->impl->output.buf, value.latitude);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_bulk_write(ctx, ctx->impl->output.buf, "x", 1);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_text_itoa(ctx, ctx->impl->output.buf, value.longitude);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ return grn_bulk_write(ctx, ctx->impl->output.buf, "\"", 1);
+}
+
+#define GRN_TS_VECTOR_OUTPUT(kind)\
+ size_t i;\
+ grn_rc rc = grn_bulk_write(ctx, ctx->impl->output.buf, "[", 1);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ for (i = 0; i < value.size; ++i) {\
+ if (i) {\
+ rc = grn_bulk_write(ctx, ctx->impl->output.buf, ",", 1);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ }\
+ rc = grn_ts_ ## kind ## _output(ctx, value.ptr[i]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ }\
+ return grn_bulk_write(ctx, ctx->impl->output.buf, "]", 1);
+/* grn_ts_bool_vector_output() outputs a value. */
+static grn_rc
+grn_ts_bool_vector_output(grn_ctx *ctx, grn_ts_bool_vector value)
+{
+ GRN_TS_VECTOR_OUTPUT(bool)
+}
+
+/* grn_ts_int_vector_output() outputs a value. */
+static grn_rc
+grn_ts_int_vector_output(grn_ctx *ctx, grn_ts_int_vector value)
+{
+ GRN_TS_VECTOR_OUTPUT(int)
+}
+
+/* grn_ts_float_vector_output() outputs a value. */
+static grn_rc
+grn_ts_float_vector_output(grn_ctx *ctx, grn_ts_float_vector value)
+{
+ GRN_TS_VECTOR_OUTPUT(float)
+}
+
+/* grn_ts_time_vector_output() outputs a value. */
+static grn_rc
+grn_ts_time_vector_output(grn_ctx *ctx, grn_ts_time_vector value)
+{
+ GRN_TS_VECTOR_OUTPUT(time)
+}
+
+/* grn_ts_text_vector_output() outputs a value. */
+static grn_rc
+grn_ts_text_vector_output(grn_ctx *ctx, grn_ts_text_vector value)
+{
+ GRN_TS_VECTOR_OUTPUT(text)
+}
+
+/* grn_ts_geo_vector_output() outputs a value. */
+static grn_rc
+grn_ts_geo_vector_output(grn_ctx *ctx, grn_ts_geo_vector value)
+{
+ GRN_TS_VECTOR_OUTPUT(geo)
+}
+#undef GRN_TS_VECTOR_OUTPUT
+
+/*-------------------------------------------------------------
+ * grn_ts_writer.
+ */
+
+typedef struct {
+ grn_ts_expr_parser *parser;
+ grn_ts_expr **exprs;
+ size_t n_exprs;
+ size_t max_n_exprs;
+ grn_obj name_buf;
+ grn_ts_str *names;
+ grn_ts_buf *bufs;
+} grn_ts_writer;
+
+/* grn_ts_writer_init() initializes a writer. */
+static void
+grn_ts_writer_init(grn_ctx *ctx, grn_ts_writer *writer)
+{
+ memset(writer, 0, sizeof(*writer));
+ writer->parser = NULL;
+ writer->exprs = NULL;
+ GRN_TEXT_INIT(&writer->name_buf, GRN_OBJ_VECTOR);
+ writer->names = NULL;
+ writer->bufs = NULL;
+}
+
+/* grn_ts_writer_fin() finalizes a writer. */
+static void
+grn_ts_writer_fin(grn_ctx *ctx, grn_ts_writer *writer)
+{
+ size_t i;
+ if (writer->bufs) {
+ for (i = 0; i < writer->n_exprs; i++) {
+ grn_ts_buf_fin(ctx, &writer->bufs[i]);
+ }
+ GRN_FREE(writer->bufs);
+ }
+ if (writer->names) {
+ GRN_FREE(writer->names);
+ }
+ GRN_OBJ_FIN(ctx, &writer->name_buf);
+ if (writer->exprs) {
+ for (i = 0; i < writer->n_exprs; i++) {
+ grn_ts_expr_close(ctx, writer->exprs[i]);
+ }
+ GRN_FREE(writer->exprs);
+ }
+ if (writer->parser) {
+ grn_ts_expr_parser_close(ctx, writer->parser);
+ }
+}
+
+/* grn_ts_writer_expand() expands a wildcard. */
+static grn_rc
+grn_ts_writer_expand(grn_ctx *ctx, grn_ts_writer *writer,
+ grn_obj *table, grn_ts_str str)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_hash_cursor *cursor;
+ grn_hash *hash = grn_hash_create(ctx, NULL, sizeof(grn_ts_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY | GRN_HASH_TINY);
+ if (!hash) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ grn_table_columns(ctx, table, str.ptr, str.size - 1, (grn_obj *)hash);
+ if (ctx->rc != GRN_SUCCESS) {
+ return ctx->rc;
+ }
+ cursor = grn_hash_cursor_open(ctx, hash, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ rc = GRN_INVALID_ARGUMENT;
+ } else {
+ while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ char name_buf[GRN_TABLE_MAX_KEY_SIZE];
+ size_t name_size;
+ grn_obj *column;
+ grn_ts_id *column_id;
+ if (!grn_hash_cursor_get_key(ctx, cursor, (void **)&column_id)) {
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ }
+ column = grn_ctx_at(ctx, *column_id);
+ if (!column) {
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ }
+ name_size = grn_column_name(ctx, column, name_buf, sizeof(name_buf));
+ grn_obj_unlink(ctx, column);
+ rc = grn_vector_add_element(ctx, &writer->name_buf,
+ name_buf, name_size, 0, GRN_DB_TEXT);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ grn_hash_cursor_close(ctx, cursor);
+ }
+ grn_hash_close(ctx, hash);
+ return rc;
+}
+
+/* grn_ts_writer_parse() parses output expressions. */
+static grn_rc
+grn_ts_writer_parse(grn_ctx *ctx, grn_ts_writer *writer,
+ grn_obj *table, grn_ts_str str)
+{
+ grn_rc rc;
+ grn_ts_str rest = str;
+ rc = grn_ts_expr_parser_open(ctx, table, &writer->parser);
+ for ( ; ; ) {
+ grn_ts_str first = { NULL, 0 };
+ rc = grn_ts_expr_parser_split(ctx, writer->parser, rest, &first, &rest);
+ if (rc != GRN_SUCCESS) {
+ return (rc == GRN_END_OF_DATA) ? GRN_SUCCESS : rc;
+ }
+ if ((first.ptr[first.size - 1] == '*') &&
+ grn_ts_str_is_name_prefix((grn_ts_str){ first.ptr, first.size - 1 })) {
+ rc = grn_ts_writer_expand(ctx, writer, table, first);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ } else if (grn_ts_str_is_key_name(first) &&
+ !grn_ts_table_has_key(ctx, table)) {
+ /*
+ * Skip _key if the table has no _key, because the default output_columns
+ * option contains _key.
+ */
+ GRN_TS_DEBUG("skip \"_key\" because the table has no _key");
+ } else {
+ rc = grn_vector_add_element(ctx, &writer->name_buf,
+ first.ptr, first.size, 0, GRN_DB_TEXT);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_writer_build() builds output expresions. */
+static grn_rc
+grn_ts_writer_build(grn_ctx *ctx, grn_ts_writer *writer, grn_obj *table)
+{
+ size_t i, n_names = grn_vector_size(ctx, &writer->name_buf);
+ if (!n_names) {
+ return GRN_SUCCESS;
+ }
+ writer->names = GRN_MALLOCN(grn_ts_str, n_names);
+ if (!writer->names) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x %" GRN_FMT_SIZE,
+ sizeof(grn_ts_str), n_names);
+ }
+ writer->exprs = GRN_MALLOCN(grn_ts_expr *, n_names);
+ if (!writer->exprs) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x %" GRN_FMT_SIZE,
+ sizeof(grn_ts_expr *), n_names);
+ }
+ for (i = 0; i < n_names; i++) {
+ grn_rc rc;
+ grn_ts_expr *new_expr;
+ const char *name_ptr;
+ size_t name_size = grn_vector_get_element(ctx, &writer->name_buf, i,
+ &name_ptr, NULL, NULL);
+ rc = grn_ts_expr_parser_parse(ctx, writer->parser,
+ (grn_ts_str){ name_ptr, name_size },
+ &new_expr);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ writer->names[i].ptr = name_ptr;
+ writer->names[i].size = name_size;
+ writer->exprs[i] = new_expr;
+ writer->n_exprs++;
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_writer_open() creates a writer. */
+static grn_rc
+grn_ts_writer_open(grn_ctx *ctx, grn_obj *table, grn_ts_str str,
+ grn_ts_writer **writer)
+{
+ grn_rc rc;
+ grn_ts_writer *new_writer = GRN_MALLOCN(grn_ts_writer, 1);
+ if (!new_writer) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_writer));
+ }
+ grn_ts_writer_init(ctx, new_writer);
+ rc = grn_ts_writer_parse(ctx, new_writer, table, str);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_writer_build(ctx, new_writer, table);
+ }
+ if (rc != GRN_SUCCESS) {
+ grn_ts_writer_fin(ctx, new_writer);
+ GRN_FREE(new_writer);
+ return rc;
+ }
+ *writer = new_writer;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_writer_close() destroys a writer. */
+static void
+grn_ts_writer_close(grn_ctx *ctx, grn_ts_writer *writer)
+{
+ grn_ts_writer_fin(ctx, writer);
+ GRN_FREE(writer);
+}
+
+/* TODO: Errors of output macros, such as GRN_TEXT_*(), are ignored. */
+
+#define GRN_TS_WRITER_OUTPUT_HEADER_CASE(TYPE, name)\
+ case GRN_DB_ ## TYPE: {\
+ GRN_TEXT_PUTS(ctx, ctx->impl->output.buf, name);\
+ break;\
+ }
+/* grn_ts_writer_output_header() outputs names and data types. */
+static grn_rc
+grn_ts_writer_output_header(grn_ctx *ctx, grn_ts_writer *writer)
+{
+ grn_rc rc;
+ GRN_OUTPUT_ARRAY_OPEN("COLUMNS", writer->n_exprs);
+ for (size_t i = 0; i < writer->n_exprs; ++i) {
+ GRN_OUTPUT_ARRAY_OPEN("COLUMN", 2);
+ rc = grn_text_esc(ctx, ctx->impl->output.buf,
+ writer->names[i].ptr, writer->names[i].size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ GRN_TEXT_PUT(ctx, ctx->impl->output.buf, ",\"", 2);
+ switch (writer->exprs[i]->data_type) {
+ case GRN_DB_VOID: {
+ if (writer->exprs[i]->data_kind == GRN_TS_GEO) {
+ GRN_TEXT_PUTS(ctx, ctx->impl->output.buf, "GeoPoint");
+ } else {
+ GRN_TEXT_PUTS(ctx, ctx->impl->output.buf, "Void");
+ }
+ break;
+ }
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(BOOL, "Bool")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(INT8, "Int8")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(INT16, "Int16")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(INT32, "Int32")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(INT64, "Int64")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(UINT8, "UInt8")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(UINT16, "UInt16")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(UINT32, "UInt32")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(UINT64, "UInt64")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(FLOAT, "Float")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(TIME, "Time")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(SHORT_TEXT, "ShortText")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(TEXT, "Text")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(LONG_TEXT, "LongText")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(TOKYO_GEO_POINT, "TokyoGeoPoint")
+ GRN_TS_WRITER_OUTPUT_HEADER_CASE(WGS84_GEO_POINT, "WGS84GeoPoint")
+ default: {
+ char name_buf[GRN_TABLE_MAX_KEY_SIZE];
+ size_t name_size;
+ grn_obj *obj = grn_ctx_at(ctx, writer->exprs[i]->data_type);
+ if (!obj) {
+ GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "grn_ctx_at failed: %d",
+ writer->exprs[i]->data_type);
+ }
+ if (!grn_ts_obj_is_table(ctx, obj)) {
+ grn_obj_unlink(ctx, obj);
+ GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "not table: %d",
+ writer->exprs[i]->data_type);
+ }
+ name_size = grn_obj_name(ctx, obj, name_buf, sizeof(name_buf));
+ GRN_TEXT_PUT(ctx, ctx->impl->output.buf, name_buf, name_size);
+ grn_obj_unlink(ctx, obj);
+ break;
+ }
+ }
+ GRN_TEXT_PUTC(ctx, ctx->impl->output.buf, '"');
+ GRN_OUTPUT_ARRAY_CLOSE();
+ }
+ GRN_OUTPUT_ARRAY_CLOSE(); /* COLUMNS. */
+ return GRN_SUCCESS;
+}
+#undef GRN_TS_WRITER_OUTPUT_HEADER_CASE
+
+#define GRN_TS_WRITER_OUTPUT_BODY_CASE(KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ grn_ts_ ## kind *value = (grn_ts_ ## kind *)writer->bufs[j].ptr;\
+ grn_ts_ ## kind ## _output(ctx, value[i]);\
+ break;\
+ }
+#define GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(KIND, kind)\
+ GRN_TS_WRITER_OUTPUT_BODY_CASE(KIND ## _VECTOR, kind ## _vector)
+/*
+ * grn_ts_writer_output_body() evaluates expressions and outputs the results.
+ */
+static grn_rc
+grn_ts_writer_output_body(grn_ctx *ctx, grn_ts_writer *writer,
+ const grn_ts_record *in, size_t n_in)
+{
+ size_t i, j, count = 0;
+ writer->bufs = GRN_MALLOCN(grn_ts_buf, writer->n_exprs);
+ if (!writer->bufs) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x %" GRN_FMT_SIZE,
+ sizeof(grn_ts_buf), writer->n_exprs);
+ }
+ for (i = 0; i < writer->n_exprs; i++) {
+ grn_ts_buf_init(ctx, &writer->bufs[i]);
+ }
+ while (count < n_in) {
+ size_t batch_size = GRN_TS_BATCH_SIZE;
+ if (batch_size > (n_in - count)) {
+ batch_size = n_in - count;
+ }
+ for (i = 0; i < writer->n_exprs; ++i) {
+ grn_rc rc = grn_ts_expr_evaluate_to_buf(ctx, writer->exprs[i], in + count,
+ batch_size, &writer->bufs[i]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ for (i = 0; i < batch_size; ++i) {
+ GRN_OUTPUT_ARRAY_OPEN("HIT", writer->n_exprs);
+ for (j = 0; j < writer->n_exprs; ++j) {
+ if (j) {
+ GRN_TEXT_PUTC(ctx, ctx->impl->output.buf, ',');
+ }
+ switch (writer->exprs[j]->data_kind) {
+ GRN_TS_WRITER_OUTPUT_BODY_CASE(BOOL, bool);
+ GRN_TS_WRITER_OUTPUT_BODY_CASE(INT, int);
+ GRN_TS_WRITER_OUTPUT_BODY_CASE(FLOAT, float);
+ GRN_TS_WRITER_OUTPUT_BODY_CASE(TIME, time);
+ GRN_TS_WRITER_OUTPUT_BODY_CASE(TEXT, text);
+ GRN_TS_WRITER_OUTPUT_BODY_CASE(GEO, geo);
+ GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(BOOL, bool);
+ GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(INT, int);
+ GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(FLOAT, float);
+ GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(TIME, time);
+ GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(TEXT, text);
+ GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(GEO, geo);
+ default: {
+ break;
+ }
+ }
+ }
+ GRN_OUTPUT_ARRAY_CLOSE(); /* HITS. */
+ }
+ count += batch_size;
+ }
+ return GRN_SUCCESS;
+}
+#undef GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE
+#undef GRN_TS_WRITER_OUTPUT_BODY_CASE
+
+/* grn_ts_writer_output() outputs search results into the output buffer. */
+static grn_rc
+grn_ts_writer_output(grn_ctx *ctx, grn_ts_writer *writer,
+ const grn_ts_record *in, size_t n_in, size_t n_hits)
+{
+ grn_rc rc;
+ GRN_OUTPUT_ARRAY_OPEN("RESULT", 1);
+ GRN_OUTPUT_ARRAY_OPEN("RESULTSET", 2 + n_in);
+ GRN_OUTPUT_ARRAY_OPEN("NHITS", 1);
+ rc = grn_text_ulltoa(ctx, ctx->impl->output.buf, n_hits);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ GRN_OUTPUT_ARRAY_CLOSE(); /* NHITS. */
+ rc = grn_ts_writer_output_header(ctx, writer);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_writer_output_body(ctx, writer, in, n_in);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ GRN_OUTPUT_ARRAY_CLOSE(); /* RESULTSET. */
+ GRN_OUTPUT_ARRAY_CLOSE(); /* RESET. */
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_select_filter() applies a filter to all the records of a table. */
+static grn_rc
+grn_ts_select_filter(grn_ctx *ctx, grn_obj *table, grn_ts_str str,
+ size_t offset, size_t limit,
+ grn_ts_record **out, size_t *n_out, size_t *n_hits)
+{
+ grn_rc rc;
+ grn_table_cursor *cursor_obj;
+ grn_ts_cursor *cursor;
+ grn_ts_expr *expr = NULL;
+ grn_ts_record *buf = NULL;
+ size_t buf_size = 0;
+
+ *out = NULL;
+ *n_out = 0;
+ *n_hits = 0;
+
+ cursor_obj = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1,
+ GRN_CURSOR_ASCENDING | GRN_CURSOR_BY_ID);
+ if (!cursor_obj) {
+ return (ctx->rc != GRN_SUCCESS) ? ctx->rc : GRN_UNKNOWN_ERROR;
+ }
+ rc = grn_ts_obj_cursor_open(ctx, cursor_obj, &cursor);
+ if (rc != GRN_SUCCESS) {
+ grn_obj_close(ctx, cursor_obj);
+ return rc;
+ }
+
+ if (str.size) {
+ rc = grn_ts_expr_parse(ctx, table, str, &expr);
+ }
+ if (rc == GRN_SUCCESS) {
+ for ( ; ; ) {
+ size_t batch_size;
+ grn_ts_record *batch;
+
+ /* Extend the record buffer. */
+ if (buf_size < (*n_out + GRN_TS_BATCH_SIZE)) {
+ size_t new_size = buf_size ? (buf_size * 2) : GRN_TS_BATCH_SIZE;
+ size_t n_bytes = sizeof(grn_ts_record) * new_size;
+ grn_ts_record *new_buf = (grn_ts_record *)GRN_REALLOC(buf, n_bytes);
+ if (!new_buf) {
+ GRN_TS_ERR(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE,
+ n_bytes);
+ rc = ctx->rc;
+ break;
+ }
+ buf = new_buf;
+ buf_size = new_size;
+ }
+
+ /* Read records from the cursor. */
+ batch = buf + *n_out;
+ rc = grn_ts_cursor_read(ctx, cursor, batch, GRN_TS_BATCH_SIZE,
+ &batch_size);
+ if ((rc != GRN_SUCCESS) || !batch_size) {
+ break;
+ }
+
+ /* Apply the filter. */
+ if (expr) {
+ rc = grn_ts_expr_filter(ctx, expr, batch, batch_size,
+ batch, &batch_size);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ *n_hits += batch_size;
+
+ /* Apply the offset and the limit. */
+ if (offset) {
+ if (batch_size <= offset) {
+ offset -= batch_size;
+ batch_size = 0;
+ } else {
+ size_t n_bytes = sizeof(grn_ts_record) * (batch_size - offset);
+ grn_memmove(batch, batch + offset, n_bytes);
+ batch_size -= offset;
+ offset = 0;
+ }
+ }
+ if (batch_size <= limit) {
+ limit -= batch_size;
+ } else {
+ batch_size = limit;
+ limit = 0;
+ }
+ *n_out += batch_size;
+ }
+ /* Ignore a failure of destruction. */
+ if (expr) {
+ grn_ts_expr_close(ctx, expr);
+ }
+ }
+ /* Ignore a failure of destruction. */
+ grn_ts_cursor_close(ctx, cursor);
+
+ if (rc != GRN_SUCCESS) {
+ if (buf) {
+ GRN_FREE(buf);
+ }
+ *n_out = 0;
+ *n_hits = 0;
+ return rc;
+ }
+ *out = buf;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_select_scorer() adjust scores. */
+static grn_rc
+grn_ts_select_scorer(grn_ctx *ctx, grn_obj *table, grn_ts_str str,
+ grn_ts_record *records, size_t n_records)
+{
+ grn_rc rc;
+ grn_ts_str rest;
+ grn_ts_expr *expr;
+ rest = grn_ts_str_trim_score_assignment(str);
+ if (!rest.size) {
+ return GRN_SUCCESS;
+ }
+ rc = grn_ts_expr_parse(ctx, table, rest, &expr);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_adjust(ctx, expr, records, n_records);
+ grn_ts_expr_close(ctx, expr);
+ return rc;
+}
+
+/* grn_ts_select_output() outputs the results. */
+static grn_rc
+grn_ts_select_output(grn_ctx *ctx, grn_obj *table, grn_ts_str str,
+ const grn_ts_record *in, size_t n_in, size_t n_hits)
+{
+ grn_ts_writer *writer;
+ grn_rc rc = grn_ts_writer_open(ctx, table, str, &writer);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_writer_output(ctx, writer, in, n_in, n_hits);
+ grn_ts_writer_close(ctx, writer);
+ return rc;
+}
+
+/* grn_ts_select_with_sortby() executes a select command with --sortby. */
+static grn_rc
+grn_ts_select_with_sortby(grn_ctx *ctx, grn_obj *table,
+ grn_ts_str filter, grn_ts_str scorer,
+ grn_ts_str sortby, grn_ts_str output_columns,
+ size_t offset, size_t limit)
+{
+ grn_rc rc;
+ grn_ts_record *recs = NULL;
+ size_t n_recs = 0, max_n_recs = 0, n_hits = 0;
+ grn_table_cursor *cursor_obj;
+ grn_ts_cursor *cursor = NULL;
+ grn_ts_expr *filter_expr = NULL;
+ grn_ts_expr *scorer_expr = NULL;
+ grn_ts_sorter *sorter = NULL;
+ cursor_obj = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1,
+ GRN_CURSOR_ASCENDING | GRN_CURSOR_BY_ID);
+ if (!cursor_obj) {
+ GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "grn_table_cursor_open failed");
+ }
+ rc = grn_ts_obj_cursor_open(ctx, cursor_obj, &cursor);
+ if (rc != GRN_SUCCESS) {
+ grn_obj_close(ctx, cursor_obj);
+ return rc;
+ }
+ if (filter.size) {
+ rc = grn_ts_expr_parse(ctx, table, filter, &filter_expr);
+ }
+ if (rc == GRN_SUCCESS) {
+ scorer = grn_ts_str_trim_score_assignment(scorer);
+ if (scorer.size) {
+ rc = grn_ts_expr_parse(ctx, table, scorer, &scorer_expr);
+ }
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_sorter_parse(ctx, table, sortby, offset, limit, &sorter);
+ }
+ }
+ if (rc == GRN_SUCCESS) {
+ size_t n_pending_recs = 0;
+ for ( ; ; ) {
+ size_t batch_size;
+ grn_ts_record *batch;
+ /* Extend a buffer for records. */
+ if (max_n_recs < (n_recs + GRN_TS_BATCH_SIZE)) {
+ size_t n_bytes, new_max_n_recs = max_n_recs * 2;
+ grn_ts_record *new_recs;
+ if (!new_max_n_recs) {
+ new_max_n_recs = GRN_TS_BATCH_SIZE;
+ }
+ n_bytes = sizeof(grn_ts_record) * new_max_n_recs;
+ new_recs = (grn_ts_record *)GRN_REALLOC(recs, n_bytes);
+ if (!new_recs) {
+ GRN_TS_ERR(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE,
+ n_bytes);
+ rc = ctx->rc;
+ break;
+ }
+ recs = new_recs;
+ max_n_recs = new_max_n_recs;
+ }
+ /* Read records from a cursor. */
+ batch = recs + n_recs;
+ rc = grn_ts_cursor_read(ctx, cursor, batch, GRN_TS_BATCH_SIZE,
+ &batch_size);
+ if (rc != GRN_SUCCESS) {
+ break;
+ } else if (!batch_size) {
+ /* Apply a scorer and complete sorting. */
+ if (scorer_expr) {
+ rc = grn_ts_expr_adjust(ctx, scorer_expr,
+ recs + n_recs - n_pending_recs,
+ n_pending_recs);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ if (n_pending_recs) {
+ rc = grn_ts_sorter_progress(ctx, sorter, recs, n_recs, &n_recs);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ rc = grn_ts_sorter_complete(ctx, sorter, recs, n_recs, &n_recs);
+ break;
+ }
+ /* Apply a filter. */
+ if (filter_expr) {
+ rc = grn_ts_expr_filter(ctx, filter_expr, batch, batch_size,
+ batch, &batch_size);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ n_hits += batch_size;
+ n_recs += batch_size;
+ n_pending_recs += batch_size;
+ /*
+ * Apply a scorer and progress sorting if there are enough pending
+ * records.
+ */
+ if (n_pending_recs >= GRN_TS_BATCH_SIZE) {
+ if (scorer_expr) {
+ rc = grn_ts_expr_adjust(ctx, scorer_expr,
+ recs + n_recs - n_pending_recs,
+ n_pending_recs);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ rc = grn_ts_sorter_progress(ctx, sorter, recs, n_recs, &n_recs);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ n_pending_recs = 0;
+ }
+ }
+ }
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_select_output(ctx, table, output_columns,
+ recs, n_recs, n_hits);
+ }
+ if (cursor) {
+ grn_ts_cursor_close(ctx, cursor);
+ }
+ if (recs) {
+ GRN_FREE(recs);
+ }
+ if (sorter) {
+ grn_ts_sorter_close(ctx, sorter);
+ }
+ if (scorer_expr) {
+ grn_ts_expr_close(ctx, scorer_expr);
+ }
+ if (filter_expr) {
+ grn_ts_expr_close(ctx, filter_expr);
+ }
+ return rc;
+}
+
+/*
+ * grn_ts_select_without_sortby() executes a select command without --sortby.
+ */
+static grn_rc
+grn_ts_select_without_sortby(grn_ctx *ctx, grn_obj *table,
+ grn_ts_str filter, grn_ts_str scorer,
+ grn_ts_str output_columns,
+ size_t offset, size_t limit)
+{
+ grn_rc rc;
+ grn_ts_record *records = NULL;
+ size_t n_records, n_hits;
+ rc = grn_ts_select_filter(ctx, table, filter, offset, limit,
+ &records, &n_records, &n_hits);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_select_scorer(ctx, table, scorer, records, n_records);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_select_output(ctx, table, output_columns,
+ records, n_records, n_hits);
+ }
+ }
+ if (records) {
+ GRN_FREE(records);
+ }
+ return rc;
+}
+
+/*-------------------------------------------------------------
+ * API.
+ */
+
+grn_rc
+grn_ts_select(grn_ctx *ctx, grn_obj *table,
+ const char *filter_ptr, size_t filter_len,
+ const char *scorer_ptr, size_t scorer_len,
+ const char *sortby_ptr, size_t sortby_len,
+ const char *output_columns_ptr, size_t output_columns_len,
+ size_t offset, size_t limit)
+{
+ grn_rc rc;
+ grn_ts_str filter = { filter_ptr, filter_len };
+ grn_ts_str scorer = { scorer_ptr, scorer_len };
+ grn_ts_str sortby = { sortby_ptr, sortby_len };
+ grn_ts_str output_columns = { output_columns_ptr, output_columns_len };
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!table || !grn_ts_obj_is_table(ctx, table) ||
+ (!filter_ptr && filter_len) || (!scorer_ptr && scorer_len) ||
+ (!sortby_ptr && sortby_len) ||
+ (!output_columns_ptr && output_columns_len)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ filter = grn_ts_str_trim_left(filter);
+ if (sortby_len) {
+ rc = grn_ts_select_with_sortby(ctx, table, filter, scorer, sortby,
+ output_columns, offset, limit);
+ } else {
+ rc = grn_ts_select_without_sortby(ctx, table, filter, scorer,
+ output_columns, offset, limit);
+ }
+ if (rc != GRN_SUCCESS) {
+ GRN_BULK_REWIND(ctx->impl->output.buf);
+ if ((ctx->rc == GRN_SUCCESS) || !ctx->errbuf[0]) {
+ ERR(rc, "error message is missing");
+ } else if (ctx->errlvl < GRN_LOG_ERROR) {
+ ctx->errlvl = GRN_LOG_ERROR;
+ }
+ }
+ return rc;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts/Makefile.am b/storage/mroonga/vendor/groonga/lib/ts/Makefile.am
new file mode 100644
index 00000000000..f1f21df487c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/Makefile.am
@@ -0,0 +1,20 @@
+BUNDLED_LIBRARIES_CFLAGS = \
+ $(MRUBY_CFLAGS) \
+ $(ONIGMO_CFLAGS)
+
+DEFAULT_INCLUDES = \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/include \
+ $(BUNDLED_LIBRARIES_CFLAGS)
+
+AM_CFLAGS = \
+ $(NO_STRICT_ALIASING_CFLAGS) \
+ $(COVERAGE_CFLAGS) \
+ $(GRN_CFLAGS) \
+ $(MESSAGE_PACK_CFLAGS)
+
+noinst_LTLIBRARIES = libgrnts.la
+
+include sources.am
+
+CLEANFILES = *.gcno *.gcda
diff --git a/storage/mroonga/vendor/groonga/lib/ts/sources.am b/storage/mroonga/vendor/groonga/lib/ts/sources.am
new file mode 100644
index 00000000000..5d89b059c65
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/sources.am
@@ -0,0 +1,25 @@
+libgrnts_la_SOURCES = \
+ ts_buf.c \
+ ts_buf.h \
+ ts_cursor.c \
+ ts_cursor.h \
+ ts_expr.c \
+ ts_expr.h \
+ ts_expr_builder.c \
+ ts_expr_builder.h \
+ ts_expr_node.c \
+ ts_expr_node.h \
+ ts_expr_parser.c \
+ ts_expr_parser.h \
+ ts_log.h \
+ ts_op.c \
+ ts_op.h \
+ ts_plan.c \
+ ts_plan.h \
+ ts_sorter.c \
+ ts_sorter.h \
+ ts_str.c \
+ ts_str.h \
+ ts_types.h \
+ ts_util.c \
+ ts_util.h
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_buf.c b/storage/mroonga/vendor/groonga/lib/ts/ts_buf.c
new file mode 100644
index 00000000000..bee724ccdcd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_buf.c
@@ -0,0 +1,244 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_buf.h"
+
+#include "../grn_ctx.h"
+
+#include "ts_log.h"
+
+#include <string.h>
+
+/*-------------------------------------------------------------
+ * grn_ts_buf
+ */
+
+void
+grn_ts_buf_init(grn_ctx *ctx, grn_ts_buf *buf)
+{
+ buf->ptr = NULL;
+ buf->size = 0;
+ buf->pos = 0;
+}
+
+/*
+grn_rc
+grn_ts_buf_open(grn_ctx *ctx, grn_ts_buf **buf)
+{
+ grn_ts_buf *new_buf = GRN_MALLOCN(grn_ts_buf, 1);
+ if (!new_buf) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_buf));
+ }
+ grn_ts_buf_init(ctx, new_buf);
+ *buf = new_buf;
+ return GRN_SUCCESS;
+}
+*/
+
+void
+grn_ts_buf_fin(grn_ctx *ctx, grn_ts_buf *buf)
+{
+ if (buf->ptr) {
+ GRN_FREE(buf->ptr);
+ }
+}
+
+/*
+void
+grn_ts_buf_close(grn_ctx *ctx, grn_ts_buf *buf)
+{
+ if (buf) {
+ grn_ts_buf_fin(ctx, buf);
+ }
+}
+*/
+
+grn_rc
+grn_ts_buf_reserve(grn_ctx *ctx, grn_ts_buf *buf, size_t min_size)
+{
+ void *new_ptr;
+ size_t enough_size;
+ if (min_size <= buf->size) {
+ return GRN_SUCCESS;
+ }
+ enough_size = buf->size ? (buf->size << 1) : 1;
+ while (enough_size < min_size) {
+ if ((enough_size << 1) < enough_size) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
+ "size overflow: %" GRN_FMT_SIZE,
+ min_size);
+ }
+ enough_size <<= 1;
+ }
+ new_ptr = GRN_REALLOC(buf->ptr, enough_size);
+ if (!new_ptr) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE,
+ enough_size);
+ }
+ buf->ptr = new_ptr;
+ buf->size = enough_size;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_buf_resize(grn_ctx *ctx, grn_ts_buf *buf, size_t new_size)
+{
+ void *new_ptr;
+ if (new_size == buf->size) {
+ return GRN_SUCCESS;
+ }
+ if (!new_size) {
+ if (buf->ptr) {
+ GRN_FREE(buf->ptr);
+ buf->ptr = NULL;
+ buf->size = new_size;
+ }
+ return GRN_SUCCESS;
+ }
+ new_ptr = GRN_REALLOC(buf->ptr, new_size);
+ if (!new_ptr) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE,
+ new_size);
+ }
+ buf->ptr = new_ptr;
+ buf->size = new_size;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_buf_write(grn_ctx *ctx, grn_ts_buf *buf, const void *ptr, size_t size)
+{
+ size_t new_pos = buf->pos + size;
+ if (new_pos < buf->pos) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
+ "size overflow: %" GRN_FMT_SIZE " + %" GRN_FMT_SIZE,
+ buf->pos, size);
+ }
+ if (new_pos > buf->size) {
+ grn_rc rc = grn_ts_buf_reserve(ctx, buf, new_pos);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ grn_memcpy((char *)buf->ptr + buf->pos, ptr, size);
+ buf->pos += size;
+ return GRN_SUCCESS;
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_rbuf
+ */
+
+void
+grn_ts_rbuf_init(grn_ctx *ctx, grn_ts_rbuf *rbuf)
+{
+ rbuf->recs = NULL;
+ rbuf->n_recs = 0;
+ rbuf->max_n_recs = 0;
+}
+
+void
+grn_ts_rbuf_fin(grn_ctx *ctx, grn_ts_rbuf *rbuf)
+{
+ if (rbuf->recs) {
+ GRN_FREE(rbuf->recs);
+ }
+}
+
+grn_rc
+grn_ts_rbuf_open(grn_ctx *ctx, grn_ts_rbuf **rbuf)
+{
+ grn_ts_rbuf *new_rbuf = GRN_MALLOCN(grn_ts_rbuf, 1);
+ if (!new_rbuf) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_rbuf));
+ }
+ grn_ts_rbuf_init(ctx, new_rbuf);
+ *rbuf = new_rbuf;
+ return GRN_SUCCESS;
+}
+
+void
+grn_ts_rbuf_close(grn_ctx *ctx, grn_ts_rbuf *rbuf)
+{
+ if (rbuf) {
+ grn_ts_rbuf_fin(ctx, rbuf);
+ }
+}
+
+grn_rc
+grn_ts_rbuf_reserve(grn_ctx *ctx, grn_ts_rbuf *rbuf, size_t min_max_n_recs)
+{
+ size_t n_bytes, enough_max_n_recs;
+ grn_ts_record *new_recs;
+ if (min_max_n_recs <= rbuf->max_n_recs) {
+ return GRN_SUCCESS;
+ }
+ enough_max_n_recs = rbuf->max_n_recs ? (rbuf->max_n_recs << 1) : 1;
+ while (enough_max_n_recs < min_max_n_recs) {
+ if ((enough_max_n_recs << 1) < enough_max_n_recs) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
+ "size overflow: %" GRN_FMT_SIZE,
+ min_max_n_recs);
+ }
+ enough_max_n_recs <<= 1;
+ }
+ n_bytes = sizeof(grn_ts_record) * enough_max_n_recs;
+ new_recs = GRN_REALLOC(rbuf->recs, n_bytes);
+ if (!new_recs) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE,
+ n_bytes);
+ }
+ rbuf->recs = new_recs;
+ rbuf->max_n_recs = enough_max_n_recs;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_rbuf_resize(grn_ctx *ctx, grn_ts_rbuf *rbuf, size_t new_max_n_recs)
+{
+ size_t n_bytes;
+ grn_ts_record *new_recs;
+ if (new_max_n_recs == rbuf->max_n_recs) {
+ return GRN_SUCCESS;
+ }
+ if (!new_max_n_recs) {
+ if (rbuf->recs) {
+ GRN_FREE(rbuf->recs);
+ rbuf->recs = NULL;
+ rbuf->max_n_recs = new_max_n_recs;
+ }
+ return GRN_SUCCESS;
+ }
+ n_bytes = sizeof(grn_ts_record) * new_max_n_recs;
+ new_recs = GRN_REALLOC(rbuf->recs, n_bytes);
+ if (!new_recs) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE,
+ new_max_n_recs);
+ }
+ rbuf->recs = new_recs;
+ rbuf->max_n_recs = new_max_n_recs;
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_buf.h b/storage/mroonga/vendor/groonga/lib/ts/ts_buf.h
new file mode 100644
index 00000000000..64caec933b0
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_buf.h
@@ -0,0 +1,111 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#include "ts_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------------------------------------------------
+ * grn_ts_buf
+ */
+
+/* grn_ts_buf works as a buffer for arbitrary data. */
+
+typedef struct {
+ void *ptr; /* The starting address. */
+ size_t size; /* The size in bytes. */
+ size_t pos; /* The current position for grn_ts_buf_write(). */
+} grn_ts_buf;
+
+/* grn_ts_buf_init() initializes a buffer. */
+void grn_ts_buf_init(grn_ctx *ctx, grn_ts_buf *buf);
+
+/* grn_ts_buf_fin() finalizes a buffer. */
+void grn_ts_buf_fin(grn_ctx *ctx, grn_ts_buf *buf);
+
+#if 0
+/* grn_ts_buf_open() creates a buffer. */
+grn_rc grn_ts_buf_open(grn_ctx *ctx, grn_ts_buf **buf);
+
+/* grn_ts_buf_close() destroys a buffer. */
+void grn_ts_buf_close(grn_ctx *ctx, grn_ts_buf *buf);
+#endif
+
+/*
+ * grn_ts_buf_reserve() reserves enough memory to store `min_size` bytes.
+ * Note that this function never shrinks a buffer and does nothing if
+ * `min_size` is not greater than `buf->size`.
+ */
+grn_rc grn_ts_buf_reserve(grn_ctx *ctx, grn_ts_buf *buf, size_t min_size);
+
+/* grn_ts_buf_resize() resizes a buffer. */
+grn_rc grn_ts_buf_resize(grn_ctx *ctx, grn_ts_buf *buf, size_t new_size);
+
+/*
+ * grn_ts_buf_write() writes data into a buffer. `buf->pos` specifies the
+ * position and it will be modified on success.
+ * Note that this function resizes a buffer if required.
+ */
+grn_rc grn_ts_buf_write(grn_ctx *ctx, grn_ts_buf *buf,
+ const void *ptr, size_t size);
+
+/*-------------------------------------------------------------
+ * grn_ts_rbuf
+ */
+
+/* grn_ts_rbuf works as a buffer for records. */
+
+typedef struct {
+ grn_ts_record *recs; /* Pointer to records. */
+ size_t n_recs; /* The number of records. */
+ size_t max_n_recs; /* The maximum number of records. */
+} grn_ts_rbuf;
+
+/* grn_ts_rbuf_init() initializes a buffer. */
+void grn_ts_rbuf_init(grn_ctx *ctx, grn_ts_rbuf *rbuf);
+
+/* grn_ts_rbuf_fin() finalizes a buffer. */
+void grn_ts_rbuf_fin(grn_ctx *ctx, grn_ts_rbuf *rbuf);
+
+/* grn_ts_rbuf_open() creates a buffer. */
+/*grn_rc grn_ts_rbuf_open(grn_ctx *ctx, grn_ts_rbuf **rbuf);*/
+
+/* grn_ts_rbuf_close() destroys a buffer. */
+/*void grn_ts_rbuf_close(grn_ctx *ctx, grn_ts_rbuf *rbuf);*/
+
+/*
+ * grn_ts_rbuf_reserve() reserves enough memory to store `n_recs` records.
+ * Note that this function never shrinks a buffer and does nothing if `n_recs`
+ * is not greater than the `rbuf->max_n_recs`.
+ */
+grn_rc grn_ts_rbuf_reserve(grn_ctx *ctx, grn_ts_rbuf *rbuf, size_t n_recs);
+
+/* grn_ts_rbuf_resize() resizes a buffer. */
+grn_rc grn_ts_rbuf_resize(grn_ctx *ctx, grn_ts_rbuf *rbuf,
+ size_t new_max_n_recs);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_cursor.c b/storage/mroonga/vendor/groonga/lib/ts/ts_cursor.c
new file mode 100644
index 00000000000..5329571ffb0
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_cursor.c
@@ -0,0 +1,163 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_cursor.h"
+
+#include "../grn_ctx.h"
+#include "../grn_dat.h"
+#include "../grn_hash.h"
+#include "../grn_pat.h"
+
+#include "ts_log.h"
+#include "ts_util.h"
+
+/*-------------------------------------------------------------
+ * grn_ts_obj_cursor.
+ */
+
+typedef struct {
+ GRN_TS_CURSOR_COMMON_MEMBERS
+ grn_obj *obj; /* Wrapped cursor object. */
+} grn_ts_obj_cursor;
+
+grn_rc
+grn_ts_obj_cursor_open(grn_ctx *ctx, grn_obj *obj, grn_ts_cursor **cursor)
+{
+ grn_ts_obj_cursor *new_cursor;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!obj || !cursor) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ switch (obj->header.type) {
+ case GRN_CURSOR_TABLE_HASH_KEY:
+ case GRN_CURSOR_TABLE_PAT_KEY:
+ case GRN_CURSOR_TABLE_DAT_KEY:
+ case GRN_CURSOR_TABLE_NO_KEY: {
+ break;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ }
+ new_cursor = GRN_MALLOCN(grn_ts_obj_cursor, 1);
+ if (!new_cursor) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_obj_cursor));
+ }
+ new_cursor->type = GRN_TS_OBJ_CURSOR;
+ new_cursor->obj = obj;
+ *cursor = (grn_ts_cursor *)new_cursor;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_obj_cursor_close() destroys a wrapper cursor. */
+static grn_rc
+grn_ts_obj_cursor_close(grn_ctx *ctx, grn_ts_obj_cursor *cursor)
+{
+ if (cursor->obj) {
+ grn_obj_close(ctx, cursor->obj);
+ }
+ GRN_FREE(cursor);
+ return GRN_SUCCESS;
+}
+
+#define GRN_TS_OBJ_CURSOR_READ(type)\
+ size_t i;\
+ grn_ ## type ## _cursor *obj = (grn_ ## type ## _cursor *)cursor->obj;\
+ for (i = 0; i < max_n_recs; i++) {\
+ recs[i].id = grn_ ## type ## _cursor_next(ctx, obj);\
+ if (!recs[i].id) {\
+ break;\
+ }\
+ recs[i].score = 0;\
+ }\
+ *n_recs = i;\
+ return GRN_SUCCESS;
+/* grn_ts_obj_cursor_read() reads records from a wrapper cursor. */
+static grn_rc
+grn_ts_obj_cursor_read(grn_ctx *ctx, grn_ts_obj_cursor *cursor,
+ grn_ts_record *recs, size_t max_n_recs, size_t *n_recs)
+{
+ switch (cursor->obj->header.type) {
+ case GRN_CURSOR_TABLE_HASH_KEY: {
+ GRN_TS_OBJ_CURSOR_READ(hash)
+ }
+ case GRN_CURSOR_TABLE_PAT_KEY: {
+ GRN_TS_OBJ_CURSOR_READ(pat)
+ }
+ case GRN_CURSOR_TABLE_DAT_KEY: {
+ GRN_TS_OBJ_CURSOR_READ(dat)
+ }
+ case GRN_CURSOR_TABLE_NO_KEY: {
+ GRN_TS_OBJ_CURSOR_READ(array)
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_cursor.
+ */
+
+grn_rc
+grn_ts_cursor_close(grn_ctx *ctx, grn_ts_cursor *cursor)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!cursor) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ switch (cursor->type) {
+ case GRN_TS_OBJ_CURSOR: {
+ return grn_ts_obj_cursor_close(ctx, (grn_ts_obj_cursor *)cursor);
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid cursor type: %d",
+ cursor->type);
+ }
+ }
+}
+
+grn_rc
+grn_ts_cursor_read(grn_ctx *ctx, grn_ts_cursor *cursor,
+ grn_ts_record *out, size_t max_n_out, size_t *n_out)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!cursor || (!out && max_n_out) || !n_out) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ switch (cursor->type) {
+ case GRN_TS_OBJ_CURSOR: {
+ return grn_ts_obj_cursor_read(ctx, (grn_ts_obj_cursor *)cursor,
+ out, max_n_out, n_out);
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid cursor type: %d",
+ cursor->type);
+ }
+ }
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_cursor.h b/storage/mroonga/vendor/groonga/lib/ts/ts_cursor.h
new file mode 100644
index 00000000000..f05aa7518df
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_cursor.h
@@ -0,0 +1,59 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#include "ts_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ GRN_TS_OBJ_CURSOR /* Wrapper cursor. */
+} grn_ts_cursor_type;
+
+#define GRN_TS_CURSOR_COMMON_MEMBERS\
+ grn_ts_cursor_type type; /* Cursor type. */
+
+typedef struct {
+ GRN_TS_CURSOR_COMMON_MEMBERS
+} grn_ts_cursor;
+
+/*
+ * grn_ts_obj_cursor_open() creates a wrapper cursor.
+ * The new cursor will be a wrapper for a Groonga cursor specified by `obj`.
+ * On success, `obj` will be closed in grn_ts_cursor_close().
+ * On failure, `obj` is left as is.
+ */
+grn_rc grn_ts_obj_cursor_open(grn_ctx *ctx, grn_obj *obj,
+ grn_ts_cursor **cursor);
+
+/* grn_ts_cursor_close() destroys a cursor. */
+grn_rc grn_ts_cursor_close(grn_ctx *ctx, grn_ts_cursor *cursor);
+
+/* grn_ts_cursor_read() reads records from a cursor. */
+grn_rc grn_ts_cursor_read(grn_ctx *ctx, grn_ts_cursor *cursor,
+ grn_ts_record *out, size_t max_n_out, size_t *n_out);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_expr.c b/storage/mroonga/vendor/groonga/lib/ts/ts_expr.c
new file mode 100644
index 00000000000..a7fcde6570e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_expr.c
@@ -0,0 +1,219 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_expr.h"
+
+#include <string.h>
+
+#include "../grn_ctx.h"
+
+#include "ts_log.h"
+#include "ts_str.h"
+#include "ts_util.h"
+#include "ts_expr_parser.h"
+
+/* grn_ts_expr_init() initializes an expression. */
+static void
+grn_ts_expr_init(grn_ctx *ctx, grn_ts_expr *expr)
+{
+ memset(expr, 0, sizeof(*expr));
+ expr->table = NULL;
+ expr->root = NULL;
+}
+
+/* grn_ts_expr_fin() finalizes an expression. */
+static void
+grn_ts_expr_fin(grn_ctx *ctx, grn_ts_expr *expr)
+{
+ if (expr->root) {
+ grn_ts_expr_node_close(ctx, expr->root);
+ }
+ if (expr->table) {
+ grn_obj_unlink(ctx, expr->table);
+ }
+}
+
+grn_rc
+grn_ts_expr_open(grn_ctx *ctx, grn_obj *table, grn_ts_expr_node *root,
+ grn_ts_expr **expr)
+{
+ grn_rc rc;
+ grn_ts_expr *new_expr;
+ grn_ts_expr_type type;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!table || !grn_ts_obj_is_table(ctx, table) || !root || !expr) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ switch (root->type) {
+ case GRN_TS_EXPR_ID_NODE: {
+ type = GRN_TS_EXPR_ID;
+ break;
+ }
+ case GRN_TS_EXPR_SCORE_NODE: {
+ type = GRN_TS_EXPR_SCORE;
+ break;
+ }
+ case GRN_TS_EXPR_KEY_NODE:
+ case GRN_TS_EXPR_VALUE_NODE: {
+ type = GRN_TS_EXPR_VARIABLE;
+ break;
+ }
+ case GRN_TS_EXPR_CONST_NODE: {
+ type = GRN_TS_EXPR_CONST;
+ break;
+ }
+ case GRN_TS_EXPR_COLUMN_NODE:
+ case GRN_TS_EXPR_OP_NODE:
+ case GRN_TS_EXPR_BRIDGE_NODE: {
+ type = GRN_TS_EXPR_VARIABLE;
+ break;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ }
+ new_expr = GRN_MALLOCN(grn_ts_expr, 1);
+ if (!new_expr) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE,
+ sizeof(grn_ts_expr));
+ }
+ rc = grn_ts_obj_increment_ref_count(ctx, table);
+ if (rc != GRN_SUCCESS) {
+ GRN_FREE(new_expr);
+ return rc;
+ }
+ grn_ts_expr_init(ctx, new_expr);
+ new_expr->table = table;
+ new_expr->type = type;
+ new_expr->data_kind = root->data_kind;
+ new_expr->data_type = root->data_type;
+ new_expr->root = root;
+ *expr = new_expr;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_parse(grn_ctx *ctx, grn_obj *table, grn_ts_str str,
+ grn_ts_expr **expr)
+{
+ grn_rc rc;
+ grn_ts_expr *new_expr;
+ grn_ts_expr_parser *parser;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!table || !grn_ts_obj_is_table(ctx, table) ||
+ (!str.ptr && str.size) || !expr) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ rc = grn_ts_expr_parser_open(ctx, table, &parser);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_parser_parse(ctx, parser, str, &new_expr);
+ grn_ts_expr_parser_close(ctx, parser);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ *expr = new_expr;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_close(grn_ctx *ctx, grn_ts_expr *expr)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!expr) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ grn_ts_expr_fin(ctx, expr);
+ GRN_FREE(expr);
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_evaluate_to_buf(grn_ctx *ctx, grn_ts_expr *expr,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_buf *out)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!expr || (!in && n_in) || !out) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ if (!n_in) {
+ return GRN_SUCCESS;
+ }
+ return grn_ts_expr_node_evaluate_to_buf(ctx, expr->root, in, n_in, out);
+}
+
+grn_rc
+grn_ts_expr_evaluate(grn_ctx *ctx, grn_ts_expr *expr,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!expr || (!in && n_in) || (n_in && !out)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ if (!n_in) {
+ return GRN_SUCCESS;
+ }
+ return grn_ts_expr_node_evaluate(ctx, expr->root, in, n_in, out);
+}
+
+grn_rc
+grn_ts_expr_filter(grn_ctx *ctx, grn_ts_expr *expr,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!expr || (!in && n_in) || !out || !n_out) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ if (!n_in) {
+ *n_out = 0;
+ return GRN_SUCCESS;
+ }
+ return grn_ts_expr_node_filter(ctx, expr->root, in, n_in, out, n_out);
+}
+
+grn_rc
+grn_ts_expr_adjust(grn_ctx *ctx, grn_ts_expr *expr,
+ grn_ts_record *io, size_t n_io)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!expr || (!io && n_io)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ if (!n_io) {
+ return GRN_SUCCESS;
+ }
+ return grn_ts_expr_node_adjust(ctx, expr->root, io, n_io);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_expr.h b/storage/mroonga/vendor/groonga/lib/ts/ts_expr.h
new file mode 100644
index 00000000000..be370e8b56b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_expr.h
@@ -0,0 +1,87 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#include "ts_buf.h"
+#include "ts_expr_node.h"
+#include "ts_str.h"
+#include "ts_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------------------------------------------------
+ * Enumeration types.
+ */
+
+typedef enum {
+ GRN_TS_EXPR_ID, /* IDs (_id). */
+ GRN_TS_EXPR_SCORE, /* Scores (_score). */
+ GRN_TS_EXPR_CONST, /* A const. */
+ GRN_TS_EXPR_VARIABLE /* An expression that contains a variable. */
+} grn_ts_expr_type;
+
+/*-------------------------------------------------------------
+ * Expression components.
+ */
+
+typedef struct {
+ grn_obj *table; /* Associated table. */
+ grn_ts_expr_type type; /* Expression type. */
+ grn_ts_data_kind data_kind; /* Abstract data type. */
+ grn_ts_data_type data_type; /* Detailed data type. */
+ grn_ts_expr_node *root; /* Root node. */
+} grn_ts_expr;
+
+/* grn_ts_expr_open() creates an expression. */
+grn_rc grn_ts_expr_open(grn_ctx *ctx, grn_obj *table, grn_ts_expr_node *root,
+ grn_ts_expr **expr);
+
+/* grn_ts_expr_parse() parses a string and creates an expression. */
+grn_rc grn_ts_expr_parse(grn_ctx *ctx, grn_obj *table, grn_ts_str str,
+ grn_ts_expr **expr);
+
+/* grn_ts_expr_close() destroys an expression. */
+grn_rc grn_ts_expr_close(grn_ctx *ctx, grn_ts_expr *expr);
+
+/* grn_ts_expr_evaluate() evaluates an expression. */
+grn_rc grn_ts_expr_evaluate(grn_ctx *ctx, grn_ts_expr *expr,
+ const grn_ts_record *in, size_t n_in, void *out);
+
+/* grn_ts_expr_evaluate_to_buf() evaluates an expression. */
+grn_rc grn_ts_expr_evaluate_to_buf(grn_ctx *ctx, grn_ts_expr *expr,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_buf *out);
+
+/* grn_ts_expr_filter() filters records. */
+grn_rc grn_ts_expr_filter(grn_ctx *ctx, grn_ts_expr *expr,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out);
+
+/* grn_ts_expr_adjust() updates scores. */
+grn_rc grn_ts_expr_adjust(grn_ctx *ctx, grn_ts_expr *expr,
+ grn_ts_record *io, size_t n_io);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_expr_builder.c b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_builder.c
new file mode 100644
index 00000000000..4577ede2611
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_builder.c
@@ -0,0 +1,757 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_expr_builder.h"
+
+#include <string.h>
+
+#include "../grn_ctx.h"
+#include "../grn_db.h"
+
+#include "ts_log.h"
+#include "ts_util.h"
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_bridge.
+ */
+
+/* grn_ts_expr_bridge_init() initializes a bridge. */
+static void
+grn_ts_expr_bridge_init(grn_ctx *ctx, grn_ts_expr_bridge *bridge)
+{
+ memset(bridge, 0, sizeof(*bridge));
+ bridge->src_table = NULL;
+ bridge->dest_table = NULL;
+}
+
+/* grn_ts_expr_bridge_fin() finalizes a bridge. */
+static void
+grn_ts_expr_bridge_fin(grn_ctx *ctx, grn_ts_expr_bridge *bridge)
+{
+ if (bridge->dest_table) {
+ grn_obj_unlink(ctx, bridge->dest_table);
+ }
+ /* Note: bridge->src_table does not increment a reference count. */
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_builder.
+ */
+
+/* grn_ts_expr_builder_init() initializes an expression builder. */
+static void
+grn_ts_expr_builder_init(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ memset(builder, 0, sizeof(*builder));
+ builder->table = NULL;
+ builder->curr_table = NULL;
+ builder->nodes = NULL;
+ builder->bridges = NULL;
+}
+
+/* grn_ts_expr_builder_fin() finalizes an expression builder. */
+static void
+grn_ts_expr_builder_fin(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ size_t i;
+ if (builder->bridges) {
+ for (i = 0; i < builder->n_bridges; i++) {
+ grn_ts_expr_bridge_fin(ctx, &builder->bridges[i]);
+ }
+ GRN_FREE(builder->bridges);
+ }
+ if (builder->nodes) {
+ for (i = 0; i < builder->n_nodes; i++) {
+ if (builder->nodes[i]) {
+ grn_ts_expr_node_close(ctx, builder->nodes[i]);
+ }
+ }
+ GRN_FREE(builder->nodes);
+ }
+ /* Note: builder->curr_table does not increment a reference count. */
+ if (builder->table) {
+ grn_obj_unlink(ctx, builder->table);
+ }
+}
+
+grn_rc
+grn_ts_expr_builder_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_expr_builder **builder)
+{
+ grn_rc rc;
+ grn_ts_expr_builder *new_builder;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!table || !grn_ts_obj_is_table(ctx, table) || !builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ new_builder = GRN_MALLOCN(grn_ts_expr_builder, 1);
+ if (!new_builder) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE,
+ sizeof(grn_ts_expr_builder));
+ }
+ rc = grn_ts_obj_increment_ref_count(ctx, table);
+ if (rc != GRN_SUCCESS) {
+ GRN_FREE(new_builder);
+ return rc;
+ }
+ grn_ts_expr_builder_init(ctx, new_builder);
+ new_builder->table = table;
+ new_builder->curr_table = table;
+ *builder = new_builder;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_builder_close(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ grn_ts_expr_builder_fin(ctx, builder);
+ GRN_FREE(builder);
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_builder_complete(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_ts_expr **expr)
+{
+ grn_rc rc;
+ grn_ts_expr *new_expr;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder || (builder->n_nodes != 1) || builder->n_bridges || !expr) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ rc = grn_ts_expr_node_deref(ctx, &builder->nodes[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_open(ctx, builder->table, builder->nodes[0], &new_expr);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ builder->n_nodes = 0;
+ *expr = new_expr;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_builder_clear(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ size_t i;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ if (builder->bridges) {
+ for (i = 0; i < builder->n_bridges; i++) {
+ grn_ts_expr_bridge_fin(ctx, &builder->bridges[i]);
+ }
+ builder->n_bridges = 0;
+ }
+ if (builder->nodes) {
+ for (i = 0; i < builder->n_nodes; i++) {
+ if (builder->nodes[i]) {
+ grn_ts_expr_node_close(ctx, builder->nodes[i]);
+ }
+ }
+ builder->n_nodes = 0;
+ }
+ builder->curr_table = builder->table;
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ts_expr_builder_push_node() pushes a node.
+ * The given node will be closed on failure.
+ */
+static grn_rc
+grn_ts_expr_builder_push_node(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_ts_expr_node *node)
+{
+ if (builder->n_nodes == builder->max_n_nodes) {
+ size_t n_bytes, new_max_n_nodes;
+ grn_ts_expr_node **new_nodes;
+ new_max_n_nodes = builder->n_nodes ? (builder->n_nodes * 2) : 1;
+ n_bytes = sizeof(grn_ts_expr_node *) * new_max_n_nodes;
+ new_nodes = (grn_ts_expr_node **)GRN_REALLOC(builder->nodes, n_bytes);
+ if (!new_nodes) {
+ grn_ts_expr_node_close(ctx, node);
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE, n_bytes);
+ }
+ builder->nodes = new_nodes;
+ builder->max_n_nodes = new_max_n_nodes;
+ }
+ builder->nodes[builder->n_nodes++] = node;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_builder_push_name(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_ts_str name)
+{
+ grn_obj *column;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder || !grn_ts_str_is_name(name)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ if (grn_ts_str_is_id_name(name)) {
+ return grn_ts_expr_builder_push_id(ctx, builder);
+ }
+ if (grn_ts_str_is_score_name(name)) {
+ return grn_ts_expr_builder_push_score(ctx, builder);
+ }
+ if (grn_ts_str_is_key_name(name)) {
+ return grn_ts_expr_builder_push_key(ctx, builder);
+ }
+ if (grn_ts_str_is_value_name(name)) {
+ return grn_ts_expr_builder_push_value(ctx, builder);
+ }
+ /* grn_obj_column() returns a column or accessor. */
+ column = grn_obj_column(ctx, builder->curr_table, name.ptr, name.size);
+ if (!column) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "object not found: \"%.*s\"",
+ (int)name.size, name.ptr);
+ }
+ return grn_ts_expr_builder_push_obj(ctx, builder, column);
+}
+
+#define GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(TYPE, KIND, kind)\
+ case GRN_DB_ ## TYPE: {\
+ value.as_ ## kind = (grn_ts_ ## kind)GRN_ ## TYPE ## _VALUE(obj);\
+ return grn_ts_expr_builder_push_const(ctx, builder, GRN_TS_ ## KIND,\
+ obj->header.domain, value);\
+ }
+/* grn_ts_expr_push_builder_bulk() pushes a scalar const. */
+static grn_rc
+grn_ts_expr_builder_push_bulk(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_obj *obj)
+{
+ grn_ts_any value;
+ switch (obj->header.domain) {
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(BOOL, BOOL, bool)
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(INT8, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(INT16, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(INT32, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(INT64, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(UINT8, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(UINT16, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(UINT32, INT, int)
+ /* The behavior is undefined if a value is greater than 2^63 - 1. */
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(UINT64, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(FLOAT, FLOAT, float)
+ GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE(TIME, TIME, time)
+ case GRN_DB_SHORT_TEXT:
+ case GRN_DB_TEXT:
+ case GRN_DB_LONG_TEXT: {
+ value.as_text.ptr = GRN_TEXT_VALUE(obj);
+ value.as_text.size = GRN_TEXT_LEN(obj);
+ return grn_ts_expr_builder_push_const(ctx, builder, GRN_TS_TEXT,
+ obj->header.domain, value);
+ }
+ case GRN_DB_TOKYO_GEO_POINT:
+ case GRN_DB_WGS84_GEO_POINT: {
+ GRN_GEO_POINT_VALUE(obj, value.as_geo.latitude, value.as_geo.longitude);
+ return grn_ts_expr_builder_push_const(ctx, builder, GRN_TS_GEO,
+ obj->header.domain, value);
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "not bulk");
+ }
+ }
+}
+#undef GRN_TS_EXPR_BUILDER_PUSH_BULK_CASE
+
+#define GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE(TYPE, KIND, kind)\
+ case GRN_DB_ ## TYPE: {\
+ value.as_ ## kind ## _vector.ptr = (grn_ts_ ## kind *)GRN_BULK_HEAD(obj);\
+ value.as_ ## kind ## _vector.size = grn_uvector_size(ctx, obj);\
+ return grn_ts_expr_builder_push_const(ctx, builder, GRN_TS_ ## KIND,\
+ obj->header.domain, value);\
+ }
+#define GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE_WITH_TYPECAST(TYPE, KIND, kind)\
+ case GRN_DB_ ## TYPE: {\
+ size_t i;\
+ grn_rc rc;\
+ grn_ts_ ## kind *buf;\
+ grn_ts_ ## kind ## _vector vector = { NULL, grn_uvector_size(ctx, obj) };\
+ if (!vector.size) {\
+ value.as_ ## kind ## _vector = vector;\
+ return grn_ts_expr_builder_push_const(ctx, builder, GRN_TS_ ## KIND,\
+ obj->header.domain, value);\
+ }\
+ buf = GRN_MALLOCN(grn_ts_ ## kind, vector.size);\
+ if (!buf) {\
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,\
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",\
+ sizeof(grn_ts_ ## kind));\
+ }\
+ for (i = 0; i < vector.size; i++) {\
+ buf[i] = GRN_ ## TYPE ##_VALUE_AT(obj, i);\
+ }\
+ vector.ptr = buf;\
+ value.as_ ## kind ## _vector = vector;\
+ rc = grn_ts_expr_builder_push_const(ctx, builder, GRN_TS_ ## KIND,\
+ obj->header.domain, value);\
+ GRN_FREE(buf);\
+ return rc;\
+ }
+/* grn_ts_expr_builder_push_uvector() pushes an array of fixed-size values. */
+static grn_rc
+grn_ts_expr_builder_push_uvector(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_obj *obj)
+{
+ grn_ts_any value;
+ switch (obj->header.domain) {
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE(BOOL, BOOL, bool)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE_WITH_TYPECAST(INT8, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE_WITH_TYPECAST(INT16, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE_WITH_TYPECAST(INT32, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE(INT64, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE_WITH_TYPECAST(UINT8, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE_WITH_TYPECAST(UINT16, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE_WITH_TYPECAST(UINT32, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE(UINT64, INT, int)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE(TIME, TIME, time)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE(TOKYO_GEO_POINT, GEO, geo)
+ GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE(WGS84_GEO_POINT, GEO, geo)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data type: %d",
+ obj->header.domain);
+ }
+ }
+}
+#undef GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE_WITH_TYPECAST
+#undef GRN_TS_EXPR_BUILDER_PUSH_UVECTOR_CASE
+
+/* grn_ts_expr_builder_push_vector() pushes a Text vector. */
+static grn_rc
+grn_ts_expr_builder_push_vector(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_obj *obj)
+{
+ switch (obj->header.domain) {
+ case GRN_DB_SHORT_TEXT:
+ case GRN_DB_TEXT:
+ case GRN_DB_LONG_TEXT: {
+ size_t i;
+ grn_rc rc;
+ grn_ts_any value;
+ grn_ts_text *buf;
+ grn_ts_text_vector vector = { NULL, grn_vector_size(ctx, obj) };
+ if (!vector.size) {
+ value.as_text_vector = vector;
+ return grn_ts_expr_builder_push_const(ctx, builder, GRN_TS_TEXT_VECTOR,
+ obj->header.domain, value);
+ }
+ buf = GRN_MALLOCN(grn_ts_text, vector.size);
+ if (!buf) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: "
+ "%" GRN_FMT_SIZE " x %" GRN_FMT_SIZE,
+ sizeof(grn_ts_text), vector.size);
+ }
+ for (i = 0; i < vector.size; i++) {
+ buf[i].size = grn_vector_get_element(ctx, obj, i, &buf[i].ptr,
+ NULL, NULL);
+ }
+ vector.ptr = buf;
+ value.as_text_vector = vector;
+ rc = grn_ts_expr_builder_push_const(ctx, builder, GRN_TS_TEXT_VECTOR,
+ obj->header.domain, value);
+ GRN_FREE(buf);
+ return rc;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data type: %d",
+ obj->header.domain);
+ }
+ }
+}
+
+static grn_rc
+grn_ts_expr_builder_push_single_accessor(grn_ctx *ctx,
+ grn_ts_expr_builder *builder,
+ grn_accessor *accessor)
+{
+ switch (accessor->action) {
+ case GRN_ACCESSOR_GET_ID: {
+ return grn_ts_expr_builder_push_id(ctx, builder);
+ }
+ case GRN_ACCESSOR_GET_SCORE: {
+ return grn_ts_expr_builder_push_score(ctx, builder);
+ }
+ case GRN_ACCESSOR_GET_KEY: {
+ if (accessor->obj != builder->curr_table) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "table conflict");
+ }
+ return grn_ts_expr_builder_push_key(ctx, builder);
+ }
+ case GRN_ACCESSOR_GET_VALUE: {
+ if (accessor->obj != builder->curr_table) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "table conflict");
+ }
+ return grn_ts_expr_builder_push_value(ctx, builder);
+ }
+ case GRN_ACCESSOR_GET_COLUMN_VALUE: {
+ return grn_ts_expr_builder_push_column(ctx, builder, accessor->obj);
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid accessor action: %d",
+ accessor->action);
+ }
+ }
+}
+
+static grn_rc
+grn_ts_expr_builder_push_accessor(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_accessor *accessor)
+{
+ grn_rc rc = grn_ts_expr_builder_push_single_accessor(ctx, builder, accessor);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ for (accessor = accessor->next; accessor; accessor = accessor->next) {
+ rc = grn_ts_expr_builder_begin_subexpr(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_builder_push_single_accessor(ctx, builder, accessor);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_builder_end_subexpr(ctx, builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_builder_push_obj(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_obj *obj)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder || !obj) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ switch (obj->header.type) {
+ case GRN_BULK: {
+ return grn_ts_expr_builder_push_bulk(ctx, builder, obj);
+ }
+ case GRN_UVECTOR: {
+ return grn_ts_expr_builder_push_uvector(ctx, builder, obj);
+ }
+ case GRN_VECTOR: {
+ return grn_ts_expr_builder_push_vector(ctx, builder, obj);
+ }
+ case GRN_ACCESSOR: {
+ return grn_ts_expr_builder_push_accessor(ctx, builder,
+ (grn_accessor *)obj);
+ }
+ case GRN_COLUMN_FIX_SIZE:
+ case GRN_COLUMN_VAR_SIZE: {
+ return grn_ts_expr_builder_push_column(ctx, builder, obj);
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid object type: %d",
+ obj->header.type);
+ }
+ }
+}
+
+grn_rc
+grn_ts_expr_builder_push_id(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ grn_rc rc;
+ grn_ts_expr_node *node;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ rc = grn_ts_expr_id_node_open(ctx, &node);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_expr_builder_push_node(ctx, builder, node);
+ }
+ return rc;
+}
+
+grn_rc
+grn_ts_expr_builder_push_score(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ grn_rc rc;
+ grn_ts_expr_node *node;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ rc = grn_ts_expr_score_node_open(ctx, &node);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_expr_builder_push_node(ctx, builder, node);
+ }
+ return rc;
+}
+
+grn_rc
+grn_ts_expr_builder_push_key(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ grn_rc rc;
+ grn_ts_expr_node *node;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ rc = grn_ts_expr_key_node_open(ctx, builder->curr_table, &node);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_expr_builder_push_node(ctx, builder, node);
+ }
+ return rc;
+}
+
+grn_rc
+grn_ts_expr_builder_push_value(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ grn_rc rc;
+ grn_ts_expr_node *node;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ rc = grn_ts_expr_value_node_open(ctx, builder->curr_table, &node);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_expr_builder_push_node(ctx, builder, node);
+ }
+ return rc;
+}
+
+grn_rc
+grn_ts_expr_builder_push_const(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_ts_data_kind kind, grn_ts_data_type type,
+ grn_ts_any value)
+{
+ grn_rc rc;
+ grn_ts_expr_node *node;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ rc = grn_ts_expr_const_node_open(ctx, kind, type, value, &node);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_expr_builder_push_node(ctx, builder, node);
+ }
+ return rc;
+}
+
+grn_rc
+grn_ts_expr_builder_push_column(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_obj *column)
+{
+ grn_rc rc;
+ grn_ts_expr_node *node;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder || !column || !grn_ts_obj_is_column(ctx, column) ||
+ (DB_OBJ(builder->curr_table)->id != column->header.domain)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ rc = grn_ts_expr_column_node_open(ctx, column, &node);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_expr_builder_push_node(ctx, builder, node);
+ }
+ return rc;
+}
+
+/*
+ * grn_ts_expr_builder_get_max_n_args() returns the number of nodes in the
+ * current subexpression.
+ */
+static size_t
+grn_ts_expr_builder_get_max_n_args(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ size_t max_n_args = builder->n_nodes;
+ if (builder->n_bridges) {
+ max_n_args -= builder->bridges[builder->n_bridges - 1].n_nodes;
+ }
+ return max_n_args;
+}
+
+grn_rc
+grn_ts_expr_builder_push_op(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_ts_op_type op_type)
+{
+ grn_rc rc;
+ grn_ts_expr_node **args, *node;
+ size_t n_args, max_n_args;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ n_args = grn_ts_op_get_n_args(op_type);
+ if (!n_args) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
+ "invalid #arguments: %" GRN_FMT_SIZE,
+ n_args);
+ }
+ max_n_args = grn_ts_expr_builder_get_max_n_args(ctx, builder);
+ if (n_args > max_n_args) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
+ "invalid #arguments: %" GRN_FMT_SIZE ", %" GRN_FMT_SIZE,
+ n_args, builder->n_nodes);
+ }
+ /* Arguments are the top n_args nodes in the stack. */
+ args = &builder->nodes[builder->n_nodes - n_args];
+ builder->n_nodes -= n_args;
+ rc = grn_ts_expr_op_node_open(ctx, op_type, args, n_args, &node);
+ if (rc == GRN_SUCCESS) {
+ builder->nodes[builder->n_nodes++] = node;
+ }
+ return rc;
+}
+
+/* grn_ts_expr_builder_push_bridge() pushes a bridge. */
+static grn_rc
+grn_ts_expr_builder_push_bridge(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_ts_expr_bridge *bridge)
+{
+ if (builder->n_bridges == builder->max_n_bridges) {
+ size_t n_bytes, new_max_n_bridges;
+ grn_ts_expr_bridge *new_bridges;
+ new_max_n_bridges = builder->n_bridges ? (builder->n_bridges * 2) : 1;
+ n_bytes = sizeof(grn_ts_expr_bridge) * new_max_n_bridges;
+ new_bridges = (grn_ts_expr_bridge *)GRN_REALLOC(builder->bridges, n_bytes);
+ if (!new_bridges) {
+ grn_ts_expr_bridge_fin(ctx, bridge);
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE, n_bytes);
+ }
+ builder->bridges = new_bridges;
+ builder->max_n_bridges = new_max_n_bridges;
+ }
+ builder->bridges[builder->n_bridges++] = *bridge;
+ builder->curr_table = bridge->dest_table;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_builder_pop_bridge() pops a bridge. */
+static void
+grn_ts_expr_builder_pop_bridge(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ grn_ts_expr_bridge *bridge = &builder->bridges[builder->n_bridges - 1];
+ builder->curr_table = bridge->src_table;
+ grn_ts_expr_bridge_fin(ctx, bridge);
+ builder->n_bridges--;
+}
+
+grn_rc
+grn_ts_expr_builder_begin_subexpr(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ grn_rc rc;
+ size_t max_n_args;
+ grn_obj *obj;
+ grn_ts_expr_node *node;
+ grn_ts_expr_bridge bridge;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ max_n_args = grn_ts_expr_builder_get_max_n_args(ctx, builder);
+ if (!max_n_args) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ /* Check whehter or not the latest node refers to a table. */
+ node = builder->nodes[builder->n_nodes - 1];
+ if ((node->data_kind & ~GRN_TS_VECTOR_FLAG) != GRN_TS_REF) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ obj = grn_ctx_at(ctx, node->data_type);
+ if (!obj) {
+ GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "grn_ctx_at failed: %d",
+ node->data_type);
+ }
+ if (!grn_ts_obj_is_table(ctx, obj)) {
+ grn_obj_unlink(ctx, obj);
+ GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "not table: %d", node->data_type);
+ }
+ /* Creates a bridge to a subexpression. */
+ grn_ts_expr_bridge_init(ctx, &bridge);
+ bridge.src_table = builder->curr_table;
+ bridge.dest_table = obj;
+ bridge.n_nodes = builder->n_nodes;
+ rc = grn_ts_expr_builder_push_bridge(ctx, builder, &bridge);
+ if (rc != GRN_SUCCESS) {
+ grn_obj_unlink(ctx, obj);
+ return rc;
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_builder_end_subexpr(grn_ctx *ctx, grn_ts_expr_builder *builder)
+{
+ grn_rc rc;
+ grn_ts_expr_node **args, *node;
+ if (!ctx || !builder || (builder->n_nodes < 2) || !builder->n_bridges) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ /* Check whehter or not the subexpression is complete.*/
+ if (grn_ts_expr_builder_get_max_n_args(ctx, builder) != 1) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ /* Creates a bridge node. */
+ args = &builder->nodes[builder->n_nodes - 2];
+ rc = grn_ts_expr_bridge_node_open(ctx, args[0], args[1], &node);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ /* Note: The following grn_ts_expr_push_node() must not fail. */
+ builder->n_nodes -= 2;
+ grn_ts_expr_builder_push_node(ctx, builder, node);
+ grn_ts_expr_builder_pop_bridge(ctx, builder);
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_expr_builder.h b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_builder.h
new file mode 100644
index 00000000000..2e2eb436db4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_builder.h
@@ -0,0 +1,128 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#include "ts_buf.h"
+#include "ts_expr.h"
+#include "ts_expr_node.h"
+#include "ts_op.h"
+#include "ts_str.h"
+#include "ts_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ grn_obj *src_table; /* The source table of a bridge (no ref. count). */
+ grn_obj *dest_table; /* The destination table of a bridge. */
+ size_t n_nodes; /* The stack depth (position) of a bridge. */
+} grn_ts_expr_bridge;
+
+typedef struct {
+ grn_obj *table; /* Associated table. */
+ grn_obj *curr_table; /* Current table (no ref. count). */
+ grn_ts_expr_node **nodes; /* Node stack. */
+ size_t n_nodes; /* Number of nodes (stack depth). */
+ size_t max_n_nodes; /* Maximum number of nodes (stack capacity). */
+ grn_ts_expr_bridge *bridges; /* Bridges to subexpressions. */
+ size_t n_bridges; /* Number of bridges (subexpression depth). */
+ size_t max_n_bridges; /* Max. number (capacity) of bridges. */
+} grn_ts_expr_builder;
+
+/* grn_ts_expr_builder_open() creates an expression builder. */
+grn_rc grn_ts_expr_builder_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_expr_builder **builder);
+
+/* grn_ts_expr_builder_close() destroys an expression builder. */
+grn_rc grn_ts_expr_builder_close(grn_ctx *ctx, grn_ts_expr_builder *builder);
+
+/* grn_ts_expr_builder_complete() completes an expression. */
+grn_rc grn_ts_expr_builder_complete(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_ts_expr **expr);
+
+/* grn_ts_expr_builder_clear() clears the internal states. */
+grn_rc grn_ts_expr_builder_clear(grn_ctx *ctx, grn_ts_expr_builder *builder);
+
+/* grn_ts_expr_builder_push_name() pushes a named object. */
+grn_rc grn_ts_expr_builder_push_name(grn_ctx *ctx,
+ grn_ts_expr_builder *builder,
+ grn_ts_str name);
+
+/*
+ * grn_ts_expr_builder_push_obj() pushes an object.
+ *
+ * Acceptable objects are as follows:
+ * - Consts
+ * - GRN_BULK: GRN_DB_*.
+ * - GRN_UVECTOR: GRN_DB_* except GRN_DB_[SHORT/LONG_]TEXT.
+ * - GRN_VECTOR: GRN_DB_[SHORT/LONG_]TEXT.
+ * - Columns
+ * - GRN_ACCESSOR: _id, _score, _key, _value, and columns.
+ * - GRN_COLUMN_FIX_SIZE: GRN_DB_* except GRN_DB_[SHORT/LONG_]TEXT.
+ * - GRN_COLUMN_VAR_SIZE: GRN_DB_[SHORT/LONG_]TEXT.
+ */
+grn_rc grn_ts_expr_builder_push_obj(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_obj *obj);
+
+/* grn_ts_expr_builder_push_id() pushes "_id". */
+grn_rc grn_ts_expr_builder_push_id(grn_ctx *ctx, grn_ts_expr_builder *builder);
+
+/* grn_ts_expr_builder_push_score() pushes "_score". */
+grn_rc grn_ts_expr_builder_push_score(grn_ctx *ctx,
+ grn_ts_expr_builder *builder);
+
+/* grn_ts_expr_builder_push_key() pushes "_key". */
+grn_rc grn_ts_expr_builder_push_key(grn_ctx *ctx,
+ grn_ts_expr_builder *builder);
+
+/* grn_ts_expr_builder_push_value() pushes "_value". */
+grn_rc grn_ts_expr_builder_push_value(grn_ctx *ctx,
+ grn_ts_expr_builder *builder);
+
+/* grn_ts_expr_builder_push_const() pushes a const. */
+grn_rc grn_ts_expr_builder_push_const(grn_ctx *ctx,
+ grn_ts_expr_builder *builder,
+ grn_ts_data_kind kind,
+ grn_ts_data_type type,
+ grn_ts_any value);
+
+/* grn_ts_expr_builder_push_column() pushes a column. */
+grn_rc grn_ts_expr_builder_push_column(grn_ctx *ctx,
+ grn_ts_expr_builder *builder,
+ grn_obj *column);
+
+/* grn_ts_expr_builder_push_op() pushes an operator. */
+grn_rc grn_ts_expr_builder_push_op(grn_ctx *ctx, grn_ts_expr_builder *builder,
+ grn_ts_op_type op_type);
+
+/* grn_ts_expr_builder_begin_subexpr() begins a subexpression. */
+grn_rc grn_ts_expr_builder_begin_subexpr(grn_ctx *ctx,
+ grn_ts_expr_builder *builder);
+
+/* grn_ts_expr_builder_end_subexpr() ends a subexpression. */
+grn_rc grn_ts_expr_builder_end_subexpr(grn_ctx *ctx,
+ grn_ts_expr_builder *builder);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.c b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.c
new file mode 100644
index 00000000000..44378cfae25
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.c
@@ -0,0 +1,5374 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_expr_node.h"
+
+#include <math.h>
+#include <string.h>
+
+#include "../grn_ctx.h"
+#include "../grn_dat.h"
+#include "../grn_db.h"
+#include "../grn_geo.h"
+#include "../grn_hash.h"
+#include "../grn_pat.h"
+#include "../grn_store.h"
+
+#include "ts_log.h"
+#include "ts_str.h"
+#include "ts_util.h"
+
+/*-------------------------------------------------------------
+ * Built-in data kinds.
+ */
+
+/* grn_ts_bool_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_bool_is_valid(grn_ts_bool value)
+{
+ return GRN_TRUE;
+}
+
+/* grn_ts_int_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_int_is_valid(grn_ts_int value)
+{
+ return GRN_TRUE;
+}
+
+/* grn_ts_float_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_float_is_valid(grn_ts_float value)
+{
+ return isfinite(value);
+}
+
+/* grn_ts_time_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_time_is_valid(grn_ts_time value)
+{
+ return GRN_TRUE;
+}
+
+/* grn_ts_text_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_text_is_valid(grn_ts_text value)
+{
+ return value.ptr || !value.size;
+}
+
+/* grn_ts_geo_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_geo_is_valid(grn_ts_geo value)
+{
+ return ((value.latitude >= GRN_GEO_MIN_LATITUDE) &&
+ (value.latitude <= GRN_GEO_MAX_LATITUDE)) &&
+ ((value.longitude >= GRN_GEO_MIN_LONGITUDE) &&
+ (value.longitude <= GRN_GEO_MAX_LONGITUDE));
+}
+
+#define GRN_TS_VECTOR_IS_VALID(type)\
+ if (value.size) {\
+ size_t i;\
+ if (!value.ptr) {\
+ return GRN_FALSE;\
+ }\
+ for (i = 0; i < value.size; i++) {\
+ if (!grn_ts_ ## type ## _is_valid(value.ptr[i])) {\
+ return GRN_FALSE;\
+ }\
+ }\
+ }\
+ return GRN_TRUE;
+/* grn_ts_bool_vector_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_bool_vector_is_valid(grn_ts_bool_vector value)
+{
+ GRN_TS_VECTOR_IS_VALID(bool)
+}
+
+/* grn_ts_int_vector_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_int_vector_is_valid(grn_ts_int_vector value)
+{
+ GRN_TS_VECTOR_IS_VALID(int)
+}
+
+/* grn_ts_float_vector_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_float_vector_is_valid(grn_ts_float_vector value)
+{
+ GRN_TS_VECTOR_IS_VALID(float)
+}
+
+/* grn_ts_time_vector_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_time_vector_is_valid(grn_ts_time_vector value)
+{
+ GRN_TS_VECTOR_IS_VALID(time)
+}
+
+/* grn_ts_text_vector_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_text_vector_is_valid(grn_ts_text_vector value)
+{
+ GRN_TS_VECTOR_IS_VALID(text)
+}
+
+/* grn_ts_geo_vector_is_valid() returns whether a value is valid or not. */
+inline static grn_ts_bool
+grn_ts_geo_vector_is_valid(grn_ts_geo_vector value)
+{
+ GRN_TS_VECTOR_IS_VALID(geo)
+}
+#undef GRN_TS_VECTOR_IS_VALID
+
+/* grn_ts_bool_zero() returns a zero. */
+inline static grn_ts_bool
+grn_ts_bool_zero(void)
+{
+ return GRN_FALSE;
+}
+
+/* grn_ts_int_zero() returns a zero. */
+inline static grn_ts_int
+grn_ts_int_zero(void)
+{
+ return 0;
+}
+
+/* grn_ts_float_zero() returns a zero. */
+inline static grn_ts_float
+grn_ts_float_zero(void)
+{
+ return 0.0;
+}
+
+/* grn_ts_time_zero() returns a zero. */
+inline static grn_ts_time
+grn_ts_time_zero(void)
+{
+ return 0;
+}
+
+/* grn_ts_text_zero() returns a zero. */
+inline static grn_ts_text
+grn_ts_text_zero(void)
+{
+ return (grn_ts_text){ NULL, 0 };
+}
+
+/* grn_ts_geo_zero() returns a zero. */
+inline static grn_ts_geo
+grn_ts_geo_zero(void)
+{
+ return (grn_ts_geo){ 0, 0 };
+}
+
+/* grn_ts_ref_zero() returns a zero. */
+inline static grn_ts_ref
+grn_ts_ref_zero(void)
+{
+ return (grn_ts_ref){ 0, 0.0 };
+}
+
+/* grn_ts_bool_vector_zero() returns a zero. */
+inline static grn_ts_bool_vector
+grn_ts_bool_vector_zero(void)
+{
+ return (grn_ts_bool_vector){ NULL, 0 };
+}
+
+/* grn_ts_int_vector_zero() returns a zero. */
+inline static grn_ts_int_vector
+grn_ts_int_vector_zero(void)
+{
+ return (grn_ts_int_vector){ NULL, 0 };
+}
+
+/* grn_ts_float_vector_zero() returns a zero. */
+inline static grn_ts_float_vector
+grn_ts_float_vector_zero(void)
+{
+ return (grn_ts_float_vector){ NULL, 0 };
+}
+
+/* grn_ts_time_vector_zero() returns a zero. */
+inline static grn_ts_time_vector
+grn_ts_time_vector_zero(void)
+{
+ return (grn_ts_time_vector){ NULL, 0 };
+}
+
+/* grn_ts_text_vector_zero() returns a zero. */
+inline static grn_ts_text_vector
+grn_ts_text_vector_zero(void)
+{
+ return (grn_ts_text_vector){ NULL, 0 };
+}
+
+/* grn_ts_geo_vector_zero() returns a zero. */
+inline static grn_ts_geo_vector
+grn_ts_geo_vector_zero(void)
+{
+ return (grn_ts_geo_vector){ NULL, 0 };
+}
+
+/* grn_ts_ref_vector_zero() returns a zero. */
+inline static grn_ts_ref_vector
+grn_ts_ref_vector_zero(void)
+{
+ return (grn_ts_ref_vector){ NULL, 0 };
+}
+
+/* grn_ts_data_type_to_kind() returns a kind associated with a type. */
+static grn_ts_data_kind
+grn_ts_data_type_to_kind(grn_ts_data_type type)
+{
+ switch (type) {
+ case GRN_DB_VOID: {
+ return GRN_TS_VOID;
+ }
+ case GRN_DB_BOOL: {
+ return GRN_TS_BOOL;
+ }
+ case GRN_DB_INT8:
+ case GRN_DB_INT16:
+ case GRN_DB_INT32:
+ case GRN_DB_INT64:
+ case GRN_DB_UINT8:
+ case GRN_DB_UINT16:
+ case GRN_DB_UINT32:
+ case GRN_DB_UINT64: {
+ return GRN_TS_INT;
+ }
+ case GRN_DB_FLOAT: {
+ return GRN_TS_FLOAT;
+ }
+ case GRN_DB_TIME: {
+ return GRN_TS_TIME;
+ }
+ case GRN_DB_SHORT_TEXT:
+ case GRN_DB_TEXT:
+ case GRN_DB_LONG_TEXT: {
+ return GRN_TS_TEXT;
+ }
+ case GRN_DB_TOKYO_GEO_POINT:
+ case GRN_DB_WGS84_GEO_POINT: {
+ return GRN_TS_GEO;
+ }
+ default: {
+ return GRN_TS_REF;
+ }
+ }
+}
+
+/* grn_ts_data_kind_to_type() returns a type associated with a kind. */
+static grn_ts_data_type
+grn_ts_data_kind_to_type(grn_ts_data_kind kind)
+{
+ switch (kind & ~GRN_TS_VECTOR_FLAG) {
+ case GRN_TS_BOOL: {
+ return GRN_DB_BOOL;
+ }
+ case GRN_TS_INT: {
+ return GRN_DB_INT64;
+ }
+ case GRN_TS_FLOAT: {
+ return GRN_DB_FLOAT;
+ }
+ case GRN_TS_TIME: {
+ return GRN_DB_TIME;
+ }
+ case GRN_TS_TEXT: {
+ return GRN_DB_TEXT;
+ }
+ case GRN_TS_GEO: {
+ /* GRN_DB_TOKYO_GEO_POINT or GRN_DB_WGS84_GEO_POINT. */
+ return GRN_DB_VOID;
+ }
+ case GRN_TS_REF: {
+ /*
+ * grn_ts_data_kind does not have enough information to get a correct
+ * table ID.
+ */
+ return GRN_DB_VOID;
+ }
+ default: {
+ return GRN_DB_VOID;
+ }
+ }
+}
+
+/*-------------------------------------------------------------
+ * Operators.
+ */
+
+/* grn_ts_op_logical_not_bool() returns !arg. */
+inline static grn_ts_bool
+grn_ts_op_logical_not_bool(grn_ts_bool arg)
+{
+ return !arg;
+}
+
+/* grn_ts_op_bitwise_not_bool() returns ~arg. */
+inline static grn_ts_bool
+grn_ts_op_bitwise_not_bool(grn_ts_bool arg)
+{
+ return !arg;
+}
+
+/* grn_ts_op_bitwise_not_int() returns ~arg. */
+inline static grn_ts_int
+grn_ts_op_bitwise_not_int(grn_ts_int arg)
+{
+ return ~arg;
+}
+
+/* grn_ts_op_positive_int() returns +arg. */
+inline static grn_ts_int
+grn_ts_op_positive_int(grn_ts_int arg)
+{
+ return arg;
+}
+
+/* grn_ts_op_positive_float() returns +arg. */
+inline static grn_ts_float
+grn_ts_op_positive_float(grn_ts_float arg)
+{
+ return arg;
+}
+
+/* grn_ts_op_negative_int() returns -arg. */
+inline static grn_ts_int
+grn_ts_op_negative_int(grn_ts_int arg)
+{
+ return -arg;
+}
+
+/* grn_ts_op_negative_float() returns -arg. */
+inline static grn_ts_float
+grn_ts_op_negative_float(grn_ts_float arg)
+{
+ return -arg;
+}
+
+/* grn_ts_op_float() returns (Float)arg. */
+static grn_rc
+grn_ts_op_float(grn_ctx *ctx, grn_ts_int arg, grn_ts_float *out)
+{
+ *out = (grn_ts_float)arg;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_op_time() returns (Time)arg. */
+static grn_rc
+grn_ts_op_time(grn_ctx *ctx, grn_ts_text arg, grn_ts_time *out)
+{
+ grn_timeval value;
+ grn_rc rc = grn_str2timeval(arg.ptr, arg.size, &value);
+ if (rc != GRN_SUCCESS) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "grn_str2timeval failed");
+ }
+ *out = (grn_ts_time)((value.tv_sec * 1000000) + (value.tv_nsec / 1000));
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_op_bitwise_and_bool() returns lhs & rhs. */
+inline static grn_ts_bool
+grn_ts_op_bitwise_and_bool(grn_ts_bool lhs, grn_ts_bool rhs)
+{
+ return lhs & rhs;
+}
+
+/* grn_ts_op_bitwise_and_int() returns lhs & rhs. */
+inline static grn_ts_int
+grn_ts_op_bitwise_and_int(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs & rhs;
+}
+
+/* grn_ts_op_bitwise_or_bool() returns lhs | rhs. */
+inline static grn_ts_bool
+grn_ts_op_bitwise_or_bool(grn_ts_bool lhs, grn_ts_bool rhs)
+{
+ return lhs | rhs;
+}
+
+/* grn_ts_op_bitwise_or_int() returns lhs | rhs. */
+inline static grn_ts_int
+grn_ts_op_bitwise_or_int(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs | rhs;
+}
+
+/* grn_ts_op_bitwise_xor_bool() returns lhs ^ rhs. */
+inline static grn_ts_bool
+grn_ts_op_bitwise_xor_bool(grn_ts_bool lhs, grn_ts_bool rhs)
+{
+ return lhs ^ rhs;
+}
+
+/* grn_ts_op_bitwise_xor_int() returns lhs ^ rhs. */
+inline static grn_ts_int
+grn_ts_op_bitwise_xor_int(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs ^ rhs;
+}
+
+/* grn_ts_op_equal_bool() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_bool(grn_ts_bool lhs, grn_ts_bool rhs)
+{
+ return lhs == rhs;
+}
+
+/* grn_ts_op_equal_int() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_int(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs == rhs;
+}
+
+/* grn_ts_op_equal_float() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_float(grn_ts_float lhs, grn_ts_float rhs)
+{
+ /* To suppress warnings, "lhs == rhs" is not used. */
+ return (lhs <= rhs) && (lhs >= rhs);
+}
+
+/* grn_ts_op_equal_time() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_time(grn_ts_time lhs, grn_ts_time rhs)
+{
+ return lhs == rhs;
+}
+
+/* grn_ts_op_equal_text() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_text(grn_ts_text lhs, grn_ts_text rhs)
+{
+ return (lhs.size == rhs.size) && !memcmp(lhs.ptr, rhs.ptr, lhs.size);
+}
+
+/* grn_ts_op_equal_geo() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_geo(grn_ts_geo lhs, grn_ts_geo rhs)
+{
+ return (lhs.latitude == rhs.latitude) && (lhs.longitude == rhs.longitude);
+}
+
+/* grn_ts_op_equal_ref() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_ref(grn_ts_ref lhs, grn_ts_ref rhs)
+{
+ /* Ignore scores. */
+ return lhs.id == rhs.id;
+}
+
+#define GRN_TS_OP_EQUAL_VECTOR(kind)\
+ size_t i;\
+ if (lhs.size != rhs.size) {\
+ return GRN_FALSE;\
+ }\
+ for (i = 0; i < lhs.size; i++) {\
+ if (!grn_ts_op_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
+ return GRN_FALSE;\
+ }\
+ }\
+ return GRN_TRUE;
+/* grn_ts_op_equal_bool_vector() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_bool_vector(grn_ts_bool_vector lhs, grn_ts_bool_vector rhs)
+{
+ GRN_TS_OP_EQUAL_VECTOR(bool)
+}
+
+/* grn_ts_op_equal_int_vector() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs)
+{
+ GRN_TS_OP_EQUAL_VECTOR(int)
+}
+
+/* grn_ts_op_equal_float_vector() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_float_vector(grn_ts_float_vector lhs, grn_ts_float_vector rhs)
+{
+ GRN_TS_OP_EQUAL_VECTOR(float)
+}
+
+/* grn_ts_op_equal_time_vector() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_time_vector(grn_ts_time_vector lhs, grn_ts_time_vector rhs)
+{
+ GRN_TS_OP_EQUAL_VECTOR(time)
+}
+
+/* grn_ts_op_equal_text_vector() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_text_vector(grn_ts_text_vector lhs, grn_ts_text_vector rhs)
+{
+ GRN_TS_OP_EQUAL_VECTOR(text)
+}
+
+/* grn_ts_op_equal_geo_vector() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_geo_vector(grn_ts_geo_vector lhs, grn_ts_geo_vector rhs)
+{
+ GRN_TS_OP_EQUAL_VECTOR(geo)
+}
+
+/* grn_ts_op_equal_ref_vector() returns lhs == rhs. */
+inline static grn_ts_bool
+grn_ts_op_equal_ref_vector(grn_ts_ref_vector lhs, grn_ts_ref_vector rhs)
+{
+ GRN_TS_OP_EQUAL_VECTOR(ref)
+}
+#undef GRN_TS_OP_EQUAL_VECTOR
+
+/* grn_ts_op_not_equal_bool() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_bool(grn_ts_bool lhs, grn_ts_bool rhs)
+{
+ return lhs != rhs;
+}
+
+/* grn_ts_op_not_equal_int() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_int(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs != rhs;
+}
+
+/* grn_ts_op_not_equal_float() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_float(grn_ts_float lhs, grn_ts_float rhs)
+{
+ /* To suppress warnings, "lhs != rhs" is not used. */
+ return (lhs < rhs) || (lhs > rhs);
+}
+
+/* grn_ts_op_not_equal_time() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_time(grn_ts_time lhs, grn_ts_time rhs)
+{
+ return lhs != rhs;
+}
+
+/* grn_ts_op_not_equal_text() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_text(grn_ts_text lhs, grn_ts_text rhs)
+{
+ return (lhs.size != rhs.size) || memcmp(lhs.ptr, rhs.ptr, lhs.size);
+}
+
+/* grn_ts_op_not_equal_geo() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_geo(grn_ts_geo lhs, grn_ts_geo rhs)
+{
+ return (lhs.latitude != rhs.latitude) || (lhs.longitude != rhs.longitude);
+}
+
+/* grn_ts_op_not_equal_ref() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_ref(grn_ts_ref lhs, grn_ts_ref rhs)
+{
+ /* Ignore scores. */
+ return lhs.id != rhs.id;
+}
+
+#define GRN_TS_OP_NOT_EQUAL_VECTOR(kind)\
+ size_t i;\
+ if (lhs.size != rhs.size) {\
+ return GRN_TRUE;\
+ }\
+ for (i = 0; i < lhs.size; i++) {\
+ if (grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
+ return GRN_TRUE;\
+ }\
+ }\
+ return GRN_FALSE;
+/* grn_ts_op_not_equal_bool_vector() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_bool_vector(grn_ts_bool_vector lhs, grn_ts_bool_vector rhs)
+{
+ GRN_TS_OP_NOT_EQUAL_VECTOR(bool)
+}
+
+/* grn_ts_op_not_equal_int_vector() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs)
+{
+ GRN_TS_OP_NOT_EQUAL_VECTOR(int)
+}
+
+/* grn_ts_op_not_equal_float_vector() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_float_vector(grn_ts_float_vector lhs,
+ grn_ts_float_vector rhs)
+{
+ GRN_TS_OP_NOT_EQUAL_VECTOR(float)
+}
+
+/* grn_ts_op_not_equal_time_vector() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_time_vector(grn_ts_time_vector lhs, grn_ts_time_vector rhs)
+{
+ GRN_TS_OP_NOT_EQUAL_VECTOR(time)
+}
+
+/* grn_ts_op_not_equal_text_vector() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_text_vector(grn_ts_text_vector lhs, grn_ts_text_vector rhs)
+{
+ GRN_TS_OP_NOT_EQUAL_VECTOR(text)
+}
+
+/* grn_ts_op_not_equal_geo_vector() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_geo_vector(grn_ts_geo_vector lhs, grn_ts_geo_vector rhs)
+{
+ GRN_TS_OP_NOT_EQUAL_VECTOR(geo)
+}
+
+/* grn_ts_op_not_equal_ref_vector() returns lhs != rhs. */
+inline static grn_ts_bool
+grn_ts_op_not_equal_ref_vector(grn_ts_ref_vector lhs, grn_ts_ref_vector rhs)
+{
+ GRN_TS_OP_NOT_EQUAL_VECTOR(ref)
+}
+#undef GRN_TS_OP_NOT_EQUAL_VECTOR
+
+/* grn_ts_op_less_int() returns lhs < rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_int(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs < rhs;
+}
+
+/* grn_ts_op_less_float() returns lhs < rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_float(grn_ts_float lhs, grn_ts_float rhs)
+{
+ return lhs < rhs;
+}
+
+/* grn_ts_op_less_time() returns lhs < rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_time(grn_ts_time lhs, grn_ts_time rhs)
+{
+ return lhs < rhs;
+}
+
+/* grn_ts_op_less_text() returns lhs < rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_text(grn_ts_text lhs, grn_ts_text rhs)
+{
+ size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
+ int cmp = memcmp(lhs.ptr, rhs.ptr, min_size);
+ return cmp ? (cmp < 0) : (lhs.size < rhs.size);
+}
+
+#define GRN_TS_OP_LESS_VECTOR(kind)\
+ size_t i, min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;\
+ for (i = 0; i < min_size; i++) {\
+ if (grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
+ if (grn_ts_op_less_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
+ return GRN_TRUE;\
+ }\
+ }\
+ }\
+ return lhs.size < rhs.size;
+/* grn_ts_op_less_int_vector() returns lhs < rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs)
+{
+ GRN_TS_OP_LESS_VECTOR(int)
+}
+
+/* grn_ts_op_less_float_vector() returns lhs < rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_float_vector(grn_ts_float_vector lhs, grn_ts_float_vector rhs)
+{
+ GRN_TS_OP_LESS_VECTOR(float)
+}
+
+/* grn_ts_op_less_time_vector() returns lhs < rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_time_vector(grn_ts_time_vector lhs, grn_ts_time_vector rhs)
+{
+ GRN_TS_OP_LESS_VECTOR(time)
+}
+
+/* grn_ts_op_less_text_vector() returns lhs < rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_text_vector(grn_ts_text_vector lhs, grn_ts_text_vector rhs)
+{
+ GRN_TS_OP_LESS_VECTOR(text)
+}
+#undef GRN_TS_OP_LESS_VECTOR
+
+/* grn_ts_op_less_equal_int() returns lhs <= rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_equal_int(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs <= rhs;
+}
+
+/* grn_ts_op_less_equal_float() returns lhs <= rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_equal_float(grn_ts_float lhs, grn_ts_float rhs)
+{
+ return lhs <= rhs;
+}
+
+/* grn_ts_op_less_equal_time() returns lhs <= rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_equal_time(grn_ts_time lhs, grn_ts_time rhs)
+{
+ return lhs <= rhs;
+}
+
+/* grn_ts_op_less_equal_text() returns lhs <= rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_equal_text(grn_ts_text lhs, grn_ts_text rhs)
+{
+ size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
+ int cmp = memcmp(lhs.ptr, rhs.ptr, min_size);
+ return cmp ? (cmp < 0) : (lhs.size <= rhs.size);
+}
+
+#define GRN_TS_OP_LESS_EQUAL_VECTOR(kind)\
+ size_t i, min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;\
+ for (i = 0; i < min_size; i++) {\
+ if (grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
+ if (grn_ts_op_less_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
+ return GRN_TRUE;\
+ }\
+ }\
+ }\
+ return lhs.size <= rhs.size;
+/* grn_ts_op_less_equal_int_vector() returns lhs <= rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_equal_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs)
+{
+ GRN_TS_OP_LESS_EQUAL_VECTOR(int)
+}
+
+/* grn_ts_op_less_equal_float_vector() returns lhs <= rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_equal_float_vector(grn_ts_float_vector lhs,
+ grn_ts_float_vector rhs)
+{
+ GRN_TS_OP_LESS_EQUAL_VECTOR(float)
+}
+
+/* grn_ts_op_less_equal_time_vector() returns lhs <= rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_equal_time_vector(grn_ts_time_vector lhs,
+ grn_ts_time_vector rhs)
+{
+ GRN_TS_OP_LESS_EQUAL_VECTOR(time)
+}
+
+/* grn_ts_op_less_equal_text_vector() returns lhs <= rhs. */
+inline static grn_ts_bool
+grn_ts_op_less_equal_text_vector(grn_ts_text_vector lhs,
+ grn_ts_text_vector rhs)
+{
+ GRN_TS_OP_LESS_EQUAL_VECTOR(text)
+}
+#undef GRN_TS_OP_LESS_EQUAL_VECTOR
+
+/* grn_ts_op_greater_int() returns lhs > rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_int(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs > rhs;
+}
+
+/* grn_ts_op_greater_float() returns lhs > rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_float(grn_ts_float lhs, grn_ts_float rhs)
+{
+ return lhs > rhs;
+}
+
+/* grn_ts_op_greater_time() returns lhs > rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_time(grn_ts_time lhs, grn_ts_time rhs)
+{
+ return lhs > rhs;
+}
+
+/* grn_ts_op_greater_text() returns lhs > rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_text(grn_ts_text lhs, grn_ts_text rhs)
+{
+ size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
+ int cmp = memcmp(lhs.ptr, rhs.ptr, min_size);
+ return cmp ? (cmp > 0) : (lhs.size > rhs.size);
+}
+
+#define GRN_TS_OP_GREATER_VECTOR(kind)\
+ size_t i, min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;\
+ for (i = 0; i < min_size; i++) {\
+ if (grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
+ if (grn_ts_op_greater_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
+ return GRN_TRUE;\
+ }\
+ }\
+ }\
+ return lhs.size > rhs.size;
+/* grn_ts_op_greater_int_vector() returns lhs > rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs)
+{
+ GRN_TS_OP_GREATER_VECTOR(int)
+}
+
+/* grn_ts_op_greater_float_vector() returns lhs > rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_float_vector(grn_ts_float_vector lhs,
+ grn_ts_float_vector rhs)
+{
+ GRN_TS_OP_GREATER_VECTOR(float)
+}
+
+/* grn_ts_op_greater_time_vector() returns lhs > rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_time_vector(grn_ts_time_vector lhs, grn_ts_time_vector rhs)
+{
+ GRN_TS_OP_GREATER_VECTOR(time)
+}
+
+/* grn_ts_op_greater_text_vector() returns lhs > rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_text_vector(grn_ts_text_vector lhs, grn_ts_text_vector rhs)
+{
+ GRN_TS_OP_GREATER_VECTOR(text)
+}
+#undef GRN_TS_OP_GREATER_VECTOR
+
+/* grn_ts_op_greater_equal_int() returns lhs >= rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_equal_int(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs >= rhs;
+}
+
+/* grn_ts_op_greater_equal_float() returns lhs >= rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_equal_float(grn_ts_float lhs, grn_ts_float rhs)
+{
+ return lhs >= rhs;
+}
+
+/* grn_ts_op_greater_equal_time() returns lhs >= rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_equal_time(grn_ts_time lhs, grn_ts_time rhs)
+{
+ return lhs >= rhs;
+}
+
+/* grn_ts_op_greater_equal_text() returns lhs >= rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_equal_text(grn_ts_text lhs, grn_ts_text rhs)
+{
+ size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
+ int cmp = memcmp(lhs.ptr, rhs.ptr, min_size);
+ return cmp ? (cmp > 0) : (lhs.size >= rhs.size);
+}
+
+#define GRN_TS_OP_GREATER_EQUAL_VECTOR(kind)\
+ size_t i, min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;\
+ for (i = 0; i < min_size; i++) {\
+ if (grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
+ if (grn_ts_op_greater_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
+ return GRN_TRUE;\
+ }\
+ }\
+ }\
+ return lhs.size >= rhs.size;
+/* grn_ts_op_greater_equal_int_vector() returns lhs >= rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_equal_int_vector(grn_ts_int_vector lhs,
+ grn_ts_int_vector rhs)
+{
+ GRN_TS_OP_GREATER_EQUAL_VECTOR(int)
+}
+
+/* grn_ts_op_greater_equal_float_vector() returns lhs >= rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_equal_float_vector(grn_ts_float_vector lhs,
+ grn_ts_float_vector rhs)
+{
+ GRN_TS_OP_GREATER_EQUAL_VECTOR(float)
+}
+
+/* grn_ts_op_greater_equal_time_vector() returns lhs >= rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_equal_time_vector(grn_ts_time_vector lhs,
+ grn_ts_time_vector rhs)
+{
+ GRN_TS_OP_GREATER_EQUAL_VECTOR(time)
+}
+
+/* grn_ts_op_greater_equal_text_vector() returns lhs >= rhs. */
+inline static grn_ts_bool
+grn_ts_op_greater_equal_text_vector(grn_ts_text_vector lhs,
+ grn_ts_text_vector rhs)
+{
+ GRN_TS_OP_GREATER_EQUAL_VECTOR(text)
+}
+#undef GRN_TS_OP_GREATER_EQUAL_VECTOR
+
+/* grn_ts_op_shift_arithmetic_left() returns lhs << rhs. */
+inline static grn_ts_int
+grn_ts_op_shift_arithmetic_left(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs << rhs;
+}
+
+/* grn_ts_op_shift_arithmetic_right() returns lhs << rhs. */
+inline static grn_ts_int
+grn_ts_op_shift_arithmetic_right(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs >> rhs;
+}
+
+/* grn_ts_op_shift_logical_left() returns lhs << rhs. */
+inline static grn_ts_int
+grn_ts_op_shift_logical_left(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return lhs << rhs;
+}
+
+/* grn_ts_op_shift_logical_right() returns lhs << rhs. */
+inline static grn_ts_int
+grn_ts_op_shift_logical_right(grn_ts_int lhs, grn_ts_int rhs)
+{
+ return (uint64_t)lhs >> rhs;
+}
+
+inline static grn_rc
+grn_ts_op_plus_int_int(grn_ctx *ctx, grn_ts_int lhs, grn_ts_int rhs,
+ grn_ts_int *out)
+{
+ *out = lhs + rhs;
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_plus_float_float(grn_ctx *ctx, grn_ts_float lhs, grn_ts_float rhs,
+ grn_ts_float *out)
+{
+ *out = lhs + rhs;
+ if (!grn_ts_float_is_valid(*out)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "%g + %g = %g", lhs, rhs, *out);
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_plus_time_int(grn_ctx *ctx, grn_ts_time lhs, grn_ts_int rhs,
+ grn_ts_time *out)
+{
+ *out = lhs + (rhs * 1000000);
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_plus_time_float(grn_ctx *ctx, grn_ts_time lhs, grn_ts_float rhs,
+ grn_ts_time *out)
+{
+ *out = (grn_ts_time)(lhs + (rhs * 1000000.0));
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_minus_int_int(grn_ctx *ctx, grn_ts_int lhs, grn_ts_int rhs,
+ grn_ts_int *out)
+{
+ *out = lhs - rhs;
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_minus_float_float(grn_ctx *ctx, grn_ts_float lhs, grn_ts_float rhs,
+ grn_ts_float *out)
+{
+ *out = lhs - rhs;
+ if (!grn_ts_float_is_valid(*out)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "%g - %g = %g", lhs, rhs, *out);
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_minus_time_time(grn_ctx *ctx, grn_ts_time lhs, grn_ts_time rhs,
+ grn_ts_float *out)
+{
+ *out = (lhs - rhs) * 0.000001;
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_minus_time_int(grn_ctx *ctx, grn_ts_time lhs, grn_ts_int rhs,
+ grn_ts_time *out)
+{
+ *out = lhs - (rhs * 1000000);
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_minus_time_float(grn_ctx *ctx, grn_ts_time lhs, grn_ts_float rhs,
+ grn_ts_time *out)
+{
+ *out = lhs - (grn_ts_int)(rhs * 1000000.0);
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_multiplication_int_int(grn_ctx *ctx, grn_ts_int lhs, grn_ts_int rhs,
+ grn_ts_int *out)
+{
+ *out = lhs * rhs;
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_multiplication_float_float(grn_ctx *ctx, grn_ts_float lhs,
+ grn_ts_float rhs, grn_ts_float *out)
+{
+ *out = lhs * rhs;
+ if (!grn_ts_float_is_valid(*out)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "%g * %g = %g", lhs, rhs, *out);
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_division_int_int(grn_ctx *ctx, grn_ts_int lhs, grn_ts_int rhs,
+ grn_ts_int *out)
+{
+ if (!rhs) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
+ "%" GRN_FMT_INT64D " / %" GRN_FMT_INT64D
+ " causes division by zero",
+ lhs, rhs);
+ }
+ *out = (rhs != -1) ? (lhs / rhs) : -lhs;
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_division_float_float(grn_ctx *ctx, grn_ts_float lhs,
+ grn_ts_float rhs, grn_ts_float *out)
+{
+ *out = lhs / rhs;
+ if (!grn_ts_float_is_valid(*out)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "%g / %g = %g", lhs, rhs, *out);
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_modulus_int_int(grn_ctx *ctx, grn_ts_int lhs, grn_ts_int rhs,
+ grn_ts_int *out)
+{
+ if (!rhs) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
+ "%" GRN_FMT_INT64D " %% %" GRN_FMT_INT64D
+ " causes division by zero",
+ lhs, rhs);
+ }
+ *out = (rhs != -1) ? (lhs % rhs) : -lhs;
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_ts_op_modulus_float_float(grn_ctx *ctx, grn_ts_float lhs, grn_ts_float rhs,
+ grn_ts_float *out)
+{
+ *out = fmod(lhs, rhs);
+ if (!grn_ts_float_is_valid(*out)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "%g %% %g = %g", lhs, rhs, *out);
+ }
+ return GRN_SUCCESS;
+}
+
+static grn_ts_bool
+grn_ts_op_match(grn_ts_text lhs, grn_ts_text rhs)
+{
+ const char *lhs_ptr, *lhs_ptr_last;
+ if (lhs.size < rhs.size) {
+ return GRN_FALSE;
+ }
+ lhs_ptr_last = lhs.ptr + lhs.size - rhs.size;
+ for (lhs_ptr = lhs.ptr; lhs_ptr <= lhs_ptr_last; lhs_ptr++) {
+ size_t i;
+ for (i = 0; i < rhs.size; i++) {
+ if (lhs_ptr[i] != rhs.ptr[i]) {
+ break;
+ }
+ }
+ if (i == rhs.size) {
+ return GRN_TRUE;
+ }
+ }
+ return GRN_FALSE;
+}
+
+static grn_ts_bool
+grn_ts_op_prefix_match(grn_ts_text lhs, grn_ts_text rhs)
+{
+ size_t i;
+ if (lhs.size < rhs.size) {
+ return GRN_FALSE;
+ }
+ for (i = 0; i < rhs.size; i++) {
+ if (lhs.ptr[i] != rhs.ptr[i]) {
+ return GRN_FALSE;
+ }
+ }
+ return GRN_TRUE;
+}
+
+static grn_ts_bool
+grn_ts_op_suffix_match(grn_ts_text lhs, grn_ts_text rhs)
+{
+ size_t i;
+ const char *lhs_ptr;
+ if (lhs.size < rhs.size) {
+ return GRN_FALSE;
+ }
+ lhs_ptr = lhs.ptr + lhs.size - rhs.size;
+ for (i = 0; i < rhs.size; i++) {
+ if (lhs_ptr[i] != rhs.ptr[i]) {
+ return GRN_FALSE;
+ }
+ }
+ return GRN_TRUE;
+}
+
+/*-------------------------------------------------------------
+ * Groonga objects.
+ */
+
+#define GRN_TS_TABLE_GET_KEY(type)\
+ uint32_t key_size;\
+ const void *key_ptr = _grn_ ## type ## _key(ctx, type, id, &key_size);\
+ if (!key_ptr) {\
+ GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "_grn_" #type "_key failed: %u", id);\
+ }\
+/* grn_ts_hash_get_bool_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_bool_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_bool *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const grn_ts_bool *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_int8_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_int8_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const int8_t *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_int16_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_int16_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const int16_t *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_int32_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_int32_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const int32_t *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_int64_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_int64_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const int64_t *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_uint8_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_uint8_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const uint8_t *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_uint16_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_uint16_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const uint16_t *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_uint32_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_uint32_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const uint32_t *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_uint64_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_uint64_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = (grn_ts_int)*(const uint64_t *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_float_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_float_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_float *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const grn_ts_float *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_time_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_time_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_time *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const grn_ts_time *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_geo_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_geo_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_geo *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ *key = *(const grn_ts_geo *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_text_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_text_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_text *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ key->ptr = key_ptr;
+ key->size = key_size;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_hash_get_ref_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_hash_get_ref_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
+ grn_ts_ref *key)
+{
+ GRN_TS_TABLE_GET_KEY(hash)
+ key->id = *(const grn_ts_id *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_bool_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_bool_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_bool *key)
+{
+ GRN_TS_TABLE_GET_KEY(pat)
+ *key = *(const grn_ts_bool *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_int8_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_int8_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_int *key)
+{
+ int8_t tmp;
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntohi(&tmp, key_ptr, sizeof(tmp));
+ *key = tmp;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_int16_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_int16_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_int *key)
+{
+ int16_t tmp;
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntohi(&tmp, key_ptr, sizeof(tmp));
+ *key = tmp;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_int32_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_int32_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_int *key)
+{
+ int32_t tmp;
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntohi(&tmp, key_ptr, sizeof(tmp));
+ *key = tmp;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_int64_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_int64_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntohi(key, key_ptr, sizeof(grn_ts_int));
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_uint8_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_uint8_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(pat)
+ *key = *(const uint8_t *)key_ptr;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_uint16_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_uint16_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_int *key)
+{
+ uint16_t tmp;
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntoh(&tmp, key_ptr, sizeof(tmp));
+ *key = tmp;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_uint32_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_uint32_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_int *key)
+{
+ uint32_t tmp;
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntoh(&tmp, key_ptr, sizeof(tmp));
+ *key = tmp;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_uint64_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_uint64_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_int *key)
+{
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntoh(key, key_ptr, sizeof(grn_ts_int));
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_float_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_float_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_float *key)
+{
+ int64_t tmp;
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntoh(&tmp, key_ptr, sizeof(tmp));
+ tmp ^= (((tmp ^ ((int64_t)1 << 63)) >> 63) | ((int64_t)1 << 63));
+ *(int64_t *)key = tmp;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_time_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_time_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_time *key)
+{
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntohi(key, key_ptr, sizeof(grn_ts_time));
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_geo_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_geo_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_geo *key)
+{
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntog(key, key_ptr, sizeof(grn_ts_geo));
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_text_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_text_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_text *key)
+{
+ GRN_TS_TABLE_GET_KEY(pat)
+ key->ptr = key_ptr;
+ key->size = key_size;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_pat_get_ref_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_pat_get_ref_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
+ grn_ts_ref *key)
+{
+ GRN_TS_TABLE_GET_KEY(pat)
+ grn_ntoh(&key->id, key_ptr, sizeof(key->id));
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_dat_get_text_key() gets a reference to a key (_key). */
+static grn_rc
+grn_ts_dat_get_text_key(grn_ctx *ctx, grn_dat *dat, grn_ts_id id,
+ grn_ts_text *key)
+{
+ GRN_TS_TABLE_GET_KEY(dat)
+ key->ptr = key_ptr;
+ key->size = key_size;
+ return GRN_SUCCESS;
+}
+#undef GRN_TS_TABLE_GET_KEY
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_id_node.
+ */
+
+typedef struct {
+ GRN_TS_EXPR_NODE_COMMON_MEMBERS
+} grn_ts_expr_id_node;
+
+/* grn_ts_expr_id_node_init() initializes a node. */
+static void
+grn_ts_expr_id_node_init(grn_ctx *ctx, grn_ts_expr_id_node *node)
+{
+ memset(node, 0, sizeof(*node));
+ node->type = GRN_TS_EXPR_ID_NODE;
+ node->data_kind = GRN_TS_INT;
+ node->data_type = GRN_DB_UINT32;
+}
+
+/* grn_ts_expr_id_node_fin() finalizes a node. */
+static void
+grn_ts_expr_id_node_fin(grn_ctx *ctx, grn_ts_expr_id_node *node)
+{
+ /* Nothing to do. */
+}
+
+grn_rc
+grn_ts_expr_id_node_open(grn_ctx *ctx, grn_ts_expr_node **node)
+{
+ grn_ts_expr_id_node *new_node = GRN_MALLOCN(grn_ts_expr_id_node, 1);
+ if (!new_node) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_expr_id_node));
+ }
+ grn_ts_expr_id_node_init(ctx, new_node);
+ *node = (grn_ts_expr_node *)new_node;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_id_node_close() destroys a node. */
+static void
+grn_ts_expr_id_node_close(grn_ctx *ctx, grn_ts_expr_id_node *node)
+{
+ grn_ts_expr_id_node_fin(ctx, node);
+ GRN_FREE(node);
+}
+
+/* grn_ts_expr_id_node_evaluate() outputs IDs. */
+static grn_rc
+grn_ts_expr_id_node_evaluate(grn_ctx *ctx, grn_ts_expr_id_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ size_t i;
+ grn_ts_int *out_ptr = (grn_ts_int *)out;
+ for (i = 0; i < n_in; i++) {
+ out_ptr[i] = (grn_ts_int)in[i].id;
+ }
+ return GRN_SUCCESS;
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_score_node.
+ */
+
+typedef struct {
+ GRN_TS_EXPR_NODE_COMMON_MEMBERS
+} grn_ts_expr_score_node;
+
+/* grn_ts_expr_score_node_init() initializes a node. */
+static void
+grn_ts_expr_score_node_init(grn_ctx *ctx, grn_ts_expr_score_node *node)
+{
+ memset(node, 0, sizeof(*node));
+ node->type = GRN_TS_EXPR_SCORE_NODE;
+ node->data_kind = GRN_TS_FLOAT;
+ node->data_type = GRN_DB_FLOAT;
+}
+
+/* grn_ts_expr_score_node_fin() finalizes a node. */
+static void
+grn_ts_expr_score_node_fin(grn_ctx *ctx, grn_ts_expr_score_node *node)
+{
+ /* Nothing to do. */
+}
+
+grn_rc
+grn_ts_expr_score_node_open(grn_ctx *ctx, grn_ts_expr_node **node)
+{
+ grn_ts_expr_score_node *new_node = GRN_MALLOCN(grn_ts_expr_score_node, 1);
+ if (!new_node) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_expr_score_node));
+ }
+ grn_ts_expr_score_node_init(ctx, new_node);
+ *node = (grn_ts_expr_node *)new_node;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_score_node_close() destroys a node. */
+static void
+grn_ts_expr_score_node_close(grn_ctx *ctx, grn_ts_expr_score_node *node)
+{
+ grn_ts_expr_score_node_fin(ctx, node);
+ GRN_FREE(node);
+}
+
+/* grn_ts_expr_score_node_evaluate() outputs scores. */
+static grn_rc
+grn_ts_expr_score_node_evaluate(grn_ctx *ctx, grn_ts_expr_score_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ size_t i;
+ grn_ts_float *out_ptr = (grn_ts_float *)out;
+ for (i = 0; i < n_in; i++) {
+ out_ptr[i] = (grn_ts_float)in[i].score;
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_score_node_adjust() does nothing. */
+static grn_rc
+grn_ts_expr_score_node_adjust(grn_ctx *ctx, grn_ts_expr_score_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ /* Nothing to do. */
+ return GRN_SUCCESS;
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_key_node.
+ */
+
+typedef struct {
+ GRN_TS_EXPR_NODE_COMMON_MEMBERS
+ grn_obj *table;
+ grn_ts_buf buf;
+} grn_ts_expr_key_node;
+
+/* grn_ts_expr_key_node_init() initializes a node. */
+static void
+grn_ts_expr_key_node_init(grn_ctx *ctx, grn_ts_expr_key_node *node)
+{
+ memset(node, 0, sizeof(*node));
+ node->type = GRN_TS_EXPR_KEY_NODE;
+ node->table = NULL;
+ grn_ts_buf_init(ctx, &node->buf);
+}
+
+/* grn_ts_expr_key_node_fin() finalizes a node. */
+static void
+grn_ts_expr_key_node_fin(grn_ctx *ctx, grn_ts_expr_key_node *node)
+{
+ grn_ts_buf_fin(ctx, &node->buf);
+ if (node->table) {
+ grn_obj_unlink(ctx, node->table);
+ }
+}
+
+grn_rc
+grn_ts_expr_key_node_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_expr_node **node)
+{
+ grn_rc rc;
+ grn_ts_expr_key_node *new_node;
+ if (!grn_ts_table_has_key(ctx, table)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "the table has no _key");
+ }
+ new_node = GRN_MALLOCN(grn_ts_expr_key_node, 1);
+ if (!new_node) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_expr_key_node));
+ }
+ grn_ts_expr_key_node_init(ctx, new_node);
+ rc = grn_ts_obj_increment_ref_count(ctx, table);
+ if (rc != GRN_SUCCESS) {
+ grn_ts_expr_key_node_fin(ctx, new_node);
+ GRN_FREE(new_node);
+ return rc;
+ }
+ new_node->data_kind = grn_ts_data_type_to_kind(table->header.domain);
+ new_node->data_type = table->header.domain;
+ new_node->table = table;
+ *node = (grn_ts_expr_node *)new_node;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_key_node_close() destroys a node. */
+static void
+grn_ts_expr_key_node_close(grn_ctx *ctx, grn_ts_expr_key_node *node)
+{
+ grn_ts_expr_key_node_fin(ctx, node);
+ GRN_FREE(node);
+}
+
+#define GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(table, KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
+ for (i = 0; i < n_in; i++) {\
+ rc = grn_ts_ ## table ## _get_ ## kind ## _key(ctx, table, in[i].id,\
+ &out_ptr[i]);\
+ if (rc != GRN_SUCCESS) {\
+ out_ptr[i] = grn_ts_ ## kind ## _zero();\
+ }\
+ }\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(table, TYPE, type)\
+ case GRN_DB_ ## TYPE: {\
+ grn_ts_int *out_ptr = (grn_ts_int *)out;\
+ for (i = 0; i < n_in; i++) {\
+ rc = grn_ts_ ## table ## _get_ ## type ## _key(ctx, table, in[i].id,\
+ &out_ptr[i]);\
+ if (rc != GRN_SUCCESS) {\
+ out_ptr[i] = grn_ts_int_zero();\
+ }\
+ }\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_EXPR_KEY_NODE_EVALUATE_TEXT_CASE(table)\
+ case GRN_TS_TEXT: {\
+ char *buf_ptr;\
+ grn_ts_text *out_ptr = (grn_ts_text *)out;\
+ node->buf.pos = 0;\
+ for (i = 0; i < n_in; i++) {\
+ grn_ts_text key;\
+ rc = grn_ts_ ## table ## _get_text_key(ctx, table, in[i].id, &key);\
+ if (rc != GRN_SUCCESS) {\
+ key = grn_ts_text_zero();\
+ }\
+ rc = grn_ts_buf_write(ctx, &node->buf, key.ptr, key.size);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ out_ptr[i].size = key.size;\
+ }\
+ buf_ptr = (char *)node->buf.ptr;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i].ptr = buf_ptr;\
+ buf_ptr += out_ptr[i].size;\
+ }\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_EXPR_KEY_NODE_EVALUATE_REF_CASE(table)\
+ case GRN_TS_REF: {\
+ grn_ts_ref *out_ptr = (grn_ts_ref *)out;\
+ for (i = 0; i < n_in; i++) {\
+ rc = grn_ts_ ## table ## _get_ref_key(ctx, table, in[i].id,\
+ &out_ptr[i]);\
+ if (rc != GRN_SUCCESS) {\
+ out_ptr[i] = grn_ts_ref_zero();\
+ }\
+ out_ptr[i].score = in[i].score;\
+ }\
+ return GRN_SUCCESS;\
+ }
+/* grn_ts_expr_key_node_evaluate() outputs keys. */
+static grn_rc
+grn_ts_expr_key_node_evaluate(grn_ctx *ctx, grn_ts_expr_key_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ size_t i;
+ grn_rc rc;
+ switch (node->table->header.type) {
+ case GRN_TABLE_HASH_KEY: {
+ grn_hash *hash = (grn_hash *)node->table;
+ switch (node->data_kind) {
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(hash, BOOL, bool)
+ case GRN_TS_INT: {
+ switch (node->data_type) {
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, INT8, int8)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, INT16, int16)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, INT32, int32)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, INT64, int64)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, UINT8, uint8)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, UINT16, uint16)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, UINT32, uint32)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, UINT64, uint64)
+ }
+ }
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(hash, FLOAT, float)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(hash, TIME, time)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_TEXT_CASE(hash)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(hash, GEO, geo)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_REF_CASE(hash)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+ }
+ case GRN_TABLE_PAT_KEY: {
+ grn_pat *pat = (grn_pat *)node->table;
+ switch (node->data_kind) {
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(pat, BOOL, bool)
+ case GRN_TS_INT: {
+ switch (node->data_type) {
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, INT8, int8)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, INT16, int16)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, INT32, int32)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, INT64, int64)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, UINT8, uint8)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, UINT16, uint16)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, UINT32, uint32)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, UINT64, uint64)
+ }
+ }
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(pat, FLOAT, float)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(pat, TIME, time)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_TEXT_CASE(pat)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(pat, GEO, geo)
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_REF_CASE(pat)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+ }
+ case GRN_TABLE_DAT_KEY: {
+ grn_dat *dat = (grn_dat *)node->table;
+ switch (node->data_kind) {
+ GRN_TS_EXPR_KEY_NODE_EVALUATE_TEXT_CASE(dat)
+ /* GRN_TABLE_DAT_KEY supports only Text. */
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+ }
+ /* GRN_TABLE_NO_KEY doesn't support _key. */
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid table type: %d",
+ node->table->header.type);
+ }
+ }
+}
+#undef GRN_TS_EXPR_KEY_NODE_EVALUATE_REF_CASE
+#undef GRN_TS_EXPR_KEY_NODE_EVALUATE_TEXT_CASE
+#undef GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE
+#undef GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE
+
+/* grn_ts_expr_key_node_filter() filters records. */
+static grn_rc
+grn_ts_expr_key_node_filter(grn_ctx *ctx, grn_ts_expr_key_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ size_t i, count;
+ grn_ts_bool key;
+ switch (node->table->header.type) {
+ case GRN_TABLE_HASH_KEY: {
+ grn_hash *hash = (grn_hash *)node->table;
+ for (i = 0, count = 0; i < n_in; i++) {
+ grn_rc rc = grn_ts_hash_get_bool_key(ctx, hash, in[i].id, &key);
+ if (rc != GRN_SUCCESS) {
+ key = grn_ts_bool_zero();
+ }
+ if (key) {
+ out[count++] = in[i];
+ }
+ }
+ *n_out = count;
+ return GRN_SUCCESS;
+ }
+ case GRN_TABLE_PAT_KEY: {
+ grn_pat *pat = (grn_pat *)node->table;
+ for (i = 0, count = 0; i < n_in; i++) {
+ grn_rc rc = grn_ts_pat_get_bool_key(ctx, pat, in[i].id, &key);
+ if (rc != GRN_SUCCESS) {
+ key = grn_ts_bool_zero();
+ }
+ if (key) {
+ out[count++] = in[i];
+ }
+ }
+ *n_out = count;
+ return GRN_SUCCESS;
+ }
+ /* GRN_TABLE_DAT_KEY and GRN_TABLE_NO_KEY don't support a Bool key. */
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid table type: %d",
+ node->table->header.type);
+ }
+ }
+}
+
+/* grn_ts_expr_key_node_adjust() updates scores. */
+static grn_rc
+grn_ts_expr_key_node_adjust(grn_ctx *ctx, grn_ts_expr_key_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ size_t i;
+ grn_ts_float key;
+ switch (node->table->header.type) {
+ case GRN_TABLE_HASH_KEY: {
+ grn_hash *hash = (grn_hash *)node->table;
+ for (i = 0; i < n_io; i++) {
+ grn_rc rc = grn_ts_hash_get_float_key(ctx, hash, io[i].id, &key);
+ if (rc != GRN_SUCCESS) {
+ key = grn_ts_float_zero();
+ }
+ io[i].score = (grn_ts_score)key;
+ }
+ return GRN_SUCCESS;
+ }
+ case GRN_TABLE_PAT_KEY: {
+ grn_pat *pat = (grn_pat *)node->table;
+ for (i = 0; i < n_io; i++) {
+ grn_rc rc = grn_ts_pat_get_float_key(ctx, pat, io[i].id, &key);
+ if (rc != GRN_SUCCESS) {
+ key = grn_ts_float_zero();
+ }
+ io[i].score = (grn_ts_score)key;
+ }
+ return GRN_SUCCESS;
+ }
+ /* GRN_TABLE_DAT_KEY and GRN_TABLE_NO_KEY don't support a Float key. */
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid table type: %d",
+ node->table->header.type);
+ }
+ }
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_value_node.
+ */
+
+typedef struct {
+ GRN_TS_EXPR_NODE_COMMON_MEMBERS
+ grn_obj *table;
+} grn_ts_expr_value_node;
+
+/* grn_ts_expr_value_node_init() initializes a node. */
+static void
+grn_ts_expr_value_node_init(grn_ctx *ctx, grn_ts_expr_value_node *node)
+{
+ memset(node, 0, sizeof(*node));
+ node->type = GRN_TS_EXPR_VALUE_NODE;
+ node->table = NULL;
+}
+
+/* grn_ts_expr_value_node_fin() finalizes a node. */
+static void
+grn_ts_expr_value_node_fin(grn_ctx *ctx, grn_ts_expr_value_node *node)
+{
+ if (node->table) {
+ grn_obj_unlink(ctx, node->table);
+ }
+}
+
+grn_rc
+grn_ts_expr_value_node_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_expr_node **node)
+{
+ grn_rc rc;
+ grn_ts_expr_value_node *new_node;
+ if (!grn_ts_table_has_value(ctx, table)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "table has no _value");
+ }
+ new_node = GRN_MALLOCN(grn_ts_expr_value_node, 1);
+ if (!new_node) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_expr_value_node));
+ }
+ grn_ts_expr_value_node_init(ctx, new_node);
+ rc = grn_ts_obj_increment_ref_count(ctx, table);
+ if (rc != GRN_SUCCESS) {
+ GRN_FREE(new_node);
+ return rc;
+ }
+ new_node->data_kind = grn_ts_data_type_to_kind(DB_OBJ(table)->range);
+ new_node->data_type = DB_OBJ(table)->range;
+ new_node->table = table;
+ *node = (grn_ts_expr_node *)new_node;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_value_node_close() destroys a node. */
+static void
+grn_ts_expr_value_node_close(grn_ctx *ctx, grn_ts_expr_value_node *node)
+{
+ grn_ts_expr_value_node_fin(ctx, node);
+ GRN_FREE(node);
+}
+
+#define GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE(KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ size_t i;\
+ grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
+ for (i = 0; i < n_in; i++) {\
+ const void *ptr = grn_ts_table_get_value(ctx, node->table, in[i].id);\
+ if (ptr) {\
+ out_ptr[i] = *(const grn_ts_ ## kind *)ptr;\
+ } else {\
+ out_ptr[i] = grn_ts_ ## kind ## _zero();\
+ }\
+ }\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(TYPE, type)\
+ case GRN_DB_ ## TYPE: {\
+ size_t i;\
+ grn_ts_int *out_ptr = (grn_ts_int *)out;\
+ for (i = 0; i < n_in; i++) {\
+ const void *ptr = grn_ts_table_get_value(ctx, node->table, in[i].id);\
+ if (ptr) {\
+ out_ptr[i] = (grn_ts_int)*(const type ## _t *)ptr;\
+ } else {\
+ out_ptr[i] = grn_ts_int_zero();\
+ }\
+ }\
+ return GRN_SUCCESS;\
+ }
+/* grn_ts_expr_value_node_evaluate() outputs values. */
+static grn_rc
+grn_ts_expr_value_node_evaluate(grn_ctx *ctx, grn_ts_expr_value_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ switch (node->data_kind) {
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE(BOOL, bool)
+ case GRN_TS_INT: {
+ switch (node->data_type) {
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(INT8, int8)
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(INT16, int16)
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(INT32, int32)
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(INT64, int64)
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(UINT8, uint8)
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(UINT16, uint16)
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(UINT32, uint32)
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(UINT64, uint64)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data type: %d",
+ node->data_type);
+ }
+ }
+ }
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE(FLOAT, float)
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE(TIME, time)
+ GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE(GEO, geo)
+ case GRN_TS_REF: {
+ size_t i;
+ grn_ts_ref *out_ptr = (grn_ts_ref *)out;
+ for (i = 0; i < n_in; i++) {
+ const void *ptr = grn_ts_table_get_value(ctx, node->table, in[i].id);
+ if (ptr) {
+ out_ptr[i].id = *(const grn_ts_id *)ptr;
+ out_ptr[i].score = in[i].score;
+ } else {
+ out_ptr[i] = grn_ts_ref_zero();
+ }
+ }
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+}
+#undef GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE
+#undef GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE
+
+/* grn_ts_expr_value_node_filter() filters records. */
+static grn_rc
+grn_ts_expr_value_node_filter(grn_ctx *ctx, grn_ts_expr_value_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ size_t i, count = 0;
+ for (i = 0; i < n_in; i++) {
+ const void *ptr = grn_ts_table_get_value(ctx, node->table, in[i].id);
+ if (ptr && *(const grn_ts_bool *)ptr) {
+ out[count++] = in[i];
+ }
+ }
+ *n_out = count;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_value_node_adjust() updates scores. */
+static grn_rc
+grn_ts_expr_value_node_adjust(grn_ctx *ctx, grn_ts_expr_value_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ size_t i;
+ for (i = 0; i < n_io; i++) {
+ const void *ptr = grn_ts_table_get_value(ctx, node->table, io[i].id);
+ if (ptr) {
+ io[i].score = (grn_ts_score)*(const grn_ts_float *)ptr;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_const_node.
+ */
+
+typedef struct {
+ GRN_TS_EXPR_NODE_COMMON_MEMBERS
+ grn_ts_any content;
+ grn_ts_buf text_buf;
+ grn_ts_buf vector_buf;
+} grn_ts_expr_const_node;
+
+/* grn_ts_expr_const_node_init() initializes a node. */
+static void
+grn_ts_expr_const_node_init(grn_ctx *ctx, grn_ts_expr_const_node *node)
+{
+ memset(node, 0, sizeof(*node));
+ node->type = GRN_TS_EXPR_CONST_NODE;
+ grn_ts_buf_init(ctx, &node->text_buf);
+ grn_ts_buf_init(ctx, &node->vector_buf);
+}
+
+/* grn_ts_expr_const_node_fin() finalizes a node. */
+static void
+grn_ts_expr_const_node_fin(grn_ctx *ctx, grn_ts_expr_const_node *node)
+{
+ grn_ts_buf_fin(ctx, &node->vector_buf);
+ grn_ts_buf_fin(ctx, &node->text_buf);
+}
+
+#define GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ node->content.as_ ## kind = value.as_ ## kind;\
+ return GRN_SUCCESS;\
+ }
+/* grn_ts_expr_const_node_set_scalar() sets a scalar value. */
+static grn_rc
+grn_ts_expr_const_node_set_scalar(grn_ctx *ctx, grn_ts_expr_const_node *node,
+ grn_ts_any value)
+{
+ switch (node->data_kind) {
+ GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(BOOL, bool)
+ GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(INT, int)
+ GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(FLOAT, float)
+ GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(TIME, time)
+ case GRN_TS_TEXT: {
+ grn_rc rc = grn_ts_buf_write(ctx, &node->text_buf,
+ value.as_text.ptr, value.as_text.size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ node->content.as_text.ptr = (const char *)node->text_buf.ptr;
+ node->content.as_text.size = value.as_text.size;
+ return GRN_SUCCESS;
+ }
+ GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(GEO, geo)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+}
+#undef GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE
+
+#define GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(KIND, kind)\
+ case GRN_TS_ ## KIND ## _VECTOR: {\
+ grn_rc rc;\
+ size_t n_bytes;\
+ const grn_ts_ ## kind *buf_ptr;\
+ grn_ts_ ## kind ## _vector vector;\
+ vector = value.as_ ## kind ## _vector;\
+ n_bytes = sizeof(grn_ts_ ## kind) * vector.size;\
+ rc = grn_ts_buf_write(ctx, &node->vector_buf, vector.ptr, n_bytes);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ buf_ptr = (const grn_ts_ ## kind *)node->vector_buf.ptr;\
+ node->content.as_ ## kind ## _vector.ptr = buf_ptr;\
+ node->content.as_ ## kind ## _vector.size = vector.size;\
+ return GRN_SUCCESS;\
+ }
+/* grn_ts_expr_const_node_set_vector() sets a vector value. */
+static grn_rc
+grn_ts_expr_const_node_set_vector(grn_ctx *ctx, grn_ts_expr_const_node *node,
+ grn_ts_any value)
+{
+ switch (node->data_kind) {
+ GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(BOOL, bool)
+ GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(INT, int)
+ GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(FLOAT, float)
+ GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(TIME, time)
+ case GRN_TS_TEXT_VECTOR: {
+ grn_rc rc;
+ size_t i, n_bytes, offset, total_size;
+ grn_ts_text_vector vector = value.as_text_vector;
+ grn_ts_text *vector_buf;
+ char *text_buf;
+ n_bytes = sizeof(grn_ts_text) * vector.size;
+ rc = grn_ts_buf_resize(ctx, &node->vector_buf, n_bytes);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ vector_buf = (grn_ts_text *)node->vector_buf.ptr;
+ total_size = 0;
+ for (i = 0; i < vector.size; i++) {
+ total_size += vector.ptr[i].size;
+ }
+ rc = grn_ts_buf_resize(ctx, &node->text_buf, total_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ text_buf = (char *)node->text_buf.ptr;
+ offset = 0;
+ for (i = 0; i < vector.size; i++) {
+ grn_memcpy(text_buf + offset, vector.ptr[i].ptr, vector.ptr[i].size);
+ vector_buf[i].ptr = text_buf + offset;
+ vector_buf[i].size = vector.ptr[i].size;
+ offset += vector.ptr[i].size;
+ }
+ node->content.as_text_vector.ptr = vector_buf;
+ node->content.as_text_vector.size = vector.size;
+ return GRN_SUCCESS;
+ }
+ GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(GEO, geo)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+}
+#undef GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE
+
+#define GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ if (!grn_ts_ ## kind ## _is_valid(value.as_ ## kind)) {\
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");\
+ }\
+ return GRN_SUCCESS;\
+ }
+static grn_rc
+grn_ts_expr_const_node_check_value(grn_ctx *ctx, grn_ts_data_kind kind,
+ grn_ts_any value)
+{
+ switch (kind) {
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(BOOL, bool)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(INT, int)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(FLOAT, float)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(TIME, time)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(TEXT, text)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(GEO, geo)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(BOOL_VECTOR, bool_vector)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(INT_VECTOR, int_vector)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(FLOAT_VECTOR, float_vector)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(TIME_VECTOR, time_vector)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(TEXT_VECTOR, text_vector)
+ GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(GEO_VECTOR, geo_vector)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ }
+}
+#undef GRN_TS_EXPR_CONST_NODE_CHECK_VALUE
+
+grn_rc
+grn_ts_expr_const_node_open(grn_ctx *ctx, grn_ts_data_kind data_kind,
+ grn_ts_data_type data_type,
+ grn_ts_any value, grn_ts_expr_node **node)
+{
+ grn_rc rc = grn_ts_expr_const_node_check_value(ctx, data_kind, value);
+ grn_ts_expr_const_node *new_node;
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ new_node = GRN_MALLOCN(grn_ts_expr_const_node, 1);
+ if (!new_node) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_expr_const_node));
+ }
+ grn_ts_expr_const_node_init(ctx, new_node);
+ new_node->data_kind = data_kind;
+ if (data_type != GRN_DB_VOID) {
+ new_node->data_type = data_type;
+ } else {
+ new_node->data_type = grn_ts_data_kind_to_type(data_kind);
+ }
+ if (data_kind & GRN_TS_VECTOR_FLAG) {
+ rc = grn_ts_expr_const_node_set_vector(ctx, new_node, value);
+ } else {
+ rc = grn_ts_expr_const_node_set_scalar(ctx, new_node, value);
+ }
+ if (rc != GRN_SUCCESS) {
+ grn_ts_expr_const_node_fin(ctx, new_node);
+ GRN_FREE(new_node);
+ return rc;
+ }
+ *node = (grn_ts_expr_node *)new_node;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_const_node_close() destroys a node. */
+static void
+grn_ts_expr_const_node_close(grn_ctx *ctx, grn_ts_expr_const_node *node)
+{
+ grn_ts_expr_const_node_fin(ctx, node);
+ GRN_FREE(node);
+}
+
+#define GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ size_t i;\
+ grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i] = node->content.as_ ## kind;\
+ }\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(KIND, kind)\
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(KIND ## _VECTOR, kind ## _vector)
+/* grn_ts_expr_const_node_evaluate() outputs the stored const. */
+static grn_rc
+grn_ts_expr_const_node_evaluate(grn_ctx *ctx, grn_ts_expr_const_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ switch (node->data_kind) {
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(BOOL, bool)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(INT, int)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(FLOAT, float)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(TIME, time)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(TEXT, text)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(GEO, geo)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(BOOL, bool)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(INT, int)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(FLOAT, float)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(TIME, time)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(TEXT, text)
+ GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(GEO, geo)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+}
+#undef GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE
+#undef GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE
+
+/* grn_ts_expr_const_node_filter() filters records. */
+static grn_rc
+grn_ts_expr_const_node_filter(grn_ctx *ctx, grn_ts_expr_const_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ if (node->content.as_bool) {
+ /* All the records pass through the filter. */
+ if (in != out) {
+ size_t i;
+ for (i = 0; i < n_in; i++) {
+ out[i] = in[i];
+ }
+ }
+ *n_out = n_in;
+ } else {
+ /* All the records are discarded. */
+ *n_out = 0;
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_const_node_adjust() updates scores. */
+static grn_rc
+grn_ts_expr_const_node_adjust(grn_ctx *ctx, grn_ts_expr_const_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ size_t i;
+ grn_ts_score score = (grn_ts_score)node->content.as_float;
+ for (i = 0; i < n_io; i++) {
+ io[i].score = score;
+ }
+ return GRN_SUCCESS;
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_column_node.
+ */
+
+typedef struct {
+ GRN_TS_EXPR_NODE_COMMON_MEMBERS
+ grn_obj *column;
+ grn_ts_buf buf;
+ grn_ts_buf body_buf;
+ grn_ja_reader *reader;
+} grn_ts_expr_column_node;
+
+/* grn_ts_expr_column_node_init() initializes a node. */
+static void
+grn_ts_expr_column_node_init(grn_ctx *ctx, grn_ts_expr_column_node *node)
+{
+ memset(node, 0, sizeof(*node));
+ node->type = GRN_TS_EXPR_COLUMN_NODE;
+ node->column = NULL;
+ grn_ts_buf_init(ctx, &node->buf);
+ grn_ts_buf_init(ctx, &node->body_buf);
+ node->reader = NULL;
+}
+
+/* grn_ts_expr_column_node_fin() finalizes a node. */
+static void
+grn_ts_expr_column_node_fin(grn_ctx *ctx, grn_ts_expr_column_node *node)
+{
+ if (node->reader) {
+ grn_ja_reader_close(ctx, node->reader);
+ }
+ grn_ts_buf_fin(ctx, &node->body_buf);
+ grn_ts_buf_fin(ctx, &node->buf);
+ if (node->column) {
+ grn_obj_unlink(ctx, node->column);
+ }
+}
+
+#define GRN_TS_EXPR_COLUMN_NODE_OPEN_CASE(TYPE)\
+ case GRN_DB_ ## TYPE: {\
+ GRN_ ## TYPE ## _INIT(&new_node->buf, GRN_OBJ_VECTOR);\
+ break;\
+ }
+grn_rc
+grn_ts_expr_column_node_open(grn_ctx *ctx, grn_obj *column,
+ grn_ts_expr_node **node)
+{
+ grn_rc rc;
+ grn_ts_expr_column_node *new_node = GRN_MALLOCN(grn_ts_expr_column_node, 1);
+ if (!new_node) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_expr_column_node));
+ }
+ grn_ts_expr_column_node_init(ctx, new_node);
+ new_node->data_kind = grn_ts_data_type_to_kind(DB_OBJ(column)->range);
+ if (column->header.type == GRN_COLUMN_VAR_SIZE) {
+ grn_obj_flags type = column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK;
+ if (type == GRN_OBJ_COLUMN_VECTOR) {
+ new_node->data_kind |= GRN_TS_VECTOR_FLAG;
+ }
+ }
+ new_node->data_type = DB_OBJ(column)->range;
+ rc = grn_ts_obj_increment_ref_count(ctx, column);
+ if (rc != GRN_SUCCESS) {
+ grn_ts_expr_column_node_fin(ctx, new_node);
+ GRN_FREE(new_node);
+ return rc;
+ }
+ new_node->column = column;
+ *node = (grn_ts_expr_node *)new_node;
+ return GRN_SUCCESS;
+}
+#undef GRN_TS_EXPR_COLUMN_NODE_OPEN_CASE
+
+/* grn_ts_expr_column_node_close() destroys a node. */
+static void
+grn_ts_expr_column_node_close(grn_ctx *ctx, grn_ts_expr_column_node *node)
+{
+ grn_ts_expr_column_node_fin(ctx, node);
+ GRN_FREE(node);
+}
+
+#define GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE(KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ size_t i;\
+ grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
+ grn_ra *ra = (grn_ra *)node->column;\
+ grn_ra_cache cache;\
+ GRN_RA_CACHE_INIT(ra, &cache);\
+ for (i = 0; i < n_in; i++) {\
+ grn_ts_ ## kind *ptr = NULL;\
+ if (in[i].id) {\
+ ptr = (grn_ts_ ## kind *)grn_ra_ref_cache(ctx, ra, in[i].id, &cache);\
+ }\
+ out_ptr[i] = ptr ? *ptr : grn_ts_ ## kind ## _zero();\
+ }\
+ GRN_RA_CACHE_FIN(ra, &cache);\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(TYPE, type)\
+ case GRN_DB_ ## TYPE: {\
+ size_t i;\
+ grn_ts_int *out_ptr = (grn_ts_int *)out;\
+ grn_ra *ra = (grn_ra *)node->column;\
+ grn_ra_cache cache;\
+ GRN_RA_CACHE_INIT(ra, &cache);\
+ for (i = 0; i < n_in; i++) {\
+ type ## _t *ptr = NULL;\
+ if (in[i].id) {\
+ ptr = (type ## _t *)grn_ra_ref_cache(ctx, ra, in[i].id, &cache);\
+ }\
+ out_ptr[i] = ptr ? (grn_ts_int)*ptr : grn_ts_int_zero();\
+ }\
+ GRN_RA_CACHE_FIN(ra, &cache);\
+ return GRN_SUCCESS;\
+ }
+/* grn_ts_expr_column_node_evaluate_scalar() outputs scalar column values. */
+static grn_rc
+grn_ts_expr_column_node_evaluate_scalar(grn_ctx *ctx,
+ grn_ts_expr_column_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ switch (node->data_kind) {
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE(BOOL, bool)
+ case GRN_TS_INT: {
+ switch (node->data_type) {
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(INT8, int8)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(INT16, int16)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(INT32, int32)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(INT64, int64)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(UINT8, uint8)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(UINT16, uint16)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(UINT32, uint32)
+ /* The behavior is undefined if a value is greater than 2^63 - 1. */
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(UINT64, uint64)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data type: %d",
+ node->data_type);
+ }
+ }
+ }
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE(FLOAT, float)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE(TIME, time)
+ case GRN_TS_TEXT: {
+ size_t i;
+ char *buf_ptr;
+ grn_rc rc;
+ grn_ts_text *out_ptr = (grn_ts_text *)out;
+ if (!node->reader) {
+ rc = grn_ja_reader_open(ctx, (grn_ja *)node->column, &node->reader);
+ if (rc != GRN_SUCCESS) {
+ GRN_TS_ERR_RETURN(rc, "grn_ja_reader_open failed");
+ }
+ } else {
+ grn_ja_reader_unref(ctx, node->reader);
+ }
+ node->buf.pos = 0;
+ for (i = 0; i < n_in; i++) {
+ rc = grn_ja_reader_seek(ctx, node->reader, in[i].id);
+ if (rc == GRN_SUCCESS) {
+ if (node->reader->ref_avail) {
+ void *addr;
+ rc = grn_ja_reader_ref(ctx, node->reader, &addr);
+ if (rc == GRN_SUCCESS) {
+ out_ptr[i].ptr = (char *)addr;
+ }
+ } else {
+ rc = grn_ts_buf_reserve(ctx, &node->buf,
+ node->buf.pos + node->reader->value_size);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ja_reader_read(ctx, node->reader,
+ (char *)node->buf.ptr + node->buf.pos);
+ if (rc == GRN_SUCCESS) {
+ out_ptr[i].ptr = NULL;
+ node->buf.pos += node->reader->value_size;
+ }
+ }
+ }
+ }
+ if (rc == GRN_SUCCESS) {
+ out_ptr[i].size = node->reader->value_size;
+ } else {
+ out_ptr[i].ptr = NULL;
+ out_ptr[i].size = 0;
+ }
+ }
+ buf_ptr = (char *)node->buf.ptr;
+ for (i = 0; i < n_in; i++) {
+ if (!out_ptr[i].ptr) {
+ out_ptr[i].ptr = buf_ptr;
+ buf_ptr += out_ptr[i].size;
+ }
+ }
+ return GRN_SUCCESS;
+ }
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE(GEO, geo)
+ case GRN_TS_REF: {
+ size_t i;
+ grn_ts_ref *out_ptr = (grn_ts_ref *)out;
+ grn_ra *ra = (grn_ra *)node->column;
+ grn_ra_cache cache;
+ GRN_RA_CACHE_INIT(ra, &cache);
+ for (i = 0; i < n_in; i++) {
+ grn_ts_id *ptr = NULL;
+ if (in[i].id) {
+ ptr = (grn_ts_id *)grn_ra_ref_cache(ctx, ra, in[i].id, &cache);
+ }
+ out_ptr[i].id = ptr ? *ptr : GRN_ID_NIL;
+ out_ptr[i].score = in[i].score;
+ }
+ GRN_RA_CACHE_FIN(ra, &cache);
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+}
+#undef GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE
+#undef GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE
+
+/*
+ * grn_ts_expr_column_node_evaluate_text_vector() outputs text vector column
+ * values.
+ */
+static grn_rc
+grn_ts_expr_column_node_evaluate_text_vector(grn_ctx *ctx,
+ grn_ts_expr_column_node *node,
+ const grn_ts_record *in,
+ size_t n_in, void *out)
+{
+ grn_rc rc;
+ char *buf_ptr;
+ size_t i, j, n_bytes, n_values, total_n_bytes = 0, total_n_values = 0;
+ grn_ts_text *text_ptr;
+ grn_ts_text_vector *out_ptr = (grn_ts_text_vector *)out;
+ /* Read encoded values into node->body_buf and get the size of each value. */
+ node->body_buf.pos = 0;
+ for (i = 0; i < n_in; i++) {
+ char *ptr;
+ rc = grn_ts_ja_get_value(ctx, node->column, in[i].id,
+ &node->body_buf, &n_bytes);
+ if (rc == GRN_SUCCESS) {
+ ptr = (char *)node->body_buf.ptr + total_n_bytes;
+ GRN_B_DEC(n_values, ptr);
+ } else {
+ n_bytes = 0;
+ n_values = 0;
+ }
+ grn_memcpy(&out_ptr[i].ptr, &n_bytes, sizeof(n_bytes));
+ out_ptr[i].size = n_values;
+ total_n_bytes += n_bytes;
+ total_n_values += n_values;
+ }
+ /* Resize node->buf. */
+ n_bytes = sizeof(grn_ts_text) * total_n_values;
+ rc = grn_ts_buf_reserve(ctx, &node->buf, n_bytes);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ /* Decode values and compose the result. */
+ buf_ptr = (char *)node->body_buf.ptr;
+ text_ptr = (grn_ts_text *)node->buf.ptr;
+ for (i = 0; i < n_in; i++) {
+ char *ptr = buf_ptr;
+ grn_memcpy(&n_bytes, &out_ptr[i].ptr, sizeof(n_bytes));
+ buf_ptr += n_bytes;
+ GRN_B_DEC(n_values, ptr);
+ out_ptr[i].ptr = text_ptr;
+ for (j = 0; j < out_ptr[i].size; j++) {
+ GRN_B_DEC(text_ptr[j].size, ptr);
+ }
+ for (j = 0; j < out_ptr[i].size; j++) {
+ text_ptr[j].ptr = ptr;
+ ptr += text_ptr[j].size;
+ }
+ text_ptr += out_ptr[i].size;
+ }
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ts_expr_column_node_evaluate_ref_vector() outputs ref vector column
+ * values.
+ */
+static grn_rc
+grn_ts_expr_column_node_evaluate_ref_vector(grn_ctx *ctx,
+ grn_ts_expr_column_node *node,
+ const grn_ts_record *in,
+ size_t n_in, void *out)
+{
+ grn_rc rc;
+ size_t i, j, n_bytes, offset = 0;
+ grn_ts_id *buf_ptr;
+ grn_ts_ref *ref_ptr;
+ grn_ts_ref_vector *out_ptr = (grn_ts_ref_vector *)out;
+ /* Read column values into node->body_buf and get the size of each value. */
+ node->body_buf.pos = 0;
+ for (i = 0; i < n_in; i++) {
+ size_t size;
+ rc = grn_ts_ja_get_value(ctx, node->column, in[i].id,
+ &node->body_buf, &size);
+ if (rc == GRN_SUCCESS) {
+ out_ptr[i].size = size / sizeof(grn_ts_id);
+ offset += out_ptr[i].size;
+ } else {
+ out_ptr[i].size = 0;
+ }
+ }
+ /* Resize node->buf. */
+ n_bytes = sizeof(grn_ts_ref) * offset;
+ rc = grn_ts_buf_reserve(ctx, &node->buf, n_bytes);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ /* Compose the result. */
+ buf_ptr = (grn_ts_id *)node->body_buf.ptr;
+ ref_ptr = (grn_ts_ref *)node->buf.ptr;
+ for (i = 0; i < n_in; i++) {
+ out_ptr[i].ptr = ref_ptr;
+ for (j = 0; j < out_ptr[i].size; j++, buf_ptr++, ref_ptr++) {
+ ref_ptr->id = *buf_ptr;
+ ref_ptr->score = in[i].score;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+#define GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE(KIND, kind)\
+ case GRN_TS_ ## KIND ## _VECTOR: {\
+ size_t i;\
+ grn_ts_ ## kind *buf_ptr;\
+ grn_ts_ ## kind ## _vector *out_ptr = (grn_ts_ ## kind ## _vector *)out;\
+ /* Read column values into node->buf and save the size of each value. */\
+ node->buf.pos = 0;\
+ for (i = 0; i < n_in; i++) {\
+ size_t n_bytes;\
+ grn_rc rc = grn_ts_ja_get_value(ctx, node->column, in[i].id,\
+ &node->buf, &n_bytes);\
+ if (rc == GRN_SUCCESS) {\
+ out_ptr[i].size = n_bytes / sizeof(grn_ts_ ## kind);\
+ } else {\
+ out_ptr[i].size = 0;\
+ }\
+ }\
+ buf_ptr = (grn_ts_ ## kind *)node->buf.ptr;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i].ptr = buf_ptr;\
+ buf_ptr += out_ptr[i].size;\
+ }\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(TYPE, type)\
+ case GRN_DB_ ## TYPE: {\
+ size_t i, j;\
+ grn_ts_int *buf_ptr;\
+ grn_ts_int_vector *out_ptr = (grn_ts_int_vector *)out;\
+ /*
+ * Read column values into body_buf and typecast the values to grn_ts_int.
+ * Then, store the grn_ts_int values into node->buf and save the size of
+ * each value.
+ */\
+ node->buf.pos = 0;\
+ for (i = 0; i < n_in; i++) {\
+ grn_rc rc;\
+ size_t n_bytes, new_n_bytes;\
+ node->body_buf.pos = 0;\
+ rc = grn_ts_ja_get_value(ctx, node->column, in[i].id,\
+ &node->body_buf, &n_bytes);\
+ if (rc == GRN_SUCCESS) {\
+ out_ptr[i].size = n_bytes / sizeof(type ## _t);\
+ } else {\
+ out_ptr[i].size = 0;\
+ }\
+ new_n_bytes = node->buf.pos + (sizeof(grn_ts_int) * out_ptr[i].size);\
+ rc = grn_ts_buf_reserve(ctx, &node->buf, new_n_bytes);\
+ if (rc == GRN_SUCCESS) {\
+ type ## _t *src_ptr = (type ## _t *)node->body_buf.ptr;\
+ grn_ts_int *dest_ptr;\
+ dest_ptr = (grn_ts_int *)((char *)node->buf.ptr + node->buf.pos);\
+ for (j = 0; j < out_ptr[i].size; j++) {\
+ dest_ptr[j] = (grn_ts_int)src_ptr[j];\
+ }\
+ node->buf.pos = new_n_bytes;\
+ } else {\
+ out_ptr[i].size = 0;\
+ }\
+ }\
+ buf_ptr = (grn_ts_int *)node->buf.ptr;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i].ptr = buf_ptr;\
+ buf_ptr += out_ptr[i].size;\
+ }\
+ return GRN_SUCCESS;\
+ }
+/* grn_ts_expr_column_node_evaluate_vector() outputs vector column values. */
+static grn_rc
+grn_ts_expr_column_node_evaluate_vector(grn_ctx *ctx,
+ grn_ts_expr_column_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ switch (node->data_kind) {
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE(BOOL, bool)
+ case GRN_TS_INT_VECTOR: {
+ switch (node->data_type) {
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(INT8, int8)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(INT16, int16)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(INT32, int32)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(INT64, int64)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(UINT8, uint8)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(UINT16, uint16)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(UINT32, uint32)
+ /* The behavior is undefined if a value is greater than 2^63 - 1. */
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(UINT64, uint64)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data type: %d",
+ node->data_type);
+ }
+ }
+ }
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE(FLOAT, float)
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE(TIME, time)
+ case GRN_TS_TEXT_VECTOR: {
+ return grn_ts_expr_column_node_evaluate_text_vector(ctx, node, in, n_in,
+ out);
+ }
+ GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE(GEO, geo)
+ case GRN_TS_REF_VECTOR: {
+ return grn_ts_expr_column_node_evaluate_ref_vector(ctx, node, in, n_in,
+ out);
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+}
+#undef GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE
+#undef GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE
+
+/* grn_ts_expr_column_node_evaluate() outputs column values. */
+static grn_rc
+grn_ts_expr_column_node_evaluate(grn_ctx *ctx, grn_ts_expr_column_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ if (node->data_kind & GRN_TS_VECTOR_FLAG) {
+ return grn_ts_expr_column_node_evaluate_vector(ctx, node, in, n_in, out);
+ } else {
+ return grn_ts_expr_column_node_evaluate_scalar(ctx, node, in, n_in, out);
+ }
+}
+
+/* grn_ts_expr_column_node_filter() filters records. */
+static grn_rc
+grn_ts_expr_column_node_filter(grn_ctx *ctx, grn_ts_expr_column_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ size_t i, count = 0;
+ grn_ra *ra = (grn_ra *)node->column;
+ grn_ra_cache cache;
+ GRN_RA_CACHE_INIT(ra, &cache);
+ for (i = 0; i < n_in; i++) {
+ grn_ts_bool *ptr = NULL;
+ if (in[i].id) {
+ ptr = grn_ra_ref_cache(ctx, ra, in[i].id, &cache);
+ }
+ if (ptr && *ptr) {
+ out[count++] = in[i];
+ }
+ }
+ GRN_RA_CACHE_FIN(ra, &cache);
+ *n_out = count;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_column_node_adjust() updates scores. */
+static grn_rc
+grn_ts_expr_column_node_adjust(grn_ctx *ctx, grn_ts_expr_column_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ size_t i;
+ grn_ra *ra = (grn_ra *)node->column;
+ grn_ra_cache cache;
+ GRN_RA_CACHE_INIT(ra, &cache);
+ for (i = 0; i < n_io; i++) {
+ grn_ts_float *ptr = NULL;
+ if (io[i].id) {
+ ptr = grn_ra_ref_cache(ctx, ra, io[i].id, &cache);
+ }
+ if (ptr) {
+ io[i].score = (grn_ts_score)*ptr;
+ }
+ }
+ GRN_RA_CACHE_FIN(ra, &cache);
+ return GRN_SUCCESS;
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_op_node.
+ */
+
+enum {
+ GRN_TS_EXPR_OP_NODE_MAX_N_ARGS = 3,
+ GRN_TS_EXPR_OP_NODE_N_BUFS = 3
+};
+
+typedef struct {
+ GRN_TS_EXPR_NODE_COMMON_MEMBERS
+ grn_ts_op_type op_type;
+ grn_ts_expr_node *args[GRN_TS_EXPR_OP_NODE_MAX_N_ARGS];
+ size_t n_args;
+ grn_ts_buf bufs[GRN_TS_EXPR_OP_NODE_N_BUFS];
+} grn_ts_expr_op_node;
+
+/* grn_ts_expr_op_node_init() initializes a node. */
+static void
+grn_ts_expr_op_node_init(grn_ctx *ctx, grn_ts_expr_op_node *node)
+{
+ size_t i;
+ memset(node, 0, sizeof(*node));
+ node->type = GRN_TS_EXPR_OP_NODE;
+ for (i = 0; i < GRN_TS_EXPR_OP_NODE_MAX_N_ARGS; i++) {
+ node->args[i] = NULL;
+ }
+ for (i = 0; i < GRN_TS_EXPR_OP_NODE_N_BUFS; i++) {
+ grn_ts_buf_init(ctx, &node->bufs[i]);
+ }
+}
+
+/* grn_ts_expr_op_node_fin() finalizes a node. */
+static void
+grn_ts_expr_op_node_fin(grn_ctx *ctx, grn_ts_expr_op_node *node)
+{
+ size_t i;
+ for (i = 0; i < GRN_TS_EXPR_OP_NODE_N_BUFS; i++) {
+ grn_ts_buf_fin(ctx, &node->bufs[i]);
+ }
+ for (i = 0; i < GRN_TS_EXPR_OP_NODE_MAX_N_ARGS; i++) {
+ if (node->args[i]) {
+ grn_ts_expr_node_close(ctx, node->args[i]);
+ }
+ }
+}
+
+/*
+ * grn_ts_expr_op_node_deref_args_for_equal() resolves references if required.
+ */
+static grn_rc
+grn_ts_expr_op_node_deref_args_for_equal(grn_ctx *ctx,
+ grn_ts_expr_op_node *node)
+{
+ grn_rc rc;
+ if (node->n_args != 2) {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid #args: %" GRN_FMT_SIZE,
+ node->n_args);
+ }
+ if ((node->args[0]->data_kind & ~GRN_TS_VECTOR_FLAG) != GRN_TS_REF) {
+ return grn_ts_expr_node_deref(ctx, &node->args[1]);
+ }
+ if ((node->args[1]->data_kind & ~GRN_TS_VECTOR_FLAG) != GRN_TS_REF) {
+ return grn_ts_expr_node_deref(ctx, &node->args[0]);
+ }
+
+ /* FIXME: Arguments should be compared as references if possible. */
+ rc = grn_ts_expr_node_deref(ctx, &node->args[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_node_deref(ctx, &node->args[1]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_op_node_deref_args() resolves references if required. */
+static grn_rc
+grn_ts_expr_op_node_deref_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
+{
+ switch (node->op_type) {
+ case GRN_TS_OP_EQUAL:
+ case GRN_TS_OP_NOT_EQUAL: {
+ return grn_ts_expr_op_node_deref_args_for_equal(ctx, node);
+ }
+ /* TODO: Add a ternary operator. */
+ default: {
+ size_t i;
+ for (i = 0; i < node->n_args; i++) {
+ grn_rc rc = grn_ts_expr_node_deref(ctx, &node->args[i]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+ }
+ }
+}
+
+/*
+ * grn_ts_op_plus_check_args() checks arguments. Note that arguments are
+ * rearranged in some cases.
+ */
+static grn_rc
+grn_ts_op_plus_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
+{
+ grn_rc rc;
+ if ((node->args[0]->data_kind == GRN_TS_INT) &&
+ (node->args[1]->data_kind == GRN_TS_FLOAT)) {
+ rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[0],
+ 1, &node->args[0]);
+ if (rc != GRN_SUCCESS) {
+ node->args[0] = NULL;
+ return rc;
+ }
+ } else if ((node->args[0]->data_kind == GRN_TS_FLOAT) &&
+ (node->args[1]->data_kind == GRN_TS_INT)) {
+ rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[1],
+ 1, &node->args[1]);
+ if (rc != GRN_SUCCESS) {
+ node->args[1] = NULL;
+ return rc;
+ }
+ }
+
+ switch (node->args[0]->data_kind) {
+ case GRN_TS_INT: {
+ switch (node->args[1]->data_kind) {
+ case GRN_TS_INT: {
+ /* Int + Int = Int. */
+ node->data_kind = GRN_TS_INT;
+ node->data_type = GRN_DB_INT64;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_TIME: {
+ /* Int + Time = Time + Int = Time. */
+ grn_ts_expr_node *tmp = node->args[0];
+ node->args[0] = node->args[1];
+ node->args[1] = tmp;
+ node->data_kind = GRN_TS_TIME;
+ node->data_type = GRN_DB_TIME;
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[1]->data_kind);
+ }
+ }
+ }
+ case GRN_TS_FLOAT: {
+ switch (node->args[1]->data_kind) {
+ case GRN_TS_FLOAT: {
+ /* Float + Float = Float. */
+ node->data_kind = GRN_TS_FLOAT;
+ node->data_type = GRN_DB_FLOAT;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_TIME: {
+ /* Float + Time = Time + Float = Time. */
+ grn_ts_expr_node *tmp = node->args[0];
+ node->args[0] = node->args[1];
+ node->args[1] = tmp;
+ node->data_kind = GRN_TS_TIME;
+ node->data_type = GRN_DB_TIME;
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[1]->data_kind);
+ }
+ }
+ }
+ case GRN_TS_TIME: {
+ switch (node->args[1]->data_kind) {
+ case GRN_TS_INT:
+ case GRN_TS_FLOAT: {
+ /* Time + Int or Float = Time. */
+ node->data_kind = GRN_TS_TIME;
+ node->data_type = GRN_DB_TIME;
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[1]->data_kind);
+ }
+ }
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+}
+
+/* grn_ts_op_minus_check_args() checks arguments. */
+static grn_rc
+grn_ts_op_minus_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
+{
+ grn_rc rc;
+ if ((node->args[0]->data_kind == GRN_TS_INT) &&
+ (node->args[1]->data_kind == GRN_TS_FLOAT)) {
+ rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[0],
+ 1, &node->args[0]);
+ if (rc != GRN_SUCCESS) {
+ node->args[0] = NULL;
+ return rc;
+ }
+ } else if ((node->args[0]->data_kind == GRN_TS_FLOAT) &&
+ (node->args[1]->data_kind == GRN_TS_INT)) {
+ rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[1],
+ 1, &node->args[1]);
+ if (rc != GRN_SUCCESS) {
+ node->args[1] = NULL;
+ return rc;
+ }
+ }
+
+ switch (node->args[0]->data_kind) {
+ case GRN_TS_INT: {
+ if (node->args[1]->data_kind != GRN_TS_INT) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[1]->data_kind);
+ }
+ /* Int - Int = Int. */
+ node->data_kind = GRN_TS_INT;
+ node->data_type = GRN_DB_INT64;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_FLOAT: {
+ if (node->args[1]->data_kind != GRN_TS_FLOAT) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[1]->data_kind);
+ }
+ /* Float - Float = Float. */
+ node->data_kind = GRN_TS_FLOAT;
+ node->data_type = GRN_DB_FLOAT;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_TIME: {
+ switch (node->args[1]->data_kind) {
+ case GRN_TS_INT:
+ case GRN_TS_FLOAT: {
+ /* Time - Int or Float = Time. */
+ node->data_kind = GRN_TS_TIME;
+ node->data_type = GRN_DB_TIME;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_TIME: {
+ /* Time - Time = Float. */
+ node->data_kind = GRN_TS_FLOAT;
+ node->data_type = GRN_DB_FLOAT;
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[1]->data_kind);
+ }
+ }
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+}
+
+/*
+ * grn_ts_expr_op_node_typecast_args_for_cmp() inserts a typecast operator for
+ * comparison.
+ */
+static grn_rc
+grn_ts_expr_op_node_typecast_args_for_cmp(grn_ctx *ctx,
+ grn_ts_expr_op_node *node)
+{
+ grn_rc rc;
+ if ((node->args[0]->data_kind == GRN_TS_INT) &&
+ (node->args[1]->data_kind == GRN_TS_FLOAT)) {
+ rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[0],
+ 1, &node->args[0]);
+ if (rc != GRN_SUCCESS) {
+ node->args[0] = NULL;
+ return rc;
+ }
+ } else if ((node->args[0]->data_kind == GRN_TS_FLOAT) &&
+ (node->args[1]->data_kind == GRN_TS_INT)) {
+ rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[1],
+ 1, &node->args[1]);
+ if (rc != GRN_SUCCESS) {
+ node->args[1] = NULL;
+ return rc;
+ }
+ } else if ((node->args[0]->data_kind == GRN_TS_TIME) &&
+ (node->args[1]->data_kind == GRN_TS_TEXT)) {
+ rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_TIME, &node->args[1],
+ 1, &node->args[1]);
+ if (rc != GRN_SUCCESS) {
+ node->args[1] = NULL;
+ return rc;
+ }
+ } else if ((node->args[0]->data_kind == GRN_TS_TEXT) &&
+ (node->args[1]->data_kind == GRN_TS_TIME)) {
+ rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_TIME, &node->args[0],
+ 1, &node->args[0]);
+ if (rc != GRN_SUCCESS) {
+ node->args[0] = NULL;
+ return rc;
+ }
+ } else {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
+ "data kind conflict: %d != %d",
+ node->args[0]->data_kind,
+ node->args[1]->data_kind);
+ }
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ts_expr_op_node_check_args() checks the combination of an operator and
+ * its arguments.
+ */
+static grn_rc
+grn_ts_expr_op_node_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
+{
+ switch (node->op_type) {
+ case GRN_TS_OP_LOGICAL_NOT: {
+ if (node->args[0]->data_kind != GRN_TS_BOOL) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ node->data_kind = GRN_TS_BOOL;
+ node->data_type = GRN_DB_BOOL;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_OP_BITWISE_NOT: {
+ switch (node->args[0]->data_kind) {
+ case GRN_TS_BOOL:
+ case GRN_TS_INT: {
+ node->data_kind = node->args[0]->data_kind;
+ node->data_type = grn_ts_data_kind_to_type(node->data_kind);
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+ }
+ case GRN_TS_OP_POSITIVE:
+ case GRN_TS_OP_NEGATIVE: {
+ if ((node->args[0]->data_kind != GRN_TS_INT) &&
+ (node->args[0]->data_kind != GRN_TS_FLOAT)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ node->data_kind = node->args[0]->data_kind;
+ node->data_type = grn_ts_data_kind_to_type(node->data_kind);
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_OP_FLOAT: {
+ if (node->args[0]->data_kind != GRN_TS_INT) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ node->data_kind = GRN_TS_FLOAT;
+ node->data_type = GRN_DB_FLOAT;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_OP_TIME: {
+ if (node->args[0]->data_kind != GRN_TS_TEXT) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ node->data_kind = GRN_TS_TIME;
+ node->data_type = GRN_DB_TIME;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_OP_LOGICAL_AND:
+ case GRN_TS_OP_LOGICAL_OR:
+ case GRN_TS_OP_LOGICAL_SUB: {
+ if ((node->args[0]->data_kind != GRN_TS_BOOL) ||
+ (node->args[1]->data_kind != GRN_TS_BOOL)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d, %d",
+ node->args[0]->data_kind, node->args[1]->data_kind);
+ }
+ node->data_kind = GRN_TS_BOOL;
+ node->data_type = GRN_DB_BOOL;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_OP_BITWISE_AND:
+ case GRN_TS_OP_BITWISE_OR:
+ case GRN_TS_OP_BITWISE_XOR: {
+ if (node->args[0]->data_kind != node->args[1]->data_kind) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "data kind conflict: %d != %d",
+ node->args[0]->data_kind, node->args[1]->data_kind);
+ }
+ switch (node->args[0]->data_kind) {
+ case GRN_TS_BOOL:
+ case GRN_TS_INT: {
+ node->data_kind = node->args[0]->data_kind;
+ node->data_type = grn_ts_data_kind_to_type(node->data_kind);
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+ node->data_kind = GRN_TS_BOOL;
+ node->data_type = GRN_DB_BOOL;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_OP_EQUAL:
+ case GRN_TS_OP_NOT_EQUAL: {
+ grn_ts_data_kind scalar_data_kind;
+ if (node->args[0]->data_kind != node->args[1]->data_kind) {
+ grn_rc rc = grn_ts_expr_op_node_typecast_args_for_cmp(ctx, node);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ scalar_data_kind = node->args[0]->data_kind & ~GRN_TS_VECTOR_FLAG;
+ if (((scalar_data_kind == GRN_TS_REF) ||
+ (scalar_data_kind == GRN_TS_GEO)) &&
+ (node->args[0]->data_type != node->args[1]->data_type)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "data type conflict: %d != %d",
+ node->args[0]->data_type, node->args[1]->data_type);
+ }
+ node->data_kind = GRN_TS_BOOL;
+ node->data_type = GRN_DB_BOOL;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_OP_LESS:
+ case GRN_TS_OP_LESS_EQUAL:
+ case GRN_TS_OP_GREATER:
+ case GRN_TS_OP_GREATER_EQUAL: {
+ if (node->args[0]->data_kind != node->args[1]->data_kind) {
+ grn_rc rc = grn_ts_expr_op_node_typecast_args_for_cmp(ctx, node);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ switch (node->args[0]->data_kind) {
+ case GRN_TS_INT:
+ case GRN_TS_FLOAT:
+ case GRN_TS_TIME:
+ case GRN_TS_TEXT:
+ case GRN_TS_INT_VECTOR:
+ case GRN_TS_FLOAT_VECTOR:
+ case GRN_TS_TIME_VECTOR:
+ case GRN_TS_TEXT_VECTOR: {
+ node->data_kind = GRN_TS_BOOL;
+ node->data_type = GRN_DB_BOOL;
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+ case GRN_TS_OP_SHIFT_ARITHMETIC_LEFT:
+ case GRN_TS_OP_SHIFT_ARITHMETIC_RIGHT:
+ case GRN_TS_OP_SHIFT_LOGICAL_LEFT:
+ case GRN_TS_OP_SHIFT_LOGICAL_RIGHT: {
+ if ((node->args[0]->data_kind != GRN_TS_INT) ||
+ (node->args[1]->data_kind != GRN_TS_INT)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d, %d",
+ node->args[0]->data_kind,
+ node->args[1]->data_kind);
+ }
+ node->data_kind = GRN_TS_INT;
+ node->data_type = GRN_DB_INT64;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_OP_PLUS: {
+ return grn_ts_op_plus_check_args(ctx, node);
+ }
+ case GRN_TS_OP_MINUS: {
+ return grn_ts_op_minus_check_args(ctx, node);
+ }
+ case GRN_TS_OP_MULTIPLICATION:
+ case GRN_TS_OP_DIVISION:
+ case GRN_TS_OP_MODULUS: {
+ if (node->args[0]->data_kind != node->args[1]->data_kind) {
+ grn_rc rc;
+ if ((node->args[0]->data_kind == GRN_TS_INT) &&
+ (node->args[1]->data_kind == GRN_TS_FLOAT)) {
+ rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[0],
+ 1, &node->args[0]);
+ if (rc != GRN_SUCCESS) {
+ node->args[0] = NULL;
+ return rc;
+ }
+ } else if ((node->args[0]->data_kind == GRN_TS_FLOAT) &&
+ (node->args[1]->data_kind == GRN_TS_INT)) {
+ rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[1],
+ 1, &node->args[1]);
+ if (rc != GRN_SUCCESS) {
+ node->args[1] = NULL;
+ return rc;
+ }
+ } else {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
+ "data kind conflict: %d != %d",
+ node->args[0]->data_kind,
+ node->args[1]->data_kind);
+ }
+ }
+ switch (node->args[0]->data_kind) {
+ case GRN_TS_INT:
+ case GRN_TS_FLOAT: {
+ node->data_kind = node->args[0]->data_kind;
+ node->data_type = grn_ts_data_kind_to_type(node->data_kind);
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+ }
+ }
+ case GRN_TS_OP_MATCH:
+ case GRN_TS_OP_PREFIX_MATCH:
+ case GRN_TS_OP_SUFFIX_MATCH: {
+ if ((node->args[0]->data_kind != GRN_TS_TEXT) ||
+ (node->args[1]->data_kind != GRN_TS_TEXT)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d, %d",
+ node->args[0]->data_kind,
+ node->args[1]->data_kind);
+ }
+ node->data_kind = GRN_TS_BOOL;
+ node->data_type = GRN_DB_BOOL;
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid operator: %d",
+ node->op_type);
+ }
+ }
+}
+
+/* grn_ts_expr_op_node_setup() sets up an operator node. */
+static grn_rc
+grn_ts_expr_op_node_setup(grn_ctx *ctx, grn_ts_expr_op_node *node)
+{
+ grn_rc rc = grn_ts_expr_op_node_deref_args(ctx, node);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_op_node_check_args(ctx, node);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (node->data_kind == GRN_TS_VOID) {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ GRN_TS_VOID);
+ } else if (node->data_type == GRN_DB_VOID) {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data type: %d",
+ GRN_DB_VOID);
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_op_node_open(grn_ctx *ctx, grn_ts_op_type op_type,
+ grn_ts_expr_node **args, size_t n_args,
+ grn_ts_expr_node **node)
+{
+ size_t i;
+ grn_rc rc;
+ grn_ts_expr_op_node *new_node = GRN_MALLOCN(grn_ts_expr_op_node, 1);
+ if (!new_node) {
+ for (i = 0; i < n_args; i++) {
+ grn_ts_expr_node_close(ctx, args[i]);
+ }
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_expr_op_node));
+ }
+ grn_ts_expr_op_node_init(ctx, new_node);
+ new_node->op_type = op_type;
+ for (i = 0; i < n_args; i++) {
+ new_node->args[i] = args[i];
+ }
+ new_node->n_args = n_args;
+ rc = grn_ts_expr_op_node_setup(ctx, new_node);
+ if (rc != GRN_SUCCESS) {
+ grn_ts_expr_op_node_fin(ctx, new_node);
+ GRN_FREE(new_node);
+ return rc;
+ }
+ *node = (grn_ts_expr_node *)new_node;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_op_node_close() destroys a node. */
+static void
+grn_ts_expr_op_node_close(grn_ctx *ctx, grn_ts_expr_op_node *node)
+{
+ grn_ts_expr_op_node_fin(ctx, node);
+ GRN_FREE(node);
+}
+
+/* grn_ts_op_logical_not_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_logical_not_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ size_t i;
+ grn_ts_bool *out_ptr = (grn_ts_bool *)out;
+ grn_rc rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ for (i = 0; i < n_in; i++) {
+ out_ptr[i] = grn_ts_op_logical_not_bool(out_ptr[i]);
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_op_bitwise_not_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_bitwise_not_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ size_t i;
+ grn_rc rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ switch (node->data_kind) {
+ case GRN_TS_BOOL: {
+ grn_ts_bool *out_ptr = (grn_ts_bool *)out;
+ for (i = 0; i < n_in; i++) {
+ out_ptr[i] = grn_ts_op_bitwise_not_bool(out_ptr[i]);
+ }
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_INT: {
+ grn_ts_int *out_ptr = (grn_ts_int *)out;
+ for (i = 0; i < n_in; i++) {
+ out_ptr[i] = grn_ts_op_bitwise_not_int(out_ptr[i]);
+ }
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+}
+
+#define GRN_TS_OP_SIGN_EVALUATE_CASE(type, KIND, kind) \
+ case GRN_TS_ ## KIND: {\
+ grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i] = grn_ts_op_ ## type ## _ ## kind(out_ptr[i]);\
+ }\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_OP_SIGN_EVALUATE(type) \
+ size_t i;\
+ grn_rc rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ switch (node->data_kind) {\
+ GRN_TS_OP_SIGN_EVALUATE_CASE(type, INT, int)\
+ GRN_TS_OP_SIGN_EVALUATE_CASE(type, FLOAT, float)\
+ default: {\
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",\
+ node->data_kind);\
+ }\
+ }
+/* grn_ts_op_positive_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_positive_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ GRN_TS_OP_SIGN_EVALUATE(positive)
+}
+
+/* grn_ts_op_negative_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_negative_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ GRN_TS_OP_SIGN_EVALUATE(negative)
+}
+#undef GRN_TS_OP_SIGN_EVALUATE
+#undef GRN_TS_OP_SIGN_EVALUATE_CASE
+
+/* grn_ts_op_float_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_float_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ size_t i;
+ grn_ts_int *buf_ptr;
+ grn_ts_float *out_ptr = (grn_ts_float *)out;
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_ptr = (grn_ts_int *)node->bufs[0].ptr;
+ for (i = 0; i < n_in; i++) {
+ rc = grn_ts_op_float(ctx, buf_ptr[i], &out_ptr[i]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_op_time_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_time_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ size_t i;
+ grn_ts_text *buf_ptr;
+ grn_ts_time *out_ptr = (grn_ts_time *)out;
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_ptr = (grn_ts_text *)node->bufs[0].ptr;
+ for (i = 0; i < n_in; i++) {
+ rc = grn_ts_op_time(ctx, buf_ptr[i], &out_ptr[i]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_op_logical_and_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_logical_and_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ size_t i, j, count;
+ grn_rc rc;
+ grn_ts_bool *buf_ptrs[2], *out_ptr = (grn_ts_bool *)out;
+ grn_ts_buf *tmp_in_buf = &node->bufs[2];
+ grn_ts_record *tmp_in;
+
+ /* Evaluate the 1st argument. */
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_ptrs[0] = (grn_ts_bool *)node->bufs[0].ptr;
+
+ /* Create a list of true records. */
+ rc = grn_ts_buf_reserve(ctx, tmp_in_buf, sizeof(grn_ts_record) * n_in);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ tmp_in = (grn_ts_record *)tmp_in_buf->ptr;
+ count = 0;
+ for (i = 0; i < n_in; i++) {
+ if (buf_ptrs[0][i]) {
+ tmp_in[count++] = in[i];
+ }
+ }
+
+ /* Evaluate the 2nd argument. */
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], tmp_in, count,
+ &node->bufs[1]);
+ buf_ptrs[1] = (grn_ts_bool *)node->bufs[1].ptr;
+
+ /* Merge the results. */
+ count = 0;
+ for (i = 0, j = 0; i < n_in; i++) {
+ out_ptr[count++] = buf_ptrs[0][i] && buf_ptrs[1][j++];
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_op_logical_or_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_logical_or_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ size_t i, j, count;
+ grn_rc rc;
+ grn_ts_bool *buf_ptrs[2], *out_ptr = (grn_ts_bool *)out;
+ grn_ts_buf *tmp_in_buf = &node->bufs[2];
+ grn_ts_record *tmp_in;
+
+ /* Evaluate the 1st argument. */
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_ptrs[0] = (grn_ts_bool *)node->bufs[0].ptr;
+
+ /* Create a list of false records. */
+ rc = grn_ts_buf_reserve(ctx, tmp_in_buf, sizeof(grn_ts_record) * n_in);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ tmp_in = (grn_ts_record *)tmp_in_buf->ptr;
+ count = 0;
+ for (i = 0; i < n_in; i++) {
+ if (!buf_ptrs[0][i]) {
+ tmp_in[count++] = in[i];
+ }
+ }
+
+ /* Evaluate the 2nd argument. */
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], tmp_in, count,
+ &node->bufs[1]);
+ buf_ptrs[1] = (grn_ts_bool *)node->bufs[1].ptr;
+
+ /* Merge the results. */
+ count = 0;
+ for (i = 0, j = 0; i < n_in; i++) {
+ out_ptr[count++] = buf_ptrs[0][i] || buf_ptrs[1][j++];
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_op_logical_sub_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_logical_sub_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ size_t i, j, count;
+ grn_rc rc;
+ grn_ts_bool *buf_ptrs[2], *out_ptr = (grn_ts_bool *)out;
+ grn_ts_buf *tmp_in_buf = &node->bufs[2];
+ grn_ts_record *tmp_in;
+
+ /* Evaluate the 1st argument. */
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_ptrs[0] = (grn_ts_bool *)node->bufs[0].ptr;
+
+ /* Create a list of true records. */
+ rc = grn_ts_buf_reserve(ctx, tmp_in_buf, sizeof(grn_ts_record) * n_in);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ tmp_in = (grn_ts_record *)tmp_in_buf->ptr;
+ count = 0;
+ for (i = 0; i < n_in; i++) {
+ if (buf_ptrs[0][i]) {
+ tmp_in[count++] = in[i];
+ }
+ }
+
+ /* Evaluate the 2nd argument. */
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], tmp_in, count,
+ &node->bufs[1]);
+ buf_ptrs[1] = (grn_ts_bool *)node->bufs[1].ptr;
+
+ /* Merge the results. */
+ count = 0;
+ for (i = 0, j = 0; i < n_in; i++) {
+ out_ptr[count++] = buf_ptrs[0][i] &&
+ grn_ts_op_logical_not_bool(buf_ptrs[1][j++]);
+ }
+ return GRN_SUCCESS;
+}
+
+#define GRN_TS_OP_BITWISE_EVALUATE_CASE(type, KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ /*
+ * Use the output buffer to put evaluation results of the 1st argument,
+ * because the data kind is same.
+ */\
+ size_t i;\
+ grn_rc rc;\
+ grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
+ rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
+ if (rc == GRN_SUCCESS) {\
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
+ in, n_in, &node->bufs[0]);\
+ if (rc == GRN_SUCCESS) {\
+ grn_ts_ ## kind *buf_ptr = (grn_ts_ ## kind *)node->bufs[0].ptr;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i] = grn_ts_op_bitwise_ ## type ## _ ## kind(out_ptr[i],\
+ buf_ptr[i]);\
+ }\
+ }\
+ }\
+ return rc;\
+ }
+/* grn_ts_op_bitwise_and_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_bitwise_and_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ switch (node->args[0]->data_kind) {
+ GRN_TS_OP_BITWISE_EVALUATE_CASE(and, BOOL, bool)
+ GRN_TS_OP_BITWISE_EVALUATE_CASE(and, INT, int)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+}
+
+/* grn_ts_op_bitwise_or_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_bitwise_or_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ switch (node->args[0]->data_kind) {
+ GRN_TS_OP_BITWISE_EVALUATE_CASE(or, BOOL, bool)
+ GRN_TS_OP_BITWISE_EVALUATE_CASE(or, INT, int)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+}
+
+/* grn_ts_op_bitwise_xor_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_bitwise_xor_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ switch (node->args[0]->data_kind) {
+ GRN_TS_OP_BITWISE_EVALUATE_CASE(xor, BOOL, bool)
+ GRN_TS_OP_BITWISE_EVALUATE_CASE(xor, INT, int)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+}
+#undef GRN_TS_OP_BITWISE_EVALUATE_CASE
+
+#define GRN_TS_OP_CHK_EVALUATE_CASE(type, KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ grn_ts_ ## kind *buf_ptrs[] = {\
+ (grn_ts_ ## kind *)node->bufs[0].ptr,\
+ (grn_ts_ ## kind *)node->bufs[1].ptr\
+ };\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i] = grn_ts_op_ ## type ## _ ## kind(buf_ptrs[0][i],\
+ buf_ptrs[1][i]);\
+ }\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, KIND, kind)\
+ GRN_TS_OP_CHK_EVALUATE_CASE(type, KIND ## _VECTOR, kind ## _vector)
+#define GRN_TS_OP_CHK_EVALUATE(type)\
+ size_t i;\
+ grn_rc rc;\
+ grn_ts_bool *out_ptr = (grn_ts_bool *)out;\
+ if (node->args[0]->data_kind == GRN_TS_BOOL) {\
+ /*
+ * Use the output buffer to put evaluation results of the 1st argument,
+ * because the data kind is same.
+ */\
+ rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
+ if (rc == GRN_SUCCESS) {\
+ grn_ts_buf *buf = &node->bufs[0];\
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
+ in, n_in, buf);\
+ if (rc == GRN_SUCCESS) {\
+ grn_ts_bool *buf_ptr = (grn_ts_bool *)buf->ptr;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i] = grn_ts_op_ ## type ## _bool(out_ptr[i], buf_ptr[i]);\
+ }\
+ }\
+ }\
+ return rc;\
+ }\
+ for (i = 0; i < 2; i++) {\
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
+ &node->bufs[i]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ }\
+ switch (node->args[0]->data_kind) {\
+ GRN_TS_OP_CHK_EVALUATE_CASE(type, INT, int)\
+ GRN_TS_OP_CHK_EVALUATE_CASE(type, FLOAT, float)\
+ GRN_TS_OP_CHK_EVALUATE_CASE(type, TIME, time)\
+ GRN_TS_OP_CHK_EVALUATE_CASE(type, TEXT, text)\
+ GRN_TS_OP_CHK_EVALUATE_CASE(type, GEO, geo)\
+ GRN_TS_OP_CHK_EVALUATE_CASE(type, REF, ref)\
+ GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, BOOL, bool)\
+ GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, INT, int)\
+ GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, FLOAT, float)\
+ GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, TIME, time)\
+ GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, TEXT, text)\
+ GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, GEO, geo)\
+ GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, REF, ref)\
+ default: {\
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",\
+ node->args[0]->data_kind);\
+ }\
+ }
+/* grn_ts_op_equal_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_equal_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ GRN_TS_OP_CHK_EVALUATE(equal)
+}
+
+/* grn_ts_op_not_equal_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_not_equal_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ GRN_TS_OP_CHK_EVALUATE(not_equal)
+}
+#undef GRN_TS_OP_CHK_EVALUATE
+#undef GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE
+#undef GRN_TS_OP_CHK_EVALUATE_CASE
+
+#define GRN_TS_OP_CMP_EVALUATE_CASE(type, KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ grn_ts_ ## kind *buf_ptrs[] = {\
+ (grn_ts_ ## kind *)node->bufs[0].ptr,\
+ (grn_ts_ ## kind *)node->bufs[1].ptr\
+ };\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i] = grn_ts_op_ ## type ## _ ## kind(buf_ptrs[0][i],\
+ buf_ptrs[1][i]);\
+ }\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE(type, KIND, kind)\
+ GRN_TS_OP_CMP_EVALUATE_CASE(type, KIND ## _VECTOR, kind ## _vector)
+#define GRN_TS_OP_CMP_EVALUATE(type)\
+ size_t i;\
+ grn_rc rc;\
+ grn_ts_bool *out_ptr = (grn_ts_bool *)out;\
+ for (i = 0; i < 2; i++) {\
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
+ &node->bufs[i]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ }\
+ switch (node->args[0]->data_kind) {\
+ GRN_TS_OP_CMP_EVALUATE_CASE(type, INT, int)\
+ GRN_TS_OP_CMP_EVALUATE_CASE(type, FLOAT, float)\
+ GRN_TS_OP_CMP_EVALUATE_CASE(type, TIME, time)\
+ GRN_TS_OP_CMP_EVALUATE_CASE(type, TEXT, text)\
+ GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE(type, INT, int)\
+ GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE(type, FLOAT, float)\
+ GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE(type, TIME, time)\
+ GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE(type, TEXT, text)\
+ default: {\
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",\
+ node->args[0]->data_kind);\
+ }\
+ }
+/* grn_ts_op_less_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_less_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ GRN_TS_OP_CMP_EVALUATE(less)
+}
+
+/* grn_ts_op_less_equal_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_less_equal_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ GRN_TS_OP_CMP_EVALUATE(less_equal)
+}
+
+/* grn_ts_op_greater_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_greater_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ GRN_TS_OP_CMP_EVALUATE(greater)
+}
+
+/* grn_ts_op_greater_equal_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_greater_equal_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ GRN_TS_OP_CMP_EVALUATE(greater_equal)
+}
+#undef GRN_TS_OP_CMP_EVALUATE
+#undef GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE
+#undef GRN_TS_OP_CMP_EVALUATE_CASE
+
+#define GRN_TS_OP_SHIFT_EVALUATE(type)\
+ size_t i;\
+ grn_rc rc;\
+ grn_ts_int *out_ptr = (grn_ts_int *)out;\
+ rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
+ if (rc == GRN_SUCCESS) {\
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
+ in, n_in, &node->bufs[0]);\
+ if (rc == GRN_SUCCESS) {\
+ grn_ts_int *buf_ptr = (grn_ts_int *)node->bufs[0].ptr;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i] = grn_ts_op_shift_ ## type(out_ptr[i], buf_ptr[i]);\
+ }\
+ }\
+ }\
+ return rc;
+/* grn_ts_op_shift_arithmetic_left_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_shift_arithmetic_left_evaluate(grn_ctx *ctx,
+ grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ GRN_TS_OP_SHIFT_EVALUATE(arithmetic_left)
+}
+
+/* grn_ts_op_shift_arithmetic_right_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_shift_arithmetic_right_evaluate(grn_ctx *ctx,
+ grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ GRN_TS_OP_SHIFT_EVALUATE(arithmetic_right)
+}
+
+/* grn_ts_op_shift_logical_left_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_shift_logical_left_evaluate(grn_ctx *ctx,
+ grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ GRN_TS_OP_SHIFT_EVALUATE(logical_left)
+}
+
+/* grn_ts_op_shift_logical_right_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_shift_logical_right_evaluate(grn_ctx *ctx,
+ grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ GRN_TS_OP_SHIFT_EVALUATE(logical_right)
+}
+#undef GRN_TS_OP_SHIFT_EVALUATE
+
+#define GRN_TS_OP_ARITH_EVALUATE(type, lhs_kind, rhs_kind)\
+ /*
+ * Use the output buffer to put evaluation results of the 1st argument,
+ * because the data kind is same.
+ */\
+ size_t i;\
+ grn_rc rc;\
+ grn_ts_ ## lhs_kind *out_ptr = (grn_ts_ ## lhs_kind *)out;\
+ rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
+ if (rc == GRN_SUCCESS) {\
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
+ in, n_in, &node->bufs[0]);\
+ if (rc == GRN_SUCCESS) {\
+ grn_ts_ ## rhs_kind *buf_ptr = (grn_ts_ ## rhs_kind *)node->bufs[0].ptr;\
+ for (i = 0; i < n_in; i++) {\
+ rc = grn_ts_op_ ## type ## _ ## lhs_kind ## _ ## rhs_kind(\
+ ctx, out_ptr[i], buf_ptr[i], &out_ptr[i]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ }\
+ }\
+ }\
+ return rc;
+
+#define GRN_TS_OP_ARITH_EVALUATE_CASE(type, KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ /*
+ * Use the output buffer to put evaluation results of the 1st argument,
+ * because the data kind is same.
+ */\
+ size_t i;\
+ grn_rc rc;\
+ grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
+ rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
+ if (rc == GRN_SUCCESS) {\
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
+ in, n_in, &node->bufs[0]);\
+ if (rc == GRN_SUCCESS) {\
+ grn_ts_ ## kind *buf_ptr = (grn_ts_ ## kind *)node->bufs[0].ptr;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i] = grn_ts_op_ ## type ## _ ## kind(out_ptr[i],\
+ buf_ptr[i]);\
+ }\
+ }\
+ }\
+ return rc;\
+ }
+#define GRN_TS_OP_ARITH_EVALUATE_TIME_CASE(type, KIND, lhs, rhs)\
+ case GRN_TS_ ## KIND: {\
+ /*
+ * Use the output buffer to put evaluation results of the 1st argument,
+ * because the data kind is same.
+ */\
+ size_t i;\
+ grn_rc rc;\
+ grn_ts_ ## lhs *out_ptr = (grn_ts_ ## lhs *)out;\
+ rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
+ if (rc == GRN_SUCCESS) {\
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
+ in, n_in, &node->bufs[0]);\
+ if (rc == GRN_SUCCESS) {\
+ grn_ts_ ## rhs *buf_ptr = (grn_ts_ ## rhs *)node->bufs[0].ptr;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i] = grn_ts_op_ ## type ## _ ## lhs ## _ ## rhs(out_ptr[i],\
+ buf_ptr[i]);\
+ }\
+ }\
+ }\
+ return rc;\
+ }
+/* grn_ts_op_plus_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_plus_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ switch (node->args[0]->data_kind) {
+ case GRN_TS_INT: {
+ GRN_TS_OP_ARITH_EVALUATE(plus, int, int)
+ }
+ case GRN_TS_FLOAT: {
+ GRN_TS_OP_ARITH_EVALUATE(plus, float, float)
+ }
+ case GRN_TS_TIME: {
+ switch (node->args[1]->data_kind) {
+ case GRN_TS_INT: {
+ GRN_TS_OP_ARITH_EVALUATE(plus, time, int)
+ }
+ case GRN_TS_FLOAT: {
+ GRN_TS_OP_ARITH_EVALUATE(plus, time, float)
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "data kind conflict: %d, %d",
+ node->args[0]->data_kind,
+ node->args[1]->data_kind);
+ }
+ }
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+}
+
+/* grn_ts_op_minus_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_minus_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ switch (node->args[0]->data_kind) {
+ case GRN_TS_INT: {
+ GRN_TS_OP_ARITH_EVALUATE(minus, int, int)
+ }
+ case GRN_TS_FLOAT: {
+ GRN_TS_OP_ARITH_EVALUATE(minus, float, float)
+ }
+ case GRN_TS_TIME: {
+ switch (node->args[1]->data_kind) {
+ case GRN_TS_INT: {
+ GRN_TS_OP_ARITH_EVALUATE(minus, time, int)
+ }
+ case GRN_TS_FLOAT: {
+ GRN_TS_OP_ARITH_EVALUATE(minus, time, float)
+ }
+ case GRN_TS_TIME: {
+ size_t i;
+ grn_rc rc;
+ grn_ts_float *out_ptr = (grn_ts_float *)out;
+ grn_ts_time *buf_ptrs[2];
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], in, n_in,
+ &node->bufs[1]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_ptrs[0] = (grn_ts_time *)node->bufs[0].ptr;
+ buf_ptrs[1] = (grn_ts_time *)node->bufs[1].ptr;
+ for (i = 0; i < n_in; i++) {
+ rc = grn_ts_op_minus_time_time(ctx, buf_ptrs[0][i], buf_ptrs[1][i],
+ &out_ptr[i]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "data kind conflict: %d, %d",
+ node->args[0]->data_kind,
+ node->args[1]->data_kind);
+ }
+ }
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->args[0]->data_kind);
+ }
+ }
+}
+#undef GRN_TS_OP_ARITH_EVALUATE_TIME_CASE
+
+/* grn_ts_op_multiplication_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_multiplication_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ switch (node->data_kind) {
+ case GRN_TS_INT: {
+ GRN_TS_OP_ARITH_EVALUATE(multiplication, int, int)
+ }
+ case GRN_TS_FLOAT: {
+ GRN_TS_OP_ARITH_EVALUATE(multiplication, float, float)
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+}
+
+/* grn_ts_op_division_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_division_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ switch (node->data_kind) {
+ case GRN_TS_INT: {
+ GRN_TS_OP_ARITH_EVALUATE(division, int, int)
+ }
+ case GRN_TS_FLOAT: {
+ GRN_TS_OP_ARITH_EVALUATE(division, float, float)
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+}
+
+/* grn_ts_op_modulus_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_modulus_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ switch (node->data_kind) {
+ case GRN_TS_INT: {
+ GRN_TS_OP_ARITH_EVALUATE(modulus, int, int)
+ }
+ case GRN_TS_FLOAT: {
+ GRN_TS_OP_ARITH_EVALUATE(modulus, float, float)
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
+ node->data_kind);
+ }
+ }
+}
+#undef GRN_TS_OP_ARITH_EVALUATE_CASE
+
+#define GRN_TS_OP_MATCH_EVALUATE(type)\
+ size_t i;\
+ grn_rc rc;\
+ grn_ts_bool *out_ptr = (grn_ts_bool *)out;\
+ grn_ts_text *buf_ptrs[2];\
+ for (i = 0; i < 2; i++) {\
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
+ &node->bufs[i]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ }\
+ buf_ptrs[0] = (grn_ts_text *)node->bufs[0].ptr;\
+ buf_ptrs[1] = (grn_ts_text *)node->bufs[1].ptr;\
+ for (i = 0; i < n_in; i++) {\
+ out_ptr[i] = grn_ts_op_ ## type(buf_ptrs[0][i], buf_ptrs[1][i]);\
+ }\
+ return GRN_SUCCESS;\
+/* grn_ts_op_match_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_match_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ GRN_TS_OP_MATCH_EVALUATE(match)
+}
+
+/* grn_ts_op_prefix_match_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_prefix_match_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ GRN_TS_OP_MATCH_EVALUATE(prefix_match)
+}
+
+/* grn_ts_op_suffix_match_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_suffix_match_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ GRN_TS_OP_MATCH_EVALUATE(suffix_match)
+}
+#undef GRN_TS_OP_MATCH_EVALUATE
+
+/* grn_ts_expr_op_node_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_expr_op_node_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ switch (node->op_type) {
+ case GRN_TS_OP_LOGICAL_NOT: {
+ return grn_ts_op_logical_not_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_BITWISE_NOT: {
+ return grn_ts_op_bitwise_not_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_POSITIVE: {
+ return grn_ts_op_positive_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_NEGATIVE: {
+ return grn_ts_op_negative_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_FLOAT: {
+ return grn_ts_op_float_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_TIME: {
+ return grn_ts_op_time_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_LOGICAL_AND: {
+ return grn_ts_op_logical_and_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_LOGICAL_OR: {
+ return grn_ts_op_logical_or_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_LOGICAL_SUB: {
+ return grn_ts_op_logical_sub_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_BITWISE_AND: {
+ return grn_ts_op_bitwise_and_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_BITWISE_OR: {
+ return grn_ts_op_bitwise_or_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_BITWISE_XOR: {
+ return grn_ts_op_bitwise_xor_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_EQUAL: {
+ return grn_ts_op_equal_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_NOT_EQUAL: {
+ return grn_ts_op_not_equal_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_LESS: {
+ return grn_ts_op_less_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_LESS_EQUAL: {
+ return grn_ts_op_less_equal_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_GREATER: {
+ return grn_ts_op_greater_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_GREATER_EQUAL: {
+ return grn_ts_op_greater_equal_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_SHIFT_ARITHMETIC_LEFT: {
+ return grn_ts_op_shift_arithmetic_left_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_SHIFT_ARITHMETIC_RIGHT: {
+ return grn_ts_op_shift_arithmetic_right_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_SHIFT_LOGICAL_LEFT: {
+ return grn_ts_op_shift_logical_left_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_SHIFT_LOGICAL_RIGHT: {
+ return grn_ts_op_shift_logical_right_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_PLUS: {
+ return grn_ts_op_plus_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_MINUS: {
+ return grn_ts_op_minus_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_MULTIPLICATION: {
+ return grn_ts_op_multiplication_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_DIVISION: {
+ return grn_ts_op_division_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_MODULUS: {
+ return grn_ts_op_modulus_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_MATCH: {
+ return grn_ts_op_match_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_PREFIX_MATCH: {
+ return grn_ts_op_prefix_match_evaluate(ctx, node, in, n_in, out);
+ }
+ case GRN_TS_OP_SUFFIX_MATCH: {
+ return grn_ts_op_suffix_match_evaluate(ctx, node, in, n_in, out);
+ }
+ // TODO: Add operators.
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
+ "operator not supported: %d", node->op_type);
+ }
+ }
+}
+
+/* grn_ts_op_logical_not_filter() filters records. */
+static grn_rc
+grn_ts_op_logical_not_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ size_t i, count;
+ grn_rc rc;
+ grn_ts_bool *buf_ptr;
+ rc = grn_ts_buf_reserve(ctx, &node->bufs[0], sizeof(grn_ts_bool) * n_in);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_ptr = (grn_ts_bool *)node->bufs[0].ptr;
+ rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, buf_ptr);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ for (i = 0, count = 0; i < n_in; i++) {
+ if (grn_ts_op_logical_not_bool(buf_ptr[i])) {
+ out[count++] = in[i];
+ }
+ }
+ *n_out = count;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_op_bitwise_not_filter() filters records. */
+static grn_rc
+grn_ts_op_bitwise_not_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ size_t i, count;
+ grn_rc rc;
+ grn_ts_bool *buf_ptr;
+ rc = grn_ts_buf_reserve(ctx, &node->bufs[0], sizeof(grn_ts_bool) * n_in);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_ptr = (grn_ts_bool *)node->bufs[0].ptr;
+ rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, buf_ptr);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ for (i = 0, count = 0; i < n_in; i++) {
+ if (grn_ts_op_bitwise_not_bool(buf_ptr[i])) {
+ out[count++] = in[i];
+ }
+ }
+ *n_out = count;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_op_logical_and_filter() filters records. */
+static grn_rc
+grn_ts_op_logical_and_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ grn_rc rc = grn_ts_expr_node_filter(ctx, node->args[0], in, n_in,
+ out, n_out);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ return grn_ts_expr_node_filter(ctx, node->args[1], out, *n_out, out, n_out);
+}
+
+/* grn_ts_op_logical_or_filter() filters records. */
+static grn_rc
+grn_ts_op_logical_or_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ size_t i, j, count;
+ grn_rc rc;
+ grn_ts_bool *buf_ptrs[2];
+ grn_ts_buf *tmp_in_buf = &node->bufs[2];
+ grn_ts_record *tmp_in;
+
+ /* Evaluate the 1st argument. */
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_ptrs[0] = (grn_ts_bool *)node->bufs[0].ptr;
+
+ /* Create a list of false records. */
+ rc = grn_ts_buf_reserve(ctx, tmp_in_buf, sizeof(grn_ts_record) * n_in);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ tmp_in = (grn_ts_record *)tmp_in_buf->ptr;
+ count = 0;
+ for (i = 0; i < n_in; i++) {
+ if (!buf_ptrs[0][i]) {
+ tmp_in[count++] = in[i];
+ }
+ }
+
+ /* Evaluate the 2nd argument. */
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], tmp_in, count,
+ &node->bufs[1]);
+ buf_ptrs[1] = (grn_ts_bool *)node->bufs[1].ptr;
+
+ /* Merge the results. */
+ count = 0;
+ for (i = 0, j = 0; i < n_in; i++) {
+ if (buf_ptrs[0][i] || buf_ptrs[1][j++]) {
+ out[count++] = in[i];
+ }
+ }
+ *n_out = count;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_op_logical_sub_filter() filters records. */
+static grn_rc
+grn_ts_op_logical_sub_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ size_t i, n, count;
+ grn_ts_bool *buf_ptr;
+ grn_rc rc = grn_ts_expr_node_filter(ctx, node->args[0], in, n_in, out, &n);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], out, n,
+ &node->bufs[0]);
+ buf_ptr = (grn_ts_bool *)node->bufs[0].ptr;
+ for (i = 0, count = 0; i < n; i++) {
+ if (grn_ts_op_logical_not_bool(buf_ptr[i])) {
+ out[count++] = out[i];
+ }
+ }
+ *n_out = count;
+ return GRN_SUCCESS;
+}
+
+#define GRN_TS_OP_BITWISE_FILTER(type)\
+ size_t i, count = 0;\
+ grn_ts_bool *buf_ptrs[2];\
+ for (i = 0; i < 2; i++) {\
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
+ &node->bufs[i]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ buf_ptrs[i] = (grn_ts_bool *)node->bufs[i].ptr;\
+ }\
+ for (i = 0; i < n_in; i++) {\
+ if (grn_ts_op_bitwise_ ## type ## _bool(buf_ptrs[0][i], buf_ptrs[1][i])) {\
+ out[count++] = in[i];\
+ }\
+ }\
+ *n_out = count;\
+ return GRN_SUCCESS;\
+/* grn_ts_op_bitwise_and_filter() filters records. */
+static grn_rc
+grn_ts_op_bitwise_and_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_BITWISE_FILTER(and);
+}
+
+/* grn_ts_op_bitwise_or_filter() filters records. */
+static grn_rc
+grn_ts_op_bitwise_or_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_BITWISE_FILTER(or);
+}
+
+/* grn_ts_op_bitwise_xor_filter() filters records. */
+static grn_rc
+grn_ts_op_bitwise_xor_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_BITWISE_FILTER(xor);
+}
+#undef GRN_TS_OP_BITWISE_FILTER_CASE
+
+#define GRN_TS_OP_CHK_FILTER_CASE(type, KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ grn_ts_ ## kind *buf_ptrs[] = {\
+ (grn_ts_ ## kind *)node->bufs[0].ptr,\
+ (grn_ts_ ## kind *)node->bufs[1].ptr\
+ };\
+ for (i = 0; i < n_in; i++) {\
+ if (grn_ts_op_ ## type ## _ ## kind(buf_ptrs[0][i], buf_ptrs[1][i])) {\
+ out[count++] = in[i];\
+ }\
+ }\
+ *n_out = count;\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, KIND, kind)\
+ GRN_TS_OP_CHK_FILTER_CASE(type, KIND ## _VECTOR, kind ## _vector)
+#define GRN_TS_OP_CHK_FILTER(type)\
+ size_t i, count = 0;\
+ for (i = 0; i < 2; i++) {\
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
+ &node->bufs[i]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ }\
+ switch (node->args[0]->data_kind) {\
+ GRN_TS_OP_CHK_FILTER_CASE(type, BOOL, bool)\
+ GRN_TS_OP_CHK_FILTER_CASE(type, INT, int)\
+ GRN_TS_OP_CHK_FILTER_CASE(type, FLOAT, float)\
+ GRN_TS_OP_CHK_FILTER_CASE(type, TIME, time)\
+ GRN_TS_OP_CHK_FILTER_CASE(type, TEXT, text)\
+ GRN_TS_OP_CHK_FILTER_CASE(type, GEO, geo)\
+ GRN_TS_OP_CHK_FILTER_CASE(type, REF, ref)\
+ GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, BOOL, bool)\
+ GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, INT, int)\
+ GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, FLOAT, float)\
+ GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, TIME, time)\
+ GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, TEXT, text)\
+ GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, GEO, geo)\
+ GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, REF, ref)\
+ default: {\
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",\
+ node->args[0]->data_kind);\
+ }\
+ }
+/* grn_ts_op_equal_filter() filters records. */
+static grn_rc
+grn_ts_op_equal_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_CHK_FILTER(equal)
+}
+
+/* grn_ts_op_not_equal_filter() filters records. */
+static grn_rc
+grn_ts_op_not_equal_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_CHK_FILTER(not_equal)
+}
+#undef GRN_TS_OP_CHK_FILTER
+#undef GRN_TS_OP_CHK_FILTER_VECTOR_CASE
+#undef GRN_TS_OP_CHK_FILTER_CASE
+
+#define GRN_TS_OP_CMP_FILTER_CASE(type, KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ grn_ts_ ## kind *buf_ptrs[] = {\
+ (grn_ts_ ## kind *)node->bufs[0].ptr,\
+ (grn_ts_ ## kind *)node->bufs[1].ptr\
+ };\
+ for (i = 0; i < n_in; i++) {\
+ if (grn_ts_op_ ## type ## _ ## kind(buf_ptrs[0][i], buf_ptrs[1][i])) {\
+ out[count++] = in[i];\
+ }\
+ }\
+ *n_out = count;\
+ return GRN_SUCCESS;\
+ }
+#define GRN_TS_OP_CMP_FILTER_VECTOR_CASE(type, KIND, kind)\
+ GRN_TS_OP_CMP_FILTER_CASE(type, KIND ## _VECTOR, kind ## _vector)
+#define GRN_TS_OP_CMP_FILTER(type)\
+ size_t i, count = 0;\
+ for (i = 0; i < 2; i++) {\
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
+ &node->bufs[i]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ }\
+ switch (node->args[0]->data_kind) {\
+ GRN_TS_OP_CMP_FILTER_CASE(type, INT, int)\
+ GRN_TS_OP_CMP_FILTER_CASE(type, FLOAT, float)\
+ GRN_TS_OP_CMP_FILTER_CASE(type, TIME, time)\
+ GRN_TS_OP_CMP_FILTER_CASE(type, TEXT, text)\
+ GRN_TS_OP_CMP_FILTER_VECTOR_CASE(type, INT, int)\
+ GRN_TS_OP_CMP_FILTER_VECTOR_CASE(type, FLOAT, float)\
+ GRN_TS_OP_CMP_FILTER_VECTOR_CASE(type, TIME, time)\
+ GRN_TS_OP_CMP_FILTER_VECTOR_CASE(type, TEXT, text)\
+ default: {\
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",\
+ node->args[0]->data_kind);\
+ }\
+ }
+/* grn_ts_op_less_filter() filters records. */
+static grn_rc
+grn_ts_op_less_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_CMP_FILTER(less)
+}
+
+/* grn_ts_op_less_equal_filter() filters records. */
+static grn_rc
+grn_ts_op_less_equal_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_CMP_FILTER(less_equal)
+}
+
+/* grn_ts_op_greater_filter() filters records. */
+static grn_rc
+grn_ts_op_greater_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_CMP_FILTER(greater)
+}
+
+/* grn_ts_op_greater_equal_filter() filters records. */
+static grn_rc
+grn_ts_op_greater_equal_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_CMP_FILTER(greater_equal)
+}
+#undef GRN_TS_OP_CMP_FILTER
+#undef GRN_TS_OP_CMP_FILTER_VECTOR_CASE
+#undef GRN_TS_OP_CMP_FILTER_CASE
+
+#define GRN_TS_OP_MATCH_FILTER_CASE(type, KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ grn_ts_ ## kind *buf_ptrs[] = {\
+ (grn_ts_ ## kind *)node->bufs[0].ptr,\
+ (grn_ts_ ## kind *)node->bufs[1].ptr\
+ };\
+ for (i = 0; i < n_in; i++) {\
+ if (grn_ts_op_ ## type ## _ ## kind(buf_ptrs[0][i], buf_ptrs[1][i])) {\
+ out[count++] = in[i];\
+ }\
+ }\
+ *n_out = count;\
+ return GRN_SUCCESS;\
+ }
+
+#define GRN_TS_OP_MATCH_FILTER(type)\
+ size_t i, count = 0;\
+ grn_ts_text *buf_ptrs[2];\
+ for (i = 0; i < 2; i++) {\
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
+ &node->bufs[i]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ }\
+ buf_ptrs[0] = (grn_ts_text *)node->bufs[0].ptr;\
+ buf_ptrs[1] = (grn_ts_text *)node->bufs[1].ptr;\
+ for (i = 0; i < n_in; i++) {\
+ if (grn_ts_op_ ## type(buf_ptrs[0][i], buf_ptrs[1][i])) {\
+ out[count++] = in[i];\
+ }\
+ }\
+ *n_out = count;\
+ return GRN_SUCCESS;\
+/* grn_ts_op_match_filter() filters records. */
+static grn_rc
+grn_ts_op_match_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_MATCH_FILTER(match)
+}
+
+/* grn_ts_op_prefix_match_filter() filters records. */
+static grn_rc
+grn_ts_op_prefix_match_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_MATCH_FILTER(prefix_match)
+}
+
+/* grn_ts_op_suffix_match_filter() filters records. */
+static grn_rc
+grn_ts_op_suffix_match_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ GRN_TS_OP_MATCH_FILTER(suffix_match)
+}
+#undef GRN_TS_OP_MATCH_FILTER
+
+/* grn_ts_expr_op_node_filter() filters records. */
+static grn_rc
+grn_ts_expr_op_node_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ switch (node->op_type) {
+ case GRN_TS_OP_LOGICAL_NOT: {
+ return grn_ts_op_logical_not_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_BITWISE_NOT: {
+ return grn_ts_op_bitwise_not_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_LOGICAL_AND: {
+ return grn_ts_op_logical_and_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_LOGICAL_OR: {
+ return grn_ts_op_logical_or_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_LOGICAL_SUB: {
+ return grn_ts_op_logical_sub_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_BITWISE_AND: {
+ return grn_ts_op_bitwise_and_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_BITWISE_OR: {
+ return grn_ts_op_bitwise_or_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_BITWISE_XOR: {
+ return grn_ts_op_bitwise_xor_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_EQUAL: {
+ return grn_ts_op_equal_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_NOT_EQUAL: {
+ return grn_ts_op_not_equal_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_LESS: {
+ return grn_ts_op_less_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_LESS_EQUAL: {
+ return grn_ts_op_less_equal_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_GREATER: {
+ return grn_ts_op_greater_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_GREATER_EQUAL: {
+ return grn_ts_op_greater_equal_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_MATCH: {
+ return grn_ts_op_match_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_PREFIX_MATCH: {
+ return grn_ts_op_prefix_match_filter(ctx, node, in, n_in, out, n_out);
+ }
+ case GRN_TS_OP_SUFFIX_MATCH: {
+ return grn_ts_op_suffix_match_filter(ctx, node, in, n_in, out, n_out);
+ }
+ // TODO: Add operators.
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
+ "operator not supported: %d", node->op_type);
+ }
+ }
+}
+
+#define GRN_TS_OP_SIGN_ADJUST(type)\
+ size_t i;\
+ grn_ts_float *buf_ptr;\
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], io, n_io,\
+ &node->bufs[0]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ buf_ptr = (grn_ts_float *)node->bufs[0].ptr;\
+ for (i = 0; i < n_io; i++) {\
+ grn_ts_float result = grn_ts_op_ ## type ## _float(buf_ptr[i]);\
+ io[i].score = (grn_ts_score)result;\
+ if (!isfinite(io[i].score)) {\
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid score: %g", result);\
+ }\
+ }\
+ return GRN_SUCCESS;
+/* grn_ts_op_positive_adjust() updates scores. */
+static grn_rc
+grn_ts_op_positive_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ GRN_TS_OP_SIGN_ADJUST(positive)
+}
+
+/* grn_ts_op_negative_adjust() updates scores. */
+static grn_rc
+grn_ts_op_negative_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ GRN_TS_OP_SIGN_ADJUST(negative)
+}
+#undef GRN_TS_OP_SIGN_ADJUST
+
+/* grn_ts_op_float_adjust() updates scores. */
+static grn_rc
+grn_ts_op_float_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ size_t i;
+ grn_ts_int *buf_ptr;
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], io, n_io,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ buf_ptr = (grn_ts_int *)node->bufs[0].ptr;
+ for (i = 0; i < n_io; i++) {
+ grn_ts_float result;
+ rc = grn_ts_op_float(ctx, buf_ptr[i], &result);
+ io[i].score = (grn_ts_score)result;
+ if (!isfinite(io[i].score)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid score: %g", result);
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+#define GRN_TS_OP_ARITH_ADJUST(type)\
+ grn_rc rc;\
+ size_t i;\
+ grn_ts_float *buf_ptrs[2];\
+ for (i = 0; i < 2; i++) {\
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], io, n_io,\
+ &node->bufs[i]);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ }\
+ buf_ptrs[0] = (grn_ts_float *)node->bufs[0].ptr;\
+ buf_ptrs[1] = (grn_ts_float *)node->bufs[1].ptr;\
+ for (i = 0; i < n_io; i++) {\
+ grn_ts_float result;\
+ rc = grn_ts_op_ ## type ## _float_float(ctx, buf_ptrs[0][i],\
+ buf_ptrs[1][i], &result);\
+ io[i].score = (grn_ts_score)result;\
+ if (!isfinite(io[i].score)) {\
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid score: %g", result);\
+ }\
+ }\
+ return GRN_SUCCESS;
+/* grn_ts_op_plus_adjust() updates scores. */
+static grn_rc
+grn_ts_op_plus_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ GRN_TS_OP_ARITH_ADJUST(plus)
+}
+
+/* grn_ts_op_minus_adjust() updates scores. */
+static grn_rc
+grn_ts_op_minus_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ GRN_TS_OP_ARITH_ADJUST(minus)
+}
+
+/* grn_ts_op_multiplication_adjust() updates scores. */
+static grn_rc
+grn_ts_op_multiplication_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ GRN_TS_OP_ARITH_ADJUST(multiplication)
+}
+
+/* grn_ts_op_division_adjust() updates scores. */
+static grn_rc
+grn_ts_op_division_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ GRN_TS_OP_ARITH_ADJUST(division)
+}
+
+/* grn_ts_op_modulus_adjust() updates scores. */
+static grn_rc
+grn_ts_op_modulus_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ GRN_TS_OP_ARITH_ADJUST(modulus)
+}
+#undef GRN_TS_OP_ARITH_ADJUST
+
+/* grn_ts_expr_op_node_adjust() updates scores. */
+static grn_rc
+grn_ts_expr_op_node_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ switch (node->op_type) {
+ case GRN_TS_OP_POSITIVE: {
+ return grn_ts_op_positive_adjust(ctx, node, io, n_io);
+ }
+ case GRN_TS_OP_NEGATIVE: {
+ return grn_ts_op_negative_adjust(ctx, node, io, n_io);
+ }
+ case GRN_TS_OP_FLOAT: {
+ return grn_ts_op_float_adjust(ctx, node, io, n_io);
+ }
+ case GRN_TS_OP_PLUS: {
+ return grn_ts_op_plus_adjust(ctx, node, io, n_io);
+ }
+ case GRN_TS_OP_MINUS: {
+ return grn_ts_op_minus_adjust(ctx, node, io, n_io);
+ }
+ case GRN_TS_OP_MULTIPLICATION: {
+ return grn_ts_op_multiplication_adjust(ctx, node, io, n_io);
+ }
+ case GRN_TS_OP_DIVISION: {
+ return grn_ts_op_division_adjust(ctx, node, io, n_io);
+ }
+ case GRN_TS_OP_MODULUS: {
+ return grn_ts_op_modulus_adjust(ctx, node, io, n_io);
+ }
+ // TODO: Add operators.
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
+ "operator not supported: %d", node->op_type);
+ }
+ }
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_bridge_node.
+ */
+
+enum { GRN_TS_EXPR_BRIDGE_NODE_N_BUFS = 2 };
+
+typedef struct {
+ GRN_TS_EXPR_NODE_COMMON_MEMBERS
+ grn_ts_expr_node *src;
+ grn_ts_expr_node *dest;
+ grn_ts_buf bufs[GRN_TS_EXPR_BRIDGE_NODE_N_BUFS];
+} grn_ts_expr_bridge_node;
+
+/* grn_ts_expr_bridge_node_init() initializes a node. */
+static void
+grn_ts_expr_bridge_node_init(grn_ctx *ctx, grn_ts_expr_bridge_node *node)
+{
+ size_t i;
+ memset(node, 0, sizeof(*node));
+ node->type = GRN_TS_EXPR_BRIDGE_NODE;
+ node->src = NULL;
+ node->dest = NULL;
+ for (i = 0; i < GRN_TS_EXPR_BRIDGE_NODE_N_BUFS; i++) {
+ grn_ts_buf_init(ctx, &node->bufs[i]);
+ }
+}
+
+/* grn_ts_expr_bridge_node_fin() finalizes a node. */
+static void
+grn_ts_expr_bridge_node_fin(grn_ctx *ctx, grn_ts_expr_bridge_node *node)
+{
+ size_t i;
+ for (i = 0; i < GRN_TS_EXPR_BRIDGE_NODE_N_BUFS; i++) {
+ grn_ts_buf_fin(ctx, &node->bufs[i]);
+ }
+ if (node->dest) {
+ grn_ts_expr_node_close(ctx, node->dest);
+ }
+ if (node->src) {
+ grn_ts_expr_node_close(ctx, node->src);
+ }
+}
+
+grn_rc
+grn_ts_expr_bridge_node_open(grn_ctx *ctx, grn_ts_expr_node *src,
+ grn_ts_expr_node *dest, grn_ts_expr_node **node)
+{
+ grn_ts_expr_bridge_node *new_node = GRN_MALLOCN(grn_ts_expr_bridge_node, 1);
+ if (!new_node) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_expr_bridge_node));
+ }
+ grn_ts_expr_bridge_node_init(ctx, new_node);
+ new_node->data_kind = dest->data_kind;
+ new_node->data_type = dest->data_type;
+ new_node->src = src;
+ new_node->dest = dest;
+ *node = (grn_ts_expr_node *)new_node;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_bridge_node_close() destroys a node. */
+static void
+grn_ts_expr_bridge_node_close(grn_ctx *ctx, grn_ts_expr_bridge_node *node)
+{
+ grn_ts_expr_bridge_node_fin(ctx, node);
+ GRN_FREE(node);
+}
+
+/* grn_ts_expr_bridge_node_evaluate() evaluates a bridge. */
+static grn_rc
+grn_ts_expr_bridge_node_evaluate(grn_ctx *ctx, grn_ts_expr_bridge_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out)
+{
+ grn_ts_record *tmp;
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->src, in, n_in,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ tmp = (grn_ts_record *)node->bufs[0].ptr;
+ return grn_ts_expr_node_evaluate(ctx, node->dest, tmp, n_in, out);
+}
+
+/* grn_ts_expr_bridge_node_filter() filters records. */
+static grn_rc
+grn_ts_expr_bridge_node_filter(grn_ctx *ctx, grn_ts_expr_bridge_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ size_t i, count;
+ grn_ts_bool *values;
+ grn_ts_record *tmp;
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->src, in, n_in,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ tmp = (grn_ts_record *)node->bufs[0].ptr;
+ rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->dest, in, n_in,
+ &node->bufs[1]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ values = (grn_ts_bool *)&node->bufs[1].ptr;
+ for (i = 0, count = 0; i < n_in; i++) {
+ if (values[i]) {
+ out[count++] = in[i];
+ }
+ }
+ *n_out = count;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_bridge_node_adjust() updates scores. */
+static grn_rc
+grn_ts_expr_bridge_node_adjust(grn_ctx *ctx, grn_ts_expr_bridge_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ size_t i;
+ grn_ts_record *tmp;
+ grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->src, io, n_io,
+ &node->bufs[0]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ tmp = (grn_ts_record *)node->bufs[0].ptr;
+ rc = grn_ts_expr_node_adjust(ctx, node->dest, tmp, n_io);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ for (i = 0; i < n_io; i++) {
+ io[i].score = tmp[i].score;
+ }
+ return GRN_SUCCESS;
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_node.
+ */
+
+#define GRN_TS_EXPR_NODE_CLOSE_CASE(TYPE, type)\
+ case GRN_TS_EXPR_ ## TYPE ## _NODE: {\
+ grn_ts_expr_ ## type ## _node *type ## _node;\
+ type ## _node = (grn_ts_expr_ ## type ## _node *)node;\
+ grn_ts_expr_ ## type ## _node_close(ctx, type ## _node);\
+ return;\
+ }
+void
+grn_ts_expr_node_close(grn_ctx *ctx, grn_ts_expr_node *node)
+{
+ switch (node->type) {
+ GRN_TS_EXPR_NODE_CLOSE_CASE(ID, id)
+ GRN_TS_EXPR_NODE_CLOSE_CASE(SCORE, score)
+ GRN_TS_EXPR_NODE_CLOSE_CASE(KEY, key)
+ GRN_TS_EXPR_NODE_CLOSE_CASE(VALUE, value)
+ GRN_TS_EXPR_NODE_CLOSE_CASE(CONST, const)
+ GRN_TS_EXPR_NODE_CLOSE_CASE(COLUMN, column)
+ GRN_TS_EXPR_NODE_CLOSE_CASE(OP, op)
+ GRN_TS_EXPR_NODE_CLOSE_CASE(BRIDGE, bridge)
+ }
+}
+#undef GRN_TS_EXPR_NODE_CLOSE_CASE
+
+/* grn_ts_expr_node_deref_once() resolves a reference. */
+static grn_rc
+grn_ts_expr_node_deref_once(grn_ctx *ctx, grn_ts_expr_node *in,
+ grn_ts_expr_node **out)
+{
+ grn_rc rc;
+ grn_id table_id = in->data_type;
+ grn_ts_expr_node *key_node, *bridge_node;
+ grn_obj *table = grn_ctx_at(ctx, table_id);
+ if (!table) {
+ GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "grn_ctx_at failed: %d", table_id);
+ }
+ if (!grn_ts_obj_is_table(ctx, table)) {
+ grn_obj_unlink(ctx, table);
+ GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "not table: %d", table_id);
+ }
+ rc = grn_ts_expr_key_node_open(ctx, table, &key_node);
+ grn_obj_unlink(ctx, table);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_bridge_node_open(ctx, in, key_node, &bridge_node);
+ if (rc != GRN_SUCCESS) {
+ grn_ts_expr_node_close(ctx, key_node);
+ return rc;
+ }
+ *out = bridge_node;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_node_deref(grn_ctx *ctx, grn_ts_expr_node **node_ptr)
+{
+ grn_ts_expr_node *node = *node_ptr, **in_ptr = NULL;
+ while ((node->data_kind & ~GRN_TS_VECTOR_FLAG) == GRN_TS_REF) {
+ grn_ts_expr_node *new_node;
+ grn_rc rc = grn_ts_expr_node_deref_once(ctx, node, &new_node);
+ if (rc != GRN_SUCCESS) {
+ if (in_ptr) {
+ *in_ptr = NULL;
+ grn_ts_expr_node_close(ctx, node);
+ }
+ return rc;
+ }
+ if (node == *node_ptr) {
+ grn_ts_expr_bridge_node *bridge_node;
+ bridge_node = (grn_ts_expr_bridge_node *)new_node;
+ if (bridge_node->src != node) {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "broken bridge node");
+ }
+ in_ptr = &bridge_node->src;
+ }
+ node = new_node;
+ }
+ *node_ptr = node;
+ return GRN_SUCCESS;
+}
+
+#define GRN_TS_EXPR_NODE_EVALUATE_CASE(TYPE, type)\
+ case GRN_TS_EXPR_ ## TYPE ## _NODE: {\
+ grn_ts_expr_ ## type ## _node *type ## _node;\
+ type ## _node = (grn_ts_expr_ ## type ## _node *)node;\
+ return grn_ts_expr_ ## type ## _node_evaluate(ctx, type ## _node,\
+ in, n_in, out);\
+ }
+grn_rc
+grn_ts_expr_node_evaluate(grn_ctx *ctx, grn_ts_expr_node *node,
+ const grn_ts_record *in, size_t n_in, void *out)
+{
+ switch (node->type) {
+ GRN_TS_EXPR_NODE_EVALUATE_CASE(ID, id)
+ GRN_TS_EXPR_NODE_EVALUATE_CASE(SCORE, score)
+ GRN_TS_EXPR_NODE_EVALUATE_CASE(KEY, key)
+ GRN_TS_EXPR_NODE_EVALUATE_CASE(VALUE, value)
+ GRN_TS_EXPR_NODE_EVALUATE_CASE(CONST, const)
+ GRN_TS_EXPR_NODE_EVALUATE_CASE(COLUMN, column)
+ GRN_TS_EXPR_NODE_EVALUATE_CASE(OP, op)
+ GRN_TS_EXPR_NODE_EVALUATE_CASE(BRIDGE, bridge)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT,
+ "invalid node type: %d", node->type);
+ }
+ }
+}
+#undef GRN_TS_EXPR_NODE_EVALUATE_CASE
+
+#define GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(KIND, kind)\
+ case GRN_TS_ ## KIND: {\
+ grn_rc rc = grn_ts_buf_reserve(ctx, out, sizeof(grn_ts_ ## kind) * n_in);\
+ if (rc != GRN_SUCCESS) {\
+ return rc;\
+ }\
+ return grn_ts_expr_node_evaluate(ctx, node, in, n_in, out->ptr);\
+ }
+#define GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(KIND, kind)\
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(KIND ## _VECTOR, kind ## _vector)
+grn_rc
+grn_ts_expr_node_evaluate_to_buf(grn_ctx *ctx, grn_ts_expr_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_buf *out)
+{
+ switch (node->data_kind) {
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(BOOL, bool)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(INT, int)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(FLOAT, float)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(TIME, time)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(TEXT, text)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(GEO, geo)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(REF, ref)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(BOOL, bool)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(INT, int)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(FLOAT, float)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(TIME, time)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(TEXT, text)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(GEO, geo)
+ GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(REF, ref)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT,
+ "invalid data kind: %d", node->data_kind);
+ }
+ }
+}
+#undef GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE
+#undef GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE
+
+#define GRN_TS_EXPR_NODE_FILTER_CASE(TYPE, type)\
+ case GRN_TS_EXPR_ ## TYPE ## _NODE: {\
+ grn_ts_expr_ ## type ## _node *type ## _node;\
+ type ## _node = (grn_ts_expr_ ## type ## _node *)node;\
+ return grn_ts_expr_ ## type ## _node_filter(ctx, type ## _node,\
+ in, n_in, out, n_out);\
+ }
+grn_rc
+grn_ts_expr_node_filter(grn_ctx *ctx, grn_ts_expr_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out)
+{
+ if (node->data_kind != GRN_TS_BOOL) {
+ GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
+ "invalid data kind: %d", node->data_kind);
+ }
+ switch (node->type) {
+ GRN_TS_EXPR_NODE_FILTER_CASE(KEY, key)
+ GRN_TS_EXPR_NODE_FILTER_CASE(VALUE, value)
+ GRN_TS_EXPR_NODE_FILTER_CASE(CONST, const)
+ GRN_TS_EXPR_NODE_FILTER_CASE(COLUMN, column)
+ GRN_TS_EXPR_NODE_FILTER_CASE(OP, op)
+ GRN_TS_EXPR_NODE_FILTER_CASE(BRIDGE, bridge)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
+ "invalid node type: %d", node->type);
+ }
+ }
+}
+#undef GRN_TS_EXPR_NODE_FILTER_CASE
+
+#define GRN_TS_EXPR_NODE_ADJUST_CASE(TYPE, type)\
+ case GRN_TS_EXPR_ ## TYPE ## _NODE: {\
+ grn_ts_expr_ ## type ## _node *type ## _node;\
+ type ## _node = (grn_ts_expr_ ## type ## _node *)node;\
+ return grn_ts_expr_ ## type ## _node_adjust(ctx, type ## _node, io, n_io);\
+ }
+grn_rc
+grn_ts_expr_node_adjust(grn_ctx *ctx, grn_ts_expr_node *node,
+ grn_ts_record *io, size_t n_io)
+{
+ if (node->data_kind != GRN_TS_FLOAT) {
+ GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
+ "invalid data kind: %d", node->data_kind);
+ }
+ switch (node->type) {
+ GRN_TS_EXPR_NODE_ADJUST_CASE(SCORE, score)
+ GRN_TS_EXPR_NODE_ADJUST_CASE(KEY, key)
+ GRN_TS_EXPR_NODE_ADJUST_CASE(VALUE, value)
+ GRN_TS_EXPR_NODE_ADJUST_CASE(CONST, const)
+ GRN_TS_EXPR_NODE_ADJUST_CASE(COLUMN, column)
+ GRN_TS_EXPR_NODE_ADJUST_CASE(OP, op)
+ GRN_TS_EXPR_NODE_ADJUST_CASE(BRIDGE, bridge)
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
+ "invalid node type: %d", node->type);
+ }
+ }
+}
+#undef GRN_TS_EXPR_NODE_ADJUST_CASE
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.h b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.h
new file mode 100644
index 00000000000..40e7022f10f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.h
@@ -0,0 +1,128 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#include "ts_buf.h"
+#include "ts_op.h"
+#include "ts_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ GRN_TS_EXPR_ID_NODE, /* ID (_id). */
+ GRN_TS_EXPR_SCORE_NODE, /* Score (_score). */
+ GRN_TS_EXPR_KEY_NODE, /* Key (_key). */
+ GRN_TS_EXPR_VALUE_NODE, /* Embedded value (_value). */
+ GRN_TS_EXPR_CONST_NODE, /* Const. */
+ GRN_TS_EXPR_COLUMN_NODE, /* Column. */
+ GRN_TS_EXPR_OP_NODE, /* Operator. */
+ GRN_TS_EXPR_BRIDGE_NODE /* Bridge to a subexpression. */
+} grn_ts_expr_node_type;
+
+#define GRN_TS_EXPR_NODE_COMMON_MEMBERS\
+ grn_ts_expr_node_type type; /* Node type. */\
+ grn_ts_data_kind data_kind; /* Abstract data type. */\
+ grn_ts_data_type data_type; /* Detailed data type. */
+
+typedef struct {
+ GRN_TS_EXPR_NODE_COMMON_MEMBERS
+} grn_ts_expr_node;
+
+/* grn_ts_expr_id_node_open() creates a node associated with IDs (_id). */
+grn_rc grn_ts_expr_id_node_open(grn_ctx *ctx, grn_ts_expr_node **node);
+
+/*
+ * grn_ts_expr_score_node_open() creates a node associated with scores
+ * (_score).
+ */
+grn_rc grn_ts_expr_score_node_open(grn_ctx *ctx, grn_ts_expr_node **node);
+
+/* grn_ts_expr_key_node_open() creates a node associated with keys (_key). */
+grn_rc grn_ts_expr_key_node_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_expr_node **node);
+
+/*
+ * grn_ts_expr_value_node_open() creates a node associated with values
+ * (_value).
+ */
+grn_rc grn_ts_expr_value_node_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_expr_node **node);
+
+/* grn_ts_expr_const_node_open() creates a node associated with a const. */
+grn_rc grn_ts_expr_const_node_open(grn_ctx *ctx, grn_ts_data_kind data_kind,
+ grn_ts_data_type data_type,
+ grn_ts_any value, grn_ts_expr_node **node);
+
+/* grn_ts_expr_column_node_open() creates a node associated with a column. */
+grn_rc grn_ts_expr_column_node_open(grn_ctx *ctx, grn_obj *column,
+ grn_ts_expr_node **node);
+
+/*
+ * grn_ts_expr_op_node_open() creates a node associated with an operator.
+ * Note that argument nodes are destroyed on failure.
+ */
+grn_rc grn_ts_expr_op_node_open(grn_ctx *ctx, grn_ts_op_type op_type,
+ grn_ts_expr_node **args, size_t n_args,
+ grn_ts_expr_node **node);
+
+/* grn_ts_expr_bridge_node_open() creates a node associated with a bridge. */
+grn_rc grn_ts_expr_bridge_node_open(grn_ctx *ctx, grn_ts_expr_node *src,
+ grn_ts_expr_node *dest,
+ grn_ts_expr_node **node);
+
+/* grn_ts_expr_node_close() destroys a node. */
+void grn_ts_expr_node_close(grn_ctx *ctx, grn_ts_expr_node *node);
+
+/*
+ * grn_ts_expr_node_deref() resolves references.
+ *
+ * If *node_ptr refers to a reference node, grn_ts_expr_node_deref() creates a
+ * key node associated with the destination table and creates a bridge node
+ * from *node_ptr to the key node. If the data kind of the bridge node is
+ * GRN_TS_REF, references are recursively resolved.
+ */
+grn_rc grn_ts_expr_node_deref(grn_ctx *ctx, grn_ts_expr_node **node_ptr);
+
+/* grn_ts_expr_node_evaluate() evaluates a subtree. */
+grn_rc grn_ts_expr_node_evaluate(grn_ctx *ctx, grn_ts_expr_node *node,
+ const grn_ts_record *in, size_t n_in,
+ void *out);
+
+/* grn_ts_expr_node_evaluate_to_buf() evaluates a subtree. */
+grn_rc grn_ts_expr_node_evaluate_to_buf(grn_ctx *ctx, grn_ts_expr_node *node,
+ const grn_ts_record *in, size_t n_in,
+ grn_ts_buf *out);
+
+/* grn_ts_expr_node_filter() filters records. */
+grn_rc grn_ts_expr_node_filter(grn_ctx *ctx, grn_ts_expr_node *node,
+ grn_ts_record *in, size_t n_in,
+ grn_ts_record *out, size_t *n_out);
+
+/* grn_ts_expr_node_adjust() updates scores. */
+grn_rc grn_ts_expr_node_adjust(grn_ctx *ctx, grn_ts_expr_node *node,
+ grn_ts_record *io, size_t n_io);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_expr_parser.c b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_parser.c
new file mode 100644
index 00000000000..425171d421a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_parser.c
@@ -0,0 +1,1329 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_expr_parser.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "../grn_ctx.h"
+
+#include "ts_log.h"
+#include "ts_str.h"
+#include "ts_util.h"
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_token.
+ */
+
+#define GRN_TS_EXPR_TOKEN_INIT(TYPE)\
+ memset(token, 0, sizeof(*token));\
+ token->type = GRN_TS_EXPR_ ## TYPE ## _TOKEN;\
+ token->src = src;
+/* grn_ts_expr_dummy_token_init() initializes a token. */
+static void
+grn_ts_expr_dummy_token_init(grn_ctx *ctx, grn_ts_expr_dummy_token *token,
+ grn_ts_str src)
+{
+ GRN_TS_EXPR_TOKEN_INIT(DUMMY)
+}
+
+/* grn_ts_expr_start_token_init() initializes a token. */
+static void
+grn_ts_expr_start_token_init(grn_ctx *ctx, grn_ts_expr_start_token *token,
+ grn_ts_str src)
+{
+ GRN_TS_EXPR_TOKEN_INIT(START)
+}
+
+/* grn_ts_expr_end_token_init() initializes a token. */
+static void
+grn_ts_expr_end_token_init(grn_ctx *ctx, grn_ts_expr_end_token *token,
+ grn_ts_str src)
+{
+ GRN_TS_EXPR_TOKEN_INIT(END)
+}
+
+/* grn_ts_expr_const_token_init() initializes a token. */
+static void
+grn_ts_expr_const_token_init(grn_ctx *ctx, grn_ts_expr_const_token *token,
+ grn_ts_str src)
+{
+ GRN_TS_EXPR_TOKEN_INIT(CONST);
+ grn_ts_buf_init(ctx, &token->buf);
+}
+
+/* grn_ts_expr_name_token_init() initializes a token. */
+static void
+grn_ts_expr_name_token_init(grn_ctx *ctx, grn_ts_expr_name_token *token,
+ grn_ts_str src)
+{
+ GRN_TS_EXPR_TOKEN_INIT(NAME);
+}
+
+/* grn_ts_expr_op_token_init() initializes a token. */
+static void
+grn_ts_expr_op_token_init(grn_ctx *ctx, grn_ts_expr_op_token *token,
+ grn_ts_str src)
+{
+ GRN_TS_EXPR_TOKEN_INIT(OP);
+}
+
+/* grn_ts_expr_bridge_token_init() initializes a token. */
+static void
+grn_ts_expr_bridge_token_init(grn_ctx *ctx, grn_ts_expr_bridge_token *token,
+ grn_ts_str src)
+{
+ GRN_TS_EXPR_TOKEN_INIT(BRIDGE)
+}
+
+/* grn_ts_expr_bracket_token_init() initializes a token. */
+static void
+grn_ts_expr_bracket_token_init(grn_ctx *ctx, grn_ts_expr_bracket_token *token,
+ grn_ts_str src)
+{
+ GRN_TS_EXPR_TOKEN_INIT(BRACKET)
+}
+#undef GRN_TS_EXPR_TOKEN_INIT
+
+/* grn_ts_expr_dummy_token_fin() finalizes a token. */
+static void
+grn_ts_expr_dummy_token_fin(grn_ctx *ctx, grn_ts_expr_dummy_token *token)
+{
+ /* Nothing to do. */
+}
+
+/* grn_ts_expr_start_token_fin() finalizes a token. */
+static void
+grn_ts_expr_start_token_fin(grn_ctx *ctx, grn_ts_expr_start_token *token)
+{
+ /* Nothing to do. */
+}
+
+/* grn_ts_expr_end_token_fin() finalizes a token. */
+static void
+grn_ts_expr_end_token_fin(grn_ctx *ctx, grn_ts_expr_end_token *token)
+{
+ /* Nothing to do. */
+}
+
+/* grn_ts_expr_const_token_fin() finalizes a token. */
+static void
+grn_ts_expr_const_token_fin(grn_ctx *ctx, grn_ts_expr_const_token *token)
+{
+ grn_ts_buf_fin(ctx, &token->buf);
+}
+
+/* grn_ts_expr_name_token_fin() finalizes a token. */
+static void
+grn_ts_expr_name_token_fin(grn_ctx *ctx, grn_ts_expr_name_token *token)
+{
+ /* Nothing to do. */
+}
+
+/* grn_ts_expr_op_token_fin() finalizes a token. */
+static void
+grn_ts_expr_op_token_fin(grn_ctx *ctx, grn_ts_expr_op_token *token)
+{
+ /* Nothing to do. */
+}
+
+/* grn_ts_expr_bridge_token_fin() finalizes a token. */
+static void
+grn_ts_expr_bridge_token_fin(grn_ctx *ctx, grn_ts_expr_bridge_token *token)
+{
+ /* Nothing to do. */
+}
+
+/* grn_ts_expr_bracket_token_fin() finalizes a token. */
+static void
+grn_ts_expr_bracket_token_fin(grn_ctx *ctx, grn_ts_expr_bracket_token *token)
+{
+ /* Nothing to do. */
+}
+
+#define GRN_TS_EXPR_TOKEN_OPEN(TYPE, type)\
+ grn_ts_expr_ ## type ## _token *new_token;\
+ new_token = GRN_MALLOCN(grn_ts_expr_ ## type ## _token, 1);\
+ if (!new_token) {\
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,\
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",\
+ sizeof(grn_ts_expr_ ## type ## _token));\
+ }\
+ grn_ts_expr_ ## type ## _token_init(ctx, new_token, src);\
+ *token = new_token;
+/* grn_ts_expr_dummy_token_open() creates a token. */
+/*
+static grn_rc
+grn_ts_expr_dummy_token_open(grn_ctx *ctx, grn_ts_str src,
+ grn_ts_expr_dummy_token **token)
+{
+ GRN_TS_EXPR_TOKEN_OPEN(DUMMY, dummy)
+ return GRN_SUCCESS;
+}
+*/
+
+/* grn_ts_expr_start_token_open() creates a token. */
+static grn_rc
+grn_ts_expr_start_token_open(grn_ctx *ctx, grn_ts_str src,
+ grn_ts_expr_start_token **token)
+{
+ GRN_TS_EXPR_TOKEN_OPEN(START, start)
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_end_token_open() creates a token. */
+static grn_rc
+grn_ts_expr_end_token_open(grn_ctx *ctx, grn_ts_str src,
+ grn_ts_expr_end_token **token)
+{
+ GRN_TS_EXPR_TOKEN_OPEN(END, end)
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_const_token_open() creates a token. */
+static grn_rc
+grn_ts_expr_const_token_open(grn_ctx *ctx, grn_ts_str src,
+ grn_ts_expr_const_token **token)
+ {
+ GRN_TS_EXPR_TOKEN_OPEN(CONST, const)
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_name_token_open() creates a token. */
+static grn_rc
+grn_ts_expr_name_token_open(grn_ctx *ctx, grn_ts_str src,
+ grn_ts_expr_name_token **token)
+{
+ GRN_TS_EXPR_TOKEN_OPEN(NAME, name)
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_op_token_open() creates a token. */
+static grn_rc
+grn_ts_expr_op_token_open(grn_ctx *ctx, grn_ts_str src, grn_ts_op_type op_type,
+ grn_ts_expr_op_token **token)
+{
+ GRN_TS_EXPR_TOKEN_OPEN(OP, op)
+ new_token->op_type = op_type;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_bridge_token_open() creates a token. */
+static grn_rc
+grn_ts_expr_bridge_token_open(grn_ctx *ctx, grn_ts_str src,
+ grn_ts_expr_bridge_token **token)
+{
+ GRN_TS_EXPR_TOKEN_OPEN(BRIDGE, bridge)
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_bracket_token_open() creates a token. */
+static grn_rc
+grn_ts_expr_bracket_token_open(grn_ctx *ctx, grn_ts_str src,
+ grn_ts_expr_bracket_token **token)
+{
+ GRN_TS_EXPR_TOKEN_OPEN(BRACKET, bracket)
+ return GRN_SUCCESS;
+}
+#undef GRN_TS_EXPR_TOKEN_OPEN
+
+#define GRN_TS_EXPR_TOKEN_CLOSE_CASE(TYPE, type)\
+ case GRN_TS_EXPR_ ## TYPE ## _TOKEN: {\
+ grn_ts_expr_ ## type ## _token *type ## _token;\
+ type ## _token = (grn_ts_expr_ ## type ## _token *)token;\
+ grn_ts_expr_ ## type ## _token_fin(ctx, type ## _token);\
+ break;\
+ }
+/* grn_ts_expr_token_close() destroys a token. */
+static void
+grn_ts_expr_token_close(grn_ctx *ctx, grn_ts_expr_token *token)
+{
+ switch (token->type) {
+ GRN_TS_EXPR_TOKEN_CLOSE_CASE(DUMMY, dummy)
+ GRN_TS_EXPR_TOKEN_CLOSE_CASE(START, start)
+ GRN_TS_EXPR_TOKEN_CLOSE_CASE(END, end)
+ GRN_TS_EXPR_TOKEN_CLOSE_CASE(CONST, const)
+ GRN_TS_EXPR_TOKEN_CLOSE_CASE(NAME, name)
+ GRN_TS_EXPR_TOKEN_CLOSE_CASE(OP, op)
+ GRN_TS_EXPR_TOKEN_CLOSE_CASE(BRACKET, bracket)
+ GRN_TS_EXPR_TOKEN_CLOSE_CASE(BRIDGE, bridge)
+ }
+ GRN_FREE(token);
+}
+#undef GRN_TS_EXPR_TOKEN_CLOSE_CASE
+
+/*-------------------------------------------------------------
+ * grn_ts_expr_parser.
+ */
+
+/* grn_ts_expr_parser_init() initializes a parser. */
+static void
+grn_ts_expr_parser_init(grn_ctx *ctx, grn_ts_expr_parser *parser)
+{
+ memset(parser, 0, sizeof(*parser));
+ parser->builder = NULL;
+ grn_ts_buf_init(ctx, &parser->str_buf);
+ parser->tokens = NULL;
+ parser->dummy_tokens = NULL;
+ parser->stack = NULL;
+}
+
+/* grn_ts_expr_parser_fin() finalizes a parser. */
+static void
+grn_ts_expr_parser_fin(grn_ctx *ctx, grn_ts_expr_parser *parser)
+{
+ if (parser->stack) {
+ GRN_FREE(parser->stack);
+ }
+ if (parser->dummy_tokens) {
+ size_t i;
+ for (i = 0; i < parser->n_dummy_tokens; i++) {
+ grn_ts_expr_dummy_token_fin(ctx, &parser->dummy_tokens[i]);
+ }
+ GRN_FREE(parser->dummy_tokens);
+ }
+ if (parser->tokens) {
+ size_t i;
+ for (i = 0; i < parser->n_tokens; i++) {
+ grn_ts_expr_token_close(ctx, parser->tokens[i]);
+ }
+ GRN_FREE(parser->tokens);
+ }
+ grn_ts_buf_fin(ctx, &parser->str_buf);
+ if (parser->builder) {
+ grn_ts_expr_builder_close(ctx, parser->builder);
+ }
+}
+
+grn_rc
+grn_ts_expr_parser_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_expr_parser **parser)
+{
+ grn_rc rc;
+ grn_ts_expr_parser *new_parser;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!table || !grn_ts_obj_is_table(ctx, table) || !parser) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ new_parser = GRN_MALLOCN(grn_ts_expr_parser, 1);
+ if (!new_parser) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_expr_parser));
+ }
+ grn_ts_expr_parser_init(ctx, new_parser);
+ rc = grn_ts_expr_builder_open(ctx, table, &new_parser->builder);
+ if (rc != GRN_SUCCESS) {
+ grn_ts_expr_parser_fin(ctx, new_parser);
+ GRN_FREE(new_parser);
+ return rc;
+ }
+ *parser = new_parser;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_expr_parser_close(grn_ctx *ctx, grn_ts_expr_parser *parser)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!parser) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ grn_ts_expr_parser_fin(ctx, parser);
+ GRN_FREE(parser);
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_tokenize_start() creates the start token. */
+static grn_rc
+grn_ts_expr_parser_tokenize_start(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr_token **token)
+{
+ grn_ts_str token_str = { str.ptr, 0 };
+ grn_ts_expr_start_token *new_token;
+ grn_rc rc = grn_ts_expr_start_token_open(ctx, token_str, &new_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ *token = (grn_ts_expr_token *)new_token;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_tokenize_end() creates the end token. */
+static grn_rc
+grn_ts_expr_parser_tokenize_end(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr_token **token)
+{
+ grn_ts_str token_str = { str.ptr, 0 };
+ grn_ts_expr_end_token *new_token;
+ grn_rc rc = grn_ts_expr_end_token_open(ctx, token_str, &new_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ *token = (grn_ts_expr_token *)new_token;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_tokenize_number() tokenizes an Int or Float literal. */
+static grn_rc
+grn_ts_expr_parser_tokenize_number(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr_token **token)
+{
+ char *end;
+ grn_rc rc;
+ grn_ts_int int_value;
+ grn_ts_str token_str;
+ grn_ts_expr_const_token *new_token;
+
+ int_value = strtol(str.ptr, &end, 0);
+ if ((end != str.ptr) && (*end != '.') && (*end != 'e')) {
+ if (grn_ts_byte_is_name_char(*end)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT,
+ "unterminated Int literal: \"%.*s\"",
+ (int)str.size, str.ptr);
+ }
+ token_str.ptr = str.ptr;
+ token_str.size = end - str.ptr;
+ rc = grn_ts_expr_const_token_open(ctx, token_str, &new_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ new_token->data_kind = GRN_TS_INT;
+ new_token->content.as_int = int_value;
+ } else {
+ grn_ts_float float_value = strtod(str.ptr, &end);
+ if (end == str.ptr) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "invalid number literal: \"%.*s\"",
+ (int)str.size, str.ptr);
+ }
+ if (grn_ts_byte_is_name_char(*end)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT,
+ "unterminated Float literal: \"%.*s\"",
+ (int)str.size, str.ptr);
+ }
+ token_str.ptr = str.ptr;
+ token_str.size = end - str.ptr;
+ rc = grn_ts_expr_const_token_open(ctx, token_str, &new_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ new_token->data_kind = GRN_TS_FLOAT;
+ new_token->content.as_float = float_value;
+ }
+ *token = (grn_ts_expr_token *)new_token;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_tokenize_text() tokenizes a Text literal. */
+static grn_rc
+grn_ts_expr_parser_tokenize_text(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr_token **token)
+{
+ size_t i, n_escapes = 0;
+ grn_rc rc;
+ grn_ts_str token_str;
+ grn_ts_expr_const_token *new_token;
+ for (i = 1; i < str.size; i++) {
+ if (str.ptr[i] == '\\') {
+ i++;
+ n_escapes++;
+ } else if (str.ptr[i] == '"') {
+ break;
+ }
+ }
+ if (i >= str.size) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "no closing double quote: \"%.*s\"",
+ (int)str.size, str.ptr);
+ }
+ token_str.ptr = str.ptr;
+ token_str.size = i + 1;
+ rc = grn_ts_expr_const_token_open(ctx, token_str, &new_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ new_token->data_kind = GRN_TS_TEXT;
+ if (n_escapes) {
+ char *buf_ptr;
+ const char *str_ptr = str.ptr + 1;
+ size_t size = token_str.size - 2 - n_escapes;
+ rc = grn_ts_buf_resize(ctx, &new_token->buf, size);
+ if (rc != GRN_SUCCESS) {
+ grn_ts_expr_token_close(ctx, (grn_ts_expr_token *)new_token);
+ return rc;
+ }
+ buf_ptr = (char *)new_token->buf.ptr;
+ for (i = 0; i < size; i++) {
+ if (str_ptr[i] == '\\') {
+ str_ptr++;
+ }
+ buf_ptr[i] = str_ptr[i];
+ }
+ new_token->content.as_text.ptr = buf_ptr;
+ new_token->content.as_text.size = size;
+ } else {
+ new_token->content.as_text.ptr = token_str.ptr + 1;
+ new_token->content.as_text.size = token_str.size - 2;
+ }
+ *token = (grn_ts_expr_token *)new_token;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_tokenize_name() tokenizes a Bool literal or a name. */
+static grn_rc
+grn_ts_expr_parser_tokenize_name(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr_token **token)
+{
+ size_t i;
+ grn_ts_str token_str;
+ for (i = 1; i < str.size; i++) {
+ if (!grn_ts_byte_is_name_char(str.ptr[i])) {
+ break;
+ }
+ }
+ token_str.ptr = str.ptr;
+ token_str.size = i;
+
+ if (grn_ts_str_is_bool(token_str)) {
+ grn_ts_expr_const_token *new_token;
+ grn_rc rc = grn_ts_expr_const_token_open(ctx, token_str, &new_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ new_token->data_kind = GRN_TS_BOOL;
+ if (token_str.ptr[0] == 't') {
+ new_token->content.as_bool = GRN_TRUE;
+ } else {
+ new_token->content.as_bool = GRN_FALSE;
+ }
+ *token = (grn_ts_expr_token *)new_token;
+ return GRN_SUCCESS;
+ }
+ return grn_ts_expr_name_token_open(ctx, token_str, token);
+}
+
+/* grn_ts_expr_parser_tokenize_bridge() tokenizes a bridge. */
+static grn_rc
+grn_ts_expr_parser_tokenize_bridge(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr_token **token)
+{
+ grn_ts_str token_str = { str.ptr, 1 };
+ grn_ts_expr_bridge_token *new_token;
+ grn_rc rc = grn_ts_expr_bridge_token_open(ctx, token_str, &new_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ *token = (grn_ts_expr_token *)new_token;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_tokenize_bracket() tokenizes a bracket. */
+static grn_rc
+grn_ts_expr_parser_tokenize_bracket(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str,
+ grn_ts_expr_token **token)
+{
+ grn_ts_str token_str = { str.ptr, 1 };
+ grn_ts_expr_bracket_token *new_token;
+ grn_rc rc = grn_ts_expr_bracket_token_open(ctx, token_str, &new_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ *token = (grn_ts_expr_token *)new_token;
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ts_expr_parsre_tokenize_sign() tokenizes an operator '+' or '-'.
+ * Note that '+' and '-' have two roles each.
+ * '+' is GRN_TS_OP_POSITIVE or GRN_TS_OP_PLUS.
+ * '-' is GRN_TS_OP_NEGATIVE or GRN_TS_OP_MINUS.
+ */
+static grn_rc
+grn_ts_expr_parser_tokenize_sign(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr_token **token)
+{
+ size_t n_args;
+ grn_rc rc;
+ grn_ts_op_type op_type;
+ grn_ts_str token_str = { str.ptr, 1 };
+ grn_ts_expr_token *prev_token = parser->tokens[parser->n_tokens - 1];
+ grn_ts_expr_op_token *new_token;
+ switch (prev_token->type) {
+ case GRN_TS_EXPR_START_TOKEN:
+ case GRN_TS_EXPR_OP_TOKEN: {
+ n_args = 1;
+ break;
+ }
+ case GRN_TS_EXPR_CONST_TOKEN:
+ case GRN_TS_EXPR_NAME_TOKEN: {
+ n_args = 2;
+ break;
+ }
+ case GRN_TS_EXPR_BRACKET_TOKEN: {
+ grn_ts_str bracket;
+ const grn_ts_expr_bracket_token *bracket_token;
+ bracket_token = (const grn_ts_expr_bracket_token *)prev_token;
+ bracket = bracket_token->src;
+ switch (bracket.ptr[0]) {
+ case '(': case '[': {
+ n_args = 1;
+ break;
+ }
+ case ')': case ']': {
+ n_args = 2;
+ break;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "undefined bracket: \"%.*s\"",
+ (int)bracket.size, bracket.ptr);
+ }
+ }
+ break;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "invalid token sequence: %d",
+ prev_token->type);
+ }
+ }
+ if (token_str.ptr[0] == '+') {
+ op_type = (n_args == 1) ? GRN_TS_OP_POSITIVE : GRN_TS_OP_PLUS;
+ } else {
+ op_type = (n_args == 1) ? GRN_TS_OP_NEGATIVE : GRN_TS_OP_MINUS;
+ }
+ rc = grn_ts_expr_op_token_open(ctx, token_str, op_type, &new_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ *token = (grn_ts_expr_token *)new_token;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_tokenize_op() tokenizes an operator. */
+static grn_rc
+grn_ts_expr_parser_tokenize_op(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr_token **token)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_ts_str token_str = str;
+ grn_ts_op_type op_type;
+ grn_ts_expr_op_token *new_token;
+ switch (str.ptr[0]) {
+ case '+': case '-': {
+ return grn_ts_expr_parser_tokenize_sign(ctx, parser, str, token);
+ }
+ case '!': {
+ if ((str.size >= 2) && (str.ptr[1] == '=')) {
+ token_str.size = 2;
+ op_type = GRN_TS_OP_NOT_EQUAL;
+ } else {
+ token_str.size = 1;
+ op_type = GRN_TS_OP_LOGICAL_NOT;
+ }
+ rc = grn_ts_expr_op_token_open(ctx, token_str, op_type, &new_token);
+ break;
+ }
+#define GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE(label, TYPE_1, TYPE_2, TYPE_3,\
+ TYPE_EQUAL)\
+ case label: {\
+ if ((str.size >= 2) && (str.ptr[1] == '=')) {\
+ token_str.size = 2;\
+ op_type = GRN_TS_OP_ ## TYPE_EQUAL;\
+ } else if ((str.size >= 2) && (str.ptr[1] == label)) {\
+ if ((str.size >= 3) && (str.ptr[2] == label)) {\
+ token_str.size = 3;\
+ op_type = GRN_TS_OP_ ## TYPE_3;\
+ } else {\
+ token_str.size = 2;\
+ op_type = GRN_TS_OP_ ## TYPE_2;\
+ }\
+ } else {\
+ token_str.size = 1;\
+ op_type = GRN_TS_OP_ ## TYPE_1;\
+ }\
+ rc = grn_ts_expr_op_token_open(ctx, token_str, op_type, &new_token);\
+ break;\
+ }
+ GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE('<', LESS, SHIFT_ARITHMETIC_LEFT,
+ SHIFT_LOGICAL_LEFT, LESS_EQUAL)
+ GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE('>', GREATER, SHIFT_ARITHMETIC_RIGHT,
+ SHIFT_LOGICAL_RIGHT, GREATER_EQUAL)
+#undef GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE
+ case '&': {
+ if ((str.size >= 2) && (str.ptr[1] == '&')) {
+ token_str.size = 2;
+ op_type = GRN_TS_OP_LOGICAL_AND;
+ } else if ((str.size >= 2) && (str.ptr[1] == '&')) {
+ token_str.size = 2;
+ op_type = GRN_TS_OP_LOGICAL_SUB;
+ } else {
+ token_str.size = 1;
+ op_type = GRN_TS_OP_BITWISE_AND;
+ }
+ rc = grn_ts_expr_op_token_open(ctx, token_str, op_type, &new_token);
+ break;
+ }
+ case '|': {
+ if ((str.size >= 2) && (str.ptr[1] == '|')) {
+ token_str.size = 2;
+ op_type = GRN_TS_OP_LOGICAL_OR;
+ } else {
+ token_str.size = 1;
+ op_type = GRN_TS_OP_BITWISE_OR;
+ }
+ rc = grn_ts_expr_op_token_open(ctx, token_str, op_type, &new_token);
+ break;
+ }
+ case '=': {
+ if ((str.size < 2) || (str.ptr[1] != '=')) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT,
+ "single equal not available: =\"%.*s\"",
+ (int)str.size, str.ptr);
+ }
+ token_str.size = 2;
+ rc = grn_ts_expr_op_token_open(ctx, token_str, GRN_TS_OP_EQUAL,
+ &new_token);
+ break;
+ }
+#define GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE(label, TYPE)\
+ case label: {\
+ token_str.size = 1;\
+ rc = grn_ts_expr_op_token_open(ctx, token_str, GRN_TS_OP_ ## TYPE,\
+ &new_token);\
+ break;\
+ }
+ GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE('~', BITWISE_NOT)
+ GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE('^', BITWISE_XOR)
+ GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE('*', MULTIPLICATION)
+ GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE('/', DIVISION)
+ GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE('%', MODULUS)
+#undef GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE
+ case '@': {
+ if ((str.size >= 2) && (str.ptr[1] == '^')) {
+ token_str.size = 2;
+ op_type = GRN_TS_OP_PREFIX_MATCH;
+ } else if ((str.size >= 2) && (str.ptr[1] == '$')) {
+ token_str.size = 2;
+ op_type = GRN_TS_OP_SUFFIX_MATCH;
+ } else {
+ token_str.size = 1;
+ op_type = GRN_TS_OP_MATCH;
+ }
+ rc = grn_ts_expr_op_token_open(ctx, token_str, op_type, &new_token);
+ break;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "invalid character: \"%.*s\"",
+ (int)str.size, str.ptr);
+ }
+ }
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ *token = (grn_ts_expr_token *)new_token;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_tokenize_next() extracts the next token. */
+static grn_rc
+grn_ts_expr_parser_tokenize_next(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr_token **token)
+{
+ grn_ts_str rest;
+ if (!parser->n_tokens) {
+ return grn_ts_expr_parser_tokenize_start(ctx, parser, str, token);
+ }
+ rest = grn_ts_str_trim_left(str);
+ if (!rest.size) {
+ return grn_ts_expr_parser_tokenize_end(ctx, parser, rest, token);
+ }
+ if (grn_ts_str_has_number_prefix(rest)) {
+ grn_ts_expr_token *prev_token;
+ if ((rest.ptr[0] != '+') && (rest.ptr[0] != '-')) {
+ return grn_ts_expr_parser_tokenize_number(ctx, parser, rest, token);
+ }
+ prev_token = parser->tokens[parser->n_tokens - 1];
+ switch (prev_token->type) {
+ case GRN_TS_EXPR_START_TOKEN:
+ case GRN_TS_EXPR_OP_TOKEN: {
+ return grn_ts_expr_parser_tokenize_number(ctx, parser, rest, token);
+ }
+ case GRN_TS_EXPR_BRACKET_TOKEN: {
+ if ((prev_token->src.ptr[0] == '(') ||
+ (prev_token->src.ptr[0] == '[')) {
+ return grn_ts_expr_parser_tokenize_number(ctx, parser, rest, token);
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ if (rest.ptr[0] == '"') {
+ return grn_ts_expr_parser_tokenize_text(ctx, parser, rest, token);
+ }
+ if (grn_ts_byte_is_name_char(rest.ptr[0])) {
+ return grn_ts_expr_parser_tokenize_name(ctx, parser, rest, token);
+ }
+ switch (rest.ptr[0]) {
+ case '(': case ')': case '[': case ']': {
+ return grn_ts_expr_parser_tokenize_bracket(ctx, parser, rest, token);
+ }
+ case '.': {
+ return grn_ts_expr_parser_tokenize_bridge(ctx, parser, rest, token);
+ }
+ default: {
+ return grn_ts_expr_parser_tokenize_op(ctx, parser, rest, token);
+ }
+ }
+}
+
+/*
+ * grn_ts_expr_parser_reserve_tokens() extends a token buffer for a new token.
+ */
+static grn_rc
+grn_ts_expr_parser_reserve_tokens(grn_ctx *ctx, grn_ts_expr_parser *parser)
+{
+ size_t i, n_bytes, new_max_n_tokens;
+ grn_ts_expr_token **new_tokens;
+ if (parser->n_tokens < parser->max_n_tokens) {
+ return GRN_SUCCESS;
+ }
+ new_max_n_tokens = parser->n_tokens * 2;
+ if (!new_max_n_tokens) {
+ new_max_n_tokens = 1;
+ }
+ n_bytes = sizeof(grn_ts_expr_token *) * new_max_n_tokens;
+ new_tokens = (grn_ts_expr_token **)GRN_REALLOC(parser->tokens, n_bytes);
+ if (!new_tokens) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE,
+ n_bytes);
+ }
+ for (i = parser->n_tokens; i < new_max_n_tokens; i++) {
+ new_tokens[i] = NULL;
+ }
+ parser->tokens = new_tokens;
+ parser->max_n_tokens = new_max_n_tokens;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_tokenize() tokenizes a string. */
+static grn_rc
+grn_ts_expr_parser_tokenize(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str)
+{
+ grn_ts_str rest = str;
+ const char *end = str.ptr + str.size;
+ grn_ts_expr_token *token = NULL;
+ GRN_TS_DEBUG("str = \"%.*s\"", (int)str.size, str.ptr);
+ do {
+ grn_rc rc = grn_ts_expr_parser_reserve_tokens(ctx, parser);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_parser_tokenize_next(ctx, parser, rest, &token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if ((token->type != GRN_TS_EXPR_START_TOKEN) &&
+ (token->type != GRN_TS_EXPR_END_TOKEN)) {
+ GRN_TS_DEBUG("token = \"%.*s\"", (int)token->src.size, token->src.ptr);
+ }
+ parser->tokens[parser->n_tokens++] = token;
+ rest.ptr = token->src.ptr + token->src.size;
+ rest.size = end - rest.ptr;
+ } while (token->type != GRN_TS_EXPR_END_TOKEN);
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_push_const() pushes a token to an expression. */
+static grn_rc
+grn_ts_expr_parser_push_const(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_expr_const_token *token)
+{
+ return grn_ts_expr_builder_push_const(ctx, parser->builder, token->data_kind,
+ GRN_DB_VOID, token->content);
+}
+
+/* grn_ts_expr_parser_push_name() pushes a token to an expression. */
+static grn_rc
+grn_ts_expr_parser_push_name(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_expr_name_token *token)
+{
+ return grn_ts_expr_builder_push_name(ctx, parser->builder, token->src);
+}
+
+/* grn_ts_expr_parser_push_op() pushes a token to an expression. */
+static grn_rc
+grn_ts_expr_parser_push_op(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_expr_op_token *token)
+{
+ return grn_ts_expr_builder_push_op(ctx, parser->builder, token->op_type);
+}
+
+/*
+ * grn_ts_expr_parser_apply_one() applies a bridge or prior operator.
+ * If there is no target, this function returns GRN_END_OF_DATA.
+ */
+// FIXME: Support a ternary operator.
+static grn_rc
+grn_ts_expr_parser_apply_one(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_op_precedence precedence_threshold)
+{
+ grn_rc rc;
+ grn_ts_str src;
+ grn_ts_expr_token **stack = parser->stack;
+ grn_ts_expr_dummy_token *dummy_token;
+ size_t n_args, depth = parser->stack_depth;
+ if (depth < 2) {
+ return GRN_END_OF_DATA;
+ }
+ if (stack[depth - 1]->type != GRN_TS_EXPR_DUMMY_TOKEN) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "argument must be dummy token");
+ }
+
+ /* Check the number of arguments. */
+ switch (stack[depth - 2]->type) {
+ case GRN_TS_EXPR_BRIDGE_TOKEN: {
+ rc = grn_ts_expr_builder_end_subexpr(ctx, parser->builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ n_args = 2;
+ break;
+ }
+ case GRN_TS_EXPR_OP_TOKEN: {
+ grn_ts_expr_op_token *op_token;
+ grn_ts_op_precedence precedence;
+ op_token = (grn_ts_expr_op_token *)stack[depth - 2];
+ precedence = grn_ts_op_get_precedence(op_token->op_type);
+ if (precedence < precedence_threshold) {
+ return GRN_END_OF_DATA;
+ }
+ rc = grn_ts_expr_parser_push_op(ctx, parser, op_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ n_args = grn_ts_op_get_n_args(op_token->op_type);
+ break;
+ }
+ default: {
+ return GRN_END_OF_DATA;
+ }
+ }
+
+ /* Concatenate the source strings. */
+ switch (n_args) {
+ case 1: {
+ grn_ts_expr_token *arg = stack[depth - 1];
+ src.ptr = stack[depth - 2]->src.ptr;
+ src.size = (arg->src.ptr + arg->src.size) - src.ptr;
+ break;
+ }
+ case 2: {
+ grn_ts_expr_token *args[2] = { stack[depth - 3], stack[depth - 1] };
+ src.ptr = args[0]->src.ptr;
+ src.size = (args[1]->src.ptr + args[1]->src.size) - src.ptr;
+ break;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
+ "invalid #arguments: %" GRN_FMT_SIZE,
+ n_args);
+ }
+ }
+
+ /* Replace the operator and argument tokens with a dummy token. */
+ dummy_token = &parser->dummy_tokens[parser->n_dummy_tokens++];
+ GRN_TS_DEBUG("dummy token: \"%.*s\"", (int)src.size, src.ptr);
+ grn_ts_expr_dummy_token_init(ctx, dummy_token, src);
+ depth -= n_args + 1;
+ stack[depth++] = dummy_token;
+ parser->stack_depth = depth;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_apply() applies bridges and prior operators. */
+static grn_rc
+grn_ts_expr_parser_apply(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_op_precedence precedence_threshold)
+{
+ for ( ; ; ) {
+ grn_rc rc = grn_ts_expr_parser_apply_one(ctx, parser,
+ precedence_threshold);
+ if (rc == GRN_END_OF_DATA) {
+ return GRN_SUCCESS;
+ } else if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+}
+
+/* grn_ts_expr_parser_analyze_op() analyzes a token. */
+static grn_rc
+grn_ts_expr_parser_analyze_op(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_expr_op_token *token)
+{
+ size_t n_args = grn_ts_op_get_n_args(token->op_type);
+ grn_ts_expr_token *ex_token = parser->stack[parser->stack_depth - 1];
+ if (n_args == 1) {
+ if (ex_token->type == GRN_TS_EXPR_DUMMY_TOKEN) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "invalid token sequence");
+ }
+ } else if (n_args == 2) {
+ grn_ts_op_precedence precedence = grn_ts_op_get_precedence(token->op_type);
+ grn_rc rc = grn_ts_expr_parser_apply(ctx, parser, precedence);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ parser->stack[parser->stack_depth++] = (grn_ts_expr_token *)token;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_analyze_bridge() analyzes a token. */
+static grn_rc
+grn_ts_expr_parser_analyze_bridge(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_expr_bridge_token *token)
+{
+ grn_rc rc = grn_ts_expr_builder_begin_subexpr(ctx, parser->builder);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ parser->stack[parser->stack_depth++] = (grn_ts_expr_token *)token;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_parser_analyze_bracket() analyzes a token. */
+static grn_rc
+grn_ts_expr_parser_analyze_bracket(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_expr_bracket_token *token)
+{
+ grn_ts_expr_token *ex_token = parser->stack[parser->stack_depth - 1];
+ switch (token->src.ptr[0]) {
+ case '(': {
+ if (ex_token->type == GRN_TS_EXPR_DUMMY_TOKEN) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "invalid token sequence");
+ }
+ parser->stack[parser->stack_depth++] = (grn_ts_expr_token *)token;
+ return GRN_SUCCESS;
+ }
+ case '[': {
+ if (ex_token->type != GRN_TS_EXPR_DUMMY_TOKEN) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "invalid token sequence");
+ }
+ parser->stack[parser->stack_depth++] = (grn_ts_expr_token *)token;
+ return GRN_SUCCESS;
+ }
+ case ')': case ']': {
+ grn_ts_expr_token *ex_ex_token;
+ grn_rc rc = grn_ts_expr_parser_apply(ctx, parser, 0);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (parser->stack_depth < 2) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "invalid token sequence");
+ }
+ ex_ex_token = parser->stack[parser->stack_depth - 2];
+ if (ex_ex_token->type != GRN_TS_EXPR_BRACKET_TOKEN) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "invalid token sequence");
+ }
+ if (token->src.ptr[0] == ')') {
+ size_t depth = parser->stack_depth;
+ grn_ts_str src;
+ grn_ts_expr_dummy_token *dummy_token;
+ if (ex_ex_token->src.ptr[0] != '(') {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "invalid token sequence");
+ }
+ src.ptr = ex_ex_token->src.ptr;
+ src.size = (token->src.ptr + token->src.size) - src.ptr;
+ dummy_token = &parser->dummy_tokens[parser->n_dummy_tokens++];
+ GRN_TS_DEBUG("dummy token: \"%.*s\"", (int)src.size, src.ptr);
+ grn_ts_expr_dummy_token_init(ctx, dummy_token, src);
+ parser->stack[depth - 2] = dummy_token;
+ parser->stack_depth--;
+ // TODO: Apply a function.
+ } else if (token->src.ptr[0] == ']') {
+ size_t depth = parser->stack_depth;
+ if (ex_ex_token->src.ptr[0] != '[') {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "invalid token sequence");
+ }
+ parser->stack[depth - 2] = parser->stack[depth - 1];
+ parser->stack_depth--;
+ // TODO: Push a subscript operator.
+ }
+ return GRN_SUCCESS;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, "undefined bracket: \"%.*s\"",
+ (int)token->src.size, token->src.ptr);
+ }
+ }
+}
+
+/* grn_ts_expr_parser_analyze_token() analyzes a token. */
+static grn_rc
+grn_ts_expr_parser_analyze_token(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_expr_token *token)
+{
+ switch (token->type) {
+ case GRN_TS_EXPR_START_TOKEN: {
+ parser->stack[parser->stack_depth++] = token;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_EXPR_END_TOKEN: {
+ return grn_ts_expr_parser_apply(ctx, parser, 0);
+ }
+ case GRN_TS_EXPR_CONST_TOKEN: {
+ grn_ts_expr_const_token *const_token = (grn_ts_expr_const_token *)token;
+ grn_ts_expr_dummy_token *dummy_token;
+ grn_rc rc = grn_ts_expr_parser_push_const(ctx, parser, const_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ dummy_token = &parser->dummy_tokens[parser->n_dummy_tokens++];
+ grn_ts_expr_dummy_token_init(ctx, dummy_token, token->src);
+ parser->stack[parser->stack_depth++] = dummy_token;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_EXPR_NAME_TOKEN: {
+ grn_ts_expr_name_token *name_token = (grn_ts_expr_name_token *)token;
+ grn_ts_expr_dummy_token *dummy_token;
+ grn_rc rc = grn_ts_expr_parser_push_name(ctx, parser, name_token);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ dummy_token = &parser->dummy_tokens[parser->n_dummy_tokens++];
+ grn_ts_expr_dummy_token_init(ctx, dummy_token, token->src);
+ parser->stack[parser->stack_depth++] = dummy_token;
+ return GRN_SUCCESS;
+ }
+ case GRN_TS_EXPR_OP_TOKEN: {
+ grn_ts_expr_op_token *op_token = (grn_ts_expr_op_token *)token;
+ return grn_ts_expr_parser_analyze_op(ctx, parser, op_token);
+ }
+ case GRN_TS_EXPR_BRIDGE_TOKEN: {
+ grn_ts_expr_bridge_token *bridge_token;
+ bridge_token = (grn_ts_expr_bridge_token *)token;
+ return grn_ts_expr_parser_analyze_bridge(ctx, parser, bridge_token);
+ }
+ case GRN_TS_EXPR_BRACKET_TOKEN: {
+ grn_ts_expr_bracket_token *bracket_token;
+ bracket_token = (grn_ts_expr_bracket_token *)token;
+ return grn_ts_expr_parser_analyze_bracket(ctx, parser, bracket_token);
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid token type: %d",
+ token->type);
+ }
+ }
+}
+
+/* grn_ts_expr_parser_analyze() analyzes tokens. */
+static grn_rc
+grn_ts_expr_parser_analyze(grn_ctx *ctx, grn_ts_expr_parser *parser)
+{
+ size_t i;
+
+ /* Reserve temporary work spaces. */
+ if (parser->n_tokens > parser->max_n_dummy_tokens) {
+ size_t n_bytes = sizeof(grn_ts_expr_dummy_token) * parser->n_tokens;
+ grn_ts_expr_dummy_token *dummy_tokens = parser->dummy_tokens;
+ grn_ts_expr_dummy_token *new_dummy_tokens;
+ new_dummy_tokens = (grn_ts_expr_dummy_token *)GRN_REALLOC(dummy_tokens,
+ n_bytes);
+ if (!new_dummy_tokens) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE, n_bytes);
+ }
+ parser->dummy_tokens = new_dummy_tokens;
+ parser->max_n_dummy_tokens = parser->n_tokens;
+ }
+ if (parser->n_tokens > parser->stack_size) {
+ size_t n_bytes = sizeof(grn_ts_expr_token *) * parser->n_tokens;
+ grn_ts_expr_token **new_stack;
+ new_stack = (grn_ts_expr_token **)GRN_REALLOC(parser->stack, n_bytes);
+ if (!new_stack) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_REALLOC failed: %" GRN_FMT_SIZE, n_bytes);
+ }
+ parser->stack = new_stack;
+ parser->stack_size = parser->n_tokens;
+ }
+
+ /* Analyze tokens. */
+ for (i = 0; i < parser->n_tokens; i++) {
+ grn_rc rc;
+ rc = grn_ts_expr_parser_analyze_token(ctx, parser, parser->tokens[i]);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (parser->stack_depth != 2) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT,
+ "tokens left in stack: %" GRN_FMT_SIZE,
+ parser->stack_depth);
+ }
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_ts_expr_parser_clear() clears the internal states for parsing the next
+ * string.
+ */
+static void
+grn_ts_expr_parser_clear(grn_ctx *ctx, grn_ts_expr_parser *parser)
+{
+ parser->stack_depth = 0;
+ if (parser->dummy_tokens) {
+ size_t i;
+ for (i = 0; i < parser->n_dummy_tokens; i++) {
+ grn_ts_expr_dummy_token_fin(ctx, &parser->dummy_tokens[i]);
+ }
+ parser->n_dummy_tokens = 0;
+ }
+ if (parser->tokens) {
+ size_t i;
+ for (i = 0; i < parser->n_tokens; i++) {
+ grn_ts_expr_token_close(ctx, parser->tokens[i]);
+ }
+ parser->n_tokens = 0;
+ }
+ grn_ts_expr_builder_clear(ctx, parser->builder);
+}
+
+grn_rc
+grn_ts_expr_parser_parse(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr **expr)
+{
+ grn_rc rc;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!parser || (!str.ptr && str.size)) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ grn_ts_expr_parser_clear(ctx, parser);
+ rc = grn_ts_buf_reserve(ctx, &parser->str_buf, str.size + 1);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ grn_memcpy(parser->str_buf.ptr, str.ptr, str.size);
+ ((char *)parser->str_buf.ptr)[str.size] = '\0';
+ str.ptr = (const char *)parser->str_buf.ptr;
+ rc = grn_ts_expr_parser_tokenize(ctx, parser, str);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = grn_ts_expr_parser_analyze(ctx, parser);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ return grn_ts_expr_builder_complete(ctx, parser->builder, expr);
+}
+
+grn_rc
+grn_ts_expr_parser_split(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_str *first, grn_ts_str *rest)
+{
+ size_t i;
+ char stack_top;
+ grn_rc rc = GRN_SUCCESS;
+ grn_ts_buf stack;
+
+ // FIXME: `stack` should be a member of `parser`.
+ grn_ts_buf_init(ctx, &stack);
+ for ( ; ; ) {
+ str = grn_ts_str_trim_left(str);
+ if (!str.size) {
+ rc = GRN_END_OF_DATA;
+ break;
+ }
+ for (i = 0; i < str.size; i++) {
+ if (stack.pos) {
+ if (str.ptr[i] == stack_top) {
+ if (--stack.pos) {
+ stack_top = ((char *)stack.ptr)[stack.pos - 1];
+ }
+ continue;
+ }
+ if (stack_top == '"') {
+ /* Skip the next byte of an escape character. */
+ if ((str.ptr[i] == '\\') && (i < (str.size - 1))) {
+ i++;
+ }
+ continue;
+ }
+ } else if (str.ptr[i] == ',') {
+ /* An expression delimiter. */
+ break;
+ }
+ switch (str.ptr[i]) {
+ case '(': {
+ stack_top = ')';
+ rc = grn_ts_buf_write(ctx, &stack, &stack_top, 1);
+ break;
+ }
+ case '[': {
+ stack_top = ']';
+ rc = grn_ts_buf_write(ctx, &stack, &stack_top, 1);
+ break;
+ }
+ case '{': {
+ stack_top = '}';
+ rc = grn_ts_buf_write(ctx, &stack, &stack_top, 1);
+ break;
+ }
+ case '"': {
+ stack_top = '"';
+ rc = grn_ts_buf_write(ctx, &stack, &stack_top, 1);
+ break;
+ }
+ }
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ if (i) {
+ /* Set the result. */
+ first->ptr = str.ptr;
+ first->size = i;
+ if (first->size == str.size) {
+ rest->ptr = str.ptr + str.size;
+ rest->size = 0;
+ } else {
+ rest->ptr = str.ptr + first->size + 1;
+ rest->size = str.size - first->size - 1;
+ }
+ break;
+ }
+ str.ptr++;
+ str.size--;
+ }
+ grn_ts_buf_fin(ctx, &stack);
+ return rc;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_expr_parser.h b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_parser.h
new file mode 100644
index 00000000000..1023356e82d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_parser.h
@@ -0,0 +1,107 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "ts_expr.h"
+#include "ts_expr_builder.h"
+#include "ts_str.h"
+#include "ts_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ GRN_TS_EXPR_DUMMY_TOKEN, /* No extra data. */
+ GRN_TS_EXPR_START_TOKEN, /* No extra data. */
+ GRN_TS_EXPR_END_TOKEN, /* No extra data. */
+ GRN_TS_EXPR_CONST_TOKEN, /* +data_kind, content and buf. */
+ GRN_TS_EXPR_NAME_TOKEN, /* +name. */
+ GRN_TS_EXPR_OP_TOKEN, /* +op_type. */
+ GRN_TS_EXPR_BRIDGE_TOKEN, /* No extra data. */
+ GRN_TS_EXPR_BRACKET_TOKEN /* No extra data. */
+} grn_ts_expr_token_type;
+
+#define GRN_TS_EXPR_TOKEN_COMMON_MEMBERS\
+ grn_ts_str src; /* Source string. */\
+ grn_ts_expr_token_type type; /* Token type. */
+
+typedef struct {
+ GRN_TS_EXPR_TOKEN_COMMON_MEMBERS
+} grn_ts_expr_token;
+
+typedef grn_ts_expr_token grn_ts_expr_dummy_token;
+typedef grn_ts_expr_token grn_ts_expr_start_token;
+typedef grn_ts_expr_token grn_ts_expr_end_token;
+
+typedef struct {
+ GRN_TS_EXPR_TOKEN_COMMON_MEMBERS
+ grn_ts_data_kind data_kind; /* The data kind of the const. */
+ grn_ts_any content; /* The const. */
+ grn_ts_buf buf; /* Buffer for content.as_text. */
+} grn_ts_expr_const_token;
+
+typedef grn_ts_expr_token grn_ts_expr_name_token;
+
+typedef struct {
+ GRN_TS_EXPR_TOKEN_COMMON_MEMBERS
+ grn_ts_op_type op_type; /* Operator type. */
+} grn_ts_expr_op_token;
+
+typedef grn_ts_expr_token grn_ts_expr_bridge_token;
+typedef grn_ts_expr_token grn_ts_expr_bracket_token;
+
+typedef struct {
+ grn_ts_expr_builder *builder; /* Builder. */
+ grn_ts_buf str_buf; /* Buffer for a source string. */
+ grn_ts_expr_token **tokens; /* Tokens. */
+ size_t n_tokens; /* Number of tokens. */
+ size_t max_n_tokens; /* Maximum number of tokens. */
+ grn_ts_expr_dummy_token *dummy_tokens; /* Dummy tokens. */
+ size_t n_dummy_tokens; /* Number of dummy tokens. */
+ size_t max_n_dummy_tokens; /* Maximum number of dummy tokens. */
+ grn_ts_expr_token **stack; /* Token stack. */
+ size_t stack_depth; /* Token stack's current depth. */
+ size_t stack_size; /* Token stack's capacity. */
+} grn_ts_expr_parser;
+
+/* grn_ts_expr_parser_open() creates a parser. */
+grn_rc grn_ts_expr_parser_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_expr_parser **parser);
+
+/* grn_ts_expr_parser_close() destroys a parser. */
+grn_rc grn_ts_expr_parser_close(grn_ctx *ctx, grn_ts_expr_parser *parser);
+
+/* grn_ts_expr_parser_parse() parses a string and creates an expression. */
+grn_rc grn_ts_expr_parser_parse(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_expr **expr);
+
+/*
+ * grn_ts_expr_parser_split() splits comma-separated strings into the first
+ * expression and the rest.
+ * Note that if `str` is empty, this function returns GRN_END_OF_DATA.
+ */
+grn_rc grn_ts_expr_parser_split(grn_ctx *ctx, grn_ts_expr_parser *parser,
+ grn_ts_str str, grn_ts_str *first,
+ grn_ts_str *rest);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_log.h b/storage/mroonga/vendor/groonga/lib/ts/ts_log.h
new file mode 100644
index 00000000000..7619d60543f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_log.h
@@ -0,0 +1,46 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* GRN_TS_DEBUG() logs a message that is useful for debug. */
+#define GRN_TS_DEBUG(...) GRN_LOG(ctx, GRN_LOG_DEBUG, __VA_ARGS__)
+
+/* GRN_TS_WARN() logs a warning. */
+#define GRN_TS_WARN(rc, ...) WARN(rc, __VA_ARGS__)
+
+/* GRN_TS_ERR() reports an error. */
+#define GRN_TS_ERR(rc, ...) ERR(rc, __VA_ARGS__)
+
+/* GRN_TS_ERR_RETURN() reports an error and returns its error code. */
+#define GRN_TS_ERR_RETURN(rc, ...) do {\
+ GRN_TS_ERR(rc, __VA_ARGS__);\
+ return rc;\
+} while (GRN_FALSE)
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_op.c b/storage/mroonga/vendor/groonga/lib/ts/ts_op.c
new file mode 100644
index 00000000000..956aa7dc7b3
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_op.c
@@ -0,0 +1,131 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_op.h"
+
+size_t
+grn_ts_op_get_n_args(grn_ts_op_type op_type)
+{
+ switch (op_type) {
+ case GRN_TS_OP_LOGICAL_NOT: /* !X */
+ case GRN_TS_OP_BITWISE_NOT: /* ~X */
+ case GRN_TS_OP_POSITIVE: /* +X */
+ case GRN_TS_OP_NEGATIVE: /* -X */
+ case GRN_TS_OP_FLOAT:
+ case GRN_TS_OP_TIME: {
+ return 1;
+ }
+ case GRN_TS_OP_LOGICAL_AND: /* X && Y */
+ case GRN_TS_OP_LOGICAL_OR: /* X || Y */
+ case GRN_TS_OP_LOGICAL_SUB: /* X &! Y */
+ case GRN_TS_OP_BITWISE_AND: /* X & Y */
+ case GRN_TS_OP_BITWISE_OR: /* X | Y */
+ case GRN_TS_OP_BITWISE_XOR: /* X ^ Y */
+ case GRN_TS_OP_EQUAL: /* X == Y */
+ case GRN_TS_OP_NOT_EQUAL: /* X != Y */
+ case GRN_TS_OP_LESS: /* X < Y */
+ case GRN_TS_OP_LESS_EQUAL: /* X <= Y */
+ case GRN_TS_OP_GREATER: /* X > Y */
+ case GRN_TS_OP_GREATER_EQUAL: /* X >= Y */
+ case GRN_TS_OP_SHIFT_ARITHMETIC_LEFT: /* X << Y */
+ case GRN_TS_OP_SHIFT_ARITHMETIC_RIGHT: /* X >> Y */
+ case GRN_TS_OP_SHIFT_LOGICAL_LEFT: /* X <<< Y */
+ case GRN_TS_OP_SHIFT_LOGICAL_RIGHT: /* X >>> Y */
+ case GRN_TS_OP_PLUS: /* X + Y */
+ case GRN_TS_OP_MINUS: /* X - Y */
+ case GRN_TS_OP_MULTIPLICATION: /* X * Y */
+ case GRN_TS_OP_DIVISION: /* X / Y */
+ case GRN_TS_OP_MODULUS: /* X % Y */
+ case GRN_TS_OP_MATCH: /* X @ Y */
+ case GRN_TS_OP_PREFIX_MATCH: /* X @^ Y */
+ case GRN_TS_OP_SUFFIX_MATCH: { /* X @$ Y */
+ return 2;
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
+grn_ts_op_precedence
+grn_ts_op_get_precedence(grn_ts_op_type op_type)
+{
+ switch (op_type) {
+ case GRN_TS_OP_LOGICAL_NOT:
+ case GRN_TS_OP_BITWISE_NOT:
+ case GRN_TS_OP_POSITIVE:
+ case GRN_TS_OP_NEGATIVE: {
+ return 15;
+ }
+ case GRN_TS_OP_FLOAT:
+ case GRN_TS_OP_TIME: {
+ return 16;
+ }
+ case GRN_TS_OP_LOGICAL_AND: {
+ return 5;
+ }
+ case GRN_TS_OP_LOGICAL_OR: {
+ return 3;
+ }
+ case GRN_TS_OP_LOGICAL_SUB: {
+ return 4;
+ }
+ case GRN_TS_OP_BITWISE_AND: {
+ return 8;
+ }
+ case GRN_TS_OP_BITWISE_OR: {
+ return 6;
+ }
+ case GRN_TS_OP_BITWISE_XOR: {
+ return 7;
+ }
+ case GRN_TS_OP_EQUAL:
+ case GRN_TS_OP_NOT_EQUAL: {
+ return 9;
+ }
+ case GRN_TS_OP_LESS:
+ case GRN_TS_OP_LESS_EQUAL:
+ case GRN_TS_OP_GREATER:
+ case GRN_TS_OP_GREATER_EQUAL: {
+ return 10;
+ }
+ case GRN_TS_OP_SHIFT_ARITHMETIC_LEFT:
+ case GRN_TS_OP_SHIFT_ARITHMETIC_RIGHT:
+ case GRN_TS_OP_SHIFT_LOGICAL_LEFT:
+ case GRN_TS_OP_SHIFT_LOGICAL_RIGHT: {
+ return 11;
+ }
+ case GRN_TS_OP_PLUS:
+ case GRN_TS_OP_MINUS: {
+ return 12;
+ }
+ case GRN_TS_OP_MULTIPLICATION:
+ case GRN_TS_OP_DIVISION:
+ case GRN_TS_OP_MODULUS: {
+ return 13;
+ }
+ case GRN_TS_OP_MATCH:
+ case GRN_TS_OP_PREFIX_MATCH:
+ case GRN_TS_OP_SUFFIX_MATCH: {
+ return 14;
+ }
+ default: {
+ return 0;
+ }
+ }
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_op.h b/storage/mroonga/vendor/groonga/lib/ts/ts_op.h
new file mode 100644
index 00000000000..3bdfcf43f81
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_op.h
@@ -0,0 +1,87 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------------------------------------------------
+ * Operator types.
+ */
+
+typedef enum {
+ /* Invalid operator. */
+ GRN_TS_OP_NOP,
+
+ /* Unary operators. */
+ GRN_TS_OP_LOGICAL_NOT, /* !X */
+ GRN_TS_OP_BITWISE_NOT, /* ~X */
+ GRN_TS_OP_POSITIVE, /* +X */
+ GRN_TS_OP_NEGATIVE, /* -X */
+
+ /* Typecast operators. */
+ GRN_TS_OP_FLOAT,
+ GRN_TS_OP_TIME,
+
+ /* Binary operators. */
+ GRN_TS_OP_LOGICAL_AND, /* X && Y */
+ GRN_TS_OP_LOGICAL_OR, /* X || Y */
+ GRN_TS_OP_LOGICAL_SUB, /* X &! Y */
+ GRN_TS_OP_BITWISE_AND, /* X & Y */
+ GRN_TS_OP_BITWISE_OR, /* X | Y */
+ GRN_TS_OP_BITWISE_XOR, /* X ^ Y */
+ GRN_TS_OP_EQUAL, /* X == Y */
+ GRN_TS_OP_NOT_EQUAL, /* X != Y */
+ GRN_TS_OP_LESS, /* X < Y */
+ GRN_TS_OP_LESS_EQUAL, /* X <= Y */
+ GRN_TS_OP_GREATER, /* X > Y */
+ GRN_TS_OP_GREATER_EQUAL, /* X >= Y */
+ GRN_TS_OP_SHIFT_ARITHMETIC_LEFT, /* X << Y */
+ GRN_TS_OP_SHIFT_ARITHMETIC_RIGHT, /* X >> Y */
+ GRN_TS_OP_SHIFT_LOGICAL_LEFT, /* X <<< Y */
+ GRN_TS_OP_SHIFT_LOGICAL_RIGHT, /* X >>> Y */
+ GRN_TS_OP_PLUS, /* X + Y */
+ GRN_TS_OP_MINUS, /* X - Y */
+ GRN_TS_OP_MULTIPLICATION, /* X * Y */
+ GRN_TS_OP_DIVISION, /* X / Y */
+ GRN_TS_OP_MODULUS, /* X % Y */
+ GRN_TS_OP_MATCH, /* X @ Y */
+ GRN_TS_OP_PREFIX_MATCH, /* X @^ Y */
+ GRN_TS_OP_SUFFIX_MATCH /* X @$ Y */
+} grn_ts_op_type;
+
+/* Operator precedence. */
+typedef int grn_ts_op_precedence;
+
+/* grn_ts_op_get_n_args() returns the number of arguments. */
+size_t grn_ts_op_get_n_args(grn_ts_op_type op_type);
+
+/*
+ * grn_ts_op_get_precedence() returns the precedence.
+ * A prior operator has a higher precedence.
+ */
+grn_ts_op_precedence grn_ts_op_get_precedence(grn_ts_op_type op_type);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_plan.c b/storage/mroonga/vendor/groonga/lib/ts/ts_plan.c
new file mode 100644
index 00000000000..2bd2a4b50e9
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_plan.c
@@ -0,0 +1,21 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_plan.h"
+
+// TODO
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_plan.h b/storage/mroonga/vendor/groonga/lib/ts/ts_plan.h
new file mode 100644
index 00000000000..c441adef4cd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_plan.h
@@ -0,0 +1,87 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#include "ts_buf.h"
+#include "ts_cursor.h"
+#include "ts_expr.h"
+#include "ts_sorter.h"
+#include "ts_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ int REMOVE_ME;
+} grn_ts_plan_node;
+
+typedef struct {
+ grn_obj *table;
+ grn_ts_plan_node *root;
+} grn_ts_plan;
+
+/* grn_ts_plan_open() creates a plan. */
+grn_rc grn_ts_plan_open(grn_ctx *ctx, grn_obj *table, grn_ts_plan_node *root,
+ grn_ts_plan **plan);
+
+/* grn_ts_plan_close() destroys a plan. */
+grn_rc grn_ts_plan_close(grn_ctx *ctx, grn_ts_plan *plan);
+
+/* grn_ts_plan_exec() executes a plan. */
+grn_rc grn_ts_plan_exec(grn_ctx *ctx, grn_ts_plan *plan,
+ grn_ts_rbuf *rbuf, size_t *n_hits);
+
+typedef struct {
+ grn_obj *table;
+} grn_ts_planner;
+
+/* grn_ts_planner_open() creates a planner. */
+grn_rc grn_ts_planner_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_planner **planner);
+
+/* grn_ts_planner_close() destroys a planner. */
+grn_rc grn_ts_planner_close(grn_ctx *ctx, grn_ts_planner *planner);
+
+/* grn_ts_planner_complete() completes a planner. */
+grn_rc grn_ts_planner_complete(grn_ctx *ctx, grn_ts_planner *planner,
+ grn_ts_plan **plan);
+
+/* grn_ts_planner_push_cursor() pushes a cursor. */
+grn_rc grn_ts_planner_push_cursor(grn_ctx *ctx, grn_ts_planner *planner,
+ grn_ts_cursor *cursor);
+
+/* grn_ts_planner_push_filter() pushes a filter. */
+grn_rc grn_ts_planner_push_filter(grn_ctx *ctx, grn_ts_planner *planner,
+ grn_ts_expr *expr);
+
+/* grn_ts_planner_push_scorer() pushes a scorer. */
+grn_rc grn_ts_planner_push_scorer(grn_ctx *ctx, grn_ts_planner *planner,
+ grn_ts_expr *expr);
+
+/* grn_ts_planner_push_sorter() pushes a sorter. */
+grn_rc grn_ts_planner_push_sorter(grn_ctx *ctx, grn_ts_planner *planner,
+ grn_ts_sorter *sorter);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_sorter.c b/storage/mroonga/vendor/groonga/lib/ts/ts_sorter.c
new file mode 100644
index 00000000000..1d880476ba9
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_sorter.c
@@ -0,0 +1,2174 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_sorter.h"
+
+#include <string.h>
+
+#include "ts_expr_parser.h"
+#include "ts_log.h"
+#include "ts_util.h"
+
+/*-------------------------------------------------------------
+ * grn_ts_sorter_node.
+ */
+
+/* grn_ts_sorter_node_init() initializes a sorter node. */
+static void
+grn_ts_sorter_node_init(grn_ctx *ctx, grn_ts_sorter_node *node)
+{
+ memset(node, 0, sizeof(*node));
+ node->expr = NULL;
+ grn_ts_buf_init(ctx, &node->buf);
+ node->next = NULL;
+}
+
+/* grn_ts_sorter_node_fin() finalizes a sorter node. */
+static void
+grn_ts_sorter_node_fin(grn_ctx *ctx, grn_ts_sorter_node *node)
+{
+ grn_ts_buf_fin(ctx, &node->buf);
+ if (node->expr) {
+ grn_ts_expr_close(ctx, node->expr);
+ }
+}
+
+/* grn_ts_sorter_node_open() creates a sorter nodes. */
+static grn_rc
+grn_ts_sorter_node_open(grn_ctx *ctx, grn_ts_expr *expr, grn_ts_bool reverse,
+ grn_ts_sorter_node **node)
+{
+ grn_ts_sorter_node *new_node;
+ new_node = GRN_MALLOCN(grn_ts_sorter_node, 1);
+ if (!new_node) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_sorter_node));
+ }
+ grn_ts_sorter_node_init(ctx, new_node);
+ new_node->expr = expr;
+ new_node->reverse = reverse;
+ *node = new_node;
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_sorter_node_close() destroys a sorter node. */
+static void
+grn_ts_sorter_node_close(grn_ctx *ctx, grn_ts_sorter_node *node)
+{
+ grn_ts_sorter_node_fin(ctx, node);
+ GRN_FREE(node);
+}
+
+/* grn_ts_sorter_node_list_close() destroys a linked list of sorter nodes. */
+static void
+grn_ts_sorter_node_list_close(grn_ctx *ctx, grn_ts_sorter_node *head)
+{
+ grn_ts_sorter_node *node = head;
+ while (node) {
+ grn_ts_sorter_node *next = node->next;
+ grn_ts_sorter_node_close(ctx, node);
+ node = next;
+ }
+}
+
+/* grn_ts_sorter_node_progress() progresses sorting. */
+static grn_rc
+grn_ts_sorter_node_progress(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs, size_t *n_rest)
+{
+ // TODO
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+}
+
+/* grn_ts_sorter_node_complete() completes sorting. */
+static grn_rc
+grn_ts_sorter_node_complete(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs, size_t *n_rest)
+{
+ // TODO
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+}
+
+/* Forward declarations. */
+static grn_rc
+grn_ts_sorter_node_sort(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs);
+
+/* grn_ts_rec_swap() swaps records. */
+inline static void
+grn_ts_rec_swap(grn_ts_record *lhs, grn_ts_record *rhs)
+{
+ grn_ts_record tmp = *lhs;
+ *lhs = *rhs;
+ *rhs = tmp;
+}
+
+/* grn_ts_int_swap() swaps Int values. */
+inline static void
+grn_ts_int_swap(grn_ts_int *lhs, grn_ts_int *rhs)
+{
+ grn_ts_int tmp = *lhs;
+ *lhs = *rhs;
+ *rhs = tmp;
+}
+
+/* FIXME: Sorting by _id does not assume ID duplicates. */
+
+/* grn_ts_move_pivot_by_id_asc() moves the pivot to the front. */
+static void
+grn_ts_move_pivot_by_id_asc(grn_ts_record *recs, size_t n_recs)
+{
+ /* Choose the median from recs[1], recs[n_recs / 2], and recs[n_recs - 2]. */
+ size_t first = 1;
+ size_t middle = n_recs / 2;
+ size_t last = n_recs - 2;
+ if (recs[first].id < recs[middle].id) {
+ /* first < middle. */
+ if (recs[middle].id < recs[last].id) {
+ /* first < middle < last */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ } else if (recs[first].id < recs[last].id) {
+ /* first < last < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ } else {
+ /* last < first < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ }
+ } else if (recs[last].id < recs[middle].id) {
+ /* last < middle < first. */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ } else if (recs[last].id < recs[first].id) {
+ /* middle < last < first. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ } else {
+ /* middle < first < last. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ }
+}
+
+/* grn_ts_isort_by_id_asc() sorts records. */
+static grn_rc
+grn_ts_isort_by_id_asc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ for (size_t i = 1; i < n_recs; ++i) {
+ for (size_t j = i; j > 0; --j) {
+ if (recs[j].id < recs[j - 1].id) {
+ grn_ts_rec_swap(&recs[j], &recs[j - 1]);
+ } else {
+ break;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_qsort_by_id_asc() sorts records. */
+static grn_rc
+grn_ts_qsort_by_id_asc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ grn_rc rc;
+ /*
+ * FIXME: Currently, the threshold is 16.
+ * This value should be optimized and replaced with a named constant.
+ */
+ while (n_recs >= 16) {
+ grn_ts_record pivot;
+ size_t left, right;
+ grn_ts_move_pivot_by_id_asc(recs, n_recs);
+ pivot = recs[0];
+ left = 1;
+ right = n_recs;
+ for ( ; ; ) {
+ /* Move prior records to left. */
+ while (left < right) {
+ if (pivot.id < recs[left].id) {
+ break;
+ }
+ ++left;
+ }
+ while (left < right) {
+ --right;
+ if (recs[right].id < pivot.id) {
+ break;
+ }
+ }
+ if (left >= right) {
+ break;
+ }
+ grn_ts_rec_swap(&recs[left], &recs[right]);
+ ++left;
+ }
+ /* Move the pivot to the boundary. */
+ --left;
+ grn_ts_rec_swap(&recs[0], &recs[left]);
+ /*
+ * Use a recursive call to sort the smaller group so that the recursion
+ * depth is less than log_2(n_recs).
+ */
+ if (left < (n_recs - right)) {
+ if ((offset < left) && (left >= 2)) {
+ size_t next_limit = (limit < left) ? limit : left;
+ rc = grn_ts_qsort_by_id_asc(ctx, node, offset, next_limit, recs, left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (limit <= right) {
+ return GRN_SUCCESS;
+ }
+ recs += right;
+ n_recs -= right;
+ offset = (offset < right) ? 0 : (offset - right);
+ limit -= right;
+ } else {
+ if ((limit > right) && ((n_recs - right) >= 2)) {
+ size_t next_offset = (offset < right) ? 0 : (offset - right);
+ size_t next_limit = limit - right;
+ rc = grn_ts_qsort_by_id_asc(ctx, node, next_offset, next_limit,
+ recs + right, n_recs - right);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (offset >= left) {
+ return GRN_SUCCESS;
+ }
+ n_recs = left;
+ if (limit > left) {
+ limit = left;
+ }
+ }
+ }
+ if (n_recs >= 2) {
+ return grn_ts_isort_by_id_asc(ctx, node, offset, limit, recs, n_recs);
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_move_pivot_by_id_desc() moves the pivot to the front. */
+static void
+grn_ts_move_pivot_by_id_desc(grn_ts_record *recs, size_t n_recs)
+{
+ /* Choose the median from recs[1], recs[n_recs / 2], and recs[n_recs - 2]. */
+ size_t first = 1;
+ size_t middle = n_recs / 2;
+ size_t last = n_recs - 2;
+ if (recs[first].id > recs[middle].id) {
+ /* first > middle. */
+ if (recs[middle].id > recs[last].id) {
+ /* first > middle > last */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ } else if (recs[first].id > recs[last].id) {
+ /* first > last > middle. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ } else {
+ /* last > first > middle. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ }
+ } else if (recs[last].id > recs[middle].id) {
+ /* last > middle > first. */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ } else if (recs[last].id > recs[first].id) {
+ /* middle > last > first. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ } else {
+ /* middle > first > last. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ }
+}
+
+/* grn_ts_isort_by_id_desc() sorts records. */
+static grn_rc
+grn_ts_isort_by_id_desc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ for (size_t i = 1; i < n_recs; ++i) {
+ for (size_t j = i; j > 0; --j) {
+ if (recs[j].id > recs[j - 1].id) {
+ grn_ts_rec_swap(&recs[j], &recs[j - 1]);
+ } else {
+ break;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_qsort_by_id_desc() sorts records. */
+static grn_rc
+grn_ts_qsort_by_id_desc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ grn_rc rc;
+ /*
+ * FIXME: Currently, the threshold is 16.
+ * This value should be optimized and replaced with a named constant.
+ */
+ while (n_recs >= 16) {
+ grn_ts_record pivot;
+ size_t left, right;
+ grn_ts_move_pivot_by_id_desc(recs, n_recs);
+ pivot = recs[0];
+ left = 1;
+ right = n_recs;
+ for ( ; ; ) {
+ /* Move prior records to left. */
+ while (left < right) {
+ if (pivot.id > recs[left].id) {
+ break;
+ }
+ ++left;
+ }
+ while (left < right) {
+ --right;
+ if (recs[right].id > pivot.id) {
+ break;
+ }
+ }
+ if (left >= right) {
+ break;
+ }
+ grn_ts_rec_swap(&recs[left], &recs[right]);
+ ++left;
+ }
+ /* Move the pivot to the boundary. */
+ --left;
+ grn_ts_rec_swap(&recs[0], &recs[left]);
+ /*
+ * Use a recursive call to sort the smaller group so that the recursion
+ * depth is less than log_2(n_recs).
+ */
+ if (left < (n_recs - right)) {
+ if ((offset < left) && (left >= 2)) {
+ size_t next_limit = (limit < left) ? limit : left;
+ rc = grn_ts_qsort_by_id_desc(ctx, node, offset, next_limit,
+ recs, left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (limit <= right) {
+ return GRN_SUCCESS;
+ }
+ recs += right;
+ n_recs -= right;
+ offset = (offset < right) ? 0 : (offset - right);
+ limit -= right;
+ } else {
+ if ((limit > right) && ((n_recs - right) >= 2)) {
+ size_t next_offset = (offset < right) ? 0 : (offset - right);
+ size_t next_limit = limit - right;
+ rc = grn_ts_qsort_by_id_desc(ctx, node, next_offset, next_limit,
+ recs + right, n_recs - right);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (offset >= left) {
+ return GRN_SUCCESS;
+ }
+ n_recs = left;
+ if (limit > left) {
+ limit = left;
+ }
+ }
+ }
+ if (n_recs >= 2) {
+ return grn_ts_isort_by_id_desc(ctx, node, offset, limit, recs, n_recs);
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_sorter_node_sort_by_id() sorts records by _id. */
+static grn_rc
+grn_ts_sorter_node_sort_by_id(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ if (node->reverse) {
+ return grn_ts_qsort_by_id_desc(ctx, node, offset, limit, recs, n_recs);
+ } else {
+ return grn_ts_qsort_by_id_asc(ctx, node, offset, limit, recs, n_recs);
+ }
+}
+
+/* grn_ts_move_pivot_by_score_asc() moves the pivot to the front. */
+static void
+grn_ts_move_pivot_by_score_asc(grn_ts_record *recs, size_t n_recs)
+{
+ /* Choose the median from recs[1], recs[n_recs / 2], and recs[n_recs - 2]. */
+ size_t first = 1;
+ size_t middle = n_recs / 2;
+ size_t last = n_recs - 2;
+ if (recs[first].score < recs[middle].score) {
+ /* first < middle. */
+ if (recs[middle].score < recs[last].score) {
+ /* first < middle < last */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ } else if (recs[first].score < recs[last].score) {
+ /* first < last < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ } else { /* last < first < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ }
+ } else if (recs[last].score < recs[middle].score) {
+ /* last < middle < first. */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ } else if (recs[last].score < recs[first].score) {
+ /* middle < last < first. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ } else { /* middle < first < last. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ }
+}
+
+/* grn_ts_isort_by_score_asc() sorts records. */
+static grn_rc
+grn_ts_isort_by_score_asc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ for (size_t i = 1; i < n_recs; ++i) {
+ for (size_t j = i; j > 0; --j) {
+ if (recs[j].score < recs[j - 1].score) {
+ grn_ts_rec_swap(&recs[j], &recs[j - 1]);
+ } else {
+ break;
+ }
+ }
+ }
+ /* Apply the next sorting if there are score duplicates. */
+ if (node->next) {
+ grn_rc rc;
+ size_t begin = 0;
+ for (size_t i = 1; i < n_recs; ++i) {
+ if ((recs[i].score < recs[begin].score) ||
+ (recs[i].score > recs[begin].score)) {
+ if ((i - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, i - begin,
+ recs + begin, i - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ begin = i;
+ }
+ }
+ if ((n_recs - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, n_recs - begin,
+ recs + begin, n_recs - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_qsort_by_score_asc() sorts records. */
+static grn_rc
+grn_ts_qsort_by_score_asc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ grn_rc rc;
+ /*
+ * FIXME: Currently, the threshold is 16.
+ * This value should be optimized and replaced with a named constant.
+ */
+ while (n_recs >= 16) {
+ grn_ts_record pivot;
+ size_t left, right;
+ size_t pivot_left, pivot_right;
+ grn_ts_move_pivot_by_score_asc(recs, n_recs);
+ pivot = recs[0];
+ left = 1;
+ right = n_recs;
+ pivot_left = 1;
+ pivot_right = n_recs;
+ for ( ; ; ) {
+ /*
+ * Prior entries are moved to left. Less prior entries are moved to
+ * right. Entries which equal to the pivot are moved to the edges.
+ */
+ while (left < right) {
+ if (pivot.score < recs[left].score) {
+ break;
+ } else if ((pivot.score <= recs[left].score) &&
+ (pivot.score >= recs[left].score)) {
+ grn_ts_rec_swap(&recs[left], &recs[pivot_left]);
+ ++pivot_left;
+ }
+ ++left;
+ }
+ while (left < right) {
+ --right;
+ if (recs[right].score < pivot.score) {
+ break;
+ } else if ((recs[right].score <= pivot.score) &&
+ (recs[right].score >= pivot.score)) {
+ --pivot_right;
+ grn_ts_rec_swap(&recs[right], &recs[pivot_right]);
+ }
+ }
+ if (left >= right) {
+ break;
+ }
+ grn_ts_rec_swap(&recs[left], &recs[right]);
+ ++left;
+ }
+ /* Move left pivot-equivalent entries to the left of the boundary. */
+ while (pivot_left > 0) {
+ --pivot_left;
+ --left;
+ grn_ts_rec_swap(&recs[pivot_left], &recs[left]);
+ }
+ /* Move right pivot-equivalent entries to the right of the boundary. */
+ while (pivot_right < n_recs) {
+ grn_ts_rec_swap(&recs[pivot_right], &recs[right]);
+ ++pivot_right;
+ ++right;
+ }
+ /* Apply the next sort condition to the pivot-equivalent recs. */
+ if (node->next) {
+ if (((right - left) >= 2) && (offset < right) && (limit > left)) {
+ size_t next_offset = (offset < left) ? 0 : (offset - left);
+ size_t next_limit = ((limit > right) ? right : limit) - left;
+ rc = grn_ts_sorter_node_sort(ctx, node->next, next_offset, next_limit,
+ recs + left, right - left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ /*
+ * Use a recursive call to sort the smaller group so that the recursion
+ * depth is less than log_2(n_recs).
+ */
+ if (left < (n_recs - right)) {
+ if ((offset < left) && (left >= 2)) {
+ size_t next_limit = (limit < left) ? limit : left;
+ rc = grn_ts_qsort_by_score_asc(ctx, node, offset, next_limit,
+ recs, left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (limit <= right) {
+ return GRN_SUCCESS;
+ }
+ recs += right;
+ n_recs -= right;
+ offset = (offset < right) ? 0 : (offset - right);
+ limit -= right;
+ } else {
+ if ((limit > right) && ((n_recs - right) >= 2)) {
+ size_t next_offset = (offset < right) ? 0 : (offset - right);
+ size_t next_limit = limit - right;
+ rc = grn_ts_qsort_by_score_asc(ctx, node, next_offset, next_limit,
+ recs + right, n_recs - right);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (offset >= left) {
+ return GRN_SUCCESS;
+ }
+ n_recs = left;
+ if (limit > left) {
+ limit = left;
+ }
+ }
+ }
+ if (n_recs >= 2) {
+ rc = grn_ts_isort_by_score_asc(ctx, node, offset, limit, recs, n_recs);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_move_pivot_by_score_desc() moves the pivot to the front. */
+static void
+grn_ts_move_pivot_by_score_desc(grn_ts_record *recs, size_t n_recs)
+{
+ /* Choose the median from recs[1], recs[n_recs / 2], and recs[n_recs - 2]. */
+ size_t first = 1;
+ size_t middle = n_recs / 2;
+ size_t last = n_recs - 2;
+ if (recs[first].score > recs[middle].score) {
+ /* first > middle. */
+ if (recs[middle].score > recs[last].score) {
+ /* first > middle > last */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ } else if (recs[first].score > recs[last].score) {
+ /* first > last > middle. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ } else { /* last > first > middle. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ }
+ } else if (recs[last].score > recs[middle].score) {
+ /* last > middle > first. */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ } else if (recs[last].score > recs[first].score) {
+ /* middle > last > first. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ } else { /* middle > first > last. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ }
+}
+
+/* grn_ts_isort_by_score_desc() sorts records. */
+static grn_rc
+grn_ts_isort_by_score_desc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ for (size_t i = 1; i < n_recs; ++i) {
+ for (size_t j = i; j > 0; --j) {
+ if (recs[j].score > recs[j - 1].score) {
+ grn_ts_rec_swap(&recs[j], &recs[j - 1]);
+ } else {
+ break;
+ }
+ }
+ }
+ /* Apply the next sorting if there are score duplicates. */
+ if (node->next) {
+ grn_rc rc;
+ size_t begin = 0;
+ for (size_t i = 1; i < n_recs; ++i) {
+ if ((recs[i].score < recs[begin].score) ||
+ (recs[i].score > recs[begin].score)) {
+ if ((i - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, i - begin,
+ recs + begin, i - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ begin = i;
+ }
+ }
+ if ((n_recs - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, n_recs - begin,
+ recs + begin, n_recs - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_qsort_by_score_desc() sorts records. */
+static grn_rc
+grn_ts_qsort_by_score_desc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ grn_rc rc;
+ /*
+ * FIXME: Currently, the threshold is 16.
+ * This value should be optimized and replaced with a named constant.
+ */
+ while (n_recs >= 16) {
+ grn_ts_record pivot;
+ size_t left = 1, right = n_recs;
+ size_t pivot_left = 1, pivot_right = n_recs;
+ grn_ts_move_pivot_by_score_desc(recs, n_recs);
+ pivot = recs[0];
+ for ( ; ; ) {
+ /*
+ * Prior entries are moved to left. Less prior entries are moved to
+ * right. Entries which equal to the pivot are moved to the edges.
+ */
+ while (left < right) {
+ if (pivot.score > recs[left].score) {
+ break;
+ } else if ((pivot.score <= recs[left].score) &&
+ (pivot.score >= recs[left].score)) {
+ grn_ts_rec_swap(&recs[left], &recs[pivot_left]);
+ ++pivot_left;
+ }
+ ++left;
+ }
+ while (left < right) {
+ --right;
+ if (recs[right].score > pivot.score) {
+ break;
+ } else if ((recs[right].score <= pivot.score) &&
+ (recs[right].score >= pivot.score)) {
+ --pivot_right;
+ grn_ts_rec_swap(&recs[right], &recs[pivot_right]);
+ }
+ }
+ if (left >= right) {
+ break;
+ }
+ grn_ts_rec_swap(&recs[left], &recs[right]);
+ ++left;
+ }
+ /* Move left pivot-equivalent entries to the left of the boundary. */
+ while (pivot_left > 0) {
+ --pivot_left;
+ --left;
+ grn_ts_rec_swap(&recs[pivot_left], &recs[left]);
+ }
+ /* Move right pivot-equivalent entries to the right of the boundary. */
+ while (pivot_right < n_recs) {
+ grn_ts_rec_swap(&recs[pivot_right], &recs[right]);
+ ++pivot_right;
+ ++right;
+ }
+ /* Apply the next sort condition to the pivot-equivalent recs. */
+ if (node->next) {
+ if (((right - left) >= 2) && (offset < right) && (limit > left)) {
+ size_t next_offset = (offset < left) ? 0 : (offset - left);
+ size_t next_limit = ((limit > right) ? right : limit) - left;
+ rc = grn_ts_sorter_node_sort(ctx, node->next, next_offset, next_limit,
+ recs + left, right - left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ /*
+ * Use a recursive call to sort the smaller group so that the recursion
+ * depth is less than log_2(n_recs).
+ */
+ if (left < (n_recs - right)) {
+ if ((offset < left) && (left >= 2)) {
+ size_t next_limit = (limit < left) ? limit : left;
+ rc = grn_ts_qsort_by_score_desc(ctx, node, offset, next_limit,
+ recs, left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (limit <= right) {
+ return GRN_SUCCESS;
+ }
+ recs += right;
+ n_recs -= right;
+ offset = (offset < right) ? 0 : (offset - right);
+ limit -= right;
+ } else {
+ if ((limit > right) && ((n_recs - right) >= 2)) {
+ size_t next_offset = (offset < right) ? 0 : (offset - right);
+ size_t next_limit = limit - right;
+ rc = grn_ts_qsort_by_score_desc(ctx, node, next_offset, next_limit,
+ recs + right, n_recs - right);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (offset >= left) {
+ return GRN_SUCCESS;
+ }
+ n_recs = left;
+ if (limit > left) {
+ limit = left;
+ }
+ }
+ }
+ if (n_recs >= 2) {
+ rc = grn_ts_isort_by_score_desc(ctx, node, offset, limit, recs, n_recs);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_sorter_node_sort_by_score() sorts records by _score. */
+static grn_rc
+grn_ts_sorter_node_sort_by_score(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ if (node->reverse) {
+ return grn_ts_qsort_by_score_desc(ctx, node, offset, limit, recs, n_recs);
+ } else {
+ return grn_ts_qsort_by_score_asc(ctx, node, offset, limit, recs, n_recs);
+ }
+}
+
+/* grn_ts_move_pivot_by_int() moves the pivot to the front. */
+static void
+grn_ts_move_pivot_by_int(grn_ts_sorter_node *node, grn_ts_int *vals,
+ grn_ts_record *recs, size_t n_recs)
+{
+ /* Choose the median from recs[1], recs[n_recs / 2], and recs[n_recs - 2]. */
+ size_t first = 1;
+ size_t middle = n_recs / 2;
+ size_t last = n_recs - 2;
+ if (vals[first] < vals[middle]) {
+ /* first < middle. */
+ if (vals[middle] < vals[last]) {
+ /* first < middle < last */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ grn_ts_int_swap(&vals[0], &vals[middle]);
+ } else if (vals[first] < vals[last]) {
+ /* first < last < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ grn_ts_int_swap(&vals[0], &vals[last]);
+ } else { /* last < first < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ grn_ts_int_swap(&vals[0], &vals[first]);
+ }
+ } else if (vals[last] < vals[middle]) {
+ /* last < middle < first. */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ grn_ts_int_swap(&vals[0], &vals[middle]);
+ } else if (vals[last] < vals[first]) {
+ /* middle < last < first. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ grn_ts_int_swap(&vals[0], &vals[last]);
+ } else { /* middle < first < last. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ grn_ts_int_swap(&vals[0], &vals[first]);
+ }
+}
+
+/* grn_ts_isort_by_int() sorts records. */
+static grn_rc
+grn_ts_isort_by_int(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_int *vals, grn_ts_record *recs, size_t n_recs)
+{
+ for (size_t i = 1; i < n_recs; ++i) {
+ for (size_t j = i; j > 0; --j) {
+ if (vals[j] < vals[j - 1]) {
+ grn_ts_rec_swap(&recs[j], &recs[j - 1]);
+ grn_ts_int_swap(&vals[j], &vals[j - 1]);
+ } else {
+ break;
+ }
+ }
+ }
+ /* Apply the next sorting if there are score duplicates. */
+ if (node->next) {
+ grn_rc rc;
+ size_t begin = 0;
+ for (size_t i = 1; i < n_recs; ++i) {
+ if (vals[i] != vals[begin]) {
+ if ((i - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, i - begin,
+ recs + begin, i - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ begin = i;
+ }
+ }
+ if ((n_recs - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, n_recs - begin,
+ recs + begin, n_recs - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_qsort_by_int() sorts records. */
+static grn_rc
+grn_ts_qsort_by_int(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_int *vals, grn_ts_record *recs, size_t n_recs)
+{
+ grn_rc rc;
+ /*
+ * FIXME: Currently, the threshold is 16.
+ * This value should be optimized and replaced with a named constant.
+ */
+ while (n_recs >= 16) {
+ grn_ts_int pivot;
+ size_t left, right;
+ size_t pivot_left, pivot_right;
+ grn_ts_move_pivot_by_int(node, vals, recs, n_recs);
+ pivot = vals[0];
+ left = 1;
+ right = n_recs;
+ pivot_left = 1;
+ pivot_right = n_recs;
+ for ( ; ; ) {
+ /*
+ * Prior entries are moved to left. Less prior entries are moved to
+ * right. Entries which equal to the pivot are moved to the edges.
+ */
+ while (left < right) {
+ if (pivot < vals[left]) {
+ break;
+ } else if (pivot == vals[left]) {
+ grn_ts_rec_swap(&recs[left], &recs[pivot_left]);
+ grn_ts_int_swap(&vals[left], &vals[pivot_left]);
+ ++pivot_left;
+ }
+ ++left;
+ }
+ while (left < right) {
+ --right;
+ if (vals[right] < pivot) {
+ break;
+ } else if (vals[right] == pivot) {
+ --pivot_right;
+ grn_ts_rec_swap(&recs[right], &recs[pivot_right]);
+ grn_ts_int_swap(&vals[right], &vals[pivot_right]);
+ }
+ }
+ if (left >= right) {
+ break;
+ }
+ grn_ts_rec_swap(&recs[left], &recs[right]);
+ grn_ts_int_swap(&vals[left], &vals[right]);
+ ++left;
+ }
+ /* Move left pivot-equivalent entries to the left of the boundary. */
+ while (pivot_left > 0) {
+ --pivot_left;
+ --left;
+ grn_ts_rec_swap(&recs[pivot_left], &recs[left]);
+ grn_ts_int_swap(&vals[pivot_left], &vals[left]);
+ }
+ /* Move right pivot-equivalent entries to the right of the boundary. */
+ while (pivot_right < n_recs) {
+ grn_ts_rec_swap(&recs[pivot_right], &recs[right]);
+ grn_ts_int_swap(&vals[pivot_right], &vals[right]);
+ ++pivot_right;
+ ++right;
+ }
+ /* Apply the next sort condition to the pivot-equivalent recs. */
+ if (node->next) {
+ if (((right - left) >= 2) && (offset < right) && (limit > left)) {
+ size_t next_offset = (offset < left) ? 0 : (offset - left);
+ size_t next_limit = ((limit > right) ? right : limit) - left;
+ rc = grn_ts_sorter_node_sort(ctx, node->next, next_offset, next_limit,
+ recs + left, right - left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ /*
+ * Use a recursive call to sort the smaller group so that the recursion
+ * depth is less than log_2(n_recs).
+ */
+ if (left < (n_recs - right)) {
+ if ((offset < left) && (left >= 2)) {
+ size_t next_limit = (limit < left) ? limit : left;
+ rc = grn_ts_qsort_by_int(ctx, node, offset, next_limit,
+ vals, recs, left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (limit <= right) {
+ return GRN_SUCCESS;
+ }
+ vals += right;
+ recs += right;
+ n_recs -= right;
+ offset = (offset < right) ? 0 : (offset - right);
+ limit -= right;
+ } else {
+ if ((limit > right) && ((n_recs - right) >= 2)) {
+ size_t next_offset = (offset < right) ? 0 : (offset - right);
+ size_t next_limit = limit - right;
+ rc = grn_ts_qsort_by_int(ctx, node, next_offset, next_limit,
+ vals + right, recs + right, n_recs - right);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (offset >= left) {
+ return GRN_SUCCESS;
+ }
+ n_recs = left;
+ if (limit > left) {
+ limit = left;
+ }
+ }
+ }
+ if (n_recs >= 2) {
+ rc = grn_ts_isort_by_int(ctx, node, offset, limit, vals, recs, n_recs);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_text_cmp() compares Text values. */
+inline static int
+grn_ts_text_cmp(grn_ts_text lhs, grn_ts_text rhs)
+{
+ size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
+ int result = memcmp(lhs.ptr, rhs.ptr, min_size);
+ if (result != 0) {
+ return result;
+ }
+ if (lhs.size == rhs.size) {
+ return 0;
+ }
+ return (lhs.size < rhs.size) ? -1 : 1;
+}
+
+/* grn_ts_text_swap() swaps Text values. */
+inline static void
+grn_ts_text_swap(grn_ts_text *lhs, grn_ts_text *rhs)
+{
+ grn_ts_text tmp = *lhs;
+ *lhs = *rhs;
+ *rhs = tmp;
+}
+
+#if 0
+/* grn_ts_move_pivot_by_text_asc() moves the pivot to the front. */
+static void
+grn_ts_move_pivot_by_text_asc(grn_ts_sorter_node *node, grn_ts_text *vals,
+ grn_ts_record *recs, size_t n_recs)
+{
+ /* Choose the median from recs[1], recs[n_recs / 2], and recs[n_recs - 2]. */
+ size_t first = 1;
+ size_t middle = n_recs / 2;
+ size_t last = n_recs - 2;
+ if (grn_ts_text_cmp(vals[first], vals[middle]) < 0) {
+ /* first < middle. */
+ if (grn_ts_text_cmp(vals[middle], vals[last]) < 0) {
+ /* first < middle < last */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ grn_ts_text_swap(&vals[0], &vals[middle]);
+ } else if (grn_ts_text_cmp(vals[first], vals[last]) < 0) {
+ /* first < last < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ grn_ts_text_swap(&vals[0], &vals[last]);
+ } else { /* last < first < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ grn_ts_text_swap(&vals[0], &vals[first]);
+ }
+ } else if (grn_ts_text_cmp(vals[last], vals[middle]) < 0) {
+ /* last < middle < first. */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ grn_ts_text_swap(&vals[0], &vals[middle]);
+ } else if (grn_ts_text_cmp(vals[last], vals[first]) < 0) {
+ /* middle < last < first. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ grn_ts_text_swap(&vals[0], &vals[last]);
+ } else { /* middle < first < last. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ grn_ts_text_swap(&vals[0], &vals[first]);
+ }
+}
+
+/* grn_ts_isort_by_text_asc() sorts records. */
+static grn_rc
+grn_ts_isort_by_text_asc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_text *vals, grn_ts_record *recs, size_t n_recs)
+{
+ for (size_t i = 1; i < n_recs; ++i) {
+ for (size_t j = i; j > 0; --j) {
+ if (grn_ts_text_cmp(vals[j], vals[j - 1]) < 0) {
+ grn_ts_rec_swap(&recs[j], &recs[j - 1]);
+ grn_ts_text_swap(&vals[j], &vals[j - 1]);
+ } else {
+ break;
+ }
+ }
+ }
+ /* Apply the next sorting if there are score duplicates. */
+ if (node->next) {
+ grn_rc rc;
+ size_t begin = 0;
+ for (size_t i = 1; i < n_recs; ++i) {
+ if (grn_ts_text_cmp(vals[i], vals[begin]) != 0) {
+ if ((i - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, i - begin,
+ recs + begin, i - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ begin = i;
+ }
+ }
+ if ((n_recs - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, n_recs - begin,
+ recs + begin, n_recs - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_qsort_by_text_asc() sorts records. */
+static grn_rc
+grn_ts_qsort_by_text_asc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_text *vals, grn_ts_record *recs, size_t n_recs)
+{
+ grn_rc rc;
+ /*
+ * FIXME: Currently, the threshold is 16.
+ * This value should be optimized and replaced with a named constant.
+ */
+ while (n_recs >= 16) {
+ grn_ts_move_pivot_by_text_asc(node, vals, recs, n_recs);
+ grn_ts_text pivot = vals[0];
+ size_t left = 1, right = n_recs;
+ size_t pivot_left = 1, pivot_right = n_recs;
+ for ( ; ; ) {
+ /*
+ * Prior entries are moved to left. Less prior entries are moved to
+ * right. Entries which equal to the pivot are moved to the edges.
+ */
+ while (left < right) {
+ int result = grn_ts_text_cmp(pivot, vals[left]);
+ if (result < 0) {
+ break;
+ } else if (result == 0) {
+ grn_ts_rec_swap(&recs[left], &recs[pivot_left]);
+ grn_ts_text_swap(&vals[left], &vals[pivot_left]);
+ ++pivot_left;
+ }
+ ++left;
+ }
+ while (left < right) {
+ int result;
+ --right;
+ result = grn_ts_text_cmp(vals[right], pivot);
+ if (result < 0) {
+ break;
+ } else if (result == 0) {
+ --pivot_right;
+ grn_ts_rec_swap(&recs[right], &recs[pivot_right]);
+ grn_ts_text_swap(&vals[right], &vals[pivot_right]);
+ }
+ }
+ if (left >= right) {
+ break;
+ }
+ grn_ts_rec_swap(&recs[left], &recs[right]);
+ grn_ts_text_swap(&vals[left], &vals[right]);
+ ++left;
+ }
+ /* Move left pivot-equivalent entries to the left of the boundary. */
+ while (pivot_left > 0) {
+ --pivot_left;
+ --left;
+ grn_ts_rec_swap(&recs[pivot_left], &recs[left]);
+ grn_ts_text_swap(&vals[pivot_left], &vals[left]);
+ }
+ /* Move right pivot-equivalent entries to the right of the boundary. */
+ while (pivot_right < n_recs) {
+ grn_ts_rec_swap(&recs[pivot_right], &recs[right]);
+ grn_ts_text_swap(&vals[pivot_right], &vals[right]);
+ ++pivot_right;
+ ++right;
+ }
+ /* Apply the next sort condition to the pivot-equivalent recs. */
+ if (node->next) {
+ if (((right - left) >= 2) && (offset < right) && (limit > left)) {
+ size_t next_offset = (offset < left) ? 0 : (offset - left);
+ size_t next_limit = ((limit > right) ? right : limit) - left;
+ rc = grn_ts_sorter_node_sort(ctx, node->next, next_offset, next_limit,
+ recs + left, right - left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ /*
+ * Use a recursive call to sort the smaller group so that the recursion
+ * depth is less than log_2(n_recs).
+ */
+ if (left < (n_recs - right)) {
+ if ((offset < left) && (left >= 2)) {
+ size_t next_limit = (limit < left) ? limit : left;
+ rc = grn_ts_qsort_by_text_asc(ctx, node, offset, next_limit,
+ vals, recs, left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (limit <= right) {
+ return GRN_SUCCESS;
+ }
+ vals += right;
+ recs += right;
+ n_recs -= right;
+ offset = (offset < right) ? 0 : (offset - right);
+ limit -= right;
+ } else {
+ if ((limit > right) && ((n_recs - right) >= 2)) {
+ size_t next_offset = (offset < right) ? 0 : (offset - right);
+ size_t next_limit = limit - right;
+ rc = grn_ts_qsort_by_text_asc(ctx, node, next_offset, next_limit,
+ vals + right, recs + right,
+ n_recs - right);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (offset >= left) {
+ return GRN_SUCCESS;
+ }
+ n_recs = left;
+ if (limit > left) {
+ limit = left;
+ }
+ }
+ }
+ if (n_recs >= 2) {
+ rc = grn_ts_isort_by_text_asc(ctx, node, offset, limit,
+ vals, recs, n_recs);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+#endif
+
+/* grn_ts_move_pivot_by_text_desc() moves the pivot to the front. */
+static void
+grn_ts_move_pivot_by_text_desc(grn_ts_sorter_node *node, grn_ts_text *vals,
+ grn_ts_record *recs, size_t n_recs)
+{
+ /* Choose the median from recs[1], recs[n_recs / 2], and recs[n_recs - 2]. */
+ size_t first = 1;
+ size_t middle = n_recs / 2;
+ size_t last = n_recs - 2;
+ if (grn_ts_text_cmp(vals[first], vals[middle]) > 0) {
+ /* first < middle. */
+ if (grn_ts_text_cmp(vals[middle], vals[last]) > 0) {
+ /* first < middle < last */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ grn_ts_text_swap(&vals[0], &vals[middle]);
+ } else if (grn_ts_text_cmp(vals[first], vals[last]) > 0) {
+ /* first < last < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ grn_ts_text_swap(&vals[0], &vals[last]);
+ } else { /* last < first < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ grn_ts_text_swap(&vals[0], &vals[first]);
+ }
+ } else if (grn_ts_text_cmp(vals[last], vals[middle]) > 0) {
+ /* last < middle < first. */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ grn_ts_text_swap(&vals[0], &vals[middle]);
+ } else if (grn_ts_text_cmp(vals[last], vals[first]) > 0) {
+ /* middle < last < first. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ grn_ts_text_swap(&vals[0], &vals[last]);
+ } else { /* middle < first < last. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ grn_ts_text_swap(&vals[0], &vals[first]);
+ }
+}
+
+/* grn_ts_isort_by_text_desc() sorts records. */
+static grn_rc
+grn_ts_isort_by_text_desc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_text *vals, grn_ts_record *recs,
+ size_t n_recs)
+{
+ for (size_t i = 1; i < n_recs; ++i) {
+ for (size_t j = i; j > 0; --j) {
+ if (grn_ts_text_cmp(vals[j], vals[j - 1]) > 0) {
+ grn_ts_rec_swap(&recs[j], &recs[j - 1]);
+ grn_ts_text_swap(&vals[j], &vals[j - 1]);
+ } else {
+ break;
+ }
+ }
+ }
+ /* Apply the next sorting if there are score duplicates. */
+ if (node->next) {
+ grn_rc rc;
+ size_t begin = 0;
+ for (size_t i = 1; i < n_recs; ++i) {
+ if (grn_ts_text_cmp(vals[i], vals[begin]) != 0) {
+ if ((i - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, i - begin,
+ recs + begin, i - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ begin = i;
+ }
+ }
+ if ((n_recs - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, n_recs - begin,
+ recs + begin, n_recs - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_qsort_by_text_desc() sorts records. */
+static grn_rc
+grn_ts_qsort_by_text_desc(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_text *vals, grn_ts_record *recs,
+ size_t n_recs)
+{
+ grn_rc rc;
+ /*
+ * FIXME: Currently, the threshold is 16.
+ * This value should be optimized and replaced with a named constant.
+ */
+ while (n_recs >= 16) {
+ grn_ts_text pivot;
+ size_t left, right;
+ size_t pivot_left, pivot_right;
+ grn_ts_move_pivot_by_text_desc(node, vals, recs, n_recs);
+ pivot = vals[0];
+ left = 1;
+ right = n_recs;
+ pivot_left = 1;
+ pivot_right = n_recs;
+ for ( ; ; ) {
+ /*
+ * Prior entries are moved to left. Less prior entries are moved to
+ * right. Entries which equal to the pivot are moved to the edges.
+ */
+ while (left < right) {
+ int result = grn_ts_text_cmp(pivot, vals[left]);
+ if (result > 0) {
+ break;
+ } else if (result == 0) {
+ grn_ts_rec_swap(&recs[left], &recs[pivot_left]);
+ grn_ts_text_swap(&vals[left], &vals[pivot_left]);
+ ++pivot_left;
+ }
+ ++left;
+ }
+ while (left < right) {
+ int result;
+ --right;
+ result = grn_ts_text_cmp(vals[right], pivot);
+ if (result > 0) {
+ break;
+ } else if (result == 0) {
+ --pivot_right;
+ grn_ts_rec_swap(&recs[right], &recs[pivot_right]);
+ grn_ts_text_swap(&vals[right], &vals[pivot_right]);
+ }
+ }
+ if (left >= right) {
+ break;
+ }
+ grn_ts_rec_swap(&recs[left], &recs[right]);
+ grn_ts_text_swap(&vals[left], &vals[right]);
+ ++left;
+ }
+ /* Move left pivot-equivalent entries to the left of the boundary. */
+ while (pivot_left > 0) {
+ --pivot_left;
+ --left;
+ grn_ts_rec_swap(&recs[pivot_left], &recs[left]);
+ grn_ts_text_swap(&vals[pivot_left], &vals[left]);
+ }
+ /* Move right pivot-equivalent entries to the right of the boundary. */
+ while (pivot_right < n_recs) {
+ grn_ts_rec_swap(&recs[pivot_right], &recs[right]);
+ grn_ts_text_swap(&vals[pivot_right], &vals[right]);
+ ++pivot_right;
+ ++right;
+ }
+ /* Apply the next sort condition to the pivot-equivalent recs. */
+ if (node->next) {
+ if (((right - left) >= 2) && (offset < right) && (limit > left)) {
+ size_t next_offset = (offset < left) ? 0 : (offset - left);
+ size_t next_limit = ((limit > right) ? right : limit) - left;
+ rc = grn_ts_sorter_node_sort(ctx, node->next, next_offset, next_limit,
+ recs + left, right - left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ /*
+ * Use a recursive call to sort the smaller group so that the recursion
+ * depth is less than log_2(n_recs).
+ */
+ if (left < (n_recs - right)) {
+ if ((offset < left) && (left >= 2)) {
+ size_t next_limit = (limit < left) ? limit : left;
+ rc = grn_ts_qsort_by_text_desc(ctx, node, offset, next_limit,
+ vals, recs, left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (limit <= right) {
+ return GRN_SUCCESS;
+ }
+ vals += right;
+ recs += right;
+ n_recs -= right;
+ offset = (offset < right) ? 0 : (offset - right);
+ limit -= right;
+ } else {
+ if ((limit > right) && ((n_recs - right) >= 2)) {
+ size_t next_offset = (offset < right) ? 0 : (offset - right);
+ size_t next_limit = limit - right;
+ rc = grn_ts_qsort_by_text_desc(ctx, node, next_offset, next_limit,
+ vals + right, recs + right,
+ n_recs - right);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (offset >= left) {
+ return GRN_SUCCESS;
+ }
+ n_recs = left;
+ if (limit > left) {
+ limit = left;
+ }
+ }
+ }
+ if (n_recs >= 2) {
+ rc = grn_ts_isort_by_text_desc(ctx, node, offset, limit,
+ vals, recs, n_recs);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_text_get_label() returns a label. */
+inline static int
+grn_ts_text_get_label(grn_ts_text val, size_t depth)
+{
+ return (depth < val.size) ? (uint8_t)val.ptr[depth] : -1;
+}
+
+/* grn_ts_text_cmp2() compares Text values. */
+inline static int
+grn_ts_text_cmp2(grn_ts_text lhs, grn_ts_text rhs, size_t depth)
+{
+ size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
+ int result = memcmp(lhs.ptr + depth, rhs.ptr + depth, min_size - depth);
+ if (result != 0) {
+ return result;
+ }
+ if (lhs.size == rhs.size) {
+ return 0;
+ }
+ return (lhs.size < rhs.size) ? -1 : 1;
+}
+
+/* grn_ts_move_pivot_by_text_asc2() moves the pivot to the front. */
+static void
+grn_ts_move_pivot_by_text_asc2(grn_ts_sorter_node *node, grn_ts_text *vals,
+ grn_ts_record *recs, size_t n_recs, size_t depth)
+{
+ /* Choose the median from recs[1], recs[n_recs / 2], and recs[n_recs - 2]. */
+ size_t first = 1;
+ size_t middle = n_recs / 2;
+ size_t last = n_recs - 2;
+ int first_label = grn_ts_text_get_label(vals[first], depth);
+ int middle_label = grn_ts_text_get_label(vals[middle], depth);
+ int last_label = grn_ts_text_get_label(vals[last], depth);
+ if (first_label < middle_label) {
+ /* first < middle. */
+ if (middle_label < last_label) {
+ /* first < middle < last */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ grn_ts_text_swap(&vals[0], &vals[middle]);
+ } else if (first_label < last_label) {
+ /* first < last < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ grn_ts_text_swap(&vals[0], &vals[last]);
+ } else { /* last < first < middle. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ grn_ts_text_swap(&vals[0], &vals[first]);
+ }
+ } else if (last_label < middle_label) {
+ /* last < middle < first. */
+ grn_ts_rec_swap(&recs[0], &recs[middle]);
+ grn_ts_text_swap(&vals[0], &vals[middle]);
+ } else if (last_label < first_label) {
+ /* middle < last < first. */
+ grn_ts_rec_swap(&recs[0], &recs[last]);
+ grn_ts_text_swap(&vals[0], &vals[last]);
+ } else { /* middle < first < last. */
+ grn_ts_rec_swap(&recs[0], &recs[first]);
+ grn_ts_text_swap(&vals[0], &vals[first]);
+ }
+}
+
+/* grn_ts_isort_by_text_asc2() sorts records. */
+static grn_rc
+grn_ts_isort_by_text_asc2(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit, grn_ts_text *vals,
+ grn_ts_record *recs, size_t n_recs, size_t depth)
+{
+ for (size_t i = 1; i < n_recs; ++i) {
+ for (size_t j = i; j > 0; --j) {
+ if (grn_ts_text_cmp2(vals[j], vals[j - 1], depth) < 0) {
+ grn_ts_rec_swap(&recs[j], &recs[j - 1]);
+ grn_ts_text_swap(&vals[j], &vals[j - 1]);
+ } else {
+ break;
+ }
+ }
+ }
+ /* Apply the next sorting if there are score duplicates. */
+ if (node->next) {
+ grn_rc rc;
+ size_t begin = 0;
+ for (size_t i = 1; i < n_recs; ++i) {
+ if (grn_ts_text_cmp2(vals[i], vals[begin], depth) != 0) {
+ if ((i - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, i - begin,
+ recs + begin, i - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ begin = i;
+ }
+ }
+ if ((n_recs - begin) >= 2) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, 0, n_recs - begin,
+ recs + begin, n_recs - begin);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_qsort_by_text_asc() sorts records. */
+static grn_rc
+grn_ts_qsort_by_text_asc2(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit, grn_ts_text *vals,
+ grn_ts_record *recs, size_t n_recs, size_t depth)
+{
+ grn_rc rc;
+ /*
+ * FIXME: Currently, the threshold is 16.
+ * This value should be optimized and replaced with a named constant.
+ */
+ while (n_recs >= 16) {
+ int pivot;
+ size_t left, right;
+ size_t pivot_left, pivot_right;
+ grn_ts_move_pivot_by_text_asc2(node, vals, recs, n_recs, depth);
+ pivot = grn_ts_text_get_label(vals[0], depth);
+ left = 1;
+ right = n_recs;
+ pivot_left = 1;
+ pivot_right = n_recs;
+ for ( ; ; ) {
+ /*
+ * Prior entries are moved to left. Less prior entries are moved to
+ * right. Entries which equal to the pivot are moved to the edges.
+ */
+ while (left < right) {
+ int label = grn_ts_text_get_label(vals[left], depth);
+ if (label > pivot) {
+ break;
+ } else if (label == pivot) {
+ grn_ts_rec_swap(&recs[left], &recs[pivot_left]);
+ grn_ts_text_swap(&vals[left], &vals[pivot_left]);
+ ++pivot_left;
+ }
+ ++left;
+ }
+ while (left < right) {
+ int label;
+ --right;
+ label = grn_ts_text_get_label(vals[right], depth);
+ if (label < pivot) {
+ break;
+ } else if (label == pivot) {
+ --pivot_right;
+ grn_ts_rec_swap(&recs[right], &recs[pivot_right]);
+ grn_ts_text_swap(&vals[right], &vals[pivot_right]);
+ }
+ }
+ if (left >= right) {
+ break;
+ }
+ grn_ts_rec_swap(&recs[left], &recs[right]);
+ grn_ts_text_swap(&vals[left], &vals[right]);
+ ++left;
+ }
+ /* Move left pivot-equivalent entries to the left of the boundary. */
+ while (pivot_left > 0) {
+ --pivot_left;
+ --left;
+ grn_ts_rec_swap(&recs[pivot_left], &recs[left]);
+ grn_ts_text_swap(&vals[pivot_left], &vals[left]);
+ }
+ /* Move right pivot-equivalent entries to the right of the boundary. */
+ while (pivot_right < n_recs) {
+ grn_ts_rec_swap(&recs[pivot_right], &recs[right]);
+ grn_ts_text_swap(&vals[pivot_right], &vals[right]);
+ ++pivot_right;
+ ++right;
+ }
+ /* Apply the next sort condition to the pivot-equivalent recs. */
+ if (((right - left) >= 2) && (offset < right) && (limit > left)) {
+ size_t next_offset = (offset < left) ? 0 : (offset - left);
+ size_t next_limit = ((limit > right) ? right : limit) - left;
+ if (pivot != -1) {
+ rc = grn_ts_qsort_by_text_asc2(ctx, node, next_offset, next_limit,
+ vals, recs + left, right - left,
+ depth + 1);
+ } else if (node->next) {
+ rc = grn_ts_sorter_node_sort(ctx, node->next, next_offset, next_limit,
+ recs + left, right - left);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ }
+ /*
+ * Use a recursive call to sort the smaller group so that the recursion
+ * depth is less than log_2(n_recs).
+ */
+ if (left < (n_recs - right)) {
+ if ((offset < left) && (left >= 2)) {
+ size_t next_limit = (limit < left) ? limit : left;
+ rc = grn_ts_qsort_by_text_asc2(ctx, node, offset, next_limit,
+ vals, recs, left, depth);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (limit <= right) {
+ return GRN_SUCCESS;
+ }
+ vals += right;
+ recs += right;
+ n_recs -= right;
+ offset = (offset < right) ? 0 : (offset - right);
+ limit -= right;
+ } else {
+ if ((limit > right) && ((n_recs - right) >= 2)) {
+ size_t next_offset = (offset < right) ? 0 : (offset - right);
+ size_t next_limit = limit - right;
+ rc = grn_ts_qsort_by_text_asc2(ctx, node, next_offset, next_limit,
+ vals + right, recs + right,
+ n_recs - right, depth);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if (offset >= left) {
+ return GRN_SUCCESS;
+ }
+ n_recs = left;
+ if (limit > left) {
+ limit = left;
+ }
+ }
+ }
+ if (n_recs >= 2) {
+ rc = grn_ts_isort_by_text_asc2(ctx, node, offset, limit,
+ vals, recs, n_recs, depth);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/* grn_ts_sorter_node_sort_by_var() sorts records. */
+static grn_rc
+grn_ts_sorter_node_sort_by_var(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ size_t i;
+ grn_rc rc;
+ switch (node->expr->data_kind) {
+ case GRN_TS_INT: {
+ grn_ts_int *vals;
+ rc = grn_ts_expr_evaluate_to_buf(ctx, node->expr, recs, n_recs,
+ &node->buf);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ vals = (grn_ts_int *)node->buf.ptr;
+ if (node->reverse) {
+ for (i = 0; i < n_recs; i++) {
+ vals[i] = -1 - vals[i];
+ }
+ }
+ return grn_ts_qsort_by_int(ctx, node, offset, limit, vals, recs, n_recs);
+ }
+ case GRN_TS_FLOAT: {
+ grn_ts_int *vals;
+ rc = grn_ts_expr_evaluate_to_buf(ctx, node->expr, recs, n_recs,
+ &node->buf);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ vals = (grn_ts_int *)node->buf.ptr;
+ if (node->reverse) {
+ for (i = 0; i < n_recs; i++) {
+ if (vals[i] < 0) {
+ vals[i] = (vals[i] ^ INT64_MAX) + 1;
+ }
+ vals[i] = -1 - vals[i];
+ }
+ } else {
+ for (i = 0; i < n_recs; i++) {
+ if (vals[i] < 0) {
+ vals[i] = (vals[i] ^ INT64_MAX) + 1;
+ }
+ }
+ }
+ return grn_ts_qsort_by_int(ctx, node, offset, limit, vals, recs, n_recs);
+ }
+ case GRN_TS_TIME: {
+ grn_ts_int *vals;
+ rc = grn_ts_expr_evaluate_to_buf(ctx, node->expr, recs, n_recs,
+ &node->buf);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ vals = (grn_ts_int *)node->buf.ptr;
+ if (node->reverse) {
+ for (i = 0; i < n_recs; i++) {
+ vals[i] = -1 - vals[i];
+ }
+ }
+ return grn_ts_qsort_by_int(ctx, node, offset, limit, vals, recs, n_recs);
+ }
+ case GRN_TS_TEXT: {
+ grn_ts_text *vals;
+ rc = grn_ts_expr_evaluate_to_buf(ctx, node->expr, recs, n_recs,
+ &node->buf);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ vals = (grn_ts_text *)node->buf.ptr;
+ if (node->reverse) {
+ return grn_ts_qsort_by_text_desc(ctx, node, offset, limit,
+ vals, recs, n_recs);
+ } else {
+ return grn_ts_qsort_by_text_asc2(ctx, node, offset, limit,
+ vals, recs, n_recs, 0);
+ }
+ }
+ case GRN_TS_INT_VECTOR:
+ case GRN_TS_FLOAT_VECTOR:
+ case GRN_TS_TIME_VECTOR:
+ case GRN_TS_TEXT_VECTOR: {
+ // TODO
+ GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED, "not supported yet");
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+ node->expr->data_kind);
+ }
+ }
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+}
+
+/* grn_ts_sorter_node_sort() sorts records. */
+static grn_rc
+grn_ts_sorter_node_sort(grn_ctx *ctx, grn_ts_sorter_node *node,
+ size_t offset, size_t limit,
+ grn_ts_record *recs, size_t n_recs)
+{
+ switch (node->expr->type) {
+ case GRN_TS_EXPR_ID: {
+ return grn_ts_sorter_node_sort_by_id(ctx, node, offset, limit,
+ recs, n_recs);
+ }
+ case GRN_TS_EXPR_SCORE: {
+ return grn_ts_sorter_node_sort_by_score(ctx, node, offset, limit,
+ recs, n_recs);
+ }
+ case GRN_TS_EXPR_CONST: {
+ if (!node->next) {
+ return GRN_SUCCESS;
+ }
+ return grn_ts_sorter_node_sort(ctx, node->next, offset, limit, recs,
+ n_recs);
+ }
+ case GRN_TS_EXPR_VARIABLE: {
+ return grn_ts_sorter_node_sort_by_var(ctx, node, offset, limit,
+ recs, n_recs);
+ break;
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid expr type: %d",
+ node->expr->type);
+ }
+ }
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_sorter.
+ */
+
+static void
+grn_ts_sorter_init(grn_ctx *ctx, grn_ts_sorter *sorter)
+{
+ memset(sorter, 0, sizeof(*sorter));
+ sorter->table = NULL;
+ sorter->head = NULL;
+}
+
+static void
+grn_ts_sorter_fin(grn_ctx *ctx, grn_ts_sorter *sorter)
+{
+ if (sorter->head) {
+ grn_ts_sorter_node_list_close(ctx, sorter->head);
+ }
+ if (sorter->table) {
+ grn_obj_unlink(ctx, sorter->table);
+ }
+}
+
+grn_rc
+grn_ts_sorter_open(grn_ctx *ctx, grn_obj *table, grn_ts_sorter_node *head,
+ size_t offset, size_t limit, grn_ts_sorter **sorter)
+{
+ grn_rc rc;
+ grn_ts_sorter *new_sorter;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!table || !grn_ts_obj_is_table(ctx, table) || !head || !sorter) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ new_sorter = GRN_MALLOCN(grn_ts_sorter, 1);
+ if (!new_sorter) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_sorter));
+ }
+ rc = grn_ts_obj_increment_ref_count(ctx, table);
+ if (rc != GRN_SUCCESS) {
+ GRN_FREE(new_sorter);
+ return rc;
+ }
+ grn_ts_sorter_init(ctx, new_sorter);
+ new_sorter->table = table;
+ new_sorter->head = head;
+ new_sorter->offset = offset;
+ new_sorter->limit = limit;
+ /* FIXME: Enable partial sorting. */
+/* new_sorter->partial = (offset + limit) < 1000;*/
+ *sorter = new_sorter;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_sorter_parse(grn_ctx *ctx, grn_obj *table,
+ grn_ts_str str, size_t offset,
+ size_t limit, grn_ts_sorter **sorter)
+{
+ grn_rc rc;
+ grn_ts_sorter *new_sorter = NULL;
+ grn_ts_expr_parser *parser;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!table || !grn_ts_obj_is_table(ctx, table) || !str.size || !sorter) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ rc = grn_ts_expr_parser_open(ctx, table, &parser);
+ if (rc == GRN_SUCCESS) {
+ grn_ts_sorter_builder *builder;
+ rc = grn_ts_sorter_builder_open(ctx, table, &builder);
+ if (rc == GRN_SUCCESS) {
+ grn_ts_str first, rest = str;
+ for ( ; ; ) {
+ grn_ts_expr *expr;
+ grn_ts_bool reverse = GRN_FALSE;
+ rc = grn_ts_expr_parser_split(ctx, parser, rest, &first, &rest);
+ if (rc == GRN_END_OF_DATA) {
+ rc = grn_ts_sorter_builder_complete(ctx, builder, offset, limit,
+ &new_sorter);
+ break;
+ } else if (rc != GRN_SUCCESS) {
+ break;
+ }
+ if (first.ptr[0] == '-') {
+ reverse = GRN_TRUE;
+ first.ptr++;
+ first.size--;
+ }
+ rc = grn_ts_expr_parser_parse(ctx, parser, first, &expr);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ rc = grn_ts_sorter_builder_push(ctx, builder, expr, reverse);
+ if (rc != GRN_SUCCESS) {
+ grn_ts_expr_close(ctx, expr);
+ break;
+ }
+ }
+ grn_ts_sorter_builder_close(ctx, builder);
+ }
+ grn_ts_expr_parser_close(ctx, parser);
+ }
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ *sorter = new_sorter;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_sorter_close(grn_ctx *ctx, grn_ts_sorter *sorter)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!sorter) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ grn_ts_sorter_fin(ctx, sorter);
+ GRN_FREE(sorter);
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_sorter_progress(grn_ctx *ctx, grn_ts_sorter *sorter,
+ grn_ts_record *recs, size_t n_recs, size_t *n_rest)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!sorter || (!recs && n_recs) || !n_rest) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ if (sorter->partial) {
+ return grn_ts_sorter_node_progress(ctx, sorter->head, sorter->offset,
+ sorter->limit, recs, n_recs, n_rest);
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_sorter_complete(grn_ctx *ctx, grn_ts_sorter *sorter,
+ grn_ts_record *recs, size_t n_recs, size_t *n_rest)
+{
+ grn_rc rc;
+ size_t i, limit;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!sorter || (!recs && n_recs) || !n_rest) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ if (sorter->offset >= n_recs) {
+ return GRN_SUCCESS;
+ }
+ limit = sorter->limit;
+ if (limit > (n_recs - sorter->offset)) {
+ limit = n_recs;
+ } else {
+ limit += sorter->offset;
+ }
+ if (sorter->partial) {
+ // FIXME: If there was no input. Partial sorting is not required.
+ rc = grn_ts_sorter_node_progress(ctx, sorter->head, sorter->offset,
+ limit, recs, n_recs, n_rest);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_ts_sorter_node_complete(ctx, sorter->head, sorter->offset,
+ limit, recs, n_recs, n_rest);
+ }
+ } else {
+ rc = grn_ts_sorter_node_sort(ctx, sorter->head, sorter->offset,
+ limit, recs, n_recs);
+ }
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (sorter->offset) {
+ for (i = 0; i < limit; i++) {
+ recs[i] = recs[sorter->offset + i];
+ }
+ }
+ *n_rest = limit;
+ return GRN_SUCCESS;
+}
+
+/*-------------------------------------------------------------
+ * grn_ts_sorter_builder.
+ */
+
+/* grn_ts_sorter_builder_init() initializes a sorter builder. */
+static void
+grn_ts_sorter_builder_init(grn_ctx *ctx, grn_ts_sorter_builder *builder)
+{
+ memset(builder, 0, sizeof(*builder));
+ builder->table = NULL;
+ builder->head = NULL;
+ builder->tail = NULL;
+}
+
+/* grn_ts_sorter_builder_fin() finalizes a sorter builder. */
+static void
+grn_ts_sorter_builder_fin(grn_ctx *ctx, grn_ts_sorter_builder *builder)
+{
+ if (builder->head) {
+ grn_ts_sorter_node_list_close(ctx, builder->head);
+ }
+ if (builder->table) {
+ grn_obj_unlink(ctx, builder->table);
+ }
+}
+
+grn_rc
+grn_ts_sorter_builder_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_sorter_builder **builder)
+{
+ grn_rc rc;
+ grn_ts_sorter_builder *new_builder;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!table || !grn_ts_obj_is_table(ctx, table) || !builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ new_builder = GRN_MALLOCN(grn_ts_sorter_builder, 1);
+ if (!new_builder) {
+ GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
+ "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
+ sizeof(grn_ts_sorter_builder));
+ }
+ grn_ts_sorter_builder_init(ctx, new_builder);
+ rc = grn_ts_obj_increment_ref_count(ctx, table);
+ if (rc != GRN_SUCCESS) {
+ grn_ts_sorter_builder_fin(ctx, new_builder);
+ GRN_FREE(new_builder);
+ return rc;
+ }
+ new_builder->table = table;
+ *builder = new_builder;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_sorter_builder_close(grn_ctx *ctx, grn_ts_sorter_builder *builder)
+{
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ grn_ts_sorter_builder_fin(ctx, builder);
+ GRN_FREE(builder);
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_sorter_builder_complete(grn_ctx *ctx, grn_ts_sorter_builder *builder,
+ size_t offset, size_t limit,
+ grn_ts_sorter **sorter)
+{
+ grn_rc rc;
+ grn_ts_sorter *new_sorter;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder || !builder->head || !sorter) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ rc = grn_ts_sorter_open(ctx, builder->table, builder->head,
+ offset, limit, &new_sorter);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ builder->head = NULL;
+ builder->tail = NULL;
+ *sorter = new_sorter;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ts_sorter_builder_push(grn_ctx *ctx, grn_ts_sorter_builder *builder,
+ grn_ts_expr *expr, grn_ts_bool reverse)
+{
+ grn_rc rc;
+ grn_ts_sorter_node *new_node;
+ if (!ctx) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!builder || !expr || expr->table != builder->table) {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ switch (expr->data_kind) {
+ case GRN_TS_INT:
+ case GRN_TS_FLOAT:
+ case GRN_TS_TIME:
+ case GRN_TS_TEXT: {
+ break;
+ }
+ case GRN_TS_INT_VECTOR:
+ case GRN_TS_FLOAT_VECTOR:
+ case GRN_TS_TIME_VECTOR:
+ case GRN_TS_TEXT_VECTOR: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "not supported yet");
+ }
+ default: {
+ GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
+ }
+ }
+ rc = grn_ts_sorter_node_open(ctx, expr, reverse, &new_node);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (builder->tail) {
+ builder->tail->next = new_node;
+ } else {
+ builder->head = new_node;
+ }
+ builder->tail = new_node;
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_sorter.h b/storage/mroonga/vendor/groonga/lib/ts/ts_sorter.h
new file mode 100644
index 00000000000..069154d26ba
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_sorter.h
@@ -0,0 +1,98 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#include "ts_expr.h"
+#include "ts_str.h"
+#include "ts_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* TODO: Sorting should take into account the order of input records. */
+
+typedef struct grn_ts_sorter_node {
+ grn_ts_expr *expr; /* Expression. */
+ grn_ts_bool reverse; /* Reverse order or not. */
+ grn_ts_buf buf; /* Buffer for values. */
+ struct grn_ts_sorter_node *next; /* Next node. */
+} grn_ts_sorter_node;
+
+typedef struct {
+ grn_obj *table; /* Table. */
+ grn_ts_sorter_node *head; /* First node. */
+ size_t offset; /* Top `offset` records will be discarded. */
+ size_t limit; /* At most `limit` records will be left. */
+ grn_ts_bool partial; /* Partial sorting or not. */
+} grn_ts_sorter;
+
+/* grn_ts_sorter_open() creates a sorter. */
+grn_rc grn_ts_sorter_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_sorter_node *head, size_t offset,
+ size_t limit, grn_ts_sorter **sorter);
+
+/* grn_ts_sorter_parse() parses a string and creates a sorter. */
+grn_rc grn_ts_sorter_parse(grn_ctx *ctx, grn_obj *table,
+ grn_ts_str str, size_t offset,
+ size_t limit, grn_ts_sorter **sorter);
+
+/* grn_ts_sorter_close() destroys a sorter. */
+grn_rc grn_ts_sorter_close(grn_ctx *ctx, grn_ts_sorter *sorter);
+
+/* grn_ts_sorter_progress() progresses sorting. */
+grn_rc grn_ts_sorter_progress(grn_ctx *ctx, grn_ts_sorter *sorter,
+ grn_ts_record *recs, size_t n_recs,
+ size_t *n_rest);
+
+/* grn_ts_sorter_complete() completes sorting. */
+grn_rc grn_ts_sorter_complete(grn_ctx *ctx, grn_ts_sorter *sorter,
+ grn_ts_record *recs, size_t n_recs,
+ size_t *n_rest);
+
+typedef struct {
+ grn_obj *table; /* Table. */
+ grn_ts_sorter_node *head; /* First node. */
+ grn_ts_sorter_node *tail; /* Last node. */
+} grn_ts_sorter_builder;
+
+/* grn_ts_sorter_builder_open() creates a sorter builder. */
+grn_rc grn_ts_sorter_builder_open(grn_ctx *ctx, grn_obj *table,
+ grn_ts_sorter_builder **builder);
+
+/* grn_ts_sorter_builder_close() destroys a sorter builder. */
+grn_rc grn_ts_sorter_builder_close(grn_ctx *ctx,
+ grn_ts_sorter_builder *builder);
+
+/* grn_ts_sorter_builder_complete() completes a sorter. */
+grn_rc grn_ts_sorter_builder_complete(grn_ctx *ctx,
+ grn_ts_sorter_builder *builder,
+ size_t offset, size_t limit,
+ grn_ts_sorter **sorter);
+
+/* grn_ts_sorter_builder_push() pushes a node. */
+grn_rc grn_ts_sorter_builder_push(grn_ctx *ctx, grn_ts_sorter_builder *builder,
+ grn_ts_expr *expr, grn_ts_bool reverse);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_str.c b/storage/mroonga/vendor/groonga/lib/ts/ts_str.c
new file mode 100644
index 00000000000..6a8792eebc2
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_str.c
@@ -0,0 +1,191 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_str.h"
+
+#include <ctype.h>
+#include <string.h>
+
+/*-------------------------------------------------------------
+ * Byte.
+ */
+
+grn_ts_bool
+grn_ts_byte_is_decimal(uint8_t byte)
+{
+ return (byte >= '0') && (byte <= '9');
+}
+
+grn_ts_bool
+grn_ts_byte_is_name_char(uint8_t byte)
+{
+ /*
+ * Note: A table name allows '#', '@' and '-'.
+ * http://groonga.org/docs/reference/commands/table_create.html#name
+ */
+ if (((byte >= '0') && (byte <= '9')) || ((byte >= 'A') && (byte <= 'Z')) ||
+ ((byte >= 'a') && (byte <= 'z')) || (byte == '_')) {
+ return GRN_TRUE;
+ }
+ return GRN_FALSE;
+}
+
+/*-------------------------------------------------------------
+ * String.
+ */
+
+grn_ts_bool
+grn_ts_str_starts_with(grn_ts_str str, grn_ts_str prefix)
+{
+ if (str.size < prefix.size) {
+ return GRN_FALSE;
+ }
+ return !memcmp(str.ptr, prefix.ptr, prefix.size);
+}
+
+grn_ts_str
+grn_ts_str_trim_left(grn_ts_str str)
+{
+ size_t i;
+ for (i = 0; i < str.size; i++) {
+ if (!isspace((uint8_t)str.ptr[i])) {
+ break;
+ }
+ }
+ str.ptr += i;
+ str.size -= i;
+ return str;
+}
+
+grn_ts_str
+grn_ts_str_trim_score_assignment(grn_ts_str str)
+{
+ grn_ts_str rest;
+ str = grn_ts_str_trim_left(str);
+ if (!grn_ts_str_starts_with(str, (grn_ts_str){ "_score", 6 })) {
+ return str;
+ }
+ rest.ptr = str.ptr + 6;
+ rest.size = str.size - 6;
+ rest = grn_ts_str_trim_left(rest);
+ if (!rest.size || (rest.ptr[0] != '=') ||
+ ((rest.size >= 2) && (rest.ptr[1] == '='))) {
+ return str;
+ }
+ rest.ptr++;
+ rest.size--;
+ return grn_ts_str_trim_left(rest);
+}
+
+grn_ts_bool
+grn_ts_str_has_number_prefix(grn_ts_str str)
+{
+ if (!str.size) {
+ return GRN_FALSE;
+ }
+ if (grn_ts_byte_is_decimal(str.ptr[0])) {
+ return GRN_TRUE;
+ }
+ if (str.size == 1) {
+ return GRN_FALSE;
+ }
+ switch (str.ptr[0]) {
+ case '+': case '-': {
+ if (grn_ts_byte_is_decimal(str.ptr[1])) {
+ return GRN_TRUE;
+ }
+ if (str.size == 2) {
+ return GRN_FALSE;
+ }
+ return (str.ptr[1] == '.') && grn_ts_byte_is_decimal(str.ptr[2]);
+ }
+ case '.': {
+ return grn_ts_byte_is_decimal(str.ptr[1]);
+ }
+ default: {
+ return GRN_FALSE;
+ }
+ }
+}
+
+grn_ts_bool
+grn_ts_str_is_name_prefix(grn_ts_str str)
+{
+ size_t i;
+ for (i = 0; i < str.size; i++) {
+ if (!grn_ts_byte_is_name_char(str.ptr[i])) {
+ return GRN_FALSE;
+ }
+ }
+ return GRN_TRUE;
+}
+
+grn_ts_bool
+grn_ts_str_is_name(grn_ts_str str)
+{
+ if (!str.size) {
+ return GRN_FALSE;
+ }
+ return grn_ts_str_is_name_prefix(str);
+}
+
+grn_ts_bool
+grn_ts_str_is_true(grn_ts_str str)
+{
+ return (str.size == 4) && !memcmp(str.ptr, "true", 4);
+}
+
+grn_ts_bool
+grn_ts_str_is_false(grn_ts_str str)
+{
+ return (str.size == 5) && !memcmp(str.ptr, "false", 5);
+}
+
+grn_ts_bool
+grn_ts_str_is_bool(grn_ts_str str)
+{
+ return grn_ts_str_is_true(str) || grn_ts_str_is_false(str);
+}
+
+grn_ts_bool
+grn_ts_str_is_id_name(grn_ts_str str)
+{
+ return (str.size == GRN_COLUMN_NAME_ID_LEN) &&
+ !memcmp(str.ptr, GRN_COLUMN_NAME_ID, GRN_COLUMN_NAME_ID_LEN);
+}
+
+grn_ts_bool
+grn_ts_str_is_score_name(grn_ts_str str)
+{
+ return (str.size == GRN_COLUMN_NAME_SCORE_LEN) &&
+ !memcmp(str.ptr, GRN_COLUMN_NAME_SCORE, GRN_COLUMN_NAME_SCORE_LEN);
+}
+
+grn_ts_bool
+grn_ts_str_is_key_name(grn_ts_str str)
+{
+ return (str.size == GRN_COLUMN_NAME_KEY_LEN) &&
+ !memcmp(str.ptr, GRN_COLUMN_NAME_KEY, GRN_COLUMN_NAME_KEY_LEN);
+}
+
+grn_ts_bool
+grn_ts_str_is_value_name(grn_ts_str str)
+{
+ return (str.size == GRN_COLUMN_NAME_VALUE_LEN) &&
+ !memcmp(str.ptr, GRN_COLUMN_NAME_VALUE, GRN_COLUMN_NAME_VALUE_LEN);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_str.h b/storage/mroonga/vendor/groonga/lib/ts/ts_str.h
new file mode 100644
index 00000000000..bca07b92fb7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_str.h
@@ -0,0 +1,106 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#include "ts_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------------------------------------------------
+ * Byte.
+ */
+
+/* grn_ts_byte_is_decimal() returns whether or not a byte is decimal. */
+grn_ts_bool grn_ts_byte_is_decimal(uint8_t byte);
+
+/*
+ * grn_ts_byte_is_name_char() returns whether or not a byte is allowed as a
+ * part of a name.
+ */
+grn_ts_bool grn_ts_byte_is_name_char(uint8_t byte);
+
+/*-------------------------------------------------------------
+ * String.
+ */
+
+typedef struct {
+ const char *ptr; /* The starting address. */
+ size_t size; /* The size in bytes. */
+} grn_ts_str;
+
+/* grn_ts_str_has_prefix() returns whether or not str starts with prefix. */
+grn_ts_bool grn_ts_str_starts_with(grn_ts_str str, grn_ts_str prefix);
+
+/* grn_ts_str_trim_left() returns a string without leading white-spaces. */
+grn_ts_str grn_ts_str_trim_left(grn_ts_str str);
+
+/*
+ * grn_ts_str_trim_score_assignment() returns a string without leading
+ * white-spaces and an assignment to _score. If `str` does not start with
+ * an assignment, this function returns `grn_ts_str_trim_left(str)`.
+ */
+grn_ts_str grn_ts_str_trim_score_assignment(grn_ts_str str);
+
+/*
+ * grn_ts_str_has_number_prefix() returns whether or not a string starts with a
+ * number or not.
+ */
+grn_ts_bool grn_ts_str_has_number_prefix(grn_ts_str str);
+
+/*
+ * grn_ts_str_is_name_prefix() returns whether or not a string is valid as a
+ * name prefix. Note that an empty string is a name prefix.
+ */
+grn_ts_bool grn_ts_str_is_name_prefix(grn_ts_str str);
+
+/*
+ * grn_ts_str_is_name() returns whether or not a string is valid as a name.
+ * Note that an empty string is invalid as a name.
+ */
+grn_ts_bool grn_ts_str_is_name(grn_ts_str str);
+
+/* grn_ts_str_is_true() returns str == "true". */
+grn_ts_bool grn_ts_str_is_true(grn_ts_str str);
+
+/* grn_ts_str_is_false() returns str == "false". */
+grn_ts_bool grn_ts_str_is_false(grn_ts_str str);
+
+/* grn_ts_str_is_bool() returns (str == "true") || (str == "false"). */
+grn_ts_bool grn_ts_str_is_bool(grn_ts_str str);
+
+/* grn_ts_str_is_id_name() returns str == "_id". */
+grn_ts_bool grn_ts_str_is_id_name(grn_ts_str str);
+
+/* grn_ts_str_is_score_name() returns str == "_score". */
+grn_ts_bool grn_ts_str_is_score_name(grn_ts_str str);
+
+/* grn_ts_str_is_key_name() returns str == "_key". */
+grn_ts_bool grn_ts_str_is_key_name(grn_ts_str str);
+
+/* grn_ts_str_is_value_name() returns str == "_value". */
+grn_ts_bool grn_ts_str_is_value_name(grn_ts_str str);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_types.h b/storage/mroonga/vendor/groonga/lib/ts/ts_types.h
new file mode 100644
index 00000000000..5a667e2ad17
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_types.h
@@ -0,0 +1,168 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------------------------------------------------
+ * Built-in data types.
+ */
+
+/* grn_builtin_type or table ID. */
+typedef grn_id grn_ts_data_type;
+
+/* ID (_id). */
+typedef grn_id grn_ts_id;
+
+/* Score (_score). */
+typedef float grn_ts_score;
+
+/* Record (_id, _score). */
+typedef struct {
+ grn_ts_id id;
+ grn_ts_score score;
+} grn_ts_record;
+
+/*-------------------------------------------------------------
+ * Built-in scalar data kinds.
+ */
+
+/* Bool. */
+typedef grn_bool grn_ts_bool;
+
+/* Int. */
+typedef int64_t grn_ts_int;
+
+/* Float. */
+typedef double grn_ts_float;
+
+/* Time. */
+typedef int64_t grn_ts_time;
+
+/* Text. */
+typedef struct {
+ const char *ptr;
+ size_t size;
+} grn_ts_text;
+
+/* Geo. */
+typedef grn_geo_point grn_ts_geo;
+typedef grn_geo_point grn_ts_tokyo_geo;
+typedef grn_geo_point grn_ts_wgs84_geo;
+
+/* Ref. */
+typedef grn_ts_record grn_ts_ref;
+
+/*-------------------------------------------------------------
+ * Built-in vector data kinds.
+ */
+
+/* BoolVector. */
+typedef struct {
+ const grn_ts_bool *ptr;
+ size_t size;
+} grn_ts_bool_vector;
+
+/* IntVector. */
+typedef struct {
+ const grn_ts_int *ptr;
+ size_t size;
+} grn_ts_int_vector;
+
+/* FloatVector. */
+typedef struct {
+ const grn_ts_float *ptr;
+ size_t size;
+} grn_ts_float_vector;
+
+/* TimeVector. */
+typedef struct {
+ const grn_ts_time *ptr;
+ size_t size;
+} grn_ts_time_vector;
+
+/* TextVector. */
+typedef struct {
+ const grn_ts_text *ptr;
+ size_t size;
+} grn_ts_text_vector;
+
+/* GeoVector. */
+typedef struct {
+ const grn_ts_geo *ptr;
+ size_t size;
+} grn_ts_geo_vector;
+typedef grn_ts_geo_vector grn_ts_tokyo_geo_vector;
+typedef grn_ts_geo_vector grn_ts_wgs84_geo_vector;
+
+/* RefVector. */
+typedef struct {
+ const grn_ts_ref *ptr;
+ size_t size;
+} grn_ts_ref_vector;
+
+/*-------------------------------------------------------------
+ * Built-in data kinds.
+ */
+
+enum { GRN_TS_VECTOR_FLAG = 1 << 7 };
+
+typedef enum {
+ GRN_TS_VOID = 0, /* GRN_DB_VOID */
+ GRN_TS_BOOL = 1, /* GRN_DB_BOOL */
+ GRN_TS_INT = 2, /* GRN_DB_[U]INT(8/16/32/64) */
+ GRN_TS_FLOAT = 3, /* GRN_DB_FLOAT */
+ GRN_TS_TIME = 4, /* GRN_DB_TIME */
+ GRN_TS_TEXT = 5, /* GRN_DB_[SHORT_/LONG_]TEST */
+ GRN_TS_GEO = 6, /* GRN_DB_(TOKYO/WGS84)_GEO_POINT */
+ GRN_TS_REF = 7, /* Table reference. */
+ GRN_TS_BOOL_VECTOR = GRN_TS_VECTOR_FLAG | GRN_TS_BOOL,
+ GRN_TS_INT_VECTOR = GRN_TS_VECTOR_FLAG | GRN_TS_INT,
+ GRN_TS_FLOAT_VECTOR = GRN_TS_VECTOR_FLAG | GRN_TS_FLOAT,
+ GRN_TS_TIME_VECTOR = GRN_TS_VECTOR_FLAG | GRN_TS_TIME,
+ GRN_TS_TEXT_VECTOR = GRN_TS_VECTOR_FLAG | GRN_TS_TEXT,
+ GRN_TS_GEO_VECTOR = GRN_TS_VECTOR_FLAG | GRN_TS_GEO,
+ GRN_TS_REF_VECTOR = GRN_TS_VECTOR_FLAG | GRN_TS_REF
+} grn_ts_data_kind;
+
+typedef union {
+ grn_ts_bool as_bool;
+ grn_ts_int as_int;
+ grn_ts_float as_float;
+ grn_ts_time as_time;
+ grn_ts_text as_text;
+ grn_ts_geo as_geo;
+ grn_ts_ref as_ref;
+ grn_ts_bool_vector as_bool_vector;
+ grn_ts_int_vector as_int_vector;
+ grn_ts_float_vector as_float_vector;
+ grn_ts_time_vector as_time_vector;
+ grn_ts_text_vector as_text_vector;
+ grn_ts_geo_vector as_geo_vector;
+ grn_ts_ref_vector as_ref_vector;
+} grn_ts_any;
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_util.c b/storage/mroonga/vendor/groonga/lib/ts/ts_util.c
new file mode 100644
index 00000000000..9e85aa4dc35
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_util.c
@@ -0,0 +1,129 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "ts_util.h"
+
+#include "../grn_dat.h"
+#include "../grn_hash.h"
+#include "../grn_pat.h"
+
+#include "ts_log.h"
+
+grn_rc
+grn_ts_obj_increment_ref_count(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_id id = grn_obj_id(ctx, obj);
+ grn_obj *obj_clone = grn_ctx_at(ctx, id);
+ if (!obj_clone) {
+ GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "grn_ctx_at failed: %d", id);
+ }
+ if (obj_clone != obj) {
+ grn_obj_unlink(ctx, obj_clone);
+ GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "wrong object: %p != %p",
+ obj, obj_clone);
+ }
+ return GRN_SUCCESS;
+}
+
+grn_ts_bool
+grn_ts_obj_is_table(grn_ctx *ctx, grn_obj *obj)
+{
+ return grn_obj_is_table(ctx, obj);
+}
+
+grn_ts_bool
+grn_ts_obj_is_column(grn_ctx *ctx, grn_obj *obj)
+{
+ switch (obj->header.type) {
+ case GRN_COLUMN_FIX_SIZE:
+ case GRN_COLUMN_VAR_SIZE: {
+ return GRN_TRUE;
+ }
+ /* GRN_COLUMN_INDEX is not supported. */
+ default: {
+ return GRN_FALSE;
+ }
+ }
+}
+
+grn_rc
+grn_ts_ja_get_value(grn_ctx *ctx, grn_obj *ja, grn_ts_id id,
+ grn_ts_buf *buf, size_t *value_size)
+{
+ grn_rc rc;
+ uint32_t size;
+ grn_io_win iw;
+ char *ptr = (char *)grn_ja_ref(ctx, (grn_ja *)ja, id, &iw, &size);
+ if (!ptr) {
+ if (value_size) {
+ *value_size = 0;
+ }
+ return GRN_SUCCESS;
+ }
+ rc = grn_ts_buf_write(ctx, buf, ptr, size);
+ grn_ja_unref(ctx, &iw);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (value_size) {
+ *value_size = size;
+ }
+ return GRN_SUCCESS;
+}
+
+grn_ts_bool
+grn_ts_table_has_key(grn_ctx *ctx, grn_obj *table)
+{
+ switch (table->header.type) {
+ case GRN_TABLE_HASH_KEY:
+ case GRN_TABLE_PAT_KEY:
+ case GRN_TABLE_DAT_KEY: {
+ return GRN_TRUE;
+ }
+ default: {
+ return GRN_FALSE;
+ }
+ }
+}
+
+grn_ts_bool
+grn_ts_table_has_value(grn_ctx *ctx, grn_obj *table)
+{
+ return DB_OBJ(table)->range != GRN_DB_VOID;
+}
+
+const void *
+grn_ts_table_get_value(grn_ctx *ctx, grn_obj *table, grn_ts_id id)
+{
+ switch (table->header.type) {
+ case GRN_TABLE_HASH_KEY: {
+ return grn_hash_get_value_(ctx, (grn_hash *)table, id, NULL);
+ }
+ case GRN_TABLE_PAT_KEY: {
+ uint32_t size;
+ return grn_pat_get_value_(ctx, (grn_pat *)table, id, &size);
+ }
+ /* GRN_TABLE_DAT_KEY does not support _value. */
+ case GRN_TABLE_NO_KEY: {
+ return _grn_array_get_value(ctx, (grn_array *)table, id);
+ }
+ default: {
+ return NULL;
+ }
+ }
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_util.h b/storage/mroonga/vendor/groonga/lib/ts/ts_util.h
new file mode 100644
index 00000000000..2ffbdd6f93d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_util.h
@@ -0,0 +1,61 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "../grn.h"
+
+#include "ts_buf.h"
+#include "ts_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* grn_ts_obj_increment_ref_count() increments an object reference count. */
+grn_rc grn_ts_obj_increment_ref_count(grn_ctx *ctx, grn_obj *obj);
+
+/* grn_ts_obj_is_table() returns whether or not an object is a table. */
+grn_ts_bool grn_ts_obj_is_table(grn_ctx *ctx, grn_obj *obj);
+
+/* grn_ts_obj_is_column() returns whether or not an object is a column. */
+grn_ts_bool grn_ts_obj_is_column(grn_ctx *ctx, grn_obj *obj);
+
+/*
+ * grn_ts_ja_get_value() gets a value from ja and writes it to buf. Note that
+ * the value is appended to the end of buf.
+ */
+grn_rc grn_ts_ja_get_value(grn_ctx *ctx, grn_obj *ja, grn_ts_id id,
+ grn_ts_buf *buf, size_t *value_size);
+
+/* grn_ts_table_has_key() returns whether or not a table has _key. */
+grn_ts_bool grn_ts_table_has_key(grn_ctx *ctx, grn_obj *table);
+
+/* grn_ts_table_has_value() returns whether or not a table has _value. */
+grn_ts_bool grn_ts_table_has_value(grn_ctx *ctx, grn_obj *table);
+
+/*
+ * grn_ts_table_get_value() gets a reference to a value (_value). On failure,
+ * this function returns NULL.
+ */
+const void *grn_ts_table_get_value(grn_ctx *ctx, grn_obj *table, grn_ts_id id);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/type.c b/storage/mroonga/vendor/groonga/lib/type.c
new file mode 100644
index 00000000000..845a28890e2
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/type.c
@@ -0,0 +1,87 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_ctx_impl.h"
+#include "grn_db.h"
+
+grn_bool
+grn_type_id_is_builtin(grn_ctx *ctx, grn_id id)
+{
+ return id >= GRN_DB_OBJECT && id <= GRN_DB_WGS84_GEO_POINT;
+}
+
+grn_bool
+grn_type_id_is_number_family(grn_ctx *ctx, grn_id id)
+{
+ return GRN_DB_INT8 <= id && id <= GRN_DB_FLOAT;
+}
+
+grn_bool
+grn_type_id_is_text_family(grn_ctx *ctx, grn_id id)
+{
+ return GRN_DB_SHORT_TEXT <= id && id <= GRN_DB_LONG_TEXT;
+}
+
+grn_obj *
+grn_type_create(grn_ctx *ctx, const char *name, unsigned int name_size,
+ grn_obj_flags flags, unsigned int size)
+{
+ grn_id id;
+ struct _grn_type *res = NULL;
+ grn_obj *db;
+ if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
+ ERR(GRN_INVALID_ARGUMENT, "db not initialized");
+ return NULL;
+ }
+ GRN_API_ENTER;
+ if (grn_db_check_name(ctx, name, name_size)) {
+ GRN_DB_CHECK_NAME_ERR("[type][create]", name, name_size);
+ GRN_API_RETURN(NULL);
+ }
+ if (!GRN_DB_P(db)) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid db assigned");
+ GRN_API_RETURN(NULL);
+ }
+ id = grn_obj_register(ctx, db, name, name_size);
+ if (id && (res = GRN_MALLOC(sizeof(grn_db_obj)))) {
+ GRN_DB_OBJ_SET_TYPE(res, GRN_TYPE);
+ res->obj.header.flags = flags;
+ res->obj.header.domain = GRN_ID_NIL;
+ GRN_TYPE_SIZE(&res->obj) = size;
+ if (grn_db_obj_init(ctx, db, id, DB_OBJ(res))) {
+ // grn_obj_delete(ctx, db, id);
+ GRN_FREE(res);
+ GRN_API_RETURN(NULL);
+ }
+ }
+ GRN_API_RETURN((grn_obj *)res);
+}
+
+uint32_t
+grn_type_size(grn_ctx *ctx, grn_obj *type)
+{
+ uint32_t size;
+
+ GRN_API_ENTER;
+ if (!type) {
+ ERR(GRN_INVALID_ARGUMENT, "[type][size] type is NULL");
+ GRN_API_RETURN(0);
+ }
+ size = GRN_TYPE_SIZE(DB_OBJ(type));
+ GRN_API_RETURN(size);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/util.c b/storage/mroonga/vendor/groonga/lib/util.c
index 17172d6cfeb..27fc944d6a0 100644
--- a/storage/mroonga/vendor/groonga/lib/util.c
+++ b/storage/mroonga/vendor/groonga/lib/util.c
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2010-2015 Brazil
+/*
+ Copyright(C) 2010-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -21,6 +22,7 @@
#include "grn_util.h"
#include "grn_string.h"
#include "grn_expr.h"
+#include "grn_load.h"
#include <string.h>
#include <stdio.h>
@@ -80,11 +82,20 @@ grn_inspect_name(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
int name_size;
name_size = grn_obj_name(ctx, obj, NULL, 0);
- if (name_size) {
+ if (name_size > 0) {
grn_bulk_space(ctx, buf, name_size);
grn_obj_name(ctx, obj, GRN_BULK_CURR(buf) - name_size, name_size);
} else {
- GRN_TEXT_PUTS(ctx, buf, "(nil)");
+ grn_id id;
+
+ id = grn_obj_id(ctx, obj);
+ if (id == GRN_ID_NIL) {
+ GRN_TEXT_PUTS(ctx, buf, "(nil)");
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "(anonymous:");
+ grn_text_lltoa(ctx, buf, id);
+ GRN_TEXT_PUTS(ctx, buf, ")");
+ }
}
return buf;
@@ -237,6 +248,39 @@ grn_inspect_type(grn_ctx *ctx, grn_obj *buf, unsigned char type)
return buf;
}
+
+grn_obj *
+grn_inspect_query_log_flags(grn_ctx *ctx, grn_obj *buffer, unsigned int flags)
+{
+ grn_bool have_content = GRN_FALSE;
+
+ if (flags == GRN_QUERY_LOG_NONE) {
+ GRN_TEXT_PUTS(ctx, buffer, "NONE");
+ return buffer;
+ }
+
+#define CHECK_FLAG(NAME) do { \
+ if (flags & GRN_QUERY_LOG_ ## NAME) { \
+ if (have_content) { \
+ GRN_TEXT_PUTS(ctx, buffer, "|"); \
+ } \
+ GRN_TEXT_PUTS(ctx, buffer, #NAME); \
+ have_content = GRN_TRUE; \
+ } \
+ } while (GRN_FALSE)
+
+ CHECK_FLAG(COMMAND);
+ CHECK_FLAG(RESULT_CODE);
+ CHECK_FLAG(DESTINATION);
+ CHECK_FLAG(CACHE);
+ CHECK_FLAG(SIZE);
+ CHECK_FLAG(SCORE);
+
+#undef CHECK_FALG
+
+ return buffer;
+}
+
static grn_rc
grn_proc_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
{
@@ -271,6 +315,9 @@ grn_proc_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
case GRN_PROC_SCORER :
GRN_TEXT_PUTS(ctx, buf, "scorer");
break;
+ case GRN_PROC_WINDOW_FUNCTION :
+ GRN_TEXT_PUTS(ctx, buf, "window-function");
+ break;
}
GRN_TEXT_PUTS(ctx, buf, " ");
@@ -368,6 +415,30 @@ grn_expr_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *expr)
}
static grn_rc
+grn_ptr_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *ptr)
+{
+ size_t size;
+
+ GRN_TEXT_PUTS(ctx, buffer, "#<ptr:");
+
+ size = GRN_BULK_VSIZE(ptr);
+ if (size == 0) {
+ GRN_TEXT_PUTS(ctx, buffer, "(empty)");
+ } else if (size >= sizeof(grn_obj *)) {
+ grn_obj *content = GRN_PTR_VALUE(ptr);
+ grn_inspect(ctx, buffer, content);
+ if (size > sizeof(grn_obj *)) {
+ grn_text_printf(ctx, buffer,
+ " (and more data: %" GRN_FMT_SIZE ")",
+ size - sizeof(grn_obj *));
+ }
+ }
+ GRN_TEXT_PUTS(ctx, buffer, ">");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
grn_pvector_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *pvector)
{
int i, n;
@@ -426,7 +497,117 @@ grn_vector_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *vector)
static grn_rc
grn_accessor_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
{
- return grn_column_name_(ctx, obj, buf);
+ grn_accessor *accessor = (grn_accessor *)obj;
+
+ GRN_TEXT_PUTS(ctx, buf, "#<accessor ");
+ for (; accessor; accessor = accessor->next) {
+ grn_bool show_obj_name = GRN_FALSE;
+ grn_bool show_obj_domain_name = GRN_FALSE;
+
+ if (accessor != (grn_accessor *)obj) {
+ GRN_TEXT_PUTS(ctx, buf, ".");
+ }
+ switch (accessor->action) {
+ case GRN_ACCESSOR_GET_ID :
+ GRN_TEXT_PUT(ctx,
+ buf,
+ GRN_COLUMN_NAME_ID,
+ GRN_COLUMN_NAME_ID_LEN);
+ show_obj_name = GRN_TRUE;
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ GRN_TEXT_PUT(ctx,
+ buf,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ show_obj_name = GRN_TRUE;
+ break;
+ case GRN_ACCESSOR_GET_VALUE :
+ GRN_TEXT_PUT(ctx,
+ buf,
+ GRN_COLUMN_NAME_VALUE,
+ GRN_COLUMN_NAME_VALUE_LEN);
+ show_obj_name = GRN_TRUE;
+ break;
+ case GRN_ACCESSOR_GET_SCORE :
+ GRN_TEXT_PUT(ctx,
+ buf,
+ GRN_COLUMN_NAME_SCORE,
+ GRN_COLUMN_NAME_SCORE_LEN);
+ break;
+ case GRN_ACCESSOR_GET_NSUBRECS :
+ GRN_TEXT_PUT(ctx,
+ buf,
+ GRN_COLUMN_NAME_NSUBRECS,
+ GRN_COLUMN_NAME_NSUBRECS_LEN);
+ break;
+ case GRN_ACCESSOR_GET_MAX :
+ GRN_TEXT_PUT(ctx,
+ buf,
+ GRN_COLUMN_NAME_MAX,
+ GRN_COLUMN_NAME_MAX_LEN);
+ break;
+ case GRN_ACCESSOR_GET_MIN :
+ GRN_TEXT_PUT(ctx,
+ buf,
+ GRN_COLUMN_NAME_MIN,
+ GRN_COLUMN_NAME_MIN_LEN);
+ break;
+ case GRN_ACCESSOR_GET_SUM :
+ GRN_TEXT_PUT(ctx,
+ buf,
+ GRN_COLUMN_NAME_SUM,
+ GRN_COLUMN_NAME_SUM_LEN);
+ break;
+ case GRN_ACCESSOR_GET_AVG :
+ GRN_TEXT_PUT(ctx,
+ buf,
+ GRN_COLUMN_NAME_AVG,
+ GRN_COLUMN_NAME_AVG_LEN);
+ break;
+ case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ grn_column_name_(ctx, accessor->obj, buf);
+ show_obj_domain_name = GRN_TRUE;
+ break;
+ case GRN_ACCESSOR_GET_DB_OBJ :
+ grn_text_printf(ctx, buf, "(_db)");
+ break;
+ case GRN_ACCESSOR_LOOKUP :
+ grn_text_printf(ctx, buf, "(_lookup)");
+ break;
+ case GRN_ACCESSOR_FUNCALL :
+ grn_text_printf(ctx, buf, "(_funcall)");
+ break;
+ default :
+ grn_text_printf(ctx, buf, "(unknown:%u)", accessor->action);
+ break;
+ }
+
+ if (show_obj_name || show_obj_domain_name) {
+ grn_obj *target = accessor->obj;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+
+ if (show_obj_domain_name) {
+ target = grn_ctx_at(ctx, target->header.domain);
+ }
+
+ name_size = grn_obj_name(ctx,
+ target,
+ name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ GRN_TEXT_PUTS(ctx, buf, "(");
+ if (name_size == 0) {
+ GRN_TEXT_PUTS(ctx, buf, "anonymous");
+ } else {
+ GRN_TEXT_PUT(ctx, buf, name, name_size);
+ }
+ GRN_TEXT_PUTS(ctx, buf, ")");
+ }
+ }
+ GRN_TEXT_PUTS(ctx, buf, ">");
+
+ return GRN_SUCCESS;
}
static grn_rc
@@ -480,7 +661,6 @@ grn_column_inspect_common(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
GRN_TEXT_PUTS(ctx, buf, " range:");
if (range) {
grn_inspect_name(ctx, buf, range);
- grn_obj_unlink(ctx, range);
} else {
grn_text_lltoa(ctx, buf, range_id);
}
@@ -516,6 +696,9 @@ grn_store_inspect_body(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
case GRN_OBJ_COMPRESS_LZ4 :
GRN_TEXT_PUTS(ctx, buf, "lz4");
break;
+ case GRN_OBJ_COMPRESS_ZSTD :
+ GRN_TEXT_PUTS(ctx, buf, "zstd");
+ break;
default:
break;
}
@@ -631,7 +814,6 @@ grn_table_key_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
domain = grn_ctx_at(ctx, domain_id);
if (domain) {
grn_inspect_name(ctx, buf, domain);
- grn_obj_unlink(ctx, domain);
} else if (domain_id) {
grn_text_lltoa(ctx, buf, domain_id);
} else {
@@ -657,7 +839,6 @@ grn_table_columns_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
if (col) {
if (i++ > 0) { GRN_TEXT_PUTS(ctx, buf, ", "); }
grn_column_name_(ctx, col, buf);
- grn_obj_unlink(ctx, col);
}
});
}
@@ -669,6 +850,37 @@ grn_table_columns_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
}
static grn_rc
+grn_table_ids_and_values_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ int i = 0;
+ grn_obj value;
+
+ GRN_VALUE_FIX_SIZE_INIT(&value, 0, grn_obj_get_range(ctx, obj));
+
+ GRN_TEXT_PUTS(ctx, buf, "ids&values:[");
+ GRN_TABLE_EACH_BEGIN(ctx, obj, cursor, id) {
+ void *value_buffer;
+ int value_size;
+
+ if (i++ > 0) {
+ GRN_TEXT_PUTS(ctx, buf, ", ");
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, "\n ");
+ grn_text_lltoa(ctx, buf, id);
+ GRN_TEXT_PUTS(ctx, buf, ":");
+ value_size = grn_table_cursor_get_value(ctx, cursor, &value_buffer);
+ grn_bulk_write_from(ctx, &value, value_buffer, 0, value_size);
+ grn_inspect(ctx, buf, &value);
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ GRN_TEXT_PUTS(ctx, buf, "\n]");
+
+ GRN_OBJ_FIN(ctx, &value);
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
grn_table_ids_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
{
grn_table_cursor *tc;
@@ -700,7 +912,6 @@ grn_table_default_tokenizer_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
GRN_INFO_DEFAULT_TOKENIZER, NULL);
if (default_tokenizer) {
grn_inspect_name(ctx, buf, default_tokenizer);
- grn_obj_unlink(ctx, default_tokenizer);
} else {
GRN_TEXT_PUTS(ctx, buf, "(nil)");
}
@@ -717,7 +928,6 @@ grn_table_normalizer_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
normalizer = grn_obj_get_info(ctx, obj, GRN_INFO_NORMALIZER, NULL);
if (normalizer) {
grn_inspect_name(ctx, buf, normalizer);
- grn_obj_unlink(ctx, normalizer);
} else {
GRN_TEXT_PUTS(ctx, buf, "(nil)");
}
@@ -729,6 +939,10 @@ static grn_rc
grn_table_keys_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
{
grn_table_cursor *tc;
+ int max_n_keys = 10;
+
+ /* TODO */
+ /* max_n_keys = grn_atoi(grn_getenv("GRN_INSPECT_TABLE_MAX_N_KEYS")); */
GRN_TEXT_PUTS(ctx, buf, "keys:[");
tc = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0,
@@ -739,6 +953,10 @@ grn_table_keys_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
grn_obj key;
GRN_OBJ_INIT(&key, GRN_BULK, 0, obj->header.domain);
while ((id = grn_table_cursor_next(ctx, tc))) {
+ if (max_n_keys > 0 && i >= max_n_keys) {
+ GRN_TEXT_PUTS(ctx, buf, ", ...");
+ break;
+ }
if (i++ > 0) { GRN_TEXT_PUTS(ctx, buf, ", "); }
grn_table_get_key2(ctx, obj, id, &key);
grn_inspect(ctx, buf, &key);
@@ -829,7 +1047,11 @@ grn_table_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
if (obj->header.type == GRN_TABLE_NO_KEY) {
GRN_TEXT_PUTS(ctx, buf, " ");
- grn_table_ids_inspect(ctx, buf, obj);
+ if (range) {
+ grn_table_ids_and_values_inspect(ctx, buf, obj);
+ } else {
+ grn_table_ids_inspect(ctx, buf, obj);
+ }
} else {
GRN_TEXT_PUTS(ctx, buf, " ");
grn_table_default_tokenizer_inspect(ctx, buf, obj);
@@ -873,6 +1095,22 @@ grn_db_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
}
static grn_rc
+grn_time_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *obj)
+{
+ int64_t time_raw;
+ int64_t sec;
+ int32_t usec;
+
+ time_raw = GRN_TIME_VALUE(obj);
+ GRN_TIME_UNPACK(time_raw, sec, usec);
+ grn_text_printf(ctx, buffer,
+ "%" GRN_FMT_INT64D ".%d",
+ sec, usec);
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
grn_geo_point_inspect_point(grn_ctx *ctx, grn_obj *buf, int point)
{
GRN_TEXT_PUTS(ctx, buf, "(");
@@ -1029,7 +1267,6 @@ grn_record_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
grn_obj_get_value(ctx, col, id, &value);
grn_inspect(ctx, buf, &value);
GRN_OBJ_FIN(ctx, &value);
- grn_obj_unlink(ctx, col);
}
});
}
@@ -1042,10 +1279,6 @@ grn_record_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
GRN_TEXT_PUTS(ctx, buf, ">");
- if (table) {
- grn_obj_unlink(ctx, table);
- }
-
return GRN_SUCCESS;
}
@@ -1098,6 +1331,9 @@ grn_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *obj)
break;
case GRN_BULK :
switch (obj->header.domain) {
+ case GRN_DB_TIME :
+ grn_time_inspect(ctx, buffer, obj);
+ return buffer;
case GRN_DB_TOKYO_GEO_POINT :
case GRN_DB_WGS84_GEO_POINT :
grn_geo_point_inspect(ctx, buffer, obj);
@@ -1112,7 +1348,6 @@ grn_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *obj)
domain = grn_ctx_at(ctx, obj->header.domain);
if (domain) {
grn_id type = domain->header.type;
- grn_obj_unlink(ctx, domain);
switch (type) {
case GRN_TABLE_HASH_KEY :
case GRN_TABLE_PAT_KEY :
@@ -1126,13 +1361,12 @@ grn_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *obj)
}
break;
case GRN_PTR :
- /* TODO */
+ grn_ptr_inspect(ctx, buffer, obj);
break;
case GRN_UVECTOR :
domain = grn_ctx_at(ctx, obj->header.domain);
if (domain) {
grn_id type = domain->header.type;
- grn_obj_unlink(ctx, domain);
switch (type) {
case GRN_TABLE_HASH_KEY :
case GRN_TABLE_PAT_KEY :
@@ -1249,6 +1483,30 @@ grn_inspect_indented(grn_ctx *ctx, grn_obj *buffer, grn_obj *obj,
return buffer;
}
+grn_obj *
+grn_inspect_limited(grn_ctx *ctx, grn_obj *buffer, grn_obj *obj)
+{
+ grn_obj sub_buffer;
+ unsigned int max_size = GRN_CTX_MSGSIZE / 2;
+
+ GRN_TEXT_INIT(&sub_buffer, 0);
+ grn_inspect(ctx, &sub_buffer, obj);
+ if (GRN_TEXT_LEN(&sub_buffer) > max_size) {
+ GRN_TEXT_PUT(ctx, buffer, GRN_TEXT_VALUE(&sub_buffer), max_size);
+ GRN_TEXT_PUTS(ctx, buffer, "...(");
+ grn_text_lltoa(ctx, buffer, GRN_TEXT_LEN(&sub_buffer));
+ GRN_TEXT_PUTS(ctx, buffer, ")");
+ } else {
+ GRN_TEXT_PUT(ctx,
+ buffer,
+ GRN_TEXT_VALUE(&sub_buffer),
+ GRN_TEXT_LEN(&sub_buffer));
+ }
+ GRN_OBJ_FIN(ctx, &sub_buffer);
+
+ return buffer;
+}
+
void
grn_p(grn_ctx *ctx, grn_obj *obj)
{
@@ -1257,7 +1515,7 @@ grn_p(grn_ctx *ctx, grn_obj *obj)
GRN_TEXT_INIT(&buffer, 0);
grn_inspect(ctx, &buffer, obj);
printf("%.*s\n", (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer));
- grn_obj_unlink(ctx, &buffer);
+ GRN_OBJ_FIN(ctx, &buffer);
}
void
@@ -1268,7 +1526,7 @@ grn_p_geo_point(grn_ctx *ctx, grn_geo_point *point)
GRN_WGS84_GEO_POINT_INIT(&obj, 0);
GRN_GEO_POINT_SET(ctx, &obj, point->latitude, point->longitude);
grn_p(ctx, &obj);
- grn_obj_unlink(ctx, &obj);
+ GRN_OBJ_FIN(ctx, &obj);
}
void
@@ -1279,7 +1537,7 @@ grn_p_ii_values(grn_ctx *ctx, grn_obj *ii)
GRN_TEXT_INIT(&buffer, 0);
grn_ii_inspect_values(ctx, (grn_ii *)ii, &buffer);
printf("%.*s\n", (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer));
- grn_obj_unlink(ctx, &buffer);
+ GRN_OBJ_FIN(ctx, &buffer);
}
void
@@ -1290,63 +1548,19 @@ grn_p_expr_code(grn_ctx *ctx, grn_expr_code *code)
GRN_TEXT_INIT(&buffer, 0);
grn_expr_code_inspect_indented(ctx, &buffer, code, "");
printf("%.*s\n", (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer));
- grn_obj_unlink(ctx, &buffer);
+ GRN_OBJ_FIN(ctx, &buffer);
}
-#ifdef WIN32
-static char *win32_base_dir = NULL;
-const char *
-grn_win32_base_dir(void)
+void
+grn_p_record(grn_ctx *ctx, grn_obj *table, grn_id id)
{
- if (!win32_base_dir) {
- HMODULE dll;
- const wchar_t *dll_filename = GRN_DLL_FILENAME;
- wchar_t absolute_dll_filename[MAX_PATH];
- DWORD absolute_dll_filename_size;
- dll = GetModuleHandleW(dll_filename);
- absolute_dll_filename_size = GetModuleFileNameW(dll,
- absolute_dll_filename,
- MAX_PATH);
- if (absolute_dll_filename_size == 0) {
- win32_base_dir = grn_strdup_raw(".");
- } else {
- DWORD ansi_dll_filename_size;
- ansi_dll_filename_size =
- WideCharToMultiByte(CP_ACP, 0,
- absolute_dll_filename, absolute_dll_filename_size,
- NULL, 0, NULL, NULL);
- if (ansi_dll_filename_size == 0) {
- win32_base_dir = grn_strdup_raw(".");
- } else {
- char *path;
- win32_base_dir = malloc(ansi_dll_filename_size + 1);
- WideCharToMultiByte(CP_ACP, 0,
- absolute_dll_filename, absolute_dll_filename_size,
- win32_base_dir, ansi_dll_filename_size,
- NULL, NULL);
- win32_base_dir[ansi_dll_filename_size] = '\0';
- if ((path = strrchr(win32_base_dir, '\\'))) {
- *path = '\0';
- }
- path = strrchr(win32_base_dir, '\\');
- if (path && (strcasecmp(path + 1, "bin") == 0 ||
- strcasecmp(path + 1, "lib") == 0)) {
- *path = '\0';
- } else {
- path = win32_base_dir + strlen(win32_base_dir);
- *path = '\0';
- }
- for (path = win32_base_dir; *path; path++) {
- if (*path == '\\') {
- *path = '/';
- }
- }
- }
- }
- }
- return win32_base_dir;
+ grn_obj record;
+
+ GRN_RECORD_INIT(&record, 0, grn_obj_id(ctx, table));
+ GRN_RECORD_SET(ctx, &record, id);
+ grn_p(ctx, &record);
+ GRN_OBJ_FIN(ctx, &record);
}
-#endif
#ifdef WIN32
int
@@ -1385,3 +1599,45 @@ grn_mkstemp(char *path_template)
# endif /* HAVE_MKSTEMP */
}
#endif /* WIN32 */
+
+grn_bool
+grn_path_exist(const char *path)
+{
+ struct stat status;
+ return stat(path, &status) == 0;
+}
+
+/* todo : refine */
+/*
+ * grn_tokenize splits a string into at most buf_size tokens and
+ * returns the number of tokens. The ending address of each token is
+ * written into tokbuf. Delimiters are ' ' and ','.
+ * Then, the address to the remaining is set to rest.
+ */
+int
+grn_tokenize(const char *str, size_t str_len,
+ const char **tokbuf, int buf_size,
+ const char **rest)
+{
+ const char **tok = tokbuf, **tok_end = tokbuf + buf_size;
+ if (buf_size > 0) {
+ const char *str_end = str + str_len;
+ while (str < str_end && (' ' == *str || ',' == *str)) { str++; }
+ for (;;) {
+ if (str == str_end) {
+ *tok++ = str;
+ break;
+ }
+ if (' ' == *str || ',' == *str) {
+ /* *str = '\0'; */
+ *tok++ = str;
+ if (tok == tok_end) { break; }
+ do { str++; } while (str < str_end && (' ' == *str || ',' == *str));
+ } else {
+ str++;
+ }
+ }
+ }
+ if (rest) { *rest = str; }
+ return tok - tokbuf;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/window_function.c b/storage/mroonga/vendor/groonga/lib/window_function.c
new file mode 100644
index 00000000000..5ee182e6236
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/window_function.c
@@ -0,0 +1,464 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_ctx.h"
+#include "grn_db.h"
+#include "grn_expr.h"
+#include "grn_window_function.h"
+
+#include <string.h>
+
+grn_rc
+grn_window_init(grn_ctx *ctx,
+ grn_window *window,
+ grn_obj *table,
+ grn_bool is_sorted)
+{
+ GRN_API_ENTER;
+
+ window->table = table;
+ GRN_RECORD_INIT(&(window->ids), GRN_OBJ_VECTOR, grn_obj_id(ctx, table));
+ window->n_ids = 0;
+ window->current_index = 0;
+ window->direction = GRN_WINDOW_DIRECTION_ASCENDING;
+ window->is_sorted = is_sorted;
+
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+grn_rc
+grn_window_fin(grn_ctx *ctx, grn_window *window)
+{
+ GRN_API_ENTER;
+
+ GRN_OBJ_FIN(ctx, &(window->ids));
+
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+grn_id
+grn_window_next(grn_ctx *ctx, grn_window *window)
+{
+ grn_id next_id;
+
+ GRN_API_ENTER;
+
+ if (!window) {
+ GRN_API_RETURN(GRN_ID_NIL);
+ }
+
+ if (window->direction == GRN_WINDOW_DIRECTION_ASCENDING) {
+ if (window->current_index >= window->n_ids) {
+ GRN_API_RETURN(GRN_ID_NIL);
+ }
+ } else {
+ if (window->current_index < 0) {
+ GRN_API_RETURN(GRN_ID_NIL);
+ }
+ }
+
+ next_id = GRN_RECORD_VALUE_AT(&(window->ids), window->current_index);
+ if (window->direction == GRN_WINDOW_DIRECTION_ASCENDING) {
+ window->current_index++;
+ } else {
+ window->current_index--;
+ }
+
+ GRN_API_RETURN(next_id);
+}
+
+grn_rc
+grn_window_rewind(grn_ctx *ctx, grn_window *window)
+{
+ GRN_API_ENTER;
+
+ if (!window) {
+ ERR(GRN_INVALID_ARGUMENT, "[window][rewind] window is NULL");
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ if (window->direction == GRN_WINDOW_DIRECTION_ASCENDING) {
+ window->current_index = 0;
+ } else {
+ window->current_index = window->n_ids - 1;
+ }
+
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+grn_obj *
+grn_window_get_table(grn_ctx *ctx, grn_window *window)
+{
+ GRN_API_ENTER;
+
+ if (!window) {
+ ERR(GRN_INVALID_ARGUMENT, "[window][rewind] window is NULL");
+ GRN_API_RETURN(NULL);
+ }
+
+ GRN_API_RETURN(window->table);
+}
+
+grn_rc
+grn_window_set_direction(grn_ctx *ctx,
+ grn_window *window,
+ grn_window_direction direction)
+{
+ GRN_API_ENTER;
+
+ if (!window) {
+ ERR(GRN_INVALID_ARGUMENT, "[window][set][direction] window is NULL");
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ switch (direction) {
+ case GRN_WINDOW_DIRECTION_ASCENDING :
+ window->direction = direction;
+ window->current_index = 0;
+ break;
+ case GRN_WINDOW_DIRECTION_DESCENDING :
+ window->direction = direction;
+ window->current_index = window->n_ids - 1;
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT,
+ "[window][set][direction] direction must be "
+ "GRN_WINDOW_DIRECTION_ASCENDING(%d) or "
+ "GRN_WINDOW_DIRECTION_DESCENDING(%d): %d",
+ GRN_WINDOW_DIRECTION_ASCENDING,
+ GRN_WINDOW_DIRECTION_DESCENDING,
+ direction);
+ GRN_API_RETURN(ctx->rc);
+ break;
+ }
+
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+static inline void
+grn_window_reset(grn_ctx *ctx,
+ grn_window *window)
+{
+ GRN_BULK_REWIND(&(window->ids));
+}
+
+static inline void
+grn_window_add_record(grn_ctx *ctx,
+ grn_window *window,
+ grn_id record_id)
+{
+ GRN_RECORD_PUT(ctx, &(window->ids), record_id);
+}
+
+static inline grn_bool
+grn_window_is_empty(grn_ctx *ctx,
+ grn_window *window)
+{
+ return GRN_BULK_VSIZE(&(window->ids)) == 0;
+}
+
+grn_bool
+grn_window_is_sorted(grn_ctx *ctx, grn_window *window)
+{
+ GRN_API_ENTER;
+
+ if (!window) {
+ ERR(GRN_INVALID_ARGUMENT, "[window][is-sorted] window is NULL");
+ GRN_API_RETURN(GRN_FALSE);
+ }
+
+ GRN_API_RETURN(window->is_sorted);
+}
+
+size_t
+grn_window_get_size(grn_ctx *ctx,
+ grn_window *window)
+{
+ GRN_API_ENTER;
+
+ GRN_API_RETURN(window->n_ids);
+}
+
+grn_obj *
+grn_window_function_create(grn_ctx *ctx,
+ const char *name,
+ int name_size,
+ grn_window_function_func func)
+{
+ grn_obj *window_function = NULL;
+
+ GRN_API_ENTER;
+
+ if (name_size == -1) {
+ name_size = strlen(name);
+ }
+
+ window_function = grn_proc_create(ctx,
+ name,
+ name_size,
+ GRN_PROC_WINDOW_FUNCTION,
+ NULL, NULL, NULL, 0, NULL);
+ if (!window_function) {
+ ERR(GRN_WINDOW_FUNCTION_ERROR,
+ "[window-function][%.*s] failed to create proc: %s",
+ name_size, name,
+ ctx->errbuf);
+ GRN_API_RETURN(NULL);
+ }
+
+ {
+ grn_proc *proc = (grn_proc *)window_function;
+ proc->callbacks.window_function = func;
+ }
+
+ GRN_API_RETURN(window_function);
+}
+
+static grn_bool
+grn_expr_is_window_function_call(grn_ctx *ctx,
+ grn_obj *window_function_call)
+{
+ grn_expr *expr = (grn_expr *)window_function_call;
+ grn_expr_code *func;
+ grn_expr_code *call;
+
+ func = &(expr->codes[0]);
+ call = &(expr->codes[expr->codes_curr - 1]);
+
+ if (func->op != GRN_OP_PUSH) {
+ return GRN_FALSE;
+ }
+ if (!grn_obj_is_window_function_proc(ctx, func->value)) {
+ return GRN_FALSE;
+ }
+
+ if (call->op != GRN_OP_CALL) {
+ return GRN_FALSE;
+ }
+ if (call->nargs != (expr->codes_curr - 1)) {
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+static grn_rc
+grn_expr_call_window_function(grn_ctx *ctx,
+ grn_obj *output_column,
+ grn_window *window,
+ grn_obj *window_function_call)
+{
+ grn_rc rc;
+ grn_expr *expr = (grn_expr *)window_function_call;
+ grn_proc *proc;
+ int32_t i, n;
+ grn_obj args;
+
+ proc = (grn_proc *)(expr->codes[0].value);
+
+ GRN_PTR_INIT(&args, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ n = expr->codes_curr - 1;
+ for (i = 1; i < n; i++) {
+ /* TODO: Check op. */
+ GRN_PTR_PUT(ctx, &args, expr->codes[i].value);
+ }
+ window->n_ids = GRN_BULK_VSIZE(&(window->ids)) / sizeof(grn_id);
+ if (window->direction == GRN_WINDOW_DIRECTION_ASCENDING) {
+ window->current_index = 0;
+ } else {
+ window->current_index = window->n_ids - 1;
+ }
+ rc = proc->callbacks.window_function(ctx,
+ output_column,
+ window,
+ (grn_obj **)GRN_BULK_HEAD(&args),
+ GRN_BULK_VSIZE(&args) / sizeof(grn_obj *));
+ GRN_OBJ_FIN(ctx, &args);
+
+ return rc;
+}
+
+grn_rc
+grn_table_apply_window_function(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *output_column,
+ grn_window_definition *definition,
+ grn_obj *window_function_call)
+{
+ GRN_API_ENTER;
+
+ if (!table) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][apply][window-function] table is NULL");
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ if (!grn_expr_is_window_function_call(ctx, window_function_call)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, window_function_call);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][apply][window-function] must be window function call: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ {
+ size_t n_sort_keys;
+ grn_table_sort_key *sort_keys;
+ grn_obj *sorted;
+ grn_window window;
+
+ n_sort_keys = definition->n_group_keys + definition->n_sort_keys;
+ sort_keys = GRN_MALLOCN(grn_table_sort_key, n_sort_keys);
+ if (!sort_keys) {
+ grn_rc rc = ctx->rc;
+ if (rc == GRN_SUCCESS) {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ }
+ ERR(rc,
+ "[table][apply][window-function] "
+ "failed to allocate internal sort keys: %s",
+ ctx->errbuf);
+ GRN_API_RETURN(ctx->rc);
+ }
+ {
+ size_t i;
+ for (i = 0; i < definition->n_group_keys; i++) {
+ sort_keys[i] = definition->group_keys[i];
+ }
+ for (i = 0; i < definition->n_sort_keys; i++) {
+ sort_keys[i + definition->n_group_keys] = definition->sort_keys[i];
+ }
+ }
+ sorted = grn_table_create(ctx,
+ NULL, 0, NULL,
+ GRN_OBJ_TABLE_NO_KEY,
+ NULL,
+ table);
+ if (!sorted) {
+ grn_rc rc = ctx->rc;
+ if (rc == GRN_SUCCESS) {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ }
+ GRN_FREE(sort_keys);
+ ERR(rc,
+ "[table][apply][window-function] "
+ "failed to allocate table to store sorted result: %s",
+ ctx->errbuf);
+ GRN_API_RETURN(ctx->rc);
+ }
+ grn_table_sort(ctx,
+ table,
+ 0, -1,
+ sorted,
+ sort_keys, n_sort_keys);
+
+ grn_window_init(ctx, &window, table, definition->n_sort_keys > 0);
+ if (definition->n_group_keys > 0) {
+ grn_obj *previous_values;
+ grn_obj *current_values;
+ size_t i, n;
+
+ previous_values = GRN_MALLOCN(grn_obj, definition->n_group_keys);
+ current_values = GRN_MALLOCN(grn_obj, definition->n_group_keys);
+ n = definition->n_group_keys;
+
+ for (i = 0; i < n; i++) {
+ GRN_VOID_INIT(&(previous_values[i]));
+ GRN_VOID_INIT(&(current_values[i]));
+ }
+
+ GRN_TABLE_EACH_BEGIN(ctx, sorted, cursor, id) {
+ void *value;
+ grn_id record_id;
+ grn_bool is_group_key_changed = GRN_FALSE;
+
+ grn_table_cursor_get_value(ctx, cursor, &value);
+ record_id = *((grn_id *)value);
+
+ for (i = 0; i < n; i++) {
+ size_t reverse_i = n - i - 1;
+ grn_obj *previous_value = &(previous_values[reverse_i]);
+ grn_obj *current_value = &(current_values[reverse_i]);
+ grn_obj *group_key = definition->group_keys[reverse_i].key;
+
+ if (is_group_key_changed) {
+ GRN_BULK_REWIND(previous_value);
+ grn_obj_get_value(ctx, group_key, record_id, previous_value);
+ } else {
+ GRN_BULK_REWIND(current_value);
+ grn_obj_get_value(ctx, group_key, record_id, current_value);
+ if ((GRN_BULK_VSIZE(current_value) !=
+ GRN_BULK_VSIZE(previous_value)) ||
+ (memcmp(GRN_BULK_HEAD(current_value),
+ GRN_BULK_HEAD(previous_value),
+ GRN_BULK_VSIZE(current_value)) != 0)) {
+ is_group_key_changed = GRN_TRUE;
+ grn_bulk_write_from(ctx,
+ previous_value,
+ GRN_BULK_HEAD(current_value),
+ 0,
+ GRN_BULK_VSIZE(current_value));
+ }
+ }
+ }
+
+ if (is_group_key_changed && !grn_window_is_empty(ctx, &window)) {
+ grn_expr_call_window_function(ctx,
+ output_column,
+ &window,
+ window_function_call);
+ grn_window_reset(ctx, &window);
+ }
+ grn_window_add_record(ctx, &window, record_id);
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ grn_expr_call_window_function(ctx,
+ output_column,
+ &window,
+ window_function_call);
+
+ for (i = 0; i < definition->n_group_keys; i++) {
+ GRN_OBJ_FIN(ctx, &(previous_values[i]));
+ GRN_OBJ_FIN(ctx, &(current_values[i]));
+ }
+ GRN_FREE(previous_values);
+ GRN_FREE(current_values);
+ } else {
+ GRN_TABLE_EACH_BEGIN(ctx, sorted, cursor, id) {
+ void *value;
+ grn_id record_id;
+
+ grn_table_cursor_get_value(ctx, cursor, &value);
+ record_id = *((grn_id *)value);
+ grn_window_add_record(ctx, &window, record_id);
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ grn_expr_call_window_function(ctx,
+ output_column,
+ &window,
+ window_function_call);
+ }
+ grn_window_fin(ctx, &window);
+
+ GRN_FREE(sort_keys);
+ }
+
+ GRN_API_RETURN(ctx->rc);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/window_functions.c b/storage/mroonga/vendor/groonga/lib/window_functions.c
new file mode 100644
index 00000000000..1812f2922bf
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/window_functions.c
@@ -0,0 +1,405 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_db.h"
+#include "grn_window_functions.h"
+
+static grn_rc
+window_record_number(grn_ctx *ctx,
+ grn_obj *output_column,
+ grn_window *window,
+ grn_obj **args,
+ int n_args)
+{
+ grn_id id;
+ uint32_t nth_record = 1;
+ grn_obj value;
+
+ GRN_UINT32_INIT(&value, 0);
+ while ((id = grn_window_next(ctx, window))) {
+ GRN_UINT32_SET(ctx, &value, nth_record);
+ grn_obj_set_value(ctx, output_column, id, &value, GRN_OBJ_SET);
+ nth_record++;
+ }
+ GRN_OBJ_FIN(ctx, &value);
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+window_sum(grn_ctx *ctx,
+ grn_obj *output_column,
+ grn_window *window,
+ grn_obj **args,
+ int n_args)
+{
+ grn_id id;
+ grn_obj *target;
+
+ if (n_args != 1) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "window_sum(): wrong number of arguments (%d for 1)",
+ n_args);
+ return ctx->rc;
+ }
+
+ target = args[0];
+ if (target->header.type != GRN_ACCESSOR) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, target);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "window_sum(): "
+ "the target column must be accessor: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return ctx->rc;
+ }
+
+ {
+ const grn_id output_column_range_id = grn_obj_get_range(ctx, output_column);
+ const grn_id target_range_id = grn_obj_get_range(ctx, target);
+ grn_obj sum;
+ grn_obj value;
+
+ switch (target_range_id) {
+ case GRN_DB_INT8 :
+ case GRN_DB_INT16 :
+ case GRN_DB_INT32 :
+ case GRN_DB_INT64 :
+ case GRN_DB_UINT8 :
+ case GRN_DB_UINT16 :
+ case GRN_DB_UINT32 :
+ case GRN_DB_UINT64 :
+ case GRN_DB_FLOAT :
+ break;
+ default :
+ {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, target);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "window_sum(): "
+ "the target column must be number column: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return ctx->rc;
+ }
+ break;
+ }
+
+ switch (output_column_range_id) {
+ case GRN_DB_INT8 :
+ case GRN_DB_INT16 :
+ case GRN_DB_INT32 :
+ case GRN_DB_INT64 :
+ GRN_INT64_INIT(&sum, 0);
+ break;
+ case GRN_DB_UINT8 :
+ case GRN_DB_UINT16 :
+ case GRN_DB_UINT32 :
+ case GRN_DB_UINT64 :
+ GRN_UINT64_INIT(&sum, 0);
+ break;
+ case GRN_DB_FLOAT :
+ GRN_FLOAT_INIT(&sum, 0);
+ break;
+ default :
+ {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, output_column);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "window_sum(): "
+ "the output column must be number column: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return ctx->rc;
+ }
+ break;
+ }
+ GRN_VOID_INIT(&value);
+
+ if (grn_window_is_sorted(ctx, window)) {
+ while ((id = grn_window_next(ctx, window))) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx, target, id, &value);
+ switch (target_range_id) {
+ case GRN_DB_INT8 :
+ GRN_INT64_SET(ctx,
+ &sum,
+ GRN_INT64_VALUE(&sum) + GRN_INT8_VALUE(&value));
+ break;
+ case GRN_DB_INT16 :
+ GRN_INT64_SET(ctx,
+ &sum,
+ GRN_INT64_VALUE(&sum) + GRN_INT16_VALUE(&value));
+ break;
+ case GRN_DB_INT32 :
+ GRN_INT64_SET(ctx,
+ &sum,
+ GRN_INT64_VALUE(&sum) + GRN_INT32_VALUE(&value));
+ break;
+ case GRN_DB_INT64 :
+ GRN_INT64_SET(ctx,
+ &sum,
+ GRN_INT64_VALUE(&sum) + GRN_INT64_VALUE(&value));
+ break;
+ case GRN_DB_UINT8 :
+ GRN_UINT64_SET(ctx,
+ &sum,
+ GRN_UINT64_VALUE(&sum) + GRN_UINT8_VALUE(&value));
+ break;
+ case GRN_DB_UINT16 :
+ GRN_UINT64_SET(ctx,
+ &sum,
+ GRN_UINT64_VALUE(&sum) + GRN_UINT16_VALUE(&value));
+ break;
+ case GRN_DB_UINT32 :
+ GRN_UINT64_SET(ctx,
+ &sum,
+ GRN_UINT64_VALUE(&sum) + GRN_UINT32_VALUE(&value));
+ break;
+ case GRN_DB_UINT64 :
+ GRN_UINT64_SET(ctx,
+ &sum,
+ GRN_UINT64_VALUE(&sum) + GRN_UINT64_VALUE(&value));
+ break;
+ case GRN_DB_FLOAT :
+ GRN_FLOAT_SET(ctx,
+ &sum,
+ GRN_FLOAT_VALUE(&sum) + GRN_FLOAT_VALUE(&value));
+ break;
+ default :
+ break;
+ }
+ grn_obj_set_value(ctx, output_column, id, &sum, GRN_OBJ_SET);
+ }
+ } else {
+ int64_t sum_raw_int64 = 0;
+ uint64_t sum_raw_uint64 = 0;
+ double sum_raw_double = 0.0;
+
+ while ((id = grn_window_next(ctx, window))) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx, target, id, &value);
+ switch (target_range_id) {
+ case GRN_DB_INT8 :
+ sum_raw_int64 += GRN_INT8_VALUE(&value);
+ break;
+ case GRN_DB_INT16 :
+ sum_raw_int64 += GRN_INT16_VALUE(&value);
+ break;
+ case GRN_DB_INT32 :
+ sum_raw_int64 += GRN_INT32_VALUE(&value);
+ break;
+ case GRN_DB_INT64 :
+ sum_raw_int64 += GRN_INT64_VALUE(&value);
+ break;
+ case GRN_DB_UINT8 :
+ sum_raw_uint64 += GRN_UINT8_VALUE(&value);
+ break;
+ case GRN_DB_UINT16 :
+ sum_raw_uint64 += GRN_UINT16_VALUE(&value);
+ break;
+ case GRN_DB_UINT32 :
+ sum_raw_uint64 += GRN_UINT32_VALUE(&value);
+ break;
+ case GRN_DB_UINT64 :
+ sum_raw_uint64 += GRN_UINT64_VALUE(&value);
+ break;
+ case GRN_DB_FLOAT :
+ sum_raw_double += GRN_FLOAT_VALUE(&value);
+ break;
+ default :
+ break;
+ }
+ }
+
+ switch (output_column_range_id) {
+ case GRN_DB_INT8 :
+ case GRN_DB_INT16 :
+ case GRN_DB_INT32 :
+ case GRN_DB_INT64 :
+ GRN_INT64_SET(ctx, &sum, sum_raw_int64);
+ break;
+ case GRN_DB_UINT8 :
+ case GRN_DB_UINT16 :
+ case GRN_DB_UINT32 :
+ case GRN_DB_UINT64 :
+ GRN_UINT64_SET(ctx, &sum, sum_raw_uint64);
+ break;
+ case GRN_DB_FLOAT :
+ GRN_FLOAT_SET(ctx, &sum, sum_raw_double);
+ break;
+ }
+
+ grn_window_rewind(ctx, window);
+ while ((id = grn_window_next(ctx, window))) {
+ grn_obj_set_value(ctx, output_column, id, &sum, GRN_OBJ_SET);
+ }
+ }
+
+ GRN_OBJ_FIN(ctx, &value);
+ GRN_OBJ_FIN(ctx, &sum);
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+window_count(grn_ctx *ctx,
+ grn_obj *output_column,
+ grn_window *window,
+ grn_obj **args,
+ int n_args)
+{
+ grn_id id;
+ grn_id output_column_range_id;
+ grn_obj n_records;
+ uint32_t n_records_raw = 0;
+
+
+ if (n_args != 0) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "window_count(): wrong number of arguments (%d for 0)",
+ n_args);
+ return ctx->rc;
+ }
+
+ output_column_range_id = grn_obj_get_range(ctx, output_column);
+ switch (output_column_range_id) {
+ case GRN_DB_INT8 :
+ case GRN_DB_INT16 :
+ case GRN_DB_INT32 :
+ case GRN_DB_INT64 :
+ GRN_INT64_INIT(&n_records, 0);
+ break;
+ case GRN_DB_UINT8 :
+ case GRN_DB_UINT16 :
+ case GRN_DB_UINT32 :
+ case GRN_DB_UINT64 :
+ GRN_UINT64_INIT(&n_records, 0);
+ break;
+ case GRN_DB_FLOAT :
+ GRN_FLOAT_INIT(&n_records, 0);
+ break;
+ default :
+ {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, output_column);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "window_count(): "
+ "the output column must be number column: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return ctx->rc;
+ }
+ break;
+ }
+
+ if (grn_window_is_sorted(ctx, window)) {
+ while ((id = grn_window_next(ctx, window))) {
+ n_records_raw++;
+ switch (output_column_range_id) {
+ case GRN_DB_INT8 :
+ case GRN_DB_INT16 :
+ case GRN_DB_INT32 :
+ case GRN_DB_INT64 :
+ GRN_INT64_SET(ctx, &n_records, n_records_raw);
+ break;
+ case GRN_DB_UINT8 :
+ case GRN_DB_UINT16 :
+ case GRN_DB_UINT32 :
+ case GRN_DB_UINT64 :
+ GRN_UINT64_SET(ctx, &n_records, n_records_raw);
+ break;
+ case GRN_DB_FLOAT :
+ GRN_FLOAT_SET(ctx, &n_records, n_records_raw);
+ break;
+ default :
+ break;
+ }
+ grn_obj_set_value(ctx, output_column, id, &n_records, GRN_OBJ_SET);
+ }
+ } else {
+ while ((id = grn_window_next(ctx, window))) {
+ n_records_raw++;
+ }
+
+ switch (output_column_range_id) {
+ case GRN_DB_INT8 :
+ case GRN_DB_INT16 :
+ case GRN_DB_INT32 :
+ case GRN_DB_INT64 :
+ GRN_INT64_SET(ctx, &n_records, n_records_raw);
+ break;
+ case GRN_DB_UINT8 :
+ case GRN_DB_UINT16 :
+ case GRN_DB_UINT32 :
+ case GRN_DB_UINT64 :
+ GRN_UINT64_SET(ctx, &n_records, n_records_raw);
+ break;
+ case GRN_DB_FLOAT :
+ GRN_FLOAT_SET(ctx, &n_records, n_records_raw);
+ break;
+ }
+
+ grn_window_rewind(ctx, window);
+ while ((id = grn_window_next(ctx, window))) {
+ grn_obj_set_value(ctx, output_column, id, &n_records, GRN_OBJ_SET);
+ }
+ }
+
+ GRN_OBJ_FIN(ctx, &n_records);
+
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_db_init_builtin_window_functions(grn_ctx *ctx)
+{
+ /* For backward compatibility. */
+ grn_window_function_create(ctx,
+ "record_number", -1,
+ window_record_number);
+ grn_window_function_create(ctx,
+ "window_record_number", -1,
+ window_record_number);
+
+ grn_window_function_create(ctx,
+ "window_sum", -1,
+ window_sum);
+
+ grn_window_function_create(ctx,
+ "window_count", -1,
+ window_count);
+
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/windows.c b/storage/mroonga/vendor/groonga/lib/windows.c
new file mode 100644
index 00000000000..83a1d499ac4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/windows.c
@@ -0,0 +1,104 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2010-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn.h"
+#include "grn_windows.h"
+
+#ifdef WIN32
+static char *windows_base_dir = NULL;
+const char *
+grn_windows_base_dir(void)
+{
+ if (!windows_base_dir) {
+ HMODULE dll;
+ const wchar_t *dll_filename = GRN_DLL_FILENAME;
+ wchar_t absolute_dll_filename[MAX_PATH];
+ DWORD absolute_dll_filename_size;
+ dll = GetModuleHandleW(dll_filename);
+ absolute_dll_filename_size = GetModuleFileNameW(dll,
+ absolute_dll_filename,
+ MAX_PATH);
+ if (absolute_dll_filename_size == 0) {
+ windows_base_dir = grn_strdup_raw(".");
+ } else {
+ DWORD ansi_dll_filename_size;
+ ansi_dll_filename_size =
+ WideCharToMultiByte(CP_ACP, 0,
+ absolute_dll_filename, absolute_dll_filename_size,
+ NULL, 0, NULL, NULL);
+ if (ansi_dll_filename_size == 0) {
+ windows_base_dir = grn_strdup_raw(".");
+ } else {
+ char *path;
+ windows_base_dir = malloc(ansi_dll_filename_size + 1);
+ WideCharToMultiByte(CP_ACP, 0,
+ absolute_dll_filename, absolute_dll_filename_size,
+ windows_base_dir, ansi_dll_filename_size,
+ NULL, NULL);
+ windows_base_dir[ansi_dll_filename_size] = '\0';
+ if ((path = strrchr(windows_base_dir, '\\'))) {
+ *path = '\0';
+ }
+ path = strrchr(windows_base_dir, '\\');
+ if (path && (grn_strcasecmp(path + 1, "bin") == 0 ||
+ grn_strcasecmp(path + 1, "lib") == 0)) {
+ *path = '\0';
+ } else {
+ path = windows_base_dir + strlen(windows_base_dir);
+ *path = '\0';
+ }
+ for (path = windows_base_dir; *path; path++) {
+ if (*path == '\\') {
+ *path = '/';
+ }
+ }
+ }
+ }
+ }
+ return windows_base_dir;
+}
+
+UINT
+grn_windows_encoding_to_code_page(grn_encoding encoding)
+{
+ UINT code_page;
+
+ switch (encoding) {
+ case GRN_ENC_EUC_JP :
+ code_page = 20932;
+ break;
+ case GRN_ENC_UTF8 :
+ code_page = CP_UTF8;
+ break;
+ case GRN_ENC_SJIS :
+ code_page = 932;
+ break;
+ case GRN_ENC_LATIN1 :
+ code_page = 1252;
+ break;
+ case GRN_ENC_KOI8R :
+ code_page = 20866;
+ break;
+ default :
+ code_page = CP_ACP;
+ break;
+ }
+
+ return code_page;
+}
+#endif /* WIN32 */
diff --git a/storage/mroonga/vendor/groonga/lib/windows_event_logger.c b/storage/mroonga/vendor/groonga/lib/windows_event_logger.c
new file mode 100644
index 00000000000..d7447e72eb7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/windows_event_logger.c
@@ -0,0 +1,203 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "grn_logger.h"
+#include "grn_ctx.h"
+#include "grn_windows.h"
+
+#include <string.h>
+
+#ifdef WIN32
+
+typedef struct _grn_windows_event_logger_data {
+ char *event_source_name;
+ HANDLE event_source;
+} grn_windows_event_logger_data;
+
+static void
+windows_event_logger_log(grn_ctx *ctx, grn_log_level level,
+ const char *timestamp, const char *title,
+ const char *message, const char *location,
+ void *user_data)
+{
+ grn_windows_event_logger_data *data = user_data;
+ WORD type;
+ WORD category = 0;
+ DWORD event_id = 0;
+ PSID user_sid = NULL;
+ WORD n_strings = 1;
+ DWORD event_data_size = 0;
+ const WCHAR *strings[1];
+ LPVOID event_data = NULL;
+ const char level_marks[] = " EACewnid-";
+ grn_obj formatted_buffer;
+ UINT code_page;
+ DWORD convert_flags = 0;
+ int n_converted_chars;
+
+ switch (level) {
+ case GRN_LOG_NONE :
+ return;
+ break;
+ case GRN_LOG_EMERG :
+ case GRN_LOG_ALERT :
+ case GRN_LOG_CRIT :
+ case GRN_LOG_ERROR :
+ type = EVENTLOG_ERROR_TYPE;
+ break;
+ case GRN_LOG_WARNING :
+ type = EVENTLOG_WARNING_TYPE;
+ break;
+ case GRN_LOG_NOTICE :
+ case GRN_LOG_INFO :
+ case GRN_LOG_DEBUG :
+ case GRN_LOG_DUMP :
+ type = EVENTLOG_INFORMATION_TYPE;
+ break;
+ default :
+ type = EVENTLOG_ERROR_TYPE;
+ break;
+ }
+
+ if (data->event_source == INVALID_HANDLE_VALUE) {
+ data->event_source = RegisterEventSourceA(NULL, data->event_source_name);
+ if (data->event_source == INVALID_HANDLE_VALUE) {
+ return;
+ }
+ }
+
+ GRN_TEXT_INIT(&formatted_buffer, 0);
+ if (location && location[0]) {
+ grn_text_printf(ctx, &formatted_buffer, "%s|%c|%s %s %s",
+ timestamp, level_marks[level], title, message, location);
+ } else {
+ grn_text_printf(ctx, &formatted_buffer, "%s|%c|%s %s",
+ timestamp, level_marks[level], title, message);
+ }
+
+ code_page = grn_windows_encoding_to_code_page(ctx->encoding);
+
+ n_converted_chars = MultiByteToWideChar(code_page,
+ convert_flags,
+ GRN_TEXT_VALUE(&formatted_buffer),
+ GRN_TEXT_LEN(&formatted_buffer),
+ NULL,
+ 0);
+#define CONVERTED_BUFFER_SIZE 512
+ if (n_converted_chars < CONVERTED_BUFFER_SIZE) {
+ WCHAR converted_buffer[CONVERTED_BUFFER_SIZE];
+ n_converted_chars = MultiByteToWideChar(code_page,
+ convert_flags,
+ GRN_TEXT_VALUE(&formatted_buffer),
+ GRN_TEXT_LEN(&formatted_buffer),
+ converted_buffer,
+ CONVERTED_BUFFER_SIZE);
+ converted_buffer[n_converted_chars] = L'\0';
+ strings[0] = converted_buffer;
+ ReportEventW(data->event_source, type, category, event_id, user_sid,
+ n_strings, event_data_size,
+ strings, event_data);
+#undef CONVERTED_BUFFER_SIZE
+ } else {
+ WCHAR *converted;
+ converted = GRN_MALLOCN(WCHAR, n_converted_chars);
+ n_converted_chars = MultiByteToWideChar(code_page,
+ convert_flags,
+ GRN_TEXT_VALUE(&formatted_buffer),
+ GRN_TEXT_LEN(&formatted_buffer),
+ converted,
+ n_converted_chars);
+ converted[n_converted_chars] = L'\0';
+ strings[0] = converted;
+ ReportEventW(data->event_source, type, category, event_id, user_sid,
+ n_strings, event_data_size,
+ strings, event_data);
+ GRN_FREE(converted);
+ }
+ GRN_OBJ_FIN(ctx, &formatted_buffer);
+}
+
+static void
+windows_event_logger_reopen(grn_ctx *ctx, void *user_data)
+{
+}
+
+static void
+windows_event_logger_fin(grn_ctx *ctx, void *user_data)
+{
+ grn_windows_event_logger_data *data = user_data;
+
+ free(data->event_source_name);
+ if (data->event_source != INVALID_HANDLE_VALUE) {
+ DeregisterEventSource(data->event_source);
+ }
+ free(data);
+}
+#endif /* WIN32 */
+
+grn_rc
+grn_windows_event_logger_set(grn_ctx *ctx, const char *event_source_name)
+{
+#ifdef WIN32
+ grn_rc rc;
+ grn_logger windows_event_logger;
+ grn_windows_event_logger_data *data;
+
+ if (ctx) {
+ GRN_API_ENTER;
+ }
+
+ data = malloc(sizeof(grn_windows_event_logger_data));
+ if (!data) {
+ if (ctx) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "failed to allocate user data for Windows event logger");
+ GRN_API_RETURN(ctx->rc);
+ } else {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+
+ if (event_source_name) {
+ data->event_source_name = grn_strdup_raw(event_source_name);
+ } else {
+ data->event_source_name = grn_strdup_raw("libgroonga");
+ }
+ data->event_source = INVALID_HANDLE_VALUE;
+
+ windows_event_logger.max_level = GRN_LOG_DEFAULT_LEVEL;
+ windows_event_logger.flags = GRN_LOG_TIME | GRN_LOG_MESSAGE;
+ windows_event_logger.user_data = data;
+ windows_event_logger.log = windows_event_logger_log;
+ windows_event_logger.reopen = windows_event_logger_reopen;
+ windows_event_logger.fin = windows_event_logger_fin;
+
+ rc = grn_logger_set(ctx, &windows_event_logger);
+ if (rc != GRN_SUCCESS) {
+ windows_event_logger.fin(ctx, windows_event_logger.user_data);
+ }
+
+ if (ctx) {
+ GRN_API_RETURN(rc);
+ } else {
+ return rc;
+ }
+#else /* WIN32 */
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+#endif /* WIN32 */
+}
diff --git a/storage/mroonga/vendor/groonga/nginx_version b/storage/mroonga/vendor/groonga/nginx_version
index 27f9cd322bb..43ded906259 100644
--- a/storage/mroonga/vendor/groonga/nginx_version
+++ b/storage/mroonga/vendor/groonga/nginx_version
@@ -1 +1 @@
-1.8.0
+1.13.5
diff --git a/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt
index 6d6a8df5d5e..244b60f9004 100644
--- a/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright(C) 2012-2015 Brazil
+# Copyright(C) 2012-2016 Brazil
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -15,7 +15,6 @@
add_subdirectory(suggest)
add_subdirectory(tokenizers)
-add_subdirectory(table)
add_subdirectory(query_expanders)
add_subdirectory(ruby)
add_subdirectory(token_filters)
diff --git a/storage/mroonga/vendor/groonga/plugins/Makefile.am b/storage/mroonga/vendor/groonga/plugins/Makefile.am
index dc3967899c2..6c98a0cc3f5 100644
--- a/storage/mroonga/vendor/groonga/plugins/Makefile.am
+++ b/storage/mroonga/vendor/groonga/plugins/Makefile.am
@@ -1,12 +1,12 @@
SUBDIRS = \
tokenizers \
suggest \
- table \
query_expanders \
ruby \
token_filters \
sharding \
- functions
+ functions \
+ expression_rewriters
EXTRA_DIST = \
CMakeLists.txt
diff --git a/storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/expression_rewriters/CMakeLists.txt
index bd423a830b3..385b5c750d2 100644
--- a/storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/expression_rewriters/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright(C) 2012-2013 Brazil
+# Copyright(C) 2015 Brazil
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,17 +13,14 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/../../lib
- ${MRUBY_INCLUDE_DIRS})
-
-read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am TABLE_SOURCES)
if(NOT GRN_EMBED)
- add_library(table MODULE ${TABLE_SOURCES})
- set_source_files_properties(${TABLE_SOURCES}
- PROPERTIES
- COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
- set_target_properties(table PROPERTIES PREFIX "")
- target_link_libraries(table libgroonga)
- install(TARGETS table DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}/table")
+ if(GRN_WITH_MRUBY)
+ set(GRN_RELATIVE_EXPRESSION_REWRITER_PLUGINS_DIR
+ "${GRN_RELATIVE_PLUGINS_DIR}/expression_rewriters")
+
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am
+ EXPRESSION_REWRITERS)
+ install(FILES ${EXPRESSION_REWRITERS}
+ DESTINATION "${GRN_RELATIVE_SEXPRESSION_REWRITER_PLUGINS_DIR}")
+ endif()
endif()
diff --git a/storage/mroonga/vendor/groonga/plugins/expression_rewriters/Makefile.am b/storage/mroonga/vendor/groonga/plugins/expression_rewriters/Makefile.am
new file mode 100644
index 00000000000..60a032acca7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/expression_rewriters/Makefile.am
@@ -0,0 +1,9 @@
+EXTRA_DIST = \
+ CMakeLists.txt
+
+if WITH_MRUBY
+dist_expression_rewriter_plugins_DATA = \
+ $(expression_rewriters)
+endif
+
+include sources.am
diff --git a/storage/mroonga/vendor/groonga/plugins/expression_rewriters/optimizer.rb b/storage/mroonga/vendor/groonga/plugins/expression_rewriters/optimizer.rb
new file mode 100644
index 00000000000..3dfee681d52
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/expression_rewriters/optimizer.rb
@@ -0,0 +1,147 @@
+module Groonga
+ module ExpressionRewriters
+ class Optimizer < ExpressionRewriter
+ register "optimizer"
+
+ def rewrite
+ builder = ExpressionTreeBuilder.new(@expression)
+ root_node = builder.build
+
+ variable = @expression[0]
+ table = context[variable.domain]
+ optimized_root_node = optimize_node(table, root_node)
+
+ rewritten = Expression.create(table)
+ optimized_root_node.build(rewritten)
+ rewritten
+ end
+
+ private
+ def optimize_node(table, node)
+ case node
+ when ExpressionTree::LogicalOperation
+ optimized_sub_nodes = node.nodes.collect do |sub_node|
+ optimize_node(table, sub_node)
+ end
+ case node.operator
+ when Operator::AND
+ optimized_sub_nodes =
+ optimize_and_sub_nodes(table, optimized_sub_nodes)
+ end
+ ExpressionTree::LogicalOperation.new(node.operator,
+ optimized_sub_nodes)
+ when ExpressionTree::BinaryOperation
+ optimized_left = optimize_node(table, node.left)
+ optimized_right = optimize_node(table, node.right)
+ if optimized_left.is_a?(ExpressionTree::Constant) and
+ optimized_right.is_a?(ExpressionTree::Variable)
+ ExpressionTree::BinaryOperation.new(node.operator,
+ optimized_right,
+ optimized_left)
+ elsif node.left == optimized_left and node.right == optimized_right
+ node
+ else
+ ExpressionTree::BinaryOperation.new(node.operator,
+ optimized_left,
+ optimized_right)
+ end
+ else
+ node
+ end
+ end
+
+ def optimize_and_sub_nodes(table, sub_nodes)
+ grouped_sub_nodes = sub_nodes.group_by do |sub_node|
+ case sub_node
+ when ExpressionTree::BinaryOperation
+ if sub_node.left.is_a?(ExpressionTree::Variable)
+ sub_node.left.column
+ else
+ nil
+ end
+ else
+ nil
+ end
+ end
+
+ optimized_nodes = []
+ grouped_sub_nodes.each do |column, grouped_nodes|
+ if column
+ grouped_nodes = optimize_grouped_nodes(column, grouped_nodes)
+ end
+ optimized_nodes.concat(grouped_nodes)
+ end
+
+ optimized_nodes.sort_by do |node|
+ node.estimate_size(table)
+ end
+ end
+
+ COMPARISON_OPERATORS = [
+ Operator::EQUAL,
+ Operator::NOT_EQUAL,
+ Operator::LESS,
+ Operator::GREATER,
+ Operator::LESS_EQUAL,
+ Operator::GREATER_EQUAL,
+ ]
+ def optimize_grouped_nodes(column, grouped_nodes)
+ target_nodes, done_nodes = grouped_nodes.partition do |node|
+ node.is_a?(ExpressionTree::BinaryOperation) and
+ COMPARISON_OPERATORS.include?(node.operator) and
+ node.right.is_a?(ExpressionTree::Constant)
+ end
+
+ # TODO: target_nodes = remove_needless_nodes(target_nodes)
+ # e.g.: x < 1 && x < 3 -> x < 1: (x < 3) is meaningless
+
+ if target_nodes.size == 2
+ between_node = try_optimize_between(column, target_nodes)
+ if between_node
+ done_nodes << between_node
+ else
+ done_nodes.concat(target_nodes)
+ end
+ else
+ done_nodes.concat(target_nodes)
+ end
+
+ done_nodes
+ end
+
+ def try_optimize_between(column, target_nodes)
+ greater_node = nil
+ less_node = nil
+ target_nodes.each do |node|
+ case node.operator
+ when Operator::GREATER, Operator::GREATER_EQUAL
+ greater_node = node
+ when Operator::LESS, Operator::LESS_EQUAL
+ less_node = node
+ end
+ end
+ return nil if greater_node.nil? or less_node.nil?
+
+ between = ExpressionTree::Procedure.new(context["between"])
+ if greater_node.operator == Operator::GREATER
+ greater_border = "exclude"
+ else
+ greater_border = "include"
+ end
+ if less_node.operator == Operator::LESS
+ less_border = "exclude"
+ else
+ less_border = "include"
+ end
+ arguments = [
+ ExpressionTree::Variable.new(column),
+ greater_node.right,
+ ExpressionTree::Constant.new(greater_border),
+ less_node.right,
+ ExpressionTree::Constant.new(less_border),
+ ]
+ ExpressionTree::FunctionCall.new(between, arguments)
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/plugins/expression_rewriters/sources.am b/storage/mroonga/vendor/groonga/plugins/expression_rewriters/sources.am
new file mode 100644
index 00000000000..7670bed6126
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/expression_rewriters/sources.am
@@ -0,0 +1,2 @@
+expression_rewriters = \
+ optimizer.rb
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt
index d831589b28b..611e30b9c48 100644
--- a/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright(C) 2015 Brazil
+# Copyright(C) 2015-2017 Brazil
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -38,3 +38,104 @@ else()
install(TARGETS vector_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
endif()
target_link_libraries(vector_functions libgroonga)
+
+read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/string_sources.am
+ STRING_SOURCES)
+set_source_files_properties(${STRING_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+if(GRN_EMBED)
+ add_library(string_functions STATIC ${STRING_SOURCES})
+ set_target_properties(
+ string_functions
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+else()
+ add_library(string_functions MODULE ${STRING_SOURCES})
+ set_target_properties(string_functions PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "string")
+ install(TARGETS string_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
+endif()
+target_link_libraries(string_functions libgroonga)
+
+read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/number_sources.am
+ NUMBER_SOURCES)
+set_source_files_properties(${NUMBER_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+if(GRN_EMBED)
+ add_library(number_functions STATIC ${NUMBER_SOURCES})
+ set_target_properties(
+ number_functions
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+else()
+ add_library(number_functions MODULE ${NUMBER_SOURCES})
+ set_target_properties(number_functions PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "number")
+ install(TARGETS number_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
+endif()
+target_link_libraries(number_functions libgroonga "${M_LIBS}")
+
+read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/time_sources.am
+ TIME_SOURCES)
+set_source_files_properties(${TIME_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+if(GRN_EMBED)
+ add_library(time_functions STATIC ${TIME_SOURCES})
+ set_target_properties(
+ time_functions
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+else()
+ add_library(time_functions MODULE ${TIME_SOURCES})
+ set_target_properties(time_functions PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "time")
+ install(TARGETS time_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
+endif()
+target_link_libraries(time_functions libgroonga)
+
+read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/index_column_sources.am
+ INDEX_COLUMN_SOURCES)
+set_source_files_properties(${INDEX_COLUMN_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+if(GRN_EMBED)
+ add_library(index_column_functions STATIC ${INDEX_COLUMN_SOURCES})
+ set_target_properties(
+ index_column_functions
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+else()
+ add_library(index_column_functions MODULE ${INDEX_COLUMN_SOURCES})
+ set_target_properties(index_column_functions PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "index_column")
+ install(TARGETS index_column_functions
+ DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
+endif()
+target_link_libraries(index_column_functions libgroonga)
+
+read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/math_sources.am
+ MATH_SOURCES)
+set_source_files_properties(${MATH_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+if(GRN_EMBED)
+ add_library(math_functions STATIC ${MATH_SOURCES})
+ set_target_properties(
+ math_functions
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+else()
+ add_library(math_functions MODULE ${MATH_SOURCES})
+ set_target_properties(math_functions PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "math")
+ install(TARGETS math_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
+endif()
+target_link_libraries(math_functions libgroonga)
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/Makefile.am b/storage/mroonga/vendor/groonga/plugins/functions/Makefile.am
index 5d8d1d9cc84..f57ee031afe 100644
--- a/storage/mroonga/vendor/groonga/plugins/functions/Makefile.am
+++ b/storage/mroonga/vendor/groonga/plugins/functions/Makefile.am
@@ -16,5 +16,18 @@ LIBS = \
function_plugins_LTLIBRARIES =
function_plugins_LTLIBRARIES += vector.la
+function_plugins_LTLIBRARIES += string.la
+function_plugins_LTLIBRARIES += number.la
+function_plugins_LTLIBRARIES += time.la
+function_plugins_LTLIBRARIES += index_column.la
+function_plugins_LTLIBRARIES += math.la
include vector_sources.am
+include string_sources.am
+include number_sources.am
+include time_sources.am
+include index_column_sources.am
+include math_sources.am
+
+number_la_LIBADD = -lm
+math_la_LIBADD = -lm
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/index_column.c b/storage/mroonga/vendor/groonga/plugins/functions/index_column.c
new file mode 100644
index 00000000000..acb7355cf5c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/functions/index_column.c
@@ -0,0 +1,266 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG functions_time
+#endif
+
+#include <groonga/plugin.h>
+
+static grn_rc
+selector_index_column_df_ratio_between(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ int n_args,
+ grn_obj **args,
+ grn_obj *res,
+ grn_operator op)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *index_column;
+ grn_ii *ii;
+ double min;
+ double max;
+ grn_obj *source_table;
+ unsigned int n_documents;
+ grn_posting posting;
+
+ if ((n_args - 1) != 3) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "index_column_df_ratio_between(): "
+ "wrong number of arguments (%d for 3)", n_args - 1);
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ index_column = args[1];
+ ii = (grn_ii *)index_column;
+ min = GRN_FLOAT_VALUE(args[2]);
+ max = GRN_FLOAT_VALUE(args[3]);
+
+ source_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, index_column));
+ n_documents = grn_table_size(ctx, source_table);
+ memset(&posting, 0, sizeof(grn_posting));
+ posting.sid = 1;
+
+ if (op == GRN_OP_AND) {
+ GRN_TABLE_EACH_BEGIN(ctx, res, cursor, record_id) {
+ void *key;
+ grn_id term_id;
+ uint32_t n_match_documents;
+ double df_ratio;
+
+ grn_table_cursor_get_key(ctx, cursor, &key);
+ term_id = *(grn_id *)key;
+ n_match_documents = grn_ii_estimate_size(ctx, ii, term_id);
+ if (n_match_documents > n_documents) {
+ n_match_documents = n_documents;
+ }
+ df_ratio = (double)n_match_documents / (double)n_documents;
+ if (min <= df_ratio && df_ratio <= max) {
+ posting.rid = term_id;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
+ } else {
+ GRN_TABLE_EACH_BEGIN(ctx, table, cursor, term_id) {
+ uint32_t n_match_documents;
+ double df_ratio;
+
+ n_match_documents = grn_ii_estimate_size(ctx, ii, term_id);
+ if (n_match_documents > n_documents) {
+ n_match_documents = n_documents;
+ }
+ df_ratio = (double)n_match_documents / (double)n_documents;
+ {
+ void *key;
+ int key_size;
+ key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+ }
+ if (min <= df_ratio && df_ratio <= max) {
+ posting.rid = term_id;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
+ }
+ } GRN_TABLE_EACH_END(ctx, cursor);
+ }
+
+exit :
+ return rc;
+}
+
+static grn_obj *
+func_index_column_df_ratio(grn_ctx *ctx,
+ int n_args,
+ grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *term_table;
+ grn_obj *index_column_name;
+ grn_obj *index_column;
+ grn_ii *ii;
+ grn_id term_id;
+
+ if (n_args != 1) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "index_column_df_ratio(): "
+ "wrong number of arguments (%d for 1)", n_args - 1);
+ return NULL;
+ }
+
+ {
+ grn_obj *expr;
+ grn_obj *variable;
+
+ expr = grn_plugin_proc_get_caller(ctx, user_data);
+ if (!expr) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "index_column_df_ratio(): "
+ "called directly");
+ return NULL;
+ }
+
+ variable = grn_expr_get_var_by_offset(ctx, expr, 0);
+ if (!variable) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "index_column_df_ratio(): "
+ "caller expression must have target record information");
+ return NULL;
+ }
+
+ term_table = grn_ctx_at(ctx, variable->header.domain);
+ term_id = GRN_RECORD_VALUE(variable);
+ while (GRN_TRUE) {
+ grn_obj *key_type;
+
+ key_type = grn_ctx_at(ctx, term_table->header.domain);
+ if (!grn_obj_is_table(ctx, key_type)) {
+ break;
+ }
+
+ grn_table_get_key(ctx, term_table, term_id, &term_id, sizeof(grn_id));
+ term_table = key_type;
+ }
+ }
+
+ index_column_name = args[0];
+ if (!grn_obj_is_text_family_bulk(ctx, index_column_name)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, index_column_name);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "index_column_df_ratio(): "
+ "the first argument must be index column name: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+
+ index_column = grn_obj_column(ctx,
+ term_table,
+ GRN_TEXT_VALUE(index_column_name),
+ GRN_TEXT_LEN(index_column_name));
+ if (!index_column) {
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "index_column_df_ratio(): "
+ "nonexistent object: <%.*s>",
+ (int)GRN_TEXT_LEN(index_column_name),
+ GRN_TEXT_VALUE(index_column_name));
+ return NULL;
+ }
+
+ if (!grn_obj_is_index_column(ctx, index_column)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, index_column);
+ GRN_PLUGIN_ERROR(ctx,
+ GRN_INVALID_ARGUMENT,
+ "index_column_df_ratio(): "
+ "the first argument must be index column: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ if (grn_obj_is_accessor(ctx, index_column)) {
+ grn_obj_unlink(ctx, index_column);
+ }
+ return NULL;
+ }
+
+ ii = (grn_ii *)index_column;
+
+ {
+ grn_obj *source_table;
+ unsigned int n_documents;
+ uint32_t n_match_documents;
+ double df_ratio;
+ grn_obj *df_ratio_value;
+
+ source_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, index_column));
+ n_documents = grn_table_size(ctx, source_table);
+ n_match_documents = grn_ii_estimate_size(ctx, ii, term_id);
+ if (n_match_documents > n_documents) {
+ n_match_documents = n_documents;
+ }
+ df_ratio = (double)n_match_documents / (double)n_documents;
+
+ df_ratio_value = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_FLOAT, 0);
+ if (!df_ratio_value) {
+ return NULL;
+ }
+ GRN_FLOAT_SET(ctx, df_ratio_value, df_ratio);
+ return df_ratio_value;
+ }
+}
+
+grn_rc
+GRN_PLUGIN_INIT(grn_ctx *ctx)
+{
+ return ctx->rc;
+}
+
+grn_rc
+GRN_PLUGIN_REGISTER(grn_ctx *ctx)
+{
+ grn_obj *selector_proc;
+
+ selector_proc = grn_proc_create(ctx, "index_column_df_ratio_between", -1,
+ GRN_PROC_FUNCTION,
+ NULL, NULL, NULL, 0, NULL);
+ grn_proc_set_selector(ctx, selector_proc,
+ selector_index_column_df_ratio_between);
+ grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_NOP);
+
+ grn_proc_create(ctx, "index_column_df_ratio", -1,
+ GRN_PROC_FUNCTION,
+ func_index_column_df_ratio, NULL, NULL, 0, NULL);
+
+ return ctx->rc;
+}
+
+grn_rc
+GRN_PLUGIN_FIN(grn_ctx *ctx)
+{
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/index_column_sources.am b/storage/mroonga/vendor/groonga/plugins/functions/index_column_sources.am
new file mode 100644
index 00000000000..261907bc570
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/functions/index_column_sources.am
@@ -0,0 +1,2 @@
+index_column_la_SOURCES = \
+ index_column.c
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/math.c b/storage/mroonga/vendor/groonga/plugins/functions/math.c
new file mode 100644
index 00000000000..2527012e9ea
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/functions/math.c
@@ -0,0 +1,142 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG functions_math
+#endif
+
+#include <groonga/plugin.h>
+
+#include <math.h>
+#include <stdlib.h>
+
+static grn_obj *
+func_math_abs(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *number;
+ grn_obj *grn_abs_number = NULL;
+
+ if (n_args != 1) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "math_abs(): wrong number of arguments (%d for 1)",
+ n_args);
+ return NULL;
+ }
+
+ number = args[0];
+ if (!(number->header.type == GRN_BULK &&
+ grn_type_id_is_number_family(ctx, number->header.domain))) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, number);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "math_abs(): the first argument must be a number: "
+ "<%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+
+#define ABS_AS_IS(return_type, to_type, getter, setter) { \
+ grn_abs_number = grn_plugin_proc_alloc(ctx, \
+ user_data, \
+ (return_type), \
+ 0); \
+ if (!grn_abs_number) { \
+ return NULL; \
+ } \
+ setter(ctx, grn_abs_number, getter(number)); \
+ }
+#define ABS_CONVERT_TYPE(func, return_type, to_type, getter, setter) { \
+ grn_abs_number = grn_plugin_proc_alloc(ctx, \
+ user_data, \
+ (return_type), \
+ 0); \
+ if (!grn_abs_number) { \
+ return NULL; \
+ } else { \
+ to_type abs_number_raw = (to_type)(func)(getter(number)); \
+ setter(ctx, grn_abs_number, abs_number_raw); \
+ } \
+ }
+
+ switch (number->header.domain) {
+ case GRN_DB_INT8:
+ ABS_CONVERT_TYPE(abs, GRN_DB_UINT8, uint8_t, GRN_INT8_VALUE, GRN_UINT8_SET);
+ break;
+ case GRN_DB_UINT8:
+ ABS_AS_IS(GRN_DB_UINT8, uint8_t, GRN_UINT8_VALUE, GRN_UINT8_SET);
+ break;
+ case GRN_DB_INT16:
+ ABS_CONVERT_TYPE(abs, GRN_DB_UINT16, uint16_t, GRN_INT16_VALUE, GRN_UINT16_SET);
+ break;
+ case GRN_DB_UINT16:
+ ABS_AS_IS(GRN_DB_UINT16, uint16_t, GRN_UINT16_VALUE, GRN_UINT16_SET);
+ break;
+ case GRN_DB_INT32:
+ ABS_CONVERT_TYPE(labs, GRN_DB_UINT32, uint32_t, GRN_INT32_VALUE, GRN_UINT32_SET);
+ break;
+ case GRN_DB_UINT32:
+ ABS_AS_IS(GRN_DB_UINT32, uint32_t, GRN_UINT32_VALUE, GRN_UINT32_SET);
+ break;
+ case GRN_DB_INT64:
+ ABS_CONVERT_TYPE(llabs, GRN_DB_UINT64, uint64_t, GRN_INT64_VALUE, GRN_UINT64_SET);
+ break;
+ case GRN_DB_UINT64:
+ ABS_AS_IS(GRN_DB_UINT64, uint64_t, GRN_UINT64_VALUE, GRN_UINT64_SET);
+ break;
+ case GRN_DB_FLOAT:
+ ABS_CONVERT_TYPE(fabs, GRN_DB_FLOAT, double, GRN_FLOAT_VALUE, GRN_FLOAT_SET);
+ break;
+ default :
+ break;
+ }
+#undef ABS_CONVERT_TYPE
+#undef ABS_AS_IS
+
+ return grn_abs_number;
+}
+
+grn_rc
+GRN_PLUGIN_INIT(grn_ctx *ctx)
+{
+ return ctx->rc;
+}
+
+grn_rc
+GRN_PLUGIN_REGISTER(grn_ctx *ctx)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ grn_proc_create(ctx,
+ "math_abs", -1,
+ GRN_PROC_FUNCTION,
+ func_math_abs,
+ NULL, NULL, 0, NULL);
+
+ return rc;
+}
+
+grn_rc
+GRN_PLUGIN_FIN(grn_ctx *ctx)
+{
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/math_sources.am b/storage/mroonga/vendor/groonga/plugins/functions/math_sources.am
new file mode 100644
index 00000000000..8c14ca7469d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/functions/math_sources.am
@@ -0,0 +1,2 @@
+math_la_SOURCES = \
+ math.c
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/number.c b/storage/mroonga/vendor/groonga/plugins/functions/number.c
new file mode 100644
index 00000000000..285c88f58f2
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/functions/number.c
@@ -0,0 +1,187 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG functions_number
+#endif
+
+#include <groonga/plugin.h>
+
+#include <math.h>
+
+static grn_obj *
+func_number_classify(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *number;
+ grn_obj *interval;
+ grn_obj casted_interval;
+ grn_obj *classed_number;
+
+ if (n_args != 2) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "number_classify(): wrong number of arguments (%d for 2)",
+ n_args);
+ return NULL;
+ }
+
+ number = args[0];
+ if (!(number->header.type == GRN_BULK &&
+ grn_type_id_is_number_family(ctx, number->header.domain))) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, number);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "number_classify(): the first argument must be a number: "
+ "<%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+
+ interval = args[1];
+ if (!(interval->header.type == GRN_BULK &&
+ grn_type_id_is_number_family(ctx, interval->header.domain))) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, interval);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "number_classify(): the second argument must be a number: "
+ "<%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+
+ classed_number = grn_plugin_proc_alloc(ctx,
+ user_data,
+ number->header.domain,
+ 0);
+ if (!classed_number) {
+ return NULL;
+ }
+
+ GRN_VALUE_FIX_SIZE_INIT(&casted_interval, 0, number->header.domain);
+ grn_obj_cast(ctx, interval, &casted_interval, GRN_FALSE);
+
+#define CLASSIFY_RAW(type, getter, setter, classifier) { \
+ type number_raw; \
+ type interval_raw; \
+ type class_raw; \
+ type classed_number_raw; \
+ \
+ number_raw = getter(number); \
+ interval_raw = getter(&casted_interval); \
+ class_raw = classifier(number_raw, interval_raw); \
+ classed_number_raw = class_raw * interval_raw; \
+ setter(ctx, classed_number, classed_number_raw); \
+ }
+
+#define CLASSIFIER_INT(number_raw, interval_raw) \
+ (number_raw) < 0 ? \
+ ((((number_raw) + 1) / (interval_raw)) - 1) : \
+ (((number_raw) / (interval_raw)))
+
+#define CLASSIFY_INT(type, getter, setter) \
+ CLASSIFY_RAW(type, getter, setter, CLASSIFIER_INT)
+
+#define CLASSIFIER_UINT(number_raw, interval_raw) \
+ ((number_raw) / (interval_raw))
+
+#define CLASSIFY_UINT(type, getter, setter) \
+ CLASSIFY_RAW(type, getter, setter, CLASSIFIER_UINT)
+
+#define CLASSIFIER_FLOAT(number_raw, interval_raw) \
+ floor((number_raw) / (interval_raw))
+
+#define CLASSIFY_FLOAT(getter, setter) \
+ CLASSIFY_RAW(double, getter, setter, CLASSIFIER_FLOAT)
+
+ switch (number->header.domain) {
+ case GRN_DB_INT8 :
+ CLASSIFY_INT(int8_t, GRN_INT8_VALUE, GRN_INT8_SET);
+ break;
+ case GRN_DB_UINT8 :
+ CLASSIFY_UINT(uint8_t, GRN_UINT8_VALUE, GRN_UINT8_SET);
+ break;
+ case GRN_DB_INT16 :
+ CLASSIFY_INT(int16_t, GRN_INT16_VALUE, GRN_INT16_SET);
+ break;
+ case GRN_DB_UINT16 :
+ CLASSIFY_UINT(uint16_t, GRN_UINT16_VALUE, GRN_UINT16_SET);
+ break;
+ case GRN_DB_INT32 :
+ CLASSIFY_INT(int32_t, GRN_INT32_VALUE, GRN_INT32_SET);
+ break;
+ case GRN_DB_UINT32 :
+ CLASSIFY_UINT(uint32_t, GRN_UINT32_VALUE, GRN_UINT32_SET);
+ break;
+ case GRN_DB_INT64 :
+ CLASSIFY_INT(int64_t, GRN_INT64_VALUE, GRN_INT64_SET);
+ break;
+ case GRN_DB_UINT64 :
+ CLASSIFY_UINT(uint64_t, GRN_UINT64_VALUE, GRN_UINT64_SET);
+ break;
+ case GRN_DB_FLOAT :
+ CLASSIFY_FLOAT(GRN_FLOAT_VALUE, GRN_FLOAT_SET);
+ break;
+ default :
+ break;
+ }
+#undef CLASSIFY_FLOAT
+#undef CLASSIFIER_FLAOT
+#undef CLASSIFY_UINT
+#undef CLASSIFIER_UINT
+#undef CLASSIFY_INT
+#undef CLASSIFIER_INT
+#undef CLASSIFY_RAW
+
+ GRN_OBJ_FIN(ctx, &casted_interval);
+
+ return classed_number;
+}
+
+grn_rc
+GRN_PLUGIN_INIT(grn_ctx *ctx)
+{
+ return ctx->rc;
+}
+
+grn_rc
+GRN_PLUGIN_REGISTER(grn_ctx *ctx)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ grn_proc_create(ctx,
+ "number_classify", -1,
+ GRN_PROC_FUNCTION,
+ func_number_classify,
+ NULL, NULL, 0, NULL);
+
+ return rc;
+}
+
+grn_rc
+GRN_PLUGIN_FIN(grn_ctx *ctx)
+{
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/number_sources.am b/storage/mroonga/vendor/groonga/plugins/functions/number_sources.am
new file mode 100644
index 00000000000..b3d9483be9a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/functions/number_sources.am
@@ -0,0 +1,2 @@
+number_la_SOURCES = \
+ number.c
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/string.c b/storage/mroonga/vendor/groonga/plugins/functions/string.c
new file mode 100644
index 00000000000..aeef335ec55
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/functions/string.c
@@ -0,0 +1,299 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG functions_string
+#endif
+
+#include <groonga/plugin.h>
+
+/*
+ * func_string_length() returns the number of characters in a string.
+ * If the string contains an invalid byte sequence, this function returns the
+ * number of characters before the invalid byte sequence.
+ */
+static grn_obj *
+func_string_length(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *target;
+ unsigned int length = 0;
+ grn_obj *grn_length;
+
+ if (n_args != 1) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "string_length(): wrong number of arguments (%d for 1)",
+ n_args);
+ return NULL;
+ }
+
+ target = args[0];
+ if (!(target->header.type == GRN_BULK &&
+ ((target->header.domain == GRN_DB_SHORT_TEXT) ||
+ (target->header.domain == GRN_DB_TEXT) ||
+ (target->header.domain == GRN_DB_LONG_TEXT)))) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, target);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "string_length(): target object must be a text bulk: "
+ "<%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+
+ {
+ const char *s = GRN_TEXT_VALUE(target);
+ const char *e = GRN_TEXT_VALUE(target) + GRN_TEXT_LEN(target);
+ const char *p;
+ unsigned int cl = 0;
+ for (p = s; p < e && (cl = grn_charlen(ctx, p, e)); p += cl) {
+ length++;
+ }
+ }
+
+ grn_length = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_UINT32, 0);
+ if (!grn_length) {
+ return NULL;
+ }
+
+ GRN_UINT32_SET(ctx, grn_length, length);
+
+ return grn_length;
+}
+
+static grn_obj *
+func_string_substring(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *target;
+ grn_obj *from_raw;
+ grn_obj *length_raw = NULL;
+ int64_t from = 0;
+ int64_t length = -1;
+ const char *start = NULL;
+ const char *end = NULL;
+ grn_obj *substring;
+
+ if (n_args < 2) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "string_substring(): wrong number of arguments (%d for 2..3)",
+ n_args);
+ return NULL;
+ }
+
+ target = args[0];
+ from_raw = args[1];
+ if (n_args == 3) {
+ length_raw = args[2];
+ }
+
+ if (!(target->header.type == GRN_BULK &&
+ grn_type_id_is_text_family(ctx, target->header.domain))) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, target);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "string_substring(): target object must be a text bulk: "
+ "<%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+
+ /* TODO: extract as grn_func_arg_int64() */
+ if (!grn_type_id_is_number_family(ctx, from_raw->header.domain)) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, from_raw);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "string_substring(): from must be a number: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+ if (from_raw->header.domain == GRN_DB_INT32) {
+ from = GRN_INT32_VALUE(from_raw);
+ } else if (from_raw->header.domain == GRN_DB_INT64) {
+ from = GRN_INT64_VALUE(from_raw);
+ } else {
+ grn_obj buffer;
+ grn_rc rc;
+
+ GRN_INT64_INIT(&buffer, 0);
+ rc = grn_obj_cast(ctx, from_raw, &buffer, GRN_FALSE);
+ if (rc == GRN_SUCCESS) {
+ from = GRN_INT64_VALUE(&buffer);
+ }
+ GRN_OBJ_FIN(ctx, &buffer);
+
+ if (rc != GRN_SUCCESS) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, from_raw);
+ GRN_PLUGIN_ERROR(ctx, rc,
+ "string_substring(): "
+ "failed to cast from value to number: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+ }
+
+ if (length_raw) {
+ /* TODO: extract as grn_func_arg_int64() */
+ if (!grn_type_id_is_number_family(ctx, length_raw->header.domain)) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, length_raw);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "string_substring(): length must be a number: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+ if (length_raw->header.domain == GRN_DB_INT32) {
+ length = GRN_INT32_VALUE(length_raw);
+ } else if (length_raw->header.domain == GRN_DB_INT64) {
+ length = GRN_INT64_VALUE(length_raw);
+ } else {
+ grn_obj buffer;
+ grn_rc rc;
+
+ GRN_INT64_INIT(&buffer, 0);
+ rc = grn_obj_cast(ctx, length_raw, &buffer, GRN_FALSE);
+ if (rc == GRN_SUCCESS) {
+ length = GRN_INT64_VALUE(&buffer);
+ }
+ GRN_OBJ_FIN(ctx, &buffer);
+
+ if (rc != GRN_SUCCESS) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, length_raw);
+ GRN_PLUGIN_ERROR(ctx, rc,
+ "string_substring(): "
+ "failed to cast length value to number: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+ }
+ }
+
+ substring = grn_plugin_proc_alloc(ctx, user_data, target->header.domain, 0);
+ if (!substring) {
+ return NULL;
+ }
+
+ GRN_BULK_REWIND(substring);
+
+ if (GRN_TEXT_LEN(target) == 0) {
+ return substring;
+ }
+ if (length == 0) {
+ return substring;
+ }
+
+ while (from < 0) {
+ from += GRN_TEXT_LEN(target);
+ }
+
+ {
+ const char *p;
+
+ start = NULL;
+ p = GRN_TEXT_VALUE(target);
+ end = p + GRN_TEXT_LEN(target);
+
+ if (from == 0) {
+ start = p;
+ } else {
+ unsigned int char_length = 0;
+ size_t n_chars = 0;
+
+ for (;
+ p < end && (char_length = grn_charlen(ctx, p, end));
+ p += char_length, n_chars++) {
+ if (n_chars == from) {
+ start = p;
+ break;
+ }
+ }
+ }
+
+ if (start && length > 0) {
+ unsigned int char_length = 0;
+ size_t n_chars = 0;
+
+ for (;
+ p < end && (char_length = grn_charlen(ctx, p, end));
+ p += char_length, n_chars++) {
+ if (n_chars == length) {
+ end = p;
+ break;
+ }
+ }
+ }
+ }
+
+ if (start) {
+ GRN_TEXT_SET(ctx, substring, start, end - start);
+ }
+
+ return substring;
+}
+
+grn_rc
+GRN_PLUGIN_INIT(grn_ctx *ctx)
+{
+ return ctx->rc;
+}
+
+grn_rc
+GRN_PLUGIN_REGISTER(grn_ctx *ctx)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ grn_proc_create(ctx, "string_length", -1, GRN_PROC_FUNCTION, func_string_length,
+ NULL, NULL, 0, NULL);
+
+ grn_proc_create(ctx, "string_substring", -1, GRN_PROC_FUNCTION, func_string_substring,
+ NULL, NULL, 0, NULL);
+
+ return rc;
+}
+
+grn_rc
+GRN_PLUGIN_FIN(grn_ctx *ctx)
+{
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/string_sources.am b/storage/mroonga/vendor/groonga/plugins/functions/string_sources.am
new file mode 100644
index 00000000000..3477e58abe1
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/functions/string_sources.am
@@ -0,0 +1,2 @@
+string_la_SOURCES = \
+ string.c
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/time.c b/storage/mroonga/vendor/groonga/plugins/functions/time.c
new file mode 100644
index 00000000000..dc54f47ea52
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/functions/time.c
@@ -0,0 +1,376 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2016 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG functions_time
+#endif
+
+#include <groonga/plugin.h>
+
+#include <math.h>
+
+typedef enum {
+ GRN_TIME_CLASSIFY_UNIT_SECOND,
+ GRN_TIME_CLASSIFY_UNIT_MINUTE,
+ GRN_TIME_CLASSIFY_UNIT_HOUR,
+ GRN_TIME_CLASSIFY_UNIT_DAY,
+ GRN_TIME_CLASSIFY_UNIT_WEEK,
+ GRN_TIME_CLASSIFY_UNIT_MONTH,
+ GRN_TIME_CLASSIFY_UNIT_YEAR
+} grn_time_classify_unit;
+
+static grn_obj *
+func_time_classify_raw(grn_ctx *ctx,
+ int n_args,
+ grn_obj **args,
+ grn_user_data *user_data,
+ const char *function_name,
+ grn_time_classify_unit unit)
+{
+ grn_obj *time;
+ uint32_t interval_raw = 1;
+ grn_obj *classed_time;
+ grn_bool accept_interval = GRN_TRUE;
+
+ switch (unit) {
+ case GRN_TIME_CLASSIFY_UNIT_SECOND :
+ case GRN_TIME_CLASSIFY_UNIT_MINUTE :
+ case GRN_TIME_CLASSIFY_UNIT_HOUR :
+ accept_interval = GRN_TRUE;
+ break;
+ case GRN_TIME_CLASSIFY_UNIT_DAY :
+ case GRN_TIME_CLASSIFY_UNIT_WEEK :
+ accept_interval = GRN_FALSE;
+ break;
+ case GRN_TIME_CLASSIFY_UNIT_MONTH :
+ case GRN_TIME_CLASSIFY_UNIT_YEAR :
+ accept_interval = GRN_TRUE;
+ break;
+ }
+
+ if (accept_interval) {
+ if (!(n_args == 1 || n_args == 2)) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "%s(): "
+ "wrong number of arguments (%d for 1..2)",
+ function_name,
+ n_args);
+ return NULL;
+ }
+ } else {
+ if (n_args != 1) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "%s(): "
+ "wrong number of arguments (%d for 1)",
+ function_name,
+ n_args);
+ return NULL;
+ }
+ }
+
+ time = args[0];
+ if (!(time->header.type == GRN_BULK &&
+ time->header.domain == GRN_DB_TIME)) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, time);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "%s(): "
+ "the first argument must be a time: "
+ "<%.*s>",
+ function_name,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+
+ if (n_args == 2) {
+ grn_obj *interval;
+ grn_obj casted_interval;
+
+ interval = args[1];
+ if (!(interval->header.type == GRN_BULK &&
+ grn_type_id_is_number_family(ctx, interval->header.domain))) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, interval);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "%s(): "
+ "the second argument must be a number: "
+ "<%.*s>",
+ function_name,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+
+ GRN_VALUE_FIX_SIZE_INIT(&casted_interval, 0, GRN_DB_UINT32);
+ grn_obj_cast(ctx, interval, &casted_interval, GRN_FALSE);
+ interval_raw = GRN_UINT32_VALUE(&casted_interval);
+ GRN_OBJ_FIN(ctx, &casted_interval);
+
+ if (interval_raw == 0) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, interval);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "%s(): "
+ "the second argument must not be zero: "
+ "<%.*s>",
+ function_name,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+ }
+
+ {
+ int64_t time_raw;
+ struct tm tm;
+ int64_t classed_time_raw;
+
+ time_raw = GRN_TIME_VALUE(time);
+ if (!grn_time_to_tm(ctx, time_raw, &tm)) {
+ return NULL;
+ }
+
+ switch (unit) {
+ case GRN_TIME_CLASSIFY_UNIT_SECOND :
+ tm.tm_sec = (tm.tm_sec / interval_raw) * interval_raw;
+ break;
+ case GRN_TIME_CLASSIFY_UNIT_MINUTE :
+ tm.tm_min = (tm.tm_min / interval_raw) * interval_raw;
+ tm.tm_sec = 0;
+ break;
+ case GRN_TIME_CLASSIFY_UNIT_HOUR :
+ tm.tm_hour = (tm.tm_hour / interval_raw) * interval_raw;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ break;
+ case GRN_TIME_CLASSIFY_UNIT_DAY :
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ break;
+ case GRN_TIME_CLASSIFY_UNIT_WEEK :
+ if ((tm.tm_mday - tm.tm_wday) >= 0) {
+ tm.tm_mday -= tm.tm_wday;
+ } else {
+ int n_underflowed_mday = -(tm.tm_mday - tm.tm_wday);
+ int mday;
+ int max_mday = 31;
+
+ if (tm.tm_mon == 0) {
+ tm.tm_year--;
+ tm.tm_mon = 11;
+ } else {
+ tm.tm_mon--;
+ }
+
+ for (mday = max_mday; mday > n_underflowed_mday; mday--) {
+ int64_t unused;
+ tm.tm_mday = mday;
+ if (grn_time_from_tm(ctx, &unused, &tm)) {
+ break;
+ }
+ }
+ tm.tm_mday -= n_underflowed_mday;
+ }
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ break;
+ case GRN_TIME_CLASSIFY_UNIT_MONTH :
+ tm.tm_mon = (tm.tm_mon / interval_raw) * interval_raw;
+ tm.tm_mday = 1;
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ break;
+ case GRN_TIME_CLASSIFY_UNIT_YEAR :
+ tm.tm_year = (((1900 + tm.tm_year) / interval_raw) * interval_raw) - 1900;
+ tm.tm_mon = 0;
+ tm.tm_mday = 1;
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ break;
+ }
+
+ if (!grn_time_from_tm(ctx, &classed_time_raw, &tm)) {
+ return NULL;
+ }
+
+ classed_time = grn_plugin_proc_alloc(ctx,
+ user_data,
+ time->header.domain,
+ 0);
+ if (!classed_time) {
+ return NULL;
+ }
+ GRN_TIME_SET(ctx, classed_time, classed_time_raw);
+
+ return classed_time;
+ }
+}
+
+static grn_obj *
+func_time_classify_second(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ return func_time_classify_raw(ctx,
+ n_args,
+ args,
+ user_data,
+ "time_classify_second",
+ GRN_TIME_CLASSIFY_UNIT_SECOND);
+}
+
+static grn_obj *
+func_time_classify_minute(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ return func_time_classify_raw(ctx,
+ n_args,
+ args,
+ user_data,
+ "time_classify_minute",
+ GRN_TIME_CLASSIFY_UNIT_MINUTE);
+}
+
+static grn_obj *
+func_time_classify_hour(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ return func_time_classify_raw(ctx,
+ n_args,
+ args,
+ user_data,
+ "time_classify_hour",
+ GRN_TIME_CLASSIFY_UNIT_HOUR);
+}
+
+static grn_obj *
+func_time_classify_day(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ return func_time_classify_raw(ctx,
+ n_args,
+ args,
+ user_data,
+ "time_classify_day",
+ GRN_TIME_CLASSIFY_UNIT_DAY);
+}
+
+static grn_obj *
+func_time_classify_week(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ return func_time_classify_raw(ctx,
+ n_args,
+ args,
+ user_data,
+ "time_classify_week",
+ GRN_TIME_CLASSIFY_UNIT_WEEK);
+}
+
+static grn_obj *
+func_time_classify_month(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ return func_time_classify_raw(ctx,
+ n_args,
+ args,
+ user_data,
+ "time_classify_month",
+ GRN_TIME_CLASSIFY_UNIT_MONTH);
+}
+
+static grn_obj *
+func_time_classify_year(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ return func_time_classify_raw(ctx,
+ n_args,
+ args,
+ user_data,
+ "time_classify_year",
+ GRN_TIME_CLASSIFY_UNIT_YEAR);
+}
+
+grn_rc
+GRN_PLUGIN_INIT(grn_ctx *ctx)
+{
+ return ctx->rc;
+}
+
+grn_rc
+GRN_PLUGIN_REGISTER(grn_ctx *ctx)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ grn_proc_create(ctx,
+ "time_classify_second", -1,
+ GRN_PROC_FUNCTION,
+ func_time_classify_second,
+ NULL, NULL, 0, NULL);
+ grn_proc_create(ctx,
+ "time_classify_minute", -1,
+ GRN_PROC_FUNCTION,
+ func_time_classify_minute,
+ NULL, NULL, 0, NULL);
+ grn_proc_create(ctx,
+ "time_classify_hour", -1,
+ GRN_PROC_FUNCTION,
+ func_time_classify_hour,
+ NULL, NULL, 0, NULL);
+ grn_proc_create(ctx,
+ "time_classify_day", -1,
+ GRN_PROC_FUNCTION,
+ func_time_classify_day,
+ NULL, NULL, 0, NULL);
+ grn_proc_create(ctx,
+ "time_classify_week", -1,
+ GRN_PROC_FUNCTION,
+ func_time_classify_week,
+ NULL, NULL, 0, NULL);
+ grn_proc_create(ctx,
+ "time_classify_month", -1,
+ GRN_PROC_FUNCTION,
+ func_time_classify_month,
+ NULL, NULL, 0, NULL);
+ grn_proc_create(ctx,
+ "time_classify_year", -1,
+ GRN_PROC_FUNCTION,
+ func_time_classify_year,
+ NULL, NULL, 0, NULL);
+
+ return rc;
+}
+
+grn_rc
+GRN_PLUGIN_FIN(grn_ctx *ctx)
+{
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/time_sources.am b/storage/mroonga/vendor/groonga/plugins/functions/time_sources.am
new file mode 100644
index 00000000000..2c55a570f0b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/functions/time_sources.am
@@ -0,0 +1,2 @@
+time_la_SOURCES = \
+ time.c
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/vector.c b/storage/mroonga/vendor/groonga/plugins/functions/vector.c
index a92fee9dbec..a7283fc59eb 100644
--- a/storage/mroonga/vendor/groonga/plugins/functions/vector.c
+++ b/storage/mroonga/vendor/groonga/plugins/functions/vector.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2015 Brazil
+ Copyright(C) 2015-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -70,6 +70,307 @@ func_vector_size(grn_ctx *ctx, int n_args, grn_obj **args,
return grn_size;
}
+static grn_obj *
+func_vector_slice(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *target;
+ grn_obj *from_raw = NULL;
+ grn_obj *length_raw = NULL;
+ int64_t from = 0;
+ int64_t length = -1;
+ uint32_t to = 0;
+ uint32_t size = 0;
+ grn_obj *slice;
+
+ if (n_args < 2 || n_args > 3) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "vector_slice(): wrong number of arguments (%d for 2..3)",
+ n_args);
+ return NULL;
+ }
+
+ target = args[0];
+ from_raw = args[1];
+ if (n_args == 3) {
+ length_raw = args[2];
+ }
+ switch (target->header.type) {
+ case GRN_VECTOR :
+ case GRN_PVECTOR :
+ case GRN_UVECTOR :
+ size = grn_vector_size(ctx, target);
+ break;
+ default :
+ {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, target, &inspected);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "vector_slice(): target object must be vector: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+ break;
+ }
+
+ if (!grn_type_id_is_number_family(ctx, from_raw->header.domain)) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, from_raw);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "vector_slice(): from must be a number: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+ if (from_raw->header.domain == GRN_DB_INT32) {
+ from = GRN_INT32_VALUE(from_raw);
+ } else if (from_raw->header.domain == GRN_DB_INT64) {
+ from = GRN_INT64_VALUE(from_raw);
+ } else {
+ grn_obj buffer;
+ grn_rc rc;
+
+ GRN_INT64_INIT(&buffer, 0);
+ rc = grn_obj_cast(ctx, from_raw, &buffer, GRN_FALSE);
+ if (rc == GRN_SUCCESS) {
+ from = GRN_INT64_VALUE(&buffer);
+ }
+ GRN_OBJ_FIN(ctx, &buffer);
+
+ if (rc != GRN_SUCCESS) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, from_raw);
+ GRN_PLUGIN_ERROR(ctx, rc,
+ "vector_slice(): "
+ "failed to cast from value to number: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+ }
+
+ if (length_raw) {
+ if (!grn_type_id_is_number_family(ctx, length_raw->header.domain)) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, length_raw);
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+ "vector_slice(): length must be a number: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+ if (length_raw->header.domain == GRN_DB_INT32) {
+ length = GRN_INT32_VALUE(length_raw);
+ } else if (length_raw->header.domain == GRN_DB_INT64) {
+ length = GRN_INT64_VALUE(length_raw);
+ } else {
+ grn_obj buffer;
+ grn_rc rc;
+
+ GRN_INT64_INIT(&buffer, 0);
+ rc = grn_obj_cast(ctx, length_raw, &buffer, GRN_FALSE);
+ if (rc == GRN_SUCCESS) {
+ length = GRN_INT64_VALUE(&buffer);
+ }
+ GRN_OBJ_FIN(ctx, &buffer);
+
+ if (rc != GRN_SUCCESS) {
+ grn_obj inspected;
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, length_raw);
+ GRN_PLUGIN_ERROR(ctx, rc,
+ "vector_slice(): "
+ "failed to cast length value to number: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return NULL;
+ }
+ }
+ }
+
+ slice = grn_plugin_proc_alloc(ctx, user_data, target->header.domain, GRN_OBJ_VECTOR);
+ if (!slice) {
+ return NULL;
+ }
+
+ if (target->header.flags & GRN_OBJ_WITH_WEIGHT) {
+ slice->header.flags |= GRN_OBJ_WITH_WEIGHT;
+ }
+
+ if (length < 0) {
+ length = size + length + 1;
+ }
+
+ if (length > size) {
+ length = size;
+ }
+
+ if (length <= 0) {
+ return slice;
+ }
+
+ while (from < 0) {
+ from += size;
+ }
+
+ to = from + length;
+ if (to > size) {
+ to = size;
+ }
+
+ switch (target->header.type) {
+ case GRN_VECTOR :
+ {
+ unsigned int i;
+ for (i = from; i < to; i++) {
+ const char *content;
+ unsigned int content_length;
+ unsigned int weight;
+ grn_id domain;
+ content_length = grn_vector_get_element(ctx, target, i,
+ &content, &weight, &domain);
+ grn_vector_add_element(ctx, slice,
+ content, content_length, weight, domain);
+ }
+ }
+ break;
+ case GRN_PVECTOR :
+ {
+ unsigned int i;
+ for (i = from; i < to; i++) {
+ grn_obj *element = GRN_PTR_VALUE_AT(target, i);
+ GRN_PTR_PUT(ctx, slice, element);
+ }
+ }
+ break;
+ case GRN_UVECTOR :
+ {
+ grn_obj *domain;
+
+ domain = grn_ctx_at(ctx, target->header.domain);
+ if (grn_obj_is_table(ctx, domain)) {
+ unsigned int i;
+ for (i = from; i < to; i++) {
+ grn_id id;
+ unsigned int weight;
+ id = grn_uvector_get_element(ctx, target, i, &weight);
+ grn_uvector_add_element(ctx, slice, id, weight);
+ }
+ } else {
+#define PUT_SLICE_VALUES(type) do { \
+ unsigned int i; \
+ for (i = from; i < to; i++) { \
+ GRN_ ## type ## _PUT(ctx, \
+ slice, \
+ GRN_ ## type ## _VALUE_AT(target, i)); \
+ } \
+ } while (GRN_FALSE)
+ switch (target->header.domain) {
+ case GRN_DB_BOOL :
+ PUT_SLICE_VALUES(BOOL);
+ break;
+ case GRN_DB_INT8 :
+ PUT_SLICE_VALUES(INT8);
+ break;
+ case GRN_DB_UINT8 :
+ PUT_SLICE_VALUES(UINT8);
+ break;
+ case GRN_DB_INT16 :
+ PUT_SLICE_VALUES(INT16);
+ break;
+ case GRN_DB_UINT16 :
+ PUT_SLICE_VALUES(UINT16);
+ break;
+ case GRN_DB_INT32 :
+ PUT_SLICE_VALUES(INT32);
+ break;
+ case GRN_DB_UINT32 :
+ PUT_SLICE_VALUES(UINT32);
+ break;
+ case GRN_DB_INT64 :
+ PUT_SLICE_VALUES(INT64);
+ break;
+ case GRN_DB_UINT64 :
+ PUT_SLICE_VALUES(UINT64);
+ break;
+ case GRN_DB_FLOAT :
+ PUT_SLICE_VALUES(FLOAT);
+ break;
+ case GRN_DB_TIME :
+ PUT_SLICE_VALUES(TIME);
+ break;
+ }
+ }
+ }
+ break;
+#undef PUT_SLICE_VALUES
+ }
+
+ return slice;
+}
+
+static grn_obj *
+func_vector_new(grn_ctx *ctx, int n_args, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *vector = NULL;
+ int i;
+
+ if (n_args == 0) {
+ return grn_plugin_proc_alloc(ctx, user_data, GRN_DB_UINT32, GRN_OBJ_VECTOR);
+ }
+
+ vector = grn_plugin_proc_alloc(ctx,
+ user_data,
+ args[0]->header.domain,
+ GRN_OBJ_VECTOR);
+ if (!vector) {
+ return NULL;
+ }
+
+ for (i = 0; i < n_args; i++) {
+ grn_obj *element = args[i];
+ switch (vector->header.type) {
+ case GRN_VECTOR :
+ grn_vector_add_element(ctx,
+ vector,
+ GRN_BULK_HEAD(element),
+ GRN_BULK_VSIZE(element),
+ 0,
+ element->header.domain);
+ break;
+ case GRN_UVECTOR :
+ grn_bulk_write(ctx,
+ vector,
+ GRN_BULK_HEAD(element),
+ GRN_BULK_VSIZE(element));
+ break;
+ case GRN_PVECTOR :
+ GRN_PTR_PUT(ctx, vector, element);
+ break;
+ default :
+ break;
+ }
+ }
+
+ return vector;
+}
+
grn_rc
GRN_PLUGIN_INIT(grn_ctx *ctx)
{
@@ -84,6 +385,12 @@ GRN_PLUGIN_REGISTER(grn_ctx *ctx)
grn_proc_create(ctx, "vector_size", -1, GRN_PROC_FUNCTION, func_vector_size,
NULL, NULL, 0, NULL);
+ grn_proc_create(ctx, "vector_slice", -1, GRN_PROC_FUNCTION, func_vector_slice,
+ NULL, NULL, 0, NULL);
+
+ grn_proc_create(ctx, "vector_new", -1, GRN_PROC_FUNCTION, func_vector_new,
+ NULL, NULL, 0, NULL);
+
return rc;
}
diff --git a/storage/mroonga/vendor/groonga/plugins/query_expanders/Makefile.am b/storage/mroonga/vendor/groonga/plugins/query_expanders/Makefile.am
index ca26760d332..96c0911a070 100644
--- a/storage/mroonga/vendor/groonga/plugins/query_expanders/Makefile.am
+++ b/storage/mroonga/vendor/groonga/plugins/query_expanders/Makefile.am
@@ -14,7 +14,7 @@ AM_LDFLAGS = \
LIBS = \
$(top_builddir)/lib/libgroonga.la
-query_expanders_plugins_LTLIBRARIES =
-query_expanders_plugins_LTLIBRARIES += tsv.la
+query_expander_plugins_LTLIBRARIES =
+query_expander_plugins_LTLIBRARIES += tsv.la
include tsv_sources.am
diff --git a/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c b/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c
index 00550f6822b..2b0a5ba244e 100644
--- a/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c
+++ b/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c
@@ -19,27 +19,20 @@
# define GRN_PLUGIN_FUNCTION_TAG query_expanders_tsv
#endif
-/* groonga's internal headers */
-/* for grn_text_fgets(): We don't want to require stdio.h for groonga.h.
- What should we do? Should we split header file such as groonga/stdio.h? */
-#include <grn_str.h>
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
#include <groonga/plugin.h>
-#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#ifdef WIN32
+# include <windows.h>
# include <share.h>
#endif /* WIN32 */
-#ifdef HAVE__STRNICMP
-# ifdef strncasecmp
-# undef strncasecmp
-# endif /* strncasecmp */
-# define strncasecmp(s1,s2,n) _strnicmp(s1,s2,n)
-#endif /* HAVE__STRNICMP */
-
#define MAX_SYNONYM_BYTES 4096
static grn_hash *synonyms = NULL;
@@ -54,7 +47,7 @@ get_system_synonyms_file(void)
const char *relative_path = GRN_QUERY_EXPANDER_TSV_RELATIVE_SYNONYMS_FILE;
size_t base_dir_length;
- base_dir = grn_plugin_win32_base_dir();
+ base_dir = grn_plugin_windows_base_dir();
base_dir_length = strlen(base_dir);
grn_strcpy(win32_synonyms_file, MAX_PATH, base_dir);
grn_strcat(win32_synonyms_file, MAX_PATH, "/");
@@ -71,13 +64,13 @@ get_system_synonyms_file(void)
}
#endif /* WIN32 */
-static inline grn_bool
+static grn_bool
is_comment_mark(char character)
{
return character == '#';
}
-static inline grn_encoding
+static grn_encoding
detect_coding_part(grn_ctx *ctx, const char *line, size_t line_length)
{
grn_encoding encoding = GRN_ENC_NONE;
@@ -95,19 +88,19 @@ detect_coding_part(grn_ctx *ctx, const char *line, size_t line_length)
coding_part = strstr(c_line, coding_part_keyword);
if (coding_part) {
encoding_name = coding_part + strlen(coding_part_keyword);
- if (strncasecmp(encoding_name, "utf-8", strlen("utf-8")) == 0 ||
- strncasecmp(encoding_name, "utf8", strlen("utf8")) == 0) {
+ if (grn_strncasecmp(encoding_name, "utf-8", strlen("utf-8")) == 0 ||
+ grn_strncasecmp(encoding_name, "utf8", strlen("utf8")) == 0) {
encoding = GRN_ENC_UTF8;
- } else if (strncasecmp(encoding_name, "sjis", strlen("sjis")) == 0 ||
- strncasecmp(encoding_name, "Shift_JIS", strlen("Shift_JIS")) == 0) {
+ } else if (grn_strncasecmp(encoding_name, "sjis", strlen("sjis")) == 0 ||
+ grn_strncasecmp(encoding_name, "Shift_JIS", strlen("Shift_JIS")) == 0) {
encoding = GRN_ENC_SJIS;
- } else if (strncasecmp(encoding_name, "EUC-JP", strlen("EUC-JP")) == 0 ||
- strncasecmp(encoding_name, "euc_jp", strlen("euc_jp")) == 0) {
+ } else if (grn_strncasecmp(encoding_name, "EUC-JP", strlen("EUC-JP")) == 0 ||
+ grn_strncasecmp(encoding_name, "euc_jp", strlen("euc_jp")) == 0) {
encoding = GRN_ENC_EUC_JP;
- } else if (strncasecmp(encoding_name, "latin1", strlen("latin1")) == 0) {
+ } else if (grn_strncasecmp(encoding_name, "latin1", strlen("latin1")) == 0) {
encoding = GRN_ENC_LATIN1;
- } else if (strncasecmp(encoding_name, "KOI8-R", strlen("KOI8-R")) == 0 ||
- strncasecmp(encoding_name, "koi8r", strlen("koi8r")) == 0) {
+ } else if (grn_strncasecmp(encoding_name, "KOI8-R", strlen("KOI8-R")) == 0 ||
+ grn_strncasecmp(encoding_name, "koi8r", strlen("koi8r")) == 0) {
encoding = GRN_ENC_KOI8R;
}
} else {
@@ -118,7 +111,7 @@ detect_coding_part(grn_ctx *ctx, const char *line, size_t line_length)
return encoding;
}
-static inline grn_encoding
+static grn_encoding
guess_encoding(grn_ctx *ctx, const char **line, size_t *line_length)
{
const char bom[] = {0xef, 0xbb, 0xbf};
@@ -138,7 +131,7 @@ guess_encoding(grn_ctx *ctx, const char **line, size_t *line_length)
}
static void
-parse_synonyms_file_line(grn_ctx *ctx, const char *line, int line_length,
+parse_synonyms_file_line(grn_ctx *ctx, const char *line, size_t line_length,
grn_obj *key, grn_obj *value)
{
size_t i = 0;
@@ -201,7 +194,7 @@ load_synonyms(grn_ctx *ctx)
{
static char path_env[GRN_ENV_BUFFER_SIZE];
const char *path;
- FILE *file;
+ grn_file_reader *file_reader;
int number_of_lines;
grn_encoding encoding;
grn_obj line, key, value;
@@ -214,8 +207,8 @@ load_synonyms(grn_ctx *ctx)
} else {
path = get_system_synonyms_file();
}
- file = grn_fopen(path, "r");
- if (!file) {
+ file_reader = grn_file_reader_open(ctx, path);
+ if (!file_reader) {
GRN_LOG(ctx, GRN_LOG_WARNING,
"[plugin][query-expander][tsv] "
"synonyms file doesn't exist: <%s>",
@@ -228,7 +221,7 @@ load_synonyms(grn_ctx *ctx)
GRN_TEXT_INIT(&value, 0);
grn_bulk_reserve(ctx, &value, MAX_SYNONYM_BYTES);
number_of_lines = 0;
- while (grn_text_fgets(ctx, &line, file) == GRN_SUCCESS) {
+ while (grn_file_reader_read_line(ctx, file_reader, &line) == GRN_SUCCESS) {
const char *line_value = GRN_TEXT_VALUE(&line);
size_t line_length = GRN_TEXT_LEN(&line);
@@ -252,7 +245,7 @@ load_synonyms(grn_ctx *ctx)
GRN_OBJ_FIN(ctx, &key);
GRN_OBJ_FIN(ctx, &value);
- fclose(file);
+ grn_file_reader_close(ctx, file_reader);
}
static grn_obj *
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt
index 63a79938552..7d34be18546 100644
--- a/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright(C) 2013 Brazil
+# Copyright(C) 2013-2016 Brazil
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,48 +13,12 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/../../lib
- ${MRUBY_INCLUDE_DIRS})
+if(NOT GRN_EMBED)
+ if(GRN_WITH_MRUBY)
+ set(GRN_RELATIVE_RUBY_PLUGINS_DIR "${GRN_RELATIVE_PLUGINS_DIR}/ruby")
-if(GRN_WITH_MRUBY)
- set(GRN_RELATIVE_RUBY_PLUGINS_DIR "${GRN_RELATIVE_PLUGINS_DIR}/ruby")
-
- read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/eval_sources.am RUBY_EVAL_SOURCES)
- set_source_files_properties(${RUBY_EVAL_SOURCES}
- PROPERTIES
- COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
- if(GRN_EMBED)
- add_library(ruby_eval STATIC ${RUBY_EVAL_SOURCES})
- set_target_properties(
- ruby_eval
- PROPERTIES
- POSITION_INDEPENDENT_CODE ON)
- else()
- add_library(ruby_eval MODULE ${RUBY_EVAL_SOURCES})
- set_target_properties(ruby_eval PROPERTIES
- PREFIX ""
- OUTPUT_NAME "eval")
- install(TARGETS ruby_eval DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}")
- endif()
- target_link_libraries(ruby_eval libgroonga)
-
- read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/load_sources.am RUBY_LOAD_SOURCES)
- set_source_files_properties(${RUBY_LOAD_SOURCES}
- PROPERTIES
- COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
- if(GRN_EMBED)
- add_library(ruby_load STATIC ${RUBY_LOAD_SOURCES})
- set_target_properties(
- ruby_load
- PROPERTIES
- POSITION_INDEPENDENT_CODE ON)
- else()
- add_library(ruby_load MODULE ${RUBY_LOAD_SOURCES})
- set_target_properties(ruby_load PROPERTIES
- PREFIX ""
- OUTPUT_NAME "load")
- install(TARGETS ruby_load DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}")
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am RUBY_SCRIPTS)
+ install(FILES ${RUBY_SCRIPTS}
+ DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}")
endif()
- target_link_libraries(ruby_load libgroonga)
endif()
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/Makefile.am b/storage/mroonga/vendor/groonga/plugins/ruby/Makefile.am
index 381fb47160b..a4949727d1a 100644
--- a/storage/mroonga/vendor/groonga/plugins/ruby/Makefile.am
+++ b/storage/mroonga/vendor/groonga/plugins/ruby/Makefile.am
@@ -1,29 +1,9 @@
EXTRA_DIST = \
CMakeLists.txt
-AM_CFLAGS = \
- $(MESSAGE_PACK_CFLAGS) \
- $(MRUBY_CFLAGS)
-
-AM_CPPFLAGS = \
- -I$(top_builddir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/lib
-
-AM_LDFLAGS = \
- -avoid-version \
- -module \
- -no-undefined
-
-LIBS = \
- $(top_builddir)/lib/libgroonga.la \
- $(MESSAGE_PACK_LIBS)
-
if WITH_MRUBY
-ruby_plugins_LTLIBRARIES = \
- eval.la \
- load.la
+dist_ruby_plugins_DATA = \
+ $(ruby_scripts)
endif
-include eval_sources.am
-include load_sources.am
+include sources.am
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/eval.c b/storage/mroonga/vendor/groonga/plugins/ruby/eval.c
deleted file mode 100644
index bacd9011c12..00000000000
--- a/storage/mroonga/vendor/groonga/plugins/ruby/eval.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/*
- Copyright(C) 2013 Brazil
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License version 2.1 as published by the Free Software Foundation.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifdef GRN_EMBEDDED
-# define GRN_PLUGIN_FUNCTION_TAG ruby_eval
-#endif
-
-#include "ruby_plugin.h"
-
-static grn_obj *
-command_ruby_eval(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- mrb_state *mrb = ctx->impl->mrb.state;
- grn_obj *script;
- mrb_value result;
-
- script = VAR(0);
- switch (script->header.domain) {
- case GRN_DB_SHORT_TEXT :
- case GRN_DB_TEXT :
- case GRN_DB_LONG_TEXT :
- break;
- default :
- {
- grn_obj inspected;
- GRN_TEXT_INIT(&inspected, 0);
- grn_inspect(ctx, &inspected, script);
- ERR(GRN_INVALID_ARGUMENT, "script must be a string: <%.*s>",
- (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected));
- GRN_OBJ_FIN(ctx, &inspected);
- return NULL;
- }
- break;
- }
-
- mrb->exc = NULL;
- result = grn_mrb_eval(ctx, GRN_TEXT_VALUE(script), GRN_TEXT_LEN(script));
- output_result(ctx, result);
-
- return NULL;
-}
-
-grn_rc
-GRN_PLUGIN_REGISTER(grn_ctx *ctx)
-{
- grn_expr_var vars[1];
-
- grn_plugin_expr_var_init(ctx, &vars[0], "script", -1);
- grn_plugin_command_create(ctx, "ruby_eval", -1, command_ruby_eval, 1, vars);
-
- return ctx->rc;
-}
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/eval.rb b/storage/mroonga/vendor/groonga/plugins/ruby/eval.rb
new file mode 100644
index 00000000000..e7619cf2a9f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/ruby/eval.rb
@@ -0,0 +1,36 @@
+module Groonga
+ module Ruby
+ class EvalCommand < Command
+ register("ruby_eval",
+ [
+ "script",
+ ])
+
+ def run_body(input)
+ script = input[:script]
+ unless script.is_a?(String)
+ message = "script must be a string: <#{script.inspect}>"
+ raise Groonga::InvalidArgument, message
+ end
+
+ eval_context = EvalContext.new
+ begin
+ result = eval_context.eval(script)
+ rescue Exception => error
+ writer.map("result", 1) do
+ writer.write("exception")
+ writer.map("exception", 1) do
+ writer.write("message")
+ writer.write(error.message)
+ end
+ end
+ else
+ writer.map("result", 1) do
+ writer.write("value")
+ writer.write(result)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/eval_sources.am b/storage/mroonga/vendor/groonga/plugins/ruby/eval_sources.am
deleted file mode 100644
index 08543e43fb4..00000000000
--- a/storage/mroonga/vendor/groonga/plugins/ruby/eval_sources.am
+++ /dev/null
@@ -1,3 +0,0 @@
-eval_la_SOURCES = \
- ruby_plugin.h \
- eval.c
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/load.c b/storage/mroonga/vendor/groonga/plugins/ruby/load.c
deleted file mode 100644
index 447882319a5..00000000000
--- a/storage/mroonga/vendor/groonga/plugins/ruby/load.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/*
- Copyright(C) 2013 Brazil
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License version 2.1 as published by the Free Software Foundation.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifdef GRN_EMBEDDED
-# define GRN_PLUGIN_FUNCTION_TAG ruby_load
-#endif
-
-#include "ruby_plugin.h"
-
-static grn_obj *
-command_ruby_load(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- grn_obj *path;
- mrb_value result;
-
- path = VAR(0);
- switch (path->header.domain) {
- case GRN_DB_SHORT_TEXT :
- case GRN_DB_TEXT :
- case GRN_DB_LONG_TEXT :
- break;
- default :
- {
- grn_obj inspected;
- GRN_TEXT_INIT(&inspected, 0);
- grn_inspect(ctx, &inspected, path);
- ERR(GRN_INVALID_ARGUMENT, "path must be a string: <%.*s>",
- (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected));
- GRN_OBJ_FIN(ctx, &inspected);
- return NULL;
- }
- break;
- }
-
- GRN_TEXT_PUTC(ctx, path, '\0');
- result = grn_mrb_load(ctx, GRN_TEXT_VALUE(path));
- output_result(ctx, result);
-
- return NULL;
-}
-
-grn_rc
-GRN_PLUGIN_REGISTER(grn_ctx *ctx)
-{
- grn_expr_var vars[1];
-
- grn_plugin_expr_var_init(ctx, &vars[0], "path", -1);
- grn_plugin_command_create(ctx, "ruby_load", -1, command_ruby_load, 1, vars);
-
- return ctx->rc;
-}
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/load_sources.am b/storage/mroonga/vendor/groonga/plugins/ruby/load_sources.am
deleted file mode 100644
index d1cce258caa..00000000000
--- a/storage/mroonga/vendor/groonga/plugins/ruby/load_sources.am
+++ /dev/null
@@ -1,3 +0,0 @@
-load_la_SOURCES = \
- ruby_plugin.h \
- load.c
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/ruby_plugin.h b/storage/mroonga/vendor/groonga/plugins/ruby/ruby_plugin.h
deleted file mode 100644
index 57cab2885b1..00000000000
--- a/storage/mroonga/vendor/groonga/plugins/ruby/ruby_plugin.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/*
- Copyright(C) 2013 Brazil
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License version 2.1 as published by the Free Software Foundation.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include <grn_mrb.h>
-#include <grn_output.h>
-#include <grn_db.h>
-#include <grn_ctx_impl.h>
-#include <grn_util.h>
-
-#include <groonga/plugin.h>
-
-#include <mruby.h>
-
-#define VAR GRN_PROC_GET_VAR_BY_OFFSET
-
-static void
-output_result(grn_ctx *ctx, mrb_value result)
-{
- mrb_state *mrb = ctx->impl->mrb.state;
-
- GRN_OUTPUT_MAP_OPEN("result", 1);
- if (mrb->exc) {
- mrb_value mrb_message;
- grn_obj grn_message;
- GRN_OUTPUT_CSTR("exception");
- GRN_OUTPUT_MAP_OPEN("exception", 1);
- GRN_OUTPUT_CSTR("message");
- mrb_message = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "message", 0);
- GRN_VOID_INIT(&grn_message);
- if (grn_mrb_to_grn(ctx, mrb_message, &grn_message) == GRN_SUCCESS) {
- GRN_OUTPUT_OBJ(&grn_message, NULL);
- } else {
- GRN_OUTPUT_CSTR("unsupported message type");
- }
- grn_obj_unlink(ctx, &grn_message);
- GRN_OUTPUT_MAP_CLOSE();
- } else {
- grn_obj grn_result;
- GRN_OUTPUT_CSTR("value");
- GRN_VOID_INIT(&grn_result);
- if (grn_mrb_to_grn(ctx, result, &grn_result) == GRN_SUCCESS) {
- GRN_OUTPUT_OBJ(&grn_result, NULL);
- } else {
- GRN_OUTPUT_CSTR("unsupported return value");
- }
- grn_obj_unlink(ctx, &grn_result);
- }
- GRN_OUTPUT_MAP_CLOSE();
-}
-
-grn_rc
-GRN_PLUGIN_INIT(grn_ctx *ctx)
-{
- return GRN_SUCCESS;
-}
-
-grn_rc
-GRN_PLUGIN_FIN(grn_ctx *ctx)
-{
- return GRN_SUCCESS;
-}
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/sources.am b/storage/mroonga/vendor/groonga/plugins/ruby/sources.am
new file mode 100644
index 00000000000..f8938291af8
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/ruby/sources.am
@@ -0,0 +1,2 @@
+ruby_scripts = \
+ eval.rb
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding.rb b/storage/mroonga/vendor/groonga/plugins/sharding.rb
index 4ebc9baf438..86401c1fa4d 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding.rb
+++ b/storage/mroonga/vendor/groonga/plugins/sharding.rb
@@ -1,6 +1,11 @@
+require "sharding/parameters"
require "sharding/range_expression_builder"
require "sharding/logical_enumerator"
+
+require "sharding/logical_parameters"
+
require "sharding/logical_count"
require "sharding/logical_range_filter"
require "sharding/logical_select"
+require "sharding/logical_shard_list"
require "sharding/logical_table_remove"
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_count.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_count.rb
index 610dae834d3..8bdd77ef79f 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding/logical_count.rb
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_count.rb
@@ -17,25 +17,59 @@ module Groonga
filter = input[:filter]
total = 0
- enumerator.each do |table, shard_key, shard_range|
- total += count_n_records(table, filter,
- shard_key, shard_range,
+ enumerator.each do |shard, shard_range|
+ total += count_n_records(filter, shard, shard_range,
enumerator.target_range)
end
writer.write(total)
end
private
- def count_n_records(table, filter,
- shard_key, shard_range,
- target_range)
+ def cache_key(input)
+ key = "logical_count\0"
+ key << "#{input[:logical_table]}\0"
+ key << "#{input[:shard_key]}\0"
+ key << "#{input[:min]}\0"
+ key << "#{input[:min_border]}\0"
+ key << "#{input[:max]}\0"
+ key << "#{input[:max_border]}\0"
+ key << "#{input[:filter]}\0"
+ key
+ end
+
+ def log_use_range_index(use, table_name, line, method)
+ message = "[logical_count]"
+ if use
+ message << "[range-index]"
+ else
+ message << "[select]"
+ end
+ message << " <#{table_name}>"
+ Context.instance.logger.log(Logger::Level::DEBUG,
+ __FILE__,
+ line,
+ method.to_s,
+ message)
+ end
+
+ def count_n_records(filter, shard, shard_range, target_range)
cover_type = target_range.cover_type(shard_range)
return 0 if cover_type == :none
+ shard_key = shard.key
+ if shard_key.nil?
+ message = "[logical_count] shard_key doesn't exist: " +
+ "<#{shard.key_name}>"
+ raise InvalidArgument, message
+ end
+ table = shard.table
+ table_name = shard.table_name
+
expression_builder = RangeExpressionBuilder.new(shard_key,
- target_range,
- filter)
+ target_range)
+ expression_builder.filter = filter
if cover_type == :all
+ log_use_range_index(false, table_name, __LINE__, __method__)
if filter.nil?
return table.size
else
@@ -53,6 +87,9 @@ module Groonga
end
end
+ use_range_index = (!range_index.nil?)
+ log_use_range_index(use_range_index, table_name, __LINE__, __method__)
+
case cover_type
when :partial_min
if range_index
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb
index 35934182591..d05a220fc23 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb
@@ -1,12 +1,15 @@
module Groonga
module Sharding
class LogicalEnumerator
+ include Enumerable
+
attr_reader :target_range
attr_reader :logical_table
attr_reader :shard_key_name
- def initialize(command_name, input)
+ def initialize(command_name, input, options={})
@command_name = command_name
@input = input
+ @options = options
initialize_parameters
end
@@ -22,7 +25,6 @@ module Groonga
def each_internal(order)
context = Context.instance
each_shard_with_around(order) do |prev_shard, current_shard, next_shard|
- table = current_shard.table
shard_range_data = current_shard.range_data
shard_range = nil
@@ -52,16 +54,7 @@ module Groonga
shard_range_data.day)
end
- physical_shard_key_name = "#{table.name}.#{@shard_key_name}"
- shard_key = context[physical_shard_key_name]
- if shard_key.nil?
- message =
- "[#{@command_name}] shard_key doesn't exist: " +
- "<#{physical_shard_key_name}>"
- raise InvalidArgument, message
- end
-
- yield(table, shard_key, shard_range)
+ yield(current_shard, shard_range)
end
end
@@ -70,10 +63,10 @@ module Groonga
prefix = "#{@logical_table}_"
shards = [nil]
- context.database.each_table(:prefix => prefix,
- :order_by => :key,
- :order => order) do |table|
- shard_range_raw = table.name[prefix.size..-1]
+ context.database.each_name(:prefix => prefix,
+ :order_by => :key,
+ :order => order) do |name|
+ shard_range_raw = name[prefix.size..-1]
case shard_range_raw
when /\A(\d{4})(\d{2})\z/
@@ -84,7 +77,7 @@ module Groonga
next
end
- shards << Shard.new(table, shard_range_data)
+ shards << Shard.new(name, @shard_key_name, shard_range_data)
next if shards.size < 3
yield(*shards)
shards.shift
@@ -104,7 +97,11 @@ module Groonga
@shard_key_name = @input[:shard_key]
if @shard_key_name.nil?
- raise InvalidArgument, "[#{@command_name}] shard_key is missing"
+ require_shard_key = @options[:require_shard_key]
+ require_shard_key = true if require_shard_key.nil?
+ if require_shard_key
+ raise InvalidArgument, "[#{@command_name}] shard_key is missing"
+ end
end
@target_range = TargetRange.new(@command_name, @input)
@@ -119,11 +116,24 @@ module Groonga
end
class Shard
- attr_reader :table, :range_data
- def initialize(table, range_data)
- @table = table
+ attr_reader :table_name, :key_name, :range_data
+ def initialize(table_name, key_name, range_data)
+ @table_name = table_name
+ @key_name = key_name
@range_data = range_data
end
+
+ def table
+ @table ||= Context.instance[@table_name]
+ end
+
+ def full_key_name
+ "#{@table_name}.#{@key_name}"
+ end
+
+ def key
+ @key ||= Context.instance[full_key_name]
+ end
end
class ShardRangeData
@@ -133,6 +143,14 @@ module Groonga
@month = month
@day = day
end
+
+ def to_suffix
+ if @day.nil?
+ "_%04d%02d" % [@year, @month]
+ else
+ "_%04d%02d%02d" % [@year, @month, @day]
+ end
+ end
end
class DayShardRange
@@ -144,7 +162,11 @@ module Groonga
end
def least_over_time
- Time.local(@year, @month, @day + 1)
+ next_day = Time.local(@year, @month, @day) + (60 * 60 * 24)
+ while next_day.day == @day # For leap second
+ next_day += 1
+ end
+ next_day
end
def min_time
@@ -168,9 +190,13 @@ module Groonga
def least_over_time
if @max_day.nil?
- Time.local(@year, @month + 1, 1)
+ if @month == 12
+ Time.local(@year + 1, 1, 1)
+ else
+ Time.local(@year, @month + 1, 1)
+ end
else
- Time.local(@year, @month, @max_day + 1)
+ Time.local(@year, @month, @max_day)
end
end
@@ -270,10 +296,7 @@ module Groonga
return true if @min_border == :exclude
- not (@min.hour == 0 and
- @min.min == 0 and
- @min.sec == 0 and
- @min.usec == 0)
+ shard_range.min_time != @min
end
def in_max?(shard_range)
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_parameters.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_parameters.rb
new file mode 100644
index 00000000000..75ff569bf7c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_parameters.rb
@@ -0,0 +1,44 @@
+module Groonga
+ module Sharding
+ class LogicalParametersCommand < Command
+ register("logical_parameters",
+ [
+ "range_index",
+ ])
+
+ def run_body(input)
+ range_index = parse_range_index(input[:range_index])
+
+ parameters = [
+ :range_index,
+ ]
+ writer.map("parameters", parameters.size) do
+ parameters.each do |name|
+ writer.write(name.to_s)
+ writer.write(Parameters.__send__(name))
+ end
+ end
+
+ Parameters.range_index = range_index if range_index
+ end
+
+ private
+ def parse_range_index(value)
+ case value
+ when nil
+ nil
+ when "auto"
+ :auto
+ when "always"
+ :always
+ when "never"
+ :never
+ else
+ message = "[logical_parameters][range_index] "
+ message << "must be auto, always or never: <#{value}>"
+ raise InvalidArgument, message
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_range_filter.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_range_filter.rb
index 94ae8600d2b..1c8f8644695 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding/logical_range_filter.rb
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_range_filter.rb
@@ -14,6 +14,7 @@ module Groonga
"offset",
"limit",
"output_columns",
+ "use_range_index",
])
def run_body(input)
@@ -55,7 +56,26 @@ module Groonga
end
end
+ private
+ def cache_key(input)
+ key = "logical_range_filter\0"
+ key << "#{input[:logical_table]}\0"
+ key << "#{input[:shard_key]}\0"
+ key << "#{input[:min]}\0"
+ key << "#{input[:min_border]}\0"
+ key << "#{input[:max]}\0"
+ key << "#{input[:max_border]}\0"
+ key << "#{input[:order]}\0"
+ key << "#{input[:filter]}\0"
+ key << "#{input[:offset]}\0"
+ key << "#{input[:limit]}\0"
+ key << "#{input[:output_columns]}\0"
+ key << "#{input[:use_range_index]}\0"
+ key
+ end
+
class ExecuteContext
+ attr_reader :use_range_index
attr_reader :enumerator
attr_reader :order
attr_reader :filter
@@ -68,6 +88,7 @@ module Groonga
attr_reader :threshold
def initialize(input)
@input = input
+ @use_range_index = parse_use_range_index(@input[:use_range_index])
@enumerator = LogicalEnumerator.new("logical_range_filter", @input)
@order = parse_order(@input, :order)
@filter = @input[:filter]
@@ -93,6 +114,17 @@ module Groonga
end
private
+ def parse_use_range_index(use_range_index)
+ case use_range_index
+ when "yes"
+ true
+ when "no"
+ false
+ else
+ nil
+ end
+ end
+
def parse_order(input, name)
order = input[name]
return :ascending if order.nil?
@@ -123,23 +155,21 @@ module Groonga
end
def execute
- first_table = nil
+ first_shard = nil
enumerator = @context.enumerator
+ target_range = enumerator.target_range
if @context.order == :descending
each_method = :reverse_each
else
each_method = :each
end
- enumerator.send(each_method) do |table, shard_key, shard_range|
- first_table ||= table
- next if table.empty?
-
- shard_executor = ShardExecutor.new(@context,
- table, shard_key, shard_range)
+ enumerator.send(each_method) do |shard, shard_range|
+ first_shard ||= shard
+ shard_executor = ShardExecutor.new(@context, shard, shard_range)
shard_executor.execute
break if @context.current_limit == 0
end
- if first_table.nil?
+ if first_shard.nil?
message =
"[logical_range_filter] no shard exists: " +
"logical_table: <#{enumerator.logical_table}>: " +
@@ -148,17 +178,16 @@ module Groonga
end
if @context.result_sets.empty?
result_set = HashTable.create(:flags => ObjectFlags::WITH_SUBREC,
- :key_type => first_table)
+ :key_type => first_shard.table)
@context.result_sets << result_set
end
end
end
class ShardExecutor
- def initialize(context, table, shard_key, shard_range)
+ def initialize(context, shard, shard_range)
@context = context
- @table = table
- @shard_key = shard_key
+ @shard = shard
@shard_range = shard_range
@filter = @context.filter
@@ -168,137 +197,279 @@ module Groonga
@target_range = @context.enumerator.target_range
@cover_type = @target_range.cover_type(@shard_range)
-
- @expression_builder = RangeExpressionBuilder.new(@shard_key,
- @target_range,
- @filter)
end
def execute
return if @cover_type == :none
+ return if @shard.table.empty?
+
+ shard_key = @shard.key
+ if shard_key.nil?
+ message = "[logical_range_filter] shard_key doesn't exist: " +
+ "<#{@shard.key_name}>"
+ raise InvalidArgument, message
+ end
+
+ expression_builder = RangeExpressionBuilder.new(shard_key,
+ @target_range)
+ expression_builder.filter = @filter
- index_info = @shard_key.find_index(Operator::LESS)
+ index_info = shard_key.find_index(Operator::LESS)
if index_info
range_index = index_info.index
- range_index = nil unless use_range_index?(range_index)
+ unless use_range_index?(range_index, expression_builder)
+ range_index = nil
+ end
else
range_index = nil
end
- case @cover_type
- when :all
- filter_shard_all(range_index)
- when :partial_min
- if range_index
- filter_by_range(range_index,
- @target_range.min, @target_range.min_border,
- nil, nil)
- else
- filter_table do |expression|
- @expression_builder.build_partial_min(expression)
- end
- end
- when :partial_max
- if range_index
- filter_by_range(range_index,
- nil, nil,
- @target_range.max, @target_range.max_border)
- else
- filter_table do |expression|
- @expression_builder.build_partial_max(expression)
- end
- end
- when :partial_min_and_max
- if range_index
- filter_by_range(range_index,
- @target_range.min, @target_range.min_border,
- @target_range.max, @target_range.max_border)
- else
- filter_table do |expression|
- @expression_builder.build_partial_min_and_max(expression)
- end
- end
- end
+ execute_filter(range_index, expression_builder)
end
private
- def use_range_index?(range_index)
+ def decide_use_range_index(use, reason, line, method)
+ message = "[logical_range_filter]"
+ if use
+ message << "[range-index] "
+ else
+ message << "[select] "
+ end
+ message << "<#{@shard.table_name}>: "
+ message << reason
+ Context.instance.logger.log(Logger::Level::DEBUG,
+ __FILE__,
+ line,
+ method.to_s,
+ message)
+
+ use
+ end
+
+ def use_range_index?(range_index, expression_builder)
+ use_range_index_parameter_message =
+ "force by use_range_index parameter"
+ case @context.use_range_index
+ when true
+ return decide_use_range_index(true,
+ use_range_index_parameter_message,
+ __LINE__, __method__)
+ when false
+ return decide_use_range_index(false,
+ use_range_index_parameter_message,
+ __LINE__, __method__)
+ end
+
+ range_index_logical_parameter_message =
+ "force by range_index logical parameter"
+ case Parameters.range_index
+ when :always
+ return decide_use_range_index(true,
+ range_index_logical_parameter_message,
+ __LINE__, __method__)
+ when :never
+ return decide_use_range_index(false,
+ range_index_logical_parameter_message,
+ __LINE__, __method__)
+ end
+
current_limit = @context.current_limit
if current_limit < 0
- return false
+ reason = "limit is negative: <#{current_limit}>"
+ return decide_use_range_index(false, reason,
+ __LINE__, __method__)
end
required_n_records = @context.current_offset + current_limit
- max_n_records = @table.size
+ max_n_records = @shard.table.size
if max_n_records <= required_n_records
- return false
+ reason = "the number of required records (#{required_n_records}) "
+ reason << ">= "
+ reason << "the number of records in shard (#{max_n_records})"
+ return decide_use_range_index(false, reason,
+ __LINE__, __method__)
end
threshold = @context.threshold
if threshold <= 0.0
- return true
+ reason = "threshold is negative: <#{threshold}>"
+ return decide_use_range_index(true, reason,
+ __LINE__, __method__)
end
if threshold >= 1.0
- return false
+ reason = "threshold (#{threshold}) >= 1.0"
+ return decide_use_range_index(false, reason,
+ __LINE__, __method__)
end
+ table = @shard.table
estimated_n_records = 0
case @cover_type
when :all
if @filter
- create_expression(@table) do |expression|
- @expression_builder.build_all(expression)
- estimated_n_records = expression.estimate_size(@table)
+ create_expression(table) do |expression|
+ expression_builder.build_all(expression)
+ unless range_index_available_expression?(expression,
+ __LINE__, __method__)
+ return false
+ end
+ estimated_n_records = expression.estimate_size(table)
end
else
estimated_n_records = max_n_records
end
when :partial_min
- create_expression(@table) do |expression|
- @expression_builder.build_partial_min(expression)
- estimated_n_records = expression.estimate_size(@table)
+ create_expression(table) do |expression|
+ expression_builder.build_partial_min(expression)
+ unless range_index_available_expression?(expression,
+ __LINE__, __method__)
+ return false
+ end
+ estimated_n_records = expression.estimate_size(table)
end
when :partial_max
- create_expression(@table) do |expression|
- @expression_builder.build_partial_max(expression)
- estimated_n_records = expression.estimate_size(@table)
+ create_expression(table) do |expression|
+ expression_builder.build_partial_max(expression)
+ unless range_index_available_expression?(expression,
+ __LINE__, __method__)
+ return false
+ end
+ estimated_n_records = expression.estimate_size(table)
end
when :partial_min_and_max
- create_expression(@table) do |expression|
- @expression_builder.build_partial_min_and_max(expression)
- estimated_n_records = expression.estimate_size(@table)
+ create_expression(table) do |expression|
+ expression_builder.build_partial_min_and_max(expression)
+ unless range_index_available_expression?(expression,
+ __LINE__, __method__)
+ return false
+ end
+ estimated_n_records = expression.estimate_size(table)
end
end
if estimated_n_records <= required_n_records
- return false
+ reason = "the number of required records (#{required_n_records}) "
+ reason << ">= "
+ reason << "the number of estimated records (#{estimated_n_records})"
+ return decide_use_range_index(false, reason,
+ __LINE__, __method__)
end
hit_ratio = estimated_n_records / max_n_records.to_f
- hit_ratio >= threshold
+ use_range_index_by_hit_ratio = (hit_ratio >= threshold)
+ if use_range_index_by_hit_ratio
+ relation = ">="
+ else
+ relation = "<"
+ end
+ reason = "hit ratio "
+ reason << "(#{hit_ratio}=#{estimated_n_records}/#{max_n_records}) "
+ reason << "#{relation} threshold (#{threshold})"
+ decide_use_range_index(use_range_index_by_hit_ratio, reason,
+ __LINE__, __method__)
+ end
+
+ def range_index_available_expression?(expression, line, method_name)
+ nested_reference_vector_column_accessor =
+ find_nested_reference_vector_column_accessor(expression)
+ if nested_reference_vector_column_accessor
+ reason = "nested reference vector column accessor can't be used: "
+ reason << "<#{nested_reference_vector_column_accessor.name}>"
+ return decide_use_range_index(false, reason, line, method_name)
+ end
+
+ selector_only_procedure = find_selector_only_procedure(expression)
+ if selector_only_procedure
+ reason = "selector only procedure can't be used: "
+ reason << "<#{selector_only_procedure.name}>"
+ return decide_use_range_index(false, reason, line, method_name)
+ end
+
+ true
+ end
+
+ def find_nested_reference_vector_column_accessor(expression)
+ expression.codes.each do |code|
+ value = code.value
+ next unless value.is_a?(Accessor)
+
+ sub_accessor = value
+ while sub_accessor.have_next?
+ object = sub_accessor.object
+ return value if object.is_a?(Column) and object.vector?
+ sub_accessor = sub_accessor.next
+ end
+ end
+ nil
+ end
+
+ def find_selector_only_procedure(expression)
+ expression.codes.each do |code|
+ value = code.value
+ return value if value.is_a?(Procedure) and value.selector_only?
+ end
+ nil
+ end
+
+ def execute_filter(range_index, expression_builder)
+ case @cover_type
+ when :all
+ filter_shard_all(range_index, expression_builder)
+ when :partial_min
+ if range_index
+ filter_by_range(range_index, expression_builder,
+ @target_range.min, @target_range.min_border,
+ nil, nil)
+ else
+ filter_table do |expression|
+ expression_builder.build_partial_min(expression)
+ end
+ end
+ when :partial_max
+ if range_index
+ filter_by_range(range_index, expression_builder,
+ nil, nil,
+ @target_range.max, @target_range.max_border)
+ else
+ filter_table do |expression|
+ expression_builder.build_partial_max(expression)
+ end
+ end
+ when :partial_min_and_max
+ if range_index
+ filter_by_range(range_index, expression_builder,
+ @target_range.min, @target_range.min_border,
+ @target_range.max, @target_range.max_border)
+ else
+ filter_table do |expression|
+ expression_builder.build_partial_min_and_max(expression)
+ end
+ end
+ end
end
- def filter_shard_all(range_index)
+ def filter_shard_all(range_index, expression_builder)
+ table = @shard.table
if @filter.nil?
- if @table.size <= @context.current_offset
- @context.current_offset -= @table.size
+ if table.size <= @context.current_offset
+ @context.current_offset -= table.size
return
end
if range_index
- filter_by_range(range_index,
+ filter_by_range(range_index, expression_builder,
nil, nil,
nil, nil)
else
- sort_result_set(@table)
+ sort_result_set(table)
end
else
if range_index
- filter_by_range(range_index,
+ filter_by_range(range_index, expression_builder,
nil, nil,
nil, nil)
else
filter_table do |expression|
- @expression_builder.build_all(expression)
+ expression_builder.build_all(expression)
end
end
end
@@ -313,7 +484,7 @@ module Groonga
end
end
- def filter_by_range(range_index,
+ def filter_by_range(range_index, expression_builder,
min, min_border, max, max_border)
lexicon = range_index.domain
data_table = range_index.range
@@ -336,6 +507,10 @@ module Groonga
else
options[:limit] = current_limit
end
+ max_n_unmatched_records =
+ compute_max_n_unmatched_records(data_table.size,
+ options[:limit])
+ options[:max_n_unmatched_records] = max_n_unmatched_records
if @filter
create_expression(data_table) do |expression|
expression.parse(@filter)
@@ -349,6 +524,17 @@ module Groonga
n_matched_records = index_cursor.select(result_set, options)
end
end
+ if n_matched_records == -1
+ result_set.close
+ fallback_message =
+ "fallback because there are too much unmatched records: "
+ fallback_message << "<#{max_n_unmatched_records}>"
+ decide_use_range_index(false,
+ fallback_message,
+ __LINE__, __method__)
+ execute_filter(nil, expression_builder)
+ return
+ end
end
rescue
result_set.close
@@ -393,10 +579,24 @@ module Groonga
flags
end
+ def compute_max_n_unmatched_records(data_table_size, limit)
+ max_n_unmatched_records = limit * 100
+ max_n_sample_records = data_table_size
+ if max_n_sample_records > 10000
+ sample_ratio = 1 / (Math.log(data_table_size) ** 2)
+ max_n_sample_records = (max_n_sample_records * sample_ratio).ceil
+ end
+ if max_n_unmatched_records > max_n_sample_records
+ max_n_unmatched_records = max_n_sample_records
+ end
+ max_n_unmatched_records
+ end
+
def filter_table
- create_expression(@table) do |expression|
+ table = @shard.table
+ create_expression(table) do |expression|
yield(expression)
- result_set = @table.select(expression)
+ result_set = table.select(expression)
sort_result_set(result_set)
end
end
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb
index da6dbe5ae91..07ebf9e8e0d 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb
@@ -10,32 +10,50 @@ module Groonga
"max",
"max_border",
"filter",
+ # Deprecated since 6.1.5. Use sort_keys instead.
"sortby",
"output_columns",
"offset",
"limit",
"drilldown",
+ # Deprecated since 6.1.5. Use drilldown_sort_keys instead.
"drilldown_sortby",
"drilldown_output_columns",
"drilldown_offset",
"drilldown_limit",
+ "drilldown_calc_types",
+ "drilldown_calc_target",
+ "sort_keys",
+ "drilldown_sort_keys",
+ "match_columns",
+ "query",
+ "drilldown_filter",
])
def run_body(input)
- enumerator = LogicalEnumerator.new("logical_select", input)
-
context = ExecuteContext.new(input)
begin
executor = Executor.new(context)
executor.execute
n_results = 1
- drilldowns = context.drilldown.result_sets
- n_results += drilldowns.size
+ n_plain_drilldowns = context.plain_drilldown.n_result_sets
+ n_labeled_drilldowns = context.labeled_drilldowns.n_result_sets
+ if n_plain_drilldowns > 0
+ n_results += n_plain_drilldowns
+ elsif
+ if n_labeled_drilldowns > 0
+ n_results += 1
+ end
+ end
writer.array("RESULT", n_results) do
write_records(writer, context)
- write_drilldowns(writer, context, drilldowns)
+ if n_plain_drilldowns > 0
+ write_plain_drilldowns(writer, context)
+ elsif n_labeled_drilldowns > 0
+ write_labeled_drilldowns(writer, context)
+ end
end
ensure
context.close
@@ -43,6 +61,68 @@ module Groonga
end
private
+ def cache_key(input)
+ sort_keys = input[:sort_keys] || input[:sortby]
+ drilldown_sort_keys =
+ input[:drilldown_sort_keys] || input[:drilldown_sortby]
+ key = "logical_select\0"
+ key << "#{input[:logical_table]}\0"
+ key << "#{input[:shard_key]}\0"
+ key << "#{input[:min]}\0"
+ key << "#{input[:min_border]}\0"
+ key << "#{input[:max]}\0"
+ key << "#{input[:max_border]}\0"
+ key << "#{input[:filter]}\0"
+ key << "#{sort_keys}\0"
+ key << "#{input[:output_columns]}\0"
+ key << "#{input[:offset]}\0"
+ key << "#{input[:limit]}\0"
+ key << "#{input[:drilldown]}\0"
+ key << "#{drilldown_sort_keys}\0"
+ key << "#{input[:match_columns]}\0"
+ key << "#{input[:query]}\0"
+ key << "#{input[:drilldown_output_columns]}\0"
+ key << "#{input[:drilldown_offset]}\0"
+ key << "#{input[:drilldown_limit]}\0"
+ key << "#{input[:drilldown_calc_types]}\0"
+ key << "#{input[:drilldown_calc_target]}\0"
+ key << "#{input[:drilldown_filter]}\0"
+ labeled_drilldowns = LabeledDrilldowns.parse(input).sort_by(&:label)
+ labeled_drilldowns.each do |drilldown|
+ key << "#{drilldown.label}\0"
+ key << "#{drilldown.keys.join(',')}\0"
+ key << "#{drilldown.output_columns}\0"
+ key << "#{drilldown.offset}\0"
+ key << "#{drilldown.limit}\0"
+ key << "#{drilldown.calc_types}\0"
+ key << "#{drilldown.calc_target_name}\0"
+ key << "#{drilldown.filter}\0"
+ cache_key_dynamic_columns(key, drilldown.dynamic_columns)
+ end
+ dynamic_columns = DynamicColumns.parse(input)
+ cache_key_dynamic_columns(key, dynamic_columns)
+ key
+ end
+
+ def cache_key_dynamic_columns(key, dynamic_columns)
+ [
+ :initial,
+ :filtered,
+ :output
+ ].each do |stage|
+ target_dynamic_columns = dynamic_columns.__send__("each_#{stage}").to_a
+ target_dynamic_columns.sort_by(&:label).each do |dynamic_column|
+ key << "#{dynamic_column.label}\0"
+ key << "#{dynamic_column.stage}\0"
+ key << "#{dynamic_column.type}\0"
+ key << "#{dynamic_column.flags}\0"
+ key << "#{dynamic_column.value}\0"
+ key << "#{dynamic_column.window_sort_keys.join(',')}\0"
+ key << "#{dynamic_column.window_group_keys.join(',')}\0"
+ end
+ end
+ end
+
def write_records(writer, context)
result_sets = context.result_sets
@@ -75,11 +155,11 @@ module Groonga
result_sets.each do |result_set|
if result_set.size > current_offset
writer.write_table_records(result_set, output_columns, options)
+ current_limit -= result_set.size
end
if current_offset > 0
current_offset = [current_offset - result_set.size, 0].max
end
- current_limit -= result_set.size
break if current_limit <= 0
options[:offset] = current_offset
options[:limit] = current_limit
@@ -87,12 +167,14 @@ module Groonga
end
end
- def write_drilldowns(writer, context, drilldowns)
- output_columns = context.drilldown.output_columns
+ def write_plain_drilldowns(writer, execute_context)
+ plain_drilldown = execute_context.plain_drilldown
+ drilldowns = plain_drilldown.result_sets
+ output_columns = plain_drilldown.output_columns
options = {
- :offset => context.drilldown.output_offset,
- :limit => context.drilldown.limit,
+ :offset => plain_drilldown.offset,
+ :limit => plain_drilldown.limit,
}
drilldowns.each do |drilldown|
@@ -109,6 +191,60 @@ module Groonga
end
end
+ def write_labeled_drilldowns(writer, execute_context)
+ labeled_drilldowns = execute_context.labeled_drilldowns
+ is_command_version1 = (context.command_version == 1)
+
+ writer.map("DRILLDOWNS", labeled_drilldowns.n_result_sets) do
+ labeled_drilldowns.each do |drilldown|
+ writer.write(drilldown.label)
+
+ result_set = drilldown.result_set
+ n_elements = 2 # for N hits and columns
+ n_elements += result_set.size
+ output_columns = drilldown.output_columns
+ options = {
+ :offset => drilldown.offset,
+ :limit => drilldown.limit,
+ }
+
+ writer.array("RESULTSET", n_elements) do
+ writer.array("NHITS", 1) do
+ writer.write(result_set.size)
+ end
+ writer.write_table_columns(result_set, output_columns)
+ if is_command_version1 and drilldown.need_command_version2?
+ context.with_command_version(2) do
+ writer.write_table_records(result_set,
+ drilldown.output_columns_v2,
+ options)
+ end
+ else
+ writer.write_table_records(result_set, output_columns, options)
+ end
+ end
+ end
+ end
+ end
+
+ class LabeledArgumentParser
+ def initialize(parameters)
+ @parameters = parameters
+ end
+
+ def parse(prefix_pattern)
+ pattern = /\A#{prefix_pattern}\[(.+?)\]\.(.+)\z/
+ labeled_arguments = {}
+ @parameters.each do |key, value|
+ match_data = pattern.match(key)
+ next if match_data.nil?
+ labeled_argument = (labeled_arguments[match_data[1]] ||= {})
+ labeled_argument[match_data[2]] = value
+ end
+ labeled_arguments
+ end
+ end
+
module KeysParsable
private
def parse_keys(raw_keys)
@@ -118,68 +254,273 @@ module Groonga
end
end
+ module Calculatable
+ def calc_target(table)
+ return nil if @calc_target_name.nil?
+ table.find_column(@calc_target_name)
+ end
+
+ private
+ def parse_calc_types(raw_types)
+ return TableGroupFlags::CALC_COUNT if raw_types.nil?
+
+ types = 0
+ raw_types.strip.split(/ *, */).each do |name|
+ case name
+ when "COUNT"
+ types |= TableGroupFlags::CALC_COUNT
+ when "MAX"
+ types |= TableGroupFlags::CALC_MAX
+ when "MIN"
+ types |= TableGroupFlags::CALC_MIN
+ when "SUM"
+ types |= TableGroupFlags::CALC_SUM
+ when "AVG"
+ types |= TableGroupFlags::CALC_AVG
+ when "NONE"
+ # Do nothing
+ else
+ raise InvalidArgument, "invalid drilldown calc type: <#{name}>"
+ end
+ end
+ types
+ end
+ end
+
class ExecuteContext
include KeysParsable
attr_reader :enumerator
+ attr_reader :match_columns
+ attr_reader :query
attr_reader :filter
attr_reader :offset
attr_reader :limit
attr_reader :sort_keys
attr_reader :output_columns
+ attr_reader :dynamic_columns
attr_reader :result_sets
- attr_reader :drilldown
+ attr_reader :unsorted_result_sets
+ attr_reader :plain_drilldown
+ attr_reader :labeled_drilldowns
+ attr_reader :temporary_tables
+ attr_reader :expressions
def initialize(input)
@input = input
@enumerator = LogicalEnumerator.new("logical_select", @input)
+ @match_columns = @input[:match_columns]
+ @query = @input[:query]
@filter = @input[:filter]
@offset = (@input[:offset] || 0).to_i
@limit = (@input[:limit] || 10).to_i
- @sort_keys = parse_keys(@input[:sortby])
- @output_columns = @input[:output_columns] || "_key, *"
+ @sort_keys = parse_keys(@input[:sort_keys] || @input[:sortby])
+ @output_columns = @input[:output_columns] || "_id, _key, *"
+
+ @dynamic_columns = DynamicColumns.parse(@input)
@result_sets = []
+ @unsorted_result_sets = []
+
+ @plain_drilldown = PlainDrilldownExecuteContext.new(@input)
+ @labeled_drilldowns = LabeledDrilldowns.parse(@input)
+
+ @temporary_tables = []
- @drilldown = DrilldownExecuteContext.new(@input)
+ @expressions = []
end
def close
@result_sets.each do |result_set|
result_set.close if result_set.temporary?
end
+ @unsorted_result_sets.each do |result_set|
+ result_set.close if result_set.temporary?
+ end
+
+ @plain_drilldown.close
+ @labeled_drilldowns.close
+
+ @dynamic_columns.close
+
+ @temporary_tables.each do |table|
+ table.close
+ end
- @drilldown.close
+ @expressions.each do |expression|
+ expression.close
+ end
end
end
- class DrilldownExecuteContext
+ class DynamicColumns
+ class << self
+ def parse(input)
+ parser = LabeledArgumentParser.new(input)
+ columns = parser.parse(/columns?/)
+
+ initial_contexts = []
+ filtered_contexts = []
+ output_contexts = []
+ columns.each do |label, parameters|
+ contexts = nil
+ case parameters["stage"]
+ when "initial"
+ contexts = initial_contexts
+ when "filtered"
+ contexts = filtered_contexts
+ when "output"
+ contexts = output_contexts
+ else
+ next
+ end
+ contexts << DynamicColumnExecuteContext.new(label, parameters)
+ end
+
+ new(initial_contexts,
+ filtered_contexts,
+ output_contexts)
+ end
+ end
+
+ def initialize(initial_contexts,
+ filtered_contexts,
+ output_contexts)
+ @initial_contexts = initial_contexts
+ @filtered_contexts = filtered_contexts
+ @output_contexts = output_contexts
+ end
+
+ def each_initial(&block)
+ @initial_contexts.each(&block)
+ end
+
+ def each_filtered(&block)
+ @filtered_contexts.each(&block)
+ end
+
+ def each_output(&block)
+ @output_contexts.each(&block)
+ end
+
+ def close
+ @initial_contexts.each do |context|
+ context.close
+ end
+ @filtered_contexts.each do |context|
+ context.close
+ end
+ @output_contexts.each do |context|
+ context.close
+ end
+ end
+ end
+
+ class DynamicColumnExecuteContext
include KeysParsable
+ attr_reader :label
+ attr_reader :stage
+ attr_reader :type
+ attr_reader :flags
+ attr_reader :value
+ attr_reader :window_sort_keys
+ attr_reader :window_group_keys
+ def initialize(label, parameters)
+ @label = label
+ @stage = parameters["stage"]
+ @type = parse_type(parameters["type"])
+ @flags = parse_flags(parameters["flags"] || "COLUMN_SCALAR")
+ @value = parameters["value"]
+ @window_sort_keys = parse_keys(parameters["window.sort_keys"])
+ @window_group_keys = parse_keys(parameters["window.group_keys"])
+ end
+
+ def close
+ end
+
+ def apply(table, condition=nil)
+ column = table.create_column(@label, @flags, @type)
+ return if table.empty?
+
+ expression = Expression.create(table)
+ begin
+ expression.parse(@value)
+ if @window_sort_keys.empty? and @window_group_keys.empty?
+ expression.condition = condition if condition
+ table.apply_expression(column, expression)
+ else
+ table.apply_window_function(column, expression,
+ :sort_keys => @window_sort_keys,
+ :group_keys => @window_group_keys)
+ end
+ ensure
+ expression.close
+ end
+ end
+
+ private
+ def parse_type(type_raw)
+ return nil if type_raw.nil?
+
+ type = Context.instance[type_raw]
+ if type.nil?
+ message = "#{error_message_tag} unknown type: <#{type_raw}>"
+ raise InvalidArgument, message
+ end
+
+ case type
+ when Type, Table
+ type
+ else
+ message = "#{error_message_tag} invalid type: #{type.grn_inspect}"
+ raise InvalidArgument, message
+ end
+ end
+
+ def parse_flags(flags_raw)
+ Column.parse_flags(error_message_tag, flags_raw)
+ end
+
+ def error_message_tag
+ "[logical_select][columns][#{@stage}][#{@label}]"
+ end
+ end
+
+ class PlainDrilldownExecuteContext
+ include KeysParsable
+ include Calculatable
+
attr_reader :keys
attr_reader :offset
attr_reader :limit
attr_reader :sort_keys
attr_reader :output_columns
- attr_reader :output_offset
+ attr_reader :calc_target_name
+ attr_reader :calc_types
+ attr_reader :filter
attr_reader :result_sets
attr_reader :unsorted_result_sets
+ attr_reader :temporary_tables
+ attr_reader :expressions
def initialize(input)
@input = input
@keys = parse_keys(@input[:drilldown])
@offset = (@input[:drilldown_offset] || 0).to_i
@limit = (@input[:drilldown_limit] || 10).to_i
- @sort_keys = parse_keys(@input[:drilldown_sortby])
+ @sort_keys = parse_keys(@input[:drilldown_sort_keys] ||
+ @input[:drilldown_sortby])
@output_columns = @input[:drilldown_output_columns]
@output_columns ||= "_key, _nsubrecs"
-
- if @sort_keys.empty?
- @output_offset = @offset
- else
- @output_offset = 0
- end
+ @calc_target_name = @input[:drilldown_calc_target]
+ @calc_types = parse_calc_types(@input[:drilldown_calc_types])
+ @filter = @input[:drilldown_filter]
@result_sets = []
@unsorted_result_sets = []
+
+ @temporary_tables = []
+
+ @expressions = []
end
def close
@@ -189,6 +530,170 @@ module Groonga
@unsorted_result_sets.each do |result_set|
result_set.close
end
+
+ @temporary_tables.each do |table|
+ table.close
+ end
+
+ @expressions.each do |expression|
+ expression.close
+ end
+ end
+
+ def have_keys?
+ @keys.size > 0
+ end
+
+ def n_result_sets
+ @result_sets.size
+ end
+ end
+
+ class LabeledDrilldowns
+ include Enumerable
+ include TSort
+
+ class << self
+ def parse(input)
+ parser = LabeledArgumentParser.new(input)
+ drilldowns = parser.parse(/drilldowns?/)
+
+ contexts = {}
+ drilldowns.each do |label, parameters|
+ next if parameters["keys"].nil?
+ context = LabeledDrilldownExecuteContext.new(label, parameters)
+ contexts[label] = context
+ end
+
+ new(contexts)
+ end
+ end
+
+ def initialize(contexts)
+ @contexts = contexts
+ @dependencies = {}
+ @contexts.each do |label, context|
+ if context.table
+ depended_context = @contexts[context.table]
+ if depended_context.nil?
+ raise "Unknown drilldown: <#{context.table}>"
+ end
+ @dependencies[label] = [depended_context]
+ else
+ @dependencies[label] = []
+ end
+ end
+ end
+
+ def close
+ @contexts.each_value do |context|
+ context.close
+ end
+ end
+
+ def [](label)
+ @contexts[label]
+ end
+
+ def have_keys?
+ not @contexts.empty?
+ end
+
+ def n_result_sets
+ @contexts.size
+ end
+
+ def each(&block)
+ @contexts.each_value(&block)
+ end
+
+ def tsort_each_node(&block)
+ @contexts.each_value(&block)
+ end
+
+ def tsort_each_child(context, &block)
+ @dependencies[context.label].each(&block)
+ end
+ end
+
+ class LabeledDrilldownExecuteContext
+ include KeysParsable
+ include Calculatable
+
+ attr_reader :label
+ attr_reader :keys
+ attr_reader :offset
+ attr_reader :limit
+ attr_reader :sort_keys
+ attr_reader :output_columns
+ attr_reader :calc_target_name
+ attr_reader :calc_types
+ attr_reader :filter
+ attr_reader :table
+ attr_reader :dynamic_columns
+ attr_accessor :result_set
+ attr_accessor :unsorted_result_set
+ attr_reader :temporary_tables
+ attr_reader :expressions
+ def initialize(label, parameters)
+ @label = label
+ @keys = parse_keys(parameters["keys"])
+ @offset = (parameters["offset"] || 0).to_i
+ @limit = (parameters["limit"] || 10).to_i
+ @sort_keys = parse_keys(parameters["sort_keys"] ||
+ parameters["sortby"])
+ @output_columns = parameters["output_columns"]
+ @output_columns ||= "_key, _nsubrecs"
+ @calc_target_name = parameters["calc_target"]
+ @calc_types = parse_calc_types(parameters["calc_types"])
+ @filter = parameters["filter"]
+ @table = parameters["table"]
+
+ @dynamic_columns = DynamicColumns.parse(parameters)
+
+ @result_set = nil
+ @unsorted_result_set = nil
+
+ @temporary_tables = []
+
+ @expressions = []
+ end
+
+ def close
+ @result_set.close if @result_set
+ @unsorted_result_set.close if @unsorted_result_set
+
+ @dynamic_columns.close
+
+ @temporary_tables.each do |table|
+ table.close
+ end
+
+ @expressions.each do |expression|
+ expression.close
+ end
+ end
+
+ def need_command_version2?
+ /[.\[]/ === @output_columns
+ end
+
+ def output_columns_v2
+ columns = @output_columns.strip.split(/ *, */)
+ converted_columns = columns.collect do |column|
+ match_data = /\A_value\.(.+)\z/.match(column)
+ if match_data.nil?
+ column
+ else
+ nth_key = keys.index(match_data[1])
+ if nth_key
+ "_key[#{nth_key}]"
+ else
+ column
+ end
+ end
+ end
+ converted_columns.join(",")
end
end
@@ -199,22 +704,23 @@ module Groonga
def execute
execute_search
- execute_drilldown
+ if @context.plain_drilldown.have_keys?
+ execute_plain_drilldown
+ elsif @context.labeled_drilldowns.have_keys?
+ execute_labeled_drilldowns
+ end
end
private
def execute_search
- first_table = nil
+ first_shard = nil
enumerator = @context.enumerator
- enumerator.each do |table, shard_key, shard_range|
- first_table ||= table
- next if table.empty?
-
- shard_executor = ShardExecutor.new(@context,
- table, shard_key, shard_range)
+ enumerator.each do |shard, shard_range|
+ first_shard ||= shard
+ shard_executor = ShardExecutor.new(@context, shard, shard_range)
shard_executor.execute
end
- if first_table.nil?
+ if first_shard.nil?
message =
"[logical_select] no shard exists: " +
"logical_table: <#{enumerator.logical_table}>: " +
@@ -223,33 +729,38 @@ module Groonga
end
if @context.result_sets.empty?
result_set = HashTable.create(:flags => ObjectFlags::WITH_SUBREC,
- :key_type => first_table)
+ :key_type => first_shard.table)
+ @context.dynamic_columns.each_initial do |dynamic_column|
+ dynamic_column.apply(result_set)
+ end
+ @context.dynamic_columns.each_filtered do |dynamic_column|
+ dynamic_column.apply(result_set)
+ end
@context.result_sets << result_set
end
end
- def execute_drilldown
- drilldown = @context.drilldown
+ def execute_plain_drilldown
+ drilldown = @context.plain_drilldown
group_result = TableGroupResult.new
- sort_options = {
- :offset => drilldown.offset,
- :limit => drilldown.limit,
- }
begin
group_result.key_begin = 0
group_result.key_end = 0
group_result.limit = 1
- group_result.flags = TableGroupFlags::CALC_COUNT
+ group_result.flags = drilldown.calc_types
drilldown.keys.each do |key|
@context.result_sets.each do |result_set|
- result_set.group([key], group_result)
+ with_calc_target(group_result,
+ drilldown.calc_target(result_set)) do
+ result_set.group([key], group_result)
+ end
end
result_set = group_result.table
+ result_set = apply_drilldown_filter(drilldown, result_set)
if drilldown.sort_keys.empty?
drilldown.result_sets << result_set
else
- drilldown.result_sets << result_set.sort(drilldown.sort_keys,
- sort_options)
+ drilldown.result_sets << result_set.sort(drilldown.sort_keys)
drilldown.unsorted_result_sets << result_set
end
group_result.table = nil
@@ -258,72 +769,204 @@ module Groonga
group_result.close
end
end
+
+ def execute_labeled_drilldowns
+ drilldowns = @context.labeled_drilldowns
+
+ drilldowns.tsort_each do |drilldown|
+ group_result = TableGroupResult.new
+ keys = drilldown.keys
+ begin
+ group_result.key_begin = 0
+ group_result.key_end = keys.size - 1
+ if keys.size > 1
+ group_result.max_n_sub_records = 1
+ end
+ group_result.limit = 1
+ group_result.flags = drilldown.calc_types
+ if drilldown.table
+ target_table = drilldowns[drilldown.table].result_set
+ with_calc_target(group_result,
+ drilldown.calc_target(target_table)) do
+ target_table.group(keys, group_result)
+ end
+ else
+ @context.result_sets.each do |result_set|
+ with_calc_target(group_result,
+ drilldown.calc_target(result_set)) do
+ result_set.group(keys, group_result)
+ end
+ end
+ end
+ result_set = group_result.table
+ drilldown.dynamic_columns.each_initial do |dynamic_column|
+ dynamic_column.apply(result_set)
+ end
+ result_set = apply_drilldown_filter(drilldown, result_set)
+ if drilldown.sort_keys.empty?
+ drilldown.result_set = result_set
+ else
+ drilldown.result_set = result_set.sort(drilldown.sort_keys)
+ drilldown.unsorted_result_set = result_set
+ end
+ group_result.table = nil
+ ensure
+ group_result.close
+ end
+ end
+ end
+
+ def with_calc_target(group_result, calc_target)
+ group_result.calc_target = calc_target
+ begin
+ yield
+ ensure
+ calc_target.close if calc_target
+ group_result.calc_target = nil
+ end
+ end
+
+ def apply_drilldown_filter(drilldown, result_set)
+ filter = drilldown.filter
+ return result_set if filter.nil?
+
+ expression = Expression.create(result_set)
+ drilldown.expressions << expression
+ expression.parse(filter)
+ filtered_result_set = result_set.select(expression)
+ drilldown.temporary_tables << result_set
+ filtered_result_set
+ end
end
class ShardExecutor
- def initialize(context, table, shard_key, shard_range)
+ def initialize(context, shard, shard_range)
@context = context
- @table = table
- @shard_key = shard_key
+ @shard = shard
@shard_range = shard_range
+ @target_table = @shard.table
+
+ @match_columns = @context.match_columns
+ @query = @context.query
@filter = @context.filter
+ @sort_keys = @context.sort_keys
@result_sets = @context.result_sets
+ @unsorted_result_sets = @context.unsorted_result_sets
@target_range = @context.enumerator.target_range
@cover_type = @target_range.cover_type(@shard_range)
-
- @expression_builder = RangeExpressionBuilder.new(@shard_key,
- @target_range,
- @filter)
end
def execute
return if @cover_type == :none
+ return if @target_table.empty?
- case @cover_type
- when :all
- filter_shard_all
- when :partial_min
- filter_table do |expression|
- @expression_builder.build_partial_min(expression)
- end
- when :partial_max
- filter_table do |expression|
- @expression_builder.build_partial_max(expression)
+ shard_key = @shard.key
+ if shard_key.nil?
+ message = "[logical_select] shard_key doesn't exist: " +
+ "<#{@shard.key_name}>"
+ raise InvalidArgument, message
+ end
+
+ @context.dynamic_columns.each_initial do |dynamic_column|
+ if @target_table == @shard.table
+ @target_table = create_all_match_table(@target_table)
+ @context.temporary_tables << @target_table
end
- when :partial_min_and_max
- filter_table do |expression|
- @expression_builder.build_partial_min_and_max(expression)
+ dynamic_column.apply(@target_table)
+ end
+
+ create_expression_builder(shard_key) do |expression_builder|
+ case @cover_type
+ when :all
+ filter_shard_all(expression_builder)
+ when :partial_min
+ filter_table do |expression|
+ expression_builder.build_partial_min(expression)
+ end
+ when :partial_max
+ filter_table do |expression|
+ expression_builder.build_partial_max(expression)
+ end
+ when :partial_min_and_max
+ filter_table do |expression|
+ expression_builder.build_partial_min_and_max(expression)
+ end
end
end
end
private
- def filter_shard_all
- if @filter.nil?
- @result_sets << @table
+ def filter_shard_all(expression_builder)
+ if @query.nil? and @filter.nil?
+ add_result_set(@target_table, nil)
+ @context.temporary_tables.delete(@target_table)
else
filter_table do |expression|
- @expression_builder.build_all(expression)
+ expression_builder.build_all(expression)
end
end
end
def create_expression(table)
expression = Expression.create(table)
+ @context.expressions << expression
+ expression
+ end
+
+ def create_expression_builder(shard_key)
+ expression_builder = RangeExpressionBuilder.new(shard_key,
+ @target_range)
+ expression_builder.match_columns = @match_columns
+ expression_builder.query = @query
+ expression_builder.filter = @filter
begin
- yield(expression)
+ yield(expression_builder)
ensure
- expression.close
+ expression = expression_builder.match_columns_expression
+ @context.expressions << expression if expression
end
end
def filter_table
- create_expression(@table) do |expression|
- yield(expression)
- @result_sets << @table.select(expression)
+ table = @target_table
+ expression = create_expression(table)
+ yield(expression)
+ add_result_set(table.select(expression), expression)
+ end
+
+ def add_result_set(result_set, condition)
+ if result_set.empty?
+ result_set.close
+ return
+ end
+
+ @context.dynamic_columns.each_filtered do |dynamic_column|
+ if result_set == @shard.table
+ @context.temporary_tables << result_set
+ result_set = create_all_match_table(result_set)
+ end
+ dynamic_column.apply(result_set, condition)
+ end
+
+ if @sort_keys.empty?
+ @result_sets << result_set
+ else
+ @unsorted_result_sets << result_set
+ sorted_result_set = result_set.sort(@sort_keys)
+ @result_sets << sorted_result_set
+ end
+ end
+
+ def create_all_match_table(table)
+ expression = Expression.create(table)
+ begin
+ expression.append_constant(true, Operator::PUSH, 1)
+ table.select(expression)
+ ensure
+ expression.close
end
end
end
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_shard_list.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_shard_list.rb
new file mode 100644
index 00000000000..b8ef3f76520
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_shard_list.rb
@@ -0,0 +1,28 @@
+module Groonga
+ module Sharding
+ class LogicalShardListCommand < Command
+ register("logical_shard_list",
+ [
+ "logical_table",
+ ])
+
+ def run_body(input)
+ enumerator = LogicalEnumerator.new("logical_shard_list",
+ input,
+ :require_shard_key => false)
+ shard_names = enumerator.collect do |current_shard, shard_range|
+ current_shard.table_name
+ end
+
+ writer.array("shards", shard_names.size) do
+ shard_names.each do |shard_name|
+ writer.map("shard", 1) do
+ writer.write("name")
+ writer.write(shard_name)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb
index f5c31c72bb1..3353d6c3a83 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb
@@ -9,48 +9,323 @@ module Groonga
"min_border",
"max",
"max_border",
+ "dependent",
+ "force",
])
def run_body(input)
+ @dependent = (input[:dependent] == "yes")
+ @force = (input[:force] == "yes")
+
enumerator = LogicalEnumerator.new("logical_table_remove", input)
- succeess = true
- enumerator.each do |table, shard_key, shard_range|
- remove_table(table,
- shard_key,
- shard_range,
- enumerator.target_range)
+ success = true
+ enumerator.each do |shard, shard_range|
+ remove_shard(shard, shard_range, enumerator.target_range)
end
- writer.write(succeess)
+ writer.write(success)
end
private
- def remove_table(table, shard_key, shard_range, target_range)
+ def remove_shard(shard, shard_range, target_range)
cover_type = target_range.cover_type(shard_range)
return if cover_type == :none
- expression_builder = RangeExpressionBuilder.new(shard_key,
- target_range,
- nil)
+ shard_key = shard.key
+ if shard_key.nil?
+ if @force
+ context.clear_error
+ else
+ message =
+ "[logical_table_remove] shard_key doesn't exist: " +
+ "<#{shard.key_name}>"
+ raise InvalidArgument, message
+ end
+ end
+ table = shard.table
+ if cover_type == :all or ((table.nil? or shard_key.nil?) and @force)
+ remove_table(shard, table)
+ return
+ end
+
+ expression_builder = RangeExpressionBuilder.new(shard_key,
+ target_range)
case cover_type
- when :all
- table.remove
when :partial_min
remove_records(table) do |expression|
expression_builder.build_partial_min(expression)
end
- table.remove if table.empty?
+ remove_table(shard, table) if table.empty?
when :partial_max
remove_records(table) do |expression|
expression_builder.build_partial_max(expression)
end
- table.remove if table.empty?
+ remove_table(shard, table) if table.empty?
when :partial_min_and_max
remove_records(table) do |expression|
expression_builder.build_partial_min_and_max(expression)
end
- table.remove if table.empty?
+ remove_table(shard, table) if table.empty?
+ end
+ end
+
+ def collect_referenced_table_ids_from_index_ids(index_ids,
+ referenced_table_ids)
+ database = context.database
+ index_ids.each do |index_id|
+ index = context[index_id]
+ if index.nil?
+ context.clear_error
+ index_name = database[index_id]
+ lexicon_name = index_name.split(".", 2)[0]
+ lexicon_id = database[lexicon_name]
+ referenced_table_ids << lexicon_id if lexicon_id
+ else
+ referenced_table_ids << index.domain_id
+ end
+ end
+ end
+
+ def collect_referenced_table_ids_from_column_name(column_name,
+ referenced_table_ids)
+ database = context.database
+ column_id = database[column_name]
+ database.each_raw do |id, cursor|
+ next if ID.builtin?(id)
+ next if id == column_id
+
+ context.open_temporary(id) do |object|
+ if object.nil?
+ context.clear_error
+ next
+ end
+
+ case object
+ when IndexColumn
+ if object.source_ids.include?(column_id)
+ collect_referenced_table_ids_from_index_ids([id],
+ referenced_table_ids)
+ end
+ end
+ end
+ end
+ end
+
+ def collect_referenced_table_ids_from_column(column,
+ referenced_table_ids)
+ range = column.range
+ case range
+ when nil
+ context.clear_error
+ when Table
+ referenced_table_ids << range.id
+ collect_referenced_table_ids_from_index_ids(range.index_ids,
+ referenced_table_ids)
+ end
+ collect_referenced_table_ids_from_index_ids(column.index_ids,
+ referenced_table_ids)
+ end
+
+ def collect_referenced_table_ids_from_column_names(column_names)
+ referenced_table_ids = []
+ column_names.each do |column_name|
+ column = context[column_name]
+ if column.nil?
+ context.clear_error
+ collect_referenced_table_ids_from_column_name(column_name,
+ referenced_table_ids)
+ else
+ collect_referenced_table_ids_from_column(column,
+ referenced_table_ids)
+ end
+ end
+ referenced_table_ids
+ end
+
+ def collect_referenced_table_ids(shard, table)
+ return [] unless @dependent
+
+ column_names = nil
+ if table
+ begin
+ column_names = table.columns.collect(&:name)
+ rescue
+ context.clear_error
+ end
+ end
+ if column_names.nil?
+ prefix = "#{shard.table_name}."
+ column_names = []
+ context.database.each_name(:prefix => prefix) do |column_name|
+ column_names << column_name
+ end
+ end
+
+ collect_referenced_table_ids_from_column_names(column_names)
+ end
+
+ def remove_table(shard, table)
+ if table.nil?
+ unless @force
+ if context.rc == Context::RC::SUCCESS.to_i
+ error_class = InvalidArgument
+ else
+ rc = Context::RC.find(context.rc)
+ error_class = rc.error_class
+ end
+ message = "[logical_table_remove] table is broken: " +
+ "<#{shard.table_name}>: #{context.error_message}"
+ raise error_class, message
+ end
+ context.clear_error
+ end
+
+ referenced_table_ids = collect_referenced_table_ids(shard, table)
+
+ if table.nil?
+ remove_table_force(shard.table_name)
+ else
+ options = {:dependent => @dependent}
+ if @force
+ begin
+ table.remove(options)
+ rescue
+ context.clear_error
+ table.close
+ remove_table_force(shard.table_name)
+ end
+ else
+ table.remove(options)
+ end
+ end
+
+ remove_referenced_tables(shard, referenced_table_ids)
+ end
+
+ def remove_table_force(table_name)
+ database = context.database
+
+ prefix = "#{table_name}."
+ database.each_raw(:prefix => prefix) do |id, cursor|
+ column = context[id]
+ if column.nil?
+ context.clear_error
+ column_name = cursor.key
+ remove_column_force(column_name)
+ table = context[table_name]
+ if table.nil?
+ context.clear_error
+ else
+ table.close
+ end
+ else
+ remove_column(column)
+ end
+ end
+
+ table_id = database[table_name]
+ return if table_id.nil?
+
+ database.each_raw do |id, cursor|
+ next if ID.builtin?(id)
+ next if id == table_id
+
+ context.open_temporary(id) do |object|
+ if object.nil?
+ context.clear_error
+ next
+ end
+
+ case object
+ when Table
+ if object.domain_id == table_id
+ begin
+ object.remove(:dependent => @dependent)
+ rescue
+ context.clear_error
+ reference_table_name = object.name
+ object.close
+ remove_table_force(reference_table_name)
+ end
+ end
+ when Column
+ if object.range_id == table_id
+ remove_column(object)
+ end
+ end
+ end
+ end
+
+ Object.remove_force(table_name)
+ end
+
+ def remove_column(column)
+ begin
+ column.remove(:dependent => @dependent)
+ rescue
+ context.clear_error
+ column_name = column.name
+ column.close
+ remove_column_force(column_name)
+ end
+ end
+
+ def remove_column_force(column_name)
+ database = context.database
+
+ column_id = database[column_name]
+
+ column = context[column_id]
+ if column.nil?
+ context.clear_error
+ else
+ column.index_ids.each do |id|
+ index_column = context[id]
+ if index_column.nil?
+ context.clear_error
+ index_column_name = database[id]
+ remove_column_force(index_column_name)
+ else
+ remove_column(index_column)
+ end
+ end
+ column.close
+ end
+
+ Object.remove_force(column_name)
+ end
+
+ def remove_referenced_tables(shard, referenced_table_ids)
+ return if referenced_table_ids.empty?
+
+ database = context.database
+ shard_suffix = shard.range_data.to_suffix
+ referenced_table_ids.uniq.each do |referenced_table_id|
+ referenced_table_name = database[referenced_table_id]
+ next if referenced_table_name.nil?
+ next unless referenced_table_name.end_with?(shard_suffix)
+
+ referenced_table = context[referenced_table_id]
+ if referenced_table.nil?
+ context.clear_error
+ if @force
+ Object.remove_force(referenced_table_name)
+ end
+ next
+ end
+
+ if @force
+ begin
+ referenced_table.remove(:dependent => @dependent)
+ rescue
+ context.clear_error
+ referenced_table.close
+ remove_table_force(referenced_table_name)
+ end
+ else
+ referenced_table.remove(:dependent => @dependent)
+ end
end
end
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/parameters.rb b/storage/mroonga/vendor/groonga/plugins/sharding/parameters.rb
new file mode 100644
index 00000000000..b09a9d6c254
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/parameters.rb
@@ -0,0 +1,10 @@
+module Groonga
+ module Sharding
+ module Parameters
+ @range_index = :auto
+ class << self
+ attr_accessor :range_index
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/range_expression_builder.rb b/storage/mroonga/vendor/groonga/plugins/sharding/range_expression_builder.rb
index 2e2dd29c51c..cc80735d4c5 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding/range_expression_builder.rb
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/range_expression_builder.rb
@@ -1,16 +1,23 @@
module Groonga
module Sharding
class RangeExpressionBuilder
- def initialize(key, target_range, filter)
+ attr_reader :match_columns_expression
+
+ attr_writer :match_columns
+ attr_writer :query
+ attr_writer :filter
+
+ def initialize(key, target_range)
@key = key
@target_range = target_range
- @filter = filter
+ @match_columns_expression = nil
+ @match_columns = nil
+ @query = nil
+ @filter = nil
end
def build_all(expression)
- return if @filter.nil?
-
- expression.parse(@filter)
+ build_condition(expression)
end
def build_partial_min(expression)
@@ -22,10 +29,7 @@ module Groonga
else
expression.append_operator(Operator::GREATER, 2)
end
- if @filter
- expression.parse(@filter)
- expression.append_operator(Operator::AND, 2)
- end
+ build_condition(expression)
end
def build_partial_max(expression)
@@ -37,10 +41,7 @@ module Groonga
else
expression.append_operator(Operator::LESS, 2)
end
- if @filter
- expression.parse(@filter)
- expression.append_operator(Operator::AND, 2)
- end
+ build_condition(expression)
end
def build_partial_min_and_max(expression)
@@ -55,9 +56,31 @@ module Groonga
expression.append_constant(@target_range.max_border,
Operator::PUSH, 1)
expression.append_operator(Operator::CALL, 5)
+ build_condition(expression)
+ end
+
+ private
+ def build_condition(expression)
+ if @query
+ is_empty = expression.empty?
+ if @match_columns
+ table = Context.instance[expression[0].domain]
+ @match_columns_expression = Expression.create(table)
+ @match_columns_expression.parse(@match_columns)
+ end
+ flags = Expression::SYNTAX_QUERY |
+ Expression::ALLOW_PRAGMA |
+ Expression::ALLOW_COLUMN
+ expression.parse(@query,
+ default_column: @match_columns_expression,
+ flags: flags)
+ expression.append_operator(Operator::AND, 2) unless is_empty
+ end
+
if @filter
+ is_empty = expression.empty?
expression.parse(@filter)
- expression.append_operator(Operator::AND, 2)
+ expression.append_operator(Operator::AND, 2) unless is_empty
end
end
end
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/sources.am b/storage/mroonga/vendor/groonga/plugins/sharding/sources.am
index 14e56609cae..df2b6d023da 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding/sources.am
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/sources.am
@@ -1,7 +1,10 @@
sharding_scripts = \
logical_count.rb \
logical_enumerator.rb \
+ logical_parameters.rb \
logical_range_filter.rb \
logical_select.rb \
+ logical_shard_list.rb \
logical_table_remove.rb \
+ parameters.rb \
range_expression_builder.rb
diff --git a/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt
index 03375f97adb..e7d5364979b 100644
--- a/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt
@@ -15,7 +15,8 @@
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../../lib
- ${MRUBY_INCLUDE_DIRS})
+ ${MRUBY_INCLUDE_DIRS}
+ ${MESSAGE_PACK_INCLUDE_DIRS})
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am SUGGEST_SOURCES)
set_source_files_properties(${SUGGEST_SOURCES}
diff --git a/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c b/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c
index 073f5e00103..4dd5f6e62ca 100644
--- a/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c
+++ b/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c
@@ -28,13 +28,6 @@
#include "grn_output.h"
#include <groonga/plugin.h>
-#ifdef HAVE__STRNICMP
-# ifdef strncasecmp
-# undef strncasecmp
-# endif /* strcasecmp */
-# define strncasecmp(s1,s2,n) _strnicmp(s1,s2,n)
-#endif /* HAVE__STRNICMP */
-
#define VAR GRN_PROC_GET_VAR_BY_OFFSET
#define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
#define TEXT_VALUE_LEN(x) GRN_TEXT_VALUE(x), GRN_TEXT_LEN(x)
@@ -166,7 +159,7 @@ cooccurrence_search(grn_ctx *ctx, grn_obj *items, grn_obj *items_boost, grn_id i
}
if ((c = grn_ii_cursor_open(ctx, (grn_ii *)co, id, GRN_ID_NIL, GRN_ID_MAX,
((grn_ii *)co)->n_elements - 1, 0))) {
- grn_ii_posting *p;
+ grn_posting *p;
grn_obj post, pair_freq, item_freq, item_freq2, item_boost;
GRN_RECORD_INIT(&post, 0, grn_obj_id(ctx, items));
GRN_INT32_INIT(&pair_freq, 0);
@@ -330,7 +323,7 @@ complete(grn_ctx *ctx, grn_obj *items, grn_obj *items_boost, grn_obj *col,
grn_ii_cursor *icur;
if ((icur = grn_ii_cursor_open(ctx, (grn_ii *)index, id,
GRN_ID_NIL, GRN_ID_MAX, 1, 0))) {
- grn_ii_posting *p;
+ grn_posting *p;
while ((p = grn_ii_cursor_next(ctx, icur))) {
complete_add_item(ctx, p->rid, res, frequency_threshold,
items_freq, items_boost,
@@ -536,10 +529,10 @@ parse_search_mode(grn_ctx *ctx, grn_obj *mode_text)
mode_length = GRN_TEXT_LEN(mode_text);
if (mode_length == 3 &&
- strncasecmp("yes", GRN_TEXT_VALUE(mode_text), 3) == 0) {
+ grn_strncasecmp("yes", GRN_TEXT_VALUE(mode_text), 3) == 0) {
mode = GRN_SUGGEST_SEARCH_YES;
} else if (mode_length == 2 &&
- strncasecmp("no", GRN_TEXT_VALUE(mode_text), 2) == 0) {
+ grn_strncasecmp("no", GRN_TEXT_VALUE(mode_text), 2) == 0) {
mode = GRN_SUGGEST_SEARCH_NO;
} else {
mode = GRN_SUGGEST_SEARCH_AUTO;
@@ -923,10 +916,10 @@ learner_learn_for_suggest(grn_ctx *ctx, grn_suggest_learner *learner)
pair_id = grn_table_add(ctx, learner->pairs, &key, sizeof(uint64_t),
&added);
if (added) {
- GRN_RECORD_SET(ctx, pre_item, tid);
- grn_obj_set_value(ctx, learner->pairs_pre, pair_id,
+ GRN_RECORD_SET(ctx, pre_item, tid);
+ grn_obj_set_value(ctx, learner->pairs_pre, pair_id,
pre_item, GRN_OBJ_SET);
- grn_obj_set_value(ctx, learner->pairs_post, pair_id,
+ grn_obj_set_value(ctx, learner->pairs_post, pair_id,
post_item, GRN_OBJ_SET);
}
if (!token_ids) {
diff --git a/storage/mroonga/vendor/groonga/plugins/table/Makefile.am b/storage/mroonga/vendor/groonga/plugins/table/Makefile.am
deleted file mode 100644
index 4b49b0a3224..00000000000
--- a/storage/mroonga/vendor/groonga/plugins/table/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-EXTRA_DIST = \
- CMakeLists.txt
-
-AM_CFLAGS = \
- $(MESSAGE_PACK_CFLAGS) \
- $(MRUBY_CFLAGS)
-
-AM_CPPFLAGS = \
- -I$(top_builddir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/lib
-
-AM_LDFLAGS = \
- -avoid-version \
- -module \
- -no-undefined
-
-LIBS = \
- $(top_builddir)/lib/libgroonga.la \
- $(MESSAGE_PACK_LIBS)
-
-table_plugins_LTLIBRARIES = table.la
-
-include sources.am
diff --git a/storage/mroonga/vendor/groonga/plugins/table/sources.am b/storage/mroonga/vendor/groonga/plugins/table/sources.am
deleted file mode 100644
index 943e79b1f5c..00000000000
--- a/storage/mroonga/vendor/groonga/plugins/table/sources.am
+++ /dev/null
@@ -1,2 +0,0 @@
-table_la_SOURCES = \
- table.c
diff --git a/storage/mroonga/vendor/groonga/plugins/table/table.c b/storage/mroonga/vendor/groonga/plugins/table/table.c
deleted file mode 100644
index 3b0c09d9a91..00000000000
--- a/storage/mroonga/vendor/groonga/plugins/table/table.c
+++ /dev/null
@@ -1,747 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* Copyright(C) 2012 Brazil
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License version 2.1 as published by the Free Software Foundation.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include <string.h>
-
-#include "grn_ctx.h"
-#include "grn_db.h"
-#include "grn_output.h"
-#include "grn_util.h"
-#include <groonga/plugin.h>
-
-#define VAR GRN_PROC_GET_VAR_BY_OFFSET
-#define TEXT_VALUE_LEN(x) GRN_TEXT_VALUE(x), GRN_TEXT_LEN(x)
-
-static grn_obj *
-grn_ctx_get_table_by_name_or_id(grn_ctx *ctx,
- const char *name, unsigned int name_len)
-{
- grn_obj *table;
- const char *end = name + name_len;
- const char *rest = NULL;
- grn_id id = grn_atoui(name, end, &rest);
- if (rest == end) {
- table = grn_ctx_at(ctx, id);
- } else {
- table = grn_ctx_get(ctx, name, name_len);
- }
- if (!GRN_OBJ_TABLEP(table)) {
- ERR(GRN_INVALID_ARGUMENT, "invalid table name: <%.*s>", name_len, name);
- if (table) {
- grn_obj_unlink(ctx, table);
- table = NULL;
- }
- }
- return table;
-}
-
-static void
-grn_output_table_name_or_id(grn_ctx *ctx, grn_obj *table)
-{
- if (table) {
- if (((grn_db_obj *)table)->id & GRN_OBJ_TMP_OBJECT) {
- GRN_OUTPUT_INT64(((grn_db_obj *)table)->id);
- } else {
- int name_len;
- char name_buf[GRN_TABLE_MAX_KEY_SIZE];
- name_len = grn_obj_name(ctx, table, name_buf, GRN_TABLE_MAX_KEY_SIZE);
- GRN_OUTPUT_STR(name_buf, name_len);
- }
- } else {
- GRN_OUTPUT_INT64(0);
- }
-}
-
-static grn_bool
-parse_bool_value(grn_ctx *ctx, grn_obj *text)
-{
- grn_bool value = GRN_FALSE;
- if (GRN_TEXT_LEN(text) == 3 &&
- memcmp("yes", GRN_TEXT_VALUE(text), 3) == 0) {
- value = GRN_TRUE;
- }
- return value;
-}
-
-static grn_operator
-parse_set_operator_value(grn_ctx *ctx, grn_obj *text)
-{
- grn_operator value = GRN_OP_OR;
- if (GRN_TEXT_LEN(text) == 3) {
- if (memcmp("and", GRN_TEXT_VALUE(text), 3) == 0) {
- value = GRN_OP_AND;
- } else if (memcmp("but", GRN_TEXT_VALUE(text), 3) == 0) {
- value = GRN_OP_AND_NOT;
- }
- } else if (GRN_TEXT_LEN(text) == 6 &&
- memcmp("adjust", GRN_TEXT_VALUE(text), 6) == 0) {
- value = GRN_OP_ADJUST;
- } else if (GRN_TEXT_LEN(text) == 7 &&
- memcmp("and_not", GRN_TEXT_VALUE(text), 7) == 0) {
- value = GRN_OP_AND_NOT;
- }
- return value;
-}
-
-static grn_obj *
-command_match(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_obj *result_set = NULL;
- grn_obj *table = grn_ctx_get_table_by_name_or_id(ctx, TEXT_VALUE_LEN(VAR(0)));
- if (table) {
- grn_expr_flags flags = GRN_EXPR_SYNTAX_QUERY;
- grn_obj *v, *query, *columns = NULL;
- GRN_EXPR_CREATE_FOR_QUERY(ctx, table, query, v);
- if (query) {
- if (GRN_TEXT_LEN(VAR(1))) {
- GRN_EXPR_CREATE_FOR_QUERY(ctx, table, columns, v);
- if (columns) {
- grn_expr_parse(ctx, columns, TEXT_VALUE_LEN(VAR(1)),
- NULL, GRN_OP_MATCH, GRN_OP_AND,
- GRN_EXPR_SYNTAX_SCRIPT);
- }
- }
- if (parse_bool_value(ctx, VAR(5))) {
- flags |= GRN_EXPR_ALLOW_COLUMN;
- }
- if (parse_bool_value(ctx, VAR(6))) {
- flags |= GRN_EXPR_ALLOW_PRAGMA;
- }
- grn_expr_parse(ctx, query, TEXT_VALUE_LEN(VAR(2)),
- columns, GRN_OP_MATCH, GRN_OP_AND, flags);
- if (GRN_TEXT_LEN(VAR(3))) {
- result_set = grn_ctx_get_table_by_name_or_id(ctx, TEXT_VALUE_LEN(VAR(3)));
- } else {
- result_set = grn_table_create(ctx, NULL, 0, NULL,
- GRN_TABLE_HASH_KEY|
- GRN_OBJ_WITH_SUBREC,
- table, NULL);
- }
- if (result_set) {
- grn_table_select(ctx, table, query, result_set,
- parse_set_operator_value(ctx, VAR(4)));
- }
- grn_obj_unlink(ctx, columns);
- grn_obj_unlink(ctx, query);
- }
- }
- grn_output_table_name_or_id(ctx, result_set);
- return NULL;
-}
-
-static grn_obj *
-command_filter_by_script(grn_ctx *ctx, int nargs,
- grn_obj **args, grn_user_data *user_data)
-{
- grn_obj *result_set = NULL;
- grn_obj *table = grn_ctx_get_table_by_name_or_id(ctx, TEXT_VALUE_LEN(VAR(0)));
- if (table) {
- grn_expr_flags flags = GRN_EXPR_SYNTAX_SCRIPT;
- grn_obj *v, *query;
- GRN_EXPR_CREATE_FOR_QUERY(ctx, table, query, v);
- if (query) {
- if (parse_bool_value(ctx, VAR(4))) {
- flags |= GRN_EXPR_ALLOW_UPDATE;
- }
- grn_expr_parse(ctx, query, TEXT_VALUE_LEN(VAR(1)),
- NULL, GRN_OP_MATCH, GRN_OP_AND, flags);
- if (GRN_TEXT_LEN(VAR(2))) {
- result_set = grn_ctx_get_table_by_name_or_id(ctx, TEXT_VALUE_LEN(VAR(2)));
- } else {
- result_set = grn_table_create(ctx, NULL, 0, NULL,
- GRN_TABLE_HASH_KEY|
- GRN_OBJ_WITH_SUBREC,
- table, NULL);
- }
- if (result_set) {
- grn_table_select(ctx, table, query, result_set,
- parse_set_operator_value(ctx, VAR(3)));
- }
- grn_obj_unlink(ctx, query);
- }
- }
- grn_output_table_name_or_id(ctx, result_set);
- return NULL;
-}
-
-static grn_obj *
-command_filter(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_operator operator = GRN_OP_NOP;
- grn_obj *table, *column, *result_set = NULL;
- if (!(table = grn_ctx_get_table_by_name_or_id(ctx, TEXT_VALUE_LEN(VAR(0))))) {
- goto exit;
- }
- if (!(column = grn_obj_column(ctx, table, TEXT_VALUE_LEN(VAR(1))))) {
- ERR(GRN_INVALID_ARGUMENT, "invalid column name: <%.*s>",
- (int)GRN_TEXT_LEN(VAR(1)), GRN_TEXT_VALUE(VAR(1)));
- goto exit;
- }
- if (GRN_TEXT_LEN(VAR(2)) == 0) {
- ERR(GRN_INVALID_ARGUMENT, "missing mandatory argument: operator");
- goto exit;
- } else {
- uint32_t operator_len = GRN_TEXT_LEN(VAR(2));
- const char *operator_text = GRN_TEXT_VALUE(VAR(2));
- switch (operator_text[0]) {
- case '<' :
- if (operator_len == 1) {
- operator = GRN_OP_LESS;
- }
- break;
- }
- if (operator == GRN_OP_NOP) {
- ERR(GRN_INVALID_ARGUMENT, "invalid operator: <%.*s>",
- operator_len, operator_text);
- goto exit;
- }
- }
- if (GRN_TEXT_LEN(VAR(4))) {
- result_set = grn_ctx_get_table_by_name_or_id(ctx, TEXT_VALUE_LEN(VAR(4)));
- } else {
- result_set = grn_table_create(ctx, NULL, 0, NULL,
- GRN_TABLE_HASH_KEY|
- GRN_OBJ_WITH_SUBREC,
- table, NULL);
- }
- if (result_set) {
- grn_column_filter(ctx, column, operator, VAR(3), result_set,
- parse_set_operator_value(ctx, VAR(5)));
- }
-exit :
- grn_output_table_name_or_id(ctx, result_set);
- return NULL;
-}
-
-static grn_obj *
-command_group(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- const char *table = GRN_TEXT_VALUE(VAR(0));
- unsigned int table_len = GRN_TEXT_LEN(VAR(0));
- const char *key = GRN_TEXT_VALUE(VAR(1));
- unsigned int key_len = GRN_TEXT_LEN(VAR(1));
- const char *set = GRN_TEXT_VALUE(VAR(2));
- unsigned int set_len = GRN_TEXT_LEN(VAR(2));
- grn_obj *table_ = grn_ctx_get_table_by_name_or_id(ctx, table, table_len);
- grn_obj *set_ = NULL;
- if (table_) {
- uint32_t ngkeys;
- grn_table_sort_key *gkeys;
- gkeys = grn_table_sort_key_from_str(ctx, key, key_len, table_, &ngkeys);
- if (gkeys) {
- if (set_len) {
- set_ = grn_ctx_get_table_by_name_or_id(ctx, set, set_len);
- } else {
- set_ = grn_table_create_for_group(ctx, NULL, 0, NULL,
- gkeys[0].key, table_, 0);
- }
- if (set_) {
- if (GRN_TEXT_LEN(VAR(3))) {
- uint32_t gap = grn_atoui(GRN_TEXT_VALUE(VAR(3)),
- GRN_BULK_CURR(VAR(3)), NULL);
- grn_table_group_with_range_gap(ctx, table_, gkeys, set_, gap);
- } else {
- grn_table_group_result g = {
- set_, 0, 0, 1,
- GRN_TABLE_GROUP_CALC_COUNT, 0
- };
- grn_table_group(ctx, table_, gkeys, 1, &g, 1);
- }
- }
- grn_table_sort_key_close(ctx, gkeys, ngkeys);
- }
- }
- grn_output_table_name_or_id(ctx, set_);
- return NULL;
-}
-
-#define DEFAULT_LIMIT 10
-
-static grn_obj *
-command_sort(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- const char *table = GRN_TEXT_VALUE(VAR(0));
- unsigned int table_len = GRN_TEXT_LEN(VAR(0));
- const char *keys = GRN_TEXT_VALUE(VAR(1));
- unsigned int keys_len = GRN_TEXT_LEN(VAR(1));
- int offset = GRN_TEXT_LEN(VAR(2))
- ? grn_atoi(GRN_TEXT_VALUE(VAR(2)), GRN_BULK_CURR(VAR(2)), NULL)
- : 0;
- int limit = GRN_TEXT_LEN(VAR(3))
- ? grn_atoi(GRN_TEXT_VALUE(VAR(3)), GRN_BULK_CURR(VAR(3)), NULL)
- : DEFAULT_LIMIT;
- grn_obj *table_ = grn_ctx_get_table_by_name_or_id(ctx, table, table_len);
- grn_obj *sorted = NULL;
- if (table_) {
- uint32_t nkeys;
- grn_table_sort_key *keys_;
- if (keys_len &&
- (keys_ = grn_table_sort_key_from_str(ctx, keys, keys_len,
- table_, &nkeys))) {
- if ((sorted = grn_table_create(ctx, NULL, 0, NULL,
- GRN_OBJ_TABLE_NO_KEY, NULL, table_))) {
- int table_size = (int)grn_table_size(ctx, table_);
- grn_normalize_offset_and_limit(ctx, table_size, &offset, &limit);
- grn_table_sort(ctx, table_, offset, limit, sorted, keys_, nkeys);
- grn_table_sort_key_close(ctx, keys_, nkeys);
- }
- }
- }
- grn_output_table_name_or_id(ctx, sorted);
- return NULL;
-}
-
-static grn_obj *
-command_output(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- const char *table = GRN_TEXT_VALUE(VAR(0));
- unsigned int table_len = GRN_TEXT_LEN(VAR(0));
- const char *columns = GRN_TEXT_VALUE(VAR(1));
- unsigned int columns_len = GRN_TEXT_LEN(VAR(1));
- int offset = GRN_TEXT_LEN(VAR(2))
- ? grn_atoi(GRN_TEXT_VALUE(VAR(2)), GRN_BULK_CURR(VAR(2)), NULL)
- : 0;
- int limit = GRN_TEXT_LEN(VAR(3))
- ? grn_atoi(GRN_TEXT_VALUE(VAR(3)), GRN_BULK_CURR(VAR(3)), NULL)
- : DEFAULT_LIMIT;
- grn_obj *table_ = grn_ctx_get_table_by_name_or_id(ctx, table, table_len);
- if (table_) {
- grn_obj_format format;
- int table_size = (int)grn_table_size(ctx, table_);
- GRN_OBJ_FORMAT_INIT(&format, table_size, 0, limit, offset);
- format.flags =
- GRN_OBJ_FORMAT_WITH_COLUMN_NAMES|
- GRN_OBJ_FORMAT_XML_ELEMENT_RESULTSET;
- /* TODO: accept only comma separated expr as columns */
- grn_obj_columns(ctx, table_, columns, columns_len, &format.columns);
- GRN_OUTPUT_OBJ(table_, &format);
- GRN_OBJ_FORMAT_FIN(ctx, &format);
- }
- return NULL;
-}
-
-static grn_obj *
-command_each(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- const char *table = GRN_TEXT_VALUE(VAR(0));
- unsigned int table_len = GRN_TEXT_LEN(VAR(0));
- const char *expr = GRN_TEXT_VALUE(VAR(1));
- unsigned int expr_len = GRN_TEXT_LEN(VAR(1));
- grn_obj *table_ = grn_ctx_get_table_by_name_or_id(ctx, table, table_len);
- if (table_) {
- grn_obj *v, *expr_;
- GRN_EXPR_CREATE_FOR_QUERY(ctx, table_, expr_, v);
- if (expr_ && v) {
- grn_table_cursor *tc;
- grn_expr_parse(ctx, expr_, expr, expr_len,
- NULL, GRN_OP_MATCH, GRN_OP_AND,
- GRN_EXPR_SYNTAX_SCRIPT|GRN_EXPR_ALLOW_UPDATE);
- if ((tc = grn_table_cursor_open(ctx, table_, NULL, 0,
- NULL, 0, 0, -1, 0))) {
- grn_id id;
- while ((id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
- GRN_RECORD_SET(ctx, v, id);
- grn_expr_exec(ctx, expr_, 0);
- }
- grn_table_cursor_close(ctx, tc);
- }
- grn_obj_unlink(ctx, expr_);
- }
- }
- GRN_OUTPUT_BOOL(!ctx->rc);
- return NULL;
-}
-
-static grn_obj *
-command_unlink(grn_ctx *ctx, int nargs, grn_obj **args,
- grn_user_data *user_data)
-{
- const char *table = GRN_TEXT_VALUE(VAR(0));
- unsigned int table_len = GRN_TEXT_LEN(VAR(0));
- grn_obj *table_ = grn_ctx_get_table_by_name_or_id(ctx, table, table_len);
- if (table_) {
- grn_obj_unlink(ctx, table_);
- }
- GRN_OUTPUT_BOOL(!ctx->rc);
- return NULL;
-}
-
-static grn_obj *
-command_add(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_load_(ctx, GRN_CONTENT_JSON,
- GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)),
- NULL, 0,
- GRN_TEXT_VALUE(VAR(1)), GRN_TEXT_LEN(VAR(1)),
- NULL, 0, NULL, 0, 0);
- GRN_OUTPUT_BOOL(ctx->impl->loader.nrecords);
- if (ctx->impl->loader.table) {
- grn_db_touch(ctx, DB_OBJ(ctx->impl->loader.table)->db);
- }
- return NULL;
-}
-
-static grn_obj *
-command_set(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- int table_name_len = GRN_TEXT_LEN(VAR(0));
- const char *table_name = GRN_TEXT_VALUE(VAR(0));
- grn_obj *table = grn_ctx_get(ctx, table_name, table_name_len);
- if (table) {
- grn_id id = GRN_ID_NIL;
- int key_len = GRN_TEXT_LEN(VAR(2));
- int id_len = GRN_TEXT_LEN(VAR(5));
- if (key_len) {
- const char *key = GRN_TEXT_VALUE(VAR(2));
- id = grn_table_get(ctx, table, key, key_len);
- } else {
- if (id_len) {
- id = grn_atoui(GRN_TEXT_VALUE(VAR(5)), GRN_BULK_CURR(VAR(5)), NULL);
- }
- id = grn_table_at(ctx, table, id);
- }
- if (id) {
- grn_obj obj;
- grn_obj_format format;
- GRN_RECORD_INIT(&obj, 0, ((grn_db_obj *)table)->id);
- GRN_OBJ_FORMAT_INIT(&format, 1, 0, 1, 0);
- GRN_RECORD_SET(ctx, &obj, id);
- grn_obj_columns(ctx, table,
- GRN_TEXT_VALUE(VAR(4)),
- GRN_TEXT_LEN(VAR(4)), &format.columns);
- format.flags = 0 /* GRN_OBJ_FORMAT_WITH_COLUMN_NAMES */;
- GRN_OUTPUT_OBJ(&obj, &format);
- GRN_OBJ_FORMAT_FIN(ctx, &format);
- }
- } else {
- ERR(GRN_INVALID_ARGUMENT,
- "nonexistent table name: <%.*s>", table_name_len, table_name);
- }
- return NULL;
-}
-
-static grn_rc
-command_get_resolve_parameters(grn_ctx *ctx, grn_user_data *user_data,
- grn_obj **table, grn_id *id)
-{
- const char *table_text, *id_text, *key_text;
- int table_length, id_length, key_length;
-
- table_text = GRN_TEXT_VALUE(VAR(0));
- table_length = GRN_TEXT_LEN(VAR(0));
- if (table_length == 0) {
- ERR(GRN_INVALID_ARGUMENT, "[table][get] table isn't specified");
- return ctx->rc;
- }
-
- *table = grn_ctx_get(ctx, table_text, table_length);
- if (!*table) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][get] table doesn't exist: <%.*s>", table_length, table_text);
- return ctx->rc;
- }
-
- key_text = GRN_TEXT_VALUE(VAR(1));
- key_length = GRN_TEXT_LEN(VAR(1));
- id_text = GRN_TEXT_VALUE(VAR(3));
- id_length = GRN_TEXT_LEN(VAR(3));
- switch ((*table)->header.type) {
- case GRN_TABLE_NO_KEY:
- if (key_length) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][get] should not specify key for NO_KEY table: <%.*s>: "
- "table: <%.*s>",
- key_length, key_text,
- table_length, table_text);
- return ctx->rc;
- }
- if (id_length) {
- const char *rest = NULL;
- *id = grn_atoi(id_text, id_text + id_length, &rest);
- if (rest == id_text) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][get] ID should be a number: <%.*s>: table: <%.*s>",
- id_length, id_text,
- table_length, table_text);
- }
- } else {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][get] ID isn't specified: table: <%.*s>",
- table_length, table_text);
- }
- break;
- case GRN_TABLE_HASH_KEY:
- case GRN_TABLE_PAT_KEY:
- case GRN_TABLE_DAT_KEY:
- if (key_length && id_length) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][get] should not specify both key and ID: "
- "key: <%.*s>: ID: <%.*s>: table: <%.*s>",
- key_length, key_text,
- id_length, id_text,
- table_length, table_text);
- return ctx->rc;
- }
- if (key_length) {
- *id = grn_table_get(ctx, *table, key_text, key_length);
- if (!*id) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][get] nonexistent key: <%.*s>: table: <%.*s>",
- key_length, key_text,
- table_length, table_text);
- }
- } else {
- if (id_length) {
- const char *rest = NULL;
- *id = grn_atoi(id_text, id_text + id_length, &rest);
- if (rest == id_text) {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][get] ID should be a number: <%.*s>: table: <%.*s>",
- id_length, id_text,
- table_length, table_text);
- }
- } else {
- ERR(GRN_INVALID_ARGUMENT,
- "[table][get] key nor ID isn't specified: table: <%.*s>",
- table_length, table_text);
- }
- }
- break;
- default:
- ERR(GRN_INVALID_ARGUMENT,
- "[table][get] not a table: <%.*s>", table_length, table_text);
- break;
- }
-
- return ctx->rc;
-}
-
-static grn_obj *
-command_get(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_id id = GRN_ID_NIL;
- grn_obj *table = NULL;
- if (!command_get_resolve_parameters(ctx, user_data, &table, &id)) {
- grn_obj obj;
- grn_obj_format format;
- GRN_OUTPUT_ARRAY_OPEN("RESULT", 2);
- GRN_RECORD_INIT(&obj, 0, ((grn_db_obj *)table)->id);
- GRN_OBJ_FORMAT_INIT(&format, 1, 0, 1, 0);
- GRN_RECORD_SET(ctx, &obj, id);
- grn_obj_columns(ctx, table, GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)),
- &format.columns);
- format.flags =
- GRN_OBJ_FORMAT_WITH_COLUMN_NAMES |
- GRN_OBJ_FORMAT_XML_ELEMENT_RESULTSET;
- GRN_OUTPUT_OBJ(&obj, &format);
- GRN_OBJ_FORMAT_FIN(ctx, &format);
- GRN_OUTPUT_ARRAY_CLOSE();
- }
- return NULL;
-}
-
-static grn_obj *
-command_push(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_obj *table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)));
- if (table) {
- switch (table->header.type) {
- case GRN_TABLE_NO_KEY:
- {
- grn_array *array = (grn_array *)table;
- grn_table_queue *queue = grn_array_queue(ctx, array);
- if (queue) {
- MUTEX_LOCK(queue->mutex);
- if (grn_table_queue_head(queue) == queue->cap) {
- grn_array_clear_curr_rec(ctx, array);
- }
- grn_load_(ctx, GRN_CONTENT_JSON,
- GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)),
- NULL, 0,
- GRN_TEXT_VALUE(VAR(1)), GRN_TEXT_LEN(VAR(1)),
- NULL, 0, NULL, 0, 0);
- if (grn_table_queue_size(queue) == queue->cap) {
- grn_table_queue_tail_increment(queue);
- }
- grn_table_queue_head_increment(queue);
- COND_SIGNAL(queue->cond);
- MUTEX_UNLOCK(queue->mutex);
- GRN_OUTPUT_BOOL(ctx->impl->loader.nrecords);
- if (ctx->impl->loader.table) {
- grn_db_touch(ctx, DB_OBJ(ctx->impl->loader.table)->db);
- }
- } else {
- ERR(GRN_OPERATION_NOT_SUPPORTED, "table '%.*s' doesn't support push",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- }
- }
- break;
- default :
- ERR(GRN_OPERATION_NOT_SUPPORTED, "table '%.*s' doesn't support push",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- }
- } else {
- ERR(GRN_INVALID_ARGUMENT, "table '%.*s' does not exist.",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- }
- return NULL;
-}
-
-static grn_obj *
-command_pull(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
- grn_obj *table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)));
- if (table) {
- switch (table->header.type) {
- case GRN_TABLE_NO_KEY:
- {
- grn_array *array = (grn_array *)table;
- grn_table_queue *queue = grn_array_queue(ctx, array);
- if (queue) {
- MUTEX_LOCK(queue->mutex);
- while (grn_table_queue_size(queue) == 0) {
- if (GRN_TEXT_LEN(VAR(2))) {
- MUTEX_UNLOCK(queue->mutex);
- GRN_OUTPUT_BOOL(0);
- return NULL;
- }
- COND_WAIT(queue->cond, queue->mutex);
- }
- grn_table_queue_tail_increment(queue);
- {
- grn_obj obj;
- grn_obj_format format;
- GRN_RECORD_INIT(&obj, 0, ((grn_db_obj *)table)->id);
- GRN_OBJ_FORMAT_INIT(&format, 1, 0, 1, 0);
- GRN_RECORD_SET(ctx, &obj, grn_table_queue_tail(queue));
- grn_obj_columns(ctx, table, GRN_TEXT_VALUE(VAR(1)), GRN_TEXT_LEN(VAR(1)),
- &format.columns);
- format.flags = 0 /* GRN_OBJ_FORMAT_WITH_COLUMN_NAMES */;
- GRN_OUTPUT_OBJ(&obj, &format);
- GRN_OBJ_FORMAT_FIN(ctx, &format);
- }
- MUTEX_UNLOCK(queue->mutex);
- } else {
- ERR(GRN_OPERATION_NOT_SUPPORTED, "table '%.*s' doesn't support pull",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- }
- }
- break;
- default :
- ERR(GRN_OPERATION_NOT_SUPPORTED, "table '%.*s' doesn't support pull",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- }
- } else {
- ERR(GRN_INVALID_ARGUMENT, "table '%.*s' does not exist.",
- (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
- }
- return NULL;
-}
-
-grn_rc
-GRN_PLUGIN_INIT(grn_ctx *ctx)
-{
- return GRN_SUCCESS;
-}
-
-grn_rc
-GRN_PLUGIN_REGISTER(grn_ctx *ctx)
-{
- grn_expr_var vars[18];
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_expr_var_init(ctx, &vars[1], "expression", -1);
- grn_plugin_expr_var_init(ctx, &vars[2], "result_set", -1);
- grn_plugin_expr_var_init(ctx, &vars[3], "set_operation", -1);
- grn_plugin_expr_var_init(ctx, &vars[4], "allow_update", -1);
- grn_plugin_command_create(ctx, "filter_by_script", -1, command_filter_by_script, 5, vars);
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_expr_var_init(ctx, &vars[1], "column", -1);
- grn_plugin_expr_var_init(ctx, &vars[2], "operator", -1);
- grn_plugin_expr_var_init(ctx, &vars[3], "value", -1);
- grn_plugin_expr_var_init(ctx, &vars[4], "result_set", -1);
- grn_plugin_expr_var_init(ctx, &vars[5], "set_operation", -1);
- grn_plugin_command_create(ctx, "filter", -1, command_filter, 6, vars);
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_expr_var_init(ctx, &vars[1], "key", -1);
- grn_plugin_expr_var_init(ctx, &vars[2], "result_set", -1);
- grn_plugin_expr_var_init(ctx, &vars[3], "range_gap", -1);
- grn_plugin_command_create(ctx, "group", -1, command_group, 4, vars);
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_expr_var_init(ctx, &vars[1], "keys", -1);
- grn_plugin_expr_var_init(ctx, &vars[2], "offset", -1);
- grn_plugin_expr_var_init(ctx, &vars[3], "limit", -1);
- grn_plugin_command_create(ctx, "sort", -1, command_sort, 4, vars);
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_expr_var_init(ctx, &vars[1], "columns", -1);
- grn_plugin_expr_var_init(ctx, &vars[2], "offset", -1);
- grn_plugin_expr_var_init(ctx, &vars[3], "limit", -1);
- grn_plugin_command_create(ctx, "output", -1, command_output, 4, vars);
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_expr_var_init(ctx, &vars[1], "expression", -1);
- grn_plugin_command_create(ctx, "each", -1, command_each, 2, vars);
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_command_create(ctx, "unlink", -1, command_unlink, 1, vars);
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_expr_var_init(ctx, &vars[1], "values", -1);
- grn_plugin_expr_var_init(ctx, &vars[2], "key", -1);
- grn_plugin_expr_var_init(ctx, &vars[3], "columns", -1);
- grn_plugin_expr_var_init(ctx, &vars[4], "output_columns", -1);
- grn_plugin_expr_var_init(ctx, &vars[5], "id", -1);
- grn_plugin_command_create(ctx, "add", -1, command_add, 2, vars);
- grn_plugin_command_create(ctx, "push", -1, command_push, 2, vars);
- grn_plugin_command_create(ctx, "set", -1, command_set, 6, vars);
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_expr_var_init(ctx, &vars[1], "key", -1);
- grn_plugin_expr_var_init(ctx, &vars[2], "output_columns", -1);
- grn_plugin_expr_var_init(ctx, &vars[3], "id", -1);
- grn_plugin_command_create(ctx, "get", -1, command_get, 4, vars);
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_expr_var_init(ctx, &vars[1], "output_columns", -1);
- grn_plugin_expr_var_init(ctx, &vars[2], "non_block", -1);
- grn_plugin_command_create(ctx, "pull", -1, command_pull, 3, vars);
-
- grn_plugin_expr_var_init(ctx, &vars[0], "table", -1);
- grn_plugin_expr_var_init(ctx, &vars[1], "columns", -1);
- grn_plugin_expr_var_init(ctx, &vars[2], "query", -1);
- grn_plugin_expr_var_init(ctx, &vars[3], "result_set", -1);
- grn_plugin_expr_var_init(ctx, &vars[4], "set_operation", -1);
- grn_plugin_expr_var_init(ctx, &vars[5], "allow_column_expression", -1);
- grn_plugin_expr_var_init(ctx, &vars[6], "allow_pragma", -1);
- grn_plugin_command_create(ctx, "match", -1, command_match, 7, vars);
-
- return ctx->rc;
-}
-
-grn_rc
-GRN_PLUGIN_FIN(grn_ctx *ctx)
-{
- return GRN_SUCCESS;
-}
diff --git a/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c b/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c
index 63e640d5ea2..e918ed8a1e5 100644
--- a/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c
+++ b/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c
@@ -92,15 +92,15 @@ is_stemmable(grn_obj *data, grn_bool *is_all_upper)
end = current + GRN_TEXT_LEN(data);
for (; current < end; current++) {
- if (islower(*current)) {
+ if (islower((unsigned char)*current)) {
have_lower = GRN_TRUE;
continue;
}
- if (isupper(*current)) {
+ if (isupper((unsigned char)*current)) {
have_upper = GRN_TRUE;
continue;
}
- if (isdigit(*current)) {
+ if (isdigit((unsigned char)*current)) {
continue;
}
switch (*current) {
@@ -131,11 +131,11 @@ normalize(grn_ctx *ctx,
end = current + length;
for (; current < end; current++) {
- if (isupper(*current)) {
+ if (isupper((unsigned char)*current)) {
if (current > unwritten) {
GRN_TEXT_PUT(ctx, normalized, unwritten, current - unwritten);
}
- GRN_TEXT_PUTC(ctx, normalized, tolower(*current));
+ GRN_TEXT_PUTC(ctx, normalized, tolower((unsigned char)*current));
unwritten = current + 1;
}
}
@@ -157,11 +157,11 @@ unnormalize(grn_ctx *ctx,
end = current + length;
for (; current < end; current++) {
- if (islower(*current)) {
+ if (islower((unsigned char)*current)) {
if (current > unwritten) {
GRN_TEXT_PUT(ctx, normalized, unwritten, current - unwritten);
}
- GRN_TEXT_PUTC(ctx, normalized, toupper(*current));
+ GRN_TEXT_PUTC(ctx, normalized, toupper((unsigned char)*current));
unwritten = current + 1;
}
}
diff --git a/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt
index 9209b44d36f..8eec25d683c 100644
--- a/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt
@@ -22,6 +22,17 @@ if(GRN_WITH_MECAB)
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mecab_sources.am MECAB_SOURCES)
include_directories(${MECAB_INCLUDE_DIRS})
link_directories(${MECAB_LIBRARY_DIRS})
+ if(GRN_WITH_BUNDLED_MECAB)
+ set(GRN_BUNDLED_MECAB_RELATIVE_RC_PATH "${CONFIG_DIR}/mecabrc")
+ set(MECAB_COMPILE_DEFINITIONS
+ "GRN_WITH_BUNDLED_MECAB"
+ "GRN_BUNDLED_MECAB_RELATIVE_RC_PATH=\"${GRN_BUNDLED_MECAB_RELATIVE_RC_PATH}\""
+ "GRN_BUNDLED_MECAB_RC_PATH=\"${CMAKE_INSTALL_PREFIX}/${GRN_BUNDLED_MECAB_RELATIVE_RC_PATH}\"")
+ set_source_files_properties(${MECAB_SOURCES}
+ PROPERTIES
+ COMPILE_DEFINITIONS
+ "${MECAB_COMPILE_DEFINITIONS}")
+ endif()
set_source_files_properties(${MECAB_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
diff --git a/storage/mroonga/vendor/groonga/plugins/tokenizers/Makefile.am b/storage/mroonga/vendor/groonga/plugins/tokenizers/Makefile.am
index 386b1554f73..9e10612baaa 100644
--- a/storage/mroonga/vendor/groonga/plugins/tokenizers/Makefile.am
+++ b/storage/mroonga/vendor/groonga/plugins/tokenizers/Makefile.am
@@ -14,12 +14,12 @@ AM_LDFLAGS = \
LIBS = \
$(top_builddir)/lib/libgroonga.la
-tokenizers_plugins_LTLIBRARIES =
+tokenizer_plugins_LTLIBRARIES =
if WITH_MECAB
-tokenizers_plugins_LTLIBRARIES += mecab.la
+tokenizer_plugins_LTLIBRARIES += mecab.la
endif
if WITH_KYTEA
-tokenizers_plugins_LTLIBRARIES += kytea.la
+tokenizer_plugins_LTLIBRARIES += kytea.la
endif
include mecab_sources.am
diff --git a/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c b/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c
index bade2f9d3de..eeb027acb92 100644
--- a/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c
+++ b/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2015 Brazil
+/*
+ Copyright(C) 2009-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -64,14 +65,14 @@ mecab_global_error_message(void)
static grn_encoding
translate_mecab_charset_to_grn_encoding(const char *charset)
{
- if (strcasecmp(charset, "euc-jp") == 0) {
+ if (grn_strcasecmp(charset, "euc-jp") == 0) {
return GRN_ENC_EUC_JP;
- } else if (strcasecmp(charset, "utf-8") == 0 ||
- strcasecmp(charset, "utf8") == 0) {
+ } else if (grn_strcasecmp(charset, "utf-8") == 0 ||
+ grn_strcasecmp(charset, "utf8") == 0) {
return GRN_ENC_UTF8;
- } else if (strcasecmp(charset, "shift_jis") == 0 ||
- strcasecmp(charset, "shift-jis") == 0 ||
- strcasecmp(charset, "sjis") == 0) {
+ } else if (grn_strcasecmp(charset, "shift_jis") == 0 ||
+ grn_strcasecmp(charset, "shift-jis") == 0 ||
+ grn_strcasecmp(charset, "sjis") == 0) {
return GRN_ENC_SJIS;
}
return GRN_ENC_NONE;
@@ -169,7 +170,7 @@ chunked_tokenize_utf8_chunk(grn_ctx *ctx,
tokenized_chunk_length = strlen(tokenized_chunk);
if (tokenized_chunk_length >= 1 &&
- isspace(tokenized_chunk[tokenized_chunk_length - 1])) {
+ isspace((unsigned char)tokenized_chunk[tokenized_chunk_length - 1])) {
GRN_TEXT_PUT(ctx, &(tokenizer->buf),
tokenized_chunk, tokenized_chunk_length - 1);
} else {
@@ -271,6 +272,65 @@ chunked_tokenize_utf8(grn_ctx *ctx,
}
}
+static mecab_t *
+mecab_create(grn_ctx *ctx)
+{
+ mecab_t *mecab;
+ int argc = 0;
+ const char *argv[4];
+
+ argv[argc++] = "Groonga";
+ argv[argc++] = "-Owakati";
+#ifdef GRN_WITH_BUNDLED_MECAB
+ argv[argc++] = "--rcfile";
+# ifdef WIN32
+ {
+ static char windows_mecab_rc_file[PATH_MAX];
+
+ grn_strcpy(windows_mecab_rc_file,
+ PATH_MAX,
+ grn_plugin_windows_base_dir());
+ grn_strcat(windows_mecab_rc_file,
+ PATH_MAX,
+ "/");
+ grn_strcat(windows_mecab_rc_file,
+ PATH_MAX,
+ GRN_BUNDLED_MECAB_RELATIVE_RC_PATH);
+ {
+ char *c;
+ for (c = windows_mecab_rc_file; *c != '\0'; c++) {
+ if (*c == '/') {
+ *c = '\\';
+ }
+ }
+ }
+ argv[argc++] = windows_mecab_rc_file;
+ }
+# else /* WIN32 */
+ argv[argc++] = GRN_BUNDLED_MECAB_RC_PATH;
+# endif /* WIN32 */
+#endif /* GRN_WITH_BUNDLED_MECAB */
+ mecab = mecab_new(argc, (char **)argv);
+
+ if (!mecab) {
+#ifdef GRN_WITH_BUNDLED_MECAB
+ GRN_PLUGIN_ERROR(ctx, GRN_TOKENIZER_ERROR,
+ "[tokenizer][mecab] failed to create mecab_t: %s: "
+ "mecab_new(\"%s\", \"%s\", \"%s\", \"%s\")",
+ mecab_global_error_message(),
+ argv[0], argv[1], argv[2], argv[3]);
+#else /* GRN_WITH_BUNDLED_MECAB */
+ GRN_PLUGIN_ERROR(ctx, GRN_TOKENIZER_ERROR,
+ "[tokenizer][mecab] failed to create mecab_t: %s: "
+ "mecab_new(\"%s\", \"%s\")",
+ mecab_global_error_message(),
+ argv[0], argv[1]);
+#endif /* GRN_WITH_BUNDLED_MECAB */
+ }
+
+ return mecab;
+}
+
/*
This function is called for a full text search query or a document to be
indexed. This means that both short/long strings are given.
@@ -294,13 +354,8 @@ mecab_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
if (!sole_mecab) {
grn_plugin_mutex_lock(ctx, sole_mecab_mutex);
if (!sole_mecab) {
- sole_mecab = mecab_new2("-Owakati");
- if (!sole_mecab) {
- GRN_PLUGIN_ERROR(ctx, GRN_TOKENIZER_ERROR,
- "[tokenizer][mecab] "
- "mecab_new2() failed on mecab_init(): %s",
- mecab_global_error_message());
- } else {
+ sole_mecab = mecab_create(ctx);
+ if (sole_mecab) {
sole_mecab_encoding = get_mecab_encoding(sole_mecab);
}
}
@@ -479,28 +534,24 @@ check_mecab_dictionary_encoding(grn_ctx *ctx)
{
#ifdef HAVE_MECAB_DICTIONARY_INFO_T
mecab_t *mecab;
+ grn_encoding encoding;
+ grn_bool have_same_encoding_dictionary;
- mecab = mecab_new2("-Owakati");
- if (mecab) {
- grn_encoding encoding;
- grn_bool have_same_encoding_dictionary;
+ mecab = mecab_create(ctx);
+ if (!mecab) {
+ return;
+ }
- encoding = GRN_CTX_GET_ENCODING(ctx);
- have_same_encoding_dictionary = (encoding == get_mecab_encoding(mecab));
- mecab_destroy(mecab);
+ encoding = GRN_CTX_GET_ENCODING(ctx);
+ have_same_encoding_dictionary = (encoding == get_mecab_encoding(mecab));
+ mecab_destroy(mecab);
- if (!have_same_encoding_dictionary) {
- GRN_PLUGIN_ERROR(ctx, GRN_TOKENIZER_ERROR,
- "[tokenizer][mecab] "
- "MeCab has no dictionary that uses the context encoding"
- ": <%s>",
- grn_encoding_to_string(encoding));
- }
- } else {
+ if (!have_same_encoding_dictionary) {
GRN_PLUGIN_ERROR(ctx, GRN_TOKENIZER_ERROR,
"[tokenizer][mecab] "
- "mecab_new2 failed in check_mecab_dictionary_encoding: %s",
- mecab_global_error_message());
+ "MeCab has no dictionary that uses the context encoding"
+ ": <%s>",
+ grn_encoding_to_string(encoding));
}
#endif
}
@@ -549,6 +600,11 @@ GRN_PLUGIN_INIT(grn_ctx *ctx)
}
check_mecab_dictionary_encoding(ctx);
+ if (ctx->rc != GRN_SUCCESS) {
+ grn_plugin_mutex_close(ctx, sole_mecab_mutex);
+ sole_mecab_mutex = NULL;
+ }
+
return ctx->rc;
}
diff --git a/storage/mroonga/vendor/groonga/ra.rb b/storage/mroonga/vendor/groonga/ra.rb
deleted file mode 100755
index dbe493d7454..00000000000
--- a/storage/mroonga/vendor/groonga/ra.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env ruby
-
-puts "table_create X TABLE_NO_KEY"
-puts "column_create X a COLUMN_SCALAR Int64"
-puts "load --table X"
-puts "["
-n_records = 2 ** 28
-(n_records - 1).times do |i|
- puts "{\"a\": #{i}},"
-end
-puts "{\"a\": #{n_records - 1}}"
-puts "]"
diff --git a/storage/mroonga/vendor/groonga/src/CMakeLists.txt b/storage/mroonga/vendor/groonga/src/CMakeLists.txt
index 258d1866c2b..57bded2dd1f 100644
--- a/storage/mroonga/vendor/groonga/src/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/src/CMakeLists.txt
@@ -15,6 +15,7 @@
include_directories(
${MRUBY_INCLUDE_DIRS}
+ ${MESSAGE_PACK_INCLUDE_DIRS}
)
add_subdirectory(suggest)
@@ -27,6 +28,19 @@ set_source_files_properties(${GROONGA_SOURCES}
target_link_libraries(groonga libgroonga)
install(TARGETS groonga DESTINATION ${BIN_DIR})
+if(GRN_WITH_MRUBY)
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/grndb_sources.am GRNDB_SOURCES)
+ add_executable(grndb ${GRNDB_SOURCES})
+ set_source_files_properties(${GRNDB_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+ set_source_files_properties(${GRNDB_SOURCES}
+ PROPERTIES
+ COMPILE_DEFINITIONS "${MRUBY_DEFINITIONS}")
+ target_link_libraries(grndb libgroonga)
+ install(TARGETS grndb DESTINATION ${BIN_DIR})
+endif()
+
if(NOT WIN32)
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/grnslap_sources.am GRNSLAP_SOURCES)
add_executable(grnslap ${GRNSLAP_SOURCES})
diff --git a/storage/mroonga/vendor/groonga/src/Makefile.am b/storage/mroonga/vendor/groonga/src/Makefile.am
index a4d57e85c44..2ee687233da 100644
--- a/storage/mroonga/vendor/groonga/src/Makefile.am
+++ b/storage/mroonga/vendor/groonga/src/Makefile.am
@@ -20,6 +20,10 @@ AM_CFLAGS = \
$(GRN_CFLAGS) \
$(MESSAGE_PACK_CFLAGS) \
$(MRUBY_CFLAGS)
+
+AM_CPPFLAGS = \
+ $(MRUBY_CPPFLAGS)
+
DEFS += $(GRN_DEFS)
AM_LDFLAGS = -no-undefined
diff --git a/storage/mroonga/vendor/groonga/src/grndb.c b/storage/mroonga/vendor/groonga/src/grndb.c
index d5a353e229a..6733be93fb2 100644
--- a/storage/mroonga/vendor/groonga/src/grndb.c
+++ b/storage/mroonga/vendor/groonga/src/grndb.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2014 Brazil
+ Copyright(C) 2014-2016 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -20,8 +20,11 @@
# define GROONGA_MAIN
#endif /* WIN32 */
+#include <stdio.h>
+
#include <grn_mrb.h>
#include <grn_ctx_impl.h>
+#include <grn_ctx_impl_mrb.h>
#include <mruby/variable.h>
#include <mruby/array.h>
@@ -119,8 +122,58 @@ int
main(int argc, char **argv)
{
int exit_code = EXIT_SUCCESS;
+ const char *log_path = GRN_LOG_PATH;
+ const char *log_level_name = NULL;
+
+ {
+ int i;
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+
+ if (arg[0] != '-') {
+ continue;
+ }
+
+ if (arg[1] == '-' && arg[2] == '\0') {
+ break;
+ }
+
+#define log_path_prefix "--log-path"
+#define log_level_prefix "--log-level"
+ if (strcmp(arg, log_path_prefix) == 0) {
+ if (i + 1 < argc) {
+ log_path = argv[i + 1];
+ i++;
+ }
+ } else if (strncmp(arg,
+ log_path_prefix "=",
+ strlen(log_path_prefix "=")) == 0) {
+ log_path = arg + strlen(log_path_prefix "=");
+ } else if (strcmp(arg, log_level_prefix) == 0) {
+ if (i + 1 < argc) {
+ log_level_name = argv[i + 1];
+ i++;
+ }
+ } else if (strncmp(arg,
+ log_level_prefix "=",
+ strlen(log_level_prefix "=")) == 0) {
+ log_level_name = arg + strlen(log_level_prefix "=");
+ }
+#undef log_path_equal_prefix
+#undef log_level_equal_prefix
+ }
+ }
- grn_default_logger_set_path(GRN_LOG_PATH);
+ grn_default_logger_set_path(log_path);
+ if (log_level_name) {
+ grn_log_level log_level = GRN_LOG_DEFAULT_LEVEL;
+ if (!grn_log_level_parse(log_level_name, &log_level)) {
+ fprintf(stderr, "%s: failed to parse log level: <%s>\n",
+ argv[0], log_level_name);
+ return EXIT_FAILURE;
+ }
+ grn_default_logger_set_max_level(log_level);
+ }
if (grn_init() != GRN_SUCCESS) {
return EXIT_FAILURE;
@@ -129,7 +182,12 @@ main(int argc, char **argv)
{
grn_ctx ctx;
grn_ctx_init(&ctx, 0);
- exit_code = run(&ctx, argc, argv);
+ grn_ctx_impl_mrb_ensure_init(&ctx);
+ if (ctx.rc == GRN_SUCCESS) {
+ exit_code = run(&ctx, argc, argv);
+ } else {
+ exit_code = EXIT_FAILURE;
+ }
grn_ctx_fin(&ctx);
}
diff --git a/storage/mroonga/vendor/groonga/src/groonga.c b/storage/mroonga/vendor/groonga/src/groonga.c
index 28c318664e0..9742712170d 100644
--- a/storage/mroonga/vendor/groonga/src/groonga.c
+++ b/storage/mroonga/vendor/groonga/src/groonga.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2009-2015 Brazil
+ Copyright(C) 2009-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -21,6 +21,7 @@
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
+#include <errno.h>
#ifdef WIN32
# define GROONGA_MAIN
@@ -32,6 +33,7 @@
#include <grn_proc.h>
#include <grn_db.h>
#include <grn_util.h>
+#include <grn_error.h>
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
@@ -58,13 +60,6 @@
# include <sys/uio.h>
#endif /* WIN32 */
-#ifdef HAVE__STRNICMP
-# ifdef strncasecmp
-# undef strncasecmp
-# endif /* strcasecmp */
-# define strncasecmp(s1,s2,n) _strnicmp(s1,s2,n)
-#endif /* HAVE__STRNICMP */
-
#ifndef USE_MSG_NOSIGNAL
# ifdef MSG_NOSIGNAL
# undef MSG_NOSIGNAL
@@ -85,7 +80,7 @@
#define DEFAULT_HTTP_PORT 10041
#define DEFAULT_GQTP_PORT 10043
#define DEFAULT_DEST "localhost"
-#define DEFAULT_MAX_NFTHREADS 8
+#define DEFAULT_MAX_N_FLOATING_THREADS 8
#define MAX_CON 0x10000
#define RLIMIT_NOFILE_MINIMUM 4096
@@ -101,16 +96,19 @@ static int (*do_client)(int argc, char **argv);
static int (*do_server)(char *path);
static const char *pid_file_path = NULL;
static const char *input_path = NULL;
+static grn_file_reader *input_reader = NULL;
static FILE *output = NULL;
+static grn_bool is_memcached_mode = GRN_FALSE;
+static const char *memcached_column_name = NULL;
static int ready_notify_pipe[2];
#define PIPE_READ 0
#define PIPE_WRITE 1
static grn_encoding encoding;
-static grn_command_version default_command_version;
-static int64_t default_match_escalation_threshold;
-static int log_level;
+static const char *windows_event_source_name = "Groonga";
+static grn_bool use_windows_event_log = GRN_FALSE;
+static grn_obj http_response_server_line;
static int
grn_rc_to_exit_code(grn_rc rc)
@@ -122,6 +120,25 @@ grn_rc_to_exit_code(grn_rc rc)
}
}
+static void
+break_accept_event_loop(grn_ctx *ctx)
+{
+ grn_com *client;
+ const char *address;
+
+ if (strcmp(bind_address, "0.0.0.0") == 0) {
+ address = "127.0.0.1";
+ } else if (strcmp(bind_address, "::") == 0) {
+ address = "::1";
+ } else {
+ address = bind_address;
+ }
+ client = grn_com_copen(ctx, NULL, address, port);
+ if (client) {
+ grn_com_close(ctx, client);
+ }
+}
+
#ifdef GRN_WITH_LIBEDIT
#include <locale.h>
#include <histedit.h>
@@ -224,10 +241,10 @@ read_next_line(grn_ctx *ctx, grn_obj *buf)
#else
fprintf(stderr, "> ");
fflush(stderr);
- rc = grn_text_fgets(ctx, buf, stdin);
+ rc = grn_file_reader_read_line(ctx, input_reader, buf);
#endif
} else {
- rc = grn_text_fgets(ctx, buf, stdin);
+ rc = grn_file_reader_read_line(ctx, input_reader, buf);
if (rc != GRN_END_OF_DATA) {
number_of_lines++;
}
@@ -299,6 +316,11 @@ s_output_raw(grn_ctx *ctx, int flags, FILE *stream)
if (flags & GRN_CTX_TAIL) {
grn_obj *command;
+ if (grn_ctx_get_output_type(ctx) == GRN_CONTENT_GROONGA_COMMAND_LIST &&
+ chunk_size > 0 &&
+ chunk[chunk_size - 1] != '\n') {
+ fwrite("\n", 1, 1, stream);
+ }
fflush(stream);
command = GRN_CTX_USER_DATA(ctx)->ptr;
@@ -476,7 +498,283 @@ static grn_com_queue ctx_new;
static grn_com_queue ctx_old;
static grn_mutex q_mutex;
static grn_cond q_cond;
-static uint32_t nthreads = 0, nfthreads = 0, max_nfthreads;
+static uint32_t n_running_threads = 0;
+static uint32_t n_floating_threads = 0;
+static uint32_t max_n_floating_threads;
+
+static uint32_t
+groonga_get_thread_limit(void *data)
+{
+ return max_n_floating_threads;
+}
+
+static void
+groonga_set_thread_limit(uint32_t new_limit, void *data)
+{
+ uint32_t i;
+ uint32_t current_n_floating_threads;
+ static uint32_t n_changing_threads = 0;
+ uint32_t prev_n_changing_threads;
+
+ GRN_ATOMIC_ADD_EX(&n_changing_threads, 1, prev_n_changing_threads);
+
+ MUTEX_LOCK_ENSURE(&grn_gctx, q_mutex);
+ current_n_floating_threads = n_floating_threads;
+ max_n_floating_threads = new_limit;
+ MUTEX_UNLOCK(q_mutex);
+
+ if (prev_n_changing_threads > 0) {
+ GRN_ATOMIC_ADD_EX(&n_changing_threads, -1, prev_n_changing_threads);
+ return;
+ }
+
+ if (current_n_floating_threads > new_limit) {
+ for (i = 0; i < current_n_floating_threads; i++) {
+ MUTEX_LOCK_ENSURE(&grn_gctx, q_mutex);
+ COND_SIGNAL(q_cond);
+ MUTEX_UNLOCK(q_mutex);
+ }
+ }
+
+ while (GRN_TRUE) {
+ grn_bool is_reduced;
+ MUTEX_LOCK_ENSURE(&grn_gctx, q_mutex);
+ is_reduced = (n_running_threads <= max_n_floating_threads);
+ if (!is_reduced && n_floating_threads > 0) {
+ COND_SIGNAL(q_cond);
+ }
+ MUTEX_UNLOCK(q_mutex);
+ if (is_reduced) {
+ break;
+ }
+ grn_nanosleep(1000000);
+ }
+
+ GRN_ATOMIC_ADD_EX(&n_changing_threads, -1, prev_n_changing_threads);
+}
+
+typedef struct {
+ grn_mutex mutex;
+ grn_ctx ctx;
+ grn_pat *entries;
+ uint64_t earliest_unix_time_msec;
+} request_timer_data;
+static request_timer_data the_request_timer_data;
+
+static void *
+request_timer_register(const char *request_id,
+ unsigned int request_id_size,
+ double timeout,
+ void *user_data)
+{
+ request_timer_data *data = user_data;
+ grn_id id = GRN_ID_NIL;
+
+ {
+ grn_ctx *ctx = &(data->ctx);
+ grn_bool is_first_timer;
+ grn_timeval tv;
+ uint64_t timeout_unix_time_msec;
+ void *value;
+
+ MUTEX_LOCK(data->mutex);
+ is_first_timer = (grn_pat_size(ctx, data->entries) == 0);
+ grn_timeval_now(ctx, &tv);
+ timeout_unix_time_msec = GRN_TIMEVAL_TO_MSEC(&tv) + (timeout * 1000);
+ while (GRN_TRUE) {
+ int added;
+ id = grn_pat_add(ctx, data->entries,
+ &timeout_unix_time_msec, sizeof(uint64_t),
+ &value, &added);
+ if (added != 0) {
+ break;
+ }
+ timeout_unix_time_msec++;
+ }
+ grn_memcpy(value, &request_id_size, sizeof(unsigned int));
+ grn_memcpy(((uint8_t *)value) + sizeof(unsigned int),
+ request_id, request_id_size);
+ if (data->earliest_unix_time_msec == 0 ||
+ data->earliest_unix_time_msec > timeout_unix_time_msec) {
+ data->earliest_unix_time_msec = timeout_unix_time_msec;
+ }
+ if (is_first_timer) {
+ break_accept_event_loop(ctx);
+ }
+ MUTEX_UNLOCK(data->mutex);
+ }
+
+ return (void *)(uint64_t)id;
+}
+
+static void
+request_timer_unregister(void *timer_id,
+ void *user_data)
+{
+ request_timer_data *data = user_data;
+ grn_id id = (grn_id)(uint64_t)timer_id;
+
+ {
+ grn_ctx *ctx = &(data->ctx);
+ uint64_t timeout_unix_time_msec;
+ int key_size;
+
+ MUTEX_LOCK(data->mutex);
+ key_size = grn_pat_get_key(ctx,
+ data->entries,
+ id,
+ &timeout_unix_time_msec,
+ sizeof(uint64_t));
+ if (key_size > 0) {
+ grn_pat_delete_by_id(ctx, data->entries, id, NULL);
+ if (data->earliest_unix_time_msec >= timeout_unix_time_msec) {
+ data->earliest_unix_time_msec = 0;
+ }
+ }
+ MUTEX_UNLOCK(data->mutex);
+ }
+}
+
+static void
+request_timer_fin(void *user_data)
+{
+ request_timer_data *data = user_data;
+
+ {
+ grn_ctx *ctx = &(data->ctx);
+ grn_pat_close(ctx, data->entries);
+ grn_ctx_fin(ctx);
+ MUTEX_FIN(data->mutex);
+ }
+}
+
+static void
+request_timer_init(void)
+{
+ static grn_request_timer timer;
+ request_timer_data *data = &the_request_timer_data;
+ grn_ctx *ctx;
+
+ MUTEX_INIT(data->mutex);
+ ctx = &(data->ctx);
+ grn_ctx_init(ctx, 0);
+ data->entries = grn_pat_create(ctx,
+ NULL,
+ sizeof(uint64_t),
+ GRN_TABLE_MAX_KEY_SIZE,
+ GRN_OBJ_KEY_UINT);
+ data->earliest_unix_time_msec = 0;
+
+ timer.user_data = data;
+ timer.register_func = request_timer_register;
+ timer.unregister_func = request_timer_unregister;
+ timer.fin_func = request_timer_fin;
+
+ grn_request_timer_set(&timer);
+}
+
+static grn_bool
+request_timer_ensure_earliest_unix_time_msec(void)
+{
+ request_timer_data *data = &the_request_timer_data;
+ grn_ctx *ctx;
+ grn_pat_cursor *cursor;
+
+ if (data->earliest_unix_time_msec > 0) {
+ return GRN_TRUE;
+ }
+
+ ctx = &(data->ctx);
+ cursor = grn_pat_cursor_open(ctx, data->entries,
+ NULL, 0,
+ NULL, 0,
+ 0, 1, GRN_CURSOR_ASCENDING);
+ if (!cursor) {
+ return GRN_FALSE;
+ }
+ while (grn_pat_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ void *key;
+ uint64_t timeout_unix_time_msec;
+
+ grn_pat_cursor_get_key(ctx, cursor, &key);
+ timeout_unix_time_msec = *(uint64_t *)key;
+ data->earliest_unix_time_msec = timeout_unix_time_msec;
+ break;
+ }
+ grn_pat_cursor_close(ctx, cursor);
+
+ return data->earliest_unix_time_msec > 0;
+}
+
+static int
+request_timer_get_poll_timeout(void)
+{
+ request_timer_data *data = &the_request_timer_data;
+ int timeout = 1000;
+ grn_ctx *ctx;
+ grn_timeval tv;
+
+ MUTEX_LOCK(data->mutex);
+ ctx = &(data->ctx);
+ if (grn_pat_size(ctx, data->entries) == 0) {
+ goto exit;
+ }
+
+ if (!request_timer_ensure_earliest_unix_time_msec()) {
+ goto exit;
+ }
+
+ grn_timeval_now(ctx, &tv);
+ timeout = data->earliest_unix_time_msec - GRN_TIMEVAL_TO_MSEC(&tv);
+ if (timeout < 0) {
+ timeout = 0;
+ } else if (timeout > 1000) {
+ timeout = 1000;
+ }
+
+exit :
+ MUTEX_UNLOCK(data->mutex);
+
+ return timeout;
+}
+
+static void
+request_timer_process_timeout(void)
+{
+ request_timer_data *data = &the_request_timer_data;
+ grn_ctx *ctx;
+ grn_timeval tv;
+ uint64_t max;
+ grn_pat_cursor *cursor;
+
+ ctx = &(data->ctx);
+ if (grn_pat_size(ctx, data->entries) == 0) {
+ return;
+ }
+
+ grn_timeval_now(ctx, &tv);
+ max = GRN_TIMEVAL_TO_MSEC(&tv);
+ cursor = grn_pat_cursor_open(ctx, data->entries,
+ NULL, 0,
+ &max, sizeof(uint64_t),
+ 0, -1, GRN_CURSOR_ASCENDING);
+ if (!cursor) {
+ return;
+ }
+
+ grn_id id;
+ while ((id = grn_pat_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ void *value;
+ const char *request_id;
+ unsigned int request_id_size;
+
+ grn_pat_cursor_get_value(ctx, cursor, &value);
+ request_id_size = *((unsigned int *)value);
+ request_id = (const char *)(((uint8_t *)value) + sizeof(unsigned int));
+ grn_request_canceler_cancel(request_id, request_id_size);
+ }
+ grn_pat_cursor_close(ctx, cursor);
+}
static void
reset_ready_notify_pipe(void)
@@ -512,29 +810,40 @@ send_ready_notify(void)
static void
create_pid_file(void)
{
-#ifndef WIN32
FILE *pid_file = NULL;
- pid_t pid;
if (!pid_file_path) {
return;
}
pid_file = fopen(pid_file_path, "w");
- pid = getpid();
- fprintf(pid_file, "%d\n", pid);
+ if (!pid_file) {
+ fprintf(stderr,
+ "Failed to open PID file: <%s>: <%s>\n",
+ pid_file_path, grn_strerror(errno));
+ return;
+ }
+
+ {
+#ifdef WIN32
+ DWORD pid;
+ pid = GetCurrentProcessId();
+ fprintf(pid_file, "%" GRN_FMT_DWORD "\n", pid);
+#else /* WIN32 */
+ pid_t pid;
+ pid = grn_getpid();
+ fprintf(pid_file, "%d\n", pid);
+#endif /* WIN32 */
+ }
fclose(pid_file);
-#endif
}
static void
clean_pid_file(void)
{
-#ifndef WIN32
if (pid_file_path) {
- unlink(pid_file_path);
+ grn_unlink(pid_file_path);
}
-#endif
}
static int
@@ -572,7 +881,7 @@ daemonize(void)
create_pid_file();
} else {
pid_t pid;
- pid = getpid();
+ pid = grn_getpid();
fprintf(stderr, "%d\n", pid);
}
break;
@@ -600,7 +909,9 @@ daemonize(void)
static void
run_server_loop(grn_ctx *ctx, grn_com_event *ev)
{
- while (!grn_com_event_poll(ctx, ev, 1000) && grn_gctx.stat != GRN_CTX_QUIT) {
+ request_timer_init();
+ while (!grn_com_event_poll(ctx, ev, request_timer_get_poll_timeout()) &&
+ grn_gctx.stat != GRN_CTX_QUIT) {
grn_edge *edge;
while ((edge = (grn_edge *)grn_com_queue_deque(ctx, &ctx_old))) {
grn_obj *msg;
@@ -616,11 +927,12 @@ run_server_loop(grn_ctx *ctx, grn_com_event *ev)
}
grn_edges_delete(ctx, edge);
}
+ request_timer_process_timeout();
/* todo : log stat */
}
for (;;) {
- MUTEX_LOCK(q_mutex);
- if (nthreads == nfthreads) { break; }
+ MUTEX_LOCK_ENSURE(ctx, q_mutex);
+ if (n_running_threads == n_floating_threads) { break; }
MUTEX_UNLOCK(q_mutex);
grn_nanosleep(1000000);
}
@@ -673,6 +985,8 @@ run_server(grn_ctx *ctx, grn_obj *db, grn_com_event *ev,
return exit_code;
}
+static grn_bool memcached_init(grn_ctx *ctx);
+
static int
start_service(grn_ctx *ctx, const char *db_path,
grn_edge_dispatcher_func dispatcher, grn_handler_func handler)
@@ -693,10 +1007,20 @@ start_service(grn_ctx *ctx, const char *db_path,
grn_obj *db;
db = (newdb || !db_path) ? grn_db_create(ctx, db_path, NULL) : grn_db_open(ctx, db_path);
if (db) {
- exit_code = run_server(ctx, db, &ev, dispatcher, handler);
+ if (is_memcached_mode) {
+ if (!memcached_init(ctx)) {
+ fprintf(stderr, "failed to initialize memcached mode: %s\n",
+ ctx->errbuf);
+ exit_code = EXIT_FAILURE;
+ send_ready_notify();
+ }
+ }
+ if (exit_code == EXIT_SUCCESS) {
+ exit_code = run_server(ctx, db, &ev, dispatcher, handler);
+ }
grn_obj_close(ctx, db);
} else {
- fprintf(stderr, "db open failed (%s)\n", db_path);
+ fprintf(stderr, "db open failed (%s): %s\n", db_path, ctx->errbuf);
exit_code = EXIT_FAILURE;
send_ready_notify();
}
@@ -719,26 +1043,43 @@ typedef struct {
} ht_context;
static void
-h_output_set_header(grn_ctx *ctx, grn_obj *header,
- grn_rc rc, long long int content_length)
+h_output_set_header(grn_ctx *ctx,
+ grn_obj *header,
+ grn_rc rc,
+ long long int content_length,
+ grn_obj *foot)
{
switch (rc) {
case GRN_SUCCESS :
GRN_TEXT_SETS(ctx, header, "HTTP/1.1 200 OK\r\n");
break;
case GRN_INVALID_ARGUMENT :
+ case GRN_FUNCTION_NOT_IMPLEMENTED :
case GRN_SYNTAX_ERROR :
GRN_TEXT_SETS(ctx, header, "HTTP/1.1 400 Bad Request\r\n");
break;
case GRN_NO_SUCH_FILE_OR_DIRECTORY :
GRN_TEXT_SETS(ctx, header, "HTTP/1.1 404 Not Found\r\n");
break;
+ case GRN_CANCEL :
+ GRN_TEXT_SETS(ctx, header, "HTTP/1.1 408 Request Timeout\r\n");
+ break;
default :
GRN_TEXT_SETS(ctx, header, "HTTP/1.1 500 Internal Server Error\r\n");
break;
}
+ GRN_TEXT_PUT(ctx, header,
+ GRN_TEXT_VALUE(&http_response_server_line),
+ GRN_TEXT_LEN(&http_response_server_line));
GRN_TEXT_PUTS(ctx, header, "Content-Type: ");
- GRN_TEXT_PUTS(ctx, header, grn_ctx_get_mime_type(ctx));
+ if (grn_ctx_get_output_type(ctx) == GRN_CONTENT_JSON &&
+ foot &&
+ GRN_TEXT_LEN(foot) > 0 &&
+ GRN_TEXT_VALUE(foot)[GRN_TEXT_LEN(foot) - 1] == ';') {
+ GRN_TEXT_PUTS(ctx, header, "application/javascript");
+ } else {
+ GRN_TEXT_PUTS(ctx, header, grn_ctx_get_mime_type(ctx));
+ }
GRN_TEXT_PUTS(ctx, header, "\r\n");
if (content_length >= 0) {
GRN_TEXT_PUTS(ctx, header, "Connection: close\r\n");
@@ -865,10 +1206,10 @@ h_output_raw(grn_ctx *ctx, int flags, ht_context *hc)
if (!hc->in_body) {
if (is_last_message) {
- h_output_set_header(ctx, &header_, expr_rc, GRN_TEXT_LEN(&body_));
+ h_output_set_header(ctx, &header_, expr_rc, GRN_TEXT_LEN(&body_), NULL);
hc->is_chunked = GRN_FALSE;
} else {
- h_output_set_header(ctx, &header_, expr_rc, -1);
+ h_output_set_header(ctx, &header_, expr_rc, -1, NULL);
hc->is_chunked = GRN_TRUE;
}
header = &header_;
@@ -938,7 +1279,8 @@ h_output_typed(grn_ctx *ctx, int flags, ht_context *hc)
h_output_set_header(ctx, &header, expr_rc,
GRN_TEXT_LEN(&head) +
GRN_TEXT_LEN(&body) +
- GRN_TEXT_LEN(&foot));
+ GRN_TEXT_LEN(&foot),
+ &foot);
if (should_return_body) {
h_output_send(ctx, fd, &header, &head, &body, &foot);
} else {
@@ -967,8 +1309,9 @@ h_output(grn_ctx *ctx, int flags, void *arg)
}
static void
-do_htreq_get(grn_ctx *ctx, grn_msg *msg)
+do_htreq_get(grn_ctx *ctx, ht_context *hc)
{
+ grn_msg *msg = hc->msg;
char *path = NULL;
char *pathe = GRN_BULK_HEAD((grn_obj *)msg);
char *e = GRN_BULK_CURR((grn_obj *)msg);
@@ -987,7 +1330,7 @@ do_htreq_get(grn_ctx *ctx, grn_msg *msg)
}
}
}
- grn_ctx_send(ctx, path, pathe - path, 0);
+ grn_ctx_send(ctx, path, pathe - path, GRN_CTX_TAIL);
}
typedef struct {
@@ -1004,7 +1347,7 @@ typedef struct {
#define STRING_EQUAL_CI(string, string_length, constant_string)\
(string_length == strlen(constant_string) &&\
- strncasecmp(string, constant_string, string_length) == 0)
+ grn_strncasecmp(string, constant_string, string_length) == 0)
static const char *
do_htreq_post_parse_header_request_line(grn_ctx *ctx,
@@ -1169,8 +1512,9 @@ do_htreq_post_parse_header(grn_ctx *ctx,
}
static void
-do_htreq_post(grn_ctx *ctx, grn_msg *msg)
+do_htreq_post(grn_ctx *ctx, ht_context *hc)
{
+ grn_msg *msg = hc->msg;
grn_sock fd = msg->u.fd;
const char *end;
h_post_header header;
@@ -1189,7 +1533,7 @@ do_htreq_post(grn_ctx *ctx, grn_msg *msg)
return;
}
- grn_ctx_send(ctx, header.path_start, header.path_length, GRN_CTX_QUIET);
+ grn_ctx_send(ctx, header.path_start, header.path_length, GRN_CTX_MORE);
if (ctx->rc != GRN_SUCCESS) {
ht_context context;
context.msg = msg;
@@ -1264,7 +1608,9 @@ do_htreq_post(grn_ctx *ctx, grn_msg *msg)
int flags = 0;
if (!(read_content_length == header.content_length &&
buffer_current + 1 == buffer_end)) {
- flags |= GRN_CTX_QUIET;
+ flags |= GRN_CTX_MORE;
+ } else {
+ flags |= GRN_CTX_TAIL;
}
grn_ctx_send(ctx,
GRN_TEXT_VALUE(&chunk_buffer),
@@ -1280,13 +1626,19 @@ do_htreq_post(grn_ctx *ctx, grn_msg *msg)
buffer_start, buffer_end - buffer_start);
}
#undef POST_BUFFER_SIZE
+
+ if (ctx->rc != GRN_SUCCESS) {
+ break;
+ }
}
- if (GRN_TEXT_LEN(&chunk_buffer) > 0) {
+ if (ctx->rc == GRN_CANCEL) {
+ h_output(ctx, GRN_CTX_TAIL, hc);
+ } else if (ctx->rc == GRN_SUCCESS && GRN_TEXT_LEN(&chunk_buffer) > 0) {
grn_ctx_send(ctx,
GRN_TEXT_VALUE(&chunk_buffer),
GRN_TEXT_LEN(&chunk_buffer),
- 0);
+ GRN_CTX_TAIL);
}
GRN_OBJ_FIN(ctx, &chunk_buffer);
@@ -1294,19 +1646,19 @@ do_htreq_post(grn_ctx *ctx, grn_msg *msg)
}
static void
-do_htreq(grn_ctx *ctx, grn_msg *msg)
+do_htreq(grn_ctx *ctx, ht_context *hc)
{
+ grn_msg *msg = hc->msg;
grn_com_header *header = &msg->header;
switch (header->qtype) {
case 'G' : /* GET */
case 'H' : /* HEAD */
- do_htreq_get(ctx, msg);
+ do_htreq_get(ctx, hc);
break;
case 'P' : /* POST */
- do_htreq_post(ctx, msg);
+ do_htreq_post(ctx, hc);
break;
}
- grn_ctx_set_next_expr(ctx, NULL);
/* if (ctx->rc != GRN_OPERATION_WOULD_BLOCK) {...} */
grn_msg_close(ctx, (grn_obj *)msg);
/* if not keep alive connection */
@@ -1355,7 +1707,6 @@ enum {
MBCMD_PREPENDQ = 0x1a
};
-static grn_critical_section cache_lock;
static grn_obj *cache_table = NULL;
static grn_obj *cache_value = NULL;
static grn_obj *cache_flags = NULL;
@@ -1364,39 +1715,189 @@ static grn_obj *cache_cas = NULL;
#define CTX_GET(name) (grn_ctx_get(ctx, (name), strlen(name)))
-static grn_obj *
-cache_init(grn_ctx *ctx)
+static grn_bool
+memcached_setup_flags_column(grn_ctx *ctx, const char *name)
+{
+ cache_flags = grn_obj_column(ctx, cache_table, name, strlen(name));
+ if (cache_flags) {
+ return GRN_TRUE;
+ }
+
+ cache_flags = grn_column_create(ctx, cache_table, name, strlen(name), NULL,
+ GRN_OBJ_COLUMN_SCALAR|GRN_OBJ_PERSISTENT,
+ grn_ctx_at(ctx, GRN_DB_UINT32));
+ if (!cache_flags) {
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+memcached_setup_expire_column(grn_ctx *ctx, const char *name)
+{
+ cache_expire = grn_obj_column(ctx, cache_table, name, strlen(name));
+ if (cache_expire) {
+ return GRN_TRUE;
+ }
+
+ cache_expire = grn_column_create(ctx, cache_table, name, strlen(name), NULL,
+ GRN_OBJ_COLUMN_SCALAR|GRN_OBJ_PERSISTENT,
+ grn_ctx_at(ctx, GRN_DB_UINT32));
+ if (!cache_expire) {
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+memcached_setup_cas_column(grn_ctx *ctx, const char *name)
{
- if (cache_cas) { return cache_cas; }
- CRITICAL_SECTION_ENTER(cache_lock);
+ cache_cas = grn_obj_column(ctx, cache_table, name, strlen(name));
+ if (cache_cas) {
+ return GRN_TRUE;
+ }
+
+ cache_cas = grn_column_create(ctx, cache_table, name, strlen(name), NULL,
+ GRN_OBJ_COLUMN_SCALAR|GRN_OBJ_PERSISTENT,
+ grn_ctx_at(ctx, GRN_DB_UINT64));
if (!cache_cas) {
- if ((cache_table = CTX_GET("Memcache"))) {
- cache_value = CTX_GET("Memcache.value");
- cache_flags = CTX_GET("Memcache.flags");
- cache_expire = CTX_GET("Memcache.expire");
- cache_cas = CTX_GET("Memcache.cas");
- } else {
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+memcached_init(grn_ctx *ctx)
+{
+ if (memcached_column_name) {
+ cache_value = CTX_GET(memcached_column_name);
+ if (!cache_value) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "memcached column doesn't exist: <%s>",
+ memcached_column_name);
+ return GRN_FALSE;
+ }
+ if (!(grn_obj_is_column(ctx, cache_value) &&
+ ((cache_value->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) ==
+ GRN_OBJ_COLUMN_SCALAR))) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, cache_value);
+ ERR(GRN_INVALID_ARGUMENT,
+ "memcached column must be scalar column: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return GRN_FALSE;
+ }
+ if (!(GRN_DB_SHORT_TEXT <= grn_obj_get_range(ctx, cache_value) &&
+ grn_obj_get_range(ctx, cache_value) <= GRN_DB_LONG_TEXT)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, cache_value);
+ ERR(GRN_INVALID_ARGUMENT,
+ "memcached column must be text column: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return GRN_FALSE;
+ }
+
+ cache_table = grn_ctx_at(ctx, cache_value->header.domain);
+ if (cache_table->header.type == GRN_TABLE_NO_KEY) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, cache_table);
+ ERR(GRN_INVALID_ARGUMENT,
+ "memcached column's table must be HASH_KEY, PAT_KEY or DAT_KEY table: "
+ "<%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return GRN_FALSE;
+ }
+
+ {
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ char value_column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int value_column_name_size;
+
+ value_column_name_size = grn_column_name(ctx, cache_value,
+ value_column_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ grn_snprintf(column_name,
+ GRN_TABLE_MAX_KEY_SIZE,
+ GRN_TABLE_MAX_KEY_SIZE,
+ "%.*s_memcached_flags",
+ value_column_name_size,
+ value_column_name);
+ if (!memcached_setup_flags_column(ctx, column_name)) {
+ return GRN_FALSE;
+ }
+ grn_snprintf(column_name,
+ GRN_TABLE_MAX_KEY_SIZE,
+ GRN_TABLE_MAX_KEY_SIZE,
+ "%.*s_memcached_expire",
+ value_column_name_size,
+ value_column_name);
+ if (!memcached_setup_expire_column(ctx, column_name)) {
+ return GRN_FALSE;
+ }
+ grn_snprintf(column_name,
+ GRN_TABLE_MAX_KEY_SIZE,
+ GRN_TABLE_MAX_KEY_SIZE,
+ "%.*s_memcached_cas",
+ value_column_name_size,
+ value_column_name);
+ if (!memcached_setup_cas_column(ctx, column_name)) {
+ return GRN_FALSE;
+ }
+ }
+ } else {
+ const char *table_name = "Memcache";
+ const char *value_column_name = "value";
+
+ cache_table = CTX_GET(table_name);
+ if (!cache_table) {
+ cache_table = grn_table_create(ctx, table_name, strlen(table_name), NULL,
+ GRN_OBJ_TABLE_PAT_KEY|GRN_OBJ_PERSISTENT,
+ grn_ctx_at(ctx, GRN_DB_SHORT_TEXT),
+ NULL);
if (!cache_table) {
- grn_obj *uint32_type = grn_ctx_at(ctx, GRN_DB_UINT32);
- grn_obj *uint64_type = grn_ctx_at(ctx, GRN_DB_UINT64);
- grn_obj *shorttext_type = grn_ctx_at(ctx, GRN_DB_SHORT_TEXT);
- if ((cache_table = grn_table_create(ctx, "Memcache", 8, NULL,
- GRN_OBJ_TABLE_PAT_KEY|GRN_OBJ_PERSISTENT,
- shorttext_type, NULL))) {
- cache_value = grn_column_create(ctx, cache_table, "value", 5, NULL,
- GRN_OBJ_PERSISTENT, shorttext_type);
- cache_flags = grn_column_create(ctx, cache_table, "flags", 5, NULL,
- GRN_OBJ_PERSISTENT, uint32_type);
- cache_expire = grn_column_create(ctx, cache_table, "expire", 6, NULL,
- GRN_OBJ_PERSISTENT, uint32_type);
- cache_cas = grn_column_create(ctx, cache_table, "cas", 3, NULL,
- GRN_OBJ_PERSISTENT, uint64_type);
- }
+ return GRN_FALSE;
}
}
+
+ cache_value = grn_obj_column(ctx, cache_table,
+ value_column_name,
+ strlen(value_column_name));
+ if (!cache_value) {
+ cache_value = grn_column_create(ctx, cache_table,
+ value_column_name,
+ strlen(value_column_name),
+ NULL,
+ GRN_OBJ_COLUMN_SCALAR|GRN_OBJ_PERSISTENT,
+ grn_ctx_at(ctx, GRN_DB_SHORT_TEXT));
+ if (!cache_value) {
+ return GRN_FALSE;
+ }
+ }
+
+ if (!memcached_setup_flags_column(ctx, "flags")) {
+ return GRN_FALSE;
+ }
+ if (!memcached_setup_expire_column(ctx, "expire")) {
+ return GRN_FALSE;
+ }
+ if (!memcached_setup_cas_column(ctx, "cas")) {
+ return GRN_FALSE;
+ }
}
- CRITICAL_SECTION_LEAVE(cache_lock);
- return cache_cas;
+
+ return GRN_TRUE;
}
#define RELATIVE_TIME_THRESH 1000000000
@@ -1439,7 +1940,6 @@ do_mbreq(grn_ctx *ctx, grn_edge *edge)
grn_id rid;
uint16_t keylen = ntohs(header->keylen);
char *key = GRN_BULK_HEAD((grn_obj *)msg);
- cache_init(ctx);
rid = grn_table_get(ctx, cache_table, key, keylen);
if (!rid) {
GRN_MSG_MBRES({
@@ -1499,7 +1999,6 @@ do_mbreq(grn_ctx *ctx, grn_edge *edge)
int f = (header->qtype == MBCMD_REPLACE ||
header->qtype == MBCMD_REPLACEQ) ? 0 : GRN_TABLE_ADD;
GRN_ASSERT(extralen == 8);
- cache_init(ctx);
if (header->qtype == MBCMD_REPLACE || header->qtype == MBCMD_REPLACEQ) {
rid = grn_table_get(ctx, cache_table, key, keylen);
} else {
@@ -1623,7 +2122,6 @@ do_mbreq(grn_ctx *ctx, grn_edge *edge)
grn_id rid;
uint16_t keylen = ntohs(header->keylen);
char *key = GRN_BULK_HEAD((grn_obj *)msg);
- cache_init(ctx);
rid = grn_table_get(ctx, cache_table, key, keylen);
if (!rid) {
/* GRN_LOG(ctx, GRN_LOG_NOTICE, "GET k=%d not found", keylen); */
@@ -1655,7 +2153,6 @@ do_mbreq(grn_ctx *ctx, grn_edge *edge)
grn_ntoh(&delta, body, 8);
grn_ntoh(&init, body + 8, 8);
GRN_ASSERT(header->level == 20); /* extralen */
- cache_init(ctx);
if (expire == 0xffffffff) {
rid = grn_table_get(ctx, cache_table, key, keylen);
} else {
@@ -1777,7 +2274,6 @@ do_mbreq(grn_ctx *ctx, grn_edge *edge)
grn_id rid;
uint16_t keylen = ntohs(header->keylen);
char *key = GRN_BULK_HEAD((grn_obj *)msg);
- cache_init(ctx);
rid = grn_table_get(ctx, cache_table, key, keylen);
if (!rid) {
GRN_MSG_MBRES({
@@ -1824,7 +2320,6 @@ do_mbreq(grn_ctx *ctx, grn_edge *edge)
char *key = GRN_BULK_HEAD((grn_obj *)msg);
char *value = key + keylen;
uint32_t valuelen = size - keylen;
- cache_init(ctx);
rid = grn_table_add(ctx, cache_table, key, keylen, NULL);
if (!rid) {
GRN_MSG_MBRES({
@@ -1845,7 +2340,7 @@ do_mbreq(grn_ctx *ctx, grn_edge *edge)
break;
case MBCMD_STAT :
{
- pid_t pid = getpid();
+ pid_t pid = grn_getpid();
GRN_MSG_MBRES({
grn_bulk_write(ctx, re, "pid", 3);
grn_text_itoa(ctx, re, pid);
@@ -1906,31 +2401,44 @@ h_worker(void *arg)
grn_ctx_init(ctx, 0);
grn_ctx_use(ctx, (grn_obj *)arg);
grn_ctx_recv_handler_set(ctx, h_output, &hc);
- GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread start (%d/%d)", nfthreads, nthreads + 1);
- MUTEX_LOCK(q_mutex);
- do {
+ MUTEX_LOCK_ENSURE(ctx, q_mutex);
+ GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread start (%d/%d)",
+ n_floating_threads, n_running_threads);
+ while (n_running_threads <= max_n_floating_threads &&
+ grn_gctx.stat != GRN_CTX_QUIT) {
grn_obj *msg;
- nfthreads++;
+ if (ctx->rc == GRN_CANCEL) {
+ ctx->rc = GRN_SUCCESS;
+ }
+ n_floating_threads++;
while (!(msg = (grn_obj *)grn_com_queue_deque(&grn_gctx, &ctx_new))) {
COND_WAIT(q_cond, q_mutex);
if (grn_gctx.stat == GRN_CTX_QUIT) {
- nfthreads--;
+ n_floating_threads--;
+ goto exit;
+ }
+ if (n_running_threads > max_n_floating_threads) {
+ n_floating_threads--;
goto exit;
}
}
- nfthreads--;
+ n_floating_threads--;
MUTEX_UNLOCK(q_mutex);
hc.msg = (grn_msg *)msg;
hc.in_body = GRN_FALSE;
hc.is_chunked = GRN_FALSE;
- do_htreq(ctx, (grn_msg *)msg);
- MUTEX_LOCK(q_mutex);
- } while (nfthreads < max_nfthreads && grn_gctx.stat != GRN_CTX_QUIT);
+ do_htreq(ctx, &hc);
+ MUTEX_LOCK_ENSURE(ctx, q_mutex);
+ }
exit :
- nthreads--;
- MUTEX_UNLOCK(q_mutex);
- GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread end (%d/%d)", nfthreads, nthreads);
+ n_running_threads--;
+ GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread end (%d/%d)",
+ n_floating_threads, n_running_threads);
+ if (grn_gctx.stat == GRN_CTX_QUIT) {
+ break_accept_event_loop(ctx);
+ }
grn_ctx_fin(ctx);
+ MUTEX_UNLOCK(q_mutex);
return GRN_THREAD_FUNC_RETURN_VALUE;
}
@@ -1947,12 +2455,15 @@ h_handler(grn_ctx *ctx, grn_obj *msg)
/* if not keep alive connection */
grn_com_event_del(ctx, com->ev, fd);
((grn_msg *)msg)->u.fd = fd;
- MUTEX_LOCK(q_mutex);
+ MUTEX_LOCK_ENSURE(ctx, q_mutex);
grn_com_queue_enque(ctx, &ctx_new, (grn_com_queue_entry *)msg);
- if (!nfthreads && nthreads < max_nfthreads) {
+ if (n_floating_threads == 0 && n_running_threads < max_n_floating_threads) {
grn_thread thread;
- nthreads++;
- if (THREAD_CREATE(thread, h_worker, arg)) { SERR("pthread_create"); }
+ n_running_threads++;
+ if (THREAD_CREATE(thread, h_worker, arg)) {
+ n_running_threads--;
+ SERR("pthread_create");
+ }
}
COND_SIGNAL(q_cond);
MUTEX_UNLOCK(q_mutex);
@@ -1965,13 +2476,17 @@ h_server(char *path)
int exit_code = EXIT_FAILURE;
grn_ctx ctx_, *ctx = &ctx_;
grn_ctx_init(ctx, 0);
- MUTEX_INIT(q_mutex);
- COND_INIT(q_cond);
- CRITICAL_SECTION_INIT(cache_lock);
GRN_COM_QUEUE_INIT(&ctx_new);
GRN_COM_QUEUE_INIT(&ctx_old);
check_rlimit_nofile(ctx);
+ GRN_TEXT_INIT(&http_response_server_line, 0);
+ grn_text_printf(ctx,
+ &http_response_server_line,
+ "Server: %s/%s\r\n",
+ grn_get_package_label(),
+ grn_get_version());
exit_code = start_service(ctx, path, NULL, h_handler);
+ GRN_OBJ_FIN(ctx, &http_response_server_line);
grn_ctx_fin(ctx);
return exit_code;
}
@@ -1979,21 +2494,27 @@ h_server(char *path)
static grn_thread_func_result CALLBACK
g_worker(void *arg)
{
- GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread start (%d/%d)", nfthreads, nthreads + 1);
- MUTEX_LOCK(q_mutex);
- do {
+ MUTEX_LOCK_ENSURE(NULL, q_mutex);
+ GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread start (%d/%d)",
+ n_floating_threads, n_running_threads);
+ while (n_running_threads <= max_n_floating_threads &&
+ grn_gctx.stat != GRN_CTX_QUIT) {
grn_ctx *ctx;
grn_edge *edge;
- nfthreads++;
+ n_floating_threads++;
while (!(edge = (grn_edge *)grn_com_queue_deque(&grn_gctx, &ctx_new))) {
COND_WAIT(q_cond, q_mutex);
if (grn_gctx.stat == GRN_CTX_QUIT) {
- nfthreads--;
+ n_floating_threads--;
+ goto exit;
+ }
+ if (n_running_threads > max_n_floating_threads) {
+ n_floating_threads--;
goto exit;
}
}
ctx = &edge->ctx;
- nfthreads--;
+ n_floating_threads--;
if (edge->stat == EDGE_DOING) { continue; }
if (edge->stat == EDGE_WAIT) {
edge->stat = EDGE_DOING;
@@ -2012,6 +2533,9 @@ g_worker(void *arg)
case GRN_COM_PROTO_GQTP :
grn_ctx_send(ctx, GRN_BULK_HEAD(msg), GRN_BULK_VSIZE(msg), header->flags);
ERRCLR(ctx);
+ if (ctx->rc == GRN_CANCEL) {
+ ctx->rc = GRN_SUCCESS;
+ }
break;
default :
ctx->stat = GRN_CTX_QUIT;
@@ -2022,7 +2546,7 @@ g_worker(void *arg)
while ((msg = (grn_obj *)grn_com_queue_deque(ctx, &edge->send_old))) {
grn_msg_close(ctx, msg);
}
- MUTEX_LOCK(q_mutex);
+ MUTEX_LOCK_ENSURE(ctx, q_mutex);
if (ctx->stat == GRN_CTX_QUIT || edge->stat == EDGE_ABORT) { break; }
}
}
@@ -2032,25 +2556,29 @@ g_worker(void *arg)
} else {
edge->stat = EDGE_IDLE;
}
- } while (nfthreads < max_nfthreads && grn_gctx.stat != GRN_CTX_QUIT);
+ };
exit :
- nthreads--;
+ n_running_threads--;
+ GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread end (%d/%d)",
+ n_floating_threads, n_running_threads);
MUTEX_UNLOCK(q_mutex);
- GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread end (%d/%d)", nfthreads, nthreads);
return GRN_THREAD_FUNC_RETURN_VALUE;
}
static void
g_dispatcher(grn_ctx *ctx, grn_edge *edge)
{
- MUTEX_LOCK(q_mutex);
+ MUTEX_LOCK_ENSURE(ctx, q_mutex);
if (edge->stat == EDGE_IDLE) {
grn_com_queue_enque(ctx, &ctx_new, (grn_com_queue_entry *)edge);
edge->stat = EDGE_WAIT;
- if (!nfthreads && nthreads < max_nfthreads) {
+ if (n_floating_threads == 0 && n_running_threads < max_n_floating_threads) {
grn_thread thread;
- nthreads++;
- if (THREAD_CREATE(thread, g_worker, NULL)) { SERR("pthread_create"); }
+ n_running_threads++;
+ if (THREAD_CREATE(thread, g_worker, NULL)) {
+ n_running_threads--;
+ SERR("pthread_create");
+ }
}
COND_SIGNAL(q_cond);
}
@@ -2062,18 +2590,18 @@ g_output(grn_ctx *ctx, int flags, void *arg)
{
grn_edge *edge = arg;
grn_com *com = edge->com;
- grn_msg *req = edge->msg, *msg = (grn_msg *)ctx->impl->outbuf;
+ grn_msg *req = edge->msg, *msg = (grn_msg *)ctx->impl->output.buf;
msg->edge_id = req->edge_id;
msg->header.proto = req->header.proto == GRN_COM_PROTO_MBREQ
? GRN_COM_PROTO_MBRES : req->header.proto;
- if (ctx->rc != GRN_SUCCESS && GRN_BULK_VSIZE(ctx->impl->outbuf) == 0) {
- GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, ctx->errbuf);
+ if (ctx->rc != GRN_SUCCESS && GRN_BULK_VSIZE(ctx->impl->output.buf) == 0) {
+ GRN_TEXT_PUTS(ctx, ctx->impl->output.buf, ctx->errbuf);
}
if (grn_msg_send(ctx, (grn_obj *)msg,
(flags & GRN_CTX_MORE) ? GRN_CTX_MORE : GRN_CTX_TAIL)) {
edge->stat = EDGE_ABORT;
}
- ctx->impl->outbuf = grn_msg_open(ctx, com, &edge->send_old);
+ ctx->impl->output.buf = grn_msg_open(ctx, com, &edge->send_old);
}
static void
@@ -2084,7 +2612,7 @@ g_handler(grn_ctx *ctx, grn_obj *msg)
if (ctx->rc) {
if (com->has_sid) {
if ((edge = com->opaque)) {
- MUTEX_LOCK(q_mutex);
+ MUTEX_LOCK_ENSURE(ctx, q_mutex);
if (edge->stat == EDGE_IDLE) {
grn_com_queue_enque(ctx, &ctx_old, (grn_com_queue_entry *)edge);
}
@@ -2105,8 +2633,9 @@ g_handler(grn_ctx *ctx, grn_obj *msg)
grn_ctx_use(&edge->ctx, (grn_obj *)com->ev->opaque);
grn_ctx_recv_handler_set(&edge->ctx, g_output, edge);
com->opaque = edge;
- grn_obj_close(&edge->ctx, edge->ctx.impl->outbuf);
- edge->ctx.impl->outbuf = grn_msg_open(&edge->ctx, com, &edge->send_old);
+ grn_obj_close(&edge->ctx, edge->ctx.impl->output.buf);
+ edge->ctx.impl->output.buf =
+ grn_msg_open(&edge->ctx, com, &edge->send_old);
edge->com = com;
edge->stat = EDGE_IDLE;
edge->flags = GRN_EDGE_WORKER;
@@ -2126,9 +2655,6 @@ g_server(char *path)
int exit_code = EXIT_FAILURE;
grn_ctx ctx_, *ctx = &ctx_;
grn_ctx_init(ctx, 0);
- MUTEX_INIT(q_mutex);
- COND_INIT(q_cond);
- CRITICAL_SECTION_INIT(cache_lock);
GRN_COM_QUEUE_INIT(&ctx_new);
GRN_COM_QUEUE_INIT(&ctx_old);
check_rlimit_nofile(ctx);
@@ -2151,6 +2677,7 @@ enum {
#define FLAG_MODE_DAEMON (1 << 6)
#define FLAG_MODE_SERVER (1 << 7)
#define FLAG_NEW_DB (1 << 8)
+#define FLAG_USE_WINDOWS_EVENT_LOG (1 << 9)
static uint32_t
get_core_number(void)
@@ -2267,7 +2794,7 @@ config_file_parse(const char *path, const grn_str_getopt_opt *opts,
char *ptr, *name, *value;
size_t name_length, value_length;
- while (isspace(*buf)) {
+ while (isspace((unsigned char)*buf)) {
buf++;
}
@@ -2278,17 +2805,17 @@ config_file_parse(const char *path, const grn_str_getopt_opt *opts,
do {
*ptr-- = '\0';
- } while (ptr >= buf && isspace(*ptr));
+ } while (ptr >= buf && isspace((unsigned char)*ptr));
if (!*buf) {
return CONFIG_FILE_SUCCESS;
}
name = ptr = buf;
- while (*ptr && !isspace(*ptr) && *ptr != '=') {
+ while (*ptr && !isspace((unsigned char)*ptr) && *ptr != '=') {
ptr++;
}
- while (isspace(*ptr)) {
+ while (isspace((unsigned char)*ptr)) {
*ptr++ = '\0';
}
@@ -2303,7 +2830,7 @@ config_file_parse(const char *path, const grn_str_getopt_opt *opts,
if (*ptr == '=') {
*ptr++ = '\0';
- while (isspace(*ptr)) {
+ while (isspace((unsigned char)*ptr)) {
ptr++;
}
value = ptr;
@@ -2370,8 +2897,8 @@ config_file_load(const char *path, const grn_str_getopt_opt *opts, int *flags)
static const int default_http_port = DEFAULT_HTTP_PORT;
static const int default_gqtp_port = DEFAULT_GQTP_PORT;
static grn_encoding default_encoding = GRN_ENC_DEFAULT;
-static uint32_t default_max_num_threads = DEFAULT_MAX_NFTHREADS;
-static const int default_log_level = GRN_LOG_DEFAULT_LEVEL;
+static uint32_t default_max_n_threads = DEFAULT_MAX_N_FLOATING_THREADS;
+static const grn_log_level default_log_level = GRN_LOG_DEFAULT_LEVEL;
static const char * const default_protocol = "gqtp";
static const char *default_hostname = "localhost";
static const char * const default_dest = "localhost";
@@ -2383,6 +2910,7 @@ static grn_command_version default_default_command_version =
GRN_COMMAND_VERSION_DEFAULT;
static int64_t default_default_match_escalation_threshold = 0;
static const char * const default_bind_address = "0.0.0.0";
+static double default_default_request_timeout = 0.0;
static void
init_default_hostname(void)
@@ -2415,9 +2943,9 @@ init_default_settings(void)
default_encoding = grn_encoding_parse(GRN_DEFAULT_ENCODING);
{
- const uint32_t num_cores = get_core_number();
- if (num_cores != 0) {
- default_max_num_threads = num_cores;
+ const uint32_t n_cores = get_core_number();
+ if (n_cores != 0) {
+ default_max_n_threads = n_cores;
}
}
@@ -2436,17 +2964,19 @@ init_default_settings(void)
#ifdef WIN32
{
- static char win32_default_document_root[PATH_MAX];
- size_t document_root_length = strlen(grn_win32_base_dir()) + 1 +
+ static char windows_default_document_root[PATH_MAX];
+ size_t document_root_length = strlen(grn_windows_base_dir()) + 1 +
strlen(GRN_DEFAULT_RELATIVE_DOCUMENT_ROOT) + 1;
if (document_root_length >= PATH_MAX) {
fprintf(stderr, "can't use default root: too long path\n");
} else {
- grn_strcpy(win32_default_document_root, PATH_MAX, grn_win32_base_dir());
- grn_strcat(win32_default_document_root, PATH_MAX, "/");
- grn_strcat(win32_default_document_root, PATH_MAX,
+ grn_strcpy(windows_default_document_root, PATH_MAX,
+ grn_windows_base_dir());
+ grn_strcat(windows_default_document_root, PATH_MAX,
+ "/");
+ grn_strcat(windows_default_document_root, PATH_MAX,
GRN_DEFAULT_RELATIVE_DOCUMENT_ROOT);
- default_document_root = win32_default_document_root;
+ default_document_root = windows_default_document_root;
}
}
#else
@@ -2455,7 +2985,8 @@ init_default_settings(void)
default_default_command_version = grn_get_default_command_version();
default_default_match_escalation_threshold =
- grn_get_default_match_escalation_threshold();
+ grn_get_default_match_escalation_threshold();
+ default_default_request_timeout = grn_get_default_request_timeout();
}
static void
@@ -2498,7 +3029,7 @@ static void
show_version(void)
{
printf("%s %s [",
- grn_get_package(),
+ grn_get_package_label(),
grn_get_version());
/* FIXME: Should we detect host information dynamically on Windows? */
@@ -2534,6 +3065,9 @@ show_version(void)
#ifdef GRN_WITH_LZ4
printf(",lz4");
#endif
+#ifdef GRN_WITH_ZSTD
+ printf(",zstd");
+#endif
#ifdef USE_KQUEUE
printf(",kqueue");
#endif
@@ -2575,7 +3109,7 @@ show_usage(FILE *output)
" --file <path>: read commands from specified file\n"
" --input-fd <FD>: read commands from specified file descriptor\n"
" --file has a prioriry over --input-fd\n"
- " --output-fd <FD>: output response to specifid file descriptor\n"
+ " --output-fd <FD>: output response to specified file descriptor\n"
" -p, --port <port number>: specify server port number (client mode only)\n"
" (default: %d)\n"
"\n"
@@ -2596,10 +3130,26 @@ show_usage(FILE *output)
" specify max number of threads (default: %u)\n"
" --pid-path <path>: specify file to write process ID to\n"
" (daemon mode only)\n"
+ " --default-request-timeout <timeout>:\n"
+ " specify the default request timeout in seconds\n"
+ " (default: %f)\n"
+ " --cache-base-path <path>: specify the cache base path\n"
+ " You can make cache persistent by this option\n"
+ " You must specify path on memory file system\n"
+ " (default: none; disabled)\n"
+ "\n"
+ "Memcached options:\n"
+ " --memcached-column <column>:\n"
+ " specify column to access by memcached protocol\n"
+ " The column must be text type column and\n"
+ " its table must be not NO_KEY table\n"
"\n"
"Logging options:\n"
" -l, --log-level <log level>:\n"
- " specify log level (default: %d)\n"
+ " specify log level\n"
+ " [none|emergency|alert|critical|\n"
+ " error|warning|notice|info|debug|dump]\n"
+ " (default: %s)\n"
" --log-path <path>: specify log path\n"
" (default: %s)\n"
" --log-rotate-threshold-size <threshold>:\n"
@@ -2608,6 +3158,10 @@ show_usage(FILE *output)
" log file size is larger than or\n"
" equals to the threshold\n"
" (default: 0; disabled)\n"
+#ifdef WIN32
+ " --use-windows-event-log:\n"
+ " report logs as Windows events\n"
+#endif /* WIN32 */
" --query-log-path <path>:\n"
" specify query log path\n"
" (default: %s)\n"
@@ -2642,8 +3196,10 @@ show_usage(FILE *output)
grn_encoding_to_string(default_encoding),
default_gqtp_port, default_bind_address,
default_http_port, default_gqtp_port, default_hostname, default_protocol,
- default_document_root, default_cache_limit, default_max_num_threads,
- default_log_level, default_log_path, default_query_log_path,
+ default_document_root, default_cache_limit, default_max_n_threads,
+ default_default_request_timeout,
+ grn_log_level_to_string(default_log_level),
+ default_log_path, default_query_log_path,
default_config_path, default_default_command_version,
(long long int)default_default_match_escalation_threshold,
default_dest);
@@ -2654,7 +3210,7 @@ main(int argc, char **argv)
{
const char *port_arg = NULL;
const char *encoding_arg = NULL;
- const char *max_num_threads_arg = NULL;
+ const char *max_n_threads_arg = NULL;
const char *log_level_arg = NULL;
const char *bind_address_arg = NULL;
const char *hostname_arg = NULL;
@@ -2671,10 +3227,15 @@ main(int argc, char **argv)
const char *output_fd_arg = NULL;
const char *working_directory_arg = NULL;
const char *config_path = NULL;
+ const char *default_request_timeout_arg = NULL;
+ const char *cache_base_path = NULL;
int exit_code = EXIT_SUCCESS;
int i;
int flags = 0;
uint32_t cache_limit = 0;
+ grn_command_version default_command_version;
+ int64_t default_match_escalation_threshold = 0;
+ double default_request_timeout = 0.0;
grn_bool need_line_editor = GRN_FALSE;
static grn_str_getopt_opt opts[] = {
{'p', "port", NULL, 0, GETOPT_OP_NONE},
@@ -2705,11 +3266,16 @@ main(int argc, char **argv)
{'\0', "input-fd", NULL, 0, GETOPT_OP_NONE},
{'\0', "output-fd", NULL, 0, GETOPT_OP_NONE},
{'\0', "working-directory", NULL, 0, GETOPT_OP_NONE},
+ {'\0', "use-windows-event-log", NULL,
+ FLAG_USE_WINDOWS_EVENT_LOG, GETOPT_OP_ON},
+ {'\0', "memcached-column", NULL, 0, GETOPT_OP_NONE},
+ {'\0', "default-request-timeout", NULL, 0, GETOPT_OP_NONE},
+ {'\0', "cache-base-path", NULL, 0, GETOPT_OP_NONE},
{'\0', NULL, NULL, 0, 0}
};
opts[0].arg = &port_arg;
opts[1].arg = &encoding_arg;
- opts[2].arg = &max_num_threads_arg;
+ opts[2].arg = &max_n_threads_arg;
opts[7].arg = &log_level_arg;
opts[8].arg = &hostname_arg;
opts[10].arg = &protocol_arg;
@@ -2728,6 +3294,9 @@ main(int argc, char **argv)
opts[25].arg = &input_fd_arg;
opts[26].arg = &output_fd_arg;
opts[27].arg = &working_directory_arg;
+ opts[29].arg = &memcached_column_name;
+ opts[30].arg = &default_request_timeout_arg;
+ opts[31].arg = &cache_base_path;
reset_ready_notify_pipe();
@@ -2771,6 +3340,10 @@ main(int argc, char **argv)
}
}
+ if (cache_base_path) {
+ grn_set_default_cache_base_path(cache_base_path);
+ }
+
/* ignore mode option in config file */
flags = (flags == ACTION_ERROR) ? 0 : (flags & ~ACTION_MASK);
@@ -2864,6 +3437,7 @@ main(int argc, char **argv)
break;
case 'm' :
case 'M' :
+ is_memcached_mode = GRN_TRUE;
do_client = g_client;
do_server = g_server;
break;
@@ -2877,6 +3451,16 @@ main(int argc, char **argv)
do_server = g_server;
}
+#ifdef WIN32
+ if (flags & FLAG_USE_WINDOWS_EVENT_LOG) {
+ use_windows_event_log = GRN_TRUE;
+ }
+#endif /* WIN32 */
+
+ if (use_windows_event_log) {
+ grn_windows_event_logger_set(NULL, windows_event_source_name);
+ }
+
if (log_path_arg) {
grn_default_logger_set_path(log_path_arg);
}
@@ -2914,69 +3498,50 @@ main(int argc, char **argv)
grn_default_query_logger_set_rotate_threshold_size(value);
}
- if (log_level_arg) {
- const char * const end = log_level_arg + strlen(log_level_arg);
- const char *rest = NULL;
- const int value = grn_atoi(log_level_arg, end, &rest);
- if (end != rest || value < 0 || value > 9) {
- fprintf(stderr, "invalid log level: <%s>\n", log_level_arg);
- return EXIT_FAILURE;
+ {
+ grn_log_level log_level;
+
+ if (log_level_arg) {
+ grn_bool parsed;
+
+ parsed = grn_log_level_parse(log_level_arg, &log_level);
+ if (!parsed) {
+ const char * const end = log_level_arg + strlen(log_level_arg);
+ const char *rest = NULL;
+ const int value = grn_atoi(log_level_arg, end, &rest);
+ if (end != rest || value < GRN_LOG_NONE || value > GRN_LOG_DUMP) {
+ fprintf(stderr, "invalid log level: <%s>\n", log_level_arg);
+ return EXIT_FAILURE;
+ }
+ log_level = value;
+ }
+ } else {
+ log_level = default_log_level;
}
- log_level = value;
- } else {
- log_level = default_log_level;
+
+ grn_default_logger_set_max_level(log_level);
}
- grn_default_logger_set_max_level(log_level);
- if (max_num_threads_arg) {
- const char * const end = max_num_threads_arg + strlen(max_num_threads_arg);
+ if (max_n_threads_arg) {
+ const char * const end = max_n_threads_arg + strlen(max_n_threads_arg);
const char *rest = NULL;
- const uint32_t value = grn_atoui(max_num_threads_arg, end, &rest);
+ const uint32_t value = grn_atoui(max_n_threads_arg, end, &rest);
if (end != rest || value < 1 || value > 100) {
fprintf(stderr, "invalid max number of threads: <%s>\n",
- max_num_threads_arg);
- return EXIT_FAILURE;
- }
- max_nfthreads = value;
- } else {
- max_nfthreads = default_max_num_threads;
- }
-
- if (input_path) {
- if (!freopen(input_path, "r", stdin)) {
- fprintf(stderr, "can't open input file: %s (%s)\n",
- input_path, strerror(errno));
+ max_n_threads_arg);
return EXIT_FAILURE;
}
- batchmode = GRN_TRUE;
+ max_n_floating_threads = value;
} else {
- if (input_fd_arg) {
- const char * const end = input_fd_arg + strlen(input_fd_arg);
- const char *rest = NULL;
- const int input_fd = grn_atoi(input_fd_arg, end, &rest);
- if (rest != end || input_fd == 0) {
- fprintf(stderr, "invalid input FD: <%s>\n", input_fd_arg);
- return EXIT_FAILURE;
- }
- if (dup2(input_fd, STDIN_FILENO) == -1) {
- fprintf(stderr, "can't open input FD: %d (%s)\n",
- input_fd, strerror(errno));
- return EXIT_FAILURE;
- }
- batchmode = GRN_TRUE;
+ if (flags & FLAG_MODE_ALONE) {
+ max_n_floating_threads = 1;
} else {
- if (argc - i > 1) {
- batchmode = GRN_TRUE;
- } else {
- batchmode = !isatty(0);
- }
+ max_n_floating_threads = default_max_n_threads;
}
}
- if ((flags & (FLAG_MODE_ALONE | FLAG_MODE_CLIENT)) &&
- !batchmode) {
- need_line_editor = GRN_TRUE;
- }
+ grn_thread_set_get_limit_func(groonga_get_thread_limit, NULL);
+ grn_thread_set_set_limit_func(groonga_set_thread_limit, NULL);
if (output_fd_arg) {
const char * const end = output_fd_arg + strlen(output_fd_arg);
@@ -3036,18 +3601,7 @@ main(int argc, char **argv)
default_command_version_arg);
return EXIT_FAILURE;
}
- switch (value) {
- case 1 :
- default_command_version = GRN_COMMAND_VERSION_1;
- break;
- case 2 :
- default_command_version = GRN_COMMAND_VERSION_2;
- break;
- default :
- fprintf(stderr, "invalid command version: <%s>\n",
- default_command_version_arg);
- return EXIT_FAILURE;
- }
+ default_command_version = value;
} else {
default_command_version = default_default_command_version;
}
@@ -3078,12 +3632,27 @@ main(int argc, char **argv)
cache_limit = value;
}
-#ifdef GRN_WITH_LIBEDIT
- if (need_line_editor) {
- line_editor_init(argc, argv);
+ if (default_request_timeout_arg) {
+ const char * const end =
+ default_request_timeout_arg + strlen(default_request_timeout_arg);
+ char *rest = NULL;
+ double value;
+ value = strtod(default_request_timeout_arg, &rest);
+ if (end != rest) {
+ fprintf(stderr, "invalid default request timeout: <%s>\n",
+ default_request_timeout_arg);
+ return EXIT_FAILURE;
+ }
+ default_request_timeout = value;
+ } else {
+ default_request_timeout = default_default_request_timeout;
+ }
+
+ grn_gctx.errbuf[0] = '\0';
+ if (grn_init()) {
+ fprintf(stderr, "failed to initialize Groonga: %s\n", grn_gctx.errbuf);
+ return EXIT_FAILURE;
}
-#endif
- if (grn_init()) { return EXIT_FAILURE; }
grn_set_default_encoding(encoding);
@@ -3095,6 +3664,10 @@ main(int argc, char **argv)
grn_set_default_match_escalation_threshold(default_match_escalation_threshold);
}
+ if (default_request_timeout_arg) {
+ grn_set_default_request_timeout(default_request_timeout);
+ }
+
grn_set_segv_handler();
grn_set_int_handler();
grn_set_term_handler();
@@ -3105,6 +3678,62 @@ main(int argc, char **argv)
grn_cache_set_max_n_entries(&grn_gctx, cache, cache_limit);
}
+ MUTEX_INIT(q_mutex);
+ COND_INIT(q_cond);
+
+ if (input_path) {
+ input_reader = grn_file_reader_open(&grn_gctx, input_path);
+ if (!input_reader) {
+ fprintf(stderr, "can't open input file: %s (%s)\n",
+ input_path, strerror(errno));
+ return EXIT_FAILURE;
+ }
+ batchmode = GRN_TRUE;
+ } else {
+ if (input_fd_arg) {
+ const char * const end = input_fd_arg + strlen(input_fd_arg);
+ const char *rest = NULL;
+ const int input_fd = grn_atoi(input_fd_arg, end, &rest);
+ if (rest != end || input_fd == 0) {
+ fprintf(stderr, "invalid input FD: <%s>\n", input_fd_arg);
+ return EXIT_FAILURE;
+ }
+ if (dup2(input_fd, STDIN_FILENO) == -1) {
+ fprintf(stderr, "can't open input FD: %d (%s)\n",
+ input_fd, strerror(errno));
+ return EXIT_FAILURE;
+ }
+ input_reader = grn_file_reader_open(&grn_gctx, "-");
+ if (!input_reader) {
+ fprintf(stderr, "%s", grn_gctx.errbuf);
+ return EXIT_FAILURE;
+ }
+ batchmode = GRN_TRUE;
+ } else {
+ input_reader = grn_file_reader_open(&grn_gctx, "-");
+ if (!input_reader) {
+ fprintf(stderr, "%s", grn_gctx.errbuf);
+ return EXIT_FAILURE;
+ }
+ if (argc - i > 1) {
+ batchmode = GRN_TRUE;
+ } else {
+ batchmode = !grn_isatty(0);
+ }
+ }
+ }
+
+ if ((flags & (FLAG_MODE_ALONE | FLAG_MODE_CLIENT)) &&
+ !batchmode) {
+ need_line_editor = GRN_TRUE;
+ }
+
+#ifdef GRN_WITH_LIBEDIT
+ if (need_line_editor) {
+ line_editor_init(argc, argv);
+ }
+#endif
+
newdb = (flags & FLAG_NEW_DB);
is_daemon_mode = (flags & FLAG_MODE_DAEMON);
if (flags & FLAG_MODE_CLIENT) {
@@ -3115,6 +3744,12 @@ main(int argc, char **argv)
exit_code = do_alone(argc - i, argv + i);
}
+ COND_FIN(q_cond);
+ MUTEX_FIN(q_mutex);
+
+ if (input_reader) {
+ grn_file_reader_close(&grn_gctx, input_reader);
+ }
#ifdef GRN_WITH_LIBEDIT
if (need_line_editor) {
line_editor_fin();
diff --git a/storage/mroonga/vendor/groonga/src/groonga_benchmark.c b/storage/mroonga/vendor/groonga/src/groonga_benchmark.c
index 2ebca387232..77543c2063d 100644
--- a/storage/mroonga/vendor/groonga/src/groonga_benchmark.c
+++ b/storage/mroonga/vendor/groonga/src/groonga_benchmark.c
@@ -146,7 +146,7 @@ struct job {
long long int max;
long long int min;
FILE *outputlog;
- FILE *inputlog;
+ grn_file_reader *inputlog;
char logfile[BUF_LEN];
};
@@ -802,12 +802,12 @@ do_load_command(grn_ctx *ctx, char *command, int type, int task_id,
}
if (test_p(grntest_task[task_id].jobtype)) {
grn_obj log;
- FILE *input;
+ grn_file_reader *input;
FILE *output;
GRN_TEXT_INIT(&log, 0);
input = grntest_job[grntest_task[task_id].job_id].inputlog;
output = grntest_job[grntest_task[task_id].job_id].outputlog;
- if (grn_text_fgets(ctx, &log, input) != GRN_SUCCESS) {
+ if (grn_file_reader_read_line(ctx, input, &log) != GRN_SUCCESS) {
GRN_LOG(ctx, GRN_ERROR, "Cannot get input-log");
error_exit_in_thread(55);
}
@@ -888,12 +888,12 @@ do_command(grn_ctx *ctx, char *command, int type, int task_id)
}
if (test_p(grntest_task[task_id].jobtype)) {
grn_obj log;
- FILE *input;
+ grn_file_reader *input;
FILE *output;
GRN_TEXT_INIT(&log, 0);
input = grntest_job[grntest_task[task_id].job_id].inputlog;
output = grntest_job[grntest_task[task_id].job_id].outputlog;
- if (grn_text_fgets(ctx, &log, input) != GRN_SUCCESS) {
+ if (grn_file_reader_read_line(ctx, input, &log) != GRN_SUCCESS) {
GRN_LOG(ctx, GRN_ERROR, "Cannot get input-log");
error_exit_in_thread(55);
}
@@ -971,10 +971,10 @@ worker_sub(grn_ctx *ctx, grn_obj *log, int task_id)
for (i = 0; i < task->ntimes; i++) {
if (task->file != NULL) {
- FILE *fp;
+ grn_file_reader *reader;
grn_obj line;
- fp = fopen(task->file, "r");
- if (!fp) {
+ reader = grn_file_reader_open(ctx, task->file);
+ if (!reader) {
fprintf(stderr, "Cannot open %s\n",grntest_task[task_id].file);
error_exit_in_thread(1);
}
@@ -982,7 +982,7 @@ worker_sub(grn_ctx *ctx, grn_obj *log, int task_id)
load_count = 0;
load_start = 0LL;
GRN_TEXT_INIT(&line, 0);
- while (grn_text_fgets(ctx, &line, fp) == GRN_SUCCESS) {
+ while (grn_file_reader_read_line(ctx, reader, &line) == GRN_SUCCESS) {
if (GRN_TEXT_VALUE(&line)[GRN_TEXT_LEN(&line) - 1] == '\n') {
grn_bulk_truncate(ctx, &line, GRN_TEXT_LEN(&line) - 1);
}
@@ -1022,7 +1022,7 @@ worker_sub(grn_ctx *ctx, grn_obj *log, int task_id)
}
}
GRN_OBJ_FIN(ctx, &line);
- fclose(fp);
+ grn_file_reader_close(ctx, reader);
} else {
int i, n_commands;
grn_obj *commands;
@@ -1602,7 +1602,7 @@ start_server(const char *dbpath, int r)
}
static int
-parse_line(char *buf, int start, int end, int num)
+parse_line(grn_ctx *ctx, char *buf, int start, int end, int num)
{
int i, j, error_flag = 0, out_or_test = 0;
char tmpbuf[BUF_LEN];
@@ -1758,7 +1758,7 @@ parse_line(char *buf, int start, int end, int num)
}
} else {
char outlog[BUF_LEN];
- grntest_job[num].inputlog = fopen(tmpbuf, "rb");
+ grntest_job[num].inputlog = grn_file_reader_open(ctx, tmpbuf);
if (grntest_job[num].inputlog == NULL) {
fprintf(stderr, "Cannot open %s\n", tmpbuf);
return 14;
@@ -1840,7 +1840,7 @@ get_jobs(grn_ctx *ctx, char *buf, int line)
while (i < len) {
if (buf[i] == ';') {
end = i;
- ret = parse_line(buf, start, end, jnum);
+ ret = parse_line(ctx, buf, start, end, jnum);
if (ret) {
if (ret > 1) {
fprintf(stderr, "Syntax error:line=%d:ret=%d:%s\n", line, ret, buf);
@@ -1854,7 +1854,7 @@ get_jobs(grn_ctx *ctx, char *buf, int line)
i++;
}
end = len;
- ret = parse_line(buf, start, end, jnum);
+ ret = parse_line(ctx, buf, start, end, jnum);
if (ret) {
if (ret > 1) {
fprintf(stderr, "Syntax error:line=%d:ret=%d:%s\n", line, ret, buf);
@@ -1871,7 +1871,6 @@ make_task_table(grn_ctx *ctx, int jobnum)
{
int i, j;
int tid = 0;
- FILE *fp;
grn_obj *commands = NULL;
for (i = 0; i < jobnum; i++) {
@@ -1886,6 +1885,7 @@ make_task_table(grn_ctx *ctx, int jobnum)
}
for (j = 0; j < grntest_job[i].concurrency; j++) {
if (j == 0) {
+ grn_file_reader *reader;
grn_obj line;
GRN_TEXT_INIT(&line, 0);
commands = grn_obj_open(ctx, GRN_PVECTOR, 0, GRN_VOID);
@@ -1893,13 +1893,13 @@ make_task_table(grn_ctx *ctx, int jobnum)
fprintf(stderr, "Cannot alloc commands\n");
error_exit(ctx, 1);
}
- fp = fopen(grntest_job[i].commandfile, "r");
- if (!fp) {
+ reader = grn_file_reader_open(ctx, grntest_job[i].commandfile);
+ if (!reader) {
fprintf(stderr, "Cannot alloc commandfile:%s\n",
grntest_job[i].commandfile);
error_exit(ctx, 1);
}
- while (grn_text_fgets(ctx, &line, fp) == GRN_SUCCESS) {
+ while (grn_file_reader_read_line(ctx, reader, &line) == GRN_SUCCESS) {
grn_obj *command;
if (GRN_TEXT_VALUE(&line)[GRN_TEXT_LEN(&line) - 1] == '\n') {
grn_bulk_truncate(ctx, &line, GRN_TEXT_LEN(&line) - 1);
@@ -1924,6 +1924,7 @@ make_task_table(grn_ctx *ctx, int jobnum)
GRN_PTR_PUT(ctx, commands, command);
GRN_BULK_REWIND(&line);
}
+ grn_file_reader_close(ctx, reader);
GRN_OBJ_FIN(ctx, &line);
}
grntest_task[tid].file = NULL;
@@ -2063,12 +2064,7 @@ printf("%d:type =%d:file=%s:con=%d:ntimes=%d\n", i, grntest_job[i].jobtype,
}
}
if (grntest_job[i].inputlog) {
- int ret;
- ret = fclose(grntest_job[i].inputlog);
- if (ret) {
- fprintf(stderr, "Cannot close %s\n", grntest_job[i].logfile);
- exit(1);
- }
+ grn_file_reader_close(ctx, grntest_job[i].inputlog);
}
}
return qnum;
@@ -2081,17 +2077,17 @@ do_script(grn_ctx *ctx, const char *script_file_path)
int n_lines = 0;
int n_jobs;
int n_queries, total_n_queries = 0;
- FILE *script_file;
+ grn_file_reader *script_file;
grn_obj line;
- script_file = fopen(script_file_path, "r");
+ script_file = grn_file_reader_open(ctx, script_file_path);
if (script_file == NULL) {
fprintf(stderr, "Cannot open script file: <%s>\n", script_file_path);
error_exit(ctx, 1);
}
GRN_TEXT_INIT(&line, 0);
- while (grn_text_fgets(ctx, &line, script_file) == GRN_SUCCESS) {
+ while (grn_file_reader_read_line(ctx, script_file, &line) == GRN_SUCCESS) {
if (grntest_sigint) {
break;
}
@@ -2126,7 +2122,7 @@ do_script(grn_ctx *ctx, const char *script_file_path)
}
grn_obj_unlink(ctx, &line);
- fclose(script_file);
+ grn_file_reader_close(ctx, script_file);
return total_n_queries;
}
@@ -2861,20 +2857,20 @@ get_token(char *line, char *token, int maxlen, char **next)
static grn_bool
check_script(grn_ctx *ctx, const char *script_file_path)
{
- FILE *script_file;
+ grn_file_reader *script_file;
grn_obj line;
char token[BUF_LEN];
char prev[BUF_LEN];
char *next = NULL;
- script_file = fopen(script_file_path, "r");
+ script_file = grn_file_reader_open(ctx, script_file_path);
if (!script_file) {
fprintf(stderr, "Cannot open script file: <%s>\n", script_file_path);
return GRN_FALSE;
}
GRN_TEXT_INIT(&line, 0);
- while (grn_text_fgets(ctx, &line, script_file) == GRN_SUCCESS) {
+ while (grn_file_reader_read_line(ctx, script_file, &line) == GRN_SUCCESS) {
GRN_TEXT_VALUE(&line)[GRN_TEXT_LEN(&line) - 1] = '\0';
get_token(GRN_TEXT_VALUE(&line), token, BUF_LEN, &next);
grn_strcpy(prev, BUF_LEN, token);
@@ -2893,7 +2889,7 @@ check_script(grn_ctx *ctx, const char *script_file_path)
}
grn_obj_unlink(ctx, &line);
- fclose(script_file);
+ grn_file_reader_close(ctx, script_file);
return GRN_TRUE;
}
@@ -3008,7 +3004,7 @@ main(int argc, char **argv)
FILE *pid_file;
pid_file = fopen(pid_path, "w");
if (pid_file) {
- fprintf(pid_file, "%d", getpid());
+ fprintf(pid_file, "%d", grn_getpid());
fclose(pid_file);
} else {
fprintf(stderr,
diff --git a/storage/mroonga/vendor/groonga/src/httpd/Makefile.am b/storage/mroonga/vendor/groonga/src/httpd/Makefile.am
index 88bcc03a33c..736dd1cf939 100644
--- a/storage/mroonga/vendor/groonga/src/httpd/Makefile.am
+++ b/storage/mroonga/vendor/groonga/src/httpd/Makefile.am
@@ -1,6 +1,6 @@
NGINX_DIR = $(top_builddir)/vendor/nginx-$(NGINX_VERSION)
-EXTRA_DIST = \
+EXTRA_DIST = \
nginx-module \
configure
diff --git a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c
index 727e65fa468..15836a92e05 100644
--- a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c
+++ b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2012-2015 Brazil
+ Copyright(C) 2012-2017 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,7 @@
#include <ngx_http.h>
#include <groonga.h>
+#include <groonga/plugin.h>
#include <sys/stat.h>
@@ -47,11 +48,13 @@ typedef struct {
ngx_str_t query_log_path;
ngx_open_file_t *query_log_file;
size_t cache_limit;
+ ngx_msec_t default_request_timeout_msec;
char *config_file;
int config_line;
char *name;
- grn_ctx context;
+ grn_obj *database;
grn_cache *cache;
+ ngx_str_t cache_base_path;
} ngx_http_groonga_loc_conf_t;
typedef struct {
@@ -62,7 +65,7 @@ typedef struct {
typedef struct {
grn_bool initialized;
- grn_ctx context;
+ grn_rc rc;
struct {
grn_bool processed;
grn_bool header_sent;
@@ -78,21 +81,14 @@ typedef struct {
} typed;
} ngx_http_groonga_handler_data_t;
-typedef struct {
- ngx_pool_t *pool;
- ngx_open_file_t *file;
-} ngx_http_groonga_logger_data_t;
-
-typedef struct {
- ngx_pool_t *pool;
- ngx_open_file_t *file;
- ngx_str_t *path;
-} ngx_http_groonga_query_logger_data_t;
-
typedef void (*ngx_http_groonga_loc_conf_callback_pt)(ngx_http_groonga_loc_conf_t *conf, void *user_data);
ngx_module_t ngx_http_groonga_module;
+static grn_ctx ngx_http_groonga_context;
+static grn_ctx *context = &ngx_http_groonga_context;
+static ngx_http_groonga_loc_conf_t *ngx_http_groonga_current_location_conf = NULL;
+
static char *
ngx_str_null_terminate(ngx_pool_t *pool, const ngx_str_t *string)
{
@@ -133,6 +129,29 @@ ngx_str_is_custom_path(ngx_str_t *string)
return GRN_TRUE;
}
+static uint32_t
+ngx_http_groonga_get_thread_limit(void *data)
+{
+ return 1;
+}
+
+static ngx_int_t
+ngx_http_groonga_grn_rc_to_http_status(grn_rc rc)
+{
+ switch (rc) {
+ case GRN_SUCCESS :
+ return NGX_HTTP_OK;
+ case GRN_INVALID_ARGUMENT :
+ case GRN_FUNCTION_NOT_IMPLEMENTED :
+ case GRN_SYNTAX_ERROR :
+ return NGX_HTTP_BAD_REQUEST;
+ case GRN_CANCEL :
+ return NGX_HTTP_REQUEST_TIME_OUT;
+ default :
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+}
+
static void
ngx_http_groonga_write_fd(ngx_fd_t fd,
u_char *buffer, size_t buffer_size,
@@ -163,62 +182,41 @@ ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level,
const char *message, const char *location,
void *user_data)
{
- ngx_http_groonga_logger_data_t *logger_data = user_data;
- const char level_marks[] = " EACewnid-";
+ ngx_open_file_t *file = user_data;
+ char level_marks[] = " EACewnid-";
u_char buffer[NGX_MAX_ERROR_STR];
- u_char *last;
- size_t prefix_size;
- size_t message_size;
- size_t location_size;
- size_t postfix_size;
- size_t log_message_size;
-
-#define LOG_PREFIX_FORMAT "%s|%c|%s "
- prefix_size =
- strlen(timestamp) +
- 1 /* | */ +
- 1 /* %c */ +
- 1 /* | */ +
- strlen(title) +
- 1 /* a space */;
- message_size = strlen(message);
- if (location && *location) {
- location_size = 1 /* a space */ + strlen(location);
- } else {
- location_size = 0;
+
+ if (!file) {
+ return;
}
- postfix_size = 1 /* \n */;
- log_message_size = prefix_size + message_size + location_size + postfix_size;
- if (log_message_size > NGX_MAX_ERROR_STR) {
- last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR,
- LOG_PREFIX_FORMAT,
- timestamp, *(level_marks + level), title);
- ngx_write_fd(logger_data->file->fd, buffer, last - buffer);
- ngx_http_groonga_write_fd(logger_data->file->fd,
+ ngx_http_groonga_write_fd(file->fd,
+ buffer, NGX_MAX_ERROR_STR,
+ timestamp, strlen(timestamp));
+ ngx_write_fd(file->fd, "|", 1);
+ ngx_write_fd(file->fd, level_marks + level, 1);
+ ngx_write_fd(file->fd, "|", 1);
+ if (location && *location) {
+ ngx_http_groonga_write_fd(file->fd,
buffer, NGX_MAX_ERROR_STR,
- message, message_size);
- if (location_size > 0) {
- ngx_write_fd(logger_data->file->fd, " ", 1);
- ngx_http_groonga_write_fd(logger_data->file->fd,
+ location, strlen(location));
+ ngx_write_fd(file->fd, ": ", 2);
+ if (title && *title) {
+ ngx_http_groonga_write_fd(file->fd,
buffer, NGX_MAX_ERROR_STR,
- location, location_size);
+ title, strlen(title));
+ ngx_write_fd(file->fd, " ", 1);
}
- ngx_write_fd(logger_data->file->fd, "\n", 1);
} else {
- if (location && *location) {
- last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR,
- LOG_PREFIX_FORMAT " %s %s\n",
- timestamp, *(level_marks + level), title, message,
- location);
- } else {
- last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR,
- LOG_PREFIX_FORMAT " %s\n",
- timestamp, *(level_marks + level), title, message);
- }
- ngx_write_fd(logger_data->file->fd, buffer, last - buffer);
+ ngx_http_groonga_write_fd(file->fd,
+ buffer, NGX_MAX_ERROR_STR,
+ title, strlen(title));
+ ngx_write_fd(file->fd, " ", 1);
}
-#undef LOG_PREFIX_FORMAT
+ ngx_http_groonga_write_fd(file->fd,
+ buffer, NGX_MAX_ERROR_STR,
+ message, strlen(message));
+ ngx_write_fd(file->fd, "\n", 1);
}
static void
@@ -232,14 +230,11 @@ ngx_http_groonga_logger_reopen(grn_ctx *ctx, void *user_data)
static void
ngx_http_groonga_logger_fin(grn_ctx *ctx, void *user_data)
{
- ngx_http_groonga_logger_data_t *logger_data = user_data;
-
- ngx_pfree(logger_data->pool, logger_data);
}
static grn_logger ngx_http_groonga_logger = {
GRN_LOG_DEFAULT_LEVEL,
- GRN_LOG_TIME | GRN_LOG_MESSAGE,
+ GRN_LOG_TIME | GRN_LOG_MESSAGE | GRN_LOG_PID,
NULL,
ngx_http_groonga_logger_log,
ngx_http_groonga_logger_reopen,
@@ -247,28 +242,17 @@ static grn_logger ngx_http_groonga_logger = {
};
static ngx_int_t
-ngx_http_groonga_context_init_logger(grn_ctx *context,
- ngx_http_groonga_loc_conf_t *location_conf,
+ngx_http_groonga_context_init_logger(ngx_http_groonga_loc_conf_t *location_conf,
ngx_pool_t *pool,
ngx_log_t *log)
{
- ngx_http_groonga_logger_data_t *logger_data;
-
- if (!location_conf->log_file) {
- return NGX_OK;
- }
-
- logger_data = ngx_pcalloc(pool, sizeof(ngx_http_groonga_logger_data_t));
- if (!logger_data) {
- ngx_log_error(NGX_LOG_ERR, log, 0,
- "http_groonga: failed to allocate memory for logger");
- return NGX_ERROR;
+ if (ngx_http_groonga_current_location_conf) {
+ ngx_http_groonga_current_location_conf->log_level =
+ grn_logger_get_max_level(context);
}
- logger_data->pool = pool;
- logger_data->file = location_conf->log_file;
ngx_http_groonga_logger.max_level = location_conf->log_level;
- ngx_http_groonga_logger.user_data = logger_data;
+ ngx_http_groonga_logger.user_data = location_conf->log_file;
grn_logger_set(context, &ngx_http_groonga_logger);
return NGX_OK;
@@ -279,36 +263,29 @@ ngx_http_groonga_query_logger_log(grn_ctx *ctx, unsigned int flag,
const char *timestamp, const char *info,
const char *message, void *user_data)
{
- ngx_http_groonga_query_logger_data_t *data = user_data;
+ ngx_open_file_t *file = user_data;
u_char buffer[NGX_MAX_ERROR_STR];
u_char *last;
+ if (!file) {
+ return;
+ }
+
last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR,
"%s|%s%s\n",
timestamp, info, message);
- ngx_write_fd(data->file->fd, buffer, last - buffer);
+ ngx_write_fd(file->fd, buffer, last - buffer);
}
static void
ngx_http_groonga_query_logger_reopen(grn_ctx *ctx, void *user_data)
{
- ngx_http_groonga_query_logger_data_t *data = user_data;
-
- GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_DESTINATION, " ",
- "query log will be closed: <%.*s>",
- (int)(data->path->len), data->path->data);
ngx_reopen_files((ngx_cycle_t *)ngx_cycle, -1);
- GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_DESTINATION, " ",
- "query log is opened: <%.*s>",
- (int)(data->path->len), data->path->data);
}
static void
ngx_http_groonga_query_logger_fin(grn_ctx *ctx, void *user_data)
{
- ngx_http_groonga_query_logger_data_t *data = user_data;
-
- ngx_pfree(data->pool, data);
}
static grn_query_logger ngx_http_groonga_query_logger = {
@@ -320,71 +297,61 @@ static grn_query_logger ngx_http_groonga_query_logger = {
};
static ngx_int_t
-ngx_http_groonga_context_init_query_logger(grn_ctx *context,
- ngx_http_groonga_loc_conf_t *location_conf,
+ngx_http_groonga_context_init_query_logger(ngx_http_groonga_loc_conf_t *location_conf,
ngx_pool_t *pool,
ngx_log_t *log)
{
- ngx_http_groonga_query_logger_data_t *query_logger_data;
-
- if (!location_conf->query_log_file) {
- return NGX_OK;
- }
-
- query_logger_data = ngx_pcalloc(pool,
- sizeof(ngx_http_groonga_query_logger_data_t));
- if (!query_logger_data) {
- ngx_log_error(NGX_LOG_ERR, log, 0,
- "http_groonga: failed to allocate memory for query logger");
- return NGX_ERROR;
- }
-
- query_logger_data->pool = pool;
- query_logger_data->file = location_conf->query_log_file;
- query_logger_data->path = &(location_conf->query_log_path);
- ngx_http_groonga_query_logger.user_data = query_logger_data;
+ ngx_http_groonga_query_logger.user_data = location_conf->query_log_file;
grn_query_logger_set(context, &ngx_http_groonga_query_logger);
return NGX_OK;
}
static ngx_int_t
-ngx_http_groonga_context_init(grn_ctx *context,
- ngx_http_groonga_loc_conf_t *location_conf,
+ngx_http_groonga_context_init(ngx_http_groonga_loc_conf_t *location_conf,
ngx_pool_t *pool,
ngx_log_t *log)
{
ngx_int_t status;
- grn_ctx_init(context, GRN_NO_FLAGS);
+ if (location_conf == ngx_http_groonga_current_location_conf) {
+ return NGX_OK;
+ }
- status = ngx_http_groonga_context_init_logger(context,
- location_conf,
+ status = ngx_http_groonga_context_init_logger(location_conf,
pool,
log);
if (status == NGX_ERROR) {
- grn_ctx_fin(context);
return status;
}
- status = ngx_http_groonga_context_init_query_logger(context,
- location_conf,
+ status = ngx_http_groonga_context_init_query_logger(location_conf,
pool,
log);
if (status == NGX_ERROR) {
- grn_ctx_fin(context);
return status;
}
- if (location_conf->cache) {
- grn_cache_current_set(context, location_conf->cache);
+ grn_ctx_use(context, location_conf->database);
+ grn_cache_current_set(context, location_conf->cache);
+
+ /* TODO: It doesn't work yet. We need to implement request timeout
+ * handler. */
+ if (location_conf->default_request_timeout_msec == NGX_CONF_UNSET_MSEC) {
+ grn_set_default_request_timeout(0.0);
+ } else {
+ double timeout;
+ timeout = location_conf->default_request_timeout_msec / 1000.0;
+ grn_set_default_request_timeout(timeout);
}
+ ngx_http_groonga_current_location_conf = location_conf;
+
return status;
}
static void
-ngx_http_groonga_context_log_error(ngx_log_t *log, grn_ctx *context)
+ngx_http_groonga_context_log_error(ngx_log_t *log)
{
if (context->rc == GRN_SUCCESS) {
return;
@@ -394,12 +361,12 @@ ngx_http_groonga_context_log_error(ngx_log_t *log, grn_ctx *context)
}
static ngx_int_t
-ngx_http_groonga_context_check_error(ngx_log_t *log, grn_ctx *context)
+ngx_http_groonga_context_check_error(ngx_log_t *log)
{
if (context->rc == GRN_SUCCESS) {
return NGX_OK;
} else {
- ngx_http_groonga_context_log_error(log, context);
+ ngx_http_groonga_context_log_error(log);
return NGX_HTTP_BAD_REQUEST;
}
}
@@ -426,19 +393,14 @@ static void
ngx_http_groonga_handler_cleanup(void *user_data)
{
ngx_http_groonga_handler_data_t *data = user_data;
- grn_ctx *context;
if (!data->initialized) {
return;
}
- context = &(data->context);
GRN_OBJ_FIN(context, &(data->typed.head));
GRN_OBJ_FIN(context, &(data->typed.body));
GRN_OBJ_FIN(context, &(data->typed.foot));
- grn_logger_set(context, NULL);
- grn_query_logger_set(context, NULL);
- grn_ctx_fin(context);
}
static void
@@ -566,7 +528,8 @@ ngx_http_groonga_context_receive_handler_typed(grn_ctx *context,
context->stat |= GRN_CTX_QUIT;
} else {
context->rc = GRN_OPERATION_NOT_PERMITTED;
- GRN_TEXT_PUTS(context, &(data->typed.body), "false");
+ result = "false";
+ result_size = strlen(result);
context->stat &= ~GRN_CTX_QUIT;
}
}
@@ -663,23 +626,20 @@ ngx_http_groonga_handler_create_data(ngx_http_request_t *r,
ngx_http_cleanup_t *cleanup;
ngx_http_groonga_handler_data_t *data;
- grn_ctx *context;
-
location_conf = ngx_http_get_module_loc_conf(r, ngx_http_groonga_module);
+ rc = ngx_http_groonga_context_init(location_conf, r->pool, r->connection->log);
+ if (rc != NGX_OK) {
+ return rc;
+ }
+
cleanup = ngx_http_cleanup_add(r, sizeof(ngx_http_groonga_handler_data_t));
cleanup->handler = ngx_http_groonga_handler_cleanup;
data = cleanup->data;
*data_return = data;
- context = &(data->context);
- rc = ngx_http_groonga_context_init(context, location_conf,
- r->pool, r->connection->log);
- if (rc != NGX_OK) {
- return rc;
- }
-
data->initialized = GRN_TRUE;
+ data->rc = GRN_SUCCESS;
data->raw.processed = GRN_FALSE;
data->raw.header_sent = GRN_FALSE;
@@ -692,8 +652,8 @@ ngx_http_groonga_handler_create_data(ngx_http_request_t *r,
GRN_TEXT_INIT(&(data->typed.body), GRN_NO_FLAGS);
GRN_TEXT_INIT(&(data->typed.foot), GRN_NO_FLAGS);
- grn_ctx_use(context, grn_ctx_db(&(location_conf->context)));
- rc = ngx_http_groonga_context_check_error(r->connection->log, context);
+ grn_ctx_use(context, location_conf->database);
+ rc = ngx_http_groonga_context_check_error(r->connection->log);
if (rc != NGX_OK) {
return rc;
}
@@ -705,32 +665,28 @@ ngx_http_groonga_handler_create_data(ngx_http_request_t *r,
return NGX_OK;
}
-static ngx_int_t
+static void
ngx_http_groonga_handler_process_command_path(ngx_http_request_t *r,
ngx_str_t *command_path,
- ngx_http_groonga_handler_data_t *data)
+ ngx_http_groonga_handler_data_t *data,
+ int flags)
{
- grn_ctx *context;
grn_obj uri;
- context = &(data->context);
GRN_TEXT_INIT(&uri, 0);
GRN_TEXT_PUTS(context, &uri, "/d/");
GRN_TEXT_PUT(context, &uri, command_path->data, command_path->len);
- grn_ctx_send(context, GRN_TEXT_VALUE(&uri), GRN_TEXT_LEN(&uri),
- GRN_NO_FLAGS);
- ngx_http_groonga_context_log_error(r->connection->log, context);
+ grn_ctx_send(context, GRN_TEXT_VALUE(&uri), GRN_TEXT_LEN(&uri), flags);
+ data->rc = context->rc;
+ ngx_http_groonga_context_log_error(r->connection->log);
GRN_OBJ_FIN(context, &uri);
-
- return NGX_OK;
}
-static ngx_int_t
+static grn_bool
ngx_http_groonga_handler_validate_post_command(ngx_http_request_t *r,
ngx_str_t *command_path,
ngx_http_groonga_handler_data_t *data)
{
- grn_ctx *context;
ngx_str_t command;
command.data = command_path->data;
@@ -740,166 +696,180 @@ ngx_http_groonga_handler_validate_post_command(ngx_http_request_t *r,
command.len = command_path->len - r->args.len - strlen("?");
}
if (ngx_str_equal_c_string(&command, "load")) {
- return NGX_OK;
+ return GRN_TRUE;
}
- context = &(data->context);
+ data->rc = GRN_INVALID_ARGUMENT;
ngx_http_groonga_handler_set_content_type(r, "text/plain");
GRN_TEXT_PUTS(context, &(data->typed.body),
"command for POST must be <load>: <");
GRN_TEXT_PUT(context, &(data->typed.body), command.data, command.len);
GRN_TEXT_PUTS(context, &(data->typed.body), ">");
- return NGX_HTTP_BAD_REQUEST;
-}
-
-static ngx_int_t
-ngx_http_groonga_send_lines(grn_ctx *context,
- ngx_http_request_t *r,
- u_char *current,
- u_char *last)
-{
- ngx_int_t rc;
-
- u_char *line_start;
-
- for (line_start = current; current < last; current++) {
- if (*current != '\n') {
- continue;
- }
-
- grn_ctx_send(context, (const char *)line_start, current - line_start,
- GRN_NO_FLAGS);
- rc = ngx_http_groonga_context_check_error(r->connection->log, context);
- if (rc != NGX_OK) {
- return rc;
- }
- line_start = current + 1;
- }
- if (line_start < current) {
- grn_ctx_send(context, (const char *)line_start, current - line_start,
- GRN_NO_FLAGS);
- rc = ngx_http_groonga_context_check_error(r->connection->log, context);
- if (rc != NGX_OK) {
- return rc;
- }
- }
-
- return NGX_OK;
+ return GRN_FALSE;
}
-static ngx_int_t
-ngx_http_groonga_join_request_body_chain(ngx_http_request_t *r,
- ngx_chain_t *chain,
- u_char **out_start,
- u_char **out_end)
+static void
+ngx_http_groonga_send_body(ngx_http_request_t *r,
+ ngx_http_groonga_handler_data_t *data)
{
- ngx_int_t rc;
-
- ngx_log_t *log = r->connection->log;
-
- ngx_chain_t *current;
- u_char *out;
- size_t out_size;
+ ngx_log_t *log;
+ grn_obj line_buffer;
+ size_t line_start_offset;
+ size_t line_check_start_offset;
+ ngx_chain_t *chain;
+ size_t line_buffer_chunk_size = 4096;
- u_char *out_cursor;
- ngx_buf_t *buffer;
- size_t buffer_size;
+ log = r->connection->log;
- out_size = 0;
- for (current = chain; current; current = current->next) {
- out_size += ngx_buf_size(current->buf);
- }
- out = ngx_palloc(r->pool, out_size);
- if (!out) {
- ngx_log_error(NGX_LOG_ERR, log, 0,
- "http_groonga: failed to allocate memory for request body");
- return NGX_ERROR;
- }
+ GRN_TEXT_INIT(&line_buffer, 0);
+ line_start_offset = 0;
+ line_check_start_offset = 0;
+ for (chain = r->request_body->bufs; chain; chain = chain->next) {
+ ngx_buf_t *buffer;
+ size_t rest_buffer_size;
+ off_t offset;
+
+ buffer = chain->buf;
+ rest_buffer_size = ngx_buf_size(buffer);
+ offset = 0;
+ while (rest_buffer_size > 0) {
+ size_t current_buffer_size;
+
+ if (rest_buffer_size > line_buffer_chunk_size) {
+ current_buffer_size = line_buffer_chunk_size;
+ } else {
+ current_buffer_size = rest_buffer_size;
+ }
- out_cursor = out;
- for (current = chain; current; current = current->next) {
- buffer = current->buf;
- buffer_size = ngx_buf_size(current->buf);
+ if (ngx_buf_in_memory(buffer)) {
+ GRN_TEXT_PUT(context,
+ &line_buffer,
+ buffer->pos + offset,
+ current_buffer_size);
+ } else {
+ ngx_int_t rc;
+ grn_bulk_reserve(context, &line_buffer, current_buffer_size);
+ rc = ngx_read_file(buffer->file,
+ (u_char *)GRN_BULK_CURR(&line_buffer),
+ current_buffer_size,
+ offset);
+ if (rc < 0) {
+ GRN_PLUGIN_ERROR(context,
+ GRN_INPUT_OUTPUT_ERROR,
+ "[nginx][post][body][read] "
+ "failed to read a request body from file");
+ goto exit;
+ }
+ GRN_BULK_INCR_LEN(&line_buffer, current_buffer_size);
+ }
+ offset += current_buffer_size;
+ rest_buffer_size -= current_buffer_size;
+
+ {
+ const char *line_start;
+ const char *line_current;
+ const char *line_end;
+
+ line_start = GRN_TEXT_VALUE(&line_buffer) + line_start_offset;
+ line_end = GRN_TEXT_VALUE(&line_buffer) + GRN_TEXT_LEN(&line_buffer);
+ for (line_current = line_start + line_check_start_offset;
+ line_current < line_end;
+ line_current++) {
+ size_t line_length;
+ int flags = GRN_NO_FLAGS;
+
+ if (*line_current != '\n') {
+ continue;
+ }
+
+ line_length = line_current - line_start + 1;
+ if (line_current + 1 == line_end &&
+ !chain->next &&
+ rest_buffer_size == 0) {
+ flags |= GRN_CTX_TAIL;
+ }
+ grn_ctx_send(context, line_start, line_length, flags);
+ line_start_offset += line_length;
+ line_start += line_length;
+ ngx_http_groonga_context_log_error(log);
+ if (context->rc != GRN_SUCCESS && data->rc == GRN_SUCCESS) {
+ data->rc = context->rc;
+ }
+ }
- if (buffer->file) {
- rc = ngx_read_file(buffer->file, out_cursor, buffer_size, 0);
- if (rc < 0) {
- ngx_log_error(NGX_LOG_ERR, log, 0,
- "http_groonga: failed to read a request body stored in a file");
- return rc;
+ if (line_start_offset == 0) {
+ line_buffer_chunk_size *= 2;
+ line_check_start_offset = GRN_TEXT_LEN(&line_buffer);
+ } else if ((size_t)GRN_TEXT_LEN(&line_buffer) == line_start_offset) {
+ GRN_BULK_REWIND(&line_buffer);
+ line_start_offset = 0;
+ line_check_start_offset = 0;
+ } else {
+ size_t rest_line_size;
+ rest_line_size = GRN_TEXT_LEN(&line_buffer) - line_start_offset;
+ grn_memmove(GRN_TEXT_VALUE(&line_buffer),
+ GRN_TEXT_VALUE(&line_buffer) + line_start_offset,
+ rest_line_size);
+ grn_bulk_truncate(context, &line_buffer, rest_line_size);
+ line_start_offset = 0;
+ line_check_start_offset = GRN_TEXT_LEN(&line_buffer);
+ }
}
- } else {
- ngx_memcpy(out_cursor, buffer->pos, buffer_size);
}
- out_cursor += buffer_size;
}
- *out_start = out;
- *out_end = out + out_size;
+ if (GRN_TEXT_LEN(&line_buffer) > 0) {
+ grn_ctx_send(context,
+ GRN_TEXT_VALUE(&line_buffer),
+ GRN_TEXT_LEN(&line_buffer),
+ GRN_CTX_TAIL);
+ ngx_http_groonga_context_log_error(log);
+ if (context->rc != GRN_SUCCESS && data->rc == GRN_SUCCESS) {
+ data->rc = context->rc;
+ }
+ }
- return NGX_OK;
+exit :
+ GRN_OBJ_FIN(context, &line_buffer);
}
-static ngx_int_t
+static void
ngx_http_groonga_handler_process_body(ngx_http_request_t *r,
ngx_http_groonga_handler_data_t *data)
{
- ngx_int_t rc;
-
- grn_ctx *context;
-
ngx_buf_t *body;
- u_char *body_data;
- u_char *body_data_end;
-
- context = &(data->context);
body = r->request_body->bufs->buf;
if (!body) {
+ data->rc = GRN_INVALID_ARGUMENT;
ngx_http_groonga_handler_set_content_type(r, "text/plain");
GRN_TEXT_PUTS(context, &(data->typed.body), "must send load data as body");
- return NGX_HTTP_BAD_REQUEST;
- }
-
- rc = ngx_http_groonga_join_request_body_chain(r,
- r->request_body->bufs,
- &body_data,
- &body_data_end);
- if (rc != NGX_OK) {
- return rc;
+ return;
}
- rc = ngx_http_groonga_send_lines(context, r, body_data, body_data_end);
- ngx_pfree(r->pool, body_data);
-
- return rc;
+ ngx_http_groonga_send_body(r, data);
}
-static ngx_int_t
+static void
ngx_http_groonga_handler_process_load(ngx_http_request_t *r,
ngx_str_t *command_path,
ngx_http_groonga_handler_data_t *data)
{
- ngx_int_t rc;
-
- rc = ngx_http_groonga_handler_validate_post_command(r, command_path, data);
- if (rc != NGX_OK) {
- return rc;
- }
-
- rc = ngx_http_groonga_handler_process_command_path(r, command_path, data);
- if (rc != NGX_OK) {
- return rc;
+ if (!ngx_http_groonga_handler_validate_post_command(r, command_path, data)) {
+ return;
}
- rc = ngx_http_groonga_handler_process_body(r, data);
- if (rc != NGX_OK) {
- return rc;
+ ngx_http_groonga_handler_process_command_path(r,
+ command_path,
+ data,
+ GRN_NO_FLAGS);
+ if (data->rc != GRN_SUCCESS) {
+ return;
}
- return NGX_OK;
+ ngx_http_groonga_handler_process_body(r, data);
}
static ngx_chain_t *
@@ -931,7 +901,6 @@ ngx_http_groonga_handler_send_response(ngx_http_request_t *r,
ngx_http_groonga_handler_data_t *data)
{
ngx_int_t rc;
- grn_ctx *context;
const char *content_type;
ngx_buf_t *head_buf, *body_buf, *foot_buf;
ngx_chain_t head_chain, body_chain, foot_chain;
@@ -941,11 +910,16 @@ ngx_http_groonga_handler_send_response(ngx_http_request_t *r,
return data->raw.rc;
}
- context = &(data->context);
-
/* set the 'Content-type' header */
if (r->headers_out.content_type.len == 0) {
- content_type = grn_ctx_get_mime_type(context);
+ grn_obj *foot = &(data->typed.foot);
+ if (grn_ctx_get_output_type(context) == GRN_CONTENT_JSON &&
+ GRN_TEXT_LEN(foot) > 0 &&
+ GRN_TEXT_VALUE(foot)[GRN_TEXT_LEN(foot) - 1] == ';') {
+ content_type = "application/javascript";
+ } else {
+ content_type = grn_ctx_get_mime_type(context);
+ }
ngx_http_groonga_handler_set_content_type(r, content_type);
}
@@ -974,7 +948,7 @@ ngx_http_groonga_handler_send_response(ngx_http_request_t *r,
output_chain = ngx_http_groonga_attach_chain(output_chain, &foot_chain);
/* set the status line */
- r->headers_out.status = NGX_HTTP_OK;
+ r->headers_out.status = ngx_http_groonga_grn_rc_to_http_status(data->rc);
r->headers_out.content_length_n = GRN_TEXT_LEN(&(data->typed.head)) +
GRN_TEXT_LEN(&(data->typed.body)) +
GRN_TEXT_LEN(&(data->typed.foot));
@@ -1012,10 +986,10 @@ ngx_http_groonga_handler_get(ngx_http_request_t *r)
return rc;
}
- rc = ngx_http_groonga_handler_process_command_path(r, &command_path, data);
- if (rc != NGX_OK) {
- return rc;
- }
+ ngx_http_groonga_handler_process_command_path(r,
+ &command_path,
+ data,
+ GRN_CTX_TAIL);
/* discard request body, since we don't need it here */
rc = ngx_http_discard_request_body(r);
@@ -1058,13 +1032,8 @@ ngx_http_groonga_handler_post(ngx_http_request_t *r)
return;
}
- rc = ngx_http_groonga_handler_process_load(r, &command_path, data);
- if (rc != NGX_OK) {
- ngx_http_groonga_handler_post_send_error_response(r, rc);
- return;
- }
-
- ngx_http_groonga_handler_send_response(r, data);
+ ngx_http_groonga_handler_process_load(r, &command_path, data);
+ rc = ngx_http_groonga_handler_send_response(r, data);
ngx_http_finalize_request(r, rc);
}
@@ -1162,29 +1131,9 @@ ngx_http_groonga_conf_set_log_level_slot(ngx_conf_t *cf, ngx_command_t *cmd,
value = ngx_str_null_terminate(cf->cycle->pool,
((ngx_str_t *)cf->args->elts) + 1);
- if (strcasecmp(value, "none") == 0) {
- groonga_location_conf->log_level = GRN_LOG_NONE;
- } else if (strcasecmp(value, "emergency") == 0) {
- groonga_location_conf->log_level = GRN_LOG_EMERG;
- } else if (strcasecmp(value, "alert") == 0) {
- groonga_location_conf->log_level = GRN_LOG_ALERT;
- } else if (strcasecmp(value, "critical") == 0) {
- groonga_location_conf->log_level = GRN_LOG_CRIT;
- } else if (strcasecmp(value, "error") == 0) {
- groonga_location_conf->log_level = GRN_LOG_ERROR;
- } else if (strcasecmp(value, "warning") == 0) {
- groonga_location_conf->log_level = GRN_LOG_WARNING;
- } else if (strcasecmp(value, "notice") == 0) {
- groonga_location_conf->log_level = GRN_LOG_NOTICE;
- } else if (strcasecmp(value, "info") == 0) {
- groonga_location_conf->log_level = GRN_LOG_INFO;
- } else if (strcasecmp(value, "debug") == 0) {
- groonga_location_conf->log_level = GRN_LOG_DEBUG;
- } else if (strcasecmp(value, "dump") == 0) {
- groonga_location_conf->log_level = GRN_LOG_DUMP;
- } else {
+ if (!grn_log_level_parse(value, &(groonga_location_conf->log_level))) {
status = "must be one of 'none', 'emergency', 'alert', "
- "'ciritical', 'error', 'warning', 'notice', 'info', 'debug' and 'dump'";
+ "'critical', 'error', 'warning', 'notice', 'info', 'debug' and 'dump'";
}
ngx_pfree(cf->cycle->pool, value);
@@ -1216,7 +1165,7 @@ ngx_http_groonga_conf_set_query_log_path_slot(ngx_conf_t *cf,
ngx_conf_open_file(cf->cycle, &(groonga_location_conf->query_log_path));
if (!groonga_location_conf->query_log_file) {
ngx_log_error(NGX_LOG_ERR, cf->cycle->log, 0,
- "http_groonga: failed to open groonga query log file: <%V>",
+ "http_groonga: failed to open Groonga query log file: <%V>",
&(groonga_location_conf->query_log_path));
return NGX_CONF_ERROR;
}
@@ -1251,6 +1200,8 @@ ngx_http_groonga_create_loc_conf(ngx_conf_t *cf)
conf->config_file = NULL;
conf->config_line = 0;
conf->cache = NULL;
+ conf->cache_base_path.data = NULL;
+ conf->cache_base_path.len = 0;
return conf;
}
@@ -1260,6 +1211,11 @@ ngx_http_groonga_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_http_groonga_loc_conf_t *prev = parent;
ngx_http_groonga_loc_conf_t *conf = child;
+ ngx_flag_t enabled = 0;
+
+ if (conf->enabled != NGX_CONF_UNSET) {
+ enabled = conf->enabled;
+ }
ngx_conf_merge_str_value(conf->database_path, prev->database_path, NULL);
ngx_conf_merge_value(conf->database_auto_create,
@@ -1269,16 +1225,17 @@ ngx_http_groonga_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
GRN_CACHE_DEFAULT_MAX_N_ENTRIES);
#ifdef NGX_HTTP_GROONGA_LOG_PATH
- if (!conf->log_file) {
- ngx_str_t default_log_path;
- default_log_path.data = (u_char *)NGX_HTTP_GROONGA_LOG_PATH;
- default_log_path.len = strlen(NGX_HTTP_GROONGA_LOG_PATH);
- conf->log_file = ngx_conf_open_file(cf->cycle, &default_log_path);
+ ngx_conf_merge_str_value(conf->log_path, prev->log_path,
+ NGX_HTTP_GROONGA_LOG_PATH);
+ if (!conf->log_file &&
+ ngx_str_is_custom_path(&(conf->log_path)) &&
+ enabled) {
+ conf->log_file = ngx_conf_open_file(cf->cycle, &(conf->log_path));
if (!conf->log_file) {
ngx_log_error(NGX_LOG_ERR, cf->cycle->log, 0,
"http_groonga: "
- "failed to open the default groonga log file: <%V>",
- &default_log_path);
+ "failed to open the default Groonga log file: <%V>",
+ &(conf->log_path));
return NGX_CONF_ERROR;
}
}
@@ -1288,18 +1245,22 @@ ngx_http_groonga_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
NGX_HTTP_GROONGA_QUERY_LOG_PATH);
if (!conf->query_log_file &&
ngx_str_is_custom_path(&(conf->query_log_path)) &&
- conf->enabled) {
+ enabled) {
conf->query_log_file = ngx_conf_open_file(cf->cycle,
&(conf->query_log_path));
if (!conf->query_log_file) {
ngx_log_error(NGX_LOG_ERR, cf->cycle->log, 0,
"http_groonga: "
- "failed to open the default groonga query log file: <%V>",
+ "failed to open the default Groonga query log file: <%V>",
&(conf->query_log_path));
return NGX_CONF_ERROR;
}
}
+ ngx_conf_merge_str_value(conf->cache_base_path,
+ prev->cache_base_path,
+ NULL);
+
return NGX_CONF_OK;
}
@@ -1351,6 +1312,41 @@ ngx_http_groonga_each_loc_conf(ngx_http_conf_ctx_t *http_conf,
ngx_http_groonga_each_loc_conf_in_tree(location_conf->static_locations,
callback,
user_data);
+
+#if NGX_PCRE
+ if (location_conf->regex_locations) {
+ ngx_uint_t j;
+ for (j = 0; location_conf->regex_locations[j]; j++) {
+ ngx_http_core_loc_conf_t *regex_location_conf;
+
+ regex_location_conf = location_conf->regex_locations[j];
+ if (regex_location_conf->handler == ngx_http_groonga_handler) {
+ callback(regex_location_conf->loc_conf[ngx_http_groonga_module.ctx_index],
+ user_data);
+ }
+ }
+ }
+#endif
+ }
+}
+
+static void
+ngx_http_groonga_set_logger_callback(ngx_http_groonga_loc_conf_t *location_conf,
+ void *user_data)
+{
+ ngx_http_groonga_database_callback_data_t *data = user_data;
+
+ data->rc = ngx_http_groonga_context_init_logger(location_conf,
+ data->pool,
+ data->log);
+ if (data->rc != NGX_OK) {
+ return;
+ }
+ data->rc = ngx_http_groonga_context_init_query_logger(location_conf,
+ data->pool,
+ data->log);
+ if (data->rc != NGX_OK) {
+ return;
}
}
@@ -1387,7 +1383,6 @@ ngx_http_groonga_create_database(ngx_http_groonga_loc_conf_t *location_conf,
ngx_http_groonga_database_callback_data_t *data)
{
const char *database_base_name;
- grn_ctx *context;
database_base_name = strrchr(location_conf->database_path_cstr, '/');
if (database_base_name) {
@@ -1402,14 +1397,14 @@ ngx_http_groonga_create_database(ngx_http_groonga_loc_conf_t *location_conf,
}
}
- context = &(location_conf->context);
- grn_db_create(context, location_conf->database_path_cstr, NULL);
+ location_conf->database =
+ grn_db_create(context, location_conf->database_path_cstr, NULL);
if (context->rc == GRN_SUCCESS) {
return;
}
ngx_log_error(NGX_LOG_EMERG, data->log, 0,
- "failed to create groonga database: %s",
+ "failed to create Groonga database: %s",
context->errbuf);
data->rc = NGX_ERROR;
}
@@ -1419,11 +1414,16 @@ ngx_http_groonga_open_database_callback(ngx_http_groonga_loc_conf_t *location_co
void *user_data)
{
ngx_http_groonga_database_callback_data_t *data = user_data;
- grn_ctx *context;
- context = &(location_conf->context);
- data->rc = ngx_http_groonga_context_init(context, location_conf,
- data->pool, data->log);
+ data->rc = ngx_http_groonga_context_init_logger(location_conf,
+ data->pool,
+ data->log);
+ if (data->rc != NGX_OK) {
+ return;
+ }
+ data->rc = ngx_http_groonga_context_init_query_logger(location_conf,
+ data->pool,
+ data->log);
if (data->rc != NGX_OK) {
return;
}
@@ -1443,27 +1443,41 @@ ngx_http_groonga_open_database_callback(ngx_http_groonga_loc_conf_t *location_co
ngx_str_null_terminate(data->pool, &(location_conf->database_path));
}
- grn_db_open(context, location_conf->database_path_cstr);
+ location_conf->database =
+ grn_db_open(context, location_conf->database_path_cstr);
if (context->rc != GRN_SUCCESS) {
if (location_conf->database_auto_create) {
ngx_http_groonga_create_database(location_conf, data);
} else {
ngx_log_error(NGX_LOG_EMERG, data->log, 0,
- "failed to open groonga database: %s",
+ "failed to open Groonga database: %s",
context->errbuf);
data->rc = NGX_ERROR;
+ }
+ if (data->rc != NGX_OK) {
return;
}
}
- location_conf->cache = grn_cache_open(context);
+ if (location_conf->cache_base_path.data &&
+ ngx_str_is_custom_path(&(location_conf->cache_base_path))) {
+ char cache_base_path[PATH_MAX];
+ grn_memcpy(cache_base_path,
+ location_conf->cache_base_path.data,
+ location_conf->cache_base_path.len);
+ cache_base_path[location_conf->cache_base_path.len] = '\0';
+ location_conf->cache = grn_persistent_cache_open(context, cache_base_path);
+ } else {
+ location_conf->cache = grn_cache_open(context);
+ }
if (!location_conf->cache) {
ngx_log_error(NGX_LOG_EMERG, data->log, 0,
- "failed to open groonga cache: %s",
+ "failed to open Groonga cache: %s",
context->errbuf);
data->rc = NGX_ERROR;
return;
}
+
if (location_conf->cache_limit != NGX_CONF_UNSET_SIZE) {
grn_cache_set_max_n_entries(context,
location_conf->cache,
@@ -1476,26 +1490,20 @@ ngx_http_groonga_close_database_callback(ngx_http_groonga_loc_conf_t *location_c
void *user_data)
{
ngx_http_groonga_database_callback_data_t *data = user_data;
- grn_ctx *context;
- context = &(location_conf->context);
- ngx_http_groonga_context_init_logger(context,
- location_conf,
+ ngx_http_groonga_context_init_logger(location_conf,
data->pool,
data->log);
- ngx_http_groonga_context_init_query_logger(context,
- location_conf,
+ ngx_http_groonga_context_init_query_logger(location_conf,
data->pool,
data->log);
grn_cache_current_set(context, location_conf->cache);
- grn_obj_close(context, grn_ctx_db(context));
- ngx_http_groonga_context_log_error(data->log, context);
+ grn_obj_close(context, location_conf->database);
+ ngx_http_groonga_context_log_error(data->log);
grn_cache_current_set(context, NULL);
grn_cache_close(context, location_conf->cache);
-
- grn_ctx_fin(context);
}
static ngx_int_t
@@ -1505,12 +1513,11 @@ ngx_http_groonga_init_process(ngx_cycle_t *cycle)
ngx_http_conf_ctx_t *http_conf;
ngx_http_groonga_database_callback_data_t data;
- rc = grn_init();
- if (rc != GRN_SUCCESS) {
- return NGX_ERROR;
- }
+ grn_thread_set_get_limit_func(ngx_http_groonga_get_thread_limit, NULL);
- grn_set_segv_handler();
+#ifdef NGX_HTTP_GROONGA_LOG_PATH
+ grn_default_logger_set_path(NGX_HTTP_GROONGA_LOG_PATH);
+#endif
http_conf =
(ngx_http_conf_ctx_t *)ngx_get_conf(cycle->conf_ctx, ngx_http_module);
@@ -1519,6 +1526,26 @@ ngx_http_groonga_init_process(ngx_cycle_t *cycle)
data.pool = cycle->pool;
data.rc = NGX_OK;
ngx_http_groonga_each_loc_conf(http_conf,
+ ngx_http_groonga_set_logger_callback,
+ &data);
+
+ if (data.rc != NGX_OK) {
+ return data.rc;
+ }
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ return NGX_ERROR;
+ }
+
+ grn_set_segv_handler();
+
+ rc = grn_ctx_init(context, GRN_NO_FLAGS);
+ if (rc != GRN_SUCCESS) {
+ return NGX_ERROR;
+ }
+
+ ngx_http_groonga_each_loc_conf(http_conf,
ngx_http_groonga_open_database_callback,
&data);
@@ -1539,6 +1566,8 @@ ngx_http_groonga_exit_process(ngx_cycle_t *cycle)
ngx_http_groonga_close_database_callback,
&data);
+ grn_ctx_fin(context);
+
grn_fin();
return;
@@ -1602,6 +1631,20 @@ static ngx_command_t ngx_http_groonga_commands[] = {
offsetof(ngx_http_groonga_loc_conf_t, cache_limit),
NULL },
+ { ngx_string("groonga_default_request_timeout"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_groonga_loc_conf_t, default_request_timeout_msec),
+ NULL },
+
+ { ngx_string("groonga_cache_base_path"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_groonga_loc_conf_t, cache_base_path),
+ NULL },
+
ngx_null_command
};
diff --git a/storage/mroonga/vendor/groonga/src/suggest/CMakeLists.txt b/storage/mroonga/vendor/groonga/src/suggest/CMakeLists.txt
index c0c7a9c9964..83ae26b8ce5 100644
--- a/storage/mroonga/vendor/groonga/src/suggest/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/src/suggest/CMakeLists.txt
@@ -15,7 +15,8 @@
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../../lib
- ${MRUBY_INCLUDE_DIRS})
+ ${MRUBY_INCLUDE_DIRS}
+ ${MESSAGE_PACK_INCLUDE_DIRS})
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/create_dataset_sources.am
GROONGA_SUGGEST_CREATE_DATASET_SOURCES)
diff --git a/storage/mroonga/vendor/groonga/src/suggest/Makefile.am b/storage/mroonga/vendor/groonga/src/suggest/Makefile.am
index cecf4001e9a..91260016fa8 100644
--- a/storage/mroonga/vendor/groonga/src/suggest/Makefile.am
+++ b/storage/mroonga/vendor/groonga/src/suggest/Makefile.am
@@ -2,7 +2,6 @@ bin_PROGRAMS =
NONEXISTENT_CXX_SOURCE = nonexistent.cpp
-if !PLATFORM_WIN32
bin_PROGRAMS += \
groonga-suggest-create-dataset
@@ -13,8 +12,6 @@ bin_PROGRAMS += \
noinst_LTLIBRARIES = libutil.la
endif
-endif
-
EXTRA_DIST = \
CMakeLists.txt
diff --git a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_create_dataset.c b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_create_dataset.c
index d566d24b96a..7220ca88ec5 100644
--- a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_create_dataset.c
+++ b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_create_dataset.c
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2010-2013 Brazil
+/* Copyright(C) 2010-2015 Brazil
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,14 +15,14 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/* For grn_str_getopt() */
+#include <grn_str.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <groonga.h>
-/* For grn_str_getopt() */
-#include <grn_str.h>
-
typedef enum {
MODE_NONE,
MODE_USAGE
@@ -151,26 +151,29 @@ main(int argc, char **argv)
grn_obj text;
GRN_TEXT_INIT(&text, 0);
#define SEND(string) send_command(ctx, &text, string, dataset_name)
- SEND("register suggest/suggest");
+ SEND("plugin_register suggest/suggest");
SEND("table_create event_type TABLE_HASH_KEY ShortText");
{
grn_obj query;
GRN_TEXT_INIT(&query, 0);
GRN_TEXT_PUTS(ctx, &query,
- "table_create bigram TABLE_PAT_KEY|KEY_NORMALIZE ShortText "
+ "table_create bigram TABLE_PAT_KEY ShortText "
"--default_tokenizer ");
if (default_tokenizer) {
GRN_TEXT_PUTS(ctx, &query, default_tokenizer);
} else {
GRN_TEXT_PUTS(ctx, &query, DEFAULT_DEFAULT_TOKENIZER);
}
+ GRN_TEXT_PUTS(ctx, &query, " --normalizer NormalizerAuto");
GRN_TEXT_PUTC(ctx, &query, '\0');
SEND(GRN_TEXT_VALUE(&query));
GRN_OBJ_FIN(ctx, &query);
}
- SEND("table_create kana TABLE_PAT_KEY|KEY_NORMALIZE ShortText");
- SEND("table_create item_${DATASET} TABLE_PAT_KEY|KEY_NORMALIZE "
- "ShortText --default_tokenizer TokenDelimit");
+ SEND("table_create kana TABLE_PAT_KEY ShortText "
+ "--normalizer NormalizerAuto");
+ SEND("table_create item_${DATASET} TABLE_PAT_KEY "
+ "ShortText --default_tokenizer TokenDelimit "
+ "--normalizer NormalizerAuto");
SEND("column_create bigram item_${DATASET}_key "
"COLUMN_INDEX|WITH_POSITION item_${DATASET} _key");
SEND("column_create item_${DATASET} kana COLUMN_VECTOR kana");
diff --git a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_httpd.c b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_httpd.c
index f3127288c73..d42ead2c907 100644
--- a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_httpd.c
+++ b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_httpd.c
@@ -212,7 +212,7 @@ log_send(struct evkeyvalq *output_headers, struct evbuffer *res_buf,
zmq_msg_t msg;
if (!zmq_msg_init_size(&msg, sbuf.size)) {
memcpy((void *)zmq_msg_data(&msg), sbuf.data, sbuf.size);
- if (zmq_msg_send(&msg, thd->zmq_sock, 0)) {
+ if (zmq_msg_send(&msg, thd->zmq_sock, 0) == -1) {
print_error("zmq_msg_send() error");
}
zmq_msg_close(&msg);
@@ -512,7 +512,7 @@ recv_handler(grn_ctx *ctx, void *zmq_recv_sock, msgpack_zone *mempool, grn_obj *
if (zmq_msg_init(&msg)) {
print_error("cannot init zmq message.");
} else {
- if (zmq_msg_recv(&msg, zmq_recv_sock, 0)) {
+ if (zmq_msg_recv(&msg, zmq_recv_sock, 0) == -1) {
print_error("cannot recv zmq message.");
} else {
msgpack_object obj;
diff --git a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_learner.c b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_learner.c
index 03d889f5b01..74465beffdd 100644
--- a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_learner.c
+++ b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_learner.c
@@ -207,7 +207,7 @@ zmq_send_to_httpd(void *zmq_send_sock, void *data, size_t size)
zmq_msg_t msg;
if (!zmq_msg_init_size(&msg, size)) {
memcpy((void *)zmq_msg_data(&msg), data, size);
- if (zmq_msg_send(&msg, zmq_send_sock, 0)) {
+ if (zmq_msg_send(&msg, zmq_send_sock, 0) == -1) {
print_error("zmq_send() error");
return -1;
}
@@ -481,7 +481,7 @@ recv_event_loop(msgpack_zone *mempool, void *zmq_sock, grn_ctx *ctx)
if (zmq_msg_init(&msg)) {
print_error("cannot init zmq message.");
} else {
- if (zmq_msg_recv(&msg, zmq_sock, 0)) {
+ if (zmq_msg_recv(&msg, zmq_sock, 0) == -1) {
print_error("cannot recv zmq message.");
} else {
msgpack_object obj;
diff --git a/storage/mroonga/vendor/groonga/tools/Makefile.am b/storage/mroonga/vendor/groonga/tools/Makefile.am
index 00e14ea5da5..6027eee1888 100644
--- a/storage/mroonga/vendor/groonga/tools/Makefile.am
+++ b/storage/mroonga/vendor/groonga/tools/Makefile.am
@@ -1,5 +1,6 @@
noinstall_ruby_scripts = \
groonga-memory-leak-checker.rb \
+ groonga-object-list-checker.rb \
prepare-sphinx-html.rb
EXTRA_DIST = \
diff --git a/storage/mroonga/vendor/groonga/tools/check-small-index-limit.rb b/storage/mroonga/vendor/groonga/tools/check-small-index-limit.rb
new file mode 100755
index 00000000000..d943d89e5ef
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/tools/check-small-index-limit.rb
@@ -0,0 +1,123 @@
+#!/usr/bin/env ruby
+
+# Groonga: 70dc95ef3b6fed1225981d099a65dcb7297248c5
+#
+# N segments N chunks N patterns N records
+# 1 1 2 50
+# 2 2 2 18898
+# 4 4 2 31181
+# 8 8 2 57853
+# 16 16 2 91349
+# 32 32 2 178502
+# 64 64 2 475020
+# 128 128 2 1066081
+# 256 256 2 2250389
+# 512 512 2 4648072
+# nil nil 1 16779239
+# nil nil 2 4648063
+# nil nil 4 7239005
+# nil nil 8 8308626
+# nil nil 16 11068608
+# nil nil 32 12670806
+# nil nil 64 18524231
+# nil nil 128 38095525
+# nil nil 256 51265415
+
+require "fileutils"
+require "json"
+
+def check_max_index(options)
+ max_n_segments = options[:max_n_segments]
+ max_n_chunks = options[:max_n_chunks]
+ n_patterns = options[:n_patterns] || 2
+
+ ENV["GRN_II_MAX_N_SEGMENTS_SMALL"] = max_n_segments&.to_s
+ ENV["GRN_II_MAX_N_CHUNKS_SMALL"] = max_n_chunks&.to_s
+
+ db_dir = "/dev/shm/db"
+ log_path = "#{db_dir}/log"
+ FileUtils.rm_rf(db_dir)
+ FileUtils.mkdir_p(db_dir)
+ command_line = [
+ "groonga",
+ "--log-path", log_path,
+ "-n", "#{db_dir}/db",
+ ]
+ IO.popen(command_line, "r+") do |groonga|
+ groonga.puts("table_create x TABLE_HASH_KEY UInt32")
+ groonga.gets
+ groonga.puts("column_create x y COLUMN_SCALAR UInt32")
+ groonga.gets
+ groonga.puts("table_create a TABLE_PAT_KEY UInt32")
+ groonga.gets
+ groonga.puts("column_create a b COLUMN_INDEX|INDEX_SMALL x y")
+ groonga.gets
+
+ groonga.puts("load --table x")
+ groonga.puts("[")
+ File.open(log_path) do |log|
+ log.seek(0, IO::SEEK_END)
+ log_size = log.size
+ i = 0
+ catch do |abort|
+ loop do
+ y = i + 1
+ n_patterns.times do
+ groonga.print(JSON.generate({"_key" => i, "y" => y}))
+ groonga.puts(",")
+ groonga.flush
+ i += 1
+ if log.size != log_size
+ data = log.read
+ if /\|[Ae]\|/ =~ data
+ parameters = [
+ max_n_segments.inspect,
+ max_n_chunks.inspect,
+ n_patterns.inspect,
+ i,
+ ]
+ puts(parameters.join("\t"))
+ # puts(data)
+ throw(abort)
+ end
+ log_size = log.size
+ end
+ end
+ end
+ end
+ end
+ groonga.puts("]")
+ load_response = groonga.gets
+ # puts(load_response)
+
+ groonga.puts("quit")
+ groonga.gets
+ end
+end
+
+puts("N segments\tN chunks\tN patterns\tN records")
+[
+ [1, 1, 2],
+ [2, 2, 2],
+ [4, 4, 2],
+ [8, 8, 2],
+ [16, 16, 2],
+ [32, 32, 2],
+ [64, 64, 2],
+ [128, 128, 2],
+ [256, 256, 2],
+ [512, 512, 2],
+ [nil, nil, 1],
+ [nil, nil, 2],
+ [nil, nil, 4],
+ [nil, nil, 8],
+ [nil, nil, 16],
+ [nil, nil, 32],
+ [nil, nil, 64],
+ [nil, nil, 128],
+ [nil, nil, 256],
+].each do |max_n_segments, max_n_chunks, n_parameters|
+ check_max_index(:max_n_segments => max_n_segments,
+ :max_n_chunks => max_n_chunks,
+ :n_patterns => n_parameters)
+end
diff --git a/storage/mroonga/vendor/groonga/tools/groonga-benchmark-indexing.rb b/storage/mroonga/vendor/groonga/tools/groonga-benchmark-indexing.rb
new file mode 100755
index 00000000000..9c64e6d9891
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/tools/groonga-benchmark-indexing.rb
@@ -0,0 +1,129 @@
+#!/usr/bin/env ruby
+
+require "fileutils"
+require "json"
+require "optparse"
+
+class IndexingBenchmarker
+ def initialize
+ @groonga = "groonga"
+ @database_path = nil
+ @benchmark_database_dir = detect_benchmark_database_dir
+ end
+
+ def run
+ catch(:run) do
+ parse_options!
+ end
+
+ dump_no_indexes = dump("dump-no-indexes.grn",
+ "--dump_indexes", "no")
+ dump_only_indexes = dump("dump-only-indexes.grn",
+ "--dump_plugins", "no",
+ "--dump_schema", "no",
+ "--dump_records", "no",
+ "--dump_configs", "no")
+ dump_no_records = dump("dump-no-records.grn",
+ "--dump_records", "no")
+ dump_only_records = dump("dump-only-records.grn",
+ "--dump_plugins", "no",
+ "--dump_schema", "no",
+ "--dump_indexes", "no",
+ "--dump_configs", "no")
+
+ create_benchmark_database do
+ p [:load_record, measure(dump_no_indexes)]
+ p [:static_index_creation, measure(dump_only_indexes)]
+ end
+
+ create_benchmark_database do
+ p [:create_schema, measure(dump_no_records)]
+ p [:load_record_and_create_index, measure(dump_only_records)]
+ end
+
+ true
+ end
+
+ private
+ def detect_benchmark_database_dir
+ candiates = [
+ "/dev/shm",
+ "tmp",
+ ]
+ candiates.find do |candidate|
+ File.exist?(candidate)
+ end
+ end
+
+ def benchmark_database_path
+ "#{@benchmark_database_dir}/bench-db/db"
+ end
+
+ def parse_options!
+ option_parser = OptionParser.new do |parser|
+ parser.banner += " SOURCE_DATABASE"
+
+ parser.on("--groonga=PATH",
+ "Use PATH as groonga command path") do |path|
+ @groonga = path
+ end
+
+ parser.on("--benchmark-database-dir=DIR",
+ "Use DIR to put benchmark database") do |dir|
+ @benchmark_database_dir = dir
+ end
+ end
+
+ @database_path, = option_parser.parse!(ARGV)
+ if @database_path.nil?
+ puts(option_parser)
+ throw(:run)
+ end
+ end
+
+ def dump(path, *dump_options)
+ return path if File.exist?(path)
+ unless system(@groonga,
+ @database_path,
+ "dump",
+ *dump_options,
+ :out => path)
+ raise "failed to dump: #{dump_options.inspect}"
+ end
+ path
+ end
+
+ def create_benchmark_database
+ dir = File.dirname(benchmark_database_path)
+ FileUtils.rm_rf(dir)
+ FileUtils.mkdir_p(dir)
+ system(@groonga,
+ "-n", benchmark_database_path,
+ "shutdown",
+ :out => IO::NULL)
+ begin
+ yield
+ ensure
+ FileUtils.rm_rf(dir)
+ end
+ end
+
+ def measure(dump_path)
+ result = "result"
+ begin
+ system(@groonga,
+ "--file", dump_path,
+ benchmark_database_path,
+ :out => result)
+ File.open(result) do |output|
+ output.each_line.inject(0) do |result, line|
+ result + JSON.parse(line)[0][2]
+ end
+ end
+ ensure
+ FileUtils.rm_f(result)
+ end
+ end
+end
+
+exit(IndexingBenchmarker.new.run)
diff --git a/storage/mroonga/vendor/groonga/tools/groonga-memory-usage-analyzer.rb b/storage/mroonga/vendor/groonga/tools/groonga-memory-usage-analyzer.rb
new file mode 100755
index 00000000000..5c4d56699b1
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/tools/groonga-memory-usage-analyzer.rb
@@ -0,0 +1,127 @@
+#!/usr/bin/env ruby
+
+class Memory < Struct.new(:size, :file, :line, :function)
+ def location
+ "#{file}:#{line}"
+ end
+end
+
+class LocationGroup
+ attr_reader :location
+ attr_reader :memories
+ def initialize(location)
+ @location = location
+ @memories = []
+ end
+
+ def add(memory)
+ @memories << memory
+ end
+
+ def total_size
+ @memories.inject(0) do |sum, memory|
+ sum + memory.size
+ end
+ end
+
+ def average_size
+ total_size / @memories.size.to_f
+ end
+
+ def max_size
+ @memories.collect(&:size).max
+ end
+
+ def min_size
+ @memories.collect(&:size).min
+ end
+end
+
+class Statistics
+ def initialize
+ @location_groups = {}
+ end
+
+ def add(memory)
+ group = location_group(memory.location)
+ group.add(memory)
+ end
+
+ def sort_by_size
+ @location_groups.values.sort_by do |group|
+ group.total_size
+ end
+ end
+
+ private
+ def location_group(location)
+ @location_groups[location] ||= LocationGroup.new(location)
+ end
+end
+
+statistics = Statistics.new
+
+ARGF.each_line do |line|
+ case line
+ when /\Aaddress\[\d+\]\[not-freed\]:\s
+ (?:0x)?[\da-fA-F]+\((\d+)\):\s
+ (.+?):(\d+):\s(\S+)/x
+ size = $1.to_i
+ file = $2
+ line = $3.to_i
+ function = $4.strip
+ memory = Memory.new(size, file, line, function)
+ statistics.add(memory)
+ end
+end
+
+def format_size(size)
+ if size < 1024
+ "#{size}B"
+ elsif size < (1024 * 1024)
+ "%.3fKiB" % (size / 1024.0)
+ elsif size < (1024 * 1024 * 1024)
+ "%.3fMiB" % (size / 1024.0 / 1024.0)
+ elsif size < (1024 * 1024 * 1024 * 1024)
+ "%.3fGiB" % (size / 1024.0 / 1024.0 / 1024.0)
+ else
+ "#{size}B"
+ end
+end
+
+puts("%10s(%10s:%10s:%10s): %s(%s)" % [
+ "Total",
+ "Average",
+ "Max",
+ "Min",
+ "Location",
+ "N allocations",
+ ])
+top_allocated_groups = statistics.sort_by_size.reverse_each.take(10)
+top_allocated_groups.each do |group|
+ puts("%10s(%10s:%10s:%10s): %s(%d)" % [
+ format_size(group.total_size),
+ format_size(group.average_size),
+ format_size(group.max_size),
+ format_size(group.min_size),
+ group.location,
+ group.memories.size,
+ ])
+end
+
+puts
+puts("Top allocated location's details")
+top_allocated_group = top_allocated_groups.first
+target_memories = top_allocated_group.memories
+size_width = Math.log10(target_memories.size).floor + 1
+target_memories.group_by(&:size).sort_by do |size, memories|
+ size * memories.size
+end.reverse_each do |size, memories|
+ total_size = memories.inject(0) {|sum, memory| sum + memory.size}
+ puts("%10s(%10s * %#{size_width}d): %s" % [
+ format_size(total_size),
+ format_size(size),
+ memories.size,
+ memories.first.location,
+ ])
+end
diff --git a/storage/mroonga/vendor/groonga/tools/groonga-object-list-checker.rb b/storage/mroonga/vendor/groonga/tools/groonga-object-list-checker.rb
new file mode 100755
index 00000000000..31d85c0cefe
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/tools/groonga-object-list-checker.rb
@@ -0,0 +1,104 @@
+#!/usr/bin/env ruby
+#
+# Copyright(C) 2016 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+require "pp"
+require "json"
+require "groonga/command/parser"
+
+if ARGV.empty?
+ puts("Usage:")
+ puts(" #{$0} schema.grn object_list_result.json")
+ puts(" #{$0} schema.grn < object_list_result.json")
+ puts(" groonga DB_PATH object_list | #{$0} schema.grn")
+ exit(false)
+end
+
+schema_grn = ARGV.shift
+
+schema = {}
+Groonga::Command::Parser.parse(File.read(schema_grn)) do |type, *args|
+ case type
+ when :on_command
+ command, = args
+ case command.name
+ when "table_create"
+ if command.table_no_key?
+ type = "table:no_key"
+ elsif command.table_pat_key?
+ type = "table:pat_key"
+ elsif command.table_dat_key?
+ type = "table:dat_key"
+ else
+ type = "table:hash_key"
+ end
+ name = command[:name]
+ schema[name] ||= []
+ schema[name] << {
+ :type => type,
+ :flags => command.flags.join("|"),
+ }
+ when "column_create"
+ if command.column_index?
+ type = "column:index"
+ elsif command.column_vector? or command.type == "ShortText"
+ type = "column:var_size"
+ else
+ type = "column:fix_size"
+ end
+ name = "#{command[:table]}.#{command[:name]}"
+ schema[name] ||= []
+ schema[name] << {
+ :type => type,
+ :flags => command.flags.join("|"),
+ }
+ end
+ end
+end
+
+MAX_RESERVED_ID = 255
+response = JSON.parse(ARGF.read)
+body = response[1]
+body.each do |name, object|
+ id = object["id"]
+ next if id <= MAX_RESERVED_ID
+ normalized_name = name.gsub(/\d{4}\d{2}(?:\d{2})?/, "YYYYMMDD")
+
+ definitions = schema[normalized_name]
+ if definitions.nil?
+ next if object["type"]["name"] == "proc"
+ puts("Unknown table/column: #{name}(#{id})")
+ exit(false)
+ end
+
+ type = object["type"]
+ if type.nil?
+ puts("[invalid][no-type] #{id}:#{name}")
+ puts(PP.pp(object, "").gsub(/^/, " "))
+ next
+ end
+
+ type_name = type["name"]
+ valid_type_names = definitions.collect {|definition| definition[:type]}
+ unless valid_type_names.include?(type["name"])
+ expected = "expected:[#{valid_type_names.join(", ")}]"
+ puts("[invalid][wrong-type] #{id}:#{name} <#{type_name}> #{expected}")
+ puts(PP.pp(object, "").gsub(/^/, " "))
+ puts(PP.pp(definitions, "").gsub(/^/, " "))
+ next
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/tools/travis-before-script.sh b/storage/mroonga/vendor/groonga/tools/travis-before-script.sh
index ac56e5bd5f0..87ed5756a54 100755
--- a/storage/mroonga/vendor/groonga/tools/travis-before-script.sh
+++ b/storage/mroonga/vendor/groonga/tools/travis-before-script.sh
@@ -1,6 +1,9 @@
#!/bin/sh
set -e
+set -u
+
+: ${ENABLE_MRUBY:=no}
git submodule update --init --depth 1
@@ -11,10 +14,14 @@ case "${BUILD_TOOL}" in
./autogen.sh
configure_args=""
+ if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
+ pkg_config_path="$(brew --prefix openssl)/lib/pkgconfig"
+ configure_args="${configure_args} PKG_CONFIG_PATH=${pkg_config_path}"
+ fi
#if [ "$CC" = "clang" ]; then
configure_args="${configure_args} --enable-debug"
#fi
- if [ "$ENABLE_MRUBY" = "yes" ]; then
+ if [ "${ENABLE_MRUBY}" = "yes" ]; then
configure_args="${configure_args} --with-ruby --enable-mruby"
fi
@@ -23,7 +30,7 @@ case "${BUILD_TOOL}" in
cmake)
cmake_args=""
cmake_args="${cmake_args} -DGRN_WITH_DEBUG=yes"
- if [ "$ENABLE_MRUBY" = "yes" ]; then
+ if [ "${ENABLE_MRUBY}" = "yes" ]; then
cmake_args="${cmake_args} -DGRN_WITH_MRUBY=yes"
fi
diff --git a/storage/mroonga/vendor/groonga/tools/travis-install.sh b/storage/mroonga/vendor/groonga/tools/travis-install.sh
index 943c6220ca6..72240ec1580 100755
--- a/storage/mroonga/vendor/groonga/tools/travis-install.sh
+++ b/storage/mroonga/vendor/groonga/tools/travis-install.sh
@@ -1,12 +1,16 @@
#!/bin/sh
set -e
+set -u
+
+: ${ENABLE_MRUBY:=no}
case "${TRAVIS_OS_NAME}" in
linux)
curl --silent --location https://raw.github.com/clear-code/cutter/master/data/travis/setup.sh | sh
sudo apt-get install -qq -y \
autotools-dev \
+ autoconf-archive \
zlib1g-dev \
libmsgpack-dev \
libevent-dev \
@@ -15,14 +19,21 @@ case "${TRAVIS_OS_NAME}" in
cmake
;;
osx)
+ brew update > /dev/null
+ brew outdated pkg-config || brew upgrade pkg-config
+ brew reinstall libtool
+ brew outdated libevent || brew upgrade libevent
+ brew outdated pcre || brew upgrade pcre
brew install \
+ autoconf-archive \
msgpack \
- libevent \
mecab \
mecab-ipadic
+ brew install --force openssl
+ # brew install cutter
;;
esac
if [ "${ENABLE_MRUBY}" = "yes" ]; then
- gem install pkg-config groonga-client
+ gem install pkg-config groonga-client test-unit
fi
diff --git a/storage/mroonga/vendor/groonga/tools/travis-script.sh b/storage/mroonga/vendor/groonga/tools/travis-script.sh
index 1c4a1a7e1a9..cc0457254c4 100755
--- a/storage/mroonga/vendor/groonga/tools/travis-script.sh
+++ b/storage/mroonga/vendor/groonga/tools/travis-script.sh
@@ -1,23 +1,73 @@
-#!/bin/sh
+#!/bin/bash
set -e
+set -u
+
+: ${ENABLE_MRUBY:=no}
+: ${TEST_TARGET:=all}
prefix=/tmp/local
-command_test_options="--n-workers=4"
+command_test_options="--reporter=mark --timeout=60"
set -x
+export COLUMNS=79
+
+retry()
+{
+ local i=0
+ while ! "$@"; do
+ if [ $i -eq 3 ]; then
+ exit 1
+ fi
+ i=$((i + 1))
+ done
+}
+
+if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
+ memory_fs_size=$[768 * 1024 * 1024] # 768MiB
+ byte_per_sector=512
+ n_sectors=$[${memory_fs_size} / ${byte_per_sector}]
+ memory_fs_device_path=$(hdid -nomount ram://${n_sectors})
+ newfs_hfs ${memory_fs_device_path}
+ mkdir -p tmp
+ mount -t hfs ${memory_fs_device_path} tmp
+
+ command_test_options="${command_test_options} --n-workers=2"
+else
+ command_test_options="${command_test_options} --n-workers=4"
+fi
+
case "${BUILD_TOOL}" in
autotools)
- test/unit/run-test.sh
- test/command/run-test.sh ${command_test_options}
- if [ "${ENABLE_MRUBY}" = "yes" ]; then
- test/query_optimizer/run-test.rb
- fi
- test/command/run-test.sh ${command_test_options} --interface http
- mkdir -p ${prefix}/var/log/groonga/httpd
- test/command/run-test.sh ${command_test_options} --testee groonga-httpd
+ case "${TEST_TARGET}" in
+ command)
+ test/command/run-test.sh ${command_test_options}
+ ;;
+ command-http)
+ retry test/command/run-test.sh ${command_test_options} \
+ --interface http
+ ;;
+ command-httpd)
+ mkdir -p ${prefix}/var/log/groonga/httpd
+ retry test/command/run-test.sh ${command_test_options} \
+ --testee groonga-httpd
+ ;;
+ *)
+ test/unit/run-test.sh -v v
+ test/command/run-test.sh ${command_test_options}
+ if [ "${ENABLE_MRUBY}" = "yes" ]; then
+ test/mruby/run-test.rb
+ test/command_line/run-test.rb
+ fi
+ retry test/command/run-test.sh ${command_test_options} \
+ --interface http
+ mkdir -p ${prefix}/var/log/groonga/httpd
+ retry test/command/run-test.sh ${command_test_options} \
+ --testee groonga-httpd
+ ;;
+ esac
;;
cmake)
test/command/run-test.sh ${command_test_options}
diff --git a/storage/mroonga/vendor/groonga/vendor/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/CMakeLists.txt
index 91a806e0429..9a923908472 100644
--- a/storage/mroonga/vendor/groonga/vendor/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/vendor/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright(C) 2013 Brazil
+# Copyright(C) 2013-2016 Brazil
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,5 +13,8 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+add_subdirectory(lz4)
add_subdirectory(onigmo)
add_subdirectory(mruby)
+add_subdirectory(mecab)
+add_subdirectory(message_pack)
diff --git a/storage/mroonga/vendor/groonga/vendor/Makefile.am b/storage/mroonga/vendor/groonga/vendor/Makefile.am
index 0b766191a08..d66aac55696 100644
--- a/storage/mroonga/vendor/groonga/vendor/Makefile.am
+++ b/storage/mroonga/vendor/groonga/vendor/Makefile.am
@@ -1,14 +1,19 @@
NGINX_DIR = nginx-$(NGINX_VERSION)
SUBDIRS = \
+ lz4 \
onigmo \
+ mecab \
+ message_pack \
mruby
EXTRA_DIST = \
$(NGINX_DIR) \
CMakeLists.txt \
plugins/CMakeLists.txt \
- mruby/CMakeLists.txt
+ download_lz4.rb \
+ download_message_pack.rb \
+ download_mecab.rb
dist-hook:
rm -rf $(distdir)/$(NGINX_DIR)/objs/
@@ -17,3 +22,8 @@ dist-hook:
$(MKDIR_P) $(distdir)/onigmo-source
GIT_DIR=$(srcdir)/onigmo-source/.git git archive --format=tar HEAD | \
tar xf - -C $(distdir)/onigmo-source
+ cd $(distdir)/onigmo-source && autoreconf --install --force
+ cd $(distdir)/onigmo-source && sleep 1 && touch config.h.in
+ $(MKDIR_P) $(distdir)/ngx_mruby-source
+ GIT_DIR=$(srcdir)/ngx_mruby-source/.git git archive --format=tar HEAD | \
+ tar xf - -C $(distdir)/ngx_mruby-source
diff --git a/storage/mroonga/vendor/groonga/vendor/download_lz4.rb b/storage/mroonga/vendor/groonga/vendor/download_lz4.rb
new file mode 100755
index 00000000000..59b35081d0f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/download_lz4.rb
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby
+
+require "pathname"
+require "fileutils"
+require "open-uri"
+require "openssl"
+require "rubygems/package"
+require "zlib"
+
+@debug = (ENV["DEBUG"] == "true" or ARGV.include?("--debug"))
+
+base_dir = Pathname.new(__FILE__).expand_path.dirname.parent
+
+lz4_version = (base_dir + "bundled_lz4_version").read.strip
+
+lz4_base = "lz4-#{lz4_version}"
+
+def extract_tar_gz(tar_gz_path)
+ Zlib::GzipReader.open(tar_gz_path) do |tar_io|
+ Gem::Package::TarReader.new(tar_io) do |tar|
+ tar.each do |entry|
+ p [entry.header.typeflag, entry.full_name] if @debug
+ if entry.directory?
+ FileUtils.mkdir_p(entry.full_name)
+ elsif entry.file?
+ File.open(entry.full_name, "wb") do |file|
+ file.print(entry.read)
+ end
+ end
+ end
+ end
+ end
+end
+
+def download(url, base)
+ ssl_verify_mode = nil
+ if /mingw/ =~ RUBY_PLATFORM
+ ssl_verify_mode = OpenSSL::SSL::VERIFY_NONE
+ end
+
+ tar = "#{base}.tar"
+ tar_gz = "#{tar}.gz"
+ open(url, :ssl_verify_mode => ssl_verify_mode) do |remote_tar_gz|
+ File.open(tar_gz, "wb") do |local_tar_gz|
+ local_tar_gz.print(remote_tar_gz.read)
+ end
+ end
+ FileUtils.rm_rf(base)
+ extract_tar_gz(tar_gz)
+ FileUtils.rm_rf(tar_gz)
+end
+
+download("https://github.com/lz4/lz4/archive/v#{lz4_version}.tar.gz",
+ lz4_base)
diff --git a/storage/mroonga/vendor/groonga/vendor/download_mecab.rb b/storage/mroonga/vendor/groonga/vendor/download_mecab.rb
new file mode 100755
index 00000000000..027f834f936
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/download_mecab.rb
@@ -0,0 +1,59 @@
+#!/usr/bin/env ruby
+
+require "pathname"
+require "fileutils"
+require "open-uri"
+require "openssl"
+require "rubygems/package"
+require "zlib"
+
+@debug = (ENV["DEBUG"] == "true" or ARGV.include?("--debug"))
+
+base_dir = Pathname.new(__FILE__).expand_path.dirname.parent
+
+mecab_version = (base_dir + "bundled_mecab_version").read.strip
+mecab_naist_jdic_version = (base_dir + "bundled_mecab_naist_jdic_version").read.strip
+
+mecab_base = "mecab-#{mecab_version}"
+mecab_naist_jdic_base = "mecab-naist-jdic-#{mecab_naist_jdic_version}"
+
+def extract_tar_gz(tar_gz_path)
+ Zlib::GzipReader.open(tar_gz_path) do |tar_io|
+ Gem::Package::TarReader.new(tar_io) do |tar|
+ tar.each do |entry|
+ p [entry.header.typeflag, entry.full_name] if @debug
+ if entry.directory?
+ FileUtils.mkdir_p(entry.full_name)
+ else
+ File.open(entry.full_name, "wb") do |file|
+ file.print(entry.read)
+ end
+ end
+ end
+ end
+ end
+end
+
+def download(url, base)
+ ssl_verify_mode = nil
+ if /mingw/ =~ RUBY_PLATFORM
+ ssl_verify_mode = OpenSSL::SSL::VERIFY_NONE
+ end
+
+ tar = "#{base}.tar"
+ tar_gz = "#{tar}.gz"
+ open(url, :ssl_verify_mode => ssl_verify_mode) do |remote_tar_gz|
+ File.open(tar_gz, "wb") do |local_tar_gz|
+ local_tar_gz.print(remote_tar_gz.read)
+ end
+ end
+ FileUtils.rm_rf(base)
+ extract_tar_gz(tar_gz)
+ FileUtils.rm_rf(tar_gz)
+end
+
+download("https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE",
+ mecab_base)
+
+download("http://osdn.dl.sourceforge.jp/naist-jdic/53500/#{mecab_naist_jdic_base}.tar.gz",
+ mecab_naist_jdic_base)
diff --git a/storage/mroonga/vendor/groonga/vendor/download_message_pack.rb b/storage/mroonga/vendor/groonga/vendor/download_message_pack.rb
new file mode 100755
index 00000000000..b2f09af703b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/download_message_pack.rb
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby
+
+require "pathname"
+require "fileutils"
+require "open-uri"
+require "openssl"
+require "rubygems/package"
+require "zlib"
+
+@debug = (ENV["DEBUG"] == "true" or ARGV.include?("--debug"))
+
+base_dir = Pathname.new(__FILE__).expand_path.dirname.parent
+
+message_pack_version = (base_dir + "bundled_message_pack_version").read.strip
+
+message_pack_base = "msgpack-#{message_pack_version}"
+
+def extract_tar_gz(tar_gz_path)
+ Zlib::GzipReader.open(tar_gz_path) do |tar_io|
+ Gem::Package::TarReader.new(tar_io) do |tar|
+ tar.each do |entry|
+ p [entry.header.typeflag, entry.full_name] if @debug
+ if entry.directory?
+ FileUtils.mkdir_p(entry.full_name)
+ else
+ File.open(entry.full_name, "wb") do |file|
+ file.print(entry.read)
+ end
+ end
+ end
+ end
+ end
+end
+
+def download(url, base)
+ ssl_verify_mode = nil
+ if /mingw/ =~ RUBY_PLATFORM
+ ssl_verify_mode = OpenSSL::SSL::VERIFY_NONE
+ end
+
+ tar = "#{base}.tar"
+ tar_gz = "#{tar}.gz"
+ open(url, :ssl_verify_mode => ssl_verify_mode) do |remote_tar_gz|
+ File.open(tar_gz, "wb") do |local_tar_gz|
+ local_tar_gz.print(remote_tar_gz.read)
+ end
+ end
+ FileUtils.rm_rf(base)
+ extract_tar_gz(tar_gz)
+ FileUtils.rm_rf(tar_gz)
+end
+
+download("https://github.com/msgpack/msgpack-c/releases/download/cpp-#{message_pack_version}/msgpack-#{message_pack_version}.tar.gz",
+ message_pack_base)
diff --git a/storage/mroonga/vendor/groonga/vendor/lz4/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/lz4/CMakeLists.txt
new file mode 100644
index 00000000000..00342223d1d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/lz4/CMakeLists.txt
@@ -0,0 +1,98 @@
+# Copyright(C) 2016 Brazil
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1 as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+set(LZ4_VERSION ${GRN_BUNDLED_LZ4_VERSION})
+
+set(LZ4_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../lz4-${LZ4_VERSION}")
+set(LZ4_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/../lz4-${LZ4_VERSION}")
+
+if(GRN_WITH_BUNDLED_LZ4)
+ include_directories(
+ BEFORE
+ ${LZ4_BINARY_DIR}
+ "${LZ4_SOURCE_DIR}/lib"
+ )
+
+ set(LIBLZ4_SOURCES
+ "${LZ4_SOURCE_DIR}/lib/lz4.c"
+ "${LZ4_SOURCE_DIR}/lib/lz4.h"
+ "${LZ4_SOURCE_DIR}/lib/lz4frame.c"
+ "${LZ4_SOURCE_DIR}/lib/lz4frame.h"
+ "${LZ4_SOURCE_DIR}/lib/lz4frame_static.h"
+ "${LZ4_SOURCE_DIR}/lib/lz4hc.c"
+ "${LZ4_SOURCE_DIR}/lib/lz4hc.h"
+ "${LZ4_SOURCE_DIR}/lib/xxhash.c"
+ "${LZ4_SOURCE_DIR}/lib/xxhash.h"
+ )
+ set(LZ4_SOURCES
+ "${LZ4_SOURCE_DIR}/programs/lz4cli.c"
+ "${LZ4_SOURCE_DIR}/programs/lz4io.c"
+ "${LZ4_SOURCE_DIR}/programs/lz4io.h"
+ "${LZ4_SOURCE_DIR}/programs/bench.c"
+ "${LZ4_SOURCE_DIR}/programs/bench.h"
+ "${LZ4_SOURCE_DIR}/programs/datagen.c"
+ "${LZ4_SOURCE_DIR}/programs/datagen.h"
+ "${LZ4_SOURCE_DIR}/programs/platform.h"
+ "${LZ4_SOURCE_DIR}/programs/util.h"
+ ${LIBLZ4_SOURCES})
+
+ set(LZ4_C_COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+
+ add_definitions("-DXXH_NAMESPACE=LZ4_")
+ if(MSVC)
+ add_definitions("-DLZ4_DLL_EXPORT=1")
+ endif()
+ set_source_files_properties(${LIBLZ4_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${LZ4_C_COMPILE_FLAGS}")
+ set_source_files_properties(${LZ4_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${LZ4_C_COMPILE_FLAGS}")
+
+ if(GRN_BUNDLED)
+ add_library(liblz4 STATIC ${LIBLZ4_SOURCES})
+ set_target_properties(
+ liblz4
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+ else()
+ add_library(liblz4 SHARED ${LIBLZ4_SOURCES})
+ endif()
+ if(NOT MSVC)
+ set_target_properties(liblz4 PROPERTIES OUTPUT_NAME "lz4")
+ endif()
+
+ if(NOT GRN_BUNDLED)
+ add_executable(lz4 ${LZ4_SOURCES})
+
+ install(TARGETS liblz4
+ ARCHIVE DESTINATION "${LIB_DIR}"
+ LIBRARY DESTINATION "${LIB_DIR}"
+ RUNTIME DESTINATION "${BIN_DIR}")
+ install(TARGETS lz4
+ DESTINATION "${BIN_DIR}")
+ install(FILES
+ "${LZ4_SOURCE_DIR}/lib/lz4.h"
+ "${LZ4_SOURCE_DIR}/lib/lz4frame.h"
+ "${LZ4_SOURCE_DIR}/lib/lz4hc.h"
+ DESTINATION "${INCLUDE_DIR}")
+ endif()
+
+ install(FILES
+ "${LZ4_SOURCE_DIR}/lib/LICENSE"
+ "${LZ4_SOURCE_DIR}/programs/COPYING"
+ "${LZ4_SOURCE_DIR}/README.md"
+ DESTINATION "${GRN_DATA_DIR}/lz4")
+endif()
diff --git a/storage/mroonga/vendor/groonga/vendor/lz4/Makefile.am b/storage/mroonga/vendor/groonga/vendor/lz4/Makefile.am
new file mode 100644
index 00000000000..8a652320e62
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/lz4/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST = \
+ CMakeLists.txt
diff --git a/storage/mroonga/vendor/groonga/vendor/mecab/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/mecab/CMakeLists.txt
new file mode 100644
index 00000000000..a0a720df294
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/mecab/CMakeLists.txt
@@ -0,0 +1,219 @@
+# Copyright(C) 2015 Brazil
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1 as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+set(MECAB_VERSION ${GRN_BUNDLED_MECAB_VERSION})
+set(MECAB_DICT_VERSION "102")
+set(MECAB_NAIST_JDIC_VERSION ${GRN_BUNDLED_MECAB_NAIST_JDIC_VERSION})
+
+set(MECAB_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../mecab-${MECAB_VERSION}")
+set(MECAB_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/../mecab-${MECAB_VERSION}")
+set(MECAB_NAIST_JDIC_SOURCE_DIR
+ "${CMAKE_CURRENT_SOURCE_DIR}/../mecab-naist-jdic-${MECAB_NAIST_JDIC_VERSION}")
+
+if(GRN_WITH_BUNDLED_MECAB)
+ include_directories(
+ BEFORE
+ ${MECAB_BINARY_DIR}
+ ${MECAB_SOURCE_DIR}
+ )
+
+ set(MECAB_RELATIVE_DICT_DIR "${DATA_DIR}/mecab/dic")
+ set(MECAB_RELATIVE_NAIST_JDIC_DICT_DIR
+ "${MECAB_RELATIVE_DICT_DIR}/naist-jdic")
+ if(WIN32)
+ string(REGEX REPLACE "/" "\\\\"
+ MECAB_WINDOWS_RELATIVE_NAIST_JDIC_DICT_DIR
+ "${MECAB_RELATIVE_NAIST_JDIC_DICT_DIR}")
+ set(MECAB_NAIST_JDIC_DICT_DIR
+ "$(rcpath)\\..\\${MECAB_WINDOWS_RELATIVE_NAIST_JDIC_DICT_DIR}")
+ else()
+ set(MECAB_NAIST_JDIC_DICT_DIR
+ "$(rcpath)/../${MECAB_RELATIVE_NAIST_JDIC_DICT_DIR}")
+ endif()
+
+ set(LIBMECAB_SOURCES
+ "${MECAB_SOURCE_DIR}/src/char_property.cpp"
+ "${MECAB_SOURCE_DIR}/src/char_property.h"
+ "${MECAB_SOURCE_DIR}/src/common.h"
+ "${MECAB_SOURCE_DIR}/src/connector.cpp"
+ "${MECAB_SOURCE_DIR}/src/connector.h"
+ "${MECAB_SOURCE_DIR}/src/context_id.cpp"
+ "${MECAB_SOURCE_DIR}/src/context_id.h"
+ "${MECAB_SOURCE_DIR}/src/darts.h"
+ "${MECAB_SOURCE_DIR}/src/dictionary.cpp"
+ "${MECAB_SOURCE_DIR}/src/dictionary.h"
+ "${MECAB_SOURCE_DIR}/src/dictionary_compiler.cpp"
+ "${MECAB_SOURCE_DIR}/src/dictionary_generator.cpp"
+ "${MECAB_SOURCE_DIR}/src/dictionary_rewriter.cpp"
+ "${MECAB_SOURCE_DIR}/src/dictionary_rewriter.h"
+ "${MECAB_SOURCE_DIR}/src/eval.cpp"
+ "${MECAB_SOURCE_DIR}/src/feature_index.cpp"
+ "${MECAB_SOURCE_DIR}/src/feature_index.h"
+ "${MECAB_SOURCE_DIR}/src/freelist.h"
+ "${MECAB_SOURCE_DIR}/src/iconv_utils.cpp"
+ "${MECAB_SOURCE_DIR}/src/iconv_utils.h"
+ "${MECAB_SOURCE_DIR}/src/lbfgs.cpp"
+ "${MECAB_SOURCE_DIR}/src/lbfgs.h"
+ "${MECAB_SOURCE_DIR}/src/learner.cpp"
+ "${MECAB_SOURCE_DIR}/src/learner_node.h"
+ "${MECAB_SOURCE_DIR}/src/learner_tagger.cpp"
+ "${MECAB_SOURCE_DIR}/src/learner_tagger.h"
+ "${MECAB_SOURCE_DIR}/src/libmecab.cpp"
+ # "${MECAB_SOURCE_DIR}/src/mecab-cost-train.cpp"
+ # "${MECAB_SOURCE_DIR}/src/mecab-dict-gen.cpp"
+ # "${MECAB_SOURCE_DIR}/src/mecab-system-eval.cpp"
+ # "${MECAB_SOURCE_DIR}/src/mecab-test-gen.cpp"
+ "${MECAB_SOURCE_DIR}/src/mecab.h"
+ "${MECAB_SOURCE_DIR}/src/mmap.h"
+ "${MECAB_SOURCE_DIR}/src/nbest_generator.cpp"
+ "${MECAB_SOURCE_DIR}/src/nbest_generator.h"
+ "${MECAB_SOURCE_DIR}/src/param.cpp"
+ "${MECAB_SOURCE_DIR}/src/param.h"
+ "${MECAB_SOURCE_DIR}/src/scoped_ptr.h"
+ "${MECAB_SOURCE_DIR}/src/stream_wrapper.h"
+ "${MECAB_SOURCE_DIR}/src/string_buffer.cpp"
+ "${MECAB_SOURCE_DIR}/src/string_buffer.h"
+ "${MECAB_SOURCE_DIR}/src/tagger.cpp"
+ "${MECAB_SOURCE_DIR}/src/thread.h"
+ "${MECAB_SOURCE_DIR}/src/tokenizer.cpp"
+ "${MECAB_SOURCE_DIR}/src/tokenizer.h"
+ "${MECAB_SOURCE_DIR}/src/ucs.h"
+ "${MECAB_SOURCE_DIR}/src/ucstable.h"
+ "${MECAB_SOURCE_DIR}/src/utils.cpp"
+ "${MECAB_SOURCE_DIR}/src/utils.h"
+ "${MECAB_SOURCE_DIR}/src/viterbi.cpp"
+ "${MECAB_SOURCE_DIR}/src/viterbi.h"
+ "${MECAB_SOURCE_DIR}/src/winmain.h"
+ "${MECAB_SOURCE_DIR}/src/writer.cpp"
+ "${MECAB_SOURCE_DIR}/src/writer.h"
+ )
+ set(MECAB_SOURCES
+ "${MECAB_SOURCE_DIR}/src/mecab.cpp"
+ )
+ set(MECAB_DICT_INDEX_SOURCES
+ "${MECAB_SOURCE_DIR}/src/mecab-dict-index.cpp"
+ )
+
+ set(MECAB_CXX_COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS}")
+ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX)
+ set(MECAB_CXX_COMPILE_FLAGS
+ "${MECAB_CXX_COMPILE_FLAGS} -Wno-type-limits")
+ set(MECAB_CXX_COMPILE_FLAGS
+ "${MECAB_CXX_COMPILE_FLAGS} -Wno-float-equal")
+ set(MECAB_CXX_COMPILE_FLAGS
+ "${MECAB_CXX_COMPILE_FLAGS} -Wno-ignored-qualifiers")
+ set(MECAB_CXX_COMPILE_FLAGS
+ "${MECAB_CXX_COMPILE_FLAGS} -Wno-unused-function")
+ endif()
+
+ add_definitions("-DPACKAGE=\"mecab\"")
+ add_definitions("-DVERSION=\"${MECAB_VERSION}\"")
+ add_definitions("-DDIC_VERSION=${MECAB_DICT_VERSION}")
+ if(MSVC)
+ add_definitions(
+ "-DMECAB_DEFAULT_RC=\"c:\\\\Program Files\\\\mecab\\\\etc\\\\mecabrc\"")
+ add_definitions(-DMECAB_USE_THREAD)
+ add_definitions(-DDLL_EXPORT)
+ add_definitions(-DHAVE_GETENV)
+ add_definitions(-DHAVE_STRING_H)
+ add_definitions(-DHAVE_UNSIGNED_LONG_LONG_INT)
+ add_definitions(-DHAVE_WINDOWS_H)
+ add_definitions(-DUNICODE)
+ add_definitions(-D_UNICODE)
+ else()
+ add_definitions(
+ "-DMECAB_DEFAULT_RC=\"${CMAKE_INSTALL_PREFIX}/${CONFIG_DIR}/mecabrc\"")
+ add_definitions(
+ "-DICONV_CONST=")
+ add_definitions(-DHAVE_DIRENT_H)
+ add_definitions(-DHAVE_FCNTL_H)
+ add_definitions(-DHAVE_ICONV)
+ add_definitions(-DHAVE_STDINT_H)
+ add_definitions(-DHAVE_STRING_H)
+ add_definitions(-DHAVE_SYS_MMAN_H)
+ add_definitions(-DHAVE_SYS_STAT_H)
+ add_definitions(-DHAVE_SYS_TYPES_H)
+ add_definitions(-DHAVE_UNISTD_H)
+ endif()
+ set_source_files_properties(${LIBMECAB_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${MECAB_CXX_COMPILE_FLAGS}")
+ set_source_files_properties(${MECAB_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS}")
+ set_source_files_properties(${MECAB_DICT_INDEX_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS}")
+
+ add_library(libmecab SHARED ${LIBMECAB_SOURCES})
+ if(NOT MSVC)
+ set_target_properties(libmecab PROPERTIES OUTPUT_NAME "mecab")
+ endif()
+ add_executable(mecab ${MECAB_SOURCES})
+ target_link_libraries(mecab libmecab)
+ add_executable(mecab-dict-index ${MECAB_DICT_INDEX_SOURCES})
+ target_link_libraries(mecab-dict-index libmecab)
+ install(TARGETS libmecab
+ ARCHIVE DESTINATION "${LIB_DIR}"
+ LIBRARY DESTINATION "${LIB_DIR}"
+ RUNTIME DESTINATION "${BIN_DIR}")
+ install(TARGETS mecab
+ DESTINATION "${BIN_DIR}")
+ install(TARGETS mecab-dict-index
+ DESTINATION "${BIN_DIR}")
+ install(FILES "${MECAB_SOURCE_DIR}/src/mecab.h"
+ DESTINATION "${INCLUDE_DIR}")
+
+ set(MECAB_NAIST_JDIC_BUILD_DATA
+ "${CMAKE_CURRENT_BINARY_DIR}/matrix.bin"
+ "${CMAKE_CURRENT_BINARY_DIR}/char.bin"
+ "${CMAKE_CURRENT_BINARY_DIR}/sys.dic"
+ "${CMAKE_CURRENT_BINARY_DIR}/unk.dic")
+ add_custom_command(OUTPUT ${MECAB_NAIST_JDIC_BUILD_DATA}
+ COMMAND
+ mecab-dict-index
+ "--dicdir" "${MECAB_NAIST_JDIC_SOURCE_DIR}"
+ "--outdir" "${CMAKE_CURRENT_BINARY_DIR}"
+ "--dictionary-charset" "EUC-JP"
+ "--charset" "utf-8"
+ DEPENDS mecab-dict-index
+ COMMENT "Build NAIST Japanese Dictionary for MeCab")
+ add_custom_target(mecab-naist-jdic ALL
+ DEPENDS ${MECAB_NAIST_JDIC_BUILD_DATA})
+ install(FILES
+ ${MECAB_NAIST_JDIC_BUILD_DATA}
+ "${MECAB_NAIST_JDIC_SOURCE_DIR}/dicrc"
+ DESTINATION "${MECAB_RELATIVE_NAIST_JDIC_DICT_DIR}")
+
+ configure_file("mecabrc.cmake" "mecabrc")
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/mecabrc"
+ DESTINATION "${CONFIG_DIR}")
+
+ install(FILES
+ "${MECAB_NAIST_JDIC_SOURCE_DIR}/AUTHORS"
+ "${MECAB_NAIST_JDIC_SOURCE_DIR}/COPYING"
+ "${MECAB_NAIST_JDIC_SOURCE_DIR}/README"
+ DESTINATION "${GRN_DATA_DIR}/mecab-naist-jdic")
+ install(FILES
+ "${MECAB_SOURCE_DIR}/AUTHORS"
+ "${MECAB_SOURCE_DIR}/BSD"
+ "${MECAB_SOURCE_DIR}/COPYING"
+ "${MECAB_SOURCE_DIR}/GPL"
+ "${MECAB_SOURCE_DIR}/LGPL"
+ "${MECAB_SOURCE_DIR}/README"
+ DESTINATION "${GRN_DATA_DIR}/mecab")
+
+ configure_file(config.h.cmake "${MECAB_BINARY_DIR}/config.h")
+endif()
diff --git a/storage/mroonga/vendor/groonga/vendor/mecab/Makefile.am b/storage/mroonga/vendor/groonga/vendor/mecab/Makefile.am
new file mode 100644
index 00000000000..d284d6fc99d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/mecab/Makefile.am
@@ -0,0 +1,4 @@
+EXTRA_DIST = \
+ CMakeLists.txt \
+ config.h.cmake \
+ mecabrc.cmake
diff --git a/storage/mroonga/vendor/groonga/vendor/mecab/config.h.cmake b/storage/mroonga/vendor/groonga/vendor/mecab/config.h.cmake
new file mode 100644
index 00000000000..2997587d820
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/mecab/config.h.cmake
@@ -0,0 +1 @@
+/* dummy */
diff --git a/storage/mroonga/vendor/groonga/vendor/mecab/mecabrc.cmake b/storage/mroonga/vendor/groonga/vendor/mecab/mecabrc.cmake
new file mode 100644
index 00000000000..8185cfaecfb
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/mecab/mecabrc.cmake
@@ -0,0 +1,3 @@
+; Configuration file of MeCab
+
+dicdir = ${MECAB_NAIST_JDIC_DICT_DIR}
diff --git a/storage/mroonga/vendor/groonga/vendor/message_pack/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/message_pack/CMakeLists.txt
new file mode 100644
index 00000000000..fc0d90a1f7c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/message_pack/CMakeLists.txt
@@ -0,0 +1,53 @@
+# Copyright(C) 2016 Brazil
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1 as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+set(MESSAGE_PACK_VERSION ${GRN_BUNDLED_MESSAGE_PACK_VERSION})
+
+set(MESSAGE_PACK_SOURCE_DIR
+ "${CMAKE_CURRENT_SOURCE_DIR}/../msgpack-${MESSAGE_PACK_VERSION}")
+
+if(GRN_WITH_BUNDLED_MESSAGE_PACK)
+ include_directories(
+ BEFORE
+ ${MESSAGE_PACK_SOURCE_DIR}/include
+ )
+
+ set(MESSAGE_PACK_SOURCES
+ "${MESSAGE_PACK_SOURCE_DIR}/src/objectc.c"
+ "${MESSAGE_PACK_SOURCE_DIR}/src/unpack.c"
+ "${MESSAGE_PACK_SOURCE_DIR}/src/version.c"
+ "${MESSAGE_PACK_SOURCE_DIR}/src/vrefbuffer.c"
+ "${MESSAGE_PACK_SOURCE_DIR}/src/zone.c"
+ )
+
+ set_source_files_properties(${MESSAGE_PACK_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+
+ add_library(msgpackc SHARED ${MESSAGE_PACK_SOURCES})
+ install(TARGETS msgpackc
+ ARCHIVE DESTINATION "${LIB_DIR}"
+ LIBRARY DESTINATION "${LIB_DIR}"
+ RUNTIME DESTINATION "${BIN_DIR}")
+ install(DIRECTORY
+ "${MESSAGE_PACK_SOURCE_DIR}/include/"
+ DESTINATION "${INCLUDE_DIR}"
+ FILES_MATCHING PATTERN "*.h")
+ install(FILES
+ "${MESSAGE_PACK_SOURCE_DIR}/COPYING"
+ "${MESSAGE_PACK_SOURCE_DIR}/LICENSE_1_0.txt"
+ "${MESSAGE_PACK_SOURCE_DIR}/README.md"
+ DESTINATION "${GRN_DATA_DIR}/msgpack")
+endif()
diff --git a/storage/mroonga/vendor/groonga/vendor/message_pack/Makefile.am b/storage/mroonga/vendor/groonga/vendor/message_pack/Makefile.am
new file mode 100644
index 00000000000..8a652320e62
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/message_pack/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST = \
+ CMakeLists.txt
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt
index f2b27aff7e8..826ea6e4ea2 100644
--- a/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright(C) 2013-2015 Brazil
+# Copyright(C) 2013-2016 Brazil
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -14,10 +14,12 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
if(GRN_WITH_MRUBY)
+ set(MRUBY_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source")
+
include_directories(
- "${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source/include"
- "${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source/src"
- "${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source/mrbgems/mruby-compiler/core"
+ "${MRUBY_SOURCE_DIR}/include"
+ "${MRUBY_SOURCE_DIR}/src"
+ "${MRUBY_SOURCE_DIR}/mrbgems/mruby-compiler/core"
"${CMAKE_CURRENT_SOURCE_DIR}/../onigmo-source"
)
@@ -30,6 +32,7 @@ if(GRN_WITH_MRUBY)
set(mruby_pre_build_timestamp
"${CMAKE_CURRENT_SOURCE_DIR}/mruby_build.timestamp")
if(EXISTS "${mruby_pre_build_timestamp}")
+ set(MRUBY_LEGAL_FILE "${CMAKE_CURRENT_SOURCE_DIR}/LEGAL")
string(REGEX REPLACE "([^;]+)" "${CMAKE_CURRENT_SOURCE_DIR}/\\1"
MRUBY_BUILT_SOURCES "${MRUBY_BUILT_SOURCES}")
include_directories(
@@ -44,7 +47,7 @@ if(GRN_WITH_MRUBY)
"${RUBY}"
"${CMAKE_CURRENT_SOURCE_DIR}/mruby_build.rb"
"${CMAKE_CURRENT_SOURCE_DIR}/build_config.rb"
- "${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source"
+ "${MRUBY_SOURCE_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}/../mruby-build"
"${CMAKE_CURRENT_SOURCE_DIR}/../onigmo-source"
"${mruby_build_timestamp}"
@@ -55,23 +58,44 @@ if(GRN_WITH_MRUBY)
message(FATAL_ERROR "Failed to build mruby files")
endif()
endif()
+ set(MRUBY_LEGAL_FILE "${CMAKE_CURRENT_BINARY_DIR}/LEGAL")
string(REGEX REPLACE "([^;]+)" "${CMAKE_CURRENT_BINARY_DIR}/\\1"
MRUBY_BUILT_SOURCES "${MRUBY_BUILT_SOURCES}")
include_directories(
"${CMAKE_CURRENT_BINARY_DIR}/mruby-io/include"
)
endif()
+ file(WRITE
+ "${CMAKE_CURRENT_BINARY_DIR}/mruby-file-stat/src/config.h"
+ "")
set(MRUBY_ALL_SOURCES
${MRUBY_SOURCES}
${MRUBY_BUILT_SOURCES}
)
add_library(mruby STATIC ${MRUBY_ALL_SOURCES})
- set_source_files_properties(${MRUBY_ALL_SOURCES}
- PROPERTIES
- COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
set_target_properties(
mruby
PROPERTIES
POSITION_INDEPENDENT_CODE ON)
+
+ set(MRUBY_C_COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANGCC)
+ set(MRUBY_C_COMPILE_FLAGS
+ "${MRUBY_C_COMPILE_FLAGS} -Wno-float-equal")
+ set(MRUBY_C_COMPILE_FLAGS
+ "${MRUBY_C_COMPILE_FLAGS} -Wno-bad-function-cast")
+ endif()
+ if(WIN32)
+ set(MRUBY_DEFINITIONS ${MRUBY_DEFINITIONS} MRB_BUILD_AS_DLL MRB_CORE)
+ endif()
+ set_source_files_properties(${MRUBY_ALL_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${MRUBY_C_COMPILE_FLAGS}")
+ set_property(SOURCE ${MRUBY_ALL_SOURCES}
+ PROPERTY COMPILE_DEFINITIONS ${MRUBY_DEFINITIONS})
+
+ install(FILES
+ "${MRUBY_LEGAL_FILE}"
+ DESTINATION "${GRN_DATA_DIR}/mruby")
endif()
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am b/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am
index c4285c1c85c..6d86565d4d4 100644
--- a/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am
@@ -1,7 +1,11 @@
EXTRA_DIST = \
+ LEGAL \
+ CMakeLists.txt \
build_config.rb \
mruby_build.rb \
- mruby_build.timestamp
+ mruby_build.timestamp \
+ version \
+ mruby-dir/src/Win/dirent.c
DEFAULT_INCLUDES = \
-I$(srcdir)/../mruby-source/include \
@@ -10,13 +14,21 @@ DEFAULT_INCLUDES = \
-Imruby-io/include \
-I$(srcdir)/mruby-io/include
-CFLAGS += $(NO_FLOAT_EQUAL_CFLAGS)
+CFLAGS += \
+ $(NO_FLOAT_EQUAL_CFLAGS) \
+ $(NO_BAD_FUNCTION_CAST_CFLAGS)
if WITH_MRUBY
+mruby_datadir = $(pkgdatadir)/mruby
+mruby_data_DATA = \
+ LEGAL
+
noinst_LTLIBRARIES = libmruby.la
AM_CPPFLAGS = \
- -I$(srcdir)/../onigmo-source
+ -I$(srcdir)/../onigmo-source \
+ -DHAVE_ONIGMO_H \
+ $(MRUBY_CPPFLAGS)
if PLATFORM_WIN32
AM_CPPFLAGS += \
@@ -28,6 +40,7 @@ include sources.am
include built_sources.am
libmruby_la_SOURCES += $(BUILT_SOURCES)
+LEGAL: mruby_build.timestamp
mrblib.c: mruby_build.timestamp
mrbgems_init.c: mruby_build.timestamp
mruby-compiler/core/parse.c: mruby_build.timestamp
@@ -38,10 +51,15 @@ mruby-io/src/file.c: mruby_build.timestamp
mruby-io/src/file_test.c: mruby_build.timestamp
mruby-io/src/io.c: mruby_build.timestamp
mruby-io/src/mruby_io_gem.c: mruby_build.timestamp
+mruby-file-stat/src/file-stat.c: mruby_build.timestamp
+mruby-file-stat/src/config.h: mruby_build.timestamp
+ touch "$(builddir)/$@"
+mruby-dir/src/dir.c: mruby_build.timestamp
+mruby-dir/src/Win/dirent.c: mruby_build.timestamp
MRUBY_CONFIG = $(abs_srcdir)/build_config.rb
MRUBY_BUILD_DIR = $(abs_top_builddir)/vendor/mruby-build
-mruby_build.timestamp: build_config.rb
+mruby_build.timestamp: build_config.rb version
$(RUBY) "$(srcdir)/mruby_build.rb" \
"$(srcdir)/build_config.rb" \
"$(srcdir)/../mruby-source" \
@@ -56,5 +74,6 @@ endif
update:
cd "$(srcdir)/../mruby-source" && \
(git checkout master && git pull --rebase)
+ (cd "$(srcdir)/../mruby-source" && git describe) > version
cd "$(srcdir)" && \
./update.rb build_config.rb ../mruby-source > sources.am
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb b/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb
index f487e08b808..335a383dffb 100644
--- a/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb
@@ -35,9 +35,20 @@ MRuby::Build.new do |conf|
conf.gem :core => "mruby-toplevel-ext"
conf.gem :core => "mruby-kernel-ext"
- conf.gem :github => "mattn/mruby-onig-regexp"
- conf.gem :github => "iij/mruby-env"
- conf.gem :github => "iij/mruby-io"
- conf.gem :github => "kou/mruby-pp"
- conf.gem :github => "kou/mruby-slop"
+ conf.gem :github => "mattn/mruby-onig-regexp",
+ :checksum_hash => "12f573cb327aa50834c3a549f62995f44edd3172"
+ conf.gem :github => "iij/mruby-env",
+ :checksum_hash => "57f0d737a4ece49dc5b6f1c7ee09b0bc8f8adf87"
+ conf.gem :github => "iij/mruby-io",
+ :checksum_hash => "69623078a86b45617a6fdbe0238c147e280ad9db"
+ conf.gem :github => "kou/mruby-pp",
+ :checksum_hash => "ddda20ca273ba532f2025d4ff7ddc8bb223ad8c2"
+ conf.gem :github => "kou/mruby-slop",
+ :checksum_hash => "752d1a3e2bc4fdc40ee92d668812a99c8fc5e1cc"
+ conf.gem :github => "ksss/mruby-file-stat",
+ :checksum_hash => "2d3ea9b5d59d2b41133228a71c110b75cb30a31e"
+ conf.gem :github => "kou/mruby-tsort",
+ :checksum_hash => "6d7f5a56ac7a90847f84186ce1dbc780e41928dc"
+ conf.gem :github => "iij/mruby-dir",
+ :checksum_hash => "14bc5c3e51eac16ebc9075b7b62132a0cf5ae724"
end
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am b/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am
index 73726cda58b..26151266eb6 100644
--- a/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am
@@ -8,4 +8,7 @@ BUILT_SOURCES = \
mruby-io/src/file.c \
mruby-io/src/file_test.c \
mruby-io/src/io.c \
- mruby-io/src/mruby_io_gem.c
+ mruby-io/src/mruby_io_gem.c \
+ mruby-file-stat/src/config.h \
+ mruby-file-stat/src/file-stat.c \
+ mruby-dir/src/dir.c
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb b/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb
index e2e8d68e7cf..c0a8644897d 100755
--- a/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb
@@ -28,6 +28,8 @@ end
FileUtils.touch(timestamp_file)
+FileUtils.cp("#{mruby_build_dir}/host/LEGAL", "./")
+
FileUtils.cp("#{mruby_build_dir}/host/mrblib/mrblib.c", "./")
File.open("mrbgems_init.c", "w") do |mrbgems_init|
@@ -53,3 +55,11 @@ mruby_io_dir = "#{mruby_build_dir}/mrbgems/mruby-io"
FileUtils.mkdir_p("mruby-io/")
FileUtils.cp_r("#{mruby_io_dir}/include/", "mruby-io/")
FileUtils.cp_r("#{mruby_io_dir}/src/", "mruby-io/")
+
+mruby_file_stat_dir = "#{mruby_build_dir}/mrbgems/mruby-file-stat"
+FileUtils.mkdir_p("mruby-file-stat/")
+FileUtils.cp_r("#{mruby_file_stat_dir}/src/", "mruby-file-stat/")
+
+mruby_dir_dir = "#{mruby_build_dir}/mrbgems/mruby-dir"
+FileUtils.mkdir_p("mruby-dir/")
+FileUtils.cp_r("#{mruby_dir_dir}/src/", "mruby-dir/")
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/version b/storage/mroonga/vendor/groonga/vendor/mruby/version
new file mode 100644
index 00000000000..232c2993a6c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/version
@@ -0,0 +1 @@
+1.0.0-3861-ge5b61d34
diff --git a/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt
index e52bb1d195c..27717a0b718 100644
--- a/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt
@@ -21,6 +21,12 @@ if(GRN_WITH_ONIGMO)
macro(ac_check_sizeof type)
string(TOUPPER "${type}" output_variable_base_name)
+ string(REPLACE "*" "P"
+ output_variable_base_name
+ "${output_variable_base_name}")
+ string(REPLACE " " "_"
+ output_variable_base_name
+ "${output_variable_base_name}")
set(output_variable_name "ONIG_SIZEOF_${output_variable_base_name}")
check_type_size(${type} ${output_variable_name})
if(HAVE_${output_variable_name})
@@ -33,6 +39,8 @@ if(GRN_WITH_ONIGMO)
ac_check_sizeof(short)
ac_check_sizeof(int)
ac_check_sizeof(long)
+ ac_check_sizeof("void*")
+ ac_check_sizeof("long long")
add_definitions(-DHAVE_STDARG_H)
add_definitions(-DHAVE_STDINT_H)
@@ -53,6 +61,7 @@ if(GRN_WITH_ONIGMO)
BEFORE
${ONIGMO_BINARY_DIR}
${ONIGMO_SOURCE_DIR}
+ ${ONIGMO_SOURCE_DIR}/enc/unicode
)
set(ONIGMO_SOURCES
@@ -75,49 +84,64 @@ if(GRN_WITH_ONIGMO)
"${ONIGMO_SOURCE_DIR}/regposerr.c"
"${ONIGMO_SOURCE_DIR}/enc/unicode.c"
"${ONIGMO_SOURCE_DIR}/enc/ascii.c"
- "${ONIGMO_SOURCE_DIR}/enc/utf8.c"
- "${ONIGMO_SOURCE_DIR}/enc/utf16_be.c"
- "${ONIGMO_SOURCE_DIR}/enc/utf16_le.c"
- "${ONIGMO_SOURCE_DIR}/enc/utf32_be.c"
- "${ONIGMO_SOURCE_DIR}/enc/utf32_le.c"
+ "${ONIGMO_SOURCE_DIR}/enc/utf_8.c"
+ "${ONIGMO_SOURCE_DIR}/enc/utf_16be.c"
+ "${ONIGMO_SOURCE_DIR}/enc/utf_16le.c"
+ "${ONIGMO_SOURCE_DIR}/enc/utf_32be.c"
+ "${ONIGMO_SOURCE_DIR}/enc/utf_32le.c"
"${ONIGMO_SOURCE_DIR}/enc/unicode/casefold.h"
"${ONIGMO_SOURCE_DIR}/enc/unicode/name2ctype.h"
"${ONIGMO_SOURCE_DIR}/enc/euc_jp.c"
- "${ONIGMO_SOURCE_DIR}/enc/sjis.c"
- "${ONIGMO_SOURCE_DIR}/enc/cp932.c"
+ "${ONIGMO_SOURCE_DIR}/enc/shift_jis.c"
+ "${ONIGMO_SOURCE_DIR}/enc/windows_31j.c"
"${ONIGMO_SOURCE_DIR}/enc/jis/props.h"
# "${ONIGMO_SOURCE_DIR}/enc/jis/props.kwd"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_1.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_2.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_3.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_4.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_5.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_6.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_7.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_8.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_9.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_10.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_11.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_13.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_14.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_15.c"
- "${ONIGMO_SOURCE_DIR}/enc/iso8859_16.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859.h"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_1.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_2.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_3.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_4.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_5.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_6.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_7.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_8.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_9.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_10.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_11.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_13.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_14.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_15.c"
+ "${ONIGMO_SOURCE_DIR}/enc/iso_8859_16.c"
"${ONIGMO_SOURCE_DIR}/enc/euc_tw.c"
"${ONIGMO_SOURCE_DIR}/enc/euc_kr.c"
"${ONIGMO_SOURCE_DIR}/enc/big5.c"
"${ONIGMO_SOURCE_DIR}/enc/gb18030.c"
"${ONIGMO_SOURCE_DIR}/enc/koi8_r.c"
- "${ONIGMO_SOURCE_DIR}/enc/cp1251.c"
+ "${ONIGMO_SOURCE_DIR}/enc/koi8_u.c"
+ "${ONIGMO_SOURCE_DIR}/enc/windows_1250.c"
+ "${ONIGMO_SOURCE_DIR}/enc/windows_1251.c"
+ "${ONIGMO_SOURCE_DIR}/enc/windows_1252.c"
+ "${ONIGMO_SOURCE_DIR}/enc/windows_1253.c"
+ "${ONIGMO_SOURCE_DIR}/enc/windows_1254.c"
+ "${ONIGMO_SOURCE_DIR}/enc/windows_1257.c"
)
+ set(ONIGMO_C_COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+
add_library(onigmo STATIC ${ONIGMO_SOURCES})
set_source_files_properties(${ONIGMO_SOURCES}
PROPERTIES
- COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+ COMPILE_FLAGS "${ONIGMO_C_COMPILE_FLAGS}")
set_target_properties(
onigmo
PROPERTIES
POSITION_INDEPENDENT_CODE ON)
configure_file(config.h.cmake "${ONIGMO_BINARY_DIR}/config.h")
+
+ install(FILES
+ "${ONIGMO_SOURCE_DIR}/AUTHORS"
+ "${ONIGMO_SOURCE_DIR}/COPYING"
+ "${ONIGMO_SOURCE_DIR}/README"
+ DESTINATION "${GRN_DATA_DIR}/onigmo")
endif()
diff --git a/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am b/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am
index cbd419d6736..2e77323f812 100644
--- a/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am
+++ b/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am
@@ -6,6 +6,7 @@ EXTRA_DIST = \
CONFIGURE_DEPENDENCIES = \
configure
+if WITH_BUNDLED_ONIGMO
ALL_DEPEND_TARGETS = onigmo-all
CLEAN_DEPEND_TARGETS = onigmo-clean
@@ -28,3 +29,4 @@ onigmo-clean:
cd ../onigmo-source && $(MAKE) clean
clean: $(CLEAN_DEPEND_TARGETS)
+endif
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt
index 3577572a9f1..6f458e232ac 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt
@@ -16,7 +16,8 @@
# MA 02110-1301, USA
cmake_minimum_required(VERSION 2.6)
-project(groonga-normalizer-mysql)
+set(GROONGA_NORMALIZER_MYSQL_PROJECT_NAME "groonga-normalizer-mysql")
+project("${GROONGA_NORMALIZER_MYSQL_PROJECT_NAME}")
if(DEFINED GROONGA_NORMALIZER_MYSQL_EMBED)
set(GROONGA_NORMALIZER_MYSQL_EMBED_DEFAULT
@@ -72,3 +73,8 @@ if(NOT GROONGA_NORMALIZER_MYSQL_EMBED)
FILES "${CMAKE_CURRENT_BINARY_DIR}/groonga-normalizer-mysql.pc"
DESTINATION "lib/pkgconfig/")
endif()
+
+install(FILES
+ "README.md"
+ "doc/text/lgpl-2.0.txt"
+ DESTINATION "share/${GROONGA_NORMALIZER_MYSQL_PROJECT_NAME}")
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/configure.ac b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/configure.ac
index fd52203837e..b619622744e 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/configure.ac
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/configure.ac
@@ -1,4 +1,4 @@
-# Copyright (C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright (C) 2013-2016 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
@@ -28,11 +28,35 @@ AM_INIT_AUTOMAKE([1.9 foreign tar-pax])
AC_PROG_LIBTOOL
+AC_MSG_CHECKING([for clang])
+if test "$CC" = "clang"; then
+ CLANG=yes
+else
+ CLANG=no
+fi
+AC_MSG_RESULT([$CLANG])
+
if test "$GCC" = "yes"; then
CFLAGS="$CFLAGS -Wall -Wextra"
CFLAGS="$CFLAGS -Wmissing-declarations -Wmissing-prototypes"
fi
+# For debug
+AC_ARG_ENABLE(debug,
+ [AS_HELP_STRING([--enable-debug],
+ [use debug flags (default=no)])],
+ [groonga_normalizer_mysql_debug="$enableval"],
+ [groonga_normalizer_mysql_debug="no"])
+if test "x$groonga_normalizer_mysql_debug" != "xno"; then
+ if test "$CLANG" = "yes"; then
+ CFLAGS="$CFLAGS -O0 -g"
+ CXXFLAGS="$CXXFLAGS -O0 -g"
+ elif test "$GCC" = "yes"; then
+ CFLAGS="$CFLAGS -O0 -g3"
+ CXXFLAGS="$CXXFLAGS -O0 -g3"
+ fi
+fi
+
m4_define([groonga_required_version], m4_include(required_groonga_version))
GROONGA_REQUIRED_VERSION=groonga_required_version
PKG_CHECK_MODULES([GROONGA], [groonga >= ${GROONGA_REQUIRED_VERSION}])
@@ -74,7 +98,12 @@ if test "x$RUBY" = "xno"; then
else
if test "x$RUBY" = "xauto"; then
AC_PATH_PROGS(RUBY,
- [ruby2.1 ruby21 ruby2.0 ruby20 ruby1.9 ruby19 ruby1.9.1 ruby],
+ [ dnl
+ ruby2.3 ruby23 dnl
+ ruby2.2 ruby22 dnl
+ ruby2.1 ruby21 dnl
+ ruby dnl
+ ],
ruby-not-found)
if test "$RUBY" != "ruby-not-found"; then
ruby_version="`$RUBY --version`"
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md
index f66e285bc7d..17bc587bb32 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md
@@ -1,5 +1,16 @@
# News
+## 1.1.1: 2016-04-29
+
+### Improvements
+
+ * Supported Ubuntu 15.10 and Ubuntu 16.04
+ * Dropped Debian 7.0
+
+### Fixes
+
+ * Fixed to install license information when cmake is used.
+
## 1.1.0: 2015-05-29
### Fixes
@@ -13,7 +24,7 @@
## 1.0.9: 2015-03-29
-### Improves
+### Improvements
* Added `NormalizerMySQLUnicode520CI`
* Added `NormalizerMySQLUnicode520CIExceptKanaCIKanaWithVoicedSoundMark`
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/Makefile.am b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/Makefile.am
index 9808a7f9e35..60969bcd270 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/Makefile.am
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/Makefile.am
@@ -1,7 +1,7 @@
REPOSITORIES_PATH = repositories
DISTRIBUTIONS = debian
ARCHITECTURES = i386 amd64
-CODE_NAMES = wheezy jessie
+CODE_NAMES = jessie
all:
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/Vagrantfile b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/Vagrantfile
index 7115ac3f6c0..c57c5a65e63 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/Vagrantfile
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/Vagrantfile
@@ -7,20 +7,12 @@ VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
vms = [
{
- :id => "debian-wheezy-i386",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-7.8-i386_chef-provisionerless.box",
- },
- {
- :id => "debian-wheezy-amd64",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-7.8_chef-provisionerless.box",
- },
- {
:id => "debian-jessie-i386",
- :box_url => "http://packages.groonga.org/tmp/opscode_debian-8.0-i386_chef-provisionerless.box",
+ :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-8.2-i386_chef-provisionerless.box",
},
{
:id => "debian-jessie-amd64",
- :box_url => "http://packages.groonga.org/tmp/opscode_debian-8.0_chef-provisionerless.box",
+ :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-8.2_chef-provisionerless.box",
},
]
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/sign-packages.sh b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/sign-packages.sh
index 11a4aea26db..55678b98cd7 100755
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/sign-packages.sh
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/sign-packages.sh
@@ -23,7 +23,7 @@ run()
for code_name in ${CODES}; do
case ${code_name} in
- squeeze|wheezy|jessie|unstable)
+ jessie|unstable)
distribution=debian
;;
*)
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/sign-repository.sh b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/sign-repository.sh
index fb0de850d6f..b2a1475f755 100755
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/sign-repository.sh
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/sign-repository.sh
@@ -23,7 +23,7 @@ run()
for code_name in ${CODES}; do
case ${code_name} in
- squeeze|wheezy|jessie|unstable)
+ jessie|unstable)
distribution=debian
;;
*)
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/update-repository.sh b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/update-repository.sh
index da1f8cd121c..0ad8f4a22d5 100755
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/update-repository.sh
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/update-repository.sh
@@ -109,7 +109,7 @@ EOF
for code_name in ${CODES}; do
case ${code_name} in
- squeeze|wheezy|jessie|unstable)
+ jessie|unstable)
distribution=debian
component=main
;;
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog
index ea07d115215..89763794a32 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog
@@ -1,3 +1,9 @@
+groonga-normalizer-mysql (1.1.1-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- HAYASHI Kentaro <hayashi@clear-code.com> Fri, 29 Apr 2016 00:00:00 +0900
+
groonga-normalizer-mysql (1.1.0-1) unstable; urgency=low
* New upstream release.
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in
index f78794f1973..a0f3b355775 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in
@@ -52,6 +52,9 @@ rm $RPM_BUILD_ROOT%{_libdir}/groonga/plugins/*/*.la
%{_libdir}/pkgconfig/groonga-normalizer-mysql.pc
%changelog
+* Fri Apr 29 2016 HAYASHI Kentaro <hayashi@clear-code.com> - 1.1.1-1
+- new upstream release.
+
* Fri May 29 2015 Kouhei Sutou <kou@clear-code.com> - 1.1.0-1
- new upstream release.
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in
index 8cf379086a6..d6e3c7cf9a5 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in
@@ -51,6 +51,9 @@ rm $RPM_BUILD_ROOT%{_libdir}/groonga/plugins/*/*.la
%{_libdir}/pkgconfig/groonga-normalizer-mysql.pc
%changelog
+* Fri Apr 29 2016 HAYASHI Kentaro <hayashi@clear-code.com> - 1.1.1-1
+- new upstream release.
+
* Fri May 29 2015 Kouhei Sutou <kou@clear-code.com> - 1.1.0-1
- new upstream release.
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/ubuntu/Makefile.am b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/ubuntu/Makefile.am
index 73dbef7791b..cb0be12d643 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/ubuntu/Makefile.am
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/ubuntu/Makefile.am
@@ -1,4 +1,4 @@
-CODE_NAMES = precise,trusty,utopic,vivid
+CODE_NAMES = precise,trusty,wily,xenial
SOURCE = ../$(PACKAGE)-$(VERSION).tar.gz
all:
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/yum/Makefile.am b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/yum/Makefile.am
index edd546fbae1..3f48f6f33c7 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/yum/Makefile.am
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/yum/Makefile.am
@@ -1,6 +1,7 @@
REPOSITORIES_PATH = repositories
DISTRIBUTIONS = centos
ARCHITECTURES = i386 x86_64
+CENTOS_VERSIONS = 5 6 7
release: download build sign-packages update-repository upload
@@ -38,7 +39,7 @@ build: build-in-vm
build-in-vm: source specs env.sh
vagrant destroy --force
for architecture in $(ARCHITECTURES); do \
- for version in 5 6 7; do \
+ for version in $(CENTOS_VERSIONS); do \
if [ $$version = 7 -a $$architecture = i386 ]; then \
continue; \
fi; \
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/yum/Vagrantfile b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/yum/Vagrantfile
index 87866a3a0ac..048d9e00baa 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/yum/Vagrantfile
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/yum/Vagrantfile
@@ -16,15 +16,15 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
},
{
:id => "centos-6-i386",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.6-i386_chef-provisionerless.box",
+ :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.7-i386_chef-provisionerless.box",
},
{
:id => "centos-6-x86_64",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.6_chef-provisionerless.box",
+ :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.7_chef-provisionerless.box",
},
{
:id => "centos-7-x86_64",
- :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-7.0_chef-provisionerless.box",
+ :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-7.2_chef-provisionerless.box",
},
]
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version
index 1cc5f657e05..8cfbc905b39 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version
@@ -1 +1 @@
-1.1.0 \ No newline at end of file
+1.1.1 \ No newline at end of file
diff --git a/storage/mroonga/version b/storage/mroonga/version
index c22ec448710..5b1f56847ae 100644
--- a/storage/mroonga/version
+++ b/storage/mroonga/version
@@ -1 +1 @@
-5.04 \ No newline at end of file
+7.07 \ No newline at end of file
diff --git a/storage/mroonga/version_in_hex b/storage/mroonga/version_in_hex
index b2bfc453d0e..33e98aa1934 100644
--- a/storage/mroonga/version_in_hex
+++ b/storage/mroonga/version_in_hex
@@ -1 +1 @@
-0x0504 \ No newline at end of file
+0x0707 \ No newline at end of file
diff --git a/storage/mroonga/version_major b/storage/mroonga/version_major
index 7813681f5b4..c7930257dfe 100644
--- a/storage/mroonga/version_major
+++ b/storage/mroonga/version_major
@@ -1 +1 @@
-5 \ No newline at end of file
+7 \ No newline at end of file
diff --git a/storage/mroonga/version_micro b/storage/mroonga/version_micro
index bf0d87ab1b2..c7930257dfe 100644
--- a/storage/mroonga/version_micro
+++ b/storage/mroonga/version_micro
@@ -1 +1 @@
-4 \ No newline at end of file
+7 \ No newline at end of file
diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c
index dee57513912..8065bb696a1 100644
--- a/storage/myisam/ft_boolean_search.c
+++ b/storage/myisam/ft_boolean_search.c
@@ -290,7 +290,7 @@ static int ftb_parse_query_internal(MYSQL_FTPARSER_PARAM *param,
info.prev= ' ';
info.quot= 0;
while (ft_get_word(cs, start, end, &w, &info))
- param->mysql_add_word(param, (char*) w.pos, w.len, &info);
+ param->mysql_add_word(param, (char*) w.pos, (int)w.len, &info);
return(0);
}
@@ -579,7 +579,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, uchar *query,
bzero(& ftb->no_dupes, sizeof(TREE));
ftb->last_word= 0;
- init_alloc_root(&ftb->mem_root, 1024, 1024, MYF(0));
+ init_alloc_root(&ftb->mem_root, "fulltext", 1024, 1024, MYF(0));
ftb->queue.max_elements= 0;
if (!(ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR))))
goto err;
@@ -675,7 +675,7 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param,
while (ft_simple_get_word(phrase_param->cs, (uchar**) &document, docend,
&word, FALSE))
{
- param->mysql_add_word(param, (char*) word.pos, word.len, 0);
+ param->mysql_add_word(param, (char*) word.pos, (int)word.len, 0);
if (phrase_param->match)
break;
}
@@ -961,7 +961,7 @@ static int ftb_find_relevance_parse(MYSQL_FTPARSER_PARAM *param,
uchar *end= (uchar*) doc + len;
FT_WORD w;
while (ft_simple_get_word(ftb->charset, (uchar**) &doc, end, &w, TRUE))
- param->mysql_add_word(param, (char*) w.pos, w.len, 0);
+ param->mysql_add_word(param, (char*) w.pos, (int)w.len, 0);
return(0);
}
diff --git a/storage/myisam/ft_myisam.c b/storage/myisam/ft_myisam.c
index 4e1879fa8ce..4cbf67ba30f 100644
--- a/storage/myisam/ft_myisam.c
+++ b/storage/myisam/ft_myisam.c
@@ -28,9 +28,9 @@ FT_INFO *ft_init_search(uint flags, void *info, uint keynr,
{
FT_INFO *res;
if (flags & FT_BOOL)
- res= ft_init_boolean_search((MI_INFO *)info, keynr, query, query_len,cs);
+ res= ft_init_boolean_search((MI_INFO *)info, keynr, query, (uint)query_len,cs);
else
- res= ft_init_nlq_search((MI_INFO *)info, keynr, query, query_len, flags,
+ res= ft_init_nlq_search((MI_INFO *)info, keynr, query, (uint)query_len, flags,
record);
return res;
}
diff --git a/storage/myisam/ft_parser.c b/storage/myisam/ft_parser.c
index fc3a649dd53..aec7bd338ac 100644
--- a/storage/myisam/ft_parser.c
+++ b/storage/myisam/ft_parser.c
@@ -295,7 +295,7 @@ static int ft_parse_internal(MYSQL_FTPARSER_PARAM *param,
DBUG_ENTER("ft_parse_internal");
while (ft_simple_get_word(wtree->custom_arg, &doc, end, &w, TRUE))
- if (param->mysql_add_word(param, (char*) w.pos, w.len, 0))
+ if (param->mysql_add_word(param, (char*) w.pos, (int)w.len, 0))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
@@ -342,7 +342,8 @@ MYSQL_FTPARSER_PARAM* ftparser_alloc_param(MI_INFO *info)
info->ftparser_param= (MYSQL_FTPARSER_PARAM *)
my_malloc(MAX_PARAM_NR * sizeof(MYSQL_FTPARSER_PARAM) *
info->s->ftkeys, MYF(MY_WME | MY_ZEROFILL));
- init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(0));
+ init_alloc_root(&info->ft_memroot, "fulltext_parser",
+ FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(0));
}
return info->ftparser_param;
}
diff --git a/storage/myisam/ft_stopwords.c b/storage/myisam/ft_stopwords.c
index 7c743743adc..7294106b569 100644
--- a/storage/myisam/ft_stopwords.c
+++ b/storage/myisam/ft_stopwords.c
@@ -77,7 +77,7 @@ int ft_init_stopwords()
if (ft_stopword_file)
{
File fd;
- uint len;
+ size_t len;
uchar *buffer, *start, *end;
FT_WORD w;
int error=-1;
@@ -87,7 +87,7 @@ int ft_init_stopwords()
if ((fd=my_open(ft_stopword_file, O_RDONLY, MYF(MY_WME))) == -1)
DBUG_RETURN(-1);
- len=(uint)my_seek(fd, 0L, MY_SEEK_END, MYF(0));
+ len=(size_t)my_seek(fd, 0L, MY_SEEK_END, MYF(0));
my_seek(fd, 0L, MY_SEEK_SET, MYF(0));
if (!(start=buffer=my_malloc(len+1, MYF(MY_WME))))
goto err0;
@@ -124,7 +124,7 @@ int is_stopword(const char *word, size_t len)
{
FT_STOPWORD sw;
sw.pos=word;
- sw.len=len;
+ sw.len=(uint)len;
return tree_search(stopwords3,&sw, stopwords3->custom_arg) != NULL;
}
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 62c400b1c07..cd7df789858 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -757,6 +757,7 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{
MI_KEYDEF *keyinfo;
MI_COLUMNDEF *recinfo= 0;
+ char readlink_buf[FN_REFLEN], name_buff[FN_REFLEN];
uint recs;
uint i;
@@ -812,6 +813,30 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
(void) mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
+
+ /*
+ Set data_file_name and index_file_name to point at the symlink value
+ if table is symlinked (Ie; Real name is not same as generated name)
+ */
+ fn_format(name_buff, file->filename, "", MI_NAME_DEXT,
+ MY_APPEND_EXT | MY_UNPACK_FILENAME);
+ if (my_is_symlink(name_buff))
+ {
+ my_readlink(readlink_buf, name_buff, MYF(0));
+ data_file_name= strdup_root(&table->mem_root, readlink_buf);
+ }
+ else
+ data_file_name= 0;
+ fn_format(name_buff, file->filename, "", MI_NAME_IEXT,
+ MY_APPEND_EXT | MY_UNPACK_FILENAME);
+ if (my_is_symlink(name_buff))
+ {
+ my_readlink(readlink_buf, name_buff, MYF(0));
+ index_file_name= strdup_root(&table->mem_root, readlink_buf);
+ }
+ else
+ index_file_name= 0;
+
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
(void) mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
if (!table->s->db_record_offset)
@@ -913,7 +938,7 @@ void ha_myisam::setup_vcols_for_repair(HA_CHECK *param)
{
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;
+ indexed_vcols|= ((*vf)->flags & PART_KEY_FLAG) != 0;
}
if (!indexed_vcols)
return;
@@ -1953,7 +1978,6 @@ void ha_myisam::position(const uchar *record)
int ha_myisam::info(uint flag)
{
MI_ISAMINFO misam_info;
- char name_buff[FN_REFLEN];
if (!table)
return 1;
@@ -2001,27 +2025,6 @@ int ha_myisam::info(uint flag)
sizeof(table->key_info[0].rec_per_key[0])*share->key_parts);
if (table_share->tmp_table == NO_TMP_TABLE)
mysql_mutex_unlock(&table_share->LOCK_share);
-
- /*
- Set data_file_name and index_file_name to point at the symlink value
- if table is symlinked (Ie; Real name is not same as generated name)
- */
- char buf[FN_REFLEN];
- data_file_name= index_file_name= 0;
- fn_format(name_buff, file->filename, "", MI_NAME_DEXT,
- MY_APPEND_EXT | MY_UNPACK_FILENAME);
- if (my_is_symlink(name_buff))
- {
- my_readlink(buf, name_buff, MYF(0));
- data_file_name= ha_thd()->strdup(buf);
- }
- fn_format(name_buff, file->filename, "", MI_NAME_IEXT,
- MY_APPEND_EXT | MY_UNPACK_FILENAME);
- if (my_is_symlink(name_buff))
- {
- my_readlink(buf, name_buff, MYF(0));
- index_file_name= ha_thd()->strdup(buf);
- }
}
if (flag & HA_STATUS_ERRKEY)
{
diff --git a/storage/myisam/mi_cache.c b/storage/myisam/mi_cache.c
index 6fa599ff981..012d410c793 100644
--- a/storage/myisam/mi_cache.c
+++ b/storage/myisam/mi_cache.c
@@ -35,10 +35,10 @@
#include "myisamdef.h"
-int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
+int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, size_t length,
int flag)
{
- uint read_length,in_buff_length;
+ size_t read_length,in_buff_length;
my_off_t offset;
uchar *in_buff_pos;
DBUG_ENTER("_mi_read_cache");
@@ -48,7 +48,7 @@ int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
{
read_length=length;
if ((my_off_t) read_length > (my_off_t) (info->pos_in_file-pos))
- read_length=(uint) (info->pos_in_file-pos);
+ read_length=(size_t)(info->pos_in_file-pos);
info->seek_not_done=1;
if (mysql_file_pread(info->file, buff, read_length, pos, MYF(MY_NABP)))
DBUG_RETURN(1);
@@ -61,9 +61,9 @@ int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
(offset= (my_off_t) (pos - info->pos_in_file)) <
(my_off_t) (info->read_end - info->request_pos))
{
- in_buff_pos=info->request_pos+(uint) offset;
- in_buff_length= MY_MIN(length, (size_t) (info->read_end-in_buff_pos));
- memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
+ in_buff_pos=info->request_pos+ (uint)offset;
+ in_buff_length= MY_MIN(length, (size_t)(info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset, in_buff_length);
if (!(length-=in_buff_length))
DBUG_RETURN(0);
pos+=in_buff_length;
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 9e60ae41e14..a73f999fc05 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -2291,7 +2291,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
mysql_file_seek(param->read_cache.file, 0L, MY_SEEK_END, MYF(0));
sort_param.wordlist=NULL;
- init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0,
+ init_alloc_root(&sort_param.wordroot, "sort", FTPARSER_MEMROOT_ALLOC_SIZE, 0,
MYF(param->malloc_flags));
if (share->data_file_type == DYNAMIC_RECORD)
@@ -2869,7 +2869,8 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
sort_param[i].keyinfo->seg->charset->mbmaxlen;
sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
- init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0,
+ init_alloc_root(&sort_param[i].wordroot, "sort",
+ FTPARSER_MEMROOT_ALLOC_SIZE, 0,
MYF(param->malloc_flags));
}
}
@@ -4790,8 +4791,7 @@ static int replace_data_file(HA_CHECK *param, MI_INFO *info, File new_file)
*/
if (info->s->file_map)
{
- (void) my_munmap((char*) info->s->file_map,
- (size_t) info->s->mmaped_length);
+ (void) my_munmap((char*) info->s->file_map, info->s->mmaped_length);
info->s->file_map= NULL;
}
diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c
index c4baca3d89f..905f8ecfbc9 100644
--- a/storage/myisam/mi_dynrec.c
+++ b/storage/myisam/mi_dynrec.c
@@ -95,7 +95,7 @@ my_bool mi_dynmap_file(MI_INFO *info, my_off_t size)
#if defined(HAVE_MADVISE)
madvise((char*) info->s->file_map, size, MADV_RANDOM);
#endif
- info->s->mmaped_length= size;
+ info->s->mmaped_length= (size_t) size;
info->s->file_read= mi_mmap_pread;
info->s->file_write= mi_mmap_pwrite;
DBUG_RETURN(0);
@@ -118,8 +118,7 @@ int mi_munmap_file(MI_INFO *info)
{
int ret;
DBUG_ENTER("mi_unmap_file");
- if ((ret= my_munmap((void*) info->s->file_map,
- (size_t) info->s->mmaped_length)))
+ if ((ret= my_munmap((void*) info->s->file_map, info->s->mmaped_length)))
DBUG_RETURN(ret);
info->s->file_read= mi_nommap_pread;
info->s->file_write= mi_nommap_pwrite;
@@ -1217,7 +1216,7 @@ err:
/* Returns -1 and my_errno =HA_ERR_RECORD_DELETED if reclength isn't */
/* right. Returns reclength (>0) if ok */
-ulong _mi_rec_unpack(register MI_INFO *info, register uchar *to, uchar *from,
+size_t _mi_rec_unpack(register MI_INFO *info, register uchar *to, uchar *from,
ulong found_length)
{
uint flag,bit,length,rec_length,min_pack_length;
diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c
index 9a2526ad2cf..52066c0033d 100644
--- a/storage/myisam/mi_key.c
+++ b/storage/myisam/mi_key.c
@@ -74,8 +74,8 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
{
enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
- uint length=keyseg->length;
- uint char_length;
+ size_t length=keyseg->length;
+ size_t char_length;
CHARSET_INFO *cs=keyseg->charset;
if (keyseg->null_bit)
@@ -116,11 +116,11 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
uchar *end= pos + length;
while (pos < end && pos[0] == ' ')
pos++;
- length=(uint) (end-pos);
+ length=(size_t) (end-pos);
}
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
- memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
+ memcpy(key, pos,char_length);
key+=char_length;
continue;
}
@@ -133,7 +133,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
set_if_smaller(length,tmp_length);
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
- memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
+ memcpy(key, pos, char_length);
key+= char_length;
continue;
}
@@ -144,7 +144,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
set_if_smaller(length,tmp_length);
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
- memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
+ memcpy(key, pos, char_length);
key+= char_length;
continue;
}
@@ -235,8 +235,8 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
old+= keyseg->length, keyseg++)
{
enum ha_base_keytype type= (enum ha_base_keytype) keyseg->type;
- uint length= keyseg->length;
- uint char_length;
+ size_t length= keyseg->length;
+ size_t char_length;
uchar *pos;
CHARSET_INFO *cs=keyseg->charset;
@@ -259,7 +259,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
uchar *end= pos + length;
while (pos < end && pos[0] == ' ')
pos++;
- length= (uint) (end - pos);
+ length= (size_t)(end - pos);
}
else if (type != HA_KEYTYPE_BINARY)
{
@@ -267,7 +267,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
}
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
- memcpy((uchar*) key,pos,(size_t) char_length);
+ memcpy(key,pos,char_length);
key+= char_length;
continue;
}
@@ -280,7 +280,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
old+=2; /* Skip length */
- memcpy((uchar*) key, pos,(size_t) char_length);
+ memcpy(key, pos, char_length);
key+= char_length;
continue;
}
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index 1921926463e..d2c74cf9980 100644
--- a/storage/myisam/mi_locking.c
+++ b/storage/myisam/mi_locking.c
@@ -1,5 +1,5 @@
-/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2009, 2018, 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
@@ -113,6 +113,8 @@ int mi_lock_database(MI_INFO *info, int lock_type)
share->changed=0;
if (myisam_flush)
{
+ if (share->file_map)
+ my_msync(info->dfile, share->file_map, share->mmaped_length, MS_SYNC);
if (mysql_file_sync(share->kfile, MYF(0)))
mark_crashed= error= my_errno;
if (mysql_file_sync(info->dfile, MYF(0)))
@@ -526,6 +528,8 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
#ifdef _WIN32
if (myisam_flush)
{
+ if (share->file_map)
+ my_msync(info->dfile, share->file_map, share->mmaped_length, MS_SYNC);
mysql_file_sync(share->kfile, 0);
mysql_file_sync(info->dfile, 0);
}
@@ -608,7 +612,7 @@ int _mi_mark_file_changed(MI_INFO *info)
{
mi_int2store(buff,share->state.open_count);
buff[2]=1; /* Mark that it's changed */
- DBUG_RETURN(mysql_file_pwrite(share->kfile, buff, sizeof(buff),
+ DBUG_RETURN((int)mysql_file_pwrite(share->kfile, buff, sizeof(buff),
sizeof(share->state.header),
MYF(MY_NABP)));
}
@@ -637,9 +641,9 @@ int _mi_decrement_open_count(MI_INFO *info)
{
share->state.open_count--;
mi_int2store(buff,share->state.open_count);
- write_error= mysql_file_pwrite(share->kfile, buff, sizeof(buff),
+ write_error= (mysql_file_pwrite(share->kfile, buff, sizeof(buff),
sizeof(share->state.header),
- MYF(MY_NABP));
+ MYF(MY_NABP)) != 0);
}
if (!lock_error && !my_disable_locking)
lock_error=mi_lock_database(info,old_lock);
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 41b0e18da02..a50fe0879c3 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -127,7 +127,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share= &share_buff;
bzero((uchar*) &share_buff,sizeof(share_buff));
share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
- strlen(name_buff),
+ (uint)strlen(name_buff),
dflt_key_cache);
DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_open",
@@ -342,7 +342,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
(char*) key_del, (sizeof(my_off_t) *
share->state.header.max_block_size_index));
strmov(share->unique_file_name, name_buff);
- share->unique_name_length= strlen(name_buff);
+ share->unique_name_length= (uint)strlen(name_buff);
strmov(share->index_file_name, index_name);
strmov(share->data_file_name, data_name);
@@ -687,7 +687,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
if (myisam_log_file >= 0)
{
intern_filename(name_buff,share->index_file_name);
- _myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
+ _myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, (uint)strlen(name_buff));
}
DBUG_RETURN(m_info);
diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c
index fc32bb7e518..242bc82bd16 100644
--- a/storage/myisam/mi_packrec.c
+++ b/storage/myisam/mi_packrec.c
@@ -1551,7 +1551,7 @@ void _mi_unmap_file(MI_INFO *info)
{
DBUG_ASSERT(info->s->options & HA_OPTION_COMPRESS_RECORD);
- (void) my_munmap((char*) info->s->file_map, (size_t) info->s->mmaped_length);
+ (void) my_munmap((char*) info->s->file_map, info->s->mmaped_length);
if (myisam_mmap_size != SIZE_T_MAX)
{
diff --git a/storage/myisam/mi_preload.c b/storage/myisam/mi_preload.c
index e0d23e0fca0..5c782defcde 100644
--- a/storage/myisam/mi_preload.c
+++ b/storage/myisam/mi_preload.c
@@ -98,7 +98,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
{
if (key_cache_insert(share->key_cache,
share->kfile, pos, DFLT_INIT_HITS,
- (uchar*) buff, block_length))
+ buff, (uint)block_length))
goto err;
}
pos+= block_length;
@@ -110,7 +110,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
{
if (key_cache_insert(share->key_cache,
share->kfile, pos, DFLT_INIT_HITS,
- (uchar*) buff, length))
+ (uchar*) buff, (uint)length))
goto err;
pos+= length;
}
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index 79ed846ce7e..d570f273b74 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -607,11 +607,11 @@ void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
@@ -728,13 +728,13 @@ void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 8: *buff++=0;
- /* fall trough */
+ /* fall through */
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c
index bc1f6438e31..61e992694d2 100644
--- a/storage/myisam/mi_test1.c
+++ b/storage/myisam/mi_test1.c
@@ -386,7 +386,7 @@ static void create_key(uchar *key,uint rownr)
}
if (keyinfo[0].seg[0].flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART))
{
- uint tmp;
+ size_t tmp;
create_key_part(key+2,rownr);
tmp=strlen((char*) key+2);
int2store(key,tmp);
@@ -411,7 +411,7 @@ static void create_record(uchar *record,uint rownr)
pos=record+1;
if (recinfo[1].type == FIELD_BLOB)
{
- uint tmp;
+ size_t tmp;
uchar *ptr;
create_key_part(blob_key,rownr);
tmp=strlen((char*) blob_key);
@@ -422,7 +422,7 @@ static void create_record(uchar *record,uint rownr)
}
else if (recinfo[1].type == FIELD_VARCHAR)
{
- uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
+ size_t tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
create_key_part(pos+pack_length,rownr);
tmp= strlen((char*) pos+pack_length);
if (pack_length == 1)
@@ -438,7 +438,7 @@ static void create_record(uchar *record,uint rownr)
}
if (recinfo[2].type == FIELD_BLOB)
{
- uint tmp;
+ size_t tmp;
uchar *ptr;;
sprintf((char*) blob_record,"... row: %d", rownr);
strappend((char*) blob_record,MY_MAX(MAX_REC_LENGTH-rownr,10),' ');
@@ -449,7 +449,7 @@ static void create_record(uchar *record,uint rownr)
}
else if (recinfo[2].type == FIELD_VARCHAR)
{
- uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
+ size_t tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
sprintf((char*) pos+pack_length, "... row: %d", rownr);
tmp= strlen((char*) pos+pack_length);
if (pack_length == 1)
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index 2e36c364453..e2f99177894 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -727,7 +727,7 @@ get_one_option(int optid,
case 2:
method_conv= MI_STATS_METHOD_IGNORE_NULLS;
break;
- default: assert(0); /* Impossible */
+ default: abort(); /* Impossible */
}
check_param.stats_method= method_conv;
break;
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index 1431f98ec1b..41ad0e8dd7f 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -225,7 +225,7 @@ typedef struct st_mi_isam_share
THR_LOCK lock;
mysql_mutex_t intern_lock; /* Locking for use with _locking */
mysql_rwlock_t *key_root_lock;
- my_off_t mmaped_length;
+ size_t mmaped_length;
uint nonmmaped_inserts; /* counter of writing in non-mmaped
area */
mysql_rwlock_t mmap_lock;
@@ -561,7 +561,7 @@ extern uint _mi_pack_key(MI_INFO *info, uint keynr, uchar *key,
HA_KEYSEG ** last_used_keyseg);
extern int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf);
extern int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos,
- uint length, int re_read_if_possibly);
+ size_t length, int re_read_if_possibly);
extern ulonglong retrieve_auto_increment(MI_INFO *info, const uchar *record);
extern uchar *mi_alloc_rec_buff(MI_INFO *, ulong, uchar **);
@@ -571,7 +571,7 @@ extern uchar *mi_alloc_rec_buff(MI_INFO *, ulong, uchar **);
#define mi_get_rec_buff_len(info,buf) \
(*((uint32 *)(mi_get_rec_buff_ptr(info,buf))))
-extern ulong _mi_rec_unpack(MI_INFO *info, uchar *to, uchar *from,
+extern size_t _mi_rec_unpack(MI_INFO *info, uchar *to, uchar *from,
ulong reclength);
extern my_bool _mi_rec_check(MI_INFO *info,const uchar *record, uchar *packpos,
ulong packed_length, my_bool with_checkum);
diff --git a/storage/myisam/mysql-test/storage_engine/misc.rdiff b/storage/myisam/mysql-test/storage_engine/misc.rdiff
index 39d43d07be2..cdbad003217 100644
--- a/storage/myisam/mysql-test/storage_engine/misc.rdiff
+++ b/storage/myisam/mysql-test/storage_engine/misc.rdiff
@@ -1,16 +1,17 @@
---- suite/storage_engine/misc.result 2013-11-08 21:49:40.000000000 +0400
-+++ suite/storage_engine/misc.reject 2013-11-08 21:51:58.000000000 +0400
-@@ -28,6 +28,9 @@
+--- suite/storage_engine/misc.result 2018-02-23 03:01:49.673249912 +0200
++++ suite/storage_engine/misc.reject 2018-02-23 03:02:05.669249564 +0200
+@@ -28,6 +28,10 @@
SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ORDER BY TABLE_NAME;
TABLE_NAME COLUMN_NAME REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME
+Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
++Warning 1286 Unknown storage engine 'InnoDB'
+Warnings:
column_stats column_name NULL NULL
column_stats db_name NULL NULL
column_stats table_name NULL NULL
-@@ -58,12 +61,6 @@
+@@ -58,12 +62,6 @@
index_stats index_name NULL NULL
index_stats prefix_arity NULL NULL
index_stats table_name NULL NULL
@@ -23,3 +24,11 @@
plugin name NULL NULL
proc db NULL NULL
proc name NULL NULL
+@@ -94,7 +92,5 @@
+ time_zone_transition Transition_time NULL NULL
+ time_zone_transition_type Time_zone_id NULL NULL
+ time_zone_transition_type Transition_type_id NULL NULL
+-transaction_registry commit_id NULL NULL
+-transaction_registry transaction_id NULL NULL
+ user Host NULL NULL
+ user User NULL NULL
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 0cf8305463b..4a35f3666d0 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -120,7 +120,7 @@ static handler *myisammrg_create_handler(handlerton *hton,
ha_myisammrg::ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg)
:handler(hton, table_arg), file(0), is_cloned(0)
{
- init_sql_alloc(&children_mem_root,
+ init_sql_alloc(&children_mem_root, "ha_myisammrg",
FN_REFLEN + ALLOC_ROOT_MIN_BLOCK_SIZE, 0, MYF(0));
}
@@ -233,9 +233,9 @@ extern "C" int myisammrg_parent_open_callback(void *callback_param,
Mrg_child_def *mrg_child_def;
char *db;
char *table_name;
- uint dirlen;
- uint db_length;
- uint table_name_length;
+ size_t dirlen;
+ size_t db_length;
+ size_t table_name_length;
char dir_path[FN_REFLEN];
char name_buf[NAME_LEN];
DBUG_ENTER("myisammrg_parent_open_callback");
@@ -465,27 +465,27 @@ int ha_myisammrg::add_children_list(void)
*/
if (parent_l->parent_l)
{
- my_error(ER_ADMIN_WRONG_MRG_TABLE, MYF(0), parent_l->alias);
+ my_error(ER_ADMIN_WRONG_MRG_TABLE, MYF(0), parent_l->alias.str);
DBUG_RETURN(1);
}
while ((mrg_child_def= it++))
{
TABLE_LIST *child_l;
- char *db;
- char *table_name;
+ LEX_CSTRING db;
+ LEX_CSTRING table_name;
child_l= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST));
- db= (char*) thd->memdup(mrg_child_def->db.str, mrg_child_def->db.length+1);
- table_name= (char*) thd->memdup(mrg_child_def->name.str,
- mrg_child_def->name.length+1);
+ db.str= (char*) thd->memdup(mrg_child_def->db.str, mrg_child_def->db.length+1);
+ db.length= mrg_child_def->db.length;
+ table_name.str= (char*) thd->memdup(mrg_child_def->name.str,
+ mrg_child_def->name.length+1);
+ table_name.length= mrg_child_def->name.length;
- if (child_l == NULL || db == NULL || table_name == NULL)
+ if (child_l == NULL || db.str == NULL || table_name.str == NULL)
DBUG_RETURN(1);
- child_l->init_one_table(db, mrg_child_def->db.length,
- table_name, mrg_child_def->name.length,
- table_name, parent_l->lock_type);
+ child_l->init_one_table(&db, &table_name, 0, parent_l->lock_type);
/* Set parent reference. Used to detect MERGE in children list. */
child_l->parent_l= parent_l;
/* Copy select_lex. Used in unique_table() at least. */
@@ -653,7 +653,7 @@ extern "C" MI_INFO *myisammrg_attach_children_callback(void *callback_param)
if (! child)
{
DBUG_PRINT("error", ("failed to open underlying table '%s'.'%s'",
- child_l->db, child_l->table_name));
+ child_l->db.str, child_l->table_name.str));
/*
This should only happen inside of CHECK/REPAIR TABLE or
for the tables added by the pre-locking code.
@@ -712,7 +712,8 @@ extern "C" MI_INFO *myisammrg_attach_children_callback(void *callback_param)
(current_thd->open_options & HA_OPEN_FOR_REPAIR))
{
char buf[2*NAME_LEN + 1 + 1];
- strxnmov(buf, sizeof(buf) - 1, child_l->db, ".", child_l->table_name, NULL);
+ strxnmov(buf, sizeof(buf) - 1, child_l->db.str, ".",
+ child_l->table_name.str, NULL);
/*
Push an error to be reported as part of CHECK/REPAIR result-set.
Note that calling my_error() from handler is a hack which is kept
@@ -1482,12 +1483,14 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
if (!(ptr= (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
goto err;
- if (!(ptr->table_name= thd->strmake(child_table->table_name,
- child_table->table_name_length)))
+ if (!(ptr->table_name.str= thd->strmake(child_table->table_name.str,
+ child_table->table_name.length)))
goto err;
- if (child_table->db && !(ptr->db= thd->strmake(child_table->db,
- child_table->db_length)))
+ ptr->table_name.length= child_table->table_name.length;
+ if (child_table->db.str && !(ptr->db.str= thd->strmake(child_table->db.str,
+ child_table->db.length)))
goto err;
+ ptr->db.length= child_table->db.length;
create_info->merge_list.elements++;
(*create_info->merge_list.next)= ptr;
@@ -1546,8 +1549,8 @@ int ha_myisammrg::create_mrg(const char *name, HA_CREATE_INFO *create_info)
opened through the table cache. They are opened by db.table_name,
not by their path name.
*/
- uint length= build_table_filename(buff, sizeof(buff),
- tables->db, tables->table_name, "", 0);
+ size_t length= build_table_filename(buff, sizeof(buff),
+ tables->db.str, tables->table_name.str, "", 0);
/*
If a MyISAM table is in the same directory as the MERGE table,
we use the table name without a path. This means that the
@@ -1609,7 +1612,7 @@ void ha_myisammrg::append_create_info(String *packet)
for (first= open_table= children_l;;
open_table= open_table->next_global)
{
- LEX_CSTRING db= { open_table->db, open_table->db_length };
+ LEX_CSTRING db= open_table->db;
if (open_table != first)
packet->append(',');
@@ -1621,8 +1624,7 @@ void ha_myisammrg::append_create_info(String *packet)
append_identifier(thd, packet, db.str, db.length);
packet->append('.');
}
- append_identifier(thd, packet, open_table->table_name,
- open_table->table_name_length);
+ append_identifier(thd, packet, &open_table->table_name);
if (&open_table->next_global == children_last_l)
break;
}
diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h
index 6ace880ab99..1a88cc053e4 100644
--- a/storage/myisammrg/ha_myisammrg.h
+++ b/storage/myisammrg/ha_myisammrg.h
@@ -91,7 +91,7 @@ public:
HA_ANY_INDEX_MAY_BE_UNIQUE | HA_CAN_BIT_FIELD |
HA_HAS_RECORDS | HA_CAN_EXPORT |
HA_NO_COPY_ON_ALTER |
- HA_DUPLICATE_POS);
+ HA_DUPLICATE_POS | HA_CAN_MULTISTEP_MERGE);
}
ulong index_flags(uint inx, uint part, bool all_parts) const
{
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index 7f3937f572d..2dcbb735a8b 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -36,7 +36,8 @@
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{
int save_errno,errpos=0;
- uint files= 0, i, dir_length, length, UNINIT_VAR(key_parts), min_keys= 0;
+ uint files= 0, i, UNINIT_VAR(key_parts), min_keys= 0;
+ size_t length, dir_length;
ulonglong file_offset=0;
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
MYRG_INFO *m_info=0;
@@ -228,7 +229,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name,
int errpos;
int save_errno;
int insert_method;
- uint length;
+ size_t length;
uint child_count;
File fd;
IO_CACHE file_cache;
diff --git a/storage/myisammrg/mysql-test/storage_engine/autoincrement.rdiff b/storage/myisammrg/mysql-test/storage_engine/autoincrement.rdiff
index 68264bdeb8d..cc04b800793 100644
--- a/storage/myisammrg/mysql-test/storage_engine/autoincrement.rdiff
+++ b/storage/myisammrg/mysql-test/storage_engine/autoincrement.rdiff
@@ -12,40 +12,40 @@
@@ -52,14 +52,14 @@
SET sql_mode = '<INITIAL_SQL_MODE>';
SHOW TABLE STATUS FROM test LIKE 't1';
- Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
--t1 <STORAGE_ENGINE> # # # # # # # # 6 # # # # # # #
-+t1 <STORAGE_ENGINE> # # # # # # # # 0 # # # # # # #
+ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+-t1 <STORAGE_ENGINE> # # # # # # # # 6 # # # # # # # # N
++t1 <STORAGE_ENGINE> # # # # # # # # 0 # # # # # # # # N
INSERT INTO t1 (a,b) VALUES (6,'g'),(7,'h');
SELECT LAST_INSERT_ID();
LAST_INSERT_ID()
5
SHOW TABLE STATUS FROM test LIKE 't1';
- Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
--t1 # # # # # # # # # 8 # # # # # # #
-+t1 # # # # # # # # # 0 # # # # # # #
+ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+-t1 # # # # # # # # # 8 # # # # # # # # N
++t1 # # # # # # # # # 0 # # # # # # # # N
INSERT INTO t1 (a,b) VALUES (NULL,'i'),(9,'j');
SELECT a,b FROM t1 ORDER BY a;
a b
@@ -78,11 +78,11 @@
8
SHOW TABLE STATUS FROM test LIKE 't1';
- Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
--t1 # # # # # # # # # 10 # # # # # # #
-+t1 # # # # # # # # # 0 # # # # # # #
+ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+-t1 # # # # # # # # # 10 # # # # # # # # N
++t1 # # # # # # # # # 0 # # # # # # # # N
INSERT INTO t1 (a,b) VALUES (20,'k');
SHOW TABLE STATUS FROM test LIKE 't1';
- Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
--t1 # # # # # # # # # 21 # # # # # # #
-+t1 # # # # # # # # # 0 # # # # # # #
+ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+-t1 # # # # # # # # # 21 # # # # # # # # N
++t1 # # # # # # # # # 0 # # # # # # # # N
INSERT INTO t1 (a,b) VALUES (NULL,'l');
SELECT a,b FROM t1 ORDER BY a;
a b
@@ -103,7 +103,7 @@
21
SHOW TABLE STATUS FROM test LIKE 't1';
- Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
--t1 # # # # # # # # # 22 # # # # # # #
-+t1 # # # # # # # # # 0 # # # # # # #
+ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+-t1 # # # # # # # # # 22 # # # # # # # # N
++t1 # # # # # # # # # 0 # # # # # # # # N
INSERT INTO t1 (a,b) VALUES (-5,'m');
SELECT a,b FROM t1 ORDER BY a;
a b
diff --git a/storage/myisammrg/mysql-test/storage_engine/misc.rdiff b/storage/myisammrg/mysql-test/storage_engine/misc.rdiff
index 2430b055735..cdbad003217 100644
--- a/storage/myisammrg/mysql-test/storage_engine/misc.rdiff
+++ b/storage/myisammrg/mysql-test/storage_engine/misc.rdiff
@@ -1,16 +1,17 @@
---- suite/storage_engine/misc.result 2013-11-08 21:49:40.000000000 +0400
-+++ suite/storage_engine/misc.reject 2013-11-08 21:58:42.000000000 +0400
-@@ -28,6 +28,9 @@
+--- suite/storage_engine/misc.result 2018-02-23 03:01:49.673249912 +0200
++++ suite/storage_engine/misc.reject 2018-02-23 03:02:05.669249564 +0200
+@@ -28,6 +28,10 @@
SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ORDER BY TABLE_NAME;
TABLE_NAME COLUMN_NAME REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME
+Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
++Warning 1286 Unknown storage engine 'InnoDB'
+Warnings:
column_stats column_name NULL NULL
column_stats db_name NULL NULL
column_stats table_name NULL NULL
-@@ -58,12 +61,6 @@
+@@ -58,12 +62,6 @@
index_stats index_name NULL NULL
index_stats prefix_arity NULL NULL
index_stats table_name NULL NULL
@@ -23,3 +24,11 @@
plugin name NULL NULL
proc db NULL NULL
proc name NULL NULL
+@@ -94,7 +92,5 @@
+ time_zone_transition Transition_time NULL NULL
+ time_zone_transition_type Time_zone_id NULL NULL
+ time_zone_transition_type Transition_type_id NULL NULL
+-transaction_registry commit_id NULL NULL
+-transaction_registry transaction_id NULL NULL
+ user Host NULL NULL
+ user User NULL NULL
diff --git a/storage/myisammrg/mysql-test/storage_engine/truncate_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/truncate_table.rdiff
index bb2e5585910..e429bbdb177 100644
--- a/storage/myisammrg/mysql-test/storage_engine/truncate_table.rdiff
+++ b/storage/myisammrg/mysql-test/storage_engine/truncate_table.rdiff
@@ -3,24 +3,24 @@
@@ -9,19 +9,19 @@
CREATE TABLE t1 (a <INT_COLUMN> KEY AUTO_INCREMENT, c <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
SHOW TABLE STATUS LIKE 't1';
- Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
--t1 # # # # # # # # # 1 # # # # # # #
-+t1 # # # # # # # # # 0 # # # # # # #
+ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+-t1 # # # # # # # # # 1 # # # # # # # # N
++t1 # # # # # # # # # 0 # # # # # # # # N
INSERT INTO t1 (c) VALUES ('a'),('b'),('c');
SHOW TABLE STATUS LIKE 't1';
- Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
--t1 # # # # # # # # # 4 # # # # # # #
-+t1 # # # # # # # # # 0 # # # # # # #
+ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+-t1 # # # # # # # # # 4 # # # # # # # # N
++t1 # # # # # # # # # 0 # # # # # # # # N
TRUNCATE TABLE t1;
SHOW TABLE STATUS LIKE 't1';
- Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
--t1 # # # # # # # # # 1 # # # # # # #
-+t1 # # # # # # # # # 0 # # # # # # #
+ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+-t1 # # # # # # # # # 1 # # # # # # # # N
++t1 # # # # # # # # # 0 # # # # # # # # N
INSERT INTO t1 (c) VALUES ('d');
SHOW TABLE STATUS LIKE 't1';
- Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
--t1 # # # # # # # # # 2 # # # # # # #
-+t1 # # # # # # # # # 0 # # # # # # #
+ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+-t1 # # # # # # # # # 2 # # # # # # # # N
++t1 # # # # # # # # # 0 # # # # # # # # N
SELECT a,c FROM t1;
a c
1 d
diff --git a/storage/oqgraph/graphcore.cc b/storage/oqgraph/graphcore.cc
index bf454aa3333..31284a7e9a1 100644
--- a/storage/oqgraph/graphcore.cc
+++ b/storage/oqgraph/graphcore.cc
@@ -330,6 +330,40 @@ namespace open_query {
};
template <typename P, typename D>
+ struct GRAPHCORE_INTERNAL oqgraph_visit_leaves
+ : public base_visitor< oqgraph_visit_leaves<P,D> >
+ {
+ typedef on_finish_vertex event_filter;
+
+ oqgraph_visit_leaves(const P& p, const D& d,
+ stack_cursor *cursor)
+ : seq(0), m_cursor(*cursor), m_p(p), m_d(d)
+ { assert(cursor); }
+
+ template<class T, class Graph>
+ void operator()(T u, Graph &g)
+ {
+ typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ boost::tuples::tie(ei, ei_end) = out_edges(u, g);
+ if (ei == ei_end)
+ {
+ m_cursor.results.push(reference(++seq, u, m_d[ u ]));
+ }
+ }
+ private:
+ int seq;
+ stack_cursor &m_cursor;
+ P m_p;
+ D m_d;
+ };
+
+ template <typename P, typename D>
+ oqgraph_visit_leaves<P,D>
+ make_oqgraph_visit_leaves(const P& p, const D& d, stack_cursor *cursor)
+ { return oqgraph_visit_leaves<P,D>(p, d, cursor); }
+
+
+ template <typename P, typename D>
struct GRAPHCORE_INTERNAL oqgraph_visit_dist
: public base_visitor< oqgraph_visit_dist<P,D> >
{
@@ -829,6 +863,7 @@ namespace open_query
case DIJKSTRAS | HAVE_ORIG:
case BREADTH_FIRST | HAVE_ORIG:
+ case LEAVES | HAVE_ORIG:
if ((cursor= new (std::nothrow) stack_cursor(share)) && (orig || dest))
{
boost::unordered_map<Vertex, Vertex> p;
@@ -879,6 +914,28 @@ namespace open_query
),
make_two_bit_judy_map(get(vertex_index, share->g)));
break;
+ case LEAVES:
+ breadth_first_visit(share->g, *orig, Q,
+ make_bfs_visitor(
+ std::make_pair(
+ record_predecessors(
+ boost::make_assoc_property_map(p),
+ on_tree_edge()
+ ),
+ std::make_pair(
+ record_distances(
+ boost::make_assoc_property_map(d),
+ on_tree_edge()
+ ),
+ make_oqgraph_visit_leaves(
+ boost::make_assoc_property_map(p),
+ boost::make_assoc_property_map(d),
+ static_cast<stack_cursor*>(cursor)
+ )
+ ))
+ ),
+ make_two_bit_judy_map(get(vertex_index, share->g)));
+ break;
default:
abort();
}
@@ -886,6 +943,7 @@ namespace open_query
break;
case BREADTH_FIRST | HAVE_DEST:
case DIJKSTRAS | HAVE_DEST:
+ case LEAVES | HAVE_DEST:
if ((cursor= new (std::nothrow) stack_cursor(share)) && (orig || dest))
{
boost::unordered_map<Vertex, Vertex> p;
@@ -937,6 +995,28 @@ namespace open_query
),
make_two_bit_judy_map(get(vertex_index, r)));
break;
+ case LEAVES:
+ breadth_first_visit(r, *dest, Q,
+ make_bfs_visitor(
+ std::make_pair(
+ record_predecessors(
+ boost::make_assoc_property_map(p),
+ on_tree_edge()
+ ),
+ std::make_pair(
+ record_distances(
+ boost::make_assoc_property_map(d),
+ on_tree_edge()
+ ),
+ make_oqgraph_visit_leaves(
+ boost::make_assoc_property_map(p),
+ boost::make_assoc_property_map(d),
+ static_cast<stack_cursor*>(cursor)
+ )
+ ))
+ ),
+ make_two_bit_judy_map(get(vertex_index, r)));
+ break;
default:
abort();
}
diff --git a/storage/oqgraph/graphcore.h b/storage/oqgraph/graphcore.h
index 7fa3d4554bf..c954b8b029a 100644
--- a/storage/oqgraph/graphcore.h
+++ b/storage/oqgraph/graphcore.h
@@ -70,6 +70,7 @@ namespace open_query
DIJKSTRAS = 1,
BREADTH_FIRST = 2,
NUM_SEARCH_OP = 3,
+ LEAVES = 4,
ALGORITHM = 0x0ffff,
HAVE_ORIG = 0x10000,
diff --git a/storage/oqgraph/ha_oqgraph.cc b/storage/oqgraph/ha_oqgraph.cc
index 82b78285a49..bd2224e1ad2 100644
--- a/storage/oqgraph/ha_oqgraph.cc
+++ b/storage/oqgraph/ha_oqgraph.cc
@@ -87,6 +87,7 @@ static const oqgraph_latch_op_table latch_ops_table[] = {
{ "", oqgraph::NO_SEARCH } , // suggested by Arjen, use empty string instead of no_search
{ "dijkstras", oqgraph::DIJKSTRAS } ,
{ "breadth_first", oqgraph::BREADTH_FIRST } ,
+ { "leaves", oqgraph::LEAVES },
{ NULL, -1 }
};
@@ -562,7 +563,7 @@ int ha_oqgraph::open(const char *name, int mode, uint test_if_locked)
init_tmp_table_share( thd, share, table->s->db.str, table->s->db.length, options->table_name, "");
// because of that, we need to reinitialize the memroot (to reset MY_THREAD_SPECIFIC flag)
DBUG_ASSERT(share->mem_root.used == NULL); // it's still empty
- init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(&share->mem_root, "share", TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
// What I think this code is doing:
// * Our OQGRAPH table is `database_blah/name`
@@ -621,7 +622,8 @@ int ha_oqgraph::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(-1);
}
- if (enum open_frm_error err= open_table_from_share(thd, share, "",
+ if (enum open_frm_error err= open_table_from_share(thd, share,
+ &empty_clex_str,
(uint) (HA_OPEN_KEYFILE | HA_TRY_READ_ONLY),
EXTRA_RECORD,
thd->open_options, edges, FALSE))
diff --git a/storage/oqgraph/mysql-test/oqgraph/general-Aria.result b/storage/oqgraph/mysql-test/oqgraph/general-Aria.result
index e527705045f..bd0f7ed9ee8 100644
--- a/storage/oqgraph/mysql-test/oqgraph/general-Aria.result
+++ b/storage/oqgraph/mysql-test/oqgraph/general-Aria.result
@@ -195,6 +195,170 @@ from to
SELECT linkid as `from`, destid as `to` FROM graph where latch='0' and destid = 10;
from to
12 10
+# Leaves search tests
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 1;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 2;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 3;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 4;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 5;
+latch origid destid weight seq linkid
+leaves 5 NULL 1 1 7
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 6;
+latch origid destid weight seq linkid
+leaves 6 NULL 2 1 7
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 7;
+latch origid destid weight seq linkid
+leaves 7 NULL 0 1 7
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 8;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 9;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 1;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 2;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 3;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 4;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 5;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 6;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 7;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 8;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 9;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+latch origid destid weight seq linkid
+INSERT INTO graph_base(from_id, to_id) VALUES (10,13);
+INSERT INTO graph_base(from_id, to_id) VALUES (11,14);
+INSERT INTO graph_base(from_id, to_id) VALUES (12,15);
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+latch origid destid weight seq linkid
+leaves 10 NULL 3 3 15
+leaves 10 NULL 2 2 14
+leaves 10 NULL 1 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+latch origid destid weight seq linkid
+leaves 11 NULL 3 3 13
+leaves 11 NULL 2 2 15
+leaves 11 NULL 1 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+latch origid destid weight seq linkid
+leaves 12 NULL 3 3 14
+leaves 12 NULL 2 2 13
+leaves 12 NULL 1 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 13;
+latch origid destid weight seq linkid
+leaves 13 NULL 0 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 14;
+latch origid destid weight seq linkid
+leaves 14 NULL 0 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 15;
+latch origid destid weight seq linkid
+leaves 15 NULL 0 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 13;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 14;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 15;
+latch origid destid weight seq linkid
+DELETE FROM graph_base where from_id=10 and to_id=13;
+DELETE FROM graph_base where from_id=11 and to_id=14;
+DELETE FROM graph_base where from_id=12 and to_id=15;
+INSERT INTO graph_base(from_id, to_id) VALUES (13,10);
+INSERT INTO graph_base(from_id, to_id) VALUES (14,11);
+INSERT INTO graph_base(from_id, to_id) VALUES (15,12);
+INSERT INTO graph_base(from_id, to_id) VALUES (16,1);
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 13;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 14;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 15;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 16;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+latch origid destid weight seq linkid
+leaves NULL 10 3 3 14
+leaves NULL 10 2 2 15
+leaves NULL 10 1 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+latch origid destid weight seq linkid
+leaves NULL 11 3 3 15
+leaves NULL 11 2 2 13
+leaves NULL 11 1 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+latch origid destid weight seq linkid
+leaves NULL 12 3 3 13
+leaves NULL 12 2 2 14
+leaves NULL 12 1 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 13;
+latch origid destid weight seq linkid
+leaves NULL 13 0 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 14;
+latch origid destid weight seq linkid
+leaves NULL 14 0 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 15;
+latch origid destid weight seq linkid
+leaves NULL 15 0 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 1;
+latch origid destid weight seq linkid
+leaves NULL 1 1 1 16
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 2;
+latch origid destid weight seq linkid
+leaves NULL 2 2 1 16
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 3;
+latch origid destid weight seq linkid
+leaves NULL 3 2 1 16
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 4;
+latch origid destid weight seq linkid
+leaves NULL 4 3 1 16
+DELETE FROM graph_base where from_id=13 and to_id=10;
+DELETE FROM graph_base where from_id=14 and to_id=11;
+DELETE FROM graph_base where from_id=15 and to_id=12;
+DELETE FROM graph_base where from_id=16 and to_id=1;
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=2;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=3;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=4;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=6 AND destid=7;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=10 AND destid=11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=10 AND destid=12;
+latch origid destid weight seq linkid
# Breadth-first search tests
SELECT * FROM graph WHERE latch = 'breadth_first' AND origid = 1;
latch origid destid weight seq linkid
diff --git a/storage/oqgraph/mysql-test/oqgraph/general-MyISAM.result b/storage/oqgraph/mysql-test/oqgraph/general-MyISAM.result
index bbf660e7db4..e5b5e958fdf 100644
--- a/storage/oqgraph/mysql-test/oqgraph/general-MyISAM.result
+++ b/storage/oqgraph/mysql-test/oqgraph/general-MyISAM.result
@@ -195,6 +195,170 @@ from to
SELECT linkid as `from`, destid as `to` FROM graph where latch='0' and destid = 10;
from to
12 10
+# Leaves search tests
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 1;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 2;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 3;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 4;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 5;
+latch origid destid weight seq linkid
+leaves 5 NULL 1 1 7
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 6;
+latch origid destid weight seq linkid
+leaves 6 NULL 2 1 7
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 7;
+latch origid destid weight seq linkid
+leaves 7 NULL 0 1 7
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 8;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 9;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 1;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 2;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 3;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 4;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 5;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 6;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 7;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 8;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 9;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+latch origid destid weight seq linkid
+INSERT INTO graph_base(from_id, to_id) VALUES (10,13);
+INSERT INTO graph_base(from_id, to_id) VALUES (11,14);
+INSERT INTO graph_base(from_id, to_id) VALUES (12,15);
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+latch origid destid weight seq linkid
+leaves 10 NULL 3 3 15
+leaves 10 NULL 2 2 14
+leaves 10 NULL 1 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+latch origid destid weight seq linkid
+leaves 11 NULL 3 3 13
+leaves 11 NULL 2 2 15
+leaves 11 NULL 1 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+latch origid destid weight seq linkid
+leaves 12 NULL 3 3 14
+leaves 12 NULL 2 2 13
+leaves 12 NULL 1 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 13;
+latch origid destid weight seq linkid
+leaves 13 NULL 0 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 14;
+latch origid destid weight seq linkid
+leaves 14 NULL 0 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 15;
+latch origid destid weight seq linkid
+leaves 15 NULL 0 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 13;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 14;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 15;
+latch origid destid weight seq linkid
+DELETE FROM graph_base where from_id=10 and to_id=13;
+DELETE FROM graph_base where from_id=11 and to_id=14;
+DELETE FROM graph_base where from_id=12 and to_id=15;
+INSERT INTO graph_base(from_id, to_id) VALUES (13,10);
+INSERT INTO graph_base(from_id, to_id) VALUES (14,11);
+INSERT INTO graph_base(from_id, to_id) VALUES (15,12);
+INSERT INTO graph_base(from_id, to_id) VALUES (16,1);
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 13;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 14;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 15;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 16;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+latch origid destid weight seq linkid
+leaves NULL 10 3 3 14
+leaves NULL 10 2 2 15
+leaves NULL 10 1 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+latch origid destid weight seq linkid
+leaves NULL 11 3 3 15
+leaves NULL 11 2 2 13
+leaves NULL 11 1 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+latch origid destid weight seq linkid
+leaves NULL 12 3 3 13
+leaves NULL 12 2 2 14
+leaves NULL 12 1 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 13;
+latch origid destid weight seq linkid
+leaves NULL 13 0 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 14;
+latch origid destid weight seq linkid
+leaves NULL 14 0 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 15;
+latch origid destid weight seq linkid
+leaves NULL 15 0 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 1;
+latch origid destid weight seq linkid
+leaves NULL 1 1 1 16
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 2;
+latch origid destid weight seq linkid
+leaves NULL 2 2 1 16
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 3;
+latch origid destid weight seq linkid
+leaves NULL 3 2 1 16
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 4;
+latch origid destid weight seq linkid
+leaves NULL 4 3 1 16
+DELETE FROM graph_base where from_id=13 and to_id=10;
+DELETE FROM graph_base where from_id=14 and to_id=11;
+DELETE FROM graph_base where from_id=15 and to_id=12;
+DELETE FROM graph_base where from_id=16 and to_id=1;
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=2;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=3;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=4;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=6 AND destid=7;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=10 AND destid=11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=10 AND destid=12;
+latch origid destid weight seq linkid
# Breadth-first search tests
SELECT * FROM graph WHERE latch = 'breadth_first' AND origid = 1;
latch origid destid weight seq linkid
diff --git a/storage/oqgraph/mysql-test/oqgraph/general-innodb.result b/storage/oqgraph/mysql-test/oqgraph/general-innodb.result
index 927d856bc84..38e3e0a23b4 100644
--- a/storage/oqgraph/mysql-test/oqgraph/general-innodb.result
+++ b/storage/oqgraph/mysql-test/oqgraph/general-innodb.result
@@ -195,6 +195,170 @@ from to
SELECT linkid as `from`, destid as `to` FROM graph where latch='0' and destid = 10;
from to
12 10
+# Leaves search tests
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 1;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 2;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 3;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 4;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 5;
+latch origid destid weight seq linkid
+leaves 5 NULL 1 1 7
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 6;
+latch origid destid weight seq linkid
+leaves 6 NULL 2 1 7
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 7;
+latch origid destid weight seq linkid
+leaves 7 NULL 0 1 7
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 8;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 9;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 1;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 2;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 3;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 4;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 5;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 6;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 7;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 8;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 9;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+latch origid destid weight seq linkid
+INSERT INTO graph_base(from_id, to_id) VALUES (10,13);
+INSERT INTO graph_base(from_id, to_id) VALUES (11,14);
+INSERT INTO graph_base(from_id, to_id) VALUES (12,15);
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+latch origid destid weight seq linkid
+leaves 10 NULL 3 3 15
+leaves 10 NULL 2 2 14
+leaves 10 NULL 1 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+latch origid destid weight seq linkid
+leaves 11 NULL 3 3 13
+leaves 11 NULL 2 2 15
+leaves 11 NULL 1 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+latch origid destid weight seq linkid
+leaves 12 NULL 3 3 14
+leaves 12 NULL 2 2 13
+leaves 12 NULL 1 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 13;
+latch origid destid weight seq linkid
+leaves 13 NULL 0 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 14;
+latch origid destid weight seq linkid
+leaves 14 NULL 0 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 15;
+latch origid destid weight seq linkid
+leaves 15 NULL 0 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 13;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 14;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 15;
+latch origid destid weight seq linkid
+DELETE FROM graph_base where from_id=10 and to_id=13;
+DELETE FROM graph_base where from_id=11 and to_id=14;
+DELETE FROM graph_base where from_id=12 and to_id=15;
+INSERT INTO graph_base(from_id, to_id) VALUES (13,10);
+INSERT INTO graph_base(from_id, to_id) VALUES (14,11);
+INSERT INTO graph_base(from_id, to_id) VALUES (15,12);
+INSERT INTO graph_base(from_id, to_id) VALUES (16,1);
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 13;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 14;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 15;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 16;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+latch origid destid weight seq linkid
+leaves NULL 10 3 3 14
+leaves NULL 10 2 2 15
+leaves NULL 10 1 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+latch origid destid weight seq linkid
+leaves NULL 11 3 3 15
+leaves NULL 11 2 2 13
+leaves NULL 11 1 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+latch origid destid weight seq linkid
+leaves NULL 12 3 3 13
+leaves NULL 12 2 2 14
+leaves NULL 12 1 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 13;
+latch origid destid weight seq linkid
+leaves NULL 13 0 1 13
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 14;
+latch origid destid weight seq linkid
+leaves NULL 14 0 1 14
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 15;
+latch origid destid weight seq linkid
+leaves NULL 15 0 1 15
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 1;
+latch origid destid weight seq linkid
+leaves NULL 1 1 1 16
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 2;
+latch origid destid weight seq linkid
+leaves NULL 2 2 1 16
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 3;
+latch origid destid weight seq linkid
+leaves NULL 3 2 1 16
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 4;
+latch origid destid weight seq linkid
+leaves NULL 4 3 1 16
+DELETE FROM graph_base where from_id=13 and to_id=10;
+DELETE FROM graph_base where from_id=14 and to_id=11;
+DELETE FROM graph_base where from_id=15 and to_id=12;
+DELETE FROM graph_base where from_id=16 and to_id=1;
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=2;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=3;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=4;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=6 AND destid=7;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=10 AND destid=11;
+latch origid destid weight seq linkid
+SELECT * FROM graph WHERE latch='leaves' AND origid=10 AND destid=12;
+latch origid destid weight seq linkid
# Breadth-first search tests
SELECT * FROM graph WHERE latch = 'breadth_first' AND origid = 1;
latch origid destid weight seq linkid
diff --git a/storage/oqgraph/mysql-test/oqgraph/general.inc b/storage/oqgraph/mysql-test/oqgraph/general.inc
index f27b7585dd7..48960f7cadb 100644
--- a/storage/oqgraph/mysql-test/oqgraph/general.inc
+++ b/storage/oqgraph/mysql-test/oqgraph/general.inc
@@ -120,6 +120,100 @@ SELECT linkid as `from`, destid as `to` FROM graph where latch='0' and destid =
SELECT linkid as `from`, destid as `to` FROM graph where latch='0' and destid = 9;
SELECT linkid as `from`, destid as `to` FROM graph where latch='0' and destid = 10;
+--echo # Leaves search tests
+#-- We are asking "Are there nodes reachable from origid, from which no other nodes can be reached"
+#-- We return a row for each leaf node that is reachable, with its id in 'linkid'
+#-- and the weight calculated as "How many _directed_ hops to get there"
+#-- If there is no path from origid to another node then there is no row for that linkid
+#-- 'seq' is the counted distance of the search, thus, the loop link will always have seq 1
+#-- if there are two reachable neighbours, they will have seq 2,3 and so on
+#-- linkid is the other end
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 1;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 2;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 3;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 4;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 5;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 6;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 7;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 8;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 9;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+
+#-- now do it in reverse - using destid find originating vertices
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 1;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 2;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 3;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 4;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 5;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 6;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 7;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 8;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 9;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+
+# Add more leaf nodes
+INSERT INTO graph_base(from_id, to_id) VALUES (10,13);
+INSERT INTO graph_base(from_id, to_id) VALUES (11,14);
+INSERT INTO graph_base(from_id, to_id) VALUES (12,15);
+
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 13;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 14;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 15;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 13;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 14;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 15;
+
+DELETE FROM graph_base where from_id=10 and to_id=13;
+DELETE FROM graph_base where from_id=11 and to_id=14;
+DELETE FROM graph_base where from_id=12 and to_id=15;
+
+# Add some root nodes
+INSERT INTO graph_base(from_id, to_id) VALUES (13,10);
+INSERT INTO graph_base(from_id, to_id) VALUES (14,11);
+INSERT INTO graph_base(from_id, to_id) VALUES (15,12);
+INSERT INTO graph_base(from_id, to_id) VALUES (16,1);
+
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 10;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 11;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 12;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 13;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 14;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 15;
+SELECT * FROM graph WHERE latch = 'leaves' AND origid = 16;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 10;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 11;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 12;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 13;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 14;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 15;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 1;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 2;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 3;
+SELECT * FROM graph WHERE latch = 'leaves' AND destid = 4;
+
+DELETE FROM graph_base where from_id=13 and to_id=10;
+DELETE FROM graph_base where from_id=14 and to_id=11;
+DELETE FROM graph_base where from_id=15 and to_id=12;
+DELETE FROM graph_base where from_id=16 and to_id=1;
+
+# path queries yield no result with "leaves"
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=2;
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=3;
+SELECT * FROM graph WHERE latch='leaves' AND origid=1 AND destid=4;
+SELECT * FROM graph WHERE latch='leaves' AND origid=6 AND destid=7;
+SELECT * FROM graph WHERE latch='leaves' AND origid=10 AND destid=11;
+SELECT * FROM graph WHERE latch='leaves' AND origid=10 AND destid=12;
+
--echo # Breadth-first search tests
#-- We are asking "Is there a path from node 'origid' to (all) other nodes?"
#-- We return a row for each other node that is reachable, with its id in 'linkid'
diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc
index a690bdf911d..1b57a3d38ab 100644
--- a/storage/perfschema/pfs.cc
+++ b/storage/perfschema/pfs.cc
@@ -41,7 +41,6 @@
#include "sp_head.h"
#include "pfs_digest.h"
-using std::min;
/**
@page PAGE_PERFORMANCE_SCHEMA The Performance Schema main page
MySQL PERFORMANCE_SCHEMA implementation.
@@ -1240,9 +1239,9 @@ static enum_operation_type socket_operation_map[]=
static int build_prefix(const LEX_CSTRING *prefix, const char *category,
char *output, int *output_length)
{
- int len= strlen(category);
+ size_t len= strlen(category);
char *out_ptr= output;
- int prefix_length= prefix->length;
+ size_t prefix_length= prefix->length;
if (unlikely((prefix_length + len + 1) >=
PFS_MAX_FULL_PREFIX_NAME_LENGTH))
@@ -1292,7 +1291,7 @@ static int build_prefix(const LEX_CSTRING *prefix, const char *category,
{ \
DBUG_ASSERT(info->m_key != NULL); \
DBUG_ASSERT(info->m_name != NULL); \
- len= strlen(info->m_name); \
+ len= (int)strlen(info->m_name); \
full_length= prefix_length + len; \
if (likely(full_length <= PFS_MAX_INFO_NAME_LENGTH)) \
{ \
@@ -1404,7 +1403,7 @@ static void register_stage_v1(const char *category,
info= *info_array;
DBUG_ASSERT(info != NULL);
DBUG_ASSERT(info->m_name != NULL);
- len= strlen(info->m_name);
+ len= (int)strlen(info->m_name);
full_length= prefix_length + len;
if (likely(full_length <= PFS_MAX_INFO_NAME_LENGTH))
{
@@ -1448,7 +1447,7 @@ static void register_statement_v1(const char *category,
if (info->m_name == NULL)
continue;
- len= strlen(info->m_name);
+ len= (int)strlen(info->m_name);
full_length= prefix_length + len;
if (likely(full_length <= PFS_MAX_INFO_NAME_LENGTH))
{
@@ -1790,7 +1789,7 @@ static void create_file_v1(PSI_file_key key, const char *name, File file)
return;
}
- uint len= strlen(name);
+ uint len= (uint)strlen(name);
PFS_file *pfs_file= find_or_create_file(pfs_thread, klass, name, len, true);
file_handle_array[index]= pfs_file;
@@ -2022,7 +2021,7 @@ static void set_thread_account_v1(const char *user, int user_len,
DBUG_ASSERT((host != NULL) || (host_len == 0));
DBUG_ASSERT(host_len >= 0);
- host_len= min<size_t>(host_len, sizeof(pfs->m_hostname));
+ host_len= MY_MIN(host_len, static_cast<int>(sizeof(pfs->m_hostname)));
if (unlikely(pfs == NULL))
return;
@@ -3965,7 +3964,7 @@ static PSI_file* end_file_open_wait_v1(PSI_file_locker *locker,
PFS_file_class *klass= reinterpret_cast<PFS_file_class*> (state->m_class);
PFS_thread *thread= reinterpret_cast<PFS_thread*> (state->m_thread);
const char *name= state->m_name;
- uint len= strlen(name);
+ uint len= (uint)strlen(name);
PFS_file *pfs_file= find_or_create_file(thread, klass, name, len, true);
state->m_file= reinterpret_cast<PSI_file*> (pfs_file);
}
@@ -3997,7 +3996,7 @@ static void end_file_open_wait_and_bind_to_descriptor_v1
PFS_file_class *klass= reinterpret_cast<PFS_file_class*> (state->m_class);
PFS_thread *thread= reinterpret_cast<PFS_thread*> (state->m_thread);
const char *name= state->m_name;
- uint len= strlen(name);
+ uint len= (uint)strlen(name);
pfs_file= find_or_create_file(thread, klass, name, len, true);
state->m_file= reinterpret_cast<PSI_file*> (pfs_file);
}
@@ -4190,7 +4189,7 @@ static void start_file_close_wait_v1(PSI_file_locker *locker,
case PSI_FILE_DELETE:
thread= reinterpret_cast<PFS_thread*> (state->m_thread);
name= state->m_name;
- len= strlen(name);
+ len= (uint)strlen(name);
pfs_file= find_or_create_file(thread, NULL, name, len, false);
state->m_file= reinterpret_cast<PSI_file*> (pfs_file);
break;
diff --git a/storage/perfschema/pfs_digest.cc b/storage/perfschema/pfs_digest.cc
index 86b05f37fd2..1cc685b7e7b 100644
--- a/storage/perfschema/pfs_digest.cc
+++ b/storage/perfschema/pfs_digest.cc
@@ -340,7 +340,7 @@ void purge_digest(PFS_thread* thread, PFS_digest_key *hash_key)
return;
}
-void PFS_statements_digest_stat::reset_data(unsigned char *token_array, uint length)
+void PFS_statements_digest_stat::reset_data(unsigned char *token_array, size_t length)
{
m_lock.set_dirty();
m_digest_storage.reset(token_array, length);
diff --git a/storage/perfschema/pfs_digest.h b/storage/perfschema/pfs_digest.h
index 429a9f4250a..a61e12d911d 100644
--- a/storage/perfschema/pfs_digest.h
+++ b/storage/perfschema/pfs_digest.h
@@ -61,7 +61,7 @@ struct PFS_ALIGNED PFS_statements_digest_stat
ulonglong m_last_seen;
/** Reset data for this record. */
- void reset_data(unsigned char* token_array, uint length);
+ void reset_data(unsigned char* token_array, size_t length);
/** Reset data and remove index for this record. */
void reset_index(PFS_thread *thread);
};
diff --git a/storage/perfschema/pfs_global.cc b/storage/perfschema/pfs_global.cc
index fe1670d0192..732f70a40df 100644
--- a/storage/perfschema/pfs_global.cc
+++ b/storage/perfschema/pfs_global.cc
@@ -219,6 +219,6 @@ uint pfs_get_socket_address(char *host,
}
/* Return actual IP address string length */
- return (strlen((const char*)host));
+ return ((uint)strlen((const char*)host));
}
diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc
index 9cb2c68dbaf..61819993c39 100644
--- a/storage/perfschema/pfs_instr.cc
+++ b/storage/perfschema/pfs_instr.cc
@@ -1296,7 +1296,7 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
*buf_end= '\0';
normalized_filename= buffer;
- normalized_length= strlen(normalized_filename);
+ normalized_length= (int)strlen(normalized_filename);
PFS_file **entry;
uint retry_count= 0;
diff --git a/storage/perfschema/pfs_instr_class.cc b/storage/perfschema/pfs_instr_class.cc
index 647702c0d8f..3f5fce9e7a2 100644
--- a/storage/perfschema/pfs_instr_class.cc
+++ b/storage/perfschema/pfs_instr_class.cc
@@ -1185,7 +1185,7 @@ PFS_instr_class *sanitize_idle_class(PFS_instr_class *unsafe)
static void set_keys(PFS_table_share *pfs, const TABLE_SHARE *share)
{
- int len;
+ uint len;
KEY *key_info= share->key_info;
PFS_table_key *pfs_key= pfs->m_keys;
PFS_table_key *pfs_key_last= pfs->m_keys + share->keys;
@@ -1193,7 +1193,7 @@ static void set_keys(PFS_table_share *pfs, const TABLE_SHARE *share)
for ( ; pfs_key < pfs_key_last; pfs_key++, key_info++)
{
- len= key_info->name.length;
+ len= (uint)key_info->name.length;
memcpy(pfs_key->m_name, key_info->name.str, len);
pfs_key->m_name_length= len;
}
@@ -1215,7 +1215,7 @@ static int compare_keys(PFS_table_share *pfs, const TABLE_SHARE *share)
for ( ; pfs_key < pfs_key_last; pfs_key++, key_info++)
{
- len= key_info->name.length;
+ len= (uint)key_info->name.length;
if (len != pfs_key->m_name_length)
return 1;
@@ -1248,9 +1248,9 @@ PFS_table_share* find_or_create_table_share(PFS_thread *thread,
}
const char *schema_name= share->db.str;
- uint schema_name_length= share->db.length;
+ uint schema_name_length= (uint)share->db.length;
const char *table_name= share->table_name.str;
- uint table_name_length= share->table_name.length;
+ uint table_name_length= (uint)share->table_name.length;
set_table_share_key(&key, temporary,
schema_name, schema_name_length,
diff --git a/storage/perfschema/pfs_server.cc b/storage/perfschema/pfs_server.cc
index ee965c0e7da..eca0f619868 100644
--- a/storage/perfschema/pfs_server.cc
+++ b/storage/perfschema/pfs_server.cc
@@ -249,8 +249,8 @@ void cleanup_instrument_config()
int add_pfs_instr_to_array(const char* name, const char* value)
{
- int name_length= strlen(name);
- int value_length= strlen(value);
+ size_t name_length= strlen(name);
+ size_t value_length= strlen(value);
/* Allocate structure plus string buffers plus null terminators */
PFS_instr_config* e = (PFS_instr_config*)my_malloc(sizeof(PFS_instr_config)
@@ -260,7 +260,7 @@ int add_pfs_instr_to_array(const char* name, const char* value)
/* Copy the instrument name */
e->m_name= (char*)e + sizeof(PFS_instr_config);
memcpy(e->m_name, name, name_length);
- e->m_name_length= name_length;
+ e->m_name_length= (uint)name_length;
e->m_name[name_length]= '\0';
/* Set flags accordingly */
diff --git a/storage/perfschema/table_events_stages.cc b/storage/perfschema/table_events_stages.cc
index 42761d92abf..4d86b131049 100644
--- a/storage/perfschema/table_events_stages.cc
+++ b/storage/perfschema/table_events_stages.cc
@@ -156,7 +156,7 @@ void table_events_stages_common::make_row(PFS_events_stages *stage)
return;
base= base_name(safe_source_file);
- m_row.m_source_length= my_snprintf(m_row.m_source, sizeof(m_row.m_source),
+ m_row.m_source_length= (uint)my_snprintf(m_row.m_source, sizeof(m_row.m_source),
"%s:%d", base, stage->m_source_line);
if (m_row.m_source_length > sizeof(m_row.m_source))
m_row.m_source_length= sizeof(m_row.m_source);
diff --git a/storage/perfschema/table_events_statements.cc b/storage/perfschema/table_events_statements.cc
index fdc63034be5..37237154173 100644
--- a/storage/perfschema/table_events_statements.cc
+++ b/storage/perfschema/table_events_statements.cc
@@ -270,7 +270,7 @@ void table_events_statements_common::make_row_part_1(PFS_events_statements *stat
if (chars > 3)
{
chars-= 3;
- size_t bytes_offset= m_row.m_sqltext.charpos(chars, 0);
+ uint32 bytes_offset= m_row.m_sqltext.charpos(chars, 0);
m_row.m_sqltext.length(bytes_offset);
m_row.m_sqltext.append("...", 3);
}
diff --git a/storage/perfschema/table_events_waits.cc b/storage/perfschema/table_events_waits.cc
index 01f8cd5e6b5..ec5acfefeb1 100644
--- a/storage/perfschema/table_events_waits.cc
+++ b/storage/perfschema/table_events_waits.cc
@@ -427,7 +427,7 @@ void table_events_waits_common::make_row(bool thread_own_wait,
return;
base= base_name(wait->m_source_file);
- m_row.m_source_length= my_snprintf(m_row.m_source, sizeof(m_row.m_source),
+ m_row.m_source_length= (uint)my_snprintf(m_row.m_source, sizeof(m_row.m_source),
"%s:%d", base, wait->m_source_line);
if (m_row.m_source_length > sizeof(m_row.m_source))
m_row.m_source_length= sizeof(m_row.m_source);
@@ -662,7 +662,7 @@ int table_events_waits_common::read_row_values(TABLE *table,
break;
case 16: /* OPERATION */
operation= &operation_names_map[(int) m_row.m_operation - 1];
- set_field_varchar_utf8(f, operation->str, operation->length);
+ set_field_varchar_utf8(f, operation->str, (uint)operation->length);
break;
case 17: /* NUMBER_OF_BYTES */
if ((m_row.m_operation == OPERATION_TYPE_FILEREAD) ||
diff --git a/storage/perfschema/table_host_cache.cc b/storage/perfschema/table_host_cache.cc
index df13207e578..d9853906b99 100644
--- a/storage/perfschema/table_host_cache.cc
+++ b/storage/perfschema/table_host_cache.cc
@@ -150,7 +150,7 @@ end:
void table_host_cache::make_row(Host_entry *entry, row_host_cache *row)
{
- row->m_ip_length= strlen(entry->ip_key);
+ row->m_ip_length= (int)strlen(entry->ip_key);
strcpy(row->m_ip, entry->ip_key);
row->m_hostname_length= entry->m_hostname_length;
if (row->m_hostname_length > 0)
diff --git a/storage/perfschema/table_setup_consumers.cc b/storage/perfschema/table_setup_consumers.cc
index f3529eb8846..b4cb359c0d2 100644
--- a/storage/perfschema/table_setup_consumers.cc
+++ b/storage/perfschema/table_setup_consumers.cc
@@ -174,7 +174,7 @@ int table_setup_consumers::read_row_values(TABLE *table,
switch(f->field_index)
{
case 0: /* NAME */
- set_field_varchar_utf8(f, m_row->m_name.str, m_row->m_name.length);
+ set_field_varchar_utf8(f, m_row->m_name.str,(uint) m_row->m_name.length);
break;
case 1: /* ENABLED */
set_field_enum(f, (*m_row->m_enabled_ptr) ? ENUM_YES : ENUM_NO);
diff --git a/storage/perfschema/table_setup_timers.cc b/storage/perfschema/table_setup_timers.cc
index 9c6af49595d..6020548abaa 100644
--- a/storage/perfschema/table_setup_timers.cc
+++ b/storage/perfschema/table_setup_timers.cc
@@ -129,7 +129,7 @@ int table_setup_timers::read_row_values(TABLE *table,
switch(f->field_index)
{
case 0: /* NAME */
- set_field_varchar_utf8(f, m_row->m_name.str, m_row->m_name.length);
+ set_field_varchar_utf8(f, m_row->m_name.str,(uint) m_row->m_name.length);
break;
case 1: /* TIMER_NAME */
set_field_enum(f, *(m_row->m_timer_name_ptr));
diff --git a/storage/perfschema/table_threads.cc b/storage/perfschema/table_threads.cc
index 7be51b2bb20..f5c97ddd175 100644
--- a/storage/perfschema/table_threads.cc
+++ b/storage/perfschema/table_threads.cc
@@ -228,7 +228,7 @@ int table_threads::read_row_values(TABLE *table,
case 7: /* PROCESSLIST_COMMAND */
if (m_row.m_processlist_id != 0)
set_field_varchar_utf8(f, command_name[m_row.m_command].str,
- command_name[m_row.m_command].length);
+ (uint)command_name[m_row.m_command].length);
else
f->set_null();
break;
@@ -257,8 +257,8 @@ int table_threads::read_row_values(TABLE *table,
changed to less than or equal to 64 characters.
*/
set_field_varchar_utf8(f, m_row.m_processlist_state_ptr,
- std::min<uint>(m_row.m_processlist_state_length,
- f->char_length()));
+ MY_MIN(m_row.m_processlist_state_length,
+ f->char_length()));
}
else
f->set_null();
diff --git a/storage/perfschema/unittest/pfs-t.cc b/storage/perfschema/unittest/pfs-t.cc
index b8814f2ad2d..3da18ac30c0 100644
--- a/storage/perfschema/unittest/pfs-t.cc
+++ b/storage/perfschema/unittest/pfs-t.cc
@@ -43,10 +43,10 @@ PFS_file* lookup_file_by_name(const char* name)
{
uint i;
PFS_file *pfs;
- uint len= strlen(name);
+ size_t len= strlen(name);
size_t dirlen;
const char *filename;
- uint filename_length;;
+ size_t filename_length;;
for (i= 0; i < file_max; i++)
{
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index 39553566062..7a6d8ef8765 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -5,17 +5,15 @@ MACRO(SKIP_ROCKSDB_PLUGIN msg)
RETURN()
ENDMACRO()
-IF(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/Makefile AND GIT_EXECUTABLE)
- EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" submodule init
- WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
- EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" submodule update
- WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
-ENDIF()
-
IF (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/Makefile")
SKIP_ROCKSDB_PLUGIN("Missing Makefile in rocksdb directory. Try \"git submodule update\".")
ENDIF()
+CHECK_LIBRARY_EXISTS(rt timer_delete "" HAVE_TIMER_DELETE)
+IF (HAVE_TIMER_DELETE)
+ ADD_DEFINITIONS(-DHAVE_TIMER_DELETE)
+ENDIF(HAVE_TIMER_DELETE)
+
CHECK_FUNCTION_EXISTS(sched_getcpu HAVE_SCHED_GETCPU)
IF(HAVE_SCHED_GETCPU)
ADD_DEFINITIONS(-DHAVE_SCHED_GETCPU=1 -DROCKSDB_SCHED_GETCPU_PRESENT)
@@ -59,6 +57,10 @@ ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SKIP_ROCKSDB_PLUGIN("${OLD_COMPILER_MSG}")
ENDIF()
SET(CXX11_FLAGS "-std=c++11 -stdlib=libstdc++")
+ IF(MSVC)
+ # clang-cl does not work yet
+ SKIP_ROCKSDB_PLUGIN("Clang-cl is not supported")
+ ENDIF()
ELSEIF(MSVC)
IF (MSVC_VERSION LESS 1900)
SKIP_ROCKSDB_PLUGIN("${OLD_COMPILER_MSG}")
@@ -210,6 +212,8 @@ TARGET_LINK_LIBRARIES(sst_dump rocksdblib)
MYSQL_ADD_EXECUTABLE(mysql_ldb tools/mysql_ldb.cc COMPONENT rocksdb-engine)
TARGET_LINK_LIBRARIES(mysql_ldb rocksdb_tools rocksdb_aux_lib)
+INSTALL_SCRIPT(myrocks_hotbackup COMPONENT rocksdb-engine)
+
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET_TARGET_PROPERTIES(rocksdb_tools sst_dump mysql_ldb PROPERTIES COMPILE_FLAGS -frtti)
ENDIF()
@@ -218,7 +222,26 @@ IF(MSVC)
# additional const qualifiers to parameters of the overriden virtual functions
# This creates a lot of warnings, that we silence here.
ADD_DEFINITIONS(/wd4373)
-
# Some checks in C++ runtime that make debug build much slower
ADD_DEFINITIONS(-D_ITERATOR_DEBUG_LEVEL=0)
+
+ # Temporarily disable "conversion from size_t .." warnings
+ IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267")
+ ENDIF()
+ENDIF()
+
+IF(GIT_EXECUTABLE)
+ EXECUTE_PROCESS(
+ COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb
+ OUTPUT_VARIABLE OUT RESULT_VARIABLE RES)
+ IF(RES EQUAL 0)
+ STRING(REGEX REPLACE "\n$" "" ROCKSDB_GIT_HASH "${OUT}")
+ ENDIF()
+ENDIF()
+IF(ROCKSDB_GIT_HASH OR
+ (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/rdb_source_revision.h))
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/rdb_source_revision.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/rdb_source_revision.h )
ENDIF()
diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake
index f7a2cdda46f..5810412f566 100644
--- a/storage/rocksdb/build_rocksdb.cmake
+++ b/storage/rocksdb/build_rocksdb.cmake
@@ -6,11 +6,17 @@ endif()
SET(ROCKSDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb)
INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_BINARY_DIR}
${ROCKSDB_SOURCE_DIR}
${ROCKSDB_SOURCE_DIR}/include
${ROCKSDB_SOURCE_DIR}/third-party/gtest-1.7.0/fused-src
)
+IF(WIN32)
+ INCLUDE_DIRECTORIES(BEFORE
+ ${CMAKE_CURRENT_SOURCE_DIR}/patch)
+ENDIF()
+
list(APPEND CMAKE_MODULE_PATH "${ROCKSDB_SOURCE_DIR}/cmake/modules/")
if(WIN32)
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index dd61a4ed76a..44cec1c2550 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -70,6 +70,7 @@
#include "rocksdb/utilities/memory_util.h"
#include "rocksdb/utilities/sim_cache.h"
#include "util/stop_watch.h"
+#include "./rdb_source_revision.h"
/* MyRocks includes */
#include "./event_listener.h"
@@ -111,6 +112,10 @@ bool thd_binlog_filter_ok(const MYSQL_THD thd);
MYSQL_PLUGIN_IMPORT bool my_disable_leak_check;
+// Needed in rocksdb_init_func
+void ignore_db_dirs_append(const char *dirname_arg);
+
+
namespace myrocks {
static st_global_stats global_stats;
@@ -369,11 +374,11 @@ static my_bool rocksdb_pause_background_work = 0;
static mysql_mutex_t rdb_sysvars_mutex;
static void rocksdb_set_pause_background_work(
- my_core::THD *const thd MY_ATTRIBUTE((__unused__)),
- struct st_mysql_sys_var *const var MY_ATTRIBUTE((__unused__)),
- void *const var_ptr MY_ATTRIBUTE((__unused__)), const void *const save) {
+ my_core::THD *const,
+ struct st_mysql_sys_var *const,
+ void *const, const void *const save) {
RDB_MUTEX_LOCK_CHECK(rdb_sysvars_mutex);
- const bool pause_requested = *static_cast<const bool *>(save);
+ const my_bool pause_requested = *static_cast<const my_bool *>(save);
if (rocksdb_pause_background_work != pause_requested) {
if (pause_requested) {
rdb->PauseBackgroundWork();
@@ -490,6 +495,7 @@ static uint32_t rocksdb_table_stats_sampling_pct;
static my_bool rocksdb_enable_bulk_load_api = 1;
static my_bool rocksdb_print_snapshot_conflict_queries = 0;
static my_bool rocksdb_large_prefix = 0;
+static char* rocksdb_git_hash;
char *compression_types_val=
const_cast<char*>(get_rocksdb_supported_compression_types());
@@ -646,6 +652,11 @@ static MYSQL_SYSVAR_BOOL(enable_bulk_load_api, rocksdb_enable_bulk_load_api,
"Enables using SstFileWriter for bulk loading",
nullptr, nullptr, rocksdb_enable_bulk_load_api);
+static MYSQL_SYSVAR_STR(git_hash, rocksdb_git_hash,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Git revision of the RocksDB library used by MyRocks",
+ nullptr, nullptr, ROCKSDB_GIT_HASH);
+
static MYSQL_THDVAR_STR(tmpdir, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_MEMALLOC,
"Directory for temporary files during DDL operations.",
nullptr, nullptr, "");
@@ -1446,7 +1457,7 @@ static MYSQL_SYSVAR_UINT(
static MYSQL_SYSVAR_STR(datadir, rocksdb_datadir,
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
"RocksDB data directory", nullptr, nullptr,
- "./.rocksdb");
+ "./#rocksdb");
static MYSQL_SYSVAR_STR(supported_compression_types,
compression_types_val,
@@ -1629,6 +1640,7 @@ static struct st_mysql_sys_var *rocksdb_system_variables[] = {
MYSQL_SYSVAR(table_stats_sampling_pct),
MYSQL_SYSVAR(large_prefix),
+ MYSQL_SYSVAR(git_hash),
nullptr};
static rocksdb::WriteOptions
@@ -2228,7 +2240,8 @@ public:
}
void set_sync(bool sync) override {
- m_rocksdb_tx->GetWriteOptions()->sync = sync;
+ if (m_rocksdb_tx)
+ m_rocksdb_tx->GetWriteOptions()->sync = sync;
}
void release_lock(rocksdb::ColumnFamilyHandle *const column_family,
@@ -3142,10 +3155,20 @@ static int rocksdb_commit(handlerton* hton, THD* thd, bool commit_tx)
- For a COMMIT statement that finishes a multi-statement transaction
- For a statement that has its own transaction
*/
+
+ // First, commit without syncing. This establishes the commit order
+ tx->set_sync(false);
if (tx->commit()) {
DBUG_RETURN(HA_ERR_ROCKSDB_COMMIT_FAILED);
}
thd_wakeup_subsequent_commits(thd, 0);
+
+ if (rocksdb_flush_log_at_trx_commit == FLUSH_LOG_SYNC)
+ {
+ rocksdb::Status s= rdb->FlushWAL(true);
+ if (!s.ok())
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+ }
} else {
/*
We get here when committing a statement within a transaction.
@@ -3934,6 +3957,7 @@ static rocksdb::Status check_rocksdb_options_compatibility(
return status;
}
+
/*
Storage Engine initialization function, invoked when plugin is loaded.
*/
@@ -3962,6 +3986,11 @@ static int rocksdb_init_func(void *const p) {
mysql_mutex_init(rdb_mem_cmp_space_mutex_key, &rdb_mem_cmp_space_mutex,
MY_MUTEX_INIT_FAST);
+ const char* initial_rocksdb_datadir_for_ignore_dirs= rocksdb_datadir;
+ if (!strncmp(rocksdb_datadir, "./", 2))
+ initial_rocksdb_datadir_for_ignore_dirs += 2;
+ ignore_db_dirs_append(initial_rocksdb_datadir_for_ignore_dirs);
+
#if defined(HAVE_PSI_INTERFACE)
rdb_collation_exceptions =
new Regex_list_handler(key_rwlock_collation_exception_list);
@@ -5698,6 +5727,41 @@ int ha_rocksdb::open(const char *const name, int mode, uint test_if_locked) {
setup_field_converters();
+ /*
+ MariaDB: adjust field->part_of_key for PK columns. We can only do it here
+ because SE API is just relying on the HA_PRIMARY_KEY_IN_READ_INDEX which
+ does not allow to distinguish between unpack'able and non-unpack'able
+ columns.
+ Upstream uses handler->init_with_fields() but we don't have that call.
+ */
+ {
+ if (!has_hidden_pk(table)) {
+ KEY *const pk_info = &table->key_info[table->s->primary_key];
+ for (uint kp = 0; kp < pk_info->user_defined_key_parts; kp++) {
+ if (!m_pk_descr->can_unpack(kp)) {
+ //
+ uint field_index= pk_info->key_part[kp].field->field_index;
+ table->field[field_index]->part_of_key.clear_all();
+ table->field[field_index]->part_of_key.set_bit(table->s->primary_key);
+ }
+ }
+ }
+
+ for (uint key= 0; key < table->s->keys; key++) {
+ KEY *const key_info = &table->key_info[key];
+ if (key == table->s->primary_key)
+ continue;
+ for (uint kp = 0; kp < key_info->usable_key_parts; kp++) {
+ uint field_index= key_info->key_part[kp].field->field_index;
+ if (m_key_descr_arr[key]->can_unpack(kp)) {
+ table->field[field_index]->part_of_key.set_bit(key);
+ } else {
+ table->field[field_index]->part_of_key.clear_bit(key);
+ }
+ }
+ }
+ }
+
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
/*
@@ -5912,13 +5976,37 @@ rdb_is_index_collation_supported(const my_core::Field *const field) {
const my_core::enum_field_types type = field->real_type();
/* Handle [VAR](CHAR|BINARY) or TEXT|BLOB */
if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_STRING ||
- type == MYSQL_TYPE_BLOB) {
- return RDB_INDEX_COLLATIONS.find(field->charset()->number) !=
- RDB_INDEX_COLLATIONS.end();
+ type == MYSQL_TYPE_BLOB) {
+
+ return (RDB_INDEX_COLLATIONS.find(field->charset()->number) !=
+ RDB_INDEX_COLLATIONS.end()) ||
+ rdb_is_collation_supported(field->charset());
}
return true;
}
+
+static bool
+rdb_field_uses_nopad_collation(const my_core::Field *const field) {
+ const my_core::enum_field_types type = field->real_type();
+ /* Handle [VAR](CHAR|BINARY) or TEXT|BLOB */
+ if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_STRING ||
+ type == MYSQL_TYPE_BLOB) {
+
+ /*
+ This is technically a NOPAD collation but it's a binary collation
+ that we can handle.
+ */
+ if (RDB_INDEX_COLLATIONS.find(field->charset()->number) !=
+ RDB_INDEX_COLLATIONS.end())
+ return false;
+
+ return (field->charset()->state & MY_CS_NOPAD);
+ }
+ return false;
+}
+
+
/*
Create structures needed for storing data in rocksdb. This is called when the
table is created. The structures will be shared by all TABLE* objects.
@@ -6027,8 +6115,7 @@ int ha_rocksdb::create_cfs(
for (uint i = 0; i < tbl_def_arg->m_key_count; i++) {
rocksdb::ColumnFamilyHandle *cf_handle;
- if (rocksdb_strict_collation_check &&
- !is_hidden_pk(i, table_arg, tbl_def_arg) &&
+ if (!is_hidden_pk(i, table_arg, tbl_def_arg) &&
tbl_def_arg->base_tablename().find(tmp_file_prefix) != 0) {
if (!tsys_set)
{
@@ -6040,21 +6127,28 @@ int ha_rocksdb::create_cfs(
for (uint part = 0; part < table_arg->key_info[i].ext_key_parts;
part++)
{
- if (!rdb_is_index_collation_supported(
+ /* MariaDB: disallow NOPAD collations */
+ if (rdb_field_uses_nopad_collation(
+ table_arg->key_info[i].key_part[part].field))
+ {
+ my_error(ER_MYROCKS_CANT_NOPAD_COLLATION, MYF(0));
+ DBUG_RETURN(HA_EXIT_FAILURE);
+ }
+
+ if (rocksdb_strict_collation_check &&
+ !rdb_is_index_collation_supported(
table_arg->key_info[i].key_part[part].field) &&
!rdb_collation_exceptions->matches(tablename_sys)) {
- std::string collation_err;
- for (const auto &coll : RDB_INDEX_COLLATIONS) {
- if (collation_err != "") {
- collation_err += ", ";
- }
- collation_err += get_charset_name(coll);
- }
- my_error(ER_UNSUPPORTED_COLLATION, MYF(0),
- tbl_def_arg->full_tablename().c_str(),
- table_arg->key_info[i].key_part[part].field->field_name.str,
- collation_err.c_str());
- DBUG_RETURN(HA_EXIT_FAILURE);
+
+ char buf[1024];
+ my_snprintf(buf, sizeof(buf),
+ "Indexed column %s.%s uses a collation that does not "
+ "allow index-only access in secondary key and has "
+ "reduced disk space efficiency in primary key.",
+ tbl_def_arg->full_tablename().c_str(),
+ table_arg->key_info[i].key_part[part].field->field_name.str);
+
+ my_error(ER_INTERNAL_ERROR, MYF(ME_JUST_WARNING), buf);
}
}
}
@@ -6062,7 +6156,7 @@ int ha_rocksdb::create_cfs(
// Internal consistency check to make sure that data in TABLE and
// Rdb_tbl_def structures matches. Either both are missing or both are
// specified. Yes, this is critical enough to make it into SHIP_ASSERT.
- SHIP_ASSERT(!table_arg->part_info == tbl_def_arg->base_partition().empty());
+ SHIP_ASSERT(IF_PARTITIONING(!table_arg->part_info,true) == tbl_def_arg->base_partition().empty());
// Generate the name for the column family to use.
bool per_part_match_found = false;
@@ -8301,7 +8395,7 @@ const std::string ha_rocksdb::generate_cf_name(const uint index,
key_comment, table_arg, tbl_def_arg, per_part_match_found,
RDB_CF_NAME_QUALIFIER);
- if (table_arg->part_info != nullptr && !*per_part_match_found) {
+ if (IF_PARTITIONING(table_arg->part_info,nullptr) != nullptr && !*per_part_match_found) {
// At this point we tried to search for a custom CF name for a partition,
// but none was specified. Therefore default one will be used.
return "";
@@ -12263,6 +12357,7 @@ void rocksdb_set_update_cf_options(THD *const /* unused */,
// Basic sanity checking and parsing the options into a map. If this fails
// then there's no point to proceed.
if (!Rdb_cf_options::parse_cf_options(val, &option_map)) {
+ my_free(*reinterpret_cast<char**>(var_ptr));
*reinterpret_cast<char**>(var_ptr) = nullptr;
// NO_LINT_DEBUG
@@ -12331,6 +12426,7 @@ void rocksdb_set_update_cf_options(THD *const /* unused */,
// the CF options. This will results in consistent behavior and avoids
// dealing with cases when only a subset of CF-s was successfully updated.
if (val) {
+ my_free(*reinterpret_cast<char**>(var_ptr));
*reinterpret_cast<char**>(var_ptr) = my_strdup(val, MYF(0));
} else {
*reinterpret_cast<char**>(var_ptr) = nullptr;
@@ -12425,6 +12521,7 @@ void print_keydup_error(TABLE *table, KEY *key, myf errflag,
its name generation.
*/
+
struct st_mysql_storage_engine rocksdb_storage_engine = {
MYSQL_HANDLERTON_INTERFACE_VERSION};
@@ -12441,7 +12538,7 @@ maria_declare_plugin(rocksdb_se){
myrocks::rocksdb_status_vars, /* status variables */
myrocks::rocksdb_system_variables, /* system variables */
"1.0", /* string version */
- MariaDB_PLUGIN_MATURITY_ALPHA /* maturity */
+ myrocks::MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
},
myrocks::rdb_i_s_cfstats, myrocks::rdb_i_s_dbstats,
myrocks::rdb_i_s_perf_context, myrocks::rdb_i_s_perf_context_global,
diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h
index 2949f6d6588..d28cb7552ed 100644
--- a/storage/rocksdb/ha_rocksdb.h
+++ b/storage/rocksdb/ha_rocksdb.h
@@ -1411,4 +1411,7 @@ private:
Rdb_inplace_alter_ctx(const Rdb_inplace_alter_ctx &);
Rdb_inplace_alter_ctx &operator=(const Rdb_inplace_alter_ctx &);
};
+
+const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_GAMMA;
+
} // namespace myrocks
diff --git a/storage/rocksdb/myrocks_hotbackup b/storage/rocksdb/myrocks_hotbackup
new file mode 100755
index 00000000000..ef1e934f3fd
--- /dev/null
+++ b/storage/rocksdb/myrocks_hotbackup
@@ -0,0 +1,686 @@
+#!/usr/bin/env python
+
+from __future__ import division
+from optparse import OptionParser
+import collections
+import signal
+import os
+import stat
+import sys
+import re
+import commands
+import subprocess
+import logging
+import logging.handlers
+import time
+import datetime
+import shutil
+import traceback
+import tempfile
+
+import MySQLdb
+import MySQLdb.connections
+from MySQLdb import OperationalError, ProgrammingError
+
+logger = None
+opts = None
+rocksdb_files = ['MANIFEST', 'CURRENT', 'OPTIONS']
+rocksdb_data_suffix = '.sst'
+rocksdb_wal_suffix = '.log'
+exclude_files = ['master.info', 'relay-log.info', 'worker-relay-log.info',
+ 'auto.cnf', 'gaplock.log', 'ibdata', 'ib_logfile', '.trash']
+wdt_bin = 'wdt'
+
+def is_manifest(fname):
+ for m in rocksdb_files:
+ if fname.startswith(m):
+ return True
+ return False
+
+class Writer(object):
+ a = None
+ def __init__(self):
+ a = None
+
+class StreamWriter(Writer):
+ stream_cmd= ''
+
+ def __init__(self, stream_option):
+ super(StreamWriter, self).__init__()
+ if stream_option == 'tar':
+ self.stream_cmd= 'tar chf -'
+ elif stream_option == 'xbstream':
+ self.stream_cmd= 'xbstream -c'
+ else:
+ raise Exception("Only tar or xbstream is supported as streaming option.")
+
+ def write(self, file_name):
+ rc= os.system(self.stream_cmd + " " + file_name)
+ if (rc != 0):
+ raise Exception("Got error on stream write: " + str(rc) + " " + file_name)
+
+
+class MiscFilesProcessor():
+ datadir = None
+ wildcard = r'.*\.[frm|MYD|MYI|MAD|MAI|MRG|TRG|TRN|ARM|ARZ|CSM|CSV|opt|par]'
+ regex = None
+ start_backup_time = None
+ skip_check_frm_timestamp = None
+
+ def __init__(self, datadir, skip_check_frm_timestamp, start_backup_time):
+ self.datadir = datadir
+ self.regex = re.compile(self.wildcard)
+ self.skip_check_frm_timestamp = skip_check_frm_timestamp
+ self.start_backup_time = start_backup_time
+
+ def process_db(self, db):
+ # do nothing
+ pass
+
+ def process_file(self, path):
+ # do nothing
+ pass
+
+ def check_frm_timestamp(self, fname, path):
+ if not self.skip_check_frm_timestamp and fname.endswith('.frm'):
+ if os.path.getmtime(path) > self.start_backup_time:
+ logger.error('FRM file %s was updated after starting backups. '
+ 'Schema could have changed and the resulting copy may '
+ 'not be valid. Aborting. '
+ '(backup time: %s, file modifled time: %s)',
+ path, datetime.datetime.fromtimestamp(self.start_backup_time).strftime('%Y-%m-%d %H:%M:%S'),
+ datetime.datetime.fromtimestamp(os.path.getmtime(path)).strftime('%Y-%m-%d %H:%M:%S'))
+ raise Exception("Inconsistent frm file timestamp");
+
+ def process(self):
+ os.chdir(self.datadir)
+ for db in self.get_databases():
+ logger.info("Starting MySQL misc file traversal from database %s..", db)
+ self.process_db(db)
+ for f in self.get_files(db):
+ if self.match(f):
+ rel_path = os.path.join(db, f)
+ self.check_frm_timestamp(f, rel_path)
+ self.process_file(rel_path)
+ logger.info("Traversing misc files from data directory..")
+ for f in self.get_files(""):
+ should_skip = False
+ for e in exclude_files:
+ if f.startswith(e) or f.endswith(e):
+ logger.info("Skipping %s", f)
+ should_skip = True
+ break
+ if not should_skip:
+ self.process_file(f)
+
+ def match(self, filename):
+ if self.regex.match(filename):
+ return True
+ else:
+ return False
+
+ def get_databases(self):
+ dbs = []
+ dirs = [ d for d in os.listdir(self.datadir) \
+ if not os.path.isfile(os.path.join(self.datadir,d))]
+ for db in dirs:
+ if not db.startswith('.') and not self._is_socket(db) and not db == "#rocksdb":
+ dbs.append(db)
+ return dbs
+
+ def get_files(self, db):
+ dbdir = self.datadir + "/" + db
+ return [ f for f in os.listdir(dbdir) \
+ if os.path.isfile(os.path.join(dbdir,f))]
+
+ def _is_socket(self, item):
+ mode = os.stat(os.path.join(self.datadir, item)).st_mode
+ if stat.S_ISSOCK(mode):
+ return True
+ return False
+
+
+class MySQLBackup(MiscFilesProcessor):
+ writer = None
+
+ def __init__(self, datadir, writer, skip_check_frm_timestamp, start_backup_time):
+ MiscFilesProcessor.__init__(self, datadir, skip_check_frm_timestamp, start_backup_time)
+ self.writer = writer
+
+ def process_file(self, fname): # overriding base class
+ self.writer.write(fname)
+
+
+class MiscFilesLinkCreator(MiscFilesProcessor):
+ snapshot_dir = None
+
+ def __init__(self, datadir, snapshot_dir, skip_check_frm_timestamp, start_backup_time):
+ MiscFilesProcessor.__init__(self, datadir, skip_check_frm_timestamp, start_backup_time)
+ self.snapshot_dir = snapshot_dir
+
+ def process_db(self, db):
+ snapshot_sub_dir = os.path.join(self.snapshot_dir, db)
+ os.makedirs(snapshot_sub_dir)
+
+ def process_file(self, path):
+ dst_path = os.path.join(self.snapshot_dir, path)
+ os.link(path, dst_path)
+
+
+# RocksDB backup
+class RocksDBBackup():
+ source_dir = None
+ writer = None
+ # sst files sent in this backup round
+ sent_sst = {}
+ # target sst files in this backup round
+ target_sst = {}
+ # sst files sent in all backup rounds
+ total_sent_sst= {}
+ # sum of sst file size sent in this backup round
+ sent_sst_size = 0
+ # sum of target sst file size in this backup round
+ # if sent_sst_size becomes equal to target_sst_size,
+ # it means the backup round finished backing up all sst files
+ target_sst_size = 0
+ # sum of all sst file size sent all backup rounds
+ total_sent_sst_size= 0
+ # sum of all target sst file size from all backup rounds
+ total_target_sst_size = 0
+ show_progress_size_interval= 1073741824 # 1GB
+ wal_files= []
+ manifest_files= []
+ finished= False
+
+ def __init__(self, source_dir, writer, prev):
+ self.source_dir = source_dir
+ self.writer = writer
+ os.chdir(self.source_dir)
+ self.init_target_files(prev)
+
+ def init_target_files(self, prev):
+ sst = {}
+ self.sent_sst = {}
+ self.target_sst= {}
+ self.total_sent_sst = {}
+ self.sent_sst_size = 0
+ self.target_sst_size = 0
+ self.total_sent_sst_size= 0
+ self.total_target_sst_size= 0
+ self.wal_files= []
+ self.manifest_files= []
+
+ for f in os.listdir(self.source_dir):
+ if f.endswith(rocksdb_data_suffix):
+ # exactly the same file (same size) was sent in previous backup rounds
+ if prev is not None and f in prev.total_sent_sst and int(os.stat(f).st_size) == prev.total_sent_sst[f]:
+ continue
+ sst[f]= int(os.stat(f).st_size)
+ self.target_sst_size = self.target_sst_size + os.stat(f).st_size
+ elif is_manifest(f):
+ self.manifest_files.append(f)
+ elif f.endswith(rocksdb_wal_suffix):
+ self.wal_files.append(f)
+ self.target_sst= collections.OrderedDict(sorted(sst.items()))
+
+ if prev is not None:
+ self.total_sent_sst = prev.total_sent_sst
+ self.total_sent_sst_size = prev.total_sent_sst_size
+ self.total_target_sst_size = self.target_sst_size + prev.total_sent_sst_size
+ else:
+ self.total_target_sst_size = self.target_sst_size
+
+ def do_backup_single(self, fname):
+ self.writer.write(fname)
+ os.remove(fname)
+
+ def do_backup_sst(self, fname, size):
+ self.do_backup_single(fname)
+ self.sent_sst[fname]= size
+ self.total_sent_sst[fname]= size
+ self.sent_sst_size = self.sent_sst_size + size
+ self.total_sent_sst_size = self.total_sent_sst_size + size
+
+ def do_backup_manifest(self):
+ for f in self.manifest_files:
+ self.do_backup_single(f)
+
+ def do_backup_wal(self):
+ for f in self.wal_files:
+ self.do_backup_single(f)
+
+ # this is the last snapshot round. backing up all the rest files
+ def do_backup_final(self):
+ logger.info("Backup WAL..")
+ self.do_backup_wal()
+ logger.info("Backup Manifest..")
+ self.do_backup_manifest()
+ self.do_cleanup()
+ self.finished= True
+
+ def do_cleanup(self):
+ shutil.rmtree(self.source_dir)
+ logger.info("Cleaned up checkpoint from %s", self.source_dir)
+
+ def do_backup_until(self, time_limit):
+ logger.info("Starting backup from snapshot: target files %d", len(self.target_sst))
+ start_time= time.time()
+ last_progress_time= start_time
+ progress_size= 0
+ for fname, size in self.target_sst.iteritems():
+ self.do_backup_sst(fname, size)
+ progress_size= progress_size + size
+ elapsed_seconds = time.time() - start_time
+ progress_seconds = time.time() - last_progress_time
+
+ if self.should_show_progress(size):
+ self.show_progress(progress_size, progress_seconds)
+ progress_size=0
+ last_progress_time= time.time()
+
+ if elapsed_seconds > time_limit and self.has_sent_all_sst() is False:
+ logger.info("Snapshot round finished. Elapsed Time: %5.2f. Remaining sst files: %d",
+ elapsed_seconds, len(self.target_sst) - len(self.sent_sst))
+ self.do_cleanup()
+ break;
+ if self.has_sent_all_sst():
+ self.do_backup_final()
+
+ return self
+
+ def should_show_progress(self, size):
+ if int(self.total_sent_sst_size/self.show_progress_size_interval) > int((self.total_sent_sst_size-size)/self.show_progress_size_interval):
+ return True
+ else:
+ return False
+
+ def show_progress(self, size, seconds):
+ logger.info("Backup Progress: %5.2f%% Sent %6.2f GB of %6.2f GB data, Transfer Speed: %6.2f MB/s",
+ self.total_sent_sst_size*100/self.total_target_sst_size,
+ self.total_sent_sst_size/1024/1024/1024,
+ self.total_target_sst_size/1024/1024/1024,
+ size/seconds/1024/1024)
+
+ def print_backup_report(self):
+ logger.info("Sent %6.2f GB of sst files, %d files in total.",
+ self.total_sent_sst_size/1024/1024/1024,
+ len(self.total_sent_sst))
+
+ def has_sent_all_sst(self):
+ if self.sent_sst_size == self.target_sst_size:
+ return True
+ return False
+
+
+class MySQLUtil:
+ @staticmethod
+ def connect(user, password, port, socket=None):
+ if socket:
+ dbh = MySQLdb.Connect(user=user,
+ passwd=password,
+ unix_socket=socket)
+ else:
+ dbh = MySQLdb.Connect(user=user,
+ passwd=password,
+ port=port,
+ host="127.0.0.1")
+ return dbh
+
+ @staticmethod
+ def create_checkpoint(dbh, checkpoint_dir):
+ sql = ("SET GLOBAL rocksdb_create_checkpoint='{0}'"
+ .format(checkpoint_dir))
+ cur= dbh.cursor()
+ cur.execute(sql)
+ cur.close()
+
+ @staticmethod
+ def get_datadir(dbh):
+ sql = "SELECT @@datadir"
+ cur = dbh.cursor()
+ cur.execute(sql)
+ row = cur.fetchone()
+ return row[0]
+
+
+class BackupRunner:
+ datadir = None
+ start_backup_time = None
+
+ def __init__(self, datadir):
+ self.datadir = datadir
+ self.start_backup_time = time.time()
+
+ def start_backup_round(self, backup_round, prev_backup):
+ def signal_handler(*args):
+ logger.info("Got signal. Exit")
+ if b is not None:
+ logger.info("Cleaning up snapshot directory..")
+ b.do_cleanup()
+ sys.exit(1)
+
+ b = None
+ try:
+ signal.signal(signal.SIGINT, signal_handler)
+ w = None
+ if opts.output_stream:
+ w = StreamWriter(opts.output_stream)
+ else:
+ raise Exception("Currently only streaming backup is supported.")
+
+ snapshot_dir = opts.checkpoint_directory + '/' + str(backup_round)
+ dbh = MySQLUtil.connect(opts.mysql_user,
+ opts.mysql_password,
+ opts.mysql_port,
+ opts.mysql_socket)
+ if not self.datadir:
+ self.datadir = MySQLUtil.get_datadir(dbh)
+ logger.info("Set datadir: %s", self.datadir)
+ logger.info("Creating checkpoint at %s", snapshot_dir)
+ MySQLUtil.create_checkpoint(dbh, snapshot_dir)
+ logger.info("Created checkpoint at %s", snapshot_dir)
+ b = RocksDBBackup(snapshot_dir, w, prev_backup)
+ return b.do_backup_until(opts.checkpoint_interval)
+ except Exception as e:
+ logger.error(e)
+ logger.error(traceback.format_exc())
+ if b is not None:
+ logger.info("Cleaning up snapshot directory.")
+ b.do_cleanup()
+ sys.exit(1)
+
+ def backup_mysql(self):
+ try:
+ w = None
+ if opts.output_stream:
+ w = StreamWriter(opts.output_stream)
+ else:
+ raise Exception("Currently only streaming backup is supported.")
+ b = MySQLBackup(self.datadir, w, opts.skip_check_frm_timestamp,
+ self.start_backup_time)
+ logger.info("Taking MySQL misc backups..")
+ b.process()
+ logger.info("MySQL misc backups done.")
+ except Exception as e:
+ logger.error(e)
+ logger.error(traceback.format_exc())
+ sys.exit(1)
+
+
+class WDTBackup:
+ datadir = None
+ start_backup_time = None
+
+ def __init__(self, datadir):
+ self.datadir = datadir
+ self.start_backup_time = time.time()
+
+ def cleanup(self, snapshot_dir, server_log):
+ if server_log:
+ server_log.seek(0)
+ logger.info("WDT server log:")
+ logger.info(server_log.read())
+ server_log.close()
+ if snapshot_dir:
+ logger.info("Cleaning up snapshot dir %s", snapshot_dir)
+ shutil.rmtree(snapshot_dir)
+
+ def backup_with_timeout(self, backup_round):
+ def signal_handler(*args):
+ logger.info("Got signal. Exit")
+ self.cleanup(snapshot_dir, server_log)
+ sys.exit(1)
+
+ logger.info("Starting backup round %d", backup_round)
+ snapshot_dir = None
+ server_log = None
+ try:
+ signal.signal(signal.SIGINT, signal_handler)
+ # create rocksdb snapshot
+ snapshot_dir = os.path.join(opts.checkpoint_directory, str(backup_round))
+ dbh = MySQLUtil.connect(opts.mysql_user,
+ opts.mysql_password,
+ opts.mysql_port,
+ opts.mysql_socket)
+ logger.info("Creating checkpoint at %s", snapshot_dir)
+ MySQLUtil.create_checkpoint(dbh, snapshot_dir)
+ logger.info("Created checkpoint at %s", snapshot_dir)
+
+ # get datadir if not provided
+ if not self.datadir:
+ self.datadir = MySQLUtil.get_datadir(dbh)
+ logger.info("Set datadir: %s", self.datadir)
+
+ # create links for misc files
+ link_creator = MiscFilesLinkCreator(self.datadir, snapshot_dir,
+ opts.skip_check_frm_timestamp,
+ self.start_backup_time)
+ link_creator.process()
+
+ current_path = os.path.join(opts.backupdir, "CURRENT")
+
+ # construct receiver cmd, using the data directory as recovery-id.
+ # we delete the current file because it is not append-only, therefore not
+ # resumable.
+ remote_cmd = (
+ "ssh {0} rm -f {1}; "
+ "{2} -directory {3} -enable_download_resumption "
+ "-recovery_id {4} -start_port 0 -abort_after_seconds {5} {6}"
+ ).format(opts.destination,
+ current_path,
+ wdt_bin,
+ opts.backupdir,
+ self.datadir,
+ opts.checkpoint_interval,
+ opts.extra_wdt_receiver_options)
+ logger.info("WDT remote cmd %s", remote_cmd)
+ server_log = tempfile.TemporaryFile()
+ remote_process = subprocess.Popen(remote_cmd.split(),
+ stdout=subprocess.PIPE,
+ stderr=server_log)
+ wdt_url = remote_process.stdout.readline().strip()
+ if not wdt_url:
+ raise Exception("Unable to get connection url from wdt receiver")
+ sender_cmd = (
+ "{0} -connection_url \'{1}\' -directory {2} -app_name=myrocks "
+ "-avg_mbytes_per_sec {3} "
+ "-enable_download_resumption -abort_after_seconds {4} {5}"
+ ).format(wdt_bin,
+ wdt_url,
+ snapshot_dir,
+ opts.avg_mbytes_per_sec,
+ opts.checkpoint_interval,
+ opts.extra_wdt_sender_options)
+ sender_status = os.system(sender_cmd) >> 8
+ remote_status = remote_process.wait()
+ self.cleanup(snapshot_dir, server_log)
+ # TODO: handle retryable and non-retyable errors differently
+ return (sender_status == 0 and remote_status == 0)
+
+ except Exception as e:
+ logger.error(e)
+ logger.error(traceback.format_exc())
+ self.cleanup(snapshot_dir, server_log)
+ sys.exit(1)
+
+
+def backup_using_wdt():
+ if not opts.destination:
+ logger.error("Must provide remote destination when using WDT")
+ sys.exit(1)
+
+ # TODO: detect whether WDT is installed
+ logger.info("Backing up myrocks to %s using WDT", opts.destination)
+ wdt_backup = WDTBackup(opts.datadir)
+ finished = False
+ backup_round = 1
+ while not finished:
+ start_time = time.time()
+ finished = wdt_backup.backup_with_timeout(backup_round)
+ end_time = time.time()
+ duration_seconds = end_time - start_time
+ if (not finished) and (duration_seconds < opts.checkpoint_interval):
+ # round finished before timeout
+ sleep_duration = (opts.checkpoint_interval - duration_seconds)
+ logger.info("Sleeping for %f seconds", sleep_duration)
+ time.sleep(sleep_duration)
+
+ backup_round = backup_round + 1
+ logger.info("Finished myrocks backup using WDT")
+
+
+def init_logger():
+ global logger
+ logger = logging.getLogger('myrocks_hotbackup')
+ logger.setLevel(logging.INFO)
+ h1= logging.StreamHandler(sys.stderr)
+ f = logging.Formatter("%(asctime)s.%(msecs)03d %(levelname)s %(message)s",
+ "%Y-%m-%d %H:%M:%S")
+ h1.setFormatter(f)
+ logger.addHandler(h1)
+
+backup_wdt_usage = ("Backup using WDT: myrocks_hotbackup "
+ "--user=root --password=pw --stream=wdt "
+ "--checkpoint_dir=<directory where temporary backup hard links "
+ "are created> --destination=<remote host name> --backup_dir="
+ "<remote directory name>. This has to be executed at the src "
+ "host.")
+backup_usage= "Backup: set -o pipefail; myrocks_hotbackup --user=root --password=pw --port=3306 --checkpoint_dir=<directory where temporary backup hard links are created> | ssh -o NoneEnabled=yes remote_server 'tar -xi -C <directory on remote server where backups will be sent>' . You need to execute backup command on a server where you take backups."
+move_back_usage= "Move-Back: myrocks_hotbackup --move_back --datadir=<dest mysql datadir> --rocksdb_datadir=<dest rocksdb datadir> --rocksdb_waldir=<dest rocksdb wal dir> --backup_dir=<where backup files are stored> . You need to execute move-back command on a server where backup files are sent."
+
+
+def parse_options():
+ global opts
+ parser = OptionParser(usage = "\n\n" + backup_usage + "\n\n" + \
+ backup_wdt_usage + "\n\n" + move_back_usage)
+ parser.add_option('-i', '--interval', type='int', dest='checkpoint_interval',
+ default=300,
+ help='Number of seconds to renew checkpoint')
+ parser.add_option('-c', '--checkpoint_dir', type='string', dest='checkpoint_directory',
+ default='/data/mysql/backup/snapshot',
+ help='Local directory name where checkpoints will be created.')
+ parser.add_option('-d', '--datadir', type='string', dest='datadir',
+ default=None,
+ help='backup mode: src MySQL datadir. move_back mode: dest MySQL datadir')
+ parser.add_option('-s', '--stream', type='string', dest='output_stream',
+ default='tar',
+ help='Setting streaming backup options. Currently tar, WDT '
+ 'and xbstream are supported. Default is tar')
+ parser.add_option('--destination', type='string', dest='destination',
+ default='',
+ help='Remote server name. Only used for WDT mode so far.')
+ parser.add_option('--avg_mbytes_per_sec', type='int',
+ dest='avg_mbytes_per_sec',
+ default=500,
+ help='Average backup rate in MBytes/sec. WDT only.')
+ parser.add_option('--extra_wdt_sender_options', type='string',
+ dest='extra_wdt_sender_options',
+ default='',
+ help='Extra options for WDT sender')
+ parser.add_option('--extra_wdt_receiver_options', type='string',
+ dest='extra_wdt_receiver_options',
+ default='',
+ help='Extra options for WDT receiver')
+ parser.add_option('-u', '--user', type='string', dest='mysql_user',
+ default='root',
+ help='MySQL user name')
+ parser.add_option('-p', '--password', type='string', dest='mysql_password',
+ default='',
+ help='MySQL password name')
+ parser.add_option('-P', '--port', type='int', dest='mysql_port',
+ default=3306,
+ help='MySQL port number')
+ parser.add_option('-S', '--socket', type='string', dest='mysql_socket',
+ default=None,
+ help='MySQL socket path. Takes precedence over --port.')
+ parser.add_option('-m', '--move_back', action='store_true', dest='move_back',
+ default=False,
+ help='Moving MyRocks backup files to proper locations.')
+ parser.add_option('-r', '--rocksdb_datadir', type='string', dest='rocksdb_datadir',
+ default=None,
+ help='RocksDB target data directory where backup data files will be moved. Must be empty.')
+ parser.add_option('-w', '--rocksdb_waldir', type='string', dest='rocksdb_waldir',
+ default=None,
+ help='RocksDB target data directory where backup wal files will be moved. Must be empty.')
+ parser.add_option('-b', '--backup_dir', type='string', dest='backupdir',
+ default=None,
+ help='backup mode for WDT: Remote directory to store '
+ 'backup. move_back mode: Locations where backup '
+ 'files are stored.')
+ parser.add_option('-f', '--skip_check_frm_timestamp',
+ dest='skip_check_frm_timestamp',
+ action='store_true', default=False,
+ help='skipping to check if frm files are updated after starting backup.')
+ parser.add_option('-D', '--debug_signal_file', type='string', dest='debug_signal_file',
+ default=None,
+ help='debugging purpose: waiting until the specified file is created')
+
+ opts, args = parser.parse_args()
+
+
+def create_moveback_dir(directory):
+ if not os.path.exists(directory):
+ os.makedirs(directory)
+ else:
+ for f in os.listdir(directory):
+ logger.error("Directory %s has file or directory %s!", directory, f)
+ raise
+
+def print_move_back_usage():
+ logger.warning(move_back_usage)
+
+def move_back():
+ if opts.rocksdb_datadir is None or opts.rocksdb_waldir is None or opts.backupdir is None or opts.datadir is None:
+ print_move_back_usage()
+ sys.exit()
+ create_moveback_dir(opts.datadir)
+ create_moveback_dir(opts.rocksdb_datadir)
+ create_moveback_dir(opts.rocksdb_waldir)
+
+ os.chdir(opts.backupdir)
+ for f in os.listdir(opts.backupdir):
+ if os.path.isfile(os.path.join(opts.backupdir,f)):
+ if f.endswith(rocksdb_wal_suffix):
+ shutil.move(f, opts.rocksdb_waldir)
+ elif f.endswith(rocksdb_data_suffix) or is_manifest(f):
+ shutil.move(f, opts.rocksdb_datadir)
+ else:
+ shutil.move(f, opts.datadir)
+ else: #directory
+ if f.endswith('.rocksdb'):
+ continue
+ shutil.move(f, opts.datadir)
+
+def start_backup():
+ logger.info("Starting backup.")
+ runner = BackupRunner(opts.datadir)
+ b = None
+ backup_round= 1
+ while True:
+ b = runner.start_backup_round(backup_round, b)
+ backup_round = backup_round + 1
+ if b.finished is True:
+ b.print_backup_report()
+ logger.info("RocksDB Backup Done.")
+ break
+ if opts.debug_signal_file:
+ while not os.path.exists(opts.debug_signal_file):
+ logger.info("Waiting until %s is created..", opts.debug_signal_file)
+ time.sleep(1)
+ runner.backup_mysql()
+ logger.info("All Backups Done.")
+
+
+def main():
+ parse_options()
+ init_logger()
+
+ if opts.move_back is True:
+ move_back()
+ elif opts.output_stream == 'wdt':
+ backup_using_wdt()
+ else:
+ start_backup()
+
+if __name__ == "__main__":
+ main()
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/2pc_group_commit.result b/storage/rocksdb/mysql-test/rocksdb/r/2pc_group_commit.result
index a9e80f1562e..ac546a284fc 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/2pc_group_commit.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/2pc_group_commit.result
@@ -14,16 +14,16 @@ SET GLOBAL rocksdb_flush_log_at_trx_commit=1;
select variable_value into @b1 from information_schema.global_status where variable_name='Binlog_commits';
select variable_value into @b2 from information_schema.global_status where variable_name='Binlog_group_commits';
select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced';
-select IF(variable_value - @b1 = 1000, 'OK', 'FAIL') as Binlog_commits
+select IF(variable_value - @b1 = 1000, 'OK', variable_value - @b1 = 1000) as Binlog_commits
from information_schema.global_status where variable_name='Binlog_commits';
Binlog_commits
OK
-select IF(variable_value - @b2 = 1000, 'OK', 'FAIL') as Binlog_group_commits
+select IF(variable_value - @b2 = 1000, 'OK', variable_value - @b2 = 1000) as Binlog_group_commits
from information_schema.global_status where variable_name='Binlog_group_commits';
Binlog_group_commits
OK
# Prepare operations sync, commits don't. We expect slightly more than 1K syncs:
-select IF(variable_value - @b3 between 1000 and 1500, 'OK', 'FAIL') as Rocksdb_wal_synced
+select IF(variable_value - @b3 between 1000 and 1500, 'OK', variable_value - @b3 between 1000 and 1500) as Rocksdb_wal_synced
from information_schema.global_status where variable_name='Rocksdb_wal_synced';
Rocksdb_wal_synced
OK
@@ -33,17 +33,17 @@ OK
select variable_value into @b1 from information_schema.global_status where variable_name='Binlog_commits';
select variable_value into @b2 from information_schema.global_status where variable_name='Binlog_group_commits';
select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced';
-select IF(variable_value - @b1 = 10000, 'OK', 'FAIL') as Binlog_commits
+select IF(variable_value - @b1 = 10000, 'OK', variable_value - @b1 = 10000) as Binlog_commits
from information_schema.global_status where variable_name='Binlog_commits';
Binlog_commits
OK
-select IF(variable_value - @b2 between 100 and 5000, 'OK', 'FAIL') as Binlog_group_commits
+select IF(variable_value - @b2 between 100 and 5000, 'OK', variable_value - @b2 between 100 and 5000) as Binlog_group_commits
from information_schema.global_status where variable_name='Binlog_group_commits';
Binlog_group_commits
OK
-select IF(variable_value - @b3 between 1 and 9000, 'OK', 'FAIL')
+select IF(variable_value - @b3 between 1 and 9000, 'OK', variable_value - @b3 between 1 and 9000)
from information_schema.global_status where variable_name='Rocksdb_wal_synced';
-IF(variable_value - @b3 between 1 and 9000, 'OK', 'FAIL')
+IF(variable_value - @b3 between 1 and 9000, 'OK', variable_value - @b3 between 1 and 9000)
OK
##
# 2PC enabled, MyRocks durability disabled, single thread
@@ -53,17 +53,17 @@ SET GLOBAL rocksdb_flush_log_at_trx_commit=0;
select variable_value into @b1 from information_schema.global_status where variable_name='Binlog_commits';
select variable_value into @b2 from information_schema.global_status where variable_name='Binlog_group_commits';
select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced';
-select IF(variable_value - @b1 = 1000, 'OK', 'FAIL') as Binlog_commits
+select IF(variable_value - @b1 = 1000, 'OK', variable_value - @b1 = 1000) as Binlog_commits
from information_schema.global_status where variable_name='Binlog_commits';
Binlog_commits
OK
-select IF(variable_value - @b2 = 1000, 'OK', 'FAIL') as Binlog_group_commits
+select IF(variable_value - @b2 = 1000, 'OK', variable_value - @b2 = 1000) as Binlog_group_commits
from information_schema.global_status where variable_name='Binlog_group_commits';
Binlog_group_commits
OK
-select IF(variable_value - @b3 < 10, 'OK', 'FAIL')
+select IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10)
from information_schema.global_status where variable_name='Rocksdb_wal_synced';
-IF(variable_value - @b3 < 10, 'OK', 'FAIL')
+IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10)
OK
##
# 2PC enabled, MyRocks durability disabled, concurrent workload
@@ -71,17 +71,17 @@ OK
select variable_value into @b1 from information_schema.global_status where variable_name='Binlog_commits';
select variable_value into @b2 from information_schema.global_status where variable_name='Binlog_group_commits';
select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced';
-select IF(variable_value - @b1 = 10000, 'OK', 'FAIL') as Binlog_commits
+select IF(variable_value - @b1 = 10000, 'OK', variable_value - @b1 = 10000) as Binlog_commits
from information_schema.global_status where variable_name='Binlog_commits';
Binlog_commits
OK
-select IF(variable_value - @b2 < 8000, 'OK', 'FAIL') as Binlog_group_commits
+select IF(variable_value - @b2 < 8000, 'OK', variable_value - @b2 < 8000) as Binlog_group_commits
from information_schema.global_status where variable_name='Binlog_group_commits';
Binlog_group_commits
OK
-select IF(variable_value - @b3 < 10, 'OK', 'FAIL')
+select IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10)
from information_schema.global_status where variable_name='Rocksdb_wal_synced';
-IF(variable_value - @b3 < 10, 'OK', 'FAIL')
+IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10)
OK
SET GLOBAL rocksdb_enable_2pc= @save_rocksdb_enable_2pc;
SET GLOBAL rocksdb_flush_log_at_trx_commit= @save_rocksdb_flush_log_at_trx_commit;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result
index 01fa9f1d35b..6325dc97cf5 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result
@@ -279,8 +279,15 @@ DROP TABLE t1;
set @tmp_rocksdb_strict_collation_check= @@rocksdb_strict_collation_check;
set global rocksdb_strict_collation_check=1;
CREATE TABLE t1 (a INT, b TEXT);
+# MariaDB no longer gives ER_UNSUPPORTED_COLLATION
ALTER TABLE t1 ADD KEY kb(b(10));
-ERROR HY000: Unsupported collation on string indexed column test.t1.b Use binary collation (latin1_bin, binary, utf8_bin).
+ALTER TABLE t1 ADD PRIMARY KEY(a);
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b TEXT collate utf8_general_ci);
+# MariaDB no longer gives ER_UNSUPPORTED_COLLATION
+ALTER TABLE t1 ADD KEY kb(b(10));
+Warnings:
+Warning 1815 Internal error: Indexed column test.t1.b uses a collation that does not allow index-only access in secondary key and has reduced disk space efficiency in primary key.
ALTER TABLE t1 ADD PRIMARY KEY(a);
DROP TABLE t1;
set global rocksdb_strict_collation_check= @tmp_rocksdb_strict_collation_check;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load.result b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load.result
index b931a61e233..90f28929db6 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load.result
@@ -38,20 +38,20 @@ LOAD DATA INFILE <input_file> INTO TABLE t2;
LOAD DATA INFILE <input_file> INTO TABLE t3;
set rocksdb_bulk_load=0;
SHOW TABLE STATUS WHERE name LIKE 't%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned 0 N
ANALYZE TABLE t1, t2, t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
test.t3 analyze status OK
SHOW TABLE STATUS WHERE name LIKE 't%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned 0 N
select count(pk) from t1;
count(pk)
5000000
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_cf.result b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_cf.result
index 947f67434a5..c24d987a906 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_cf.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_cf.result
@@ -38,20 +38,20 @@ LOAD DATA INFILE <input_file> INTO TABLE t2;
LOAD DATA INFILE <input_file> INTO TABLE t3;
set rocksdb_bulk_load=0;
SHOW TABLE STATUS WHERE name LIKE 't%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned 0 N
ANALYZE TABLE t1, t2, t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
test.t3 analyze status OK
SHOW TABLE STATUS WHERE name LIKE 't%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned 0 N
select count(pk) from t1;
count(pk)
5000000
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_cf_and_data.result b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_cf_and_data.result
index 6c38e030afb..b851133ab18 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_cf_and_data.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_cf_and_data.result
@@ -38,20 +38,20 @@ LOAD DATA INFILE <input_file> INTO TABLE t2;
LOAD DATA INFILE <input_file> INTO TABLE t3;
set rocksdb_bulk_load=0;
SHOW TABLE STATUS WHERE name LIKE 't%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned 0 N
ANALYZE TABLE t1, t2, t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
test.t3 analyze status OK
SHOW TABLE STATUS WHERE name LIKE 't%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned 0 N
select count(pk) from t1;
count(pk)
5000000
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_data.result b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_data.result
index e566691af28..efd7c40ed69 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_data.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_rev_data.result
@@ -38,20 +38,20 @@ LOAD DATA INFILE <input_file> INTO TABLE t2;
LOAD DATA INFILE <input_file> INTO TABLE t3;
set rocksdb_bulk_load=0;
SHOW TABLE STATUS WHERE name LIKE 't%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned 0 N
ANALYZE TABLE t1, t2, t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
test.t3 analyze status OK
SHOW TABLE STATUS WHERE name LIKE 't%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL
-t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL 0 N
+t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned 0 N
select count(pk) from t1;
count(pk)
5000000
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_unsorted.result b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_unsorted.result
index 2a7c7bd69fd..2bc8193e94f 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_unsorted.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_unsorted.result
@@ -67,20 +67,20 @@ LOAD DATA INFILE <input_file> INTO TABLE t2;
LOAD DATA INFILE <input_file> INTO TABLE t3;
set rocksdb_bulk_load=0;
SHOW TABLE STATUS WHERE name LIKE 't%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL 0 N
+t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL 0 N
+t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned 0 N
ANALYZE TABLE t1, t2, t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
test.t3 analyze status OK
SHOW TABLE STATUS WHERE name LIKE 't%';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL 0 N
+t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL 0 N
+t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned 0 N
select count(a) from t1;
count(a)
5000000
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result b/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result
index 291effa832c..6850d8dff16 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result
@@ -1,28 +1,30 @@
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
+SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=1;
+create table t1 (a int) engine=rocksdb;
+drop table t1;
select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
TYPE NAME VALUE
MAX_INDEX_ID MAX_INDEX_ID max_index_id
CF_FLAGS 0 default [0]
CF_FLAGS 1 __system__ [0]
+DDL_DROP_INDEX_ONGOING cf_id:0,index_id:max_index_id
select count(*) from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
count(*)
-3
+4
+SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=0;
select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CF_NAME = 'default' and LEVEL = 'Sum' and TYPE = 'KeyIn';
CREATE TABLE t1 (i1 INT, i2 INT, PRIMARY KEY (i1)) ENGINE = ROCKSDB;
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
TYPE NAME VALUE
-BINLOG FILE master-bin.000001
-BINLOG POS 1066
-BINLOG GTID uuid:5
MAX_INDEX_ID MAX_INDEX_ID max_index_id
CF_FLAGS 0 default [0]
CF_FLAGS 1 __system__ [0]
select count(*) from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
count(*)
-6
+3
set global rocksdb_force_flush_memtable_now = true;
set global rocksdb_compact_cf='default';
select case when VALUE-@keysIn >= 3 then 'true' else 'false' end from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CF_NAME = 'default' and LEVEL = 'Sum' and TYPE = 'KeyIn';
@@ -66,7 +68,7 @@ SHOW GLOBAL VARIABLES LIKE 'ROCKSDB_PAUSE_BACKGROUND_WORK';
Variable_name Value
rocksdb_pause_background_work ON
DROP TABLE t3;
-cf_id:0,index_id:267
+cf_id:0,index_id:264
SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=0;
SHOW GLOBAL VARIABLES LIKE 'ROCKSDB_PAUSE_BACKGROUND_WORK';
Variable_name Value
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/issue255.result b/storage/rocksdb/mysql-test/rocksdb/r/issue255.result
index 62875e378a4..be9e6d1167a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/issue255.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/issue255.result
@@ -1,14 +1,14 @@
CREATE TABLE t1 (pk BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT);
INSERT INTO t1 VALUES (5);
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB # Fixed 1 # # # # # 6 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB # Fixed 1 # # # # # 6 NULL NULL NULL latin1_swedish_ci NULL 0 N
INSERT INTO t1 VALUES ('538647864786478647864');
Warnings:
Warning 1264 Out of range value for column 'pk' at row 1
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB # Fixed 2 # # # # # 9223372036854775807 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB # Fixed 2 # # # # # 9223372036854775807 NULL NULL NULL latin1_swedish_ci NULL 0 N
INSERT INTO t1 VALUES ();
ERROR 23000: Duplicate entry '9223372036854775807' for key 'PRIMARY'
SELECT * FROM t1;
@@ -16,6 +16,6 @@ pk
5
9223372036854775807
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB # Fixed 2 # # # # # 9223372036854775807 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB # Fixed 2 # # # # # 9223372036854775807 NULL NULL NULL latin1_swedish_ci NULL 0 N
DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_ignore_dirs.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_ignore_dirs.result
new file mode 100644
index 00000000000..9b91cdb5551
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_ignore_dirs.result
@@ -0,0 +1,9 @@
+#
+# RocksDB plugin adds #rocksdb to ignore_db_dirs
+#
+select @@ignore_db_dirs;
+@@ignore_db_dirs
+#rocksdb
+select @@ignore_db_dirs;
+@@ignore_db_dirs
+aa,bbb,#rocksdb
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
new file mode 100644
index 00000000000..27b1fd1e9af
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
@@ -0,0 +1,83 @@
+#
+# MDEV-14433: RocksDB may show empty or incorrect output with rocksdb_strict_collation_check=off
+#
+set global rocksdb_strict_collation_check=off;
+set @tmp_rscc=@@rocksdb_strict_collation_check;
+CREATE TABLE t1(
+a varchar(10) NOT NULL,
+b char(1) DEFAULT 'X',
+c char(2) NOT NULL DEFAULT '??',
+d varchar(10) NOT NULL,
+e int(11) DEFAULT 0,
+PRIMARY KEY (a,d),
+KEY (e)
+) ENGINE=ROCKSDB DEFAULT CHARSET=utf8;
+insert into t1 select 1,1,1,1,0;
+insert into t1 select 2,1,1,1,0;
+insert into t1 select 3,1,1,1,0;
+explain
+select a from t1 force index(e) where e<10000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range e e 5 NULL # Using index condition
+select a from t1;
+a
+1
+2
+3
+select * from t1;
+a b c d e
+1 1 1 1 0
+2 1 1 1 0
+3 1 1 1 0
+DROP TABLE t1;
+#
+# MDEV-14563: Wrong query plan for query with no PK
+#
+CREATE TABLE t1(
+pk int primary key,
+a varchar(10) NOT NULL,
+e int(11) DEFAULT 0,
+KEY (a)
+) ENGINE=ROCKSDB DEFAULT CHARSET=utf8;
+insert into t1 values (1,1,1),(2,2,2);
+explain select a from t1 where a <'zzz';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 32 NULL # Using where
+CREATE TABLE t2(
+pk int,
+a varchar(10) NOT NULL,
+e int(11) DEFAULT 0,
+KEY (a)
+) ENGINE=ROCKSDB DEFAULT CHARSET=utf8;
+insert into t2 values (1,1,1),(2,2,2);
+explain select a from t2 where a <'zzz';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 32 NULL # Using where
+drop table t1,t2;
+set global rocksdb_strict_collation_check=@tmp_rscc;
+#
+# MDEV-14389: MyRocks and NOPAD collations
+#
+create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb;
+ERROR HY000: MyRocks doesn't currently support collations with "No pad" attribute.
+set global rocksdb_strict_collation_check=off;
+create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb;
+ERROR HY000: MyRocks doesn't currently support collations with "No pad" attribute.
+set global rocksdb_strict_collation_check=@tmp_rscc;
+#
+# MDEV-14679: RocksdB plugin fails to load with "Loading of unknown plugin ROCKSDB_CFSTATS
+#
+select plugin_name, plugin_maturity from information_schema.plugins where plugin_name like '%rocksdb%';
+plugin_name plugin_maturity
+ROCKSDB Gamma
+ROCKSDB_CFSTATS Gamma
+ROCKSDB_DBSTATS Gamma
+ROCKSDB_PERF_CONTEXT Gamma
+ROCKSDB_PERF_CONTEXT_GLOBAL Gamma
+ROCKSDB_CF_OPTIONS Gamma
+ROCKSDB_COMPACTION_STATS Gamma
+ROCKSDB_GLOBAL_INFO Gamma
+ROCKSDB_DDL Gamma
+ROCKSDB_INDEX_FILE_MAP Gamma
+ROCKSDB_LOCKS Gamma
+ROCKSDB_TRX Gamma
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/misc.result b/storage/rocksdb/mysql-test/rocksdb/r/misc.result
index 4a39f1cbff4..6087928b80f 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/misc.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/misc.result
@@ -30,6 +30,7 @@ FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ORDER BY TABLE_NAME;
TABLE_NAME COLUMN_NAME REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
Warnings:
column_stats column_name NULL NULL
column_stats db_name NULL NULL
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
index ed0688c96ad..875950336b6 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
@@ -898,7 +898,7 @@ rocksdb_concurrent_prepare ON
rocksdb_create_checkpoint
rocksdb_create_if_missing ON
rocksdb_create_missing_column_families OFF
-rocksdb_datadir ./.rocksdb
+rocksdb_datadir ./#rocksdb
rocksdb_db_write_buffer_size 0
rocksdb_deadlock_detect OFF
rocksdb_deadlock_detect_depth 50
@@ -924,6 +924,7 @@ rocksdb_force_compute_memtable_stats_cachetime 0
rocksdb_force_flush_memtable_and_lzero_now OFF
rocksdb_force_flush_memtable_now OFF
rocksdb_force_index_records_in_range 0
+rocksdb_git_hash #
rocksdb_hash_index_allow_collision ON
rocksdb_index_type kBinarySearch
rocksdb_info_log_level error_level
@@ -1406,8 +1407,8 @@ drop table t1;
create table t1 (i int primary key auto_increment) engine=RocksDB;
insert into t1 values (null),(null);
show table status like 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 1000 0 # 0 0 0 3 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 1000 0 # 0 0 0 3 NULL NULL NULL latin1_swedish_ci NULL 0 N
drop table t1;
#
# Fix Issue #4: Crash when using pseudo-unique keys
@@ -2500,8 +2501,8 @@ DROP TABLE t1;
CREATE TABLE t1(a INT AUTO_INCREMENT KEY);
INSERT INTO t1 VALUES(0),(-1),(0);
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 1000 0 0 0 0 0 3 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 1000 0 0 0 0 0 3 NULL NULL NULL latin1_swedish_ci NULL 0 N
SELECT * FROM t1;
a
-1
@@ -2511,8 +2512,8 @@ DROP TABLE t1;
CREATE TABLE t1(a INT AUTO_INCREMENT KEY);
INSERT INTO t1 VALUES(0),(10),(0);
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 1000 0 0 0 0 0 12 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 1000 0 0 0 0 0 12 NULL NULL NULL latin1_swedish_ci NULL 0 N
SELECT * FROM t1;
a
1
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rpl_row_triggers.result b/storage/rocksdb/mysql-test/rocksdb/r/rpl_row_triggers.result
index 1d3cd7db641..69acc4a92e8 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rpl_row_triggers.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rpl_row_triggers.result
@@ -1,12 +1,12 @@
include/master-slave.inc
-Warnings:
-Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
-Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
[connection master]
# Test of row replication with triggers on the slave side
+connection master;
CREATE TABLE t1 (C1 CHAR(1) primary key, C2 CHAR(1));
SELECT * FROM t1;
C1 C2
+connection slave;
+connection slave;
SET @old_slave_exec_mode= @@global.slave_exec_mode;
SET @old_slave_run_triggers_for_rbr= @@global.slave_run_triggers_for_rbr;
SET @@global.slave_exec_mode= IDEMPOTENT;
@@ -38,8 +38,11 @@ i0 0
i1 0
u0 0
u1 0
+connection master;
# INSERT triggers test
insert into t1 values ('a','b');
+connection slave;
+connection slave;
SELECT * FROM t2 order by id;
id cnt o n
d0 0
@@ -48,8 +51,11 @@ i0 1 a
i1 1 a
u0 0
u1 0
+connection master;
# UPDATE triggers test
update t1 set C1= 'd';
+connection slave;
+connection slave;
SELECT * FROM t2 order by id;
id cnt o n
d0 0
@@ -58,8 +64,11 @@ i0 1 a
i1 1 a
u0 1 a d
u1 1 a d
+connection master;
# DELETE triggers test
delete from t1 where C1='d';
+connection slave;
+connection slave;
SELECT * FROM t2 order by id;
id cnt o n
d0 1 d
@@ -78,7 +87,10 @@ i0 2 0
i1 2 0
u0 1 a d
u1 1 a d
+connection master;
insert into t1 values ('0','1');
+connection slave;
+connection slave;
SELECT * FROM t2 order by id;
id cnt o n
d0 1 d
@@ -90,32 +102,44 @@ u1 2 0 0
# INSERT triggers which cause also DELETE test
# (insert duplicate row in table referenced by foreign key)
insert into t1 values ('1','1');
+connection master;
drop table if exists t1;
+connection slave;
+connection slave;
SET @@global.slave_exec_mode= @old_slave_exec_mode;
SET @@global.slave_run_triggers_for_rbr= @old_slave_run_triggers_for_rbr;
drop table t2;
+connection master;
CREATE TABLE t1 (i INT);
CREATE TABLE t2 (i INT);
+connection slave;
SET @old_slave_run_triggers_for_rbr= @@global.slave_run_triggers_for_rbr;
SET GLOBAL slave_run_triggers_for_rbr=YES;
CREATE TRIGGER tr AFTER INSERT ON t1 FOR EACH ROW
INSERT INTO t2 VALUES (new.i);
+connection master;
BEGIN;
INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (2);
COMMIT;
+connection slave;
select * from t2;
i
1
2
SET @@global.slave_run_triggers_for_rbr= @old_slave_run_triggers_for_rbr;
+connection master;
drop tables t2,t1;
+connection slave;
# Triggers on slave do not work if master has some
+connection master;
CREATE TABLE t1 (C1 CHAR(1) primary key, C2 CHAR(1));
SELECT * FROM t1;
C1 C2
create trigger t1_dummy before delete on t1 for each row
set @dummy= 1;
+connection slave;
+connection slave;
SET @old_slave_exec_mode= @@global.slave_exec_mode;
SET @old_slave_run_triggers_for_rbr= @@global.slave_run_triggers_for_rbr;
SET @@global.slave_exec_mode= IDEMPOTENT;
@@ -145,8 +169,11 @@ i0 0
i1 0
u0 0
u1 0
+connection master;
# INSERT triggers test
insert into t1 values ('a','b');
+connection slave;
+connection slave;
SELECT * FROM t2 order by id;
id cnt o n
d0 0
@@ -155,8 +182,11 @@ i0 0
i1 0
u0 0
u1 0
+connection master;
# UPDATE triggers test
update t1 set C1= 'd';
+connection slave;
+connection slave;
SELECT * FROM t2 order by id;
id cnt o n
d0 0
@@ -165,8 +195,11 @@ i0 0
i1 0
u0 0
u1 0
+connection master;
# DELETE triggers test
delete from t1 where C1='d';
+connection slave;
+connection slave;
SELECT * FROM t2 order by id;
id cnt o n
d0 0
@@ -185,7 +218,10 @@ i0 1 0
i1 1 0
u0 0
u1 0
+connection master;
insert into t1 values ('0','1');
+connection slave;
+connection slave;
SELECT * FROM t2 order by id;
id cnt o n
d0 0
@@ -197,22 +233,30 @@ u1 0
# INSERT triggers which cause also DELETE test
# (insert duplicate row in table referenced by foreign key)
insert into t1 values ('1','1');
+connection master;
drop table if exists t1;
+connection slave;
+connection slave;
SET @@global.slave_exec_mode= @old_slave_exec_mode;
SET @@global.slave_run_triggers_for_rbr= @old_slave_run_triggers_for_rbr;
drop table t2;
#
# MDEV-5513: Trigger is applied to the rows after first one
#
+connection master;
create table t1 (a int, b int);
create table tlog (a int auto_increment primary key);
set sql_log_bin=0;
create trigger tr1 after insert on t1 for each row insert into tlog values (null);
set sql_log_bin=1;
+connection slave;
+connection slave;
set @slave_run_triggers_for_rbr.saved = @@slave_run_triggers_for_rbr;
set global slave_run_triggers_for_rbr=1;
create trigger tr2 before insert on t1 for each row set new.b = new.a;
+connection master;
insert into t1 values (1,10),(2,20),(3,30);
+connection slave;
select * from t1;
a b
1 10
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/show_table_status.result b/storage/rocksdb/mysql-test/rocksdb/r/show_table_status.result
index 407a8b103bd..989ddc0f03e 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/show_table_status.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/show_table_status.result
@@ -6,13 +6,13 @@ INSERT INTO t2 (a,b) VALUES (1,'bar');
set global rocksdb_force_flush_memtable_now = true;
CREATE TABLE t3 (a INT, b CHAR(8), pk INT PRIMARY KEY) ENGINE=rocksdb CHARACTER SET utf8;
SHOW TABLE STATUS WHERE name IN ( 't1', 't2', 't3' );
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed 2 # # 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t2 ROCKSDB 10 Fixed 1 # # 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t3 ROCKSDB 10 Fixed 1000 # # 0 0 0 NULL NULL NULL NULL utf8_general_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed 2 # # 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL 0 N
+t2 ROCKSDB 10 Fixed 1 # # 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL 0 N
+t3 ROCKSDB 10 Fixed 1000 # # 0 0 0 NULL NULL NULL NULL utf8_general_ci NULL 0 N
SHOW TABLE STATUS WHERE name LIKE 't2';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t2 ROCKSDB 10 Fixed 10000 # # 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t2 ROCKSDB 10 Fixed 10000 # # 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL 0 N
DROP TABLE t1, t2, t3;
CREATE DATABASE `db_new..............................................end`;
USE `db_new..............................................end`;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/truncate_table.result b/storage/rocksdb/mysql-test/rocksdb/r/truncate_table.result
index e6ff6e1ca32..76d00d90420 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/truncate_table.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/truncate_table.result
@@ -8,20 +8,20 @@ a b
DROP TABLE t1;
CREATE TABLE t1 (a INT KEY AUTO_INCREMENT, c CHAR(8)) ENGINE=rocksdb;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed # # # 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed # # # 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL 0 N
INSERT INTO t1 (c) VALUES ('a'),('b'),('c');
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed # # # 0 0 0 4 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed # # # 0 0 0 4 NULL NULL NULL latin1_swedish_ci NULL 0 N
TRUNCATE TABLE t1;
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed # # # 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed # # # 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL 0 N
INSERT INTO t1 (c) VALUES ('d');
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed # # # 0 0 0 2 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed # # # 0 0 0 2 NULL NULL NULL latin1_swedish_ci NULL 0 N
SELECT a,c FROM t1;
a c
1 d
diff --git a/storage/rocksdb/mysql-test/rocksdb/suite.opt b/storage/rocksdb/mysql-test/rocksdb/suite.opt
index f5dc0ce891c..8ca2405f1ef 100644
--- a/storage/rocksdb/mysql-test/rocksdb/suite.opt
+++ b/storage/rocksdb/mysql-test/rocksdb/suite.opt
@@ -1,2 +1 @@
---ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO --default-storage-engine=rocksdb
-
+--plugin-load=$HA_ROCKSDB_SO --default-storage-engine=rocksdb
diff --git a/storage/rocksdb/mysql-test/rocksdb/suite.pm b/storage/rocksdb/mysql-test/rocksdb/suite.pm
index 133d9344414..3423d34ded5 100644
--- a/storage/rocksdb/mysql-test/rocksdb/suite.pm
+++ b/storage/rocksdb/mysql-test/rocksdb/suite.pm
@@ -23,7 +23,6 @@ $ENV{MARIAROCKS_SST_DUMP}="$sst_dump";
# Temporarily disable testing under valgrind, due to MDEV-12439
return "RocksDB tests disabled under valgrind" if ($::opt_valgrind);
-return "Temporarily disabled on Windows due to MDEV-13852" if (My::SysInfo::IS_WINDOWS);
bless { };
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/2pc_group_commit.test b/storage/rocksdb/mysql-test/rocksdb/t/2pc_group_commit.test
index 124d700d51d..d91d54a3543 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/2pc_group_commit.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/2pc_group_commit.test
@@ -1,6 +1,6 @@
--source include/have_rocksdb.inc
--source include/have_log_bin.inc
-
+--source include/not_windows.inc
--echo # Disable for valgrind because this takes too long
--source include/not_valgrind.inc
@@ -31,12 +31,12 @@ select variable_value into @b1 from information_schema.global_status where varia
select variable_value into @b2 from information_schema.global_status where variable_name='Binlog_group_commits';
select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced';
--exec $MYSQL_SLAP --silent --concurrency=1 --number-of-queries=1000 --query="INSERT INTO t1 (id, value) VALUES(NULL, 1)"
-select IF(variable_value - @b1 = 1000, 'OK', 'FAIL') as Binlog_commits
+select IF(variable_value - @b1 = 1000, 'OK', variable_value - @b1 = 1000) as Binlog_commits
from information_schema.global_status where variable_name='Binlog_commits';
-select IF(variable_value - @b2 = 1000, 'OK', 'FAIL') as Binlog_group_commits
+select IF(variable_value - @b2 = 1000, 'OK', variable_value - @b2 = 1000) as Binlog_group_commits
from information_schema.global_status where variable_name='Binlog_group_commits';
--echo # Prepare operations sync, commits don't. We expect slightly more than 1K syncs:
-select IF(variable_value - @b3 between 1000 and 1500, 'OK', 'FAIL') as Rocksdb_wal_synced
+select IF(variable_value - @b3 between 1000 and 1500, 'OK', variable_value - @b3 between 1000 and 1500) as Rocksdb_wal_synced
from information_schema.global_status where variable_name='Rocksdb_wal_synced';
--echo ##
@@ -48,11 +48,11 @@ select variable_value into @b3 from information_schema.global_status where varia
--exec $MYSQL_SLAP --silent --concurrency=50 --number-of-queries=10000 --query="INSERT INTO t1 (id, value) VALUES(NULL, 1)"
-select IF(variable_value - @b1 = 10000, 'OK', 'FAIL') as Binlog_commits
+select IF(variable_value - @b1 = 10000, 'OK', variable_value - @b1 = 10000) as Binlog_commits
from information_schema.global_status where variable_name='Binlog_commits';
-select IF(variable_value - @b2 between 100 and 5000, 'OK', 'FAIL') as Binlog_group_commits
+select IF(variable_value - @b2 between 100 and 5000, 'OK', variable_value - @b2 between 100 and 5000) as Binlog_group_commits
from information_schema.global_status where variable_name='Binlog_group_commits';
-select IF(variable_value - @b3 between 1 and 9000, 'OK', 'FAIL')
+select IF(variable_value - @b3 between 1 and 9000, 'OK', variable_value - @b3 between 1 and 9000)
from information_schema.global_status where variable_name='Rocksdb_wal_synced';
--echo ##
@@ -66,11 +66,11 @@ select variable_value into @b2 from information_schema.global_status where varia
select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced';
--exec $MYSQL_SLAP --silent --concurrency=1 --number-of-queries=1000 --query="INSERT INTO t1 (id, value) VALUES(NULL, 1)"
-select IF(variable_value - @b1 = 1000, 'OK', 'FAIL') as Binlog_commits
+select IF(variable_value - @b1 = 1000, 'OK', variable_value - @b1 = 1000) as Binlog_commits
from information_schema.global_status where variable_name='Binlog_commits';
-select IF(variable_value - @b2 = 1000, 'OK', 'FAIL') as Binlog_group_commits
+select IF(variable_value - @b2 = 1000, 'OK', variable_value - @b2 = 1000) as Binlog_group_commits
from information_schema.global_status where variable_name='Binlog_group_commits';
-select IF(variable_value - @b3 < 10, 'OK', 'FAIL')
+select IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10)
from information_schema.global_status where variable_name='Rocksdb_wal_synced';
--echo ##
@@ -83,11 +83,11 @@ select variable_value into @b3 from information_schema.global_status where varia
--exec $MYSQL_SLAP --silent --concurrency=50 --number-of-queries=10000 --query="INSERT INTO t1 (id, value) VALUES(NULL, 1)"
-select IF(variable_value - @b1 = 10000, 'OK', 'FAIL') as Binlog_commits
+select IF(variable_value - @b1 = 10000, 'OK', variable_value - @b1 = 10000) as Binlog_commits
from information_schema.global_status where variable_name='Binlog_commits';
-select IF(variable_value - @b2 < 8000, 'OK', 'FAIL') as Binlog_group_commits
+select IF(variable_value - @b2 < 8000, 'OK', variable_value - @b2 < 8000) as Binlog_group_commits
from information_schema.global_status where variable_name='Binlog_group_commits';
-select IF(variable_value - @b3 < 10, 'OK', 'FAIL')
+select IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10)
from information_schema.global_status where variable_name='Rocksdb_wal_synced';
##
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test
index c1a91c2a5a2..876ef2c9965 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test
@@ -173,10 +173,17 @@ set @tmp_rocksdb_strict_collation_check= @@rocksdb_strict_collation_check;
set global rocksdb_strict_collation_check=1;
CREATE TABLE t1 (a INT, b TEXT);
---error ER_UNSUPPORTED_COLLATION
+--echo # MariaDB no longer gives ER_UNSUPPORTED_COLLATION
ALTER TABLE t1 ADD KEY kb(b(10));
ALTER TABLE t1 ADD PRIMARY KEY(a);
DROP TABLE t1;
+
+CREATE TABLE t1 (a INT, b TEXT collate utf8_general_ci);
+--echo # MariaDB no longer gives ER_UNSUPPORTED_COLLATION
+ALTER TABLE t1 ADD KEY kb(b(10));
+ALTER TABLE t1 ADD PRIMARY KEY(a);
+DROP TABLE t1;
+
set global rocksdb_strict_collation_check= @tmp_rocksdb_strict_collation_check;
# make sure race condition between connection close and alter on another
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bulk_load.inc b/storage/rocksdb/mysql-test/rocksdb/t/bulk_load.inc
index 42cab5ad8c1..87cb1f70f32 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/bulk_load.inc
+++ b/storage/rocksdb/mysql-test/rocksdb/t/bulk_load.inc
@@ -134,7 +134,7 @@ select count(b) from t3;
# the server starts
--let $tmpext = .bulk_load.tmp
--let $MYSQLD_DATADIR= `SELECT @@datadir`
---let $datadir = $MYSQLD_DATADIR/.rocksdb
+--let $datadir = $MYSQLD_DATADIR/#rocksdb
--write_file $datadir/test$tmpext
dummy data
EOF
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bulk_load_unsorted.test b/storage/rocksdb/mysql-test/rocksdb/t/bulk_load_unsorted.test
index 9d9433eaafa..78bb9312ca5 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/bulk_load_unsorted.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/bulk_load_unsorted.test
@@ -82,6 +82,7 @@ eval CREATE TABLE t3(a INT, b INT, PRIMARY KEY(a) COMMENT "$pk_cf")
perl;
my $fn = $ENV{'ROCKSDB_INFILE'};
open(my $fh, '>', $fn) || die "perl open($fn): $!";
+binmode $fh;
my $max = 5000000;
my $sign = 1;
for (my $ii = 0; $ii < $max; $ii++)
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/compact_deletes_test.inc b/storage/rocksdb/mysql-test/rocksdb/t/compact_deletes_test.inc
index 19a16fbe3a7..0a0d670505f 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/compact_deletes_test.inc
+++ b/storage/rocksdb/mysql-test/rocksdb/t/compact_deletes_test.inc
@@ -44,7 +44,7 @@ perl;
print "wait_for_delete: $ENV{no_more_deletes}\n";
while ($retry++ < $num_retries) {
$total_d=$total_e=0;
- for $f (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/.rocksdb/*.sst>) {
+ for $f (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/#rocksdb/*.sst>) {
# excluding system cf
$filename= "$ENV{MARIAROCKS_SST_DUMP} --command=scan --output_hex --file=$f";
open(D, '-|', $filename) || die("Can't open file $filename: $!");
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
index 118d8598de3..47005c1baff 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
+++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
@@ -41,7 +41,7 @@ rocksdb_deadlock_stress_rr: stress test
##
persistent_cache: Upstream RocksDB bug https://github.com/facebook/mysql-5.6/issues/579
collation: Fails on gcc 4.8 and before, MDEV-12433
-col_opt_zerofill: MDEV-14165: not MyRocks -problem in ps-protocol, happens in upstream too
+col_opt_zerofill: MDEV-14729 (also MDEV-14165 which was fixed): problem in the client
##
@@ -59,7 +59,7 @@ bytes_written: Needs I_S.TABLE_STATISTICS.IO_WRITE_BYTES
trx_info_rpl : MariaRocks: @@rpl_skip_tx_api doesn't work, yet.
rpl_read_free: MDEV-10976
lock_wait_timeout_stats: MDEV-13404
-
+rpl_row_triggers : Requires read-free slave.
##
## Test failures (in buildbot or else where)
@@ -69,18 +69,12 @@ compact_deletes: MDEV-12663 : rocksdb.compact_deletes times out and causes other
blind_delete_without_tx_api: MDEV-12286: rocksdb.blind_delete_without_tx_api test fails
unique_check: wrong error number
autoinc_vars_thread: debug sync point wait timed out
-
-# Enabling these didn't seem to cause any trouble:
-# autoinc_vars_thread : MDEV-12474 Regularly fails on buildbot
-# unique_check : MDEV-12474 Regularly fails on buildbot
-# bloomfilter : MDEV-12474 Regularly fails on buildbot
-# unique_sec : Intermittent failures in BB
-
+information_schema: MDEV-14372: unstable testcase
+bloomfilter: MDEV-14562
##
## Tests that fail for some other reason
##
-information_schema : MariaRocks: requires GTIDs
+
mysqlbinlog_gtid_skip_empty_trans_rocksdb : MariaRocks: requires GTIDs
-#read_only_tx : MariaRocks: requires GTIDs
-rpl_row_triggers : MariaRocks: requires GTIDs
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/drop_table2.test b/storage/rocksdb/mysql-test/rocksdb/t/drop_table2.test
index 14d856cc0c5..a9012aea80a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/drop_table2.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/drop_table2.test
@@ -97,7 +97,7 @@ set @@global.rocksdb_compact_cf = 'rev:cf2';
set @@global.rocksdb_compact_cf = 'default';
perl;
-$size+=-s $_ for (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/.rocksdb/*.sst>);
+$size+=-s $_ for (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/\#rocksdb/*.sst>);
$filename= "$ENV{MYSQLTEST_VARDIR}/tmp/size_output";
open(F, '>', $filename) || die("Can't open file $filename: $!");
print F $size;
@@ -121,7 +121,7 @@ let $wait_condition = select count(*) = 0
# Check that space is reclaimed
perl;
-$size+=-s $_ for (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/.rocksdb/*.sst>);
+$size+=-s $_ for (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/\#rocksdb/*.sst>);
$filename= "$ENV{MYSQLTEST_VARDIR}/tmp/size_output";
open(F, '<', $filename) || die("Can't open file $filename: $!");
$old=<F>;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/information_schema-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/information_schema-master.opt
index 40b14167e17..86379847638 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/information_schema-master.opt
+++ b/storage/rocksdb/mysql-test/rocksdb/t/information_schema-master.opt
@@ -1 +1 @@
---binlog_format=row --gtid_mode=ON --enforce_gtid_consistency --log_slave_updates
+--binlog_format=row --log_slave_updates
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test b/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test
index c8d9b538529..2ffc186dd8f 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test
@@ -9,19 +9,29 @@ DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
--enable_warnings
+# MariaDB: the following is for handling the case where the tests
+# is started on a totally empty datadir, where no MyRocks table has
+# ever been created). In that case, there is no MAX_INDEX_ID.
+# Create/drop a table so that we do have MAX_INDEX_ID.
+SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=1;
+create table t1 (a int) engine=rocksdb;
+drop table t1;
+
--let $max_index_id = query_get_value(SELECT * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO where type = 'MAX_INDEX_ID', VALUE, 1)
--replace_result $max_index_id max_index_id
select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
select count(*) from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
+SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=0;
select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CF_NAME = 'default' and LEVEL = 'Sum' and TYPE = 'KeyIn';
CREATE TABLE t1 (i1 INT, i2 INT, PRIMARY KEY (i1)) ENGINE = ROCKSDB;
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
---let $MASTER_UUID = query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
+# No binlog coordinates in MariaDB: --let $MASTER_UUID = query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
--let $max_index_id = query_get_value(SELECT * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO where type = 'MAX_INDEX_ID', VALUE, 1)
---replace_result $MASTER_UUID uuid $max_index_id max_index_id
+# No binlog coordinates in MariaDB: --replace_result $MASTER_UUID uuid $max_index_id max_index_id
+--replace_result $max_index_id max_index_id
select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
select count(*) from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_ignore_dirs.test b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_ignore_dirs.test
new file mode 100644
index 00000000000..49591dd612a
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_ignore_dirs.test
@@ -0,0 +1,17 @@
+--source include/have_rocksdb.inc
+
+
+--echo #
+--echo # RocksDB plugin adds #rocksdb to ignore_db_dirs
+--echo #
+
+select @@ignore_db_dirs;
+
+--let $_mysqld_option=--ignore-db-dirs=aa --ignore-db-dirs=bbb
+--source include/restart_mysqld_with_option.inc
+
+select @@ignore_db_dirs;
+
+--let $_mysqld_option=--ignore-db-dirs=#rocksdb
+--source include/restart_mysqld_with_option.inc
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test
new file mode 100644
index 00000000000..980f2e302b2
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test
@@ -0,0 +1,75 @@
+--source include/have_rocksdb.inc
+
+--echo #
+--echo # MDEV-14433: RocksDB may show empty or incorrect output with rocksdb_strict_collation_check=off
+--echo #
+set global rocksdb_strict_collation_check=off;
+set @tmp_rscc=@@rocksdb_strict_collation_check;
+
+CREATE TABLE t1(
+ a varchar(10) NOT NULL,
+ b char(1) DEFAULT 'X',
+ c char(2) NOT NULL DEFAULT '??',
+ d varchar(10) NOT NULL,
+ e int(11) DEFAULT 0,
+ PRIMARY KEY (a,d),
+ KEY (e)
+) ENGINE=ROCKSDB DEFAULT CHARSET=utf8;
+
+insert into t1 select 1,1,1,1,0;
+insert into t1 select 2,1,1,1,0;
+insert into t1 select 3,1,1,1,0;
+
+--replace_column 9 #
+explain
+select a from t1 force index(e) where e<10000;
+select a from t1;
+select * from t1;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14563: Wrong query plan for query with no PK
+--echo #
+
+CREATE TABLE t1(
+ pk int primary key,
+ a varchar(10) NOT NULL,
+ e int(11) DEFAULT 0,
+ KEY (a)
+) ENGINE=ROCKSDB DEFAULT CHARSET=utf8;
+insert into t1 values (1,1,1),(2,2,2);
+--replace_column 9 #
+explain select a from t1 where a <'zzz';
+
+CREATE TABLE t2(
+ pk int,
+ a varchar(10) NOT NULL,
+ e int(11) DEFAULT 0,
+ KEY (a)
+) ENGINE=ROCKSDB DEFAULT CHARSET=utf8;
+insert into t2 values (1,1,1),(2,2,2);
+--replace_column 9 #
+explain select a from t2 where a <'zzz';
+
+drop table t1,t2;
+
+set global rocksdb_strict_collation_check=@tmp_rscc;
+
+--echo #
+--echo # MDEV-14389: MyRocks and NOPAD collations
+--echo #
+
+--error ER_MYROCKS_CANT_NOPAD_COLLATION
+create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb;
+
+set global rocksdb_strict_collation_check=off;
+--error ER_MYROCKS_CANT_NOPAD_COLLATION
+create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb;
+
+set global rocksdb_strict_collation_check=@tmp_rscc;
+
+--echo #
+--echo # MDEV-14679: RocksdB plugin fails to load with "Loading of unknown plugin ROCKSDB_CFSTATS
+--echo #
+select plugin_name, plugin_maturity from information_schema.plugins where plugin_name like '%rocksdb%';
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.inc b/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.inc
index 9d03aae5c0c..5f66937cef1 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.inc
+++ b/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.inc
@@ -1,7 +1,7 @@
# run a check script to verify sst files reduced enough during each optimize table
perl;
-$size += -s $_ for (<$ENV{datadir}/.rocksdb/*.sst>);
+$size += -s $_ for (<$ENV{datadir}/#rocksdb/*.sst>);
$file= "$ENV{MYSQL_TMP_DIR}/sst_size.dat";
if (-f $file) {
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
index 5c8fa9ed443..9199c572933 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
@@ -786,6 +786,8 @@ drop table t45;
--echo # Now it fails if there is data overlap with what
--echo # already exists
--echo #
+
+--replace_regex /[a-f0-9]{40}/#/
show variables
where
variable_name like 'rocksdb%' and
diff --git a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/stream_run.sh b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/stream_run.sh
index ecf8a851267..b6735abb0a9 100755
--- a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/stream_run.sh
+++ b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/stream_run.sh
@@ -77,7 +77,7 @@ MOVEBACK_LOG="${MYSQL_TMP_DIR}/myrocks_hotbackup_moveback_log"
echo "myrocks_hotbackup move-back phase"
$MYSQL_MYROCKS_HOTBACKUP --move_back --datadir=$dest_data_dir \
- --rocksdb_datadir=$dest_data_dir/.rocksdb \
- --rocksdb_waldir=$dest_data_dir/.rocksdb \
+ --rocksdb_datadir=$dest_data_dir/\#rocksdb \
+ --rocksdb_waldir=$dest_data_dir/\#rocksdb \
--backup_dir=$backup_dir > $MOVEBACK_LOG 2>&1
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/my.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/my.cnf
index 2beaf514cee..ec7370b65f0 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/my.cnf
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/my.cnf
@@ -1,3 +1,4 @@
+!include rpl_1slave_base.cnf
!include include/default_my.cnf
[server]
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/mdev12179.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/mdev12179.result
new file mode 100644
index 00000000000..9c20fea97ae
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/mdev12179.result
@@ -0,0 +1,265 @@
+include/master-slave.inc
+[connection master]
+connection server_2;
+include/stop_slave.inc
+CHANGE MASTER TO master_use_gtid=slave_pos;
+SET sql_log_bin=0;
+CREATE TABLE mysql.gtid_slave_pos_innodb LIKE mysql.gtid_slave_pos;
+ALTER TABLE mysql.gtid_slave_pos_innodb ENGINE=InnoDB;
+CREATE TABLE mysql.gtid_slave_pos_rocksdb LIKE mysql.gtid_slave_pos;
+ALTER TABLE mysql.gtid_slave_pos_rocksdb ENGINE=rocksdb;
+CREATE TABLE mysql.gtid_slave_pos_myisam_redundant LIKE mysql.gtid_slave_pos;
+CREATE TABLE mysql.gtid_slave_pos_innodb_redundant LIKE mysql.gtid_slave_pos;
+ALTER TABLE mysql.gtid_slave_pos_innodb_redundant ENGINE=InnoDB;
+call mtr.add_suppression("Ignoring redundant table.*since.*has the same storage engine");
+include/start_slave.inc
+connection server_1;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=MyISAM;
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t3 (a INT PRIMARY KEY) ENGINE=rocksdb;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+INSERT INTO t3 VALUES (1);
+SELECT * FROM t1 ORDER BY a;
+a
+1
+SELECT * FROM t2 ORDER BY a;
+a
+1
+SELECT * FROM t3 ORDER BY a;
+a
+1
+connection server_2;
+SELECT * FROM t1 ORDER BY a;
+a
+1
+SELECT * FROM t2 ORDER BY a;
+a
+1
+SELECT * FROM t3 ORDER BY a;
+a
+1
+SELECT * FROM mysql.gtid_slave_pos ORDER BY sub_id;
+domain_id sub_id server_id seq_no
+0 3 1 3
+0 4 1 4
+SELECT * FROM ( SELECT * FROM mysql.gtid_slave_pos_innodb
+UNION ALL SELECT * FROM mysql.gtid_slave_pos_innodb_redundant) inner_select
+ORDER BY sub_id;
+domain_id sub_id server_id seq_no
+0 5 1 5
+SELECT * FROM mysql.gtid_slave_pos_rocksdb ORDER BY sub_id;
+domain_id sub_id server_id seq_no
+0 6 1 6
+connection server_2;
+FLUSH NO_WRITE_TO_BINLOG STATUS;
+SET sql_log_bin=0;
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 0
+INSERT INTO t1 VALUES (100);
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 0
+INSERT INTO t2 VALUES (101);
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 0
+INSERT INTO t3 VALUES (101);
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 0
+BEGIN;
+INSERT INTO t3 VALUES (102);
+INSERT INTO t2 VALUES (103);
+COMMIT;
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 1
+BEGIN;
+INSERT INTO t2 VALUES (104);
+INSERT INTO t3 VALUES (105);
+COMMIT;
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 2
+UPDATE t2, t3 SET t2.a=106, t3.a=107 WHERE t2.a=104 AND t3.a=105;
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 3
+SET sql_log_bin=1;
+INSERT INTO t1 VALUES (200);
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 3
+INSERT INTO t2 VALUES (201);
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 3
+INSERT INTO t3 VALUES (201);
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 3
+BEGIN;
+INSERT INTO t3 VALUES (202);
+INSERT INTO t2 VALUES (203);
+COMMIT;
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 4
+BEGIN;
+INSERT INTO t2 VALUES (204);
+INSERT INTO t3 VALUES (205);
+COMMIT;
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 5
+UPDATE t2, t3 SET t2.a=206, t3.a=207 WHERE t2.a=204 AND t3.a=205;
+SHOW STATUS LIKE "Transactions_multi_engine";
+Variable_name Value
+Transactions_multi_engine 6
+DELETE FROM t1 WHERE a >= 100;
+DELETE FROM t2 WHERE a >= 100;
+DELETE FROM t3 WHERE a >= 100;
+connection server_2;
+include/stop_slave.inc
+SET sql_log_bin=0;
+DROP TABLE mysql.gtid_slave_pos_rocksdb;
+DROP TABLE mysql.gtid_slave_pos_myisam_redundant;
+DROP TABLE mysql.gtid_slave_pos_innodb_redundant;
+SET sql_log_bin=1;
+FLUSH NO_WRITE_TO_BINLOG STATUS;
+include/start_slave.inc
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 0
+Transactions_gtid_foreign_engine 0
+Transactions_multi_engine 0
+connection server_1;
+INSERT INTO t1 VALUES (100);
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 0
+Transactions_gtid_foreign_engine 0
+Transactions_multi_engine 0
+connection server_1;
+INSERT INTO t2 VALUES (101);
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 0
+Transactions_gtid_foreign_engine 0
+Transactions_multi_engine 0
+connection server_1;
+INSERT INTO t3 VALUES (101);
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 0
+Transactions_gtid_foreign_engine 1
+Transactions_multi_engine 0
+connection server_1;
+BEGIN;
+INSERT INTO t3 VALUES (102);
+INSERT INTO t2 VALUES (103);
+COMMIT;
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 1
+Transactions_gtid_foreign_engine 1
+Transactions_multi_engine 1
+connection server_1;
+BEGIN;
+INSERT INTO t2 VALUES (104);
+INSERT INTO t3 VALUES (105);
+COMMIT;
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 2
+Transactions_gtid_foreign_engine 1
+Transactions_multi_engine 2
+connection server_1;
+UPDATE t2, t3 SET t2.a=106, t3.a=107 WHERE t2.a=104 AND t3.a=105;
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 3
+Transactions_gtid_foreign_engine 1
+Transactions_multi_engine 3
+connection server_2;
+connection server_2;
+SHOW VARIABLES LIKE 'log_bin';
+Variable_name Value
+log_bin OFF
+include/start_slave.inc
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 0
+Transactions_gtid_foreign_engine 0
+Transactions_multi_engine 0
+connection server_1;
+INSERT INTO t1 VALUES (200);
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 0
+Transactions_gtid_foreign_engine 0
+Transactions_multi_engine 0
+connection server_1;
+INSERT INTO t2 VALUES (201);
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 0
+Transactions_gtid_foreign_engine 0
+Transactions_multi_engine 0
+connection server_1;
+INSERT INTO t3 VALUES (201);
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 0
+Transactions_gtid_foreign_engine 1
+Transactions_multi_engine 0
+connection server_1;
+BEGIN;
+INSERT INTO t3 VALUES (202);
+INSERT INTO t2 VALUES (203);
+COMMIT;
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 1
+Transactions_gtid_foreign_engine 1
+Transactions_multi_engine 1
+connection server_1;
+BEGIN;
+INSERT INTO t2 VALUES (204);
+INSERT INTO t3 VALUES (205);
+COMMIT;
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 2
+Transactions_gtid_foreign_engine 1
+Transactions_multi_engine 2
+connection server_1;
+UPDATE t2, t3 SET t2.a=206, t3.a=207 WHERE t2.a=204 AND t3.a=205;
+connection server_2;
+SHOW STATUS LIKE "%transactions%engine";
+Variable_name Value
+Rpl_transactions_multi_engine 3
+Transactions_gtid_foreign_engine 1
+Transactions_multi_engine 3
+connection server_2;
+SET sql_log_bin=0;
+DROP TABLE mysql.gtid_slave_pos_innodb;
+SET sql_log_bin=1;
+connection server_1;
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+include/rpl_end.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_binlog_xid_count.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_binlog_xid_count.result
new file mode 100644
index 00000000000..9b46a5b5227
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_binlog_xid_count.result
@@ -0,0 +1,204 @@
+CREATE TABLE `t` (
+`a` text DEFAULT NULL
+) ENGINE=ROCKSDB;
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+DROP TABLE t;
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/singledelete_idempotent_table.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/singledelete_idempotent_table.result
index 609d4a8821a..979e2cbf6c3 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/r/singledelete_idempotent_table.result
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/singledelete_idempotent_table.result
@@ -1,16 +1,19 @@
include/master-slave.inc
-Warnings:
-Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
-Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
[connection master]
+connection master;
drop table if exists r1;
create table r1 (id1 int, id2 int, primary key (id1, id2), index i (id2)) engine=rocksdb;
insert into r1 values (1, 1000);
set sql_log_bin=0;
delete from r1 where id1=1 and id2=1000;
set sql_log_bin=1;
+connection slave;
+connection slave;
set global rocksdb_force_flush_memtable_now=1;
+connection master;
insert into r1 values (1, 1000);
+connection slave;
+connection slave;
delete r1 from r1 force index (i) where id2=1000;
select id1,id2 from r1 force index (primary);
id1 id2
@@ -21,5 +24,6 @@ select id1,id2 from r1 force index (primary);
id1 id2
select id2 from r1 force index (i);
id2
+connection master;
drop table r1;
include/rpl_end.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/suite.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/suite.opt
index f5dc0ce891c..761a2108cec 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/suite.opt
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/suite.opt
@@ -1,2 +1 @@
--ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO --default-storage-engine=rocksdb
-
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
index 07a2738eee5..956355dceee 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
@@ -1,19 +1,29 @@
+##
+## Tests that require FB/MySQL specific features for which there are
+## no plans to port them to MariaDB
+##
+rpl_no_unique_check_on_lag : unique_check_lag_threshold is not available in MariaDB
+rpl_no_unique_check_on_lag_mts : unique_check_lag_threshold is not available in MariaDB
+consistent_snapshot_mixed_engines : Tests START TRANSACTION WITH CONSISTENT $ENGINE_NAME SNAPSHOT
+rpl_skip_trx_api_binlog_format : requires @@rpl_skip_tx_api
+rpl_ddl_high_priority : DDL commands with HIGH_PRIORITY syntax are not in MariaDB
+rpl_gtid_rocksdb_sys_header : MariaDB doesn't support printing "RocksDB: Last MySQL Gtid UUID" into server stderr on startup
+singledelete_idempotent_recovery: MariaDB doesn't support --slave-use-idempotent-for-recovery
-# rpl_rocksdb_2pc_crash_recover
+##
+## Tests that do not fit MariaDB's test environment (Functional tests only,
+## can't have stress tests)
+##
+rpl_rocksdb_stress_crash : Stress test
+
+##
+## Tests that are disabled for other reasons
+##
-consistent_snapshot_mixed_engines : Didn't try with MariaDB, yet
multiclient_2pc : Didn't try with MariaDB, yet
rpl_crash_safe_wal_corrupt : Didn't try with MariaDB, yet
-rpl_ddl_high_priority : Didn't try with MariaDB, yet
rpl_gtid_crash_safe : Didn't try with MariaDB, yet
rpl_gtid_crash_safe_wal_corrupt : Didn't try with MariaDB, yet
-rpl_gtid_rocksdb_sys_header : Didn't try with MariaDB, yet
-rpl_no_unique_check_on_lag : Didn't try with MariaDB, yet
-rpl_no_unique_check_on_lag_mts : Didn't try with MariaDB, yet
rpl_rocksdb_snapshot : Didn't try with MariaDB, yet
rpl_rocksdb_snapshot_without_gtid : Didn't try with MariaDB, yet
-rpl_rocksdb_stress_crash : Didn't try with MariaDB, yet
-rpl_skip_trx_api_binlog_format : Didn't try with MariaDB, yet
-singledelete_idempotent_recovery : Didn't try with MariaDB, yet
-singledelete_idempotent_table : Didn't try with MariaDB, yet
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test
new file mode 100644
index 00000000000..e0d16e7f242
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test
@@ -0,0 +1,232 @@
+--source include/have_rocksdb.inc
+--source include/have_innodb.inc
+--source include/master-slave.inc
+
+--connection server_2
+--source include/stop_slave.inc
+CHANGE MASTER TO master_use_gtid=slave_pos;
+SET sql_log_bin=0;
+CREATE TABLE mysql.gtid_slave_pos_innodb LIKE mysql.gtid_slave_pos;
+ALTER TABLE mysql.gtid_slave_pos_innodb ENGINE=InnoDB;
+CREATE TABLE mysql.gtid_slave_pos_rocksdb LIKE mysql.gtid_slave_pos;
+ALTER TABLE mysql.gtid_slave_pos_rocksdb ENGINE=rocksdb;
+CREATE TABLE mysql.gtid_slave_pos_myisam_redundant LIKE mysql.gtid_slave_pos;
+CREATE TABLE mysql.gtid_slave_pos_innodb_redundant LIKE mysql.gtid_slave_pos;
+ALTER TABLE mysql.gtid_slave_pos_innodb_redundant ENGINE=InnoDB;
+call mtr.add_suppression("Ignoring redundant table.*since.*has the same storage engine");
+--source include/start_slave.inc
+
+--connection server_1
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=MyISAM;
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t3 (a INT PRIMARY KEY) ENGINE=rocksdb;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+INSERT INTO t3 VALUES (1);
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+SELECT * FROM t3 ORDER BY a;
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+SELECT * FROM t3 ORDER BY a;
+SELECT * FROM mysql.gtid_slave_pos ORDER BY sub_id;
+SELECT * FROM ( SELECT * FROM mysql.gtid_slave_pos_innodb
+ UNION ALL SELECT * FROM mysql.gtid_slave_pos_innodb_redundant) inner_select
+ ORDER BY sub_id;
+SELECT * FROM mysql.gtid_slave_pos_rocksdb ORDER BY sub_id;
+
+
+# Test status variable Transactions_multi_engine.
+--connection server_2
+FLUSH NO_WRITE_TO_BINLOG STATUS;
+SET sql_log_bin=0;
+SHOW STATUS LIKE "Transactions_multi_engine";
+INSERT INTO t1 VALUES (100);
+SHOW STATUS LIKE "Transactions_multi_engine";
+INSERT INTO t2 VALUES (101);
+SHOW STATUS LIKE "Transactions_multi_engine";
+INSERT INTO t3 VALUES (101);
+SHOW STATUS LIKE "Transactions_multi_engine";
+BEGIN;
+INSERT INTO t3 VALUES (102);
+INSERT INTO t2 VALUES (103);
+COMMIT;
+SHOW STATUS LIKE "Transactions_multi_engine";
+BEGIN;
+INSERT INTO t2 VALUES (104);
+INSERT INTO t3 VALUES (105);
+COMMIT;
+SHOW STATUS LIKE "Transactions_multi_engine";
+UPDATE t2, t3 SET t2.a=106, t3.a=107 WHERE t2.a=104 AND t3.a=105;
+SHOW STATUS LIKE "Transactions_multi_engine";
+# Try again with binlog enabled.
+SET sql_log_bin=1;
+INSERT INTO t1 VALUES (200);
+SHOW STATUS LIKE "Transactions_multi_engine";
+INSERT INTO t2 VALUES (201);
+SHOW STATUS LIKE "Transactions_multi_engine";
+INSERT INTO t3 VALUES (201);
+SHOW STATUS LIKE "Transactions_multi_engine";
+BEGIN;
+INSERT INTO t3 VALUES (202);
+INSERT INTO t2 VALUES (203);
+COMMIT;
+SHOW STATUS LIKE "Transactions_multi_engine";
+BEGIN;
+INSERT INTO t2 VALUES (204);
+INSERT INTO t3 VALUES (205);
+COMMIT;
+SHOW STATUS LIKE "Transactions_multi_engine";
+UPDATE t2, t3 SET t2.a=206, t3.a=207 WHERE t2.a=204 AND t3.a=205;
+SHOW STATUS LIKE "Transactions_multi_engine";
+
+DELETE FROM t1 WHERE a >= 100;
+DELETE FROM t2 WHERE a >= 100;
+DELETE FROM t3 WHERE a >= 100;
+
+
+# Test status variables Rpl_transactions_multi_engine and Transactions_gtid_foreign_engine.
+# Have mysql.gtid_slave_pos* for myisam and innodb but not rocksdb.
+--connection server_2
+--source include/stop_slave.inc
+SET sql_log_bin=0;
+DROP TABLE mysql.gtid_slave_pos_rocksdb;
+DROP TABLE mysql.gtid_slave_pos_myisam_redundant;
+DROP TABLE mysql.gtid_slave_pos_innodb_redundant;
+SET sql_log_bin=1;
+FLUSH NO_WRITE_TO_BINLOG STATUS;
+--source include/start_slave.inc
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+INSERT INTO t1 VALUES (100);
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+INSERT INTO t2 VALUES (101);
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+INSERT INTO t3 VALUES (101);
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+BEGIN;
+INSERT INTO t3 VALUES (102);
+INSERT INTO t2 VALUES (103);
+COMMIT;
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+BEGIN;
+INSERT INTO t2 VALUES (104);
+INSERT INTO t3 VALUES (105);
+COMMIT;
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+UPDATE t2, t3 SET t2.a=106, t3.a=107 WHERE t2.a=104 AND t3.a=105;
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+# Now the same thing, but without binlogging on the slave.
+--connection server_2
+--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+wait
+EOF
+--shutdown_server 30
+--source include/wait_until_disconnected.inc
+
+# Restart without binary log.
+--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+restart: --skip-log-bin
+EOF
+
+--connection server_2
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+SHOW VARIABLES LIKE 'log_bin';
+--source include/start_slave.inc
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+INSERT INTO t1 VALUES (200);
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+INSERT INTO t2 VALUES (201);
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+INSERT INTO t3 VALUES (201);
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+BEGIN;
+INSERT INTO t3 VALUES (202);
+INSERT INTO t2 VALUES (203);
+COMMIT;
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+BEGIN;
+INSERT INTO t2 VALUES (204);
+INSERT INTO t3 VALUES (205);
+COMMIT;
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+--connection server_1
+UPDATE t2, t3 SET t2.a=206, t3.a=207 WHERE t2.a=204 AND t3.a=205;
+--save_master_pos
+--connection server_2
+--sync_with_master
+SHOW STATUS LIKE "%transactions%engine";
+
+
+--connection server_2
+SET sql_log_bin=0;
+DROP TABLE mysql.gtid_slave_pos_innodb;
+SET sql_log_bin=1;
+
+--connection server_1
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+--source include/rpl_end.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt
new file mode 100644
index 00000000000..ed50a8a3deb
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt
@@ -0,0 +1,3 @@
+--innodb --max-binlog-size=4096
+
+
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test
new file mode 100644
index 00000000000..7667f153cde
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test
@@ -0,0 +1,20 @@
+--source include/have_rocksdb.inc
+--source include/have_binlog_format_row.inc
+
+CREATE TABLE `t` (
+ `a` text DEFAULT NULL
+) ENGINE=ROCKSDB;
+
+
+--let $size=`SELECT @@GLOBAL.max_binlog_size`
+--let $loop_cnt= 100
+while ($loop_cnt)
+{
+ --eval INSERT INTO t SET a=repeat('a', $size)
+ --eval INSERT INTO t SET a=repeat('a', $size/2)
+
+ --dec $loop_cnt
+}
+
+# Cleanup
+DROP TABLE t;
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc
index a52bfc9186d..5e5961f3aef 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc
@@ -40,7 +40,7 @@ select * from mysql.slave_gtid_info;
--write_file $MYSQL_TMP_DIR/truncate_tail_wal.sh
#!/bin/bash
-F=`ls -t $slave_data_dir/.rocksdb/*.log | head -n 1`
+F=`ls -t $slave_data_dir/\#rocksdb/*.log | head -n 1`
SIZE=`stat -c %s $F`
NEW_SIZE=`expr $SIZE - 10`
truncate -s $NEW_SIZE $F
@@ -116,7 +116,7 @@ connection slave;
#!/bin/bash
# expected to be around 950 bytes
-F=`ls -t $slave_data_dir/.rocksdb/*.log | head -n 1`
+F=`ls -t $slave_data_dir/\#rocksdb/*.log | head -n 1`
SIZE=`stat -c %s $F`
OFFSET=$(( $SIZE-500 ))
dd bs=1 if=/dev/zero of=$F count=100 seek=$OFFSET conv=notrunc
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf
index ad4894f5b38..5f1f87d762f 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf
@@ -2,14 +2,10 @@
[mysqld.1]
log_slave_updates
-gtid_mode=ON
-enforce_gtid_consistency=ON
[mysqld.2]
relay_log_recovery=1
-relay_log_info_repository=FILE
+#relay_log_info_repository=FILE
log_slave_updates
-gtid_mode=ON
-enforce_gtid_consistency=ON
-rbr_idempotent_tables='r1'
-
+#rbr_idempotent_tables='r1'
+slave_exec_mode=IDEMPOTENT
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test
index 23d335d6b57..00dce7c2ca9 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test
@@ -2,7 +2,7 @@
--source include/have_binlog_format_row.inc
--source include/have_rocksdb.inc
--source include/master-slave.inc
---source include/have_gtid.inc
+#--source include/have_gtid.inc
--source include/not_valgrind.inc
# This is a test case for issue#655 -- SingleDelete on Primary Key may
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/include/rocksdb_sys_var.inc b/storage/rocksdb/mysql-test/rocksdb_sys_vars/include/rocksdb_sys_var.inc
index 6ba93026674..db0abc57358 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/include/rocksdb_sys_var.inc
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/include/rocksdb_sys_var.inc
@@ -10,6 +10,7 @@
--eval SET @start_global_value = @@global.$sys_var
if (!$suppress_default_value)
{
+ --replace_regex /[a-f0-9]{40}/#/
SELECT @start_global_value;
if ($session)
{
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_datadir_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_datadir_basic.result
index a3f9eff6c1f..3215624bad8 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_datadir_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_datadir_basic.result
@@ -1,7 +1,7 @@
SET @start_global_value = @@global.ROCKSDB_DATADIR;
SELECT @start_global_value;
@start_global_value
-./.rocksdb
+./#rocksdb
"Trying to set variable @@global.ROCKSDB_DATADIR to 444. It should fail because it is readonly."
SET @@global.ROCKSDB_DATADIR = 444;
ERROR HY000: Variable 'rocksdb_datadir' is a read only variable
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_flush_memtable_on_analyze_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_flush_memtable_on_analyze_basic.result
index 905feec9b1a..010ba954366 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_flush_memtable_on_analyze_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_flush_memtable_on_analyze_basic.result
@@ -47,12 +47,12 @@ a b
2 2
3 3
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed # # # 0 0 0 4 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed # # # 0 0 0 4 NULL NULL NULL latin1_swedish_ci NULL 0 N
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
SHOW TABLE STATUS LIKE 't1';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 ROCKSDB 10 Fixed # # # 0 0 0 4 NULL NULL NULL latin1_swedish_ci NULL
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 ROCKSDB 10 Fixed # # # 0 0 0 4 NULL NULL NULL latin1_swedish_ci NULL 0 N
DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_git_hash_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_git_hash_basic.result
new file mode 100644
index 00000000000..bbcfa1417eb
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_git_hash_basic.result
@@ -0,0 +1,7 @@
+SET @start_global_value = @@global.ROCKSDB_GIT_HASH;
+SELECT @start_global_value;
+@start_global_value
+#
+"Trying to set variable @@global.ROCKSDB_GIT_HASH to 444. It should fail because it is readonly."
+SET @@global.ROCKSDB_GIT_HASH = 444;
+ERROR HY000: Variable 'rocksdb_git_hash' is a read only variable
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/suite.opt b/storage/rocksdb/mysql-test/rocksdb_sys_vars/suite.opt
index 431fc331458..f6640ca596c 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/suite.opt
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/suite.opt
@@ -1,2 +1 @@
---ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO
-
+--ignore-db-dirs=#rocksdb --plugin-load=$HA_ROCKSDB_SO
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_git_hash_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_git_hash_basic.test
new file mode 100644
index 00000000000..7b314e47d4b
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_git_hash_basic.test
@@ -0,0 +1,6 @@
+--source include/have_rocksdb.inc
+
+--let $sys_var=ROCKSDB_GIT_HASH
+--let $read_only=1
+--let $session=0
+--source include/rocksdb_sys_var.inc
diff --git a/storage/rocksdb/mysql-test/storage_engine/cleanup_engine.inc b/storage/rocksdb/mysql-test/storage_engine/cleanup_engine.inc
index 4f6c586172d..e6fe915ed38 100644
--- a/storage/rocksdb/mysql-test/storage_engine/cleanup_engine.inc
+++ b/storage/rocksdb/mysql-test/storage_engine/cleanup_engine.inc
@@ -12,14 +12,14 @@
--let $datadir= `SELECT @@datadir`
--error 0,1
---file_exists $datadir/.rocksdb/*
+--file_exists $datadir/\#rocksdb/*
if (!$mysql_errno)
{
--enable_reconnect
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server
--source include/wait_until_disconnected.inc
- --rmdir $datadir/.rocksdb
+ --rmdir $datadir/\#rocksdb
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
}
diff --git a/storage/rocksdb/mysql-test/storage_engine/disabled.def b/storage/rocksdb/mysql-test/storage_engine/disabled.def
index 0643b2052e2..930e1d82b87 100644
--- a/storage/rocksdb/mysql-test/storage_engine/disabled.def
+++ b/storage/rocksdb/mysql-test/storage_engine/disabled.def
@@ -14,6 +14,7 @@ lock_concurrent : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bog
optimize_table : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bogus error message
repair_table : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bogus error message
select_high_prio : Not supported
+show_engine : SHOW ENGINE produces different number of lines depending on previous tests
show_table_status : MDEV-13152 - Indeterministic row number in SHOW TABLE STATUS on RocksDB table
tbl_opt_data_dir : Not supported
tbl_opt_index_dir : Not supported
diff --git a/storage/rocksdb/mysql-test/storage_engine/misc.rdiff b/storage/rocksdb/mysql-test/storage_engine/misc.rdiff
index 694f3f54815..cdbad003217 100644
--- a/storage/rocksdb/mysql-test/storage_engine/misc.rdiff
+++ b/storage/rocksdb/mysql-test/storage_engine/misc.rdiff
@@ -1,16 +1,17 @@
---- /data/src/bb-10.2-mdev12528/mysql-test/suite/storage_engine/misc.result 2017-06-22 00:33:46.419995639 +0300
-+++ /data/src/bb-10.2-mdev12528/mysql-test/suite/storage_engine/misc.reject 2017-06-22 02:34:23.647950149 +0300
-@@ -28,6 +28,9 @@
+--- suite/storage_engine/misc.result 2018-02-23 03:01:49.673249912 +0200
++++ suite/storage_engine/misc.reject 2018-02-23 03:02:05.669249564 +0200
+@@ -28,6 +28,10 @@
SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ORDER BY TABLE_NAME;
TABLE_NAME COLUMN_NAME REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME
+Warning 1286 Unknown storage engine 'InnoDB'
+Warning 1286 Unknown storage engine 'InnoDB'
++Warning 1286 Unknown storage engine 'InnoDB'
+Warnings:
column_stats column_name NULL NULL
column_stats db_name NULL NULL
column_stats table_name NULL NULL
-@@ -58,12 +61,6 @@
+@@ -58,12 +62,6 @@
index_stats index_name NULL NULL
index_stats prefix_arity NULL NULL
index_stats table_name NULL NULL
@@ -23,3 +24,11 @@
plugin name NULL NULL
proc db NULL NULL
proc name NULL NULL
+@@ -94,7 +92,5 @@
+ time_zone_transition Transition_time NULL NULL
+ time_zone_transition_type Time_zone_id NULL NULL
+ time_zone_transition_type Transition_type_id NULL NULL
+-transaction_registry commit_id NULL NULL
+-transaction_registry transaction_id NULL NULL
+ user Host NULL NULL
+ user User NULL NULL
diff --git a/storage/rocksdb/mysql-test/storage_engine/parts/suite.opt b/storage/rocksdb/mysql-test/storage_engine/parts/suite.opt
index 1e464761753..d77a822766f 100644
--- a/storage/rocksdb/mysql-test/storage_engine/parts/suite.opt
+++ b/storage/rocksdb/mysql-test/storage_engine/parts/suite.opt
@@ -1 +1 @@
---ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --loose-rocksdb_flush_log_at_trx_commit=0
+--ignore-db-dirs=#rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --loose-rocksdb_flush_log_at_trx_commit=0
diff --git a/storage/rocksdb/mysql-test/storage_engine/suite.opt b/storage/rocksdb/mysql-test/storage_engine/suite.opt
index 8eb0e87db98..e6122c7ed3e 100644
--- a/storage/rocksdb/mysql-test/storage_engine/suite.opt
+++ b/storage/rocksdb/mysql-test/storage_engine/suite.opt
@@ -1 +1 @@
---ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --collation-server=latin1_bin --loose-rocksdb_flush_log_at_trx_commit=0
+--ignore-db-dirs=#rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --collation-server=latin1_bin --loose-rocksdb_flush_log_at_trx_commit=0
diff --git a/storage/rocksdb/mysql-test/storage_engine/trx/suite.opt b/storage/rocksdb/mysql-test/storage_engine/trx/suite.opt
index 1e464761753..d77a822766f 100644
--- a/storage/rocksdb/mysql-test/storage_engine/trx/suite.opt
+++ b/storage/rocksdb/mysql-test/storage_engine/trx/suite.opt
@@ -1 +1 @@
---ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --loose-rocksdb_flush_log_at_trx_commit=0
+--ignore-db-dirs=#rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --loose-rocksdb_flush_log_at_trx_commit=0
diff --git a/storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff b/storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff
new file mode 100644
index 00000000000..e53a33b4fba
--- /dev/null
+++ b/storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff
@@ -0,0 +1,20 @@
+--- suite/storage_engine/type_bit_indexes.result 2017-12-12 20:34:34.000000000 +0200
++++ suite/storage_engine/type_bit_indexes.reject 2017-12-12 20:35:24.539330056 +0200
+@@ -69,7 +69,7 @@
+ (1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
+ EXPLAIN SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # b_c # # # #
++# # # # # NULL # # # #
+ SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
+ HEX(b+c)
+ 10
+@@ -98,7 +98,7 @@
+ (1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
+ EXPLAIN SELECT DISTINCT a+0 FROM t1 ORDER BY a;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # a # # # #
++# # # # # NULL # # # #
+ SELECT DISTINCT a+0 FROM t1 ORDER BY a;
+ a+0
+ 0
diff --git a/storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff b/storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff
new file mode 100644
index 00000000000..be83fb6e212
--- /dev/null
+++ b/storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff
@@ -0,0 +1,11 @@
+--- suite/storage_engine/type_enum_indexes.result 2017-03-12 04:38:50.000000000 +0200
++++ suite/storage_engine/type_enum_indexes.reject 2017-12-12 20:36:47.455331726 +0200
+@@ -30,7 +30,7 @@
+ t1 0 a_b 2 b # # NULL NULL # #
+ EXPLAIN SELECT a FROM t1 WHERE b > 'test2' ORDER BY a;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # a_b # # # #
++# # # # # NULL # # # #
+ SELECT a FROM t1 WHERE b > 'test2' ORDER BY a;
+ a
+ Africa
diff --git a/storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff b/storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff
new file mode 100644
index 00000000000..2703e81b745
--- /dev/null
+++ b/storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff
@@ -0,0 +1,20 @@
+--- suite/storage_engine/type_set_indexes.result 2017-03-12 04:38:50.000000000 +0200
++++ suite/storage_engine/type_set_indexes.reject 2017-12-12 20:37:16.187332305 +0200
+@@ -97,7 +97,7 @@
+ Warning 1265 Data truncated for column 'b' at row 7
+ EXPLAIN SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # a # # # #
++# # # # # NULL # # # #
+ SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0;
+ a
+ Africa,Europe,Asia
+@@ -124,7 +124,7 @@
+ Warning 1265 Data truncated for column 'b' at row 7
+ EXPLAIN SELECT DISTINCT a, b FROM t1 ORDER BY b DESC, a;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # b_a # # # #
++# # # # # NULL # # # #
+ SELECT DISTINCT a, b FROM t1 ORDER BY b DESC, a;
+ a b
+ test1,test3
diff --git a/storage/rocksdb/patch/port/win/io_win.h b/storage/rocksdb/patch/port/win/io_win.h
new file mode 100644
index 00000000000..f5ff253bbaa
--- /dev/null
+++ b/storage/rocksdb/patch/port/win/io_win.h
@@ -0,0 +1,446 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file. See the AUTHORS file for names of contributors.
+#pragma once
+
+#include <stdint.h>
+#include <mutex>
+#include <string>
+
+#include "rocksdb/status.h"
+#include "rocksdb/env.h"
+#include "util/aligned_buffer.h"
+
+#include <windows.h>
+
+
+namespace rocksdb {
+namespace port {
+
+std::string GetWindowsErrSz(DWORD err);
+
+inline Status IOErrorFromWindowsError(const std::string& context, DWORD err) {
+ return ((err == ERROR_HANDLE_DISK_FULL) || (err == ERROR_DISK_FULL))
+ ? Status::NoSpace(context, GetWindowsErrSz(err))
+ : Status::IOError(context, GetWindowsErrSz(err));
+}
+
+inline Status IOErrorFromLastWindowsError(const std::string& context) {
+ return IOErrorFromWindowsError(context, GetLastError());
+}
+
+inline Status IOError(const std::string& context, int err_number) {
+ return (err_number == ENOSPC)
+ ? Status::NoSpace(context, strerror(err_number))
+ : Status::IOError(context, strerror(err_number));
+}
+
+// Note the below two do not set errno because they are used only here in this
+// file
+// on a Windows handle and, therefore, not necessary. Translating GetLastError()
+// to errno
+// is a sad business
+inline int fsync(HANDLE hFile) {
+ if (!FlushFileBuffers(hFile)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+SSIZE_T pwrite(HANDLE hFile, const char* src, size_t numBytes, uint64_t offset);
+
+SSIZE_T pread(HANDLE hFile, char* src, size_t numBytes, uint64_t offset);
+
+Status fallocate(const std::string& filename, HANDLE hFile, uint64_t to_size);
+
+Status ftruncate(const std::string& filename, HANDLE hFile, uint64_t toSize);
+
+size_t GetUniqueIdFromFile(HANDLE hFile, char* id, size_t max_size);
+
+class WinFileData {
+ protected:
+ const std::string filename_;
+ HANDLE hFile_;
+ // If ture, the I/O issued would be direct I/O which the buffer
+ // will need to be aligned (not sure there is a guarantee that the buffer
+ // passed in is aligned).
+ const bool use_direct_io_;
+
+ public:
+ // We want this class be usable both for inheritance (prive
+ // or protected) and for containment so __ctor and __dtor public
+ WinFileData(const std::string& filename, HANDLE hFile, bool direct_io)
+ : filename_(filename), hFile_(hFile), use_direct_io_(direct_io) {}
+
+ virtual ~WinFileData() { this->CloseFile(); }
+
+ bool CloseFile() {
+ bool result = true;
+
+ if (hFile_ != NULL && hFile_ != INVALID_HANDLE_VALUE) {
+ result = ::CloseHandle(hFile_);
+ assert(result);
+ hFile_ = NULL;
+ }
+ return result;
+ }
+
+ const std::string& GetName() const { return filename_; }
+
+ HANDLE GetFileHandle() const { return hFile_; }
+
+ bool use_direct_io() const { return use_direct_io_; }
+
+ WinFileData(const WinFileData&) = delete;
+ WinFileData& operator=(const WinFileData&) = delete;
+};
+
+class WinSequentialFile : protected WinFileData, public SequentialFile {
+
+ // Override for behavior change when creating a custom env
+ virtual SSIZE_T PositionedReadInternal(char* src, size_t numBytes,
+ uint64_t offset) const;
+
+public:
+ WinSequentialFile(const std::string& fname, HANDLE f,
+ const EnvOptions& options);
+
+ ~WinSequentialFile();
+
+ WinSequentialFile(const WinSequentialFile&) = delete;
+ WinSequentialFile& operator=(const WinSequentialFile&) = delete;
+
+ virtual Status Read(size_t n, Slice* result, char* scratch) override;
+ virtual Status PositionedRead(uint64_t offset, size_t n, Slice* result,
+ char* scratch) override;
+
+ virtual Status Skip(uint64_t n) override;
+
+ virtual Status InvalidateCache(size_t offset, size_t length) override;
+
+ virtual bool use_direct_io() const override { return WinFileData::use_direct_io(); }
+};
+
+// mmap() based random-access
+class WinMmapReadableFile : private WinFileData, public RandomAccessFile {
+ HANDLE hMap_;
+
+ const void* mapped_region_;
+ const size_t length_;
+
+ public:
+ // mapped_region_[0,length-1] contains the mmapped contents of the file.
+ WinMmapReadableFile(const std::string& fileName, HANDLE hFile, HANDLE hMap,
+ const void* mapped_region, size_t length);
+
+ ~WinMmapReadableFile();
+
+ WinMmapReadableFile(const WinMmapReadableFile&) = delete;
+ WinMmapReadableFile& operator=(const WinMmapReadableFile&) = delete;
+
+ virtual Status Read(uint64_t offset, size_t n, Slice* result,
+ char* scratch) const override;
+
+ virtual Status InvalidateCache(size_t offset, size_t length) override;
+
+ virtual size_t GetUniqueId(char* id, size_t max_size) const override;
+};
+
+// We preallocate and use memcpy to append new
+// data to the file. This is safe since we either properly close the
+// file before reading from it, or for log files, the reading code
+// knows enough to skip zero suffixes.
+class WinMmapFile : private WinFileData, public WritableFile {
+ private:
+ HANDLE hMap_;
+
+ const size_t page_size_; // We flush the mapping view in page_size
+ // increments. We may decide if this is a memory
+ // page size or SSD page size
+ const size_t
+ allocation_granularity_; // View must start at such a granularity
+
+ size_t reserved_size_; // Preallocated size
+
+ size_t mapping_size_; // The max size of the mapping object
+ // we want to guess the final file size to minimize the remapping
+ size_t view_size_; // How much memory to map into a view at a time
+
+ char* mapped_begin_; // Must begin at the file offset that is aligned with
+ // allocation_granularity_
+ char* mapped_end_;
+ char* dst_; // Where to write next (in range [mapped_begin_,mapped_end_])
+ char* last_sync_; // Where have we synced up to
+
+ uint64_t file_offset_; // Offset of mapped_begin_ in file
+
+ // Do we have unsynced writes?
+ bool pending_sync_;
+
+ // Can only truncate or reserve to a sector size aligned if
+ // used on files that are opened with Unbuffered I/O
+ Status TruncateFile(uint64_t toSize);
+
+ Status UnmapCurrentRegion();
+
+ Status MapNewRegion();
+
+ virtual Status PreallocateInternal(uint64_t spaceToReserve);
+
+ public:
+ WinMmapFile(const std::string& fname, HANDLE hFile, size_t page_size,
+ size_t allocation_granularity, const EnvOptions& options);
+
+ ~WinMmapFile();
+
+ WinMmapFile(const WinMmapFile&) = delete;
+ WinMmapFile& operator=(const WinMmapFile&) = delete;
+
+ virtual Status Append(const Slice& data) override;
+
+ // Means Close() will properly take care of truncate
+ // and it does not need any additional information
+ virtual Status Truncate(uint64_t size) override;
+
+ virtual Status Close() override;
+
+ virtual Status Flush() override;
+
+ // Flush only data
+ virtual Status Sync() override;
+
+ /**
+ * Flush data as well as metadata to stable storage.
+ */
+ virtual Status Fsync() override;
+
+ /**
+ * Get the size of valid data in the file. This will not match the
+ * size that is returned from the filesystem because we use mmap
+ * to extend file by map_size every time.
+ */
+ virtual uint64_t GetFileSize() override;
+
+ virtual Status InvalidateCache(size_t offset, size_t length) override;
+
+ virtual Status Allocate(uint64_t offset, uint64_t len) override;
+
+ virtual size_t GetUniqueId(char* id, size_t max_size) const override;
+};
+
+class WinRandomAccessImpl {
+ protected:
+ WinFileData* file_base_;
+ size_t alignment_;
+
+ // Override for behavior change when creating a custom env
+ virtual SSIZE_T PositionedReadInternal(char* src, size_t numBytes,
+ uint64_t offset) const;
+
+ WinRandomAccessImpl(WinFileData* file_base, size_t alignment,
+ const EnvOptions& options);
+
+ virtual ~WinRandomAccessImpl() {}
+
+ Status ReadImpl(uint64_t offset, size_t n, Slice* result,
+ char* scratch) const;
+
+ size_t GetAlignment() const { return alignment_; }
+
+ public:
+
+ WinRandomAccessImpl(const WinRandomAccessImpl&) = delete;
+ WinRandomAccessImpl& operator=(const WinRandomAccessImpl&) = delete;
+};
+
+// pread() based random-access
+class WinRandomAccessFile
+ : private WinFileData,
+ protected WinRandomAccessImpl, // Want to be able to override
+ // PositionedReadInternal
+ public RandomAccessFile {
+ public:
+ WinRandomAccessFile(const std::string& fname, HANDLE hFile, size_t alignment,
+ const EnvOptions& options);
+
+ ~WinRandomAccessFile();
+
+ virtual Status Read(uint64_t offset, size_t n, Slice* result,
+ char* scratch) const override;
+
+ virtual size_t GetUniqueId(char* id, size_t max_size) const override;
+
+ virtual bool use_direct_io() const override { return WinFileData::use_direct_io(); }
+
+ virtual Status InvalidateCache(size_t offset, size_t length) override;
+
+ virtual size_t GetRequiredBufferAlignment() const override;
+};
+
+// This is a sequential write class. It has been mimicked (as others) after
+// the original Posix class. We add support for unbuffered I/O on windows as
+// well
+// we utilize the original buffer as an alignment buffer to write directly to
+// file with no buffering.
+// No buffering requires that the provided buffer is aligned to the physical
+// sector size (SSD page size) and
+// that all SetFilePointer() operations to occur with such an alignment.
+// We thus always write in sector/page size increments to the drive and leave
+// the tail for the next write OR for Close() at which point we pad with zeros.
+// No padding is required for
+// buffered access.
+class WinWritableImpl {
+ protected:
+ WinFileData* file_data_;
+ const uint64_t alignment_;
+ uint64_t next_write_offset_; // Needed because Windows does not support O_APPEND
+ uint64_t reservedsize_; // how far we have reserved space
+
+ virtual Status PreallocateInternal(uint64_t spaceToReserve);
+
+ WinWritableImpl(WinFileData* file_data, size_t alignment);
+
+ ~WinWritableImpl() {}
+
+
+ uint64_t GetAlignement() const { return alignment_; }
+
+ Status AppendImpl(const Slice& data);
+
+ // Requires that the data is aligned as specified by
+ // GetRequiredBufferAlignment()
+ Status PositionedAppendImpl(const Slice& data, uint64_t offset);
+
+ Status TruncateImpl(uint64_t size);
+
+ Status CloseImpl();
+
+ Status SyncImpl();
+
+ uint64_t GetFileNextWriteOffset() {
+ // Double accounting now here with WritableFileWriter
+ // and this size will be wrong when unbuffered access is used
+ // but tests implement their own writable files and do not use
+ // WritableFileWrapper
+ // so we need to squeeze a square peg through
+ // a round hole here.
+ return next_write_offset_;
+ }
+
+ Status AllocateImpl(uint64_t offset, uint64_t len);
+
+ public:
+ WinWritableImpl(const WinWritableImpl&) = delete;
+ WinWritableImpl& operator=(const WinWritableImpl&) = delete;
+};
+
+class WinWritableFile : private WinFileData,
+ protected WinWritableImpl,
+ public WritableFile {
+ public:
+ WinWritableFile(const std::string& fname, HANDLE hFile, size_t alignment,
+ size_t capacity, const EnvOptions& options);
+
+ ~WinWritableFile();
+
+ bool IsSyncThreadSafe() const override {
+ return true;
+ }
+
+ virtual Status Append(const Slice& data) override;
+
+ // Requires that the data is aligned as specified by
+ // GetRequiredBufferAlignment()
+ virtual Status PositionedAppend(const Slice& data, uint64_t offset) override;
+
+ // Need to implement this so the file is truncated correctly
+ // when buffered and unbuffered mode
+ virtual Status Truncate(uint64_t size) override;
+
+ virtual Status Close() override;
+
+ // write out the cached data to the OS cache
+ // This is now taken care of the WritableFileWriter
+ virtual Status Flush() override;
+
+ virtual Status Sync() override;
+
+ virtual Status Fsync() override;
+
+ // Indicates if the class makes use of direct I/O
+ // Use PositionedAppend
+ virtual bool use_direct_io() const override;
+
+ virtual size_t GetRequiredBufferAlignment() const override;
+
+ virtual uint64_t GetFileSize() override;
+
+ virtual Status Allocate(uint64_t offset, uint64_t len) override;
+
+ virtual size_t GetUniqueId(char* id, size_t max_size) const override;
+};
+
+class WinRandomRWFile : private WinFileData,
+ protected WinRandomAccessImpl,
+ protected WinWritableImpl,
+ public RandomRWFile {
+ public:
+ WinRandomRWFile(const std::string& fname, HANDLE hFile, size_t alignment,
+ const EnvOptions& options);
+
+ ~WinRandomRWFile() {}
+
+ // Indicates if the class makes use of direct I/O
+ // If false you must pass aligned buffer to Write()
+ virtual bool use_direct_io() const override;
+
+ // Use the returned alignment value to allocate aligned
+ // buffer for Write() when use_direct_io() returns true
+ virtual size_t GetRequiredBufferAlignment() const override;
+
+ // Write bytes in `data` at offset `offset`, Returns Status::OK() on success.
+ // Pass aligned buffer when use_direct_io() returns true.
+ virtual Status Write(uint64_t offset, const Slice& data) override;
+
+ // Read up to `n` bytes starting from offset `offset` and store them in
+ // result, provided `scratch` size should be at least `n`.
+ // Returns Status::OK() on success.
+ virtual Status Read(uint64_t offset, size_t n, Slice* result,
+ char* scratch) const override;
+
+ virtual Status Flush() override;
+
+ virtual Status Sync() override;
+
+ virtual Status Fsync() { return Sync(); }
+
+ virtual Status Close() override;
+};
+
+class WinDirectory : public Directory {
+ public:
+ WinDirectory() {}
+
+ virtual Status Fsync() override;
+};
+
+class WinFileLock : public FileLock {
+ public:
+ explicit WinFileLock(HANDLE hFile) : hFile_(hFile) {
+ assert(hFile != NULL);
+ assert(hFile != INVALID_HANDLE_VALUE);
+ }
+
+ ~WinFileLock();
+
+ private:
+ HANDLE hFile_;
+};
+}
+}
diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc
index 22d117f74ad..deba2d50ccc 100644
--- a/storage/rocksdb/rdb_datadic.cc
+++ b/storage/rocksdb/rdb_datadic.cc
@@ -538,7 +538,7 @@ const std::string Rdb_key_def::parse_comment_for_qualifier(
// NOTE: this means if you specify a qualifier for a specific partition it
// will take precedence the 'table level' qualifier if one exists.
std::string search_str_part;
- if (table_arg->part_info != nullptr) {
+ if (IF_PARTITIONING(table_arg->part_info,nullptr) != nullptr) {
std::string partition_name = tbl_def_arg->base_partition();
DBUG_ASSERT(!partition_name.empty());
search_str_part = gen_qualifier_for_table(qualifier, partition_name);
@@ -1461,7 +1461,8 @@ int Rdb_key_def::unpack_record(TABLE *const table, uchar *const buf,
if (has_covered_bitmap && field->real_type() == MYSQL_TYPE_VARCHAR &&
!m_pack_info[i].m_covered) {
covered_column = curr_bitmap_pos < MAX_REF_PARTS &&
- bitmap_is_set(&covered_bitmap, curr_bitmap_pos++);
+ bitmap_is_set(&covered_bitmap, curr_bitmap_pos);
+ curr_bitmap_pos++;
}
if (fpi->m_unpack_func && covered_column) {
/* It is possible to unpack this column. Do it. */
@@ -2921,7 +2922,7 @@ std::array<const Rdb_collation_codec *, MY_ALL_CHARSETS_SIZE>
rdb_collation_data;
mysql_mutex_t rdb_collation_data_mutex;
-static bool rdb_is_collation_supported(const my_core::CHARSET_INFO *const cs) {
+bool rdb_is_collation_supported(const my_core::CHARSET_INFO *const cs) {
return cs->strxfrm_multiply==1 && cs->mbmaxlen == 1 &&
!(cs->state & (MY_CS_BINSORT | MY_CS_NOPAD));
}
@@ -4260,7 +4261,7 @@ bool Rdb_binlog_manager::read(char *const binlog_name,
std::string value;
rocksdb::Status status = m_dict->get_value(m_key_slice, &value);
if (status.ok()) {
- if (!unpack_value((const uchar *)value.c_str(), binlog_name, binlog_pos,
+ if (!unpack_value((const uchar *)value.c_str(), value.size(), binlog_name, binlog_pos,
binlog_gtid))
ret = true;
}
@@ -4330,35 +4331,60 @@ Rdb_binlog_manager::pack_value(uchar *const buf, const char *const binlog_name,
@return true on error
*/
bool Rdb_binlog_manager::unpack_value(const uchar *const value,
+ size_t value_size_arg,
char *const binlog_name,
my_off_t *const binlog_pos,
char *const binlog_gtid) const {
uint pack_len = 0;
+ intmax_t value_size= value_size_arg;
DBUG_ASSERT(binlog_pos != nullptr);
+ if ((value_size -= Rdb_key_def::VERSION_SIZE) < 0)
+ return true;
// read version
const uint16_t version = rdb_netbuf_to_uint16(value);
+
pack_len += Rdb_key_def::VERSION_SIZE;
if (version != Rdb_key_def::BINLOG_INFO_INDEX_NUMBER_VERSION)
return true;
+ if ((value_size -= sizeof(uint16)) < 0)
+ return true;
+
// read binlog file name length
const uint16_t binlog_name_len = rdb_netbuf_to_uint16(value + pack_len);
pack_len += sizeof(uint16);
+
+ if (binlog_name_len >= (FN_REFLEN+1))
+ return true;
+
+ if ((value_size -= binlog_name_len) < 0)
+ return true;
+
if (binlog_name_len) {
// read and set binlog name
memcpy(binlog_name, value + pack_len, binlog_name_len);
binlog_name[binlog_name_len] = '\0';
pack_len += binlog_name_len;
+ if ((value_size -= sizeof(uint32)) < 0)
+ return true;
// read and set binlog pos
*binlog_pos = rdb_netbuf_to_uint32(value + pack_len);
pack_len += sizeof(uint32);
+ if ((value_size -= sizeof(uint16)) < 0)
+ return true;
// read gtid length
const uint16_t binlog_gtid_len = rdb_netbuf_to_uint16(value + pack_len);
pack_len += sizeof(uint16);
+
+ if (binlog_gtid_len >= GTID_BUF_LEN)
+ return true;
+ if ((value_size -= binlog_gtid_len) < 0)
+ return true;
+
if (binlog_gtid && binlog_gtid_len > 0) {
// read and set gtid
memcpy(binlog_gtid, value + pack_len, binlog_gtid_len);
diff --git a/storage/rocksdb/rdb_datadic.h b/storage/rocksdb/rdb_datadic.h
index 4599f4b1ce3..fa0c0fd09e5 100644
--- a/storage/rocksdb/rdb_datadic.h
+++ b/storage/rocksdb/rdb_datadic.h
@@ -46,6 +46,8 @@ class Rdb_field_packing;
class Rdb_cf_manager;
class Rdb_ddl_manager;
+const uint32_t GTID_BUF_LEN = 60;
+
/*
@brief
Field packing context.
@@ -1158,7 +1160,8 @@ private:
rocksdb::Slice pack_value(uchar *const buf, const char *const binlog_name,
const my_off_t &binlog_pos,
const char *const binlog_gtid) const;
- bool unpack_value(const uchar *const value, char *const binlog_name,
+ bool unpack_value(const uchar *const value, size_t value_size,
+ char *const binlog_name,
my_off_t *const binlog_pos, char *const binlog_gtid) const;
std::atomic<Rdb_tbl_def *> m_slave_gtid_info_tbl;
@@ -1362,4 +1365,6 @@ struct Rdb_index_info {
uint64 m_ttl_duration = 0;
};
+bool rdb_is_collation_supported(const my_core::CHARSET_INFO *const cs);
+
} // namespace myrocks
diff --git a/storage/rocksdb/rdb_i_s.cc b/storage/rocksdb/rdb_i_s.cc
index b86245d80b8..8407f280d5c 100644
--- a/storage/rocksdb/rdb_i_s.cc
+++ b/storage/rocksdb/rdb_i_s.cc
@@ -729,7 +729,6 @@ static int rdb_i_s_global_info_fill_table(
DBUG_ASSERT(tables != nullptr);
static const uint32_t INT_BUF_LEN = 21;
- static const uint32_t GTID_BUF_LEN = 60;
static const uint32_t CF_ID_INDEX_BUF_LEN = 60;
int ret = 0;
@@ -1484,7 +1483,7 @@ struct st_maria_plugin rdb_i_s_cfstats = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_dbstats = {
@@ -1500,7 +1499,7 @@ struct st_maria_plugin rdb_i_s_dbstats = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_perf_context = {
@@ -1516,7 +1515,7 @@ struct st_maria_plugin rdb_i_s_perf_context = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_perf_context_global = {
@@ -1532,7 +1531,7 @@ struct st_maria_plugin rdb_i_s_perf_context_global = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_cfoptions = {
@@ -1548,7 +1547,7 @@ struct st_maria_plugin rdb_i_s_cfoptions = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_global_info = {
@@ -1564,7 +1563,7 @@ struct st_maria_plugin rdb_i_s_global_info = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_compact_stats = {
@@ -1580,7 +1579,7 @@ struct st_maria_plugin rdb_i_s_compact_stats = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_ddl = {
@@ -1596,7 +1595,7 @@ struct st_maria_plugin rdb_i_s_ddl = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_index_file_map = {
@@ -1612,7 +1611,7 @@ struct st_maria_plugin rdb_i_s_index_file_map = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_lock_info = {
@@ -1628,7 +1627,7 @@ struct st_maria_plugin rdb_i_s_lock_info = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_trx_info = {
@@ -1644,6 +1643,6 @@ struct st_maria_plugin rdb_i_s_trx_info = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
- 0, /* flags */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
} // namespace myrocks
diff --git a/storage/rocksdb/rdb_io_watchdog.cc b/storage/rocksdb/rdb_io_watchdog.cc
index b41e9248d52..039b0d7baf1 100644
--- a/storage/rocksdb/rdb_io_watchdog.cc
+++ b/storage/rocksdb/rdb_io_watchdog.cc
@@ -22,7 +22,7 @@
#include <vector>
/* Rdb_io_watchdog doesn't work on Windows [yet] */
-#if !defined(_WIN32) && !defined(__APPLE__)
+#ifdef HAVE_TIMER_DELETE
namespace myrocks {
diff --git a/storage/rocksdb/rdb_io_watchdog.h b/storage/rocksdb/rdb_io_watchdog.h
index c50547745df..8900de5b32a 100644
--- a/storage/rocksdb/rdb_io_watchdog.h
+++ b/storage/rocksdb/rdb_io_watchdog.h
@@ -35,7 +35,7 @@
namespace myrocks {
// Rdb_io_watchdog does not support Windows ATM.
-#if !defined(_WIN32) && !defined(__APPLE__)
+#ifdef HAVE_TIMER_DELETE
class Rdb_io_watchdog {
const int RDB_IO_WRITE_BUFFER_SIZE = 4096;
diff --git a/storage/rocksdb/rdb_source_revision.h.in b/storage/rocksdb/rdb_source_revision.h.in
new file mode 100644
index 00000000000..617b39c9186
--- /dev/null
+++ b/storage/rocksdb/rdb_source_revision.h.in
@@ -0,0 +1 @@
+#define ROCKSDB_GIT_HASH "@ROCKSDB_GIT_HASH@"
diff --git a/storage/rocksdb/rdb_sst_info.cc b/storage/rocksdb/rdb_sst_info.cc
index da3a3d94354..70f19c6af11 100644
--- a/storage/rocksdb/rdb_sst_info.cc
+++ b/storage/rocksdb/rdb_sst_info.cc
@@ -109,6 +109,9 @@ Rdb_sst_file_ordered::Rdb_sst_file::put(const rocksdb::Slice &key,
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
+#ifdef _MSC_VER
+#pragma warning (disable : 4996)
+#endif
return m_sst_file_writer->Add(key, value);
}
diff --git a/storage/sphinx/CMakeLists.txt b/storage/sphinx/CMakeLists.txt
index e50ba74ba90..7cae7982e05 100644
--- a/storage/sphinx/CMakeLists.txt
+++ b/storage/sphinx/CMakeLists.txt
@@ -5,6 +5,16 @@ ADD_DEFINITIONS(-DMYSQL_SERVER)
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-write-strings")
IF(MSVC)
+ # Temporarily disable "conversion from size_t .." warnings
+ IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267")
+ ENDIF()
+ # Disable warning about deprecated functions, inet_aton
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996")
+ STRING(REPLACE "/permissive-" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" )
+ENDIF()
+
+IF(MSVC)
LINK_LIBRARIES(ws2_32)
ENDIF(MSVC)
diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc
index fdc51685f7d..b1d9681da2a 100644
--- a/storage/sphinx/ha_sphinx.cc
+++ b/storage/sphinx/ha_sphinx.cc
@@ -1042,8 +1042,8 @@ static bool ParseUrl ( CSphSEShare * share, TABLE * table, bool bCreate )
bool bOk = true;
bool bQL = false;
char * sScheme = NULL;
- char * sHost = SPHINXAPI_DEFAULT_HOST;
- char * sIndex = SPHINXAPI_DEFAULT_INDEX;
+ char * sHost = (char*) SPHINXAPI_DEFAULT_HOST;
+ char * sIndex = (char*) SPHINXAPI_DEFAULT_INDEX;
int iPort = SPHINXAPI_DEFAULT_PORT;
// parse connection string, if any
@@ -1069,12 +1069,12 @@ static bool ParseUrl ( CSphSEShare * share, TABLE * table, bool bCreate )
sHost--; // reuse last slash
iPort = 0;
if (!( sIndex = strrchr ( sHost, ':' ) ))
- sIndex = SPHINXAPI_DEFAULT_INDEX;
+ sIndex = (char*) SPHINXAPI_DEFAULT_INDEX;
else
{
*sIndex++ = '\0';
if ( !*sIndex )
- sIndex = SPHINXAPI_DEFAULT_INDEX;
+ sIndex = (char*) SPHINXAPI_DEFAULT_INDEX;
}
bOk = true;
break;
@@ -1096,11 +1096,11 @@ static bool ParseUrl ( CSphSEShare * share, TABLE * table, bool bCreate )
if ( sIndex )
*sIndex++ = '\0';
else
- sIndex = SPHINXAPI_DEFAULT_INDEX;
+ sIndex = (char*) SPHINXAPI_DEFAULT_INDEX;
iPort = atoi(sPort);
if ( !iPort )
- iPort = SPHINXAPI_DEFAULT_PORT;
+ iPort = SPHINXAPI_DEFAULT_PORT;
}
} else
{
@@ -1108,7 +1108,7 @@ static bool ParseUrl ( CSphSEShare * share, TABLE * table, bool bCreate )
if ( sIndex )
*sIndex++ = '\0';
else
- sIndex = SPHINXAPI_DEFAULT_INDEX;
+ sIndex = (char*) SPHINXAPI_DEFAULT_INDEX;
}
bOk = true;
break;
@@ -1159,7 +1159,7 @@ static bool ParseUrl ( CSphSEShare * share, TABLE * table, bool bCreate )
if ( !bOk )
{
my_error ( bCreate ? ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE : ER_FOREIGN_DATA_STRING_INVALID,
- MYF(0), table->s->connect_string );
+ MYF(0), table->s->connect_string.str);
} else
{
if ( share )
@@ -1304,8 +1304,8 @@ CSphSEQuery::CSphSEQuery ( const char * sQuery, int iLength, const char * sIndex
, m_sGeoLongAttr ( "" )
, m_fGeoLatitude ( 0.0f )
, m_fGeoLongitude ( 0.0f )
- , m_sComment ( "" )
- , m_sSelect ( "*" )
+ , m_sComment ( (char*) "" )
+ , m_sSelect ( (char*) "*" )
, m_pBuf ( NULL )
, m_pCur ( NULL )
@@ -3508,8 +3508,11 @@ int ha_sphinx::create ( const char * name, TABLE * table_arg, HA_CREATE_INFO * )
// report and bail
if ( sError[0] )
{
- my_error ( ER_CANT_CREATE_TABLE, MYF(0),
- table_arg->s->db.str, table_arg->s->table_name, sError );
+ my_printf_error(ER_CANT_CREATE_TABLE,
+ "Can\'t create table %s.%s (Error: %s)",
+ MYF(0),
+ table_arg->s->db.str,
+ table_arg->s->table_name.str, sError);
SPH_RET(-1);
}
diff --git a/storage/spider/CMakeLists.txt b/storage/spider/CMakeLists.txt
index 14c50f35bd9..21278dde3b3 100644
--- a/storage/spider/CMakeLists.txt
+++ b/storage/spider/CMakeLists.txt
@@ -1,13 +1,24 @@
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_HANDLERSOCKET")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_HANDLERSOCKET")
-MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-vla" DEBUG)
+IF(HAVE_WVLA)
+ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-vla")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wno-vla")
+ENDIF()
+
+IF(MSVC)
+ # Temporarily disable "conversion from size_t .."
+ IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267")
+ ENDIF()
+ENDIF()
SET(SPIDER_SOURCES
spd_param.cc spd_sys_table.cc spd_trx.cc spd_db_conn.cc spd_conn.cc
spd_table.cc spd_direct_sql.cc spd_udf.cc spd_ping_table.cc
spd_copy_tables.cc spd_i_s.cc spd_malloc.cc ha_spider.cc spd_udf.def
spd_db_mysql.cc spd_db_handlersocket.cc spd_db_oracle.cc
+ spd_group_by_handler.cc
hs_client/config.cpp hs_client/escape.cpp hs_client/fatal.cpp
hs_client/hstcpcli.cpp hs_client/socket.cpp hs_client/string_util.cpp
)
@@ -21,11 +32,11 @@ IF(DEFINED ENV{ORACLE_HOME})
ENDIF()
IF(EXISTS ${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake)
- SET(CMAKE_CXX_FLAGS_DEBUG
+ SET(CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi")
- SET(CMAKE_C_FLAGS_DEBUG
+ SET(CMAKE_C_FLAGS_DEBUG
"${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi")
- SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /MAP /MAPINFO:EXPORTS")
+ SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /MAP /MAPINFO:EXPORTS")
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
INCLUDE_DIRECTORIES(
@@ -34,6 +45,8 @@ IF(EXISTS ${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake)
${CMAKE_SOURCE_DIR}/regex)
MYSQL_STORAGE_ENGINE(SPIDER)
+ELSEIF(PLUGIN_PARTITION MATCHES "^NO$")
+ MESSAGE(STATUS "Spider is skipped because partitioning is disabled")
ELSE()
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/spider/hs_client)
@@ -53,3 +66,12 @@ IF(ORACLE_INCLUDE_DIR AND ORACLE_OCI_LIBRARY)
TARGET_LINK_LIBRARIES (spider ${ORACLE_OCI_LIBRARY})
ENDIF()
ENDIF()
+
+IF(MSVC)
+ IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
+ ADD_CUSTOM_COMMAND(TARGET spider
+ POST_BUILD
+ COMMAND if not exist ..\\..\\sql\\lib mkdir ..\\..\\sql\\lib\\plugin
+ COMMAND copy Debug\\ha_spider.dll ..\\..\\sql\\lib\\plugin\\ha_spider.dll)
+ ENDIF()
+ENDIF()
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc
index a38e90f373f..38f157d3c4f 100644
--- a/storage/spider/ha_spider.cc
+++ b/storage/spider/ha_spider.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation
@@ -20,6 +20,7 @@
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -108,6 +109,9 @@ ha_spider::ha_spider(
sql_kinds = 0;
error_mode = 0;
use_spatial_index = FALSE;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ use_fields = FALSE;
+#endif
use_pre_call = FALSE;
use_pre_records = FALSE;
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
@@ -152,6 +156,7 @@ ha_spider::ha_spider(
result_list.tmp_tables_created = FALSE;
result_list.bgs_working = FALSE;
result_list.direct_order_limit = FALSE;
+ result_list.direct_limit_offset = FALSE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
result_list.hs_has_result = FALSE;
#endif
@@ -216,6 +221,9 @@ ha_spider::ha_spider(
sql_kinds = 0;
error_mode = 0;
use_spatial_index = FALSE;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ use_fields = FALSE;
+#endif
use_pre_call = FALSE;
use_pre_records = FALSE;
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
@@ -260,6 +268,7 @@ ha_spider::ha_spider(
result_list.tmp_tables_created = FALSE;
result_list.bgs_working = FALSE;
result_list.direct_order_limit = FALSE;
+ result_list.direct_limit_offset = FALSE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
result_list.hs_has_result = FALSE;
#endif
@@ -415,6 +424,7 @@ int ha_spider::open(
partition_handler_share->rnd_bitmap_is_set = FALSE;
partition_handler_share->table_hash_value = hash_value;
partition_handler_share->creator = this;
+ partition_handler_share->parallel_search_query_id = 0;
pt_handler_share_creator = this;
if (part_num)
{
@@ -482,6 +492,8 @@ int ha_spider::open(
}
}
#endif
+ memset(ft_discard_bitmap, 0xFF, no_bytes_in_map(table->read_set));
+ memset(searched_bitmap, 0, no_bytes_in_map(table->read_set));
init_sql_alloc_size =
spider_param_init_sql_alloc_size(thd, share->init_sql_alloc_size);
@@ -1308,6 +1320,7 @@ int ha_spider::external_lock(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -1361,6 +1374,7 @@ int ha_spider::external_lock(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -1393,6 +1407,7 @@ int ha_spider::external_lock(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -1428,6 +1443,7 @@ int ha_spider::external_lock(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -1453,6 +1469,7 @@ int ha_spider::external_lock(
if (thd_test_options(trx->thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
trans_register_ha(trx->thd, TRUE, spider_hton_ptr);
}
+
if ((conn_kinds & SPIDER_CONN_KIND_HS_READ))
{
SPIDER_CONN *hs_conn;
@@ -1534,6 +1551,43 @@ int ha_spider::external_lock(
}
}
#endif
+
+ DBUG_PRINT("info",("spider trx_start=%s", trx->trx_start ? "TRUE" : "FALSE"));
+ /* need to check after spider_internal_start_trx() */
+ if (trx->trx_start)
+ {
+ switch (sql_command)
+ {
+ case SQLCOM_SELECT:
+ case SQLCOM_HA_READ:
+#ifdef HS_HAS_SQLCOM
+ case SQLCOM_HS_READ:
+#endif
+ /* nothing to do */
+ break;
+ case SQLCOM_UPDATE:
+ case SQLCOM_UPDATE_MULTI:
+#ifdef HS_HAS_SQLCOM
+ case SQLCOM_HS_UPDATE:
+#endif
+ case SQLCOM_CREATE_TABLE:
+ case SQLCOM_INSERT:
+ case SQLCOM_INSERT_SELECT:
+ case SQLCOM_DELETE:
+ case SQLCOM_LOAD:
+ case SQLCOM_REPLACE:
+ case SQLCOM_REPLACE_SELECT:
+ case SQLCOM_DELETE_MULTI:
+#ifdef HS_HAS_SQLCOM
+ case SQLCOM_HS_INSERT:
+ case SQLCOM_HS_DELETE:
+#endif
+ default:
+ trx->updated_in_this_trx = TRUE;
+ DBUG_PRINT("info",("spider trx->updated_in_this_trx=TRUE"));
+ break;
+ }
+ }
DBUG_RETURN(0);
}
@@ -1621,7 +1675,11 @@ int ha_spider::reset()
partition_handler_share->rnd_bitmap_is_set = FALSE;
}
#endif
- memset(ft_discard_bitmap, 0xFF, no_bytes_in_map(table->read_set));
+ if (!is_clone)
+ {
+ memset(ft_discard_bitmap, 0xFF, no_bytes_in_map(table->read_set));
+ memset(searched_bitmap, 0, no_bytes_in_map(table->read_set));
+ }
if (!(tmp_trx = spider_get_trx(thd, TRUE, &error_num2)))
{
DBUG_PRINT("info",("spider get trx error"));
@@ -1685,6 +1743,7 @@ int ha_spider::reset()
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -1791,6 +1850,7 @@ int ha_spider::reset()
prev_index_rnd_init = SPD_NONE;
result_list.have_sql_kind_backup = FALSE;
result_list.direct_order_limit = FALSE;
+ result_list.direct_limit_offset = FALSE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if ((error_num2 = reset_hs_strs(SPIDER_SQL_TYPE_UPDATE_HS)))
error_num = error_num2;
@@ -1798,6 +1858,9 @@ int ha_spider::reset()
result_list.set_split_read = FALSE;
result_list.insert_dup_update_pushdown = FALSE;
use_spatial_index = FALSE;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ use_fields = FALSE;
+#endif
error_mode = 0;
#ifdef HA_CAN_BULK_ACCESS
#ifndef DBUG_OFF
@@ -1872,9 +1935,14 @@ int ha_spider::extra(
DBUG_RETURN(error_num);
break;
#endif
+#if defined(HA_EXTRA_HAS_STARTING_ORDERED_INDEX_SCAN) || defined(HA_EXTRA_HAS_HA_EXTRA_USE_CMP_REF)
+#ifdef HA_EXTRA_HAS_STARTING_ORDERED_INDEX_SCAN
+ case HA_EXTRA_STARTING_ORDERED_INDEX_SCAN:
+#endif
#ifdef HA_EXTRA_HAS_HA_EXTRA_USE_CMP_REF
case HA_EXTRA_USE_CMP_REF:
- DBUG_PRINT("info",("spider HA_EXTRA_USE_CMP_REF"));
+#endif
+ DBUG_PRINT("info",("spider HA_EXTRA_STARTING_ORDERED_INDEX_SCAN"));
if (table_share->primary_key != MAX_KEY)
{
DBUG_PRINT("info",("spider need primary key columns"));
@@ -2221,6 +2289,7 @@ int ha_spider::index_read_map_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -2304,6 +2373,7 @@ int ha_spider::index_read_map_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -2337,6 +2407,7 @@ int ha_spider::index_read_map_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -2367,6 +2438,7 @@ int ha_spider::index_read_map_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -2713,6 +2785,7 @@ int ha_spider::index_read_last_map_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -2793,6 +2866,7 @@ int ha_spider::index_read_last_map_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -2826,6 +2900,7 @@ int ha_spider::index_read_last_map_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -2856,6 +2931,7 @@ int ha_spider::index_read_last_map_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3179,6 +3255,7 @@ int ha_spider::index_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3260,6 +3337,7 @@ int ha_spider::index_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3293,6 +3371,7 @@ int ha_spider::index_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3323,6 +3402,7 @@ int ha_spider::index_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3563,6 +3643,7 @@ int ha_spider::index_last_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3644,6 +3725,7 @@ int ha_spider::index_last_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3677,6 +3759,7 @@ int ha_spider::index_last_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3707,6 +3790,7 @@ int ha_spider::index_last_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4007,6 +4091,7 @@ int ha_spider::read_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4087,6 +4172,7 @@ int ha_spider::read_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4120,6 +4206,7 @@ int ha_spider::read_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4150,6 +4237,7 @@ int ha_spider::read_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4635,6 +4723,7 @@ int ha_spider::read_multi_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4720,6 +4809,7 @@ int ha_spider::read_multi_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4754,6 +4844,7 @@ int ha_spider::read_multi_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4786,6 +4877,7 @@ int ha_spider::read_multi_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -5426,6 +5518,7 @@ int ha_spider::read_multi_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -5514,6 +5607,7 @@ int ha_spider::read_multi_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -5554,6 +5648,7 @@ int ha_spider::read_multi_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -5589,6 +5684,7 @@ int ha_spider::read_multi_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -5619,6 +5715,7 @@ int ha_spider::read_multi_range_first_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6075,6 +6172,7 @@ int ha_spider::read_multi_range_next(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6160,6 +6258,7 @@ int ha_spider::read_multi_range_next(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6194,6 +6293,7 @@ int ha_spider::read_multi_range_next(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6226,6 +6326,7 @@ int ha_spider::read_multi_range_next(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6870,6 +6971,7 @@ int ha_spider::read_multi_range_next(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6958,6 +7060,7 @@ int ha_spider::read_multi_range_next(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6998,6 +7101,7 @@ int ha_spider::read_multi_range_next(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7033,6 +7137,7 @@ int ha_spider::read_multi_range_next(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7063,6 +7168,7 @@ int ha_spider::read_multi_range_next(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7366,6 +7472,8 @@ int ha_spider::rnd_next_internal(
uchar *buf
) {
int error_num;
+ ha_spider *direct_limit_offset_spider =
+ (ha_spider *) partition_handler_share->creator;
backup_error_status();
DBUG_ENTER("ha_spider::rnd_next_internal");
DBUG_PRINT("info",("spider this=%p", this));
@@ -7397,6 +7505,42 @@ int ha_spider::rnd_next_internal(
#ifdef WITH_PARTITION_STORAGE_ENGINE
check_select_column(TRUE);
#endif
+
+ if (this->result_list.direct_limit_offset)
+ {
+ if (direct_limit_offset_spider->direct_select_limit == 0)
+ { // mean has got all result
+ DBUG_RETURN(check_error_mode_eof(HA_ERR_END_OF_FILE));
+ }
+ if (
+ partition_handler_share->handlers &&
+ direct_limit_offset_spider->direct_current_offset > 0
+ ) {
+ longlong table_count = this->records();
+ DBUG_PRINT("info",("spider table_count=%lld", table_count));
+ if (table_count <= direct_limit_offset_spider->direct_current_offset)
+ {
+ // skip this spider(partition)
+ direct_limit_offset_spider->direct_current_offset -= table_count;
+ DBUG_PRINT("info",("spider direct_current_offset=%lld",
+ direct_limit_offset_spider->direct_current_offset));
+ DBUG_RETURN(check_error_mode_eof(HA_ERR_END_OF_FILE));
+ }
+ }
+
+ // make the offset/limit statement
+ DBUG_PRINT("info",("spider direct_current_offset=%lld",
+ direct_limit_offset_spider->direct_current_offset));
+ result_list.internal_offset = direct_limit_offset_spider->direct_current_offset;
+ DBUG_PRINT("info",("spider direct_select_limit=%lld",
+ direct_limit_offset_spider->direct_select_limit));
+ result_list.internal_limit = direct_limit_offset_spider->direct_select_limit;
+ result_list.split_read = direct_limit_offset_spider->direct_select_limit;
+
+ // start with this spider(partition)
+ direct_limit_offset_spider->direct_current_offset = 0;
+ }
+
DBUG_PRINT("info",("spider result_list.finish_flg = FALSE"));
result_list.finish_flg = FALSE;
result_list.record_num = 0;
@@ -7500,6 +7644,7 @@ int ha_spider::rnd_next_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7559,6 +7704,7 @@ int ha_spider::rnd_next_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7592,6 +7738,7 @@ int ha_spider::rnd_next_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7622,6 +7769,7 @@ int ha_spider::rnd_next_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7647,7 +7795,25 @@ int ha_spider::rnd_next_internal(
#endif
}
rnd_scan_and_first = FALSE;
+
+ if (this->result_list.direct_limit_offset)
+ {
+ if (buf && (error_num = spider_db_seek_next(buf, this, search_link_idx,
+ table)))
+ DBUG_RETURN(check_error_mode_eof(error_num));
+ DBUG_RETURN(0);
+ }
}
+
+ if (
+ result_list.direct_limit_offset &&
+ direct_limit_offset_spider->direct_select_offset > 0
+ ) {
+ // limit-- for each got row
+ direct_limit_offset_spider->direct_select_offset--;
+ DBUG_RETURN(0);
+ }
+
if (buf && (error_num = spider_db_seek_next(buf, this, search_link_idx,
table)))
DBUG_RETURN(check_error_mode_eof(error_num));
@@ -7794,7 +7960,7 @@ int ha_spider::cmp_ref(
*field;
field++
) {
- if ((ret = (*field)->cmp_binary_offset((uint)ptr_diff)))
+ if ((ret = (*field)->cmp_binary_offset((uint) ptr_diff)))
{
DBUG_PRINT("info",("spider different at %s",
(*field)->field_name.str));
@@ -7900,6 +8066,7 @@ void ha_spider::ft_end()
store_error_num = index_end();
}
ft_init_without_index_init = FALSE;
+ handler::ft_end();
DBUG_VOID_RETURN;
}
@@ -8099,6 +8266,7 @@ int ha_spider::ft_read_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -8152,6 +8320,7 @@ int ha_spider::ft_read_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -8184,6 +8353,7 @@ int ha_spider::ft_read_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -8214,6 +8384,7 @@ int ha_spider::ft_read_internal(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -8474,6 +8645,7 @@ int ha_spider::info(
trx,
trx->thd,
share,
+ search_link_idx,
(uint32) share->monitoring_sid[search_link_idx],
share->table_name,
share->table_name_length,
@@ -8521,7 +8693,7 @@ int ha_spider::info(
}
}
#ifndef WITHOUT_SPIDER_BG_SEARCH
- } else {
+ } else if (sts_bg_mode == 1) {
/* background */
if (!share->bg_sts_init || share->bg_sts_thd_wait)
{
@@ -8551,6 +8723,14 @@ int ha_spider::info(
} else
pthread_cond_signal(&share->bg_sts_cond);
}
+ } else {
+ share->bg_sts_try_time = tmp_time;
+ share->bg_sts_interval = sts_interval;
+ share->bg_sts_mode = sts_mode;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ share->bg_sts_sync = sts_sync;
+#endif
+ spider_table_add_share_to_sts_thread(share);
}
#endif
pthread_mutex_unlock(&share->sts_mutex);
@@ -8744,6 +8924,7 @@ ha_rows ha_spider::records_in_range(
trx,
trx->thd,
share,
+ search_link_idx,
(uint32) share->monitoring_sid[search_link_idx],
share->table_name,
share->table_name_length,
@@ -8784,7 +8965,7 @@ ha_rows ha_spider::records_in_range(
}
}
#ifndef WITHOUT_SPIDER_BG_SEARCH
- } else {
+ } else if (crd_bg_mode == 1) {
/* background */
if (!share->bg_crd_init || share->bg_crd_thd_wait)
{
@@ -8806,6 +8987,14 @@ ha_rows ha_spider::records_in_range(
} else
pthread_cond_signal(&share->bg_crd_cond);
}
+ } else {
+ share->bg_crd_try_time = tmp_time;
+ share->bg_crd_interval = crd_interval;
+ share->bg_crd_mode = crd_mode;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ share->bg_crd_sync = crd_sync;
+#endif
+ spider_table_add_share_to_crd_thread(share);
}
#endif
pthread_mutex_unlock(&share->crd_mutex);
@@ -9035,6 +9224,7 @@ int ha_spider::check_crd()
trx,
trx->thd,
share,
+ search_link_idx,
(uint32) share->monitoring_sid[search_link_idx],
share->table_name,
share->table_name_length,
@@ -9069,7 +9259,7 @@ int ha_spider::check_crd()
}
}
#ifndef WITHOUT_SPIDER_BG_SEARCH
- } else {
+ } else if (crd_bg_mode == 1) {
/* background */
if (!share->bg_crd_init || share->bg_crd_thd_wait)
{
@@ -9090,6 +9280,14 @@ int ha_spider::check_crd()
} else
pthread_cond_signal(&share->bg_crd_cond);
}
+ } else {
+ share->bg_crd_try_time = tmp_time;
+ share->bg_crd_interval = crd_interval;
+ share->bg_crd_mode = crd_mode;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ share->bg_crd_sync = crd_sync;
+#endif
+ spider_table_add_share_to_crd_thread(share);
}
#endif
pthread_mutex_unlock(&share->crd_mutex);
@@ -9139,11 +9337,11 @@ ha_rows ha_spider::records()
use_pre_records = FALSE;
DBUG_RETURN(0);
}
- if (!(share->additional_table_flags & HA_HAS_RECORDS))
+ if (!(share->additional_table_flags & HA_HAS_RECORDS) && !this->result_list.direct_limit_offset)
{
DBUG_RETURN(handler::records());
}
- if (!use_pre_records)
+ if (!use_pre_records && !this->result_list.direct_limit_offset)
{
THD *thd = trx->thd;
if (
@@ -9194,6 +9392,9 @@ ulonglong ha_spider::table_flags() const
HA_BINLOG_ROW_CAPABLE |
HA_BINLOG_STMT_CAPABLE |
HA_PARTIAL_COLUMN_READ |
+#ifdef HA_CMP_REF_IS_EXPENSIVE
+ HA_CMP_REF_IS_EXPENSIVE |
+#endif
#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON
HA_CAN_TABLE_CONDITION_PUSHDOWN |
#endif
@@ -9205,6 +9406,9 @@ ulonglong ha_spider::table_flags() const
SPIDER_CAN_BG_SEARCH |
SPIDER_CAN_BG_INSERT |
SPIDER_CAN_BG_UPDATE |
+#ifdef HA_CAN_DIRECT_UPDATE_AND_DELETE
+ HA_CAN_DIRECT_UPDATE_AND_DELETE |
+#endif
#ifdef HA_CAN_FORCE_BULK_UPDATE
(share && share->force_bulk_update ? HA_CAN_FORCE_BULK_UPDATE : 0) |
#endif
@@ -9566,6 +9770,9 @@ int ha_spider::write_row(
DBUG_RETURN(error_num);
}
#endif
+#ifndef SPIDER_WITHOUT_HA_STATISTIC_INCREMENT
+ ha_statistic_increment(&SSV::ha_write_count);
+#endif
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000
#else
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
@@ -9726,7 +9933,7 @@ bool ha_spider::start_bulk_update(
}
int ha_spider::exec_bulk_update(
- uint *dup_key_found
+ ha_rows *dup_key_found
) {
int error_num;
backup_error_status();
@@ -9738,7 +9945,7 @@ int ha_spider::exec_bulk_update(
DBUG_RETURN(0);
}
-void ha_spider::end_bulk_update(
+int ha_spider::end_bulk_update(
) {
int error_num;
backup_error_status();
@@ -9747,15 +9954,15 @@ void ha_spider::end_bulk_update(
if ((error_num = check_and_end_bulk_update(SPD_BU_START_BY_BULK_INIT)))
{
if (check_error_mode(error_num))
- my_errno = error_num;
+ DBUG_RETURN(error_num);
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(0);
}
int ha_spider::bulk_update_row(
const uchar *old_data,
const uchar *new_data,
- uint *dup_key_found
+ ha_rows *dup_key_found
) {
DBUG_ENTER("ha_spider::bulk_update_row");
DBUG_PRINT("info",("spider this=%p", this));
@@ -9801,6 +10008,9 @@ int ha_spider::update_row(
DBUG_RETURN(error_num);
}
#endif
+#ifndef SPIDER_WITHOUT_HA_STATISTIC_INCREMENT
+ ha_statistic_increment(&SSV::ha_update_count);
+#endif
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
do_direct_update = FALSE;
#endif
@@ -9853,12 +10063,13 @@ int ha_spider::update_row(
}
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int ha_spider::direct_update_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
- uchar *new_data
+ const uchar *new_data
) {
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
int error_num;
@@ -9990,8 +10201,103 @@ int ha_spider::direct_update_rows_init(
do_direct_update = FALSE;
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
+#else
+int ha_spider::direct_update_rows_init()
+{
+ st_select_lex *select_lex;
+ longlong select_limit;
+ longlong offset_limit;
+ THD *thd = trx->thd;
+ DBUG_ENTER("ha_spider::direct_update_rows_init");
+ DBUG_PRINT("info",("spider this=%p", this));
+#ifdef HA_CAN_BULK_ACCESS
+ if (
+ bulk_access_executing &&
+ (
+ (
+ !is_bulk_access_clone &&
+ bulk_access_link_exec_tgt->called
+ ) ||
+ bulk_access_pre_called
+ )
+ ) {
+ if (is_bulk_access_clone)
+ {
+ DBUG_PRINT("info",("spider return pre_direct_init_result %d",
+ pre_direct_init_result));
+ DBUG_RETURN(pre_direct_init_result);
+ }
+ DBUG_RETURN(bulk_access_link_exec_tgt->spider->direct_update_rows_init());
+ }
+#endif
+ direct_update_init(
+ thd,
+ FALSE
+ );
+ if (!condition)
+ cond_check = FALSE;
+ spider_get_select_limit(this, &select_lex, &select_limit, &offset_limit);
+ if (direct_update_fields)
+ {
+ if (
+#if MYSQL_VERSION_ID < 50500
+ !thd->variables.engine_condition_pushdown ||
+#else
+#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON
+#else
+ !(thd->variables.optimizer_switch &
+ OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) ||
+#endif
+#endif
+ !select_lex ||
+ select_lex->table_list.elements != 1 ||
+ check_update_columns_sql_part() ||
+ spider_db_append_condition(this, NULL, 0, TRUE)
+ ) {
+ DBUG_PRINT("info",("spider FALSE by condition"));
+ do_direct_update = FALSE;
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ }
+ if (select_lex->order_list.elements)
+ {
+ ORDER *order;
+ for (order = (ORDER *) select_lex->order_list.first; order;
+ order = order->next)
+ {
+ if (check_item_type_sql((*order->item)))
+ {
+ DBUG_PRINT("info",("spider FALSE by order"));
+ do_direct_update = FALSE;
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ }
+ }
+ result_list.direct_order_limit = TRUE;
+ }
+ trx->direct_update_count++;
+ DBUG_PRINT("info",("spider OK"));
+ DBUG_RETURN(0);
+ }
+
+ DBUG_PRINT("info",("spider offset_limit=%lld", offset_limit));
+ DBUG_PRINT("info",("spider sql_command=%u", sql_command));
+ DBUG_PRINT("info",("spider do_direct_update=%s",
+ do_direct_update ? "TRUE" : "FALSE"));
+ if (
+ !offset_limit &&
+ do_direct_update
+ ) {
+ trx->direct_update_count++;
+ DBUG_PRINT("info",("spider OK"));
+ DBUG_RETURN(0);
+ }
+ DBUG_PRINT("info",("spider FALSE by default"));
+ do_direct_update = FALSE;
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+}
+#endif
#ifdef HA_CAN_BULK_ACCESS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int ha_spider::pre_direct_update_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
@@ -10005,7 +10311,7 @@ int ha_spider::pre_direct_update_rows_init(
if (bulk_access_started)
{
error_num = bulk_access_link_current->spider->
- ha_pre_direct_update_rows_init(
+ pre_direct_update_rows_init(
mode, ranges, range_count, sorted, new_data);
bulk_access_link_current->spider->bulk_access_pre_called = TRUE;
bulk_access_link_current->called = TRUE;
@@ -10015,14 +10321,33 @@ int ha_spider::pre_direct_update_rows_init(
mode, ranges, range_count, sorted, new_data);
DBUG_RETURN(pre_direct_init_result);
}
+#else
+int ha_spider::pre_direct_update_rows_init()
+{
+ int error_num;
+ DBUG_ENTER("ha_spider::pre_direct_update_rows_init");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (bulk_access_started)
+ {
+ error_num = bulk_access_link_current->spider->
+ pre_direct_update_rows_init();
+ bulk_access_link_current->spider->bulk_access_pre_called = TRUE;
+ bulk_access_link_current->called = TRUE;
+ DBUG_RETURN(error_num);
+ }
+ pre_direct_init_result = direct_update_rows_init();
+ DBUG_RETURN(pre_direct_init_result);
+}
+#endif
#endif
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int ha_spider::direct_update_rows(
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
uchar *new_data,
- uint *update_rows
+ ha_rows *update_rows
) {
int error_num;
THD *thd = ha_thd();
@@ -10072,20 +10397,83 @@ int ha_spider::direct_update_rows(
#endif
DBUG_RETURN(0);
}
+#else
+int ha_spider::direct_update_rows(
+ ha_rows *update_rows
+) {
+ int error_num;
+ THD *thd = ha_thd();
+ backup_error_status();
+ DBUG_ENTER("ha_spider::direct_update_rows");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (spider_param_read_only_mode(thd, share->read_only_mode))
+ {
+ my_printf_error(ER_SPIDER_READ_ONLY_NUM, ER_SPIDER_READ_ONLY_STR, MYF(0),
+ table_share->db.str, table_share->table_name.str);
+ DBUG_RETURN(ER_SPIDER_READ_ONLY_NUM);
+ }
+#ifdef HA_CAN_BULK_ACCESS
+ if (
+ bulk_access_executing &&
+ (
+ (
+ !is_bulk_access_clone &&
+ bulk_access_link_exec_tgt->called
+ ) ||
+ bulk_access_pre_called
+ )
+ ) {
+ if (is_bulk_access_clone)
+ {
+ bulk_access_pre_called = FALSE;
+ DBUG_RETURN(spider_db_bulk_direct_update(this, update_rows));
+ }
+ DBUG_RETURN(bulk_access_link_exec_tgt->spider->ha_direct_update_rows(
+ update_rows));
+ }
+#endif
+ if (
+ (active_index != MAX_KEY && (error_num = index_handler_init())) ||
+ (active_index == MAX_KEY && (error_num = rnd_handler_init())) ||
+ (error_num = spider_db_direct_update(this, table, update_rows))
+ )
+ DBUG_RETURN(check_error_mode(error_num));
+
+#ifdef HA_CAN_BULK_ACCESS
+ if (bulk_access_executing && is_bulk_access_clone)
+ {
+ bulk_req_exec();
+ DBUG_RETURN(spider_db_bulk_direct_update(this, update_rows));
+ }
+#endif
+ DBUG_RETURN(0);
+}
+#endif
#ifdef HA_CAN_BULK_ACCESS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int ha_spider::pre_direct_update_rows(
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
uchar *new_data,
- uint *update_rows
+ ha_rows *update_rows
) {
DBUG_ENTER("ha_spider::pre_direct_update_rows");
DBUG_PRINT("info",("spider this=%p", this));
DBUG_RETURN(bulk_access_link_current->spider->ha_direct_update_rows(ranges,
range_count, sorted, new_data, update_rows));
}
+#else
+int ha_spider::pre_direct_update_rows()
+{
+ uint update_rows;
+ DBUG_ENTER("ha_spider::pre_direct_update_rows");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN(bulk_access_link_current->spider->ha_direct_update_rows(
+ &update_rows));
+}
+#endif
#endif
#endif
@@ -10143,6 +10531,9 @@ int ha_spider::delete_row(
DBUG_RETURN(error_num);
}
#endif
+#ifndef SPIDER_WITHOUT_HA_STATISTIC_INCREMENT
+ ha_statistic_increment(&SSV::ha_delete_count);
+#endif
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
do_direct_update = FALSE;
#endif
@@ -10152,6 +10543,7 @@ int ha_spider::delete_row(
}
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int ha_spider::direct_delete_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
@@ -10263,8 +10655,81 @@ int ha_spider::direct_delete_rows_init(
do_direct_update = FALSE;
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
+#else
+int ha_spider::direct_delete_rows_init()
+{
+ st_select_lex *select_lex;
+ longlong select_limit;
+ longlong offset_limit;
+ THD *thd = trx->thd;
+ DBUG_ENTER("ha_spider::direct_delete_rows_init");
+ DBUG_PRINT("info",("spider this=%p", this));
+#ifdef HA_CAN_BULK_ACCESS
+ if (
+ bulk_access_executing &&
+ (
+ (
+ !is_bulk_access_clone &&
+ bulk_access_link_exec_tgt->called
+ ) ||
+ bulk_access_pre_called
+ )
+ ) {
+ if (is_bulk_access_clone)
+ {
+ DBUG_RETURN(pre_direct_init_result);
+ }
+ DBUG_RETURN(bulk_access_link_exec_tgt->spider->direct_delete_rows_init());
+ }
+#endif
+ direct_update_init(
+ thd,
+ FALSE
+ );
+ if (!condition)
+ cond_check = FALSE;
+ spider_get_select_limit(this, &select_lex, &select_limit, &offset_limit);
+ if (
+#if MYSQL_VERSION_ID < 50500
+ !thd->variables.engine_condition_pushdown ||
+#else
+#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON
+#else
+ !(thd->variables.optimizer_switch &
+ OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) ||
+#endif
+#endif
+ !select_lex ||
+ select_lex->table_list.elements != 1 ||
+ spider_db_append_condition(this, NULL, 0, TRUE)
+ ) {
+ DBUG_PRINT("info",("spider FALSE by condition"));
+ do_direct_update = FALSE;
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ }
+ if (select_lex->order_list.elements)
+ {
+ ORDER *order;
+ for (order = (ORDER *) select_lex->order_list.first; order;
+ order = order->next)
+ {
+ if (check_item_type_sql((*order->item)))
+ {
+ DBUG_PRINT("info",("spider FALSE by order"));
+ do_direct_update = FALSE;
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ }
+ }
+ result_list.direct_order_limit = TRUE;
+ }
+ trx->direct_delete_count++;
+ DBUG_PRINT("info",("spider OK"));
+ DBUG_RETURN(0);
+}
+#endif
#ifdef HA_CAN_BULK_ACCESS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int ha_spider::pre_direct_delete_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
@@ -10277,7 +10742,7 @@ int ha_spider::pre_direct_delete_rows_init(
if (bulk_access_started)
{
error_num = bulk_access_link_current->spider->
- ha_pre_direct_delete_rows_init(
+ pre_direct_delete_rows_init(
mode, ranges, range_count, sorted);
bulk_access_link_current->spider->bulk_access_pre_called = TRUE;
bulk_access_link_current->called = TRUE;
@@ -10287,13 +10752,32 @@ int ha_spider::pre_direct_delete_rows_init(
mode, ranges, range_count, sorted);
DBUG_RETURN(pre_direct_init_result);
}
+#else
+int ha_spider::pre_direct_delete_rows_init()
+{
+ int error_num;
+ DBUG_ENTER("ha_spider::pre_direct_delete_rows_init");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (bulk_access_started)
+ {
+ error_num = bulk_access_link_current->spider->
+ pre_direct_delete_rows_init();
+ bulk_access_link_current->spider->bulk_access_pre_called = TRUE;
+ bulk_access_link_current->called = TRUE;
+ DBUG_RETURN(error_num);
+ }
+ pre_direct_init_result = direct_delete_rows_init();
+ DBUG_RETURN(pre_direct_init_result);
+}
+#endif
#endif
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int ha_spider::direct_delete_rows(
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
- uint *delete_rows
+ ha_rows *delete_rows
) {
int error_num;
THD *thd = ha_thd();
@@ -10343,19 +10827,82 @@ int ha_spider::direct_delete_rows(
#endif
DBUG_RETURN(0);
}
+#else
+int ha_spider::direct_delete_rows(
+ ha_rows *delete_rows
+) {
+ int error_num;
+ THD *thd = ha_thd();
+ backup_error_status();
+ DBUG_ENTER("ha_spider::direct_delete_rows");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (spider_param_read_only_mode(thd, share->read_only_mode))
+ {
+ my_printf_error(ER_SPIDER_READ_ONLY_NUM, ER_SPIDER_READ_ONLY_STR, MYF(0),
+ table_share->db.str, table_share->table_name.str);
+ DBUG_RETURN(ER_SPIDER_READ_ONLY_NUM);
+ }
+#ifdef HA_CAN_BULK_ACCESS
+ if (
+ bulk_access_executing &&
+ (
+ (
+ !is_bulk_access_clone &&
+ bulk_access_link_exec_tgt->called
+ ) ||
+ bulk_access_pre_called
+ )
+ ) {
+ if (is_bulk_access_clone)
+ {
+ bulk_access_pre_called = FALSE;
+ DBUG_RETURN(spider_db_bulk_direct_update(this, delete_rows));
+ }
+ DBUG_RETURN(bulk_access_link_exec_tgt->spider->ha_direct_delete_rows(
+ delete_rows));
+ }
+#endif
+ if (
+ (active_index != MAX_KEY && (error_num = index_handler_init())) ||
+ (active_index == MAX_KEY && (error_num = rnd_handler_init())) ||
+ (error_num = spider_db_direct_delete(this, table, delete_rows))
+ )
+ DBUG_RETURN(check_error_mode(error_num));
#ifdef HA_CAN_BULK_ACCESS
+ if (bulk_access_executing && is_bulk_access_clone)
+ {
+ bulk_req_exec();
+ DBUG_RETURN(spider_db_bulk_direct_update(this, delete_rows));
+ }
+#endif
+ DBUG_RETURN(0);
+}
+#endif
+
+#ifdef HA_CAN_BULK_ACCESS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int ha_spider::pre_direct_delete_rows(
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
- uint *delete_rows
+ ha_rows *delete_rows
) {
DBUG_ENTER("ha_spider::pre_direct_delete_rows");
DBUG_PRINT("info",("spider this=%p", this));
DBUG_RETURN(bulk_access_link_current->spider->ha_direct_delete_rows(
ranges, range_count, sorted, delete_rows));
}
+#else
+int ha_spider::pre_direct_delete_rows()
+{
+ uint delete_rows;
+ DBUG_ENTER("ha_spider::pre_direct_delete_rows");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN(bulk_access_link_current->spider->ha_direct_delete_rows(
+ &delete_rows));
+}
+#endif
#endif
#endif
@@ -10540,7 +11087,17 @@ void ha_spider::print_error(
DBUG_ENTER("ha_spider::print_error");
DBUG_PRINT("info",("spider this=%p", this));
if (!current_thd->is_error())
- handler::print_error(error, errflag);
+ {
+ switch (error)
+ {
+ case ER_SPIDER_CON_COUNT_ERROR:
+ my_message(error, ER_SPIDER_CON_COUNT_ERROR_STR, MYF(0));
+ break;
+ default:
+ handler::print_error(error, errflag);
+ break;
+ }
+ }
DBUG_VOID_RETURN;
}
@@ -10572,7 +11129,7 @@ int ha_spider::create(
TABLE *form,
HA_CREATE_INFO *info
) {
- int error_num;
+ int error_num, dummy;
SPIDER_SHARE tmp_share;
THD *thd = ha_thd();
uint sql_command = thd_sql_command(thd), roop_count;
@@ -10663,6 +11220,15 @@ int ha_spider::create(
) {
goto error;
}
+#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE
+ if (
+ thd->lex->create_info.or_replace() &&
+ (error_num = spider_delete_tables(
+ table_tables, tmp_share.table_name, &dummy))
+ ) {
+ goto error;
+ }
+#endif
if (
(error_num = spider_insert_tables(table_tables, &tmp_share))
) {
@@ -10697,7 +11263,7 @@ int ha_spider::create(
trx->tmp_flg = TRUE;
DBUG_PRINT("info",
- ("spider alter_info.flags=%u", thd->lex->alter_info.flags));
+ ("spider alter_info.flags=%llu", thd->lex->alter_info.flags));
if (
(thd->lex->alter_info.flags &
(
@@ -10858,7 +11424,13 @@ int ha_spider::rename_table(
/* release table mon list */
for (roop_count = 0; roop_count < old_link_count; roop_count++)
- spider_release_ping_table_mon_list(from, from_len, roop_count);
+ {
+ if ((error_num =
+ spider_release_ping_table_mon_list(from, from_len, roop_count)))
+ {
+ goto error;
+ }
+ }
} else if (sql_command == SQLCOM_ALTER_TABLE)
{
DBUG_PRINT("info",("spider alter_table_from=%p", alter_table_from));
@@ -10887,7 +11459,7 @@ int ha_spider::rename_table(
}
DBUG_PRINT("info",
- ("spider alter_info.flags=%u", thd->lex->alter_info.flags));
+ ("spider alter_info.flags=%llu", thd->lex->alter_info.flags));
if (
(thd->lex->alter_info.flags &
(
@@ -10940,9 +11512,21 @@ int ha_spider::rename_table(
/* release table mon list */
for (roop_count = 0; roop_count < (int) alter_table_from->all_link_count;
roop_count++)
- spider_release_ping_table_mon_list(from, from_len, roop_count);
+ {
+ if ((error_num =
+ spider_release_ping_table_mon_list(from, from_len, roop_count)))
+ {
+ goto error;
+ }
+ }
for (roop_count = 0; roop_count < old_link_count; roop_count++)
- spider_release_ping_table_mon_list(to, to_len, roop_count);
+ {
+ if ((error_num =
+ spider_release_ping_table_mon_list(to, to_len, roop_count)))
+ {
+ goto error;
+ }
+ }
}
/*
spider_free_trx_alter_table_alloc(trx, alter_table_from);
@@ -11070,7 +11654,7 @@ int ha_spider::delete_table(
DBUG_RETURN(0);
DBUG_PRINT("info",
- ("spider alter_info.flags=%u", thd->lex->alter_info.flags));
+ ("spider alter_info.flags=%llu", thd->lex->alter_info.flags));
if (
sql_command == SQLCOM_ALTER_TABLE &&
(thd->lex->alter_info.flags &
@@ -11083,6 +11667,12 @@ int ha_spider::delete_table(
)
need_lock = TRUE;
+ if ((error_num = spider_sys_delete_table_sts(
+ current_thd, name, name_len, need_lock)))
+ goto error;
+ if ((error_num = spider_sys_delete_table_crd(
+ current_thd, name, name_len, need_lock)))
+ goto error;
if (
!(table_tables = spider_open_sys_table(
current_thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
@@ -11103,7 +11693,11 @@ int ha_spider::delete_table(
/* release table mon list */
for (roop_count = 0; roop_count < old_link_count; roop_count++)
- spider_release_ping_table_mon_list(name, name_len, roop_count);
+ {
+ if ((error_num =
+ spider_release_ping_table_mon_list(name, name_len, roop_count)))
+ goto error;
+ }
pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex);
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
@@ -11294,15 +11888,18 @@ Field *ha_spider::field_exchange(
}
#endif
DBUG_PRINT("info",("spider in field=%p", field));
+ DBUG_PRINT("info",("spider in field->table=%p", field->table));
#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
if (set_top_table_fields)
{
+ DBUG_PRINT("info",("spider top_table=%p", top_table));
if (field->table != top_table)
DBUG_RETURN(NULL);
if (!(field = top_table_field[field->field_index]))
DBUG_RETURN(NULL);
} else {
#endif
+ DBUG_PRINT("info",("spider table=%p", table));
if (field->table != table)
DBUG_RETURN(NULL);
#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
@@ -11482,6 +12079,7 @@ int ha_spider::info_push(
hs_decrement = FALSE;
break;
#endif
+#ifdef INFO_KIND_UPDATE_FIELDS
case INFO_KIND_UPDATE_FIELDS:
DBUG_PRINT("info",("spider INFO_KIND_UPDATE_FIELDS"));
direct_update_fields = (List<Item> *) info;
@@ -11491,10 +12089,13 @@ int ha_spider::info_push(
keyread = FALSE;
#endif
break;
+#endif
+#ifdef INFO_KIND_UPDATE_VALUES
case INFO_KIND_UPDATE_VALUES:
DBUG_PRINT("info",("spider INFO_KIND_UPDATE_VALUES"));
direct_update_values = (List<Item> *) info;
break;
+#endif
#ifdef INFO_KIND_FORCE_LIMIT_BEGIN
case INFO_KIND_FORCE_LIMIT_BEGIN:
DBUG_PRINT("info",("spider INFO_KIND_FORCE_LIMIT_BEGIN"));
@@ -11773,8 +12374,22 @@ void ha_spider::set_searched_bitmap()
void ha_spider::set_clone_searched_bitmap()
{
DBUG_ENTER("ha_spider::set_clone_searched_bitmap");
+ DBUG_PRINT("info",("spider searched_bitmap=%p", searched_bitmap));
+#ifndef DBUG_OFF
+ int roop_count;
+ for (roop_count = 0; roop_count < (int) ((table_share->fields + 7) / 8);
+ roop_count++)
+ DBUG_PRINT("info", ("spider before searched_bitmap is %x",
+ ((uchar *) searched_bitmap)[roop_count]));
+#endif
memcpy(searched_bitmap, pt_clone_source_handler->searched_bitmap,
(table_share->fields + 7) / 8);
+#ifndef DBUG_OFF
+ for (roop_count = 0; roop_count < (int) ((table_share->fields + 7) / 8);
+ roop_count++)
+ DBUG_PRINT("info", ("spider after searched_bitmap is %x",
+ ((uchar *) searched_bitmap)[roop_count]));
+#endif
memcpy(ft_discard_bitmap, pt_clone_source_handler->ft_discard_bitmap,
(table_share->fields + 7) / 8);
DBUG_VOID_RETURN;
@@ -12027,7 +12642,7 @@ int ha_spider::check_and_end_bulk_update(
spider_bulk_upd_start bulk_upd_start
) {
int error_num = 0;
- uint dup_key_found = 0;
+ ha_rows dup_key_found = 0;
DBUG_ENTER("ha_spider::check_and_end_bulk_update");
DBUG_PRINT("info",("spider this=%p", this));
DBUG_PRINT("info",("spider bulk_update_start=%d",
@@ -12079,6 +12694,8 @@ void ha_spider::check_direct_order_limit()
sql_kind[roop_count] = SPIDER_SQL_KIND_SQL;
} else
result_list.direct_order_limit = FALSE;
+
+ spider_set_direct_limit_offset(this);
result_list.check_direct_order_limit = TRUE;
}
DBUG_VOID_RETURN;
@@ -12097,27 +12714,27 @@ void ha_spider::check_direct_order_limit()
********************************************************************/
void ha_spider::check_distinct_key_query()
{
- DBUG_ENTER( "ha_spider::check_distinct_key_query" );
+ DBUG_ENTER( "ha_spider::check_distinct_key_query" );
- if ( result_list.direct_distinct && !partition_handler_share->handlers &&
- result_list.keyread && result_list.check_direct_order_limit )
- {
- // SELECT DISTINCT query using an index in a non-partitioned configuration
- KEY_PART_INFO* key_part = result_list.key_info->key_part;
- Field* key_field = key_part->field;
+ if ( result_list.direct_distinct && !partition_handler_share->handlers &&
+ result_list.keyread && result_list.check_direct_order_limit )
+ {
+ // SELECT DISTINCT query using an index in a non-partitioned configuration
+ KEY_PART_INFO* key_part = result_list.key_info->key_part;
+ Field* key_field = key_part->field;
- if ( is_sole_projection_field( key_field->field_index ) )
- {
- // Projection list consists solely of the first key prefix column
+ if ( is_sole_projection_field( key_field->field_index ) )
+ {
+ // Projection list consists solely of the first key prefix column
- // Set the internal row retrieval limit to avoid visiting each row
- // multiple times. This fixes a Spider performance bug that
- // caused each row to be visited multiple times.
- result_list.internal_limit = 1;
- }
+ // Set the internal row retrieval limit to avoid visiting each row
+ // multiple times. This fixes a Spider performance bug that
+ // caused each row to be visited multiple times.
+ result_list.internal_limit = 1;
}
+ }
- DBUG_VOID_RETURN;
+ DBUG_VOID_RETURN;
}
/********************************************************************
@@ -12132,31 +12749,32 @@ void ha_spider::check_distinct_key_query()
* solely of the specified column.
* FALSE - otherwise.
********************************************************************/
-bool ha_spider::is_sole_projection_field( uint16 field_index )
-{
- // NOTE: It is assumed that spider_db_append_select_columns() has already been called
- // to build the bitmap of projection fields
- bool is_ha_sole_projection_field;
- uint loop_index, dbton_id;
- spider_db_handler* dbton_hdl;
- DBUG_ENTER( "ha_spider::is_sole_projection_field" );
+bool ha_spider::is_sole_projection_field(
+ uint16 field_index
+) {
+ // NOTE: It is assumed that spider_db_append_select_columns() has already been called
+ // to build the bitmap of projection fields
+ bool is_ha_sole_projection_field;
+ uint loop_index, dbton_id;
+ spider_db_handler* dbton_hdl;
+ DBUG_ENTER( "ha_spider::is_sole_projection_field" );
- for ( loop_index = 0; loop_index < share->use_sql_dbton_count; loop_index++ )
- {
- dbton_id = share->use_sql_dbton_ids[ loop_index ];
- dbton_hdl = dbton_handler[ dbton_id ];
+ for ( loop_index = 0; loop_index < share->use_sql_dbton_count; loop_index++ )
+ {
+ dbton_id = share->use_sql_dbton_ids[ loop_index ];
+ dbton_hdl = dbton_handler[ dbton_id ];
- if ( dbton_hdl->first_link_idx >= 0 )
- {
- is_ha_sole_projection_field = dbton_hdl->is_sole_projection_field( field_index );
- if ( !is_ha_sole_projection_field )
- {
- DBUG_RETURN( FALSE );
- }
- }
+ if ( dbton_hdl->first_link_idx >= 0 )
+ {
+ is_ha_sole_projection_field = dbton_hdl->is_sole_projection_field( field_index );
+ if ( !is_ha_sole_projection_field )
+ {
+ DBUG_RETURN( FALSE );
+ }
}
+ }
- DBUG_RETURN( TRUE );
+ DBUG_RETURN( TRUE );
}
int ha_spider::check_ha_range_eof()
@@ -12253,6 +12871,7 @@ int ha_spider::drop_tmp_tables()
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -12288,6 +12907,7 @@ int ha_spider::drop_tmp_tables()
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -12407,6 +13027,7 @@ int ha_spider::close_opened_handler(
trx,
trx->thd,
share,
+ link_idx,
(uint32) share->monitoring_sid[link_idx],
share->table_name,
share->table_name_length,
@@ -12442,6 +13063,7 @@ int ha_spider::close_opened_handler(
trx,
trx->thd,
share,
+ link_idx,
(uint32) share->monitoring_sid[link_idx],
share->table_name,
share->table_name_length,
@@ -12483,6 +13105,7 @@ int ha_spider::close_opened_handler(
trx,
trx->thd,
share,
+ link_idx,
(uint32) share->monitoring_sid[link_idx],
share->table_name,
share->table_name_length,
@@ -12584,6 +13207,7 @@ int ha_spider::index_handler_init()
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -12690,6 +13314,7 @@ int ha_spider::rnd_handler_init()
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -12845,15 +13470,39 @@ int ha_spider::check_error_mode_eof(
void ha_spider::check_pre_call(
bool use_parallel
) {
+ THD* thd = ha_thd();
+ st_select_lex *select_lex = spider_get_select_lex(this);
+ int skip_parallel_search =
+ spider_param_skip_parallel_search(thd, share->skip_parallel_search);
DBUG_ENTER("ha_spider::check_pre_call");
DBUG_PRINT("info",("spider this=%p", this));
+ if (
+ (
+ (skip_parallel_search & 1) &&
+ thd->lex && thd->lex->sql_command != SQLCOM_SELECT // such like insert .. select ..
+ ) ||
+ (
+ (skip_parallel_search & 2) &&
+ select_lex && select_lex->sql_cache == SELECT_LEX::SQL_NO_CACHE // for mysqldump
+ )
+ ) {
+ use_pre_call = FALSE;
+ DBUG_VOID_RETURN;
+ }
+ if (
+ use_parallel &&
+ thd->query_id != partition_handler_share->parallel_search_query_id
+ ) {
+ partition_handler_share->parallel_search_query_id = thd->query_id;
+ ++trx->parallel_search_count;
+ }
use_pre_call = use_parallel;
if (!use_pre_call)
{
- st_select_lex *select_lex;
longlong select_limit;
longlong offset_limit;
- spider_get_select_limit(this, &select_lex, &select_limit, &offset_limit);
+ spider_get_select_limit_from_select_lex(
+ select_lex, &select_limit, &offset_limit);
if (
select_lex &&
(!select_lex->explicit_limit || !select_limit)
@@ -15083,7 +15732,7 @@ int ha_spider::print_item_type(
if (
dbton_hdl->first_link_idx >= 0 &&
(error_num = spider_db_print_item_type(item, this, str,
- alias, alias_length, dbton_id))
+ alias, alias_length, dbton_id, FALSE, NULL))
) {
DBUG_RETURN(error_num);
}
diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h
index 87c6afaa89f..b79e1b89fbf 100644
--- a/storage/spider/ha_spider.h
+++ b/storage/spider/ha_spider.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,16 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef USE_PRAGMA_INTERFACE
#pragma interface
#endif
-#if (defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000)
-#define SPIDER_HANDLER_START_BULK_INSERT_HAS_FLAGS
-#endif
-
#define SPIDER_CONNECT_INFO_MAX_LEN 64
#define SPIDER_CONNECT_INFO_PATH_MAX_LEN FN_REFLEN
#define SPIDER_LONGLONG_LEN 20
@@ -133,6 +129,14 @@ public:
bool da_status;
bool use_spatial_index;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ uint idx_for_direct_join;
+ bool use_fields;
+ spider_fields *fields;
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain;
+ SPIDER_LINK_IDX_CHAIN *result_link_idx_chain;
+#endif
+
/* for mrr */
bool mrr_with_cnt;
uint multi_range_cnt;
@@ -251,6 +255,11 @@ public:
/* for dbton */
spider_db_handler **dbton_handler;
+ /* for direct limit offset */
+ longlong direct_select_offset;
+ longlong direct_current_offset;
+ longlong direct_select_limit;
+
ha_spider();
ha_spider(
handlerton *hton,
@@ -564,19 +573,24 @@ public:
#endif
bool start_bulk_update();
int exec_bulk_update(
- uint *dup_key_found
+ ha_rows *dup_key_found
);
- void end_bulk_update();
+ int end_bulk_update();
int bulk_update_row(
const uchar *old_data,
const uchar *new_data,
- uint *dup_key_found
+ ha_rows *dup_key_found
);
int update_row(
const uchar *old_data,
const uchar *new_data
);
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
+ inline int direct_update_rows_init()
+ {
+ return direct_update_rows_init(2, NULL, 0, FALSE, NULL);
+ }
int direct_update_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
@@ -584,7 +598,15 @@ public:
bool sorted,
const uchar *new_data
);
+#else
+ int direct_update_rows_init();
+#endif
#ifdef HA_CAN_BULK_ACCESS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
+ inline int pre_direct_update_rows_init()
+ {
+ return pre_direct_update_rows_init(2, NULL, 0, FALSE, NULL);
+ }
int pre_direct_update_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
@@ -592,22 +614,45 @@ public:
bool sorted,
uchar *new_data
);
+#else
+ int pre_direct_update_rows_init();
#endif
+#endif
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
+ inline int direct_update_rows(ha_rows *update_rows)
+ {
+ return direct_update_rows(NULL, 0, FALSE, NULL, update_rows);
+ }
int direct_update_rows(
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
uchar *new_data,
- uint *update_rows
+ ha_rows *update_rows
+ );
+#else
+ int direct_update_rows(
+ ha_rows *update_rows
);
+#endif
#ifdef HA_CAN_BULK_ACCESS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
+ inline int pre_direct_update_rows()
+ {
+ ha_rows update_rows;
+
+ return pre_direct_update_rows(NULL, 0, FALSE, NULL, &update_rows);
+ }
int pre_direct_update_rows(
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
uchar *new_data,
- uint *update_rows
+ ha_rows *update_rows
);
+#else
+ int pre_direct_update_rows();
+#endif
#endif
#endif
bool start_bulk_delete();
@@ -616,33 +661,69 @@ public:
const uchar *buf
);
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
+ inline int direct_delete_rows_init()
+ {
+ return direct_delete_rows_init(2, NULL, 0, FALSE);
+ }
int direct_delete_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted
);
+#else
+ int direct_delete_rows_init();
+#endif
#ifdef HA_CAN_BULK_ACCESS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
+ inline int pre_direct_delete_rows_init()
+ {
+ return pre_direct_delete_rows_init(2, NULL, 0, FALSE);
+ }
int pre_direct_delete_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted
);
+#else
+ int pre_direct_delete_rows_init();
+#endif
#endif
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
+ inline int direct_delete_rows(ha_rows *delete_rows)
+ {
+ return direct_delete_rows(NULL, 0, FALSE, delete_rows);
+ }
int direct_delete_rows(
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
- uint *delete_rows
+ ha_rows *delete_rows
+ );
+#else
+ int direct_delete_rows(
+ ha_rows *delete_rows
);
+#endif
#ifdef HA_CAN_BULK_ACCESS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
+ inline int pre_direct_delete_rows()
+ {
+ ha_rows delete_rows;
+
+ return pre_direct_delete_rows(NULL, 0, FALSE, &delete_rows);
+ }
int pre_direct_delete_rows(
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
- uint *delete_rows
+ ha_rows *delete_rows
);
+#else
+ int pre_direct_delete_rows();
+#endif
#endif
#endif
int delete_all_rows();
@@ -752,7 +833,9 @@ public:
uint check_partitioned();
void check_direct_order_limit();
void check_distinct_key_query();
- bool is_sole_projection_field( uint16 field_index );
+ bool is_sole_projection_field(
+ uint16 field_index
+ );
int check_ha_range_eof();
int drop_tmp_tables();
bool handler_opened(
diff --git a/storage/spider/hs_client/allocator.hpp b/storage/spider/hs_client/allocator.hpp
index a29015e6886..c302e07804e 100644
--- a/storage/spider/hs_client/allocator.hpp
+++ b/storage/spider/hs_client/allocator.hpp
@@ -3,7 +3,7 @@
/*
* Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved.
- * Copyright (C) 2011 Kentoku SHIBA
+ * Copyright (C) 2011-2017 Kentoku SHIBA
* See COPYRIGHT.txt for details.
*/
@@ -31,11 +31,11 @@ extern "C" {
#if 1
#define DENA_ALLOCA_ALLOCATE(typ, len) \
- (typ *) alloca((len) * sizeof(typ))
+ (typ *) (alloca((len) * sizeof(typ)))
#define DENA_ALLOCA_FREE(x)
#else
#define DENA_ALLOCA_ALLOCATE(typ, len) \
- static_cast<typ *>(malloc((len) * sizeof(typ)))
+ (typ *) (malloc((len) * sizeof(typ)))
#define DENA_ALLOCA_FREE(x) free(x)
#endif
diff --git a/storage/spider/hs_client/config.cpp b/storage/spider/hs_client/config.cpp
index 3bf0f3e5bdf..97d479220e0 100644
--- a/storage/spider/hs_client/config.cpp
+++ b/storage/spider/hs_client/config.cpp
@@ -3,7 +3,7 @@
/*
* Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved.
- * Copyright (C) 2011 Kentoku SHIBA
+ * Copyright (C) 2011-2017 Kentoku SHIBA
* See COPYRIGHT.txt for details.
*/
@@ -264,7 +264,7 @@ parse_args(int argc, char **argv, config& conf)
if (!(param = new conf_param()))
continue;
uint32 key_len = (uint32)(eq - arg);
- uint32 val_len = (uint32)(strlen(eq + 1));
+ uint32 val_len = strlen(eq + 1);
if (
param->key.reserve(key_len + 1) ||
param->val.reserve(val_len + 1)
diff --git a/storage/spider/hs_client/escape.cpp b/storage/spider/hs_client/escape.cpp
index c3194e1d111..f3e60afc387 100644
--- a/storage/spider/hs_client/escape.cpp
+++ b/storage/spider/hs_client/escape.cpp
@@ -3,6 +3,7 @@
/*
* Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * Copyright (C) 2011-2017 Kentoku SHIBA
* See COPYRIGHT.txt for details.
*/
diff --git a/storage/spider/hs_client/fatal.cpp b/storage/spider/hs_client/fatal.cpp
index 260a2e75372..cfbc14df64a 100644
--- a/storage/spider/hs_client/fatal.cpp
+++ b/storage/spider/hs_client/fatal.cpp
@@ -3,7 +3,7 @@
/*
* Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved.
- * Copyright (C) 2011 Kentoku SHIBA
+ * Copyright (C) 2011-2017 Kentoku SHIBA
* See COPYRIGHT.txt for details.
*/
diff --git a/storage/spider/hs_client/fatal.hpp b/storage/spider/hs_client/fatal.hpp
index e1190ae49c1..38fc149e98e 100644
--- a/storage/spider/hs_client/fatal.hpp
+++ b/storage/spider/hs_client/fatal.hpp
@@ -3,7 +3,7 @@
/*
* Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved.
- * Copyright (C) 2011 Kentoku SHIBA
+ * Copyright (C) 2011-2017 Kentoku SHIBA
* See COPYRIGHT.txt for details.
*/
diff --git a/storage/spider/hs_client/hs_compat.h b/storage/spider/hs_client/hs_compat.h
index a26dd18e481..e832b2974da 100644
--- a/storage/spider/hs_client/hs_compat.h
+++ b/storage/spider/hs_client/hs_compat.h
@@ -11,12 +11,17 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef HS_COMPAT_H
#define HS_COMPAT_H
-#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100213
+#define SPD_INIT_DYNAMIC_ARRAY2(A, B, C, D, E, F) \
+ my_init_dynamic_array2(A, B, C, D, E, F)
+#define SPD_INIT_ALLOC_ROOT(A, B, C, D) \
+ init_alloc_root(A, "spider", B, C, D)
+#elif defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000
#define SPD_INIT_DYNAMIC_ARRAY2(A, B, C, D, E, F) \
my_init_dynamic_array2(A, B, C, D, E, F)
#define SPD_INIT_ALLOC_ROOT(A, B, C, D) \
diff --git a/storage/spider/hs_client/hstcpcli.cpp b/storage/spider/hs_client/hstcpcli.cpp
index 60da87b9f20..2cb37c7be9d 100644
--- a/storage/spider/hs_client/hstcpcli.cpp
+++ b/storage/spider/hs_client/hstcpcli.cpp
@@ -3,7 +3,7 @@
/*
* Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved.
- * Copyright (C) 2011 Kentoku SHIBA
+ * Copyright (C) 2011-2017 Kentoku SHIBA
* See COPYRIGHT.txt for details.
*/
diff --git a/storage/spider/hs_client/socket.cpp b/storage/spider/hs_client/socket.cpp
index 0717acf0da1..45b8100e64c 100644
--- a/storage/spider/hs_client/socket.cpp
+++ b/storage/spider/hs_client/socket.cpp
@@ -3,11 +3,12 @@
/*
* Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved.
- * Copyright (C) 2011 Kentoku SHIBA
+ * Copyright (C) 2011-2017 Kentoku SHIBA
* See COPYRIGHT.txt for details.
*/
#include <my_global.h>
+#include <my_config.h>
#ifndef __WIN__
#include <sys/types.h>
#include <sys/un.h>
@@ -223,7 +224,7 @@ socket_set_options(auto_file& fd, const socket_args& args, String& err_r)
int
socket_open(auto_file& fd, const socket_args& args, String& err_r)
{
- fd.reset((int)socket(args.family, args.socktype, args.protocol));
+ fd.reset((int) socket(args.family, args.socktype, args.protocol));
if (fd.get() < 0) {
return errno_string("socket", errno, err_r);
}
@@ -253,7 +254,7 @@ socket_connect(auto_file& fd, const socket_args& args, String& err_r)
int
socket_bind(auto_file& fd, const socket_args& args, String& err_r)
{
- fd.reset((int)socket(args.family, args.socktype, args.protocol));
+ fd.reset((int) socket(args.family, args.socktype, args.protocol));
if (fd.get() < 0) {
return errno_string("socket", errno, err_r);
}
@@ -300,8 +301,8 @@ int
socket_accept(int listen_fd, auto_file& fd, const socket_args& args,
sockaddr_storage& addr_r, socklen_t& addrlen_r, String& err_r)
{
- fd.reset((int)accept(listen_fd, reinterpret_cast<sockaddr *>(&addr_r),
- &addrlen_r));
+ fd.reset((int) accept(listen_fd, reinterpret_cast<sockaddr *>(&addr_r),
+ &addrlen_r));
if (fd.get() < 0) {
return errno_string("accept", errno, err_r);
}
diff --git a/storage/spider/hs_client/string_util.cpp b/storage/spider/hs_client/string_util.cpp
index 9cf2f04d5b6..39934148cb8 100644
--- a/storage/spider/hs_client/string_util.cpp
+++ b/storage/spider/hs_client/string_util.cpp
@@ -3,7 +3,7 @@
/*
* Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved.
- * Copyright (C) 2011 Kentoku SHIBA
+ * Copyright (C) 2011-2017 Kentoku SHIBA
* See COPYRIGHT.txt for details.
*/
diff --git a/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result b/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result
index 9a8660ba79e..ede48906a84 100644
--- a/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result
+++ b/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result
@@ -60,25 +60,25 @@ MAX(a)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 1
SELECT MIN(a) FROM ta_l;
MIN(a)
1
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 2
SELECT MAX(a) FROM ta_l WHERE a < 5;
MAX(a)
4
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 3
SELECT MIN(a) FROM ta_l WHERE a > 1;
MIN(a)
2
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 4
deinit
connection master_1;
diff --git a/storage/spider/mysql-test/spider/bg/r/direct_aggregate_part.result b/storage/spider/mysql-test/spider/bg/r/direct_aggregate_part.result
index 760b39e16d5..02cdc033a88 100644
--- a/storage/spider/mysql-test/spider/bg/r/direct_aggregate_part.result
+++ b/storage/spider/mysql-test/spider/bg/r/direct_aggregate_part.result
@@ -44,31 +44,31 @@ COUNT(*)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 2
SELECT MAX(a) FROM ta_l2;
MAX(a)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 4
SELECT MIN(a) FROM ta_l2;
MIN(a)
1
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 6
SELECT MAX(a) FROM ta_l2 WHERE a < 5;
MAX(a)
4
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 8
SELECT MIN(a) FROM ta_l2 WHERE a > 1;
MIN(a)
2
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 10
deinit
connection master_1;
diff --git a/storage/spider/mysql-test/spider/bg/r/direct_update.result b/storage/spider/mysql-test/spider/bg/r/direct_update.result
index 74dae7aec2e..0e536d48617 100644
--- a/storage/spider/mysql-test/spider/bg/r/direct_update.result
+++ b/storage/spider/mysql-test/spider/bg/r/direct_update.result
@@ -48,6 +48,7 @@ direct_updating test
connection master_1;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 0
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-01 10:21:39
@@ -59,6 +60,7 @@ update all rows with function
UPDATE ta_l SET c = ADDDATE(c, 1);
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 1
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -70,6 +72,7 @@ update by primary key
UPDATE ta_l SET b = 'x' WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 2
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -81,6 +84,7 @@ update by a column without index
UPDATE ta_l SET c = '2011-10-17' WHERE b = 'x';
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -92,6 +96,7 @@ update by primary key with order and limit
UPDATE ta_l SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 4
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -103,6 +108,7 @@ delete by primary key with order and limit
DELETE FROM ta_l WHERE a < 4 ORDER BY c LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 1
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -113,6 +119,7 @@ delete by a column without index
DELETE FROM ta_l WHERE b = 'c';
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 2
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -122,6 +129,7 @@ delete by primary key
DELETE FROM ta_l WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
diff --git a/storage/spider/mysql-test/spider/bg/r/direct_update_part.result b/storage/spider/mysql-test/spider/bg/r/direct_update_part.result
index 6db7c01f563..7069cd72fda 100644
--- a/storage/spider/mysql-test/spider/bg/r/direct_update_part.result
+++ b/storage/spider/mysql-test/spider/bg/r/direct_update_part.result
@@ -38,6 +38,7 @@ PRIMARY KEY(a)
) MASTER_1_ENGINE MASTER_1_COMMENT2_P_2_1
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 0
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-01 10:21:39
@@ -49,6 +50,7 @@ update all rows with function
UPDATE ta_l2 SET c = ADDDATE(c, 1);
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 2
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -60,6 +62,7 @@ update by primary key
UPDATE ta_l2 SET b = 'x' WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -71,6 +74,7 @@ update by a column without index
UPDATE ta_l2 SET c = '2011-10-17' WHERE b = 'x';
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 5
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -82,6 +86,7 @@ update by primary key with order and limit
UPDATE ta_l2 SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 6
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -93,6 +98,7 @@ delete by primary key with order and limit
DELETE FROM ta_l2 WHERE a < 4 ORDER BY c LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 1
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -103,6 +109,7 @@ delete by a column without index
DELETE FROM ta_l2 WHERE b = 'c';
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -112,6 +119,7 @@ delete by primary key
DELETE FROM ta_l2 WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 4
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
diff --git a/storage/spider/mysql-test/spider/bg/r/spider_fixes.result b/storage/spider/mysql-test/spider/bg/r/spider_fixes.result
index f50c9822534..1db31ca9f95 100644
--- a/storage/spider/mysql-test/spider/bg/r/spider_fixes.result
+++ b/storage/spider/mysql-test/spider/bg/r/spider_fixes.result
@@ -461,6 +461,7 @@ Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
DELETE FROM t1;
Warnings:
Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
+Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
TRUNCATE t1;
Warnings:
diff --git a/storage/spider/mysql-test/spider/handler/r/direct_update.result b/storage/spider/mysql-test/spider/handler/r/direct_update.result
index 74dae7aec2e..0e536d48617 100644
--- a/storage/spider/mysql-test/spider/handler/r/direct_update.result
+++ b/storage/spider/mysql-test/spider/handler/r/direct_update.result
@@ -48,6 +48,7 @@ direct_updating test
connection master_1;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 0
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-01 10:21:39
@@ -59,6 +60,7 @@ update all rows with function
UPDATE ta_l SET c = ADDDATE(c, 1);
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 1
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -70,6 +72,7 @@ update by primary key
UPDATE ta_l SET b = 'x' WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 2
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -81,6 +84,7 @@ update by a column without index
UPDATE ta_l SET c = '2011-10-17' WHERE b = 'x';
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -92,6 +96,7 @@ update by primary key with order and limit
UPDATE ta_l SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 4
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -103,6 +108,7 @@ delete by primary key with order and limit
DELETE FROM ta_l WHERE a < 4 ORDER BY c LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 1
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -113,6 +119,7 @@ delete by a column without index
DELETE FROM ta_l WHERE b = 'c';
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 2
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -122,6 +129,7 @@ delete by primary key
DELETE FROM ta_l WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
diff --git a/storage/spider/mysql-test/spider/handler/r/direct_update_part.result b/storage/spider/mysql-test/spider/handler/r/direct_update_part.result
index 6db7c01f563..7069cd72fda 100644
--- a/storage/spider/mysql-test/spider/handler/r/direct_update_part.result
+++ b/storage/spider/mysql-test/spider/handler/r/direct_update_part.result
@@ -38,6 +38,7 @@ PRIMARY KEY(a)
) MASTER_1_ENGINE MASTER_1_COMMENT2_P_2_1
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 0
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-01 10:21:39
@@ -49,6 +50,7 @@ update all rows with function
UPDATE ta_l2 SET c = ADDDATE(c, 1);
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 2
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -60,6 +62,7 @@ update by primary key
UPDATE ta_l2 SET b = 'x' WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -71,6 +74,7 @@ update by a column without index
UPDATE ta_l2 SET c = '2011-10-17' WHERE b = 'x';
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 5
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -82,6 +86,7 @@ update by primary key with order and limit
UPDATE ta_l2 SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 6
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -93,6 +98,7 @@ delete by primary key with order and limit
DELETE FROM ta_l2 WHERE a < 4 ORDER BY c LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 1
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -103,6 +109,7 @@ delete by a column without index
DELETE FROM ta_l2 WHERE b = 'c';
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -112,6 +119,7 @@ delete by primary key
DELETE FROM ta_l2 WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 4
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
diff --git a/storage/spider/mysql-test/spider/handler/r/spider_fixes.result b/storage/spider/mysql-test/spider/handler/r/spider_fixes.result
index 9b14817eee4..c171167a1b7 100644
--- a/storage/spider/mysql-test/spider/handler/r/spider_fixes.result
+++ b/storage/spider/mysql-test/spider/handler/r/spider_fixes.result
@@ -465,6 +465,7 @@ Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
DELETE FROM t1;
Warnings:
Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
+Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
TRUNCATE t1;
Warnings:
diff --git a/storage/spider/mysql-test/spider/handler/suite.pm b/storage/spider/mysql-test/spider/handler/suite.pm
index f106147deb6..b023e5206ef 100644
--- a/storage/spider/mysql-test/spider/handler/suite.pm
+++ b/storage/spider/mysql-test/spider/handler/suite.pm
@@ -9,4 +9,3 @@ return "Test needs --big-test" unless $::opt_big_test;
sub is_default { 1 }
bless { };
-
diff --git a/storage/spider/mysql-test/spider/include/deinit_spider.inc b/storage/spider/mysql-test/spider/include/deinit_spider.inc
index c9c414eb56e..3609551e169 100644
--- a/storage/spider/mysql-test/spider/include/deinit_spider.inc
+++ b/storage/spider/mysql-test/spider/include/deinit_spider.inc
@@ -6,9 +6,13 @@ DROP FUNCTION spider_flush_table_mon_cache;
UNINSTALL PLUGIN spider;
DROP TABLE IF EXISTS mysql.spider_xa;
DROP TABLE IF EXISTS mysql.spider_xa_member;
+DROP TABLE IF EXISTS mysql.spider_xa_failed_log;
DROP TABLE IF EXISTS mysql.spider_tables;
DROP TABLE IF EXISTS mysql.spider_link_mon_servers;
DROP TABLE IF EXISTS mysql.spider_link_failed_log;
+DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery;
+DROP TABLE IF EXISTS mysql.spider_table_sts;
+DROP TABLE IF EXISTS mysql.spider_table_crd;
DROP SERVER s_2_1;
DROP SERVER s_2_2;
DROP SERVER s_2_3;
diff --git a/storage/spider/mysql-test/spider/include/direct_join_deinit.inc b/storage/spider/mysql-test/spider/include/direct_join_deinit.inc
new file mode 100644
index 00000000000..53bc29a0016
--- /dev/null
+++ b/storage/spider/mysql-test/spider/include/direct_join_deinit.inc
@@ -0,0 +1,9 @@
+--let $OUTPUT_CHILD_GROUP2= $OUTPUT_CHILD_GROUP2_BACKUP
+--let $USE_GENERAL_LOG= $USE_GENERAL_LOG_BACKUP
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
diff --git a/storage/spider/mysql-test/spider/include/direct_join_init.inc b/storage/spider/mysql-test/spider/include/direct_join_init.inc
new file mode 100644
index 00000000000..7e4947bf078
--- /dev/null
+++ b/storage/spider/mysql-test/spider/include/direct_join_init.inc
@@ -0,0 +1,13 @@
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_init.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
+let $CHILD2_1_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2
+--let $OUTPUT_CHILD_GROUP2= 1
+--let $USE_GENERAL_LOG_BACKUP= $USE_GENERAL_LOG
+--let $USE_GENERAL_LOG= 1
diff --git a/storage/spider/mysql-test/spider/include/init_spider.inc b/storage/spider/mysql-test/spider/include/init_spider.inc
index 90c4b7d7084..f94bd51edd7 100644
--- a/storage/spider/mysql-test/spider/include/init_spider.inc
+++ b/storage/spider/mysql-test/spider/include/init_spider.inc
@@ -277,10 +277,35 @@ if (`SELECT IF($PLUGIN_VERSION = 3, 1, 0)`)
default_group char(64) default null,
KEY idx1 (data, format_id, gtrid_length, host)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+ DROP TABLE IF EXISTS mysql.spider_xa_failed_log;
+ CREATE TABLE mysql.spider_xa_failed_log(
+ format_id int not null default 0,
+ gtrid_length int not null default 0,
+ bqual_length int not null default 0,
+ data char(128) charset binary not null default '',
+ scheme char(64) not null default '',
+ host char(64) not null default '',
+ port char(5) not null default '',
+ socket text not null,
+ username char(64) not null default '',
+ password char(64) not null default '',
+ ssl_ca text,
+ ssl_capath text,
+ ssl_cert text,
+ ssl_cipher char(64) default null,
+ ssl_key text,
+ ssl_verify_server_cert tinyint not null default 0,
+ default_file text,
+ default_group char(64) default null,
+ thread_id int default null,
+ status char(8) not null default '',
+ failed_time timestamp not null default current_timestamp,
+ key idx1 (data, format_id, gtrid_length, host)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS mysql.spider_tables;
CREATE TABLE mysql.spider_tables(
db_name char(64) not null default '',
- table_name char(64) not null default '',
+ table_name char(199) not null default '',
link_id int not null default 0,
priority bigint not null default 0,
server char(64) default null,
@@ -296,18 +321,22 @@ if (`SELECT IF($PLUGIN_VERSION = 3, 1, 0)`)
ssl_cipher char(64) default null,
ssl_key text default null,
ssl_verify_server_cert tinyint not null default 0,
+ monitoring_binlog_pos_at_failing tinyint not null default 0,
default_file text default null,
default_group char(64) default null,
tgt_db_name char(64) default null,
tgt_table_name char(64) default null,
link_status tinyint not null default 1,
+ block_status tinyint not null default 0,
+ static_link_id char(64) default null,
PRIMARY KEY (db_name, table_name, link_id),
- KEY idx1 (priority)
+ KEY idx1 (priority),
+ UNIQUE KEY uidx1 (db_name, table_name, static_link_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS mysql.spider_link_mon_servers;
CREATE TABLE mysql.spider_link_mon_servers(
db_name char(64) not null default '',
- table_name char(64) not null default '',
+ table_name char(199) not null default '',
link_id char(5) not null default '',
sid int not null default 0,
server char(64) default null,
@@ -330,10 +359,43 @@ if (`SELECT IF($PLUGIN_VERSION = 3, 1, 0)`)
DROP TABLE IF EXISTS mysql.spider_link_failed_log;
CREATE TABLE mysql.spider_link_failed_log(
db_name char(64) not null default '',
- table_name char(64) not null default '',
+ table_name char(199) not null default '',
link_id int not null default 0,
failed_time timestamp not null default current_timestamp
) ENGINE=MYISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+ DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery;
+ CREATE TABLE mysql.spider_table_position_for_recovery(
+ db_name char(64) not null default '',
+ table_name char(199) not null default '',
+ failed_link_id int not null default 0,
+ source_link_id int not null default 0,
+ file text,
+ position text,
+ gtid text,
+ primary key (db_name, table_name, failed_link_id, source_link_id)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+ DROP TABLE IF EXISTS mysql.spider_table_sts;
+ CREATE TABLE mysql.spider_table_sts(
+ db_name char(64) not null default '',
+ table_name char(199) not null default '',
+ data_file_length bigint unsigned not null default 0,
+ max_data_file_length bigint unsigned not null default 0,
+ index_file_length bigint unsigned not null default 0,
+ records bigint unsigned not null default 0,
+ mean_rec_length bigint unsigned not null default 0,
+ check_time datetime not null default '0000-00-00 00:00:00',
+ create_time datetime not null default '0000-00-00 00:00:00',
+ update_time datetime not null default '0000-00-00 00:00:00',
+ primary key (db_name, table_name)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+ DROP TABLE IF EXISTS mysql.spider_table_crd;
+ CREATE TABLE mysql.spider_table_crd(
+ db_name char(64) not null default '',
+ table_name char(199) not null default '',
+ key_seq int unsigned not null default 0,
+ cardinality bigint not null default 0,
+ primary key (db_name, table_name, key_seq)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
}
SET spider_internal_sql_log_off= 0;
diff --git a/storage/spider/mysql-test/spider/include/partition_cond_push_deinit.inc b/storage/spider/mysql-test/spider/include/partition_cond_push_deinit.inc
new file mode 100644
index 00000000000..668eaa2fdba
--- /dev/null
+++ b/storage/spider/mysql-test/spider/include/partition_cond_push_deinit.inc
@@ -0,0 +1,20 @@
+--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP
+--let $MASTER_1_COMMENT_2_2= $MASTER_1_COMMENT_2_2_BACKUP
+--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
+--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
+--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
+--let $CHILD2_2_DROP_TABLES= $CHILD2_2_DROP_TABLES_BACKUP
+--let $CHILD2_2_CREATE_TABLES= $CHILD2_2_CREATE_TABLES_BACKUP
+--let $CHILD2_2_SELECT_TABLES= $CHILD2_2_SELECT_TABLES_BACKUP
+--let $CHILD2_3_DROP_TABLES= $CHILD2_3_DROP_TABLES_BACKUP
+--let $CHILD2_3_CREATE_TABLES= $CHILD2_3_CREATE_TABLES_BACKUP
+--let $CHILD2_3_SELECT_TABLES= $CHILD2_3_SELECT_TABLES_BACKUP
+--let $OUTPUT_CHILD_GROUP2= $OUTPUT_CHILD_GROUP2_BACKUP
+--let $USE_GENERAL_LOG= $USE_GENERAL_LOG_BACKUP
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
diff --git a/storage/spider/mysql-test/spider/include/partition_cond_push_init.inc b/storage/spider/mysql-test/spider/include/partition_cond_push_init.inc
new file mode 100644
index 00000000000..30a333d6699
--- /dev/null
+++ b/storage/spider/mysql-test/spider/include/partition_cond_push_init.inc
@@ -0,0 +1,58 @@
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_init.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
+--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1
+let $MASTER_1_COMMENT_2_1=
+ COMMENT='table "tbl_a"'
+ PARTITION BY KEY(value) (
+ PARTITION pt1 COMMENT='srv "s_2_1"',
+ PARTITION pt2 COMMENT='srv "s_2_2"',
+ PARTITION pt3 COMMENT='srv "s_2_3"'
+ );
+--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
+let $CHILD2_1_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
+let $CHILD2_1_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ value int NOT NULL
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
+let $CHILD2_1_SELECT_TABLES=
+ SELECT value FROM tbl_a ORDER BY value;
+let $CHILD2_1_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $CHILD2_2_DROP_TABLES_BACKUP= $CHILD2_2_DROP_TABLES
+let $CHILD2_2_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_2_CREATE_TABLES_BACKUP= $CHILD2_2_CREATE_TABLES
+let $CHILD2_2_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ value int NOT NULL
+ ) $CHILD2_2_ENGINE $CHILD2_2_CHARSET;
+--let $CHILD2_2_SELECT_TABLES_BACKUP= $CHILD2_2_SELECT_TABLES
+let $CHILD2_2_SELECT_TABLES=
+ SELECT value FROM tbl_a ORDER BY value;
+let $CHILD2_2_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $CHILD2_3_DROP_TABLES_BACKUP= $CHILD2_3_DROP_TABLES
+let $CHILD2_3_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_3_CREATE_TABLES_BACKUP= $CHILD2_3_CREATE_TABLES
+let $CHILD2_3_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ value int NOT NULL
+ ) $CHILD2_3_ENGINE $CHILD2_3_CHARSET;
+--let $CHILD2_3_SELECT_TABLES_BACKUP= $CHILD2_3_SELECT_TABLES
+let $CHILD2_3_SELECT_TABLES=
+ SELECT value FROM tbl_a ORDER BY value;
+let $CHILD2_3_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2
+--let $OUTPUT_CHILD_GROUP2= 1
+--let $USE_GENERAL_LOG_BACKUP= $USE_GENERAL_LOG
+--let $USE_GENERAL_LOG= 1
diff --git a/storage/spider/mysql-test/spider/include/partition_fulltext_deinit.inc b/storage/spider/mysql-test/spider/include/partition_fulltext_deinit.inc
new file mode 100644
index 00000000000..c0c652d14f5
--- /dev/null
+++ b/storage/spider/mysql-test/spider/include/partition_fulltext_deinit.inc
@@ -0,0 +1,23 @@
+--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP
+--let $MASTER_1_COMMENT_2_2= $MASTER_1_COMMENT_2_2_BACKUP
+--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
+--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
+--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
+--let $CHILD2_2_DROP_TABLES= $CHILD2_2_DROP_TABLES_BACKUP
+--let $CHILD2_2_CREATE_TABLES= $CHILD2_2_CREATE_TABLES_BACKUP
+--let $CHILD2_2_SELECT_TABLES= $CHILD2_2_SELECT_TABLES_BACKUP
+--let $CHILD2_3_DROP_TABLES= $CHILD2_3_DROP_TABLES_BACKUP
+--let $CHILD2_3_CREATE_TABLES= $CHILD2_3_CREATE_TABLES_BACKUP
+--let $CHILD2_3_SELECT_TABLES= $CHILD2_3_SELECT_TABLES_BACKUP
+--let $OUTPUT_CHILD_GROUP2= $OUTPUT_CHILD_GROUP2_BACKUP
+--let $USE_GENERAL_LOG= $USE_GENERAL_LOG_BACKUP
+--connection master_1
+set session join_cache_level= @old_join_cache_level;
+set session optimizer_switch= @old_optimizer_switch;
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
diff --git a/storage/spider/mysql-test/spider/include/partition_fulltext_init.inc b/storage/spider/mysql-test/spider/include/partition_fulltext_init.inc
new file mode 100644
index 00000000000..754395493af
--- /dev/null
+++ b/storage/spider/mysql-test/spider/include/partition_fulltext_init.inc
@@ -0,0 +1,72 @@
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_init.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
+--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1
+let $MASTER_1_COMMENT_2_1=
+ COMMENT='table "tbl_a", bka_mode "1"'
+ PARTITION BY KEY(pkey) (
+ PARTITION pt1 COMMENT='srv "s_2_1"',
+ PARTITION pt2 COMMENT='srv "s_2_2"',
+ PARTITION pt3 COMMENT='srv "s_2_3"'
+ );
+--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
+let $CHILD2_1_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
+let $CHILD2_1_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ words text NOT NULL,
+ PRIMARY KEY (pkey),
+ FULLTEXT (words)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
+let $CHILD2_1_SELECT_TABLES=
+ SELECT pkey FROM tbl_a ORDER BY pkey;
+let $CHILD2_1_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $CHILD2_2_DROP_TABLES_BACKUP= $CHILD2_2_DROP_TABLES
+let $CHILD2_2_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_2_CREATE_TABLES_BACKUP= $CHILD2_2_CREATE_TABLES
+let $CHILD2_2_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ words text NOT NULL,
+ PRIMARY KEY (pkey),
+ FULLTEXT (words)
+ ) $CHILD2_2_ENGINE $CHILD2_2_CHARSET;
+--let $CHILD2_2_SELECT_TABLES_BACKUP= $CHILD2_2_SELECT_TABLES
+let $CHILD2_2_SELECT_TABLES=
+ SELECT pkey FROM tbl_a ORDER BY pkey;
+let $CHILD2_2_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $CHILD2_3_DROP_TABLES_BACKUP= $CHILD2_3_DROP_TABLES
+let $CHILD2_3_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_3_CREATE_TABLES_BACKUP= $CHILD2_3_CREATE_TABLES
+let $CHILD2_3_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ words text NOT NULL,
+ PRIMARY KEY (pkey),
+ FULLTEXT (words)
+ ) $CHILD2_3_ENGINE $CHILD2_3_CHARSET;
+--let $CHILD2_3_SELECT_TABLES_BACKUP= $CHILD2_3_SELECT_TABLES
+let $CHILD2_3_SELECT_TABLES=
+ SELECT pkey FROM tbl_a ORDER BY pkey;
+let $CHILD2_3_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2
+--let $OUTPUT_CHILD_GROUP2= 1
+--let $USE_GENERAL_LOG_BACKUP= $USE_GENERAL_LOG
+--let $USE_GENERAL_LOG= 1
+--connection master_1
+set @old_join_cache_level= @@join_cache_level;
+set session join_cache_level= 5;
+set @old_optimizer_switch= @@optimizer_switch;
+set session optimizer_switch= 'mrr=on';
diff --git a/storage/spider/mysql-test/spider/include/partition_join_pushdown_for_single_partition_deinit.inc b/storage/spider/mysql-test/spider/include/partition_join_pushdown_for_single_partition_deinit.inc
new file mode 100644
index 00000000000..d9dfcf23ed6
--- /dev/null
+++ b/storage/spider/mysql-test/spider/include/partition_join_pushdown_for_single_partition_deinit.inc
@@ -0,0 +1,30 @@
+--connection master_1
+--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP
+--let $MASTER_1_COMMENT_2_2= $MASTER_1_COMMENT_2_2_BACKUP
+--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
+--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
+--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
+--let $CHILD2_1_DROP_TABLES2= $CHILD2_1_DROP_TABLES2_BACKUP
+--let $CHILD2_1_CREATE_TABLES2= $CHILD2_1_CREATE_TABLES2_BACKUP
+--let $CHILD2_1_SELECT_TABLES2= $CHILD2_1_SELECT_TABLES2_BACKUP
+--let $CHILD2_2_DROP_TABLES= $CHILD2_2_DROP_TABLES_BACKUP
+--let $CHILD2_2_CREATE_TABLES= $CHILD2_2_CREATE_TABLES_BACKUP
+--let $CHILD2_2_SELECT_TABLES= $CHILD2_2_SELECT_TABLES_BACKUP
+--let $CHILD2_2_DROP_TABLES2= $CHILD2_2_DROP_TABLES2_BACKUP
+--let $CHILD2_2_CREATE_TABLES2= $CHILD2_2_CREATE_TABLES2_BACKUP
+--let $CHILD2_2_SELECT_TABLES2= $CHILD2_2_SELECT_TABLES2_BACKUP
+--let $CHILD2_3_DROP_TABLES= $CHILD2_3_DROP_TABLES_BACKUP
+--let $CHILD2_3_CREATE_TABLES= $CHILD2_3_CREATE_TABLES_BACKUP
+--let $CHILD2_3_SELECT_TABLES= $CHILD2_3_SELECT_TABLES_BACKUP
+--let $CHILD2_3_DROP_TABLES2= $CHILD2_3_DROP_TABLES2_BACKUP
+--let $CHILD2_3_CREATE_TABLES2= $CHILD2_3_CREATE_TABLES2_BACKUP
+--let $CHILD2_3_SELECT_TABLES2= $CHILD2_3_SELECT_TABLES2_BACKUP
+--let $OUTPUT_CHILD_GROUP2= $OUTPUT_CHILD_GROUP2_BACKUP
+--let $USE_GENERAL_LOG= $USE_GENERAL_LOG_BACKUP
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
diff --git a/storage/spider/mysql-test/spider/include/partition_join_pushdown_for_single_partition_init.inc b/storage/spider/mysql-test/spider/include/partition_join_pushdown_for_single_partition_init.inc
new file mode 100644
index 00000000000..dccffa60c0d
--- /dev/null
+++ b/storage/spider/mysql-test/spider/include/partition_join_pushdown_for_single_partition_init.inc
@@ -0,0 +1,105 @@
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_init.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
+--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1
+let $MASTER_1_COMMENT_2_1=
+ COMMENT='table "tbl_a"'
+ PARTITION BY RANGE(value) (
+ PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1"',
+ PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_2"',
+ PARTITION pt3 VALUES LESS THAN (15) COMMENT='srv "s_2_3"'
+ );
+--let $MASTER_1_COMMENT_2_2_BACKUP= $MASTER_1_COMMENT_2_2
+let $MASTER_1_COMMENT_2_2=
+ COMMENT='table "tbl_b"'
+ PARTITION BY RANGE(value2) (
+ PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1"',
+ PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_2"',
+ PARTITION pt3 VALUES LESS THAN (15) COMMENT='srv "s_2_3"'
+ );
+--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
+let $CHILD2_1_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
+let $CHILD2_1_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ value int NOT NULL,
+ PRIMARY KEY(value)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
+let $CHILD2_1_SELECT_TABLES=
+ SELECT value FROM tbl_a ORDER BY value;
+--let $CHILD2_1_DROP_TABLES2_BACKUP= $CHILD2_1_DROP_TABLES2
+let $CHILD2_1_DROP_TABLES2=
+ DROP TABLE IF EXISTS tbl_b;
+--let $CHILD2_1_CREATE_TABLES2_BACKUP= $CHILD2_1_CREATE_TABLES2
+let $CHILD2_1_CREATE_TABLES2=
+ CREATE TABLE tbl_b (
+ value2 int NOT NULL,
+ PRIMARY KEY(value2)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+--let $CHILD2_1_SELECT_TABLES2_BACKUP= $CHILD2_1_SELECT_TABLES2
+let $CHILD2_1_SELECT_TABLES2=
+ SELECT value FROM tbl_b ORDER BY value2;
+let $CHILD2_1_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $CHILD2_2_DROP_TABLES_BACKUP= $CHILD2_2_DROP_TABLES
+let $CHILD2_2_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_2_CREATE_TABLES_BACKUP= $CHILD2_2_CREATE_TABLES
+let $CHILD2_2_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ value int NOT NULL,
+ PRIMARY KEY(value)
+ ) $CHILD2_2_ENGINE $CHILD2_2_CHARSET;
+--let $CHILD2_2_SELECT_TABLES_BACKUP= $CHILD2_2_SELECT_TABLES
+let $CHILD2_2_SELECT_TABLES=
+ SELECT value FROM tbl_a ORDER BY value;
+--let $CHILD2_2_DROP_TABLES2_BACKUP= $CHILD2_2_DROP_TABLES2
+let $CHILD2_2_DROP_TABLES2=
+ DROP TABLE IF EXISTS tbl_b;
+--let $CHILD2_2_CREATE_TABLES2_BACKUP= $CHILD2_2_CREATE_TABLES2
+let $CHILD2_2_CREATE_TABLES2=
+ CREATE TABLE tbl_b (
+ value2 int NOT NULL,
+ PRIMARY KEY(value2)
+ ) $CHILD2_2_ENGINE $CHILD2_2_CHARSET;
+--let $CHILD2_2_SELECT_TABLES2_BACKUP= $CHILD2_2_SELECT_TABLES2
+let $CHILD2_2_SELECT_TABLES2=
+ SELECT value FROM tbl_b ORDER BY value;
+let $CHILD2_2_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $CHILD2_3_DROP_TABLES_BACKUP= $CHILD2_3_DROP_TABLES
+let $CHILD2_3_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_3_CREATE_TABLES_BACKUP= $CHILD2_3_CREATE_TABLES
+let $CHILD2_3_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ value int NOT NULL,
+ PRIMARY KEY(value)
+ ) $CHILD2_3_ENGINE $CHILD2_3_CHARSET;
+--let $CHILD2_3_SELECT_TABLES_BACKUP= $CHILD2_3_SELECT_TABLES
+let $CHILD2_3_SELECT_TABLES=
+ SELECT value FROM tbl_a ORDER BY value;
+--let $CHILD2_3_DROP_TABLES2_BACKUP= $CHILD2_3_DROP_TABLES2
+let $CHILD2_3_DROP_TABLES2=
+ DROP TABLE IF EXISTS tbl_b;
+--let $CHILD2_3_CREATE_TABLES2_BACKUP= $CHILD2_3_CREATE_TABLES2
+let $CHILD2_3_CREATE_TABLES2=
+ CREATE TABLE tbl_b (
+ value2 int NOT NULL,
+ PRIMARY KEY(value2)
+ ) $CHILD2_3_ENGINE $CHILD2_3_CHARSET;
+--let $CHILD2_3_SELECT_TABLES2_BACKUP= $CHILD2_3_SELECT_TABLES2
+let $CHILD2_3_SELECT_TABLES2=
+ SELECT value FROM tbl_b ORDER BY value;
+let $CHILD2_3_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2
+--let $OUTPUT_CHILD_GROUP2= 1
+--let $USE_GENERAL_LOG_BACKUP= $USE_GENERAL_LOG
+--let $USE_GENERAL_LOG= 1
diff --git a/storage/spider/mysql-test/spider/include/partition_mrr_deinit.inc b/storage/spider/mysql-test/spider/include/partition_mrr_deinit.inc
new file mode 100644
index 00000000000..c0c652d14f5
--- /dev/null
+++ b/storage/spider/mysql-test/spider/include/partition_mrr_deinit.inc
@@ -0,0 +1,23 @@
+--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP
+--let $MASTER_1_COMMENT_2_2= $MASTER_1_COMMENT_2_2_BACKUP
+--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
+--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
+--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
+--let $CHILD2_2_DROP_TABLES= $CHILD2_2_DROP_TABLES_BACKUP
+--let $CHILD2_2_CREATE_TABLES= $CHILD2_2_CREATE_TABLES_BACKUP
+--let $CHILD2_2_SELECT_TABLES= $CHILD2_2_SELECT_TABLES_BACKUP
+--let $CHILD2_3_DROP_TABLES= $CHILD2_3_DROP_TABLES_BACKUP
+--let $CHILD2_3_CREATE_TABLES= $CHILD2_3_CREATE_TABLES_BACKUP
+--let $CHILD2_3_SELECT_TABLES= $CHILD2_3_SELECT_TABLES_BACKUP
+--let $OUTPUT_CHILD_GROUP2= $OUTPUT_CHILD_GROUP2_BACKUP
+--let $USE_GENERAL_LOG= $USE_GENERAL_LOG_BACKUP
+--connection master_1
+set session join_cache_level= @old_join_cache_level;
+set session optimizer_switch= @old_optimizer_switch;
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
diff --git a/storage/spider/mysql-test/spider/include/partition_mrr_init.inc b/storage/spider/mysql-test/spider/include/partition_mrr_init.inc
new file mode 100644
index 00000000000..03e113940a7
--- /dev/null
+++ b/storage/spider/mysql-test/spider/include/partition_mrr_init.inc
@@ -0,0 +1,92 @@
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_init.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
+--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1
+let $MASTER_1_COMMENT_2_1=
+ COMMENT='table "tbl_a", bka_mode "1"'
+ PARTITION BY KEY(pkey) (
+ PARTITION pt1 COMMENT='srv "s_2_1"',
+ PARTITION pt2 COMMENT='srv "s_2_2"',
+ PARTITION pt3 COMMENT='srv "s_2_3"'
+ );
+--let $MASTER_1_COMMENT_2_2_BACKUP= $MASTER_1_COMMENT_2_2
+let $MASTER_1_COMMENT_2_2=
+ COMMENT='table "tbl_b", bka_mode "1"'
+ PARTITION BY KEY(pkey) (
+ PARTITION pt1 COMMENT='srv "s_2_2"',
+ PARTITION pt2 COMMENT='srv "s_2_3"',
+ PARTITION pt3 COMMENT='srv "s_2_1"'
+ );
+--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
+let $CHILD2_1_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a $STR_SEMICOLON
+ DROP TABLE IF EXISTS tbl_b;
+--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
+let $CHILD2_1_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON
+ CREATE TABLE tbl_b (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
+let $CHILD2_1_SELECT_TABLES=
+ SELECT pkey FROM tbl_a ORDER BY pkey $STR_SEMICOLON
+ SELECT pkey FROM tbl_b ORDER BY pkey;
+let $CHILD2_1_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $CHILD2_2_DROP_TABLES_BACKUP= $CHILD2_2_DROP_TABLES
+let $CHILD2_2_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a $STR_SEMICOLON
+ DROP TABLE IF EXISTS tbl_b;
+--let $CHILD2_2_CREATE_TABLES_BACKUP= $CHILD2_2_CREATE_TABLES
+let $CHILD2_2_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+ ) $CHILD2_2_ENGINE $CHILD2_2_CHARSET $STR_SEMICOLON
+ CREATE TABLE tbl_b (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+ ) $CHILD2_2_ENGINE $CHILD2_2_CHARSET;
+--let $CHILD2_2_SELECT_TABLES_BACKUP= $CHILD2_2_SELECT_TABLES
+let $CHILD2_2_SELECT_TABLES=
+ SELECT pkey FROM tbl_a ORDER BY pkey $STR_SEMICOLON
+ SELECT pkey FROM tbl_b ORDER BY pkey;
+let $CHILD2_2_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $CHILD2_3_DROP_TABLES_BACKUP= $CHILD2_3_DROP_TABLES
+let $CHILD2_3_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a $STR_SEMICOLON
+ DROP TABLE IF EXISTS tbl_b;
+--let $CHILD2_3_CREATE_TABLES_BACKUP= $CHILD2_3_CREATE_TABLES
+let $CHILD2_3_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+ ) $CHILD2_3_ENGINE $CHILD2_3_CHARSET $STR_SEMICOLON
+ CREATE TABLE tbl_b (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+ ) $CHILD2_3_ENGINE $CHILD2_3_CHARSET;
+--let $CHILD2_3_SELECT_TABLES_BACKUP= $CHILD2_3_SELECT_TABLES
+let $CHILD2_3_SELECT_TABLES=
+ SELECT pkey FROM tbl_a ORDER BY pkey $STR_SEMICOLON
+ SELECT pkey FROM tbl_b ORDER BY pkey;
+let $CHILD2_3_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2
+--let $OUTPUT_CHILD_GROUP2= 1
+--let $USE_GENERAL_LOG_BACKUP= $USE_GENERAL_LOG
+--let $USE_GENERAL_LOG= 1
+--connection master_1
+set @old_join_cache_level= @@join_cache_level;
+set session join_cache_level= 5;
+set @old_optimizer_switch= @@optimizer_switch;
+set session optimizer_switch= 'mrr=on';
diff --git a/storage/spider/mysql-test/spider/r/auto_increment.result b/storage/spider/mysql-test/spider/r/auto_increment.result
new file mode 100644
index 00000000000..cbc7fee0671
--- /dev/null
+++ b/storage/spider/mysql-test/spider/r/auto_increment.result
@@ -0,0 +1,186 @@
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+drop and create databases
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+connection child2_1;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+
+test select 1
+connection master_1;
+SELECT 1;
+1
+1
+connection child2_1;
+SELECT 1;
+1
+1
+
+create table select test
+connection child2_1;
+CHILD2_1_DROP_TABLES
+CHILD2_1_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+DROP TABLE IF EXISTS tbl_a;
+CREATE TABLE tbl_a (
+col_a INT NOT NULL AUTO_INCREMENT,
+col_b VARCHAR(20) DEFAULT 'defg',
+col_c INT NOT NULL DEFAULT 100,
+PRIMARY KEY(col_a)
+) MASTER_1_ENGINE MASTER_1_AUTO_INCREMENT_2_1 MASTER_1_COMMENT_2_1
+SHOW CREATE TABLE tbl_a;
+Table Create Table
+tbl_a CREATE TABLE `tbl_a` (
+ `col_a` int(11) NOT NULL AUTO_INCREMENT,
+ `col_b` varchar(20) DEFAULT 'defg',
+ `col_c` int(11) NOT NULL DEFAULT 100,
+ PRIMARY KEY (`col_a`)
+) ENGINE=SPIDER AUTO_INCREMENT=20 DEFAULT CHARSET=latin1 COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"'
+INSERT INTO tbl_a () VALUES ();
+INSERT INTO tbl_a () VALUES ();
+SHOW CREATE TABLE tbl_a;
+Table Create Table
+tbl_a CREATE TABLE `tbl_a` (
+ `col_a` int(11) NOT NULL AUTO_INCREMENT,
+ `col_b` varchar(20) DEFAULT 'defg',
+ `col_c` int(11) NOT NULL DEFAULT 100,
+ PRIMARY KEY (`col_a`)
+) ENGINE=SPIDER DEFAULT CHARSET=latin1 COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"'
+ALTER TABLE tbl_a MODIFY col_c MEDIUMINT NOT NULL DEFAULT 100;
+SHOW CREATE TABLE tbl_a;
+Table Create Table
+tbl_a CREATE TABLE `tbl_a` (
+ `col_a` int(11) NOT NULL AUTO_INCREMENT,
+ `col_b` varchar(20) DEFAULT 'defg',
+ `col_c` mediumint(9) NOT NULL DEFAULT 100,
+ PRIMARY KEY (`col_a`)
+) ENGINE=SPIDER AUTO_INCREMENT=20 DEFAULT CHARSET=latin1 COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"'
+RENAME TABLE tbl_a TO tbl_x;
+SHOW CREATE TABLE tbl_x;
+Table Create Table
+tbl_x CREATE TABLE `tbl_x` (
+ `col_a` int(11) NOT NULL AUTO_INCREMENT,
+ `col_b` varchar(20) DEFAULT 'defg',
+ `col_c` mediumint(9) NOT NULL DEFAULT 100,
+ PRIMARY KEY (`col_a`)
+) ENGINE=SPIDER AUTO_INCREMENT=20 DEFAULT CHARSET=latin1 COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"'
+RENAME TABLE tbl_x TO tbl_a;
+SHOW CREATE TABLE tbl_a;
+Table Create Table
+tbl_a CREATE TABLE `tbl_a` (
+ `col_a` int(11) NOT NULL AUTO_INCREMENT,
+ `col_b` varchar(20) DEFAULT 'defg',
+ `col_c` mediumint(9) NOT NULL DEFAULT 100,
+ PRIMARY KEY (`col_a`)
+) ENGINE=SPIDER AUTO_INCREMENT=20 DEFAULT CHARSET=latin1 COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"'
+INSERT INTO tbl_a () VALUES ();
+INSERT INTO tbl_a () VALUES ();
+SHOW CREATE TABLE tbl_a;
+Table Create Table
+tbl_a CREATE TABLE `tbl_a` (
+ `col_a` int(11) NOT NULL AUTO_INCREMENT,
+ `col_b` varchar(20) DEFAULT 'defg',
+ `col_c` mediumint(9) NOT NULL DEFAULT 100,
+ PRIMARY KEY (`col_a`)
+) ENGINE=SPIDER AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"'
+MASTER_1_AUTO_INCREMENT1
+SHOW CREATE TABLE tbl_a;
+Table Create Table
+tbl_a CREATE TABLE `tbl_a` (
+ `col_a` int(11) NOT NULL AUTO_INCREMENT,
+ `col_b` varchar(20) DEFAULT 'defg',
+ `col_c` mediumint(9) NOT NULL DEFAULT 100,
+ PRIMARY KEY (`col_a`)
+) ENGINE=SPIDER AUTO_INCREMENT=30 DEFAULT CHARSET=latin1 COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"'
+INSERT INTO tbl_a () VALUES ();
+INSERT INTO tbl_a () VALUES ();
+SHOW CREATE TABLE tbl_a;
+Table Create Table
+tbl_a CREATE TABLE `tbl_a` (
+ `col_a` int(11) NOT NULL AUTO_INCREMENT,
+ `col_b` varchar(20) DEFAULT 'defg',
+ `col_c` mediumint(9) NOT NULL DEFAULT 100,
+ PRIMARY KEY (`col_a`)
+) ENGINE=SPIDER AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"'
+MASTER_1_AUTO_INCREMENT2
+SHOW CREATE TABLE tbl_a;
+Table Create Table
+tbl_a CREATE TABLE `tbl_a` (
+ `col_a` int(11) NOT NULL AUTO_INCREMENT,
+ `col_b` varchar(20) DEFAULT 'defg',
+ `col_c` mediumint(9) NOT NULL DEFAULT 100,
+ PRIMARY KEY (`col_a`)
+) ENGINE=SPIDER AUTO_INCREMENT=20 DEFAULT CHARSET=latin1 COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"'
+INSERT INTO tbl_a () VALUES ();
+INSERT INTO tbl_a () VALUES ();
+SHOW CREATE TABLE tbl_a;
+Table Create Table
+tbl_a CREATE TABLE `tbl_a` (
+ `col_a` int(11) NOT NULL AUTO_INCREMENT,
+ `col_b` varchar(20) DEFAULT 'defg',
+ `col_c` mediumint(9) NOT NULL DEFAULT 100,
+ PRIMARY KEY (`col_a`)
+) ENGINE=SPIDER AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"'
+
+select test
+connection child2_1;
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+SELECT * FROM tbl_a;
+col_a col_b col_c
+1 def 10
+2 def 10
+3 def 10
+4 def 10
+5 def 10
+6 def 10
+7 def 10
+8 def 10
+connection child2_1;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select `col_a`,`col_b`,`col_c` from `auto_test_remote`.`tbl_a`
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT col_a, col_b, col_c FROM tbl_a ORDER BY col_a;
+col_a col_b col_c
+1 def 10
+2 def 10
+3 def 10
+4 def 10
+5 def 10
+6 def 10
+7 def 10
+8 def 10
+
+deinit
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+SET GLOBAL log_output = @old_log_output;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+end of test
diff --git a/storage/spider/mysql-test/spider/r/direct_aggregate.result b/storage/spider/mysql-test/spider/r/direct_aggregate.result
index 9a8660ba79e..ede48906a84 100644
--- a/storage/spider/mysql-test/spider/r/direct_aggregate.result
+++ b/storage/spider/mysql-test/spider/r/direct_aggregate.result
@@ -60,25 +60,25 @@ MAX(a)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 1
SELECT MIN(a) FROM ta_l;
MIN(a)
1
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 2
SELECT MAX(a) FROM ta_l WHERE a < 5;
MAX(a)
4
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 3
SELECT MIN(a) FROM ta_l WHERE a > 1;
MIN(a)
2
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 4
deinit
connection master_1;
diff --git a/storage/spider/mysql-test/spider/r/direct_aggregate_part.result b/storage/spider/mysql-test/spider/r/direct_aggregate_part.result
index 760b39e16d5..02cdc033a88 100644
--- a/storage/spider/mysql-test/spider/r/direct_aggregate_part.result
+++ b/storage/spider/mysql-test/spider/r/direct_aggregate_part.result
@@ -44,31 +44,31 @@ COUNT(*)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 2
SELECT MAX(a) FROM ta_l2;
MAX(a)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 4
SELECT MIN(a) FROM ta_l2;
MIN(a)
1
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 6
SELECT MAX(a) FROM ta_l2 WHERE a < 5;
MAX(a)
4
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 8
SELECT MIN(a) FROM ta_l2 WHERE a > 1;
MIN(a)
2
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 0
+Spider_direct_aggregate 10
deinit
connection master_1;
diff --git a/storage/spider/mysql-test/spider/r/direct_join.result b/storage/spider/mysql-test/spider/r/direct_join.result
new file mode 100644
index 00000000000..5cc44a56910
--- /dev/null
+++ b/storage/spider/mysql-test/spider/r/direct_join.result
@@ -0,0 +1,105 @@
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+drop and create databases
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+connection child2_1;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+
+test select 1
+connection master_1;
+SELECT 1;
+1
+1
+connection child2_1;
+SELECT 1;
+1
+1
+
+create table and insert
+connection child2_1;
+CHILD2_1_DROP_TABLES
+CHILD2_1_DROP_TABLES6
+CHILD2_1_DROP_TABLES5
+CHILD2_1_CREATE_TABLES
+CHILD2_1_CREATE_TABLES6
+CHILD2_1_CREATE_TABLES5
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+DROP TABLE IF EXISTS tbl_a;
+CREATE TABLE tbl_a (
+a INT DEFAULT 10,
+b CHAR(1) DEFAULT 'c',
+c DATETIME DEFAULT '1999-10-10 10:10:10',
+PRIMARY KEY(a),
+KEY idx1(b)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
+CREATE TABLE tbl_b (
+a INT DEFAULT 10,
+b CHAR(1) DEFAULT 'c',
+c DATETIME DEFAULT '1999-10-10 10:10:10'
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT5_2_1
+CREATE TABLE tbl_c (
+a INT AUTO_INCREMENT,
+b INT DEFAULT 10,
+c INT DEFAULT 11,
+PRIMARY KEY(a),
+KEY idx1(b),
+KEY idx2(c)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT4_2_1
+insert into tbl_a values (1,'a','2000/01/01'),(2,'b','2000/01/02'),(3,'c','2000/01/03'),(4,'d','2000/01/04'),(5,'e','2000/01/05');
+insert into tbl_b values (1,'a','2000/01/01'),(2,'b','2000/01/02'),(3,'c','2000/01/03'),(4,'d','2000/01/04'),(5,'e','2000/01/05');
+insert into tbl_c values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500);
+
+select test
+connection child2_1;
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+SELECT a.a, c.b, c.c FROM tbl_a a, tbl_b b, tbl_c c WHERE a.a = b.a and a.a = c.a ORDER BY a.b DESC LIMIT 1,2;
+a b c
+4 40 400
+3 30 300
+connection child2_1;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select t0.`b` `b`,t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r` t0,`auto_test_remote`.`ta_r_3` t1,`auto_test_remote`.`ta_r_int` t2 where ((t0.`a` = t1.`a`) and (t2.`a` = t1.`a`)) order by t0.`b` desc limit 1,2
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a;
+a b date_format(c, '%Y-%m-%d %H:%i:%s')
+1 a 2000-01-01 00:00:00
+2 b 2000-01-02 00:00:00
+3 c 2000-01-03 00:00:00
+4 d 2000-01-04 00:00:00
+5 e 2000-01-05 00:00:00
+
+deinit
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+SET GLOBAL log_output = @old_log_output;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+end of test
diff --git a/storage/spider/mysql-test/spider/r/direct_update.result b/storage/spider/mysql-test/spider/r/direct_update.result
index 74dae7aec2e..0e536d48617 100644
--- a/storage/spider/mysql-test/spider/r/direct_update.result
+++ b/storage/spider/mysql-test/spider/r/direct_update.result
@@ -48,6 +48,7 @@ direct_updating test
connection master_1;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 0
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-01 10:21:39
@@ -59,6 +60,7 @@ update all rows with function
UPDATE ta_l SET c = ADDDATE(c, 1);
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 1
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -70,6 +72,7 @@ update by primary key
UPDATE ta_l SET b = 'x' WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 2
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -81,6 +84,7 @@ update by a column without index
UPDATE ta_l SET c = '2011-10-17' WHERE b = 'x';
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -92,6 +96,7 @@ update by primary key with order and limit
UPDATE ta_l SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 4
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -103,6 +108,7 @@ delete by primary key with order and limit
DELETE FROM ta_l WHERE a < 4 ORDER BY c LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 1
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -113,6 +119,7 @@ delete by a column without index
DELETE FROM ta_l WHERE b = 'c';
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 2
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -122,6 +129,7 @@ delete by primary key
DELETE FROM ta_l WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
diff --git a/storage/spider/mysql-test/spider/r/direct_update_part.result b/storage/spider/mysql-test/spider/r/direct_update_part.result
index 6db7c01f563..7069cd72fda 100644
--- a/storage/spider/mysql-test/spider/r/direct_update_part.result
+++ b/storage/spider/mysql-test/spider/r/direct_update_part.result
@@ -38,6 +38,7 @@ PRIMARY KEY(a)
) MASTER_1_ENGINE MASTER_1_COMMENT2_P_2_1
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 0
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-01 10:21:39
@@ -49,6 +50,7 @@ update all rows with function
UPDATE ta_l2 SET c = ADDDATE(c, 1);
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 2
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -60,6 +62,7 @@ update by primary key
UPDATE ta_l2 SET b = 'x' WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -71,6 +74,7 @@ update by a column without index
UPDATE ta_l2 SET c = '2011-10-17' WHERE b = 'x';
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 5
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -82,6 +86,7 @@ update by primary key with order and limit
UPDATE ta_l2 SET c = ADDDATE(c, 1) WHERE a < 4 ORDER BY b DESC LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_update';
Variable_name Value
+Spider_direct_update 6
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -93,6 +98,7 @@ delete by primary key with order and limit
DELETE FROM ta_l2 WHERE a < 4 ORDER BY c LIMIT 1;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 1
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -103,6 +109,7 @@ delete by a column without index
DELETE FROM ta_l2 WHERE b = 'c';
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 3
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
@@ -112,6 +119,7 @@ delete by primary key
DELETE FROM ta_l2 WHERE a = 3;
SHOW STATUS LIKE 'Spider_direct_delete';
Variable_name Value
+Spider_direct_delete 4
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l2 ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
1 a 2008-08-02 10:21:39
diff --git a/storage/spider/mysql-test/spider/r/partition_cond_push.result b/storage/spider/mysql-test/spider/r/partition_cond_push.result
new file mode 100644
index 00000000000..ce26416b9f8
--- /dev/null
+++ b/storage/spider/mysql-test/spider/r/partition_cond_push.result
@@ -0,0 +1,168 @@
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+drop and create databases
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+connection child2_1;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+connection child2_2;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote2;
+CREATE DATABASE auto_test_remote2;
+USE auto_test_remote2;
+connection child2_3;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote3;
+CREATE DATABASE auto_test_remote3;
+USE auto_test_remote3;
+
+create table and insert
+connection child2_1;
+CHILD2_1_DROP_TABLES
+CHILD2_1_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection child2_2;
+CHILD2_2_DROP_TABLES
+CHILD2_2_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection child2_3;
+CHILD2_3_DROP_TABLES
+CHILD2_3_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+DROP TABLE IF EXISTS tbl_a;
+DROP TABLE IF EXISTS tbl_b;
+CREATE TABLE tbl_a (
+value int NOT NULL
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
+INSERT INTO tbl_a (value) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+INSERT INTO tbl_a (value) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19);
+INSERT INTO tbl_a (value) VALUES (20),(21),(22),(23),(24),(25),(26),(27),(28),(29);
+
+select test
+connection child2_1;
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+SELECT value FROM tbl_a WHERE value < 100;
+value
+4
+5
+10
+11
+16
+17
+22
+23
+28
+29
+0
+1
+6
+7
+12
+13
+18
+19
+24
+25
+2
+3
+8
+9
+14
+15
+20
+21
+26
+27
+connection child2_1;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select `value` from `auto_test_remote`.`tbl_a` where (`value` < 100)
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT value FROM tbl_a ORDER BY value;
+value
+4
+5
+10
+11
+16
+17
+22
+23
+28
+29
+connection child2_2;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select `value` from `auto_test_remote2`.`tbl_a` where (`value` < 100)
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT value FROM tbl_a ORDER BY value;
+value
+0
+1
+6
+7
+12
+13
+18
+19
+24
+25
+connection child2_3;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select `value` from `auto_test_remote3`.`tbl_a` where (`value` < 100)
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT value FROM tbl_a ORDER BY value;
+value
+2
+3
+8
+9
+14
+15
+20
+21
+26
+27
+
+deinit
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+SET GLOBAL log_output = @old_log_output;
+connection child2_2;
+DROP DATABASE IF EXISTS auto_test_remote2;
+SET GLOBAL log_output = @old_log_output;
+connection child2_3;
+DROP DATABASE IF EXISTS auto_test_remote3;
+SET GLOBAL log_output = @old_log_output;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+end of test
diff --git a/storage/spider/mysql-test/spider/r/partition_fulltext.result b/storage/spider/mysql-test/spider/r/partition_fulltext.result
new file mode 100644
index 00000000000..3289473b905
--- /dev/null
+++ b/storage/spider/mysql-test/spider/r/partition_fulltext.result
@@ -0,0 +1,126 @@
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+connection master_1;
+set @old_join_cache_level= @@join_cache_level;
+set session join_cache_level= 5;
+set @old_optimizer_switch= @@optimizer_switch;
+set session optimizer_switch= 'mrr=on';
+
+drop and create databases
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+connection child2_1;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+connection child2_2;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote2;
+CREATE DATABASE auto_test_remote2;
+USE auto_test_remote2;
+connection child2_3;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote3;
+CREATE DATABASE auto_test_remote3;
+USE auto_test_remote3;
+
+create table and insert
+connection child2_1;
+CHILD2_1_DROP_TABLES
+CHILD2_1_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection child2_2;
+CHILD2_2_DROP_TABLES
+CHILD2_2_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection child2_3;
+CHILD2_3_DROP_TABLES
+CHILD2_3_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+DROP TABLE IF EXISTS tbl_a;
+DROP TABLE IF EXISTS tbl_b;
+CREATE TABLE tbl_a (
+pkey int NOT NULL,
+words text NOT NULL,
+PRIMARY KEY (pkey),
+FULLTEXT (words)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
+INSERT INTO tbl_a (pkey, words) VALUES (0, 'abc'),(1, 'def'),(2, 'ghi'),(3, 'jkl'),(4, 'mno'),(5, 'pqr'),(6, 'stu'),(7, 'vwx');
+
+select test
+connection child2_1;
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+SELECT pkey, words FROM tbl_a WHERE match(words) against('+ghi' in boolean mode);
+pkey words
+2 ghi
+connection child2_1;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select match(`words`)against('+ghi' in boolean mode),`pkey`,`words` from `auto_test_remote`.`tbl_a` where match(`words`)against('+ghi' in boolean mode) and (match(`words`)against('+ghi' in boolean mode))
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT pkey FROM tbl_a ORDER BY pkey;
+pkey
+4
+5
+connection child2_2;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select match(`words`)against('+ghi' in boolean mode),`pkey`,`words` from `auto_test_remote2`.`tbl_a` where match(`words`)against('+ghi' in boolean mode) and (match(`words`)against('+ghi' in boolean mode))
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT pkey FROM tbl_a ORDER BY pkey;
+pkey
+0
+1
+6
+7
+connection child2_3;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select match(`words`)against('+ghi' in boolean mode),`pkey`,`words` from `auto_test_remote3`.`tbl_a` where match(`words`)against('+ghi' in boolean mode) and (match(`words`)against('+ghi' in boolean mode))
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT pkey FROM tbl_a ORDER BY pkey;
+pkey
+2
+3
+
+deinit
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+SET GLOBAL log_output = @old_log_output;
+connection child2_2;
+DROP DATABASE IF EXISTS auto_test_remote2;
+SET GLOBAL log_output = @old_log_output;
+connection child2_3;
+DROP DATABASE IF EXISTS auto_test_remote3;
+SET GLOBAL log_output = @old_log_output;
+connection master_1;
+set session join_cache_level= @old_join_cache_level;
+set session optimizer_switch= @old_optimizer_switch;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+end of test
diff --git a/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result b/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result
new file mode 100644
index 00000000000..899788ae1c1
--- /dev/null
+++ b/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result
@@ -0,0 +1,130 @@
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+drop and create databases
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+connection child2_1;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+connection child2_2;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote2;
+CREATE DATABASE auto_test_remote2;
+USE auto_test_remote2;
+connection child2_3;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote3;
+CREATE DATABASE auto_test_remote3;
+USE auto_test_remote3;
+
+create table and insert
+connection child2_1;
+CHILD2_1_DROP_TABLES
+CHILD2_1_DROP_TABLES2
+CHILD2_1_CREATE_TABLES
+CHILD2_1_CREATE_TABLES2
+TRUNCATE TABLE mysql.general_log;
+connection child2_2;
+CHILD2_2_DROP_TABLES
+CHILD2_2_DROP_TABLES2
+CHILD2_2_CREATE_TABLES
+CHILD2_2_CREATE_TABLES2
+TRUNCATE TABLE mysql.general_log;
+connection child2_3;
+CHILD2_3_DROP_TABLES
+CHILD2_3_DROP_TABLES2
+CHILD2_3_CREATE_TABLES
+CHILD2_3_CREATE_TABLES2
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+DROP TABLE IF EXISTS tbl_a;
+DROP TABLE IF EXISTS tbl_b;
+CREATE TABLE tbl_a (
+value int NOT NULL,
+PRIMARY KEY(value)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
+CREATE TABLE tbl_b (
+value2 int NOT NULL,
+PRIMARY KEY(value2)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_2
+insert into tbl_a values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+insert into tbl_b values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+connection master_1;
+SELECT sum(a.value), count(b.value2) FROM tbl_a a, tbl_b b WHERE a.value = b.value2 AND a.value = 5;
+sum(a.value) count(b.value2)
+5 1
+SELECT sum(a.value), count(b.value2) FROM tbl_a a, tbl_b b WHERE a.value = 5 and b.value2 = 5;
+sum(a.value) count(b.value2)
+5 1
+connection child2_1;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT value FROM tbl_a ORDER BY value;
+value
+1
+2
+3
+4
+connection child2_2;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select `value` from `auto_test_remote2`.`tbl_a` where `value` = 5
+select `value2` from `auto_test_remote2`.`tbl_b` where `value2` = 5
+select `value` from `auto_test_remote2`.`tbl_a` where `value` = 5
+select `value2` from `auto_test_remote2`.`tbl_b` where `value2` = 5
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT value FROM tbl_a ORDER BY value;
+value
+5
+6
+7
+8
+9
+connection child2_3;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT value FROM tbl_a ORDER BY value;
+value
+10
+
+deinit
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+SET GLOBAL log_output = @old_log_output;
+connection child2_2;
+DROP DATABASE IF EXISTS auto_test_remote2;
+SET GLOBAL log_output = @old_log_output;
+connection child2_3;
+DROP DATABASE IF EXISTS auto_test_remote3;
+SET GLOBAL log_output = @old_log_output;
+connection master_1;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+end of test
diff --git a/storage/spider/mysql-test/spider/r/partition_mrr.result b/storage/spider/mysql-test/spider/r/partition_mrr.result
new file mode 100644
index 00000000000..2335e8933a4
--- /dev/null
+++ b/storage/spider/mysql-test/spider/r/partition_mrr.result
@@ -0,0 +1,223 @@
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+connection master_1;
+set @old_join_cache_level= @@join_cache_level;
+set session join_cache_level= 5;
+set @old_optimizer_switch= @@optimizer_switch;
+set session optimizer_switch= 'mrr=on';
+
+drop and create databases
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+connection child2_1;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+connection child2_2;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote2;
+CREATE DATABASE auto_test_remote2;
+USE auto_test_remote2;
+connection child2_3;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+DROP DATABASE IF EXISTS auto_test_remote3;
+CREATE DATABASE auto_test_remote3;
+USE auto_test_remote3;
+
+create table and insert
+connection child2_1;
+CHILD2_1_DROP_TABLES
+CHILD2_1_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection child2_2;
+CHILD2_2_DROP_TABLES
+CHILD2_2_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection child2_3;
+CHILD2_3_DROP_TABLES
+CHILD2_3_CREATE_TABLES
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+DROP TABLE IF EXISTS tbl_a;
+DROP TABLE IF EXISTS tbl_b;
+CREATE TABLE tbl_a (
+pkey int NOT NULL,
+PRIMARY KEY (pkey)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
+CREATE TABLE tbl_b (
+pkey int NOT NULL,
+PRIMARY KEY (pkey)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_2
+INSERT INTO tbl_a (pkey) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+INSERT INTO tbl_a (pkey) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19);
+INSERT INTO tbl_a (pkey) VALUES (20),(21),(22),(23),(24),(25),(26),(27),(28),(29);
+INSERT INTO tbl_b (pkey) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+INSERT INTO tbl_b (pkey) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19);
+INSERT INTO tbl_b (pkey) VALUES (20),(21),(22),(23),(24),(25),(26),(27),(28),(29);
+
+select test
+connection child2_1;
+TRUNCATE TABLE mysql.general_log;
+connection master_1;
+SELECT a.pkey FROM tbl_a a, tbl_b b WHERE a.pkey = b.pkey;
+pkey
+4
+5
+10
+11
+16
+17
+22
+23
+28
+29
+0
+1
+6
+7
+12
+13
+18
+19
+24
+25
+2
+3
+8
+9
+14
+15
+20
+21
+26
+27
+connection child2_1;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select `pkey` from `auto_test_remote`.`tbl_a` order by `pkey`
+select a.id,b.`pkey` from auto_test_remote.tmp_spider_bka_xxxx a,`auto_test_remote`.`tbl_b` b where a.c0 <=> b.`pkey`
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT pkey FROM tbl_a ORDER BY pkey ;
+SELECT pkey FROM tbl_b ORDER BY pkey;
+pkey
+4
+5
+10
+11
+16
+17
+22
+23
+28
+29
+pkey
+2
+3
+8
+9
+14
+15
+20
+21
+26
+27
+connection child2_2;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select `pkey` from `auto_test_remote2`.`tbl_a` order by `pkey`
+select a.id,b.`pkey` from auto_test_remote2.tmp_spider_bka_xxxx a,`auto_test_remote2`.`tbl_b` b where a.c0 <=> b.`pkey`
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT pkey FROM tbl_a ORDER BY pkey ;
+SELECT pkey FROM tbl_b ORDER BY pkey;
+pkey
+0
+1
+6
+7
+12
+13
+18
+19
+24
+25
+pkey
+4
+5
+10
+11
+16
+17
+22
+23
+28
+29
+connection child2_3;
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+argument
+select `pkey` from `auto_test_remote3`.`tbl_a` order by `pkey`
+select a.id,b.`pkey` from auto_test_remote3.tmp_spider_bka_xxxx a,`auto_test_remote3`.`tbl_b` b where a.c0 <=> b.`pkey`
+SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
+SELECT pkey FROM tbl_a ORDER BY pkey ;
+SELECT pkey FROM tbl_b ORDER BY pkey;
+pkey
+2
+3
+8
+9
+14
+15
+20
+21
+26
+27
+pkey
+0
+1
+6
+7
+12
+13
+18
+19
+24
+25
+
+deinit
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection child2_1;
+DROP DATABASE IF EXISTS auto_test_remote;
+SET GLOBAL log_output = @old_log_output;
+connection child2_2;
+DROP DATABASE IF EXISTS auto_test_remote2;
+SET GLOBAL log_output = @old_log_output;
+connection child2_3;
+DROP DATABASE IF EXISTS auto_test_remote3;
+SET GLOBAL log_output = @old_log_output;
+connection master_1;
+set session join_cache_level= @old_join_cache_level;
+set session optimizer_switch= @old_optimizer_switch;
+for master_1
+for child2
+child2_1
+child2_2
+child2_3
+for child3
+child3_1
+child3_2
+child3_3
+
+end of test
diff --git a/storage/spider/mysql-test/spider/r/spider3_fixes_part.result b/storage/spider/mysql-test/spider/r/spider3_fixes_part.result
index b793346df4b..937f222f02f 100644
--- a/storage/spider/mysql-test/spider/r/spider3_fixes_part.result
+++ b/storage/spider/mysql-test/spider/r/spider3_fixes_part.result
@@ -85,10 +85,10 @@ MASTER_1_AUTO_INCREMENT_OFFSET3
INSERT INTO t1 (id) VALUES (null);
SELECT LAST_INSERT_ID();
LAST_INSERT_ID()
-778
+1555
SELECT MAX(id) FROM t1;
MAX(id)
-1554
+1555
MASTER_1_AUTO_INCREMENT_OFFSET4
INSERT INTO t2 (id) VALUES (null);
SELECT LAST_INSERT_ID();
@@ -101,36 +101,36 @@ MASTER_1_AUTO_INCREMENT_OFFSET3
INSERT INTO t1 () VALUES (),(),(),();
SELECT LAST_INSERT_ID();
LAST_INSERT_ID()
-1555
+2332
SELECT id FROM t1 ORDER BY id;
id
777
-778
1554
1555
2331
2332
3109
3886
+4663
MASTER_1_AUTO_INCREMENT_OFFSET4
INSERT INTO t2 () VALUES (),(),(),();
SELECT LAST_INSERT_ID();
LAST_INSERT_ID()
-3108
+5439
SELECT id FROM t2 ORDER BY id;
id
777
-778
1554
1555
2331
2332
-3108
3109
-3885
3886
-4662
+4663
5439
+6216
+6993
+7770
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
INSERT INTO t1 () VALUES (),(),(),();
diff --git a/storage/spider/mysql-test/spider/r/spider_fixes.result b/storage/spider/mysql-test/spider/r/spider_fixes.result
index f50c9822534..1db31ca9f95 100644
--- a/storage/spider/mysql-test/spider/r/spider_fixes.result
+++ b/storage/spider/mysql-test/spider/r/spider_fixes.result
@@ -461,6 +461,7 @@ Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
DELETE FROM t1;
Warnings:
Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
+Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
TRUNCATE t1;
Warnings:
diff --git a/storage/spider/mysql-test/spider/t/auto_increment.test b/storage/spider/mysql-test/spider/t/auto_increment.test
new file mode 100644
index 00000000000..12d93ca3e72
--- /dev/null
+++ b/storage/spider/mysql-test/spider/t/auto_increment.test
@@ -0,0 +1,185 @@
+--source auto_increment_init.inc
+
+--echo
+--echo drop and create databases
+--connection master_1
+--disable_warnings
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote;
+ CREATE DATABASE auto_test_remote;
+ USE auto_test_remote;
+}
+--enable_warnings
+
+--echo
+--echo test select 1
+--connection master_1
+SELECT 1;
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ SELECT 1;
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--echo
+--echo create table select test
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_1_DROP_TABLES;
+ echo CHILD2_1_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_1_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_1_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+--connection master_1
+--disable_warnings
+DROP TABLE IF EXISTS tbl_a;
+--enable_warnings
+--disable_query_log
+echo CREATE TABLE tbl_a (
+ col_a INT NOT NULL AUTO_INCREMENT,
+ col_b VARCHAR(20) DEFAULT 'defg',
+ col_c INT NOT NULL DEFAULT 100,
+ PRIMARY KEY(col_a)
+) MASTER_1_ENGINE MASTER_1_AUTO_INCREMENT_2_1 MASTER_1_COMMENT_2_1;
+eval CREATE TABLE tbl_a (
+ col_a INT NOT NULL AUTO_INCREMENT,
+ col_b VARCHAR(20) DEFAULT 'defg',
+ col_c INT NOT NULL DEFAULT 100,
+ PRIMARY KEY(col_a)
+) $MASTER_1_ENGINE $MASTER_1_AUTO_INCREMENT_2_1 $MASTER_1_COMMENT_2_1;
+--enable_query_log
+SHOW CREATE TABLE tbl_a;
+INSERT INTO tbl_a () VALUES ();
+INSERT INTO tbl_a () VALUES ();
+SHOW CREATE TABLE tbl_a;
+ALTER TABLE tbl_a MODIFY col_c MEDIUMINT NOT NULL DEFAULT 100;
+SHOW CREATE TABLE tbl_a;
+RENAME TABLE tbl_a TO tbl_x;
+SHOW CREATE TABLE tbl_x;
+RENAME TABLE tbl_x TO tbl_a;
+SHOW CREATE TABLE tbl_a;
+INSERT INTO tbl_a () VALUES ();
+INSERT INTO tbl_a () VALUES ();
+SHOW CREATE TABLE tbl_a;
+--disable_query_log
+echo MASTER_1_AUTO_INCREMENT1;
+eval $MASTER_1_AUTO_INCREMENT1;
+--enable_query_log
+SHOW CREATE TABLE tbl_a;
+INSERT INTO tbl_a () VALUES ();
+INSERT INTO tbl_a () VALUES ();
+SHOW CREATE TABLE tbl_a;
+--disable_query_log
+echo MASTER_1_AUTO_INCREMENT2;
+eval $MASTER_1_AUTO_INCREMENT2;
+--enable_query_log
+SHOW CREATE TABLE tbl_a;
+INSERT INTO tbl_a () VALUES ();
+INSERT INTO tbl_a () VALUES ();
+SHOW CREATE TABLE tbl_a;
+
+--echo
+--echo select test
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+--connection master_1
+SELECT * FROM tbl_a;
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_1_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_1_SELECT_TABLES;
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--echo
+--echo deinit
+--disable_warnings
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ DROP DATABASE IF EXISTS auto_test_remote;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+}
+--enable_warnings
+--source auto_increment_deinit.inc
+--echo
+--echo end of test
diff --git a/storage/spider/mysql-test/spider/t/auto_increment_deinit.inc b/storage/spider/mysql-test/spider/t/auto_increment_deinit.inc
new file mode 100644
index 00000000000..52be67a1d09
--- /dev/null
+++ b/storage/spider/mysql-test/spider/t/auto_increment_deinit.inc
@@ -0,0 +1,13 @@
+--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP
+--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
+--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
+--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
+--let $OUTPUT_CHILD_GROUP2= $OUTPUT_CHILD_GROUP2_BACKUP
+--let $USE_GENERAL_LOG= $USE_GENERAL_LOG_BACKUP
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
diff --git a/storage/spider/mysql-test/spider/t/auto_increment_init.inc b/storage/spider/mysql-test/spider/t/auto_increment_init.inc
new file mode 100644
index 00000000000..e4c1325072a
--- /dev/null
+++ b/storage/spider/mysql-test/spider/t/auto_increment_init.inc
@@ -0,0 +1,38 @@
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_init.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
+--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1
+let $MASTER_1_COMMENT_2_1=
+ COMMENT='database "auto_test_remote", table "tbl_a", srv "s_2_1", aim "0"';
+let $MASTER_1_AUTO_INCREMENT_2_1=
+ AUTO_INCREMENT=20;
+let $MASTER_1_AUTO_INCREMENT1=
+ ALTER TABLE tbl_a AUTO_INCREMENT=30;
+let $MASTER_1_AUTO_INCREMENT2=
+ ALTER TABLE tbl_a AUTO_INCREMENT=10;
+let $CHILD2_1_CHARSET_AUTO_INCREMENT=
+ AUTO_INCREMENT=20;
+--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
+let $CHILD2_1_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
+let $CHILD2_1_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ col_a INT NOT NULL AUTO_INCREMENT,
+ col_b VARCHAR(20) DEFAULT 'def',
+ col_c INT NOT NULL DEFAULT 10,
+ PRIMARY KEY(col_a)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET_AUTO_INCREMENT $CHILD2_1_CHARSET;
+--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
+let $CHILD2_1_SELECT_TABLES=
+ SELECT col_a, col_b, col_c FROM tbl_a ORDER BY col_a;
+let $CHILD2_1_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2
+--let $OUTPUT_CHILD_GROUP2= 1
+--let $USE_GENERAL_LOG_BACKUP= $USE_GENERAL_LOG
+--let $USE_GENERAL_LOG= 1
diff --git a/storage/spider/mysql-test/spider/t/direct_join.test b/storage/spider/mysql-test/spider/t/direct_join.test
new file mode 100644
index 00000000000..680164006c8
--- /dev/null
+++ b/storage/spider/mysql-test/spider/t/direct_join.test
@@ -0,0 +1,197 @@
+--source ../include/direct_join_init.inc
+
+--echo
+--echo drop and create databases
+--connection master_1
+--disable_warnings
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote;
+ CREATE DATABASE auto_test_remote;
+ USE auto_test_remote;
+}
+--enable_warnings
+
+--echo
+--echo test select 1
+--connection master_1
+SELECT 1;
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ SELECT 1;
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--echo
+--echo create table and insert
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_1_DROP_TABLES;
+ echo CHILD2_1_DROP_TABLES6;
+ echo CHILD2_1_DROP_TABLES5;
+ echo CHILD2_1_CREATE_TABLES;
+ echo CHILD2_1_CREATE_TABLES6;
+ echo CHILD2_1_CREATE_TABLES5;
+ }
+ --disable_warnings
+ eval $CHILD2_1_DROP_TABLES;
+ eval $CHILD2_1_DROP_TABLES6;
+ eval $CHILD2_1_DROP_TABLES5;
+ --enable_warnings
+ eval $CHILD2_1_CREATE_TABLES;
+ eval $CHILD2_1_CREATE_TABLES6;
+ eval $CHILD2_1_CREATE_TABLES5;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+--connection master_1
+--disable_warnings
+DROP TABLE IF EXISTS tbl_a;
+--enable_warnings
+--disable_query_log
+echo CREATE TABLE tbl_a (
+ a INT DEFAULT 10,
+ b CHAR(1) DEFAULT 'c',
+ c DATETIME DEFAULT '1999-10-10 10:10:10',
+ PRIMARY KEY(a),
+ KEY idx1(b)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
+eval CREATE TABLE tbl_a (
+ a INT DEFAULT 10,
+ b CHAR(1) DEFAULT 'c',
+ c DATETIME DEFAULT '1999-10-10 10:10:10',
+ PRIMARY KEY(a),
+ KEY idx1(b)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
+echo CREATE TABLE tbl_b (
+ a INT DEFAULT 10,
+ b CHAR(1) DEFAULT 'c',
+ c DATETIME DEFAULT '1999-10-10 10:10:10'
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT5_2_1;
+eval CREATE TABLE tbl_b (
+ a INT DEFAULT 10,
+ b CHAR(1) DEFAULT 'c',
+ c DATETIME DEFAULT '1999-10-10 10:10:10'
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT5_2_1;
+echo CREATE TABLE tbl_c (
+ a INT AUTO_INCREMENT,
+ b INT DEFAULT 10,
+ c INT DEFAULT 11,
+ PRIMARY KEY(a),
+ KEY idx1(b),
+ KEY idx2(c)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT4_2_1;
+eval CREATE TABLE tbl_c (
+ a INT AUTO_INCREMENT,
+ b INT DEFAULT 10,
+ c INT DEFAULT 11,
+ PRIMARY KEY(a),
+ KEY idx1(b),
+ KEY idx2(c)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT4_2_1;
+--enable_query_log
+insert into tbl_a values (1,'a','2000/01/01'),(2,'b','2000/01/02'),(3,'c','2000/01/03'),(4,'d','2000/01/04'),(5,'e','2000/01/05');
+insert into tbl_b values (1,'a','2000/01/01'),(2,'b','2000/01/02'),(3,'c','2000/01/03'),(4,'d','2000/01/04'),(5,'e','2000/01/05');
+insert into tbl_c values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500);
+
+--echo
+--echo select test
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--connection master_1
+SELECT a.a, c.b, c.c FROM tbl_a a, tbl_b b, tbl_c c WHERE a.a = b.a and a.a = c.a ORDER BY a.b DESC LIMIT 1,2;
+
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_1_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_1_SELECT_TABLES;
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--echo
+--echo deinit
+--disable_warnings
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ DROP DATABASE IF EXISTS auto_test_remote;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+}
+--enable_warnings
+--source ../include/direct_join_deinit.inc
+--echo
+--echo end of test
diff --git a/storage/spider/mysql-test/spider/t/partition_cond_push.test b/storage/spider/mysql-test/spider/t/partition_cond_push.test
new file mode 100644
index 00000000000..4bcfc2aa386
--- /dev/null
+++ b/storage/spider/mysql-test/spider/t/partition_cond_push.test
@@ -0,0 +1,219 @@
+--source ../include/partition_cond_push_init.inc
+if (!$HAVE_PARTITION)
+{
+ --source ../include/partition_cond_push_deinit.inc
+ skip Test requires partitioning;
+}
+
+--echo
+--echo drop and create databases
+--connection master_1
+--disable_warnings
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote;
+ CREATE DATABASE auto_test_remote;
+ USE auto_test_remote;
+ --connection child2_2
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote2;
+ CREATE DATABASE auto_test_remote2;
+ USE auto_test_remote2;
+ --connection child2_3
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote3;
+ CREATE DATABASE auto_test_remote3;
+ USE auto_test_remote3;
+}
+--enable_warnings
+
+--echo
+--echo create table and insert
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_1_DROP_TABLES;
+ echo CHILD2_1_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_1_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_1_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ --connection child2_2
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_2_DROP_TABLES;
+ echo CHILD2_2_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_2_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_2_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ --connection child2_3
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_3_DROP_TABLES;
+ echo CHILD2_3_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_3_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_3_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+--connection master_1
+--disable_warnings
+DROP TABLE IF EXISTS tbl_a;
+DROP TABLE IF EXISTS tbl_b;
+--enable_warnings
+--disable_query_log
+echo CREATE TABLE tbl_a (
+ value int NOT NULL
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
+eval CREATE TABLE tbl_a (
+ value int NOT NULL
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
+--enable_query_log
+INSERT INTO tbl_a (value) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+INSERT INTO tbl_a (value) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19);
+INSERT INTO tbl_a (value) VALUES (20),(21),(22),(23),(24),(25),(26),(27),(28),(29);
+
+--echo
+--echo select test
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+--connection master_1
+SELECT value FROM tbl_a WHERE value < 100;
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_1_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_1_SELECT_TABLES;
+ --connection child2_2
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_2_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_2_SELECT_TABLES;
+ --connection child2_3
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_3_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_3_SELECT_TABLES;
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--echo
+--echo deinit
+--disable_warnings
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ DROP DATABASE IF EXISTS auto_test_remote;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+ --connection child2_2
+ DROP DATABASE IF EXISTS auto_test_remote2;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+ --connection child2_3
+ DROP DATABASE IF EXISTS auto_test_remote3;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+}
+--enable_warnings
+--source ../include/partition_cond_push_deinit.inc
+--echo
+--echo end of test
diff --git a/storage/spider/mysql-test/spider/t/partition_fulltext.test b/storage/spider/mysql-test/spider/t/partition_fulltext.test
new file mode 100644
index 00000000000..cd9f9b05e9d
--- /dev/null
+++ b/storage/spider/mysql-test/spider/t/partition_fulltext.test
@@ -0,0 +1,223 @@
+--source ../include/partition_fulltext_init.inc
+if (!$HAVE_PARTITION)
+{
+ --source ../include/partition_fulltext_deinit.inc
+ skip Test requires partitioning;
+}
+
+--echo
+--echo drop and create databases
+--connection master_1
+--disable_warnings
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote;
+ CREATE DATABASE auto_test_remote;
+ USE auto_test_remote;
+ --connection child2_2
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote2;
+ CREATE DATABASE auto_test_remote2;
+ USE auto_test_remote2;
+ --connection child2_3
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote3;
+ CREATE DATABASE auto_test_remote3;
+ USE auto_test_remote3;
+}
+--enable_warnings
+
+--echo
+--echo create table and insert
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_1_DROP_TABLES;
+ echo CHILD2_1_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_1_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_1_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ --connection child2_2
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_2_DROP_TABLES;
+ echo CHILD2_2_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_2_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_2_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ --connection child2_3
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_3_DROP_TABLES;
+ echo CHILD2_3_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_3_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_3_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+--connection master_1
+--disable_warnings
+DROP TABLE IF EXISTS tbl_a;
+DROP TABLE IF EXISTS tbl_b;
+--enable_warnings
+--disable_query_log
+echo CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ words text NOT NULL,
+ PRIMARY KEY (pkey),
+ FULLTEXT (words)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
+eval CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ words text NOT NULL,
+ PRIMARY KEY (pkey),
+ FULLTEXT (words)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
+--enable_query_log
+INSERT INTO tbl_a (pkey, words) VALUES (0, 'abc'),(1, 'def'),(2, 'ghi'),(3, 'jkl'),(4, 'mno'),(5, 'pqr'),(6, 'stu'),(7, 'vwx');
+
+--echo
+--echo select test
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+--connection master_1
+SELECT pkey, words FROM tbl_a WHERE match(words) against('+ghi' in boolean mode);
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_1_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_1_SELECT_TABLES;
+ --connection child2_2
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_2_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_2_SELECT_TABLES;
+ --connection child2_3
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_3_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_3_SELECT_TABLES;
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--echo
+--echo deinit
+--disable_warnings
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ DROP DATABASE IF EXISTS auto_test_remote;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+ --connection child2_2
+ DROP DATABASE IF EXISTS auto_test_remote2;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+ --connection child2_3
+ DROP DATABASE IF EXISTS auto_test_remote3;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+}
+--enable_warnings
+--source ../include/partition_fulltext_deinit.inc
+--echo
+--echo end of test
diff --git a/storage/spider/mysql-test/spider/t/partition_join_pushdown_for_single_partition.test b/storage/spider/mysql-test/spider/t/partition_join_pushdown_for_single_partition.test
new file mode 100644
index 00000000000..f4e155be5e2
--- /dev/null
+++ b/storage/spider/mysql-test/spider/t/partition_join_pushdown_for_single_partition.test
@@ -0,0 +1,222 @@
+--source ../include/partition_join_pushdown_for_single_partition_init.inc
+if (!$HAVE_PARTITION)
+{
+ --source ../include/partition_join_pushdown_for_single_partition_deinit.inc
+ skip Test requires partitioning;
+}
+
+--echo
+--echo drop and create databases
+--connection master_1
+--disable_warnings
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote;
+ CREATE DATABASE auto_test_remote;
+ USE auto_test_remote;
+ --connection child2_2
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote2;
+ CREATE DATABASE auto_test_remote2;
+ USE auto_test_remote2;
+ --connection child2_3
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote3;
+ CREATE DATABASE auto_test_remote3;
+ USE auto_test_remote3;
+}
+--enable_warnings
+
+--echo
+--echo create table and insert
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_1_DROP_TABLES;
+ echo CHILD2_1_DROP_TABLES2;
+ echo CHILD2_1_CREATE_TABLES;
+ echo CHILD2_1_CREATE_TABLES2;
+ }
+ --disable_warnings
+ eval $CHILD2_1_DROP_TABLES;
+ eval $CHILD2_1_DROP_TABLES2;
+ --enable_warnings
+ eval $CHILD2_1_CREATE_TABLES;
+ eval $CHILD2_1_CREATE_TABLES2;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ --connection child2_2
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_2_DROP_TABLES;
+ echo CHILD2_2_DROP_TABLES2;
+ echo CHILD2_2_CREATE_TABLES;
+ echo CHILD2_2_CREATE_TABLES2;
+ }
+ --disable_warnings
+ eval $CHILD2_2_DROP_TABLES;
+ eval $CHILD2_2_DROP_TABLES2;
+ --enable_warnings
+ eval $CHILD2_2_CREATE_TABLES;
+ eval $CHILD2_2_CREATE_TABLES2;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ --connection child2_3
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_3_DROP_TABLES;
+ echo CHILD2_3_DROP_TABLES2;
+ echo CHILD2_3_CREATE_TABLES;
+ echo CHILD2_3_CREATE_TABLES2;
+ }
+ --disable_warnings
+ eval $CHILD2_3_DROP_TABLES;
+ eval $CHILD2_3_DROP_TABLES2;
+ --enable_warnings
+ eval $CHILD2_3_CREATE_TABLES;
+ eval $CHILD2_3_CREATE_TABLES2;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+--connection master_1
+--disable_warnings
+DROP TABLE IF EXISTS tbl_a;
+DROP TABLE IF EXISTS tbl_b;
+--enable_warnings
+--disable_query_log
+echo CREATE TABLE tbl_a (
+ value int NOT NULL,
+ PRIMARY KEY(value)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
+eval CREATE TABLE tbl_a (
+ value int NOT NULL,
+ PRIMARY KEY(value)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
+echo CREATE TABLE tbl_b (
+ value2 int NOT NULL,
+ PRIMARY KEY(value2)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_2;
+eval CREATE TABLE tbl_b (
+ value2 int NOT NULL,
+ PRIMARY KEY(value2)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_2;
+--enable_query_log
+
+insert into tbl_a values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+insert into tbl_b values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+
+--connection master_1
+SELECT sum(a.value), count(b.value2) FROM tbl_a a, tbl_b b WHERE a.value = b.value2 AND a.value = 5;
+SELECT sum(a.value), count(b.value2) FROM tbl_a a, tbl_b b WHERE a.value = 5 and b.value2 = 5;
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_1_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_1_SELECT_TABLES;
+ --connection child2_2
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_2_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_2_SELECT_TABLES;
+ --connection child2_3
+ if ($USE_GENERAL_LOG)
+ {
+ eval $CHILD2_3_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_3_SELECT_TABLES;
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--echo
+--echo deinit
+--disable_warnings
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ DROP DATABASE IF EXISTS auto_test_remote;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+ --connection child2_2
+ DROP DATABASE IF EXISTS auto_test_remote2;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+ --connection child2_3
+ DROP DATABASE IF EXISTS auto_test_remote3;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+}
+--enable_warnings
+--source ../include/partition_join_pushdown_for_single_partition_deinit.inc
+--echo
+--echo end of test
diff --git a/storage/spider/mysql-test/spider/t/partition_mrr.test b/storage/spider/mysql-test/spider/t/partition_mrr.test
new file mode 100644
index 00000000000..e7fedce33e6
--- /dev/null
+++ b/storage/spider/mysql-test/spider/t/partition_mrr.test
@@ -0,0 +1,235 @@
+--source ../include/partition_mrr_init.inc
+if (!$HAVE_PARTITION)
+{
+ --source ../include/partition_mrr_deinit.inc
+ skip Test requires partitioning;
+}
+
+--echo
+--echo drop and create databases
+--connection master_1
+--disable_warnings
+DROP DATABASE IF EXISTS auto_test_local;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote;
+ CREATE DATABASE auto_test_remote;
+ USE auto_test_remote;
+ --connection child2_2
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote2;
+ CREATE DATABASE auto_test_remote2;
+ USE auto_test_remote2;
+ --connection child2_3
+ if ($USE_GENERAL_LOG)
+ {
+ SET @old_log_output = @@global.log_output;
+ SET GLOBAL log_output = 'TABLE,FILE';
+ }
+ DROP DATABASE IF EXISTS auto_test_remote3;
+ CREATE DATABASE auto_test_remote3;
+ USE auto_test_remote3;
+}
+--enable_warnings
+
+--echo
+--echo create table and insert
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_1_DROP_TABLES;
+ echo CHILD2_1_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_1_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_1_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ --connection child2_2
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_2_DROP_TABLES;
+ echo CHILD2_2_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_2_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_2_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ --connection child2_3
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ echo CHILD2_3_DROP_TABLES;
+ echo CHILD2_3_CREATE_TABLES;
+ }
+ --disable_warnings
+ eval $CHILD2_3_DROP_TABLES;
+ --enable_warnings
+ eval $CHILD2_3_CREATE_TABLES;
+ if ($OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ }
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+--connection master_1
+--disable_warnings
+DROP TABLE IF EXISTS tbl_a;
+DROP TABLE IF EXISTS tbl_b;
+--enable_warnings
+--disable_query_log
+echo CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
+echo CREATE TABLE tbl_b (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_2;
+eval CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
+eval CREATE TABLE tbl_b (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_2;
+--enable_query_log
+INSERT INTO tbl_a (pkey) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+INSERT INTO tbl_a (pkey) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19);
+INSERT INTO tbl_a (pkey) VALUES (20),(21),(22),(23),(24),(25),(26),(27),(28),(29);
+INSERT INTO tbl_b (pkey) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+INSERT INTO tbl_b (pkey) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19);
+INSERT INTO tbl_b (pkey) VALUES (20),(21),(22),(23),(24),(25),(26),(27),(28),(29);
+
+--echo
+--echo select test
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+ TRUNCATE TABLE mysql.general_log;
+ }
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+--connection master_1
+SELECT a.pkey FROM tbl_a a, tbl_b b WHERE a.pkey = b.pkey;
+if ($USE_CHILD_GROUP2)
+{
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --disable_query_log
+ --disable_result_log
+ }
+ --connection child2_1
+ if ($USE_GENERAL_LOG)
+ {
+--replace_regex /tmp_spider_bka_0x[0-9a-f]*/tmp_spider_bka_xxxx/
+ eval $CHILD2_1_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_1_SELECT_TABLES;
+ --connection child2_2
+ if ($USE_GENERAL_LOG)
+ {
+--replace_regex /tmp_spider_bka_0x[0-9a-f]*/tmp_spider_bka_xxxx/
+ eval $CHILD2_2_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_2_SELECT_TABLES;
+ --connection child2_3
+ if ($USE_GENERAL_LOG)
+ {
+--replace_regex /tmp_spider_bka_0x[0-9a-f]*/tmp_spider_bka_xxxx/
+ eval $CHILD2_3_SELECT_ARGUMENT1;
+ }
+ eval $CHILD2_3_SELECT_TABLES;
+ if (!$OUTPUT_CHILD_GROUP2)
+ {
+ --enable_query_log
+ --enable_result_log
+ }
+}
+
+--echo
+--echo deinit
+--disable_warnings
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+if ($USE_CHILD_GROUP2)
+{
+ --connection child2_1
+ DROP DATABASE IF EXISTS auto_test_remote;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+ --connection child2_2
+ DROP DATABASE IF EXISTS auto_test_remote2;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+ --connection child2_3
+ DROP DATABASE IF EXISTS auto_test_remote3;
+ if ($USE_GENERAL_LOG)
+ {
+ SET GLOBAL log_output = @old_log_output;
+ }
+}
+--enable_warnings
+--source ../include/partition_mrr_deinit.inc
+--echo
+--echo end of test
diff --git a/storage/spider/scripts/install_spider.sql b/storage/spider/scripts/install_spider.sql
index 328541a550b..3fd9a6c8a37 100644
--- a/storage/spider/scripts/install_spider.sql
+++ b/storage/spider/scripts/install_spider.sql
@@ -1,4 +1,4 @@
-# Copyright (C) 2010-2013 Kentoku Shiba
+# Copyright (C) 2010-2016 Kentoku Shiba
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -73,7 +73,7 @@ create table if not exists mysql.spider_xa_failed_log(
) engine=MyISAM default charset=utf8 collate=utf8_bin;
create table if not exists mysql.spider_tables(
db_name char(64) not null default '',
- table_name char(64) not null default '',
+ table_name char(199) not null default '',
link_id int not null default 0,
priority bigint not null default 0,
server char(64) default null,
@@ -89,18 +89,22 @@ create table if not exists mysql.spider_tables(
ssl_cipher char(64) default null,
ssl_key text,
ssl_verify_server_cert tinyint not null default 0,
+ monitoring_binlog_pos_at_failing tinyint not null default 0,
default_file text,
default_group char(64) default null,
tgt_db_name char(64) default null,
tgt_table_name char(64) default null,
link_status tinyint not null default 1,
+ block_status tinyint not null default 0,
+ static_link_id char(64) default null,
primary key (db_name, table_name, link_id),
- key idx1 (priority)
+ key idx1 (priority),
+ unique key uidx1 (db_name, table_name, static_link_id)
) engine=MyISAM default charset=utf8 collate=utf8_bin;
create table if not exists mysql.spider_link_mon_servers(
db_name char(64) not null default '',
- table_name char(64) not null default '',
- link_id char(5) not null default '',
+ table_name char(199) not null default '',
+ link_id char(64) not null default '',
sid int unsigned not null default 0,
server char(64) default null,
scheme char(64) default null,
@@ -121,10 +125,40 @@ create table if not exists mysql.spider_link_mon_servers(
) engine=MyISAM default charset=utf8 collate=utf8_bin;
create table if not exists mysql.spider_link_failed_log(
db_name char(64) not null default '',
- table_name char(64) not null default '',
- link_id int not null default 0,
+ table_name char(199) not null default '',
+ link_id char(64) not null default '',
failed_time timestamp not null default current_timestamp
) engine=MyISAM default charset=utf8 collate=utf8_bin;
+create table if not exists mysql.spider_table_position_for_recovery(
+ db_name char(64) not null default '',
+ table_name char(199) not null default '',
+ failed_link_id int not null default 0,
+ source_link_id int not null default 0,
+ file text,
+ position text,
+ gtid text,
+ primary key (db_name, table_name, failed_link_id, source_link_id)
+) engine=MyISAM default charset=utf8 collate=utf8_bin;
+create table if not exists mysql.spider_table_sts(
+ db_name char(64) not null default '',
+ table_name char(199) not null default '',
+ data_file_length bigint unsigned not null default 0,
+ max_data_file_length bigint unsigned not null default 0,
+ index_file_length bigint unsigned not null default 0,
+ records bigint unsigned not null default 0,
+ mean_rec_length bigint unsigned not null default 0,
+ check_time datetime not null default '0000-00-00 00:00:00',
+ create_time datetime not null default '0000-00-00 00:00:00',
+ update_time datetime not null default '0000-00-00 00:00:00',
+ primary key (db_name, table_name)
+) engine=MyISAM default charset=utf8 collate=utf8_bin;
+create table if not exists mysql.spider_table_crd(
+ db_name char(64) not null default '',
+ table_name char(199) not null default '',
+ key_seq int unsigned not null default 0,
+ cardinality bigint not null default 0,
+ primary key (db_name, table_name, key_seq)
+) engine=MyISAM default charset=utf8 collate=utf8_bin;
-- If tables already exist and their definition differ from the latest ones,
-- we fix them here.
@@ -222,14 +256,14 @@ begin
add column default_group char(64) default null after default_file');
-- Fix for version 2.25
- select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
- where TABLE_SCHEMA = 'mysql'
- AND TABLE_NAME = 'spider_link_mon_servers'
- AND COLUMN_NAME = 'link_id';
- if @col_type != 'char(5)' then
- alter table mysql.spider_link_mon_servers
- modify link_id char(5) not null default '';
- end if;
+ -- select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
+ -- where TABLE_SCHEMA = 'mysql'
+ -- AND TABLE_NAME = 'spider_link_mon_servers'
+ -- AND COLUMN_NAME = 'link_id';
+ -- if @col_type != 'char(5)' then
+ -- alter table mysql.spider_link_mon_servers
+ -- modify link_id char(5) not null default '';
+ -- end if;
-- Fix for version 2.28
select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
@@ -283,6 +317,87 @@ begin
modify ssl_key text,
modify default_file text;
end if;
+
+ -- Fix for version 3.3.0
+ call mysql.spider_fix_one_table('spider_tables',
+ 'monitoring_binlog_pos_at_failing',
+ 'alter table mysql.spider_tables
+ add monitoring_binlog_pos_at_failing tinyint not null default 0 after ssl_verify_server_cert');
+
+ -- Fix for version 3.3.6
+ call mysql.spider_fix_one_table('spider_tables', 'block_status',
+ 'alter table mysql.spider_tables
+ add column block_status tinyint not null default 0 after link_status');
+ call mysql.spider_fix_one_table('spider_tables', 'static_link_id',
+ 'alter table mysql.spider_tables
+ add column static_link_id char(64) default null after block_status,
+ add unique index uidx1 (db_name, table_name, static_link_id)');
+ select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
+ where TABLE_SCHEMA = 'mysql'
+ AND TABLE_NAME = 'spider_link_mon_servers'
+ AND COLUMN_NAME = 'link_id';
+ if @col_type != 'char(64)' then
+ alter table mysql.spider_link_mon_servers
+ modify link_id char(64) not null default '';
+ end if;
+ select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
+ where TABLE_SCHEMA = 'mysql'
+ AND TABLE_NAME = 'spider_link_failed_log'
+ AND COLUMN_NAME = 'link_id';
+ if @col_type != 'char(64)' then
+ alter table mysql.spider_link_failed_log
+ modify link_id char(64) not null default '';
+ end if;
+
+ -- Fix for version 3.3.10
+ select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
+ where TABLE_SCHEMA = 'mysql'
+ AND TABLE_NAME = 'spider_tables'
+ AND COLUMN_NAME = 'table_name';
+ if @col_type != 'char(199)' then
+ alter table mysql.spider_tables
+ modify table_name char(199) not null default '';
+ end if;
+ select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
+ where TABLE_SCHEMA = 'mysql'
+ AND TABLE_NAME = 'spider_link_mon_servers'
+ AND COLUMN_NAME = 'table_name';
+ if @col_type != 'char(199)' then
+ alter table mysql.spider_link_mon_servers
+ modify table_name char(199) not null default '';
+ end if;
+ select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
+ where TABLE_SCHEMA = 'mysql'
+ AND TABLE_NAME = 'spider_link_failed_log'
+ AND COLUMN_NAME = 'table_name';
+ if @col_type != 'char(199)' then
+ alter table mysql.spider_link_failed_log
+ modify table_name char(199) not null default '';
+ end if;
+ select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
+ where TABLE_SCHEMA = 'mysql'
+ AND TABLE_NAME = 'spider_table_position_for_recovery'
+ AND COLUMN_NAME = 'table_name';
+ if @col_type != 'char(199)' then
+ alter table mysql.spider_table_position_for_recovery
+ modify table_name char(199) not null default '';
+ end if;
+ select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
+ where TABLE_SCHEMA = 'mysql'
+ AND TABLE_NAME = 'spider_table_sts'
+ AND COLUMN_NAME = 'table_name';
+ if @col_type != 'char(199)' then
+ alter table mysql.spider_table_sts
+ modify table_name char(199) not null default '';
+ end if;
+ select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS
+ where TABLE_SCHEMA = 'mysql'
+ AND TABLE_NAME = 'spider_table_crd'
+ AND COLUMN_NAME = 'table_name';
+ if @col_type != 'char(199)' then
+ alter table mysql.spider_table_crd
+ modify table_name char(199) not null default '';
+ end if;
end;//
delimiter ;
call mysql.spider_fix_system_tables;
diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc
index 01ed4a19ee0..3fa825a9d88 100644
--- a/storage/spider/spd_conn.cc
+++ b/storage/spider/spd_conn.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -26,6 +27,7 @@
#include "sql_partition.h"
#include "tztime.h"
#endif
+#include "spd_err.h"
#include "spd_param.h"
#include "spd_db_include.h"
#include "spd_include.h"
@@ -37,10 +39,24 @@
#include "spd_direct_sql.h"
#include "spd_ping_table.h"
#include "spd_malloc.h"
+#include "spd_err.h"
+
+#ifdef SPIDER_HAS_NEXT_THREAD_ID
+#define SPIDER_set_next_thread_id(A)
+#else
+extern ulong *spd_db_att_thread_id;
+inline void SPIDER_set_next_thread_id(THD *A)
+{
+ pthread_mutex_lock(&LOCK_thread_count);
+ A->thread_id = (*spd_db_att_thread_id)++;
+ pthread_mutex_unlock(&LOCK_thread_count);
+}
+#endif
extern handlerton *spider_hton_ptr;
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
pthread_mutex_t spider_conn_id_mutex;
+pthread_mutex_t spider_ipport_conn_mutex;
ulonglong spider_conn_id = 1;
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -48,6 +64,8 @@ extern pthread_attr_t spider_pt_attr;
#ifdef HAVE_PSI_INTERFACE
extern PSI_mutex_key spd_key_mutex_mta_conn;
+extern PSI_mutex_key spd_key_mutex_conn_i;
+extern PSI_cond_key spd_key_cond_conn_i;
#ifndef WITHOUT_SPIDER_BG_SEARCH
extern PSI_mutex_key spd_key_mutex_bg_conn_chain;
extern PSI_mutex_key spd_key_mutex_bg_conn_sync;
@@ -75,6 +93,9 @@ extern SPIDER_TRX *spider_global_trx;
HASH spider_open_connections;
uint spider_open_connections_id;
+HASH spider_ipport_conns;
+long spider_conn_mutex_id = 0;
+
const char *spider_open_connections_func_name;
const char *spider_open_connections_file_name;
ulong spider_open_connections_line_no;
@@ -109,6 +130,17 @@ uchar *spider_conn_get_key(
DBUG_RETURN((uchar*) conn->conn_key);
}
+uchar *spider_ipport_conn_get_key(
+ SPIDER_IP_PORT_CONN *ip_port,
+ size_t *length,
+ my_bool not_used __attribute__ ((unused))
+)
+{
+ DBUG_ENTER("spider_ipport_conn_get_key");
+ *length = ip_port->key_len;
+ DBUG_RETURN((uchar*) ip_port->key);
+}
+
int spider_reset_conn_setted_parameter(
SPIDER_CONN *conn,
THD *thd
@@ -152,10 +184,10 @@ int spider_free_conn_alloc(
SPIDER_CONN *conn
) {
DBUG_ENTER("spider_free_conn_alloc");
- spider_db_disconnect(conn);
#ifndef WITHOUT_SPIDER_BG_SEARCH
spider_free_conn_thread(conn);
#endif
+ spider_db_disconnect(conn);
if (conn->db_conn)
{
delete conn->db_conn;
@@ -175,6 +207,7 @@ void spider_free_conn_from_trx(
int *roop_count
) {
ha_spider *spider;
+ SPIDER_IP_PORT_CONN *ip_port_conn = conn->ip_port_conn;
DBUG_ENTER("spider_free_conn_from_trx");
spider_conn_clear_queue(conn);
conn->use_for_active_standby = FALSE;
@@ -252,6 +285,15 @@ void spider_free_conn_from_trx(
pthread_mutex_unlock(&spider_conn_mutex);
spider_free_conn(conn);
} else {
+ if (ip_port_conn)
+ { /* exists */
+ if (ip_port_conn->waiting_count)
+ {
+ pthread_mutex_lock(&ip_port_conn->mutex);
+ pthread_cond_signal(&ip_port_conn->cond);
+ pthread_mutex_unlock(&ip_port_conn->mutex);
+ }
+ }
if (spider_open_connections.array.max_element > old_elements)
{
spider_alloc_calc_mem(spider_current_trx,
@@ -409,6 +451,7 @@ SPIDER_CONN *spider_create_conn(
) {
int *need_mon;
SPIDER_CONN *conn;
+ SPIDER_IP_PORT_CONN *ip_port_conn;
char *tmp_name, *tmp_host, *tmp_username, *tmp_password, *tmp_socket;
char *tmp_wrapper, *tmp_ssl_ca, *tmp_ssl_capath, *tmp_ssl_cert;
char *tmp_ssl_cipher, *tmp_ssl_key, *tmp_default_file, *tmp_default_group;
@@ -625,6 +668,28 @@ SPIDER_CONN *spider_create_conn(
conn->dbton_id = share->hs_dbton_ids[link_idx];
}
#endif
+ if (conn->dbton_id == SPIDER_DBTON_SIZE)
+ {
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
+ {
+#endif
+ my_printf_error(
+ ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM,
+ ER_SPIDER_SQL_WRAPPER_IS_INVALID_STR,
+ MYF(0), conn->tgt_wrapper);
+ *error_num = ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM;
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ } else {
+ my_printf_error(
+ ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM,
+ ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_STR,
+ MYF(0), conn->tgt_wrapper);
+ *error_num = ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM;
+ }
+#endif
+ goto error_invalid_wrapper;
+ }
if (!(conn->db_conn = spider_dbton[conn->dbton_id].create_db_conn(conn)))
{
*error_num = HA_ERR_OUT_OF_MEM;
@@ -667,6 +732,47 @@ SPIDER_CONN *spider_create_conn(
++spider_conn_id;
pthread_mutex_unlock(&spider_conn_id_mutex);
+ pthread_mutex_lock(&spider_ipport_conn_mutex);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search_using_hash_value(
+ &spider_ipport_conns, conn->conn_key_hash_value,
+ (uchar*)conn->conn_key, conn->conn_key_length)))
+#else
+ if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search(
+ &spider_ipport_conns, (uchar*)conn->conn_key, conn->conn_key_length)))
+#endif
+ { /* exists, +1 */
+ pthread_mutex_unlock(&spider_ipport_conn_mutex);
+ pthread_mutex_lock(&ip_port_conn->mutex);
+ if (spider_param_max_connections())
+ { /* enable conncetion pool */
+ if (ip_port_conn->ip_port_count >= spider_param_max_connections())
+ { /* bigger than the max num of connections, free conn and return NULL */
+ pthread_mutex_unlock(&ip_port_conn->mutex);
+ *error_num = ER_SPIDER_CON_COUNT_ERROR;
+ goto error_too_many_ipport_count;
+ }
+ }
+ ip_port_conn->ip_port_count++;
+ pthread_mutex_unlock(&ip_port_conn->mutex);
+ }
+ else
+ {// do not exist
+ ip_port_conn = spider_create_ipport_conn(conn);
+ if (!ip_port_conn) {
+ /* failed, always do not effect 'create conn' */
+ pthread_mutex_unlock(&spider_ipport_conn_mutex);
+ DBUG_RETURN(conn);
+ }
+ if (my_hash_insert(&spider_ipport_conns, (uchar *)ip_port_conn)) {
+ /* insert failed, always do not effect 'create conn' */
+ pthread_mutex_unlock(&spider_ipport_conn_mutex);
+ DBUG_RETURN(conn);
+ }
+ pthread_mutex_unlock(&spider_ipport_conn_mutex);
+ }
+ conn->ip_port_conn = ip_port_conn;
+
DBUG_RETURN(conn);
/*
@@ -674,10 +780,12 @@ error_init_lock_table_hash:
DBUG_ASSERT(!conn->mta_conn_mutex_file_pos.file_name);
pthread_mutex_destroy(&conn->mta_conn_mutex);
*/
+error_too_many_ipport_count:
error_mta_conn_mutex_init:
error_db_conn_init:
delete conn->db_conn;
error_db_conn_create:
+error_invalid_wrapper:
spider_free(spider_current_trx, conn, MYF(0));
error_alloc_conn:
DBUG_RETURN(NULL);
@@ -827,16 +935,27 @@ SPIDER_CONN *spider_get_conn(
#endif
{
pthread_mutex_unlock(&spider_conn_mutex);
- DBUG_PRINT("info",("spider create new conn"));
- if (!(conn = spider_create_conn(share, spider, link_idx,
- base_link_idx, conn_kind, error_num)))
- goto error;
- *conn->conn_key = *conn_key;
- if (spider)
- {
- spider->conns[base_link_idx] = conn;
- if (spider_bit_is_set(spider->conn_can_fo, base_link_idx))
- conn->use_for_active_standby = TRUE;
+ if (spider_param_max_connections())
+ { /* enable connection pool */
+ conn = spider_get_conn_from_idle_connection(share, link_idx, conn_key, spider, conn_kind, base_link_idx, error_num);
+ /* failed get conn, goto error */
+ if (!conn)
+ goto error;
+
+ }
+ else
+ { /* did not enable conncetion pool , create_conn */
+ DBUG_PRINT("info",("spider create new conn"));
+ if (!(conn = spider_create_conn(share, spider, link_idx,
+ base_link_idx, conn_kind, error_num)))
+ goto error;
+ *conn->conn_key = *conn_key;
+ if (spider)
+ {
+ spider->conns[base_link_idx] = conn;
+ if (spider_bit_is_set(spider->conn_can_fo, base_link_idx))
+ conn->use_for_active_standby = TRUE;
+ }
}
} else {
#ifdef HASH_UPDATE_WITH_HASH_VALUE
@@ -1108,6 +1227,14 @@ int spider_free_conn(
) {
DBUG_ENTER("spider_free_conn");
DBUG_PRINT("info", ("spider conn=%p", conn));
+ SPIDER_IP_PORT_CONN* ip_port_conn = conn->ip_port_conn;
+ if (ip_port_conn)
+ { /* free conn, ip_port_count-- */
+ pthread_mutex_lock(&ip_port_conn->mutex);
+ if (ip_port_conn->ip_port_count > 0)
+ ip_port_conn->ip_port_count--;
+ pthread_mutex_unlock(&ip_port_conn->mutex);
+ }
spider_free_conn_alloc(conn);
spider_free(spider_current_trx, conn, MYF(0));
DBUG_RETURN(0);
@@ -1570,6 +1697,7 @@ int spider_set_conn_bg_param(
SPIDER_RESULT_LIST *result_list = &spider->result_list;
THD *thd = spider->trx->thd;
DBUG_ENTER("spider_set_conn_bg_param");
+ DBUG_PRINT("info",("spider spider=%p", spider));
bgs_mode =
spider_param_bgs_mode(thd, share->bgs_mode);
if (bgs_mode == 0)
@@ -1610,28 +1738,44 @@ int spider_set_conn_bg_param(
if (result_list->bgs_phase > 0)
{
- for (
- roop_count = spider_conn_link_idx_next(share->link_statuses,
- spider->conn_link_idx, -1, share->link_count,
- spider->lock_mode ?
- SPIDER_LINK_STATUS_RECOVERY : SPIDER_LINK_STATUS_OK);
- roop_count < (int) share->link_count;
- roop_count = spider_conn_link_idx_next(share->link_statuses,
- spider->conn_link_idx, roop_count, share->link_count,
- spider->lock_mode ?
- SPIDER_LINK_STATUS_RECOVERY : SPIDER_LINK_STATUS_OK)
- ) {
- if ((error_num = spider_create_conn_thread(spider->conns[roop_count])))
- DBUG_RETURN(error_num);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ if (spider->use_fields)
+ {
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain;
+ spider_fields *fields = spider->fields;
+ fields->set_pos_to_first_link_idx_chain();
+ while ((link_idx_chain = fields->get_next_link_idx_chain()))
+ {
+ if ((error_num = spider_create_conn_thread(link_idx_chain->conn)))
+ DBUG_RETURN(error_num);
+ }
+ } else {
+#endif
+ for (
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, -1, share->link_count,
+ spider->lock_mode ?
+ SPIDER_LINK_STATUS_RECOVERY : SPIDER_LINK_STATUS_OK);
+ roop_count < (int) share->link_count;
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, roop_count, share->link_count,
+ spider->lock_mode ?
+ SPIDER_LINK_STATUS_RECOVERY : SPIDER_LINK_STATUS_OK)
+ ) {
+ if ((error_num = spider_create_conn_thread(spider->conns[roop_count])))
+ DBUG_RETURN(error_num);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
- if ((error_num = spider_create_conn_thread(
- spider->hs_r_conns[roop_count])))
- DBUG_RETURN(error_num);
- if ((error_num = spider_create_conn_thread(
- spider->hs_w_conns[roop_count])))
- DBUG_RETURN(error_num);
+ if ((error_num = spider_create_conn_thread(
+ spider->hs_r_conns[roop_count])))
+ DBUG_RETURN(error_num);
+ if ((error_num = spider_create_conn_thread(
+ spider->hs_w_conns[roop_count])))
+ DBUG_RETURN(error_num);
#endif
+ }
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
}
+#endif
}
DBUG_RETURN(0);
}
@@ -1976,6 +2120,7 @@ int spider_bg_conn_search(
SPIDER_RESULT_LIST *result_list = &spider->result_list;
bool with_lock = FALSE;
DBUG_ENTER("spider_bg_conn_search");
+ DBUG_PRINT("info",("spider spider=%p", spider));
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_MYSQL)
{
@@ -2017,7 +2162,7 @@ int spider_bg_conn_search(
DBUG_RETURN(result_list->bgs_error);
}
}
- if (!result_list->finish_flg)
+ if (result_list->bgs_working || !result_list->finish_flg)
{
pthread_mutex_lock(&conn->bg_conn_mutex);
if (!result_list->finish_flg)
@@ -2041,10 +2186,18 @@ int spider_bg_conn_search(
result_list->bgs_error_msg, MYF(0));
DBUG_RETURN(result_list->bgs_error);
}
+ DBUG_PRINT("info",("spider result_list->quick_mode=%d",
+ result_list->quick_mode));
+ DBUG_PRINT("info",("spider result_list->bgs_current->result=%p",
+ result_list->bgs_current->result));
if (
result_list->quick_mode == 0 ||
!result_list->bgs_current->result
) {
+ DBUG_PRINT("info",("spider result_list->bgs_second_read=%lld",
+ result_list->bgs_second_read));
+ DBUG_PRINT("info",("spider result_list->bgs_split_read=%lld",
+ result_list->bgs_split_read));
result_list->split_read =
result_list->bgs_second_read > 0 ?
result_list->bgs_second_read :
@@ -2054,6 +2207,7 @@ int spider_bg_conn_search(
result_list->split_read ?
result_list->split_read :
result_list->internal_limit - result_list->record_num;
+ DBUG_PRINT("info",("spider sql_kinds=%u", spider->sql_kinds));
if (spider->sql_kinds & SPIDER_SQL_KIND_SQL)
{
if ((error_num = spider->reappend_limit_sql_part(
@@ -2095,6 +2249,9 @@ int spider_bg_conn_search(
conn->bg_target = spider;
conn->link_idx = link_idx;
conn->bg_discard_result = discard_result;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ conn->link_idx_chain = spider->link_idx_chain;
+#endif
pthread_mutex_lock(&conn->bg_conn_sync_mutex);
pthread_cond_signal(&conn->bg_conn_cond);
pthread_mutex_unlock(&conn->bg_conn_mutex);
@@ -2106,11 +2263,33 @@ int spider_bg_conn_search(
DBUG_PRINT("info",("spider bg current->finish_flg=%s",
result_list->current ?
(result_list->current->finish_flg ? "TRUE" : "FALSE") : "NULL"));
+ if (result_list->bgs_error)
+ {
+ DBUG_PRINT("info",("spider bg error"));
+ if (result_list->bgs_error != HA_ERR_END_OF_FILE)
+ {
+ if (result_list->bgs_error_with_message)
+ my_message(result_list->bgs_error,
+ result_list->bgs_error_msg, MYF(0));
+ DBUG_RETURN(result_list->bgs_error);
+ }
+ }
}
} else {
DBUG_PRINT("info",("spider bg current->finish_flg=%s",
result_list->current ?
(result_list->current->finish_flg ? "TRUE" : "FALSE") : "NULL"));
+ if (result_list->bgs_error)
+ {
+ DBUG_PRINT("info",("spider bg error"));
+ if (result_list->bgs_error != HA_ERR_END_OF_FILE)
+ {
+ if (result_list->bgs_error_with_message)
+ my_message(result_list->bgs_error,
+ result_list->bgs_error_msg, MYF(0));
+ DBUG_RETURN(result_list->bgs_error);
+ }
+ }
}
} else {
DBUG_PRINT("info",("spider bg search"));
@@ -2148,6 +2327,10 @@ int spider_bg_conn_search(
DBUG_PRINT("info",("spider bg next search"));
if (!result_list->current->finish_flg)
{
+ DBUG_PRINT("info",("spider result_list->quick_mode=%d",
+ result_list->quick_mode));
+ DBUG_PRINT("info",("spider result_list->bgs_current->result=%p",
+ result_list->bgs_current->result));
pthread_mutex_lock(&conn->bg_conn_mutex);
result_list->bgs_phase = 3;
if (
@@ -2160,6 +2343,7 @@ int spider_bg_conn_search(
result_list->split_read ?
result_list->split_read :
result_list->internal_limit - result_list->record_num;
+ DBUG_PRINT("info",("spider sql_kinds=%u", spider->sql_kinds));
if (spider->sql_kinds & SPIDER_SQL_KIND_SQL)
{
if ((error_num = spider->reappend_limit_sql_part(
@@ -2194,6 +2378,9 @@ int spider_bg_conn_search(
conn->bg_target = spider;
conn->link_idx = link_idx;
conn->bg_discard_result = discard_result;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ conn->link_idx_chain = spider->link_idx_chain;
+#endif
result_list->bgs_working = TRUE;
conn->bg_search = TRUE;
if (with_lock)
@@ -2260,7 +2447,7 @@ void *spider_bg_conn_action(
my_thread_init();
DBUG_ENTER("spider_bg_conn_action");
/* init start */
- if (!(thd = new THD(next_thread_id())))
+ if (!(thd = SPIDER_new_THD(next_thread_id())))
{
pthread_mutex_lock(&conn->bg_conn_sync_mutex);
pthread_cond_signal(&conn->bg_conn_sync_cond);
@@ -2268,6 +2455,7 @@ void *spider_bg_conn_action(
my_thread_end();
DBUG_RETURN(NULL);
}
+ SPIDER_set_next_thread_id(thd);
#ifdef HAVE_PSI_INTERFACE
mysql_thread_set_psi_id(thd->thread_id);
#endif
@@ -2394,12 +2582,23 @@ void *spider_bg_conn_action(
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
- if ((error_num = dbton_handler->set_sql_for_exec(sql_type,
- conn->link_idx)))
+ if (spider->use_fields)
{
- result_list->bgs_error = error_num;
- if ((result_list->bgs_error_with_message = thd->is_error()))
- strmov(result_list->bgs_error_msg, spider_stmt_da_message(thd));
+ if ((error_num = dbton_handler->set_sql_for_exec(sql_type,
+ conn->link_idx, conn->link_idx_chain)))
+ {
+ result_list->bgs_error = error_num;
+ if ((result_list->bgs_error_with_message = thd->is_error()))
+ strmov(result_list->bgs_error_msg, spider_stmt_da_message(thd));
+ }
+ } else {
+ if ((error_num = dbton_handler->set_sql_for_exec(sql_type,
+ conn->link_idx)))
+ {
+ result_list->bgs_error = error_num;
+ if ((result_list->bgs_error_with_message = thd->is_error()))
+ strmov(result_list->bgs_error_msg, spider_stmt_da_message(thd));
+ }
}
if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
@@ -2702,7 +2901,6 @@ void *spider_bg_sts_action(
SPIDER_TRX *trx;
int error_num = 0, roop_count;
ha_spider spider;
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
int *need_mons;
SPIDER_CONN **conns;
uint *conn_link_idx;
@@ -2713,48 +2911,31 @@ void *spider_bg_sts_action(
char **hs_w_conn_keys;
#endif
spider_db_handler **dbton_hdl;
-#else
- int need_mons[share->link_count];
- SPIDER_CONN *conns[share->link_count];
- uint conn_link_idx[share->link_count];
- uchar conn_can_fo[share->link_bitmap_size];
- char *conn_keys[share->link_count];
-#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
- char *hs_r_conn_keys[share->link_count];
- char *hs_w_conn_keys[share->link_count];
-#endif
- spider_db_handler *dbton_hdl[SPIDER_DBTON_SIZE];
-#endif
THD *thd;
my_thread_init();
DBUG_ENTER("spider_bg_sts_action");
/* init start */
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
+ char *ptr;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
- if (!(need_mons = (int *)
- spider_bulk_malloc(spider_current_trx, 21, MYF(MY_WME),
- &need_mons, sizeof(int) * share->link_count,
- &conns, sizeof(SPIDER_CONN *) * share->link_count,
- &conn_link_idx, sizeof(uint) * share->link_count,
- &conn_can_fo, sizeof(uchar) * share->link_bitmap_size,
- &conn_keys, sizeof(char *) * share->link_count,
- &hs_r_conn_keys, sizeof(char *) * share->link_count,
- &hs_w_conn_keys, sizeof(char *) * share->link_count,
- &dbton_hdl, sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE,
- NullS))
- )
+ ptr = (char *) my_alloca(
+ (sizeof(int) * share->link_count) +
+ (sizeof(SPIDER_CONN *) * share->link_count) +
+ (sizeof(uint) * share->link_count) +
+ (sizeof(uchar) * share->link_bitmap_size) +
+ (sizeof(char *) * share->link_count) +
+ (sizeof(char *) * share->link_count) +
+ (sizeof(char *) * share->link_count) +
+ (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE));
#else
- if (!(need_mons = (int *)
- spider_bulk_malloc(spider_current_trx, 21, MYF(MY_WME),
- &need_mons, sizeof(int) * share->link_count,
- &conns, sizeof(SPIDER_CONN *) * share->link_count,
- &conn_link_idx, sizeof(uint) * share->link_count,
- &conn_can_fo, sizeof(uchar) * share->link_bitmap_size,
- &conn_keys, sizeof(char *) * share->link_count,
- &dbton_hdl, sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE,
- NullS))
- )
-#endif
+ ptr = (char *) my_alloca(
+ (sizeof(int) * share->link_count) +
+ (sizeof(SPIDER_CONN *) * share->link_count) +
+ (sizeof(uint) * share->link_count) +
+ (sizeof(uchar) * share->link_bitmap_size) +
+ (sizeof(char *) * share->link_count) +
+ (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE));
+#endif
+ if (!ptr)
{
pthread_mutex_lock(&share->sts_mutex);
share->bg_sts_thd_wait = FALSE;
@@ -2764,20 +2945,35 @@ void *spider_bg_sts_action(
my_thread_end();
DBUG_RETURN(NULL);
}
+ need_mons = (int *) ptr;
+ ptr += (sizeof(int) * share->link_count);
+ conns = (SPIDER_CONN **) ptr;
+ ptr += (sizeof(SPIDER_CONN *) * share->link_count);
+ conn_link_idx = (uint *) ptr;
+ ptr += (sizeof(uint) * share->link_count);
+ conn_can_fo = (uchar *) ptr;
+ ptr += (sizeof(uchar) * share->link_bitmap_size);
+ conn_keys = (char **) ptr;
+ ptr += (sizeof(char *) * share->link_count);
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ hs_r_conn_keys = (char **) ptr;
+ ptr += (sizeof(char *) * share->link_count);
+ hs_w_conn_keys = (char **) ptr;
+ ptr += (sizeof(char *) * share->link_count);
#endif
+ dbton_hdl = (spider_db_handler **) ptr;
pthread_mutex_lock(&share->sts_mutex);
- if (!(thd = new THD(next_thread_id())))
+ if (!(thd = SPIDER_new_THD(next_thread_id())))
{
share->bg_sts_thd_wait = FALSE;
share->bg_sts_kill = FALSE;
share->bg_sts_init = FALSE;
pthread_mutex_unlock(&share->sts_mutex);
my_thread_end();
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(NULL, need_mons, MYF(MY_WME));
-#endif
+ my_afree(need_mons);
DBUG_RETURN(NULL);
}
+ SPIDER_set_next_thread_id(thd);
#ifdef HAVE_PSI_INTERFACE
mysql_thread_set_psi_id(thd->thread_id);
#endif
@@ -2794,9 +2990,7 @@ void *spider_bg_sts_action(
my_pthread_setspecific_ptr(THR_THD, NULL);
#endif
my_thread_end();
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(NULL, need_mons, MYF(MY_WME));
-#endif
+ my_afree(need_mons);
DBUG_RETURN(NULL);
}
share->bg_sts_thd = thd;
@@ -2829,14 +3023,14 @@ void *spider_bg_sts_action(
spider_bit_is_set(share->dbton_bitmap, roop_count) &&
spider_dbton[roop_count].create_db_handler
) {
- if ((dbton_hdl[roop_count] = spider_dbton[roop_count].create_db_handler(
+ if (!(dbton_hdl[roop_count] = spider_dbton[roop_count].create_db_handler(
&spider, share->dbton_share[roop_count])))
break;
if (dbton_hdl[roop_count]->init())
break;
}
}
- if (roop_count == SPIDER_DBTON_SIZE)
+ if (roop_count < SPIDER_DBTON_SIZE)
{
DBUG_PRINT("info",("spider handler init error"));
for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; --roop_count)
@@ -2859,9 +3053,7 @@ void *spider_bg_sts_action(
my_pthread_setspecific_ptr(THR_THD, NULL);
#endif
my_thread_end();
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(NULL, need_mons, MYF(MY_WME));
-#endif
+ my_afree(need_mons);
DBUG_RETURN(NULL);
}
/* init end */
@@ -2890,12 +3082,10 @@ void *spider_bg_sts_action(
my_pthread_setspecific_ptr(THR_THD, NULL);
#endif
my_thread_end();
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(NULL, need_mons, MYF(MY_WME));
-#endif
+ my_afree(need_mons);
DBUG_RETURN(NULL);
}
- if (spider.search_link_idx == -1)
+ if (spider.search_link_idx < 0)
{
spider_trx_set_link_idx_for_all(&spider);
/*
@@ -2933,6 +3123,7 @@ void *spider_bg_sts_action(
spider_global_trx,
thd,
share,
+ spider.search_link_idx,
(uint32) share->monitoring_sid[spider.search_link_idx],
share->table_name,
share->table_name_length,
@@ -2975,6 +3166,7 @@ void *spider_bg_sts_action(
spider_global_trx,
thd,
share,
+ spider.search_link_idx,
(uint32) share->monitoring_sid[spider.search_link_idx],
share->table_name,
share->table_name_length,
@@ -3081,7 +3273,6 @@ void *spider_bg_crd_action(
int error_num = 0, roop_count;
ha_spider spider;
TABLE table;
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
int *need_mons;
SPIDER_CONN **conns;
uint *conn_link_idx;
@@ -3092,48 +3283,31 @@ void *spider_bg_crd_action(
char **hs_w_conn_keys;
#endif
spider_db_handler **dbton_hdl;
-#else
- int need_mons[share->link_count];
- SPIDER_CONN *conns[share->link_count];
- uint conn_link_idx[share->link_count];
- uchar conn_can_fo[share->link_bitmap_size];
- char *conn_keys[share->link_count];
-#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
- char *hs_r_conn_keys[share->link_count];
- char *hs_w_conn_keys[share->link_count];
-#endif
- spider_db_handler *dbton_hdl[SPIDER_DBTON_SIZE];
-#endif
THD *thd;
my_thread_init();
DBUG_ENTER("spider_bg_crd_action");
/* init start */
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
+ char *ptr;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
- if (!(need_mons = (int *)
- spider_bulk_malloc(spider_current_trx, 22, MYF(MY_WME),
- &need_mons, sizeof(int) * share->link_count,
- &conns, sizeof(SPIDER_CONN *) * share->link_count,
- &conn_link_idx, sizeof(uint) * share->link_count,
- &conn_can_fo, sizeof(uchar) * share->link_bitmap_size,
- &conn_keys, sizeof(char *) * share->link_count,
- &hs_r_conn_keys, sizeof(char *) * share->link_count,
- &hs_w_conn_keys, sizeof(char *) * share->link_count,
- &dbton_hdl, sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE,
- NullS))
- )
+ ptr = (char *) my_alloca(
+ (sizeof(int) * share->link_count) +
+ (sizeof(SPIDER_CONN *) * share->link_count) +
+ (sizeof(uint) * share->link_count) +
+ (sizeof(uchar) * share->link_bitmap_size) +
+ (sizeof(char *) * share->link_count) +
+ (sizeof(char *) * share->link_count) +
+ (sizeof(char *) * share->link_count) +
+ (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE));
#else
- if (!(need_mons = (int *)
- spider_bulk_malloc(spider_current_trx, 22, MYF(MY_WME),
- &need_mons, sizeof(int) * share->link_count,
- &conns, sizeof(SPIDER_CONN *) * share->link_count,
- &conn_link_idx, sizeof(uint) * share->link_count,
- &conn_can_fo, sizeof(uchar) * share->link_bitmap_size,
- &conn_keys, sizeof(char *) * share->link_count,
- &dbton_hdl, sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE,
- NullS))
- )
-#endif
+ ptr = (char *) my_alloca(
+ (sizeof(int) * share->link_count) +
+ (sizeof(SPIDER_CONN *) * share->link_count) +
+ (sizeof(uint) * share->link_count) +
+ (sizeof(uchar) * share->link_bitmap_size) +
+ (sizeof(char *) * share->link_count) +
+ (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE));
+#endif
+ if (!ptr)
{
pthread_mutex_lock(&share->crd_mutex);
share->bg_crd_thd_wait = FALSE;
@@ -3143,20 +3317,35 @@ void *spider_bg_crd_action(
my_thread_end();
DBUG_RETURN(NULL);
}
+ need_mons = (int *) ptr;
+ ptr += (sizeof(int) * share->link_count);
+ conns = (SPIDER_CONN **) ptr;
+ ptr += (sizeof(SPIDER_CONN *) * share->link_count);
+ conn_link_idx = (uint *) ptr;
+ ptr += (sizeof(uint) * share->link_count);
+ conn_can_fo = (uchar *) ptr;
+ ptr += (sizeof(uchar) * share->link_bitmap_size);
+ conn_keys = (char **) ptr;
+ ptr += (sizeof(char *) * share->link_count);
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ hs_r_conn_keys = (char **) ptr;
+ ptr += (sizeof(char *) * share->link_count);
+ hs_w_conn_keys = (char **) ptr;
+ ptr += (sizeof(char *) * share->link_count);
#endif
+ dbton_hdl = (spider_db_handler **) ptr;
pthread_mutex_lock(&share->crd_mutex);
- if (!(thd = new THD(next_thread_id())))
+ if (!(thd = SPIDER_new_THD(next_thread_id())))
{
share->bg_crd_thd_wait = FALSE;
share->bg_crd_kill = FALSE;
share->bg_crd_init = FALSE;
pthread_mutex_unlock(&share->crd_mutex);
my_thread_end();
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(NULL, need_mons, MYF(MY_WME));
-#endif
+ my_afree(need_mons);
DBUG_RETURN(NULL);
}
+ SPIDER_set_next_thread_id(thd);
#ifdef HAVE_PSI_INTERFACE
mysql_thread_set_psi_id(thd->thread_id);
#endif
@@ -3173,9 +3362,7 @@ void *spider_bg_crd_action(
my_pthread_setspecific_ptr(THR_THD, NULL);
#endif
my_thread_end();
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(NULL, need_mons, MYF(MY_WME));
-#endif
+ my_afree(need_mons);
DBUG_RETURN(NULL);
}
share->bg_crd_thd = thd;
@@ -3212,14 +3399,14 @@ void *spider_bg_crd_action(
spider_bit_is_set(share->dbton_bitmap, roop_count) &&
spider_dbton[roop_count].create_db_handler
) {
- if ((dbton_hdl[roop_count] = spider_dbton[roop_count].create_db_handler(
+ if (!(dbton_hdl[roop_count] = spider_dbton[roop_count].create_db_handler(
&spider, share->dbton_share[roop_count])))
break;
if (dbton_hdl[roop_count]->init())
break;
}
}
- if (roop_count == SPIDER_DBTON_SIZE)
+ if (roop_count < SPIDER_DBTON_SIZE)
{
DBUG_PRINT("info",("spider handler init error"));
for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; --roop_count)
@@ -3242,9 +3429,7 @@ void *spider_bg_crd_action(
my_pthread_setspecific_ptr(THR_THD, NULL);
#endif
my_thread_end();
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(NULL, need_mons, MYF(MY_WME));
-#endif
+ my_afree(need_mons);
DBUG_RETURN(NULL);
}
/* init end */
@@ -3273,12 +3458,10 @@ void *spider_bg_crd_action(
my_pthread_setspecific_ptr(THR_THD, NULL);
#endif
my_thread_end();
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(NULL, need_mons, MYF(MY_WME));
-#endif
+ my_afree(need_mons);
DBUG_RETURN(NULL);
}
- if (spider.search_link_idx == -1)
+ if (spider.search_link_idx < 0)
{
spider_trx_set_link_idx_for_all(&spider);
/*
@@ -3316,6 +3499,7 @@ void *spider_bg_crd_action(
spider_global_trx,
thd,
share,
+ spider.search_link_idx,
(uint32) share->monitoring_sid[spider.search_link_idx],
share->table_name,
share->table_name_length,
@@ -3358,6 +3542,7 @@ void *spider_bg_crd_action(
spider_global_trx,
thd,
share,
+ spider.search_link_idx,
(uint32) share->monitoring_sid[spider.search_link_idx],
share->table_name,
share->table_name_length,
@@ -3407,15 +3592,9 @@ int spider_create_mon_threads(
{
char link_idx_str[SPIDER_SQL_INT_LEN];
int link_idx_str_length;
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_string conv_name_str(share->table_name_length +
- SPIDER_SQL_INT_LEN + 1);
- conv_name_str.set_charset(system_charset_info);
-#else
- char buf[share->table_name_length + SPIDER_SQL_INT_LEN + 1];
+ char *buf = (char *) my_alloca(share->table_name_length + SPIDER_SQL_INT_LEN + 1);
spider_string conv_name_str(buf, share->table_name_length +
SPIDER_SQL_INT_LEN + 1, system_charset_info);
-#endif
conv_name_str.init_calc_mem(105);
conv_name_str.length(0);
conv_name_str.q_append(share->table_name, share->table_name_length);
@@ -3425,14 +3604,26 @@ int spider_create_mon_threads(
if (share->monitoring_bg_kind[roop_count])
{
conv_name_str.length(share->table_name_length);
- link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str,
- "%010d", roop_count));
+ if (share->static_link_ids[roop_count])
+ {
+ memcpy(link_idx_str, share->static_link_ids[roop_count],
+ share->static_link_ids_lengths[roop_count] + 1);
+ link_idx_str_length = share->static_link_ids_lengths[roop_count];
+ } else {
+ link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str,
+ "%010d", roop_count));
+ }
conv_name_str.q_append(link_idx_str, link_idx_str_length + 1);
conv_name_str.length(conv_name_str.length() - 1);
if (!(table_mon_list = spider_get_ping_table_mon_list(trx, trx->thd,
&conv_name_str, share->table_name_length, roop_count,
+ share->static_link_ids[roop_count],
+ share->static_link_ids_lengths[roop_count],
(uint32) share->monitoring_sid[roop_count], FALSE, &error_num)))
+ {
+ my_afree(buf);
goto error_get_ping_table_mon_list;
+ }
spider_free_ping_table_mon_list(table_mon_list);
}
}
@@ -3448,6 +3639,7 @@ int spider_create_mon_threads(
NullS))
) {
error_num = HA_ERR_OUT_OF_MEM;
+ my_afree(buf);
goto error_alloc_base;
}
for (roop_count = 0; roop_count < (int) share->all_link_count;
@@ -3464,6 +3656,7 @@ int spider_create_mon_threads(
#endif
) {
error_num = HA_ERR_OUT_OF_MEM;
+ my_afree(buf);
goto error_mutex_init;
}
}
@@ -3480,6 +3673,7 @@ int spider_create_mon_threads(
#endif
) {
error_num = HA_ERR_OUT_OF_MEM;
+ my_afree(buf);
goto error_cond_init;
}
}
@@ -3496,6 +3690,7 @@ int spider_create_mon_threads(
#endif
) {
error_num = HA_ERR_OUT_OF_MEM;
+ my_afree(buf);
goto error_sleep_cond_init;
}
}
@@ -3519,6 +3714,7 @@ int spider_create_mon_threads(
#endif
{
error_num = HA_ERR_OUT_OF_MEM;
+ my_afree(buf);
goto error_thread_create;
}
pthread_cond_wait(&share->bg_mon_conds[roop_count],
@@ -3527,6 +3723,7 @@ int spider_create_mon_threads(
}
}
share->bg_mon_init = TRUE;
+ my_afree(buf);
}
}
DBUG_RETURN(0);
@@ -3634,7 +3831,7 @@ void *spider_bg_mon_action(
DBUG_ENTER("spider_bg_mon_action");
/* init start */
pthread_mutex_lock(&share->bg_mon_mutexes[link_idx]);
- if (!(thd = new THD(next_thread_id())))
+ if (!(thd = SPIDER_new_THD(next_thread_id())))
{
share->bg_mon_kill = FALSE;
share->bg_mon_init = FALSE;
@@ -3643,6 +3840,7 @@ void *spider_bg_mon_action(
my_thread_end();
DBUG_RETURN(NULL);
}
+ SPIDER_set_next_thread_id(thd);
#ifdef HAVE_PSI_INTERFACE
mysql_thread_set_psi_id(thd->thread_id);
#endif
@@ -3707,6 +3905,7 @@ void *spider_bg_mon_action(
spider_global_trx,
thd,
share,
+ link_idx,
(uint32) share->monitoring_sid[link_idx],
share->table_name,
share->table_name_length,
@@ -3735,25 +3934,19 @@ int spider_conn_first_link_idx(
int roop_count, active_links = 0;
longlong balance_total = 0, balance_val;
double rand_val;
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
int *link_idxs, link_idx;
long *balances;
-#else
- int link_idxs[link_count];
- long balances[link_count];
-#endif
DBUG_ENTER("spider_conn_first_link_idx");
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- if (!(link_idxs = (int *)
- spider_bulk_malloc(spider_current_trx, 24, MYF(MY_WME),
- &link_idxs, sizeof(int) * link_count,
- &balances, sizeof(long) * link_count,
- NullS))
- ) {
+ char *ptr;
+ ptr = (char *) my_alloca((sizeof(int) * link_count) + (sizeof(long) * link_count));
+ if (!ptr)
+ {
DBUG_PRINT("info",("spider out of memory"));
- DBUG_RETURN(-1);
+ DBUG_RETURN(-2);
}
-#endif
+ link_idxs = (int *) ptr;
+ ptr += sizeof(int) * link_count;
+ balances = (long *) ptr;
for (roop_count = 0; roop_count < link_count; roop_count++)
{
DBUG_ASSERT((conn_link_idx[roop_count] - roop_count) % link_count == 0);
@@ -3769,9 +3962,7 @@ int spider_conn_first_link_idx(
if (active_links == 0)
{
DBUG_PRINT("info",("spider all links are failed"));
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(spider_current_trx, link_idxs, MYF(MY_WME));
-#endif
+ my_afree(link_idxs);
DBUG_RETURN(-1);
}
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002
@@ -3798,13 +3989,9 @@ int spider_conn_first_link_idx(
}
DBUG_PRINT("info",("spider first link_idx=%d", link_idxs[roop_count]));
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
link_idx = link_idxs[roop_count];
- spider_free(spider_current_trx, link_idxs, MYF(MY_WME));
+ my_afree(link_idxs);
DBUG_RETURN(link_idx);
-#else
- DBUG_RETURN(link_idxs[roop_count]);
-#endif
}
int spider_conn_next_link_idx(
@@ -3857,6 +4044,17 @@ int spider_conn_link_idx_next(
DBUG_RETURN(link_idx);
}
+int spider_conn_get_link_status(
+ long *link_statuses,
+ uint *conn_link_idx,
+ int link_idx
+) {
+ DBUG_ENTER("spider_conn_get_link_status");
+ DBUG_PRINT("info",("spider link_status=%d",
+ (int) link_statuses[conn_link_idx[link_idx]]));
+ DBUG_RETURN((int) link_statuses[conn_link_idx[link_idx]]);
+}
+
int spider_conn_lock_mode(
ha_spider *spider
) {
@@ -4166,3 +4364,208 @@ bool spider_conn_need_open_handler(
}
DBUG_RETURN(TRUE);
}
+
+SPIDER_CONN* spider_get_conn_from_idle_connection(
+ SPIDER_SHARE *share,
+ int link_idx,
+ char *conn_key,
+ ha_spider *spider,
+ uint conn_kind,
+ int base_link_idx,
+ int *error_num
+ )
+{
+ DBUG_ENTER("spider_get_conn_from_idle_connection");
+ SPIDER_IP_PORT_CONN *ip_port_conn;
+ SPIDER_CONN *conn = NULL;
+ uint spider_max_connections = spider_param_max_connections();
+ struct timespec abstime;
+ ulonglong start, inter_val = 0;
+ longlong last_ntime = 0;
+ ulonglong wait_time = (ulonglong)spider_param_conn_wait_timeout()*1000*1000*1000; // default 10s
+
+ unsigned long ip_port_count = 0; // init 0
+
+ set_timespec(abstime, 0);
+
+ pthread_mutex_lock(&spider_ipport_conn_mutex);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search_using_hash_value(
+ &spider_ipport_conns, share->conn_keys_hash_value[link_idx],
+ (uchar*) share->conn_keys[link_idx], share->conn_keys_lengths[link_idx])))
+#else
+ if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search(
+ &spider_ipport_conns,
+ (uchar*) share->conn_keys[link_idx], share->conn_keys_lengths[link_idx])))
+#endif
+ { /* exists */
+ pthread_mutex_unlock(&spider_ipport_conn_mutex);
+ pthread_mutex_lock(&ip_port_conn->mutex);
+ ip_port_count = ip_port_conn->ip_port_count;
+ } else {
+ pthread_mutex_unlock(&spider_ipport_conn_mutex);
+ }
+
+ if (
+ ip_port_conn &&
+ ip_port_count >= spider_max_connections &&
+ spider_max_connections > 0
+ ) { /* no idle conn && enable connection pool, wait */
+ pthread_mutex_unlock(&ip_port_conn->mutex);
+ start = my_hrtime().val;
+ while(1)
+ {
+ int error;
+ inter_val = my_hrtime().val - start; // us
+ last_ntime = wait_time - inter_val*1000; // *1000, to ns
+ if(last_ntime <= 0)
+ {/* wait timeout */
+ *error_num = ER_SPIDER_CON_COUNT_ERROR;
+ DBUG_RETURN(NULL);
+ }
+ set_timespec_nsec(abstime, last_ntime);
+ pthread_mutex_lock(&ip_port_conn->mutex);
+ ++ip_port_conn->waiting_count;
+ error = pthread_cond_timedwait(&ip_port_conn->cond, &ip_port_conn->mutex, &abstime);
+ --ip_port_conn->waiting_count;
+ pthread_mutex_unlock(&ip_port_conn->mutex);
+ if (error == ETIMEDOUT || error == ETIME || error != 0 )
+ {
+ *error_num = ER_SPIDER_CON_COUNT_ERROR;
+ DBUG_RETURN(NULL);
+ }
+
+ pthread_mutex_lock(&spider_conn_mutex);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ if ((conn = (SPIDER_CONN*) my_hash_search_using_hash_value(
+ &spider_open_connections, share->conn_keys_hash_value[link_idx],
+ (uchar*) share->conn_keys[link_idx],
+ share->conn_keys_lengths[link_idx])))
+#else
+ if ((conn = (SPIDER_CONN*) my_hash_search(&spider_open_connections,
+ (uchar*) share->conn_keys[link_idx],
+ share->conn_keys_lengths[link_idx])))
+#endif
+ {
+ /* get conn from spider_open_connections, then delete conn in spider_open_connections */
+#ifdef HASH_UPDATE_WITH_HASH_VALUE
+ my_hash_delete_with_hash_value(&spider_open_connections,
+ conn->conn_key_hash_value, (uchar*) conn);
+#else
+ my_hash_delete(&spider_open_connections, (uchar*) conn);
+#endif
+ pthread_mutex_unlock(&spider_conn_mutex);
+ DBUG_PRINT("info",("spider get global conn"));
+ if (spider)
+ {
+ spider->conns[base_link_idx] = conn;
+ if (spider_bit_is_set(spider->conn_can_fo, base_link_idx))
+ conn->use_for_active_standby = TRUE;
+ }
+ DBUG_RETURN(conn);
+ }
+ else
+ {
+ pthread_mutex_unlock(&spider_conn_mutex);
+ }
+ }
+ }
+ else
+ { /* create conn */
+ if (ip_port_conn)
+ pthread_mutex_unlock(&ip_port_conn->mutex);
+ DBUG_PRINT("info",("spider create new conn"));
+ if (!(conn = spider_create_conn(share, spider, link_idx, base_link_idx, conn_kind, error_num)))
+ DBUG_RETURN(conn);
+ *conn->conn_key = *conn_key;
+ if (spider)
+ {
+ spider->conns[base_link_idx] = conn;
+ if (spider_bit_is_set(spider->conn_can_fo, base_link_idx))
+ conn->use_for_active_standby = TRUE;
+ }
+ }
+
+ DBUG_RETURN(conn);
+}
+
+
+SPIDER_IP_PORT_CONN* spider_create_ipport_conn(SPIDER_CONN *conn)
+{
+ DBUG_ENTER("spider_create_ipport_conn");
+ if (conn)
+ {
+ SPIDER_IP_PORT_CONN *ret = (SPIDER_IP_PORT_CONN *) my_malloc(sizeof(*ret), MY_ZEROFILL | MY_WME);
+ if (!ret)
+ {
+ goto err_return_direct;
+ }
+
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_mutex_init(&ret->mutex, MY_MUTEX_INIT_FAST))
+#else
+ if (mysql_mutex_init(spd_key_mutex_conn_i, &ret->mutex, MY_MUTEX_INIT_FAST))
+#endif
+ {
+ //error
+ goto err_malloc_key;
+ }
+
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_cond_init(&ret->cond, NULL))
+#else
+ if (mysql_cond_init(spd_key_cond_conn_i, &ret->cond, NULL))
+#endif
+ {
+ pthread_mutex_destroy(&ret->mutex);
+ goto err_malloc_key;
+ //error
+ }
+
+ ret->key_len = conn->conn_key_length;
+ if (ret->key_len <= 0) {
+ pthread_cond_destroy(&ret->cond);
+ pthread_mutex_destroy(&ret->mutex);
+ goto err_malloc_key;
+ }
+
+ ret->key = (char *) my_malloc(ret->key_len, MY_ZEROFILL | MY_WME);
+ if (!ret->key) {
+ pthread_cond_destroy(&ret->cond);
+ pthread_mutex_destroy(&ret->mutex);
+ goto err_malloc_key;
+ }
+
+ memcpy(ret->key, conn->conn_key, ret->key_len);
+
+ strncpy(ret->remote_ip_str, conn->tgt_host, sizeof(ret->remote_ip_str));
+ ret->remote_port = conn->tgt_port;
+ ret->conn_id = conn->conn_id;
+ ret->ip_port_count = 1; // init
+
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ ret->key_hash_value = conn->conn_key_hash_value;
+#endif
+ DBUG_RETURN(ret);
+err_malloc_key:
+ spider_my_free(ret, MYF(0));
+err_return_direct:
+ DBUG_RETURN(NULL);
+ }
+ DBUG_RETURN(NULL);
+}
+
+
+void spider_free_ipport_conn(void *info)
+{
+ DBUG_ENTER("spider_free_ipport_conn");
+ if (info)
+ {
+ SPIDER_IP_PORT_CONN *p = (SPIDER_IP_PORT_CONN *)info;
+ pthread_cond_destroy(&p->cond);
+ pthread_mutex_destroy(&p->mutex);
+ spider_my_free(p->key, MYF(0));
+ spider_my_free(p, MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
diff --git a/storage/spider/spd_conn.h b/storage/spider/spd_conn.h
index cdcb6543a35..48c9d206d97 100644
--- a/storage/spider/spd_conn.h
+++ b/storage/spider/spd_conn.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2014 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define SPIDER_LOCK_MODE_NO_LOCK 0
#define SPIDER_LOCK_MODE_SHARED 1
@@ -28,6 +28,12 @@ uchar *spider_conn_get_key(
my_bool not_used __attribute__ ((unused))
);
+uchar *spider_ipport_conn_get_key(
+ SPIDER_IP_PORT_CONN *ip_port,
+ size_t *length,
+ my_bool not_used __attribute__ ((unused))
+);
+
int spider_reset_conn_setted_parameter(
SPIDER_CONN *conn,
THD *thd
@@ -315,6 +321,12 @@ int spider_conn_link_idx_next(
int link_status
);
+int spider_conn_get_link_status(
+ long *link_statuses,
+ uint *conn_link_idx,
+ int link_idx
+);
+
int spider_conn_lock_mode(
ha_spider *spider
);
@@ -334,3 +346,16 @@ bool spider_conn_need_open_handler(
uint idx,
int link_idx
);
+
+SPIDER_IP_PORT_CONN *spider_create_ipport_conn(SPIDER_CONN *conn);
+SPIDER_CONN* spider_get_conn_from_idle_connection
+(
+ SPIDER_SHARE *share,
+ int link_idx,
+ char *conn_key,
+ ha_spider *spider,
+ uint conn_kind,
+ int base_link_idx,
+ int *error_num
+ );
+void spider_free_ipport_conn(void *info);
diff --git a/storage/spider/spd_copy_tables.cc b/storage/spider/spd_copy_tables.cc
index 58ec690bd8d..97ad1c70631 100644
--- a/storage/spider/spd_copy_tables.cc
+++ b/storage/spider/spd_copy_tables.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009-2014 Kentoku Shiba
+/* Copyright (C) 2009-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -52,10 +53,10 @@ int spider_udf_set_copy_tables_param_default(
if (!copy_tables->database)
{
DBUG_PRINT("info",("spider create default database"));
- copy_tables->database_length = copy_tables->trx->thd->db_length;
+ copy_tables->database_length = copy_tables->trx->thd->db.length;
if (
!(copy_tables->database = spider_create_string(
- copy_tables->trx->thd->db,
+ copy_tables->trx->thd->db.str,
copy_tables->database_length))
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
@@ -977,28 +978,31 @@ long long spider_copy_tables_body(
goto error;
table_list = &copy_tables->spider_table_list;
- table_list->db = copy_tables->spider_db_name;
- table_list->db_length = copy_tables->spider_db_name_length;
- table_list->alias = table_list->table_name =
+ table_list->db.str = copy_tables->spider_db_name;
+ table_list->db.length = copy_tables->spider_db_name_length;
+ table_list->alias.str = table_list->table_name.str =
copy_tables->spider_real_table_name;
- table_list->table_name_length = copy_tables->spider_real_table_name_length;
+ table_list->table_name.length = copy_tables->spider_real_table_name_length;
+ table_list->alias.length= table_list->table_name.length;
table_list->lock_type = TL_READ;
- DBUG_PRINT("info",("spider db=%s", table_list->db));
- DBUG_PRINT("info",("spider db_length=%zd", table_list->db_length));
- DBUG_PRINT("info",("spider table_name=%s", table_list->table_name));
+ DBUG_PRINT("info",("spider db=%s", table_list->db.str));
+ DBUG_PRINT("info",("spider db_length=%zd", table_list->db.length));
+ DBUG_PRINT("info",("spider table_name=%s", table_list->table_name.str));
DBUG_PRINT("info",("spider table_name_length=%zd",
- table_list->table_name_length));
+ table_list->table_name.length));
reprepare_observer_backup = thd->m_reprepare_observer;
thd->m_reprepare_observer = NULL;
copy_tables->trx->trx_start = TRUE;
+ copy_tables->trx->updated_in_this_trx = FALSE;
+ DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
#if MYSQL_VERSION_ID < 50500
if (open_and_lock_tables(thd, table_list))
#else
table_list->mdl_request.init(
MDL_key::TABLE,
- table_list->db,
- table_list->table_name,
+ table_list->db.str,
+ table_list->table_name.str,
MDL_SHARED_READ,
MDL_TRANSACTION
);
@@ -1007,6 +1011,8 @@ long long spider_copy_tables_body(
{
thd->m_reprepare_observer = reprepare_observer_backup;
copy_tables->trx->trx_start = FALSE;
+ copy_tables->trx->updated_in_this_trx = FALSE;
+ DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
my_printf_error(ER_SPIDER_UDF_CANT_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_OPEN_TABLE_STR, MYF(0), table_list->db,
table_list->table_name);
@@ -1014,6 +1020,8 @@ long long spider_copy_tables_body(
}
thd->m_reprepare_observer = reprepare_observer_backup;
copy_tables->trx->trx_start = FALSE;
+ copy_tables->trx->updated_in_this_trx = FALSE;
+ DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
table = table_list->table;
table_share = table->s;
diff --git a/storage/spider/spd_copy_tables.h b/storage/spider/spd_copy_tables.h
index bac9b5d202c..bda7a051bc6 100644
--- a/storage/spider/spd_copy_tables.h
+++ b/storage/spider/spd_copy_tables.h
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
int spider_udf_set_copy_tables_param_default(
SPIDER_COPY_TABLES *copy_tables
diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc
index ab10ddcab86..3c1c0885617 100644
--- a/storage/spider/spd_db_conn.cc
+++ b/storage/spider/spd_db_conn.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -194,29 +195,24 @@ int spider_db_connect(
DBUG_RETURN(0);
}
-int spider_db_ping(
- ha_spider *spider,
+int spider_db_ping_internal(
+ SPIDER_SHARE *share,
SPIDER_CONN *conn,
- int link_idx
+ int all_link_idx,
+ int *need_mon
) {
int error_num;
- DBUG_ENTER("spider_db_ping");
-#ifndef DBUG_OFF
- if (spider->trx->thd)
- DBUG_PRINT("info", ("spider thd->query_id is %lld",
- spider->trx->thd->query_id));
-#endif
+ DBUG_ENTER("spider_db_ping_internal");
if (!conn->mta_conn_mutex_lock_already)
{
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
+ conn->need_mon = need_mon;
}
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
if (conn->server_lost || conn->queued_connect)
{
- if ((error_num = spider_db_connect(spider->share, conn,
- spider->conn_link_idx[link_idx])))
+ if ((error_num = spider_db_connect(share, conn, all_link_idx)))
{
if (!conn->mta_conn_mutex_unlock_later)
{
@@ -231,8 +227,7 @@ int spider_db_ping(
if ((error_num = conn->db_conn->ping()))
{
spider_db_disconnect(conn);
- if ((error_num = spider_db_connect(spider->share, conn,
- spider->conn_link_idx[link_idx])))
+ if ((error_num = spider_db_connect(share, conn, all_link_idx)))
{
DBUG_PRINT("info", ("spider conn=%p SERVER_LOST", conn));
conn->server_lost = TRUE;
@@ -265,6 +260,21 @@ int spider_db_ping(
DBUG_RETURN(0);
}
+int spider_db_ping(
+ ha_spider *spider,
+ SPIDER_CONN *conn,
+ int link_idx
+) {
+ DBUG_ENTER("spider_db_ping");
+#ifndef DBUG_OFF
+ if (spider->trx->thd)
+ DBUG_PRINT("info", ("spider thd->query_id is %lld",
+ spider->trx->thd->query_id));
+#endif
+ DBUG_RETURN(spider_db_ping_internal(spider->share, conn,
+ spider->conn_link_idx[link_idx], &spider->need_mons[link_idx]));
+}
+
void spider_db_disconnect(
SPIDER_CONN *conn
) {
@@ -735,11 +745,11 @@ int spider_db_errorno(
struct tm lt;
struct tm *l_time = localtime_r(&cur_time, &lt);
fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] "
- "to %ld: %d %s\n",
+ "to %lld: %d %s\n",
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
- (ulong) current_thd->thread_id, error_num,
- conn->db_conn->get_error());
+ (long long int) current_thd->thread_id, error_num,
+ conn->db_conn->get_error());
}
if (!conn->mta_conn_mutex_unlock_later)
{
@@ -756,11 +766,11 @@ int spider_db_errorno(
struct tm lt;
struct tm *l_time = localtime_r(&cur_time, &lt);
fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [ERROR SPIDER RESULT] "
- "to %ld: %d %s\n",
+ "to %lld: %d %s\n",
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
- (ulong) current_thd->thread_id, error_num,
- conn->db_conn->get_error());
+ (long long int) current_thd->thread_id, error_num,
+ conn->db_conn->get_error());
}
if (!conn->mta_conn_mutex_unlock_later)
{
@@ -805,7 +815,7 @@ int spider_db_errorno(
"to %ld: %d %s\n",
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
- current_thd->thread_id, conn->db_conn->get_errno(),
+ (ulong) current_thd->thread_id, conn->db_conn->get_errno(),
conn->db_conn->get_error());
}
*conn->need_mon = ER_SPIDER_HS_NUM;
@@ -953,6 +963,7 @@ int spider_db_query_with_set_names(
spider->trx,
spider->trx->thd,
share,
+ link_idx,
(uint32) share->monitoring_sid[link_idx],
share->table_name,
share->table_name_length,
@@ -986,6 +997,7 @@ int spider_db_query_with_set_names(
spider->trx,
spider->trx->thd,
share,
+ link_idx,
(uint32) share->monitoring_sid[link_idx],
share->table_name,
share->table_name_length,
@@ -1011,7 +1023,7 @@ int spider_db_query_for_bulk_update(
ha_spider *spider,
SPIDER_CONN *conn,
int link_idx,
- uint *dup_key_found
+ ha_rows *dup_key_found
) {
int error_num;
SPIDER_SHARE *share = spider->share;
@@ -1038,6 +1050,7 @@ int spider_db_query_for_bulk_update(
spider->trx,
spider->trx->thd,
share,
+ link_idx,
(uint32) share->monitoring_sid[link_idx],
share->table_name,
share->table_name_length,
@@ -1075,6 +1088,7 @@ int spider_db_query_for_bulk_update(
spider->trx,
spider->trx->thd,
share,
+ link_idx,
(uint32) share->monitoring_sid[link_idx],
share->table_name,
share->table_name_length,
@@ -1119,6 +1133,7 @@ int spider_db_query_for_bulk_update(
spider->trx,
spider->trx->thd,
share,
+ link_idx,
(uint32) share->monitoring_sid[link_idx],
share->table_name,
share->table_name_length,
@@ -1371,7 +1386,11 @@ int spider_db_append_name_with_quote_str(
for (name_end = name + length; name < name_end; name += length)
{
head_code = *name;
- if ((length= my_charlen(system_charset_info, name, name_end)) < 1)
+#ifdef SPIDER_HAS_MY_CHARLEN
+ if ((length = my_charlen(system_charset_info, name, name_end)) < 1)
+#else
+ if (!(length = my_mbcharlen(system_charset_info, (uchar) head_code)))
+#endif
{
my_message(ER_SPIDER_WRONG_CHARACTER_IN_NAME_NUM,
ER_SPIDER_WRONG_CHARACTER_IN_NAME_STR, MYF(0));
@@ -2937,9 +2956,16 @@ int spider_db_fetch_table(
}
#endif
- if ((error_num = spider_db_append_match_fetch(spider,
- spider->ft_first, spider->ft_current, row)))
- DBUG_RETURN(error_num);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ if (!spider->use_fields)
+ {
+#endif
+ if ((error_num = spider_db_append_match_fetch(spider,
+ spider->ft_first, spider->ft_current, row)))
+ DBUG_RETURN(error_num);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ }
+#endif
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
} else {
if (!(row = result_list->hs_result->fetch_row_from_result_buffer(
@@ -3179,6 +3205,10 @@ int spider_db_fetch_minimum_columns(
} else {
if (result_list->current_row_num < result_list->quick_page_size)
{
+ DBUG_PRINT("info", ("spider current=%p", current));
+ DBUG_PRINT("info", ("spider first_position=%p", current->first_position));
+ DBUG_PRINT("info", ("spider current_row_num=%lld", result_list->current_row_num));
+ DBUG_PRINT("info", ("spider first_position[]=%p", &current->first_position[result_list->current_row_num]));
row = current->first_position[result_list->current_row_num].row;
} else {
if ((error_num = spider_db_get_row_from_tmp_tbl(
@@ -3893,6 +3923,7 @@ int spider_db_store_result(
SPIDER_DB_ROW *row;
if (!(row = current->result->fetch_row()))
{
+ error_num = current->result->get_errno();
DBUG_PRINT("info",("spider set finish_flg point 3"));
DBUG_PRINT("info",("spider current->finish_flg = TRUE"));
DBUG_PRINT("info",("spider result_list->finish_flg = TRUE"));
@@ -3912,7 +3943,10 @@ int spider_db_store_result(
) {
result_list->current_row_num = 0;
table->status = STATUS_NOT_FOUND;
- } else if (result_list->quick_phase > 0)
+ }
+ if (error_num)
+ DBUG_RETURN(error_num);
+ else if (result_list->quick_phase > 0)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
@@ -4017,6 +4051,10 @@ int spider_db_store_result(
conn->quick_target = NULL;
spider->quick_targets[link_idx] = NULL;
}
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ DBUG_PRINT("info", ("spider bgs_phase=%d", result_list->bgs_phase));
+#endif
+ DBUG_PRINT("info", ("spider quick_phase=%d", result_list->quick_phase));
if (
#ifndef WITHOUT_SPIDER_BG_SEARCH
result_list->bgs_phase <= 1 &&
@@ -4025,6 +4063,12 @@ int spider_db_store_result(
) {
result_list->current_row_num = 0;
}
+ DBUG_PRINT("info", ("spider result_list->current=%p", result_list->current));
+ DBUG_PRINT("info", ("spider current=%p", current));
+ DBUG_PRINT("info", ("spider first_position=%p", current->first_position));
+ DBUG_PRINT("info", ("spider current_row_num=%lld", result_list->current_row_num));
+ DBUG_PRINT("info", ("spider first_position[]=%p", &current->first_position[result_list->current_row_num]));
+ DBUG_PRINT("info", ("spider row=%p", current->first_position[result_list->current_row_num].row));
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
} else {
@@ -4265,39 +4309,74 @@ int spider_db_seek_next(
spider_db_free_one_result(result_list,
(SPIDER_RESULT*) result_list->current);
- int roop_start, roop_end, roop_count, lock_mode, link_ok;
- lock_mode = spider_conn_lock_mode(spider);
- if (lock_mode)
+ int roop_start = 0, roop_end = 1, roop_count, lock_mode, link_ok = 0;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ if (!spider->use_fields)
{
- /* "for update" or "lock in share mode" */
- link_ok = spider_conn_link_idx_next(share->link_statuses,
- spider->conn_link_idx, -1, share->link_count,
- SPIDER_LINK_STATUS_OK);
- roop_start = spider_conn_link_idx_next(share->link_statuses,
- spider->conn_link_idx, -1, share->link_count,
- SPIDER_LINK_STATUS_RECOVERY);
- roop_end = spider->share->link_count;
- } else {
- link_ok = link_idx;
- roop_start = link_idx;
- roop_end = link_idx + 1;
+#endif
+ lock_mode = spider_conn_lock_mode(spider);
+ if (lock_mode)
+ {
+ /* "for update" or "lock in share mode" */
+ link_ok = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, -1, share->link_count,
+ SPIDER_LINK_STATUS_OK);
+ roop_start = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, -1, share->link_count,
+ SPIDER_LINK_STATUS_RECOVERY);
+ roop_end = spider->share->link_count;
+ } else {
+ link_ok = link_idx;
+ roop_start = link_idx;
+ roop_end = link_idx + 1;
+ }
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
}
+#endif
#ifndef WITHOUT_SPIDER_BG_SEARCH
if (result_list->bgs_phase > 0)
{
- for (roop_count = roop_start; roop_count < roop_end;
- roop_count = spider_conn_link_idx_next(share->link_statuses,
- spider->conn_link_idx, roop_count, share->link_count,
- SPIDER_LINK_STATUS_RECOVERY)
- ) {
- if ((error_num = spider_bg_conn_search(spider, roop_count, roop_start,
- FALSE, FALSE, (roop_count != link_ok))))
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ if (spider->use_fields)
+ {
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain;
+ SPIDER_LINK_IDX_HOLDER *link_idx_holder;
+ spider_fields *fields = spider->fields;
+ fields->set_pos_to_first_link_idx_chain();
+ while ((link_idx_chain = fields->get_next_link_idx_chain()))
{
- DBUG_PRINT("info",("spider error_num 1=%d", error_num));
- DBUG_RETURN(error_num);
+ conn = link_idx_chain->conn;
+ link_idx_holder = link_idx_chain->link_idx_holder;
+ spider_db_handler *dbton_hdl =
+ spider->dbton_handler[conn->dbton_id];
+ spider->link_idx_chain = link_idx_chain;
+ if ((error_num = spider_bg_conn_search(spider,
+ link_idx_holder->link_idx, dbton_hdl->first_link_idx,
+ FALSE, FALSE,
+ !fields->is_first_link_ok_chain(link_idx_chain))))
+ {
+ DBUG_PRINT("info",("spider error_num 1=%d", error_num));
+ DBUG_RETURN(error_num);
+ }
}
+ } else {
+#endif
+ for (roop_count = roop_start; roop_count < roop_end;
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, roop_count, share->link_count,
+ SPIDER_LINK_STATUS_RECOVERY)
+ ) {
+ if ((error_num = spider_bg_conn_search(spider, roop_count, roop_start,
+ FALSE, FALSE, (roop_count != link_ok))))
+ {
+ DBUG_PRINT("info",("spider error_num 1=%d", error_num));
+ DBUG_RETURN(error_num);
+ }
+ }
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
}
+#endif
} else {
#endif
if (result_list->current == result_list->bgs_current)
@@ -4349,113 +4428,142 @@ int spider_db_seek_next(
}
}
- for (roop_count = roop_start; roop_count < roop_end;
- roop_count = spider_conn_link_idx_next(share->link_statuses,
- spider->conn_link_idx, roop_count, share->link_count,
- SPIDER_LINK_STATUS_RECOVERY)
- ) {
- ulong sql_type;
- conn = spider->conns[roop_count];
- if (spider->sql_kind[roop_count] == SPIDER_SQL_KIND_SQL)
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ if (spider->use_fields)
+ {
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain;
+ SPIDER_LINK_IDX_HOLDER *link_idx_holder;
+ spider_fields *fields = spider->fields;
+ fields->set_pos_to_first_link_idx_chain();
+ while ((link_idx_chain = fields->get_next_link_idx_chain()))
{
+ ulong sql_type;
+ conn = link_idx_chain->conn;
sql_type = SPIDER_SQL_TYPE_SELECT_SQL;
- } else {
- sql_type = SPIDER_SQL_TYPE_HANDLER;
- }
- spider_db_handler *dbton_handler =
- spider->dbton_handler[conn->dbton_id];
- if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- }
- if ((error_num = dbton_handler->set_sql_for_exec(sql_type,
- roop_count)))
- {
- DBUG_PRINT("info",("spider error_num 6=%d", error_num));
- DBUG_RETURN(error_num);
- }
- if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- }
- conn->need_mon = &spider->need_mons[roop_count];
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
- if ((error_num = spider_db_set_names(spider, conn, roop_count)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- if (
- share->monitoring_kind[roop_count] &&
- spider->need_mons[roop_count]
+ link_idx_holder = link_idx_chain->link_idx_holder;
+ link_idx = link_idx_holder->link_idx;
+ spider_db_handler *dbton_handler =
+ spider->dbton_handler[conn->dbton_id];
+ if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ }
+ if ((error_num = dbton_handler->set_sql_for_exec(sql_type,
+ link_idx)))
+ {
+ DBUG_PRINT("info",("spider error_num 6=%d", error_num));
+ DBUG_RETURN(error_num);
+ }
+ if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ }
+ conn->need_mon = &spider->need_mons[link_idx];
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
+ if ((error_num = spider_db_set_names(spider, conn, link_idx)))
+ {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ if (
+ spider->need_mons[link_idx]
+ ) {
+ error_num = fields->ping_table_mon_from_table(link_idx_chain);
+ }
+ DBUG_PRINT("info",("spider error_num 7a=%d", error_num));
+ DBUG_RETURN(error_num);
+ }
+ spider_conn_set_timeout_from_share(conn, link_idx,
+ spider->trx->thd, share);
+ if (dbton_handler->execute_sql(
+ sql_type,
+ conn,
+ result_list->quick_mode,
+ &spider->need_mons[link_idx])
) {
- error_num = spider_ping_table_mon_from_table(
- spider->trx,
- spider->trx->thd,
- share,
- (uint32) share->monitoring_sid[roop_count],
- share->table_name,
- share->table_name_length,
- spider->conn_link_idx[roop_count],
- NULL,
- 0,
- share->monitoring_kind[roop_count],
- share->monitoring_limit[roop_count],
- share->monitoring_flag[roop_count],
- TRUE
- );
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ error_num = spider_db_errorno(conn);
+ if (
+ spider->need_mons[link_idx]
+ ) {
+ error_num = fields->ping_table_mon_from_table(link_idx_chain);
+ }
+ DBUG_PRINT("info",("spider error_num 8a=%d", error_num));
+ DBUG_RETURN(error_num);
}
- DBUG_PRINT("info",("spider error_num 7=%d", error_num));
- DBUG_RETURN(error_num);
- }
- spider_conn_set_timeout_from_share(conn, roop_count,
- spider->trx->thd, share);
- if (dbton_handler->execute_sql(
- sql_type,
- conn,
- result_list->quick_mode,
- &spider->need_mons[roop_count])
- ) {
+ spider->connection_ids[link_idx] = conn->connection_id;
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- error_num = spider_db_errorno(conn);
- if (
- share->monitoring_kind[roop_count] &&
- spider->need_mons[roop_count]
- ) {
- error_num = spider_ping_table_mon_from_table(
- spider->trx,
- spider->trx->thd,
- share,
- (uint32) share->monitoring_sid[roop_count],
- share->table_name,
- share->table_name_length,
- spider->conn_link_idx[roop_count],
- NULL,
- 0,
- share->monitoring_kind[roop_count],
- share->monitoring_limit[roop_count],
- share->monitoring_flag[roop_count],
- TRUE
- );
+ if (fields->is_first_link_ok_chain(link_idx_chain))
+ {
+ if ((error_num = spider_db_store_result(spider, link_idx,
+ table)))
+ {
+ if (
+ error_num != HA_ERR_END_OF_FILE &&
+ spider->need_mons[link_idx]
+ ) {
+ error_num =
+ fields->ping_table_mon_from_table(link_idx_chain);
+ }
+ DBUG_PRINT("info",("spider error_num 9a=%d", error_num));
+ DBUG_RETURN(error_num);
+ }
+ spider->result_link_idx = link_ok;
+ } else {
+ spider_db_discard_result(spider, link_idx, conn);
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
}
- DBUG_PRINT("info",("spider error_num 8=%d", error_num));
- DBUG_RETURN(error_num);
}
- spider->connection_ids[roop_count] = conn->connection_id;
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- if (roop_count == link_ok)
- {
- if ((error_num = spider_db_store_result(spider, roop_count,
- table)))
+ } else {
+#endif
+ for (roop_count = roop_start; roop_count < roop_end;
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, roop_count, share->link_count,
+ SPIDER_LINK_STATUS_RECOVERY)
+ ) {
+ ulong sql_type;
+ conn = spider->conns[roop_count];
+ if (spider->sql_kind[roop_count] == SPIDER_SQL_KIND_SQL)
+ {
+ sql_type = SPIDER_SQL_TYPE_SELECT_SQL;
+ } else {
+ sql_type = SPIDER_SQL_TYPE_HANDLER;
+ }
+ spider_db_handler *dbton_handler =
+ spider->dbton_handler[conn->dbton_id];
+ if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ }
+ if ((error_num = dbton_handler->set_sql_for_exec(sql_type,
+ roop_count)))
+ {
+ DBUG_PRINT("info",("spider error_num 6=%d", error_num));
+ DBUG_RETURN(error_num);
+ }
+ if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ }
+ conn->need_mon = &spider->need_mons[roop_count];
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
+ if ((error_num = spider_db_set_names(spider, conn, roop_count)))
+ {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
if (
- error_num != HA_ERR_END_OF_FILE &&
share->monitoring_kind[roop_count] &&
spider->need_mons[roop_count]
) {
@@ -4463,6 +4571,7 @@ int spider_db_seek_next(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4475,16 +4584,87 @@ int spider_db_seek_next(
TRUE
);
}
- DBUG_PRINT("info",("spider error_num 9=%d", error_num));
+ DBUG_PRINT("info",("spider error_num 7=%d", error_num));
DBUG_RETURN(error_num);
}
- spider->result_link_idx = link_ok;
- } else {
- spider_db_discard_result(spider, roop_count, conn);
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
+ spider_conn_set_timeout_from_share(conn, roop_count,
+ spider->trx->thd, share);
+ if (dbton_handler->execute_sql(
+ sql_type,
+ conn,
+ result_list->quick_mode,
+ &spider->need_mons[roop_count])
+ ) {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ error_num = spider_db_errorno(conn);
+ if (
+ share->monitoring_kind[roop_count] &&
+ spider->need_mons[roop_count]
+ ) {
+ error_num = spider_ping_table_mon_from_table(
+ spider->trx,
+ spider->trx->thd,
+ share,
+ roop_count,
+ (uint32) share->monitoring_sid[roop_count],
+ share->table_name,
+ share->table_name_length,
+ spider->conn_link_idx[roop_count],
+ NULL,
+ 0,
+ share->monitoring_kind[roop_count],
+ share->monitoring_limit[roop_count],
+ share->monitoring_flag[roop_count],
+ TRUE
+ );
+ }
+ DBUG_PRINT("info",("spider error_num 8=%d", error_num));
+ DBUG_RETURN(error_num);
+ }
+ spider->connection_ids[roop_count] = conn->connection_id;
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ if (roop_count == link_ok)
+ {
+ if ((error_num = spider_db_store_result(spider, roop_count,
+ table)))
+ {
+ if (
+ error_num != HA_ERR_END_OF_FILE &&
+ share->monitoring_kind[roop_count] &&
+ spider->need_mons[roop_count]
+ ) {
+ error_num = spider_ping_table_mon_from_table(
+ spider->trx,
+ spider->trx->thd,
+ share,
+ roop_count,
+ (uint32) share->monitoring_sid[roop_count],
+ share->table_name,
+ share->table_name_length,
+ spider->conn_link_idx[roop_count],
+ NULL,
+ 0,
+ share->monitoring_kind[roop_count],
+ share->monitoring_limit[roop_count],
+ share->monitoring_flag[roop_count],
+ TRUE
+ );
+ }
+ DBUG_PRINT("info",("spider error_num 9=%d", error_num));
+ DBUG_RETURN(error_num);
+ }
+ spider->result_link_idx = link_ok;
+ } else {
+ spider_db_discard_result(spider, roop_count, conn);
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
}
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
}
+#endif
} else {
spider->connection_ids[link_idx] = conn->connection_id;
conn->mta_conn_mutex_unlock_later = TRUE;
@@ -4645,6 +4825,7 @@ int spider_db_seek_last(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4678,6 +4859,7 @@ int spider_db_seek_last(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4708,6 +4890,7 @@ int spider_db_seek_last(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4845,6 +5028,7 @@ int spider_db_seek_last(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4878,6 +5062,7 @@ int spider_db_seek_last(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4908,6 +5093,7 @@ int spider_db_seek_last(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -5512,6 +5698,7 @@ int spider_db_bulk_insert_init(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -5682,6 +5869,7 @@ int spider_db_bulk_insert(
spider->trx,
spider->trx->thd,
share,
+ roop_count2,
(uint32) share->monitoring_sid[roop_count2],
share->table_name,
share->table_name_length,
@@ -5731,6 +5919,7 @@ int spider_db_bulk_insert(
spider->trx,
spider->trx->thd,
share,
+ roop_count2,
(uint32) share->monitoring_sid[roop_count2],
share->table_name,
share->table_name_length,
@@ -6100,7 +6289,7 @@ int spider_db_bulk_update_size_limit(
SPIDER_SHARE *share = spider->share;
SPIDER_RESULT_LIST *result_list = &spider->result_list;
SPIDER_CONN *conn;
- uint dup_key_found = 0;
+ ha_rows dup_key_found = 0;
DBUG_ENTER("spider_db_bulk_update_size_limit");
if (result_list->bulk_update_mode == 1)
@@ -6163,7 +6352,7 @@ error_mk_table:
int spider_db_bulk_update_end(
ha_spider *spider,
- uint *dup_key_found
+ ha_rows *dup_key_found
) {
int error_num = 0, error_num2, roop_count;
THD *thd = spider->trx->thd;
@@ -6377,6 +6566,7 @@ int spider_db_update(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6413,6 +6603,7 @@ int spider_db_update(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6465,6 +6656,7 @@ int spider_db_update(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6491,12 +6683,13 @@ int spider_db_update(
}
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int spider_db_direct_update(
ha_spider *spider,
TABLE *table,
KEY_MULTI_RANGE *ranges,
uint range_count,
- uint *update_rows
+ ha_rows *update_rows
) {
int error_num, roop_count;
SPIDER_SHARE *share = spider->share;
@@ -6706,6 +6899,7 @@ int spider_db_direct_update(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6745,6 +6939,7 @@ int spider_db_direct_update(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -6766,7 +6961,7 @@ int spider_db_direct_update(
if (!counted)
{
*update_rows = spider->conns[roop_count]->db_conn->affected_rows();
- DBUG_PRINT("info", ("spider update_rows = %u", *update_rows));
+ DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows));
counted = TRUE;
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -6787,7 +6982,7 @@ int spider_db_direct_update(
if (!counted)
{
*update_rows = conn->db_conn->affected_rows();
- DBUG_PRINT("info", ("spider update_rows = %u", *update_rows));
+ DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows));
counted = TRUE;
}
result->free_result();
@@ -6821,12 +7016,223 @@ int spider_db_direct_update(
#endif
DBUG_RETURN(0);
}
+#else
+int spider_db_direct_update(
+ ha_spider *spider,
+ TABLE *table,
+ ha_rows *update_rows
+) {
+ int error_num, roop_count;
+ SPIDER_SHARE *share = spider->share;
+ SPIDER_CONN *conn;
+ SPIDER_RESULT_LIST *result_list = &spider->result_list;
+ bool counted = FALSE;
+ st_select_lex *select_lex;
+ longlong select_limit;
+ longlong offset_limit;
+ DBUG_ENTER("spider_db_direct_update");
+
+ spider_set_result_list_param(spider);
+ result_list->finish_flg = FALSE;
+ DBUG_PRINT("info", ("spider do_direct_update=%s",
+ spider->do_direct_update ? "TRUE" : "FALSE"));
+ DBUG_PRINT("info", ("spider direct_update_kinds=%u",
+ spider->direct_update_kinds));
+ if ((error_num = spider->append_update_sql_part()))
+ DBUG_RETURN(error_num);
+
+/*
+ SQL access -> SQL remote access
+ !spider->do_direct_update &&
+ (spider->sql_kinds & SPIDER_SQL_KIND_SQL)
+
+ SQL access -> SQL remote access with dirct_update
+ spider->do_direct_update &&
+ spider->direct_update_kinds == SPIDER_SQL_KIND_SQL &&
+ spider->direct_update_fields
+*/
+
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+ if (!spider->do_direct_update)
+ {
+#endif
+ if (
+ (spider->sql_kinds & SPIDER_SQL_KIND_SQL) &&
+ (error_num = spider->append_update_set_sql_part())
+ ) {
+ DBUG_RETURN(error_num);
+ }
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+ } else {
+ if (
+ (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL) &&
+ (error_num = spider->append_direct_update_set_sql_part())
+ ) {
+ DBUG_RETURN(error_num);
+ }
+ }
+#endif
+
+ result_list->desc_flg = FALSE;
+ result_list->sorted = TRUE;
+ if (spider->active_index == MAX_KEY)
+ result_list->key_info = NULL;
+ else
+ result_list->key_info = &table->key_info[spider->active_index];
+ spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit);
+ result_list->limit_num =
+ result_list->internal_limit >= select_limit ?
+ select_limit : result_list->internal_limit;
+ result_list->internal_offset += offset_limit;
+ if (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL)
+ {
+ if (
+ (error_num = spider->append_key_where_sql_part(
+ NULL,
+ NULL,
+ SPIDER_SQL_TYPE_UPDATE_SQL)) ||
+ (error_num = spider->
+ append_key_order_for_direct_order_limit_with_alias_sql_part(
+ NULL, 0, SPIDER_SQL_TYPE_UPDATE_SQL)) ||
+ (error_num = spider->append_limit_sql_part(
+ result_list->internal_offset, result_list->limit_num,
+ SPIDER_SQL_TYPE_UPDATE_SQL))
+ ) {
+ DBUG_RETURN(error_num);
+ }
+ }
+
+ for (
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, -1, share->link_count,
+ SPIDER_LINK_STATUS_RECOVERY);
+ roop_count < (int) share->link_count;
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, roop_count, share->link_count,
+ SPIDER_LINK_STATUS_RECOVERY)
+ ) {
+ ulong sql_type;
+ DBUG_PRINT("info", ("spider exec sql"));
+ conn = spider->conns[roop_count];
+ sql_type = SPIDER_SQL_TYPE_UPDATE_SQL;
+ spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ }
+ if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ }
+#ifdef HA_CAN_BULK_ACCESS
+ if (spider->is_bulk_access_clone)
+ {
+ spider->connection_ids[roop_count] = conn->connection_id;
+ spider_trx_add_bulk_access_conn(spider->trx, conn);
+ } else {
+#endif
+ conn->need_mon = &spider->need_mons[roop_count];
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
+ if ((error_num = spider_db_set_names(spider, conn, roop_count)))
+ {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ if (
+ share->monitoring_kind[roop_count] &&
+ spider->need_mons[roop_count]
+ ) {
+ error_num = spider_ping_table_mon_from_table(
+ spider->trx,
+ spider->trx->thd,
+ share,
+ roop_count,
+ (uint32) share->monitoring_sid[roop_count],
+ share->table_name,
+ share->table_name_length,
+ spider->conn_link_idx[roop_count],
+ NULL,
+ 0,
+ share->monitoring_kind[roop_count],
+ share->monitoring_limit[roop_count],
+ share->monitoring_flag[roop_count],
+ TRUE
+ );
+ }
+ DBUG_RETURN(error_num);
+ }
+ spider_conn_set_timeout_from_share(conn, roop_count, spider->trx->thd,
+ share);
+ if (
+ (error_num = dbton_hdl->execute_sql(
+ sql_type,
+ conn,
+ -1,
+ &spider->need_mons[roop_count])
+ ) &&
+ (error_num != HA_ERR_FOUND_DUPP_KEY || !spider->ignore_dup_key)
+ ) {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ error_num = spider_db_errorno(conn);
+ if (
+ error_num != ER_DUP_ENTRY &&
+ error_num != ER_DUP_KEY &&
+ error_num != HA_ERR_FOUND_DUPP_KEY &&
+ share->monitoring_kind[roop_count] &&
+ spider->need_mons[roop_count]
+ ) {
+ error_num = spider_ping_table_mon_from_table(
+ spider->trx,
+ spider->trx->thd,
+ share,
+ roop_count,
+ (uint32) share->monitoring_sid[roop_count],
+ share->table_name,
+ share->table_name_length,
+ spider->conn_link_idx[roop_count],
+ NULL,
+ 0,
+ share->monitoring_kind[roop_count],
+ share->monitoring_limit[roop_count],
+ share->monitoring_flag[roop_count],
+ TRUE
+ );
+ }
+ DBUG_RETURN(error_num);
+ }
+ if (!counted)
+ {
+ *update_rows = spider->conns[roop_count]->db_conn->affected_rows();
+ DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows));
+ counted = TRUE;
+ }
+#ifdef HA_CAN_BULK_ACCESS
+ }
+#endif
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
+ spider->reset_sql_sql(SPIDER_SQL_TYPE_UPDATE_SQL);
+ DBUG_RETURN(0);
+}
+#endif
#endif
#ifdef HA_CAN_BULK_ACCESS
int spider_db_bulk_direct_update(
ha_spider *spider,
- uint *update_rows
+ ha_rows *update_rows
) {
int error_num = 0, roop_count, tmp_error_num;
SPIDER_SHARE *share = spider->share;
@@ -6870,7 +7276,7 @@ int spider_db_bulk_direct_update(
if (!counted)
{
*update_rows = spider->conns[roop_count]->db_conn->affected_rows();
- DBUG_PRINT("info", ("spider update_rows = %u", *update_rows));
+ DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows));
counted = TRUE;
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -6891,7 +7297,7 @@ int spider_db_bulk_direct_update(
if (!counted)
{
*update_rows = conn->db_conn->affected_rows();
- DBUG_PRINT("info", ("spider update_rows = %u", *update_rows));
+ DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows));
counted = TRUE;
}
result->free_result();
@@ -6995,12 +7401,13 @@ int spider_db_delete(
}
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int spider_db_direct_delete(
ha_spider *spider,
TABLE *table,
KEY_MULTI_RANGE *ranges,
uint range_count,
- uint *delete_rows
+ ha_rows *delete_rows
) {
int error_num, roop_count;
SPIDER_SHARE *share = spider->share;
@@ -7134,6 +7541,7 @@ int spider_db_direct_delete(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7167,6 +7575,7 @@ int spider_db_direct_delete(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7190,7 +7599,7 @@ int spider_db_direct_delete(
if (!counted)
{
*delete_rows = spider->conns[roop_count]->db_conn->affected_rows();
- DBUG_PRINT("info", ("spider delete_rows = %u", *delete_rows));
+ DBUG_PRINT("info", ("spider delete_rows = %llu", *delete_rows));
counted = TRUE;
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -7211,7 +7620,7 @@ int spider_db_direct_delete(
if (!counted)
{
*delete_rows = conn->db_conn->affected_rows();
- DBUG_PRINT("info", ("spider delete_rows = %u", *delete_rows));
+ DBUG_PRINT("info", ("spider delete_rows = %llu", *delete_rows));
counted = TRUE;
}
result->free_result();
@@ -7248,6 +7657,184 @@ int spider_db_direct_delete(
#endif
DBUG_RETURN(error_num2);
}
+#else
+int spider_db_direct_delete(
+ ha_spider *spider,
+ TABLE *table,
+ ha_rows *delete_rows
+) {
+ int error_num, roop_count;
+ SPIDER_SHARE *share = spider->share;
+ SPIDER_CONN *conn;
+ SPIDER_RESULT_LIST *result_list = &spider->result_list;
+ bool counted = FALSE;
+ st_select_lex *select_lex;
+ longlong select_limit;
+ longlong offset_limit;
+ DBUG_ENTER("spider_db_direct_delete");
+
+ spider_set_result_list_param(spider);
+ result_list->finish_flg = FALSE;
+ result_list->desc_flg = FALSE;
+ result_list->sorted = TRUE;
+ if (spider->active_index == MAX_KEY)
+ result_list->key_info = NULL;
+ else
+ result_list->key_info = &table->key_info[spider->active_index];
+ spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit);
+ result_list->limit_num =
+ result_list->internal_limit >= select_limit ?
+ select_limit : result_list->internal_limit;
+ result_list->internal_offset += offset_limit;
+ if (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL)
+ {
+ if (
+ (error_num = spider->append_delete_sql_part()) ||
+ (error_num = spider->append_from_sql_part(SPIDER_SQL_TYPE_DELETE_SQL))
+ ) {
+ DBUG_RETURN(error_num);
+ }
+ spider->set_where_pos_sql(SPIDER_SQL_TYPE_DELETE_SQL);
+ if (
+ (error_num = spider->append_key_where_sql_part(
+ NULL,
+ NULL,
+ SPIDER_SQL_TYPE_DELETE_SQL)) ||
+ (error_num = spider->
+ append_key_order_for_direct_order_limit_with_alias_sql_part(
+ NULL, 0, SPIDER_SQL_TYPE_DELETE_SQL)) ||
+ (error_num = spider->append_limit_sql_part(
+ result_list->internal_offset, result_list->limit_num,
+ SPIDER_SQL_TYPE_DELETE_SQL))
+ ) {
+ DBUG_RETURN(error_num);
+ }
+ }
+
+ for (
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, -1, share->link_count,
+ SPIDER_LINK_STATUS_RECOVERY);
+ roop_count < (int) share->link_count;
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, roop_count, share->link_count,
+ SPIDER_LINK_STATUS_RECOVERY)
+ ) {
+ ulong sql_type;
+ DBUG_PRINT("info", ("spider exec sql"));
+ conn = spider->conns[roop_count];
+ sql_type = SPIDER_SQL_TYPE_DELETE_SQL;
+ spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ }
+ if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ }
+#ifdef HA_CAN_BULK_ACCESS
+ if (spider->is_bulk_access_clone)
+ {
+ spider->connection_ids[roop_count] = conn->connection_id;
+ spider_trx_add_bulk_access_conn(spider->trx, conn);
+ } else {
+#endif
+ conn->need_mon = &spider->need_mons[roop_count];
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
+ if ((error_num = spider_db_set_names(spider, conn, roop_count)))
+ {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ if (
+ share->monitoring_kind[roop_count] &&
+ spider->need_mons[roop_count]
+ ) {
+ error_num = spider_ping_table_mon_from_table(
+ spider->trx,
+ spider->trx->thd,
+ share,
+ roop_count,
+ (uint32) share->monitoring_sid[roop_count],
+ share->table_name,
+ share->table_name_length,
+ spider->conn_link_idx[roop_count],
+ NULL,
+ 0,
+ share->monitoring_kind[roop_count],
+ share->monitoring_limit[roop_count],
+ share->monitoring_flag[roop_count],
+ TRUE
+ );
+ }
+ DBUG_RETURN(error_num);
+ }
+ spider_conn_set_timeout_from_share(conn, roop_count, spider->trx->thd,
+ share);
+ if (dbton_hdl->execute_sql(
+ sql_type,
+ conn,
+ -1,
+ &spider->need_mons[roop_count])
+ ) {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ error_num = spider_db_errorno(conn);
+ if (
+ share->monitoring_kind[roop_count] &&
+ spider->need_mons[roop_count]
+ ) {
+ error_num = spider_ping_table_mon_from_table(
+ spider->trx,
+ spider->trx->thd,
+ share,
+ roop_count,
+ (uint32) share->monitoring_sid[roop_count],
+ share->table_name,
+ share->table_name_length,
+ spider->conn_link_idx[roop_count],
+ NULL,
+ 0,
+ share->monitoring_kind[roop_count],
+ share->monitoring_limit[roop_count],
+ share->monitoring_flag[roop_count],
+ TRUE
+ );
+ }
+ DBUG_RETURN(error_num);
+ }
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ if (!counted)
+ {
+ *delete_rows = spider->conns[roop_count]->db_conn->affected_rows();
+ DBUG_PRINT("info", ("spider delete_rows = %llu", *delete_rows));
+ counted = TRUE;
+ }
+#ifdef HA_CAN_BULK_ACCESS
+ }
+#endif
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
+ int error_num2 = 0;
+ if (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL)
+ {
+ if ((error_num = spider->reset_sql_sql(SPIDER_SQL_TYPE_DELETE_SQL)))
+ error_num2 = error_num;
+ }
+ DBUG_RETURN(error_num2);
+}
+#endif
#endif
int spider_db_delete_all_rows(
@@ -7325,6 +7912,7 @@ int spider_db_delete_all_rows(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7353,6 +7941,7 @@ int spider_db_delete_all_rows(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7386,6 +7975,7 @@ int spider_db_delete_all_rows(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7413,6 +8003,7 @@ int spider_db_delete_all_rows(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7471,6 +8062,7 @@ int spider_db_disable_keys(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7523,6 +8115,7 @@ int spider_db_enable_keys(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7576,6 +8169,7 @@ int spider_db_check_table(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7629,6 +8223,7 @@ int spider_db_repair_table(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7681,6 +8276,7 @@ int spider_db_analyze_table(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7733,6 +8329,7 @@ int spider_db_optimize_table(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7782,6 +8379,7 @@ int spider_db_flush_tables(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7829,6 +8427,7 @@ int spider_db_flush_logs(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -7853,7 +8452,9 @@ int spider_db_print_item_type(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
DBUG_ENTER("spider_db_print_item_type");
DBUG_PRINT("info",("spider COND type=%d", item->type()));
@@ -7861,38 +8462,38 @@ int spider_db_print_item_type(
{
case Item::FUNC_ITEM:
DBUG_RETURN(spider_db_open_item_func((Item_func *) item, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
case Item::SUM_FUNC_ITEM:
DBUG_RETURN(spider_db_open_item_sum_func((Item_sum *)item, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
#endif
case Item::COND_ITEM:
DBUG_RETURN(spider_db_open_item_cond((Item_cond *) item, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item::FIELD_ITEM:
DBUG_RETURN(spider_db_open_item_field((Item_field *) item, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item::REF_ITEM:
DBUG_RETURN(spider_db_open_item_ref((Item_ref *) item, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item::ROW_ITEM:
DBUG_RETURN(spider_db_open_item_row((Item_row *) item, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item::STRING_ITEM:
DBUG_RETURN(spider_db_open_item_string(item, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item::INT_ITEM:
case Item::REAL_ITEM:
case Item::DECIMAL_ITEM:
DBUG_RETURN(spider_db_open_item_int(item, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item::CACHE_ITEM:
DBUG_RETURN(spider_db_open_item_cache((Item_cache *)item, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item::INSERT_VALUE_ITEM:
- DBUG_RETURN(spider_db_open_item_insert_value((Item_insert_value *)item, spider, str,
- alias, alias_length, dbton_id));
+ DBUG_RETURN(spider_db_open_item_insert_value((Item_insert_value *)item,
+ spider, str, alias, alias_length, dbton_id, use_fields, fields));
case Item::SUBSELECT_ITEM:
case Item::TRIGGER_FIELD_ITEM:
#ifdef SPIDER_HAS_EXPR_CACHE_ITEM
@@ -7930,7 +8531,9 @@ int spider_db_open_item_cond(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
int error_num = 0;
List_iterator_fast<Item> lif(*(item_cond->argument_list()));
@@ -7951,7 +8554,7 @@ restart_first:
if (str)
restart_pos = str->length();
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
{
if (
str &&
@@ -7985,7 +8588,7 @@ restart_first:
}
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
{
if (
str &&
@@ -8013,11 +8616,13 @@ int spider_db_open_item_func(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
DBUG_ENTER("spider_db_open_item_func");
DBUG_RETURN(spider_dbton[dbton_id].db_util->open_item_func(
- item_func, spider, str, alias, alias_length));
+ item_func, spider, str, alias, alias_length, use_fields, fields));
}
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
@@ -8027,11 +8632,13 @@ int spider_db_open_item_sum_func(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
DBUG_ENTER("spider_db_open_item_func");
DBUG_RETURN(spider_dbton[dbton_id].db_util->open_item_sum_func(
- item_sum, spider, str, alias, alias_length));
+ item_sum, spider, str, alias, alias_length, use_fields, fields));
}
#endif
@@ -8041,7 +8648,9 @@ int spider_db_open_item_ident(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
int error_num, field_name_length;
SPIDER_SHARE *share = spider->share;
@@ -8052,15 +8661,37 @@ int spider_db_open_item_ident(
) {
Field *field = item_ident->cached_table->table->field[
item_ident->cached_field_index];
- if (!(field = spider->field_exchange(field)))
- DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
DBUG_PRINT("info",("spider use cached_field_index"));
- if (str)
+ if (!use_fields)
{
- if ((error_num = share->dbton_share[dbton_id]->
- append_column_name_with_alias(str, field->field_index,
- alias, alias_length)))
- DBUG_RETURN(error_num);
+ if (!(field = spider->field_exchange(field)))
+ DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
+ if (str)
+ {
+ if ((error_num = share->dbton_share[dbton_id]->
+ append_column_name_with_alias(str, field->field_index,
+ alias, alias_length)))
+ DBUG_RETURN(error_num);
+ }
+ } else {
+ if (str)
+ {
+ SPIDER_FIELD_CHAIN *field_chain = fields->get_next_field_chain();
+ SPIDER_FIELD_HOLDER *field_holder = field_chain->field_holder;
+ spider = field_holder->spider;
+ share = spider->share;
+ field = spider->field_exchange(field);
+ DBUG_ASSERT(field);
+ if ((error_num = share->dbton_share[dbton_id]->
+ append_column_name_with_alias(str, field->field_index,
+ field_holder->alias->ptr(), field_holder->alias->length())))
+ DBUG_RETURN(error_num);
+ } else {
+ if ((error_num = fields->add_field(field)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ }
}
DBUG_RETURN(0);
}
@@ -8101,31 +8732,60 @@ int spider_db_open_item_field(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
int error_num;
Field *field = item_field->field;
SPIDER_SHARE *share = spider->share;
DBUG_ENTER("spider_db_open_item_field");
- if (field)
+ if (field && !field->table->const_table)
{
DBUG_PRINT("info",("spider field=%p", field));
- if (!(field = spider->field_exchange(field)))
- DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
- if (field->table->const_table)
+ DBUG_PRINT("info",("spider db=%s", field->table->s->db.str));
+ DBUG_PRINT("info",("spider table_name=%s", field->table->s->table_name.str));
+ DBUG_PRINT("info",("spider tmp_table=%u", field->table->s->tmp_table));
+ if (field->table->s->tmp_table != INTERNAL_TMP_TABLE)
{
- if (str)
+ if (!use_fields)
{
- if ((error_num = share->dbton_share[dbton_id]->
- append_column_name_with_alias(str, field->field_index,
- alias, alias_length)))
- DBUG_RETURN(error_num);
+ if (!(field = spider->field_exchange(field)))
+ DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
+ if (str)
+ {
+ if ((error_num = share->dbton_share[dbton_id]->
+ append_column_name_with_alias(str, field->field_index,
+ alias, alias_length)))
+ DBUG_RETURN(error_num);
+ }
+ DBUG_RETURN(0);
+ } else {
+ if (str)
+ {
+ SPIDER_FIELD_CHAIN *field_chain = fields->get_next_field_chain();
+ SPIDER_FIELD_HOLDER *field_holder = field_chain->field_holder;
+ spider = field_holder->spider;
+ share = spider->share;
+ field = spider->field_exchange(field);
+ DBUG_ASSERT(field);
+ if ((error_num = share->dbton_share[dbton_id]->
+ append_column_name_with_alias(str, field->field_index,
+ field_holder->alias->ptr(), field_holder->alias->length())))
+ DBUG_RETURN(error_num);
+ } else {
+ if ((error_num = fields->add_field(field)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ }
+ DBUG_RETURN(0);
}
- DBUG_RETURN(0);
}
}
DBUG_RETURN(spider_db_open_item_ident(
- (Item_ident *) item_field, spider, str, alias, alias_length, dbton_id));
+ (Item_ident *) item_field, spider, str, alias, alias_length, dbton_id,
+ use_fields, fields));
}
int spider_db_open_item_ref(
@@ -8134,7 +8794,9 @@ int spider_db_open_item_ref(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
int error_num;
DBUG_ENTER("spider_db_open_item_ref");
@@ -8163,10 +8825,10 @@ int spider_db_open_item_ref(
DBUG_RETURN(0);
}
DBUG_RETURN(spider_db_print_item_type(*(item_ref->ref), spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
}
DBUG_RETURN(spider_db_open_item_ident((Item_ident *) item_ref, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
}
int spider_db_open_item_row(
@@ -8175,7 +8837,9 @@ int spider_db_open_item_row(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
int error_num;
uint roop_count, cols = item_row->cols() - 1;
@@ -8191,7 +8855,7 @@ int spider_db_open_item_row(
{
item = item_row->element_index(roop_count);
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -8202,7 +8866,7 @@ int spider_db_open_item_row(
}
item = item_row->element_index(roop_count);
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -8220,7 +8884,9 @@ int spider_db_open_item_string(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
DBUG_ENTER("spider_db_open_item_string");
if (str)
@@ -8257,7 +8923,9 @@ int spider_db_open_item_int(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
DBUG_ENTER("spider_db_open_item_int");
if (str)
@@ -8295,7 +8963,9 @@ int spider_db_open_item_cache(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
DBUG_ENTER("spider_db_open_item_cache");
if (!item_cache->const_item())
@@ -8305,7 +8975,7 @@ int spider_db_open_item_cache(
{
case STRING_RESULT:
DBUG_RETURN(spider_db_open_item_string(item_cache, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case ROW_RESULT:
{
int error_num;
@@ -8321,7 +8991,7 @@ int spider_db_open_item_cache(
{
if ((error_num = spider_db_open_item_cache(
(Item_cache *) item_cache_row->element_index(roop_count),
- spider, str, alias, alias_length, dbton_id
+ spider, str, alias, alias_length, dbton_id, use_fields, fields
))) {
DBUG_RETURN(error_num);
}
@@ -8334,7 +9004,7 @@ int spider_db_open_item_cache(
}
if ((error_num = spider_db_open_item_cache(
(Item_cache *) item_cache_row->element_index(roop_count),
- spider, str, alias, alias_length, dbton_id
+ spider, str, alias, alias_length, dbton_id, use_fields, fields
))) {
DBUG_RETURN(error_num);
}
@@ -8354,7 +9024,7 @@ int spider_db_open_item_cache(
break;
}
DBUG_RETURN(spider_db_open_item_int(item_cache, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
}
int spider_db_open_item_insert_value(
@@ -8363,7 +9033,9 @@ int spider_db_open_item_insert_value(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
int error_num;
DBUG_ENTER("spider_db_open_item_insert_value");
@@ -8377,7 +9049,7 @@ int spider_db_open_item_insert_value(
str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN);
}
if ((error_num = spider_db_print_item_type(item_insert_value->arg, spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -8428,7 +9100,9 @@ int spider_db_append_update_columns(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
) {
int error_num;
bool add_comma = FALSE;
@@ -8440,7 +9114,8 @@ int spider_db_append_update_columns(
{
value = vi++;
if ((error_num = spider_db_print_item_type(
- (Item *) field, spider, str, alias, alias_length, dbton_id)))
+ (Item *) field, spider, str, alias, alias_length, dbton_id,
+ use_fields, fields)))
{
if (
error_num == ER_SPIDER_COND_SKIP_NUM &&
@@ -8459,7 +9134,8 @@ int spider_db_append_update_columns(
str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN);
}
if ((error_num = spider_db_print_item_type(
- (Item *) value, spider, str, alias, alias_length, dbton_id)))
+ (Item *) value, spider, str, alias, alias_length, dbton_id,
+ use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -9300,18 +9976,19 @@ int spider_db_udf_ping_table(
{
int init_sql_alloc_size =
spider_param_init_sql_alloc_size(trx->thd, share->init_sql_alloc_size);
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_string sql_str(init_sql_alloc_size);
- sql_str.set_charset(system_charset_info);
- spider_string where_str(init_sql_alloc_size);
- where_str.set_charset(system_charset_info);
-#else
- char sql_buf[init_sql_alloc_size], where_buf[init_sql_alloc_size];
+ char *sql_buf = (char *) my_alloca(init_sql_alloc_size * 2);
+ if (!sql_buf)
+ {
+ table_mon_list->last_mon_result = HA_ERR_OUT_OF_MEM;
+ pthread_mutex_unlock(&table_mon_list->monitor_mutex);
+ my_error(HA_ERR_OUT_OF_MEM, MYF(0));
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ char *where_buf = sql_buf + init_sql_alloc_size;
spider_string sql_str(sql_buf, sizeof(sql_buf),
system_charset_info);
spider_string where_str(where_buf, sizeof(where_buf),
system_charset_info);
-#endif
sql_str.init_calc_mem(128);
where_str.init_calc_mem(129);
sql_str.length(0);
@@ -9324,6 +10001,7 @@ int spider_db_udf_ping_table(
table_mon_list->last_mon_result = HA_ERR_OUT_OF_MEM;
pthread_mutex_unlock(&table_mon_list->monitor_mutex);
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
+ my_afree(sql_buf);
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
share->access_charset = system_charset_info;
@@ -9333,6 +10011,7 @@ int spider_db_udf_ping_table(
table_mon_list->last_mon_result = error_num;
pthread_mutex_unlock(&table_mon_list->monitor_mutex);
my_error(error_num, MYF(0));
+ my_afree(sql_buf);
DBUG_RETURN(error_num);
}
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -9349,6 +10028,7 @@ int spider_db_udf_ping_table(
table_mon_list->last_mon_result = error_num;
pthread_mutex_unlock(&table_mon_list->monitor_mutex);
DBUG_PRINT("info",("spider error_num=%d", error_num));
+ my_afree(sql_buf);
DBUG_RETURN(error_num);
}
spider_conn_set_timeout_from_share(conn, 0, trx->thd, share);
@@ -9365,6 +10045,7 @@ int spider_db_udf_ping_table(
table_mon_list->last_mon_result = error_num;
pthread_mutex_unlock(&table_mon_list->monitor_mutex);
DBUG_PRINT("info",("spider error_num=%d", error_num));
+ my_afree(sql_buf);
DBUG_RETURN(error_num);
}
conn->mta_conn_mutex_lock_already = FALSE;
@@ -9372,6 +10053,7 @@ int spider_db_udf_ping_table(
spider_db_discard_result(&spider, 0, conn);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
+ my_afree(sql_buf);
}
table_mon_list->last_mon_result = 0;
pthread_mutex_unlock(&table_mon_list->monitor_mutex);
@@ -9390,6 +10072,8 @@ int spider_db_udf_ping_table_append_mon_next(
char *child_table_name,
uint child_table_name_length,
int link_id,
+ char *static_link_id,
+ uint static_link_id_length,
char *where_clause,
uint where_clause_length,
longlong first_sid,
@@ -9417,7 +10101,13 @@ int spider_db_udf_ping_table_append_mon_next(
SPIDER_SQL_SELECT_LEN +
SPIDER_SQL_PING_TABLE_LEN +
(child_table_name_length * 2) +
- (SPIDER_SQL_INT_LEN * 6) +
+ (
+ static_link_id ?
+ (SPIDER_SQL_INT_LEN * 5) +
+ (SPIDER_SQL_VALUE_QUOTE_LEN * 2) +
+ (static_link_id_length * 2) :
+ (SPIDER_SQL_INT_LEN * 6)
+ ) +
sid_str_length +
limit_str_length +
(where_clause_length * 2) +
@@ -9432,7 +10122,14 @@ int spider_db_udf_ping_table_append_mon_next(
str->append_escape_string(child_table_name_str.ptr(), child_table_name_str.length());
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
- str->qs_append(link_id);
+ if (static_link_id)
+ {
+ str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ str->append_for_single_quote(static_link_id, static_link_id_length);
+ str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ } else {
+ str->qs_append(link_id);
+ }
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
str->qs_append(flags);
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
@@ -9523,17 +10220,17 @@ int spider_db_udf_ping_table_mon_next(
SPIDER_SHARE *share = table_mon->share;
int init_sql_alloc_size =
spider_param_init_sql_alloc_size(thd, share->init_sql_alloc_size);
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_string sql_str(init_sql_alloc_size);
- sql_str.set_charset(thd->variables.character_set_client);
-#else
- char sql_buf[init_sql_alloc_size];
- spider_string sql_str(sql_buf, sizeof(sql_buf),
- thd->variables.character_set_client);
-#endif
ha_spider spider;
SPIDER_TRX trx;
DBUG_ENTER("spider_db_udf_ping_table_mon_next");
+ char *sql_buf = (char *) my_alloca(init_sql_alloc_size);
+ if (!sql_buf)
+ {
+ my_error(HA_ERR_OUT_OF_MEM, MYF(0));
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ spider_string sql_str(sql_buf, sizeof(sql_buf),
+ thd->variables.character_set_client);
sql_str.init_calc_mem(132);
sql_str.length(0);
trx.thd = thd;
@@ -9544,11 +10241,15 @@ int spider_db_udf_ping_table_mon_next(
share->access_charset = thd->variables.character_set_client;
if ((error_num = spider_db_udf_ping_table_append_mon_next(&sql_str,
- child_table_name, child_table_name_length, link_id, where_clause,
+ child_table_name, child_table_name_length, link_id,
+ table_mon->parent->share->static_link_ids[0],
+ table_mon->parent->share->static_link_ids_lengths[0],
+ where_clause,
where_clause_length, first_sid, full_mon_count, current_mon_count,
success_count, fault_count, flags, limit)))
{
my_error(error_num, MYF(0));
+ my_afree(sql_buf);
DBUG_RETURN(error_num);
}
@@ -9565,6 +10266,7 @@ int spider_db_udf_ping_table_mon_next(
pthread_mutex_unlock(&conn->mta_conn_mutex);
my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0),
share->server_names[0]);
+ my_afree(sql_buf);
DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE);
}
if ((error_num = spider_db_set_names(&spider, conn, 0)))
@@ -9573,6 +10275,7 @@ int spider_db_udf_ping_table_mon_next(
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
+ my_afree(sql_buf);
DBUG_RETURN(error_num);
}
spider_conn_set_timeout_from_share(conn, 0, thd, share);
@@ -9585,6 +10288,7 @@ int spider_db_udf_ping_table_mon_next(
) {
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
+ my_afree(sql_buf);
DBUG_RETURN(spider_db_errorno(conn));
}
st_spider_db_request_key request_key;
@@ -9598,14 +10302,19 @@ int spider_db_udf_ping_table_mon_next(
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (error_num || (error_num = spider_db_errorno(conn)))
+ {
+ my_afree(sql_buf);
DBUG_RETURN(error_num);
+ }
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
+ my_afree(sql_buf);
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
+ my_afree(sql_buf);
error_num = res->fetch_table_mon_status(mon_table_result->result_status);
res->free_result();
delete res;
diff --git a/storage/spider/spd_db_conn.h b/storage/spider/spd_db_conn.h
index 6d149f6d4a0..7977e61da58 100644
--- a/storage/spider/spd_db_conn.h
+++ b/storage/spider/spd_db_conn.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define SPIDER_DB_WRAPPER_STR "mysql"
#define SPIDER_DB_WRAPPER_LEN (sizeof(SPIDER_DB_WRAPPER_STR) - 1)
@@ -192,6 +192,8 @@
#define SPIDER_SQL_PF_EQUAL_LEN (sizeof(SPIDER_SQL_PF_EQUAL_STR) - 1)
#define SPIDER_SQL_GROUP_STR " group by "
#define SPIDER_SQL_GROUP_LEN (sizeof(SPIDER_SQL_GROUP_STR) - 1)
+#define SPIDER_SQL_HAVING_STR " having "
+#define SPIDER_SQL_HAVING_LEN (sizeof(SPIDER_SQL_HAVING_STR) - 1)
#define SPIDER_SQL_PLUS_STR " + "
#define SPIDER_SQL_PLUS_LEN (sizeof(SPIDER_SQL_PLUS_STR) - 1)
#define SPIDER_SQL_MINUS_STR " - "
@@ -250,6 +252,13 @@
#define SPIDER_SQL_B_STR "b"
#define SPIDER_SQL_B_LEN (sizeof(SPIDER_SQL_B_STR) - 1)
+#define SPIDER_SQL_INDEX_IGNORE_STR " IGNORE INDEX "
+#define SPIDER_SQL_INDEX_IGNORE_LEN (sizeof(SPIDER_SQL_INDEX_IGNORE_STR) - 1)
+#define SPIDER_SQL_INDEX_USE_STR " USE INDEX "
+#define SPIDER_SQL_INDEX_USE_LEN (sizeof(SPIDER_SQL_INDEX_USE_STR) - 1)
+#define SPIDER_SQL_INDEX_FORCE_STR " FORCE INDEX "
+#define SPIDER_SQL_INDEX_FORCE_LEN (sizeof(SPIDER_SQL_INDEX_FORCE_STR) - 1)
+
#define SPIDER_SQL_INT_LEN 20
#define SPIDER_SQL_HANDLER_CID_LEN 6
#define SPIDER_SQL_HANDLER_CID_FORMAT "t%05u"
@@ -263,6 +272,13 @@ int spider_db_connect(
int link_idx
);
+int spider_db_ping_internal(
+ SPIDER_SHARE *share,
+ SPIDER_CONN *conn,
+ int all_link_idx,
+ int *need_mon
+);
+
int spider_db_ping(
ha_spider *spider,
SPIDER_CONN *conn,
@@ -325,7 +341,7 @@ int spider_db_query_for_bulk_update(
ha_spider *spider,
SPIDER_CONN *conn,
int link_idx,
- uint *dup_key_found
+ ha_rows *dup_key_found
);
size_t spider_db_real_escape_string(
@@ -713,7 +729,7 @@ int spider_db_bulk_update_size_limit(
int spider_db_bulk_update_end(
ha_spider *spider,
- uint *dup_key_found
+ ha_rows *dup_key_found
);
int spider_db_bulk_update(
@@ -729,19 +745,27 @@ int spider_db_update(
);
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int spider_db_direct_update(
ha_spider *spider,
TABLE *table,
KEY_MULTI_RANGE *ranges,
uint range_count,
- uint *update_rows
+ ha_rows *update_rows
);
+#else
+int spider_db_direct_update(
+ ha_spider *spider,
+ TABLE *table,
+ ha_rows *update_rows
+);
+#endif
#endif
#ifdef HA_CAN_BULK_ACCESS
int spider_db_bulk_direct_update(
ha_spider *spider,
- uint *update_rows
+ ha_rows *update_rows
);
#endif
@@ -758,14 +782,22 @@ int spider_db_delete(
);
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int spider_db_direct_delete(
ha_spider *spider,
TABLE *table,
KEY_MULTI_RANGE *ranges,
uint range_count,
- uint *delete_rows
+ ha_rows *delete_rows
+);
+#else
+int spider_db_direct_delete(
+ ha_spider *spider,
+ TABLE *table,
+ ha_rows *delete_rows
);
#endif
+#endif
int spider_db_delete_all_rows(
ha_spider *spider
@@ -812,7 +844,9 @@ int spider_db_print_item_type(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
int spider_db_open_item_cond(
@@ -821,7 +855,9 @@ int spider_db_open_item_cond(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
int spider_db_open_item_func(
@@ -830,7 +866,9 @@ int spider_db_open_item_func(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
@@ -840,7 +878,9 @@ int spider_db_open_item_sum_func(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
#endif
@@ -850,7 +890,9 @@ int spider_db_open_item_ident(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
int spider_db_open_item_field(
@@ -859,7 +901,9 @@ int spider_db_open_item_field(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
int spider_db_open_item_ref(
@@ -868,7 +912,9 @@ int spider_db_open_item_ref(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
int spider_db_open_item_row(
@@ -877,7 +923,9 @@ int spider_db_open_item_row(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
int spider_db_open_item_string(
@@ -886,7 +934,9 @@ int spider_db_open_item_string(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
int spider_db_open_item_int(
@@ -895,7 +945,9 @@ int spider_db_open_item_int(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
int spider_db_open_item_cache(
@@ -904,7 +956,9 @@ int spider_db_open_item_cache(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
int spider_db_open_item_insert_value(
@@ -913,7 +967,9 @@ int spider_db_open_item_insert_value(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
int spider_db_append_condition(
@@ -929,7 +985,9 @@ int spider_db_append_update_columns(
spider_string *str,
const char *alias,
uint alias_length,
- uint dbton_id
+ uint dbton_id,
+ bool use_fields,
+ spider_fields *fields
);
#endif
diff --git a/storage/spider/spd_db_handlersocket.cc b/storage/spider/spd_db_handlersocket.cc
index 5ffa00f5fe6..dc4b9dd25ec 100644
--- a/storage/spider/spd_db_handlersocket.cc
+++ b/storage/spider/spd_db_handlersocket.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012-2014 Kentoku Shiba
+/* Copyright (C) 2012-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -39,6 +40,7 @@
extern handlerton *spider_hton_ptr;
extern HASH spider_open_connections;
+extern HASH spider_ipport_conns;
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
extern const char spider_dig_upper[];
@@ -106,6 +108,12 @@ SPIDER_DB_CONN *spider_handlersocket_create_conn(
DBUG_RETURN(new spider_db_handlersocket(conn));
}
+bool spider_handlersocket_support_direct_join(
+) {
+ DBUG_ENTER("spider_handlersocket_support_direct_join");
+ DBUG_RETURN(FALSE);
+}
+
spider_db_handlersocket_util spider_db_handlersocket_utility;
SPIDER_DBTON spider_dbton_handlersocket = {
@@ -118,6 +126,7 @@ SPIDER_DBTON spider_dbton_handlersocket = {
spider_handlersocket_create_handler,
NULL,
spider_handlersocket_create_conn,
+ spider_handlersocket_support_direct_join,
&spider_db_handlersocket_utility
};
@@ -590,7 +599,8 @@ bool spider_db_handlersocket_result_buffer::check_size(
}
spider_db_handlersocket_result::spider_db_handlersocket_result(
-) : spider_db_result(spider_dbton_handlersocket.dbton_id)
+ SPIDER_DB_CONN *in_db_conn
+) : spider_db_result(in_db_conn, spider_dbton_handlersocket.dbton_id)
{
DBUG_ENTER("spider_db_handlersocket_result::spider_db_handlersocket_result");
DBUG_PRINT("info",("spider this=%p", this));
@@ -1227,7 +1237,7 @@ spider_db_result *spider_db_handlersocket::store_result(
*spider_res_buf = (spider_db_result_buffer *) hs_res_buf;
}
hs_res_buf->clear();
- if (!(result = new spider_db_handlersocket_result()))
+ if (!(result = new spider_db_handlersocket_result(this)))
{
*error_num = HA_ERR_OUT_OF_MEM;
DBUG_RETURN(NULL);
@@ -1437,7 +1447,7 @@ spider_db_result *spider_db_handlersocket::use_result(
spider_db_handlersocket_result *result;
DBUG_ENTER("spider_db_handlersocket::use_result");
DBUG_PRINT("info",("spider this=%p", this));
- if (!(result = new spider_db_handlersocket_result()))
+ if (!(result = new spider_db_handlersocket_result(this)))
{
*error_num = HA_ERR_OUT_OF_MEM;
DBUG_RETURN(NULL);
@@ -1840,6 +1850,22 @@ int spider_db_handlersocket::set_time_zone(
DBUG_RETURN(0);
}
+int spider_db_handlersocket::show_master_status(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ int all_link_idx,
+ int *need_mon,
+ TABLE *table,
+ spider_string *str,
+ int mode,
+ SPIDER_DB_RESULT **res1,
+ SPIDER_DB_RESULT **res2
+) {
+ DBUG_ENTER("spider_db_handlersocket::show_master_status");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN(0);
+}
+
int spider_db_handlersocket::append_sql(
char *sql,
ulong sql_length,
@@ -2720,7 +2746,9 @@ int spider_db_handlersocket_util::open_item_func(
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
) {
uint dbton_id = spider_dbton_handlersocket.dbton_id;
int error_num;
@@ -2733,6 +2761,7 @@ int spider_db_handlersocket_util::open_item_func(
separete_str_length = SPIDER_SQL_NULL_CHAR_LEN,
last_str_length = SPIDER_SQL_NULL_CHAR_LEN;
int use_pushdown_udf;
+ bool merge_func = FALSE;
DBUG_ENTER("spider_db_handlersocket_util::open_item_func");
if (str)
{
@@ -2796,7 +2825,7 @@ int spider_db_handlersocket_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_int(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (
!strncasecmp("case", func_name, func_name_length)
) {
@@ -2812,7 +2841,7 @@ int spider_db_handlersocket_util::open_item_func(
{
if ((error_num = spider_db_print_item_type(
item_list[item_func_case->first_expr_num], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
for (roop_count = 0; roop_count < item_func_case->ncases;
@@ -2826,7 +2855,7 @@ int spider_db_handlersocket_util::open_item_func(
}
if ((error_num = spider_db_print_item_type(
item_list[roop_count], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -2836,7 +2865,7 @@ int spider_db_handlersocket_util::open_item_func(
}
if ((error_num = spider_db_print_item_type(
item_list[roop_count + 1], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (item_func_case->else_expr_num != -1)
@@ -2849,7 +2878,7 @@ int spider_db_handlersocket_util::open_item_func(
}
if ((error_num = spider_db_print_item_type(
item_list[item_func_case->else_expr_num], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (str)
@@ -2886,7 +2915,7 @@ int spider_db_handlersocket_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (
!strncasecmp("convert", func_name, func_name_length)
) {
@@ -2911,41 +2940,110 @@ int spider_db_handlersocket_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (func_name_length == 9 &&
!strncasecmp("isnottrue", func_name, func_name_length)
) {
last_str = SPIDER_SQL_IS_NOT_TRUE_STR;
last_str_length = SPIDER_SQL_IS_NOT_TRUE_LEN;
break;
- } else if (func_name_length == 10 &&
- !strncasecmp("isnotfalse", func_name, func_name_length)
- ) {
- last_str = SPIDER_SQL_IS_NOT_FALSE_STR;
- last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN;
- break;
+ } else if (func_name_length == 10)
+ {
+ if (!strncasecmp("isnotfalse", func_name, func_name_length))
+ {
+ last_str = SPIDER_SQL_IS_NOT_FALSE_STR;
+ last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN;
+ break;
+ } else if (!strncasecmp("column_get", func_name, func_name_length))
+ {
+ if (str)
+ {
+ str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
+ if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(func_name, func_name_length);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN);
+ }
+ func_name = SPIDER_SQL_COMMA_STR;
+ func_name_length = SPIDER_SQL_COMMA_LEN;
+ separete_str = SPIDER_SQL_COMMA_STR;
+ separete_str_length = SPIDER_SQL_COMMA_LEN;
+ break;
+ }
} else if (func_name_length == 12)
{
if (!strncasecmp("cast_as_date", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_DATE_STR;
last_str_length = SPIDER_SQL_AS_DATE_LEN;
break;
} else if (!strncasecmp("cast_as_time", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_TIME_STR;
last_str_length = SPIDER_SQL_AS_TIME_LEN;
@@ -2958,7 +3056,7 @@ int spider_db_handlersocket_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (!strncasecmp("timestampdiff", func_name, func_name_length))
{
#ifdef ITEM_FUNC_TIMESTAMPDIFF_ARE_PUBLIC
@@ -3021,7 +3119,7 @@ int spider_db_handlersocket_util::open_item_func(
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
}
if ((error_num = spider_db_print_item_type(item_list[0], spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3030,7 +3128,7 @@ int spider_db_handlersocket_util::open_item_func(
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
}
if ((error_num = spider_db_print_item_type(item_list[1], spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3048,6 +3146,29 @@ int spider_db_handlersocket_util::open_item_func(
{
if (!strncasecmp("cast_as_binary", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2;
@@ -3055,9 +3176,12 @@ int spider_db_handlersocket_util::open_item_func(
tmp_str.init_calc_mem(123);
tmp_str.length(0);
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
#if MYSQL_VERSION_ID < 50500
item_func->print(tmp_str.get_str(), QT_IS);
#else
@@ -3076,12 +3200,38 @@ int spider_db_handlersocket_util::open_item_func(
break;
} else if (!strncasecmp("cast_as_signed", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_SIGNED_STR;
last_str_length = SPIDER_SQL_AS_SIGNED_LEN;
@@ -3091,12 +3241,38 @@ int spider_db_handlersocket_util::open_item_func(
{
if (!strncasecmp("cast_as_unsigned", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_UNSIGNED_STR;
last_str_length = SPIDER_SQL_AS_UNSIGNED_LEN;
@@ -3104,6 +3280,29 @@ int spider_db_handlersocket_util::open_item_func(
} else if (!strncasecmp("decimal_typecast", func_name,
func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2;
@@ -3111,9 +3310,12 @@ int spider_db_handlersocket_util::open_item_func(
tmp_str.init_calc_mem(124);
tmp_str.length(0);
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
#if MYSQL_VERSION_ID < 50500
item_func->print(tmp_str.get_str(), QT_IS);
#else
@@ -3133,12 +3335,38 @@ int spider_db_handlersocket_util::open_item_func(
} else if (!strncasecmp("cast_as_datetime", func_name,
func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_DATETIME_STR;
last_str_length = SPIDER_SQL_AS_DATETIME_LEN;
@@ -3154,7 +3382,7 @@ int spider_db_handlersocket_util::open_item_func(
item_date_add_interval->int_type];
func_name_length = strlen(func_name);
if ((error_num = spider_db_print_item_type(item_list[0], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3171,7 +3399,7 @@ int spider_db_handlersocket_util::open_item_func(
}
}
if ((error_num = spider_db_print_item_type(item_list[1], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3202,9 +3430,33 @@ int spider_db_handlersocket_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item_func::CHAR_TYPECAST_FUNC:
+ DBUG_PRINT("info",("spider CHAR_TYPECAST_FUNC"));
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2;
@@ -3212,9 +3464,12 @@ int spider_db_handlersocket_util::open_item_func(
tmp_str.init_calc_mem(125);
tmp_str.length(0);
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
#if MYSQL_VERSION_ID < 50500
item_func->print(tmp_str.get_str(), QT_IS);
#else
@@ -3247,12 +3502,15 @@ int spider_db_handlersocket_util::open_item_func(
bool has_other_item = FALSE;
while((item = lif++))
{
+#ifdef SPIDER_HAS_EXPR_CACHE_ITEM
if (
item->type() == Item::EXPR_CACHE_ITEM
) {
DBUG_PRINT("info",("spider EXPR_CACHE_ITEM"));
has_expr_cache_item = TRUE;
- } else if (
+ } else
+#endif
+ if (
item->type() == Item::FUNC_ITEM &&
((Item_func *) item)->functype() == Item_func::ISNOTNULL_FUNC
) {
@@ -3356,7 +3614,7 @@ int spider_db_handlersocket_util::open_item_func(
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(
spider_db_open_item_cond((Item_cond *) item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item_func::TRIG_COND_FUNC:
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
case Item_func::GUSERVAR_FUNC:
@@ -3364,10 +3622,10 @@ int spider_db_handlersocket_util::open_item_func(
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
if (item_func->result_type() == STRING_RESULT)
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
else
DBUG_RETURN(spider_db_open_item_int(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item_func::FT_FUNC:
if (spider_db_check_ft_idx(item_func, spider) == MAX_KEY)
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
@@ -3473,7 +3731,7 @@ int spider_db_handlersocket_util::open_item_func(
{
item = item_list[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (roop_count == 1)
{
@@ -3491,7 +3749,7 @@ int spider_db_handlersocket_util::open_item_func(
}
item = item_list[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (item_func->functype() == Item_func::FT_FUNC)
@@ -3505,7 +3763,7 @@ int spider_db_handlersocket_util::open_item_func(
}
item = item_list[0];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3533,7 +3791,8 @@ int spider_db_handlersocket_util::open_item_func(
{
Item_func_conv_charset *item_func_conv_charset =
(Item_func_conv_charset *)item_func;
- CHARSET_INFO *conv_charset = item_func_conv_charset->conv_charset;
+ CHARSET_INFO *conv_charset =
+ item_func_conv_charset->SPIDER_Item_func_conv_charset_conv_charset;
uint cset_length = strlen(conv_charset->csname);
if (str->reserve(SPIDER_SQL_USING_LEN + cset_length))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -3544,6 +3803,8 @@ int spider_db_handlersocket_util::open_item_func(
}
if (str)
{
+ if (merge_func)
+ str->length(str->length() - SPIDER_SQL_CLOSE_PAREN_LEN);
if (str->reserve(last_str_length + SPIDER_SQL_CLOSE_PAREN_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
str->q_append(last_str, last_str_length);
@@ -3558,7 +3819,9 @@ int spider_db_handlersocket_util::open_item_sum_func(
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
) {
uint dbton_id = spider_dbton_handlersocket.dbton_id;
uint roop_count, item_count = item_sum->get_arg_count();
@@ -3588,7 +3851,7 @@ int spider_db_handlersocket_util::open_item_sum_func(
{
item = args[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3599,7 +3862,7 @@ int spider_db_handlersocket_util::open_item_sum_func(
}
item = args[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (str)
@@ -3637,6 +3900,47 @@ int spider_db_handlersocket_util::append_escaped_util(
DBUG_RETURN(0);
}
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+int spider_db_handlersocket_util::append_from_and_tables(
+ spider_fields *fields,
+ spider_string *str
+) {
+ DBUG_ENTER("spider_db_handlersocket_util::append_from_and_tables");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+
+int spider_db_handlersocket_util::reappend_tables(
+ spider_fields *fields,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain,
+ spider_string *str
+) {
+ DBUG_ENTER("spider_db_handlersocket_util::reappend_tables");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+
+int spider_db_handlersocket_util::append_where(
+ spider_string *str
+) {
+ DBUG_ENTER("spider_db_handlersocket_util::append_where");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+
+int spider_db_handlersocket_util::append_having(
+ spider_string *str
+) {
+ DBUG_ENTER("spider_db_handlersocket_util::append_having");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+#endif
+
spider_handlersocket_share::spider_handlersocket_share(
st_spider_share *share
) : spider_db_share(
@@ -4052,6 +4356,16 @@ int spider_handlersocket_handler::init()
DBUG_RETURN(0);
}
+int spider_handlersocket_handler::append_index_hint(
+ spider_string *str,
+ int link_idx,
+ ulong sql_type
+ )
+{
+ DBUG_ENTER("spider_handlersocket_handler::append_index_hint");
+ DBUG_RETURN(0);
+}
+
int spider_handlersocket_handler::append_table_name_with_adjusting(
spider_string *str,
int link_idx,
@@ -4999,7 +5313,7 @@ int spider_handlersocket_handler::is_sole_projection_field(
uint16 field_index
) {
DBUG_ENTER("spider_handlersocket_handler::is_sole_projection_field");
- DBUG_PRINT("info", ("spider this=%p", this));
+ DBUG_PRINT("info",("spider this=%p", this));
DBUG_ASSERT(0);
DBUG_RETURN(0);
}
@@ -5366,6 +5680,19 @@ bool spider_handlersocket_handler::need_lock_before_set_sql_for_exec(
DBUG_RETURN(TRUE);
}
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+int spider_handlersocket_handler::set_sql_for_exec(
+ ulong sql_type,
+ int link_idx,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain
+) {
+ DBUG_ENTER("spider_handlersocket_handler::set_sql_for_exec");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+#endif
+
int spider_handlersocket_handler::set_sql_for_exec(
ulong sql_type,
int link_idx
@@ -5443,7 +5770,7 @@ int spider_handlersocket_handler::show_table_status(
int sts_mode,
uint flag
) {
- spider_db_handlersocket_result res;
+ spider_db_handlersocket_result res(NULL);
SPIDER_SHARE *share = spider->share;
ulonglong auto_increment_value = 0;
DBUG_ENTER("spider_handlersocket_show_table_status");
@@ -5791,4 +6118,100 @@ int spider_handlersocket_handler::reset_union_table_name(
DBUG_ASSERT(0);
DBUG_RETURN(0);
}
+
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+int spider_handlersocket_handler::append_list_item_select_part(
+ List<Item> *select,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ DBUG_ENTER("spider_handlersocket_handler::append_list_item_select_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+
+int spider_handlersocket_handler::append_from_and_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+) {
+ DBUG_ENTER("spider_handlersocket_handler::append_from_and_tables_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+
+int spider_handlersocket_handler::reappend_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+) {
+ DBUG_ENTER("spider_handlersocket_handler::reappend_tables_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+
+int spider_handlersocket_handler::append_where_part(
+ ulong sql_type
+) {
+ DBUG_ENTER("spider_handlersocket_handler::append_where_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+
+int spider_handlersocket_handler::append_having_part(
+ ulong sql_type
+) {
+ DBUG_ENTER("spider_handlersocket_handler::append_having_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+
+int spider_handlersocket_handler::append_item_type_part(
+ Item *item,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ DBUG_ENTER("spider_handlersocket_handler::append_item_type_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+
+int spider_handlersocket_handler::append_group_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ DBUG_ENTER("spider_handlersocket_handler::append_group_by_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+
+int spider_handlersocket_handler::append_order_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ DBUG_ENTER("spider_handlersocket_handler::append_order_by_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(0);
+ DBUG_RETURN(0);
+}
+#endif
#endif
diff --git a/storage/spider/spd_db_handlersocket.h b/storage/spider/spd_db_handlersocket.h
index a3955aea044..19138b22e1a 100644
--- a/storage/spider/spd_db_handlersocket.h
+++ b/storage/spider/spd_db_handlersocket.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012-2014 Kentoku Shiba
+/* Copyright (C) 2012-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define SPIDER_HS_CONN dena::hstcpcli_ptr
#define SPIDER_HS_CONN_CREATE dena::hstcpcli_i::create
@@ -94,7 +94,9 @@ public:
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
);
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
int open_item_sum_func(
@@ -102,13 +104,36 @@ public:
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
);
#endif
int append_escaped_util(
spider_string *to,
String *from
);
+ int append_escaped_util(
+ spider_string *to,
+ String *from
+ );
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ int append_from_and_tables(
+ spider_fields *fields,
+ spider_string *str
+ );
+ int reappend_tables(
+ spider_fields *fields,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain,
+ spider_string *str
+ );
+ int append_where(
+ spider_string *str
+ );
+ int append_having(
+ spider_string *str
+ );
+#endif
};
class spider_db_handlersocket_row: public spider_db_row
@@ -167,7 +192,7 @@ public:
SPIDER_HS_STRING_REF hs_row;
uint field_count;
int store_error_num;
- spider_db_handlersocket_result();
+ spider_db_handlersocket_result(SPIDER_DB_CONN *in_db_conn);
~spider_db_handlersocket_result();
bool has_result();
void free_result();
@@ -355,6 +380,17 @@ public:
Time_zone *time_zone,
int *need_mon
);
+ int show_master_status(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ int all_link_idx,
+ int *need_mon,
+ TABLE *table,
+ spider_string *str,
+ int mode,
+ SPIDER_DB_RESULT **res1,
+ SPIDER_DB_RESULT **res2
+ );
int append_sql(
char *sql,
ulong sql_length,
@@ -505,6 +541,11 @@ public:
);
~spider_handlersocket_handler();
int init();
+ int append_index_hint(
+ spider_string *str,
+ int link_idx,
+ ulong sql_type
+ );
int append_table_name_with_adjusting(
spider_string *str,
int link_idx,
@@ -849,6 +890,13 @@ public:
bool need_lock_before_set_sql_for_exec(
ulong sql_type
);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ int set_sql_for_exec(
+ ulong sql_type,
+ int link_idx,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain
+ );
+#endif
int set_sql_for_exec(
ulong sql_type,
int link_idx
@@ -960,4 +1008,52 @@ public:
int link_idx,
ulong sql_type
);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ int append_from_and_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int reappend_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_where_part(
+ ulong sql_type
+ );
+ int append_having_part(
+ ulong sql_type
+ );
+ int append_item_type_part(
+ Item *item,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_list_item_select_part(
+ List<Item> *select,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_group_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_order_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+#endif
};
diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h
index 56bc2ccad42..2913f911587 100644
--- a/storage/spider/spd_db_include.h
+++ b/storage/spider/spd_db_include.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2014 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,15 +11,29 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "hs_compat.h"
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
#include "hstcpcli.hpp"
#endif
+#define SPIDER_DBTON_SIZE 15
+
#define SPIDER_DB_WRAPPER_MYSQL "mysql"
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100204
+#define PLUGIN_VAR_CAN_MEMALLOC
+/*
+#define ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC
+#define HASH_UPDATE_WITH_HASH_VALUE
+*/
+#else
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+#define HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
+#endif
+#endif
+
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002
#define SPIDER_HAS_DISCOVER_TABLE_STRUCTURE
#define SPIDER_HAS_APPEND_FOR_SINGLE_QUOTE
@@ -31,7 +45,6 @@
#endif
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100007
-#define SPIDER_HAS_DISCOVER_TABLE_STRUCTURE_COMMENT
#define SPIDER_ITEM_HAS_CMP_TYPE
#endif
@@ -47,6 +60,14 @@
#endif
#endif
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108
+#define SPIDER_HAS_GROUP_BY_HANDLER
+#endif
+
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100200
+#define SPIDER_ORDER_HAS_ENUM_ORDER
+#endif
+
#if defined(MARIADB_BASE_VERSION)
#define SPIDER_ITEM_GEOFUNC_NAME_HAS_MBR
#define SPIDER_HANDLER_AUTO_REPAIR_HAS_ERROR
@@ -182,32 +203,32 @@ typedef st_spider_result SPIDER_RESULT;
#define SPIDER_SQL_LCL_NAME_QUOTE_STR "`"
#define SPIDER_SQL_LCL_NAME_QUOTE_LEN (sizeof(SPIDER_SQL_LCL_NAME_QUOTE_STR) - 1)
-#define SPIDER_CONN_KIND_MYSQL (1U << 0)
+#define SPIDER_CONN_KIND_MYSQL (1 << 0)
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
-#define SPIDER_CONN_KIND_HS_READ (1U << 2)
-#define SPIDER_CONN_KIND_HS_WRITE (1U << 3)
+#define SPIDER_CONN_KIND_HS_READ (1 << 2)
+#define SPIDER_CONN_KIND_HS_WRITE (1 << 3)
#endif
-#define SPIDER_SQL_KIND_SQL (1U << 0)
-#define SPIDER_SQL_KIND_HANDLER (1U << 1)
+#define SPIDER_SQL_KIND_SQL (1 << 0)
+#define SPIDER_SQL_KIND_HANDLER (1 << 1)
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
-#define SPIDER_SQL_KIND_HS (1U << 2)
+#define SPIDER_SQL_KIND_HS (1 << 2)
#endif
-#define SPIDER_SQL_TYPE_SELECT_SQL (1U << 0)
-#define SPIDER_SQL_TYPE_INSERT_SQL (1U << 1)
-#define SPIDER_SQL_TYPE_UPDATE_SQL (1U << 2)
-#define SPIDER_SQL_TYPE_DELETE_SQL (1U << 3)
-#define SPIDER_SQL_TYPE_BULK_UPDATE_SQL (1U << 4)
-#define SPIDER_SQL_TYPE_TMP_SQL (1U << 5)
-#define SPIDER_SQL_TYPE_DROP_TMP_TABLE_SQL (1U << 6)
-#define SPIDER_SQL_TYPE_OTHER_SQL (1U << 7)
-#define SPIDER_SQL_TYPE_HANDLER (1U << 8)
-#define SPIDER_SQL_TYPE_SELECT_HS (1U << 9)
-#define SPIDER_SQL_TYPE_INSERT_HS (1U << 10)
-#define SPIDER_SQL_TYPE_UPDATE_HS (1U << 11)
-#define SPIDER_SQL_TYPE_DELETE_HS (1U << 12)
-#define SPIDER_SQL_TYPE_OTHER_HS (1U << 13)
+#define SPIDER_SQL_TYPE_SELECT_SQL (1 << 0)
+#define SPIDER_SQL_TYPE_INSERT_SQL (1 << 1)
+#define SPIDER_SQL_TYPE_UPDATE_SQL (1 << 2)
+#define SPIDER_SQL_TYPE_DELETE_SQL (1 << 3)
+#define SPIDER_SQL_TYPE_BULK_UPDATE_SQL (1 << 4)
+#define SPIDER_SQL_TYPE_TMP_SQL (1 << 5)
+#define SPIDER_SQL_TYPE_DROP_TMP_TABLE_SQL (1 << 6)
+#define SPIDER_SQL_TYPE_OTHER_SQL (1 << 7)
+#define SPIDER_SQL_TYPE_HANDLER (1 << 8)
+#define SPIDER_SQL_TYPE_SELECT_HS (1 << 9)
+#define SPIDER_SQL_TYPE_INSERT_HS (1 << 10)
+#define SPIDER_SQL_TYPE_UPDATE_HS (1 << 11)
+#define SPIDER_SQL_TYPE_DELETE_HS (1 << 12)
+#define SPIDER_SQL_TYPE_OTHER_HS (1 << 13)
enum spider_bulk_upd_start {
SPD_BU_NOT_START,
@@ -531,6 +552,169 @@ public:
bool is_ascii() const;
};
+typedef struct spider_table_link_idx_holder SPIDER_TABLE_LINK_IDX_HOLDER;
+typedef struct spider_table_holder SPIDER_TABLE_HOLDER;
+
+typedef struct spider_link_idx_holder
+{
+ spider_table_link_idx_holder *table_link_idx_holder;
+ int link_idx;
+ int link_status;
+ spider_link_idx_holder *next_table;
+ spider_link_idx_holder *next;
+} SPIDER_LINK_IDX_HOLDER;
+
+typedef struct spider_link_idx_chain
+{
+ SPIDER_CONN *conn;
+ spider_link_idx_holder *link_idx_holder;
+ spider_link_idx_holder *current_link_idx_holder;
+ int link_status;
+ spider_link_idx_chain *next;
+} SPIDER_LINK_IDX_CHAIN;
+
+typedef struct spider_table_link_idx_holder
+{
+ spider_table_holder *table_holder;
+ spider_link_idx_holder *first_link_idx_holder;
+ spider_link_idx_holder *last_link_idx_holder;
+ spider_link_idx_holder *current_link_idx_holder;
+ uint link_idx_holder_count;
+} SPIDER_TABLE_LINK_IDX_HOLDER;
+
+typedef struct spider_conn_holder
+{
+ SPIDER_CONN *conn;
+ spider_table_link_idx_holder *table_link_idx_holder;
+ uint link_idx_holder_count_max;
+ bool checked_for_same_conn;
+ long access_balance;
+ spider_conn_holder *prev;
+ spider_conn_holder *next;
+} SPIDER_CONN_HOLDER;
+
+typedef struct spider_table_holder
+{
+ TABLE *table;
+ ha_spider *spider;
+ spider_string *alias;
+} SPIDER_TABLE_HOLDER;
+
+typedef struct spider_field_holder
+{
+ Field *field;
+ ha_spider *spider;
+ spider_string *alias;
+ spider_field_holder *next;
+} SPIDER_FIELD_HOLDER;
+
+typedef struct spider_field_chain
+{
+ spider_field_holder *field_holder;
+ spider_field_chain *next;
+} SPIDER_FIELD_CHAIN;
+
+class spider_fields
+{
+ uint dbton_count;
+ uint current_dbton_num;
+ uint dbton_ids[SPIDER_DBTON_SIZE];
+ uint table_count;
+ uint current_table_num;
+ SPIDER_TABLE_HOLDER *table_holder;
+ SPIDER_LINK_IDX_CHAIN *first_link_idx_chain;
+ SPIDER_LINK_IDX_CHAIN *last_link_idx_chain;
+ SPIDER_LINK_IDX_CHAIN *current_link_idx_chain;
+ SPIDER_LINK_IDX_CHAIN *first_ok_link_idx_chain;
+ SPIDER_CONN_HOLDER *first_conn_holder;
+ SPIDER_CONN_HOLDER *last_conn_holder;
+ SPIDER_CONN_HOLDER *current_conn_holder;
+ SPIDER_FIELD_HOLDER *first_field_holder;
+ SPIDER_FIELD_HOLDER *last_field_holder;
+ SPIDER_FIELD_HOLDER *current_field_holder;
+ SPIDER_FIELD_CHAIN *first_field_chain;
+ SPIDER_FIELD_CHAIN *last_field_chain;
+ SPIDER_FIELD_CHAIN *current_field_chain;
+ Field **first_field_ptr;
+ Field **current_field_ptr;
+public:
+ spider_fields();
+ virtual ~spider_fields();
+ void add_dbton_id(
+ uint dbton_id_arg
+ );
+ void set_pos_to_first_dbton_id();
+ uint get_next_dbton_id();
+ int make_link_idx_chain(
+ int link_status
+ );
+ SPIDER_LINK_IDX_CHAIN *create_link_idx_chain();
+ void set_pos_to_first_link_idx_chain();
+ SPIDER_LINK_IDX_CHAIN *get_next_link_idx_chain();
+ SPIDER_LINK_IDX_HOLDER *get_dup_link_idx_holder(
+ SPIDER_TABLE_LINK_IDX_HOLDER *table_link_idx_holder,
+ SPIDER_LINK_IDX_HOLDER *current
+ );
+ bool check_link_ok_chain();
+ bool is_first_link_ok_chain(
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg
+ );
+ int get_ok_link_idx();
+ void set_first_link_idx();
+ int add_link_idx(
+ SPIDER_CONN_HOLDER *conn_holder_arg,
+ ha_spider *spider_arg,
+ int link_idx
+ );
+ SPIDER_LINK_IDX_HOLDER *create_link_idx_holder();
+ void set_pos_to_first_table_on_link_idx_chain(
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg
+ );
+ SPIDER_LINK_IDX_HOLDER *get_next_table_on_link_idx_chain(
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg
+ );
+ SPIDER_CONN_HOLDER *add_conn(
+ SPIDER_CONN *conn_arg,
+ long access_balance
+ );
+ SPIDER_CONN_HOLDER *create_conn_holder();
+ void set_pos_to_first_conn_holder();
+ SPIDER_CONN_HOLDER *get_next_conn_holder();
+ bool has_conn_holder();
+ void clear_conn_holder_from_conn();
+ bool check_conn_same_conn(
+ SPIDER_CONN *conn_arg
+ );
+ bool remove_conn_if_not_checked();
+ void check_support_dbton(
+ uchar *dbton_bitmap
+ );
+ void choose_a_conn();
+ void free_conn_holder(
+ SPIDER_CONN_HOLDER *conn_holder_arg
+ );
+ SPIDER_TABLE_HOLDER *add_table(
+ ha_spider *spider_arg
+ );
+ int create_table_holder(
+ uint table_count_arg
+ );
+ void set_pos_to_first_table_holder();
+ SPIDER_TABLE_HOLDER *get_next_table_holder();
+ int add_field(Field *field_arg);
+ SPIDER_FIELD_HOLDER *create_field_holder();
+ void set_pos_to_first_field_holder();
+ SPIDER_FIELD_HOLDER *get_next_field_holder();
+ SPIDER_FIELD_CHAIN *create_field_chain();
+ void set_pos_to_first_field_chain();
+ SPIDER_FIELD_CHAIN *get_next_field_chain();
+ void set_field_ptr(Field **field_arg);
+ Field **get_next_field_ptr();
+ int ping_table_mon_from_table(
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain
+ );
+};
+
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
#define SPIDER_HS_UINT32_INFO dena::uint32_info
#define SPIDER_HS_STRING_REF dena::string_ref
@@ -681,7 +865,9 @@ public:
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
) = 0;
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
virtual int open_item_sum_func(
@@ -689,13 +875,32 @@ public:
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
) = 0;
#endif
virtual int append_escaped_util(
spider_string *to,
String *from
) = 0;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ virtual int append_from_and_tables(
+ spider_fields *fields,
+ spider_string *str
+ ) = 0;
+ virtual int reappend_tables(
+ spider_fields *fields,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain,
+ spider_string *str
+ ) = 0;
+ virtual int append_where(
+ spider_string *str
+ ) = 0;
+ virtual int append_having(
+ spider_string *str
+ ) = 0;
+#endif
};
class spider_db_row
@@ -745,9 +950,12 @@ public:
class spider_db_result
{
+protected:
+ SPIDER_DB_CONN *db_conn;
public:
uint dbton_id;
- spider_db_result(uint in_dbton_id) : dbton_id(in_dbton_id) {}
+ spider_db_result(SPIDER_DB_CONN *in_db_conn, uint in_dbton_id) :
+ db_conn(in_db_conn), dbton_id(in_dbton_id) {}
virtual ~spider_db_result() {}
virtual bool has_result() = 0;
virtual void free_result() = 0;
@@ -922,6 +1130,17 @@ public:
Time_zone *time_zone,
int *need_mon
) = 0;
+ virtual int show_master_status(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ int all_link_idx,
+ int *need_mon,
+ TABLE *table,
+ spider_string *str,
+ int mode,
+ SPIDER_DB_RESULT **res1,
+ SPIDER_DB_RESULT **res2
+ ) = 0;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
virtual int append_sql(
char *sql,
@@ -1041,10 +1260,18 @@ public:
ha_spider *spider;
spider_db_share *db_share;
int first_link_idx;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain;
+#endif
spider_db_handler(ha_spider *spider, spider_db_share *db_share) :
spider(spider), db_share(db_share), first_link_idx(-1) {}
virtual ~spider_db_handler() {}
virtual int init() = 0;
+ virtual int append_index_hint(
+ spider_string *str,
+ int link_idx,
+ ulong sql_type
+ ) = 0;
virtual int append_table_name_with_adjusting(
spider_string *str,
int link_idx,
@@ -1104,6 +1331,10 @@ public:
virtual int append_select_part(
ulong sql_type
) = 0;
+ virtual int append_select(
+ spider_string *str,
+ ulong sql_type
+ ) = 0;
virtual int append_table_select_part(
ulong sql_type
) = 0;
@@ -1280,7 +1511,7 @@ public:
int link_idx
) = 0;
virtual bool is_sole_projection_field(
- uint16 field_index
+ uint16 field_index
) = 0;
virtual bool is_bulk_insert_exec_period(
bool bulk_end
@@ -1342,6 +1573,13 @@ public:
virtual bool need_lock_before_set_sql_for_exec(
ulong sql_type
) = 0;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ virtual int set_sql_for_exec(
+ ulong sql_type,
+ int link_idx,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain
+ ) = 0;
+#endif
virtual int set_sql_for_exec(
ulong sql_type,
int link_idx
@@ -1452,6 +1690,54 @@ public:
int link_idx,
ulong sql_type
) = 0;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ virtual int append_from_and_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+ ) = 0;
+ virtual int reappend_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+ ) = 0;
+ virtual int append_where_part(
+ ulong sql_type
+ ) = 0;
+ virtual int append_having_part(
+ ulong sql_type
+ ) = 0;
+ virtual int append_item_type_part(
+ Item *item,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ ) = 0;
+ virtual int append_list_item_select_part(
+ List<Item> *select,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ ) = 0;
+ virtual int append_group_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ ) = 0;
+ virtual int append_order_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ ) = 0;
+#endif
};
class spider_db_copy_table
@@ -1539,9 +1825,9 @@ typedef struct st_spider_dbton
spider_db_copy_table *(*create_db_copy_table)(
spider_db_share *db_share);
SPIDER_DB_CONN *(*create_db_conn)(SPIDER_CONN *conn);
+ bool (*support_direct_join)();
spider_db_util *db_util;
} SPIDER_DBTON;
-#define SPIDER_DBTON_SIZE 15
typedef struct st_spider_position
{
@@ -1661,6 +1947,8 @@ typedef struct st_spider_result_list
spider_bulk_upd_start bulk_update_start;
bool check_direct_order_limit;
bool direct_order_limit;
+ /* the limit_offeset, without where condition */
+ bool direct_limit_offset;
bool direct_distinct;
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
bool direct_aggregate;
diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc
index 4e2a41e9fa6..6ff2e25bc27 100644
--- a/storage/spider/spd_db_mysql.cc
+++ b/storage/spider/spd_db_mysql.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012-2015 Kentoku Shiba
+/* Copyright (C) 2012-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -52,6 +53,7 @@ extern bool volatile *spd_abort_loop;
extern handlerton *spider_hton_ptr;
extern pthread_mutex_t spider_open_conn_mutex;
extern HASH spider_open_connections;
+extern HASH spider_ipport_conns;
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
extern const char spider_dig_upper[];
@@ -114,6 +116,11 @@ static const char *name_quote_str = SPIDER_SQL_NAME_QUOTE_STR;
#define SPIDER_SQL_SHOW_WARNINGS_STR "show warnings"
#define SPIDER_SQL_SHOW_WARNINGS_LEN sizeof(SPIDER_SQL_SHOW_WARNINGS_STR) - 1
+#define SPIDER_SQL_SHOW_MASTER_STATUS_STR "show master status"
+#define SPIDER_SQL_SHOW_MASTER_STATUS_LEN sizeof(SPIDER_SQL_SHOW_MASTER_STATUS_STR) - 1
+#define SPIDER_SQL_BINLOG_GTID_POS_STR "select binlog_gtid_pos"
+#define SPIDER_SQL_BINLOG_GTID_POS_LEN sizeof(SPIDER_SQL_BINLOG_GTID_POS_STR) - 1
+
#ifdef SPIDER_HAS_DISCOVER_TABLE_STRUCTURE
#define SPIDER_SQL_SHOW_COLUMNS_STR "show columns from "
#define SPIDER_SQL_SHOW_COLUMNS_LEN sizeof(SPIDER_SQL_SHOW_COLUMNS_STR) - 1
@@ -215,6 +222,12 @@ SPIDER_DB_CONN *spider_mysql_create_conn(
DBUG_RETURN(new spider_db_mysql(conn));
}
+bool spider_mysql_support_direct_join(
+) {
+ DBUG_ENTER("spider_mysql_support_direct_join");
+ DBUG_RETURN(TRUE);
+}
+
spider_db_mysql_util spider_db_mysql_utility;
SPIDER_DBTON spider_dbton_mysql = {
@@ -227,6 +240,7 @@ SPIDER_DBTON spider_dbton_mysql = {
spider_mysql_create_handler,
spider_mysql_create_copy_table,
spider_mysql_create_conn,
+ spider_mysql_support_direct_join,
&spider_db_mysql_utility
};
@@ -467,8 +481,8 @@ int spider_db_mysql_row::store_to_tmp_table(
DBUG_RETURN(tmp_table->file->ha_write_row(tmp_table->record[0]));
}
-spider_db_mysql_result::spider_db_mysql_result() :
- spider_db_result(spider_dbton_mysql.dbton_id),
+spider_db_mysql_result::spider_db_mysql_result(SPIDER_DB_CONN *in_db_conn) :
+ spider_db_result(in_db_conn, spider_dbton_mysql.dbton_id),
db_result(NULL)
{
DBUG_ENTER("spider_db_mysql_result::spider_db_mysql_result");
@@ -520,7 +534,13 @@ SPIDER_DB_ROW *spider_db_mysql_result::fetch_row()
DBUG_PRINT("info",("spider this=%p", this));
if (!(row.row = mysql_fetch_row(db_result)))
{
- store_error_num = HA_ERR_END_OF_FILE;
+ if (mysql_errno(((spider_db_mysql *) db_conn)->db_conn))
+ {
+ store_error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn);
+ my_message(store_error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ } else
+ store_error_num = HA_ERR_END_OF_FILE;
DBUG_RETURN(NULL);
}
row.lengths = mysql_fetch_lengths(db_result);
@@ -537,7 +557,13 @@ SPIDER_DB_ROW *spider_db_mysql_result::fetch_row_from_result_buffer(
DBUG_PRINT("info",("spider this=%p", this));
if (!(row.row = mysql_fetch_row(db_result)))
{
- store_error_num = HA_ERR_END_OF_FILE;
+ if (mysql_errno(((spider_db_mysql *) db_conn)->db_conn))
+ {
+ store_error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn);
+ my_message(store_error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ } else
+ store_error_num = HA_ERR_END_OF_FILE;
DBUG_RETURN(NULL);
}
row.lengths = mysql_fetch_lengths(db_result);
@@ -620,13 +646,20 @@ int spider_db_mysql_result::fetch_table_status(
if (!(mysql_row = mysql_fetch_row(db_result)))
{
DBUG_PRINT("info",("spider fetch row is null"));
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
DBUG_RETURN(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM);
}
if (mode == 1)
{
- if (num_fields() != 18)
+ /* Ok to test for 18 fields as all new fields are added last */
+ if (num_fields() < 18)
{
- DBUG_PRINT("info",("spider field_count != 18"));
+ DBUG_PRINT("info",("spider field_count < 18"));
DBUG_RETURN(ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM);
}
@@ -880,6 +913,12 @@ int spider_db_mysql_result::fetch_table_records(
if (!(mysql_row = mysql_fetch_row(db_result)))
{
DBUG_PRINT("info",("spider fetch row is null"));
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
if (mode == 1)
@@ -924,6 +963,12 @@ int spider_db_mysql_result::fetch_table_cardinality(
if (!(mysql_row = mysql_fetch_row(db_result)))
{
DBUG_PRINT("info",("spider fetch row is null"));
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
/* no index */
DBUG_RETURN(0);
}
@@ -990,18 +1035,31 @@ int spider_db_mysql_result::fetch_table_cardinality(
mysql_row = mysql_fetch_row(db_result);
}
}
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
DBUG_RETURN(0);
}
int spider_db_mysql_result::fetch_table_mon_status(
int &status
) {
+ int error_num;
MYSQL_ROW mysql_row;
DBUG_ENTER("spider_db_mysql_result::fetch_table_mon_status");
DBUG_PRINT("info",("spider this=%p", this));
if (!(mysql_row = mysql_fetch_row(db_result)))
{
DBUG_PRINT("info",("spider fetch row is null"));
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
if (num_fields() != 1)
@@ -1018,6 +1076,65 @@ int spider_db_mysql_result::fetch_table_mon_status(
DBUG_RETURN(0);
}
+int spider_db_mysql_result::fetch_show_master_status(
+ const char **binlog_file_name,
+ const char **binlog_pos
+) {
+ int error_num;
+ MYSQL_ROW mysql_row;
+ DBUG_ENTER("spider_db_mysql_result::fetch_show_master_status");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (!(mysql_row = mysql_fetch_row(db_result)))
+ {
+ DBUG_PRINT("info",("spider fetch row is null"));
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
+ }
+ if (num_fields() != 4)
+ {
+ DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
+ }
+
+ *binlog_file_name = mysql_row[0];
+ DBUG_PRINT("info",("spider binlog_file_name=%s", *binlog_file_name));
+ *binlog_pos = mysql_row[1];
+ DBUG_PRINT("info",("spider binlog_pos=%s", *binlog_pos));
+ DBUG_RETURN(0);
+}
+
+int spider_db_mysql_result::fetch_select_binlog_gtid_pos(
+ const char **gtid_pos
+) {
+ int error_num;
+ MYSQL_ROW mysql_row;
+ DBUG_ENTER("spider_db_mysql_result::fetch_select_binlog_gtid_pos");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (!(mysql_row = mysql_fetch_row(db_result)))
+ {
+ DBUG_PRINT("info",("spider fetch row is null"));
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
+ }
+ if (num_fields() != 1)
+ {
+ DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
+ }
+
+ *gtid_pos = mysql_row[0];
+ DBUG_PRINT("info",("spider gtid_pos=%s", *gtid_pos));
+ DBUG_RETURN(0);
+}
+
longlong spider_db_mysql_result::num_rows()
{
DBUG_ENTER("spider_db_mysql_result::num_rows");
@@ -1058,12 +1175,20 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
spider_string *str,
CHARSET_INFO *access_charset
) {
+ int error_num;
+ uint length;
MYSQL_ROW mysql_row;
DBUG_ENTER("spider_db_mysql_result::fetch_columns_for_discover_table_structure");
DBUG_PRINT("info",("spider this=%p", this));
if (!(mysql_row = mysql_fetch_row(db_result)))
{
DBUG_PRINT("info",("spider fetch row is null"));
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
if (num_fields() != 7)
@@ -1094,21 +1219,23 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
}
if (mysql_row[3])
{
- if (str->reserve(SPIDER_SQL_CHARACTER_SET_LEN))
+ length = strlen(mysql_row[3]);
+ if (str->reserve(SPIDER_SQL_CHARACTER_SET_LEN + length))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
str->q_append(SPIDER_SQL_CHARACTER_SET_STR, SPIDER_SQL_CHARACTER_SET_LEN);
- str->q_append(mysql_row[3], strlen(mysql_row[3]));
+ str->q_append(mysql_row[3], length);
}
if (mysql_row[4])
{
- if (str->reserve(SPIDER_SQL_COLLATE_LEN))
+ length = strlen(mysql_row[4]);
+ if (str->reserve(SPIDER_SQL_COLLATE_LEN + length))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
str->q_append(SPIDER_SQL_COLLATE_STR, SPIDER_SQL_COLLATE_LEN);
- str->q_append(mysql_row[4], strlen(mysql_row[4]));
+ str->q_append(mysql_row[4], length);
}
if (!strcmp(mysql_row[2], "NO"))
{
@@ -1124,16 +1251,10 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
str->q_append(SPIDER_SQL_DEFAULT_STR, SPIDER_SQL_DEFAULT_LEN);
- if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
if (str->append(mysql_row[1], strlen(mysql_row[1]), access_charset))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
}
} else {
if (str->reserve(SPIDER_SQL_DEFAULT_LEN))
@@ -1143,16 +1264,10 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
str->q_append(SPIDER_SQL_DEFAULT_STR, SPIDER_SQL_DEFAULT_LEN);
if (mysql_row[1])
{
- if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
if (str->append(mysql_row[1], strlen(mysql_row[1]), access_charset))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
} else {
if (str->reserve(SPIDER_SQL_NULL_LEN))
{
@@ -1173,6 +1288,12 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
}
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
} while ((mysql_row = mysql_fetch_row(db_result)));
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
DBUG_RETURN(0);
}
@@ -1180,15 +1301,18 @@ int spider_db_mysql_result::fetch_index_for_discover_table_structure(
spider_string *str,
CHARSET_INFO *access_charset
) {
+ int error_num;
MYSQL_ROW mysql_row;
DBUG_ENTER("spider_db_mysql_result::fetch_index_for_discover_table_structure");
DBUG_PRINT("info",("spider this=%p", this));
if (!(mysql_row = mysql_fetch_row(db_result)))
{
DBUG_PRINT("info",("spider fetch row is null"));
- if (mysql_errno(db_result->handle))
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
{
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
}
DBUG_RETURN(0);
}
@@ -1356,6 +1480,12 @@ int spider_db_mysql_result::fetch_index_for_discover_table_structure(
else
using_hash = FALSE;
} while ((mysql_row = mysql_fetch_row(db_result)));
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
if (!first)
{
if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN + SPIDER_SQL_COMMA_LEN +
@@ -1376,12 +1506,19 @@ int spider_db_mysql_result::fetch_table_for_discover_table_structure(
SPIDER_SHARE *spider_share,
CHARSET_INFO *access_charset
) {
+ int error_num;
MYSQL_ROW mysql_row;
DBUG_ENTER("spider_db_mysql_result::fetch_table_for_discover_table_structure");
DBUG_PRINT("info",("spider this=%p", this));
if (!(mysql_row = mysql_fetch_row(db_result)))
{
DBUG_PRINT("info",("spider fetch row is null"));
+ if ((error_num = mysql_errno(((spider_db_mysql *) db_conn)->db_conn)))
+ {
+ my_message(error_num,
+ mysql_error(((spider_db_mysql *) db_conn)->db_conn), MYF(0));
+ DBUG_RETURN(error_num);
+ }
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
if (num_fields() != 18)
@@ -1916,7 +2053,7 @@ spider_db_result *spider_db_mysql::store_result(
DBUG_ENTER("spider_db_mysql::store_result");
DBUG_PRINT("info",("spider this=%p", this));
DBUG_ASSERT(!spider_res_buf);
- if ((result = new spider_db_mysql_result()))
+ if ((result = new spider_db_mysql_result(this)))
{
*error_num = 0;
if (
@@ -1942,7 +2079,7 @@ spider_db_result *spider_db_mysql::use_result(
spider_db_mysql_result *result;
DBUG_ENTER("spider_db_mysql::use_result");
DBUG_PRINT("info",("spider this=%p", this));
- if ((result = new spider_db_mysql_result()))
+ if ((result = new spider_db_mysql_result(this)))
{
*error_num = 0;
if (
@@ -2438,6 +2575,237 @@ int spider_db_mysql::set_time_zone(
DBUG_RETURN(0);
}
+int spider_db_mysql::exec_simple_sql_with_result(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ const char *sql,
+ uint sql_length,
+ int all_link_idx,
+ int *need_mon,
+ SPIDER_DB_RESULT **res
+) {
+ int error_num;
+ DBUG_ENTER("spider_db_mysql::exec_simple_sql_with_result");
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
+ spider_conn_set_timeout_from_share(conn, all_link_idx, trx->thd,
+ share);
+ if (
+ (error_num = spider_db_set_names_internal(trx, share, conn,
+ all_link_idx, need_mon)) ||
+ (
+ spider_db_query(
+ conn,
+ sql,
+ sql_length,
+ -1,
+ need_mon) &&
+ (error_num = spider_db_errorno(conn))
+ )
+ ) {
+ if (
+ error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM &&
+ !conn->disable_reconnect
+ ) {
+ /* retry */
+ if ((error_num = spider_db_ping_internal(share, conn,
+ all_link_idx, need_mon)))
+ {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ DBUG_PRINT("info", ("spider error_num=%d 1", error_num));
+ DBUG_RETURN(error_num);
+ }
+ if ((error_num = spider_db_set_names_internal(trx, share, conn,
+ all_link_idx, need_mon)))
+ {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ DBUG_PRINT("info", ("spider error_num=%d 2", error_num));
+ DBUG_RETURN(error_num);
+ }
+ spider_conn_set_timeout_from_share(conn, all_link_idx, trx->thd,
+ share);
+ if (spider_db_query(
+ conn,
+ sql,
+ sql_length,
+ -1,
+ need_mon)
+ ) {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ DBUG_PRINT("info", ("spider error_num=%d 3", error_num));
+ DBUG_RETURN(spider_db_errorno(conn));
+ }
+ } else {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ DBUG_PRINT("info", ("spider error_num=%d 4", error_num));
+ DBUG_RETURN(error_num);
+ }
+ }
+ if (!(*res = store_result(NULL, NULL, &error_num)))
+ {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ if (error_num || (error_num = spider_db_errorno(conn)))
+ {
+ DBUG_PRINT("info", ("spider error_num=%d 5", error_num));
+ DBUG_RETURN(error_num);
+ } else {
+ DBUG_PRINT("info", ("spider error_num=%d 6",
+ ER_QUERY_ON_FOREIGN_DATA_SOURCE));
+ DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
+ }
+ }
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ DBUG_RETURN(0);
+}
+
+int spider_db_mysql::show_master_status(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ int all_link_idx,
+ int *need_mon,
+ TABLE *table,
+ spider_string *str,
+ int mode,
+ SPIDER_DB_RESULT **res1,
+ SPIDER_DB_RESULT **res2
+) {
+ int error_num;
+ const char *binlog_file_name, *binlog_pos;
+ uint binlog_file_name_length, binlog_pos_length;
+ DBUG_ENTER("spider_db_mysql::show_master_status");
+ if ((error_num = exec_simple_sql_with_result(trx, share,
+ SPIDER_SQL_SHOW_MASTER_STATUS_STR, SPIDER_SQL_SHOW_MASTER_STATUS_LEN,
+ all_link_idx, need_mon, res1))
+ ) {
+ DBUG_PRINT("info", ("spider error_num=%d 1", error_num));
+ DBUG_RETURN(error_num);
+ }
+
+ if (!(error_num = ((spider_db_mysql_result *)*res1)->fetch_show_master_status(
+ &binlog_file_name, &binlog_pos))
+ ) {
+ binlog_file_name_length = strlen(binlog_file_name);
+ binlog_pos_length = strlen(binlog_pos);
+ spider_store_binlog_pos_binlog_file(table,
+ binlog_file_name, binlog_file_name_length,
+ binlog_pos, binlog_pos_length, conn->access_charset);
+ if (mode > 0)
+ {
+ error_num = select_binlog_gtid_pos(
+ trx,
+ share,
+ all_link_idx,
+ need_mon,
+ table,
+ str,
+ binlog_file_name,
+ binlog_file_name_length,
+ binlog_pos,
+ binlog_pos_length,
+ res2
+ );
+ } else {
+ spider_store_binlog_pos_gtid(table, NULL, 0, conn->access_charset);
+ }
+ }
+/*
+ res->free_result();
+ delete res;
+*/
+ if (error_num)
+ {
+ DBUG_PRINT("info", ("spider error_num=%d 2", error_num));
+ DBUG_RETURN(error_num);
+ }
+ DBUG_RETURN(0);
+}
+
+int spider_db_mysql::select_binlog_gtid_pos(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ int all_link_idx,
+ int *need_mon,
+ TABLE *table,
+ spider_string *str,
+ const char *binlog_file_name,
+ uint binlog_file_name_length,
+ const char *binlog_pos,
+ uint binlog_pos_length,
+ SPIDER_DB_RESULT **res
+) {
+ int error_num;
+ size_t length;
+ const char *gtid_pos;
+ DBUG_ENTER("spider_db_mysql::select_binlog_gtid_pos");
+ str->length(0);
+ if (str->reserve(
+ SPIDER_SQL_BINLOG_GTID_POS_LEN +
+ SPIDER_SQL_OPEN_PAREN_LEN +
+ SPIDER_SQL_VALUE_QUOTE_LEN +
+ binlog_file_name_length * 2 +
+ SPIDER_SQL_VALUE_QUOTE_LEN +
+ SPIDER_SQL_COMMA_LEN +
+ SPIDER_SQL_VALUE_QUOTE_LEN +
+ binlog_pos_length * 2 +
+ SPIDER_SQL_VALUE_QUOTE_LEN +
+ SPIDER_SQL_CLOSE_PAREN_LEN
+ ))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_BINLOG_GTID_POS_STR,
+ SPIDER_SQL_BINLOG_GTID_POS_LEN);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN);
+ str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ length = conn->db_conn->escape_string((char *)str->ptr() + str->length(),
+ binlog_file_name, binlog_file_name_length);
+ str->length(str->length() + length);
+ str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ length = conn->db_conn->escape_string((char *)str->ptr() + str->length(),
+ binlog_pos, binlog_pos_length);
+ str->length(str->length() + length);
+ str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, SPIDER_SQL_CLOSE_PAREN_LEN);
+
+ if ((error_num = exec_simple_sql_with_result(trx, share,
+ str->ptr(), str->length(), all_link_idx, need_mon, res)))
+ {
+ DBUG_PRINT("info", ("spider error_num=%d 1", error_num));
+ DBUG_RETURN(error_num);
+ }
+ if (!(error_num = ((spider_db_mysql_result *)*res)->fetch_select_binlog_gtid_pos(&gtid_pos)))
+ {
+ spider_store_binlog_pos_gtid(table, gtid_pos, strlen(gtid_pos), conn->access_charset);
+ }
+/*
+ res->free_result();
+ delete res;
+*/
+ if (error_num)
+ {
+ DBUG_PRINT("info", ("spider error_num=%d 2", error_num));
+ DBUG_RETURN(error_num);
+ }
+ DBUG_RETURN(0);
+}
+
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
int spider_db_mysql::append_sql(
char *sql,
@@ -3229,7 +3597,9 @@ int spider_db_mysql_util::open_item_func(
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
) {
uint dbton_id = spider_dbton_mysql.dbton_id;
int error_num;
@@ -3242,6 +3612,7 @@ int spider_db_mysql_util::open_item_func(
separete_str_length = SPIDER_SQL_NULL_CHAR_LEN,
last_str_length = SPIDER_SQL_NULL_CHAR_LEN;
int use_pushdown_udf;
+ bool merge_func = FALSE;
DBUG_ENTER("spider_db_mysql_util::open_item_func");
if (str)
{
@@ -3305,7 +3676,7 @@ int spider_db_mysql_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_int(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (
!strncasecmp("case", func_name, func_name_length)
) {
@@ -3321,7 +3692,7 @@ int spider_db_mysql_util::open_item_func(
{
if ((error_num = spider_db_print_item_type(
item_list[item_func_case->first_expr_num], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
for (roop_count = 0; roop_count < item_func_case->ncases;
@@ -3335,7 +3706,7 @@ int spider_db_mysql_util::open_item_func(
}
if ((error_num = spider_db_print_item_type(
item_list[roop_count], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3345,7 +3716,7 @@ int spider_db_mysql_util::open_item_func(
}
if ((error_num = spider_db_print_item_type(
item_list[roop_count + 1], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (item_func_case->else_expr_num != -1)
@@ -3358,7 +3729,7 @@ int spider_db_mysql_util::open_item_func(
}
if ((error_num = spider_db_print_item_type(
item_list[item_func_case->else_expr_num], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (str)
@@ -3395,7 +3766,7 @@ int spider_db_mysql_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (
!strncasecmp("convert", func_name, func_name_length)
) {
@@ -3420,41 +3791,110 @@ int spider_db_mysql_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (func_name_length == 9 &&
!strncasecmp("isnottrue", func_name, func_name_length)
) {
last_str = SPIDER_SQL_IS_NOT_TRUE_STR;
last_str_length = SPIDER_SQL_IS_NOT_TRUE_LEN;
break;
- } else if (func_name_length == 10 &&
- !strncasecmp("isnotfalse", func_name, func_name_length)
- ) {
- last_str = SPIDER_SQL_IS_NOT_FALSE_STR;
- last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN;
- break;
+ } else if (func_name_length == 10)
+ {
+ if (!strncasecmp("isnotfalse", func_name, func_name_length))
+ {
+ last_str = SPIDER_SQL_IS_NOT_FALSE_STR;
+ last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN;
+ break;
+ } else if (!strncasecmp("column_get", func_name, func_name_length))
+ {
+ if (str)
+ {
+ str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
+ if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(func_name, func_name_length);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN);
+ }
+ func_name = SPIDER_SQL_COMMA_STR;
+ func_name_length = SPIDER_SQL_COMMA_LEN;
+ separete_str = SPIDER_SQL_COMMA_STR;
+ separete_str_length = SPIDER_SQL_COMMA_LEN;
+ break;
+ }
} else if (func_name_length == 12)
{
if (!strncasecmp("cast_as_date", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_DATE_STR;
last_str_length = SPIDER_SQL_AS_DATE_LEN;
break;
} else if (!strncasecmp("cast_as_time", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_TIME_STR;
last_str_length = SPIDER_SQL_AS_TIME_LEN;
@@ -3467,7 +3907,7 @@ int spider_db_mysql_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (!strncasecmp("timestampdiff", func_name, func_name_length))
{
#ifdef ITEM_FUNC_TIMESTAMPDIFF_ARE_PUBLIC
@@ -3530,7 +3970,7 @@ int spider_db_mysql_util::open_item_func(
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
}
if ((error_num = spider_db_print_item_type(item_list[0], spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3539,7 +3979,7 @@ int spider_db_mysql_util::open_item_func(
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
}
if ((error_num = spider_db_print_item_type(item_list[1], spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3557,6 +3997,29 @@ int spider_db_mysql_util::open_item_func(
{
if (!strncasecmp("cast_as_binary", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2;
@@ -3564,9 +4027,12 @@ int spider_db_mysql_util::open_item_func(
tmp_str.init_calc_mem(123);
tmp_str.length(0);
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
#if MYSQL_VERSION_ID < 50500
item_func->print(tmp_str.get_str(), QT_IS);
#else
@@ -3585,12 +4051,38 @@ int spider_db_mysql_util::open_item_func(
break;
} else if (!strncasecmp("cast_as_signed", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_SIGNED_STR;
last_str_length = SPIDER_SQL_AS_SIGNED_LEN;
@@ -3600,12 +4092,38 @@ int spider_db_mysql_util::open_item_func(
{
if (!strncasecmp("cast_as_unsigned", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_UNSIGNED_STR;
last_str_length = SPIDER_SQL_AS_UNSIGNED_LEN;
@@ -3613,6 +4131,29 @@ int spider_db_mysql_util::open_item_func(
} else if (!strncasecmp("decimal_typecast", func_name,
func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2;
@@ -3620,9 +4161,12 @@ int spider_db_mysql_util::open_item_func(
tmp_str.init_calc_mem(124);
tmp_str.length(0);
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
#if MYSQL_VERSION_ID < 50500
item_func->print(tmp_str.get_str(), QT_IS);
#else
@@ -3642,12 +4186,38 @@ int spider_db_mysql_util::open_item_func(
} else if (!strncasecmp("cast_as_datetime", func_name,
func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_DATETIME_STR;
last_str_length = SPIDER_SQL_AS_DATETIME_LEN;
@@ -3663,7 +4233,7 @@ int spider_db_mysql_util::open_item_func(
item_date_add_interval->int_type];
func_name_length = strlen(func_name);
if ((error_num = spider_db_print_item_type(item_list[0], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3680,7 +4250,7 @@ int spider_db_mysql_util::open_item_func(
}
}
if ((error_num = spider_db_print_item_type(item_list[1], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3711,9 +4281,33 @@ int spider_db_mysql_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item_func::CHAR_TYPECAST_FUNC:
+ DBUG_PRINT("info",("spider CHAR_TYPECAST_FUNC"));
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2;
@@ -3721,9 +4315,12 @@ int spider_db_mysql_util::open_item_func(
tmp_str.init_calc_mem(125);
tmp_str.length(0);
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
#if MYSQL_VERSION_ID < 50500
item_func->print(tmp_str.get_str(), QT_IS);
#else
@@ -3756,12 +4353,15 @@ int spider_db_mysql_util::open_item_func(
bool has_other_item = FALSE;
while((item = lif++))
{
+#ifdef SPIDER_HAS_EXPR_CACHE_ITEM
if (
item->type() == Item::EXPR_CACHE_ITEM
) {
DBUG_PRINT("info",("spider EXPR_CACHE_ITEM"));
has_expr_cache_item = TRUE;
- } else if (
+ } else
+#endif
+ if (
item->type() == Item::FUNC_ITEM &&
((Item_func *) item)->functype() == Item_func::ISNOTNULL_FUNC
) {
@@ -3865,7 +4465,7 @@ int spider_db_mysql_util::open_item_func(
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(
spider_db_open_item_cond((Item_cond *) item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item_func::TRIG_COND_FUNC:
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
case Item_func::GUSERVAR_FUNC:
@@ -3873,10 +4473,10 @@ int spider_db_mysql_util::open_item_func(
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
if (item_func->result_type() == STRING_RESULT)
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
else
DBUG_RETURN(spider_db_open_item_int(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item_func::FT_FUNC:
if (spider_db_check_ft_idx(item_func, spider) == MAX_KEY)
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
@@ -3982,7 +4582,7 @@ int spider_db_mysql_util::open_item_func(
{
item = item_list[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (roop_count == 1)
{
@@ -4000,7 +4600,7 @@ int spider_db_mysql_util::open_item_func(
}
item = item_list[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (item_func->functype() == Item_func::FT_FUNC)
@@ -4014,7 +4614,7 @@ int spider_db_mysql_util::open_item_func(
}
item = item_list[0];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -4042,7 +4642,8 @@ int spider_db_mysql_util::open_item_func(
{
Item_func_conv_charset *item_func_conv_charset =
(Item_func_conv_charset *)item_func;
- CHARSET_INFO *conv_charset = item_func_conv_charset->collation.collation;
+ CHARSET_INFO *conv_charset =
+ item_func_conv_charset->SPIDER_Item_func_conv_charset_conv_charset;
uint cset_length = strlen(conv_charset->csname);
if (str->reserve(SPIDER_SQL_USING_LEN + cset_length))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -4053,6 +4654,8 @@ int spider_db_mysql_util::open_item_func(
}
if (str)
{
+ if (merge_func)
+ str->length(str->length() - SPIDER_SQL_CLOSE_PAREN_LEN);
if (str->reserve(last_str_length + SPIDER_SQL_CLOSE_PAREN_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
str->q_append(last_str, last_str_length);
@@ -4067,7 +4670,9 @@ int spider_db_mysql_util::open_item_sum_func(
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
) {
uint dbton_id = spider_dbton_mysql.dbton_id;
uint roop_count, item_count = item_sum->get_arg_count();
@@ -4097,7 +4702,7 @@ int spider_db_mysql_util::open_item_sum_func(
{
item = args[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -4108,7 +4713,7 @@ int spider_db_mysql_util::open_item_sum_func(
}
item = args[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (str)
@@ -4148,6 +4753,125 @@ int spider_db_mysql_util::append_escaped_util(
DBUG_RETURN(0);
}
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+int spider_db_mysql_util::append_from_and_tables(
+ spider_fields *fields,
+ spider_string *str
+) {
+ SPIDER_TABLE_HOLDER *table_holder;
+ int error_num;
+ uint dbton_id = spider_dbton_mysql.dbton_id, from_length;
+ spider_mysql_share *db_share;
+ spider_mysql_handler *dbton_hdl;
+ ha_spider *spider;
+ DBUG_ENTER("spider_db_mysql_util::append_from_and_tables");
+ DBUG_PRINT("info",("spider this=%p", this));
+
+ /* calculate from size */
+ from_length = SPIDER_SQL_FROM_LEN;
+ fields->set_pos_to_first_table_holder();
+ while ((table_holder = fields->get_next_table_holder()))
+ {
+ spider = table_holder->spider;
+ db_share = (spider_mysql_share *)
+ spider->share->dbton_share[dbton_id];
+ from_length +=
+ db_share->db_nm_max_length +
+ SPIDER_SQL_DOT_LEN + /* SPIDER_SQL_NAME_QUOTE_LEN */ 4 +
+ db_share->table_nm_max_length +
+ SPIDER_SQL_SPACE_LEN + SPIDER_SQL_COMMA_LEN +
+ table_holder->alias->length() - SPIDER_SQL_DOT_LEN;
+ }
+
+ if (str->reserve(from_length))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN);
+
+ fields->set_pos_to_first_table_holder();
+ while ((table_holder = fields->get_next_table_holder()))
+ {
+ spider = table_holder->spider;
+ db_share = (spider_mysql_share *)
+ spider->share->dbton_share[dbton_id];
+ dbton_hdl = (spider_mysql_handler *)
+ spider->dbton_handler[dbton_id];
+ dbton_hdl->table_name_pos = str->length();
+ if ((error_num = db_share->append_table_name_with_adjusting(str,
+ spider->conn_link_idx[dbton_hdl->first_link_idx])))
+ {
+ DBUG_RETURN(error_num);
+ }
+ str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN);
+ str->q_append(table_holder->alias->ptr(),
+ table_holder->alias->length() - SPIDER_SQL_DOT_LEN);
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ }
+ str->length(str->length() - SPIDER_SQL_COMMA_LEN);
+ DBUG_RETURN(0);
+}
+
+int spider_db_mysql_util::reappend_tables(
+ spider_fields *fields,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain,
+ spider_string *str
+) {
+ int error_num;
+ uint dbton_id = spider_dbton_mysql.dbton_id, length;
+ ha_spider *spider;
+ spider_mysql_share *db_share;
+ spider_mysql_handler *dbton_hdl;
+ SPIDER_TABLE_HOLDER *table_holder;
+ SPIDER_LINK_IDX_HOLDER *link_idx_holder;
+ DBUG_ENTER("spider_db_mysql_util::reappend_tables");
+ DBUG_PRINT("info",("spider this=%p", this));
+ length = str->length();
+ fields->set_pos_to_first_table_on_link_idx_chain(link_idx_chain);
+ fields->set_pos_to_first_table_holder();
+ while ((table_holder = fields->get_next_table_holder()))
+ {
+ link_idx_holder =
+ fields->get_next_table_on_link_idx_chain(link_idx_chain);
+ spider = table_holder->spider;
+ db_share = (spider_mysql_share *)
+ spider->share->dbton_share[dbton_id];
+ if (!db_share->same_db_table_name)
+ {
+ dbton_hdl = (spider_mysql_handler *) spider->dbton_handler[dbton_id];
+ str->length(dbton_hdl->table_name_pos);
+ if ((error_num = db_share->append_table_name_with_adjusting(str,
+ spider->conn_link_idx[link_idx_holder->link_idx])))
+ {
+ DBUG_RETURN(error_num);
+ }
+ }
+ }
+ str->length(length);
+ DBUG_RETURN(0);
+}
+
+int spider_db_mysql_util::append_where(
+ spider_string *str
+) {
+ DBUG_ENTER("spider_db_mysql_util::append_where");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (str->reserve(SPIDER_SQL_WHERE_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_WHERE_STR, SPIDER_SQL_WHERE_LEN);
+ DBUG_RETURN(0);
+}
+
+int spider_db_mysql_util::append_having(
+ spider_string *str
+) {
+ DBUG_ENTER("spider_db_mysql_util::append_having");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (str->reserve(SPIDER_SQL_HAVING_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_HAVING_STR, SPIDER_SQL_HAVING_LEN);
+ DBUG_RETURN(0);
+}
+#endif
+
spider_mysql_share::spider_mysql_share(
st_spider_share *share
) : spider_db_share(
@@ -5262,6 +5986,61 @@ int spider_mysql_handler::init()
DBUG_RETURN(0);
}
+
+int spider_mysql_handler::append_index_hint(
+ spider_string *str,
+ int link_idx,
+ ulong sql_type
+ )
+{
+ List<Index_hint> *index_hints = spider_get_index_hints(spider);
+ List_iterator <Index_hint> iter(*index_hints);
+ Index_hint *hint;
+// THD *thd = current_thd;
+ int error_num = 0;
+ DBUG_ENTER("spider_mysql_handler::append_index_hint");
+ DBUG_PRINT("info",("spider this=%p", this));
+
+ while(index_hints && (hint = iter++))
+ {
+// hint->print(thd, str);
+ if (sql_type != SPIDER_SQL_TYPE_HANDLER)
+ {
+ switch(hint->type)
+ {
+ case INDEX_HINT_IGNORE:
+ if (str->reserve(hint->key_name.length+ SPIDER_SQL_INDEX_IGNORE_LEN + SPIDER_SQL_OPEN_PAREN_LEN + SPIDER_SQL_CLOSE_PAREN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_INDEX_IGNORE_STR,SPIDER_SQL_INDEX_IGNORE_LEN);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR,SPIDER_SQL_OPEN_PAREN_LEN);
+ str->q_append(hint->key_name.str, hint->key_name.length);
+ str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,SPIDER_SQL_CLOSE_PAREN_LEN);
+ break;
+ case INDEX_HINT_USE:
+ if (str->reserve(hint->key_name.length+ SPIDER_SQL_INDEX_USE_LEN + SPIDER_SQL_OPEN_PAREN_LEN + SPIDER_SQL_CLOSE_PAREN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_INDEX_USE_STR,SPIDER_SQL_INDEX_USE_LEN);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR,SPIDER_SQL_OPEN_PAREN_LEN);
+ str->q_append(hint->key_name.str, hint->key_name.length);
+ str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,SPIDER_SQL_CLOSE_PAREN_LEN);
+ break;
+ case INDEX_HINT_FORCE:
+ if (str->reserve(hint->key_name.length+ SPIDER_SQL_INDEX_FORCE_LEN + SPIDER_SQL_OPEN_PAREN_LEN + SPIDER_SQL_CLOSE_PAREN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_INDEX_FORCE_STR,SPIDER_SQL_INDEX_FORCE_LEN);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR,SPIDER_SQL_OPEN_PAREN_LEN);
+ str->q_append(hint->key_name.str, hint->key_name.length);
+ str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,SPIDER_SQL_CLOSE_PAREN_LEN);
+ break;
+ default:
+ // SPIDER_SQL_COMMA_STR
+ break;
+ }
+ }
+ }
+ DBUG_RETURN(error_num);
+}
+
int spider_mysql_handler::append_table_name_with_adjusting(
spider_string *str,
int link_idx,
@@ -6282,7 +7061,7 @@ int spider_mysql_handler::append_direct_update_set(
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
str->q_append(SPIDER_SQL_SET_STR, SPIDER_SQL_SET_LEN);
DBUG_RETURN(spider_db_append_update_columns(spider, str, NULL, 0,
- spider_dbton_mysql.dbton_id));
+ spider_dbton_mysql.dbton_id, FALSE, NULL));
}
if (
@@ -6387,7 +7166,7 @@ int spider_mysql_handler::append_update_columns(
int error_num;
DBUG_ENTER("spider_mysql_handler::append_update_columns");
error_num = spider_db_append_update_columns(spider, str,
- alias, alias_length, spider_dbton_mysql.dbton_id);
+ alias, alias_length, spider_dbton_mysql.dbton_id, FALSE, NULL);
DBUG_RETURN(error_num);
}
#endif
@@ -6814,7 +7593,7 @@ int spider_mysql_handler::check_item_type(
DBUG_ENTER("spider_mysql_handler::check_item_type");
DBUG_PRINT("info",("spider this=%p", this));
error_num = spider_db_print_item_type(item, spider, NULL, NULL, 0,
- spider_dbton_mysql.dbton_id);
+ spider_dbton_mysql.dbton_id, FALSE, NULL);
DBUG_RETURN(error_num);
}
@@ -7614,7 +8393,7 @@ int spider_mysql_handler::append_condition(
}
if ((error_num = spider_db_print_item_type(
(Item *) tmp_cond->cond, spider, str, alias, alias_length,
- spider_dbton_mysql.dbton_id)))
+ spider_dbton_mysql.dbton_id, FALSE, NULL)))
{
if (str && error_num == ER_SPIDER_COND_SKIP_NUM)
{
@@ -7822,7 +8601,7 @@ int spider_mysql_handler::append_sum_select(
for (item_sum_ptr = join->sum_funcs; *item_sum_ptr; ++item_sum_ptr)
{
if ((error_num = spider_db_mysql_utility.open_item_sum_func(*item_sum_ptr,
- spider, str, alias, alias_length)))
+ spider, str, alias, alias_length, FALSE, NULL)))
{
DBUG_RETURN(error_num);
}
@@ -7937,7 +8716,7 @@ int spider_mysql_handler::append_group_by(
for (; group; group = group->next)
{
if ((error_num = spider_db_print_item_type((*group->item), spider, str,
- alias, alias_length, spider_dbton_mysql.dbton_id)))
+ alias, alias_length, spider_dbton_mysql.dbton_id, FALSE, NULL)))
{
DBUG_RETURN(error_num);
}
@@ -8130,12 +8909,12 @@ int spider_mysql_handler::append_key_order_for_direct_order_limit_with_alias(
{
if ((error_num =
spider_db_print_item_type((*order->item), spider, str, alias,
- alias_length, spider_dbton_mysql.dbton_id)))
+ alias_length, spider_dbton_mysql.dbton_id, FALSE, NULL)))
{
DBUG_PRINT("info",("spider error=%d", error_num));
DBUG_RETURN(error_num);
}
- if (order->direction == ORDER::ORDER_ASC)
+ if (SPIDER_order_direction_is_asc(order))
{
if (str->reserve(SPIDER_SQL_COMMA_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -9043,6 +9822,7 @@ int spider_mysql_handler::append_from(
DBUG_ENTER("spider_mysql_handler::append_from");
DBUG_PRINT("info",("spider this=%p", this));
DBUG_PRINT("info",("spider link_idx=%d", link_idx));
+ int error_num = 0;
if (sql_type == SPIDER_SQL_TYPE_HANDLER)
{
ha_table_name_pos = str->length();
@@ -9062,6 +9842,13 @@ int spider_mysql_handler::append_from(
str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN);
table_name_pos = str->length();
append_table_name_with_adjusting(str, link_idx, sql_type);
+ if(spider_param_index_hint_pushdown(spider->trx->thd))
+ {
+ if((error_num = append_index_hint(str, link_idx, sql_type)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ }
}
DBUG_RETURN(0);
}
@@ -9529,51 +10316,52 @@ int spider_mysql_handler::append_explain_select(
* solely of the specified column.
* FALSE - otherwise.
********************************************************************/
-bool spider_mysql_handler::is_sole_projection_field( uint16 field_index )
-{
- // Determine whether the projection list consists solely of the field of interest
- bool is_field_in_projection_list = FALSE;
- TABLE* table = spider->get_table();
- uint16 projection_field_count = 0;
- uint16 projection_field_index;
- Field** field;
- DBUG_ENTER( "spider_mysql_handler::is_sole_projection_field" );
-
- for ( field = table->field; *field ; field++ )
- {
- projection_field_index = ( *field )->field_index;
+bool spider_mysql_handler::is_sole_projection_field(
+ uint16 field_index
+) {
+ // Determine whether the projection list consists solely of the field of interest
+ bool is_field_in_projection_list = FALSE;
+ TABLE* table = spider->get_table();
+ uint16 projection_field_count = 0;
+ uint16 projection_field_index;
+ Field** field;
+ DBUG_ENTER( "spider_mysql_handler::is_sole_projection_field" );
- if ( !( minimum_select_bit_is_set( projection_field_index ) ) )
- {
- // Current field is not in the projection list
- continue;
- }
+ for ( field = table->field; *field ; field++ )
+ {
+ projection_field_index = ( *field )->field_index;
- projection_field_count++;
+ if ( !( minimum_select_bit_is_set( projection_field_index ) ) )
+ {
+ // Current field is not in the projection list
+ continue;
+ }
- if ( !is_field_in_projection_list )
- {
- if ( field_index == projection_field_index )
- {
- // Field of interest is in the projection list
- is_field_in_projection_list = TRUE;
- }
- }
+ projection_field_count++;
- if ( is_field_in_projection_list && ( projection_field_count != 1 ) )
- {
- // Field of interest is not the sole column in the projection list
- DBUG_RETURN( FALSE );
- }
+ if ( !is_field_in_projection_list )
+ {
+ if ( field_index == projection_field_index )
+ {
+ // Field of interest is in the projection list
+ is_field_in_projection_list = TRUE;
+ }
}
- if ( is_field_in_projection_list && ( projection_field_count == 1 ) )
+ if ( is_field_in_projection_list && ( projection_field_count != 1 ) )
{
- // Field of interest is the only column in the projection list
- DBUG_RETURN( TRUE );
+ // Field of interest is not the sole column in the projection list
+ DBUG_RETURN( FALSE );
}
+ }
- DBUG_RETURN( FALSE );
+ if ( is_field_in_projection_list && ( projection_field_count == 1 ) )
+ {
+ // Field of interest is the only column in the projection list
+ DBUG_RETURN( TRUE );
+ }
+
+ DBUG_RETURN( FALSE );
}
bool spider_mysql_handler::is_bulk_insert_exec_period(
@@ -10039,6 +10827,26 @@ bool spider_mysql_handler::need_lock_before_set_sql_for_exec(
DBUG_RETURN(FALSE);
}
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+int spider_mysql_handler::set_sql_for_exec(
+ ulong sql_type,
+ int link_idx,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain
+) {
+ int error_num;
+ DBUG_ENTER("spider_mysql_handler::set_sql_for_exec");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (sql_type & SPIDER_SQL_TYPE_SELECT_SQL)
+ {
+ if ((error_num = spider_db_mysql_utility.reappend_tables(
+ spider->fields, link_idx_chain, &sql)))
+ DBUG_RETURN(error_num);
+ exec_sql = &sql;
+ }
+ DBUG_RETURN(0);
+}
+#endif
+
int spider_mysql_handler::set_sql_for_exec(
ulong sql_type,
int link_idx
@@ -11841,6 +12649,302 @@ int spider_mysql_handler::reset_union_table_name(
DBUG_RETURN(0);
}
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+int spider_mysql_handler::append_from_and_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_mysql_handler::append_from_and_tables_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = spider_db_mysql_utility.append_from_and_tables(fields, str);
+ DBUG_RETURN(error_num);
+}
+
+int spider_mysql_handler::reappend_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_mysql_handler::reappend_tables_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = spider_db_mysql_utility.reappend_tables(fields,
+ link_idx_chain, str);
+ DBUG_RETURN(error_num);
+}
+
+int spider_mysql_handler::append_where_part(
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_mysql_handler::append_where_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = spider_db_mysql_utility.append_where(str);
+ DBUG_RETURN(error_num);
+}
+
+int spider_mysql_handler::append_having_part(
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_mysql_handler::append_having_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = spider_db_mysql_utility.append_having(str);
+ DBUG_RETURN(error_num);
+}
+
+int spider_mysql_handler::append_item_type_part(
+ Item *item,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_mysql_handler::append_item_type_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = spider_db_print_item_type(item, spider, str, alias, alias_length,
+ spider_dbton_mysql.dbton_id, use_fields, fields);
+ DBUG_RETURN(error_num);
+}
+
+int spider_mysql_handler::append_list_item_select_part(
+ List<Item> *select,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_mysql_handler::append_list_item_select_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = append_list_item_select(select, str, alias, alias_length,
+ use_fields, fields);
+ DBUG_RETURN(error_num);
+}
+
+int spider_mysql_handler::append_list_item_select(
+ List<Item> *select,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+) {
+ int error_num;
+ uint dbton_id = spider_dbton_mysql.dbton_id, length;
+ List_iterator_fast<Item> it(*select);
+ Item *item;
+ Field **field_ptr;
+ DBUG_ENTER("spider_mysql_handler::append_list_item_select");
+ DBUG_PRINT("info",("spider this=%p", this));
+ while ((item = it++))
+ {
+ if ((error_num = spider_db_print_item_type(item, spider, str,
+ alias, alias_length, dbton_id, use_fields, fields)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ field_ptr = fields->get_next_field_ptr();
+ length = (*field_ptr)->field_name.length;
+ if (str->reserve(
+ SPIDER_SQL_COMMA_LEN + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 +
+ SPIDER_SQL_SPACE_LEN + length
+ ))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN);
+ if ((error_num = spider_db_mysql_utility.append_name(str,
+ (*field_ptr)->field_name.str, length)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ }
+ str->length(str->length() - SPIDER_SQL_COMMA_LEN);
+ DBUG_RETURN(0);
+}
+
+int spider_mysql_handler::append_group_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_mysql_handler::append_group_by_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = append_group_by(order, str, alias, alias_length,
+ use_fields, fields);
+ DBUG_RETURN(error_num);
+}
+
+int spider_mysql_handler::append_group_by(
+ ORDER *order,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+) {
+ int error_num;
+ uint dbton_id = spider_dbton_mysql.dbton_id;
+ DBUG_ENTER("spider_mysql_handler::append_group_by");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (order)
+ {
+ if (str->reserve(SPIDER_SQL_GROUP_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_GROUP_STR, SPIDER_SQL_GROUP_LEN);
+ for (; order; order = order->next)
+ {
+ if ((error_num = spider_db_print_item_type((*order->item), spider, str,
+ alias, alias_length, dbton_id, use_fields, fields)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if (str->reserve(SPIDER_SQL_COMMA_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ }
+ str->length(str->length() - SPIDER_SQL_COMMA_LEN);
+ }
+ DBUG_RETURN(0);
+}
+
+int spider_mysql_handler::append_order_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_mysql_handler::append_order_by_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = append_order_by(order, str, alias, alias_length,
+ use_fields, fields);
+ DBUG_RETURN(error_num);
+}
+
+int spider_mysql_handler::append_order_by(
+ ORDER *order,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+) {
+ int error_num;
+ uint dbton_id = spider_dbton_mysql.dbton_id;
+ DBUG_ENTER("spider_mysql_handler::append_order_by");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (order)
+ {
+ if (str->reserve(SPIDER_SQL_ORDER_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_ORDER_STR, SPIDER_SQL_ORDER_LEN);
+ for (; order; order = order->next)
+ {
+ if ((error_num = spider_db_print_item_type((*order->item), spider, str,
+ alias, alias_length, dbton_id, use_fields, fields)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if (SPIDER_order_direction_is_asc(order))
+ {
+ if (str->reserve(SPIDER_SQL_COMMA_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ } else {
+ if (str->reserve(SPIDER_SQL_COMMA_LEN + SPIDER_SQL_DESC_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_DESC_STR, SPIDER_SQL_DESC_LEN);
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ }
+ }
+ str->length(str->length() - SPIDER_SQL_COMMA_LEN);
+ }
+ DBUG_RETURN(0);
+}
+#endif
+
spider_mysql_copy_table::spider_mysql_copy_table(
spider_mysql_share *db_share
) : spider_db_copy_table(
diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h
index 482289d1d68..766c15971ec 100644
--- a/storage/spider/spd_db_mysql.h
+++ b/storage/spider/spd_db_mysql.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012-2014 Kentoku Shiba
+/* Copyright (C) 2012-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
class spider_db_mysql_util: public spider_db_util
{
@@ -99,7 +99,9 @@ public:
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
);
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
int open_item_sum_func(
@@ -107,13 +109,32 @@ public:
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
);
#endif
int append_escaped_util(
spider_string *to,
String *from
);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ int append_from_and_tables(
+ spider_fields *fields,
+ spider_string *str
+ );
+ int reappend_tables(
+ spider_fields *fields,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain,
+ spider_string *str
+ );
+ int append_where(
+ spider_string *str
+ );
+ int append_having(
+ spider_string *str
+ );
+#endif
};
class spider_db_mysql_row: public spider_db_row
@@ -161,7 +182,7 @@ public:
spider_db_mysql_row row;
MYSQL_ROW_OFFSET first_row;
int store_error_num;
- spider_db_mysql_result();
+ spider_db_mysql_result(SPIDER_DB_CONN *in_db_conn);
~spider_db_mysql_result();
bool has_result();
void free_result();
@@ -199,6 +220,13 @@ public:
int fetch_table_mon_status(
int &status
);
+ int fetch_show_master_status(
+ const char **binlog_file_name,
+ const char **binlog_pos
+ );
+ int fetch_select_binlog_gtid_pos(
+ const char **gtid_pos
+ );
longlong num_rows();
uint num_fields();
void move_to_pos(
@@ -224,9 +252,9 @@ public:
class spider_db_mysql: public spider_db_conn
{
- MYSQL *db_conn;
int stored_error;
public:
+ MYSQL *db_conn;
HASH lock_table_hash;
bool lock_table_hash_inited;
uint lock_table_hash_id;
@@ -351,6 +379,39 @@ public:
Time_zone *time_zone,
int *need_mon
);
+ int exec_simple_sql_with_result(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ const char *sql,
+ uint sql_length,
+ int all_link_idx,
+ int *need_mon,
+ SPIDER_DB_RESULT **res
+ );
+ int show_master_status(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ int all_link_idx,
+ int *need_mon,
+ TABLE *table,
+ spider_string *str,
+ int mode,
+ SPIDER_DB_RESULT **res1,
+ SPIDER_DB_RESULT **res2
+ );
+ int select_binlog_gtid_pos(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ int all_link_idx,
+ int *need_mon,
+ TABLE *table,
+ spider_string *str,
+ const char *binlog_file_name,
+ uint binlog_file_name_length,
+ const char *binlog_pos,
+ uint binlog_pos_length,
+ SPIDER_DB_RESULT **res
+ );
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
int append_sql(
char *sql,
@@ -512,7 +573,9 @@ class spider_mysql_handler: public spider_db_handler
int where_pos;
int order_pos;
int limit_pos;
+public:
int table_name_pos;
+private:
int ha_read_pos;
int ha_next_pos;
int ha_where_pos;
@@ -554,6 +617,11 @@ public:
);
~spider_mysql_handler();
int init();
+ int append_index_hint(
+ spider_string *str,
+ int link_idx,
+ ulong sql_type
+ );
int append_table_name_with_adjusting(
spider_string *str,
int link_idx,
@@ -1129,7 +1197,7 @@ public:
int link_idx
);
bool is_sole_projection_field(
- uint16 field_index
+ uint16 field_index
);
bool is_bulk_insert_exec_period(
bool bulk_end
@@ -1199,6 +1267,13 @@ public:
bool need_lock_before_set_sql_for_exec(
ulong sql_type
);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ int set_sql_for_exec(
+ ulong sql_type,
+ int link_idx,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain
+ );
+#endif
int set_sql_for_exec(
ulong sql_type,
int link_idx
@@ -1310,6 +1385,78 @@ public:
int link_idx,
ulong sql_type
);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ int append_from_and_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int reappend_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_where_part(
+ ulong sql_type
+ );
+ int append_having_part(
+ ulong sql_type
+ );
+ int append_item_type_part(
+ Item *item,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_list_item_select_part(
+ List<Item> *select,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_list_item_select(
+ List<Item> *select,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+ );
+ int append_group_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_group_by(
+ ORDER *order,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+ );
+ int append_order_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_order_by(
+ ORDER *order,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+ );
+#endif
};
class spider_mysql_copy_table: public spider_db_copy_table
diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc
index 3e0b96c8492..f9eb305d258 100644
--- a/storage/spider/spd_db_oracle.cc
+++ b/storage/spider/spd_db_oracle.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012-2015 Kentoku Shiba
+/* Copyright (C) 2012-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -48,6 +49,7 @@ extern struct charset_info_st *spd_charset_utf8_bin;
extern handlerton *spider_hton_ptr;
extern pthread_mutex_t spider_open_conn_mutex;
extern HASH spider_open_connections;
+extern HASH spider_ipport_conns;
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
extern const char spider_dig_upper[];
@@ -307,6 +309,12 @@ SPIDER_DB_CONN *spider_oracle_create_conn(
DBUG_RETURN(new spider_db_oracle(conn));
}
+bool spider_oracle_support_direct_join(
+) {
+ DBUG_ENTER("spider_oracle_support_direct_join");
+ DBUG_RETURN(FALSE);
+}
+
spider_db_oracle_util spider_db_oracle_utility;
SPIDER_DBTON spider_dbton_oracle = {
@@ -319,6 +327,7 @@ SPIDER_DBTON spider_dbton_oracle = {
spider_oracle_create_handler,
spider_oracle_create_copy_table,
spider_oracle_create_conn,
+ spider_oracle_support_direct_join,
&spider_db_oracle_utility
};
@@ -745,8 +754,8 @@ int spider_db_oracle_row::fetch()
DBUG_RETURN(0);
}
-spider_db_oracle_result::spider_db_oracle_result() :
- spider_db_result(spider_dbton_oracle.dbton_id),
+spider_db_oracle_result::spider_db_oracle_result(SPIDER_DB_CONN *in_db_conn) :
+ spider_db_result(in_db_conn, spider_dbton_oracle.dbton_id),
db_conn(NULL), stmtp(NULL), field_count(0), access_charset(NULL),
fetched(FALSE)
{
@@ -1563,7 +1572,7 @@ int spider_db_oracle::exec_query(
DBUG_RETURN(error_num);
}
- if ((result = new spider_db_oracle_result()))
+ if ((result = new spider_db_oracle_result(this)))
{
result->db_conn = this;
result->stmtp = stmtp;
@@ -2094,6 +2103,22 @@ int spider_db_oracle::set_time_zone(
DBUG_RETURN(0);
}
+int spider_db_oracle::show_master_status(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ int all_link_idx,
+ int *need_mon,
+ TABLE *table,
+ spider_string *str,
+ int mode,
+ SPIDER_DB_RESULT **res1,
+ SPIDER_DB_RESULT **res2
+) {
+ DBUG_ENTER("spider_db_oracle::show_master_status");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN(0);
+}
+
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
int spider_db_oracle::append_sql(
char *sql,
@@ -2873,7 +2898,9 @@ int spider_db_oracle_util::open_item_func(
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
) {
uint dbton_id = spider_dbton_oracle.dbton_id;
int error_num;
@@ -2886,6 +2913,7 @@ int spider_db_oracle_util::open_item_func(
separete_str_length = SPIDER_SQL_NULL_CHAR_LEN,
last_str_length = SPIDER_SQL_NULL_CHAR_LEN;
int use_pushdown_udf;
+ bool merge_func = FALSE;
DBUG_ENTER("spider_db_oracle_util::open_item_func");
if (str)
{
@@ -2949,7 +2977,7 @@ int spider_db_oracle_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_int(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (
!strncasecmp("case", func_name, func_name_length)
) {
@@ -2965,7 +2993,7 @@ int spider_db_oracle_util::open_item_func(
{
if ((error_num = spider_db_print_item_type(
item_list[item_func_case->first_expr_num], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
for (roop_count = 0; roop_count < item_func_case->ncases;
@@ -2979,7 +3007,7 @@ int spider_db_oracle_util::open_item_func(
}
if ((error_num = spider_db_print_item_type(
item_list[roop_count], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -2989,7 +3017,7 @@ int spider_db_oracle_util::open_item_func(
}
if ((error_num = spider_db_print_item_type(
item_list[roop_count + 1], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (item_func_case->else_expr_num != -1)
@@ -3002,7 +3030,7 @@ int spider_db_oracle_util::open_item_func(
}
if ((error_num = spider_db_print_item_type(
item_list[item_func_case->else_expr_num], spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (str)
@@ -3039,7 +3067,7 @@ int spider_db_oracle_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (
!strncasecmp("convert", func_name, func_name_length)
) {
@@ -3064,41 +3092,110 @@ int spider_db_oracle_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (func_name_length == 9 &&
!strncasecmp("isnottrue", func_name, func_name_length)
) {
last_str = SPIDER_SQL_IS_NOT_TRUE_STR;
last_str_length = SPIDER_SQL_IS_NOT_TRUE_LEN;
break;
- } else if (func_name_length == 10 &&
- !strncasecmp("isnotfalse", func_name, func_name_length)
- ) {
- last_str = SPIDER_SQL_IS_NOT_FALSE_STR;
- last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN;
- break;
+ } else if (func_name_length == 10)
+ {
+ if (!strncasecmp("isnotfalse", func_name, func_name_length))
+ {
+ last_str = SPIDER_SQL_IS_NOT_FALSE_STR;
+ last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN;
+ break;
+ } else if (!strncasecmp("column_get", func_name, func_name_length))
+ {
+ if (str)
+ {
+ str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
+ if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(func_name, func_name_length);
+ str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN);
+ }
+ func_name = SPIDER_SQL_COMMA_STR;
+ func_name_length = SPIDER_SQL_COMMA_LEN;
+ separete_str = SPIDER_SQL_COMMA_STR;
+ separete_str_length = SPIDER_SQL_COMMA_LEN;
+ break;
+ }
} else if (func_name_length == 12)
{
if (!strncasecmp("cast_as_date", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_DATE_STR;
last_str_length = SPIDER_SQL_AS_DATE_LEN;
break;
} else if (!strncasecmp("cast_as_time", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_TIME_STR;
last_str_length = SPIDER_SQL_AS_TIME_LEN;
@@ -3111,7 +3208,7 @@ int spider_db_oracle_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
} else if (!strncasecmp("timestampdiff", func_name, func_name_length))
{
#ifdef ITEM_FUNC_TIMESTAMPDIFF_ARE_PUBLIC
@@ -3174,7 +3271,7 @@ int spider_db_oracle_util::open_item_func(
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
}
if ((error_num = spider_db_print_item_type(item_list[0], spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3183,7 +3280,7 @@ int spider_db_oracle_util::open_item_func(
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
}
if ((error_num = spider_db_print_item_type(item_list[1], spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3201,6 +3298,29 @@ int spider_db_oracle_util::open_item_func(
{
if (!strncasecmp("cast_as_binary", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2;
@@ -3208,9 +3328,12 @@ int spider_db_oracle_util::open_item_func(
tmp_str.init_calc_mem(123);
tmp_str.length(0);
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
#if MYSQL_VERSION_ID < 50500
item_func->print(tmp_str.get_str(), QT_IS);
#else
@@ -3229,12 +3352,38 @@ int spider_db_oracle_util::open_item_func(
break;
} else if (!strncasecmp("cast_as_signed", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_SIGNED_STR;
last_str_length = SPIDER_SQL_AS_SIGNED_LEN;
@@ -3244,12 +3393,38 @@ int spider_db_oracle_util::open_item_func(
{
if (!strncasecmp("cast_as_unsigned", func_name, func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_UNSIGNED_STR;
last_str_length = SPIDER_SQL_AS_UNSIGNED_LEN;
@@ -3257,6 +3432,29 @@ int spider_db_oracle_util::open_item_func(
} else if (!strncasecmp("decimal_typecast", func_name,
func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2;
@@ -3264,9 +3462,12 @@ int spider_db_oracle_util::open_item_func(
tmp_str.init_calc_mem(124);
tmp_str.length(0);
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
#if MYSQL_VERSION_ID < 50500
item_func->print(tmp_str.get_str(), QT_IS);
#else
@@ -3286,12 +3487,38 @@ int spider_db_oracle_util::open_item_func(
} else if (!strncasecmp("cast_as_datetime", func_name,
func_name_length))
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
}
last_str = SPIDER_SQL_AS_DATETIME_STR;
last_str_length = SPIDER_SQL_AS_DATETIME_LEN;
@@ -3319,7 +3546,7 @@ int spider_db_oracle_util::open_item_func(
SPIDER_SQL_OPEN_PAREN_LEN);
}
if ((error_num = spider_db_print_item_type(item_list[0], spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3337,7 +3564,7 @@ int spider_db_oracle_util::open_item_func(
}
}
if ((error_num = spider_db_print_item_type(item_list[1], spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3383,7 +3610,7 @@ int spider_db_oracle_util::open_item_func(
case INTERVAL_SECOND:
case INTERVAL_MICROSECOND:
if ((error_num = spider_db_print_item_type(item_list[0], spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3399,7 +3626,7 @@ int spider_db_oracle_util::open_item_func(
}
}
if ((error_num = spider_db_print_item_type(item_list[1], spider,
- str, alias, alias_length, dbton_id)))
+ str, alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3487,9 +3714,33 @@ int spider_db_oracle_util::open_item_func(
if (str)
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item_func::CHAR_TYPECAST_FUNC:
+ DBUG_PRINT("info",("spider CHAR_TYPECAST_FUNC"));
{
+ item = item_list[0];
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ DBUG_PRINT("info",("spider child is FUNC_ITEM"));
+ Item_func *ifunc = (Item_func *) item;
+ if (ifunc->functype() == Item_func::UNKNOWN_FUNC)
+ {
+ const char *child_func_name;
+ int child_func_name_length;
+ DBUG_PRINT("info",("spider child is UNKNOWN_FUNC"));
+ child_func_name = (char*) ifunc->func_name();
+ child_func_name_length = strlen(child_func_name);
+ DBUG_PRINT("info",("spider child func_name is %s", child_func_name));
+ if (
+ child_func_name_length == 10 &&
+ !strncasecmp("column_get", child_func_name, child_func_name_length)
+ ) {
+ DBUG_PRINT("info",("spider this is merge func"));
+ merge_func = TRUE;
+ }
+ }
+ }
+
if (str)
{
char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2;
@@ -3497,9 +3748,12 @@ int spider_db_oracle_util::open_item_func(
tmp_str.init_calc_mem(125);
tmp_str.length(0);
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
- if (str->reserve(SPIDER_SQL_CAST_LEN))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ if (!merge_func)
+ {
+ if (str->reserve(SPIDER_SQL_CAST_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN);
+ }
#if MYSQL_VERSION_ID < 50500
item_func->print(tmp_str.get_str(), QT_IS);
#else
@@ -3532,12 +3786,15 @@ int spider_db_oracle_util::open_item_func(
bool has_other_item = FALSE;
while((item = lif++))
{
+#ifdef SPIDER_HAS_EXPR_CACHE_ITEM
if (
item->type() == Item::EXPR_CACHE_ITEM
) {
DBUG_PRINT("info",("spider EXPR_CACHE_ITEM"));
has_expr_cache_item = TRUE;
- } else if (
+ } else
+#endif
+ if (
item->type() == Item::FUNC_ITEM &&
((Item_func *) item)->functype() == Item_func::ISNOTNULL_FUNC
) {
@@ -3641,7 +3898,7 @@ int spider_db_oracle_util::open_item_func(
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
DBUG_RETURN(
spider_db_open_item_cond((Item_cond *) item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item_func::TRIG_COND_FUNC:
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
case Item_func::GUSERVAR_FUNC:
@@ -3649,10 +3906,10 @@ int spider_db_oracle_util::open_item_func(
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
if (item_func->result_type() == STRING_RESULT)
DBUG_RETURN(spider_db_open_item_string(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
else
DBUG_RETURN(spider_db_open_item_int(item_func, spider, str,
- alias, alias_length, dbton_id));
+ alias, alias_length, dbton_id, use_fields, fields));
case Item_func::FT_FUNC:
if (spider_db_check_ft_idx(item_func, spider) == MAX_KEY)
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
@@ -3758,7 +4015,7 @@ int spider_db_oracle_util::open_item_func(
{
item = item_list[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (roop_count == 1)
{
@@ -3776,7 +4033,7 @@ int spider_db_oracle_util::open_item_func(
}
item = item_list[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (item_func->functype() == Item_func::FT_FUNC)
@@ -3790,7 +4047,7 @@ int spider_db_oracle_util::open_item_func(
}
item = item_list[0];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3818,7 +4075,8 @@ int spider_db_oracle_util::open_item_func(
{
Item_func_conv_charset *item_func_conv_charset =
(Item_func_conv_charset *)item_func;
- CHARSET_INFO *conv_charset = item_func_conv_charset->conv_charset;
+ CHARSET_INFO *conv_charset =
+ item_func_conv_charset->SPIDER_Item_func_conv_charset_conv_charset;
uint cset_length = strlen(conv_charset->csname);
if (str->reserve(SPIDER_SQL_USING_LEN + cset_length))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -3829,6 +4087,8 @@ int spider_db_oracle_util::open_item_func(
}
if (str)
{
+ if (merge_func)
+ str->length(str->length() - SPIDER_SQL_CLOSE_PAREN_LEN);
if (str->reserve(last_str_length + SPIDER_SQL_CLOSE_PAREN_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
str->q_append(last_str, last_str_length);
@@ -3843,7 +4103,9 @@ int spider_db_oracle_util::open_item_sum_func(
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
) {
uint dbton_id = spider_dbton_oracle.dbton_id;
uint roop_count, item_count = item_sum->get_arg_count();
@@ -3873,7 +4135,7 @@ int spider_db_oracle_util::open_item_sum_func(
{
item = args[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
if (str)
{
@@ -3884,7 +4146,7 @@ int spider_db_oracle_util::open_item_sum_func(
}
item = args[roop_count];
if ((error_num = spider_db_print_item_type(item, spider, str,
- alias, alias_length, dbton_id)))
+ alias, alias_length, dbton_id, use_fields, fields)))
DBUG_RETURN(error_num);
}
if (str)
@@ -3941,6 +4203,123 @@ int spider_db_oracle_util::append_escaped_util(
DBUG_RETURN(0);
}
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+int spider_db_oracle_util::append_from_and_tables(
+ spider_fields *fields,
+ spider_string *str
+) {
+ SPIDER_TABLE_HOLDER *table_holder;
+ int error_num;
+ uint dbton_id = spider_dbton_oracle.dbton_id, from_length;
+ spider_oracle_share *db_share;
+ spider_oracle_handler *dbton_hdl;
+ ha_spider *spider;
+ DBUG_ENTER("spider_db_oracle_util::append_from_and_tables");
+ DBUG_PRINT("info",("spider this=%p", this));
+
+ /* calculate from size */
+ from_length = SPIDER_SQL_FROM_LEN;
+ fields->set_pos_to_first_table_holder();
+ while ((table_holder = fields->get_next_table_holder()))
+ {
+ spider = table_holder->spider;
+ db_share = (spider_oracle_share *)
+ spider->share->dbton_share[dbton_id];
+ from_length +=
+ db_share->db_nm_max_length +
+ SPIDER_SQL_DOT_LEN + /* SPIDER_SQL_NAME_QUOTE_LEN */ 4 +
+ db_share->table_nm_max_length +
+ SPIDER_SQL_SPACE_LEN + SPIDER_SQL_COMMA_LEN +
+ table_holder->alias->length() - SPIDER_SQL_DOT_LEN;
+ }
+
+ if (str->reserve(from_length))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN);
+
+ fields->set_pos_to_first_table_holder();
+ while ((table_holder = fields->get_next_table_holder()))
+ {
+ spider = table_holder->spider;
+ db_share = (spider_oracle_share *)
+ spider->share->dbton_share[dbton_id];
+ dbton_hdl = (spider_oracle_handler *) spider->dbton_handler[dbton_id];
+ dbton_hdl->table_name_pos = str->length();
+ if ((error_num = db_share->append_table_name_with_adjusting(str,
+ spider->conn_link_idx[dbton_hdl->first_link_idx])))
+ {
+ DBUG_RETURN(error_num);
+ }
+ str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN);
+ str->q_append(table_holder->alias->ptr(),
+ table_holder->alias->length() - SPIDER_SQL_DOT_LEN);
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ }
+ str->length(str->length() - SPIDER_SQL_COMMA_LEN);
+ DBUG_RETURN(0);
+}
+
+int spider_db_oracle_util::reappend_tables(
+ spider_fields *fields,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain,
+ spider_string *str
+) {
+ int error_num;
+ uint dbton_id = spider_dbton_oracle.dbton_id, length;
+ ha_spider *spider;
+ spider_oracle_share *db_share;
+ spider_oracle_handler *dbton_hdl;
+ SPIDER_TABLE_HOLDER *table_holder;
+ SPIDER_LINK_IDX_HOLDER *link_idx_holder;
+ DBUG_ENTER("spider_db_oracle_util::reappend_tables");
+ DBUG_PRINT("info",("spider this=%p", this));
+ length = str->length();
+ fields->set_pos_to_first_table_on_link_idx_chain(link_idx_chain);
+ fields->set_pos_to_first_table_holder();
+ while ((table_holder = fields->get_next_table_holder()))
+ {
+ link_idx_holder = fields->get_next_table_on_link_idx_chain(link_idx_chain);
+ spider = table_holder->spider;
+ db_share = (spider_oracle_share *)
+ spider->share->dbton_share[dbton_id];
+ if (!db_share->same_db_table_name)
+ {
+ dbton_hdl = (spider_oracle_handler *) spider->dbton_handler[dbton_id];
+ str->length(dbton_hdl->table_name_pos);
+ if ((error_num = db_share->append_table_name_with_adjusting(str,
+ spider->conn_link_idx[link_idx_holder->link_idx])))
+ {
+ DBUG_RETURN(error_num);
+ }
+ }
+ }
+ str->length(length);
+ DBUG_RETURN(0);
+}
+
+int spider_db_oracle_util::append_where(
+ spider_string *str
+) {
+ DBUG_ENTER("spider_db_oracle_util::append_where");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (str->reserve(SPIDER_SQL_WHERE_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_WHERE_STR, SPIDER_SQL_WHERE_LEN);
+ DBUG_RETURN(0);
+}
+
+int spider_db_oracle_util::append_having(
+ spider_string *str
+) {
+ DBUG_ENTER("spider_db_oracle_util::append_having");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (str->reserve(SPIDER_SQL_HAVING_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_HAVING_STR, SPIDER_SQL_HAVING_LEN);
+ DBUG_RETURN(0);
+}
+#endif
+
spider_oracle_share::spider_oracle_share(
st_spider_share *share
) : spider_db_share(
@@ -4984,6 +5363,16 @@ int spider_oracle_handler::init()
DBUG_RETURN(0);
}
+int spider_oracle_handler::append_index_hint(
+ spider_string *str,
+ int link_idx,
+ ulong sql_type
+ )
+{
+ DBUG_ENTER("spider_oracle_handler::append_index_hint");
+ DBUG_RETURN(0);
+}
+
int spider_oracle_handler::append_table_name_with_adjusting(
spider_string *str,
int link_idx,
@@ -6022,7 +6411,7 @@ int spider_oracle_handler::append_update_columns(
value = vi++;
if ((error_num = spider_db_print_item_type(
(Item *) field, spider, str, alias, alias_length,
- spider_dbton_oracle.dbton_id)))
+ spider_dbton_oracle.dbton_id, FALSE, NULL)))
{
if (
error_num == ER_SPIDER_COND_SKIP_NUM &&
@@ -6040,7 +6429,7 @@ int spider_oracle_handler::append_update_columns(
}
if ((error_num = spider_db_print_item_type(
(Item *) value, spider, str, alias, alias_length,
- spider_dbton_oracle.dbton_id)))
+ spider_dbton_oracle.dbton_id, FALSE, NULL)))
DBUG_RETURN(error_num);
if (str)
{
@@ -6442,7 +6831,7 @@ int spider_oracle_handler::check_item_type(
DBUG_ENTER("spider_oracle_handler::check_item_type");
DBUG_PRINT("info",("spider this=%p", this));
error_num = spider_db_print_item_type(item, spider, NULL, NULL, 0,
- spider_dbton_oracle.dbton_id);
+ spider_dbton_oracle.dbton_id, FALSE, NULL);
DBUG_RETURN(error_num);
}
@@ -7223,7 +7612,7 @@ int spider_oracle_handler::append_condition(
}
if ((error_num = spider_db_print_item_type(
(Item *) tmp_cond->cond, spider, str, alias, alias_length,
- spider_dbton_oracle.dbton_id)))
+ spider_dbton_oracle.dbton_id, FALSE, NULL)))
{
if (str && error_num == ER_SPIDER_COND_SKIP_NUM)
{
@@ -7430,7 +7819,7 @@ int spider_oracle_handler::append_sum_select(
for (item_sum_ptr = join->sum_funcs; *item_sum_ptr; ++item_sum_ptr)
{
if ((error_num = spider_db_oracle_utility.open_item_sum_func(*item_sum_ptr,
- spider, str, alias, alias_length)))
+ spider, str, alias, alias_length, FALSE, NULL)))
{
DBUG_RETURN(error_num);
}
@@ -7545,7 +7934,7 @@ int spider_oracle_handler::append_group_by(
for (; group; group = group->next)
{
if ((error_num = spider_db_print_item_type((*group->item), spider, str,
- alias, alias_length, spider_dbton_oracle.dbton_id)))
+ alias, alias_length, spider_dbton_oracle.dbton_id, FALSE, NULL)))
{
DBUG_RETURN(error_num);
}
@@ -7884,12 +8273,12 @@ int spider_oracle_handler::append_key_order_for_direct_order_limit_with_alias(
{
if ((error_num =
spider_db_print_item_type((*order->item), spider, &sql_part, alias,
- alias_length, spider_dbton_oracle.dbton_id)))
+ alias_length, spider_dbton_oracle.dbton_id, FALSE, NULL)))
{
DBUG_PRINT("info",("spider error=%d", error_num));
DBUG_RETURN(error_num);
}
- if (order->asc)
+ if (SPIDER_order_direction_is_asc(order))
{
if (sql_part.reserve(SPIDER_SQL_COMMA_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -7975,12 +8364,12 @@ int spider_oracle_handler::append_key_order_for_direct_order_limit_with_alias(
{
if ((error_num =
spider_db_print_item_type((*order->item), spider, str, alias,
- alias_length, spider_dbton_oracle.dbton_id)))
+ alias_length, spider_dbton_oracle.dbton_id, FALSE, NULL)))
{
DBUG_PRINT("info",("spider error=%d", error_num));
DBUG_RETURN(error_num);
}
- if (order->asc)
+ if (SPIDER_order_direction_is_asc(order))
{
if (str->reserve(SPIDER_SQL_COMMA_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -9586,49 +9975,49 @@ int spider_oracle_handler::append_explain_select(
********************************************************************/
bool spider_oracle_handler::is_sole_projection_field( uint16 field_index )
{
- // Determine whether the projection list consists solely of the field of interest
- bool is_field_in_projection_list = FALSE;
- TABLE* table = spider->get_table();
- uint16 projection_field_count = 0;
- uint16 projection_field_index;
- Field** field;
- DBUG_ENTER( "spider_oracle_handler::is_sole_projection_field" );
+ // Determine whether the projection list consists solely of the field of interest
+ bool is_field_in_projection_list = FALSE;
+ TABLE* table = spider->get_table();
+ uint16 projection_field_count = 0;
+ uint16 projection_field_index;
+ Field** field;
+ DBUG_ENTER( "spider_oracle_handler::is_sole_projection_field" );
- for ( field = table->field; *field; field++ )
- {
- projection_field_index = ( *field )->field_index;
-
- if ( !( minimum_select_bit_is_set( projection_field_index ) ) )
- {
- // Current field is not in the projection list
- continue;
- }
+ for ( field = table->field; *field; field++ )
+ {
+ projection_field_index = ( *field )->field_index;
- projection_field_count++;
+ if ( !( minimum_select_bit_is_set( projection_field_index ) ) )
+ {
+ // Current field is not in the projection list
+ continue;
+ }
- if ( !is_field_in_projection_list )
- {
- if (field_index == projection_field_index)
- {
- // Field of interest is in the projection list
- is_field_in_projection_list = TRUE;
- }
- }
+ projection_field_count++;
- if ( is_field_in_projection_list && ( projection_field_count != 1 ) )
- {
- // Field of interest is not the sole column in the projection list
- DBUG_RETURN( FALSE );
- }
+ if ( !is_field_in_projection_list )
+ {
+ if (field_index == projection_field_index)
+ {
+ // Field of interest is in the projection list
+ is_field_in_projection_list = TRUE;
+ }
}
- if ( is_field_in_projection_list && ( projection_field_count == 1 ) )
+ if ( is_field_in_projection_list && ( projection_field_count != 1 ) )
{
- // Field of interest is the only column in the projection list
- DBUG_RETURN( TRUE );
+ // Field of interest is not the sole column in the projection list
+ DBUG_RETURN( FALSE );
}
+ }
- DBUG_RETURN( FALSE );
+ if ( is_field_in_projection_list && ( projection_field_count == 1 ) )
+ {
+ // Field of interest is the only column in the projection list
+ DBUG_RETURN( TRUE );
+ }
+
+ DBUG_RETURN( FALSE );
}
bool spider_oracle_handler::is_bulk_insert_exec_period(
@@ -10100,6 +10489,53 @@ bool spider_oracle_handler::need_lock_before_set_sql_for_exec(
DBUG_RETURN(FALSE);
}
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+int spider_oracle_handler::set_sql_for_exec(
+ ulong sql_type,
+ int link_idx,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain
+) {
+ int error_num;
+ SPIDER_RESULT_LIST *result_list = &spider->result_list;
+ int all_link_idx = spider->conn_link_idx[link_idx];
+ DBUG_ENTER("spider_oracle_handler::set_sql_for_exec");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (sql_type & SPIDER_SQL_TYPE_SELECT_SQL)
+ {
+ if (table_lock_mode)
+ {
+ spider_string *str = &result_list->insert_sqls[link_idx];
+ str->length(0);
+ if (str->reserve(SPIDER_SQL_LOCK_TABLE_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_LOCK_TABLE_STR, SPIDER_SQL_LOCK_TABLE_LEN);
+ if ((error_num = oracle_share->append_table_name(str, all_link_idx)))
+ DBUG_RETURN(error_num);
+ if (table_lock_mode == SPIDER_LOCK_MODE_EXCLUSIVE)
+ {
+ if (str->reserve(SPIDER_SQL_LOCK_TABLE_EXCLUSIVE_MODE_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_LOCK_TABLE_EXCLUSIVE_MODE_STR,
+ SPIDER_SQL_LOCK_TABLE_EXCLUSIVE_MODE_LEN);
+ } else if (table_lock_mode == SPIDER_LOCK_MODE_SHARED)
+ {
+ if (str->reserve(SPIDER_SQL_LOCK_TABLE_SHARE_MODE_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_LOCK_TABLE_SHARE_MODE_STR,
+ SPIDER_SQL_LOCK_TABLE_SHARE_MODE_LEN);
+ }
+ exec_lock_sql = str;
+ }
+
+ if ((error_num = spider_db_oracle_utility.reappend_tables(
+ spider->fields, link_idx_chain, &sql)))
+ DBUG_RETURN(error_num);
+ exec_sql = &sql;
+ }
+ DBUG_RETURN(0);
+}
+#endif
+
int spider_oracle_handler::set_sql_for_exec(
ulong sql_type,
int link_idx
@@ -12007,6 +12443,306 @@ int spider_oracle_handler::reset_union_table_name(
DBUG_RETURN(0);
}
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+int spider_oracle_handler::append_from_and_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_oracle_handler::append_from_and_tables_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = spider_db_oracle_utility.append_from_and_tables(fields, str);
+ DBUG_RETURN(error_num);
+}
+
+int spider_oracle_handler::reappend_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_oracle_handler::reappend_tables_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = spider_db_oracle_utility.reappend_tables(fields,
+ link_idx_chain, str);
+ DBUG_RETURN(error_num);
+}
+
+int spider_oracle_handler::append_where_part(
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_oracle_handler::append_where_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = spider_db_oracle_utility.append_where(str);
+ DBUG_RETURN(error_num);
+}
+
+int spider_oracle_handler::append_having_part(
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_oracle_handler::append_having_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = spider_db_oracle_utility.append_having(str);
+ DBUG_RETURN(error_num);
+}
+
+int spider_oracle_handler::append_item_type_part(
+ Item *item,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_oracle_handler::append_item_type_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = spider_db_print_item_type(item, spider, str, alias, alias_length,
+ spider_dbton_oracle.dbton_id, use_fields, fields);
+ DBUG_RETURN(error_num);
+}
+
+int spider_oracle_handler::append_list_item_select_part(
+ List<Item> *select,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_oracle_handler::append_list_item_select_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = append_list_item_select(select, str, alias, alias_length,
+ use_fields, fields);
+ DBUG_RETURN(error_num);
+}
+
+int spider_oracle_handler::append_list_item_select(
+ List<Item> *select,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+) {
+ int error_num;
+ uint dbton_id = spider_dbton_oracle.dbton_id, length;
+ List_iterator_fast<Item> it(*select);
+ Item *item;
+ Field **field_ptr;
+ DBUG_ENTER("spider_oracle_handler::append_list_item_select");
+ DBUG_PRINT("info",("spider this=%p", this));
+ while ((item = it++))
+ {
+ if ((error_num = spider_db_print_item_type(item, spider, str,
+ alias, alias_length, dbton_id, use_fields, fields)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ field_ptr = fields->get_next_field_ptr();
+ length = strlen((*field_ptr)->field_name);
+ if (str->reserve(
+ SPIDER_SQL_COMMA_LEN + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 +
+ SPIDER_SQL_SPACE_LEN + length
+ ))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN);
+ if ((error_num = spider_db_oracle_utility.append_name(str,
+ (*field_ptr)->field_name, length)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ }
+ str->length(str->length() - SPIDER_SQL_COMMA_LEN);
+ DBUG_RETURN(0);
+}
+
+int spider_oracle_handler::append_group_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_oracle_handler::append_group_by_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = append_group_by(order, str, alias, alias_length,
+ use_fields, fields);
+ DBUG_RETURN(error_num);
+}
+
+int spider_oracle_handler::append_group_by(
+ ORDER *order,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+) {
+ int error_num;
+ uint dbton_id = spider_dbton_oracle.dbton_id;
+ DBUG_ENTER("spider_oracle_handler::append_group_by");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (order)
+ {
+ if (str->reserve(SPIDER_SQL_GROUP_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_GROUP_STR, SPIDER_SQL_GROUP_LEN);
+ for (; order; order = order->next)
+ {
+ if ((error_num = spider_db_print_item_type((*order->item), spider, str,
+ alias, alias_length, dbton_id, use_fields, fields)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if (str->reserve(SPIDER_SQL_COMMA_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ }
+ str->length(str->length() - SPIDER_SQL_COMMA_LEN);
+ }
+ DBUG_RETURN(0);
+}
+
+int spider_oracle_handler::append_order_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+) {
+ int error_num;
+ spider_string *str;
+ DBUG_ENTER("spider_oracle_handler::append_order_by_part");
+ DBUG_PRINT("info",("spider this=%p", this));
+ switch (sql_type)
+ {
+ case SPIDER_SQL_TYPE_SELECT_SQL:
+ str = &sql;
+ break;
+ default:
+ DBUG_RETURN(0);
+ }
+ error_num = append_order_by(order, str, alias, alias_length,
+ use_fields, fields);
+ DBUG_RETURN(error_num);
+}
+
+int spider_oracle_handler::append_order_by(
+ ORDER *order,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+) {
+ int error_num;
+ uint dbton_id = spider_dbton_oracle.dbton_id;
+ DBUG_ENTER("spider_oracle_handler::append_order_by");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (order)
+ {
+ if (str->reserve(SPIDER_SQL_ORDER_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_ORDER_STR, SPIDER_SQL_ORDER_LEN);
+ for (; order; order = order->next)
+ {
+ if ((error_num = spider_db_print_item_type((*order->item), spider, str,
+ alias, alias_length, dbton_id, use_fields, fields)))
+ {
+ DBUG_RETURN(error_num);
+ }
+#ifdef SPIDER_ORDER_HAS_ENUM_ORDER
+ if (order->direction == ORDER::ORDER_DESC)
+#else
+ if (!order->asc)
+#endif
+ {
+ if (str->reserve(SPIDER_SQL_COMMA_LEN + SPIDER_SQL_DESC_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_DESC_STR, SPIDER_SQL_DESC_LEN);
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ } else {
+ if (str->reserve(SPIDER_SQL_COMMA_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
+ }
+ }
+ str->length(str->length() - SPIDER_SQL_COMMA_LEN);
+ }
+ DBUG_RETURN(0);
+}
+#endif
+
spider_oracle_copy_table::spider_oracle_copy_table(
spider_oracle_share *db_share
) : spider_db_copy_table(
diff --git a/storage/spider/spd_db_oracle.h b/storage/spider/spd_db_oracle.h
index 7a070f498da..2e9da5cab84 100644
--- a/storage/spider/spd_db_oracle.h
+++ b/storage/spider/spd_db_oracle.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012-2014 Kentoku Shiba
+/* Copyright (C) 2012-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
class spider_db_oracle;
class spider_db_oracle_result;
@@ -102,7 +102,9 @@ public:
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
);
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
int open_item_sum_func(
@@ -110,7 +112,9 @@ public:
ha_spider *spider,
spider_string *str,
const char *alias,
- uint alias_length
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
);
#endif
size_t escape_string(
@@ -123,6 +127,23 @@ public:
spider_string *to,
String *from
);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ int append_from_and_tables(
+ spider_fields *fields,
+ spider_string *str
+ );
+ int reappend_tables(
+ spider_fields *fields,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain,
+ spider_string *str
+ );
+ int append_where(
+ spider_string *str
+ );
+ int append_having(
+ spider_string *str
+ );
+#endif
};
class spider_db_oracle_row: public spider_db_row
@@ -195,7 +216,7 @@ public:
spider_db_oracle_row row;
int store_error_num;
- spider_db_oracle_result();
+ spider_db_oracle_result(SPIDER_DB_CONN *in_db_conn);
~spider_db_oracle_result();
bool has_result();
void free_result();
@@ -409,6 +430,17 @@ public:
Time_zone *time_zone,
int *need_mon
);
+ int show_master_status(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ int all_link_idx,
+ int *need_mon,
+ TABLE *table,
+ spider_string *str,
+ int mode,
+ SPIDER_DB_RESULT **res1,
+ SPIDER_DB_RESULT **res2
+ );
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
int append_sql(
char *sql,
@@ -586,7 +618,9 @@ class spider_oracle_handler: public spider_db_handler
int where_pos;
int order_pos;
int limit_pos;
+public:
int table_name_pos;
+private:
int update_set_pos;
int ha_read_pos;
int ha_next_pos;
@@ -634,6 +668,11 @@ public:
);
~spider_oracle_handler();
int init();
+ int spider_oracle_handler::append_index_hint(
+ spider_string *str,
+ int link_idx,
+ ulong sql_type
+ );
int append_table_name_with_adjusting(
spider_string *str,
int link_idx,
@@ -1209,7 +1248,7 @@ public:
int link_idx
);
bool is_sole_projection_field(
- uint16 field_index
+ uint16 field_index
);
bool is_bulk_insert_exec_period(
bool bulk_end
@@ -1279,6 +1318,13 @@ public:
bool need_lock_before_set_sql_for_exec(
ulong sql_type
);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ int set_sql_for_exec(
+ ulong sql_type,
+ int link_idx,
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain
+ );
+#endif
int set_sql_for_exec(
ulong sql_type,
int link_idx
@@ -1393,6 +1439,78 @@ public:
int link_idx,
ulong sql_type
);
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ int append_from_and_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int reappend_tables_part(
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_where_part(
+ ulong sql_type
+ );
+ int append_having_part(
+ ulong sql_type
+ );
+ int append_item_type_part(
+ Item *item,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_list_item_select_part(
+ List<Item> *select,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_list_item_select(
+ List<Item> *select,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+ );
+ int append_group_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_group_by(
+ ORDER *order,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+ );
+ int append_order_by_part(
+ ORDER *order,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields,
+ ulong sql_type
+ );
+ int append_order_by(
+ ORDER *order,
+ spider_string *str,
+ const char *alias,
+ uint alias_length,
+ bool use_fields,
+ spider_fields *fields
+ );
+#endif
};
class spider_oracle_copy_table: public spider_db_copy_table
diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc
index 1aa532e500b..4d69d9af615 100644
--- a/storage/spider/spd_direct_sql.cc
+++ b/storage/spider/spd_direct_sql.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009-2015 Kentoku Shiba
+/* Copyright (C) 2009-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -58,7 +59,11 @@ extern PSI_cond_key spd_key_cond_bg_direct_sql;
#endif
extern HASH spider_open_connections;
+extern HASH spider_ipport_conns;
extern pthread_mutex_t spider_conn_mutex;
+extern pthread_mutex_t spider_conn_id_mutex;
+extern pthread_mutex_t spider_ipport_conn_mutex;
+extern ulonglong spider_conn_id;
uint spider_udf_calc_hash(
char *key,
@@ -127,7 +132,7 @@ int spider_udf_direct_sql_create_table_list(
&direct_sql->tables, sizeof(TABLE*) * table_count,
&tmp_name_ptr, sizeof(char) * (
table_name_list_length +
- thd->db_length * table_count +
+ thd->db.length * table_count +
2 * table_count
),
&direct_sql->iop, sizeof(int) * table_count,
@@ -158,11 +163,11 @@ int spider_udf_direct_sql_create_table_list(
tmp_name_ptr += length + 1;
tmp_ptr = tmp_ptr3 + 1;
} else {
- if (thd->db)
+ if (thd->db.str)
{
- memcpy(tmp_name_ptr, thd->db,
- thd->db_length + 1);
- tmp_name_ptr += thd->db_length + 1;
+ memcpy(tmp_name_ptr, thd->db.str,
+ thd->db.length + 1);
+ tmp_name_ptr += thd->db.length + 1;
} else {
direct_sql->db_names[roop_count] = (char *) "";
}
@@ -350,6 +355,27 @@ int spider_udf_direct_sql_create_conn_key(
#endif
}
}
+ if (direct_sql->dbton_id == SPIDER_DBTON_SIZE)
+ {
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ if (direct_sql->access_mode == 0)
+ {
+#endif
+ my_printf_error(
+ ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM,
+ ER_SPIDER_SQL_WRAPPER_IS_INVALID_STR,
+ MYF(0), direct_sql->tgt_wrapper);
+ DBUG_RETURN(ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM);
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ } else {
+ my_printf_error(
+ ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM,
+ ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_STR,
+ MYF(0), direct_sql->tgt_wrapper);
+ DBUG_RETURN(ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM);
+ }
+#endif
+ }
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
direct_sql->conn_key_hash_value = my_calc_hash(&spider_open_connections,
(uchar*) direct_sql->conn_key, direct_sql->conn_key_length);
@@ -362,6 +388,7 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn(
int *error_num
) {
SPIDER_CONN *conn;
+ SPIDER_IP_PORT_CONN *ip_port_conn;
char *tmp_name, *tmp_host, *tmp_username, *tmp_password, *tmp_socket;
char *tmp_wrapper, *tmp_ssl_ca, *tmp_ssl_capath, *tmp_ssl_cert;
char *tmp_ssl_cipher, *tmp_ssl_key, *tmp_default_file, *tmp_default_group;
@@ -559,12 +586,57 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn(
goto error;
conn->ping_time = (time_t) time((time_t*) 0);
conn->connect_error_time = conn->ping_time;
+ pthread_mutex_lock(&spider_conn_id_mutex);
+ conn->conn_id = spider_conn_id;
+ ++spider_conn_id;
+ pthread_mutex_unlock(&spider_conn_id_mutex);
+
+ pthread_mutex_lock(&spider_ipport_conn_mutex);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search_using_hash_value(
+ &spider_ipport_conns, conn->conn_key_hash_value,
+ (uchar*)conn->conn_key, conn->conn_key_length)))
+#else
+ if ((ip_port_conn = (SPIDER_IP_PORT_CONN*) my_hash_search(
+ &spider_ipport_conns, (uchar*)conn->conn_key, conn->conn_key_length)))
+#endif
+ { /* exists, +1 */
+ pthread_mutex_unlock(&spider_ipport_conn_mutex);
+ pthread_mutex_lock(&ip_port_conn->mutex);
+ if (spider_param_max_connections())
+ { /* enable conncetion pool */
+ if (ip_port_conn->ip_port_count >= spider_param_max_connections())
+ { /* bigger than the max num of connections, free conn and return NULL */
+ pthread_mutex_unlock(&ip_port_conn->mutex);
+ goto error_too_many_ipport_count;
+ }
+ }
+ ip_port_conn->ip_port_count++;
+ pthread_mutex_unlock(&ip_port_conn->mutex);
+ }
+ else
+ {// do not exist
+ ip_port_conn = spider_create_ipport_conn(conn);
+ if (!ip_port_conn) {
+ /* failed, always do not effect 'create conn' */
+ pthread_mutex_unlock(&spider_ipport_conn_mutex);
+ DBUG_RETURN(conn);
+ }
+ if (my_hash_insert(&spider_ipport_conns, (uchar *)ip_port_conn)) {
+ /* insert failed, always do not effect 'create conn' */
+ pthread_mutex_unlock(&spider_ipport_conn_mutex);
+ DBUG_RETURN(conn);
+ }
+ pthread_mutex_unlock(&spider_ipport_conn_mutex);
+ }
+ conn->ip_port_conn = ip_port_conn;
DBUG_RETURN(conn);
error:
DBUG_ASSERT(!conn->mta_conn_mutex_file_pos.file_name);
pthread_mutex_destroy(&conn->mta_conn_mutex);
+error_too_many_ipport_count:
error_mta_conn_mutex_init:
error_db_conn_init:
delete conn->db_conn;
@@ -1284,10 +1356,10 @@ int spider_udf_set_direct_sql_param_default(
if (!direct_sql->tgt_default_db_name)
{
DBUG_PRINT("info",("spider create default tgt_default_db_name"));
- direct_sql->tgt_default_db_name_length = trx->thd->db_length;
+ direct_sql->tgt_default_db_name_length = trx->thd->db.length;
if (
!(direct_sql->tgt_default_db_name = spider_create_string(
- trx->thd->db,
+ trx->thd->db.str,
direct_sql->tgt_default_db_name_length))
) {
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
@@ -1623,6 +1695,15 @@ long long spider_direct_sql_body(
goto error;
}
}
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ if (trx->trx_start && direct_sql->access_mode != 1)
+ {
+#endif
+ trx->updated_in_this_trx = TRUE;
+ DBUG_PRINT("info",("spider trx->updated_in_this_trx=TRUE"));
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ }
+#endif
#if MYSQL_VERSION_ID < 50500
#else
use_real_table = spider_param_udf_ds_use_real_table(thd,
@@ -1631,17 +1712,17 @@ long long spider_direct_sql_body(
for (roop_count = 0; roop_count < direct_sql->table_count; roop_count++)
{
#ifdef SPIDER_NEED_INIT_ONE_TABLE_FOR_FIND_TEMPORARY_TABLE
- table_list.init_one_table(direct_sql->db_names[roop_count],
- strlen(direct_sql->db_names[roop_count]),
- direct_sql->table_names[roop_count],
- strlen(direct_sql->table_names[roop_count]),
- direct_sql->table_names[roop_count], TL_WRITE);
+ LEX_CSTRING db_name= { direct_sql->db_names[roop_count],
+ strlen(direct_sql->db_names[roop_count]) };
+ LEX_CSTRING tbl_name= { direct_sql->table_names[roop_count],
+ strlen(direct_sql->table_names[roop_count]) };
+ table_list.init_one_table(&db_name, &tbl_name, 0, TL_WRITE);
#else
table_list.db = direct_sql->db_names[roop_count];
table_list.table_name = direct_sql->table_names[roop_count];
#endif
if (!(direct_sql->tables[roop_count] =
- thd->find_temporary_table(&table_list)))
+ SPIDER_find_temporary_table(thd, &table_list)))
{
#if MYSQL_VERSION_ID < 50500
#else
@@ -1657,11 +1738,10 @@ long long spider_direct_sql_body(
#else
}
TABLE_LIST *tables = &direct_sql->table_list[roop_count];
- tables->init_one_table(table_list.db, strlen(table_list.db),
- table_list.table_name, strlen(table_list.table_name),
- table_list.table_name, TL_WRITE);
- tables->mdl_request.init(MDL_key::TABLE, table_list.db,
- table_list.table_name, MDL_SHARED_WRITE, MDL_TRANSACTION);
+
+ table_list.init_one_table(&table_list.db, &table_list.table_name, 0, TL_WRITE);
+ tables->mdl_request.init(MDL_key::TABLE, table_list.db.str,
+ table_list.table_name.str, MDL_SHARED_WRITE, MDL_TRANSACTION);
if (!direct_sql->table_list_first)
{
direct_sql->table_list_first = tables;
diff --git a/storage/spider/spd_direct_sql.h b/storage/spider/spd_direct_sql.h
index 12d81346f0d..26e3043dd94 100644
--- a/storage/spider/spd_direct_sql.h
+++ b/storage/spider/spd_direct_sql.h
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
uint spider_udf_calc_hash(
char *key,
diff --git a/storage/spider/spd_environ.h b/storage/spider/spd_environ.h
new file mode 100644
index 00000000000..ef7e6ff88c8
--- /dev/null
+++ b/storage/spider/spd_environ.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 2008-2017 Kentoku Shiba & 2017 MariaDB corp
+
+ This program is free 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Define functionality offered by MySQL or MariaDB
+*/
+
+#ifndef SPD_ENVIRON_INCLUDED
+
+#if (defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000)
+#define SPIDER_HANDLER_START_BULK_INSERT_HAS_FLAGS
+#endif
+
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100100
+#define SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE
+#endif
+
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100211
+#define HANDLER_HAS_TOP_TABLE_FIELDS
+#define HANDLER_HAS_DIRECT_UPDATE_ROWS
+#define HANDLER_HAS_DIRECT_AGGREGATE
+#define PARTITION_HAS_GET_CHILD_HANDLERS
+#define PARTITION_HAS_GET_PART_SPEC
+#define HA_EXTRA_HAS_STARTING_ORDERED_INDEX_SCAN
+#define HANDLER_HAS_NEED_INFO_FOR_AUTO_INC
+#define HANDLER_HAS_CAN_USE_FOR_AUTO_INC_INIT
+#endif
+#endif /* SPD_ENVIRON_INCLUDED */
diff --git a/storage/spider/spd_err.h b/storage/spider/spd_err.h
index ed26359f98b..1523df21cf1 100644
--- a/storage/spider/spd_err.h
+++ b/storage/spider/spd_err.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2014 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define ER_SPIDER_INVALID_CONNECT_INFO_NUM 12501
#define ER_SPIDER_INVALID_CONNECT_INFO_STR "The connect info '%-.64s' is invalid"
@@ -21,10 +21,10 @@
#define ER_SPIDER_INVALID_UDF_PARAM_STR "The UDF parameter '%-.64s' is invalid"
#define ER_SPIDER_DIFFERENT_LINK_COUNT_NUM 12504
#define ER_SPIDER_DIFFERENT_LINK_COUNT_STR "Different multiple table link parameter's count"
-#define ER_SPIDER_UDF_PING_TABLE_PARAM_TOO_LONG_NUM 12505
-#define ER_SPIDER_UDF_PING_TABLE_PARAM_TOO_LONG_STR "Server name or table name are too long"
-#define ER_SPIDER_UDF_PING_TABLE_PARAM_REQIRED_NUM 12506
-#define ER_SPIDER_UDF_PING_TABLE_PARAM_REQIRED_STR "Server name or table name are required"
+#define ER_SPIDER_UDF_PARAM_TOO_LONG_NUM 12505
+#define ER_SPIDER_UDF_PARAM_TOO_LONG_STR "The UDF parameter '%-.64s' is too long"
+#define ER_SPIDER_UDF_PARAM_REQIRED_NUM 12506
+#define ER_SPIDER_UDF_PARAM_REQIRED_STR "The UDF parameter '%-.64s' is required"
#define ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM 12507
#define ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR "This UDF can't execute if other tables are opened"
#define ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_NUM "This UDF can't execute if other tables are opened '%s'=%lld"
@@ -65,6 +65,10 @@
#define ER_SPIDER_CANT_OPEN_SYS_TABLE_STR "Can't open system table %s.%s"
#define ER_SPIDER_LINK_MON_JUST_NG_NUM 12525
#define ER_SPIDER_LINK_MON_JUST_NG_STR "Table '%s.%s' just got a problem"
+#define ER_SPIDER_INVALID_CONNECT_INFO_START_WITH_NUM_NUM 12526
+#define ER_SPIDER_INVALID_CONNECT_INFO_START_WITH_NUM_STR "The connect info '%-.64s' for %s cannot start with number"
+#define ER_SPIDER_INVALID_CONNECT_INFO_SAME_NUM 12527
+#define ER_SPIDER_INVALID_CONNECT_INFO_SAME_STR "The connect info '%-.64s' for %s cannot use same name in same table"
#define ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_NUM 12601
#define ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_STR "Can't use both spider_use_consistent_snapshot = 1 and spider_internal_xa = 1"
@@ -116,6 +120,10 @@
#define ER_SPIDER_ORACLE_STR "Error from Oracle %d %d %s"
#define ER_SPIDER_ORACLE_NUM 12712
#define ER_SPIDER_ORACLE_ERR "Oracle error"
+#define ER_SPIDER_CON_COUNT_ERROR 12713
+#define ER_SPIDER_CON_COUNT_ERROR_STR "Too many connections between spider and remote"
+#define ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM 12714
+#define ER_SPIDER_TABLE_OPEN_TIMEOUT_STR "Table %s.%s open timeout"
#define ER_SPIDER_COND_SKIP_NUM 12801
#define ER_SPIDER_UNKNOWN_NUM 12500
diff --git a/storage/spider/spd_group_by_handler.cc b/storage/spider/spd_group_by_handler.cc
new file mode 100644
index 00000000000..673248d0530
--- /dev/null
+++ b/storage/spider/spd_group_by_handler.cc
@@ -0,0 +1,2040 @@
+/* Copyright (C) 2008-2017 Kentoku Shiba
+
+ This program is free 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#define MYSQL_SERVER 1
+#include <my_global.h>
+#include "mysql_version.h"
+#include "spd_environ.h"
+#if MYSQL_VERSION_ID < 50500
+#include "mysql_priv.h"
+#include <mysql/plugin.h>
+#else
+#include "sql_priv.h"
+#include "probes_mysql.h"
+#include "sql_class.h"
+#include "sql_partition.h"
+#include "ha_partition.h"
+#endif
+#include "sql_common.h"
+#include <errmsg.h>
+#include "spd_err.h"
+#include "spd_param.h"
+#include "spd_db_include.h"
+#include "spd_include.h"
+#include "ha_spider.h"
+#include "spd_conn.h"
+#include "spd_db_conn.h"
+#include "spd_malloc.h"
+#include "spd_table.h"
+#include "spd_ping_table.h"
+#include "spd_group_by_handler.h"
+
+extern handlerton *spider_hton_ptr;
+extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
+
+spider_fields::spider_fields() :
+ dbton_count(0), current_dbton_num(0),
+ table_count(0), current_table_num(0), table_holder(NULL),
+ first_link_idx_chain(NULL), last_link_idx_chain(NULL), current_link_idx_chain(NULL),
+ first_conn_holder(NULL), last_conn_holder(NULL), current_conn_holder(NULL),
+ first_field_holder(NULL), last_field_holder(NULL), current_field_holder(NULL),
+ first_field_chain(NULL), last_field_chain(NULL), current_field_chain(NULL)
+{
+ DBUG_ENTER("spider_fields::spider_fields");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_VOID_RETURN;
+}
+
+spider_fields::~spider_fields()
+{
+ DBUG_ENTER("spider_fields::~spider_fields");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (first_link_idx_chain)
+ {
+ while ((current_link_idx_chain = first_link_idx_chain))
+ {
+ first_link_idx_chain = current_link_idx_chain->next;
+ spider_free(spider_current_trx, current_link_idx_chain, MYF(0));
+ }
+ }
+ if (first_field_chain)
+ {
+ while ((current_field_chain = first_field_chain))
+ {
+ first_field_chain = current_field_chain->next;
+ spider_free(spider_current_trx, current_field_chain, MYF(0));
+ }
+ }
+ if (first_field_holder)
+ {
+ while ((current_field_holder = first_field_holder))
+ {
+ first_field_holder = current_field_holder->next;
+ spider_free(spider_current_trx, current_field_holder, MYF(0));
+ }
+ }
+ if (table_holder)
+ spider_free(spider_current_trx, table_holder, MYF(0));
+ if (first_conn_holder)
+ {
+ while ((current_conn_holder = first_conn_holder))
+ {
+ first_conn_holder = current_conn_holder->next;
+ free_conn_holder(current_conn_holder);
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
+void spider_fields::add_dbton_id(
+ uint dbton_id_arg
+) {
+ uint roop_count;
+ DBUG_ENTER("spider_fields::add_dbton_id");
+ DBUG_PRINT("info",("spider this=%p", this));
+ for (roop_count = 0; roop_count < dbton_count; ++roop_count)
+ {
+ if (dbton_ids[roop_count] == dbton_id_arg)
+ {
+ DBUG_VOID_RETURN;
+ }
+ }
+ dbton_ids[roop_count] = dbton_id_arg;
+ ++dbton_count;
+ DBUG_VOID_RETURN;
+}
+
+void spider_fields::set_pos_to_first_dbton_id(
+) {
+ DBUG_ENTER("spider_fields::set_pos_to_first_dbton_id");
+ DBUG_PRINT("info",("spider this=%p", this));
+ current_dbton_num = 0;
+ DBUG_VOID_RETURN;
+}
+
+uint spider_fields::get_next_dbton_id(
+) {
+ uint return_dbton_id;
+ DBUG_ENTER("spider_fields::get_next_dbton_id");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (current_dbton_num >= dbton_count)
+ DBUG_RETURN(SPIDER_DBTON_SIZE);
+ return_dbton_id = dbton_ids[current_dbton_num];
+ ++current_dbton_num;
+ DBUG_RETURN(return_dbton_id);
+}
+
+int spider_fields::make_link_idx_chain(
+ int link_status
+) {
+ uint roop_count, roop_count2;
+ SPIDER_CONN *conn;
+ SPIDER_CONN_HOLDER *conn_holder;
+ SPIDER_TABLE_LINK_IDX_HOLDER *table_link_idx_holder;
+ SPIDER_LINK_IDX_HOLDER *link_idx_holder, *add_link_idx_holder,
+ *dup_link_idx_holder, *current_link_idx_holder;
+ ha_spider *spider;
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain;
+ SPIDER_SHARE *share;
+ DBUG_ENTER("spider_fields::make_link_idx_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ conn_holder = first_conn_holder;
+ bool has_remain, skip;
+ do {
+ for (roop_count2 = 0; roop_count2 < table_count; ++roop_count2)
+ {
+ table_link_idx_holder = &conn_holder->table_link_idx_holder[roop_count2];
+ link_idx_holder = table_link_idx_holder->first_link_idx_holder;
+ dup_link_idx_holder = NULL;
+ for (roop_count = 0;
+ roop_count < conn_holder->link_idx_holder_count_max - 1; ++roop_count)
+ {
+ if (!link_idx_holder->next)
+ {
+ DBUG_PRINT("info",("spider fill link_idx_holder for %u",
+ roop_count2));
+ if (!(add_link_idx_holder = create_link_idx_holder()))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ dup_link_idx_holder = get_dup_link_idx_holder(
+ table_link_idx_holder, dup_link_idx_holder);
+ add_link_idx_holder->table_link_idx_holder =
+ dup_link_idx_holder->table_link_idx_holder;
+ add_link_idx_holder->link_idx = dup_link_idx_holder->link_idx;
+ link_idx_holder->next = add_link_idx_holder;
+ }
+ link_idx_holder = link_idx_holder->next;
+ }
+ }
+
+ for (roop_count2 = 0; roop_count2 < table_count; ++roop_count2)
+ {
+ table_link_idx_holder = &conn_holder->table_link_idx_holder[roop_count2];
+ table_link_idx_holder->current_link_idx_holder =
+ table_link_idx_holder->first_link_idx_holder;
+ }
+ for (roop_count = 0;
+ roop_count < conn_holder->link_idx_holder_count_max; ++roop_count)
+ {
+ link_idx_holder = NULL;
+ for (roop_count2 = 0; roop_count2 < table_count; ++roop_count2)
+ {
+ table_link_idx_holder =
+ &conn_holder->table_link_idx_holder[roop_count2];
+ if (link_idx_holder)
+ {
+ link_idx_holder->next_table =
+ table_link_idx_holder->current_link_idx_holder;
+ }
+ link_idx_holder = table_link_idx_holder->current_link_idx_holder;
+ table_link_idx_holder->current_link_idx_holder = link_idx_holder->next;
+ }
+ }
+ } while ((conn_holder = conn_holder->next));
+
+ current_conn_holder = first_conn_holder;
+ do {
+ table_link_idx_holder =
+ &current_conn_holder->table_link_idx_holder[0];
+ table_link_idx_holder->current_link_idx_holder =
+ table_link_idx_holder->first_link_idx_holder;
+ } while ((current_conn_holder = current_conn_holder->next));
+
+ spider = table_holder[0].spider;
+ share = spider->share;
+ DBUG_PRINT("info",("spider create link_idx_chain sorted by 0"));
+ for (
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, -1, share->link_count,
+ link_status);
+ roop_count < share->link_count;
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, roop_count, share->link_count,
+ link_status)
+ ) {
+ conn = spider->conns[roop_count];
+ if (!conn->conn_holder_for_direct_join)
+ {
+ continue;
+ }
+ table_link_idx_holder =
+ &conn->conn_holder_for_direct_join->table_link_idx_holder[0];
+ link_idx_holder = table_link_idx_holder->current_link_idx_holder;
+ table_link_idx_holder->current_link_idx_holder = link_idx_holder->next;
+ DBUG_ASSERT(link_idx_holder->link_idx == (int) roop_count);
+ if (!(link_idx_chain = create_link_idx_chain()))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ if (!first_link_idx_chain)
+ {
+ first_link_idx_chain = link_idx_chain;
+ } else {
+ last_link_idx_chain->next = link_idx_chain;
+ }
+ last_link_idx_chain = link_idx_chain;
+ link_idx_chain->conn = conn;
+ link_idx_chain->link_idx_holder = link_idx_holder;
+ do {
+ if (link_idx_chain->link_status < link_idx_holder->link_status)
+ {
+ link_idx_chain->link_status = link_idx_holder->link_status;
+ }
+ } while ((link_idx_holder = link_idx_holder->next_table));
+ }
+
+ do {
+ has_remain = FALSE;
+ current_conn_holder = first_conn_holder;
+ do {
+ table_link_idx_holder =
+ &current_conn_holder->table_link_idx_holder[0];
+ link_idx_holder = table_link_idx_holder->current_link_idx_holder;
+ if (link_idx_holder)
+ {
+ has_remain = TRUE;
+ for (roop_count2 = 1; roop_count2 < table_count; ++roop_count2)
+ {
+ if (table_link_idx_holder[roop_count2].link_idx_holder_count ==
+ current_conn_holder->link_idx_holder_count_max)
+ {
+ break;
+ }
+ }
+ break;
+ }
+ } while ((current_conn_holder = current_conn_holder->next));
+
+ if (has_remain)
+ {
+ current_conn_holder = first_conn_holder;
+ do {
+ table_link_idx_holder =
+ &current_conn_holder->table_link_idx_holder[0];
+ link_idx_holder = table_link_idx_holder->current_link_idx_holder;
+ if (link_idx_holder)
+ {
+ for (roop_count = 1; roop_count <= roop_count2; ++roop_count)
+ {
+ link_idx_holder = link_idx_holder->next_table;
+ }
+ table_link_idx_holder[roop_count2].current_link_idx_holder =
+ link_idx_holder;
+ } else {
+ table_link_idx_holder[roop_count2].current_link_idx_holder = NULL;
+ }
+ } while ((current_conn_holder = current_conn_holder->next));
+
+ spider = table_holder[roop_count2].spider;
+ share = spider->share;
+ DBUG_PRINT("info",("spider create link_idx_chain sorted by %d",
+ roop_count2));
+ for (
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, -1, share->link_count,
+ link_status);
+ roop_count < share->link_count;
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, roop_count, share->link_count,
+ link_status)
+ ) {
+ conn = spider->conns[roop_count];
+ if (!conn->conn_holder_for_direct_join)
+ {
+ continue;
+ }
+ table_link_idx_holder =
+ &conn->conn_holder_for_direct_join->table_link_idx_holder[0];
+ link_idx_holder =
+ table_link_idx_holder[roop_count2].current_link_idx_holder;
+ skip = FALSE;
+ if (link_idx_holder)
+ {
+ current_link_idx_holder = table_link_idx_holder->first_link_idx_holder;
+ while (current_link_idx_holder != link_idx_holder)
+ {
+ if (current_link_idx_holder->link_idx ==
+ link_idx_holder->link_idx)
+ {
+ skip = TRUE;
+ break;
+ }
+ current_link_idx_holder = current_link_idx_holder->next;
+ }
+ }
+ if (skip)
+ {
+ continue;
+ }
+ DBUG_PRINT("info",("spider create link_idx_chain for %d",
+ roop_count2));
+ table_link_idx_holder[roop_count2].current_link_idx_holder =
+ link_idx_holder->next;
+ link_idx_holder =
+ table_link_idx_holder->current_link_idx_holder;
+ table_link_idx_holder->current_link_idx_holder =
+ link_idx_holder->next;
+ if (!(link_idx_chain = create_link_idx_chain()))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ DBUG_ASSERT(first_link_idx_chain);
+ last_link_idx_chain->next = link_idx_chain;
+ last_link_idx_chain = link_idx_chain;
+ link_idx_chain->conn = conn;
+ link_idx_chain->link_idx_holder = link_idx_holder;
+ do {
+ if (link_idx_chain->link_status < link_idx_holder->link_status)
+ {
+ link_idx_chain->link_status = link_idx_holder->link_status;
+ }
+ } while ((link_idx_holder = link_idx_holder->next_table));
+ }
+ }
+ } while (has_remain);
+ DBUG_RETURN(0);
+}
+
+SPIDER_LINK_IDX_CHAIN *spider_fields::create_link_idx_chain(
+) {
+ DBUG_ENTER("spider_fields::create_link_idx_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN((SPIDER_LINK_IDX_CHAIN *)
+ spider_malloc(spider_current_trx, 254, sizeof(SPIDER_LINK_IDX_CHAIN),
+ MYF(MY_WME | MY_ZEROFILL)));
+}
+
+void spider_fields::set_pos_to_first_link_idx_chain(
+) {
+ DBUG_ENTER("spider_fields::set_pos_to_first_link_idx_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ current_link_idx_chain = first_link_idx_chain;
+ DBUG_VOID_RETURN;
+}
+
+SPIDER_LINK_IDX_CHAIN *spider_fields::get_next_link_idx_chain(
+) {
+ SPIDER_LINK_IDX_CHAIN *return_link_idx_chain = current_link_idx_chain;
+ DBUG_ENTER("spider_fields::get_next_link_idx_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (current_link_idx_chain)
+ current_link_idx_chain = current_link_idx_chain->next;
+ DBUG_RETURN(return_link_idx_chain);
+}
+
+SPIDER_LINK_IDX_HOLDER *spider_fields::get_dup_link_idx_holder(
+ SPIDER_TABLE_LINK_IDX_HOLDER *table_link_idx_holder,
+ SPIDER_LINK_IDX_HOLDER *current
+) {
+ SPIDER_LINK_IDX_HOLDER *return_link_idx_holder;
+ DBUG_ENTER("spider_fields::get_dup_link_idx_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (!current)
+ {
+ return_link_idx_holder = table_link_idx_holder->first_link_idx_holder;
+ do {
+ if (return_link_idx_holder->link_status == SPIDER_LINK_STATUS_OK)
+ break;
+ } while ((return_link_idx_holder = return_link_idx_holder->next));
+ if (!return_link_idx_holder)
+ {
+ return_link_idx_holder = table_link_idx_holder->first_link_idx_holder;
+ }
+ } else {
+ if (current->link_status == SPIDER_LINK_STATUS_OK)
+ {
+ return_link_idx_holder = current;
+ while ((return_link_idx_holder = return_link_idx_holder->next))
+ {
+ if (return_link_idx_holder->link_status == SPIDER_LINK_STATUS_OK)
+ break;
+ }
+ if (!return_link_idx_holder)
+ {
+ return_link_idx_holder = table_link_idx_holder->first_link_idx_holder;
+ do {
+ if (
+ return_link_idx_holder->link_status == SPIDER_LINK_STATUS_OK
+ )
+ break;
+ DBUG_ASSERT(return_link_idx_holder != current);
+ } while ((return_link_idx_holder = return_link_idx_holder->next));
+ }
+ } else {
+ if (!current->next)
+ {
+ return_link_idx_holder = table_link_idx_holder->first_link_idx_holder;
+ } else {
+ return_link_idx_holder = current->next;
+ }
+ }
+ }
+ DBUG_RETURN(return_link_idx_holder);
+}
+
+bool spider_fields::check_link_ok_chain(
+) {
+ DBUG_ENTER("spider_fields::check_link_ok_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ for (current_link_idx_chain = first_link_idx_chain; current_link_idx_chain;
+ current_link_idx_chain = current_link_idx_chain->next)
+ {
+ if (current_link_idx_chain->link_status == SPIDER_LINK_STATUS_OK)
+ {
+ first_ok_link_idx_chain = current_link_idx_chain;
+ DBUG_RETURN(FALSE);
+ }
+ }
+ DBUG_RETURN(TRUE);
+}
+
+bool spider_fields::is_first_link_ok_chain(
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg
+) {
+ DBUG_ENTER("spider_fields::is_first_link_ok_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN(first_ok_link_idx_chain == link_idx_chain_arg);
+}
+
+int spider_fields::get_ok_link_idx(
+) {
+ DBUG_ENTER("spider_fields::get_ok_link_idx");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN(first_ok_link_idx_chain->link_idx_holder->link_idx);
+}
+
+void spider_fields::set_first_link_idx(
+) {
+ SPIDER_TABLE_HOLDER *table_holder;
+ SPIDER_LINK_IDX_HOLDER *link_idx_holder;
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain;
+ uint dbton_id;
+ ha_spider *spider;
+ spider_db_handler *dbton_hdl;
+ DBUG_ENTER("spider_fields::set_first_link_idx");
+ DBUG_PRINT("info",("spider this=%p", this));
+ set_pos_to_first_dbton_id();
+ while ((dbton_id = get_next_dbton_id()) < SPIDER_DBTON_SIZE)
+ {
+ set_pos_to_first_link_idx_chain();
+ while ((link_idx_chain = get_next_link_idx_chain()))
+ {
+ if (link_idx_chain->conn->dbton_id == dbton_id)
+ {
+ break;
+ }
+ }
+ DBUG_ASSERT(link_idx_chain);
+ set_pos_to_first_table_on_link_idx_chain(link_idx_chain);
+
+ set_pos_to_first_table_holder();
+ while ((table_holder = get_next_table_holder()))
+ {
+ link_idx_holder = get_next_table_on_link_idx_chain(link_idx_chain);
+ spider = table_holder->spider;
+ dbton_hdl = spider->dbton_handler[dbton_id];
+ dbton_hdl->first_link_idx = link_idx_holder->link_idx;
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
+int spider_fields::add_link_idx(
+ SPIDER_CONN_HOLDER *conn_holder_arg,
+ ha_spider *spider_arg,
+ int link_idx
+) {
+ SPIDER_TABLE_LINK_IDX_HOLDER *table_link_idx_holder;
+ SPIDER_LINK_IDX_HOLDER *link_idx_holder;
+ DBUG_ENTER("spider_fields::add_link_idx");
+ DBUG_PRINT("info",("spider this=%p", this));
+ table_link_idx_holder =
+ &conn_holder_arg->table_link_idx_holder[spider_arg->idx_for_direct_join];
+ if (!table_link_idx_holder->first_link_idx_holder)
+ {
+ link_idx_holder = create_link_idx_holder();
+ DBUG_PRINT("info",("spider link_idx_holder=%p", link_idx_holder));
+ if (!link_idx_holder)
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ table_link_idx_holder->first_link_idx_holder = link_idx_holder;
+ table_link_idx_holder->last_link_idx_holder = link_idx_holder;
+ table_link_idx_holder->table_holder =
+ &table_holder[spider_arg->idx_for_direct_join];
+ } else {
+ link_idx_holder = create_link_idx_holder();
+ DBUG_PRINT("info",("spider link_idx_holder=%p", link_idx_holder));
+ if (!link_idx_holder)
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ table_link_idx_holder->last_link_idx_holder->next = link_idx_holder;
+ table_link_idx_holder->last_link_idx_holder = link_idx_holder;
+ }
+ link_idx_holder->table_link_idx_holder = table_link_idx_holder;
+ link_idx_holder->link_idx = link_idx;
+ link_idx_holder->link_status = spider_conn_get_link_status(
+ spider_arg->share->link_statuses, spider_arg->conn_link_idx,
+ link_idx);
+ ++table_link_idx_holder->link_idx_holder_count;
+ if (conn_holder_arg->link_idx_holder_count_max <
+ table_link_idx_holder->link_idx_holder_count)
+ {
+ conn_holder_arg->link_idx_holder_count_max =
+ table_link_idx_holder->link_idx_holder_count;
+ }
+ DBUG_RETURN(0);
+}
+
+SPIDER_LINK_IDX_HOLDER *spider_fields::create_link_idx_holder(
+) {
+ DBUG_ENTER("spider_fields::create_link_idx_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN((SPIDER_LINK_IDX_HOLDER *)
+ spider_malloc(spider_current_trx, 253, sizeof(SPIDER_LINK_IDX_HOLDER),
+ MYF(MY_WME | MY_ZEROFILL)));
+}
+
+void spider_fields::set_pos_to_first_table_on_link_idx_chain(
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg
+) {
+ DBUG_ENTER("spider_fields::set_pos_to_first_table_on_link_idx_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ link_idx_chain_arg->current_link_idx_holder =
+ link_idx_chain_arg->link_idx_holder;
+ DBUG_VOID_RETURN;
+}
+
+SPIDER_LINK_IDX_HOLDER *spider_fields::get_next_table_on_link_idx_chain(
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain_arg
+) {
+ SPIDER_LINK_IDX_HOLDER *return_link_idx_holder;
+ DBUG_ENTER("spider_fields::get_next_table_on_link_idx_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (!link_idx_chain_arg->current_link_idx_holder)
+ DBUG_RETURN(NULL);
+ return_link_idx_holder = link_idx_chain_arg->current_link_idx_holder;
+ link_idx_chain_arg->current_link_idx_holder =
+ link_idx_chain_arg->current_link_idx_holder->next_table;
+ DBUG_RETURN(return_link_idx_holder);
+}
+
+SPIDER_CONN_HOLDER *spider_fields::add_conn(
+ SPIDER_CONN *conn_arg,
+ long access_balance
+) {
+ SPIDER_CONN_HOLDER *conn_holder;
+ DBUG_ENTER("spider_fields::add_conn");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (!first_conn_holder)
+ {
+ conn_holder = create_conn_holder();
+ DBUG_PRINT("info",("spider conn_holder=%p", conn_holder));
+ if (!conn_holder)
+ DBUG_RETURN(NULL);
+ conn_holder->conn = conn_arg;
+ conn_holder->access_balance = access_balance;
+ first_conn_holder = conn_holder;
+ last_conn_holder = conn_holder;
+ conn_arg->conn_holder_for_direct_join = conn_holder;
+ add_dbton_id(conn_arg->dbton_id);
+ } else {
+ conn_holder = first_conn_holder;
+ do {
+ if (conn_holder->conn == conn_arg)
+ break;
+ } while ((conn_holder = conn_holder->next));
+ if (!conn_holder)
+ {
+ conn_holder = create_conn_holder();
+ DBUG_PRINT("info",("spider conn_holder=%p", conn_holder));
+ if (!conn_holder)
+ DBUG_RETURN(NULL);
+ conn_holder->conn = conn_arg;
+ conn_holder->access_balance = access_balance;
+ conn_holder->prev = last_conn_holder;
+ last_conn_holder->next = conn_holder;
+ last_conn_holder = conn_holder;
+ conn_arg->conn_holder_for_direct_join = conn_holder;
+ add_dbton_id(conn_arg->dbton_id);
+ }
+ }
+ DBUG_RETURN(conn_holder);
+}
+
+SPIDER_CONN_HOLDER *spider_fields::create_conn_holder(
+) {
+ SPIDER_CONN_HOLDER *return_conn_holder;
+ SPIDER_TABLE_LINK_IDX_HOLDER *table_link_idx_holder;
+ DBUG_ENTER("spider_fields::create_conn_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ return_conn_holder = (SPIDER_CONN_HOLDER *)
+ spider_bulk_malloc(spider_current_trx, 252, MYF(MY_WME | MY_ZEROFILL),
+ &return_conn_holder, sizeof(SPIDER_CONN_HOLDER),
+ &table_link_idx_holder,
+ table_count * sizeof(SPIDER_TABLE_LINK_IDX_HOLDER),
+ NullS
+ );
+ if (!return_conn_holder)
+ DBUG_RETURN(NULL);
+ DBUG_PRINT("info",("spider table_count=%u", table_count));
+ DBUG_PRINT("info",("spider table_link_idx_holder=%p", table_link_idx_holder));
+ return_conn_holder->table_link_idx_holder = table_link_idx_holder;
+ DBUG_RETURN(return_conn_holder);
+}
+
+void spider_fields::set_pos_to_first_conn_holder(
+) {
+ DBUG_ENTER("spider_fields::set_pos_to_first_conn_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ current_conn_holder = first_conn_holder;
+ DBUG_VOID_RETURN;
+}
+
+SPIDER_CONN_HOLDER *spider_fields::get_next_conn_holder(
+) {
+ SPIDER_CONN_HOLDER *return_conn_holder = current_conn_holder;
+ DBUG_ENTER("spider_fields::get_next_conn_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (current_conn_holder)
+ current_conn_holder = current_conn_holder->next;
+ DBUG_RETURN(return_conn_holder);
+}
+
+bool spider_fields::has_conn_holder(
+) {
+ DBUG_ENTER("spider_fields::has_conn_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN(first_conn_holder);
+}
+
+void spider_fields::clear_conn_holder_from_conn(
+) {
+ DBUG_ENTER("spider_fields::clear_conn_checked_for_same_conn");
+ DBUG_PRINT("info",("spider this=%p", this));
+ for (current_conn_holder = first_conn_holder; current_conn_holder;
+ current_conn_holder = current_conn_holder->next)
+ {
+ current_conn_holder->checked_for_same_conn = FALSE;
+ }
+ DBUG_VOID_RETURN;
+}
+
+bool spider_fields::check_conn_same_conn(
+ SPIDER_CONN *conn_arg
+) {
+ DBUG_ENTER("spider_fields::check_conn_same_conn");
+ DBUG_PRINT("info",("spider this=%p", this));
+ for (current_conn_holder = first_conn_holder; current_conn_holder;
+ current_conn_holder = current_conn_holder->next)
+ {
+ if (current_conn_holder->conn == conn_arg)
+ {
+ current_conn_holder->checked_for_same_conn = TRUE;
+ DBUG_RETURN(TRUE);
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
+
+bool spider_fields::remove_conn_if_not_checked(
+) {
+ SPIDER_CONN_HOLDER *conn_holder;
+ bool removed = FALSE;
+ DBUG_ENTER("spider_fields::remove_conn_if_not_checked");
+ DBUG_PRINT("info",("spider this=%p", this));
+ current_conn_holder = first_conn_holder;
+ while (current_conn_holder)
+ {
+ if (!current_conn_holder->checked_for_same_conn)
+ {
+ removed = TRUE;
+ DBUG_PRINT("info",("spider remove connection %p",
+ current_conn_holder->conn));
+ if (!current_conn_holder->prev)
+ {
+ first_conn_holder = current_conn_holder->next;
+ if (current_conn_holder->next)
+ {
+ current_conn_holder->next->prev = NULL;
+ } else {
+ last_conn_holder = NULL;
+ }
+ } else {
+ current_conn_holder->prev->next = current_conn_holder->next;
+ if (current_conn_holder->next)
+ {
+ current_conn_holder->next->prev = current_conn_holder->prev;
+ } else {
+ last_conn_holder = current_conn_holder->prev;
+ last_conn_holder->next = NULL;
+ }
+ }
+ conn_holder = current_conn_holder->next;
+ free_conn_holder(current_conn_holder);
+ current_conn_holder = conn_holder;
+ } else {
+ current_conn_holder = current_conn_holder->next;
+ }
+ }
+ DBUG_RETURN(removed);
+}
+
+void spider_fields::check_support_dbton(
+ uchar *dbton_bitmap
+) {
+ SPIDER_CONN_HOLDER *conn_holder;
+ DBUG_ENTER("spider_fields::check_support_dbton");
+ DBUG_PRINT("info",("spider this=%p", this));
+ current_conn_holder = first_conn_holder;
+ while (current_conn_holder)
+ {
+ if (!spider_bit_is_set(dbton_bitmap, current_conn_holder->conn->dbton_id))
+ {
+ DBUG_PRINT("info",("spider remove connection %p",
+ current_conn_holder->conn));
+ if (!current_conn_holder->prev)
+ {
+ first_conn_holder = current_conn_holder->next;
+ if (current_conn_holder->next)
+ {
+ current_conn_holder->next->prev = NULL;
+ } else {
+ last_conn_holder = NULL;
+ }
+ } else {
+ current_conn_holder->prev->next = current_conn_holder->next;
+ if (current_conn_holder->next)
+ {
+ current_conn_holder->next->prev = current_conn_holder->prev;
+ } else {
+ last_conn_holder = current_conn_holder->prev;
+ last_conn_holder->next = NULL;
+ }
+ }
+ conn_holder = current_conn_holder->next;
+ free_conn_holder(current_conn_holder);
+ current_conn_holder = conn_holder;
+ } else {
+ current_conn_holder = current_conn_holder->next;
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
+void spider_fields::choose_a_conn(
+) {
+ SPIDER_CONN_HOLDER *conn_holder;
+ longlong balance_total = 0, balance_val;
+ double rand_val;
+ THD *thd = table_holder[0].spider->trx->thd;
+ DBUG_ENTER("spider_fields::choose_a_conn");
+ DBUG_PRINT("info",("spider this=%p", this));
+ for (current_conn_holder = first_conn_holder; current_conn_holder;
+ current_conn_holder = current_conn_holder->next)
+ {
+ balance_total += current_conn_holder->access_balance;
+ }
+
+ rand_val = spider_rand(thd->variables.server_id + thd_get_thread_id(thd));
+ balance_val = (longlong) (rand_val * balance_total);
+
+ current_conn_holder = first_conn_holder;
+ while (current_conn_holder)
+ {
+ if (balance_val < current_conn_holder->access_balance)
+ break;
+ balance_val -= current_conn_holder->access_balance;
+
+ DBUG_PRINT("info",("spider remove connection %p",
+ current_conn_holder->conn));
+ first_conn_holder = current_conn_holder->next;
+ DBUG_ASSERT(current_conn_holder->next);
+ first_conn_holder->prev = NULL;
+ free_conn_holder(current_conn_holder);
+ current_conn_holder = first_conn_holder;
+ }
+
+ DBUG_PRINT("info",("spider choosed connection is %p",
+ current_conn_holder->conn));
+ last_conn_holder = current_conn_holder;
+ current_conn_holder = current_conn_holder->next;
+ last_conn_holder->next = NULL;
+
+ while (current_conn_holder)
+ {
+ DBUG_PRINT("info",("spider remove connection %p",
+ current_conn_holder->conn));
+ conn_holder = current_conn_holder->next;
+ free_conn_holder(current_conn_holder);
+ current_conn_holder = conn_holder;
+ }
+ DBUG_VOID_RETURN;
+}
+
+void spider_fields::free_conn_holder(
+ SPIDER_CONN_HOLDER *conn_holder_arg
+) {
+ uint roop_count;
+ DBUG_ENTER("spider_fields::free_conn_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ for (roop_count = 0; roop_count < table_count; ++roop_count)
+ {
+ if (conn_holder_arg->table_link_idx_holder[roop_count].first_link_idx_holder)
+ {
+ SPIDER_LINK_IDX_HOLDER *first_link_idx_holder, *current_link_idx_holder;
+ first_link_idx_holder =
+ conn_holder_arg->table_link_idx_holder[roop_count].first_link_idx_holder;
+ while ((current_link_idx_holder = first_link_idx_holder))
+ {
+ first_link_idx_holder = current_link_idx_holder->next;
+ spider_free(spider_current_trx, current_link_idx_holder, MYF(0));
+ }
+ }
+ }
+ conn_holder_arg->conn->conn_holder_for_direct_join = NULL;
+ DBUG_PRINT("info",("spider free conn_holder=%p", conn_holder_arg));
+ spider_free(spider_current_trx, conn_holder_arg, MYF(0));
+ DBUG_VOID_RETURN;
+}
+
+SPIDER_TABLE_HOLDER *spider_fields::add_table(
+ ha_spider *spider_arg
+) {
+ spider_string *str;
+ uint length;
+ char tmp_buf[SPIDER_SQL_INT_LEN + 2];
+ SPIDER_TABLE_HOLDER *return_table_holder;
+ SPIDER_FIELD_HOLDER *field_holder;
+ TABLE *table = spider_arg->get_table();
+ Field *field;
+ DBUG_ENTER("spider_fields::add_table");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_PRINT("info",("spider table_count=%u", table_count));
+ DBUG_PRINT("info",("spider idx_for_direct_join=%u",
+ spider_arg->idx_for_direct_join));
+ length = my_sprintf(tmp_buf, (tmp_buf, "t%u",
+ spider_arg->idx_for_direct_join));
+ str = &spider_arg->result_list.tmp_sqls[0];
+ str->length(0);
+ if (str->reserve(length + SPIDER_SQL_DOT_LEN))
+ {
+ DBUG_RETURN(NULL);
+ }
+ str->q_append(tmp_buf, length);
+ str->q_append(SPIDER_SQL_DOT_STR, SPIDER_SQL_DOT_LEN);
+
+ return_table_holder = &table_holder[spider_arg->idx_for_direct_join];
+ return_table_holder->table = spider_arg->get_table();
+ return_table_holder->spider = spider_arg;
+ return_table_holder->alias = str;
+
+ set_pos_to_first_field_holder();
+ while ((field_holder = get_next_field_holder()))
+ {
+ if (!field_holder->spider)
+ {
+ field = field_holder->field;
+ if (
+ field->field_index < table->s->fields &&
+ field == table->field[field->field_index]
+ ) {
+ field_holder->spider = spider_arg;
+ field_holder->alias = str;
+ }
+ }
+ }
+ DBUG_RETURN(return_table_holder);
+}
+
+int spider_fields::create_table_holder(
+ uint table_count_arg
+) {
+ DBUG_ENTER("spider_fields::create_table_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(!table_holder);
+ table_holder = (SPIDER_TABLE_HOLDER *)
+ spider_malloc(spider_current_trx, 249,
+ table_count_arg * sizeof(SPIDER_TABLE_HOLDER),
+ MYF(MY_WME | MY_ZEROFILL));
+ if (!table_holder)
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ table_count = table_count_arg;
+ current_table_num = 0;
+ DBUG_RETURN(0);
+}
+
+void spider_fields::set_pos_to_first_table_holder(
+) {
+ DBUG_ENTER("spider_fields::set_pos_to_first_table_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ current_table_num = 0;
+ DBUG_VOID_RETURN;
+}
+
+SPIDER_TABLE_HOLDER *spider_fields::get_next_table_holder(
+) {
+ SPIDER_TABLE_HOLDER *return_table_holder;
+ DBUG_ENTER("spider_fields::get_next_table_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (current_table_num >= table_count)
+ DBUG_RETURN(NULL);
+ return_table_holder = &table_holder[current_table_num];
+ ++current_table_num;
+ DBUG_RETURN(return_table_holder);
+}
+
+int spider_fields::add_field(
+ Field *field_arg
+) {
+ SPIDER_FIELD_HOLDER *field_holder;
+ SPIDER_FIELD_CHAIN *field_chain;
+ DBUG_ENTER("spider_fields::add_field");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_PRINT("info",("spider field=%p", field_arg));
+ if (!first_field_holder)
+ {
+ field_holder = create_field_holder();
+ DBUG_PRINT("info",("spider field_holder=%p", field_holder));
+ if (!field_holder)
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ field_holder->field = field_arg;
+ first_field_holder = field_holder;
+ last_field_holder = field_holder;
+ } else {
+ field_holder = first_field_holder;
+ do {
+ if (field_holder->field == field_arg)
+ break;
+ } while ((field_holder = field_holder->next));
+ if (!field_holder)
+ {
+ field_holder = create_field_holder();
+ DBUG_PRINT("info",("spider field_holder=%p", field_holder));
+ if (!field_holder)
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ field_holder->field = field_arg;
+ last_field_holder->next = field_holder;
+ last_field_holder = field_holder;
+ }
+ }
+ field_chain = create_field_chain();
+ DBUG_PRINT("info",("spider field_chain=%p", field_chain));
+ if (!field_chain)
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ field_chain->field_holder = field_holder;
+ if (!first_field_chain)
+ {
+ first_field_chain = field_chain;
+ last_field_chain = field_chain;
+ } else {
+ last_field_chain->next = field_chain;
+ last_field_chain = field_chain;
+ }
+ DBUG_RETURN(0);
+}
+
+SPIDER_FIELD_HOLDER *spider_fields::create_field_holder(
+) {
+ DBUG_ENTER("spider_fields::create_field_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN((SPIDER_FIELD_HOLDER *)
+ spider_malloc(spider_current_trx, 250, sizeof(SPIDER_FIELD_HOLDER),
+ MYF(MY_WME | MY_ZEROFILL)));
+}
+
+void spider_fields::set_pos_to_first_field_holder(
+) {
+ DBUG_ENTER("spider_fields::set_pos_to_first_field_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ current_field_holder = first_field_holder;
+ DBUG_VOID_RETURN;
+}
+
+SPIDER_FIELD_HOLDER *spider_fields::get_next_field_holder(
+) {
+ SPIDER_FIELD_HOLDER *return_field_holder = current_field_holder;
+ DBUG_ENTER("spider_fields::get_next_field_holder");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (current_field_holder)
+ current_field_holder = current_field_holder->next;
+ DBUG_RETURN(return_field_holder);
+}
+
+SPIDER_FIELD_CHAIN *spider_fields::create_field_chain(
+) {
+ DBUG_ENTER("spider_fields::create_field_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN((SPIDER_FIELD_CHAIN *)
+ spider_malloc(spider_current_trx, 251, sizeof(SPIDER_FIELD_CHAIN),
+ MYF(MY_WME | MY_ZEROFILL)));
+}
+
+void spider_fields::set_pos_to_first_field_chain(
+) {
+ DBUG_ENTER("spider_fields::set_pos_to_first_field_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ current_field_chain = first_field_chain;
+ DBUG_VOID_RETURN;
+}
+
+SPIDER_FIELD_CHAIN *spider_fields::get_next_field_chain(
+) {
+ SPIDER_FIELD_CHAIN *return_field_chain = current_field_chain;
+ DBUG_ENTER("spider_fields::get_next_field_chain");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (current_field_chain)
+ current_field_chain = current_field_chain->next;
+ DBUG_RETURN(return_field_chain);
+}
+
+void spider_fields::set_field_ptr(
+ Field **field_arg
+) {
+ DBUG_ENTER("spider_fields::set_field_ptr");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_PRINT("info",("spider field_ptr=%p", field_arg));
+ first_field_ptr = field_arg;
+ current_field_ptr = field_arg;
+ DBUG_VOID_RETURN;
+}
+
+Field **spider_fields::get_next_field_ptr(
+) {
+ Field **return_field_ptr = current_field_ptr;
+ DBUG_ENTER("spider_fields::get_next_field_ptr");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (*current_field_ptr)
+ current_field_ptr++;
+ DBUG_PRINT("info",("spider field_ptr=%p", return_field_ptr));
+ DBUG_RETURN(return_field_ptr);
+}
+
+int spider_fields::ping_table_mon_from_table(
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain
+) {
+ int error_num = 0, error_num_buf;
+ ha_spider *tmp_spider;
+ SPIDER_SHARE *tmp_share;
+ int tmp_link_idx;
+ SPIDER_TABLE_HOLDER *table_holder;
+ SPIDER_LINK_IDX_HOLDER *link_idx_holder;
+ DBUG_ENTER("spider_fields::ping_table_mon_from_table");
+ set_pos_to_first_table_on_link_idx_chain(link_idx_chain);
+ set_pos_to_first_table_holder();
+ while ((table_holder = get_next_table_holder()))
+ {
+ link_idx_holder = get_next_table_on_link_idx_chain(link_idx_chain);
+ tmp_spider = table_holder->spider;
+ tmp_link_idx = link_idx_holder->link_idx;
+ tmp_share = tmp_spider->share;
+ if (tmp_share->monitoring_kind[tmp_link_idx])
+ {
+ error_num_buf = spider_ping_table_mon_from_table(
+ tmp_spider->trx,
+ tmp_spider->trx->thd,
+ tmp_share,
+ tmp_link_idx,
+ (uint32) tmp_share->monitoring_sid[tmp_link_idx],
+ tmp_share->table_name,
+ tmp_share->table_name_length,
+ tmp_spider->conn_link_idx[tmp_link_idx],
+ NULL,
+ 0,
+ tmp_share->monitoring_kind[tmp_link_idx],
+ tmp_share->monitoring_limit[tmp_link_idx],
+ tmp_share->monitoring_flag[tmp_link_idx],
+ TRUE
+ );
+ if (!error_num)
+ error_num = error_num_buf;
+ }
+ }
+ DBUG_RETURN(error_num);
+}
+
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+spider_group_by_handler::spider_group_by_handler(
+ THD *thd_arg,
+ Query *query_arg,
+ spider_fields *fields_arg
+) : group_by_handler(thd_arg, spider_hton_ptr),
+ query(*query_arg), fields(fields_arg)
+{
+ DBUG_ENTER("spider_group_by_handler::spider_group_by_handler");
+ fields->set_pos_to_first_table_holder();
+ SPIDER_TABLE_HOLDER *table_holder = fields->get_next_table_holder();
+ spider = table_holder->spider;
+ trx = spider->trx;
+ DBUG_VOID_RETURN;
+}
+
+spider_group_by_handler::~spider_group_by_handler()
+{
+ DBUG_ENTER("spider_group_by_handler::~spider_group_by_handler");
+ delete fields;
+ DBUG_VOID_RETURN;
+}
+
+int spider_group_by_handler::init_scan()
+{
+ int error_num, link_idx;
+ uint dbton_id;
+ spider_db_handler *dbton_hdl;
+ st_select_lex *select_lex;
+ longlong select_limit;
+ longlong direct_order_limit;
+ SPIDER_SHARE *share = spider->share;
+ SPIDER_CONN *conn;
+ SPIDER_RESULT_LIST *result_list = &spider->result_list;
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain;
+ SPIDER_LINK_IDX_HOLDER *link_idx_holder;
+ DBUG_ENTER("spider_group_by_handler::init_scan");
+ store_error = 0;
+#ifndef DBUG_OFF
+ Field **field;
+ for (
+ field = table->field;
+ *field;
+ field++
+ ) {
+ DBUG_PRINT("info",("spider field_name=%s", (*field)->field_name.str));
+ }
+#endif
+
+ if (trx->thd->killed)
+ {
+ my_error(ER_QUERY_INTERRUPTED, MYF(0));
+ DBUG_RETURN(ER_QUERY_INTERRUPTED);
+ }
+
+ spider->use_fields = TRUE;
+ spider->fields = fields;
+
+ spider->check_pre_call(TRUE);
+
+ spider->pushed_pos = NULL;
+ result_list->sorted = (query.group_by || query.order_by);
+ spider_set_result_list_param(spider);
+ spider->mrr_with_cnt = FALSE;
+ spider->init_index_handler = FALSE;
+ spider->use_spatial_index = FALSE;
+ result_list->check_direct_order_limit = FALSE;
+ spider->select_column_mode = 0;
+ spider->search_link_idx = fields->get_ok_link_idx();
+ spider->result_link_idx = spider->search_link_idx;
+
+ spider_db_free_one_result_for_start_next(spider);
+
+ spider->sql_kinds = SPIDER_SQL_KIND_SQL;
+ for (link_idx = 0; link_idx < (int) share->link_count; ++link_idx)
+ spider->sql_kind[link_idx] = SPIDER_SQL_KIND_SQL;
+
+#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
+ spider->do_direct_update = FALSE;
+ spider->direct_update_kinds = 0;
+#endif
+ spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit);
+ direct_order_limit = spider_param_direct_order_limit(thd,
+ share->direct_order_limit);
+ if (
+ direct_order_limit &&
+ select_lex->explicit_limit &&
+ !(select_lex->options & OPTION_FOUND_ROWS) &&
+ select_limit < direct_order_limit /* - offset_limit */
+ ) {
+ result_list->internal_limit = select_limit /* + offset_limit */;
+ result_list->split_read = select_limit /* + offset_limit */;
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ result_list->bgs_split_read = select_limit /* + offset_limit */;
+#endif
+
+ result_list->split_read_base = 9223372036854775807LL;
+ result_list->semi_split_read = 0;
+ result_list->semi_split_read_limit = 9223372036854775807LL;
+ result_list->first_read = 9223372036854775807LL;
+ result_list->second_read = 9223372036854775807LL;
+ trx->direct_order_limit_count++;
+ }
+ result_list->semi_split_read_base = 0;
+ result_list->set_split_read = TRUE;
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ if ((error_num = spider_set_conn_bg_param(spider)))
+ DBUG_RETURN(error_num);
+#endif
+ DBUG_PRINT("info",("spider result_list.finish_flg = FALSE"));
+ result_list->finish_flg = FALSE;
+ result_list->record_num = 0;
+ result_list->keyread = FALSE;
+ result_list->desc_flg = FALSE;
+ result_list->sorted = FALSE;
+ result_list->key_info = NULL;
+ result_list->key_order = 0;
+ result_list->limit_num =
+ result_list->internal_limit >= result_list->split_read ?
+ result_list->split_read : result_list->internal_limit;
+
+ if (select_lex->explicit_limit)
+ {
+ result_list->internal_offset += offset_limit;
+ } else {
+ offset_limit = 0;
+ }
+
+ /* making a query */
+ fields->set_pos_to_first_dbton_id();
+ while ((dbton_id = fields->get_next_dbton_id()) < SPIDER_DBTON_SIZE)
+ {
+ dbton_hdl = spider->dbton_handler[dbton_id];
+ result_list->direct_distinct = query.distinct;
+ fields->set_pos_to_first_field_chain();
+ if ((error_num = dbton_hdl->reset_sql(SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if ((error_num = dbton_hdl->append_select_part(SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ fields->set_field_ptr(table->field);
+ if ((error_num = dbton_hdl->append_list_item_select_part(
+ query.select, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if ((error_num = dbton_hdl->append_from_and_tables_part(
+ fields, SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if (query.where)
+ {
+ if ((error_num =
+ dbton_hdl->append_where_part(SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if ((error_num = dbton_hdl->append_item_type_part(
+ query.where, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ }
+ if (query.group_by)
+ {
+ if ((error_num = dbton_hdl->append_group_by_part(
+ query.group_by, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ }
+ if (query.having)
+ {
+ if ((error_num =
+ dbton_hdl->append_having_part(SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if ((error_num = dbton_hdl->append_item_type_part(
+ query.having, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ }
+ if (query.order_by)
+ {
+ if ((error_num = dbton_hdl->append_order_by_part(
+ query.order_by, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ }
+ if ((error_num = dbton_hdl->append_limit_part(result_list->internal_offset,
+ result_list->limit_num, SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if ((error_num = dbton_hdl->append_select_lock_part(
+ SPIDER_SQL_TYPE_SELECT_SQL)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ }
+
+ fields->set_pos_to_first_link_idx_chain();
+ while ((link_idx_chain = fields->get_next_link_idx_chain()))
+ {
+ conn = link_idx_chain->conn;
+ link_idx_holder = link_idx_chain->link_idx_holder;
+ link_idx = link_idx_holder->link_idx;
+ dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ spider->link_idx_chain = link_idx_chain;
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ if (result_list->bgs_phase > 0)
+ {
+ if ((error_num = spider_check_and_init_casual_read(trx->thd, spider,
+ link_idx)))
+ DBUG_RETURN(error_num);
+ if ((error_num = spider_bg_conn_search(spider, link_idx,
+ dbton_hdl->first_link_idx, TRUE, FALSE,
+ !fields->is_first_link_ok_chain(link_idx_chain))))
+ {
+ if (
+ error_num != HA_ERR_END_OF_FILE &&
+ spider->need_mons[link_idx]
+ ) {
+ error_num = fields->ping_table_mon_from_table(link_idx_chain);
+ }
+ if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE)
+ {
+ store_error = HA_ERR_END_OF_FILE;
+ error_num = 0;
+ }
+ DBUG_RETURN(error_num);
+ }
+ } else {
+#endif
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_SELECT_SQL))
+ {
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ }
+ if ((error_num =
+ dbton_hdl->set_sql_for_exec(SPIDER_SQL_TYPE_SELECT_SQL, link_idx,
+ link_idx_chain)))
+ {
+ DBUG_RETURN(error_num);
+ }
+ if (!dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_SELECT_SQL))
+ {
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ }
+ conn->need_mon = &spider->need_mons[link_idx];
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
+ if ((error_num = spider_db_set_names(spider, conn,
+ link_idx)))
+ {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ if (
+ spider->need_mons[link_idx]
+ ) {
+ error_num = fields->ping_table_mon_from_table(link_idx_chain);
+ }
+ if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE)
+ {
+ store_error = HA_ERR_END_OF_FILE;
+ error_num = 0;
+ }
+ DBUG_RETURN(error_num);
+ }
+ spider_conn_set_timeout_from_share(conn, link_idx,
+ trx->thd, share);
+ if (dbton_hdl->execute_sql(
+ SPIDER_SQL_TYPE_SELECT_SQL,
+ conn,
+ spider->result_list.quick_mode,
+ &spider->need_mons[link_idx])
+ ) {
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ error_num = spider_db_errorno(conn);
+ if (
+ spider->need_mons[link_idx]
+ ) {
+ error_num = fields->ping_table_mon_from_table(link_idx_chain);
+ }
+ if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE)
+ {
+ store_error = HA_ERR_END_OF_FILE;
+ error_num = 0;
+ }
+ DBUG_RETURN(error_num);
+ }
+ spider->connection_ids[link_idx] = conn->connection_id;
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ if (fields->is_first_link_ok_chain(link_idx_chain))
+ {
+ if ((error_num = spider_db_store_result(spider, link_idx, table)))
+ {
+ if (
+ error_num != HA_ERR_END_OF_FILE &&
+ spider->need_mons[link_idx]
+ ) {
+ error_num = fields->ping_table_mon_from_table(link_idx_chain);
+ }
+ if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE)
+ {
+ store_error = HA_ERR_END_OF_FILE;
+ error_num = 0;
+ }
+ DBUG_RETURN(error_num);
+ }
+ spider->result_link_idx = link_idx;
+ spider->result_link_idx_chain = link_idx_chain;
+ } else {
+ spider_db_discard_result(spider, link_idx, conn);
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ }
+#endif
+ }
+
+ first = TRUE;
+ DBUG_RETURN(0);
+}
+
+int spider_group_by_handler::next_row()
+{
+ int error_num, link_idx;
+ spider_db_handler *dbton_hdl;
+ SPIDER_CONN *conn;
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain;
+ SPIDER_LINK_IDX_HOLDER *link_idx_holder;
+ DBUG_ENTER("spider_group_by_handler::next_row");
+ if (trx->thd->killed)
+ {
+ my_error(ER_QUERY_INTERRUPTED, MYF(0));
+ DBUG_RETURN(ER_QUERY_INTERRUPTED);
+ }
+ if (store_error)
+ {
+ if (store_error == HA_ERR_END_OF_FILE)
+ {
+ table->status = STATUS_NOT_FOUND;
+ }
+ DBUG_RETURN(store_error);
+ }
+ if (first)
+ {
+ first = FALSE;
+ if (spider->use_pre_call)
+ {
+ if (spider->store_error_num)
+ {
+ if (spider->store_error_num == HA_ERR_END_OF_FILE)
+ table->status = STATUS_NOT_FOUND;
+ DBUG_RETURN(spider->store_error_num);
+ }
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ if (spider->result_list.bgs_phase > 0)
+ {
+ fields->set_pos_to_first_link_idx_chain();
+ while ((link_idx_chain = fields->get_next_link_idx_chain()))
+ {
+ conn = link_idx_chain->conn;
+ link_idx_holder = link_idx_chain->link_idx_holder;
+ link_idx = link_idx_holder->link_idx;
+ dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ spider->link_idx_chain = link_idx_chain;
+ if ((error_num = spider_bg_conn_search(spider, link_idx,
+ dbton_hdl->first_link_idx, TRUE, TRUE,
+ !fields->is_first_link_ok_chain(link_idx_chain))))
+ {
+ if (
+ error_num != HA_ERR_END_OF_FILE &&
+ spider->need_mons[link_idx]
+ ) {
+ error_num = fields->ping_table_mon_from_table(link_idx_chain);
+ }
+ if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE)
+ {
+ table->status = STATUS_NOT_FOUND;
+ }
+ DBUG_RETURN(error_num);
+ }
+ }
+ }
+#endif
+ spider->use_pre_call = FALSE;
+ }
+ } else if (offset_limit)
+ {
+ --offset_limit;
+ DBUG_RETURN(0);
+ }
+ if ((error_num = spider_db_seek_next(table->record[0], spider,
+ spider->search_link_idx, table)))
+ {
+ if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE)
+ {
+ table->status = STATUS_NOT_FOUND;
+ }
+ DBUG_RETURN(error_num);
+ }
+ DBUG_RETURN(0);
+}
+
+int spider_group_by_handler::end_scan()
+{
+ DBUG_ENTER("spider_group_by_handler::end_scan");
+ DBUG_RETURN(0);
+}
+
+group_by_handler *spider_create_group_by_handler(
+ THD *thd,
+ Query *query
+) {
+ spider_group_by_handler *group_by_handler;
+ Item *item;
+ TABLE_LIST *from;
+ SPIDER_CONN *conn;
+ ha_spider *spider;
+ SPIDER_SHARE *share;
+ int roop_count, lock_mode;
+ List_iterator_fast<Item> it(*query->select);
+ uchar dbton_bitmap[spider_bitmap_size(SPIDER_DBTON_SIZE)];
+ uchar dbton_bitmap_tmp[spider_bitmap_size(SPIDER_DBTON_SIZE)];
+ ORDER *order;
+ bool keep_going;
+ bool find_dbton = FALSE;
+ spider_fields *fields = NULL, *fields_arg = NULL;
+ uint table_idx, dbton_id;
+ long tgt_link_status;
+ DBUG_ENTER("spider_create_group_by_handler");
+
+ switch (thd_sql_command(thd))
+ {
+ case SQLCOM_UPDATE:
+ case SQLCOM_UPDATE_MULTI:
+ case SQLCOM_DELETE:
+ case SQLCOM_DELETE_MULTI:
+ DBUG_PRINT("info",("spider update and delete does not support this feature"));
+ DBUG_RETURN(NULL);
+ default:
+ break;
+ }
+
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ from = query->from;
+ do {
+ DBUG_PRINT("info",("spider from=%p", from));
+ if (from->table->const_table)
+ continue;
+ if (from->table->part_info)
+ {
+ DBUG_PRINT("info",("spider partition handler"));
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ ha_partition *partition = (ha_partition *) from->table->file;
+ part_id_range *part_spec = partition->get_part_spec();
+ DBUG_PRINT("info",("spider part_spec->start_part=%u", part_spec->start_part));
+ DBUG_PRINT("info",("spider part_spec->end_part=%u", part_spec->end_part));
+ if (
+ part_spec->start_part == partition->get_no_current_part_id() ||
+ part_spec->start_part != part_spec->end_part
+ ) {
+ DBUG_PRINT("info",("spider using multiple partitions is not supported by this feature yet"));
+#else
+ DBUG_PRINT("info",("spider partition is not supported by this feature yet"));
+#endif
+ DBUG_RETURN(NULL);
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ }
+#endif
+ }
+ } while ((from = from->next_local));
+#endif
+
+ table_idx = 0;
+ from = query->from;
+ while (from && from->table->const_table)
+ {
+ from = from->next_local;
+ }
+ if (!from)
+ {
+ /* all tables are const_table */
+ DBUG_RETURN(NULL);
+ }
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ if (from->table->part_info)
+ {
+ ha_partition *partition = (ha_partition *) from->table->file;
+ part_id_range *part_spec = partition->get_part_spec();
+ handler **handlers = partition->get_child_handlers();
+ spider = (ha_spider *) handlers[part_spec->start_part];
+ } else {
+#endif
+ spider = (ha_spider *) from->table->file;
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ }
+#endif
+ share = spider->share;
+ spider->idx_for_direct_join = table_idx;
+ ++table_idx;
+ memset(dbton_bitmap, 0, spider_bitmap_size(SPIDER_DBTON_SIZE));
+ for (roop_count = 0; roop_count < (int) share->use_dbton_count; ++roop_count)
+ {
+ dbton_id = share->use_sql_dbton_ids[roop_count];
+ if (
+ spider_dbton[dbton_id].support_direct_join &&
+ spider_dbton[dbton_id].support_direct_join()
+ ) {
+ spider_set_bit(dbton_bitmap, dbton_id);
+ }
+ }
+ while ((from = from->next_local))
+ {
+ if (from->table->const_table)
+ continue;
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ if (from->table->part_info)
+ {
+ ha_partition *partition = (ha_partition *) from->table->file;
+ part_id_range *part_spec = partition->get_part_spec();
+ handler **handlers = partition->get_child_handlers();
+ spider = (ha_spider *) handlers[part_spec->start_part];
+ } else {
+#endif
+ spider = (ha_spider *) from->table->file;
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ }
+#endif
+ share = spider->share;
+ spider->idx_for_direct_join = table_idx;
+ ++table_idx;
+ memset(dbton_bitmap_tmp, 0, spider_bitmap_size(SPIDER_DBTON_SIZE));
+ for (roop_count = 0; roop_count < (int) share->use_dbton_count; ++roop_count)
+ {
+ dbton_id = share->use_sql_dbton_ids[roop_count];
+ if (
+ spider_dbton[dbton_id].support_direct_join &&
+ spider_dbton[dbton_id].support_direct_join()
+ ) {
+ spider_set_bit(dbton_bitmap_tmp, dbton_id);
+ }
+ }
+ for (roop_count = 0;
+ roop_count < spider_bitmap_size(SPIDER_DBTON_SIZE); ++roop_count)
+ {
+ dbton_bitmap[roop_count] &= dbton_bitmap_tmp[roop_count];
+ }
+ }
+
+ from = query->from;
+ do {
+ if (from->table->const_table)
+ continue;
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ if (from->table->part_info)
+ {
+ ha_partition *partition = (ha_partition *) from->table->file;
+ part_id_range *part_spec = partition->get_part_spec();
+ handler **handlers = partition->get_child_handlers();
+ spider = (ha_spider *) handlers[part_spec->start_part];
+ } else {
+#endif
+ spider = (ha_spider *) from->table->file;
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ }
+#endif
+ share = spider->share;
+ if (spider_param_skip_default_condition(thd,
+ share->skip_default_condition))
+ {
+ /* find skip_default_condition = 1 */
+ break;
+ }
+ } while ((from = from->next_local));
+
+ for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; ++roop_count)
+ {
+ if (spider_bit_is_set(dbton_bitmap, roop_count))
+ {
+ if (!fields)
+ {
+ fields_arg = new spider_fields();
+ if (!fields_arg)
+ {
+ DBUG_RETURN(NULL);
+ }
+ }
+ keep_going = TRUE;
+ it.init(*query->select);
+ while ((item = it++))
+ {
+ DBUG_PRINT("info",("spider select item=%p", item));
+ if (spider_db_print_item_type(item, spider, NULL, NULL, 0,
+ roop_count, TRUE, fields_arg))
+ {
+ DBUG_PRINT("info",("spider dbton_id=%d can't create select", roop_count));
+ spider_clear_bit(dbton_bitmap, roop_count);
+ keep_going = FALSE;
+ break;
+ }
+ }
+ if (keep_going)
+ {
+ DBUG_PRINT("info",("spider query->where=%p", query->where));
+ if (query->where)
+ {
+ if (spider_db_print_item_type(query->where, spider, NULL, NULL, 0,
+ roop_count, TRUE, fields_arg))
+ {
+ DBUG_PRINT("info",("spider dbton_id=%d can't create where", roop_count));
+ spider_clear_bit(dbton_bitmap, roop_count);
+ keep_going = FALSE;
+ }
+ }
+ }
+ if (keep_going)
+ {
+ DBUG_PRINT("info",("spider query->group_by=%p", query->group_by));
+ if (query->group_by)
+ {
+ for (order = query->group_by; order; order = order->next)
+ {
+ if (spider_db_print_item_type((*order->item), spider, NULL, NULL, 0,
+ roop_count, TRUE, fields_arg))
+ {
+ DBUG_PRINT("info",("spider dbton_id=%d can't create group by", roop_count));
+ spider_clear_bit(dbton_bitmap, roop_count);
+ keep_going = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ if (keep_going)
+ {
+ DBUG_PRINT("info",("spider query->order_by=%p", query->order_by));
+ if (query->order_by)
+ {
+ for (order = query->order_by; order; order = order->next)
+ {
+ if (spider_db_print_item_type((*order->item), spider, NULL, NULL, 0,
+ roop_count, TRUE, fields_arg))
+ {
+ DBUG_PRINT("info",("spider dbton_id=%d can't create order by", roop_count));
+ spider_clear_bit(dbton_bitmap, roop_count);
+ keep_going = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ if (keep_going)
+ {
+ DBUG_PRINT("info",("spider query->having=%p", query->having));
+ if (query->having)
+ {
+ if (spider_db_print_item_type(query->having, spider, NULL, NULL, 0,
+ roop_count, TRUE, fields_arg))
+ {
+ DBUG_PRINT("info",("spider dbton_id=%d can't create having", roop_count));
+ spider_clear_bit(dbton_bitmap, roop_count);
+ keep_going = FALSE;
+ }
+ }
+ }
+ if (keep_going)
+ {
+ find_dbton = TRUE;
+ fields = fields_arg;
+ fields_arg = NULL;
+ } else {
+ delete fields_arg;
+ }
+ }
+ }
+ if (!find_dbton)
+ {
+ DBUG_RETURN(NULL);
+ }
+
+ if (fields->create_table_holder(table_idx))
+ {
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+
+ from = query->from;
+ while (from->table->const_table)
+ {
+ from = from->next_local;
+ }
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ if (from->table->part_info)
+ {
+ ha_partition *partition = (ha_partition *) from->table->file;
+ part_id_range *part_spec = partition->get_part_spec();
+ handler **handlers = partition->get_child_handlers();
+ spider = (ha_spider *) handlers[part_spec->start_part];
+ } else {
+#endif
+ spider = (ha_spider *) from->table->file;
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ }
+#endif
+ share = spider->share;
+ lock_mode = spider_conn_lock_mode(spider);
+ if (lock_mode)
+ {
+ tgt_link_status = SPIDER_LINK_STATUS_RECOVERY;
+ } else {
+ tgt_link_status = SPIDER_LINK_STATUS_OK;
+ }
+ DBUG_PRINT("info",("spider s->db=%s", from->table->s->db.str));
+ DBUG_PRINT("info",("spider s->table_name=%s", from->table->s->table_name.str));
+ if (!fields->add_table(spider))
+ {
+ DBUG_PRINT("info",("spider can not add a table"));
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ for (
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, -1, share->link_count,
+ tgt_link_status);
+ roop_count < (int) share->link_count;
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, roop_count, share->link_count,
+ tgt_link_status)
+ ) {
+ if (spider_param_use_handler(thd, share->use_handlers[roop_count]))
+ {
+ DBUG_PRINT("info",("spider direct_join does not support use_handler"));
+ if (lock_mode)
+ {
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ continue;
+ }
+ conn = spider->conns[roop_count];
+ DBUG_PRINT("info",("spider roop_count=%d", roop_count));
+ DBUG_PRINT("info",("spider conn=%p", conn));
+ DBUG_ASSERT(conn);
+ if (conn->table_lock)
+ {
+ DBUG_PRINT("info",("spider direct_join does not support with lock tables yet"));
+ if (lock_mode)
+ {
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ continue;
+ }
+ if (!fields->add_conn(conn,
+ share->access_balances[spider->conn_link_idx[roop_count]]))
+ {
+ DBUG_PRINT("info",("spider can not create conn_holder"));
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ if (fields->add_link_idx(conn->conn_holder_for_direct_join, spider, roop_count))
+ {
+ DBUG_PRINT("info",("spider can not create link_idx_holder"));
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ }
+ if (!fields->has_conn_holder())
+ {
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+
+ while ((from = from->next_local))
+ {
+ if (from->table->const_table)
+ continue;
+ fields->clear_conn_holder_from_conn();
+
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ if (from->table->part_info)
+ {
+ ha_partition *partition = (ha_partition *) from->table->file;
+ part_id_range *part_spec = partition->get_part_spec();
+ handler **handlers = partition->get_child_handlers();
+ spider = (ha_spider *) handlers[part_spec->start_part];
+ } else {
+#endif
+ spider = (ha_spider *) from->table->file;
+#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
+ }
+#endif
+ share = spider->share;
+ if (!fields->add_table(spider))
+ {
+ DBUG_PRINT("info",("spider can not add a table"));
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ DBUG_PRINT("info",("spider s->db=%s", from->table->s->db.str));
+ DBUG_PRINT("info",("spider s->table_name=%s", from->table->s->table_name.str));
+ for (
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, -1, share->link_count,
+ tgt_link_status);
+ roop_count < (int) share->link_count;
+ roop_count = spider_conn_link_idx_next(share->link_statuses,
+ spider->conn_link_idx, roop_count, share->link_count,
+ tgt_link_status)
+ ) {
+ DBUG_PRINT("info",("spider roop_count=%d", roop_count));
+ if (spider_param_use_handler(thd, share->use_handlers[roop_count]))
+ {
+ DBUG_PRINT("info",("spider direct_join does not support use_handler"));
+ if (lock_mode)
+ {
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ continue;
+ }
+ conn = spider->conns[roop_count];
+ DBUG_PRINT("info",("spider conn=%p", conn));
+ if (!fields->check_conn_same_conn(conn))
+ {
+ DBUG_PRINT("info",("spider connection %p can not be used for this query with locking",
+ conn));
+ if (lock_mode)
+ {
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ continue;
+ }
+ if (fields->add_link_idx(conn->conn_holder_for_direct_join, spider, roop_count))
+ {
+ DBUG_PRINT("info",("spider can not create link_idx_holder"));
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ }
+
+ if (fields->remove_conn_if_not_checked())
+ {
+ if (lock_mode)
+ {
+ DBUG_PRINT("info",("spider some connections can not be used for this query with locking"));
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ }
+ if (!fields->has_conn_holder())
+ {
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ }
+
+ fields->check_support_dbton(dbton_bitmap);
+ if (!fields->has_conn_holder())
+ {
+ DBUG_PRINT("info",("spider all choosed connections can't match dbton_id"));
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+
+ /* choose a connection */
+ if (!lock_mode)
+ {
+ fields->choose_a_conn();
+ }
+
+ if (fields->make_link_idx_chain(tgt_link_status))
+ {
+ DBUG_PRINT("info",("spider can not create link_idx_chain"));
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+
+ /* choose link_id */
+ if (fields->check_link_ok_chain())
+ {
+ DBUG_PRINT("info",("spider do not have link ok status"));
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+
+ fields->set_first_link_idx();
+
+ if (!(group_by_handler = new spider_group_by_handler(thd, query, fields)))
+ {
+ DBUG_PRINT("info",("spider can't create group_by_handler"));
+ delete fields;
+ DBUG_RETURN(NULL);
+ }
+ query->distinct = FALSE;
+ query->where = NULL;
+ query->group_by = NULL;
+ query->having = NULL;
+ query->order_by = NULL;
+ DBUG_RETURN(group_by_handler);
+}
+#endif
diff --git a/storage/spider/spd_group_by_handler.h b/storage/spider/spd_group_by_handler.h
new file mode 100644
index 00000000000..09f82168708
--- /dev/null
+++ b/storage/spider/spd_group_by_handler.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 2016 Kentoku Shiba
+
+ This program is free 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+class spider_group_by_handler: public group_by_handler
+{
+ Query query;
+ spider_fields *fields;
+ ha_spider *spider;
+ SPIDER_TRX *trx;
+ spider_db_result *result;
+ bool first;
+ longlong offset_limit;
+ int store_error;
+
+public:
+ spider_group_by_handler(
+ THD *thd_arg,
+ Query *query_arg,
+ spider_fields *fields_arg
+ );
+ ~spider_group_by_handler();
+ int init_scan();
+ int next_row();
+ int end_scan();
+};
+
+group_by_handler *spider_create_group_by_handler(
+ THD *thd,
+ Query *query
+);
+#endif
diff --git a/storage/spider/spd_i_s.cc b/storage/spider/spd_i_s.cc
index a9bdab638a1..3ef04a0dacc 100644
--- a/storage/spider/spd_i_s.cc
+++ b/storage/spider/spd_i_s.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012-2014 Kentoku Shiba
+/* Copyright (C) 2012-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h
index 37d9db3ba57..e6a2a8ef3b2 100644
--- a/storage/spider/spd_include.h
+++ b/storage/spider/spd_include.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,14 +11,15 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define SPIDER_DETAIL_VERSION "3.2.37"
-#define SPIDER_HEX_VERSION 0x0302
+#define SPIDER_DETAIL_VERSION "3.3.13"
+#define SPIDER_HEX_VERSION 0x0303
#if MYSQL_VERSION_ID < 50500
+#define spider_my_free(A,B) my_free(A,B)
#else
-#define my_free(A,B) my_free(A)
+#define spider_my_free(A,B) my_free(A)
#ifdef pthread_mutex_t
#undef pthread_mutex_t
#endif
@@ -66,6 +67,7 @@
#define my_sprintf(A,B) sprintf B
#endif
+
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100004
#define spider_stmt_da_message(A) thd_get_error_message(A)
#define spider_stmt_da_sql_errno(A) thd_get_error_number(A)
@@ -129,6 +131,55 @@
#define SPIDER_Item_args_arg_count_IS_PROTECTED
#endif
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100112
+#define SPIDER_Item_func_conv_charset_conv_charset collation.collation
+#else
+#define SPIDER_Item_func_conv_charset_conv_charset conv_charset
+#endif
+
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100200
+#define SPIDER_WITHOUT_HA_STATISTIC_INCREMENT
+#define SPIDER_init_read_record(A,B,C,D,E,F,G,H) init_read_record(A,B,C,D,E,F,G,H)
+#define SPIDER_HAS_NEXT_THREAD_ID
+#define SPIDER_new_THD(A) (new THD(A))
+#define SPIDER_order_direction_is_asc(A) (A->direction == ORDER::ORDER_ASC)
+#else
+#define SPIDER_init_read_record(A,B,C,D,E,F,G,H) init_read_record(A,B,C,D,F,G,H)
+#define SPIDER_new_THD(A) (new THD())
+#define SPIDER_order_direction_is_asc(A) (A->asc)
+#endif
+
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100201
+#define SPIDER_HAS_MY_CHARLEN
+#define SPIDER_find_temporary_table(A,B) A->find_temporary_table(B)
+#else
+#define SPIDER_find_temporary_table(A,B) find_temporary_table(A,B)
+#endif
+
+#if defined(MARIADB_BASE_VERSION)
+#if MYSQL_VERSION_ID >= 100209
+#define SPIDER_generate_partition_syntax(A,B,C,D,E,F,G,H) generate_partition_syntax(A,B,C,E,F,G)
+#elif MYSQL_VERSION_ID >= 100200
+#define SPIDER_generate_partition_syntax(A,B,C,D,E,F,G,H) generate_partition_syntax(A,B,C,D,E,F,G,H)
+#elif MYSQL_VERSION_ID >= 100007
+#define SPIDER_generate_partition_syntax(A,B,C,D,E,F,G,H) generate_partition_syntax(B,C,D,E,F,G,H)
+#else
+#define SPIDER_generate_partition_syntax(A,B,C,D,E,F,G,H) generate_partition_syntax(B,C,D,E,F,G)
+#endif
+#else
+#define SPIDER_generate_partition_syntax(A,B,C,D,E,F,G,H)
+#endif
+
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100209
+#define SPIDER_create_partition_name(A,B,C,D,E,F) create_partition_name(A,B,C,D,E,F)
+#define SPIDER_create_subpartition_name(A,B,C,D,E,F) create_subpartition_name(A,B,C,D,E,F)
+#define SPIDER_free_part_syntax(A,B)
+#else
+#define SPIDER_create_partition_name(A,B,C,D,E,F) create_partition_name(A,C,D,E,F)
+#define SPIDER_create_subpartition_name(A,B,C,D,E,F) create_subpartition_name(A,C,D,E,F)
+#define SPIDER_free_part_syntax(A,B) spider_my_free(A,B)
+#endif
+
#if MYSQL_VERSION_ID >= 50500
#define SPIDER_HAS_HASH_VALUE_TYPE
#endif
@@ -151,12 +202,13 @@
#define SPIDER_LINK_MON_DRAW_FEW_MON 1
#define SPIDER_LINK_MON_DRAW 2
-#define SPIDER_TMP_SHARE_CHAR_PTR_COUNT 19
+#define SPIDER_TMP_SHARE_CHAR_PTR_COUNT 20
#define SPIDER_TMP_SHARE_UINT_COUNT 17
-#define SPIDER_TMP_SHARE_LONG_COUNT 18
+#define SPIDER_TMP_SHARE_LONG_COUNT 19
#define SPIDER_TMP_SHARE_LONGLONG_COUNT 3
-#define SPIDER_MEM_CALC_LIST_NUM 247
+#define SPIDER_MEM_CALC_LIST_NUM 257
+#define SPIDER_CONN_META_BUF_LEN 64
#define SPIDER_BACKUP_DASTATUS \
bool da_status; if (thd) da_status = thd->is_error(); else da_status = FALSE;
@@ -176,6 +228,25 @@
class ha_spider;
typedef struct st_spider_share SPIDER_SHARE;
+typedef struct st_spider_table_mon_list SPIDER_TABLE_MON_LIST;
+typedef struct st_spider_ip_port_conn SPIDER_IP_PORT_CONN;
+
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+typedef struct st_spider_thread
+{
+ uint thread_idx;
+ THD *thd;
+ volatile bool killed;
+ volatile bool thd_wait;
+ volatile bool first_free_wait;
+ pthread_t thread;
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+ pthread_cond_t sync_cond;
+ volatile SPIDER_SHARE *queue_first;
+ volatile SPIDER_SHARE *queue_last;
+} SPIDER_THREAD;
+#endif
typedef struct st_spider_file_pos
{
@@ -224,8 +295,10 @@ typedef struct st_spider_alter_table
char **tmp_tgt_ssl_keys;
char **tmp_tgt_default_files;
char **tmp_tgt_default_groups;
+ char **tmp_static_link_ids;
long *tmp_tgt_ports;
long *tmp_tgt_ssl_vscs;
+ long *tmp_monitoring_binlog_pos_at_failing;
long *tmp_link_statuses;
uint *tmp_server_names_lengths;
@@ -243,6 +316,7 @@ typedef struct st_spider_alter_table
uint *tmp_tgt_ssl_keys_lengths;
uint *tmp_tgt_default_files_lengths;
uint *tmp_tgt_default_groups_lengths;
+ uint *tmp_static_link_ids_lengths;
uint tmp_server_names_charlen;
uint tmp_tgt_table_names_charlen;
@@ -259,6 +333,7 @@ typedef struct st_spider_alter_table
uint tmp_tgt_ssl_keys_charlen;
uint tmp_tgt_default_files_charlen;
uint tmp_tgt_default_groups_charlen;
+ uint tmp_static_link_ids_charlen;
uint tmp_server_names_length;
uint tmp_tgt_table_names_length;
@@ -275,8 +350,10 @@ typedef struct st_spider_alter_table
uint tmp_tgt_ssl_keys_length;
uint tmp_tgt_default_files_length;
uint tmp_tgt_default_groups_length;
+ uint tmp_static_link_ids_length;
uint tmp_tgt_ports_length;
uint tmp_tgt_ssl_vscs_length;
+ uint tmp_monitoring_binlog_pos_at_failing_length;
uint tmp_link_statuses_length;
} SPIDER_ALTER_TABLE;
@@ -455,6 +532,12 @@ typedef struct st_spider_conn
THD *connect_error_thd;
query_id_t connect_error_query_id;
time_t connect_error_time;
+
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ SPIDER_CONN_HOLDER *conn_holder_for_direct_join;
+ SPIDER_LINK_IDX_CHAIN *link_idx_chain;
+#endif
+ SPIDER_IP_PORT_CONN *ip_port_conn;
} SPIDER_CONN;
typedef struct st_spider_lgtm_tblhnd_share
@@ -489,6 +572,7 @@ typedef struct st_spider_patition_handler_share
bool between_flg;
bool idx_bitmap_is_set;
bool rnd_bitmap_is_set;
+ query_id_t parallel_search_query_id;
} SPIDER_PARTITION_HANDLER_SHARE;
typedef struct st_spider_patition_share
@@ -544,6 +628,8 @@ typedef struct st_spider_transaction
bool tmp_flg;
bool registed_allocated_thds;
+ bool updated_in_this_trx;
+
THD *thd;
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
my_hash_value_type thd_hash_value;
@@ -608,6 +694,7 @@ typedef struct st_spider_transaction
ulonglong direct_delete_count;
ulonglong direct_order_limit_count;
ulonglong direct_aggregate_count;
+ ulonglong parallel_search_count;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
ulonglong hs_result_free_count;
#endif
@@ -719,6 +806,27 @@ typedef struct st_spider_share
pthread_cond_t *bg_mon_conds;
pthread_cond_t *bg_mon_sleep_conds;
#endif
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ /* static bg thread for sts and crd */
+ TABLE table;
+ ha_spider *sts_spider;
+ ha_spider *crd_spider;
+ SPIDER_THREAD *sts_thread;
+ SPIDER_THREAD *crd_thread;
+ volatile bool sts_spider_init;
+ volatile bool sts_working;
+ volatile bool sts_wait;
+ volatile bool crd_spider_init;
+ volatile bool crd_working;
+ volatile bool crd_wait;
+ volatile SPIDER_SHARE *sts_prev;
+ volatile SPIDER_SHARE *sts_next;
+ volatile SPIDER_SHARE *crd_prev;
+ volatile SPIDER_SHARE *crd_next;
+#endif
+
+ MEM_ROOT mem_root;
+
/*
volatile bool auto_increment_init;
volatile ulonglong auto_increment_lclval;
@@ -755,6 +863,8 @@ typedef struct st_spider_share
#ifdef WITH_PARTITION_STORAGE_ENGINE
int sts_sync;
#endif
+ int store_last_sts;
+ int load_sts_at_startup;
#ifndef WITHOUT_SPIDER_BG_SEARCH
int crd_bg_mode;
#endif
@@ -763,6 +873,8 @@ typedef struct st_spider_share
#ifdef WITH_PARTITION_STORAGE_ENGINE
int crd_sync;
#endif
+ int store_last_crd;
+ int load_crd_at_startup;
int crd_type;
double crd_weight;
longlong internal_offset;
@@ -804,6 +916,7 @@ typedef struct st_spider_share
int use_table_charset;
int use_pushdown_udf;
int skip_default_condition;
+ int skip_parallel_search;
int direct_dup_insert;
longlong direct_order_limit;
int read_only_mode;
@@ -851,6 +964,7 @@ typedef struct st_spider_share
char **tgt_ssl_keys;
char **tgt_default_files;
char **tgt_default_groups;
+ char **static_link_ids;
char **tgt_pk_names;
char **tgt_sequence_names;
char **conn_keys;
@@ -867,6 +981,7 @@ typedef struct st_spider_share
long *monitoring_bg_flag;
long *monitoring_bg_kind;
#endif
+ long *monitoring_binlog_pos_at_failing;
long *monitoring_flag;
long *monitoring_kind;
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -903,6 +1018,7 @@ typedef struct st_spider_share
uint *tgt_ssl_keys_lengths;
uint *tgt_default_files_lengths;
uint *tgt_default_groups_lengths;
+ uint *static_link_ids_lengths;
uint *tgt_pk_names_lengths;
uint *tgt_sequence_names_lengths;
uint *conn_keys_lengths;
@@ -932,6 +1048,7 @@ typedef struct st_spider_share
uint tgt_ssl_keys_charlen;
uint tgt_default_files_charlen;
uint tgt_default_groups_charlen;
+ uint static_link_ids_charlen;
uint tgt_pk_names_charlen;
uint tgt_sequence_names_charlen;
uint conn_keys_charlen;
@@ -957,6 +1074,7 @@ typedef struct st_spider_share
uint tgt_ssl_keys_length;
uint tgt_default_files_length;
uint tgt_default_groups_length;
+ uint static_link_ids_length;
uint tgt_pk_names_length;
uint tgt_sequence_names_length;
uint conn_keys_length;
@@ -973,6 +1091,7 @@ typedef struct st_spider_share
uint monitoring_bg_flag_length;
uint monitoring_bg_kind_length;
#endif
+ uint monitoring_binlog_pos_at_failing_length;
uint monitoring_flag_length;
uint monitoring_kind_length;
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -1143,6 +1262,7 @@ typedef struct st_spider_table_mon
{
SPIDER_SHARE *share;
uint32 server_id;
+ st_spider_table_mon_list *parent;
st_spider_table_mon *next;
} SPIDER_TABLE_MON;
@@ -1276,3 +1396,19 @@ char *spider_create_string(
const char *str,
uint length
);
+
+
+typedef struct st_spider_ip_port_conn {
+ char *key;
+ size_t key_len;
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ my_hash_value_type key_hash_value;
+#endif
+ char remote_ip_str[SPIDER_CONN_META_BUF_LEN];
+ long remote_port;
+ ulong ip_port_count;
+ volatile ulong waiting_count;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ ulonglong conn_id; /* each conn has it's own conn_id */
+} SPIDER_IP_PORT_CONN;
diff --git a/storage/spider/spd_malloc.cc b/storage/spider/spd_malloc.cc
index acf32e48966..e7a6e710cbc 100644
--- a/storage/spider/spd_malloc.cc
+++ b/storage/spider/spd_malloc.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012-2014 Kentoku Shiba
+/* Copyright (C) 2012-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -183,7 +184,7 @@ void spider_free_mem(
size = *((uint *) tmp_ptr);
tmp_ptr -= ALIGN_SIZE(sizeof(uint));
id = *((uint *) tmp_ptr);
- my_free(tmp_ptr, my_flags);
+ spider_my_free(tmp_ptr, my_flags);
spider_free_mem_calc(trx, id, size);
DBUG_VOID_RETURN;
diff --git a/storage/spider/spd_malloc.h b/storage/spider/spd_malloc.h
index 3c5c6e67c2a..42e6abd407c 100644
--- a/storage/spider/spd_malloc.h
+++ b/storage/spider/spd_malloc.h
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define spider_free(A,B,C) spider_free_mem(A,B,C)
#define spider_malloc(A,B,C,D) \
diff --git a/storage/spider/spd_param.cc b/storage/spider/spd_param.cc
index 390dec43a16..6970f19e85f 100644
--- a/storage/spider/spd_param.cc
+++ b/storage/spider/spd_param.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,12 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
-#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -88,6 +88,17 @@ static int spider_direct_aggregate(THD *thd, SHOW_VAR *var, char *buff)
DBUG_RETURN(error_num);
}
+static int spider_parallel_search(THD *thd, SHOW_VAR *var, char *buff)
+{
+ int error_num = 0;
+ SPIDER_TRX *trx;
+ DBUG_ENTER("spider_parallel_search");
+ var->type = SHOW_LONGLONG;
+ if ((trx = spider_get_trx(thd, TRUE, &error_num)))
+ var->value = (char *) &trx->parallel_search_count;
+ DBUG_RETURN(error_num);
+}
+
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
static int spider_hs_result_free(THD *thd, SHOW_VAR *var, char *buff)
{
@@ -121,11 +132,15 @@ struct st_mysql_show_var spider_status_variables[] =
(char *) &spider_direct_order_limit, SHOW_SIMPLE_FUNC},
{"Spider_direct_aggregate",
(char *) &spider_direct_aggregate, SHOW_SIMPLE_FUNC},
+ {"Spider_parallel_search",
+ (char *) &spider_parallel_search, SHOW_SIMPLE_FUNC},
#else
{"Spider_direct_order_limit",
(char *) &spider_direct_order_limit, SHOW_FUNC},
{"Spider_direct_aggregate",
(char *) &spider_direct_aggregate, SHOW_FUNC},
+ {"Spider_parallel_search",
+ (char *) &spider_parallel_search, SHOW_FUNC},
#endif
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
#ifdef SPIDER_HAS_SHOW_SIMPLE_FUNC
@@ -410,6 +425,29 @@ uint spider_param_force_commit(
}
/*
+ 0: register all XA transaction
+ 1: register only write XA transaction
+ */
+static MYSQL_THDVAR_UINT(
+ xa_register_mode, /* name */
+ PLUGIN_VAR_RQCMDARG, /* opt */
+ "Mode of XA transaction register into system table", /* comment */
+ NULL, /* check */
+ NULL, /* update */
+ 1, /* def */
+ 0, /* min */
+ 1, /* max */
+ 0 /* blk */
+);
+
+uint spider_param_xa_register_mode(
+ THD *thd
+) {
+ DBUG_ENTER("spider_param_xa_register_mode");
+ DBUG_RETURN(THDVAR(thd, xa_register_mode));
+}
+
+/*
-1 :use table parameter
0-:offset
*/
@@ -1667,7 +1705,8 @@ double spider_param_crd_weight(
/*
-1 :use table parameter
0 :Background confirmation is disabled
- 1 :Background confirmation is enabled
+ 1 :Background confirmation is enabled (create thread per table/partition)
+ 2 :Background confirmation is enabled (use static threads)
*/
static MYSQL_THDVAR_INT(
crd_bg_mode, /* name */
@@ -1677,7 +1716,7 @@ static MYSQL_THDVAR_INT(
NULL, /* update */
-1, /* def */
-1, /* min */
- 1, /* max */
+ 2, /* max */
0 /* blk */
);
@@ -1778,7 +1817,8 @@ int spider_param_sts_sync(
/*
-1 :use table parameter
0 :Background confirmation is disabled
- 1 :Background confirmation is enabled
+ 1 :Background confirmation is enabled (create thread per table/partition)
+ 2 :Background confirmation is enabled (use static threads)
*/
static MYSQL_THDVAR_INT(
sts_bg_mode, /* name */
@@ -1788,7 +1828,7 @@ static MYSQL_THDVAR_INT(
NULL, /* update */
-1, /* def */
-1, /* min */
- 1, /* max */
+ 2, /* max */
0 /* blk */
);
@@ -2703,6 +2743,34 @@ int spider_param_skip_default_condition(
/*
-1 :use table parameter
+ 0 :not skip
+ 1 :skip parallel search if query is not SELECT statement
+ 2 :skip parallel search if query has SQL_NO_CACHE
+ 3 :1+2
+ */
+static MYSQL_THDVAR_INT(
+ skip_parallel_search, /* name */
+ PLUGIN_VAR_RQCMDARG, /* opt */
+ "Skip parallel search by specific conditions", /* comment */
+ NULL, /* check */
+ NULL, /* update */
+ -1, /* def */
+ -1, /* min */
+ 3, /* max */
+ 0 /* blk */
+);
+
+int spider_param_skip_parallel_search(
+ THD *thd,
+ int skip_parallel_search
+) {
+ DBUG_ENTER("spider_param_skip_parallel_search");
+ DBUG_RETURN(THDVAR(thd, skip_parallel_search) == -1 ?
+ skip_parallel_search : THDVAR(thd, skip_parallel_search));
+}
+
+/*
+ -1 :use table parameter
0 :not send directly
1-:send directly
*/
@@ -2828,6 +2896,66 @@ my_bool spider_param_general_log()
DBUG_RETURN(spider_general_log);
}
+/*
+ FALSE: no pushdown hints
+ TRUE: pushdown hints
+ */
+static MYSQL_THDVAR_BOOL(
+ index_hint_pushdown, /* name */
+ PLUGIN_VAR_OPCMDARG, /* opt */
+ "switch to control if push down index hint, like force_index", /* comment */
+ NULL, /* check */
+ NULL, /* update */
+ FALSE /* def */
+);
+
+my_bool spider_param_index_hint_pushdown(
+ THD *thd
+) {
+ DBUG_ENTER("spider_param_index_hint_pushdown");
+ DBUG_RETURN(THDVAR(thd, index_hint_pushdown));
+}
+
+static uint spider_max_connections;
+static MYSQL_SYSVAR_UINT(
+ max_connections,
+ spider_max_connections,
+ PLUGIN_VAR_RQCMDARG,
+ "the values, as the max conncetion from spider to remote mysql. Default 0, mean unlimit the connections",
+ NULL,
+ NULL,
+ 0, /* def */
+ 0, /* min */
+ 99999, /* max */
+ 0 /* blk */
+);
+
+uint spider_param_max_connections()
+{
+ DBUG_ENTER("spider_param_max_connections");
+ DBUG_RETURN(spider_max_connections);
+}
+
+static uint spider_conn_wait_timeout;
+static MYSQL_SYSVAR_UINT(
+ conn_wait_timeout,
+ spider_conn_wait_timeout,
+ PLUGIN_VAR_RQCMDARG,
+ "the values, as the max waiting time when spider get a remote conn",
+ NULL,
+ NULL,
+ 10, /* def */
+ 0, /* min */
+ 1000, /* max */
+ 0 /* blk */
+);
+
+uint spider_param_conn_wait_timeout()
+{
+ DBUG_ENTER("spider_param_conn_wait_timeout");
+ DBUG_RETURN(spider_conn_wait_timeout);
+}
+
static uint spider_log_result_errors;
/*
0: no log
@@ -3011,6 +3139,162 @@ int spider_param_bka_table_name_type(
bka_table_name_type : THDVAR(thd, bka_table_name_type));
}
+static int spider_store_last_sts;
+/*
+ -1 : use table parameter
+ 0 : do not store
+ 1 : do store
+ */
+static MYSQL_SYSVAR_INT(
+ store_last_sts,
+ spider_store_last_sts,
+ PLUGIN_VAR_RQCMDARG,
+ "Store last sts result into system table",
+ NULL,
+ NULL,
+ -1,
+ -1,
+ 1,
+ 0
+);
+
+int spider_param_store_last_sts(
+ int store_last_sts
+) {
+ DBUG_ENTER("spider_param_store_last_sts");
+ DBUG_RETURN(spider_store_last_sts == -1 ?
+ store_last_sts : spider_store_last_sts);
+}
+
+static int spider_store_last_crd;
+/*
+ -1 : use table parameter
+ 0 : do not store
+ 1 : do store
+ */
+static MYSQL_SYSVAR_INT(
+ store_last_crd,
+ spider_store_last_crd,
+ PLUGIN_VAR_RQCMDARG,
+ "Store last crd result into system table",
+ NULL,
+ NULL,
+ -1,
+ -1,
+ 1,
+ 0
+);
+
+int spider_param_store_last_crd(
+ int store_last_crd
+) {
+ DBUG_ENTER("spider_param_store_last_crd");
+ DBUG_RETURN(spider_store_last_crd == -1 ?
+ store_last_crd : spider_store_last_crd);
+}
+
+static int spider_load_sts_at_startup;
+/*
+ -1 : use table parameter
+ 0 : do not load
+ 1 : do load
+ */
+static MYSQL_SYSVAR_INT(
+ load_sts_at_startup,
+ spider_load_sts_at_startup,
+ PLUGIN_VAR_RQCMDARG,
+ "Load sts from system table at startup",
+ NULL,
+ NULL,
+ -1,
+ -1,
+ 1,
+ 0
+);
+
+int spider_param_load_sts_at_startup(
+ int load_sts_at_startup
+) {
+ DBUG_ENTER("spider_param_load_sts_at_startup");
+ DBUG_RETURN(spider_load_sts_at_startup == -1 ?
+ load_sts_at_startup : spider_load_sts_at_startup);
+}
+
+static int spider_load_crd_at_startup;
+/*
+ -1 : use table parameter
+ 0 : do not load
+ 1 : do load
+ */
+static MYSQL_SYSVAR_INT(
+ load_crd_at_startup,
+ spider_load_crd_at_startup,
+ PLUGIN_VAR_RQCMDARG,
+ "Load crd from system table at startup",
+ NULL,
+ NULL,
+ -1,
+ -1,
+ 1,
+ 0
+);
+
+int spider_param_load_crd_at_startup(
+ int load_crd_at_startup
+) {
+ DBUG_ENTER("spider_param_load_crd_at_startup");
+ DBUG_RETURN(spider_load_crd_at_startup == -1 ?
+ load_crd_at_startup : spider_load_crd_at_startup);
+}
+
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+static uint spider_table_sts_thread_count;
+/*
+ 1-: thread count
+ */
+static MYSQL_SYSVAR_UINT(
+ table_sts_thread_count,
+ spider_table_sts_thread_count,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Static thread count of table sts",
+ NULL,
+ NULL,
+ 10,
+ 1,
+ 4294967295U,
+ 0
+);
+
+uint spider_param_table_sts_thread_count()
+{
+ DBUG_ENTER("spider_param_table_sts_thread_count");
+ DBUG_RETURN(spider_table_sts_thread_count);
+}
+
+static uint spider_table_crd_thread_count;
+/*
+ 1-: thread count
+ */
+static MYSQL_SYSVAR_UINT(
+ table_crd_thread_count,
+ spider_table_crd_thread_count,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Static thread count of table crd",
+ NULL,
+ NULL,
+ 10,
+ 1,
+ 4294967295U,
+ 0
+);
+
+uint spider_param_table_crd_thread_count()
+{
+ DBUG_ENTER("spider_param_table_crd_thread_count");
+ DBUG_RETURN(spider_table_crd_thread_count);
+}
+#endif
+
static struct st_mysql_storage_engine spider_storage_engine =
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
@@ -3025,6 +3309,7 @@ static struct st_mysql_sys_var* spider_system_variables[] = {
MYSQL_SYSVAR(internal_xa),
MYSQL_SYSVAR(internal_xa_snapshot),
MYSQL_SYSVAR(force_commit),
+ MYSQL_SYSVAR(xa_register_mode),
MYSQL_SYSVAR(internal_offset),
MYSQL_SYSVAR(internal_limit),
MYSQL_SYSVAR(split_read),
@@ -3076,6 +3361,8 @@ static struct st_mysql_sys_var* spider_system_variables[] = {
#ifdef WITH_PARTITION_STORAGE_ENGINE
MYSQL_SYSVAR(crd_sync),
#endif
+ MYSQL_SYSVAR(store_last_crd),
+ MYSQL_SYSVAR(load_crd_at_startup),
MYSQL_SYSVAR(crd_type),
MYSQL_SYSVAR(crd_weight),
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -3086,6 +3373,8 @@ static struct st_mysql_sys_var* spider_system_variables[] = {
#ifdef WITH_PARTITION_STORAGE_ENGINE
MYSQL_SYSVAR(sts_sync),
#endif
+ MYSQL_SYSVAR(store_last_sts),
+ MYSQL_SYSVAR(load_sts_at_startup),
#ifndef WITHOUT_SPIDER_BG_SEARCH
MYSQL_SYSVAR(sts_bg_mode),
#endif
@@ -3127,6 +3416,7 @@ static struct st_mysql_sys_var* spider_system_variables[] = {
MYSQL_SYSVAR(error_read_mode),
MYSQL_SYSVAR(error_write_mode),
MYSQL_SYSVAR(skip_default_condition),
+ MYSQL_SYSVAR(skip_parallel_search),
MYSQL_SYSVAR(direct_order_limit),
MYSQL_SYSVAR(read_only_mode),
#ifdef HA_CAN_BULK_ACCESS
@@ -3137,6 +3427,9 @@ static struct st_mysql_sys_var* spider_system_variables[] = {
MYSQL_SYSVAR(udf_ds_use_real_table),
#endif
MYSQL_SYSVAR(general_log),
+ MYSQL_SYSVAR(index_hint_pushdown),
+ MYSQL_SYSVAR(max_connections),
+ MYSQL_SYSVAR(conn_wait_timeout),
MYSQL_SYSVAR(log_result_errors),
MYSQL_SYSVAR(log_result_error_with_sql),
MYSQL_SYSVAR(version),
@@ -3146,6 +3439,10 @@ static struct st_mysql_sys_var* spider_system_variables[] = {
MYSQL_SYSVAR(delete_all_rows_type),
MYSQL_SYSVAR(bka_table_name_type),
MYSQL_SYSVAR(connect_error_interval),
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ MYSQL_SYSVAR(table_sts_thread_count),
+ MYSQL_SYSVAR(table_crd_thread_count),
+#endif
NULL
};
diff --git a/storage/spider/spd_param.h b/storage/spider/spd_param.h
index d62917adb37..d4af48a75ea 100644
--- a/storage/spider/spd_param.h
+++ b/storage/spider/spd_param.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software); you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
my_bool spider_param_support_xa();
my_bool spider_param_connect_mutex();
@@ -41,6 +41,9 @@ uint spider_param_internal_xa_snapshot(
uint spider_param_force_commit(
THD *thd
);
+uint spider_param_xa_register_mode(
+ THD *thd
+);
longlong spider_param_internal_offset(
THD *thd,
longlong internal_offset
@@ -349,6 +352,10 @@ int spider_param_skip_default_condition(
THD *thd,
int skip_default_condition
);
+int spider_param_skip_parallel_search(
+ THD *thd,
+ int skip_parallel_search
+);
longlong spider_param_direct_order_limit(
THD *thd,
longlong direct_order_limit
@@ -370,6 +377,11 @@ int spider_param_udf_ds_use_real_table(
);
#endif
my_bool spider_param_general_log();
+my_bool spider_param_index_hint_pushdown(
+ THD *thd
+);
+uint spider_param_max_connections();
+uint spider_param_conn_wait_timeout();
uint spider_param_log_result_errors();
uint spider_param_log_result_error_with_sql();
uint spider_param_internal_xa_id_type(
@@ -388,3 +400,19 @@ int spider_param_bka_table_name_type(
THD *thd,
int bka_table_name_type
);
+int spider_param_store_last_sts(
+ int store_last_sts
+);
+int spider_param_store_last_crd(
+ int store_last_crd
+);
+int spider_param_load_sts_at_startup(
+ int load_sts_at_startup
+);
+int spider_param_load_crd_at_startup(
+ int load_crd_at_startup
+);
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+uint spider_param_table_sts_thread_count();
+uint spider_param_table_crd_thread_count();
+#endif
diff --git a/storage/spider/spd_ping_table.cc b/storage/spider/spd_ping_table.cc
index a4d731bb0a5..58b44ec202e 100644
--- a/storage/spider/spd_ping_table.cc
+++ b/storage/spider/spd_ping_table.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009-2015 Kentoku Shiba
+/* Copyright (C) 2009-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -81,6 +82,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list(
spider_string *str,
uint conv_name_length,
int link_idx,
+ char *static_link_id,
+ uint static_link_id_length,
uint32 server_id,
bool need_lock,
int *error_num
@@ -139,7 +142,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list(
spider_release_ping_table_mon_list_loop(mutex_hash, table_mon_list);
if (!(table_mon_list = spider_get_ping_table_tgt(thd, str->c_ptr(),
- conv_name_length, link_idx, server_id, str, need_lock, error_num)))
+ conv_name_length, link_idx, static_link_id, static_link_id_length,
+ server_id, str, need_lock, error_num)))
{
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]);
goto error;
@@ -227,14 +231,14 @@ void spider_release_ping_table_mon_list_loop(
DBUG_VOID_RETURN;
}
-void spider_release_ping_table_mon_list(
+int spider_release_ping_table_mon_list(
const char *conv_name,
uint conv_name_length,
int link_idx
) {
uint mutex_hash;
SPIDER_TABLE_MON_LIST *table_mon_list;
- char link_idx_str[SPIDER_SQL_INT_LEN];
+ char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1];
int link_idx_str_length;
DBUG_ENTER("spider_release_ping_table_mon_list");
DBUG_PRINT("info", ("spider conv_name=%s", conv_name));
@@ -242,14 +246,14 @@ void spider_release_ping_table_mon_list(
DBUG_PRINT("info", ("spider link_idx=%d", link_idx));
link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
link_idx));
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_string conv_name_str(conv_name_length + link_idx_str_length + 1);
- conv_name_str.set_charset(system_charset_info);
-#else
- char buf[conv_name_length + link_idx_str_length + 1];
+ char *buf = (char *) my_alloca(conv_name_length + link_idx_str_length + 1);
+ if (!buf)
+ {
+ my_error(HA_ERR_OUT_OF_MEM, MYF(0));
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1,
system_charset_info);
-#endif
conv_name_str.init_calc_mem(134);
conv_name_str.length(0);
conv_name_str.q_append(conv_name, conv_name_length);
@@ -275,7 +279,8 @@ void spider_release_ping_table_mon_list(
#endif
spider_release_ping_table_mon_list_loop(mutex_hash, table_mon_list);
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]);
- DBUG_VOID_RETURN;
+ my_afree(buf);
+ DBUG_RETURN(0);
}
int spider_get_ping_table_mon(
@@ -314,6 +319,28 @@ int spider_get_ping_table_mon(
my_error(error_num, MYF(0));
goto error;
}
+ if (table_mon_list->share->static_link_ids[0])
+ {
+ spider_store_tables_name(table_link_mon, name, name_length);
+ spider_store_tables_link_idx_str(table_link_mon,
+ table_mon_list->share->static_link_ids[0],
+ table_mon_list->share->static_link_ids_lengths[0]);
+ if (!(error_num = spider_ping_table_cache_compare(table_link_mon, mem_root)))
+ goto create_table_mon;
+ if (error_num == HA_ERR_OUT_OF_MEM)
+ goto error;
+ if ((tmp_ptr = strstr(name, "#P#")))
+ {
+ *tmp_ptr = '\0';
+ spider_store_tables_name(table_link_mon, name, strlen(name));
+ *tmp_ptr = '#';
+ if (!(error_num = spider_ping_table_cache_compare(table_link_mon,
+ mem_root)))
+ goto create_table_mon;
+ if (error_num == HA_ERR_OUT_OF_MEM)
+ goto error;
+ }
+ }
spider_store_tables_name(table_link_mon, name, name_length);
spider_store_tables_link_idx(table_link_mon, link_idx);
if (!(error_num = spider_ping_table_cache_compare(table_link_mon, mem_root)))
@@ -363,6 +390,7 @@ create_table_mon:
tmp_connect_info_length, tmp_long, tmp_longlong);
tmp_share->link_statuses[0] = -1;
table_mon->share = tmp_share;
+ table_mon->parent = table_mon_list;
if (table_mon_prev)
table_mon_prev->next = table_mon;
else
@@ -441,6 +469,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt(
char *name,
uint name_length,
int link_idx,
+ char *static_link_id,
+ uint static_link_id_length,
uint32 server_id,
spider_string *str,
bool need_lock,
@@ -497,9 +527,29 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt(
goto error;
}
spider_store_tables_name(table_tables, name, name_length);
- spider_store_tables_link_idx(table_tables, link_idx);
+ if (static_link_id)
+ {
+ spider_store_tables_static_link_id(table_tables,
+ static_link_id, static_link_id_length);
+ if (
+ (*error_num = spider_get_sys_table_by_idx(table_tables, table_key, 2,
+ SPIDER_SYS_TABLES_UIDX1_COL_CNT)) ||
+ (*error_num = spider_get_sys_tables_link_idx(
+ table_tables, &link_idx, &mem_root))
+ ) {
+ table_tables->file->print_error(*error_num, MYF(0));
+ goto error;
+ }
+ } else {
+ spider_store_tables_link_idx(table_tables, link_idx);
+ if (
+ (*error_num = spider_check_sys_table(table_tables, table_key))
+ ) {
+ table_tables->file->print_error(*error_num, MYF(0));
+ goto error;
+ }
+ }
if (
- (*error_num = spider_check_sys_table(table_tables, table_key)) ||
(*error_num = spider_get_sys_tables_connect_info(
table_tables, tmp_share, 0, &mem_root)) ||
(*error_num = spider_get_sys_tables_link_status(
@@ -649,6 +699,165 @@ error:
DBUG_RETURN(NULL);
}
+int spider_get_ping_table_gtid_pos(
+ SPIDER_TRX *trx,
+ THD *thd,
+ spider_string *str,
+ uint conv_name_length,
+ int failed_link_idx,
+ uint32 server_id,
+ bool need_lock,
+ spider_string *tmp_str
+) {
+ int error_num, source_link_idx, need_mon;
+ char table_key[MAX_KEY_LENGTH];
+ TABLE *table_tables, *table_gtid_pos;
+#if MYSQL_VERSION_ID < 50500
+ Open_tables_state open_tables_backup_tables;
+ Open_tables_state open_tables_backup_gtid_pos;
+#else
+ Open_tables_backup open_tables_backup_tables;
+ Open_tables_backup open_tables_backup_gtid_pos;
+#endif
+ MEM_ROOT mem_root;
+ long link_status;
+ long monitoring_binlog_pos_at_failing;
+ SPIDER_TABLE_MON_LIST *table_mon_list;
+ SPIDER_CONN *ping_conn = NULL;
+ char *static_link_id;
+ uint static_link_id_length;
+ DBUG_ENTER("spider_get_ping_table_gtid_pos");
+
+ /*
+ select * from
+ mysql.spider_tables
+ where
+ db_name = setted db_name and
+ table_name = setted table_name
+ */
+ if (
+ !(table_tables = spider_open_sys_table(
+ thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
+ SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup_tables,
+ need_lock, &error_num))
+ )
+ goto error_open_table_tables;
+
+ if (
+ !(table_gtid_pos = spider_open_sys_table(
+ thd, SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR,
+ SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN, TRUE,
+ &open_tables_backup_gtid_pos, need_lock, &error_num))
+ )
+ goto error_open_table_gtid_pos;
+
+ table_tables->use_all_columns();
+ table_gtid_pos->use_all_columns();
+ spider_store_tables_name(table_tables, str->ptr(), conv_name_length);
+ spider_store_tables_name(table_gtid_pos, str->ptr(), conv_name_length);
+ spider_store_binlog_pos_failed_link_idx(table_gtid_pos, failed_link_idx);
+ if ((error_num = spider_get_sys_table_by_idx(table_tables, table_key, 0,
+ SPIDER_SYS_TABLES_PK_COL_CNT - 1)))
+ {
+ if (error_num == HA_ERR_KEY_NOT_FOUND || error_num == HA_ERR_END_OF_FILE)
+ {
+ error_num = 0;
+ }
+ goto error_get_sys_table_by_idx;
+ }
+
+ SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
+ do {
+ if (
+ (error_num = spider_get_sys_tables_link_status(table_tables,
+ &link_status, &mem_root)) ||
+ (error_num = spider_get_sys_tables_static_link_id(table_tables,
+ &static_link_id, &static_link_id_length, &mem_root)) ||
+ (error_num = spider_get_sys_tables_monitoring_binlog_pos_at_failing(
+ table_tables, &monitoring_binlog_pos_at_failing, &mem_root))
+ ) {
+ goto error_get_sys_tables_link_status;
+ }
+
+ if (link_status == 1 && monitoring_binlog_pos_at_failing > 0)
+ {
+ if ((error_num = spider_get_sys_tables_link_idx(table_tables,
+ &source_link_idx, &mem_root)))
+ {
+ goto error_get_sys_tables_link_idx;
+ }
+ if (
+ (table_mon_list = spider_get_ping_table_mon_list(
+ trx,
+ thd,
+ str,
+ conv_name_length,
+ source_link_idx,
+ static_link_id,
+ static_link_id_length,
+ server_id,
+ need_lock,
+ &error_num
+ ))
+ ) {
+ SPIDER_DB_RESULT *res1 = NULL;
+ SPIDER_DB_RESULT *res2 = NULL;
+ if (
+ (ping_conn = spider_get_ping_table_tgt_conn(trx,
+ table_mon_list->share, &error_num
+ )) &&
+ !(error_num = ping_conn->db_conn->show_master_status(
+ trx, table_mon_list->share, 0, &need_mon, table_gtid_pos, tmp_str,
+ monitoring_binlog_pos_at_failing == 1 ? 0 : 1, &res1, &res2))
+ ) {
+ spider_store_binlog_pos_source_link_idx(
+ table_gtid_pos, source_link_idx);
+ spider_insert_sys_table(table_gtid_pos);
+ }
+ if (res1)
+ {
+ res1->free_result();
+ delete res1;
+ }
+ if (res2)
+ {
+ res2->free_result();
+ delete res2;
+ }
+ spider_free_ping_table_mon_list(table_mon_list);
+ }
+ }
+
+ error_num = spider_sys_index_next_same(table_tables, table_key);
+ } while (error_num == 0);
+ free_root(&mem_root, MYF(0));
+
+ if ((error_num = spider_sys_index_end(table_tables)))
+ {
+ goto error_sys_index_end;
+ }
+ spider_close_sys_table(thd, table_gtid_pos, &open_tables_backup_gtid_pos,
+ need_lock);
+ spider_close_sys_table(thd, table_tables, &open_tables_backup_tables,
+ need_lock);
+
+ DBUG_RETURN(0);
+
+error_get_sys_tables_link_idx:
+error_get_sys_tables_link_status:
+ free_root(&mem_root, MYF(0));
+ spider_sys_index_end(table_tables);
+error_sys_index_end:
+error_get_sys_table_by_idx:
+ spider_close_sys_table(thd, table_gtid_pos, &open_tables_backup_gtid_pos,
+ need_lock);
+error_open_table_gtid_pos:
+ spider_close_sys_table(thd, table_tables, &open_tables_backup_tables,
+ need_lock);
+error_open_table_tables:
+ DBUG_RETURN(error_num);
+}
+
int spider_init_ping_table_mon_cache(
THD *thd,
MEM_ROOT *mem_root,
@@ -819,7 +1028,7 @@ long long spider_ping_table_body(
) {
int error_num = 0, link_idx, flags, full_mon_count, current_mon_count,
success_count, fault_count, tmp_error_num = 0;
- uint32 first_sid;
+ uint32 first_sid, server_id;
longlong limit, tmp_sid = -1;
SPIDER_MON_TABLE_RESULT *mon_table_result =
(SPIDER_MON_TABLE_RESULT *) initid->ptr;
@@ -830,15 +1039,24 @@ long long spider_ping_table_body(
SPIDER_TABLE_MON_LIST *table_mon_list;
SPIDER_TABLE_MON *table_mon;
- char buf[MAX_FIELD_WIDTH];
+ char buf[MAX_FIELD_WIDTH], buf2[MAX_FIELD_WIDTH];
spider_string conv_name(buf, sizeof(buf), system_charset_info);
+ spider_string tmp_str(buf2, sizeof(buf2), system_charset_info);
int conv_name_length;
- char link_idx_str[SPIDER_SQL_INT_LEN];
+ char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1];
int link_idx_str_length;
- bool get_lock = FALSE;
+ char *static_link_id = NULL;
+ int static_link_id_length = 0;
+ bool get_lock = FALSE, status_changed_to_ng = FALSE;
DBUG_ENTER("spider_ping_table_body");
conv_name.init_calc_mem(135);
+ tmp_str.init_calc_mem(247);
conv_name.length(0);
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002
+ server_id = global_system_variables.server_id;
+#else
+ server_id = thd->server_id;
+#endif
if (
thd->open_tables != 0 ||
thd->handler_tables_hash.records != 0 ||
@@ -904,26 +1122,52 @@ long long spider_ping_table_body(
if (
args->lengths[0] > SPIDER_CONNECT_INFO_MAX_LEN
) {
- my_printf_error(ER_SPIDER_UDF_PING_TABLE_PARAM_TOO_LONG_NUM,
- ER_SPIDER_UDF_PING_TABLE_PARAM_TOO_LONG_STR, MYF(0));
+ my_printf_error(ER_SPIDER_UDF_PARAM_TOO_LONG_NUM,
+ ER_SPIDER_UDF_PARAM_TOO_LONG_STR, MYF(0), "table name");
goto error;
}
if (
args->lengths[0] == 0
) {
- my_printf_error(ER_SPIDER_UDF_PING_TABLE_PARAM_REQIRED_NUM,
- ER_SPIDER_UDF_PING_TABLE_PARAM_REQIRED_STR, MYF(0));
+ my_printf_error(ER_SPIDER_UDF_PARAM_REQIRED_NUM,
+ ER_SPIDER_UDF_PARAM_REQIRED_STR, MYF(0), "table name");
goto error;
}
-
- link_idx = (int) (args->args[1] ? *((longlong *) args->args[1]) : 0);
+ if (args->arg_type[1] == STRING_RESULT)
+ {
+ if (
+ !args->args[1]
+ ) {
+ my_printf_error(ER_SPIDER_UDF_PARAM_REQIRED_NUM,
+ ER_SPIDER_UDF_PARAM_REQIRED_STR, MYF(0), "link id");
+ goto error;
+ }
+ if (
+ args->lengths[1] > SPIDER_CONNECT_INFO_MAX_LEN
+ ) {
+ my_printf_error(ER_SPIDER_UDF_PARAM_TOO_LONG_NUM,
+ ER_SPIDER_UDF_PARAM_TOO_LONG_STR, MYF(0), "link id");
+ goto error;
+ }
+ link_idx_str_length = args->lengths[1];
+ memcpy(link_idx_str, args->args[1], link_idx_str_length + 1);
+ if (link_idx_str[0] >= '0' && link_idx_str[0] <= '9')
+ {
+ link_idx = atoi(link_idx_str);
+ } else {
+ link_idx = -1;
+ static_link_id = link_idx_str;
+ static_link_id_length = link_idx_str_length;
+ }
+ } else {
+ link_idx = (int) (args->args[1] ? *((longlong *) args->args[1]) : 0);
+ link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
+ link_idx));
+ }
flags = (int) (args->args[2] ? *((longlong *) args->args[2]) : 0);
limit = args->args[3] ? *((longlong *) args->args[3]) : 0;
where_clause = args->args[4] ? args->args[4] : (char *) "";
- link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
- link_idx));
-
if (conv_name.append(args->args[0], args->lengths[0],
trx->thd->variables.character_set_client))
{
@@ -939,14 +1183,10 @@ long long spider_ping_table_body(
conv_name.q_append(link_idx_str, link_idx_str_length + 1);
conv_name.length(conv_name.length() - 1);
-#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002
if (!(table_mon_list = spider_get_ping_table_mon_list(trx, trx->thd,
- &conv_name, conv_name_length, link_idx, global_system_variables.server_id,
- TRUE, &error_num)))
-#else
- if (!(table_mon_list = spider_get_ping_table_mon_list(trx, trx->thd,
- &conv_name, conv_name_length, link_idx, thd->server_id, TRUE, &error_num)))
-#endif
+ &conv_name, conv_name_length, link_idx,
+ static_link_id, static_link_id_length,
+ server_id, TRUE, &error_num)))
goto error;
if (table_mon_list->mon_status == SPIDER_LINK_MON_NG)
@@ -973,11 +1213,7 @@ long long spider_ping_table_body(
goto error_with_free_table_mon_list;
}
} else {
-#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002
- first_sid = global_system_variables.server_id;
-#else
- first_sid = thd->server_id;
-#endif
+ first_sid = server_id;
full_mon_count = table_mon_list->list_size;
current_mon_count = 1;
}
@@ -1039,11 +1275,21 @@ long long spider_ping_table_body(
SPIDER_LINK_STATUS_NG, TRUE);
spider_sys_log_tables_link_failed(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx, TRUE);
+ status_changed_to_ng = TRUE;
}
/*
pthread_mutex_unlock(&table_mon_list->update_status_mutex);
*/
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
+ if (status_changed_to_ng)
+ {
+ bool is_error = trx->thd->is_error();
+ spider_get_ping_table_gtid_pos(trx, trx->thd,
+ &conv_name, conv_name_length, link_idx, server_id, TRUE,
+ &tmp_str);
+ if (!is_error && trx->thd->is_error())
+ trx->thd->clear_error();
+ }
}
goto end;
}
@@ -1102,11 +1348,21 @@ long long spider_ping_table_body(
SPIDER_LINK_STATUS_NG, TRUE);
spider_sys_log_tables_link_failed(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx, TRUE);
+ status_changed_to_ng = TRUE;
}
/*
pthread_mutex_unlock(&table_mon_list->update_status_mutex);
*/
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
+ if (status_changed_to_ng)
+ {
+ bool is_error = trx->thd->is_error();
+ spider_get_ping_table_gtid_pos(trx, trx->thd,
+ &conv_name, conv_name_length, link_idx, server_id, TRUE,
+ &tmp_str);
+ if (!is_error && trx->thd->is_error())
+ trx->thd->clear_error();
+ }
}
} else if (
(flags & SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES) &&
@@ -1155,11 +1411,21 @@ long long spider_ping_table_body(
SPIDER_LINK_STATUS_NG, TRUE);
spider_sys_log_tables_link_failed(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx, TRUE);
+ status_changed_to_ng = TRUE;
}
/*
pthread_mutex_unlock(&table_mon_list->update_status_mutex);
*/
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
+ if (status_changed_to_ng)
+ {
+ bool is_error = trx->thd->is_error();
+ spider_get_ping_table_gtid_pos(trx, trx->thd,
+ &conv_name, conv_name_length, link_idx, server_id, TRUE,
+ &tmp_str);
+ if (!is_error && trx->thd->is_error())
+ trx->thd->clear_error();
+ }
}
table_mon_list->last_receptor_result =
mon_table_result->result_status;
@@ -1215,7 +1481,6 @@ my_bool spider_ping_table_init_body(
goto error;
}
if (
- args->arg_type[1] != INT_RESULT ||
args->arg_type[2] != INT_RESULT ||
args->arg_type[3] != INT_RESULT ||
args->arg_type[5] != INT_RESULT ||
@@ -1224,10 +1489,18 @@ my_bool spider_ping_table_init_body(
args->arg_type[8] != INT_RESULT ||
args->arg_type[9] != INT_RESULT
) {
- strcpy(message, "spider_ping_table() requires integer 2nd, 3rd, 4,6,7,8,"
+ strcpy(message, "spider_ping_table() requires integer 3rd, 4,6,7,8,"
"9th and 10th argument");
goto error;
}
+ if (
+ args->arg_type[1] != INT_RESULT &&
+ args->arg_type[1] != STRING_RESULT
+ ) {
+ strcpy(message, "spider_ping_table() requires string or integer for "
+ "2nd argument");
+ goto error;
+ }
if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
{
@@ -1311,6 +1584,7 @@ int spider_ping_table_mon_from_table(
SPIDER_TRX *trx,
THD *thd,
SPIDER_SHARE *share,
+ int base_link_idx,
uint32 server_id,
char *conv_name,
uint conv_name_length,
@@ -1332,7 +1606,7 @@ int spider_ping_table_mon_from_table(
SPIDER_MON_TABLE_RESULT mon_table_result;
SPIDER_CONN *mon_conn;
TABLE_SHARE *table_share = share->table_share;
- char link_idx_str[SPIDER_SQL_INT_LEN];
+ char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1];
int link_idx_str_length;
uint sql_command = thd_sql_command(thd);
DBUG_ENTER("spider_ping_table_mon_from_table");
@@ -1361,19 +1635,24 @@ int spider_ping_table_mon_from_table(
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
}
- link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
- link_idx));
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_string conv_name_str(conv_name_length + link_idx_str_length + 1);
- conv_name_str.set_charset(system_charset_info);
- *((char *)(conv_name_str.ptr() + conv_name_length + link_idx_str_length)) =
- '\0';
-#else
- char buf[conv_name_length + link_idx_str_length + 1];
+ if (share->static_link_ids[link_idx])
+ {
+ memcpy(link_idx_str, share->static_link_ids[link_idx],
+ share->static_link_ids_lengths[link_idx] + 1);
+ link_idx_str_length = share->static_link_ids_lengths[link_idx];
+ } else {
+ link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
+ link_idx));
+ }
+ char *buf = (char *) my_alloca(conv_name_length + link_idx_str_length + 1);
+ if (!buf)
+ {
+ my_error(HA_ERR_OUT_OF_MEM, MYF(0));
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
buf[conv_name_length + link_idx_str_length] = '\0';
spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1,
system_charset_info);
-#endif
conv_name_str.init_calc_mem(136);
conv_name_str.length(0);
conv_name_str.q_append(conv_name, conv_name_length);
@@ -1391,9 +1670,14 @@ int spider_ping_table_mon_from_table(
flags |= SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES;
if (!(table_mon_list = spider_get_ping_table_mon_list(trx, thd,
- &conv_name_str, conv_name_length, link_idx, server_id, need_lock,
- &error_num)))
+ &conv_name_str, conv_name_length, link_idx,
+ share->static_link_ids[link_idx],
+ share->static_link_ids_lengths[link_idx],
+ server_id, need_lock, &error_num)))
+ {
+ my_afree(buf);
goto end;
+ }
if (table_mon_list->mon_status == SPIDER_LINK_MON_NG)
{
@@ -1407,6 +1691,7 @@ int spider_ping_table_mon_from_table(
ER_SPIDER_LINK_MON_NG_STR, MYF(0),
table_mon_list->share->tgt_dbs[0],
table_mon_list->share->tgt_table_names[0]);
+ my_afree(buf);
goto end_with_free_table_mon_list;
}
@@ -1579,6 +1864,7 @@ int spider_ping_table_mon_from_table(
pthread_mutex_unlock(&table_mon_list->caller_mutex);
}
+ my_afree(buf);
end_with_free_table_mon_list:
spider_free_ping_table_mon_list(table_mon_list);
end:
diff --git a/storage/spider/spd_ping_table.h b/storage/spider/spd_ping_table.h
index 8d12010e524..24d477996db 100644
--- a/storage/spider/spd_ping_table.h
+++ b/storage/spider/spd_ping_table.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009-2014 Kentoku Shiba
+/* Copyright (C) 2009-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list(
SPIDER_TRX *trx,
@@ -19,6 +19,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list(
spider_string *str,
uint conv_name_length,
int link_idx,
+ char *static_link_id,
+ uint static_link_id_length,
uint32 server_id,
bool need_lock,
int *error_num
@@ -33,7 +35,7 @@ void spider_release_ping_table_mon_list_loop(
SPIDER_TABLE_MON_LIST *table_mon_list
);
-void spider_release_ping_table_mon_list(
+int spider_release_ping_table_mon_list(
const char *conv_name,
uint conv_name_length,
int link_idx
@@ -55,6 +57,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt(
char *name,
uint name_length,
int link_idx,
+ char *static_link_id,
+ uint static_link_id_length,
uint32 server_id,
spider_string *str,
bool need_lock,
@@ -67,6 +71,17 @@ SPIDER_CONN *spider_get_ping_table_tgt_conn(
int *error_num
);
+int spider_get_ping_table_gtid_pos(
+ SPIDER_TRX *trx,
+ THD *thd,
+ spider_string *str,
+ uint conv_name_length,
+ int failed_link_idx,
+ uint32 server_id,
+ bool need_lock,
+ spider_string *tmp_str
+);
+
int spider_init_ping_table_mon_cache(
THD *thd,
MEM_ROOT *mem_root,
@@ -90,6 +105,7 @@ int spider_ping_table_mon_from_table(
SPIDER_TRX *trx,
THD *thd,
SPIDER_SHARE *share,
+ int base_link_idx,
uint32 server_id,
char *conv_name,
uint conv_name_length,
diff --git a/storage/spider/spd_sys_table.cc b/storage/spider/spd_sys_table.cc
index 54af725bb64..ae64da1c29f 100644
--- a/storage/spider/spd_sys_table.cc
+++ b/storage/spider/spd_sys_table.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -25,6 +26,7 @@
#include "sql_class.h"
#include "key.h"
#include "sql_base.h"
+#include "tztime.h"
#endif
#include "sql_select.h"
#include "spd_err.h"
@@ -35,6 +37,8 @@
#include "spd_malloc.h"
extern handlerton *spider_hton_ptr;
+extern Time_zone *spd_tz_system;
+static const LEX_CSTRING empty_clex_string= {"", 0};
#if MYSQL_VERSION_ID < 50500
TABLE *spider_open_sys_table(
@@ -75,9 +79,9 @@ TABLE *spider_open_sys_table(
tables.table_name_length = table_name_length;
tables.lock_type = (write ? TL_WRITE : TL_READ);
#else
- tables.init_one_table(
- "mysql", sizeof("mysql") - 1, table_name, table_name_length, table_name,
- (write ? TL_WRITE : TL_READ));
+ LEX_CSTRING db_name= { "mysql", sizeof("mysql") - 1 };
+ LEX_CSTRING tbl_name= { table_name, (size_t) table_name_length };
+ tables.init_one_table( &db_name, &tbl_name, 0, (write ? TL_WRITE : TL_READ));
#endif
#if MYSQL_VERSION_ID < 50500
@@ -192,6 +196,22 @@ TABLE *spider_open_sys_table(
*error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM;
goto error_col_num_chk;
}
+ } else if (table_name_length == SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN)
+ {
+ if (
+ !memcmp(table_name,
+ SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR,
+ SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN) &&
+ table->s->fields != SPIDER_SYS_POS_FOR_RECOVERY_TABLE_COL_CNT
+ ) {
+ spider_close_sys_table(thd, table, open_tables_backup, need_lock);
+ table = NULL;
+ my_printf_error(ER_SPIDER_SYS_TABLE_VERSION_NUM,
+ ER_SPIDER_SYS_TABLE_VERSION_STR, MYF(0),
+ SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR);
+ *error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM;
+ goto error_col_num_chk;
+ }
}
DBUG_RETURN(table);
@@ -228,8 +248,7 @@ void spider_close_sys_table(
close_performance_schema_table(thd, open_tables_backup);
} else {
table->file->ha_reset();
- closefrm(table);
- tdc_release_share(table->s);
+ closefrm(table, TRUE);
spider_free(spider_current_trx, table, MYF(0));
thd->restore_backup_open_tables_state(open_tables_backup);
}
@@ -372,6 +391,29 @@ int spider_check_sys_table_with_find_flag(
#endif
}
+int spider_check_sys_table_for_update_all_columns(
+ TABLE *table,
+ char *table_key
+) {
+ DBUG_ENTER("spider_check_sys_table_for_update_all_columns");
+
+ key_copy(
+ (uchar *) table_key,
+ table->record[0],
+ table->key_info,
+ table->key_info->key_length);
+
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 50200
+ DBUG_RETURN(table->file->ha_index_read_idx_map(
+ table->record[1], 0, (uchar *) table_key,
+ HA_WHOLE_KEY, HA_READ_KEY_EXACT));
+#else
+ DBUG_RETURN(table->file->index_read_idx_map(
+ table->record[1], 0, (uchar *) table_key,
+ HA_WHOLE_KEY, HA_READ_KEY_EXACT));
+#endif
+}
+
int spider_get_sys_table_by_idx(
TABLE *table,
char *table_key,
@@ -684,7 +726,7 @@ void spider_store_tables_name(
table->field[0]->null_bit));
table->field[1]->store(
ptr_table,
- (uint)(name_length - ptr_diff_db - ptr_diff_table),
+ (uint) ((my_ptrdiff_t) name_length - ptr_diff_db - ptr_diff_table),
system_charset_info);
DBUG_PRINT("info",("spider field[1]->null_bit = %d",
table->field[1]->null_bit));
@@ -739,6 +781,26 @@ void spider_store_tables_link_idx_str(
DBUG_VOID_RETURN;
}
+void spider_store_tables_static_link_id(
+ TABLE *table,
+ const char *static_link_id,
+ const uint static_link_id_length
+) {
+ DBUG_ENTER("spider_store_tables_static_link_id");
+ if (static_link_id)
+ {
+ table->field[24]->set_notnull();
+ table->field[24]->store(
+ static_link_id,
+ static_link_id_length,
+ system_charset_info);
+ } else {
+ table->field[24]->set_null();
+ table->field[24]->reset();
+ }
+ DBUG_VOID_RETURN;
+}
+
void spider_store_tables_priority(
TABLE *table,
longlong priority
@@ -894,50 +956,73 @@ void spider_store_tables_connect_info(
table->field[16]->set_null();
table->field[16]->reset();
}
- if (alter_table->tmp_tgt_default_files[link_idx])
+ table->field[17]->set_notnull();
+ if (alter_table->tmp_monitoring_binlog_pos_at_failing[link_idx] >= 0)
{
- table->field[17]->set_notnull();
table->field[17]->store(
- alter_table->tmp_tgt_default_files[link_idx],
- (uint) alter_table->tmp_tgt_default_files_lengths[link_idx],
- system_charset_info);
+ alter_table->tmp_monitoring_binlog_pos_at_failing[link_idx]);
} else {
- table->field[17]->set_null();
- table->field[17]->reset();
+ table->field[17]->store(0);
}
- if (alter_table->tmp_tgt_default_groups[link_idx])
+ if (alter_table->tmp_tgt_default_files[link_idx])
{
table->field[18]->set_notnull();
table->field[18]->store(
- alter_table->tmp_tgt_default_groups[link_idx],
- (uint) alter_table->tmp_tgt_default_groups_lengths[link_idx],
+ alter_table->tmp_tgt_default_files[link_idx],
+ (uint) alter_table->tmp_tgt_default_files_lengths[link_idx],
system_charset_info);
} else {
table->field[18]->set_null();
table->field[18]->reset();
}
- if (alter_table->tmp_tgt_dbs[link_idx])
+ if (alter_table->tmp_tgt_default_groups[link_idx])
{
table->field[19]->set_notnull();
table->field[19]->store(
- alter_table->tmp_tgt_dbs[link_idx],
- (uint) alter_table->tmp_tgt_dbs_lengths[link_idx],
+ alter_table->tmp_tgt_default_groups[link_idx],
+ (uint) alter_table->tmp_tgt_default_groups_lengths[link_idx],
system_charset_info);
} else {
table->field[19]->set_null();
table->field[19]->reset();
}
- if (alter_table->tmp_tgt_table_names[link_idx])
+ if (alter_table->tmp_tgt_dbs[link_idx])
{
table->field[20]->set_notnull();
table->field[20]->store(
- alter_table->tmp_tgt_table_names[link_idx],
- (uint) alter_table->tmp_tgt_table_names_lengths[link_idx],
+ alter_table->tmp_tgt_dbs[link_idx],
+ (uint) alter_table->tmp_tgt_dbs_lengths[link_idx],
system_charset_info);
} else {
table->field[20]->set_null();
table->field[20]->reset();
}
+ if (alter_table->tmp_tgt_table_names[link_idx])
+ {
+ table->field[21]->set_notnull();
+ table->field[21]->store(
+ alter_table->tmp_tgt_table_names[link_idx],
+ (uint) alter_table->tmp_tgt_table_names_lengths[link_idx],
+ system_charset_info);
+ } else {
+ table->field[21]->set_null();
+ table->field[21]->reset();
+ }
+ table->field[23]->store((longlong) 0, FALSE);
+ if (alter_table->tmp_static_link_ids[link_idx])
+ {
+ DBUG_PRINT("info",("spider static_link_id[%d] = %s",
+ link_idx, alter_table->tmp_static_link_ids[link_idx]));
+ table->field[24]->set_notnull();
+ table->field[24]->store(
+ alter_table->tmp_static_link_ids[link_idx],
+ (uint) alter_table->tmp_static_link_ids_lengths[link_idx],
+ system_charset_info);
+ } else {
+ DBUG_PRINT("info",("spider static_link_id[%d] = NULL", link_idx));
+ table->field[24]->set_null();
+ table->field[24]->reset();
+ }
DBUG_VOID_RETURN;
}
@@ -948,7 +1033,7 @@ void spider_store_tables_link_status(
DBUG_ENTER("spider_store_tables_link_status");
DBUG_PRINT("info",("spider link_status = %ld", link_status));
if (link_status > SPIDER_LINK_STATUS_NO_CHANGE)
- table->field[21]->store(link_status, FALSE);
+ table->field[22]->store(link_status, FALSE);
DBUG_VOID_RETURN;
}
@@ -962,6 +1047,116 @@ void spider_store_link_chk_server_id(
DBUG_VOID_RETURN;
}
+void spider_store_binlog_pos_failed_link_idx(
+ TABLE *table,
+ int failed_link_idx
+) {
+ DBUG_ENTER("spider_store_binlog_pos_failed_link_idx");
+ table->field[2]->set_notnull();
+ table->field[2]->store(failed_link_idx);
+ DBUG_VOID_RETURN;
+}
+
+void spider_store_binlog_pos_source_link_idx(
+ TABLE *table,
+ int source_link_idx
+) {
+ DBUG_ENTER("spider_store_binlog_pos_source_link_idx");
+ table->field[3]->set_notnull();
+ table->field[3]->store(source_link_idx);
+ DBUG_VOID_RETURN;
+}
+
+void spider_store_binlog_pos_binlog_file(
+ TABLE *table,
+ const char *file_name,
+ int file_name_length,
+ const char *position,
+ int position_length,
+ CHARSET_INFO *binlog_pos_cs
+) {
+ DBUG_ENTER("spider_store_binlog_pos_binlog_file");
+ if (!file_name)
+ {
+ DBUG_PRINT("info",("spider file_name is NULL"));
+ table->field[4]->set_null();
+ table->field[4]->reset();
+ } else {
+ DBUG_PRINT("info",("spider file_name = %s", file_name));
+ table->field[4]->set_notnull();
+ table->field[4]->store(file_name, file_name_length, binlog_pos_cs);
+ }
+ if (!position)
+ {
+ DBUG_PRINT("info",("spider position is NULL"));
+ table->field[5]->set_null();
+ table->field[5]->reset();
+ } else {
+ DBUG_PRINT("info",("spider position = %s", position));
+ table->field[5]->set_notnull();
+ table->field[5]->store(position, position_length, binlog_pos_cs);
+ }
+ DBUG_VOID_RETURN;
+}
+
+void spider_store_binlog_pos_gtid(
+ TABLE *table,
+ const char *gtid,
+ int gtid_length,
+ CHARSET_INFO *binlog_pos_cs
+) {
+ DBUG_ENTER("spider_store_binlog_pos_gtid");
+ if (!gtid)
+ {
+ DBUG_PRINT("info",("spider gtid is NULL"));
+ table->field[6]->set_null();
+ table->field[6]->reset();
+ } else {
+ DBUG_PRINT("info",("spider gtid = %s", gtid));
+ table->field[6]->set_notnull();
+ table->field[6]->store(gtid, gtid_length, binlog_pos_cs);
+ }
+ DBUG_VOID_RETURN;
+}
+
+void spider_store_table_sts_info(
+ TABLE *table,
+ ulonglong *data_file_length,
+ ulonglong *max_data_file_length,
+ ulonglong *index_file_length,
+ ha_rows *records,
+ ulong *mean_rec_length,
+ time_t *check_time,
+ time_t *create_time,
+ time_t *update_time
+) {
+ MYSQL_TIME mysql_time;
+ DBUG_ENTER("spider_store_table_sts_info");
+ table->field[2]->store((longlong) *data_file_length, TRUE);
+ table->field[3]->store((longlong) *max_data_file_length, TRUE);
+ table->field[4]->store((longlong) *index_file_length, TRUE);
+ table->field[5]->store((longlong) *records, TRUE);
+ table->field[6]->store((longlong) *mean_rec_length, TRUE);
+ spd_tz_system->gmt_sec_to_TIME(&mysql_time, (my_time_t) *check_time);
+ table->field[7]->store_time(&mysql_time);
+ spd_tz_system->gmt_sec_to_TIME(&mysql_time, (my_time_t) *create_time);
+ table->field[8]->store_time(&mysql_time);
+ spd_tz_system->gmt_sec_to_TIME(&mysql_time, (my_time_t) *update_time);
+ table->field[9]->store_time(&mysql_time);
+ DBUG_VOID_RETURN;
+}
+
+void spider_store_table_crd_info(
+ TABLE *table,
+ uint *seq,
+ longlong *cardinality
+) {
+ DBUG_ENTER("spider_store_table_crd_info");
+ table->field[2]->store((longlong) *seq, TRUE);
+ table->field[3]->store((longlong) *cardinality, FALSE);
+ DBUG_VOID_RETURN;
+}
+
int spider_insert_xa(
TABLE *table,
XID *xid,
@@ -1062,6 +1257,114 @@ int spider_insert_tables(
DBUG_RETURN(0);
}
+int spider_insert_sys_table(
+ TABLE *table
+) {
+ int error_num;
+ DBUG_ENTER("spider_insert_sys_table");
+ if ((error_num = table->file->ha_write_row(table->record[0])))
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ DBUG_RETURN(0);
+}
+
+int spider_insert_or_update_table_sts(
+ TABLE *table,
+ const char *name,
+ uint name_length,
+ ulonglong *data_file_length,
+ ulonglong *max_data_file_length,
+ ulonglong *index_file_length,
+ ha_rows *records,
+ ulong *mean_rec_length,
+ time_t *check_time,
+ time_t *create_time,
+ time_t *update_time
+) {
+ int error_num;
+ char table_key[MAX_KEY_LENGTH];
+ DBUG_ENTER("spider_insert_or_update_table_sts");
+ table->use_all_columns();
+ spider_store_tables_name(table, name, name_length);
+ spider_store_table_sts_info(
+ table,
+ data_file_length,
+ max_data_file_length,
+ index_file_length,
+ records,
+ mean_rec_length,
+ check_time,
+ create_time,
+ update_time
+ );
+
+ if ((error_num = spider_check_sys_table_for_update_all_columns(table, table_key)))
+ {
+ if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ if ((error_num = table->file->ha_write_row(table->record[0])))
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ } else {
+ if ((error_num = table->file->ha_update_row(table->record[1],
+ table->record[0])))
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ }
+
+ DBUG_RETURN(0);
+}
+
+int spider_insert_or_update_table_crd(
+ TABLE *table,
+ const char *name,
+ uint name_length,
+ longlong *cardinality,
+ uint number_of_keys
+) {
+ int error_num;
+ uint roop_count;
+ char table_key[MAX_KEY_LENGTH];
+ DBUG_ENTER("spider_insert_or_update_table_crd");
+ table->use_all_columns();
+ spider_store_tables_name(table, name, name_length);
+
+ for (roop_count = 0; roop_count < number_of_keys; ++roop_count)
+ {
+ spider_store_table_crd_info(table, &roop_count, &cardinality[roop_count]);
+ if ((error_num = spider_check_sys_table_for_update_all_columns(table, table_key)))
+ {
+ if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ if ((error_num = table->file->ha_write_row(table->record[0])))
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ } else {
+ if ((error_num = table->file->ha_update_row(table->record[1],
+ table->record[0])))
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ }
+ }
+ DBUG_RETURN(0);
+}
+
int spider_log_tables_link_failed(
TABLE *table,
char *name,
@@ -1438,6 +1741,78 @@ int spider_delete_tables(
DBUG_RETURN(0);
}
+int spider_delete_table_sts(
+ TABLE *table,
+ const char *name,
+ uint name_length
+) {
+ int error_num;
+ char table_key[MAX_KEY_LENGTH];
+ DBUG_ENTER("spider_delete_table_sts");
+ table->use_all_columns();
+ spider_store_tables_name(table, name, name_length);
+
+ if ((error_num = spider_check_sys_table(table, table_key)))
+ {
+ if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ /* no record is ok */
+ DBUG_RETURN(0);
+ } else {
+ if ((error_num = table->file->ha_delete_row(table->record[0])))
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ }
+
+ DBUG_RETURN(0);
+}
+
+int spider_delete_table_crd(
+ TABLE *table,
+ const char *name,
+ uint name_length
+) {
+ int error_num;
+ char table_key[MAX_KEY_LENGTH];
+ DBUG_ENTER("spider_delete_table_crd");
+ table->use_all_columns();
+ spider_store_tables_name(table, name, name_length);
+
+ if ((error_num = spider_get_sys_table_by_idx(table, table_key, 0,
+ SPIDER_SYS_TABLE_CRD_PK_COL_CNT - 1)))
+ {
+ if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ /* no record is ok */
+ DBUG_RETURN(0);
+ } else {
+ do {
+ if ((error_num = table->file->ha_delete_row(table->record[0])))
+ {
+ spider_sys_index_end(table);
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+ error_num = spider_sys_index_next_same(table, table_key);
+ } while (error_num == 0);
+ }
+ if ((error_num = spider_sys_index_end(table)))
+ {
+ table->file->print_error(error_num, MYF(0));
+ DBUG_RETURN(error_num);
+ }
+
+ DBUG_RETURN(0);
+}
+
int spider_get_sys_xid(
TABLE *table,
XID *xid,
@@ -1820,6 +2195,13 @@ int spider_get_sys_tables_connect_info(
!table->field[17]->is_null() &&
(ptr = get_field(mem_root, table->field[17]))
) {
+ share->monitoring_binlog_pos_at_failing[link_idx] = atol(ptr);
+ } else
+ share->monitoring_binlog_pos_at_failing[link_idx] = 0;
+ if (
+ !table->field[18]->is_null() &&
+ (ptr = get_field(mem_root, table->field[18]))
+ ) {
share->tgt_default_files_lengths[link_idx] = strlen(ptr);
share->tgt_default_files[link_idx] =
spider_create_string(ptr, share->tgt_default_files_lengths[link_idx]);
@@ -1828,8 +2210,8 @@ int spider_get_sys_tables_connect_info(
share->tgt_default_files[link_idx] = NULL;
}
if (
- !table->field[18]->is_null() &&
- (ptr = get_field(mem_root, table->field[18]))
+ !table->field[19]->is_null() &&
+ (ptr = get_field(mem_root, table->field[19]))
) {
share->tgt_default_groups_lengths[link_idx] = strlen(ptr);
share->tgt_default_groups[link_idx] =
@@ -1839,8 +2221,8 @@ int spider_get_sys_tables_connect_info(
share->tgt_default_groups[link_idx] = NULL;
}
if (
- !table->field[19]->is_null() &&
- (ptr = get_field(mem_root, table->field[19]))
+ !table->field[20]->is_null() &&
+ (ptr = get_field(mem_root, table->field[20]))
) {
share->tgt_dbs_lengths[link_idx] = strlen(ptr);
share->tgt_dbs[link_idx] =
@@ -1850,8 +2232,8 @@ int spider_get_sys_tables_connect_info(
share->tgt_dbs[link_idx] = NULL;
}
if (
- !table->field[20]->is_null() &&
- (ptr = get_field(mem_root, table->field[20]))
+ !table->field[21]->is_null() &&
+ (ptr = get_field(mem_root, table->field[21]))
) {
share->tgt_table_names_lengths[link_idx] = strlen(ptr);
share->tgt_table_names[link_idx] =
@@ -1860,6 +2242,35 @@ int spider_get_sys_tables_connect_info(
share->tgt_table_names_lengths[link_idx] = 0;
share->tgt_table_names[link_idx] = NULL;
}
+ if (
+ !table->field[24]->is_null() &&
+ (ptr = get_field(mem_root, table->field[24]))
+ ) {
+ share->static_link_ids_lengths[link_idx] = strlen(ptr);
+ share->static_link_ids[link_idx] =
+ spider_create_string(ptr, share->static_link_ids_lengths[link_idx]);
+ } else {
+ share->static_link_ids_lengths[link_idx] = 0;
+ share->static_link_ids[link_idx] = NULL;
+ }
+ DBUG_RETURN(error_num);
+}
+
+int spider_get_sys_tables_monitoring_binlog_pos_at_failing(
+ TABLE *table,
+ long *monitoring_binlog_pos_at_failing,
+ MEM_ROOT *mem_root
+) {
+ char *ptr;
+ int error_num = 0;
+ DBUG_ENTER("spider_get_sys_tables_monitoring_binlog_pos_at_failing");
+ if ((ptr = get_field(mem_root, table->field[17])))
+ *monitoring_binlog_pos_at_failing = (long) my_strtoll10(ptr, (char**) NULL,
+ &error_num);
+ else
+ *monitoring_binlog_pos_at_failing = 1;
+ DBUG_PRINT("info",("spider monitoring_binlog_pos_at_failing=%ld",
+ *monitoring_binlog_pos_at_failing));
DBUG_RETURN(error_num);
}
@@ -1872,7 +2283,7 @@ int spider_get_sys_tables_link_status(
char *ptr;
int error_num = 0;
DBUG_ENTER("spider_get_sys_tables_link_status");
- if ((ptr = get_field(mem_root, table->field[21])))
+ if ((ptr = get_field(mem_root, table->field[22])))
{
share->link_statuses[link_idx] =
(long) my_strtoll10(ptr, (char**) NULL, &error_num);
@@ -1883,6 +2294,22 @@ int spider_get_sys_tables_link_status(
DBUG_RETURN(error_num);
}
+int spider_get_sys_tables_link_status(
+ TABLE *table,
+ long *link_status,
+ MEM_ROOT *mem_root
+) {
+ char *ptr;
+ int error_num = 0;
+ DBUG_ENTER("spider_get_sys_tables_link_status");
+ if ((ptr = get_field(mem_root, table->field[22])))
+ *link_status = (long) my_strtoll10(ptr, (char**) NULL, &error_num);
+ else
+ *link_status = 1;
+ DBUG_PRINT("info",("spider link_statuses=%ld", *link_status));
+ DBUG_RETURN(error_num);
+}
+
int spider_get_sys_tables_link_idx(
TABLE *table,
int *link_idx,
@@ -1890,7 +2317,7 @@ int spider_get_sys_tables_link_idx(
) {
char *ptr;
int error_num = 0;
- DBUG_ENTER("spider_get_sys_tables_link_status");
+ DBUG_ENTER("spider_get_sys_tables_link_idx");
if ((ptr = get_field(mem_root, table->field[2])))
*link_idx = (int) my_strtoll10(ptr, (char**) NULL, &error_num);
else
@@ -1899,6 +2326,92 @@ int spider_get_sys_tables_link_idx(
DBUG_RETURN(error_num);
}
+int spider_get_sys_tables_static_link_id(
+ TABLE *table,
+ char **static_link_id,
+ uint *static_link_id_length,
+ MEM_ROOT *mem_root
+) {
+ int error_num = 0;
+ DBUG_ENTER("spider_get_sys_tables_static_link_id");
+ if (
+ !table->field[24]->is_null() &&
+ (*static_link_id = get_field(mem_root, table->field[24]))
+ ) {
+ *static_link_id_length = strlen(*static_link_id);
+ } else {
+ *static_link_id_length = 0;
+ }
+ DBUG_PRINT("info",("spider static_link_id=%s", *static_link_id ? *static_link_id : "NULL"));
+ DBUG_RETURN(error_num);
+}
+
+void spider_get_sys_table_sts_info(
+ TABLE *table,
+ ulonglong *data_file_length,
+ ulonglong *max_data_file_length,
+ ulonglong *index_file_length,
+ ha_rows *records,
+ ulong *mean_rec_length,
+ time_t *check_time,
+ time_t *create_time,
+ time_t *update_time
+) {
+ MYSQL_TIME mysql_time;
+#ifdef MARIADB_BASE_VERSION
+ uint not_used_uint;
+#else
+ my_bool not_used_my_bool;
+#endif
+ long not_used_long;
+ DBUG_ENTER("spider_get_sys_table_sts_info");
+ *data_file_length = (ulonglong) table->field[2]->val_int();
+ *max_data_file_length = (ulonglong) table->field[3]->val_int();
+ *index_file_length = (ulonglong) table->field[4]->val_int();
+ *records = (ha_rows) table->field[5]->val_int();
+ *mean_rec_length = (ulong) table->field[6]->val_int();
+ table->field[7]->get_date(&mysql_time, 0);
+#ifdef MARIADB_BASE_VERSION
+ *check_time = (time_t) my_system_gmt_sec(&mysql_time,
+ &not_used_long, &not_used_uint);
+#else
+ *check_time = (time_t) my_system_gmt_sec(&mysql_time,
+ &not_used_long, &not_used_my_bool);
+#endif
+ table->field[8]->get_date(&mysql_time, 0);
+#ifdef MARIADB_BASE_VERSION
+ *create_time = (time_t) my_system_gmt_sec(&mysql_time,
+ &not_used_long, &not_used_uint);
+#else
+ *create_time = (time_t) my_system_gmt_sec(&mysql_time,
+ &not_used_long, &not_used_my_bool);
+#endif
+ table->field[9]->get_date(&mysql_time, 0);
+#ifdef MARIADB_BASE_VERSION
+ *update_time = (time_t) my_system_gmt_sec(&mysql_time,
+ &not_used_long, &not_used_uint);
+#else
+ *update_time = (time_t) my_system_gmt_sec(&mysql_time,
+ &not_used_long, &not_used_my_bool);
+#endif
+ DBUG_VOID_RETURN;
+}
+
+void spider_get_sys_table_crd_info(
+ TABLE *table,
+ longlong *cardinality,
+ uint number_of_keys
+) {
+ uint seq;
+ DBUG_ENTER("spider_get_sys_table_crd_info");
+ seq = (uint) table->field[2]->val_int();
+ if (seq < number_of_keys)
+ {
+ cardinality[seq] = (longlong) table->field[3]->val_int();
+ }
+ DBUG_VOID_RETURN;
+}
+
int spider_sys_update_tables_link_status(
THD *thd,
char *name,
@@ -2297,6 +2810,310 @@ int spider_get_link_statuses(
DBUG_RETURN(0);
}
+int spider_sys_insert_or_update_table_sts(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ ulonglong *data_file_length,
+ ulonglong *max_data_file_length,
+ ulonglong *index_file_length,
+ ha_rows *records,
+ ulong *mean_rec_length,
+ time_t *check_time,
+ time_t *create_time,
+ time_t *update_time,
+ bool need_lock
+) {
+ int error_num;
+ TABLE *table_sts = NULL;
+#if MYSQL_VERSION_ID < 50500
+ Open_tables_state open_tables_backup;
+#else
+ Open_tables_backup open_tables_backup;
+#endif
+ DBUG_ENTER("spider_sys_insert_or_update_table_sts");
+ if (
+ !(table_sts = spider_open_sys_table(
+ thd, SPIDER_SYS_TABLE_STS_TABLE_NAME_STR,
+ SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN, TRUE,
+ &open_tables_backup, need_lock, &error_num))
+ ) {
+ goto error;
+ }
+ if ((error_num = spider_insert_or_update_table_sts(
+ table_sts,
+ name,
+ name_length,
+ data_file_length,
+ max_data_file_length,
+ index_file_length,
+ records,
+ mean_rec_length,
+ check_time,
+ create_time,
+ update_time
+ )))
+ goto error;
+ spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock);
+ table_sts = NULL;
+ DBUG_RETURN(0);
+
+error:
+ if (table_sts)
+ spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock);
+ DBUG_RETURN(error_num);
+}
+
+int spider_sys_insert_or_update_table_crd(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ longlong *cardinality,
+ uint number_of_keys,
+ bool need_lock
+) {
+ int error_num;
+ TABLE *table_crd = NULL;
+#if MYSQL_VERSION_ID < 50500
+ Open_tables_state open_tables_backup;
+#else
+ Open_tables_backup open_tables_backup;
+#endif
+ DBUG_ENTER("spider_sys_insert_or_update_table_crd");
+ if (
+ !(table_crd = spider_open_sys_table(
+ thd, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR,
+ SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN, TRUE,
+ &open_tables_backup, need_lock, &error_num))
+ ) {
+ goto error;
+ }
+ if ((error_num = spider_insert_or_update_table_crd(
+ table_crd,
+ name,
+ name_length,
+ cardinality,
+ number_of_keys
+ )))
+ goto error;
+ spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock);
+ table_crd = NULL;
+ DBUG_RETURN(0);
+
+error:
+ if (table_crd)
+ spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock);
+ DBUG_RETURN(error_num);
+}
+
+int spider_sys_delete_table_sts(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ bool need_lock
+) {
+ int error_num;
+ TABLE *table_sts = NULL;
+#if MYSQL_VERSION_ID < 50500
+ Open_tables_state open_tables_backup;
+#else
+ Open_tables_backup open_tables_backup;
+#endif
+ DBUG_ENTER("spider_sys_delete_table_sts");
+ if (
+ !(table_sts = spider_open_sys_table(
+ thd, SPIDER_SYS_TABLE_STS_TABLE_NAME_STR,
+ SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN, TRUE,
+ &open_tables_backup, need_lock, &error_num))
+ ) {
+ goto error;
+ }
+ if ((error_num = spider_delete_table_sts(
+ table_sts,
+ name,
+ name_length
+ )))
+ goto error;
+ spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock);
+ table_sts = NULL;
+ DBUG_RETURN(0);
+
+error:
+ if (table_sts)
+ spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock);
+ DBUG_RETURN(error_num);
+}
+
+int spider_sys_delete_table_crd(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ bool need_lock
+) {
+ int error_num;
+ TABLE *table_crd = NULL;
+#if MYSQL_VERSION_ID < 50500
+ Open_tables_state open_tables_backup;
+#else
+ Open_tables_backup open_tables_backup;
+#endif
+ DBUG_ENTER("spider_sys_delete_table_crd");
+ if (
+ !(table_crd = spider_open_sys_table(
+ thd, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR,
+ SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN, TRUE,
+ &open_tables_backup, need_lock, &error_num))
+ ) {
+ goto error;
+ }
+ if ((error_num = spider_delete_table_crd(
+ table_crd,
+ name,
+ name_length
+ )))
+ goto error;
+ spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock);
+ table_crd = NULL;
+ DBUG_RETURN(0);
+
+error:
+ if (table_crd)
+ spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock);
+ DBUG_RETURN(error_num);
+}
+
+int spider_sys_get_table_sts(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ ulonglong *data_file_length,
+ ulonglong *max_data_file_length,
+ ulonglong *index_file_length,
+ ha_rows *records,
+ ulong *mean_rec_length,
+ time_t *check_time,
+ time_t *create_time,
+ time_t *update_time,
+ bool need_lock
+) {
+ int error_num;
+ char table_key[MAX_KEY_LENGTH];
+ TABLE *table_sts = NULL;
+#if MYSQL_VERSION_ID < 50500
+ Open_tables_state open_tables_backup;
+#else
+ Open_tables_backup open_tables_backup;
+#endif
+ DBUG_ENTER("spider_sys_get_table_sts");
+ if (
+ !(table_sts = spider_open_sys_table(
+ thd, SPIDER_SYS_TABLE_STS_TABLE_NAME_STR,
+ SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN, TRUE,
+ &open_tables_backup, need_lock, &error_num))
+ ) {
+ goto error;
+ }
+
+ table_sts->use_all_columns();
+ spider_store_tables_name(table_sts, name, name_length);
+ if ((error_num = spider_check_sys_table(table_sts, table_key)))
+ {
+ if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
+ {
+ table_sts->file->print_error(error_num, MYF(0));
+ }
+ goto error;
+ } else {
+ spider_get_sys_table_sts_info(
+ table_sts,
+ data_file_length,
+ max_data_file_length,
+ index_file_length,
+ records,
+ mean_rec_length,
+ check_time,
+ create_time,
+ update_time
+ );
+ }
+
+ spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock);
+ table_sts = NULL;
+ DBUG_RETURN(0);
+
+error:
+ if (table_sts)
+ spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock);
+ DBUG_RETURN(error_num);
+}
+
+int spider_sys_get_table_crd(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ longlong *cardinality,
+ uint number_of_keys,
+ bool need_lock
+) {
+ int error_num;
+ char table_key[MAX_KEY_LENGTH];
+ bool index_inited = FALSE;
+ TABLE *table_crd = NULL;
+#if MYSQL_VERSION_ID < 50500
+ Open_tables_state open_tables_backup;
+#else
+ Open_tables_backup open_tables_backup;
+#endif
+ DBUG_ENTER("spider_sys_get_table_crd");
+ if (
+ !(table_crd = spider_open_sys_table(
+ thd, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR,
+ SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN, TRUE,
+ &open_tables_backup, need_lock, &error_num))
+ ) {
+ goto error;
+ }
+
+ table_crd->use_all_columns();
+ spider_store_tables_name(table_crd, name, name_length);
+ if ((error_num = spider_get_sys_table_by_idx(table_crd, table_key, 0,
+ SPIDER_SYS_TABLE_CRD_PK_COL_CNT - 1)))
+ {
+ if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
+ {
+ table_crd->file->print_error(error_num, MYF(0));
+ }
+ goto error;
+ } else {
+ index_inited = TRUE;
+ do {
+ spider_get_sys_table_crd_info(
+ table_crd,
+ cardinality,
+ number_of_keys
+ );
+ error_num = spider_sys_index_next_same(table_crd, table_key);
+ } while (error_num == 0);
+ }
+ index_inited = FALSE;
+ if ((error_num = spider_sys_index_end(table_crd)))
+ {
+ table_crd->file->print_error(error_num, MYF(0));
+ goto error;
+ }
+
+ spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock);
+ table_crd = NULL;
+ DBUG_RETURN(0);
+
+error:
+ if (index_inited)
+ spider_sys_index_end(table_crd);
+ if (table_crd)
+ spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock);
+ DBUG_RETURN(error_num);
+}
+
int spider_sys_replace(
TABLE *table,
bool *modified_non_trans_table
@@ -2390,9 +3207,15 @@ TABLE *spider_mk_sys_tmp_table(
LEX_CSTRING name= { field_name, strlen(field_name) };
DBUG_ENTER("spider_mk_sys_tmp_table");
+#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR
+ if (!(field = new (thd->mem_root) Field_blob(
+ (uint32) 4294967295U, FALSE, &name, cs, TRUE)))
+ goto error_alloc_field;
+#else
if (!(field = new Field_blob(
4294967295U, FALSE, &name, cs, TRUE)))
goto error_alloc_field;
+#endif
field->init(table);
#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR
@@ -2408,7 +3231,7 @@ TABLE *spider_mk_sys_tmp_table(
if (!(tmp_table = create_tmp_table(thd, tmp_tbl_prm,
i_list, (ORDER*) NULL, FALSE, FALSE, TMP_TABLE_FORCE_MYISAM,
- HA_POS_ERROR, (char *) "")))
+ HA_POS_ERROR, &empty_clex_string)))
goto error_create_tmp_table;
DBUG_RETURN(tmp_table);
@@ -2451,9 +3274,15 @@ TABLE *spider_mk_sys_tmp_table_for_result(
LEX_CSTRING name3= { field_name3, strlen(field_name3) };
DBUG_ENTER("spider_mk_sys_tmp_table_for_result");
+#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR
+ if (!(field1 = new (thd->mem_root) Field_blob(
+ (uint32) 4294967295U, FALSE, &name1, cs, TRUE)))
+ goto error_alloc_field1;
+#else
if (!(field1 = new Field_blob(
4294967295U, FALSE, &name1, cs, TRUE)))
goto error_alloc_field1;
+#endif
field1->init(table);
#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR
@@ -2467,9 +3296,15 @@ TABLE *spider_mk_sys_tmp_table_for_result(
if (i_list.push_back(i_field1))
goto error_push_item1;
+#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR
if (!(field2 = new (thd->mem_root) Field_blob(
4294967295U, FALSE, &name2, cs, TRUE)))
goto error_alloc_field2;
+#else
+ if (!(field2 = new Field_blob(
+ 4294967295U, FALSE, &name2, cs, TRUE)))
+ goto error_alloc_field2;
+#endif
field2->init(table);
#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR
@@ -2483,9 +3318,15 @@ TABLE *spider_mk_sys_tmp_table_for_result(
if (i_list.push_back(i_field2))
goto error_push_item2;
+#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR
if (!(field3 = new (thd->mem_root) Field_blob(
4294967295U, FALSE, &name3, cs, TRUE)))
goto error_alloc_field3;
+#else
+ if (!(field3 = new Field_blob(
+ 4294967295U, FALSE, field_name3, cs, TRUE)))
+ goto error_alloc_field3;
+#endif
field3->init(table);
#ifdef SPIDER_FIELD_FIELDPTR_REQUIRES_THDPTR
@@ -2501,7 +3342,7 @@ TABLE *spider_mk_sys_tmp_table_for_result(
if (!(tmp_table = create_tmp_table(thd, tmp_tbl_prm,
i_list, (ORDER*) NULL, FALSE, FALSE, TMP_TABLE_FORCE_MYISAM,
- HA_POS_ERROR, (char *) "")))
+ HA_POS_ERROR, &empty_clex_string)))
goto error_create_tmp_table;
DBUG_RETURN(tmp_table);
diff --git a/storage/spider/spd_sys_table.h b/storage/spider/spd_sys_table.h
index fc9d3fc38bd..009ef2ac8ca 100644
--- a/storage/spider/spd_sys_table.h
+++ b/storage/spider/spd_sys_table.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2014 Kentoku Shiba
+/* Copyright (C) 2008-2016 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define SPIDER_SYS_XA_TABLE_NAME_STR "spider_xa"
#define SPIDER_SYS_XA_TABLE_NAME_LEN (sizeof(SPIDER_SYS_XA_TABLE_NAME_STR) - 1)
@@ -25,6 +25,12 @@
#define SPIDER_SYS_LINK_FAILED_TABLE_NAME_LEN (sizeof(SPIDER_SYS_LINK_FAILED_TABLE_NAME_STR) - 1)
#define SPIDER_SYS_XA_FAILED_TABLE_NAME_STR "spider_xa_failed_log"
#define SPIDER_SYS_XA_FAILED_TABLE_NAME_LEN (sizeof(SPIDER_SYS_XA_FAILED_TABLE_NAME_STR) - 1)
+#define SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR "spider_table_position_for_recovery"
+#define SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN (sizeof(SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR) - 1)
+#define SPIDER_SYS_TABLE_STS_TABLE_NAME_STR "spider_table_sts"
+#define SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN (sizeof(SPIDER_SYS_TABLE_STS_TABLE_NAME_STR) - 1)
+#define SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR "spider_table_crd"
+#define SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN (sizeof(SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR) - 1)
#define SPIDER_SYS_XA_PREPARED_STR "PREPARED"
#define SPIDER_SYS_XA_NOT_YET_STR "NOT YET"
@@ -36,14 +42,20 @@
#define SPIDER_SYS_XA_IDX1_COL_CNT 1
#define SPIDER_SYS_XA_MEMBER_COL_CNT 18
#define SPIDER_SYS_XA_MEMBER_PK_COL_CNT 6
-#define SPIDER_SYS_TABLES_COL_CNT 22
-#define SPIDER_SYS_TABLES_PK_COL_CNT 2
+#define SPIDER_SYS_TABLES_COL_CNT 25
+#define SPIDER_SYS_TABLES_PK_COL_CNT 3
#define SPIDER_SYS_TABLES_IDX1_COL_CNT 1
+#define SPIDER_SYS_TABLES_UIDX1_COL_CNT 3
#define SPIDER_SYS_LINK_MON_TABLE_COL_CNT 19
+#define SPIDER_SYS_POS_FOR_RECOVERY_TABLE_COL_CNT 7
+#define SPIDER_SYS_TABLE_STS_COL_CNT 10
+#define SPIDER_SYS_TABLE_STS_PK_COL_CNT 2
+#define SPIDER_SYS_TABLE_CRD_COL_CNT 4
+#define SPIDER_SYS_TABLE_CRD_PK_COL_CNT 3
#define SPIDER_SYS_LINK_MON_TABLE_DB_NAME_SIZE 64
#define SPIDER_SYS_LINK_MON_TABLE_TABLE_NAME_SIZE 64
-#define SPIDER_SYS_LINK_MON_TABLE_LINK_ID_SIZE 10
+#define SPIDER_SYS_LINK_MON_TABLE_LINK_ID_SIZE 64
class SPIDER_MON_KEY: public SPIDER_SORT
{
@@ -139,6 +151,11 @@ int spider_check_sys_table_with_find_flag(
enum ha_rkey_function find_flag
);
+int spider_check_sys_table_for_update_all_columns(
+ TABLE *table,
+ char *table_key
+);
+
int spider_get_sys_table_by_idx(
TABLE *table,
char *table_key,
@@ -212,6 +229,12 @@ void spider_store_tables_link_idx_str(
const uint link_idx_length
);
+void spider_store_tables_static_link_id(
+ TABLE *table,
+ const char *static_link_id,
+ const uint static_link_id_length
+);
+
void spider_store_tables_priority(
TABLE *table,
longlong priority
@@ -233,6 +256,50 @@ void spider_store_link_chk_server_id(
uint32 server_id
);
+void spider_store_binlog_pos_failed_link_idx(
+ TABLE *table,
+ int failed_link_idx
+);
+
+void spider_store_binlog_pos_source_link_idx(
+ TABLE *table,
+ int source_link_idx
+);
+
+void spider_store_binlog_pos_binlog_file(
+ TABLE *table,
+ const char *file_name,
+ int file_name_length,
+ const char *position,
+ int position_length,
+ CHARSET_INFO *binlog_pos_cs
+);
+
+void spider_store_binlog_pos_gtid(
+ TABLE *table,
+ const char *gtid,
+ int gtid_length,
+ CHARSET_INFO *binlog_pos_cs
+);
+
+void spider_store_table_sts_info(
+ TABLE *table,
+ ulonglong *data_file_length,
+ ulonglong *max_data_file_length,
+ ulonglong *index_file_length,
+ ha_rows *records,
+ ulong *mean_rec_length,
+ time_t *check_time,
+ time_t *create_time,
+ time_t *update_time
+);
+
+void spider_store_table_crd_info(
+ TABLE *table,
+ uint *seq,
+ longlong *cardinality
+);
+
int spider_insert_xa(
TABLE *table,
XID *xid,
@@ -250,6 +317,32 @@ int spider_insert_tables(
SPIDER_SHARE *share
);
+int spider_insert_sys_table(
+ TABLE *table
+);
+
+int spider_insert_or_update_table_sts(
+ TABLE *table,
+ const char *name,
+ uint name_length,
+ ulonglong *data_file_length,
+ ulonglong *max_data_file_length,
+ ulonglong *index_file_length,
+ ha_rows *records,
+ ulong *mean_rec_length,
+ time_t *check_time,
+ time_t *create_time,
+ time_t *update_time
+);
+
+int spider_insert_or_update_table_crd(
+ TABLE *table,
+ const char *name,
+ uint name_length,
+ longlong *cardinality,
+ uint number_of_keys
+);
+
int spider_log_tables_link_failed(
TABLE *table,
char *name,
@@ -309,6 +402,18 @@ int spider_delete_tables(
int *old_link_count
);
+int spider_delete_table_sts(
+ TABLE *table,
+ const char *name,
+ uint name_length
+);
+
+int spider_delete_table_crd(
+ TABLE *table,
+ const char *name,
+ uint name_length
+);
+
int spider_get_sys_xid(
TABLE *table,
XID *xid,
@@ -345,6 +450,12 @@ int spider_get_sys_tables_connect_info(
MEM_ROOT *mem_root
);
+int spider_get_sys_tables_monitoring_binlog_pos_at_failing(
+ TABLE *table,
+ long *monitoring_binlog_pos_at_failing,
+ MEM_ROOT *mem_root
+);
+
int spider_get_sys_tables_link_status(
TABLE *table,
SPIDER_SHARE *share,
@@ -352,12 +463,43 @@ int spider_get_sys_tables_link_status(
MEM_ROOT *mem_root
);
+int spider_get_sys_tables_link_status(
+ TABLE *table,
+ long *link_status,
+ MEM_ROOT *mem_root
+);
+
int spider_get_sys_tables_link_idx(
TABLE *table,
int *link_idx,
MEM_ROOT *mem_root
);
+int spider_get_sys_tables_static_link_id(
+ TABLE *table,
+ char **static_link_id,
+ uint *static_link_id_length,
+ MEM_ROOT *mem_root
+);
+
+void spider_get_sys_table_sts_info(
+ TABLE *table,
+ ulonglong *data_file_length,
+ ulonglong *max_data_file_length,
+ ulonglong *index_file_length,
+ ha_rows *records,
+ ulong *mean_rec_length,
+ time_t *check_time,
+ time_t *create_time,
+ time_t *update_time
+);
+
+void spider_get_sys_table_crd_info(
+ TABLE *table,
+ longlong *cardinality,
+ uint number_of_keys
+);
+
int spider_sys_update_tables_link_status(
THD *thd,
char *name,
@@ -409,6 +551,68 @@ int spider_get_link_statuses(
MEM_ROOT *mem_root
);
+int spider_sys_insert_or_update_table_sts(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ ulonglong *data_file_length,
+ ulonglong *max_data_file_length,
+ ulonglong *index_file_length,
+ ha_rows *records,
+ ulong *mean_rec_length,
+ time_t *check_time,
+ time_t *create_time,
+ time_t *update_time,
+ bool need_lock
+);
+
+int spider_sys_insert_or_update_table_crd(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ longlong *cardinality,
+ uint number_of_keys,
+ bool need_lock
+);
+
+int spider_sys_delete_table_sts(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ bool need_lock
+);
+
+int spider_sys_delete_table_crd(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ bool need_lock
+);
+
+int spider_sys_get_table_sts(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ ulonglong *data_file_length,
+ ulonglong *max_data_file_length,
+ ulonglong *index_file_length,
+ ha_rows *records,
+ ulong *mean_rec_length,
+ time_t *check_time,
+ time_t *create_time,
+ time_t *update_time,
+ bool need_lock
+);
+
+int spider_sys_get_table_crd(
+ THD *thd,
+ const char *name,
+ uint name_length,
+ longlong *cardinality,
+ uint number_of_keys,
+ bool need_lock
+);
+
int spider_sys_replace(
TABLE *table,
bool *modified_non_trans_table
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index 64bfce88d1c..fde470daadd 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -27,6 +28,7 @@
#include "sql_partition.h"
#include "sql_servers.h"
#include "sql_select.h"
+#include "tztime.h"
#endif
#include "spd_err.h"
#include "spd_param.h"
@@ -41,6 +43,53 @@
#include "spd_ping_table.h"
#include "spd_direct_sql.h"
#include "spd_malloc.h"
+#include "spd_group_by_handler.h"
+
+/* Background thread management */
+#ifdef SPIDER_HAS_NEXT_THREAD_ID
+#define SPIDER_set_next_thread_id(A)
+MYSQL_THD create_thd();
+void destroy_thd(MYSQL_THD thd);
+#else
+ulong *spd_db_att_thread_id;
+inline void SPIDER_set_next_thread_id(THD *A)
+{
+ pthread_mutex_lock(&LOCK_thread_count);
+ A->thread_id = (*spd_db_att_thread_id)++;
+ pthread_mutex_unlock(&LOCK_thread_count);
+}
+MYSQL_THD create_thd()
+{
+ THD *thd = SPIDER_new_THD(next_thread_id());
+ if (thd)
+ {
+ thd->thread_stack = (char*) &thd;
+ thd->store_globals();
+ thd->set_command(COM_DAEMON);
+ thd->security_ctx->host_or_ip = "";
+ }
+ return thd;
+}
+void destroy_thd(MYSQL_THD thd)
+{
+ delete thd;
+}
+#endif
+inline MYSQL_THD spider_create_thd(SPIDER_THREAD *thread)
+{
+ THD *thd = create_thd();
+ if (thd)
+ {
+ SPIDER_set_next_thread_id(thd);
+ thd->mysys_var->current_cond = &thread->cond;
+ thd->mysys_var->current_mutex = &thread->mutex;
+ }
+ return thd;
+}
+inline void spider_destroy_thd(MYSQL_THD thd)
+{
+ destroy_thd(thd);
+}
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
@@ -54,7 +103,8 @@ struct charset_info_st *spd_charset_utf8_bin;
const char **spd_defaults_extra_file;
const char **spd_defaults_file;
bool volatile *spd_abort_loop;
-
+Time_zone *spd_tz_system;
+extern long spider_conn_mutex_id;
handlerton *spider_hton_ptr;
SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
extern SPIDER_DBTON spider_dbton_mysql;
@@ -64,6 +114,10 @@ extern SPIDER_DBTON spider_dbton_handlersocket;
#ifdef HAVE_ORACLE_OCI
extern SPIDER_DBTON spider_dbton_oracle;
#endif
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+SPIDER_THREAD *spider_table_sts_threads;
+SPIDER_THREAD *spider_table_crd_threads;
+#endif
#ifdef HAVE_PSI_INTERFACE
PSI_mutex_key spd_key_mutex_tbl;
@@ -110,6 +164,12 @@ PSI_mutex_key spd_key_mutex_udf_table;
PSI_mutex_key spd_key_mutex_mem_calc;
PSI_mutex_key spd_key_thread_id;
PSI_mutex_key spd_key_conn_id;
+PSI_mutex_key spd_key_mutex_ipport_count;
+PSI_mutex_key spd_key_mutex_conn_i;
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+PSI_mutex_key spd_key_mutex_bg_stss;
+PSI_mutex_key spd_key_mutex_bg_crds;
+#endif
static PSI_mutex_info all_spider_mutexes[]=
{
@@ -134,6 +194,12 @@ static PSI_mutex_info all_spider_mutexes[]=
{ &spd_key_mutex_mem_calc, "mem_calc", PSI_FLAG_GLOBAL},
{ &spd_key_thread_id, "thread_id", PSI_FLAG_GLOBAL},
{ &spd_key_conn_id, "conn_id", PSI_FLAG_GLOBAL},
+ { &spd_key_mutex_ipport_count, "ipport_count", PSI_FLAG_GLOBAL},
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ { &spd_key_mutex_bg_stss, "bg_stss", PSI_FLAG_GLOBAL},
+ { &spd_key_mutex_bg_crds, "bg_crds", PSI_FLAG_GLOBAL},
+#endif
+ { &spd_key_mutex_conn_i, "conn_i", 0},
{ &spd_key_mutex_mta_conn, "mta_conn", 0},
#ifndef WITHOUT_SPIDER_BG_SEARCH
{ &spd_key_mutex_bg_conn_chain, "bg_conn_chain", 0},
@@ -171,6 +237,13 @@ PSI_cond_key spd_key_cond_bg_mon_sleep;
PSI_cond_key spd_key_cond_bg_direct_sql;
#endif
PSI_cond_key spd_key_cond_udf_table_mon;
+PSI_cond_key spd_key_cond_conn_i;
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+PSI_cond_key spd_key_cond_bg_stss;
+PSI_cond_key spd_key_cond_bg_sts_syncs;
+PSI_cond_key spd_key_cond_bg_crds;
+PSI_cond_key spd_key_cond_bg_crd_syncs;
+#endif
static PSI_cond_info all_spider_conds[] = {
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -185,6 +258,13 @@ static PSI_cond_info all_spider_conds[] = {
{&spd_key_cond_bg_direct_sql, "bg_direct_sql", 0},
#endif
{&spd_key_cond_udf_table_mon, "udf_table_mon", 0},
+ {&spd_key_cond_conn_i, "conn_i", 0},
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ {&spd_key_cond_bg_stss, "bg_stss", 0},
+ {&spd_key_cond_bg_sts_syncs, "bg_sts_syncs", 0},
+ {&spd_key_cond_bg_crds, "bg_crds", 0},
+ {&spd_key_cond_bg_crd_syncs, "bg_crd_syncs", 0},
+#endif
};
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -192,6 +272,8 @@ PSI_thread_key spd_key_thd_bg;
PSI_thread_key spd_key_thd_bg_sts;
PSI_thread_key spd_key_thd_bg_crd;
PSI_thread_key spd_key_thd_bg_mon;
+PSI_thread_key spd_key_thd_bg_stss;
+PSI_thread_key spd_key_thd_bg_crds;
#endif
static PSI_thread_info all_spider_threads[] = {
@@ -200,11 +282,14 @@ static PSI_thread_info all_spider_threads[] = {
{&spd_key_thd_bg_sts, "bg_sts", 0},
{&spd_key_thd_bg_crd, "bg_crd", 0},
{&spd_key_thd_bg_mon, "bg_mon", 0},
+ {&spd_key_thd_bg_stss, "bg_stss", 0},
+ {&spd_key_thd_bg_crds, "bg_crds", 0},
#endif
};
#endif
extern HASH spider_open_connections;
+extern HASH spider_ipport_conns;
extern uint spider_open_connections_id;
extern const char *spider_open_connections_func_name;
extern const char *spider_open_connections_file_name;
@@ -254,6 +339,7 @@ pthread_mutex_t spider_init_error_tbl_mutex;
extern pthread_mutex_t spider_thread_id_mutex;
extern pthread_mutex_t spider_conn_id_mutex;
+extern pthread_mutex_t spider_ipport_conn_mutex;
#ifdef WITH_PARTITION_STORAGE_ENGINE
HASH spider_open_pt_share;
@@ -517,14 +603,12 @@ int spider_free_share_alloc(
) {
int roop_count;
DBUG_ENTER("spider_free_share_alloc");
+ for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; roop_count--)
{
- for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; roop_count--)
+ if (share->dbton_share[roop_count])
{
- if (share->dbton_share[roop_count])
- {
- delete share->dbton_share[roop_count];
- share->dbton_share[roop_count] = NULL;
- }
+ delete share->dbton_share[roop_count];
+ share->dbton_share[roop_count] = NULL;
}
}
if (share->server_names)
@@ -712,6 +796,17 @@ int spider_free_share_alloc(
}
spider_free(spider_current_trx, share->tgt_sequence_names, MYF(0));
}
+ if (share->static_link_ids)
+ {
+ for (roop_count = 0; roop_count < (int) share->static_link_ids_length;
+ roop_count++)
+ {
+ if (share->static_link_ids[roop_count])
+ spider_free(spider_current_trx, share->static_link_ids[roop_count],
+ MYF(0));
+ }
+ spider_free(spider_current_trx, share->static_link_ids, MYF(0));
+ }
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (share->hs_read_socks)
{
@@ -752,6 +847,8 @@ int spider_free_share_alloc(
if (share->monitoring_bg_kind)
spider_free(spider_current_trx, share->monitoring_bg_kind, MYF(0));
#endif
+ if (share->monitoring_binlog_pos_at_failing)
+ spider_free(spider_current_trx, share->monitoring_binlog_pos_at_failing, MYF(0));
if (share->monitoring_flag)
spider_free(spider_current_trx, share->monitoring_flag, MYF(0));
if (share->monitoring_kind)
@@ -892,6 +989,11 @@ void spider_free_tmp_share_alloc(
spider_free(spider_current_trx, share->tgt_sequence_names[0], MYF(0));
share->tgt_sequence_names[0] = NULL;
}
+ if (share->static_link_ids && share->static_link_ids[0])
+ {
+ spider_free(spider_current_trx, share->static_link_ids[0], MYF(0));
+ share->static_link_ids[0] = NULL;
+ }
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (share->hs_read_socks && share->hs_read_socks[0])
{
@@ -1395,6 +1497,56 @@ error:
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
+int spider_increase_null_string_list(
+ char ***string_list,
+ uint **string_length_list,
+ uint *list_length,
+ uint *list_charlen,
+ uint link_count
+) {
+ int roop_count;
+ char **tmp_str_list;
+ uint *tmp_length_list;
+ DBUG_ENTER("spider_increase_null_string_list");
+ if (*list_length == link_count)
+ DBUG_RETURN(0);
+
+ if (!(tmp_str_list = (char**)
+ spider_bulk_malloc(spider_current_trx, 247, MYF(MY_WME | MY_ZEROFILL),
+ &tmp_str_list, sizeof(char*) * link_count,
+ &tmp_length_list, sizeof(uint) * link_count,
+ NullS))
+ ) {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+
+ for (roop_count = 0; roop_count < (int) *list_length; roop_count++)
+ {
+ tmp_str_list[roop_count] = (*string_list)[roop_count];
+ tmp_length_list[roop_count] = (*string_length_list)[roop_count];
+ }
+ if (*string_list)
+ {
+ spider_free(spider_current_trx, *string_list, MYF(0));
+ }
+ *list_length = link_count;
+ *string_list = tmp_str_list;
+ *string_length_list = tmp_length_list;
+#ifndef DBUG_OFF
+ DBUG_PRINT("info",("spider list_length=%u", *list_length));
+ for (roop_count = 0; roop_count < (int) *list_length; roop_count++)
+ {
+ DBUG_PRINT("info",("spider string_list[%d]=%s", roop_count,
+ (*string_list)[roop_count] ? (*string_list)[roop_count] : "NULL"));
+ DBUG_PRINT("info",("spider string_length_list[%d]=%u", roop_count,
+ (*string_length_list)[roop_count]));
+ }
+#endif
+
+ DBUG_RETURN(0);
+}
+
int spider_increase_long_list(
long **long_list,
uint *list_length,
@@ -1798,6 +1950,8 @@ int spider_parse_connect_info(
#ifdef WITH_PARTITION_STORAGE_ENGINE
share->sts_sync = -1;
#endif
+ share->store_last_sts = -1;
+ share->load_sts_at_startup = -1;
#ifndef WITHOUT_SPIDER_BG_SEARCH
share->crd_bg_mode = -1;
#endif
@@ -1806,6 +1960,8 @@ int spider_parse_connect_info(
#ifdef WITH_PARTITION_STORAGE_ENGINE
share->crd_sync = -1;
#endif
+ share->store_last_crd = -1;
+ share->load_crd_at_startup = -1;
share->crd_type = -1;
share->crd_weight = -1;
share->internal_offset = -1;
@@ -1847,6 +2003,7 @@ int spider_parse_connect_info(
share->use_table_charset = -1;
share->use_pushdown_udf = -1;
share->skip_default_condition = -1;
+ share->skip_parallel_search = -1;
share->direct_dup_insert = -1;
share->direct_order_limit = -1;
share->bka_mode = -1;
@@ -2001,7 +2158,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_INT_WITH_MAX("bum", bulk_update_mode, 0, 2);
SPIDER_PARAM_INT("bus", bulk_update_size, 0);
#ifndef WITHOUT_SPIDER_BG_SEARCH
- SPIDER_PARAM_INT_WITH_MAX("cbm", crd_bg_mode, 0, 1);
+ SPIDER_PARAM_INT_WITH_MAX("cbm", crd_bg_mode, 0, 2);
#endif
SPIDER_PARAM_DOUBLE("civ", crd_interval, 0);
SPIDER_PARAM_INT_WITH_MAX("cmd", crd_mode, 0, 3);
@@ -2045,6 +2202,8 @@ int spider_parse_connect_info(
SPIDER_PARAM_INT_WITH_MAX("iom", internal_optimize, 0, 1);
SPIDER_PARAM_INT_WITH_MAX("iol", internal_optimize_local, 0, 1);
SPIDER_PARAM_INT_WITH_MAX("lmr", low_mem_read, 0, 1);
+ SPIDER_PARAM_INT_WITH_MAX("lcs", load_crd_at_startup, 0, 1);
+ SPIDER_PARAM_INT_WITH_MAX("lss", load_sts_at_startup, 0, 1);
SPIDER_PARAM_LONG_LIST_WITH_MAX("lst", link_statuses, 0, 3);
#ifndef WITHOUT_SPIDER_BG_SEARCH
SPIDER_PARAM_LONG_LIST_WITH_MAX("mbf", monitoring_bg_flag, 0, 1);
@@ -2052,6 +2211,7 @@ int spider_parse_connect_info(
"mbi", monitoring_bg_interval, 0, 4294967295LL);
SPIDER_PARAM_LONG_LIST_WITH_MAX("mbk", monitoring_bg_kind, 0, 3);
#endif
+ SPIDER_PARAM_LONG_LIST_WITH_MAX("mbp", monitoring_binlog_pos_at_failing, 0, 2);
SPIDER_PARAM_LONG_LIST_WITH_MAX("mfg", monitoring_flag, 0, 1);
SPIDER_PARAM_LONG_LIST_WITH_MAX("mkd", monitoring_kind, 0, 3);
SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(
@@ -2074,7 +2234,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_DOUBLE("rrt", read_rate, 0);
SPIDER_PARAM_INT_WITH_MAX("rsa", reset_sql_alloc, 0, 1);
#ifndef WITHOUT_SPIDER_BG_SEARCH
- SPIDER_PARAM_INT_WITH_MAX("sbm", sts_bg_mode, 0, 1);
+ SPIDER_PARAM_INT_WITH_MAX("sbm", sts_bg_mode, 0, 2);
#endif
SPIDER_PARAM_STR_LIST("sca", tgt_ssl_cas);
SPIDER_PARAM_STR_LIST("sch", tgt_ssl_ciphers);
@@ -2084,10 +2244,14 @@ int spider_parse_connect_info(
SPIDER_PARAM_INT_WITH_MAX("sdc", skip_default_condition, 0, 1);
SPIDER_PARAM_DOUBLE("siv", sts_interval, 0);
SPIDER_PARAM_STR_LIST("sky", tgt_ssl_keys);
+ SPIDER_PARAM_STR_LIST("sli", static_link_ids);
+ SPIDER_PARAM_INT_WITH_MAX("slc", store_last_crd, 0, 1);
SPIDER_PARAM_INT_WITH_MAX("slm", selupd_lock_mode, 0, 2);
+ SPIDER_PARAM_INT_WITH_MAX("sls", store_last_sts, 0, 1);
SPIDER_PARAM_INT_WITH_MAX("smd", sts_mode, 1, 2);
SPIDER_PARAM_LONGLONG("smr", static_mean_rec_length, 0);
SPIDER_PARAM_LONGLONG("spr", split_read, 0);
+ SPIDER_PARAM_INT_WITH_MAX("sps", skip_parallel_search, 0, 3);
SPIDER_PARAM_STR_LIST("sqn", tgt_sequence_names);
SPIDER_PARAM_LONGLONG("srd", second_read, 0);
SPIDER_PARAM_DOUBLE("srt", scan_rate, 0);
@@ -2196,8 +2360,8 @@ int spider_parse_connect_info(
case 11:
SPIDER_PARAM_INT_WITH_MAX("query_cache", query_cache, 0, 2);
#ifndef WITHOUT_SPIDER_BG_SEARCH
- SPIDER_PARAM_INT_WITH_MAX("crd_bg_mode", crd_bg_mode, 0, 1);
- SPIDER_PARAM_INT_WITH_MAX("sts_bg_mode", sts_bg_mode, 0, 1);
+ SPIDER_PARAM_INT_WITH_MAX("crd_bg_mode", crd_bg_mode, 0, 2);
+ SPIDER_PARAM_INT_WITH_MAX("sts_bg_mode", sts_bg_mode, 0, 2);
#endif
SPIDER_PARAM_LONG_LIST_WITH_MAX("link_status", link_statuses, 0, 3);
SPIDER_PARAM_LONG_LIST_WITH_MAX("use_handler", use_handlers, 0, 3);
@@ -2247,6 +2411,9 @@ int spider_parse_connect_info(
SPIDER_PARAM_INT_WITH_MAX("read_only_mode", read_only_mode, 0, 1);
SPIDER_PARAM_LONG_LIST_WITH_MAX("access_balance", access_balances, 0,
2147483647);
+ SPIDER_PARAM_STR_LIST("static_link_id", static_link_ids);
+ SPIDER_PARAM_INT_WITH_MAX("store_last_crd", store_last_crd, 0, 1);
+ SPIDER_PARAM_INT_WITH_MAX("store_last_sts", store_last_sts, 0, 1);
error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
MYF(0), tmp_ptr);
@@ -2353,6 +2520,10 @@ int spider_parse_connect_info(
#endif
SPIDER_PARAM_LONG_LIST_WITH_MAX("bka_table_name_type",
bka_table_name_types, 0, 1);
+ SPIDER_PARAM_INT_WITH_MAX(
+ "load_crd_at_startup", load_crd_at_startup, 0, 1);
+ SPIDER_PARAM_INT_WITH_MAX(
+ "load_sts_at_startup", load_sts_at_startup, 0, 1);
error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
MYF(0), tmp_ptr);
@@ -2362,6 +2533,8 @@ int spider_parse_connect_info(
"monitoring_server_id", monitoring_sid, 0, 4294967295LL);
SPIDER_PARAM_INT_WITH_MAX(
"delete_all_rows_type", delete_all_rows_type, 0, 1);
+ SPIDER_PARAM_INT_WITH_MAX(
+ "skip_parallel_search", skip_parallel_search, 0, 3);
error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
MYF(0), tmp_ptr);
@@ -2411,6 +2584,13 @@ int spider_parse_connect_info(
my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
MYF(0), tmp_ptr);
goto error;
+ case 32:
+ SPIDER_PARAM_LONG_LIST_WITH_MAX("monitoring_binlog_pos_at_failing",
+ monitoring_binlog_pos_at_failing, 0, 2);
+ error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM;
+ my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
+ MYF(0), tmp_ptr);
+ goto error;
default:
error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
@@ -2456,12 +2636,16 @@ int spider_parse_connect_info(
share->all_link_count = share->tgt_pk_names_length;
if (share->all_link_count < share->tgt_sequence_names_length)
share->all_link_count = share->tgt_sequence_names_length;
+ if (share->all_link_count < share->static_link_ids_length)
+ share->all_link_count = share->static_link_ids_length;
if (share->all_link_count < share->tgt_ports_length)
share->all_link_count = share->tgt_ports_length;
if (share->all_link_count < share->tgt_ssl_vscs_length)
share->all_link_count = share->tgt_ssl_vscs_length;
if (share->all_link_count < share->link_statuses_length)
share->all_link_count = share->link_statuses_length;
+ if (share->all_link_count < share->monitoring_binlog_pos_at_failing_length)
+ share->all_link_count = share->monitoring_binlog_pos_at_failing_length;
if (share->all_link_count < share->monitoring_flag_length)
share->all_link_count = share->monitoring_flag_length;
if (share->all_link_count < share->monitoring_kind_length)
@@ -2625,6 +2809,13 @@ int spider_parse_connect_info(
&share->tgt_sequence_names_charlen,
share->all_link_count)))
goto error;
+ if ((error_num = spider_increase_null_string_list(
+ &share->static_link_ids,
+ &share->static_link_ids_lengths,
+ &share->static_link_ids_length,
+ &share->static_link_ids_charlen,
+ share->all_link_count)))
+ goto error;
if ((error_num = spider_increase_long_list(
&share->tgt_ports,
&share->tgt_ports_length,
@@ -2653,6 +2844,11 @@ int spider_parse_connect_info(
goto error;
#endif
if ((error_num = spider_increase_long_list(
+ &share->monitoring_binlog_pos_at_failing,
+ &share->monitoring_binlog_pos_at_failing_length,
+ share->all_link_count)))
+ goto error;
+ if ((error_num = spider_increase_long_list(
&share->monitoring_flag,
&share->monitoring_flag_length,
share->all_link_count)))
@@ -2757,13 +2953,15 @@ int spider_parse_connect_info(
if (!(share_alter->tmp_server_names = (char **)
spider_bulk_malloc(spider_current_trx, 43, MYF(MY_WME | MY_ZEROFILL),
&share_alter->tmp_server_names,
- sizeof(char *) * 15 * share->all_link_count,
+ sizeof(char *) * 16 * share->all_link_count,
&share_alter->tmp_server_names_lengths,
- sizeof(uint *) * 15 * share->all_link_count,
+ sizeof(uint *) * 16 * share->all_link_count,
&share_alter->tmp_tgt_ports,
sizeof(long) * share->all_link_count,
&share_alter->tmp_tgt_ssl_vscs,
sizeof(long) * share->all_link_count,
+ &share_alter->tmp_monitoring_binlog_pos_at_failing,
+ sizeof(long) * share->all_link_count,
&share_alter->tmp_link_statuses,
sizeof(long) * share->all_link_count,
NullS))
@@ -2831,11 +3029,18 @@ int spider_parse_connect_info(
share_alter->tmp_tgt_default_files + share->all_link_count;
memcpy(share_alter->tmp_tgt_default_groups, share->tgt_default_groups,
sizeof(char *) * share->all_link_count);
+ share_alter->tmp_static_link_ids =
+ share_alter->tmp_tgt_default_groups + share->all_link_count;
+ memcpy(share_alter->tmp_static_link_ids, share->static_link_ids,
+ sizeof(char *) * share->all_link_count);
memcpy(share_alter->tmp_tgt_ports, share->tgt_ports,
sizeof(long) * share->all_link_count);
memcpy(share_alter->tmp_tgt_ssl_vscs, share->tgt_ssl_vscs,
sizeof(long) * share->all_link_count);
+ memcpy(share_alter->tmp_monitoring_binlog_pos_at_failing,
+ share->monitoring_binlog_pos_at_failing,
+ sizeof(long) * share->all_link_count);
memcpy(share_alter->tmp_link_statuses, share->link_statuses,
sizeof(long) * share->all_link_count);
@@ -2909,6 +3114,11 @@ int spider_parse_connect_info(
memcpy(share_alter->tmp_tgt_default_groups_lengths,
share->tgt_default_groups_lengths,
sizeof(uint) * share->all_link_count);
+ share_alter->tmp_static_link_ids_lengths =
+ share_alter->tmp_tgt_default_groups_lengths + share->all_link_count;
+ memcpy(share_alter->tmp_static_link_ids_lengths,
+ share->static_link_ids_lengths,
+ sizeof(uint) * share->all_link_count);
share_alter->tmp_server_names_charlen = share->server_names_charlen;
share_alter->tmp_tgt_table_names_charlen = share->tgt_table_names_charlen;
@@ -2927,6 +3137,8 @@ int spider_parse_connect_info(
share->tgt_default_files_charlen;
share_alter->tmp_tgt_default_groups_charlen =
share->tgt_default_groups_charlen;
+ share_alter->tmp_static_link_ids_charlen =
+ share->static_link_ids_charlen;
share_alter->tmp_server_names_length = share->server_names_length;
share_alter->tmp_tgt_table_names_length = share->tgt_table_names_length;
@@ -2944,8 +3156,12 @@ int spider_parse_connect_info(
share_alter->tmp_tgt_default_files_length = share->tgt_default_files_length;
share_alter->tmp_tgt_default_groups_length =
share->tgt_default_groups_length;
+ share_alter->tmp_static_link_ids_length =
+ share->static_link_ids_length;
share_alter->tmp_tgt_ports_length = share->tgt_ports_length;
share_alter->tmp_tgt_ssl_vscs_length = share->tgt_ssl_vscs_length;
+ share_alter->tmp_monitoring_binlog_pos_at_failing_length =
+ share->monitoring_binlog_pos_at_failing_length;
share_alter->tmp_link_statuses_length = share->link_statuses_length;
/* copy for tables end */
@@ -3185,6 +3401,51 @@ int spider_parse_connect_info(
MYF(0), share->tgt_sequence_names[roop_count], "sequence_name");
goto error;
}
+
+ DBUG_PRINT("info",
+ ("spider static_link_ids_lengths[%d] = %u", roop_count,
+ share->static_link_ids_lengths[roop_count]));
+ if (share->static_link_ids_lengths[roop_count] >
+ SPIDER_CONNECT_INFO_MAX_LEN)
+ {
+ error_num = ER_SPIDER_INVALID_CONNECT_INFO_TOO_LONG_NUM;
+ my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_TOO_LONG_STR,
+ MYF(0), share->static_link_ids[roop_count], "static_link_id");
+ goto error;
+ }
+ if (share->static_link_ids[roop_count])
+ {
+ if (
+ share->static_link_ids_lengths[roop_count] > 0 &&
+ share->static_link_ids[roop_count][0] >= '0' &&
+ share->static_link_ids[roop_count][0] <= '9'
+ ) {
+ error_num = ER_SPIDER_INVALID_CONNECT_INFO_START_WITH_NUM_NUM;
+ my_printf_error(error_num,
+ ER_SPIDER_INVALID_CONNECT_INFO_START_WITH_NUM_STR,
+ MYF(0), share->static_link_ids[roop_count], "static_link_id");
+ goto error;
+ }
+ for (roop_count2 = roop_count + 1;
+ roop_count2 < (int) share->all_link_count;
+ roop_count2++)
+ {
+ if (
+ share->static_link_ids_lengths[roop_count] ==
+ share->static_link_ids_lengths[roop_count2] &&
+ !memcmp(share->static_link_ids[roop_count],
+ share->static_link_ids[roop_count2],
+ share->static_link_ids_lengths[roop_count])
+ ) {
+ error_num = ER_SPIDER_INVALID_CONNECT_INFO_SAME_NUM;
+ my_printf_error(error_num,
+ ER_SPIDER_INVALID_CONNECT_INFO_SAME_STR,
+ MYF(0), share->static_link_ids[roop_count],
+ "static_link_id");
+ goto error;
+ }
+ }
+ }
}
}
@@ -3341,6 +3602,22 @@ int spider_set_connect_info_default(
}
}
+/*
+ if (!share->static_link_ids[roop_count])
+ {
+ DBUG_PRINT("info",("spider create default static_link_ids"));
+ share->static_link_ids_lengths[roop_count] =
+ SPIDER_DB_STATIC_LINK_ID_LEN;
+ if (
+ !(share->static_link_ids[roop_count] = spider_create_string(
+ SPIDER_DB_STATIC_LINK_ID_STR,
+ share->static_link_ids_lengths[roop_count]))
+ ) {
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ }
+*/
+
if (share->tgt_ports[roop_count] == -1)
{
share->tgt_ports[roop_count] = MYSQL_PORT;
@@ -3380,6 +3657,8 @@ int spider_set_connect_info_default(
if (share->monitoring_bg_kind[roop_count] == -1)
share->monitoring_bg_kind[roop_count] = 0;
#endif
+ if (share->monitoring_binlog_pos_at_failing[roop_count] == -1)
+ share->monitoring_binlog_pos_at_failing[roop_count] = 0;
if (share->monitoring_flag[roop_count] == -1)
share->monitoring_flag[roop_count] = 0;
if (share->monitoring_kind[roop_count] == -1)
@@ -3449,7 +3728,7 @@ int spider_set_connect_info_default(
#ifndef WITHOUT_SPIDER_BG_SEARCH
if (share->sts_bg_mode == -1)
- share->sts_bg_mode = 1;
+ share->sts_bg_mode = 2;
#endif
if (share->sts_interval == -1)
share->sts_interval = 10;
@@ -3459,9 +3738,13 @@ int spider_set_connect_info_default(
if (share->sts_sync == -1)
share->sts_sync = 0;
#endif
+ if (share->store_last_sts == -1)
+ share->store_last_sts = 1;
+ if (share->load_sts_at_startup == -1)
+ share->load_sts_at_startup = 1;
#ifndef WITHOUT_SPIDER_BG_SEARCH
if (share->crd_bg_mode == -1)
- share->crd_bg_mode = 1;
+ share->crd_bg_mode = 2;
#endif
if (share->crd_interval == -1)
share->crd_interval = 51;
@@ -3471,6 +3754,10 @@ int spider_set_connect_info_default(
if (share->crd_sync == -1)
share->crd_sync = 0;
#endif
+ if (share->store_last_crd == -1)
+ share->store_last_crd = 1;
+ if (share->load_crd_at_startup == -1)
+ share->load_crd_at_startup = 1;
if (share->crd_type == -1)
share->crd_type = 2;
if (share->crd_weight == -1)
@@ -3551,6 +3838,8 @@ int spider_set_connect_info_default(
share->use_pushdown_udf = 1;
if (share->skip_default_condition == -1)
share->skip_default_condition = 0;
+ if (share->skip_parallel_search == -1)
+ share->skip_parallel_search = 0;
if (share->direct_dup_insert == -1)
share->direct_dup_insert = 0;
if (share->direct_order_limit == -1)
@@ -3702,31 +3991,28 @@ int spider_create_conn_keys(
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
char *tmp_hs_r_name, *tmp_hs_w_name;
#endif
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
uint *conn_keys_lengths;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
uint *hs_r_conn_keys_lengths;
uint *hs_w_conn_keys_lengths;
#endif
-#else
- uint conn_keys_lengths[share->all_link_count];
-#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
- uint hs_r_conn_keys_lengths[share->all_link_count];
- uint hs_w_conn_keys_lengths[share->all_link_count];
-#endif
-#endif
DBUG_ENTER("spider_create_conn_keys");
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- if (!(conn_keys_lengths =
- (uint *) spider_bulk_alloc_mem(spider_current_trx, 44,
- __func__, __FILE__, __LINE__, MYF(MY_WME),
- &conn_keys_lengths, sizeof(uint) * share->all_link_count,
+ char *ptr;
+ uint length = sizeof(uint) * share->all_link_count;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
- &hs_r_conn_keys_lengths, sizeof(uint) * share->all_link_count,
- &hs_w_conn_keys_lengths, sizeof(uint) * share->all_link_count,
+ length += (sizeof(uint) * share->all_link_count) * 2;
#endif
- NullS)))
+ ptr = (char *) my_alloca(length);
+ if (!ptr)
+ {
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ conn_keys_lengths = (uint *) ptr;
+ ptr += (sizeof(uint) * share->all_link_count);
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ hs_r_conn_keys_lengths = (uint *) ptr;
+ ptr += (sizeof(uint) * share->all_link_count);
+ hs_w_conn_keys_lengths = (uint *) ptr;
#endif
share->conn_keys_charlen = 0;
@@ -3805,9 +4091,7 @@ int spider_create_conn_keys(
#endif
NullS))
) {
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(spider_current_trx, conn_keys_lengths, MYF(MY_WME));
-#endif
+ my_afree(conn_keys_lengths);
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
share->conn_keys_length = share->all_link_count;
@@ -3822,9 +4106,7 @@ int spider_create_conn_keys(
sizeof(uint) * share->all_link_count);
#endif
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(spider_current_trx, conn_keys_lengths, MYF(MY_WME));
-#endif
+ my_afree(conn_keys_lengths);
for (roop_count = 0; roop_count < (int) share->all_link_count; roop_count++)
{
@@ -4093,6 +4375,7 @@ SPIDER_SHARE *spider_create_share(
goto error_alloc_share;
}
+ SPD_INIT_ALLOC_ROOT(&share->mem_root, 4096, 0, MYF(MY_WME));
share->use_count = 0;
share->use_dbton_count = 0;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -4114,6 +4397,12 @@ SPIDER_SHARE *spider_create_share(
(uchar*) table_share->path.str, table_share->path.length);
#endif
#endif
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ share->table.s = table_share;
+ share->table.field = table_share->field;
+ share->table.key_info = table_share->key_info;
+ share->table.read_set = &table_share->all_set;
+#endif
if (table_share->keys > 0 &&
!(share->key_hint = new spider_string[table_share->keys])
@@ -4305,6 +4594,9 @@ SPIDER_SHARE *spider_get_share(
MEM_ROOT mem_root;
TABLE *table_tables = NULL;
bool init_mem_root = FALSE;
+ bool same_server_link;
+ int load_sts_at_startup;
+ int load_crd_at_startup;
DBUG_ENTER("spider_get_share");
length = (uint) strlen(table_name);
@@ -4396,6 +4688,9 @@ SPIDER_SHARE *spider_get_share(
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]);
}
pthread_mutex_unlock(&share->mutex);
+ share->init_error = TRUE;
+ share->init_error_time = (time_t) time((time_t*) 0);
+ share->init = TRUE;
spider_free_share(share);
goto error_open_sys_table;
}
@@ -4415,6 +4710,9 @@ SPIDER_SHARE *spider_get_share(
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]);
}
pthread_mutex_unlock(&share->mutex);
+ share->init_error = TRUE;
+ share->init_error_time = (time_t) time((time_t*) 0);
+ share->init = TRUE;
spider_free_share(share);
goto error_get_link_statuses;
}
@@ -4466,6 +4764,64 @@ SPIDER_SHARE *spider_get_share(
spider->set_error_mode();
#ifndef WITHOUT_SPIDER_BG_SEARCH
+ if (!share->sts_spider_init)
+ {
+ pthread_mutex_lock(&share->mutex);
+ if (!share->sts_spider_init)
+ {
+ if ((*error_num = spider_create_spider_object_for_share(
+ spider->trx, share, &share->sts_spider)))
+ {
+ pthread_mutex_unlock(&share->mutex);
+ share->init_error = TRUE;
+ share->init_error_time = (time_t) time((time_t*) 0);
+ share->init = TRUE;
+ spider_free_share(share);
+ goto error_sts_spider_init;
+ }
+#ifdef HASH_UPDATE_WITH_HASH_VALUE
+ share->sts_thread = &spider_table_sts_threads[
+ hash_value % spider_param_table_sts_thread_count()];
+#else
+ share->sts_thread = &spider_table_sts_threads[
+ my_calc_hash(&spider_open_tables, (uchar*) table_name, length) %
+ spider_param_table_sts_thread_count()];
+#endif
+ share->sts_spider_init = TRUE;
+ }
+ pthread_mutex_unlock(&share->mutex);
+ }
+
+ if (!share->crd_spider_init)
+ {
+ pthread_mutex_lock(&share->mutex);
+ if (!share->crd_spider_init)
+ {
+ if ((*error_num = spider_create_spider_object_for_share(
+ spider->trx, share, &share->crd_spider)))
+ {
+ pthread_mutex_unlock(&share->mutex);
+ share->init_error = TRUE;
+ share->init_error_time = (time_t) time((time_t*) 0);
+ share->init = TRUE;
+ spider_free_share(share);
+ goto error_crd_spider_init;
+ }
+#ifdef HASH_UPDATE_WITH_HASH_VALUE
+ share->crd_thread = &spider_table_crd_threads[
+ hash_value % spider_param_table_crd_thread_count()];
+#else
+ share->crd_thread = &spider_table_crd_threads[
+ my_calc_hash(&spider_open_tables, (uchar*) table_name, length) %
+ spider_param_table_crd_thread_count()];
+#endif
+ share->crd_spider_init = TRUE;
+ }
+ pthread_mutex_unlock(&share->mutex);
+ }
+#endif
+
+#ifndef WITHOUT_SPIDER_BG_SEARCH
if (
sql_command != SQLCOM_DROP_TABLE &&
sql_command != SQLCOM_ALTER_TABLE &&
@@ -4618,6 +4974,10 @@ SPIDER_SHARE *spider_get_share(
spider->dbton_handler[dbton_id] = NULL;
}
}
+ share->init_error = TRUE;
+ share->init_error_time = (time_t) time((time_t*) 0);
+ share->init = TRUE;
+ spider_free_share(share);
goto error_but_no_delete;
}
@@ -4649,6 +5009,7 @@ SPIDER_SHARE *spider_get_share(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4675,14 +5036,10 @@ SPIDER_SHARE *spider_get_share(
share->link_count, SPIDER_LINK_STATUS_OK);
if (search_link_idx == -1)
{
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- char *db, *table_name;
- if (!(db = (char *)
- spider_bulk_malloc(spider_current_trx, 48, MYF(MY_WME),
- &db, table_share->db.length + 1,
- &table_name, table_share->table_name.length + 1,
- NullS))
- ) {
+ char *db = (char *) my_alloca(
+ table_share->db.length + 1 + table_share->table_name.length + 1);
+ if (!db)
+ {
*error_num = HA_ERR_OUT_OF_MEM;
share->init_error = TRUE;
share->init_error_time = (time_t) time((time_t*) 0);
@@ -4690,10 +5047,7 @@ SPIDER_SHARE *spider_get_share(
spider_free_share(share);
goto error_but_no_delete;
}
-#else
- char db[table_share->db.length + 1],
- table_name[table_share->table_name.length + 1];
-#endif
+ char *table_name = db + table_share->db.length + 1;
memcpy(db, table_share->db.str, table_share->db.length);
db[table_share->db.length] = '\0';
memcpy(table_name, table_share->table_name.str,
@@ -4701,24 +5055,39 @@ SPIDER_SHARE *spider_get_share(
table_name[table_share->table_name.length] = '\0';
my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM,
ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name);
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(spider->trx, db, MYF(MY_WME));
-#endif
+ my_afree(db);
*error_num = ER_SPIDER_ALL_LINKS_FAILED_NUM;
share->init_error = TRUE;
share->init_error_time = (time_t) time((time_t*) 0);
share->init = TRUE;
spider_free_share(share);
goto error_but_no_delete;
+ } else if (search_link_idx == -2)
+ {
+ *error_num = HA_ERR_OUT_OF_MEM;
+ share->init_error = TRUE;
+ share->init_error_time = (time_t) time((time_t*) 0);
+ share->init = TRUE;
+ spider_free_share(share);
+ goto error_but_no_delete;
}
spider->search_link_idx = search_link_idx;
+ same_server_link = spider_param_same_server_link(thd);
+ load_sts_at_startup =
+ spider_param_load_sts_at_startup(share->load_sts_at_startup);
+ load_crd_at_startup =
+ spider_param_load_crd_at_startup(share->load_crd_at_startup);
if (
sql_command != SQLCOM_DROP_TABLE &&
sql_command != SQLCOM_ALTER_TABLE &&
sql_command != SQLCOM_SHOW_CREATE &&
!spider->error_mode &&
- !spider_param_same_server_link(thd)
+ (
+ !same_server_link ||
+ load_sts_at_startup ||
+ load_crd_at_startup
+ )
) {
SPIDER_INIT_ERROR_TABLE *spider_init_error_table;
sts_interval = spider_param_sts_interval(thd, share->sts_interval);
@@ -4762,22 +5131,32 @@ SPIDER_SHARE *spider_get_share(
}
}
- if (spider_get_sts(share, spider->search_link_idx, tmp_time,
- spider, sts_interval, sts_mode,
+ if (
+ (
+ !same_server_link ||
+ load_sts_at_startup
+ ) &&
+ spider_get_sts(share, spider->search_link_idx, tmp_time,
+ spider, sts_interval, sts_mode,
#ifdef WITH_PARTITION_STORAGE_ENGINE
- sts_sync,
+ sts_sync,
#endif
- 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO))
- {
+ 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO)
+ ) {
thd->clear_error();
}
- if (spider_get_crd(share, spider->search_link_idx, tmp_time,
- spider, table, crd_interval, crd_mode,
+ if (
+ (
+ !same_server_link ||
+ load_crd_at_startup
+ ) &&
+ spider_get_crd(share, spider->search_link_idx, tmp_time,
+ spider, table, crd_interval, crd_mode,
#ifdef WITH_PARTITION_STORAGE_ENGINE
- crd_sync,
+ crd_sync,
#endif
- 1))
- {
+ 1)
+ ) {
thd->clear_error();
}
pthread_mutex_unlock(&share->crd_mutex);
@@ -4789,9 +5168,22 @@ SPIDER_SHARE *spider_get_share(
share->use_count++;
pthread_mutex_unlock(&spider_tbl_mutex);
+ int sleep_cnt = 0;
while (!share->init)
{
- my_sleep(10);
+ // avoid for dead loop
+ if (sleep_cnt++ > 1000)
+ {
+ fprintf(stderr, " [WARN SPIDER RESULT] "
+ "Wait share->init too long, table_name %s %s %ld\n",
+ share->table_name, share->tgt_hosts[0], share->tgt_ports[0]);
+ *error_num = ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM;
+ my_printf_error(ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM,
+ ER_SPIDER_TABLE_OPEN_TIMEOUT_STR, MYF(0),
+ table_share->db.str, table_share->table_name.str);
+ goto error_but_no_delete;
+ }
+ my_sleep(10000); // wait 10 ms
}
if (!share->link_status_init)
@@ -4899,6 +5291,58 @@ SPIDER_SHARE *spider_get_share(
spider->set_error_mode();
#ifndef WITHOUT_SPIDER_BG_SEARCH
+ if (!share->sts_spider_init)
+ {
+ pthread_mutex_lock(&share->mutex);
+ if (!share->sts_spider_init)
+ {
+ if ((*error_num = spider_create_spider_object_for_share(
+ spider->trx, share, &share->sts_spider)))
+ {
+ pthread_mutex_unlock(&share->mutex);
+ spider_free_share(share);
+ goto error_sts_spider_init;
+ }
+#ifdef HASH_UPDATE_WITH_HASH_VALUE
+ share->sts_thread = &spider_table_sts_threads[
+ hash_value % spider_param_table_sts_thread_count()];
+#else
+ share->sts_thread = &spider_table_sts_threads[
+ my_calc_hash(&spider_open_tables, (uchar*) table_name, length) %
+ spider_param_table_sts_thread_count()];
+#endif
+ share->sts_spider_init = TRUE;
+ }
+ pthread_mutex_unlock(&share->mutex);
+ }
+
+ if (!share->crd_spider_init)
+ {
+ pthread_mutex_lock(&share->mutex);
+ if (!share->crd_spider_init)
+ {
+ if ((*error_num = spider_create_spider_object_for_share(
+ spider->trx, share, &share->crd_spider)))
+ {
+ pthread_mutex_unlock(&share->mutex);
+ spider_free_share(share);
+ goto error_crd_spider_init;
+ }
+#ifdef HASH_UPDATE_WITH_HASH_VALUE
+ share->crd_thread = &spider_table_crd_threads[
+ hash_value % spider_param_table_crd_thread_count()];
+#else
+ share->crd_thread = &spider_table_crd_threads[
+ my_calc_hash(&spider_open_tables, (uchar*) table_name, length) %
+ spider_param_table_crd_thread_count()];
+#endif
+ share->crd_spider_init = TRUE;
+ }
+ pthread_mutex_unlock(&share->mutex);
+ }
+#endif
+
+#ifndef WITHOUT_SPIDER_BG_SEARCH
if (
sql_command != SQLCOM_DROP_TABLE &&
sql_command != SQLCOM_ALTER_TABLE &&
@@ -5076,6 +5520,7 @@ SPIDER_SHARE *spider_get_share(
spider->trx,
spider->trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -5099,22 +5544,15 @@ SPIDER_SHARE *spider_get_share(
share->link_count, SPIDER_LINK_STATUS_OK);
if (search_link_idx == -1)
{
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- char *db, *table_name;
- if (!(db = (char *)
- spider_bulk_malloc(spider_current_trx, 50, MYF(MY_WME),
- &db, table_share->db.length + 1,
- &table_name, table_share->table_name.length + 1,
- NullS))
- ) {
+ char *db = (char *) my_alloca(
+ table_share->db.length + 1 + table_share->table_name.length + 1);
+ if (!db)
+ {
*error_num = HA_ERR_OUT_OF_MEM;
spider_free_share(share);
goto error_but_no_delete;
}
-#else
- char db[table_share->db.length + 1],
- table_name[table_share->table_name.length + 1];
-#endif
+ char *table_name = db + table_share->db.length + 1;
memcpy(db, table_share->db.str, table_share->db.length);
db[table_share->db.length] = '\0';
memcpy(table_name, table_share->table_name.str,
@@ -5122,12 +5560,15 @@ SPIDER_SHARE *spider_get_share(
table_name[table_share->table_name.length] = '\0';
my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM,
ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name);
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(spider->trx, db, MYF(MY_WME));
-#endif
+ my_afree(db);
*error_num = ER_SPIDER_ALL_LINKS_FAILED_NUM;
spider_free_share(share);
goto error_but_no_delete;
+ } else if (search_link_idx == -2)
+ {
+ *error_num = HA_ERR_OUT_OF_MEM;
+ spider_free_share(share);
+ goto error_but_no_delete;
}
spider->search_link_idx = search_link_idx;
@@ -5137,12 +5578,21 @@ SPIDER_SHARE *spider_get_share(
pthread_mutex_lock(&share->crd_mutex);
if (share->init_error)
{
+ same_server_link = spider_param_same_server_link(thd);
+ load_sts_at_startup =
+ spider_param_load_sts_at_startup(share->load_sts_at_startup);
+ load_crd_at_startup =
+ spider_param_load_crd_at_startup(share->load_crd_at_startup);
if (
sql_command != SQLCOM_DROP_TABLE &&
sql_command != SQLCOM_ALTER_TABLE &&
sql_command != SQLCOM_SHOW_CREATE &&
!spider->error_mode &&
- !spider_param_same_server_link(thd)
+ (
+ !same_server_link ||
+ load_sts_at_startup ||
+ load_crd_at_startup
+ )
) {
SPIDER_INIT_ERROR_TABLE *spider_init_error_table;
sts_interval = spider_param_sts_interval(thd, share->sts_interval);
@@ -5182,22 +5632,32 @@ SPIDER_SHARE *spider_get_share(
}
}
- if (spider_get_sts(share, spider->search_link_idx,
- tmp_time, spider, sts_interval, sts_mode,
+ if (
+ (
+ !same_server_link ||
+ load_sts_at_startup
+ ) &&
+ spider_get_sts(share, spider->search_link_idx,
+ tmp_time, spider, sts_interval, sts_mode,
#ifdef WITH_PARTITION_STORAGE_ENGINE
- sts_sync,
+ sts_sync,
#endif
- 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO))
- {
+ 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO)
+ ) {
thd->clear_error();
}
- if (spider_get_crd(share, spider->search_link_idx,
- tmp_time, spider, table, crd_interval, crd_mode,
+ if (
+ (
+ !same_server_link ||
+ load_crd_at_startup
+ ) &&
+ spider_get_crd(share, spider->search_link_idx,
+ tmp_time, spider, table, crd_interval, crd_mode,
#ifdef WITH_PARTITION_STORAGE_ENGINE
- crd_sync,
+ crd_sync,
#endif
- 1))
- {
+ 1)
+ ) {
thd->clear_error();
}
}
@@ -5223,6 +5683,10 @@ error_get_link_statuses:
table_tables = NULL;
}
error_open_sys_table:
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+error_crd_spider_init:
+error_sts_spider_init:
+#endif
if (init_mem_root)
{
free_root(&mem_root, MYF(0));
@@ -5256,7 +5720,49 @@ int spider_free_share(
spider_free_sts_thread(share);
spider_free_crd_thread(share);
spider_free_mon_threads(share);
+ if (share->sts_spider_init)
+ {
+ spider_table_remove_share_from_sts_thread(share);
+ spider_free_spider_object_for_share(&share->sts_spider);
+ }
+ if (share->crd_spider_init)
+ {
+ spider_table_remove_share_from_crd_thread(share);
+ spider_free_spider_object_for_share(&share->crd_spider);
+ }
#endif
+ if (
+ share->sts_init &&
+ spider_param_store_last_sts(share->store_last_sts)
+ ) {
+ spider_sys_insert_or_update_table_sts(
+ current_thd,
+ share->lgtm_tblhnd_share->table_name,
+ share->lgtm_tblhnd_share->table_name_length,
+ &share->data_file_length,
+ &share->max_data_file_length,
+ &share->index_file_length,
+ &share->records,
+ &share->mean_rec_length,
+ &share->check_time,
+ &share->create_time,
+ &share->update_time,
+ FALSE
+ );
+ }
+ if (
+ share->crd_init &&
+ spider_param_store_last_crd(share->store_last_crd)
+ ) {
+ spider_sys_insert_or_update_table_crd(
+ current_thd,
+ share->lgtm_tblhnd_share->table_name,
+ share->lgtm_tblhnd_share->table_name_length,
+ share->cardinality,
+ share->table_share->fields,
+ FALSE
+ );
+ }
spider_free_share_alloc(share);
#ifdef HASH_UPDATE_WITH_HASH_VALUE
my_hash_delete_with_hash_value(&spider_open_tables,
@@ -5268,6 +5774,7 @@ int spider_free_share(
pthread_mutex_destroy(&share->crd_mutex);
pthread_mutex_destroy(&share->sts_mutex);
pthread_mutex_destroy(&share->mutex);
+ free_root(&share->mem_root, MYF(0));
spider_free(spider_current_trx, share, MYF(0));
}
pthread_mutex_unlock(&spider_tbl_mutex);
@@ -6068,6 +6575,20 @@ int spider_db_done(
}
}
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ for (roop_count = spider_param_table_crd_thread_count() - 1;
+ roop_count >= 0; roop_count--)
+ {
+ spider_free_crd_threads(&spider_table_crd_threads[roop_count]);
+ }
+ for (roop_count = spider_param_table_sts_thread_count() - 1;
+ roop_count >= 0; roop_count--)
+ {
+ spider_free_sts_threads(&spider_table_sts_threads[roop_count]);
+ }
+ spider_free(NULL, spider_table_sts_threads, MYF(0));
+#endif
+
for (roop_count = spider_param_udf_table_mon_mutex_count() - 1;
roop_count >= 0; roop_count--)
{
@@ -6185,6 +6706,7 @@ int spider_db_done(
spider_open_connections.array.max_element *
spider_open_connections.array.size_of_element);
my_hash_free(&spider_open_connections);
+ my_hash_free(&spider_ipport_conns);
spider_free_mem_calc(spider_current_trx,
spider_lgtm_tblhnd_share_hash_id,
spider_lgtm_tblhnd_share_hash.array.max_element *
@@ -6240,6 +6762,7 @@ int spider_db_done(
#endif
pthread_mutex_destroy(&spider_init_error_tbl_mutex);
pthread_mutex_destroy(&spider_conn_id_mutex);
+ pthread_mutex_destroy(&spider_ipport_conn_mutex);
pthread_mutex_destroy(&spider_thread_id_mutex);
pthread_mutex_destroy(&spider_tbl_mutex);
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -6286,6 +6809,9 @@ int spider_db_init(
spider_hton->state = SHOW_OPTION_YES;
spider_hton->flags = HTON_NO_FLAGS;
+#ifdef HTON_CAN_READ_CONNECT_STRING_IN_PARTITION
+ spider_hton->flags |= HTON_CAN_READ_CONNECT_STRING_IN_PARTITION;
+#endif
/* spider_hton->db_type = DB_TYPE_SPIDER; */
/*
spider_hton->savepoint_offset;
@@ -6315,6 +6841,9 @@ int spider_db_init(
spider_hton->create = spider_create_handler;
spider_hton->drop_database = spider_drop_database;
spider_hton->show_status = spider_show_status;
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ spider_hton->create_group_by = spider_create_group_by_handler;
+#endif
memset(&spider_alloc_func_name, 0, sizeof(spider_alloc_func_name));
memset(&spider_alloc_file_name, 0, sizeof(spider_alloc_file_name));
@@ -6326,6 +6855,10 @@ int spider_db_init(
#ifdef _WIN32
HMODULE current_module = GetModuleHandle(NULL);
+#ifndef SPIDER_HAS_NEXT_THREAD_ID
+ spd_db_att_thread_id = (ulong *)
+ GetProcAddress(current_module, "?thread_id@@3KA");
+#endif
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
#ifdef XID_CACHE_IS_SPLITTED
@@ -6337,7 +6870,7 @@ int spider_db_init(
"?LOCK_xid_cache@@3PAUst_mysql_mutex@@A"));
spd_db_att_xid_cache = *((HASH **)
GetProcAddress(current_module, "?xid_cache@@3PAUst_hash@@A"));
-#elif MYSQL_VERSION_ID < 100103
+#else
spd_db_att_LOCK_xid_cache = (pthread_mutex_t *)
#if MYSQL_VERSION_ID < 50500
GetProcAddress(current_module,
@@ -6358,14 +6891,23 @@ int spider_db_init(
GetProcAddress(current_module, "my_defaults_file");
spd_abort_loop = (bool volatile *)
GetProcAddress(current_module, "?abort_loop@@3_NC");
+ spd_tz_system = *(Time_zone **)
+#ifdef _WIN64
+ GetProcAddress(current_module, "?my_tz_SYSTEM@@3PEAVTime_zone@@EA");
+#else
+ GetProcAddress(current_module, "?my_tz_SYSTEM@@3PAVTime_zone@@A");
+#endif
#else
+#ifndef SPIDER_HAS_NEXT_THREAD_ID
+ spd_db_att_thread_id = &thread_id;
+#endif
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
#ifdef XID_CACHE_IS_SPLITTED
spd_db_att_xid_cache_split_num = &opt_xid_cache_split_num;
spd_db_att_LOCK_xid_cache = LOCK_xid_cache;
spd_db_att_xid_cache = xid_cache;
-#elif MYSQL_VERSION_ID < 100103
+#else
spd_db_att_LOCK_xid_cache = &LOCK_xid_cache;
spd_db_att_xid_cache = &xid_cache;
#endif
@@ -6374,6 +6916,7 @@ int spider_db_init(
spd_defaults_extra_file = &my_defaults_extra_file;
spd_defaults_file = &my_defaults_file;
spd_abort_loop = &abort_loop;
+ spd_tz_system = my_tz_SYSTEM;
#endif
#ifdef HAVE_PSI_INTERFACE
@@ -6426,6 +6969,17 @@ int spider_db_init(
goto error_conn_id_mutex_init;
}
#if MYSQL_VERSION_ID < 50500
+ if (pthread_mutex_init(&spider_ipport_conn_mutex, MY_MUTEX_INIT_FAST))
+#else
+ if (mysql_mutex_init(spd_key_mutex_ipport_count,
+ &spider_ipport_conn_mutex, MY_MUTEX_INIT_FAST))
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_ipport_count_mutex_init;
+ }
+
+#if MYSQL_VERSION_ID < 50500
if (pthread_mutex_init(&spider_init_error_tbl_mutex, MY_MUTEX_INIT_FAST))
#else
if (mysql_mutex_init(spd_key_mutex_init_error_tbl,
@@ -6601,6 +7155,13 @@ int spider_db_init(
error_num = HA_ERR_OUT_OF_MEM;
goto error_open_connections_hash_init;
}
+ if(
+ my_hash_init(&spider_ipport_conns, spd_charset_utf8_bin, 32, 0, 0,
+ (my_hash_get_key) spider_ipport_conn_get_key, spider_free_ipport_conn, 0)
+ ) {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_ipport_conn__hash_init;
+ }
spider_alloc_calc_mem_init(spider_open_connections, 146);
spider_alloc_calc_mem(NULL,
spider_open_connections,
@@ -6719,6 +7280,37 @@ int spider_db_init(
spider_udf_table_mon_list_hash[roop_count].array.size_of_element);
}
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+ if (!(spider_table_sts_threads = (SPIDER_THREAD *)
+ spider_bulk_malloc(NULL, 256, MYF(MY_WME | MY_ZEROFILL),
+ &spider_table_sts_threads, sizeof(SPIDER_THREAD) *
+ spider_param_table_sts_thread_count(),
+ &spider_table_crd_threads, sizeof(SPIDER_THREAD) *
+ spider_param_table_crd_thread_count(),
+ NullS))
+ )
+ goto error_alloc_mon_mutxes;
+
+ for (roop_count = 0;
+ roop_count < (int) spider_param_table_sts_thread_count();
+ roop_count++)
+ {
+ if ((error_num = spider_create_sts_threads(&spider_table_sts_threads[roop_count])))
+ {
+ goto error_init_table_sts_threads;
+ }
+ }
+ for (roop_count = 0;
+ roop_count < (int) spider_param_table_crd_thread_count();
+ roop_count++)
+ {
+ if ((error_num = spider_create_crd_threads(&spider_table_crd_threads[roop_count])))
+ {
+ goto error_init_table_crd_threads;
+ }
+ }
+#endif
+
spider_dbton_mysql.dbton_id = dbton_id;
spider_dbton[dbton_id] = spider_dbton_mysql;
++dbton_id;
@@ -6761,6 +7353,19 @@ error_init_dbton:
spider_dbton[roop_count].deinit();
}
}
+ roop_count = spider_param_table_crd_thread_count() - 1;
+error_init_table_crd_threads:
+ for (; roop_count >= 0; roop_count--)
+ {
+ spider_free_crd_threads(&spider_table_crd_threads[roop_count]);
+ }
+ roop_count = spider_param_table_sts_thread_count() - 1;
+error_init_table_sts_threads:
+ for (; roop_count >= 0; roop_count--)
+ {
+ spider_free_sts_threads(&spider_table_sts_threads[roop_count]);
+ }
+ spider_free(NULL, spider_table_sts_threads, MYF(0));
roop_count = spider_param_udf_table_mon_mutex_count() - 1;
#endif
error_init_udf_table_mon_list_hash:
@@ -6794,6 +7399,8 @@ error_mon_table_cache_array_init:
spider_allocated_thds.array.size_of_element);
my_hash_free(&spider_allocated_thds);
error_allocated_thds_hash_init:
+ my_hash_free(&spider_ipport_conns);
+error_ipport_conn__hash_init:
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
spider_free_mem_calc(NULL,
spider_hs_w_conn_hash_id,
@@ -6868,6 +7475,8 @@ error_pt_share_mutex_init:
#endif
pthread_mutex_destroy(&spider_init_error_tbl_mutex);
error_init_error_tbl_mutex_init:
+ pthread_mutex_destroy(&spider_ipport_conn_mutex);
+error_ipport_count_mutex_init:
pthread_mutex_destroy(&spider_conn_id_mutex);
error_conn_id_mutex_init:
pthread_mutex_destroy(&spider_thread_id_mutex);
@@ -6959,10 +7568,13 @@ void spider_get_partition_info(
List_iterator<partition_element> sub_it((*part_elem)->subpartitions);
while ((*sub_elem = sub_it++))
{
- if (create_subpartition_name(tmp_name, sizeof(tmp_name),
- table_share->path.str, (*part_elem)->partition_name,
- (*sub_elem)->partition_name, NORMAL_PART_NAME))
+ if (SPIDER_create_subpartition_name(
+ tmp_name, FN_REFLEN + 1, table_share->path.str,
+ (*part_elem)->partition_name, (*sub_elem)->partition_name,
+ NORMAL_PART_NAME))
+ {
DBUG_VOID_RETURN;
+ }
DBUG_PRINT("info",("spider tmp_name=%s", tmp_name));
if (!memcmp(table_name, tmp_name, table_name_length + 1))
DBUG_VOID_RETURN;
@@ -6978,10 +7590,12 @@ void spider_get_partition_info(
}
}
} else {
- if (create_partition_name(tmp_name, sizeof(tmp_name),
- table_share->path.str, (*part_elem)->partition_name,
- NORMAL_PART_NAME, TRUE))
+ if (SPIDER_create_partition_name(
+ tmp_name, FN_REFLEN + 1, table_share->path.str,
+ (*part_elem)->partition_name, NORMAL_PART_NAME, TRUE))
+ {
DBUG_VOID_RETURN;
+ }
DBUG_PRINT("info",("spider tmp_name=%s", tmp_name));
if (!memcmp(table_name, tmp_name, table_name_length + 1))
DBUG_VOID_RETURN;
@@ -7025,6 +7639,7 @@ int spider_get_sts(
) {
int get_type;
int error_num = 0;
+ bool need_to_get = TRUE;
DBUG_ENTER("spider_get_sts");
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -7063,11 +7678,45 @@ int spider_get_sts(
/* copy */
get_type = 0;
}
- if (get_type == 0)
- spider_copy_sts_to_share(share, share->partition_share);
- else
#endif
- error_num = spider_db_show_table_status(spider, link_idx, sts_mode, flag);
+ if (
+ !share->sts_init &&
+ spider_param_load_sts_at_startup(share->load_sts_at_startup) &&
+ (!share->init || share->init_error)
+ ) {
+ error_num = spider_sys_get_table_sts(
+ current_thd,
+ share->lgtm_tblhnd_share->table_name,
+ share->lgtm_tblhnd_share->table_name_length,
+ &share->data_file_length,
+ &share->max_data_file_length,
+ &share->index_file_length,
+ &share->records,
+ &share->mean_rec_length,
+ &share->check_time,
+ &share->create_time,
+ &share->update_time,
+ FALSE
+ );
+ if (
+ !error_num ||
+ (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
+ )
+ need_to_get = FALSE;
+ }
+
+ if (need_to_get)
+ {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (get_type == 0)
+ spider_copy_sts_to_share(share, share->partition_share);
+ else {
+#endif
+ error_num = spider_db_show_table_status(spider, link_idx, sts_mode, flag);
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ }
+#endif
+ }
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (get_type >= 2)
pthread_mutex_unlock(&share->partition_share->sts_mutex);
@@ -7147,6 +7796,7 @@ int spider_get_crd(
) {
int get_type;
int error_num = 0;
+ bool need_to_get = TRUE;
DBUG_ENTER("spider_get_crd");
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -7185,12 +7835,39 @@ int spider_get_crd(
/* copy */
get_type = 0;
}
- if (get_type == 0)
- spider_copy_crd_to_share(share, share->partition_share,
- table->s->fields);
- else
#endif
- error_num = spider_db_show_index(spider, link_idx, table, crd_mode);
+ if (
+ !share->crd_init &&
+ spider_param_load_sts_at_startup(share->load_crd_at_startup)
+ ) {
+ error_num = spider_sys_get_table_crd(
+ current_thd,
+ share->lgtm_tblhnd_share->table_name,
+ share->lgtm_tblhnd_share->table_name_length,
+ share->cardinality,
+ table->s->fields,
+ FALSE
+ );
+ if (
+ !error_num ||
+ (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
+ )
+ need_to_get = FALSE;
+ }
+
+ if (need_to_get)
+ {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (get_type == 0)
+ spider_copy_crd_to_share(share, share->partition_share,
+ table->s->fields);
+ else {
+#endif
+ error_num = spider_db_show_index(spider, link_idx, table, crd_mode);
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ }
+#endif
+ }
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (get_type >= 2)
pthread_mutex_unlock(&share->partition_share->crd_mutex);
@@ -7548,35 +8225,37 @@ void spider_set_tmp_share_pointer(
tmp_share->tgt_default_groups = &tmp_connect_info[14];
tmp_share->tgt_pk_names = &tmp_connect_info[15];
tmp_share->tgt_sequence_names = &tmp_connect_info[16];
+ tmp_share->static_link_ids = &tmp_connect_info[17];
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
- tmp_share->hs_read_socks = &tmp_connect_info[17];
- tmp_share->hs_write_socks = &tmp_connect_info[18];
+ tmp_share->hs_read_socks = &tmp_connect_info[18];
+ tmp_share->hs_write_socks = &tmp_connect_info[19];
#endif
tmp_share->tgt_ports = &tmp_long[0];
tmp_share->tgt_ssl_vscs = &tmp_long[1];
tmp_share->link_statuses = &tmp_long[2];
- tmp_share->monitoring_flag = &tmp_long[3];
- tmp_share->monitoring_kind = &tmp_long[4];
+ tmp_share->monitoring_binlog_pos_at_failing = &tmp_long[3];
+ tmp_share->monitoring_flag = &tmp_long[4];
+ tmp_share->monitoring_kind = &tmp_long[5];
#ifndef WITHOUT_SPIDER_BG_SEARCH
- tmp_share->monitoring_bg_flag = &tmp_long[5];
- tmp_share->monitoring_bg_kind = &tmp_long[6];
+ tmp_share->monitoring_bg_flag = &tmp_long[6];
+ tmp_share->monitoring_bg_kind = &tmp_long[7];
#endif
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
- tmp_share->use_hs_reads = &tmp_long[7];
- tmp_share->use_hs_writes = &tmp_long[8];
- tmp_share->hs_read_ports = &tmp_long[9];
- tmp_share->hs_write_ports = &tmp_long[10];
- tmp_share->hs_write_to_reads = &tmp_long[11];
-#endif
- tmp_share->use_handlers = &tmp_long[12];
- tmp_share->connect_timeouts = &tmp_long[13];
+ tmp_share->use_hs_reads = &tmp_long[8];
+ tmp_share->use_hs_writes = &tmp_long[9];
+ tmp_share->hs_read_ports = &tmp_long[10];
+ tmp_share->hs_write_ports = &tmp_long[11];
+ tmp_share->hs_write_to_reads = &tmp_long[12];
+#endif
+ tmp_share->use_handlers = &tmp_long[13];
+ tmp_share->connect_timeouts = &tmp_long[14];
tmp_long[13] = -1;
- tmp_share->net_read_timeouts = &tmp_long[14];
+ tmp_share->net_read_timeouts = &tmp_long[15];
tmp_long[14] = -1;
- tmp_share->net_write_timeouts = &tmp_long[15];
+ tmp_share->net_write_timeouts = &tmp_long[16];
tmp_long[15] = -1;
- tmp_share->access_balances = &tmp_long[16];
- tmp_share->bka_table_name_types = &tmp_long[17];
+ tmp_share->access_balances = &tmp_long[17];
+ tmp_share->bka_table_name_types = &tmp_long[18];
tmp_share->monitoring_limit = &tmp_longlong[0];
tmp_share->monitoring_sid = &tmp_longlong[1];
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -7599,9 +8278,10 @@ void spider_set_tmp_share_pointer(
tmp_share->tgt_default_groups_lengths = &tmp_connect_info_length[14];
tmp_share->tgt_pk_names_lengths = &tmp_connect_info_length[15];
tmp_share->tgt_sequence_names_lengths = &tmp_connect_info_length[16];
+ tmp_share->static_link_ids_lengths = &tmp_connect_info_length[17];
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
- tmp_share->hs_read_socks_lengths = &tmp_connect_info_length[17];
- tmp_share->hs_write_socks_lengths = &tmp_connect_info_length[18];
+ tmp_share->hs_read_socks_lengths = &tmp_connect_info_length[18];
+ tmp_share->hs_write_socks_lengths = &tmp_connect_info_length[19];
#endif
tmp_share->server_names_length = 1;
tmp_share->tgt_table_names_length = 1;
@@ -7620,9 +8300,11 @@ void spider_set_tmp_share_pointer(
tmp_share->tgt_default_groups_length = 1;
tmp_share->tgt_pk_names_length = 1;
tmp_share->tgt_sequence_names_length = 1;
+ tmp_share->static_link_ids_length = 1;
tmp_share->tgt_ports_length = 1;
tmp_share->tgt_ssl_vscs_length = 1;
tmp_share->link_statuses_length = 1;
+ tmp_share->monitoring_binlog_pos_at_failing_length = 1;
tmp_share->monitoring_flag_length = 1;
tmp_share->monitoring_kind_length = 1;
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -7654,6 +8336,7 @@ void spider_set_tmp_share_pointer(
tmp_share->monitoring_bg_flag[0] = -1;
tmp_share->monitoring_bg_kind[0] = -1;
#endif
+ tmp_share->monitoring_binlog_pos_at_failing[0] = -1;
tmp_share->monitoring_flag[0] = -1;
tmp_share->monitoring_kind[0] = -1;
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -7753,6 +8436,19 @@ TABLE_LIST *spider_get_parent_table_list(
DBUG_RETURN(NULL);
}
+List<Index_hint> *spider_get_index_hints(
+ ha_spider *spider
+ ) {
+ TABLE_LIST *table_list = spider_get_parent_table_list(spider);
+ DBUG_ENTER("spider_get_index_hint");
+ if (table_list)
+ {
+ DBUG_RETURN(table_list->index_hints);
+ }
+ DBUG_RETURN(NULL);
+}
+
+
st_select_lex *spider_get_select_lex(
ha_spider *spider
) {
@@ -7765,6 +8461,24 @@ st_select_lex *spider_get_select_lex(
DBUG_RETURN(NULL);
}
+void spider_get_select_limit_from_select_lex(
+ st_select_lex *select_lex,
+ longlong *select_limit,
+ longlong *offset_limit
+) {
+ DBUG_ENTER("spider_get_select_limit_from_select_lex");
+ *select_limit = 9223372036854775807LL;
+ *offset_limit = 0;
+ if (select_lex && select_lex->explicit_limit)
+ {
+ *select_limit = select_lex->select_limit ?
+ select_lex->select_limit->val_int() : 0;
+ *offset_limit = select_lex->offset_limit ?
+ select_lex->offset_limit->val_int() : 0;
+ }
+ DBUG_VOID_RETURN;
+}
+
void spider_get_select_limit(
ha_spider *spider,
st_select_lex **select_lex,
@@ -7773,15 +8487,8 @@ void spider_get_select_limit(
) {
DBUG_ENTER("spider_get_select_limit");
*select_lex = spider_get_select_lex(spider);
- *select_limit = 9223372036854775807LL;
- *offset_limit = 0;
- if (*select_lex && (*select_lex)->explicit_limit)
- {
- *select_limit = (*select_lex)->select_limit ?
- (*select_lex)->select_limit->val_int() : 0;
- *offset_limit = (*select_lex)->offset_limit ?
- (*select_lex)->offset_limit->val_int() : 0;
- }
+ spider_get_select_limit_from_select_lex(
+ *select_lex, select_limit, offset_limit);
DBUG_VOID_RETURN;
}
@@ -7826,6 +8533,16 @@ longlong spider_split_read_param(
DBUG_PRINT("info",("spider bulk_update_mode=%d", bulk_update_mode));
DBUG_PRINT("info",("spider support_bulk_update_sql=%s",
spider->support_bulk_update_sql() ? "TRUE" : "FALSE"));
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ bool inserting =
+ (
+#ifdef HS_HAS_SQLCOM
+ spider->sql_command == SQLCOM_HS_INSERT ||
+#endif
+ spider->sql_command == SQLCOM_INSERT ||
+ spider->sql_command == SQLCOM_INSERT_SELECT
+ );
+#endif
bool updating =
(
#ifdef HS_HAS_SQLCOM
@@ -7852,6 +8569,12 @@ longlong spider_split_read_param(
DBUG_PRINT("info",("spider replacing=%s", replacing ? "TRUE" : "FALSE"));
TABLE *table = spider->get_table();
if (
+#ifdef SPIDER_HAS_GROUP_BY_HANDLER
+ (
+ inserting &&
+ spider->use_fields
+ ) ||
+#endif
replacing ||
(
(
@@ -8209,6 +8932,104 @@ bool spider_check_direct_order_limit(
DBUG_RETURN(FALSE);
}
+int spider_set_direct_limit_offset(
+ ha_spider *spider
+) {
+ THD *thd = spider->trx->thd;
+ st_select_lex *select_lex;
+ longlong select_limit;
+ longlong offset_limit;
+ TABLE_LIST *table_list;
+ DBUG_ENTER("spider_set_direct_limit_offset");
+
+ if (spider->result_list.direct_limit_offset)
+ DBUG_RETURN(TRUE);
+
+ if (
+ spider->pt_handler_share_creator &&
+ spider->pt_handler_share_creator != spider
+ ) {
+ if (spider->pt_handler_share_creator->result_list.direct_limit_offset == TRUE)
+ {
+ spider->result_list.direct_limit_offset = TRUE;
+ DBUG_RETURN(TRUE);
+ } else {
+ DBUG_RETURN(FALSE);
+ }
+ }
+
+ if (
+ spider->sql_command != SQLCOM_SELECT ||
+#ifdef HANDLER_HAS_DIRECT_AGGREGATE
+ spider->result_list.direct_aggregate ||
+#endif
+ spider->result_list.direct_order_limit ||
+ spider->prev_index_rnd_init != SPD_RND // must be RND_INIT and not be INDEX_INIT
+ )
+ DBUG_RETURN(FALSE);
+
+ spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit);
+
+ // limit and offset is non-zero
+ if (!(select_limit && offset_limit))
+ DBUG_RETURN(FALSE);
+
+ // more than one table
+ if (
+ !select_lex ||
+ select_lex->table_list.elements != 1
+ )
+ DBUG_RETURN(FALSE);
+
+ table_list = (TABLE_LIST *) select_lex->table_list.first;
+ if (table_list->table->file->partition_ht() != spider_hton_ptr)
+ {
+ DBUG_PRINT("info",("spider ht1=%u ht2=%u",
+ table_list->table->file->partition_ht()->slot,
+ spider_hton_ptr->slot
+ ));
+ DBUG_RETURN(FALSE);
+ }
+
+ // contain where
+ if (
+#if MYSQL_VERSION_ID < 50500
+ !thd->variables.engine_condition_pushdown ||
+#else
+#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON
+#else
+ !(thd->variables.optimizer_switch &
+ OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) ||
+#endif
+#endif
+ spider->condition // conditions is null may be no where condition in rand_init
+ )
+ DBUG_RETURN(FALSE);
+
+ // ignore condition like 1=1
+ if (select_lex->where && select_lex->where->with_subquery())
+ DBUG_RETURN(FALSE);
+
+ if (
+ select_lex->group_list.elements ||
+ select_lex->with_sum_func ||
+ select_lex->having ||
+ select_lex->order_list.elements
+ )
+ DBUG_RETURN(FALSE);
+
+ // must not be derived table
+ if (&thd->lex->select_lex != select_lex)
+ DBUG_RETURN(FALSE);
+
+ spider->direct_select_offset = offset_limit;
+ spider->direct_current_offset = offset_limit;
+ spider->direct_select_limit = select_limit;
+ spider->result_list.direct_limit_offset = TRUE;
+ DBUG_RETURN(TRUE);
+}
+
+
bool spider_check_index_merge(
TABLE *table,
st_select_lex *select_lex
@@ -8367,7 +9188,7 @@ int spider_discover_table_structure(
TABLE_SHARE *share,
HA_CREATE_INFO *info
) {
- int error_num = HA_ERR_WRONG_COMMAND;
+ int error_num = HA_ERR_WRONG_COMMAND, dummy;
SPIDER_SHARE *spider_share;
const char *table_name = share->path.str;
uint table_name_length = (uint) strlen(table_name);
@@ -8375,6 +9196,8 @@ int spider_discover_table_structure(
#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *part_info = thd->work_part_info;
#endif
+ Open_tables_backup open_tables_backup;
+ TABLE *table_tables;
uint str_len;
char buf[MAX_FIELD_WIDTH];
spider_string str(buf, sizeof(buf), system_charset_info);
@@ -8430,15 +9253,25 @@ int spider_discover_table_structure(
if (!error_num)
{
- Open_tables_backup open_tables_backup;
- TABLE *table_tables;
if (
(table_tables = spider_open_sys_table(
thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
SPIDER_SYS_TABLES_TABLE_NAME_LEN, TRUE, &open_tables_backup, FALSE,
&error_num))
) {
- error_num = spider_insert_tables(table_tables, spider_share);
+#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE
+ if (thd->lex->create_info.or_replace())
+ {
+ error_num = spider_delete_tables(table_tables,
+ spider_share->table_name, &dummy);
+ }
+ if (!error_num)
+ {
+#endif
+ error_num = spider_insert_tables(table_tables, spider_share);
+#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE
+ }
+#endif
spider_close_sys_table(thd, table_tables,
&open_tables_backup, FALSE);
}
@@ -8449,6 +9282,7 @@ int spider_discover_table_structure(
} else {
char tmp_name[FN_REFLEN + 1];
List_iterator<partition_element> part_it(part_info->partitions);
+ List_iterator<partition_element> part_it2(part_info->partitions);
partition_element *part_elem, *sub_elem;
while ((part_elem = part_it++))
{
@@ -8458,19 +9292,22 @@ int spider_discover_table_structure(
while ((sub_elem = sub_it++))
{
str.length(str_len);
- if (create_subpartition_name(tmp_name, sizeof(tmp_name), table_name,
- (part_elem)->partition_name, (sub_elem)->partition_name,
- NORMAL_PART_NAME))
- DBUG_RETURN(1);
+ if ((error_num = SPIDER_create_subpartition_name(
+ tmp_name, FN_REFLEN + 1, table_name,
+ (part_elem)->partition_name, (sub_elem)->partition_name,
+ NORMAL_PART_NAME)))
+ {
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
DBUG_PRINT("info",("spider tmp_name=%s", tmp_name));
- if (!(spider_share = spider_create_share(table_name, share,
+ if (!(spider_share = spider_create_share(tmp_name, share,
part_info,
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
hash_value,
#endif
&error_num
))) {
- continue;
+ DBUG_RETURN(error_num);
}
error_num = spider_discover_table_structure_internal(
@@ -8484,18 +9321,21 @@ int spider_discover_table_structure(
break;
} else {
str.length(str_len);
- if (create_partition_name(tmp_name, sizeof(tmp_name), table_name,
- (part_elem)->partition_name, NORMAL_PART_NAME, TRUE))
- DBUG_RETURN(1);
+ if ((error_num = SPIDER_create_partition_name(
+ tmp_name, FN_REFLEN + 1, table_name,
+ (part_elem)->partition_name, NORMAL_PART_NAME, TRUE)))
+ {
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
DBUG_PRINT("info",("spider tmp_name=%s", tmp_name));
- if (!(spider_share = spider_create_share(table_name, share,
+ if (!(spider_share = spider_create_share(tmp_name, share,
part_info,
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
hash_value,
#endif
&error_num
))) {
- continue;
+ DBUG_RETURN(error_num);
}
error_num = spider_discover_table_structure_internal(
@@ -8506,6 +9346,101 @@ int spider_discover_table_structure(
break;
}
}
+ if (!error_num)
+ {
+ if (
+ !(table_tables = spider_open_sys_table(
+ thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
+ SPIDER_SYS_TABLES_TABLE_NAME_LEN, TRUE, &open_tables_backup, FALSE,
+ &error_num))
+ ) {
+ DBUG_RETURN(error_num);
+ }
+ while ((part_elem = part_it2++))
+ {
+ if ((part_elem)->subpartitions.elements)
+ {
+ List_iterator<partition_element> sub_it((part_elem)->subpartitions);
+ while ((sub_elem = sub_it++))
+ {
+ if ((error_num = SPIDER_create_subpartition_name(
+ tmp_name, FN_REFLEN + 1, table_name,
+ (part_elem)->partition_name, (sub_elem)->partition_name,
+ NORMAL_PART_NAME)))
+ {
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ DBUG_PRINT("info",("spider tmp_name=%s", tmp_name));
+ if (!(spider_share = spider_create_share(tmp_name, share,
+ part_info,
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ hash_value,
+#endif
+ &error_num
+ ))) {
+ DBUG_RETURN(error_num);
+ }
+
+#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE
+ if (thd->lex->create_info.or_replace())
+ {
+ error_num = spider_delete_tables(table_tables,
+ spider_share->table_name, &dummy);
+ }
+ if (!error_num)
+ {
+#endif
+ error_num = spider_insert_tables(table_tables, spider_share);
+#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE
+ }
+#endif
+
+ spider_free_share_resource_only(spider_share);
+ if (error_num)
+ break;
+ }
+ if (error_num)
+ break;
+ } else {
+ if ((error_num = SPIDER_create_partition_name(
+ tmp_name, FN_REFLEN + 1, table_name,
+ (part_elem)->partition_name, NORMAL_PART_NAME, TRUE)))
+ {
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ DBUG_PRINT("info",("spider tmp_name=%s", tmp_name));
+ if (!(spider_share = spider_create_share(tmp_name, share,
+ part_info,
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ hash_value,
+#endif
+ &error_num
+ ))) {
+ DBUG_RETURN(error_num);
+ }
+
+#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE
+ if (thd->lex->create_info.or_replace())
+ {
+ error_num = spider_delete_tables(table_tables,
+ spider_share->table_name, &dummy);
+ }
+ if (!error_num)
+ {
+#endif
+ error_num = spider_insert_tables(table_tables, spider_share);
+#ifdef SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE
+ }
+#endif
+
+ spider_free_share_resource_only(spider_share);
+ if (error_num)
+ break;
+ }
+ }
+ spider_close_sys_table(thd, table_tables,
+ &open_tables_backup, FALSE);
+ }
}
#endif
@@ -8577,13 +9512,8 @@ int spider_discover_table_structure(
{
DBUG_RETURN(ER_SPIDER_UNKNOWN_NUM);
}
-#ifdef SPIDER_HAS_DISCOVER_TABLE_STRUCTURE_COMMENT
- if (!(part_syntax = generate_partition_syntax(thd, part_info, &part_syntax_len,
- TRUE, info, NULL)))
-#else
- if (!(part_syntax = generate_partition_syntax(part_info, &part_syntax_len,
- FALSE, TRUE, info, NULL)))
-#endif
+ if (!(part_syntax = SPIDER_generate_partition_syntax(thd, part_info,
+ &part_syntax_len, FALSE, TRUE, info, NULL, NULL)))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
@@ -8592,6 +9522,7 @@ int spider_discover_table_structure(
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
str.q_append(part_syntax, part_syntax_len);
+ SPIDER_free_part_syntax(part_syntax, MYF(0));
}
#endif
DBUG_PRINT("info",("spider str=%s", str.c_ptr_safe()));
@@ -8601,3 +9532,784 @@ int spider_discover_table_structure(
DBUG_RETURN(error_num);
}
#endif
+
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+int spider_create_spider_object_for_share(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ ha_spider **spider
+) {
+ int error_num, roop_count, *need_mons;
+ SPIDER_CONN **conns;
+ uint *conn_link_idx;
+ uchar *conn_can_fo;
+ char **conn_keys;
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ char **hs_r_conn_keys;
+ char **hs_w_conn_keys;
+#endif
+ spider_db_handler **dbton_hdl;
+ DBUG_ENTER("spider_create_spider_object_for_share");
+ DBUG_PRINT("info",("spider trx=%p", trx));
+ DBUG_PRINT("info",("spider share=%p", share));
+ DBUG_PRINT("info",("spider spider_ptr=%p", spider));
+ DBUG_PRINT("info",("spider spider=%p", (*spider)));
+
+ if (*spider)
+ {
+ /* already exists */
+ DBUG_RETURN(0);
+ }
+ (*spider) = new (&share->mem_root) ha_spider();
+ if (!(*spider))
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_spider_alloc;
+ }
+ DBUG_PRINT("info",("spider spider=%p", (*spider)));
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ if (!(need_mons = (int *)
+ spider_bulk_malloc(spider_current_trx, 255, MYF(MY_WME | MY_ZEROFILL),
+ &need_mons, (sizeof(int) * share->link_count),
+ &conns, (sizeof(SPIDER_CONN *) * share->link_count),
+ &conn_link_idx, (sizeof(uint) * share->link_count),
+ &conn_can_fo, (sizeof(uchar) * share->link_bitmap_size),
+ &conn_keys, (sizeof(char *) * share->link_count),
+ &hs_r_conn_keys, (sizeof(char *) * share->link_count),
+ &hs_w_conn_keys, (sizeof(char *) * share->link_count),
+ &dbton_hdl, (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE),
+ NullS))
+ )
+#else
+ if (!(need_mons = (int *)
+ spider_bulk_malloc(spider_current_trx, 255, MYF(MY_WME | MY_ZEROFILL),
+ &need_mons, (sizeof(int) * share->link_count),
+ &conns, (sizeof(SPIDER_CONN *) * share->link_count),
+ &conn_link_idx, (sizeof(uint) * share->link_count),
+ &conn_can_fo, (sizeof(uchar) * share->link_bitmap_size),
+ &conn_keys, (sizeof(char *) * share->link_count),
+ &dbton_hdl, (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE),
+ NullS))
+ )
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_need_mons_alloc;
+ }
+ DBUG_PRINT("info",("spider need_mons=%p", need_mons));
+ (*spider)->trx = trx;
+ (*spider)->change_table_ptr(&share->table, share->table_share);
+ (*spider)->share = share;
+ (*spider)->conns = conns;
+ (*spider)->conn_link_idx = conn_link_idx;
+ (*spider)->conn_can_fo = conn_can_fo;
+ (*spider)->need_mons = need_mons;
+ (*spider)->conn_keys_first_ptr = share->conn_keys[0];
+ (*spider)->conn_keys = conn_keys;
+#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
+ (*spider)->hs_r_conn_keys = hs_r_conn_keys;
+ (*spider)->hs_w_conn_keys = hs_w_conn_keys;
+#endif
+ (*spider)->dbton_handler = dbton_hdl;
+ (*spider)->search_link_idx = -1;
+ for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; roop_count++)
+ {
+ if (
+ spider_bit_is_set(share->dbton_bitmap, roop_count) &&
+ spider_dbton[roop_count].create_db_handler
+ ) {
+ if (!(dbton_hdl[roop_count] = spider_dbton[roop_count].create_db_handler(
+ *spider, share->dbton_share[roop_count])))
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_init_db_handler;
+ }
+ if ((error_num = dbton_hdl[roop_count]->init()))
+ goto error_init_db_handler;
+ }
+ }
+ DBUG_PRINT("info",("spider share=%p", (*spider)->share));
+ DBUG_PRINT("info",("spider need_mons=%p", (*spider)->need_mons));
+ DBUG_RETURN(0);
+
+error_init_db_handler:
+ for (; roop_count >= 0; --roop_count)
+ {
+ if (
+ spider_bit_is_set(share->dbton_bitmap, roop_count) &&
+ dbton_hdl[roop_count]
+ ) {
+ delete dbton_hdl[roop_count];
+ dbton_hdl[roop_count] = NULL;
+ }
+ }
+ spider_free(spider_current_trx, (*spider)->need_mons, MYF(0));
+error_need_mons_alloc:
+ delete (*spider);
+ (*spider) = NULL;
+error_spider_alloc:
+ DBUG_RETURN(error_num);
+}
+
+void spider_free_spider_object_for_share(
+ ha_spider **spider
+) {
+ int roop_count;
+ SPIDER_SHARE *share = (*spider)->share;
+ spider_db_handler **dbton_hdl = (*spider)->dbton_handler;
+ DBUG_ENTER("spider_free_spider_object_for_share");
+ DBUG_PRINT("info",("spider share=%p", share));
+ DBUG_PRINT("info",("spider spider_ptr=%p", spider));
+ DBUG_PRINT("info",("spider spider=%p", (*spider)));
+ for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; --roop_count)
+ {
+ if (
+ spider_bit_is_set(share->dbton_bitmap, roop_count) &&
+ dbton_hdl[roop_count]
+ ) {
+ delete dbton_hdl[roop_count];
+ dbton_hdl[roop_count] = NULL;
+ }
+ }
+ spider_free(spider_current_trx, (*spider)->need_mons, MYF(0));
+ delete (*spider);
+ (*spider) = NULL;
+ DBUG_VOID_RETURN;
+}
+
+int spider_create_sts_threads(
+ SPIDER_THREAD *spider_thread
+) {
+ int error_num;
+ DBUG_ENTER("spider_create_sts_threads");
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_mutex_init(&spider_thread->mutex,
+ MY_MUTEX_INIT_FAST))
+#else
+ if (mysql_mutex_init(spd_key_mutex_bg_stss,
+ &spider_thread->mutex, MY_MUTEX_INIT_FAST))
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_mutex_init;
+ }
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_cond_init(&spider_thread->cond, NULL))
+#else
+ if (mysql_cond_init(spd_key_cond_bg_stss,
+ &spider_thread->cond, NULL))
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_cond_init;
+ }
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_cond_init(&spider_thread->sync_cond, NULL))
+#else
+ if (mysql_cond_init(spd_key_cond_bg_sts_syncs,
+ &spider_thread->sync_cond, NULL))
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_sync_cond_init;
+ }
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_create(&spider_thread->thread, &spider_pt_attr,
+ spider_table_bg_sts_action, (void *) spider_thread)
+ )
+#else
+ if (mysql_thread_create(spd_key_thd_bg_stss, &spider_thread->thread,
+ &spider_pt_attr, spider_table_bg_sts_action, (void *) spider_thread)
+ )
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_thread_create;
+ }
+ DBUG_RETURN(0);
+
+error_thread_create:
+ pthread_cond_destroy(&spider_thread->sync_cond);
+error_sync_cond_init:
+ pthread_cond_destroy(&spider_thread->cond);
+error_cond_init:
+ pthread_mutex_destroy(&spider_thread->mutex);
+error_mutex_init:
+ DBUG_RETURN(error_num);
+}
+
+void spider_free_sts_threads(
+ SPIDER_THREAD *spider_thread
+) {
+ bool thread_killed;
+ DBUG_ENTER("spider_free_sts_threads");
+ pthread_mutex_lock(&spider_thread->mutex);
+ thread_killed = spider_thread->killed;
+ spider_thread->killed = TRUE;
+ if (!thread_killed)
+ {
+ if (spider_thread->thd_wait)
+ {
+ pthread_cond_signal(&spider_thread->cond);
+ }
+ pthread_cond_wait(&spider_thread->sync_cond, &spider_thread->mutex);
+ }
+ pthread_mutex_unlock(&spider_thread->mutex);
+ pthread_join(spider_thread->thread, NULL);
+ pthread_cond_destroy(&spider_thread->sync_cond);
+ pthread_cond_destroy(&spider_thread->cond);
+ pthread_mutex_destroy(&spider_thread->mutex);
+ spider_thread->thd_wait = FALSE;
+ spider_thread->killed = FALSE;
+ DBUG_VOID_RETURN;
+}
+
+int spider_create_crd_threads(
+ SPIDER_THREAD *spider_thread
+) {
+ int error_num;
+ DBUG_ENTER("spider_create_crd_threads");
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_mutex_init(&spider_thread->mutex,
+ MY_MUTEX_INIT_FAST))
+#else
+ if (mysql_mutex_init(spd_key_mutex_bg_crds,
+ &spider_thread->mutex, MY_MUTEX_INIT_FAST))
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_mutex_init;
+ }
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_cond_init(&spider_thread->cond, NULL))
+#else
+ if (mysql_cond_init(spd_key_cond_bg_crds,
+ &spider_thread->cond, NULL))
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_cond_init;
+ }
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_cond_init(&spider_thread->sync_cond, NULL))
+#else
+ if (mysql_cond_init(spd_key_cond_bg_crd_syncs,
+ &spider_thread->sync_cond, NULL))
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_sync_cond_init;
+ }
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_create(&spider_thread->thread, &spider_pt_attr,
+ spider_table_bg_crd_action, (void *) spider_thread)
+ )
+#else
+ if (mysql_thread_create(spd_key_thd_bg_crds, &spider_thread->thread,
+ &spider_pt_attr, spider_table_bg_crd_action, (void *) spider_thread)
+ )
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_thread_create;
+ }
+ DBUG_RETURN(0);
+
+error_thread_create:
+ pthread_cond_destroy(&spider_thread->sync_cond);
+error_sync_cond_init:
+ pthread_cond_destroy(&spider_thread->cond);
+error_cond_init:
+ pthread_mutex_destroy(&spider_thread->mutex);
+error_mutex_init:
+ DBUG_RETURN(error_num);
+}
+
+void spider_free_crd_threads(
+ SPIDER_THREAD *spider_thread
+) {
+ bool thread_killed;
+ DBUG_ENTER("spider_free_crd_threads");
+ pthread_mutex_lock(&spider_thread->mutex);
+ thread_killed = spider_thread->killed;
+ spider_thread->killed = TRUE;
+ if (!thread_killed)
+ {
+ if (spider_thread->thd_wait)
+ {
+ pthread_cond_signal(&spider_thread->cond);
+ }
+ pthread_cond_wait(&spider_thread->sync_cond, &spider_thread->mutex);
+ }
+ pthread_mutex_unlock(&spider_thread->mutex);
+ pthread_join(spider_thread->thread, NULL);
+ pthread_cond_destroy(&spider_thread->sync_cond);
+ pthread_cond_destroy(&spider_thread->cond);
+ pthread_mutex_destroy(&spider_thread->mutex);
+ spider_thread->thd_wait = FALSE;
+ spider_thread->killed = FALSE;
+ DBUG_VOID_RETURN;
+}
+
+void *spider_table_bg_sts_action(
+ void *arg
+) {
+ SPIDER_THREAD *thread = (SPIDER_THREAD *) arg;
+ SPIDER_SHARE *share;
+ SPIDER_TRX *trx;
+ int error_num;
+ ha_spider *spider;
+ SPIDER_CONN **conns;
+ THD *thd;
+ my_thread_init();
+ DBUG_ENTER("spider_table_bg_sts_action");
+ /* init start */
+ pthread_mutex_lock(&thread->mutex);
+ if (!(thd = spider_create_thd(thread)))
+ {
+ thread->thd_wait = FALSE;
+ thread->killed = FALSE;
+ pthread_mutex_unlock(&thread->mutex);
+ my_thread_end();
+ DBUG_RETURN(NULL);
+ }
+ SPIDER_set_next_thread_id(thd);
+#ifdef HAVE_PSI_INTERFACE
+ mysql_thread_set_psi_id(thd->thread_id);
+#endif
+ thd_proc_info(thd, "Spider table background statistics action handler");
+ if (!(trx = spider_get_trx(NULL, FALSE, &error_num)))
+ {
+ spider_destroy_thd(thd);
+ thread->thd_wait = FALSE;
+ thread->killed = FALSE;
+ pthread_mutex_unlock(&thread->mutex);
+#if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
+ my_pthread_setspecific_ptr(THR_THD, NULL);
+#endif
+ my_thread_end();
+ DBUG_RETURN(NULL);
+ }
+ trx->thd = thd;
+ /* init end */
+
+ while (TRUE)
+ {
+ DBUG_PRINT("info",("spider bg sts loop start"));
+ if (thread->killed)
+ {
+ DBUG_PRINT("info",("spider bg sts kill start"));
+ trx->thd = NULL;
+ spider_free_trx(trx, TRUE);
+ spider_destroy_thd(thd);
+ pthread_cond_signal(&thread->sync_cond);
+ pthread_mutex_unlock(&thread->mutex);
+#if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
+ my_pthread_setspecific_ptr(THR_THD, NULL);
+#endif
+ my_thread_end();
+ DBUG_RETURN(NULL);
+ }
+ if (!thread->queue_first)
+ {
+ DBUG_PRINT("info",("spider bg sts has no job"));
+ thread->thd_wait = TRUE;
+ pthread_cond_wait(&thread->cond, &thread->mutex);
+ thread->thd_wait = FALSE;
+ if (thd->killed)
+ thread->killed = TRUE;
+ continue;
+ }
+ share = (SPIDER_SHARE *) thread->queue_first;
+ share->sts_working = TRUE;
+ pthread_mutex_unlock(&thread->mutex);
+
+ spider = share->sts_spider;
+ conns = spider->conns;
+ if (spider->search_link_idx < 0)
+ {
+ spider->trx = trx;
+ spider_trx_set_link_idx_for_all(spider);
+ spider->search_link_idx = spider_conn_first_link_idx(thd,
+ share->link_statuses, share->access_balances, spider->conn_link_idx,
+ share->link_count, SPIDER_LINK_STATUS_OK);
+ }
+ if (spider->search_link_idx >= 0)
+ {
+ DBUG_PRINT("info",
+ ("spider difftime=%f",
+ difftime(share->bg_sts_try_time, share->sts_get_time)));
+ DBUG_PRINT("info",
+ ("spider bg_sts_interval=%f", share->bg_sts_interval));
+ if (difftime(share->bg_sts_try_time, share->sts_get_time) >=
+ share->bg_sts_interval)
+ {
+ if (!conns[spider->search_link_idx])
+ {
+ spider_get_conn(share, spider->search_link_idx,
+ share->conn_keys[spider->search_link_idx],
+ trx, spider, FALSE, FALSE, SPIDER_CONN_KIND_MYSQL,
+ &error_num);
+ if (conns[spider->search_link_idx])
+ {
+ conns[spider->search_link_idx]->error_mode = 0;
+ } else {
+ spider->search_link_idx = -1;
+ }
+ }
+ DBUG_PRINT("info",
+ ("spider search_link_idx=%d", spider->search_link_idx));
+ if (spider->search_link_idx >= 0 && conns[spider->search_link_idx])
+ {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (spider_get_sts(share, spider->search_link_idx,
+ share->bg_sts_try_time, spider,
+ share->bg_sts_interval, share->bg_sts_mode,
+ share->bg_sts_sync,
+ 2, HA_STATUS_CONST | HA_STATUS_VARIABLE))
+#else
+ if (spider_get_sts(share, spider->search_link_idx,
+ share->bg_sts_try_time, spider,
+ share->bg_sts_interval, share->bg_sts_mode,
+ 2, HA_STATUS_CONST | HA_STATUS_VARIABLE))
+#endif
+ {
+ spider->search_link_idx = -1;
+ }
+ }
+ }
+ }
+ memset(spider->need_mons, 0, sizeof(int) * share->link_count);
+ pthread_mutex_lock(&thread->mutex);
+ if (thread->queue_first == thread->queue_last)
+ {
+ thread->queue_first = NULL;
+ thread->queue_last = NULL;
+ } else {
+ thread->queue_first = share->sts_next;
+ share->sts_next->sts_prev = NULL;
+ share->sts_next = NULL;
+ }
+ share->sts_working = FALSE;
+ share->sts_wait = FALSE;
+ if (thread->first_free_wait)
+ {
+ pthread_cond_signal(&thread->sync_cond);
+ pthread_cond_wait(&thread->cond, &thread->mutex);
+ if (thd->killed)
+ thread->killed = TRUE;
+ }
+ }
+}
+
+void *spider_table_bg_crd_action(
+ void *arg
+) {
+ SPIDER_THREAD *thread = (SPIDER_THREAD *) arg;
+ SPIDER_SHARE *share;
+ SPIDER_TRX *trx;
+ int error_num;
+ ha_spider *spider;
+ TABLE *table;
+ SPIDER_CONN **conns;
+ THD *thd;
+ my_thread_init();
+ DBUG_ENTER("spider_table_bg_crd_action");
+ /* init start */
+ pthread_mutex_lock(&thread->mutex);
+ if (!(thd = spider_create_thd(thread)))
+ {
+ thread->thd_wait = FALSE;
+ thread->killed = FALSE;
+ pthread_mutex_unlock(&thread->mutex);
+ my_thread_end();
+ DBUG_RETURN(NULL);
+ }
+ SPIDER_set_next_thread_id(thd);
+#ifdef HAVE_PSI_INTERFACE
+ mysql_thread_set_psi_id(thd->thread_id);
+#endif
+ thd_proc_info(thd, "Spider table background cardinality action handler");
+ if (!(trx = spider_get_trx(NULL, FALSE, &error_num)))
+ {
+ spider_destroy_thd(thd);
+ thread->thd_wait = FALSE;
+ thread->killed = FALSE;
+ pthread_mutex_unlock(&thread->mutex);
+#if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
+ my_pthread_setspecific_ptr(THR_THD, NULL);
+#endif
+ my_thread_end();
+ DBUG_RETURN(NULL);
+ }
+ trx->thd = thd;
+ /* init end */
+
+ while (TRUE)
+ {
+ DBUG_PRINT("info",("spider bg crd loop start"));
+ if (thread->killed)
+ {
+ DBUG_PRINT("info",("spider bg crd kill start"));
+ trx->thd = NULL;
+ spider_free_trx(trx, TRUE);
+ spider_destroy_thd(thd);
+ pthread_cond_signal(&thread->sync_cond);
+ pthread_mutex_unlock(&thread->mutex);
+#if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
+ my_pthread_setspecific_ptr(THR_THD, NULL);
+#endif
+ my_thread_end();
+ DBUG_RETURN(NULL);
+ }
+ if (!thread->queue_first)
+ {
+ DBUG_PRINT("info",("spider bg crd has no job"));
+ thread->thd_wait = TRUE;
+ pthread_cond_wait(&thread->cond, &thread->mutex);
+ thread->thd_wait = FALSE;
+ if (thd->killed)
+ thread->killed = TRUE;
+ continue;
+ }
+ share = (SPIDER_SHARE *) thread->queue_first;
+ share->crd_working = TRUE;
+ pthread_mutex_unlock(&thread->mutex);
+
+ table = &share->table;
+ spider = share->crd_spider;
+ conns = spider->conns;
+ if (spider->search_link_idx < 0)
+ {
+ spider->trx = trx;
+ spider_trx_set_link_idx_for_all(spider);
+ spider->search_link_idx = spider_conn_first_link_idx(thd,
+ share->link_statuses, share->access_balances, spider->conn_link_idx,
+ share->link_count, SPIDER_LINK_STATUS_OK);
+ }
+ if (spider->search_link_idx >= 0)
+ {
+ DBUG_PRINT("info",
+ ("spider difftime=%f",
+ difftime(share->bg_crd_try_time, share->crd_get_time)));
+ DBUG_PRINT("info",
+ ("spider bg_crd_interval=%f", share->bg_crd_interval));
+ if (difftime(share->bg_crd_try_time, share->crd_get_time) >=
+ share->bg_crd_interval)
+ {
+ if (!conns[spider->search_link_idx])
+ {
+ spider_get_conn(share, spider->search_link_idx,
+ share->conn_keys[spider->search_link_idx],
+ spider_global_trx, spider, FALSE, FALSE, SPIDER_CONN_KIND_MYSQL,
+ &error_num);
+ if (conns[spider->search_link_idx])
+ {
+ conns[spider->search_link_idx]->error_mode = 0;
+ } else {
+ spider->search_link_idx = -1;
+ }
+ }
+ DBUG_PRINT("info",
+ ("spider search_link_idx=%d", spider->search_link_idx));
+ if (spider->search_link_idx >= 0 && conns[spider->search_link_idx])
+ {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (spider_get_crd(share, spider->search_link_idx,
+ share->bg_crd_try_time, spider, table,
+ share->bg_crd_interval, share->bg_crd_mode,
+ share->bg_crd_sync,
+ 2))
+#else
+ if (spider_get_crd(share, spider->search_link_idx,
+ share->bg_crd_try_time, spider, table,
+ share->bg_crd_interval, share->bg_crd_mode,
+ 2))
+#endif
+ {
+ spider->search_link_idx = -1;
+ }
+ }
+ }
+ }
+ memset(spider->need_mons, 0, sizeof(int) * share->link_count);
+ pthread_mutex_lock(&thread->mutex);
+ if (thread->queue_first == thread->queue_last)
+ {
+ thread->queue_first = NULL;
+ thread->queue_last = NULL;
+ } else {
+ thread->queue_first = share->crd_next;
+ share->crd_next->crd_prev = NULL;
+ share->crd_next = NULL;
+ }
+ share->crd_working = FALSE;
+ share->crd_wait = FALSE;
+ if (thread->first_free_wait)
+ {
+ pthread_cond_signal(&thread->sync_cond);
+ pthread_cond_wait(&thread->cond, &thread->mutex);
+ if (thd->killed)
+ thread->killed = TRUE;
+ }
+ }
+}
+
+void spider_table_add_share_to_sts_thread(
+ SPIDER_SHARE *share
+) {
+ SPIDER_THREAD *spider_thread = share->sts_thread;
+ DBUG_ENTER("spider_table_add_share_to_sts_thread");
+ if (
+ !share->sts_wait &&
+ !pthread_mutex_trylock(&spider_thread->mutex)
+ ) {
+ if (!share->sts_wait)
+ {
+ if (spider_thread->queue_last)
+ {
+ DBUG_PRINT("info",("spider add to last"));
+ share->sts_prev = spider_thread->queue_last;
+ spider_thread->queue_last->sts_next = share;
+ } else {
+ spider_thread->queue_first = share;
+ }
+ spider_thread->queue_last = share;
+ share->sts_wait = TRUE;
+
+ if (spider_thread->thd_wait)
+ {
+ pthread_cond_signal(&spider_thread->cond);
+ }
+ }
+ pthread_mutex_unlock(&spider_thread->mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+void spider_table_add_share_to_crd_thread(
+ SPIDER_SHARE *share
+) {
+ SPIDER_THREAD *spider_thread = share->crd_thread;
+ DBUG_ENTER("spider_table_add_share_to_crd_thread");
+ if (
+ !share->crd_wait &&
+ !pthread_mutex_trylock(&spider_thread->mutex)
+ ) {
+ if (!share->crd_wait)
+ {
+ if (spider_thread->queue_last)
+ {
+ DBUG_PRINT("info",("spider add to last"));
+ share->crd_prev = spider_thread->queue_last;
+ spider_thread->queue_last->crd_next = share;
+ } else {
+ spider_thread->queue_first = share;
+ }
+ spider_thread->queue_last = share;
+ share->crd_wait = TRUE;
+
+ if (spider_thread->thd_wait)
+ {
+ pthread_cond_signal(&spider_thread->cond);
+ }
+ }
+ pthread_mutex_unlock(&spider_thread->mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+void spider_table_remove_share_from_sts_thread(
+ SPIDER_SHARE *share
+) {
+ SPIDER_THREAD *spider_thread = share->sts_thread;
+ DBUG_ENTER("spider_table_remove_share_from_sts_thread");
+ if (share->sts_wait)
+ {
+ pthread_mutex_lock(&spider_thread->mutex);
+ if (share->sts_wait)
+ {
+ if (share->sts_working)
+ {
+ DBUG_PRINT("info",("spider waiting bg sts start"));
+ spider_thread->first_free_wait = TRUE;
+ pthread_cond_wait(&spider_thread->sync_cond, &spider_thread->mutex);
+ spider_thread->first_free_wait = FALSE;
+ pthread_cond_signal(&spider_thread->cond);
+ DBUG_PRINT("info",("spider waiting bg sts end"));
+ }
+
+ if (share->sts_prev)
+ {
+ if (share->sts_next)
+ {
+ DBUG_PRINT("info",("spider remove middle one"));
+ share->sts_prev->sts_next = share->sts_next;
+ share->sts_next->sts_prev = share->sts_prev;
+ } else {
+ DBUG_PRINT("info",("spider remove last one"));
+ share->sts_prev->sts_next = NULL;
+ spider_thread->queue_last = share->sts_prev;
+ }
+ } else if (share->sts_next) {
+ DBUG_PRINT("info",("spider remove first one"));
+ share->sts_next->sts_prev = NULL;
+ spider_thread->queue_first = share->sts_next;
+ } else {
+ DBUG_PRINT("info",("spider empty"));
+ spider_thread->queue_first = NULL;
+ spider_thread->queue_last = NULL;
+ }
+ }
+ pthread_mutex_unlock(&spider_thread->mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+void spider_table_remove_share_from_crd_thread(
+ SPIDER_SHARE *share
+) {
+ SPIDER_THREAD *spider_thread = share->crd_thread;
+ DBUG_ENTER("spider_table_remove_share_from_crd_thread");
+ if (share->crd_wait)
+ {
+ pthread_mutex_lock(&spider_thread->mutex);
+ if (share->crd_wait)
+ {
+ if (share->crd_working)
+ {
+ DBUG_PRINT("info",("spider waiting bg crd start"));
+ spider_thread->first_free_wait = TRUE;
+ pthread_cond_wait(&spider_thread->sync_cond, &spider_thread->mutex);
+ spider_thread->first_free_wait = FALSE;
+ pthread_cond_signal(&spider_thread->cond);
+ DBUG_PRINT("info",("spider waiting bg crd end"));
+ }
+
+ if (share->crd_prev)
+ {
+ if (share->crd_next)
+ {
+ DBUG_PRINT("info",("spider remove middle one"));
+ share->crd_prev->crd_next = share->crd_next;
+ share->crd_next->crd_prev = share->crd_prev;
+ } else {
+ DBUG_PRINT("info",("spider remove last one"));
+ share->crd_prev->crd_next = NULL;
+ spider_thread->queue_last = share->crd_prev;
+ }
+ } else if (share->crd_next) {
+ DBUG_PRINT("info",("spider remove first one"));
+ share->crd_next->crd_prev = NULL;
+ spider_thread->queue_first = share->crd_next;
+ } else {
+ DBUG_PRINT("info",("spider empty"));
+ spider_thread->queue_first = NULL;
+ spider_thread->queue_last = NULL;
+ }
+ }
+ pthread_mutex_unlock(&spider_thread->mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+#endif
diff --git a/storage/spider/spd_table.h b/storage/spider/spd_table.h
index 6140f5bbdc7..7165c4504f8 100644
--- a/storage/spider/spd_table.h
+++ b/storage/spider/spd_table.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2014 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
uchar *spider_tbl_get_key(
SPIDER_SHARE *share,
@@ -389,11 +389,20 @@ void spider_free_tmp_dbton_handler(
TABLE_LIST *spider_get_parent_table_list(
ha_spider *spider
);
+List<Index_hint> *spider_get_index_hints(
+ ha_spider *spider
+ );
st_select_lex *spider_get_select_lex(
ha_spider *spider
);
+void spider_get_select_limit_from_select_lex(
+ st_select_lex *select_lex,
+ longlong *select_limit,
+ longlong *offset_limit
+);
+
void spider_get_select_limit(
ha_spider *spider,
st_select_lex **select_lex,
@@ -421,6 +430,10 @@ bool spider_check_direct_order_limit(
ha_spider *spider
);
+int spider_set_direct_limit_offset(
+ ha_spider* spider
+ );
+
bool spider_check_index_merge(
TABLE *table,
st_select_lex *select_lex
@@ -454,3 +467,55 @@ int spider_discover_table_structure(
HA_CREATE_INFO *info
);
#endif
+
+#ifndef WITHOUT_SPIDER_BG_SEARCH
+int spider_create_spider_object_for_share(
+ SPIDER_TRX *trx,
+ SPIDER_SHARE *share,
+ ha_spider **spider
+);
+
+void spider_free_spider_object_for_share(
+ ha_spider **spider
+);
+
+int spider_create_sts_threads(
+ SPIDER_THREAD *spider_thread
+);
+
+void spider_free_sts_threads(
+ SPIDER_THREAD *spider_thread
+);
+
+int spider_create_crd_threads(
+ SPIDER_THREAD *spider_thread
+);
+
+void spider_free_crd_threads(
+ SPIDER_THREAD *spider_thread
+);
+
+void *spider_table_bg_sts_action(
+ void *arg
+);
+
+void *spider_table_bg_crd_action(
+ void *arg
+);
+
+void spider_table_add_share_to_sts_thread(
+ SPIDER_SHARE *share
+);
+
+void spider_table_add_share_to_crd_thread(
+ SPIDER_SHARE *share
+);
+
+void spider_table_remove_share_from_sts_thread(
+ SPIDER_SHARE *share
+);
+
+void spider_table_remove_share_from_crd_thread(
+ SPIDER_SHARE *share
+);
+#endif
diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc
index 1b47c8ccf3c..179156a0950 100644
--- a/storage/spider/spd_trx.cc
+++ b/storage/spider/spd_trx.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2015 Kentoku Shiba
+/* Copyright (C) 2008-2017 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,11 +11,12 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
+#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
@@ -503,6 +504,7 @@ int spider_create_trx_alter_table(
char **tmp_tgt_ssl_keys;
char **tmp_tgt_default_files;
char **tmp_tgt_default_groups;
+ char **tmp_static_link_ids;
uint *tmp_server_names_lengths;
uint *tmp_tgt_table_names_lengths;
uint *tmp_tgt_dbs_lengths;
@@ -518,8 +520,10 @@ int spider_create_trx_alter_table(
uint *tmp_tgt_ssl_keys_lengths;
uint *tmp_tgt_default_files_lengths;
uint *tmp_tgt_default_groups_lengths;
+ uint *tmp_static_link_ids_lengths;
long *tmp_tgt_ports;
long *tmp_tgt_ssl_vscs;
+ long *tmp_monitoring_binlog_pos_at_failing;
long *tmp_link_statuses;
char *tmp_server_names_char;
char *tmp_tgt_table_names_char;
@@ -536,6 +540,7 @@ int spider_create_trx_alter_table(
char *tmp_tgt_ssl_keys_char;
char *tmp_tgt_default_files_char;
char *tmp_tgt_default_groups_char;
+ char *tmp_static_link_ids_char;
uint old_elements;
DBUG_ENTER("spider_create_trx_alter_table");
@@ -561,6 +566,7 @@ int spider_create_trx_alter_table(
&tmp_tgt_ssl_keys, sizeof(char *) * share->all_link_count,
&tmp_tgt_default_files, sizeof(char *) * share->all_link_count,
&tmp_tgt_default_groups, sizeof(char *) * share->all_link_count,
+ &tmp_static_link_ids, sizeof(char *) * share->all_link_count,
&tmp_server_names_lengths, sizeof(uint) * share->all_link_count,
&tmp_tgt_table_names_lengths, sizeof(uint) * share->all_link_count,
@@ -577,9 +583,12 @@ int spider_create_trx_alter_table(
&tmp_tgt_ssl_keys_lengths, sizeof(uint) * share->all_link_count,
&tmp_tgt_default_files_lengths, sizeof(uint) * share->all_link_count,
&tmp_tgt_default_groups_lengths, sizeof(uint) * share->all_link_count,
+ &tmp_static_link_ids_lengths, sizeof(uint) * share->all_link_count,
&tmp_tgt_ports, sizeof(long) * share->all_link_count,
&tmp_tgt_ssl_vscs, sizeof(long) * share->all_link_count,
+ &tmp_monitoring_binlog_pos_at_failing,
+ sizeof(long) * share->all_link_count,
&tmp_link_statuses, sizeof(long) * share->all_link_count,
&tmp_server_names_char, sizeof(char) *
@@ -612,6 +621,8 @@ int spider_create_trx_alter_table(
(share_alter->tmp_tgt_default_files_charlen + 1),
&tmp_tgt_default_groups_char, sizeof(char) *
(share_alter->tmp_tgt_default_groups_charlen + 1),
+ &tmp_static_link_ids_char, sizeof(char) *
+ (share_alter->tmp_static_link_ids_charlen + 1),
NullS))
) {
error_num = HA_ERR_OUT_OF_MEM;
@@ -645,9 +656,12 @@ int spider_create_trx_alter_table(
alter_table->tmp_tgt_ssl_keys = tmp_tgt_ssl_keys;
alter_table->tmp_tgt_default_files = tmp_tgt_default_files;
alter_table->tmp_tgt_default_groups = tmp_tgt_default_groups;
+ alter_table->tmp_static_link_ids = tmp_static_link_ids;
alter_table->tmp_tgt_ports = tmp_tgt_ports;
alter_table->tmp_tgt_ssl_vscs = tmp_tgt_ssl_vscs;
+ alter_table->tmp_monitoring_binlog_pos_at_failing =
+ tmp_monitoring_binlog_pos_at_failing;
alter_table->tmp_link_statuses = tmp_link_statuses;
alter_table->tmp_server_names_lengths = tmp_server_names_lengths;
@@ -665,6 +679,7 @@ int spider_create_trx_alter_table(
alter_table->tmp_tgt_ssl_keys_lengths = tmp_tgt_ssl_keys_lengths;
alter_table->tmp_tgt_default_files_lengths = tmp_tgt_default_files_lengths;
alter_table->tmp_tgt_default_groups_lengths = tmp_tgt_default_groups_lengths;
+ alter_table->tmp_static_link_ids_lengths = tmp_static_link_ids_lengths;
for(roop_count = 0; roop_count < (int) share->all_link_count; roop_count++)
{
@@ -763,12 +778,25 @@ int spider_create_trx_alter_table(
sizeof(char) * share_alter->tmp_tgt_default_groups_lengths[roop_count]);
tmp_tgt_default_groups_char +=
share_alter->tmp_tgt_default_groups_lengths[roop_count] + 1;
+
+ if (share_alter->tmp_static_link_ids[roop_count])
+ {
+ tmp_static_link_ids[roop_count] = tmp_static_link_ids_char;
+ memcpy(tmp_static_link_ids_char,
+ share_alter->tmp_static_link_ids[roop_count],
+ sizeof(char) * share_alter->tmp_static_link_ids_lengths[roop_count]);
+ tmp_static_link_ids_char +=
+ share_alter->tmp_static_link_ids_lengths[roop_count] + 1;
+ }
}
memcpy(tmp_tgt_ports, share_alter->tmp_tgt_ports,
sizeof(long) * share->all_link_count);
memcpy(tmp_tgt_ssl_vscs, share_alter->tmp_tgt_ssl_vscs,
sizeof(long) * share->all_link_count);
+ memcpy(tmp_monitoring_binlog_pos_at_failing,
+ share_alter->tmp_monitoring_binlog_pos_at_failing,
+ sizeof(long) * share->all_link_count);
memcpy(tmp_link_statuses, share_alter->tmp_link_statuses,
sizeof(long) * share->all_link_count);
@@ -804,6 +832,9 @@ int spider_create_trx_alter_table(
memcpy(tmp_tgt_default_groups_lengths,
share_alter->tmp_tgt_default_groups_lengths,
sizeof(uint) * share->all_link_count);
+ memcpy(tmp_static_link_ids_lengths,
+ share_alter->tmp_static_link_ids_lengths,
+ sizeof(uint) * share->all_link_count);
alter_table->tmp_server_names_length =
share_alter->tmp_server_names_length;
@@ -835,10 +866,14 @@ int spider_create_trx_alter_table(
share_alter->tmp_tgt_default_files_length;
alter_table->tmp_tgt_default_groups_length =
share_alter->tmp_tgt_default_groups_length;
+ alter_table->tmp_static_link_ids_length =
+ share_alter->tmp_static_link_ids_length;
alter_table->tmp_tgt_ports_length =
share_alter->tmp_tgt_ports_length;
alter_table->tmp_tgt_ssl_vscs_length =
share_alter->tmp_tgt_ssl_vscs_length;
+ alter_table->tmp_monitoring_binlog_pos_at_failing_length =
+ share_alter->tmp_monitoring_binlog_pos_at_failing_length;
alter_table->tmp_link_statuses_length =
share_alter->tmp_link_statuses_length;
@@ -1034,9 +1069,21 @@ bool spider_cmp_trx_alter_table(
cmp2->tmp_tgt_default_groups[roop_count])
)
) ||
+ (
+ cmp1->tmp_static_link_ids[roop_count] !=
+ cmp2->tmp_static_link_ids[roop_count] &&
+ (
+ !cmp1->tmp_static_link_ids[roop_count] ||
+ !cmp2->tmp_static_link_ids[roop_count] ||
+ strcmp(cmp1->tmp_static_link_ids[roop_count],
+ cmp2->tmp_static_link_ids[roop_count])
+ )
+ ) ||
cmp1->tmp_tgt_ports[roop_count] != cmp2->tmp_tgt_ports[roop_count] ||
cmp1->tmp_tgt_ssl_vscs[roop_count] !=
cmp2->tmp_tgt_ssl_vscs[roop_count] ||
+ cmp1->tmp_monitoring_binlog_pos_at_failing[roop_count] !=
+ cmp2->tmp_monitoring_binlog_pos_at_failing[roop_count] ||
cmp1->tmp_link_statuses[roop_count] !=
cmp2->tmp_link_statuses[roop_count]
)
@@ -1659,7 +1706,8 @@ int spider_xa_lock(
#ifdef SPIDER_XID_USES_xid_cache_iterate
if (xid_cache_insert(thd, xid_state))
{
- error_num = my_errno;
+ error_num = (spider_stmt_da_sql_errno(thd) == ER_XAER_DUPID ?
+ ER_SPIDER_XA_LOCKED_NUM : HA_ERR_OUT_OF_MEM);
goto error;
}
#else
@@ -1905,6 +1953,8 @@ int spider_internal_start_trx(
}
trx->trx_start = TRUE;
trx->trx_xa_prepared = FALSE;
+ trx->updated_in_this_trx = FALSE;
+ DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
}
DBUG_PRINT("info",("spider sync_autocommit = %d", sync_autocommit));
@@ -1983,7 +2033,7 @@ int spider_internal_xa_commit(
TABLE *table_xa,
TABLE *table_xa_member
) {
- int error_num, tmp_error_num;
+ int error_num = 0, tmp_error_num;
char xa_key[MAX_KEY_LENGTH];
SPIDER_CONN *conn;
uint force_commit = spider_param_force_commit(thd);
@@ -1997,72 +2047,75 @@ int spider_internal_xa_commit(
bool table_xa_member_opened = FALSE;
DBUG_ENTER("spider_internal_xa_commit");
- /*
- select
- status
- from
- mysql.spider_xa
- where
- format_id = xid->format_id and
- gtrid_length = xid->gtrid_length and
- data = xid->data
- */
- if (
- !(table_xa = spider_open_sys_table(
- thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
- TRUE, &open_tables_backup, TRUE, &error_num))
- )
- goto error_open_table;
- table_xa_opened = TRUE;
- spider_store_xa_pk(table_xa, &trx->xid);
- if (
- (error_num = spider_check_sys_table(table_xa, xa_key))
- ) {
- if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
- {
- table_xa->file->print_error(error_num, MYF(0));
+ if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0)
+ {
+ /*
+ select
+ status
+ from
+ mysql.spider_xa
+ where
+ format_id = xid->format_id and
+ gtrid_length = xid->gtrid_length and
+ data = xid->data
+ */
+ if (
+ !(table_xa = spider_open_sys_table(
+ thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
+ TRUE, &open_tables_backup, TRUE, &error_num))
+ )
+ goto error_open_table;
+ table_xa_opened = TRUE;
+ spider_store_xa_pk(table_xa, &trx->xid);
+ if (
+ (error_num = spider_check_sys_table(table_xa, xa_key))
+ ) {
+ if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
+ {
+ table_xa->file->print_error(error_num, MYF(0));
+ goto error;
+ }
+ my_message(ER_SPIDER_XA_NOT_EXISTS_NUM, ER_SPIDER_XA_NOT_EXISTS_STR,
+ MYF(0));
+ error_num = ER_SPIDER_XA_NOT_EXISTS_NUM;
+ goto error;
+ }
+ SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
+ if (
+ force_commit != 2 &&
+ (error_num = spider_check_sys_xa_status(
+ table_xa,
+ SPIDER_SYS_XA_PREPARED_STR,
+ SPIDER_SYS_XA_COMMIT_STR,
+ NULL,
+ ER_SPIDER_XA_NOT_PREPARED_NUM,
+ &mem_root))
+ ) {
+ free_root(&mem_root, MYF(0));
+ if (error_num == ER_SPIDER_XA_NOT_PREPARED_NUM)
+ my_message(error_num, ER_SPIDER_XA_NOT_PREPARED_STR, MYF(0));
goto error;
}
- my_message(ER_SPIDER_XA_NOT_EXISTS_NUM, ER_SPIDER_XA_NOT_EXISTS_STR,
- MYF(0));
- error_num = ER_SPIDER_XA_NOT_EXISTS_NUM;
- goto error;
- }
- SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
- if (
- force_commit != 2 &&
- (error_num = spider_check_sys_xa_status(
- table_xa,
- SPIDER_SYS_XA_PREPARED_STR,
- SPIDER_SYS_XA_COMMIT_STR,
- NULL,
- ER_SPIDER_XA_NOT_PREPARED_NUM,
- &mem_root))
- ) {
free_root(&mem_root, MYF(0));
- if (error_num == ER_SPIDER_XA_NOT_PREPARED_NUM)
- my_message(error_num, ER_SPIDER_XA_NOT_PREPARED_STR, MYF(0));
- goto error;
- }
- free_root(&mem_root, MYF(0));
- /*
- update
- mysql.spider_xa
- set
- status = 'COMMIT'
- where
- format_id = trx->xid.format_id and
- gtrid_length = trx->xid.gtrid_length and
- data = trx->xid.data
- */
- if (
- (error_num = spider_update_xa(
- table_xa, &trx->xid, SPIDER_SYS_XA_COMMIT_STR))
- )
- goto error;
- spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
- table_xa_opened = FALSE;
+ /*
+ update
+ mysql.spider_xa
+ set
+ status = 'COMMIT'
+ where
+ format_id = trx->xid.format_id and
+ gtrid_length = trx->xid.gtrid_length and
+ data = trx->xid.data
+ */
+ if (
+ (error_num = spider_update_xa(
+ table_xa, &trx->xid, SPIDER_SYS_XA_COMMIT_STR))
+ )
+ goto error;
+ spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
+ table_xa_opened = FALSE;
+ }
SPIDER_BACKUP_DASTATUS;
if ((conn = spider_tree_first(trx->join_trx_top)))
@@ -2100,46 +2153,49 @@ int spider_internal_xa_commit(
if (error_num)
goto error_in_commit;
- /*
- delete from
- mysql.spider_xa_member
- where
- format_id = xid->format_id and
- gtrid_length = xid->gtrid_length and
- data = xid->data
- */
- if (
- !(table_xa_member = spider_open_sys_table(
- thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
- SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
- &error_num))
- )
- goto error_open_table;
- table_xa_member_opened = TRUE;
- if ((error_num = spider_delete_xa_member(table_xa_member, &trx->xid)))
- goto error;
- spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
- table_xa_member_opened = FALSE;
+ if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0)
+ {
+ /*
+ delete from
+ mysql.spider_xa_member
+ where
+ format_id = xid->format_id and
+ gtrid_length = xid->gtrid_length and
+ data = xid->data
+ */
+ if (
+ !(table_xa_member = spider_open_sys_table(
+ thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
+ SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
+ &error_num))
+ )
+ goto error_open_table;
+ table_xa_member_opened = TRUE;
+ if ((error_num = spider_delete_xa_member(table_xa_member, &trx->xid)))
+ goto error;
+ spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
+ table_xa_member_opened = FALSE;
- /*
- delete from
- mysql.spider_xa
- where
- format_id = xid->format_id and
- gtrid_length = xid->gtrid_length and
- data = xid->data
- */
- if (
- !(table_xa = spider_open_sys_table(
- thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
- TRUE, &open_tables_backup, TRUE, &error_num))
- )
- goto error_open_table;
- table_xa_opened = TRUE;
- if ((error_num = spider_delete_xa(table_xa, &trx->xid)))
- goto error;
- spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
- table_xa_opened = FALSE;
+ /*
+ delete from
+ mysql.spider_xa
+ where
+ format_id = xid->format_id and
+ gtrid_length = xid->gtrid_length and
+ data = xid->data
+ */
+ if (
+ !(table_xa = spider_open_sys_table(
+ thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
+ TRUE, &open_tables_backup, TRUE, &error_num))
+ )
+ goto error_open_table;
+ table_xa_opened = TRUE;
+ if ((error_num = spider_delete_xa(table_xa, &trx->xid)))
+ goto error;
+ spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
+ table_xa_opened = FALSE;
+ }
spider_xa_unlock(&trx->internal_xid_state);
trx->internal_xid_state.xa_state = XA_NOTR;
DBUG_RETURN(0);
@@ -2176,8 +2232,13 @@ int spider_internal_xa_rollback(
bool table_xa_member_opened = FALSE;
DBUG_ENTER("spider_internal_xa_rollback");
- if (trx->trx_xa_prepared)
- {
+ if (
+ trx->trx_xa_prepared &&
+ (
+ trx->updated_in_this_trx ||
+ spider_param_xa_register_mode(thd) == 0
+ )
+ ) {
/*
select
status
@@ -2326,7 +2387,11 @@ int spider_internal_xa_rollback(
if (
trx->trx_xa_prepared &&
- !server_lost
+ !server_lost &&
+ (
+ trx->updated_in_this_trx ||
+ spider_param_xa_register_mode(thd) == 0
+ )
) {
/*
delete from
@@ -2403,35 +2468,38 @@ int spider_internal_xa_prepare(
bool table_xa_opened = FALSE;
bool table_xa_member_opened = FALSE;
DBUG_ENTER("spider_internal_xa_prepare");
- /*
- insert into mysql.spider_xa
- (format_id, gtrid_length, bqual_length, data, status) values
- (trx->xid.format_id, trx->xid.gtrid_length, trx->xid.bqual_length,
- trx->xid.data, 'NOT YET')
- */
- if (
- !(table_xa = spider_open_sys_table(
- thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
- TRUE, &open_tables_backup, TRUE, &error_num))
- )
- goto error_open_table;
- table_xa_opened = TRUE;
- if (
- (error_num = spider_insert_xa(
- table_xa, &trx->xid, SPIDER_SYS_XA_NOT_YET_STR))
- )
- goto error;
- spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
- table_xa_opened = FALSE;
+ if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0)
+ {
+ /*
+ insert into mysql.spider_xa
+ (format_id, gtrid_length, bqual_length, data, status) values
+ (trx->xid.format_id, trx->xid.gtrid_length, trx->xid.bqual_length,
+ trx->xid.data, 'NOT YET')
+ */
+ if (
+ !(table_xa = spider_open_sys_table(
+ thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
+ TRUE, &open_tables_backup, TRUE, &error_num))
+ )
+ goto error_open_table;
+ table_xa_opened = TRUE;
+ if (
+ (error_num = spider_insert_xa(
+ table_xa, &trx->xid, SPIDER_SYS_XA_NOT_YET_STR))
+ )
+ goto error;
+ spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
+ table_xa_opened = FALSE;
- if (
- !(table_xa_member = spider_open_sys_table(
- thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
- SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
- &error_num))
- )
- goto error_open_table;
- table_xa_member_opened = TRUE;
+ if (
+ !(table_xa_member = spider_open_sys_table(
+ thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
+ SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
+ &error_num))
+ )
+ goto error_open_table;
+ table_xa_member_opened = TRUE;
+ }
SPIDER_BACKUP_DASTATUS;
if ((conn = spider_tree_first(trx->join_trx_top)))
{
@@ -2457,26 +2525,29 @@ int spider_internal_xa_prepare(
}
conn->join_trx = 0;
} else {
- /*
- insert into mysql.spider_xa_member
- (format_id, gtrid_length, bqual_length, data,
- scheme, host, port, socket, username, password) values
- (trx->xid.format_id, trx->xid.gtrid_length,
- trx->xid.bqual_length, trx->xid.data,
- conn->tgt_wrapper,
- conn->tgt_host,
- conn->tgt_port,
- conn->tgt_socket,
- conn->tgt_username,
- conn->tgt_password)
- */
- if (
- (error_num = spider_insert_xa_member(
- table_xa_member, &trx->xid, conn))
- ) {
- SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
- if (error_num)
- goto error;
+ if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0)
+ {
+ /*
+ insert into mysql.spider_xa_member
+ (format_id, gtrid_length, bqual_length, data,
+ scheme, host, port, socket, username, password) values
+ (trx->xid.format_id, trx->xid.gtrid_length,
+ trx->xid.bqual_length, trx->xid.data,
+ conn->tgt_wrapper,
+ conn->tgt_host,
+ conn->tgt_port,
+ conn->tgt_socket,
+ conn->tgt_username,
+ conn->tgt_password)
+ */
+ if (
+ (error_num = spider_insert_xa_member(
+ table_xa_member, &trx->xid, conn))
+ ) {
+ SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
+ if (error_num)
+ goto error;
+ }
}
if ((error_num = spider_db_xa_end(conn, &trx->xid)))
@@ -2514,33 +2585,36 @@ int spider_internal_xa_prepare(
trx->join_trx_top = NULL;
*/
}
- spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
- table_xa_member_opened = FALSE;
+ if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0)
+ {
+ spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
+ table_xa_member_opened = FALSE;
- /*
- update
- mysql.spider_xa
- set
- status = 'PREPARED'
- where
- format_id = trx->xid.format_id and
- gtrid_length = trx->xid.gtrid_length and
- data = trx->xid.data
- */
- if (
- !(table_xa = spider_open_sys_table(
- thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
- TRUE, &open_tables_backup, TRUE, &error_num))
- )
- goto error_open_table;
- table_xa_opened = TRUE;
- if (
- (error_num = spider_update_xa(
- table_xa, &trx->xid, SPIDER_SYS_XA_PREPARED_STR))
- )
- goto error;
- spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
- table_xa_opened = FALSE;
+ /*
+ update
+ mysql.spider_xa
+ set
+ status = 'PREPARED'
+ where
+ format_id = trx->xid.format_id and
+ gtrid_length = trx->xid.gtrid_length and
+ data = trx->xid.data
+ */
+ if (
+ !(table_xa = spider_open_sys_table(
+ thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
+ TRUE, &open_tables_backup, TRUE, &error_num))
+ )
+ goto error_open_table;
+ table_xa_opened = TRUE;
+ if (
+ (error_num = spider_update_xa(
+ table_xa, &trx->xid, SPIDER_SYS_XA_PREPARED_STR))
+ )
+ goto error;
+ spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
+ table_xa_opened = FALSE;
+ }
if (internal_xa)
trx->internal_xid_state.xa_state = XA_PREPARED;
DBUG_RETURN(0);
@@ -2684,8 +2758,8 @@ int spider_initinal_xa_recover(
FALSE, open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
- init_read_record(read_record, thd, table_xa, NULL, NULL, TRUE, FALSE,
- FALSE);
+ SPIDER_init_read_record(read_record, thd, table_xa, NULL, NULL, TRUE,
+ FALSE, FALSE);
}
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
while ((!(read_record->read_record())) && cnt < (int) len)
@@ -3370,7 +3444,9 @@ int spider_commit(
}
}
trx->trx_start = FALSE;
+ trx->updated_in_this_trx = FALSE;
DBUG_PRINT("info",("spider trx->trx_start=FALSE"));
+ DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
}
spider_reuse_trx_ha(trx);
spider_free_trx_conn(trx, FALSE);
@@ -3441,7 +3517,9 @@ int spider_rollback(
}
}
trx->trx_start = FALSE;
+ trx->updated_in_this_trx = FALSE;
DBUG_PRINT("info",("spider trx->trx_start=FALSE"));
+ DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
}
spider_reuse_trx_ha(trx);
spider_free_trx_conn(trx, FALSE);
@@ -3712,21 +3790,14 @@ int spider_check_trx_and_get_conn(
{
TABLE *table = spider->get_table();
TABLE_SHARE *table_share = table->s;
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- char *db, *table_name;
- if (!(db = (char *)
- spider_bulk_malloc(spider_current_trx, 57, MYF(MY_WME),
- &db, table_share->db.length + 1,
- &table_name, table_share->table_name.length + 1,
- NullS))
- ) {
- my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
+ char *db = (char *) my_alloca(
+ table_share->db.length + 1 + table_share->table_name.length + 1);
+ if (!db)
+ {
+ my_error(HA_ERR_OUT_OF_MEM, MYF(0));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
-#else
- char db[table_share->db.length + 1],
- table_name[table_share->table_name.length + 1];
-#endif
+ char *table_name = db + table_share->db.length + 1;
memcpy(db, table_share->db.str, table_share->db.length);
db[table_share->db.length] = '\0';
memcpy(table_name, table_share->table_name.str,
@@ -3734,10 +3805,12 @@ int spider_check_trx_and_get_conn(
table_name[table_share->table_name.length] = '\0';
my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM,
ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name);
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(trx, db, MYF(MY_WME));
-#endif
+ my_afree(db);
DBUG_RETURN(ER_SPIDER_ALL_LINKS_FAILED_NUM);
+ } else if (search_link_idx == -2)
+ {
+ my_error(HA_ERR_OUT_OF_MEM, MYF(0));
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
spider->search_link_idx = search_link_idx;
spider->search_link_query_id = thd->query_id;
@@ -3803,6 +3876,7 @@ int spider_check_trx_and_get_conn(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3845,6 +3919,7 @@ int spider_check_trx_and_get_conn(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3871,21 +3946,14 @@ int spider_check_trx_and_get_conn(
{
TABLE *table = spider->get_table();
TABLE_SHARE *table_share = table->s;
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- char *db, *table_name;
- if (!(db = (char *)
- spider_bulk_malloc(spider_current_trx, 57, MYF(MY_WME),
- &db, table_share->db.length + 1,
- &table_name, table_share->table_name.length + 1,
- NullS))
- ) {
- my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
+ char *db = (char *) my_alloca(
+ table_share->db.length + 1 + table_share->table_name.length + 1);
+ if (!db)
+ {
+ my_error(HA_ERR_OUT_OF_MEM, MYF(0));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
-#else
- char db[table_share->db.length + 1],
- table_name[table_share->table_name.length + 1];
-#endif
+ char *table_name = db + table_share->db.length + 1;
memcpy(db, table_share->db.str, table_share->db.length);
db[table_share->db.length] = '\0';
memcpy(table_name, table_share->table_name.str,
@@ -3893,9 +3961,7 @@ int spider_check_trx_and_get_conn(
table_name[table_share->table_name.length] = '\0';
my_printf_error(ER_SPIDER_LINK_MON_JUST_NG_NUM,
ER_SPIDER_LINK_MON_JUST_NG_STR, MYF(0), db, table_name);
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(trx, db, MYF(MY_WME));
-#endif
+ my_afree(db);
DBUG_RETURN(ER_SPIDER_LINK_MON_JUST_NG_NUM);
}
} else {
@@ -3949,6 +4015,7 @@ int spider_check_trx_and_get_conn(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -3992,6 +4059,7 @@ int spider_check_trx_and_get_conn(
trx,
trx->thd,
share,
+ roop_count,
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
@@ -4017,21 +4085,14 @@ int spider_check_trx_and_get_conn(
{
TABLE *table = spider->get_table();
TABLE_SHARE *table_share = table->s;
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- char *db, *table_name;
- if (!(db = (char *)
- spider_bulk_malloc(spider_current_trx, 57, MYF(MY_WME),
- &db, table_share->db.length + 1,
- &table_name, table_share->table_name.length + 1,
- NullS))
- ) {
- my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
+ char *db = (char *) my_alloca(
+ table_share->db.length + 1 + table_share->table_name.length + 1);
+ if (!db)
+ {
+ my_error(HA_ERR_OUT_OF_MEM, MYF(0));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
-#else
- char db[table_share->db.length + 1],
- table_name[table_share->table_name.length + 1];
-#endif
+ char *table_name = db + table_share->db.length + 1;
memcpy(db, table_share->db.str, table_share->db.length);
db[table_share->db.length] = '\0';
memcpy(table_name, table_share->table_name.str,
@@ -4039,9 +4100,7 @@ int spider_check_trx_and_get_conn(
table_name[table_share->table_name.length] = '\0';
my_printf_error(ER_SPIDER_LINK_MON_JUST_NG_NUM,
ER_SPIDER_LINK_MON_JUST_NG_STR, MYF(0), db, table_name);
-#if defined(_MSC_VER) || defined(__SUNPRO_CC)
- spider_free(trx, db, MYF(MY_WME));
-#endif
+ my_afree(db);
DBUG_RETURN(ER_SPIDER_LINK_MON_JUST_NG_NUM);
}
}
@@ -4056,7 +4115,7 @@ THD *spider_create_tmp_thd()
{
THD *thd;
DBUG_ENTER("spider_create_tmp_thd");
- if (!(thd = new THD(0)))
+ if (!(thd = SPIDER_new_THD((my_thread_id) 0)))
DBUG_RETURN(NULL);
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000
thd->killed = NOT_KILLED;
@@ -4067,6 +4126,10 @@ THD *spider_create_tmp_thd()
thd->locked_tables = FALSE;
#endif
thd->proc_info = "";
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100200
+#else
+ thd->thread_id = thd->variables.pseudo_thread_id = 0;
+#endif
thd->thread_stack = (char*) &thd;
if (thd->store_globals())
DBUG_RETURN(NULL);
diff --git a/storage/spider/spd_trx.h b/storage/spider/spd_trx.h
index b4abecf457f..3f3ca7fabed 100644
--- a/storage/spider/spd_trx.h
+++ b/storage/spider/spd_trx.h
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
int spider_free_trx_conn(
SPIDER_TRX *trx,
diff --git a/storage/spider/spd_udf.cc b/storage/spider/spd_udf.cc
index 8381121aaab..17498fbd8de 100644
--- a/storage/spider/spd_udf.cc
+++ b/storage/spider/spd_udf.cc
@@ -11,10 +11,11 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
+#include "spd_environ.h"
#include "mysql.h"
#include "spd_udf.h"
diff --git a/storage/spider/spd_udf.h b/storage/spider/spd_udf.h
index 30a2d6699d1..0b20a10393e 100644
--- a/storage/spider/spd_udf.h
+++ b/storage/spider/spd_udf.h
@@ -11,7 +11,7 @@
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 02111-1301 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
long long spider_direct_sql_body(
UDF_INIT *initid,
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index b0ed6e41188..aa5949b4860 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -1,14 +1,24 @@
-SET(TOKUDB_VERSION 5.6.37-82.2)
+SET(TOKUDB_VERSION 5.6.38-83.0)
# PerconaFT only supports x86-64 and cmake-2.8.9+
IF(CMAKE_VERSION VERSION_LESS "2.8.9")
MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB")
+ELSEIF(NOT HAVE_DLOPEN)
+ MESSAGE(STATUS "dlopen is required by TokuDB")
+ELSEIF(NOT TARGET perfschema)
+ MESSAGE(STATUS "Performance Schema is required by TokuDB")
ELSEIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR
CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64")
+# tokudb requires F_NOCACHE or O_DIRECT, and designated initializers
CHECK_CXX_SOURCE_COMPILES(
"
+#include <fcntl.h>
struct a {int b; int c; };
struct a d = { .b=1, .c=2 };
+#if defined(O_DIRECT) || defined(F_NOCACHE)
int main() { return 0; }
+#else
+#error
+#endif
" TOKUDB_OK)
ENDIF()
diff --git a/storage/tokudb/PerconaFT/CMakeLists.txt b/storage/tokudb/PerconaFT/CMakeLists.txt
index 1c9052c2a55..5c6d938808e 100644
--- a/storage/tokudb/PerconaFT/CMakeLists.txt
+++ b/storage/tokudb/PerconaFT/CMakeLists.txt
@@ -12,9 +12,14 @@ set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
# detect when we are being built as a subproject
if (DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
add_definitions( -DMYSQL_TOKUDB_ENGINE=1)
+ # Extended PFS instrumentation:
+ # -DTOKU_PFS_MUTEX_EXTENDED_CACHETABLEMMUTEX=1
+ if (WITH_PERFSCHEMA_STORAGE_ENGINE)
+ add_definitions(-DTOKU_MYSQL_WITH_PFS)
+ endif ()
+ include_directories(${CMAKE_SOURCE_DIR}/include)
if ((CMAKE_BUILD_TYPE MATCHES "Debug") AND
(CMAKE_CXX_FLAGS_DEBUG MATCHES " -DENABLED_DEBUG_SYNC"))
- include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/sql)
endif ()
endif ()
diff --git a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
index 0fa876f2bd8..95d6207edda 100644
--- a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
+++ b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
@@ -445,14 +445,15 @@ static void print_db_key_range_struct (void) {
sort_and_dump_fields("db_key_range", false, NULL);
}
-static void print_db_lsn_struct (void) {
- field_counter=0;
- /* A dummy field to make sizeof(DB_LSN) equal in C and C++ */
- const char *extra[] = { "char dummy", NULL };
- sort_and_dump_fields("db_lsn", false, extra);
+static void print_db_lsn_struct(void) {
+ field_counter = 0;
+ // FT-692
+ STRUCT_SETUP(DB_LSN, file, "uint32_t %s");
+ STRUCT_SETUP(DB_LSN, offset, "uint32_t %s");
+ sort_and_dump_fields("db_lsn", false, NULL);
}
-static void print_dbt_struct (void) {
+static void print_dbt_struct(void) {
field_counter=0;
#if 0 && DB_VERSION_MAJOR==4 && DB_VERSION_MINOR==1
STRUCT_SETUP(DBT, app_private, "void*%s");
diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
index 0cd9a9c5941..385723aebc7 100644
--- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
+++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
@@ -53,7 +53,13 @@ macro(set_cflags_if_supported)
endforeach(flag)
endmacro(set_cflags_if_supported)
+if (NOT DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
+ set (OPTIONAL_CFLAGS "${OPTIONAL_CFLAGS} -Wmissing-format-attribute")
+endif()
+
## disable some warnings
+## missing-format-attribute causes warnings in some MySQL include files
+## if the library is built as a part of TokuDB MySQL storage engine
set_cflags_if_supported(
-Wno-missing-field-initializers
-Wstrict-null-sentinel
@@ -61,7 +67,7 @@ set_cflags_if_supported(
-Wswitch
-Wtrampolines
-Wlogical-op
- -Wmissing-format-attribute
+ ${OPTIONAL_CFLAGS}
-Wno-error=missing-format-attribute
-Wno-error=address-of-array-temporary
-Wno-error=tautological-constant-out-of-range-compare
@@ -143,8 +149,8 @@ set_cflags_if_supported(
-Wmissing-prototypes
-Wmissing-declarations
-Wpointer-arith
- -Wmissing-format-attribute
-Wshadow
+ ${OPTIONAL_CFLAGS}
## other flags to try:
#-Wunsafe-loop-optimizations
#-Wpointer-arith
diff --git a/storage/tokudb/PerconaFT/ft/cachetable/background_job_manager.cc b/storage/tokudb/PerconaFT/ft/cachetable/background_job_manager.cc
index 9119a49b081..c109185f973 100644
--- a/storage/tokudb/PerconaFT/ft/cachetable/background_job_manager.cc
+++ b/storage/tokudb/PerconaFT/ft/cachetable/background_job_manager.cc
@@ -42,6 +42,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "cachetable/background_job_manager.h"
+toku_instr_key *bjm_jobs_lock_mutex_key;
+toku_instr_key *bjm_jobs_wait_key;
+
struct background_job_manager_struct {
bool accepting_jobs;
uint32_t num_jobs;
@@ -49,10 +52,10 @@ struct background_job_manager_struct {
toku_mutex_t jobs_lock;
};
-void bjm_init(BACKGROUND_JOB_MANAGER* pbjm) {
+void bjm_init(BACKGROUND_JOB_MANAGER *pbjm) {
BACKGROUND_JOB_MANAGER XCALLOC(bjm);
- toku_mutex_init(&bjm->jobs_lock, 0);
- toku_cond_init(&bjm->jobs_wait, NULL);
+ toku_mutex_init(*bjm_jobs_lock_mutex_key, &bjm->jobs_lock, nullptr);
+ toku_cond_init(*bjm_jobs_wait_key, &bjm->jobs_wait, nullptr);
bjm->accepting_jobs = true;
bjm->num_jobs = 0;
*pbjm = bjm;
diff --git a/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc b/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
index 54ef11eb1eb..b72edc8d231 100644
--- a/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
+++ b/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
@@ -58,6 +58,25 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/status.h"
#include "util/context.h"
+toku_instr_key *cachetable_m_mutex_key;
+toku_instr_key *cachetable_ev_thread_lock_mutex_key;
+
+toku_instr_key *cachetable_m_list_lock_key;
+toku_instr_key *cachetable_m_pending_lock_expensive_key;
+toku_instr_key *cachetable_m_pending_lock_cheap_key;
+toku_instr_key *cachetable_m_lock_key;
+
+toku_instr_key *cachetable_value_key;
+toku_instr_key *cachetable_disk_nb_rwlock_key;
+
+toku_instr_key *cachetable_p_refcount_wait_key;
+toku_instr_key *cachetable_m_flow_control_cond_key;
+toku_instr_key *cachetable_m_ev_thread_cond_key;
+
+toku_instr_key *cachetable_disk_nb_mutex_key;
+toku_instr_key *log_internal_lock_mutex_key;
+toku_instr_key *eviction_thread_key;
+
///////////////////////////////////////////////////////////////////////////////////
// Engine status
//
@@ -780,18 +799,25 @@ void pair_init(PAIR p,
p->checkpoint_complete_callback = write_callback.checkpoint_complete_callback;
p->write_extraargs = write_callback.write_extraargs;
- p->count = 0; // <CER> Is zero the correct init value?
+ p->count = 0; // <CER> Is zero the correct init value?
p->refcount = 0;
p->num_waiting_on_refs = 0;
- toku_cond_init(&p->refcount_wait, NULL);
+ toku_cond_init(*cachetable_p_refcount_wait_key, &p->refcount_wait, nullptr);
p->checkpoint_pending = false;
p->mutex = list->get_mutex_for_pair(fullhash);
assert(p->mutex);
- p->value_rwlock.init(p->mutex);
- nb_mutex_init(&p->disk_nb_mutex);
+ p->value_rwlock.init(p->mutex
+#ifdef TOKU_MYSQL_WITH_PFS
+ ,
+ *cachetable_value_key
+#endif
+ );
+ nb_mutex_init(*cachetable_disk_nb_mutex_key,
+ *cachetable_disk_nb_rwlock_key,
+ &p->disk_nb_mutex);
- p->size_evicting_estimate = 0; // <CER> Is zero the correct init value?
+ p->size_evicting_estimate = 0; // <CER> Is zero the correct init value?
p->ev = ev;
p->list = list;
@@ -3230,16 +3256,26 @@ void pair_list::init() {
#if defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP)
pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
#else
- // TODO: need to figure out how to make writer-preferential rwlocks
- // happen on osx
+// TODO: need to figure out how to make writer-preferential rwlocks
+// happen on osx
#endif
- toku_pthread_rwlock_init(&m_list_lock, &attr);
- toku_pthread_rwlock_init(&m_pending_lock_expensive, &attr);
- toku_pthread_rwlock_init(&m_pending_lock_cheap, &attr);
+ toku_pthread_rwlock_init(*cachetable_m_list_lock_key, &m_list_lock, &attr);
+ toku_pthread_rwlock_init(*cachetable_m_pending_lock_expensive_key,
+ &m_pending_lock_expensive,
+ &attr);
+ toku_pthread_rwlock_init(
+ *cachetable_m_pending_lock_cheap_key, &m_pending_lock_cheap, &attr);
XCALLOC_N(m_table_size, m_table);
XCALLOC_N(m_num_locks, m_mutexes);
for (uint64_t i = 0; i < m_num_locks; i++) {
- toku_mutex_init(&m_mutexes[i].aligned_mutex, NULL);
+ toku_mutex_init(
+#ifdef TOKU_PFS_MUTEX_EXTENDED_CACHETABLEMMUTEX
+ *cachetable_m_mutex_key,
+#else
+ toku_uninstrumented,
+#endif
+ &m_mutexes[i].aligned_mutex,
+ nullptr);
}
}
@@ -3579,9 +3615,9 @@ ENSURE_POD(evictor);
// This is the function that runs eviction on its own thread.
//
static void *eviction_thread(void *evictor_v) {
- evictor* CAST_FROM_VOIDP(evictor, evictor_v);
+ evictor *CAST_FROM_VOIDP(evictor, evictor_v);
evictor->run_eviction_thread();
- return evictor_v;
+ return toku_pthread_done(evictor_v);
}
//
@@ -3630,11 +3666,14 @@ int evictor::init(long _size_limit, pair_list* _pl, cachefile_list* _cf_list, KI
m_pl = _pl;
m_cf_list = _cf_list;
- m_kibbutz = _kibbutz;
- toku_mutex_init(&m_ev_thread_lock, NULL);
- toku_cond_init(&m_flow_control_cond, NULL);
- toku_cond_init(&m_ev_thread_cond, NULL);
- m_num_sleepers = 0;
+ m_kibbutz = _kibbutz;
+ toku_mutex_init(
+ *cachetable_ev_thread_lock_mutex_key, &m_ev_thread_lock, nullptr);
+ toku_cond_init(
+ *cachetable_m_flow_control_cond_key, &m_flow_control_cond, nullptr);
+ toku_cond_init(
+ *cachetable_m_ev_thread_cond_key, &m_ev_thread_cond, nullptr);
+ m_num_sleepers = 0;
m_ev_thread_is_running = false;
m_period_in_seconds = eviction_period;
@@ -3642,11 +3681,12 @@ int evictor::init(long _size_limit, pair_list* _pl, cachefile_list* _cf_list, KI
int r = myinitstate_r(seed, m_random_statebuf, sizeof m_random_statebuf, &m_random_data);
assert_zero(r);
- // start the background thread
+ // start the background thread
m_run_thread = true;
m_num_eviction_thread_runs = 0;
m_ev_thread_init = false;
- r = toku_pthread_create(&m_ev_thread, NULL, eviction_thread, this);
+ r = toku_pthread_create(
+ *eviction_thread_key, &m_ev_thread, nullptr, eviction_thread, this);
if (r == 0) {
m_ev_thread_init = true;
}
@@ -4703,7 +4743,7 @@ static_assert(std::is_pod<cachefile_list>::value, "cachefile_list isn't POD");
void cachefile_list::init() {
m_next_filenum_to_use.fileid = 0;
m_next_hash_id_to_use = 0;
- toku_pthread_rwlock_init(&m_lock, NULL);
+ toku_pthread_rwlock_init(*cachetable_m_lock_key, &m_lock, nullptr);
m_active_filenum.create();
m_active_fileid.create();
m_stale_fileid.create();
diff --git a/storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc b/storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc
index 4d54962fe9c..aad018f4097 100644
--- a/storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc
@@ -87,8 +87,16 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/frwlock.h"
#include "util/status.h"
-void
-toku_checkpoint_get_status(CACHETABLE ct, CHECKPOINT_STATUS statp) {
+toku_instr_key *checkpoint_safe_mutex_key;
+toku_instr_key *checkpoint_safe_rwlock_key;
+toku_instr_key *multi_operation_lock_key;
+toku_instr_key *low_priority_multi_operation_lock_key;
+
+toku_instr_key *rwlock_cond_key;
+toku_instr_key *rwlock_wait_read_key;
+toku_instr_key *rwlock_wait_write_key;
+
+void toku_checkpoint_get_status(CACHETABLE ct, CHECKPOINT_STATUS statp) {
cp_status.init();
CP_STATUS_VAL(CP_PERIOD) = toku_get_checkpoint_period_unlocked(ct);
*statp = cp_status;
@@ -117,11 +125,14 @@ multi_operation_lock_init(void) {
#if defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP)
pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
#else
- // TODO: need to figure out how to make writer-preferential rwlocks
- // happen on osx
+// TODO: need to figure out how to make writer-preferential rwlocks
+// happen on osx
#endif
- toku_pthread_rwlock_init(&multi_operation_lock, &attr);
- toku_pthread_rwlock_init(&low_priority_multi_operation_lock, &attr);
+ toku_pthread_rwlock_init(
+ *multi_operation_lock_key, &multi_operation_lock, &attr);
+ toku_pthread_rwlock_init(*low_priority_multi_operation_lock_key,
+ &low_priority_multi_operation_lock,
+ &attr);
pthread_rwlockattr_destroy(&attr);
locked_mo = false;
}
@@ -146,10 +157,15 @@ multi_operation_checkpoint_unlock(void) {
toku_pthread_rwlock_wrunlock(&low_priority_multi_operation_lock);
}
-static void
-checkpoint_safe_lock_init(void) {
- toku_mutex_init(&checkpoint_safe_mutex, NULL);
- checkpoint_safe_lock.init(&checkpoint_safe_mutex);
+static void checkpoint_safe_lock_init(void) {
+ toku_mutex_init(
+ *checkpoint_safe_mutex_key, &checkpoint_safe_mutex, nullptr);
+ checkpoint_safe_lock.init(&checkpoint_safe_mutex
+#ifdef TOKU_MYSQL_WITH_PFS
+ ,
+ *checkpoint_safe_rwlock_key
+#endif
+ );
locked_cs = false;
}
diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.cc b/storage/tokudb/PerconaFT/ft/ft-ops.cc
index 20035b1d02f..ef2009db1b1 100644
--- a/storage/tokudb/PerconaFT/ft/ft-ops.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-ops.cc
@@ -187,9 +187,35 @@ basement nodes, bulk fetch, and partial fetch:
*/
static toku_mutex_t ft_open_close_lock;
-
-void
-toku_ft_get_status(FT_STATUS s) {
+static toku_instr_key *ft_open_close_lock_mutex_key;
+// FIXME: the instrumentation keys below are defined here even though they
+// belong to other modules, because they are registered here. If desired, they
+// can be moved to their proper modules and registration done there in a
+// one-time init function
+// locktree
+toku_instr_key *treenode_mutex_key;
+toku_instr_key *manager_mutex_key;
+toku_instr_key *manager_escalation_mutex_key;
+toku_instr_key *manager_escalator_mutex_key;
+// src
+toku_instr_key *db_txn_struct_i_txn_mutex_key;
+toku_instr_key *indexer_i_indexer_lock_mutex_key;
+toku_instr_key *indexer_i_indexer_estimate_lock_mutex_key;
+toku_instr_key *result_i_open_dbs_rwlock_key;
+// locktree
+toku_instr_key *lock_request_m_wait_cond_key;
+toku_instr_key *manager_m_escalator_done_key;
+toku_instr_key *locktree_request_info_mutex_key;
+toku_instr_key *locktree_request_info_retry_mutex_key;
+toku_instr_key *locktree_request_info_retry_cv_key;
+
+// this is a sample probe for custom instrumentation
+static toku_instr_key *fti_probe_1_key;
+
+// This is a sample probe for custom instrumentation
+toku_instr_probe *toku_instr_probe_1;
+
+void toku_ft_get_status(FT_STATUS s) {
ft_status.init();
*s = ft_status;
@@ -2644,11 +2670,14 @@ void toku_ft_set_direct_io (bool direct_io_on) {
use_direct_io = direct_io_on;
}
-static inline int ft_open_maybe_direct(const char *filename, int oflag, int mode) {
+static inline int ft_open_maybe_direct(const char *filename,
+ int oflag,
+ int mode) {
if (use_direct_io) {
- return toku_os_open_direct(filename, oflag, mode);
+ return toku_os_open_direct(
+ filename, oflag, mode, *tokudb_file_data_key);
} else {
- return toku_os_open(filename, oflag, mode);
+ return toku_os_open(filename, oflag, mode, *tokudb_file_data_key);
}
}
@@ -2722,7 +2751,7 @@ bool toku_create_subdirs_if_needed(const char *path) {
if (!subdir.get())
return true;
- if (toku_stat(subdir.get(), &stat) == -1) {
+ if (toku_stat(subdir.get(), &stat, toku_uninstrumented) == -1) {
if (ENOENT == get_error_errno())
subdir_exists = false;
else
@@ -2934,6 +2963,8 @@ ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only
CACHEFILE cf = NULL;
FT ft = NULL;
bool did_create = false;
+ bool was_already_open = false;
+
toku_ft_open_close_lock();
if (ft_h->did_set_flags) {
@@ -2945,7 +2976,6 @@ ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only
FILENUM reserved_filenum;
reserved_filenum = use_filenum;
fname_in_cwd = toku_cachetable_get_fname_in_cwd(cachetable, fname_in_env);
- bool was_already_open;
{
int fd = -1;
r = ft_open_file(fname_in_cwd, &fd);
@@ -4615,20 +4645,265 @@ int toku_dump_ft(FILE *f, FT_HANDLE ft_handle) {
return toku_dump_ftnode(f, ft_handle, root_key, 0, 0, 0);
}
+
+static void toku_pfs_keys_init(const char *toku_instr_group_name) {
+ kibbutz_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name, "kibbutz_mutex");
+ minicron_p_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "minicron_p_mutex");
+ queue_result_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "queue_result_mutex");
+ tpool_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "tpool_lock_mutex");
+ workset_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "workset_lock_mutex");
+ bjm_jobs_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "bjm_jobs_lock_mutex");
+ log_internal_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "log_internal_lock_mutex");
+ cachetable_ev_thread_lock_mutex_key =
+ new toku_instr_key(toku_instr_object_type::mutex,
+ toku_instr_group_name,
+ "cachetable_ev_thread_lock_mutex");
+ cachetable_disk_nb_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "cachetable_disk_nb_mutex");
+ safe_file_size_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "safe_file_size_lock_mutex");
+ cachetable_m_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "cachetable_m_mutex_key");
+ checkpoint_safe_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "checkpoint_safe_mutex");
+ ft_ref_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "ft_ref_lock_mutex");
+ ft_open_close_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "ft_open_close_lock_mutex");
+ loader_error_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "loader_error_mutex");
+ bfs_mutex_key =
+ new toku_instr_key(toku_instr_object_type::mutex, toku_instr_group_name,
+ "bfs_mutex");
+ loader_bl_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "loader_bl_mutex");
+ loader_fi_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "loader_fi_lock_mutex");
+ loader_out_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "loader_out_mutex");
+ result_output_condition_lock_mutex_key =
+ new toku_instr_key(toku_instr_object_type::mutex,
+ toku_instr_group_name,
+ "result_output_condition_lock_mutex");
+ block_table_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "block_table_mutex");
+ rollback_log_node_cache_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "rollback_log_node_cache_mutex");
+ txn_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name, "txn_lock_mutex");
+ txn_state_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "txn_state_lock_mutex");
+ txn_child_manager_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "txn_child_manager_mutex");
+ txn_manager_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "txn_manager_lock_mutex");
+ treenode_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name, "treenode_mutex");
+ locktree_request_info_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "locktree_request_info_mutex");
+ locktree_request_info_retry_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "locktree_request_info_retry_mutex_key");
+ manager_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name, "manager_mutex");
+ manager_escalation_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "manager_escalation_mutex");
+ db_txn_struct_i_txn_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "db_txn_struct_i_txn_mutex");
+ manager_escalator_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "manager_escalator_mutex");
+ indexer_i_indexer_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "indexer_i_indexer_lock_mutex");
+ indexer_i_indexer_estimate_lock_mutex_key =
+ new toku_instr_key(toku_instr_object_type::mutex,
+ toku_instr_group_name,
+ "indexer_i_indexer_estimate_lock_mutex");
+
+ tokudb_file_data_key = new toku_instr_key(
+ toku_instr_object_type::file, toku_instr_group_name, "tokudb_data_file");
+ tokudb_file_load_key = new toku_instr_key(
+ toku_instr_object_type::file, toku_instr_group_name, "tokudb_load_file");
+ tokudb_file_tmp_key = new toku_instr_key(
+ toku_instr_object_type::file, toku_instr_group_name, "tokudb_tmp_file");
+ tokudb_file_log_key = new toku_instr_key(
+ toku_instr_object_type::file, toku_instr_group_name, "tokudb_log_file");
+
+ fti_probe_1_key =
+ new toku_instr_key(toku_instr_object_type::mutex, toku_instr_group_name,
+ "fti_probe_1");
+
+ extractor_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name,
+ "extractor_thread");
+ fractal_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name, "fractal_thread");
+ io_thread_key =
+ new toku_instr_key(toku_instr_object_type::thread, toku_instr_group_name,
+ "io_thread");
+ eviction_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name,
+ "eviction_thread");
+ kibbutz_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name, "kibbutz_thread");
+ minicron_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name,
+ "minicron_thread");
+ tp_internal_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name,
+ "tp_internal_thread");
+
+ result_state_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "result_state_cond");
+ bjm_jobs_wait_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name, "bjm_jobs_wait");
+ cachetable_p_refcount_wait_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "cachetable_p_refcount_wait");
+ cachetable_m_flow_control_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "cachetable_m_flow_control_cond");
+ cachetable_m_ev_thread_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "cachetable_m_ev_thread_cond");
+ bfs_cond_key =
+ new toku_instr_key(toku_instr_object_type::cond, toku_instr_group_name,
+ "bfs_cond");
+ result_output_condition_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "result_output_condition");
+ manager_m_escalator_done_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "manager_m_escalator_done");
+ lock_request_m_wait_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "lock_request_m_wait_cond");
+ queue_result_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "queue_result_cond");
+ ws_worker_wait_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name, "ws_worker_wait");
+ rwlock_wait_read_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name, "rwlock_wait_read");
+ rwlock_wait_write_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "rwlock_wait_write");
+ rwlock_cond_key =
+ new toku_instr_key(toku_instr_object_type::cond, toku_instr_group_name,
+ "rwlock_cond");
+ tp_thread_wait_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name, "tp_thread_wait");
+ tp_pool_wait_free_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "tp_pool_wait_free");
+ frwlock_m_wait_read_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "frwlock_m_wait_read");
+ kibbutz_k_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name, "kibbutz_k_cond");
+ minicron_p_condvar_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "minicron_p_condvar");
+ locktree_request_info_retry_cv_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "locktree_request_info_retry_cv_key");
+
+ multi_operation_lock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "multi_operation_lock");
+ low_priority_multi_operation_lock_key =
+ new toku_instr_key(toku_instr_object_type::rwlock,
+ toku_instr_group_name,
+ "low_priority_multi_operation_lock");
+ cachetable_m_list_lock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "cachetable_m_list_lock");
+ cachetable_m_pending_lock_expensive_key =
+ new toku_instr_key(toku_instr_object_type::rwlock,
+ toku_instr_group_name,
+ "cachetable_m_pending_lock_expensive");
+ cachetable_m_pending_lock_cheap_key =
+ new toku_instr_key(toku_instr_object_type::rwlock,
+ toku_instr_group_name,
+ "cachetable_m_pending_lock_cheap");
+ cachetable_m_lock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "cachetable_m_lock");
+ result_i_open_dbs_rwlock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "result_i_open_dbs_rwlock");
+ checkpoint_safe_rwlock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "checkpoint_safe_rwlock");
+ cachetable_value_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "cachetable_value");
+ safe_file_size_lock_rwlock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "safe_file_size_lock_rwlock");
+ cachetable_disk_nb_rwlock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "cachetable_disk_nb_rwlock");
+
+ toku_instr_probe_1 = new toku_instr_probe(*fti_probe_1_key);
+}
+
int toku_ft_layer_init(void) {
int r = 0;
- //Portability must be initialized first
+
+ // Portability must be initialized first
r = toku_portability_init();
- if (r) { goto exit; }
+ if (r) {
+ goto exit;
+ }
+
+ toku_pfs_keys_init("fti");
+
r = db_env_set_toku_product_name("tokudb");
- if (r) { goto exit; }
+ if (r) {
+ goto exit;
+ }
partitioned_counters_init();
toku_status_init();
toku_context_status_init();
toku_checkpoint_init();
toku_ft_serialize_layer_init();
- toku_mutex_init(&ft_open_close_lock, NULL);
+ toku_mutex_init(
+ *ft_open_close_lock_mutex_key, &ft_open_close_lock, nullptr);
toku_scoped_malloc_init();
exit:
return r;
@@ -4642,7 +4917,10 @@ void toku_ft_layer_destroy(void) {
toku_status_destroy();
partitioned_counters_destroy();
toku_scoped_malloc_destroy();
- //Portability must be cleaned up last
+
+ delete toku_instr_probe_1;
+
+ // Portability must be cleaned up last
toku_portability_destroy();
}
diff --git a/storage/tokudb/PerconaFT/ft/ft.cc b/storage/tokudb/PerconaFT/ft/ft.cc
index abc9d295eae..c7c2ea33c9e 100644
--- a/storage/tokudb/PerconaFT/ft/ft.cc
+++ b/storage/tokudb/PerconaFT/ft/ft.cc
@@ -51,9 +51,10 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <toku_assert.h>
#include <portability/toku_atomic.h>
-void
-toku_reset_root_xid_that_created(FT ft, TXNID new_root_xid_that_created) {
- // Reset the root_xid_that_created field to the given value.
+toku_instr_key *ft_ref_lock_mutex_key;
+
+void toku_reset_root_xid_that_created(FT ft, TXNID new_root_xid_that_created) {
+ // Reset the root_xid_that_created field to the given value.
// This redefines which xid created the dictionary.
// hold lock around setting and clearing of dirty bit
@@ -101,15 +102,11 @@ toku_ft_free (FT ft) {
toku_free(ft);
}
-void
-toku_ft_init_reflock(FT ft) {
- toku_mutex_init(&ft->ft_ref_lock, NULL);
+void toku_ft_init_reflock(FT ft) {
+ toku_mutex_init(*ft_ref_lock_mutex_key, &ft->ft_ref_lock, nullptr);
}
-void
-toku_ft_destroy_reflock(FT ft) {
- toku_mutex_destroy(&ft->ft_ref_lock);
-}
+void toku_ft_destroy_reflock(FT ft) { toku_mutex_destroy(&ft->ft_ref_lock); }
void
toku_ft_grab_reflock(FT ft) {
diff --git a/storage/tokudb/PerconaFT/ft/loader/callbacks.cc b/storage/tokudb/PerconaFT/ft/loader/callbacks.cc
index 6a520dba3a3..ac69fb7e789 100644
--- a/storage/tokudb/PerconaFT/ft/loader/callbacks.cc
+++ b/storage/tokudb/PerconaFT/ft/loader/callbacks.cc
@@ -45,6 +45,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "loader/loader-internal.h"
#include "util/dbt.h"
+toku_instr_key *loader_error_mutex_key;
+
static void error_callback_lock(ft_loader_error_callback loader_error) {
toku_mutex_lock(&loader_error->mutex);
}
@@ -57,10 +59,10 @@ void ft_loader_init_error_callback(ft_loader_error_callback loader_error) {
memset(loader_error, 0, sizeof *loader_error);
toku_init_dbt(&loader_error->key);
toku_init_dbt(&loader_error->val);
- toku_mutex_init(&loader_error->mutex, NULL);
+ toku_mutex_init(*loader_error_mutex_key, &loader_error->mutex, nullptr);
}
-void ft_loader_destroy_error_callback(ft_loader_error_callback loader_error) {
+void ft_loader_destroy_error_callback(ft_loader_error_callback loader_error) {
toku_mutex_destroy(&loader_error->mutex);
toku_destroy_dbt(&loader_error->key);
toku_destroy_dbt(&loader_error->val);
diff --git a/storage/tokudb/PerconaFT/ft/loader/dbufio.cc b/storage/tokudb/PerconaFT/ft/loader/dbufio.cc
index ad084a4fbdc..90f76cecf90 100644
--- a/storage/tokudb/PerconaFT/ft/loader/dbufio.cc
+++ b/storage/tokudb/PerconaFT/ft/loader/dbufio.cc
@@ -49,6 +49,10 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "loader/dbufio.h"
#include "loader/loader-internal.h"
+toku_instr_key *bfs_mutex_key;
+toku_instr_key *bfs_cond_key;
+toku_instr_key *io_thread_key;
+
struct dbufio_file {
// i/o thread owns these
int fd;
@@ -276,39 +280,44 @@ static void* io_thread (void *v)
toku_mutex_lock(&bfs->mutex);
//printf("%s:%d Locked\n", __FILE__, __LINE__);
while (1) {
+ if (paniced(bfs)) {
+ toku_mutex_unlock(&bfs->mutex); // ignore any error
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
+ }
+ // printf("n_not_done=%d\n", bfs->n_not_done);
+ if (bfs->n_not_done == 0) {
+ // all done (meaning we stored EOF (or another error) in
+ // error_code[0] for the file.
+ // printf("unlocked\n");
+ toku_mutex_unlock(&bfs->mutex);
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
+ }
- if (paniced(bfs)) {
- toku_mutex_unlock(&bfs->mutex); // ignore any error
- return 0;
- }
- //printf("n_not_done=%d\n", bfs->n_not_done);
- if (bfs->n_not_done==0) {
- // all done (meaning we stored EOF (or another error) in error_code[0] for the file.
- //printf("unlocked\n");
- toku_mutex_unlock(&bfs->mutex);
- return 0;
- }
-
- struct dbufio_file *dbf = bfs->head;
- if (dbf==NULL) {
- // No I/O needs to be done yet.
- // Wait until something happens that will wake us up.
- toku_cond_wait(&bfs->cond, &bfs->mutex);
- if (paniced(bfs)) {
- toku_mutex_unlock(&bfs->mutex); // ignore any error
- return 0;
- }
- // Have the lock so go around.
- } else {
- // Some I/O needs to be done.
- //printf("%s:%d Need I/O\n", __FILE__, __LINE__);
- assert(dbf->second_buf_ready == false);
- assert(!dbf->io_done);
- bfs->head = dbf->next;
- if (bfs->head==NULL) bfs->tail=NULL;
-
- // Unlock the mutex now that we have ownership of dbf to allow consumers to get the mutex and perform swaps. They won't swap
- // this buffer because second_buf_ready is false.
+ struct dbufio_file *dbf = bfs->head;
+ if (dbf == NULL) {
+ // No I/O needs to be done yet.
+ // Wait until something happens that will wake us up.
+ toku_cond_wait(&bfs->cond, &bfs->mutex);
+ if (paniced(bfs)) {
+ toku_mutex_unlock(&bfs->mutex); // ignore any error
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
+ }
+ // Have the lock so go around.
+ } else {
+ // Some I/O needs to be done.
+ // printf("%s:%d Need I/O\n", __FILE__, __LINE__);
+ assert(dbf->second_buf_ready == false);
+ assert(!dbf->io_done);
+ bfs->head = dbf->next;
+ if (bfs->head == NULL)
+ bfs->tail = NULL;
+
+ // Unlock the mutex now that we have ownership of dbf to allow
+ // consumers to get the mutex and perform swaps. They won't swap
+ // this buffer because second_buf_ready is false.
toku_mutex_unlock(&bfs->mutex);
//printf("%s:%d Doing read fd=%d\n", __FILE__, __LINE__, dbf->fd);
{
@@ -339,14 +348,16 @@ static void* io_thread (void *v)
//printf("%s:%d locking mutex again=%ld\n", __FILE__, __LINE__, readcode);
{
- toku_mutex_lock(&bfs->mutex);
- if (paniced(bfs)) {
- toku_mutex_unlock(&bfs->mutex); // ignore any error
- return 0;
- }
- }
- // Now that we have the mutex, we can decrement n_not_done (if applicable) and set second_buf_ready
- if (readcode<=0) {
+ toku_mutex_lock(&bfs->mutex);
+ if (paniced(bfs)) {
+ toku_mutex_unlock(&bfs->mutex); // ignore any error
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
+ }
+ }
+ // Now that we have the mutex, we can decrement n_not_done (if
+ // applicable) and set second_buf_ready
+ if (readcode<=0) {
bfs->n_not_done--;
}
//printf("%s:%d n_not_done=%d\n", __FILE__, __LINE__, bfs->n_not_done);
@@ -377,34 +388,36 @@ int create_dbufio_fileset (DBUFIO_FILESET *bfsp, int N, int fds[/*N*/], size_t b
}
}
}
- //printf("%s:%d here\n", __FILE__, __LINE__);
- if (result==0) {
- toku_mutex_init(&bfs->mutex, NULL);
- mutex_inited = true;
+ // printf("%s:%d here\n", __FILE__, __LINE__);
+ if (result == 0) {
+ toku_mutex_init(*bfs_mutex_key, &bfs->mutex, nullptr);
+ mutex_inited = true;
}
- if (result==0) {
- toku_cond_init(&bfs->cond, NULL);
- cond_inited = true;
+ if (result == 0) {
+ toku_cond_init(*bfs_cond_key, &bfs->cond, nullptr);
+ cond_inited = true;
}
- if (result==0) {
- bfs->N = N;
- bfs->n_not_done = N;
- bfs->head = bfs->tail = NULL;
- for (int i=0; i<N; i++) {
- bfs->files[i].fd = fds[i];
- bfs->files[i].offset_in_buf = 0;
- bfs->files[i].offset_in_uncompressed_file = 0;
- bfs->files[i].next = NULL;
- bfs->files[i].second_buf_ready = false;
- for (int j=0; j<2; j++) {
- if (result==0) {
- MALLOC_N(bufsize, bfs->files[i].buf[j]);
- if (bfs->files[i].buf[j]==NULL) { result=get_error_errno(); }
- }
- bfs->files[i].n_in_buf[j] = 0;
- bfs->files[i].error_code[j] = 0;
- }
- bfs->files[i].io_done = false;
+ if (result == 0) {
+ bfs->N = N;
+ bfs->n_not_done = N;
+ bfs->head = bfs->tail = NULL;
+ for (int i = 0; i < N; i++) {
+ bfs->files[i].fd = fds[i];
+ bfs->files[i].offset_in_buf = 0;
+ bfs->files[i].offset_in_uncompressed_file = 0;
+ bfs->files[i].next = NULL;
+ bfs->files[i].second_buf_ready = false;
+ for (int j = 0; j < 2; j++) {
+ if (result == 0) {
+ MALLOC_N(bufsize, bfs->files[i].buf[j]);
+ if (bfs->files[i].buf[j] == NULL) {
+ result = get_error_errno();
+ }
+ }
+ bfs->files[i].n_in_buf[j] = 0;
+ bfs->files[i].error_code[j] = 0;
+ }
+ bfs->files[i].io_done = false;
ssize_t r;
if (bfs->compressed) {
r = dbf_read_compressed(&bfs->files[i], bfs->files[i].buf[0], bufsize);
@@ -431,13 +444,21 @@ int create_dbufio_fileset (DBUFIO_FILESET *bfsp, int N, int fds[/*N*/], size_t b
bfs->panic = false;
bfs->panic_errno = 0;
}
- //printf("Creating IO thread\n");
- if (result==0) {
- result = toku_pthread_create(&bfs->iothread, NULL, io_thread, (void*)bfs);
+ // printf("Creating IO thread\n");
+ if (result == 0) {
+ result = toku_pthread_create(*io_thread_key,
+ &bfs->iothread,
+ nullptr,
+ io_thread,
+ static_cast<void *>(bfs));
+ }
+ if (result == 0) {
+ *bfsp = bfs;
+ return 0;
}
- if (result==0) { *bfsp = bfs; return 0; }
// Now undo everything.
- // If we got here, there is no thread (either result was zero before the thread was created, or else the thread creation itself failed.
+ // If we got here, there is no thread (either result was zero before the
+ // thread was created, or else the thread creation itself failed.
if (bfs) {
if (bfs->files) {
// the files were allocated, so we have to free all the bufs.
diff --git a/storage/tokudb/PerconaFT/ft/loader/loader-internal.h b/storage/tokudb/PerconaFT/ft/loader/loader-internal.h
index 1aa2c203831..6f7b0147b21 100644
--- a/storage/tokudb/PerconaFT/ft/loader/loader-internal.h
+++ b/storage/tokudb/PerconaFT/ft/loader/loader-internal.h
@@ -64,10 +64,10 @@ enum {
/* These structures maintain a collection of all the open temporary files used by the loader. */
struct file_info {
bool is_open;
- bool is_extant; // if true, the file must be unlinked.
+ bool is_extant; // if true, the file must be unlinked.
char *fname;
- FILE *file;
- uint64_t n_rows; // how many rows were written into that file
+ TOKU_FILE *file;
+ uint64_t n_rows; // how many rows were written into that file
size_t buffer_size;
void *buffer;
};
@@ -80,11 +80,11 @@ struct file_infos {
};
typedef struct fidx { int idx; } FIDX;
static const FIDX FIDX_NULL __attribute__((__unused__)) = {-1};
-static int fidx_is_null (const FIDX f) __attribute__((__unused__));
-static int fidx_is_null (const FIDX f) { return f.idx==-1; }
-FILE *toku_bl_fidx2file (FTLOADER bl, FIDX i);
+static int fidx_is_null(const FIDX f) __attribute__((__unused__));
+static int fidx_is_null(const FIDX f) { return f.idx == -1; }
+TOKU_FILE *toku_bl_fidx2file(FTLOADER bl, FIDX i);
-int ft_loader_open_temp_file (FTLOADER bl, FIDX*file_idx);
+int ft_loader_open_temp_file(FTLOADER bl, FIDX *file_idx);
/* These data structures are used for manipulating a collection of rows in main memory. */
struct row {
@@ -100,11 +100,17 @@ struct rowset {
};
int init_rowset (struct rowset *rows, uint64_t memory_budget);
-void destroy_rowset (struct rowset *rows);
-int add_row (struct rowset *rows, DBT *key, DBT *val);
-
-int loader_write_row(DBT *key, DBT *val, FIDX data, FILE*, uint64_t *dataoff, struct wbuf *wb, FTLOADER bl);
-int loader_read_row (FILE *f, DBT *key, DBT *val);
+void destroy_rowset(struct rowset *rows);
+int add_row(struct rowset *rows, DBT *key, DBT *val);
+
+int loader_write_row(DBT *key,
+ DBT *val,
+ FIDX data,
+ TOKU_FILE *,
+ uint64_t *dataoff,
+ struct wbuf *wb,
+ FTLOADER bl);
+int loader_read_row(TOKU_FILE *f, DBT *key, DBT *val);
struct merge_fileset {
bool have_sorted_output; // Is there an previous key?
@@ -195,12 +201,13 @@ struct ft_loader_s {
bool did_reserve_memory;
bool compress_intermediates;
bool allow_puts;
- uint64_t reserved_memory; // how much memory are we allowed to use?
+ uint64_t reserved_memory; // how much memory are we allowed to use?
- /* To make it easier to recover from errors, we don't use FILE*, instead we use an index into the file_infos. */
+ /* To make it easier to recover from errors, we don't use TOKU_FILE*,
+ * instead we use an index into the file_infos. */
struct file_infos file_infos;
-#define PROGRESS_MAX (1<<16)
+#define PROGRESS_MAX (1 << 16)
int progress; // Progress runs from 0 to PROGRESS_MAX. When we call the poll function we convert to a float from 0.0 to 1.0
// We use an integer so that we can add to the progress using a fetch-and-add instruction.
diff --git a/storage/tokudb/PerconaFT/ft/loader/loader.cc b/storage/tokudb/PerconaFT/ft/loader/loader.cc
index f867639b953..5f57b473bc5 100644
--- a/storage/tokudb/PerconaFT/ft/loader/loader.cc
+++ b/storage/tokudb/PerconaFT/ft/loader/loader.cc
@@ -63,21 +63,17 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/x1764.h"
-static size_t (*os_fwrite_fun)(const void *,size_t,size_t,FILE*)=NULL;
-void ft_loader_set_os_fwrite (size_t (*fwrite_fun)(const void*,size_t,size_t,FILE*)) {
- os_fwrite_fun=fwrite_fun;
-}
+toku_instr_key *loader_bl_mutex_key;
+toku_instr_key *loader_fi_lock_mutex_key;
+toku_instr_key *loader_out_mutex_key;
-static size_t do_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) {
- if (os_fwrite_fun) {
- return os_fwrite_fun(ptr, size, nmemb, stream);
- } else {
- return fwrite(ptr, size, nmemb, stream);
- }
-}
+toku_instr_key *extractor_thread_key;
+toku_instr_key *fractal_thread_key;
+toku_instr_key *tokudb_file_tmp_key;
+toku_instr_key *tokudb_file_load_key;
-// 1024 is the right size_factor for production.
+// 1024 is the right size_factor for production.
// Different values for these sizes may be used for testing.
static uint32_t size_factor = 1024;
static uint32_t default_loader_nodesize = FT_DEFAULT_NODE_SIZE;
@@ -99,7 +95,7 @@ toku_ft_loader_get_rowset_budget_for_testing (void)
void ft_loader_lock_init(FTLOADER bl) {
invariant(!bl->mutex_init);
- toku_mutex_init(&bl->mutex, NULL);
+ toku_mutex_init(*loader_bl_mutex_key, &bl->mutex, nullptr);
bl->mutex_init = true;
}
@@ -131,7 +127,10 @@ static int add_big_buffer(struct file_info *file) {
newbuffer = true;
}
if (result == 0) {
- int r = setvbuf(file->file, (char *) file->buffer, _IOFBF, file->buffer_size);
+ int r = setvbuf(file->file->file,
+ static_cast<char *>(file->buffer),
+ _IOFBF,
+ file->buffer_size);
if (r != 0) {
result = get_error_errno();
if (newbuffer) {
@@ -150,9 +149,9 @@ static void cleanup_big_buffer(struct file_info *file) {
}
}
-int ft_loader_init_file_infos (struct file_infos *fi) {
+int ft_loader_init_file_infos(struct file_infos *fi) {
int result = 0;
- toku_mutex_init(&fi->lock, NULL);
+ toku_mutex_init(*loader_fi_lock_mutex_key, &fi->lock, nullptr);
fi->n_files = 0;
fi->n_files_limit = 1;
fi->n_files_open = 0;
@@ -196,11 +195,10 @@ void ft_loader_fi_destroy (struct file_infos *fi, bool is_error)
fi->file_infos = NULL;
}
-static int open_file_add (struct file_infos *fi,
- FILE *file,
- char *fname,
- /* out */ FIDX *idx)
-{
+static int open_file_add(struct file_infos *fi,
+ TOKU_FILE *file,
+ char *fname,
+ /* out */ FIDX *idx) {
int result = 0;
toku_mutex_lock(&fi->lock);
if (fi->n_files >= fi->n_files_limit) {
@@ -230,11 +228,12 @@ int ft_loader_fi_reopen (struct file_infos *fi, FIDX idx, const char *mode) {
int result = 0;
toku_mutex_lock(&fi->lock);
int i = idx.idx;
- invariant(i>=0 && i<fi->n_files);
+ invariant(i >= 0 && i < fi->n_files);
invariant(!fi->file_infos[i].is_open);
invariant(fi->file_infos[i].is_extant);
- fi->file_infos[i].file = toku_os_fopen(fi->file_infos[i].fname, mode);
- if (fi->file_infos[i].file == NULL) {
+ fi->file_infos[i].file =
+ toku_os_fopen(fi->file_infos[i].fname, mode, *tokudb_file_load_key);
+ if (fi->file_infos[i].file == NULL) {
result = get_error_errno();
} else {
fi->file_infos[i].is_open = true;
@@ -307,20 +306,20 @@ int ft_loader_open_temp_file (FTLOADER bl, FIDX *file_idx)
*/
{
int result = 0;
- if (result) // debug hack
+ if (result) // debug hack
return result;
- FILE *f = NULL;
+ TOKU_FILE *f = NULL;
int fd = -1;
- char *fname = toku_strdup(bl->temp_file_template);
+ char *fname = toku_strdup(bl->temp_file_template);
if (fname == NULL)
result = get_error_errno();
else {
fd = mkstemp(fname);
- if (fd < 0) {
+ if (fd < 0) {
result = get_error_errno();
} else {
- f = toku_os_fdopen(fd, "r+");
- if (f == NULL)
+ f = toku_os_fdopen(fd, "r+", fname, *tokudb_file_tmp_key);
+ if (f->file == nullptr)
result = get_error_errno();
else
result = open_file_add(&bl->file_infos, f, fname, file_idx);
@@ -339,7 +338,7 @@ int ft_loader_open_temp_file (FTLOADER bl, FIDX *file_idx)
return result;
}
-void toku_ft_loader_internal_destroy (FTLOADER bl, bool is_error) {
+void toku_ft_loader_internal_destroy(FTLOADER bl, bool is_error) {
ft_loader_lock_destroy(bl);
// These frees rely on the fact that if you free a NULL pointer then nothing bad happens.
@@ -635,12 +634,16 @@ int toku_ft_loader_open (FTLOADER *blp, /* out */
allow_puts);
if (r!=0) result = r;
}
- if (result==0 && allow_puts) {
+ if (result == 0 && allow_puts) {
FTLOADER bl = *blp;
- int r = toku_pthread_create(&bl->extractor_thread, NULL, extractor_thread, (void*)bl);
- if (r==0) {
+ int r = toku_pthread_create(*extractor_thread_key,
+ &bl->extractor_thread,
+ nullptr,
+ extractor_thread,
+ static_cast<void *>(bl));
+ if (r == 0) {
bl->extractor_live = true;
- } else {
+ } else {
result = r;
(void) toku_ft_loader_internal_destroy(bl, true);
}
@@ -659,17 +662,17 @@ static void ft_loader_set_panic(FTLOADER bl, int error, bool callback, int which
}
// One of the tests uses this.
-FILE *toku_bl_fidx2file (FTLOADER bl, FIDX i) {
+TOKU_FILE *toku_bl_fidx2file(FTLOADER bl, FIDX i) {
toku_mutex_lock(&bl->file_infos.lock);
- invariant(i.idx >=0 && i.idx < bl->file_infos.n_files);
+ invariant(i.idx >= 0 && i.idx < bl->file_infos.n_files);
invariant(bl->file_infos.file_infos[i.idx].is_open);
- FILE *result=bl->file_infos.file_infos[i.idx].file;
+ TOKU_FILE *result = bl->file_infos.file_infos[i.idx].file;
toku_mutex_unlock(&bl->file_infos.lock);
return result;
}
-static int bl_finish_compressed_write(FILE *stream, struct wbuf *wb) {
- int r;
+static int bl_finish_compressed_write(TOKU_FILE *stream, struct wbuf *wb) {
+ int r = 0;
char *compressed_buf = NULL;
const size_t data_size = wb->ndone;
invariant(data_size > 0);
@@ -720,31 +723,23 @@ static int bl_finish_compressed_write(FILE *stream, struct wbuf *wb) {
// Mark as written
wb->ndone = 0;
- size_t size_to_write = total_size + 4; // Includes writing total_size
+ size_t size_to_write = total_size + 4; // Includes writing total_size
+
+ r = toku_os_fwrite(compressed_buf, 1, size_to_write, stream);
- {
- size_t written = do_fwrite(compressed_buf, 1, size_to_write, stream);
- if (written!=size_to_write) {
- if (os_fwrite_fun) // if using hook to induce artificial errors (for testing) ...
- r = get_maybe_error_errno(); // ... then there is no error in the stream, but there is one in errno
- else
- r = ferror(stream);
- invariant(r!=0);
- goto exit;
- }
- }
- r = 0;
-exit:
if (compressed_buf) {
toku_free(compressed_buf);
}
return r;
}
-static int bl_compressed_write(void *ptr, size_t nbytes, FILE *stream, struct wbuf *wb) {
+static int bl_compressed_write(void *ptr,
+ size_t nbytes,
+ TOKU_FILE *stream,
+ struct wbuf *wb) {
invariant(wb->size <= MAX_UNCOMPRESSED_BUF);
size_t bytes_left = nbytes;
- char *buf = (char*)ptr;
+ char *buf = (char *)ptr;
while (bytes_left > 0) {
size_t bytes_to_copy = bytes_left;
@@ -767,29 +762,28 @@ static int bl_compressed_write(void *ptr, size_t nbytes, FILE *stream, struct wb
return 0;
}
-static int bl_fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream, struct wbuf *wb, FTLOADER bl)
-/* Effect: this is a wrapper for fwrite that returns 0 on success, otherwise returns an error number.
+static int bl_fwrite(void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ struct wbuf *wb,
+ FTLOADER bl)
+/* Effect: this is a wrapper for fwrite that returns 0 on success, otherwise
+ * returns an error number.
* Arguments:
* ptr the data to be writen.
* size the amount of data to be written.
* nmemb the number of units of size to be written.
* stream write the data here.
- * wb where to write uncompressed data (if we're compressing) or ignore if NULL
- * bl passed so we can panic the ft_loader if something goes wrong (recording the error number).
+ * wb where to write uncompressed data (if we're compressing) or ignore if
+ * NULL
+ * bl passed so we can panic the ft_loader if something goes wrong
+ * (recording the error number).
* Return value: 0 on success, an error number otherwise.
*/
{
if (!bl->compress_intermediates || !wb) {
- size_t r = do_fwrite(ptr, size, nmemb, stream);
- if (r!=nmemb) {
- int e;
- if (os_fwrite_fun) // if using hook to induce artificial errors (for testing) ...
- e = get_maybe_error_errno(); // ... then there is no error in the stream, but there is one in errno
- else
- e = ferror(stream);
- invariant(e!=0);
- return e;
- }
+ return toku_os_fwrite(ptr, size, nmemb, stream);
} else {
size_t num_bytes = size * nmemb;
int r = bl_compressed_write(ptr, num_bytes, stream, wb);
@@ -800,8 +794,9 @@ static int bl_fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream, struct
return 0;
}
-static int bl_fread (void *ptr, size_t size, size_t nmemb, FILE *stream)
-/* Effect: this is a wrapper for fread that returns 0 on success, otherwise returns an error number.
+static int bl_fread(void *ptr, size_t size, size_t nmemb, TOKU_FILE *stream)
+/* Effect: this is a wrapper for fread that returns 0 on success, otherwise
+ * returns an error number.
* Arguments:
* ptr read data into here.
* size size of data element to be read.
@@ -810,24 +805,14 @@ static int bl_fread (void *ptr, size_t size, size_t nmemb, FILE *stream)
* Return value: 0 on success, an error number otherwise.
*/
{
- size_t r = fread(ptr, size, nmemb, stream);
- if (r==0) {
- if (feof(stream)) return EOF;
- else {
- do_error: ;
- int e = ferror(stream);
- // r == 0 && !feof && e == 0, how does this happen? invariant(e!=0);
- return e;
- }
- } else if (r<nmemb) {
- goto do_error;
- } else {
- return 0;
- }
+ return toku_os_fread(ptr, size, nmemb, stream);
}
-static int bl_write_dbt (DBT *dbt, FILE* datafile, uint64_t *dataoff, struct wbuf *wb, FTLOADER bl)
-{
+static int bl_write_dbt(DBT *dbt,
+ TOKU_FILE *datafile,
+ uint64_t *dataoff,
+ struct wbuf *wb,
+ FTLOADER bl) {
int r;
int dlen = dbt->size;
if ((r=bl_fwrite(&dlen, sizeof(dlen), 1, datafile, wb, bl))) return r;
@@ -837,8 +822,7 @@ static int bl_write_dbt (DBT *dbt, FILE* datafile, uint64_t *dataoff, struct wbu
return 0;
}
-static int bl_read_dbt (/*in*/DBT *dbt, FILE *stream)
-{
+static int bl_read_dbt(/*in*/ DBT *dbt, TOKU_FILE *stream) {
int len;
{
int r;
@@ -892,13 +876,20 @@ static int bl_read_dbt_from_dbufio (/*in*/DBT *dbt, DBUFIO_FILESET bfs, int file
return result;
}
-
-int loader_write_row(DBT *key, DBT *val, FIDX data, FILE *dataf, uint64_t *dataoff, struct wbuf *wb, FTLOADER bl)
-/* Effect: Given a key and a val (both DBTs), write them to a file. Increment *dataoff so that it's up to date.
+int loader_write_row(DBT *key,
+ DBT *val,
+ FIDX data,
+ TOKU_FILE *dataf,
+ uint64_t *dataoff,
+ struct wbuf *wb,
+ FTLOADER bl)
+/* Effect: Given a key and a val (both DBTs), write them to a file. Increment
+ * *dataoff so that it's up to date.
* Arguments:
* key, val write these.
* data the file to write them to
- * dataoff a pointer to a counter that keeps track of the amount of data written so far.
+ * dataoff a pointer to a counter that keeps track of the amount of data
+ * written so far.
* wb a pointer (possibly NULL) to buffer uncompressed output
* bl the ft_loader (passed so we can panic if needed).
* Return value: 0 on success, an error number otherwise.
@@ -916,8 +907,9 @@ int loader_write_row(DBT *key, DBT *val, FIDX data, FILE *dataf, uint64_t *datao
return 0;
}
-int loader_read_row (FILE *f, DBT *key, DBT *val)
-/* Effect: Read a key value pair from a file. The DBTs must have DB_DBT_REALLOC set.
+int loader_read_row(TOKU_FILE *f, DBT *key, DBT *val)
+/* Effect: Read a key value pair from a file. The DBTs must have DB_DBT_REALLOC
+ * set.
* Arguments:
* f where to read it from.
* key, val read it into these.
@@ -1087,7 +1079,7 @@ static void* extractor_thread (void *blv) {
FTLOADER bl = (FTLOADER)blv;
int r = 0;
while (1) {
- void *item;
+ void *item = nullptr;
{
int rq = toku_queue_deq(bl->primary_rowset_queue, &item, NULL, NULL);
if (rq==EOF) break;
@@ -1108,14 +1100,14 @@ static void* extractor_thread (void *blv) {
//printf("%s:%d extractor finishing\n", __FILE__, __LINE__);
if (r == 0) {
r = finish_primary_rows(bl);
- if (r)
+ if (r)
ft_loader_set_panic(bl, r, false, 0, nullptr, nullptr);
-
}
- return NULL;
+ toku_instr_delete_current_thread();
+ return nullptr;
}
-static void enqueue_for_extraction (FTLOADER bl) {
+static void enqueue_for_extraction(FTLOADER bl) {
//printf("%s:%d enqueing %ld items\n", __FILE__, __LINE__, bl->primary_rowset.n_rows);
struct rowset *XMALLOC(enqueue_me);
*enqueue_me = bl->primary_rowset;
@@ -1626,11 +1618,12 @@ static int write_rowset_to_file (FTLOADER bl, FIDX sfile, const struct rowset ro
struct wbuf wb;
wbuf_init(&wb, uncompressed_buffer, MAX_UNCOMPRESSED_BUF);
- FILE *sstream = toku_bl_fidx2file(bl, sfile);
- for (size_t i=0; i<rows.n_rows; i++) {
- DBT skey = make_dbt(rows.data + rows.rows[i].off, rows.rows[i].klen);
- DBT sval = make_dbt(rows.data + rows.rows[i].off + rows.rows[i].klen, rows.rows[i].vlen);
-
+ TOKU_FILE *sstream = toku_bl_fidx2file(bl, sfile);
+ for (size_t i = 0; i < rows.n_rows; i++) {
+ DBT skey = make_dbt(rows.data + rows.rows[i].off, rows.rows[i].klen);
+ DBT sval = make_dbt(rows.data + rows.rows[i].off + rows.rows[i].klen,
+ rows.rows[i].vlen);
+
uint64_t soffset=0; // don't really need this.
r = loader_write_row(&skey, &sval, sfile, sstream, &soffset, &wb, bl);
if (r != 0) {
@@ -1727,14 +1720,30 @@ int ft_loader_sort_and_write_rows (struct rowset *rows, struct merge_fileset *fs
return sort_and_write_rows (*rows, fs, bl, which_db, dest_db, compare);
}
-int toku_merge_some_files_using_dbufio (const bool to_q, FIDX dest_data, QUEUE q, int n_sources, DBUFIO_FILESET bfs, FIDX srcs_fidxs[/*n_sources*/], FTLOADER bl, int which_db, DB *dest_db, ft_compare_func compare, int progress_allocation)
-/* Effect: Given an array of FILE*'s each containing sorted, merge the data and write it to an output. All the files remain open after the merge.
- * This merge is performed in one pass, so don't pass too many files in. If you need a tree of merges do it elsewhere.
- * If TO_Q is true then we write rowsets into queue Q. Otherwise we write into dest_data.
- * Modifies: May modify the arrays of files (but if modified, it must be a permutation so the caller can use that array to close everything.)
- * Requires: The number of sources is at least one, and each of the input files must have at least one row in it.
+int toku_merge_some_files_using_dbufio(const bool to_q,
+ FIDX dest_data,
+ QUEUE q,
+ int n_sources,
+ DBUFIO_FILESET bfs,
+ FIDX srcs_fidxs[/*n_sources*/],
+ FTLOADER bl,
+ int which_db,
+ DB *dest_db,
+ ft_compare_func compare,
+ int progress_allocation)
+/* Effect: Given an array of FILE*'s each containing sorted, merge the data and
+ * write it to an output. All the files remain open after the merge.
+ * This merge is performed in one pass, so don't pass too many files in. If
+ * you need a tree of merges do it elsewhere.
+ * If TO_Q is true then we write rowsets into queue Q. Otherwise we write
+ * into dest_data.
+ * Modifies: May modify the arrays of files (but if modified, it must be a
+ * permutation so the caller can use that array to close everything.)
+ * Requires: The number of sources is at least one, and each of the input files
+ * must have at least one row in it.
* Arguments:
- * to_q boolean indicating that output is queue (true) or a file (false)
+ * to_q boolean indicating that output is queue (true) or a file
+ * (false)
* dest_data where to write the sorted data
* q where to write the sorted data
* n_sources how many source files.
@@ -1747,9 +1756,10 @@ int toku_merge_some_files_using_dbufio (const bool to_q, FIDX dest_data, QUEUE q
{
int result = 0;
- FILE *dest_stream = to_q ? NULL : toku_bl_fidx2file(bl, dest_data);
+ TOKU_FILE *dest_stream = to_q ? nullptr : toku_bl_fidx2file(bl, dest_data);
- //printf(" merge_some_files progress=%d fin at %d\n", bl->progress, bl->progress+progress_allocation);
+ // printf(" merge_some_files progress=%d fin at %d\n", bl->progress,
+ // bl->progress+progress_allocation);
DBT keys[n_sources];
DBT vals[n_sources];
uint64_t dataoff[n_sources];
@@ -1943,12 +1953,18 @@ static int merge_some_files (const bool to_q, FIDX dest_data, QUEUE q, int n_sou
int result = 0;
DBUFIO_FILESET bfs = NULL;
int *MALLOC_N(n_sources, fds);
- if (fds==NULL) result=get_error_errno();
- if (result==0) {
- for (int i=0; i<n_sources; i++) {
- int r = fileno(toku_bl_fidx2file(bl, srcs_fidxs[i])); // we rely on the fact that when the files are closed, the fd is also closed.
- if (r==-1) {
- result=get_error_errno();
+ if (fds == NULL)
+ result = get_error_errno();
+ if (result == 0) {
+ for (int i = 0; i < n_sources; i++) {
+ int r = fileno(
+ toku_bl_fidx2file(bl, srcs_fidxs[i])->file); // we rely on the
+ // fact that when
+ // the files are
+ // closed, the fd
+ // is also closed.
+ if (r == -1) {
+ result = get_error_errno();
break;
}
fds[i] = r;
@@ -2178,7 +2194,7 @@ static inline void dbout_init(struct dbout *out, FT ft) {
out->current_off = 0;
out->n_translations = out->n_translations_limit = 0;
out->translation = NULL;
- toku_mutex_init(&out->mutex, NULL);
+ toku_mutex_init(*loader_out_mutex_key, &out->mutex, nullptr);
out->ft = ft;
}
@@ -2418,7 +2434,7 @@ static int toku_loader_write_ft_from_q (FTLOADER bl,
assert_zero(r);
return result;
}
- FILE *pivots_stream = toku_bl_fidx2file(bl, pivots_file);
+ TOKU_FILE *pivots_stream = toku_bl_fidx2file(bl, pivots_file);
TXNID root_xid_that_created = TXNID_NONE;
if (bl->root_xids_that_created)
@@ -2705,21 +2721,35 @@ int toku_loader_write_ft_from_q_in_C (FTLOADER bl,
static void* fractal_thread (void *ftav) {
struct fractal_thread_args *fta = (struct fractal_thread_args *)ftav;
- int r = toku_loader_write_ft_from_q (fta->bl, fta->descriptor, fta->fd, fta->progress_allocation, fta->q, fta->total_disksize_estimate, fta->which_db, fta->target_nodesize, fta->target_basementnodesize, fta->target_compression_method, fta->target_fanout);
+ int r = toku_loader_write_ft_from_q(fta->bl,
+ fta->descriptor,
+ fta->fd,
+ fta->progress_allocation,
+ fta->q,
+ fta->total_disksize_estimate,
+ fta->which_db,
+ fta->target_nodesize,
+ fta->target_basementnodesize,
+ fta->target_compression_method,
+ fta->target_fanout);
fta->errno_result = r;
- return NULL;
-}
-
-static int loader_do_i (FTLOADER bl,
- int which_db,
- DB *dest_db,
- ft_compare_func compare,
- const DESCRIPTOR descriptor,
- const char *new_fname,
- int progress_allocation // how much progress do I need to add into bl->progress by the end..
- )
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
+}
+
+static int loader_do_i(FTLOADER bl,
+ int which_db,
+ DB *dest_db,
+ ft_compare_func compare,
+ const DESCRIPTOR descriptor,
+ const char *new_fname,
+ int progress_allocation // how much progress do I need
+ // to add into bl->progress by
+ // the end..
+ )
/* Effect: Handle the file creating for one particular DB in the bulk loader. */
-/* Requires: The data is fully extracted, so we can do merges out of files and write the ft file. */
+/* Requires: The data is fully extracted, so we can do merges out of files and
+ write the ft file. */
{
//printf("doing i use %d progress=%d fin at %d\n", progress_allocation, bl->progress, bl->progress+progress_allocation);
struct merge_fileset *fs = &(bl->fs[which_db]);
@@ -2730,10 +2760,14 @@ static int loader_do_i (FTLOADER bl,
if (r) goto error;
{
- mode_t mode = S_IRUSR+S_IWUSR + S_IRGRP+S_IWGRP;
- int fd = toku_os_open(new_fname, O_RDWR| O_CREAT | O_BINARY, mode); // #2621
+ mode_t mode = S_IRUSR + S_IWUSR + S_IRGRP + S_IWGRP;
+ int fd = toku_os_open(new_fname,
+ O_RDWR | O_CREAT | O_BINARY,
+ mode,
+ *tokudb_file_load_key); // #2621
if (fd < 0) {
- r = get_error_errno(); goto error;
+ r = get_error_errno();
+ goto error;
}
uint32_t target_nodesize, target_basementnodesize, target_fanout;
@@ -2753,24 +2787,27 @@ static int loader_do_i (FTLOADER bl,
progress_allocation -= allocation_for_merge;
// This structure must stay live until the join below.
- struct fractal_thread_args fta = {
- bl,
- descriptor,
- fd,
- progress_allocation,
- bl->fractal_queues[which_db],
- bl->extracted_datasizes[which_db],
- 0,
- which_db,
- target_nodesize,
- target_basementnodesize,
- target_compression_method,
- target_fanout
- };
-
- r = toku_pthread_create(bl->fractal_threads+which_db, NULL, fractal_thread, (void*)&fta);
+ struct fractal_thread_args fta = {bl,
+ descriptor,
+ fd,
+ progress_allocation,
+ bl->fractal_queues[which_db],
+ bl->extracted_datasizes[which_db],
+ 0,
+ which_db,
+ target_nodesize,
+ target_basementnodesize,
+ target_compression_method,
+ target_fanout};
+
+ r = toku_pthread_create(*fractal_thread_key,
+ bl->fractal_threads + which_db,
+ nullptr,
+ fractal_thread,
+ static_cast<void *>(&fta));
if (r) {
- int r2 __attribute__((__unused__)) = toku_queue_destroy(bl->fractal_queues[which_db]);
+ int r2 __attribute__((__unused__)) =
+ toku_queue_destroy(bl->fractal_queues[which_db]);
// ignore r2, since we already have an error
bl->fractal_queues[which_db] = nullptr;
goto error;
@@ -3107,7 +3144,7 @@ static int read_some_pivots (FIDX pivots_file, int n_to_read, FTLOADER bl,
for (int i = 0; i < n_to_read; i++)
pivots[i] = zero_dbt;
- FILE *pivots_stream = toku_bl_fidx2file(bl, pivots_file);
+ TOKU_FILE *pivots_stream = toku_bl_fidx2file(bl, pivots_file);
int result = 0;
for (int i = 0; i < n_to_read; i++) {
@@ -3159,8 +3196,9 @@ static int setup_nonleaf_block (int n_children,
}
if (result == 0) {
- FILE *next_pivots_stream = toku_bl_fidx2file(bl, next_pivots_file);
- int r = bl_write_dbt(&pivots[n_children-1], next_pivots_stream, NULL, nullptr, bl);
+ TOKU_FILE *next_pivots_stream = toku_bl_fidx2file(bl, next_pivots_file);
+ int r = bl_write_dbt(
+ &pivots[n_children - 1], next_pivots_stream, NULL, nullptr, bl);
if (r)
result = r;
}
@@ -3275,8 +3313,11 @@ static int write_nonleaves (FTLOADER bl, FIDX pivots_fidx, struct dbout *out, st
// 2) We put the 15 pivots and 16 blocks into an non-leaf node.
// 3) We put the 16th pivot into the next pivots file.
{
- int r = fseek(toku_bl_fidx2file(bl, pivots_fidx), 0, SEEK_SET);
- if (r!=0) { return get_error_errno(); }
+ int r =
+ fseek(toku_bl_fidx2file(bl, pivots_fidx)->file, 0, SEEK_SET);
+ if (r != 0) {
+ return get_error_errno();
+ }
}
FIDX next_pivots_file;
@@ -3296,7 +3337,7 @@ static int write_nonleaves (FTLOADER bl, FIDX pivots_fidx, struct dbout *out, st
while (sts->n_subtrees - n_subtrees_used >= n_per_block*2) {
// grab the first N_PER_BLOCK and build a node.
DBT *pivots;
- int64_t blocknum_of_new_node;
+ int64_t blocknum_of_new_node = 0;
struct subtree_info *subtree_info;
int r = setup_nonleaf_block (n_per_block,
sts, pivots_fidx, n_subtrees_used,
diff --git a/storage/tokudb/PerconaFT/ft/loader/loader.h b/storage/tokudb/PerconaFT/ft/loader/loader.h
index 9c1bdab1ee2..cea2e8dfda2 100644
--- a/storage/tokudb/PerconaFT/ft/loader/loader.h
+++ b/storage/tokudb/PerconaFT/ft/loader/loader.h
@@ -38,6 +38,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#pragma once
+#include "toku_portability.h"
#include "ft/txn/txn.h"
#include "ft/cachetable/cachetable.h"
#include "ft/comparator.h"
@@ -77,8 +78,6 @@ int toku_ft_loader_abort(FTLOADER bl,
bool is_error);
// For test purposes only
-void toku_ft_loader_set_size_factor (uint32_t factor);
-
-void ft_loader_set_os_fwrite (size_t (*fwrite_fun)(const void*,size_t,size_t,FILE*));
+void toku_ft_loader_set_size_factor(uint32_t factor);
size_t ft_loader_leafentry_size(size_t key_size, size_t val_size, TXNID xid);
diff --git a/storage/tokudb/PerconaFT/ft/logger/log-internal.h b/storage/tokudb/PerconaFT/ft/logger/log-internal.h
index bee74fac346..be19e1342cd 100644
--- a/storage/tokudb/PerconaFT/ft/logger/log-internal.h
+++ b/storage/tokudb/PerconaFT/ft/logger/log-internal.h
@@ -70,11 +70,11 @@ struct mylock {
};
static inline void ml_init(struct mylock *l) {
- toku_mutex_init(&l->lock, 0);
-}
-static inline void ml_lock(struct mylock *l) {
- toku_mutex_lock(&l->lock);
+ toku_mutex_init(*log_internal_lock_mutex_key, &l->lock, nullptr);
}
+// TODO: source location info might have be to be pulled up one caller
+// to be useful
+static inline void ml_lock(struct mylock *l) { toku_mutex_lock(&l->lock); }
static inline void ml_unlock(struct mylock *l) {
toku_mutex_unlock(&l->lock);
}
diff --git a/storage/tokudb/PerconaFT/ft/logger/logcursor.cc b/storage/tokudb/PerconaFT/ft/logger/logcursor.cc
index 910a608cef9..07f57220bf0 100644
--- a/storage/tokudb/PerconaFT/ft/logger/logcursor.cc
+++ b/storage/tokudb/PerconaFT/ft/logger/logcursor.cc
@@ -86,10 +86,10 @@ static int lc_close_cur_logfile(TOKULOGCURSOR lc) {
}
static toku_off_t lc_file_len(const char *name) {
- toku_struct_stat buf;
- int r = toku_stat(name, &buf);
- assert(r == 0);
- return buf.st_size;
+ toku_struct_stat buf;
+ int r = toku_stat(name, &buf, *tokudb_file_data_key);
+ assert(r == 0);
+ return buf.st_size;
}
// Cat the file and throw away the contents. This brings the file into the file system cache
diff --git a/storage/tokudb/PerconaFT/ft/logger/logger.cc b/storage/tokudb/PerconaFT/ft/logger/logger.cc
index d6d1673b5e3..0e1e5a276b7 100644
--- a/storage/tokudb/PerconaFT/ft/logger/logger.cc
+++ b/storage/tokudb/PerconaFT/ft/logger/logger.cc
@@ -50,11 +50,17 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/status.h"
-static const int log_format_version=TOKU_LOG_VERSION;
+static const int log_format_version = TOKU_LOG_VERSION;
-static int open_logfile (TOKULOGGER logger);
-static void logger_write_buffer (TOKULOGGER logger, LSN *fsynced_lsn);
-static void delete_logfile(TOKULOGGER logger, long long index, uint32_t version);
+toku_instr_key *result_output_condition_lock_mutex_key;
+toku_instr_key *result_output_condition_key;
+toku_instr_key *tokudb_file_log_key;
+
+static int open_logfile(TOKULOGGER logger);
+static void logger_write_buffer(TOKULOGGER logger, LSN *fsynced_lsn);
+static void delete_logfile(TOKULOGGER logger,
+ long long index,
+ uint32_t version);
static void grab_output(TOKULOGGER logger, LSN *fsynced_lsn);
static void release_output(TOKULOGGER logger, LSN fsynced_lsn);
@@ -132,10 +138,13 @@ int toku_logger_create (TOKULOGGER *resultp) {
// n_in_file is uninitialized
result->write_block_size = FT_DEFAULT_NODE_SIZE; // default logging size is the same as the default ft block size
toku_logfilemgr_create(&result->logfilemgr);
- *resultp=result;
+ *resultp = result;
ml_init(&result->input_lock);
- toku_mutex_init(&result->output_condition_lock, NULL);
- toku_cond_init(&result->output_condition, NULL);
+ toku_mutex_init(*result_output_condition_lock_mutex_key,
+ &result->output_condition_lock,
+ nullptr);
+ toku_cond_init(
+ *result_output_condition_key, &result->output_condition, nullptr);
result->rollback_cachefile = NULL;
result->output_is_available = true;
toku_txn_manager_init(&result->txn_manager);
@@ -301,10 +310,10 @@ int toku_logger_close(TOKULOGGER *loggerp) {
grab_output(logger, &fsynced_lsn);
logger_write_buffer(logger, &fsynced_lsn);
if (logger->fd!=-1) {
- if ( logger->write_log_files ) {
+ if (logger->write_log_files) {
toku_file_fsync_without_accounting(logger->fd);
}
- r = close(logger->fd);
+ r = toku_os_close(logger->fd);
assert(r == 0);
}
r = close_logdir(logger);
@@ -346,9 +355,13 @@ static int close_and_open_logfile (TOKULOGGER logger, LSN *fsynced_lsn)
if (logger->write_log_files) {
toku_file_fsync_without_accounting(logger->fd);
*fsynced_lsn = logger->written_lsn;
- toku_logfilemgr_update_last_lsn(logger->logfilemgr, logger->written_lsn); // fixes t:2294
+ toku_logfilemgr_update_last_lsn(logger->logfilemgr,
+ logger->written_lsn); // fixes t:2294
}
- r = close(logger->fd); if (r!=0) return get_error_errno();
+ r = toku_os_close(logger->fd);
+
+ if (r != 0)
+ return get_error_errno();
return open_logfile(logger);
}
@@ -678,18 +691,28 @@ static int open_logfile (TOKULOGGER logger)
{
int fnamelen = strlen(logger->directory)+50;
char fname[fnamelen];
- snprintf(fname, fnamelen, "%s/log%012lld.tokulog%d", logger->directory, logger->next_log_file_number, TOKU_LOG_VERSION);
+ snprintf(fname,
+ fnamelen,
+ "%s/log%012lld.tokulog%d",
+ logger->directory,
+ logger->next_log_file_number,
+ TOKU_LOG_VERSION);
long long index = logger->next_log_file_number;
if (logger->write_log_files) {
- logger->fd = open(fname, O_CREAT+O_WRONLY+O_TRUNC+O_EXCL+O_BINARY, S_IRUSR+S_IWUSR);
- if (logger->fd==-1) {
+ logger->fd =
+ toku_os_open(fname,
+ O_CREAT + O_WRONLY + O_TRUNC + O_EXCL + O_BINARY,
+ S_IRUSR + S_IWUSR,
+ *tokudb_file_log_key);
+ if (logger->fd == -1) {
return get_error_errno();
}
fsync_logdir(logger);
logger->next_log_file_number++;
} else {
- logger->fd = open(DEV_NULL_FILE, O_WRONLY+O_BINARY);
- if (logger->fd==-1) {
+ logger->fd = toku_os_open(
+ DEV_NULL_FILE, O_WRONLY + O_BINARY, S_IWUSR, *tokudb_file_log_key);
+ if (logger->fd == -1) {
return get_error_errno();
}
}
@@ -835,10 +858,11 @@ int toku_logger_restart(TOKULOGGER logger, LSN lastlsn)
logger_write_buffer(logger, &fsynced_lsn);
// close the log file
- if ( logger->write_log_files) { // fsyncs don't work to /dev/null
+ if (logger->write_log_files) { // fsyncs don't work to /dev/null
toku_file_fsync_without_accounting(logger->fd);
}
- r = close(logger->fd); assert(r == 0);
+ r = toku_os_close(logger->fd);
+ assert(r == 0);
logger->fd = -1;
// reset the LSN's to the lastlsn when the logger was opened
@@ -1238,11 +1262,13 @@ void toku_txnid2txn(TOKULOGGER logger, TXNID_PAIR txnid, TOKUTXN *result) {
}
// Find the earliest LSN in a log. No locks are needed.
-static int peek_at_log (TOKULOGGER logger, char* filename, LSN *first_lsn) {
- int fd = open(filename, O_RDONLY+O_BINARY);
- if (fd<0) {
+static int peek_at_log(TOKULOGGER logger, char *filename, LSN *first_lsn) {
+ int fd = toku_os_open(
+ filename, O_RDONLY + O_BINARY, S_IRUSR, *tokudb_file_log_key);
+ if (fd < 0) {
int er = get_error_errno();
- if (logger->write_log_files) printf("couldn't open: %s\n", strerror(er));
+ if (logger->write_log_files)
+ printf("couldn't open: %s\n", strerror(er));
return er;
}
enum { SKIP = 12+1+4 }; // read the 12 byte header, the first message, and the first len
@@ -1259,10 +1285,13 @@ static int peek_at_log (TOKULOGGER logger, char* filename, LSN *first_lsn) {
lsn = rbuf_ulonglong(&rb);
}
- r=close(fd);
- if (r!=0) { return 0; }
+ r = toku_os_close(fd);
+
+ if (r != 0) {
+ return 0;
+ }
- first_lsn->lsn=lsn;
+ first_lsn->lsn = lsn;
return 0;
}
diff --git a/storage/tokudb/PerconaFT/ft/logger/recover.cc b/storage/tokudb/PerconaFT/ft/logger/recover.cc
index 9eaa56bdc53..9a9a1214ecb 100644
--- a/storage/tokudb/PerconaFT/ft/logger/recover.cc
+++ b/storage/tokudb/PerconaFT/ft/logger/recover.cc
@@ -954,14 +954,14 @@ static int toku_recover_frename(struct logtype_frename *l, RECOVER_ENV renv) {
std::unique_ptr<char[], decltype(&toku_free)> new_iname_full(
toku_construct_full_name(2, data_dir, l->new_iname.data), &toku_free);
- if (toku_stat(old_iname_full.get(), &stat) == -1) {
+ if (toku_stat(old_iname_full.get(), &stat, toku_uninstrumented) == -1) {
if (ENOENT == errno)
old_exist = false;
else
return 1;
}
- if (toku_stat(new_iname_full.get(), &stat) == -1) {
+ if (toku_stat(new_iname_full.get(), &stat, toku_uninstrumented) == -1) {
if (ENOENT == errno)
new_exist = false;
else
@@ -980,7 +980,7 @@ static int toku_recover_frename(struct logtype_frename *l, RECOVER_ENV renv) {
// 'stalled cachefiles' container the new file is removed
// and the old file is renamed.
if (old_exist && new_exist &&
- (toku_os_unlink(new_iname_full.get()) == -1 ||
+ (toku_os_delete(new_iname_full.get()) == -1 ||
toku_os_rename(old_iname_full.get(), new_iname_full.get()) == -1 ||
toku_fsync_directory(old_iname_full.get()) == -1 ||
toku_fsync_directory(new_iname_full.get()) == -1))
@@ -1473,9 +1473,13 @@ static int do_recovery(RECOVER_ENV renv, const char *env_dir, const char *log_di
{
toku_struct_stat buf;
- if (toku_stat(env_dir, &buf)!=0) {
+ if (toku_stat(env_dir, &buf, toku_uninstrumented)) {
rr = get_error_errno();
- fprintf(stderr, "%.24s PerconaFT recovery error: directory does not exist: %s\n", ctime(&tnow), env_dir);
+ fprintf(stderr,
+ "%.24s PerconaFT recovery error: directory does not exist: "
+ "%s\n",
+ ctime(&tnow),
+ env_dir);
goto errorexit;
} else if (!S_ISDIR(buf.st_mode)) {
fprintf(stderr, "%.24s PerconaFT recovery error: this file is supposed to be a directory, but is not: %s\n", ctime(&tnow), env_dir);
diff --git a/storage/tokudb/PerconaFT/ft/serialize/block_allocator.cc b/storage/tokudb/PerconaFT/ft/serialize/block_allocator.cc
index 19811373d16..29f6daa293a 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/block_allocator.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/block_allocator.cc
@@ -40,6 +40,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <string.h>
+#include "toku_portability.h"
#include "portability/memory.h"
#include "portability/toku_assert.h"
#include "portability/toku_stdint.h"
diff --git a/storage/tokudb/PerconaFT/ft/serialize/block_table.cc b/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
index 12700d9d83e..811f86c30a7 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
@@ -55,6 +55,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/nb_mutex.h"
#include "util/scoped_malloc.h"
+
+toku_instr_key *block_table_mutex_key;
+toku_instr_key *safe_file_size_lock_mutex_key;
+toku_instr_key *safe_file_size_lock_rwlock_key;
+
// indicates the end of a freelist
static const BLOCKNUM freelist_null = {-1};
@@ -100,8 +105,10 @@ void block_table::_create_internal() {
memset(&_checkpointed, 0, sizeof(struct translation));
memset(&_mutex, 0, sizeof(_mutex));
_bt_block_allocator = new BlockAllocator();
- toku_mutex_init(&_mutex, nullptr);
- nb_mutex_init(&_safe_file_size_lock);
+ toku_mutex_init(*block_table_mutex_key, &_mutex, nullptr);
+ nb_mutex_init(*safe_file_size_lock_mutex_key,
+ *safe_file_size_lock_rwlock_key,
+ &_safe_file_size_lock);
}
// Fill in the checkpointed translation from buffer, and copy checkpointed to
@@ -129,7 +136,7 @@ int block_table::create_from_buffer(
_copy_translation(&_current, &_checkpointed, TRANSLATION_CURRENT);
// Determine the file size
- int64_t file_size;
+ int64_t file_size = 0;
r = toku_os_get_file_size(fd, &file_size);
lazy_assert_zero(r);
invariant(file_size >= 0);
diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
index fcab9fc675e..b24d72a5dff 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
@@ -417,8 +417,10 @@ static size_t serialize_ft_min_size(uint32_t version) {
switch (version) {
case FT_LAYOUT_VERSION_29:
size += sizeof(uint64_t); // logrows in ft
+ // fallthrough
case FT_LAYOUT_VERSION_28:
size += sizeof(uint32_t); // fanout in ft
+ // fallthrough
case FT_LAYOUT_VERSION_27:
case FT_LAYOUT_VERSION_26:
case FT_LAYOUT_VERSION_25:
@@ -427,10 +429,12 @@ static size_t serialize_ft_min_size(uint32_t version) {
case FT_LAYOUT_VERSION_22:
case FT_LAYOUT_VERSION_21:
size += sizeof(MSN); // max_msn_in_ft
+ // fallthrough
case FT_LAYOUT_VERSION_20:
case FT_LAYOUT_VERSION_19:
size += 1; // compression method
size += sizeof(MSN); // highest_unused_msn_for_upgrade
+ // fallthrough
case FT_LAYOUT_VERSION_18:
size += sizeof(uint64_t); // time_of_last_optimize_begin
size += sizeof(uint64_t); // time_of_last_optimize_end
@@ -438,9 +442,11 @@ static size_t serialize_ft_min_size(uint32_t version) {
size += sizeof(MSN); // msn_at_start_of_last_completed_optimize
size -= 8; // removed num_blocks_to_upgrade_14
size -= 8; // removed num_blocks_to_upgrade_13
+ // fallthrough
case FT_LAYOUT_VERSION_17:
size += 16;
invariant(sizeof(STAT64INFO_S) == 16);
+ // fallthrough
case FT_LAYOUT_VERSION_16:
case FT_LAYOUT_VERSION_15:
size += 4; // basement node size
@@ -448,8 +454,10 @@ static size_t serialize_ft_min_size(uint32_t version) {
// num_blocks_to_upgrade, now one int each for upgrade
// from 13, 14
size += 8; // time of last verification
+ // fallthrough
case FT_LAYOUT_VERSION_14:
size += 8; // TXNID that created
+ // fallthrough
case FT_LAYOUT_VERSION_13:
size += (4 // build_id
+
@@ -459,7 +467,7 @@ static size_t serialize_ft_min_size(uint32_t version) {
+
8 // time_of_last_modification
);
- // fall through
+ // fallthrough
case FT_LAYOUT_VERSION_12:
size += (+8 // "tokudata"
+
diff --git a/storage/tokudb/PerconaFT/ft/serialize/sub_block.cc b/storage/tokudb/PerconaFT/ft/serialize/sub_block.cc
index c967d4b4c1c..6dc1f82844a 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/sub_block.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/sub_block.cc
@@ -51,6 +51,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/threadpool.h"
#include "util/x1764.h"
+toku_instr_key *workset_lock_mutex_key;
+toku_instr_key *ws_worker_wait_key;
+
SUB_BLOCK sub_block_creat(void) {
SUB_BLOCK XMALLOC(sb);
sub_block_init(sb);
diff --git a/storage/tokudb/PerconaFT/ft/serialize/workset.h b/storage/tokudb/PerconaFT/ft/serialize/workset.h
index 073741fccb1..295eb73cec9 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/workset.h
+++ b/storage/tokudb/PerconaFT/ft/serialize/workset.h
@@ -41,6 +41,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <toku_list.h>
#include <toku_pthread.h>
+extern toku_instr_key *ws_worker_wait_key;
+
// The work struct is the base class for work to be done by some threads
struct work {
struct toku_list next;
@@ -54,16 +56,14 @@ struct workset {
toku_cond_t worker_wait; // a condition variable used to wait for all of the worker to release their reference on the workset
};
-static inline void
-workset_init(struct workset *ws) {
- toku_mutex_init(&ws->lock, NULL);
+static inline void workset_init(struct workset *ws) {
+ toku_mutex_init(*workset_lock_mutex_key, &ws->lock, nullptr);
toku_list_init(&ws->worklist);
- ws->refs = 1; // the calling thread gets a reference
- toku_cond_init(&ws->worker_wait, NULL);
+ ws->refs = 1; // the calling thread gets a reference
+ toku_cond_init(*ws_worker_wait_key, &ws->worker_wait, nullptr);
}
-static inline void
-workset_destroy(struct workset *ws) {
+static inline void workset_destroy(struct workset *ws) {
invariant(toku_list_empty(&ws->worklist));
toku_cond_destroy(&ws->worker_wait);
toku_mutex_destroy(&ws->lock);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-4357.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-4357.cc
index 8bbda295462..0af5c8185a9 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-4357.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-4357.cc
@@ -71,21 +71,26 @@ cachetable_test (void) {
void* v1;
long s1;
- r = toku_cachetable_get_and_pin(
- f1,
- make_blocknum(1),
- toku_cachetable_hash(f1, make_blocknum(1)),
- &v1,
- &s1,
- def_write_callback(NULL), def_fetch, def_pf_req_callback, def_pf_callback,
- true,
- NULL
- );
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ toku_cachetable_hash(f1, make_blocknum(1)),
+ &v1,
+ &s1,
+ def_write_callback(NULL),
+ def_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ true,
+ NULL);
toku_pthread_t pin_nonblocking_tid;
- r = toku_pthread_create(&pin_nonblocking_tid, NULL, pin_nonblocking, NULL);
- assert_zero(r);
+ r = toku_pthread_create(toku_uninstrumented,
+ &pin_nonblocking_tid,
+ nullptr,
+ pin_nonblocking,
+ nullptr);
+ assert_zero(r);
// sleep 3 seconds
- usleep(3*1024*1024);
+ usleep(3 * 1024 * 1024);
r = toku_test_cachetable_unpin_and_remove(f1, make_blocknum(1), NULL, NULL);
assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-4365.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-4365.cc
index 9c54c086f5b..7bee0b80770 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-4365.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-4365.cc
@@ -71,15 +71,16 @@ static void *put_same_key(void *arg) {
return arg;
}
-
toku_pthread_t put_tid;
-static void test_remove_key(CACHEKEY* UU(cachekey), bool UU(for_checkpoint), void* UU(extra)) {
- int r = toku_pthread_create(&put_tid, NULL, put_same_key, NULL);
- assert_zero(r);
+static void test_remove_key(CACHEKEY *UU(cachekey),
+ bool UU(for_checkpoint),
+ void *UU(extra)) {
+ int r = toku_pthread_create(
+ toku_uninstrumented, &put_tid, nullptr, put_same_key, nullptr);
+ assert_zero(r);
}
-
static void
cachetable_test (void) {
const int test_limit = 12;
@@ -92,21 +93,26 @@ cachetable_test (void) {
void* v1;
long s1;
- r = toku_cachetable_get_and_pin(
- f1,
- make_blocknum(1),
- toku_cachetable_hash(f1, make_blocknum(1)),
- &v1,
- &s1,
- def_write_callback(NULL), def_fetch, def_pf_req_callback, def_pf_callback,
- true,
- NULL
- );
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ toku_cachetable_hash(f1, make_blocknum(1)),
+ &v1,
+ &s1,
+ def_write_callback(nullptr),
+ def_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ true,
+ nullptr);
toku_pthread_t pin_nonblocking_tid;
- r = toku_pthread_create(&pin_nonblocking_tid, NULL, pin_nonblocking, NULL);
- assert_zero(r);
+ r = toku_pthread_create(toku_uninstrumented,
+ &pin_nonblocking_tid,
+ nullptr,
+ pin_nonblocking,
+ nullptr);
+ assert_zero(r);
// sleep 3 seconds
- usleep(3*1024*1024);
+ usleep(3 * 1024 * 1024);
r = toku_test_cachetable_unpin_and_remove(f1, make_blocknum(1), test_remove_key, NULL);
assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-5097.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-5097.cc
index c1b6e0a94f2..5ab0df88e08 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-5097.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-5097.cc
@@ -153,13 +153,16 @@ cachetable_test (void) {
assert(r == 0);
}
- // at this point, we have a dirty PAIR in the cachetable associated with cachefile f1
- // launch a thread that will put another PAIR in the cachetable, and get partial eviction started
+ // at this point, we have a dirty PAIR in the cachetable associated with
+ // cachefile f1
+ // launch a thread that will put another PAIR in the cachetable, and get
+ // partial eviction started
toku_pthread_t tid;
- r = toku_pthread_create(&tid, NULL, f2_pin, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, f2_pin, nullptr);
assert_zero(r);
- usleep(2*1024*1024);
+ usleep(2 * 1024 * 1024);
check_flush = true;
toku_cachefile_close(&f1, false, ZERO_LSN);
if (enable_partial_eviction)
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-5978-2.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-5978-2.cc
index b462d76eeee..0b5110ddd99 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-5978-2.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-5978-2.cc
@@ -114,14 +114,14 @@ unpin_two (void* UU(v)) {
);
assert_zero(r);
- // at this point, we have p1 pinned, want to start a thread to do an unpin_and_remove
- // on p1
- r = toku_pthread_create(
- &unpin_and_remove_tid,
- NULL,
- unpin_and_remove_one,
- NULL
- );
+ // at this point, we have p1 pinned, want to start a thread to do an
+ // unpin_and_remove
+ // on p1
+ r = toku_pthread_create(toku_uninstrumented,
+ &unpin_and_remove_tid,
+ nullptr,
+ unpin_and_remove_one,
+ nullptr);
assert_zero(r);
// sleep to give a chance for the unpin_and_remove to get going
usleep(512*1024);
@@ -173,9 +173,9 @@ cachetable_test (void) {
r = toku_cachetable_get_and_pin(f1, make_blocknum(2), 2, &v1, &s1, wc, fetch_two, def_pf_req_callback, def_pf_callback, true, NULL);
assert_zero(r);
-
toku_pthread_t tid1;
- r = toku_pthread_create(&tid1, NULL, repin_one, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid1, nullptr, repin_one, nullptr);
assert_zero(r);
void *ret;
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-5978.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-5978.cc
index ee68ab3ef0b..a4ff6c33e6a 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-5978.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-5978.cc
@@ -199,9 +199,11 @@ cachetable_test (void) {
toku_pthread_t tid1;
toku_pthread_t tid2;
- r = toku_pthread_create(&tid1, NULL, repin_one, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid1, nullptr, repin_one, nullptr);
assert_zero(r);
- r = toku_pthread_create(&tid2, NULL, repin_two, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid2, nullptr, repin_two, nullptr);
assert_zero(r);
// unpin 1 and 2 so tid1 and tid2 can make progress
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-checkpoint-pending.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-checkpoint-pending.cc
index 3dd3a15e2de..5e87fed740d 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-checkpoint-pending.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-checkpoint-pending.cc
@@ -158,14 +158,24 @@ static void checkpoint_pending(void) {
// the checkpoint should cause n writes, but since n <= the cachetable size,
// all items should be kept in the cachetable
- n_flush = n_write_me = n_keep_me = n_fetch = 0; expect_value = 42;
- //printf("E42\n");
+ n_flush = n_write_me = n_keep_me = n_fetch = 0;
+ expect_value = 42;
+ // printf("E42\n");
toku_pthread_t checkpoint_thread, update_thread;
- r = toku_pthread_create(&checkpoint_thread, NULL, do_checkpoint, NULL); assert(r==0);
- r = toku_pthread_create(&update_thread, NULL, do_update, NULL); assert(r==0);
- r = toku_pthread_join(checkpoint_thread, 0); assert(r==0);
- r = toku_pthread_join(update_thread, 0); assert(r==0);
-
+ r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_thread,
+ nullptr,
+ do_checkpoint,
+ nullptr);
+ assert(r == 0);
+ r = toku_pthread_create(
+ toku_uninstrumented, &update_thread, nullptr, do_update, nullptr);
+ assert(r == 0);
+ r = toku_pthread_join(checkpoint_thread, 0);
+ assert(r == 0);
+ r = toku_pthread_join(update_thread, 0);
+ assert(r == 0);
+
assert(n_flush == N && n_write_me == N && n_keep_me == N);
// after the checkpoint, all of the items should be 43
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-cleaner-thread-attrs-accumulate.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-cleaner-thread-attrs-accumulate.cc
index c1e7b373e83..dd6c674af24 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-cleaner-thread-attrs-accumulate.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-cleaner-thread-attrs-accumulate.cc
@@ -91,7 +91,7 @@ run_test (void) {
const int test_limit = 1000;
int r;
CACHETABLE ct;
- toku_mutex_init(&attr_mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &attr_mutex, nullptr);
toku_cachetable_create(&ct, test_limit, ZERO_LSN, nullptr);
const char *fname1 = TOKU_TEST_FILENAME;
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-clone-checkpoint.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-clone-checkpoint.cc
index 50bd20f492e..99d595b1ff1 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-clone-checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-clone-checkpoint.cc
@@ -112,14 +112,17 @@ cachetable_test (void) {
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
toku_cachetable_begin_checkpoint(cp, NULL);
-
clone_flush_started = false;
clone_flush_completed = false;
toku_pthread_t checkpoint_tid;
- r = toku_pthread_create(&checkpoint_tid, NULL, run_end_checkpoint, NULL);
- assert_zero(r);
+ r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ run_end_checkpoint,
+ nullptr);
+ assert_zero(r);
- usleep(1*1024*1024);
+ usleep(1 * 1024 * 1024);
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-pin-checkpoint.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-pin-checkpoint.cc
index 8a270af0566..65b02aebaec 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-pin-checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-pin-checkpoint.cc
@@ -386,19 +386,28 @@ cachetable_test (void) {
run_test = true;
for (int i = 0; i < NUM_MOVER_THREADS; i++) {
- r = toku_pthread_create(&read_random_tid[i], NULL, read_random_numbers, NULL);
+ r = toku_pthread_create(toku_uninstrumented,
+ &read_random_tid[i],
+ nullptr,
+ read_random_numbers,
+ nullptr);
assert_zero(r);
}
for (int i = 0; i < NUM_MOVER_THREADS; i++) {
- r = toku_pthread_create(&move_tid[i], NULL, move_numbers, NULL);
+ r = toku_pthread_create(toku_uninstrumented,
+ &move_tid[i],
+ nullptr,
+ move_numbers,
+ nullptr);
assert_zero(r);
}
- r = toku_pthread_create(&checkpoint_tid, NULL, checkpoints, NULL);
- assert_zero(r);
- r = toku_pthread_create(&time_tid, NULL, test_time, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &checkpoint_tid, nullptr, checkpoints, nullptr);
+ assert_zero(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &time_tid, nullptr, test_time, nullptr);
assert_zero(r);
-
void *ret;
r = toku_pthread_join(time_tid, &ret);
assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-put-checkpoint.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-put-checkpoint.cc
index afc95471116..4cf1678449b 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-put-checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-put-checkpoint.cc
@@ -518,19 +518,28 @@ cachetable_test (void) {
run_test = true;
for (int i = 0; i < NUM_MOVER_THREADS; i++) {
- r = toku_pthread_create(&move_tid[i], NULL, move_numbers, NULL);
+ r = toku_pthread_create(toku_uninstrumented,
+ &move_tid[i],
+ nullptr,
+ move_numbers,
+ nullptr);
assert_zero(r);
}
for (int i = 0; i < NUM_MOVER_THREADS; i++) {
- r = toku_pthread_create(&merge_and_split_tid[i], NULL, merge_and_split, NULL);
+ r = toku_pthread_create(toku_uninstrumented,
+ &merge_and_split_tid[i],
+ nullptr,
+ merge_and_split,
+ nullptr);
assert_zero(r);
}
- r = toku_pthread_create(&checkpoint_tid, NULL, checkpoints, NULL);
- assert_zero(r);
- r = toku_pthread_create(&time_tid, NULL, test_time, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &checkpoint_tid, nullptr, checkpoints, nullptr);
+ assert_zero(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &time_tid, nullptr, test_time, nullptr);
assert_zero(r);
-
void *ret;
r = toku_pthread_join(time_tid, &ret);
assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-rwlock-test.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-rwlock-test.cc
index 9a62f99e1fa..6d8bc28026c 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-rwlock-test.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-rwlock-test.cc
@@ -40,24 +40,22 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
// test create and destroy
-static void
-test_create_destroy (void) {
- struct rwlock the_rwlock, *rwlock = &the_rwlock;
+static void test_create_destroy(void) {
+ struct st_rwlock the_rwlock, *rwlock = &the_rwlock;
- rwlock_init(rwlock);
+ rwlock_init(toku_uninstrumented, rwlock);
rwlock_destroy(rwlock);
}
// test read lock and unlock with no writers
-static void
-test_simple_read_lock (int n) {
- struct rwlock the_rwlock, *rwlock = &the_rwlock;
+static void test_simple_read_lock(int n) {
+ struct st_rwlock the_rwlock, *rwlock = &the_rwlock;
- rwlock_init(rwlock);
+ rwlock_init(toku_uninstrumented, rwlock);
assert(rwlock_readers(rwlock) == 0);
int i;
- for (i=1; i<=n; i++) {
+ for (i = 1; i <= n; i++) {
rwlock_read_lock(rwlock, 0);
assert(rwlock_readers(rwlock) == i);
assert(rwlock_users(rwlock) == i);
@@ -72,11 +70,10 @@ test_simple_read_lock (int n) {
// test write lock and unlock with no readers
-static void
-test_simple_write_lock (void) {
- struct rwlock the_rwlock, *rwlock = &the_rwlock;
+static void test_simple_write_lock(void) {
+ struct st_rwlock the_rwlock, *rwlock = &the_rwlock;
- rwlock_init(rwlock);
+ rwlock_init(toku_uninstrumented, rwlock);
assert(rwlock_users(rwlock) == 0);
rwlock_write_lock(rwlock, 0);
assert(rwlock_writers(rwlock) == 1);
@@ -88,19 +85,17 @@ test_simple_write_lock (void) {
struct rw_event {
int e;
- struct rwlock the_rwlock;
+ struct st_rwlock the_rwlock;
toku_mutex_t mutex;
};
-static void
-rw_event_init (struct rw_event *rwe) {
+static void rw_event_init(struct rw_event *rwe) {
rwe->e = 0;
- rwlock_init(&rwe->the_rwlock);
- toku_mutex_init(&rwe->mutex, 0);
+ rwlock_init(toku_uninstrumented, &rwe->the_rwlock);
+ toku_mutex_init(toku_uninstrumented, &rwe->mutex, nullptr);
}
-static void
-rw_event_destroy (struct rw_event *rwe) {
+static void rw_event_destroy(struct rw_event *rwe) {
rwlock_destroy(&rwe->the_rwlock);
toku_mutex_destroy(&rwe->mutex);
}
@@ -138,10 +133,12 @@ test_writer_priority (void) {
toku_mutex_unlock(&rwe->mutex);
toku_pthread_t tid;
- r = toku_pthread_create(&tid, 0, test_writer_priority_thread, rwe);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, 0, test_writer_priority_thread, rwe);
sleep(1);
toku_mutex_lock(&rwe->mutex);
- rwe->e++; assert(rwe->e == 2);
+ rwe->e++;
+ assert(rwe->e == 2);
toku_mutex_unlock(&rwe->mutex);
sleep(1);
@@ -196,10 +193,12 @@ test_single_writer (void) {
toku_mutex_unlock(&rwe->mutex);
toku_pthread_t tid;
- r = toku_pthread_create(&tid, 0, test_single_writer_thread, rwe);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, 0, test_single_writer_thread, rwe);
sleep(1);
toku_mutex_lock(&rwe->mutex);
- rwe->e++; assert(rwe->e == 2);
+ rwe->e++;
+ assert(rwe->e == 2);
assert(rwlock_writers(&rwe->the_rwlock) == 1);
assert(rwlock_users(&rwe->the_rwlock) == 2);
rwlock_write_unlock(&rwe->the_rwlock);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin-nonblocking.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin-nonblocking.cc
index 8fd8828737a..ebe05e50883 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin-nonblocking.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin-nonblocking.cc
@@ -111,9 +111,20 @@ run_test (void) {
toku_pthread_t fetch_tid;
fetch_called = false;
- r = toku_pthread_create(&fetch_tid, NULL, run_expensive_fetch, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &fetch_tid, nullptr, run_expensive_fetch, nullptr);
sleep(1);
- r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, sleep_fetch, def_pf_req_callback, def_pf_callback, false, NULL);
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ 1,
+ &v1,
+ &s1,
+ wc,
+ sleep_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ false,
+ NULL);
assert_zero(r);
assert(fetch_called);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
@@ -133,9 +144,20 @@ run_test (void) {
toku_pthread_t pf_tid;
pf_called = false;
- r = toku_pthread_create(&pf_tid, NULL, run_expensive_pf, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &pf_tid, nullptr, run_expensive_pf, nullptr);
sleep(1);
- r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, sleep_fetch, def_pf_req_callback, def_pf_callback, false, NULL);
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ 1,
+ &v1,
+ &s1,
+ wc,
+ sleep_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ false,
+ NULL);
assert_zero(r);
assert(pf_called);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin.cc
index 63ca871a459..dd5d59df002 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin.cc
@@ -117,9 +117,20 @@ run_test (void) {
toku_pthread_t fetch_tid;
fetch_called = false;
- r = toku_pthread_create(&fetch_tid, NULL, run_expensive_fetch, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &fetch_tid, nullptr, run_expensive_fetch, nullptr);
sleep(1);
- r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, sleep_fetch, def_pf_req_callback, def_pf_callback, false, NULL);
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ 1,
+ &v1,
+ &s1,
+ wc,
+ sleep_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ false,
+ NULL);
assert_zero(r);
assert(fetch_called);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
@@ -141,9 +152,20 @@ run_test (void) {
toku_pthread_t pf_tid;
pf_called = false;
- r = toku_pthread_create(&pf_tid, NULL, run_expensive_pf, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &pf_tid, nullptr, run_expensive_pf, nullptr);
sleep(1);
- r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, sleep_fetch, def_pf_req_callback, def_pf_callback, false, NULL);
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ 1,
+ &v1,
+ &s1,
+ wc,
+ sleep_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ false,
+ NULL);
assert_zero(r);
assert(pf_called);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-test.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-test.cc
index e4bb5fb0aea..64f688c470d 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-test.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-test.cc
@@ -42,15 +42,13 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
// global data, especially between the test thread and the cachetable
// writeback threads
-toku_mutex_t test_mutex;
+toku_mutex_t test_mutex;
static inline void test_mutex_init(void) {
- toku_mutex_init(&test_mutex, 0);
+ toku_mutex_init(toku_uninstrumented, &test_mutex, nullptr);
}
-static inline void test_mutex_destroy(void) {
- toku_mutex_destroy(&test_mutex);
-}
+static inline void test_mutex_destroy(void) { toku_mutex_destroy(&test_mutex); }
static inline void test_mutex_lock(void) {
toku_mutex_lock(&test_mutex);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-unpin-remove-and-checkpoint.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-unpin-remove-and-checkpoint.cc
index 11baa36e51b..0e44bf10349 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-unpin-remove-and-checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-unpin-remove-and-checkpoint.cc
@@ -86,11 +86,22 @@ run_test (void) {
// now this should mark the pair for checkpoint
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
toku_cachetable_begin_checkpoint(cp, NULL);
- r = toku_cachetable_get_and_pin(f1, make_blocknum(1), toku_cachetable_hash(f1, make_blocknum(1)), &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ toku_cachetable_hash(f1, make_blocknum(1)),
+ &v1,
+ &s1,
+ wc,
+ def_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ true,
+ NULL);
toku_pthread_t mytid;
- r = toku_pthread_create(&mytid, NULL, run_end_chkpt, NULL);
- assert(r==0);
+ r = toku_pthread_create(
+ toku_uninstrumented, &mytid, nullptr, run_end_chkpt, nullptr);
+ assert(r == 0);
// give checkpoint thread a chance to start waiting on lock
sleep(1);
diff --git a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-extractor-errors.cc b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-extractor-errors.cc
index 872b674c784..4bff52ceb1b 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-extractor-errors.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-extractor-errors.cc
@@ -141,7 +141,7 @@ static void test_extractor(int nrows, int nrowsets, bool expect_fail, const char
// setup error injection
toku_set_func_malloc(my_malloc);
toku_set_func_realloc(my_realloc);
- ft_loader_set_os_fwrite(bad_fwrite);
+ toku_set_func_fwrite(bad_fwrite);
toku_set_func_write(bad_write);
toku_set_func_pwrite(bad_pwrite);
ft_loader_set_poll_function(&loader->poll_callback, loader_poll_callback, NULL);
@@ -157,7 +157,7 @@ static void test_extractor(int nrows, int nrowsets, bool expect_fail, const char
toku_set_func_malloc(NULL);
toku_set_func_realloc(NULL);
- ft_loader_set_os_fwrite(NULL);
+ toku_set_func_fwrite(nullptr);
toku_set_func_write(NULL);
toku_set_func_pwrite(NULL);
diff --git a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-merge-files-dbufio.cc b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-merge-files-dbufio.cc
index d1aeff198ff..0b121316738 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-merge-files-dbufio.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-merge-files-dbufio.cc
@@ -393,13 +393,17 @@ static void test (const char *directory, bool is_error) {
toku_pthread_t consumer;
struct consumer_thunk cthunk = {q, 0};
{
- int r = toku_pthread_create(&consumer, NULL, consumer_thread, (void*)&cthunk);
- assert(r==0);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &consumer,
+ nullptr,
+ consumer_thread,
+ static_cast<void *>(&cthunk));
+ assert(r == 0);
}
toku_set_func_malloc_only(my_malloc);
toku_set_func_realloc_only(my_realloc);
- ft_loader_set_os_fwrite(bad_fwrite);
+ toku_set_func_fwrite(bad_fwrite);
toku_set_func_write(bad_write);
toku_set_func_pwrite(bad_pwrite);
toku_set_func_fdopen(bad_fdopen);
@@ -427,7 +431,7 @@ static void test (const char *directory, bool is_error) {
toku_set_func_malloc(NULL);
toku_set_func_realloc(NULL);
- ft_loader_set_os_fwrite(NULL);
+ toku_set_func_fwrite(nullptr);
toku_set_func_write(NULL);
toku_set_func_pwrite(NULL);
toku_set_func_fdopen(NULL);
diff --git a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-writer-errors.cc b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-writer-errors.cc
index 0784ca87a26..e4423319518 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-writer-errors.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-writer-errors.cc
@@ -154,7 +154,7 @@ static int write_dbfile (char *tf_template, int n, char *output_name, bool expec
toku_set_func_malloc_only(my_malloc);
toku_set_func_realloc_only(my_realloc);
- ft_loader_set_os_fwrite(bad_fwrite);
+ toku_set_func_fwrite(bad_fwrite);
toku_set_func_write(bad_write);
toku_set_func_pwrite(bad_pwrite);
ft_loader_set_error_function(&bl.error_callback, NULL, NULL);
@@ -164,7 +164,7 @@ static int write_dbfile (char *tf_template, int n, char *output_name, bool expec
toku_set_func_malloc_only(NULL);
toku_set_func_realloc_only(NULL);
- ft_loader_set_os_fwrite(NULL);
+ toku_set_func_fwrite(nullptr);
toku_set_func_write(NULL);
toku_set_func_pwrite(NULL);
diff --git a/storage/tokudb/PerconaFT/ft/tests/log-test4.cc b/storage/tokudb/PerconaFT/ft/tests/log-test4.cc
index a31181deb30..e0bbedb95bf 100644
--- a/storage/tokudb/PerconaFT/ft/tests/log-test4.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/log-test4.cc
@@ -63,11 +63,14 @@ test_main (int argc __attribute__((__unused__)),
r = toku_logger_close(&logger); assert(r == 0);
{
- toku_struct_stat statbuf;
- sprintf(logname, "%s/log000000000000.tokulog%d", TOKU_TEST_FILENAME, TOKU_LOG_VERSION);
- r = toku_stat(logname, &statbuf);
- assert(r==0);
- assert(statbuf.st_size==12+5);
+ toku_struct_stat statbuf;
+ sprintf(logname,
+ "%s/log000000000000.tokulog%d",
+ TOKU_TEST_FILENAME,
+ TOKU_LOG_VERSION);
+ r = toku_stat(logname, &statbuf, toku_uninstrumented);
+ assert(r == 0);
+ assert(statbuf.st_size == 12 + 5);
}
toku_os_recursive_delete(TOKU_TEST_FILENAME);
return 0;
diff --git a/storage/tokudb/PerconaFT/ft/tests/log-test5.cc b/storage/tokudb/PerconaFT/ft/tests/log-test5.cc
index d4e31af22dc..fed9467a4ae 100644
--- a/storage/tokudb/PerconaFT/ft/tests/log-test5.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/log-test5.cc
@@ -81,14 +81,14 @@ test_main (int argc __attribute__((__unused__)),
struct dirent *dirent;
while ((dirent=readdir(dir))) {
if (strncmp(dirent->d_name, "log", 3)!=0) continue;
- char fname[TOKU_PATH_MAX+1];
- toku_path_join(fname, 2, TOKU_TEST_FILENAME, dirent->d_name);
- toku_struct_stat statbuf;
- r = toku_stat(fname, &statbuf);
- assert(r==0);
- assert(statbuf.st_size<=LSIZE+10);
- }
- r = closedir(dir);
+ char fname[TOKU_PATH_MAX + 1];
+ toku_path_join(fname, 2, TOKU_TEST_FILENAME, dirent->d_name);
+ toku_struct_stat statbuf;
+ r = toku_stat(fname, &statbuf, toku_uninstrumented);
+ assert(r == 0);
+ assert(statbuf.st_size <= LSIZE + 10);
+ }
+ r = closedir(dir);
assert(r==0);
}
toku_os_recursive_delete(TOKU_TEST_FILENAME);
diff --git a/storage/tokudb/PerconaFT/ft/tests/log-test6.cc b/storage/tokudb/PerconaFT/ft/tests/log-test6.cc
index 4d17488c57c..0e8b94566df 100644
--- a/storage/tokudb/PerconaFT/ft/tests/log-test6.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/log-test6.cc
@@ -86,11 +86,14 @@ test_main (int argc __attribute__((__unused__)),
{
char logname[PATH_MAX];
- toku_struct_stat statbuf;
- sprintf(logname, "%s/log000000000000.tokulog%d", TOKU_TEST_FILENAME, TOKU_LOG_VERSION);
- r = toku_stat(logname, &statbuf);
- assert(r==0);
- assert(statbuf.st_size<=LSIZE);
+ toku_struct_stat statbuf;
+ sprintf(logname,
+ "%s/log000000000000.tokulog%d",
+ TOKU_TEST_FILENAME,
+ TOKU_LOG_VERSION);
+ r = toku_stat(logname, &statbuf, toku_uninstrumented);
+ assert(r == 0);
+ assert(statbuf.st_size <= LSIZE);
}
toku_os_recursive_delete(TOKU_TEST_FILENAME);
return 0;
diff --git a/storage/tokudb/PerconaFT/ft/tests/recovery-bad-last-entry.cc b/storage/tokudb/PerconaFT/ft/tests/recovery-bad-last-entry.cc
index 431ee4b5e50..a3c934d1f4b 100644
--- a/storage/tokudb/PerconaFT/ft/tests/recovery-bad-last-entry.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/recovery-bad-last-entry.cc
@@ -83,11 +83,16 @@ run_test(void) {
r = toku_dup2(devnul, fileno(stderr)); assert(r==fileno(stderr));
r = close(devnul); assert(r==0);
- char fname[TOKU_PATH_MAX+1];
- sprintf(fname, "%s/%s%d", TOKU_TEST_FILENAME, "log000000000000.tokulog", TOKU_LOG_VERSION);
-
- r = toku_stat(fname, &st); assert(r==0);
- if ( st.st_size - trim > magic_begin_end_checkpoint_sz ) {
+ char fname[TOKU_PATH_MAX + 1];
+ sprintf(fname,
+ "%s/%s%d",
+ TOKU_TEST_FILENAME,
+ "log000000000000.tokulog",
+ TOKU_LOG_VERSION);
+
+ r = toku_stat(fname, &st, toku_uninstrumented);
+ assert(r == 0);
+ if (st.st_size - trim > magic_begin_end_checkpoint_sz) {
r = truncate(fname, st.st_size - trim);
CKERR(r);
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-bjm.cc b/storage/tokudb/PerconaFT/ft/tests/test-bjm.cc
index 97e00c42b95..6afe5b9f7c4 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-bjm.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-bjm.cc
@@ -71,12 +71,16 @@ static void bjm_test(void) {
bjm_reset(bjm);
r = bjm_add_background_job(bjm);
- assert_zero(r);
- toku_pthread_t tid;
- r = toku_pthread_create(&tid, NULL, finish_bjm, NULL);
assert_zero(r);
- usleep(2*1024*1024);
- // should return non-zero because tid is waiting
+ toku_pthread_t tid;
+ r = toku_pthread_create(toku_uninstrumented,
+ &tid,
+ nullptr,
+ finish_bjm,
+ nullptr);
+ assert_zero(r);
+ usleep(2 * 1024 * 1024);
+ // should return non-zero because tid is waiting
// for background jobs to finish
r = bjm_add_background_job(bjm);
assert(r != 0);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
index 3e5d9bba817..06a26614885 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
@@ -113,10 +113,14 @@ static void flusher_callback(int state, void* extra) {
if ((state == flt_flush_before_child_pin && !after_child_pin) ||
(state == ft_flush_aflter_child_pin && after_child_pin)) {
checkpoint_called = true;
- int r = toku_pthread_create(&checkpoint_tid, NULL, do_checkpoint, NULL);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ do_checkpoint,
+ nullptr);
assert_zero(r);
while (!checkpoint_callback_called) {
- usleep(1*1024*1024);
+ usleep(1 * 1024 * 1024);
}
}
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
index cb316127ef7..1029dfef320 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
@@ -103,10 +103,14 @@ static void flusher_callback(int state, void* extra) {
}
if (state == desired_state) {
checkpoint_called = true;
- int r = toku_pthread_create(&checkpoint_tid, NULL, do_checkpoint, NULL);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ do_checkpoint,
+ nullptr);
assert_zero(r);
while (!checkpoint_callback_called) {
- usleep(1*1024*1024);
+ usleep(1 * 1024 * 1024);
}
}
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
index 5f8485ac4ec..208ebe3ca31 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
@@ -103,10 +103,14 @@ static void flusher_callback(int state, void* extra) {
}
if (state == desired_state) {
checkpoint_called = true;
- int r = toku_pthread_create(&checkpoint_tid, NULL, do_checkpoint, NULL);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ do_checkpoint,
+ nullptr);
assert_zero(r);
while (!checkpoint_callback_called) {
- usleep(1*1024*1024);
+ usleep(1 * 1024 * 1024);
}
}
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
index 70c3ba22a0c..2b29de409b1 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
@@ -113,10 +113,14 @@ static void flusher_callback(int state, void* extra) {
if ((state == flt_flush_before_split && !after_split) ||
(state == flt_flush_during_split && after_split)) {
checkpoint_called = true;
- int r = toku_pthread_create(&checkpoint_tid, NULL, do_checkpoint, NULL);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ do_checkpoint,
+ nullptr);
assert_zero(r);
while (!checkpoint_callback_called) {
- usleep(1*1024*1024);
+ usleep(1 * 1024 * 1024);
}
}
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test3681.cc b/storage/tokudb/PerconaFT/ft/tests/test3681.cc
index e5e24a88246..9e4a46e8dfe 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test3681.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test3681.cc
@@ -91,13 +91,35 @@ static void *startb (void *n) {
return NULL;
}
-static void test3681 (void) {
+static void test3681(void) {
setup();
- toku_pthread_t a,b;
- { int r; r = toku_pthread_create(&a, NULL, starta, NULL); assert(r==0); }
- { int r; r = toku_pthread_create(&b, NULL, startb, NULL); assert(r==0); }
- { int r; void *v; r = toku_pthread_join(a, &v); assert(r==0); assert(v==NULL); }
- { int r; void *v; r = toku_pthread_join(b, &v); assert(r==0); assert(v==NULL); }
+ toku_pthread_t a, b;
+ {
+ int r;
+ r = toku_pthread_create(
+ toku_uninstrumented, &a, nullptr, starta, nullptr);
+ assert(r == 0);
+ }
+ {
+ int r;
+ r = toku_pthread_create(
+ toku_uninstrumented, &b, nullptr, startb, nullptr);
+ assert(r == 0);
+ }
+ {
+ int r;
+ void *v;
+ r = toku_pthread_join(a, &v);
+ assert(r == 0);
+ assert(v == NULL);
+ }
+ {
+ int r;
+ void *v;
+ r = toku_pthread_join(b, &v);
+ assert(r == 0);
+ assert(v == NULL);
+ }
finish();
}
diff --git a/storage/tokudb/PerconaFT/ft/txn/roll.cc b/storage/tokudb/PerconaFT/ft/txn/roll.cc
index 97afd2f5bdb..7228de06f34 100644
--- a/storage/tokudb/PerconaFT/ft/txn/roll.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/roll.cc
@@ -195,14 +195,14 @@ int toku_rollback_frename(BYTESTRING old_iname,
toku_cachetable_get_fname_in_cwd(cachetable, new_iname.data),
&toku_free);
- if (toku_stat(old_iname_full.get(), &stat) == -1) {
+ if (toku_stat(old_iname_full.get(), &stat, toku_uninstrumented) == -1) {
if (ENOENT == errno)
old_exist = false;
else
return 1;
}
- if (toku_stat(new_iname_full.get(), &stat) == -1) {
+ if (toku_stat(new_iname_full.get(), &stat, toku_uninstrumented) == -1) {
if (ENOENT == errno || ENAMETOOLONG == errno)
new_exist = false;
else
@@ -220,7 +220,7 @@ int toku_rollback_frename(BYTESTRING old_iname,
// removed
// and the new file is renamed.
if (old_exist && new_exist &&
- (toku_os_unlink(old_iname_full.get()) == -1 ||
+ (toku_os_delete(old_iname_full.get()) == -1 ||
toku_os_rename(new_iname_full.get(), old_iname_full.get()) == -1 ||
toku_fsync_directory(new_iname_full.get()) == -1 ||
toku_fsync_directory(old_iname_full.get()) == -1))
diff --git a/storage/tokudb/PerconaFT/ft/txn/rollback_log_node_cache.cc b/storage/tokudb/PerconaFT/ft/txn/rollback_log_node_cache.cc
index 71b1e79277c..5e1ab746936 100644
--- a/storage/tokudb/PerconaFT/ft/txn/rollback_log_node_cache.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/rollback_log_node_cache.cc
@@ -41,7 +41,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "txn/rollback_log_node_cache.h"
-void rollback_log_node_cache::init (uint32_t max_num_avail_nodes) {
+toku_instr_key* rollback_log_node_cache_mutex_key;
+
+void rollback_log_node_cache::init(uint32_t max_num_avail_nodes) {
XMALLOC_N(max_num_avail_nodes, m_avail_blocknums);
m_max_num_avail = max_num_avail_nodes;
m_first = 0;
@@ -49,7 +51,7 @@ void rollback_log_node_cache::init (uint32_t max_num_avail_nodes) {
toku_pthread_mutexattr_t attr;
toku_mutexattr_init(&attr);
toku_mutexattr_settype(&attr, TOKU_MUTEX_ADAPTIVE);
- toku_mutex_init(&m_mutex, &attr);
+ toku_mutex_init(*rollback_log_node_cache_mutex_key, &m_mutex, &attr);
toku_mutexattr_destroy(&attr);
}
diff --git a/storage/tokudb/PerconaFT/ft/txn/txn.cc b/storage/tokudb/PerconaFT/ft/txn/txn.cc
index a3ce6beb7b0..7327cbd9d24 100644
--- a/storage/tokudb/PerconaFT/ft/txn/txn.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/txn.cc
@@ -45,8 +45,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "ft/txn/txn_manager.h"
#include "util/status.h"
-void
-toku_txn_get_status(TXN_STATUS s) {
+toku_instr_key *txn_lock_mutex_key;
+toku_instr_key *txn_state_lock_mutex_key;
+toku_instr_key *result_state_cond_key;
+
+void toku_txn_get_status(TXN_STATUS s) {
txn_status.init();
*s = txn_status;
}
@@ -225,74 +228,74 @@ static void toku_txn_create_txn (
static txn_child_manager tcm;
- struct tokutxn new_txn = {
- .txnid = {.parent_id64 = TXNID_NONE, .child_id64 = TXNID_NONE },
- .snapshot_txnid64 = TXNID_NONE,
- .snapshot_type = for_recovery ? TXN_SNAPSHOT_NONE : snapshot_type,
- .for_recovery = for_recovery,
- .logger = logger,
- .parent = parent_tokutxn,
- .child = NULL,
- .child_manager_s = tcm,
- .child_manager = NULL,
- .container_db_txn = container_db_txn,
- .live_root_txn_list = nullptr,
- .xids = NULL,
- .snapshot_next = NULL,
- .snapshot_prev = NULL,
- .begin_was_logged = false,
- .declared_read_only = read_only,
- .do_fsync = false,
- .force_fsync_on_commit = false,
- .do_fsync_lsn = ZERO_LSN,
- .xa_xid = {0, 0, 0, ""},
- .progress_poll_fun = NULL,
- .progress_poll_fun_extra = NULL,
-
- // You cannot initialize txn_lock a TOKU_MUTEX_INITIALIZER, because we
- // will initialize it in the code below, and it cannot already
- // be initialized at that point. Also, in general, you don't
- // get to use PTHREAD_MUTEX_INITALIZER (which is what is inside
- // TOKU_MUTEX_INITIALIZER) except in static variables, and this
- // is initializing an auto variable.
- //
- // And we cannot simply avoid initializing these fields
- // because, although it avoids -Wmissing-field-initializer
- // errors under gcc, it gets other errors about non-trivial
- // designated initializers not being supported.
-
- .txn_lock = ZERO_MUTEX_INITIALIZER, // Not TOKU_MUTEX_INITIALIZER
- .open_fts = open_fts,
- .roll_info = roll_info,
- .state_lock = ZERO_MUTEX_INITIALIZER, // Not TOKU_MUTEX_INITIALIZER
- .state_cond = ZERO_COND_INITIALIZER, // Not TOKU_COND_INITIALIZER
- .state = TOKUTXN_LIVE,
- .num_pin = 0,
- .client_id = 0,
- .client_extra = nullptr,
- .start_time = time(NULL),
- };
+struct tokutxn new_txn = {
+ .txnid = {.parent_id64 = TXNID_NONE, .child_id64 = TXNID_NONE },
+ .snapshot_txnid64 = TXNID_NONE,
+ .snapshot_type = for_recovery ? TXN_SNAPSHOT_NONE : snapshot_type,
+ .for_recovery = for_recovery,
+ .logger = logger,
+ .parent = parent_tokutxn,
+ .child = NULL,
+ .child_manager_s = tcm,
+ .child_manager = NULL,
+ .container_db_txn = container_db_txn,
+ .live_root_txn_list = nullptr,
+ .xids = NULL,
+ .snapshot_next = NULL,
+ .snapshot_prev = NULL,
+ .begin_was_logged = false,
+ .declared_read_only = read_only,
+ .do_fsync = false,
+ .force_fsync_on_commit = false,
+ .do_fsync_lsn = ZERO_LSN,
+ .xa_xid = {0, 0, 0, ""},
+ .progress_poll_fun = NULL,
+ .progress_poll_fun_extra = NULL,
+
+ // You cannot initialize txn_lock a TOKU_MUTEX_INITIALIZER, because we
+ // will initialize it in the code below, and it cannot already
+ // be initialized at that point. Also, in general, you don't
+ // get to use PTHREAD_MUTEX_INITALIZER (which is what is inside
+ // TOKU_MUTEX_INITIALIZER) except in static variables, and this
+ // is initializing an auto variable.
+ //
+ // And we cannot simply avoid initializing these fields
+ // because, although it avoids -Wmissing-field-initializer
+ // errors under gcc, it gets other errors about non-trivial
+ // designated initializers not being supported.
+
+ .txn_lock = ZERO_MUTEX_INITIALIZER, // Not TOKU_MUTEX_INITIALIZER
+ .open_fts = open_fts,
+ .roll_info = roll_info,
+ .state_lock = ZERO_MUTEX_INITIALIZER, // Not TOKU_MUTEX_INITIALIZER
+ .state_cond = ZERO_COND_INITIALIZER, // Not TOKU_COND_INITIALIZER
+ .state = TOKUTXN_LIVE,
+ .num_pin = 0,
+ .client_id = 0,
+ .client_extra = nullptr,
+ .start_time = time(NULL),
+};
- TOKUTXN result = NULL;
- XMEMDUP(result, &new_txn);
- invalidate_xa_xid(&result->xa_xid);
- if (parent_tokutxn == NULL) {
- result->child_manager = &result->child_manager_s;
- result->child_manager->init(result);
+TOKUTXN result = NULL;
+XMEMDUP(result, &new_txn);
+invalidate_xa_xid(&result->xa_xid);
+if (parent_tokutxn == NULL) {
+ result->child_manager = &result->child_manager_s;
+ result->child_manager->init(result);
}
else {
result->child_manager = parent_tokutxn->child_manager;
}
- toku_mutex_init(&result->txn_lock, nullptr);
+ toku_mutex_init(*txn_lock_mutex_key, &result->txn_lock, nullptr);
toku_pthread_mutexattr_t attr;
toku_mutexattr_init(&attr);
toku_mutexattr_settype(&attr, TOKU_MUTEX_ADAPTIVE);
- toku_mutex_init(&result->state_lock, &attr);
+ toku_mutex_init(*txn_state_lock_mutex_key, &result->state_lock, &attr);
toku_mutexattr_destroy(&attr);
- toku_cond_init(&result->state_cond, nullptr);
+ toku_cond_init(*result_state_cond_key, &result->state_cond, nullptr);
*tokutxn = result;
diff --git a/storage/tokudb/PerconaFT/ft/txn/txn_child_manager.cc b/storage/tokudb/PerconaFT/ft/txn/txn_child_manager.cc
index db110127c55..99a21331b0a 100644
--- a/storage/tokudb/PerconaFT/ft/txn/txn_child_manager.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/txn_child_manager.cc
@@ -39,6 +39,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "ft/logger/log-internal.h"
#include "ft/txn/txn_child_manager.h"
+toku_instr_key *txn_child_manager_mutex_key;
+
//
// initialized a txn_child_manager,
// when called, root->txnid.parent_id64 may not yet be set
@@ -53,7 +55,7 @@ void txn_child_manager::init(TOKUTXN root) {
toku_pthread_mutexattr_t attr;
toku_mutexattr_init(&attr);
toku_mutexattr_settype(&attr, TOKU_MUTEX_ADAPTIVE);
- toku_mutex_init(&m_mutex, &attr);
+ toku_mutex_init(*txn_child_manager_mutex_key, &m_mutex, &attr);
toku_mutexattr_destroy(&attr);
}
diff --git a/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc b/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc
index 8fe52b10597..1b55844bc7d 100644
--- a/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc
@@ -56,7 +56,10 @@ void set_test_txn_sync_callback(void (*cb) (pthread_t, void *), void *extra) {
}
bool garbage_collection_debug = false;
-static bool txn_records_snapshot(TXN_SNAPSHOT_TYPE snapshot_type, struct tokutxn *parent) {
+toku_instr_key *txn_manager_lock_mutex_key;
+
+static bool txn_records_snapshot(TXN_SNAPSHOT_TYPE snapshot_type,
+ struct tokutxn *parent) {
if (snapshot_type == TXN_COPIES_SNAPSHOT) {
return false;
}
@@ -248,9 +251,10 @@ verify_snapshot_system(TXN_MANAGER txn_manager UU()) {
live_root_txns_omt.destroy();
}
-void toku_txn_manager_init(TXN_MANAGER* txn_managerp) {
+void toku_txn_manager_init(TXN_MANAGER *txn_managerp) {
TXN_MANAGER XCALLOC(txn_manager);
- toku_mutex_init(&txn_manager->txn_manager_lock, NULL);
+ toku_mutex_init(
+ *txn_manager_lock_mutex_key, &txn_manager->txn_manager_lock, nullptr);
txn_manager->live_root_txns.create();
txn_manager->live_root_ids.create();
txn_manager->snapshot_head = NULL;
diff --git a/storage/tokudb/PerconaFT/locktree/lock_request.cc b/storage/tokudb/PerconaFT/locktree/lock_request.cc
index 0151b5bd466..c0829e3f4e1 100644
--- a/storage/tokudb/PerconaFT/locktree/lock_request.cc
+++ b/storage/tokudb/PerconaFT/locktree/lock_request.cc
@@ -62,7 +62,7 @@ void lock_request::create(void) {
m_state = state::UNINITIALIZED;
m_info = nullptr;
- toku_cond_init(&m_wait_cond, nullptr);
+ toku_cond_init(*lock_request_m_wait_cond_key, &m_wait_cond, nullptr);
m_start_test_callback = nullptr;
m_start_before_pending_test_callback = nullptr;
diff --git a/storage/tokudb/PerconaFT/locktree/locktree.cc b/storage/tokudb/PerconaFT/locktree/locktree.cc
index 2fbf078bdd6..069aae26f66 100644
--- a/storage/tokudb/PerconaFT/locktree/locktree.cc
+++ b/storage/tokudb/PerconaFT/locktree/locktree.cc
@@ -51,7 +51,6 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
// the locktree source file instead of the header.
#include "concurrent_tree.h"
-
namespace toku {
// A locktree represents the set of row locks owned by all transactions
@@ -87,12 +86,13 @@ void lt_lock_request_info::init(void) {
pending_lock_requests.create();
pending_is_empty = true;
ZERO_STRUCT(mutex);
- toku_mutex_init(&mutex, nullptr);
+ toku_mutex_init(*locktree_request_info_mutex_key, &mutex, nullptr);
retry_want = retry_done = 0;
ZERO_STRUCT(counters);
ZERO_STRUCT(retry_mutex);
- toku_mutex_init(&retry_mutex, nullptr);
- toku_cond_init(&retry_cv, nullptr);
+ toku_mutex_init(
+ *locktree_request_info_retry_mutex_key, &retry_mutex, nullptr);
+ toku_cond_init(*locktree_request_info_retry_cv_key, &retry_cv, nullptr);
running_retry = false;
TOKU_VALGRIND_HG_DISABLE_CHECKING(&pending_is_empty,
diff --git a/storage/tokudb/PerconaFT/locktree/manager.cc b/storage/tokudb/PerconaFT/locktree/manager.cc
index 91ff7c5a007..6bb5c77bf32 100644
--- a/storage/tokudb/PerconaFT/locktree/manager.cc
+++ b/storage/tokudb/PerconaFT/locktree/manager.cc
@@ -56,9 +56,8 @@ void locktree_manager::create(lt_create_cb create_cb, lt_destroy_cb destroy_cb,
m_lt_destroy_callback = destroy_cb;
m_lt_escalate_callback = escalate_cb;
m_lt_escalate_callback_extra = escalate_extra;
-
ZERO_STRUCT(m_mutex);
- toku_mutex_init(&m_mutex, nullptr);
+ toku_mutex_init(*manager_mutex_key, &m_mutex, nullptr);
ZERO_STRUCT(m_lt_counters);
@@ -346,7 +345,8 @@ int locktree_manager::check_current_lock_constraints(bool big_txn) {
void locktree_manager::escalator_init(void) {
ZERO_STRUCT(m_escalation_mutex);
- toku_mutex_init(&m_escalation_mutex, nullptr);
+ toku_mutex_init(
+ *manager_escalation_mutex_key, &m_escalation_mutex, nullptr);
m_escalation_count = 0;
m_escalation_time = 0;
m_wait_escalation_count = 0;
@@ -403,8 +403,8 @@ struct escalate_args {
void locktree_manager::locktree_escalator::create(void) {
ZERO_STRUCT(m_escalator_mutex);
- toku_mutex_init(&m_escalator_mutex, nullptr);
- toku_cond_init(&m_escalator_done, nullptr);
+ toku_mutex_init(*manager_escalator_mutex_key, &m_escalator_mutex, nullptr);
+ toku_cond_init(*manager_m_escalator_done_key, &m_escalator_done, nullptr);
m_escalator_running = false;
}
diff --git a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_1big7lt_1small.cc b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_1big7lt_1small.cc
index 6c143f963ba..32029b5bddd 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_1big7lt_1small.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_1big7lt_1small.cc
@@ -201,12 +201,14 @@ int main(int argc, const char *argv[]) {
locktree *small_lt = mgr.get_lt(dict_id, dbt_comparator, nullptr);
// create the worker threads
- struct big_arg big_arg = { &mgr, big_lt, n_big, 1000 };
- r = toku_pthread_create(&big_id, nullptr, big_f, &big_arg);
+ struct big_arg big_arg = {&mgr, big_lt, n_big, 1000};
+ r = toku_pthread_create(
+ toku_uninstrumented, &big_id, nullptr, big_f, &big_arg);
assert(r == 0);
- struct small_arg small_arg = { &mgr, small_lt, 2000, 0 };
- r = toku_pthread_create(&small_id, nullptr, small_f, &small_arg);
+ struct small_arg small_arg = {&mgr, small_lt, 2000, 0};
+ r = toku_pthread_create(
+ toku_uninstrumented, &small_id, nullptr, small_f, &small_arg);
assert(r == 0);
// wait for some escalations to occur
diff --git a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_1lt.cc b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_1lt.cc
index 17eb07060d4..ff59a7bdd5c 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_1lt.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_1lt.cc
@@ -169,8 +169,10 @@ int main(int argc, const char *argv[]) {
struct arg big_arg[n_big];
pthread_t big_ids[n_big];
for (int i = 0; i < n_big; i++) {
- big_arg[i] = { &mgr, lt[i % n_lt], (TXNID)(1000+i), i == 0 ? 1 : -1000000000 };
- r = toku_pthread_create(&big_ids[i], nullptr, big_f, &big_arg[i]);
+ big_arg[i] = {
+ &mgr, lt[i % n_lt], (TXNID)(1000 + i), i == 0 ? 1 : -1000000000};
+ r = toku_pthread_create(
+ toku_uninstrumented, &big_ids[i], nullptr, big_f, &big_arg[i]);
assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_2lt.cc b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_2lt.cc
index 4326e8fafc2..be1ddaba9d0 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_2lt.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_2lt.cc
@@ -169,8 +169,10 @@ int main(int argc, const char *argv[]) {
struct arg big_arg[n_big];
pthread_t big_ids[n_big];
for (int i = 0; i < n_big; i++) {
- big_arg[i] = { &mgr, lt[i % n_lt], (TXNID)(1000+i), i == 0 ? 1 : -1000000000 };
- r = toku_pthread_create(&big_ids[i], nullptr, big_f, &big_arg[i]);
+ big_arg[i] = {
+ &mgr, lt[i % n_lt], (TXNID)(1000 + i), i == 0 ? 1 : -1000000000};
+ r = toku_pthread_create(
+ toku_uninstrumented, &big_ids[i], nullptr, big_f, &big_arg[i]);
assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_stalls.cc b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_stalls.cc
index d146d94e337..9dc9596a7ed 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_stalls.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_stalls.cc
@@ -182,9 +182,10 @@ int main(int argc, const char *argv[]) {
locktree *lt_1 = mgr.get_lt(dict_id_1, dbt_comparator, nullptr);
// create the worker threads
- struct arg big_arg = { &mgr, lt_0, 1000 };
+ struct arg big_arg = {&mgr, lt_0, 1000};
pthread_t big_id;
- r = toku_pthread_create(&big_id, nullptr, big_f, &big_arg);
+ r = toku_pthread_create(
+ toku_uninstrumented, &big_id, nullptr, big_f, &big_arg);
assert(r == 0);
const int n_small = 7;
@@ -192,8 +193,12 @@ int main(int argc, const char *argv[]) {
struct arg small_args[n_small];
for (int i = 0; i < n_small; i++) {
- small_args[i] = { &mgr, lt_1, (TXNID)(2000+i), i };
- r = toku_pthread_create(&small_ids[i], nullptr, small_f, &small_args[i]);
+ small_args[i] = {&mgr, lt_1, (TXNID)(2000 + i), i};
+ r = toku_pthread_create(toku_uninstrumented,
+ &small_ids[i],
+ nullptr,
+ small_f,
+ &small_args[i]);
assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/locktree/tests/manager_parallel_locktree_get_release.cc b/storage/tokudb/PerconaFT/locktree/tests/manager_parallel_locktree_get_release.cc
index ec9ef21583c..08ce63140a5 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/manager_parallel_locktree_get_release.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/manager_parallel_locktree_get_release.cc
@@ -71,7 +71,8 @@ void manager_unit_test::test_reference_release_lt(void) {
const int nthreads = 2;
pthread_t ids[nthreads];
for (int i = 0; i < nthreads; i++) {
- r = toku_pthread_create(&ids[i], nullptr, my_tester, &mgr);
+ r = toku_pthread_create(
+ toku_uninstrumented, &ids[i], nullptr, my_tester, &mgr);
assert(r == 0);
}
for (int i = 0; i < nthreads; i++) {
diff --git a/storage/tokudb/PerconaFT/locktree/treenode.cc b/storage/tokudb/PerconaFT/locktree/treenode.cc
index 4f43291fe76..cc3a4969643 100644
--- a/storage/tokudb/PerconaFT/locktree/treenode.cc
+++ b/storage/tokudb/PerconaFT/locktree/treenode.cc
@@ -38,9 +38,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <toku_race_tools.h>
-void treenode::mutex_lock(void) {
- toku_mutex_lock(&m_mutex);
-}
+// TODO: source location info might have to be pulled up one caller
+// to be useful
+void treenode::mutex_lock(void) { toku_mutex_lock(&m_mutex); }
void treenode::mutex_unlock(void) {
toku_mutex_unlock(&m_mutex);
@@ -58,7 +58,7 @@ void treenode::init(const comparator *cmp) {
toku_pthread_mutexattr_t attr;
toku_mutexattr_init(&attr);
toku_mutexattr_settype(&attr, TOKU_MUTEX_ADAPTIVE);
- toku_mutex_init(&m_mutex, &attr);
+ toku_mutex_init(*treenode_mutex_key, &m_mutex, &attr);
toku_mutexattr_destroy(&attr);
m_left_child.set(nullptr);
m_right_child.set(nullptr);
diff --git a/storage/tokudb/PerconaFT/portability/CMakeLists.txt b/storage/tokudb/PerconaFT/portability/CMakeLists.txt
index 4793db63cc1..e5576a5d463 100644
--- a/storage/tokudb/PerconaFT/portability/CMakeLists.txt
+++ b/storage/tokudb/PerconaFT/portability/CMakeLists.txt
@@ -8,6 +8,7 @@ set(tokuportability_srcs
portability
toku_assert
toku_crash
+ toku_instr_mysql
toku_path
toku_pthread
toku_time
@@ -53,6 +54,10 @@ if (NOT DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
DESTINATION ${INSTALL_LIBDIR}
COMPONENT tokukv_libs_shared
)
+else ()
+ set_property(SOURCE toku_pthread portability APPEND PROPERTY
+ COMPILE_DEFINITIONS MYSQL_TOKUDB_ENGINE=1 )
+ target_link_libraries(${LIBTOKUPORTABILITY} LINK_PRIVATE mysys)
endif ()
add_subdirectory(tests)
diff --git a/storage/tokudb/PerconaFT/portability/file.cc b/storage/tokudb/PerconaFT/portability/file.cc
index 0e3efc1a12a..485bfac8514 100644
--- a/storage/tokudb/PerconaFT/portability/file.cc
+++ b/storage/tokudb/PerconaFT/portability/file.cc
@@ -52,9 +52,12 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "toku_path.h"
#include <portability/toku_atomic.h>
+toku_instr_key *tokudb_file_data_key;
+
static int toku_assert_on_write_enospc = 0;
static const int toku_write_enospc_sleep = 1;
-static uint64_t toku_write_enospc_last_report; // timestamp of most recent report to error log
+static uint64_t toku_write_enospc_last_report; // timestamp of most recent
+ // report to error log
static time_t toku_write_enospc_last_time; // timestamp of most recent ENOSPC
static uint32_t toku_write_enospc_current; // number of threads currently blocked on ENOSPC
static uint64_t toku_write_enospc_total; // total number of times ENOSPC was returned from an attempt to write
@@ -142,11 +145,17 @@ static ssize_t (*t_full_pwrite)(int, const void *, size_t, off_t);
static FILE * (*t_fdopen)(int, const char *);
static FILE * (*t_fopen)(const char *, const char *);
static int (*t_open)(const char *, int, int);
-static int (*t_fclose)(FILE *);
+static int (*t_fclose)(FILE *);
static ssize_t (*t_read)(int, void *, size_t);
static ssize_t (*t_pread)(int, void *, size_t, off_t);
+static size_t (*os_fwrite_fun)(const void *, size_t, size_t, FILE *) = nullptr;
+
+void toku_set_func_fwrite(
+ size_t (*fwrite_fun)(const void *, size_t, size_t, FILE *)) {
+ os_fwrite_fun = fwrite_fun;
+}
-void toku_set_func_write (ssize_t (*write_fun)(int, const void *, size_t)) {
+void toku_set_func_write(ssize_t (*write_fun)(int, const void *, size_t)) {
t_write = write_fun;
}
@@ -186,9 +195,63 @@ void toku_set_func_pread (ssize_t (*pread_fun)(int, void *, size_t, off_t)) {
t_pread = pread_fun;
}
-void
-toku_os_full_write (int fd, const void *buf, size_t len) {
- const char *bp = (const char *) buf;
+int toku_os_delete_with_source_location(const char *name,
+ const char *src_file,
+ uint src_line) {
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_name_close_begin(io_annotation,
+ *tokudb_file_data_key,
+ toku_instr_file_op::file_delete,
+ name,
+ src_file,
+ src_line);
+ const int result = unlink(name);
+
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_close_end(io_annotation, result);
+
+ return result;
+}
+
+int toku_os_rename_with_source_location(const char *old_name,
+ const char *new_name,
+ const char *src_file,
+ uint src_line) {
+ int result;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_name_io_begin(io_annotation,
+ *tokudb_file_data_key,
+ toku_instr_file_op::file_rename,
+ new_name,
+ 0,
+ src_file,
+ src_line);
+
+ result = rename(old_name, new_name);
+ /* Regsiter the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, 0);
+
+ return result;
+}
+
+void toku_os_full_write_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line) {
+ const char *bp = (const char *)buf;
+ size_t bytes_written = len;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_write,
+ fd,
+ len,
+ src_file,
+ src_line);
+
while (len > 0) {
ssize_t r;
if (t_full_write) {
@@ -205,14 +268,30 @@ toku_os_full_write (int fd, const void *buf, size_t len) {
}
}
assert(len == 0);
+
+ /* Register the result value with the instrumentaion system */
+ toku_instr_file_io_end(io_annotation, bytes_written);
}
-int
-toku_os_write (int fd, const void *buf, size_t len) {
- const char *bp = (const char *) buf;
+int toku_os_write_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line) {
+ const char *bp = (const char *)buf;
int result = 0;
+ ssize_t r;
+
+ size_t bytes_written = len;
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_write,
+ fd,
+ len,
+ src_file,
+ src_line);
+
while (len > 0) {
- ssize_t r;
if (t_write) {
r = t_write(fd, bp, len);
} else {
@@ -222,17 +301,33 @@ toku_os_write (int fd, const void *buf, size_t len) {
result = errno;
break;
}
- len -= r;
- bp += r;
+ len -= r;
+ bp += r;
}
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, bytes_written - len);
+
return result;
}
-void
-toku_os_full_pwrite (int fd, const void *buf, size_t len, toku_off_t off) {
- assert(0==((long long)buf)%512);
- assert((len%512 == 0) && (off%512)==0); // to make pwrite work.
- const char *bp = (const char *) buf;
+void toku_os_full_pwrite_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line) {
+ assert(0 == ((long long)buf) % 512);
+ assert((len % 512 == 0) && (off % 512) == 0); // to make pwrite work.
+ const char *bp = (const char *)buf;
+
+ size_t bytes_written = len;
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_write,
+ fd,
+ len,
+ src_file,
+ src_line);
while (len > 0) {
ssize_t r;
if (t_full_pwrite) {
@@ -250,71 +345,209 @@ toku_os_full_pwrite (int fd, const void *buf, size_t len, toku_off_t off) {
}
}
assert(len == 0);
-}
-ssize_t
-toku_os_pwrite (int fd, const void *buf, size_t len, toku_off_t off) {
- assert(0==((long long)buf)%512); // these asserts are to ensure that direct I/O will work.
- assert(0==len %512);
- assert(0==off %512);
- const char *bp = (const char *) buf;
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, bytes_written);
+}
+
+ssize_t toku_os_pwrite_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line) {
+ assert(0 ==
+ ((long long)buf) %
+ 512); // these asserts are to ensure that direct I/O will work.
+ assert(0 == len % 512);
+ assert(0 == off % 512);
+ const char *bp = (const char *)buf;
ssize_t result = 0;
+ ssize_t r;
+
+ size_t bytes_written = len;
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_write,
+ fd,
+ len,
+ src_file,
+ src_line);
while (len > 0) {
- ssize_t r;
- if (t_pwrite) {
- r = t_pwrite(fd, bp, len, off);
- } else {
- r = pwrite(fd, bp, len, off);
- }
+ r = (t_pwrite) ? t_pwrite(fd, bp, len, off) : pwrite(fd, bp, len, off);
+
if (r < 0) {
result = errno;
break;
}
len -= r;
- bp += r;
- off += r;
+ bp += r;
+ off += r;
+ }
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, bytes_written - len);
+
+ return result;
+}
+
+int toku_os_fwrite_with_source_location(const void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line) {
+ int result = 0;
+ size_t bytes_written;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_stream_io_begin(io_annotation,
+ toku_instr_file_op::file_write,
+ *stream,
+ nmemb,
+ src_file,
+ src_line);
+
+ if (os_fwrite_fun) {
+ bytes_written = os_fwrite_fun(ptr, size, nmemb, stream->file);
+ } else {
+ bytes_written = fwrite(ptr, size, nmemb, stream->file);
+ }
+
+ if (bytes_written != nmemb) {
+ if (os_fwrite_fun) // if using hook to induce artificial errors (for
+ // testing) ...
+ result = get_maybe_error_errno(); // ... then there is no error in
+ // the stream, but there is one
+ // in errno
+ else
+ result = ferror(stream->file);
+ invariant(result != 0); // Should we assert here?
+ }
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, bytes_written);
+
+ return result;
+}
+
+int toku_os_fread_with_source_location(void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line) {
+ int result = 0;
+ size_t bytes_read;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_stream_io_begin(io_annotation,
+ toku_instr_file_op::file_read,
+ *stream,
+ nmemb,
+ src_file,
+ src_line);
+
+ if ((bytes_read = fread(ptr, size, nmemb, stream->file)) != nmemb) {
+ if ((feof(stream->file)))
+ result = EOF;
+ else
+ result = ferror(stream->file);
+ invariant(result != 0); // Should we assert here?
}
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, bytes_read);
+
return result;
}
-FILE *
-toku_os_fdopen(int fildes, const char *mode) {
- FILE * rval;
- if (t_fdopen)
- rval = t_fdopen(fildes, mode);
- else
- rval = fdopen(fildes, mode);
+TOKU_FILE *toku_os_fdopen_with_source_location(int fildes,
+ const char *mode,
+ const char *filename,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line) {
+ TOKU_FILE *XMALLOC(rval);
+ if (FT_LIKELY(rval != nullptr)) {
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_open_begin(io_annotation,
+ instr_key,
+ toku_instr_file_op::file_stream_open,
+ filename,
+ src_file,
+ src_line);
+
+ rval->file = (t_fdopen) ? t_fdopen(fildes, mode) : fdopen(fildes, mode);
+ toku_instr_file_stream_open_end(io_annotation, *rval);
+
+ if (FT_UNLIKELY(rval->file == nullptr)) {
+ toku_free(rval);
+ rval = nullptr;
+ }
+ }
return rval;
}
-
-FILE *
-toku_os_fopen(const char *filename, const char *mode){
- FILE * rval;
- if (t_fopen)
- rval = t_fopen(filename, mode);
- else
- rval = fopen(filename, mode);
+TOKU_FILE *toku_os_fopen_with_source_location(const char *filename,
+ const char *mode,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line) {
+ TOKU_FILE *XMALLOC(rval);
+ if (FT_UNLIKELY(rval == nullptr))
+ return nullptr;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_open_begin(io_annotation,
+ instr_key,
+ toku_instr_file_op::file_stream_open,
+ filename,
+ src_file,
+ src_line);
+ rval->file = t_fopen ? t_fopen(filename, mode) : fopen(filename, mode);
+ /* Register the returning "file" value with the system */
+ toku_instr_file_stream_open_end(io_annotation, *rval);
+
+ if (FT_UNLIKELY(rval->file == nullptr)) {
+ toku_free(rval);
+ rval = nullptr;
+ }
return rval;
}
-int
-toku_os_open(const char *path, int oflag, int mode) {
- int rval;
+int toku_os_open_with_source_location(const char *path,
+ int oflag,
+ int mode,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line) {
+ int fd;
+ toku_io_instrumentation io_annotation;
+ /* register a file open or creation depending on "oflag" */
+ toku_instr_file_open_begin(
+ io_annotation,
+ instr_key,
+ ((oflag & O_CREAT) ? toku_instr_file_op::file_create
+ : toku_instr_file_op::file_open),
+ path,
+ src_file,
+ src_line);
if (t_open)
- rval = t_open(path, oflag, mode);
+ fd = t_open(path, oflag, mode);
else
- rval = open(path, oflag, mode);
- return rval;
+ fd = open(path, oflag, mode);
+
+ toku_instr_file_open_end(io_annotation, fd);
+ return fd;
}
-int
-toku_os_open_direct(const char *path, int oflag, int mode) {
+int toku_os_open_direct(const char *path,
+ int oflag,
+ int mode,
+ const toku_instr_key &instr_key) {
int rval;
#if defined(HAVE_O_DIRECT)
- rval = toku_os_open(path, oflag | O_DIRECT, mode);
+ rval = toku_os_open(path, oflag | O_DIRECT, mode, instr_key);
#elif defined(HAVE_F_NOCACHE)
- rval = toku_os_open(path, oflag, mode);
+ rval = toku_os_open(path, oflag, mode, instr_key);
if (rval >= 0) {
int r = fcntl(rval, F_NOCACHE, 1);
if (r == -1) {
@@ -327,63 +560,112 @@ toku_os_open_direct(const char *path, int oflag, int mode) {
return rval;
}
-int
-toku_os_fclose(FILE * stream) {
+int toku_os_fclose_with_source_location(TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line) {
int rval = -1;
- if (t_fclose)
- rval = t_fclose(stream);
- else { // if EINTR, retry until success
- while (rval != 0) {
- rval = fclose(stream);
- if (rval && (errno != EINTR))
- break;
- }
+ if (FT_LIKELY(stream != nullptr)) {
+ /* register a file stream close " */
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_stream_close_begin(
+ io_annotation,
+ toku_instr_file_op::file_stream_close,
+ *stream,
+ src_file,
+ src_line);
+
+ if (t_fclose)
+ rval = t_fclose(stream->file);
+ else { // if EINTR, retry until success
+ while (rval != 0) {
+ rval = fclose(stream->file);
+ if (rval && (errno != EINTR))
+ break;
+ }
+ }
+ /* Register the returning "rval" value with the system */
+ toku_instr_file_close_end(io_annotation, rval);
+ toku_free(stream);
+ stream = nullptr;
}
return rval;
}
-int
-toku_os_close(int fd) { // if EINTR, retry until success
+int toku_os_close_with_source_location(
+ int fd,
+ const char *src_file,
+ uint src_line) { // if EINTR, retry until success
+ /* register the file close */
int r = -1;
+
+ /* register a file descriptor close " */
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_fd_close_begin(
+ io_annotation, toku_instr_file_op::file_close, fd, src_file, src_line);
while (r != 0) {
- r = close(fd);
- if (r) {
- int rr = errno;
- if (rr!=EINTR) printf("rr=%d (%s)\n", rr, strerror(rr));
- assert(rr==EINTR);
- }
+ r = close(fd);
+ if (r) {
+ int rr = errno;
+ if (rr != EINTR)
+ printf("rr=%d (%s)\n", rr, strerror(rr));
+ assert(rr == EINTR);
+ }
}
- return r;
-}
-
-int toku_os_rename(const char *old_name, const char *new_name) {
- return rename(old_name, new_name);
-}
-int toku_os_unlink(const char *path) { return unlink(path); }
+ /* Regsiter the returning value with the system */
+ toku_instr_file_close_end(io_annotation, r);
-ssize_t
-toku_os_read(int fd, void *buf, size_t count) {
- ssize_t r;
- if (t_read)
- r = t_read(fd, buf, count);
- else
- r = read(fd, buf, count);
return r;
}
-ssize_t
-toku_os_pread (int fd, void *buf, size_t count, off_t offset) {
- assert(0==((long long)buf)%512);
- assert(0==count%512);
- assert(0==offset%512);
- ssize_t r;
+ssize_t toku_os_read_with_source_location(int fd,
+ void *buf,
+ size_t count,
+ const char *src_file,
+ uint src_line) {
+ ssize_t bytes_read;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_read,
+ fd,
+ count,
+ src_file,
+ src_line);
+
+ bytes_read = (t_read) ? t_read(fd, buf, count) : read(fd, buf, count);
+
+ toku_instr_file_io_end(io_annotation, bytes_read);
+
+ return bytes_read;
+}
+
+ssize_t inline_toku_os_pread_with_source_location(int fd,
+ void *buf,
+ size_t count,
+ off_t offset,
+ const char *src_file,
+ uint src_line) {
+ assert(0 == ((long long)buf) % 512);
+ assert(0 == count % 512);
+ assert(0 == offset % 512);
+ ssize_t bytes_read;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_read,
+ fd,
+ count,
+ src_file,
+ src_line);
if (t_pread) {
- r = t_pread(fd, buf, count, offset);
+ bytes_read = t_pread(fd, buf, count, offset);
} else {
- r = pread(fd, buf, count, offset);
+ bytes_read = pread(fd, buf, count, offset);
}
- return r;
+ toku_instr_file_io_end(io_annotation, bytes_read);
+
+ return bytes_read;
}
void toku_os_recursive_delete(const char *path) {
@@ -411,13 +693,24 @@ void toku_set_func_fsync(int (*fsync_function)(int)) {
}
// keep trying if fsync fails because of EINTR
-static void file_fsync_internal (int fd) {
+void file_fsync_internal_with_source_location(int fd,
+ const char *src_file,
+ uint src_line) {
uint64_t tstart = toku_current_time_microsec();
int r = -1;
uint64_t eintr_count = 0;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_sync,
+ fd,
+ 0,
+ src_file,
+ src_line);
+
while (r != 0) {
- if (t_fsync) {
- r = t_fsync(fd);
+ if (t_fsync) {
+ r = t_fsync(fd);
} else {
r = fsync(fd);
}
@@ -429,6 +722,9 @@ static void file_fsync_internal (int fd) {
toku_sync_fetch_and_add(&toku_fsync_count, 1);
uint64_t duration = toku_current_time_microsec() - tstart;
toku_sync_fetch_and_add(&toku_fsync_time, duration);
+
+ toku_instr_file_io_end(io_annotation, 0);
+
if (duration >= toku_long_fsync_threshold) {
toku_sync_fetch_and_add(&toku_long_fsync_count, 1);
toku_sync_fetch_and_add(&toku_long_fsync_time, duration);
diff --git a/storage/tokudb/PerconaFT/portability/memory.cc b/storage/tokudb/PerconaFT/portability/memory.cc
index 5430ff84b70..9594158cf38 100644
--- a/storage/tokudb/PerconaFT/portability/memory.cc
+++ b/storage/tokudb/PerconaFT/portability/memory.cc
@@ -104,7 +104,13 @@ toku_memory_startup(void) {
size_t lg_chunk; // log2 of the mmap threshold
size_t lg_chunk_length = sizeof lg_chunk;
result = mallctl_f("opt.lg_chunk", &lg_chunk, &lg_chunk_length, NULL, 0);
- if (result == 0)
+ if (result)
+ {
+ status.mmap_threshold = 1 << 21; // Default value.
+ // Incompatible jemalloc change.
+ result = 0;
+ }
+ else
status.mmap_threshold = 1 << lg_chunk;
}
}
diff --git a/storage/tokudb/PerconaFT/portability/portability.cc b/storage/tokudb/PerconaFT/portability/portability.cc
index 19f445a85d7..dfa5153cc66 100644
--- a/storage/tokudb/PerconaFT/portability/portability.cc
+++ b/storage/tokudb/PerconaFT/portability/portability.cc
@@ -79,6 +79,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "toku_os.h"
#include "toku_time.h"
#include "memory.h"
+
+#include "toku_instrumentation.h"
+
#include <portability/toku_atomic.h>
#include <util/partitioned_counter.h>
@@ -172,13 +175,26 @@ toku_os_get_phys_memory_size(void) {
#endif
}
-int
-toku_os_get_file_size(int fildes, int64_t *fsize) {
+int toku_os_get_file_size_with_source_location(int fildes,
+ int64_t *fsize,
+ const char *src_file,
+ uint src_line) {
toku_struct_stat sbuf;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_stat,
+ fildes,
+ 0,
+ src_file,
+ src_line);
+
int r = fstat(fildes, &sbuf);
- if (r==0) {
+ if (r == 0) {
*fsize = sbuf.st_size;
}
+ toku_instr_file_io_end(io_annotation, 0);
+
return r;
}
@@ -272,15 +288,39 @@ toku_os_get_max_process_data_size(uint64_t *maxdata) {
return r;
}
-int
-toku_stat(const char *name, toku_struct_stat *buf) {
+int toku_stat_with_source_location(const char *name,
+ toku_struct_stat *buf,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line) {
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_name_io_begin(io_annotation,
+ instr_key,
+ toku_instr_file_op::file_stat,
+ name,
+ 0,
+ src_file,
+ src_line);
int r = stat(name, buf);
+
+ toku_instr_file_io_end(io_annotation, 0);
return r;
}
-int
-toku_fstat(int fd, toku_struct_stat *buf) {
+int toku_os_fstat_with_source_location(int fd,
+ toku_struct_stat *buf,
+ const char *src_file,
+ uint src_line) {
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_stat,
+ fd,
+ 0,
+ src_file,
+ src_line);
+
int r = fstat(fd, buf);
+ toku_instr_file_io_end(io_annotation, 0);
return r;
}
@@ -427,5 +467,9 @@ void __attribute__((constructor)) toku_portability_helgrind_ignore(void);
void
toku_portability_helgrind_ignore(void) {
TOKU_VALGRIND_HG_DISABLE_CHECKING(&toku_cached_hz, sizeof toku_cached_hz);
- TOKU_VALGRIND_HG_DISABLE_CHECKING(&toku_cached_pagesize, sizeof toku_cached_pagesize);
+ TOKU_VALGRIND_HG_DISABLE_CHECKING(&toku_cached_pagesize,
+ sizeof toku_cached_pagesize);
}
+
+static const pfs_key_t pfs_not_instrumented = 0xFFFFFFFF;
+toku_instr_key toku_uninstrumented(pfs_not_instrumented);
diff --git a/storage/tokudb/PerconaFT/portability/tests/rwlock_condvar.h b/storage/tokudb/PerconaFT/portability/tests/rwlock_condvar.h
index 92f2fb354f7..d1ebc81e1dc 100644
--- a/storage/tokudb/PerconaFT/portability/tests/rwlock_condvar.h
+++ b/storage/tokudb/PerconaFT/portability/tests/rwlock_condvar.h
@@ -107,10 +107,10 @@ get_waitstate(void)
#endif
int toku_cv_fair_rwlock_init (toku_cv_fair_rwlock_t *rwlock) {
- rwlock->state=0;
+ rwlock->state = 0;
rwlock->waiters_head = NULL;
rwlock->waiters_tail = NULL;
- toku_mutex_init(&rwlock->mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &rwlock->mutex, nullptr);
return 0;
}
diff --git a/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rdlock.cc b/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rdlock.cc
index 364bd7d3766..62aa5205f3c 100644
--- a/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rdlock.cc
+++ b/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rdlock.cc
@@ -48,7 +48,7 @@ int test_main(int argc __attribute__((__unused__)), char *const argv[] __attribu
toku_pthread_rwlock_t rwlock;
ZERO_STRUCT(rwlock);
- toku_pthread_rwlock_init(&rwlock, NULL);
+ toku_pthread_rwlock_init(toku_uninstrumented, &rwlock, nullptr);
toku_pthread_rwlock_rdlock(&rwlock);
toku_pthread_rwlock_rdlock(&rwlock);
toku_pthread_rwlock_rdunlock(&rwlock);
diff --git a/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rwr.cc b/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rwr.cc
index 3ca9e06bff7..92b30421ba9 100644
--- a/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rwr.cc
+++ b/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rwr.cc
@@ -71,13 +71,19 @@ int test_main(int argc , char *const argv[] ) {
toku_pthread_t tid;
void *retptr;
- toku_pthread_rwlock_init(&rwlock, NULL);
- state = 37; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
+ toku_pthread_rwlock_init(toku_uninstrumented, &rwlock, nullptr);
+ state = 37;
+ if (verbose)
+ printf("%s:%d\n", __FUNCTION__, __LINE__);
toku_pthread_rwlock_rdlock(&rwlock);
- r = toku_pthread_create(&tid, NULL, f, &rwlock); assert(r == 0);
+ r = toku_pthread_create(toku_uninstrumented, &tid, nullptr, f, &rwlock);
+ assert(r == 0);
- assert(state==37); state = 42; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
+ assert(state == 37);
+ state = 42;
+ if (verbose)
+ printf("%s:%d\n", __FUNCTION__, __LINE__);
sleep(4);
assert(state==16); state = 44; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
toku_pthread_rwlock_rdlock(&rwlock);
diff --git a/storage/tokudb/PerconaFT/portability/tests/test-stat.cc b/storage/tokudb/PerconaFT/portability/tests/test-stat.cc
index 494a17bd074..57201764afb 100644
--- a/storage/tokudb/PerconaFT/portability/tests/test-stat.cc
+++ b/storage/tokudb/PerconaFT/portability/tests/test-stat.cc
@@ -47,10 +47,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
static void test_stat(const char *dirname, int result, int ex_errno) {
int r;
toku_struct_stat buf;
- r = toku_stat(dirname, &buf);
- //printf("stat %s %d %d\n", dirname, r, errno); fflush(stdout);
- assert(r==result);
- if (r!=0) assert(get_maybe_error_errno() == ex_errno);
+ r = toku_stat(dirname, &buf, toku_uninstrumented);
+ // printf("stat %s %d %d\n", dirname, r, errno); fflush(stdout);
+ assert(r == result);
+ if (r != 0)
+ assert(get_maybe_error_errno() == ex_errno);
}
int main(void) {
diff --git a/storage/tokudb/PerconaFT/portability/tests/test-toku-malloc.cc b/storage/tokudb/PerconaFT/portability/tests/test-toku-malloc.cc
index 1e1c7533c15..0d99b36b51a 100644
--- a/storage/tokudb/PerconaFT/portability/tests/test-toku-malloc.cc
+++ b/storage/tokudb/PerconaFT/portability/tests/test-toku-malloc.cc
@@ -53,10 +53,12 @@ int main(void) {
int i;
const int max_threads = 2;
toku_pthread_t tids[max_threads];
- for (i=0; i<max_threads; i++) {
- r = toku_pthread_create(&tids[i], NULL, f, 0); assert(r == 0);
+ for (i = 0; i < max_threads; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, f, nullptr);
+ assert(r == 0);
}
- for (i=0; i<max_threads; i++) {
+ for (i = 0; i < max_threads; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/portability/toku_assert.h b/storage/tokudb/PerconaFT/portability/toku_assert.h
index 26a71cede7d..b0a7be3287b 100644
--- a/storage/tokudb/PerconaFT/portability/toku_assert.h
+++ b/storage/tokudb/PerconaFT/portability/toku_assert.h
@@ -53,13 +53,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#error NDEBUG should not be set
#endif
-static inline int get_error_errno(void);
+inline int get_error_errno(void);
-static inline int
-get_maybe_error_errno(void)
-{
- return errno;
-}
+static inline int get_maybe_error_errno(void) { return errno; }
static inline void
set_errno(int new_errno)
@@ -139,12 +135,10 @@ void db_env_do_backtrace(FILE *outf);
#define paranoid_invariant(a) ((void) 0)
#define paranoid_invariant_null(a) ((void) 0)
#define paranoid_invariant_notnull(a) ((void) 0)
-#define paranoid_invariant_zero(a) ((void) 0)
+#define paranoid_invariant_zero(a) ((void)0)
#endif
-static inline int
-get_error_errno(void)
-{
+inline int get_error_errno(void) {
invariant(errno);
return errno;
}
diff --git a/storage/tokudb/PerconaFT/portability/toku_debug_sync.h b/storage/tokudb/PerconaFT/portability/toku_debug_sync.h
index b5394e58d68..cbe72b16912 100644
--- a/storage/tokudb/PerconaFT/portability/toku_debug_sync.h
+++ b/storage/tokudb/PerconaFT/portability/toku_debug_sync.h
@@ -43,13 +43,14 @@ struct tokutxn;
#if defined(ENABLED_DEBUG_SYNC)
/*
- the below macros are defined in my_global.h, which is included in m_string.h,
+ the below macros are defined in my_global.h
the same macros are defined in TokuSetupCompiler.cmake as compiler options,
undefine them here to avoid build errors
*/
#undef __STDC_FORMAT_MACROS
#undef __STDC_LIMIT_MACROS
+#include "my_global.h"
#include "m_string.h"
#include "debug_sync.h"
diff --git a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc
new file mode 100644
index 00000000000..b7b4c0ab233
--- /dev/null
+++ b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc
@@ -0,0 +1,365 @@
+#ifdef MYSQL_TOKUDB_ENGINE
+#include "toku_portability.h"
+#include "toku_pthread.h"
+
+toku_instr_probe_pfs::toku_instr_probe_pfs(const toku_instr_key &key)
+ : mutex(new toku_mutex_t) {
+ toku_mutex_init(key, mutex.get(), nullptr);
+}
+
+toku_instr_probe_pfs::~toku_instr_probe_pfs() {
+ toku_mutex_destroy(mutex.get());
+}
+
+// Thread instrumentation
+
+int toku_pthread_create(const toku_instr_key &key,
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void *),
+ void *arg) {
+#if (MYSQL_VERSION_MAJOR >= 5) && (MYSQL_VERSION_MINOR >= 7)
+ return PSI_THREAD_CALL(spawn_thread)(
+ key.id(), reinterpret_cast<my_thread_handle *>(thread),
+ attr, start_routine, arg);
+#else
+ return PSI_THREAD_CALL(spawn_thread)(
+ key.id(), thread, attr, start_routine, arg);
+#endif
+}
+
+void toku_instr_register_current_thread(const toku_instr_key &key) {
+ struct PSI_thread *psi_thread =
+ PSI_THREAD_CALL(new_thread)(key.id(), nullptr, 0);
+ PSI_THREAD_CALL(set_thread)(psi_thread);
+}
+
+void toku_instr_delete_current_thread() {
+ PSI_THREAD_CALL(delete_current_thread)();
+}
+
+// I/O instrumentation
+
+void toku_instr_file_open_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker =
+ PSI_FILE_CALL(get_thread_file_name_locker)(
+ &io_instr.state, key.id(), static_cast<PSI_file_operation>(op),
+ name, io_instr.locker);
+ if (io_instr.locker != nullptr) {
+ PSI_FILE_CALL(start_file_open_wait)
+ (io_instr.locker, src_file, src_line);
+ }
+}
+
+void toku_instr_file_stream_open_end(toku_io_instrumentation &io_instr,
+ TOKU_FILE &file) {
+ file.key = nullptr;
+ if (FT_LIKELY(io_instr.locker)) {
+ file.key =
+ PSI_FILE_CALL(end_file_open_wait)(io_instr.locker, file.file);
+ }
+}
+
+void toku_instr_file_open_end(toku_io_instrumentation &io_instr, int fd) {
+ if (FT_LIKELY(io_instr.locker))
+ PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)
+ (io_instr.locker, fd);
+}
+
+void toku_instr_file_name_close_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker =
+ PSI_FILE_CALL(get_thread_file_name_locker)(
+ &io_instr.state, key.id(), static_cast<PSI_file_operation>(op),
+ name,
+ io_instr.locker);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_close_wait)
+ (io_instr.locker, src_file, src_line);
+ }
+}
+
+void toku_instr_file_stream_close_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ const TOKU_FILE &file,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker = nullptr;
+ if (FT_LIKELY(file.key)) {
+ io_instr.locker = PSI_FILE_CALL(get_thread_file_stream_locker)(
+ &io_instr.state, file.key, (PSI_file_operation)op);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_close_wait)
+ (io_instr.locker, src_file, src_line);
+ }
+ }
+}
+
+void toku_instr_file_fd_close_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ int fd,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
+ &io_instr.state, fd, (PSI_file_operation)op);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_close_wait)
+ (io_instr.locker, src_file, src_line);
+ }
+}
+
+void toku_instr_file_close_end(const toku_io_instrumentation &io_instr,
+ int result) {
+ if (FT_LIKELY(io_instr.locker))
+ PSI_FILE_CALL(end_file_close_wait)
+ (io_instr.locker, result);
+}
+
+void toku_instr_file_io_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ int fd,
+ ssize_t count,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
+ &io_instr.state, fd, (PSI_file_operation)op);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_wait)
+ (io_instr.locker, count, src_file, src_line);
+ }
+}
+
+void toku_instr_file_name_io_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ ssize_t count,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker =
+ PSI_FILE_CALL(get_thread_file_name_locker)(&io_instr.state,
+ key.id(),
+ (PSI_file_operation)op,
+ name,
+ &io_instr.locker);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_wait)
+ (io_instr.locker, count, src_file, src_line);
+ }
+}
+
+void toku_instr_file_stream_io_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ const TOKU_FILE &file,
+ ssize_t count,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker = nullptr;
+ if (FT_LIKELY(file.key)) {
+ io_instr.locker = PSI_FILE_CALL(get_thread_file_stream_locker)(
+ &io_instr.state, file.key, (PSI_file_operation)op);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_wait)
+ (io_instr.locker, count, src_file, src_line);
+ }
+ }
+}
+
+void toku_instr_file_io_end(toku_io_instrumentation &io_instr, ssize_t count) {
+ if (FT_LIKELY(io_instr.locker))
+ PSI_FILE_CALL(end_file_wait)
+ (io_instr.locker, count);
+}
+
+// Mutex instrumentation
+
+void toku_instr_mutex_init(const toku_instr_key &key, toku_mutex_t &mutex) {
+ mutex.psi_mutex = PSI_MUTEX_CALL(init_mutex)(key.id(), &mutex.pmutex);
+#if TOKU_PTHREAD_DEBUG
+ mutex.instr_key_id = key.id();
+#endif
+}
+
+void toku_instr_mutex_destroy(PSI_mutex *&mutex_instr) {
+ if (mutex_instr != nullptr) {
+ PSI_MUTEX_CALL(destroy_mutex)(mutex_instr);
+ mutex_instr = nullptr;
+ }
+}
+
+void toku_instr_mutex_lock_start(toku_mutex_instrumentation &mutex_instr,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line) {
+ mutex_instr.locker = nullptr;
+ if (mutex.psi_mutex) {
+ mutex_instr.locker =
+ PSI_MUTEX_CALL(start_mutex_wait)(&mutex_instr.state,
+ mutex.psi_mutex,
+ PSI_MUTEX_LOCK,
+ src_file,
+ src_line);
+ }
+}
+
+void toku_instr_mutex_trylock_start(toku_mutex_instrumentation &mutex_instr,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line) {
+ mutex_instr.locker = nullptr;
+ if (mutex.psi_mutex) {
+ mutex_instr.locker =
+ PSI_MUTEX_CALL(start_mutex_wait)(&mutex_instr.state,
+ mutex.psi_mutex,
+ PSI_MUTEX_TRYLOCK,
+ src_file,
+ src_line);
+ }
+}
+
+void toku_instr_mutex_lock_end(toku_mutex_instrumentation &mutex_instr,
+ int pthread_mutex_lock_result) {
+ if (mutex_instr.locker)
+ PSI_MUTEX_CALL(end_mutex_wait)
+ (mutex_instr.locker, pthread_mutex_lock_result);
+}
+
+void toku_instr_mutex_unlock(PSI_mutex *mutex_instr) {
+ if (mutex_instr)
+ PSI_MUTEX_CALL(unlock_mutex)(mutex_instr);
+}
+
+// Condvar instrumentation
+
+void toku_instr_cond_init(const toku_instr_key &key, toku_cond_t &cond) {
+ cond.psi_cond = PSI_COND_CALL(init_cond)(key.id(), &cond.pcond);
+#if TOKU_PTHREAD_DEBUG
+ cond.instr_key_id = key.id();
+#endif
+}
+
+void toku_instr_cond_destroy(PSI_cond *&cond_instr) {
+ if (cond_instr != nullptr) {
+ PSI_COND_CALL(destroy_cond)(cond_instr);
+ cond_instr = nullptr;
+ }
+}
+
+void toku_instr_cond_wait_start(toku_cond_instrumentation &cond_instr,
+ toku_instr_cond_op op,
+ toku_cond_t &cond,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line) {
+ cond_instr.locker = nullptr;
+ if (cond.psi_cond) {
+ /* Instrumentation start */
+ cond_instr.locker =
+ PSI_COND_CALL(start_cond_wait)(&cond_instr.state,
+ cond.psi_cond,
+ mutex.psi_mutex,
+ (PSI_cond_operation)op,
+ src_file,
+ src_line);
+ }
+}
+
+void toku_instr_cond_wait_end(toku_cond_instrumentation &cond_instr,
+ int pthread_cond_wait_result) {
+ if (cond_instr.locker)
+ PSI_COND_CALL(end_cond_wait)
+ (cond_instr.locker, pthread_cond_wait_result);
+}
+
+void toku_instr_cond_signal(const toku_cond_t &cond) {
+ if (cond.psi_cond)
+ PSI_COND_CALL(signal_cond)(cond.psi_cond);
+}
+
+void toku_instr_cond_broadcast(const toku_cond_t &cond) {
+ if (cond.psi_cond)
+ PSI_COND_CALL(broadcast_cond)(cond.psi_cond);
+}
+
+// rwlock instrumentation
+
+void toku_instr_rwlock_init(const toku_instr_key &key,
+ toku_pthread_rwlock_t &rwlock) {
+ rwlock.psi_rwlock = PSI_RWLOCK_CALL(init_rwlock)(key.id(), &rwlock.rwlock);
+#if TOKU_PTHREAD_DEBUG
+ rwlock.instr_key_id = key.id();
+#endif
+}
+
+void toku_instr_rwlock_destroy(PSI_rwlock *&rwlock_instr) {
+ if (rwlock_instr != nullptr) {
+ PSI_RWLOCK_CALL(destroy_rwlock)(rwlock_instr);
+ rwlock_instr = nullptr;
+ }
+}
+
+void toku_instr_rwlock_rdlock_wait_start(
+ toku_rwlock_instrumentation &rwlock_instr,
+ toku_pthread_rwlock_t &rwlock,
+ const char *src_file,
+ int src_line) {
+ rwlock_instr.locker = nullptr;
+ if (rwlock.psi_rwlock) {
+ /* Instrumentation start */
+ rwlock_instr.locker =
+ PSI_RWLOCK_CALL(start_rwlock_rdwait)(&rwlock_instr.state,
+ rwlock.psi_rwlock,
+ PSI_RWLOCK_READLOCK,
+ src_file,
+ src_line);
+ }
+}
+
+void toku_instr_rwlock_wrlock_wait_start(
+ toku_rwlock_instrumentation &rwlock_instr,
+ toku_pthread_rwlock_t &rwlock,
+ const char *src_file,
+ int src_line) {
+ rwlock_instr.locker = nullptr;
+ if (rwlock.psi_rwlock) {
+ /* Instrumentation start */
+ rwlock_instr.locker =
+ PSI_RWLOCK_CALL(start_rwlock_wrwait)(&rwlock_instr.state,
+ rwlock.psi_rwlock,
+ PSI_RWLOCK_WRITELOCK,
+ src_file,
+ src_line);
+ }
+}
+
+void toku_instr_rwlock_rdlock_wait_end(
+ toku_rwlock_instrumentation &rwlock_instr,
+ int pthread_rwlock_wait_result) {
+ if (rwlock_instr.locker)
+ PSI_RWLOCK_CALL(end_rwlock_rdwait)
+ (rwlock_instr.locker, pthread_rwlock_wait_result);
+}
+
+void toku_instr_rwlock_wrlock_wait_end(
+ toku_rwlock_instrumentation &rwlock_instr,
+ int pthread_rwlock_wait_result) {
+ if (rwlock_instr.locker)
+ PSI_RWLOCK_CALL(end_rwlock_wrwait)
+ (rwlock_instr.locker, pthread_rwlock_wait_result);
+}
+
+void toku_instr_rwlock_unlock(toku_pthread_rwlock_t &rwlock) {
+ if (rwlock.psi_rwlock)
+ PSI_RWLOCK_CALL(unlock_rwlock)(rwlock.psi_rwlock);
+}
+
+#endif // MYSQL_TOKUDB_ENGINE
diff --git a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h
new file mode 100644
index 00000000000..d6b0ed35ce9
--- /dev/null
+++ b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h
@@ -0,0 +1,249 @@
+#ifdef TOKU_INSTR_MYSQL_H
+// This file can be included only from toku_instumentation.h because
+// it replaces the defintitions for the case if MySQL PFS is available
+#error "toku_instr_mysql.h can be included only once"
+#else // TOKU_INSTR_MYSQL_H
+#define TOKU_INSTR_MYSQL_H
+
+#include <memory>
+
+// As these macros are defined in my_global.h
+// and they are also defined in command line
+// undefine them here to avoid compilation errors.
+#undef __STDC_FORMAT_MACROS
+#undef __STDC_LIMIT_MACROS
+#include <mysql/psi/mysql_file.h> // PSI_file
+#include <mysql/psi/mysql_thread.h> // PSI_mutex
+
+#ifndef HAVE_PSI_MUTEX_INTERFACE
+#error HAVE_PSI_MUTEX_INTERFACE required
+#endif
+#ifndef HAVE_PSI_RWLOCK_INTERFACE
+#error HAVE_PSI_RWLOCK_INTERFACE required
+#endif
+#ifndef HAVE_PSI_THREAD_INTERFACE
+#error HAVE_PSI_THREAD_INTERFACE required
+#endif
+
+// Instrumentation keys
+
+class toku_instr_key {
+ private:
+ pfs_key_t m_id;
+
+ public:
+ toku_instr_key(toku_instr_object_type type,
+ const char *group,
+ const char *name) {
+ switch (type) {
+ case toku_instr_object_type::mutex: {
+ PSI_mutex_info mutex_info{&m_id, name, 0};
+ mysql_mutex_register(group, &mutex_info, 1);
+ } break;
+ case toku_instr_object_type::rwlock: {
+ PSI_rwlock_info rwlock_info{&m_id, name, 0};
+ mysql_rwlock_register(group, &rwlock_info, 1);
+ } break;
+ case toku_instr_object_type::cond: {
+ PSI_cond_info cond_info{&m_id, name, 0};
+ mysql_cond_register(group, &cond_info, 1);
+ } break;
+ case toku_instr_object_type::thread: {
+ PSI_thread_info thread_info{&m_id, name, 0};
+ mysql_thread_register(group, &thread_info, 1);
+ } break;
+ case toku_instr_object_type::file: {
+ PSI_file_info file_info{&m_id, name, 0};
+ mysql_file_register(group, &file_info, 1);
+ } break;
+ }
+ }
+
+ explicit toku_instr_key(pfs_key_t key_id) : m_id(key_id) {}
+
+ pfs_key_t id() const { return m_id; }
+};
+
+// Thread instrumentation
+int toku_pthread_create(const toku_instr_key &key,
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void *),
+ void *arg);
+void toku_instr_register_current_thread(const toku_instr_key &key);
+void toku_instr_delete_current_thread();
+
+// I/O instrumentation
+
+enum class toku_instr_file_op {
+ file_stream_open = PSI_FILE_STREAM_OPEN,
+ file_create = PSI_FILE_CREATE,
+ file_open = PSI_FILE_OPEN,
+ file_delete = PSI_FILE_DELETE,
+ file_rename = PSI_FILE_RENAME,
+ file_read = PSI_FILE_READ,
+ file_write = PSI_FILE_WRITE,
+ file_sync = PSI_FILE_SYNC,
+ file_stream_close = PSI_FILE_STREAM_CLOSE,
+ file_close = PSI_FILE_CLOSE,
+ file_stat = PSI_FILE_STAT
+};
+
+struct toku_io_instrumentation {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+
+ toku_io_instrumentation() : locker(nullptr) {}
+};
+
+void toku_instr_file_open_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_stream_open_end(toku_io_instrumentation &io_instr,
+ TOKU_FILE &file);
+void toku_instr_file_open_end(toku_io_instrumentation &io_instr, int fd);
+void toku_instr_file_name_close_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_stream_close_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ const TOKU_FILE &file,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_fd_close_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ int fd,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_close_end(const toku_io_instrumentation &io_instr,
+ int result);
+void toku_instr_file_io_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ int fd,
+ ssize_t count,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_name_io_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ ssize_t count,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_stream_io_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ const TOKU_FILE &file,
+ ssize_t count,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_io_end(toku_io_instrumentation &io_instr, ssize_t count);
+
+// Mutex instrumentation
+
+struct toku_mutex_instrumentation {
+ struct PSI_mutex_locker *locker;
+ PSI_mutex_locker_state state;
+
+ toku_mutex_instrumentation() : locker(nullptr) {}
+};
+
+void toku_instr_mutex_init(const toku_instr_key &key, toku_mutex_t &mutex);
+void toku_instr_mutex_destroy(PSI_mutex *&mutex_instr);
+void toku_instr_mutex_lock_start(toku_mutex_instrumentation &mutex_instr,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line);
+void toku_instr_mutex_trylock_start(toku_mutex_instrumentation &mutex_instr,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line);
+void toku_instr_mutex_lock_end(toku_mutex_instrumentation &mutex_instr,
+ int pthread_mutex_lock_result);
+void toku_instr_mutex_unlock(PSI_mutex *mutex_instr);
+
+// Instrumentation probes
+
+class toku_instr_probe_pfs {
+ private:
+ std::unique_ptr<toku_mutex_t> mutex;
+ toku_mutex_instrumentation mutex_instr;
+
+ public:
+ explicit toku_instr_probe_pfs(const toku_instr_key &key);
+
+ ~toku_instr_probe_pfs();
+
+ void start_with_source_location(const char *src_file, int src_line) {
+ mutex_instr.locker = nullptr;
+ toku_instr_mutex_lock_start(mutex_instr, *mutex, src_file, src_line);
+ }
+
+ void stop() { toku_instr_mutex_lock_end(mutex_instr, 0); }
+};
+
+typedef toku_instr_probe_pfs toku_instr_probe;
+
+// Condvar instrumentation
+
+struct toku_cond_instrumentation {
+ struct PSI_cond_locker *locker;
+ PSI_cond_locker_state state;
+
+ toku_cond_instrumentation() : locker(nullptr) {}
+};
+
+enum class toku_instr_cond_op {
+ cond_wait = PSI_COND_WAIT,
+ cond_timedwait = PSI_COND_TIMEDWAIT,
+};
+
+void toku_instr_cond_init(const toku_instr_key &key, toku_cond_t &cond);
+void toku_instr_cond_destroy(PSI_cond *&cond_instr);
+void toku_instr_cond_wait_start(toku_cond_instrumentation &cond_instr,
+ toku_instr_cond_op op,
+ toku_cond_t &cond,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line);
+void toku_instr_cond_wait_end(toku_cond_instrumentation &cond_instr,
+ int pthread_cond_wait_result);
+void toku_instr_cond_signal(const toku_cond_t &cond);
+void toku_instr_cond_broadcast(const toku_cond_t &cond);
+
+// rwlock instrumentation
+
+struct toku_rwlock_instrumentation {
+ struct PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+
+ toku_rwlock_instrumentation() : locker(nullptr) { }
+};
+
+void toku_instr_rwlock_init(const toku_instr_key &key,
+ toku_pthread_rwlock_t &rwlock);
+void toku_instr_rwlock_destroy(PSI_rwlock *&rwlock_instr);
+void toku_instr_rwlock_rdlock_wait_start(
+ toku_rwlock_instrumentation &rwlock_instr,
+ toku_pthread_rwlock_t &rwlock,
+ const char *src_file,
+ int src_line);
+void toku_instr_rwlock_wrlock_wait_start(
+ toku_rwlock_instrumentation &rwlock_instr,
+ toku_pthread_rwlock_t &rwlock,
+ const char *src_file,
+ int src_line);
+void toku_instr_rwlock_rdlock_wait_end(
+ toku_rwlock_instrumentation &rwlock_instr,
+ int pthread_rwlock_wait_result);
+void toku_instr_rwlock_wrlock_wait_end(
+ toku_rwlock_instrumentation &rwlock_instr,
+ int pthread_rwlock_wait_result);
+void toku_instr_rwlock_unlock(toku_pthread_rwlock_t &rwlock);
+
+#endif // TOKU_INSTR_MYSQL_H
diff --git a/storage/tokudb/PerconaFT/portability/toku_instrumentation.h b/storage/tokudb/PerconaFT/portability/toku_instrumentation.h
new file mode 100644
index 00000000000..8c9390edc0a
--- /dev/null
+++ b/storage/tokudb/PerconaFT/portability/toku_instrumentation.h
@@ -0,0 +1,339 @@
+#pragma once
+
+#include <stdio.h> // FILE
+
+// Performance instrumentation object identifier type
+typedef unsigned int pfs_key_t;
+
+enum class toku_instr_object_type { mutex, rwlock, cond, thread, file };
+
+struct PSI_file;
+
+struct TOKU_FILE {
+ /** The real file. */
+ FILE *file;
+ struct PSI_file *key;
+ TOKU_FILE() : file(nullptr), key(nullptr) {}
+};
+
+struct PSI_mutex;
+struct PSI_cond;
+struct PSI_rwlock;
+
+struct toku_mutex_t;
+struct toku_cond_t;
+struct toku_pthread_rwlock_t;
+
+class toku_instr_key;
+
+class toku_instr_probe_empty {
+ public:
+ explicit toku_instr_probe_empty(UU(const toku_instr_key &key)) {}
+
+ void start_with_source_location(UU(const char *src_file),
+ UU(int src_line)) {}
+
+ void stop() {}
+};
+
+#define TOKU_PROBE_START(p) p->start_with_source_location(__FILE__, __LINE__)
+#define TOKU_PROBE_STOP(p) p->stop
+
+extern toku_instr_key toku_uninstrumented;
+
+#ifndef MYSQL_TOKUDB_ENGINE
+
+#include <pthread.h>
+
+class toku_instr_key {
+ public:
+ toku_instr_key(UU(toku_instr_object_type type),
+ UU(const char *group),
+ UU(const char *name)) {}
+
+ explicit toku_instr_key(UU(pfs_key_t key_id)) {}
+};
+
+typedef toku_instr_probe_empty toku_instr_probe;
+
+enum class toku_instr_file_op {
+ file_stream_open,
+ file_create,
+ file_open,
+ file_delete,
+ file_rename,
+ file_read,
+ file_write,
+ file_sync,
+ file_stream_close,
+ file_close,
+ file_stat
+};
+
+struct PSI_file {};
+struct PSI_mutex {};
+
+struct toku_io_instrumentation {};
+
+inline int toku_pthread_create(UU(const toku_instr_key &key),
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void *),
+ void *arg) {
+ return pthread_create(thread, attr, start_routine, arg);
+}
+
+inline void toku_instr_register_current_thread() {}
+
+inline void toku_instr_delete_current_thread() {}
+
+// Instrument file creation, opening, closing, and renaming
+inline void toku_instr_file_open_begin(UU(toku_io_instrumentation &io_instr),
+ UU(const toku_instr_key &key),
+ UU(toku_instr_file_op op),
+ UU(const char *name),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_stream_open_end(
+ UU(toku_io_instrumentation &io_instr),
+ UU(TOKU_FILE &file)) {}
+
+inline void toku_instr_file_open_end(UU(toku_io_instrumentation &io_instr),
+ UU(int fd)) {}
+
+inline void toku_instr_file_name_close_begin(
+ UU(toku_io_instrumentation &io_instr),
+ UU(const toku_instr_key &key),
+ UU(toku_instr_file_op op),
+ UU(const char *name),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_stream_close_begin(
+ UU(toku_io_instrumentation &io_instr),
+ UU(toku_instr_file_op op),
+ UU(TOKU_FILE &file),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_fd_close_begin(
+ UU(toku_io_instrumentation &io_instr),
+ UU(toku_instr_file_op op),
+ UU(int fd),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_close_end(UU(toku_io_instrumentation &io_instr),
+ UU(int result)) {}
+
+inline void toku_instr_file_io_begin(UU(toku_io_instrumentation &io_instr),
+ UU(toku_instr_file_op op),
+ UU(int fd),
+ UU(unsigned int count),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_name_io_begin(UU(toku_io_instrumentation &io_instr),
+ UU(const toku_instr_key &key),
+ UU(toku_instr_file_op op),
+ UU(const char *name),
+ UU(unsigned int count),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_stream_io_begin(
+ UU(toku_io_instrumentation &io_instr),
+ UU(toku_instr_file_op op),
+ UU(TOKU_FILE &file),
+ UU(unsigned int count),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_io_end(UU(toku_io_instrumentation &io_instr),
+ UU(unsigned int count)) {}
+
+struct toku_mutex_t;
+
+struct toku_mutex_instrumentation {};
+
+inline PSI_mutex *toku_instr_mutex_init(UU(const toku_instr_key &key),
+ UU(toku_mutex_t &mutex)) {
+ return nullptr;
+}
+
+inline void toku_instr_mutex_destroy(UU(PSI_mutex *&mutex_instr)) {}
+
+inline void toku_instr_mutex_lock_start(
+ UU(toku_mutex_instrumentation &mutex_instr),
+ UU(toku_mutex_t &mutex),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_mutex_trylock_start(
+ UU(toku_mutex_instrumentation &mutex_instr),
+ UU(toku_mutex_t &mutex),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_mutex_lock_end(
+ UU(toku_mutex_instrumentation &mutex_instr),
+ UU(int pthread_mutex_lock_result)) {}
+
+inline void toku_instr_mutex_unlock(UU(PSI_mutex *mutex_instr)) {}
+
+struct toku_cond_instrumentation {};
+
+enum class toku_instr_cond_op {
+ cond_wait,
+ cond_timedwait,
+};
+
+inline PSI_cond *toku_instr_cond_init(UU(const toku_instr_key &key),
+ UU(toku_cond_t &cond)) {
+ return nullptr;
+}
+
+inline void toku_instr_cond_destroy(UU(PSI_cond *&cond_instr)) {}
+
+inline void toku_instr_cond_wait_start(
+ UU(toku_cond_instrumentation &cond_instr),
+ UU(toku_instr_cond_op op),
+ UU(toku_cond_t &cond),
+ UU(toku_mutex_t &mutex),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_cond_wait_end(UU(toku_cond_instrumentation &cond_instr),
+ UU(int pthread_cond_wait_result)) {}
+
+inline void toku_instr_cond_signal(UU(toku_cond_t &cond)) {}
+
+inline void toku_instr_cond_broadcast(UU(toku_cond_t &cond)) {}
+
+// rwlock instrumentation
+struct toku_rwlock_instrumentation {};
+
+inline PSI_rwlock *toku_instr_rwlock_init(UU(const toku_instr_key &key),
+ UU(toku_pthread_rwlock_t &rwlock)) {
+ return nullptr;
+}
+
+inline void toku_instr_rwlock_destroy(UU(PSI_rwlock *&rwlock_instr)) {}
+
+inline void toku_instr_rwlock_rdlock_wait_start(
+ UU(toku_rwlock_instrumentation &rwlock_instr),
+ UU(toku_pthread_rwlock_t &rwlock),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_rwlock_wrlock_wait_start(
+ UU(toku_rwlock_instrumentation &rwlock_instr),
+ UU(toku_pthread_rwlock_t &rwlock),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_rwlock_rdlock_wait_end(
+ UU(toku_rwlock_instrumentation &rwlock_instr),
+ UU(int pthread_rwlock_wait_result)) {}
+
+inline void toku_instr_rwlock_wrlock_wait_end(
+ UU(toku_rwlock_instrumentation &rwlock_instr),
+ UU(int pthread_rwlock_wait_result)) {}
+
+inline void toku_instr_rwlock_unlock(UU(toku_pthread_rwlock_t &rwlock)) {}
+
+#else // MYSQL_TOKUDB_ENGINE
+// There can be not only mysql but also mongodb or any other PFS stuff
+#include <toku_instr_mysql.h>
+#endif // MYSQL_TOKUDB_ENGINE
+
+extern toku_instr_key toku_uninstrumented;
+
+extern toku_instr_probe *toku_instr_probe_1;
+
+// threads
+extern toku_instr_key *extractor_thread_key;
+extern toku_instr_key *fractal_thread_key;
+extern toku_instr_key *io_thread_key;
+extern toku_instr_key *eviction_thread_key;
+extern toku_instr_key *kibbutz_thread_key;
+extern toku_instr_key *minicron_thread_key;
+extern toku_instr_key *tp_internal_thread_key;
+
+// Files
+extern toku_instr_key *tokudb_file_data_key;
+extern toku_instr_key *tokudb_file_load_key;
+extern toku_instr_key *tokudb_file_tmp_key;
+extern toku_instr_key *tokudb_file_log_key;
+
+// Mutexes
+extern toku_instr_key *kibbutz_mutex_key;
+extern toku_instr_key *minicron_p_mutex_key;
+extern toku_instr_key *queue_result_mutex_key;
+extern toku_instr_key *tpool_lock_mutex_key;
+extern toku_instr_key *workset_lock_mutex_key;
+extern toku_instr_key *bjm_jobs_lock_mutex_key;
+extern toku_instr_key *log_internal_lock_mutex_key;
+extern toku_instr_key *cachetable_ev_thread_lock_mutex_key;
+extern toku_instr_key *cachetable_disk_nb_mutex_key;
+extern toku_instr_key *cachetable_m_mutex_key;
+extern toku_instr_key *safe_file_size_lock_mutex_key;
+extern toku_instr_key *checkpoint_safe_mutex_key;
+extern toku_instr_key *ft_ref_lock_mutex_key;
+extern toku_instr_key *loader_error_mutex_key;
+extern toku_instr_key *bfs_mutex_key;
+extern toku_instr_key *loader_bl_mutex_key;
+extern toku_instr_key *loader_fi_lock_mutex_key;
+extern toku_instr_key *loader_out_mutex_key;
+extern toku_instr_key *result_output_condition_lock_mutex_key;
+extern toku_instr_key *block_table_mutex_key;
+extern toku_instr_key *rollback_log_node_cache_mutex_key;
+extern toku_instr_key *txn_lock_mutex_key;
+extern toku_instr_key *txn_state_lock_mutex_key;
+extern toku_instr_key *txn_child_manager_mutex_key;
+extern toku_instr_key *txn_manager_lock_mutex_key;
+extern toku_instr_key *treenode_mutex_key;
+extern toku_instr_key *manager_mutex_key;
+extern toku_instr_key *manager_escalation_mutex_key;
+extern toku_instr_key *manager_escalator_mutex_key;
+extern toku_instr_key *db_txn_struct_i_txn_mutex_key;
+extern toku_instr_key *indexer_i_indexer_lock_mutex_key;
+extern toku_instr_key *indexer_i_indexer_estimate_lock_mutex_key;
+extern toku_instr_key *locktree_request_info_mutex_key;
+extern toku_instr_key *locktree_request_info_retry_mutex_key;
+
+// condition vars
+extern toku_instr_key *result_state_cond_key;
+extern toku_instr_key *bjm_jobs_wait_key;
+extern toku_instr_key *cachetable_p_refcount_wait_key;
+extern toku_instr_key *cachetable_m_flow_control_cond_key;
+extern toku_instr_key *cachetable_m_ev_thread_cond_key;
+extern toku_instr_key *bfs_cond_key;
+extern toku_instr_key *result_output_condition_key;
+extern toku_instr_key *manager_m_escalator_done_key;
+extern toku_instr_key *lock_request_m_wait_cond_key;
+extern toku_instr_key *queue_result_cond_key;
+extern toku_instr_key *ws_worker_wait_key;
+extern toku_instr_key *rwlock_wait_read_key;
+extern toku_instr_key *rwlock_wait_write_key;
+extern toku_instr_key *rwlock_cond_key;
+extern toku_instr_key *tp_thread_wait_key;
+extern toku_instr_key *tp_pool_wait_free_key;
+extern toku_instr_key *frwlock_m_wait_read_key;
+extern toku_instr_key *kibbutz_k_cond_key;
+extern toku_instr_key *minicron_p_condvar_key;
+extern toku_instr_key *locktree_request_info_retry_cv_key;
+
+// rwlocks
+extern toku_instr_key *multi_operation_lock_key;
+extern toku_instr_key *low_priority_multi_operation_lock_key;
+extern toku_instr_key *cachetable_m_list_lock_key;
+extern toku_instr_key *cachetable_m_pending_lock_expensive_key;
+extern toku_instr_key *cachetable_m_pending_lock_cheap_key;
+extern toku_instr_key *cachetable_m_lock_key;
+extern toku_instr_key *result_i_open_dbs_rwlock_key;
+extern toku_instr_key *checkpoint_safe_rwlock_key;
+extern toku_instr_key *cachetable_value_key;
+extern toku_instr_key *safe_file_size_lock_rwlock_key;
+extern toku_instr_key *cachetable_disk_nb_rwlock_key;
diff --git a/storage/tokudb/PerconaFT/portability/toku_os.h b/storage/tokudb/PerconaFT/portability/toku_os.h
index 3a0e7376971..d7cfcfefb9a 100644
--- a/storage/tokudb/PerconaFT/portability/toku_os.h
+++ b/storage/tokudb/PerconaFT/portability/toku_os.h
@@ -116,12 +116,10 @@ int toku_fsync_dir_by_name_without_accounting(const char *dir_name);
// *free_size is set to the bytes of free space in the file system
// *total_size is set to the total bytes in the file system
// Return 0 on success, otherwise an error number
-int toku_get_filesystem_sizes(const char *path, uint64_t *avail_size, uint64_t *free_size, uint64_t *total_size);
-
-// Portable linux 'stat'
-int toku_stat(const char *name, toku_struct_stat *statbuf) __attribute__((__visibility__("default")));
-// Portable linux 'fstat'
-int toku_fstat(int fd, toku_struct_stat *statbuf) __attribute__((__visibility__("default")));
+int toku_get_filesystem_sizes(const char *path,
+ uint64_t *avail_size,
+ uint64_t *free_size,
+ uint64_t *total_size);
// Portable linux 'dup2'
int toku_dup2(int fd, int fd2) __attribute__((__visibility__("default")));
diff --git a/storage/tokudb/PerconaFT/portability/toku_portability.h b/storage/tokudb/PerconaFT/portability/toku_portability.h
index d3a4e391a9f..e459cfb8779 100644
--- a/storage/tokudb/PerconaFT/portability/toku_portability.h
+++ b/storage/tokudb/PerconaFT/portability/toku_portability.h
@@ -54,6 +54,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#define DEV_NULL_FILE "/dev/null"
+#include <my_global.h>
+
// include here, before they get deprecated
#include <toku_atomic.h>
@@ -125,6 +127,33 @@ typedef int64_t toku_off_t;
#define UU(x) x __attribute__((__unused__))
+// Branch prediction macros.
+// If supported by the compiler, will hint in inctruction caching for likely
+// branching. Should only be used where there is a very good idea of the correct
+// branch heuristics as determined by profiling. Mostly copied from InnoDB.
+// Use:
+// "if (FT_LIKELY(x))" where the chances of "x" evaluating true are higher
+// "if (FT_UNLIKELY(x))" where the chances of "x" evaluating false are higher
+#if defined(__GNUC__) && (__GNUC__ > 2) && !defined(__INTEL_COMPILER)
+
+// Tell the compiler that 'expr' probably evaluates to 'constant'.
+#define FT_EXPECT(expr, constant) __builtin_expect(expr, constant)
+
+#else
+
+#warning "No FT branch prediction operations in use!"
+#define FT_EXPECT(expr, constant) (expr)
+
+#endif // defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
+
+// Tell the compiler that cond is likely to hold
+#define FT_LIKELY(cond) FT_EXPECT(bool(cond), true)
+
+// Tell the compiler that cond is unlikely to hold
+#define FT_UNLIKELY(cond) FT_EXPECT(bool(cond), false)
+
+#include "toku_instrumentation.h"
+
#if defined(__cplusplus)
extern "C" {
#endif
@@ -242,28 +271,272 @@ void toku_os_full_write (int fd, const void *buf, size_t len) __attribute__((__v
// os_write returns 0 on success, otherwise an errno.
ssize_t toku_os_pwrite (int fd, const void *buf, size_t len, toku_off_t off) __attribute__((__visibility__("default")));
-int toku_os_write (int fd, const void *buf, size_t len) __attribute__((__visibility__("default")));
+int toku_os_write(int fd, const void *buf, size_t len)
+ __attribute__((__visibility__("default")));
// wrappers around file system calls
-FILE * toku_os_fdopen(int fildes, const char *mode);
-FILE * toku_os_fopen(const char *filename, const char *mode);
-int toku_os_open(const char *path, int oflag, int mode);
-int toku_os_open_direct(const char *path, int oflag, int mode);
-int toku_os_close(int fd);
-int toku_os_fclose(FILE * stream);
-int toku_os_rename(const char *old_name, const char *new_name);
-int toku_os_unlink(const char *path);
-ssize_t toku_os_read(int fd, void *buf, size_t count);
-ssize_t toku_os_pread(int fd, void *buf, size_t count, off_t offset);
void toku_os_recursive_delete(const char *path);
+TOKU_FILE *toku_os_fdopen_with_source_location(int fildes,
+ const char *mode,
+ const char *filename,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line);
+#define toku_os_fdopen(FD, M, FN, K) \
+ toku_os_fdopen_with_source_location(FD, M, FN, K, __FILE__, __LINE__)
+
+TOKU_FILE *toku_os_fopen_with_source_location(const char *filename,
+ const char *mode,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line);
+#define toku_os_fopen(F, M, K) \
+ toku_os_fopen_with_source_location(F, M, K, __FILE__, __LINE__)
+
+int toku_os_open_with_source_location(const char *path,
+ int oflag,
+ int mode,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line);
+#define toku_os_open(FD, F, M, K) \
+ toku_os_open_with_source_location(FD, F, M, K, __FILE__, __LINE__)
+
+int toku_os_open_direct(const char *path,
+ int oflag,
+ int mode,
+ const toku_instr_key &instr_key);
+
+int toku_os_delete_with_source_location(const char *name,
+ const char *src_file,
+ uint src_line);
+#define toku_os_delete(FN) \
+ toku_os_delete_with_source_location(FN, __FILE__, __LINE__)
+
+int toku_os_rename_with_source_location(const char *old_name,
+ const char *new_name,
+ const char *src_file,
+ uint src_line);
+#define toku_os_rename(old_name, new_name) \
+ toku_os_rename_with_source_location(old_name, new_name, __FILE__, __LINE__)
+
+void toku_os_full_write_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line);
+#define toku_os_full_write(FD, B, L) \
+ toku_os_full_write_with_source_location(FD, B, L, __FILE__, __LINE__)
+
+int toku_os_write_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line);
+#define toku_os_write(FD, B, L) \
+ toku_os_write_with_source_location(FD, B, L, __FILE__, __LINE__)
+
+void toku_os_full_pwrite_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line);
+#define toku_os_full_pwrite(FD, B, L, O) \
+ toku_os_full_pwrite_with_source_location(FD, B, L, O, __FILE__, __LINE__)
+
+ssize_t toku_os_pwrite_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line);
+
+#define toku_os_pwrite(FD, B, L, O) \
+ toku_os_pwrite_with_source_location(FD, B, L, O, __FILE__, __LINE__)
+
+int toku_os_fwrite_with_source_location(const void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+
+#define toku_os_fwrite(P, S, N, FS) \
+ toku_os_fwrite_with_source_location(P, S, N, FS, __FILE__, __LINE__)
+
+int toku_os_fread_with_source_location(void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+#define toku_os_fread(P, S, N, FS) \
+ toku_os_fread_with_source_location(P, S, N, FS, __FILE__, __LINE__)
+
+TOKU_FILE *toku_os_fopen_with_source_location(const char *filename,
+ const char *mode,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line);
+
+int toku_os_fclose_with_source_location(TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+
+#define toku_os_fclose(FS) \
+ toku_os_fclose_with_source_location(FS, __FILE__, __LINE__)
+
+int toku_os_close_with_source_location(int fd,
+ const char *src_file,
+ uint src_line);
+#define toku_os_close(FD) \
+ toku_os_close_with_source_location(FD, __FILE__, __LINE__)
+
+ssize_t toku_os_read_with_source_location(int fd,
+ void *buf,
+ size_t count,
+ const char *src_file,
+ uint src_line);
+
+#define toku_os_read(FD, B, C) \
+ toku_os_read_with_source_location(FD, B, C, __FILE__, __LINE__);
+
+ssize_t inline_toku_os_pread_with_source_location(int fd,
+ void *buf,
+ size_t count,
+ off_t offset,
+ const char *src_file,
+ uint src_line);
+#define toku_os_pread(FD, B, C, O) \
+ inline_toku_os_pread_with_source_location(FD, B, C, O, __FILE__, __LINE__);
+
+void file_fsync_internal_with_source_location(int fd,
+ const char *src_file,
+ uint src_line);
+
+#define file_fsync_internal(FD) \
+ file_fsync_internal_with_source_location(FD, __FILE__, __LINE__);
+
+int toku_os_get_file_size_with_source_location(int fildes,
+ int64_t *fsize,
+ const char *src_file,
+ uint src_line);
+
+#define toku_os_get_file_size(D, S) \
+ toku_os_get_file_size_with_source_location(D, S, __FILE__, __LINE__)
+
+// TODO: should this prototype be moved to toku_os.h?
+int toku_stat_with_source_location(const char *name,
+ toku_struct_stat *buf,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line)
+ __attribute__((__visibility__("default")));
+
+#define toku_stat(N, B, K) \
+ toku_stat_with_source_location(N, B, K, __FILE__, __LINE__)
+
+int toku_os_fstat_with_source_location(int fd,
+ toku_struct_stat *buf,
+ const char *src_file,
+ uint src_line)
+ __attribute__((__visibility__("default")));
+
+#define toku_os_fstat(FD, B) \
+ toku_os_fstat_with_source_location(FD, B, __FILE__, __LINE__)
+
+#ifdef HAVE_PSI_FILE_INTERFACE2
+int inline_toku_os_close(int fd, const char *src_file, uint src_line);
+int inline_toku_os_fclose(TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+ssize_t inline_toku_os_read(int fd,
+ void *buf,
+ size_t count,
+ const char *src_file,
+ uint src_line);
+ssize_t inline_toku_os_pread(int fd,
+ void *buf,
+ size_t count,
+ off_t offset,
+ const char *src_file,
+ uint src_line);
+int inline_toku_os_fwrite(const void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+int inline_toku_os_fread(void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+int inline_toku_os_write(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line);
+ssize_t inline_toku_os_pwrite(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line);
+void inline_toku_os_full_write(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line);
+void inline_toku_os_full_pwrite(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line);
+int inline_toku_os_delete(const char *name,
+ const char *srv_file,
+ uint src_line);
+//#else
+int inline_toku_os_close(int fd);
+int inline_toku_os_fclose(TOKU_FILE *stream);
+ssize_t inline_toku_os_read(int fd, void *buf, size_t count);
+ssize_t inline_toku_os_pread(int fd, void *buf, size_t count, off_t offset);
+int inline_toku_os_fwrite(const void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream);
+int inline_toku_os_fread(void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream);
+int inline_toku_os_write(int fd, const void *buf, size_t len);
+ssize_t inline_toku_os_pwrite(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off);
+void inline_toku_os_full_write(int fd, const void *buf, size_t len);
+void inline_toku_os_full_pwrite(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off);
+int inline_toku_os_delete(const char *name);
+#endif
+
// wrapper around fsync
-void toku_file_fsync_without_accounting(int fd);
void toku_file_fsync(int fd);
int toku_fsync_directory(const char *fname);
+void toku_file_fsync_without_accounting(int fd);
// get the number of fsync calls and the fsync times (total)
-void toku_get_fsync_times(uint64_t *fsync_count, uint64_t *fsync_time, uint64_t *long_fsync_threshold, uint64_t *long_fsync_count, uint64_t *long_fsync_time);
+void toku_get_fsync_times(uint64_t *fsync_count,
+ uint64_t *fsync_time,
+ uint64_t *long_fsync_threshold,
+ uint64_t *long_fsync_count,
+ uint64_t *long_fsync_time);
void toku_set_func_fsync (int (*fsync_function)(int));
void toku_set_func_pwrite (ssize_t (*)(int, const void *, size_t, toku_off_t));
@@ -273,9 +546,11 @@ void toku_set_func_full_write (ssize_t (*)(int, const void *, size_t));
void toku_set_func_fdopen (FILE * (*)(int, const char *));
void toku_set_func_fopen (FILE * (*)(const char *, const char *));
void toku_set_func_open (int (*)(const char *, int, int));
-void toku_set_func_fclose(int (*)(FILE*));
+void toku_set_func_fclose(int (*)(FILE *));
void toku_set_func_read(ssize_t (*)(int, void *, size_t));
-void toku_set_func_pread (ssize_t (*)(int, void *, size_t, off_t));
+void toku_set_func_pread(ssize_t (*)(int, void *, size_t, off_t));
+void toku_set_func_fwrite(
+ size_t (*fwrite_fun)(const void *, size_t, size_t, FILE *));
int toku_portability_init(void);
void toku_portability_destroy(void);
@@ -285,28 +560,3 @@ void toku_portability_destroy(void);
static inline uint64_t roundup_to_multiple(uint64_t alignment, uint64_t v) {
return (v + alignment - 1) & ~(alignment - 1);
}
-
-// Branch prediction macros.
-// If supported by the compiler, will hint in inctruction caching for likely
-// branching. Should only be used where there is a very good idea of the correct
-// branch heuristics as determined by profiling. Mostly copied from InnoDB.
-// Use:
-// "if (FT_LIKELY(x))" where the chances of "x" evaluating true are higher
-// "if (FT_UNLIKELY(x))" where the chances of "x" evaluating false are higher
-#if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
-
-// Tell the compiler that 'expr' probably evaluates to 'constant'.
-#define FT_EXPECT(expr,constant) __builtin_expect(expr, constant)
-
-#else
-
-#warning "No FT branch prediction operations in use!"
-#define FT_EXPECT(expr,constant) (expr)
-
-#endif // defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
-
-// Tell the compiler that cond is likely to hold
-#define FT_LIKELY(cond) FT_EXPECT(cond, 1)
-
-// Tell the compiler that cond is unlikely to hold
-#define FT_UNLIKELY(cond) FT_EXPECT(cond, 0)
diff --git a/storage/tokudb/PerconaFT/portability/toku_pthread.h b/storage/tokudb/PerconaFT/portability/toku_pthread.h
index 84c27736201..44de01244d2 100644
--- a/storage/tokudb/PerconaFT/portability/toku_pthread.h
+++ b/storage/tokudb/PerconaFT/portability/toku_pthread.h
@@ -42,31 +42,62 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <time.h>
#include <stdint.h>
+#include "toku_portability.h"
#include "toku_assert.h"
+// TODO: some things moved toku_instrumentation.h, not necessarily the best
+// place
typedef pthread_attr_t toku_pthread_attr_t;
typedef pthread_t toku_pthread_t;
-typedef pthread_mutexattr_t toku_pthread_mutexattr_t;
typedef pthread_mutex_t toku_pthread_mutex_t;
typedef pthread_condattr_t toku_pthread_condattr_t;
typedef pthread_cond_t toku_pthread_cond_t;
-typedef pthread_rwlock_t toku_pthread_rwlock_t;
-typedef pthread_rwlockattr_t toku_pthread_rwlockattr_t;
+typedef pthread_rwlockattr_t toku_pthread_rwlockattr_t;
typedef pthread_key_t toku_pthread_key_t;
typedef struct timespec toku_timespec_t;
-#ifndef TOKU_PTHREAD_DEBUG
-# define TOKU_PTHREAD_DEBUG 0
-#endif
+// TODO: break this include loop
+#include <pthread.h>
+typedef pthread_mutexattr_t toku_pthread_mutexattr_t;
-typedef struct toku_mutex {
+struct toku_mutex_t {
pthread_mutex_t pmutex;
+ struct PSI_mutex
+ *psi_mutex; /* The performance schema instrumentation hook */
#if TOKU_PTHREAD_DEBUG
- pthread_t owner; // = pthread_self(); // for debugging
+ pthread_t owner; // = pthread_self(); // for debugging
bool locked;
bool valid;
+ pfs_key_t instr_key_id;
+#endif
+};
+
+struct toku_cond_t {
+ pthread_cond_t pcond;
+ struct PSI_cond *psi_cond;
+#if TOKU_PTHREAD_DEBUG
+ pfs_key_t instr_key_id;
+#endif
+};
+
+#ifdef TOKU_PTHREAD_DEBUG
+#define TOKU_COND_INITIALIZER \
+ { \
+ .pcond = PTHREAD_COND_INITIALIZER, .psi_cond = nullptr, \
+ .instr_key_id = 0 \
+ }
+#else
+#define TOKU_COND_INITIALIZER \
+ { .pcond = PTHREAD_COND_INITIALIZER, .psi_cond = nullptr }
#endif
-} toku_mutex_t;
+
+struct toku_pthread_rwlock_t {
+ pthread_rwlock_t rwlock;
+ struct PSI_rwlock *psi_rwlock;
+#if TOKU_PTHREAD_DEBUG
+ pfs_key_t instr_key_id;
+#endif
+};
typedef struct toku_mutex_aligned {
toku_mutex_t aligned_mutex __attribute__((__aligned__(64)));
@@ -83,45 +114,68 @@ typedef struct toku_mutex_aligned {
// In general it will be a lot of busy work to make this codebase compile
// cleanly with -Wmissing-field-initializers
-# define ZERO_MUTEX_INITIALIZER {}
+#define ZERO_MUTEX_INITIALIZER \
+ {}
#if TOKU_PTHREAD_DEBUG
-# define TOKU_MUTEX_INITIALIZER { .pmutex = PTHREAD_MUTEX_INITIALIZER, .owner = 0, .locked = false, .valid = true }
+#define TOKU_MUTEX_INITIALIZER \
+ { \
+ .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr, .owner = 0, \
+ .locked = false, .valid = true, .instr_key_id = 0 \
+ }
#else
-# define TOKU_MUTEX_INITIALIZER { .pmutex = PTHREAD_MUTEX_INITIALIZER }
+#define TOKU_MUTEX_INITIALIZER \
+ { .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr }
#endif
// Darwin doesn't provide adaptive mutexes
#if defined(__APPLE__)
-# define TOKU_MUTEX_ADAPTIVE PTHREAD_MUTEX_DEFAULT
-# if TOKU_PTHREAD_DEBUG
-# define TOKU_ADAPTIVE_MUTEX_INITIALIZER { .pmutex = PTHREAD_MUTEX_INITIALIZER, .owner = 0, .locked = false, .valid = true }
-# else
-# define TOKU_ADAPTIVE_MUTEX_INITIALIZER { .pmutex = PTHREAD_MUTEX_INITIALIZER }
-# endif
-#else // __FreeBSD__, __linux__, at least
-# define TOKU_MUTEX_ADAPTIVE PTHREAD_MUTEX_ADAPTIVE_NP
-# if TOKU_PTHREAD_DEBUG
-# define TOKU_ADAPTIVE_MUTEX_INITIALIZER { .pmutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, .owner = 0, .locked = false, .valid = true }
-# else
-# define TOKU_ADAPTIVE_MUTEX_INITIALIZER { .pmutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP }
-# endif
+#define TOKU_MUTEX_ADAPTIVE PTHREAD_MUTEX_DEFAULT
+#if TOKU_PTHREAD_DEBUG
+#define TOKU_ADAPTIVE_MUTEX_INITIALIZER \
+ { \
+ .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr, .owner = 0, \
+ .locked = false, .valid = true, .instr_key_id = 0 \
+ }
+#else
+#define TOKU_ADAPTIVE_MUTEX_INITIALIZER \
+ { .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr }
#endif
-
-static inline void
-toku_mutex_init(toku_mutex_t *mutex, const toku_pthread_mutexattr_t *attr) {
- int r = pthread_mutex_init(&mutex->pmutex, attr);
- assert_zero(r);
+#else // __FreeBSD__, __linux__, at least
+#define TOKU_MUTEX_ADAPTIVE PTHREAD_MUTEX_ADAPTIVE_NP
#if TOKU_PTHREAD_DEBUG
- mutex->locked = false;
- invariant(!mutex->valid);
- mutex->valid = true;
- mutex->owner = 0;
+#define TOKU_ADAPTIVE_MUTEX_INITIALIZER \
+ { \
+ .pmutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, .psi_mutex = nullptr, \
+ .owner = 0, .locked = false, .valid = true, .instr_key_id = 0 \
+ }
+#else
+#define TOKU_ADAPTIVE_MUTEX_INITIALIZER \
+ { .pmutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, .psi_mutex = nullptr }
+#endif
#endif
-}
-static inline void
-toku_mutexattr_init(toku_pthread_mutexattr_t *attr) {
+// Different OSes implement mutexes as different amounts of nested structs.
+// C++ will fill out all missing values with zeroes if you provide at least one
+// zero, but it needs the right amount of nesting.
+#if defined(__FreeBSD__)
+#define ZERO_COND_INITIALIZER \
+ { 0 }
+#elif defined(__APPLE__)
+#define ZERO_COND_INITIALIZER \
+ { \
+ { 0 } \
+ }
+#else // __linux__, at least
+#define ZERO_COND_INITIALIZER \
+ { \
+ { \
+ { 0 } \
+ } \
+ }
+#endif
+
+static inline void toku_mutexattr_init(toku_pthread_mutexattr_t *attr) {
int r = pthread_mutexattr_init(attr);
assert_zero(r);
}
@@ -138,61 +192,8 @@ toku_mutexattr_destroy(toku_pthread_mutexattr_t *attr) {
assert_zero(r);
}
-static inline void
-toku_mutex_destroy(toku_mutex_t *mutex) {
#if TOKU_PTHREAD_DEBUG
- invariant(mutex->valid);
- mutex->valid = false;
- invariant(!mutex->locked);
-#endif
- int r = pthread_mutex_destroy(&mutex->pmutex);
- assert_zero(r);
-}
-
-static inline void
-toku_mutex_lock(toku_mutex_t *mutex) {
- int r = pthread_mutex_lock(&mutex->pmutex);
- assert_zero(r);
-#if TOKU_PTHREAD_DEBUG
- invariant(mutex->valid);
- invariant(!mutex->locked);
- invariant(mutex->owner == 0);
- mutex->locked = true;
- mutex->owner = pthread_self();
-#endif
-}
-
-static inline int
-toku_mutex_trylock(toku_mutex_t *mutex) {
- int r = pthread_mutex_trylock(&mutex->pmutex);
-#if TOKU_PTHREAD_DEBUG
- if (r == 0) {
- invariant(mutex->valid);
- invariant(!mutex->locked);
- invariant(mutex->owner == 0);
- mutex->locked = true;
- mutex->owner = pthread_self();
- }
-#endif
- return r;
-}
-
-static inline void
-toku_mutex_unlock(toku_mutex_t *mutex) {
-#if TOKU_PTHREAD_DEBUG
- invariant(mutex->owner == pthread_self());
- invariant(mutex->valid);
- invariant(mutex->locked);
- mutex->locked = false;
- mutex->owner = 0;
-#endif
- int r = pthread_mutex_unlock(&mutex->pmutex);
- assert_zero(r);
-}
-
-#if TOKU_PTHREAD_DEBUG
-static inline void
-toku_mutex_assert_locked(const toku_mutex_t *mutex) {
+static inline void toku_mutex_assert_locked(const toku_mutex_t *mutex) {
invariant(mutex->locked);
invariant(mutex->owner == pthread_self());
}
@@ -217,40 +218,123 @@ toku_mutex_assert_unlocked(toku_mutex_t *mutex) {
invariant(!mutex->locked);
}
#else
-static inline void
-toku_mutex_assert_unlocked(toku_mutex_t *mutex __attribute__((unused))) {
+static inline void toku_mutex_assert_unlocked(toku_mutex_t *mutex
+ __attribute__((unused))) {}
+#endif
+
+#define toku_mutex_lock(M) \
+ toku_mutex_lock_with_source_location(M, __FILE__, __LINE__)
+
+static inline void toku_cond_init(toku_cond_t *cond,
+ const toku_pthread_condattr_t *attr) {
+ int r = pthread_cond_init(&cond->pcond, attr);
+ assert_zero(r);
+}
+
+#define toku_mutex_trylock(M) \
+ toku_mutex_trylock_with_source_location(M, __FILE__, __LINE__)
+
+inline void toku_mutex_unlock(toku_mutex_t *mutex) {
+#if TOKU_PTHREAD_DEBUG
+ invariant(mutex->owner == pthread_self());
+ invariant(mutex->valid);
+ invariant(mutex->locked);
+ mutex->locked = false;
+ mutex->owner = 0;
+#endif
+ toku_instr_mutex_unlock(mutex->psi_mutex);
+ int r = pthread_mutex_unlock(&mutex->pmutex);
+ assert_zero(r);
}
+
+inline void toku_mutex_lock_with_source_location(toku_mutex_t *mutex,
+ const char *src_file,
+ int src_line) {
+
+ toku_mutex_instrumentation mutex_instr;
+ toku_instr_mutex_lock_start(mutex_instr, *mutex, src_file, src_line);
+
+ const int r = pthread_mutex_lock(&mutex->pmutex);
+ toku_instr_mutex_lock_end(mutex_instr, r);
+
+ assert_zero(r);
+#if TOKU_PTHREAD_DEBUG
+ invariant(mutex->valid);
+ invariant(!mutex->locked);
+ invariant(mutex->owner == 0);
+ mutex->locked = true;
+ mutex->owner = pthread_self();
#endif
+}
-typedef struct toku_cond {
- pthread_cond_t pcond;
-} toku_cond_t;
+inline int toku_mutex_trylock_with_source_location(toku_mutex_t *mutex,
+ const char *src_file,
+ int src_line) {
-// Same considerations as for ZERO_MUTEX_INITIALIZER apply
-#define ZERO_COND_INITIALIZER {}
+ toku_mutex_instrumentation mutex_instr;
+ toku_instr_mutex_trylock_start(mutex_instr, *mutex, src_file, src_line);
-#define TOKU_COND_INITIALIZER {PTHREAD_COND_INITIALIZER}
+ const int r = pthread_mutex_lock(&mutex->pmutex);
+ toku_instr_mutex_lock_end(mutex_instr, r);
-static inline void
-toku_cond_init(toku_cond_t *cond, const toku_pthread_condattr_t *attr) {
+#if TOKU_PTHREAD_DEBUG
+ if (r == 0) {
+ invariant(mutex->valid);
+ invariant(!mutex->locked);
+ invariant(mutex->owner == 0);
+ mutex->locked = true;
+ mutex->owner = pthread_self();
+ }
+#endif
+ return r;
+}
+
+#define toku_cond_wait(C, M) \
+ toku_cond_wait_with_source_location(C, M, __FILE__, __LINE__)
+
+#define toku_cond_timedwait(C, M, W) \
+ toku_cond_timedwait_with_source_location(C, M, W, __FILE__, __LINE__)
+
+inline void toku_cond_init(const toku_instr_key &key,
+ toku_cond_t *cond,
+ const pthread_condattr_t *attr) {
+ toku_instr_cond_init(key, *cond);
int r = pthread_cond_init(&cond->pcond, attr);
assert_zero(r);
}
-static inline void
-toku_cond_destroy(toku_cond_t *cond) {
+inline void toku_cond_destroy(toku_cond_t *cond) {
+ toku_instr_cond_destroy(cond->psi_cond);
int r = pthread_cond_destroy(&cond->pcond);
assert_zero(r);
}
-static inline void
-toku_cond_wait(toku_cond_t *cond, toku_mutex_t *mutex) {
+inline void toku_cond_wait_with_source_location(toku_cond_t *cond,
+ toku_mutex_t *mutex,
+ const char *src_file,
+ uint src_line) {
+
#if TOKU_PTHREAD_DEBUG
invariant(mutex->locked);
mutex->locked = false;
mutex->owner = 0;
#endif
- int r = pthread_cond_wait(&cond->pcond, &mutex->pmutex);
+
+ /* Instrumentation start */
+ toku_cond_instrumentation cond_instr;
+ toku_instr_cond_wait_start(cond_instr,
+ toku_instr_cond_op::cond_wait,
+ *cond,
+ *mutex,
+ src_file,
+ src_line);
+
+ /* Instrumented code */
+ const int r = pthread_cond_wait(&cond->pcond, &mutex->pmutex);
+
+ /* Instrumentation end */
+ toku_instr_cond_wait_end(cond_instr, r);
+
assert_zero(r);
#if TOKU_PTHREAD_DEBUG
invariant(!mutex->locked);
@@ -259,14 +343,33 @@ toku_cond_wait(toku_cond_t *cond, toku_mutex_t *mutex) {
#endif
}
-static inline int
-toku_cond_timedwait(toku_cond_t *cond, toku_mutex_t *mutex, toku_timespec_t *wakeup_at) {
+inline int toku_cond_timedwait_with_source_location(toku_cond_t *cond,
+ toku_mutex_t *mutex,
+ toku_timespec_t *wakeup_at,
+ const char *src_file,
+ uint src_line) {
#if TOKU_PTHREAD_DEBUG
invariant(mutex->locked);
mutex->locked = false;
mutex->owner = 0;
#endif
- int r = pthread_cond_timedwait(&cond->pcond, &mutex->pmutex, wakeup_at);
+
+ /* Instrumentation start */
+ toku_cond_instrumentation cond_instr;
+ toku_instr_cond_wait_start(cond_instr,
+ toku_instr_cond_op::cond_timedwait,
+ *cond,
+ *mutex,
+ src_file,
+ src_line);
+
+ /* Instrumented code */
+ const int r = pthread_cond_timedwait(
+ &cond->pcond, &mutex->pmutex, wakeup_at);
+
+ /* Instrumentation end */
+ toku_instr_cond_wait_end(cond_instr, r);
+
#if TOKU_PTHREAD_DEBUG
invariant(!mutex->locked);
mutex->locked = true;
@@ -275,69 +378,116 @@ toku_cond_timedwait(toku_cond_t *cond, toku_mutex_t *mutex, toku_timespec_t *wak
return r;
}
-static inline void
-toku_cond_signal(toku_cond_t *cond) {
- int r = pthread_cond_signal(&cond->pcond);
+inline void toku_cond_signal(toku_cond_t *cond) {
+ toku_instr_cond_signal(*cond);
+ const int r = pthread_cond_signal(&cond->pcond);
assert_zero(r);
}
-static inline void
-toku_cond_broadcast(toku_cond_t *cond) {
- int r =pthread_cond_broadcast(&cond->pcond);
+inline void toku_cond_broadcast(toku_cond_t *cond) {
+ toku_instr_cond_broadcast(*cond);
+ const int r = pthread_cond_broadcast(&cond->pcond);
assert_zero(r);
}
-int
-toku_pthread_yield(void) __attribute__((__visibility__("default")));
-
-static inline toku_pthread_t
-toku_pthread_self(void) {
- return pthread_self();
+inline void toku_mutex_init(const toku_instr_key &key,
+ toku_mutex_t *mutex,
+ const toku_pthread_mutexattr_t *attr) {
+#if TOKU_PTHREAD_DEBUG
+ mutex->valid = true;
+#endif
+ toku_instr_mutex_init(key, *mutex);
+ const int r = pthread_mutex_init(&mutex->pmutex, attr);
+ assert_zero(r);
+#if TOKU_PTHREAD_DEBUG
+ mutex->locked = false;
+ invariant(mutex->valid);
+ mutex->valid = true;
+ mutex->owner = 0;
+#endif
}
-static inline void
-toku_pthread_rwlock_init(toku_pthread_rwlock_t *__restrict rwlock, const toku_pthread_rwlockattr_t *__restrict attr) {
- int r = pthread_rwlock_init(rwlock, attr);
+inline void toku_mutex_destroy(toku_mutex_t *mutex) {
+#if TOKU_PTHREAD_DEBUG
+ invariant(mutex->valid);
+ mutex->valid = false;
+ invariant(!mutex->locked);
+#endif
+ toku_instr_mutex_destroy(mutex->psi_mutex);
+ int r = pthread_mutex_destroy(&mutex->pmutex);
assert_zero(r);
}
-static inline void
-toku_pthread_rwlock_destroy(toku_pthread_rwlock_t *rwlock) {
- int r = pthread_rwlock_destroy(rwlock);
+#define toku_pthread_rwlock_rdlock(RW) \
+ toku_pthread_rwlock_rdlock_with_source_location(RW, __FILE__, __LINE__)
+
+#define toku_pthread_rwlock_wrlock(RW) \
+ toku_pthread_rwlock_wrlock_with_source_location(RW, __FILE__, __LINE__)
+
+inline void toku_pthread_rwlock_init(
+ const toku_instr_key &key,
+ toku_pthread_rwlock_t *__restrict rwlock,
+ const toku_pthread_rwlockattr_t *__restrict attr) {
+ toku_instr_rwlock_init(key, *rwlock);
+ int r = pthread_rwlock_init(&rwlock->rwlock, attr);
assert_zero(r);
}
-static inline void
-toku_pthread_rwlock_rdlock(toku_pthread_rwlock_t *rwlock) {
- int r = pthread_rwlock_rdlock(rwlock);
+inline void toku_pthread_rwlock_destroy(toku_pthread_rwlock_t *rwlock) {
+ toku_instr_rwlock_destroy(rwlock->psi_rwlock);
+ int r = pthread_rwlock_destroy(&rwlock->rwlock);
assert_zero(r);
}
-static inline void
-toku_pthread_rwlock_rdunlock(toku_pthread_rwlock_t *rwlock) {
- int r = pthread_rwlock_unlock(rwlock);
+inline void toku_pthread_rwlock_rdlock_with_source_location(
+ toku_pthread_rwlock_t *rwlock,
+ const char *src_file,
+ uint src_line) {
+
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ toku_instr_rwlock_rdlock_wait_start(
+ rwlock_instr, *rwlock, src_file, src_line);
+ /* Instrumented code */
+ const int r = pthread_rwlock_rdlock(&rwlock->rwlock);
+
+ /* Instrumentation end */
+ toku_instr_rwlock_rdlock_wait_end(rwlock_instr, r);
+
assert_zero(r);
}
-static inline void
-toku_pthread_rwlock_wrlock(toku_pthread_rwlock_t *rwlock) {
- int r = pthread_rwlock_wrlock(rwlock);
+inline void toku_pthread_rwlock_wrlock_with_source_location(
+ toku_pthread_rwlock_t *rwlock,
+ const char *src_file,
+ uint src_line) {
+
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ toku_instr_rwlock_wrlock_wait_start(
+ rwlock_instr, *rwlock, src_file, src_line);
+ /* Instrumented code */
+ const int r = pthread_rwlock_wrlock(&rwlock->rwlock);
+
+ /* Instrumentation end */
+ toku_instr_rwlock_wrlock_wait_end(rwlock_instr, r);
+
assert_zero(r);
}
-static inline void
-toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) {
- int r = pthread_rwlock_unlock(rwlock);
+inline void toku_pthread_rwlock_rdunlock(toku_pthread_rwlock_t *rwlock) {
+ toku_instr_rwlock_unlock(*rwlock);
+ const int r = pthread_rwlock_unlock(&rwlock->rwlock);
assert_zero(r);
}
-static inline int
-toku_pthread_create(toku_pthread_t *thread, const toku_pthread_attr_t *attr, void *(*start_function)(void *), void *arg) {
- return pthread_create(thread, attr, start_function, arg);
+inline void toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) {
+ toku_instr_rwlock_unlock(*rwlock);
+ const int r = pthread_rwlock_unlock(&rwlock->rwlock);
+ assert_zero(r);
}
-static inline int
-toku_pthread_join(toku_pthread_t thread, void **value_ptr) {
+static inline int toku_pthread_join(toku_pthread_t thread, void **value_ptr) {
return pthread_join(thread, value_ptr);
}
@@ -361,7 +511,15 @@ toku_pthread_getspecific(toku_pthread_key_t key) {
return pthread_getspecific(key);
}
-static inline int
-toku_pthread_setspecific(toku_pthread_key_t key, void *data) {
+static inline int toku_pthread_setspecific(toku_pthread_key_t key, void *data) {
return pthread_setspecific(key, data);
}
+
+int toku_pthread_yield(void) __attribute__((__visibility__("default")));
+
+static inline toku_pthread_t toku_pthread_self(void) { return pthread_self(); }
+
+static inline void *toku_pthread_done(void *exit_value) {
+ toku_instr_delete_current_thread();
+ pthread_exit(exit_value);
+}
diff --git a/storage/tokudb/PerconaFT/portability/toku_race_tools.h b/storage/tokudb/PerconaFT/portability/toku_race_tools.h
index 8482a164fb8..9ed46ec909d 100644
--- a/storage/tokudb/PerconaFT/portability/toku_race_tools.h
+++ b/storage/tokudb/PerconaFT/portability/toku_race_tools.h
@@ -40,6 +40,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <portability/toku_config.h>
+#ifdef HAVE_valgrind
+#undef USE_VALGRIND
+#define USE_VALGRIND 1
+#endif
+
#if defined(__linux__) && USE_VALGRIND
# include <valgrind/helgrind.h>
diff --git a/storage/tokudb/PerconaFT/src/indexer-undo-do.cc b/storage/tokudb/PerconaFT/src/indexer-undo-do.cc
index 4c7f5336161..cc86402751b 100644
--- a/storage/tokudb/PerconaFT/src/indexer-undo-do.cc
+++ b/storage/tokudb/PerconaFT/src/indexer-undo-do.cc
@@ -571,6 +571,7 @@ indexer_ft_delete_committed(DB_INDEXER *indexer, DB *hotdb, DBT *hotkey, XIDS xi
oldest_referenced_xid_estimate,
true);
toku_ft_send_delete(db_struct_i(hotdb)->ft_handle, hotkey, xids, &gc_info);
+ toku_ft_adjust_logical_row_count(db_struct_i(hotdb)->ft_handle->ft, -1);
}
}
return result;
@@ -616,6 +617,7 @@ indexer_ft_insert_committed(DB_INDEXER *indexer, DB *hotdb, DBT *hotkey, DBT *ho
oldest_referenced_xid_estimate,
true);
toku_ft_send_insert(db_struct_i(hotdb)->ft_handle, hotkey, hotval, xids, FT_INSERT, &gc_info);
+ toku_ft_adjust_logical_row_count(db_struct_i(hotdb)->ft_handle->ft, 1);
}
}
return result;
diff --git a/storage/tokudb/PerconaFT/src/indexer.cc b/storage/tokudb/PerconaFT/src/indexer.cc
index b475b08beb5..044ffac917c 100644
--- a/storage/tokudb/PerconaFT/src/indexer.cc
+++ b/storage/tokudb/PerconaFT/src/indexer.cc
@@ -253,16 +253,21 @@ toku_indexer_create_indexer(DB_ENV *env,
indexer->set_error_callback = toku_indexer_set_error_callback;
indexer->set_poll_function = toku_indexer_set_poll_function;
indexer->build = build_index;
- indexer->close = close_indexer;
- indexer->abort = abort_indexer;
-
- toku_mutex_init(&indexer->i->indexer_lock, NULL);
- toku_mutex_init(&indexer->i->indexer_estimate_lock, NULL);
+ indexer->close = close_indexer;
+ indexer->abort = abort_indexer;
+
+ toku_mutex_init(
+ *indexer_i_indexer_lock_mutex_key, &indexer->i->indexer_lock, nullptr);
+ toku_mutex_init(*indexer_i_indexer_estimate_lock_mutex_key,
+ &indexer->i->indexer_estimate_lock,
+ nullptr);
toku_init_dbt(&indexer->i->position_estimate);
//
- // create and close a dummy loader to get redirection going for the hot indexer
- // This way, if the hot index aborts, but other transactions have references to the
+ // create and close a dummy loader to get redirection going for the hot
+ // indexer
+ // This way, if the hot index aborts, but other transactions have references
+ // to the
// underlying FT, then those transactions can do dummy operations on the FT
// while the DB gets redirected back to an empty dictionary
//
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-first-empty.cc b/storage/tokudb/PerconaFT/src/tests/blocking-first-empty.cc
index d9d865254f1..3b53911e614 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-first-empty.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-first-empty.cc
@@ -99,12 +99,14 @@ static void *blocking_first_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_first_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_first_thread, &a); assert(r == 0);
+ struct blocking_first_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_first_thread, &a);
+ assert(r == 0);
}
blocking_first(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-first.cc b/storage/tokudb/PerconaFT/src/tests/blocking-first.cc
index 9f3f8f4eb6a..c104eabd6c3 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-first.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-first.cc
@@ -116,12 +116,14 @@ static void *blocking_first_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_first_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_first_thread, &a); assert(r == 0);
+ struct blocking_first_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_first_thread, &a);
+ assert(r == 0);
}
blocking_first(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-last.cc b/storage/tokudb/PerconaFT/src/tests/blocking-last.cc
index a62d83eb46f..3a702e3f115 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-last.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-last.cc
@@ -116,12 +116,14 @@ static void *blocking_last_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_last_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_last_thread, &a); assert(r == 0);
+ struct blocking_last_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_last_thread, &a);
+ assert(r == 0);
}
blocking_last(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-next-prev-deadlock.cc b/storage/tokudb/PerconaFT/src/tests/blocking-next-prev-deadlock.cc
index bd5697ba526..781708cc627 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-next-prev-deadlock.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-next-prev-deadlock.cc
@@ -181,12 +181,14 @@ static void *blocking_next_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_next_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_next_thread, &a); assert(r == 0);
+ struct blocking_next_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_next_thread, &a);
+ assert(r == 0);
}
blocking_prev(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-next-prev.cc b/storage/tokudb/PerconaFT/src/tests/blocking-next-prev.cc
index 729473bb7cf..aa179e88d76 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-next-prev.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-next-prev.cc
@@ -188,12 +188,14 @@ static void *blocking_next_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_next_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_next_thread, &a); assert(r == 0);
+ struct blocking_next_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_next_thread, &a);
+ assert(r == 0);
}
blocking_prev(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-prelock-range.cc b/storage/tokudb/PerconaFT/src/tests/blocking-prelock-range.cc
index 8821b39aa8a..38875a2f8ec 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-prelock-range.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-prelock-range.cc
@@ -140,12 +140,17 @@ int test_main(int argc, char * const argv[]) {
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
toku_pthread_t tids[nthreads];
- struct blocking_range_lock_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_range_lock_thread, &a); assert(r == 0);
+ struct blocking_range_lock_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(toku_uninstrumented,
+ &tids[i],
+ nullptr,
+ blocking_range_lock_thread,
+ &a);
+ assert(r == 0);
}
blocking_range_lock(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-put-timeout.cc b/storage/tokudb/PerconaFT/src/tests/blocking-put-timeout.cc
index a31e173fd83..bf4a8a24f47 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-put-timeout.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-put-timeout.cc
@@ -57,8 +57,8 @@ struct test_seq {
static void test_seq_init(struct test_seq *seq) {
seq->state = 0;
- toku_mutex_init(&seq->lock, NULL);
- toku_cond_init(&seq->cv, NULL);
+ toku_mutex_init(toku_uninstrumented, &seq->lock, nullptr);
+ toku_cond_init(toku_uninstrumented, &seq->cv, nullptr);
}
static void test_seq_destroy(struct test_seq *seq) {
@@ -172,13 +172,18 @@ int test_main(int argc, char * const argv[]) {
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
// run test
- struct test_seq seq; ZERO_STRUCT(seq); test_seq_init(&seq);
+ struct test_seq seq;
+ ZERO_STRUCT(seq);
+ test_seq_init(&seq);
toku_pthread_t t_a_id;
- struct t_a_args t_a_args = { db_env, db, &seq };
- r = toku_pthread_create(&t_a_id, NULL, t_a_thread, &t_a_args); assert(r == 0);
+ struct t_a_args t_a_args = {db_env, db, &seq};
+ r = toku_pthread_create(
+ toku_uninstrumented, &t_a_id, nullptr, t_a_thread, &t_a_args);
+ assert(r == 0);
t_b(db_env, db, &seq);
void *ret;
- r = toku_pthread_join(t_a_id, &ret); assert(r == 0);
+ r = toku_pthread_join(t_a_id, &ret);
+ assert(r == 0);
test_seq_destroy(&seq);
// close env
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-put-wakeup.cc b/storage/tokudb/PerconaFT/src/tests/blocking-put-wakeup.cc
index 615cdb5d17c..dba7962de35 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-put-wakeup.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-put-wakeup.cc
@@ -58,8 +58,8 @@ struct test_seq {
static void test_seq_init(struct test_seq *seq) {
seq->state = 0;
- toku_mutex_init(&seq->lock, NULL);
- toku_cond_init(&seq->cv, NULL);
+ toku_mutex_init(toku_uninstrumented, &seq->lock, nullptr);
+ toku_cond_init(toku_uninstrumented, &seq->cv, nullptr);
}
static void test_seq_destroy(struct test_seq *seq) {
@@ -167,13 +167,18 @@ int test_main(int argc, char * const argv[]) {
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
// run test
- struct test_seq seq; ZERO_STRUCT(seq); test_seq_init(&seq);
+ struct test_seq seq;
+ ZERO_STRUCT(seq);
+ test_seq_init(&seq);
toku_pthread_t t_a_id;
- struct t_a_args t_a_args = { db_env, db, &seq };
- r = toku_pthread_create(&t_a_id, NULL, t_a_thread, &t_a_args); assert(r == 0);
+ struct t_a_args t_a_args = {db_env, db, &seq};
+ r = toku_pthread_create(
+ toku_uninstrumented, &t_a_id, nullptr, t_a_thread, &t_a_args);
+ assert(r == 0);
t_b(db_env, db, &seq);
void *ret;
- r = toku_pthread_join(t_a_id, &ret); assert(r == 0);
+ r = toku_pthread_join(t_a_id, &ret);
+ assert(r == 0);
test_seq_destroy(&seq);
// close env
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-put.cc b/storage/tokudb/PerconaFT/src/tests/blocking-put.cc
index 0fa56325007..95481062483 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-put.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-put.cc
@@ -139,12 +139,14 @@ int test_main(int argc, char * const argv[]) {
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
toku_pthread_t tids[nthreads];
- struct blocking_put_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_put_thread, &a); assert(r == 0);
+ struct blocking_put_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_put_thread, &a);
+ assert(r == 0);
}
blocking_put(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-0.cc b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-0.cc
index a0e03ab3293..7c2e7b0fb26 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-0.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-0.cc
@@ -126,12 +126,15 @@ static void *blocking_set_range_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime, uint64_t the_key) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_set_range_args a = { db_env, db, nrows, sleeptime, the_key };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_set_range_thread, &a); assert(r == 0);
+ struct blocking_set_range_args a = {db_env, db, nrows, sleeptime, the_key};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr,
+ blocking_set_range_thread, &a);
+ assert(r == 0);
}
blocking_set_range(db_env, db, nrows, sleeptime, the_key);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-n.cc b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-n.cc
index 056d74dbdd2..54a5846eb5e 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-n.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-n.cc
@@ -121,12 +121,15 @@ static void *blocking_set_range_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime, uint64_t the_key) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_set_range_args a = { db_env, db, nrows, sleeptime, the_key };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_set_range_thread, &a); assert(r == 0);
+ struct blocking_set_range_args a = {db_env, db, nrows, sleeptime, the_key};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr,
+ blocking_set_range_thread, &a);
+ assert(r == 0);
}
blocking_set_range(db_env, db, nrows, sleeptime, the_key);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-reverse-0.cc b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-reverse-0.cc
index 1e7fca85bff..59e582547bf 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-reverse-0.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-reverse-0.cc
@@ -126,12 +126,15 @@ static void *blocking_set_range_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime, uint64_t the_key) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_set_range_args a = { db_env, db, nrows, sleeptime, the_key };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_set_range_thread, &a); assert(r == 0);
+ struct blocking_set_range_args a = {db_env, db, nrows, sleeptime, the_key};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr,
+ blocking_set_range_thread, &a);
+ assert(r == 0);
}
blocking_set_range(db_env, db, nrows, sleeptime, the_key);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-set.cc b/storage/tokudb/PerconaFT/src/tests/blocking-set.cc
index ba64989842a..aa433c87be1 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-set.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-set.cc
@@ -182,12 +182,14 @@ int test_main(int argc, char * const argv[]) {
populate(db_env, db, nrows);
toku_pthread_t tids[nthreads];
- struct blocking_set_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_set_thread, &a); assert(r == 0);
+ struct blocking_set_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_set_thread, &a);
+ assert(r == 0);
}
blocking_set(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-table-lock.cc b/storage/tokudb/PerconaFT/src/tests/blocking-table-lock.cc
index 9ae33c56621..0953a4e80de 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-table-lock.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-table-lock.cc
@@ -133,12 +133,17 @@ int test_main(int argc, char * const argv[]) {
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
toku_pthread_t tids[nthreads];
- struct blocking_table_lock_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_table_lock_thread, &a); assert(r == 0);
+ struct blocking_table_lock_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(toku_uninstrumented,
+ &tids[i],
+ nullptr,
+ blocking_table_lock_thread,
+ &a);
+ assert(r == 0);
}
blocking_table_lock(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/checkpoint_fairness.cc b/storage/tokudb/PerconaFT/src/tests/checkpoint_fairness.cc
index be82f8c352f..f62dfbc76d3 100644
--- a/storage/tokudb/PerconaFT/src/tests/checkpoint_fairness.cc
+++ b/storage/tokudb/PerconaFT/src/tests/checkpoint_fairness.cc
@@ -113,10 +113,14 @@ int test_main(int argc, char * const argv[]) {
{ int chk_r = db->open(db, NULL, "db", NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT, 0666); CKERR(chk_r); }
pthread_t thds[n_threads];
- int ids[n_threads];
- for (int i=0; i<n_threads; i++) {
- ids[i]=i;
- { int chk_r = toku_pthread_create(&thds[i], NULL, start_txns, &ids[i]); CKERR(chk_r); }
+ int ids[n_threads];
+ for (int i = 0; i < n_threads; i++) {
+ ids[i] = i;
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &thds[i], nullptr, start_txns, &ids[i]);
+ CKERR(chk_r);
+ }
}
start_checkpoints();
diff --git a/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc b/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc
index 221471a8045..135a9843ce4 100644
--- a/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc
+++ b/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc
@@ -271,24 +271,29 @@ run_test (int iter, int die) {
}
// take checkpoint (all dictionaries)
- snapshot(NULL, 1);
+ snapshot(NULL, 1);
if (die) {
- // separate thread will perform random acts on other dictionaries (not 0)
- int r = toku_pthread_create(&thread, 0, random_acts, (void *) dictionaries);
- CKERR(r);
- // this thead will scribble over dictionary 0 before crash to verify that
- // post-checkpoint inserts are not in the database
- DB* db = dictionaries[0].db;
- if (iter & 1)
- scribble(db, iter);
- else
- thin_out(db, iter);
- uint32_t delay = myrandom();
- delay &= 0xFFF; // select lower 12 bits, shifted up 8 for random number ...
- delay = delay << 8; // ... uniformly distributed between 0 and 1M ...
- usleep(delay); // ... to sleep up to one second (1M usec)
- drop_dead();
+ // separate thread will perform random acts on other dictionaries (not
+ // 0)
+ int r = toku_pthread_create(
+ toku_uninstrumented, &thread, nullptr,
+ random_acts, static_cast<void*>(dictionaries));
+ CKERR(r);
+ // this thead will scribble over dictionary 0 before crash to verify
+ // that
+ // post-checkpoint inserts are not in the database
+ DB* db = dictionaries[0].db;
+ if (iter & 1)
+ scribble(db, iter);
+ else
+ thin_out(db, iter);
+ uint32_t delay = myrandom();
+ delay &=
+ 0xFFF; // select lower 12 bits, shifted up 8 for random number ...
+ delay = delay << 8; // ... uniformly distributed between 0 and 1M ...
+ usleep(delay); // ... to sleep up to one second (1M usec)
+ drop_dead();
}
else {
for (i = 0; i < NUM_DICTIONARIES; i++) {
diff --git a/storage/tokudb/PerconaFT/src/tests/db-put-simple-deadlock-threads.cc b/storage/tokudb/PerconaFT/src/tests/db-put-simple-deadlock-threads.cc
index ada46bd7516..e5bcc6af7bb 100644
--- a/storage/tokudb/PerconaFT/src/tests/db-put-simple-deadlock-threads.cc
+++ b/storage/tokudb/PerconaFT/src/tests/db-put-simple-deadlock-threads.cc
@@ -57,8 +57,8 @@ struct test_seq {
static void test_seq_init(struct test_seq *seq) {
seq->state = 0;
- toku_mutex_init(&seq->lock, NULL);
- toku_cond_init(&seq->cv, NULL);
+ toku_mutex_init(toku_uninstrumented, &seq->lock, nullptr);
+ toku_cond_init(toku_uninstrumented, &seq->cv, nullptr);
}
static void test_seq_destroy(struct test_seq *seq) {
@@ -146,8 +146,9 @@ static void simple_deadlock(DB_ENV *db_env, DB *db, int do_txn, int n) {
struct test_seq test_seq; ZERO_STRUCT(test_seq); test_seq_init(&test_seq);
toku_pthread_t tid;
- struct run_txn_b_arg arg = { &test_seq, txn_b, db, n};
- r = toku_pthread_create(&tid, NULL, run_txn_b, &arg);
+ struct run_txn_b_arg arg = {&test_seq, txn_b, db, n};
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, run_txn_b, &arg);
test_seq_sleep(&test_seq, 0);
insert_row(db, txn_a, htonl(0), 0, 0);
diff --git a/storage/tokudb/PerconaFT/src/tests/db-put-simple-lockwait.cc b/storage/tokudb/PerconaFT/src/tests/db-put-simple-lockwait.cc
index 365ea39eced..0fbe851532e 100644
--- a/storage/tokudb/PerconaFT/src/tests/db-put-simple-lockwait.cc
+++ b/storage/tokudb/PerconaFT/src/tests/db-put-simple-lockwait.cc
@@ -95,10 +95,11 @@ static void simple_lockwait(DB_ENV *db_env, DB *db, int do_txn, int nrows, int n
insert_row(db, txns[0], htonl(0), 0, 0);
toku_pthread_t tids[ntxns];
- for (int i = 1 ; i < ntxns; i++) {
+ for (int i = 1; i < ntxns; i++) {
struct insert_one_arg *XMALLOC(arg);
- *arg = (struct insert_one_arg) { txns[i], db};
- r = toku_pthread_create(&tids[i], NULL, insert_one, arg);
+ *arg = (struct insert_one_arg){txns[i], db};
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, insert_one, arg);
}
sleep(10);
diff --git a/storage/tokudb/PerconaFT/src/tests/db-put-update-deadlock.cc b/storage/tokudb/PerconaFT/src/tests/db-put-update-deadlock.cc
index 3660f11d1bd..7a968058d7f 100644
--- a/storage/tokudb/PerconaFT/src/tests/db-put-update-deadlock.cc
+++ b/storage/tokudb/PerconaFT/src/tests/db-put-update-deadlock.cc
@@ -128,10 +128,12 @@ static void update_deadlock(DB_ENV *db_env, DB *db, int do_txn, int nrows, int n
// get write locks
toku_pthread_t tids[ntxns];
- for (int i = 0 ; i < ntxns; i++) {
+ for (int i = 0; i < ntxns; i++) {
struct write_one_arg *XMALLOC(arg);
- *arg = (struct write_one_arg) { txns[i], db, (int) htonl((i + 1) % ntxns), 0};
- r = toku_pthread_create(&tids[i], NULL, write_one_f, arg);
+ *arg =
+ (struct write_one_arg){txns[i], db, (int)htonl((i + 1) % ntxns), 0};
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, write_one_f, arg);
}
#else
// get read locks
@@ -141,10 +143,11 @@ static void update_deadlock(DB_ENV *db_env, DB *db, int do_txn, int nrows, int n
// get write locks
toku_pthread_t tids[ntxns];
- for (int i = 0 ; i < ntxns; i++) {
+ for (int i = 0; i < ntxns; i++) {
struct write_one_arg *XMALLOC(arg);
- *arg = (struct write_one_arg) { txns[i], db, (int) htonl(0), 0};
- r = toku_pthread_create(&tids[i], NULL, write_one_f, arg);
+ *arg = (struct write_one_arg){txns[i], db, (int)htonl(0), 0};
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, write_one_f, arg);
}
#endif
diff --git a/storage/tokudb/PerconaFT/src/tests/filesize.cc b/storage/tokudb/PerconaFT/src/tests/filesize.cc
index 6ab22245e68..9dfeea131c6 100644
--- a/storage/tokudb/PerconaFT/src/tests/filesize.cc
+++ b/storage/tokudb/PerconaFT/src/tests/filesize.cc
@@ -170,11 +170,9 @@ get_file_pathname(void) {
if (verbose) printf("path = %s\n", path);
}
-
-static int
-getsizeM(void) {
+static int getsizeM(void) {
toku_struct_stat buf;
- int r = toku_stat(path, &buf);
+ int r = toku_stat(path, &buf, toku_uninstrumented);
CKERR(r);
int sizeM = (int)buf.st_size >> 20;
check_fragmentation();
diff --git a/storage/tokudb/PerconaFT/src/tests/hotindexer-bw.cc b/storage/tokudb/PerconaFT/src/tests/hotindexer-bw.cc
index 82471f30e45..5336bc3329f 100644
--- a/storage/tokudb/PerconaFT/src/tests/hotindexer-bw.cc
+++ b/storage/tokudb/PerconaFT/src/tests/hotindexer-bw.cc
@@ -302,12 +302,19 @@ static void test_indexer(DB *src, DB **dbs)
CKERR(r);
toku_mutex_unlock(&put_lock);
- // start threads doing additional inserts - no lock issues since indexer already created
- r = toku_pthread_create(&client_threads[0], 0, client, (void *)&client_specs[0]); CKERR(r);
-// r = toku_pthread_create(&client_threads[1], 0, client, (void *)&client_specs[1]); CKERR(r);
+ // start threads doing additional inserts - no lock issues since indexer
+ // already created
+ r = toku_pthread_create(toku_uninstrumented,
+ &client_threads[0],
+ nullptr,
+ client,
+ static_cast<void *>(&client_specs[0]));
+ CKERR(r);
+ // r = toku_pthread_create(toku_uninstrumented, &client_threads[1], 0,
+ // client, (void *)&client_specs[1]); CKERR(r);
struct timeval start, now;
- if ( verbose ) {
+ if (verbose) {
printf("test_indexer build\n");
gettimeofday(&start,0);
}
@@ -342,14 +349,13 @@ static void test_indexer(DB *src, DB **dbs)
if ( verbose ) printf("test_indexer done\n");
}
-
-static void run_test(void)
-{
+static void run_test(void) {
int r;
- toku_mutex_init(&put_lock, NULL);
+ toku_mutex_init(toku_uninstrumented, &put_lock, nullptr);
toku_os_recursive_delete(TOKU_TEST_FILENAME);
- r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
- char logname[TOKU_PATH_MAX+1];
+ r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU + S_IRWXG + S_IRWXO);
+ CKERR(r);
+ char logname[TOKU_PATH_MAX + 1];
r = toku_os_mkdir(toku_path_join(logname, 2, TOKU_TEST_FILENAME, "log"), S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
r = db_env_create(&env, 0); CKERR(r);
diff --git a/storage/tokudb/PerconaFT/src/tests/hotindexer-multiclient.cc b/storage/tokudb/PerconaFT/src/tests/hotindexer-multiclient.cc
index eefc621f80a..004a19eccec 100644
--- a/storage/tokudb/PerconaFT/src/tests/hotindexer-multiclient.cc
+++ b/storage/tokudb/PerconaFT/src/tests/hotindexer-multiclient.cc
@@ -303,13 +303,25 @@ static void test_indexer(DB *src, DB **dbs)
r = indexer->set_poll_function(indexer, poll_print, NULL);
CKERR(r);
- // start threads doing additional inserts - no lock issues since indexer already created
- r = toku_pthread_create(&client_threads[0], 0, client, (void *)&client_specs[0]); CKERR(r);
- r = toku_pthread_create(&client_threads[1], 0, client, (void *)&client_specs[1]); CKERR(r);
-// r = toku_pthread_create(&client_threads[2], 0, client, (void *)&client_specs[2]); CKERR(r);
+ // start threads doing additional inserts - no lock issues since indexer
+ // already created
+ r = toku_pthread_create(toku_uninstrumented,
+ &client_threads[0],
+ nullptr,
+ client,
+ static_cast<void *>(&client_specs[0]));
+ CKERR(r);
+ r = toku_pthread_create(toku_uninstrumented,
+ &client_threads[1],
+ nullptr,
+ client,
+ static_cast<void *>(&client_specs[1]));
+ CKERR(r);
+ // r = toku_pthread_create(toku_uninstrumented, &client_threads[2], 0,
+ // client, (void *)&client_specs[2]); CKERR(r);
struct timeval start, now;
- if ( verbose ) {
+ if (verbose) {
printf("test_indexer build\n");
gettimeofday(&start,0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/hotindexer-put-abort.cc b/storage/tokudb/PerconaFT/src/tests/hotindexer-put-abort.cc
index 27501291b15..f4dd9c53ed5 100644
--- a/storage/tokudb/PerconaFT/src/tests/hotindexer-put-abort.cc
+++ b/storage/tokudb/PerconaFT/src/tests/hotindexer-put-abort.cc
@@ -142,11 +142,14 @@ run_test(void) {
}
// run the indexer
- struct indexer_arg indexer_arg = { env, src_db, 1, &dest_db };
+ struct indexer_arg indexer_arg = {env, src_db, 1, &dest_db};
toku_pthread_t pid;
- r = toku_pthread_create(&pid, NULL, indexer_thread, &indexer_arg); assert_zero(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &pid, nullptr, indexer_thread, &indexer_arg);
+ assert_zero(r);
- r = txn->abort(txn); assert_zero(r);
+ r = txn->abort(txn);
+ assert_zero(r);
void *ret;
r = toku_pthread_join(pid, &ret); assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/src/tests/hotindexer-put-commit.cc b/storage/tokudb/PerconaFT/src/tests/hotindexer-put-commit.cc
index 59b40037125..99c9bf301cc 100644
--- a/storage/tokudb/PerconaFT/src/tests/hotindexer-put-commit.cc
+++ b/storage/tokudb/PerconaFT/src/tests/hotindexer-put-commit.cc
@@ -166,12 +166,16 @@ run_test(void) {
}
// run the indexer
- struct indexer_arg indexer_arg = { env, src_db, 1, &dest_db };
+ struct indexer_arg indexer_arg = {env, src_db, 1, &dest_db};
toku_pthread_t pid;
- r = toku_pthread_create(&pid, NULL, indexer_thread, &indexer_arg); assert_zero(r);
-
- if (verbose) fprintf(stderr, "commit start\n");
- r = txn->commit(txn, 0); assert_zero(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &pid, nullptr, indexer_thread, &indexer_arg);
+ assert_zero(r);
+
+ if (verbose)
+ fprintf(stderr, "commit start\n");
+ r = txn->commit(txn, 0);
+ assert_zero(r);
if (verbose) fprintf(stderr, "commit end\n");
void *ret;
diff --git a/storage/tokudb/PerconaFT/src/tests/hotindexer-with-queries.cc b/storage/tokudb/PerconaFT/src/tests/hotindexer-with-queries.cc
index a0be49c1617..2bc60142f3c 100644
--- a/storage/tokudb/PerconaFT/src/tests/hotindexer-with-queries.cc
+++ b/storage/tokudb/PerconaFT/src/tests/hotindexer-with-queries.cc
@@ -114,10 +114,12 @@ static void query_only(DB *src)
client_init();
// start thread doing query
- r = toku_pthread_create(client_thread, 0, client, (void *)src);
+ r = toku_pthread_create(
+ toku_uninstrumented, client_thread, nullptr,
+ client, static_cast<void *>(src));
CKERR(r);
- r = toku_pthread_join(*client_thread, &t0);
+ r = toku_pthread_join(*client_thread, &t0);
CKERR(r);
client_cleanup();
@@ -150,10 +152,13 @@ static void test_indexer(DB *src, DB **dbs)
CKERR(r);
// start thread doing query
- r = toku_pthread_create(client_thread, 0, client, (void *)src); CKERR(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, client_thread, nullptr,
+ client, static_cast<void *>(src));
+ CKERR(r);
struct timeval start, now;
- if ( verbose ) {
+ if (verbose) {
printf("test_indexer build\n");
gettimeofday(&start,0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/locktree_escalation_stalls.cc b/storage/tokudb/PerconaFT/src/tests/locktree_escalation_stalls.cc
index b4874472bcb..e6c1b18b2b6 100644
--- a/storage/tokudb/PerconaFT/src/tests/locktree_escalation_stalls.cc
+++ b/storage/tokudb/PerconaFT/src/tests/locktree_escalation_stalls.cc
@@ -191,17 +191,22 @@ static void run_test(uint64_t max_i, int n_small) {
env, big_db, max_i, big_test,
};
toku_pthread_t big_id;
- r = toku_pthread_create(&big_id, NULL, test_f, &big_test_args);
+ r = toku_pthread_create(
+ toku_uninstrumented, &big_id, nullptr, test_f, &big_test_args);
assert(r == 0);
struct test_args small_test_args[n_small];
toku_pthread_t small_id[n_small];
for (int i = 0; i < n_small; i++) {
- small_test_args[i] = { env, small_db, max_i, small_test };
- r = toku_pthread_create(&small_id[i], NULL, test_f, &small_test_args[i]);
+ small_test_args[i] = {env, small_db, max_i, small_test};
+ r = toku_pthread_create(toku_uninstrumented,
+ &small_id[i],
+ nullptr,
+ test_f,
+ &small_test_args[i]);
assert(r == 0);
}
-
+
void *big_ret;
r = toku_pthread_join(big_id, &big_ret);
assert(r == 0);
diff --git a/storage/tokudb/PerconaFT/src/tests/recover-test_crash_in_flusher_thread.h b/storage/tokudb/PerconaFT/src/tests/recover-test_crash_in_flusher_thread.h
index 0ed68207ed4..5c10d0cb712 100644
--- a/storage/tokudb/PerconaFT/src/tests/recover-test_crash_in_flusher_thread.h
+++ b/storage/tokudb/PerconaFT/src/tests/recover-test_crash_in_flusher_thread.h
@@ -70,13 +70,18 @@ static void *do_checkpoint_and_crash(void *arg) {
static void flt_callback(int flt_state, void* extra) {
cnt++;
if (verbose) printf("flt_state!! %d\n", flt_state);
- if (cnt > 0 && !starting_a_chkpt && flt_state == state_to_crash) {
- starting_a_chkpt = true;
- if (verbose) printf("flt_state %d\n", flt_state);
- int r = toku_pthread_create(&checkpoint_tid, NULL, do_checkpoint_and_crash, extra);
- assert(r==0);
- usleep(2*1000*1000);
- }
+ if (cnt > 0 && !starting_a_chkpt && flt_state == state_to_crash) {
+ starting_a_chkpt = true;
+ if (verbose)
+ printf("flt_state %d\n", flt_state);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ do_checkpoint_and_crash,
+ extra);
+ assert(r == 0);
+ usleep(2 * 1000 * 1000);
+ }
}
diff --git a/storage/tokudb/PerconaFT/src/tests/recovery_stress.cc b/storage/tokudb/PerconaFT/src/tests/recovery_stress.cc
index b1f5f98a90a..1646030cc85 100644
--- a/storage/tokudb/PerconaFT/src/tests/recovery_stress.cc
+++ b/storage/tokudb/PerconaFT/src/tests/recovery_stress.cc
@@ -515,19 +515,8 @@ static void run_test (int iter) {
// if requesting crash, randomly do other non-committed acts, then "drop_dead"
if (iter > 0) {
- if (verbose) printf("dying\n");
-#if 0
- // separate thread will perform random acts on other dictionaries (not 0)
- r = toku_pthread_create(&thread, 0, random_acts, (void *) dictionaries);
- CKERR(r);
- // this thead will scribble over dictionary 0 before crash to verify that
- // post-checkpoint inserts are not in the database
- DB* db = dictionaries[0].db;
- if (iter & 1)
- scribble(db, iter);
- else
- thin_out(db, iter);
-#endif
+ if (verbose)
+ printf("dying\n");
uint32_t delay = myrandom();
delay &= 0xFFF; // select lower 12 bits, shifted up 8 for random number ...
delay = delay << 8; // ... uniformly distributed between 0 and 1M ...
diff --git a/storage/tokudb/PerconaFT/src/tests/stress_openclose.h b/storage/tokudb/PerconaFT/src/tests/stress_openclose.h
index 3f10bfe8aeb..3a55ca4486f 100644
--- a/storage/tokudb/PerconaFT/src/tests/stress_openclose.h
+++ b/storage/tokudb/PerconaFT/src/tests/stress_openclose.h
@@ -245,19 +245,16 @@ stress_table(DB_ENV *env, DB **dbp, struct cli_args *cli_args) {
// which they can choose a random db to either touch or query
XMALLOC_N(num_buckets, buckets);
for (int i = 0; i < num_buckets; i++) {
- struct db_bucket bucket = {
- .env = env,
- .db = dbp[i],
- .is_open = true
- };
+ struct db_bucket bucket = {.env = env, .db = dbp[i], .is_open = true};
buckets[i] = bucket;
- toku_mutex_init(&buckets[i].mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &buckets[i].mutex, nullptr);
}
// run all of the query and update workers. they may randomly open
// and close the dbs in each db_bucket to be some random dictionary,
// so when they're done we'll have to clean up the mess so this
// stress test can exit gracefully expecting db[i] = the ith db
- //verbose_printf("stressing %d tables using %d update threads, %d query threads\n",
+ // verbose_printf("stressing %d tables using %d update threads, %d query
+ // threads\n",
// num_buckets, update_threads, query_threads);
verbose_printf("stressing %d tables using %d update threads\n",
num_buckets, update_threads);
diff --git a/storage/tokudb/PerconaFT/src/tests/test3039.cc b/storage/tokudb/PerconaFT/src/tests/test3039.cc
index 54a2b3bf730..6c38fa13592 100644
--- a/storage/tokudb/PerconaFT/src/tests/test3039.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test3039.cc
@@ -184,30 +184,36 @@ void do_threads (unsigned long long N, int do_nonlocal) {
toku_pthread_t ths[2];
struct reader_thread_state rstates[2] = {{.elapsed_time = 0.0,
.n_did_read = 0,
- .n_to_read = (long long signed) N,
- .do_local = 1,
- .finish = 0},
+ .n_to_read = (long long signed)N,
+ .do_local = 1,
+ .finish = 0},
{.elapsed_time = 0.0,
.n_did_read = 0,
.n_to_read = -1,
- .do_local = 0,
- .finish = 0}};
+ .do_local = 0,
+ .finish = 0}};
int n_to_create = do_nonlocal ? 2 : 1;
- for (int i=0; i<n_to_create; i++) {
- int r = toku_pthread_create(&ths[i], 0, reader_thread, (void*)&rstates[i]);
- CKERR(r);
+ for (int i = 0; i < n_to_create; i++) {
+ int r = toku_pthread_create(toku_uninstrumented,
+ &ths[i],
+ nullptr,
+ reader_thread,
+ static_cast<void *>(&rstates[i]));
+ CKERR(r);
}
- for (int i=0; i<n_to_create; i++) {
- void *retval;
- int r = toku_pthread_join(ths[i], &retval);
- CKERR(r);
- assert(retval==0);
- if (verbose) {
- printf("%9s thread time = %8.2fs on %9lld reads (%.3f us/read)\n",
- (i==0 ? "local" : "nonlocal"),
- rstates[i].elapsed_time, rstates[i].n_did_read, rstates[i].elapsed_time/rstates[i].n_did_read * 1e6);
- }
- rstates[1].finish = 1;
+ for (int i = 0; i < n_to_create; i++) {
+ void *retval;
+ int r = toku_pthread_join(ths[i], &retval);
+ CKERR(r);
+ assert(retval == 0);
+ if (verbose) {
+ printf("%9s thread time = %8.2fs on %9lld reads (%.3f us/read)\n",
+ (i == 0 ? "local" : "nonlocal"),
+ rstates[i].elapsed_time,
+ rstates[i].n_did_read,
+ rstates[i].elapsed_time / rstates[i].n_did_read * 1e6);
+ }
+ rstates[1].finish = 1;
}
if (verbose && do_nonlocal) {
printf("total %9lld reads (%.3f us/read)\n",
diff --git a/storage/tokudb/PerconaFT/src/tests/test_1672532.cc b/storage/tokudb/PerconaFT/src/tests/test_1672532.cc
new file mode 100644
index 00000000000..721e7677824
--- /dev/null
+++ b/storage/tokudb/PerconaFT/src/tests/test_1672532.cc
@@ -0,0 +1,210 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+#ident "$Id$"
+/*======
+This file is part of PerconaFT.
+
+
+Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
+
+ PerconaFT is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2,
+ as published by the Free Software Foundation.
+
+ PerconaFT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
+
+----------------------------------------
+
+ PerconaFT is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License, version 3,
+ as published by the Free Software Foundation.
+
+ PerconaFT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
+======= */
+
+#ident \
+ "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
+
+#include "test.h"
+// to verify the DB_LOCKING_READ works to lock the read rows for snapshot
+// isolaton.
+// we create a db, then init a read transaction with repeatable-read isolation
+// and
+// locking read flag, then we start another transaction to grab the write lock.
+// DB_LOCKING_READ is defined here to just make the before and after tests work
+// (before
+// test did not have DB_LOCKING_READ flag).
+#if !defined(DB_LOCKING_READ)
+#define DB_LOCKING_READ 0
+#endif
+static int prelock_range(DBC *cursor, int left, int right) {
+ DBT key_left;
+ dbt_init(&key_left, &left, sizeof left);
+ DBT key_right;
+ dbt_init(&key_right, &right, sizeof right);
+ int r = cursor->c_set_bounds(cursor, &key_left, &key_right, true, 0);
+ return r;
+}
+
+static void test_read_write_range(DB_ENV *env,
+ DB *db,
+ uint32_t iso_flags,
+ int expect_r) {
+ int r;
+
+ DB_TXN *txn_a = NULL;
+ r = env->txn_begin(env, NULL, &txn_a, iso_flags);
+ assert_zero(r);
+ DB_TXN *txn_b = NULL;
+ r = env->txn_begin(env, NULL, &txn_b, iso_flags);
+ assert_zero(r);
+
+ DBC *cursor_a = NULL;
+ r = db->cursor(db, txn_a, &cursor_a, DB_LOCKING_READ);
+ assert_zero(r);
+ DBC *cursor_b = NULL;
+ r = db->cursor(db, txn_b, &cursor_b, DB_RMW);
+ assert_zero(r);
+
+ r = prelock_range(cursor_a, htonl(10), htonl(100));
+ assert_zero(r);
+ r = prelock_range(cursor_b, htonl(50), htonl(200));
+ assert(r == expect_r);
+
+ r = cursor_a->c_close(cursor_a);
+ assert_zero(r);
+ r = cursor_b->c_close(cursor_b);
+ assert_zero(r);
+
+ r = txn_a->commit(txn_a, 0);
+ assert_zero(r);
+ r = txn_b->commit(txn_b, 0);
+ assert_zero(r);
+}
+
+static void test_read_write_point(DB_ENV *env,
+ DB *db,
+ uint32_t iso_flags,
+ int expect_r) {
+ int r;
+
+ DB_TXN *txn1 = NULL;
+ r = env->txn_begin(env, NULL, &txn1, iso_flags);
+ assert_zero(r);
+
+ DB_TXN *txn2 = NULL;
+ r = env->txn_begin(env, NULL, &txn2, iso_flags);
+ assert_zero(r);
+
+ DBC *c1 = NULL;
+ r = db->cursor(db, txn1, &c1, DB_LOCKING_READ);
+ assert_zero(r);
+
+ DBC *c2 = NULL;
+ r = db->cursor(db, txn2, &c2, DB_RMW);
+ assert_zero(r);
+
+ int k = htonl(42);
+ DBT key;
+ dbt_init(&key, &k, sizeof k);
+ DBT val;
+ memset(&val, 0, sizeof val);
+ r = c1->c_get(c1, &key, &val, DB_SET);
+ assert_zero(r);
+
+ r = c2->c_get(c2, &key, &val, DB_SET);
+ assert(r == expect_r);
+
+ r = c1->c_close(c1);
+ assert_zero(r);
+ r = c2->c_close(c2);
+ assert_zero(r);
+
+ r = txn1->commit(txn1, 0);
+ assert_zero(r);
+ r = txn2->commit(txn2, 0);
+ assert_zero(r);
+}
+
+int test_main(int argc, char *const argv[]) {
+ int r;
+
+ const char *env_dir = TOKU_TEST_FILENAME;
+ const char *db_filename = "lockingreadtest";
+
+ parse_args(argc, argv);
+
+ char rm_cmd[strlen(env_dir) + strlen("rm -rf ") + 1];
+ snprintf(rm_cmd, sizeof(rm_cmd), "rm -rf %s", env_dir);
+ r = system(rm_cmd);
+ assert_zero(r);
+
+ r = toku_os_mkdir(env_dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+ assert_zero(r);
+
+ DB_ENV *env = NULL;
+ r = db_env_create(&env, 0);
+ assert_zero(r);
+ int env_open_flags = DB_CREATE | DB_PRIVATE | DB_INIT_MPOOL | DB_INIT_TXN |
+ DB_INIT_LOCK | DB_INIT_LOG;
+ r = env->open(
+ env, env_dir, env_open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ assert_zero(r);
+
+ // create the db
+ DB *db = NULL;
+ r = db_create(&db, env, 0);
+ assert_zero(r);
+ DB_TXN *create_txn = NULL;
+ r = env->txn_begin(env, NULL, &create_txn, 0);
+ assert_zero(r);
+ r = db->open(db,
+ create_txn,
+ db_filename,
+ NULL,
+ DB_BTREE,
+ DB_CREATE,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ assert_zero(r);
+ r = create_txn->commit(create_txn, 0);
+ assert_zero(r);
+
+ // add a record
+
+ DB_TXN *write_txn = NULL;
+ r = env->txn_begin(env, NULL, &write_txn, 0);
+ assert_zero(r);
+
+ int k = htonl(42);
+ int v = 42;
+ DBT key;
+ dbt_init(&key, &k, sizeof k);
+ DBT val;
+ dbt_init(&val, &v, sizeof v);
+ r = db->put(db, write_txn, &key, &val, DB_NOOVERWRITE);
+ assert_zero(r);
+ r = write_txn->commit(write_txn, 0);
+ assert_zero(r);
+
+ test_read_write_range(env, db, DB_TXN_SNAPSHOT, DB_LOCK_NOTGRANTED);
+ test_read_write_point(env, db, DB_TXN_SNAPSHOT, DB_LOCK_NOTGRANTED);
+
+ r = db->close(db, 0);
+ assert_zero(r);
+
+ r = env->close(env, 0);
+ assert_zero(r);
+ return 0;
+}
diff --git a/storage/tokudb/PerconaFT/src/tests/test_3645.cc b/storage/tokudb/PerconaFT/src/tests/test_3645.cc
index bb5566b032d..e1fa37bef54 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_3645.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_3645.cc
@@ -239,33 +239,61 @@ test_evictions (void) {
// make the forward fast scanner
myargs[0].fast = true;
myargs[0].fwd = true;
- { int chk_r = toku_pthread_create(&mytids[0], NULL, scan_db, &myargs[0]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[0], nullptr, scan_db, &myargs[0]);
+ CKERR(chk_r);
+ }
// make the forward slow scanner
myargs[1].fast = false;
myargs[1].fwd = true;
- { int chk_r = toku_pthread_create(&mytids[1], NULL, scan_db, &myargs[1]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[1], nullptr, scan_db, &myargs[1]);
+ CKERR(chk_r);
+ }
// make the backward fast scanner
myargs[2].fast = true;
myargs[2].fwd = false;
- { int chk_r = toku_pthread_create(&mytids[2], NULL, scan_db, &myargs[2]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[2], nullptr, scan_db, &myargs[2]);
+ CKERR(chk_r);
+ }
// make the backward slow scanner
myargs[3].fast = false;
myargs[3].fwd = false;
- { int chk_r = toku_pthread_create(&mytids[3], NULL, scan_db, &myargs[3]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[3], nullptr, scan_db, &myargs[3]);
+ CKERR(chk_r);
+ }
// make the guy that updates the db
- { int chk_r = toku_pthread_create(&mytids[4], NULL, update_db, &myargs[4]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[4], nullptr, update_db, &myargs[4]);
+ CKERR(chk_r);
+ }
// make the guy that does point queries
- { int chk_r = toku_pthread_create(&mytids[5], NULL, ptquery_db, &myargs[5]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[5], nullptr, ptquery_db, &myargs[5]);
+ CKERR(chk_r);
+ }
// make the guy that sleeps
- { int chk_r = toku_pthread_create(&mytids[6], NULL, test_time, NULL); CKERR(chk_r); }
-
- for (uint32_t i = 0; i < sizeof(myargs)/sizeof(myargs[0]); i++) {
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[6], nullptr, test_time, nullptr);
+ CKERR(chk_r);
+ }
+
+ for (uint32_t i = 0; i < sizeof(myargs) / sizeof(myargs[0]); i++) {
void *ret;
r = toku_pthread_join(mytids[i], &ret); assert_zero(r);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/test_4015.cc b/storage/tokudb/PerconaFT/src/tests/test_4015.cc
index dc18242b489..1231e3b4bca 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_4015.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_4015.cc
@@ -151,10 +151,18 @@ int test_main(int argc, char * const argv[]) {
{ int chk_r = db->open(db, NULL, "db", NULL, DB_BTREE, DB_CREATE, 0666); CKERR(chk_r); }
DBT desc;
dbt_init(&desc, "foo", sizeof("foo"));
- IN_TXN_COMMIT(env, NULL, txn, 0,
- { int chk_r = db->change_descriptor(db, txn, &desc, DB_UPDATE_CMP_DESCRIPTOR); CKERR(chk_r); });
+ IN_TXN_COMMIT(env, NULL, txn, 0, {
+ int chk_r =
+ db->change_descriptor(db, txn, &desc, DB_UPDATE_CMP_DESCRIPTOR);
+ CKERR(chk_r);
+ });
pthread_t thd;
- { int chk_r = toku_pthread_create(&thd, NULL, startA, NULL); CKERR(chk_r); }
+ {
+ int chk_r =
+ toku_pthread_create(
+ toku_uninstrumented, &thd, nullptr, startA, nullptr);
+ CKERR(chk_r);
+ }
startB();
diff --git a/storage/tokudb/PerconaFT/src/tests/test_abort1.cc b/storage/tokudb/PerconaFT/src/tests/test_abort1.cc
index 55449610ffb..7b60364878b 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_abort1.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_abort1.cc
@@ -87,10 +87,12 @@ test_db_open_aborts (void) {
CKERR2(r, DB_NOTFOUND);
}
toku_struct_stat statbuf;
- char filename[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(filename, 2, TOKU_TEST_FILENAME, "foo.db"), &statbuf);
- assert(r!=0);
- assert(errno==ENOENT);
+ char filename[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(filename, 2, TOKU_TEST_FILENAME, "foo.db"),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r != 0);
+ assert(errno == ENOENT);
}
r=env->close(env, 0); assert(r==0);
@@ -153,10 +155,12 @@ test_db_put_aborts (void) {
CAST_FROM_VOIDP(filename, iname.data);
assert(filename);
}
- toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename), &statbuf);
- assert(r==0);
+ toku_struct_stat statbuf;
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == 0);
toku_free(filename);
}
// But the item should not be in it.
diff --git a/storage/tokudb/PerconaFT/src/tests/test_abort4.cc b/storage/tokudb/PerconaFT/src/tests/test_abort4.cc
index e67efb465b2..e797fc640d8 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_abort4.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_abort4.cc
@@ -160,10 +160,12 @@ verify_and_tear_down(int close_first) {
CAST_FROM_VOIDP(filename, iname.data);
assert(filename);
}
- toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename), &statbuf);
- assert(r==0);
+ toku_struct_stat statbuf;
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == 0);
toku_free(filename);
}
CKERR(r);
diff --git a/storage/tokudb/PerconaFT/src/tests/test_abort5.cc b/storage/tokudb/PerconaFT/src/tests/test_abort5.cc
index 728afcce1b9..d5d056d5126 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_abort5.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_abort5.cc
@@ -191,10 +191,12 @@ verify_and_tear_down(int close_first) {
CAST_FROM_VOIDP(filename, iname.data);
assert(filename);
}
- toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename), &statbuf);
- assert(r==0);
+ toku_struct_stat statbuf;
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == 0);
toku_free(filename);
}
if (close_first) {
diff --git a/storage/tokudb/PerconaFT/src/tests/test_forkjoin.cc b/storage/tokudb/PerconaFT/src/tests/test_forkjoin.cc
index 910cf46e513..766372a15c2 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_forkjoin.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_forkjoin.cc
@@ -48,12 +48,13 @@ f (void *arg) {
return arg;
}
-int
-test_main(int argc, char *const argv[]) {
+int test_main(int argc, char *const argv[]) {
parse_args(argc, argv);
toku_pthread_t t;
- int r = toku_pthread_create(&t, 0, f, 0); assert(r == 0);
+ int r = toku_pthread_create(toku_uninstrumented, &t, nullptr, f, nullptr);
+ assert(r == 0);
void *ret;
- r = toku_pthread_join(t, &ret); assert(r == 0);
+ r = toku_pthread_join(t, &ret);
+ assert(r == 0);
return 0;
}
diff --git a/storage/tokudb/PerconaFT/src/tests/test_groupcommit_count.cc b/storage/tokudb/PerconaFT/src/tests/test_groupcommit_count.cc
index 414ddd2b70a..35104c2a569 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_groupcommit_count.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_groupcommit_count.cc
@@ -87,12 +87,16 @@ test_groupcommit (int nthreads) {
int i;
toku_pthread_t threads[nthreads];
int whichthread[nthreads];
- for (i=0; i<nthreads; i++) {
- whichthread[i]=i;
- r=toku_pthread_create(&threads[i], 0, start_a_thread, &whichthread[i]);
+ for (i = 0; i < nthreads; i++) {
+ whichthread[i] = i;
+ r = toku_pthread_create(toku_uninstrumented,
+ &threads[i],
+ nullptr,
+ start_a_thread,
+ &whichthread[i]);
}
- for (i=0; i<nthreads; i++) {
- toku_pthread_join(threads[i], 0);
+ for (i = 0; i < nthreads; i++) {
+ toku_pthread_join(threads[i], 0);
}
r=db->close(db, 0); assert(r==0);
diff --git a/storage/tokudb/PerconaFT/src/tests/test_groupcommit_perf.cc b/storage/tokudb/PerconaFT/src/tests/test_groupcommit_perf.cc
index 94eaf2a01a9..6f872d10a32 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_groupcommit_perf.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_groupcommit_perf.cc
@@ -84,12 +84,16 @@ test_groupcommit (int nthreads) {
int i;
toku_pthread_t threads[nthreads];
int whichthread[nthreads];
- for (i=0; i<nthreads; i++) {
- whichthread[i]=i;
- r=toku_pthread_create(&threads[i], 0, start_a_thread, &whichthread[i]);
+ for (i = 0; i < nthreads; i++) {
+ whichthread[i] = i;
+ r = toku_pthread_create(toku_uninstrumented,
+ &threads[i],
+ nullptr,
+ start_a_thread,
+ &whichthread[i]);
}
- for (i=0; i<nthreads; i++) {
- toku_pthread_join(threads[i], 0);
+ for (i = 0; i < nthreads; i++) {
+ toku_pthread_join(threads[i], 0);
}
#if 0
r=env->txn_begin(env, 0, &tid, 0); CKERR(r);
diff --git a/storage/tokudb/PerconaFT/src/tests/test_iterate_pending_lock_requests.cc b/storage/tokudb/PerconaFT/src/tests/test_iterate_pending_lock_requests.cc
index f2bf0a2c756..66471a74af2 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_iterate_pending_lock_requests.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_iterate_pending_lock_requests.cc
@@ -112,12 +112,17 @@ int test_main(int UU(argc), char *const UU(argv[])) {
acquire_lock(txn1, magic_key);
acquire_lock_extra e1(txn2, magic_key);
- r = toku_pthread_create(&thread1, NULL, acquire_lock_thread, &e1); CKERR(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &thread1, nullptr, acquire_lock_thread, &e1);
+ CKERR(r);
acquire_lock_extra e2(txn3, magic_key);
- r = toku_pthread_create(&thread2, NULL, acquire_lock_thread, &e2); CKERR(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &thread2, nullptr, acquire_lock_thread, &e2);
+ CKERR(r);
sleep(1);
- r = env->iterate_pending_lock_requests(env, iterate_callback, NULL); CKERR(r);
+ r = env->iterate_pending_lock_requests(env, iterate_callback, NULL);
+ CKERR(r);
invariant(iterate_callback_called == 2);
void *v;
diff --git a/storage/tokudb/PerconaFT/src/tests/test_lock_timeout_callback.cc b/storage/tokudb/PerconaFT/src/tests/test_lock_timeout_callback.cc
index 75ea49ec858..571bae69916 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_lock_timeout_callback.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_lock_timeout_callback.cc
@@ -118,7 +118,8 @@ int test_main(int UU(argc), char *const UU(argv[])) {
acquire_lock(txn2, magic_key + 1);
toku_pthread_t thread;
acquire_lock_extra e(txn1, magic_key + 1);
- r = toku_pthread_create(&thread, NULL, acquire_lock_thread, &e);
+ r = toku_pthread_create(
+ toku_uninstrumented, &thread, nullptr, acquire_lock_thread, &e);
usleep(100000);
acquire_lock(txn2, magic_key);
invariant(callback_calls == 2);
diff --git a/storage/tokudb/PerconaFT/src/tests/test_log1.cc b/storage/tokudb/PerconaFT/src/tests/test_log1.cc
index 65fa1d830ef..5473a8e3d5e 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_log1.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_log1.cc
@@ -87,10 +87,12 @@ static void make_db (bool close_env) {
r=tid->commit(tid, 0); assert(r==0);
r=db->close(db, 0); assert(r==0);
{
- toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename), &statbuf);
- assert(r==0);
+ toku_struct_stat statbuf;
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == 0);
toku_free(filename);
}
if (close_env) {
diff --git a/storage/tokudb/PerconaFT/src/tests/test_log1_abort.cc b/storage/tokudb/PerconaFT/src/tests/test_log1_abort.cc
index 92c3657a154..c66409fb823 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_log1_abort.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_log1_abort.cc
@@ -80,11 +80,13 @@ test_main (int UU(argc), char UU(*const argv[])) {
r=env->close(env, 0);
assert(r==0);
{
- toku_struct_stat statbuf;
- char filename[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(filename, 2, TOKU_TEST_FILENAME, "foo.db"), &statbuf);
- assert(r==-1);
- assert(errno==ENOENT);
+ toku_struct_stat statbuf;
+ char filename[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(filename, 2, TOKU_TEST_FILENAME, "foo.db"),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == -1);
+ assert(errno == ENOENT);
}
return 0;
}
diff --git a/storage/tokudb/PerconaFT/src/tests/test_logmax.cc b/storage/tokudb/PerconaFT/src/tests/test_logmax.cc
index e5de0a5d906..133eb36ddb5 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_logmax.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_logmax.cc
@@ -50,14 +50,19 @@ check_logmax (int max) {
struct dirent *ent;
while ((ent=readdir(dir))) {
if ((ent->d_type==DT_REG || ent->d_type==DT_UNKNOWN) && strncmp(ent->d_name, "log", 3)==0) {
- // It is a "log*" file
- char full_fname[TOKU_PATH_MAX+1];
- toku_struct_stat sbuf;
- int r = toku_stat(toku_path_join(full_fname, 2, TOKU_TEST_FILENAME, ent->d_name), &sbuf);
- assert(r==0);
- if (verbose)
- printf("%s is of size %" PRId64 "\n", ent->d_name, (int64_t)sbuf.st_size);
- if (sbuf.st_size > max) any_too_big=1;
+ // It is a "log*" file
+ char full_fname[TOKU_PATH_MAX + 1];
+ toku_struct_stat sbuf;
+ int r = toku_stat(
+ toku_path_join(full_fname, 2, TOKU_TEST_FILENAME, ent->d_name),
+ &sbuf,
+ toku_uninstrumented);
+ assert(r == 0);
+ if (verbose)
+ printf("%s is of size %" PRId64 "\n",
+ ent->d_name,
+ (int64_t)sbuf.st_size);
+ if (sbuf.st_size > max) any_too_big=1;
}
}
assert(!any_too_big);
diff --git a/storage/tokudb/PerconaFT/src/tests/test_multiple_checkpoints_block_commit.cc b/storage/tokudb/PerconaFT/src/tests/test_multiple_checkpoints_block_commit.cc
index 66e9f4a5ec8..da53a7bfe11 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_multiple_checkpoints_block_commit.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_multiple_checkpoints_block_commit.cc
@@ -101,10 +101,17 @@ static void run_test(void) {
toku_pthread_t chkpt1_tid;
toku_pthread_t chkpt2_tid;
-
- { int chk_r = toku_pthread_create(&chkpt1_tid, NULL, run_checkpoint, NULL); CKERR(chk_r); }
- { int chk_r = toku_pthread_create(&chkpt2_tid, NULL, run_checkpoint, NULL); CKERR(chk_r); }
- usleep(2*1024*1024);
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &chkpt1_tid, nullptr, run_checkpoint, nullptr);
+ CKERR(chk_r);
+ }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &chkpt2_tid, nullptr, run_checkpoint, nullptr);
+ CKERR(chk_r);
+ }
+ usleep(2 * 1024 * 1024);
struct timeval tstart;
gettimeofday(&tstart, NULL);
DB_TXN *txn = NULL;
diff --git a/storage/tokudb/PerconaFT/src/tests/test_stress_hot_indexing.cc b/storage/tokudb/PerconaFT/src/tests/test_stress_hot_indexing.cc
index e0bf0d2ec6f..6395f591660 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_stress_hot_indexing.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_stress_hot_indexing.cc
@@ -312,12 +312,11 @@ stress_table(DB_ENV *env, DB **dbp, struct cli_args *cli_args) {
run_workers(myargs, num_threads, cli_args->num_seconds, false, cli_args);
}
-int
-test_main(int argc, char *const argv[]) {
+int test_main(int argc, char *const argv[]) {
gid_count = 0;
memset(hi_gid, 0, sizeof(hi_gid));
- toku_mutex_init(&hi_lock, NULL);
- toku_mutex_init(&fops_lock, NULL);
+ toku_mutex_init(toku_uninstrumented, &hi_lock, nullptr);
+ toku_mutex_init(toku_uninstrumented, &fops_lock, nullptr);
hot_db = NULL;
struct cli_args args = get_default_args();
// let's make default checkpointing period really slow
diff --git a/storage/tokudb/PerconaFT/src/tests/test_thread_insert.cc b/storage/tokudb/PerconaFT/src/tests/test_thread_insert.cc
index 0d5245e8f80..a266de638f1 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_thread_insert.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_thread_insert.cc
@@ -150,10 +150,13 @@ test_main(int argc, char *const argv[]) {
work[i].endno = n;
}
- if (verbose) printf("pid:%d\n", toku_os_getpid());
+ if (verbose)
+ printf("pid:%d\n", toku_os_getpid());
- for (i=1; i<nthreads; i++) {
- r = toku_pthread_create(&work[i].tid, 0, do_inserts, &work[i]); assert(r == 0);
+ for (i = 1; i < nthreads; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &work[i].tid, nullptr, do_inserts, &work[i]);
+ assert(r == 0);
}
work[0].do_exit = 0;
diff --git a/storage/tokudb/PerconaFT/src/tests/test_txn_abort7.cc b/storage/tokudb/PerconaFT/src/tests/test_txn_abort7.cc
index fb428f437b1..0a4463644b3 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_txn_abort7.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_txn_abort7.cc
@@ -79,10 +79,12 @@ test_abort_create (void) {
CAST_FROM_VOIDP(filename, iname.data);
assert(filename);
}
- toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename), &statbuf);
- assert(r==0);
+ toku_struct_stat statbuf;
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == 0);
toku_free(filename);
}
@@ -100,10 +102,13 @@ test_abort_create (void) {
CKERR2(r, DB_NOTFOUND);
}
toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, "test.db"), &statbuf);
- assert(r!=0);
- assert(errno==ENOENT);
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(
+ toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, "test.db"),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r != 0);
+ assert(errno == ENOENT);
}
r = env->close(env, 0); assert(r == 0);
diff --git a/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h b/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
index f2bacceed9d..e232f327d10 100644
--- a/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
+++ b/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
@@ -469,11 +469,11 @@ static int get_commit_flags(struct cli_args *args) {
}
struct worker_extra {
- struct arg* thread_arg;
+ struct arg *thread_arg;
toku_mutex_t *operation_lock_mutex;
- struct rwlock *operation_lock;
+ struct st_rwlock *operation_lock;
uint64_t *counters;
- int64_t pad[4]; // pad to 64 bytes
+ int64_t pad[4]; // pad to 64 bytes
};
static void lock_worker_op(struct worker_extra* we) {
@@ -1772,11 +1772,12 @@ static int run_workers(
)
{
int r;
- const struct perf_formatter *perf_formatter = &perf_formatters[cli_args->perf_output_format];
+ const struct perf_formatter *perf_formatter =
+ &perf_formatters[cli_args->perf_output_format];
toku_mutex_t mutex = ZERO_MUTEX_INITIALIZER;
- toku_mutex_init(&mutex, nullptr);
- struct rwlock rwlock;
- rwlock_init(&rwlock);
+ toku_mutex_init(toku_uninstrumented, &mutex, nullptr);
+ struct st_rwlock rwlock;
+ rwlock_init(toku_uninstrumented, &rwlock);
toku_pthread_t tids[num_threads];
toku_pthread_t time_tid;
if (cli_args->print_performance) {
@@ -1798,15 +1799,26 @@ static int run_workers(
worker_extra[i].thread_arg = &thread_args[i];
worker_extra[i].operation_lock = &rwlock;
worker_extra[i].operation_lock_mutex = &mutex;
- XCALLOC_N((int) NUM_OPERATION_TYPES, worker_extra[i].counters);
+ XCALLOC_N((int)NUM_OPERATION_TYPES, worker_extra[i].counters);
TOKU_DRD_IGNORE_VAR(worker_extra[i].counters);
- { int chk_r = toku_pthread_create(&tids[i], nullptr, worker, &worker_extra[i]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(toku_uninstrumented,
+ &tids[i],
+ nullptr,
+ worker,
+ &worker_extra[i]);
+ CKERR(chk_r);
+ }
if (verbose)
- printf("%lu created\n", (unsigned long) tids[i]);
+ printf("%lu created\n", (unsigned long)tids[i]);
+ }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &time_tid, nullptr, test_time, &tte);
+ CKERR(chk_r);
}
- { int chk_r = toku_pthread_create(&time_tid, nullptr, test_time, &tte); CKERR(chk_r); }
if (verbose)
- printf("%lu created\n", (unsigned long) time_tid);
+ printf("%lu created\n", (unsigned long)time_tid);
void *ret;
r = toku_pthread_join(time_tid, &ret); assert_zero(r);
@@ -1817,17 +1829,22 @@ static int run_workers(
// threads (i.e. there is some runaway thread).
struct sleep_and_crash_extra sac_extra;
ZERO_STRUCT(sac_extra);
- toku_mutex_init(&sac_extra.mutex, nullptr);
- toku_cond_init(&sac_extra.cond, nullptr);
+ toku_mutex_init(toku_uninstrumented, &sac_extra.mutex, nullptr);
+ toku_cond_init(toku_uninstrumented, &sac_extra.cond, nullptr);
sac_extra.seconds = cli_args->join_timeout;
sac_extra.is_setup = false;
sac_extra.threads_have_joined = false;
toku_mutex_lock(&sac_extra.mutex);
toku_pthread_t sac_thread;
- r = toku_pthread_create(&sac_thread, nullptr, sleep_and_crash, &sac_extra);
+ r = toku_pthread_create(toku_uninstrumented,
+ &sac_thread,
+ nullptr,
+ sleep_and_crash,
+ &sac_extra);
assert_zero(r);
- // Wait for sleep_and_crash thread to get set up, spinning is ok, this should be quick.
+ // Wait for sleep_and_crash thread to get set up, spinning is ok, this
+ // should be quick.
while (!sac_extra.is_setup) {
toku_mutex_unlock(&sac_extra.mutex);
r = toku_pthread_yield();
diff --git a/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc b/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc
index 30cc16d73a7..469e78f492f 100644
--- a/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc
+++ b/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc
@@ -52,8 +52,8 @@ struct test_sync {
static void test_sync_init(struct test_sync *UU(sync)) {
#if TOKU_DEBUG_TXN_SYNC
sync->state = 0;
- toku_mutex_init(&sync->lock, NULL);
- toku_cond_init(&sync->cv, NULL);
+ toku_mutex_init(toku_uninstrumented, &sync->lock, nullptr);
+ toku_cond_init(toku_uninstrumented, &sync->cv, nullptr);
#endif
}
diff --git a/storage/tokudb/PerconaFT/src/ydb.cc b/storage/tokudb/PerconaFT/src/ydb.cc
index 886832cec6a..9875e9227d4 100644
--- a/storage/tokudb/PerconaFT/src/ydb.cc
+++ b/storage/tokudb/PerconaFT/src/ydb.cc
@@ -228,7 +228,7 @@ env_fs_poller(void *arg) {
int in_red; // set true to prevent certain operations (returning ENOSPC)
// get the fs sizes for the home dir
- uint64_t avail_size, total_size;
+ uint64_t avail_size = 0, total_size = 0;
r = toku_get_filesystem_sizes(env->i->dir, &avail_size, NULL, &total_size);
assert(r == 0);
in_yellow = (avail_size < 2 * env_fs_redzone(env, total_size));
@@ -644,7 +644,7 @@ static int validate_env(DB_ENV *env,
path = toku_construct_full_name(
2, env->i->dir, toku_product_name_strings.environmentdictionary);
assert(path);
- r = toku_stat(path, &buf);
+ r = toku_stat(path, &buf, toku_uninstrumented);
if (r == 0) {
expect_newenv = false; // persistent info exists
} else {
@@ -669,7 +669,7 @@ static int validate_env(DB_ENV *env,
path = toku_construct_full_name(
2, env->i->dir, toku_product_name_strings.rollback_cachefile);
assert(path);
- r = toku_stat(path, &buf);
+ r = toku_stat(path, &buf, toku_uninstrumented);
if (r == 0) {
if (expect_newenv) // rollback cachefile exists, but persistent env
// is missing
@@ -711,7 +711,7 @@ static int validate_env(DB_ENV *env,
path = toku_construct_full_name(
2, env->i->dir, toku_product_name_strings.fileopsdirectory);
assert(path);
- r = toku_stat(path, &buf);
+ r = toku_stat(path, &buf, toku_uninstrumented);
if (r == 0) {
if (expect_newenv) // fileops directory exists, but persistent env
// is missing
@@ -857,10 +857,11 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
// Verify that the home exists.
toku_struct_stat buf;
- r = toku_stat(home, &buf);
+ r = toku_stat(home, &buf, toku_uninstrumented);
if (r != 0) {
int e = get_error_errno();
- r = toku_ydb_do_error(env, e, "Error from toku_stat(\"%s\",...)\n", home);
+ r = toku_ydb_do_error(
+ env, e, "Error from toku_stat(\"%s\",...)\n", home);
goto cleanup;
}
unused_flags &= ~DB_PRIVATE;
@@ -876,13 +877,22 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
env->i->open_flags = flags;
env->i->open_mode = mode;
+ // Instrumentation probe start
+ TOKU_PROBE_START(toku_instr_probe_1);
+
env_setup_real_data_dir(env);
env_setup_real_log_dir(env);
env_setup_real_tmp_dir(env);
- r = toku_single_process_lock(env->i->dir, "environment", &env->i->envdir_lockfd);
- if (r!=0) goto cleanup;
- r = toku_single_process_lock(env->i->real_data_dir, "data", &env->i->datadir_lockfd);
+ // Instrumentation probe stop
+ toku_instr_probe_1->stop();
+
+ r = toku_single_process_lock(
+ env->i->dir, "environment", &env->i->envdir_lockfd);
+ if (r != 0)
+ goto cleanup;
+ r = toku_single_process_lock(
+ env->i->real_data_dir, "data", &env->i->datadir_lockfd);
if (r!=0) goto cleanup;
r = toku_single_process_lock(env->i->real_log_dir, "logs", &env->i->logdir_lockfd);
if (r!=0) goto cleanup;
@@ -2932,7 +2942,8 @@ toku_env_create(DB_ENV ** envp, uint32_t flags) {
result->i->open_dbs_by_dname->create();
XMALLOC(result->i->open_dbs_by_dict_id);
result->i->open_dbs_by_dict_id->create();
- toku_pthread_rwlock_init(&result->i->open_dbs_rwlock, NULL);
+ toku_pthread_rwlock_init(
+ *result_i_open_dbs_rwlock_key, &result->i->open_dbs_rwlock, nullptr);
*envp = result;
r = 0;
diff --git a/storage/tokudb/PerconaFT/src/ydb_db.cc b/storage/tokudb/PerconaFT/src/ydb_db.cc
index 29d21ad0452..6b4452325f4 100644
--- a/storage/tokudb/PerconaFT/src/ydb_db.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_db.cc
@@ -84,53 +84,56 @@ ydb_db_layer_get_status(YDB_DB_LAYER_STATUS statp) {
*statp = ydb_db_layer_status;
}
-void create_iname_hint(const char *dname, char *hint) {
+void create_iname_hint(DB_ENV *env, const char *dname, char *hint) {
//Requires: size of hint array must be > strlen(dname)
//Copy alphanumeric characters only.
//Replace strings of non-alphanumeric characters with a single underscore.
- bool underscored = false;
- while (*dname) {
- if (isalnum(*dname)) {
- char c = *dname++;
- *hint++ = c;
- underscored = false;
- }
- else {
- if (!underscored)
- *hint++ = '_';
- dname++;
- underscored = true;
+ if (env->get_dir_per_db(env) && !toku_os_is_absolute_name(dname)) {
+ assert(dname);
+ if (*dname == '.')
+ ++dname;
+ if (*dname == '/')
+ ++dname;
+ bool underscored = false;
+ bool dbdir_is_parsed = false;
+ // Do not change the first '/' because this is
+ // delimiter which splits name into database dir
+ // and table dir.
+ while (*dname) {
+ if (isalnum(*dname) || (*dname == '/' && !dbdir_is_parsed)) {
+ char c = *dname++;
+ *hint++ = c;
+ if (c == '/')
+ dbdir_is_parsed = true;
+ underscored = false;
+ } else if (!dbdir_is_parsed) {
+ char c = *dname++;
+ *hint++ = c;
+ } else {
+ if (!underscored)
+ *hint++ = '_';
+ dname++;
+ underscored = true;
+ }
}
- }
- *hint = '\0';
-}
-
-void create_iname_hint_for_dbdir(const char *dname, char *hint) {
- assert(dname);
- if (*dname == '.')
- ++dname;
- if (*dname == '/')
- ++dname;
- bool underscored = false;
- bool dbdir_is_parsed = false;
- // Do not change the first '/' because this is
- // delimiter which splits name into database dir
- // and table dir.
- while (*dname) {
- if (isalnum(*dname) || (*dname == '/' && !dbdir_is_parsed)) {
- char c = *dname++;
- *hint++ = c;
- if (c == '/')
- dbdir_is_parsed = true;
- underscored = false;
- } else {
- if (!underscored)
- *hint++ = '_';
- dname++;
- underscored = true;
+ *hint = '\0';
+ } else {
+ bool underscored = false;
+ while (*dname) {
+ if (isalnum(*dname)) {
+ char c = *dname++;
+ *hint++ = c;
+ underscored = false;
+ }
+ else {
+ if (!underscored)
+ *hint++ = '_';
+ dname++;
+ underscored = true;
+ }
}
+ *hint = '\0';
}
- *hint = '\0';
}
// n < 0 means to ignore mark and ignore n
@@ -188,10 +191,7 @@ std::unique_ptr<char[], decltype(&toku_free)> generate_iname_for_rename_or_open(
} else if (is_open)
id1 = toku_sync_fetch_and_add(&nontransactional_open_id, 1);
- if (env->get_dir_per_db(env) && !toku_os_is_absolute_name(dname))
- create_iname_hint_for_dbdir(dname, hint);
- else
- create_iname_hint(dname, hint);
+ create_iname_hint(env, dname, hint);
result.reset(create_iname(env, id1, id2, hint, NULL, -1));
@@ -1222,15 +1222,18 @@ load_inames(DB_ENV * env, DB_TXN * txn, int N, DB * dbs[/*N*/], const char * new
for (i = 0; i < N; i++) {
char * dname = dbs[i]->i->dname;
toku_fill_dbt(&dname_dbt, dname, strlen(dname)+1);
+
// now create new iname
char hint[strlen(dname) + 1];
- if (env->get_dir_per_db(env) && !toku_os_is_absolute_name(dname))
- create_iname_hint_for_dbdir(dname, hint);
- else
- create_iname_hint(dname, hint);
- const char *new_iname = create_iname(env, xid.parent_id64, xid.child_id64, hint, mark, i); // allocates memory for iname_in_env
+ create_iname_hint(env, dname, hint);
+
+ // allocates memory for iname_in_env
+ const char *new_iname =
+ create_iname(env, xid.parent_id64, xid.child_id64, hint, mark, i);
new_inames_in_env[i] = new_iname;
- toku_fill_dbt(&iname_dbt, new_iname, strlen(new_iname) + 1); // iname_in_env goes in directory
+
+ // iname_in_env goes in directory
+ toku_fill_dbt(&iname_dbt, new_iname, strlen(new_iname) + 1);
rval = toku_db_put(env->i->directory, txn, &dname_dbt, &iname_dbt, 0, true);
if (rval) break;
}
diff --git a/storage/tokudb/PerconaFT/src/ydb_db.h b/storage/tokudb/PerconaFT/src/ydb_db.h
index 8be28857c14..ab8fcd2a401 100644
--- a/storage/tokudb/PerconaFT/src/ydb_db.h
+++ b/storage/tokudb/PerconaFT/src/ydb_db.h
@@ -122,8 +122,7 @@ toku_db_destruct_autotxn(DB_TXN *txn, int r, bool changed) {
return r;
}
-void create_iname_hint_for_dbdir(const char *dname, char *hint);
-void create_iname_hint(const char *dname, char *hint);
+void create_iname_hint(DB_ENV *env, const char *dname, char *hint);
char *create_iname(DB_ENV *env,
uint64_t id1,
uint64_t id2,
diff --git a/storage/tokudb/PerconaFT/src/ydb_env_func.cc b/storage/tokudb/PerconaFT/src/ydb_env_func.cc
index cd5388106ac..aa8f9063a7e 100644
--- a/storage/tokudb/PerconaFT/src/ydb_env_func.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_env_func.cc
@@ -110,7 +110,7 @@ void db_env_set_func_pread (ssize_t (*fun)(int, void *, size_t, off_t)) {
}
void db_env_set_func_loader_fwrite (size_t (*fwrite_fun)(const void*,size_t,size_t,FILE*)) {
- ft_loader_set_os_fwrite(fwrite_fun);
+ toku_set_func_fwrite(fwrite_fun);
}
void db_env_set_func_malloc (void *(*f)(size_t)) {
diff --git a/storage/tokudb/PerconaFT/src/ydb_txn.cc b/storage/tokudb/PerconaFT/src/ydb_txn.cc
index 40b479055f2..dd5fb3b8f0c 100644
--- a/storage/tokudb/PerconaFT/src/ydb_txn.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_txn.cc
@@ -540,10 +540,12 @@ int toku_txn_begin(DB_ENV *env, DB_TXN * stxn, DB_TXN ** txn, uint32_t flags) {
db_txn_struct_i(result)->iso = child_isolation;
db_txn_struct_i(result)->lt_map.create_no_array();
- toku_mutex_init(&db_txn_struct_i(result)->txn_mutex, NULL);
+ toku_mutex_init(*db_txn_struct_i_txn_mutex_key,
+ &db_txn_struct_i(result)->txn_mutex,
+ nullptr);
TXN_SNAPSHOT_TYPE snapshot_type;
- switch(db_txn_struct_i(result)->iso){
+ switch (db_txn_struct_i(result)->iso) {
case(TOKU_ISO_SNAPSHOT):
{
snapshot_type = TXN_SNAPSHOT_ROOT;
@@ -603,7 +605,9 @@ void toku_keep_prepared_txn_callback (DB_ENV *env, TOKUTXN tokutxn) {
toku_txn_set_container_db_txn(tokutxn, result);
- toku_mutex_init(&db_txn_struct_i(result)->txn_mutex, NULL);
+ toku_mutex_init(*db_txn_struct_i_txn_mutex_key,
+ &db_txn_struct_i(result)->txn_mutex,
+ nullptr);
}
// Test-only function
diff --git a/storage/tokudb/PerconaFT/tools/CMakeLists.txt b/storage/tokudb/PerconaFT/tools/CMakeLists.txt
index e8aed51f813..dd54249ab40 100644
--- a/storage/tokudb/PerconaFT/tools/CMakeLists.txt
+++ b/storage/tokudb/PerconaFT/tools/CMakeLists.txt
@@ -12,6 +12,7 @@ foreach(tool ${tools})
(CMAKE_CXX_FLAGS_DEBUG MATCHES " -DENABLED_DEBUG_SYNC"))
target_link_libraries(${tool} sql)
endif()
+ target_link_libraries(${tool} mysys)
endif ()
add_space_separated_property(TARGET ${tool} COMPILE_FLAGS -fvisibility=hidden)
diff --git a/storage/tokudb/PerconaFT/util/dbt.cc b/storage/tokudb/PerconaFT/util/dbt.cc
index 5bc1cb7446f..b6d2a584a45 100644
--- a/storage/tokudb/PerconaFT/util/dbt.cc
+++ b/storage/tokudb/PerconaFT/util/dbt.cc
@@ -199,7 +199,8 @@ int toku_dbt_set(uint32_t len, const void *val, DBT *d, struct simple_dbt *sdbt)
case (DB_DBT_MALLOC):
d->data = NULL;
d->ulen = 0;
- //Fall through to DB_DBT_REALLOC
+ // fallthrough
+ // to DB_DBT_REALLOC
case (DB_DBT_REALLOC):
if (d->ulen < len) {
d->ulen = len*2;
diff --git a/storage/tokudb/PerconaFT/util/fmutex.h b/storage/tokudb/PerconaFT/util/fmutex.h
index 9ff95978a16..fed1bc24a92 100644
--- a/storage/tokudb/PerconaFT/util/fmutex.h
+++ b/storage/tokudb/PerconaFT/util/fmutex.h
@@ -38,6 +38,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#pragma once
+extern toku_instr_key *fmutex_cond_key;
+
// fair mutex
struct fmutex {
pthread_mutex_t mutex;
@@ -98,8 +100,8 @@ void fmutex_lock(struct fmutex *fm) {
}
pthread_cond_t cond;
- pthread_cond_init(&cond, NULL);
- struct queue_item item = { .cond = &cond, .next = NULL };
+ pthread_cond_init(*fmutex_cond_key, &cond, nullptr);
+ struct queue_item item = {.cond = &cond, .next = NULL};
enq_item(fm, &item);
// Wait for our turn.
diff --git a/storage/tokudb/PerconaFT/util/frwlock.cc b/storage/tokudb/PerconaFT/util/frwlock.cc
index ce1e33e85d3..1f821fe5f54 100644
--- a/storage/tokudb/PerconaFT/util/frwlock.cc
+++ b/storage/tokudb/PerconaFT/util/frwlock.cc
@@ -41,271 +41,311 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <util/context.h>
#include <util/frwlock.h>
+toku_instr_key *frwlock_m_wait_read_key;
+
namespace toku {
-static __thread int thread_local_tid = -1;
-static int get_local_tid() {
- if (thread_local_tid == -1) {
- thread_local_tid = toku_os_gettid();
- }
- return thread_local_tid;
-}
-
-void frwlock::init(toku_mutex_t *const mutex) {
- m_mutex = mutex;
-
- m_num_readers = 0;
- m_num_writers = 0;
- m_num_want_write = 0;
- m_num_want_read = 0;
- m_num_signaled_readers = 0;
- m_num_expensive_want_write = 0;
-
- toku_cond_init(&m_wait_read, nullptr);
- m_queue_item_read.cond = &m_wait_read;
- m_queue_item_read.next = nullptr;
- m_wait_read_is_in_queue = false;
- m_current_writer_expensive = false;
- m_read_wait_expensive = false;
- m_current_writer_tid = -1;
- m_blocking_writer_context_id = CTX_INVALID;
-
- m_wait_head = nullptr;
- m_wait_tail = nullptr;
-}
-
-void frwlock::deinit(void) {
- toku_cond_destroy(&m_wait_read);
-}
-
-bool frwlock::queue_is_empty(void) const {
- return m_wait_head == nullptr;
-}
-
-void frwlock::enq_item(queue_item *const item) {
- paranoid_invariant_null(item->next);
- if (m_wait_tail != nullptr) {
- m_wait_tail->next = item;
- } else {
- paranoid_invariant_null(m_wait_head);
- m_wait_head = item;
+ static __thread int thread_local_tid = -1;
+ static int get_local_tid() {
+ if (thread_local_tid == -1) {
+ thread_local_tid = toku_os_gettid();
+ }
+ return thread_local_tid;
}
- m_wait_tail = item;
-}
-
-toku_cond_t *frwlock::deq_item(void) {
- paranoid_invariant_notnull(m_wait_head);
- paranoid_invariant_notnull(m_wait_tail);
- queue_item *item = m_wait_head;
- m_wait_head = m_wait_head->next;
- if (m_wait_tail == item) {
+
+ void frwlock::init(toku_mutex_t *const mutex
+#if defined(TOKU_MYSQL_WITH_PFS)
+ ,
+ const toku_instr_key &rwlock_instr_key
+#endif
+ ) {
+ m_mutex = mutex;
+
+ m_num_readers = 0;
+ m_num_writers = 0;
+ m_num_want_write = 0;
+ m_num_want_read = 0;
+ m_num_signaled_readers = 0;
+ m_num_expensive_want_write = 0;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_init(rwlock_instr_key, &m_rwlock, nullptr);
+#endif
+ toku_cond_init(toku_uninstrumented, &m_wait_read, nullptr);
+ m_queue_item_read.cond = &m_wait_read;
+ m_queue_item_read.next = nullptr;
+ m_wait_read_is_in_queue = false;
+ m_current_writer_expensive = false;
+ m_read_wait_expensive = false;
+ m_current_writer_tid = -1;
+ m_blocking_writer_context_id = CTX_INVALID;
+
+ m_wait_head = nullptr;
m_wait_tail = nullptr;
}
- return item->cond;
-}
-
-// Prerequisite: Holds m_mutex.
-void frwlock::write_lock(bool expensive) {
- toku_mutex_assert_locked(m_mutex);
- if (this->try_write_lock(expensive)) {
- return;
+
+ void frwlock::deinit(void) {
+ toku_cond_destroy(&m_wait_read);
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_destroy(&m_rwlock);
+#endif
}
- toku_cond_t cond = TOKU_COND_INITIALIZER;
- queue_item item = { .cond = &cond, .next = nullptr };
- this->enq_item(&item);
+ bool frwlock::queue_is_empty(void) const { return m_wait_head == nullptr; }
- // Wait for our turn.
- ++m_num_want_write;
- if (expensive) {
- ++m_num_expensive_want_write;
- }
- if (m_num_writers == 0 && m_num_want_write == 1) {
- // We are the first to want a write lock. No new readers can get the lock.
- // Set our thread id and context for proper instrumentation.
- // see: toku_context_note_frwlock_contention()
- m_current_writer_tid = get_local_tid();
- m_blocking_writer_context_id = toku_thread_get_context()->get_id();
- }
- toku_cond_wait(&cond, m_mutex);
- toku_cond_destroy(&cond);
-
- // Now it's our turn.
- paranoid_invariant(m_num_want_write > 0);
- paranoid_invariant_zero(m_num_readers);
- paranoid_invariant_zero(m_num_writers);
- paranoid_invariant_zero(m_num_signaled_readers);
-
- // Not waiting anymore; grab the lock.
- --m_num_want_write;
- if (expensive) {
- --m_num_expensive_want_write;
+ void frwlock::enq_item(queue_item *const item) {
+ paranoid_invariant_null(item->next);
+ if (m_wait_tail != nullptr) {
+ m_wait_tail->next = item;
+ } else {
+ paranoid_invariant_null(m_wait_head);
+ m_wait_head = item;
+ }
+ m_wait_tail = item;
}
- m_num_writers = 1;
- m_current_writer_expensive = expensive;
- m_current_writer_tid = get_local_tid();
- m_blocking_writer_context_id = toku_thread_get_context()->get_id();
-}
-
-bool frwlock::try_write_lock(bool expensive) {
- toku_mutex_assert_locked(m_mutex);
- if (m_num_readers > 0 || m_num_writers > 0 || m_num_signaled_readers > 0 || m_num_want_write > 0) {
- return false;
+
+ toku_cond_t *frwlock::deq_item(void) {
+ paranoid_invariant_notnull(m_wait_head);
+ paranoid_invariant_notnull(m_wait_tail);
+ queue_item *item = m_wait_head;
+ m_wait_head = m_wait_head->next;
+ if (m_wait_tail == item) {
+ m_wait_tail = nullptr;
+ }
+ return item->cond;
}
- // No one holds the lock. Grant the write lock.
- paranoid_invariant_zero(m_num_want_write);
- paranoid_invariant_zero(m_num_want_read);
- m_num_writers = 1;
- m_current_writer_expensive = expensive;
- m_current_writer_tid = get_local_tid();
- m_blocking_writer_context_id = toku_thread_get_context()->get_id();
- return true;
-}
-
-void frwlock::read_lock(void) {
- toku_mutex_assert_locked(m_mutex);
- if (m_num_writers > 0 || m_num_want_write > 0) {
- if (!m_wait_read_is_in_queue) {
- // Throw the read cond_t onto the queue.
- paranoid_invariant(m_num_signaled_readers == m_num_want_read);
- m_queue_item_read.next = nullptr;
- this->enq_item(&m_queue_item_read);
- m_wait_read_is_in_queue = true;
- paranoid_invariant(!m_read_wait_expensive);
- m_read_wait_expensive = (
- m_current_writer_expensive ||
- (m_num_expensive_want_write > 0)
- );
+
+ // Prerequisite: Holds m_mutex.
+ void frwlock::write_lock(bool expensive) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ toku_instr_rwlock_wrlock_wait_start(
+ rwlock_instr, m_rwlock, __FILE__, __LINE__);
+#endif
+
+ toku_mutex_assert_locked(m_mutex);
+ if (this->try_write_lock(expensive)) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation end */
+ toku_instr_rwlock_wrlock_wait_end(rwlock_instr, 0);
+#endif
+ return;
}
- // Note this contention event in engine status.
- toku_context_note_frwlock_contention(
- toku_thread_get_context()->get_id(),
- m_blocking_writer_context_id
- );
+ toku_cond_t cond = TOKU_COND_INITIALIZER;
+ queue_item item = {.cond = &cond, .next = nullptr};
+ this->enq_item(&item);
// Wait for our turn.
- ++m_num_want_read;
- toku_cond_wait(&m_wait_read, m_mutex);
+ ++m_num_want_write;
+ if (expensive) {
+ ++m_num_expensive_want_write;
+ }
+ if (m_num_writers == 0 && m_num_want_write == 1) {
+ // We are the first to want a write lock. No new readers can get the
+ // lock.
+ // Set our thread id and context for proper instrumentation.
+ // see: toku_context_note_frwlock_contention()
+ m_current_writer_tid = get_local_tid();
+ m_blocking_writer_context_id = toku_thread_get_context()->get_id();
+ }
+ toku_cond_wait(&cond, m_mutex);
+ toku_cond_destroy(&cond);
// Now it's our turn.
+ paranoid_invariant(m_num_want_write > 0);
+ paranoid_invariant_zero(m_num_readers);
paranoid_invariant_zero(m_num_writers);
- paranoid_invariant(m_num_want_read > 0);
- paranoid_invariant(m_num_signaled_readers > 0);
+ paranoid_invariant_zero(m_num_signaled_readers);
// Not waiting anymore; grab the lock.
- --m_num_want_read;
- --m_num_signaled_readers;
+ --m_num_want_write;
+ if (expensive) {
+ --m_num_expensive_want_write;
+ }
+ m_num_writers = 1;
+ m_current_writer_expensive = expensive;
+ m_current_writer_tid = get_local_tid();
+ m_blocking_writer_context_id = toku_thread_get_context()->get_id();
+
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation end */
+ toku_instr_rwlock_wrlock_wait_end(rwlock_instr, 0);
+#endif
+ }
+
+ bool frwlock::try_write_lock(bool expensive) {
+ toku_mutex_assert_locked(m_mutex);
+ if (m_num_readers > 0 || m_num_writers > 0 ||
+ m_num_signaled_readers > 0 || m_num_want_write > 0) {
+ return false;
+ }
+ // No one holds the lock. Grant the write lock.
+ paranoid_invariant_zero(m_num_want_write);
+ paranoid_invariant_zero(m_num_want_read);
+ m_num_writers = 1;
+ m_current_writer_expensive = expensive;
+ m_current_writer_tid = get_local_tid();
+ m_blocking_writer_context_id = toku_thread_get_context()->get_id();
+ return true;
}
- ++m_num_readers;
-}
-bool frwlock::try_read_lock(void) {
- toku_mutex_assert_locked(m_mutex);
- if (m_num_writers > 0 || m_num_want_write > 0) {
- return false;
+ void frwlock::read_lock(void) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ toku_instr_rwlock_rdlock_wait_start(
+ rwlock_instr, m_rwlock, __FILE__, __LINE__);
+#endif
+ toku_mutex_assert_locked(m_mutex);
+ if (m_num_writers > 0 || m_num_want_write > 0) {
+ if (!m_wait_read_is_in_queue) {
+ // Throw the read cond_t onto the queue.
+ paranoid_invariant(m_num_signaled_readers == m_num_want_read);
+ m_queue_item_read.next = nullptr;
+ this->enq_item(&m_queue_item_read);
+ m_wait_read_is_in_queue = true;
+ paranoid_invariant(!m_read_wait_expensive);
+ m_read_wait_expensive = (m_current_writer_expensive ||
+ (m_num_expensive_want_write > 0));
+ }
+
+ // Note this contention event in engine status.
+ toku_context_note_frwlock_contention(
+ toku_thread_get_context()->get_id(),
+ m_blocking_writer_context_id);
+
+ // Wait for our turn.
+ ++m_num_want_read;
+ toku_cond_wait(&m_wait_read, m_mutex);
+
+ // Now it's our turn.
+ paranoid_invariant_zero(m_num_writers);
+ paranoid_invariant(m_num_want_read > 0);
+ paranoid_invariant(m_num_signaled_readers > 0);
+
+ // Not waiting anymore; grab the lock.
+ --m_num_want_read;
+ --m_num_signaled_readers;
+ }
+ ++m_num_readers;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation end */
+ toku_instr_rwlock_rdlock_wait_end(rwlock_instr, 0);
+#endif
}
- // No writer holds the lock.
- // No writers are waiting.
- // Grant the read lock.
- ++m_num_readers;
- return true;
-}
-
-void frwlock::maybe_signal_next_writer(void) {
- if (m_num_want_write > 0 && m_num_signaled_readers == 0 && m_num_readers == 0) {
- toku_cond_t *cond = this->deq_item();
- paranoid_invariant(cond != &m_wait_read);
- // Grant write lock to waiting writer.
- paranoid_invariant(m_num_want_write > 0);
- toku_cond_signal(cond);
+
+ bool frwlock::try_read_lock(void) {
+ toku_mutex_assert_locked(m_mutex);
+ if (m_num_writers > 0 || m_num_want_write > 0) {
+ return false;
+ }
+ // No writer holds the lock.
+ // No writers are waiting.
+ // Grant the read lock.
+ ++m_num_readers;
+ return true;
}
-}
-
-void frwlock::read_unlock(void) {
- toku_mutex_assert_locked(m_mutex);
- paranoid_invariant(m_num_writers == 0);
- paranoid_invariant(m_num_readers > 0);
- --m_num_readers;
- this->maybe_signal_next_writer();
-}
-
-bool frwlock::read_lock_is_expensive(void) {
- toku_mutex_assert_locked(m_mutex);
- if (m_wait_read_is_in_queue) {
- return m_read_wait_expensive;
+
+ void frwlock::maybe_signal_next_writer(void) {
+ if (m_num_want_write > 0 && m_num_signaled_readers == 0 &&
+ m_num_readers == 0) {
+ toku_cond_t *cond = this->deq_item();
+ paranoid_invariant(cond != &m_wait_read);
+ // Grant write lock to waiting writer.
+ paranoid_invariant(m_num_want_write > 0);
+ toku_cond_signal(cond);
+ }
+ }
+
+ void frwlock::read_unlock(void) {
+#ifdef TOKU_MYSQL_WITH_PFS
+ toku_instr_rwlock_unlock(m_rwlock);
+#endif
+ toku_mutex_assert_locked(m_mutex);
+ paranoid_invariant(m_num_writers == 0);
+ paranoid_invariant(m_num_readers > 0);
+ --m_num_readers;
+ this->maybe_signal_next_writer();
}
- else {
- return m_current_writer_expensive || (m_num_expensive_want_write > 0);
+
+ bool frwlock::read_lock_is_expensive(void) {
+ toku_mutex_assert_locked(m_mutex);
+ if (m_wait_read_is_in_queue) {
+ return m_read_wait_expensive;
+ } else {
+ return m_current_writer_expensive ||
+ (m_num_expensive_want_write > 0);
+ }
}
-}
+ void frwlock::maybe_signal_or_broadcast_next(void) {
+ paranoid_invariant(m_num_signaled_readers == 0);
-void frwlock::maybe_signal_or_broadcast_next(void) {
- paranoid_invariant(m_num_signaled_readers == 0);
+ if (this->queue_is_empty()) {
+ paranoid_invariant(m_num_want_write == 0);
+ paranoid_invariant(m_num_want_read == 0);
+ return;
+ }
+ toku_cond_t *cond = this->deq_item();
+ if (cond == &m_wait_read) {
+ // Grant read locks to all waiting readers
+ paranoid_invariant(m_wait_read_is_in_queue);
+ paranoid_invariant(m_num_want_read > 0);
+ m_num_signaled_readers = m_num_want_read;
+ m_wait_read_is_in_queue = false;
+ m_read_wait_expensive = false;
+ toku_cond_broadcast(cond);
+ } else {
+ // Grant write lock to waiting writer.
+ paranoid_invariant(m_num_want_write > 0);
+ toku_cond_signal(cond);
+ }
+ }
- if (this->queue_is_empty()) {
- paranoid_invariant(m_num_want_write == 0);
- paranoid_invariant(m_num_want_read == 0);
- return;
+ void frwlock::write_unlock(void) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_instr_rwlock_unlock(m_rwlock);
+#endif
+ toku_mutex_assert_locked(m_mutex);
+ paranoid_invariant(m_num_writers == 1);
+ m_num_writers = 0;
+ m_current_writer_expensive = false;
+ m_current_writer_tid = -1;
+ m_blocking_writer_context_id = CTX_INVALID;
+ this->maybe_signal_or_broadcast_next();
}
- toku_cond_t *cond = this->deq_item();
- if (cond == &m_wait_read) {
- // Grant read locks to all waiting readers
- paranoid_invariant(m_wait_read_is_in_queue);
- paranoid_invariant(m_num_want_read > 0);
- m_num_signaled_readers = m_num_want_read;
- m_wait_read_is_in_queue = false;
- m_read_wait_expensive = false;
- toku_cond_broadcast(cond);
+ bool frwlock::write_lock_is_expensive(void) {
+ toku_mutex_assert_locked(m_mutex);
+ return (m_num_expensive_want_write > 0) || (m_current_writer_expensive);
}
- else {
- // Grant write lock to waiting writer.
- paranoid_invariant(m_num_want_write > 0);
- toku_cond_signal(cond);
+
+ uint32_t frwlock::users(void) const {
+ toku_mutex_assert_locked(m_mutex);
+ return m_num_readers + m_num_writers + m_num_want_read +
+ m_num_want_write;
+ }
+ uint32_t frwlock::blocked_users(void) const {
+ toku_mutex_assert_locked(m_mutex);
+ return m_num_want_read + m_num_want_write;
+ }
+ uint32_t frwlock::writers(void) const {
+ // this is sometimes called as "assert(lock->writers())" when we
+ // assume we have the write lock. if that's the assumption, we may
+ // not own the mutex, so we don't assert_locked here
+ return m_num_writers;
+ }
+ uint32_t frwlock::blocked_writers(void) const {
+ toku_mutex_assert_locked(m_mutex);
+ return m_num_want_write;
+ }
+ uint32_t frwlock::readers(void) const {
+ toku_mutex_assert_locked(m_mutex);
+ return m_num_readers;
+ }
+ uint32_t frwlock::blocked_readers(void) const {
+ toku_mutex_assert_locked(m_mutex);
+ return m_num_want_read;
}
-}
-
-void frwlock::write_unlock(void) {
- toku_mutex_assert_locked(m_mutex);
- paranoid_invariant(m_num_writers == 1);
- m_num_writers = 0;
- m_current_writer_expensive = false;
- m_current_writer_tid = -1;
- m_blocking_writer_context_id = CTX_INVALID;
- this->maybe_signal_or_broadcast_next();
-}
-bool frwlock::write_lock_is_expensive(void) {
- toku_mutex_assert_locked(m_mutex);
- return (m_num_expensive_want_write > 0) || (m_current_writer_expensive);
-}
-
-
-uint32_t frwlock::users(void) const {
- toku_mutex_assert_locked(m_mutex);
- return m_num_readers + m_num_writers + m_num_want_read + m_num_want_write;
-}
-uint32_t frwlock::blocked_users(void) const {
- toku_mutex_assert_locked(m_mutex);
- return m_num_want_read + m_num_want_write;
-}
-uint32_t frwlock::writers(void) const {
- // this is sometimes called as "assert(lock->writers())" when we
- // assume we have the write lock. if that's the assumption, we may
- // not own the mutex, so we don't assert_locked here
- return m_num_writers;
-}
-uint32_t frwlock::blocked_writers(void) const {
- toku_mutex_assert_locked(m_mutex);
- return m_num_want_write;
-}
-uint32_t frwlock::readers(void) const {
- toku_mutex_assert_locked(m_mutex);
- return m_num_readers;
-}
-uint32_t frwlock::blocked_readers(void) const {
- toku_mutex_assert_locked(m_mutex);
- return m_num_want_read;
-}
} // namespace toku
diff --git a/storage/tokudb/PerconaFT/util/frwlock.h b/storage/tokudb/PerconaFT/util/frwlock.h
index 52b98a8d727..b02d95e545c 100644
--- a/storage/tokudb/PerconaFT/util/frwlock.h
+++ b/storage/tokudb/PerconaFT/util/frwlock.h
@@ -48,76 +48,82 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
namespace toku {
-class frwlock {
-public:
-
- void init(toku_mutex_t *const mutex);
- void deinit(void);
-
- void write_lock(bool expensive);
- bool try_write_lock(bool expensive);
- void write_unlock(void);
- // returns true if acquiring a write lock will be expensive
- bool write_lock_is_expensive(void);
-
- void read_lock(void);
- bool try_read_lock(void);
- void read_unlock(void);
- // returns true if acquiring a read lock will be expensive
- bool read_lock_is_expensive(void);
-
- uint32_t users(void) const;
- uint32_t blocked_users(void) const;
- uint32_t writers(void) const;
- uint32_t blocked_writers(void) const;
- uint32_t readers(void) const;
- uint32_t blocked_readers(void) const;
-
-private:
- struct queue_item {
- toku_cond_t *cond;
- struct queue_item *next;
+ class frwlock {
+ public:
+ void init(toku_mutex_t *const mutex
+#if defined(TOKU_MYSQL_WITH_PFS)
+ ,
+ const toku_instr_key &rwlock_instr_key
+#endif
+ );
+ void deinit(void);
+
+ void write_lock(bool expensive);
+ bool try_write_lock(bool expensive);
+ void write_unlock(void);
+ // returns true if acquiring a write lock will be expensive
+ bool write_lock_is_expensive(void);
+
+ void read_lock(void);
+ bool try_read_lock(void);
+ void read_unlock(void);
+ // returns true if acquiring a read lock will be expensive
+ bool read_lock_is_expensive(void);
+
+ uint32_t users(void) const;
+ uint32_t blocked_users(void) const;
+ uint32_t writers(void) const;
+ uint32_t blocked_writers(void) const;
+ uint32_t readers(void) const;
+ uint32_t blocked_readers(void) const;
+
+ private:
+ struct queue_item {
+ toku_cond_t *cond;
+ struct queue_item *next;
+ };
+
+ bool queue_is_empty(void) const;
+ void enq_item(queue_item *const item);
+ toku_cond_t *deq_item(void);
+ void maybe_signal_or_broadcast_next(void);
+ void maybe_signal_next_writer(void);
+
+ toku_mutex_t *m_mutex;
+
+ uint32_t m_num_readers;
+ uint32_t m_num_writers;
+ uint32_t m_num_want_write;
+ uint32_t m_num_want_read;
+ uint32_t m_num_signaled_readers;
+ // number of writers waiting that are expensive
+ // MUST be < m_num_want_write
+ uint32_t m_num_expensive_want_write;
+ // bool that states if the current writer is expensive
+ // if there is no current writer, then is false
+ bool m_current_writer_expensive;
+ // bool that states if waiting for a read
+ // is expensive
+ // if there are currently no waiting readers, then set to false
+ bool m_read_wait_expensive;
+ // thread-id of the current writer
+ int m_current_writer_tid;
+ // context id describing the context of the current writer blocking
+ // new readers (either because this writer holds the write lock or
+ // is the first to want the write lock).
+ context_id m_blocking_writer_context_id;
+ queue_item m_queue_item_read;
+ bool m_wait_read_is_in_queue;
+
+ toku_cond_t m_wait_read;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_t m_rwlock;
+#endif
+ queue_item *m_wait_head;
+ queue_item *m_wait_tail;
};
- bool queue_is_empty(void) const;
- void enq_item(queue_item *const item);
- toku_cond_t *deq_item(void);
- void maybe_signal_or_broadcast_next(void);
- void maybe_signal_next_writer(void);
-
- toku_mutex_t *m_mutex;
-
- uint32_t m_num_readers;
- uint32_t m_num_writers;
- uint32_t m_num_want_write;
- uint32_t m_num_want_read;
- uint32_t m_num_signaled_readers;
- // number of writers waiting that are expensive
- // MUST be < m_num_want_write
- uint32_t m_num_expensive_want_write;
- // bool that states if the current writer is expensive
- // if there is no current writer, then is false
- bool m_current_writer_expensive;
- // bool that states if waiting for a read
- // is expensive
- // if there are currently no waiting readers, then set to false
- bool m_read_wait_expensive;
- // thread-id of the current writer
- int m_current_writer_tid;
- // context id describing the context of the current writer blocking
- // new readers (either because this writer holds the write lock or
- // is the first to want the write lock).
- context_id m_blocking_writer_context_id;
-
- toku_cond_t m_wait_read;
- queue_item m_queue_item_read;
- bool m_wait_read_is_in_queue;
-
- queue_item *m_wait_head;
- queue_item *m_wait_tail;
-};
-
-ENSURE_POD(frwlock);
+ ENSURE_POD(frwlock);
} // namespace toku
diff --git a/storage/tokudb/PerconaFT/util/kibbutz.cc b/storage/tokudb/PerconaFT/util/kibbutz.cc
index 7fc24bae727..409bf6bdd7b 100644
--- a/storage/tokudb/PerconaFT/util/kibbutz.cc
+++ b/storage/tokudb/PerconaFT/util/kibbutz.cc
@@ -72,14 +72,18 @@ struct kibbutz {
uint64_t total_execution_time;
};
-static void *work_on_kibbutz (void *);
+static void *work_on_kibbutz(void *);
-int toku_kibbutz_create (int n_workers, KIBBUTZ *kb_ret) {
+toku_instr_key *kibbutz_mutex_key;
+toku_instr_key *kibbutz_k_cond_key;
+toku_instr_key *kibbutz_thread_key;
+
+int toku_kibbutz_create(int n_workers, KIBBUTZ *kb_ret) {
int r = 0;
*kb_ret = NULL;
KIBBUTZ XCALLOC(k);
- toku_mutex_init(&k->mutex, NULL);
- toku_cond_init(&k->cond, NULL);
+ toku_mutex_init(*kibbutz_mutex_key, &k->mutex, nullptr);
+ toku_cond_init(*kibbutz_k_cond_key, &k->cond, nullptr);
k->please_shutdown = false;
k->head = NULL;
k->tail = NULL;
@@ -93,7 +97,11 @@ int toku_kibbutz_create (int n_workers, KIBBUTZ *kb_ret) {
XMALLOC_N(n_workers, k->ids);
for (int i = 0; i < n_workers; i++) {
k->ids[i].k = k;
- r = toku_pthread_create(&k->workers[i], NULL, work_on_kibbutz, &k->ids[i]);
+ r = toku_pthread_create(*kibbutz_thread_key,
+ &k->workers[i],
+ nullptr,
+ work_on_kibbutz,
+ &k->ids[i]);
if (r != 0) {
k->n_workers = i;
toku_kibbutz_destroy(k);
@@ -153,10 +161,14 @@ static void *work_on_kibbutz (void *kidv) {
// if there's another item on k->head, then we'll just go grab it now, without waiting for a signal.
}
if (k->please_shutdown) {
- // Don't follow this unless the work is all done, so that when we set please_shutdown, all the work finishes before any threads quit.
- ksignal(k); // must wake up anyone else who is waiting, so they can shut down.
+ // Don't follow this unless the work is all done, so that when we
+ // set please_shutdown, all the work finishes before any threads
+ // quit.
+ ksignal(k); // must wake up anyone else who is waiting, so they can
+ // shut down.
kunlock(k);
- return NULL;
+ toku_instr_delete_current_thread();
+ return nullptr;
}
// There is no work to do and it's not time to shutdown, so wait.
kwait(k);
diff --git a/storage/tokudb/PerconaFT/util/minicron.cc b/storage/tokudb/PerconaFT/util/minicron.cc
index 737c6ef6a4f..c1412015be0 100644
--- a/storage/tokudb/PerconaFT/util/minicron.cc
+++ b/storage/tokudb/PerconaFT/util/minicron.cc
@@ -43,8 +43,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "portability/toku_assert.h"
#include "util/minicron.h"
-static void
-toku_gettime (toku_timespec_t *a) {
+toku_instr_key *minicron_p_mutex_key;
+toku_instr_key *minicron_p_condvar_key;
+toku_instr_key *minicron_thread_key;
+
+static void toku_gettime(toku_timespec_t *a) {
struct timeval tv;
gettimeofday(&tv, 0);
a->tv_sec = tv.tv_sec;
@@ -74,7 +77,8 @@ minicron_do (void *pv)
while (1) {
if (p->do_shutdown) {
toku_mutex_unlock(&p->mutex);
- return 0;
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
}
if (p->period_in_ms == 0) {
// if we aren't supposed to do it then just do an untimed wait.
@@ -104,7 +108,8 @@ minicron_do (void *pv)
// Now we woke up, and we should figure out what to do
if (p->do_shutdown) {
toku_mutex_unlock(&p->mutex);
- return 0;
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
}
if (p->period_in_ms > 1000) {
toku_timespec_t now;
@@ -137,17 +142,17 @@ toku_minicron_setup(struct minicron *p, uint32_t period_in_ms, int(*f)(void *),
p->f = f;
p->arg = arg;
toku_gettime(&p->time_of_last_call_to_f);
- //printf("now=%.6f", p->time_of_last_call_to_f.tv_sec + p->time_of_last_call_to_f.tv_nsec*1e-9);
- p->period_in_ms = period_in_ms;
+ // printf("now=%.6f", p->time_of_last_call_to_f.tv_sec +
+ // p->time_of_last_call_to_f.tv_nsec*1e-9);
+ p->period_in_ms = period_in_ms;
p->do_shutdown = false;
- toku_mutex_init(&p->mutex, 0);
- toku_cond_init (&p->condvar, 0);
- return toku_pthread_create(&p->thread, 0, minicron_do, p);
+ toku_mutex_init(*minicron_p_mutex_key, &p->mutex, nullptr);
+ toku_cond_init(*minicron_p_condvar_key, &p->condvar, nullptr);
+ return toku_pthread_create(
+ *minicron_thread_key, &p->thread, nullptr, minicron_do, p);
}
-
-void
-toku_minicron_change_period(struct minicron *p, uint32_t new_period)
-{
+
+void toku_minicron_change_period(struct minicron *p, uint32_t new_period) {
toku_mutex_lock(&p->mutex);
p->period_in_ms = new_period;
toku_cond_signal(&p->condvar);
diff --git a/storage/tokudb/PerconaFT/util/nb_mutex.h b/storage/tokudb/PerconaFT/util/nb_mutex.h
index 3490c1b365c..d777961ad78 100644
--- a/storage/tokudb/PerconaFT/util/nb_mutex.h
+++ b/storage/tokudb/PerconaFT/util/nb_mutex.h
@@ -49,35 +49,67 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
// increase parallelism at the expense of single thread performance, we
// are experimenting with a single higher level lock.
+extern toku_instr_key *nb_mutex_key;
+
typedef struct nb_mutex *NB_MUTEX;
struct nb_mutex {
- struct rwlock lock;
+ struct st_rwlock lock;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_mutex_t toku_mutex;
+#endif
};
+#if defined(TOKU_MYSQL_WITH_PFS)
+#define nb_mutex_init(MK, RK, M) \
+ inline_nb_mutex_init(MK, RK, M)
+#else
+#define nb_mutex_init(MK, RK, M) inline_nb_mutex_init(M)
+#endif
+
// initialize an nb mutex
-static __attribute__((__unused__))
-void
-nb_mutex_init(NB_MUTEX nb_mutex) {
- rwlock_init(&nb_mutex->lock);
+inline void inline_nb_mutex_init(
+#if defined(TOKU_MYSQL_WITH_PFS)
+ const toku_instr_key &mutex_instr_key,
+ const toku_instr_key &rwlock_instr_key,
+#endif
+ NB_MUTEX nb_mutex) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_mutex_init(mutex_instr_key, &nb_mutex->toku_mutex, nullptr);
+#endif
+ rwlock_init(rwlock_instr_key, &nb_mutex->lock);
}
// destroy a read write lock
-static __attribute__((__unused__))
-void
-nb_mutex_destroy(NB_MUTEX nb_mutex) {
+inline void nb_mutex_destroy(NB_MUTEX nb_mutex) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_instr_mutex_destroy(nb_mutex->toku_mutex.psi_mutex);
+#endif
rwlock_destroy(&nb_mutex->lock);
}
// obtain a write lock
// expects: mutex is locked
-static inline void nb_mutex_lock(NB_MUTEX nb_mutex, toku_mutex_t *mutex) {
+inline void nb_mutex_lock(NB_MUTEX nb_mutex, toku_mutex_t *mutex) {
+#ifdef TOKU_MYSQL_WITH_PFS
+ toku_mutex_instrumentation mutex_instr;
+ toku_instr_mutex_lock_start(mutex_instr,
+ *mutex,
+ __FILE__,
+ __LINE__); // TODO: pull these to caller?
+#endif
rwlock_write_lock(&nb_mutex->lock, mutex);
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_instr_mutex_lock_end(mutex_instr, 0);
+#endif
}
// release a write lock
// expects: mutex is locked
-static inline void nb_mutex_unlock(NB_MUTEX nb_mutex) {
+inline void nb_mutex_unlock(NB_MUTEX nb_mutex) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_instr_mutex_unlock(nb_mutex->toku_mutex.psi_mutex);
+#endif
rwlock_write_unlock(&nb_mutex->lock);
}
diff --git a/storage/tokudb/PerconaFT/util/queue.cc b/storage/tokudb/PerconaFT/util/queue.cc
index 0716dfb2f59..39dfbbc699a 100644
--- a/storage/tokudb/PerconaFT/util/queue.cc
+++ b/storage/tokudb/PerconaFT/util/queue.cc
@@ -44,6 +44,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "memory.h"
#include <toku_pthread.h>
+toku_instr_key *queue_result_mutex_key;
+toku_instr_key *queue_result_cond_key;
+
struct qitem;
struct qitem {
@@ -81,11 +84,11 @@ int toku_queue_create (QUEUE *q, uint64_t weight_limit)
if (result==NULL) return get_error_errno();
result->contents_weight = 0;
result->weight_limit = weight_limit;
- result->head = NULL;
- result->tail = NULL;
- result->eof = false;
- toku_mutex_init(&result->mutex, NULL);
- toku_cond_init(&result->cond, NULL);
+ result->head = NULL;
+ result->tail = NULL;
+ result->eof = false;
+ toku_mutex_init(*queue_result_mutex_key, &result->mutex, nullptr);
+ toku_cond_init(*queue_result_cond_key, &result->cond, nullptr);
*q = result;
return 0;
}
diff --git a/storage/tokudb/PerconaFT/util/rwlock.h b/storage/tokudb/PerconaFT/util/rwlock.h
index 47f78df70d1..d9a13ba9014 100644
--- a/storage/tokudb/PerconaFT/util/rwlock.h
+++ b/storage/tokudb/PerconaFT/util/rwlock.h
@@ -39,6 +39,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#pragma once
#include <toku_assert.h>
+#include <toku_portability.h>
+#include <toku_instrumentation.h>
/* Readers/writers locks implementation
*
@@ -147,53 +149,81 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
// increase parallelism at the expense of single thread performance, we
// are experimenting with a single higher level lock.
-typedef struct rwlock *RWLOCK;
-struct rwlock {
- int reader; // the number of readers
- int want_read; // the number of blocked readers
+extern toku_instr_key *rwlock_cond_key;
+extern toku_instr_key *rwlock_wait_read_key;
+extern toku_instr_key *rwlock_wait_write_key;
+
+typedef struct st_rwlock *RWLOCK;
+struct st_rwlock {
+ int reader; // the number of readers
+ int want_read; // the number of blocked readers
toku_cond_t wait_read;
int writer; // the number of writers
int want_write; // the number of blocked writers
toku_cond_t wait_write;
- toku_cond_t* wait_users_go_to_zero;
+ toku_cond_t *wait_users_go_to_zero;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_t prwlock;
+#endif
};
// returns: the sum of the number of readers, pending readers, writers, and
// pending writers
static inline int rwlock_users(RWLOCK rwlock) {
- return rwlock->reader + rwlock->want_read + rwlock->writer + rwlock->want_write;
+ return rwlock->reader + rwlock->want_read + rwlock->writer +
+ rwlock->want_write;
}
-// initialize a read write lock
+#if defined(TOKU_MYSQL_WITH_PFS)
+#define rwlock_init(K, R) inline_rwlock_init(K, R)
+#else
+#define rwlock_init(K, R) inline_rwlock_init(R)
+#endif
-static __attribute__((__unused__))
-void
-rwlock_init(RWLOCK rwlock) {
+// initialize a read write lock
+static inline __attribute__((__unused__)) void inline_rwlock_init(
+#if defined(TOKU_MYSQL_WITH_PFS)
+ const toku_instr_key &rwlock_instr_key,
+#endif
+ RWLOCK rwlock) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_init(rwlock_instr_key, &rwlock->prwlock, nullptr);
+#endif
rwlock->reader = rwlock->want_read = 0;
- toku_cond_init(&rwlock->wait_read, 0);
rwlock->writer = rwlock->want_write = 0;
- toku_cond_init(&rwlock->wait_write, 0);
+ toku_cond_init(toku_uninstrumented, &rwlock->wait_read, nullptr);
+ toku_cond_init(toku_uninstrumented, &rwlock->wait_write, nullptr);
rwlock->wait_users_go_to_zero = NULL;
}
// destroy a read write lock
-static __attribute__((__unused__))
-void
-rwlock_destroy(RWLOCK rwlock) {
+static inline __attribute__((__unused__)) void rwlock_destroy(RWLOCK rwlock) {
paranoid_invariant(rwlock->reader == 0);
paranoid_invariant(rwlock->want_read == 0);
paranoid_invariant(rwlock->writer == 0);
paranoid_invariant(rwlock->want_write == 0);
toku_cond_destroy(&rwlock->wait_read);
toku_cond_destroy(&rwlock->wait_write);
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_destroy(&rwlock->prwlock);
+#endif
}
// obtain a read lock
// expects: mutex is locked
static inline void rwlock_read_lock(RWLOCK rwlock, toku_mutex_t *mutex) {
+#ifdef TOKU_MYSQL_WITH_PFS
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ // TODO: pull location information up to caller
+ toku_instr_rwlock_rdlock_wait_start(
+ rwlock_instr, rwlock->prwlock, __FILE__, __LINE__);
+
+#endif
+
paranoid_invariant(!rwlock->wait_users_go_to_zero);
if (rwlock->writer || rwlock->want_write) {
rwlock->want_read++;
@@ -203,12 +233,19 @@ static inline void rwlock_read_lock(RWLOCK rwlock, toku_mutex_t *mutex) {
rwlock->want_read--;
}
rwlock->reader++;
+#ifdef TOKU_MYSQL_WITH_PFS
+ /* Instrumentation end */
+ toku_instr_rwlock_wrlock_wait_end(rwlock_instr, 0);
+#endif
}
// release a read lock
// expects: mutex is locked
static inline void rwlock_read_unlock(RWLOCK rwlock) {
+#ifdef TOKU_MYSQL_WITH_PFS
+ toku_instr_rwlock_unlock(rwlock->prwlock);
+#endif
paranoid_invariant(rwlock->reader > 0);
paranoid_invariant(rwlock->writer == 0);
rwlock->reader--;
@@ -224,6 +261,12 @@ static inline void rwlock_read_unlock(RWLOCK rwlock) {
// expects: mutex is locked
static inline void rwlock_write_lock(RWLOCK rwlock, toku_mutex_t *mutex) {
+#ifdef TOKU_MYSQL_WITH_PFS
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ toku_instr_rwlock_wrlock_wait_start(
+ rwlock_instr, rwlock->prwlock, __FILE__, __LINE__);
+#endif
paranoid_invariant(!rwlock->wait_users_go_to_zero);
if (rwlock->reader || rwlock->writer) {
rwlock->want_write++;
@@ -233,12 +276,19 @@ static inline void rwlock_write_lock(RWLOCK rwlock, toku_mutex_t *mutex) {
rwlock->want_write--;
}
rwlock->writer++;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation end */
+ toku_instr_rwlock_wrlock_wait_end(rwlock_instr, 0);
+#endif
}
// release a write lock
// expects: mutex is locked
static inline void rwlock_write_unlock(RWLOCK rwlock) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_instr_rwlock_unlock(rwlock->prwlock);
+#endif
paranoid_invariant(rwlock->reader == 0);
paranoid_invariant(rwlock->writer == 1);
rwlock->writer--;
@@ -284,14 +334,10 @@ static inline int rwlock_read_will_block(RWLOCK rwlock) {
return (rwlock->writer > 0 || rwlock->want_write > 0);
}
-static inline void rwlock_wait_for_users(
- RWLOCK rwlock,
- toku_mutex_t *mutex
- )
-{
+static inline void rwlock_wait_for_users(RWLOCK rwlock, toku_mutex_t *mutex) {
paranoid_invariant(!rwlock->wait_users_go_to_zero);
toku_cond_t cond;
- toku_cond_init(&cond, NULL);
+ toku_cond_init(toku_uninstrumented, &cond, nullptr);
while (rwlock_users(rwlock) > 0) {
rwlock->wait_users_go_to_zero = &cond;
toku_cond_wait(&cond, mutex);
diff --git a/storage/tokudb/PerconaFT/util/tests/marked-omt-test.cc b/storage/tokudb/PerconaFT/util/tests/marked-omt-test.cc
index bce1b1a885b..7e60c711c66 100644
--- a/storage/tokudb/PerconaFT/util/tests/marked-omt-test.cc
+++ b/storage/tokudb/PerconaFT/util/tests/marked-omt-test.cc
@@ -156,7 +156,7 @@ int int_heaviside(const uint32_t &v, const uint32_t &target) {
struct stress_shared {
stress_omt *omt;
volatile bool running;
- struct rwlock lock;
+ struct st_rwlock lock;
toku_mutex_t mutex;
int num_marker_threads;
};
@@ -400,8 +400,8 @@ static void stress_test(int nelts) {
struct stress_shared extra;
ZERO_STRUCT(extra);
extra.omt = &omt;
- toku_mutex_init(&extra.mutex, NULL);
- rwlock_init(&extra.lock);
+ toku_mutex_init(toku_uninstrumented, &extra.mutex, nullptr);
+ rwlock_init(toku_uninstrumented, &extra.lock);
extra.running = true;
extra.num_marker_threads = num_marker_threads;
@@ -422,11 +422,19 @@ static void stress_test(int nelts) {
r = myinitstate_r(seed, reader.buf_write, 8, &reader.rand_write);
invariant_zero(r);
- toku_pthread_create(&marker_threads[i], NULL, stress_mark_worker, &reader);
+ toku_pthread_create(toku_uninstrumented,
+ &marker_threads[i],
+ nullptr,
+ stress_mark_worker,
+ &reader);
}
toku_pthread_t deleter_thread;
- toku_pthread_create(&deleter_thread, NULL, stress_delete_worker, &readers[0]);
+ toku_pthread_create(toku_uninstrumented,
+ &deleter_thread,
+ nullptr,
+ stress_delete_worker,
+ &readers[0]);
toku_pthread_join(deleter_thread, NULL);
for (int i = 0; i < num_marker_threads; ++i) {
diff --git a/storage/tokudb/PerconaFT/util/tests/minicron-test.cc b/storage/tokudb/PerconaFT/util/tests/minicron-test.cc
index a2ddbdeabdf..026ab7446d3 100644
--- a/storage/tokudb/PerconaFT/util/tests/minicron-test.cc
+++ b/storage/tokudb/PerconaFT/util/tests/minicron-test.cc
@@ -206,11 +206,12 @@ test_main (int argc, const char *argv[]) {
toku_pthread_t tests[N];
unsigned int i;
- for (i=0; i<N; i++) {
- int r=toku_pthread_create(tests+i, 0, testfuns[i], 0);
- assert(r==0);
+ for (i = 0; i < N; i++) {
+ int r = toku_pthread_create(
+ toku_uninstrumented, tests + i, nullptr, testfuns[i], nullptr);
+ assert(r == 0);
}
- for (i=0; i<N; i++) {
+ for (i = 0; i < N; i++) {
void *v;
int r=toku_pthread_join(tests[i], &v);
assert(r==0);
diff --git a/storage/tokudb/PerconaFT/util/tests/queue-test.cc b/storage/tokudb/PerconaFT/util/tests/queue-test.cc
index 433a0aca32a..f87e05bc664 100644
--- a/storage/tokudb/PerconaFT/util/tests/queue-test.cc
+++ b/storage/tokudb/PerconaFT/util/tests/queue-test.cc
@@ -87,9 +87,11 @@ static void queue_test_0 (uint64_t weight)
d_max_weight = 0;
QUEUE q;
int r;
- r = toku_queue_create(&q, weight); assert(r==0);
+ r = toku_queue_create(&q, weight);
+ assert(r == 0);
toku_pthread_t thread;
- r = toku_pthread_create(&thread, NULL, start_0, q); assert(r==0);
+ r = toku_pthread_create(toku_uninstrumented, &thread, nullptr, start_0, q);
+ assert(r == 0);
enq(q, 0L, weight);
enq(q, 1L, weight);
enq(q, 2L, weight);
diff --git a/storage/tokudb/PerconaFT/util/tests/rwlock_condvar.h b/storage/tokudb/PerconaFT/util/tests/rwlock_condvar.h
index 816b98af81c..b49c2780ff8 100644
--- a/storage/tokudb/PerconaFT/util/tests/rwlock_condvar.h
+++ b/storage/tokudb/PerconaFT/util/tests/rwlock_condvar.h
@@ -67,13 +67,13 @@ struct toku_cv_fair_rwlock_waiter_state {
static __thread struct toku_cv_fair_rwlock_waiter_state waitstate = {0, NULL, {PTHREAD_COND_INITIALIZER} };
void toku_cv_fair_rwlock_init (toku_cv_fair_rwlock_t *rwlock) {
- rwlock->state=0;
+ rwlock->state = 0;
rwlock->waiters_head = NULL;
rwlock->waiters_tail = NULL;
- toku_mutex_init(&rwlock->mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &rwlock->mutex, nullptr);
}
-void toku_cv_fair_rwlock_destroy (toku_cv_fair_rwlock_t *rwlock) {
+void toku_cv_fair_rwlock_destroy(toku_cv_fair_rwlock_t *rwlock) {
toku_mutex_destroy(&rwlock->mutex);
}
diff --git a/storage/tokudb/PerconaFT/util/tests/sm-basic.cc b/storage/tokudb/PerconaFT/util/tests/sm-basic.cc
index 80bc965fd31..0e5eb8364e2 100644
--- a/storage/tokudb/PerconaFT/util/tests/sm-basic.cc
+++ b/storage/tokudb/PerconaFT/util/tests/sm-basic.cc
@@ -64,7 +64,8 @@ int main(void) {
// run the test
toku_pthread_t tid;
int r;
- r = toku_pthread_create(&tid, NULL, sm_test_f, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, sm_test_f, nullptr);
assert_zero(r);
void *ret;
r = toku_pthread_join(tid, &ret);
diff --git a/storage/tokudb/PerconaFT/util/tests/sm-crash-double-free.cc b/storage/tokudb/PerconaFT/util/tests/sm-crash-double-free.cc
index c5d7e3e53a7..5aa3565510b 100644
--- a/storage/tokudb/PerconaFT/util/tests/sm-crash-double-free.cc
+++ b/storage/tokudb/PerconaFT/util/tests/sm-crash-double-free.cc
@@ -64,10 +64,12 @@ int main(void) {
toku_scoped_malloc_init();
toku_pthread_t tid;
int r;
- r = toku_pthread_create(&tid, NULL, sm_test_f, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, sm_test_f, nullptr);
assert_zero(r);
void *ret;
- while (state != 1) sleep(1);
+ while (state != 1)
+ sleep(1);
toku_scoped_malloc_destroy_set();
state = 2;
r = toku_pthread_join(tid, &ret);
diff --git a/storage/tokudb/PerconaFT/util/tests/test-frwlock-fair-writers.cc b/storage/tokudb/PerconaFT/util/tests/test-frwlock-fair-writers.cc
index 7fd4801fe11..9a625c32aeb 100644
--- a/storage/tokudb/PerconaFT/util/tests/test-frwlock-fair-writers.cc
+++ b/storage/tokudb/PerconaFT/util/tests/test-frwlock-fair-writers.cc
@@ -66,9 +66,9 @@ static void *t1_func(void *arg) {
int main(void) {
int r;
- toku_mutex_init(&rwlock_mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &rwlock_mutex, nullptr);
rwlock.init(&rwlock_mutex);
-
+
const int nthreads = 2;
pthread_t tids[nthreads];
for (int i = 0; i < nthreads; i++) {
diff --git a/storage/tokudb/PerconaFT/util/tests/test-rwlock-cheapness.cc b/storage/tokudb/PerconaFT/util/tests/test-rwlock-cheapness.cc
index 0075ddf9bcb..c0b43c2db1c 100644
--- a/storage/tokudb/PerconaFT/util/tests/test-rwlock-cheapness.cc
+++ b/storage/tokudb/PerconaFT/util/tests/test-rwlock-cheapness.cc
@@ -101,7 +101,8 @@ static void *do_read_wait(void *arg) {
static void launch_cheap_waiter(void) {
toku_pthread_t tid;
- int r = toku_pthread_create(&tid, NULL, do_cheap_wait, NULL);
+ int r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, do_cheap_wait, nullptr);
assert_zero(r);
toku_pthread_detach(tid);
sleep(1);
@@ -109,7 +110,8 @@ static void launch_cheap_waiter(void) {
static void launch_expensive_waiter(void) {
toku_pthread_t tid;
- int r = toku_pthread_create(&tid, NULL, do_expensive_wait, NULL);
+ int r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, do_expensive_wait, nullptr);
assert_zero(r);
toku_pthread_detach(tid);
sleep(1);
@@ -117,7 +119,8 @@ static void launch_expensive_waiter(void) {
static void launch_reader(void) {
toku_pthread_t tid;
- int r = toku_pthread_create(&tid, NULL, do_read_wait, NULL);
+ int r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, do_read_wait, nullptr);
assert_zero(r);
toku_pthread_detach(tid);
sleep(1);
@@ -132,7 +135,7 @@ static bool locks_are_expensive(void) {
}
static void test_write_cheapness(void) {
- toku_mutex_init(&mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &mutex, nullptr);
w.init(&mutex);
// single expensive write lock
diff --git a/storage/tokudb/PerconaFT/util/tests/test-rwlock.cc b/storage/tokudb/PerconaFT/util/tests/test-rwlock.cc
index 18ca1229f56..56dd3f6b480 100644
--- a/storage/tokudb/PerconaFT/util/tests/test-rwlock.cc
+++ b/storage/tokudb/PerconaFT/util/tests/test-rwlock.cc
@@ -245,14 +245,14 @@ static void util_rwlock_unlock (RWLOCK rwlock, toku_mutex_t *mutex) {
}
// Time the read lock that's in util/rwlock.h
-void time_util_rwlock (void) __attribute((__noinline__));
-void time_util_rwlock (void) {
- struct rwlock rwlock;
+void time_util_rwlock(void) __attribute((__noinline__));
+void time_util_rwlock(void) {
+ struct st_rwlock rwlock;
toku_mutex_t external_mutex;
- toku_mutex_init(&external_mutex, NULL);
- rwlock_init(&rwlock);
- struct timeval start,end;
-
+ toku_mutex_init(toku_uninstrumented, &external_mutex, nullptr);
+ rwlock_init(toku_uninstrumented, &rwlock);
+ struct timeval start, end;
+
util_rwlock_lock(&rwlock, &external_mutex);
util_rwlock_unlock(&rwlock, &external_mutex);
for (int t=0; t<T; t++) {
@@ -271,16 +271,17 @@ void time_util_rwlock (void) {
toku_mutex_destroy(&external_mutex);
}
-// Time the read lock that's in util/rwlock.h, assuming the mutex is already held.
-void time_util_prelocked_rwlock (void) __attribute__((__noinline__));
-void time_util_prelocked_rwlock (void) {
- struct rwlock rwlock;
+// Time the read lock that's in util/rwlock.h, assuming the mutex is already
+// held.
+void time_util_prelocked_rwlock(void) __attribute__((__noinline__));
+void time_util_prelocked_rwlock(void) {
+ struct st_rwlock rwlock;
toku_mutex_t external_mutex;
- toku_mutex_init(&external_mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &external_mutex, nullptr);
toku_mutex_lock(&external_mutex);
- rwlock_init(&rwlock);
- struct timeval start,end;
-
+ rwlock_init(toku_uninstrumented, &rwlock);
+ struct timeval start, end;
+
rwlock_read_lock(&rwlock, &external_mutex);
rwlock_read_unlock(&rwlock);
for (int t=0; t<T; t++) {
@@ -303,8 +304,8 @@ void time_util_prelocked_rwlock (void) {
void time_frwlock_prelocked(void) __attribute__((__noinline__));
void time_frwlock_prelocked(void) {
toku_mutex_t external_mutex;
- toku_mutex_init(&external_mutex, NULL);
- struct timeval start,end;
+ toku_mutex_init(toku_uninstrumented, &external_mutex, nullptr);
+ struct timeval start, end;
toku::frwlock x;
x.init(&external_mutex);
toku_mutex_lock(&external_mutex);
@@ -340,8 +341,8 @@ void time_frwlock_prelocked(void) {
void time_frwlock(void) __attribute__((__noinline__));
void time_frwlock(void) {
toku_mutex_t external_mutex;
- toku_mutex_init(&external_mutex, NULL);
- struct timeval start,end;
+ toku_mutex_init(toku_uninstrumented, &external_mutex, nullptr);
+ struct timeval start, end;
toku::frwlock x;
x.init(&external_mutex);
toku_mutex_lock(&external_mutex);
diff --git a/storage/tokudb/PerconaFT/util/tests/threadpool-test.cc b/storage/tokudb/PerconaFT/util/tests/threadpool-test.cc
index 3379507270d..83c142edc2d 100644
--- a/storage/tokudb/PerconaFT/util/tests/threadpool-test.cc
+++ b/storage/tokudb/PerconaFT/util/tests/threadpool-test.cc
@@ -67,10 +67,11 @@ struct my_threadpool {
static void
my_threadpool_init (struct my_threadpool *my_threadpool, int max_threads) {
int r;
- r = toku_thread_pool_create(&my_threadpool->threadpool, max_threads); assert(r == 0);
+ r = toku_thread_pool_create(&my_threadpool->threadpool, max_threads);
+ assert(r == 0);
assert(my_threadpool != 0);
- toku_mutex_init(&my_threadpool->mutex, 0);
- toku_cond_init(&my_threadpool->wait, 0);
+ toku_mutex_init(toku_uninstrumented, &my_threadpool->mutex, nullptr);
+ toku_cond_init(toku_uninstrumented, &my_threadpool->wait, nullptr);
my_threadpool->closed = 0;
my_threadpool->counter = 0;
}
diff --git a/storage/tokudb/PerconaFT/util/threadpool.cc b/storage/tokudb/PerconaFT/util/threadpool.cc
index 146cc63242a..6e0ccf05f93 100644
--- a/storage/tokudb/PerconaFT/util/threadpool.cc
+++ b/storage/tokudb/PerconaFT/util/threadpool.cc
@@ -48,6 +48,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "threadpool.h"
+toku_instr_key *tpool_lock_mutex_key;
+toku_instr_key *tp_thread_wait_key;
+toku_instr_key *tp_pool_wait_free_key;
+toku_instr_key *tp_internal_thread_key;
+
struct toku_thread {
struct toku_thread_pool *pool;
toku_pthread_t tid;
@@ -84,8 +89,12 @@ toku_thread_create(struct toku_thread_pool *pool, struct toku_thread **toku_thre
} else {
memset(thread, 0, sizeof *thread);
thread->pool = pool;
- toku_cond_init(&thread->wait, nullptr);
- r = toku_pthread_create(&thread->tid, nullptr, toku_thread_run_internal, thread);
+ toku_cond_init(*tp_thread_wait_key, &thread->wait, nullptr);
+ r = toku_pthread_create(*tp_internal_thread_key,
+ &thread->tid,
+ nullptr,
+ toku_thread_run_internal,
+ thread);
if (r) {
toku_cond_destroy(&thread->wait);
toku_free(thread);
@@ -105,11 +114,11 @@ toku_thread_run(struct toku_thread *thread, void *(*f)(void *arg), void *arg) {
toku_thread_pool_unlock(thread->pool);
}
-static void
-toku_thread_destroy(struct toku_thread *thread) {
+static void toku_thread_destroy(struct toku_thread *thread) {
int r;
void *ret;
- r = toku_pthread_join(thread->tid, &ret); invariant(r == 0 && ret == thread);
+ r = toku_pthread_join(thread->tid, &ret);
+ invariant(r == 0 && ret == thread);
struct toku_thread_pool *pool = thread->pool;
toku_thread_pool_lock(pool);
toku_list_remove(&thread->free_link);
@@ -147,20 +156,20 @@ toku_thread_run_internal(void *arg) {
thread->f = nullptr;
toku_list_push(&pool->free_threads, &thread->free_link);
}
- return arg;
-}
+ return toku_pthread_done(arg);
+}
-int
-toku_thread_pool_create(struct toku_thread_pool **pool_return, int max_threads) {
+int toku_thread_pool_create(struct toku_thread_pool **pool_return,
+ int max_threads) {
int r;
struct toku_thread_pool *CALLOC(pool);
if (pool == nullptr) {
r = get_error_errno();
} else {
- toku_mutex_init(&pool->lock, nullptr);
+ toku_mutex_init(*tpool_lock_mutex_key, &pool->lock, nullptr);
toku_list_init(&pool->free_threads);
toku_list_init(&pool->all_threads);
- toku_cond_init(&pool->wait_free, nullptr);
+ toku_cond_init(*tp_pool_wait_free_key, &pool->wait_free, nullptr);
pool->cur_threads = 0;
pool->max_threads = max_threads;
*pool_return = pool;
diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc
index 4bd00722623..ebf4b5a22d3 100644
--- a/storage/tokudb/ha_tokudb.cc
+++ b/storage/tokudb/ha_tokudb.cc
@@ -31,6 +31,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "ha_tokudb.h"
#include "sql_db.h"
+pfs_key_t ha_tokudb_mutex_key;
+pfs_key_t num_DBs_lock_key;
#if TOKU_INCLUDE_EXTENDED_KEYS
static inline uint get_ext_key_parts(const KEY *key) {
@@ -187,13 +189,9 @@ const char* TOKUDB_SHARE::get_state_string(share_state_t state) {
void* TOKUDB_SHARE::operator new(size_t sz) {
return tokudb::memory::malloc(sz, MYF(MY_WME|MY_ZEROFILL|MY_FAE));
}
-void TOKUDB_SHARE::operator delete(void* p) {
- tokudb::memory::free(p);
-}
-TOKUDB_SHARE::TOKUDB_SHARE() :
- _num_DBs_lock(),
- _mutex() {
-}
+void TOKUDB_SHARE::operator delete(void* p) { tokudb::memory::free(p); }
+TOKUDB_SHARE::TOKUDB_SHARE()
+ : _num_DBs_lock(num_DBs_lock_key), _mutex(ha_tokudb_mutex_key) {}
void TOKUDB_SHARE::init(const char* table_name) {
_use_count = 0;
thr_lock_init(&_thr_lock);
@@ -228,20 +226,15 @@ void TOKUDB_SHARE::destroy() {
thr_lock_delete(&_thr_lock);
TOKUDB_SHARE_DBUG_VOID_RETURN();
}
-TOKUDB_SHARE* TOKUDB_SHARE::get_share(
- const char* table_name,
- TABLE_SHARE* table_share,
- THR_LOCK_DATA* data,
- bool create_new) {
-
- _open_tables_mutex.lock();
+TOKUDB_SHARE* TOKUDB_SHARE::get_share(const char* table_name,
+ TABLE_SHARE* table_share,
+ THR_LOCK_DATA* data,
+ bool create_new) {
+ mutex_t_lock(_open_tables_mutex);
int error = 0;
- uint length = (uint) strlen(table_name);
- TOKUDB_SHARE* share =
- (TOKUDB_SHARE*)my_hash_search(
- &_open_tables,
- (uchar*)table_name,
- length);
+ uint length = (uint)strlen(table_name);
+ TOKUDB_SHARE* share = (TOKUDB_SHARE*)my_hash_search(
+ &_open_tables, (uchar*)table_name, length);
TOKUDB_TRACE_FOR_FLAGS(
TOKUDB_DEBUG_SHARE,
@@ -276,28 +269,27 @@ TOKUDB_SHARE* TOKUDB_SHARE::get_share(
thr_lock_data_init(&(share->_thr_lock), data, NULL);
exit:
- _open_tables_mutex.unlock();
+ mutex_t_unlock(_open_tables_mutex);
return share;
}
void TOKUDB_SHARE::drop_share(TOKUDB_SHARE* share) {
- TOKUDB_TRACE_FOR_FLAGS(
- TOKUDB_DEBUG_SHARE,
- "share[%p]:file[%s]:state[%s]:use_count[%d]",
- share,
- share->_full_table_name.ptr(),
- get_state_string(share->_state),
- share->_use_count);
-
- _open_tables_mutex.lock();
+ TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_SHARE,
+ "share[%p]:file[%s]:state[%s]:use_count[%d]",
+ share,
+ share->_full_table_name.ptr(),
+ get_state_string(share->_state),
+ share->_use_count);
+
+ mutex_t_lock(_open_tables_mutex);
my_hash_delete(&_open_tables, (uchar*)share);
- _open_tables_mutex.unlock();
+ mutex_t_unlock(_open_tables_mutex);
}
TOKUDB_SHARE::share_state_t TOKUDB_SHARE::addref() {
TOKUDB_SHARE_TRACE_FOR_FLAGS((TOKUDB_DEBUG_ENTER & TOKUDB_DEBUG_SHARE),
- "file[%s]:state[%s]:use_count[%d]",
- _full_table_name.ptr(),
- get_state_string(_state),
- _use_count);
+ "file[%s]:state[%s]:use_count[%d]",
+ _full_table_name.ptr(),
+ get_state_string(_state),
+ _use_count);
lock();
_use_count++;
@@ -312,7 +304,7 @@ int TOKUDB_SHARE::release() {
int error, result = 0;
- _mutex.lock();
+ mutex_t_lock(_mutex);
assert_always(_use_count != 0);
_use_count--;
if (_use_count == 0 && _state == TOKUDB_SHARE::OPENED) {
@@ -356,7 +348,7 @@ int TOKUDB_SHARE::release() {
_state = TOKUDB_SHARE::CLOSED;
}
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
TOKUDB_SHARE_DBUG_RETURN(result);
}
@@ -1195,8 +1187,10 @@ static int generate_row_for_put(
ha_tokudb::ha_tokudb(handlerton * hton, TABLE_SHARE * table_arg):handler(hton, table_arg) {
TOKUDB_HANDLER_DBUG_ENTER("");
share = NULL;
- int_table_flags = HA_REC_NOT_IN_SEQ | HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_PRIMARY_KEY_IN_READ_INDEX | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
- HA_FILE_BASED | HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX | HA_CAN_WRITE_DURING_OPTIMIZE;
+ int_table_flags = HA_REC_NOT_IN_SEQ | HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS
+ | HA_PRIMARY_KEY_IN_READ_INDEX | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
+ | HA_FILE_BASED | HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX
+ | HA_CAN_WRITE_DURING_OPTIMIZE | HA_ONLINE_ANALYZE;
alloc_ptr = NULL;
rec_buff = NULL;
rec_update_buff = NULL;
@@ -3313,12 +3307,12 @@ void ha_tokudb::start_bulk_insert(ha_rows rows) {
delay_updating_ai_metadata = true;
ai_metadata_update_required = false;
abort_loader = false;
-
- share->_num_DBs_lock.lock_read();
+
+ rwlock_t_lock_read(share->_num_DBs_lock);
uint curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key);
num_DBs_locked_in_bulk = true;
lock_count = 0;
-
+
if ((rows == 0 || rows > 1) && share->try_table_lock) {
if (tokudb::sysvars::prelock_empty(thd) &&
may_table_be_empty(transaction) &&
@@ -4029,14 +4023,13 @@ int ha_tokudb::write_row(uchar * record) {
// grab reader lock on numDBs_lock
//
if (!num_DBs_locked_in_bulk) {
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
num_DBs_locked = true;
- }
- else {
+ } else {
lock_count++;
if (lock_count >= 2000) {
share->_num_DBs_lock.unlock();
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
lock_count = 0;
}
}
@@ -4206,7 +4199,7 @@ int ha_tokudb::update_row(const uchar * old_row, const uchar * new_row) {
//
bool num_DBs_locked = false;
if (!num_DBs_locked_in_bulk) {
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
num_DBs_locked = true;
}
curr_num_DBs = share->num_DBs;
@@ -4346,7 +4339,7 @@ int ha_tokudb::delete_row(const uchar * record) {
//
bool num_DBs_locked = false;
if (!num_DBs_locked_in_bulk) {
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
num_DBs_locked = true;
}
curr_num_DBs = share->num_DBs;
@@ -4637,6 +4630,9 @@ int ha_tokudb::index_init(uint keynr, bool sorted) {
if (tokudb::sysvars::disable_prefetching(thd)) {
cursor_flags |= DBC_DISABLE_PREFETCHING;
}
+ if (lock.type == TL_READ_WITH_SHARED_LOCKS) {
+ cursor_flags |= DB_LOCKING_READ;
+ }
if ((error = share->key_file[keynr]->cursor(share->key_file[keynr],
transaction, &cursor,
cursor_flags))) {
@@ -6198,6 +6194,8 @@ int ha_tokudb::info(uint flag) {
}
if ((flag & HA_STATUS_CONST)) {
stats.max_data_file_length = 9223372036854775807ULL;
+ }
+ if (flag & (HA_STATUS_VARIABLE | HA_STATUS_CONST)) {
share->set_cardinality_counts_in_table(table);
}
@@ -6281,7 +6279,7 @@ int ha_tokudb::acquire_table_lock (DB_TXN* trans, TABLE_LOCK_TYPE lt) {
TOKUDB_HANDLER_DBUG_ENTER("%p %s", trans, lt == lock_read ? "r" : "w");
int error = ENOSYS;
if (!num_DBs_locked_in_bulk) {
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
}
uint curr_num_DBs = share->num_DBs;
if (lt == lock_read) {
@@ -6637,8 +6635,9 @@ THR_LOCK_DATA* *ha_tokudb::store_lock(
if (sql_command == SQLCOM_CREATE_INDEX &&
tokudb::sysvars::create_index_online(thd)) {
// hot indexing
- share->_num_DBs_lock.lock_read();
- if (share->num_DBs == (table->s->keys + tokudb_test(hidden_primary_key))) {
+ rwlock_t_lock_read(share->_num_DBs_lock);
+ if (share->num_DBs ==
+ (table->s->keys + tokudb_test(hidden_primary_key))) {
lock_type = TL_WRITE_ALLOW_WRITE;
}
share->_num_DBs_lock.unlock();
@@ -7212,10 +7211,28 @@ int ha_tokudb::create(
const tokudb::sysvars::row_format_t row_format =
(tokudb::sysvars::row_format_t)form->s->option_struct->row_format;
#else
- const tokudb::sysvars::row_format_t row_format =
- (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)
- ? row_type_to_row_format(create_info->row_type)
- : tokudb::sysvars::row_format(thd);
+ // TDB-76 : CREATE TABLE ... LIKE ... does not use source row_format on
+ // target table
+ // Original code would only use create_info->row_type if
+ // create_info->used_fields & HA_CREATE_USED_ROW_FORMAT was true. This
+ // would cause us to skip transferring the row_format for a table created
+ // via CREATE TABLE tn LIKE tn. We also take on more InnoDB like behavior
+ // and throw a warning if we get a row_format that we can't translate into
+ // a known TokuDB row_format.
+ tokudb::sysvars::row_format_t row_format =
+ tokudb::sysvars::row_format(thd);
+
+ if ((create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) ||
+ create_info->row_type != ROW_TYPE_DEFAULT) {
+ row_format = row_type_to_row_format(create_info->row_type);
+ if (row_format == tokudb::sysvars::SRV_ROW_FORMAT_DEFAULT &&
+ create_info->row_type != ROW_TYPE_DEFAULT) {
+ push_warning(thd,
+ Sql_condition::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "TokuDB: invalid ROW_FORMAT specifier.");
+ }
+ }
#endif
const toku_compression_method compression_method =
row_format_to_toku_compression_method(row_format);
@@ -8100,8 +8117,8 @@ int ha_tokudb::tokudb_add_index(
}
}
}
-
- share->_num_DBs_lock.lock_write();
+
+ rwlock_t_lock_write(share->_num_DBs_lock);
rw_lock_taken = true;
//
// open all the DB files and set the appropriate variables in share
@@ -8211,7 +8228,7 @@ int ha_tokudb::tokudb_add_index(
goto cleanup;
}
- share->_num_DBs_lock.lock_write();
+ rwlock_t_lock_write(share->_num_DBs_lock);
error = indexer->close(indexer);
share->_num_DBs_lock.unlock();
if (error) {
@@ -8445,7 +8462,7 @@ cleanup:
if (indexer != NULL) {
sprintf(status_msg, "aborting creation of indexes.");
thd_proc_info(thd, status_msg);
- share->_num_DBs_lock.lock_write();
+ rwlock_t_lock_write(share->_num_DBs_lock);
indexer->abort(indexer);
share->_num_DBs_lock.unlock();
}
@@ -8494,10 +8511,10 @@ void ha_tokudb::restore_add_index(
//
// need to restore num_DBs, and we have to do it before we close the dictionaries
- // so that there is not a window
+ // so that there is not a window
//
if (incremented_numDBs) {
- share->_num_DBs_lock.lock_write();
+ rwlock_t_lock_write(share->_num_DBs_lock);
share->num_DBs--;
}
if (modified_DBs) {
diff --git a/storage/tokudb/ha_tokudb.h b/storage/tokudb/ha_tokudb.h
index 7476efe380f..c80be207005 100644
--- a/storage/tokudb/ha_tokudb.h
+++ b/storage/tokudb/ha_tokudb.h
@@ -318,18 +318,18 @@ inline int TOKUDB_SHARE::use_count() const {
}
inline void TOKUDB_SHARE::lock() const {
TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]",
- _full_table_name.ptr(),
- get_state_string(_state),
- _use_count);
- _mutex.lock();
+ _full_table_name.ptr(),
+ get_state_string(_state),
+ _use_count);
+ mutex_t_lock(_mutex);
TOKUDB_SHARE_DBUG_VOID_RETURN();
}
inline void TOKUDB_SHARE::unlock() const {
TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]",
- _full_table_name.ptr(),
- get_state_string(_state),
- _use_count);
- _mutex.unlock();
+ _full_table_name.ptr(),
+ get_state_string(_state),
+ _use_count);
+ mutex_t_unlock(_mutex);
TOKUDB_SHARE_DBUG_VOID_RETURN();
}
inline TOKUDB_SHARE::share_state_t TOKUDB_SHARE::state() const {
diff --git a/storage/tokudb/ha_tokudb_update.cc b/storage/tokudb/ha_tokudb_update.cc
index a6c72506448..2e56d4c6698 100644
--- a/storage/tokudb/ha_tokudb_update.cc
+++ b/storage/tokudb/ha_tokudb_update.cc
@@ -918,7 +918,7 @@ int ha_tokudb::send_update_message(
marshall_update(update_message, lhs_item, rhs_item, table, share);
}
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
// hot index in progress
if (share->num_DBs > table->s->keys + tokudb_test(hidden_primary_key)) {
@@ -1108,7 +1108,7 @@ int ha_tokudb::send_upsert_message(
marshall_update(update_message, lhs_item, rhs_item, table, share);
}
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
// hot index in progress
if (share->num_DBs > table->s->keys + tokudb_test(hidden_primary_key)) {
diff --git a/storage/tokudb/hatoku_cmp.cc b/storage/tokudb/hatoku_cmp.cc
index b615d4437d2..ee4d1dac4ea 100644
--- a/storage/tokudb/hatoku_cmp.cc
+++ b/storage/tokudb/hatoku_cmp.cc
@@ -1987,6 +1987,7 @@ static uint32_t pack_desc_key_length_info(uchar* buf, KEY_AND_COL_INFO* kc_info,
case (toku_type_fixstring):
field_length = field->pack_length();
set_if_smaller(key_part_length, field_length);
+ // fallthrough
case (toku_type_varbinary):
case (toku_type_varstring):
case (toku_type_blob):
diff --git a/storage/tokudb/hatoku_defines.h b/storage/tokudb/hatoku_defines.h
index f6d70c7026a..8fd8ab538cd 100644
--- a/storage/tokudb/hatoku_defines.h
+++ b/storage/tokudb/hatoku_defines.h
@@ -168,6 +168,14 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#define HA_CAN_WRITE_DURING_OPTIMIZE 0
#endif
+#if !defined(HA_ONLINE_ANALYZE)
+#define HA_ONLINE_ANALYZE 0
+#endif
+
+#if !defined(MY_ATTRIBUTE)
+#define MY_ATTRIBUTE(A) __attribute__(A)
+#endif
+
#if !defined(HA_OPTION_CREATE_FROM_ENGINE)
#define HA_OPTION_CREATE_FROM_ENGINE 0
#endif
@@ -248,4 +256,22 @@ inline uint tokudb_uint3korr(const uchar *a) {
return uint3korr(b);
}
-#endif // _HATOKU_DEFINES_H
+typedef unsigned int pfs_key_t;
+
+#if defined(HAVE_PSI_MUTEX_INTERFACE)
+#define mutex_t_lock(M) M.lock(__FILE__, __LINE__)
+#define mutex_t_unlock(M) M.unlock(__FILE__, __LINE__)
+#else // HAVE_PSI_MUTEX_INTERFACE
+#define mutex_t_lock(M) M.lock()
+#define mutex_t_unlock(M) M.unlock()
+#endif // HAVE_PSI_MUTEX_INTERFACE
+
+#if defined(HAVE_PSI_RWLOCK_INTERFACE)
+#define rwlock_t_lock_read(M) M.lock_read(__FILE__, __LINE__)
+#define rwlock_t_lock_write(M) M.lock_write(__FILE__, __LINE__)
+#else // HAVE_PSI_RWLOCK_INTERFACE
+#define rwlock_t_lock_read(M) M.lock_read()
+#define rwlock_t_lock_write(M) M.lock_write()
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+
+#endif // _HATOKU_DEFINES_H
diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc
index 599948e03f8..cee8575eebb 100644
--- a/storage/tokudb/hatoku_hton.cc
+++ b/storage/tokudb/hatoku_hton.cc
@@ -28,6 +28,17 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#define TOKU_METADB_NAME "tokudb_meta"
+static pfs_key_t tokudb_map_mutex_key;
+
+static PSI_mutex_info all_tokudb_mutexes[] = {
+ {&tokudb_map_mutex_key, "tokudb_map_mutex", 0},
+ {&ha_tokudb_mutex_key, "ha_tokudb_mutex", 0},
+};
+
+static PSI_rwlock_info all_tokudb_rwlocks[] = {
+ {&num_DBs_lock_key, "num_DBs_lock", 0},
+};
+
typedef struct savepoint_info {
DB_TXN* txn;
tokudb_trx_data* trx;
@@ -109,8 +120,8 @@ handlerton* tokudb_hton;
const char* ha_tokudb_ext = ".tokudb";
DB_ENV* db_env;
-#if TOKU_THDVAR_MEMALLOC_BUG
static tokudb::thread::mutex_t tokudb_map_mutex;
+#if TOKU_THDVAR_MEMALLOC_BUG
static TREE tokudb_map;
struct tokudb_map_pair {
THD* thd;
@@ -212,6 +223,10 @@ extern "C" {
// use constructor and destructor functions to create and destroy
// the lock before and after main(), respectively.
int tokudb_hton_initialized;
+
+// tokudb_hton_initialized_lock can not be instrumented as it must be
+// initialized before mysql_mutex_register() call to protect
+// some globals from race condition.
tokudb::thread::rwlock_t tokudb_hton_initialized_lock;
static SHOW_VAR *toku_global_status_variables = NULL;
@@ -267,10 +282,23 @@ static int tokudb_init_func(void *p) {
int r;
// 3938: lock the handlerton's initialized status flag for writing
- tokudb_hton_initialized_lock.lock_write();
+ rwlock_t_lock_write(tokudb_hton_initialized_lock);
+
+#ifdef HAVE_PSI_INTERFACE
+ /* Register TokuDB mutex keys with MySQL performance schema */
+ int count;
+
+ count = array_elements(all_tokudb_mutexes);
+ mysql_mutex_register("tokudb", all_tokudb_mutexes, count);
+
+ count = array_elements(all_tokudb_rwlocks);
+ mysql_rwlock_register("tokudb", all_tokudb_rwlocks, count);
+
+ tokudb_map_mutex.reinit(tokudb_map_mutex_key);
+#endif /* HAVE_PSI_INTERFACE */
db_env = NULL;
- tokudb_hton = (handlerton *) p;
+ tokudb_hton = (handlerton*)p;
if (tokudb::sysvars::check_jemalloc) {
typedef int (*mallctl_type)(
@@ -668,7 +696,7 @@ int tokudb_end(handlerton* hton, ha_panic_function type) {
// initialized. grab a writer lock for the duration of the
// call, so we can drop the flag and destroy the mutexes
// in isolation.
- tokudb_hton_initialized_lock.lock_write();
+ rwlock_t_lock_write(tokudb_hton_initialized_lock);
assert_always(tokudb_hton_initialized);
tokudb::background::destroy();
@@ -748,16 +776,16 @@ static int tokudb_close_connection(handlerton* hton, THD* thd) {
}
tokudb::memory::free(trx);
#if TOKU_THDVAR_MEMALLOC_BUG
- tokudb_map_mutex.lock();
- struct tokudb_map_pair key = { thd, NULL };
+ mutex_t_lock(tokudb_map_mutex);
+ struct tokudb_map_pair key = {thd, NULL};
struct tokudb_map_pair* found_key =
- (struct tokudb_map_pair*) tree_search(&tokudb_map, &key, NULL);
+ (struct tokudb_map_pair*)tree_search(&tokudb_map, &key, NULL);
if (found_key) {
tokudb::memory::free(found_key->last_lock_timeout);
tree_delete(&tokudb_map, found_key, sizeof(*found_key), NULL);
}
- tokudb_map_mutex.unlock();
+ mutex_t_unlock(tokudb_map_mutex);
#endif
return error;
}
@@ -1718,12 +1746,12 @@ static void tokudb_lock_timeout_callback(
tokudb::memory::strdup(log_str.c_ptr(), MY_FAE);
tokudb::sysvars::set_last_lock_timeout(thd, new_lock_timeout);
#if TOKU_THDVAR_MEMALLOC_BUG
- tokudb_map_mutex.lock();
- struct tokudb_map_pair old_key = { thd, old_lock_timeout };
+ mutex_t_lock(tokudb_map_mutex);
+ struct tokudb_map_pair old_key = {thd, old_lock_timeout};
tree_delete(&tokudb_map, &old_key, sizeof old_key, NULL);
- struct tokudb_map_pair new_key = { thd, new_lock_timeout };
+ struct tokudb_map_pair new_key = {thd, new_lock_timeout};
tree_insert(&tokudb_map, &new_key, sizeof new_key, NULL);
- tokudb_map_mutex.unlock();
+ mutex_t_unlock(tokudb_map_mutex);
#endif
tokudb::memory::free(old_lock_timeout);
}
diff --git a/storage/tokudb/hatoku_hton.h b/storage/tokudb/hatoku_hton.h
index d126ff4339f..80e13fa9b0c 100644
--- a/storage/tokudb/hatoku_hton.h
+++ b/storage/tokudb/hatoku_hton.h
@@ -39,6 +39,9 @@ extern handlerton* tokudb_hton;
extern DB_ENV* db_env;
+extern pfs_key_t ha_tokudb_mutex_key;
+extern pfs_key_t num_DBs_lock_key;
+
inline tokudb::sysvars::row_format_t toku_compression_method_to_row_format(
toku_compression_method method) {
@@ -180,9 +183,7 @@ inline bool tokudb_killed_thd_callback(void *extra, uint64_t deleted_rows) {
return thd_kill_level(thd) != 0;
}
-
extern HASH tokudb_open_tables;
-extern tokudb::thread::mutex_t tokudb_mutex;
extern const char* tokudb_hton_name;
extern int tokudb_hton_initialized;
extern tokudb::thread::rwlock_t tokudb_hton_initialized_lock;
diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_crash_safe.result b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_crash_safe.result
deleted file mode 100644
index 04578c3ff68..00000000000
--- a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_crash_safe.result
+++ /dev/null
@@ -1,2183 +0,0 @@
-include/master-slave.inc
-Warnings:
-Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
-Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
-[connection master]
-call mtr.add_suppression('Attempting backtrace');
-call mtr.add_suppression("Recovery from master pos .* and file master-bin.000001");
-call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
-call mtr.add_suppression(".* InnoDB: Warning: allocated tablespace .*, old maximum was .*");
-###################################################################################
-# PREPARE EXECUTION
-###################################################################################
-include/stop_slave.inc
-SHOW CREATE TABLE mysql.slave_relay_log_info;
-Table Create Table
-slave_relay_log_info CREATE TABLE `slave_relay_log_info` (
- `Number_of_lines` int(10) unsigned NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
- `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.',
- `Relay_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The relay log position of the last executed event.',
- `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.',
- `Master_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The master log position of the last executed event.',
- `Sql_delay` int(11) NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.',
- `Number_of_workers` int(10) unsigned NOT NULL,
- `Id` int(10) unsigned NOT NULL COMMENT 'Internal Id that uniquely identifies this record.',
- PRIMARY KEY (`Id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Relay Log Information'
-SHOW CREATE TABLE mysql.slave_worker_info;
-Table Create Table
-slave_worker_info CREATE TABLE `slave_worker_info` (
- `Id` int(10) unsigned NOT NULL,
- `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Relay_log_pos` bigint(20) unsigned NOT NULL,
- `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Master_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Checkpoint_relay_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Checkpoint_master_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_seqno` int(10) unsigned NOT NULL,
- `Checkpoint_group_size` int(10) unsigned NOT NULL,
- `Checkpoint_group_bitmap` blob NOT NULL,
- PRIMARY KEY (`Id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Worker Information'
-ALTER TABLE mysql.slave_relay_log_info ENGINE= Innodb;
-ALTER TABLE mysql.slave_worker_info ENGINE= Innodb;
-SHOW CREATE TABLE mysql.slave_relay_log_info;
-Table Create Table
-slave_relay_log_info CREATE TABLE `slave_relay_log_info` (
- `Number_of_lines` int(10) unsigned NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
- `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.',
- `Relay_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The relay log position of the last executed event.',
- `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.',
- `Master_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The master log position of the last executed event.',
- `Sql_delay` int(11) NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.',
- `Number_of_workers` int(10) unsigned NOT NULL,
- `Id` int(10) unsigned NOT NULL COMMENT 'Internal Id that uniquely identifies this record.',
- PRIMARY KEY (`Id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Relay Log Information'
-SHOW CREATE TABLE mysql.slave_worker_info;
-Table Create Table
-slave_worker_info CREATE TABLE `slave_worker_info` (
- `Id` int(10) unsigned NOT NULL,
- `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Relay_log_pos` bigint(20) unsigned NOT NULL,
- `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Master_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Checkpoint_relay_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Checkpoint_master_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_seqno` int(10) unsigned NOT NULL,
- `Checkpoint_group_size` int(10) unsigned NOT NULL,
- `Checkpoint_group_bitmap` blob NOT NULL,
- PRIMARY KEY (`Id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Worker Information'
-include/start_slave.inc
-rpl_mixing_engines.inc [commands=configure]
-CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-INSERT INTO nt_1(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO nt_2(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO nt_3(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO nt_4(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO nt_5(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO nt_6(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_1(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_2(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_3(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_4(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_5(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_6(trans_id, stmt_id) VALUES(1,1);
-CREATE PROCEDURE pc_i_tt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER)
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
-END|
-CREATE PROCEDURE pc_i_nt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER)
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
-END|
-CREATE FUNCTION fc_i_tt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
-RETURN "fc_i_tt_5_suc";
-END|
-CREATE FUNCTION fc_i_nt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
-RETURN "fc_i_nt_5_suc";
-END|
-CREATE FUNCTION fc_i_nt_3_tt_3_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO nt_3(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-SELECT max(stmt_id) INTO in_stmt_id FROM tt_3 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO tt_3(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-RETURN "fc_i_nt_3_tt_3_suc";
-END|
-CREATE TRIGGER tr_i_tt_3_to_nt_3 AFTER INSERT ON tt_3 FOR EACH ROW
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= NEW.trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
-INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
-INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
-END|
-CREATE TRIGGER tr_i_nt_4_to_tt_4 AFTER INSERT ON nt_4 FOR EACH ROW
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM tt_4 WHERE trans_id= NEW.trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
-INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
-INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
-END|
-CREATE TRIGGER tr_i_tt_5_to_tt_6 AFTER INSERT ON tt_5 FOR EACH ROW
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM tt_6 WHERE trans_id= NEW.trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id, 1), 1) INTO in_stmt_id;
-INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
-INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
-END|
-CREATE TRIGGER tr_i_nt_5_to_nt_6 AFTER INSERT ON nt_5 FOR EACH ROW
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM nt_6 WHERE trans_id= NEW.trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
-INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
-INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
-END|
-###################################################################################
-# EXECUTE CASES CRASHING THE XID
-###################################################################################
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=T]
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (7, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-trig]
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (8, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-func]
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (9, 1);
-fc_i_tt_5_suc (9, 1)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-proc]
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (10, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-trig C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (11, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (11, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-trig C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-trig C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-func C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (12, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (12, 4);
-fc_i_tt_5_suc (12, 4)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-func C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-func C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-proc C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (13, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (13, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-proc C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-proc C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-trig T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (14, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (14, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-trig T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-trig T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-func T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (15, 2);
-fc_i_tt_5_suc (15, 2)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (15, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-func T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-func T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-proc T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (16, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (16, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-proc T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-proc T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=T]
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (17, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-trig]
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (18, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-func]
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (19, 1);
-fc_i_tt_5_suc (19, 1)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-proc]
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (20, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-trig C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (21, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (21, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-trig C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-trig C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-func C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (22, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (22, 4);
-fc_i_tt_5_suc (22, 4)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-func C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-func C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-proc C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (23, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (23, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-proc C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-proc C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-trig T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (24, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (24, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-trig T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-trig T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-func T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (25, 2);
-fc_i_tt_5_suc (25, 2)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (25, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-func T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-func T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-proc T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (26, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-proc T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-proc T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=T]
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (27, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-trig]
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (28, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-func]
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (29, 1);
-fc_i_tt_5_suc (29, 1)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-proc]
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (30, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-trig C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (31, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (31, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-trig C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-trig C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-func C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (32, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (32, 4);
-fc_i_tt_5_suc (32, 4)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-func C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-func C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-proc C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (33, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (33, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-proc C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-proc C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-trig T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (34, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (34, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-trig T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-trig T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-func T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (35, 2);
-fc_i_tt_5_suc (35, 2)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (35, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-func T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-func T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-proc T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (36, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (36, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-proc T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-proc T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=T]
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (37, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-trig]
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (38, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-func]
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (39, 1);
-fc_i_tt_5_suc (39, 1)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-proc]
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (40, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-trig C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (41, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (41, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-trig C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-trig C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-func C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (42, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (42, 4);
-fc_i_tt_5_suc (42, 4)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-func C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-func C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-proc C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (43, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (43, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-proc C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-proc C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-trig T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (44, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (44, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-trig T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-trig T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-func T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (45, 2);
-fc_i_tt_5_suc (45, 2)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (45, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-func T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-func T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-proc T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (46, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (46, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-proc T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_5)
-master-bin.000001 # Table_map # # table_id: # (test.tt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.tt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-proc T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-###################################################################################
-# EXECUTE CASES CRASHING THE BEGIN/COMMIT
-###################################################################################
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_and_update_pos";;
-FAILURE d,crash_after_commit_and_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=N]
--b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO nt_1(trans_id, stmt_id) VALUES (47, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.nt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.nt_1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_and_update_pos";;
-FAILURE d,crash_after_commit_and_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=N-trig]
--b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO nt_5(trans_id, stmt_id) VALUES (48, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.nt_5)
-master-bin.000001 # Table_map # # table_id: # (test.nt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.nt_5)
-master-bin.000001 # Table_map # # table_id: # (test.nt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_and_update_pos";;
-FAILURE d,crash_after_commit_and_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=N-func]
--b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_nt_5_suc (49, 1);
-fc_i_nt_5_suc (49, 1)
-fc_i_nt_5_suc
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.nt_5)
-master-bin.000001 # Table_map # # table_id: # (test.nt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.nt_5)
-master-bin.000001 # Table_map # # table_id: # (test.nt_6)
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: #
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-###################################################################################
-# CHECK CONSISTENCY
-###################################################################################
-include/sync_slave_sql_with_master.inc
-###################################################################################
-# CLEAN
-###################################################################################
-rpl_mixing_engines.inc [commands=clean]
-DROP TABLE tt_1;
-DROP TABLE tt_2;
-DROP TABLE tt_3;
-DROP TABLE tt_4;
-DROP TABLE tt_5;
-DROP TABLE tt_6;
-DROP TABLE nt_1;
-DROP TABLE nt_2;
-DROP TABLE nt_3;
-DROP TABLE nt_4;
-DROP TABLE nt_5;
-DROP TABLE nt_6;
-DROP PROCEDURE pc_i_tt_5_suc;
-DROP PROCEDURE pc_i_nt_5_suc;
-DROP FUNCTION fc_i_tt_5_suc;
-DROP FUNCTION fc_i_nt_5_suc;
-DROP FUNCTION fc_i_nt_3_tt_3_suc;
-include/rpl_end.inc
diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result
index 73c010c6eb7..ab33725fa3f 100644
--- a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result
+++ b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result
@@ -226,7 +226,6 @@ master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Binlog_checkpoint # # master-bin.000002
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
master-bin.000002 # Gtid # # GTID #-#-#
@@ -268,7 +267,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002
slave-bin.000002 # Gtid # # GTID #-#-#
slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB
slave-bin.000002 # Gtid # # BEGIN GTID #-#-#
diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result
index 83335b0237c..652ef18c039 100644
--- a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result
+++ b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result
@@ -222,7 +222,6 @@ master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Binlog_checkpoint # # master-bin.000002
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
master-bin.000002 # Gtid # # GTID #-#-#
@@ -260,7 +259,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002
slave-bin.000002 # Gtid # # GTID #-#-#
slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB
slave-bin.000002 # Gtid # # BEGIN GTID #-#-#
diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_mixed_crash_safe.result b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_mixed_crash_safe.result
deleted file mode 100644
index 226a2b93140..00000000000
--- a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_mixed_crash_safe.result
+++ /dev/null
@@ -1,1773 +0,0 @@
-include/master-slave.inc
-Warnings:
-Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
-Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
-[connection master]
-call mtr.add_suppression('Attempting backtrace');
-call mtr.add_suppression("Recovery from master pos .* and file master-bin.000001");
-call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
-call mtr.add_suppression(".* InnoDB: Warning: allocated tablespace .*, old maximum was .*");
-###################################################################################
-# PREPARE EXECUTION
-###################################################################################
-include/stop_slave.inc
-SHOW CREATE TABLE mysql.slave_relay_log_info;
-Table Create Table
-slave_relay_log_info CREATE TABLE `slave_relay_log_info` (
- `Number_of_lines` int(10) unsigned NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
- `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.',
- `Relay_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The relay log position of the last executed event.',
- `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.',
- `Master_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The master log position of the last executed event.',
- `Sql_delay` int(11) NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.',
- `Number_of_workers` int(10) unsigned NOT NULL,
- `Id` int(10) unsigned NOT NULL COMMENT 'Internal Id that uniquely identifies this record.',
- PRIMARY KEY (`Id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Relay Log Information'
-SHOW CREATE TABLE mysql.slave_worker_info;
-Table Create Table
-slave_worker_info CREATE TABLE `slave_worker_info` (
- `Id` int(10) unsigned NOT NULL,
- `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Relay_log_pos` bigint(20) unsigned NOT NULL,
- `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Master_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Checkpoint_relay_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Checkpoint_master_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_seqno` int(10) unsigned NOT NULL,
- `Checkpoint_group_size` int(10) unsigned NOT NULL,
- `Checkpoint_group_bitmap` blob NOT NULL,
- PRIMARY KEY (`Id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Worker Information'
-ALTER TABLE mysql.slave_relay_log_info ENGINE= Innodb;
-ALTER TABLE mysql.slave_worker_info ENGINE= Innodb;
-SHOW CREATE TABLE mysql.slave_relay_log_info;
-Table Create Table
-slave_relay_log_info CREATE TABLE `slave_relay_log_info` (
- `Number_of_lines` int(10) unsigned NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
- `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.',
- `Relay_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The relay log position of the last executed event.',
- `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.',
- `Master_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The master log position of the last executed event.',
- `Sql_delay` int(11) NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.',
- `Number_of_workers` int(10) unsigned NOT NULL,
- `Id` int(10) unsigned NOT NULL COMMENT 'Internal Id that uniquely identifies this record.',
- PRIMARY KEY (`Id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Relay Log Information'
-SHOW CREATE TABLE mysql.slave_worker_info;
-Table Create Table
-slave_worker_info CREATE TABLE `slave_worker_info` (
- `Id` int(10) unsigned NOT NULL,
- `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Relay_log_pos` bigint(20) unsigned NOT NULL,
- `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Master_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Checkpoint_relay_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `Checkpoint_master_log_pos` bigint(20) unsigned NOT NULL,
- `Checkpoint_seqno` int(10) unsigned NOT NULL,
- `Checkpoint_group_size` int(10) unsigned NOT NULL,
- `Checkpoint_group_bitmap` blob NOT NULL,
- PRIMARY KEY (`Id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Worker Information'
-include/start_slave.inc
-rpl_mixing_engines.inc [commands=configure]
-CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
-CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = TokuDB;
-INSERT INTO nt_1(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO nt_2(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO nt_3(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO nt_4(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO nt_5(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO nt_6(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_1(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_2(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_3(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_4(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_5(trans_id, stmt_id) VALUES(1,1);
-INSERT INTO tt_6(trans_id, stmt_id) VALUES(1,1);
-CREATE PROCEDURE pc_i_tt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER)
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
-END|
-CREATE PROCEDURE pc_i_nt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER)
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
-END|
-CREATE FUNCTION fc_i_tt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
-RETURN "fc_i_tt_5_suc";
-END|
-CREATE FUNCTION fc_i_nt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
-RETURN "fc_i_nt_5_suc";
-END|
-CREATE FUNCTION fc_i_nt_3_tt_3_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO nt_3(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-SELECT max(stmt_id) INTO in_stmt_id FROM tt_3 WHERE trans_id= p_trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
-INSERT INTO tt_3(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
-RETURN "fc_i_nt_3_tt_3_suc";
-END|
-CREATE TRIGGER tr_i_tt_3_to_nt_3 AFTER INSERT ON tt_3 FOR EACH ROW
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= NEW.trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
-INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
-INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
-END|
-CREATE TRIGGER tr_i_nt_4_to_tt_4 AFTER INSERT ON nt_4 FOR EACH ROW
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM tt_4 WHERE trans_id= NEW.trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
-INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
-INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
-END|
-CREATE TRIGGER tr_i_tt_5_to_tt_6 AFTER INSERT ON tt_5 FOR EACH ROW
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM tt_6 WHERE trans_id= NEW.trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id, 1), 1) INTO in_stmt_id;
-INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
-INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
-END|
-CREATE TRIGGER tr_i_nt_5_to_nt_6 AFTER INSERT ON nt_5 FOR EACH ROW
-BEGIN
-DECLARE in_stmt_id INTEGER;
-SELECT max(stmt_id) INTO in_stmt_id FROM nt_6 WHERE trans_id= NEW.trans_id;
-SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
-INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
-INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
-END|
-###################################################################################
-# EXECUTE CASES CRASHING THE XID
-###################################################################################
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=T]
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (7, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (7, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (7, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-trig]
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (8, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (8, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (8, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-func]
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (9, 1);
-fc_i_tt_5_suc (9, 1)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(9,1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(9,1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-proc]
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (10, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-trig C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (11, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (11, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (11, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (11, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-trig C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (11, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (11, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-trig C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-func C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (12, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (12, 4);
-fc_i_tt_5_suc (12, 4)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (12, 2)
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(12,4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-func C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (12, 2)
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(12,4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-func C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-proc C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (13, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (13, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (13, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',13), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',13), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-proc C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (13, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',13), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',13), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-proc C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-trig T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (14, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (14, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (14, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (14, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-trig T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (14, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (14, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-trig T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-func T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (15, 2);
-fc_i_tt_5_suc (15, 2)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (15, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(15,2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (15, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-func T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(15,2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (15, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-func T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_apply";;
-FAILURE d,crash_after_apply and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-proc T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (16, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (16, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',16), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',16), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (16, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-proc T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',16), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',16), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (16, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-proc T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=T]
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (17, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (17, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (17, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-trig]
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (18, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (18, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (18, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-func]
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (19, 1);
-fc_i_tt_5_suc (19, 1)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(19,1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(19,1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-proc]
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (20, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-trig C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (21, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (21, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (21, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (21, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-trig C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (21, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (21, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-trig C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-func C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (22, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (22, 4);
-fc_i_tt_5_suc (22, 4)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (22, 2)
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(22,4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-func C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (22, 2)
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(22,4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-func C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-proc C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (23, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (23, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (23, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',23), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',23), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-proc C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (23, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',23), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',23), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-proc C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-trig T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (24, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (24, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (24, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (24, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-trig T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (24, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (24, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-trig T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-func T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (25, 2);
-fc_i_tt_5_suc (25, 2)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (25, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(25,2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (25, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-func T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(25,2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (25, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-func T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_before_update_pos";;
-FAILURE d,crash_before_update_pos and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-proc T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (26, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',26), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',26), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-proc T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',26), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',26), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-proc T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=T]
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (27, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (27, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (27, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-trig]
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (28, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (28, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (28, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-func]
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (29, 1);
-fc_i_tt_5_suc (29, 1)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(29,1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(29,1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=T-proc]
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (30, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-trig C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (31, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (31, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (31, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (31, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-trig C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (31, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (31, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-trig C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-func C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (32, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (32, 4);
-fc_i_tt_5_suc (32, 4)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (32, 2)
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(32,4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-func C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (32, 2)
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(32,4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-func C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T T-proc C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (33, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (33, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (33, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',33), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',33), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-proc C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (33, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',33), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',33), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-proc C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-trig T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (34, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (34, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (34, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (34, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-trig T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (34, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (34, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-trig T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-func T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (35, 2);
-fc_i_tt_5_suc (35, 2)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (35, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(35,2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (35, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-func T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(35,2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (35, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-func T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_update_pos_before_apply";;
-FAILURE d,crash_after_update_pos_before_apply and OUTCOME O1
-rpl_mixing_engines.inc [commands=B T-proc T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (36, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (36, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',36), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',36), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (36, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-proc T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',36), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',36), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (36, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-proc T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=T]
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (37, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (37, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (37, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-trig]
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (38, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (38, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (38, 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-func]
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (39, 1);
-fc_i_tt_5_suc (39, 1)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(39,1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(39,1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=T-proc]
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (40, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-trig C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (41, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (41, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (41, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (41, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-trig C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (41, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (41, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-trig C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-func C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (42, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (42, 4);
-fc_i_tt_5_suc (42, 4)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (42, 2)
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(42,4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-func C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (42, 2)
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(42,4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-func C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T T-proc C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (43, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (43, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (43, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',43), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',43), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T T-proc C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (43, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',43), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',43), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T T-proc C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-trig T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_5(trans_id, stmt_id) VALUES (44, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (44, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (44, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (44, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-trig T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (44, 2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (44, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-trig T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-func T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_tt_5_suc (45, 2);
-fc_i_tt_5_suc (45, 2)
-fc_i_tt_5_suc
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (45, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(45,2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (45, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-func T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(45,2)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (45, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-func T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_before_update_pos";;
-FAILURE d,crash_after_commit_before_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=B T-proc T C]
--b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
-BEGIN;
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
-CALL pc_i_tt_5_suc (46, 2);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO tt_1(trans_id, stmt_id) VALUES (46, 4);
-include/show_binlog_events.inc
--e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
-COMMIT;
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',46), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',46), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (46, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> B T-proc T C << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',46), NAME_CONST('in_stmt_id',1))
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',46), NAME_CONST('in_stmt_id',1) + 1)
-master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (46, 4)
-master-bin.000001 # Xid # # COMMIT /* XID */
--e-e-e-e-e-e-e-e-e-e-e- >> B T-proc T C << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-###################################################################################
-# EXECUTE CASES CRASHING THE BEGIN/COMMIT
-###################################################################################
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_and_update_pos";;
-FAILURE d,crash_after_commit_and_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=N]
--b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO nt_1(trans_id, stmt_id) VALUES (47, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (47, 1)
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (47, 1)
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_and_update_pos";;
-FAILURE d,crash_after_commit_and_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=N-trig]
--b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
-INSERT INTO nt_5(trans_id, stmt_id) VALUES (48, 1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (48, 1)
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (48, 1)
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-
-
-
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-SET GLOBAL debug="d,crash_after_commit_and_update_pos";;
-FAILURE d,crash_after_commit_and_update_pos and OUTCOME O2
-rpl_mixing_engines.inc [commands=N-func]
--b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
-SELECT fc_i_nt_5_suc (49, 1);
-fc_i_nt_5_suc (49, 1)
-fc_i_nt_5_suc
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(49,1)
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
--b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(49,1)
-master-bin.000001 # Query # # COMMIT
--e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
-
-include/rpl_reconnect.inc
-START SLAVE;
-include/wait_for_slave_to_start.inc
-###################################################################################
-# CHECK CONSISTENCY
-###################################################################################
-include/sync_slave_sql_with_master.inc
-###################################################################################
-# CLEAN
-###################################################################################
-rpl_mixing_engines.inc [commands=clean]
-DROP TABLE tt_1;
-DROP TABLE tt_2;
-DROP TABLE tt_3;
-DROP TABLE tt_4;
-DROP TABLE tt_5;
-DROP TABLE tt_6;
-DROP TABLE nt_1;
-DROP TABLE nt_2;
-DROP TABLE nt_3;
-DROP TABLE nt_4;
-DROP TABLE nt_5;
-DROP TABLE nt_6;
-DROP PROCEDURE pc_i_tt_5_suc;
-DROP PROCEDURE pc_i_nt_5_suc;
-DROP FUNCTION fc_i_tt_5_suc;
-DROP FUNCTION fc_i_nt_5_suc;
-DROP FUNCTION fc_i_nt_3_tt_3_suc;
-include/rpl_end.inc
diff --git a/storage/tokudb/mysql-test/rpl/t/rpl_tokudb_row_crash_safe.test b/storage/tokudb/mysql-test/rpl/t/rpl_tokudb_row_crash_safe.test
deleted file mode 100644
index 6bd79691528..00000000000
--- a/storage/tokudb/mysql-test/rpl/t/rpl_tokudb_row_crash_safe.test
+++ /dev/null
@@ -1,19 +0,0 @@
-# This test takes long time, so only run it with the --big-test mtr-flag.
---source include/big_test.inc
---source include/not_embedded.inc
---source include/not_valgrind.inc
---source include/have_debug.inc
---source include/have_tokudb.inc
---source include/have_binlog_format_row.inc
---source include/not_mts_slave_parallel_workers.inc
---source include/master-slave.inc
-
-call mtr.add_suppression('Attempting backtrace');
-call mtr.add_suppression("Recovery from master pos .* and file master-bin.000001");
-call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
-call mtr.add_suppression(".* InnoDB: Warning: allocated tablespace .*, old maximum was .*");
-
-let $engine_type=TokuDB;
-let $database_name=test;
---source extra/rpl_tests/rpl_crash_safe.test
---source include/rpl_end.inc
diff --git a/storage/tokudb/mysql-test/rpl/t/rpl_tokudb_stm_mixed_crash_safe.test b/storage/tokudb/mysql-test/rpl/t/rpl_tokudb_stm_mixed_crash_safe.test
deleted file mode 100644
index 724550fae4a..00000000000
--- a/storage/tokudb/mysql-test/rpl/t/rpl_tokudb_stm_mixed_crash_safe.test
+++ /dev/null
@@ -1,18 +0,0 @@
---source include/big_test.inc
---source include/not_embedded.inc
---source include/not_valgrind.inc
---source include/have_debug.inc
---source include/have_tokudb.inc
---source include/have_binlog_format_mixed_or_statement.inc
---source include/not_mts_slave_parallel_workers.inc
---source include/master-slave.inc
-
-call mtr.add_suppression('Attempting backtrace');
-call mtr.add_suppression("Recovery from master pos .* and file master-bin.000001");
-call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
-call mtr.add_suppression(".* InnoDB: Warning: allocated tablespace .*, old maximum was .*");
-
-let $engine_type=TokuDB;
-let $database_name=test;
---source extra/rpl_tests/rpl_crash_safe.test
---source include/rpl_end.inc
diff --git a/storage/tokudb/mysql-test/tokudb/disabled.def b/storage/tokudb/mysql-test/tokudb/disabled.def
index ddefceb432e..89f6992d26d 100644
--- a/storage/tokudb/mysql-test/tokudb/disabled.def
+++ b/storage/tokudb/mysql-test/tokudb/disabled.def
@@ -29,3 +29,6 @@ cluster_key_part: engine options on partitioned tables
i_s_tokudb_lock_waits_released: unstable, race conditions
i_s_tokudb_locks_released: unstable, race conditions
row_format: n/a
+nonflushing_analyze_debug: Freezes in MariaDB 10.0
+tokudb.change_column_all_1000_1: We are too lazy to fix this properly
+tokudb.change_column_all_1000_10: We are too lazy to fix this properly
diff --git a/storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result b/storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result
index cfd7e38179c..981433fac91 100644
--- a/storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result
+++ b/storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result
@@ -1,7 +1,7 @@
-set global tokudb_cardinality_scale_percent = 10;
analyze table tt;
Table Op Msg_type Msg_text
test.tt analyze status OK
+set global tokudb_cardinality_scale_percent = 10;
show indexes from tt;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE
@@ -9,9 +9,6 @@ tt 1 b 1 b A 4000 NULL NULL YES BTREE
tt 1 c 1 c A 4000 NULL NULL YES BTREE
tt 1 d 1 d A 4000 NULL NULL YES BTREE
set global tokudb_cardinality_scale_percent = 50;
-analyze table tt;
-Table Op Msg_type Msg_text
-test.tt analyze status OK
show indexes from tt;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE
@@ -19,9 +16,6 @@ tt 1 b 1 b A 4000 NULL NULL YES BTREE
tt 1 c 1 c A 4000 NULL NULL YES BTREE
tt 1 d 1 d A 2000 NULL NULL YES BTREE
set global tokudb_cardinality_scale_percent = 100;
-analyze table tt;
-Table Op Msg_type Msg_text
-test.tt analyze status OK
show indexes from tt;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE
@@ -31,9 +25,6 @@ tt 1 d 1 d A 1000 NULL NULL YES BTREE
set global tokudb_cardinality_scale_percent = 200;
Warnings:
Warning 1292 Truncated incorrect tokudb_cardinality_scale_percent value: '200'
-analyze table tt;
-Table Op Msg_type Msg_text
-test.tt analyze status OK
show indexes from tt;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result
index 16b3571db9f..a80e1664663 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result
@@ -1,7 +1,7 @@
drop table if exists t;
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
create table t (id int not null, x int not null, y int not null, primary key(id), key(x)) engine=innodb;
insert into t values (0,0,0),(1,1,1),(2,2,2),(3,2,3),(4,2,4);
explain select x,id from t force index (x) where x=0 and id=0;
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result
index 961504412a9..96d681407fe 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result
@@ -1,7 +1,7 @@
drop table if exists t;
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
create table t (id int not null, x int not null, y int not null, primary key(id), key(x)) engine=tokudb;
insert into t values (0,0,0),(1,1,1),(2,2,2),(3,2,3),(4,2,4);
explain select x,id from t force index (x) where x=0 and id=0;
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result
index e5796f7a9b1..43737c7753e 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result
@@ -1,7 +1,7 @@
drop table if exists t;
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
create table t (a int not null, b int not null, c int not null, d int not null, primary key(a,b), key(c,a)) engine=innodb;
insert into t values (0,0,0,0),(0,1,0,1);
explain select c,a,b from t where c=0 and a=0 and b=1;
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
index 3f1ed9971c3..1dcb1ee1b8b 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
@@ -1,7 +1,7 @@
drop table if exists t;
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
create table t (a int not null, b int not null, c int not null, d int not null, primary key(a,b), key(c,a)) engine=tokudb;
insert into t values (0,0,0,0),(0,1,0,1);
explain select c,a,b from t where c=0 and a=0 and b=1;
diff --git a/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-1.result b/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-1.result
new file mode 100644
index 00000000000..433b5baf18b
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-1.result
@@ -0,0 +1,16 @@
+create table t (a int primary key, b int) ENGINE=TokuDB;
+insert into t values (1,0);
+set session transaction isolation level repeatable read;
+begin;
+select * from t where a=1 lock in share mode;
+a b
+1 0
+connect conn1,localhost,root;
+set session transaction isolation level repeatable read;
+begin;
+update t set b=b+1 where a=1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection default;
+commit;
+disconnect conn1;
+drop table t;
diff --git a/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-2.result b/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-2.result
new file mode 100644
index 00000000000..79e886a8682
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-2.result
@@ -0,0 +1,20 @@
+create table t (a int primary key, b int) ENGINE=TokuDB;
+insert into t values (1,0);
+insert into t values (2,1);
+insert into t values (3,2);
+set session transaction isolation level repeatable read;
+begin;
+select * from t lock in share mode;
+a b
+1 0
+2 1
+3 2
+connect conn1,localhost,root;
+set session transaction isolation level repeatable read;
+begin;
+update t set b=b+1 where a=2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection default;
+commit;
+disconnect conn1;
+drop table t;
diff --git a/storage/tokudb/mysql-test/tokudb/r/nonflushing_analyze_debug.result b/storage/tokudb/mysql-test/tokudb/r/nonflushing_analyze_debug.result
new file mode 100644
index 00000000000..e8f51edee04
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/r/nonflushing_analyze_debug.result
@@ -0,0 +1,19 @@
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=TokuDB;
+INSERT INTO t1 VALUES (1), (2), (3);
+SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan";
+SELECT * FROM t1;
+SET DEBUG_SYNC="now WAIT_FOR idx_scan_in_progress";
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+SELECT * FROM t1;
+a
+1
+2
+3
+SET DEBUG_SYNC="now SIGNAL finish_scan";
+a
+1
+2
+3
+DROP TABLE t1;
diff --git a/storage/tokudb/mysql-test/tokudb/r/row_format.result b/storage/tokudb/mysql-test/tokudb/r/row_format.result
index cb669148445..15d4f9fe12a 100644
--- a/storage/tokudb/mysql-test/tokudb/r/row_format.result
+++ b/storage/tokudb/mysql-test/tokudb/r/row_format.result
@@ -1,4 +1,6 @@
CREATE TABLE tokudb_row_format_test_1 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_DEFAULT;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
CREATE TABLE tokudb_row_format_test_2 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_FAST;
CREATE TABLE tokudb_row_format_test_3 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_SMALL;
CREATE TABLE tokudb_row_format_test_4 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_UNCOMPRESSED;
@@ -6,6 +8,41 @@ CREATE TABLE tokudb_row_format_test_5 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_ZL
CREATE TABLE tokudb_row_format_test_6 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_LZMA;
CREATE TABLE tokudb_row_format_test_7 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_QUICKLZ;
CREATE TABLE tokudb_row_format_test_8 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_SNAPPY;
+CREATE TABLE tdb76_1 LIKE tokudb_row_format_test_1;
+CREATE TABLE tdb76_2 LIKE tokudb_row_format_test_2;
+CREATE TABLE tdb76_3 LIKE tokudb_row_format_test_3;
+CREATE TABLE tdb76_4 LIKE tokudb_row_format_test_4;
+CREATE TABLE tdb76_5 LIKE tokudb_row_format_test_5;
+CREATE TABLE tdb76_6 LIKE tokudb_row_format_test_6;
+CREATE TABLE tdb76_7 LIKE tokudb_row_format_test_7;
+CREATE TABLE tdb76_8 LIKE tokudb_row_format_test_8;
+CREATE TABLE tdb76_compact(a INT) ENGINE=TokuDB ROW_FORMAT=COMPACT;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
+CREATE TABLE tdb76_redundant(a INT) ENGINE=TokuDB ROW_FORMAT=REDUNDANT;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
+CREATE TABLE tdb76_dynamic(a INT) ENGINE=TokuDB ROW_FORMAT=DYNAMIC;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
+CREATE TABLE tdb76_compressed(a INT) ENGINE=TokuDB ROW_FORMAT=COMPRESSED;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
+SELECT table_name, row_format, engine FROM information_schema.tables WHERE table_name like 'tdb76_%' ORDER BY table_name;
+table_name row_format engine
+tdb76_1 tokudb_zlib TokuDB
+tdb76_2 tokudb_quicklz TokuDB
+tdb76_3 tokudb_lzma TokuDB
+tdb76_4 tokudb_uncompressed TokuDB
+tdb76_5 tokudb_zlib TokuDB
+tdb76_6 tokudb_lzma TokuDB
+tdb76_7 tokudb_quicklz TokuDB
+tdb76_8 tokudb_snappy TokuDB
+tdb76_compact tokudb_zlib TokuDB
+tdb76_compressed tokudb_zlib TokuDB
+tdb76_dynamic tokudb_zlib TokuDB
+tdb76_redundant tokudb_zlib TokuDB
+DROP TABLE tdb76_1, tdb76_2, tdb76_3, tdb76_4, tdb76_5, tdb76_6, tdb76_7, tdb76_8, tdb76_compact, tdb76_redundant, tdb76_dynamic, tdb76_compressed;
SELECT table_name, row_format, engine FROM information_schema.tables WHERE table_name like 'tokudb_row_format_test%' ORDER BY table_name;
table_name row_format engine
tokudb_row_format_test_1 tokudb_zlib TokuDB
@@ -45,6 +82,8 @@ SELECT table_name, row_format, engine FROM information_schema.tables WHERE table
table_name row_format engine
tokudb_row_format_test_1 tokudb_lzma TokuDB
ALTER TABLE tokudb_row_format_test_1 ENGINE=TokuDB ROW_FORMAT=TOKUDB_DEFAULT;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
SELECT table_name, row_format, engine FROM information_schema.tables WHERE table_name = 'tokudb_row_format_test_1';
table_name row_format engine
tokudb_row_format_test_1 tokudb_zlib TokuDB
diff --git a/storage/tokudb/mysql-test/tokudb/r/tokudb_support_xa.result b/storage/tokudb/mysql-test/tokudb/r/tokudb_support_xa.result
index 120e8de7c7f..fd32fa031c7 100644
--- a/storage/tokudb/mysql-test/tokudb/r/tokudb_support_xa.result
+++ b/storage/tokudb/mysql-test/tokudb/r/tokudb_support_xa.result
@@ -43,7 +43,7 @@ SET @@session.tokudb_support_xa = "T";
ERROR 42000: Variable 'tokudb_support_xa' can't be set to the value of 'T'
SET @@session.tokudb_support_xa = "Y";
ERROR 42000: Variable 'tokudb_support_xa' can't be set to the value of 'Y'
-SET @@session.tokudb_support_xa = OF;
+SET @@session.tokudb_support_xa = OFF;
SELECT @@session.tokudb_support_xa;
@@session.tokudb_support_xa
0
diff --git a/storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test b/storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test
index 47f1eb37989..75c53611308 100644
--- a/storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test
+++ b/storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test
@@ -30,20 +30,18 @@ set session tokudb_analyze_throttle=0;
-- enable_query_log
-set global tokudb_cardinality_scale_percent = 10;
analyze table tt;
+
+set global tokudb_cardinality_scale_percent = 10;
show indexes from tt;
set global tokudb_cardinality_scale_percent = 50;
-analyze table tt;
show indexes from tt;
set global tokudb_cardinality_scale_percent = 100;
-analyze table tt;
show indexes from tt;
set global tokudb_cardinality_scale_percent = 200;
-analyze table tt;
show indexes from tt;
-- disable_query_log
diff --git a/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-1.test b/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-1.test
new file mode 100644
index 00000000000..c5ef0f0703e
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-1.test
@@ -0,0 +1,23 @@
+source include/have_tokudb.inc;
+source include/count_sessions.inc;
+create table t (a int primary key, b int) ENGINE=TokuDB;
+insert into t values (1,0);
+set session transaction isolation level repeatable read;
+begin;
+# t1 select in share mode
+select * from t where a=1 lock in share mode;
+# t2 update
+connect(conn1,localhost,root);
+set session transaction isolation level repeatable read;
+begin;
+# t2 select for update, should hang until t1 commits
+send update t set b=b+1 where a=1;
+--error ER_LOCK_WAIT_TIMEOUT
+reap;
+# t2 update
+connection default;
+commit;
+disconnect conn1;
+drop table t;
+
+source include/wait_until_count_sessions.inc;
diff --git a/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-2.test b/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-2.test
new file mode 100644
index 00000000000..20a4549c45f
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-2.test
@@ -0,0 +1,29 @@
+#the difference of this test from locking-read-repeatable-read-1
+#is that this test is on range query(gap lock) which actually
+#examines a different patch
+
+source include/have_tokudb.inc;
+source include/count_sessions.inc;
+create table t (a int primary key, b int) ENGINE=TokuDB;
+insert into t values (1,0);
+insert into t values (2,1);
+insert into t values (3,2);
+set session transaction isolation level repeatable read;
+begin;
+# t1 select in share mode
+select * from t lock in share mode;
+# t2 update
+connect(conn1,localhost,root);
+set session transaction isolation level repeatable read;
+begin;
+# t2 select for update, should hang until t1 commits
+send update t set b=b+1 where a=2;
+--error ER_LOCK_WAIT_TIMEOUT
+reap;
+# t2 update
+connection default;
+commit;
+disconnect conn1;
+drop table t;
+
+source include/wait_until_count_sessions.inc;
diff --git a/storage/tokudb/mysql-test/tokudb/t/nonflushing_analyze_debug.test b/storage/tokudb/mysql-test/tokudb/t/nonflushing_analyze_debug.test
new file mode 100644
index 00000000000..0c4c01b3dc0
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/t/nonflushing_analyze_debug.test
@@ -0,0 +1,10 @@
+--source include/have_debug_sync.inc
+--source include/have_tokudb.inc
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=TokuDB;
+INSERT INTO t1 VALUES (1), (2), (3);
+
+--let $percona_nonflushing_analyze_table= t1
+--source include/percona_nonflushing_analyze_debug.inc
+
+DROP TABLE t1;
diff --git a/storage/tokudb/mysql-test/tokudb/t/row_format.test b/storage/tokudb/mysql-test/tokudb/t/row_format.test
index 6533f8c06be..9c5c6e6403e 100644
--- a/storage/tokudb/mysql-test/tokudb/t/row_format.test
+++ b/storage/tokudb/mysql-test/tokudb/t/row_format.test
@@ -12,6 +12,27 @@ CREATE TABLE tokudb_row_format_test_6 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_LZ
CREATE TABLE tokudb_row_format_test_7 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_QUICKLZ;
CREATE TABLE tokudb_row_format_test_8 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_SNAPPY;
+# TDB-76 : CREATE TABLE ... LIKE ... does not use source row_format on target table
+CREATE TABLE tdb76_1 LIKE tokudb_row_format_test_1;
+CREATE TABLE tdb76_2 LIKE tokudb_row_format_test_2;
+CREATE TABLE tdb76_3 LIKE tokudb_row_format_test_3;
+CREATE TABLE tdb76_4 LIKE tokudb_row_format_test_4;
+CREATE TABLE tdb76_5 LIKE tokudb_row_format_test_5;
+CREATE TABLE tdb76_6 LIKE tokudb_row_format_test_6;
+CREATE TABLE tdb76_7 LIKE tokudb_row_format_test_7;
+CREATE TABLE tdb76_8 LIKE tokudb_row_format_test_8;
+
+CREATE TABLE tdb76_compact(a INT) ENGINE=TokuDB ROW_FORMAT=COMPACT;
+CREATE TABLE tdb76_redundant(a INT) ENGINE=TokuDB ROW_FORMAT=REDUNDANT;
+CREATE TABLE tdb76_dynamic(a INT) ENGINE=TokuDB ROW_FORMAT=DYNAMIC;
+CREATE TABLE tdb76_compressed(a INT) ENGINE=TokuDB ROW_FORMAT=COMPRESSED;
+
+SELECT table_name, row_format, engine FROM information_schema.tables WHERE table_name like 'tdb76_%' ORDER BY table_name;
+
+DROP TABLE tdb76_1, tdb76_2, tdb76_3, tdb76_4, tdb76_5, tdb76_6, tdb76_7, tdb76_8, tdb76_compact, tdb76_redundant, tdb76_dynamic, tdb76_compressed;
+
+
+
SELECT table_name, row_format, engine FROM information_schema.tables WHERE table_name like 'tokudb_row_format_test%' ORDER BY table_name;
ALTER TABLE tokudb_row_format_test_1 ENGINE=TokuDB ROW_FORMAT=TOKUDB_FAST;
diff --git a/storage/tokudb/mysql-test/tokudb/t/tokudb_support_xa.test b/storage/tokudb/mysql-test/tokudb/t/tokudb_support_xa.test
index f0ad03b91ee..fa1efde7cf7 100644
--- a/storage/tokudb/mysql-test/tokudb/t/tokudb_support_xa.test
+++ b/storage/tokudb/mysql-test/tokudb/t/tokudb_support_xa.test
@@ -39,7 +39,7 @@ SET @@session.tokudb_support_xa = 1.6;
SET @@session.tokudb_support_xa = "T";
--Error ER_WRONG_VALUE_FOR_VAR
SET @@session.tokudb_support_xa = "Y";
-SET @@session.tokudb_support_xa = OF;
+SET @@session.tokudb_support_xa = OFF;
SELECT @@session.tokudb_support_xa;
# for global
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result
index 5ba5da21789..caaa963c325 100644
--- a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result
+++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result
@@ -17,5 +17,5 @@ test.t analyze status OK
show indexes from t;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t 0 PRIMARY 1 id A 7 NULL NULL BTREE
-t 1 x 1 x A 3 NULL NULL YES BTREE
+t 1 x 1 x A 7 NULL NULL YES BTREE
drop table t;
diff --git a/storage/tokudb/mysql-test/tokudb_parts/disabled.def b/storage/tokudb/mysql-test/tokudb_parts/disabled.def
index 3252a463176..17a8ddcc12e 100644
--- a/storage/tokudb/mysql-test/tokudb_parts/disabled.def
+++ b/storage/tokudb/mysql-test/tokudb_parts/disabled.def
@@ -7,3 +7,4 @@ partition_max_sub_parts_key_list_tokudb: 5.6 test not merged yet
partition_max_sub_parts_key_range_tokudb: 5.6 test not merged yet
partition_max_sub_parts_list_tokudb: 5.6 test not merged yet
partition_max_sub_parts_range_tokudb: 5.6 test not merged yet
+nonflushing_analyze_debug: Freezes in MariaDB 10.0
diff --git a/storage/tokudb/mysql-test/tokudb_parts/r/nonflushing_analyze_debug.result b/storage/tokudb/mysql-test/tokudb_parts/r/nonflushing_analyze_debug.result
new file mode 100644
index 00000000000..5a7bfb369df
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_parts/r/nonflushing_analyze_debug.result
@@ -0,0 +1,50 @@
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=TokuDB
+PARTITION BY RANGE (a) (
+PARTITION p0 VALUES LESS THAN (3),
+PARTITION p1 VALUES LESS THAN (10));
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan";
+SELECT * FROM t1;
+SET DEBUG_SYNC="now WAIT_FOR idx_scan_in_progress";
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+SELECT * FROM t1;
+a
+1
+2
+3
+4
+SET DEBUG_SYNC="now SIGNAL finish_scan";
+a
+1
+2
+3
+4
+DROP TABLE t1;
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=TokuDB
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH (A)
+SUBPARTITIONS 2 (
+PARTITION p0 VALUES LESS THAN (3),
+PARTITION p1 VALUES LESS THAN (10));
+INSERT INTO t2 VALUES (1), (2), (3), (4);
+SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan";
+SELECT * FROM t2;
+SET DEBUG_SYNC="now WAIT_FOR idx_scan_in_progress";
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+SELECT * FROM t2;
+a
+2
+1
+4
+3
+SET DEBUG_SYNC="now SIGNAL finish_scan";
+a
+2
+1
+4
+3
+DROP TABLE t2;
diff --git a/storage/tokudb/mysql-test/tokudb_parts/t/nonflushing_analyze_debug.test b/storage/tokudb/mysql-test/tokudb_parts/t/nonflushing_analyze_debug.test
new file mode 100644
index 00000000000..c99206acfe3
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_parts/t/nonflushing_analyze_debug.test
@@ -0,0 +1,29 @@
+--source include/have_debug_sync.inc
+--source include/have_tokudb.inc
+--source include/have_partition.inc
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=TokuDB
+ PARTITION BY RANGE (a) (
+ PARTITION p0 VALUES LESS THAN (3),
+ PARTITION p1 VALUES LESS THAN (10));
+
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+
+--let $percona_nonflushing_analyze_table= t1
+--source include/percona_nonflushing_analyze_debug.inc
+
+DROP TABLE t1;
+
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=TokuDB
+ PARTITION BY RANGE (a)
+ SUBPARTITION BY HASH (A)
+ SUBPARTITIONS 2 (
+ PARTITION p0 VALUES LESS THAN (3),
+ PARTITION p1 VALUES LESS THAN (10));
+
+INSERT INTO t2 VALUES (1), (2), (3), (4);
+
+--let $percona_nonflushing_analyze_table= t2
+--source include/percona_nonflushing_analyze_debug.inc
+
+DROP TABLE t2;
diff --git a/storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_tokudb-master.opt
index d57f32b54fb..43fac202fd4 100644
--- a/storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_tokudb-master.opt
+++ b/storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_tokudb-master.opt
@@ -1 +1 @@
---innodb-file-format-check --innodb-file-per-table=1
+--innodb-file-per-table=1
diff --git a/storage/tokudb/mysql-test/tokudb_perfschema/r/crash_tokudb.result b/storage/tokudb/mysql-test/tokudb_perfschema/r/crash_tokudb.result
new file mode 100644
index 00000000000..189d6bef14e
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_perfschema/r/crash_tokudb.result
@@ -0,0 +1,30 @@
+SELECT COUNT(*) > 0 FROM performance_schema.setup_consumers
+WHERE ENABLED = "NO";
+COUNT(*) > 0
+0
+SELECT COUNT(*) > 0 FROM performance_schema.setup_instruments
+WHERE NAME LIKE "%/fti/%" AND (ENABLED = 'NO' OR TIMED = "NO");
+COUNT(*) > 0
+0
+CREATE TABLE t(a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE=TokuDB;
+INSERT INTO t (b) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+INSERT INTO t (b) SELECT b FROM t;
+UPDATE t SET b = 11 WHERE b = 10;
+DELETE FROM t WHERE b = 1;
+ALTER TABLE t ADD COLUMN c CHAR(10) default NULL;
+TRUNCATE TABLE t;
+RENAME TABLE t TO t1;
+RENAME TABLE t1 TO t;
+SELECT COUNT(*) > 0 FROM t;
+COUNT(*) > 0
+0
+DROP TABLE t;
diff --git a/storage/tokudb/mysql-test/tokudb_perfschema/r/start_server_tokudb.result b/storage/tokudb/mysql-test/tokudb_perfschema/r/start_server_tokudb.result
new file mode 100644
index 00000000000..2e220916ec3
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_perfschema/r/start_server_tokudb.result
@@ -0,0 +1,114 @@
+show databases;
+Database
+information_schema
+mtr
+mysql
+performance_schema
+test
+select count(*) from performance_schema.performance_timers;
+count(*)
+5
+select count(*) from performance_schema.setup_consumers;
+count(*)
+12
+select count(*) > 3 from performance_schema.setup_instruments;
+count(*) > 3
+1
+select count(*) from performance_schema.setup_timers;
+count(*)
+4
+select * from performance_schema.accounts;
+select * from performance_schema.cond_instances;
+select * from performance_schema.events_stages_current;
+select * from performance_schema.events_stages_history;
+select * from performance_schema.events_stages_history_long;
+select * from performance_schema.events_stages_summary_by_account_by_event_name;
+select * from performance_schema.events_stages_summary_by_host_by_event_name;
+select * from performance_schema.events_stages_summary_by_thread_by_event_name;
+select * from performance_schema.events_stages_summary_by_user_by_event_name;
+select * from performance_schema.events_stages_summary_global_by_event_name;
+select * from performance_schema.events_statements_current;
+select * from performance_schema.events_statements_history;
+select * from performance_schema.events_statements_history_long;
+select * from performance_schema.events_statements_summary_by_account_by_event_name;
+select * from performance_schema.events_statements_summary_by_digest;
+select * from performance_schema.events_statements_summary_by_host_by_event_name;
+select * from performance_schema.events_statements_summary_by_thread_by_event_name;
+select * from performance_schema.events_statements_summary_by_user_by_event_name;
+select * from performance_schema.events_statements_summary_global_by_event_name;
+select * from performance_schema.events_waits_current;
+select * from performance_schema.events_waits_history;
+select * from performance_schema.events_waits_history_long;
+select * from performance_schema.events_waits_summary_by_account_by_event_name;
+select * from performance_schema.events_waits_summary_by_host_by_event_name;
+select * from performance_schema.events_waits_summary_by_instance;
+select * from performance_schema.events_waits_summary_by_thread_by_event_name;
+select * from performance_schema.events_waits_summary_by_user_by_event_name;
+select * from performance_schema.events_waits_summary_global_by_event_name;
+select * from performance_schema.file_instances;
+select * from performance_schema.file_summary_by_event_name;
+select * from performance_schema.file_summary_by_instance;
+select * from performance_schema.host_cache;
+select * from performance_schema.hosts;
+select * from performance_schema.mutex_instances;
+select * from performance_schema.objects_summary_global_by_type;
+select * from performance_schema.performance_timers;
+select * from performance_schema.rwlock_instances;
+select * from performance_schema.session_account_connect_attrs;
+select * from performance_schema.session_connect_attrs;
+select * from performance_schema.setup_actors;
+select * from performance_schema.setup_consumers;
+select * from performance_schema.setup_instruments;
+select * from performance_schema.setup_objects;
+select * from performance_schema.setup_timers;
+select * from performance_schema.socket_instances;
+select * from performance_schema.socket_summary_by_instance;
+select * from performance_schema.socket_summary_by_event_name;
+select * from performance_schema.table_io_waits_summary_by_index_usage;
+select * from performance_schema.table_io_waits_summary_by_table;
+select * from performance_schema.table_lock_waits_summary_by_table;
+select * from performance_schema.threads;
+select * from performance_schema.users;
+show variables where
+`Variable_name` != "performance_schema_max_statement_classes" and
+`Variable_name` like "performance_schema%";
+Variable_name Value
+performance_schema ON
+performance_schema_accounts_size 100
+performance_schema_digests_size 200
+performance_schema_events_stages_history_long_size 1000
+performance_schema_events_stages_history_size 10
+performance_schema_events_statements_history_long_size 1000
+performance_schema_events_statements_history_size 10
+performance_schema_events_waits_history_long_size 10000
+performance_schema_events_waits_history_size 10
+performance_schema_hosts_size 100
+performance_schema_max_cond_classes 80
+performance_schema_max_cond_instances 1000
+performance_schema_max_digest_length 1024
+performance_schema_max_file_classes 50
+performance_schema_max_file_handles 32768
+performance_schema_max_file_instances 10000
+performance_schema_max_mutex_classes 200
+performance_schema_max_mutex_instances 5000
+performance_schema_max_rwlock_classes 40
+performance_schema_max_rwlock_instances 5000
+performance_schema_max_socket_classes 10
+performance_schema_max_socket_instances 1000
+performance_schema_max_stage_classes 150
+performance_schema_max_table_handles 1000
+performance_schema_max_table_instances 500
+performance_schema_max_thread_classes 50
+performance_schema_max_thread_instances 200
+performance_schema_session_connect_attrs_size 2048
+performance_schema_setup_actors_size 100
+performance_schema_setup_objects_size 100
+performance_schema_users_size 100
+show engine PERFORMANCE_SCHEMA status;
+show status like "performance_schema%";
+SELECT COUNT(NAME) > 0 FROM performance_schema.setup_instruments WHERE NAME LIKE "%/fti/%";
+COUNT(NAME) > 0
+1
+SELECT COUNT(NAME) > 0 FROM performance_schema.threads WHERE NAME LIKE "%kibbutz%";
+COUNT(NAME) > 0
+1
diff --git a/storage/tokudb/mysql-test/tokudb_perfschema/t/crash_tokudb.test b/storage/tokudb/mysql-test/tokudb_perfschema/t/crash_tokudb.test
new file mode 100644
index 00000000000..31757a20259
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_perfschema/t/crash_tokudb.test
@@ -0,0 +1,36 @@
+# TokuDB PFS crash test:
+# Make sure FTI instrumentation is on, execute base DDL, DML queries
+# and make sure there is no crash.
+
+--source include/not_embedded.inc
+--source include/have_perfschema.inc
+--source include/have_tokudb.inc
+
+SELECT COUNT(*) > 0 FROM performance_schema.setup_consumers
+ WHERE ENABLED = "NO";
+SELECT COUNT(*) > 0 FROM performance_schema.setup_instruments
+ WHERE NAME LIKE "%/fti/%" AND (ENABLED = 'NO' OR TIMED = "NO");
+
+CREATE TABLE t(a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE=TokuDB;
+INSERT INTO t (b) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+INSERT INTO t (b) SELECT b FROM t;
+
+UPDATE t SET b = 11 WHERE b = 10;
+DELETE FROM t WHERE b = 1;
+
+ALTER TABLE t ADD COLUMN c CHAR(10) default NULL;
+TRUNCATE TABLE t;
+RENAME TABLE t TO t1;
+RENAME TABLE t1 TO t;
+
+SELECT COUNT(*) > 0 FROM t;
+DROP TABLE t;
diff --git a/storage/tokudb/mysql-test/tokudb_perfschema/t/start_server_tokudb.test b/storage/tokudb/mysql-test/tokudb_perfschema/t/start_server_tokudb.test
new file mode 100644
index 00000000000..4034fba0549
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_perfschema/t/start_server_tokudb.test
@@ -0,0 +1,10 @@
+# Tests for PERFORMANCE_SCHEMA
+
+--source include/not_embedded.inc
+--source include/have_perfschema.inc
+--source include/have_tokudb.inc
+
+--source ../../perfschema/include/start_server_common.inc
+
+SELECT COUNT(NAME) > 0 FROM performance_schema.setup_instruments WHERE NAME LIKE "%/fti/%";
+SELECT COUNT(NAME) > 0 FROM performance_schema.threads WHERE NAME LIKE "%kibbutz%";
diff --git a/storage/tokudb/mysql-test/tokudb_perfschema/t/suite.opt b/storage/tokudb/mysql-test/tokudb_perfschema/t/suite.opt
new file mode 100644
index 00000000000..6d826fe91d1
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_perfschema/t/suite.opt
@@ -0,0 +1 @@
+--loose-enable-performance-schema $TOKUDB_OPT $TOKUDB_LOAD_ADD --loose-tokudb-check-jemalloc=0 --loose-tokudb-cache-size=512M --loose-tokudb-block-size=1M
diff --git a/storage/tokudb/tokudb_background.cc b/storage/tokudb/tokudb_background.cc
index e019e41c788..13e0e9321cc 100644
--- a/storage/tokudb/tokudb_background.cc
+++ b/storage/tokudb/tokudb_background.cc
@@ -66,13 +66,13 @@ void job_manager_t::destroy() {
_sem.set_interrupt();
while (_background_jobs.size()) {
- _mutex.lock();
+ mutex_t_lock(_mutex);
job_t* job = _background_jobs.front();
if (!job->cancelled())
cancel(job);
_background_jobs.pop_front();
delete job;
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
}
void* result;
@@ -83,7 +83,7 @@ bool job_manager_t::run_job(job_t* newjob, bool background) {
bool ret = false;
const char* jobkey = newjob->key();
- _mutex.lock();
+ mutex_t_lock(_mutex);
assert_always(!_shutdown);
for (jobs_t::iterator it = _background_jobs.begin();
@@ -138,15 +138,16 @@ bool job_manager_t::run_job(job_t* newjob, bool background) {
}
cleanup:
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
return ret;
}
bool job_manager_t::cancel_job(const char* key) {
bool ret = false;
- _mutex.lock();
+ mutex_t_lock(_mutex);
for (jobs_t::iterator it = _background_jobs.begin();
- it != _background_jobs.end(); it++) {
+ it != _background_jobs.end();
+ it++) {
job_t* job = *it;
if (!job->cancelled() && strcmp(job->key(), key) == 0) {
@@ -155,12 +156,11 @@ bool job_manager_t::cancel_job(const char* key) {
}
}
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
return ret;
}
void job_manager_t::iterate_jobs(pfn_iterate_t callback, void* extra) const {
-
- _mutex.lock();
+ mutex_t_lock(_mutex);
for (jobs_t::const_iterator it = _background_jobs.begin();
it != _background_jobs.end();
@@ -171,7 +171,7 @@ void job_manager_t::iterate_jobs(pfn_iterate_t callback, void* extra) const {
}
}
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
}
void* job_manager_t::thread_func(void* v) {
return ((tokudb::background::job_manager_t*)v)->real_thread_func();
@@ -189,14 +189,14 @@ void* job_manager_t::real_thread_func() {
tokudb::time::sleep_microsec(250000);
continue;
}
-#endif // TOKUDB_DEBUG
+#endif // TOKUDB_DEBUG
- _mutex.lock();
+ mutex_t_lock(_mutex);
assert_debug(_background_jobs.size() > 0);
job_t* job = _background_jobs.front();
run(job);
_background_jobs.pop_front();
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
delete job;
}
}
@@ -205,11 +205,11 @@ void* job_manager_t::real_thread_func() {
void job_manager_t::run(job_t* job) {
assert_debug(_mutex.is_owned_by_me());
if (!job->cancelled()) {
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
// do job
job->run();
// done job
- _mutex.lock();
+ mutex_t_lock(_mutex);
}
if (!job->cancelled()) {
job->destroy();
diff --git a/storage/tokudb/tokudb_background.h b/storage/tokudb/tokudb_background.h
index 29991ab325d..bf5eb97a619 100644
--- a/storage/tokudb/tokudb_background.h
+++ b/storage/tokudb/tokudb_background.h
@@ -174,11 +174,11 @@ bool destroy();
inline void job_manager_t::lock() {
assert_debug(!_mutex.is_owned_by_me());
- _mutex.lock();
+ mutex_t_lock(_mutex);
}
inline void job_manager_t::unlock() {
assert_debug(_mutex.is_owned_by_me());
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
}
inline void job_manager_t::job_t::run() {
diff --git a/storage/tokudb/tokudb_information_schema.cc b/storage/tokudb/tokudb_information_schema.cc
index 5cd0609ac74..bb263d5f960 100644
--- a/storage/tokudb/tokudb_information_schema.cc
+++ b/storage/tokudb/tokudb_information_schema.cc
@@ -99,7 +99,7 @@ int trx_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) {
TOKUDB_DBUG_ENTER("");
int error;
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -234,7 +234,7 @@ int lock_waits_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) {
TOKUDB_DBUG_ENTER("");
int error;
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -377,7 +377,7 @@ int locks_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) {
TOKUDB_DBUG_ENTER("");
int error;
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -521,7 +521,7 @@ int file_map_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) {
int error;
TABLE* table = tables->table;
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -728,7 +728,7 @@ int fractal_tree_info_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) {
// 3938: Get a read lock on the status flag, since we must
// read it before safely proceeding
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -1025,7 +1025,7 @@ int fractal_tree_block_map_fill_table(
// 3938: Get a read lock on the status flag, since we must
// read it before safely proceeding
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -1162,7 +1162,7 @@ int background_job_status_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) {
int error;
TABLE* table = tables->table;
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
diff --git a/storage/tokudb/tokudb_thread.cc b/storage/tokudb/tokudb_thread.cc
index f27e803a065..6fc1191975d 100644
--- a/storage/tokudb/tokudb_thread.cc
+++ b/storage/tokudb/tokudb_thread.cc
@@ -29,6 +29,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
namespace tokudb {
namespace thread {
+const pfs_key_t pfs_not_instrumented = 0xFFFFFFFF;
pthread_t mutex_t::_null_owner = 0;
} // namespace thread
diff --git a/storage/tokudb/tokudb_thread.h b/storage/tokudb/tokudb_thread.h
index 72eb17ea05a..0be5583ffb2 100644
--- a/storage/tokudb/tokudb_thread.h
+++ b/storage/tokudb/tokudb_thread.h
@@ -34,95 +34,68 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
namespace tokudb {
namespace thread {
-#if (defined(__MACH__) || defined(__APPLE__)) && _POSIX_TIMERS <= 0
-
-#define _x_min(a, b) ((a) < (b) ? (a) : (b))
-
-#define timed_lock_define(timed_func_name, lock_type_name, lock_func_name) \
-inline int timed_func_name(lock_type_name *mutex, \
- const struct timespec *abs_timeout) { \
- int pthread_rc; \
- struct timespec remaining, slept, ts; \
- static const int sleep_step = 1000000; \
- \
- remaining = *abs_timeout; \
- while ((pthread_rc = lock_func_name(mutex)) == EBUSY) { \
- ts.tv_sec = 0; \
- ts.tv_nsec = (remaining.tv_sec > 0 ? \
- sleep_step : \
- _x_min(remaining.tv_nsec,sleep_step)); \
- nanosleep(&ts, &slept); \
- ts.tv_nsec -= slept.tv_nsec; \
- if (ts.tv_nsec <= remaining.tv_nsec) { \
- remaining.tv_nsec -= ts.tv_nsec; \
- } else { \
- remaining.tv_sec--; \
- remaining.tv_nsec = \
- (sleep_step - (ts.tv_nsec - remaining.tv_nsec)); \
- } \
- if (remaining.tv_sec < 0 || \
- (!remaining.tv_sec && remaining.tv_nsec <= 0)) { \
- return ETIMEDOUT; \
- } \
- } \
- \
- return pthread_rc; \
-}
-
-timed_lock_define(pthread_mutex_timedlock,
- pthread_mutex_t,
- pthread_mutex_trylock);
-
-timed_lock_define(pthread_rwlock_timedrdlock,
- pthread_rwlock_t,
- pthread_rwlock_tryrdlock);
-
-timed_lock_define(pthread_rwlock_timedwrlock,
- pthread_rwlock_t,
- pthread_rwlock_trywrlock);
-
-#endif //(defined(__MACH__) || defined(__APPLE__)) && _POSIX_TIMERS <= 0
+extern const pfs_key_t pfs_not_instrumented;
uint my_tid(void);
// Your basic mutex
class mutex_t {
public:
- mutex_t(void);
+ explicit mutex_t(pfs_key_t key);
+ mutex_t(void) : mutex_t(pfs_not_instrumented) {}
~mutex_t(void);
- void lock(void);
- int lock(ulonglong microseconds);
- void unlock(void);
+ void reinit(pfs_key_t key);
+ void lock(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_MUTEX_INTERFACE
+ );
+ void unlock(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_MUTEX_INTERFACE
+ );
#ifdef TOKUDB_DEBUG
bool is_owned_by_me(void) const;
#endif
private:
static pthread_t _null_owner;
- pthread_mutex_t _mutex;
+ mysql_mutex_t _mutex;
#ifdef TOKUDB_DEBUG
- uint _owners;
- pthread_t _owner;
+ uint _owners;
+ pthread_t _owner;
#endif
};
// Simple read write lock
class rwlock_t {
public:
- rwlock_t(void);
+ explicit rwlock_t(pfs_key_t key);
+ rwlock_t(void) : rwlock_t(pfs_not_instrumented) {}
~rwlock_t(void);
- void lock_read(void);
- int lock_read(ulonglong microseconds);
- void lock_write(void);
- int lock_write(ulonglong microseconds);
+ void lock_read(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ );
+ void lock_write(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ );
void unlock(void);
private:
rwlock_t(const rwlock_t&);
rwlock_t& operator=(const rwlock_t&);
- pthread_rwlock_t _rwlock;
+ mysql_rwlock_t _rwlock;
};
// Simple event signal/wait class
@@ -224,57 +197,76 @@ private:
pthread_t _thread;
};
+inline uint my_tid(void) { return (uint)toku_os_gettid(); }
-inline uint my_tid(void) {
- return (uint)toku_os_gettid();
-}
-
-
-inline mutex_t::mutex_t(void) {
- #ifdef TOKUDB_DEBUG
- _owners = 0;
- _owner = _null_owner;
- #endif
- int r __attribute__((unused)) = pthread_mutex_init(&_mutex, MY_MUTEX_INIT_FAST);
+inline mutex_t::mutex_t(pfs_key_t key) {
+#ifdef TOKUDB_DEBUG
+ _owners = 0;
+ _owner = _null_owner;
+#endif
+ int r MY_ATTRIBUTE((unused)) = mysql_mutex_init(key, &_mutex, MY_MUTEX_INIT_FAST);
assert_debug(r == 0);
}
-inline mutex_t::~mutex_t(void) {
- #ifdef TOKUDB_DEBUG
- assert_debug(_owners == 0);
- #endif
- int r __attribute__((unused)) = pthread_mutex_destroy(&_mutex);
+inline mutex_t::~mutex_t() {
+#ifdef TOKUDB_DEBUG
+ assert_debug(_owners == 0);
+#endif
+ int r MY_ATTRIBUTE((unused)) = mysql_mutex_destroy(&_mutex);
assert_debug(r == 0);
}
-inline void mutex_t::lock(void) {
- assert_debug(is_owned_by_me() == false);
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+inline void mutex_t::reinit(pfs_key_t key) {
+#ifdef TOKUDB_DEBUG
+ assert_debug(_owners == 0);
+#endif
+ int r MY_ATTRIBUTE((unused));
+ r = mysql_mutex_destroy(&_mutex);
+ assert_debug(r == 0);
+ r = mysql_mutex_init(key, &_mutex, MY_MUTEX_INIT_FAST);
assert_debug(r == 0);
- #ifdef TOKUDB_DEBUG
- _owners++;
- _owner = pthread_self();
- #endif
}
-inline int mutex_t::lock(ulonglong microseconds) {
+inline void mutex_t::lock(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_MUTEX_INTERFACE
+ ) {
assert_debug(is_owned_by_me() == false);
- timespec waittime = time::offset_timespec(microseconds);
- int r = pthread_mutex_timedlock(&_mutex, &waittime);
- #ifdef TOKUDB_DEBUG
- if (r == 0) {
- _owners++;
- _owner = pthread_self();
- }
- #endif
- assert_debug(r == 0 || r == ETIMEDOUT);
- return r;
+ int r MY_ATTRIBUTE((unused)) = inline_mysql_mutex_lock(&_mutex
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ ,
+ src_file,
+ src_line
+#endif // HAVE_PSI_MUTEX_INTERFACE
+ );
+ assert_debug(r == 0);
+#ifdef TOKUDB_DEBUG
+ _owners++;
+ _owner = pthread_self();
+#endif
}
-inline void mutex_t::unlock(void) {
- #ifdef TOKUDB_DEBUG
- assert_debug(_owners > 0);
- assert_debug(is_owned_by_me());
- _owners--;
- _owner = _null_owner;
- #endif
- int r __attribute__((unused)) = pthread_mutex_unlock(&_mutex);
+inline void mutex_t::unlock(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_MUTEX_INTERFACE
+ ) {
+#ifndef SAFE_MUTEX
+ (void)(src_file);
+ (void)(src_line);
+#endif // SAFE_MUTEX
+#ifdef TOKUDB_DEBUG
+ assert_debug(_owners > 0);
+ assert_debug(is_owned_by_me());
+ _owners--;
+ _owner = _null_owner;
+#endif
+ int r MY_ATTRIBUTE((unused)) = inline_mysql_mutex_unlock(&_mutex
+#ifdef SAFE_MUTEX
+ ,
+ src_file,
+ src_line
+#endif // SAFE_MUTEX
+ );
assert_debug(r == 0);
}
#ifdef TOKUDB_DEBUG
@@ -283,44 +275,28 @@ inline bool mutex_t::is_owned_by_me(void) const {
}
#endif
-
-inline rwlock_t::rwlock_t(void) {
- int r __attribute__((unused)) = pthread_rwlock_init(&_rwlock, NULL);
- assert_debug(r == 0);
-}
-inline rwlock_t::~rwlock_t(void) {
- int r __attribute__((unused)) = pthread_rwlock_destroy(&_rwlock);
+inline rwlock_t::rwlock_t(pfs_key_t key) {
+ int r MY_ATTRIBUTE((unused)) = mysql_rwlock_init(key, &_rwlock);
assert_debug(r == 0);
}
-inline void rwlock_t::lock_read(void) {
- int r;
- while ((r = pthread_rwlock_rdlock(&_rwlock)) != 0) {
- if (r == EBUSY || r == EAGAIN) {
- time::sleep_microsec(1000);
- continue;
- }
- break;
- }
- assert_debug(r == 0);
-}
-inline int rwlock_t::lock_read(ulonglong microseconds) {
- int r;
- timespec waittime = time::offset_timespec(microseconds);
- while ((r = pthread_rwlock_timedrdlock(&_rwlock, &waittime)) != 0) {
- if (r == EBUSY || r == EAGAIN) {
- time::sleep_microsec(1000);
- continue;
- } else if (r == ETIMEDOUT) {
- return ETIMEDOUT;
- }
- break;
- }
+inline rwlock_t::~rwlock_t() {
+ int r MY_ATTRIBUTE((unused)) = mysql_rwlock_destroy(&_rwlock);
assert_debug(r == 0);
- return r;
}
-inline void rwlock_t::lock_write(void) {
+inline void rwlock_t::lock_read(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ ) {
int r;
- while ((r = pthread_rwlock_wrlock(&_rwlock)) != 0) {
+ while ((r = inline_mysql_rwlock_rdlock(&_rwlock
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ ,
+ src_file,
+ src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ )) != 0) {
if (r == EBUSY || r == EAGAIN) {
time::sleep_microsec(1000);
continue;
@@ -329,27 +305,33 @@ inline void rwlock_t::lock_write(void) {
}
assert_debug(r == 0);
}
-inline int rwlock_t::lock_write(ulonglong microseconds) {
+inline void rwlock_t::lock_write(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ ) {
int r;
- timespec waittime = time::offset_timespec(microseconds);
- while ((r = pthread_rwlock_timedwrlock(&_rwlock, &waittime)) != 0) {
+ while ((r = inline_mysql_rwlock_wrlock(&_rwlock
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ ,
+ src_file,
+ src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ )) != 0) {
if (r == EBUSY || r == EAGAIN) {
time::sleep_microsec(1000);
continue;
- } else if (r == ETIMEDOUT) {
- return ETIMEDOUT;
}
break;
}
assert_debug(r == 0);
- return r;
}
inline void rwlock_t::unlock(void) {
- int r __attribute__((unused)) = pthread_rwlock_unlock(&_rwlock);
+ int r MY_ATTRIBUTE((unused)) = mysql_rwlock_unlock(&_rwlock);
assert_debug(r == 0);
}
-inline rwlock_t::rwlock_t(const rwlock_t&) {
-}
+inline rwlock_t::rwlock_t(const rwlock_t&) {}
inline rwlock_t& rwlock_t::operator=(const rwlock_t&) {
return *this;
}
@@ -358,7 +340,7 @@ inline rwlock_t& rwlock_t::operator=(const rwlock_t&) {
inline event_t::event_t(bool create_signalled, bool manual_reset) :
_manual_reset(manual_reset) {
- int __attribute__((unused)) r = pthread_mutex_init(&_mutex, NULL);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_init(&_mutex, NULL);
assert_debug(r == 0);
r = pthread_cond_init(&_cond, NULL);
assert_debug(r == 0);
@@ -370,13 +352,13 @@ inline event_t::event_t(bool create_signalled, bool manual_reset) :
_pulsed = false;
}
inline event_t::~event_t(void) {
- int r __attribute__((unused)) = pthread_mutex_destroy(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_destroy(&_mutex);
assert_debug(r == 0);
r = pthread_cond_destroy(&_cond);
assert_debug(r == 0);
}
inline void event_t::wait(void) {
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
while (_signalled == false && _pulsed == false) {
r = pthread_cond_wait(&_cond, &_mutex);
@@ -413,7 +395,7 @@ inline int event_t::wait(ulonglong microseconds) {
return 0;
}
inline void event_t::signal(void) {
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_signalled = true;
if (_manual_reset) {
@@ -427,7 +409,7 @@ inline void event_t::signal(void) {
assert_debug(r == 0);
}
inline void event_t::pulse(void) {
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_pulsed = true;
r = pthread_cond_signal(&_cond);
@@ -437,7 +419,7 @@ inline void event_t::pulse(void) {
}
inline bool event_t::signalled(void) {
bool ret = false;
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
ret = _signalled;
r = pthread_mutex_unlock(&_mutex);
@@ -445,7 +427,7 @@ inline bool event_t::signalled(void) {
return ret;
}
inline void event_t::reset(void) {
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_signalled = false;
_pulsed = false;
@@ -467,21 +449,21 @@ inline semaphore_t::semaphore_t(
_initial_count(initial_count),
_max_count(max_count) {
- int r __attribute__((unused)) = pthread_mutex_init(&_mutex, NULL);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_init(&_mutex, NULL);
assert_debug(r == 0);
r = pthread_cond_init(&_cond, NULL);
assert_debug(r == 0);
_signalled = _initial_count;
}
inline semaphore_t::~semaphore_t(void) {
- int r __attribute__((unused)) = pthread_mutex_destroy(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_destroy(&_mutex);
assert_debug(r == 0);
r = pthread_cond_destroy(&_cond);
assert_debug(r == 0);
}
inline semaphore_t::E_WAIT semaphore_t::wait(void) {
E_WAIT ret;
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
while (_signalled == 0 && _interrupted == false) {
r = pthread_cond_wait(&_cond, &_mutex);
@@ -524,7 +506,7 @@ inline semaphore_t::E_WAIT semaphore_t::wait(ulonglong microseconds) {
}
inline bool semaphore_t::signal(void) {
bool ret = false;
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
if (_signalled < _max_count) {
_signalled++;
@@ -538,7 +520,7 @@ inline bool semaphore_t::signal(void) {
}
inline int semaphore_t::signalled(void) {
int ret = 0;
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
ret = _signalled;
r = pthread_mutex_unlock(&_mutex);
@@ -546,7 +528,7 @@ inline int semaphore_t::signalled(void) {
return ret;
}
inline void semaphore_t::reset(void) {
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_signalled = 0;
r = pthread_mutex_unlock(&_mutex);
@@ -554,7 +536,7 @@ inline void semaphore_t::reset(void) {
return;
}
inline void semaphore_t::set_interrupt(void) {
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_interrupted = true;
r = pthread_cond_broadcast(&_cond);
@@ -563,7 +545,7 @@ inline void semaphore_t::set_interrupt(void) {
assert_debug(r == 0);
}
inline void semaphore_t::clear_interrupt(void) {
- int r __attribute__((unused)) = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_interrupted = false;
r = pthread_mutex_unlock(&_mutex);
diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt
index 6d2190772c5..1f1e4635f31 100644
--- a/strings/CMakeLists.txt
+++ b/strings/CMakeLists.txt
@@ -20,7 +20,7 @@ SET(STRINGS_SOURCES bchange.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c
ctype-latin1.c ctype-mb.c ctype-simple.c ctype-sjis.c ctype-tis620.c ctype-uca.c
ctype-ucs2.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype.c decimal.c dtoa.c int2str.c
is_prefix.c llstr.c longlong2str.c my_strtoll10.c my_vsnprintf.c
- str2int.c str_alloc.c strcend.c strend.c strfill.c strmake.c strmov.c strnmov.c
+ str2int.c strcend.c strend.c strfill.c strmake.c strmov.c strnmov.c
strxmov.c strxnmov.c xml.c
strmov_overlapp.c
my_strchr.c strcont.c strappend.c json_lib.c)
@@ -34,4 +34,5 @@ ADD_DEFINITIONS(-DDISABLE_MYSQL_THREAD_H)
ADD_CONVENIENCE_LIBRARY(strings ${STRINGS_SOURCES})
ADD_EXECUTABLE(conf_to_src EXCLUDE_FROM_ALL conf_to_src.c)
-TARGET_LINK_LIBRARIES(conf_to_src strings)
+SET_TARGET_PROPERTIES(conf_to_src PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
+TARGET_LINK_LIBRARIES(conf_to_src mysys strings)
diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c
index 0bbbd282530..612fdbab38c 100644
--- a/strings/ctype-bin.c
+++ b/strings/ctype-bin.c
@@ -402,7 +402,7 @@ my_strnxfrm_8bit_bin(CHARSET_INFO *cs,
if (dst != src)
memcpy(dst, src, srclen);
return my_strxfrm_pad_desc_and_reverse(cs, dst, dst + srclen, dst + dstlen,
- nweights - srclen, flags, 0);
+ (uint)(nweights - srclen), flags, 0);
}
@@ -416,7 +416,7 @@ my_strnxfrm_8bit_nopad_bin(CHARSET_INFO *cs,
if (dst != src)
memcpy(dst, src, srclen);
return my_strxfrm_pad_desc_and_reverse_nopad(cs, dst, dst + srclen,
- dst + dstlen, nweights - srclen,
+ dst + dstlen,(uint)(nweights - srclen),
flags, 0);
}
@@ -464,13 +464,13 @@ skip:
if (nmatch > 0)
{
match[0].beg= 0;
- match[0].end= (size_t) (str- (const uchar*)b-1);
+ match[0].end= (uint) (str- (const uchar*)b-1);
match[0].mb_len= match[0].end;
if (nmatch > 1)
{
match[1].beg= match[0].end;
- match[1].end= match[0].end+s_length;
+ match[1].end= (uint)(match[0].end+s_length);
match[1].mb_len= match[1].end-match[1].beg;
}
}
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index 9e476c23202..19caa22edb4 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -528,12 +528,12 @@ uint my_instr_mb(CHARSET_INFO *cs,
if (nmatch)
{
match[0].beg= 0;
- match[0].end= (size_t) (b-b0);
+ match[0].end= (uint) (b-b0);
match[0].mb_len= res;
if (nmatch > 1)
{
match[1].beg= match[0].end;
- match[1].end= match[0].end+s_length;
+ match[1].end= (uint)(match[0].end+s_length);
match[1].mb_len= 0; /* Not computed */
}
}
@@ -799,9 +799,9 @@ fill_max_and_min:
'a\0\0... is the smallest possible string when we have space expand
a\ff\ff... is the biggest possible string
*/
- *min_length= ((cs->state & MY_CS_BINSORT) ? (size_t) (min_str - min_org) :
- res_length);
- *max_length= res_length;
+ *min_length= (cs->state & (MY_CS_BINSORT | MY_CS_NOPAD)) ?
+ (size_t) (min_str - min_org) :
+ res_length;
/* Create min key */
do
{
@@ -1002,9 +1002,9 @@ my_like_range_generic(CHARSET_INFO *cs,
a\min\min... is the smallest possible string
a\max\max... is the biggest possible string
*/
- *min_length= ((cs->state & MY_CS_BINSORT) ?
+ *min_length= (cs->state & (MY_CS_BINSORT | MY_CS_NOPAD)) ?
(size_t) (min_str - min_org) :
- res_length);
+ res_length;
*max_length= res_length;
goto pad_min_max;
}
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index cf73f117f0f..d6e5f02d463 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -78,8 +78,8 @@ size_t my_strnxfrm_simple_internal(CHARSET_INFO * cs,
const uchar *map= cs->sort_order;
uchar *d0= dst;
uint frmlen;
- if ((frmlen= MY_MIN(dstlen, *nweights)) > srclen)
- frmlen= srclen;
+ if ((frmlen= (uint)MY_MIN(dstlen, *nweights)) > srclen)
+ frmlen= (uint)srclen;
if (dst != src)
{
const uchar *end;
@@ -321,7 +321,7 @@ size_t my_snprintf_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char* fmt, ...)
{
va_list args;
- int result;
+ size_t result;
va_start(args,fmt);
result= my_vsnprintf(to, n, fmt, args);
va_end(args);
@@ -1059,9 +1059,9 @@ my_bool my_like_range_simple(CHARSET_INFO *cs,
if (*ptr == w_many) /* '%' in SQL */
{
/* Calculate length of keys */
- *min_length= ((cs->state & MY_CS_BINSORT) ?
+ *min_length= (cs->state & (MY_CS_BINSORT | MY_CS_NOPAD)) ?
(size_t) (min_str - min_org) :
- res_length);
+ res_length;
*max_length= res_length;
do
{
@@ -1226,13 +1226,13 @@ skip:
if (nmatch > 0)
{
match[0].beg= 0;
- match[0].end= (size_t) (str- (const uchar*)b-1);
+ match[0].end= (uint) (str- (const uchar*)b-1);
match[0].mb_len= match[0].end;
if (nmatch > 1)
{
match[1].beg= match[0].end;
- match[1].end= match[0].end+s_length;
+ match[1].end= (uint)(match[0].end+s_length);
match[1].mb_len= match[1].end-match[1].beg;
}
}
diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c
index 4dbb66d89c5..bfd8b0db1d5 100644
--- a/strings/ctype-tis620.c
+++ b/strings/ctype-tis620.c
@@ -449,7 +449,7 @@ static const uchar sort_order_tis620[]=
static size_t thai2sortable(uchar *tstr, size_t len)
{
uchar *p;
- int tlen;
+ size_t tlen;
uchar l2bias;
tlen= len;
@@ -524,7 +524,7 @@ int my_strnncoll_tis620(CHARSET_INFO *cs __attribute__((unused)),
tc1= buf;
if ((len1 + len2 +2) > (int) sizeof(buf))
- tc1= (uchar*) my_str_malloc(len1+len2+2);
+ tc1= (uchar*) my_malloc(len1+len2+2, MYF(MY_FAE));
tc2= tc1 + len1+1;
memcpy((char*) tc1, (char*) s1, len1);
tc1[len1]= 0; /* if length(s1)> len1, need to put 'end of string' */
@@ -534,7 +534,7 @@ int my_strnncoll_tis620(CHARSET_INFO *cs __attribute__((unused)),
thai2sortable(tc2, len2);
i= strcmp((char*)tc1, (char*)tc2);
if (tc1 != buf)
- my_str_free(tc1);
+ my_free(tc1);
return i;
}
@@ -550,7 +550,7 @@ int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)),
a= buf;
if ((a_length + b_length +2) > (int) sizeof(buf))
- alloced= a= (uchar*) my_str_malloc(a_length+b_length+2);
+ alloced= a= (uchar*) my_malloc(a_length+b_length+2, MYF(MY_FAE));
b= a + a_length+1;
memcpy((char*) a, (char*) a0, a_length);
@@ -578,7 +578,7 @@ int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)),
ret:
if (alloced)
- my_str_free(alloced);
+ my_free(alloced);
return res;
}
@@ -609,10 +609,10 @@ my_strnxfrm_tis620(CHARSET_INFO *cs,
set_if_smaller(dstlen, nweights);
set_if_smaller(len, dstlen);
len= my_strxfrm_pad_desc_and_reverse(cs, dst, dst + len, dst + dstlen,
- dstlen - len, flags, 0);
+ (uint)(dstlen - len), flags, 0);
if ((flags & MY_STRXFRM_PAD_TO_MAXLEN) && len < dstlen0)
{
- uint fill_length= dstlen0 - len;
+ size_t fill_length= dstlen0 - len;
cs->cset->fill(cs, (char*) dst + len, fill_length, cs->pad_char);
len= dstlen0;
}
@@ -632,10 +632,10 @@ my_strnxfrm_tis620_nopad(CHARSET_INFO *cs,
set_if_smaller(dstlen, nweights);
set_if_smaller(len, dstlen);
len= my_strxfrm_pad_desc_and_reverse_nopad(cs, dst, dst + len, dst + dstlen,
- dstlen - len, flags, 0);
+ (uint)(dstlen - len), flags, 0);
if ((flags & MY_STRXFRM_PAD_TO_MAXLEN) && len < dstlen0)
{
- uint fill_length= dstlen0 - len;
+ size_t fill_length= dstlen0 - len;
memset(dst + len, 0x00, fill_length);
len= dstlen0;
}
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index e3ed531df93..a51722b544b 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -31260,7 +31260,7 @@ static my_bool
my_uca_alloc_contractions(MY_CONTRACTIONS *contractions,
MY_CHARSET_LOADER *loader, size_t n)
{
- uint size= n * sizeof(MY_CONTRACTION);
+ size_t size= n * sizeof(MY_CONTRACTION);
if (!(contractions->item= (loader->once_alloc)(size)) ||
!(contractions->flags= (char *) (loader->once_alloc)(MY_UCA_CNT_FLAG_SIZE)))
return 1;
@@ -34005,7 +34005,7 @@ apply_one_rule(MY_CHARSET_LOADER *loader,
{
MY_CONTRACTIONS *contractions= &dst->contractions;
to= my_uca_init_one_contraction(contractions,
- r->curr, nshift, r->with_context);
+ r->curr, (uint)nshift, r->with_context);
/* Store weights of the "reset to" character */
dst->contractions.nitems--; /* Temporarily hide - it's incomplete */
rc= my_char_weight_put(dst,
@@ -34034,7 +34034,7 @@ apply_one_rule(MY_CHARSET_LOADER *loader,
/**
Check if collation rules are valid,
- i.e. characters are not outside of the collation suported range.
+ i.e. characters are not outside of the collation supported range.
*/
static int
check_rules(MY_CHARSET_LOADER *loader,
@@ -34170,7 +34170,7 @@ init_weight_level(MY_CHARSET_LOADER *loader, MY_COLL_RULES *rules,
memcpy(dst->weights, src->weights, npages * sizeof(uint16 *));
/*
- Calculate maximum lenghts for the pages which will be overwritten.
+ Calculate maximum lengths for the pages which will be overwritten.
Mark pages that will be otherwriten as NULL.
We'll allocate their own memory.
*/
@@ -34188,7 +34188,7 @@ init_weight_level(MY_CHARSET_LOADER *loader, MY_COLL_RULES *rules,
{
/*
Not an expansion and not a contraction.
- The page correspoding to r->curr[0] in "dst"
+ The page corresponding to r->curr[0] in "dst"
will need at least the same amount of weights
that r->base[0] has in "src".
*/
@@ -34202,9 +34202,9 @@ init_weight_level(MY_CHARSET_LOADER *loader, MY_COLL_RULES *rules,
ncontractions++;
}
- ncontractions += src->contractions.nitems;
+ ncontractions += (int)src->contractions.nitems;
- if ((my_uca_generate_pages(loader, dst, src, npages)))
+ if ((my_uca_generate_pages(loader, dst, src, (uint)npages)))
return TRUE;
if (ncontractions)
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index 43fdca6efc1..df6572ee77d 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -1078,7 +1078,7 @@ my_fill_mb2(CHARSET_INFO *cs, char *s, size_t slen, int fill)
}
-static int
+static size_t
my_vsnprintf_mb2(char *dst, size_t n, const char* fmt, va_list ap)
{
char *start=dst, *end= dst + n - 1;
@@ -2327,7 +2327,7 @@ my_charlen_utf32(CHARSET_INFO *cs __attribute__((unused)),
/* Defines my_well_formed_char_length_utf32 */
-static int
+static size_t
my_vsnprintf_utf32(char *dst, size_t n, const char* fmt, va_list ap)
{
char *start= dst, *end= dst + n;
diff --git a/strings/ctype.c b/strings/ctype.c
index 0aed6c8bf52..28bfbf16ff6 100644
--- a/strings/ctype.c
+++ b/strings/ctype.c
@@ -831,7 +831,7 @@ my_parse_charset_xml(MY_CHARSET_LOADER *loader, const char *buf, size_t len)
uint
-my_string_repertoire_8bit(CHARSET_INFO *cs, const char *str, ulong length)
+my_string_repertoire_8bit(CHARSET_INFO *cs, const char *str, size_t length)
{
const char *strend;
if ((cs->state & MY_CS_NONASCII) && length > 0)
@@ -904,11 +904,11 @@ my_string_metadata_get(MY_STRING_METADATA *metadata,
if (cs->mbmaxlen == 1 && !(cs->state & MY_CS_NONASCII))
{
metadata->char_length= length;
- metadata->repertoire= my_string_repertoire_8bit(cs, str, length);
+ metadata->repertoire= my_string_repertoire_8bit(cs, str, (ulong)length);
}
else
{
- my_string_metadata_get_mb(metadata, cs, str, length);
+ my_string_metadata_get_mb(metadata, cs, str, (ulong)length);
}
}
@@ -917,7 +917,7 @@ my_string_metadata_get(MY_STRING_METADATA *metadata,
Check repertoire: detect pure ascii strings
*/
uint
-my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong length)
+my_string_repertoire(CHARSET_INFO *cs, const char *str, size_t length)
{
if (cs->mbminlen == 1 && !(cs->state & MY_CS_NONASCII))
{
@@ -1001,9 +1001,9 @@ my_charset_is_ascii_based(CHARSET_INFO *cs)
*/
uint32
-my_convert_using_func(char *to, uint32 to_length,
+my_convert_using_func(char *to, size_t to_length,
CHARSET_INFO *to_cs, my_charset_conv_wc_mb wc_mb,
- const char *from, uint32 from_length,
+ const char *from, size_t from_length,
CHARSET_INFO *from_cs, my_charset_conv_mb_wc mb_wc,
uint *errors)
{
diff --git a/strings/decimal.c b/strings/decimal.c
index 7db5111fc84..4473e754365 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1365,7 +1365,7 @@ int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
case 2: x=mi_sint2korr(from); break;
case 3: x=mi_sint3korr(from); break;
case 4: x=mi_sint4korr(from); break;
- default: DBUG_ASSERT(0);
+ default: abort();
}
from+=i;
*buf=x ^ mask;
@@ -1406,7 +1406,7 @@ int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
case 2: x=mi_sint2korr(from); break;
case 3: x=mi_sint3korr(from); break;
case 4: x=mi_sint4korr(from); break;
- default: DBUG_ASSERT(0);
+ default: abort();
}
*buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
if (((uint32)*buf) > DIG_MAX)
@@ -1694,7 +1694,7 @@ done:
scale increment for '/'
NOTE
- returned valued may be larger than the actual buffer requred
+ returned valued may be larger than the actual buffer required
in the operation, as decimal_result_size, by design, operates on
precision/scale values only and not on the actual decimal number
diff --git a/strings/dtoa.c b/strings/dtoa.c
index 9e0f7f4f43d..7b560227026 100644
--- a/strings/dtoa.c
+++ b/strings/dtoa.c
@@ -1290,7 +1290,7 @@ static double ratio(Bigint *a, Bigint *b)
dval(&db)= b2d(b, &kb);
k= ka - kb + 32*(a->wds - b->wds);
if (k > 0)
- word0(&da)+= k*Exp_msk1;
+ word0(&da)+= (ULong)(k*Exp_msk1 * 1.0);
else
{
k= -k;
diff --git a/strings/json_lib.c b/strings/json_lib.c
index 8e928e2c522..625f6f8fff4 100644
--- a/strings/json_lib.c
+++ b/strings/json_lib.c
@@ -501,7 +501,7 @@ static int skip_num_constant(json_engine_t *j)
for (;;)
{
j->num_flags|= json_num_state_flags[state];
- if ((c_len= json_next_char(&j->s)) > 0)
+ if ((c_len= json_next_char(&j->s)) > 0 && j->s.c_next < 128)
{
if ((state= json_num_states[state][json_num_chr_map[j->s.c_next]]) > 0)
{
@@ -1386,7 +1386,7 @@ int json_find_paths_next(json_engine_t *je, json_find_paths_t *state)
if (!json_key_matches(je, &key_name))
continue;
}
- if (cur_step - state->paths[p_c].last_step == state->cur_depth)
+ if ((uint) (cur_step - state->paths[p_c].last_step) == state->cur_depth)
path_found= TRUE;
else
{
@@ -1419,7 +1419,7 @@ int json_find_paths_next(json_engine_t *je, json_find_paths_t *state)
cur_step->n_item == state->array_counters[state->cur_depth])
{
/* Array item matches. */
- if (cur_step - state->paths[p_c].last_step == state->cur_depth)
+ if ((uint) (cur_step - state->paths[p_c].last_step) == state->cur_depth)
path_found= TRUE;
else
{
diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c
index b2ff1e0fa2c..c6d9e8530dd 100644
--- a/strings/my_vsnprintf.c
+++ b/strings/my_vsnprintf.c
@@ -92,10 +92,10 @@ static const char *get_length(const char *fmt, size_t *length, uint *pre_zero)
*/
static const char *get_length_arg(const char *fmt, ARGS_INFO *args_arr,
- uint *arg_count, size_t *length, uint *flags)
+ size_t *arg_count, size_t *length, uint *flags)
{
fmt= get_length(fmt+1, length, flags);
- *arg_count= MY_MAX(*arg_count, (uint) *length);
+ *arg_count= MY_MAX(*arg_count, *length);
(*length)--;
DBUG_ASSERT(*fmt == '$' && *length < MAX_ARGS);
args_arr[*length].arg_type= 'd';
@@ -330,7 +330,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
{
ARGS_INFO args_arr[MAX_ARGS];
PRINT_INFO print_arr[MAX_PRINT_INFO];
- uint idx= 0, arg_count= arg_index;
+ size_t idx= 0, arg_count= arg_index;
start:
/* Here we are at the beginning of positional argument, right after $ */
@@ -752,14 +752,14 @@ int my_vfprintf(FILE *stream, const char* format, va_list args)
and try again.
*/
if (alloc)
- (*my_str_free)(p);
+ my_free(p);
else
alloc= 1;
new_len= cur_len*2;
if (new_len < cur_len)
return 0; /* Overflow */
cur_len= new_len;
- p= (*my_str_malloc)(cur_len);
+ p= my_malloc(cur_len, MYF(MY_FAE));
if (!p)
return 0;
}
@@ -767,7 +767,7 @@ int my_vfprintf(FILE *stream, const char* format, va_list args)
if (fputs(p, stream) < 0)
ret= -1;
if (alloc)
- (*my_str_free)(p);
+ my_free(p);
return ret;
}
diff --git a/strings/str_alloc.c b/strings/str_alloc.c
deleted file mode 100644
index 91246603f2e..00000000000
--- a/strings/str_alloc.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (c) 2005, 2006 MySQL AB
- Copyright (c) 2009-2011, Monty Program Ab
- Use is subject to license terms.
- Copyright (c) 2009-2011, Monty Program 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 St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "strings_def.h"
-
-static void *my_str_malloc_default(size_t size)
-{
- void *ret= malloc(size);
- if (!ret)
- exit(1);
- return ret;
-}
-
-static void my_str_free_default(void *ptr)
-{
- free(ptr);
-}
-
-void *my_str_realloc_default(void *ptr, size_t size)
-{
- return realloc(ptr, size);
-}
-
-void *(*my_str_malloc)(size_t)= &my_str_malloc_default;
-void (*my_str_free)(void *)= &my_str_free_default;
-void *(*my_str_realloc)(void *, size_t)= &my_str_realloc_default;
diff --git a/strings/xml.c b/strings/xml.c
index 4685a04faec..b5fed6a6760 100644
--- a/strings/xml.c
+++ b/strings/xml.c
@@ -17,6 +17,7 @@
#include "strings_def.h"
#include "m_string.h"
#include "my_xml.h"
+#include "my_sys.h"
#define MY_XML_UNKNOWN 'U'
@@ -231,13 +232,13 @@ static int my_xml_attr_ensure_space(MY_XML_PARSER *st, size_t len)
if (!st->attr.buffer)
{
- st->attr.buffer= (char *) my_str_malloc(st->attr.buffer_size);
+ st->attr.buffer= (char *) my_malloc(st->attr.buffer_size, MYF(0));
if (st->attr.buffer)
memcpy(st->attr.buffer, st->attr.static_buffer, ofs + 1 /*term. zero */);
}
else
- st->attr.buffer= (char *) my_str_realloc(st->attr.buffer,
- st->attr.buffer_size);
+ st->attr.buffer= (char *) my_realloc(st->attr.buffer,
+ st->attr.buffer_size, MYF(0));
st->attr.start= st->attr.buffer;
st->attr.end= st->attr.start + ofs;
@@ -507,7 +508,7 @@ void my_xml_parser_free(MY_XML_PARSER *p)
{
if (p->attr.buffer)
{
- my_str_free(p->attr.buffer);
+ my_free(p->attr.buffer);
p->attr.buffer= NULL;
}
}
diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt
index a3a8f9fd1b4..52184baef7e 100644
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -102,6 +102,21 @@ IF(UNIX)
${CMAKE_CURRENT_BINARY_DIR}/mariadb.service
DESTINATION ${inst_location}/systemd COMPONENT SupportFiles)
+ IF(INSTALL_SYSTEMD_SYSUSERSDIR)
+ CONFIGURE_FILE(sysusers.conf.in
+ ${CMAKE_CURRENT_BINARY_DIR}/sysusers.conf @ONLY)
+ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/sysusers.conf
+ DESTINATION ${INSTALL_SYSTEMD_SYSUSERSDIR} COMPONENT Server)
+ ENDIF()
+
+ IF(INSTALL_SYSTEMD_TMPFILESDIR)
+ get_filename_component(MYSQL_UNIX_DIR ${MYSQL_UNIX_ADDR} DIRECTORY)
+ CONFIGURE_FILE(tmpfiles.conf.in
+ ${CMAKE_CURRENT_BINARY_DIR}/tmpfiles.conf @ONLY)
+ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tmpfiles.conf
+ DESTINATION ${INSTALL_SYSTEMD_TMPFILESDIR} COMPONENT Server)
+ ENDIF()
+
# @ in directory name broken between CMake version 2.8.12.2 and 3.3
# http://public.kitware.com/Bug/view.php?id=14782
IF(NOT CMAKE_VERSION VERSION_LESS 3.3.0 OR NOT RPM)
diff --git a/support-files/compiler_warnings.supp b/support-files/compiler_warnings.supp
index cfda98de86d..4d9ca1c815b 100644
--- a/support-files/compiler_warnings.supp
+++ b/support-files/compiler_warnings.supp
@@ -176,6 +176,11 @@
.*/liblzma/lz/lz_encoder\.c : variable.*in_used.*set but not used
#
+# pcre
+#
+.*/pcre/pcre_exec\.c: noclone.*attribute directive ignored
+
+#
# Unexplanable (?) stuff
#
.*/listener\.cc : .*conversion from 'SOCKET' to 'int'.*
diff --git a/support-files/mariadb.service.in b/support-files/mariadb.service.in
index 6a307b2c41f..ef9fa5c2a22 100644
--- a/support-files/mariadb.service.in
+++ b/support-files/mariadb.service.in
@@ -13,7 +13,9 @@
# and probably others
[Unit]
-Description=MariaDB database server
+Description=MariaDB @VERSION@ database server
+Documentation=man:mysqld(8)
+Documentation=https://mariadb.com/kb/en/library/systemd/
After=network.target
After=syslog.target
@@ -76,7 +78,7 @@ ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \
# Start main service
# MYSQLD_OPTS here is for users to set in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf
-# Use the [service] section and Environment="MYSQLD_OPTS=...".
+# Use the [Service] section and Environment="MYSQLD_OPTS=...".
# This isn't a replacement for my.cnf.
# _WSREP_NEW_CLUSTER is for the exclusive use of the script galera_new_cluster
ExecStart=@sbindir@/mysqld $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION
@@ -85,7 +87,6 @@ ExecStart=@sbindir@/mysqld $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITI
# Unset _WSREP_START_POSITION environment variable.
ExecStartPost=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION"
-KillMode=process
KillSignal=SIGTERM
# Don't want to see an automated SIGKILL ever
@@ -103,7 +104,8 @@ UMask=007
##
##
## by creating a file in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf
-## and adding/setting the following will override this file's settings.
+## and adding/setting the following under [Service] will override this file's
+## settings.
# Useful options not previously available in [mysqld_safe]
diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in
index 410e7433b2b..465a0d94c62 100644
--- a/support-files/mariadb@.service.in
+++ b/support-files/mariadb@.service.in
@@ -18,7 +18,9 @@
# Inspired from https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-db/mysql-init-scripts/files/mysqld_at.service
[Unit]
-Description=MariaDB database server
+Description=MariaDB @VERSION@ database server (multi-instance)
+Documentation=man:mysqld(8)
+Documentation=https://mariadb.com/kb/en/library/systemd/
After=network.target
After=syslog.target
@@ -89,7 +91,7 @@ ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \
# Start main service
# MYSQLD_OPTS here is for users to set in /etc/systemd/system/mariadb@.service.d/MY_SPECIAL.conf
-# Use the [service] section and Environment="MYSQLD_OPTS=...".
+# Use the [Service] section and Environment="MYSQLD_OPTS=...".
# This isn't a replacement for my.cnf.
# _WSREP_NEW_CLUSTER is for the exclusive use of the script galera_new_cluster
@@ -106,7 +108,6 @@ ExecStart=@sbindir@/mysqld --defaults-file=@sysconf2dir@/my%I.cnf \
# Unset _WSREP_START_POSITION environment variable.
ExecStartPost=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION%I"
-KillMode=process
KillSignal=SIGTERM
# Don't want to see an automated SIGKILL ever
@@ -124,7 +125,8 @@ UMask=007
##
##
## by creating a file in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf
-## and adding/setting the following will override this file's settings.
+## and adding/setting the following below [Service] will override this file's
+## settings.
# Useful options not previously available in [mysqld_safe]
diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh
index 1ebf2922279..342929d2ecd 100644
--- a/support-files/mysql.server.sh
+++ b/support-files/mysql.server.sh
@@ -2,7 +2,7 @@
# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
# This file is public domain and comes with NO WARRANTY of any kind
-# MySQL daemon start/stop script.
+# MariaDB daemon start/stop script.
# Usually this is put in /etc/init.d (at least on machines SYSV R4 based
# systems) and linked to /etc/rc3.d/S99mysql and /etc/rc0.d/K01mysql.
@@ -21,14 +21,14 @@
# Required-Stop: $local_fs $network $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
-# Short-Description: start and stop MySQL
-# Description: MySQL is a very fast and reliable SQL database engine.
+# Short-Description: start and stop MariaDB
+# Description: MariaDB is a very fast and reliable SQL database engine.
### END INIT INFO
-# If you install MySQL on some other places than @prefix@, then you
+# If you install MariaDB on some other places than @prefix@, then you
# have to do one of the following things for this script to work:
#
-# - Run this script from within the MySQL installation directory
+# - Run this script from within the MariaDB installation directory
# - Create a /etc/my.cnf file with the following information:
# [mysqld]
# basedir=<path-to-mysql-installation-directory>
@@ -37,11 +37,11 @@
# - Add the path to the mysql-installation-directory to the basedir variable
# below.
#
-# If you want to affect other MySQL variables, you should make your changes
-# in the /etc/my.cnf, ~/.my.cnf or other MySQL configuration files.
+# If you want to affect other MariaDB variables, you should make your changes
+# in the /etc/my.cnf, ~/.my.cnf or other MariaDB configuration files.
# If you change base dir, you must also change datadir. These may get
-# overwritten by settings in the MySQL configuration files.
+# overwritten by settings in the MariaDB configuration files.
basedir=
datadir=
@@ -291,7 +291,7 @@ case "$mode" in
# Safeguard (relative paths, core dumps..)
cd $basedir
- echo $echo_n "Starting MySQL"
+ echo $echo_n "Starting MariaDB"
if test -x $bindir/mysqld_safe
then
# Give extra arguments to mysqld with the my.cnf file. This script
@@ -307,7 +307,7 @@ case "$mode" in
exit $return_value
else
- log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)"
+ log_failure_msg "Couldn't find MariaDB server ($bindir/mysqld_safe)"
fi
;;
@@ -321,12 +321,12 @@ case "$mode" in
if (kill -0 $mysqld_pid 2>/dev/null)
then
- echo $echo_n "Shutting down MySQL"
+ echo $echo_n "Shutting down MariaDB"
kill $mysqld_pid
# mysqld should remove the pid file when it exits, so wait for it.
wait_for_gone $mysqld_pid "$mysqld_pid_file_path"; return_value=$?
else
- log_failure_msg "MySQL server process #$mysqld_pid is not running!"
+ log_failure_msg "MariaDB server process #$mysqld_pid is not running!"
rm "$mysqld_pid_file_path"
fi
@@ -337,7 +337,7 @@ case "$mode" in
fi
exit $return_value
else
- log_failure_msg "MySQL server PID file could not be found!"
+ log_failure_msg "MariaDB server PID file could not be found!"
fi
;;
@@ -358,10 +358,10 @@ case "$mode" in
'reload'|'force-reload')
if test -s "$mysqld_pid_file_path" ; then
read mysqld_pid < "$mysqld_pid_file_path"
- kill -HUP $mysqld_pid && log_success_msg "Reloading service MySQL"
+ kill -HUP $mysqld_pid && log_success_msg "Reloading service MariaDB"
touch "$mysqld_pid_file_path"
else
- log_failure_msg "MySQL PID file could not be found!"
+ log_failure_msg "MariaDB PID file could not be found!"
exit 1
fi
;;
@@ -370,10 +370,10 @@ case "$mode" in
if test -s "$mysqld_pid_file_path" ; then
read mysqld_pid < "$mysqld_pid_file_path"
if kill -0 $mysqld_pid 2>/dev/null ; then
- log_success_msg "MySQL running ($mysqld_pid)"
+ log_success_msg "MariaDB running ($mysqld_pid)"
exit 0
else
- log_failure_msg "MySQL is not running, but PID file exists"
+ log_failure_msg "MariaDB is not running, but PID file exists"
exit 1
fi
else
@@ -383,17 +383,17 @@ case "$mode" in
# test if multiple pids exist
pid_count=`echo $mysqld_pid | wc -w`
if test $pid_count -gt 1 ; then
- log_failure_msg "Multiple MySQL running but PID file could not be found ($mysqld_pid)"
+ log_failure_msg "Multiple MariaDB running but PID file could not be found ($mysqld_pid)"
exit 5
elif test -z $mysqld_pid ; then
if test -f "$lock_file_path" ; then
- log_failure_msg "MySQL is not running, but lock file ($lock_file_path) exists"
+ log_failure_msg "MariaDB is not running, but lock file ($lock_file_path) exists"
exit 2
fi
- log_failure_msg "MySQL is not running"
+ log_failure_msg "MariaDB is not running"
exit 3
else
- log_failure_msg "MySQL is running but PID file could not be found"
+ log_failure_msg "MariaDB is running but PID file could not be found"
exit 4
fi
fi
@@ -401,7 +401,7 @@ case "$mode" in
'configtest')
# Safeguard (relative paths, core dumps..)
cd $basedir
- echo $echo_n "Testing MySQL configuration syntax"
+ echo $echo_n "Testing MariaDB configuration syntax"
daemon=$bindir/mysqld
if test -x $libexecdir/mysqld
then
@@ -439,7 +439,7 @@ case "$mode" in
*)
# usage
basename=`basename "$0"`
- echo "Usage: $basename {start|stop|restart|reload|force-reload|status|configtest|bootstrap} [ MySQL server options ]"
+ echo "Usage: $basename {start|stop|restart|reload|force-reload|status|configtest|bootstrap} [ MariaDB server options ]"
exit 1
;;
esac
diff --git a/support-files/sysusers.conf.in b/support-files/sysusers.conf.in
new file mode 100644
index 00000000000..a975b29476a
--- /dev/null
+++ b/support-files/sysusers.conf.in
@@ -0,0 +1 @@
+u @MYSQLD_USER@ - "MariaDB" @MYSQL_DATADIR@
diff --git a/support-files/tmpfiles.conf.in b/support-files/tmpfiles.conf.in
new file mode 100644
index 00000000000..03d66abc0c7
--- /dev/null
+++ b/support-files/tmpfiles.conf.in
@@ -0,0 +1 @@
+d @MYSQL_UNIX_DIR@ 0755 @MYSQLD_USER@ @MYSQLD_USER@ -
diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c
index bf06e2b502b..622183d527a 100644
--- a/tests/mysql_client_fw.c
+++ b/tests/mysql_client_fw.c
@@ -1177,6 +1177,15 @@ static my_bool thread_query(const char *query)
}
+static int mysql_query_or_error(MYSQL *mysql, const char *query)
+{
+ int rc= mysql_query(mysql, query);
+ if (rc)
+ fprintf(stderr, "ERROR %d: %s", mysql_errno(mysql), mysql_error(mysql));
+ return rc;
+}
+
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index dd1e10e7529..f188287a001 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -31,6 +31,9 @@
The fw.c file includes all the mysql_client_test framework; this file
contains only the actual tests, plus the list of test functions to call.
*/
+#ifdef _MSC_VER
+#pragma warning (disable : 4267)
+#endif
#include "mysql_client_fw.c"
#ifndef _WIN32
@@ -12406,6 +12409,119 @@ static void test_datetime_ranges()
}
+/*
+ This test is used in:
+ mysql-test/suite/binlog/binlog_stm_datetime_ranges_mdev15289.test
+*/
+static void test_datetime_ranges_mdev15289()
+{
+ const char *stmt_text;
+ int rc, i;
+ MYSQL_STMT *stmt;
+ MYSQL_BIND my_bind[4];
+ MYSQL_TIME tm[4];
+
+ myheader("test_datetime_ranges_mdev15289");
+
+ stmt_text= "SET sql_mode=''";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+
+ stmt_text= "create or replace table t1 "
+ "(t time, d date, dt datetime,ts timestamp)";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?, ?, ?, ?)");
+ check_stmt(stmt);
+ verify_param_count(stmt, 4);
+
+ /*** Testing DATETIME ***/
+ bzero((char*) my_bind, sizeof(my_bind));
+ for (i= 0; i < 4; i++)
+ {
+ my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
+ my_bind[i].buffer= &tm[i];
+ }
+ rc= mysql_stmt_bind_param(stmt, my_bind);
+ check_execute(stmt, rc);
+
+ /* Notice bad year */
+ tm[0].year= 20010; tm[0].month= 1; tm[0].day= 2;
+ tm[0].hour= 03; tm[0].minute= 04; tm[0].second= 05;
+ tm[0].second_part= 0; tm[0].neg= 0;
+ tm[0].time_type= MYSQL_TIMESTAMP_DATETIME;
+ tm[3]= tm[2]= tm[1]= tm[0];
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ my_process_warnings(mysql, 4);
+
+ verify_col_data("t1", "t", "00:00:00");
+ verify_col_data("t1", "d", "0000-00-00");
+ verify_col_data("t1", "dt", "0000-00-00 00:00:00");
+ verify_col_data("t1", "ts", "0000-00-00 00:00:00");
+
+ /*** Testing DATE ***/
+ bzero((char*) my_bind, sizeof(my_bind));
+ for (i= 0; i < 4; i++)
+ {
+ my_bind[i].buffer_type= MYSQL_TYPE_DATE;
+ my_bind[i].buffer= &tm[i];
+ }
+ rc= mysql_stmt_bind_param(stmt, my_bind);
+ check_execute(stmt, rc);
+
+ /* Notice bad year */
+ tm[0].year= 20010; tm[0].month= 1; tm[0].day= 2;
+ tm[0].hour= 00; tm[0].minute= 00; tm[0].second= 00;
+ tm[0].second_part= 0; tm[0].neg= 0;
+ tm[0].time_type= MYSQL_TIMESTAMP_DATE;
+ tm[3]= tm[2]= tm[1]= tm[0];
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ my_process_warnings(mysql, 4);
+
+ verify_col_data("t1", "t", "00:00:00");
+ verify_col_data("t1", "d", "0000-00-00");
+ verify_col_data("t1", "dt", "0000-00-00 00:00:00");
+ verify_col_data("t1", "ts", "0000-00-00 00:00:00");
+
+ /*** Testing TIME ***/
+ bzero((char*) my_bind, sizeof(my_bind));
+ for (i= 0; i < 4; i++)
+ {
+ my_bind[i].buffer_type= MYSQL_TYPE_TIME;
+ my_bind[i].buffer= &tm[i];
+ }
+ rc= mysql_stmt_bind_param(stmt, my_bind);
+ check_execute(stmt, rc);
+
+ /* Notice bad hour */
+ tm[0].year= 0; tm[0].month= 0; tm[0].day= 0;
+ tm[0].hour= 100; tm[0].minute= 64; tm[0].second= 05;
+ tm[0].second_part= 0; tm[0].neg= 0;
+ tm[0].time_type= MYSQL_TIMESTAMP_TIME;
+ tm[3]= tm[2]= tm[1]= tm[0];
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ my_process_warnings(mysql, 4);
+
+ verify_col_data("t1", "t", "00:00:00");
+ verify_col_data("t1", "d", "0000-00-00");
+ verify_col_data("t1", "dt", "0000-00-00 00:00:00");
+ verify_col_data("t1", "ts", "0000-00-00 00:00:00");
+
+ mysql_stmt_close(stmt);
+
+ stmt_text= "drop table t1";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+}
+
+
static void test_bug4172()
{
MYSQL_STMT *stmt;
@@ -19433,7 +19549,9 @@ static void test_mdev4326()
myquery(rc);
}
+/* Test uses MYSQL_PROTOCOL_SOCKET, not on Windows */
+#ifndef _WIN32
/**
BUG#17512527: LIST HANDLING INCORRECT IN MYSQL_PRUNE_STMT_LIST()
*/
@@ -19474,7 +19592,7 @@ static void test_bug17512527()
mysql_stmt_close(stmt2);
mysql_stmt_close(stmt1);
}
-
+#endif
/*
@@ -19861,6 +19979,85 @@ static void test_mdev14013_1()
}
+static void test_mdev14454_internal(const char *init,
+ unsigned int csid,
+ const char *value)
+{
+ MYSQL_STMT *stmt;
+ MYSQL_BIND bind;
+ const char *stmtstr= "CALL P1(?)";
+ char res[20];
+ int rc;
+
+ if ((rc= mysql_query_or_error(mysql, init)) ||
+ (rc= mysql_query_or_error(mysql, "DROP PROCEDURE IF EXISTS p1")) ||
+ (rc= mysql_query_or_error(mysql,
+ "CREATE PROCEDURE p1"
+ "("
+ " OUT param1 TEXT CHARACTER SET utf8"
+ ")"
+ "BEGIN "
+ " SET param1 = _latin1'test\xFF'; "
+ "END")))
+ DIE("Initiation failed");
+
+ stmt= mysql_stmt_init(mysql);
+ rc= mysql_stmt_prepare(stmt, stmtstr, strlen(stmtstr));
+ DIE_UNLESS(rc == 0);
+ DIE_UNLESS(mysql_stmt_param_count(stmt) == 1);
+
+ bind.buffer_type= MYSQL_TYPE_NULL;
+ rc= mysql_stmt_bind_param(stmt, &bind);
+ DIE_UNLESS(rc == 0);
+
+ rc= mysql_stmt_execute(stmt);
+ DIE_UNLESS(rc == 0);
+
+ memset(res, 0, sizeof(res));
+ memset(&bind, 0, sizeof(bind));
+ bind.buffer_type= MYSQL_TYPE_STRING;
+ bind.buffer_length= sizeof(res);
+ bind.buffer= res;
+
+ do {
+ if (mysql->server_status & SERVER_PS_OUT_PARAMS)
+ {
+ MYSQL_FIELD *field;
+ printf("\nOUT param result set:\n");
+ DIE_UNLESS(mysql_stmt_field_count(stmt) == 1);
+ field= &stmt->fields[0];
+ printf("Field: %s\n", field->name);
+ printf("Type: %d\n", field->type);
+ printf("Collation: %d\n", field->charsetnr);
+ printf("Length: %lu\n", field->length);
+ DIE_UNLESS(stmt->fields[0].charsetnr == csid);
+
+ rc= mysql_stmt_bind_result(stmt, &bind);
+ DIE_UNLESS(rc == 0);
+ rc= mysql_stmt_fetch(stmt);
+ DIE_UNLESS(rc == 0);
+ printf("Value: %s\n", res);
+ DIE_UNLESS(strcmp(res, value) == 0);
+ }
+ else if (mysql_stmt_field_count(stmt))
+ {
+ printf("sp result set\n");
+ }
+ } while (mysql_stmt_next_result(stmt) == 0);
+
+ mysql_stmt_close(stmt);
+ DIE_UNLESS(mysql_query_or_error(mysql, "DROP PROCEDURE p1") == 0);
+}
+
+
+static void test_mdev14454()
+{
+ myheader("test_mdev14454");
+ test_mdev14454_internal("SET NAMES latin1", 8, "test\xFF");
+ test_mdev14454_internal("SET NAMES utf8", 33, "test\xC3\xBF");
+}
+
+
typedef struct {
char sig[12];
char ver_cmd;
@@ -20187,6 +20384,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug6081", test_bug6081 },
{ "test_bug6096", test_bug6096 },
{ "test_datetime_ranges", test_datetime_ranges },
+ { "test_datetime_ranges_mdev15289", test_datetime_ranges_mdev15289 },
{ "test_bug4172", test_bug4172 },
{ "test_conversion", test_conversion },
{ "test_rewind", test_rewind },
@@ -20318,6 +20516,7 @@ static struct my_tests_st my_tests[]= {
{ "test_mdev12579", test_mdev12579 },
{ "test_mdev14013", test_mdev14013 },
{ "test_mdev14013_1", test_mdev14013_1 },
+ { "test_mdev14454", test_mdev14454 },
#ifndef EMBEDDED_LIBRARY
{ "test_proxy_header", test_proxy_header},
#endif
diff --git a/unittest/mysys/base64-t.c b/unittest/mysys/base64-t.c
index 58d0014dee1..a61deefa669 100644
--- a/unittest/mysys/base64-t.c
+++ b/unittest/mysys/base64-t.c
@@ -48,7 +48,7 @@ main(int argc __attribute__((unused)),char *argv[])
}
/* Encode */
- needed_length= my_base64_needed_encoded_length(src_len);
+ needed_length= my_base64_needed_encoded_length((int)src_len);
str= (char *) malloc(needed_length);
for (k= 0; k < needed_length; k++)
str[k]= 0xff; /* Fill memory to check correct NUL termination */
@@ -58,7 +58,7 @@ main(int argc __attribute__((unused)),char *argv[])
"my_base64_needed_encoded_length: size %d", i);
/* Decode */
- dst= (char *) malloc(my_base64_needed_decoded_length(strlen(str)));
+ dst= (char *) malloc(my_base64_needed_decoded_length((int)strlen(str)));
dst_len= my_base64_decode(str, strlen(str), dst, NULL, 0);
ok(dst_len == src_len, "Comparing lengths");
@@ -90,6 +90,9 @@ main(int argc __attribute__((unused)),char *argv[])
diag("src length: %.8x, dst length: %.8x\n",
(uint) src_len, (uint) dst_len);
}
+ free(dst);
+ free(str);
+ free(src);
}
my_end(0);
return exit_status();
diff --git a/unittest/mysys/thr_template.c b/unittest/mysys/thr_template.c
index 38999022da0..83c7432c823 100644
--- a/unittest/mysys/thr_template.c
+++ b/unittest/mysys/thr_template.c
@@ -67,7 +67,7 @@ int main(int argc __attribute__((unused)), char **argv)
#define CYCLES 3000
#define THREADS 30
- diag("N CPUs: %d, atomic ops: %s", my_getncpus(), MY_ATOMIC_MODE);
+ diag("N CPUs: %d", my_getncpus());
do_tests();
diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc
index 2f36127af6d..f27e49d7ea3 100644
--- a/unittest/sql/mf_iocache-t.cc
+++ b/unittest/sql/mf_iocache-t.cc
@@ -138,7 +138,7 @@ void temp_io_cache()
res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
- res= my_pread(info.file, buf, 50, 50, MYF(MY_NABP));
+ res= (int)my_pread(info.file, buf, 50, 50, MYF(MY_NABP));
ok(res == 0 && data_bad(buf, 50) == encrypt_tmp_files,
"file must be %sreadable", encrypt_tmp_files ?"un":"");
@@ -176,7 +176,7 @@ void mdev9044()
res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
- res= my_b_fill(&info);
+ res= (int)my_b_fill(&info);
ok(res == 0, "fill" INFO_TAIL);
res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
diff --git a/vio/viopipe.c b/vio/viopipe.c
index f9af50bc3c9..d3447a95c6e 100644
--- a/vio/viopipe.c
+++ b/vio/viopipe.c
@@ -78,7 +78,7 @@ size_t vio_read_pipe(Vio *vio, uchar *buf, size_t count)
disable_iocp_notification(&vio->overlapped);
/* Attempt to read from the pipe (overlapped I/O). */
- if (ReadFile(vio->hPipe, buf, count, &transferred, &vio->overlapped))
+ if (ReadFile(vio->hPipe, buf, (DWORD)count, &transferred, &vio->overlapped))
{
/* The operation completed immediately. */
ret= transferred;
@@ -101,7 +101,7 @@ size_t vio_write_pipe(Vio *vio, const uchar *buf, size_t count)
disable_iocp_notification(&vio->overlapped);
/* Attempt to write to the pipe (overlapped I/O). */
- if (WriteFile(vio->hPipe, buf, count, &transferred, &vio->overlapped))
+ if (WriteFile(vio->hPipe, buf, (DWORD)count, &transferred, &vio->overlapped))
{
/* The operation completed immediately. */
ret= transferred;
diff --git a/vio/viosocket.c b/vio/viosocket.c
index 6be830fee9e..d34bb13b1bd 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -83,6 +83,16 @@ int vio_errno(Vio *vio __attribute__((unused)))
return socket_errno;
}
+static int vio_set_linger(my_socket s, unsigned short timeout_sec)
+{
+ struct linger s_linger;
+ int ret;
+ s_linger.l_onoff = 1;
+ s_linger.l_linger = timeout_sec;
+ ret = setsockopt(s, SOL_SOCKET, SO_LINGER, (const char *)&s_linger, (int)sizeof(s_linger));
+ return ret;
+}
+
/**
Attempt to wait for an I/O event on a socket.
@@ -115,6 +125,7 @@ int vio_socket_io_wait(Vio *vio, enum enum_vio_io_event event)
case 0:
/* The wait timed out. */
ret= -1;
+ vio_set_linger(vio->mysql_socket.fd, 0);
break;
default:
/* A positive value indicates an I/O event. */
@@ -400,43 +411,6 @@ int vio_socket_timeout(Vio *vio,
{
int ret= 0;
DBUG_ENTER("vio_socket_timeout");
-
-#if defined(_WIN32)
- {
- int optname;
- DWORD timeout= 0;
- const char *optval= (const char *) &timeout;
-
- /*
- The default socket timeout value is zero, which means an infinite
- timeout. Values less than 500 milliseconds are interpreted to be of
- 500 milliseconds. Hence, the VIO behavior for zero timeout, which is
- intended to cause the send or receive operation to fail immediately
- if no data is available, is not supported on WIN32 and neither is
- necessary as it's not possible to set the VIO timeout value to zero.
-
- Assert that the VIO timeout is either positive or set to infinite.
- */
- DBUG_ASSERT(which || vio->read_timeout);
- DBUG_ASSERT(!which || vio->write_timeout);
-
- if (which)
- {
- optname= SO_SNDTIMEO;
- if (vio->write_timeout > 0)
- timeout= vio->write_timeout;
- }
- else
- {
- optname= SO_RCVTIMEO;
- if (vio->read_timeout > 0)
- timeout= vio->read_timeout;
- }
-
- ret= mysql_socket_setsockopt(vio->mysql_socket, SOL_SOCKET, optname,
- optval, sizeof(timeout));
- }
-#else
/*
The MSG_DONTWAIT trick is not used with SSL sockets as the send and
receive I/O operations are wrapped through SSL-specific functions
@@ -457,7 +431,6 @@ int vio_socket_timeout(Vio *vio,
if (new_mode != old_mode)
ret= vio_blocking(vio, new_mode, &not_used);
}
-#endif
DBUG_RETURN(ret);
}
@@ -630,8 +603,6 @@ int vio_close(Vio *vio)
vio->type == VIO_TYPE_SSL);
DBUG_ASSERT(mysql_socket_getfd(vio->mysql_socket) >= 0);
- if (mysql_socket_shutdown(vio->mysql_socket, SHUT_RDWR))
- r= -1;
if (mysql_socket_close(vio->mysql_socket))
r= -1;
}
@@ -682,18 +653,15 @@ my_socket vio_fd(Vio* vio)
@param src_length [in] length of the src.
@param dst [out] a buffer to store normalized IP address
(sockaddr_storage).
- @param dst_length [out] actual length of the normalized IP address.
+ @param dst_length [out] optional - actual length of the normalized IP address.
*/
-void vio_get_normalized_ip(const struct sockaddr *src,
- int src_length,
- struct sockaddr *dst,
- int *dst_length)
+void vio_get_normalized_ip(const struct sockaddr *src, size_t src_length,
+ struct sockaddr *dst)
{
switch (src->sa_family) {
case AF_INET:
memcpy(dst, src, src_length);
- *dst_length= src_length;
break;
#ifdef HAVE_IPV6
@@ -712,9 +680,7 @@ void vio_get_normalized_ip(const struct sockaddr *src,
be converted to the IPv4 form.
*/
- *dst_length= sizeof (struct sockaddr_in);
-
- memset(dst_ip4, 0, *dst_length);
+ memset(dst_ip4, 0, sizeof (struct sockaddr_in));
dst_ip4->sin_family= AF_INET;
dst_ip4->sin_port= src_addr6->sin6_port;
@@ -728,9 +694,7 @@ void vio_get_normalized_ip(const struct sockaddr *src,
else
{
/* This is a "native" IPv6 address. */
-
memcpy(dst, src, src_length);
- *dst_length= src_length;
}
break;
@@ -761,17 +725,15 @@ void vio_get_normalized_ip(const struct sockaddr *src,
@retval FALSE on success.
*/
-my_bool vio_get_normalized_ip_string(const struct sockaddr *addr,
- int addr_length,
+my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, size_t addr_length,
char *ip_string,
size_t ip_string_size)
{
struct sockaddr_storage norm_addr_storage;
struct sockaddr *norm_addr= (struct sockaddr *) &norm_addr_storage;
- int norm_addr_length;
int err_code;
- vio_get_normalized_ip(addr, addr_length, norm_addr, &norm_addr_length);
+ vio_get_normalized_ip(addr, addr_length, norm_addr);
err_code= vio_getnameinfo(norm_addr, ip_string, ip_string_size, NULL, 0,
NI_NUMERICHOST);
@@ -810,9 +772,7 @@ my_bool vio_peer_addr(Vio *vio, char *ip_buffer, uint16 *port,
address.
*/
struct in_addr *ip4= &((struct sockaddr_in *) &(vio->remote))->sin_addr;
-
vio->remote.ss_family= AF_INET;
- vio->addrLen= sizeof (struct sockaddr_in);
ip4->s_addr= htonl(INADDR_LOOPBACK);
@@ -829,7 +789,6 @@ my_bool vio_peer_addr(Vio *vio, char *ip_buffer, uint16 *port,
struct sockaddr_storage addr_storage;
struct sockaddr *addr= (struct sockaddr *) &addr_storage;
size_socket addr_length= sizeof (addr_storage);
-
/* Get sockaddr by socked fd. */
err_code= mysql_socket_getpeername(vio->mysql_socket, addr, &addr_length);
@@ -843,7 +802,7 @@ my_bool vio_peer_addr(Vio *vio, char *ip_buffer, uint16 *port,
/* Normalize IP address. */
vio_get_normalized_ip(addr, addr_length,
- (struct sockaddr *) &vio->remote, &vio->addrLen);
+ (struct sockaddr *) &vio->remote);
/* Get IP address & port number. */
@@ -884,7 +843,7 @@ static my_bool socket_peek_read(Vio *vio, uint *bytes)
{
my_socket sd= mysql_socket_getfd(vio->mysql_socket);
#if defined(_WIN32)
- int len;
+ u_long len;
if (ioctlsocket(sd, FIONREAD, &len))
return TRUE;
*bytes= len;
@@ -1354,7 +1313,7 @@ int vio_getnameinfo(const struct sockaddr *sa,
}
return getnameinfo(sa, sa_length,
- hostname, hostname_size,
- port, port_size,
+ hostname, (uint)hostname_size,
+ port, (uint)port_size,
flags);
}
diff --git a/vio/viossl.c b/vio/viossl.c
index e7cc85ea539..000a526a892 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -141,10 +141,10 @@ size_t vio_ssl_read(Vio *vio, uchar *buf, size_t size)
vio->ssl_arg));
if (vio->async_context && vio->async_context->active)
- ret= my_ssl_read_async(vio->async_context, (SSL *)vio->ssl_arg, buf, size);
+ ret= my_ssl_read_async(vio->async_context, (SSL *)vio->ssl_arg, buf, (int)size);
else
{
- while ((ret= SSL_read(ssl, buf, size)) < 0)
+ while ((ret= SSL_read(ssl, buf, (int)size)) < 0)
{
enum enum_vio_io_event event;
@@ -174,10 +174,10 @@ size_t vio_ssl_write(Vio *vio, const uchar *buf, size_t size)
if (vio->async_context && vio->async_context->active)
ret= my_ssl_write_async(vio->async_context, (SSL *)vio->ssl_arg, buf,
- size);
+ (int)size);
else
{
- while ((ret= SSL_write(ssl, buf, size)) < 0)
+ while ((ret= SSL_write(ssl, buf, (int)size)) < 0)
{
enum enum_vio_io_event event;
@@ -200,7 +200,7 @@ size_t vio_ssl_write(Vio *vio, const uchar *buf, size_t size)
static long yassl_recv(void *ptr, void *buf, size_t len,
int flag __attribute__((unused)))
{
- return vio_read(ptr, buf, len);
+ return (long)vio_read(ptr, buf, len);
}
@@ -208,7 +208,7 @@ static long yassl_recv(void *ptr, void *buf, size_t len,
static long yassl_send(void *ptr, const void *buf, size_t len,
int flag __attribute__((unused)))
{
- return vio_write(ptr, buf, len);
+ return (long)vio_write(ptr, buf, len);
}
#endif
diff --git a/win/create_def_file.js b/win/create_def_file.js
index 25bbbb4eb3d..9a178510ca8 100644
--- a/win/create_def_file.js
+++ b/win/create_def_file.js
@@ -257,4 +257,9 @@ function addToResponseFile(filename, responseFile)
responseFile.WriteLine("\""+fso.GetFile(filename).Path+"\"");
}
}
+ else
+ {
+ echo("file " + filename + " not found. Can't generate symbols file");
+ WScript.Quit (1);
+ }
}
diff --git a/win/packaging/WixUIBannerBmp.jpg b/win/packaging/WixUIBannerBmp.jpg
index a04177bed9d..66256b79255 100644
--- a/win/packaging/WixUIBannerBmp.jpg
+++ b/win/packaging/WixUIBannerBmp.jpg
Binary files differ
diff --git a/win/packaging/WixUIDialogBmp.jpg b/win/packaging/WixUIDialogBmp.jpg
index 466cdc461c8..c6ddf12bd2a 100644
--- a/win/packaging/WixUIDialogBmp.jpg
+++ b/win/packaging/WixUIDialogBmp.jpg
Binary files differ
diff --git a/win/packaging/ca/CustomAction.cpp b/win/packaging/ca/CustomAction.cpp
index c0062ddcdd1..71c24e96f92 100644
--- a/win/packaging/ca/CustomAction.cpp
+++ b/win/packaging/ca/CustomAction.cpp
@@ -60,13 +60,13 @@ extern "C" UINT __stdcall RemoveDataDirectory(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
+ wchar_t dir[MAX_PATH];
+ DWORD len = MAX_PATH;
hr = WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
- wchar_t dir[MAX_PATH];
- DWORD len = MAX_PATH;
MsiGetPropertyW(hInstall, L"CustomActionData", dir, &len);
er= ExecRemoveDataDirectory(dir);
@@ -90,7 +90,7 @@ static void EscapeCommandLine(const wchar_t *in, wchar_t *out, size_t buflen)
bool needs_escaping= false;
size_t pos;
- for(int i=0; i< sizeof(special_chars) -1; i++)
+ for(size_t i=0; i< sizeof(special_chars) -1; i++)
{
if (wcschr(in, special_chars[i]))
{
@@ -160,20 +160,21 @@ extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
+ wchar_t buf[MAX_PATH];
+ DWORD len = MAX_PATH;
+ WIN32_FIND_DATAW data;
+ HANDLE h;
+ bool empty;
+
hr = WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
-
- wchar_t buf[MAX_PATH];
- DWORD len = MAX_PATH;
MsiGetPropertyW(hInstall, PropertyName, buf, &len);
wcscat_s(buf, MAX_PATH, L"*.*");
WcaLog(LOGMSG_STANDARD, "Checking files in %S", buf);
- WIN32_FIND_DATAW data;
- HANDLE h;
- bool empty;
+
h= FindFirstFile(buf, &data);
if (h != INVALID_HANDLE_VALUE)
{
@@ -270,7 +271,7 @@ bool IsPortFree(short port)
struct sockaddr_in sin;
SOCKET sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
- if(sock == -1)
+ if(sock == INVALID_SOCKET)
{
return false;
}
@@ -342,6 +343,12 @@ void CheckServiceConfig(
wchar_t * commandline= config->lpBinaryPathName;
int numargs;
wchar_t **argv= CommandLineToArgvW(commandline, &numargs);
+ wchar_t current_datadir_buf[MAX_PATH]={0};
+ wchar_t normalized_current_datadir[MAX_PATH+1];
+ wchar_t *current_datadir;
+ wchar_t *defaults_file;
+ bool is_my_service;
+
WcaLog(LOGMSG_VERBOSE, "CommandLine= %S", commandline);
if(!argv || !argv[0] || ! wcsstr(argv[0], L"mysqld"))
{
@@ -356,7 +363,7 @@ void CheckServiceConfig(
same_bindir = true;
}
- bool is_my_service = (_wcsicmp(my_servicename, other_servicename) == 0);
+ is_my_service = (_wcsicmp(my_servicename, other_servicename) == 0);
if(!is_my_service)
{
WcaLog(LOGMSG_STANDARD, "service does not match current service");
@@ -379,10 +386,8 @@ void CheckServiceConfig(
goto end;
}
- wchar_t current_datadir_buf[MAX_PATH]={0};
- wchar_t normalized_current_datadir[MAX_PATH+1];
- wchar_t *current_datadir= current_datadir_buf;
- wchar_t *defaults_file= argv[1]+16;
+ current_datadir= current_datadir_buf;
+ defaults_file= argv[1]+16;
defaults_file= strip_quotes(defaults_file);
WcaLog(LOGMSG_STANDARD, "parsed defaults file is %S", defaults_file);
@@ -453,6 +458,7 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall)
ULONG bufneed = 0x00;
ULONG num_services = 0x00;
LPENUM_SERVICE_STATUS_PROCESS info = NULL;
+ BOOL ok;
hr = WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
@@ -471,7 +477,7 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall)
ExitOnFailure(E_FAIL, "OpenSCManager failed");
}
- BOOL ok= EnumServicesStatusExW( scm,
+ ok = EnumServicesStatusExW( scm,
SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
SERVICE_STATE_ALL,
@@ -524,7 +530,7 @@ LExit:
or 4GB(x64 OS).
Fragmentation due to loaded modules, heap and stack
- limit maximum size of continous memory block further,
+ limit maximum size of continuous memory block further,
so that limit for 32 bit process is about 1200 on 32 bit OS
or 2000 MB on 64 bit OS(found experimentally).
*/
@@ -559,13 +565,16 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
const wchar_t *ErrorMsg=0;
HRESULT hr= S_OK;
UINT er= ERROR_SUCCESS;
-
+ DWORD ServiceNameLen = MAX_PATH;
+ DWORD QuickConfigLen = MAX_PATH;
+ DWORD PasswordLen= MAX_PATH;
+ DWORD SkipNetworkingLen= MAX_PATH;
hr = WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
- DWORD ServiceNameLen = MAX_PATH;
+
MsiGetPropertyW (hInstall, L"SERVICENAME", ServiceName, &ServiceNameLen);
if(ServiceName[0])
{
@@ -594,13 +603,11 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
}
}
- DWORD PasswordLen= MAX_PATH;
MsiGetPropertyW (hInstall, L"PASSWORD", Password, &PasswordLen);
EscapeCommandLine(Password, EscapedPassword,
sizeof(EscapedPassword)/sizeof(EscapedPassword[0]));
MsiSetPropertyW(hInstall,L"ESCAPEDPASSWORD",EscapedPassword);
- DWORD SkipNetworkingLen= MAX_PATH;
MsiGetPropertyW(hInstall, L"SKIPNETWORKING", SkipNetworking,
&SkipNetworkingLen);
MsiGetPropertyW(hInstall, L"PORT", Port, &PortLen);
@@ -644,8 +651,6 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
}
}
-
- DWORD QuickConfigLen = MAX_PATH;
MsiGetPropertyW (hInstall, L"STDCONFIG", QuickConfig, &QuickConfigLen);
if(QuickConfig[0] !=0)
{
@@ -722,12 +727,12 @@ extern "C" UINT __stdcall PresetDatabaseProperties(MSIHANDLE hInstall)
UINT er = ERROR_SUCCESS;
HRESULT hr= S_OK;
MEMORYSTATUSEX memstatus;
+ DWORD BufferPoolsizeParamLen = MAX_PATH;
hr = WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
/* Check if bufferpoolsize parameter was given on the command line*/
- DWORD BufferPoolsizeParamLen = MAX_PATH;
MsiGetPropertyW(hInstall, L"BUFFERPOOLSIZE", buff, &BufferPoolsizeParamLen);
if (BufferPoolsizeParamLen && buff[0])
@@ -817,11 +822,13 @@ extern "C" UINT __stdcall CreateDatabaseRollback(MSIHANDLE hInstall)
UINT er = ERROR_SUCCESS;
wchar_t* service= 0;
wchar_t* dir= 0;
+ wchar_t data[2*MAX_PATH];
+ DWORD len= MAX_PATH;
+
hr = WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
- wchar_t data[2*MAX_PATH];
- DWORD len= MAX_PATH;
+
MsiGetPropertyW(hInstall, L"CustomActionData", data, &len);
/* Property is encoded as [SERVICENAME]\[DBLOCATION] */
@@ -864,13 +871,16 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
- wchar_t* service= 0;
- wchar_t* dir= 0;
wchar_t installerVersion[MAX_VERSION_PROPERTY_SIZE];
char installDir[MAX_PATH];
DWORD size =MAX_VERSION_PROPERTY_SIZE;
int installerMajorVersion, installerMinorVersion, installerPatchVersion;
bool upgradableServiceFound=false;
+ LPENUM_SERVICE_STATUS_PROCESSW info;
+ DWORD bufsize;
+ int index;
+ BOOL ok;
+ SC_HANDLE scm = NULL;
hr = WcaInitialize(hInstall, __FUNCTION__);
WcaLog(LOGMSG_STANDARD, "Initialized.");
@@ -895,7 +905,7 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
}
- SC_HANDLE scm = OpenSCManager(NULL, NULL,
+ scm = OpenSCManager(NULL, NULL,
SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
if (scm == NULL)
{
@@ -906,19 +916,19 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
static BYTE buf[64*1024];
static BYTE config_buffer[8*1024];
- DWORD bufsize= sizeof(buf);
+ bufsize= sizeof(buf);
DWORD bufneed;
DWORD num_services;
- BOOL ok= EnumServicesStatusExW(scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
+ ok= EnumServicesStatusExW(scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
SERVICE_STATE_ALL, buf, bufsize, &bufneed, &num_services, NULL, NULL);
if(!ok)
{
hr = HRESULT_FROM_WIN32(GetLastError());
ExitOnFailure(hr,"EnumServicesStatusEx failed");
}
- LPENUM_SERVICE_STATUS_PROCESSW info =
+ info =
(LPENUM_SERVICE_STATUS_PROCESSW)buf;
- int index=-1;
+ index=-1;
for (ULONG i=0; i < num_services; i++)
{
SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName,
@@ -928,7 +938,7 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
QUERY_SERVICE_CONFIGW *config=
(QUERY_SERVICE_CONFIGW*)(void *)config_buffer;
DWORD needed;
- BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer),
+ ok= QueryServiceConfigW(service, config,sizeof(config_buffer),
&needed) && (config->dwStartType != SERVICE_DISABLED);
CloseServiceHandle(service);
if (ok)
diff --git a/win/upgrade_wizard/CMakeLists.txt b/win/upgrade_wizard/CMakeLists.txt
index dc4ef67387d..2186a79f732 100644
--- a/win/upgrade_wizard/CMakeLists.txt
+++ b/win/upgrade_wizard/CMakeLists.txt
@@ -1,6 +1,10 @@
IF(NOT MSVC)
RETURN()
ENDIF()
+IF(CMAKE_C_COMPILER_ID MATCHES Clang)
+ # MFC stuff does not compile with clang
+ RETURN()
+ENDIF()
IF(CMAKE_USING_VC_FREE_TOOLS)
# No MFC, so it cannot be built
RETURN()
@@ -24,7 +28,7 @@ ELSE()
SET(CMAKE_MFC_FLAG 1)
ENDIF()
# Enable exception handling (avoids warnings)
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc -DNO_WARN_MBCS_MFC_DEPRECATION")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql)
MYSQL_ADD_EXECUTABLE(mysql_upgrade_wizard
diff --git a/win/upgrade_wizard/stdafx.h b/win/upgrade_wizard/stdafx.h
index 55f9e71ed70..86e4fd826de 100644
--- a/win/upgrade_wizard/stdafx.h
+++ b/win/upgrade_wizard/stdafx.h
@@ -14,7 +14,7 @@
#endif
#include "targetver.h"
-
+struct IUnknown;
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
// turns off MFC's hiding of some common and often safely ignored warning messages
diff --git a/wsrep/CMakeLists.txt b/wsrep/CMakeLists.txt
index 53c8e853078..ff2bdec4def 100644
--- a/wsrep/CMakeLists.txt
+++ b/wsrep/CMakeLists.txt
@@ -15,6 +15,10 @@
SET(WSREP_SOURCES wsrep_gtid.c wsrep_uuid.c wsrep_loader.c wsrep_dummy.c)
+IF(NOT WITH_INNOBASE_STORAGE_ENGINE)
+ MESSAGE(WARNING "WSRep is enabled, but innodb is not. This configuration is not supported")
+ENDIF()
+
ADD_CONVENIENCE_LIBRARY(wsrep ${WSREP_SOURCES})
DTRACE_INSTRUMENT(wsrep)